From b7591356d22e2cacaa73ef118b91a53c09c97c88 Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Thu, 23 Feb 2023 22:12:54 +0100 Subject: [PATCH 01/54] Fix MergeToModel for mesh without properties --- .../NMR_MeshInformationTypes.h | 6 +-- .../NMR_MeshInformationHandler.cpp | 8 ++-- .../NMR_MeshInformation_Properties.cpp | 6 ++- Tests/CPP_Bindings/Source/MergeModels.cpp | 40 +++++++++++++++++- Tests/TestFiles/Models/platform.3mf | Bin 0 -> 85670 bytes 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 Tests/TestFiles/Models/platform.3mf diff --git a/Include/Common/MeshInformation/NMR_MeshInformationTypes.h b/Include/Common/MeshInformation/NMR_MeshInformationTypes.h index c61513a55..dc9ae88fb 100644 --- a/Include/Common/MeshInformation/NMR_MeshInformationTypes.h +++ b/Include/Common/MeshInformation/NMR_MeshInformationTypes.h @@ -50,9 +50,9 @@ namespace NMR { typedef nfByte MESHINFORMATIONFACEDATA; #pragma pack (1) - typedef struct { - nfUint32 m_nUniqueResourceID; - nfUint32 m_nPropertyIDs[3]; + typedef struct sMESHINFORMATION_PROPERTIES { + nfUint32 m_nUniqueResourceID = 0; + nfUint32 m_nPropertyIDs[3] = { 0,0,0 }; } MESHINFORMATION_PROPERTIES; diff --git a/Source/Common/MeshInformation/NMR_MeshInformationHandler.cpp b/Source/Common/MeshInformation/NMR_MeshInformationHandler.cpp index dbf223b03..791c126e3 100644 --- a/Source/Common/MeshInformation/NMR_MeshInformationHandler.cpp +++ b/Source/Common/MeshInformation/NMR_MeshInformationHandler.cpp @@ -119,8 +119,10 @@ namespace NMR { { nfInt32 eType; for (eType = emiAbstract; eType < emiLastType; eType++) { - if ((pOtherInfoHandler->m_pLookup[eType]) && (m_pLookup[eType])) - m_pLookup[eType]->cloneDefaultInfosFrom(pOtherInfoHandler->m_pLookup[eType]); + if ((pOtherInfoHandler->m_pLookup[eType]) && (m_pLookup[eType])) { + if (pOtherInfoHandler->m_pLookup[eType]->getDefaultData()) + m_pLookup[eType]->cloneDefaultInfosFrom(pOtherInfoHandler->m_pLookup[eType]); + } } } @@ -128,7 +130,7 @@ namespace NMR { { nfInt32 eType; for (eType = emiAbstract; eType < emiLastType; eType++) { - if ((pOtherInfoHandler->m_pLookup[eType]) && (m_pLookup[eType])) + if ((pOtherInfoHandler->m_pLookup[eType]) && (m_pLookup[eType]) && (m_pLookup[eType]->getDefaultData())) m_pLookup[eType]->cloneFaceInfosFrom(nFaceIdx, pOtherInfoHandler->m_pLookup[eType], nOtherFaceIndex); } } diff --git a/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp b/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp index 1e55b3468..29ca1d3ac 100644 --- a/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp +++ b/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp @@ -117,12 +117,16 @@ namespace NMR { void CMeshInformation_Properties::cloneDefaultInfosFrom(_In_ CMeshInformation * pOtherInformation) { + MESHINFORMATION_PROPERTIES* pSourceDefaultData = (MESHINFORMATION_PROPERTIES*)pOtherInformation->getDefaultData(); + if (!pSourceDefaultData) + return; + MESHINFORMATION_PROPERTIES * pTargetDefaultData = (MESHINFORMATION_PROPERTIES*)getDefaultData(); if (!pTargetDefaultData) { setDefaultData((MESHINFORMATIONFACEDATA*)new MESHINFORMATION_PROPERTIES); pTargetDefaultData = (MESHINFORMATION_PROPERTIES*)getDefaultData(); } - MESHINFORMATION_PROPERTIES * pSourceDefaultData = (MESHINFORMATION_PROPERTIES*)pOtherInformation->getDefaultData(); + if (pTargetDefaultData && pSourceDefaultData) { for (nfUint32 j = 0; j < 3; j++) pTargetDefaultData->m_nPropertyIDs[j] = pSourceDefaultData->m_nPropertyIDs[j]; diff --git a/Tests/CPP_Bindings/Source/MergeModels.cpp b/Tests/CPP_Bindings/Source/MergeModels.cpp index fb6e47803..98655e8c7 100644 --- a/Tests/CPP_Bindings/Source/MergeModels.cpp +++ b/Tests/CPP_Bindings/Source/MergeModels.cpp @@ -67,7 +67,45 @@ namespace Lib3MF { auto writer3MF = pMergedModel->QueryWriter("3mf"); writer3MF->WriteToBuffer(buffer); - // writer3MF->WriteToFile(sTestFilesPath + "/Models/" + "WithSomeResources_out.3mf"); + //writer3MF->WriteToFile(sTestFilesPath + "/Models/" + "WithSomeResources_out.3mf"); + } + + ExpectEqModels(m_pModel, pMergedModel); + EXPECT_EQ(pMergedModel->GetMeshObjects()->Count(), 1); + EXPECT_EQ(pMergedModel->GetComponentsObjects()->Count(), 0); + EXPECT_EQ(pMergedModel->GetBuildItems()->Count(), 1); + + auto pReadModel = wrapper->CreateModel(); + { + auto reader3MF = pReadModel->QueryReader("3mf"); + reader3MF->ReadFromBuffer(buffer); + } + ExpectEqModels(m_pModel, pReadModel); + } + + + class MergeModels2 : public Lib3MFTest { + protected: + virtual void SetUp() { + m_pModel = wrapper->CreateModel(); + auto reader3MF = m_pModel->QueryReader("3mf"); + reader3MF->ReadFromFile(sTestFilesPath + "/Models/" + "platform.3mf"); + + } + virtual void TearDown() { + m_pModel.reset(); + } + + PModel m_pModel; + }; + + TEST_F(MergeModels2, MergeModel) + { + std::vector buffer; + auto pMergedModel = m_pModel->MergeToModel(); + { + auto writer3MF = pMergedModel->QueryWriter("3mf"); + writer3MF->WriteToBuffer(buffer); } ExpectEqModels(m_pModel, pMergedModel); diff --git a/Tests/TestFiles/Models/platform.3mf b/Tests/TestFiles/Models/platform.3mf new file mode 100644 index 0000000000000000000000000000000000000000..1cbd2c05c0d513420a780dc8d2ab16577fcd8dd9 GIT binary patch literal 85670 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%0D;U0t|!7xBV?C@6~LbE8JG+Cy; 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

E$ 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 XK^6w|lvKA{Px!YCbd;V4f4co2jW)T; literal 0 HcmV?d00001 From 428948968c56be69c5964f8f7c7c4a86952be6c8 Mon Sep 17 00:00:00 2001 From: Martin Weismann <30837766+martinweismann@users.noreply.github.com> Date: Wed, 15 Sep 2021 11:47:38 +0200 Subject: [PATCH 02/54] Clarify behavior of Attachment::ReadFrom*-methods --- AutomaticComponentToolkit/lib3mf.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 954cbdedd..26b0c171e 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -1013,10 +1013,10 @@ - + - + @@ -1028,7 +1028,7 @@ - + + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + + /* BIO *bio; */ /* this is now in the BIO struct */ + int ibuf_size; /* how big is the input buffer */ + int obuf_size; /* how big is the output buffer */ + + char *ibuf; /* the char array */ + int ibuf_len; /* how many bytes are in it */ + int ibuf_off; /* write/read offset */ + + char *obuf; /* the char array */ + int obuf_len; /* how many bytes are in it */ + int obuf_off; /* write/read offset */ +} BIO_F_BUFFER_CTX; + +__END_HIDDEN_DECLS + +#endif /* !HEADER_BIO_LOCAL_H */ diff --git a/Libraries/libressl/crypto/bio/bio_meth.c b/Libraries/libressl/crypto/bio/bio_meth.c new file mode 100644 index 000000000..37f866a0c --- /dev/null +++ b/Libraries/libressl/crypto/bio/bio_meth.c @@ -0,0 +1,165 @@ +/* $OpenBSD: bio_meth.c,v 1.9 2023/07/05 21:23:37 beck Exp $ */ +/* + * Copyright (c) 2018 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "bio_local.h" + +BIO_METHOD * +BIO_meth_new(int type, const char *name) +{ + BIO_METHOD *biom; + + if ((biom = calloc(1, sizeof(*biom))) == NULL) + return NULL; + + biom->type = type; + biom->name = name; + + return biom; +} +LCRYPTO_ALIAS(BIO_meth_new); + +void +BIO_meth_free(BIO_METHOD *biom) +{ + free(biom); +} +LCRYPTO_ALIAS(BIO_meth_free); + +int +(*BIO_meth_get_write(const BIO_METHOD *biom))(BIO *, const char *, int) +{ + return biom->bwrite; +} +LCRYPTO_ALIAS(BIO_meth_get_write); + +int +BIO_meth_set_write(BIO_METHOD *biom, int (*write)(BIO *, const char *, int)) +{ + biom->bwrite = write; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_write); + +int +(*BIO_meth_get_read(const BIO_METHOD *biom))(BIO *, char *, int) +{ + return biom->bread; +} +LCRYPTO_ALIAS(BIO_meth_get_read); + +int +BIO_meth_set_read(BIO_METHOD *biom, int (*read)(BIO *, char *, int)) +{ + biom->bread = read; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_read); + +int +(*BIO_meth_get_puts(const BIO_METHOD *biom))(BIO *, const char *) +{ + return biom->bputs; +} +LCRYPTO_ALIAS(BIO_meth_get_puts); + +int +BIO_meth_set_puts(BIO_METHOD *biom, int (*puts)(BIO *, const char *)) +{ + biom->bputs = puts; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_puts); + +int +(*BIO_meth_get_gets(const BIO_METHOD *biom))(BIO *, char *, int) +{ + return biom->bgets; +} +LCRYPTO_ALIAS(BIO_meth_get_gets); + +int +BIO_meth_set_gets(BIO_METHOD *biom, int (*gets)(BIO *, char *, int)) +{ + biom->bgets = gets; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_gets); + +long +(*BIO_meth_get_ctrl(const BIO_METHOD *biom))(BIO *, int, long, void *) +{ + return biom->ctrl; +} +LCRYPTO_ALIAS(BIO_meth_get_ctrl); + +int +BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl)(BIO *, int, long, void *)) +{ + biom->ctrl = ctrl; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_ctrl); + +int +(*BIO_meth_get_create(const BIO_METHOD *biom))(BIO *) +{ + return biom->create; +} +LCRYPTO_ALIAS(BIO_meth_get_create); + +int +BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *)) +{ + biom->create = create; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_create); + +int +(*BIO_meth_get_destroy(const BIO_METHOD *biom))(BIO *) +{ + return biom->destroy; +} +LCRYPTO_ALIAS(BIO_meth_get_destroy); + +int +BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *)) +{ + biom->destroy = destroy; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_destroy); + +long +(*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))(BIO *, int, BIO_info_cb *) +{ + return biom->callback_ctrl; +} +LCRYPTO_ALIAS(BIO_meth_get_callback_ctrl); + +int +BIO_meth_set_callback_ctrl(BIO_METHOD *biom, + long (*callback_ctrl)(BIO *, int, BIO_info_cb *)) +{ + biom->callback_ctrl = callback_ctrl; + return 1; +} +LCRYPTO_ALIAS(BIO_meth_set_callback_ctrl); diff --git a/Libraries/libressl/crypto/bio/bss_acpt.c b/Libraries/libressl/crypto/bio/bss_acpt.c new file mode 100644 index 000000000..d74c710a7 --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_acpt.c @@ -0,0 +1,456 @@ +/* $OpenBSD: bss_acpt.c,v 1.31 2023/07/05 21:23:37 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "bio_local.h" + +#define SOCKET_PROTOCOL IPPROTO_TCP + +typedef struct bio_accept_st { + int state; + char *param_addr; + + int accept_sock; + int accept_nbio; + + char *addr; + int nbio; + /* If 0, it means normal, if 1, do a connect on bind failure, + * and if there is no-one listening, bind with SO_REUSEADDR. + * If 2, always use SO_REUSEADDR. */ + int bind_mode; + BIO *bio_chain; +} BIO_ACCEPT; + +static int acpt_write(BIO *h, const char *buf, int num); +static int acpt_read(BIO *h, char *buf, int size); +static int acpt_puts(BIO *h, const char *str); +static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int acpt_new(BIO *h); +static int acpt_free(BIO *data); +static int acpt_state(BIO *b, BIO_ACCEPT *c); +static void acpt_close_socket(BIO *data); +static BIO_ACCEPT *BIO_ACCEPT_new(void ); +static void BIO_ACCEPT_free(BIO_ACCEPT *a); + +#define ACPT_S_BEFORE 1 +#define ACPT_S_GET_ACCEPT_SOCKET 2 +#define ACPT_S_OK 3 + +static const BIO_METHOD methods_acceptp = { + .type = BIO_TYPE_ACCEPT, + .name = "socket accept", + .bwrite = acpt_write, + .bread = acpt_read, + .bputs = acpt_puts, + .ctrl = acpt_ctrl, + .create = acpt_new, + .destroy = acpt_free +}; + +const BIO_METHOD * +BIO_s_accept(void) +{ + return (&methods_acceptp); +} +LCRYPTO_ALIAS(BIO_s_accept); + +static int +acpt_new(BIO *bi) +{ + BIO_ACCEPT *ba; + + bi->init = 0; + bi->num = -1; + bi->flags = 0; + if ((ba = BIO_ACCEPT_new()) == NULL) + return (0); + bi->ptr = (char *)ba; + ba->state = ACPT_S_BEFORE; + bi->shutdown = 1; + return (1); +} + +static BIO_ACCEPT * +BIO_ACCEPT_new(void) +{ + BIO_ACCEPT *ret; + + if ((ret = calloc(1, sizeof(BIO_ACCEPT))) == NULL) + return (NULL); + ret->accept_sock = -1; + ret->bind_mode = BIO_BIND_NORMAL; + return (ret); +} + +static void +BIO_ACCEPT_free(BIO_ACCEPT *a) +{ + if (a == NULL) + return; + + free(a->param_addr); + free(a->addr); + BIO_free(a->bio_chain); + free(a); +} + +static void +acpt_close_socket(BIO *bio) +{ + BIO_ACCEPT *c; + + c = (BIO_ACCEPT *)bio->ptr; + if (c->accept_sock != -1) { + shutdown(c->accept_sock, SHUT_RDWR); + close(c->accept_sock); + c->accept_sock = -1; + bio->num = -1; + } +} + +static int +acpt_free(BIO *a) +{ + BIO_ACCEPT *data; + + if (a == NULL) + return (0); + data = (BIO_ACCEPT *)a->ptr; + + if (a->shutdown) { + acpt_close_socket(a); + BIO_ACCEPT_free(data); + a->ptr = NULL; + a->flags = 0; + a->init = 0; + } + return (1); +} + +static int +acpt_state(BIO *b, BIO_ACCEPT *c) +{ + BIO *bio = NULL, *dbio; + int s = -1; + int i; + +again: + switch (c->state) { + case ACPT_S_BEFORE: + if (c->param_addr == NULL) { + BIOerror(BIO_R_NO_ACCEPT_PORT_SPECIFIED); + return (-1); + } + s = BIO_get_accept_socket(c->param_addr, c->bind_mode); + if (s == -1) + return (-1); + + if (c->accept_nbio) { + if (!BIO_socket_nbio(s, 1)) { + close(s); + BIOerror(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET); + return (-1); + } + } + c->accept_sock = s; + b->num = s; + c->state = ACPT_S_GET_ACCEPT_SOCKET; + return (1); + /* break; */ + case ACPT_S_GET_ACCEPT_SOCKET: + if (b->next_bio != NULL) { + c->state = ACPT_S_OK; + goto again; + } + BIO_clear_retry_flags(b); + b->retry_reason = 0; + i = BIO_accept(c->accept_sock, &(c->addr)); + + /* -2 return means we should retry */ + if (i == -2) { + BIO_set_retry_special(b); + b->retry_reason = BIO_RR_ACCEPT; + return -1; + } + + if (i < 0) + return (i); + + bio = BIO_new_socket(i, BIO_CLOSE); + if (bio == NULL) + goto err; + + BIO_set_callback(bio, BIO_get_callback(b)); + BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); + + if (c->nbio) { + if (!BIO_socket_nbio(i, 1)) { + BIOerror(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET); + goto err; + } + } + + /* If the accept BIO has an bio_chain, we dup it and + * put the new socket at the end. */ + if (c->bio_chain != NULL) { + if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) + goto err; + if (!BIO_push(dbio, bio)) goto err; + bio = dbio; + } + if (BIO_push(b, bio) + == NULL) goto err; + + c->state = ACPT_S_OK; + return (1); + +err: + if (bio != NULL) + BIO_free(bio); + return (0); + /* break; */ + case ACPT_S_OK: + if (b->next_bio == NULL) { + c->state = ACPT_S_GET_ACCEPT_SOCKET; + goto again; + } + return (1); + /* break; */ + default: + return (0); + /* break; */ + } +} + +static int +acpt_read(BIO *b, char *out, int outl) +{ + int ret = 0; + BIO_ACCEPT *data; + + BIO_clear_retry_flags(b); + data = (BIO_ACCEPT *)b->ptr; + + while (b->next_bio == NULL) { + ret = acpt_state(b, data); + if (ret <= 0) + return (ret); + } + + ret = BIO_read(b->next_bio, out, outl); + BIO_copy_next_retry(b); + return (ret); +} + +static int +acpt_write(BIO *b, const char *in, int inl) +{ + int ret; + BIO_ACCEPT *data; + + BIO_clear_retry_flags(b); + data = (BIO_ACCEPT *)b->ptr; + + while (b->next_bio == NULL) { + ret = acpt_state(b, data); + if (ret <= 0) + return (ret); + } + + ret = BIO_write(b->next_bio, in, inl); + BIO_copy_next_retry(b); + return (ret); +} + +static long +acpt_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + int *ip; + long ret = 1; + BIO_ACCEPT *data; + char **pp; + + data = (BIO_ACCEPT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = ACPT_S_BEFORE; + acpt_close_socket(b); + b->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + ret = (long)acpt_state(b, data); + break; + case BIO_C_SET_ACCEPT: + if (ptr != NULL) { + if (num == 0) { + b->init = 1; + free(data->param_addr); + data->param_addr = strdup(ptr); + } else if (num == 1) { + data->accept_nbio = (ptr != NULL); + } else if (num == 2) { + BIO_free(data->bio_chain); + data->bio_chain = (BIO *)ptr; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_SET_FD: + b->init = 1; + b->num= *((int *)ptr); + data->accept_sock = b->num; + data->state = ACPT_S_GET_ACCEPT_SOCKET; + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = data->accept_sock; + ret = data->accept_sock; + } else + ret = -1; + break; + case BIO_C_GET_ACCEPT: + if (b->init) { + if (ptr != NULL) { + pp = (char **)ptr; + *pp = data->param_addr; + } else + ret = -1; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_C_SET_BIND_MODE: + data->bind_mode = (int)num; + break; + case BIO_C_GET_BIND_MODE: + ret = (long)data->bind_mode; + break; + case BIO_CTRL_DUP: +/* dbio=(BIO *)ptr; + if (data->param_port) EAY EAY + BIO_set_port(dbio,data->param_port); + if (data->param_hostname) + BIO_set_hostname(dbio,data->param_hostname); + BIO_set_nbio(dbio,data->nbio); +*/ + break; + + default: + ret = 0; + break; + } + return (ret); +} + +static int +acpt_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = acpt_write(bp, str, n); + return (ret); +} + +BIO * +BIO_new_accept(const char *str) +{ + BIO *ret; + + ret = BIO_new(BIO_s_accept()); + if (ret == NULL) + return (NULL); + if (BIO_set_accept_port(ret, str)) + return (ret); + else { + BIO_free(ret); + return (NULL); + } +} +LCRYPTO_ALIAS(BIO_new_accept); diff --git a/Libraries/libressl/crypto/bio/bss_bio.c b/Libraries/libressl/crypto/bio/bss_bio.c new file mode 100644 index 000000000..9a3215a7d --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_bio.c @@ -0,0 +1,640 @@ +/* $OpenBSD: bss_bio.c,v 1.28 2023/07/28 10:13:50 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Special method for a BIO where the other endpoint is also a BIO + * of this kind, handled by the same thread (i.e. the "peer" is actually + * ourselves, wearing a different hat). + * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces + * for which no specific BIO method is available. + * See ssl/ssltest.c for some hints on how this can be used. */ + +/* BIO_DEBUG implies BIO_PAIR_DEBUG */ +#ifdef BIO_DEBUG +# ifndef BIO_PAIR_DEBUG +# define BIO_PAIR_DEBUG +# endif +#endif + +/* disable assert() unless BIO_PAIR_DEBUG has been defined */ +#ifndef BIO_PAIR_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "bio_local.h" + +static int bio_new(BIO *bio); +static int bio_free(BIO *bio); +static int bio_read(BIO *bio, char *buf, int size); +static int bio_write(BIO *bio, const char *buf, int num); +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); +static int bio_puts(BIO *bio, const char *str); + +static int bio_make_pair(BIO *bio1, BIO *bio2); +static void bio_destroy_pair(BIO *bio); + +static const BIO_METHOD methods_biop = { + .type = BIO_TYPE_BIO, + .name = "BIO pair", + .bwrite = bio_write, + .bread = bio_read, + .bputs = bio_puts, + .ctrl = bio_ctrl, + .create = bio_new, + .destroy = bio_free +}; + +const BIO_METHOD * +BIO_s_bio(void) +{ + return &methods_biop; +} +LCRYPTO_ALIAS(BIO_s_bio); + +struct bio_bio_st { + BIO *peer; /* NULL if buf == NULL. + * If peer != NULL, then peer->ptr is also a bio_bio_st, + * and its "peer" member points back to us. + * peer != NULL iff init != 0 in the BIO. */ + + /* This is for what we write (i.e. reading uses peer's struct): */ + int closed; /* valid iff peer != NULL */ + size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ + size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ + size_t size; + char *buf; /* "size" elements (if != NULL) */ + + size_t request; /* valid iff peer != NULL; 0 if len != 0, + * otherwise set by peer to number of bytes + * it (unsuccessfully) tried to read, + * never more than buffer space (size-len) warrants. */ +}; + +static int +bio_new(BIO *bio) +{ + struct bio_bio_st *b; + + b = malloc(sizeof *b); + if (b == NULL) + return 0; + + b->peer = NULL; + b->size = 17 * 1024; /* enough for one TLS record (just a default) */ + b->buf = NULL; + + bio->ptr = b; + return 1; +} + +static int +bio_free(BIO *bio) +{ + struct bio_bio_st *b; + + if (bio == NULL) + return 0; + b = bio->ptr; + + assert(b != NULL); + + if (b->peer) + bio_destroy_pair(bio); + + free(b->buf); + free(b); + return 1; +} + + + +static int +bio_read(BIO *bio, char *buf, int size_) +{ + size_t size = size_; + size_t rest; + struct bio_bio_st *b, *peer_b; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + peer_b = b->peer->ptr; + assert(peer_b != NULL); + assert(peer_b->buf != NULL); + + peer_b->request = 0; /* will be set in "retry_read" situation */ + + if (buf == NULL || size == 0) + return 0; + + if (peer_b->len == 0) { + if (peer_b->closed) + return 0; /* writer has closed, and no data is left */ + else { + BIO_set_retry_read(bio); /* buffer is empty */ + if (size <= peer_b->size) + peer_b->request = size; + else + /* don't ask for more than the peer can + * deliver in one write */ + peer_b->request = peer_b->size; + return -1; + } + } + + /* we can read */ + if (peer_b->len < size) + size = peer_b->len; + + /* now read "size" bytes */ + + rest = size; + + assert(rest > 0); + do /* one or two iterations */ + { + size_t chunk; + + assert(rest <= peer_b->len); + if (peer_b->offset + rest <= peer_b->size) + chunk = rest; + else + /* wrap around ring buffer */ + chunk = peer_b->size - peer_b->offset; + assert(peer_b->offset + chunk <= peer_b->size); + + memcpy(buf, peer_b->buf + peer_b->offset, chunk); + + peer_b->len -= chunk; + if (peer_b->len) { + peer_b->offset += chunk; + assert(peer_b->offset <= peer_b->size); + if (peer_b->offset == peer_b->size) + peer_b->offset = 0; + buf += chunk; + } else { + /* buffer now empty, no need to advance "buf" */ + assert(chunk == rest); + peer_b->offset = 0; + } + rest -= chunk; + } while (rest); + + return size; +} + +static int +bio_write(BIO *bio, const char *buf, int num_) +{ + size_t num = num_; + size_t rest; + struct bio_bio_st *b; + + BIO_clear_retry_flags(bio); + + if (!bio->init || buf == NULL || num == 0) + return 0; + + b = bio->ptr; + + assert(b != NULL); + assert(b->peer != NULL); + assert(b->buf != NULL); + + b->request = 0; + if (b->closed) { + /* we already closed */ + BIOerror(BIO_R_BROKEN_PIPE); + return -1; + } + + assert(b->len <= b->size); + + if (b->len == b->size) { + BIO_set_retry_write(bio); /* buffer is full */ + return -1; + } + + /* we can write */ + if (num > b->size - b->len) + num = b->size - b->len; + + /* now write "num" bytes */ + + rest = num; + + assert(rest > 0); + do /* one or two iterations */ + { + size_t write_offset; + size_t chunk; + + assert(b->len + rest <= b->size); + + write_offset = b->offset + b->len; + if (write_offset >= b->size) + write_offset -= b->size; + /* b->buf[write_offset] is the first byte we can write to. */ + + if (write_offset + rest <= b->size) + chunk = rest; + else + /* wrap around ring buffer */ + chunk = b->size - write_offset; + + memcpy(b->buf + write_offset, buf, chunk); + + b->len += chunk; + + assert(b->len <= b->size); + + rest -= chunk; + buf += chunk; + } while (rest); + + return num; +} + +static long +bio_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret; + struct bio_bio_st *b = bio->ptr; + + assert(b != NULL); + + switch (cmd) { + /* specific CTRL codes */ + + case BIO_C_SET_WRITE_BUF_SIZE: + if (b->peer) { + BIOerror(BIO_R_IN_USE); + ret = 0; + } else if (num == 0) { + BIOerror(BIO_R_INVALID_ARGUMENT); + ret = 0; + } else { + size_t new_size = num; + + if (b->size != new_size) { + free(b->buf); + b->buf = NULL; + b->size = new_size; + } + ret = 1; + } + break; + + case BIO_C_GET_WRITE_BUF_SIZE: + ret = (long) b->size; + break; + + case BIO_C_MAKE_BIO_PAIR: + { + BIO *other_bio = ptr; + + if (bio_make_pair(bio, other_bio)) + ret = 1; + else + ret = 0; + } + break; + + case BIO_C_DESTROY_BIO_PAIR: + /* Affects both BIOs in the pair -- call just once! + * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ + bio_destroy_pair(bio); + ret = 1; + break; + + case BIO_C_GET_WRITE_GUARANTEE: + /* How many bytes can the caller feed to the next write + * without having to keep any? */ + if (b->peer == NULL || b->closed) + ret = 0; + else + ret = (long) b->size - b->len; + break; + + case BIO_C_GET_READ_REQUEST: + /* If the peer unsuccessfully tried to read, how many bytes + * were requested? (As with BIO_CTRL_PENDING, that number + * can usually be treated as boolean.) */ + ret = (long) b->request; + break; + + case BIO_C_RESET_READ_REQUEST: + /* Reset request. (Can be useful after read attempts + * at the other side that are meant to be non-blocking, + * e.g. when probing SSL_read to see if any data is + * available.) */ + b->request = 0; + ret = 1; + break; + + case BIO_C_SHUTDOWN_WR: + /* similar to shutdown(..., SHUT_WR) */ + b->closed = 1; + ret = 1; + break; + + /* standard CTRL codes follow */ + + case BIO_CTRL_RESET: + if (b->buf != NULL) { + b->len = 0; + b->offset = 0; + } + ret = 0; + break; + + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int) num; + ret = 1; + break; + + case BIO_CTRL_PENDING: + if (b->peer != NULL) { + struct bio_bio_st *peer_b = b->peer->ptr; + + ret = (long) peer_b->len; + } else + ret = 0; + break; + + case BIO_CTRL_WPENDING: + if (b->buf != NULL) + ret = (long) b->len; + else + ret = 0; + break; + + case BIO_CTRL_DUP: + /* See BIO_dup_chain for circumstances we have to expect. */ + { + BIO *other_bio = ptr; + struct bio_bio_st *other_b; + + assert(other_bio != NULL); + other_b = other_bio->ptr; + assert(other_b != NULL); + + assert(other_b->buf == NULL); /* other_bio is always fresh */ + + other_b->size = b->size; + } + + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_EOF: + { + BIO *other_bio = ptr; + + if (other_bio) { + struct bio_bio_st *other_b = other_bio->ptr; + + assert(other_b != NULL); + ret = other_b->len == 0 && other_b->closed; + } else + ret = 1; + } + break; + + default: + ret = 0; + } + return ret; +} + +static int +bio_puts(BIO *bio, const char *str) +{ + return bio_write(bio, str, strlen(str)); +} + + +static int +bio_make_pair(BIO *bio1, BIO *bio2) +{ + struct bio_bio_st *b1, *b2; + + assert(bio1 != NULL); + assert(bio2 != NULL); + + b1 = bio1->ptr; + b2 = bio2->ptr; + + if (b1->peer != NULL || b2->peer != NULL) { + BIOerror(BIO_R_IN_USE); + return 0; + } + + if (b1->buf == NULL) { + b1->buf = malloc(b1->size); + if (b1->buf == NULL) { + BIOerror(ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf == NULL) { + b2->buf = malloc(b2->size); + if (b2->buf == NULL) { + BIOerror(ERR_R_MALLOC_FAILURE); + return 0; + } + b2->len = 0; + b2->offset = 0; + } + + b1->peer = bio2; + b1->closed = 0; + b1->request = 0; + b2->peer = bio1; + b2->closed = 0; + b2->request = 0; + + bio1->init = 1; + bio2->init = 1; + + return 1; +} + +static void +bio_destroy_pair(BIO *bio) +{ + struct bio_bio_st *b = bio->ptr; + + if (b != NULL) { + BIO *peer_bio = b->peer; + + if (peer_bio != NULL) { + struct bio_bio_st *peer_b = peer_bio->ptr; + + assert(peer_b != NULL); + assert(peer_b->peer == bio); + + peer_b->peer = NULL; + peer_bio->init = 0; + assert(peer_b->buf != NULL); + peer_b->len = 0; + peer_b->offset = 0; + + b->peer = NULL; + bio->init = 0; + assert(b->buf != NULL); + b->len = 0; + b->offset = 0; + } + } +} + + +/* Exported convenience functions */ +int +BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2) +{ + BIO *bio1 = NULL, *bio2 = NULL; + long r; + int ret = 0; + + bio1 = BIO_new(BIO_s_bio()); + if (bio1 == NULL) + goto err; + bio2 = BIO_new(BIO_s_bio()); + if (bio2 == NULL) + goto err; + + if (writebuf1) { + r = BIO_set_write_buf_size(bio1, writebuf1); + if (!r) + goto err; + } + if (writebuf2) { + r = BIO_set_write_buf_size(bio2, writebuf2); + if (!r) + goto err; + } + + r = BIO_make_bio_pair(bio1, bio2); + if (!r) + goto err; + ret = 1; + + err: + if (ret == 0) { + if (bio1) { + BIO_free(bio1); + bio1 = NULL; + } + if (bio2) { + BIO_free(bio2); + bio2 = NULL; + } + } + + *bio1_p = bio1; + *bio2_p = bio2; + return ret; +} + +size_t +BIO_ctrl_get_write_guarantee(BIO *bio) +{ + return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); +} +LCRYPTO_ALIAS(BIO_ctrl_get_write_guarantee); + +size_t +BIO_ctrl_get_read_request(BIO *bio) +{ + return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); +} +LCRYPTO_ALIAS(BIO_ctrl_get_read_request); + +int +BIO_ctrl_reset_read_request(BIO *bio) +{ + return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); +} +LCRYPTO_ALIAS(BIO_ctrl_reset_read_request); diff --git a/Libraries/libressl/crypto/bio/bss_conn.c b/Libraries/libressl/crypto/bio/bss_conn.c new file mode 100644 index 000000000..427bd4b9e --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_conn.c @@ -0,0 +1,598 @@ +/* $OpenBSD: bss_conn.c,v 1.39 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "bio_local.h" + +#define SOCKET_PROTOCOL IPPROTO_TCP + +typedef struct bio_connect_st { + int state; + + char *param_hostname; + char *param_port; + int nbio; + + unsigned char ip[4]; + unsigned short port; + + struct sockaddr_in them; + + /* int socket; this will be kept in bio->num so that it is + * compatible with the bss_sock bio */ + + /* called when the connection is initially made + * callback(BIO,state,ret); The callback should return + * 'ret'. state is for compatibility with the ssl info_callback */ + BIO_info_cb *info_callback; +} BIO_CONNECT; + +static int conn_write(BIO *h, const char *buf, int num); +static int conn_read(BIO *h, char *buf, int size); +static int conn_puts(BIO *h, const char *str); +static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int conn_new(BIO *h); +static int conn_free(BIO *data); +static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *); + +static int conn_state(BIO *b, BIO_CONNECT *c); +static void conn_close_socket(BIO *data); +BIO_CONNECT *BIO_CONNECT_new(void); +void BIO_CONNECT_free(BIO_CONNECT *a); + +static const BIO_METHOD methods_connectp = { + .type = BIO_TYPE_CONNECT, + .name = "socket connect", + .bwrite = conn_write, + .bread = conn_read, + .bputs = conn_puts, + .ctrl = conn_ctrl, + .create = conn_new, + .destroy = conn_free, + .callback_ctrl = conn_callback_ctrl +}; + +static int +conn_state(BIO *b, BIO_CONNECT *c) +{ + int ret = -1, i; + unsigned long l; + char *p, *q; + BIO_info_cb *cb = NULL; + + if (c->info_callback != NULL) + cb = c->info_callback; + + for (;;) { + switch (c->state) { + case BIO_CONN_S_BEFORE: + p = c->param_hostname; + if (p == NULL) { + BIOerror(BIO_R_NO_HOSTNAME_SPECIFIED); + goto exit_loop; + } + for (; *p != '\0'; p++) { + if ((*p == ':') || (*p == '/')) + break; + } + + i= *p; + if ((i == ':') || (i == '/')) { + *(p++) = '\0'; + if (i == ':') { + for (q = p; *q; q++) + if (*q == '/') { + *q = '\0'; + break; + } + free(c->param_port); + c->param_port = strdup(p); + } + } + + if (c->param_port == NULL) { + BIOerror(BIO_R_NO_PORT_SPECIFIED); + ERR_asprintf_error_data("host=%s", + c->param_hostname); + goto exit_loop; + } + c->state = BIO_CONN_S_GET_IP; + break; + + case BIO_CONN_S_GET_IP: + if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0) + goto exit_loop; + c->state = BIO_CONN_S_GET_PORT; + break; + + case BIO_CONN_S_GET_PORT: + if (c->param_port == NULL) { + /* abort(); */ + goto exit_loop; + } else if (BIO_get_port(c->param_port, &c->port) <= 0) + goto exit_loop; + c->state = BIO_CONN_S_CREATE_SOCKET; + break; + + case BIO_CONN_S_CREATE_SOCKET: + /* now setup address */ + memset((char *)&c->them, 0, sizeof(c->them)); + c->them.sin_family = AF_INET; + c->them.sin_port = htons((unsigned short)c->port); + l = (unsigned long) + ((unsigned long)c->ip[0] << 24L)| + ((unsigned long)c->ip[1] << 16L)| + ((unsigned long)c->ip[2] << 8L)| + ((unsigned long)c->ip[3]); + c->them.sin_addr.s_addr = htonl(l); + c->state = BIO_CONN_S_CREATE_SOCKET; + + ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); + if (ret == -1) { + SYSerror(errno); + ERR_asprintf_error_data("host=%s:%s", + c->param_hostname, c->param_port); + BIOerror(BIO_R_UNABLE_TO_CREATE_SOCKET); + goto exit_loop; + } + b->num = ret; + c->state = BIO_CONN_S_NBIO; + break; + + case BIO_CONN_S_NBIO: + if (c->nbio) { + if (!BIO_socket_nbio(b->num, 1)) { + BIOerror(BIO_R_ERROR_SETTING_NBIO); + ERR_asprintf_error_data("host=%s:%s", + c->param_hostname, c->param_port); + goto exit_loop; + } + } + c->state = BIO_CONN_S_CONNECT; + +#if defined(SO_KEEPALIVE) + i = 1; + i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i)); + if (i < 0) { + SYSerror(errno); + ERR_asprintf_error_data("host=%s:%s", + c->param_hostname, c->param_port); + BIOerror(BIO_R_KEEPALIVE); + goto exit_loop; + } +#endif + break; + + case BIO_CONN_S_CONNECT: + BIO_clear_retry_flags(b); + ret = connect(b->num, + (struct sockaddr *)&c->them, + sizeof(c->them)); + b->retry_reason = 0; + if (ret < 0) { + if (BIO_sock_should_retry(ret)) { + BIO_set_retry_special(b); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + b->retry_reason = BIO_RR_CONNECT; + } else { + SYSerror(errno); + ERR_asprintf_error_data("host=%s:%s", + c->param_hostname, c->param_port); + BIOerror(BIO_R_CONNECT_ERROR); + } + goto exit_loop; + } else + c->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = BIO_sock_error(b->num); + if (i) { + BIO_clear_retry_flags(b); + SYSerror(i); + ERR_asprintf_error_data("host=%s:%s", + c->param_hostname, c->param_port); + BIOerror(BIO_R_NBIO_CONNECT_ERROR); + ret = 0; + goto exit_loop; + } else + c->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + default: + /* abort(); */ + goto exit_loop; + } + + if (cb != NULL) { + if (!(ret = cb((BIO *)b, c->state, ret))) + goto end; + } + } + + /* Loop does not exit */ +exit_loop: + if (cb != NULL) + ret = cb((BIO *)b, c->state, ret); +end: + return (ret); +} + +BIO_CONNECT * +BIO_CONNECT_new(void) +{ + BIO_CONNECT *ret; + + if ((ret = malloc(sizeof(BIO_CONNECT))) == NULL) + return (NULL); + ret->state = BIO_CONN_S_BEFORE; + ret->param_hostname = NULL; + ret->param_port = NULL; + ret->info_callback = NULL; + ret->nbio = 0; + ret->ip[0] = 0; + ret->ip[1] = 0; + ret->ip[2] = 0; + ret->ip[3] = 0; + ret->port = 0; + memset((char *)&ret->them, 0, sizeof(ret->them)); + return (ret); +} + +void +BIO_CONNECT_free(BIO_CONNECT *a) +{ + if (a == NULL) + return; + + free(a->param_hostname); + free(a->param_port); + free(a); +} + +const BIO_METHOD * +BIO_s_connect(void) +{ + return (&methods_connectp); +} +LCRYPTO_ALIAS(BIO_s_connect); + +static int +conn_new(BIO *bi) +{ + bi->init = 0; + bi->num = -1; + bi->flags = 0; + if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL) + return (0); + else + return (1); +} + +static void +conn_close_socket(BIO *bio) +{ + BIO_CONNECT *c; + + c = (BIO_CONNECT *)bio->ptr; + if (bio->num != -1) { + /* Only do a shutdown if things were established */ + if (c->state == BIO_CONN_S_OK) + shutdown(bio->num, SHUT_RDWR); + close(bio->num); + bio->num = -1; + } +} + +static int +conn_free(BIO *a) +{ + BIO_CONNECT *data; + + if (a == NULL) + return (0); + data = (BIO_CONNECT *)a->ptr; + + if (a->shutdown) { + conn_close_socket(a); + BIO_CONNECT_free(data); + a->ptr = NULL; + a->flags = 0; + a->init = 0; + } + return (1); +} + +static int +conn_read(BIO *b, char *out, int outl) +{ + int ret = 0; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(b, data); + if (ret <= 0) + return (ret); + } + + if (out != NULL) { + errno = 0; + ret = read(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int +conn_write(BIO *b, const char *in, int inl) +{ + int ret; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(b, data); + if (ret <= 0) + return (ret); + } + + errno = 0; + ret = write(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long +conn_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + int *ip; + const char **pptr; + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = BIO_CONN_S_BEFORE; + conn_close_socket(b); + b->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + if (data->state != BIO_CONN_S_OK) + ret = (long)conn_state(b, data); + else + ret = 1; + break; + case BIO_C_GET_CONNECT: + if (ptr != NULL) { + pptr = (const char **)ptr; + if (num == 0) { + *pptr = data->param_hostname; + + } else if (num == 1) { + *pptr = data->param_port; + } else if (num == 2) { + *pptr = (char *)&(data->ip[0]); + } else if (num == 3) { + *((int *)ptr) = data->port; + } + if ((!b->init) || (ptr == NULL)) + *pptr = "not initialized"; + ret = 1; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL) { + b->init = 1; + if (num == 0) { + free(data->param_hostname); + data->param_hostname = strdup(ptr); + } else if (num == 1) { + free(data->param_port); + data->param_port = strdup(ptr); + } else if (num == 2) { + unsigned char *p = ptr; + free(data->param_hostname); + if (asprintf(&data->param_hostname, + "%u.%u.%u.%u", p[0], p[1], + p[2], p[3]) == -1) + data->param_hostname = NULL; + memcpy(&(data->ip[0]), ptr, 4); + } else if (num == 3) { + free(data->param_port); + data->port= *(int *)ptr; + if (asprintf(&data->param_port, "%d", + data->port) == -1) + data->param_port = NULL; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_CTRL_DUP: + { + dbio = (BIO *)ptr; + if (data->param_port) + BIO_set_conn_port(dbio, data->param_port); + if (data->param_hostname) + BIO_set_conn_hostname(dbio, + data->param_hostname); + BIO_set_nbio(dbio, data->nbio); + (void)BIO_set_info_callback(dbio, data->info_callback); + } + break; + case BIO_CTRL_SET_CALLBACK: + { +#if 0 /* FIXME: Should this be used? -- Richard Levitte */ + BIOerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ret = -1; +#else + ret = 0; +#endif + } + break; + case BIO_CTRL_GET_CALLBACK: + { + BIO_info_cb **fptr = ptr; + + *fptr = data->info_callback; + } + break; + default: + ret = 0; + break; + } + return (ret); +} + +static long +conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + data->info_callback = (BIO_info_cb *)fp; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int +conn_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = conn_write(bp, str, n); + return (ret); +} + +BIO * +BIO_new_connect(const char *str) +{ + BIO *ret; + + ret = BIO_new(BIO_s_connect()); + if (ret == NULL) + return (NULL); + if (BIO_set_conn_hostname(ret, str)) + return (ret); + else { + BIO_free(ret); + return (NULL); + } +} +LCRYPTO_ALIAS(BIO_new_connect); diff --git a/Libraries/libressl/crypto/bio/bss_dgram.c b/Libraries/libressl/crypto/bio/bss_dgram.c new file mode 100644 index 000000000..65a8f6fae --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_dgram.c @@ -0,0 +1,663 @@ +/* $OpenBSD: bss_dgram.c,v 1.45 2023/07/05 21:23:37 beck Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include "bio_local.h" + +#ifndef OPENSSL_NO_DGRAM + + +static int dgram_write(BIO *h, const char *buf, int num); +static int dgram_read(BIO *h, char *buf, int size); +static int dgram_puts(BIO *h, const char *str); +static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int dgram_new(BIO *h); +static int dgram_free(BIO *data); +static int dgram_clear(BIO *bio); + + +static int BIO_dgram_should_retry(int s); + +static const BIO_METHOD methods_dgramp = { + .type = BIO_TYPE_DGRAM, + .name = "datagram socket", + .bwrite = dgram_write, + .bread = dgram_read, + .bputs = dgram_puts, + .ctrl = dgram_ctrl, + .create = dgram_new, + .destroy = dgram_free +}; + + +typedef struct bio_dgram_data_st { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_in6 sa_in6; + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct timeval next_timeout; + struct timeval socket_timeout; +} bio_dgram_data; + + +const BIO_METHOD * +BIO_s_datagram(void) +{ + return (&methods_dgramp); +} +LCRYPTO_ALIAS(BIO_s_datagram); + +BIO * +BIO_new_dgram(int fd, int close_flag) +{ + BIO *ret; + + ret = BIO_new(BIO_s_datagram()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} +LCRYPTO_ALIAS(BIO_new_dgram); + +static int +dgram_new(BIO *bi) +{ + bio_dgram_data *data = NULL; + + bi->init = 0; + bi->num = 0; + data = calloc(1, sizeof(bio_dgram_data)); + if (data == NULL) + return 0; + bi->ptr = data; + + bi->flags = 0; + return (1); +} + +static int +dgram_free(BIO *a) +{ + bio_dgram_data *data; + + if (a == NULL) + return (0); + if (!dgram_clear(a)) + return 0; + + data = (bio_dgram_data *)a->ptr; + free(data); + + return (1); +} + +static int +dgram_clear(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + shutdown(a->num, SHUT_RDWR); + close(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static void +dgram_adjust_rcv_timeout(BIO *b) +{ +#if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { + struct timeval timenow, timeleft; + + /* Read current socket timeout */ + socklen_t sz = sizeof(data->socket_timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + &(data->socket_timeout), &sz) < 0) { + perror("getsockopt"); + } + + /* Get current time */ + gettimeofday(&timenow, NULL); + + /* Calculate time left until timer expires */ + memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); + timeleft.tv_sec -= timenow.tv_sec; + timeleft.tv_usec -= timenow.tv_usec; + if (timeleft.tv_usec < 0) { + timeleft.tv_sec--; + timeleft.tv_usec += 1000000; + } + + if (timeleft.tv_sec < 0) { + timeleft.tv_sec = 0; + timeleft.tv_usec = 1; + } + + /* Adjust socket timeout if next handshake message timer + * will expire earlier. + */ + if ((data->socket_timeout.tv_sec == 0 && + data->socket_timeout.tv_usec == 0) || + (data->socket_timeout.tv_sec > timeleft.tv_sec) || + (data->socket_timeout.tv_sec == timeleft.tv_sec && + data->socket_timeout.tv_usec >= timeleft.tv_usec)) { + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + &timeleft, sizeof(struct timeval)) < 0) { + perror("setsockopt"); + } + } + } +#endif +} + +static void +dgram_reset_rcv_timeout(BIO *b) +{ +#if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + &(data->socket_timeout), sizeof(struct timeval)) < 0) { + perror("setsockopt"); + } + } +#endif +} + +static int +dgram_read(BIO *b, char *out, int outl) +{ + int ret = 0; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + struct { + socklen_t len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_in6 sa_in6; + } peer; + } sa; + + sa.len = sizeof(sa.peer); + + if (out != NULL) { + errno = 0; + memset(&sa.peer, 0, sizeof(sa.peer)); + dgram_adjust_rcv_timeout(b); + ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, &sa.len); + + if (! data->connected && ret >= 0) + BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); + + BIO_clear_retry_flags(b); + if (ret < 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_read(b); + data->_errno = errno; + } + } + + dgram_reset_rcv_timeout(b); + } + return (ret); +} + +static int +dgram_write(BIO *b, const char *in, int inl) +{ + int ret; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + errno = 0; + + if (data->connected) + ret = write(b->num, in, inl); + else { + int peerlen = sizeof(data->peer); + + if (data->peer.sa.sa_family == AF_INET) + peerlen = sizeof(data->peer.sa_in); + else if (data->peer.sa.sa_family == AF_INET6) + peerlen = sizeof(data->peer.sa_in6); + ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); + } + + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_write(b); + + data->_errno = errno; + /* + * higher layers are responsible for querying MTU, + * if necessary + */ + } + } + return (ret); +} + +static long +dgram_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + struct sockaddr *to = NULL; + bio_dgram_data *data = NULL; +#if (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) + int sockopt_val = 0; + socklen_t sockopt_len; /* assume that system supporting IP_MTU is + * modern enough to define socklen_t */ + socklen_t addr_len; + union { + struct sockaddr sa; + struct sockaddr_in s4; + struct sockaddr_in6 s6; + } addr; +#endif + + data = (bio_dgram_data *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + case BIO_C_FILE_SEEK: + ret = 0; + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SET_FD: + dgram_clear(b); + b->num= *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + case BIO_CTRL_DGRAM_CONNECT: + to = (struct sockaddr *)ptr; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + break; + /* (Linux)kernel sets DF bit on outgoing IP packets */ + case BIO_CTRL_DGRAM_MTU_DISCOVER: +#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) + addr_len = (socklen_t)sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { + ret = 0; + break; + } + switch (addr.sa.sa_family) { + case AF_INET: + sockopt_val = IP_PMTUDISC_DO; + ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val)); + if (ret < 0) + perror("setsockopt"); + break; +#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) + case AF_INET6: + sockopt_val = IPV6_PMTUDISC_DO; + ret = setsockopt(b->num, IPPROTO_IPV6, + IPV6_MTU_DISCOVER, &sockopt_val, + sizeof(sockopt_val)); + if (ret < 0) + perror("setsockopt"); + break; +#endif + default: + ret = -1; + break; + } +#else + ret = -1; +#endif + break; + case BIO_CTRL_DGRAM_QUERY_MTU: +#if defined(IP_MTU) + addr_len = (socklen_t)sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { + ret = 0; + break; + } + sockopt_len = sizeof(sockopt_val); + switch (addr.sa.sa_family) { + case AF_INET: + ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, + &sockopt_val, &sockopt_len); + if (ret < 0 || sockopt_val < 0) { + ret = 0; + } else { + /* we assume that the transport protocol is UDP and no + * IP options are used. + */ + data->mtu = sockopt_val - 8 - 20; + ret = data->mtu; + } + break; +#if defined(IPV6_MTU) + case AF_INET6: + ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, + &sockopt_val, &sockopt_len); + if (ret < 0 || sockopt_val < 0) { + ret = 0; + } else { + /* we assume that the transport protocol is UDP and no + * IPV6 options are used. + */ + data->mtu = sockopt_val - 8 - 40; + ret = data->mtu; + } + break; +#endif +default: + ret = 0; + break; + } +#else + ret = 0; +#endif + break; + case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: + switch (data->peer.sa.sa_family) { + case AF_INET: + ret = 576 - 20 - 8; + break; + case AF_INET6: +#ifdef IN6_IS_ADDR_V4MAPPED + if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) + ret = 576 - 20 - 8; + else +#endif + ret = 1280 - 40 - 8; + break; + default: + ret = 576 - 20 - 8; + break; + } + break; + case BIO_CTRL_DGRAM_GET_MTU: + return data->mtu; + break; + case BIO_CTRL_DGRAM_SET_MTU: + data->mtu = num; + ret = num; + break; + case BIO_CTRL_DGRAM_SET_CONNECTED: + to = (struct sockaddr *)ptr; + + if (to != NULL) { + data->connected = 1; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + } else { + data->connected = 0; + memset(&(data->peer), 0, sizeof(data->peer)); + } + break; + case BIO_CTRL_DGRAM_GET_PEER: + switch (data->peer.sa.sa_family) { + case AF_INET: + ret = sizeof(data->peer.sa_in); + break; + case AF_INET6: + ret = sizeof(data->peer.sa_in6); + break; + default: + ret = sizeof(data->peer.sa); + break; + } + if (num == 0 || num > ret) + num = ret; + memcpy(ptr, &data->peer, (ret = num)); + break; + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *) ptr; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + break; + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + break; +#if defined(SO_RCVTIMEO) + case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + ret = -1; + } + break; + case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: + { + socklen_t sz = sizeof(struct timeval); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + ptr, &sz) < 0) { + perror("getsockopt"); + ret = -1; + } else + ret = sz; + } + break; +#endif +#if defined(SO_SNDTIMEO) + case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + ret = -1; + } + break; + case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: + { + socklen_t sz = sizeof(struct timeval); + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + ptr, &sz) < 0) { + perror("getsockopt"); + ret = -1; + } else + ret = sz; + } + break; +#endif + case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: + /* fall-through */ + case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: + if (data->_errno == EAGAIN) { + ret = 1; + data->_errno = 0; + } else + ret = 0; + break; +#ifdef EMSGSIZE + case BIO_CTRL_DGRAM_MTU_EXCEEDED: + if (data->_errno == EMSGSIZE) { + ret = 1; + data->_errno = 0; + } else + ret = 0; + break; +#endif + default: + ret = 0; + break; + } + return (ret); +} + +static int +dgram_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = dgram_write(bp, str, n); + return (ret); +} + + +static int +BIO_dgram_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = errno; + return (BIO_dgram_non_fatal_error(err)); + } + return (0); +} + +int +BIO_dgram_non_fatal_error(int err) +{ + switch (err) { + case EINTR: + case EAGAIN: + case EINPROGRESS: + case EALREADY: + return (1); + default: + break; + } + return (0); +} +LCRYPTO_ALIAS(BIO_dgram_non_fatal_error); + +#endif diff --git a/Libraries/libressl/crypto/bio/bss_fd.c b/Libraries/libressl/crypto/bio/bss_fd.c new file mode 100644 index 000000000..63eac3232 --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_fd.c @@ -0,0 +1,273 @@ +/* $OpenBSD: bss_fd.c,v 1.21 2023/07/05 21:23:37 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include + +#include "bio_local.h" + +static int fd_write(BIO *h, const char *buf, int num); +static int fd_read(BIO *h, char *buf, int size); +static int fd_puts(BIO *h, const char *str); +static int fd_gets(BIO *h, char *buf, int size); +static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int fd_new(BIO *h); +static int fd_free(BIO *data); +int BIO_fd_should_retry(int s); + +static const BIO_METHOD methods_fdp = { + .type = BIO_TYPE_FD, + .name = "file descriptor", + .bwrite = fd_write, + .bread = fd_read, + .bputs = fd_puts, + .bgets = fd_gets, + .ctrl = fd_ctrl, + .create = fd_new, + .destroy = fd_free +}; + +const BIO_METHOD * +BIO_s_fd(void) +{ + return (&methods_fdp); +} +LCRYPTO_ALIAS(BIO_s_fd); + +BIO * +BIO_new_fd(int fd, int close_flag) +{ + BIO *ret; + ret = BIO_new(BIO_s_fd()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} +LCRYPTO_ALIAS(BIO_new_fd); + +static int +fd_new(BIO *bi) +{ + bi->init = 0; + bi->num = -1; + bi->ptr = NULL; + bi->flags=0; + return (1); +} + +static int +fd_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + close(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static int +fd_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out != NULL) { + errno = 0; + ret = read(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_fd_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int +fd_write(BIO *b, const char *in, int inl) +{ + int ret; + errno = 0; + ret = write(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_fd_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long +fd_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + case BIO_C_FILE_SEEK: + ret = (long)lseek(b->num, num, 0); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = (long)lseek(b->num, 0, 1); + break; + case BIO_C_SET_FD: + fd_free(b); + b->num= *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int +fd_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = fd_write(bp, str, n); + return (ret); +} + +static int +fd_gets(BIO *bp, char *buf, int size) +{ + int ret = 0; + char *ptr = buf; + char *end = buf + size - 1; + + while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n')) + ptr++; + + ptr[0] = '\0'; + + if (buf[0] != '\0') + ret = strlen(buf); + return (ret); +} + +int +BIO_fd_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = errno; + return (BIO_fd_non_fatal_error(err)); + } + return (0); +} +LCRYPTO_ALIAS(BIO_fd_should_retry); + +int +BIO_fd_non_fatal_error(int err) +{ + switch (err) { + case ENOTCONN: + case EINTR: + case EAGAIN: + case EINPROGRESS: + case EALREADY: + return (1); + default: + break; + } + return (0); +} +LCRYPTO_ALIAS(BIO_fd_non_fatal_error); diff --git a/Libraries/libressl/crypto/bio/bss_file.c b/Libraries/libressl/crypto/bio/bss_file.c new file mode 100644 index 000000000..9b6ca2bdd --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_file.c @@ -0,0 +1,325 @@ +/* $OpenBSD: bss_file.c,v 1.35 2023/07/05 21:23:37 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout + * with binary data (e.g. asn1parse -inform DER < xxx) under + * Windows + */ + +#ifndef HEADER_BSS_FILE_C +#define HEADER_BSS_FILE_C + +#if defined(__linux) || defined(__sun) || defined(__hpux) +/* Following definition aliases fopen to fopen64 on above mentioned + * platforms. This makes it possible to open and sequentially access + * files larger than 2GB from 32-bit application. It does not allow to + * traverse them beyond 2GB with fseek/ftell, but on the other hand *no* + * 32-bit platform permits that, not with fseek/ftell. Not to mention + * that breaking 2GB limit for seeking would require surgery to *our* + * API. But sequential access suffices for practical cases when you + * can run into large files, such as fingerprinting, so we can let API + * alone. For reference, the list of 32-bit platforms which allow for + * sequential access of large files without extra "magic" comprise *BSD, + * Darwin, IRIX... + */ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif +#endif + +#include +#include +#include + +#include +#include + +#include "bio_local.h" + +static int file_write(BIO *h, const char *buf, int num); +static int file_read(BIO *h, char *buf, int size); +static int file_puts(BIO *h, const char *str); +static int file_gets(BIO *h, char *str, int size); +static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int file_new(BIO *h); +static int file_free(BIO *data); + +static const BIO_METHOD methods_filep = { + .type = BIO_TYPE_FILE, + .name = "FILE pointer", + .bwrite = file_write, + .bread = file_read, + .bputs = file_puts, + .bgets = file_gets, + .ctrl = file_ctrl, + .create = file_new, + .destroy = file_free +}; + +BIO * +BIO_new_file(const char *filename, const char *mode) +{ + BIO *ret; + FILE *file = NULL; + + file = fopen(filename, mode); + + if (file == NULL) { + SYSerror(errno); + ERR_asprintf_error_data("fopen('%s', '%s')", filename, mode); + if (errno == ENOENT) + BIOerror(BIO_R_NO_SUCH_FILE); + else + BIOerror(ERR_R_SYS_LIB); + return (NULL); + } + if ((ret = BIO_new(BIO_s_file())) == NULL) { + fclose(file); + return (NULL); + } + + BIO_set_fp(ret, file, BIO_CLOSE); + return (ret); +} +LCRYPTO_ALIAS(BIO_new_file); + +BIO * +BIO_new_fp(FILE *stream, int close_flag) +{ + BIO *ret; + + if ((ret = BIO_new(BIO_s_file())) == NULL) + return (NULL); + + BIO_set_fp(ret, stream, close_flag); + return (ret); +} +LCRYPTO_ALIAS(BIO_new_fp); + +const BIO_METHOD * +BIO_s_file(void) +{ + return (&methods_filep); +} +LCRYPTO_ALIAS(BIO_s_file); + +static int +file_new(BIO *bi) +{ + bi->init = 0; + bi->num = 0; + bi->ptr = NULL; + bi->flags=0; + return (1); +} + +static int +file_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if ((a->init) && (a->ptr != NULL)) { + fclose (a->ptr); + a->ptr = NULL; + a->flags = 0; + } + a->init = 0; + } + return (1); +} + +static int +file_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (b->init && out != NULL) { + ret = fread(out, 1, outl, (FILE *)b->ptr); + if (ret == 0 && ferror((FILE *)b->ptr)) { + SYSerror(errno); + BIOerror(ERR_R_SYS_LIB); + ret = -1; + } + } + return (ret); +} + +static int +file_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + + if (b->init && in != NULL) + ret = fwrite(in, 1, inl, (FILE *)b->ptr); + return (ret); +} + +static long +file_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + FILE *fp = (FILE *)b->ptr; + FILE **fpp; + char p[4]; + + switch (cmd) { + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + ret = (long)fseek(fp, num, 0); + break; + case BIO_CTRL_EOF: + ret = (long)feof(fp); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = ftell(fp); + break; + case BIO_C_SET_FILE_PTR: + file_free(b); + b->shutdown = (int)num&BIO_CLOSE; + b->ptr = ptr; + b->init = 1; + break; + case BIO_C_SET_FILENAME: + file_free(b); + b->shutdown = (int)num&BIO_CLOSE; + if (num & BIO_FP_APPEND) { + if (num & BIO_FP_READ) + strlcpy(p, "a+", sizeof p); + else strlcpy(p, "a", sizeof p); + } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) + strlcpy(p, "r+", sizeof p); + else if (num & BIO_FP_WRITE) + strlcpy(p, "w", sizeof p); + else if (num & BIO_FP_READ) + strlcpy(p, "r", sizeof p); + else { + BIOerror(BIO_R_BAD_FOPEN_MODE); + ret = 0; + break; + } + fp = fopen(ptr, p); + if (fp == NULL) { + SYSerror(errno); + ERR_asprintf_error_data("fopen('%s', '%s')", ptr, p); + BIOerror(ERR_R_SYS_LIB); + ret = 0; + break; + } + b->ptr = fp; + b->init = 1; + break; + case BIO_C_GET_FILE_PTR: + /* the ptr parameter is actually a FILE ** in this case. */ + if (ptr != NULL) { + fpp = (FILE **)ptr; + *fpp = (FILE *)b->ptr; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_FLUSH: + fflush((FILE *)b->ptr); + break; + case BIO_CTRL_DUP: + ret = 1; + break; + + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + return (ret); +} + +static int +file_gets(BIO *bp, char *buf, int size) +{ + int ret = 0; + + buf[0] = '\0'; + if (!fgets(buf, size,(FILE *)bp->ptr)) + goto err; + if (buf[0] != '\0') + ret = strlen(buf); +err: + return (ret); +} + +static int +file_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = file_write(bp, str, n); + return (ret); +} + + +#endif /* HEADER_BSS_FILE_C */ diff --git a/Libraries/libressl/crypto/bio/bss_log.c b/Libraries/libressl/crypto/bio/bss_log.c new file mode 100644 index 000000000..9e2e88264 --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_log.c @@ -0,0 +1,216 @@ +/* $OpenBSD: bss_log.c,v 1.24 2023/07/05 21:23:37 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + Why BIO_s_log? + + BIO_s_log is useful for system daemons (or services under NT). + It is one-way BIO, it sends all stuff to syslogd (on system that + commonly use that), or event log (on NT), or OPCOM (on OpenVMS). + +*/ + +#include +#include +#include +#include + +#include +#include + +#include "bio_local.h" + +#ifndef NO_SYSLOG + +static int slg_write(BIO *h, const char *buf, int num); +static int slg_puts(BIO *h, const char *str); +static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int slg_new(BIO *h); +static int slg_free(BIO *data); +static void xopenlog(BIO* bp, char* name, int level); +static void xsyslog(BIO* bp, int priority, const char* string); +static void xcloselog(BIO* bp); + +static const BIO_METHOD methods_slg = { + .type = BIO_TYPE_MEM, + .name = "syslog", + .bwrite = slg_write, + .bputs = slg_puts, + .ctrl = slg_ctrl, + .create = slg_new, + .destroy = slg_free +}; + +const BIO_METHOD * +BIO_s_log(void) +{ + return (&methods_slg); +} +LCRYPTO_ALIAS(BIO_s_log); + +static int +slg_new(BIO *bi) +{ + bi->init = 1; + bi->num = 0; + bi->ptr = NULL; + xopenlog(bi, "application", LOG_DAEMON); + return (1); +} + +static int +slg_free(BIO *a) +{ + if (a == NULL) + return (0); + xcloselog(a); + return (1); +} + +static int +slg_write(BIO *b, const char *in, int inl) +{ + int ret = inl; + char* buf; + char* pp; + int priority, i; + static const struct { + int strl; + char str[10]; + int log_level; + } + mapping[] = { + { 6, "PANIC ", LOG_EMERG }, + { 6, "EMERG ", LOG_EMERG }, + { 4, "EMR ", LOG_EMERG }, + { 6, "ALERT ", LOG_ALERT }, + { 4, "ALR ", LOG_ALERT }, + { 5, "CRIT ", LOG_CRIT }, + { 4, "CRI ", LOG_CRIT }, + { 6, "ERROR ", LOG_ERR }, + { 4, "ERR ", LOG_ERR }, + { 8, "WARNING ", LOG_WARNING }, + { 5, "WARN ", LOG_WARNING }, + { 4, "WAR ", LOG_WARNING }, + { 7, "NOTICE ", LOG_NOTICE }, + { 5, "NOTE ", LOG_NOTICE }, + { 4, "NOT ", LOG_NOTICE }, + { 5, "INFO ", LOG_INFO }, + { 4, "INF ", LOG_INFO }, + { 6, "DEBUG ", LOG_DEBUG }, + { 4, "DBG ", LOG_DEBUG }, + { 0, "", LOG_ERR } /* The default */ + }; + + if ((buf = malloc(inl + 1)) == NULL) { + return (0); + } + strlcpy(buf, in, inl + 1); + i = 0; + while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) + i++; + priority = mapping[i].log_level; + pp = buf + mapping[i].strl; + + xsyslog(b, priority, pp); + + free(buf); + return (ret); +} + +static long +slg_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + switch (cmd) { + case BIO_CTRL_SET: + xcloselog(b); + xopenlog(b, ptr, num); + break; + default: + break; + } + return (0); +} + +static int +slg_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = slg_write(bp, str, n); + return (ret); +} + + +static void +xopenlog(BIO* bp, char* name, int level) +{ + openlog(name, LOG_PID|LOG_CONS, level); +} + +static void +xsyslog(BIO *bp, int priority, const char *string) +{ + syslog(priority, "%s", string); +} + +static void +xcloselog(BIO* bp) +{ + closelog(); +} + +#endif /* NO_SYSLOG */ diff --git a/Libraries/libressl/crypto/bio/bss_mem.c b/Libraries/libressl/crypto/bio/bss_mem.c new file mode 100644 index 000000000..6d0d54db8 --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_mem.c @@ -0,0 +1,367 @@ +/* $OpenBSD: bss_mem.c,v 1.22 2023/07/05 21:23:37 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "bio_local.h" + +struct bio_mem { + BUF_MEM *buf; + size_t read_offset; +}; + +static size_t +bio_mem_pending(struct bio_mem *bm) +{ + if (bm->read_offset > bm->buf->length) + return 0; + + return bm->buf->length - bm->read_offset; +} + +static uint8_t * +bio_mem_read_ptr(struct bio_mem *bm) +{ + return &bm->buf->data[bm->read_offset]; +} + +static int mem_new(BIO *bio); +static int mem_free(BIO *bio); +static int mem_write(BIO *bio, const char *in, int in_len); +static int mem_read(BIO *bio, char *out, int out_len); +static int mem_puts(BIO *bio, const char *in); +static int mem_gets(BIO *bio, char *out, int out_len); +static long mem_ctrl(BIO *bio, int cmd, long arg1, void *arg2); + +static const BIO_METHOD mem_method = { + .type = BIO_TYPE_MEM, + .name = "memory buffer", + .bwrite = mem_write, + .bread = mem_read, + .bputs = mem_puts, + .bgets = mem_gets, + .ctrl = mem_ctrl, + .create = mem_new, + .destroy = mem_free +}; + +/* + * bio->num is used to hold the value to return on 'empty', if it is + * 0, should_retry is not set. + */ + +const BIO_METHOD * +BIO_s_mem(void) +{ + return &mem_method; +} +LCRYPTO_ALIAS(BIO_s_mem); + +BIO * +BIO_new_mem_buf(const void *buf, int buf_len) +{ + struct bio_mem *bm; + BIO *bio; + + if (buf == NULL) { + BIOerror(BIO_R_NULL_PARAMETER); + return NULL; + } + if (buf_len == -1) + buf_len = strlen(buf); + if (buf_len < 0) { + BIOerror(BIO_R_INVALID_ARGUMENT); + return NULL; + } + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + return NULL; + + bm = bio->ptr; + bm->buf->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */ + bm->buf->length = buf_len; + bm->buf->max = buf_len; + bio->flags |= BIO_FLAGS_MEM_RDONLY; + /* Since this is static data retrying will not help. */ + bio->num = 0; + + return bio; +} +LCRYPTO_ALIAS(BIO_new_mem_buf); + +static int +mem_new(BIO *bio) +{ + struct bio_mem *bm; + + if ((bm = calloc(1, sizeof(*bm))) == NULL) + return 0; + if ((bm->buf = BUF_MEM_new()) == NULL) { + free(bm); + return 0; + } + + bio->shutdown = 1; + bio->init = 1; + bio->num = -1; + bio->ptr = bm; + + return 1; +} + +static int +mem_free(BIO *bio) +{ + struct bio_mem *bm; + + if (bio == NULL) + return 0; + if (!bio->init || bio->ptr == NULL) + return 1; + + bm = bio->ptr; + if (bio->shutdown) { + if (bio->flags & BIO_FLAGS_MEM_RDONLY) + bm->buf->data = NULL; + BUF_MEM_free(bm->buf); + } + free(bm); + bio->ptr = NULL; + + return 1; +} + +static int +mem_read(BIO *bio, char *out, int out_len) +{ + struct bio_mem *bm = bio->ptr; + + BIO_clear_retry_flags(bio); + + if (out == NULL || out_len <= 0) + return 0; + + if ((size_t)out_len > bio_mem_pending(bm)) + out_len = bio_mem_pending(bm); + + if (out_len == 0) { + if (bio->num != 0) + BIO_set_retry_read(bio); + return bio->num; + } + + memcpy(out, bio_mem_read_ptr(bm), out_len); + bm->read_offset += out_len; + + return out_len; +} + +static int +mem_write(BIO *bio, const char *in, int in_len) +{ + struct bio_mem *bm = bio->ptr; + size_t buf_len; + + BIO_clear_retry_flags(bio); + + if (in == NULL || in_len <= 0) + return 0; + + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + BIOerror(BIO_R_WRITE_TO_READ_ONLY_BIO); + return -1; + } + + if (bm->read_offset > 4096) { + memmove(bm->buf->data, bio_mem_read_ptr(bm), + bio_mem_pending(bm)); + bm->buf->length = bio_mem_pending(bm); + bm->read_offset = 0; + } + + /* + * Check for overflow and ensure we do not exceed an int, otherwise we + * cannot tell if BUF_MEM_grow_clean() succeeded. + */ + buf_len = bm->buf->length + in_len; + if (buf_len < bm->buf->length || buf_len > INT_MAX) + return -1; + + if (BUF_MEM_grow_clean(bm->buf, buf_len) != buf_len) + return -1; + + memcpy(&bm->buf->data[buf_len - in_len], in, in_len); + + return in_len; +} + +static long +mem_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + struct bio_mem *bm = bio->ptr; + void **pptr; + long ret = 1; + + switch (cmd) { + case BIO_CTRL_RESET: + if (bm->buf->data != NULL) { + if (!(bio->flags & BIO_FLAGS_MEM_RDONLY)) { + memset(bm->buf->data, 0, bm->buf->max); + bm->buf->length = 0; + } + bm->read_offset = 0; + } + break; + case BIO_CTRL_EOF: + ret = (long)(bio_mem_pending(bm) == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + bio->num = (int)num; + break; + case BIO_CTRL_INFO: + if (ptr != NULL) { + pptr = (void **)ptr; + *pptr = bio_mem_read_ptr(bm); + } + ret = (long)bio_mem_pending(bm); + break; + case BIO_C_SET_BUF_MEM: + BUF_MEM_free(bm->buf); + bio->shutdown = (int)num; + bm->buf = ptr; + bm->read_offset = 0; + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { + pptr = (void **)ptr; + *pptr = bm->buf; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)bio_mem_pending(bm); + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + return ret; +} + +static int +mem_gets(BIO *bio, char *out, int out_len) +{ + struct bio_mem *bm = bio->ptr; + int i, out_max; + char *p; + int ret = -1; + + BIO_clear_retry_flags(bio); + + out_max = bio_mem_pending(bm); + if (out_len - 1 < out_max) + out_max = out_len - 1; + if (out_max <= 0) { + *out = '\0'; + return 0; + } + + p = bio_mem_read_ptr(bm); + for (i = 0; i < out_max; i++) { + if (p[i] == '\n') { + i++; + break; + } + } + + /* + * i is now the max num of bytes to copy, either out_max or up to and + * including the first newline + */ + if ((ret = mem_read(bio, out, i)) > 0) + out[ret] = '\0'; + + return ret; +} + +static int +mem_puts(BIO *bio, const char *in) +{ + return mem_write(bio, in, strlen(in)); +} diff --git a/Libraries/libressl/crypto/bio/bss_null.c b/Libraries/libressl/crypto/bio/bss_null.c new file mode 100644 index 000000000..5f9340967 --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_null.c @@ -0,0 +1,161 @@ +/* $OpenBSD: bss_null.c,v 1.13 2023/07/05 21:23:37 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include "bio_local.h" + +static int null_write(BIO *h, const char *buf, int num); +static int null_read(BIO *h, char *buf, int size); +static int null_puts(BIO *h, const char *str); +static int null_gets(BIO *h, char *str, int size); +static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int null_new(BIO *h); +static int null_free(BIO *data); + +static const BIO_METHOD null_method = { + .type = BIO_TYPE_NULL, + .name = "NULL", + .bwrite = null_write, + .bread = null_read, + .bputs = null_puts, + .bgets = null_gets, + .ctrl = null_ctrl, + .create = null_new, + .destroy = null_free +}; + +const BIO_METHOD * +BIO_s_null(void) +{ + return (&null_method); +} +LCRYPTO_ALIAS(BIO_s_null); + +static int +null_new(BIO *bi) +{ + bi->init = 1; + bi->num = 0; + bi->ptr = (NULL); + return (1); +} + +static int +null_free(BIO *a) +{ + if (a == NULL) + return (0); + return (1); +} + +static int +null_read(BIO *b, char *out, int outl) +{ + return (0); +} + +static int +null_write(BIO *b, const char *in, int inl) +{ + return (inl); +} + +static long +null_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) { + case BIO_CTRL_RESET: + case BIO_CTRL_EOF: + case BIO_CTRL_SET: + case BIO_CTRL_SET_CLOSE: + case BIO_CTRL_FLUSH: + case BIO_CTRL_DUP: + ret = 1; + break; + case BIO_CTRL_GET_CLOSE: + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + default: + ret = 0; + break; + } + return (ret); +} + +static int +null_gets(BIO *bp, char *buf, int size) +{ + return (0); +} + +static int +null_puts(BIO *bp, const char *str) +{ + if (str == NULL) + return (0); + return (strlen(str)); +} diff --git a/Libraries/libressl/crypto/bio/bss_sock.c b/Libraries/libressl/crypto/bio/bss_sock.c new file mode 100644 index 000000000..79194a7e5 --- /dev/null +++ b/Libraries/libressl/crypto/bio/bss_sock.c @@ -0,0 +1,244 @@ +/* $OpenBSD: bss_sock.c,v 1.27 2023/08/07 10:54:14 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include + +#include "bio_local.h" + +static int sock_write(BIO *h, const char *buf, int num); +static int sock_read(BIO *h, char *buf, int size); +static int sock_puts(BIO *h, const char *str); +static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int sock_new(BIO *h); +static int sock_free(BIO *data); +int BIO_sock_should_retry(int s); + +static const BIO_METHOD methods_sockp = { + .type = BIO_TYPE_SOCKET, + .name = "socket", + .bwrite = sock_write, + .bread = sock_read, + .bputs = sock_puts, + .ctrl = sock_ctrl, + .create = sock_new, + .destroy = sock_free +}; + +const BIO_METHOD * +BIO_s_socket(void) +{ + return (&methods_sockp); +} +LCRYPTO_ALIAS(BIO_s_socket); + +BIO * +BIO_new_socket(int fd, int close_flag) +{ + BIO *ret; + + ret = BIO_new(BIO_s_socket()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} +LCRYPTO_ALIAS(BIO_new_socket); + +static int +sock_new(BIO *bi) +{ + bi->init = 0; + bi->num = 0; + bi->ptr = NULL; + bi->flags = 0; + return (1); +} + +static int +sock_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + shutdown(a->num, SHUT_RDWR); + close(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static int +sock_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out != NULL) { + errno = 0; + ret = read(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int +sock_write(BIO *b, const char *in, int inl) +{ + int ret; + + errno = 0; + ret = write(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long +sock_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_C_SET_FD: + sock_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int +sock_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = sock_write(bp, str, n); + return (ret); +} + +int +BIO_sock_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = errno; + return (BIO_sock_non_fatal_error(err)); + } + return (0); +} +LCRYPTO_ALIAS(BIO_sock_should_retry); + +int +BIO_sock_non_fatal_error(int err) +{ + switch (err) { + case ENOTCONN: + case EINTR: + case EAGAIN: + case EINPROGRESS: + case EALREADY: + return (1); + default: + break; + } + return (0); +} +LCRYPTO_ALIAS(BIO_sock_non_fatal_error); diff --git a/Libraries/libressl/crypto/bn/arch/aarch64/bn_arch.h b/Libraries/libressl/crypto/bn/arch/aarch64/bn_arch.h new file mode 100644 index 000000000..fe6f8a3ae --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/aarch64/bn_arch.h @@ -0,0 +1,369 @@ +/* $OpenBSD: bn_arch.h,v 1.13 2023/07/24 10:21:29 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#if defined(__GNUC__) + +#define HAVE_BN_CLZW + +static inline int +bn_clzw(BN_ULONG w) +{ + BN_ULONG n; + + __asm__ ("clz %[n], %[w]" + : [n]"=r"(n) + : [w]"r"(w)); + + return n; +} + +#define HAVE_BN_ADDW + +static inline void +bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG carry, r0; + + __asm__ ( + "adds %[r0], %[a], %[b] \n" + "cset %[carry], cs \n" + : [carry]"=r"(carry), [r0]"=r"(r0) + : [a]"r"(a), [b]"r"(b) + : "cc"); + + *out_r1 = carry; + *out_r0 = r0; +} + +#define HAVE_BN_ADDW_ADDW + +static inline void +bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULONG carry, r0; + + __asm__ ( + "adds %[r0], %[a], %[b] \n" + "cset %[carry], cs \n" + "adds %[r0], %[r0], %[c] \n" + "cinc %[carry], %[carry], cs \n" + : [carry]"=&r"(carry), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b), [c]"r"(c) + : "cc"); + + *out_r1 = carry; + *out_r0 = r0; +} + +#define HAVE_BN_QWADDQW + +static inline void +bn_qwaddqw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b3, + BN_ULONG b2, BN_ULONG b1, BN_ULONG b0, BN_ULONG carry, BN_ULONG *out_carry, + BN_ULONG *out_r3, BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r3, r2, r1, r0; + + __asm__ ( + "adds xzr, %[carry], #-1 \n" + "adcs %[r0], %[a0], %[b0] \n" + "adcs %[r1], %[a1], %[b1] \n" + "adcs %[r2], %[a2], %[b2] \n" + "adcs %[r3], %[a3], %[b3] \n" + "cset %[carry], cs \n" + : [carry]"+r"(carry), [r3]"=&r"(r3), [r2]"=&r"(r2), + [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a3]"r"(a3), [a2]"r"(a2), [a1]"r"(a1), [a0]"r"(a0), + [b3]"r"(b3), [b2]"r"(b2), [b1]"r"(b1), [b0]"r"(b0) + : "cc"); + + *out_carry = carry; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_MULW + +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + /* Unsigned multiplication using a umulh/mul pair. */ + __asm__ ( + "umulh %[r1], %[a], %[b] \n" + "mul %[r0], %[a], %[b] \n" + : [r1]"=&r"(r1), [r0]"=r"(r0) + : [a]"r"(a), [b]"r"(b)); + + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_MULW_ADDW + +static inline void +bn_mulw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + __asm__ ( + "umulh %[r1], %[a], %[b] \n" + "mul %[r0], %[a], %[b] \n" + "adds %[r0], %[r0], %[c] \n" + "adc %[r1], %[r1], xzr \n" + : [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b), [c]"r"(c) + : "cc"); + + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_MULW_ADDW_ADDW + +static inline void +bn_mulw_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG d, + BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + __asm__ ( + "umulh %[r1], %[a], %[b] \n" + "mul %[r0], %[a], %[b] \n" + "adds %[r0], %[r0], %[c] \n" + "adc %[r1], %[r1], xzr \n" + "adds %[r0], %[r0], %[d] \n" + "adc %[r1], %[r1], xzr \n" + : [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b), [c]"r"(c), [d]"r"(d) + : "cc"); + + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_MULW_ADDTW + +static inline void +bn_mulw_addtw(BN_ULONG a, BN_ULONG b, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0, + BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r2, r1, r0; + + __asm__ ( + "umulh %[r1], %[a], %[b] \n" + "mul %[r0], %[a], %[b] \n" + "adds %[r0], %[r0], %[c0] \n" + "adcs %[r1], %[r1], %[c1] \n" + "adc %[r2], xzr, %[c2] \n" + : [r2]"=&r"(r2), [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b), [c2]"r"(c2), [c1]"r"(c1), [c0]"r"(c0) + : "cc"); + + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_MUL2_MULW_ADDTW + +static inline void +bn_mul2_mulw_addtw(BN_ULONG a, BN_ULONG b, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0, + BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r2, r1, r0, x1, x0; + + __asm__ ( + "umulh %[x1], %[a], %[b] \n" + "mul %[x0], %[a], %[b] \n" + "adds %[r0], %[c0], %[x0] \n" + "adcs %[r1], %[c1], %[x1] \n" + "adc %[r2], xzr, %[c2] \n" + "adds %[r0], %[r0], %[x0] \n" + "adcs %[r1], %[r1], %[x1] \n" + "adc %[r2], xzr, %[r2] \n" + : [r2]"=&r"(r2), [r1]"=&r"(r1), [r0]"=&r"(r0), [x1]"=&r"(x1), + [x0]"=&r"(x0) + : [a]"r"(a), [b]"r"(b), [c2]"r"(c2), [c1]"r"(c1), [c0]"r"(c0) + : "cc"); + + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_QWMULW_ADDW + +static inline void +bn_qwmulw_addw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b, + BN_ULONG c, BN_ULONG *out_r4, BN_ULONG *out_r3, BN_ULONG *out_r2, + BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r4, r3, r2, r1, r0; + + __asm__ ( + "umulh %[r1], %[a0], %[b] \n" + "mul %[r0], %[a0], %[b] \n" + "adds %[r0], %[r0], %[c] \n" + "umulh %[r2], %[a1], %[b] \n" + "mul %[c], %[a1], %[b] \n" + "adcs %[r1], %[r1], %[c] \n" + "umulh %[r3], %[a2], %[b] \n" + "mul %[c], %[a2], %[b] \n" + "adcs %[r2], %[r2], %[c] \n" + "umulh %[r4], %[a3], %[b] \n" + "mul %[c], %[a3], %[b] \n" + "adcs %[r3], %[r3], %[c] \n" + "adc %[r4], %[r4], xzr \n" + : [c]"+&r"(c), [r4]"=&r"(r4), [r3]"=&r"(r3), [r2]"=&r"(r2), + [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a3]"r"(a3), [a2]"r"(a2), [a1]"r"(a1), [a0]"r"(a0), [b]"r"(b) + : "cc"); + + *out_r4 = r4; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_QWMULW_ADDQW_ADDW + +static inline void +bn_qwmulw_addqw_addw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, + BN_ULONG b, BN_ULONG c3, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0, BN_ULONG d, + BN_ULONG *out_r4, BN_ULONG *out_r3, BN_ULONG *out_r2, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULONG r4, r3, r2, r1, r0; + + __asm__ ( + "umulh %[r1], %[a0], %[b] \n" + "mul %[r0], %[a0], %[b] \n" + "adds %[r0], %[r0], %[d] \n" + "umulh %[r2], %[a1], %[b] \n" + "mul %[d], %[a1], %[b] \n" + "adcs %[r1], %[r1], %[d] \n" + "umulh %[r3], %[a2], %[b] \n" + "mul %[d], %[a2], %[b] \n" + "adcs %[r2], %[r2], %[d] \n" + "umulh %[r4], %[a3], %[b] \n" + "mul %[d], %[a3], %[b] \n" + "adcs %[r3], %[r3], %[d] \n" + "adc %[r4], %[r4], xzr \n" + "adds %[r0], %[r0], %[c0] \n" + "adcs %[r1], %[r1], %[c1] \n" + "adcs %[r2], %[r2], %[c2] \n" + "adcs %[r3], %[r3], %[c3] \n" + "adc %[r4], %[r4], xzr \n" + : [d]"+&r"(d), [r4]"=&r"(r4), [r3]"=&r"(r3), [r2]"=&r"(r2), + [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a3]"r"(a3), [a2]"r"(a2), [a1]"r"(a1), [a0]"r"(a0), [b]"r"(b), + [c3]"r"(c3), [c2]"r"(c2), [c1]"r"(c1), [c0]"r"(c0) + : "cc"); + + *out_r4 = r4; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_SUBW + +static inline void +bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0) +{ + BN_ULONG borrow, r0; + + __asm__ ( + "subs %[r0], %[a], %[b] \n" + "cset %[borrow], cc \n" + : [borrow]"=r"(borrow), [r0]"=r"(r0) + : [a]"r"(a), [b]"r"(b) + : "cc"); + + *out_borrow = borrow; + *out_r0 = r0; +} + +#define HAVE_BN_SUBW_SUBW + +static inline void +bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow, + BN_ULONG *out_r0) +{ + BN_ULONG borrow, r0; + + __asm__ ( + "subs %[r0], %[a], %[b] \n" + "cset %[borrow], cc \n" + "subs %[r0], %[r0], %[c] \n" + "cinc %[borrow], %[borrow], cc \n" + : [borrow]"=&r"(borrow), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b), [c]"r"(c) + : "cc"); + + *out_borrow = borrow; + *out_r0 = r0; +} + +#define HAVE_BN_QWSUBQW + +static inline void +bn_qwsubqw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b3, + BN_ULONG b2, BN_ULONG b1, BN_ULONG b0, BN_ULONG borrow, BN_ULONG *out_borrow, + BN_ULONG *out_r3, BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r3, r2, r1, r0; + + __asm__ ( + "subs xzr, xzr, %[borrow] \n" + "sbcs %[r0], %[a0], %[b0] \n" + "sbcs %[r1], %[a1], %[b1] \n" + "sbcs %[r2], %[a2], %[b2] \n" + "sbcs %[r3], %[a3], %[b3] \n" + "cset %[borrow], cc \n" + : [borrow]"+r"(borrow), [r3]"=&r"(r3), [r2]"=&r"(r2), + [r1]"=&r"(r1), [r0]"=&r"(r0) + : [a3]"r"(a3), [a2]"r"(a2), [a1]"r"(a1), [a0]"r"(a0), + [b3]"r"(b3), [b2]"r"(b2), [b1]"r"(b1), [b0]"r"(b0) + : "cc"); + + *out_borrow = borrow; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} + +#endif /* __GNUC__ */ + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_add.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_add.S new file mode 100644 index 000000000..06298ca69 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_add.S @@ -0,0 +1,165 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Add, z := x + y +// Inputs x[m], y[n]; outputs function return (carry-out) and z[p] +// +// extern uint64_t bignum_add +// (uint64_t p, uint64_t *z, +// uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); +// +// Does the z := x + y operation, truncating modulo p words in general and +// returning a top carry (0 or 1) in the p'th place, only adding the input +// words below p (as well as m and n respectively) to get the sum and carry. +// +// Standard x86-64 ABI: RDI = p, RSI = z, RDX = m, RCX = x, R8 = n, R9 = y, returns RAX +// Microsoft x64 ABI: RCX = p, RDX = z, R8 = m, R9 = x, [RSP+40] = n, [RSP+48] = y, returns RAX +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_add) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_add) + .text + +#define p rdi +#define z rsi +#define m rdx +#define x rcx +#define n r8 +#define y r9 +#define i r10 +#define a rax + +#define ashort eax + + + +S2N_BN_SYMBOL(bignum_add): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] + mov r9, [rsp+64] +#endif + +// Zero the main index counter for both branches + + xor i, i + +// First clamp the two input sizes m := min(p,m) and n := min(p,n) since +// we'll never need words past the p'th. Can now assume m <= p and n <= p. +// Then compare the modified m and n and branch accordingly + + cmp p, m + cmovc m, p + cmp p, n + cmovc n, p + cmp m, n + jc ylonger + +// The case where x is longer or of the same size (p >= m >= n) + + sub p, m + sub m, n + inc m + test n, n + jz xtest +xmainloop: + mov a, [x+8*i] + adc a, [y+8*i] + mov [z+8*i],a + inc i + dec n + jnz xmainloop + jmp xtest +xtoploop: + mov a, [x+8*i] + adc a, 0 + mov [z+8*i],a + inc i +xtest: + dec m + jnz xtoploop + mov ashort, 0 + adc a, 0 + test p, p + jnz tails +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +// The case where y is longer (p >= n > m) + +ylonger: + + sub p, n + sub n, m + test m, m + jz ytoploop +ymainloop: + mov a, [x+8*i] + adc a, [y+8*i] + mov [z+8*i],a + inc i + dec m + jnz ymainloop +ytoploop: + mov a, [y+8*i] + adc a, 0 + mov [z+8*i],a + inc i + dec n + jnz ytoploop + mov ashort, 0 + adc a, 0 + test p, p + jnz tails +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +// Adding a non-trivial tail, when p > max(m,n) + +tails: + mov [z+8*i],a + xor a, a + jmp tail +tailloop: + mov [z+8*i],a +tail: + inc i + dec p + jnz tailloop +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_cmadd.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_cmadd.S new file mode 100644 index 000000000..5ad712749 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_cmadd.S @@ -0,0 +1,155 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Multiply-add with single-word multiplier, z := z + c * y +// Inputs c, y[n]; outputs function return (carry-out) and z[k] +// +// extern uint64_t bignum_cmadd +// (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); +// +// Does the "z := z + c * y" operation where y is n digits, result z is p. +// Truncates the result in general. +// +// The return value is a high/carry word that is meaningful when p = n + 1, or +// more generally when n <= p and the result fits in p + 1 digits. In these +// cases it gives the top digit of the (p + 1)-digit result. +// +// Standard x86-64 ABI: RDI = k, RSI = z, RDX = c, RCX = n, R8 = y, returns RAX +// Microsoft x64 ABI: RCX = k, RDX = z, R8 = c, R9 = n, [RSP+40] = y, returns RAX +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_cmadd) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_cmadd) + .text + +#define p rdi +#define z rsi +#define c r9 +#define n rcx +#define x r8 + +#define i r10 +#define h r11 + +#define r rbx + +#define hshort r11d +#define ishort r10d + + + +S2N_BN_SYMBOL(bignum_cmadd): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] +#endif + +// Seems hard to avoid one more register + + push rbx + +// First clamp the input size n := min(p,n) since we can never need to read +// past the p'th term of the input to generate p-digit output. +// Subtract p := p - min(n,p) so it holds the size of the extra tail needed + + cmp p, n + cmovc n, p + sub p, n + +// Initialize high part h = 0; if n = 0 do nothing but return that zero + + xor h, h + test n, n + jz end + +// Move c into a safer register as multiplies overwrite rdx + + mov c, rdx + +// Initialization of the loop: 2^64 * CF + [h,z_0'] = z_0 + c * x_0 + + mov rax, [x] + mul c + add [z], rax + mov h, rdx + mov ishort, 1 + dec n + jz hightail + +// Main loop, where we always have CF + previous high part h to add in + +loop: + adc h, [z+8*i] + sbb r, r + mov rax, [x+8*i] + mul c + sub rdx, r + add rax, h + mov [z+8*i], rax + mov h, rdx + inc i + dec n + jnz loop + +hightail: + adc h, 0 + +// Propagate the carry all the way to the end with h as extra carry word + +tail: + test p, p + jz end + + add [z+8*i], h + mov hshort, 0 + inc i + dec p + jz highend + +tloop: + adc [z+8*i], h + inc i + dec p + jnz tloop + +highend: + + adc h, 0 + +// Return the high/carry word + +end: + mov rax, h + + pop rbx +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_cmul.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_cmul.S new file mode 100644 index 000000000..9199c8f48 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_cmul.S @@ -0,0 +1,138 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Multiply by a single word, z := c * y +// Inputs c, y[n]; outputs function return (carry-out) and z[k] +// +// extern uint64_t bignum_cmul +// (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); +// +// Does the "z := c * y" operation where y is n digits, result z is p. +// Truncates the result in general unless p >= n + 1. +// +// The return value is a high/carry word that is meaningful when p >= n as +// giving the high part of the result. Since this is always zero if p > n, +// it is mainly of interest in the special case p = n, i.e. where the source +// and destination have the same nominal size, when it gives the extra word +// of the full result. +// +// Standard x86-64 ABI: RDI = k, RSI = z, RDX = c, RCX = n, R8 = y, returns RAX +// Microsoft x64 ABI: RCX = k, RDX = z, R8 = c, R9 = n, [RSP+40] = y, returns RAX +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_cmul) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_cmul) + .text + +#define p rdi +#define z rsi +#define c r9 +#define n rcx +#define x r8 + +#define i r10 +#define h r11 + + + +S2N_BN_SYMBOL(bignum_cmul): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] +#endif + +// First clamp the input size n := min(p,n) since we can never need to read +// past the p'th term of the input to generate p-digit output. Now we can +// assume that n <= p + + cmp p, n + cmovc n, p + +// Initialize current input/output pointer offset i and high part h. +// But then if n = 0 skip the multiplication and go to the tail part + + xor h, h + xor i, i + test n, n + jz tail + +// Move c into a safer register as multiplies overwrite rdx + + mov c, rdx + +// Initialization of the loop: [h,l] = c * x_0 + + mov rax, [x] + mul c + mov [z], rax + mov h, rdx + inc i + cmp i, n + jz tail + +// Main loop doing the multiplications + +loop: + mov rax, [x+8*i] + mul c + add rax, h + adc rdx, 0 + mov [z+8*i], rax + mov h, rdx + inc i + cmp i, n + jc loop + +// Add a tail when the destination is longer + +tail: + cmp i, p + jnc end + mov [z+8*i], h + xor h, h + inc i + cmp i, p + jnc end + +tloop: + mov [z+8*i], h + inc i + cmp i, p + jc tloop + +// Return the high/carry word + +end: + mov rax, h + +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul.S new file mode 100644 index 000000000..2d7ed1909 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul.S @@ -0,0 +1,167 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Multiply z := x * y +// Inputs x[m], y[n]; output z[k] +// +// extern void bignum_mul +// (uint64_t k, uint64_t *z, +// uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); +// +// Does the "z := x * y" operation where x is m digits, y is n, result z is k. +// Truncates the result in general unless k >= m + n +// +// Standard x86-64 ABI: RDI = k, RSI = z, RDX = m, RCX = x, R8 = n, R9 = y +// Microsoft x64 ABI: RCX = k, RDX = z, R8 = m, R9 = x, [RSP+40] = n, [RSP+48] = y +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul) + .text + +// These are actually right + +#define p rdi +#define z rsi +#define n r8 + +// These are not + +#define c r15 +#define h r14 +#define l r13 +#define x r12 +#define y r11 +#define i rbx +#define k r10 +#define m rbp + +// These are always local scratch since multiplier result is in these + +#define a rax +#define d rdx + + + +S2N_BN_SYMBOL(bignum_mul): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] + mov r9, [rsp+64] +#endif + +// We use too many registers, and also we need rax:rdx for multiplications + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov m, rdx + +// If the result size is zero, do nothing +// Note that even if either or both inputs has size zero, we can't +// just give up because we at least need to zero the output array +// If we did a multiply-add variant, however, then we could + + test p, p + jz end + +// Set initial 2-part sum to zero (we zero c inside the body) + + xor h,h + xor l,l + +// Otherwise do outer loop k = 0 ... k = p - 1 + + xor k, k + +outerloop: + +// Zero our carry term first; we eventually want it and a zero is useful now +// Set a = max 0 (k + 1 - n), i = min (k + 1) m +// This defines the range a <= j < i for the inner summation +// Note that since k < p < 2^64 we can assume k + 1 doesn't overflow +// And since we want to increment it anyway, we might as well do it now + + xor c, c // c = 0 + inc k // k = k + 1 + + mov a, k // a = k + 1 + sub a, n // a = k + 1 - n + cmovc a, c // a = max 0 (k + 1 - n) + + mov i, m // i = m + cmp k, m // CF <=> k + 1 < m + cmovc i, k // i = min (k + 1) m + +// Turn i into a loop count, and skip things if it's <= 0 +// Otherwise set up initial pointers x -> x0[a] and y -> y0[k - a] +// and then launch into the main inner loop, postdecrementing i + + mov d, k + sub d, i + sub i, a + jbe innerend + lea x,[rcx+8*a] + lea y,[r9+8*d-8] + +innerloop: + mov rax, [y+8*i] + mul QWORD PTR [x] + add x, 8 + add l, rax + adc h, rdx + adc c, 0 + dec i + jnz innerloop + +innerend: + + mov [z], l + mov l, h + mov h, c + add z, 8 + + cmp k, p + jc outerloop + +end: + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul_4_8_alt.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul_4_8_alt.S new file mode 100644 index 000000000..f02b09b28 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul_4_8_alt.S @@ -0,0 +1,157 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Multiply z := x * y +// Inputs x[4], y[4]; output z[8] +// +// extern void bignum_mul_4_8_alt +// (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); +// +// Standard x86-64 ABI: RDI = z, RSI = x, RDX = y +// Microsoft x64 ABI: RCX = z, RDX = x, R8 = y +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul_4_8_alt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul_4_8_alt) + .text + +// These are actually right + +#define z rdi +#define x rsi + +// This is moved from rdx to free it for muls + +#define y rcx + +// Other variables used as a rotating 3-word window to add terms to + +#define t0 r8 +#define t1 r9 +#define t2 r10 + +// Macro for the key "multiply and add to (c,h,l)" step + +#define combadd(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +// A minutely shorter form for when c = 0 initially + +#define combadz(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx; \ + adc c, c + +// A short form where we don't expect a top carry + +#define combads(h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx + +S2N_BN_SYMBOL(bignum_mul_4_8_alt): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 +#endif + +// Copy y into a safe register to start with + + mov y, rdx + +// Result term 0 + + mov rax, [x] + mul QWORD PTR [y] + + mov [z], rax + mov t0, rdx + xor t1, t1 + +// Result term 1 + + xor t2, t2 + combads(t1,t0,[x],[y+8]) + combadz(t2,t1,t0,[x+8],[y]) + mov [z+8], t0 + +// Result term 2 + + xor t0, t0 + combadz(t0,t2,t1,[x],[y+16]) + combadd(t0,t2,t1,[x+8],[y+8]) + combadd(t0,t2,t1,[x+16],[y]) + mov [z+16], t1 + +// Result term 3 + + xor t1, t1 + combadz(t1,t0,t2,[x],[y+24]) + combadd(t1,t0,t2,[x+8],[y+16]) + combadd(t1,t0,t2,[x+16],[y+8]) + combadd(t1,t0,t2,[x+24],[y]) + mov [z+24], t2 + +// Result term 4 + + xor t2, t2 + combadz(t2,t1,t0,[x+8],[y+24]) + combadd(t2,t1,t0,[x+16],[y+16]) + combadd(t2,t1,t0,[x+24],[y+8]) + mov [z+32], t0 + +// Result term 5 + + xor t0, t0 + combadz(t0,t2,t1,[x+16],[y+24]) + combadd(t0,t2,t1,[x+24],[y+16]) + mov [z+40], t1 + +// Result term 6 + + xor t1, t1 + combads(t0,t2,[x+24],[y+24]) + mov [z+48], t2 + +// Result term 7 + + mov [z+56], t0 + +// Return + +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul_8_16_alt.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul_8_16_alt.S new file mode 100644 index 000000000..97be83e1f --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_mul_8_16_alt.S @@ -0,0 +1,244 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Multiply z := x * y +// Inputs x[8], y[8]; output z[16] +// +// extern void bignum_mul_8_16_alt +// (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); +// +// Standard x86-64 ABI: RDI = z, RSI = x, RDX = y +// Microsoft x64 ABI: RCX = z, RDX = x, R8 = y +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul_8_16_alt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul_8_16_alt) + .text + +// These are actually right + +#define z rdi +#define x rsi + +// This is moved from rdx to free it for muls + +#define y rcx + +// Other variables used as a rotating 3-word window to add terms to + +#define t0 r8 +#define t1 r9 +#define t2 r10 + +// Macro for the key "multiply and add to (c,h,l)" step + +#define combadd(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +// A minutely shorter form for when c = 0 initially + +#define combadz(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx; \ + adc c, c + +// A short form where we don't expect a top carry + +#define combads(h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx + +S2N_BN_SYMBOL(bignum_mul_8_16_alt): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 +#endif + +// Copy y into a safe register to start with + + mov y, rdx + +// Result term 0 + + mov rax, [x] + mul QWORD PTR [y] + + mov [z], rax + mov t0, rdx + xor t1, t1 + +// Result term 1 + + xor t2, t2 + combads(t1,t0,[x],[y+8]) + combadz(t2,t1,t0,[x+8],[y]) + mov [z+8], t0 + +// Result term 2 + + xor t0, t0 + combadz(t0,t2,t1,[x],[y+16]) + combadd(t0,t2,t1,[x+8],[y+8]) + combadd(t0,t2,t1,[x+16],[y]) + mov [z+16], t1 + +// Result term 3 + + xor t1, t1 + combadz(t1,t0,t2,[x],[y+24]) + combadd(t1,t0,t2,[x+8],[y+16]) + combadd(t1,t0,t2,[x+16],[y+8]) + combadd(t1,t0,t2,[x+24],[y]) + mov [z+24], t2 + +// Result term 4 + + xor t2, t2 + combadz(t2,t1,t0,[x],[y+32]) + combadd(t2,t1,t0,[x+8],[y+24]) + combadd(t2,t1,t0,[x+16],[y+16]) + combadd(t2,t1,t0,[x+24],[y+8]) + combadd(t2,t1,t0,[x+32],[y]) + mov [z+32], t0 + +// Result term 5 + + xor t0, t0 + combadz(t0,t2,t1,[x],[y+40]) + combadd(t0,t2,t1,[x+8],[y+32]) + combadd(t0,t2,t1,[x+16],[y+24]) + combadd(t0,t2,t1,[x+24],[y+16]) + combadd(t0,t2,t1,[x+32],[y+8]) + combadd(t0,t2,t1,[x+40],[y]) + mov [z+40], t1 + +// Result term 6 + + xor t1, t1 + combadz(t1,t0,t2,[x],[y+48]) + combadd(t1,t0,t2,[x+8],[y+40]) + combadd(t1,t0,t2,[x+16],[y+32]) + combadd(t1,t0,t2,[x+24],[y+24]) + combadd(t1,t0,t2,[x+32],[y+16]) + combadd(t1,t0,t2,[x+40],[y+8]) + combadd(t1,t0,t2,[x+48],[y]) + mov [z+48], t2 + +// Result term 7 + + xor t2, t2 + combadz(t2,t1,t0,[x],[y+56]) + combadd(t2,t1,t0,[x+8],[y+48]) + combadd(t2,t1,t0,[x+16],[y+40]) + combadd(t2,t1,t0,[x+24],[y+32]) + combadd(t2,t1,t0,[x+32],[y+24]) + combadd(t2,t1,t0,[x+40],[y+16]) + combadd(t2,t1,t0,[x+48],[y+8]) + combadd(t2,t1,t0,[x+56],[y]) + mov [z+56], t0 + +// Result term 8 + + xor t0, t0 + combadz(t0,t2,t1,[x+8],[y+56]) + combadd(t0,t2,t1,[x+16],[y+48]) + combadd(t0,t2,t1,[x+24],[y+40]) + combadd(t0,t2,t1,[x+32],[y+32]) + combadd(t0,t2,t1,[x+40],[y+24]) + combadd(t0,t2,t1,[x+48],[y+16]) + combadd(t0,t2,t1,[x+56],[y+8]) + mov [z+64], t1 + +// Result term 9 + + xor t1, t1 + combadz(t1,t0,t2,[x+16],[y+56]) + combadd(t1,t0,t2,[x+24],[y+48]) + combadd(t1,t0,t2,[x+32],[y+40]) + combadd(t1,t0,t2,[x+40],[y+32]) + combadd(t1,t0,t2,[x+48],[y+24]) + combadd(t1,t0,t2,[x+56],[y+16]) + mov [z+72], t2 + +// Result term 10 + + xor t2, t2 + combadz(t2,t1,t0,[x+24],[y+56]) + combadd(t2,t1,t0,[x+32],[y+48]) + combadd(t2,t1,t0,[x+40],[y+40]) + combadd(t2,t1,t0,[x+48],[y+32]) + combadd(t2,t1,t0,[x+56],[y+24]) + mov [z+80], t0 + +// Result term 11 + + xor t0, t0 + combadz(t0,t2,t1,[x+32],[y+56]) + combadd(t0,t2,t1,[x+40],[y+48]) + combadd(t0,t2,t1,[x+48],[y+40]) + combadd(t0,t2,t1,[x+56],[y+32]) + mov [z+88], t1 + +// Result term 12 + + xor t1, t1 + combadz(t1,t0,t2,[x+40],[y+56]) + combadd(t1,t0,t2,[x+48],[y+48]) + combadd(t1,t0,t2,[x+56],[y+40]) + mov [z+96], t2 + +// Result term 13 + + xor t2, t2 + combadz(t2,t1,t0,[x+48],[y+56]) + combadd(t2,t1,t0,[x+56],[y+48]) + mov [z+104], t0 + +// Result term 14 + + combads(t2,t1,[x+56],[y+56]) + mov [z+112], t1 + +// Result term 11 + + mov [z+120], t2 + +// Return + +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr.S new file mode 100644 index 000000000..c4a0cabf3 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr.S @@ -0,0 +1,197 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Square z := x^2 +// Input x[n]; output z[k] +// +// extern void bignum_sqr +// (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); +// +// Does the "z := x^2" operation where x is n digits and result z is k. +// Truncates the result in general unless k >= 2 * n +// +// Standard x86-64 ABI: RDI = k, RSI = z, RDX = n, RCX = x +// Microsoft x64 ABI: RCX = k, RDX = z, R8 = n, R9 = x +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sqr) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr) + .text + +// First three are where arguments come in, but n is moved. + +#define p rdi +#define z rsi +#define x rcx +#define n r8 + +// These are always local scratch since multiplier result is in these + +#define a rax +#define d rdx + +// Other variables + +#define i rbx +#define ll rbp +#define hh r9 +#define k r10 +#define y r11 +#define htop r12 +#define l r13 +#define h r14 +#define c r15 + +// Short versions + +#define llshort ebp + +S2N_BN_SYMBOL(bignum_sqr): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 +#endif + +// We use too many registers, and also we need rax:rdx for multiplications + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov n, rdx + +// If p = 0 the result is trivial and nothing needs doing + + test p, p + jz end + +// initialize (hh,ll) = 0 + + xor llshort, llshort + xor hh, hh + +// Iterate outer loop from k = 0 ... k = p - 1 producing result digits + + xor k, k + +outerloop: + +// First let bot = MAX 0 (k + 1 - n) and top = MIN (k + 1) n +// We want to accumulate all x[i] * x[k - i] for bot <= i < top +// For the optimization of squaring we avoid duplication and do +// 2 * x[i] * x[k - i] for i < htop, where htop = MIN ((k+1)/2) n +// Initialize i = bot; in fact just compute bot as i directly. + + xor c, c + lea i, [k+1] + mov htop, i + shr htop, 1 + sub i, n + cmovc i, c + cmp htop, n + cmovnc htop, n + +// Initialize the three-part local sum (c,h,l); c was already done above + + xor l, l + xor h, h + +// If htop <= bot then main doubled part of the sum is empty + + cmp i, htop + jnc nosumming + +// Use a moving pointer for [y] = x[k-i] for the cofactor + + mov a, k + sub a, i + lea y, [x+8*a] + +// Do the main part of the sum x[i] * x[k - i] for 2 * i < k + +innerloop: + mov a, [x+8*i] + mul QWORD PTR [y] + add l, a + adc h, d + adc c, 0 + sub y, 8 + inc i + cmp i, htop + jc innerloop + +// Now double it + + add l, l + adc h, h + adc c, c + +// If k is even (which means 2 * i = k) and i < n add the extra x[i]^2 term + +nosumming: + test k, 1 + jnz innerend + cmp i, n + jnc innerend + + mov a, [x+8*i] + mul a + add l, a + adc h, d + adc c, 0 + +// Now add the local sum into the global sum, store and shift + +innerend: + add l, ll + mov [z+8*k], l + adc h, hh + mov ll, h + adc c, 0 + mov hh, c + + inc k + cmp k, p + jc outerloop + +// Restore registers and return + +end: + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr_4_8_alt.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr_4_8_alt.S new file mode 100644 index 000000000..b228414dc --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr_4_8_alt.S @@ -0,0 +1,145 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Square, z := x^2 +// Input x[4]; output z[8] +// +// extern void bignum_sqr_4_8_alt +// (uint64_t z[static 8], uint64_t x[static 4]); +// +// Standard x86-64 ABI: RDI = z, RSI = x +// Microsoft x64 ABI: RCX = z, RDX = x +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sqr_4_8_alt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr_4_8_alt) + .text + +// Input arguments + +#define z rdi +#define x rsi + +// Other variables used as a rotating 3-word window to add terms to + +#define t0 rcx +#define t1 r8 +#define t2 r9 + +// Macro for the key "multiply and add to (c,h,l)" step, for square term + +#define combadd1(c,h,l,numa) \ + mov rax, numa; \ + mul rax; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +// A short form where we don't expect a top carry + +#define combads(h,l,numa) \ + mov rax, numa; \ + mul rax; \ + add l, rax; \ + adc h, rdx + +// A version doubling before adding, for non-square terms + +#define combadd2(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add rax, rax; \ + adc rdx, rdx; \ + adc c, 0; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +S2N_BN_SYMBOL(bignum_sqr_4_8_alt): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx +#endif + +// Result term 0 + + mov rax, [x] + mul rax + + mov [z], rax + mov t0, rdx + xor t1, t1 + +// Result term 1 + + xor t2, t2 + combadd2(t2,t1,t0,[x],[x+8]) + mov [z+8], t0 + +// Result term 2 + + xor t0, t0 + combadd1(t0,t2,t1,[x+8]) + combadd2(t0,t2,t1,[x],[x+16]) + mov [z+16], t1 + +// Result term 3 + + xor t1, t1 + combadd2(t1,t0,t2,[x],[x+24]) + combadd2(t1,t0,t2,[x+8],[x+16]) + mov [z+24], t2 + +// Result term 4 + + xor t2, t2 + combadd2(t2,t1,t0,[x+8],[x+24]) + combadd1(t2,t1,t0,[x+16]) + mov [z+32], t0 + +// Result term 5 + + xor t0, t0 + combadd2(t0,t2,t1,[x+16],[x+24]) + mov [z+40], t1 + +// Result term 6 + + xor t1, t1 + combads(t0,t2,[x+24]) + mov [z+48], t2 + +// Result term 7 + + mov [z+56], t0 + +// Return + +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr_8_16_alt.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr_8_16_alt.S new file mode 100644 index 000000000..04efeec7e --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sqr_8_16_alt.S @@ -0,0 +1,242 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Square, z := x^2 +// Input x[8]; output z[16] +// +// extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]); +// +// Standard x86-64 ABI: RDI = z, RSI = x +// Microsoft x64 ABI: RCX = z, RDX = x +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sqr_8_16_alt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr_8_16_alt) + .text + +// Input arguments + +#define z rdi +#define x rsi + +// Other variables used as a rotating 3-word window to add terms to + +#define t0 r8 +#define t1 r9 +#define t2 r10 + +// Additional temporaries for local windows to share doublings + +#define u0 rcx +#define u1 r11 + +// Macro for the key "multiply and add to (c,h,l)" step + +#define combadd(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +// Set up initial window (c,h,l) = numa * numb + +#define combaddz(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + xor c, c; \ + mov l, rax; \ + mov h, rdx + +// Doubling step (c,h,l) = 2 * (c,hh,ll) + (0,h,l) + +#define doubladd(c,h,l,hh,ll) \ + add ll, ll; \ + adc hh, hh; \ + adc c, c; \ + add l, ll; \ + adc h, hh; \ + adc c, 0 + +// Square term incorporation (c,h,l) += numba^2 + +#define combadd1(c,h,l,numa) \ + mov rax, numa; \ + mul rax; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +// A short form where we don't expect a top carry + +#define combads(h,l,numa) \ + mov rax, numa; \ + mul rax; \ + add l, rax; \ + adc h, rdx + +// A version doubling directly before adding, for single non-square terms + +#define combadd2(c,h,l,numa,numb) \ + mov rax, numa; \ + mul QWORD PTR numb; \ + add rax, rax; \ + adc rdx, rdx; \ + adc c, 0; \ + add l, rax; \ + adc h, rdx; \ + adc c, 0 + +S2N_BN_SYMBOL(bignum_sqr_8_16_alt): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx +#endif + +// Result term 0 + + mov rax, [x] + mul rax + + mov [z], rax + mov t0, rdx + xor t1, t1 + +// Result term 1 + + xor t2, t2 + combadd2(t2,t1,t0,[x],[x+8]) + mov [z+8], t0 + +// Result term 2 + + xor t0, t0 + combadd1(t0,t2,t1,[x+8]) + combadd2(t0,t2,t1,[x],[x+16]) + mov [z+16], t1 + +// Result term 3 + + combaddz(t1,u1,u0,[x],[x+24]) + combadd(t1,u1,u0,[x+8],[x+16]) + doubladd(t1,t0,t2,u1,u0) + mov [z+24], t2 + +// Result term 4 + + combaddz(t2,u1,u0,[x],[x+32]) + combadd(t2,u1,u0,[x+8],[x+24]) + doubladd(t2,t1,t0,u1,u0) + combadd1(t2,t1,t0,[x+16]) + mov [z+32], t0 + +// Result term 5 + + combaddz(t0,u1,u0,[x],[x+40]) + combadd(t0,u1,u0,[x+8],[x+32]) + combadd(t0,u1,u0,[x+16],[x+24]) + doubladd(t0,t2,t1,u1,u0) + mov [z+40], t1 + +// Result term 6 + + combaddz(t1,u1,u0,[x],[x+48]) + combadd(t1,u1,u0,[x+8],[x+40]) + combadd(t1,u1,u0,[x+16],[x+32]) + doubladd(t1,t0,t2,u1,u0) + combadd1(t1,t0,t2,[x+24]) + mov [z+48], t2 + +// Result term 7 + + combaddz(t2,u1,u0,[x],[x+56]) + combadd(t2,u1,u0,[x+8],[x+48]) + combadd(t2,u1,u0,[x+16],[x+40]) + combadd(t2,u1,u0,[x+24],[x+32]) + doubladd(t2,t1,t0,u1,u0) + mov [z+56], t0 + +// Result term 8 + + combaddz(t0,u1,u0,[x+8],[x+56]) + combadd(t0,u1,u0,[x+16],[x+48]) + combadd(t0,u1,u0,[x+24],[x+40]) + doubladd(t0,t2,t1,u1,u0) + combadd1(t0,t2,t1,[x+32]) + mov [z+64], t1 + +// Result term 9 + + combaddz(t1,u1,u0,[x+16],[x+56]) + combadd(t1,u1,u0,[x+24],[x+48]) + combadd(t1,u1,u0,[x+32],[x+40]) + doubladd(t1,t0,t2,u1,u0) + mov [z+72], t2 + +// Result term 10 + + combaddz(t2,u1,u0,[x+24],[x+56]) + combadd(t2,u1,u0,[x+32],[x+48]) + doubladd(t2,t1,t0,u1,u0) + combadd1(t2,t1,t0,[x+40]) + mov [z+80], t0 + +// Result term 11 + + combaddz(t0,u1,u0,[x+32],[x+56]) + combadd(t0,u1,u0,[x+40],[x+48]) + doubladd(t0,t2,t1,u1,u0) + mov [z+88], t1 + +// Result term 12 + + xor t1, t1 + combadd2(t1,t0,t2,[x+40],[x+56]) + combadd1(t1,t0,t2,[x+48]) + mov [z+96], t2 + +// Result term 13 + + xor t2, t2 + combadd2(t2,t1,t0,[x+48],[x+56]) + mov [z+104], t0 + +// Result term 14 + + combads(t2,t1,[x+56]) + mov [z+112], t1 + +// Result term 15 + + mov [z+120], t2 + +// Return + +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bignum_sub.S b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sub.S new file mode 100644 index 000000000..11a9bd7ed --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bignum_sub.S @@ -0,0 +1,153 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Subtract, z := x - y +// Inputs x[m], y[n]; outputs function return (carry-out) and z[p] +// +// extern uint64_t bignum_sub +// (uint64_t p, uint64_t *z, +// uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); +// +// Does the z := x - y operation, truncating modulo p words in general and +// returning a top borrow (0 or 1) in the p'th place, only subtracting input +// words below p (as well as m and n respectively) to get the diff and borrow. +// +// Standard x86-64 ABI: RDI = p, RSI = z, RDX = m, RCX = x, R8 = n, R9 = y, returns RAX +// Microsoft x64 ABI: RCX = p, RDX = z, R8 = m, R9 = x, [RSP+40] = n, [RSP+48] = y, returns RAX +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sub) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sub) + .text + +#define p rdi +#define z rsi +#define m rdx +#define x rcx +#define n r8 +#define y r9 +#define i r10 +#define a rax + +#define ashort eax + + + +S2N_BN_SYMBOL(bignum_sub): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] + mov r9, [rsp+64] +#endif + +// Zero the main index counter for both branches + + xor i, i + +// First clamp the two input sizes m := min(p,m) and n := min(p,n) since +// we'll never need words past the p'th. Can now assume m <= p and n <= p. +// Then compare the modified m and n and branch accordingly + + cmp p, m + cmovc m, p + cmp p, n + cmovc n, p + cmp m, n + jc ylonger + +// The case where x is longer or of the same size (p >= m >= n) + + sub p, m + sub m, n + inc m + test n, n + jz xtest +xmainloop: + mov a, [x+8*i] + sbb a, [y+8*i] + mov [z+8*i],a + inc i + dec n + jnz xmainloop + jmp xtest +xtoploop: + mov a, [x+8*i] + sbb a, 0 + mov [z+8*i],a + inc i +xtest: + dec m + jnz xtoploop + sbb a, a + test p, p + jz tailskip +tailloop: + mov [z+8*i],a + inc i + dec p + jnz tailloop +tailskip: + neg a +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +// The case where y is longer (p >= n > m) + +ylonger: + + sub p, n + sub n, m + test m, m + jz ytoploop +ymainloop: + mov a, [x+8*i] + sbb a, [y+8*i] + mov [z+8*i],a + inc i + dec m + jnz ymainloop +ytoploop: + mov ashort, 0 + sbb a, [y+8*i] + mov [z+8*i],a + inc i + dec n + jnz ytoploop + sbb a, a + test p, p + jnz tailloop + neg a +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bn_arch.c b/Libraries/libressl/crypto/bn/arch/amd64/bn_arch.c new file mode 100644 index 000000000..a377a0568 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bn_arch.c @@ -0,0 +1,131 @@ +/* $OpenBSD: bn_arch.c,v 1.7 2023/06/24 16:01:44 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bn_arch.h" +#include "bn_local.h" +#include "s2n_bignum.h" + +#ifdef HAVE_BN_ADD +BN_ULONG +bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, + int b_len) +{ + return bignum_add(r_len, (uint64_t *)r, a_len, (uint64_t *)a, + b_len, (uint64_t *)b); +} +#endif + + +#ifdef HAVE_BN_ADD_WORDS +BN_ULONG +bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) +{ + return bignum_add(n, (uint64_t *)rd, n, (uint64_t *)ad, n, + (uint64_t *)bd); +} +#endif + +#ifdef HAVE_BN_SUB +BN_ULONG +bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, + int b_len) +{ + return bignum_sub(r_len, (uint64_t *)r, a_len, (uint64_t *)a, + b_len, (uint64_t *)b); +} +#endif + +#ifdef HAVE_BN_SUB_WORDS +BN_ULONG +bn_sub_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) +{ + return bignum_sub(n, (uint64_t *)rd, n, (uint64_t *)ad, n, + (uint64_t *)bd); +} +#endif + +#ifdef HAVE_BN_MUL_ADD_WORDS +BN_ULONG +bn_mul_add_words(BN_ULONG *rd, const BN_ULONG *ad, int num, BN_ULONG w) +{ + return bignum_cmadd(num, (uint64_t *)rd, w, num, (uint64_t *)ad); +} +#endif + +#ifdef HAVE_BN_MUL_WORDS +BN_ULONG +bn_mul_words(BN_ULONG *rd, const BN_ULONG *ad, int num, BN_ULONG w) +{ + return bignum_cmul(num, (uint64_t *)rd, w, num, (uint64_t *)ad); +} +#endif + +#ifdef HAVE_BN_MUL_COMBA4 +void +bn_mul_comba4(BN_ULONG *rd, BN_ULONG *ad, BN_ULONG *bd) +{ + /* XXX - consider using non-alt on CPUs that have the ADX extension. */ + bignum_mul_4_8_alt((uint64_t *)rd, (uint64_t *)ad, (uint64_t *)bd); +} +#endif + +#ifdef HAVE_BN_MUL_COMBA8 +void +bn_mul_comba8(BN_ULONG *rd, BN_ULONG *ad, BN_ULONG *bd) +{ + /* XXX - consider using non-alt on CPUs that have the ADX extension. */ + bignum_mul_8_16_alt((uint64_t *)rd, (uint64_t *)ad, (uint64_t *)bd); +} +#endif + +#ifdef HAVE_BN_SQR +int +bn_sqr(BIGNUM *r, const BIGNUM *a, int r_len, BN_CTX *ctx) +{ + bignum_sqr(r_len, (uint64_t *)r->d, a->top, (uint64_t *)a->d); + + return 1; +} +#endif + +#ifdef HAVE_BN_SQR_COMBA4 +void +bn_sqr_comba4(BN_ULONG *rd, const BN_ULONG *ad) +{ + /* XXX - consider using non-alt on CPUs that have the ADX extension. */ + bignum_sqr_4_8_alt((uint64_t *)rd, (uint64_t *)ad); +} +#endif + +#ifdef HAVE_BN_SQR_COMBA8 +void +bn_sqr_comba8(BN_ULONG *rd, const BN_ULONG *ad) +{ + /* XXX - consider using non-alt on CPUs that have the ADX extension. */ + bignum_sqr_8_16_alt((uint64_t *)rd, (uint64_t *)ad); +} +#endif + +#ifdef HAVE_BN_WORD_CLZ +int +bn_word_clz(BN_ULONG w) +{ + return word_clz(w); +} +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/bn_arch.h b/Libraries/libressl/crypto/bn/arch/amd64/bn_arch.h new file mode 100644 index 000000000..9d491e272 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/bn_arch.h @@ -0,0 +1,95 @@ +/* $OpenBSD: bn_arch.h,v 1.13 2023/02/16 11:13:05 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifdef _WIN32 +#define OPENSSL_NO_ASM +#else + +#ifndef OPENSSL_NO_ASM + +#define HAVE_BN_ADD +#define HAVE_BN_ADD_WORDS + +#define HAVE_BN_DIV_WORDS + +#define HAVE_BN_MUL_ADD_WORDS +#define HAVE_BN_MUL_COMBA4 +#define HAVE_BN_MUL_COMBA8 +#define HAVE_BN_MUL_WORDS + +#define HAVE_BN_SQR +#define HAVE_BN_SQR_COMBA4 +#define HAVE_BN_SQR_COMBA8 + +#define HAVE_BN_SUB +#define HAVE_BN_SUB_WORDS + +#define HAVE_BN_WORD_CLZ + +#if defined(__GNUC__) +#define HAVE_BN_DIV_REM_WORDS_INLINE + +static inline void +bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q, + BN_ULONG *out_r) +{ + BN_ULONG q, r; + + /* + * Unsigned division of %rdx:%rax by d with quotient being stored in + * %rax and remainder in %rdx. + */ + __asm__ volatile ("divq %4" + : "=a"(q), "=d"(r) + : "d"(h), "a"(l), "rm"(d) + : "cc"); + + *out_q = q; + *out_r = r; +} +#endif /* __GNUC__ */ + +#if defined(__GNUC__) +#define HAVE_BN_MULW + +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + /* + * Unsigned multiplication of %rax, with the double word result being + * stored in %rdx:%rax. + */ + __asm__ ("mulq %3" + : "=d"(r1), "=a"(r0) + : "a"(a), "rm"(b) + : "cc"); + + *out_r1 = r1; + *out_r0 = r0; +} +#endif /* __GNUC__ */ +#endif /* _WIN32 */ + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/amd64/word_clz.S b/Libraries/libressl/crypto/bn/arch/amd64/word_clz.S new file mode 100644 index 000000000..464a9d90f --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/amd64/word_clz.S @@ -0,0 +1,60 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// Count leading zero bits in a single word +// Input a; output function return +// +// extern uint64_t word_clz (uint64_t a); +// +// Standard x86-64 ABI: RDI = a, returns RAX +// Microsoft x64 ABI: RCX = a, returns RAX +// ---------------------------------------------------------------------------- + +#include "s2n_bignum_internal.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(word_clz) + S2N_BN_SYM_PRIVACY_DIRECTIVE(word_clz) + .text + +S2N_BN_SYMBOL(word_clz): + endbr64 + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx +#endif + +// First do rax = 63 - bsr(a), which is right except (maybe) for zero inputs + + bsr rax, rdi + xor rax, 63 + +// Force return of 64 in the zero-input case + + mov edx, 64 + test rdi, rdi + cmove rax, rdx + +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/arch/arm/bn_arch.h b/Libraries/libressl/crypto/bn/arch/arm/bn_arch.h new file mode 100644 index 000000000..ef9bf7f15 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/arm/bn_arch.h @@ -0,0 +1,73 @@ +/* $OpenBSD: bn_arch.h,v 1.2 2023/06/24 15:51:47 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#if defined(__GNUC__) + +#define HAVE_BN_SUBW + +static inline void +bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0) +{ + BN_ULONG borrow, r0; + + __asm__ ( + "mov %[borrow], #0 \n" + "subs %[r0], %[a], %[b] \n" + "sbc %[borrow], %[borrow], #0 \n" + "neg %[borrow], %[borrow] \n" + : [borrow]"=&r"(borrow), [r0]"=r"(r0) + : [a]"r"(a), [b]"r"(b) + : "cc"); + + *out_borrow = borrow; + *out_r0 = r0; +} + +#define HAVE_BN_SUBW_SUBW + +static inline void +bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow, + BN_ULONG *out_r0) +{ + BN_ULONG borrow, r0; + + __asm__ ( + "mov %[borrow], #0 \n" + "subs %[r0], %[a], %[b] \n" + "sbc %[borrow], %[borrow], #0 \n" + "subs %[r0], %[r0], %[c] \n" + "sbc %[borrow], %[borrow], #0 \n" + "neg %[borrow], %[borrow] \n" + : [borrow]"=&r"(borrow), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b), [c]"r"(c) + : "cc"); + + *out_borrow = borrow; + *out_r0 = r0; +} + +#endif /* __GNUC__ */ + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/i386/bn_arch.h b/Libraries/libressl/crypto/bn/arch/i386/bn_arch.h new file mode 100644 index 000000000..eef519fcc --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/i386/bn_arch.h @@ -0,0 +1,86 @@ +/* $OpenBSD: bn_arch.h,v 1.9 2023/02/16 10:41:03 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#define HAVE_BN_ADD_WORDS + +#define HAVE_BN_DIV_WORDS + +#define HAVE_BN_MUL_ADD_WORDS +#define HAVE_BN_MUL_COMBA4 +#define HAVE_BN_MUL_COMBA8 +#define HAVE_BN_MUL_WORDS + +#define HAVE_BN_SQR_COMBA4 +#define HAVE_BN_SQR_COMBA8 +#define HAVE_BN_SQR_WORDS + +#define HAVE_BN_SUB_WORDS + +#if defined(__GNUC__) +#define HAVE_BN_DIV_REM_WORDS_INLINE + +static inline void +bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q, + BN_ULONG *out_r) +{ + BN_ULONG q, r; + + /* + * Unsigned division of %edx:%eax by d with quotient being stored in + * %eax and remainder in %edx. + */ + __asm__ volatile ("divl %4" + : "=a"(q), "=d"(r) + : "a"(l), "d"(h), "rm"(d) + : "cc"); + + *out_q = q; + *out_r = r; +} +#endif /* __GNUC__ */ + +#if defined(__GNUC__) +#define HAVE_BN_MULW + +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + /* + * Unsigned multiplication of %eax, with the double word result being + * stored in %edx:%eax. + */ + __asm__ ("mull %3" + : "=d"(r1), "=a"(r0) + : "a"(a), "rm"(b) + : "cc"); + + *out_r1 = r1; + *out_r0 = r0; +} +#endif /* __GNUC__ */ + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/mips/bn_arch.h b/Libraries/libressl/crypto/bn/arch/mips/bn_arch.h new file mode 100644 index 000000000..4d6571f9c --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/mips/bn_arch.h @@ -0,0 +1,24 @@ +/* $OpenBSD: bn_arch.h,v 1.1 2023/01/20 10:04:34 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/mips64/bn_arch.h b/Libraries/libressl/crypto/bn/arch/mips64/bn_arch.h new file mode 100644 index 000000000..53771bce1 --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/mips64/bn_arch.h @@ -0,0 +1,40 @@ +/* $OpenBSD: bn_arch.h,v 1.7 2023/01/23 12:17:58 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#define HAVE_BN_ADD_WORDS + +#define HAVE_BN_DIV_WORDS +#define HAVE_BN_DIV_3_WORDS + +#define HAVE_BN_MUL_ADD_WORDS +#define HAVE_BN_MUL_COMBA4 +#define HAVE_BN_MUL_COMBA8 +#define HAVE_BN_MUL_WORDS + +#define HAVE_BN_SQR_COMBA4 +#define HAVE_BN_SQR_COMBA8 +#define HAVE_BN_SQR_WORDS + +#define HAVE_BN_SUB_WORDS + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/powerpc/bn_arch.h b/Libraries/libressl/crypto/bn/arch/powerpc/bn_arch.h new file mode 100644 index 000000000..46e932a2d --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/powerpc/bn_arch.h @@ -0,0 +1,39 @@ +/* $OpenBSD: bn_arch.h,v 1.6 2023/01/23 12:17:58 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#define HAVE_BN_ADD_WORDS + +#define HAVE_BN_DIV_WORDS + +#define HAVE_BN_MUL_ADD_WORDS +#define HAVE_BN_MUL_COMBA4 +#define HAVE_BN_MUL_COMBA8 +#define HAVE_BN_MUL_WORDS + +#define HAVE_BN_SQR_COMBA4 +#define HAVE_BN_SQR_COMBA8 +#define HAVE_BN_SQR_WORDS + +#define HAVE_BN_SUB_WORDS + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/powerpc64/bn_arch.h b/Libraries/libressl/crypto/bn/arch/powerpc64/bn_arch.h new file mode 100644 index 000000000..18bac203e --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/powerpc64/bn_arch.h @@ -0,0 +1,44 @@ +/* $OpenBSD: bn_arch.h,v 1.4 2023/02/16 10:41:03 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#if 0 /* Needs testing and enabling. */ +#if defined(__GNUC__) +#define HAVE_BN_MULW + +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + /* Unsigned multiplication using a mulhdu/mul pair. */ + __asm__ ("mulhdu %0, %2, %3; mul %1, %2, %3" + : "=&r"(r1), "=r"(r0) + : "r"(a), "r"(b)); + + *out_r1 = r1; + *out_r0 = r0; +} +#endif /* __GNUC__ */ +#endif + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/riscv64/bn_arch.h b/Libraries/libressl/crypto/bn/arch/riscv64/bn_arch.h new file mode 100644 index 000000000..e67de835c --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/riscv64/bn_arch.h @@ -0,0 +1,86 @@ +/* $OpenBSD: bn_arch.h,v 1.7 2023/07/09 10:37:32 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#if defined(__GNUC__) + +#define HAVE_BN_ADDW + +static inline void +bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG carry, r0; + + __asm__ ( + "add %[r0], %[a], %[b] \n" + "sltu %[carry], %[r0], %[a] \n" + : [carry]"=r"(carry), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b)); + + *out_r1 = carry; + *out_r0 = r0; +} + +#define HAVE_BN_MULW + +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0; + + /* + * Unsigned multiplication using a mulh/mul pair. Note that the order + * of these instructions is important, as they can potentially be fused + * into a single operation. + */ + __asm__ ( + "mulhu %[r1], %[a], %[b] \n" + "mul %[r0], %[a], %[b] \n" + : [r1]"=&r"(r1), [r0]"=r"(r0) + : [a]"r"(a), [b]"r"(b)); + + *out_r1 = r1; + *out_r0 = r0; +} + +#define HAVE_BN_SUBW + +static inline void +bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0) +{ + BN_ULONG borrow, r0; + + __asm__ ( + "sub %[r0], %[a], %[b] \n" + "sltu %[borrow], %[a], %[r0] \n" + : [borrow]"=r"(borrow), [r0]"=&r"(r0) + : [a]"r"(a), [b]"r"(b)); + + *out_borrow = borrow; + *out_r0 = r0; +} + +#endif /* __GNUC__ */ + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/arch/sparc64/bn_arch.h b/Libraries/libressl/crypto/bn/arch/sparc64/bn_arch.h new file mode 100644 index 000000000..4d6571f9c --- /dev/null +++ b/Libraries/libressl/crypto/bn/arch/sparc64/bn_arch.h @@ -0,0 +1,24 @@ +/* $OpenBSD: bn_arch.h,v 1.1 2023/01/20 10:04:34 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_BN_ARCH_H +#define HEADER_BN_ARCH_H + +#ifndef OPENSSL_NO_ASM + +#endif +#endif diff --git a/Libraries/libressl/crypto/bn/bn-mips.S b/Libraries/libressl/crypto/bn/bn-mips.S new file mode 100644 index 000000000..eb4ac9b9f --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn-mips.S @@ -0,0 +1,2162 @@ +.set mips2 +.rdata +.asciiz "mips3.s, Version 1.2" +.asciiz "MIPS II/III/IV ISA artwork by Andy Polyakov " + +.text +.set noat + +.align 5 +.globl bn_mul_add_words +.ent bn_mul_add_words +bn_mul_add_words: + .set noreorder + bgtz $6,bn_mul_add_words_internal + move $2,$0 + jr $31 + move $4,$2 +.end bn_mul_add_words + +.align 5 +.ent bn_mul_add_words_internal +bn_mul_add_words_internal: + .set reorder + li $3,-4 + and $8,$6,$3 + beqz $8,.L_bn_mul_add_words_tail + +.L_bn_mul_add_words_loop: + lw $12,0($5) + multu $12,$7 + lw $13,0($4) + lw $14,4($5) + lw $15,4($4) + lw $8,2*4($5) + lw $9,2*4($4) + addu $13,$2 + sltu $2,$13,$2 # All manuals say it "compares 32-bit + # values", but it seems to work fine + # even on 64-bit registers. + mflo $1 + mfhi $12 + addu $13,$1 + addu $2,$12 + multu $14,$7 + sltu $1,$13,$1 + sw $13,0($4) + addu $2,$1 + + lw $10,3*4($5) + lw $11,3*4($4) + addu $15,$2 + sltu $2,$15,$2 + mflo $1 + mfhi $14 + addu $15,$1 + addu $2,$14 + multu $8,$7 + sltu $1,$15,$1 + sw $15,4($4) + addu $2,$1 + + subu $6,4 + addu $4,4*4 + addu $5,4*4 + addu $9,$2 + sltu $2,$9,$2 + mflo $1 + mfhi $8 + addu $9,$1 + addu $2,$8 + multu $10,$7 + sltu $1,$9,$1 + sw $9,-2*4($4) + addu $2,$1 + + + and $8,$6,$3 + addu $11,$2 + sltu $2,$11,$2 + mflo $1 + mfhi $10 + addu $11,$1 + addu $2,$10 + sltu $1,$11,$1 + sw $11,-4($4) + .set noreorder + bgtz $8,.L_bn_mul_add_words_loop + addu $2,$1 + + beqz $6,.L_bn_mul_add_words_return + nop + +.L_bn_mul_add_words_tail: + .set reorder + lw $12,0($5) + multu $12,$7 + lw $13,0($4) + subu $6,1 + addu $13,$2 + sltu $2,$13,$2 + mflo $1 + mfhi $12 + addu $13,$1 + addu $2,$12 + sltu $1,$13,$1 + sw $13,0($4) + addu $2,$1 + beqz $6,.L_bn_mul_add_words_return + + lw $12,4($5) + multu $12,$7 + lw $13,4($4) + subu $6,1 + addu $13,$2 + sltu $2,$13,$2 + mflo $1 + mfhi $12 + addu $13,$1 + addu $2,$12 + sltu $1,$13,$1 + sw $13,4($4) + addu $2,$1 + beqz $6,.L_bn_mul_add_words_return + + lw $12,2*4($5) + multu $12,$7 + lw $13,2*4($4) + addu $13,$2 + sltu $2,$13,$2 + mflo $1 + mfhi $12 + addu $13,$1 + addu $2,$12 + sltu $1,$13,$1 + sw $13,2*4($4) + addu $2,$1 + +.L_bn_mul_add_words_return: + .set noreorder + jr $31 + move $4,$2 +.end bn_mul_add_words_internal + +.align 5 +.globl bn_mul_words +.ent bn_mul_words +bn_mul_words: + .set noreorder + bgtz $6,bn_mul_words_internal + move $2,$0 + jr $31 + move $4,$2 +.end bn_mul_words + +.align 5 +.ent bn_mul_words_internal +bn_mul_words_internal: + .set reorder + li $3,-4 + and $8,$6,$3 + beqz $8,.L_bn_mul_words_tail + +.L_bn_mul_words_loop: + lw $12,0($5) + multu $12,$7 + lw $14,4($5) + lw $8,2*4($5) + lw $10,3*4($5) + mflo $1 + mfhi $12 + addu $2,$1 + sltu $13,$2,$1 + multu $14,$7 + sw $2,0($4) + addu $2,$13,$12 + + subu $6,4 + addu $4,4*4 + addu $5,4*4 + mflo $1 + mfhi $14 + addu $2,$1 + sltu $15,$2,$1 + multu $8,$7 + sw $2,-3*4($4) + addu $2,$15,$14 + + mflo $1 + mfhi $8 + addu $2,$1 + sltu $9,$2,$1 + multu $10,$7 + sw $2,-2*4($4) + addu $2,$9,$8 + + and $8,$6,$3 + mflo $1 + mfhi $10 + addu $2,$1 + sltu $11,$2,$1 + sw $2,-4($4) + .set noreorder + bgtz $8,.L_bn_mul_words_loop + addu $2,$11,$10 + + beqz $6,.L_bn_mul_words_return + nop + +.L_bn_mul_words_tail: + .set reorder + lw $12,0($5) + multu $12,$7 + subu $6,1 + mflo $1 + mfhi $12 + addu $2,$1 + sltu $13,$2,$1 + sw $2,0($4) + addu $2,$13,$12 + beqz $6,.L_bn_mul_words_return + + lw $12,4($5) + multu $12,$7 + subu $6,1 + mflo $1 + mfhi $12 + addu $2,$1 + sltu $13,$2,$1 + sw $2,4($4) + addu $2,$13,$12 + beqz $6,.L_bn_mul_words_return + + lw $12,2*4($5) + multu $12,$7 + mflo $1 + mfhi $12 + addu $2,$1 + sltu $13,$2,$1 + sw $2,2*4($4) + addu $2,$13,$12 + +.L_bn_mul_words_return: + .set noreorder + jr $31 + move $4,$2 +.end bn_mul_words_internal + +.align 5 +.globl bn_sqr_words +.ent bn_sqr_words +bn_sqr_words: + .set noreorder + bgtz $6,bn_sqr_words_internal + move $2,$0 + jr $31 + move $4,$2 +.end bn_sqr_words + +.align 5 +.ent bn_sqr_words_internal +bn_sqr_words_internal: + .set reorder + li $3,-4 + and $8,$6,$3 + beqz $8,.L_bn_sqr_words_tail + +.L_bn_sqr_words_loop: + lw $12,0($5) + multu $12,$12 + lw $14,4($5) + lw $8,2*4($5) + lw $10,3*4($5) + mflo $13 + mfhi $12 + sw $13,0($4) + sw $12,4($4) + + multu $14,$14 + subu $6,4 + addu $4,8*4 + addu $5,4*4 + mflo $15 + mfhi $14 + sw $15,-6*4($4) + sw $14,-5*4($4) + + multu $8,$8 + mflo $9 + mfhi $8 + sw $9,-4*4($4) + sw $8,-3*4($4) + + + multu $10,$10 + and $8,$6,$3 + mflo $11 + mfhi $10 + sw $11,-2*4($4) + + .set noreorder + bgtz $8,.L_bn_sqr_words_loop + sw $10,-4($4) + + beqz $6,.L_bn_sqr_words_return + nop + +.L_bn_sqr_words_tail: + .set reorder + lw $12,0($5) + multu $12,$12 + subu $6,1 + mflo $13 + mfhi $12 + sw $13,0($4) + sw $12,4($4) + beqz $6,.L_bn_sqr_words_return + + lw $12,4($5) + multu $12,$12 + subu $6,1 + mflo $13 + mfhi $12 + sw $13,2*4($4) + sw $12,3*4($4) + beqz $6,.L_bn_sqr_words_return + + lw $12,2*4($5) + multu $12,$12 + mflo $13 + mfhi $12 + sw $13,4*4($4) + sw $12,5*4($4) + +.L_bn_sqr_words_return: + .set noreorder + jr $31 + move $4,$2 + +.end bn_sqr_words_internal + +.align 5 +.globl bn_add_words +.ent bn_add_words +bn_add_words: + .set noreorder + bgtz $7,bn_add_words_internal + move $2,$0 + jr $31 + move $4,$2 +.end bn_add_words + +.align 5 +.ent bn_add_words_internal +bn_add_words_internal: + .set reorder + li $3,-4 + and $1,$7,$3 + beqz $1,.L_bn_add_words_tail + +.L_bn_add_words_loop: + lw $12,0($5) + lw $8,0($6) + subu $7,4 + lw $13,4($5) + and $1,$7,$3 + lw $14,2*4($5) + addu $6,4*4 + lw $15,3*4($5) + addu $4,4*4 + lw $9,-3*4($6) + addu $5,4*4 + lw $10,-2*4($6) + lw $11,-4($6) + addu $8,$12 + sltu $24,$8,$12 + addu $12,$8,$2 + sltu $2,$12,$8 + sw $12,-4*4($4) + addu $2,$24 + + addu $9,$13 + sltu $25,$9,$13 + addu $13,$9,$2 + sltu $2,$13,$9 + sw $13,-3*4($4) + addu $2,$25 + + addu $10,$14 + sltu $24,$10,$14 + addu $14,$10,$2 + sltu $2,$14,$10 + sw $14,-2*4($4) + addu $2,$24 + + addu $11,$15 + sltu $25,$11,$15 + addu $15,$11,$2 + sltu $2,$15,$11 + sw $15,-4($4) + + .set noreorder + bgtz $1,.L_bn_add_words_loop + addu $2,$25 + + beqz $7,.L_bn_add_words_return + nop + +.L_bn_add_words_tail: + .set reorder + lw $12,0($5) + lw $8,0($6) + addu $8,$12 + subu $7,1 + sltu $24,$8,$12 + addu $12,$8,$2 + sltu $2,$12,$8 + sw $12,0($4) + addu $2,$24 + beqz $7,.L_bn_add_words_return + + lw $13,4($5) + lw $9,4($6) + addu $9,$13 + subu $7,1 + sltu $25,$9,$13 + addu $13,$9,$2 + sltu $2,$13,$9 + sw $13,4($4) + addu $2,$25 + beqz $7,.L_bn_add_words_return + + lw $14,2*4($5) + lw $10,2*4($6) + addu $10,$14 + sltu $24,$10,$14 + addu $14,$10,$2 + sltu $2,$14,$10 + sw $14,2*4($4) + addu $2,$24 + +.L_bn_add_words_return: + .set noreorder + jr $31 + move $4,$2 + +.end bn_add_words_internal + +.align 5 +.globl bn_sub_words +.ent bn_sub_words +bn_sub_words: + .set noreorder + bgtz $7,bn_sub_words_internal + move $2,$0 + jr $31 + move $4,$0 +.end bn_sub_words + +.align 5 +.ent bn_sub_words_internal +bn_sub_words_internal: + .set reorder + li $3,-4 + and $1,$7,$3 + beqz $1,.L_bn_sub_words_tail + +.L_bn_sub_words_loop: + lw $12,0($5) + lw $8,0($6) + subu $7,4 + lw $13,4($5) + and $1,$7,$3 + lw $14,2*4($5) + addu $6,4*4 + lw $15,3*4($5) + addu $4,4*4 + lw $9,-3*4($6) + addu $5,4*4 + lw $10,-2*4($6) + lw $11,-4($6) + sltu $24,$12,$8 + subu $8,$12,$8 + subu $12,$8,$2 + sgtu $2,$12,$8 + sw $12,-4*4($4) + addu $2,$24 + + sltu $25,$13,$9 + subu $9,$13,$9 + subu $13,$9,$2 + sgtu $2,$13,$9 + sw $13,-3*4($4) + addu $2,$25 + + + sltu $24,$14,$10 + subu $10,$14,$10 + subu $14,$10,$2 + sgtu $2,$14,$10 + sw $14,-2*4($4) + addu $2,$24 + + sltu $25,$15,$11 + subu $11,$15,$11 + subu $15,$11,$2 + sgtu $2,$15,$11 + sw $15,-4($4) + + .set noreorder + bgtz $1,.L_bn_sub_words_loop + addu $2,$25 + + beqz $7,.L_bn_sub_words_return + nop + +.L_bn_sub_words_tail: + .set reorder + lw $12,0($5) + lw $8,0($6) + subu $7,1 + sltu $24,$12,$8 + subu $8,$12,$8 + subu $12,$8,$2 + sgtu $2,$12,$8 + sw $12,0($4) + addu $2,$24 + beqz $7,.L_bn_sub_words_return + + lw $13,4($5) + subu $7,1 + lw $9,4($6) + sltu $25,$13,$9 + subu $9,$13,$9 + subu $13,$9,$2 + sgtu $2,$13,$9 + sw $13,4($4) + addu $2,$25 + beqz $7,.L_bn_sub_words_return + + lw $14,2*4($5) + lw $10,2*4($6) + sltu $24,$14,$10 + subu $10,$14,$10 + subu $14,$10,$2 + sgtu $2,$14,$10 + sw $14,2*4($4) + addu $2,$24 + +.L_bn_sub_words_return: + .set noreorder + jr $31 + move $4,$2 +.end bn_sub_words_internal + +.align 5 +.globl bn_div_3_words +.ent bn_div_3_words +bn_div_3_words: + .set noreorder + move $7,$4 # we know that bn_div_words does not + # touch $7, $10, $11 and preserves $6 + # so that we can save two arguments + # and return address in registers + # instead of stack:-) + + lw $4,($7) + move $10,$5 + bne $4,$6,bn_div_3_words_internal + lw $5,-4($7) + li $2,-1 + jr $31 + move $4,$2 +.end bn_div_3_words + +.align 5 +.ent bn_div_3_words_internal +bn_div_3_words_internal: + .set reorder + move $11,$31 + bal bn_div_words_internal + move $31,$11 + multu $10,$2 + lw $14,-2*4($7) + move $8,$0 + mfhi $13 + mflo $12 + sltu $24,$13,$5 +.L_bn_div_3_words_inner_loop: + bnez $24,.L_bn_div_3_words_inner_loop_done + sgeu $1,$14,$12 + seq $25,$13,$5 + and $1,$25 + sltu $15,$12,$10 + addu $5,$6 + subu $13,$15 + subu $12,$10 + sltu $24,$13,$5 + sltu $8,$5,$6 + or $24,$8 + .set noreorder + beqz $1,.L_bn_div_3_words_inner_loop + subu $2,1 + addu $2,1 + .set reorder +.L_bn_div_3_words_inner_loop_done: + .set noreorder + jr $31 + move $4,$2 +.end bn_div_3_words_internal + +.align 5 +.globl bn_div_words +.ent bn_div_words +bn_div_words: + .set noreorder + bnez $6,bn_div_words_internal + li $2,-1 # I would rather signal div-by-zero + # which can be done with 'break 7' + jr $31 + move $4,$2 +.end bn_div_words + +.align 5 +.ent bn_div_words_internal +bn_div_words_internal: + move $3,$0 + bltz $6,.L_bn_div_words_body + move $25,$3 + sll $6,1 + bgtz $6,.-4 + addu $25,1 + + .set reorder + negu $13,$25 + li $14,-1 + sll $14,$13 + and $14,$4 + srl $1,$5,$13 + .set noreorder + beqz $14,.+12 + nop + break 6 # signal overflow + .set reorder + sll $4,$25 + sll $5,$25 + or $4,$1 +.L_bn_div_words_body: + srl $3,$6,4*4 # bits + sgeu $1,$4,$6 + .set noreorder + beqz $1,.+12 + nop + subu $4,$6 + .set reorder + + li $8,-1 + srl $9,$4,4*4 # bits + srl $8,4*4 # q=0xffffffff + beq $3,$9,.L_bn_div_words_skip_div1 + divu $0,$4,$3 + mflo $8 +.L_bn_div_words_skip_div1: + multu $6,$8 + sll $15,$4,4*4 # bits + srl $1,$5,4*4 # bits + or $15,$1 + mflo $12 + mfhi $13 +.L_bn_div_words_inner_loop1: + sltu $14,$15,$12 + seq $24,$9,$13 + sltu $1,$9,$13 + and $14,$24 + sltu $2,$12,$6 + or $1,$14 + .set noreorder + beqz $1,.L_bn_div_words_inner_loop1_done + subu $13,$2 + subu $12,$6 + b .L_bn_div_words_inner_loop1 + subu $8,1 + .set reorder +.L_bn_div_words_inner_loop1_done: + + sll $5,4*4 # bits + subu $4,$15,$12 + sll $2,$8,4*4 # bits + + li $8,-1 + srl $9,$4,4*4 # bits + srl $8,4*4 # q=0xffffffff + beq $3,$9,.L_bn_div_words_skip_div2 + divu $0,$4,$3 + mflo $8 +.L_bn_div_words_skip_div2: + multu $6,$8 + sll $15,$4,4*4 # bits + srl $1,$5,4*4 # bits + or $15,$1 + mflo $12 + mfhi $13 +.L_bn_div_words_inner_loop2: + sltu $14,$15,$12 + seq $24,$9,$13 + sltu $1,$9,$13 + and $14,$24 + sltu $3,$12,$6 + or $1,$14 + .set noreorder + beqz $1,.L_bn_div_words_inner_loop2_done + subu $13,$3 + subu $12,$6 + b .L_bn_div_words_inner_loop2 + subu $8,1 + .set reorder +.L_bn_div_words_inner_loop2_done: + + subu $4,$15,$12 + or $2,$8 + srl $3,$4,$25 # $3 contains remainder if anybody wants it + srl $6,$25 # restore $6 + + .set noreorder + move $5,$3 + jr $31 + move $4,$2 +.end bn_div_words_internal + +.align 5 +.globl bn_mul_comba8 +.ent bn_mul_comba8 +bn_mul_comba8: + .set noreorder + .frame $29,6*4,$31 + .mask 0x003f0000,-4 + subu $29,6*4 + sw $21,5*4($29) + sw $20,4*4($29) + sw $19,3*4($29) + sw $18,2*4($29) + sw $17,1*4($29) + sw $16,0*4($29) + + .set reorder + lw $12,0($5) # If compiled with -mips3 option on + # R5000 box assembler barks on this + # 1ine with "should not have mult/div + # as last instruction in bb (R10K + # bug)" warning. If anybody out there + # has a clue about how to circumvent + # this do send me a note. + # + + lw $8,0($6) + lw $13,4($5) + lw $14,2*4($5) + multu $12,$8 # mul_add_c(a[0],b[0],c1,c2,c3); + lw $15,3*4($5) + lw $9,4($6) + lw $10,2*4($6) + lw $11,3*4($6) + mflo $2 + mfhi $3 + + lw $16,4*4($5) + lw $18,5*4($5) + multu $12,$9 # mul_add_c(a[0],b[1],c2,c3,c1); + lw $20,6*4($5) + lw $5,7*4($5) + lw $17,4*4($6) + lw $19,5*4($6) + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $13,$8 # mul_add_c(a[1],b[0],c2,c3,c1); + addu $7,$25,$1 + lw $21,6*4($6) + lw $6,7*4($6) + sw $2,0($4) # r[0]=c1; + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$8 # mul_add_c(a[2],b[0],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + sw $3,4($4) # r[1]=c2; + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$9 # mul_add_c(a[1],b[1],c3,c1,c2); + addu $25,$1 + addu $2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $12,$10 # mul_add_c(a[0],b[2],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $3,$2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $12,$11 # mul_add_c(a[0],b[3],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,2*4($4) # r[2]=c3; + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $13,$10 # mul_add_c(a[1],b[2],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $7,$3,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $14,$9 # mul_add_c(a[2],b[1],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$8 # mul_add_c(a[3],b[0],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $16,$8 # mul_add_c(a[4],b[0],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,3*4($4) # r[3]=c1; + + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $15,$9 # mul_add_c(a[3],b[1],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$10 # mul_add_c(a[2],b[2],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $13,$11 # mul_add_c(a[1],b[3],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $12,$17 # mul_add_c(a[0],b[4],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $12,$19 # mul_add_c(a[0],b[5],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,4*4($4) # r[4]=c2; + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$17 # mul_add_c(a[1],b[4],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $3,$2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $14,$11 # mul_add_c(a[2],b[3],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $15,$10 # mul_add_c(a[3],b[2],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $16,$9 # mul_add_c(a[4],b[1],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $18,$8 # mul_add_c(a[5],b[0],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $20,$8 # mul_add_c(a[6],b[0],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,5*4($4) # r[5]=c3; + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $18,$9 # mul_add_c(a[5],b[1],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $7,$3,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $16,$10 # mul_add_c(a[4],b[2],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$11 # mul_add_c(a[3],b[3],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $14,$17 # mul_add_c(a[2],b[4],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $13,$19 # mul_add_c(a[1],b[5],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $12,$21 # mul_add_c(a[0],b[6],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $12,$6 # mul_add_c(a[0],b[7],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,6*4($4) # r[6]=c1; + + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $13,$21 # mul_add_c(a[1],b[6],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$19 # mul_add_c(a[2],b[5],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $15,$17 # mul_add_c(a[3],b[4],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $16,$11 # mul_add_c(a[4],b[3],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $18,$10 # mul_add_c(a[5],b[2],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $20,$9 # mul_add_c(a[6],b[1],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $5,$8 # mul_add_c(a[7],b[0],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $5,$9 # mul_add_c(a[7],b[1],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,7*4($4) # r[7]=c2; + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $20,$10 # mul_add_c(a[6],b[2],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $3,$2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $18,$11 # mul_add_c(a[5],b[3],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $16,$17 # mul_add_c(a[4],b[4],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $15,$19 # mul_add_c(a[3],b[5],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $14,$21 # mul_add_c(a[2],b[6],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$6 # mul_add_c(a[1],b[7],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $14,$6 # mul_add_c(a[2],b[7],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,8*4($4) # r[8]=c3; + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$21 # mul_add_c(a[3],b[6],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $7,$3,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $16,$19 # mul_add_c(a[4],b[5],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $18,$17 # mul_add_c(a[5],b[4],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $20,$11 # mul_add_c(a[6],b[3],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $5,$10 # mul_add_c(a[7],b[2],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $5,$11 # mul_add_c(a[7],b[3],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,9*4($4) # r[9]=c1; + + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $20,$17 # mul_add_c(a[6],b[4],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $18,$19 # mul_add_c(a[5],b[5],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $16,$21 # mul_add_c(a[4],b[6],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $15,$6 # mul_add_c(a[3],b[7],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $16,$6 # mul_add_c(a[4],b[7],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,10*4($4) # r[10]=c2; + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $18,$21 # mul_add_c(a[5],b[6],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $3,$2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $20,$19 # mul_add_c(a[6],b[5],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $5,$17 # mul_add_c(a[7],b[4],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $5,$19 # mul_add_c(a[7],b[5],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,11*4($4) # r[11]=c3; + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $20,$21 # mul_add_c(a[6],b[6],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $7,$3,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $18,$6 # mul_add_c(a[5],b[7],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $20,$6 # mul_add_c(a[6],b[7],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,12*4($4) # r[12]=c1; + + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $5,$21 # mul_add_c(a[7],b[6],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $5,$6 # mul_add_c(a[7],b[7],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,13*4($4) # r[13]=c2; + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + addu $25,$1 + addu $2,$25 + sw $7,14*4($4) # r[14]=c3; + sw $2,15*4($4) # r[15]=c1; + + .set noreorder + lw $21,5*4($29) + lw $20,4*4($29) + lw $19,3*4($29) + lw $18,2*4($29) + lw $17,1*4($29) + lw $16,0*4($29) + jr $31 + addu $29,6*4 +.end bn_mul_comba8 + +.align 5 +.globl bn_mul_comba4 +.ent bn_mul_comba4 +bn_mul_comba4: + .set reorder + lw $12,0($5) + lw $8,0($6) + lw $13,4($5) + lw $14,2*4($5) + multu $12,$8 # mul_add_c(a[0],b[0],c1,c2,c3); + lw $15,3*4($5) + lw $9,4($6) + lw $10,2*4($6) + lw $11,3*4($6) + mflo $2 + mfhi $3 + sw $2,0($4) + + multu $12,$9 # mul_add_c(a[0],b[1],c2,c3,c1); + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $13,$8 # mul_add_c(a[1],b[0],c2,c3,c1); + addu $7,$25,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$8 # mul_add_c(a[2],b[0],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + sw $3,4($4) + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$9 # mul_add_c(a[1],b[1],c3,c1,c2); + addu $25,$1 + addu $2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $12,$10 # mul_add_c(a[0],b[2],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $3,$2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $12,$11 # mul_add_c(a[0],b[3],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,2*4($4) + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $13,$10 # mul_add_c(a[1],b[2],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $7,$3,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $14,$9 # mul_add_c(a[2],b[1],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$8 # mul_add_c(a[3],b[0],c1,c2,c3); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$9 # mul_add_c(a[3],b[1],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,3*4($4) + + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$10 # mul_add_c(a[2],b[2],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $2,$7,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $13,$11 # mul_add_c(a[1],b[3],c2,c3,c1); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$11 # mul_add_c(a[2],b[3],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,4*4($4) + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $15,$10 # mul_add_c(a[3],b[2],c3,c1,c2); + addu $25,$1 + addu $2,$25 + sltu $3,$2,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $15,$11 # mul_add_c(a[3],b[3],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,5*4($4) + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + addu $25,$1 + addu $3,$25 + sw $2,6*4($4) + sw $3,7*4($4) + + .set noreorder + jr $31 + nop +.end bn_mul_comba4 + +.align 5 +.globl bn_sqr_comba8 +.ent bn_sqr_comba8 +bn_sqr_comba8: + .set reorder + lw $12,0($5) + lw $13,4($5) + lw $14,2*4($5) + lw $15,3*4($5) + + multu $12,$12 # mul_add_c(a[0],b[0],c1,c2,c3); + lw $8,4*4($5) + lw $9,5*4($5) + lw $10,6*4($5) + lw $11,7*4($5) + mflo $2 + mfhi $3 + sw $2,0($4) + + multu $12,$13 # mul_add_c2(a[0],b[1],c2,c3,c1); + mflo $24 + mfhi $25 + slt $2,$25,$0 + sll $25,1 + multu $14,$12 # mul_add_c2(a[2],b[0],c3,c1,c2); + slt $6,$24,$0 + addu $25,$6 + sll $24,1 + addu $3,$24 + sltu $1,$3,$24 + addu $7,$25,$1 + sw $3,4($4) + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$13 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $3,$2,$1 + addu $2,$25 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $12,$15 # mul_add_c2(a[0],b[3],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,2*4($4) + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $13,$14 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $7,$3,$1 + addu $3,$25 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $8,$12 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $1,$3,$1 + addu $3,$25 + addu $7,$1 + sltu $25,$3,$25 + addu $7,$25 + sw $2,3*4($4) + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $15,$13 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $2,$7,$1 + addu $7,$25 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$14 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $1,$7,$1 + addu $7,$25 + addu $2,$1 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $12,$9 # mul_add_c2(a[0],b[5],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,4*4($4) + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$8 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $3,$2,$1 + addu $2,$25 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $14,$15 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $1,$2,$1 + addu $2,$25 + addu $3,$1 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $10,$12 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $1,$2,$1 + addu $2,$25 + addu $3,$1 + sltu $25,$2,$25 + addu $3,$25 + sw $7,5*4($4) + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $9,$13 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $7,$3,$1 + addu $3,$25 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $8,$14 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $1,$3,$1 + addu $3,$25 + addu $7,$1 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$15 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $1,$3,$1 + addu $3,$25 + addu $7,$1 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $12,$11 # mul_add_c2(a[0],b[7],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,6*4($4) + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $13,$10 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $2,$7,$1 + addu $7,$25 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$9 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $1,$7,$1 + addu $7,$25 + addu $2,$1 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $15,$8 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $1,$7,$1 + addu $7,$25 + addu $2,$1 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $11,$13 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $1,$7,$1 + addu $7,$25 + addu $2,$1 + sltu $25,$7,$25 + addu $2,$25 + sw $3,7*4($4) + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $10,$14 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $3,$2,$1 + addu $2,$25 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $9,$15 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $1,$2,$1 + addu $2,$25 + addu $3,$1 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $8,$8 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $1,$2,$1 + addu $2,$25 + addu $3,$1 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $14,$11 # mul_add_c2(a[2],b[7],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,8*4($4) + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$10 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $7,$3,$1 + addu $3,$25 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $8,$9 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $1,$3,$1 + addu $3,$25 + addu $7,$1 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $11,$15 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $1,$3,$1 + addu $3,$25 + addu $7,$1 + sltu $25,$3,$25 + addu $7,$25 + sw $2,9*4($4) + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $10,$8 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $2,$7,$1 + addu $7,$25 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $9,$9 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $1,$7,$1 + addu $7,$25 + addu $2,$1 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $8,$11 # mul_add_c2(a[4],b[7],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,10*4($4) + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $9,$10 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $3,$2,$1 + addu $2,$25 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $11,$9 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $1,$2,$1 + addu $2,$25 + addu $3,$1 + sltu $25,$2,$25 + addu $3,$25 + sw $7,11*4($4) + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $10,$10 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $7,$3,$1 + addu $3,$25 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $10,$11 # mul_add_c2(a[6],b[7],c2,c3,c1); + addu $25,$1 + addu $3,$25 + sltu $1,$3,$25 + addu $7,$1 + sw $2,12*4($4) + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $11,$11 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $2,$7,$1 + addu $7,$25 + sltu $25,$7,$25 + addu $2,$25 + sw $3,13*4($4) + + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + addu $25,$1 + addu $2,$25 + sw $7,14*4($4) + sw $2,15*4($4) + + .set noreorder + jr $31 + nop +.end bn_sqr_comba8 + +.align 5 +.globl bn_sqr_comba4 +.ent bn_sqr_comba4 +bn_sqr_comba4: + .set reorder + lw $12,0($5) + lw $13,4($5) + multu $12,$12 # mul_add_c(a[0],b[0],c1,c2,c3); + lw $14,2*4($5) + lw $15,3*4($5) + mflo $2 + mfhi $3 + sw $2,0($4) + + multu $12,$13 # mul_add_c2(a[0],b[1],c2,c3,c1); + mflo $24 + mfhi $25 + slt $2,$25,$0 + sll $25,1 + multu $14,$12 # mul_add_c2(a[2],b[0],c3,c1,c2); + slt $6,$24,$0 + addu $25,$6 + sll $24,1 + addu $3,$24 + sltu $1,$3,$24 + addu $7,$25,$1 + sw $3,4($4) + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $13,$13 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $3,$2,$1 + addu $2,$25 + sltu $25,$2,$25 + addu $3,$25 + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $12,$15 # mul_add_c2(a[0],b[3],c1,c2,c3); + addu $25,$1 + addu $2,$25 + sltu $1,$2,$25 + addu $3,$1 + sw $7,2*4($4) + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $13,$14 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $7,$3,$1 + addu $3,$25 + sltu $25,$3,$25 + addu $7,$25 + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + multu $15,$13 # forward multiplication + addu $2,$24 + addu $1,$25 + sltu $24,$2,$24 + addu $3,$1 + addu $25,$24 + sltu $1,$3,$1 + addu $3,$25 + addu $7,$1 + sltu $25,$3,$25 + addu $7,$25 + sw $2,3*4($4) + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$14 # forward multiplication + addu $3,$24 + addu $1,$25 + sltu $24,$3,$24 + addu $7,$1 + addu $25,$24 + sltu $2,$7,$1 + addu $7,$25 + sltu $25,$7,$25 + addu $2,$25 + mflo $24 + mfhi $25 + addu $3,$24 + sltu $1,$3,$24 + multu $14,$15 # mul_add_c2(a[2],b[3],c3,c1,c2); + addu $25,$1 + addu $7,$25 + sltu $1,$7,$25 + addu $2,$1 + sw $3,4*4($4) + mflo $24 + mfhi $25 + addu $7,$24 + sltu $1,$7,$24 + multu $15,$15 # forward multiplication + addu $7,$24 + addu $1,$25 + sltu $24,$7,$24 + addu $2,$1 + addu $25,$24 + sltu $3,$2,$1 + addu $2,$25 + sltu $25,$2,$25 + addu $3,$25 + sw $7,5*4($4) + + mflo $24 + mfhi $25 + addu $2,$24 + sltu $1,$2,$24 + addu $25,$1 + addu $3,$25 + sw $2,6*4($4) + sw $3,7*4($4) + + .set noreorder + jr $31 + nop +.end bn_sqr_comba4 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/bn_add.c b/Libraries/libressl/crypto/bn/bn_add.c new file mode 100644 index 000000000..86768a312 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_add.c @@ -0,0 +1,341 @@ +/* $OpenBSD: bn_add.c,v 1.26 2023/07/08 12:21:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include "bn_arch.h" +#include "bn_local.h" +#include "bn_internal.h" + +/* + * bn_add_words() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b + * are both arrays of words. Any carry resulting from the addition is returned. + */ +#ifndef HAVE_BN_ADD_WORDS +BN_ULONG +bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) +{ + BN_ULONG carry = 0; + + assert(n >= 0); + if (n <= 0) + return 0; + + while (n & ~3) { + bn_qwaddqw(a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0], + carry, &carry, &r[3], &r[2], &r[1], &r[0]); + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + bn_addw_addw(a[0], b[0], carry, &carry, &r[0]); + a++; + b++; + r++; + n--; + } + return carry; +} +#endif + +/* + * bn_add() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b are both + * arrays of words (r may be the same as a or b). The length of a and b may + * differ, while r must be at least max(a_len, b_len) in length. Any carry + * resulting from the addition is returned. + */ +#ifndef HAVE_BN_ADD +BN_ULONG +bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, + int b_len) +{ + int min_len, diff_len; + BN_ULONG carry = 0; + + if ((min_len = a_len) > b_len) + min_len = b_len; + + diff_len = a_len - b_len; + + carry = bn_add_words(r, a, b, min_len); + + a += min_len; + b += min_len; + r += min_len; + + /* XXX - consider doing four at a time to match bn_add_words(). */ + while (diff_len < 0) { + /* Compute r[0] = 0 + b[0] + carry. */ + bn_addw(b[0], carry, &carry, &r[0]); + diff_len++; + b++; + r++; + } + + /* XXX - consider doing four at a time to match bn_add_words(). */ + while (diff_len > 0) { + /* Compute r[0] = a[0] + 0 + carry. */ + bn_addw(a[0], carry, &carry, &r[0]); + diff_len--; + a++; + r++; + } + + return carry; +} +#endif + +/* + * bn_sub_words() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b + * are both arrays of words. Any borrow resulting from the subtraction is + * returned. + */ +#ifndef HAVE_BN_SUB_WORDS +BN_ULONG +bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) +{ + BN_ULONG borrow = 0; + + assert(n >= 0); + if (n <= 0) + return 0; + + while (n & ~3) { + bn_qwsubqw(a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0], + borrow, &borrow, &r[3], &r[2], &r[1], &r[0]); + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]); + a++; + b++; + r++; + n--; + } + return borrow; +} +#endif + +/* + * bn_sub() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b are both + * arrays of words (r may be the same as a or b). The length of a and b may + * differ, while r must be at least max(a_len, b_len) in length. Any borrow + * resulting from the subtraction is returned. + */ +#ifndef HAVE_BN_SUB +BN_ULONG +bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, + int b_len) +{ + int min_len, diff_len; + BN_ULONG borrow = 0; + + if ((min_len = a_len) > b_len) + min_len = b_len; + + diff_len = a_len - b_len; + + borrow = bn_sub_words(r, a, b, min_len); + + a += min_len; + b += min_len; + r += min_len; + + /* XXX - consider doing four at a time to match bn_sub_words. */ + while (diff_len < 0) { + /* Compute r[0] = 0 - b[0] - borrow. */ + bn_subw(0 - b[0], borrow, &borrow, &r[0]); + diff_len++; + b++; + r++; + } + + /* XXX - consider doing four at a time to match bn_sub_words. */ + while (diff_len > 0) { + /* Compute r[0] = a[0] - 0 - borrow. */ + bn_subw(a[0], borrow, &borrow, &r[0]); + diff_len--; + a++; + r++; + } + + return borrow; +} +#endif + +int +BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + BN_ULONG carry; + int rn; + + if ((rn = a->top) < b->top) + rn = b->top; + if (rn == INT_MAX) + return 0; + if (!bn_wexpand(r, rn + 1)) + return 0; + + carry = bn_add(r->d, rn, a->d, a->top, b->d, b->top); + r->d[rn] = carry; + + r->top = rn + (carry & 1); + r->neg = 0; + + return 1; +} +LCRYPTO_ALIAS(BN_uadd); + +int +BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + BN_ULONG borrow; + int rn; + + if (a->top < b->top) { + BNerror(BN_R_ARG2_LT_ARG3); + return 0; + } + rn = a->top; + + if (!bn_wexpand(r, rn)) + return 0; + + borrow = bn_sub(r->d, rn, a->d, a->top, b->d, b->top); + if (borrow > 0) { + BNerror(BN_R_ARG2_LT_ARG3); + return 0; + } + + r->top = rn; + r->neg = 0; + + bn_correct_top(r); + + return 1; +} +LCRYPTO_ALIAS(BN_usub); + +int +BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int ret, r_neg; + + if (a->neg == b->neg) { + r_neg = a->neg; + ret = BN_uadd(r, a, b); + } else { + int cmp = BN_ucmp(a, b); + + if (cmp > 0) { + r_neg = a->neg; + ret = BN_usub(r, a, b); + } else if (cmp < 0) { + r_neg = b->neg; + ret = BN_usub(r, b, a); + } else { + r_neg = 0; + BN_zero(r); + ret = 1; + } + } + + BN_set_negative(r, r_neg); + + return ret; +} +LCRYPTO_ALIAS(BN_add); + +int +BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int ret, r_neg; + + if (a->neg != b->neg) { + r_neg = a->neg; + ret = BN_uadd(r, a, b); + } else { + int cmp = BN_ucmp(a, b); + + if (cmp > 0) { + r_neg = a->neg; + ret = BN_usub(r, a, b); + } else if (cmp < 0) { + r_neg = !b->neg; + ret = BN_usub(r, b, a); + } else { + r_neg = 0; + BN_zero(r); + ret = 1; + } + } + + BN_set_negative(r, r_neg); + + return ret; +} +LCRYPTO_ALIAS(BN_sub); diff --git a/Libraries/libressl/crypto/bn/bn_bpsw.c b/Libraries/libressl/crypto/bn/bn_bpsw.c new file mode 100644 index 000000000..14f2800ad --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_bpsw.c @@ -0,0 +1,534 @@ +/* $OpenBSD: bn_bpsw.c,v 1.11 2023/08/03 18:53:55 tb Exp $ */ +/* + * Copyright (c) 2022 Martin Grenouilloux + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bn_local.h" +#include "bn_prime.h" + +/* + * For an odd n compute a / 2 (mod n). If a is even, we can do a plain + * division, otherwise calculate (a + n) / 2. Then reduce (mod n). + */ + +static int +bn_div_by_two_mod_odd_n(BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) +{ + if (!BN_is_odd(n)) + return 0; + + if (BN_is_odd(a)) { + if (!BN_add(a, a, n)) + return 0; + } + if (!BN_rshift1(a, a)) + return 0; + if (!BN_mod_ct(a, a, n, ctx)) + return 0; + + return 1; +} + +/* + * Given the next binary digit of k and the current Lucas terms U and V, this + * helper computes the next terms in the Lucas sequence defined as follows: + * + * U' = U * V (mod n) + * V' = (V^2 + D * U^2) / 2 (mod n) + * + * If digit == 0, bn_lucas_step() returns U' and V'. If digit == 1, it returns + * + * U'' = (U' + V') / 2 (mod n) + * V'' = (V' + D * U') / 2 (mod n) + * + * Compare with FIPS 186-4, Appendix C.3.3, step 6. + */ + +static int +bn_lucas_step(BIGNUM *U, BIGNUM *V, int digit, const BIGNUM *D, + const BIGNUM *n, BN_CTX *ctx) +{ + BIGNUM *tmp; + int ret = 0; + + BN_CTX_start(ctx); + + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Calculate D * U^2 before computing U'. */ + if (!BN_sqr(tmp, U, ctx)) + goto err; + if (!BN_mul(tmp, D, tmp, ctx)) + goto err; + + /* U' = U * V (mod n). */ + if (!BN_mod_mul(U, U, V, n, ctx)) + goto err; + + /* V' = (V^2 + D * U^2) / 2 (mod n). */ + if (!BN_sqr(V, V, ctx)) + goto err; + if (!BN_add(V, V, tmp)) + goto err; + if (!bn_div_by_two_mod_odd_n(V, n, ctx)) + goto err; + + if (digit == 1) { + /* Calculate D * U' before computing U''. */ + if (!BN_mul(tmp, D, U, ctx)) + goto err; + + /* U'' = (U' + V') / 2 (mod n). */ + if (!BN_add(U, U, V)) + goto err; + if (!bn_div_by_two_mod_odd_n(U, n, ctx)) + goto err; + + /* V'' = (V' + D * U') / 2 (mod n). */ + if (!BN_add(V, V, tmp)) + goto err; + if (!bn_div_by_two_mod_odd_n(V, n, ctx)) + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Compute the Lucas terms U_k, V_k, see FIPS 186-4, Appendix C.3.3, steps 4-6. + */ + +static int +bn_lucas(BIGNUM *U, BIGNUM *V, const BIGNUM *k, const BIGNUM *D, + const BIGNUM *n, BN_CTX *ctx) +{ + int digit, i; + int ret = 0; + + if (!BN_one(U)) + goto err; + if (!BN_one(V)) + goto err; + + /* + * Iterate over the digits of k from MSB to LSB. Start at digit 2 + * since the first digit is dealt with by setting U = 1 and V = 1. + */ + + for (i = BN_num_bits(k) - 2; i >= 0; i--) { + digit = BN_is_bit_set(k, i); + + if (!bn_lucas_step(U, V, digit, D, n, ctx)) + goto err; + } + + ret = 1; + + err: + return ret; +} + +/* + * This is a stronger variant of the Lucas test in FIPS 186-4, Appendix C.3.3. + * Every strong Lucas pseudoprime n is also a Lucas pseudoprime since + * U_{n+1} == 0 follows from U_k == 0 or V_{k * 2^r} == 0 for 0 <= r < s. + */ + +static int +bn_strong_lucas_test(int *is_pseudoprime, const BIGNUM *n, const BIGNUM *D, + BN_CTX *ctx) +{ + BIGNUM *k, *U, *V; + int r, s; + int ret = 0; + + BN_CTX_start(ctx); + + if ((k = BN_CTX_get(ctx)) == NULL) + goto err; + if ((U = BN_CTX_get(ctx)) == NULL) + goto err; + if ((V = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Factorize n + 1 = k * 2^s with odd k: shift away the s trailing ones + * of n and set the lowest bit of the resulting number k. + */ + + s = 0; + while (BN_is_bit_set(n, s)) + s++; + if (!BN_rshift(k, n, s)) + goto err; + if (!BN_set_bit(k, 0)) + goto err; + + /* + * Calculate the Lucas terms U_k and V_k. If either of them is zero, + * then n is a strong Lucas pseudoprime. + */ + + if (!bn_lucas(U, V, k, D, n, ctx)) + goto err; + + if (BN_is_zero(U) || BN_is_zero(V)) { + *is_pseudoprime = 1; + goto done; + } + + /* + * Calculate the Lucas terms U_{k * 2^r}, V_{k * 2^r} for 1 <= r < s. + * If any V_{k * 2^r} is zero then n is a strong Lucas pseudoprime. + */ + + for (r = 1; r < s; r++) { + if (!bn_lucas_step(U, V, 0, D, n, ctx)) + goto err; + + if (BN_is_zero(V)) { + *is_pseudoprime = 1; + goto done; + } + } + + /* + * If we got here, n is definitely composite. + */ + + *is_pseudoprime = 0; + + done: + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Test n for primality using the strong Lucas test with Selfridge's Method A. + * Returns 1 if n is prime or a strong Lucas-Selfridge pseudoprime. + * If it returns 0 then n is definitely composite. + */ + +static int +bn_strong_lucas_selfridge(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx) +{ + BIGNUM *D, *two; + int is_perfect_square, jacobi_symbol, sign; + int ret = 0; + + BN_CTX_start(ctx); + + /* If n is a perfect square, it is composite. */ + if (!bn_is_perfect_square(&is_perfect_square, n, ctx)) + goto err; + if (is_perfect_square) { + *is_pseudoprime = 0; + goto done; + } + + /* + * Find the first D in the Selfridge sequence 5, -7, 9, -11, 13, ... + * such that the Jacobi symbol (D/n) is -1. + */ + + if ((D = BN_CTX_get(ctx)) == NULL) + goto err; + if ((two = BN_CTX_get(ctx)) == NULL) + goto err; + + sign = 1; + if (!BN_set_word(D, 5)) + goto err; + if (!BN_set_word(two, 2)) + goto err; + + while (1) { + /* For odd n the Kronecker symbol computes the Jacobi symbol. */ + if ((jacobi_symbol = BN_kronecker(D, n, ctx)) == -2) + goto err; + + /* We found the value for D. */ + if (jacobi_symbol == -1) + break; + + /* n and D have prime factors in common. */ + if (jacobi_symbol == 0) { + *is_pseudoprime = 0; + goto done; + } + + sign = -sign; + if (!BN_uadd(D, D, two)) + goto err; + BN_set_negative(D, sign == -1); + } + + if (!bn_strong_lucas_test(is_pseudoprime, n, D, ctx)) + goto err; + + done: + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Fermat criterion in Miller-Rabin test. + * + * Check whether 1 < base < n - 1 witnesses that n is composite. For prime n: + * + * * Fermat's little theorem: base^(n-1) = 1 (mod n). + * * The only square roots of 1 (mod n) are 1 and -1. + * + * Calculate base^((n-1)/2) by writing n - 1 = k * 2^s with odd k. Iteratively + * compute power = (base^k)^(2^(s-1)) by successive squaring of base^k. + * + * If power ever reaches -1, base^(n-1) is equal to 1 and n is a pseudoprime + * for base. If power reaches 1 before -1 during successive squaring, we have + * an unexpected square root of 1 and n is composite. Otherwise base^(n-1) != 1, + * and n is composite. + */ + +static int +bn_fermat(int *is_pseudoprime, const BIGNUM *n, const BIGNUM *n_minus_one, + const BIGNUM *k, int s, const BIGNUM *base, BN_CTX *ctx, BN_MONT_CTX *mctx) +{ + BIGNUM *power; + int ret = 0; + int i; + + BN_CTX_start(ctx); + + if ((power = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Sanity check: ensure that 1 < base < n - 1. */ + if (BN_cmp(base, BN_value_one()) <= 0 || BN_cmp(base, n_minus_one) >= 0) + goto err; + + if (!BN_mod_exp_mont_ct(power, base, k, n, ctx, mctx)) + goto err; + + if (BN_is_one(power) || BN_cmp(power, n_minus_one) == 0) { + *is_pseudoprime = 1; + goto done; + } + + /* Loop invariant: power is neither 1 nor -1 (mod n). */ + for (i = 1; i < s; i++) { + if (!BN_mod_sqr(power, power, n, ctx)) + goto err; + + /* n is a pseudoprime for base. */ + if (BN_cmp(power, n_minus_one) == 0) { + *is_pseudoprime = 1; + goto done; + } + + /* n is composite: there's a square root of unity != 1 or -1. */ + if (BN_is_one(power)) { + *is_pseudoprime = 0; + goto done; + } + } + + /* + * If we get here, n is definitely composite: base^(n-1) != 1. + */ + + *is_pseudoprime = 0; + + done: + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Miller-Rabin primality test for base 2 and for |rounds| of random bases. + * On success: is_pseudoprime == 0 implies that n is composite. + */ + +static int +bn_miller_rabin(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx, + size_t rounds) +{ + BN_MONT_CTX *mctx = NULL; + BIGNUM *base, *k, *n_minus_one; + size_t i; + int s; + int ret = 0; + + BN_CTX_start(ctx); + + if ((base = BN_CTX_get(ctx)) == NULL) + goto err; + if ((k = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n_minus_one = BN_CTX_get(ctx)) == NULL) + goto err; + + if (BN_is_word(n, 2) || BN_is_word(n, 3)) { + *is_pseudoprime = 1; + goto done; + } + + if (BN_cmp(n, BN_value_one()) <= 0 || !BN_is_odd(n)) { + *is_pseudoprime = 0; + goto done; + } + + if (!BN_sub(n_minus_one, n, BN_value_one())) + goto err; + + /* + * Factorize n - 1 = k * 2^s. + */ + + s = 0; + while (!BN_is_bit_set(n_minus_one, s)) + s++; + if (!BN_rshift(k, n_minus_one, s)) + goto err; + + /* + * Montgomery setup for n. + */ + + if ((mctx = BN_MONT_CTX_new()) == NULL) + goto err; + + if (!BN_MONT_CTX_set(mctx, n, ctx)) + goto err; + + /* + * Perform a Miller-Rabin test for base 2 as required by BPSW. + */ + + if (!BN_set_word(base, 2)) + goto err; + + if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx, mctx)) + goto err; + if (!*is_pseudoprime) + goto done; + + /* + * Perform Miller-Rabin tests with random 3 <= base < n - 1 to reduce + * risk of false positives in BPSW. + */ + + for (i = 0; i < rounds; i++) { + if (!bn_rand_interval(base, 3, n_minus_one)) + goto err; + + if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx, + mctx)) + goto err; + if (!*is_pseudoprime) + goto done; + } + + /* + * If we got here, we have a Miller-Rabin pseudoprime. + */ + + *is_pseudoprime = 1; + + done: + ret = 1; + + err: + BN_MONT_CTX_free(mctx); + BN_CTX_end(ctx); + + return ret; +} + +/* + * The Baillie-Pomerance-Selfridge-Wagstaff algorithm combines a Miller-Rabin + * test for base 2 with a Strong Lucas pseudoprime test. + */ + +int +bn_is_prime_bpsw(int *is_pseudoprime, const BIGNUM *n, BN_CTX *in_ctx, + size_t rounds) +{ + BN_CTX *ctx = NULL; + BN_ULONG mod; + int i; + int ret = 0; + + if (BN_is_word(n, 2)) { + *is_pseudoprime = 1; + goto done; + } + + if (BN_cmp(n, BN_value_one()) <= 0 || !BN_is_odd(n)) { + *is_pseudoprime = 0; + goto done; + } + + /* Trial divisions with the first 2048 primes. */ + for (i = 0; i < NUMPRIMES; i++) { + if ((mod = BN_mod_word(n, primes[i])) == (BN_ULONG)-1) + goto err; + if (mod == 0) { + *is_pseudoprime = BN_is_word(n, primes[i]); + goto done; + } + } + + if ((ctx = in_ctx) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (!bn_miller_rabin(is_pseudoprime, n, ctx, rounds)) + goto err; + if (!*is_pseudoprime) + goto done; + + if (!bn_strong_lucas_selfridge(is_pseudoprime, n, ctx)) + goto err; + + done: + ret = 1; + + err: + if (ctx != in_ctx) + BN_CTX_free(ctx); + + return ret; +} diff --git a/Libraries/libressl/crypto/bn/bn_const.c b/Libraries/libressl/crypto/bn/bn_const.c new file mode 100644 index 000000000..bf684c8a4 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_const.c @@ -0,0 +1,433 @@ +/* $OpenBSD: bn_const.c,v 1.8 2023/07/28 10:07:30 tb Exp $ */ +/* Insert boilerplate */ + +#include + +/* + * "First Oakley Default Group" from RFC2409, section 6.1. + * + * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } + * + * RFC2409 specifies a generator of 2. + * RFC2412 specifies a generator of of 22. + */ + +static const unsigned char RFC2409_PRIME_768[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc2409_prime_768(BIGNUM *bn) +{ + return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn); +} +LCRYPTO_ALIAS(BN_get_rfc2409_prime_768); + +/* + * "Second Oakley Default Group" from RFC2409, section 6.2. + * + * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. + * + * RFC2409 specifies a generator of 2. + * RFC2412 specifies a generator of 22. + */ + +static const unsigned char RFC2409_PRIME_1024[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc2409_prime_1024(BIGNUM *bn) +{ + return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn); +} +LCRYPTO_ALIAS(BN_get_rfc2409_prime_1024); + +/* + * "1536-bit MODP Group" from RFC3526, Section 2. + * + * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + * + * RFC3526 specifies a generator of 2. + * RFC2312 specifies a generator of 22. + */ + +static const unsigned char RFC3526_PRIME_1536[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, + 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc3526_prime_1536(BIGNUM *bn) +{ + return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn); +} +LCRYPTO_ALIAS(BN_get_rfc3526_prime_1536); + +/* + * "2048-bit MODP Group" from RFC3526, Section 3. + * + * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + * + * RFC3526 specifies a generator of 2. + */ + +static const unsigned char RFC3526_PRIME_2048[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, + 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, + 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, + 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc3526_prime_2048(BIGNUM *bn) +{ + return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn); +} +LCRYPTO_ALIAS(BN_get_rfc3526_prime_2048); + +/* + * "3072-bit MODP Group" from RFC3526, Section 4. + * + * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + * + * RFC3526 specifies a generator of 2. + */ + +static const unsigned char RFC3526_PRIME_3072[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, + 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, + 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, + 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, + 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, + 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, + 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, + 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, + 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, + 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc3526_prime_3072(BIGNUM *bn) +{ + return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn); +} +LCRYPTO_ALIAS(BN_get_rfc3526_prime_3072); + +/* + * "4096-bit MODP Group" from RFC3526, Section 5. + * + * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + * + * RFC3526 specifies a generator of 2. + */ + +static const unsigned char RFC3526_PRIME_4096[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, + 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, + 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, + 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, + 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, + 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, + 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, + 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, + 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, + 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, + 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB, + 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, + 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76, + 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, + 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc3526_prime_4096(BIGNUM *bn) +{ + return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn); +} +LCRYPTO_ALIAS(BN_get_rfc3526_prime_4096); + +/* + * "6144-bit MODP Group" from RFC3526, Section 6. + * + * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } + * + * RFC3526 specifies a generator of 2. + */ + +static const unsigned char RFC3526_PRIME_6144[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, + 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, + 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, + 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, + 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, + 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, + 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, + 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, + 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, + 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, + 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB, + 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, + 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76, + 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, + 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2, + 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F, + 0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB, + 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51, + 0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15, + 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31, + 0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7, + 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2, + 0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D, + 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7, + 0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E, + 0x6D, 0xCC, 0x40, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc3526_prime_6144(BIGNUM *bn) +{ + return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn); +} +LCRYPTO_ALIAS(BN_get_rfc3526_prime_6144); + +/* + * "8192-bit MODP Group" from RFC3526, Section 7. + * + * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } + * + * RFC3526 specifies a generator of 2. + */ + +static const unsigned char RFC3526_PRIME_8192[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, + 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, + 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, + 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, + 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, + 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, + 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, + 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, + 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, + 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, + 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB, + 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, + 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76, + 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, + 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2, + 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F, + 0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB, + 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51, + 0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15, + 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31, + 0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7, + 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2, + 0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D, + 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7, + 0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E, + 0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, + 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0, + 0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, + 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93, + 0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, + 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB, + 0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, + 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8, + 0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, + 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F, + 0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, + 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8, + 0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, + 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5, + 0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, + 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3, + 0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, + 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E, + 0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, + 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2, + 0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, + 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, +}; + +BIGNUM * +BN_get_rfc3526_prime_8192(BIGNUM *bn) +{ + return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn); +} +LCRYPTO_ALIAS(BN_get_rfc3526_prime_8192); diff --git a/Libraries/libressl/crypto/bn/bn_convert.c b/Libraries/libressl/crypto/bn/bn_convert.c new file mode 100644 index 000000000..f09c9091e --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_convert.c @@ -0,0 +1,773 @@ +/* $OpenBSD: bn_convert.c,v 1.15 2023/07/09 18:37:58 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "bn_local.h" +#include "bytestring.h" + +static int bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs); +static int bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs); + +static const char hex_digits[] = "0123456789ABCDEF"; + +typedef enum { + big, + little, +} endianness_t; + +/* ignore negative */ +static int +bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness) +{ + int n; + size_t i, lasti, j, atop, mask; + BN_ULONG l; + + /* + * In case |a| is fixed-top, BN_num_bytes can return bogus length, + * but it's assumed that fixed-top inputs ought to be "nominated" + * even for padded output, so it works out... + */ + n = BN_num_bytes(a); + if (tolen == -1) + tolen = n; + else if (tolen < n) { /* uncommon/unlike case */ + BIGNUM temp = *a; + + bn_correct_top(&temp); + + n = BN_num_bytes(&temp); + if (tolen < n) + return -1; + } + + /* Swipe through whole available data and don't give away padded zero. */ + atop = a->dmax * BN_BYTES; + if (atop == 0) { + explicit_bzero(to, tolen); + return tolen; + } + + lasti = atop - 1; + atop = a->top * BN_BYTES; + + if (endianness == big) + to += tolen; /* start from the end of the buffer */ + + for (i = 0, j = 0; j < (size_t)tolen; j++) { + unsigned char val; + + l = a->d[i / BN_BYTES]; + mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); + val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); + + if (endianness == big) + *--to = val; + else + *to++ = val; + + i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ + } + + return tolen; +} + +int +BN_bn2bin(const BIGNUM *a, unsigned char *to) +{ + return bn2binpad(a, to, -1, big); +} +LCRYPTO_ALIAS(BN_bn2bin); + +int +BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) +{ + if (tolen < 0) + return -1; + return bn2binpad(a, to, tolen, big); +} +LCRYPTO_ALIAS(BN_bn2binpad); + +BIGNUM * +BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + unsigned int i, m; + unsigned int n; + BN_ULONG l; + BIGNUM *bn = NULL; + + if (len < 0) + return (NULL); + if (ret == NULL) + ret = bn = BN_new(); + if (ret == NULL) + return (NULL); + l = 0; + n = len; + if (n == 0) { + ret->top = 0; + return (ret); + } + i = ((n - 1) / BN_BYTES) + 1; + m = ((n - 1) % (BN_BYTES)); + if (!bn_wexpand(ret, (int)i)) { + BN_free(bn); + return NULL; + } + ret->top = i; + ret->neg = 0; + while (n--) { + l = (l << 8L) | *(s++); + if (m-- == 0) { + ret->d[--i] = l; + l = 0; + m = BN_BYTES - 1; + } + } + /* need to call this due to clear byte at top if avoiding + * having the top bit set (-ve number) */ + bn_correct_top(ret); + return (ret); +} +LCRYPTO_ALIAS(BN_bin2bn); + +int +BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) +{ + if (tolen < 0) + return -1; + + return bn2binpad(a, to, tolen, little); +} +LCRYPTO_ALIAS(BN_bn2lebinpad); + +BIGNUM * +BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + unsigned int i, m, n; + BN_ULONG l; + BIGNUM *bn = NULL; + + if (ret == NULL) + ret = bn = BN_new(); + if (ret == NULL) + return NULL; + + + s += len; + /* Skip trailing zeroes. */ + for (; len > 0 && s[-1] == 0; s--, len--) + continue; + + n = len; + if (n == 0) { + ret->top = 0; + return ret; + } + + i = ((n - 1) / BN_BYTES) + 1; + m = (n - 1) % BN_BYTES; + if (!bn_wexpand(ret, (int)i)) { + BN_free(bn); + return NULL; + } + + ret->top = i; + ret->neg = 0; + l = 0; + while (n-- > 0) { + s--; + l = (l << 8L) | *s; + if (m-- == 0) { + ret->d[--i] = l; + l = 0; + m = BN_BYTES - 1; + } + } + + /* + * need to call this due to clear byte at top if avoiding having the + * top bit set (-ve number) + */ + bn_correct_top(ret); + + return ret; +} +LCRYPTO_ALIAS(BN_lebin2bn); + +int +BN_asc2bn(BIGNUM **bnp, const char *s) +{ + CBS cbs, cbs_hex; + size_t s_len; + uint8_t v; + int neg; + + if (bnp != NULL && *bnp != NULL) + BN_zero(*bnp); + + if (s == NULL) + return 0; + if ((s_len = strlen(s)) == 0) + return 0; + + CBS_init(&cbs, s, s_len); + + /* Handle negative sign. */ + if (!CBS_peek_u8(&cbs, &v)) + return 0; + if ((neg = (v == '-'))) { + if (!CBS_skip(&cbs, 1)) + return 0; + } + + /* Try parsing as hexadecimal with a 0x prefix. */ + CBS_dup(&cbs, &cbs_hex); + if (!CBS_get_u8(&cbs_hex, &v)) + goto decimal; + if (v != '0') + goto decimal; + if (!CBS_get_u8(&cbs_hex, &v)) + goto decimal; + if (v != 'X' && v != 'x') + goto decimal; + if (bn_hex2bn_cbs(bnp, &cbs_hex) == 0) + return 0; + + goto done; + + decimal: + if (bn_dec2bn_cbs(bnp, &cbs) == 0) + return 0; + + done: + if (bnp != NULL && *bnp != NULL) + BN_set_negative(*bnp, neg); + + return 1; +} +LCRYPTO_ALIAS(BN_asc2bn); + +char * +BN_bn2dec(const BIGNUM *bn) +{ + int started = 0; + BIGNUM *tmp = NULL; + uint8_t *data = NULL; + size_t data_len = 0; + uint8_t *s = NULL; + size_t s_len; + BN_ULONG v, w; + uint8_t c; + CBB cbb; + CBS cbs; + int i; + + if (!CBB_init(&cbb, 0)) + goto err; + + if ((tmp = BN_dup(bn)) == NULL) + goto err; + + /* + * Divide the BIGNUM by a large multiple of 10, then break the remainder + * into decimal digits. This produces a reversed string of digits, + * potentially with leading zeroes. + */ + while (!BN_is_zero(tmp)) { + if ((w = BN_div_word(tmp, BN_DEC_CONV)) == -1) + goto err; + for (i = 0; i < BN_DEC_NUM; i++) { + v = w % 10; + if (!CBB_add_u8(&cbb, '0' + v)) + goto err; + w /= 10; + } + } + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; + + if (data_len > SIZE_MAX - 3) + goto err; + if (!CBB_init(&cbb, data_len + 3)) + goto err; + + if (BN_is_negative(bn)) { + if (!CBB_add_u8(&cbb, '-')) + goto err; + } + + /* Reverse digits and trim leading zeroes. */ + CBS_init(&cbs, data, data_len); + while (CBS_len(&cbs) > 0) { + if (!CBS_get_last_u8(&cbs, &c)) + goto err; + if (!started && c == '0') + continue; + if (!CBB_add_u8(&cbb, c)) + goto err; + started = 1; + } + + if (!started) { + if (!CBB_add_u8(&cbb, '0')) + goto err; + } + if (!CBB_add_u8(&cbb, '\0')) + goto err; + if (!CBB_finish(&cbb, &s, &s_len)) + goto err; + + err: + BN_free(tmp); + CBB_cleanup(&cbb); + freezero(data, data_len); + + return s; +} +LCRYPTO_ALIAS(BN_bn2dec); + +static int +bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs) +{ + CBS cbs_digits; + BIGNUM *bn = NULL; + int d, neg, num; + size_t digits = 0; + BN_ULONG w; + uint8_t v; + + /* Handle negative sign. */ + if (!CBS_peek_u8(cbs, &v)) + goto err; + if ((neg = (v == '-'))) { + if (!CBS_skip(cbs, 1)) + goto err; + } + + /* Scan to find last decimal digit. */ + CBS_dup(cbs, &cbs_digits); + while (CBS_len(&cbs_digits) > 0) { + if (!CBS_get_u8(&cbs_digits, &v)) + goto err; + if (!isdigit(v)) + break; + digits++; + } + if (digits > INT_MAX / 4) + goto err; + + num = digits + neg; + + if (bnp == NULL) + return num; + + if ((bn = *bnp) == NULL) + bn = BN_new(); + if (bn == NULL) + goto err; + if (!bn_expand(bn, digits * 4)) + goto err; + + if ((d = digits % BN_DEC_NUM) == 0) + d = BN_DEC_NUM; + + w = 0; + + /* Work forwards from most significant digit. */ + while (digits-- > 0) { + if (!CBS_get_u8(cbs, &v)) + goto err; + + if (v < '0' || v > '9') + goto err; + + v -= '0'; + w = w * 10 + v; + d--; + + if (d == 0) { + if (!BN_mul_word(bn, BN_DEC_CONV)) + goto err; + if (!BN_add_word(bn, w)) + goto err; + + d = BN_DEC_NUM; + w = 0; + } + } + + bn_correct_top(bn); + + BN_set_negative(bn, neg); + + *bnp = bn; + + return num; + + err: + if (bnp != NULL && *bnp == NULL) + BN_free(bn); + + return 0; +} + +int +BN_dec2bn(BIGNUM **bnp, const char *s) +{ + size_t s_len; + CBS cbs; + + if (bnp != NULL && *bnp != NULL) + BN_zero(*bnp); + + if (s == NULL) + return 0; + if ((s_len = strlen(s)) == 0) + return 0; + + CBS_init(&cbs, s, s_len); + + return bn_dec2bn_cbs(bnp, &cbs); +} +LCRYPTO_ALIAS(BN_dec2bn); + +static int +bn_bn2hex_internal(const BIGNUM *bn, int include_sign, int nibbles_only, + char **out, size_t *out_len) +{ + int started = 0; + uint8_t *s = NULL; + size_t s_len = 0; + BN_ULONG v, w; + int i, j; + CBB cbb; + CBS cbs; + uint8_t nul; + int ret = 0; + + *out = NULL; + *out_len = 0; + + if (!CBB_init(&cbb, 0)) + goto err; + + if (BN_is_negative(bn) && include_sign) { + if (!CBB_add_u8(&cbb, '-')) + goto err; + } + if (BN_is_zero(bn)) { + if (!CBB_add_u8(&cbb, '0')) + goto err; + } + for (i = bn->top - 1; i >= 0; i--) { + w = bn->d[i]; + for (j = BN_BITS2 - 8; j >= 0; j -= 8) { + v = (w >> j) & 0xff; + if (!started && v == 0) + continue; + if (started || !nibbles_only || (v >> 4) != 0) { + if (!CBB_add_u8(&cbb, hex_digits[v >> 4])) + goto err; + } + if (!CBB_add_u8(&cbb, hex_digits[v & 0xf])) + goto err; + started = 1; + } + } + if (!CBB_add_u8(&cbb, '\0')) + goto err; + if (!CBB_finish(&cbb, &s, &s_len)) + goto err; + + /* The length of a C string does not include the terminating NUL. */ + CBS_init(&cbs, s, s_len); + if (!CBS_get_last_u8(&cbs, &nul)) + goto err; + + *out = (char *)CBS_data(&cbs); + *out_len = CBS_len(&cbs); + s = NULL; + s_len = 0; + + ret = 1; + + err: + CBB_cleanup(&cbb); + freezero(s, s_len); + + return ret; +} + +int +bn_bn2hex_nosign(const BIGNUM *bn, char **out, size_t *out_len) +{ + return bn_bn2hex_internal(bn, 0, 0, out, out_len); +} + +int +bn_bn2hex_nibbles(const BIGNUM *bn, char **out, size_t *out_len) +{ + return bn_bn2hex_internal(bn, 1, 1, out, out_len); +} + +char * +BN_bn2hex(const BIGNUM *bn) +{ + char *s; + size_t s_len; + + if (!bn_bn2hex_internal(bn, 1, 0, &s, &s_len)) + return NULL; + + return s; +} +LCRYPTO_ALIAS(BN_bn2hex); + +static int +bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs) +{ + CBS cbs_digits; + BIGNUM *bn = NULL; + int b, i, neg, num; + size_t digits = 0; + BN_ULONG w; + uint8_t v; + + /* Handle negative sign. */ + if (!CBS_peek_u8(cbs, &v)) + goto err; + if ((neg = (v == '-'))) { + if (!CBS_skip(cbs, 1)) + goto err; + } + + /* Scan to find last hexadecimal digit. */ + CBS_dup(cbs, &cbs_digits); + while (CBS_len(&cbs_digits) > 0) { + if (!CBS_get_u8(&cbs_digits, &v)) + goto err; + if (!isxdigit(v)) + break; + digits++; + } + if (digits > INT_MAX / 4) + goto err; + + num = digits + neg; + + if (bnp == NULL) + return num; + + if ((bn = *bnp) == NULL) + bn = BN_new(); + if (bn == NULL) + goto err; + if (!bn_expand(bn, digits * 4)) + goto err; + + if (!CBS_get_bytes(cbs, cbs, digits)) + goto err; + + b = BN_BITS2; + i = 0; + w = 0; + + /* Work backwards from least significant digit. */ + while (digits-- > 0) { + if (!CBS_get_last_u8(cbs, &v)) + goto err; + + if (v >= '0' && v <= '9') + v -= '0'; + else if (v >= 'a' && v <= 'f') + v -= 'a' - 10; + else if (v >= 'A' && v <= 'F') + v -= 'A' - 10; + else + goto err; + + w |= (BN_ULONG)v << (BN_BITS2 - b); + b -= 4; + + if (b == 0 || digits == 0) { + b = BN_BITS2; + bn->d[i++] = w; + w = 0; + } + } + + bn->top = i; + bn_correct_top(bn); + + BN_set_negative(bn, neg); + + *bnp = bn; + + return num; + + err: + if (bnp != NULL && *bnp == NULL) + BN_free(bn); + + return 0; +} + +int +BN_hex2bn(BIGNUM **bnp, const char *s) +{ + size_t s_len; + CBS cbs; + + if (bnp != NULL && *bnp != NULL) + BN_zero(*bnp); + + if (s == NULL) + return 0; + if ((s_len = strlen(s)) == 0) + return 0; + + CBS_init(&cbs, s, s_len); + + return bn_hex2bn_cbs(bnp, &cbs); +} +LCRYPTO_ALIAS(BN_hex2bn); + +int +BN_bn2mpi(const BIGNUM *a, unsigned char *d) +{ + int bits; + int num = 0; + int ext = 0; + long l; + + bits = BN_num_bits(a); + num = (bits + 7) / 8; + if (bits > 0) { + ext = ((bits & 0x07) == 0); + } + if (d == NULL) + return (num + 4 + ext); + + l = num + ext; + d[0] = (unsigned char)(l >> 24) & 0xff; + d[1] = (unsigned char)(l >> 16) & 0xff; + d[2] = (unsigned char)(l >> 8) & 0xff; + d[3] = (unsigned char)(l) & 0xff; + if (ext) + d[4] = 0; + num = BN_bn2bin(a, &(d[4 + ext])); + if (a->neg) + d[4] |= 0x80; + return (num + 4 + ext); +} +LCRYPTO_ALIAS(BN_bn2mpi); + +BIGNUM * +BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) +{ + BIGNUM *a = ain; + long len; + int neg = 0; + + if (n < 4) { + BNerror(BN_R_INVALID_LENGTH); + return (NULL); + } + len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | + (int)d[3]; + if ((len + 4) != n) { + BNerror(BN_R_ENCODING_ERROR); + return (NULL); + } + + if (a == NULL) + a = BN_new(); + if (a == NULL) + return (NULL); + + if (len == 0) { + a->neg = 0; + a->top = 0; + return (a); + } + d += 4; + if ((*d) & 0x80) + neg = 1; + if (BN_bin2bn(d, (int)len, a) == NULL) { + if (ain == NULL) + BN_free(a); + return (NULL); + } + BN_set_negative(a, neg); + if (neg) { + BN_clear_bit(a, BN_num_bits(a) - 1); + } + return (a); +} +LCRYPTO_ALIAS(BN_mpi2bn); diff --git a/Libraries/libressl/crypto/bn/bn_ctx.c b/Libraries/libressl/crypto/bn/bn_ctx.c new file mode 100644 index 000000000..129b9c978 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_ctx.c @@ -0,0 +1,161 @@ +/* $OpenBSD: bn_ctx.c,v 1.22 2023/07/08 12:21:58 beck Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "bn_local.h" + +#define BN_CTX_INITIAL_LEN 8 + +struct bignum_ctx { + BIGNUM **bignums; + uint8_t *groups; + uint8_t group; + size_t index; + size_t len; + + int error; +}; + +static int +bn_ctx_grow(BN_CTX *bctx) +{ + BIGNUM **bignums = NULL; + uint8_t *groups = NULL; + size_t len; + + if ((len = bctx->len) == 0) { + len = BN_CTX_INITIAL_LEN; + } else { + if (SIZE_MAX - len < len) + return 0; + len *= 2; + } + + if ((bignums = recallocarray(bctx->bignums, bctx->len, len, + sizeof(bctx->bignums[0]))) == NULL) + return 0; + bctx->bignums = bignums; + + if ((groups = reallocarray(bctx->groups, len, + sizeof(bctx->groups[0]))) == NULL) + return 0; + bctx->groups = groups; + + bctx->len = len; + + return 1; +} + +BN_CTX * +BN_CTX_new(void) +{ + return calloc(1, sizeof(struct bignum_ctx)); +} +LCRYPTO_ALIAS(BN_CTX_new); + +void +BN_CTX_free(BN_CTX *bctx) +{ + size_t i; + + if (bctx == NULL) + return; + + for (i = 0; i < bctx->len; i++) { + BN_free(bctx->bignums[i]); + bctx->bignums[i] = NULL; + } + + free(bctx->bignums); + free(bctx->groups); + + freezero(bctx, sizeof(*bctx)); +} +LCRYPTO_ALIAS(BN_CTX_free); + +void +BN_CTX_start(BN_CTX *bctx) +{ + bctx->group++; + + if (bctx->group == 0) { + BNerror(BN_R_TOO_MANY_TEMPORARY_VARIABLES); + bctx->error = 1; + return; + } +} +LCRYPTO_ALIAS(BN_CTX_start); + +BIGNUM * +BN_CTX_get(BN_CTX *bctx) +{ + BIGNUM *bn = NULL; + + if (bctx->error) + return NULL; + + if (bctx->group == 0) { + BNerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + bctx->error = 1; + return NULL; + } + + if (bctx->index == bctx->len) { + if (!bn_ctx_grow(bctx)) { + BNerror(BN_R_TOO_MANY_TEMPORARY_VARIABLES); + bctx->error = 1; + return NULL; + } + } + + if ((bn = bctx->bignums[bctx->index]) == NULL) { + if ((bn = BN_new()) == NULL) { + BNerror(BN_R_TOO_MANY_TEMPORARY_VARIABLES); + bctx->error = 1; + return NULL; + } + bctx->bignums[bctx->index] = bn; + } + bctx->groups[bctx->index] = bctx->group; + bctx->index++; + + BN_zero(bn); + + return bn; +} +LCRYPTO_ALIAS(BN_CTX_get); + +void +BN_CTX_end(BN_CTX *bctx) +{ + if (bctx == NULL || bctx->error || bctx->group == 0) + return; + + while (bctx->index > 0 && bctx->groups[bctx->index - 1] == bctx->group) { + BN_zero(bctx->bignums[bctx->index - 1]); + bctx->groups[bctx->index - 1] = 0; + bctx->index--; + } + + bctx->group--; +} +LCRYPTO_ALIAS(BN_CTX_end); diff --git a/Libraries/libressl/crypto/bn/bn_div.c b/Libraries/libressl/crypto/bn/bn_div.c new file mode 100644 index 000000000..3225fa442 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_div.c @@ -0,0 +1,457 @@ +/* $OpenBSD: bn_div.c,v 1.40 2023/03/27 10:21:23 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include + +#include "bn_arch.h" +#include "bn_local.h" +#include "bn_internal.h" + +BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0); + +#ifndef HAVE_BN_DIV_WORDS +#if defined(BN_LLONG) && defined(BN_DIV2W) + +BN_ULONG +bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + return ((BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2)|l)/(BN_ULLONG)d)); +} + +#else + +/* Divide h,l by d and return the result. */ +/* I need to test this some more :-( */ +BN_ULONG +bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + BN_ULONG dh, dl, q,ret = 0, th, tl, t; + int i, count = 2; + + if (d == 0) + return (BN_MASK2); + + i = BN_num_bits_word(d); + assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); + + i = BN_BITS2 - i; + if (h >= d) + h -= d; + + if (i) { + d <<= i; + h = (h << i) | (l >> (BN_BITS2 - i)); + l <<= i; + } + dh = (d & BN_MASK2h) >> BN_BITS4; + dl = (d & BN_MASK2l); + for (;;) { + if ((h >> BN_BITS4) == dh) + q = BN_MASK2l; + else + q = h / dh; + + th = q * dh; + tl = dl * q; + for (;;) { + t = h - th; + if ((t & BN_MASK2h) || + ((tl) <= ( + (t << BN_BITS4) | + ((l & BN_MASK2h) >> BN_BITS4)))) + break; + q--; + th -= dh; + tl -= dl; + } + t = (tl >> BN_BITS4); + tl = (tl << BN_BITS4) & BN_MASK2h; + th += t; + + if (l < tl) + th++; + l -= tl; + if (h < th) { + h += d; + q--; + } + h -= th; + + if (--count == 0) + break; + + ret = q << BN_BITS4; + h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2; + l = (l & BN_MASK2l) << BN_BITS4; + } + ret |= q; + return (ret); +} +#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */ +#endif + +/* + * Divide a double word (h:l) by d, returning the quotient q and the remainder + * r, such that q * d + r is equal to the numerator. + */ +#ifndef HAVE_BN_DIV_REM_WORDS +#ifndef HAVE_BN_DIV_REM_WORDS_INLINE +static inline void +bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q, + BN_ULONG *out_r) +{ + BN_ULONG q, r; + + q = bn_div_words(h, l, d); + r = (l - q * d) & BN_MASK2; + + *out_q = q; + *out_r = r; +} +#endif + +void +bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q, + BN_ULONG *out_r) +{ + bn_div_rem_words_inline(h, l, d, out_q, out_r); +} +#endif + +#ifndef HAVE_BN_DIV_3_WORDS + +/* + * Interface is somewhat quirky, |m| is pointer to most significant limb, + * and less significant limb is referred at |m[-1]|. This means that caller + * is responsible for ensuring that |m[-1]| is valid. Second condition that + * has to be met is that |d0|'s most significant bit has to be set. Or in + * other words divisor has to be "bit-aligned to the left." The subroutine + * considers four limbs, two of which are "overlapping," hence the name... + */ +BN_ULONG +bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0) +{ + BN_ULONG n0, n1, q, t2h, t2l; + BN_ULONG rem = 0; + + n0 = m[0]; + n1 = m[-1]; + + if (n0 == d0) + return BN_MASK2; + + /* n0 < d0 */ + bn_div_rem_words(n0, n1, d0, &q, &rem); + + bn_mulw(d1, q, &t2h, &t2l); + + for (;;) { + if (t2h < rem || (t2h == rem && t2l <= m[-2])) + break; + q--; + rem += d0; + if (rem < d0) + break; /* don't let rem overflow */ + if (t2l < d1) + t2h--; + t2l -= d1; + } + + return q; +} +#endif /* !HAVE_BN_DIV_3_WORDS */ + +/* + * BN_div_internal computes quotient := numerator / divisor, rounding towards + * zero and setting remainder such that quotient * divisor + remainder equals + * the numerator. Thus: + * + * quotient->neg == numerator->neg ^ divisor->neg (unless result is zero) + * remainder->neg == numerator->neg (unless the remainder is zero) + * + * If either the quotient or remainder is NULL, the respective value is not + * returned. + */ +static int +BN_div_internal(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx, int ct) +{ + int norm_shift, i, loop, r_neg; + BIGNUM *tmp, wnum, *snum, *sdiv, *res; + BN_ULONG *resp, *wnump; + BN_ULONG d0, d1; + int num_n, div_n; + int no_branch = 0; + int ret = 0; + + BN_CTX_start(ctx); + + /* Invalid zero-padding would have particularly bad consequences. */ + if (numerator->top > 0 && numerator->d[numerator->top - 1] == 0) { + BNerror(BN_R_NOT_INITIALIZED); + goto err; + } + + if (ct) + no_branch = 1; + + if (BN_is_zero(divisor)) { + BNerror(BN_R_DIV_BY_ZERO); + goto err; + } + + if (!no_branch) { + if (BN_ucmp(numerator, divisor) < 0) { + if (remainder != NULL) { + if (!bn_copy(remainder, numerator)) + goto err; + } + if (quotient != NULL) + BN_zero(quotient); + + goto done; + } + } + + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + if ((snum = BN_CTX_get(ctx)) == NULL) + goto err; + if ((sdiv = BN_CTX_get(ctx)) == NULL) + goto err; + if ((res = quotient) == NULL) { + if ((res = BN_CTX_get(ctx)) == NULL) + goto err; + } + + /* First we normalise the numbers. */ + norm_shift = BN_BITS2 - BN_num_bits(divisor) % BN_BITS2; + if (!BN_lshift(sdiv, divisor, norm_shift)) + goto err; + sdiv->neg = 0; + norm_shift += BN_BITS2; + if (!BN_lshift(snum, numerator, norm_shift)) + goto err; + snum->neg = 0; + + if (no_branch) { + /* + * Since we don't know whether snum is larger than sdiv, we pad + * snum with enough zeroes without changing its value. + */ + if (snum->top <= sdiv->top + 1) { + if (!bn_wexpand(snum, sdiv->top + 2)) + goto err; + for (i = snum->top; i < sdiv->top + 2; i++) + snum->d[i] = 0; + snum->top = sdiv->top + 2; + } else { + if (!bn_wexpand(snum, snum->top + 1)) + goto err; + snum->d[snum->top] = 0; + snum->top++; + } + } + + div_n = sdiv->top; + num_n = snum->top; + loop = num_n - div_n; + + /* + * Setup a 'window' into snum - this is the part that corresponds to the + * current 'area' being divided. + */ + wnum.neg = 0; + wnum.d = &(snum->d[loop]); + wnum.top = div_n; + /* only needed when BN_ucmp messes up the values between top and max */ + wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */ + wnum.flags = snum->flags | BN_FLG_STATIC_DATA; + + /* Get the top 2 words of sdiv */ + /* div_n=sdiv->top; */ + d0 = sdiv->d[div_n - 1]; + d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2]; + + /* pointer to the 'top' of snum */ + wnump = &(snum->d[num_n - 1]); + + /* Setup to 'res' */ + if (!bn_wexpand(res, (loop + 1))) + goto err; + res->top = loop - no_branch; + r_neg = numerator->neg ^ divisor->neg; + resp = &(res->d[loop - 1]); + + /* space for temp */ + if (!bn_wexpand(tmp, (div_n + 1))) + goto err; + + if (!no_branch) { + if (BN_ucmp(&wnum, sdiv) >= 0) { + bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n); + *resp = 1; + } else + res->top--; + } + + /* + * If res->top == 0 then clear the neg value otherwise decrease the resp + * pointer. + */ + if (res->top == 0) + res->neg = 0; + else + resp--; + + for (i = 0; i < loop - 1; i++, wnump--, resp--) { + BN_ULONG q, l0; + + /* + * The first part of the loop uses the top two words of snum and + * sdiv to calculate a BN_ULONG q such that: + * + * | wnum - sdiv * q | < sdiv + */ + q = bn_div_3_words(wnump, d1, d0); + l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q); + tmp->d[div_n] = l0; + wnum.d--; + + /* + * Ignore top values of the bignums just sub the two BN_ULONG + * arrays with bn_sub_words. + */ + if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) { + /* + * Note: As we have considered only the leading two + * BN_ULONGs in the calculation of q, sdiv * q might be + * greater than wnum (but then (q-1) * sdiv is less or + * equal than wnum). + */ + q--; + if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) { + /* + * We can't have an overflow here (assuming + * that q != 0, but if q == 0 then tmp is + * zero anyway). + */ + (*wnump)++; + } + } + /* store part of the result */ + *resp = q; + } + + bn_correct_top(snum); + + if (remainder != NULL) { + /* + * Keep a copy of the neg flag in numerator because if + * remainder == numerator, BN_rshift() will overwrite it. + */ + int neg = numerator->neg; + + BN_rshift(remainder, snum, norm_shift); + BN_set_negative(remainder, neg); + } + + if (no_branch) + bn_correct_top(res); + + BN_set_negative(res, r_neg); + + done: + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +BN_div(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx) +{ + int ct; + + ct = BN_get_flags(numerator, BN_FLG_CONSTTIME) != 0 || + BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0; + + return BN_div_internal(quotient, remainder, numerator, divisor, ctx, ct); +} + +int +BN_div_nonct(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx) +{ + return BN_div_internal(quotient, remainder, numerator, divisor, ctx, 0); +} + +int +BN_div_ct(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx) +{ + return BN_div_internal(quotient, remainder, numerator, divisor, ctx, 1); +} diff --git a/Libraries/libressl/crypto/bn/bn_err.c b/Libraries/libressl/crypto/bn/bn_err.c new file mode 100644 index 000000000..6fd6030a0 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_err.c @@ -0,0 +1,108 @@ +/* $OpenBSD: bn_err.c,v 1.17 2023/07/08 12:21:58 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason) + +static ERR_STRING_DATA BN_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA BN_str_reasons[]= { + {ERR_REASON(BN_R_ARG2_LT_ARG3) , "arg2 lt arg3"}, + {ERR_REASON(BN_R_BAD_RECIPROCAL) , "bad reciprocal"}, + {ERR_REASON(BN_R_BIGNUM_TOO_LONG) , "bignum too long"}, + {ERR_REASON(BN_R_BITS_TOO_SMALL) , "bits too small"}, + {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"}, + {ERR_REASON(BN_R_DIV_BY_ZERO) , "div by zero"}, + {ERR_REASON(BN_R_ENCODING_ERROR) , "encoding error"}, + {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), "expand on static bignum data"}, + {ERR_REASON(BN_R_INPUT_NOT_REDUCED) , "input not reduced"}, + {ERR_REASON(BN_R_INVALID_ARGUMENT) , "invalid argument"}, + {ERR_REASON(BN_R_INVALID_LENGTH) , "invalid length"}, + {ERR_REASON(BN_R_INVALID_RANGE) , "invalid range"}, + {ERR_REASON(BN_R_NOT_A_SQUARE) , "not a square"}, + {ERR_REASON(BN_R_NOT_INITIALIZED) , "not initialized"}, + {ERR_REASON(BN_R_NO_INVERSE) , "no inverse"}, + {ERR_REASON(BN_R_NO_SOLUTION) , "no solution"}, + {ERR_REASON(BN_R_P_IS_NOT_PRIME) , "p is not prime"}, + {ERR_REASON(BN_R_TOO_MANY_ITERATIONS) , "too many iterations"}, + {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES), "too many temporary variables"}, + {0, NULL} +}; + +#endif + +void +ERR_load_BN_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(BN_str_functs[0].error) == NULL) { + ERR_load_strings(0, BN_str_functs); + ERR_load_strings(0, BN_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_BN_strings); diff --git a/Libraries/libressl/crypto/bn/bn_exp.c b/Libraries/libressl/crypto/bn/bn_exp.c new file mode 100644 index 000000000..a50fa5953 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_exp.c @@ -0,0 +1,1338 @@ +/* $OpenBSD: bn_exp.c,v 1.47 2023/07/08 12:21:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include "bn_local.h" +#include "constant_time.h" + +/* maximum precomputation table size for *variable* sliding windows */ +#define TABLE_SIZE 32 + +/* Calculates r = a^p by successive squaring of a. Not constant time. */ +int +BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *rr, *v; + int i; + int ret = 0; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + BNerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + BN_CTX_start(ctx); + + if ((v = BN_CTX_get(ctx)) == NULL) + goto err; + + rr = r; + if (r == a || r == p) + rr = BN_CTX_get(ctx); + if (rr == NULL) + goto err; + + if (!BN_one(rr)) + goto err; + if (BN_is_odd(p)) { + if (!bn_copy(rr, a)) + goto err; + } + + if (!bn_copy(v, a)) + goto err; + + for (i = 1; i < BN_num_bits(p); i++) { + if (!BN_sqr(v, v, ctx)) + goto err; + if (!BN_is_bit_set(p, i)) + continue; + if (!BN_mul(rr, rr, v, ctx)) + goto err; + } + + if (!bn_copy(r, rr)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_exp); + +/* The old fallback, simple version :-) */ +int +BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *d; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(r); + } else + ret = BN_one(r); + return ret; + } + + BN_CTX_start(ctx); + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((val[0] = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_nnmod(val[0],a,m,ctx)) + goto err; /* 1 */ + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul(d, val[0], val[0], m, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul(val[i], val[i - 1], d,m, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_one(r)) + goto err; + + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) + if (!BN_mod_mul(r, r, r, m, ctx)) + goto err; + if (wstart == 0) + break; + wstart--; + continue; + } + /* We now have wstart on a 'set' bit, we now need to work out + * how bit a window to do. To do this we need to scan + * forward until the last set bit before the end of the + * window */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul(r, r, r, m, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return (ret); +} +LCRYPTO_ALIAS(BN_mod_exp_simple); + +/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout + * so that accessing any of these table values shows the same access pattern as far + * as cache lines are concerned. The following functions are used to transfer a BIGNUM + * from/to that table. */ + +static int +MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, + int idx, int window) +{ + int i, j; + int width = 1 << window; + BN_ULONG *table = (BN_ULONG *)buf; + + if (top > b->top) + top = b->top; /* this works because 'buf' is explicitly zeroed */ + + for (i = 0, j = idx; i < top; i++, j += width) { + table[j] = b->d[i]; + } + + return 1; +} + +static int +MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, + int window) +{ + int i, j; + int width = 1 << window; + volatile BN_ULONG *table = (volatile BN_ULONG *)buf; + + if (!bn_wexpand(b, top)) + return 0; + + if (window <= 3) { + for (i = 0; i < top; i++, table += width) { + BN_ULONG acc = 0; + + for (j = 0; j < width; j++) { + acc |= table[j] & + ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); + } + + b->d[i] = acc; + } + } else { + int xstride = 1 << (window - 2); + BN_ULONG y0, y1, y2, y3; + + i = idx >> (window - 2); /* equivalent of idx / xstride */ + idx &= xstride - 1; /* equivalent of idx % xstride */ + + y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1); + y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1); + y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1); + y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1); + + for (i = 0; i < top; i++, table += width) { + BN_ULONG acc = 0; + + for (j = 0; j < xstride; j++) { + acc |= ( (table[j + 0 * xstride] & y0) | + (table[j + 1 * xstride] & y1) | + (table[j + 2 * xstride] & y2) | + (table[j + 3 * xstride] & y3) ) + & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); + } + + b->d[i] = acc; + } + } + b->top = top; + bn_correct_top(b); + return 1; +} + +/* Given a pointer value, compute the next address that is a cache line multiple. */ +#define MOD_EXP_CTIME_ALIGN(x_) \ + ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) + +/* This variant of BN_mod_exp_mont() uses fixed windows and the special + * precomputation memory layout to limit data-dependency to a minimum + * to protect secret exponents (cf. the hyper-threading timing attacks + * pointed out by Colin Percival, + * http://www.daemonology.net/hyperthreading-considered-harmful/) + */ +int +BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + int i, bits, ret = 0, window, wvalue; + int top; + BN_MONT_CTX *mont = NULL; + int numPowers; + unsigned char *powerbufFree = NULL; + int powerbufLen = 0; + unsigned char *powerbuf = NULL; + BIGNUM tmp, am; + + + if (!BN_is_odd(m)) { + BNerror(BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + + top = m->top; + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(rr); + } else + ret = BN_one(rr); + return ret; + } + + BN_CTX_start(ctx); + + /* + * Allocate a Montgomery context if it was not supplied by the caller. + * If this is not done, things will break in the montgomery part. + */ + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + /* Get the window size to use with size of p. */ + window = BN_window_bits_for_ctime_exponent_size(bits); +#if defined(OPENSSL_BN_ASM_MONT5) + if (window == 6 && bits <= 1024) + window = 5; /* ~5% improvement of 2048-bit RSA sign */ +#endif + + /* Allocate a buffer large enough to hold all of the pre-computed + * powers of am, am itself and tmp. + */ + numPowers = 1 << window; + powerbufLen = sizeof(m->d[0]) * (top * numPowers + + ((2*top) > numPowers ? (2*top) : numPowers)); + if ((powerbufFree = calloc(powerbufLen + + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH, 1)) == NULL) + goto err; + powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); + + /* lay down tmp and am right after powers table */ + tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers); + am.d = tmp.d + top; + tmp.top = am.top = 0; + tmp.dmax = am.dmax = top; + tmp.neg = am.neg = 0; + tmp.flags = am.flags = BN_FLG_STATIC_DATA; + + /* prepare a^0 in Montgomery domain */ +#if 1 + if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) + goto err; +#else + tmp.d[0] = (0 - m - >d[0]) & BN_MASK2; /* 2^(top*BN_BITS2) - m */ + for (i = 1; i < top; i++) + tmp.d[i] = (~m->d[i]) & BN_MASK2; + tmp.top = top; +#endif + + /* prepare a^1 in Montgomery domain */ + if (!BN_nnmod(&am, a, m, ctx)) + goto err; + if (!BN_to_montgomery(&am, &am, mont, ctx)) + goto err; + +#if defined(OPENSSL_BN_ASM_MONT5) + /* This optimization uses ideas from http://eprint.iacr.org/2011/239, + * specifically optimization of cache-timing attack countermeasures + * and pre-computation optimization. */ + + /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as + * 512-bit RSA is hardly relevant, we omit it to spare size... */ + if (window == 5 && top > 1) { + void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, + const void *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + void bn_scatter5(const BN_ULONG *inp, size_t num, + void *table, size_t power); + void bn_gather5(BN_ULONG *out, size_t num, + void *table, size_t power); + + BN_ULONG *np = mont->N.d, *n0 = mont->n0; + + /* BN_to_montgomery can contaminate words above .top + * [in BN_DEBUG[_DEBUG] build]... */ + for (i = am.top; i < top; i++) + am.d[i] = 0; + for (i = tmp.top; i < top; i++) + tmp.d[i] = 0; + + bn_scatter5(tmp.d, top, powerbuf, 0); + bn_scatter5(am.d, am.top, powerbuf, 1); + bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2); + +#if 0 + for (i = 3; i < 32; i++) { + /* Calculate a^i = a^(i-1) * a */ + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, + n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } +#else + /* same as above, but uses squaring for 1/2 of operations */ + for (i = 4; i < 32; i*=2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, i); + } + for (i = 3; i < 8; i += 2) { + int j; + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, + n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + for (j = 2 * i; j < 32; j *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, j); + } + } + for (; i < 16; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, + n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2*i); + } + for (; i < 32; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, + n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } +#endif + bits--; + for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + bn_gather5(tmp.d, top, powerbuf, wvalue); + + /* Scan the exponent one window at a time starting from the most + * significant bits. + */ + while (bits >= 0) { + for (wvalue = 0, i = 0; i < 5; i++, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + + tmp.top = top; + bn_correct_top(&tmp); + } else +#endif + { + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, + window)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, + window)) + goto err; + + /* If the window size is greater than 1, then calculate + * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) + * (even powers could instead be computed as (a^(i/2))^2 + * to use the slight performance advantage of sqr over mul). + */ + if (window > 1) { + if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, + 2, window)) + goto err; + for (i = 3; i < numPowers; i++) { + /* Calculate a^i = a^(i-1) * a */ + if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, + mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, + powerbuf, i, window)) + goto err; + } + } + + bits--; + for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, + wvalue, window)) + goto err; + + /* Scan the exponent one window at a time starting from the most + * significant bits. + */ + while (bits >= 0) { + wvalue = 0; /* The 'value' of the window */ + + /* Scan the window, squaring the result as we go */ + for (i = 0; i < window; i++, bits--) { + if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, + mont, ctx)) + goto err; + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + + /* Fetch the appropriate pre-computed value from the pre-buf */ + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, + wvalue, window)) + goto err; + + /* Multiply the result into the intermediate result */ + if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) + goto err; + } + } + + /* Convert the final result from montgomery to standard format */ + if (!BN_from_montgomery(rr, &tmp, mont, ctx)) + goto err; + ret = 1; + +err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + freezero(powerbufFree, powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); + BN_CTX_end(ctx); + return (ret); +} +LCRYPTO_ALIAS(BN_mod_exp_mont_consttime); + +static int +BN_mod_exp_mont_internal(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont, int ct) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *d, *r; + const BIGNUM *aa; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + BN_MONT_CTX *mont = NULL; + + if (ct) { + return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); + } + + + if (!BN_is_odd(m)) { + BNerror(BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(rr); + } else + ret = BN_one(rr); + return ret; + } + + BN_CTX_start(ctx); + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r = BN_CTX_get(ctx)) == NULL) + goto err; + if ((val[0] = BN_CTX_get(ctx)) == NULL) + goto err; + + /* If this is not done, things will break in the montgomery + * part */ + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + if (!BN_nnmod(val[0], a,m, ctx)) + goto err; + aa = val[0]; + if (BN_is_zero(aa)) { + BN_zero(rr); + ret = 1; + goto err; + } + if (!BN_to_montgomery(val[0], aa, mont, ctx)) + goto err; /* 1 */ + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val[i], val[i - 1], + d, mont, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) + goto err; + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + if (wstart == 0) + break; + wstart--; + continue; + } + /* We now have wstart on a 'set' bit, we now need to work out + * how bit a window to do. To do this we need to scan + * forward until the last set bit before the end of the + * window */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + if (!BN_from_montgomery(rr, r,mont, ctx)) + goto err; + ret = 1; + +err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + return (ret); +} + +int +BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + return BN_mod_exp_mont_internal(rr, a, p, m, ctx, in_mont, + (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)); +} + +int +BN_mod_exp_mont_ct(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + return BN_mod_exp_mont_internal(rr, a, p, m, ctx, in_mont, 1); +} + +int +BN_mod_exp_mont_nonct(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + return BN_mod_exp_mont_internal(rr, a, p, m, ctx, in_mont, 0); +} + +int +BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BN_MONT_CTX *mont = NULL; + int b, bits, ret = 0; + int r_is_one; + BN_ULONG w, next_w; + BIGNUM *d, *r, *t; + BIGNUM *swap_tmp; + +#define BN_MOD_MUL_WORD(r, w, m) \ + (BN_mul_word(r, (w)) && \ + (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ + (BN_mod_ct(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1)))) + /* BN_MOD_MUL_WORD is only used with 'w' large, + * so the BN_ucmp test is probably more overhead + * than always using BN_mod (which uses bn_copy if + * a similar test returns true). */ + /* We can use BN_mod and do not need BN_nnmod because our + * accumulator is never negative (the result of BN_mod does + * not depend on the sign of the modulus). + */ +#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ + (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + + if (!BN_is_odd(m)) { + BNerror(BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + if (m->top == 1) + a %= m->d[0]; /* make sure that 'a' is reduced */ + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(rr); + } else + ret = BN_one(rr); + return ret; + } + if (a == 0) { + BN_zero(rr); + ret = 1; + return ret; + } + + BN_CTX_start(ctx); + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r = BN_CTX_get(ctx)) == NULL) + goto err; + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + r_is_one = 1; /* except for Montgomery factor */ + + /* bits-1 >= 0 */ + + /* The result is accumulated in the product r*w. */ + w = a; /* bit 'bits-1' of 'p' is always set */ + for (b = bits - 2; b >= 0; b--) { + /* First, square r*w. */ + next_w = w * w; + if ((next_w / w) != w) /* overflow */ + { + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + next_w = 1; + } + w = next_w; + if (!r_is_one) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + /* Second, multiply r*w by 'a' if exponent bit is set. */ + if (BN_is_bit_set(p, b)) { + next_w = w * a; + if ((next_w / a) != w) /* overflow */ + { + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + next_w = a; + } + w = next_w; + } + } + + /* Finally, set r:=r*w. */ + if (w != 1) { + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + } + + if (r_is_one) /* can happen only if a == 1*/ + { + if (!BN_one(rr)) + goto err; + } else { + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + } + ret = 1; + +err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + return (ret); +} +LCRYPTO_ALIAS(BN_mod_exp_mont_word); + +int +BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *aa; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + BN_RECP_CTX recp; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(r); + } else + ret = BN_one(r); + return ret; + } + + BN_RECP_CTX_init(&recp); + + BN_CTX_start(ctx); + if ((aa = BN_CTX_get(ctx)) == NULL) + goto err; + if ((val[0] = BN_CTX_get(ctx)) == NULL) + goto err; + + if (m->neg) { + /* ignore sign of 'm' */ + if (!bn_copy(aa, m)) + goto err; + aa->neg = 0; + if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) + goto err; + } else { + if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) + goto err; + } + + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; /* 1 */ + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_reciprocal(val[i], val[i - 1], + aa, &recp, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_one(r)) + goto err; + + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) + if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx)) + goto err; + if (wstart == 0) + break; + wstart--; + continue; + } + /* We now have wstart on a 'set' bit, we now need to work out + * how bit a window to do. To do this we need to scan + * forward until the last set bit before the end of the + * window */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_reciprocal(r, r,val[wvalue >> 1], &recp, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + ret = 1; + +err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(&recp); + return (ret); +} + +static int +BN_mod_exp_internal(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, int ct) +{ + int ret; + + + /* For even modulus m = 2^k*m_odd, it might make sense to compute + * a^p mod m_odd and a^p mod 2^k separately (with Montgomery + * exponentiation for the odd part), using appropriate exponent + * reductions, and combine the results using the CRT. + * + * For now, we use Montgomery only if the modulus is odd; otherwise, + * exponentiation using the reciprocal-based quick remaindering + * algorithm is used. + * + * (Timing obtained with expspeed.c [computations a^p mod m + * where a, p, m are of the same length: 256, 512, 1024, 2048, + * 4096, 8192 bits], compared to the running time of the + * standard algorithm: + * + * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration] + * 55 .. 77 % [UltraSparc processor, but + * debug-solaris-sparcv8-gcc conf.] + * + * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration] + * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc] + * + * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont + * at 2048 and more bits, but at 512 and 1024 bits, it was + * slower even than the standard algorithm! + * + * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations] + * should be obtained when the new Montgomery reduction code + * has been integrated into OpenSSL.) + */ + + if (BN_is_odd(m)) { + if (a->top == 1 && !a->neg && !ct) { + BN_ULONG A = a->d[0]; + ret = BN_mod_exp_mont_word(r, A,p, m,ctx, NULL); + } else + ret = BN_mod_exp_mont_ct(r, a,p, m,ctx, NULL); + } else { + ret = BN_mod_exp_recp(r, a,p, m, ctx); + } + + return (ret); +} + +int +BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + return BN_mod_exp_internal(r, a, p, m, ctx, + (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)); +} + +int +BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + return BN_mod_exp_internal(r, a, p, m, ctx, 1); +} + +int +BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + return BN_mod_exp_internal(r, a, p, m, ctx, 0); +} + +int +BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) +{ + int i, j, bits, b, bits1, bits2, ret = 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2; + int r_is_one = 1; + BIGNUM *d, *r; + const BIGNUM *a_mod_m; + /* Tables of variables obtained from 'ctx' */ + BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE]; + BN_MONT_CTX *mont = NULL; + + + if (!BN_is_odd(m)) { + BNerror(BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + bits1 = BN_num_bits(p1); + bits2 = BN_num_bits(p2); + if ((bits1 == 0) && (bits2 == 0)) { + ret = BN_one(rr); + return ret; + } + + bits = (bits1 > bits2) ? bits1 : bits2; + + BN_CTX_start(ctx); + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r = BN_CTX_get(ctx)) == NULL) + goto err; + if ((val1[0] = BN_CTX_get(ctx)) == NULL) + goto err; + if ((val2[0] = BN_CTX_get(ctx)) == NULL) + goto err; + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + window1 = BN_window_bits_for_exponent_size(bits1); + window2 = BN_window_bits_for_exponent_size(bits2); + + /* + * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1) + */ + if (!BN_nnmod(val1[0], a1, m, ctx)) + goto err; + a_mod_m = val1[0]; + if (BN_is_zero(a_mod_m)) { + BN_zero(rr); + ret = 1; + goto err; + } + + if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx)) + goto err; + if (window1 > 1) { + if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx)) + goto err; + + j = 1 << (window1 - 1); + for (i = 1; i < j; i++) { + if (((val1[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val1[i], val1[i - 1], + d, mont, ctx)) + goto err; + } + } + + + /* + * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1) + */ + if (!BN_nnmod(val2[0], a2, m, ctx)) + goto err; + a_mod_m = val2[0]; + if (BN_is_zero(a_mod_m)) { + BN_zero(rr); + ret = 1; + goto err; + } + if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx)) + goto err; + if (window2 > 1) { + if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx)) + goto err; + + j = 1 << (window2 - 1); + for (i = 1; i < j; i++) { + if (((val2[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val2[i], val2[i - 1], + d, mont, ctx)) + goto err; + } + } + + + /* Now compute the power product, using independent windows. */ + r_is_one = 1; + wvalue1 = 0; /* The 'value' of the first window */ + wvalue2 = 0; /* The 'value' of the second window */ + wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the first window */ + wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the second window */ + + if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) + goto err; + for (b = bits - 1; b >= 0; b--) { + if (!r_is_one) { + if (!BN_mod_mul_montgomery(r, r,r, mont, ctx)) + goto err; + } + + if (!wvalue1) + if (BN_is_bit_set(p1, b)) { + /* consider bits b-window1+1 .. b for this window */ + i = b - window1 + 1; + while (!BN_is_bit_set(p1, i)) /* works for i<0 */ + i++; + wpos1 = i; + wvalue1 = 1; + for (i = b - 1; i >= wpos1; i--) { + wvalue1 <<= 1; + if (BN_is_bit_set(p1, i)) + wvalue1++; + } + } + + if (!wvalue2) + if (BN_is_bit_set(p2, b)) { + /* consider bits b-window2+1 .. b for this window */ + i = b - window2 + 1; + while (!BN_is_bit_set(p2, i)) + i++; + wpos2 = i; + wvalue2 = 1; + for (i = b - 1; i >= wpos2; i--) { + wvalue2 <<= 1; + if (BN_is_bit_set(p2, i)) + wvalue2++; + } + } + + if (wvalue1 && b == wpos1) { + /* wvalue1 is odd and < 2^window1 */ + if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], + mont, ctx)) + goto err; + wvalue1 = 0; + r_is_one = 0; + } + + if (wvalue2 && b == wpos2) { + /* wvalue2 is odd and < 2^window2 */ + if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], + mont, ctx)) + goto err; + wvalue2 = 0; + r_is_one = 0; + } + } + if (!BN_from_montgomery(rr, r,mont, ctx)) + goto err; + ret = 1; + +err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + return (ret); +} +LCRYPTO_ALIAS(BN_mod_exp2_mont); diff --git a/Libraries/libressl/crypto/bn/bn_gcd.c b/Libraries/libressl/crypto/bn/bn_gcd.c new file mode 100644 index 000000000..6b3d8a3cb --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_gcd.c @@ -0,0 +1,822 @@ +/* $OpenBSD: bn_gcd.c,v 1.28 2023/06/02 17:15:30 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "bn_local.h" + +static BIGNUM * +euclid(BIGNUM *a, BIGNUM *b) +{ + BIGNUM *t; + int shifts = 0; + + /* Loop invariant: 0 <= b <= a. */ + while (!BN_is_zero(b)) { + if (BN_is_odd(a) && BN_is_odd(b)) { + if (!BN_sub(a, a, b)) + goto err; + if (!BN_rshift1(a, a)) + goto err; + } else if (BN_is_odd(a) && !BN_is_odd(b)) { + if (!BN_rshift1(b, b)) + goto err; + } else if (!BN_is_odd(a) && BN_is_odd(b)) { + if (!BN_rshift1(a, a)) + goto err; + } else { + if (!BN_rshift1(a, a)) + goto err; + if (!BN_rshift1(b, b)) + goto err; + shifts++; + continue; + } + + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } + + if (shifts) { + if (!BN_lshift(a, a, shifts)) + goto err; + } + + return a; + + err: + return NULL; +} + +int +BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) +{ + BIGNUM *a, *b, *t; + int ret = 0; + + BN_CTX_start(ctx); + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!bn_copy(a, in_a)) + goto err; + if (!bn_copy(b, in_b)) + goto err; + a->neg = 0; + b->neg = 0; + + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + t = euclid(a, b); + if (t == NULL) + goto err; + + if (!bn_copy(r, t)) + goto err; + ret = 1; + + err: + BN_CTX_end(ctx); + return (ret); +} + +int +BN_gcd_nonct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) +{ + return BN_gcd(r, in_a, in_b, ctx); +} + +/* + * BN_gcd_no_branch is a special version of BN_mod_inverse_no_branch. + * that returns the GCD. + */ +static BIGNUM * +BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM local_A, local_B; + BIGNUM *pA, *pB; + BIGNUM *ret = NULL; + int sign; + + if (in == NULL) + goto err; + R = in; + + BN_init(&local_A); + BN_init(&local_B); + + BN_CTX_start(ctx); + if ((A = BN_CTX_get(ctx)) == NULL) + goto err; + if ((B = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((D = BN_CTX_get(ctx)) == NULL) + goto err; + if ((M = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Y = BN_CTX_get(ctx)) == NULL) + goto err; + if ((T = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_one(X)) + goto err; + BN_zero(Y); + if (!bn_copy(B, a)) + goto err; + if (!bn_copy(A, n)) + goto err; + A->neg = 0; + + if (B->neg || (BN_ucmp(B, A) >= 0)) { + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pB = &local_B; + /* BN_init() done at the top of the function. */ + BN_with_flags(pB, B, BN_FLG_CONSTTIME); + if (!BN_nnmod(B, pB, A, ctx)) + goto err; + } + sign = -1; + /* From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /* + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pA = &local_A; + /* BN_init() done at the top of the function. */ + BN_with_flags(pA, A, BN_FLG_CONSTTIME); + + /* (D, M) := (A/B, A%B) ... */ + if (!BN_div_ct(D, M, pA, B, ctx)) + goto err; + + /* Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + tmp = A; /* keep the BIGNUM object, the value does not matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /* Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + if (!BN_mul(tmp, D, X, ctx)) + goto err; + if (!BN_add(tmp, tmp, Y)) + goto err; + + M = Y; /* keep the BIGNUM object, the value does not matter */ + Y = X; + X = tmp; + sign = -sign; + } + + /* + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + */ + + if (!bn_copy(R, A)) + goto err; + ret = R; + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + return (ret); +} + +int +BN_gcd_ct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) +{ + if (BN_gcd_no_branch(r, in_a, in_b, ctx) == NULL) + return 0; + return 1; +} + +/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. + * It does not contain branches that may leak sensitive information. + */ +static BIGNUM * +BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM local_A, local_B; + BIGNUM *pA, *pB; + BIGNUM *ret = NULL; + int sign; + + BN_init(&local_A); + BN_init(&local_B); + + BN_CTX_start(ctx); + if ((A = BN_CTX_get(ctx)) == NULL) + goto err; + if ((B = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((D = BN_CTX_get(ctx)) == NULL) + goto err; + if ((M = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Y = BN_CTX_get(ctx)) == NULL) + goto err; + if ((T = BN_CTX_get(ctx)) == NULL) + goto err; + + if (in == NULL) + R = BN_new(); + else + R = in; + if (R == NULL) + goto err; + + if (!BN_one(X)) + goto err; + BN_zero(Y); + if (!bn_copy(B, a)) + goto err; + if (!bn_copy(A, n)) + goto err; + A->neg = 0; + + if (B->neg || (BN_ucmp(B, A) >= 0)) { + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pB = &local_B; + /* BN_init() done at the top of the function. */ + BN_with_flags(pB, B, BN_FLG_CONSTTIME); + if (!BN_nnmod(B, pB, A, ctx)) + goto err; + } + sign = -1; + /* From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /* + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pA = &local_A; + /* BN_init() done at the top of the function. */ + BN_with_flags(pA, A, BN_FLG_CONSTTIME); + + /* (D, M) := (A/B, A%B) ... */ + if (!BN_div_ct(D, M, pA, B, ctx)) + goto err; + + /* Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + tmp = A; /* keep the BIGNUM object, the value does not matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /* Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + if (!BN_mul(tmp, D, X, ctx)) + goto err; + if (!BN_add(tmp, tmp, Y)) + goto err; + + M = Y; /* keep the BIGNUM object, the value does not matter */ + Y = X; + X = tmp; + sign = -sign; + } + + /* + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) + goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (!BN_is_one(A)) { + BNerror(BN_R_NO_INVERSE); + goto err; + } + + if (!BN_nnmod(Y, Y, n, ctx)) + goto err; + if (!bn_copy(R, Y)) + goto err; + + ret = R; + + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + return (ret); +} + +/* solves ax == 1 (mod n) */ +static BIGNUM * +BN_mod_inverse_internal(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, + int ct) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM *ret = NULL; + int sign; + + if (ct) + return BN_mod_inverse_no_branch(in, a, n, ctx); + + BN_CTX_start(ctx); + if ((A = BN_CTX_get(ctx)) == NULL) + goto err; + if ((B = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((D = BN_CTX_get(ctx)) == NULL) + goto err; + if ((M = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Y = BN_CTX_get(ctx)) == NULL) + goto err; + if ((T = BN_CTX_get(ctx)) == NULL) + goto err; + + if (in == NULL) + R = BN_new(); + else + R = in; + if (R == NULL) + goto err; + + if (!BN_one(X)) + goto err; + BN_zero(Y); + if (!bn_copy(B, a)) + goto err; + if (!bn_copy(A, n)) + goto err; + A->neg = 0; + if (B->neg || (BN_ucmp(B, A) >= 0)) { + if (!BN_nnmod(B, B, A, ctx)) + goto err; + } + sign = -1; + /* From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { + /* Binary inversion algorithm; requires odd modulus. + * This is faster than the general algorithm if the modulus + * is sufficiently small (about 400 .. 500 bits on 32-bit + * systems, but much more on 64-bit systems) */ + int shift; + + while (!BN_is_zero(B)) { + /* + * 0 < B < |n|, + * 0 < A <= |n|, + * (1) -sign*X*a == B (mod |n|), + * (2) sign*Y*a == A (mod |n|) + */ + + /* Now divide B by the maximum possible power of two in the integers, + * and divide X by the same value mod |n|. + * When we're done, (1) still holds. */ + shift = 0; + while (!BN_is_bit_set(B, shift)) /* note that 0 < B */ + { + shift++; + + if (BN_is_odd(X)) { + if (!BN_uadd(X, X, n)) + goto err; + } + /* now X is even, so we can easily divide it by two */ + if (!BN_rshift1(X, X)) + goto err; + } + if (shift > 0) { + if (!BN_rshift(B, B, shift)) + goto err; + } + + /* Same for A and Y. Afterwards, (2) still holds. */ + shift = 0; + while (!BN_is_bit_set(A, shift)) /* note that 0 < A */ + { + shift++; + + if (BN_is_odd(Y)) { + if (!BN_uadd(Y, Y, n)) + goto err; + } + /* now Y is even */ + if (!BN_rshift1(Y, Y)) + goto err; + } + if (shift > 0) { + if (!BN_rshift(A, A, shift)) + goto err; + } + + /* We still have (1) and (2). + * Both A and B are odd. + * The following computations ensure that + * + * 0 <= B < |n|, + * 0 < A < |n|, + * (1) -sign*X*a == B (mod |n|), + * (2) sign*Y*a == A (mod |n|), + * + * and that either A or B is even in the next iteration. + */ + if (BN_ucmp(B, A) >= 0) { + /* -sign*(X + Y)*a == B - A (mod |n|) */ + if (!BN_uadd(X, X, Y)) + goto err; + /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that + * actually makes the algorithm slower */ + if (!BN_usub(B, B, A)) + goto err; + } else { + /* sign*(X + Y)*a == A - B (mod |n|) */ + if (!BN_uadd(Y, Y, X)) + goto err; + /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */ + if (!BN_usub(A, A, B)) + goto err; + } + } + } else { + /* general inversion algorithm */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /* + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* (D, M) := (A/B, A%B) ... */ + if (BN_num_bits(A) == BN_num_bits(B)) { + if (!BN_one(D)) + goto err; + if (!BN_sub(M, A, B)) + goto err; + } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { + /* A/B is 1, 2, or 3 */ + if (!BN_lshift1(T, B)) + goto err; + if (BN_ucmp(A, T) < 0) { + /* A < 2*B, so D=1 */ + if (!BN_one(D)) + goto err; + if (!BN_sub(M, A, B)) + goto err; + } else { + /* A >= 2*B, so D=2 or D=3 */ + if (!BN_sub(M, A, T)) + goto err; + if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */ + if (BN_ucmp(A, D) < 0) { + /* A < 3*B, so D=2 */ + if (!BN_set_word(D, 2)) + goto err; + /* M (= A - 2*B) already has the correct value */ + } else { + /* only D=3 remains */ + if (!BN_set_word(D, 3)) + goto err; + /* currently M = A - 2*B, but we need M = A - 3*B */ + if (!BN_sub(M, M, B)) + goto err; + } + } + } else { + if (!BN_div_nonct(D, M, A, B, ctx)) + goto err; + } + + /* Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + tmp = A; /* keep the BIGNUM object, the value does not matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /* Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + /* most of the time D is very small, so we can optimize tmp := D*X+Y */ + if (BN_is_one(D)) { + if (!BN_add(tmp, X, Y)) + goto err; + } else { + if (BN_is_word(D, 2)) { + if (!BN_lshift1(tmp, X)) + goto err; + } else if (BN_is_word(D, 4)) { + if (!BN_lshift(tmp, X, 2)) + goto err; + } else if (D->top == 1) { + if (!bn_copy(tmp, X)) + goto err; + if (!BN_mul_word(tmp, D->d[0])) + goto err; + } else { + if (!BN_mul(tmp, D,X, ctx)) + goto err; + } + if (!BN_add(tmp, tmp, Y)) + goto err; + } + + M = Y; /* keep the BIGNUM object, the value does not matter */ + Y = X; + X = tmp; + sign = -sign; + } + } + + /* + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) + goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (!BN_is_one(A)) { + BNerror(BN_R_NO_INVERSE); + goto err; + } + + if (!BN_nnmod(Y, Y, n, ctx)) + goto err; + if (!bn_copy(R, Y)) + goto err; + + ret = R; + + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + return (ret); +} + +BIGNUM * +BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) +{ + int ct = ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || + (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)); + return BN_mod_inverse_internal(in, a, n, ctx, ct); +} + +BIGNUM * +BN_mod_inverse_nonct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) +{ + return BN_mod_inverse_internal(in, a, n, ctx, 0); +} + +BIGNUM * +BN_mod_inverse_ct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) +{ + return BN_mod_inverse_internal(in, a, n, ctx, 1); +} diff --git a/Libraries/libressl/crypto/bn/bn_internal.h b/Libraries/libressl/crypto/bn/bn_internal.h new file mode 100644 index 000000000..fd04bc9f8 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_internal.h @@ -0,0 +1,568 @@ +/* $OpenBSD: bn_internal.h,v 1.15 2023/06/25 11:42:26 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bn_arch.h" + +#ifndef HEADER_BN_INTERNAL_H +#define HEADER_BN_INTERNAL_H + +int bn_word_clz(BN_ULONG w); + +int bn_bitsize(const BIGNUM *bn); + +#ifndef HAVE_BN_CT_NE_ZERO +static inline int +bn_ct_ne_zero(BN_ULONG w) +{ + return (w | ~(w - 1)) >> (BN_BITS2 - 1); +} +#endif + +#ifndef HAVE_BN_CT_NE_ZERO_MASK +static inline BN_ULONG +bn_ct_ne_zero_mask(BN_ULONG w) +{ + return 0 - bn_ct_ne_zero(w); +} +#endif + +#ifndef HAVE_BN_CT_EQ_ZERO +static inline int +bn_ct_eq_zero(BN_ULONG w) +{ + return 1 - bn_ct_ne_zero(w); +} +#endif + +#ifndef HAVE_BN_CT_EQ_ZERO_MASK +static inline BN_ULONG +bn_ct_eq_zero_mask(BN_ULONG w) +{ + return 0 - bn_ct_eq_zero(w); +} +#endif + +#ifndef HAVE_BN_CLZW +static inline int +bn_clzw(BN_ULONG w) +{ + return bn_word_clz(w); +} +#endif + +/* + * Big number primitives are named as the operation followed by a suffix + * that indicates the number of words that it operates on, where 'w' means + * single word, 'dw' means double word, 'tw' means triple word and 'qw' means + * quadruple word. Unless otherwise noted, the size of the output is implied + * based on its inputs, for example bn_mulw() takes two single word inputs + * and is going to produce a double word result. + * + * Where a function implements multiple operations, these are listed in order. + * For example, a function that computes (r1:r0) = a * b + c is named + * bn_mulw_addw(), producing a double word result. + */ + +/* + * Default implementations for BN_ULLONG architectures. + * + * On these platforms the C compiler is generally better at optimising without + * the use of inline assembly primitives. However, it can be difficult for the + * compiler to see through primitives in order to combine operations, due to + * type changes/narrowing. For this reason compound primitives are usually + * explicitly provided. + */ +#ifdef BN_ULLONG + +#ifndef HAVE_BN_ADDW +#define HAVE_BN_ADDW +static inline void +bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULLONG r; + + r = (BN_ULLONG)a + (BN_ULLONG)b; + + *out_r1 = r >> BN_BITS2; + *out_r0 = r & BN_MASK2; +} +#endif + +#ifndef HAVE_BN_ADDW_ADDW +#define HAVE_BN_ADDW_ADDW +static inline void +bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULLONG r; + + r = (BN_ULLONG)a + (BN_ULLONG)b + (BN_ULLONG)c; + + *out_r1 = r >> BN_BITS2; + *out_r0 = r & BN_MASK2; +} +#endif + +#ifndef HAVE_BN_MULW +#define HAVE_BN_MULW +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULLONG r; + + r = (BN_ULLONG)a * (BN_ULLONG)b; + + *out_r1 = r >> BN_BITS2; + *out_r0 = r & BN_MASK2; +} +#endif + +#ifndef HAVE_BN_MULW_ADDW +#define HAVE_BN_MULW_ADDW +static inline void +bn_mulw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULLONG r; + + r = (BN_ULLONG)a * (BN_ULLONG)b + (BN_ULLONG)c; + + *out_r1 = r >> BN_BITS2; + *out_r0 = r & BN_MASK2; +} +#endif + +#ifndef HAVE_BN_MULW_ADDW_ADDW +#define HAVE_BN_MULW_ADDW_ADDW +static inline void +bn_mulw_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG d, + BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULLONG r; + + r = (BN_ULLONG)a * (BN_ULLONG)b + (BN_ULLONG)c + (BN_ULLONG)d; + + *out_r1 = r >> BN_BITS2; + *out_r0 = r & BN_MASK2; +} +#endif + +#endif /* !BN_ULLONG */ + +/* + * bn_addw() computes (r1:r0) = a + b, where both inputs are single words, + * producing a double word result. The value of r1 is the carry from the + * addition. + */ +#ifndef HAVE_BN_ADDW +static inline void +bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r1, r0, c1, c2; + + c1 = a | b; + c2 = a & b; + r0 = a + b; + r1 = ((c1 & ~r0) | c2) >> (BN_BITS2 - 1); /* carry */ + + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_addw_addw() computes (r1:r0) = a + b + c, where all inputs are single + * words, producing a double word result. + */ +#ifndef HAVE_BN_ADDW_ADDW +static inline void +bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULONG carry, r1, r0; + + bn_addw(a, b, &r1, &r0); + bn_addw(r0, c, &carry, &r0); + r1 += carry; + + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_qwaddqw() computes + * (r4:r3:r2:r1:r0) = (a3:a2:a1:a0) + (b3:b2:b1:b0) + carry, where a is a quad word, + * b is a quad word, and carry is a single word with value 0 or 1, producing a four + * word result and carry. + */ +#ifndef HAVE_BN_QWADDQW +static inline void +bn_qwaddqw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b3, + BN_ULONG b2, BN_ULONG b1, BN_ULONG b0, BN_ULONG carry, BN_ULONG *out_carry, + BN_ULONG *out_r3, BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r3, r2, r1, r0; + + bn_addw_addw(a0, b0, carry, &carry, &r0); + bn_addw_addw(a1, b1, carry, &carry, &r1); + bn_addw_addw(a2, b2, carry, &carry, &r2); + bn_addw_addw(a3, b3, carry, &carry, &r3); + + *out_carry = carry; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_subw() computes r0 = a - b, where both inputs are single words, + * producing a single word result and borrow. + */ +#ifndef HAVE_BN_SUBW +static inline void +bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0) +{ + BN_ULONG borrow, r0; + + r0 = a - b; + borrow = ((r0 | (b & ~a)) & (b | ~a)) >> (BN_BITS2 - 1); + + *out_borrow = borrow; + *out_r0 = r0; +} +#endif + +/* + * bn_subw_subw() computes r0 = a - b - c, where all inputs are single words, + * producing a single word result and borrow. + */ +#ifndef HAVE_BN_SUBW_SUBW +static inline void +bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow, + BN_ULONG *out_r0) +{ + BN_ULONG b1, b2, r0; + + bn_subw(a, b, &b1, &r0); + bn_subw(r0, c, &b2, &r0); + + *out_borrow = b1 + b2; + *out_r0 = r0; +} +#endif + +/* + * bn_qwsubqw() computes + * (r3:r2:r1:r0) = (a3:a2:a1:a0) - (b3:b2:b1:b0) - borrow, where a is a quad word, + * b is a quad word, and borrow is a single word with value 0 or 1, producing a + * four word result and borrow. + */ +#ifndef HAVE_BN_QWSUBQW +static inline void +bn_qwsubqw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b3, + BN_ULONG b2, BN_ULONG b1, BN_ULONG b0, BN_ULONG borrow, BN_ULONG *out_borrow, + BN_ULONG *out_r3, BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r3, r2, r1, r0; + + bn_subw_subw(a0, b0, borrow, &borrow, &r0); + bn_subw_subw(a1, b1, borrow, &borrow, &r1); + bn_subw_subw(a2, b2, borrow, &borrow, &r2); + bn_subw_subw(a3, b3, borrow, &borrow, &r3); + + *out_borrow = borrow; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_mulw() computes (r1:r0) = a * b, where both inputs are single words, + * producing a double word result. + */ +#ifndef HAVE_BN_MULW +/* + * Multiply two words (a * b) producing a double word result (h:l). + * + * This can be rewritten as: + * + * a * b = (hi32(a) * 2^32 + lo32(a)) * (hi32(b) * 2^32 + lo32(b)) + * = hi32(a) * hi32(b) * 2^64 + + * hi32(a) * lo32(b) * 2^32 + + * hi32(b) * lo32(a) * 2^32 + + * lo32(a) * lo32(b) + * + * The multiplication for each part of a and b can be calculated for each of + * these four terms without overflowing a BN_ULONG, as the maximum value of a + * 32 bit x 32 bit multiplication is 32 + 32 = 64 bits. Once these + * multiplications have been performed the result can be partitioned and summed + * into a double word (h:l). The same applies on a 32 bit system, substituting + * 16 for 32 and 32 for 64. + */ +#if 1 +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG a1, a0, b1, b0, r1, r0; + BN_ULONG carry, x; + + a1 = a >> BN_BITS4; + a0 = a & BN_MASK2l; + b1 = b >> BN_BITS4; + b0 = b & BN_MASK2l; + + r1 = a1 * b1; + r0 = a0 * b0; + + /* (a1 * b0) << BN_BITS4, partition the result across r1:r0 with carry. */ + x = a1 * b0; + r1 += x >> BN_BITS4; + bn_addw(r0, x << BN_BITS4, &carry, &r0); + r1 += carry; + + /* (b1 * a0) << BN_BITS4, partition the result across r1:r0 with carry. */ + x = b1 * a0; + r1 += x >> BN_BITS4; + bn_addw(r0, x << BN_BITS4, &carry, &r0); + r1 += carry; + + *out_r1 = r1; + *out_r0 = r0; +} +#else + +/* + * XXX - this accumulator based version uses fewer instructions, however + * requires more variables/registers. It seems to be slower on at least amd64 + * and i386, however may be faster on other architectures that have more + * registers available. Further testing is required and one of the two + * implementations should eventually be removed. + */ +static inline void +bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG a1, a0, b1, b0, r1, r0, x; + BN_ULONG acc0, acc1, acc2, acc3; + + a1 = a >> BN_BITS4; + b1 = b >> BN_BITS4; + a0 = a & BN_MASK2l; + b0 = b & BN_MASK2l; + + r1 = a1 * b1; + r0 = a0 * b0; + + acc0 = r0 & BN_MASK2l; + acc1 = r0 >> BN_BITS4; + acc2 = r1 & BN_MASK2l; + acc3 = r1 >> BN_BITS4; + + /* (a1 * b0) << BN_BITS4, partition the result across r1:r0. */ + x = a1 * b0; + acc1 += x & BN_MASK2l; + acc2 += (acc1 >> BN_BITS4) + (x >> BN_BITS4); + acc1 &= BN_MASK2l; + acc3 += acc2 >> BN_BITS4; + acc2 &= BN_MASK2l; + + /* (b1 * a0) << BN_BITS4, partition the result across r1:r0. */ + x = b1 * a0; + acc1 += x & BN_MASK2l; + acc2 += (acc1 >> BN_BITS4) + (x >> BN_BITS4); + acc1 &= BN_MASK2l; + acc3 += acc2 >> BN_BITS4; + acc2 &= BN_MASK2l; + + *out_r1 = (acc3 << BN_BITS4) | acc2; + *out_r0 = (acc1 << BN_BITS4) | acc0; +} +#endif +#endif + +#ifndef HAVE_BN_MULW_LO +static inline BN_ULONG +bn_mulw_lo(BN_ULONG a, BN_ULONG b) +{ + return a * b; +} +#endif + +#ifndef HAVE_BN_MULW_HI +static inline BN_ULONG +bn_mulw_hi(BN_ULONG a, BN_ULONG b) +{ + BN_ULONG h, l; + + bn_mulw(a, b, &h, &l); + + return h; +} +#endif + +/* + * bn_mulw_addw() computes (r1:r0) = a * b + c with all inputs being single + * words, producing a double word result. + */ +#ifndef HAVE_BN_MULW_ADDW +static inline void +bn_mulw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULONG carry, r1, r0; + + bn_mulw(a, b, &r1, &r0); + bn_addw(r0, c, &carry, &r0); + r1 += carry; + + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_mulw_addw_addw() computes (r1:r0) = a * b + c + d with all inputs being + * single words, producing a double word result. + */ +#ifndef HAVE_BN_MULW_ADDW_ADDW +static inline void +bn_mulw_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG d, + BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG carry, r1, r0; + + bn_mulw_addw(a, b, c, &r1, &r0); + bn_addw(r0, d, &carry, &r0); + r1 += carry; + + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_mulw_addtw() computes (r2:r1:r0) = a * b + (c2:c1:c0), where a and b are + * single words and (c2:c1:c0) is a triple word, producing a triple word result. + * The caller must ensure that the inputs provided do not result in c2 + * overflowing. + */ +#ifndef HAVE_BN_MULW_ADDTW +static inline void +bn_mulw_addtw(BN_ULONG a, BN_ULONG b, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0, + BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG carry, r2, r1, r0, x1; + + bn_mulw_addw(a, b, c0, &x1, &r0); + bn_addw(c1, x1, &carry, &r1); + r2 = c2 + carry; + + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_mul2_mulw_addtw() computes (r2:r1:r0) = 2 * a * b + (c2:c1:c0), where a + * and b are single words and (c2:c1:c0) is a triple word, producing a triple + * word result. The caller must ensure that the inputs provided do not result + * in c2 overflowing. + */ +#ifndef HAVE_BN_MUL2_MULW_ADDTW +static inline void +bn_mul2_mulw_addtw(BN_ULONG a, BN_ULONG b, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0, + BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r2, r1, r0, x1, x0; + BN_ULONG carry; + + bn_mulw(a, b, &x1, &x0); + bn_addw(c0, x0, &carry, &r0); + bn_addw(c1, x1 + carry, &r2, &r1); + bn_addw(c2, r2, &carry, &r2); + bn_addw(r0, x0, &carry, &r0); + bn_addw(r1, x1 + carry, &carry, &r1); + r2 += carry; + + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_qwmulw_addw() computes (r4:r3:r2:r1:r0) = (a3:a2:a1:a0) * b + c, where a + * is a quad word, b is a single word and c is a single word, producing a five + * word result. + */ +#ifndef HAVE_BN_QWMULW_ADDW +static inline void +bn_qwmulw_addw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b, + BN_ULONG c, BN_ULONG *out_r4, BN_ULONG *out_r3, BN_ULONG *out_r2, + BN_ULONG *out_r1, BN_ULONG *out_r0) +{ + BN_ULONG r3, r2, r1, r0; + + bn_mulw_addw(a0, b, c, &c, &r0); + bn_mulw_addw(a1, b, c, &c, &r1); + bn_mulw_addw(a2, b, c, &c, &r2); + bn_mulw_addw(a3, b, c, &c, &r3); + + *out_r4 = c; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +/* + * bn_qwmulw_addqw_addw() computes + * (r4:r3:r2:r1:r0) = (a3:a2:a1:a0) * b + (c3:c2:c1:c0) + d, where a + * is a quad word, b is a single word, c is a quad word, and d is a single word, + * producing a five word result. + */ +#ifndef HAVE_BN_QWMULW_ADDQW_ADDW +static inline void +bn_qwmulw_addqw_addw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, + BN_ULONG b, BN_ULONG c3, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0, BN_ULONG d, + BN_ULONG *out_r4, BN_ULONG *out_r3, BN_ULONG *out_r2, BN_ULONG *out_r1, + BN_ULONG *out_r0) +{ + BN_ULONG r3, r2, r1, r0; + + bn_mulw_addw_addw(a0, b, c0, d, &d, &r0); + bn_mulw_addw_addw(a1, b, c1, d, &d, &r1); + bn_mulw_addw_addw(a2, b, c2, d, &d, &r2); + bn_mulw_addw_addw(a3, b, c3, d, &d, &r3); + + *out_r4 = d; + *out_r3 = r3; + *out_r2 = r2; + *out_r1 = r1; + *out_r0 = r0; +} +#endif + +#endif diff --git a/Libraries/libressl/crypto/bn/bn_isqrt.c b/Libraries/libressl/crypto/bn/bn_isqrt.c new file mode 100644 index 000000000..018d5f34b --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_isqrt.c @@ -0,0 +1,234 @@ +/* $OpenBSD: bn_isqrt.c,v 1.10 2023/06/04 17:28:35 tb Exp $ */ +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "bn_local.h" +#include "crypto_internal.h" + +/* + * Calculate integer square root of |n| using a variant of Newton's method. + * + * Returns the integer square root of |n| in the caller-provided |out_sqrt|; + * |*out_perfect| is set to 1 if and only if |n| is a perfect square. + * One of |out_sqrt| and |out_perfect| can be NULL; |in_ctx| can be NULL. + * + * Returns 0 on error, 1 on success. + * + * Adapted from pure Python describing cpython's math.isqrt(), without bothering + * with any of the optimizations in the C code. A correctness proof is here: + * https://github.com/mdickinson/snippets/blob/master/proofs/isqrt/src/isqrt.lean + * The comments in the Python code also give a rather detailed proof. + */ + +int +bn_isqrt(BIGNUM *out_sqrt, int *out_perfect, const BIGNUM *n, BN_CTX *in_ctx) +{ + BN_CTX *ctx = NULL; + BIGNUM *a, *b; + int c, d, e, s; + int cmp, perfect; + int ret = 0; + + if (out_perfect == NULL && out_sqrt == NULL) { + BNerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if (BN_is_negative(n)) { + BNerror(BN_R_INVALID_RANGE); + goto err; + } + + if ((ctx = in_ctx) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + + if (BN_is_zero(n)) { + perfect = 1; + BN_zero(a); + goto done; + } + + if (!BN_one(a)) + goto err; + + c = (BN_num_bits(n) - 1) / 2; + d = 0; + + /* Calculate s = floor(log(c)). */ + if (!BN_set_word(b, c)) + goto err; + s = BN_num_bits(b) - 1; + + /* + * By definition, the loop below is run <= floor(log(log(n))) times. + * Comments in the cpython code establish the loop invariant that + * + * (a - 1)^2 < n / 4^(c - d) < (a + 1)^2 + * + * holds true in every iteration. Once this is proved via induction, + * correctness of the algorithm is easy. + * + * Roughly speaking, A = (a << (d - e)) is used for one Newton step + * "a = (A >> 1) + (m >> 1) / A" approximating m = (n >> 2 * (c - d)). + */ + + for (; s >= 0; s--) { + e = d; + d = c >> s; + + if (!BN_rshift(b, n, 2 * c - d - e + 1)) + goto err; + + if (!BN_div_ct(b, NULL, b, a, ctx)) + goto err; + + if (!BN_lshift(a, a, d - e - 1)) + goto err; + + if (!BN_add(a, a, b)) + goto err; + } + + /* + * The loop invariant implies that either a or a - 1 is isqrt(n). + * Figure out which one it is. The invariant also implies that for + * a perfect square n, a must be the square root. + */ + + if (!BN_sqr(b, a, ctx)) + goto err; + + /* If a^2 > n, we must have isqrt(n) == a - 1. */ + if ((cmp = BN_cmp(b, n)) > 0) { + if (!BN_sub_word(a, 1)) + goto err; + } + + perfect = cmp == 0; + + done: + if (out_perfect != NULL) + *out_perfect = perfect; + + if (out_sqrt != NULL) { + if (!bn_copy(out_sqrt, a)) + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + if (ctx != in_ctx) + BN_CTX_free(ctx); + + return ret; +} + +/* + * is_square_mod_N[r % N] indicates whether r % N has a square root modulo N. + * The tables are generated in regress/lib/libcrypto/bn/bn_isqrt.c. + */ + +const uint8_t is_square_mod_11[] = { + 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, +}; +CTASSERT(sizeof(is_square_mod_11) == 11); + +const uint8_t is_square_mod_63[] = { + 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +}; +CTASSERT(sizeof(is_square_mod_63) == 63); + +const uint8_t is_square_mod_64[] = { + 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +}; +CTASSERT(sizeof(is_square_mod_64) == 64); + +const uint8_t is_square_mod_65[] = { + 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, + 1, +}; +CTASSERT(sizeof(is_square_mod_65) == 65); + +/* + * Determine whether n is a perfect square or not. + * + * Returns 1 on success and 0 on error. In case of success, |*out_perfect| is + * set to 1 if and only if |n| is a perfect square. + */ + +int +bn_is_perfect_square(int *out_perfect, const BIGNUM *n, BN_CTX *ctx) +{ + BN_ULONG r; + + *out_perfect = 0; + + if (BN_is_negative(n)) + return 1; + + /* + * Before performing an expensive bn_isqrt() operation, weed out many + * obvious non-squares. See H. Cohen, "A course in computational + * algebraic number theory", Algorithm 1.7.3. + * + * The idea is that a square remains a square when reduced modulo any + * number. The moduli are chosen in such a way that a non-square has + * probability < 1% of passing the four table lookups. + */ + + /* n % 64 */ + r = BN_lsw(n) & 0x3f; + + if (!is_square_mod_64[r % 64]) + return 1; + + if ((r = BN_mod_word(n, 11 * 63 * 65)) == (BN_ULONG)-1) + return 0; + + if (!is_square_mod_63[r % 63] || + !is_square_mod_65[r % 65] || + !is_square_mod_11[r % 11]) + return 1; + + return bn_isqrt(NULL, out_perfect, n, ctx); +} diff --git a/Libraries/libressl/crypto/bn/bn_kron.c b/Libraries/libressl/crypto/bn/bn_kron.c new file mode 100644 index 000000000..a170d688e --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_kron.c @@ -0,0 +1,195 @@ +/* $OpenBSD: bn_kron.c,v 1.15 2023/07/08 12:21:58 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "bn_local.h" + +/* + * Kronecker symbol, implemented according to Henri Cohen, "A Course in + * Computational Algebraic Number Theory", Algorithm 1.4.10. + * + * Returns -1, 0, or 1 on success and -2 on error. + */ + +int +BN_kronecker(const BIGNUM *A, const BIGNUM *B, BN_CTX *ctx) +{ + /* tab[BN_lsw(n) & 7] = (-1)^((n^2 - 1)) / 8) for odd values of n. */ + static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1}; + BIGNUM *a, *b, *tmp; + int k, v; + int ret = -2; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto end; + if ((b = BN_CTX_get(ctx)) == NULL) + goto end; + + if (!bn_copy(a, A)) + goto end; + if (!bn_copy(b, B)) + goto end; + + /* + * Cohen's step 1: + */ + + /* If b is zero, output 1 if |a| is 1, otherwise output 0. */ + if (BN_is_zero(b)) { + ret = BN_abs_is_word(a, 1); + goto end; + } + + /* + * Cohen's step 2: + */ + + /* If both are even, they have a factor in common, so output 0. */ + if (!BN_is_odd(a) && !BN_is_odd(b)) { + ret = 0; + goto end; + } + + /* Factorize b = 2^v * u with odd u and replace b with u. */ + v = 0; + while (!BN_is_bit_set(b, v)) + v++; + if (!BN_rshift(b, b, v)) + goto end; + + /* If v is even set k = 1, otherwise set it to (-1)^((a^2 - 1) / 8). */ + k = 1; + if (v % 2 != 0) + k = tab[BN_lsw(a) & 7]; + + /* + * If b is negative, replace it with -b and if a is also negative + * replace k with -k. + */ + if (BN_is_negative(b)) { + BN_set_negative(b, 0); + + if (BN_is_negative(a)) + k = -k; + } + + /* + * Now b is positive and odd, so compute the Jacobi symbol (a/b) + * and multiply it by k. + */ + + while (1) { + /* + * Cohen's step 3: + */ + + /* b is positive and odd. */ + + /* If a is zero output k if b is one, otherwise output 0. */ + if (BN_is_zero(a)) { + ret = BN_is_one(b) ? k : 0; + goto end; + } + + /* Factorize a = 2^v * u with odd u and replace a with u. */ + v = 0; + while (!BN_is_bit_set(a, v)) + v++; + if (!BN_rshift(a, a, v)) + goto end; + + /* If v is odd, multiply k with (-1)^((b^2 - 1) / 8). */ + if (v % 2 != 0) + k *= tab[BN_lsw(b) & 7]; + + /* + * Cohen's step 4: + */ + + /* + * Apply the reciprocity law: multiply k by (-1)^((a-1)(b-1)/4). + * + * This expression is -1 if and only if a and b are 3 (mod 4). + * In turn, this is the case if and only if their two's + * complement representations have the second bit set. + * a could be negative in the first iteration, b is positive. + */ + if ((BN_is_negative(a) ? ~BN_lsw(a) : BN_lsw(a)) & BN_lsw(b) & 2) + k = -k; + + /* + * (a, b) := (b mod |a|, |a|) + * + * Once this is done, we know that 0 < a < b at the start of the + * loop. Since b is strictly decreasing, the loop terminates. + */ + + if (!BN_nnmod(b, b, a, ctx)) + goto end; + + tmp = a; + a = b; + b = tmp; + + BN_set_negative(b, 0); + } + + end: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_kronecker); diff --git a/Libraries/libressl/crypto/bn/bn_lib.c b/Libraries/libressl/crypto/bn/bn_lib.c new file mode 100644 index 000000000..c0c0ac876 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_lib.c @@ -0,0 +1,736 @@ +/* $OpenBSD: bn_lib.c,v 1.90 2023/07/28 10:35:14 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include + +#include "bn_local.h" +#include "bn_internal.h" + +BIGNUM * +BN_new(void) +{ + BIGNUM *bn; + + if ((bn = calloc(1, sizeof(BIGNUM))) == NULL) { + BNerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + bn->flags = BN_FLG_MALLOCED; + + return bn; +} +LCRYPTO_ALIAS(BN_new); + +void +BN_init(BIGNUM *a) +{ + memset(a, 0, sizeof(BIGNUM)); +} + +void +BN_clear(BIGNUM *a) +{ + if (a->d != NULL) + explicit_bzero(a->d, a->dmax * sizeof(a->d[0])); + a->top = 0; + a->neg = 0; +} +LCRYPTO_ALIAS(BN_clear); + +void +BN_free(BIGNUM *bn) +{ + if (bn == NULL) + return; + + if (!BN_get_flags(bn, BN_FLG_STATIC_DATA)) + freezero(bn->d, bn->dmax * sizeof(bn->d[0])); + + if (!BN_get_flags(bn, BN_FLG_MALLOCED)) { + explicit_bzero(bn, sizeof(*bn)); + return; + } + + freezero(bn, sizeof(*bn)); +} +LCRYPTO_ALIAS(BN_free); + +void +BN_clear_free(BIGNUM *bn) +{ + BN_free(bn); +} +LCRYPTO_ALIAS(BN_clear_free); + +void +BN_set_flags(BIGNUM *b, int n) +{ + b->flags |= n; +} +LCRYPTO_ALIAS(BN_set_flags); + +int +BN_get_flags(const BIGNUM *b, int n) +{ + return b->flags & n; +} +LCRYPTO_ALIAS(BN_get_flags); + +void +BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags) +{ + int dest_flags; + + dest_flags = (dest->flags & BN_FLG_MALLOCED) | + (b->flags & ~BN_FLG_MALLOCED) | BN_FLG_STATIC_DATA | flags; + + *dest = *b; + dest->flags = dest_flags; +} +LCRYPTO_ALIAS(BN_with_flags); + +static const BN_ULONG bn_value_one_data = 1; +static const BIGNUM bn_value_one = { + .d = (BN_ULONG *)&bn_value_one_data, + .top = 1, + .dmax = 1, + .neg = 0, + .flags = BN_FLG_STATIC_DATA, +}; + +const BIGNUM * +BN_value_one(void) +{ + return &bn_value_one; +} +LCRYPTO_ALIAS(BN_value_one); + +int +BN_num_bits_word(BN_ULONG w) +{ + return BN_BITS2 - bn_clzw(w); +} +LCRYPTO_ALIAS(BN_num_bits_word); + +int +BN_num_bits(const BIGNUM *bn) +{ + return bn_bitsize(bn); +} +LCRYPTO_ALIAS(BN_num_bits); + +void +bn_correct_top(BIGNUM *a) +{ + while (a->top > 0 && a->d[a->top - 1] == 0) + a->top--; +} + +static int +bn_expand_internal(BIGNUM *bn, int words) +{ + BN_ULONG *d; + + if (words < 0) { + BNerror(BN_R_BIGNUM_TOO_LONG); // XXX + return 0; + } + + if (words > INT_MAX / (4 * BN_BITS2)) { + BNerror(BN_R_BIGNUM_TOO_LONG); + return 0; + } + if (BN_get_flags(bn, BN_FLG_STATIC_DATA)) { + BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return 0; + } + + d = recallocarray(bn->d, bn->dmax, words, sizeof(BN_ULONG)); + if (d == NULL) { + BNerror(ERR_R_MALLOC_FAILURE); + return 0; + } + bn->d = d; + bn->dmax = words; + + return 1; +} + +int +bn_expand(BIGNUM *bn, int bits) +{ + int words; + + if (bits < 0) + return 0; + + if (bits > (INT_MAX - BN_BITS2 + 1)) + return 0; + + words = (bits + BN_BITS2 - 1) / BN_BITS2; + + return bn_wexpand(bn, words); +} + +int +bn_wexpand(BIGNUM *bn, int words) +{ + if (words < 0) + return 0; + + if (words <= bn->dmax) + return 1; + + return bn_expand_internal(bn, words); +} + +BIGNUM * +BN_dup(const BIGNUM *a) +{ + BIGNUM *t; + + if (a == NULL) + return NULL; + + t = BN_new(); + if (t == NULL) + return NULL; + if (!bn_copy(t, a)) { + BN_free(t); + return NULL; + } + return t; +} +LCRYPTO_ALIAS(BN_dup); + +static inline void +bn_copy_words(BN_ULONG *ap, const BN_ULONG *bp, int n) +{ + while (n > 0) { + ap[0] = bp[0]; + ap++; + bp++; + n--; + } +} + +BIGNUM * +BN_copy(BIGNUM *a, const BIGNUM *b) +{ + if (a == b) + return (a); + + if (!bn_wexpand(a, b->top)) + return (NULL); + + bn_copy_words(a->d, b->d, b->top); + + /* Copy constant time flag from b, but make it sticky on a. */ + a->flags |= b->flags & BN_FLG_CONSTTIME; + + a->top = b->top; + a->neg = b->neg; + + return (a); +} +LCRYPTO_ALIAS(BN_copy); + +int +bn_copy(BIGNUM *dst, const BIGNUM *src) +{ + return BN_copy(dst, src) != NULL; +} + +void +BN_swap(BIGNUM *a, BIGNUM *b) +{ + int flags_old_a, flags_old_b; + BN_ULONG *tmp_d; + int tmp_top, tmp_dmax, tmp_neg; + + + flags_old_a = a->flags; + flags_old_b = b->flags; + + tmp_d = a->d; + tmp_top = a->top; + tmp_dmax = a->dmax; + tmp_neg = a->neg; + + a->d = b->d; + a->top = b->top; + a->dmax = b->dmax; + a->neg = b->neg; + + b->d = tmp_d; + b->top = tmp_top; + b->dmax = tmp_dmax; + b->neg = tmp_neg; + + a->flags = (flags_old_a & BN_FLG_MALLOCED) | + (flags_old_b & BN_FLG_STATIC_DATA); + b->flags = (flags_old_b & BN_FLG_MALLOCED) | + (flags_old_a & BN_FLG_STATIC_DATA); +} +LCRYPTO_ALIAS(BN_swap); + +BN_ULONG +BN_get_word(const BIGNUM *a) +{ + if (a->top > 1) + return BN_MASK2; + else if (a->top == 1) + return a->d[0]; + /* a->top == 0 */ + return 0; +} +LCRYPTO_ALIAS(BN_get_word); + +int +BN_set_word(BIGNUM *a, BN_ULONG w) +{ + if (!bn_wexpand(a, 1)) + return (0); + a->neg = 0; + a->d[0] = w; + a->top = (w ? 1 : 0); + return (1); +} +LCRYPTO_ALIAS(BN_set_word); + +int +BN_ucmp(const BIGNUM *a, const BIGNUM *b) +{ + int i; + + if (a->top < b->top) + return -1; + if (a->top > b->top) + return 1; + + for (i = a->top - 1; i >= 0; i--) { + if (a->d[i] != b->d[i]) + return (a->d[i] > b->d[i] ? 1 : -1); + } + + return 0; +} +LCRYPTO_ALIAS(BN_ucmp); + +int +BN_cmp(const BIGNUM *a, const BIGNUM *b) +{ + if (a == NULL || b == NULL) { + if (a != NULL) + return -1; + if (b != NULL) + return 1; + return 0; + } + + if (a->neg != b->neg) + return b->neg - a->neg; + + if (a->neg) + return BN_ucmp(b, a); + + return BN_ucmp(a, b); +} +LCRYPTO_ALIAS(BN_cmp); + +int +BN_set_bit(BIGNUM *a, int n) +{ + int i, j, k; + + if (n < 0) + return 0; + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) { + if (!bn_wexpand(a, i + 1)) + return (0); + for (k = a->top; k < i + 1; k++) + a->d[k] = 0; + a->top = i + 1; + } + + a->d[i] |= (((BN_ULONG)1) << j); + return (1); +} +LCRYPTO_ALIAS(BN_set_bit); + +int +BN_clear_bit(BIGNUM *a, int n) +{ + int i, j; + + if (n < 0) + return 0; + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) + return (0); + + a->d[i] &= (~(((BN_ULONG)1) << j)); + bn_correct_top(a); + return (1); +} +LCRYPTO_ALIAS(BN_clear_bit); + +int +BN_is_bit_set(const BIGNUM *a, int n) +{ + int i, j; + + if (n < 0) + return 0; + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) + return 0; + return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); +} +LCRYPTO_ALIAS(BN_is_bit_set); + +int +BN_mask_bits(BIGNUM *a, int n) +{ + int b, w; + + if (n < 0) + return 0; + + w = n / BN_BITS2; + b = n % BN_BITS2; + if (w >= a->top) + return 0; + if (b == 0) + a->top = w; + else { + a->top = w + 1; + a->d[w] &= ~(BN_MASK2 << b); + } + bn_correct_top(a); + return (1); +} +LCRYPTO_ALIAS(BN_mask_bits); + +void +BN_set_negative(BIGNUM *bn, int neg) +{ + bn->neg = ~BN_is_zero(bn) & bn_ct_ne_zero(neg); +} +LCRYPTO_ALIAS(BN_set_negative); + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. + * The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. + * The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void +BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) +{ + BN_ULONG t; + int i; + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top^b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: + BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} +LCRYPTO_ALIAS(BN_consttime_swap); + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. + * nwords is the number of words to swap. + */ +int +BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords) +{ + BN_ULONG t; + int i, words; + + if (a == b) + return 1; + if (nwords > INT_MAX) + return 0; + words = (int)nwords; + if (!bn_wexpand(a, words) || !bn_wexpand(b, words)) + return 0; + if (a->top > words || b->top > words) { + BNerror(BN_R_INVALID_LENGTH); + return 0; + } + + /* Set condition to 0 (if it was zero) or all 1s otherwise. */ + condition = ((~condition & (condition - 1)) >> (BN_BITS2 - 1)) - 1; + + /* swap top field */ + t = (a->top ^ b->top) & condition; + a->top ^= t; + b->top ^= t; + + /* swap neg field */ + t = (a->neg ^ b->neg) & condition; + a->neg ^= t; + b->neg ^= t; + + /* swap BN_FLG_CONSTTIME from flag field */ + t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition; + a->flags ^= t; + b->flags ^= t; + + /* swap the data */ + for (i = 0; i < words; i++) { + t = (a->d[i] ^ b->d[i]) & condition; + a->d[i] ^= t; + b->d[i] ^= t; + } + + return 1; +} + +void +BN_zero(BIGNUM *a) +{ + a->neg = 0; + a->top = 0; +} +LCRYPTO_ALIAS(BN_zero); + +int +BN_one(BIGNUM *a) +{ + return BN_set_word(a, 1); +} +LCRYPTO_ALIAS(BN_one); + +int +BN_abs_is_word(const BIGNUM *a, const BN_ULONG w) +{ + return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0); +} +LCRYPTO_ALIAS(BN_abs_is_word); + +int +BN_is_zero(const BIGNUM *bn) +{ + BN_ULONG bits = 0; + int i; + + for (i = 0; i < bn->top; i++) + bits |= bn->d[i]; + + return bits == 0; +} +LCRYPTO_ALIAS(BN_is_zero); + +int +BN_is_one(const BIGNUM *a) +{ + return BN_abs_is_word(a, 1) && !a->neg; +} +LCRYPTO_ALIAS(BN_is_one); + +int +BN_is_word(const BIGNUM *a, const BN_ULONG w) +{ + return BN_abs_is_word(a, w) && (w == 0 || !a->neg); +} +LCRYPTO_ALIAS(BN_is_word); + +int +BN_is_odd(const BIGNUM *a) +{ + return a->top > 0 && (a->d[0] & 1); +} +LCRYPTO_ALIAS(BN_is_odd); + +int +BN_is_negative(const BIGNUM *a) +{ + return a->neg != 0; +} +LCRYPTO_ALIAS(BN_is_negative); + +/* + * Bits of security, see SP800-57, section 5.6.11, table 2. + */ +int +BN_security_bits(int L, int N) +{ + int secbits, bits; + + if (L >= 15360) + secbits = 256; + else if (L >= 7680) + secbits = 192; + else if (L >= 3072) + secbits = 128; + else if (L >= 2048) + secbits = 112; + else if (L >= 1024) + secbits = 80; + else + return 0; + + if (N == -1) + return secbits; + + bits = N / 2; + if (bits < 80) + return 0; + + return bits >= secbits ? secbits : bits; +} +LCRYPTO_ALIAS(BN_security_bits); + +BN_GENCB * +BN_GENCB_new(void) +{ + BN_GENCB *cb; + + if ((cb = calloc(1, sizeof(*cb))) == NULL) + return NULL; + + return cb; +} +LCRYPTO_ALIAS(BN_GENCB_new); + +void +BN_GENCB_free(BN_GENCB *cb) +{ + if (cb == NULL) + return; + free(cb); +} +LCRYPTO_ALIAS(BN_GENCB_free); + +/* Populate a BN_GENCB structure with an "old"-style callback */ +void +BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg) +{ + gencb->ver = 1; + gencb->cb.cb_1 = cb; + gencb->arg = cb_arg; +} +LCRYPTO_ALIAS(BN_GENCB_set_old); + +/* Populate a BN_GENCB structure with a "new"-style callback */ +void +BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg) +{ + gencb->ver = 2; + gencb->cb.cb_2 = cb; + gencb->arg = cb_arg; +} +LCRYPTO_ALIAS(BN_GENCB_set); + +void * +BN_GENCB_get_arg(BN_GENCB *cb) +{ + return cb->arg; +} +LCRYPTO_ALIAS(BN_GENCB_get_arg); diff --git a/Libraries/libressl/crypto/bn/bn_local.h b/Libraries/libressl/crypto/bn/bn_local.h new file mode 100644 index 000000000..a9ce466db --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_local.h @@ -0,0 +1,335 @@ +/* $OpenBSD: bn_local.h,v 1.38 2023/08/09 09:23:03 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_BN_LOCAL_H +#define HEADER_BN_LOCAL_H + +#include + +#include + +__BEGIN_HIDDEN_DECLS + +struct bignum_st { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; +}; + +struct bn_mont_ctx_st { + int ri; /* Number of bits in R */ + BIGNUM RR; /* Used to convert to Montgomery form */ + BIGNUM N; /* Modulus */ + + /* Least significant word(s) of Ni; R*(1/R mod N) - N*Ni = 1 */ + BN_ULONG n0[2]; + + int flags; +}; + +/* Used for reciprocal division/mod functions + * It cannot be shared between threads + */ +typedef struct bn_recp_ctx_st { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; +} BN_RECP_CTX; + +/* Used for slow "generation" functions. */ +struct bn_gencb_st { + unsigned int ver; /* To handle binary (in)compatibility */ + void *arg; /* callback-specific data */ + union { + /* if(ver==1) - handles old style callbacks */ + void (*cb_1)(int, int, void *); + /* if(ver==2) - new callback style */ + int (*cb_2)(int, int, BN_GENCB *); + } cb; +}; + +/* + * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions + * + * + * For window size 'w' (w >= 2) and a random 'b' bits exponent, + * the number of multiplications is a constant plus on average + * + * 2^(w-1) + (b-w)/(w+1); + * + * here 2^(w-1) is for precomputing the table (we actually need + * entries only for windows that have the lowest bit set), and + * (b-w)/(w+1) is an approximation for the expected number of + * w-bit windows, not counting the first one. + * + * Thus we should use + * + * w >= 6 if b > 671 + * w = 5 if 671 > b > 239 + * w = 4 if 239 > b > 79 + * w = 3 if 79 > b > 23 + * w <= 2 if 23 > b + * + * (with draws in between). Very small exponents are often selected + * with low Hamming weight, so we use w = 1 for b <= 23. + */ +#define BN_window_bits_for_exponent_size(b) \ + ((b) > 671 ? 6 : \ + (b) > 239 ? 5 : \ + (b) > 79 ? 4 : \ + (b) > 23 ? 3 : 1) + + +/* BN_mod_exp_mont_consttime is based on the assumption that the + * L1 data cache line width of the target processor is at least + * the following value. + */ +#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 ) +#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) + +/* Window sizes optimized for fixed window size modular exponentiation + * algorithm (BN_mod_exp_mont_consttime). + * + * To achieve the security goals of BN_mode_exp_mont_consttime, the + * maximum size of the window must not exceed + * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). + * + * Window size thresholds are defined for cache line sizes of 32 and 64, + * cache line sizes where log_2(32)=5 and log_2(64)=6 respectively. A + * window size of 7 should only be used on processors that have a 128 + * byte or greater cache line size. + */ +#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 + +# define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 937 ? 6 : \ + (b) > 306 ? 5 : \ + (b) > 89 ? 4 : \ + (b) > 22 ? 3 : 1) +# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) + +#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 + +# define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 306 ? 5 : \ + (b) > 89 ? 4 : \ + (b) > 22 ? 3 : 1) +# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) + +#endif + + +/* Pentium pro 16,16,16,32,64 */ +/* Alpha 16,16,16,16.64 */ +#define BN_MULL_SIZE_NORMAL (16) /* 32 */ +#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */ +#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */ +#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */ +#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */ + +/* The least significant word of a BIGNUM. */ +#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) + +BN_ULONG bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, + const BN_ULONG *b, int b_len); +BN_ULONG bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, + const BN_ULONG *b, int b_len); + +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); + +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a); +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); + +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + +void bn_correct_top(BIGNUM *a); +int bn_expand(BIGNUM *a, int bits); +int bn_wexpand(BIGNUM *a, int words); + +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); +void bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q, + BN_ULONG *out_r); + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); +int bn_rand_in_range(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc); +int bn_rand_interval(BIGNUM *rnd, BN_ULONG lower_word, const BIGNUM *upper_exc); + +void BN_init(BIGNUM *); + +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); + +void BN_RECP_CTX_init(BN_RECP_CTX *recp); +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +/* Explicitly const time / non-const time versions for internal use */ +int BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_div_nonct(BIGNUM *q, BIGNUM *r, const BIGNUM *n, const BIGNUM *d, + BN_CTX *ctx); +int BN_div_ct(BIGNUM *q, BIGNUM *r, const BIGNUM *n, const BIGNUM *d, + BN_CTX *ctx); +int BN_mod_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); + +BIGNUM *BN_mod_inverse_ct(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); +BIGNUM *BN_mod_inverse_nonct(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); +int BN_gcd_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_gcd_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +int BN_swap_ct(BN_ULONG swap, BIGNUM *a, BIGNUM *b, size_t nwords); + +int bn_copy(BIGNUM *dst, const BIGNUM *src); + +int bn_isqrt(BIGNUM *out_sqrt, int *out_perfect, const BIGNUM *n, BN_CTX *ctx); +int bn_is_perfect_square(int *out_perfect, const BIGNUM *n, BN_CTX *ctx); + +int bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *ctx, size_t rounds); + +int bn_printf(BIO *bio, const BIGNUM *bn, int indent, const char *fmt, ...) + __attribute__((__format__ (printf, 4, 5))) + __attribute__((__nonnull__ (4))); + +int bn_bn2hex_nosign(const BIGNUM *bn, char **out, size_t *out_len); +int bn_bn2hex_nibbles(const BIGNUM *bn, char **out, size_t *out_len); + +__END_HIDDEN_DECLS +#endif /* !HEADER_BN_LOCAL_H */ diff --git a/Libraries/libressl/crypto/bn/bn_mod.c b/Libraries/libressl/crypto/bn/bn_mod.c new file mode 100644 index 000000000..365f6fcf0 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_mod.c @@ -0,0 +1,369 @@ +/* $OpenBSD: bn_mod.c,v 1.22 2023/07/08 12:21:58 beck Exp $ */ +/* Includes code written by Lenka Fibikova + * for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "bn_local.h" + +int +BN_mod_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + return BN_div_ct(NULL, r, a, m, ctx); +} + +int +BN_mod_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + return BN_div_nonct(NULL, r, a, m, ctx); +} + +/* + * BN_nnmod() is like BN_mod(), but always returns a non-negative remainder + * (that is 0 <= r < |m| always holds). If both a and m have the same sign then + * the result is already non-negative. Otherwise, -|m| < r < 0, which needs to + * be adjusted as r := r + |m|. This equates to r := |m| - |r|. + */ +int +BN_nnmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (!BN_mod_ct(r, a, m, ctx)) + return 0; + if (BN_is_negative(r)) + return BN_usub(r, m, r); + return 1; +} +LCRYPTO_ALIAS(BN_nnmod); + +int +BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (!BN_add(r, a, b)) + return 0; + return BN_nnmod(r, r, m, ctx); +} +LCRYPTO_ALIAS(BN_mod_add); + +/* + * BN_mod_add() variant that may only be used if both a and b are non-negative + * and have already been reduced (less than m). + */ +int +BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (!BN_uadd(r, a, b)) + return 0; + if (BN_ucmp(r, m) >= 0) + return BN_usub(r, r, m); + return 1; +} +LCRYPTO_ALIAS(BN_mod_add_quick); + +int +BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (!BN_sub(r, a, b)) + return 0; + return BN_nnmod(r, r, m, ctx); +} +LCRYPTO_ALIAS(BN_mod_sub); + +/* + * BN_mod_sub() variant that may only be used if both a and b are non-negative + * and have already been reduced (less than m). + */ +int +BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (BN_ucmp(a, b) >= 0) + return BN_usub(r, a, b); + if (!BN_usub(r, b, a)) + return 0; + return BN_usub(r, m, r); +} +LCRYPTO_ALIAS(BN_mod_sub_quick); + +int +BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + BIGNUM *rr; + int ret = 0; + + BN_CTX_start(ctx); + + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + goto err; + } + + rr = r; + if (rr == a || rr == b) + rr = BN_CTX_get(ctx); + if (rr == NULL) + goto err; + + if (a == b) { + if (!BN_sqr(rr, a, ctx)) + goto err; + } else { + if (!BN_mul(rr, a, b, ctx)) + goto err; + } + if (!BN_nnmod(r, rr, m, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_mod_mul); + +int +BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + return BN_mod_mul(r, a, a, m, ctx); +} +LCRYPTO_ALIAS(BN_mod_sqr); + +int +BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (!BN_lshift1(r, a)) + return 0; + return BN_nnmod(r, r, m, ctx); +} +LCRYPTO_ALIAS(BN_mod_lshift1); + +/* + * BN_mod_lshift1() variant that may be used if a is non-negative + * and has already been reduced (less than m). + */ +int +BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) +{ + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + if (!BN_lshift1(r, a)) + return 0; + if (BN_ucmp(r, m) >= 0) + return BN_usub(r, r, m); + return 1; +} +LCRYPTO_ALIAS(BN_mod_lshift1_quick); + +int +BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx) +{ + BIGNUM *abs_m; + int ret = 0; + + BN_CTX_start(ctx); + + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + goto err; + } + + if (!BN_nnmod(r, a, m, ctx)) + goto err; + + if (BN_is_negative(m)) { + if ((abs_m = BN_CTX_get(ctx)) == NULL) + goto err; + if (!bn_copy(abs_m, m)) + goto err; + BN_set_negative(abs_m, 0); + m = abs_m; + } + if (!BN_mod_lshift_quick(r, r, n, m)) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_mod_lshift); + +/* + * BN_mod_lshift() variant that may be used if a is non-negative + * and has already been reduced (less than m). + */ +int +BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) +{ + int max_shift; + + if (r == m) { + BNerror(BN_R_INVALID_ARGUMENT); + return 0; + } + + if (!bn_copy(r, a)) + return 0; + + while (n > 0) { + if ((max_shift = BN_num_bits(m) - BN_num_bits(r)) < 0) { + BNerror(BN_R_INPUT_NOT_REDUCED); + return 0; + } + if (max_shift == 0) + max_shift = 1; + if (max_shift > n) + max_shift = n; + + if (!BN_lshift(r, r, max_shift)) + return 0; + n -= max_shift; + + if (BN_ucmp(r, m) >= 0) { + if (!BN_usub(r, r, m)) + return 0; + } + } + + return 1; +} +LCRYPTO_ALIAS(BN_mod_lshift_quick); diff --git a/Libraries/libressl/crypto/bn/bn_mod_sqrt.c b/Libraries/libressl/crypto/bn/bn_mod_sqrt.c new file mode 100644 index 000000000..280002cc4 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_mod_sqrt.c @@ -0,0 +1,723 @@ +/* $OpenBSD: bn_mod_sqrt.c,v 1.3 2023/08/03 18:53:55 tb Exp $ */ + +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bn_local.h" + +/* + * Tonelli-Shanks according to H. Cohen "A Course in Computational Algebraic + * Number Theory", Section 1.5.1, Springer GTM volume 138, Berlin, 1996. + * + * Under the assumption that p is prime and a is a quadratic residue, we know: + * + * a^[(p-1)/2] = 1 (mod p). (*) + * + * To find a square root of a (mod p), we handle three cases of increasing + * complexity. In the first two cases, we can compute a square root using an + * explicit formula, thus avoiding the probabilistic nature of Tonelli-Shanks. + * + * 1. p = 3 (mod 4). + * + * Set n = (p+1)/4. Then 2n = 1 + (p-1)/2 and (*) shows that x = a^n (mod p) + * is a square root of a: x^2 = a^(2n) = a * a^[(p-1)/2] = a (mod p). + * + * 2. p = 5 (mod 8). + * + * This uses a simplification due to Atkin. By Theorem 1.4.7 and 1.4.9, the + * Kronecker symbol (2/p) evaluates to (-1)^[(p^2-1)/8]. From p = 5 (mod 8) + * we get (p^2-1)/8 = 1 (mod 2), so (2/p) = -1, and thus + * + * 2^[(p-1)/2] = -1 (mod p). (**) + * + * Set b = (2a)^[(p-5)/8]. With (p-1)/2 = 2 + (p-5)/2, (*) and (**) show + * + * i = 2 a b^2 is a square root of -1 (mod p). + * + * Indeed, i^2 = 2^2 a^2 b^4 = 2^[(p-1)/2] a^[(p-1)/2] = -1 (mod p). Because + * of (i-1)^2 = -2i (mod p) and i (-i) = 1 (mod p), a square root of a is + * + * x = a b (i-1) + * + * as x^2 = a^2 b^2 (-2i) = a (2 a b^2) (-i) = a (mod p). + * + * 3. p = 1 (mod 8). + * + * This is the Tonelli-Shanks algorithm. For a prime p, the multiplicative + * group of GF(p) is cyclic of order p - 1 = 2^s q, with odd q. Denote its + * 2-Sylow subgroup by S. It is cyclic of order 2^s. The squares in S have + * order dividing 2^(s-1). They are the even powers of any generator z of S. + * If a is a quadratic residue, 1 = a^[(p-1)/2] = (a^q)^[2^(s-1)], so b = a^q + * is a square in S. Therefore there is an integer k such that b z^(2k) = 1. + * Set x = a^[(q+1)/2] z^k, and find x^2 = a (mod p). + * + * The problem is thus reduced to finding a generator z of the 2-Sylow + * subgroup S of GF(p)* and finding k. An iterative constructions avoids + * the need for an explicit k, a generator is found by a randomized search. + * + * While we do not actually know that p is a prime number, we can still apply + * the formulas in cases 1 and 2 and verify that we have indeed found a square + * root of p. Similarly, in case 3, we can try to find a quadratic non-residue, + * which will fail for example if p is a square. The iterative construction + * may or may not find a candidate square root which we can then validate. + */ + +/* + * Handle the cases where p is 2, p isn't odd or p is one. Since BN_mod_sqrt() + * can run on untrusted data, a primality check is too expensive. Also treat + * the obvious cases where a is 0 or 1. + */ + +static int +bn_mod_sqrt_trivial_cases(int *done, BIGNUM *out_sqrt, const BIGNUM *a, + const BIGNUM *p, BN_CTX *ctx) +{ + *done = 1; + + if (BN_abs_is_word(p, 2)) + return BN_set_word(out_sqrt, BN_is_odd(a)); + + if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { + BNerror(BN_R_P_IS_NOT_PRIME); + return 0; + } + + if (BN_is_zero(a) || BN_is_one(a)) + return BN_set_word(out_sqrt, BN_is_one(a)); + + *done = 0; + + return 1; +} + +/* + * Case 1. We know that (a/p) = 1 and that p = 3 (mod 4). + */ + +static int +bn_mod_sqrt_p_is_3_mod_4(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx) +{ + BIGNUM *n; + int ret = 0; + + BN_CTX_start(ctx); + + if ((n = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Calculate n = (|p| + 1) / 4. */ + if (!BN_uadd(n, p, BN_value_one())) + goto err; + if (!BN_rshift(n, n, 2)) + goto err; + + /* By case 1 above, out_sqrt = a^n is a square root of a (mod p). */ + if (!BN_mod_exp_ct(out_sqrt, a, n, p, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Case 2. We know that (a/p) = 1 and that p = 5 (mod 8). + */ + +static int +bn_mod_sqrt_p_is_5_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx) +{ + BIGNUM *b, *i, *n, *tmp; + int ret = 0; + + BN_CTX_start(ctx); + + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((i = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Calculate n = (|p| - 5) / 8. Since p = 5 (mod 8), simply shift. */ + if (!BN_rshift(n, p, 3)) + goto err; + BN_set_negative(n, 0); + + /* Compute tmp = 2a (mod p) for later use. */ + if (!BN_mod_lshift1(tmp, a, p, ctx)) + goto err; + + /* Calculate b = (2a)^n (mod p). */ + if (!BN_mod_exp_ct(b, tmp, n, p, ctx)) + goto err; + + /* Calculate i = 2 a b^2 (mod p). */ + if (!BN_mod_sqr(i, b, p, ctx)) + goto err; + if (!BN_mod_mul(i, tmp, i, p, ctx)) + goto err; + + /* A square root is out_sqrt = a b (i-1) (mod p). */ + if (!BN_sub_word(i, 1)) + goto err; + if (!BN_mod_mul(out_sqrt, a, b, p, ctx)) + goto err; + if (!BN_mod_mul(out_sqrt, out_sqrt, i, p, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Case 3. We know that (a/p) = 1 and that p = 1 (mod 8). + */ + +/* + * Simple helper. To find a generator of the 2-Sylow subgroup of GF(p)*, we + * need to find a quadratic non-residue of p, i.e., n such that (n/p) = -1. + */ + +static int +bn_mod_sqrt_n_is_non_residue(int *is_non_residue, const BIGNUM *n, + const BIGNUM *p, BN_CTX *ctx) +{ + switch (BN_kronecker(n, p, ctx)) { + case -1: + *is_non_residue = 1; + return 1; + case 1: + *is_non_residue = 0; + return 1; + case 0: + /* n divides p, so ... */ + BNerror(BN_R_P_IS_NOT_PRIME); + return 0; + default: + return 0; + } +} + +/* + * The following is the only non-deterministic part preparing Tonelli-Shanks. + * + * If we find n such that (n/p) = -1, then n^q (mod p) is a generator of the + * 2-Sylow subgroup of GF(p)*. To find such n, first try some small numbers, + * then random ones. + */ + +static int +bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p, + const BIGNUM *q, BN_CTX *ctx) +{ + BIGNUM *n, *p_abs; + int i, is_non_residue; + int ret = 0; + + BN_CTX_start(ctx); + + if ((n = BN_CTX_get(ctx)) == NULL) + goto err; + if ((p_abs = BN_CTX_get(ctx)) == NULL) + goto err; + + for (i = 2; i < 32; i++) { + if (!BN_set_word(n, i)) + goto err; + if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx)) + goto err; + if (is_non_residue) + goto found; + } + + if (!bn_copy(p_abs, p)) + goto err; + BN_set_negative(p_abs, 0); + + for (i = 0; i < 128; i++) { + if (!bn_rand_interval(n, 32, p_abs)) + goto err; + if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx)) + goto err; + if (is_non_residue) + goto found; + } + + /* + * The probability to get here is < 2^(-128) for prime p. For squares + * it is easy: for p = 1369 = 37^2 this happens in ~3% of runs. + */ + + BNerror(BN_R_TOO_MANY_ITERATIONS); + goto err; + + found: + /* + * If p is prime, n^q generates the 2-Sylow subgroup S of GF(p)*. + */ + + if (!BN_mod_exp_ct(out_generator, n, q, p, ctx)) + goto err; + + /* Sanity: p is not necessarily prime, so we could have found 0 or 1. */ + if (BN_is_zero(out_generator) || BN_is_one(out_generator)) { + BNerror(BN_R_P_IS_NOT_PRIME); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Initialization step for Tonelli-Shanks. + * + * In the end, b = a^q (mod p) and x = a^[(q+1)/2] (mod p). Cohen optimizes this + * to minimize taking powers of a. This is a bit confusing and distracting, so + * factor this into a separate function. + */ + +static int +bn_mod_sqrt_tonelli_shanks_initialize(BIGNUM *b, BIGNUM *x, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *q, BN_CTX *ctx) +{ + BIGNUM *k; + int ret = 0; + + BN_CTX_start(ctx); + + if ((k = BN_CTX_get(ctx)) == NULL) + goto err; + + /* k = (q-1)/2. Since q is odd, we can shift. */ + if (!BN_rshift1(k, q)) + goto err; + + /* x = a^[(q-1)/2] (mod p). */ + if (!BN_mod_exp_ct(x, a, k, p, ctx)) + goto err; + + /* b = ax^2 = a^q (mod p). */ + if (!BN_mod_sqr(b, x, p, ctx)) + goto err; + if (!BN_mod_mul(b, a, b, p, ctx)) + goto err; + + /* x = ax = a^[(q+1)/2] (mod p). */ + if (!BN_mod_mul(x, a, x, p, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Find smallest exponent m such that b^(2^m) = 1 (mod p). Assuming that a + * is a quadratic residue and p is a prime, we know that 1 <= m < r. + */ + +static int +bn_mod_sqrt_tonelli_shanks_find_exponent(int *out_exponent, const BIGNUM *b, + const BIGNUM *p, int r, BN_CTX *ctx) +{ + BIGNUM *x; + int m; + int ret = 0; + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * If r <= 1, the Tonelli-Shanks iteration should have terminated as + * r == 1 implies b == 1. + */ + if (r <= 1) { + BNerror(BN_R_P_IS_NOT_PRIME); + goto err; + } + + /* + * Sanity check to ensure taking squares actually does something: + * If b is 1, the Tonelli-Shanks iteration should have terminated. + * If b is 0, something's very wrong, in particular p can't be prime. + */ + if (BN_is_zero(b) || BN_is_one(b)) { + BNerror(BN_R_P_IS_NOT_PRIME); + goto err; + } + + if (!bn_copy(x, b)) + goto err; + + for (m = 1; m < r; m++) { + if (!BN_mod_sqr(x, x, p, ctx)) + goto err; + if (BN_is_one(x)) + break; + } + + if (m >= r) { + /* This means a is not a quadratic residue. As (a/p) = 1, ... */ + BNerror(BN_R_P_IS_NOT_PRIME); + goto err; + } + + *out_exponent = m; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * The update step. With the minimal m such that b^(2^m) = 1 (mod m), + * set t = y^[2^(r-m-1)] (mod p) and update x = xt, y = t^2, b = by. + * This preserves the loop invariants a b = x^2, y^[2^(r-1)] = -1 and + * b^[2^(r-1)] = 1. + */ + +static int +bn_mod_sqrt_tonelli_shanks_update(BIGNUM *b, BIGNUM *x, BIGNUM *y, + const BIGNUM *p, int m, int r, BN_CTX *ctx) +{ + BIGNUM *t; + int ret = 0; + + BN_CTX_start(ctx); + + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + + /* t = y^[2^(r-m-1)] (mod p). */ + if (!BN_set_bit(t, r - m - 1)) + goto err; + if (!BN_mod_exp_ct(t, y, t, p, ctx)) + goto err; + + /* x = xt (mod p). */ + if (!BN_mod_mul(x, x, t, p, ctx)) + goto err; + + /* y = t^2 = y^[2^(r-m)] (mod p). */ + if (!BN_mod_sqr(y, t, p, ctx)) + goto err; + + /* b = by (mod p). */ + if (!BN_mod_mul(b, b, y, p, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +static int +bn_mod_sqrt_p_is_1_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx) +{ + BIGNUM *b, *q, *x, *y; + int e, m, r; + int ret = 0; + + BN_CTX_start(ctx); + + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((q = BN_CTX_get(ctx)) == NULL) + goto err; + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + if ((y = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Factor p - 1 = 2^e q with odd q. Since p = 1 (mod 8), we know e >= 3. + */ + + e = 1; + while (!BN_is_bit_set(p, e)) + e++; + if (!BN_rshift(q, p, e)) + goto err; + + if (!bn_mod_sqrt_find_sylow_generator(y, p, q, ctx)) + goto err; + + /* + * Set b = a^q (mod p) and x = a^[(q+1)/2] (mod p). + */ + if (!bn_mod_sqrt_tonelli_shanks_initialize(b, x, a, p, q, ctx)) + goto err; + + /* + * The Tonelli-Shanks iteration. Starting with r = e, the following loop + * invariants hold at the start of the loop. + * + * a b = x^2 (mod p) + * y^[2^(r-1)] = -1 (mod p) + * b^[2^(r-1)] = 1 (mod p) + * + * In particular, if b = 1 (mod p), x is a square root of a. + * + * Since p - 1 = 2^e q, we have 2^(e-1) q = (p - 1) / 2, so in the first + * iteration this follows from (a/p) = 1, (n/p) = -1, y = n^q, b = a^q. + * + * In subsequent iterations, t = y^[2^(r-m-1)], where m is the smallest + * m such that b^(2^m) = 1. With x = xt (mod p) and b = bt^2 (mod p) the + * first invariant is preserved, the second and third follow from + * y = t^2 (mod p) and r = m as well as the choice of m. + * + * Finally, r is strictly decreasing in each iteration. If p is prime, + * let S be the 2-Sylow subgroup of GF(p)*. We can prove the algorithm + * stops: Let S_r be the subgroup of S consisting of elements of order + * dividing 2^r. Then S_r = and b is in S_(r-1). The S_r form a + * descending filtration of S and when r = 1, then b = 1. + */ + + for (r = e; r >= 1; r = m) { + /* + * Termination condition. If b == 1 then x is a square root. + */ + if (BN_is_one(b)) + goto done; + + /* Find smallest exponent 1 <= m < r such that b^(2^m) == 1. */ + if (!bn_mod_sqrt_tonelli_shanks_find_exponent(&m, b, p, r, ctx)) + goto err; + + /* + * With t = y^[2^(r-m-1)], update x = xt, y = t^2, b = by. + */ + if (!bn_mod_sqrt_tonelli_shanks_update(b, x, y, p, m, r, ctx)) + goto err; + + /* + * Sanity check to make sure we don't loop indefinitely. + * bn_mod_sqrt_tonelli_shanks_find_exponent() ensures m < r. + */ + if (r <= m) + goto err; + } + + /* + * If p is prime, we should not get here. + */ + + BNerror(BN_R_NOT_A_SQUARE); + goto err; + + done: + if (!bn_copy(out_sqrt, x)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Choose the smaller of sqrt and |p| - sqrt. + */ + +static int +bn_mod_sqrt_normalize(BIGNUM *sqrt, const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *x; + int ret = 0; + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_lshift1(x, sqrt)) + goto err; + + if (BN_ucmp(x, p) > 0) { + if (!BN_usub(sqrt, p, sqrt)) + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Verify that a = (sqrt_a)^2 (mod p). Requires that a is reduced (mod p). + */ + +static int +bn_mod_sqrt_verify(const BIGNUM *a, const BIGNUM *sqrt_a, const BIGNUM *p, + BN_CTX *ctx) +{ + BIGNUM *x; + int ret = 0; + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_mod_sqr(x, sqrt_a, p, ctx)) + goto err; + + if (BN_cmp(x, a) != 0) { + BNerror(BN_R_NOT_A_SQUARE); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +static int +bn_mod_sqrt_internal(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx) +{ + BIGNUM *a_mod_p, *sqrt; + BN_ULONG lsw; + int done; + int kronecker; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a_mod_p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((sqrt = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_nnmod(a_mod_p, a, p, ctx)) + goto err; + + if (!bn_mod_sqrt_trivial_cases(&done, sqrt, a_mod_p, p, ctx)) + goto err; + if (done) + goto verify; + + /* + * Make sure that the Kronecker symbol (a/p) == 1. In case p is prime + * this is equivalent to a having a square root (mod p). The cost of + * BN_kronecker() is O(log^2(n)). This is small compared to the cost + * O(log^4(n)) of Tonelli-Shanks. + */ + + if ((kronecker = BN_kronecker(a_mod_p, p, ctx)) == -2) + goto err; + if (kronecker <= 0) { + /* This error is only accurate if p is known to be a prime. */ + BNerror(BN_R_NOT_A_SQUARE); + goto err; + } + + lsw = BN_lsw(p); + + if (lsw % 4 == 3) { + if (!bn_mod_sqrt_p_is_3_mod_4(sqrt, a_mod_p, p, ctx)) + goto err; + } else if (lsw % 8 == 5) { + if (!bn_mod_sqrt_p_is_5_mod_8(sqrt, a_mod_p, p, ctx)) + goto err; + } else if (lsw % 8 == 1) { + if (!bn_mod_sqrt_p_is_1_mod_8(sqrt, a_mod_p, p, ctx)) + goto err; + } else { + /* Impossible to hit since the trivial cases ensure p is odd. */ + BNerror(BN_R_P_IS_NOT_PRIME); + goto err; + } + + if (!bn_mod_sqrt_normalize(sqrt, p, ctx)) + goto err; + + verify: + if (!bn_mod_sqrt_verify(a_mod_p, sqrt, p, ctx)) + goto err; + + if (!bn_copy(out_sqrt, sqrt)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +BIGNUM * +BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *out_sqrt; + + if ((out_sqrt = in) == NULL) + out_sqrt = BN_new(); + if (out_sqrt == NULL) + goto err; + + if (!bn_mod_sqrt_internal(out_sqrt, a, p, ctx)) + goto err; + + return out_sqrt; + + err: + if (out_sqrt != in) + BN_free(out_sqrt); + + return NULL; +} +LCRYPTO_ALIAS(BN_mod_sqrt); diff --git a/Libraries/libressl/crypto/bn/bn_mont.c b/Libraries/libressl/crypto/bn/bn_mont.c new file mode 100644 index 000000000..12fea44c5 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_mont.c @@ -0,0 +1,607 @@ +/* $OpenBSD: bn_mont.c,v 1.61 2023/07/08 12:21:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Details about Montgomery multiplication algorithms can be found at + * http://security.ece.orst.edu/publications.html, e.g. + * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and + * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf + */ + +#include +#include +#include + +#include "bn_internal.h" +#include "bn_local.h" + +BN_MONT_CTX * +BN_MONT_CTX_new(void) +{ + BN_MONT_CTX *mctx; + + if ((mctx = calloc(1, sizeof(BN_MONT_CTX))) == NULL) + return NULL; + mctx->flags = BN_FLG_MALLOCED; + + BN_init(&mctx->RR); + BN_init(&mctx->N); + + return mctx; +} +LCRYPTO_ALIAS(BN_MONT_CTX_new); + +void +BN_MONT_CTX_free(BN_MONT_CTX *mctx) +{ + if (mctx == NULL) + return; + + BN_free(&mctx->RR); + BN_free(&mctx->N); + + if (mctx->flags & BN_FLG_MALLOCED) + free(mctx); +} +LCRYPTO_ALIAS(BN_MONT_CTX_free); + +BN_MONT_CTX * +BN_MONT_CTX_copy(BN_MONT_CTX *dst, BN_MONT_CTX *src) +{ + if (dst == src) + return dst; + + if (!bn_copy(&dst->RR, &src->RR)) + return NULL; + if (!bn_copy(&dst->N, &src->N)) + return NULL; + + dst->ri = src->ri; + dst->n0[0] = src->n0[0]; + dst->n0[1] = src->n0[1]; + + return dst; +} +LCRYPTO_ALIAS(BN_MONT_CTX_copy); + +int +BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) +{ + BIGNUM *N, *Ninv, *Rinv, *R; + int ret = 0; + + BN_CTX_start(ctx); + + if ((N = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Ninv = BN_CTX_get(ctx)) == NULL) + goto err; + if ((R = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Rinv = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Save modulus and determine length of R. */ + if (BN_is_zero(mod)) + goto err; + if (!bn_copy(&mont->N, mod)) + goto err; + mont->N.neg = 0; + mont->ri = ((BN_num_bits(mod) + BN_BITS2 - 1) / BN_BITS2) * BN_BITS2; + if (mont->ri * 2 < mont->ri) + goto err; + + /* + * Compute Ninv = (R * Rinv - 1)/N mod R, for R = 2^64. This provides + * a single or double word result (dependent on BN word size), that is + * later used to implement Montgomery reduction. + */ + BN_zero(R); + if (!BN_set_bit(R, 64)) + goto err; + + /* N = N mod R. */ + if (!bn_wexpand(N, 2)) + goto err; + if (!BN_set_word(N, mod->d[0])) + goto err; +#if BN_BITS2 == 32 + if (mod->top > 1) { + N->d[1] = mod->d[1]; + N->top += bn_ct_ne_zero(N->d[1]); + } +#endif + + /* Rinv = R^-1 mod N */ + if ((BN_mod_inverse_ct(Rinv, R, N, ctx)) == NULL) + goto err; + + /* Ninv = (R * Rinv - 1) / N */ + if (!BN_lshift(Ninv, Rinv, 64)) + goto err; + if (BN_is_zero(Ninv)) { + /* R * Rinv == 0, set to R so that R * Rinv - 1 is mod R. */ + if (!BN_set_bit(Ninv, 64)) + goto err; + } + if (!BN_sub_word(Ninv, 1)) + goto err; + if (!BN_div_ct(Ninv, NULL, Ninv, N, ctx)) + goto err; + + /* Store least significant word(s) of Ninv. */ + mont->n0[0] = mont->n0[1] = 0; + if (Ninv->top > 0) + mont->n0[0] = Ninv->d[0]; +#if BN_BITS2 == 32 + /* Some BN_BITS2 == 32 platforms (namely parisc) use two words of Ninv. */ + if (Ninv->top > 1) + mont->n0[1] = Ninv->d[1]; +#endif + + /* Compute RR = R * R mod N, for use when converting to Montgomery form. */ + BN_zero(&mont->RR); + if (!BN_set_bit(&mont->RR, mont->ri * 2)) + goto err; + if (!BN_mod_ct(&mont->RR, &mont->RR, &mont->N, ctx)) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_MONT_CTX_set); + +BN_MONT_CTX * +BN_MONT_CTX_set_locked(BN_MONT_CTX **pmctx, int lock, const BIGNUM *mod, + BN_CTX *ctx) +{ + BN_MONT_CTX *mctx = NULL; + + CRYPTO_r_lock(lock); + mctx = *pmctx; + CRYPTO_r_unlock(lock); + + if (mctx != NULL) + goto done; + + if ((mctx = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mctx, mod, ctx)) + goto err; + + CRYPTO_w_lock(lock); + if (*pmctx != NULL) { + /* Someone else raced us... */ + BN_MONT_CTX_free(mctx); + mctx = *pmctx; + } else { + *pmctx = mctx; + } + CRYPTO_w_unlock(lock); + + goto done; + err: + BN_MONT_CTX_free(mctx); + mctx = NULL; + done: + return mctx; +} +LCRYPTO_ALIAS(BN_MONT_CTX_set_locked); + +static int bn_montgomery_reduce(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mctx); + +static int +bn_mod_mul_montgomery_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + BIGNUM *tmp; + int ret = 0; + + BN_CTX_start(ctx); + + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + if (a == b) { + if (!BN_sqr(tmp, a, ctx)) + goto err; + } else { + if (!BN_mul(tmp, a, b, ctx)) + goto err; + } + + /* Reduce from aRR to aR. */ + if (!bn_montgomery_reduce(r, tmp, mctx)) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +static void +bn_montgomery_multiply_word(const BN_ULONG *ap, BN_ULONG b, const BN_ULONG *np, + BN_ULONG *tp, BN_ULONG w, BN_ULONG *carry_a, BN_ULONG *carry_n, int n_len) +{ + BN_ULONG x3, x2, x1, x0; + + *carry_a = *carry_n = 0; + + while (n_len & ~3) { + bn_qwmulw_addqw_addw(ap[3], ap[2], ap[1], ap[0], b, + tp[3], tp[2], tp[1], tp[0], *carry_a, carry_a, + &x3, &x2, &x1, &x0); + bn_qwmulw_addqw_addw(np[3], np[2], np[1], np[0], w, + x3, x2, x1, x0, *carry_n, carry_n, + &tp[3], &tp[2], &tp[1], &tp[0]); + ap += 4; + np += 4; + tp += 4; + n_len -= 4; + } + while (n_len > 0) { + bn_mulw_addw_addw(ap[0], b, tp[0], *carry_a, carry_a, &x0); + bn_mulw_addw_addw(np[0], w, x0, *carry_n, carry_n, &tp[0]); + ap++; + np++; + tp++; + n_len--; + } +} + +/* + * bn_montgomery_multiply_words() computes r = aR * bR * R^-1 = abR for the + * given word arrays. The caller must ensure that rp, ap, bp and np are all + * n_len words in length, while tp must be n_len * 2 + 2 words in length. + */ +void +bn_montgomery_multiply_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, BN_ULONG *tp, BN_ULONG n0, int n_len) +{ + BN_ULONG a0, b, carry_a, carry_n, carry, mask, w; + int i; + + carry = 0; + + for (i = 0; i < n_len; i++) + tp[i] = 0; + + a0 = ap[0]; + + for (i = 0; i < n_len; i++) { + b = bp[i]; + + /* Compute new t[0] * n0, as we need it for this iteration. */ + w = (a0 * b + tp[0]) * n0; + + bn_montgomery_multiply_word(ap, b, np, tp, w, &carry_a, + &carry_n, n_len); + bn_addw_addw(carry_a, carry_n, carry, &carry, &tp[n_len]); + + tp++; + } + tp[n_len] = carry; + + /* + * The output is now in the range of [0, 2N). Attempt to reduce once by + * subtracting the modulus. If the reduction was necessary then the + * result is already in r, otherwise copy the value prior to reduction + * from tp. + */ + mask = bn_ct_ne_zero(tp[n_len]) - bn_sub_words(rp, tp, np, n_len); + + for (i = 0; i < n_len; i++) { + *rp = (*rp & ~mask) | (*tp & mask); + rp++; + tp++; + } +} + +/* + * bn_montgomery_multiply() computes r = aR * bR * R^-1 = abR for the given + * BIGNUMs. The caller must ensure that the modulus is two or more words in + * length and that a and b have the same number of words as the modulus. + */ +int +bn_montgomery_multiply(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + BIGNUM *t; + int ret = 0; + + BN_CTX_start(ctx); + + if (mctx->N.top <= 1 || a->top != mctx->N.top || b->top != mctx->N.top) + goto err; + if (!bn_wexpand(r, mctx->N.top)) + goto err; + + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + if (!bn_wexpand(t, mctx->N.top * 2 + 2)) + goto err; + + bn_montgomery_multiply_words(r->d, a->d, b->d, mctx->N.d, t->d, + mctx->n0[0], mctx->N.top); + + r->top = mctx->N.top; + bn_correct_top(r); + + BN_set_negative(r, a->neg ^ b->neg); + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +#ifndef OPENSSL_BN_ASM_MONT +int +bn_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + if (mctx->N.top <= 1 || a->top != mctx->N.top || b->top != mctx->N.top) + return bn_mod_mul_montgomery_simple(r, a, b, mctx, ctx); + + return bn_montgomery_multiply(r, a, b, mctx, ctx); +} +#else + +int +bn_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + if (mctx->N.top <= 1 || a->top != mctx->N.top || b->top != mctx->N.top) + return bn_mod_mul_montgomery_simple(r, a, b, mctx, ctx); + + /* + * Legacy bn_mul_mont() performs stack based allocation, without + * size limitation. Allowing a large size results in the stack + * being blown. + */ + if (mctx->N.top > (8 * 1024 / sizeof(BN_ULONG))) + return bn_montgomery_multiply(r, a, b, mctx, ctx); + + if (!bn_wexpand(r, mctx->N.top)) + return 0; + + /* + * Legacy bn_mul_mont() can indicate that we should "fallback" to + * another implementation. + */ + if (!bn_mul_mont(r->d, a->d, b->d, mctx->N.d, mctx->n0, mctx->N.top)) + return bn_montgomery_multiply(r, a, b, mctx, ctx); + + r->top = mctx->N.top; + bn_correct_top(r); + + BN_set_negative(r, a->neg ^ b->neg); + + return (1); +} +#endif + +int +BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + /* Compute r = aR * bR * R^-1 mod N = abR mod N */ + return bn_mod_mul_montgomery(r, a, b, mctx, ctx); +} +LCRYPTO_ALIAS(BN_mod_mul_montgomery); + +int +BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + /* Compute r = a * R * R * R^-1 mod N = aR mod N */ + return bn_mod_mul_montgomery(r, a, &mctx->RR, mctx, ctx); +} +LCRYPTO_ALIAS(BN_to_montgomery); + +/* + * bn_montgomery_reduce() performs Montgomery reduction, reducing the input + * from its Montgomery form aR to a, returning the result in r. Note that the + * input is mutated in the process of performing the reduction, destroying its + * original value. + */ +static int +bn_montgomery_reduce(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mctx) +{ + BIGNUM *n; + BN_ULONG *ap, *rp, n0, v, carry, mask; + int i, max, n_len; + + n = &mctx->N; + n_len = mctx->N.top; + + if (n_len == 0) { + BN_zero(r); + return 1; + } + + if (!bn_wexpand(r, n_len)) + return 0; + + /* + * Expand a to twice the length of the modulus, zero if necessary. + * XXX - make this a requirement of the caller. + */ + if ((max = 2 * n_len) < n_len) + return 0; + if (!bn_wexpand(a, max)) + return 0; + for (i = a->top; i < max; i++) + a->d[i] = 0; + + carry = 0; + n0 = mctx->n0[0]; + + /* Add multiples of the modulus, so that it becomes divisible by R. */ + for (i = 0; i < n_len; i++) { + v = bn_mul_add_words(&a->d[i], n->d, n_len, a->d[i] * n0); + bn_addw_addw(v, a->d[i + n_len], carry, &carry, + &a->d[i + n_len]); + } + + /* Divide by R (this is the equivalent of right shifting by n_len). */ + ap = &a->d[n_len]; + + /* + * The output is now in the range of [0, 2N). Attempt to reduce once by + * subtracting the modulus. If the reduction was necessary then the + * result is already in r, otherwise copy the value prior to reduction + * from the top half of a. + */ + mask = carry - bn_sub_words(r->d, ap, n->d, n_len); + + rp = r->d; + for (i = 0; i < n_len; i++) { + *rp = (*rp & ~mask) | (*ap & mask); + rp++; + ap++; + } + r->top = n_len; + + bn_correct_top(r); + + BN_set_negative(r, a->neg ^ n->neg); + + return 1; +} + +int +BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mctx, BN_CTX *ctx) +{ + BIGNUM *tmp; + int ret = 0; + + BN_CTX_start(ctx); + + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + if (!bn_copy(tmp, a)) + goto err; + if (!bn_montgomery_reduce(r, tmp, mctx)) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_from_montgomery); diff --git a/Libraries/libressl/crypto/bn/bn_mul.c b/Libraries/libressl/crypto/bn/bn_mul.c new file mode 100644 index 000000000..bdeb9b0fe --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_mul.c @@ -0,0 +1,370 @@ +/* $OpenBSD: bn_mul.c,v 1.39 2023/07/08 12:21:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include "bn_arch.h" +#include "bn_internal.h" +#include "bn_local.h" + +/* + * bn_mul_comba4() computes r[] = a[] * b[] using Comba multiplication + * (https://everything2.com/title/Comba+multiplication), where a and b are both + * four word arrays, producing an eight word array result. + */ +#ifndef HAVE_BN_MUL_COMBA4 +void +bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + BN_ULONG c0, c1, c2; + + bn_mulw_addtw(a[0], b[0], 0, 0, 0, &c2, &c1, &r[0]); + + bn_mulw_addtw(a[0], b[1], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[0], c2, c1, c0, &c2, &c1, &r[1]); + + bn_mulw_addtw(a[2], b[0], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[0], b[2], c2, c1, c0, &c2, &c1, &r[2]); + + bn_mulw_addtw(a[0], b[3], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[0], c2, c1, c0, &c2, &c1, &r[3]); + + bn_mulw_addtw(a[3], b[1], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[3], c2, c1, c0, &c2, &c1, &r[4]); + + bn_mulw_addtw(a[2], b[3], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[2], c2, c1, c0, &c2, &c1, &r[5]); + + bn_mulw_addtw(a[3], b[3], 0, c2, c1, &c2, &r[7], &r[6]); +} +#endif + +/* + * bn_mul_comba8() computes r[] = a[] * b[] using Comba multiplication + * (https://everything2.com/title/Comba+multiplication), where a and b are both + * eight word arrays, producing a 16 word array result. + */ +#ifndef HAVE_BN_MUL_COMBA8 +void +bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + BN_ULONG c0, c1, c2; + + bn_mulw_addtw(a[0], b[0], 0, 0, 0, &c2, &c1, &r[0]); + + bn_mulw_addtw(a[0], b[1], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[0], c2, c1, c0, &c2, &c1, &r[1]); + + bn_mulw_addtw(a[2], b[0], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[0], b[2], c2, c1, c0, &c2, &c1, &r[2]); + + bn_mulw_addtw(a[0], b[3], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[0], c2, c1, c0, &c2, &c1, &r[3]); + + bn_mulw_addtw(a[4], b[0], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[3], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[0], b[4], c2, c1, c0, &c2, &c1, &r[4]); + + bn_mulw_addtw(a[0], b[5], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[4], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[3], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[4], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[0], c2, c1, c0, &c2, &c1, &r[5]); + + bn_mulw_addtw(a[6], b[0], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[4], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[3], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[4], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[5], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[0], b[6], c2, c1, c0, &c2, &c1, &r[6]); + + bn_mulw_addtw(a[0], b[7], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[6], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[5], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[4], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[4], b[3], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[6], b[1], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[7], b[0], c2, c1, c0, &c2, &c1, &r[7]); + + bn_mulw_addtw(a[7], b[1], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[6], b[2], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[3], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[4], b[4], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[5], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[2], b[6], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[1], b[7], c2, c1, c0, &c2, &c1, &r[8]); + + bn_mulw_addtw(a[2], b[7], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[6], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[4], b[5], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[4], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[6], b[3], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[7], b[2], c2, c1, c0, &c2, &c1, &r[9]); + + bn_mulw_addtw(a[7], b[3], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[6], b[4], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[5], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[4], b[6], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[3], b[7], c2, c1, c0, &c2, &c1, &r[10]); + + bn_mulw_addtw(a[4], b[7], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[6], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[6], b[5], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[7], b[4], c2, c1, c0, &c2, &c1, &r[11]); + + bn_mulw_addtw(a[7], b[5], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[6], b[6], c2, c1, c0, &c2, &c1, &c0); + bn_mulw_addtw(a[5], b[7], c2, c1, c0, &c2, &c1, &r[12]); + + bn_mulw_addtw(a[6], b[7], 0, c2, c1, &c2, &c1, &c0); + bn_mulw_addtw(a[7], b[6], c2, c1, c0, &c2, &c1, &r[13]); + + bn_mulw_addtw(a[7], b[7], 0, c2, c1, &c2, &r[15], &r[14]); +} +#endif + +/* + * bn_mul_words() computes (carry:r[i]) = a[i] * w + carry, where a is an array + * of words and w is a single word. This should really be called bn_mulw_words() + * since only one input is an array. This is used as a step in the multiplication + * of word arrays. + */ +#ifndef HAVE_BN_MUL_WORDS +BN_ULONG +bn_mul_words(BN_ULONG *r, const BN_ULONG *a, int num, BN_ULONG w) +{ + BN_ULONG carry = 0; + + assert(num >= 0); + if (num <= 0) + return 0; + + while (num & ~3) { + bn_qwmulw_addw(a[3], a[2], a[1], a[0], w, carry, &carry, + &r[3], &r[2], &r[1], &r[0]); + a += 4; + r += 4; + num -= 4; + } + while (num) { + bn_mulw_addw(a[0], w, carry, &carry, &r[0]); + a++; + r++; + num--; + } + return carry; +} +#endif + +/* + * bn_mul_add_words() computes (carry:r[i]) = a[i] * w + r[i] + carry, where + * a is an array of words and w is a single word. This should really be called + * bn_mulw_add_words() since only one input is an array. This is used as a step + * in the multiplication of word arrays. + */ +#ifndef HAVE_BN_MUL_ADD_WORDS +BN_ULONG +bn_mul_add_words(BN_ULONG *r, const BN_ULONG *a, int num, BN_ULONG w) +{ + BN_ULONG carry = 0; + + assert(num >= 0); + if (num <= 0) + return 0; + + while (num & ~3) { + bn_qwmulw_addqw_addw(a[3], a[2], a[1], a[0], w, + r[3], r[2], r[1], r[0], carry, &carry, + &r[3], &r[2], &r[1], &r[0]); + a += 4; + r += 4; + num -= 4; + } + while (num) { + bn_mulw_addw_addw(a[0], w, r[0], carry, &carry, &r[0]); + a++; + r++; + num--; + } + + return carry; +} +#endif + +void +bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) +{ + BN_ULONG *rr; + + + if (na < nb) { + int itmp; + BN_ULONG *ltmp; + + itmp = na; + na = nb; + nb = itmp; + ltmp = a; + a = b; + b = ltmp; + + } + rr = &(r[na]); + if (nb <= 0) { + (void)bn_mul_words(r, a, na, 0); + return; + } else + rr[0] = bn_mul_words(r, a, na, b[0]); + + for (;;) { + if (--nb <= 0) + return; + rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]); + if (--nb <= 0) + return; + rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]); + if (--nb <= 0) + return; + rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]); + if (--nb <= 0) + return; + rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]); + rr += 4; + r += 4; + b += 4; + } +} + + +#ifndef HAVE_BN_MUL +int +bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int rn, BN_CTX *ctx) +{ + bn_mul_normal(r->d, a->d, a->top, b->d, b->top); + + return 1; +} + +#endif /* HAVE_BN_MUL */ + +int +BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + BIGNUM *rr; + int rn; + int ret = 0; + + BN_CTX_start(ctx); + + if (BN_is_zero(a) || BN_is_zero(b)) { + BN_zero(r); + goto done; + } + + rr = r; + if (rr == a || rr == b) + rr = BN_CTX_get(ctx); + if (rr == NULL) + goto err; + + rn = a->top + b->top; + if (rn < a->top) + goto err; + if (!bn_wexpand(rr, rn)) + goto err; + + if (a->top == 4 && b->top == 4) { + bn_mul_comba4(rr->d, a->d, b->d); + } else if (a->top == 8 && b->top == 8) { + bn_mul_comba8(rr->d, a->d, b->d); + } else { + if (!bn_mul(rr, a, b, rn, ctx)) + goto err; + } + + rr->top = rn; + bn_correct_top(rr); + + BN_set_negative(rr, a->neg ^ b->neg); + + if (!bn_copy(r, rr)) + goto err; + done: + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_mul); diff --git a/Libraries/libressl/crypto/bn/bn_prime.c b/Libraries/libressl/crypto/bn/bn_prime.c new file mode 100644 index 000000000..5a4aa50bf --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_prime.c @@ -0,0 +1,423 @@ +/* $OpenBSD: bn_prime.c,v 1.34 2023/07/20 06:26:27 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include "bn_local.h" + +/* The quick sieve algorithm approach to weeding out primes is + * Philip Zimmermann's, as implemented in PGP. I have had a read of + * his comments and implemented my own version. + */ +#include "bn_prime.h" + +static int probable_prime(BIGNUM *rnd, int bits); +static int probable_prime_dh(BIGNUM *rnd, int bits, + const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); +static int probable_prime_dh_safe(BIGNUM *rnd, int bits, + const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); + +int +BN_GENCB_call(BN_GENCB *cb, int a, int b) +{ + /* No callback means continue */ + if (!cb) + return 1; + switch (cb->ver) { + case 1: + /* Deprecated-style callbacks */ + if (!cb->cb.cb_1) + return 1; + cb->cb.cb_1(a, b, cb->arg); + return 1; + case 2: + /* New-style callbacks */ + return cb->cb.cb_2(a, b, cb); + default: + break; + } + /* Unrecognised callback type */ + return 0; +} +LCRYPTO_ALIAS(BN_GENCB_call); + +int +BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb) +{ + BN_CTX *ctx; + BIGNUM *p; + int is_prime; + int loops = 0; + int found = 0; + + if (bits < 2 || (bits == 2 && safe)) { + /* + * There are no prime numbers smaller than 2, and the smallest + * safe prime (7) spans three bits. + */ + BNerror(BN_R_BITS_TOO_SMALL); + return 0; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + + loop: + /* Make a random number and set the top and bottom bits. */ + if (add == NULL) { + if (!probable_prime(ret, bits)) + goto err; + } else { + if (safe) { + if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) + goto err; + } else { + if (!probable_prime_dh(ret, bits, add, rem, ctx)) + goto err; + } + } + + if (!BN_GENCB_call(cb, 0, loops++)) + goto err; + + if (!safe) { + if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1)) + goto err; + if (!is_prime) + goto loop; + } else { + if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1)) + goto err; + if (!is_prime) + goto loop; + + /* + * For safe prime generation, check that p = (ret-1)/2 is prime. + * Since this prime has >= 3 bits, it is odd, and we can simply + * divide by 2. + */ + if (!BN_rshift1(p, ret)) + goto err; + + if (!bn_is_prime_bpsw(&is_prime, p, ctx, 1)) + goto err; + if (!is_prime) + goto loop; + + if (!BN_GENCB_call(cb, 2, loops - 1)) + goto err; + } + + found = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return found; +} +LCRYPTO_ALIAS(BN_generate_prime_ex); + +int +BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) +{ + return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); +} +LCRYPTO_ALIAS(BN_is_prime_ex); + +#define BN_PRIME_MAXIMUM_BITS (32 * 1024) + +int +BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, + int do_trial_division, BN_GENCB *cb) +{ + int is_prime; + + if (checks < 0) + return -1; + + /* + * Prime numbers this large do not appear in everyday cryptography + * and checking such numbers for primality is very expensive. + */ + if (BN_num_bits(a) > BN_PRIME_MAXIMUM_BITS) { + BNerror(BN_R_BIGNUM_TOO_LONG); + return -1; + } + + if (checks == BN_prime_checks) + checks = BN_prime_checks_for_size(BN_num_bits(a)); + + /* XXX - tickle BN_GENCB in bn_is_prime_bpsw(). */ + if (!bn_is_prime_bpsw(&is_prime, a, ctx_passed, checks)) + return -1; + + return is_prime; +} +LCRYPTO_ALIAS(BN_is_prime_fasttest_ex); + +static int +probable_prime(BIGNUM *rnd, int bits) +{ + int i; + BN_ULONG mods[NUMPRIMES]; + BN_ULONG delta, maxdelta; + +again: + if (!BN_rand(rnd, bits, 1, 1)) + return (0); + /* we now have a random number 'rand' to test. */ + for (i = 1; i < NUMPRIMES; i++) { + BN_ULONG mod = BN_mod_word(rnd, primes[i]); + if (mod == (BN_ULONG)-1) + return (0); + mods[i] = mod; + } + maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + delta = 0; +loop: + for (i = 1; i < NUMPRIMES; i++) { + /* check that rnd is not a prime and also + * that gcd(rnd-1,primes) == 1 (except for 2) */ + if (((mods[i] + delta) % primes[i]) <= 1) { + delta += 2; + if (delta > maxdelta) + goto again; + goto loop; + } + } + if (!BN_add_word(rnd, delta)) + return (0); + return (1); +} + +static int +probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *t1; + + BN_CTX_start(ctx); + if ((t1 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_rand(rnd, bits, 0, 1)) + goto err; + + /* we need ((rnd-rem) % add) == 0 */ + + if (!BN_mod_ct(t1, rnd, add, ctx)) + goto err; + if (!BN_sub(rnd, rnd, t1)) + goto err; + if (rem == NULL) { + if (!BN_add_word(rnd, 1)) + goto err; + } else { + if (!BN_add(rnd, rnd, rem)) + goto err; + } + + /* we now have a random number 'rand' to test. */ + +loop: + for (i = 1; i < NUMPRIMES; i++) { + /* check that rnd is a prime */ + BN_LONG mod = BN_mod_word(rnd, primes[i]); + if (mod == (BN_ULONG)-1) + goto err; + if (mod <= 1) { + if (!BN_add(rnd, rnd, add)) + goto err; + goto loop; + } + } + ret = 1; + +err: + BN_CTX_end(ctx); + return (ret); +} + +static int +probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, + const BIGNUM *rem, BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *t1, *qadd, *q; + + bits--; + BN_CTX_start(ctx); + if ((t1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((q = BN_CTX_get(ctx)) == NULL) + goto err; + if ((qadd = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_rshift1(qadd, padd)) + goto err; + + if (!BN_rand(q, bits, 0, 1)) + goto err; + + /* we need ((rnd-rem) % add) == 0 */ + if (!BN_mod_ct(t1, q,qadd, ctx)) + goto err; + if (!BN_sub(q, q, t1)) + goto err; + if (rem == NULL) { + if (!BN_add_word(q, 1)) + goto err; + } else { + if (!BN_rshift1(t1, rem)) + goto err; + if (!BN_add(q, q, t1)) + goto err; + } + + /* we now have a random number 'rand' to test. */ + if (!BN_lshift1(p, q)) + goto err; + if (!BN_add_word(p, 1)) + goto err; + +loop: + for (i = 1; i < NUMPRIMES; i++) { + /* check that p and q are prime */ + /* check that for p and q + * gcd(p-1,primes) == 1 (except for 2) */ + BN_ULONG pmod = BN_mod_word(p, primes[i]); + BN_ULONG qmod = BN_mod_word(q, primes[i]); + if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1) + goto err; + if (pmod == 0 || qmod == 0) { + if (!BN_add(p, p, padd)) + goto err; + if (!BN_add(q, q, qadd)) + goto err; + goto loop; + } + } + ret = 1; + +err: + BN_CTX_end(ctx); + return (ret); +} diff --git a/Libraries/libressl/crypto/bn/bn_prime.h b/Libraries/libressl/crypto/bn/bn_prime.h new file mode 100644 index 000000000..4ea2d4794 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_prime.h @@ -0,0 +1,14 @@ +/* $OpenBSD: bn_prime.h,v 1.9 2022/11/10 10:24:50 tb Exp $ */ +/* + * Public domain. + */ + +#include + +__BEGIN_HIDDEN_DECLS + +#define NUMPRIMES 2048 + +extern const uint16_t primes[NUMPRIMES]; + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/bn/bn_primitives.c b/Libraries/libressl/crypto/bn/bn_primitives.c new file mode 100644 index 000000000..66427a904 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_primitives.c @@ -0,0 +1,65 @@ +/* $OpenBSD: bn_primitives.c,v 1.2 2023/06/21 07:48:41 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bn_arch.h" +#include "bn_internal.h" +#include "bn_local.h" + +#ifndef HAVE_BN_CLZW +#ifndef HAVE_BN_WORD_CLZ +int +bn_word_clz(BN_ULONG w) +{ + BN_ULONG bits, mask, shift; + + bits = shift = BN_BITS2; + mask = 0; + + while ((shift >>= 1) != 0) { + bits += (shift & mask) - (shift & ~mask); + mask = bn_ct_ne_zero_mask(w >> bits); + } + bits += 1 & mask; + + bits -= bn_ct_eq_zero(w); + + return BN_BITS2 - bits; +} +#endif +#endif + +#ifndef HAVE_BN_BITSIZE +int +bn_bitsize(const BIGNUM *bn) +{ + BN_ULONG n = 0, x = 0; + BN_ULONG mask, w; + int i = 0; + + while (i < bn->top) { + w = bn->d[i]; + mask = bn_ct_ne_zero_mask(w); + n = ((BN_ULONG)i & mask) | (n & ~mask); + x = (w & mask) | (x & ~mask); + i++; + } + + return (n + 1) * BN_BITS2 - bn_clzw(x); +} +#endif diff --git a/Libraries/libressl/crypto/bn/bn_print.c b/Libraries/libressl/crypto/bn/bn_print.c new file mode 100644 index 000000000..e7678f7a9 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_print.c @@ -0,0 +1,190 @@ +/* $OpenBSD: bn_print.c,v 1.46 2023/07/22 17:14:08 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "bn_local.h" +#include "bytestring.h" + +static int +bn_print_zero(BIO *bio, const BIGNUM *bn) +{ + if (!BN_is_zero(bn)) + return 0; + if (BIO_printf(bio, " 0\n") <= 0) + return 0; + return 1; +} + +static int +bn_print_word(BIO *bio, const BIGNUM *bn) +{ + unsigned long long word; + const char *neg = ""; + + if (BN_is_zero(bn) || BN_num_bytes(bn) > BN_BYTES) + return 0; + + if (BN_is_negative(bn)) + neg = "-"; + + word = BN_get_word(bn); + if (BIO_printf(bio, " %s%llu (%s0x%llx)\n", neg, word, neg, word) <= 0) + return 0; + + return 1; +} + +static int +bn_print_bignum(BIO *bio, const BIGNUM *bn, int indent) +{ + CBS cbs; + char *hex = NULL; + size_t hex_len = 0; + size_t octets = 0; + uint8_t hi, lo; + const char *sep = ":"; + int ret = 0; + + if (BN_num_bytes(bn) <= BN_BYTES) + goto err; + + /* Secondary indent is 4 spaces, capped at 128. */ + if (indent > 124) + indent = 124; + indent += 4; + if (indent < 0) + indent = 0; + + if (!bn_bn2hex_nosign(bn, &hex, &hex_len)) + goto err; + + CBS_init(&cbs, hex, hex_len); + + if (BN_is_negative(bn)) { + if (BIO_printf(bio, " (Negative)") <= 0) + goto err; + } + + while (CBS_len(&cbs) > 0) { + if (!CBS_get_u8(&cbs, &hi)) + goto err; + if (!CBS_get_u8(&cbs, &lo)) + goto err; + if (octets++ % 15 == 0) { + if (BIO_printf(bio, "\n%*s", indent, "") <= 0) + goto err; + } + /* First nibble has the high bit set. Insert leading 0 octet. */ + if (octets == 1 && hi >= '8') { + if (BIO_printf(bio, "00:") <= 0) + goto err; + octets++; + } + if (CBS_len(&cbs) == 0) + sep = ""; + if (BIO_printf(bio, "%c%c%s", tolower(hi), tolower(lo), sep) <= 0) + goto err; + } + + if (BIO_printf(bio, "\n") <= 0) + goto err; + + ret = 1; + + err: + freezero(hex, hex_len); + + return ret; +} + +int +bn_printf(BIO *bio, const BIGNUM *bn, int indent, const char *fmt, ...) +{ + va_list ap; + int rv; + + if (bn == NULL) + return 1; + + if (!BIO_indent(bio, indent, 128)) + return 0; + + va_start(ap, fmt); + rv = BIO_vprintf(bio, fmt, ap); + va_end(ap); + if (rv < 0) + return 0; + + if (BN_is_zero(bn)) + return bn_print_zero(bio, bn); + + if (BN_num_bytes(bn) <= BN_BYTES) + return bn_print_word(bio, bn); + + return bn_print_bignum(bio, bn, indent); +} + +int +BN_print(BIO *bio, const BIGNUM *bn) +{ + char *hex = NULL; + size_t hex_len = 0; + int ret = 0; + + if (!bn_bn2hex_nibbles(bn, &hex, &hex_len)) + goto err; + if (BIO_printf(bio, "%s", hex) <= 0) + goto err; + + ret = 1; + + err: + freezero(hex, hex_len); + + return ret; +} +LCRYPTO_ALIAS(BN_print); + +int +BN_print_fp(FILE *fp, const BIGNUM *bn) +{ + char *hex = NULL; + size_t hex_len = 0; + int ret = 0; + + if (!bn_bn2hex_nibbles(bn, &hex, &hex_len)) + goto err; + if (fprintf(fp, "%s", hex) < 0) + goto err; + + ret = 1; + + err: + freezero(hex, hex_len); + + return ret; +} +LCRYPTO_ALIAS(BN_print_fp); diff --git a/Libraries/libressl/crypto/bn/bn_rand.c b/Libraries/libressl/crypto/bn/bn_rand.c new file mode 100644 index 000000000..a5b163c82 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_rand.c @@ -0,0 +1,335 @@ +/* $OpenBSD: bn_rand.c,v 1.29 2023/08/03 18:53:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include + +#include "bn_local.h" + +static int +bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) +{ + unsigned char *buf = NULL; + int ret = 0, bit, bytes, mask; + + if (rnd == NULL) { + BNerror(ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + + if (bits < 0 || (bits == 1 && top > 0)) { + BNerror(BN_R_BITS_TOO_SMALL); + return (0); + } + + if (bits == 0) { + BN_zero(rnd); + return (1); + } + + bytes = (bits + 7) / 8; + bit = (bits - 1) % 8; + mask = 0xff << (bit + 1); + + buf = malloc(bytes); + if (buf == NULL) { + BNerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* make a random number and set the top and bottom bits */ + arc4random_buf(buf, bytes); + +#if 1 + if (pseudorand == 2) { + /* generate patterns that are more likely to trigger BN + library bugs */ + int i; + unsigned char c; + + for (i = 0; i < bytes; i++) { + arc4random_buf(&c, 1); + if (c >= 128 && i > 0) + buf[i] = buf[i - 1]; + else if (c < 42) + buf[i] = 0; + else if (c < 84) + buf[i] = 255; + } + } +#endif + + if (top > 0) { + if (bit == 0) { + buf[0] = 1; + buf[1] |= 0x80; + } else { + buf[0] |= (3 << (bit - 1)); + } + } + if (top == 0) + buf[0] |= (1 << bit); + buf[0] &= ~mask; + if (bottom) /* set bottom bit if requested */ + buf[bytes - 1] |= 1; + if (BN_bin2bn(buf, bytes, rnd) == NULL) + goto err; + ret = 1; + +err: + freezero(buf, bytes); + return (ret); +} + +int +BN_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(0, rnd, bits, top, bottom); +} +LCRYPTO_ALIAS(BN_rand); + +int +BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(1, rnd, bits, top, bottom); +} +LCRYPTO_ALIAS(BN_pseudo_rand); + +#if 1 +int +BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(2, rnd, bits, top, bottom); +} +#endif + + +/* random number r: 0 <= r < range */ +static int +bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range) +{ + int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; + int n; + int count = 100; + + if (range->neg || BN_is_zero(range)) { + BNerror(BN_R_INVALID_RANGE); + return 0; + } + + n = BN_num_bits(range); /* n > 0 */ + + /* BN_is_bit_set(range, n - 1) always holds */ + + if (n == 1) + BN_zero(r); + else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { + /* range = 100..._2, + * so 3*range (= 11..._2) is exactly one bit longer than range */ + do { + if (!bn_rand(r, n + 1, -1, 0)) + return 0; + /* If r < 3*range, use r := r MOD range + * (which is either r, r - range, or r - 2*range). + * Otherwise, iterate once more. + * Since 3*range = 11..._2, each iteration succeeds with + * probability >= .75. */ + if (BN_cmp(r, range) >= 0) { + if (!BN_sub(r, r, range)) + return 0; + if (BN_cmp(r, range) >= 0) + if (!BN_sub(r, r, range)) + return 0; + } + + if (!--count) { + BNerror(BN_R_TOO_MANY_ITERATIONS); + return 0; + } + + } while (BN_cmp(r, range) >= 0); + } else { + do { + /* range = 11..._2 or range = 101..._2 */ + if (!bn_rand(r, n, -1, 0)) + return 0; + + if (!--count) { + BNerror(BN_R_TOO_MANY_ITERATIONS); + return 0; + } + } while (BN_cmp(r, range) >= 0); + } + + return 1; +} + +int +BN_rand_range(BIGNUM *r, const BIGNUM *range) +{ + return bn_rand_range(0, r, range); +} +LCRYPTO_ALIAS(BN_rand_range); + +int +bn_rand_in_range(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc) +{ + BIGNUM *len; + int ret = 0; + + if ((len = BN_new()) == NULL) + goto err; + if (!BN_sub(len, upper_exc, lower_inc)) + goto err; + if (!BN_rand_range(rnd, len)) + goto err; + if (!BN_add(rnd, rnd, lower_inc)) + goto err; + + ret = 1; + + err: + BN_free(len); + + return ret; +} + +int +bn_rand_interval(BIGNUM *rnd, BN_ULONG lower_word, const BIGNUM *upper_exc) +{ + BIGNUM *lower_inc = NULL; + int ret = 0; + + if ((lower_inc = BN_new()) == NULL) + goto err; + if (!BN_set_word(lower_inc, lower_word)) + goto err; + if (!bn_rand_in_range(rnd, lower_inc, upper_exc)) + goto err; + + ret = 1; + + err: + BN_free(lower_inc); + + return ret; +} + +int +BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) +{ + return bn_rand_range(1, r, range); +} +LCRYPTO_ALIAS(BN_pseudo_rand_range); diff --git a/Libraries/libressl/crypto/bn/bn_recp.c b/Libraries/libressl/crypto/bn/bn_recp.c new file mode 100644 index 000000000..35390e30d --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_recp.c @@ -0,0 +1,260 @@ +/* $OpenBSD: bn_recp.c,v 1.19 2023/03/27 10:25:02 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include "bn_local.h" + +void +BN_RECP_CTX_init(BN_RECP_CTX *recp) +{ + BN_init(&(recp->N)); + BN_init(&(recp->Nr)); + recp->num_bits = 0; + recp->flags = 0; +} + +BN_RECP_CTX * +BN_RECP_CTX_new(void) +{ + BN_RECP_CTX *ret; + + if ((ret = malloc(sizeof(BN_RECP_CTX))) == NULL) + return (NULL); + + BN_RECP_CTX_init(ret); + ret->flags = BN_FLG_MALLOCED; + return (ret); +} + +void +BN_RECP_CTX_free(BN_RECP_CTX *recp) +{ + if (recp == NULL) + return; + + BN_free(&(recp->N)); + BN_free(&(recp->Nr)); + if (recp->flags & BN_FLG_MALLOCED) + free(recp); +} + +int +BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) +{ + if (!bn_copy(&(recp->N), d)) + return 0; + BN_zero(&(recp->Nr)); + recp->num_bits = BN_num_bits(d); + recp->shift = 0; + return (1); +} + +int +BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *a; + const BIGNUM *ca; + + BN_CTX_start(ctx); + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if (y != NULL) { + if (x == y) { + if (!BN_sqr(a, x, ctx)) + goto err; + } else { + if (!BN_mul(a, x, y, ctx)) + goto err; + } + ca = a; + } else + ca = x; /* Just do the mod */ + + ret = BN_div_recp(NULL, r, ca, recp, ctx); + +err: + BN_CTX_end(ctx); + return (ret); +} + +int +BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp, + BN_CTX *ctx) +{ + int i, j, ret = 0; + BIGNUM *a, *b, *d, *r; + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (dv != NULL) + d = dv; + else + d = BN_CTX_get(ctx); + if (rem != NULL) + r = rem; + else + r = BN_CTX_get(ctx); + if (a == NULL || b == NULL || d == NULL || r == NULL) + goto err; + + if (BN_ucmp(m, &(recp->N)) < 0) { + BN_zero(d); + if (!bn_copy(r, m)) { + BN_CTX_end(ctx); + return 0; + } + BN_CTX_end(ctx); + return (1); + } + + /* We want the remainder + * Given input of ABCDEF / ab + * we need multiply ABCDEF by 3 digests of the reciprocal of ab + * + */ + + /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */ + i = BN_num_bits(m); + j = recp->num_bits << 1; + if (j > i) + i = j; + + /* Nr := round(2^i / N) */ + if (i != recp->shift) + recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx); + + /* BN_reciprocal returns i, or -1 for an error */ + if (recp->shift == -1) + goto err; + + /* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))| + * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))| + * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)| + * = |m/N| + */ + if (!BN_rshift(a, m, recp->num_bits)) + goto err; + if (!BN_mul(b, a,&(recp->Nr), ctx)) + goto err; + if (!BN_rshift(d, b, i - recp->num_bits)) + goto err; + d->neg = 0; + + if (!BN_mul(b, &(recp->N), d, ctx)) + goto err; + if (!BN_usub(r, m, b)) + goto err; + r->neg = 0; + +#if 1 + j = 0; + while (BN_ucmp(r, &(recp->N)) >= 0) { + if (j++ > 2) { + BNerror(BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_usub(r, r, &(recp->N))) + goto err; + if (!BN_add_word(d, 1)) + goto err; + } +#endif + + BN_set_negative(r, m->neg); + BN_set_negative(d, m->neg ^ recp->N.neg); + + ret = 1; + +err: + BN_CTX_end(ctx); + return (ret); +} + +/* len is the expected size of the result + * We actually calculate with an extra word of precision, so + * we can do faster division if the remainder is not required. + */ +/* r := 2^len / m */ +int +BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) +{ + int ret = -1; + BIGNUM *t; + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_set_bit(t, len)) + goto err; + + if (!BN_div_ct(r, NULL, t,m, ctx)) + goto err; + + ret = len; + +err: + BN_CTX_end(ctx); + return (ret); +} diff --git a/Libraries/libressl/crypto/bn/bn_shift.c b/Libraries/libressl/crypto/bn/bn_shift.c new file mode 100644 index 000000000..12edc7c0a --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_shift.c @@ -0,0 +1,175 @@ +/* $OpenBSD: bn_shift.c,v 1.22 2023/07/08 12:21:58 beck Exp $ */ +/* + * Copyright (c) 2022, 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "bn_local.h" + +static inline int +bn_lshift(BIGNUM *r, const BIGNUM *a, int n) +{ + size_t count, shift_bits, shift_words; + size_t lshift, rshift; + ssize_t rstride; + BN_ULONG *dst, *src; + + if (n < 0) { + BNerror(BN_R_INVALID_LENGTH); + return 0; + } + shift_bits = n; + + /* + * Left bit shift, potentially across word boundaries. + * + * When shift is not an exact multiple of BN_BITS2, the bottom bits of + * the previous word need to be right shifted and combined with the left + * shifted bits using bitwise OR. If shift is an exact multiple of + * BN_BITS2, the source for the left and right shifts are the same + * and the shifts become zero bits (which is effectively a memmove). + */ + shift_words = shift_bits / BN_BITS2; + lshift = shift_bits % BN_BITS2; + rshift = (BN_BITS2 - lshift) % BN_BITS2; + rstride = 0 - (lshift + rshift) / BN_BITS2; + + if (a->top < 1) { + BN_zero(r); + return 1; + } + + count = a->top + shift_words + 1; + + if (count < shift_words) + return 0; + + if (!bn_wexpand(r, count)) + return 0; + + src = a->d + a->top - 1; + dst = r->d + a->top + shift_words; + + /* Handle right shift for top most word. */ + *dst = (*src >> rshift) & rstride; + dst--; + + /* Handle left shift and right shift for remaining words. */ + while (src > a->d) { + *dst = *src << lshift | src[rstride] >> rshift; + src--; + dst--; + } + *dst = *src << lshift; + + /* Zero any additional words resulting from the left shift. */ + while (dst > r->d) { + dst--; + *dst = 0; + } + + r->top = count; + bn_correct_top(r); + + BN_set_negative(r, a->neg); + + return 1; +} + +static inline int +bn_rshift(BIGNUM *r, const BIGNUM *a, int n) +{ + size_t count, shift_bits, shift_words; + size_t lshift, rshift; + ssize_t lstride; + BN_ULONG *dst, *src; + size_t i; + + if (n < 0) { + BNerror(BN_R_INVALID_LENGTH); + return 0; + } + shift_bits = n; + + /* + * Right bit shift, potentially across word boundaries. + * + * When shift is not an exact multiple of BN_BITS2, the top bits of + * the next word need to be left shifted and combined with the right + * shifted bits using bitwise OR. If shift is an exact multiple of + * BN_BITS2, the source for the left and right shifts are the same + * and the shifts become zero (which is effectively a memmove). + */ + shift_words = shift_bits / BN_BITS2; + rshift = shift_bits % BN_BITS2; + lshift = (BN_BITS2 - rshift) % BN_BITS2; + lstride = (lshift + rshift) / BN_BITS2; + + if (a->top <= shift_words) { + BN_zero(r); + return 1; + } + count = a->top - shift_words; + + if (!bn_wexpand(r, count)) + return 0; + + src = a->d + shift_words; + dst = r->d; + + for (i = 1; i < count; i++) { + *dst = src[lstride] << lshift | *src >> rshift; + src++; + dst++; + } + *dst = *src >> rshift; + + r->top = count; + bn_correct_top(r); + + BN_set_negative(r, a->neg); + + return 1; +} + +int +BN_lshift1(BIGNUM *r, const BIGNUM *a) +{ + return bn_lshift(r, a, 1); +} +LCRYPTO_ALIAS(BN_lshift1); + +int +BN_lshift(BIGNUM *r, const BIGNUM *a, int n) +{ + return bn_lshift(r, a, n); +} +LCRYPTO_ALIAS(BN_lshift); + +int +BN_rshift1(BIGNUM *r, const BIGNUM *a) +{ + return bn_rshift(r, a, 1); +} +LCRYPTO_ALIAS(BN_rshift1); + +int +BN_rshift(BIGNUM *r, const BIGNUM *a, int n) +{ + return bn_rshift(r, a, n); +} +LCRYPTO_ALIAS(BN_rshift); diff --git a/Libraries/libressl/crypto/bn/bn_small_primes.c b/Libraries/libressl/crypto/bn/bn_small_primes.c new file mode 100644 index 000000000..bfb7903a5 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_small_primes.c @@ -0,0 +1,265 @@ +/* $OpenBSD: bn_small_primes.c,v 1.1 2022/11/09 22:52:51 tb Exp $ */ +/* + * Public domain, generated by bn_prime.pl. + */ + +#include "bn_prime.h" + +const uint16_t primes[NUMPRIMES] = { + 2, 3, 5, 7, 11, 13, 17, 19, + 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, + 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, + 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, + 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, + 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, + 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, + 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, + 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, + 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, + 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, + 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, + 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, + 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, + 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, + 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, + 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, + 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, + 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, + 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, + 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, + 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, + 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, + 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, + 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, + 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, + 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, + 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, + 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, + 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, + 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, + 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, + 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, + 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, + 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, + 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, + 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, + 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, + 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, + 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, + 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, + 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, + 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, + 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, + 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, + 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, + 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, + 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, + 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, + 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, + 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, + 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, + 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, + 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, + 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, + 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, + 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, + 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, + 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, + 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, + 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, + 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, + 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, + 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, + 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, + 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, + 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, + 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, + 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, + 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, + 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, + 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, + 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, + 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, + 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, + 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, + 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, + 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, + 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, + 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, + 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, + 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, + 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, + 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, + 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, + 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, + 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, + 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, + 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, + 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, + 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, + 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, + 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, + 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, + 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, + 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, + 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, + 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, + 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, + 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, + 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, + 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, + 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, + 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, + 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, + 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, + 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, + 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, + 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, + 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, + 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, + 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, + 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, + 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, + 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, + 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, + 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, + 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, + 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, + 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, + 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, + 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, + 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, + 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, + 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, + 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, + 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, + 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, + 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, + 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, + 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, + 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, + 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, + 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, + 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, + 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, + 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, + 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, + 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, + 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, + 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, + 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, + 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, + 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, + 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, + 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, + 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, + 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, + 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, + 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, + 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, + 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, + 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, + 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, + 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, + 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, + 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, + 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, + 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, + 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, + 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, + 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, + 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, + 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, + 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, + 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, + 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, + 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, + 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, + 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, + 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, + 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, + 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, + 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, + 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, + 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, + 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, + 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, + 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, + 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, + 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, + 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, + 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, + 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, + 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, + 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, + 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, + 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, + 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, + 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, + 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, + 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, + 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, + 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, + 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, + 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, + 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, + 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, + 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, + 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, + 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, + 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, + 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, + 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, + 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, + 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, + 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, + 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, + 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, + 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, + 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, + 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, + 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, + 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, + 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, + 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, + 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, + 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, + 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, + 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, + 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, + 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, + 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, + 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, + 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, + 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, + 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, + 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, + 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, + 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, + 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, + 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, +}; diff --git a/Libraries/libressl/crypto/bn/bn_sqr.c b/Libraries/libressl/crypto/bn/bn_sqr.c new file mode 100644 index 000000000..0dbccbf85 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_sqr.c @@ -0,0 +1,305 @@ +/* $OpenBSD: bn_sqr.c,v 1.36 2023/07/08 12:21:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "bn_arch.h" +#include "bn_local.h" +#include "bn_internal.h" + +int bn_sqr(BIGNUM *r, const BIGNUM *a, int max, BN_CTX *ctx); + +/* + * bn_sqr_comba4() computes r[] = a[] * a[] using Comba multiplication + * (https://everything2.com/title/Comba+multiplication), where a is a + * four word array, producing an eight word array result. + */ +#ifndef HAVE_BN_SQR_COMBA4 +void +bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG c2, c1, c0; + + bn_mulw_addtw(a[0], a[0], 0, 0, 0, &c2, &c1, &r[0]); + + bn_mul2_mulw_addtw(a[1], a[0], 0, c2, c1, &c2, &c1, &r[1]); + + bn_mulw_addtw(a[1], a[1], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[2], a[0], c2, c1, c0, &c2, &c1, &r[2]); + + bn_mul2_mulw_addtw(a[3], a[0], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[2], a[1], c2, c1, c0, &c2, &c1, &r[3]); + + bn_mulw_addtw(a[2], a[2], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[3], a[1], c2, c1, c0, &c2, &c1, &r[4]); + + bn_mul2_mulw_addtw(a[3], a[2], 0, c2, c1, &c2, &c1, &r[5]); + + bn_mulw_addtw(a[3], a[3], 0, c2, c1, &c2, &r[7], &r[6]); +} +#endif + +/* + * bn_sqr_comba8() computes r[] = a[] * a[] using Comba multiplication + * (https://everything2.com/title/Comba+multiplication), where a is an + * eight word array, producing an 16 word array result. + */ +#ifndef HAVE_BN_SQR_COMBA8 +void +bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG c2, c1, c0; + + bn_mulw_addtw(a[0], a[0], 0, 0, 0, &c2, &c1, &r[0]); + + bn_mul2_mulw_addtw(a[1], a[0], 0, c2, c1, &c2, &c1, &r[1]); + + bn_mulw_addtw(a[1], a[1], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[2], a[0], c2, c1, c0, &c2, &c1, &r[2]); + + bn_mul2_mulw_addtw(a[3], a[0], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[2], a[1], c2, c1, c0, &c2, &c1, &r[3]); + + bn_mulw_addtw(a[2], a[2], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[3], a[1], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[4], a[0], c2, c1, c0, &c2, &c1, &r[4]); + + bn_mul2_mulw_addtw(a[5], a[0], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[4], a[1], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[3], a[2], c2, c1, c0, &c2, &c1, &r[5]); + + bn_mulw_addtw(a[3], a[3], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[4], a[2], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[5], a[1], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[6], a[0], c2, c1, c0, &c2, &c1, &r[6]); + + bn_mul2_mulw_addtw(a[7], a[0], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[6], a[1], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[5], a[2], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[4], a[3], c2, c1, c0, &c2, &c1, &r[7]); + + bn_mulw_addtw(a[4], a[4], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[5], a[3], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[6], a[2], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[7], a[1], c2, c1, c0, &c2, &c1, &r[8]); + + bn_mul2_mulw_addtw(a[7], a[2], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[6], a[3], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[5], a[4], c2, c1, c0, &c2, &c1, &r[9]); + + bn_mulw_addtw(a[5], a[5], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[6], a[4], c2, c1, c0, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[7], a[3], c2, c1, c0, &c2, &c1, &r[10]); + + bn_mul2_mulw_addtw(a[7], a[4], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[6], a[5], c2, c1, c0, &c2, &c1, &r[11]); + + bn_mulw_addtw(a[6], a[6], 0, c2, c1, &c2, &c1, &c0); + bn_mul2_mulw_addtw(a[7], a[5], c2, c1, c0, &c2, &c1, &r[12]); + + bn_mul2_mulw_addtw(a[7], a[6], 0, c2, c1, &c2, &c1, &r[13]); + + bn_mulw_addtw(a[7], a[7], 0, c2, c1, &c2, &r[15], &r[14]); +} +#endif + +#ifndef HAVE_BN_SQR +/* + * bn_sqr_add_words() computes (r[i*2+1]:r[i*2]) = (r[i*2+1]:r[i*2]) + a[i] * a[i]. + */ +static void +bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + BN_ULONG x3, x2, x1, x0; + BN_ULONG carry = 0; + + assert(n >= 0); + if (n <= 0) + return; + + while (n & ~3) { + bn_mulw(a[0], a[0], &x1, &x0); + bn_mulw(a[1], a[1], &x3, &x2); + bn_qwaddqw(x3, x2, x1, x0, r[3], r[2], r[1], r[0], carry, + &carry, &r[3], &r[2], &r[1], &r[0]); + bn_mulw(a[2], a[2], &x1, &x0); + bn_mulw(a[3], a[3], &x3, &x2); + bn_qwaddqw(x3, x2, x1, x0, r[7], r[6], r[5], r[4], carry, + &carry, &r[7], &r[6], &r[5], &r[4]); + + a += 4; + r += 8; + n -= 4; + } + while (n) { + bn_mulw_addw_addw(a[0], a[0], r[0], carry, &carry, &r[0]); + bn_addw(r[1], carry, &carry, &r[1]); + a++; + r += 2; + n--; + } +} + +static void +bn_sqr_normal(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len) +{ + const BN_ULONG *ap; + BN_ULONG *rp; + BN_ULONG w; + int n; + + if (a_len <= 0) + return; + + ap = a; + w = ap[0]; + ap++; + + rp = r; + rp[0] = rp[r_len - 1] = 0; + rp++; + + /* Compute initial product - r[n:1] = a[n:1] * a[0] */ + n = a_len - 1; + if (n > 0) { + rp[n] = bn_mul_words(rp, ap, n, w); + } + rp += 2; + n--; + + /* Compute and sum remaining products. */ + while (n > 0) { + w = ap[0]; + ap++; + + rp[n] = bn_mul_add_words(rp, ap, n, w); + rp += 2; + n--; + } + + /* Double the sum of products. */ + bn_add_words(r, r, r, r_len); + + /* Add squares. */ + bn_sqr_add_words(r, a, a_len); +} + +/* + * bn_sqr() computes a * a, storing the result in r. The caller must ensure that + * r is not the same BIGNUM as a and that r has been expanded to rn = a->top * 2 + * words. + */ +int +bn_sqr(BIGNUM *r, const BIGNUM *a, int r_len, BN_CTX *ctx) +{ + bn_sqr_normal(r->d, r_len, a->d, a->top); + + return 1; +} +#endif + +int +BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ + BIGNUM *rr; + int r_len; + int ret = 1; + + BN_CTX_start(ctx); + + if (a->top < 1) { + BN_zero(r); + goto done; + } + + if ((rr = r) == a) + rr = BN_CTX_get(ctx); + if (rr == NULL) + goto err; + + if ((r_len = a->top * 2) < a->top) + goto err; + if (!bn_wexpand(rr, r_len)) + goto err; + + if (a->top == 4) { + bn_sqr_comba4(rr->d, a->d); + } else if (a->top == 8) { + bn_sqr_comba8(rr->d, a->d); + } else { + if (!bn_sqr(rr, a, r_len, ctx)) + goto err; + } + + rr->top = r_len; + bn_correct_top(rr); + + rr->neg = 0; + + if (!bn_copy(r, rr)) + goto err; + done: + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} +LCRYPTO_ALIAS(BN_sqr); diff --git a/Libraries/libressl/crypto/bn/bn_word.c b/Libraries/libressl/crypto/bn/bn_word.c new file mode 100644 index 000000000..a82b911e6 --- /dev/null +++ b/Libraries/libressl/crypto/bn/bn_word.c @@ -0,0 +1,245 @@ +/* $OpenBSD: bn_word.c,v 1.21 2023/07/08 12:21:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "bn_local.h" + +BN_ULONG +BN_mod_word(const BIGNUM *a, BN_ULONG w) +{ +#ifndef BN_LLONG + BN_ULONG ret = 0; +#else + BN_ULLONG ret = 0; +#endif + int i; + + if (w == 0) + return (BN_ULONG) - 1; + +#ifndef BN_ULLONG + /* If |w| is too long and we don't have |BN_ULLONG| then we need to fall back + * to using |BN_div_word|. */ + if (w > ((BN_ULONG)1 << BN_BITS4)) { + BIGNUM *tmp = BN_dup(a); + if (tmp == NULL) { + return (BN_ULONG)-1; + } + ret = BN_div_word(tmp, w); + BN_free(tmp); + return ret; + } +#endif + + w &= BN_MASK2; + for (i = a->top - 1; i >= 0; i--) { +#ifndef BN_LLONG + ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & + BN_MASK2l)) % w; + ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; +#else + ret = (BN_ULLONG)(((ret << (BN_ULLONG)BN_BITS2) | + a->d[i]) % (BN_ULLONG)w); +#endif + } + return ((BN_ULONG)ret); +} +LCRYPTO_ALIAS(BN_mod_word); + +BN_ULONG +BN_div_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG ret = 0; + int i, j; + + w &= BN_MASK2; + + if (!w) + /* actually this an error (division by zero) */ + return (BN_ULONG) - 1; + if (a->top == 0) + return 0; + + /* normalize input (so bn_div_words doesn't complain) */ + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) + return (BN_ULONG) - 1; + + for (i = a->top - 1; i >= 0; i--) { + BN_ULONG l, d; + + l = a->d[i]; + bn_div_rem_words(ret, l, w, &d, &ret); + a->d[i] = d; + } + if ((a->top > 0) && (a->d[a->top - 1] == 0)) + a->top--; + ret >>= j; + + /* Set negative again, to handle -0 case. */ + BN_set_negative(a, a->neg); + + return (ret); +} +LCRYPTO_ALIAS(BN_div_word); + +int +BN_add_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG l; + int i; + + w &= BN_MASK2; + + /* degenerate case: w is zero */ + if (!w) + return 1; + /* degenerate case: a is zero */ + if (BN_is_zero(a)) + return BN_set_word(a, w); + /* handle 'a' when negative */ + if (a->neg) { + a->neg = 0; + i = BN_sub_word(a, w); + BN_set_negative(a, !a->neg); + return (i); + } + for (i = 0; w != 0 && i < a->top; i++) { + a->d[i] = l = (a->d[i] + w) & BN_MASK2; + w = (w > l) ? 1 : 0; + } + if (w && i == a->top) { + if (!bn_wexpand(a, a->top + 1)) + return 0; + a->top++; + a->d[i] = w; + } + return (1); +} +LCRYPTO_ALIAS(BN_add_word); + +int +BN_sub_word(BIGNUM *a, BN_ULONG w) +{ + int i; + + w &= BN_MASK2; + + /* degenerate case: w is zero */ + if (!w) + return 1; + /* degenerate case: a is zero */ + if (BN_is_zero(a)) { + i = BN_set_word(a, w); + if (i != 0) + BN_set_negative(a, 1); + return i; + } + /* handle 'a' when negative */ + if (a->neg) { + a->neg = 0; + i = BN_add_word(a, w); + BN_set_negative(a, !a->neg); + return (i); + } + + if ((a->top == 1) && (a->d[0] < w)) { + a->d[0] = w - a->d[0]; + BN_set_negative(a, 1); + return (1); + } + i = 0; + for (;;) { + if (a->d[i] >= w) { + a->d[i] -= w; + break; + } else { + a->d[i] = (a->d[i] - w) & BN_MASK2; + i++; + w = 1; + } + } + if ((a->d[i] == 0) && (i == (a->top - 1))) + a->top--; + return (1); +} +LCRYPTO_ALIAS(BN_sub_word); + +int +BN_mul_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG ll; + + w &= BN_MASK2; + if (a->top) { + if (w == 0) + BN_zero(a); + else { + ll = bn_mul_words(a->d, a->d, a->top, w); + if (ll) { + if (!bn_wexpand(a, a->top + 1)) + return (0); + a->d[a->top++] = ll; + } + } + } + return (1); +} +LCRYPTO_ALIAS(BN_mul_word); diff --git a/Libraries/libressl/crypto/bn/modexp512-elf-x86_64.S b/Libraries/libressl/crypto/bn/modexp512-elf-x86_64.S new file mode 100644 index 000000000..87fc02618 --- /dev/null +++ b/Libraries/libressl/crypto/bn/modexp512-elf-x86_64.S @@ -0,0 +1,1782 @@ +#include "x86_arch.h" +.text + +.type MULADD_128x512,@function +.align 16 +MULADD_128x512: + endbr64 + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + movq %r8,0(%rcx) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq 8(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + movq %r9,8(%rcx) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%r9 + retq +.size MULADD_128x512,.-MULADD_128x512 +.type mont_reduce,@function +.align 16 +mont_reduce: + endbr64 + leaq 192(%rsp),%rdi + movq 32(%rsp),%rsi + addq $576,%rsi + leaq 520(%rsp),%rcx + + movq 96(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + movq (%rcx),%r8 + addq %rax,%r8 + adcq $0,%rdx + movq %r8,0(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + movq 8(%rcx),%r9 + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + movq 16(%rcx),%r10 + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + movq 24(%rcx),%r11 + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + movq 32(%rcx),%r12 + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + movq 40(%rcx),%r13 + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + movq 48(%rcx),%r14 + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + movq 56(%rcx),%r15 + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq 104(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + movq %r9,8(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%r9 + movq 112(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + movq %r10,16(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%r10 + movq 120(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + movq %r11,24(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%r11 + xorq %rax,%rax + + addq 64(%rcx),%r8 + adcq 72(%rcx),%r9 + adcq 80(%rcx),%r10 + adcq 88(%rcx),%r11 + adcq $0,%rax + + + + + movq %r8,64(%rdi) + movq %r9,72(%rdi) + movq %r10,%rbp + movq %r11,88(%rdi) + + movq %rax,384(%rsp) + + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + + + + + + + + + addq $80,%rdi + + addq $64,%rsi + leaq 296(%rsp),%rcx + + call MULADD_128x512 + + movq 384(%rsp),%rax + + + addq -16(%rdi),%r8 + adcq -8(%rdi),%r9 + movq %r8,64(%rcx) + movq %r9,72(%rcx) + + adcq %rax,%rax + movq %rax,384(%rsp) + + leaq 192(%rsp),%rdi + addq $64,%rsi + + + + + + movq (%rsi),%r8 + movq 8(%rsi),%rbx + + movq (%rcx),%rax + mulq %r8 + movq %rax,%rbp + movq %rdx,%r9 + + movq 8(%rcx),%rax + mulq %r8 + addq %rax,%r9 + + movq (%rcx),%rax + mulq %rbx + addq %rax,%r9 + + movq %r9,8(%rdi) + + + subq $192,%rsi + + movq (%rcx),%r8 + movq 8(%rcx),%r9 + + call MULADD_128x512 + + + + + movq 0(%rsi),%rax + movq 8(%rsi),%rbx + movq 16(%rsi),%rdi + movq 24(%rsi),%rdx + + + movq 384(%rsp),%rbp + + addq 64(%rcx),%r8 + adcq 72(%rcx),%r9 + + + adcq %rbp,%rbp + + + + shlq $3,%rbp + movq 32(%rsp),%rcx + addq %rcx,%rbp + + + xorq %rsi,%rsi + + addq 0(%rbp),%r10 + adcq 64(%rbp),%r11 + adcq 128(%rbp),%r12 + adcq 192(%rbp),%r13 + adcq 256(%rbp),%r14 + adcq 320(%rbp),%r15 + adcq 384(%rbp),%r8 + adcq 448(%rbp),%r9 + + + + sbbq $0,%rsi + + + andq %rsi,%rax + andq %rsi,%rbx + andq %rsi,%rdi + andq %rsi,%rdx + + movq $1,%rbp + subq %rax,%r10 + sbbq %rbx,%r11 + sbbq %rdi,%r12 + sbbq %rdx,%r13 + + + + + sbbq $0,%rbp + + + + addq $512,%rcx + movq 32(%rcx),%rax + movq 40(%rcx),%rbx + movq 48(%rcx),%rdi + movq 56(%rcx),%rdx + + + + andq %rsi,%rax + andq %rsi,%rbx + andq %rsi,%rdi + andq %rsi,%rdx + + + + subq $1,%rbp + + sbbq %rax,%r14 + sbbq %rbx,%r15 + sbbq %rdi,%r8 + sbbq %rdx,%r9 + + + + movq 144(%rsp),%rsi + movq %r10,0(%rsi) + movq %r11,8(%rsi) + movq %r12,16(%rsi) + movq %r13,24(%rsi) + movq %r14,32(%rsi) + movq %r15,40(%rsi) + movq %r8,48(%rsi) + movq %r9,56(%rsi) + + retq +.size mont_reduce,.-mont_reduce +.type mont_mul_a3b,@function +.align 16 +mont_mul_a3b: + endbr64 + + + + + movq 0(%rdi),%rbp + + movq %r10,%rax + mulq %rbp + movq %rax,520(%rsp) + movq %rdx,%r10 + movq %r11,%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + movq %rdx,%r11 + movq %r12,%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + movq %rdx,%r12 + movq %r13,%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + movq %rdx,%r13 + movq %r14,%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + movq %rdx,%r14 + movq %r15,%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r15 + movq %r8,%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq %r9,%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + movq %rdx,%r9 + movq 8(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + movq %r10,528(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%r10 + movq 16(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + movq %r11,536(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%r11 + movq 24(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + movq %r12,544(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%r12 + movq 32(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + movq %r13,552(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%r13 + movq 40(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + movq %r14,560(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%r14 + movq 48(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + movq %r15,568(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%r15 + movq 56(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + movq %r8,576(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq %r9,584(%rsp) + movq %r10,592(%rsp) + movq %r11,600(%rsp) + movq %r12,608(%rsp) + movq %r13,616(%rsp) + movq %r14,624(%rsp) + movq %r15,632(%rsp) + movq %r8,640(%rsp) + + + + + + jmp mont_reduce + + +.size mont_mul_a3b,.-mont_mul_a3b +.type sqr_reduce,@function +.align 16 +sqr_reduce: + endbr64 + movq 16(%rsp),%rcx + + + + movq %r10,%rbx + + movq %r11,%rax + mulq %rbx + movq %rax,528(%rsp) + movq %rdx,%r10 + movq %r12,%rax + mulq %rbx + addq %rax,%r10 + adcq $0,%rdx + movq %rdx,%r11 + movq %r13,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + movq %rdx,%r12 + movq %r14,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + movq %rdx,%r13 + movq %r15,%rax + mulq %rbx + addq %rax,%r13 + adcq $0,%rdx + movq %rdx,%r14 + movq %r8,%rax + mulq %rbx + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r15 + movq %r9,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + movq %rdx,%rsi + + movq %r10,536(%rsp) + + + + + + movq 8(%rcx),%rbx + + movq 16(%rcx),%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + movq %r11,544(%rsp) + + movq %rdx,%r10 + movq 24(%rcx),%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + addq %r10,%r12 + adcq $0,%rdx + movq %r12,552(%rsp) + + movq %rdx,%r10 + movq 32(%rcx),%rax + mulq %rbx + addq %rax,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + + movq %rdx,%r10 + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%r14 + adcq $0,%rdx + addq %r10,%r14 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r10,%r15 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%rsi + adcq $0,%rdx + addq %r10,%rsi + adcq $0,%rdx + + movq %rdx,%r11 + + + + + movq 16(%rcx),%rbx + + movq 24(%rcx),%rax + mulq %rbx + addq %rax,%r13 + adcq $0,%rdx + movq %r13,560(%rsp) + + movq %rdx,%r10 + movq 32(%rcx),%rax + mulq %rbx + addq %rax,%r14 + adcq $0,%rdx + addq %r10,%r14 + adcq $0,%rdx + movq %r14,568(%rsp) + + movq %rdx,%r10 + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r10,%r15 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%rsi + adcq $0,%rdx + addq %r10,%rsi + adcq $0,%rdx + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + addq %r10,%r11 + adcq $0,%rdx + + movq %rdx,%r12 + + + + + + movq 24(%rcx),%rbx + + movq 32(%rcx),%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + movq %r15,576(%rsp) + + movq %rdx,%r10 + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%rsi + adcq $0,%rdx + addq %r10,%rsi + adcq $0,%rdx + movq %rsi,584(%rsp) + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + addq %r10,%r11 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + addq %r10,%r12 + adcq $0,%rdx + + movq %rdx,%r15 + + + + + movq 32(%rcx),%rbx + + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + movq %r11,592(%rsp) + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + addq %r10,%r12 + adcq $0,%rdx + movq %r12,600(%rsp) + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r10,%r15 + adcq $0,%rdx + + movq %rdx,%r11 + + + + + movq 40(%rcx),%rbx + + movq %r8,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + movq %r15,608(%rsp) + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + addq %r10,%r11 + adcq $0,%rdx + movq %r11,616(%rsp) + + movq %rdx,%r12 + + + + + movq %r8,%rbx + + movq %r9,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + movq %r12,624(%rsp) + + movq %rdx,632(%rsp) + + + movq 528(%rsp),%r10 + movq 536(%rsp),%r11 + movq 544(%rsp),%r12 + movq 552(%rsp),%r13 + movq 560(%rsp),%r14 + movq 568(%rsp),%r15 + + movq 24(%rcx),%rax + mulq %rax + movq %rax,%rdi + movq %rdx,%r8 + + addq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq %r15,%r15 + adcq $0,%r8 + + movq 0(%rcx),%rax + mulq %rax + movq %rax,520(%rsp) + movq %rdx,%rbx + + movq 8(%rcx),%rax + mulq %rax + + addq %rbx,%r10 + adcq %rax,%r11 + adcq $0,%rdx + + movq %rdx,%rbx + movq %r10,528(%rsp) + movq %r11,536(%rsp) + + movq 16(%rcx),%rax + mulq %rax + + addq %rbx,%r12 + adcq %rax,%r13 + adcq $0,%rdx + + movq %rdx,%rbx + + movq %r12,544(%rsp) + movq %r13,552(%rsp) + + xorq %rbp,%rbp + addq %rbx,%r14 + adcq %rdi,%r15 + adcq $0,%rbp + + movq %r14,560(%rsp) + movq %r15,568(%rsp) + + + + + movq 576(%rsp),%r10 + movq 584(%rsp),%r11 + movq 592(%rsp),%r12 + movq 600(%rsp),%r13 + movq 608(%rsp),%r14 + movq 616(%rsp),%r15 + movq 624(%rsp),%rdi + movq 632(%rsp),%rsi + + movq %r9,%rax + mulq %rax + movq %rax,%r9 + movq %rdx,%rbx + + addq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq %r15,%r15 + adcq %rdi,%rdi + adcq %rsi,%rsi + adcq $0,%rbx + + addq %rbp,%r10 + + movq 32(%rcx),%rax + mulq %rax + + addq %r8,%r10 + adcq %rax,%r11 + adcq $0,%rdx + + movq %rdx,%rbp + + movq %r10,576(%rsp) + movq %r11,584(%rsp) + + movq 40(%rcx),%rax + mulq %rax + + addq %rbp,%r12 + adcq %rax,%r13 + adcq $0,%rdx + + movq %rdx,%rbp + + movq %r12,592(%rsp) + movq %r13,600(%rsp) + + movq 48(%rcx),%rax + mulq %rax + + addq %rbp,%r14 + adcq %rax,%r15 + adcq $0,%rdx + + movq %r14,608(%rsp) + movq %r15,616(%rsp) + + addq %rdx,%rdi + adcq %r9,%rsi + adcq $0,%rbx + + movq %rdi,624(%rsp) + movq %rsi,632(%rsp) + movq %rbx,640(%rsp) + + jmp mont_reduce + + +.size sqr_reduce,.-sqr_reduce +.globl mod_exp_512 +.type mod_exp_512,@function +mod_exp_512: + endbr64 + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + + movq %rsp,%r8 + subq $2688,%rsp + andq $-64,%rsp + + + movq %r8,0(%rsp) + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rcx,24(%rsp) +.Lbody: + + + + pxor %xmm4,%xmm4 + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqa %xmm4,512(%rsp) + movdqa %xmm4,528(%rsp) + movdqa %xmm4,608(%rsp) + movdqa %xmm4,624(%rsp) + movdqa %xmm0,544(%rsp) + movdqa %xmm1,560(%rsp) + movdqa %xmm2,576(%rsp) + movdqa %xmm3,592(%rsp) + + + movdqu 0(%rdx),%xmm0 + movdqu 16(%rdx),%xmm1 + movdqu 32(%rdx),%xmm2 + movdqu 48(%rdx),%xmm3 + + leaq 384(%rsp),%rbx + movq %rbx,136(%rsp) + call mont_reduce + + + leaq 448(%rsp),%rcx + xorq %rax,%rax + movq %rax,0(%rcx) + movq %rax,8(%rcx) + movq %rax,24(%rcx) + movq %rax,32(%rcx) + movq %rax,40(%rcx) + movq %rax,48(%rcx) + movq %rax,56(%rcx) + movq %rax,128(%rsp) + movq $1,16(%rcx) + + leaq 640(%rsp),%rbp + movq %rcx,%rsi + movq %rbp,%rdi + movq $8,%rax +loop_0: + movq (%rcx),%rbx + movw %bx,(%rdi) + shrq $16,%rbx + movw %bx,64(%rdi) + shrq $16,%rbx + movw %bx,128(%rdi) + shrq $16,%rbx + movw %bx,192(%rdi) + leaq 8(%rcx),%rcx + leaq 256(%rdi),%rdi + decq %rax + jnz loop_0 + movq $31,%rax + movq %rax,32(%rsp) + movq %rbp,40(%rsp) + + movq %rsi,136(%rsp) + movq 0(%rsi),%r10 + movq 8(%rsi),%r11 + movq 16(%rsi),%r12 + movq 24(%rsi),%r13 + movq 32(%rsi),%r14 + movq 40(%rsi),%r15 + movq 48(%rsi),%r8 + movq 56(%rsi),%r9 +init_loop: + leaq 384(%rsp),%rdi + call mont_mul_a3b + leaq 448(%rsp),%rsi + movq 40(%rsp),%rbp + addq $2,%rbp + movq %rbp,40(%rsp) + movq %rsi,%rcx + movq $8,%rax +loop_1: + movq (%rcx),%rbx + movw %bx,(%rbp) + shrq $16,%rbx + movw %bx,64(%rbp) + shrq $16,%rbx + movw %bx,128(%rbp) + shrq $16,%rbx + movw %bx,192(%rbp) + leaq 8(%rcx),%rcx + leaq 256(%rbp),%rbp + decq %rax + jnz loop_1 + movq 32(%rsp),%rax + subq $1,%rax + movq %rax,32(%rsp) + jne init_loop + + + + movdqa %xmm0,64(%rsp) + movdqa %xmm1,80(%rsp) + movdqa %xmm2,96(%rsp) + movdqa %xmm3,112(%rsp) + + + + + + movl 126(%rsp),%eax + movq %rax,%rdx + shrq $11,%rax + andl $2047,%edx + movl %edx,126(%rsp) + leaq 640(%rsp,%rax,2),%rsi + movq 8(%rsp),%rdx + movq $4,%rbp +loop_2: + movzwq 192(%rsi),%rbx + movzwq 448(%rsi),%rax + shlq $16,%rbx + shlq $16,%rax + movw 128(%rsi),%bx + movw 384(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 64(%rsi),%bx + movw 320(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 0(%rsi),%bx + movw 256(%rsi),%ax + movq %rbx,0(%rdx) + movq %rax,8(%rdx) + leaq 512(%rsi),%rsi + leaq 16(%rdx),%rdx + subq $1,%rbp + jnz loop_2 + movq $505,48(%rsp) + + movq 8(%rsp),%rcx + movq %rcx,136(%rsp) + movq 0(%rcx),%r10 + movq 8(%rcx),%r11 + movq 16(%rcx),%r12 + movq 24(%rcx),%r13 + movq 32(%rcx),%r14 + movq 40(%rcx),%r15 + movq 48(%rcx),%r8 + movq 56(%rcx),%r9 + jmp sqr_2 + +main_loop_a3b: + call sqr_reduce + call sqr_reduce + call sqr_reduce +sqr_2: + call sqr_reduce + call sqr_reduce + + + + movq 48(%rsp),%rcx + movq %rcx,%rax + shrq $4,%rax + movl 64(%rsp,%rax,2),%edx + andq $15,%rcx + shrq %cl,%rdx + andq $31,%rdx + + leaq 640(%rsp,%rdx,2),%rsi + leaq 448(%rsp),%rdx + movq %rdx,%rdi + movq $4,%rbp +loop_3: + movzwq 192(%rsi),%rbx + movzwq 448(%rsi),%rax + shlq $16,%rbx + shlq $16,%rax + movw 128(%rsi),%bx + movw 384(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 64(%rsi),%bx + movw 320(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 0(%rsi),%bx + movw 256(%rsi),%ax + movq %rbx,0(%rdx) + movq %rax,8(%rdx) + leaq 512(%rsi),%rsi + leaq 16(%rdx),%rdx + subq $1,%rbp + jnz loop_3 + movq 8(%rsp),%rsi + call mont_mul_a3b + + + + movq 48(%rsp),%rcx + subq $5,%rcx + movq %rcx,48(%rsp) + jge main_loop_a3b + + + +end_main_loop_a3b: + + + movq 8(%rsp),%rdx + pxor %xmm4,%xmm4 + movdqu 0(%rdx),%xmm0 + movdqu 16(%rdx),%xmm1 + movdqu 32(%rdx),%xmm2 + movdqu 48(%rdx),%xmm3 + movdqa %xmm4,576(%rsp) + movdqa %xmm4,592(%rsp) + movdqa %xmm4,608(%rsp) + movdqa %xmm4,624(%rsp) + movdqa %xmm0,512(%rsp) + movdqa %xmm1,528(%rsp) + movdqa %xmm2,544(%rsp) + movdqa %xmm3,560(%rsp) + call mont_reduce + + + + movq 8(%rsp),%rax + movq 0(%rax),%r8 + movq 8(%rax),%r9 + movq 16(%rax),%r10 + movq 24(%rax),%r11 + movq 32(%rax),%r12 + movq 40(%rax),%r13 + movq 48(%rax),%r14 + movq 56(%rax),%r15 + + + movq 24(%rsp),%rbx + addq $512,%rbx + + subq 0(%rbx),%r8 + sbbq 8(%rbx),%r9 + sbbq 16(%rbx),%r10 + sbbq 24(%rbx),%r11 + sbbq 32(%rbx),%r12 + sbbq 40(%rbx),%r13 + sbbq 48(%rbx),%r14 + sbbq 56(%rbx),%r15 + + + movq 0(%rax),%rsi + movq 8(%rax),%rdi + movq 16(%rax),%rcx + movq 24(%rax),%rdx + cmovncq %r8,%rsi + cmovncq %r9,%rdi + cmovncq %r10,%rcx + cmovncq %r11,%rdx + movq %rsi,0(%rax) + movq %rdi,8(%rax) + movq %rcx,16(%rax) + movq %rdx,24(%rax) + + movq 32(%rax),%rsi + movq 40(%rax),%rdi + movq 48(%rax),%rcx + movq 56(%rax),%rdx + cmovncq %r12,%rsi + cmovncq %r13,%rdi + cmovncq %r14,%rcx + cmovncq %r15,%rdx + movq %rsi,32(%rax) + movq %rdi,40(%rax) + movq %rcx,48(%rax) + movq %rdx,56(%rax) + + movq 0(%rsp),%rsi + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbx + movq 40(%rsi),%rbp + leaq 48(%rsi),%rsp +.Lepilogue: + retq +.size mod_exp_512, . - mod_exp_512 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/modexp512-macosx-x86_64.S b/Libraries/libressl/crypto/bn/modexp512-macosx-x86_64.S new file mode 100644 index 000000000..4d7b0b825 --- /dev/null +++ b/Libraries/libressl/crypto/bn/modexp512-macosx-x86_64.S @@ -0,0 +1,1774 @@ +#include "x86_arch.h" +.text + + +.p2align 4 +MULADD_128x512: + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + movq %r8,0(%rcx) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq 8(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + movq %r9,8(%rcx) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%r9 + retq + + +.p2align 4 +mont_reduce: + leaq 192(%rsp),%rdi + movq 32(%rsp),%rsi + addq $576,%rsi + leaq 520(%rsp),%rcx + + movq 96(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + movq (%rcx),%r8 + addq %rax,%r8 + adcq $0,%rdx + movq %r8,0(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + movq 8(%rcx),%r9 + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + movq 16(%rcx),%r10 + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + movq 24(%rcx),%r11 + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + movq 32(%rcx),%r12 + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + movq 40(%rcx),%r13 + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + movq 48(%rcx),%r14 + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + movq 56(%rcx),%r15 + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq 104(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + movq %r9,8(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%r9 + movq 112(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + movq %r10,16(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%r10 + movq 120(%rcx),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + movq %r11,24(%rdi) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%r11 + xorq %rax,%rax + + addq 64(%rcx),%r8 + adcq 72(%rcx),%r9 + adcq 80(%rcx),%r10 + adcq 88(%rcx),%r11 + adcq $0,%rax + + + + + movq %r8,64(%rdi) + movq %r9,72(%rdi) + movq %r10,%rbp + movq %r11,88(%rdi) + + movq %rax,384(%rsp) + + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + + + + + + + + + addq $80,%rdi + + addq $64,%rsi + leaq 296(%rsp),%rcx + + call MULADD_128x512 + + movq 384(%rsp),%rax + + + addq -16(%rdi),%r8 + adcq -8(%rdi),%r9 + movq %r8,64(%rcx) + movq %r9,72(%rcx) + + adcq %rax,%rax + movq %rax,384(%rsp) + + leaq 192(%rsp),%rdi + addq $64,%rsi + + + + + + movq (%rsi),%r8 + movq 8(%rsi),%rbx + + movq (%rcx),%rax + mulq %r8 + movq %rax,%rbp + movq %rdx,%r9 + + movq 8(%rcx),%rax + mulq %r8 + addq %rax,%r9 + + movq (%rcx),%rax + mulq %rbx + addq %rax,%r9 + + movq %r9,8(%rdi) + + + subq $192,%rsi + + movq (%rcx),%r8 + movq 8(%rcx),%r9 + + call MULADD_128x512 + + + + + movq 0(%rsi),%rax + movq 8(%rsi),%rbx + movq 16(%rsi),%rdi + movq 24(%rsi),%rdx + + + movq 384(%rsp),%rbp + + addq 64(%rcx),%r8 + adcq 72(%rcx),%r9 + + + adcq %rbp,%rbp + + + + shlq $3,%rbp + movq 32(%rsp),%rcx + addq %rcx,%rbp + + + xorq %rsi,%rsi + + addq 0(%rbp),%r10 + adcq 64(%rbp),%r11 + adcq 128(%rbp),%r12 + adcq 192(%rbp),%r13 + adcq 256(%rbp),%r14 + adcq 320(%rbp),%r15 + adcq 384(%rbp),%r8 + adcq 448(%rbp),%r9 + + + + sbbq $0,%rsi + + + andq %rsi,%rax + andq %rsi,%rbx + andq %rsi,%rdi + andq %rsi,%rdx + + movq $1,%rbp + subq %rax,%r10 + sbbq %rbx,%r11 + sbbq %rdi,%r12 + sbbq %rdx,%r13 + + + + + sbbq $0,%rbp + + + + addq $512,%rcx + movq 32(%rcx),%rax + movq 40(%rcx),%rbx + movq 48(%rcx),%rdi + movq 56(%rcx),%rdx + + + + andq %rsi,%rax + andq %rsi,%rbx + andq %rsi,%rdi + andq %rsi,%rdx + + + + subq $1,%rbp + + sbbq %rax,%r14 + sbbq %rbx,%r15 + sbbq %rdi,%r8 + sbbq %rdx,%r9 + + + + movq 144(%rsp),%rsi + movq %r10,0(%rsi) + movq %r11,8(%rsi) + movq %r12,16(%rsi) + movq %r13,24(%rsi) + movq %r14,32(%rsi) + movq %r15,40(%rsi) + movq %r8,48(%rsi) + movq %r9,56(%rsi) + + retq + + +.p2align 4 +mont_mul_a3b: + + + + + movq 0(%rdi),%rbp + + movq %r10,%rax + mulq %rbp + movq %rax,520(%rsp) + movq %rdx,%r10 + movq %r11,%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + movq %rdx,%r11 + movq %r12,%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + movq %rdx,%r12 + movq %r13,%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + movq %rdx,%r13 + movq %r14,%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + movq %rdx,%r14 + movq %r15,%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r15 + movq %r8,%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq %r9,%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + movq %rdx,%r9 + movq 8(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + movq %r10,528(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%r10 + movq 16(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + movq %r11,536(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%r11 + movq 24(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + movq %r12,544(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%r12 + movq 32(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + movq %r13,552(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%r13 + movq 40(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + movq %r14,560(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%r14 + movq 48(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + movq %r15,568(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + addq %rbx,%r8 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%r15 + movq 56(%rdi),%rbp + movq 0(%rsi),%rax + mulq %rbp + addq %rax,%r8 + adcq $0,%rdx + movq %r8,576(%rsp) + movq %rdx,%rbx + + movq 8(%rsi),%rax + mulq %rbp + addq %rax,%r9 + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + movq %rdx,%rbx + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r10 + adcq $0,%rdx + addq %rbx,%r10 + adcq $0,%rdx + movq %rdx,%rbx + + movq 24(%rsi),%rax + mulq %rbp + addq %rax,%r11 + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + movq %rdx,%rbx + + movq 32(%rsi),%rax + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + addq %rbx,%r12 + adcq $0,%rdx + movq %rdx,%rbx + + movq 40(%rsi),%rax + mulq %rbp + addq %rax,%r13 + adcq $0,%rdx + addq %rbx,%r13 + adcq $0,%rdx + movq %rdx,%rbx + + movq 48(%rsi),%rax + mulq %rbp + addq %rax,%r14 + adcq $0,%rdx + addq %rbx,%r14 + adcq $0,%rdx + movq %rdx,%rbx + + movq 56(%rsi),%rax + mulq %rbp + addq %rax,%r15 + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + movq %rdx,%r8 + movq %r9,584(%rsp) + movq %r10,592(%rsp) + movq %r11,600(%rsp) + movq %r12,608(%rsp) + movq %r13,616(%rsp) + movq %r14,624(%rsp) + movq %r15,632(%rsp) + movq %r8,640(%rsp) + + + + + + jmp mont_reduce + + + + +.p2align 4 +sqr_reduce: + movq 16(%rsp),%rcx + + + + movq %r10,%rbx + + movq %r11,%rax + mulq %rbx + movq %rax,528(%rsp) + movq %rdx,%r10 + movq %r12,%rax + mulq %rbx + addq %rax,%r10 + adcq $0,%rdx + movq %rdx,%r11 + movq %r13,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + movq %rdx,%r12 + movq %r14,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + movq %rdx,%r13 + movq %r15,%rax + mulq %rbx + addq %rax,%r13 + adcq $0,%rdx + movq %rdx,%r14 + movq %r8,%rax + mulq %rbx + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r15 + movq %r9,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + movq %rdx,%rsi + + movq %r10,536(%rsp) + + + + + + movq 8(%rcx),%rbx + + movq 16(%rcx),%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + movq %r11,544(%rsp) + + movq %rdx,%r10 + movq 24(%rcx),%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + addq %r10,%r12 + adcq $0,%rdx + movq %r12,552(%rsp) + + movq %rdx,%r10 + movq 32(%rcx),%rax + mulq %rbx + addq %rax,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + + movq %rdx,%r10 + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%r14 + adcq $0,%rdx + addq %r10,%r14 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r10,%r15 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%rsi + adcq $0,%rdx + addq %r10,%rsi + adcq $0,%rdx + + movq %rdx,%r11 + + + + + movq 16(%rcx),%rbx + + movq 24(%rcx),%rax + mulq %rbx + addq %rax,%r13 + adcq $0,%rdx + movq %r13,560(%rsp) + + movq %rdx,%r10 + movq 32(%rcx),%rax + mulq %rbx + addq %rax,%r14 + adcq $0,%rdx + addq %r10,%r14 + adcq $0,%rdx + movq %r14,568(%rsp) + + movq %rdx,%r10 + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r10,%r15 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%rsi + adcq $0,%rdx + addq %r10,%rsi + adcq $0,%rdx + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + addq %r10,%r11 + adcq $0,%rdx + + movq %rdx,%r12 + + + + + + movq 24(%rcx),%rbx + + movq 32(%rcx),%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + movq %r15,576(%rsp) + + movq %rdx,%r10 + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%rsi + adcq $0,%rdx + addq %r10,%rsi + adcq $0,%rdx + movq %rsi,584(%rsp) + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + addq %r10,%r11 + adcq $0,%rdx + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + addq %r10,%r12 + adcq $0,%rdx + + movq %rdx,%r15 + + + + + movq 32(%rcx),%rbx + + movq 40(%rcx),%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + movq %r11,592(%rsp) + + movq %rdx,%r10 + movq %r8,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + addq %r10,%r12 + adcq $0,%rdx + movq %r12,600(%rsp) + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r10,%r15 + adcq $0,%rdx + + movq %rdx,%r11 + + + + + movq 40(%rcx),%rbx + + movq %r8,%rax + mulq %rbx + addq %rax,%r15 + adcq $0,%rdx + movq %r15,608(%rsp) + + movq %rdx,%r10 + movq %r9,%rax + mulq %rbx + addq %rax,%r11 + adcq $0,%rdx + addq %r10,%r11 + adcq $0,%rdx + movq %r11,616(%rsp) + + movq %rdx,%r12 + + + + + movq %r8,%rbx + + movq %r9,%rax + mulq %rbx + addq %rax,%r12 + adcq $0,%rdx + movq %r12,624(%rsp) + + movq %rdx,632(%rsp) + + + movq 528(%rsp),%r10 + movq 536(%rsp),%r11 + movq 544(%rsp),%r12 + movq 552(%rsp),%r13 + movq 560(%rsp),%r14 + movq 568(%rsp),%r15 + + movq 24(%rcx),%rax + mulq %rax + movq %rax,%rdi + movq %rdx,%r8 + + addq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq %r15,%r15 + adcq $0,%r8 + + movq 0(%rcx),%rax + mulq %rax + movq %rax,520(%rsp) + movq %rdx,%rbx + + movq 8(%rcx),%rax + mulq %rax + + addq %rbx,%r10 + adcq %rax,%r11 + adcq $0,%rdx + + movq %rdx,%rbx + movq %r10,528(%rsp) + movq %r11,536(%rsp) + + movq 16(%rcx),%rax + mulq %rax + + addq %rbx,%r12 + adcq %rax,%r13 + adcq $0,%rdx + + movq %rdx,%rbx + + movq %r12,544(%rsp) + movq %r13,552(%rsp) + + xorq %rbp,%rbp + addq %rbx,%r14 + adcq %rdi,%r15 + adcq $0,%rbp + + movq %r14,560(%rsp) + movq %r15,568(%rsp) + + + + + movq 576(%rsp),%r10 + movq 584(%rsp),%r11 + movq 592(%rsp),%r12 + movq 600(%rsp),%r13 + movq 608(%rsp),%r14 + movq 616(%rsp),%r15 + movq 624(%rsp),%rdi + movq 632(%rsp),%rsi + + movq %r9,%rax + mulq %rax + movq %rax,%r9 + movq %rdx,%rbx + + addq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq %r15,%r15 + adcq %rdi,%rdi + adcq %rsi,%rsi + adcq $0,%rbx + + addq %rbp,%r10 + + movq 32(%rcx),%rax + mulq %rax + + addq %r8,%r10 + adcq %rax,%r11 + adcq $0,%rdx + + movq %rdx,%rbp + + movq %r10,576(%rsp) + movq %r11,584(%rsp) + + movq 40(%rcx),%rax + mulq %rax + + addq %rbp,%r12 + adcq %rax,%r13 + adcq $0,%rdx + + movq %rdx,%rbp + + movq %r12,592(%rsp) + movq %r13,600(%rsp) + + movq 48(%rcx),%rax + mulq %rax + + addq %rbp,%r14 + adcq %rax,%r15 + adcq $0,%rdx + + movq %r14,608(%rsp) + movq %r15,616(%rsp) + + addq %rdx,%rdi + adcq %r9,%rsi + adcq $0,%rbx + + movq %rdi,624(%rsp) + movq %rsi,632(%rsp) + movq %rbx,640(%rsp) + + jmp mont_reduce + + + +.globl _mod_exp_512 + +_mod_exp_512: + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + + movq %rsp,%r8 + subq $2688,%rsp + andq $-64,%rsp + + + movq %r8,0(%rsp) + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rcx,24(%rsp) +L$body: + + + + pxor %xmm4,%xmm4 + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqa %xmm4,512(%rsp) + movdqa %xmm4,528(%rsp) + movdqa %xmm4,608(%rsp) + movdqa %xmm4,624(%rsp) + movdqa %xmm0,544(%rsp) + movdqa %xmm1,560(%rsp) + movdqa %xmm2,576(%rsp) + movdqa %xmm3,592(%rsp) + + + movdqu 0(%rdx),%xmm0 + movdqu 16(%rdx),%xmm1 + movdqu 32(%rdx),%xmm2 + movdqu 48(%rdx),%xmm3 + + leaq 384(%rsp),%rbx + movq %rbx,136(%rsp) + call mont_reduce + + + leaq 448(%rsp),%rcx + xorq %rax,%rax + movq %rax,0(%rcx) + movq %rax,8(%rcx) + movq %rax,24(%rcx) + movq %rax,32(%rcx) + movq %rax,40(%rcx) + movq %rax,48(%rcx) + movq %rax,56(%rcx) + movq %rax,128(%rsp) + movq $1,16(%rcx) + + leaq 640(%rsp),%rbp + movq %rcx,%rsi + movq %rbp,%rdi + movq $8,%rax +loop_0: + movq (%rcx),%rbx + movw %bx,(%rdi) + shrq $16,%rbx + movw %bx,64(%rdi) + shrq $16,%rbx + movw %bx,128(%rdi) + shrq $16,%rbx + movw %bx,192(%rdi) + leaq 8(%rcx),%rcx + leaq 256(%rdi),%rdi + decq %rax + jnz loop_0 + movq $31,%rax + movq %rax,32(%rsp) + movq %rbp,40(%rsp) + + movq %rsi,136(%rsp) + movq 0(%rsi),%r10 + movq 8(%rsi),%r11 + movq 16(%rsi),%r12 + movq 24(%rsi),%r13 + movq 32(%rsi),%r14 + movq 40(%rsi),%r15 + movq 48(%rsi),%r8 + movq 56(%rsi),%r9 +init_loop: + leaq 384(%rsp),%rdi + call mont_mul_a3b + leaq 448(%rsp),%rsi + movq 40(%rsp),%rbp + addq $2,%rbp + movq %rbp,40(%rsp) + movq %rsi,%rcx + movq $8,%rax +loop_1: + movq (%rcx),%rbx + movw %bx,(%rbp) + shrq $16,%rbx + movw %bx,64(%rbp) + shrq $16,%rbx + movw %bx,128(%rbp) + shrq $16,%rbx + movw %bx,192(%rbp) + leaq 8(%rcx),%rcx + leaq 256(%rbp),%rbp + decq %rax + jnz loop_1 + movq 32(%rsp),%rax + subq $1,%rax + movq %rax,32(%rsp) + jne init_loop + + + + movdqa %xmm0,64(%rsp) + movdqa %xmm1,80(%rsp) + movdqa %xmm2,96(%rsp) + movdqa %xmm3,112(%rsp) + + + + + + movl 126(%rsp),%eax + movq %rax,%rdx + shrq $11,%rax + andl $2047,%edx + movl %edx,126(%rsp) + leaq 640(%rsp,%rax,2),%rsi + movq 8(%rsp),%rdx + movq $4,%rbp +loop_2: + movzwq 192(%rsi),%rbx + movzwq 448(%rsi),%rax + shlq $16,%rbx + shlq $16,%rax + movw 128(%rsi),%bx + movw 384(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 64(%rsi),%bx + movw 320(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 0(%rsi),%bx + movw 256(%rsi),%ax + movq %rbx,0(%rdx) + movq %rax,8(%rdx) + leaq 512(%rsi),%rsi + leaq 16(%rdx),%rdx + subq $1,%rbp + jnz loop_2 + movq $505,48(%rsp) + + movq 8(%rsp),%rcx + movq %rcx,136(%rsp) + movq 0(%rcx),%r10 + movq 8(%rcx),%r11 + movq 16(%rcx),%r12 + movq 24(%rcx),%r13 + movq 32(%rcx),%r14 + movq 40(%rcx),%r15 + movq 48(%rcx),%r8 + movq 56(%rcx),%r9 + jmp sqr_2 + +main_loop_a3b: + call sqr_reduce + call sqr_reduce + call sqr_reduce +sqr_2: + call sqr_reduce + call sqr_reduce + + + + movq 48(%rsp),%rcx + movq %rcx,%rax + shrq $4,%rax + movl 64(%rsp,%rax,2),%edx + andq $15,%rcx + shrq %cl,%rdx + andq $31,%rdx + + leaq 640(%rsp,%rdx,2),%rsi + leaq 448(%rsp),%rdx + movq %rdx,%rdi + movq $4,%rbp +loop_3: + movzwq 192(%rsi),%rbx + movzwq 448(%rsi),%rax + shlq $16,%rbx + shlq $16,%rax + movw 128(%rsi),%bx + movw 384(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 64(%rsi),%bx + movw 320(%rsi),%ax + shlq $16,%rbx + shlq $16,%rax + movw 0(%rsi),%bx + movw 256(%rsi),%ax + movq %rbx,0(%rdx) + movq %rax,8(%rdx) + leaq 512(%rsi),%rsi + leaq 16(%rdx),%rdx + subq $1,%rbp + jnz loop_3 + movq 8(%rsp),%rsi + call mont_mul_a3b + + + + movq 48(%rsp),%rcx + subq $5,%rcx + movq %rcx,48(%rsp) + jge main_loop_a3b + + + +end_main_loop_a3b: + + + movq 8(%rsp),%rdx + pxor %xmm4,%xmm4 + movdqu 0(%rdx),%xmm0 + movdqu 16(%rdx),%xmm1 + movdqu 32(%rdx),%xmm2 + movdqu 48(%rdx),%xmm3 + movdqa %xmm4,576(%rsp) + movdqa %xmm4,592(%rsp) + movdqa %xmm4,608(%rsp) + movdqa %xmm4,624(%rsp) + movdqa %xmm0,512(%rsp) + movdqa %xmm1,528(%rsp) + movdqa %xmm2,544(%rsp) + movdqa %xmm3,560(%rsp) + call mont_reduce + + + + movq 8(%rsp),%rax + movq 0(%rax),%r8 + movq 8(%rax),%r9 + movq 16(%rax),%r10 + movq 24(%rax),%r11 + movq 32(%rax),%r12 + movq 40(%rax),%r13 + movq 48(%rax),%r14 + movq 56(%rax),%r15 + + + movq 24(%rsp),%rbx + addq $512,%rbx + + subq 0(%rbx),%r8 + sbbq 8(%rbx),%r9 + sbbq 16(%rbx),%r10 + sbbq 24(%rbx),%r11 + sbbq 32(%rbx),%r12 + sbbq 40(%rbx),%r13 + sbbq 48(%rbx),%r14 + sbbq 56(%rbx),%r15 + + + movq 0(%rax),%rsi + movq 8(%rax),%rdi + movq 16(%rax),%rcx + movq 24(%rax),%rdx + cmovncq %r8,%rsi + cmovncq %r9,%rdi + cmovncq %r10,%rcx + cmovncq %r11,%rdx + movq %rsi,0(%rax) + movq %rdi,8(%rax) + movq %rcx,16(%rax) + movq %rdx,24(%rax) + + movq 32(%rax),%rsi + movq 40(%rax),%rdi + movq 48(%rax),%rcx + movq 56(%rax),%rdx + cmovncq %r12,%rsi + cmovncq %r13,%rdi + cmovncq %r14,%rcx + cmovncq %r15,%rdx + movq %rsi,32(%rax) + movq %rdi,40(%rax) + movq %rcx,48(%rax) + movq %rdx,56(%rax) + + movq 0(%rsp),%rsi + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbx + movq 40(%rsi),%rbp + leaq 48(%rsi),%rsp +L$epilogue: + retq + diff --git a/Libraries/libressl/crypto/bn/modexp512-masm-x86_64.S b/Libraries/libressl/crypto/bn/modexp512-masm-x86_64.S new file mode 100644 index 000000000..9626fe387 --- /dev/null +++ b/Libraries/libressl/crypto/bn/modexp512-masm-x86_64.S @@ -0,0 +1,1859 @@ +; 1 "crypto/bn/modexp512-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/bn/modexp512-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/bn/modexp512-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + + +ALIGN 16 +MULADD_128x512 PROC PRIVATE + mov rax,QWORD PTR[rsi] + mul rbp + add r8,rax + adc rdx,0 + mov QWORD PTR[rcx],r8 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov r8,rdx + mov rbp,QWORD PTR[8+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r9,rax + adc rdx,0 + mov QWORD PTR[8+rcx],r9 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov r9,rdx + DB 0F3h,0C3h ;repret +MULADD_128x512 ENDP + +ALIGN 16 +mont_reduce PROC PRIVATE + lea rdi,QWORD PTR[192+rsp] + mov rsi,QWORD PTR[32+rsp] + add rsi,576 + lea rcx,QWORD PTR[520+rsp] + + mov rbp,QWORD PTR[96+rcx] + mov rax,QWORD PTR[rsi] + mul rbp + mov r8,QWORD PTR[rcx] + add r8,rax + adc rdx,0 + mov QWORD PTR[rdi],r8 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + mov r9,QWORD PTR[8+rcx] + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + mov r10,QWORD PTR[16+rcx] + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + mov r11,QWORD PTR[24+rcx] + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + mov r12,QWORD PTR[32+rcx] + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + mov r13,QWORD PTR[40+rcx] + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + mov r14,QWORD PTR[48+rcx] + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + mov r15,QWORD PTR[56+rcx] + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov r8,rdx + mov rbp,QWORD PTR[104+rcx] + mov rax,QWORD PTR[rsi] + mul rbp + add r9,rax + adc rdx,0 + mov QWORD PTR[8+rdi],r9 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov r9,rdx + mov rbp,QWORD PTR[112+rcx] + mov rax,QWORD PTR[rsi] + mul rbp + add r10,rax + adc rdx,0 + mov QWORD PTR[16+rdi],r10 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov r10,rdx + mov rbp,QWORD PTR[120+rcx] + mov rax,QWORD PTR[rsi] + mul rbp + add r11,rax + adc rdx,0 + mov QWORD PTR[24+rdi],r11 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov r11,rdx + xor rax,rax + + add r8,QWORD PTR[64+rcx] + adc r9,QWORD PTR[72+rcx] + adc r10,QWORD PTR[80+rcx] + adc r11,QWORD PTR[88+rcx] + adc rax,0 + + + + + mov QWORD PTR[64+rdi],r8 + mov QWORD PTR[72+rdi],r9 + mov rbp,r10 + mov QWORD PTR[88+rdi],r11 + + mov QWORD PTR[384+rsp],rax + + mov r8,QWORD PTR[rdi] + mov r9,QWORD PTR[8+rdi] + mov r10,QWORD PTR[16+rdi] + mov r11,QWORD PTR[24+rdi] + + + + + + + + + add rdi,8*10 + + add rsi,64 + lea rcx,QWORD PTR[296+rsp] + + call MULADD_128x512 + + mov rax,QWORD PTR[384+rsp] + + + add r8,QWORD PTR[((-16))+rdi] + adc r9,QWORD PTR[((-8))+rdi] + mov QWORD PTR[64+rcx],r8 + mov QWORD PTR[72+rcx],r9 + + adc rax,rax + mov QWORD PTR[384+rsp],rax + + lea rdi,QWORD PTR[192+rsp] + add rsi,64 + + + + + + mov r8,QWORD PTR[rsi] + mov rbx,QWORD PTR[8+rsi] + + mov rax,QWORD PTR[rcx] + mul r8 + mov rbp,rax + mov r9,rdx + + mov rax,QWORD PTR[8+rcx] + mul r8 + add r9,rax + + mov rax,QWORD PTR[rcx] + mul rbx + add r9,rax + + mov QWORD PTR[8+rdi],r9 + + + sub rsi,192 + + mov r8,QWORD PTR[rcx] + mov r9,QWORD PTR[8+rcx] + + call MULADD_128x512 + + + + + mov rax,QWORD PTR[rsi] + mov rbx,QWORD PTR[8+rsi] + mov rdi,QWORD PTR[16+rsi] + mov rdx,QWORD PTR[24+rsi] + + + mov rbp,QWORD PTR[384+rsp] + + add r8,QWORD PTR[64+rcx] + adc r9,QWORD PTR[72+rcx] + + + adc rbp,rbp + + + + shl rbp,3 + mov rcx,QWORD PTR[32+rsp] + add rbp,rcx + + + xor rsi,rsi + + add r10,QWORD PTR[rbp] + adc r11,QWORD PTR[64+rbp] + adc r12,QWORD PTR[128+rbp] + adc r13,QWORD PTR[192+rbp] + adc r14,QWORD PTR[256+rbp] + adc r15,QWORD PTR[320+rbp] + adc r8,QWORD PTR[384+rbp] + adc r9,QWORD PTR[448+rbp] + + + + sbb rsi,0 + + + and rax,rsi + and rbx,rsi + and rdi,rsi + and rdx,rsi + + mov rbp,1 + sub r10,rax + sbb r11,rbx + sbb r12,rdi + sbb r13,rdx + + + + + sbb rbp,0 + + + + add rcx,512 + mov rax,QWORD PTR[32+rcx] + mov rbx,QWORD PTR[40+rcx] + mov rdi,QWORD PTR[48+rcx] + mov rdx,QWORD PTR[56+rcx] + + + + and rax,rsi + and rbx,rsi + and rdi,rsi + and rdx,rsi + + + + sub rbp,1 + + sbb r14,rax + sbb r15,rbx + sbb r8,rdi + sbb r9,rdx + + + + mov rsi,QWORD PTR[144+rsp] + mov QWORD PTR[rsi],r10 + mov QWORD PTR[8+rsi],r11 + mov QWORD PTR[16+rsi],r12 + mov QWORD PTR[24+rsi],r13 + mov QWORD PTR[32+rsi],r14 + mov QWORD PTR[40+rsi],r15 + mov QWORD PTR[48+rsi],r8 + mov QWORD PTR[56+rsi],r9 + + DB 0F3h,0C3h ;repret +mont_reduce ENDP + +ALIGN 16 +mont_mul_a3b PROC PRIVATE + + + + + mov rbp,QWORD PTR[rdi] + + mov rax,r10 + mul rbp + mov QWORD PTR[520+rsp],rax + mov r10,rdx + mov rax,r11 + mul rbp + add r10,rax + adc rdx,0 + mov r11,rdx + mov rax,r12 + mul rbp + add r11,rax + adc rdx,0 + mov r12,rdx + mov rax,r13 + mul rbp + add r12,rax + adc rdx,0 + mov r13,rdx + mov rax,r14 + mul rbp + add r13,rax + adc rdx,0 + mov r14,rdx + mov rax,r15 + mul rbp + add r14,rax + adc rdx,0 + mov r15,rdx + mov rax,r8 + mul rbp + add r15,rax + adc rdx,0 + mov r8,rdx + mov rax,r9 + mul rbp + add r8,rax + adc rdx,0 + mov r9,rdx + mov rbp,QWORD PTR[8+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r10,rax + adc rdx,0 + mov QWORD PTR[528+rsp],r10 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov r10,rdx + mov rbp,QWORD PTR[16+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r11,rax + adc rdx,0 + mov QWORD PTR[536+rsp],r11 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov r11,rdx + mov rbp,QWORD PTR[24+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r12,rax + adc rdx,0 + mov QWORD PTR[544+rsp],r12 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov r12,rdx + mov rbp,QWORD PTR[32+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r13,rax + adc rdx,0 + mov QWORD PTR[552+rsp],r13 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov r13,rdx + mov rbp,QWORD PTR[40+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r14,rax + adc rdx,0 + mov QWORD PTR[560+rsp],r14 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov r14,rdx + mov rbp,QWORD PTR[48+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r15,rax + adc rdx,0 + mov QWORD PTR[568+rsp],r15 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r8,rax + adc rdx,0 + add r8,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov r15,rdx + mov rbp,QWORD PTR[56+rdi] + mov rax,QWORD PTR[rsi] + mul rbp + add r8,rax + adc rdx,0 + mov QWORD PTR[576+rsp],r8 + mov rbx,rdx + + mov rax,QWORD PTR[8+rsi] + mul rbp + add r9,rax + adc rdx,0 + add r9,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[16+rsi] + mul rbp + add r10,rax + adc rdx,0 + add r10,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[24+rsi] + mul rbp + add r11,rax + adc rdx,0 + add r11,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[32+rsi] + mul rbp + add r12,rax + adc rdx,0 + add r12,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[40+rsi] + mul rbp + add r13,rax + adc rdx,0 + add r13,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[48+rsi] + mul rbp + add r14,rax + adc rdx,0 + add r14,rbx + adc rdx,0 + mov rbx,rdx + + mov rax,QWORD PTR[56+rsi] + mul rbp + add r15,rax + adc rdx,0 + add r15,rbx + adc rdx,0 + mov r8,rdx + mov QWORD PTR[584+rsp],r9 + mov QWORD PTR[592+rsp],r10 + mov QWORD PTR[600+rsp],r11 + mov QWORD PTR[608+rsp],r12 + mov QWORD PTR[616+rsp],r13 + mov QWORD PTR[624+rsp],r14 + mov QWORD PTR[632+rsp],r15 + mov QWORD PTR[640+rsp],r8 + + + + + + jmp mont_reduce + + +mont_mul_a3b ENDP + +ALIGN 16 +sqr_reduce PROC PRIVATE + mov rcx,QWORD PTR[16+rsp] + + + + mov rbx,r10 + + mov rax,r11 + mul rbx + mov QWORD PTR[528+rsp],rax + mov r10,rdx + mov rax,r12 + mul rbx + add r10,rax + adc rdx,0 + mov r11,rdx + mov rax,r13 + mul rbx + add r11,rax + adc rdx,0 + mov r12,rdx + mov rax,r14 + mul rbx + add r12,rax + adc rdx,0 + mov r13,rdx + mov rax,r15 + mul rbx + add r13,rax + adc rdx,0 + mov r14,rdx + mov rax,r8 + mul rbx + add r14,rax + adc rdx,0 + mov r15,rdx + mov rax,r9 + mul rbx + add r15,rax + adc rdx,0 + mov rsi,rdx + + mov QWORD PTR[536+rsp],r10 + + + + + + mov rbx,QWORD PTR[8+rcx] + + mov rax,QWORD PTR[16+rcx] + mul rbx + add r11,rax + adc rdx,0 + mov QWORD PTR[544+rsp],r11 + + mov r10,rdx + mov rax,QWORD PTR[24+rcx] + mul rbx + add r12,rax + adc rdx,0 + add r12,r10 + adc rdx,0 + mov QWORD PTR[552+rsp],r12 + + mov r10,rdx + mov rax,QWORD PTR[32+rcx] + mul rbx + add r13,rax + adc rdx,0 + add r13,r10 + adc rdx,0 + + mov r10,rdx + mov rax,QWORD PTR[40+rcx] + mul rbx + add r14,rax + adc rdx,0 + add r14,r10 + adc rdx,0 + + mov r10,rdx + mov rax,r8 + mul rbx + add r15,rax + adc rdx,0 + add r15,r10 + adc rdx,0 + + mov r10,rdx + mov rax,r9 + mul rbx + add rsi,rax + adc rdx,0 + add rsi,r10 + adc rdx,0 + + mov r11,rdx + + + + + mov rbx,QWORD PTR[16+rcx] + + mov rax,QWORD PTR[24+rcx] + mul rbx + add r13,rax + adc rdx,0 + mov QWORD PTR[560+rsp],r13 + + mov r10,rdx + mov rax,QWORD PTR[32+rcx] + mul rbx + add r14,rax + adc rdx,0 + add r14,r10 + adc rdx,0 + mov QWORD PTR[568+rsp],r14 + + mov r10,rdx + mov rax,QWORD PTR[40+rcx] + mul rbx + add r15,rax + adc rdx,0 + add r15,r10 + adc rdx,0 + + mov r10,rdx + mov rax,r8 + mul rbx + add rsi,rax + adc rdx,0 + add rsi,r10 + adc rdx,0 + + mov r10,rdx + mov rax,r9 + mul rbx + add r11,rax + adc rdx,0 + add r11,r10 + adc rdx,0 + + mov r12,rdx + + + + + + mov rbx,QWORD PTR[24+rcx] + + mov rax,QWORD PTR[32+rcx] + mul rbx + add r15,rax + adc rdx,0 + mov QWORD PTR[576+rsp],r15 + + mov r10,rdx + mov rax,QWORD PTR[40+rcx] + mul rbx + add rsi,rax + adc rdx,0 + add rsi,r10 + adc rdx,0 + mov QWORD PTR[584+rsp],rsi + + mov r10,rdx + mov rax,r8 + mul rbx + add r11,rax + adc rdx,0 + add r11,r10 + adc rdx,0 + + mov r10,rdx + mov rax,r9 + mul rbx + add r12,rax + adc rdx,0 + add r12,r10 + adc rdx,0 + + mov r15,rdx + + + + + mov rbx,QWORD PTR[32+rcx] + + mov rax,QWORD PTR[40+rcx] + mul rbx + add r11,rax + adc rdx,0 + mov QWORD PTR[592+rsp],r11 + + mov r10,rdx + mov rax,r8 + mul rbx + add r12,rax + adc rdx,0 + add r12,r10 + adc rdx,0 + mov QWORD PTR[600+rsp],r12 + + mov r10,rdx + mov rax,r9 + mul rbx + add r15,rax + adc rdx,0 + add r15,r10 + adc rdx,0 + + mov r11,rdx + + + + + mov rbx,QWORD PTR[40+rcx] + + mov rax,r8 + mul rbx + add r15,rax + adc rdx,0 + mov QWORD PTR[608+rsp],r15 + + mov r10,rdx + mov rax,r9 + mul rbx + add r11,rax + adc rdx,0 + add r11,r10 + adc rdx,0 + mov QWORD PTR[616+rsp],r11 + + mov r12,rdx + + + + + mov rbx,r8 + + mov rax,r9 + mul rbx + add r12,rax + adc rdx,0 + mov QWORD PTR[624+rsp],r12 + + mov QWORD PTR[632+rsp],rdx + + + mov r10,QWORD PTR[528+rsp] + mov r11,QWORD PTR[536+rsp] + mov r12,QWORD PTR[544+rsp] + mov r13,QWORD PTR[552+rsp] + mov r14,QWORD PTR[560+rsp] + mov r15,QWORD PTR[568+rsp] + + mov rax,QWORD PTR[24+rcx] + mul rax + mov rdi,rax + mov r8,rdx + + add r10,r10 + adc r11,r11 + adc r12,r12 + adc r13,r13 + adc r14,r14 + adc r15,r15 + adc r8,0 + + mov rax,QWORD PTR[rcx] + mul rax + mov QWORD PTR[520+rsp],rax + mov rbx,rdx + + mov rax,QWORD PTR[8+rcx] + mul rax + + add r10,rbx + adc r11,rax + adc rdx,0 + + mov rbx,rdx + mov QWORD PTR[528+rsp],r10 + mov QWORD PTR[536+rsp],r11 + + mov rax,QWORD PTR[16+rcx] + mul rax + + add r12,rbx + adc r13,rax + adc rdx,0 + + mov rbx,rdx + + mov QWORD PTR[544+rsp],r12 + mov QWORD PTR[552+rsp],r13 + + xor rbp,rbp + add r14,rbx + adc r15,rdi + adc rbp,0 + + mov QWORD PTR[560+rsp],r14 + mov QWORD PTR[568+rsp],r15 + + + + + mov r10,QWORD PTR[576+rsp] + mov r11,QWORD PTR[584+rsp] + mov r12,QWORD PTR[592+rsp] + mov r13,QWORD PTR[600+rsp] + mov r14,QWORD PTR[608+rsp] + mov r15,QWORD PTR[616+rsp] + mov rdi,QWORD PTR[624+rsp] + mov rsi,QWORD PTR[632+rsp] + + mov rax,r9 + mul rax + mov r9,rax + mov rbx,rdx + + add r10,r10 + adc r11,r11 + adc r12,r12 + adc r13,r13 + adc r14,r14 + adc r15,r15 + adc rdi,rdi + adc rsi,rsi + adc rbx,0 + + add r10,rbp + + mov rax,QWORD PTR[32+rcx] + mul rax + + add r10,r8 + adc r11,rax + adc rdx,0 + + mov rbp,rdx + + mov QWORD PTR[576+rsp],r10 + mov QWORD PTR[584+rsp],r11 + + mov rax,QWORD PTR[40+rcx] + mul rax + + add r12,rbp + adc r13,rax + adc rdx,0 + + mov rbp,rdx + + mov QWORD PTR[592+rsp],r12 + mov QWORD PTR[600+rsp],r13 + + mov rax,QWORD PTR[48+rcx] + mul rax + + add r14,rbp + adc r15,rax + adc rdx,0 + + mov QWORD PTR[608+rsp],r14 + mov QWORD PTR[616+rsp],r15 + + add rdi,rdx + adc rsi,r9 + adc rbx,0 + + mov QWORD PTR[624+rsp],rdi + mov QWORD PTR[632+rsp],rsi + mov QWORD PTR[640+rsp],rbx + + jmp mont_reduce + + +sqr_reduce ENDP +PUBLIC mod_exp_512 + +mod_exp_512 PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_mod_exp_512:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + + push rbp + push rbx + push r12 + push r13 + push r14 + push r15 + + + mov r8,rsp + sub rsp,2688 + and rsp,-64 + + + mov QWORD PTR[rsp],r8 + mov QWORD PTR[8+rsp],rdi + mov QWORD PTR[16+rsp],rsi + mov QWORD PTR[24+rsp],rcx +$L$body:: + + + + pxor xmm4,xmm4 + movdqu xmm0,XMMWORD PTR[rsi] + movdqu xmm1,XMMWORD PTR[16+rsi] + movdqu xmm2,XMMWORD PTR[32+rsi] + movdqu xmm3,XMMWORD PTR[48+rsi] + movdqa XMMWORD PTR[512+rsp],xmm4 + movdqa XMMWORD PTR[528+rsp],xmm4 + movdqa XMMWORD PTR[608+rsp],xmm4 + movdqa XMMWORD PTR[624+rsp],xmm4 + movdqa XMMWORD PTR[544+rsp],xmm0 + movdqa XMMWORD PTR[560+rsp],xmm1 + movdqa XMMWORD PTR[576+rsp],xmm2 + movdqa XMMWORD PTR[592+rsp],xmm3 + + + movdqu xmm0,XMMWORD PTR[rdx] + movdqu xmm1,XMMWORD PTR[16+rdx] + movdqu xmm2,XMMWORD PTR[32+rdx] + movdqu xmm3,XMMWORD PTR[48+rdx] + + lea rbx,QWORD PTR[384+rsp] + mov QWORD PTR[136+rsp],rbx + call mont_reduce + + + lea rcx,QWORD PTR[448+rsp] + xor rax,rax + mov QWORD PTR[rcx],rax + mov QWORD PTR[8+rcx],rax + mov QWORD PTR[24+rcx],rax + mov QWORD PTR[32+rcx],rax + mov QWORD PTR[40+rcx],rax + mov QWORD PTR[48+rcx],rax + mov QWORD PTR[56+rcx],rax + mov QWORD PTR[128+rsp],rax + mov QWORD PTR[16+rcx],1 + + lea rbp,QWORD PTR[640+rsp] + mov rsi,rcx + mov rdi,rbp + mov rax,8 +loop_0:: + mov rbx,QWORD PTR[rcx] + mov WORD PTR[rdi],bx + shr rbx,16 + mov WORD PTR[64+rdi],bx + shr rbx,16 + mov WORD PTR[128+rdi],bx + shr rbx,16 + mov WORD PTR[192+rdi],bx + lea rcx,QWORD PTR[8+rcx] + lea rdi,QWORD PTR[256+rdi] + dec rax + jnz loop_0 + mov rax,31 + mov QWORD PTR[32+rsp],rax + mov QWORD PTR[40+rsp],rbp + + mov QWORD PTR[136+rsp],rsi + mov r10,QWORD PTR[rsi] + mov r11,QWORD PTR[8+rsi] + mov r12,QWORD PTR[16+rsi] + mov r13,QWORD PTR[24+rsi] + mov r14,QWORD PTR[32+rsi] + mov r15,QWORD PTR[40+rsi] + mov r8,QWORD PTR[48+rsi] + mov r9,QWORD PTR[56+rsi] +init_loop:: + lea rdi,QWORD PTR[384+rsp] + call mont_mul_a3b + lea rsi,QWORD PTR[448+rsp] + mov rbp,QWORD PTR[40+rsp] + add rbp,2 + mov QWORD PTR[40+rsp],rbp + mov rcx,rsi + mov rax,8 +loop_1:: + mov rbx,QWORD PTR[rcx] + mov WORD PTR[rbp],bx + shr rbx,16 + mov WORD PTR[64+rbp],bx + shr rbx,16 + mov WORD PTR[128+rbp],bx + shr rbx,16 + mov WORD PTR[192+rbp],bx + lea rcx,QWORD PTR[8+rcx] + lea rbp,QWORD PTR[256+rbp] + dec rax + jnz loop_1 + mov rax,QWORD PTR[32+rsp] + sub rax,1 + mov QWORD PTR[32+rsp],rax + jne init_loop + + + + movdqa XMMWORD PTR[64+rsp],xmm0 + movdqa XMMWORD PTR[80+rsp],xmm1 + movdqa XMMWORD PTR[96+rsp],xmm2 + movdqa XMMWORD PTR[112+rsp],xmm3 + + + + + + mov eax,DWORD PTR[126+rsp] + mov rdx,rax + shr rax,11 + and edx,007FFh + mov DWORD PTR[126+rsp],edx + lea rsi,QWORD PTR[640+rax*2+rsp] + mov rdx,QWORD PTR[8+rsp] + mov rbp,4 +loop_2:: + movzx rbx,WORD PTR[192+rsi] + movzx rax,WORD PTR[448+rsi] + shl rbx,16 + shl rax,16 + mov bx,WORD PTR[128+rsi] + mov ax,WORD PTR[384+rsi] + shl rbx,16 + shl rax,16 + mov bx,WORD PTR[64+rsi] + mov ax,WORD PTR[320+rsi] + shl rbx,16 + shl rax,16 + mov bx,WORD PTR[rsi] + mov ax,WORD PTR[256+rsi] + mov QWORD PTR[rdx],rbx + mov QWORD PTR[8+rdx],rax + lea rsi,QWORD PTR[512+rsi] + lea rdx,QWORD PTR[16+rdx] + sub rbp,1 + jnz loop_2 + mov QWORD PTR[48+rsp],505 + + mov rcx,QWORD PTR[8+rsp] + mov QWORD PTR[136+rsp],rcx + mov r10,QWORD PTR[rcx] + mov r11,QWORD PTR[8+rcx] + mov r12,QWORD PTR[16+rcx] + mov r13,QWORD PTR[24+rcx] + mov r14,QWORD PTR[32+rcx] + mov r15,QWORD PTR[40+rcx] + mov r8,QWORD PTR[48+rcx] + mov r9,QWORD PTR[56+rcx] + jmp sqr_2 + +main_loop_a3b:: + call sqr_reduce + call sqr_reduce + call sqr_reduce +sqr_2:: + call sqr_reduce + call sqr_reduce + + + + mov rcx,QWORD PTR[48+rsp] + mov rax,rcx + shr rax,4 + mov edx,DWORD PTR[64+rax*2+rsp] + and rcx,15 + shr rdx,cl + and rdx,01Fh + + lea rsi,QWORD PTR[640+rdx*2+rsp] + lea rdx,QWORD PTR[448+rsp] + mov rdi,rdx + mov rbp,4 +loop_3:: + movzx rbx,WORD PTR[192+rsi] + movzx rax,WORD PTR[448+rsi] + shl rbx,16 + shl rax,16 + mov bx,WORD PTR[128+rsi] + mov ax,WORD PTR[384+rsi] + shl rbx,16 + shl rax,16 + mov bx,WORD PTR[64+rsi] + mov ax,WORD PTR[320+rsi] + shl rbx,16 + shl rax,16 + mov bx,WORD PTR[rsi] + mov ax,WORD PTR[256+rsi] + mov QWORD PTR[rdx],rbx + mov QWORD PTR[8+rdx],rax + lea rsi,QWORD PTR[512+rsi] + lea rdx,QWORD PTR[16+rdx] + sub rbp,1 + jnz loop_3 + mov rsi,QWORD PTR[8+rsp] + call mont_mul_a3b + + + + mov rcx,QWORD PTR[48+rsp] + sub rcx,5 + mov QWORD PTR[48+rsp],rcx + jge main_loop_a3b + + + +end_main_loop_a3b:: + + + mov rdx,QWORD PTR[8+rsp] + pxor xmm4,xmm4 + movdqu xmm0,XMMWORD PTR[rdx] + movdqu xmm1,XMMWORD PTR[16+rdx] + movdqu xmm2,XMMWORD PTR[32+rdx] + movdqu xmm3,XMMWORD PTR[48+rdx] + movdqa XMMWORD PTR[576+rsp],xmm4 + movdqa XMMWORD PTR[592+rsp],xmm4 + movdqa XMMWORD PTR[608+rsp],xmm4 + movdqa XMMWORD PTR[624+rsp],xmm4 + movdqa XMMWORD PTR[512+rsp],xmm0 + movdqa XMMWORD PTR[528+rsp],xmm1 + movdqa XMMWORD PTR[544+rsp],xmm2 + movdqa XMMWORD PTR[560+rsp],xmm3 + call mont_reduce + + + + mov rax,QWORD PTR[8+rsp] + mov r8,QWORD PTR[rax] + mov r9,QWORD PTR[8+rax] + mov r10,QWORD PTR[16+rax] + mov r11,QWORD PTR[24+rax] + mov r12,QWORD PTR[32+rax] + mov r13,QWORD PTR[40+rax] + mov r14,QWORD PTR[48+rax] + mov r15,QWORD PTR[56+rax] + + + mov rbx,QWORD PTR[24+rsp] + add rbx,512 + + sub r8,QWORD PTR[rbx] + sbb r9,QWORD PTR[8+rbx] + sbb r10,QWORD PTR[16+rbx] + sbb r11,QWORD PTR[24+rbx] + sbb r12,QWORD PTR[32+rbx] + sbb r13,QWORD PTR[40+rbx] + sbb r14,QWORD PTR[48+rbx] + sbb r15,QWORD PTR[56+rbx] + + + mov rsi,QWORD PTR[rax] + mov rdi,QWORD PTR[8+rax] + mov rcx,QWORD PTR[16+rax] + mov rdx,QWORD PTR[24+rax] + cmovnc rsi,r8 + cmovnc rdi,r9 + cmovnc rcx,r10 + cmovnc rdx,r11 + mov QWORD PTR[rax],rsi + mov QWORD PTR[8+rax],rdi + mov QWORD PTR[16+rax],rcx + mov QWORD PTR[24+rax],rdx + + mov rsi,QWORD PTR[32+rax] + mov rdi,QWORD PTR[40+rax] + mov rcx,QWORD PTR[48+rax] + mov rdx,QWORD PTR[56+rax] + cmovnc rsi,r12 + cmovnc rdi,r13 + cmovnc rcx,r14 + cmovnc rdx,r15 + mov QWORD PTR[32+rax],rsi + mov QWORD PTR[40+rax],rdi + mov QWORD PTR[48+rax],rcx + mov QWORD PTR[56+rax],rdx + + mov rsi,QWORD PTR[rsp] + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbx,QWORD PTR[32+rsi] + mov rbp,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_mod_exp_512:: +mod_exp_512 ENDP + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/bn/mont-elf-armv4.S b/Libraries/libressl/crypto/bn/mont-elf-armv4.S new file mode 100644 index 000000000..136da6281 --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont-elf-armv4.S @@ -0,0 +1,148 @@ +.text + +.global bn_mul_mont +.type bn_mul_mont,%function + +.align 2 +bn_mul_mont: + stmdb sp!,{r0,r2} @ sp points at argument block + ldr r0,[sp,#3*4] @ load num + cmp r0,#2 + movlt r0,#0 + addlt sp,sp,#2*4 + blt .Labrt + + stmdb sp!,{r4-r12,lr} @ save 10 registers + + mov r0,r0,lsl#2 @ rescale r0 for byte count + sub sp,sp,r0 @ alloca(4*num) + sub sp,sp,#4 @ +extra dword + sub r0,r0,#4 @ "num=num-1" + add r4,r2,r0 @ &bp[num-1] + + add r0,sp,r0 @ r0 to point at &tp[num-1] + ldr r8,[r0,#14*4] @ &n0 + ldr r2,[r2] @ bp[0] + ldr r5,[r1],#4 @ ap[0],ap++ + ldr r6,[r3],#4 @ np[0],np++ + ldr r8,[r8] @ *n0 + str r4,[r0,#15*4] @ save &bp[num] + + umull r10,r11,r5,r2 @ ap[0]*bp[0] + str r8,[r0,#14*4] @ save n0 value + mul r8,r10,r8 @ "tp[0]"*n0 + mov r12,#0 + umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]" + mov r4,sp + +.L1st: + ldr r5,[r1],#4 @ ap[j],ap++ + mov r10,r11 + ldr r6,[r3],#4 @ np[j],np++ + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[j]*bp[0] + mov r14,#0 + umlal r12,r14,r6,r8 @ np[j]*n0 + adds r12,r12,r10 + str r12,[r4],#4 @ tp[j-1]=,tp++ + adc r12,r14,#0 + cmp r4,r0 + bne .L1st + + adds r12,r12,r11 + ldr r4,[r0,#13*4] @ restore bp + mov r14,#0 + ldr r8,[r0,#14*4] @ restore n0 + adc r14,r14,#0 + str r12,[r0] @ tp[num-1]= + str r14,[r0,#4] @ tp[num]= + +.Louter: + sub r7,r0,sp @ "original" r0-1 value + sub r1,r1,r7 @ "rewind" ap to &ap[1] + ldr r2,[r4,#4]! @ *(++bp) + sub r3,r3,r7 @ "rewind" np to &np[1] + ldr r5,[r1,#-4] @ ap[0] + ldr r10,[sp] @ tp[0] + ldr r6,[r3,#-4] @ np[0] + ldr r7,[sp,#4] @ tp[1] + + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0] + str r4,[r0,#13*4] @ save bp + mul r8,r10,r8 + mov r12,#0 + umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]" + mov r4,sp + +.Linner: + ldr r5,[r1],#4 @ ap[j],ap++ + adds r10,r11,r7 @ +=tp[j] + ldr r6,[r3],#4 @ np[j],np++ + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[j]*bp[i] + mov r14,#0 + umlal r12,r14,r6,r8 @ np[j]*n0 + adc r11,r11,#0 + ldr r7,[r4,#8] @ tp[j+1] + adds r12,r12,r10 + str r12,[r4],#4 @ tp[j-1]=,tp++ + adc r12,r14,#0 + cmp r4,r0 + bne .Linner + + adds r12,r12,r11 + mov r14,#0 + ldr r4,[r0,#13*4] @ restore bp + adc r14,r14,#0 + ldr r8,[r0,#14*4] @ restore n0 + adds r12,r12,r7 + ldr r7,[r0,#15*4] @ restore &bp[num] + adc r14,r14,#0 + str r12,[r0] @ tp[num-1]= + str r14,[r0,#4] @ tp[num]= + + cmp r4,r7 + bne .Louter + + ldr r2,[r0,#12*4] @ pull rp + add r0,r0,#4 @ r0 to point at &tp[num] + sub r5,r0,sp @ "original" num value + mov r4,sp @ "rewind" r4 + mov r1,r4 @ "borrow" r1 + sub r3,r3,r5 @ "rewind" r3 to &np[0] + + subs r7,r7,r7 @ "clear" carry flag +.Lsub: ldr r7,[r4],#4 + ldr r6,[r3],#4 + sbcs r7,r7,r6 @ tp[j]-np[j] + str r7,[r2],#4 @ rp[j]= + teq r4,r0 @ preserve carry + bne .Lsub + sbcs r14,r14,#0 @ upmost carry + mov r4,sp @ "rewind" r4 + sub r2,r2,r5 @ "rewind" r2 + + and r1,r4,r14 + bic r3,r2,r14 + orr r1,r1,r3 @ ap=borrow?tp:rp + +.Lcopy: ldr r7,[r1],#4 @ copy or in-place refresh + str sp,[r4],#4 @ zap tp + str r7,[r2],#4 + cmp r4,r0 + bne .Lcopy + + add sp,r0,#4 @ skip over tp[num+1] + ldmia sp!,{r4-r12,lr} @ restore registers + add sp,sp,#2*4 @ skip over {r0,r2} + mov r0,#1 +.Labrt: tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + .word 0xe12fff1e @ interoperable with Thumb ISA:-) +.size bn_mul_mont,.-bn_mul_mont +.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by " +.align 2 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/mont-elf-x86_64.S b/Libraries/libressl/crypto/bn/mont-elf-x86_64.S new file mode 100644 index 000000000..7847a1905 --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont-elf-x86_64.S @@ -0,0 +1,1379 @@ +#include "x86_arch.h" +.text + +.globl bn_mul_mont +.type bn_mul_mont,@function +.align 16 +bn_mul_mont: + endbr64 + testl $3,%r9d + jnz .Lmul_enter + cmpl $8,%r9d + jb .Lmul_enter + cmpq %rsi,%rdx + jne .Lmul4x_enter + jmp .Lsqr4x_enter + +.align 16 +.Lmul_enter: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movl %r9d,%r9d + leaq 2(%r9),%r10 + movq %rsp,%r11 + negq %r10 + leaq (%rsp,%r10,8),%rsp + andq $-1024,%rsp + + movq %r11,8(%rsp,%r9,8) +.Lmul_body: + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .L1st_enter + +.align 16 +.L1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.L1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jl .L1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp .Louter +.align 16 +.Louter: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .Linner_enter + +.align 16 +.Linner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.Linner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jl .Linner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jl .Louter + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp .Lsub +.align 16 +.Lsub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz .Lsub + + sbbq $0,%rax + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + movq %r9,%r15 + orq %rcx,%rsi +.align 16 +.Lcopy: + movq (%rsi,%r14,8),%rax + movq %r14,(%rsp,%r14,8) + movq %rax,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz .Lcopy + + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lmul_epilogue: + retq +.size bn_mul_mont,.-bn_mul_mont +.type bn_mul4x_mont,@function +.align 16 +bn_mul4x_mont: +.Lmul4x_enter: + endbr64 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movl %r9d,%r9d + leaq 4(%r9),%r10 + movq %rsp,%r11 + negq %r10 + leaq (%rsp,%r10,8),%rsp + andq $-1024,%rsp + + movq %r11,8(%rsp,%r9,8) +.Lmul4x_body: + movq %rdi,16(%rsp,%r9,8) + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .L1st4x +.align 16 +.L1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl .L1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.align 4 +.Louter4x: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .Linner4x +.align 16 +.Linner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl .Linner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jl .Louter4x + movq 16(%rsp,%r9,8),%rdi + movq 0(%rsp),%rax + pxor %xmm0,%xmm0 + movq 8(%rsp),%rdx + shrq $2,%r9 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + leaq -1(%r9),%r15 + jmp .Lsub4x +.align 16 +.Lsub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz .Lsub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + leaq -1(%r9),%r15 + orq %rcx,%rsi + + movdqu (%rsi),%xmm1 + movdqa %xmm0,(%rsp) + movdqu %xmm1,(%rdi) + jmp .Lcopy4x +.align 16 +.Lcopy4x: + movdqu 16(%rsi,%r14,1),%xmm2 + movdqu 32(%rsi,%r14,1),%xmm1 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movdqa %xmm0,32(%rsp,%r14,1) + movdqu %xmm1,32(%rdi,%r14,1) + leaq 32(%r14),%r14 + decq %r15 + jnz .Lcopy4x + + shlq $2,%r9 + movdqu 16(%rsi,%r14,1),%xmm2 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lmul4x_epilogue: + retq +.size bn_mul4x_mont,.-bn_mul4x_mont +.type bn_sqr4x_mont,@function +.align 16 +bn_sqr4x_mont: +.Lsqr4x_enter: + endbr64 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + shll $3,%r9d + xorq %r10,%r10 + movq %rsp,%r11 + subq %r9,%r10 + movq (%r8),%r8 + leaq -72(%rsp,%r10,2),%rsp + andq $-1024,%rsp + + + + + + + + + + + + movq %rdi,32(%rsp) + movq %rcx,40(%rsp) + movq %r8,48(%rsp) + movq %r11,56(%rsp) +.Lsqr4x_body: + + + + + + + + leaq 32(%r10),%rbp + leaq (%rsi,%r9,1),%rsi + + movq %r9,%rcx + + + movq -32(%rsi,%rbp,1),%r14 + leaq 64(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + xorq %r10,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,-16(%rdi,%rbp,1) + + leaq -16(%rbp),%rcx + + + movq 8(%rsi,%rcx,1),%rbx + mulq %r15 + movq %rax,%r12 + movq %rbx,%rax + movq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + leaq 16(%rcx),%rcx + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi,%rcx,1) + jmp .Lsqr4x_1st + +.align 16 +.Lsqr4x_1st: + movq (%rsi,%rcx,1),%rbx + xorq %r12,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,(%rdi,%rcx,1) + + + movq 8(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,8(%rdi,%rcx,1) + + movq 16(%rsi,%rcx,1),%rbx + xorq %r12,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,16(%rdi,%rcx,1) + + + movq 24(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + leaq 32(%rcx),%rcx + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne .Lsqr4x_1st + + xorq %r12,%r12 + addq %r11,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + adcq %rdx,%r12 + + movq %r13,(%rdi) + leaq 16(%rbp),%rbp + movq %r12,8(%rdi) + jmp .Lsqr4x_outer + +.align 16 +.Lsqr4x_outer: + movq -32(%rsi,%rbp,1),%r14 + leaq 64(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + movq -24(%rdi,%rbp,1),%r10 + xorq %r11,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + xorq %r10,%r10 + addq -16(%rdi,%rbp,1),%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,-16(%rdi,%rbp,1) + + leaq -16(%rbp),%rcx + xorq %r12,%r12 + + + movq 8(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq 8(%rdi,%rcx,1),%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,8(%rdi,%rcx,1) + + leaq 16(%rcx),%rcx + jmp .Lsqr4x_inner + +.align 16 +.Lsqr4x_inner: + movq (%rsi,%rcx,1),%rbx + xorq %r12,%r12 + addq (%rdi,%rcx,1),%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,(%rdi,%rcx,1) + + movq 8(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq 8(%rdi,%rcx,1),%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + leaq 16(%rcx),%rcx + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne .Lsqr4x_inner + + xorq %r12,%r12 + addq %r11,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + adcq %rdx,%r12 + + movq %r13,(%rdi) + movq %r12,8(%rdi) + + addq $16,%rbp + jnz .Lsqr4x_outer + + + movq -32(%rsi),%r14 + leaq 64(%rsp,%r9,2),%rdi + movq -24(%rsi),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi),%rbx + movq %rax,%r15 + + xorq %r11,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-24(%rdi) + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,-16(%rdi) + + movq -8(%rsi),%rbx + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq $0,%rdx + + xorq %r11,%r11 + addq %r12,%r10 + movq %rdx,%r13 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi) + + xorq %r12,%r12 + addq %r11,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq -16(%rsi),%rax + adcq %rdx,%r12 + + movq %r13,(%rdi) + movq %r12,8(%rdi) + + mulq %rbx + addq $16,%rbp + xorq %r14,%r14 + subq %r9,%rbp + xorq %r15,%r15 + + addq %r12,%rax + adcq $0,%rdx + movq %rax,8(%rdi) + movq %rdx,16(%rdi) + movq %r15,24(%rdi) + + movq -16(%rsi,%rbp,1),%rax + leaq 64(%rsp,%r9,2),%rdi + xorq %r10,%r10 + movq -24(%rdi,%rbp,2),%r11 + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi,%rbp,2),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi,%rbp,2) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi,%rbp,2),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi,%rbp,2) + adcq %rdx,%r8 + leaq 16(%rbp),%rbp + movq %r8,-40(%rdi,%rbp,2) + sbbq %r15,%r15 + jmp .Lsqr4x_shift_n_add + +.align 16 +.Lsqr4x_shift_n_add: + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi,%rbp,2),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi,%rbp,2) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi,%rbp,2),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi,%rbp,2) + adcq %rdx,%r8 + + leaq (%r14,%r10,2),%r12 + movq %r8,-8(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi,%rbp,2),%r11 + adcq %rax,%r12 + movq 8(%rsi,%rbp,1),%rax + movq %r12,0(%rdi,%rbp,2) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi,%rbp,2),%r11 + adcq %rax,%rbx + movq 16(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi,%rbp,2) + adcq %rdx,%r8 + movq %r8,24(%rdi,%rbp,2) + sbbq %r15,%r15 + addq $32,%rbp + jnz .Lsqr4x_shift_n_add + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + mulq %rax + negq %r15 + adcq %rax,%rbx + adcq %rdx,%r8 + movq %rbx,-16(%rdi) + movq %r8,-8(%rdi) + movq 40(%rsp),%rsi + movq 48(%rsp),%r8 + xorq %rcx,%rcx + movq %r9,0(%rsp) + subq %r9,%rcx + movq 64(%rsp),%r10 + movq %r8,%r14 + leaq 64(%rsp,%r9,2),%rax + leaq 64(%rsp,%r9,1),%rdi + movq %rax,8(%rsp) + leaq (%rsi,%r9,1),%rsi + xorq %rbp,%rbp + + movq 0(%rsi,%rcx,1),%rax + movq 8(%rsi,%rcx,1),%r9 + imulq %r10,%r14 + movq %rax,%rbx + jmp .Lsqr4x_mont_outer + +.align 16 +.Lsqr4x_mont_outer: + xorq %r11,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + movq %r8,%r15 + + xorq %r10,%r10 + addq 8(%rdi,%rcx,1),%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + + imulq %r11,%r15 + + movq 16(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + movq %r12,8(%rdi,%rcx,1) + + xorq %r11,%r11 + addq 16(%rdi,%rcx,1),%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + + movq 24(%rsi,%rcx,1),%r9 + xorq %r12,%r12 + addq %r10,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %r9,%rax + adcq %rdx,%r12 + movq %r13,16(%rdi,%rcx,1) + + xorq %r10,%r10 + addq 24(%rdi,%rcx,1),%r11 + leaq 32(%rcx),%rcx + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + jmp .Lsqr4x_mont_inner + +.align 16 +.Lsqr4x_mont_inner: + movq (%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + movq %r12,-8(%rdi,%rcx,1) + + xorq %r11,%r11 + addq (%rdi,%rcx,1),%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + + movq 8(%rsi,%rcx,1),%r9 + xorq %r12,%r12 + addq %r10,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %r9,%rax + adcq %rdx,%r12 + movq %r13,(%rdi,%rcx,1) + + xorq %r10,%r10 + addq 8(%rdi,%rcx,1),%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + + + movq 16(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + movq %r12,8(%rdi,%rcx,1) + + xorq %r11,%r11 + addq 16(%rdi,%rcx,1),%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + + movq 24(%rsi,%rcx,1),%r9 + xorq %r12,%r12 + addq %r10,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %r9,%rax + adcq %rdx,%r12 + movq %r13,16(%rdi,%rcx,1) + + xorq %r10,%r10 + addq 24(%rdi,%rcx,1),%r11 + leaq 32(%rcx),%rcx + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + cmpq $0,%rcx + jne .Lsqr4x_mont_inner + + subq 0(%rsp),%rcx + movq %r8,%r14 + + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + movq %r12,-8(%rdi) + + xorq %r11,%r11 + addq (%rdi),%r10 + adcq $0,%r11 + movq 0(%rsi,%rcx,1),%rbx + addq %rbp,%r10 + adcq $0,%r11 + + imulq 16(%rdi,%rcx,1),%r14 + xorq %r12,%r12 + movq 8(%rsi,%rcx,1),%r9 + addq %r10,%r13 + movq 16(%rdi,%rcx,1),%r10 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + movq %r13,(%rdi) + + xorq %rbp,%rbp + addq 8(%rdi),%r12 + adcq %rbp,%rbp + addq %r11,%r12 + leaq 16(%rdi),%rdi + adcq $0,%rbp + movq %r12,-8(%rdi) + cmpq 8(%rsp),%rdi + jb .Lsqr4x_mont_outer + + movq 0(%rsp),%r9 + movq %rbp,(%rdi) + movq 64(%rsp,%r9,1),%rax + leaq 64(%rsp,%r9,1),%rbx + movq 40(%rsp),%rsi + shrq $5,%r9 + movq 8(%rbx),%rdx + xorq %rbp,%rbp + + movq 32(%rsp),%rdi + subq 0(%rsi),%rax + movq 16(%rbx),%r10 + movq 24(%rbx),%r11 + sbbq 8(%rsi),%rdx + leaq -1(%r9),%rcx + jmp .Lsqr4x_sub +.align 16 +.Lsqr4x_sub: + movq %rax,0(%rdi,%rbp,8) + movq %rdx,8(%rdi,%rbp,8) + sbbq 16(%rsi,%rbp,8),%r10 + movq 32(%rbx,%rbp,8),%rax + movq 40(%rbx,%rbp,8),%rdx + sbbq 24(%rsi,%rbp,8),%r11 + movq %r10,16(%rdi,%rbp,8) + movq %r11,24(%rdi,%rbp,8) + sbbq 32(%rsi,%rbp,8),%rax + movq 48(%rbx,%rbp,8),%r10 + movq 56(%rbx,%rbp,8),%r11 + sbbq 40(%rsi,%rbp,8),%rdx + leaq 4(%rbp),%rbp + decq %rcx + jnz .Lsqr4x_sub + + movq %rax,0(%rdi,%rbp,8) + movq 32(%rbx,%rbp,8),%rax + sbbq 16(%rsi,%rbp,8),%r10 + movq %rdx,8(%rdi,%rbp,8) + sbbq 24(%rsi,%rbp,8),%r11 + movq %r10,16(%rdi,%rbp,8) + + sbbq $0,%rax + movq %r11,24(%rdi,%rbp,8) + xorq %rbp,%rbp + andq %rax,%rbx + notq %rax + movq %rdi,%rsi + andq %rax,%rsi + leaq -1(%r9),%rcx + orq %rsi,%rbx + + pxor %xmm0,%xmm0 + leaq 64(%rsp,%r9,8),%rsi + movdqu (%rbx),%xmm1 + leaq (%rsi,%r9,8),%rsi + movdqa %xmm0,64(%rsp) + movdqa %xmm0,(%rsi) + movdqu %xmm1,(%rdi) + jmp .Lsqr4x_copy +.align 16 +.Lsqr4x_copy: + movdqu 16(%rbx,%rbp,1),%xmm2 + movdqu 32(%rbx,%rbp,1),%xmm1 + movdqa %xmm0,80(%rsp,%rbp,1) + movdqa %xmm0,96(%rsp,%rbp,1) + movdqa %xmm0,16(%rsi,%rbp,1) + movdqa %xmm0,32(%rsi,%rbp,1) + movdqu %xmm2,16(%rdi,%rbp,1) + movdqu %xmm1,32(%rdi,%rbp,1) + leaq 32(%rbp),%rbp + decq %rcx + jnz .Lsqr4x_copy + + movdqu 16(%rbx,%rbp,1),%xmm2 + movdqa %xmm0,80(%rsp,%rbp,1) + movdqa %xmm0,16(%rsi,%rbp,1) + movdqu %xmm2,16(%rdi,%rbp,1) + movq 56(%rsp),%rsi + movq $1,%rax + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lsqr4x_epilogue: + retq +.size bn_sqr4x_mont,.-bn_sqr4x_mont +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/mont-macosx-x86_64.S b/Libraries/libressl/crypto/bn/mont-macosx-x86_64.S new file mode 100644 index 000000000..7de69d906 --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont-macosx-x86_64.S @@ -0,0 +1,1375 @@ +#include "x86_arch.h" +.text + +.globl _bn_mul_mont + +.p2align 4 +_bn_mul_mont: + testl $3,%r9d + jnz L$mul_enter + cmpl $8,%r9d + jb L$mul_enter + cmpq %rsi,%rdx + jne L$mul4x_enter + jmp L$sqr4x_enter + +.p2align 4 +L$mul_enter: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movl %r9d,%r9d + leaq 2(%r9),%r10 + movq %rsp,%r11 + negq %r10 + leaq (%rsp,%r10,8),%rsp + andq $-1024,%rsp + + movq %r11,8(%rsp,%r9,8) +L$mul_body: + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$1st_enter + +.p2align 4 +L$1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jl L$1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp L$outer +.p2align 4 +L$outer: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$inner_enter + +.p2align 4 +L$inner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$inner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jl L$inner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jl L$outer + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp L$sub +.p2align 4 +L$sub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz L$sub + + sbbq $0,%rax + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + movq %r9,%r15 + orq %rcx,%rsi +.p2align 4 +L$copy: + movq (%rsi,%r14,8),%rax + movq %r14,(%rsp,%r14,8) + movq %rax,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz L$copy + + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$mul_epilogue: + retq + + +.p2align 4 +bn_mul4x_mont: +L$mul4x_enter: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movl %r9d,%r9d + leaq 4(%r9),%r10 + movq %rsp,%r11 + negq %r10 + leaq (%rsp,%r10,8),%rsp + andq $-1024,%rsp + + movq %r11,8(%rsp,%r9,8) +L$mul4x_body: + movq %rdi,16(%rsp,%r9,8) + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp L$1st4x +.p2align 4 +L$1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl L$1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.p2align 2 +L$outer4x: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp L$inner4x +.p2align 4 +L$inner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl L$inner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jl L$outer4x + movq 16(%rsp,%r9,8),%rdi + movq 0(%rsp),%rax + pxor %xmm0,%xmm0 + movq 8(%rsp),%rdx + shrq $2,%r9 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + leaq -1(%r9),%r15 + jmp L$sub4x +.p2align 4 +L$sub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz L$sub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + leaq -1(%r9),%r15 + orq %rcx,%rsi + + movdqu (%rsi),%xmm1 + movdqa %xmm0,(%rsp) + movdqu %xmm1,(%rdi) + jmp L$copy4x +.p2align 4 +L$copy4x: + movdqu 16(%rsi,%r14,1),%xmm2 + movdqu 32(%rsi,%r14,1),%xmm1 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movdqa %xmm0,32(%rsp,%r14,1) + movdqu %xmm1,32(%rdi,%r14,1) + leaq 32(%r14),%r14 + decq %r15 + jnz L$copy4x + + shlq $2,%r9 + movdqu 16(%rsi,%r14,1),%xmm2 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$mul4x_epilogue: + retq + + +.p2align 4 +bn_sqr4x_mont: +L$sqr4x_enter: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + shll $3,%r9d + xorq %r10,%r10 + movq %rsp,%r11 + subq %r9,%r10 + movq (%r8),%r8 + leaq -72(%rsp,%r10,2),%rsp + andq $-1024,%rsp + + + + + + + + + + + + movq %rdi,32(%rsp) + movq %rcx,40(%rsp) + movq %r8,48(%rsp) + movq %r11,56(%rsp) +L$sqr4x_body: + + + + + + + + leaq 32(%r10),%rbp + leaq (%rsi,%r9,1),%rsi + + movq %r9,%rcx + + + movq -32(%rsi,%rbp,1),%r14 + leaq 64(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + xorq %r10,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,-16(%rdi,%rbp,1) + + leaq -16(%rbp),%rcx + + + movq 8(%rsi,%rcx,1),%rbx + mulq %r15 + movq %rax,%r12 + movq %rbx,%rax + movq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + leaq 16(%rcx),%rcx + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi,%rcx,1) + jmp L$sqr4x_1st + +.p2align 4 +L$sqr4x_1st: + movq (%rsi,%rcx,1),%rbx + xorq %r12,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,(%rdi,%rcx,1) + + + movq 8(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,8(%rdi,%rcx,1) + + movq 16(%rsi,%rcx,1),%rbx + xorq %r12,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,16(%rdi,%rcx,1) + + + movq 24(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + leaq 32(%rcx),%rcx + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne L$sqr4x_1st + + xorq %r12,%r12 + addq %r11,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + adcq %rdx,%r12 + + movq %r13,(%rdi) + leaq 16(%rbp),%rbp + movq %r12,8(%rdi) + jmp L$sqr4x_outer + +.p2align 4 +L$sqr4x_outer: + movq -32(%rsi,%rbp,1),%r14 + leaq 64(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + movq -24(%rdi,%rbp,1),%r10 + xorq %r11,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + xorq %r10,%r10 + addq -16(%rdi,%rbp,1),%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,-16(%rdi,%rbp,1) + + leaq -16(%rbp),%rcx + xorq %r12,%r12 + + + movq 8(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq 8(%rdi,%rcx,1),%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,8(%rdi,%rcx,1) + + leaq 16(%rcx),%rcx + jmp L$sqr4x_inner + +.p2align 4 +L$sqr4x_inner: + movq (%rsi,%rcx,1),%rbx + xorq %r12,%r12 + addq (%rdi,%rcx,1),%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,(%rdi,%rcx,1) + + movq 8(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq 8(%rdi,%rcx,1),%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + + xorq %r11,%r11 + addq %r12,%r10 + leaq 16(%rcx),%rcx + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne L$sqr4x_inner + + xorq %r12,%r12 + addq %r11,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + adcq %rdx,%r12 + + movq %r13,(%rdi) + movq %r12,8(%rdi) + + addq $16,%rbp + jnz L$sqr4x_outer + + + movq -32(%rsi),%r14 + leaq 64(%rsp,%r9,2),%rdi + movq -24(%rsi),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi),%rbx + movq %rax,%r15 + + xorq %r11,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-24(%rdi) + + xorq %r10,%r10 + addq %r13,%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + movq %r11,-16(%rdi) + + movq -8(%rsi),%rbx + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq $0,%rdx + + xorq %r11,%r11 + addq %r12,%r10 + movq %rdx,%r13 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq %rdx,%r11 + movq %r10,-8(%rdi) + + xorq %r12,%r12 + addq %r11,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq -16(%rsi),%rax + adcq %rdx,%r12 + + movq %r13,(%rdi) + movq %r12,8(%rdi) + + mulq %rbx + addq $16,%rbp + xorq %r14,%r14 + subq %r9,%rbp + xorq %r15,%r15 + + addq %r12,%rax + adcq $0,%rdx + movq %rax,8(%rdi) + movq %rdx,16(%rdi) + movq %r15,24(%rdi) + + movq -16(%rsi,%rbp,1),%rax + leaq 64(%rsp,%r9,2),%rdi + xorq %r10,%r10 + movq -24(%rdi,%rbp,2),%r11 + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi,%rbp,2),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi,%rbp,2) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi,%rbp,2),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi,%rbp,2) + adcq %rdx,%r8 + leaq 16(%rbp),%rbp + movq %r8,-40(%rdi,%rbp,2) + sbbq %r15,%r15 + jmp L$sqr4x_shift_n_add + +.p2align 4 +L$sqr4x_shift_n_add: + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi,%rbp,2),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi,%rbp,2) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi,%rbp,2),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi,%rbp,2) + adcq %rdx,%r8 + + leaq (%r14,%r10,2),%r12 + movq %r8,-8(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi,%rbp,2),%r11 + adcq %rax,%r12 + movq 8(%rsi,%rbp,1),%rax + movq %r12,0(%rdi,%rbp,2) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi,%rbp,2) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi,%rbp,2),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi,%rbp,2),%r11 + adcq %rax,%rbx + movq 16(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi,%rbp,2) + adcq %rdx,%r8 + movq %r8,24(%rdi,%rbp,2) + sbbq %r15,%r15 + addq $32,%rbp + jnz L$sqr4x_shift_n_add + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + mulq %rax + negq %r15 + adcq %rax,%rbx + adcq %rdx,%r8 + movq %rbx,-16(%rdi) + movq %r8,-8(%rdi) + movq 40(%rsp),%rsi + movq 48(%rsp),%r8 + xorq %rcx,%rcx + movq %r9,0(%rsp) + subq %r9,%rcx + movq 64(%rsp),%r10 + movq %r8,%r14 + leaq 64(%rsp,%r9,2),%rax + leaq 64(%rsp,%r9,1),%rdi + movq %rax,8(%rsp) + leaq (%rsi,%r9,1),%rsi + xorq %rbp,%rbp + + movq 0(%rsi,%rcx,1),%rax + movq 8(%rsi,%rcx,1),%r9 + imulq %r10,%r14 + movq %rax,%rbx + jmp L$sqr4x_mont_outer + +.p2align 4 +L$sqr4x_mont_outer: + xorq %r11,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + movq %r8,%r15 + + xorq %r10,%r10 + addq 8(%rdi,%rcx,1),%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + + imulq %r11,%r15 + + movq 16(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + movq %r12,8(%rdi,%rcx,1) + + xorq %r11,%r11 + addq 16(%rdi,%rcx,1),%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + + movq 24(%rsi,%rcx,1),%r9 + xorq %r12,%r12 + addq %r10,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %r9,%rax + adcq %rdx,%r12 + movq %r13,16(%rdi,%rcx,1) + + xorq %r10,%r10 + addq 24(%rdi,%rcx,1),%r11 + leaq 32(%rcx),%rcx + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + jmp L$sqr4x_mont_inner + +.p2align 4 +L$sqr4x_mont_inner: + movq (%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + movq %r12,-8(%rdi,%rcx,1) + + xorq %r11,%r11 + addq (%rdi,%rcx,1),%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + + movq 8(%rsi,%rcx,1),%r9 + xorq %r12,%r12 + addq %r10,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %r9,%rax + adcq %rdx,%r12 + movq %r13,(%rdi,%rcx,1) + + xorq %r10,%r10 + addq 8(%rdi,%rcx,1),%r11 + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + + + movq 16(%rsi,%rcx,1),%rbx + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq %rdx,%r13 + movq %r12,8(%rdi,%rcx,1) + + xorq %r11,%r11 + addq 16(%rdi,%rcx,1),%r10 + adcq $0,%r11 + mulq %r14 + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + + movq 24(%rsi,%rcx,1),%r9 + xorq %r12,%r12 + addq %r10,%r13 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %r9,%rax + adcq %rdx,%r12 + movq %r13,16(%rdi,%rcx,1) + + xorq %r10,%r10 + addq 24(%rdi,%rcx,1),%r11 + leaq 32(%rcx),%rcx + adcq $0,%r10 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq %rdx,%r10 + cmpq $0,%rcx + jne L$sqr4x_mont_inner + + subq 0(%rsp),%rcx + movq %r8,%r14 + + xorq %r13,%r13 + addq %r11,%r12 + adcq $0,%r13 + mulq %r15 + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + movq %r12,-8(%rdi) + + xorq %r11,%r11 + addq (%rdi),%r10 + adcq $0,%r11 + movq 0(%rsi,%rcx,1),%rbx + addq %rbp,%r10 + adcq $0,%r11 + + imulq 16(%rdi,%rcx,1),%r14 + xorq %r12,%r12 + movq 8(%rsi,%rcx,1),%r9 + addq %r10,%r13 + movq 16(%rdi,%rcx,1),%r10 + adcq $0,%r12 + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + adcq %rdx,%r12 + movq %r13,(%rdi) + + xorq %rbp,%rbp + addq 8(%rdi),%r12 + adcq %rbp,%rbp + addq %r11,%r12 + leaq 16(%rdi),%rdi + adcq $0,%rbp + movq %r12,-8(%rdi) + cmpq 8(%rsp),%rdi + jb L$sqr4x_mont_outer + + movq 0(%rsp),%r9 + movq %rbp,(%rdi) + movq 64(%rsp,%r9,1),%rax + leaq 64(%rsp,%r9,1),%rbx + movq 40(%rsp),%rsi + shrq $5,%r9 + movq 8(%rbx),%rdx + xorq %rbp,%rbp + + movq 32(%rsp),%rdi + subq 0(%rsi),%rax + movq 16(%rbx),%r10 + movq 24(%rbx),%r11 + sbbq 8(%rsi),%rdx + leaq -1(%r9),%rcx + jmp L$sqr4x_sub +.p2align 4 +L$sqr4x_sub: + movq %rax,0(%rdi,%rbp,8) + movq %rdx,8(%rdi,%rbp,8) + sbbq 16(%rsi,%rbp,8),%r10 + movq 32(%rbx,%rbp,8),%rax + movq 40(%rbx,%rbp,8),%rdx + sbbq 24(%rsi,%rbp,8),%r11 + movq %r10,16(%rdi,%rbp,8) + movq %r11,24(%rdi,%rbp,8) + sbbq 32(%rsi,%rbp,8),%rax + movq 48(%rbx,%rbp,8),%r10 + movq 56(%rbx,%rbp,8),%r11 + sbbq 40(%rsi,%rbp,8),%rdx + leaq 4(%rbp),%rbp + decq %rcx + jnz L$sqr4x_sub + + movq %rax,0(%rdi,%rbp,8) + movq 32(%rbx,%rbp,8),%rax + sbbq 16(%rsi,%rbp,8),%r10 + movq %rdx,8(%rdi,%rbp,8) + sbbq 24(%rsi,%rbp,8),%r11 + movq %r10,16(%rdi,%rbp,8) + + sbbq $0,%rax + movq %r11,24(%rdi,%rbp,8) + xorq %rbp,%rbp + andq %rax,%rbx + notq %rax + movq %rdi,%rsi + andq %rax,%rsi + leaq -1(%r9),%rcx + orq %rsi,%rbx + + pxor %xmm0,%xmm0 + leaq 64(%rsp,%r9,8),%rsi + movdqu (%rbx),%xmm1 + leaq (%rsi,%r9,8),%rsi + movdqa %xmm0,64(%rsp) + movdqa %xmm0,(%rsi) + movdqu %xmm1,(%rdi) + jmp L$sqr4x_copy +.p2align 4 +L$sqr4x_copy: + movdqu 16(%rbx,%rbp,1),%xmm2 + movdqu 32(%rbx,%rbp,1),%xmm1 + movdqa %xmm0,80(%rsp,%rbp,1) + movdqa %xmm0,96(%rsp,%rbp,1) + movdqa %xmm0,16(%rsi,%rbp,1) + movdqa %xmm0,32(%rsi,%rbp,1) + movdqu %xmm2,16(%rdi,%rbp,1) + movdqu %xmm1,32(%rdi,%rbp,1) + leaq 32(%rbp),%rbp + decq %rcx + jnz L$sqr4x_copy + + movdqu 16(%rbx,%rbp,1),%xmm2 + movdqa %xmm0,80(%rsp,%rbp,1) + movdqa %xmm0,16(%rsi,%rbp,1) + movdqu %xmm2,16(%rdi,%rbp,1) + movq 56(%rsp),%rsi + movq $1,%rax + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$sqr4x_epilogue: + retq + +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 4 diff --git a/Libraries/libressl/crypto/bn/mont-masm-x86_64.S b/Libraries/libressl/crypto/bn/mont-masm-x86_64.S new file mode 100644 index 000000000..4896acd1a --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont-masm-x86_64.S @@ -0,0 +1,1496 @@ +; 1 "crypto/bn/mont-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/bn/mont-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/bn/mont-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC bn_mul_mont + +ALIGN 16 +bn_mul_mont PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_bn_mul_mont:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + + test r9d,3 + jnz $L$mul_enter + cmp r9d,8 + jb $L$mul_enter + cmp rdx,rsi + jne $L$mul4x_enter + jmp $L$sqr4x_enter + +ALIGN 16 +$L$mul_enter:: + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + mov r9d,r9d + lea r10,QWORD PTR[2+r9] + mov r11,rsp + neg r10 + lea rsp,QWORD PTR[r10*8+rsp] + and rsp,-1024 + + mov QWORD PTR[8+r9*8+rsp],r11 +$L$mul_body:: + mov r12,rdx + mov r8,QWORD PTR[r8] + mov rbx,QWORD PTR[r12] + mov rax,QWORD PTR[rsi] + + xor r14,r14 + xor r15,r15 + + mov rbp,r8 + mul rbx + mov r10,rax + mov rax,QWORD PTR[rcx] + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov r13,rdx + + lea r15,QWORD PTR[1+r15] + jmp $L$1st_enter + +ALIGN 16 +$L$1st:: + add r13,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add r13,r11 + mov r11,r10 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + +$L$1st_enter:: + mul rbx + add r11,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + lea r15,QWORD PTR[1+r15] + mov r10,rdx + + mul rbp + cmp r15,r9 + jl $L$1st + + add r13,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add r13,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + mov r11,r10 + + xor rdx,rdx + add r13,r11 + adc rdx,0 + mov QWORD PTR[((-8))+r9*8+rsp],r13 + mov QWORD PTR[r9*8+rsp],rdx + + lea r14,QWORD PTR[1+r14] + jmp $L$outer +ALIGN 16 +$L$outer:: + mov rbx,QWORD PTR[r14*8+r12] + xor r15,r15 + mov rbp,r8 + mov r10,QWORD PTR[rsp] + mul rbx + add r10,rax + mov rax,QWORD PTR[rcx] + adc rdx,0 + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov r10,QWORD PTR[8+rsp] + mov r13,rdx + + lea r15,QWORD PTR[1+r15] + jmp $L$inner_enter + +ALIGN 16 +$L$inner:: + add r13,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add r13,r10 + mov r10,QWORD PTR[r15*8+rsp] + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + +$L$inner_enter:: + mul rbx + add r11,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + add r10,r11 + mov r11,rdx + adc r11,0 + lea r15,QWORD PTR[1+r15] + + mul rbp + cmp r15,r9 + jl $L$inner + + add r13,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add r13,r10 + mov r10,QWORD PTR[r15*8+rsp] + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + + xor rdx,rdx + add r13,r11 + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-8))+r9*8+rsp],r13 + mov QWORD PTR[r9*8+rsp],rdx + + lea r14,QWORD PTR[1+r14] + cmp r14,r9 + jl $L$outer + + xor r14,r14 + mov rax,QWORD PTR[rsp] + lea rsi,QWORD PTR[rsp] + mov r15,r9 + jmp $L$sub +ALIGN 16 +$L$sub:: sbb rax,QWORD PTR[r14*8+rcx] + mov QWORD PTR[r14*8+rdi],rax + mov rax,QWORD PTR[8+r14*8+rsi] + lea r14,QWORD PTR[1+r14] + dec r15 + jnz $L$sub + + sbb rax,0 + xor r14,r14 + and rsi,rax + not rax + mov rcx,rdi + and rcx,rax + mov r15,r9 + or rsi,rcx +ALIGN 16 +$L$copy:: + mov rax,QWORD PTR[r14*8+rsi] + mov QWORD PTR[r14*8+rsp],r14 + mov QWORD PTR[r14*8+rdi],rax + lea r14,QWORD PTR[1+r14] + sub r15,1 + jnz $L$copy + + mov rsi,QWORD PTR[8+r9*8+rsp] + mov rax,1 + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$mul_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_bn_mul_mont:: +bn_mul_mont ENDP + +ALIGN 16 +bn_mul4x_mont PROC PRIVATE + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_bn_mul4x_mont:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + +$L$mul4x_enter:: + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + mov r9d,r9d + lea r10,QWORD PTR[4+r9] + mov r11,rsp + neg r10 + lea rsp,QWORD PTR[r10*8+rsp] + and rsp,-1024 + + mov QWORD PTR[8+r9*8+rsp],r11 +$L$mul4x_body:: + mov QWORD PTR[16+r9*8+rsp],rdi + mov r12,rdx + mov r8,QWORD PTR[r8] + mov rbx,QWORD PTR[r12] + mov rax,QWORD PTR[rsi] + + xor r14,r14 + xor r15,r15 + + mov rbp,r8 + mul rbx + mov r10,rax + mov rax,QWORD PTR[rcx] + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+rcx] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[16+rsi] + adc rdx,0 + add rdi,r11 + lea r15,QWORD PTR[4+r15] + adc rdx,0 + mov QWORD PTR[rsp],rdi + mov r13,rdx + jmp $L$1st4x +ALIGN 16 +$L$1st4x:: + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov r13,rdx + + mul rbx + add r10,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[8+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+r15*8+rcx] + adc rdx,0 + lea r15,QWORD PTR[4+r15] + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[((-16))+r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-32))+r15*8+rsp],rdi + mov r13,rdx + cmp r15,r9 + jl $L$1st4x + + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov r13,rdx + + xor rdi,rdi + add r13,r10 + adc rdi,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov QWORD PTR[r15*8+rsp],rdi + + lea r14,QWORD PTR[1+r14] +ALIGN 4 +$L$outer4x:: + mov rbx,QWORD PTR[r14*8+r12] + xor r15,r15 + mov r10,QWORD PTR[rsp] + mov rbp,r8 + mul rbx + add r10,rax + mov rax,QWORD PTR[rcx] + adc rdx,0 + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+rcx] + adc rdx,0 + add r11,QWORD PTR[8+rsp] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[16+rsi] + adc rdx,0 + add rdi,r11 + lea r15,QWORD PTR[4+r15] + adc rdx,0 + mov QWORD PTR[rsp],rdi + mov r13,rdx + jmp $L$inner4x +ALIGN 16 +$L$inner4x:: + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + add r10,QWORD PTR[((-16))+r15*8+rsp] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + add r11,QWORD PTR[((-8))+r15*8+rsp] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov r13,rdx + + mul rbx + add r10,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + add r10,QWORD PTR[r15*8+rsp] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[8+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+r15*8+rcx] + adc rdx,0 + add r11,QWORD PTR[8+r15*8+rsp] + adc rdx,0 + lea r15,QWORD PTR[4+r15] + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[((-16))+r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-32))+r15*8+rsp],rdi + mov r13,rdx + cmp r15,r9 + jl $L$inner4x + + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + add r10,QWORD PTR[((-16))+r15*8+rsp] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + add r11,QWORD PTR[((-8))+r15*8+rsp] + adc rdx,0 + lea r14,QWORD PTR[1+r14] + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov r13,rdx + + xor rdi,rdi + add r13,r10 + adc rdi,0 + add r13,QWORD PTR[r9*8+rsp] + adc rdi,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov QWORD PTR[r15*8+rsp],rdi + + cmp r14,r9 + jl $L$outer4x + mov rdi,QWORD PTR[16+r9*8+rsp] + mov rax,QWORD PTR[rsp] + pxor xmm0,xmm0 + mov rdx,QWORD PTR[8+rsp] + shr r9,2 + lea rsi,QWORD PTR[rsp] + xor r14,r14 + + sub rax,QWORD PTR[rcx] + mov rbx,QWORD PTR[16+rsi] + mov rbp,QWORD PTR[24+rsi] + sbb rdx,QWORD PTR[8+rcx] + lea r15,QWORD PTR[((-1))+r9] + jmp $L$sub4x +ALIGN 16 +$L$sub4x:: + mov QWORD PTR[r14*8+rdi],rax + mov QWORD PTR[8+r14*8+rdi],rdx + sbb rbx,QWORD PTR[16+r14*8+rcx] + mov rax,QWORD PTR[32+r14*8+rsi] + mov rdx,QWORD PTR[40+r14*8+rsi] + sbb rbp,QWORD PTR[24+r14*8+rcx] + mov QWORD PTR[16+r14*8+rdi],rbx + mov QWORD PTR[24+r14*8+rdi],rbp + sbb rax,QWORD PTR[32+r14*8+rcx] + mov rbx,QWORD PTR[48+r14*8+rsi] + mov rbp,QWORD PTR[56+r14*8+rsi] + sbb rdx,QWORD PTR[40+r14*8+rcx] + lea r14,QWORD PTR[4+r14] + dec r15 + jnz $L$sub4x + + mov QWORD PTR[r14*8+rdi],rax + mov rax,QWORD PTR[32+r14*8+rsi] + sbb rbx,QWORD PTR[16+r14*8+rcx] + mov QWORD PTR[8+r14*8+rdi],rdx + sbb rbp,QWORD PTR[24+r14*8+rcx] + mov QWORD PTR[16+r14*8+rdi],rbx + + sbb rax,0 + mov QWORD PTR[24+r14*8+rdi],rbp + xor r14,r14 + and rsi,rax + not rax + mov rcx,rdi + and rcx,rax + lea r15,QWORD PTR[((-1))+r9] + or rsi,rcx + + movdqu xmm1,XMMWORD PTR[rsi] + movdqa XMMWORD PTR[rsp],xmm0 + movdqu XMMWORD PTR[rdi],xmm1 + jmp $L$copy4x +ALIGN 16 +$L$copy4x:: + movdqu xmm2,XMMWORD PTR[16+r14*1+rsi] + movdqu xmm1,XMMWORD PTR[32+r14*1+rsi] + movdqa XMMWORD PTR[16+r14*1+rsp],xmm0 + movdqu XMMWORD PTR[16+r14*1+rdi],xmm2 + movdqa XMMWORD PTR[32+r14*1+rsp],xmm0 + movdqu XMMWORD PTR[32+r14*1+rdi],xmm1 + lea r14,QWORD PTR[32+r14] + dec r15 + jnz $L$copy4x + + shl r9,2 + movdqu xmm2,XMMWORD PTR[16+r14*1+rsi] + movdqa XMMWORD PTR[16+r14*1+rsp],xmm0 + movdqu XMMWORD PTR[16+r14*1+rdi],xmm2 + mov rsi,QWORD PTR[8+r9*8+rsp] + mov rax,1 + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$mul4x_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_bn_mul4x_mont:: +bn_mul4x_mont ENDP + +ALIGN 16 +bn_sqr4x_mont PROC PRIVATE + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_bn_sqr4x_mont:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + +$L$sqr4x_enter:: + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + shl r9d,3 + xor r10,r10 + mov r11,rsp + sub r10,r9 + mov r8,QWORD PTR[r8] + lea rsp,QWORD PTR[((-72))+r10*2+rsp] + and rsp,-1024 + + + + + + + + + + + + mov QWORD PTR[32+rsp],rdi + mov QWORD PTR[40+rsp],rcx + mov QWORD PTR[48+rsp],r8 + mov QWORD PTR[56+rsp],r11 +$L$sqr4x_body:: + + + + + + + + lea rbp,QWORD PTR[32+r10] + lea rsi,QWORD PTR[r9*1+rsi] + + mov rcx,r9 + + + mov r14,QWORD PTR[((-32))+rbp*1+rsi] + lea rdi,QWORD PTR[64+r9*2+rsp] + mov rax,QWORD PTR[((-24))+rbp*1+rsi] + lea rdi,QWORD PTR[((-32))+rbp*1+rdi] + mov rbx,QWORD PTR[((-16))+rbp*1+rsi] + mov r15,rax + + mul r14 + mov r10,rax + mov rax,rbx + mov r11,rdx + mov QWORD PTR[((-24))+rbp*1+rdi],r10 + + xor r10,r10 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + mov QWORD PTR[((-16))+rbp*1+rdi],r11 + + lea rcx,QWORD PTR[((-16))+rbp] + + + mov rbx,QWORD PTR[8+rcx*1+rsi] + mul r15 + mov r12,rax + mov rax,rbx + mov r13,rdx + + xor r11,r11 + add r10,r12 + lea rcx,QWORD PTR[16+rcx] + adc r11,0 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[((-8))+rcx*1+rdi],r10 + jmp $L$sqr4x_1st + +ALIGN 16 +$L$sqr4x_1st:: + mov rbx,QWORD PTR[rcx*1+rsi] + xor r12,r12 + mul r15 + add r13,rax + mov rax,rbx + adc r12,rdx + + xor r10,r10 + add r11,r13 + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + mov QWORD PTR[rcx*1+rdi],r11 + + + mov rbx,QWORD PTR[8+rcx*1+rsi] + xor r13,r13 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + + xor r11,r11 + add r10,r12 + adc r11,0 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[8+rcx*1+rdi],r10 + + mov rbx,QWORD PTR[16+rcx*1+rsi] + xor r12,r12 + mul r15 + add r13,rax + mov rax,rbx + adc r12,rdx + + xor r10,r10 + add r11,r13 + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + mov QWORD PTR[16+rcx*1+rdi],r11 + + + mov rbx,QWORD PTR[24+rcx*1+rsi] + xor r13,r13 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + + xor r11,r11 + add r10,r12 + lea rcx,QWORD PTR[32+rcx] + adc r11,0 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[((-8))+rcx*1+rdi],r10 + + cmp rcx,0 + jne $L$sqr4x_1st + + xor r12,r12 + add r13,r11 + adc r12,0 + mul r15 + add r13,rax + adc r12,rdx + + mov QWORD PTR[rdi],r13 + lea rbp,QWORD PTR[16+rbp] + mov QWORD PTR[8+rdi],r12 + jmp $L$sqr4x_outer + +ALIGN 16 +$L$sqr4x_outer:: + mov r14,QWORD PTR[((-32))+rbp*1+rsi] + lea rdi,QWORD PTR[64+r9*2+rsp] + mov rax,QWORD PTR[((-24))+rbp*1+rsi] + lea rdi,QWORD PTR[((-32))+rbp*1+rdi] + mov rbx,QWORD PTR[((-16))+rbp*1+rsi] + mov r15,rax + + mov r10,QWORD PTR[((-24))+rbp*1+rdi] + xor r11,r11 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[((-24))+rbp*1+rdi],r10 + + xor r10,r10 + add r11,QWORD PTR[((-16))+rbp*1+rdi] + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + mov QWORD PTR[((-16))+rbp*1+rdi],r11 + + lea rcx,QWORD PTR[((-16))+rbp] + xor r12,r12 + + + mov rbx,QWORD PTR[8+rcx*1+rsi] + xor r13,r13 + add r12,QWORD PTR[8+rcx*1+rdi] + adc r13,0 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + + xor r11,r11 + add r10,r12 + adc r11,0 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[8+rcx*1+rdi],r10 + + lea rcx,QWORD PTR[16+rcx] + jmp $L$sqr4x_inner + +ALIGN 16 +$L$sqr4x_inner:: + mov rbx,QWORD PTR[rcx*1+rsi] + xor r12,r12 + add r13,QWORD PTR[rcx*1+rdi] + adc r12,0 + mul r15 + add r13,rax + mov rax,rbx + adc r12,rdx + + xor r10,r10 + add r11,r13 + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + mov QWORD PTR[rcx*1+rdi],r11 + + mov rbx,QWORD PTR[8+rcx*1+rsi] + xor r13,r13 + add r12,QWORD PTR[8+rcx*1+rdi] + adc r13,0 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + + xor r11,r11 + add r10,r12 + lea rcx,QWORD PTR[16+rcx] + adc r11,0 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[((-8))+rcx*1+rdi],r10 + + cmp rcx,0 + jne $L$sqr4x_inner + + xor r12,r12 + add r13,r11 + adc r12,0 + mul r15 + add r13,rax + adc r12,rdx + + mov QWORD PTR[rdi],r13 + mov QWORD PTR[8+rdi],r12 + + add rbp,16 + jnz $L$sqr4x_outer + + + mov r14,QWORD PTR[((-32))+rsi] + lea rdi,QWORD PTR[64+r9*2+rsp] + mov rax,QWORD PTR[((-24))+rsi] + lea rdi,QWORD PTR[((-32))+rbp*1+rdi] + mov rbx,QWORD PTR[((-16))+rsi] + mov r15,rax + + xor r11,r11 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[((-24))+rdi],r10 + + xor r10,r10 + add r11,r13 + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + mov QWORD PTR[((-16))+rdi],r11 + + mov rbx,QWORD PTR[((-8))+rsi] + mul r15 + add r12,rax + mov rax,rbx + adc rdx,0 + + xor r11,r11 + add r10,r12 + mov r13,rdx + adc r11,0 + mul r14 + add r10,rax + mov rax,rbx + adc r11,rdx + mov QWORD PTR[((-8))+rdi],r10 + + xor r12,r12 + add r13,r11 + adc r12,0 + mul r15 + add r13,rax + mov rax,QWORD PTR[((-16))+rsi] + adc r12,rdx + + mov QWORD PTR[rdi],r13 + mov QWORD PTR[8+rdi],r12 + + mul rbx + add rbp,16 + xor r14,r14 + sub rbp,r9 + xor r15,r15 + + add rax,r12 + adc rdx,0 + mov QWORD PTR[8+rdi],rax + mov QWORD PTR[16+rdi],rdx + mov QWORD PTR[24+rdi],r15 + + mov rax,QWORD PTR[((-16))+rbp*1+rsi] + lea rdi,QWORD PTR[64+r9*2+rsp] + xor r10,r10 + mov r11,QWORD PTR[((-24))+rbp*2+rdi] + + lea r12,QWORD PTR[r10*2+r14] + shr r10,63 + lea r13,QWORD PTR[r11*2+rcx] + shr r11,63 + or r13,r10 + mov r10,QWORD PTR[((-16))+rbp*2+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[((-8))+rbp*2+rdi] + adc r12,rax + mov rax,QWORD PTR[((-8))+rbp*1+rsi] + mov QWORD PTR[((-32))+rbp*2+rdi],r12 + adc r13,rdx + + lea rbx,QWORD PTR[r10*2+r14] + mov QWORD PTR[((-24))+rbp*2+rdi],r13 + sbb r15,r15 + shr r10,63 + lea r8,QWORD PTR[r11*2+rcx] + shr r11,63 + or r8,r10 + mov r10,QWORD PTR[rbp*2+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[8+rbp*2+rdi] + adc rbx,rax + mov rax,QWORD PTR[rbp*1+rsi] + mov QWORD PTR[((-16))+rbp*2+rdi],rbx + adc r8,rdx + lea rbp,QWORD PTR[16+rbp] + mov QWORD PTR[((-40))+rbp*2+rdi],r8 + sbb r15,r15 + jmp $L$sqr4x_shift_n_add + +ALIGN 16 +$L$sqr4x_shift_n_add:: + lea r12,QWORD PTR[r10*2+r14] + shr r10,63 + lea r13,QWORD PTR[r11*2+rcx] + shr r11,63 + or r13,r10 + mov r10,QWORD PTR[((-16))+rbp*2+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[((-8))+rbp*2+rdi] + adc r12,rax + mov rax,QWORD PTR[((-8))+rbp*1+rsi] + mov QWORD PTR[((-32))+rbp*2+rdi],r12 + adc r13,rdx + + lea rbx,QWORD PTR[r10*2+r14] + mov QWORD PTR[((-24))+rbp*2+rdi],r13 + sbb r15,r15 + shr r10,63 + lea r8,QWORD PTR[r11*2+rcx] + shr r11,63 + or r8,r10 + mov r10,QWORD PTR[rbp*2+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[8+rbp*2+rdi] + adc rbx,rax + mov rax,QWORD PTR[rbp*1+rsi] + mov QWORD PTR[((-16))+rbp*2+rdi],rbx + adc r8,rdx + + lea r12,QWORD PTR[r10*2+r14] + mov QWORD PTR[((-8))+rbp*2+rdi],r8 + sbb r15,r15 + shr r10,63 + lea r13,QWORD PTR[r11*2+rcx] + shr r11,63 + or r13,r10 + mov r10,QWORD PTR[16+rbp*2+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[24+rbp*2+rdi] + adc r12,rax + mov rax,QWORD PTR[8+rbp*1+rsi] + mov QWORD PTR[rbp*2+rdi],r12 + adc r13,rdx + + lea rbx,QWORD PTR[r10*2+r14] + mov QWORD PTR[8+rbp*2+rdi],r13 + sbb r15,r15 + shr r10,63 + lea r8,QWORD PTR[r11*2+rcx] + shr r11,63 + or r8,r10 + mov r10,QWORD PTR[32+rbp*2+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[40+rbp*2+rdi] + adc rbx,rax + mov rax,QWORD PTR[16+rbp*1+rsi] + mov QWORD PTR[16+rbp*2+rdi],rbx + adc r8,rdx + mov QWORD PTR[24+rbp*2+rdi],r8 + sbb r15,r15 + add rbp,32 + jnz $L$sqr4x_shift_n_add + + lea r12,QWORD PTR[r10*2+r14] + shr r10,63 + lea r13,QWORD PTR[r11*2+rcx] + shr r11,63 + or r13,r10 + mov r10,QWORD PTR[((-16))+rdi] + mov r14,r11 + mul rax + neg r15 + mov r11,QWORD PTR[((-8))+rdi] + adc r12,rax + mov rax,QWORD PTR[((-8))+rsi] + mov QWORD PTR[((-32))+rdi],r12 + adc r13,rdx + + lea rbx,QWORD PTR[r10*2+r14] + mov QWORD PTR[((-24))+rdi],r13 + sbb r15,r15 + shr r10,63 + lea r8,QWORD PTR[r11*2+rcx] + shr r11,63 + or r8,r10 + mul rax + neg r15 + adc rbx,rax + adc r8,rdx + mov QWORD PTR[((-16))+rdi],rbx + mov QWORD PTR[((-8))+rdi],r8 + mov rsi,QWORD PTR[40+rsp] + mov r8,QWORD PTR[48+rsp] + xor rcx,rcx + mov QWORD PTR[rsp],r9 + sub rcx,r9 + mov r10,QWORD PTR[64+rsp] + mov r14,r8 + lea rax,QWORD PTR[64+r9*2+rsp] + lea rdi,QWORD PTR[64+r9*1+rsp] + mov QWORD PTR[8+rsp],rax + lea rsi,QWORD PTR[r9*1+rsi] + xor rbp,rbp + + mov rax,QWORD PTR[rcx*1+rsi] + mov r9,QWORD PTR[8+rcx*1+rsi] + imul r14,r10 + mov rbx,rax + jmp $L$sqr4x_mont_outer + +ALIGN 16 +$L$sqr4x_mont_outer:: + xor r11,r11 + mul r14 + add r10,rax + mov rax,r9 + adc r11,rdx + mov r15,r8 + + xor r10,r10 + add r11,QWORD PTR[8+rcx*1+rdi] + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + + imul r15,r11 + + mov rbx,QWORD PTR[16+rcx*1+rsi] + xor r13,r13 + add r12,r11 + adc r13,0 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + mov QWORD PTR[8+rcx*1+rdi],r12 + + xor r11,r11 + add r10,QWORD PTR[16+rcx*1+rdi] + adc r11,0 + mul r14 + add r10,rax + mov rax,r9 + adc r11,rdx + + mov r9,QWORD PTR[24+rcx*1+rsi] + xor r12,r12 + add r13,r10 + adc r12,0 + mul r15 + add r13,rax + mov rax,r9 + adc r12,rdx + mov QWORD PTR[16+rcx*1+rdi],r13 + + xor r10,r10 + add r11,QWORD PTR[24+rcx*1+rdi] + lea rcx,QWORD PTR[32+rcx] + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + jmp $L$sqr4x_mont_inner + +ALIGN 16 +$L$sqr4x_mont_inner:: + mov rbx,QWORD PTR[rcx*1+rsi] + xor r13,r13 + add r12,r11 + adc r13,0 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + mov QWORD PTR[((-8))+rcx*1+rdi],r12 + + xor r11,r11 + add r10,QWORD PTR[rcx*1+rdi] + adc r11,0 + mul r14 + add r10,rax + mov rax,r9 + adc r11,rdx + + mov r9,QWORD PTR[8+rcx*1+rsi] + xor r12,r12 + add r13,r10 + adc r12,0 + mul r15 + add r13,rax + mov rax,r9 + adc r12,rdx + mov QWORD PTR[rcx*1+rdi],r13 + + xor r10,r10 + add r11,QWORD PTR[8+rcx*1+rdi] + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + + + mov rbx,QWORD PTR[16+rcx*1+rsi] + xor r13,r13 + add r12,r11 + adc r13,0 + mul r15 + add r12,rax + mov rax,rbx + adc r13,rdx + mov QWORD PTR[8+rcx*1+rdi],r12 + + xor r11,r11 + add r10,QWORD PTR[16+rcx*1+rdi] + adc r11,0 + mul r14 + add r10,rax + mov rax,r9 + adc r11,rdx + + mov r9,QWORD PTR[24+rcx*1+rsi] + xor r12,r12 + add r13,r10 + adc r12,0 + mul r15 + add r13,rax + mov rax,r9 + adc r12,rdx + mov QWORD PTR[16+rcx*1+rdi],r13 + + xor r10,r10 + add r11,QWORD PTR[24+rcx*1+rdi] + lea rcx,QWORD PTR[32+rcx] + adc r10,0 + mul r14 + add r11,rax + mov rax,rbx + adc r10,rdx + cmp rcx,0 + jne $L$sqr4x_mont_inner + + sub rcx,QWORD PTR[rsp] + mov r14,r8 + + xor r13,r13 + add r12,r11 + adc r13,0 + mul r15 + add r12,rax + mov rax,r9 + adc r13,rdx + mov QWORD PTR[((-8))+rdi],r12 + + xor r11,r11 + add r10,QWORD PTR[rdi] + adc r11,0 + mov rbx,QWORD PTR[rcx*1+rsi] + add r10,rbp + adc r11,0 + + imul r14,QWORD PTR[16+rcx*1+rdi] + xor r12,r12 + mov r9,QWORD PTR[8+rcx*1+rsi] + add r13,r10 + mov r10,QWORD PTR[16+rcx*1+rdi] + adc r12,0 + mul r15 + add r13,rax + mov rax,rbx + adc r12,rdx + mov QWORD PTR[rdi],r13 + + xor rbp,rbp + add r12,QWORD PTR[8+rdi] + adc rbp,rbp + add r12,r11 + lea rdi,QWORD PTR[16+rdi] + adc rbp,0 + mov QWORD PTR[((-8))+rdi],r12 + cmp rdi,QWORD PTR[8+rsp] + jb $L$sqr4x_mont_outer + + mov r9,QWORD PTR[rsp] + mov QWORD PTR[rdi],rbp + mov rax,QWORD PTR[64+r9*1+rsp] + lea rbx,QWORD PTR[64+r9*1+rsp] + mov rsi,QWORD PTR[40+rsp] + shr r9,5 + mov rdx,QWORD PTR[8+rbx] + xor rbp,rbp + + mov rdi,QWORD PTR[32+rsp] + sub rax,QWORD PTR[rsi] + mov r10,QWORD PTR[16+rbx] + mov r11,QWORD PTR[24+rbx] + sbb rdx,QWORD PTR[8+rsi] + lea rcx,QWORD PTR[((-1))+r9] + jmp $L$sqr4x_sub +ALIGN 16 +$L$sqr4x_sub:: + mov QWORD PTR[rbp*8+rdi],rax + mov QWORD PTR[8+rbp*8+rdi],rdx + sbb r10,QWORD PTR[16+rbp*8+rsi] + mov rax,QWORD PTR[32+rbp*8+rbx] + mov rdx,QWORD PTR[40+rbp*8+rbx] + sbb r11,QWORD PTR[24+rbp*8+rsi] + mov QWORD PTR[16+rbp*8+rdi],r10 + mov QWORD PTR[24+rbp*8+rdi],r11 + sbb rax,QWORD PTR[32+rbp*8+rsi] + mov r10,QWORD PTR[48+rbp*8+rbx] + mov r11,QWORD PTR[56+rbp*8+rbx] + sbb rdx,QWORD PTR[40+rbp*8+rsi] + lea rbp,QWORD PTR[4+rbp] + dec rcx + jnz $L$sqr4x_sub + + mov QWORD PTR[rbp*8+rdi],rax + mov rax,QWORD PTR[32+rbp*8+rbx] + sbb r10,QWORD PTR[16+rbp*8+rsi] + mov QWORD PTR[8+rbp*8+rdi],rdx + sbb r11,QWORD PTR[24+rbp*8+rsi] + mov QWORD PTR[16+rbp*8+rdi],r10 + + sbb rax,0 + mov QWORD PTR[24+rbp*8+rdi],r11 + xor rbp,rbp + and rbx,rax + not rax + mov rsi,rdi + and rsi,rax + lea rcx,QWORD PTR[((-1))+r9] + or rbx,rsi + + pxor xmm0,xmm0 + lea rsi,QWORD PTR[64+r9*8+rsp] + movdqu xmm1,XMMWORD PTR[rbx] + lea rsi,QWORD PTR[r9*8+rsi] + movdqa XMMWORD PTR[64+rsp],xmm0 + movdqa XMMWORD PTR[rsi],xmm0 + movdqu XMMWORD PTR[rdi],xmm1 + jmp $L$sqr4x_copy +ALIGN 16 +$L$sqr4x_copy:: + movdqu xmm2,XMMWORD PTR[16+rbp*1+rbx] + movdqu xmm1,XMMWORD PTR[32+rbp*1+rbx] + movdqa XMMWORD PTR[80+rbp*1+rsp],xmm0 + movdqa XMMWORD PTR[96+rbp*1+rsp],xmm0 + movdqa XMMWORD PTR[16+rbp*1+rsi],xmm0 + movdqa XMMWORD PTR[32+rbp*1+rsi],xmm0 + movdqu XMMWORD PTR[16+rbp*1+rdi],xmm2 + movdqu XMMWORD PTR[32+rbp*1+rdi],xmm1 + lea rbp,QWORD PTR[32+rbp] + dec rcx + jnz $L$sqr4x_copy + + movdqu xmm2,XMMWORD PTR[16+rbp*1+rbx] + movdqa XMMWORD PTR[80+rbp*1+rsp],xmm0 + movdqa XMMWORD PTR[16+rbp*1+rsi],xmm0 + movdqu XMMWORD PTR[16+rbp*1+rdi],xmm2 + mov rsi,QWORD PTR[56+rsp] + mov rax,1 + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$sqr4x_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_bn_sqr4x_mont:: +bn_sqr4x_mont ENDP +DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 +DB 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 +DB 54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83 +DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 +DB 115,108,46,111,114,103,62,0 +ALIGN 16 + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/bn/mont-mips.S b/Libraries/libressl/crypto/bn/mont-mips.S new file mode 100644 index 000000000..65f7b226c --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont-mips.S @@ -0,0 +1,287 @@ +.text + +.set noat +.set noreorder + +.align 5 +.globl bn_mul_mont +.ent bn_mul_mont +bn_mul_mont: + lw $8,16($29) + lw $9,20($29) + slt $1,$9,4 + bnez $1,1f + li $2,0 + slt $1,$9,17 # on in-order CPU + bnez $1,bn_mul_mont_internal + nop +1: jr $31 + li $4,0 +.end bn_mul_mont + +.align 5 +.ent bn_mul_mont_internal +bn_mul_mont_internal: + .frame $30,14*4,$31 + .mask 0x40000000|16711680,-4 + sub $29,14*4 + sw $30,(14-1)*4($29) + sw $23,(14-2)*4($29) + sw $22,(14-3)*4($29) + sw $21,(14-4)*4($29) + sw $20,(14-5)*4($29) + sw $19,(14-6)*4($29) + sw $18,(14-7)*4($29) + sw $17,(14-8)*4($29) + sw $16,(14-9)*4($29) + move $30,$29 + + .set reorder + lw $8,0($8) + lw $13,0($6) # bp[0] + lw $12,0($5) # ap[0] + lw $14,0($7) # np[0] + + sub $29,2*4 # place for two extra words + sll $9,2 + li $1,-4096 + sub $29,$9 + and $29,$1 + + multu $12,$13 + lw $16,4($5) + lw $18,4($7) + mflo $10 + mfhi $11 + multu $10,$8 + mflo $23 + + multu $16,$13 + mflo $16 + mfhi $17 + + multu $14,$23 + mflo $24 + mfhi $25 + multu $18,$23 + addu $24,$10 + sltu $1,$24,$10 + addu $25,$1 + mflo $18 + mfhi $19 + + move $15,$29 + li $22,2*4 +.align 4 +.L1st: + .set noreorder + add $12,$5,$22 + add $14,$7,$22 + lw $12,($12) + lw $14,($14) + + multu $12,$13 + addu $10,$16,$11 + addu $24,$18,$25 + sltu $1,$10,$11 + sltu $2,$24,$25 + addu $11,$17,$1 + addu $25,$19,$2 + mflo $16 + mfhi $17 + + addu $24,$10 + sltu $1,$24,$10 + multu $14,$23 + addu $25,$1 + addu $22,4 + sw $24,($15) + sltu $2,$22,$9 + mflo $18 + mfhi $19 + + bnez $2,.L1st + add $15,4 + .set reorder + + addu $10,$16,$11 + sltu $1,$10,$11 + addu $11,$17,$1 + + addu $24,$18,$25 + sltu $2,$24,$25 + addu $25,$19,$2 + addu $24,$10 + sltu $1,$24,$10 + addu $25,$1 + + sw $24,($15) + + addu $25,$11 + sltu $1,$25,$11 + sw $25,4($15) + sw $1,2*4($15) + + li $21,4 +.align 4 +.Louter: + add $13,$6,$21 + lw $13,($13) + lw $12,($5) + lw $16,4($5) + lw $20,($29) + + multu $12,$13 + lw $14,($7) + lw $18,4($7) + mflo $10 + mfhi $11 + addu $10,$20 + multu $10,$8 + sltu $1,$10,$20 + addu $11,$1 + mflo $23 + + multu $16,$13 + mflo $16 + mfhi $17 + + multu $14,$23 + mflo $24 + mfhi $25 + + multu $18,$23 + addu $24,$10 + sltu $1,$24,$10 + addu $25,$1 + mflo $18 + mfhi $19 + + move $15,$29 + li $22,2*4 + lw $20,4($15) +.align 4 +.Linner: + .set noreorder + add $12,$5,$22 + add $14,$7,$22 + lw $12,($12) + lw $14,($14) + + multu $12,$13 + addu $10,$16,$11 + addu $24,$18,$25 + sltu $1,$10,$11 + sltu $2,$24,$25 + addu $11,$17,$1 + addu $25,$19,$2 + mflo $16 + mfhi $17 + + addu $10,$20 + addu $22,4 + multu $14,$23 + sltu $1,$10,$20 + addu $24,$10 + addu $11,$1 + sltu $2,$24,$10 + lw $20,2*4($15) + addu $25,$2 + sltu $1,$22,$9 + mflo $18 + mfhi $19 + sw $24,($15) + bnez $1,.Linner + add $15,4 + .set reorder + + addu $10,$16,$11 + sltu $1,$10,$11 + addu $11,$17,$1 + addu $10,$20 + sltu $2,$10,$20 + addu $11,$2 + + lw $20,2*4($15) + addu $24,$18,$25 + sltu $1,$24,$25 + addu $25,$19,$1 + addu $24,$10 + sltu $2,$24,$10 + addu $25,$2 + sw $24,($15) + + addu $24,$25,$11 + sltu $25,$24,$11 + addu $24,$20 + sltu $1,$24,$20 + addu $25,$1 + sw $24,4($15) + sw $25,2*4($15) + + addu $21,4 + sltu $2,$21,$9 + bnez $2,.Louter + + .set noreorder + add $20,$29,$9 # &tp[num] + move $15,$29 + move $5,$29 + li $11,0 # clear borrow bit + +.align 4 +.Lsub: lw $10,($15) + lw $24,($7) + add $15,4 + add $7,4 + subu $24,$10,$24 # tp[i]-np[i] + sgtu $1,$24,$10 + subu $10,$24,$11 + sgtu $11,$10,$24 + sw $10,($4) + or $11,$1 + sltu $1,$15,$20 + bnez $1,.Lsub + add $4,4 + + subu $11,$25,$11 # handle upmost overflow bit + move $15,$29 + sub $4,$9 # restore rp + not $25,$11 + + and $5,$11,$29 + and $6,$25,$4 + or $5,$5,$6 # ap=borrow?tp:rp + +.align 4 +.Lcopy: lw $12,($5) + add $5,4 + sw $0,($15) + add $15,4 + sltu $1,$15,$20 + sw $12,($4) + bnez $1,.Lcopy + add $4,4 + + li $4,1 + li $2,1 + + .set noreorder + move $29,$30 + lw $30,(14-1)*4($29) + lw $23,(14-2)*4($29) + lw $22,(14-3)*4($29) + lw $21,(14-4)*4($29) + lw $20,(14-5)*4($29) + lw $19,(14-6)*4($29) + lw $18,(14-7)*4($29) + lw $17,(14-8)*4($29) + lw $16,(14-9)*4($29) + jr $31 + add $29,14*4 +.end bn_mul_mont_internal +.rdata +.asciiz "Montgomery Multiplication for MIPS, CRYPTOGAMS by " +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/mont5-elf-x86_64.S b/Libraries/libressl/crypto/bn/mont5-elf-x86_64.S new file mode 100644 index 000000000..a3dbbcab0 --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont5-elf-x86_64.S @@ -0,0 +1,1182 @@ +#include "x86_arch.h" +.text + +.globl bn_mul_mont_gather5 +.type bn_mul_mont_gather5,@function +.align 64 +bn_mul_mont_gather5: + endbr64 + testl $3,%r9d + jnz .Lmul_enter + cmpl $8,%r9d + jb .Lmul_enter + jmp .Lmul4x_enter + +.align 16 +.Lmul_enter: + movl %r9d,%r9d + movd 8(%rsp),%xmm5 + leaq .Linc(%rip),%r10 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + +.Lmul_alloca: + movq %rsp,%rax + leaq 2(%r9),%r11 + negq %r11 + leaq -264(%rsp,%r11,8),%rsp + andq $-1024,%rsp + + movq %rax,8(%rsp,%r9,8) +.Lmul_body: + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 24-112(%rsp,%r9,8),%r10 + andq $-16,%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $78,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .L1st_enter + +.align 16 +.L1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.L1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jl .L1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp .Louter +.align 16 +.Louter: + leaq 24+128(%rsp,%r9,8),%rdx + andq $-16,%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $78,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .Linner_enter + +.align 16 +.Linner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.Linner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jl .Linner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jl .Louter + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp .Lsub +.align 16 +.Lsub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz .Lsub + + sbbq $0,%rax + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + movq %r9,%r15 + orq %rcx,%rsi +.align 16 +.Lcopy: + movq (%rsi,%r14,8),%rax + movq %r14,(%rsp,%r14,8) + movq %rax,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz .Lcopy + + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lmul_epilogue: + retq +.size bn_mul_mont_gather5,.-bn_mul_mont_gather5 +.type bn_mul4x_mont_gather5,@function +.align 16 +bn_mul4x_mont_gather5: + endbr64 +.Lmul4x_enter: + movl %r9d,%r9d + movd 8(%rsp),%xmm5 + leaq .Linc(%rip),%r10 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + +.Lmul4x_alloca: + movq %rsp,%rax + leaq 4(%r9),%r11 + negq %r11 + leaq -256(%rsp,%r11,8),%rsp + andq $-1024,%rsp + + movq %rax,8(%rsp,%r9,8) +.Lmul4x_body: + movq %rdi,16(%rsp,%r9,8) + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 32-112(%rsp,%r9,8),%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67,0x67 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $78,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .L1st4x +.align 16 +.L1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl .L1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.align 4 +.Louter4x: + leaq 32+128(%rsp,%r9,8),%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $78,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + xorq %r15,%r15 + + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdx,%r13 + jmp .Linner4x +.align 16 +.Linner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-40(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl .Linner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%r13 + + movq %rdi,-16(%rsp,%r15,8) + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jl .Louter4x + movq 16(%rsp,%r9,8),%rdi + movq 0(%rsp),%rax + pxor %xmm0,%xmm0 + movq 8(%rsp),%rdx + shrq $2,%r9 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + leaq -1(%r9),%r15 + jmp .Lsub4x +.align 16 +.Lsub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz .Lsub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + leaq -1(%r9),%r15 + orq %rcx,%rsi + + movdqu (%rsi),%xmm1 + movdqa %xmm0,(%rsp) + movdqu %xmm1,(%rdi) + jmp .Lcopy4x +.align 16 +.Lcopy4x: + movdqu 16(%rsi,%r14,1),%xmm2 + movdqu 32(%rsi,%r14,1),%xmm1 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movdqa %xmm0,32(%rsp,%r14,1) + movdqu %xmm1,32(%rdi,%r14,1) + leaq 32(%r14),%r14 + decq %r15 + jnz .Lcopy4x + + shlq $2,%r9 + movdqu 16(%rsi,%r14,1),%xmm2 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lmul4x_epilogue: + retq +.size bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5 +.globl bn_scatter5 +.type bn_scatter5,@function +.align 16 +bn_scatter5: + endbr64 + cmpq $0,%rsi + jz .Lscatter_epilogue + leaq (%rdx,%rcx,8),%rdx +.Lscatter: + movq (%rdi),%rax + leaq 8(%rdi),%rdi + movq %rax,(%rdx) + leaq 256(%rdx),%rdx + subq $1,%rsi + jnz .Lscatter +.Lscatter_epilogue: + retq +.size bn_scatter5,.-bn_scatter5 + +.globl bn_gather5 +.type bn_gather5,@function +.align 16 +bn_gather5: + endbr64 +.LSEH_begin_bn_gather5: + +.byte 0x4c,0x8d,0x14,0x24 +.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 + leaq .Linc(%rip),%rax + andq $-16,%rsp + + movd %ecx,%xmm5 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 128(%rdx),%r11 + leaq 128(%rsp),%rax + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-128(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-112(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-96(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-80(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-48(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-16(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,0(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,16(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,48(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,80(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,96(%rax) + movdqa %xmm4,%xmm2 + movdqa %xmm3,112(%rax) + jmp .Lgather + +.align 32 +.Lgather: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r11),%xmm0 + movdqa -112(%r11),%xmm1 + movdqa -96(%r11),%xmm2 + pand -128(%rax),%xmm0 + movdqa -80(%r11),%xmm3 + pand -112(%rax),%xmm1 + por %xmm0,%xmm4 + pand -96(%rax),%xmm2 + por %xmm1,%xmm5 + pand -80(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r11),%xmm0 + movdqa -48(%r11),%xmm1 + movdqa -32(%r11),%xmm2 + pand -64(%rax),%xmm0 + movdqa -16(%r11),%xmm3 + pand -48(%rax),%xmm1 + por %xmm0,%xmm4 + pand -32(%rax),%xmm2 + por %xmm1,%xmm5 + pand -16(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r11),%xmm0 + movdqa 16(%r11),%xmm1 + movdqa 32(%r11),%xmm2 + pand 0(%rax),%xmm0 + movdqa 48(%r11),%xmm3 + pand 16(%rax),%xmm1 + por %xmm0,%xmm4 + pand 32(%rax),%xmm2 + por %xmm1,%xmm5 + pand 48(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r11),%xmm0 + movdqa 80(%r11),%xmm1 + movdqa 96(%r11),%xmm2 + pand 64(%rax),%xmm0 + movdqa 112(%r11),%xmm3 + pand 80(%rax),%xmm1 + por %xmm0,%xmm4 + pand 96(%rax),%xmm2 + por %xmm1,%xmm5 + pand 112(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + leaq 256(%r11),%r11 + pshufd $78,%xmm4,%xmm0 + por %xmm4,%xmm0 + movq %xmm0,(%rdi) + leaq 8(%rdi),%rdi + subq $1,%rsi + jnz .Lgather + + leaq (%r10),%rsp + retq +.LSEH_end_bn_gather5: +.size bn_gather5,.-bn_gather5 +.section .rodata +.align 64 +.Linc: +.long 0,0, 1,1 +.long 2,2, 2,2 +.text +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/bn/mont5-macosx-x86_64.S b/Libraries/libressl/crypto/bn/mont5-macosx-x86_64.S new file mode 100644 index 000000000..039229fd5 --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont5-macosx-x86_64.S @@ -0,0 +1,1174 @@ +#include "x86_arch.h" +.text + +.globl _bn_mul_mont_gather5 + +.p2align 6 +_bn_mul_mont_gather5: + testl $3,%r9d + jnz L$mul_enter + cmpl $8,%r9d + jb L$mul_enter + jmp L$mul4x_enter + +.p2align 4 +L$mul_enter: + movl %r9d,%r9d + movd 8(%rsp),%xmm5 + leaq L$inc(%rip),%r10 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + +L$mul_alloca: + movq %rsp,%rax + leaq 2(%r9),%r11 + negq %r11 + leaq -264(%rsp,%r11,8),%rsp + andq $-1024,%rsp + + movq %rax,8(%rsp,%r9,8) +L$mul_body: + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 24-112(%rsp,%r9,8),%r10 + andq $-16,%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $78,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$1st_enter + +.p2align 4 +L$1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jl L$1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp L$outer +.p2align 4 +L$outer: + leaq 24+128(%rsp,%r9,8),%rdx + andq $-16,%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $78,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$inner_enter + +.p2align 4 +L$inner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$inner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jl L$inner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jl L$outer + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp L$sub +.p2align 4 +L$sub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz L$sub + + sbbq $0,%rax + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + movq %r9,%r15 + orq %rcx,%rsi +.p2align 4 +L$copy: + movq (%rsi,%r14,8),%rax + movq %r14,(%rsp,%r14,8) + movq %rax,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz L$copy + + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$mul_epilogue: + retq + + +.p2align 4 +bn_mul4x_mont_gather5: +L$mul4x_enter: + movl %r9d,%r9d + movd 8(%rsp),%xmm5 + leaq L$inc(%rip),%r10 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + +L$mul4x_alloca: + movq %rsp,%rax + leaq 4(%r9),%r11 + negq %r11 + leaq -256(%rsp,%r11,8),%rsp + andq $-1024,%rsp + + movq %rax,8(%rsp,%r9,8) +L$mul4x_body: + movq %rdi,16(%rsp,%r9,8) + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 32-112(%rsp,%r9,8),%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67,0x67 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $78,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp L$1st4x +.p2align 4 +L$1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl L$1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.p2align 2 +L$outer4x: + leaq 32+128(%rsp,%r9,8),%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $78,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + movd %xmm0,%rbx + + xorq %r15,%r15 + + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdx,%r13 + jmp L$inner4x +.p2align 4 +L$inner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-40(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jl L$inner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%r13 + + movq %rdi,-16(%rsp,%r15,8) + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jl L$outer4x + movq 16(%rsp,%r9,8),%rdi + movq 0(%rsp),%rax + pxor %xmm0,%xmm0 + movq 8(%rsp),%rdx + shrq $2,%r9 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + leaq -1(%r9),%r15 + jmp L$sub4x +.p2align 4 +L$sub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz L$sub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + xorq %r14,%r14 + andq %rax,%rsi + notq %rax + movq %rdi,%rcx + andq %rax,%rcx + leaq -1(%r9),%r15 + orq %rcx,%rsi + + movdqu (%rsi),%xmm1 + movdqa %xmm0,(%rsp) + movdqu %xmm1,(%rdi) + jmp L$copy4x +.p2align 4 +L$copy4x: + movdqu 16(%rsi,%r14,1),%xmm2 + movdqu 32(%rsi,%r14,1),%xmm1 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movdqa %xmm0,32(%rsp,%r14,1) + movdqu %xmm1,32(%rdi,%r14,1) + leaq 32(%r14),%r14 + decq %r15 + jnz L$copy4x + + shlq $2,%r9 + movdqu 16(%rsi,%r14,1),%xmm2 + movdqa %xmm0,16(%rsp,%r14,1) + movdqu %xmm2,16(%rdi,%r14,1) + movq 8(%rsp,%r9,8),%rsi + movq $1,%rax + + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$mul4x_epilogue: + retq + +.globl _bn_scatter5 + +.p2align 4 +_bn_scatter5: + cmpq $0,%rsi + jz L$scatter_epilogue + leaq (%rdx,%rcx,8),%rdx +L$scatter: + movq (%rdi),%rax + leaq 8(%rdi),%rdi + movq %rax,(%rdx) + leaq 256(%rdx),%rdx + subq $1,%rsi + jnz L$scatter +L$scatter_epilogue: + retq + + +.globl _bn_gather5 + +.p2align 4 +_bn_gather5: +L$SEH_begin_bn_gather5: + +.byte 0x4c,0x8d,0x14,0x24 +.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 + leaq L$inc(%rip),%rax + andq $-16,%rsp + + movd %ecx,%xmm5 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 128(%rdx),%r11 + leaq 128(%rsp),%rax + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-128(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-112(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-96(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-80(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-48(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-16(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,0(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,16(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,48(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,80(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,96(%rax) + movdqa %xmm4,%xmm2 + movdqa %xmm3,112(%rax) + jmp L$gather + +.p2align 5 +L$gather: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r11),%xmm0 + movdqa -112(%r11),%xmm1 + movdqa -96(%r11),%xmm2 + pand -128(%rax),%xmm0 + movdqa -80(%r11),%xmm3 + pand -112(%rax),%xmm1 + por %xmm0,%xmm4 + pand -96(%rax),%xmm2 + por %xmm1,%xmm5 + pand -80(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r11),%xmm0 + movdqa -48(%r11),%xmm1 + movdqa -32(%r11),%xmm2 + pand -64(%rax),%xmm0 + movdqa -16(%r11),%xmm3 + pand -48(%rax),%xmm1 + por %xmm0,%xmm4 + pand -32(%rax),%xmm2 + por %xmm1,%xmm5 + pand -16(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r11),%xmm0 + movdqa 16(%r11),%xmm1 + movdqa 32(%r11),%xmm2 + pand 0(%rax),%xmm0 + movdqa 48(%r11),%xmm3 + pand 16(%rax),%xmm1 + por %xmm0,%xmm4 + pand 32(%rax),%xmm2 + por %xmm1,%xmm5 + pand 48(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r11),%xmm0 + movdqa 80(%r11),%xmm1 + movdqa 96(%r11),%xmm2 + pand 64(%rax),%xmm0 + movdqa 112(%r11),%xmm3 + pand 80(%rax),%xmm1 + por %xmm0,%xmm4 + pand 96(%rax),%xmm2 + por %xmm1,%xmm5 + pand 112(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + leaq 256(%r11),%r11 + pshufd $78,%xmm4,%xmm0 + por %xmm4,%xmm0 + movq %xmm0,(%rdi) + leaq 8(%rdi),%rdi + subq $1,%rsi + jnz L$gather + + leaq (%r10),%rsp + retq +L$SEH_end_bn_gather5: + +.p2align 6 +L$inc: +.long 0,0, 1,1 +.long 2,2, 2,2 +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 diff --git a/Libraries/libressl/crypto/bn/mont5-masm-x86_64.S b/Libraries/libressl/crypto/bn/mont5-masm-x86_64.S new file mode 100644 index 000000000..cc709e673 --- /dev/null +++ b/Libraries/libressl/crypto/bn/mont5-masm-x86_64.S @@ -0,0 +1,1412 @@ +; 1 "crypto/bn/mont5-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/bn/mont5-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/bn/mont5-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC bn_mul_mont_gather5 + +ALIGN 64 +bn_mul_mont_gather5 PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_bn_mul_mont_gather5:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + + test r9d,3 + jnz $L$mul_enter + cmp r9d,8 + jb $L$mul_enter + jmp $L$mul4x_enter + +ALIGN 16 +$L$mul_enter:: + mov r9d,r9d + movd xmm5,DWORD PTR[56+rsp] + lea r10,QWORD PTR[$L$inc] + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + +$L$mul_alloca:: + mov rax,rsp + lea r11,QWORD PTR[2+r9] + neg r11 + lea rsp,QWORD PTR[((-264))+r11*8+rsp] + and rsp,-1024 + + mov QWORD PTR[8+r9*8+rsp],rax +$L$mul_body:: + lea r12,QWORD PTR[128+rdx] + movdqa xmm0,XMMWORD PTR[r10] + movdqa xmm1,XMMWORD PTR[16+r10] + lea r10,QWORD PTR[((24-112))+r9*8+rsp] + and r10,-16 + + pshufd xmm5,xmm5,0 + movdqa xmm4,xmm1 + movdqa xmm2,xmm1 + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 +DB 067h + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[112+r10],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[128+r10],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[144+r10],xmm2 + movdqa xmm2,xmm4 + + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[160+r10],xmm3 + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[176+r10],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[192+r10],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[208+r10],xmm2 + movdqa xmm2,xmm4 + + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[224+r10],xmm3 + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[240+r10],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[256+r10],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[272+r10],xmm2 + movdqa xmm2,xmm4 + + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[288+r10],xmm3 + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[304+r10],xmm0 + + paddd xmm3,xmm2 +DB 067h + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[320+r10],xmm1 + + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[336+r10],xmm2 + pand xmm0,XMMWORD PTR[64+r12] + + pand xmm1,XMMWORD PTR[80+r12] + pand xmm2,XMMWORD PTR[96+r12] + movdqa XMMWORD PTR[352+r10],xmm3 + pand xmm3,XMMWORD PTR[112+r12] + por xmm0,xmm2 + por xmm1,xmm3 + movdqa xmm4,XMMWORD PTR[((-128))+r12] + movdqa xmm5,XMMWORD PTR[((-112))+r12] + movdqa xmm2,XMMWORD PTR[((-96))+r12] + pand xmm4,XMMWORD PTR[112+r10] + movdqa xmm3,XMMWORD PTR[((-80))+r12] + pand xmm5,XMMWORD PTR[128+r10] + por xmm0,xmm4 + pand xmm2,XMMWORD PTR[144+r10] + por xmm1,xmm5 + pand xmm3,XMMWORD PTR[160+r10] + por xmm0,xmm2 + por xmm1,xmm3 + movdqa xmm4,XMMWORD PTR[((-64))+r12] + movdqa xmm5,XMMWORD PTR[((-48))+r12] + movdqa xmm2,XMMWORD PTR[((-32))+r12] + pand xmm4,XMMWORD PTR[176+r10] + movdqa xmm3,XMMWORD PTR[((-16))+r12] + pand xmm5,XMMWORD PTR[192+r10] + por xmm0,xmm4 + pand xmm2,XMMWORD PTR[208+r10] + por xmm1,xmm5 + pand xmm3,XMMWORD PTR[224+r10] + por xmm0,xmm2 + por xmm1,xmm3 + movdqa xmm4,XMMWORD PTR[r12] + movdqa xmm5,XMMWORD PTR[16+r12] + movdqa xmm2,XMMWORD PTR[32+r12] + pand xmm4,XMMWORD PTR[240+r10] + movdqa xmm3,XMMWORD PTR[48+r12] + pand xmm5,XMMWORD PTR[256+r10] + por xmm0,xmm4 + pand xmm2,XMMWORD PTR[272+r10] + por xmm1,xmm5 + pand xmm3,XMMWORD PTR[288+r10] + por xmm0,xmm2 + por xmm1,xmm3 + por xmm0,xmm1 + pshufd xmm1,xmm0,04eh + por xmm0,xmm1 + lea r12,QWORD PTR[256+r12] + movd rbx,xmm0 + + mov r8,QWORD PTR[r8] + mov rax,QWORD PTR[rsi] + + xor r14,r14 + xor r15,r15 + + mov rbp,r8 + mul rbx + mov r10,rax + mov rax,QWORD PTR[rcx] + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov r13,rdx + + lea r15,QWORD PTR[1+r15] + jmp $L$1st_enter + +ALIGN 16 +$L$1st:: + add r13,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add r13,r11 + mov r11,r10 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + +$L$1st_enter:: + mul rbx + add r11,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + lea r15,QWORD PTR[1+r15] + mov r10,rdx + + mul rbp + cmp r15,r9 + jl $L$1st + + add r13,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add r13,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + mov r11,r10 + + xor rdx,rdx + add r13,r11 + adc rdx,0 + mov QWORD PTR[((-8))+r9*8+rsp],r13 + mov QWORD PTR[r9*8+rsp],rdx + + lea r14,QWORD PTR[1+r14] + jmp $L$outer +ALIGN 16 +$L$outer:: + lea rdx,QWORD PTR[((24+128))+r9*8+rsp] + and rdx,-16 + pxor xmm4,xmm4 + pxor xmm5,xmm5 + movdqa xmm0,XMMWORD PTR[((-128))+r12] + movdqa xmm1,XMMWORD PTR[((-112))+r12] + movdqa xmm2,XMMWORD PTR[((-96))+r12] + movdqa xmm3,XMMWORD PTR[((-80))+r12] + pand xmm0,XMMWORD PTR[((-128))+rdx] + pand xmm1,XMMWORD PTR[((-112))+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[((-96))+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[((-80))+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[((-64))+r12] + movdqa xmm1,XMMWORD PTR[((-48))+r12] + movdqa xmm2,XMMWORD PTR[((-32))+r12] + movdqa xmm3,XMMWORD PTR[((-16))+r12] + pand xmm0,XMMWORD PTR[((-64))+rdx] + pand xmm1,XMMWORD PTR[((-48))+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[((-32))+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[((-16))+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[r12] + movdqa xmm1,XMMWORD PTR[16+r12] + movdqa xmm2,XMMWORD PTR[32+r12] + movdqa xmm3,XMMWORD PTR[48+r12] + pand xmm0,XMMWORD PTR[rdx] + pand xmm1,XMMWORD PTR[16+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[32+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[48+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[64+r12] + movdqa xmm1,XMMWORD PTR[80+r12] + movdqa xmm2,XMMWORD PTR[96+r12] + movdqa xmm3,XMMWORD PTR[112+r12] + pand xmm0,XMMWORD PTR[64+rdx] + pand xmm1,XMMWORD PTR[80+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[96+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[112+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + por xmm4,xmm5 + pshufd xmm0,xmm4,04eh + por xmm0,xmm4 + lea r12,QWORD PTR[256+r12] + movd rbx,xmm0 + + xor r15,r15 + mov rbp,r8 + mov r10,QWORD PTR[rsp] + + mul rbx + add r10,rax + mov rax,QWORD PTR[rcx] + adc rdx,0 + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov r10,QWORD PTR[8+rsp] + mov r13,rdx + + lea r15,QWORD PTR[1+r15] + jmp $L$inner_enter + +ALIGN 16 +$L$inner:: + add r13,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add r13,r10 + mov r10,QWORD PTR[r15*8+rsp] + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + +$L$inner_enter:: + mul rbx + add r11,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + add r10,r11 + mov r11,rdx + adc r11,0 + lea r15,QWORD PTR[1+r15] + + mul rbp + cmp r15,r9 + jl $L$inner + + add r13,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add r13,r10 + mov r10,QWORD PTR[r15*8+rsp] + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],r13 + mov r13,rdx + + xor rdx,rdx + add r13,r11 + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-8))+r9*8+rsp],r13 + mov QWORD PTR[r9*8+rsp],rdx + + lea r14,QWORD PTR[1+r14] + cmp r14,r9 + jl $L$outer + + xor r14,r14 + mov rax,QWORD PTR[rsp] + lea rsi,QWORD PTR[rsp] + mov r15,r9 + jmp $L$sub +ALIGN 16 +$L$sub:: sbb rax,QWORD PTR[r14*8+rcx] + mov QWORD PTR[r14*8+rdi],rax + mov rax,QWORD PTR[8+r14*8+rsi] + lea r14,QWORD PTR[1+r14] + dec r15 + jnz $L$sub + + sbb rax,0 + xor r14,r14 + and rsi,rax + not rax + mov rcx,rdi + and rcx,rax + mov r15,r9 + or rsi,rcx +ALIGN 16 +$L$copy:: + mov rax,QWORD PTR[r14*8+rsi] + mov QWORD PTR[r14*8+rsp],r14 + mov QWORD PTR[r14*8+rdi],rax + lea r14,QWORD PTR[1+r14] + sub r15,1 + jnz $L$copy + + mov rsi,QWORD PTR[8+r9*8+rsp] + mov rax,1 + + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$mul_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_bn_mul_mont_gather5:: +bn_mul_mont_gather5 ENDP + +ALIGN 16 +bn_mul4x_mont_gather5 PROC PRIVATE + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_bn_mul4x_mont_gather5:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + +$L$mul4x_enter:: + mov r9d,r9d + movd xmm5,DWORD PTR[56+rsp] + lea r10,QWORD PTR[$L$inc] + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + +$L$mul4x_alloca:: + mov rax,rsp + lea r11,QWORD PTR[4+r9] + neg r11 + lea rsp,QWORD PTR[((-256))+r11*8+rsp] + and rsp,-1024 + + mov QWORD PTR[8+r9*8+rsp],rax +$L$mul4x_body:: + mov QWORD PTR[16+r9*8+rsp],rdi + lea r12,QWORD PTR[128+rdx] + movdqa xmm0,XMMWORD PTR[r10] + movdqa xmm1,XMMWORD PTR[16+r10] + lea r10,QWORD PTR[((32-112))+r9*8+rsp] + + pshufd xmm5,xmm5,0 + movdqa xmm4,xmm1 +DB 067h,067h + movdqa xmm2,xmm1 + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 +DB 067h + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[112+r10],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[128+r10],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[144+r10],xmm2 + movdqa xmm2,xmm4 + + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[160+r10],xmm3 + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[176+r10],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[192+r10],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[208+r10],xmm2 + movdqa xmm2,xmm4 + + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[224+r10],xmm3 + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[240+r10],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[256+r10],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[272+r10],xmm2 + movdqa xmm2,xmm4 + + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[288+r10],xmm3 + movdqa xmm3,xmm4 + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[304+r10],xmm0 + + paddd xmm3,xmm2 +DB 067h + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[320+r10],xmm1 + + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[336+r10],xmm2 + pand xmm0,XMMWORD PTR[64+r12] + + pand xmm1,XMMWORD PTR[80+r12] + pand xmm2,XMMWORD PTR[96+r12] + movdqa XMMWORD PTR[352+r10],xmm3 + pand xmm3,XMMWORD PTR[112+r12] + por xmm0,xmm2 + por xmm1,xmm3 + movdqa xmm4,XMMWORD PTR[((-128))+r12] + movdqa xmm5,XMMWORD PTR[((-112))+r12] + movdqa xmm2,XMMWORD PTR[((-96))+r12] + pand xmm4,XMMWORD PTR[112+r10] + movdqa xmm3,XMMWORD PTR[((-80))+r12] + pand xmm5,XMMWORD PTR[128+r10] + por xmm0,xmm4 + pand xmm2,XMMWORD PTR[144+r10] + por xmm1,xmm5 + pand xmm3,XMMWORD PTR[160+r10] + por xmm0,xmm2 + por xmm1,xmm3 + movdqa xmm4,XMMWORD PTR[((-64))+r12] + movdqa xmm5,XMMWORD PTR[((-48))+r12] + movdqa xmm2,XMMWORD PTR[((-32))+r12] + pand xmm4,XMMWORD PTR[176+r10] + movdqa xmm3,XMMWORD PTR[((-16))+r12] + pand xmm5,XMMWORD PTR[192+r10] + por xmm0,xmm4 + pand xmm2,XMMWORD PTR[208+r10] + por xmm1,xmm5 + pand xmm3,XMMWORD PTR[224+r10] + por xmm0,xmm2 + por xmm1,xmm3 + movdqa xmm4,XMMWORD PTR[r12] + movdqa xmm5,XMMWORD PTR[16+r12] + movdqa xmm2,XMMWORD PTR[32+r12] + pand xmm4,XMMWORD PTR[240+r10] + movdqa xmm3,XMMWORD PTR[48+r12] + pand xmm5,XMMWORD PTR[256+r10] + por xmm0,xmm4 + pand xmm2,XMMWORD PTR[272+r10] + por xmm1,xmm5 + pand xmm3,XMMWORD PTR[288+r10] + por xmm0,xmm2 + por xmm1,xmm3 + por xmm0,xmm1 + pshufd xmm1,xmm0,04eh + por xmm0,xmm1 + lea r12,QWORD PTR[256+r12] + movd rbx,xmm0 + + mov r8,QWORD PTR[r8] + mov rax,QWORD PTR[rsi] + + xor r14,r14 + xor r15,r15 + + mov rbp,r8 + mul rbx + mov r10,rax + mov rax,QWORD PTR[rcx] + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+rcx] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[16+rsi] + adc rdx,0 + add rdi,r11 + lea r15,QWORD PTR[4+r15] + adc rdx,0 + mov QWORD PTR[rsp],rdi + mov r13,rdx + jmp $L$1st4x +ALIGN 16 +$L$1st4x:: + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov r13,rdx + + mul rbx + add r10,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[8+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+r15*8+rcx] + adc rdx,0 + lea r15,QWORD PTR[4+r15] + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[((-16))+r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-32))+r15*8+rsp],rdi + mov r13,rdx + cmp r15,r9 + jl $L$1st4x + + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov r13,rdx + + xor rdi,rdi + add r13,r10 + adc rdi,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov QWORD PTR[r15*8+rsp],rdi + + lea r14,QWORD PTR[1+r14] +ALIGN 4 +$L$outer4x:: + lea rdx,QWORD PTR[((32+128))+r9*8+rsp] + pxor xmm4,xmm4 + pxor xmm5,xmm5 + movdqa xmm0,XMMWORD PTR[((-128))+r12] + movdqa xmm1,XMMWORD PTR[((-112))+r12] + movdqa xmm2,XMMWORD PTR[((-96))+r12] + movdqa xmm3,XMMWORD PTR[((-80))+r12] + pand xmm0,XMMWORD PTR[((-128))+rdx] + pand xmm1,XMMWORD PTR[((-112))+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[((-96))+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[((-80))+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[((-64))+r12] + movdqa xmm1,XMMWORD PTR[((-48))+r12] + movdqa xmm2,XMMWORD PTR[((-32))+r12] + movdqa xmm3,XMMWORD PTR[((-16))+r12] + pand xmm0,XMMWORD PTR[((-64))+rdx] + pand xmm1,XMMWORD PTR[((-48))+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[((-32))+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[((-16))+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[r12] + movdqa xmm1,XMMWORD PTR[16+r12] + movdqa xmm2,XMMWORD PTR[32+r12] + movdqa xmm3,XMMWORD PTR[48+r12] + pand xmm0,XMMWORD PTR[rdx] + pand xmm1,XMMWORD PTR[16+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[32+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[48+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[64+r12] + movdqa xmm1,XMMWORD PTR[80+r12] + movdqa xmm2,XMMWORD PTR[96+r12] + movdqa xmm3,XMMWORD PTR[112+r12] + pand xmm0,XMMWORD PTR[64+rdx] + pand xmm1,XMMWORD PTR[80+rdx] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[96+rdx] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[112+rdx] + por xmm4,xmm2 + por xmm5,xmm3 + por xmm4,xmm5 + pshufd xmm0,xmm4,04eh + por xmm0,xmm4 + lea r12,QWORD PTR[256+r12] + movd rbx,xmm0 + + xor r15,r15 + + mov r10,QWORD PTR[rsp] + mov rbp,r8 + mul rbx + add r10,rax + mov rax,QWORD PTR[rcx] + adc rdx,0 + + imul rbp,r10 + mov r11,rdx + + mul rbp + add r10,rax + mov rax,QWORD PTR[8+rsi] + adc rdx,0 + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+rcx] + adc rdx,0 + add r11,QWORD PTR[8+rsp] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[16+rsi] + adc rdx,0 + add rdi,r11 + lea r15,QWORD PTR[4+r15] + adc rdx,0 + mov r13,rdx + jmp $L$inner4x +ALIGN 16 +$L$inner4x:: + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + add r10,QWORD PTR[((-16))+r15*8+rsp] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-32))+r15*8+rsp],rdi + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + add r11,QWORD PTR[((-8))+r15*8+rsp] + adc rdx,0 + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov r13,rdx + + mul rbx + add r10,rax + mov rax,QWORD PTR[r15*8+rcx] + adc rdx,0 + add r10,QWORD PTR[r15*8+rsp] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[8+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-16))+r15*8+rsp],rdi + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[8+r15*8+rcx] + adc rdx,0 + add r11,QWORD PTR[8+r15*8+rsp] + adc rdx,0 + lea r15,QWORD PTR[4+r15] + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[((-16))+r15*8+rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-40))+r15*8+rsp],r13 + mov r13,rdx + cmp r15,r9 + jl $L$inner4x + + mul rbx + add r10,rax + mov rax,QWORD PTR[((-16))+r15*8+rcx] + adc rdx,0 + add r10,QWORD PTR[((-16))+r15*8+rsp] + adc rdx,0 + mov r11,rdx + + mul rbp + add r13,rax + mov rax,QWORD PTR[((-8))+r15*8+rsi] + adc rdx,0 + add r13,r10 + adc rdx,0 + mov QWORD PTR[((-32))+r15*8+rsp],rdi + mov rdi,rdx + + mul rbx + add r11,rax + mov rax,QWORD PTR[((-8))+r15*8+rcx] + adc rdx,0 + add r11,QWORD PTR[((-8))+r15*8+rsp] + adc rdx,0 + lea r14,QWORD PTR[1+r14] + mov r10,rdx + + mul rbp + add rdi,rax + mov rax,QWORD PTR[rsi] + adc rdx,0 + add rdi,r11 + adc rdx,0 + mov QWORD PTR[((-24))+r15*8+rsp],r13 + mov r13,rdx + + mov QWORD PTR[((-16))+r15*8+rsp],rdi + + xor rdi,rdi + add r13,r10 + adc rdi,0 + add r13,QWORD PTR[r9*8+rsp] + adc rdi,0 + mov QWORD PTR[((-8))+r15*8+rsp],r13 + mov QWORD PTR[r15*8+rsp],rdi + + cmp r14,r9 + jl $L$outer4x + mov rdi,QWORD PTR[16+r9*8+rsp] + mov rax,QWORD PTR[rsp] + pxor xmm0,xmm0 + mov rdx,QWORD PTR[8+rsp] + shr r9,2 + lea rsi,QWORD PTR[rsp] + xor r14,r14 + + sub rax,QWORD PTR[rcx] + mov rbx,QWORD PTR[16+rsi] + mov rbp,QWORD PTR[24+rsi] + sbb rdx,QWORD PTR[8+rcx] + lea r15,QWORD PTR[((-1))+r9] + jmp $L$sub4x +ALIGN 16 +$L$sub4x:: + mov QWORD PTR[r14*8+rdi],rax + mov QWORD PTR[8+r14*8+rdi],rdx + sbb rbx,QWORD PTR[16+r14*8+rcx] + mov rax,QWORD PTR[32+r14*8+rsi] + mov rdx,QWORD PTR[40+r14*8+rsi] + sbb rbp,QWORD PTR[24+r14*8+rcx] + mov QWORD PTR[16+r14*8+rdi],rbx + mov QWORD PTR[24+r14*8+rdi],rbp + sbb rax,QWORD PTR[32+r14*8+rcx] + mov rbx,QWORD PTR[48+r14*8+rsi] + mov rbp,QWORD PTR[56+r14*8+rsi] + sbb rdx,QWORD PTR[40+r14*8+rcx] + lea r14,QWORD PTR[4+r14] + dec r15 + jnz $L$sub4x + + mov QWORD PTR[r14*8+rdi],rax + mov rax,QWORD PTR[32+r14*8+rsi] + sbb rbx,QWORD PTR[16+r14*8+rcx] + mov QWORD PTR[8+r14*8+rdi],rdx + sbb rbp,QWORD PTR[24+r14*8+rcx] + mov QWORD PTR[16+r14*8+rdi],rbx + + sbb rax,0 + mov QWORD PTR[24+r14*8+rdi],rbp + xor r14,r14 + and rsi,rax + not rax + mov rcx,rdi + and rcx,rax + lea r15,QWORD PTR[((-1))+r9] + or rsi,rcx + + movdqu xmm1,XMMWORD PTR[rsi] + movdqa XMMWORD PTR[rsp],xmm0 + movdqu XMMWORD PTR[rdi],xmm1 + jmp $L$copy4x +ALIGN 16 +$L$copy4x:: + movdqu xmm2,XMMWORD PTR[16+r14*1+rsi] + movdqu xmm1,XMMWORD PTR[32+r14*1+rsi] + movdqa XMMWORD PTR[16+r14*1+rsp],xmm0 + movdqu XMMWORD PTR[16+r14*1+rdi],xmm2 + movdqa XMMWORD PTR[32+r14*1+rsp],xmm0 + movdqu XMMWORD PTR[32+r14*1+rdi],xmm1 + lea r14,QWORD PTR[32+r14] + dec r15 + jnz $L$copy4x + + shl r9,2 + movdqu xmm2,XMMWORD PTR[16+r14*1+rsi] + movdqa XMMWORD PTR[16+r14*1+rsp],xmm0 + movdqu XMMWORD PTR[16+r14*1+rdi],xmm2 + mov rsi,QWORD PTR[8+r9*8+rsp] + mov rax,1 + + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$mul4x_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_bn_mul4x_mont_gather5:: +bn_mul4x_mont_gather5 ENDP +PUBLIC bn_scatter5 + +ALIGN 16 +bn_scatter5 PROC PUBLIC + cmp rdx,0 + jz $L$scatter_epilogue + lea r8,QWORD PTR[r9*8+r8] +$L$scatter:: + mov rax,QWORD PTR[rcx] + lea rcx,QWORD PTR[8+rcx] + mov QWORD PTR[r8],rax + lea r8,QWORD PTR[256+r8] + sub rdx,1 + jnz $L$scatter +$L$scatter_epilogue:: + DB 0F3h,0C3h ;repret +bn_scatter5 ENDP + +PUBLIC bn_gather5 + +ALIGN 16 +bn_gather5 PROC PUBLIC +$L$SEH_begin_bn_gather5:: + +DB 04ch,08dh,014h,024h +DB 048h,081h,0ech,008h,001h,000h,000h + lea rax,QWORD PTR[$L$inc] + and rsp,-16 + + movd xmm5,r9d + movdqa xmm0,XMMWORD PTR[rax] + movdqa xmm1,XMMWORD PTR[16+rax] + lea r11,QWORD PTR[128+r8] + lea rax,QWORD PTR[128+rsp] + + pshufd xmm5,xmm5,0 + movdqa xmm4,xmm1 + movdqa xmm2,xmm1 + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa xmm3,xmm4 + + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[(-128)+rax],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[(-112)+rax],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[(-96)+rax],xmm2 + movdqa xmm2,xmm4 + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[(-80)+rax],xmm3 + movdqa xmm3,xmm4 + + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[(-64)+rax],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[(-48)+rax],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[(-32)+rax],xmm2 + movdqa xmm2,xmm4 + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[(-16)+rax],xmm3 + movdqa xmm3,xmm4 + + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[rax],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[16+rax],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[32+rax],xmm2 + movdqa xmm2,xmm4 + paddd xmm1,xmm0 + pcmpeqd xmm0,xmm5 + movdqa XMMWORD PTR[48+rax],xmm3 + movdqa xmm3,xmm4 + + paddd xmm2,xmm1 + pcmpeqd xmm1,xmm5 + movdqa XMMWORD PTR[64+rax],xmm0 + movdqa xmm0,xmm4 + + paddd xmm3,xmm2 + pcmpeqd xmm2,xmm5 + movdqa XMMWORD PTR[80+rax],xmm1 + movdqa xmm1,xmm4 + + paddd xmm0,xmm3 + pcmpeqd xmm3,xmm5 + movdqa XMMWORD PTR[96+rax],xmm2 + movdqa xmm2,xmm4 + movdqa XMMWORD PTR[112+rax],xmm3 + jmp $L$gather + +ALIGN 32 +$L$gather:: + pxor xmm4,xmm4 + pxor xmm5,xmm5 + movdqa xmm0,XMMWORD PTR[((-128))+r11] + movdqa xmm1,XMMWORD PTR[((-112))+r11] + movdqa xmm2,XMMWORD PTR[((-96))+r11] + pand xmm0,XMMWORD PTR[((-128))+rax] + movdqa xmm3,XMMWORD PTR[((-80))+r11] + pand xmm1,XMMWORD PTR[((-112))+rax] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[((-96))+rax] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[((-80))+rax] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[((-64))+r11] + movdqa xmm1,XMMWORD PTR[((-48))+r11] + movdqa xmm2,XMMWORD PTR[((-32))+r11] + pand xmm0,XMMWORD PTR[((-64))+rax] + movdqa xmm3,XMMWORD PTR[((-16))+r11] + pand xmm1,XMMWORD PTR[((-48))+rax] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[((-32))+rax] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[((-16))+rax] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[r11] + movdqa xmm1,XMMWORD PTR[16+r11] + movdqa xmm2,XMMWORD PTR[32+r11] + pand xmm0,XMMWORD PTR[rax] + movdqa xmm3,XMMWORD PTR[48+r11] + pand xmm1,XMMWORD PTR[16+rax] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[32+rax] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[48+rax] + por xmm4,xmm2 + por xmm5,xmm3 + movdqa xmm0,XMMWORD PTR[64+r11] + movdqa xmm1,XMMWORD PTR[80+r11] + movdqa xmm2,XMMWORD PTR[96+r11] + pand xmm0,XMMWORD PTR[64+rax] + movdqa xmm3,XMMWORD PTR[112+r11] + pand xmm1,XMMWORD PTR[80+rax] + por xmm4,xmm0 + pand xmm2,XMMWORD PTR[96+rax] + por xmm5,xmm1 + pand xmm3,XMMWORD PTR[112+rax] + por xmm4,xmm2 + por xmm5,xmm3 + por xmm4,xmm5 + lea r11,QWORD PTR[256+r11] + pshufd xmm0,xmm4,04eh + por xmm0,xmm4 + movq QWORD PTR[rcx],xmm0 + lea rcx,QWORD PTR[8+rcx] + sub rdx,1 + jnz $L$gather + + lea rsp,QWORD PTR[r10] + DB 0F3h,0C3h ;repret +$L$SEH_end_bn_gather5:: +bn_gather5 ENDP +ALIGN 64 +$L$inc:: + DD 0,0,1,1 + DD 2,2,2,2 +DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 +DB 112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115 +DB 99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111 +DB 114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79 +DB 71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111 +DB 112,101,110,115,115,108,46,111,114,103,62,0 +EXTERN __imp_RtlVirtualUnwind:NEAR + +ALIGN 16 +mul_handler PROC PRIVATE + push rsi + push rdi + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + pushfq + sub rsp,64 + + mov rax,QWORD PTR[120+r8] + mov rbx,QWORD PTR[248+r8] + + mov rsi,QWORD PTR[8+r9] + mov r11,QWORD PTR[56+r9] + + mov r10d,DWORD PTR[r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jb $L$common_seh_tail + + lea rax,QWORD PTR[48+rax] + + mov r10d,DWORD PTR[4+r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jb $L$common_seh_tail + + mov rax,QWORD PTR[152+r8] + + mov r10d,DWORD PTR[8+r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jae $L$common_seh_tail + + mov r10,QWORD PTR[192+r8] + mov rax,QWORD PTR[8+r10*8+rax] + + lea rax,QWORD PTR[48+rax] + + mov rbx,QWORD PTR[((-8))+rax] + mov rbp,QWORD PTR[((-16))+rax] + mov r12,QWORD PTR[((-24))+rax] + mov r13,QWORD PTR[((-32))+rax] + mov r14,QWORD PTR[((-40))+rax] + mov r15,QWORD PTR[((-48))+rax] + mov QWORD PTR[144+r8],rbx + mov QWORD PTR[160+r8],rbp + mov QWORD PTR[216+r8],r12 + mov QWORD PTR[224+r8],r13 + mov QWORD PTR[232+r8],r14 + mov QWORD PTR[240+r8],r15 + +$L$common_seh_tail:: + mov rdi,QWORD PTR[8+rax] + mov rsi,QWORD PTR[16+rax] + mov QWORD PTR[152+r8],rax + mov QWORD PTR[168+r8],rsi + mov QWORD PTR[176+r8],rdi + + mov rdi,QWORD PTR[40+r9] + mov rsi,r8 + mov ecx,154 + DD 0a548f3fch + + mov rsi,r9 + xor rcx,rcx + mov rdx,QWORD PTR[8+rsi] + mov r8,QWORD PTR[rsi] + mov r9,QWORD PTR[16+rsi] + mov r10,QWORD PTR[40+rsi] + lea r11,QWORD PTR[56+rsi] + lea r12,QWORD PTR[24+rsi] + mov QWORD PTR[32+rsp],r10 + mov QWORD PTR[40+rsp],r11 + mov QWORD PTR[48+rsp],r12 + mov QWORD PTR[56+rsp],rcx + call QWORD PTR[__imp_RtlVirtualUnwind] + + mov eax,1 + add rsp,64 + popfq + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + pop rdi + pop rsi + DB 0F3h,0C3h ;repret +mul_handler ENDP + +.text$ ENDS +.pdata SEGMENT READONLY ALIGN(4) +ALIGN 4 + DD imagerel $L$SEH_begin_bn_mul_mont_gather5 + DD imagerel $L$SEH_end_bn_mul_mont_gather5 + DD imagerel $L$SEH_info_bn_mul_mont_gather5 + + DD imagerel $L$SEH_begin_bn_mul4x_mont_gather5 + DD imagerel $L$SEH_end_bn_mul4x_mont_gather5 + DD imagerel $L$SEH_info_bn_mul4x_mont_gather5 + + DD imagerel $L$SEH_begin_bn_gather5 + DD imagerel $L$SEH_end_bn_gather5 + DD imagerel $L$SEH_info_bn_gather5 + +.pdata ENDS +.xdata SEGMENT READONLY ALIGN(8) +ALIGN 8 +$L$SEH_info_bn_mul_mont_gather5:: +DB 9,0,0,0 + DD imagerel mul_handler + DD imagerel $L$mul_alloca,imagerel $L$mul_body,imagerel $L$mul_epilogue +ALIGN 8 +$L$SEH_info_bn_mul4x_mont_gather5:: +DB 9,0,0,0 + DD imagerel mul_handler + DD imagerel $L$mul4x_alloca,imagerel $L$mul4x_body,imagerel $L$mul4x_epilogue +ALIGN 8 +$L$SEH_info_bn_gather5:: +DB 001h,00bh,003h,00ah +DB 00bh,001h,021h,000h +DB 004h,0a3h,000h,000h +ALIGN 8 + +.xdata ENDS +END + diff --git a/Libraries/libressl/crypto/bn/s2n_bignum.h b/Libraries/libressl/crypto/bn/s2n_bignum.h new file mode 100644 index 000000000..ce6e8cdc9 --- /dev/null +++ b/Libraries/libressl/crypto/bn/s2n_bignum.h @@ -0,0 +1,856 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// ---------------------------------------------------------------------------- +// C prototypes for s2n-bignum functions, so you can use them in C programs via +// +// #include "s2n-bignum.h" +// +// The functions are listed in alphabetical order with a brief description +// in comments for each one. For more detailed documentation see the comment +// banner at the top of the corresponding assembly (.S) file, and +// for the last word in what properties it satisfies see the spec in the +// formal proof (the .ml file in the architecture-specific directory). +// +// For some functions there are additional variants with names ending in +// "_alt". These have the same core mathematical functionality as their +// non-"alt" versions, but can be better suited to some microarchitectures: +// +// - On x86, the "_alt" forms avoid BMI and ADX instruction set +// extensions, so will run on any x86_64 machine, even older ones +// +// - On ARM, the "_alt" forms target machines with higher multiplier +// throughput, generally offering higher performance there. +// ---------------------------------------------------------------------------- + +// Add, z := x + y +// Inputs x[m], y[n]; outputs function return (carry-out) and z[p] +extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Add modulo p_25519, z := (x + y) mod p_25519, assuming x and y reduced +// Inputs x[4], y[4]; output z[4] +extern void bignum_add_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Add modulo p_256, z := (x + y) mod p_256, assuming x and y reduced +// Inputs x[4], y[4]; output z[4] +extern void bignum_add_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Add modulo p_256k1, z := (x + y) mod p_256k1, assuming x and y reduced +// Inputs x[4], y[4]; output z[4] +extern void bignum_add_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Add modulo p_384, z := (x + y) mod p_384, assuming x and y reduced +// Inputs x[6], y[6]; output z[6] +extern void bignum_add_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); + +// Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced +// Inputs x[9], y[9]; output z[9] +extern void bignum_add_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); + +// Compute "amontification" constant z :== 2^{128k} (congruent mod m) +// Input m[k]; output z[k]; temporary buffer t[>=k] +extern void bignum_amontifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); + +// Almost-Montgomery multiply, z :== (x * y / 2^{64k}) (congruent mod m) +// Inputs x[k], y[k], m[k]; output z[k] +extern void bignum_amontmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); + +// Almost-Montgomery reduce, z :== (x' / 2^{64p}) (congruent mod m) +// Inputs x[n], m[k], p; output z[k] +extern void bignum_amontredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); + +// Almost-Montgomery square, z :== (x^2 / 2^{64k}) (congruent mod m) +// Inputs x[k], m[k]; output z[k] +extern void bignum_amontsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); + +// Convert 4-digit (256-bit) bignum to/from big-endian form +// Input x[4]; output z[4] +extern void bignum_bigendian_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert 6-digit (384-bit) bignum to/from big-endian form +// Input x[6]; output z[6] +extern void bignum_bigendian_6 (uint64_t z[static 6], uint64_t x[static 6]); + +// Select bitfield starting at bit n with length l <= 64 +// Inputs x[k], n, l; output function return +extern uint64_t bignum_bitfield (uint64_t k, uint64_t *x, uint64_t n, uint64_t l); + +// Return size of bignum in bits +// Input x[k]; output function return +extern uint64_t bignum_bitsize (uint64_t k, uint64_t *x); + +// Divide by a single (nonzero) word, z := x / m and return x mod m +// Inputs x[n], m; outputs function return (remainder) and z[k] +extern uint64_t bignum_cdiv (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); + +// Divide by a single word, z := x / m when known to be exact +// Inputs x[n], m; output z[k] +extern void bignum_cdiv_exact (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); + +// Count leading zero digits (64-bit words) +// Input x[k]; output function return +extern uint64_t bignum_cld (uint64_t k, uint64_t *x); + +// Count leading zero bits +// Input x[k]; output function return +extern uint64_t bignum_clz (uint64_t k, uint64_t *x); + +// Multiply-add with single-word multiplier, z := z + c * y +// Inputs c, y[n]; outputs function return (carry-out) and z[k] +extern uint64_t bignum_cmadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); + +// Negated multiply-add with single-word multiplier, z := z - c * y +// Inputs c, y[n]; outputs function return (negative carry-out) and z[k] +extern uint64_t bignum_cmnegadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); + +// Find modulus of bignum w.r.t. single nonzero word m, returning x mod m +// Input x[k], m; output function return +extern uint64_t bignum_cmod (uint64_t k, uint64_t *x, uint64_t m); + +// Multiply by a single word, z := c * y +// Inputs c, y[n]; outputs function return (carry-out) and z[k] +extern uint64_t bignum_cmul (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); + +// Multiply by a single word modulo p_25519, z := (c * x) mod p_25519, assuming x reduced +// Inputs c, x[4]; output z[4] +extern void bignum_cmul_p25519 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); +extern void bignum_cmul_p25519_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); + +// Multiply by a single word modulo p_256, z := (c * x) mod p_256, assuming x reduced +// Inputs c, x[4]; output z[4] +extern void bignum_cmul_p256 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); +extern void bignum_cmul_p256_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); + +// Multiply by a single word modulo p_256k1, z := (c * x) mod p_256k1, assuming x reduced +// Inputs c, x[4]; output z[4] +extern void bignum_cmul_p256k1 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); +extern void bignum_cmul_p256k1_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); + +// Multiply by a single word modulo p_384, z := (c * x) mod p_384, assuming x reduced +// Inputs c, x[6]; output z[6] +extern void bignum_cmul_p384 (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); +extern void bignum_cmul_p384_alt (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); + +// Multiply by a single word modulo p_521, z := (c * x) mod p_521, assuming x reduced +// Inputs c, x[9]; output z[9] +extern void bignum_cmul_p521 (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); +extern void bignum_cmul_p521_alt (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); + +// Test bignums for coprimality, gcd(x,y) = 1 +// Inputs x[m], y[n]; output function return; temporary buffer t[>=2*max(m,n)] +extern uint64_t bignum_coprime (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y, uint64_t *t); + +// Copy bignum with zero-extension or truncation, z := x +// Input x[n]; output z[k] +extern void bignum_copy (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); + +// Count trailing zero digits (64-bit words) +// Input x[k]; output function return +extern uint64_t bignum_ctd (uint64_t k, uint64_t *x); + +// Count trailing zero bits +// Input x[k]; output function return +extern uint64_t bignum_ctz (uint64_t k, uint64_t *x); + +// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256 +// Input x[4]; output z[4] +extern void bignum_deamont_p256 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_deamont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256k1 +// Input x[4]; output z[4] +extern void bignum_deamont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert from almost-Montgomery form, z := (x / 2^384) mod p_384 +// Input x[6]; output z[6] +extern void bignum_deamont_p384 (uint64_t z[static 6], uint64_t x[static 6]); +extern void bignum_deamont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); + +// Convert from almost-Montgomery form z := (x / 2^576) mod p_521 +// Input x[9]; output z[9] +extern void bignum_deamont_p521 (uint64_t z[static 9], uint64_t x[static 9]); + +// Convert from (almost-)Montgomery form z := (x / 2^{64k}) mod m +// Inputs x[k], m[k]; output z[k] +extern void bignum_demont (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); + +// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_demont_p256 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_demont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert from Montgomery form z := (x / 2^256) mod p_256k1, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_demont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert from Montgomery form z := (x / 2^384) mod p_384, assuming x reduced +// Input x[6]; output z[6] +extern void bignum_demont_p384 (uint64_t z[static 6], uint64_t x[static 6]); +extern void bignum_demont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); + +// Convert from Montgomery form z := (x / 2^576) mod p_521, assuming x reduced +// Input x[9]; output z[9] +extern void bignum_demont_p521 (uint64_t z[static 9], uint64_t x[static 9]); + +// Select digit x[n] +// Inputs x[k], n; output function return +extern uint64_t bignum_digit (uint64_t k, uint64_t *x, uint64_t n); + +// Return size of bignum in digits (64-bit word) +// Input x[k]; output function return +extern uint64_t bignum_digitsize (uint64_t k, uint64_t *x); + +// Divide bignum by 10: z' := z div 10, returning remainder z mod 10 +// Inputs z[k]; outputs function return (remainder) and z[k] +extern uint64_t bignum_divmod10 (uint64_t k, uint64_t *z); + +// Double modulo p_25519, z := (2 * x) mod p_25519, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_double_p25519 (uint64_t z[static 4], uint64_t x[static 4]); + +// Double modulo p_256, z := (2 * x) mod p_256, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_double_p256 (uint64_t z[static 4], uint64_t x[static 4]); + +// Double modulo p_256k1, z := (2 * x) mod p_256k1, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_double_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); + +// Double modulo p_384, z := (2 * x) mod p_384, assuming x reduced +// Input x[6]; output z[6] +extern void bignum_double_p384 (uint64_t z[static 6], uint64_t x[static 6]); + +// Double modulo p_521, z := (2 * x) mod p_521, assuming x reduced +// Input x[9]; output z[9] +extern void bignum_double_p521 (uint64_t z[static 9], uint64_t x[static 9]); + +// Extended Montgomery reduce, returning results in input-output buffer +// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k] +extern uint64_t bignum_emontredc (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); + +// Extended Montgomery reduce in 8-digit blocks, results in input-output buffer +// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k] +extern uint64_t bignum_emontredc_8n (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); + +// Test bignums for equality, x = y +// Inputs x[m], y[n]; output function return +extern uint64_t bignum_eq (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Test bignum for even-ness +// Input x[k]; output function return +extern uint64_t bignum_even (uint64_t k, uint64_t *x); + +// Convert 4-digit (256-bit) bignum from big-endian bytes +// Input x[32] (bytes); output z[4] +extern void bignum_frombebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); + +// Convert 6-digit (384-bit) bignum from big-endian bytes +// Input x[48] (bytes); output z[6] +extern void bignum_frombebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); + +// Convert 4-digit (256-bit) bignum from little-endian bytes +// Input x[32] (bytes); output z[4] +extern void bignum_fromlebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); + +// Convert 6-digit (384-bit) bignum from little-endian bytes +// Input x[48] (bytes); output z[6] +extern void bignum_fromlebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); + +// Convert little-endian bytes to 9-digit 528-bit bignum +// Input x[66] (bytes); output z[9] +extern void bignum_fromlebytes_p521 (uint64_t z[static 9],uint8_t x[static 66]); + +// Compare bignums, x >= y +// Inputs x[m], y[n]; output function return +extern uint64_t bignum_ge (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Compare bignums, x > y +// Inputs x[m], y[n]; output function return +extern uint64_t bignum_gt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Halve modulo p_256, z := (x / 2) mod p_256, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_half_p256 (uint64_t z[static 4], uint64_t x[static 4]); + +// Halve modulo p_256k1, z := (x / 2) mod p_256k1, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_half_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); + +// Halve modulo p_384, z := (x / 2) mod p_384, assuming x reduced +// Input x[6]; output z[6] +extern void bignum_half_p384 (uint64_t z[static 6], uint64_t x[static 6]); + +// Halve modulo p_521, z := (x / 2) mod p_521, assuming x reduced +// Input x[9]; output z[9] +extern void bignum_half_p521 (uint64_t z[static 9], uint64_t x[static 9]); + +// Test bignum for zero-ness, x = 0 +// Input x[k]; output function return +extern uint64_t bignum_iszero (uint64_t k, uint64_t *x); + +// Multiply z := x * y +// Inputs x[16], y[16]; output z[32]; temporary buffer t[>=32] +extern void bignum_kmul_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t y[static 16], uint64_t t[static 32]); + +// Multiply z := x * y +// Inputs x[32], y[32]; output z[64]; temporary buffer t[>=96] +extern void bignum_kmul_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t y[static 32], uint64_t t[static 96]); + +// Square, z := x^2 +// Input x[16]; output z[32]; temporary buffer t[>=24] +extern void bignum_ksqr_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t t[static 24]); + +// Square, z := x^2 +// Input x[32]; output z[64]; temporary buffer t[>=72] +extern void bignum_ksqr_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t t[static 72]); + +// Compare bignums, x <= y +// Inputs x[m], y[n]; output function return +extern uint64_t bignum_le (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Convert 4-digit (256-bit) bignum to/from little-endian form +// Input x[4]; output z[4] +extern void bignum_littleendian_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert 6-digit (384-bit) bignum to/from little-endian form +// Input x[6]; output z[6] +extern void bignum_littleendian_6 (uint64_t z[static 6], uint64_t x[static 6]); + +// Compare bignums, x < y +// Inputs x[m], y[n]; output function return +extern uint64_t bignum_lt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Multiply-add, z := z + x * y +// Inputs x[m], y[n]; outputs function return (carry-out) and z[k] +extern uint64_t bignum_madd (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Reduce modulo group order, z := x mod n_256 +// Input x[k]; output z[4] +extern void bignum_mod_n256 (uint64_t z[static 4], uint64_t k, uint64_t *x); +extern void bignum_mod_n256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); + +// Reduce modulo group order, z := x mod n_256 +// Input x[4]; output z[4] +extern void bignum_mod_n256_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Reduce modulo group order, z := x mod n_256k1 +// Input x[4]; output z[4] +extern void bignum_mod_n256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Reduce modulo group order, z := x mod n_384 +// Input x[k]; output z[6] +extern void bignum_mod_n384 (uint64_t z[static 6], uint64_t k, uint64_t *x); +extern void bignum_mod_n384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); + +// Reduce modulo group order, z := x mod n_384 +// Input x[6]; output z[6] +extern void bignum_mod_n384_6 (uint64_t z[static 6], uint64_t x[static 6]); + +// Reduce modulo group order, z := x mod n_521 +// Input x[9]; output z[9] +extern void bignum_mod_n521_9 (uint64_t z[static 9], uint64_t x[static 9]); +extern void bignum_mod_n521_9_alt (uint64_t z[static 9], uint64_t x[static 9]); + +// Reduce modulo field characteristic, z := x mod p_25519 +// Input x[4]; output z[4] +extern void bignum_mod_p25519_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Reduce modulo field characteristic, z := x mod p_256 +// Input x[k]; output z[4] +extern void bignum_mod_p256 (uint64_t z[static 4], uint64_t k, uint64_t *x); +extern void bignum_mod_p256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); + +// Reduce modulo field characteristic, z := x mod p_256 +// Input x[4]; output z[4] +extern void bignum_mod_p256_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Reduce modulo field characteristic, z := x mod p_256k1 +// Input x[4]; output z[4] +extern void bignum_mod_p256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); + +// Reduce modulo field characteristic, z := x mod p_384 +// Input x[k]; output z[6] +extern void bignum_mod_p384 (uint64_t z[static 6], uint64_t k, uint64_t *x); +extern void bignum_mod_p384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); + +// Reduce modulo field characteristic, z := x mod p_384 +// Input x[6]; output z[6] +extern void bignum_mod_p384_6 (uint64_t z[static 6], uint64_t x[static 6]); + +// Reduce modulo field characteristic, z := x mod p_521 +// Input x[9]; output z[9] +extern void bignum_mod_p521_9 (uint64_t z[static 9], uint64_t x[static 9]); + +// Add modulo m, z := (x + y) mod m, assuming x and y reduced +// Inputs x[k], y[k], m[k]; output z[k] +extern void bignum_modadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); + +// Double modulo m, z := (2 * x) mod m, assuming x reduced +// Inputs x[k], m[k]; output z[k] +extern void bignum_moddouble (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); + +// Compute "modification" constant z := 2^{64k} mod m +// Input m[k]; output z[k]; temporary buffer t[>=k] +extern void bignum_modifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); + +// Invert modulo m, z = (1/a) mod b, assuming b is an odd number > 1, a coprime to b +// Inputs a[k], b[k]; output z[k]; temporary buffer t[>=3*k] +extern void bignum_modinv (uint64_t k, uint64_t *z, uint64_t *a, uint64_t *b, uint64_t *t); + +// Optionally negate modulo m, z := (-x) mod m (if p nonzero) or z := x (if p zero), assuming x reduced +// Inputs p, x[k], m[k]; output z[k] +extern void bignum_modoptneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x, uint64_t *m); + +// Subtract modulo m, z := (x - y) mod m, assuming x and y reduced +// Inputs x[k], y[k], m[k]; output z[k] +extern void bignum_modsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); + +// Compute "montification" constant z := 2^{128k} mod m +// Input m[k]; output z[k]; temporary buffer t[>=k] +extern void bignum_montifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); + +// Montgomery multiply, z := (x * y / 2^{64k}) mod m +// Inputs x[k], y[k], m[k]; output z[k] +extern void bignum_montmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); + +// Montgomery multiply, z := (x * y / 2^256) mod p_256 +// Inputs x[4], y[4]; output z[4] +extern void bignum_montmul_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); +extern void bignum_montmul_p256_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Montgomery multiply, z := (x * y / 2^256) mod p_256k1 +// Inputs x[4], y[4]; output z[4] +extern void bignum_montmul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); +extern void bignum_montmul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Montgomery multiply, z := (x * y / 2^384) mod p_384 +// Inputs x[6], y[6]; output z[6] +extern void bignum_montmul_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); +extern void bignum_montmul_p384_alt (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); + +// Montgomery multiply, z := (x * y / 2^576) mod p_521 +// Inputs x[9], y[9]; output z[9] +extern void bignum_montmul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); +extern void bignum_montmul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); + +// Montgomery reduce, z := (x' / 2^{64p}) MOD m +// Inputs x[n], m[k], p; output z[k] +extern void bignum_montredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); + +// Montgomery square, z := (x^2 / 2^{64k}) mod m +// Inputs x[k], m[k]; output z[k] +extern void bignum_montsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); + +// Montgomery square, z := (x^2 / 2^256) mod p_256 +// Input x[4]; output z[4] +extern void bignum_montsqr_p256 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_montsqr_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Montgomery square, z := (x^2 / 2^256) mod p_256k1 +// Input x[4]; output z[4] +extern void bignum_montsqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_montsqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Montgomery square, z := (x^2 / 2^384) mod p_384 +// Input x[6]; output z[6] +extern void bignum_montsqr_p384 (uint64_t z[static 6], uint64_t x[static 6]); +extern void bignum_montsqr_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); + +// Montgomery square, z := (x^2 / 2^576) mod p_521 +// Input x[9]; output z[9] +extern void bignum_montsqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); +extern void bignum_montsqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); + +// Multiply z := x * y +// Inputs x[m], y[n]; output z[k] +extern void bignum_mul (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Multiply z := x * y +// Inputs x[4], y[4]; output z[8] +extern void bignum_mul_4_8 (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); +extern void bignum_mul_4_8_alt (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); + +// Multiply z := x * y +// Inputs x[6], y[6]; output z[12] +extern void bignum_mul_6_12 (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); +extern void bignum_mul_6_12_alt (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); + +// Multiply z := x * y +// Inputs x[8], y[8]; output z[16] +extern void bignum_mul_8_16 (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); +extern void bignum_mul_8_16_alt (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); + +// Multiply modulo p_25519, z := (x * y) mod p_25519 +// Inputs x[4], y[4]; output z[4] +extern void bignum_mul_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); +extern void bignum_mul_p25519_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Multiply modulo p_256k1, z := (x * y) mod p_256k1 +// Inputs x[4], y[4]; output z[4] +extern void bignum_mul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); +extern void bignum_mul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced +// Inputs x[9], y[9]; output z[9] +extern void bignum_mul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); +extern void bignum_mul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); + +// Multiply bignum by 10 and add word: z := 10 * z + d +// Inputs z[k], d; outputs function return (carry) and z[k] +extern uint64_t bignum_muladd10 (uint64_t k, uint64_t *z, uint64_t d); + +// Multiplex/select z := x (if p nonzero) or z := y (if p zero) +// Inputs p, x[k], y[k]; output z[k] +extern void bignum_mux (uint64_t p, uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y); + +// 256-bit multiplex/select z := x (if p nonzero) or z := y (if p zero) +// Inputs p, x[4], y[4]; output z[4] +extern void bignum_mux_4 (uint64_t p, uint64_t z[static 4],uint64_t x[static 4], uint64_t y[static 4]); + +// 384-bit multiplex/select z := x (if p nonzero) or z := y (if p zero) +// Inputs p, x[6], y[6]; output z[6] +extern void bignum_mux_6 (uint64_t p, uint64_t z[static 6],uint64_t x[static 6], uint64_t y[static 6]); + +// Select element from 16-element table, z := xs[k*i] +// Inputs xs[16*k], i; output z[k] +extern void bignum_mux16 (uint64_t k, uint64_t *z, uint64_t *xs, uint64_t i); + +// Negate modulo p_25519, z := (-x) mod p_25519, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_neg_p25519 (uint64_t z[static 4], uint64_t x[static 4]); + +// Negate modulo p_256, z := (-x) mod p_256, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_neg_p256 (uint64_t z[static 4], uint64_t x[static 4]); + +// Negate modulo p_256k1, z := (-x) mod p_256k1, assuming x reduced +// Input x[4]; output z[4] +extern void bignum_neg_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); + +// Negate modulo p_384, z := (-x) mod p_384, assuming x reduced +// Input x[6]; output z[6] +extern void bignum_neg_p384 (uint64_t z[static 6], uint64_t x[static 6]); + +// Negate modulo p_521, z := (-x) mod p_521, assuming x reduced +// Input x[9]; output z[9] +extern void bignum_neg_p521 (uint64_t z[static 9], uint64_t x[static 9]); + +// Negated modular inverse, z := (-1/x) mod 2^{64k} +// Input x[k]; output z[k] +extern void bignum_negmodinv (uint64_t k, uint64_t *z, uint64_t *x); + +// Test bignum for nonzero-ness x =/= 0 +// Input x[k]; output function return +extern uint64_t bignum_nonzero (uint64_t k, uint64_t *x); + +// Test 256-bit bignum for nonzero-ness x =/= 0 +// Input x[4]; output function return +extern uint64_t bignum_nonzero_4(uint64_t x[static 4]); + +// Test 384-bit bignum for nonzero-ness x =/= 0 +// Input x[6]; output function return +extern uint64_t bignum_nonzero_6(uint64_t x[static 6]); + +// Normalize bignum in-place by shifting left till top bit is 1 +// Input z[k]; outputs function return (bits shifted left) and z[k] +extern uint64_t bignum_normalize (uint64_t k, uint64_t *z); + +// Test bignum for odd-ness +// Input x[k]; output function return +extern uint64_t bignum_odd (uint64_t k, uint64_t *x); + +// Convert single digit to bignum, z := n +// Input n; output z[k] +extern void bignum_of_word (uint64_t k, uint64_t *z, uint64_t n); + +// Optionally add, z := x + y (if p nonzero) or z := x (if p zero) +// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] +extern uint64_t bignum_optadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); + +// Optionally negate, z := -x (if p nonzero) or z := x (if p zero) +// Inputs p, x[k]; outputs function return (nonzero input) and z[k] +extern uint64_t bignum_optneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x); + +// Optionally negate modulo p_25519, z := (-x) mod p_25519 (if p nonzero) or z := x (if p zero), assuming x reduced +// Inputs p, x[4]; output z[4] +extern void bignum_optneg_p25519 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); + +// Optionally negate modulo p_256, z := (-x) mod p_256 (if p nonzero) or z := x (if p zero), assuming x reduced +// Inputs p, x[4]; output z[4] +extern void bignum_optneg_p256 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); + +// Optionally negate modulo p_256k1, z := (-x) mod p_256k1 (if p nonzero) or z := x (if p zero), assuming x reduced +// Inputs p, x[4]; output z[4] +extern void bignum_optneg_p256k1 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); + +// Optionally negate modulo p_384, z := (-x) mod p_384 (if p nonzero) or z := x (if p zero), assuming x reduced +// Inputs p, x[6]; output z[6] +extern void bignum_optneg_p384 (uint64_t z[static 6], uint64_t p, uint64_t x[static 6]); + +// Optionally negate modulo p_521, z := (-x) mod p_521 (if p nonzero) or z := x (if p zero), assuming x reduced +// Inputs p, x[9]; output z[9] +extern void bignum_optneg_p521 (uint64_t z[static 9], uint64_t p, uint64_t x[static 9]); + +// Optionally subtract, z := x - y (if p nonzero) or z := x (if p zero) +// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] +extern uint64_t bignum_optsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); + +// Optionally subtract or add, z := x + sgn(p) * y interpreting p as signed +// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] +extern uint64_t bignum_optsubadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); + +// Return bignum of power of 2, z := 2^n +// Input n; output z[k] +extern void bignum_pow2 (uint64_t k, uint64_t *z, uint64_t n); + +// Shift bignum left by c < 64 bits z := x * 2^c +// Inputs x[n], c; outputs function return (carry-out) and z[k] +extern uint64_t bignum_shl_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); + +// Shift bignum right by c < 64 bits z := floor(x / 2^c) +// Inputs x[n], c; outputs function return (bits shifted out) and z[k] +extern uint64_t bignum_shr_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); + +// Square, z := x^2 +// Input x[n]; output z[k] +extern void bignum_sqr (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); + +// Square, z := x^2 +// Input x[4]; output z[8] +extern void bignum_sqr_4_8 (uint64_t z[static 8], uint64_t x[static 4]); +extern void bignum_sqr_4_8_alt (uint64_t z[static 8], uint64_t x[static 4]); + +// Square, z := x^2 +// Input x[6]; output z[12] +extern void bignum_sqr_6_12 (uint64_t z[static 12], uint64_t x[static 6]); +extern void bignum_sqr_6_12_alt (uint64_t z[static 12], uint64_t x[static 6]); + +// Square, z := x^2 +// Input x[8]; output z[16] +extern void bignum_sqr_8_16 (uint64_t z[static 16], uint64_t x[static 8]); +extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]); + +// Square modulo p_25519, z := (x^2) mod p_25519 +// Input x[4]; output z[4] +extern void bignum_sqr_p25519 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_sqr_p25519_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Square modulo p_256k1, z := (x^2) mod p_256k1 +// Input x[4]; output z[4] +extern void bignum_sqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_sqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Square modulo p_521, z := (x^2) mod p_521, assuming x reduced +// Input x[9]; output z[9] +extern void bignum_sqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); +extern void bignum_sqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); + +// Subtract, z := x - y +// Inputs x[m], y[n]; outputs function return (carry-out) and z[p] +extern uint64_t bignum_sub (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); + +// Subtract modulo p_25519, z := (x - y) mod p_25519, assuming x and y reduced +// Inputs x[4], y[4]; output z[4] +extern void bignum_sub_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Subtract modulo p_256, z := (x - y) mod p_256, assuming x and y reduced +// Inputs x[4], y[4]; output z[4] +extern void bignum_sub_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Subtract modulo p_256k1, z := (x - y) mod p_256k1, assuming x and y reduced +// Inputs x[4], y[4]; output z[4] +extern void bignum_sub_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); + +// Subtract modulo p_384, z := (x - y) mod p_384, assuming x and y reduced +// Inputs x[6], y[6]; output z[6] +extern void bignum_sub_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); + +// Subtract modulo p_521, z := (x - y) mod p_521, assuming x and y reduced +// Inputs x[9], y[9]; output z[9] +extern void bignum_sub_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); + +// Convert 4-digit (256-bit) bignum to big-endian bytes +// Input x[4]; output z[32] (bytes) +extern void bignum_tobebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); + +// Convert 6-digit (384-bit) bignum to big-endian bytes +// Input x[6]; output z[48] (bytes) +extern void bignum_tobebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); + +// Convert 4-digit (256-bit) bignum to little-endian bytes +// Input x[4]; output z[32] (bytes) +extern void bignum_tolebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); + +// Convert 6-digit (384-bit) bignum to little-endian bytes +// Input x[6]; output z[48] (bytes) +extern void bignum_tolebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); + +// Convert 9-digit 528-bit bignum to little-endian bytes +// Input x[6]; output z[66] (bytes) +extern void bignum_tolebytes_p521 (uint8_t z[static 66], uint64_t x[static 9]); + +// Convert to Montgomery form z := (2^256 * x) mod p_256 +// Input x[4]; output z[4] +extern void bignum_tomont_p256 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_tomont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert to Montgomery form z := (2^256 * x) mod p_256k1 +// Input x[4]; output z[4] +extern void bignum_tomont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_tomont_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Convert to Montgomery form z := (2^384 * x) mod p_384 +// Input x[6]; output z[6] +extern void bignum_tomont_p384 (uint64_t z[static 6], uint64_t x[static 6]); +extern void bignum_tomont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); + +// Convert to Montgomery form z := (2^576 * x) mod p_521 +// Input x[9]; output z[9] +extern void bignum_tomont_p521 (uint64_t z[static 9], uint64_t x[static 9]); + +// Triple modulo p_256, z := (3 * x) mod p_256 +// Input x[4]; output z[4] +extern void bignum_triple_p256 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_triple_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Triple modulo p_256k1, z := (3 * x) mod p_256k1 +// Input x[4]; output z[4] +extern void bignum_triple_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); +extern void bignum_triple_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); + +// Triple modulo p_384, z := (3 * x) mod p_384 +// Input x[6]; output z[6] +extern void bignum_triple_p384 (uint64_t z[static 6], uint64_t x[static 6]); +extern void bignum_triple_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); + +// Triple modulo p_521, z := (3 * x) mod p_521, assuming x reduced +// Input x[9]; output z[9] +extern void bignum_triple_p521 (uint64_t z[static 9], uint64_t x[static 9]); +extern void bignum_triple_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); + +// Montgomery ladder step for curve25519 +// Inputs point[8], pp[16], b; output rr[16] +extern void curve25519_ladderstep(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); +extern void curve25519_ladderstep_alt(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); + +// Projective scalar multiplication, x coordinate only, for curve25519 +// Inputs scalar[4], point[4]; output res[8] +extern void curve25519_pxscalarmul(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); +extern void curve25519_pxscalarmul_alt(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); + +// x25519 function for curve25519 +// Inputs scalar[4], point[4]; output res[4] +extern void curve25519_x25519(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); +extern void curve25519_x25519_alt(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); + +// x25519 function for curve25519 on base element 9 +// Input scalar[4]; output res[4] +extern void curve25519_x25519base(uint64_t res[static 4],uint64_t scalar[static 4]); +extern void curve25519_x25519base_alt(uint64_t res[static 4],uint64_t scalar[static 4]); + +// Extended projective addition for edwards25519 +// Inputs p1[16], p2[16]; output p3[16] +extern void edwards25519_epadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); +extern void edwards25519_epadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); + +// Extended projective doubling for edwards25519 +// Inputs p1[12]; output p3[16] +extern void edwards25519_epdouble(uint64_t p3[static 16],uint64_t p1[static 12]); +extern void edwards25519_epdouble_alt(uint64_t p3[static 16],uint64_t p1[static 12]); + +// Projective doubling for edwards25519 +// Inputs p1[12]; output p3[12] +extern void edwards25519_pdouble(uint64_t p3[static 12],uint64_t p1[static 12]); +extern void edwards25519_pdouble_alt(uint64_t p3[static 12],uint64_t p1[static 12]); + +// Extended projective + precomputed mixed addition for edwards25519 +// Inputs p1[16], p2[12]; output p3[16] +extern void edwards25519_pepadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); +extern void edwards25519_pepadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); + +// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates +// Inputs p1[12], p2[12]; output p3[12] +extern void p256_montjadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); + +// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates +// Inputs p1[12]; output p3[12] +extern void p256_montjdouble(uint64_t p3[static 12],uint64_t p1[static 12]); + +// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates +// Inputs p1[12], p2[8]; output p3[12] +extern void p256_montjmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); + +// Point addition on NIST curve P-384 in Montgomery-Jacobian coordinates +// Inputs p1[18], p2[18]; output p3[18] +extern void p384_montjadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 18]); + +// Point doubling on NIST curve P-384 in Montgomery-Jacobian coordinates +// Inputs p1[18]; output p3[18] +extern void p384_montjdouble(uint64_t p3[static 18],uint64_t p1[static 18]); + +// Point mixed addition on NIST curve P-384 in Montgomery-Jacobian coordinates +// Inputs p1[18], p2[12]; output p3[18] +extern void p384_montjmixadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 12]); + +// Point addition on NIST curve P-521 in Jacobian coordinates +// Inputs p1[27], p2[27]; output p3[27] +extern void p521_jadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 27]); + +// Point doubling on NIST curve P-521 in Jacobian coordinates +// Input p1[27]; output p3[27] +extern void p521_jdouble(uint64_t p3[static 27],uint64_t p1[static 27]); + +// Point mixed addition on NIST curve P-521 in Jacobian coordinates +// Inputs p1[27], p2[18]; output p3[27] +extern void p521_jmixadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 18]); + +// Point addition on SECG curve secp256k1 in Jacobian coordinates +// Inputs p1[12], p2[12]; output p3[12] +extern void secp256k1_jadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); + +// Point doubling on SECG curve secp256k1 in Jacobian coordinates +// Input p1[12]; output p3[12] +extern void secp256k1_jdouble(uint64_t p3[static 12],uint64_t p1[static 12]); + +// Point mixed addition on SECG curve secp256k1 in Jacobian coordinates +// Inputs p1[12], p2[8]; output p3[12] +extern void secp256k1_jmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); + +// Reverse the bytes in a single word +// Input a; output function return +extern uint64_t word_bytereverse (uint64_t a); + +// Count leading zero bits in a single word +// Input a; output function return +extern uint64_t word_clz (uint64_t a); + +// Count trailing zero bits in a single word +// Input a; output function return +extern uint64_t word_ctz (uint64_t a); + +// Return maximum of two unsigned 64-bit words +// Inputs a, b; output function return +extern uint64_t word_max (uint64_t a, uint64_t b); + +// Return minimum of two unsigned 64-bit words +// Inputs a, b; output function return +extern uint64_t word_min (uint64_t a, uint64_t b); + +// Single-word negated modular inverse (-1/a) mod 2^64 +// Input a; output function return +extern uint64_t word_negmodinv (uint64_t a); + +// Single-word reciprocal, 2^64 + ret = ceil(2^128/a) - 1 if MSB of "a" is set +// Input a; output function return +extern uint64_t word_recip (uint64_t a); diff --git a/Libraries/libressl/crypto/bn/s2n_bignum_internal.h b/Libraries/libressl/crypto/bn/s2n_bignum_internal.h new file mode 100644 index 000000000..f41368833 --- /dev/null +++ b/Libraries/libressl/crypto/bn/s2n_bignum_internal.h @@ -0,0 +1,30 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#ifdef __APPLE__ +# define S2N_BN_SYMBOL(NAME) _##NAME +#else +# define S2N_BN_SYMBOL(name) name +#endif + +#define S2N_BN_SYM_VISIBILITY_DIRECTIVE(name) .globl S2N_BN_SYMBOL(name) +#ifdef S2N_BN_HIDE_SYMBOLS +# ifdef __APPLE__ +# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) .private_extern S2N_BN_SYMBOL(name) +# else +# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) .hidden S2N_BN_SYMBOL(name) +# endif +#else +# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) /* NO-OP: S2N_BN_SYM_PRIVACY_DIRECTIVE */ +#endif diff --git a/Libraries/libressl/crypto/buffer/buf_err.c b/Libraries/libressl/crypto/buffer/buf_err.c new file mode 100644 index 000000000..3b045cf58 --- /dev/null +++ b/Libraries/libressl/crypto/buffer/buf_err.c @@ -0,0 +1,89 @@ +/* $OpenBSD: buf_err.c,v 1.13 2023/07/08 08:26:26 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason) + +static ERR_STRING_DATA BUF_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA BUF_str_reasons[] = { + {0, NULL} +}; + +#endif + +void +ERR_load_BUF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) { + ERR_load_strings(0, BUF_str_functs); + ERR_load_strings(0, BUF_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_BUF_strings); diff --git a/Libraries/libressl/crypto/buffer/buffer.c b/Libraries/libressl/crypto/buffer/buffer.c new file mode 100644 index 000000000..51ce90ff8 --- /dev/null +++ b/Libraries/libressl/crypto/buffer/buffer.c @@ -0,0 +1,155 @@ +/* $OpenBSD: buffer.c,v 1.28 2023/07/08 08:26:26 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include + +/* + * LIMIT_BEFORE_EXPANSION is the maximum n such that (n + 3) / 3 * 4 < 2**31. + * That function is applied in several functions in this file and this limit + * ensures that the result fits in an int. + */ +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc + +BUF_MEM * +BUF_MEM_new(void) +{ + BUF_MEM *ret; + + if ((ret = calloc(1, sizeof(BUF_MEM))) == NULL) { + BUFerror(ERR_R_MALLOC_FAILURE); + return (NULL); + } + + return (ret); +} +LCRYPTO_ALIAS(BUF_MEM_new); + +void +BUF_MEM_free(BUF_MEM *a) +{ + if (a == NULL) + return; + + freezero(a->data, a->max); + free(a); +} +LCRYPTO_ALIAS(BUF_MEM_free); + +int +BUF_MEM_grow(BUF_MEM *str, size_t len) +{ + return BUF_MEM_grow_clean(str, len); +} +LCRYPTO_ALIAS(BUF_MEM_grow); + +int +BUF_MEM_grow_clean(BUF_MEM *str, size_t len) +{ + char *ret; + size_t n; + + if (str->max >= len) { + if (str->length >= len) + memset(&str->data[len], 0, str->length - len); + str->length = len; + return (len); + } + + if (len > LIMIT_BEFORE_EXPANSION) { + BUFerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + n = (len + 3) / 3 * 4; + if ((ret = recallocarray(str->data, str->max, n, 1)) == NULL) { + BUFerror(ERR_R_MALLOC_FAILURE); + return (0); + } + str->data = ret; + str->max = n; + str->length = len; + + return (len); +} +LCRYPTO_ALIAS(BUF_MEM_grow_clean); + +void +BUF_reverse(unsigned char *out, const unsigned char *in, size_t size) +{ + size_t i; + + if (in) { + out += size - 1; + for (i = 0; i < size; i++) + *out-- = *in++; + } else { + unsigned char *q; + char c; + q = out + size - 1; + for (i = 0; i < size / 2; i++) { + c = *q; + *q-- = *out; + *out++ = c; + } + } +} diff --git a/Libraries/libressl/crypto/bytestring/bs_ber.c b/Libraries/libressl/crypto/bytestring/bs_ber.c new file mode 100644 index 000000000..c9779c896 --- /dev/null +++ b/Libraries/libressl/crypto/bytestring/bs_ber.c @@ -0,0 +1,269 @@ +/* $OpenBSD: bs_ber.c,v 1.2 2021/12/15 18:02:39 jsing Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bytestring.h" + +/* + * kMaxDepth is a just a sanity limit. The code should be such that the length + * of the input being processes always decreases. None the less, a very large + * input could otherwise cause the stack to overflow. + */ +static const unsigned int kMaxDepth = 2048; + +/* Non-strict version that allows a relaxed DER with indefinite form. */ +static int +cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len) +{ + return cbs_get_any_asn1_element_internal(cbs, out, + out_tag, out_header_len, 0); +} + +/* + * cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets + * |*indefinite_found| depending on whether an indefinite length element was + * found. The value of |orig_in| is not modified. + * + * Returns one on success (i.e. |*indefinite_found| was set) and zero on error. + */ +static int +cbs_find_indefinite(const CBS *orig_in, char *indefinite_found, + unsigned int depth) +{ + CBS in; + + if (depth > kMaxDepth) + return 0; + + CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); + + while (CBS_len(&in) > 0) { + CBS contents; + unsigned int tag; + size_t header_len; + + if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag, + &header_len)) + return 0; + + /* Indefinite form not allowed by DER. */ + if (CBS_len(&contents) == header_len && header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + *indefinite_found = 1; + return 1; + } + if (tag & CBS_ASN1_CONSTRUCTED) { + if (!CBS_skip(&contents, header_len) || + !cbs_find_indefinite(&contents, indefinite_found, + depth + 1)) + return 0; + } + } + + *indefinite_found = 0; + return 1; +} + +/* + * is_primitive_type returns true if |tag| likely a primitive type. Normally + * one can just test the "constructed" bit in the tag but, in BER, even + * primitive tags can have the constructed bit if they have indefinite + * length. + */ +static char +is_primitive_type(unsigned int tag) +{ + return (tag & 0xc0) == 0 && + (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) && + (tag & 0x1f) != (CBS_ASN1_SET & 0x1f); +} + +/* + * is_eoc returns true if |header_len| and |contents|, as returned by + * |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC) + * value. + */ +static char +is_eoc(size_t header_len, CBS *contents) +{ + const unsigned char eoc[] = {0x0, 0x0}; + + return header_len == 2 && CBS_mem_equal(contents, eoc, 2); +} + +/* + * cbs_convert_indefinite reads data with DER encoding (but relaxed to allow + * indefinite form) from |in| and writes definite form DER data to |out|. If + * |squash_header| is set then the top-level of elements from |in| will not + * have their headers written. This is used when concatenating the fragments of + * an indefinite length, primitive value. If |looking_for_eoc| is set then any + * EOC elements found will cause the function to return after consuming it. + * It returns one on success and zero on error. + */ +static int +cbs_convert_indefinite(CBS *in, CBB *out, char squash_header, + char looking_for_eoc, unsigned int depth) +{ + if (depth > kMaxDepth) + return 0; + + while (CBS_len(in) > 0) { + CBS contents; + unsigned int tag; + size_t header_len; + CBB *out_contents, out_contents_storage; + + if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag, + &header_len)) + return 0; + + out_contents = out; + + if (CBS_len(&contents) == header_len) { + if (is_eoc(header_len, &contents)) + return looking_for_eoc; + + if (header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + /* + * This is an indefinite length element. If + * it's a SEQUENCE or SET then we just need to + * write the out the contents as normal, but + * with a concrete length prefix. + * + * If it's a something else then the contents + * will be a series of DER elements of the same + * type which need to be concatenated. + */ + const char context_specific = (tag & 0xc0) + == 0x80; + char squash_child_headers = + is_primitive_type(tag); + + /* + * This is a hack, but it sufficies to handle + * NSS's output. If we find an indefinite + * length, context-specific tag with a definite, + * primtive tag inside it, then we assume that + * the context-specific tag is implicit and the + * tags within are fragments of a primitive type + * that need to be concatenated. + */ + if (context_specific && + (tag & CBS_ASN1_CONSTRUCTED)) { + CBS in_copy, inner_contents; + unsigned int inner_tag; + size_t inner_header_len; + + CBS_init(&in_copy, CBS_data(in), + CBS_len(in)); + if (!cbs_nonstrict_get_any_asn1_element( + &in_copy, &inner_contents, + &inner_tag, &inner_header_len)) + return 0; + + if (CBS_len(&inner_contents) > + inner_header_len && + is_primitive_type(inner_tag)) + squash_child_headers = 1; + } + + if (!squash_header) { + unsigned int out_tag = tag; + + if (squash_child_headers) + out_tag &= + ~CBS_ASN1_CONSTRUCTED; + + if (!CBB_add_asn1(out, + &out_contents_storage, out_tag)) + return 0; + + out_contents = &out_contents_storage; + } + + if (!cbs_convert_indefinite(in, out_contents, + squash_child_headers, + 1 /* looking for eoc */, depth + 1)) + return 0; + + if (out_contents != out && !CBB_flush(out)) + return 0; + + continue; + } + } + + if (!squash_header) { + if (!CBB_add_asn1(out, &out_contents_storage, tag)) + return 0; + + out_contents = &out_contents_storage; + } + + if (!CBS_skip(&contents, header_len)) + return 0; + + if (tag & CBS_ASN1_CONSTRUCTED) { + if (!cbs_convert_indefinite(&contents, out_contents, + 0 /* don't squash header */, + 0 /* not looking for eoc */, depth + 1)) + return 0; + } else { + if (!CBB_add_bytes(out_contents, CBS_data(&contents), + CBS_len(&contents))) + return 0; + } + + if (out_contents != out && !CBB_flush(out)) + return 0; + } + + return looking_for_eoc == 0; +} + +int +CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len) +{ + CBB cbb; + + /* + * First, do a quick walk to find any indefinite-length elements. Most + * of the time we hope that there aren't any and thus we can quickly + * return. + */ + char conversion_needed; + if (!cbs_find_indefinite(in, &conversion_needed, 0)) + return 0; + + if (!conversion_needed) { + *out = NULL; + *out_len = 0; + return 1; + } + + if (!CBB_init(&cbb, CBS_len(in))) + return 0; + if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) { + CBB_cleanup(&cbb); + return 0; + } + + return CBB_finish(&cbb, out, out_len); +} diff --git a/Libraries/libressl/crypto/bytestring/bs_cbb.c b/Libraries/libressl/crypto/bytestring/bs_cbb.c new file mode 100644 index 000000000..c8b6f4824 --- /dev/null +++ b/Libraries/libressl/crypto/bytestring/bs_cbb.c @@ -0,0 +1,483 @@ +/* $OpenBSD: bs_cbb.c,v 1.4 2022/07/07 17:16:05 tb Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "bytestring.h" + +#define CBB_INITIAL_SIZE 64 + +static int +cbb_init(CBB *cbb, uint8_t *buf, size_t cap) +{ + struct cbb_buffer_st *base; + + if ((base = calloc(1, sizeof(struct cbb_buffer_st))) == NULL) + return 0; + + base->buf = buf; + base->len = 0; + base->cap = cap; + base->can_resize = 1; + + cbb->base = base; + cbb->is_top_level = 1; + + return 1; +} + +int +CBB_init(CBB *cbb, size_t initial_capacity) +{ + uint8_t *buf = NULL; + + memset(cbb, 0, sizeof(*cbb)); + + if (initial_capacity == 0) + initial_capacity = CBB_INITIAL_SIZE; + + if ((buf = calloc(1, initial_capacity)) == NULL) + return 0; + + if (!cbb_init(cbb, buf, initial_capacity)) { + free(buf); + return 0; + } + + return 1; +} + +int +CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) +{ + memset(cbb, 0, sizeof(*cbb)); + + if (!cbb_init(cbb, buf, len)) + return 0; + + cbb->base->can_resize = 0; + + return 1; +} + +void +CBB_cleanup(CBB *cbb) +{ + if (cbb->base) { + if (cbb->base->can_resize) + freezero(cbb->base->buf, cbb->base->cap); + free(cbb->base); + } + cbb->base = NULL; + cbb->child = NULL; +} + +static int +cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len) +{ + size_t newlen; + + if (base == NULL) + return 0; + + newlen = base->len + len; + if (newlen < base->len) + /* Overflow */ + return 0; + + if (newlen > base->cap) { + size_t newcap = base->cap * 2; + uint8_t *newbuf; + + if (!base->can_resize) + return 0; + + if (newcap < base->cap || newcap < newlen) + newcap = newlen; + + newbuf = recallocarray(base->buf, base->cap, newcap, 1); + if (newbuf == NULL) + return 0; + + base->buf = newbuf; + base->cap = newcap; + } + + if (out) + *out = base->buf + base->len; + + base->len = newlen; + return 1; +} + +static int +cbb_add_u(CBB *cbb, uint32_t v, size_t len_len) +{ + uint8_t *buf; + size_t i; + + if (len_len == 0) + return 1; + + if (len_len > 4) + return 0; + + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len)) + return 0; + + for (i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + return 1; +} + +int +CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) +{ + if (!cbb->is_top_level) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) + /* + * |out_data| and |out_len| can only be NULL if the CBB is + * fixed. + */ + return 0; + + if (out_data != NULL && *out_data != NULL) + return 0; + + if (out_data != NULL) + *out_data = cbb->base->buf; + + if (out_len != NULL) + *out_len = cbb->base->len; + + cbb->base->buf = NULL; + CBB_cleanup(cbb); + return 1; +} + +/* + * CBB_flush recurses and then writes out any pending length prefix. The current + * length of the underlying base is taken to be the length of the + * length-prefixed data. + */ +int +CBB_flush(CBB *cbb) +{ + size_t child_start, i, len; + + if (cbb->base == NULL) + return 0; + + if (cbb->child == NULL || cbb->pending_len_len == 0) + return 1; + + child_start = cbb->offset + cbb->pending_len_len; + + if (!CBB_flush(cbb->child) || child_start < cbb->offset || + cbb->base->len < child_start) + return 0; + + len = cbb->base->len - child_start; + + if (cbb->pending_is_asn1) { + /* + * For ASN.1, we assumed that we were using short form which + * only requires a single byte for the length octet. + * + * If it turns out that we need long form, we have to move + * the contents along in order to make space for more length + * octets. + */ + size_t len_len = 1; /* total number of length octets */ + uint8_t initial_length_byte; + + /* We already wrote 1 byte for the length. */ + if (cbb->pending_len_len != 1) + return 0; + + /* Check for long form */ + if (len > 0xfffffffe) + return 0; /* 0xffffffff is reserved */ + else if (len > 0xffffff) + len_len = 5; + else if (len > 0xffff) + len_len = 4; + else if (len > 0xff) + len_len = 3; + else if (len > 0x7f) + len_len = 2; + + if (len_len == 1) { + /* For short form, the initial byte is the length. */ + initial_length_byte = len; + len = 0; + + } else { + /* + * For long form, the initial byte is the number of + * subsequent length octets (plus bit 8 set). + */ + initial_length_byte = 0x80 | (len_len - 1); + + /* + * We need to move the contents along in order to make + * space for the long form length octets. + */ + size_t extra_bytes = len_len - 1; + if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) + return 0; + + memmove(cbb->base->buf + child_start + extra_bytes, + cbb->base->buf + child_start, len); + } + cbb->base->buf[cbb->offset++] = initial_length_byte; + cbb->pending_len_len = len_len - 1; + } + + for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { + cbb->base->buf[cbb->offset + i] = len; + len >>= 8; + } + if (len != 0) + return 0; + + cbb->child->base = NULL; + cbb->child = NULL; + cbb->pending_len_len = 0; + cbb->pending_is_asn1 = 0; + cbb->offset = 0; + + return 1; +} + +void +CBB_discard_child(CBB *cbb) +{ + if (cbb->child == NULL) + return; + + cbb->base->len = cbb->offset; + + cbb->child->base = NULL; + cbb->child = NULL; + cbb->pending_len_len = 0; + cbb->pending_is_asn1 = 0; + cbb->offset = 0; +} + +static int +cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len) +{ + uint8_t *prefix_bytes; + + if (!CBB_flush(cbb)) + return 0; + + cbb->offset = cbb->base->len; + if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) + return 0; + + memset(prefix_bytes, 0, len_len); + memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->pending_len_len = len_len; + cbb->pending_is_asn1 = 0; + + return 1; +} + +int +CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 1); +} + +int +CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 2); +} + +int +CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 3); +} + +int +CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag) +{ + if (tag > UINT8_MAX) + return 0; + + /* Long form identifier octets are not supported. */ + if ((tag & 0x1f) == 0x1f) + return 0; + + /* Short-form identifier octet only needs a single byte */ + if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) + return 0; + + /* + * Add 1 byte to cover the short-form length octet case. If it turns + * out we need long-form, it will be extended later. + */ + cbb->offset = cbb->base->len; + if (!CBB_add_u8(cbb, 0)) + return 0; + + memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->pending_len_len = 1; + cbb->pending_is_asn1 = 1; + + return 1; +} + +int +CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) +{ + uint8_t *dest; + + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len)) + return 0; + + memcpy(dest, data, len); + return 1; +} + +int +CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) +{ + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len)) + return 0; + + memset(*out_data, 0, len); + return 1; +} + +int +CBB_add_u8(CBB *cbb, size_t value) +{ + if (value > UINT8_MAX) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 1); +} + +int +CBB_add_u16(CBB *cbb, size_t value) +{ + if (value > UINT16_MAX) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 2); +} + +int +CBB_add_u24(CBB *cbb, size_t value) +{ + if (value > 0xffffffUL) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 3); +} + +int +CBB_add_u32(CBB *cbb, size_t value) +{ + if (value > 0xffffffffUL) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 4); +} + +int +CBB_add_u64(CBB *cbb, uint64_t value) +{ + uint32_t a, b; + + a = value >> 32; + b = value & 0xffffffff; + + if (!CBB_add_u32(cbb, a)) + return 0; + return CBB_add_u32(cbb, b); +} + +int +CBB_add_asn1_uint64(CBB *cbb, uint64_t value) +{ + CBB child; + size_t i; + int started = 0; + + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) + return 0; + + for (i = 0; i < 8; i++) { + uint8_t byte = (value >> 8 * (7 - i)) & 0xff; + + /* + * ASN.1 restriction: first 9 bits cannot be all zeroes or + * all ones. Since this function only encodes unsigned + * integers, the only concerns are not encoding leading + * zeros and adding a padding byte if necessary. + * + * In practice, this means: + * 1) Skip leading octets of all zero bits in the value + * 2) After skipping the leading zero octets, if the next 9 + * bits are all ones, add an all zero prefix octet (and + * set the high bit of the prefix octet if negative). + * + * Additionally, for an unsigned value, add an all zero + * prefix if the high bit of the first octet would be one. + */ + if (!started) { + if (byte == 0) + /* Don't encode leading zeros. */ + continue; + + /* + * If the high bit is set, add a padding byte to make it + * unsigned. + */ + if ((byte & 0x80) && !CBB_add_u8(&child, 0)) + return 0; + + started = 1; + } + if (!CBB_add_u8(&child, byte)) + return 0; + } + + /* 0 is encoded as a single 0, not the empty string. */ + if (!started && !CBB_add_u8(&child, 0)) + return 0; + + return CBB_flush(cbb); +} diff --git a/Libraries/libressl/crypto/bytestring/bs_cbs.c b/Libraries/libressl/crypto/bytestring/bs_cbs.c new file mode 100644 index 000000000..e2bb54e46 --- /dev/null +++ b/Libraries/libressl/crypto/bytestring/bs_cbs.c @@ -0,0 +1,615 @@ +/* $OpenBSD: bs_cbs.c,v 1.2 2021/12/15 18:02:39 jsing Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "bytestring.h" + +void +CBS_init(CBS *cbs, const uint8_t *data, size_t len) +{ + cbs->data = data; + cbs->initial_len = len; + cbs->len = len; +} + +void +CBS_dup(const CBS *cbs, CBS *out) +{ + CBS_init(out, CBS_data(cbs), CBS_len(cbs)); + out->initial_len = cbs->initial_len; +} + +static int +cbs_get(CBS *cbs, const uint8_t **p, size_t n) +{ + if (cbs->len < n) + return 0; + + *p = cbs->data; + cbs->data += n; + cbs->len -= n; + return 1; +} + +static int +cbs_peek(CBS *cbs, const uint8_t **p, size_t n) +{ + if (cbs->len < n) + return 0; + + *p = cbs->data; + return 1; +} + +size_t +CBS_offset(const CBS *cbs) +{ + return cbs->initial_len - cbs->len; +} + +int +CBS_skip(CBS *cbs, size_t len) +{ + const uint8_t *dummy; + return cbs_get(cbs, &dummy, len); +} + +const uint8_t * +CBS_data(const CBS *cbs) +{ + return cbs->data; +} + +size_t +CBS_len(const CBS *cbs) +{ + return cbs->len; +} + +int +CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) +{ + free(*out_ptr); + *out_ptr = NULL; + *out_len = 0; + + if (cbs->len == 0) + return 1; + + if ((*out_ptr = malloc(cbs->len)) == NULL) + return 0; + + memcpy(*out_ptr, cbs->data, cbs->len); + + *out_len = cbs->len; + return 1; +} + +int +CBS_strdup(const CBS *cbs, char **out_ptr) +{ + free(*out_ptr); + *out_ptr = NULL; + + if (CBS_contains_zero_byte(cbs)) + return 0; + + *out_ptr = strndup((const char *)cbs->data, cbs->len); + return (*out_ptr != NULL); +} + +int +CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied) +{ + if (dst_len < cbs->len) + return 0; + + memmove(dst, cbs->data, cbs->len); + + if (copied != NULL) + *copied = cbs->len; + + return 1; +} + +int +CBS_contains_zero_byte(const CBS *cbs) +{ + return memchr(cbs->data, 0, cbs->len) != NULL; +} + +int +CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) +{ + if (len != cbs->len) + return 0; + + return timingsafe_memcmp(cbs->data, data, len) == 0; +} + +static int +cbs_get_u(CBS *cbs, uint32_t *out, size_t len) +{ + uint32_t result = 0; + size_t i; + const uint8_t *data; + + if (len < 1 || len > 4) + return 0; + + if (!cbs_get(cbs, &data, len)) + return 0; + + for (i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int +CBS_get_u8(CBS *cbs, uint8_t *out) +{ + const uint8_t *v; + + if (!cbs_get(cbs, &v, 1)) + return 0; + + *out = *v; + return 1; +} + +int +CBS_get_u16(CBS *cbs, uint16_t *out) +{ + uint32_t v; + + if (!cbs_get_u(cbs, &v, 2)) + return 0; + + *out = v; + return 1; +} + +int +CBS_get_u24(CBS *cbs, uint32_t *out) +{ + return cbs_get_u(cbs, out, 3); +} + +int +CBS_get_u32(CBS *cbs, uint32_t *out) +{ + return cbs_get_u(cbs, out, 4); +} + +int +CBS_get_u64(CBS *cbs, uint64_t *out) +{ + uint32_t a, b; + + if (cbs->len < 8) + return 0; + + if (!CBS_get_u32(cbs, &a)) + return 0; + if (!CBS_get_u32(cbs, &b)) + return 0; + + *out = (uint64_t)a << 32 | b; + return 1; +} + +int +CBS_get_last_u8(CBS *cbs, uint8_t *out) +{ + if (cbs->len == 0) + return 0; + + *out = cbs->data[cbs->len - 1]; + cbs->len--; + return 1; +} + +int +CBS_get_bytes(CBS *cbs, CBS *out, size_t len) +{ + const uint8_t *v; + + if (!cbs_get(cbs, &v, len)) + return 0; + + CBS_init(out, v, len); + return 1; +} + +static int +cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) +{ + uint32_t len; + + if (!cbs_get_u(cbs, &len, len_len)) + return 0; + + return CBS_get_bytes(cbs, out, len); +} + +int +CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 1); +} + +int +CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 2); +} + +int +CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 3); +} + +static int +cbs_peek_u(CBS *cbs, uint32_t *out, size_t len) +{ + uint32_t result = 0; + size_t i; + const uint8_t *data; + + if (len < 1 || len > 4) + return 0; + + if (!cbs_peek(cbs, &data, len)) + return 0; + + for (i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int +CBS_peek_u8(CBS *cbs, uint8_t *out) +{ + const uint8_t *v; + + if (!cbs_peek(cbs, &v, 1)) + return 0; + + *out = *v; + return 1; +} + +int +CBS_peek_u16(CBS *cbs, uint16_t *out) +{ + uint32_t v; + + if (!cbs_peek_u(cbs, &v, 2)) + return 0; + + *out = v; + return 1; +} + +int +CBS_peek_u24(CBS *cbs, uint32_t *out) +{ + return cbs_peek_u(cbs, out, 3); +} + +int +CBS_peek_u32(CBS *cbs, uint32_t *out) +{ + return cbs_peek_u(cbs, out, 4); +} + +int +CBS_peek_last_u8(CBS *cbs, uint8_t *out) +{ + if (cbs->len == 0) + return 0; + + *out = cbs->data[cbs->len - 1]; + return 1; +} + +int +CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len) +{ + return cbs_get_any_asn1_element_internal(cbs, out, out_tag, + out_header_len, 1); +} + +/* + * Review X.690 for details on ASN.1 DER encoding. + * + * If non-strict mode is enabled, then DER rules are relaxed + * for indefinite constructs (violates DER but a little closer to BER). + * Non-strict mode should only be used by bs_ber.c + * + * Sections 8, 10 and 11 for DER encoding + */ +int +cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len, int strict) +{ + uint8_t tag, length_byte; + CBS header = *cbs; + CBS throwaway; + size_t len; + + if (out == NULL) + out = &throwaway; + + /* + * Get identifier octet and length octet. Only 1 octet for each + * is a CBS limitation. + */ + if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) + return 0; + + /* CBS limitation: long form tags are not supported. */ + if ((tag & 0x1f) == 0x1f) + return 0; + + if (out_tag != NULL) + *out_tag = tag; + + if ((length_byte & 0x80) == 0) { + /* Short form length. */ + len = ((size_t) length_byte) + 2; + if (out_header_len != NULL) + *out_header_len = 2; + + } else { + /* Long form length. */ + const size_t num_bytes = length_byte & 0x7f; + uint32_t len32; + + /* ASN.1 reserved value for future extensions */ + if (num_bytes == 0x7f) + return 0; + + /* Handle indefinite form length */ + if (num_bytes == 0) { + /* DER encoding doesn't allow for indefinite form. */ + if (strict) + return 0; + + /* Primitive cannot use indefinite in BER or DER. */ + if ((tag & CBS_ASN1_CONSTRUCTED) == 0) + return 0; + + /* Constructed, indefinite length allowed in BER. */ + if (out_header_len != NULL) + *out_header_len = 2; + return CBS_get_bytes(cbs, out, 2); + } + + /* CBS limitation. */ + if (num_bytes > 4) + return 0; + + if (!cbs_get_u(&header, &len32, num_bytes)) + return 0; + + /* DER has a minimum length octet requirement. */ + if (len32 < 128) + /* Should have used short form instead */ + return 0; + + if ((len32 >> ((num_bytes - 1) * 8)) == 0) + /* Length should have been at least one byte shorter. */ + return 0; + + len = len32; + if (len + 2 + num_bytes < len) + /* Overflow. */ + return 0; + + len += 2 + num_bytes; + if (out_header_len != NULL) + *out_header_len = 2 + num_bytes; + } + + return CBS_get_bytes(cbs, out, len); +} + +static int +cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header) +{ + size_t header_len; + unsigned int tag; + CBS throwaway; + + if (out == NULL) + out = &throwaway; + + if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || + tag != tag_value) + return 0; + + if (skip_header && !CBS_skip(out, header_len)) + return 0; + + return 1; +} + +int +CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value) +{ + return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); +} + +int +CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value) +{ + return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); +} + +int +CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value) +{ + if (CBS_len(cbs) < 1) + return 0; + + /* + * Tag number 31 indicates the start of a long form number. + * This is valid in ASN.1, but CBS only supports short form. + */ + if ((tag_value & 0x1f) == 0x1f) + return 0; + + return CBS_data(cbs)[0] == tag_value; +} + +/* Encoding details are in ASN.1: X.690 section 8.3 */ +int +CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) +{ + CBS bytes; + const uint8_t *data; + size_t i, len; + + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) + return 0; + + *out = 0; + data = CBS_data(&bytes); + len = CBS_len(&bytes); + + if (len == 0) + /* An INTEGER is encoded with at least one content octet. */ + return 0; + + if ((data[0] & 0x80) != 0) + /* Negative number. */ + return 0; + + if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) + /* Violates smallest encoding rule: excessive leading zeros. */ + return 0; + + for (i = 0; i < len; i++) { + if ((*out >> 56) != 0) + /* Too large to represent as a uint64_t. */ + return 0; + + *out <<= 8; + *out |= data[i]; + } + + return 1; +} + +int +CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag) +{ + if (CBS_peek_asn1_tag(cbs, tag)) { + if (!CBS_get_asn1(cbs, out, tag)) + return 0; + + *out_present = 1; + } else { + *out_present = 0; + } + return 1; +} + +int +CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned int tag) +{ + CBS child; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) + return 0; + } else { + CBS_init(out, NULL, 0); + } + if (out_present) + *out_present = present; + + return 1; +} + +int +CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, + uint64_t default_value) +{ + CBS child; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + if (!CBS_get_asn1_uint64(&child, out) || + CBS_len(&child) != 0) + return 0; + } else { + *out = default_value; + } + return 1; +} + +int +CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, + int default_value) +{ + CBS child, child2; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + uint8_t boolean; + + if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || + CBS_len(&child2) != 1 || CBS_len(&child) != 0) + return 0; + + boolean = CBS_data(&child2)[0]; + if (boolean == 0) + *out = 0; + else if (boolean == 0xff) + *out = 1; + else + return 0; + + } else { + *out = default_value; + } + return 1; +} diff --git a/Libraries/libressl/crypto/bytestring/bytestring.h b/Libraries/libressl/crypto/bytestring/bytestring.h new file mode 100644 index 000000000..d80e89c9a --- /dev/null +++ b/Libraries/libressl/crypto/bytestring/bytestring.h @@ -0,0 +1,564 @@ +/* $OpenBSD: bytestring.h,v 1.4 2022/11/09 19:05:42 jsing Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENSSL_HEADER_BYTESTRING_H +#define OPENSSL_HEADER_BYTESTRING_H + +#include +#include + +__BEGIN_HIDDEN_DECLS + +/* + * Bytestrings are used for parsing and building TLS and ASN.1 messages. + * + * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and + * provides utility functions for safely parsing length-prefixed structures + * like TLS and ASN.1 from it. + * + * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and + * provides utility functions for building length-prefixed messages. + */ + +/* CRYPTO ByteString */ +typedef struct cbs_st { + const uint8_t *data; + size_t initial_len; + size_t len; +} CBS; + +/* + * CBS_init sets |cbs| to point to |data|. It does not take ownership of + * |data|. + */ +void CBS_init(CBS *cbs, const uint8_t *data, size_t len); + +/* + * CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero + * otherwise. + */ +int CBS_skip(CBS *cbs, size_t len); + +/* + * CBS_data returns a pointer to the contents of |cbs|. + */ +const uint8_t *CBS_data(const CBS *cbs); + +/* + * CBS_len returns the number of bytes remaining in |cbs|. + */ +size_t CBS_len(const CBS *cbs); + +/* + * CBS_offset returns the current offset into the original data of |cbs|. + */ +size_t CBS_offset(const CBS *cbs); + +/* + * CBS_stow copies the current contents of |cbs| into |*out_ptr| and + * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with + * free. It returns one on success and zero on allocation failure. On + * success, |*out_ptr| should be freed with free. If |cbs| is empty, + * |*out_ptr| will be NULL. + */ +int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); + +/* + * CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a + * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed + * with free. It returns one on success and zero on failure. On success, + * |*out_ptr| should be freed with free. If |cbs| contains NUL bytes, + * CBS_strdup will fail. + */ +int CBS_strdup(const CBS *cbs, char **out_ptr); + +/* + * CBS_write_bytes writes all of the remaining data from |cbs| into |dst| + * if it is at most |dst_len| bytes. If |copied| is not NULL, it will be set + * to the amount copied. It returns one on success and zero otherwise. + */ +int CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, + size_t *copied); + +/* + * CBS_contains_zero_byte returns one if the current contents of |cbs| contains + * a NUL byte and zero otherwise. + */ +int CBS_contains_zero_byte(const CBS *cbs); + +/* + * CBS_mem_equal compares the current contents of |cbs| with the |len| bytes + * starting at |data|. If they're equal, it returns one, otherwise zero. If the + * lengths match, it uses a constant-time comparison. + */ +int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len); + +/* + * CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It + * returns one on success and zero on error. + */ +int CBS_get_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and + * advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u16(CBS *cbs, uint16_t *out); + +/* + * CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and + * advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u24(CBS *cbs, uint32_t *out); + +/* + * CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| + * and advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u32(CBS *cbs, uint32_t *out); + +/* + * CBS_get_u64 sets |*out| to the next, big-endian uint64_t value from |cbs| + * and advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u64(CBS *cbs, uint64_t *out); + +/* + * CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens + * |cbs|. It returns one on success and zero on error. + */ +int CBS_get_last_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances + * |cbs|. It returns one on success and zero on error. + */ +int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); + +/* + * CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, + * length-prefixed value from |cbs| and advances |cbs| over it. It returns one + * on success and zero on error. + */ +int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, + * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It + * returns one on success and zero on error. + */ +int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, + * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It + * returns one on success and zero on error. + */ +int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_peek_u8 sets |*out| to the next uint8_t from |cbs|, but does not advance + * |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_peek_u16 sets |*out| to the next, big-endian uint16_t from |cbs|, but + * does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u16(CBS *cbs, uint16_t *out); + +/* + * CBS_peek_u24 sets |*out| to the next, big-endian 24-bit value from |cbs|, but + * does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u24(CBS *cbs, uint32_t *out); + +/* + * CBS_peek_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|, + * but does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u32(CBS *cbs, uint32_t *out); + +/* + * CBS_peek_last_u8 sets |*out| to the last uint8_t from |cbs|, but does not + * shorten |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_last_u8(CBS *cbs, uint8_t *out); + + +/* Parsing ASN.1 */ + +/* + * While an identifier can be multiple octets, this library only handles the + * single octet variety currently. This limits support up to tag number 30 + * since tag number 31 is a reserved value to indicate multiple octets. + */ + +/* Bits 8 and 7: class tag type: See X.690 section 8.1.2.2. */ +#define CBS_ASN1_UNIVERSAL 0x00 +#define CBS_ASN1_APPLICATION 0x40 +#define CBS_ASN1_CONTEXT_SPECIFIC 0x80 +#define CBS_ASN1_PRIVATE 0xc0 + +/* Bit 6: Primitive or constructed: See X.690 section 8.1.2.3. */ +#define CBS_ASN1_PRIMITIVE 0x00 +#define CBS_ASN1_CONSTRUCTED 0x20 + +/* + * Bits 5 to 1 are the tag number. See X.680 section 8.6 for tag numbers of + * the universal class. + */ + +/* + * Common universal identifier octets. + * See X.690 section 8.1 and X.680 section 8.6 for universal tag numbers. + * + * Note: These definitions are the cause of some of the strange behavior in + * CBS's bs_ber.c. + * + * In BER, it is the sender's option to use primitive or constructed for + * bitstring (X.690 section 8.6.1) and octetstring (X.690 section 8.7.1). + * + * In DER, bitstring and octetstring are required to be primitive + * (X.690 section 10.2). + */ +#define CBS_ASN1_BOOLEAN (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x1) +#define CBS_ASN1_INTEGER (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x2) +#define CBS_ASN1_BITSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x3) +#define CBS_ASN1_OCTETSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x4) +#define CBS_ASN1_OBJECT (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x6) +#define CBS_ASN1_ENUMERATED (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0xa) +#define CBS_ASN1_SEQUENCE (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x10) +#define CBS_ASN1_SET (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x11) + +/* + * CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not + * including tag and length bytes) and advances |cbs| over it. The ASN.1 + * element must match |tag_value|. It returns one on success and zero + * on error. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value); + +/* + * CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the + * ASN.1 header bytes too. + */ +int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value); + +/* + * CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one + * if the next ASN.1 element on |cbs| would have tag |tag_value|. If + * |cbs| is empty or the tag does not match, it returns zero. Note: if + * it returns one, CBS_get_asn1 may still fail if the rest of the + * element is malformed. + */ +int CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value); + +/* + * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from + * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to + * the tag number and |*out_header_len| to the length of the ASN.1 header. + * Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore + * the value. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len); + +/* + * CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| + * and sets |*out| to its value. It returns one on success and zero on error, + * where error includes the integer being negative, or too large to represent + * in 64 bits. + */ +int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); + +/* + * CBS_get_optional_asn1 gets an optional explicitly-tagged element + * from |cbs| tagged with |tag| and sets |*out| to its contents. If + * present, it sets |*out_present| to one, otherwise zero. It returns + * one on success, whether or not the element was present, and zero on + * decode failure. + */ +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, + unsigned int tag); + +/* + * CBS_get_optional_asn1_octet_string gets an optional + * explicitly-tagged OCTET STRING from |cbs|. If present, it sets + * |*out| to the string and |*out_present| to one. Otherwise, it sets + * |*out| to empty and |*out_present| to zero. |out_present| may be + * NULL. It returns one on success, whether or not the element was + * present, and zero on decode failure. + */ +int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned int tag); + +/* + * CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged + * INTEGER from |cbs|. If present, it sets |*out| to the + * value. Otherwise, it sets |*out| to |default_value|. It returns one + * on success, whether or not the element was present, and zero on + * decode failure. + */ +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, + uint64_t default_value); + +/* + * CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from + * |cbs|. If present, it sets |*out| to either zero or one, based on the + * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on + * success, whether or not the element was present, and zero on decode + * failure. + */ +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, + int default_value); + + +/* + * CRYPTO ByteBuilder. + * + * |CBB| objects allow one to build length-prefixed serialisations. A |CBB| + * object is associated with a buffer and new buffers are created with + * |CBB_init|. Several |CBB| objects can point at the same buffer when a + * length-prefix is pending, however only a single |CBB| can be 'current' at + * any one time. For example, if one calls |CBB_add_u8_length_prefixed| then + * the new |CBB| points at the same buffer as the original. But if the original + * |CBB| is used then the length prefix is written out and the new |CBB| must + * not be used again. + * + * If one needs to force a length prefix to be written out because a |CBB| is + * going out of scope, use |CBB_flush|. + */ + +struct cbb_buffer_st { + uint8_t *buf; + + /* The number of valid bytes. */ + size_t len; + + /* The size of buf. */ + size_t cap; + + /* + * One iff |buf| is owned by this object. If not then |buf| cannot be + * resized. + */ + char can_resize; +}; + +typedef struct cbb_st { + struct cbb_buffer_st *base; + + /* + * offset is the offset from the start of |base->buf| to the position of any + * pending length-prefix. + */ + size_t offset; + + /* child points to a child CBB if a length-prefix is pending. */ + struct cbb_st *child; + + /* + * pending_len_len contains the number of bytes in a pending length-prefix, + * or zero if no length-prefix is pending. + */ + uint8_t pending_len_len; + + char pending_is_asn1; + + /* + * is_top_level is true iff this is a top-level |CBB| (as opposed to a child + * |CBB|). Top-level objects are valid arguments for |CBB_finish|. + */ + char is_top_level; +} CBB; + +/* + * CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as + * needed, the |initial_capacity| is just a hint. It returns one on success or + * zero on error. + */ +int CBB_init(CBB *cbb, size_t initial_capacity); + +/* + * CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since + * |buf| cannot grow, trying to write more than |len| bytes will cause CBB + * functions to fail. It returns one on success or zero on error. + */ +int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); + +/* + * CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects + * writing to the same buffer. This should be used in an error case where a + * serialisation is abandoned. + */ +void CBB_cleanup(CBB *cbb); + +/* + * CBB_finish completes any pending length prefix and sets |*out_data| to a + * malloced buffer and |*out_len| to the length of that buffer. The caller + * takes ownership of the buffer and, unless the buffer was fixed with + * |CBB_init_fixed|, must call |free| when done. + * + * It can only be called on a "top level" |CBB|, i.e. one initialised with + * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on + * error. + */ +int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); + +/* + * CBB_flush causes any pending length prefixes to be written out and any child + * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero + * on error. + */ +int CBB_flush(CBB *cbb); + +/* + * CBB_discard_child discards the current unflushed child of |cbb|. Neither the + * child's contents nor the length prefix will be included in the output. + */ +void CBB_discard_child(CBB *cbb); + +/* + * CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The + * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit + * length. It returns one on success or zero on error. + */ +int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. + * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, + * big-endian length. It returns one on success or zero on error. + */ +int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. + * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, + * big-endian length. It returns one on success or zero on error. + */ +int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an + * ASN.1 object can be written. The |tag| argument will be used as the tag for + * the object. Passing in |tag| number 31 will return in an error since only + * single octet identifiers are supported. It returns one on success or zero + * on error. + */ +int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag); + +/* + * CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on + * success and zero otherwise. + */ +int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); + +/* + * CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to + * the beginning of that space. The caller must then write |len| bytes of + * actual contents to |*out_data|. It returns one on success and zero + * otherwise. + */ +int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); + +/* + * CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on + * success and zero otherwise. + */ +int CBB_add_u8(CBB *cbb, size_t value); + +/* + * CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u16(CBB *cbb, size_t value); + +/* + * CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u24(CBB *cbb, size_t value); + +/* + * CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u32(CBB *cbb, size_t value); + +/* + * CBB_add_u64 appends a 64-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u64(CBB *cbb, uint64_t value); + +/* + * CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| + * and writes |value| in its contents. It returns one on success and zero on + * error. + */ +int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); + +#ifdef LIBRESSL_INTERNAL +/* + * CBS_dup sets |out| to point to cbs's |data| and |len|. It results in two + * CBS that point to the same buffer. + */ +void CBS_dup(const CBS *cbs, CBS *out); + +/* + * cbs_get_any_asn1_element sets |*out| to contain the next ASN.1 element from + * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to + * the tag number and |*out_header_len| to the length of the ASN.1 header. If + * strict mode is disabled and the element has indefinite length then |*out| + * will only contain the header. Each of |out|, |out_tag|, and + * |out_header_len| may be NULL to ignore the value. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len, int strict); + +/* + * CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it + * finds indefinite-length elements that otherwise appear to be valid DER, it + * attempts to convert the DER-like data to DER and sets |*out| and + * |*out_length| to describe a malloced buffer containing the DER data. + * Additionally, |*in| will be advanced over the ASN.1 data. + * + * If it doesn't find any indefinite-length elements then it sets |*out| to + * NULL and |*in| is unmodified. + * + * This is NOT a conversion from BER to DER. There are many restrictions when + * dealing with DER data. This is only concerned with one: indefinite vs. + * definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output + * from NSS. + * + * It returns one on success and zero otherwise. + */ +int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len); +#endif /* LIBRESSL_INTERNAL */ + +__END_HIDDEN_DECLS + +#endif /* OPENSSL_HEADER_BYTESTRING_H */ diff --git a/Libraries/libressl/crypto/camellia/camellia.c b/Libraries/libressl/crypto/camellia/camellia.c new file mode 100644 index 000000000..336074ad7 --- /dev/null +++ b/Libraries/libressl/crypto/camellia/camellia.c @@ -0,0 +1,566 @@ +/* $OpenBSD: camellia.c,v 1.12 2022/11/26 16:08:51 tb Exp $ */ +/* ==================================================================== + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . + * ALL RIGHTS RESERVED. + * + * Intellectual Property information for Camellia: + * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html + * + * News Release for Announcement of Camellia open source: + * http://www.ntt.co.jp/news/news06e/0604/060413a.html + * + * The Camellia Code included herein is developed by + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed + * to the OpenSSL project. + * + * The Camellia Code is licensed pursuant to the OpenSSL open source + * license provided below. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* + * Algorithm Specification + * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html + */ + +/* + * This release balances code size and performance. In particular key + * schedule setup is fully unrolled, because doing so *significantly* + * reduces amount of instructions per setup round and code increase is + * justifiable. In block functions on the other hand only inner loops + * are unrolled, as full unroll gives only nominal performance boost, + * while code size grows 4 or 7 times. Also, unlike previous versions + * this one "encourages" compiler to keep intermediate variables in + * registers, which should give better "all round" results, in other + * words reasonable performance even with not so modern compilers. + */ + +#include +#include +#include +#include + +#include "cmll_local.h" + +/* 32-bit rotations */ +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined(__x86_64) +# define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; }) +# define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; }) +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# endif +# endif +#endif + +#if !defined(RightRotate) && !defined(LeftRotate) +# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) ) +# define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) ) +#endif + +#if !defined(GETU32) && !defined(PUTU32) +# define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3])) +# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v)) +#endif + +/* S-box data */ +#define SBOX1_1110 Camellia_SBOX[0] +#define SBOX4_4404 Camellia_SBOX[1] +#define SBOX2_0222 Camellia_SBOX[2] +#define SBOX3_3033 Camellia_SBOX[3] +static const u32 Camellia_SBOX[][256] = { +{ 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, + 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, + 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, + 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, + 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, + 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, + 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, + 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, + 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, + 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, + 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, + 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, + 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, + 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, + 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, + 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, + 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, + 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, + 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, + 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, + 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, + 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 }, +{ 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, + 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, + 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, + 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, + 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, + 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, + 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, + 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, + 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, + 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, + 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, + 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, + 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, + 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, + 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, + 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, + 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, + 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, + 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, + 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, + 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, + 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e }, +{ 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, + 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, + 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, + 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, + 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, + 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, + 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, + 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, + 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, + 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, + 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, + 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, + 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, + 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, + 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, + 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, + 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, + 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, + 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, + 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, + 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, + 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d }, +{ 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, + 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, + 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, + 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, + 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, + 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, + 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, + 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, + 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, + 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, + 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, + 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, + 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, + 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, + 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, + 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, + 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, + 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, + 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, + 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, + 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, + 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f } +}; + +/* Key generation constants */ +static const u32 SIGMA[] = { + 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd +}; + +/* The phi algorithm given in C.2.7 of the Camellia spec document. */ +/* + * This version does not attempt to minimize amount of temporary + * variables, but instead explicitly exposes algorithm's parallelism. + * It is therefore most appropriate for platforms with not less than + * ~16 registers. For platforms with fewer registers [well, x86 to be + * specific] assembler version should be/is provided anyway... + */ +#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) \ +do { \ + u32 _t0, _t1, _t2, _t3; \ + _t0 = _s0 ^ (_key)[0]; \ + _t3 = SBOX4_4404[_t0 & 0xff]; \ + _t1 = _s1 ^ (_key)[1]; \ + _t3 ^= SBOX3_3033[(_t0 >> 8) & 0xff]; \ + _t2 = SBOX1_1110[_t1 & 0xff]; \ + _t3 ^= SBOX2_0222[(_t0 >> 16) & 0xff]; \ + _t2 ^= SBOX4_4404[(_t1 >> 8) & 0xff]; \ + _t3 ^= SBOX1_1110[(_t0 >> 24)]; \ + _t2 ^= _t3; \ + _t3 = RightRotate(_t3, 8); \ + _t2 ^= SBOX3_3033[(_t1 >> 16) & 0xff]; \ + _s3 ^= _t3; \ + _t2 ^= SBOX2_0222[(_t1 >> 24)]; \ + _s2 ^= _t2; \ + _s3 ^= _t2; \ +} while(0) + +/* + * Note that n has to be less than 32. Rotations for larger amount + * of bits are achieved by "rotating" order of s-elements and + * adjusting n accordingly, e.g. RotLeft128(s1, s2, s3, s0, n - 32). + */ +#define RotLeft128(_s0, _s1, _s2, _s3, _n) \ +do { \ + u32 _t0 = _s0 >> (32 - _n); \ + _s0 = (_s0 << _n) | (_s1 >> (32 - _n)); \ + _s1 = (_s1 << _n) | (_s2 >> (32 - _n)); \ + _s2 = (_s2 << _n) | (_s3 >> (32 - _n)); \ + _s3 = (_s3 << _n) | _t0; \ +} while (0) + +int +Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) +{ + u32 s0, s1, s2, s3; + + k[0] = s0 = GETU32(rawKey); + k[1] = s1 = GETU32(rawKey + 4); + k[2] = s2 = GETU32(rawKey + 8); + k[3] = s3 = GETU32(rawKey + 12); + + if (keyBitLength != 128) { + k[8] = s0 = GETU32(rawKey + 16); + k[9] = s1 = GETU32(rawKey + 20); + if (keyBitLength == 192) { + k[10] = s2 = ~s0; + k[11] = s3 = ~s1; + } else { + k[10] = s2 = GETU32(rawKey + 24); + k[11] = s3 = GETU32(rawKey + 28); + } + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + } + + /* Use the Feistel routine to scramble the key material */ + Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0); + Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2); + + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4); + Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6); + + /* Fill the keyTable. Requires many block rotations. */ + if (keyBitLength == 128) { + k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */ + k[24] = s0, k[25] = s1; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */ + k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + + s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3]; + RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */ + k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */ + k[26] = s2, k[27] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */ + k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */ + k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; + + return 3; /* grand rounds */ + } else { + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11]; + Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8)); + Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10)); + + k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */ + k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; + RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */ + k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; + + s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11]; + RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */ + k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */ + k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; + + s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + /* KA <<< 77 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */ + k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; + + s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3]; + RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */ + k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; + RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */ + k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */ + k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; + RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */ + k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; + + return 4; /* grand rounds */ + } + /* + * It is possible to perform certain precalculations, which + * would spare few cycles in block procedure. It's not done, + * because it upsets the performance balance between key + * setup and block procedures, negatively affecting overall + * throughput in applications operating on short messages + * and volatile keys. + */ +} + +void +Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + u32 s0, s1, s2, s3; + const u32 *k = keyTable, *kend = keyTable + grandRounds * 16; + + s0 = GETU32(plaintext) ^ k[0]; + s1 = GETU32(plaintext + 4) ^ k[1]; + s2 = GETU32(plaintext + 8) ^ k[2]; + s3 = GETU32(plaintext + 12) ^ k[3]; + k += 4; + + while (1) { + /* Camellia makes 6 Feistel rounds */ + Camellia_Feistel(s0, s1, s2, s3, k + 0); + Camellia_Feistel(s2, s3, s0, s1, k + 2); + Camellia_Feistel(s0, s1, s2, s3, k + 4); + Camellia_Feistel(s2, s3, s0, s1, k + 6); + Camellia_Feistel(s0, s1, s2, s3, k + 8); + Camellia_Feistel(s2, s3, s0, s1, k + 10); + k += 12; + + if (k == kend) + break; + + /* This is the same function as the diffusion function D + * of the accompanying documentation. See section 3.2 + * for properties of the FLlayer function. */ + s1 ^= LeftRotate(s0 & k[0], 1); + s2 ^= s3 | k[3]; + s0 ^= s1 | k[1]; + s3 ^= LeftRotate(s2 & k[2], 1); + k += 4; + } + + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(ciphertext, s2); + PUTU32(ciphertext + 4, s3); + PUTU32(ciphertext + 8, s0); + PUTU32(ciphertext + 12, s1); +} + +void +Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, + plaintext, keyTable, ciphertext); +} + +void +Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]) +{ + u32 s0, s1, s2, s3; + const u32 *k = keyTable+grandRounds * 16, *kend = keyTable+4; + + s0 = GETU32(ciphertext) ^ k[0]; + s1 = GETU32(ciphertext+4) ^ k[1]; + s2 = GETU32(ciphertext+8) ^ k[2]; + s3 = GETU32(ciphertext+12) ^ k[3]; + + while (1) { + /* Camellia makes 6 Feistel rounds */ + k -= 12; + Camellia_Feistel(s0, s1, s2, s3, k+10); + Camellia_Feistel(s2, s3, s0, s1, k+8); + Camellia_Feistel(s0, s1, s2, s3, k+6); + Camellia_Feistel(s2, s3, s0, s1, k+4); + Camellia_Feistel(s0, s1, s2, s3, k+2); + Camellia_Feistel(s2, s3, s0, s1, k+0); + + if (k == kend) + break; + + /* This is the same function as the diffusion function D + * of the accompanying documentation. See section 3.2 + * for properties of the FLlayer function. */ + k -= 4; + s1 ^= LeftRotate(s0 & k[2], 1); + s2 ^= s3 | k[1]; + s0 ^= s1 | k[3]; + s3 ^= LeftRotate(s2 & k[0], 1); + } + + k -= 4; + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(plaintext, s2); + PUTU32(plaintext+4, s3); + PUTU32(plaintext+8, s0); + PUTU32(plaintext+12, s1); +} + +void +Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, + plaintext, keyTable, ciphertext); +} diff --git a/Libraries/libressl/crypto/camellia/camellia.h b/Libraries/libressl/crypto/camellia/camellia.h new file mode 100644 index 000000000..b9b5f792b --- /dev/null +++ b/Libraries/libressl/crypto/camellia/camellia.h @@ -0,0 +1,125 @@ +/* $OpenBSD: camellia.h,v 1.5 2014/11/13 20:01:58 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_CAMELLIA_H +#define HEADER_CAMELLIA_H + +#include + +#ifdef OPENSSL_NO_CAMELLIA +#error CAMELLIA is disabled. +#endif + +#include + +#define CAMELLIA_ENCRYPT 1 +#define CAMELLIA_DECRYPT 0 + +/* Because array size can't be a const in C, the following two are macros. + Both sizes are in bytes. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ + +#define CAMELLIA_BLOCK_SIZE 16 +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_Camellia_H */ diff --git a/Libraries/libressl/crypto/camellia/cmll-elf-x86_64.S b/Libraries/libressl/crypto/camellia/cmll-elf-x86_64.S new file mode 100644 index 000000000..ab4a184cf --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll-elf-x86_64.S @@ -0,0 +1,1850 @@ +#include "x86_arch.h" +.text + + +.globl Camellia_EncryptBlock +.type Camellia_EncryptBlock,@function +.align 16 +Camellia_EncryptBlock: + endbr64 + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp .Lenc_rounds +.size Camellia_EncryptBlock,.-Camellia_EncryptBlock + +.globl Camellia_EncryptBlock_Rounds +.type Camellia_EncryptBlock_Rounds,@function +.align 16 +.Lenc_rounds: +Camellia_EncryptBlock_Rounds: + endbr64 + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +.Lenc_prologue: + + + movq %rcx,%r13 + movq %rdx,%r14 + + shll $6,%edi + leaq .LCamellia_SBOX(%rip),%rbp + leaq (%r14,%rdi,1),%r15 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +.Lenc_epilogue: + retq +.size Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds + +.type _x86_64_Camellia_encrypt,@function +.align 16 +_x86_64_Camellia_encrypt: + endbr64 + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.align 16 +.Leloop: + movl 16(%r14),%ebx + movl 20(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 56(%r14),%ebx + movl 60(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 64(%r14),%ebx + movl 68(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq 64(%r14),%r14 + cmpq %r15,%r14 + movl 8(%r14),%edx + movl 12(%r14),%ecx + je .Ledone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + jmp .Leloop + +.align 16 +.Ledone: + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r8d,%ecx + xorl %r9d,%edx + + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r10d + movl %edx,%r11d + + retq +.size _x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt + + +.globl Camellia_DecryptBlock +.type Camellia_DecryptBlock,@function +.align 16 +Camellia_DecryptBlock: + endbr64 + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp .Ldec_rounds +.size Camellia_DecryptBlock,.-Camellia_DecryptBlock + +.globl Camellia_DecryptBlock_Rounds +.type Camellia_DecryptBlock_Rounds,@function +.align 16 +.Ldec_rounds: +Camellia_DecryptBlock_Rounds: + endbr64 + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +.Ldec_prologue: + + + movq %rcx,%r13 + movq %rdx,%r15 + + shll $6,%edi + leaq .LCamellia_SBOX(%rip),%rbp + leaq (%r15,%rdi,1),%r14 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_decrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +.Ldec_epilogue: + retq +.size Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds + +.type _x86_64_Camellia_decrypt,@function +.align 16 +_x86_64_Camellia_decrypt: + endbr64 + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.align 16 +.Ldloop: + movl -8(%r14),%ebx + movl -4(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -16(%r14),%ebx + movl -12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -24(%r14),%ebx + movl -20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -32(%r14),%ebx + movl -28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -40(%r14),%ebx + movl -36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -48(%r14),%ebx + movl -44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -56(%r14),%ebx + movl -52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq -64(%r14),%r14 + cmpq %r15,%r14 + movl 0(%r14),%edx + movl 4(%r14),%ecx + je .Lddone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + + jmp .Ldloop + +.align 16 +.Lddone: + xorl %r10d,%ecx + xorl %r11d,%edx + xorl %r8d,%eax + xorl %r9d,%ebx + + movl %ecx,%r8d + movl %edx,%r9d + movl %eax,%r10d + movl %ebx,%r11d + + retq +.size _x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt +.globl Camellia_Ekeygen +.type Camellia_Ekeygen,@function +.align 16 +Camellia_Ekeygen: + endbr64 + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +.Lkey_prologue: + + movq %rdi,%r15 + movq %rdx,%r13 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + movl 12(%rsi),%r11d + + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,0(%r13) + movl %r8d,4(%r13) + movl %r11d,8(%r13) + movl %r10d,12(%r13) + cmpq $128,%r15 + je .L1st128 + + movl 16(%rsi),%r8d + movl 20(%rsi),%r9d + cmpq $192,%r15 + je .L1st192 + movl 24(%rsi),%r10d + movl 28(%rsi),%r11d + jmp .L1st256 +.L1st192: + movl %r8d,%r10d + movl %r9d,%r11d + notl %r10d + notl %r11d +.L1st256: + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,32(%r13) + movl %r8d,36(%r13) + movl %r11d,40(%r13) + movl %r10d,44(%r13) + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + +.L1st128: + leaq .LCamellia_SIGMA(%rip),%r14 + leaq .LCamellia_SBOX(%rip),%rbp + + movl 0(%r14),%ebx + movl 4(%r14),%eax + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 8(%r14),%ebx + movl 12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 16(%r14),%ebx + movl 20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + cmpq $128,%r15 + jne .L2nd256 + + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq -128(%r13),%rax + movq -120(%r13),%rbx + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,-96(%r13) + movq %rbx,-88(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-80(%r13) + movq %r10,-72(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-64(%r13) + movq %r10,-56(%r13) + movq %rax,%r11 + shlq $30,%rax + movq %rbx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rax + shlq $30,%rbx + orq %r11,%rbx + movq %rax,-48(%r13) + movq %rbx,-40(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-32(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rbx,-24(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-16(%r13) + movq %r10,-8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,16(%r13) + movq %rbx,24(%r13) + movq %r8,%r11 + shlq $34,%r8 + movq %r10,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%r8 + shlq $34,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r8,%r11 + shlq $17,%r8 + movq %r10,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r8 + shlq $17,%r10 + orq %r11,%r10 + movq %r8,64(%r13) + movq %r10,72(%r13) + movl $3,%eax + jmp .Ldone +.align 16 +.L2nd256: + movl %r9d,48(%r13) + movl %r8d,52(%r13) + movl %r11d,56(%r13) + movl %r10d,60(%r13) + xorl 32(%r13),%r9d + xorl 36(%r13),%r8d + xorl 40(%r13),%r11d + xorl 44(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + movq 0(%r13),%rax + movq 8(%r13),%rbx + movq 32(%r13),%rcx + movq 40(%r13),%rdx + movq 48(%r13),%r14 + movq 56(%r13),%r15 + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-96(%r13) + movq %rdx,-88(%r13) + movq %r14,%r11 + shlq $15,%r14 + movq %r15,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r14 + shlq $15,%r15 + orq %r11,%r15 + movq %r14,-80(%r13) + movq %r15,-72(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-64(%r13) + movq %rdx,-56(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,-48(%r13) + movq %r10,-40(%r13) + movq %rax,%r11 + shlq $45,%rax + movq %rbx,%r9 + shrq $19,%r9 + shrq $19,%r11 + orq %r9,%rax + shlq $45,%rbx + orq %r11,%rbx + movq %rax,-32(%r13) + movq %rbx,-24(%r13) + movq %r14,%r11 + shlq $30,%r14 + movq %r15,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r14 + shlq $30,%r15 + orq %r11,%r15 + movq %r14,-16(%r13) + movq %r15,-8(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rcx,%r11 + shlq $30,%rcx + movq %rdx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rcx + shlq $30,%rdx + orq %r11,%rdx + movq %rcx,16(%r13) + movq %rdx,24(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r14,%r11 + shlq $32,%r14 + movq %r15,%r9 + shrq $32,%r9 + shrq $32,%r11 + orq %r9,%r14 + shlq $32,%r15 + orq %r11,%r15 + movq %r14,64(%r13) + movq %r15,72(%r13) + movq %rcx,%r11 + shlq $34,%rcx + movq %rdx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rcx + shlq $34,%rdx + orq %r11,%rdx + movq %rcx,80(%r13) + movq %rdx,88(%r13) + movq %r14,%r11 + shlq $17,%r14 + movq %r15,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r14 + shlq $17,%r15 + orq %r11,%r15 + movq %r14,96(%r13) + movq %r15,104(%r13) + movq %rax,%r11 + shlq $34,%rax + movq %rbx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rax + shlq $34,%rbx + orq %r11,%rbx + movq %rax,112(%r13) + movq %rbx,120(%r13) + movq %r8,%r11 + shlq $51,%r8 + movq %r10,%r9 + shrq $13,%r9 + shrq $13,%r11 + orq %r9,%r8 + shlq $51,%r10 + orq %r11,%r10 + movq %r8,128(%r13) + movq %r10,136(%r13) + movl $4,%eax +.Ldone: + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +.Lkey_epilogue: + retq +.size Camellia_Ekeygen,.-Camellia_Ekeygen +.section .rodata +.align 64 +.LCamellia_SIGMA: +.long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858 +.long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5 +.long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2 +.long 0, 0, 0, 0 +.LCamellia_SBOX: +.long 0x70707000,0x70700070 +.long 0x82828200,0x2c2c002c +.long 0x2c2c2c00,0xb3b300b3 +.long 0xececec00,0xc0c000c0 +.long 0xb3b3b300,0xe4e400e4 +.long 0x27272700,0x57570057 +.long 0xc0c0c000,0xeaea00ea +.long 0xe5e5e500,0xaeae00ae +.long 0xe4e4e400,0x23230023 +.long 0x85858500,0x6b6b006b +.long 0x57575700,0x45450045 +.long 0x35353500,0xa5a500a5 +.long 0xeaeaea00,0xeded00ed +.long 0x0c0c0c00,0x4f4f004f +.long 0xaeaeae00,0x1d1d001d +.long 0x41414100,0x92920092 +.long 0x23232300,0x86860086 +.long 0xefefef00,0xafaf00af +.long 0x6b6b6b00,0x7c7c007c +.long 0x93939300,0x1f1f001f +.long 0x45454500,0x3e3e003e +.long 0x19191900,0xdcdc00dc +.long 0xa5a5a500,0x5e5e005e +.long 0x21212100,0x0b0b000b +.long 0xededed00,0xa6a600a6 +.long 0x0e0e0e00,0x39390039 +.long 0x4f4f4f00,0xd5d500d5 +.long 0x4e4e4e00,0x5d5d005d +.long 0x1d1d1d00,0xd9d900d9 +.long 0x65656500,0x5a5a005a +.long 0x92929200,0x51510051 +.long 0xbdbdbd00,0x6c6c006c +.long 0x86868600,0x8b8b008b +.long 0xb8b8b800,0x9a9a009a +.long 0xafafaf00,0xfbfb00fb +.long 0x8f8f8f00,0xb0b000b0 +.long 0x7c7c7c00,0x74740074 +.long 0xebebeb00,0x2b2b002b +.long 0x1f1f1f00,0xf0f000f0 +.long 0xcecece00,0x84840084 +.long 0x3e3e3e00,0xdfdf00df +.long 0x30303000,0xcbcb00cb +.long 0xdcdcdc00,0x34340034 +.long 0x5f5f5f00,0x76760076 +.long 0x5e5e5e00,0x6d6d006d +.long 0xc5c5c500,0xa9a900a9 +.long 0x0b0b0b00,0xd1d100d1 +.long 0x1a1a1a00,0x04040004 +.long 0xa6a6a600,0x14140014 +.long 0xe1e1e100,0x3a3a003a +.long 0x39393900,0xdede00de +.long 0xcacaca00,0x11110011 +.long 0xd5d5d500,0x32320032 +.long 0x47474700,0x9c9c009c +.long 0x5d5d5d00,0x53530053 +.long 0x3d3d3d00,0xf2f200f2 +.long 0xd9d9d900,0xfefe00fe +.long 0x01010100,0xcfcf00cf +.long 0x5a5a5a00,0xc3c300c3 +.long 0xd6d6d600,0x7a7a007a +.long 0x51515100,0x24240024 +.long 0x56565600,0xe8e800e8 +.long 0x6c6c6c00,0x60600060 +.long 0x4d4d4d00,0x69690069 +.long 0x8b8b8b00,0xaaaa00aa +.long 0x0d0d0d00,0xa0a000a0 +.long 0x9a9a9a00,0xa1a100a1 +.long 0x66666600,0x62620062 +.long 0xfbfbfb00,0x54540054 +.long 0xcccccc00,0x1e1e001e +.long 0xb0b0b000,0xe0e000e0 +.long 0x2d2d2d00,0x64640064 +.long 0x74747400,0x10100010 +.long 0x12121200,0x00000000 +.long 0x2b2b2b00,0xa3a300a3 +.long 0x20202000,0x75750075 +.long 0xf0f0f000,0x8a8a008a +.long 0xb1b1b100,0xe6e600e6 +.long 0x84848400,0x09090009 +.long 0x99999900,0xdddd00dd +.long 0xdfdfdf00,0x87870087 +.long 0x4c4c4c00,0x83830083 +.long 0xcbcbcb00,0xcdcd00cd +.long 0xc2c2c200,0x90900090 +.long 0x34343400,0x73730073 +.long 0x7e7e7e00,0xf6f600f6 +.long 0x76767600,0x9d9d009d +.long 0x05050500,0xbfbf00bf +.long 0x6d6d6d00,0x52520052 +.long 0xb7b7b700,0xd8d800d8 +.long 0xa9a9a900,0xc8c800c8 +.long 0x31313100,0xc6c600c6 +.long 0xd1d1d100,0x81810081 +.long 0x17171700,0x6f6f006f +.long 0x04040400,0x13130013 +.long 0xd7d7d700,0x63630063 +.long 0x14141400,0xe9e900e9 +.long 0x58585800,0xa7a700a7 +.long 0x3a3a3a00,0x9f9f009f +.long 0x61616100,0xbcbc00bc +.long 0xdedede00,0x29290029 +.long 0x1b1b1b00,0xf9f900f9 +.long 0x11111100,0x2f2f002f +.long 0x1c1c1c00,0xb4b400b4 +.long 0x32323200,0x78780078 +.long 0x0f0f0f00,0x06060006 +.long 0x9c9c9c00,0xe7e700e7 +.long 0x16161600,0x71710071 +.long 0x53535300,0xd4d400d4 +.long 0x18181800,0xabab00ab +.long 0xf2f2f200,0x88880088 +.long 0x22222200,0x8d8d008d +.long 0xfefefe00,0x72720072 +.long 0x44444400,0xb9b900b9 +.long 0xcfcfcf00,0xf8f800f8 +.long 0xb2b2b200,0xacac00ac +.long 0xc3c3c300,0x36360036 +.long 0xb5b5b500,0x2a2a002a +.long 0x7a7a7a00,0x3c3c003c +.long 0x91919100,0xf1f100f1 +.long 0x24242400,0x40400040 +.long 0x08080800,0xd3d300d3 +.long 0xe8e8e800,0xbbbb00bb +.long 0xa8a8a800,0x43430043 +.long 0x60606000,0x15150015 +.long 0xfcfcfc00,0xadad00ad +.long 0x69696900,0x77770077 +.long 0x50505000,0x80800080 +.long 0xaaaaaa00,0x82820082 +.long 0xd0d0d000,0xecec00ec +.long 0xa0a0a000,0x27270027 +.long 0x7d7d7d00,0xe5e500e5 +.long 0xa1a1a100,0x85850085 +.long 0x89898900,0x35350035 +.long 0x62626200,0x0c0c000c +.long 0x97979700,0x41410041 +.long 0x54545400,0xefef00ef +.long 0x5b5b5b00,0x93930093 +.long 0x1e1e1e00,0x19190019 +.long 0x95959500,0x21210021 +.long 0xe0e0e000,0x0e0e000e +.long 0xffffff00,0x4e4e004e +.long 0x64646400,0x65650065 +.long 0xd2d2d200,0xbdbd00bd +.long 0x10101000,0xb8b800b8 +.long 0xc4c4c400,0x8f8f008f +.long 0x00000000,0xebeb00eb +.long 0x48484800,0xcece00ce +.long 0xa3a3a300,0x30300030 +.long 0xf7f7f700,0x5f5f005f +.long 0x75757500,0xc5c500c5 +.long 0xdbdbdb00,0x1a1a001a +.long 0x8a8a8a00,0xe1e100e1 +.long 0x03030300,0xcaca00ca +.long 0xe6e6e600,0x47470047 +.long 0xdadada00,0x3d3d003d +.long 0x09090900,0x01010001 +.long 0x3f3f3f00,0xd6d600d6 +.long 0xdddddd00,0x56560056 +.long 0x94949400,0x4d4d004d +.long 0x87878700,0x0d0d000d +.long 0x5c5c5c00,0x66660066 +.long 0x83838300,0xcccc00cc +.long 0x02020200,0x2d2d002d +.long 0xcdcdcd00,0x12120012 +.long 0x4a4a4a00,0x20200020 +.long 0x90909000,0xb1b100b1 +.long 0x33333300,0x99990099 +.long 0x73737300,0x4c4c004c +.long 0x67676700,0xc2c200c2 +.long 0xf6f6f600,0x7e7e007e +.long 0xf3f3f300,0x05050005 +.long 0x9d9d9d00,0xb7b700b7 +.long 0x7f7f7f00,0x31310031 +.long 0xbfbfbf00,0x17170017 +.long 0xe2e2e200,0xd7d700d7 +.long 0x52525200,0x58580058 +.long 0x9b9b9b00,0x61610061 +.long 0xd8d8d800,0x1b1b001b +.long 0x26262600,0x1c1c001c +.long 0xc8c8c800,0x0f0f000f +.long 0x37373700,0x16160016 +.long 0xc6c6c600,0x18180018 +.long 0x3b3b3b00,0x22220022 +.long 0x81818100,0x44440044 +.long 0x96969600,0xb2b200b2 +.long 0x6f6f6f00,0xb5b500b5 +.long 0x4b4b4b00,0x91910091 +.long 0x13131300,0x08080008 +.long 0xbebebe00,0xa8a800a8 +.long 0x63636300,0xfcfc00fc +.long 0x2e2e2e00,0x50500050 +.long 0xe9e9e900,0xd0d000d0 +.long 0x79797900,0x7d7d007d +.long 0xa7a7a700,0x89890089 +.long 0x8c8c8c00,0x97970097 +.long 0x9f9f9f00,0x5b5b005b +.long 0x6e6e6e00,0x95950095 +.long 0xbcbcbc00,0xffff00ff +.long 0x8e8e8e00,0xd2d200d2 +.long 0x29292900,0xc4c400c4 +.long 0xf5f5f500,0x48480048 +.long 0xf9f9f900,0xf7f700f7 +.long 0xb6b6b600,0xdbdb00db +.long 0x2f2f2f00,0x03030003 +.long 0xfdfdfd00,0xdada00da +.long 0xb4b4b400,0x3f3f003f +.long 0x59595900,0x94940094 +.long 0x78787800,0x5c5c005c +.long 0x98989800,0x02020002 +.long 0x06060600,0x4a4a004a +.long 0x6a6a6a00,0x33330033 +.long 0xe7e7e700,0x67670067 +.long 0x46464600,0xf3f300f3 +.long 0x71717100,0x7f7f007f +.long 0xbababa00,0xe2e200e2 +.long 0xd4d4d400,0x9b9b009b +.long 0x25252500,0x26260026 +.long 0xababab00,0x37370037 +.long 0x42424200,0x3b3b003b +.long 0x88888800,0x96960096 +.long 0xa2a2a200,0x4b4b004b +.long 0x8d8d8d00,0xbebe00be +.long 0xfafafa00,0x2e2e002e +.long 0x72727200,0x79790079 +.long 0x07070700,0x8c8c008c +.long 0xb9b9b900,0x6e6e006e +.long 0x55555500,0x8e8e008e +.long 0xf8f8f800,0xf5f500f5 +.long 0xeeeeee00,0xb6b600b6 +.long 0xacacac00,0xfdfd00fd +.long 0x0a0a0a00,0x59590059 +.long 0x36363600,0x98980098 +.long 0x49494900,0x6a6a006a +.long 0x2a2a2a00,0x46460046 +.long 0x68686800,0xbaba00ba +.long 0x3c3c3c00,0x25250025 +.long 0x38383800,0x42420042 +.long 0xf1f1f100,0xa2a200a2 +.long 0xa4a4a400,0xfafa00fa +.long 0x40404000,0x07070007 +.long 0x28282800,0x55550055 +.long 0xd3d3d300,0xeeee00ee +.long 0x7b7b7b00,0x0a0a000a +.long 0xbbbbbb00,0x49490049 +.long 0xc9c9c900,0x68680068 +.long 0x43434300,0x38380038 +.long 0xc1c1c100,0xa4a400a4 +.long 0x15151500,0x28280028 +.long 0xe3e3e300,0x7b7b007b +.long 0xadadad00,0xc9c900c9 +.long 0xf4f4f400,0xc1c100c1 +.long 0x77777700,0xe3e300e3 +.long 0xc7c7c700,0xf4f400f4 +.long 0x80808000,0xc7c700c7 +.long 0x9e9e9e00,0x9e9e009e +.long 0x00e0e0e0,0x38003838 +.long 0x00050505,0x41004141 +.long 0x00585858,0x16001616 +.long 0x00d9d9d9,0x76007676 +.long 0x00676767,0xd900d9d9 +.long 0x004e4e4e,0x93009393 +.long 0x00818181,0x60006060 +.long 0x00cbcbcb,0xf200f2f2 +.long 0x00c9c9c9,0x72007272 +.long 0x000b0b0b,0xc200c2c2 +.long 0x00aeaeae,0xab00abab +.long 0x006a6a6a,0x9a009a9a +.long 0x00d5d5d5,0x75007575 +.long 0x00181818,0x06000606 +.long 0x005d5d5d,0x57005757 +.long 0x00828282,0xa000a0a0 +.long 0x00464646,0x91009191 +.long 0x00dfdfdf,0xf700f7f7 +.long 0x00d6d6d6,0xb500b5b5 +.long 0x00272727,0xc900c9c9 +.long 0x008a8a8a,0xa200a2a2 +.long 0x00323232,0x8c008c8c +.long 0x004b4b4b,0xd200d2d2 +.long 0x00424242,0x90009090 +.long 0x00dbdbdb,0xf600f6f6 +.long 0x001c1c1c,0x07000707 +.long 0x009e9e9e,0xa700a7a7 +.long 0x009c9c9c,0x27002727 +.long 0x003a3a3a,0x8e008e8e +.long 0x00cacaca,0xb200b2b2 +.long 0x00252525,0x49004949 +.long 0x007b7b7b,0xde00dede +.long 0x000d0d0d,0x43004343 +.long 0x00717171,0x5c005c5c +.long 0x005f5f5f,0xd700d7d7 +.long 0x001f1f1f,0xc700c7c7 +.long 0x00f8f8f8,0x3e003e3e +.long 0x00d7d7d7,0xf500f5f5 +.long 0x003e3e3e,0x8f008f8f +.long 0x009d9d9d,0x67006767 +.long 0x007c7c7c,0x1f001f1f +.long 0x00606060,0x18001818 +.long 0x00b9b9b9,0x6e006e6e +.long 0x00bebebe,0xaf00afaf +.long 0x00bcbcbc,0x2f002f2f +.long 0x008b8b8b,0xe200e2e2 +.long 0x00161616,0x85008585 +.long 0x00343434,0x0d000d0d +.long 0x004d4d4d,0x53005353 +.long 0x00c3c3c3,0xf000f0f0 +.long 0x00727272,0x9c009c9c +.long 0x00959595,0x65006565 +.long 0x00ababab,0xea00eaea +.long 0x008e8e8e,0xa300a3a3 +.long 0x00bababa,0xae00aeae +.long 0x007a7a7a,0x9e009e9e +.long 0x00b3b3b3,0xec00ecec +.long 0x00020202,0x80008080 +.long 0x00b4b4b4,0x2d002d2d +.long 0x00adadad,0x6b006b6b +.long 0x00a2a2a2,0xa800a8a8 +.long 0x00acacac,0x2b002b2b +.long 0x00d8d8d8,0x36003636 +.long 0x009a9a9a,0xa600a6a6 +.long 0x00171717,0xc500c5c5 +.long 0x001a1a1a,0x86008686 +.long 0x00353535,0x4d004d4d +.long 0x00cccccc,0x33003333 +.long 0x00f7f7f7,0xfd00fdfd +.long 0x00999999,0x66006666 +.long 0x00616161,0x58005858 +.long 0x005a5a5a,0x96009696 +.long 0x00e8e8e8,0x3a003a3a +.long 0x00242424,0x09000909 +.long 0x00565656,0x95009595 +.long 0x00404040,0x10001010 +.long 0x00e1e1e1,0x78007878 +.long 0x00636363,0xd800d8d8 +.long 0x00090909,0x42004242 +.long 0x00333333,0xcc00cccc +.long 0x00bfbfbf,0xef00efef +.long 0x00989898,0x26002626 +.long 0x00979797,0xe500e5e5 +.long 0x00858585,0x61006161 +.long 0x00686868,0x1a001a1a +.long 0x00fcfcfc,0x3f003f3f +.long 0x00ececec,0x3b003b3b +.long 0x000a0a0a,0x82008282 +.long 0x00dadada,0xb600b6b6 +.long 0x006f6f6f,0xdb00dbdb +.long 0x00535353,0xd400d4d4 +.long 0x00626262,0x98009898 +.long 0x00a3a3a3,0xe800e8e8 +.long 0x002e2e2e,0x8b008b8b +.long 0x00080808,0x02000202 +.long 0x00afafaf,0xeb00ebeb +.long 0x00282828,0x0a000a0a +.long 0x00b0b0b0,0x2c002c2c +.long 0x00747474,0x1d001d1d +.long 0x00c2c2c2,0xb000b0b0 +.long 0x00bdbdbd,0x6f006f6f +.long 0x00363636,0x8d008d8d +.long 0x00222222,0x88008888 +.long 0x00383838,0x0e000e0e +.long 0x00646464,0x19001919 +.long 0x001e1e1e,0x87008787 +.long 0x00393939,0x4e004e4e +.long 0x002c2c2c,0x0b000b0b +.long 0x00a6a6a6,0xa900a9a9 +.long 0x00303030,0x0c000c0c +.long 0x00e5e5e5,0x79007979 +.long 0x00444444,0x11001111 +.long 0x00fdfdfd,0x7f007f7f +.long 0x00888888,0x22002222 +.long 0x009f9f9f,0xe700e7e7 +.long 0x00656565,0x59005959 +.long 0x00878787,0xe100e1e1 +.long 0x006b6b6b,0xda00dada +.long 0x00f4f4f4,0x3d003d3d +.long 0x00232323,0xc800c8c8 +.long 0x00484848,0x12001212 +.long 0x00101010,0x04000404 +.long 0x00d1d1d1,0x74007474 +.long 0x00515151,0x54005454 +.long 0x00c0c0c0,0x30003030 +.long 0x00f9f9f9,0x7e007e7e +.long 0x00d2d2d2,0xb400b4b4 +.long 0x00a0a0a0,0x28002828 +.long 0x00555555,0x55005555 +.long 0x00a1a1a1,0x68006868 +.long 0x00414141,0x50005050 +.long 0x00fafafa,0xbe00bebe +.long 0x00434343,0xd000d0d0 +.long 0x00131313,0xc400c4c4 +.long 0x00c4c4c4,0x31003131 +.long 0x002f2f2f,0xcb00cbcb +.long 0x00a8a8a8,0x2a002a2a +.long 0x00b6b6b6,0xad00adad +.long 0x003c3c3c,0x0f000f0f +.long 0x002b2b2b,0xca00caca +.long 0x00c1c1c1,0x70007070 +.long 0x00ffffff,0xff00ffff +.long 0x00c8c8c8,0x32003232 +.long 0x00a5a5a5,0x69006969 +.long 0x00202020,0x08000808 +.long 0x00898989,0x62006262 +.long 0x00000000,0x00000000 +.long 0x00909090,0x24002424 +.long 0x00474747,0xd100d1d1 +.long 0x00efefef,0xfb00fbfb +.long 0x00eaeaea,0xba00baba +.long 0x00b7b7b7,0xed00eded +.long 0x00151515,0x45004545 +.long 0x00060606,0x81008181 +.long 0x00cdcdcd,0x73007373 +.long 0x00b5b5b5,0x6d006d6d +.long 0x00121212,0x84008484 +.long 0x007e7e7e,0x9f009f9f +.long 0x00bbbbbb,0xee00eeee +.long 0x00292929,0x4a004a4a +.long 0x000f0f0f,0xc300c3c3 +.long 0x00b8b8b8,0x2e002e2e +.long 0x00070707,0xc100c1c1 +.long 0x00040404,0x01000101 +.long 0x009b9b9b,0xe600e6e6 +.long 0x00949494,0x25002525 +.long 0x00212121,0x48004848 +.long 0x00666666,0x99009999 +.long 0x00e6e6e6,0xb900b9b9 +.long 0x00cecece,0xb300b3b3 +.long 0x00ededed,0x7b007b7b +.long 0x00e7e7e7,0xf900f9f9 +.long 0x003b3b3b,0xce00cece +.long 0x00fefefe,0xbf00bfbf +.long 0x007f7f7f,0xdf00dfdf +.long 0x00c5c5c5,0x71007171 +.long 0x00a4a4a4,0x29002929 +.long 0x00373737,0xcd00cdcd +.long 0x00b1b1b1,0x6c006c6c +.long 0x004c4c4c,0x13001313 +.long 0x00919191,0x64006464 +.long 0x006e6e6e,0x9b009b9b +.long 0x008d8d8d,0x63006363 +.long 0x00767676,0x9d009d9d +.long 0x00030303,0xc000c0c0 +.long 0x002d2d2d,0x4b004b4b +.long 0x00dedede,0xb700b7b7 +.long 0x00969696,0xa500a5a5 +.long 0x00262626,0x89008989 +.long 0x007d7d7d,0x5f005f5f +.long 0x00c6c6c6,0xb100b1b1 +.long 0x005c5c5c,0x17001717 +.long 0x00d3d3d3,0xf400f4f4 +.long 0x00f2f2f2,0xbc00bcbc +.long 0x004f4f4f,0xd300d3d3 +.long 0x00191919,0x46004646 +.long 0x003f3f3f,0xcf00cfcf +.long 0x00dcdcdc,0x37003737 +.long 0x00797979,0x5e005e5e +.long 0x001d1d1d,0x47004747 +.long 0x00525252,0x94009494 +.long 0x00ebebeb,0xfa00fafa +.long 0x00f3f3f3,0xfc00fcfc +.long 0x006d6d6d,0x5b005b5b +.long 0x005e5e5e,0x97009797 +.long 0x00fbfbfb,0xfe00fefe +.long 0x00696969,0x5a005a5a +.long 0x00b2b2b2,0xac00acac +.long 0x00f0f0f0,0x3c003c3c +.long 0x00313131,0x4c004c4c +.long 0x000c0c0c,0x03000303 +.long 0x00d4d4d4,0x35003535 +.long 0x00cfcfcf,0xf300f3f3 +.long 0x008c8c8c,0x23002323 +.long 0x00e2e2e2,0xb800b8b8 +.long 0x00757575,0x5d005d5d +.long 0x00a9a9a9,0x6a006a6a +.long 0x004a4a4a,0x92009292 +.long 0x00575757,0xd500d5d5 +.long 0x00848484,0x21002121 +.long 0x00111111,0x44004444 +.long 0x00454545,0x51005151 +.long 0x001b1b1b,0xc600c6c6 +.long 0x00f5f5f5,0x7d007d7d +.long 0x00e4e4e4,0x39003939 +.long 0x000e0e0e,0x83008383 +.long 0x00737373,0xdc00dcdc +.long 0x00aaaaaa,0xaa00aaaa +.long 0x00f1f1f1,0x7c007c7c +.long 0x00dddddd,0x77007777 +.long 0x00595959,0x56005656 +.long 0x00141414,0x05000505 +.long 0x006c6c6c,0x1b001b1b +.long 0x00929292,0xa400a4a4 +.long 0x00545454,0x15001515 +.long 0x00d0d0d0,0x34003434 +.long 0x00787878,0x1e001e1e +.long 0x00707070,0x1c001c1c +.long 0x00e3e3e3,0xf800f8f8 +.long 0x00494949,0x52005252 +.long 0x00808080,0x20002020 +.long 0x00505050,0x14001414 +.long 0x00a7a7a7,0xe900e9e9 +.long 0x00f6f6f6,0xbd00bdbd +.long 0x00777777,0xdd00dddd +.long 0x00939393,0xe400e4e4 +.long 0x00868686,0xa100a1a1 +.long 0x00838383,0xe000e0e0 +.long 0x002a2a2a,0x8a008a8a +.long 0x00c7c7c7,0xf100f1f1 +.long 0x005b5b5b,0xd600d6d6 +.long 0x00e9e9e9,0x7a007a7a +.long 0x00eeeeee,0xbb00bbbb +.long 0x008f8f8f,0xe300e3e3 +.long 0x00010101,0x40004040 +.long 0x003d3d3d,0x4f004f4f +.text +.globl Camellia_cbc_encrypt +.type Camellia_cbc_encrypt,@function +.align 16 +Camellia_cbc_encrypt: + endbr64 + cmpq $0,%rdx + je .Lcbc_abort + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 +.Lcbc_prologue: + + movq %rsp,%rbp + subq $64,%rsp + andq $-64,%rsp + + + + leaq -64-63(%rcx),%r10 + subq %rsp,%r10 + negq %r10 + andq $960,%r10 + subq %r10,%rsp + + + movq %rdi,%r12 + movq %rsi,%r13 + movq %r8,%rbx + movq %rcx,%r14 + movl 272(%rcx),%r15d + + movq %r8,40(%rsp) + movq %rbp,48(%rsp) + +.Lcbc_body: + leaq .LCamellia_SBOX(%rip),%rbp + + movl $32,%ecx +.align 4 +.Lcbc_prefetch_sbox: + movq 0(%rbp),%rax + movq 32(%rbp),%rsi + movq 64(%rbp),%rdi + movq 96(%rbp),%r11 + leaq 128(%rbp),%rbp + loop .Lcbc_prefetch_sbox + subq $4096,%rbp + shlq $6,%r15 + movq %rdx,%rcx + leaq (%r14,%r15,1),%r15 + + cmpl $0,%r9d + je .LCBC_DECRYPT + + andq $-16,%rdx + andq $15,%rcx + leaq (%r12,%rdx,1),%rdx + movq %r14,0(%rsp) + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + cmpq %r12,%rdx + movl 0(%rbx),%r8d + movl 4(%rbx),%r9d + movl 8(%rbx),%r10d + movl 12(%rbx),%r11d + je .Lcbc_enc_tail + jmp .Lcbc_eloop + +.align 16 +.Lcbc_eloop: + xorl 0(%r12),%r8d + xorl 4(%r12),%r9d + xorl 8(%r12),%r10d + bswapl %r8d + xorl 12(%r12),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + movq 0(%rsp),%r14 + bswapl %r8d + movq 8(%rsp),%rdx + bswapl %r9d + movq 16(%rsp),%rcx + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + leaq 16(%r12),%r12 + movl %r11d,12(%r13) + cmpq %rdx,%r12 + leaq 16(%r13),%r13 + jne .Lcbc_eloop + + cmpq $0,%rcx + jne .Lcbc_enc_tail + + movq 40(%rsp),%r13 + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + jmp .Lcbc_done + +.align 16 +.Lcbc_enc_tail: + xorq %rax,%rax + movq %rax,0+24(%rsp) + movq %rax,8+24(%rsp) + movq %rax,16(%rsp) + +.Lcbc_enc_pushf: + pushfq + cld + movq %r12,%rsi + leaq 8+24(%rsp),%rdi +.long 0x9066A4F3 + popfq +.Lcbc_enc_popf: + + leaq 24(%rsp),%r12 + leaq 16+24(%rsp),%rax + movq %rax,8(%rsp) + jmp .Lcbc_eloop + +.align 16 +.LCBC_DECRYPT: + xchgq %r14,%r15 + addq $15,%rdx + andq $15,%rcx + andq $-16,%rdx + movq %r14,0(%rsp) + leaq (%r12,%rdx,1),%rdx + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + movq (%rbx),%rax + movq 8(%rbx),%rbx + jmp .Lcbc_dloop +.align 16 +.Lcbc_dloop: + movl 0(%r12),%r8d + movl 4(%r12),%r9d + movl 8(%r12),%r10d + bswapl %r8d + movl 12(%r12),%r11d + bswapl %r9d + movq %rax,0+24(%rsp) + bswapl %r10d + movq %rbx,8+24(%rsp) + bswapl %r11d + + call _x86_64_Camellia_decrypt + + movq 0(%rsp),%r14 + movq 8(%rsp),%rdx + movq 16(%rsp),%rcx + + bswapl %r8d + movq (%r12),%rax + bswapl %r9d + movq 8(%r12),%rbx + bswapl %r10d + xorl 0+24(%rsp),%r8d + bswapl %r11d + xorl 4+24(%rsp),%r9d + xorl 8+24(%rsp),%r10d + leaq 16(%r12),%r12 + xorl 12+24(%rsp),%r11d + cmpq %rdx,%r12 + je .Lcbc_ddone + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + leaq 16(%r13),%r13 + jmp .Lcbc_dloop + +.align 16 +.Lcbc_ddone: + movq 40(%rsp),%rdx + cmpq $0,%rcx + jne .Lcbc_dec_tail + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp .Lcbc_done +.align 16 +.Lcbc_dec_tail: + movl %r8d,0+24(%rsp) + movl %r9d,4+24(%rsp) + movl %r10d,8+24(%rsp) + movl %r11d,12+24(%rsp) + +.Lcbc_dec_pushf: + pushfq + cld + leaq 8+24(%rsp),%rsi + leaq (%r13),%rdi +.long 0x9066A4F3 + popfq +.Lcbc_dec_popf: + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp .Lcbc_done + +.align 16 +.Lcbc_done: + movq 48(%rsp),%rcx + movq 0(%rcx),%r15 + movq 8(%rcx),%r14 + movq 16(%rcx),%r13 + movq 24(%rcx),%r12 + movq 32(%rcx),%rbp + movq 40(%rcx),%rbx + leaq 48(%rcx),%rsp +.Lcbc_abort: + retq +.size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/camellia/cmll-macosx-x86_64.S b/Libraries/libressl/crypto/camellia/cmll-macosx-x86_64.S new file mode 100644 index 000000000..5e7a1b7bb --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll-macosx-x86_64.S @@ -0,0 +1,1839 @@ +#include "x86_arch.h" +.text + + +.globl _Camellia_EncryptBlock + +.p2align 4 +_Camellia_EncryptBlock: + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp L$enc_rounds + + +.globl _Camellia_EncryptBlock_Rounds + +.p2align 4 +L$enc_rounds: +_Camellia_EncryptBlock_Rounds: + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +L$enc_prologue: + + + movq %rcx,%r13 + movq %rdx,%r14 + + shll $6,%edi + leaq L$Camellia_SBOX(%rip),%rbp + leaq (%r14,%rdi,1),%r15 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +L$enc_epilogue: + retq + + + +.p2align 4 +_x86_64_Camellia_encrypt: + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.p2align 4 +L$eloop: + movl 16(%r14),%ebx + movl 20(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 56(%r14),%ebx + movl 60(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 64(%r14),%ebx + movl 68(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq 64(%r14),%r14 + cmpq %r15,%r14 + movl 8(%r14),%edx + movl 12(%r14),%ecx + je L$edone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + jmp L$eloop + +.p2align 4 +L$edone: + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r8d,%ecx + xorl %r9d,%edx + + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r10d + movl %edx,%r11d + + retq + + + +.globl _Camellia_DecryptBlock + +.p2align 4 +_Camellia_DecryptBlock: + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp L$dec_rounds + + +.globl _Camellia_DecryptBlock_Rounds + +.p2align 4 +L$dec_rounds: +_Camellia_DecryptBlock_Rounds: + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +L$dec_prologue: + + + movq %rcx,%r13 + movq %rdx,%r15 + + shll $6,%edi + leaq L$Camellia_SBOX(%rip),%rbp + leaq (%r15,%rdi,1),%r14 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_decrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +L$dec_epilogue: + retq + + + +.p2align 4 +_x86_64_Camellia_decrypt: + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.p2align 4 +L$dloop: + movl -8(%r14),%ebx + movl -4(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -16(%r14),%ebx + movl -12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -24(%r14),%ebx + movl -20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -32(%r14),%ebx + movl -28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -40(%r14),%ebx + movl -36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -48(%r14),%ebx + movl -44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -56(%r14),%ebx + movl -52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq -64(%r14),%r14 + cmpq %r15,%r14 + movl 0(%r14),%edx + movl 4(%r14),%ecx + je L$ddone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + + jmp L$dloop + +.p2align 4 +L$ddone: + xorl %r10d,%ecx + xorl %r11d,%edx + xorl %r8d,%eax + xorl %r9d,%ebx + + movl %ecx,%r8d + movl %edx,%r9d + movl %eax,%r10d + movl %ebx,%r11d + + retq + +.globl _Camellia_Ekeygen + +.p2align 4 +_Camellia_Ekeygen: + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +L$key_prologue: + + movq %rdi,%r15 + movq %rdx,%r13 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + movl 12(%rsi),%r11d + + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,0(%r13) + movl %r8d,4(%r13) + movl %r11d,8(%r13) + movl %r10d,12(%r13) + cmpq $128,%r15 + je L$1st128 + + movl 16(%rsi),%r8d + movl 20(%rsi),%r9d + cmpq $192,%r15 + je L$1st192 + movl 24(%rsi),%r10d + movl 28(%rsi),%r11d + jmp L$1st256 +L$1st192: + movl %r8d,%r10d + movl %r9d,%r11d + notl %r10d + notl %r11d +L$1st256: + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,32(%r13) + movl %r8d,36(%r13) + movl %r11d,40(%r13) + movl %r10d,44(%r13) + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + +L$1st128: + leaq L$Camellia_SIGMA(%rip),%r14 + leaq L$Camellia_SBOX(%rip),%rbp + + movl 0(%r14),%ebx + movl 4(%r14),%eax + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 8(%r14),%ebx + movl 12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 16(%r14),%ebx + movl 20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + cmpq $128,%r15 + jne L$2nd256 + + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq -128(%r13),%rax + movq -120(%r13),%rbx + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,-96(%r13) + movq %rbx,-88(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-80(%r13) + movq %r10,-72(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-64(%r13) + movq %r10,-56(%r13) + movq %rax,%r11 + shlq $30,%rax + movq %rbx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rax + shlq $30,%rbx + orq %r11,%rbx + movq %rax,-48(%r13) + movq %rbx,-40(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-32(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rbx,-24(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-16(%r13) + movq %r10,-8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,16(%r13) + movq %rbx,24(%r13) + movq %r8,%r11 + shlq $34,%r8 + movq %r10,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%r8 + shlq $34,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r8,%r11 + shlq $17,%r8 + movq %r10,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r8 + shlq $17,%r10 + orq %r11,%r10 + movq %r8,64(%r13) + movq %r10,72(%r13) + movl $3,%eax + jmp L$done +.p2align 4 +L$2nd256: + movl %r9d,48(%r13) + movl %r8d,52(%r13) + movl %r11d,56(%r13) + movl %r10d,60(%r13) + xorl 32(%r13),%r9d + xorl 36(%r13),%r8d + xorl 40(%r13),%r11d + xorl 44(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + movq 0(%r13),%rax + movq 8(%r13),%rbx + movq 32(%r13),%rcx + movq 40(%r13),%rdx + movq 48(%r13),%r14 + movq 56(%r13),%r15 + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-96(%r13) + movq %rdx,-88(%r13) + movq %r14,%r11 + shlq $15,%r14 + movq %r15,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r14 + shlq $15,%r15 + orq %r11,%r15 + movq %r14,-80(%r13) + movq %r15,-72(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-64(%r13) + movq %rdx,-56(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,-48(%r13) + movq %r10,-40(%r13) + movq %rax,%r11 + shlq $45,%rax + movq %rbx,%r9 + shrq $19,%r9 + shrq $19,%r11 + orq %r9,%rax + shlq $45,%rbx + orq %r11,%rbx + movq %rax,-32(%r13) + movq %rbx,-24(%r13) + movq %r14,%r11 + shlq $30,%r14 + movq %r15,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r14 + shlq $30,%r15 + orq %r11,%r15 + movq %r14,-16(%r13) + movq %r15,-8(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rcx,%r11 + shlq $30,%rcx + movq %rdx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rcx + shlq $30,%rdx + orq %r11,%rdx + movq %rcx,16(%r13) + movq %rdx,24(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r14,%r11 + shlq $32,%r14 + movq %r15,%r9 + shrq $32,%r9 + shrq $32,%r11 + orq %r9,%r14 + shlq $32,%r15 + orq %r11,%r15 + movq %r14,64(%r13) + movq %r15,72(%r13) + movq %rcx,%r11 + shlq $34,%rcx + movq %rdx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rcx + shlq $34,%rdx + orq %r11,%rdx + movq %rcx,80(%r13) + movq %rdx,88(%r13) + movq %r14,%r11 + shlq $17,%r14 + movq %r15,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r14 + shlq $17,%r15 + orq %r11,%r15 + movq %r14,96(%r13) + movq %r15,104(%r13) + movq %rax,%r11 + shlq $34,%rax + movq %rbx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rax + shlq $34,%rbx + orq %r11,%rbx + movq %rax,112(%r13) + movq %rbx,120(%r13) + movq %r8,%r11 + shlq $51,%r8 + movq %r10,%r9 + shrq $13,%r9 + shrq $13,%r11 + orq %r9,%r8 + shlq $51,%r10 + orq %r11,%r10 + movq %r8,128(%r13) + movq %r10,136(%r13) + movl $4,%eax +L$done: + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +L$key_epilogue: + retq + +.p2align 6 +L$Camellia_SIGMA: +.long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858 +.long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5 +.long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2 +.long 0, 0, 0, 0 +L$Camellia_SBOX: +.long 0x70707000,0x70700070 +.long 0x82828200,0x2c2c002c +.long 0x2c2c2c00,0xb3b300b3 +.long 0xececec00,0xc0c000c0 +.long 0xb3b3b300,0xe4e400e4 +.long 0x27272700,0x57570057 +.long 0xc0c0c000,0xeaea00ea +.long 0xe5e5e500,0xaeae00ae +.long 0xe4e4e400,0x23230023 +.long 0x85858500,0x6b6b006b +.long 0x57575700,0x45450045 +.long 0x35353500,0xa5a500a5 +.long 0xeaeaea00,0xeded00ed +.long 0x0c0c0c00,0x4f4f004f +.long 0xaeaeae00,0x1d1d001d +.long 0x41414100,0x92920092 +.long 0x23232300,0x86860086 +.long 0xefefef00,0xafaf00af +.long 0x6b6b6b00,0x7c7c007c +.long 0x93939300,0x1f1f001f +.long 0x45454500,0x3e3e003e +.long 0x19191900,0xdcdc00dc +.long 0xa5a5a500,0x5e5e005e +.long 0x21212100,0x0b0b000b +.long 0xededed00,0xa6a600a6 +.long 0x0e0e0e00,0x39390039 +.long 0x4f4f4f00,0xd5d500d5 +.long 0x4e4e4e00,0x5d5d005d +.long 0x1d1d1d00,0xd9d900d9 +.long 0x65656500,0x5a5a005a +.long 0x92929200,0x51510051 +.long 0xbdbdbd00,0x6c6c006c +.long 0x86868600,0x8b8b008b +.long 0xb8b8b800,0x9a9a009a +.long 0xafafaf00,0xfbfb00fb +.long 0x8f8f8f00,0xb0b000b0 +.long 0x7c7c7c00,0x74740074 +.long 0xebebeb00,0x2b2b002b +.long 0x1f1f1f00,0xf0f000f0 +.long 0xcecece00,0x84840084 +.long 0x3e3e3e00,0xdfdf00df +.long 0x30303000,0xcbcb00cb +.long 0xdcdcdc00,0x34340034 +.long 0x5f5f5f00,0x76760076 +.long 0x5e5e5e00,0x6d6d006d +.long 0xc5c5c500,0xa9a900a9 +.long 0x0b0b0b00,0xd1d100d1 +.long 0x1a1a1a00,0x04040004 +.long 0xa6a6a600,0x14140014 +.long 0xe1e1e100,0x3a3a003a +.long 0x39393900,0xdede00de +.long 0xcacaca00,0x11110011 +.long 0xd5d5d500,0x32320032 +.long 0x47474700,0x9c9c009c +.long 0x5d5d5d00,0x53530053 +.long 0x3d3d3d00,0xf2f200f2 +.long 0xd9d9d900,0xfefe00fe +.long 0x01010100,0xcfcf00cf +.long 0x5a5a5a00,0xc3c300c3 +.long 0xd6d6d600,0x7a7a007a +.long 0x51515100,0x24240024 +.long 0x56565600,0xe8e800e8 +.long 0x6c6c6c00,0x60600060 +.long 0x4d4d4d00,0x69690069 +.long 0x8b8b8b00,0xaaaa00aa +.long 0x0d0d0d00,0xa0a000a0 +.long 0x9a9a9a00,0xa1a100a1 +.long 0x66666600,0x62620062 +.long 0xfbfbfb00,0x54540054 +.long 0xcccccc00,0x1e1e001e +.long 0xb0b0b000,0xe0e000e0 +.long 0x2d2d2d00,0x64640064 +.long 0x74747400,0x10100010 +.long 0x12121200,0x00000000 +.long 0x2b2b2b00,0xa3a300a3 +.long 0x20202000,0x75750075 +.long 0xf0f0f000,0x8a8a008a +.long 0xb1b1b100,0xe6e600e6 +.long 0x84848400,0x09090009 +.long 0x99999900,0xdddd00dd +.long 0xdfdfdf00,0x87870087 +.long 0x4c4c4c00,0x83830083 +.long 0xcbcbcb00,0xcdcd00cd +.long 0xc2c2c200,0x90900090 +.long 0x34343400,0x73730073 +.long 0x7e7e7e00,0xf6f600f6 +.long 0x76767600,0x9d9d009d +.long 0x05050500,0xbfbf00bf +.long 0x6d6d6d00,0x52520052 +.long 0xb7b7b700,0xd8d800d8 +.long 0xa9a9a900,0xc8c800c8 +.long 0x31313100,0xc6c600c6 +.long 0xd1d1d100,0x81810081 +.long 0x17171700,0x6f6f006f +.long 0x04040400,0x13130013 +.long 0xd7d7d700,0x63630063 +.long 0x14141400,0xe9e900e9 +.long 0x58585800,0xa7a700a7 +.long 0x3a3a3a00,0x9f9f009f +.long 0x61616100,0xbcbc00bc +.long 0xdedede00,0x29290029 +.long 0x1b1b1b00,0xf9f900f9 +.long 0x11111100,0x2f2f002f +.long 0x1c1c1c00,0xb4b400b4 +.long 0x32323200,0x78780078 +.long 0x0f0f0f00,0x06060006 +.long 0x9c9c9c00,0xe7e700e7 +.long 0x16161600,0x71710071 +.long 0x53535300,0xd4d400d4 +.long 0x18181800,0xabab00ab +.long 0xf2f2f200,0x88880088 +.long 0x22222200,0x8d8d008d +.long 0xfefefe00,0x72720072 +.long 0x44444400,0xb9b900b9 +.long 0xcfcfcf00,0xf8f800f8 +.long 0xb2b2b200,0xacac00ac +.long 0xc3c3c300,0x36360036 +.long 0xb5b5b500,0x2a2a002a +.long 0x7a7a7a00,0x3c3c003c +.long 0x91919100,0xf1f100f1 +.long 0x24242400,0x40400040 +.long 0x08080800,0xd3d300d3 +.long 0xe8e8e800,0xbbbb00bb +.long 0xa8a8a800,0x43430043 +.long 0x60606000,0x15150015 +.long 0xfcfcfc00,0xadad00ad +.long 0x69696900,0x77770077 +.long 0x50505000,0x80800080 +.long 0xaaaaaa00,0x82820082 +.long 0xd0d0d000,0xecec00ec +.long 0xa0a0a000,0x27270027 +.long 0x7d7d7d00,0xe5e500e5 +.long 0xa1a1a100,0x85850085 +.long 0x89898900,0x35350035 +.long 0x62626200,0x0c0c000c +.long 0x97979700,0x41410041 +.long 0x54545400,0xefef00ef +.long 0x5b5b5b00,0x93930093 +.long 0x1e1e1e00,0x19190019 +.long 0x95959500,0x21210021 +.long 0xe0e0e000,0x0e0e000e +.long 0xffffff00,0x4e4e004e +.long 0x64646400,0x65650065 +.long 0xd2d2d200,0xbdbd00bd +.long 0x10101000,0xb8b800b8 +.long 0xc4c4c400,0x8f8f008f +.long 0x00000000,0xebeb00eb +.long 0x48484800,0xcece00ce +.long 0xa3a3a300,0x30300030 +.long 0xf7f7f700,0x5f5f005f +.long 0x75757500,0xc5c500c5 +.long 0xdbdbdb00,0x1a1a001a +.long 0x8a8a8a00,0xe1e100e1 +.long 0x03030300,0xcaca00ca +.long 0xe6e6e600,0x47470047 +.long 0xdadada00,0x3d3d003d +.long 0x09090900,0x01010001 +.long 0x3f3f3f00,0xd6d600d6 +.long 0xdddddd00,0x56560056 +.long 0x94949400,0x4d4d004d +.long 0x87878700,0x0d0d000d +.long 0x5c5c5c00,0x66660066 +.long 0x83838300,0xcccc00cc +.long 0x02020200,0x2d2d002d +.long 0xcdcdcd00,0x12120012 +.long 0x4a4a4a00,0x20200020 +.long 0x90909000,0xb1b100b1 +.long 0x33333300,0x99990099 +.long 0x73737300,0x4c4c004c +.long 0x67676700,0xc2c200c2 +.long 0xf6f6f600,0x7e7e007e +.long 0xf3f3f300,0x05050005 +.long 0x9d9d9d00,0xb7b700b7 +.long 0x7f7f7f00,0x31310031 +.long 0xbfbfbf00,0x17170017 +.long 0xe2e2e200,0xd7d700d7 +.long 0x52525200,0x58580058 +.long 0x9b9b9b00,0x61610061 +.long 0xd8d8d800,0x1b1b001b +.long 0x26262600,0x1c1c001c +.long 0xc8c8c800,0x0f0f000f +.long 0x37373700,0x16160016 +.long 0xc6c6c600,0x18180018 +.long 0x3b3b3b00,0x22220022 +.long 0x81818100,0x44440044 +.long 0x96969600,0xb2b200b2 +.long 0x6f6f6f00,0xb5b500b5 +.long 0x4b4b4b00,0x91910091 +.long 0x13131300,0x08080008 +.long 0xbebebe00,0xa8a800a8 +.long 0x63636300,0xfcfc00fc +.long 0x2e2e2e00,0x50500050 +.long 0xe9e9e900,0xd0d000d0 +.long 0x79797900,0x7d7d007d +.long 0xa7a7a700,0x89890089 +.long 0x8c8c8c00,0x97970097 +.long 0x9f9f9f00,0x5b5b005b +.long 0x6e6e6e00,0x95950095 +.long 0xbcbcbc00,0xffff00ff +.long 0x8e8e8e00,0xd2d200d2 +.long 0x29292900,0xc4c400c4 +.long 0xf5f5f500,0x48480048 +.long 0xf9f9f900,0xf7f700f7 +.long 0xb6b6b600,0xdbdb00db +.long 0x2f2f2f00,0x03030003 +.long 0xfdfdfd00,0xdada00da +.long 0xb4b4b400,0x3f3f003f +.long 0x59595900,0x94940094 +.long 0x78787800,0x5c5c005c +.long 0x98989800,0x02020002 +.long 0x06060600,0x4a4a004a +.long 0x6a6a6a00,0x33330033 +.long 0xe7e7e700,0x67670067 +.long 0x46464600,0xf3f300f3 +.long 0x71717100,0x7f7f007f +.long 0xbababa00,0xe2e200e2 +.long 0xd4d4d400,0x9b9b009b +.long 0x25252500,0x26260026 +.long 0xababab00,0x37370037 +.long 0x42424200,0x3b3b003b +.long 0x88888800,0x96960096 +.long 0xa2a2a200,0x4b4b004b +.long 0x8d8d8d00,0xbebe00be +.long 0xfafafa00,0x2e2e002e +.long 0x72727200,0x79790079 +.long 0x07070700,0x8c8c008c +.long 0xb9b9b900,0x6e6e006e +.long 0x55555500,0x8e8e008e +.long 0xf8f8f800,0xf5f500f5 +.long 0xeeeeee00,0xb6b600b6 +.long 0xacacac00,0xfdfd00fd +.long 0x0a0a0a00,0x59590059 +.long 0x36363600,0x98980098 +.long 0x49494900,0x6a6a006a +.long 0x2a2a2a00,0x46460046 +.long 0x68686800,0xbaba00ba +.long 0x3c3c3c00,0x25250025 +.long 0x38383800,0x42420042 +.long 0xf1f1f100,0xa2a200a2 +.long 0xa4a4a400,0xfafa00fa +.long 0x40404000,0x07070007 +.long 0x28282800,0x55550055 +.long 0xd3d3d300,0xeeee00ee +.long 0x7b7b7b00,0x0a0a000a +.long 0xbbbbbb00,0x49490049 +.long 0xc9c9c900,0x68680068 +.long 0x43434300,0x38380038 +.long 0xc1c1c100,0xa4a400a4 +.long 0x15151500,0x28280028 +.long 0xe3e3e300,0x7b7b007b +.long 0xadadad00,0xc9c900c9 +.long 0xf4f4f400,0xc1c100c1 +.long 0x77777700,0xe3e300e3 +.long 0xc7c7c700,0xf4f400f4 +.long 0x80808000,0xc7c700c7 +.long 0x9e9e9e00,0x9e9e009e +.long 0x00e0e0e0,0x38003838 +.long 0x00050505,0x41004141 +.long 0x00585858,0x16001616 +.long 0x00d9d9d9,0x76007676 +.long 0x00676767,0xd900d9d9 +.long 0x004e4e4e,0x93009393 +.long 0x00818181,0x60006060 +.long 0x00cbcbcb,0xf200f2f2 +.long 0x00c9c9c9,0x72007272 +.long 0x000b0b0b,0xc200c2c2 +.long 0x00aeaeae,0xab00abab +.long 0x006a6a6a,0x9a009a9a +.long 0x00d5d5d5,0x75007575 +.long 0x00181818,0x06000606 +.long 0x005d5d5d,0x57005757 +.long 0x00828282,0xa000a0a0 +.long 0x00464646,0x91009191 +.long 0x00dfdfdf,0xf700f7f7 +.long 0x00d6d6d6,0xb500b5b5 +.long 0x00272727,0xc900c9c9 +.long 0x008a8a8a,0xa200a2a2 +.long 0x00323232,0x8c008c8c +.long 0x004b4b4b,0xd200d2d2 +.long 0x00424242,0x90009090 +.long 0x00dbdbdb,0xf600f6f6 +.long 0x001c1c1c,0x07000707 +.long 0x009e9e9e,0xa700a7a7 +.long 0x009c9c9c,0x27002727 +.long 0x003a3a3a,0x8e008e8e +.long 0x00cacaca,0xb200b2b2 +.long 0x00252525,0x49004949 +.long 0x007b7b7b,0xde00dede +.long 0x000d0d0d,0x43004343 +.long 0x00717171,0x5c005c5c +.long 0x005f5f5f,0xd700d7d7 +.long 0x001f1f1f,0xc700c7c7 +.long 0x00f8f8f8,0x3e003e3e +.long 0x00d7d7d7,0xf500f5f5 +.long 0x003e3e3e,0x8f008f8f +.long 0x009d9d9d,0x67006767 +.long 0x007c7c7c,0x1f001f1f +.long 0x00606060,0x18001818 +.long 0x00b9b9b9,0x6e006e6e +.long 0x00bebebe,0xaf00afaf +.long 0x00bcbcbc,0x2f002f2f +.long 0x008b8b8b,0xe200e2e2 +.long 0x00161616,0x85008585 +.long 0x00343434,0x0d000d0d +.long 0x004d4d4d,0x53005353 +.long 0x00c3c3c3,0xf000f0f0 +.long 0x00727272,0x9c009c9c +.long 0x00959595,0x65006565 +.long 0x00ababab,0xea00eaea +.long 0x008e8e8e,0xa300a3a3 +.long 0x00bababa,0xae00aeae +.long 0x007a7a7a,0x9e009e9e +.long 0x00b3b3b3,0xec00ecec +.long 0x00020202,0x80008080 +.long 0x00b4b4b4,0x2d002d2d +.long 0x00adadad,0x6b006b6b +.long 0x00a2a2a2,0xa800a8a8 +.long 0x00acacac,0x2b002b2b +.long 0x00d8d8d8,0x36003636 +.long 0x009a9a9a,0xa600a6a6 +.long 0x00171717,0xc500c5c5 +.long 0x001a1a1a,0x86008686 +.long 0x00353535,0x4d004d4d +.long 0x00cccccc,0x33003333 +.long 0x00f7f7f7,0xfd00fdfd +.long 0x00999999,0x66006666 +.long 0x00616161,0x58005858 +.long 0x005a5a5a,0x96009696 +.long 0x00e8e8e8,0x3a003a3a +.long 0x00242424,0x09000909 +.long 0x00565656,0x95009595 +.long 0x00404040,0x10001010 +.long 0x00e1e1e1,0x78007878 +.long 0x00636363,0xd800d8d8 +.long 0x00090909,0x42004242 +.long 0x00333333,0xcc00cccc +.long 0x00bfbfbf,0xef00efef +.long 0x00989898,0x26002626 +.long 0x00979797,0xe500e5e5 +.long 0x00858585,0x61006161 +.long 0x00686868,0x1a001a1a +.long 0x00fcfcfc,0x3f003f3f +.long 0x00ececec,0x3b003b3b +.long 0x000a0a0a,0x82008282 +.long 0x00dadada,0xb600b6b6 +.long 0x006f6f6f,0xdb00dbdb +.long 0x00535353,0xd400d4d4 +.long 0x00626262,0x98009898 +.long 0x00a3a3a3,0xe800e8e8 +.long 0x002e2e2e,0x8b008b8b +.long 0x00080808,0x02000202 +.long 0x00afafaf,0xeb00ebeb +.long 0x00282828,0x0a000a0a +.long 0x00b0b0b0,0x2c002c2c +.long 0x00747474,0x1d001d1d +.long 0x00c2c2c2,0xb000b0b0 +.long 0x00bdbdbd,0x6f006f6f +.long 0x00363636,0x8d008d8d +.long 0x00222222,0x88008888 +.long 0x00383838,0x0e000e0e +.long 0x00646464,0x19001919 +.long 0x001e1e1e,0x87008787 +.long 0x00393939,0x4e004e4e +.long 0x002c2c2c,0x0b000b0b +.long 0x00a6a6a6,0xa900a9a9 +.long 0x00303030,0x0c000c0c +.long 0x00e5e5e5,0x79007979 +.long 0x00444444,0x11001111 +.long 0x00fdfdfd,0x7f007f7f +.long 0x00888888,0x22002222 +.long 0x009f9f9f,0xe700e7e7 +.long 0x00656565,0x59005959 +.long 0x00878787,0xe100e1e1 +.long 0x006b6b6b,0xda00dada +.long 0x00f4f4f4,0x3d003d3d +.long 0x00232323,0xc800c8c8 +.long 0x00484848,0x12001212 +.long 0x00101010,0x04000404 +.long 0x00d1d1d1,0x74007474 +.long 0x00515151,0x54005454 +.long 0x00c0c0c0,0x30003030 +.long 0x00f9f9f9,0x7e007e7e +.long 0x00d2d2d2,0xb400b4b4 +.long 0x00a0a0a0,0x28002828 +.long 0x00555555,0x55005555 +.long 0x00a1a1a1,0x68006868 +.long 0x00414141,0x50005050 +.long 0x00fafafa,0xbe00bebe +.long 0x00434343,0xd000d0d0 +.long 0x00131313,0xc400c4c4 +.long 0x00c4c4c4,0x31003131 +.long 0x002f2f2f,0xcb00cbcb +.long 0x00a8a8a8,0x2a002a2a +.long 0x00b6b6b6,0xad00adad +.long 0x003c3c3c,0x0f000f0f +.long 0x002b2b2b,0xca00caca +.long 0x00c1c1c1,0x70007070 +.long 0x00ffffff,0xff00ffff +.long 0x00c8c8c8,0x32003232 +.long 0x00a5a5a5,0x69006969 +.long 0x00202020,0x08000808 +.long 0x00898989,0x62006262 +.long 0x00000000,0x00000000 +.long 0x00909090,0x24002424 +.long 0x00474747,0xd100d1d1 +.long 0x00efefef,0xfb00fbfb +.long 0x00eaeaea,0xba00baba +.long 0x00b7b7b7,0xed00eded +.long 0x00151515,0x45004545 +.long 0x00060606,0x81008181 +.long 0x00cdcdcd,0x73007373 +.long 0x00b5b5b5,0x6d006d6d +.long 0x00121212,0x84008484 +.long 0x007e7e7e,0x9f009f9f +.long 0x00bbbbbb,0xee00eeee +.long 0x00292929,0x4a004a4a +.long 0x000f0f0f,0xc300c3c3 +.long 0x00b8b8b8,0x2e002e2e +.long 0x00070707,0xc100c1c1 +.long 0x00040404,0x01000101 +.long 0x009b9b9b,0xe600e6e6 +.long 0x00949494,0x25002525 +.long 0x00212121,0x48004848 +.long 0x00666666,0x99009999 +.long 0x00e6e6e6,0xb900b9b9 +.long 0x00cecece,0xb300b3b3 +.long 0x00ededed,0x7b007b7b +.long 0x00e7e7e7,0xf900f9f9 +.long 0x003b3b3b,0xce00cece +.long 0x00fefefe,0xbf00bfbf +.long 0x007f7f7f,0xdf00dfdf +.long 0x00c5c5c5,0x71007171 +.long 0x00a4a4a4,0x29002929 +.long 0x00373737,0xcd00cdcd +.long 0x00b1b1b1,0x6c006c6c +.long 0x004c4c4c,0x13001313 +.long 0x00919191,0x64006464 +.long 0x006e6e6e,0x9b009b9b +.long 0x008d8d8d,0x63006363 +.long 0x00767676,0x9d009d9d +.long 0x00030303,0xc000c0c0 +.long 0x002d2d2d,0x4b004b4b +.long 0x00dedede,0xb700b7b7 +.long 0x00969696,0xa500a5a5 +.long 0x00262626,0x89008989 +.long 0x007d7d7d,0x5f005f5f +.long 0x00c6c6c6,0xb100b1b1 +.long 0x005c5c5c,0x17001717 +.long 0x00d3d3d3,0xf400f4f4 +.long 0x00f2f2f2,0xbc00bcbc +.long 0x004f4f4f,0xd300d3d3 +.long 0x00191919,0x46004646 +.long 0x003f3f3f,0xcf00cfcf +.long 0x00dcdcdc,0x37003737 +.long 0x00797979,0x5e005e5e +.long 0x001d1d1d,0x47004747 +.long 0x00525252,0x94009494 +.long 0x00ebebeb,0xfa00fafa +.long 0x00f3f3f3,0xfc00fcfc +.long 0x006d6d6d,0x5b005b5b +.long 0x005e5e5e,0x97009797 +.long 0x00fbfbfb,0xfe00fefe +.long 0x00696969,0x5a005a5a +.long 0x00b2b2b2,0xac00acac +.long 0x00f0f0f0,0x3c003c3c +.long 0x00313131,0x4c004c4c +.long 0x000c0c0c,0x03000303 +.long 0x00d4d4d4,0x35003535 +.long 0x00cfcfcf,0xf300f3f3 +.long 0x008c8c8c,0x23002323 +.long 0x00e2e2e2,0xb800b8b8 +.long 0x00757575,0x5d005d5d +.long 0x00a9a9a9,0x6a006a6a +.long 0x004a4a4a,0x92009292 +.long 0x00575757,0xd500d5d5 +.long 0x00848484,0x21002121 +.long 0x00111111,0x44004444 +.long 0x00454545,0x51005151 +.long 0x001b1b1b,0xc600c6c6 +.long 0x00f5f5f5,0x7d007d7d +.long 0x00e4e4e4,0x39003939 +.long 0x000e0e0e,0x83008383 +.long 0x00737373,0xdc00dcdc +.long 0x00aaaaaa,0xaa00aaaa +.long 0x00f1f1f1,0x7c007c7c +.long 0x00dddddd,0x77007777 +.long 0x00595959,0x56005656 +.long 0x00141414,0x05000505 +.long 0x006c6c6c,0x1b001b1b +.long 0x00929292,0xa400a4a4 +.long 0x00545454,0x15001515 +.long 0x00d0d0d0,0x34003434 +.long 0x00787878,0x1e001e1e +.long 0x00707070,0x1c001c1c +.long 0x00e3e3e3,0xf800f8f8 +.long 0x00494949,0x52005252 +.long 0x00808080,0x20002020 +.long 0x00505050,0x14001414 +.long 0x00a7a7a7,0xe900e9e9 +.long 0x00f6f6f6,0xbd00bdbd +.long 0x00777777,0xdd00dddd +.long 0x00939393,0xe400e4e4 +.long 0x00868686,0xa100a1a1 +.long 0x00838383,0xe000e0e0 +.long 0x002a2a2a,0x8a008a8a +.long 0x00c7c7c7,0xf100f1f1 +.long 0x005b5b5b,0xd600d6d6 +.long 0x00e9e9e9,0x7a007a7a +.long 0x00eeeeee,0xbb00bbbb +.long 0x008f8f8f,0xe300e3e3 +.long 0x00010101,0x40004040 +.long 0x003d3d3d,0x4f004f4f +.globl _Camellia_cbc_encrypt + +.p2align 4 +_Camellia_cbc_encrypt: + cmpq $0,%rdx + je L$cbc_abort + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 +L$cbc_prologue: + + movq %rsp,%rbp + subq $64,%rsp + andq $-64,%rsp + + + + leaq -64-63(%rcx),%r10 + subq %rsp,%r10 + negq %r10 + andq $960,%r10 + subq %r10,%rsp + + + movq %rdi,%r12 + movq %rsi,%r13 + movq %r8,%rbx + movq %rcx,%r14 + movl 272(%rcx),%r15d + + movq %r8,40(%rsp) + movq %rbp,48(%rsp) + +L$cbc_body: + leaq L$Camellia_SBOX(%rip),%rbp + + movl $32,%ecx +.p2align 2 +L$cbc_prefetch_sbox: + movq 0(%rbp),%rax + movq 32(%rbp),%rsi + movq 64(%rbp),%rdi + movq 96(%rbp),%r11 + leaq 128(%rbp),%rbp + loop L$cbc_prefetch_sbox + subq $4096,%rbp + shlq $6,%r15 + movq %rdx,%rcx + leaq (%r14,%r15,1),%r15 + + cmpl $0,%r9d + je L$CBC_DECRYPT + + andq $-16,%rdx + andq $15,%rcx + leaq (%r12,%rdx,1),%rdx + movq %r14,0(%rsp) + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + cmpq %r12,%rdx + movl 0(%rbx),%r8d + movl 4(%rbx),%r9d + movl 8(%rbx),%r10d + movl 12(%rbx),%r11d + je L$cbc_enc_tail + jmp L$cbc_eloop + +.p2align 4 +L$cbc_eloop: + xorl 0(%r12),%r8d + xorl 4(%r12),%r9d + xorl 8(%r12),%r10d + bswapl %r8d + xorl 12(%r12),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + movq 0(%rsp),%r14 + bswapl %r8d + movq 8(%rsp),%rdx + bswapl %r9d + movq 16(%rsp),%rcx + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + leaq 16(%r12),%r12 + movl %r11d,12(%r13) + cmpq %rdx,%r12 + leaq 16(%r13),%r13 + jne L$cbc_eloop + + cmpq $0,%rcx + jne L$cbc_enc_tail + + movq 40(%rsp),%r13 + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + jmp L$cbc_done + +.p2align 4 +L$cbc_enc_tail: + xorq %rax,%rax + movq %rax,0+24(%rsp) + movq %rax,8+24(%rsp) + movq %rax,16(%rsp) + +L$cbc_enc_pushf: + pushfq + cld + movq %r12,%rsi + leaq 8+24(%rsp),%rdi +.long 0x9066A4F3 + popfq +L$cbc_enc_popf: + + leaq 24(%rsp),%r12 + leaq 16+24(%rsp),%rax + movq %rax,8(%rsp) + jmp L$cbc_eloop + +.p2align 4 +L$CBC_DECRYPT: + xchgq %r14,%r15 + addq $15,%rdx + andq $15,%rcx + andq $-16,%rdx + movq %r14,0(%rsp) + leaq (%r12,%rdx,1),%rdx + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + movq (%rbx),%rax + movq 8(%rbx),%rbx + jmp L$cbc_dloop +.p2align 4 +L$cbc_dloop: + movl 0(%r12),%r8d + movl 4(%r12),%r9d + movl 8(%r12),%r10d + bswapl %r8d + movl 12(%r12),%r11d + bswapl %r9d + movq %rax,0+24(%rsp) + bswapl %r10d + movq %rbx,8+24(%rsp) + bswapl %r11d + + call _x86_64_Camellia_decrypt + + movq 0(%rsp),%r14 + movq 8(%rsp),%rdx + movq 16(%rsp),%rcx + + bswapl %r8d + movq (%r12),%rax + bswapl %r9d + movq 8(%r12),%rbx + bswapl %r10d + xorl 0+24(%rsp),%r8d + bswapl %r11d + xorl 4+24(%rsp),%r9d + xorl 8+24(%rsp),%r10d + leaq 16(%r12),%r12 + xorl 12+24(%rsp),%r11d + cmpq %rdx,%r12 + je L$cbc_ddone + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + leaq 16(%r13),%r13 + jmp L$cbc_dloop + +.p2align 4 +L$cbc_ddone: + movq 40(%rsp),%rdx + cmpq $0,%rcx + jne L$cbc_dec_tail + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp L$cbc_done +.p2align 4 +L$cbc_dec_tail: + movl %r8d,0+24(%rsp) + movl %r9d,4+24(%rsp) + movl %r10d,8+24(%rsp) + movl %r11d,12+24(%rsp) + +L$cbc_dec_pushf: + pushfq + cld + leaq 8+24(%rsp),%rsi + leaq (%r13),%rdi +.long 0x9066A4F3 + popfq +L$cbc_dec_popf: + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp L$cbc_done + +.p2align 4 +L$cbc_done: + movq 48(%rsp),%rcx + movq 0(%rcx),%r15 + movq 8(%rcx),%r14 + movq 16(%rcx),%r13 + movq 24(%rcx),%r12 + movq 32(%rcx),%rbp + movq 40(%rcx),%rbx + leaq 48(%rcx),%rsp +L$cbc_abort: + retq + + +.byte 67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 diff --git a/Libraries/libressl/crypto/camellia/cmll-masm-x86_64.S b/Libraries/libressl/crypto/camellia/cmll-masm-x86_64.S new file mode 100644 index 000000000..e1871b501 --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll-masm-x86_64.S @@ -0,0 +1,1966 @@ +; 1 "crypto/camellia/cmll-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/camellia/cmll-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/camellia/cmll-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + + +PUBLIC Camellia_EncryptBlock + +ALIGN 16 +Camellia_EncryptBlock PROC PUBLIC + mov eax,128 + sub eax,edi + mov edi,3 + adc edi,0 + jmp $L$enc_rounds +Camellia_EncryptBlock ENDP + +PUBLIC Camellia_EncryptBlock_Rounds + +ALIGN 16 +$L$enc_rounds:: +Camellia_EncryptBlock_Rounds PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_Camellia_EncryptBlock_Rounds:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + + push rbx + push rbp + push r13 + push r14 + push r15 +$L$enc_prologue:: + + + mov r13,rcx + mov r14,rdx + + shl edi,6 + lea rbp,QWORD PTR[$L$Camellia_SBOX] + lea r15,QWORD PTR[rdi*1+r14] + + mov r8d,DWORD PTR[rsi] + mov r9d,DWORD PTR[4+rsi] + mov r10d,DWORD PTR[8+rsi] + bswap r8d + mov r11d,DWORD PTR[12+rsi] + bswap r9d + bswap r10d + bswap r11d + + call _x86_64_Camellia_encrypt + + bswap r8d + bswap r9d + bswap r10d + mov DWORD PTR[r13],r8d + bswap r11d + mov DWORD PTR[4+r13],r9d + mov DWORD PTR[8+r13],r10d + mov DWORD PTR[12+r13],r11d + + mov r15,QWORD PTR[rsp] + mov r14,QWORD PTR[8+rsp] + mov r13,QWORD PTR[16+rsp] + mov rbp,QWORD PTR[24+rsp] + mov rbx,QWORD PTR[32+rsp] + lea rsp,QWORD PTR[40+rsp] +$L$enc_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_Camellia_EncryptBlock_Rounds:: +Camellia_EncryptBlock_Rounds ENDP + + +ALIGN 16 +_x86_64_Camellia_encrypt PROC PRIVATE + xor r9d,DWORD PTR[r14] + xor r8d,DWORD PTR[4+r14] + xor r11d,DWORD PTR[8+r14] + xor r10d,DWORD PTR[12+r14] +ALIGN 16 +$L$eloop:: + mov ebx,DWORD PTR[16+r14] + mov eax,DWORD PTR[20+r14] + + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[24+r14] + mov eax,DWORD PTR[28+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[32+r14] + mov eax,DWORD PTR[36+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[40+r14] + mov eax,DWORD PTR[44+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[48+r14] + mov eax,DWORD PTR[52+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[56+r14] + mov eax,DWORD PTR[60+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[64+r14] + mov eax,DWORD PTR[68+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + lea r14,QWORD PTR[64+r14] + cmp r14,r15 + mov edx,DWORD PTR[8+r14] + mov ecx,DWORD PTR[12+r14] + je $L$edone + + and eax,r8d + or edx,r11d + rol eax,1 + xor r10d,edx + xor r9d,eax + and ecx,r10d + or ebx,r9d + rol ecx,1 + xor r8d,ebx + xor r11d,ecx + jmp $L$eloop + +ALIGN 16 +$L$edone:: + xor eax,r10d + xor ebx,r11d + xor ecx,r8d + xor edx,r9d + + mov r8d,eax + mov r9d,ebx + mov r10d,ecx + mov r11d,edx + + DB 0F3h,0C3h ;repret +_x86_64_Camellia_encrypt ENDP + + +PUBLIC Camellia_DecryptBlock + +ALIGN 16 +Camellia_DecryptBlock PROC PUBLIC + mov eax,128 + sub eax,edi + mov edi,3 + adc edi,0 + jmp $L$dec_rounds +Camellia_DecryptBlock ENDP + +PUBLIC Camellia_DecryptBlock_Rounds + +ALIGN 16 +$L$dec_rounds:: +Camellia_DecryptBlock_Rounds PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_Camellia_DecryptBlock_Rounds:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + + push rbx + push rbp + push r13 + push r14 + push r15 +$L$dec_prologue:: + + + mov r13,rcx + mov r15,rdx + + shl edi,6 + lea rbp,QWORD PTR[$L$Camellia_SBOX] + lea r14,QWORD PTR[rdi*1+r15] + + mov r8d,DWORD PTR[rsi] + mov r9d,DWORD PTR[4+rsi] + mov r10d,DWORD PTR[8+rsi] + bswap r8d + mov r11d,DWORD PTR[12+rsi] + bswap r9d + bswap r10d + bswap r11d + + call _x86_64_Camellia_decrypt + + bswap r8d + bswap r9d + bswap r10d + mov DWORD PTR[r13],r8d + bswap r11d + mov DWORD PTR[4+r13],r9d + mov DWORD PTR[8+r13],r10d + mov DWORD PTR[12+r13],r11d + + mov r15,QWORD PTR[rsp] + mov r14,QWORD PTR[8+rsp] + mov r13,QWORD PTR[16+rsp] + mov rbp,QWORD PTR[24+rsp] + mov rbx,QWORD PTR[32+rsp] + lea rsp,QWORD PTR[40+rsp] +$L$dec_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_Camellia_DecryptBlock_Rounds:: +Camellia_DecryptBlock_Rounds ENDP + + +ALIGN 16 +_x86_64_Camellia_decrypt PROC PRIVATE + xor r9d,DWORD PTR[r14] + xor r8d,DWORD PTR[4+r14] + xor r11d,DWORD PTR[8+r14] + xor r10d,DWORD PTR[12+r14] +ALIGN 16 +$L$dloop:: + mov ebx,DWORD PTR[((-8))+r14] + mov eax,DWORD PTR[((-4))+r14] + + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[((-16))+r14] + mov eax,DWORD PTR[((-12))+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[((-24))+r14] + mov eax,DWORD PTR[((-20))+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[((-32))+r14] + mov eax,DWORD PTR[((-28))+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[((-40))+r14] + mov eax,DWORD PTR[((-36))+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[((-48))+r14] + mov eax,DWORD PTR[((-44))+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[((-56))+r14] + mov eax,DWORD PTR[((-52))+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + lea r14,QWORD PTR[((-64))+r14] + cmp r14,r15 + mov edx,DWORD PTR[r14] + mov ecx,DWORD PTR[4+r14] + je $L$ddone + + and eax,r8d + or edx,r11d + rol eax,1 + xor r10d,edx + xor r9d,eax + and ecx,r10d + or ebx,r9d + rol ecx,1 + xor r8d,ebx + xor r11d,ecx + + jmp $L$dloop + +ALIGN 16 +$L$ddone:: + xor ecx,r10d + xor edx,r11d + xor eax,r8d + xor ebx,r9d + + mov r8d,ecx + mov r9d,edx + mov r10d,eax + mov r11d,ebx + + DB 0F3h,0C3h ;repret +_x86_64_Camellia_decrypt ENDP +PUBLIC Camellia_Ekeygen + +ALIGN 16 +Camellia_Ekeygen PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_Camellia_Ekeygen:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + + push rbx + push rbp + push r13 + push r14 + push r15 +$L$key_prologue:: + + mov r15,rdi + mov r13,rdx + + mov r8d,DWORD PTR[rsi] + mov r9d,DWORD PTR[4+rsi] + mov r10d,DWORD PTR[8+rsi] + mov r11d,DWORD PTR[12+rsi] + + bswap r8d + bswap r9d + bswap r10d + bswap r11d + mov DWORD PTR[r13],r9d + mov DWORD PTR[4+r13],r8d + mov DWORD PTR[8+r13],r11d + mov DWORD PTR[12+r13],r10d + cmp r15,128 + je $L$1st128 + + mov r8d,DWORD PTR[16+rsi] + mov r9d,DWORD PTR[20+rsi] + cmp r15,192 + je $L$1st192 + mov r10d,DWORD PTR[24+rsi] + mov r11d,DWORD PTR[28+rsi] + jmp $L$1st256 +$L$1st192:: + mov r10d,r8d + mov r11d,r9d + not r10d + not r11d +$L$1st256:: + bswap r8d + bswap r9d + bswap r10d + bswap r11d + mov DWORD PTR[32+r13],r9d + mov DWORD PTR[36+r13],r8d + mov DWORD PTR[40+r13],r11d + mov DWORD PTR[44+r13],r10d + xor r9d,DWORD PTR[r13] + xor r8d,DWORD PTR[4+r13] + xor r11d,DWORD PTR[8+r13] + xor r10d,DWORD PTR[12+r13] + +$L$1st128:: + lea r14,QWORD PTR[$L$Camellia_SIGMA] + lea rbp,QWORD PTR[$L$Camellia_SBOX] + + mov ebx,DWORD PTR[r14] + mov eax,DWORD PTR[4+r14] + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[8+r14] + mov eax,DWORD PTR[12+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[16+r14] + mov eax,DWORD PTR[20+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + xor r9d,DWORD PTR[r13] + xor r8d,DWORD PTR[4+r13] + xor r11d,DWORD PTR[8+r13] + xor r10d,DWORD PTR[12+r13] + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[24+r14] + mov eax,DWORD PTR[28+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[32+r14] + mov eax,DWORD PTR[36+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + cmp r15,128 + jne $L$2nd256 + + lea r13,QWORD PTR[128+r13] + shl r8,32 + shl r10,32 + or r8,r9 + or r10,r11 + mov rax,QWORD PTR[((-128))+r13] + mov rbx,QWORD PTR[((-120))+r13] + mov QWORD PTR[((-112))+r13],r8 + mov QWORD PTR[((-104))+r13],r10 + mov r11,rax + shl rax,15 + mov r9,rbx + shr r9,49 + shr r11,49 + or rax,r9 + shl rbx,15 + or rbx,r11 + mov QWORD PTR[((-96))+r13],rax + mov QWORD PTR[((-88))+r13],rbx + mov r11,r8 + shl r8,15 + mov r9,r10 + shr r9,49 + shr r11,49 + or r8,r9 + shl r10,15 + or r10,r11 + mov QWORD PTR[((-80))+r13],r8 + mov QWORD PTR[((-72))+r13],r10 + mov r11,r8 + shl r8,15 + mov r9,r10 + shr r9,49 + shr r11,49 + or r8,r9 + shl r10,15 + or r10,r11 + mov QWORD PTR[((-64))+r13],r8 + mov QWORD PTR[((-56))+r13],r10 + mov r11,rax + shl rax,30 + mov r9,rbx + shr r9,34 + shr r11,34 + or rax,r9 + shl rbx,30 + or rbx,r11 + mov QWORD PTR[((-48))+r13],rax + mov QWORD PTR[((-40))+r13],rbx + mov r11,r8 + shl r8,15 + mov r9,r10 + shr r9,49 + shr r11,49 + or r8,r9 + shl r10,15 + or r10,r11 + mov QWORD PTR[((-32))+r13],r8 + mov r11,rax + shl rax,15 + mov r9,rbx + shr r9,49 + shr r11,49 + or rax,r9 + shl rbx,15 + or rbx,r11 + mov QWORD PTR[((-24))+r13],rbx + mov r11,r8 + shl r8,15 + mov r9,r10 + shr r9,49 + shr r11,49 + or r8,r9 + shl r10,15 + or r10,r11 + mov QWORD PTR[((-16))+r13],r8 + mov QWORD PTR[((-8))+r13],r10 + mov r11,rax + shl rax,17 + mov r9,rbx + shr r9,47 + shr r11,47 + or rax,r9 + shl rbx,17 + or rbx,r11 + mov QWORD PTR[r13],rax + mov QWORD PTR[8+r13],rbx + mov r11,rax + shl rax,17 + mov r9,rbx + shr r9,47 + shr r11,47 + or rax,r9 + shl rbx,17 + or rbx,r11 + mov QWORD PTR[16+r13],rax + mov QWORD PTR[24+r13],rbx + mov r11,r8 + shl r8,34 + mov r9,r10 + shr r9,30 + shr r11,30 + or r8,r9 + shl r10,34 + or r10,r11 + mov QWORD PTR[32+r13],r8 + mov QWORD PTR[40+r13],r10 + mov r11,rax + shl rax,17 + mov r9,rbx + shr r9,47 + shr r11,47 + or rax,r9 + shl rbx,17 + or rbx,r11 + mov QWORD PTR[48+r13],rax + mov QWORD PTR[56+r13],rbx + mov r11,r8 + shl r8,17 + mov r9,r10 + shr r9,47 + shr r11,47 + or r8,r9 + shl r10,17 + or r10,r11 + mov QWORD PTR[64+r13],r8 + mov QWORD PTR[72+r13],r10 + mov eax,3 + jmp $L$done +ALIGN 16 +$L$2nd256:: + mov DWORD PTR[48+r13],r9d + mov DWORD PTR[52+r13],r8d + mov DWORD PTR[56+r13],r11d + mov DWORD PTR[60+r13],r10d + xor r9d,DWORD PTR[32+r13] + xor r8d,DWORD PTR[36+r13] + xor r11d,DWORD PTR[40+r13] + xor r10d,DWORD PTR[44+r13] + xor eax,r8d + xor ebx,r9d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[40+r14] + mov eax,DWORD PTR[44+r14] + xor ecx,edx + ror edx,8 + xor r10d,ecx + xor r11d,ecx + xor r11d,edx + xor eax,r10d + xor ebx,r11d + movzx esi,ah + movzx edi,bl + mov edx,DWORD PTR[2052+rsi*8+rbp] + mov ecx,DWORD PTR[rdi*8+rbp] + movzx esi,al + shr eax,16 + movzx edi,bh + xor edx,DWORD PTR[4+rsi*8+rbp] + shr ebx,16 + xor ecx,DWORD PTR[4+rdi*8+rbp] + movzx esi,ah + movzx edi,bl + xor edx,DWORD PTR[rsi*8+rbp] + xor ecx,DWORD PTR[2052+rdi*8+rbp] + movzx esi,al + movzx edi,bh + xor edx,DWORD PTR[2048+rsi*8+rbp] + xor ecx,DWORD PTR[2048+rdi*8+rbp] + mov ebx,DWORD PTR[48+r14] + mov eax,DWORD PTR[52+r14] + xor ecx,edx + ror edx,8 + xor r8d,ecx + xor r9d,ecx + xor r9d,edx + mov rax,QWORD PTR[r13] + mov rbx,QWORD PTR[8+r13] + mov rcx,QWORD PTR[32+r13] + mov rdx,QWORD PTR[40+r13] + mov r14,QWORD PTR[48+r13] + mov r15,QWORD PTR[56+r13] + lea r13,QWORD PTR[128+r13] + shl r8,32 + shl r10,32 + or r8,r9 + or r10,r11 + mov QWORD PTR[((-112))+r13],r8 + mov QWORD PTR[((-104))+r13],r10 + mov r11,rcx + shl rcx,15 + mov r9,rdx + shr r9,49 + shr r11,49 + or rcx,r9 + shl rdx,15 + or rdx,r11 + mov QWORD PTR[((-96))+r13],rcx + mov QWORD PTR[((-88))+r13],rdx + mov r11,r14 + shl r14,15 + mov r9,r15 + shr r9,49 + shr r11,49 + or r14,r9 + shl r15,15 + or r15,r11 + mov QWORD PTR[((-80))+r13],r14 + mov QWORD PTR[((-72))+r13],r15 + mov r11,rcx + shl rcx,15 + mov r9,rdx + shr r9,49 + shr r11,49 + or rcx,r9 + shl rdx,15 + or rdx,r11 + mov QWORD PTR[((-64))+r13],rcx + mov QWORD PTR[((-56))+r13],rdx + mov r11,r8 + shl r8,30 + mov r9,r10 + shr r9,34 + shr r11,34 + or r8,r9 + shl r10,30 + or r10,r11 + mov QWORD PTR[((-48))+r13],r8 + mov QWORD PTR[((-40))+r13],r10 + mov r11,rax + shl rax,45 + mov r9,rbx + shr r9,19 + shr r11,19 + or rax,r9 + shl rbx,45 + or rbx,r11 + mov QWORD PTR[((-32))+r13],rax + mov QWORD PTR[((-24))+r13],rbx + mov r11,r14 + shl r14,30 + mov r9,r15 + shr r9,34 + shr r11,34 + or r14,r9 + shl r15,30 + or r15,r11 + mov QWORD PTR[((-16))+r13],r14 + mov QWORD PTR[((-8))+r13],r15 + mov r11,rax + shl rax,15 + mov r9,rbx + shr r9,49 + shr r11,49 + or rax,r9 + shl rbx,15 + or rbx,r11 + mov QWORD PTR[r13],rax + mov QWORD PTR[8+r13],rbx + mov r11,rcx + shl rcx,30 + mov r9,rdx + shr r9,34 + shr r11,34 + or rcx,r9 + shl rdx,30 + or rdx,r11 + mov QWORD PTR[16+r13],rcx + mov QWORD PTR[24+r13],rdx + mov r11,r8 + shl r8,30 + mov r9,r10 + shr r9,34 + shr r11,34 + or r8,r9 + shl r10,30 + or r10,r11 + mov QWORD PTR[32+r13],r8 + mov QWORD PTR[40+r13],r10 + mov r11,rax + shl rax,17 + mov r9,rbx + shr r9,47 + shr r11,47 + or rax,r9 + shl rbx,17 + or rbx,r11 + mov QWORD PTR[48+r13],rax + mov QWORD PTR[56+r13],rbx + mov r11,r14 + shl r14,32 + mov r9,r15 + shr r9,32 + shr r11,32 + or r14,r9 + shl r15,32 + or r15,r11 + mov QWORD PTR[64+r13],r14 + mov QWORD PTR[72+r13],r15 + mov r11,rcx + shl rcx,34 + mov r9,rdx + shr r9,30 + shr r11,30 + or rcx,r9 + shl rdx,34 + or rdx,r11 + mov QWORD PTR[80+r13],rcx + mov QWORD PTR[88+r13],rdx + mov r11,r14 + shl r14,17 + mov r9,r15 + shr r9,47 + shr r11,47 + or r14,r9 + shl r15,17 + or r15,r11 + mov QWORD PTR[96+r13],r14 + mov QWORD PTR[104+r13],r15 + mov r11,rax + shl rax,34 + mov r9,rbx + shr r9,30 + shr r11,30 + or rax,r9 + shl rbx,34 + or rbx,r11 + mov QWORD PTR[112+r13],rax + mov QWORD PTR[120+r13],rbx + mov r11,r8 + shl r8,51 + mov r9,r10 + shr r9,13 + shr r11,13 + or r8,r9 + shl r10,51 + or r10,r11 + mov QWORD PTR[128+r13],r8 + mov QWORD PTR[136+r13],r10 + mov eax,4 +$L$done:: + mov r15,QWORD PTR[rsp] + mov r14,QWORD PTR[8+rsp] + mov r13,QWORD PTR[16+rsp] + mov rbp,QWORD PTR[24+rsp] + mov rbx,QWORD PTR[32+rsp] + lea rsp,QWORD PTR[40+rsp] +$L$key_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_Camellia_Ekeygen:: +Camellia_Ekeygen ENDP +ALIGN 64 +$L$Camellia_SIGMA:: + DD 03bcc908bh,0a09e667fh,04caa73b2h,0b67ae858h + DD 0e94f82beh,0c6ef372fh,0f1d36f1ch,054ff53a5h + DD 0de682d1dh,010e527fah,0b3e6c1fdh,0b05688c2h + DD 0,0,0,0 +$L$Camellia_SBOX:: + DD 070707000h,070700070h + DD 082828200h,02c2c002ch + DD 02c2c2c00h,0b3b300b3h + DD 0ececec00h,0c0c000c0h + DD 0b3b3b300h,0e4e400e4h + DD 027272700h,057570057h + DD 0c0c0c000h,0eaea00eah + DD 0e5e5e500h,0aeae00aeh + DD 0e4e4e400h,023230023h + DD 085858500h,06b6b006bh + DD 057575700h,045450045h + DD 035353500h,0a5a500a5h + DD 0eaeaea00h,0eded00edh + DD 00c0c0c00h,04f4f004fh + DD 0aeaeae00h,01d1d001dh + DD 041414100h,092920092h + DD 023232300h,086860086h + DD 0efefef00h,0afaf00afh + DD 06b6b6b00h,07c7c007ch + DD 093939300h,01f1f001fh + DD 045454500h,03e3e003eh + DD 019191900h,0dcdc00dch + DD 0a5a5a500h,05e5e005eh + DD 021212100h,00b0b000bh + DD 0ededed00h,0a6a600a6h + DD 00e0e0e00h,039390039h + DD 04f4f4f00h,0d5d500d5h + DD 04e4e4e00h,05d5d005dh + DD 01d1d1d00h,0d9d900d9h + DD 065656500h,05a5a005ah + DD 092929200h,051510051h + DD 0bdbdbd00h,06c6c006ch + DD 086868600h,08b8b008bh + DD 0b8b8b800h,09a9a009ah + DD 0afafaf00h,0fbfb00fbh + DD 08f8f8f00h,0b0b000b0h + DD 07c7c7c00h,074740074h + DD 0ebebeb00h,02b2b002bh + DD 01f1f1f00h,0f0f000f0h + DD 0cecece00h,084840084h + DD 03e3e3e00h,0dfdf00dfh + DD 030303000h,0cbcb00cbh + DD 0dcdcdc00h,034340034h + DD 05f5f5f00h,076760076h + DD 05e5e5e00h,06d6d006dh + DD 0c5c5c500h,0a9a900a9h + DD 00b0b0b00h,0d1d100d1h + DD 01a1a1a00h,004040004h + DD 0a6a6a600h,014140014h + DD 0e1e1e100h,03a3a003ah + DD 039393900h,0dede00deh + DD 0cacaca00h,011110011h + DD 0d5d5d500h,032320032h + DD 047474700h,09c9c009ch + DD 05d5d5d00h,053530053h + DD 03d3d3d00h,0f2f200f2h + DD 0d9d9d900h,0fefe00feh + DD 001010100h,0cfcf00cfh + DD 05a5a5a00h,0c3c300c3h + DD 0d6d6d600h,07a7a007ah + DD 051515100h,024240024h + DD 056565600h,0e8e800e8h + DD 06c6c6c00h,060600060h + DD 04d4d4d00h,069690069h + DD 08b8b8b00h,0aaaa00aah + DD 00d0d0d00h,0a0a000a0h + DD 09a9a9a00h,0a1a100a1h + DD 066666600h,062620062h + DD 0fbfbfb00h,054540054h + DD 0cccccc00h,01e1e001eh + DD 0b0b0b000h,0e0e000e0h + DD 02d2d2d00h,064640064h + DD 074747400h,010100010h + DD 012121200h,000000000h + DD 02b2b2b00h,0a3a300a3h + DD 020202000h,075750075h + DD 0f0f0f000h,08a8a008ah + DD 0b1b1b100h,0e6e600e6h + DD 084848400h,009090009h + DD 099999900h,0dddd00ddh + DD 0dfdfdf00h,087870087h + DD 04c4c4c00h,083830083h + DD 0cbcbcb00h,0cdcd00cdh + DD 0c2c2c200h,090900090h + DD 034343400h,073730073h + DD 07e7e7e00h,0f6f600f6h + DD 076767600h,09d9d009dh + DD 005050500h,0bfbf00bfh + DD 06d6d6d00h,052520052h + DD 0b7b7b700h,0d8d800d8h + DD 0a9a9a900h,0c8c800c8h + DD 031313100h,0c6c600c6h + DD 0d1d1d100h,081810081h + DD 017171700h,06f6f006fh + DD 004040400h,013130013h + DD 0d7d7d700h,063630063h + DD 014141400h,0e9e900e9h + DD 058585800h,0a7a700a7h + DD 03a3a3a00h,09f9f009fh + DD 061616100h,0bcbc00bch + DD 0dedede00h,029290029h + DD 01b1b1b00h,0f9f900f9h + DD 011111100h,02f2f002fh + DD 01c1c1c00h,0b4b400b4h + DD 032323200h,078780078h + DD 00f0f0f00h,006060006h + DD 09c9c9c00h,0e7e700e7h + DD 016161600h,071710071h + DD 053535300h,0d4d400d4h + DD 018181800h,0abab00abh + DD 0f2f2f200h,088880088h + DD 022222200h,08d8d008dh + DD 0fefefe00h,072720072h + DD 044444400h,0b9b900b9h + DD 0cfcfcf00h,0f8f800f8h + DD 0b2b2b200h,0acac00ach + DD 0c3c3c300h,036360036h + DD 0b5b5b500h,02a2a002ah + DD 07a7a7a00h,03c3c003ch + DD 091919100h,0f1f100f1h + DD 024242400h,040400040h + DD 008080800h,0d3d300d3h + DD 0e8e8e800h,0bbbb00bbh + DD 0a8a8a800h,043430043h + DD 060606000h,015150015h + DD 0fcfcfc00h,0adad00adh + DD 069696900h,077770077h + DD 050505000h,080800080h + DD 0aaaaaa00h,082820082h + DD 0d0d0d000h,0ecec00ech + DD 0a0a0a000h,027270027h + DD 07d7d7d00h,0e5e500e5h + DD 0a1a1a100h,085850085h + DD 089898900h,035350035h + DD 062626200h,00c0c000ch + DD 097979700h,041410041h + DD 054545400h,0efef00efh + DD 05b5b5b00h,093930093h + DD 01e1e1e00h,019190019h + DD 095959500h,021210021h + DD 0e0e0e000h,00e0e000eh + DD 0ffffff00h,04e4e004eh + DD 064646400h,065650065h + DD 0d2d2d200h,0bdbd00bdh + DD 010101000h,0b8b800b8h + DD 0c4c4c400h,08f8f008fh + DD 000000000h,0ebeb00ebh + DD 048484800h,0cece00ceh + DD 0a3a3a300h,030300030h + DD 0f7f7f700h,05f5f005fh + DD 075757500h,0c5c500c5h + DD 0dbdbdb00h,01a1a001ah + DD 08a8a8a00h,0e1e100e1h + DD 003030300h,0caca00cah + DD 0e6e6e600h,047470047h + DD 0dadada00h,03d3d003dh + DD 009090900h,001010001h + DD 03f3f3f00h,0d6d600d6h + DD 0dddddd00h,056560056h + DD 094949400h,04d4d004dh + DD 087878700h,00d0d000dh + DD 05c5c5c00h,066660066h + DD 083838300h,0cccc00cch + DD 002020200h,02d2d002dh + DD 0cdcdcd00h,012120012h + DD 04a4a4a00h,020200020h + DD 090909000h,0b1b100b1h + DD 033333300h,099990099h + DD 073737300h,04c4c004ch + DD 067676700h,0c2c200c2h + DD 0f6f6f600h,07e7e007eh + DD 0f3f3f300h,005050005h + DD 09d9d9d00h,0b7b700b7h + DD 07f7f7f00h,031310031h + DD 0bfbfbf00h,017170017h + DD 0e2e2e200h,0d7d700d7h + DD 052525200h,058580058h + DD 09b9b9b00h,061610061h + DD 0d8d8d800h,01b1b001bh + DD 026262600h,01c1c001ch + DD 0c8c8c800h,00f0f000fh + DD 037373700h,016160016h + DD 0c6c6c600h,018180018h + DD 03b3b3b00h,022220022h + DD 081818100h,044440044h + DD 096969600h,0b2b200b2h + DD 06f6f6f00h,0b5b500b5h + DD 04b4b4b00h,091910091h + DD 013131300h,008080008h + DD 0bebebe00h,0a8a800a8h + DD 063636300h,0fcfc00fch + DD 02e2e2e00h,050500050h + DD 0e9e9e900h,0d0d000d0h + DD 079797900h,07d7d007dh + DD 0a7a7a700h,089890089h + DD 08c8c8c00h,097970097h + DD 09f9f9f00h,05b5b005bh + DD 06e6e6e00h,095950095h + DD 0bcbcbc00h,0ffff00ffh + DD 08e8e8e00h,0d2d200d2h + DD 029292900h,0c4c400c4h + DD 0f5f5f500h,048480048h + DD 0f9f9f900h,0f7f700f7h + DD 0b6b6b600h,0dbdb00dbh + DD 02f2f2f00h,003030003h + DD 0fdfdfd00h,0dada00dah + DD 0b4b4b400h,03f3f003fh + DD 059595900h,094940094h + DD 078787800h,05c5c005ch + DD 098989800h,002020002h + DD 006060600h,04a4a004ah + DD 06a6a6a00h,033330033h + DD 0e7e7e700h,067670067h + DD 046464600h,0f3f300f3h + DD 071717100h,07f7f007fh + DD 0bababa00h,0e2e200e2h + DD 0d4d4d400h,09b9b009bh + DD 025252500h,026260026h + DD 0ababab00h,037370037h + DD 042424200h,03b3b003bh + DD 088888800h,096960096h + DD 0a2a2a200h,04b4b004bh + DD 08d8d8d00h,0bebe00beh + DD 0fafafa00h,02e2e002eh + DD 072727200h,079790079h + DD 007070700h,08c8c008ch + DD 0b9b9b900h,06e6e006eh + DD 055555500h,08e8e008eh + DD 0f8f8f800h,0f5f500f5h + DD 0eeeeee00h,0b6b600b6h + DD 0acacac00h,0fdfd00fdh + DD 00a0a0a00h,059590059h + DD 036363600h,098980098h + DD 049494900h,06a6a006ah + DD 02a2a2a00h,046460046h + DD 068686800h,0baba00bah + DD 03c3c3c00h,025250025h + DD 038383800h,042420042h + DD 0f1f1f100h,0a2a200a2h + DD 0a4a4a400h,0fafa00fah + DD 040404000h,007070007h + DD 028282800h,055550055h + DD 0d3d3d300h,0eeee00eeh + DD 07b7b7b00h,00a0a000ah + DD 0bbbbbb00h,049490049h + DD 0c9c9c900h,068680068h + DD 043434300h,038380038h + DD 0c1c1c100h,0a4a400a4h + DD 015151500h,028280028h + DD 0e3e3e300h,07b7b007bh + DD 0adadad00h,0c9c900c9h + DD 0f4f4f400h,0c1c100c1h + DD 077777700h,0e3e300e3h + DD 0c7c7c700h,0f4f400f4h + DD 080808000h,0c7c700c7h + DD 09e9e9e00h,09e9e009eh + DD 000e0e0e0h,038003838h + DD 000050505h,041004141h + DD 000585858h,016001616h + DD 000d9d9d9h,076007676h + DD 000676767h,0d900d9d9h + DD 0004e4e4eh,093009393h + DD 000818181h,060006060h + DD 000cbcbcbh,0f200f2f2h + DD 000c9c9c9h,072007272h + DD 0000b0b0bh,0c200c2c2h + DD 000aeaeaeh,0ab00ababh + DD 0006a6a6ah,09a009a9ah + DD 000d5d5d5h,075007575h + DD 000181818h,006000606h + DD 0005d5d5dh,057005757h + DD 000828282h,0a000a0a0h + DD 000464646h,091009191h + DD 000dfdfdfh,0f700f7f7h + DD 000d6d6d6h,0b500b5b5h + DD 000272727h,0c900c9c9h + DD 0008a8a8ah,0a200a2a2h + DD 000323232h,08c008c8ch + DD 0004b4b4bh,0d200d2d2h + DD 000424242h,090009090h + DD 000dbdbdbh,0f600f6f6h + DD 0001c1c1ch,007000707h + DD 0009e9e9eh,0a700a7a7h + DD 0009c9c9ch,027002727h + DD 0003a3a3ah,08e008e8eh + DD 000cacacah,0b200b2b2h + DD 000252525h,049004949h + DD 0007b7b7bh,0de00dedeh + DD 0000d0d0dh,043004343h + DD 000717171h,05c005c5ch + DD 0005f5f5fh,0d700d7d7h + DD 0001f1f1fh,0c700c7c7h + DD 000f8f8f8h,03e003e3eh + DD 000d7d7d7h,0f500f5f5h + DD 0003e3e3eh,08f008f8fh + DD 0009d9d9dh,067006767h + DD 0007c7c7ch,01f001f1fh + DD 000606060h,018001818h + DD 000b9b9b9h,06e006e6eh + DD 000bebebeh,0af00afafh + DD 000bcbcbch,02f002f2fh + DD 0008b8b8bh,0e200e2e2h + DD 000161616h,085008585h + DD 000343434h,00d000d0dh + DD 0004d4d4dh,053005353h + DD 000c3c3c3h,0f000f0f0h + DD 000727272h,09c009c9ch + DD 000959595h,065006565h + DD 000abababh,0ea00eaeah + DD 0008e8e8eh,0a300a3a3h + DD 000bababah,0ae00aeaeh + DD 0007a7a7ah,09e009e9eh + DD 000b3b3b3h,0ec00ecech + DD 000020202h,080008080h + DD 000b4b4b4h,02d002d2dh + DD 000adadadh,06b006b6bh + DD 000a2a2a2h,0a800a8a8h + DD 000acacach,02b002b2bh + DD 000d8d8d8h,036003636h + DD 0009a9a9ah,0a600a6a6h + DD 000171717h,0c500c5c5h + DD 0001a1a1ah,086008686h + DD 000353535h,04d004d4dh + DD 000cccccch,033003333h + DD 000f7f7f7h,0fd00fdfdh + DD 000999999h,066006666h + DD 000616161h,058005858h + DD 0005a5a5ah,096009696h + DD 000e8e8e8h,03a003a3ah + DD 000242424h,009000909h + DD 000565656h,095009595h + DD 000404040h,010001010h + DD 000e1e1e1h,078007878h + DD 000636363h,0d800d8d8h + DD 000090909h,042004242h + DD 000333333h,0cc00cccch + DD 000bfbfbfh,0ef00efefh + DD 000989898h,026002626h + DD 000979797h,0e500e5e5h + DD 000858585h,061006161h + DD 000686868h,01a001a1ah + DD 000fcfcfch,03f003f3fh + DD 000ececech,03b003b3bh + DD 0000a0a0ah,082008282h + DD 000dadadah,0b600b6b6h + DD 0006f6f6fh,0db00dbdbh + DD 000535353h,0d400d4d4h + DD 000626262h,098009898h + DD 000a3a3a3h,0e800e8e8h + DD 0002e2e2eh,08b008b8bh + DD 000080808h,002000202h + DD 000afafafh,0eb00ebebh + DD 000282828h,00a000a0ah + DD 000b0b0b0h,02c002c2ch + DD 000747474h,01d001d1dh + DD 000c2c2c2h,0b000b0b0h + DD 000bdbdbdh,06f006f6fh + DD 000363636h,08d008d8dh + DD 000222222h,088008888h + DD 000383838h,00e000e0eh + DD 000646464h,019001919h + DD 0001e1e1eh,087008787h + DD 000393939h,04e004e4eh + DD 0002c2c2ch,00b000b0bh + DD 000a6a6a6h,0a900a9a9h + DD 000303030h,00c000c0ch + DD 000e5e5e5h,079007979h + DD 000444444h,011001111h + DD 000fdfdfdh,07f007f7fh + DD 000888888h,022002222h + DD 0009f9f9fh,0e700e7e7h + DD 000656565h,059005959h + DD 000878787h,0e100e1e1h + DD 0006b6b6bh,0da00dadah + DD 000f4f4f4h,03d003d3dh + DD 000232323h,0c800c8c8h + DD 000484848h,012001212h + DD 000101010h,004000404h + DD 000d1d1d1h,074007474h + DD 000515151h,054005454h + DD 000c0c0c0h,030003030h + DD 000f9f9f9h,07e007e7eh + DD 000d2d2d2h,0b400b4b4h + DD 000a0a0a0h,028002828h + DD 000555555h,055005555h + DD 000a1a1a1h,068006868h + DD 000414141h,050005050h + DD 000fafafah,0be00bebeh + DD 000434343h,0d000d0d0h + DD 000131313h,0c400c4c4h + DD 000c4c4c4h,031003131h + DD 0002f2f2fh,0cb00cbcbh + DD 000a8a8a8h,02a002a2ah + DD 000b6b6b6h,0ad00adadh + DD 0003c3c3ch,00f000f0fh + DD 0002b2b2bh,0ca00cacah + DD 000c1c1c1h,070007070h + DD 000ffffffh,0ff00ffffh + DD 000c8c8c8h,032003232h + DD 000a5a5a5h,069006969h + DD 000202020h,008000808h + DD 000898989h,062006262h + DD 000000000h,000000000h + DD 000909090h,024002424h + DD 000474747h,0d100d1d1h + DD 000efefefh,0fb00fbfbh + DD 000eaeaeah,0ba00babah + DD 000b7b7b7h,0ed00ededh + DD 000151515h,045004545h + DD 000060606h,081008181h + DD 000cdcdcdh,073007373h + DD 000b5b5b5h,06d006d6dh + DD 000121212h,084008484h + DD 0007e7e7eh,09f009f9fh + DD 000bbbbbbh,0ee00eeeeh + DD 000292929h,04a004a4ah + DD 0000f0f0fh,0c300c3c3h + DD 000b8b8b8h,02e002e2eh + DD 000070707h,0c100c1c1h + DD 000040404h,001000101h + DD 0009b9b9bh,0e600e6e6h + DD 000949494h,025002525h + DD 000212121h,048004848h + DD 000666666h,099009999h + DD 000e6e6e6h,0b900b9b9h + DD 000cececeh,0b300b3b3h + DD 000edededh,07b007b7bh + DD 000e7e7e7h,0f900f9f9h + DD 0003b3b3bh,0ce00ceceh + DD 000fefefeh,0bf00bfbfh + DD 0007f7f7fh,0df00dfdfh + DD 000c5c5c5h,071007171h + DD 000a4a4a4h,029002929h + DD 000373737h,0cd00cdcdh + DD 000b1b1b1h,06c006c6ch + DD 0004c4c4ch,013001313h + DD 000919191h,064006464h + DD 0006e6e6eh,09b009b9bh + DD 0008d8d8dh,063006363h + DD 000767676h,09d009d9dh + DD 000030303h,0c000c0c0h + DD 0002d2d2dh,04b004b4bh + DD 000dededeh,0b700b7b7h + DD 000969696h,0a500a5a5h + DD 000262626h,089008989h + DD 0007d7d7dh,05f005f5fh + DD 000c6c6c6h,0b100b1b1h + DD 0005c5c5ch,017001717h + DD 000d3d3d3h,0f400f4f4h + DD 000f2f2f2h,0bc00bcbch + DD 0004f4f4fh,0d300d3d3h + DD 000191919h,046004646h + DD 0003f3f3fh,0cf00cfcfh + DD 000dcdcdch,037003737h + DD 000797979h,05e005e5eh + DD 0001d1d1dh,047004747h + DD 000525252h,094009494h + DD 000ebebebh,0fa00fafah + DD 000f3f3f3h,0fc00fcfch + DD 0006d6d6dh,05b005b5bh + DD 0005e5e5eh,097009797h + DD 000fbfbfbh,0fe00fefeh + DD 000696969h,05a005a5ah + DD 000b2b2b2h,0ac00acach + DD 000f0f0f0h,03c003c3ch + DD 000313131h,04c004c4ch + DD 0000c0c0ch,003000303h + DD 000d4d4d4h,035003535h + DD 000cfcfcfh,0f300f3f3h + DD 0008c8c8ch,023002323h + DD 000e2e2e2h,0b800b8b8h + DD 000757575h,05d005d5dh + DD 000a9a9a9h,06a006a6ah + DD 0004a4a4ah,092009292h + DD 000575757h,0d500d5d5h + DD 000848484h,021002121h + DD 000111111h,044004444h + DD 000454545h,051005151h + DD 0001b1b1bh,0c600c6c6h + DD 000f5f5f5h,07d007d7dh + DD 000e4e4e4h,039003939h + DD 0000e0e0eh,083008383h + DD 000737373h,0dc00dcdch + DD 000aaaaaah,0aa00aaaah + DD 000f1f1f1h,07c007c7ch + DD 000ddddddh,077007777h + DD 000595959h,056005656h + DD 000141414h,005000505h + DD 0006c6c6ch,01b001b1bh + DD 000929292h,0a400a4a4h + DD 000545454h,015001515h + DD 000d0d0d0h,034003434h + DD 000787878h,01e001e1eh + DD 000707070h,01c001c1ch + DD 000e3e3e3h,0f800f8f8h + DD 000494949h,052005252h + DD 000808080h,020002020h + DD 000505050h,014001414h + DD 000a7a7a7h,0e900e9e9h + DD 000f6f6f6h,0bd00bdbdh + DD 000777777h,0dd00ddddh + DD 000939393h,0e400e4e4h + DD 000868686h,0a100a1a1h + DD 000838383h,0e000e0e0h + DD 0002a2a2ah,08a008a8ah + DD 000c7c7c7h,0f100f1f1h + DD 0005b5b5bh,0d600d6d6h + DD 000e9e9e9h,07a007a7ah + DD 000eeeeeeh,0bb00bbbbh + DD 0008f8f8fh,0e300e3e3h + DD 000010101h,040004040h + DD 0003d3d3dh,04f004f4fh +PUBLIC Camellia_cbc_encrypt + +ALIGN 16 +Camellia_cbc_encrypt PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_Camellia_cbc_encrypt:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + + cmp rdx,0 + je $L$cbc_abort + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 +$L$cbc_prologue:: + + mov rbp,rsp + sub rsp,64 + and rsp,-64 + + + + lea r10,QWORD PTR[((-64-63))+rcx] + sub r10,rsp + neg r10 + and r10,03C0h + sub rsp,r10 + + + mov r12,rdi + mov r13,rsi + mov rbx,r8 + mov r14,rcx + mov r15d,DWORD PTR[272+rcx] + + mov QWORD PTR[40+rsp],r8 + mov QWORD PTR[48+rsp],rbp + +$L$cbc_body:: + lea rbp,QWORD PTR[$L$Camellia_SBOX] + + mov ecx,32 +ALIGN 4 +$L$cbc_prefetch_sbox:: + mov rax,QWORD PTR[rbp] + mov rsi,QWORD PTR[32+rbp] + mov rdi,QWORD PTR[64+rbp] + mov r11,QWORD PTR[96+rbp] + lea rbp,QWORD PTR[128+rbp] + loop $L$cbc_prefetch_sbox + sub rbp,4096 + shl r15,6 + mov rcx,rdx + lea r15,QWORD PTR[r15*1+r14] + + cmp r9d,0 + je $L$CBC_DECRYPT + + and rdx,-16 + and rcx,15 + lea rdx,QWORD PTR[rdx*1+r12] + mov QWORD PTR[rsp],r14 + mov QWORD PTR[8+rsp],rdx + mov QWORD PTR[16+rsp],rcx + + cmp rdx,r12 + mov r8d,DWORD PTR[rbx] + mov r9d,DWORD PTR[4+rbx] + mov r10d,DWORD PTR[8+rbx] + mov r11d,DWORD PTR[12+rbx] + je $L$cbc_enc_tail + jmp $L$cbc_eloop + +ALIGN 16 +$L$cbc_eloop:: + xor r8d,DWORD PTR[r12] + xor r9d,DWORD PTR[4+r12] + xor r10d,DWORD PTR[8+r12] + bswap r8d + xor r11d,DWORD PTR[12+r12] + bswap r9d + bswap r10d + bswap r11d + + call _x86_64_Camellia_encrypt + + mov r14,QWORD PTR[rsp] + bswap r8d + mov rdx,QWORD PTR[8+rsp] + bswap r9d + mov rcx,QWORD PTR[16+rsp] + bswap r10d + mov DWORD PTR[r13],r8d + bswap r11d + mov DWORD PTR[4+r13],r9d + mov DWORD PTR[8+r13],r10d + lea r12,QWORD PTR[16+r12] + mov DWORD PTR[12+r13],r11d + cmp r12,rdx + lea r13,QWORD PTR[16+r13] + jne $L$cbc_eloop + + cmp rcx,0 + jne $L$cbc_enc_tail + + mov r13,QWORD PTR[40+rsp] + mov DWORD PTR[r13],r8d + mov DWORD PTR[4+r13],r9d + mov DWORD PTR[8+r13],r10d + mov DWORD PTR[12+r13],r11d + jmp $L$cbc_done + +ALIGN 16 +$L$cbc_enc_tail:: + xor rax,rax + mov QWORD PTR[((0+24))+rsp],rax + mov QWORD PTR[((8+24))+rsp],rax + mov QWORD PTR[16+rsp],rax + +$L$cbc_enc_pushf:: + pushfq + cld + mov rsi,r12 + lea rdi,QWORD PTR[((8+24))+rsp] + DD 09066A4F3h + popfq +$L$cbc_enc_popf:: + + lea r12,QWORD PTR[24+rsp] + lea rax,QWORD PTR[((16+24))+rsp] + mov QWORD PTR[8+rsp],rax + jmp $L$cbc_eloop + +ALIGN 16 +$L$CBC_DECRYPT:: + xchg r15,r14 + add rdx,15 + and rcx,15 + and rdx,-16 + mov QWORD PTR[rsp],r14 + lea rdx,QWORD PTR[rdx*1+r12] + mov QWORD PTR[8+rsp],rdx + mov QWORD PTR[16+rsp],rcx + + mov rax,QWORD PTR[rbx] + mov rbx,QWORD PTR[8+rbx] + jmp $L$cbc_dloop +ALIGN 16 +$L$cbc_dloop:: + mov r8d,DWORD PTR[r12] + mov r9d,DWORD PTR[4+r12] + mov r10d,DWORD PTR[8+r12] + bswap r8d + mov r11d,DWORD PTR[12+r12] + bswap r9d + mov QWORD PTR[((0+24))+rsp],rax + bswap r10d + mov QWORD PTR[((8+24))+rsp],rbx + bswap r11d + + call _x86_64_Camellia_decrypt + + mov r14,QWORD PTR[rsp] + mov rdx,QWORD PTR[8+rsp] + mov rcx,QWORD PTR[16+rsp] + + bswap r8d + mov rax,QWORD PTR[r12] + bswap r9d + mov rbx,QWORD PTR[8+r12] + bswap r10d + xor r8d,DWORD PTR[((0+24))+rsp] + bswap r11d + xor r9d,DWORD PTR[((4+24))+rsp] + xor r10d,DWORD PTR[((8+24))+rsp] + lea r12,QWORD PTR[16+r12] + xor r11d,DWORD PTR[((12+24))+rsp] + cmp r12,rdx + je $L$cbc_ddone + + mov DWORD PTR[r13],r8d + mov DWORD PTR[4+r13],r9d + mov DWORD PTR[8+r13],r10d + mov DWORD PTR[12+r13],r11d + + lea r13,QWORD PTR[16+r13] + jmp $L$cbc_dloop + +ALIGN 16 +$L$cbc_ddone:: + mov rdx,QWORD PTR[40+rsp] + cmp rcx,0 + jne $L$cbc_dec_tail + + mov DWORD PTR[r13],r8d + mov DWORD PTR[4+r13],r9d + mov DWORD PTR[8+r13],r10d + mov DWORD PTR[12+r13],r11d + + mov QWORD PTR[rdx],rax + mov QWORD PTR[8+rdx],rbx + jmp $L$cbc_done +ALIGN 16 +$L$cbc_dec_tail:: + mov DWORD PTR[((0+24))+rsp],r8d + mov DWORD PTR[((4+24))+rsp],r9d + mov DWORD PTR[((8+24))+rsp],r10d + mov DWORD PTR[((12+24))+rsp],r11d + +$L$cbc_dec_pushf:: + pushfq + cld + lea rsi,QWORD PTR[((8+24))+rsp] + lea rdi,QWORD PTR[r13] + DD 09066A4F3h + popfq +$L$cbc_dec_popf:: + + mov QWORD PTR[rdx],rax + mov QWORD PTR[8+rdx],rbx + jmp $L$cbc_done + +ALIGN 16 +$L$cbc_done:: + mov rcx,QWORD PTR[48+rsp] + mov r15,QWORD PTR[rcx] + mov r14,QWORD PTR[8+rcx] + mov r13,QWORD PTR[16+rcx] + mov r12,QWORD PTR[24+rcx] + mov rbp,QWORD PTR[32+rcx] + mov rbx,QWORD PTR[40+rcx] + lea rsp,QWORD PTR[48+rcx] +$L$cbc_abort:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_Camellia_cbc_encrypt:: +Camellia_cbc_encrypt ENDP + +DB 67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54 +DB 95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112 +DB 101,110,115,115,108,46,111,114,103,62,0 + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/camellia/cmll-mingw64-x86_64.S b/Libraries/libressl/crypto/camellia/cmll-mingw64-x86_64.S new file mode 100644 index 000000000..75966f43b --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll-mingw64-x86_64.S @@ -0,0 +1,1884 @@ +#include "x86_arch.h" +.text + + +.globl Camellia_EncryptBlock +.def Camellia_EncryptBlock; .scl 2; .type 32; .endef +.p2align 4 +Camellia_EncryptBlock: + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp .Lenc_rounds + + +.globl Camellia_EncryptBlock_Rounds +.def Camellia_EncryptBlock_Rounds; .scl 2; .type 32; .endef +.p2align 4 +.Lenc_rounds: +Camellia_EncryptBlock_Rounds: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_Camellia_EncryptBlock_Rounds: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +.Lenc_prologue: + + + movq %rcx,%r13 + movq %rdx,%r14 + + shll $6,%edi + leaq .LCamellia_SBOX(%rip),%rbp + leaq (%r14,%rdi,1),%r15 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +.Lenc_epilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_Camellia_EncryptBlock_Rounds: + +.def _x86_64_Camellia_encrypt; .scl 3; .type 32; .endef +.p2align 4 +_x86_64_Camellia_encrypt: + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.p2align 4 +.Leloop: + movl 16(%r14),%ebx + movl 20(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 56(%r14),%ebx + movl 60(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 64(%r14),%ebx + movl 68(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq 64(%r14),%r14 + cmpq %r15,%r14 + movl 8(%r14),%edx + movl 12(%r14),%ecx + je .Ledone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + jmp .Leloop + +.p2align 4 +.Ledone: + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r8d,%ecx + xorl %r9d,%edx + + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r10d + movl %edx,%r11d + + retq + + + +.globl Camellia_DecryptBlock +.def Camellia_DecryptBlock; .scl 2; .type 32; .endef +.p2align 4 +Camellia_DecryptBlock: + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp .Ldec_rounds + + +.globl Camellia_DecryptBlock_Rounds +.def Camellia_DecryptBlock_Rounds; .scl 2; .type 32; .endef +.p2align 4 +.Ldec_rounds: +Camellia_DecryptBlock_Rounds: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_Camellia_DecryptBlock_Rounds: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +.Ldec_prologue: + + + movq %rcx,%r13 + movq %rdx,%r15 + + shll $6,%edi + leaq .LCamellia_SBOX(%rip),%rbp + leaq (%r15,%rdi,1),%r14 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_decrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +.Ldec_epilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_Camellia_DecryptBlock_Rounds: + +.def _x86_64_Camellia_decrypt; .scl 3; .type 32; .endef +.p2align 4 +_x86_64_Camellia_decrypt: + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.p2align 4 +.Ldloop: + movl -8(%r14),%ebx + movl -4(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -16(%r14),%ebx + movl -12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -24(%r14),%ebx + movl -20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -32(%r14),%ebx + movl -28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -40(%r14),%ebx + movl -36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -48(%r14),%ebx + movl -44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -56(%r14),%ebx + movl -52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq -64(%r14),%r14 + cmpq %r15,%r14 + movl 0(%r14),%edx + movl 4(%r14),%ecx + je .Lddone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + + jmp .Ldloop + +.p2align 4 +.Lddone: + xorl %r10d,%ecx + xorl %r11d,%edx + xorl %r8d,%eax + xorl %r9d,%ebx + + movl %ecx,%r8d + movl %edx,%r9d + movl %eax,%r10d + movl %ebx,%r11d + + retq + +.globl Camellia_Ekeygen +.def Camellia_Ekeygen; .scl 2; .type 32; .endef +.p2align 4 +Camellia_Ekeygen: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_Camellia_Ekeygen: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + + pushq %rbx + pushq %rbp + pushq %r13 + pushq %r14 + pushq %r15 +.Lkey_prologue: + + movq %rdi,%r15 + movq %rdx,%r13 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + movl 12(%rsi),%r11d + + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,0(%r13) + movl %r8d,4(%r13) + movl %r11d,8(%r13) + movl %r10d,12(%r13) + cmpq $128,%r15 + je .L1st128 + + movl 16(%rsi),%r8d + movl 20(%rsi),%r9d + cmpq $192,%r15 + je .L1st192 + movl 24(%rsi),%r10d + movl 28(%rsi),%r11d + jmp .L1st256 +.L1st192: + movl %r8d,%r10d + movl %r9d,%r11d + notl %r10d + notl %r11d +.L1st256: + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,32(%r13) + movl %r8d,36(%r13) + movl %r11d,40(%r13) + movl %r10d,44(%r13) + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + +.L1st128: + leaq .LCamellia_SIGMA(%rip),%r14 + leaq .LCamellia_SBOX(%rip),%rbp + + movl 0(%r14),%ebx + movl 4(%r14),%eax + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 8(%r14),%ebx + movl 12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 16(%r14),%ebx + movl 20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + cmpq $128,%r15 + jne .L2nd256 + + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq -128(%r13),%rax + movq -120(%r13),%rbx + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,-96(%r13) + movq %rbx,-88(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-80(%r13) + movq %r10,-72(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-64(%r13) + movq %r10,-56(%r13) + movq %rax,%r11 + shlq $30,%rax + movq %rbx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rax + shlq $30,%rbx + orq %r11,%rbx + movq %rax,-48(%r13) + movq %rbx,-40(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-32(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rbx,-24(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-16(%r13) + movq %r10,-8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,16(%r13) + movq %rbx,24(%r13) + movq %r8,%r11 + shlq $34,%r8 + movq %r10,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%r8 + shlq $34,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r8,%r11 + shlq $17,%r8 + movq %r10,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r8 + shlq $17,%r10 + orq %r11,%r10 + movq %r8,64(%r13) + movq %r10,72(%r13) + movl $3,%eax + jmp .Ldone +.p2align 4 +.L2nd256: + movl %r9d,48(%r13) + movl %r8d,52(%r13) + movl %r11d,56(%r13) + movl %r10d,60(%r13) + xorl 32(%r13),%r9d + xorl 36(%r13),%r8d + xorl 40(%r13),%r11d + xorl 44(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + movq 0(%r13),%rax + movq 8(%r13),%rbx + movq 32(%r13),%rcx + movq 40(%r13),%rdx + movq 48(%r13),%r14 + movq 56(%r13),%r15 + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-96(%r13) + movq %rdx,-88(%r13) + movq %r14,%r11 + shlq $15,%r14 + movq %r15,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r14 + shlq $15,%r15 + orq %r11,%r15 + movq %r14,-80(%r13) + movq %r15,-72(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-64(%r13) + movq %rdx,-56(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,-48(%r13) + movq %r10,-40(%r13) + movq %rax,%r11 + shlq $45,%rax + movq %rbx,%r9 + shrq $19,%r9 + shrq $19,%r11 + orq %r9,%rax + shlq $45,%rbx + orq %r11,%rbx + movq %rax,-32(%r13) + movq %rbx,-24(%r13) + movq %r14,%r11 + shlq $30,%r14 + movq %r15,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r14 + shlq $30,%r15 + orq %r11,%r15 + movq %r14,-16(%r13) + movq %r15,-8(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rcx,%r11 + shlq $30,%rcx + movq %rdx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rcx + shlq $30,%rdx + orq %r11,%rdx + movq %rcx,16(%r13) + movq %rdx,24(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r14,%r11 + shlq $32,%r14 + movq %r15,%r9 + shrq $32,%r9 + shrq $32,%r11 + orq %r9,%r14 + shlq $32,%r15 + orq %r11,%r15 + movq %r14,64(%r13) + movq %r15,72(%r13) + movq %rcx,%r11 + shlq $34,%rcx + movq %rdx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rcx + shlq $34,%rdx + orq %r11,%rdx + movq %rcx,80(%r13) + movq %rdx,88(%r13) + movq %r14,%r11 + shlq $17,%r14 + movq %r15,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r14 + shlq $17,%r15 + orq %r11,%r15 + movq %r14,96(%r13) + movq %r15,104(%r13) + movq %rax,%r11 + shlq $34,%rax + movq %rbx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rax + shlq $34,%rbx + orq %r11,%rbx + movq %rax,112(%r13) + movq %rbx,120(%r13) + movq %r8,%r11 + shlq $51,%r8 + movq %r10,%r9 + shrq $13,%r9 + shrq $13,%r11 + orq %r9,%r8 + shlq $51,%r10 + orq %r11,%r10 + movq %r8,128(%r13) + movq %r10,136(%r13) + movl $4,%eax +.Ldone: + movq 0(%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r13 + movq 24(%rsp),%rbp + movq 32(%rsp),%rbx + leaq 40(%rsp),%rsp +.Lkey_epilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_Camellia_Ekeygen: +.p2align 6 +.LCamellia_SIGMA: +.long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858 +.long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5 +.long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2 +.long 0, 0, 0, 0 +.LCamellia_SBOX: +.long 0x70707000,0x70700070 +.long 0x82828200,0x2c2c002c +.long 0x2c2c2c00,0xb3b300b3 +.long 0xececec00,0xc0c000c0 +.long 0xb3b3b300,0xe4e400e4 +.long 0x27272700,0x57570057 +.long 0xc0c0c000,0xeaea00ea +.long 0xe5e5e500,0xaeae00ae +.long 0xe4e4e400,0x23230023 +.long 0x85858500,0x6b6b006b +.long 0x57575700,0x45450045 +.long 0x35353500,0xa5a500a5 +.long 0xeaeaea00,0xeded00ed +.long 0x0c0c0c00,0x4f4f004f +.long 0xaeaeae00,0x1d1d001d +.long 0x41414100,0x92920092 +.long 0x23232300,0x86860086 +.long 0xefefef00,0xafaf00af +.long 0x6b6b6b00,0x7c7c007c +.long 0x93939300,0x1f1f001f +.long 0x45454500,0x3e3e003e +.long 0x19191900,0xdcdc00dc +.long 0xa5a5a500,0x5e5e005e +.long 0x21212100,0x0b0b000b +.long 0xededed00,0xa6a600a6 +.long 0x0e0e0e00,0x39390039 +.long 0x4f4f4f00,0xd5d500d5 +.long 0x4e4e4e00,0x5d5d005d +.long 0x1d1d1d00,0xd9d900d9 +.long 0x65656500,0x5a5a005a +.long 0x92929200,0x51510051 +.long 0xbdbdbd00,0x6c6c006c +.long 0x86868600,0x8b8b008b +.long 0xb8b8b800,0x9a9a009a +.long 0xafafaf00,0xfbfb00fb +.long 0x8f8f8f00,0xb0b000b0 +.long 0x7c7c7c00,0x74740074 +.long 0xebebeb00,0x2b2b002b +.long 0x1f1f1f00,0xf0f000f0 +.long 0xcecece00,0x84840084 +.long 0x3e3e3e00,0xdfdf00df +.long 0x30303000,0xcbcb00cb +.long 0xdcdcdc00,0x34340034 +.long 0x5f5f5f00,0x76760076 +.long 0x5e5e5e00,0x6d6d006d +.long 0xc5c5c500,0xa9a900a9 +.long 0x0b0b0b00,0xd1d100d1 +.long 0x1a1a1a00,0x04040004 +.long 0xa6a6a600,0x14140014 +.long 0xe1e1e100,0x3a3a003a +.long 0x39393900,0xdede00de +.long 0xcacaca00,0x11110011 +.long 0xd5d5d500,0x32320032 +.long 0x47474700,0x9c9c009c +.long 0x5d5d5d00,0x53530053 +.long 0x3d3d3d00,0xf2f200f2 +.long 0xd9d9d900,0xfefe00fe +.long 0x01010100,0xcfcf00cf +.long 0x5a5a5a00,0xc3c300c3 +.long 0xd6d6d600,0x7a7a007a +.long 0x51515100,0x24240024 +.long 0x56565600,0xe8e800e8 +.long 0x6c6c6c00,0x60600060 +.long 0x4d4d4d00,0x69690069 +.long 0x8b8b8b00,0xaaaa00aa +.long 0x0d0d0d00,0xa0a000a0 +.long 0x9a9a9a00,0xa1a100a1 +.long 0x66666600,0x62620062 +.long 0xfbfbfb00,0x54540054 +.long 0xcccccc00,0x1e1e001e +.long 0xb0b0b000,0xe0e000e0 +.long 0x2d2d2d00,0x64640064 +.long 0x74747400,0x10100010 +.long 0x12121200,0x00000000 +.long 0x2b2b2b00,0xa3a300a3 +.long 0x20202000,0x75750075 +.long 0xf0f0f000,0x8a8a008a +.long 0xb1b1b100,0xe6e600e6 +.long 0x84848400,0x09090009 +.long 0x99999900,0xdddd00dd +.long 0xdfdfdf00,0x87870087 +.long 0x4c4c4c00,0x83830083 +.long 0xcbcbcb00,0xcdcd00cd +.long 0xc2c2c200,0x90900090 +.long 0x34343400,0x73730073 +.long 0x7e7e7e00,0xf6f600f6 +.long 0x76767600,0x9d9d009d +.long 0x05050500,0xbfbf00bf +.long 0x6d6d6d00,0x52520052 +.long 0xb7b7b700,0xd8d800d8 +.long 0xa9a9a900,0xc8c800c8 +.long 0x31313100,0xc6c600c6 +.long 0xd1d1d100,0x81810081 +.long 0x17171700,0x6f6f006f +.long 0x04040400,0x13130013 +.long 0xd7d7d700,0x63630063 +.long 0x14141400,0xe9e900e9 +.long 0x58585800,0xa7a700a7 +.long 0x3a3a3a00,0x9f9f009f +.long 0x61616100,0xbcbc00bc +.long 0xdedede00,0x29290029 +.long 0x1b1b1b00,0xf9f900f9 +.long 0x11111100,0x2f2f002f +.long 0x1c1c1c00,0xb4b400b4 +.long 0x32323200,0x78780078 +.long 0x0f0f0f00,0x06060006 +.long 0x9c9c9c00,0xe7e700e7 +.long 0x16161600,0x71710071 +.long 0x53535300,0xd4d400d4 +.long 0x18181800,0xabab00ab +.long 0xf2f2f200,0x88880088 +.long 0x22222200,0x8d8d008d +.long 0xfefefe00,0x72720072 +.long 0x44444400,0xb9b900b9 +.long 0xcfcfcf00,0xf8f800f8 +.long 0xb2b2b200,0xacac00ac +.long 0xc3c3c300,0x36360036 +.long 0xb5b5b500,0x2a2a002a +.long 0x7a7a7a00,0x3c3c003c +.long 0x91919100,0xf1f100f1 +.long 0x24242400,0x40400040 +.long 0x08080800,0xd3d300d3 +.long 0xe8e8e800,0xbbbb00bb +.long 0xa8a8a800,0x43430043 +.long 0x60606000,0x15150015 +.long 0xfcfcfc00,0xadad00ad +.long 0x69696900,0x77770077 +.long 0x50505000,0x80800080 +.long 0xaaaaaa00,0x82820082 +.long 0xd0d0d000,0xecec00ec +.long 0xa0a0a000,0x27270027 +.long 0x7d7d7d00,0xe5e500e5 +.long 0xa1a1a100,0x85850085 +.long 0x89898900,0x35350035 +.long 0x62626200,0x0c0c000c +.long 0x97979700,0x41410041 +.long 0x54545400,0xefef00ef +.long 0x5b5b5b00,0x93930093 +.long 0x1e1e1e00,0x19190019 +.long 0x95959500,0x21210021 +.long 0xe0e0e000,0x0e0e000e +.long 0xffffff00,0x4e4e004e +.long 0x64646400,0x65650065 +.long 0xd2d2d200,0xbdbd00bd +.long 0x10101000,0xb8b800b8 +.long 0xc4c4c400,0x8f8f008f +.long 0x00000000,0xebeb00eb +.long 0x48484800,0xcece00ce +.long 0xa3a3a300,0x30300030 +.long 0xf7f7f700,0x5f5f005f +.long 0x75757500,0xc5c500c5 +.long 0xdbdbdb00,0x1a1a001a +.long 0x8a8a8a00,0xe1e100e1 +.long 0x03030300,0xcaca00ca +.long 0xe6e6e600,0x47470047 +.long 0xdadada00,0x3d3d003d +.long 0x09090900,0x01010001 +.long 0x3f3f3f00,0xd6d600d6 +.long 0xdddddd00,0x56560056 +.long 0x94949400,0x4d4d004d +.long 0x87878700,0x0d0d000d +.long 0x5c5c5c00,0x66660066 +.long 0x83838300,0xcccc00cc +.long 0x02020200,0x2d2d002d +.long 0xcdcdcd00,0x12120012 +.long 0x4a4a4a00,0x20200020 +.long 0x90909000,0xb1b100b1 +.long 0x33333300,0x99990099 +.long 0x73737300,0x4c4c004c +.long 0x67676700,0xc2c200c2 +.long 0xf6f6f600,0x7e7e007e +.long 0xf3f3f300,0x05050005 +.long 0x9d9d9d00,0xb7b700b7 +.long 0x7f7f7f00,0x31310031 +.long 0xbfbfbf00,0x17170017 +.long 0xe2e2e200,0xd7d700d7 +.long 0x52525200,0x58580058 +.long 0x9b9b9b00,0x61610061 +.long 0xd8d8d800,0x1b1b001b +.long 0x26262600,0x1c1c001c +.long 0xc8c8c800,0x0f0f000f +.long 0x37373700,0x16160016 +.long 0xc6c6c600,0x18180018 +.long 0x3b3b3b00,0x22220022 +.long 0x81818100,0x44440044 +.long 0x96969600,0xb2b200b2 +.long 0x6f6f6f00,0xb5b500b5 +.long 0x4b4b4b00,0x91910091 +.long 0x13131300,0x08080008 +.long 0xbebebe00,0xa8a800a8 +.long 0x63636300,0xfcfc00fc +.long 0x2e2e2e00,0x50500050 +.long 0xe9e9e900,0xd0d000d0 +.long 0x79797900,0x7d7d007d +.long 0xa7a7a700,0x89890089 +.long 0x8c8c8c00,0x97970097 +.long 0x9f9f9f00,0x5b5b005b +.long 0x6e6e6e00,0x95950095 +.long 0xbcbcbc00,0xffff00ff +.long 0x8e8e8e00,0xd2d200d2 +.long 0x29292900,0xc4c400c4 +.long 0xf5f5f500,0x48480048 +.long 0xf9f9f900,0xf7f700f7 +.long 0xb6b6b600,0xdbdb00db +.long 0x2f2f2f00,0x03030003 +.long 0xfdfdfd00,0xdada00da +.long 0xb4b4b400,0x3f3f003f +.long 0x59595900,0x94940094 +.long 0x78787800,0x5c5c005c +.long 0x98989800,0x02020002 +.long 0x06060600,0x4a4a004a +.long 0x6a6a6a00,0x33330033 +.long 0xe7e7e700,0x67670067 +.long 0x46464600,0xf3f300f3 +.long 0x71717100,0x7f7f007f +.long 0xbababa00,0xe2e200e2 +.long 0xd4d4d400,0x9b9b009b +.long 0x25252500,0x26260026 +.long 0xababab00,0x37370037 +.long 0x42424200,0x3b3b003b +.long 0x88888800,0x96960096 +.long 0xa2a2a200,0x4b4b004b +.long 0x8d8d8d00,0xbebe00be +.long 0xfafafa00,0x2e2e002e +.long 0x72727200,0x79790079 +.long 0x07070700,0x8c8c008c +.long 0xb9b9b900,0x6e6e006e +.long 0x55555500,0x8e8e008e +.long 0xf8f8f800,0xf5f500f5 +.long 0xeeeeee00,0xb6b600b6 +.long 0xacacac00,0xfdfd00fd +.long 0x0a0a0a00,0x59590059 +.long 0x36363600,0x98980098 +.long 0x49494900,0x6a6a006a +.long 0x2a2a2a00,0x46460046 +.long 0x68686800,0xbaba00ba +.long 0x3c3c3c00,0x25250025 +.long 0x38383800,0x42420042 +.long 0xf1f1f100,0xa2a200a2 +.long 0xa4a4a400,0xfafa00fa +.long 0x40404000,0x07070007 +.long 0x28282800,0x55550055 +.long 0xd3d3d300,0xeeee00ee +.long 0x7b7b7b00,0x0a0a000a +.long 0xbbbbbb00,0x49490049 +.long 0xc9c9c900,0x68680068 +.long 0x43434300,0x38380038 +.long 0xc1c1c100,0xa4a400a4 +.long 0x15151500,0x28280028 +.long 0xe3e3e300,0x7b7b007b +.long 0xadadad00,0xc9c900c9 +.long 0xf4f4f400,0xc1c100c1 +.long 0x77777700,0xe3e300e3 +.long 0xc7c7c700,0xf4f400f4 +.long 0x80808000,0xc7c700c7 +.long 0x9e9e9e00,0x9e9e009e +.long 0x00e0e0e0,0x38003838 +.long 0x00050505,0x41004141 +.long 0x00585858,0x16001616 +.long 0x00d9d9d9,0x76007676 +.long 0x00676767,0xd900d9d9 +.long 0x004e4e4e,0x93009393 +.long 0x00818181,0x60006060 +.long 0x00cbcbcb,0xf200f2f2 +.long 0x00c9c9c9,0x72007272 +.long 0x000b0b0b,0xc200c2c2 +.long 0x00aeaeae,0xab00abab +.long 0x006a6a6a,0x9a009a9a +.long 0x00d5d5d5,0x75007575 +.long 0x00181818,0x06000606 +.long 0x005d5d5d,0x57005757 +.long 0x00828282,0xa000a0a0 +.long 0x00464646,0x91009191 +.long 0x00dfdfdf,0xf700f7f7 +.long 0x00d6d6d6,0xb500b5b5 +.long 0x00272727,0xc900c9c9 +.long 0x008a8a8a,0xa200a2a2 +.long 0x00323232,0x8c008c8c +.long 0x004b4b4b,0xd200d2d2 +.long 0x00424242,0x90009090 +.long 0x00dbdbdb,0xf600f6f6 +.long 0x001c1c1c,0x07000707 +.long 0x009e9e9e,0xa700a7a7 +.long 0x009c9c9c,0x27002727 +.long 0x003a3a3a,0x8e008e8e +.long 0x00cacaca,0xb200b2b2 +.long 0x00252525,0x49004949 +.long 0x007b7b7b,0xde00dede +.long 0x000d0d0d,0x43004343 +.long 0x00717171,0x5c005c5c +.long 0x005f5f5f,0xd700d7d7 +.long 0x001f1f1f,0xc700c7c7 +.long 0x00f8f8f8,0x3e003e3e +.long 0x00d7d7d7,0xf500f5f5 +.long 0x003e3e3e,0x8f008f8f +.long 0x009d9d9d,0x67006767 +.long 0x007c7c7c,0x1f001f1f +.long 0x00606060,0x18001818 +.long 0x00b9b9b9,0x6e006e6e +.long 0x00bebebe,0xaf00afaf +.long 0x00bcbcbc,0x2f002f2f +.long 0x008b8b8b,0xe200e2e2 +.long 0x00161616,0x85008585 +.long 0x00343434,0x0d000d0d +.long 0x004d4d4d,0x53005353 +.long 0x00c3c3c3,0xf000f0f0 +.long 0x00727272,0x9c009c9c +.long 0x00959595,0x65006565 +.long 0x00ababab,0xea00eaea +.long 0x008e8e8e,0xa300a3a3 +.long 0x00bababa,0xae00aeae +.long 0x007a7a7a,0x9e009e9e +.long 0x00b3b3b3,0xec00ecec +.long 0x00020202,0x80008080 +.long 0x00b4b4b4,0x2d002d2d +.long 0x00adadad,0x6b006b6b +.long 0x00a2a2a2,0xa800a8a8 +.long 0x00acacac,0x2b002b2b +.long 0x00d8d8d8,0x36003636 +.long 0x009a9a9a,0xa600a6a6 +.long 0x00171717,0xc500c5c5 +.long 0x001a1a1a,0x86008686 +.long 0x00353535,0x4d004d4d +.long 0x00cccccc,0x33003333 +.long 0x00f7f7f7,0xfd00fdfd +.long 0x00999999,0x66006666 +.long 0x00616161,0x58005858 +.long 0x005a5a5a,0x96009696 +.long 0x00e8e8e8,0x3a003a3a +.long 0x00242424,0x09000909 +.long 0x00565656,0x95009595 +.long 0x00404040,0x10001010 +.long 0x00e1e1e1,0x78007878 +.long 0x00636363,0xd800d8d8 +.long 0x00090909,0x42004242 +.long 0x00333333,0xcc00cccc +.long 0x00bfbfbf,0xef00efef +.long 0x00989898,0x26002626 +.long 0x00979797,0xe500e5e5 +.long 0x00858585,0x61006161 +.long 0x00686868,0x1a001a1a +.long 0x00fcfcfc,0x3f003f3f +.long 0x00ececec,0x3b003b3b +.long 0x000a0a0a,0x82008282 +.long 0x00dadada,0xb600b6b6 +.long 0x006f6f6f,0xdb00dbdb +.long 0x00535353,0xd400d4d4 +.long 0x00626262,0x98009898 +.long 0x00a3a3a3,0xe800e8e8 +.long 0x002e2e2e,0x8b008b8b +.long 0x00080808,0x02000202 +.long 0x00afafaf,0xeb00ebeb +.long 0x00282828,0x0a000a0a +.long 0x00b0b0b0,0x2c002c2c +.long 0x00747474,0x1d001d1d +.long 0x00c2c2c2,0xb000b0b0 +.long 0x00bdbdbd,0x6f006f6f +.long 0x00363636,0x8d008d8d +.long 0x00222222,0x88008888 +.long 0x00383838,0x0e000e0e +.long 0x00646464,0x19001919 +.long 0x001e1e1e,0x87008787 +.long 0x00393939,0x4e004e4e +.long 0x002c2c2c,0x0b000b0b +.long 0x00a6a6a6,0xa900a9a9 +.long 0x00303030,0x0c000c0c +.long 0x00e5e5e5,0x79007979 +.long 0x00444444,0x11001111 +.long 0x00fdfdfd,0x7f007f7f +.long 0x00888888,0x22002222 +.long 0x009f9f9f,0xe700e7e7 +.long 0x00656565,0x59005959 +.long 0x00878787,0xe100e1e1 +.long 0x006b6b6b,0xda00dada +.long 0x00f4f4f4,0x3d003d3d +.long 0x00232323,0xc800c8c8 +.long 0x00484848,0x12001212 +.long 0x00101010,0x04000404 +.long 0x00d1d1d1,0x74007474 +.long 0x00515151,0x54005454 +.long 0x00c0c0c0,0x30003030 +.long 0x00f9f9f9,0x7e007e7e +.long 0x00d2d2d2,0xb400b4b4 +.long 0x00a0a0a0,0x28002828 +.long 0x00555555,0x55005555 +.long 0x00a1a1a1,0x68006868 +.long 0x00414141,0x50005050 +.long 0x00fafafa,0xbe00bebe +.long 0x00434343,0xd000d0d0 +.long 0x00131313,0xc400c4c4 +.long 0x00c4c4c4,0x31003131 +.long 0x002f2f2f,0xcb00cbcb +.long 0x00a8a8a8,0x2a002a2a +.long 0x00b6b6b6,0xad00adad +.long 0x003c3c3c,0x0f000f0f +.long 0x002b2b2b,0xca00caca +.long 0x00c1c1c1,0x70007070 +.long 0x00ffffff,0xff00ffff +.long 0x00c8c8c8,0x32003232 +.long 0x00a5a5a5,0x69006969 +.long 0x00202020,0x08000808 +.long 0x00898989,0x62006262 +.long 0x00000000,0x00000000 +.long 0x00909090,0x24002424 +.long 0x00474747,0xd100d1d1 +.long 0x00efefef,0xfb00fbfb +.long 0x00eaeaea,0xba00baba +.long 0x00b7b7b7,0xed00eded +.long 0x00151515,0x45004545 +.long 0x00060606,0x81008181 +.long 0x00cdcdcd,0x73007373 +.long 0x00b5b5b5,0x6d006d6d +.long 0x00121212,0x84008484 +.long 0x007e7e7e,0x9f009f9f +.long 0x00bbbbbb,0xee00eeee +.long 0x00292929,0x4a004a4a +.long 0x000f0f0f,0xc300c3c3 +.long 0x00b8b8b8,0x2e002e2e +.long 0x00070707,0xc100c1c1 +.long 0x00040404,0x01000101 +.long 0x009b9b9b,0xe600e6e6 +.long 0x00949494,0x25002525 +.long 0x00212121,0x48004848 +.long 0x00666666,0x99009999 +.long 0x00e6e6e6,0xb900b9b9 +.long 0x00cecece,0xb300b3b3 +.long 0x00ededed,0x7b007b7b +.long 0x00e7e7e7,0xf900f9f9 +.long 0x003b3b3b,0xce00cece +.long 0x00fefefe,0xbf00bfbf +.long 0x007f7f7f,0xdf00dfdf +.long 0x00c5c5c5,0x71007171 +.long 0x00a4a4a4,0x29002929 +.long 0x00373737,0xcd00cdcd +.long 0x00b1b1b1,0x6c006c6c +.long 0x004c4c4c,0x13001313 +.long 0x00919191,0x64006464 +.long 0x006e6e6e,0x9b009b9b +.long 0x008d8d8d,0x63006363 +.long 0x00767676,0x9d009d9d +.long 0x00030303,0xc000c0c0 +.long 0x002d2d2d,0x4b004b4b +.long 0x00dedede,0xb700b7b7 +.long 0x00969696,0xa500a5a5 +.long 0x00262626,0x89008989 +.long 0x007d7d7d,0x5f005f5f +.long 0x00c6c6c6,0xb100b1b1 +.long 0x005c5c5c,0x17001717 +.long 0x00d3d3d3,0xf400f4f4 +.long 0x00f2f2f2,0xbc00bcbc +.long 0x004f4f4f,0xd300d3d3 +.long 0x00191919,0x46004646 +.long 0x003f3f3f,0xcf00cfcf +.long 0x00dcdcdc,0x37003737 +.long 0x00797979,0x5e005e5e +.long 0x001d1d1d,0x47004747 +.long 0x00525252,0x94009494 +.long 0x00ebebeb,0xfa00fafa +.long 0x00f3f3f3,0xfc00fcfc +.long 0x006d6d6d,0x5b005b5b +.long 0x005e5e5e,0x97009797 +.long 0x00fbfbfb,0xfe00fefe +.long 0x00696969,0x5a005a5a +.long 0x00b2b2b2,0xac00acac +.long 0x00f0f0f0,0x3c003c3c +.long 0x00313131,0x4c004c4c +.long 0x000c0c0c,0x03000303 +.long 0x00d4d4d4,0x35003535 +.long 0x00cfcfcf,0xf300f3f3 +.long 0x008c8c8c,0x23002323 +.long 0x00e2e2e2,0xb800b8b8 +.long 0x00757575,0x5d005d5d +.long 0x00a9a9a9,0x6a006a6a +.long 0x004a4a4a,0x92009292 +.long 0x00575757,0xd500d5d5 +.long 0x00848484,0x21002121 +.long 0x00111111,0x44004444 +.long 0x00454545,0x51005151 +.long 0x001b1b1b,0xc600c6c6 +.long 0x00f5f5f5,0x7d007d7d +.long 0x00e4e4e4,0x39003939 +.long 0x000e0e0e,0x83008383 +.long 0x00737373,0xdc00dcdc +.long 0x00aaaaaa,0xaa00aaaa +.long 0x00f1f1f1,0x7c007c7c +.long 0x00dddddd,0x77007777 +.long 0x00595959,0x56005656 +.long 0x00141414,0x05000505 +.long 0x006c6c6c,0x1b001b1b +.long 0x00929292,0xa400a4a4 +.long 0x00545454,0x15001515 +.long 0x00d0d0d0,0x34003434 +.long 0x00787878,0x1e001e1e +.long 0x00707070,0x1c001c1c +.long 0x00e3e3e3,0xf800f8f8 +.long 0x00494949,0x52005252 +.long 0x00808080,0x20002020 +.long 0x00505050,0x14001414 +.long 0x00a7a7a7,0xe900e9e9 +.long 0x00f6f6f6,0xbd00bdbd +.long 0x00777777,0xdd00dddd +.long 0x00939393,0xe400e4e4 +.long 0x00868686,0xa100a1a1 +.long 0x00838383,0xe000e0e0 +.long 0x002a2a2a,0x8a008a8a +.long 0x00c7c7c7,0xf100f1f1 +.long 0x005b5b5b,0xd600d6d6 +.long 0x00e9e9e9,0x7a007a7a +.long 0x00eeeeee,0xbb00bbbb +.long 0x008f8f8f,0xe300e3e3 +.long 0x00010101,0x40004040 +.long 0x003d3d3d,0x4f004f4f +.globl Camellia_cbc_encrypt +.def Camellia_cbc_encrypt; .scl 2; .type 32; .endef +.p2align 4 +Camellia_cbc_encrypt: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_Camellia_cbc_encrypt: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + movq 40(%rsp),%r8 + movq 48(%rsp),%r9 + + cmpq $0,%rdx + je .Lcbc_abort + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 +.Lcbc_prologue: + + movq %rsp,%rbp + subq $64,%rsp + andq $-64,%rsp + + + + leaq -64-63(%rcx),%r10 + subq %rsp,%r10 + negq %r10 + andq $960,%r10 + subq %r10,%rsp + + + movq %rdi,%r12 + movq %rsi,%r13 + movq %r8,%rbx + movq %rcx,%r14 + movl 272(%rcx),%r15d + + movq %r8,40(%rsp) + movq %rbp,48(%rsp) + +.Lcbc_body: + leaq .LCamellia_SBOX(%rip),%rbp + + movl $32,%ecx +.p2align 2 +.Lcbc_prefetch_sbox: + movq 0(%rbp),%rax + movq 32(%rbp),%rsi + movq 64(%rbp),%rdi + movq 96(%rbp),%r11 + leaq 128(%rbp),%rbp + loop .Lcbc_prefetch_sbox + subq $4096,%rbp + shlq $6,%r15 + movq %rdx,%rcx + leaq (%r14,%r15,1),%r15 + + cmpl $0,%r9d + je .LCBC_DECRYPT + + andq $-16,%rdx + andq $15,%rcx + leaq (%r12,%rdx,1),%rdx + movq %r14,0(%rsp) + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + cmpq %r12,%rdx + movl 0(%rbx),%r8d + movl 4(%rbx),%r9d + movl 8(%rbx),%r10d + movl 12(%rbx),%r11d + je .Lcbc_enc_tail + jmp .Lcbc_eloop + +.p2align 4 +.Lcbc_eloop: + xorl 0(%r12),%r8d + xorl 4(%r12),%r9d + xorl 8(%r12),%r10d + bswapl %r8d + xorl 12(%r12),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + movq 0(%rsp),%r14 + bswapl %r8d + movq 8(%rsp),%rdx + bswapl %r9d + movq 16(%rsp),%rcx + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + leaq 16(%r12),%r12 + movl %r11d,12(%r13) + cmpq %rdx,%r12 + leaq 16(%r13),%r13 + jne .Lcbc_eloop + + cmpq $0,%rcx + jne .Lcbc_enc_tail + + movq 40(%rsp),%r13 + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + jmp .Lcbc_done + +.p2align 4 +.Lcbc_enc_tail: + xorq %rax,%rax + movq %rax,0+24(%rsp) + movq %rax,8+24(%rsp) + movq %rax,16(%rsp) + +.Lcbc_enc_pushf: + pushfq + cld + movq %r12,%rsi + leaq 8+24(%rsp),%rdi +.long 0x9066A4F3 + popfq +.Lcbc_enc_popf: + + leaq 24(%rsp),%r12 + leaq 16+24(%rsp),%rax + movq %rax,8(%rsp) + jmp .Lcbc_eloop + +.p2align 4 +.LCBC_DECRYPT: + xchgq %r14,%r15 + addq $15,%rdx + andq $15,%rcx + andq $-16,%rdx + movq %r14,0(%rsp) + leaq (%r12,%rdx,1),%rdx + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + movq (%rbx),%rax + movq 8(%rbx),%rbx + jmp .Lcbc_dloop +.p2align 4 +.Lcbc_dloop: + movl 0(%r12),%r8d + movl 4(%r12),%r9d + movl 8(%r12),%r10d + bswapl %r8d + movl 12(%r12),%r11d + bswapl %r9d + movq %rax,0+24(%rsp) + bswapl %r10d + movq %rbx,8+24(%rsp) + bswapl %r11d + + call _x86_64_Camellia_decrypt + + movq 0(%rsp),%r14 + movq 8(%rsp),%rdx + movq 16(%rsp),%rcx + + bswapl %r8d + movq (%r12),%rax + bswapl %r9d + movq 8(%r12),%rbx + bswapl %r10d + xorl 0+24(%rsp),%r8d + bswapl %r11d + xorl 4+24(%rsp),%r9d + xorl 8+24(%rsp),%r10d + leaq 16(%r12),%r12 + xorl 12+24(%rsp),%r11d + cmpq %rdx,%r12 + je .Lcbc_ddone + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + leaq 16(%r13),%r13 + jmp .Lcbc_dloop + +.p2align 4 +.Lcbc_ddone: + movq 40(%rsp),%rdx + cmpq $0,%rcx + jne .Lcbc_dec_tail + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp .Lcbc_done +.p2align 4 +.Lcbc_dec_tail: + movl %r8d,0+24(%rsp) + movl %r9d,4+24(%rsp) + movl %r10d,8+24(%rsp) + movl %r11d,12+24(%rsp) + +.Lcbc_dec_pushf: + pushfq + cld + leaq 8+24(%rsp),%rsi + leaq (%r13),%rdi +.long 0x9066A4F3 + popfq +.Lcbc_dec_popf: + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp .Lcbc_done + +.p2align 4 +.Lcbc_done: + movq 48(%rsp),%rcx + movq 0(%rcx),%r15 + movq 8(%rcx),%r14 + movq 16(%rcx),%r13 + movq 24(%rcx),%r12 + movq 32(%rcx),%rbp + movq 40(%rcx),%rbx + leaq 48(%rcx),%rsp +.Lcbc_abort: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_Camellia_cbc_encrypt: + +.byte 67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 diff --git a/Libraries/libressl/crypto/camellia/cmll_cbc.c b/Libraries/libressl/crypto/camellia/cmll_cbc.c new file mode 100644 index 000000000..6567e5deb --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_cbc.c @@ -0,0 +1,65 @@ +/* $OpenBSD: cmll_cbc.c,v 1.4 2014/11/13 20:01:58 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void +Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const CAMELLIA_KEY *key, unsigned char *ivec, const int enc) +{ + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, + (block128_f)Camellia_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, + (block128_f)Camellia_decrypt); +} diff --git a/Libraries/libressl/crypto/camellia/cmll_cfb.c b/Libraries/libressl/crypto/camellia/cmll_cfb.c new file mode 100644 index 000000000..755ab9f8b --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_cfb.c @@ -0,0 +1,144 @@ +/* $OpenBSD: cmll_cfb.c,v 1.4 2014/11/13 20:01:58 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + + +/* + * The input and output encrypted as though 128bit cfb mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num; + */ + +void +Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, + const int enc) +{ + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, + (block128_f)Camellia_encrypt); +} + +/* N.B. This expects the input to be packed, MS bit first */ +void +Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, + const int enc) +{ + CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, + (block128_f)Camellia_encrypt); +} + +void +Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, + const int enc) +{ + CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, + (block128_f)Camellia_encrypt); +} diff --git a/Libraries/libressl/crypto/camellia/cmll_ctr.c b/Libraries/libressl/crypto/camellia/cmll_ctr.c new file mode 100644 index 000000000..59a351ee1 --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_ctr.c @@ -0,0 +1,63 @@ +/* $OpenBSD: cmll_ctr.c,v 1.4 2014/11/13 20:01:58 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void +Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], unsigned int *num) +{ + CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, + (block128_f)Camellia_encrypt); +} diff --git a/Libraries/libressl/crypto/camellia/cmll_ecb.c b/Libraries/libressl/crypto/camellia/cmll_ecb.c new file mode 100644 index 000000000..0575d29e2 --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_ecb.c @@ -0,0 +1,64 @@ +/* $OpenBSD: cmll_ecb.c,v 1.7 2023/09/04 08:43:41 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include + +#include "cmll_local.h" + +void +Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc) +{ + if (CAMELLIA_ENCRYPT == enc) + Camellia_encrypt(in, out, key); + else + Camellia_decrypt(in, out, key); +} diff --git a/Libraries/libressl/crypto/camellia/cmll_local.h b/Libraries/libressl/crypto/camellia/cmll_local.h new file mode 100644 index 000000000..831625e77 --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_local.h @@ -0,0 +1,91 @@ +/* $OpenBSD: cmll_local.h,v 1.3 2023/09/04 08:43:41 tb Exp $ */ +/* ==================================================================== + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . + * ALL RIGHTS RESERVED. + * + * Intellectual Property information for Camellia: + * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html + * + * News Release for Announcement of Camellia open source: + * http://www.ntt.co.jp/news/news06e/0604/060413a.html + * + * The Camellia Code included herein is developed by + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed + * to the OpenSSL project. + * + * The Camellia Code is licensed pursuant to the OpenSSL open source + * license provided below. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CAMELLIA_LOCAL_H +#define HEADER_CAMELLIA_LOCAL_H + +#include + +__BEGIN_HIDDEN_DECLS + +typedef unsigned int u32; +typedef unsigned char u8; + +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, + KEY_TABLE_TYPE keyTable); +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]); +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); +void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_CAMELLIA_LOCAL_H */ diff --git a/Libraries/libressl/crypto/camellia/cmll_misc.c b/Libraries/libressl/crypto/camellia/cmll_misc.c new file mode 100644 index 000000000..9fce92df2 --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_misc.c @@ -0,0 +1,81 @@ +/* $OpenBSD: cmll_misc.c,v 1.7 2022/11/26 16:08:51 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include "cmll_local.h" + +int +Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +{ + if (userKey == NULL || key == NULL) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key); + return 0; +} + +void +Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key) +{ + Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); +} + +void +Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key) +{ + Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); +} diff --git a/Libraries/libressl/crypto/camellia/cmll_ofb.c b/Libraries/libressl/crypto/camellia/cmll_ofb.c new file mode 100644 index 000000000..cd3a65e2f --- /dev/null +++ b/Libraries/libressl/crypto/camellia/cmll_ofb.c @@ -0,0 +1,122 @@ +/* $OpenBSD: cmll_ofb.c,v 1.4 2014/11/13 20:01:58 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +/* + * The input and output encrypted as though 128bit ofb mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num; + */ +void +Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, + (block128_f)Camellia_encrypt); +} diff --git a/Libraries/libressl/crypto/cast/c_cfb64.c b/Libraries/libressl/crypto/cast/c_cfb64.c new file mode 100644 index 000000000..2acf7632e --- /dev/null +++ b/Libraries/libressl/crypto/cast/c_cfb64.c @@ -0,0 +1,124 @@ +/* $OpenBSD: c_cfb64.c,v 1.8 2023/07/08 10:43:59 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_local.h" + +/* The input and output encrypted as though 64bit cfb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ + +void +CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, unsigned char *ivec, + int *num, int enc) +{ + CAST_LONG v0, v1, t; + int n= *num; + long l = length; + CAST_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = ivec; + if (enc) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + CAST_encrypt((CAST_LONG *)ti, schedule); + iv = ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = ivec; + } + c= *(in++)^iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1)&0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + CAST_encrypt((CAST_LONG *)ti, schedule); + iv = ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = ivec; + } + cc= *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c^cc; + n = (n + 1)&0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t=c = cc = 0; + *num = n; +} +LCRYPTO_ALIAS(CAST_cfb64_encrypt); diff --git a/Libraries/libressl/crypto/cast/c_ecb.c b/Libraries/libressl/crypto/cast/c_ecb.c new file mode 100644 index 000000000..89338a18e --- /dev/null +++ b/Libraries/libressl/crypto/cast/c_ecb.c @@ -0,0 +1,83 @@ +/* $OpenBSD: c_ecb.c,v 1.10 2023/07/08 10:43:59 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_local.h" +#include + +void +CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *ks, int enc) +{ + CAST_LONG l, d[2]; + + n2l(in, l); + d[0] = l; + n2l(in, l); + d[1] = l; + if (enc) + CAST_encrypt(d, ks); + else + CAST_decrypt(d, ks); + l = d[0]; + l2n(l, out); + l = d[1]; + l2n(l, out); + l = d[0] = d[1] = 0; +} +LCRYPTO_ALIAS(CAST_ecb_encrypt); diff --git a/Libraries/libressl/crypto/cast/c_enc.c b/Libraries/libressl/crypto/cast/c_enc.c new file mode 100644 index 000000000..34fe69f0a --- /dev/null +++ b/Libraries/libressl/crypto/cast/c_enc.c @@ -0,0 +1,207 @@ +/* $OpenBSD: c_enc.c,v 1.10 2023/07/08 10:43:59 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_local.h" + +#ifndef OPENBSD_CAST_ASM +void +CAST_encrypt(CAST_LONG *data, const CAST_KEY *key) +{ + CAST_LONG l, r, t; + const CAST_LONG *k; + + k = &(key->data[0]); + l = data[0]; + r = data[1]; + + E_CAST( 0, k,l, r,+,^, -); + E_CAST( 1, k,r, l,^, -,+); + E_CAST( 2, k,l, r, -,+,^); + E_CAST( 3, k,r, l,+,^, -); + E_CAST( 4, k,l, r,^, -,+); + E_CAST( 5, k,r, l, -,+,^); + E_CAST( 6, k,l, r,+,^, -); + E_CAST( 7, k,r, l,^, -,+); + E_CAST( 8, k,l, r, -,+,^); + E_CAST( 9, k,r, l,+,^, -); + E_CAST(10, k,l, r,^, -,+); + E_CAST(11, k,r, l, -,+,^); + if (!key->short_key) { + E_CAST(12, k,l, r,+,^, -); + E_CAST(13, k,r, l,^, -,+); + E_CAST(14, k,l, r, -,+,^); + E_CAST(15, k,r, l,+,^, -); + } + + data[1] = l&0xffffffffL; + data[0] = r&0xffffffffL; +} +LCRYPTO_ALIAS(CAST_encrypt); + +void +CAST_decrypt(CAST_LONG *data, const CAST_KEY *key) +{ + CAST_LONG l, r, t; + const CAST_LONG *k; + + k = &(key->data[0]); + l = data[0]; + r = data[1]; + + if (!key->short_key) { + E_CAST(15, k,l, r,+,^, -); + E_CAST(14, k,r, l, -,+,^); + E_CAST(13, k,l, r,^, -,+); + E_CAST(12, k,r, l,+,^, -); + } + E_CAST(11, k,l, r, -,+,^); + E_CAST(10, k,r, l,^, -,+); + E_CAST( 9, k,l, r,+,^, -); + E_CAST( 8, k,r, l, -,+,^); + E_CAST( 7, k,l, r,^, -,+); + E_CAST( 6, k,r, l,+,^, -); + E_CAST( 5, k,l, r, -,+,^); + E_CAST( 4, k,r, l,^, -,+); + E_CAST( 3, k,l, r,+,^, -); + E_CAST( 2, k,r, l, -,+,^); + E_CAST( 1, k,l, r,^, -,+); + E_CAST( 0, k,r, l,+,^, -); + + data[1] = l&0xffffffffL; + data[0] = r&0xffffffffL; +} +LCRYPTO_ALIAS(CAST_decrypt); +#endif + +void +CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const CAST_KEY *ks, unsigned char *iv, int enc) +{ + CAST_LONG tin0, tin1; + CAST_LONG tout0, tout1, xor0, xor1; + long l = length; + CAST_LONG tin[2]; + + if (enc) { + n2l(iv, tout0); + n2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + CAST_encrypt(tin, ks); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + CAST_encrypt(tin, ks); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, iv); + l2n(tout1, iv); + } else { + n2l(iv, xor0); + n2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + CAST_decrypt(tin, ks); + tout0 = tin[0]^xor0; + tout1 = tin[1]^xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + CAST_decrypt(tin, ks); + tout0 = tin[0]^xor0; + tout1 = tin[1]^xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, iv); + l2n(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +LCRYPTO_ALIAS(CAST_cbc_encrypt); diff --git a/Libraries/libressl/crypto/cast/c_ofb64.c b/Libraries/libressl/crypto/cast/c_ofb64.c new file mode 100644 index 000000000..48ebab906 --- /dev/null +++ b/Libraries/libressl/crypto/cast/c_ofb64.c @@ -0,0 +1,111 @@ +/* $OpenBSD: c_ofb64.c,v 1.8 2023/07/08 10:43:59 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_local.h" + +/* The input and output encrypted as though 64bit ofb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ +void +CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, unsigned char *ivec, + int *num) +{ + CAST_LONG v0, v1, t; + int n= *num; + long l = length; + unsigned char d[8]; + char *dp; + CAST_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + CAST_encrypt((CAST_LONG *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++)= *(in++)^d[n]; + n = (n + 1)&0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} +LCRYPTO_ALIAS(CAST_ofb64_encrypt); diff --git a/Libraries/libressl/crypto/cast/c_skey.c b/Libraries/libressl/crypto/cast/c_skey.c new file mode 100644 index 000000000..ecce7bad7 --- /dev/null +++ b/Libraries/libressl/crypto/cast/c_skey.c @@ -0,0 +1,169 @@ +/* $OpenBSD: c_skey.c,v 1.14 2023/07/08 10:43:59 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cast_local.h" +#include "cast_s.h" + +#define CAST_exp(l,A,a,n) \ + A[n/4]=l; \ + a[n+3]=(l )&0xff; \ + a[n+2]=(l>> 8)&0xff; \ + a[n+1]=(l>>16)&0xff; \ + a[n+0]=(l>>24)&0xff; + +#define S4 CAST_S_table4 +#define S5 CAST_S_table5 +#define S6 CAST_S_table6 +#define S7 CAST_S_table7 +void +CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +{ + CAST_LONG x[16]; + CAST_LONG z[16]; + CAST_LONG k[32]; + CAST_LONG X[4], Z[4]; + CAST_LONG l, *K; + int i; + + for (i = 0; + i < 16; + i++) x[i] = 0; + if (len > 16) + len = 16; + for (i = 0; i < len; i++) + x[i] = data[i]; + if (len <= 10) + key->short_key = 1; + else + key->short_key = 0; + + K = &k[0]; + X[0] = ((x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3])&0xffffffffL; + X[1] = ((x[ 4]<<24)|(x[ 5]<<16)|(x[ 6]<<8)|x[ 7])&0xffffffffL; + X[2] = ((x[ 8]<<24)|(x[ 9]<<16)|(x[10]<<8)|x[11])&0xffffffffL; + X[3] = ((x[12]<<24)|(x[13]<<16)|(x[14]<<8)|x[15])&0xffffffffL; + + for (;;) { + l = X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]]; + CAST_exp(l, Z, z, 0); + l = X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]]; + CAST_exp(l, Z, z, 4); + l = X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]]; + CAST_exp(l, Z, z, 8); + l = X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]]; + CAST_exp(l, Z,z, 12); + + K[0] = S4[z[ 8]]^S5[z[ 9]]^S6[z[ 7]]^S7[z[ 6]]^S4[z[ 2]]; + K[1] = S4[z[10]]^S5[z[11]]^S6[z[ 5]]^S7[z[ 4]]^S5[z[ 6]]; + K[2] = S4[z[12]]^S5[z[13]]^S6[z[ 3]]^S7[z[ 2]]^S6[z[ 9]]; + K[3] = S4[z[14]]^S5[z[15]]^S6[z[ 1]]^S7[z[ 0]]^S7[z[12]]; + + l = Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]]; + CAST_exp(l, X, x, 0); + l = Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]]; + CAST_exp(l, X, x, 4); + l = Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]]; + CAST_exp(l, X, x, 8); + l = Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]]; + CAST_exp(l, X,x, 12); + + K[4] = S4[x[ 3]]^S5[x[ 2]]^S6[x[12]]^S7[x[13]]^S4[x[ 8]]; + K[5] = S4[x[ 1]]^S5[x[ 0]]^S6[x[14]]^S7[x[15]]^S5[x[13]]; + K[6] = S4[x[ 7]]^S5[x[ 6]]^S6[x[ 8]]^S7[x[ 9]]^S6[x[ 3]]; + K[7] = S4[x[ 5]]^S5[x[ 4]]^S6[x[10]]^S7[x[11]]^S7[x[ 7]]; + + l = X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]]; + CAST_exp(l, Z, z, 0); + l = X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]]; + CAST_exp(l, Z, z, 4); + l = X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]]; + CAST_exp(l, Z, z, 8); + l = X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]]; + CAST_exp(l, Z,z, 12); + + K[8] = S4[z[ 3]]^S5[z[ 2]]^S6[z[12]]^S7[z[13]]^S4[z[ 9]]; + K[9] = S4[z[ 1]]^S5[z[ 0]]^S6[z[14]]^S7[z[15]]^S5[z[12]]; + K[10] = S4[z[ 7]]^S5[z[ 6]]^S6[z[ 8]]^S7[z[ 9]]^S6[z[ 2]]; + K[11] = S4[z[ 5]]^S5[z[ 4]]^S6[z[10]]^S7[z[11]]^S7[z[ 6]]; + + l = Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]]; + CAST_exp(l, X, x, 0); + l = Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]]; + CAST_exp(l, X, x, 4); + l = Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]]; + CAST_exp(l, X, x, 8); + l = Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]]; + CAST_exp(l, X,x, 12); + + K[12] = S4[x[ 8]]^S5[x[ 9]]^S6[x[ 7]]^S7[x[ 6]]^S4[x[ 3]]; + K[13] = S4[x[10]]^S5[x[11]]^S6[x[ 5]]^S7[x[ 4]]^S5[x[ 7]]; + K[14] = S4[x[12]]^S5[x[13]]^S6[x[ 3]]^S7[x[ 2]]^S6[x[ 8]]; + K[15] = S4[x[14]]^S5[x[15]]^S6[x[ 1]]^S7[x[ 0]]^S7[x[13]]; + if (K != k) + break; + K += 16; + } + + for (i = 0; i < 16; i++) { + key->data[i*2] = k[i]; + key->data[i*2 + 1] = ((k[i + 16]) + 16)&0x1f; + } +} +LCRYPTO_ALIAS(CAST_set_key); diff --git a/Libraries/libressl/crypto/cast/cast_local.h b/Libraries/libressl/crypto/cast/cast_local.h new file mode 100644 index 000000000..5fb991110 --- /dev/null +++ b/Libraries/libressl/crypto/cast/cast_local.h @@ -0,0 +1,216 @@ +/* $OpenBSD: cast_local.h,v 1.2 2023/07/08 07:25:43 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* only invoked with 0 <= n <= 31 */ +#define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>((32-(n))&31))) + +#define C_M 0x3fc +#define C_0 22L +#define C_1 14L +#define C_2 6L +#define C_3 2L /* left shift */ + +/* The rotate has an extra 16 added to it to help the x86 asm */ +#if defined(CAST_PTR) +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + t=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + t=ROTL(t,i); \ + L^= (((((*(CAST_LONG *)((unsigned char *) \ + CAST_S_table0+((t>>C_2)&C_M)) OP2 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \ + } +#elif defined(CAST_PTR2) +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + CAST_LONG u,v,w; \ + w=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + w=ROTL(w,i); \ + u=w>>C_2; \ + v=w<>C_0; \ + t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\ + v=w>>C_1; \ + u&=C_M; \ + v&=C_M; \ + t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\ + t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\ + L^=(t&0xffffffff); \ + } +#else +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + CAST_LONG a,b,c,d; \ + t=(key[n*2] OP1 R)&0xffffffff; \ + t=ROTL(t,(key[n*2+1])); \ + a=CAST_S_table0[(t>> 8)&0xff]; \ + b=CAST_S_table1[(t )&0xff]; \ + c=CAST_S_table2[(t>>24)&0xff]; \ + d=CAST_S_table3[(t>>16)&0xff]; \ + L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \ + } +#endif + +extern const CAST_LONG CAST_S_table0[256]; +extern const CAST_LONG CAST_S_table1[256]; +extern const CAST_LONG CAST_S_table2[256]; +extern const CAST_LONG CAST_S_table3[256]; +extern const CAST_LONG CAST_S_table4[256]; +extern const CAST_LONG CAST_S_table5[256]; +extern const CAST_LONG CAST_S_table6[256]; +extern const CAST_LONG CAST_S_table7[256]; diff --git a/Libraries/libressl/crypto/cast/cast_s.h b/Libraries/libressl/crypto/cast/cast_s.h new file mode 100644 index 000000000..dc339504d --- /dev/null +++ b/Libraries/libressl/crypto/cast/cast_s.h @@ -0,0 +1,590 @@ +/* $OpenBSD: cast_s.h,v 1.7 2023/07/08 07:25:43 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +__BEGIN_HIDDEN_DECLS + +const CAST_LONG CAST_S_table0[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, + 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, + 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, + 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, + 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, + 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, + 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, + 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, + 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, + 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, + 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, + 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, + 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, + 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, + 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, + 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, + 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, + 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, + 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, + 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, + 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, + 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, + 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, + 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, + 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, + 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, + 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, + 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, + 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, + 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, + 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, + 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, + 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf, +}; +const CAST_LONG CAST_S_table1[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, + 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, + 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, + 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, + 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, + 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, + 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, + 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, + 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, + 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, + 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, + 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, + 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, + 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, + 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, + 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, + 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, + 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, + 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, + 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, + 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, + 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, + 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, + 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, + 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, + 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, + 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, + 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, + 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, + 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, + 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, + 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, + 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1, +}; +const CAST_LONG CAST_S_table2[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, + 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, + 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, + 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, + 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, + 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, + 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, + 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, + 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, + 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, + 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, + 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, + 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, + 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, + 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, + 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, + 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, + 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, + 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, + 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, + 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, + 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, + 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, + 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, + 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, + 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, + 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, + 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, + 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, + 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, + 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, + 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, + 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783, +}; +const CAST_LONG CAST_S_table3[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, + 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, + 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, + 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, + 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, + 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, + 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, + 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, + 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, + 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, + 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, + 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, + 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, + 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, + 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, + 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, + 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, + 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, + 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, + 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, + 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, + 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, + 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, + 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, + 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, + 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, + 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, + 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, + 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, + 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, + 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, + 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, + 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2, +}; +const CAST_LONG CAST_S_table4[256] = { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, + 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, + 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, + 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, + 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, + 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, + 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, + 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, + 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, + 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, + 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, + 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, + 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, + 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, + 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, + 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, + 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, + 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, + 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, + 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, + 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, + 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, + 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, + 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, + 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, + 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, + 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, + 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, + 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, + 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, + 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, + 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, + 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4, +}; +const CAST_LONG CAST_S_table5[256] = { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, + 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, + 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, + 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, + 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, + 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, + 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, + 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, + 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, + 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, + 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, + 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, + 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, + 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, + 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, + 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, + 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, + 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, + 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, + 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, + 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, + 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, + 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, + 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, + 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, + 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, + 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, + 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, + 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, + 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, + 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, + 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, + 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f, +}; +const CAST_LONG CAST_S_table6[256] = { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, + 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, + 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, + 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, + 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, + 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, + 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, + 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, + 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, + 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, + 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, + 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, + 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, + 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, + 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, + 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, + 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, + 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, + 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, + 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, + 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, + 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, + 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, + 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, + 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, + 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, + 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, + 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, + 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, + 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, + 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, + 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, + 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3, +}; +const CAST_LONG CAST_S_table7[256] = { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, + 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, + 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, + 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, + 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, + 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, + 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, + 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, + 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, + 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, + 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, + 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, + 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, + 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, + 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, + 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, + 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, + 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, + 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, + 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, + 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, + 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, + 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, + 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, + 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, + 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, + 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, + 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, + 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, + 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, + 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, + 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, + 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e, +}; + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/chacha/chacha-merged.c b/Libraries/libressl/crypto/chacha/chacha-merged.c new file mode 100644 index 000000000..b405af84e --- /dev/null +++ b/Libraries/libressl/crypto/chacha/chacha-merged.c @@ -0,0 +1,323 @@ +/* $OpenBSD: chacha-merged.c,v 1.11 2023/07/07 19:37:53 beck Exp $ */ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include + +#define CHACHA_MINKEYLEN 16 +#define CHACHA_NONCELEN 8 +#define CHACHA_CTRLEN 8 +#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) +#define CHACHA_BLOCKLEN 64 + +typedef uint8_t u8; +typedef uint32_t u32; + +struct chacha_ctx { + u32 input[16]; + u8 ks[CHACHA_BLOCKLEN]; + u8 unused; +}; + +static inline void chacha_keysetup(struct chacha_ctx *x, const u8 *k, u32 kbits) + __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN))); +static inline void chacha_ivsetup(struct chacha_ctx *x, const u8 *iv, + const u8 *ctr) + __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN))) + __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN))); +static inline void chacha_encrypt_bytes(struct chacha_ctx *x, const u8 *m, + u8 *c, u32 bytes) + __attribute__((__bounded__(__buffer__, 2, 4))) + __attribute__((__bounded__(__buffer__, 3, 4))); + +typedef struct chacha_ctx chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0])) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v)); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +/* Initialise with "expand 32-byte k". */ +static const char sigma[16] = { + 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x33, + 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, +}; + +/* Initialise with "expand 16-byte k". */ +static const char tau[16] = { + 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x31, + 0x36, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, +}; + +static inline void +chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +static inline void +chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) +{ + x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); + x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +static inline void +chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7; + u32 x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7; + u32 j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = NULL; + u8 tmp[64]; + u32 i; + + if (!bytes) + return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0; i < bytes; ++i) + tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + if (bytes < 64) { + U32TO8_LITTLE(x->ks + 0, x0); + U32TO8_LITTLE(x->ks + 4, x1); + U32TO8_LITTLE(x->ks + 8, x2); + U32TO8_LITTLE(x->ks + 12, x3); + U32TO8_LITTLE(x->ks + 16, x4); + U32TO8_LITTLE(x->ks + 20, x5); + U32TO8_LITTLE(x->ks + 24, x6); + U32TO8_LITTLE(x->ks + 28, x7); + U32TO8_LITTLE(x->ks + 32, x8); + U32TO8_LITTLE(x->ks + 36, x9); + U32TO8_LITTLE(x->ks + 40, x10); + U32TO8_LITTLE(x->ks + 44, x11); + U32TO8_LITTLE(x->ks + 48, x12); + U32TO8_LITTLE(x->ks + 52, x13); + U32TO8_LITTLE(x->ks + 56, x14); + U32TO8_LITTLE(x->ks + 60, x15); + } + + x0 = XOR(x0, U8TO32_LITTLE(m + 0)); + x1 = XOR(x1, U8TO32_LITTLE(m + 4)); + x2 = XOR(x2, U8TO32_LITTLE(m + 8)); + x3 = XOR(x3, U8TO32_LITTLE(m + 12)); + x4 = XOR(x4, U8TO32_LITTLE(m + 16)); + x5 = XOR(x5, U8TO32_LITTLE(m + 20)); + x6 = XOR(x6, U8TO32_LITTLE(m + 24)); + x7 = XOR(x7, U8TO32_LITTLE(m + 28)); + x8 = XOR(x8, U8TO32_LITTLE(m + 32)); + x9 = XOR(x9, U8TO32_LITTLE(m + 36)); + x10 = XOR(x10, U8TO32_LITTLE(m + 40)); + x11 = XOR(x11, U8TO32_LITTLE(m + 44)); + x12 = XOR(x12, U8TO32_LITTLE(m + 48)); + x13 = XOR(x13, U8TO32_LITTLE(m + 52)); + x14 = XOR(x14, U8TO32_LITTLE(m + 56)); + x15 = XOR(x15, U8TO32_LITTLE(m + 60)); + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* + * Stopping at 2^70 bytes per nonce is the user's + * responsibility. + */ + } + + U32TO8_LITTLE(c + 0, x0); + U32TO8_LITTLE(c + 4, x1); + U32TO8_LITTLE(c + 8, x2); + U32TO8_LITTLE(c + 12, x3); + U32TO8_LITTLE(c + 16, x4); + U32TO8_LITTLE(c + 20, x5); + U32TO8_LITTLE(c + 24, x6); + U32TO8_LITTLE(c + 28, x7); + U32TO8_LITTLE(c + 32, x8); + U32TO8_LITTLE(c + 36, x9); + U32TO8_LITTLE(c + 40, x10); + U32TO8_LITTLE(c + 44, x11); + U32TO8_LITTLE(c + 48, x12); + U32TO8_LITTLE(c + 52, x13); + U32TO8_LITTLE(c + 56, x14); + U32TO8_LITTLE(c + 60, x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0; i < bytes; ++i) + ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + x->unused = 64 - bytes; + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} + +void +CRYPTO_hchacha_20(unsigned char subkey[32], const unsigned char key[32], + const unsigned char nonce[16]) +{ + uint32_t x[16]; + int i; + + x[0] = U8TO32_LITTLE(sigma + 0); + x[1] = U8TO32_LITTLE(sigma + 4); + x[2] = U8TO32_LITTLE(sigma + 8); + x[3] = U8TO32_LITTLE(sigma + 12); + x[4] = U8TO32_LITTLE(key + 0); + x[5] = U8TO32_LITTLE(key + 4); + x[6] = U8TO32_LITTLE(key + 8); + x[7] = U8TO32_LITTLE(key + 12); + x[8] = U8TO32_LITTLE(key + 16); + x[9] = U8TO32_LITTLE(key + 20); + x[10] = U8TO32_LITTLE(key + 24); + x[11] = U8TO32_LITTLE(key + 28); + x[12] = U8TO32_LITTLE(nonce + 0); + x[13] = U8TO32_LITTLE(nonce + 4); + x[14] = U8TO32_LITTLE(nonce + 8); + x[15] = U8TO32_LITTLE(nonce + 12); + + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x[0], x[4], x[8], x[12]) + QUARTERROUND(x[1], x[5], x[9], x[13]) + QUARTERROUND(x[2], x[6], x[10], x[14]) + QUARTERROUND(x[3], x[7], x[11], x[15]) + QUARTERROUND(x[0], x[5], x[10], x[15]) + QUARTERROUND(x[1], x[6], x[11], x[12]) + QUARTERROUND(x[2], x[7], x[8], x[13]) + QUARTERROUND(x[3], x[4], x[9], x[14]) + } + + U32TO8_LITTLE(subkey + 0, x[0]); + U32TO8_LITTLE(subkey + 4, x[1]); + U32TO8_LITTLE(subkey + 8, x[2]); + U32TO8_LITTLE(subkey + 12, x[3]); + + U32TO8_LITTLE(subkey + 16, x[12]); + U32TO8_LITTLE(subkey + 20, x[13]); + U32TO8_LITTLE(subkey + 24, x[14]); + U32TO8_LITTLE(subkey + 28, x[15]); +} +LCRYPTO_ALIAS(CRYPTO_hchacha_20); diff --git a/Libraries/libressl/crypto/chacha/chacha.c b/Libraries/libressl/crypto/chacha/chacha.c new file mode 100644 index 000000000..b60e3c4f2 --- /dev/null +++ b/Libraries/libressl/crypto/chacha/chacha.c @@ -0,0 +1,112 @@ +/* $OpenBSD: chacha.c,v 1.10 2023/07/05 16:17:20 beck Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "chacha-merged.c" + +void +ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, uint32_t keybits) +{ + chacha_keysetup((chacha_ctx *)ctx, key, keybits); + ctx->unused = 0; +} +LCRYPTO_ALIAS(ChaCha_set_key); + +void +ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv, + const unsigned char *counter) +{ + chacha_ivsetup((chacha_ctx *)ctx, iv, counter); + ctx->unused = 0; +} +LCRYPTO_ALIAS(ChaCha_set_iv); + +void +ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, size_t len) +{ + unsigned char *k; + uint64_t n; + int i, l; + + /* Consume remaining keystream, if any exists. */ + if (ctx->unused > 0) { + k = ctx->ks + 64 - ctx->unused; + l = (len > ctx->unused) ? ctx->unused : len; + for (i = 0; i < l; i++) + *(out++) = *(in++) ^ *(k++); + ctx->unused -= l; + len -= l; + } + + while (len > 0) { + if ((n = len) > UINT32_MAX) + n = UINT32_MAX; + + chacha_encrypt_bytes((chacha_ctx *)ctx, in, out, (uint32_t)n); + + in += n; + out += n; + len -= n; + } +} +LCRYPTO_ALIAS(ChaCha); + +void +CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len, + const unsigned char key[32], const unsigned char iv[8], uint64_t counter) +{ + struct chacha_ctx ctx; + uint64_t n; + + /* + * chacha_ivsetup expects the counter to be in u8. Rather than + * converting size_t to u8 and then back again, pass a counter of + * NULL and manually assign it afterwards. + */ + chacha_keysetup(&ctx, key, 256); + chacha_ivsetup(&ctx, iv, NULL); + if (counter != 0) { + ctx.input[12] = (uint32_t)counter; + ctx.input[13] = (uint32_t)(counter >> 32); + } + + while (len > 0) { + if ((n = len) > UINT32_MAX) + n = UINT32_MAX; + + chacha_encrypt_bytes(&ctx, in, out, (uint32_t)n); + + in += n; + out += n; + len -= n; + } +} +LCRYPTO_ALIAS(CRYPTO_chacha_20); + +void +CRYPTO_xchacha_20(unsigned char *out, const unsigned char *in, size_t len, + const unsigned char key[32], const unsigned char iv[24]) +{ + uint8_t subkey[32]; + + CRYPTO_hchacha_20(subkey, key, iv); + CRYPTO_chacha_20(out, in, len, subkey, iv + 16, 0); +} +LCRYPTO_ALIAS(CRYPTO_xchacha_20); diff --git a/Libraries/libressl/crypto/cmac/cm_ameth.c b/Libraries/libressl/crypto/cmac/cm_ameth.c new file mode 100644 index 000000000..04e0eb836 --- /dev/null +++ b/Libraries/libressl/crypto/cmac/cm_ameth.c @@ -0,0 +1,88 @@ +/* $OpenBSD: cm_ameth.c,v 1.10 2022/11/26 16:08:51 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2010. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include +#include + +#include "asn1_local.h" +#include "evp_local.h" + +/* CMAC "ASN1" method. This is just here to indicate the + * maximum CMAC output length and to free up a CMAC + * key. + */ + +static int +cmac_size(const EVP_PKEY *pkey) +{ + return EVP_MAX_BLOCK_LENGTH; +} + +static void +cmac_key_free(EVP_PKEY *pkey) +{ + CMAC_CTX_free(pkey->pkey.ptr); +} + +const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { + .pkey_id = EVP_PKEY_CMAC, + .pkey_base_id = EVP_PKEY_CMAC, + + .pem_str = "CMAC", + .info = "OpenSSL CMAC method", + + .pkey_size = cmac_size, + .pkey_free = cmac_key_free +}; diff --git a/Libraries/libressl/crypto/cmac/cm_pmeth.c b/Libraries/libressl/crypto/cmac/cm_pmeth.c new file mode 100644 index 000000000..d47cfb7b7 --- /dev/null +++ b/Libraries/libressl/crypto/cmac/cm_pmeth.c @@ -0,0 +1,212 @@ +/* $OpenBSD: cm_pmeth.c,v 1.10 2022/11/26 16:08:51 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2010. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include + +#include +#include +#include +#include + +#include "evp_local.h" + +/* The context structure and "key" is simply a CMAC_CTX */ + +static int +pkey_cmac_init(EVP_PKEY_CTX *ctx) +{ + ctx->data = CMAC_CTX_new(); + if (!ctx->data) + return 0; + ctx->keygen_info_count = 0; + return 1; +} + +static int +pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + if (!pkey_cmac_init(dst)) + return 0; + if (!CMAC_CTX_copy(dst->data, src->data)) + return 0; + return 1; +} + +static void +pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) +{ + CMAC_CTX_free(ctx->data); +} + +static int +pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + CMAC_CTX *cmkey = CMAC_CTX_new(); + CMAC_CTX *cmctx = ctx->data; + + if (!cmkey) + return 0; + if (!CMAC_CTX_copy(cmkey, cmctx)) { + CMAC_CTX_free(cmkey); + return 0; + } + EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); + + return 1; +} + +static int +int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + if (!CMAC_Update(ctx->pctx->data, data, count)) + return 0; + return 1; +} + +static int +cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int +cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + return CMAC_Final(ctx->data, sig, siglen); +} + +static int +pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + CMAC_CTX *cmctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (!p2 || p1 < 0) + return 0; + if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) + return 0; + break; + + case EVP_PKEY_CTRL_CIPHER: + if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) + return 0; + break; + + case EVP_PKEY_CTRL_MD: + if (ctx->pkey && !CMAC_CTX_copy(ctx->data, ctx->pkey->pkey.ptr)) + return 0; + if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) + return 0; + break; + + default: + return -2; + } + return 1; +} + +static int +pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + if (!value) + return 0; + if (!strcmp(type, "key")) { + void *p = (void *)value; + return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + strlen(p), p); + } + if (!strcmp(type, "cipher")) { + const EVP_CIPHER *c; + + c = EVP_get_cipherbyname(value); + if (!c) + return 0; + return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); + } + if (!strcmp(type, "hexkey")) { + unsigned char *key; + int r; + long keylen; + + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + free(key); + return r; + } + + return -2; +} + +const EVP_PKEY_METHOD cmac_pkey_meth = { + .pkey_id = EVP_PKEY_CMAC, + .flags = EVP_PKEY_FLAG_SIGCTX_CUSTOM, + + .init = pkey_cmac_init, + .copy = pkey_cmac_copy, + .cleanup = pkey_cmac_cleanup, + + .keygen = pkey_cmac_keygen, + + .signctx_init = cmac_signctx_init, + .signctx = cmac_signctx, + + .ctrl = pkey_cmac_ctrl, + .ctrl_str = pkey_cmac_ctrl_str +}; diff --git a/Libraries/libressl/crypto/cmac/cmac.c b/Libraries/libressl/crypto/cmac/cmac.c new file mode 100644 index 000000000..9c05a98e1 --- /dev/null +++ b/Libraries/libressl/crypto/cmac/cmac.c @@ -0,0 +1,292 @@ +/* $OpenBSD: cmac.c,v 1.14 2023/07/08 14:27:14 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +#include + +#include "evp_local.h" + +struct CMAC_CTX_st { + /* Cipher context to use */ + EVP_CIPHER_CTX cctx; + /* Keys k1 and k2 */ + unsigned char k1[EVP_MAX_BLOCK_LENGTH]; + unsigned char k2[EVP_MAX_BLOCK_LENGTH]; + /* Temporary block */ + unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; + /* Last (possibly partial) block */ + unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; + /* Number of bytes in last block: -1 means context not initialised */ + int nlast_block; +}; + + +/* Make temporary keys K1 and K2 */ + +static void +make_kn(unsigned char *k1, unsigned char *l, int bl) +{ + int i; + + /* Shift block to left, including carry */ + for (i = 0; i < bl; i++) { + k1[i] = l[i] << 1; + if (i < bl - 1 && l[i + 1] & 0x80) + k1[i] |= 1; + } + /* If MSB set fixup with R */ + if (l[0] & 0x80) + k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; +} + +CMAC_CTX * +CMAC_CTX_new(void) +{ + CMAC_CTX *ctx; + + ctx = malloc(sizeof(CMAC_CTX)); + if (!ctx) + return NULL; + EVP_CIPHER_CTX_init(&ctx->cctx); + ctx->nlast_block = -1; + return ctx; +} +LCRYPTO_ALIAS(CMAC_CTX_new); + +void +CMAC_CTX_cleanup(CMAC_CTX *ctx) +{ + EVP_CIPHER_CTX_cleanup(&ctx->cctx); + explicit_bzero(ctx->tbl, EVP_MAX_BLOCK_LENGTH); + explicit_bzero(ctx->k1, EVP_MAX_BLOCK_LENGTH); + explicit_bzero(ctx->k2, EVP_MAX_BLOCK_LENGTH); + explicit_bzero(ctx->last_block, EVP_MAX_BLOCK_LENGTH); + ctx->nlast_block = -1; +} +LCRYPTO_ALIAS(CMAC_CTX_cleanup); + +EVP_CIPHER_CTX * +CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) +{ + return &ctx->cctx; +} +LCRYPTO_ALIAS(CMAC_CTX_get0_cipher_ctx); + +void +CMAC_CTX_free(CMAC_CTX *ctx) +{ + if (ctx == NULL) + return; + + CMAC_CTX_cleanup(ctx); + free(ctx); +} +LCRYPTO_ALIAS(CMAC_CTX_free); + +int +CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) +{ + int bl; + + if (in->nlast_block == -1) + return 0; + if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) + return 0; + bl = EVP_CIPHER_CTX_block_size(&in->cctx); + memcpy(out->k1, in->k1, bl); + memcpy(out->k2, in->k2, bl); + memcpy(out->tbl, in->tbl, bl); + memcpy(out->last_block, in->last_block, bl); + out->nlast_block = in->nlast_block; + return 1; +} +LCRYPTO_ALIAS(CMAC_CTX_copy); + +int +CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl) +{ + static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; + + /* All zeros means restart */ + if (!key && !cipher && !impl && keylen == 0) { + /* Not initialised */ + if (ctx->nlast_block == -1) + return 0; + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) + return 0; + memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); + ctx->nlast_block = 0; + return 1; + } + /* Initialise context */ + if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) + return 0; + /* Non-NULL key means initialisation complete */ + if (key) { + int bl; + + if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) + return 0; + if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) + return 0; + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) + return 0; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) + return 0; + make_kn(ctx->k1, ctx->tbl, bl); + make_kn(ctx->k2, ctx->k1, bl); + explicit_bzero(ctx->tbl, bl); + /* Reset context again ready for first data block */ + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) + return 0; + /* Zero tbl so resume works */ + memset(ctx->tbl, 0, bl); + ctx->nlast_block = 0; + } + return 1; +} +LCRYPTO_ALIAS(CMAC_Init); + +int +CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) +{ + const unsigned char *data = in; + size_t bl; + + if (ctx->nlast_block == -1) + return 0; + if (dlen == 0) + return 1; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + /* Copy into partial block if we need to */ + if (ctx->nlast_block > 0) { + size_t nleft; + + nleft = bl - ctx->nlast_block; + if (dlen < nleft) + nleft = dlen; + memcpy(ctx->last_block + ctx->nlast_block, data, nleft); + dlen -= nleft; + ctx->nlast_block += nleft; + /* If no more to process return */ + if (dlen == 0) + return 1; + data += nleft; + /* Else not final block so encrypt it */ + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl)) + return 0; + } + /* Encrypt all but one of the complete blocks left */ + while (dlen > bl) { + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) + return 0; + dlen -= bl; + data += bl; + } + /* Copy any data left to last block buffer */ + memcpy(ctx->last_block, data, dlen); + ctx->nlast_block = dlen; + return 1; +} +LCRYPTO_ALIAS(CMAC_Update); + +int +CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) +{ + int i, bl, lb; + + if (ctx->nlast_block == -1) + return 0; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + *poutlen = (size_t)bl; + if (!out) + return 1; + lb = ctx->nlast_block; + /* Is last block complete? */ + if (lb == bl) { + for (i = 0; i < bl; i++) + out[i] = ctx->last_block[i] ^ ctx->k1[i]; + } else { + ctx->last_block[lb] = 0x80; + if (bl - lb > 1) + memset(ctx->last_block + lb + 1, 0, bl - lb - 1); + for (i = 0; i < bl; i++) + out[i] = ctx->last_block[i] ^ ctx->k2[i]; + } + if (!EVP_Cipher(&ctx->cctx, out, out, bl)) { + explicit_bzero(out, bl); + return 0; + } + return 1; +} +LCRYPTO_ALIAS(CMAC_Final); + +int +CMAC_resume(CMAC_CTX *ctx) +{ + if (ctx->nlast_block == -1) + return 0; + /* The buffer "tbl" containes the last fully encrypted block + * which is the last IV (or all zeroes if no last encrypted block). + * The last block has not been modified since CMAC_final(). + * So reinitialising using the last decrypted block will allow + * CMAC to continue after calling CMAC_Final(). + */ + return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl); +} +LCRYPTO_ALIAS(CMAC_resume); diff --git a/Libraries/libressl/crypto/cms/cms_asn1.c b/Libraries/libressl/crypto/cms/cms_asn1.c new file mode 100644 index 000000000..531b8c587 --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_asn1.c @@ -0,0 +1,1622 @@ +/* $OpenBSD: cms_asn1.c,v 1.23 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "cms_local.h" + + +static const ASN1_TEMPLATE CMS_IssuerAndSerialNumber_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_IssuerAndSerialNumber, issuer), + .field_name = "issuer", + .item = &X509_NAME_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_IssuerAndSerialNumber, serialNumber), + .field_name = "serialNumber", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM CMS_IssuerAndSerialNumber_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_IssuerAndSerialNumber_seq_tt, + .tcount = sizeof(CMS_IssuerAndSerialNumber_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_IssuerAndSerialNumber), + .sname = "CMS_IssuerAndSerialNumber", +}; + +static const ASN1_TEMPLATE CMS_OtherCertificateFormat_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OtherCertificateFormat, otherCertFormat), + .field_name = "otherCertFormat", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_OtherCertificateFormat, otherCert), + .field_name = "otherCert", + .item = &ASN1_ANY_it, + }, +}; + +static const ASN1_ITEM CMS_OtherCertificateFormat_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_OtherCertificateFormat_seq_tt, + .tcount = sizeof(CMS_OtherCertificateFormat_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OtherCertificateFormat), + .sname = "CMS_OtherCertificateFormat", +}; + +static const ASN1_TEMPLATE CMS_CertificateChoices_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_CertificateChoices, d.certificate), + .field_name = "d.certificate", + .item = &X509_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(CMS_CertificateChoices, d.extendedCertificate), + .field_name = "d.extendedCertificate", + .item = &ASN1_SEQUENCE_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 1, + .offset = offsetof(CMS_CertificateChoices, d.v1AttrCert), + .field_name = "d.v1AttrCert", + .item = &ASN1_SEQUENCE_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 2, + .offset = offsetof(CMS_CertificateChoices, d.v2AttrCert), + .field_name = "d.v2AttrCert", + .item = &ASN1_SEQUENCE_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 3, + .offset = offsetof(CMS_CertificateChoices, d.other), + .field_name = "d.other", + .item = &CMS_OtherCertificateFormat_it, + }, +}; + +const ASN1_ITEM CMS_CertificateChoices_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_CertificateChoices, type), + .templates = CMS_CertificateChoices_ch_tt, + .tcount = sizeof(CMS_CertificateChoices_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_CertificateChoices), + .sname = "CMS_CertificateChoices", +}; + +static const ASN1_TEMPLATE CMS_SignerIdentifier_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignerIdentifier, d.issuerAndSerialNumber), + .field_name = "d.issuerAndSerialNumber", + .item = &CMS_IssuerAndSerialNumber_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(CMS_SignerIdentifier, d.subjectKeyIdentifier), + .field_name = "d.subjectKeyIdentifier", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +static const ASN1_ITEM CMS_SignerIdentifier_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_SignerIdentifier, type), + .templates = CMS_SignerIdentifier_ch_tt, + .tcount = sizeof(CMS_SignerIdentifier_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_SignerIdentifier), + .sname = "CMS_SignerIdentifier", +}; + +static const ASN1_TEMPLATE CMS_EncapsulatedContentInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EncapsulatedContentInfo, eContentType), + .field_name = "eContentType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_EncapsulatedContentInfo, eContent), + .field_name = "eContent", + .item = &ASN1_OCTET_STRING_NDEF_it, + }, +}; + +static const ASN1_ITEM CMS_EncapsulatedContentInfo_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_EncapsulatedContentInfo_seq_tt, + .tcount = sizeof(CMS_EncapsulatedContentInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_EncapsulatedContentInfo), + .sname = "CMS_EncapsulatedContentInfo", +}; + +/* Minor tweak to operation: free up signer key, cert */ +static int +cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + CMS_SignerInfo *si = (CMS_SignerInfo *)*pval; + EVP_PKEY_free(si->pkey); + X509_free(si->signer); + EVP_MD_CTX_free(si->mctx); + } + return 1; +} + +static const ASN1_AUX CMS_SignerInfo_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = cms_si_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE CMS_SignerInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignerInfo, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignerInfo, sid), + .field_name = "sid", + .item = &CMS_SignerIdentifier_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignerInfo, digestAlgorithm), + .field_name = "digestAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_SignerInfo, signedAttrs), + .field_name = "signedAttrs", + .item = &X509_ATTRIBUTE_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignerInfo, signatureAlgorithm), + .field_name = "signatureAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignerInfo, signature), + .field_name = "signature", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(CMS_SignerInfo, unsignedAttrs), + .field_name = "unsignedAttrs", + .item = &X509_ATTRIBUTE_it, + }, +}; + +const ASN1_ITEM CMS_SignerInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_SignerInfo_seq_tt, + .tcount = sizeof(CMS_SignerInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &CMS_SignerInfo_aux, + .size = sizeof(CMS_SignerInfo), + .sname = "CMS_SignerInfo", +}; + +static const ASN1_TEMPLATE CMS_OtherRevocationInfoFormat_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OtherRevocationInfoFormat, otherRevInfoFormat), + .field_name = "otherRevInfoFormat", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_OtherRevocationInfoFormat, otherRevInfo), + .field_name = "otherRevInfo", + .item = &ASN1_ANY_it, + }, +}; + +static const ASN1_ITEM CMS_OtherRevocationInfoFormat_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_OtherRevocationInfoFormat_seq_tt, + .tcount = sizeof(CMS_OtherRevocationInfoFormat_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OtherRevocationInfoFormat), + .sname = "CMS_OtherRevocationInfoFormat", +}; + +static const ASN1_TEMPLATE CMS_RevocationInfoChoice_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_RevocationInfoChoice, d.crl), + .field_name = "d.crl", + .item = &X509_CRL_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 1, + .offset = offsetof(CMS_RevocationInfoChoice, d.other), + .field_name = "d.other", + .item = &CMS_OtherRevocationInfoFormat_it, + }, +}; + +const ASN1_ITEM CMS_RevocationInfoChoice_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_RevocationInfoChoice, type), + .templates = CMS_RevocationInfoChoice_ch_tt, + .tcount = sizeof(CMS_RevocationInfoChoice_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_RevocationInfoChoice), + .sname = "CMS_RevocationInfoChoice", +}; + +static const ASN1_TEMPLATE CMS_SignedData_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignedData, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(CMS_SignedData, digestAlgorithms), + .field_name = "digestAlgorithms", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SignedData, encapContentInfo), + .field_name = "encapContentInfo", + .item = &CMS_EncapsulatedContentInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_SignedData, certificates), + .field_name = "certificates", + .item = &CMS_CertificateChoices_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(CMS_SignedData, crls), + .field_name = "crls", + .item = &CMS_RevocationInfoChoice_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(CMS_SignedData, signerInfos), + .field_name = "signerInfos", + .item = &CMS_SignerInfo_it, + }, +}; + +const ASN1_ITEM CMS_SignedData_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_SignedData_seq_tt, + .tcount = sizeof(CMS_SignedData_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_SignedData), + .sname = "CMS_SignedData", +}; + +static const ASN1_TEMPLATE CMS_OriginatorInfo_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_OriginatorInfo, certificates), + .field_name = "certificates", + .item = &CMS_CertificateChoices_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(CMS_OriginatorInfo, crls), + .field_name = "crls", + .item = &CMS_RevocationInfoChoice_it, + }, +}; + +static const ASN1_ITEM CMS_OriginatorInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_OriginatorInfo_seq_tt, + .tcount = sizeof(CMS_OriginatorInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OriginatorInfo), + .sname = "CMS_OriginatorInfo", +}; + +static const ASN1_TEMPLATE CMS_EncryptedContentInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EncryptedContentInfo, contentType), + .field_name = "contentType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EncryptedContentInfo, contentEncryptionAlgorithm), + .field_name = "contentEncryptionAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_EncryptedContentInfo, encryptedContent), + .field_name = "encryptedContent", + .item = &ASN1_OCTET_STRING_NDEF_it, + }, +}; + +static const ASN1_ITEM CMS_EncryptedContentInfo_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_EncryptedContentInfo_seq_tt, + .tcount = sizeof(CMS_EncryptedContentInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_EncryptedContentInfo), + .sname = "CMS_EncryptedContentInfo", +}; + +static const ASN1_TEMPLATE CMS_KeyTransRecipientInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyTransRecipientInfo, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyTransRecipientInfo, rid), + .field_name = "rid", + .item = &CMS_SignerIdentifier_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm), + .field_name = "keyEncryptionAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyTransRecipientInfo, encryptedKey), + .field_name = "encryptedKey", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM CMS_KeyTransRecipientInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_KeyTransRecipientInfo_seq_tt, + .tcount = sizeof(CMS_KeyTransRecipientInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_KeyTransRecipientInfo), + .sname = "CMS_KeyTransRecipientInfo", +}; + +static const ASN1_TEMPLATE CMS_OtherKeyAttribute_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OtherKeyAttribute, keyAttrId), + .field_name = "keyAttrId", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_OtherKeyAttribute, keyAttr), + .field_name = "keyAttr", + .item = &ASN1_ANY_it, + }, +}; + +const ASN1_ITEM CMS_OtherKeyAttribute_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_OtherKeyAttribute_seq_tt, + .tcount = sizeof(CMS_OtherKeyAttribute_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OtherKeyAttribute), + .sname = "CMS_OtherKeyAttribute", +}; + +static const ASN1_TEMPLATE CMS_RecipientKeyIdentifier_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_RecipientKeyIdentifier, subjectKeyIdentifier), + .field_name = "subjectKeyIdentifier", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_RecipientKeyIdentifier, date), + .field_name = "date", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_RecipientKeyIdentifier, other), + .field_name = "other", + .item = &CMS_OtherKeyAttribute_it, + }, +}; + +const ASN1_ITEM CMS_RecipientKeyIdentifier_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_RecipientKeyIdentifier_seq_tt, + .tcount = sizeof(CMS_RecipientKeyIdentifier_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_RecipientKeyIdentifier), + .sname = "CMS_RecipientKeyIdentifier", +}; + +static const ASN1_TEMPLATE CMS_KeyAgreeRecipientIdentifier_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber), + .field_name = "d.issuerAndSerialNumber", + .item = &CMS_IssuerAndSerialNumber_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(CMS_KeyAgreeRecipientIdentifier, d.rKeyId), + .field_name = "d.rKeyId", + .item = &CMS_RecipientKeyIdentifier_it, + }, +}; + +static const ASN1_ITEM CMS_KeyAgreeRecipientIdentifier_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_KeyAgreeRecipientIdentifier, type), + .templates = CMS_KeyAgreeRecipientIdentifier_ch_tt, + .tcount = sizeof(CMS_KeyAgreeRecipientIdentifier_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_KeyAgreeRecipientIdentifier), + .sname = "CMS_KeyAgreeRecipientIdentifier", +}; + +static int +cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval; + if (operation == ASN1_OP_FREE_POST) { + EVP_PKEY_free(rek->pkey); + } + return 1; +} + +static const ASN1_AUX CMS_RecipientEncryptedKey_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = cms_rek_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE CMS_RecipientEncryptedKey_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_RecipientEncryptedKey, rid), + .field_name = "rid", + .item = &CMS_KeyAgreeRecipientIdentifier_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_RecipientEncryptedKey, encryptedKey), + .field_name = "encryptedKey", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM CMS_RecipientEncryptedKey_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_RecipientEncryptedKey_seq_tt, + .tcount = sizeof(CMS_RecipientEncryptedKey_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &CMS_RecipientEncryptedKey_aux, + .size = sizeof(CMS_RecipientEncryptedKey), + .sname = "CMS_RecipientEncryptedKey", +}; + +static const ASN1_TEMPLATE CMS_OriginatorPublicKey_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OriginatorPublicKey, algorithm), + .field_name = "algorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OriginatorPublicKey, publicKey), + .field_name = "publicKey", + .item = &ASN1_BIT_STRING_it, + }, +}; + +const ASN1_ITEM CMS_OriginatorPublicKey_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_OriginatorPublicKey_seq_tt, + .tcount = sizeof(CMS_OriginatorPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OriginatorPublicKey), + .sname = "CMS_OriginatorPublicKey", +}; + +static const ASN1_TEMPLATE CMS_OriginatorIdentifierOrKey_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber), + .field_name = "d.issuerAndSerialNumber", + .item = &CMS_IssuerAndSerialNumber_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier), + .field_name = "d.subjectKeyIdentifier", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 1, + .offset = offsetof(CMS_OriginatorIdentifierOrKey, d.originatorKey), + .field_name = "d.originatorKey", + .item = &CMS_OriginatorPublicKey_it, + }, +}; + +static const ASN1_ITEM CMS_OriginatorIdentifierOrKey_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_OriginatorIdentifierOrKey, type), + .templates = CMS_OriginatorIdentifierOrKey_ch_tt, + .tcount = sizeof(CMS_OriginatorIdentifierOrKey_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OriginatorIdentifierOrKey), + .sname = "CMS_OriginatorIdentifierOrKey", +}; + +static int +cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval; + if (operation == ASN1_OP_NEW_POST) { + kari->ctx = EVP_CIPHER_CTX_new(); + if (kari->ctx == NULL) + return 0; + EVP_CIPHER_CTX_set_flags(kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + kari->pctx = NULL; + } else if (operation == ASN1_OP_FREE_POST) { + EVP_PKEY_CTX_free(kari->pctx); + EVP_CIPHER_CTX_free(kari->ctx); + } + return 1; +} + +static const ASN1_AUX CMS_KeyAgreeRecipientInfo_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = cms_kari_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE CMS_KeyAgreeRecipientInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyAgreeRecipientInfo, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(CMS_KeyAgreeRecipientInfo, originator), + .field_name = "originator", + .item = &CMS_OriginatorIdentifierOrKey_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(CMS_KeyAgreeRecipientInfo, ukm), + .field_name = "ukm", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm), + .field_name = "keyEncryptionAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys), + .field_name = "recipientEncryptedKeys", + .item = &CMS_RecipientEncryptedKey_it, + }, +}; + +const ASN1_ITEM CMS_KeyAgreeRecipientInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_KeyAgreeRecipientInfo_seq_tt, + .tcount = sizeof(CMS_KeyAgreeRecipientInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &CMS_KeyAgreeRecipientInfo_aux, + .size = sizeof(CMS_KeyAgreeRecipientInfo), + .sname = "CMS_KeyAgreeRecipientInfo", +}; + +static const ASN1_TEMPLATE CMS_KEKIdentifier_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KEKIdentifier, keyIdentifier), + .field_name = "keyIdentifier", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_KEKIdentifier, date), + .field_name = "date", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_KEKIdentifier, other), + .field_name = "other", + .item = &CMS_OtherKeyAttribute_it, + }, +}; + +static const ASN1_ITEM CMS_KEKIdentifier_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_KEKIdentifier_seq_tt, + .tcount = sizeof(CMS_KEKIdentifier_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_KEKIdentifier), + .sname = "CMS_KEKIdentifier", +}; + +static const ASN1_TEMPLATE CMS_KEKRecipientInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KEKRecipientInfo, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KEKRecipientInfo, kekid), + .field_name = "kekid", + .item = &CMS_KEKIdentifier_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KEKRecipientInfo, keyEncryptionAlgorithm), + .field_name = "keyEncryptionAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_KEKRecipientInfo, encryptedKey), + .field_name = "encryptedKey", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM CMS_KEKRecipientInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_KEKRecipientInfo_seq_tt, + .tcount = sizeof(CMS_KEKRecipientInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_KEKRecipientInfo), + .sname = "CMS_KEKRecipientInfo", +}; + +static const ASN1_TEMPLATE CMS_PasswordRecipientInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_PasswordRecipientInfo, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_PasswordRecipientInfo, keyDerivationAlgorithm), + .field_name = "keyDerivationAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm), + .field_name = "keyEncryptionAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_PasswordRecipientInfo, encryptedKey), + .field_name = "encryptedKey", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM CMS_PasswordRecipientInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_PasswordRecipientInfo_seq_tt, + .tcount = sizeof(CMS_PasswordRecipientInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_PasswordRecipientInfo), + .sname = "CMS_PasswordRecipientInfo", +}; + +static const ASN1_TEMPLATE CMS_OtherRecipientInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_OtherRecipientInfo, oriType), + .field_name = "oriType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_OtherRecipientInfo, oriValue), + .field_name = "oriValue", + .item = &ASN1_ANY_it, + }, +}; + +static const ASN1_ITEM CMS_OtherRecipientInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_OtherRecipientInfo_seq_tt, + .tcount = sizeof(CMS_OtherRecipientInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_OtherRecipientInfo), + .sname = "CMS_OtherRecipientInfo", +}; + +/* Free up RecipientInfo additional data */ +static int +cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_FREE_PRE) { + CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval; + if (ri->type == CMS_RECIPINFO_TRANS) { + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY_free(ktri->pkey); + X509_free(ktri->recip); + EVP_PKEY_CTX_free(ktri->pctx); + } else if (ri->type == CMS_RECIPINFO_KEK) { + CMS_KEKRecipientInfo *kekri = ri->d.kekri; + freezero(kekri->key, kekri->keylen); + } else if (ri->type == CMS_RECIPINFO_PASS) { + CMS_PasswordRecipientInfo *pwri = ri->d.pwri; + freezero(pwri->pass, pwri->passlen); + } + } + return 1; +} + +static const ASN1_AUX CMS_RecipientInfo_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = cms_ri_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE CMS_RecipientInfo_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_RecipientInfo, d.ktri), + .field_name = "d.ktri", + .item = &CMS_KeyTransRecipientInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 1, + .offset = offsetof(CMS_RecipientInfo, d.kari), + .field_name = "d.kari", + .item = &CMS_KeyAgreeRecipientInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 2, + .offset = offsetof(CMS_RecipientInfo, d.kekri), + .field_name = "d.kekri", + .item = &CMS_KEKRecipientInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 3, + .offset = offsetof(CMS_RecipientInfo, d.pwri), + .field_name = "d.pwri", + .item = &CMS_PasswordRecipientInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 4, + .offset = offsetof(CMS_RecipientInfo, d.ori), + .field_name = "d.ori", + .item = &CMS_OtherRecipientInfo_it, + }, +}; + +const ASN1_ITEM CMS_RecipientInfo_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_RecipientInfo, type), + .templates = CMS_RecipientInfo_ch_tt, + .tcount = sizeof(CMS_RecipientInfo_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &CMS_RecipientInfo_aux, + .size = sizeof(CMS_RecipientInfo), + .sname = "CMS_RecipientInfo", +}; + +static const ASN1_TEMPLATE CMS_EnvelopedData_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EnvelopedData, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_EnvelopedData, originatorInfo), + .field_name = "originatorInfo", + .item = &CMS_OriginatorInfo_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(CMS_EnvelopedData, recipientInfos), + .field_name = "recipientInfos", + .item = &CMS_RecipientInfo_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EnvelopedData, encryptedContentInfo), + .field_name = "encryptedContentInfo", + .item = &CMS_EncryptedContentInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(CMS_EnvelopedData, unprotectedAttrs), + .field_name = "unprotectedAttrs", + .item = &X509_ATTRIBUTE_it, + }, +}; + +const ASN1_ITEM CMS_EnvelopedData_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_EnvelopedData_seq_tt, + .tcount = sizeof(CMS_EnvelopedData_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_EnvelopedData), + .sname = "CMS_EnvelopedData", +}; + +static const ASN1_TEMPLATE CMS_DigestedData_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_DigestedData, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_DigestedData, digestAlgorithm), + .field_name = "digestAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_DigestedData, encapContentInfo), + .field_name = "encapContentInfo", + .item = &CMS_EncapsulatedContentInfo_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_DigestedData, digest), + .field_name = "digest", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM CMS_DigestedData_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_DigestedData_seq_tt, + .tcount = sizeof(CMS_DigestedData_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_DigestedData), + .sname = "CMS_DigestedData", +}; + +static const ASN1_TEMPLATE CMS_EncryptedData_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EncryptedData, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_EncryptedData, encryptedContentInfo), + .field_name = "encryptedContentInfo", + .item = &CMS_EncryptedContentInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(CMS_EncryptedData, unprotectedAttrs), + .field_name = "unprotectedAttrs", + .item = &X509_ATTRIBUTE_it, + }, +}; + +const ASN1_ITEM CMS_EncryptedData_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_EncryptedData_seq_tt, + .tcount = sizeof(CMS_EncryptedData_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_EncryptedData), + .sname = "CMS_EncryptedData", +}; + +static const ASN1_TEMPLATE CMS_AuthenticatedData_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_AuthenticatedData, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_AuthenticatedData, originatorInfo), + .field_name = "originatorInfo", + .item = &CMS_OriginatorInfo_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(CMS_AuthenticatedData, recipientInfos), + .field_name = "recipientInfos", + .item = &CMS_RecipientInfo_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_AuthenticatedData, macAlgorithm), + .field_name = "macAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 1, + .offset = offsetof(CMS_AuthenticatedData, digestAlgorithm), + .field_name = "digestAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_AuthenticatedData, encapContentInfo), + .field_name = "encapContentInfo", + .item = &CMS_EncapsulatedContentInfo_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(CMS_AuthenticatedData, authAttrs), + .field_name = "authAttrs", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_AuthenticatedData, mac), + .field_name = "mac", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 3, + .offset = offsetof(CMS_AuthenticatedData, unauthAttrs), + .field_name = "unauthAttrs", + .item = &X509_ALGOR_it, + }, +}; + +static const ASN1_ITEM CMS_AuthenticatedData_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_AuthenticatedData_seq_tt, + .tcount = sizeof(CMS_AuthenticatedData_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_AuthenticatedData), + .sname = "CMS_AuthenticatedData", +}; + +static const ASN1_TEMPLATE CMS_CompressedData_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_CompressedData, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_CompressedData, compressionAlgorithm), + .field_name = "compressionAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_CompressedData, encapContentInfo), + .field_name = "encapContentInfo", + .item = &CMS_EncapsulatedContentInfo_it, + }, +}; + +const ASN1_ITEM CMS_CompressedData_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_CompressedData_seq_tt, + .tcount = sizeof(CMS_CompressedData_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_CompressedData), + .sname = "CMS_CompressedData", +}; + +/* This is the ANY DEFINED BY table for the top level ContentInfo structure */ + +static const ASN1_TEMPLATE cms_default_tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.other), + .field_name = "d.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE CMS_ContentInfo_adbtbl[] = { + { + .value = NID_pkcs7_data, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.data), + .field_name = "d.data", + .item = &ASN1_OCTET_STRING_NDEF_it, + }, + }, + { + .value = NID_pkcs7_signed, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.signedData), + .field_name = "d.signedData", + .item = &CMS_SignedData_it, + }, + }, + { + .value = NID_pkcs7_enveloped, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.envelopedData), + .field_name = "d.envelopedData", + .item = &CMS_EnvelopedData_it, + }, + }, + { + .value = NID_pkcs7_digest, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.digestedData), + .field_name = "d.digestedData", + .item = &CMS_DigestedData_it, + }, + }, + { + .value = NID_pkcs7_encrypted, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.encryptedData), + .field_name = "d.encryptedData", + .item = &CMS_EncryptedData_it, + }, + }, + { + .value = NID_id_smime_ct_authData, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.authenticatedData), + .field_name = "d.authenticatedData", + .item = &CMS_AuthenticatedData_it, + }, + }, + { + .value = NID_id_smime_ct_compressedData, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, d.compressedData), + .field_name = "d.compressedData", + .item = &CMS_CompressedData_it, + }, + }, +}; + +static const ASN1_ADB CMS_ContentInfo_adb = { + .flags = 0, + .offset = offsetof(CMS_ContentInfo, contentType), + .tbl = CMS_ContentInfo_adbtbl, + .tblcount = sizeof(CMS_ContentInfo_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &cms_default_tt, + .null_tt = NULL, +}; + +/* CMS streaming support */ +static int +cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + CMS_ContentInfo *cms = NULL; + + if (pval) + cms = (CMS_ContentInfo *)*pval; + else + return 1; + + switch (operation) { + case ASN1_OP_STREAM_PRE: + if (CMS_stream(&sarg->boundary, cms) <= 0) + return 0; + /* FALLTHROUGH */ + + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = CMS_dataInit(cms, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0) + return 0; + break; + } + + return 1; +} + +static const ASN1_AUX CMS_ContentInfo_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = cms_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE CMS_ContentInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_ContentInfo, contentType), + .field_name = "contentType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "CMS_ContentInfo", + .item = (const ASN1_ITEM *)&CMS_ContentInfo_adb, + }, +}; + +const ASN1_ITEM CMS_ContentInfo_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_ContentInfo_seq_tt, + .tcount = sizeof(CMS_ContentInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &CMS_ContentInfo_aux, + .size = sizeof(CMS_ContentInfo), + .sname = "CMS_ContentInfo", +}; + +/* Specials for signed attributes */ + +/* + * When signing attributes we want to reorder them to match the sorted + * encoding. + */ + +static const ASN1_TEMPLATE CMS_Attributes_Sign_item_tt = { + .flags = ASN1_TFLG_SET_ORDER, + .tag = 0, + .offset = 0, + .field_name = "CMS_ATTRIBUTES", + .item = &X509_ATTRIBUTE_it, +}; + +const ASN1_ITEM CMS_Attributes_Sign_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &CMS_Attributes_Sign_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "CMS_Attributes_Sign", +}; + +/* + * When verifying attributes we need to use the received order. So we use + * SEQUENCE OF and tag it to SET OF + */ + +static const ASN1_TEMPLATE CMS_Attributes_Verify_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, + .tag = V_ASN1_SET, + .offset = 0, + .field_name = "CMS_ATTRIBUTES", + .item = &X509_ATTRIBUTE_it, +}; + +const ASN1_ITEM CMS_Attributes_Verify_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &CMS_Attributes_Verify_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "CMS_Attributes_Verify", +}; + + + +static const ASN1_TEMPLATE CMS_ReceiptsFrom_ch_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(CMS_ReceiptsFrom, d.allOrFirstTier), + .field_name = "d.allOrFirstTier", + .item = &LONG_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF, + .tag = 1, + .offset = offsetof(CMS_ReceiptsFrom, d.receiptList), + .field_name = "d.receiptList", + .item = &GENERAL_NAMES_it, + }, +}; + +static const ASN1_ITEM CMS_ReceiptsFrom_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(CMS_ReceiptsFrom, type), + .templates = CMS_ReceiptsFrom_ch_tt, + .tcount = sizeof(CMS_ReceiptsFrom_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_ReceiptsFrom), + .sname = "CMS_ReceiptsFrom", +}; + +static const ASN1_TEMPLATE CMS_ReceiptRequest_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_ReceiptRequest, signedContentIdentifier), + .field_name = "signedContentIdentifier", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_ReceiptRequest, receiptsFrom), + .field_name = "receiptsFrom", + .item = &CMS_ReceiptsFrom_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(CMS_ReceiptRequest, receiptsTo), + .field_name = "receiptsTo", + .item = &GENERAL_NAMES_it, + }, +}; + +const ASN1_ITEM CMS_ReceiptRequest_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_ReceiptRequest_seq_tt, + .tcount = sizeof(CMS_ReceiptRequest_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_ReceiptRequest), + .sname = "CMS_ReceiptRequest", +}; + +static const ASN1_TEMPLATE CMS_Receipt_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_Receipt, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_Receipt, contentType), + .field_name = "contentType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_Receipt, signedContentIdentifier), + .field_name = "signedContentIdentifier", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_Receipt, originatorSignatureValue), + .field_name = "originatorSignatureValue", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM CMS_Receipt_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_Receipt_seq_tt, + .tcount = sizeof(CMS_Receipt_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_Receipt), + .sname = "CMS_Receipt", +}; + +/* + * Utilities to encode the CMS_SharedInfo structure used during key + * derivation. + */ + +typedef struct { + X509_ALGOR *keyInfo; + ASN1_OCTET_STRING *entityUInfo; + ASN1_OCTET_STRING *suppPubInfo; +} CMS_SharedInfo; + +static const ASN1_TEMPLATE CMS_SharedInfo_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(CMS_SharedInfo, keyInfo), + .field_name = "keyInfo", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(CMS_SharedInfo, entityUInfo), + .field_name = "entityUInfo", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(CMS_SharedInfo, suppPubInfo), + .field_name = "suppPubInfo", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +static const ASN1_ITEM CMS_SharedInfo_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = CMS_SharedInfo_seq_tt, + .tcount = sizeof(CMS_SharedInfo_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(CMS_SharedInfo), + .sname = "CMS_SharedInfo", +}; + +int +CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen) +{ + union { + CMS_SharedInfo *pecsi; + ASN1_VALUE *a; + } intsi = { + NULL + }; + + ASN1_OCTET_STRING oklen; + unsigned char kl[4]; + CMS_SharedInfo ecsi; + + keylen <<= 3; + kl[0] = (keylen >> 24) & 0xff; + kl[1] = (keylen >> 16) & 0xff; + kl[2] = (keylen >> 8) & 0xff; + kl[3] = keylen & 0xff; + oklen.length = 4; + oklen.data = kl; + oklen.type = V_ASN1_OCTET_STRING; + oklen.flags = 0; + ecsi.keyInfo = kekalg; + ecsi.entityUInfo = ukm; + ecsi.suppPubInfo = &oklen; + intsi.pecsi = &ecsi; + + return ASN1_item_i2d(intsi.a, pder, &CMS_SharedInfo_it); +} +LCRYPTO_ALIAS(CMS_SharedInfo_encode); diff --git a/Libraries/libressl/crypto/cms/cms_att.c b/Libraries/libressl/crypto/cms/cms_att.c new file mode 100644 index 000000000..62362ad3f --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_att.c @@ -0,0 +1,231 @@ +/* $OpenBSD: cms_att.c,v 1.11 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "cms_local.h" + +/* CMS SignedData Attribute utilities */ + +int +CMS_signed_get_attr_count(const CMS_SignerInfo *si) +{ + return X509at_get_attr_count(si->signedAttrs); +} +LCRYPTO_ALIAS(CMS_signed_get_attr_count); + +int +CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos); +} +LCRYPTO_ALIAS(CMS_signed_get_attr_by_NID); + +int +CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos); +} +LCRYPTO_ALIAS(CMS_signed_get_attr_by_OBJ); + +X509_ATTRIBUTE * +CMS_signed_get_attr(const CMS_SignerInfo *si, int loc) +{ + return X509at_get_attr(si->signedAttrs, loc); +} +LCRYPTO_ALIAS(CMS_signed_get_attr); + +X509_ATTRIBUTE * +CMS_signed_delete_attr(CMS_SignerInfo *si, int loc) +{ + return X509at_delete_attr(si->signedAttrs, loc); +} +LCRYPTO_ALIAS(CMS_signed_delete_attr); + +int +CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&si->signedAttrs, attr)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_signed_add1_attr); + +int +CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *obj, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_signed_add1_attr_by_OBJ); + +int +CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, int nid, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_signed_add1_attr_by_NID); + +int +CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, const char *attrname, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_signed_add1_attr_by_txt); + +void * +CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, + int lastpos, int type) +{ + return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type); +} +LCRYPTO_ALIAS(CMS_signed_get0_data_by_OBJ); + +int +CMS_unsigned_get_attr_count(const CMS_SignerInfo *si) +{ + return X509at_get_attr_count(si->unsignedAttrs); +} +LCRYPTO_ALIAS(CMS_unsigned_get_attr_count); + +int +CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos); +} +LCRYPTO_ALIAS(CMS_unsigned_get_attr_by_NID); + +int +CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos); +} +LCRYPTO_ALIAS(CMS_unsigned_get_attr_by_OBJ); + +X509_ATTRIBUTE * +CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc) +{ + return X509at_get_attr(si->unsignedAttrs, loc); +} +LCRYPTO_ALIAS(CMS_unsigned_get_attr); + +X509_ATTRIBUTE * +CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc) +{ + return X509at_delete_attr(si->unsignedAttrs, loc); +} +LCRYPTO_ALIAS(CMS_unsigned_delete_attr); + +int +CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&si->unsignedAttrs, attr)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_unsigned_add1_attr); + +int +CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int type, const void *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_unsigned_add1_attr_by_OBJ); + +int +CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, int nid, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_unsigned_add1_attr_by_NID); + +int +CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, const char *attrname, + int type, const void *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname, type, + bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(CMS_unsigned_add1_attr_by_txt); + +void * +CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, int lastpos, + int type) +{ + return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type); +} +LCRYPTO_ALIAS(CMS_unsigned_get0_data_by_OBJ); + +/* Specific attribute cases */ diff --git a/Libraries/libressl/crypto/cms/cms_dd.c b/Libraries/libressl/crypto/cms/cms_dd.c new file mode 100644 index 000000000..a08fccc2a --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_dd.c @@ -0,0 +1,150 @@ +/* $OpenBSD: cms_dd.c,v 1.15 2022/11/26 16:08:51 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "cms_local.h" + +/* CMS DigestedData Utilities */ + +CMS_ContentInfo * +cms_DigestedData_create(const EVP_MD *md) +{ + CMS_ContentInfo *cms; + CMS_DigestedData *dd; + + cms = CMS_ContentInfo_new(); + if (cms == NULL) + return NULL; + + dd = (CMS_DigestedData *)ASN1_item_new(&CMS_DigestedData_it); + + if (dd == NULL) + goto err; + + cms->contentType = OBJ_nid2obj(NID_pkcs7_digest); + cms->d.digestedData = dd; + + dd->version = 0; + dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); + + X509_ALGOR_set_md(dd->digestAlgorithm, md); + + return cms; + + err: + CMS_ContentInfo_free(cms); + + return NULL; +} + +BIO * +cms_DigestedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_DigestedData *dd; + + dd = cms->d.digestedData; + + return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); +} + +int +cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) +{ + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + int r = 0; + CMS_DigestedData *dd; + + if (mctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + dd = cms->d.digestedData; + + if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm)) + goto err; + + if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0) + goto err; + + if (verify) { + if (mdlen != (unsigned int)dd->digest->length) { + CMSerror(CMS_R_MESSAGEDIGEST_WRONG_LENGTH); + goto err; + } + + if (memcmp(md, dd->digest->data, mdlen)) + CMSerror(CMS_R_VERIFICATION_FAILURE); + else + r = 1; + } else { + if (!ASN1_STRING_set(dd->digest, md, mdlen)) + goto err; + r = 1; + } + + err: + EVP_MD_CTX_free(mctx); + + return r; +} diff --git a/Libraries/libressl/crypto/cms/cms_enc.c b/Libraries/libressl/crypto/cms/cms_enc.c new file mode 100644 index 000000000..547f9ff74 --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_enc.c @@ -0,0 +1,263 @@ +/* $OpenBSD: cms_enc.c,v 1.23 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_local.h" + +/* CMS EncryptedData Utilities */ + +/* Return BIO based on EncryptedContentInfo and key */ + +BIO * +cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) +{ + BIO *b; + EVP_CIPHER_CTX *ctx; + const EVP_CIPHER *ciph; + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; + unsigned char *tkey = NULL; + size_t tkeylen = 0; + + int ok = 0; + + int enc, keep_key = 0; + + enc = ec->cipher ? 1 : 0; + + b = BIO_new(BIO_f_cipher()); + if (b == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + BIO_get_cipher_ctx(b, &ctx); + + if (enc) { + ciph = ec->cipher; + /* + * If not keeping key set cipher to NULL so subsequent calls decrypt. + */ + if (ec->key) + ec->cipher = NULL; + } else { + ciph = EVP_get_cipherbyobj(calg->algorithm); + + if (!ciph) { + CMSerror(CMS_R_UNKNOWN_CIPHER); + goto err; + } + } + + if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { + CMSerror(CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + + if (enc) { + int ivlen; + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + /* Generate a random IV if we need one */ + ivlen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivlen > 0) { + arc4random_buf(iv, ivlen); + piv = iv; + } + } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { + CMSerror(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + if (!enc || !ec->key) { + tkey = malloc(tkeylen); + if (tkey == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) + goto err; + } + + if (!ec->key) { + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + if (enc) + keep_key = 1; + else + ERR_clear_error(); + + } + + if (ec->keylen != tkeylen) { + /* If necessary set key length */ + if (!EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen)) { + /* + * Only reveal failure if debugging so we don't leak information + * which may be useful in MMA. + */ + if (enc || ec->debug) { + CMSerror(CMS_R_INVALID_KEY_LENGTH); + goto err; + } else { + /* Use random key */ + freezero(ec->key, ec->keylen); + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + ERR_clear_error(); + } + } + } + + if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { + CMSerror(CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + if (enc) { + calg->parameter = ASN1_TYPE_new(); + if (calg->parameter == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { + CMSerror(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + /* If parameter type not set omit parameter */ + if (calg->parameter->type == V_ASN1_UNDEF) { + ASN1_TYPE_free(calg->parameter); + calg->parameter = NULL; + } + } + ok = 1; + + err: + if (!keep_key || !ok) { + freezero(ec->key, ec->keylen); + ec->key = NULL; + } + freezero(tkey, tkeylen); + if (ok) + return b; + BIO_free(b); + return NULL; +} + +int +cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen) +{ + ec->cipher = cipher; + if (key) { + if ((ec->key = malloc(keylen)) == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(ec->key, key, keylen); + } + ec->keylen = keylen; + if (cipher) + ec->contentType = OBJ_nid2obj(NID_pkcs7_data); + + return 1; +} + +int +CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen) +{ + CMS_EncryptedContentInfo *ec; + + if (!key || !keylen) { + CMSerror(CMS_R_NO_KEY); + return 0; + } + if (ciph) { + cms->d.encryptedData = (CMS_EncryptedData *)ASN1_item_new(&CMS_EncryptedData_it); + if (!cms->d.encryptedData) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); + cms->d.encryptedData->version = 0; + } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) { + CMSerror(CMS_R_NOT_ENCRYPTED_DATA); + return 0; + } + ec = cms->d.encryptedData->encryptedContentInfo; + + return cms_EncryptedContent_init(ec, ciph, key, keylen); +} +LCRYPTO_ALIAS(CMS_EncryptedData_set1_key); + +BIO * +cms_EncryptedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedData *enc = cms->d.encryptedData; + + if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) + enc->version = 2; + + return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); +} diff --git a/Libraries/libressl/crypto/cms/cms_env.c b/Libraries/libressl/crypto/cms/cms_env.c new file mode 100644 index 000000000..7bb8f613a --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_env.c @@ -0,0 +1,994 @@ +/* $OpenBSD: cms_env.c,v 1.26 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_local.h" +#include "asn1/asn1_local.h" +#include "evp/evp_local.h" + +/* CMS EnvelopedData Utilities */ + +CMS_EnvelopedData * +cms_get0_enveloped(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { + CMSerror(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return NULL; + } + return cms->d.envelopedData; +} + +static CMS_EnvelopedData * +cms_enveloped_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.envelopedData = (CMS_EnvelopedData *)ASN1_item_new(&CMS_EnvelopedData_it); + if (!cms->d.envelopedData) { + CMSerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + cms->d.envelopedData->version = 0; + cms->d.envelopedData->encryptedContentInfo->contentType = + OBJ_nid2obj(NID_pkcs7_data); + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); + return cms->d.envelopedData; + } + return cms_get0_enveloped(cms); +} + +int +cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) +{ + EVP_PKEY *pkey; + int i; + + if (ri->type == CMS_RECIPINFO_TRANS) + pkey = ri->d.ktri->pkey; + else if (ri->type == CMS_RECIPINFO_AGREE) { + EVP_PKEY_CTX *pctx = ri->d.kari->pctx; + if (!pctx) + return 0; + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!pkey) + return 0; + } else + return 0; + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return 1; + i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); + if (i == -2) { + CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + if (i <= 0) { + CMSerror(CMS_R_CTRL_FAILURE); + return 0; + } + + return 1; +} + +STACK_OF(CMS_RecipientInfo) * +CMS_get0_RecipientInfos(CMS_ContentInfo *cms) +{ + CMS_EnvelopedData *env; + + env = cms_get0_enveloped(cms); + if (!env) + return NULL; + + return env->recipientInfos; +} +LCRYPTO_ALIAS(CMS_get0_RecipientInfos); + +int +CMS_RecipientInfo_type(CMS_RecipientInfo *ri) +{ + return ri->type; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_type); + +EVP_PKEY_CTX * +CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) +{ + if (ri->type == CMS_RECIPINFO_TRANS) + return ri->d.ktri->pctx; + else if (ri->type == CMS_RECIPINFO_AGREE) + return ri->d.kari->pctx; + + return NULL; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_get0_pkey_ctx); + +CMS_ContentInfo * +CMS_EnvelopedData_create(const EVP_CIPHER *cipher) +{ + CMS_ContentInfo *cms; + CMS_EnvelopedData *env; + + cms = CMS_ContentInfo_new(); + if (cms == NULL) + goto merr; + env = cms_enveloped_data_init(cms); + if (env == NULL) + goto merr; + if (!cms_EncryptedContent_init(env->encryptedContentInfo, cipher, + NULL, 0)) + goto merr; + + return cms; + + merr: + CMS_ContentInfo_free(cms); + CMSerror(ERR_R_MALLOC_FAILURE); + return NULL; +} +LCRYPTO_ALIAS(CMS_EnvelopedData_create); + +/* Key Transport Recipient Info (KTRI) routines */ + +/* Initialise a ktri based on passed certificate and key */ + +static int +cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, + unsigned int flags) +{ + CMS_KeyTransRecipientInfo *ktri; + int idtype; + + ri->d.ktri = (CMS_KeyTransRecipientInfo *)ASN1_item_new(&CMS_KeyTransRecipientInfo_it); + if (!ri->d.ktri) + return 0; + ri->type = CMS_RECIPINFO_TRANS; + + ktri = ri->d.ktri; + + if (flags & CMS_USE_KEYID) { + ktri->version = 2; + idtype = CMS_RECIPINFO_KEYIDENTIFIER; + } else { + ktri->version = 0; + idtype = CMS_RECIPINFO_ISSUER_SERIAL; + } + + /* + * Not a typo: RecipientIdentifier and SignerIdentifier are the same + * structure. + */ + + if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) + return 0; + + X509_up_ref(recip); + EVP_PKEY_up_ref(pk); + + ktri->pkey = pk; + ktri->recip = recip; + + if (flags & CMS_KEY_PARAM) { + ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (ktri->pctx == NULL) + return 0; + if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) + return 0; + } else if (!cms_env_asn1_ctrl(ri, 0)) + return 0; + + return 1; +} + +/* + * Add a recipient certificate using appropriate type of RecipientInfo + */ + +CMS_RecipientInfo * +CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + EVP_PKEY *pk = NULL; + + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + /* Initialize recipient info */ + ri = (CMS_RecipientInfo *)ASN1_item_new(&CMS_RecipientInfo_it); + if (!ri) + goto merr; + + pk = X509_get0_pubkey(recip); + if (!pk) { + CMSerror(CMS_R_ERROR_GETTING_PUBLIC_KEY); + goto err; + } + + switch (cms_pkey_get_ri_type(pk)) { + + case CMS_RECIPINFO_TRANS: + if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) + goto err; + break; + + case CMS_RECIPINFO_AGREE: + if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) + goto err; + break; + + default: + CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + return ri; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + err: + ASN1_item_free((ASN1_VALUE *)ri, &CMS_RecipientInfo_it); + return NULL; +} +LCRYPTO_ALIAS(CMS_add1_recipient_cert); + +int +CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, EVP_PKEY **pk, + X509 **recip, X509_ALGOR **palg) +{ + CMS_KeyTransRecipientInfo *ktri; + + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerror(CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + + ktri = ri->d.ktri; + + if (pk) + *pk = ktri->pkey; + if (recip) + *recip = ktri->recip; + if (palg) + *palg = ktri->keyEncryptionAlgorithm; + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_ktri_get0_algs); + +int +CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) +{ + CMS_KeyTransRecipientInfo *ktri; + + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerror(CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ktri = ri->d.ktri; + + return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); +} +LCRYPTO_ALIAS(CMS_RecipientInfo_ktri_get0_signer_id); + +int +CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) +{ + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerror(CMS_R_NOT_KEY_TRANSPORT); + return -2; + } + + return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); +} +LCRYPTO_ALIAS(CMS_RecipientInfo_ktri_cert_cmp); + +int +CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) +{ + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerror(CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + EVP_PKEY_free(ri->d.ktri->pkey); + ri->d.ktri->pkey = pkey; + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_set0_pkey); + +/* Encrypt content key in key transport recipient info */ + +static int +cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri; + CMS_EncryptedContentInfo *ec; + EVP_PKEY_CTX *pctx; + unsigned char *ek = NULL; + size_t eklen; + + int ret = 0; + + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerror(CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ktri = ri->d.ktri; + ec = cms->d.envelopedData->encryptedContentInfo; + + pctx = ktri->pctx; + + if (pctx) { + if (!cms_env_asn1_ctrl(ri, 0)) + goto err; + } else { + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (pctx == NULL) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + } + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { + CMSerror(CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) + goto err; + + ek = malloc(eklen); + + if (ek == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) + goto err; + + ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); + ek = NULL; + + ret = 1; + + err: + EVP_PKEY_CTX_free(pctx); + ktri->pctx = NULL; + free(ek); + + return ret; +} + +/* Decrypt content key from KTRI */ + +static int +cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY *pkey = ktri->pkey; + unsigned char *ek = NULL; + size_t eklen; + size_t fixlen = 0; + int ret = 0; + CMS_EncryptedContentInfo *ec; + + ec = cms->d.envelopedData->encryptedContentInfo; + + if (ktri->pkey == NULL) { + CMSerror(CMS_R_NO_PRIVATE_KEY); + return 0; + } + + if (cms->d.envelopedData->encryptedContentInfo->havenocert && + !cms->d.envelopedData->encryptedContentInfo->debug) { + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + const EVP_CIPHER *ciph; + + if ((ciph = EVP_get_cipherbyobj(calg->algorithm)) == NULL) { + CMSerror(CMS_R_UNKNOWN_CIPHER); + return 0; + } + + fixlen = EVP_CIPHER_key_length(ciph); + } + + ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (ktri->pctx == NULL) + return 0; + + if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) + goto err; + + if (!cms_env_asn1_ctrl(ri, 1)) + goto err; + + if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { + CMSerror(CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0 || eklen == 0 || + (fixlen != 0 && eklen != fixlen)) { + CMSerror(CMS_R_CMS_LIB); + goto err; + } + + ek = malloc(eklen); + + if (ek == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) { + CMSerror(CMS_R_CMS_LIB); + goto err; + } + + ret = 1; + + freezero(ec->key, ec->keylen); + ec->key = ek; + ec->keylen = eklen; + + err: + EVP_PKEY_CTX_free(ktri->pctx); + ktri->pctx = NULL; + if (!ret) + free(ek); + + return ret; +} + +/* Key Encrypted Key (KEK) RecipientInfo routines */ + +int +CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, const unsigned char *id, + size_t idlen) +{ + ASN1_OCTET_STRING tmp_os; + CMS_KEKRecipientInfo *kekri; + + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerror(CMS_R_NOT_KEK); + return -2; + } + kekri = ri->d.kekri; + tmp_os.type = V_ASN1_OCTET_STRING; + tmp_os.flags = 0; + tmp_os.data = (unsigned char *)id; + tmp_os.length = (int)idlen; + + return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kekri_id_cmp); + +/* For now hard code AES key wrap info */ + +static size_t +aes_wrap_keylen(int nid) +{ + switch (nid) { + case NID_id_aes128_wrap: + return 16; + + case NID_id_aes192_wrap: + return 24; + + case NID_id_aes256_wrap: + return 32; + + default: + return 0; + } +} + +CMS_RecipientInfo * +CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, unsigned char *key, + size_t keylen, unsigned char *id, size_t idlen, ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, ASN1_TYPE *otherType) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + CMS_KEKRecipientInfo *kekri; + + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + if (nid == NID_undef) { + switch (keylen) { + case 16: + nid = NID_id_aes128_wrap; + break; + + case 24: + nid = NID_id_aes192_wrap; + break; + + case 32: + nid = NID_id_aes256_wrap; + break; + + default: + CMSerror(CMS_R_INVALID_KEY_LENGTH); + goto err; + } + + } else { + + size_t exp_keylen = aes_wrap_keylen(nid); + + if (!exp_keylen) { + CMSerror(CMS_R_UNSUPPORTED_KEK_ALGORITHM); + goto err; + } + + if (keylen != exp_keylen) { + CMSerror(CMS_R_INVALID_KEY_LENGTH); + goto err; + } + + } + + /* Initialize recipient info */ + ri = (CMS_RecipientInfo *)ASN1_item_new(&CMS_RecipientInfo_it); + if (!ri) + goto merr; + + ri->d.kekri = (CMS_KEKRecipientInfo *)ASN1_item_new(&CMS_KEKRecipientInfo_it); + if (!ri->d.kekri) + goto merr; + ri->type = CMS_RECIPINFO_KEK; + + kekri = ri->d.kekri; + + if (otherTypeId) { + kekri->kekid->other = (CMS_OtherKeyAttribute *)ASN1_item_new(&CMS_OtherKeyAttribute_it); + if (kekri->kekid->other == NULL) + goto merr; + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + /* After this point no calls can fail */ + + kekri->version = 4; + + kekri->key = key; + kekri->keylen = keylen; + + ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); + + kekri->kekid->date = date; + + if (kekri->kekid->other) { + kekri->kekid->other->keyAttrId = otherTypeId; + kekri->kekid->other->keyAttr = otherType; + } + + X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, + OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); + + return ri; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + err: + ASN1_item_free((ASN1_VALUE *)ri, &CMS_RecipientInfo_it); + return NULL; +} +LCRYPTO_ALIAS(CMS_add0_recipient_key); + +int +CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, ASN1_TYPE **pothertype) +{ + CMS_KEKIdentifier *rkid; + + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerror(CMS_R_NOT_KEK); + return 0; + } + rkid = ri->d.kekri->kekid; + if (palg) + *palg = ri->d.kekri->keyEncryptionAlgorithm; + if (pid) + *pid = rkid->keyIdentifier; + if (pdate) + *pdate = rkid->date; + if (potherid) { + if (rkid->other) + *potherid = rkid->other->keyAttrId; + else + *potherid = NULL; + } + if (pothertype) { + if (rkid->other) + *pothertype = rkid->other->keyAttr; + else + *pothertype = NULL; + } + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kekri_get0_id); + +int +CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, + size_t keylen) +{ + CMS_KEKRecipientInfo *kekri; + + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerror(CMS_R_NOT_KEK); + return 0; + } + + kekri = ri->d.kekri; + kekri->key = key; + kekri->keylen = keylen; + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_set0_key); + +/* Encrypt content key in KEK recipient info */ + +static int +cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + CMS_EncryptedContentInfo *ec; + CMS_KEKRecipientInfo *kekri; + AES_KEY actx; + unsigned char *wkey = NULL; + int wkeylen; + int r = 0; + + ec = cms->d.envelopedData->encryptedContentInfo; + kekri = ri->d.kekri; + + if (!kekri->key) { + CMSerror(CMS_R_NO_KEY); + return 0; + } + + if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { + CMSerror(CMS_R_ERROR_SETTING_KEY); + goto err; + } + + wkey = malloc(ec->keylen + 8); + if (wkey == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); + if (wkeylen <= 0) { + CMSerror(CMS_R_WRAP_ERROR); + goto err; + } + + ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); + + r = 1; + + err: + if (!r) + free(wkey); + explicit_bzero(&actx, sizeof(actx)); + + return r; +} + +/* Decrypt content key in KEK recipient info */ + +static int +cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + CMS_EncryptedContentInfo *ec; + CMS_KEKRecipientInfo *kekri; + AES_KEY actx; + unsigned char *ukey = NULL; + int ukeylen; + int r = 0, wrap_nid; + + ec = cms->d.envelopedData->encryptedContentInfo; + kekri = ri->d.kekri; + + if (!kekri->key) { + CMSerror(CMS_R_NO_KEY); + return 0; + } + + wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); + if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { + CMSerror(CMS_R_INVALID_KEY_LENGTH); + return 0; + } + + /* If encrypted key length is invalid don't bother */ + + if (kekri->encryptedKey->length < 16) { + CMSerror(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); + goto err; + } + + if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { + CMSerror(CMS_R_ERROR_SETTING_KEY); + goto err; + } + + ukey = malloc(kekri->encryptedKey->length - 8); + if (ukey == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + ukeylen = AES_unwrap_key(&actx, NULL, ukey, kekri->encryptedKey->data, + kekri->encryptedKey->length); + + if (ukeylen <= 0) { + CMSerror(CMS_R_UNWRAP_ERROR); + goto err; + } + + freezero(ec->key, ec->keylen); + ec->key = ukey; + ec->keylen = ukeylen; + + r = 1; + + err: + + if (!r) + free(ukey); + explicit_bzero(&actx, sizeof(actx)); + + return r; +} + +int +CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + switch (ri->type) { + case CMS_RECIPINFO_TRANS: + return cms_RecipientInfo_ktri_decrypt(cms, ri); + + case CMS_RECIPINFO_KEK: + return cms_RecipientInfo_kekri_decrypt(cms, ri); + + case CMS_RECIPINFO_PASS: + return cms_RecipientInfo_pwri_crypt(cms, ri, 0); + + default: + CMSerror(CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE); + return 0; + } +} +LCRYPTO_ALIAS(CMS_RecipientInfo_decrypt); + +int +CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + switch (ri->type) { + case CMS_RECIPINFO_TRANS: + return cms_RecipientInfo_ktri_encrypt(cms, ri); + + case CMS_RECIPINFO_AGREE: + return cms_RecipientInfo_kari_encrypt(cms, ri); + + case CMS_RECIPINFO_KEK: + return cms_RecipientInfo_kekri_encrypt(cms, ri); + + case CMS_RECIPINFO_PASS: + return cms_RecipientInfo_pwri_crypt(cms, ri, 1); + + default: + CMSerror(CMS_R_UNSUPPORTED_RECIPIENT_TYPE); + return 0; + } +} +LCRYPTO_ALIAS(CMS_RecipientInfo_encrypt); + +/* Check structures and fixup version numbers (if necessary) */ + +static void +cms_env_set_originfo_version(CMS_EnvelopedData *env) +{ + CMS_OriginatorInfo *org = env->originatorInfo; + int i; + + if (org == NULL) + return; + for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) { + CMS_CertificateChoices *cch; + + cch = sk_CMS_CertificateChoices_value(org->certificates, i); + if (cch->type == CMS_CERTCHOICE_OTHER) { + env->version = 4; + return; + } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { + if (env->version < 3) + env->version = 3; + } + } + + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) { + CMS_RevocationInfoChoice *rch; + + rch = sk_CMS_RevocationInfoChoice_value(org->crls, i); + if (rch->type == CMS_REVCHOICE_OTHER) { + env->version = 4; + return; + } + } +} + +static void +cms_env_set_version(CMS_EnvelopedData *env) +{ + int i; + CMS_RecipientInfo *ri; + + /* + * Can't set version higher than 4 so if 4 or more already nothing to do. + */ + if (env->version >= 4) + return; + + cms_env_set_originfo_version(env); + + if (env->version >= 3) + return; + + for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) { + ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i); + if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) { + env->version = 3; + return; + } else if (ri->type != CMS_RECIPINFO_TRANS + || ri->d.ktri->version != 0) { + env->version = 2; + } + } + if (env->originatorInfo || env->unprotectedAttrs) + env->version = 2; + if (env->version == 2) + return; + env->version = 0; +} + +BIO * +cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedContentInfo *ec; + STACK_OF(CMS_RecipientInfo) *rinfos; + CMS_RecipientInfo *ri; + int i, ok = 0; + BIO *ret; + + /* Get BIO first to set up key */ + + ec = cms->d.envelopedData->encryptedContentInfo; + ret = cms_EncryptedContent_init_bio(ec); + + /* If error or no cipher end of processing */ + + if (!ret || !ec->cipher) + return ret; + + /* Now encrypt content key according to each RecipientInfo type */ + + rinfos = cms->d.envelopedData->recipientInfos; + + for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { + ri = sk_CMS_RecipientInfo_value(rinfos, i); + if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { + CMSerror(CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; + } + } + cms_env_set_version(cms->d.envelopedData); + + ok = 1; + + err: + ec->cipher = NULL; + freezero(ec->key, ec->keylen); + ec->key = NULL; + ec->keylen = 0; + if (ok) + return ret; + BIO_free(ret); + return NULL; +} + +/* + * Get RecipientInfo type (if any) supported by a key (public or private). To + * retain compatibility with previous behaviour if the ctrl value isn't + * supported we assume key transport. + */ +int +cms_pkey_get_ri_type(EVP_PKEY *pk) +{ + if (pk->ameth && pk->ameth->pkey_ctrl) { + int i, r; + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); + if (i > 0) + return r; + } + return CMS_RECIPINFO_TRANS; +} diff --git a/Libraries/libressl/crypto/cms/cms_err.c b/Libraries/libressl/crypto/cms/cms_err.c new file mode 100644 index 000000000..5758a26db --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_err.c @@ -0,0 +1,164 @@ +/* $OpenBSD: cms_err.c,v 1.14 2023/07/08 08:26:26 beck Exp $ */ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason) + +static ERR_STRING_DATA CMS_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA CMS_str_reasons[] = { + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_ALREADY_PRESENT), + "certificate already present"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_HAS_NO_KEYID), + "certificate has no keyid"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR), + "certificate verify error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_INITIALISATION_ERROR), + "cipher initialisation error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), + "cipher parameter initialisation error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_DATAFINAL_ERROR), + "cms datafinal error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_LIB), "cms lib"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENTIDENTIFIER_MISMATCH), + "contentidentifier mismatch"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_NOT_FOUND), "content not found"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_MISMATCH), + "content type mismatch"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA), + "content type not compressed data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA), + "content type not enveloped data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA), + "content type not signed data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_VERIFY_ERROR), + "content verify error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY), + "error getting public key"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE), + "error reading messagedigest attribute"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO), + "error setting recipientinfo"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), + "invalid encrypted key length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), + "invalid key encryption parameter"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), + "messagedigest attribute wrong length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_WRONG_LENGTH), + "messagedigest wrong length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE), + "msgsigdigest verification failure"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_WRONG_LENGTH), + "msgsigdigest wrong length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NEED_ONE_SIGNER), "need one signer"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_A_SIGNED_RECEIPT), + "not a signed receipt"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEK), "not kek"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_AGREEMENT), "not key agreement"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_TRANSPORT), "not key transport"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_PWRI), "not pwri"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "not supported for this key type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CIPHER), "no cipher"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT), "no content"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_DIGEST_SET), "no digest set"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY), "no key"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY_OR_CERT), "no key or cert"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_DIGEST), "no matching digest"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_RECIPIENT), + "no matching recipient"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_SIGNATURE), + "no matching signature"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PASSWORD), "no password"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PRIVATE_KEY), "no private key"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR), + "receipt decode error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SMIME_TEXT_ERROR), "smime text error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_STORE_INIT_ERROR), "store init error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_COMPRESSED_DATA), + "type not compressed data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DATA), "type not data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DIGESTED_DATA), + "type not digested data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENCRYPTED_DATA), + "type not encrypted data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENVELOPED_DATA), + "type not enveloped data"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNABLE_TO_FINALIZE_CONTEXT), + "unable to finalize context"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_CIPHER), "unknown cipher"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_DIGEST_ALGORITHM), + "unknown digest algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_ID), "unknown id"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM), + "unsupported compression algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE), + "unsupported content type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM), + "unsupported kek algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), + "unsupported key encryption algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE), + "unsupported recipientinfo type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE), + "unsupported recipient type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_ERROR), "unwrap error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_FAILURE), "unwrap failure"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_VERIFICATION_FAILURE), + "verification failure"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_WRAP_ERROR), "wrap error"}, + {0, NULL} +}; + +#endif + +int +ERR_load_CMS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) { + ERR_load_strings(ERR_LIB_CMS, CMS_str_functs); + ERR_load_strings(ERR_LIB_CMS, CMS_str_reasons); + } +#endif + return 1; +} +LCRYPTO_ALIAS(ERR_load_CMS_strings); diff --git a/Libraries/libressl/crypto/cms/cms_ess.c b/Libraries/libressl/crypto/cms/cms_ess.c new file mode 100644 index 000000000..b9a4cd8af --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_ess.c @@ -0,0 +1,408 @@ +/* $OpenBSD: cms_ess.c,v 1.23 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_local.h" + + +CMS_ReceiptRequest * +d2i_CMS_ReceiptRequest(CMS_ReceiptRequest **a, const unsigned char **in, long len) +{ + return (CMS_ReceiptRequest *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &CMS_ReceiptRequest_it); +} +LCRYPTO_ALIAS(d2i_CMS_ReceiptRequest); + +int +i2d_CMS_ReceiptRequest(CMS_ReceiptRequest *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &CMS_ReceiptRequest_it); +} +LCRYPTO_ALIAS(i2d_CMS_ReceiptRequest); + +CMS_ReceiptRequest * +CMS_ReceiptRequest_new(void) +{ + return (CMS_ReceiptRequest *)ASN1_item_new(&CMS_ReceiptRequest_it); +} +LCRYPTO_ALIAS(CMS_ReceiptRequest_new); + +void +CMS_ReceiptRequest_free(CMS_ReceiptRequest *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &CMS_ReceiptRequest_it); +} +LCRYPTO_ALIAS(CMS_ReceiptRequest_free); + +/* ESS services: for now just Signed Receipt related */ + +int +CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) +{ + ASN1_STRING *str; + CMS_ReceiptRequest *rr = NULL; + + if (prr) + *prr = NULL; + str = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_id_smime_aa_receiptRequest), -3, V_ASN1_SEQUENCE); + if (!str) + return 0; + + rr = ASN1_item_unpack(str, &CMS_ReceiptRequest_it); + if (!rr) + return -1; + if (prr) + *prr = rr; + else + CMS_ReceiptRequest_free(rr); + + return 1; +} + +CMS_ReceiptRequest * +CMS_ReceiptRequest_create0(unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo) +{ + CMS_ReceiptRequest *rr = NULL; + + rr = CMS_ReceiptRequest_new(); + if (rr == NULL) + goto merr; + if (id) + ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); + else { + if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) + goto merr; + arc4random_buf(rr->signedContentIdentifier->data, 32); + } + + sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); + rr->receiptsTo = receiptsTo; + + if (receiptList) { + rr->receiptsFrom->type = 1; + rr->receiptsFrom->d.receiptList = receiptList; + } else { + rr->receiptsFrom->type = 0; + rr->receiptsFrom->d.allOrFirstTier = allorfirst; + } + + return rr; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + CMS_ReceiptRequest_free(rr); + + return NULL; +} + +int +CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) +{ + unsigned char *rrder = NULL; + int rrderlen, r = 0; + + rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); + if (rrderlen < 0) + goto merr; + + if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, + V_ASN1_SEQUENCE, rrder, rrderlen)) + goto merr; + + r = 1; + + merr: + if (!r) + CMSerror(ERR_R_MALLOC_FAILURE); + + free(rrder); + + return r; +} + +void +CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid, + int *pallorfirst, STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto) +{ + if (pcid) + *pcid = rr->signedContentIdentifier; + if (rr->receiptsFrom->type == 0) { + if (pallorfirst) + *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; + if (plist) + *plist = NULL; + } else { + if (pallorfirst) + *pallorfirst = -1; + if (plist) + *plist = rr->receiptsFrom->d.receiptList; + } + if (prto) + *prto = rr->receiptsTo; +} + +/* Digest a SignerInfo structure for msgSigDigest attribute processing */ + +static int +cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen) +{ + const EVP_MD *md; + + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return 0; + if (!ASN1_item_digest(&CMS_Attributes_Verify_it, md, + si->signedAttrs, dig, diglen)) + return 0; + + return 1; +} + +/* Add a msgSigDigest attribute to a SignerInfo */ + +int +cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) +{ + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (!cms_msgSigDigest(src, dig, &diglen)) { + CMSerror(CMS_R_MSGSIGDIGEST_ERROR); + return 0; + } + if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, + V_ASN1_OCTET_STRING, dig, diglen)) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +/* Verify signed receipt after it has already passed normal CMS verify */ + +int +cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) +{ + int r = 0, i; + CMS_ReceiptRequest *rr = NULL; + CMS_Receipt *rct = NULL; + STACK_OF(CMS_SignerInfo) *sis, *osis; + CMS_SignerInfo *si, *osi = NULL; + ASN1_OCTET_STRING *msig, **pcont; + ASN1_OBJECT *octype; + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + /* Get SignerInfos, also checks SignedData content type */ + osis = CMS_get0_SignerInfos(req_cms); + sis = CMS_get0_SignerInfos(cms); + if (!osis || !sis) + goto err; + + if (sk_CMS_SignerInfo_num(sis) != 1) { + CMSerror(CMS_R_NEED_ONE_SIGNER); + goto err; + } + + /* Check receipt content type */ + if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { + CMSerror(CMS_R_NOT_A_SIGNED_RECEIPT); + goto err; + } + + /* Extract and decode receipt content */ + pcont = CMS_get0_content(cms); + if (!pcont || !*pcont) { + CMSerror(CMS_R_NO_CONTENT); + goto err; + } + + rct = ASN1_item_unpack(*pcont, &CMS_Receipt_it); + + if (!rct) { + CMSerror(CMS_R_RECEIPT_DECODE_ERROR); + goto err; + } + + /* Locate original request */ + + for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) { + osi = sk_CMS_SignerInfo_value(osis, i); + if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue)) + break; + } + + if (i == sk_CMS_SignerInfo_num(osis)) { + CMSerror(CMS_R_NO_MATCHING_SIGNATURE); + goto err; + } + + si = sk_CMS_SignerInfo_value(sis, 0); + + /* Get msgSigDigest value and compare */ + + msig = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_id_smime_aa_msgSigDigest), -3, V_ASN1_OCTET_STRING); + + if (!msig) { + CMSerror(CMS_R_NO_MSGSIGDIGEST); + goto err; + } + + if (!cms_msgSigDigest(osi, dig, &diglen)) { + CMSerror(CMS_R_MSGSIGDIGEST_ERROR); + goto err; + } + + if (diglen != (unsigned int)msig->length) { + CMSerror(CMS_R_MSGSIGDIGEST_WRONG_LENGTH); + goto err; + } + + if (memcmp(dig, msig->data, diglen)) { + CMSerror(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); + goto err; + } + + /* Compare content types */ + + octype = CMS_signed_get0_data_by_OBJ(osi, + OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT); + if (!octype) { + CMSerror(CMS_R_NO_CONTENT_TYPE); + goto err; + } + + /* Compare details in receipt request */ + + if (OBJ_cmp(octype, rct->contentType)) { + CMSerror(CMS_R_CONTENT_TYPE_MISMATCH); + goto err; + } + + /* Get original receipt request details */ + + if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { + CMSerror(CMS_R_NO_RECEIPT_REQUEST); + goto err; + } + + if (ASN1_STRING_cmp(rr->signedContentIdentifier, + rct->signedContentIdentifier)) { + CMSerror(CMS_R_CONTENTIDENTIFIER_MISMATCH); + goto err; + } + + r = 1; + + err: + CMS_ReceiptRequest_free(rr); + ASN1_item_free((ASN1_VALUE *)rct, &CMS_Receipt_it); + return r; +} + +/* + * Encode a Receipt into an OCTET STRING read for including into content of a + * SignedData ContentInfo. + */ + +ASN1_OCTET_STRING * +cms_encode_Receipt(CMS_SignerInfo *si) +{ + CMS_Receipt rct; + CMS_ReceiptRequest *rr = NULL; + ASN1_OBJECT *ctype; + ASN1_OCTET_STRING *os = NULL; + + /* Get original receipt request */ + + /* Get original receipt request details */ + + if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { + CMSerror(CMS_R_NO_RECEIPT_REQUEST); + goto err; + } + + /* Get original content type */ + + ctype = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT); + if (!ctype) { + CMSerror(CMS_R_NO_CONTENT_TYPE); + goto err; + } + + rct.version = 1; + rct.contentType = ctype; + rct.signedContentIdentifier = rr->signedContentIdentifier; + rct.originatorSignatureValue = si->signature; + + os = ASN1_item_pack(&rct, &CMS_Receipt_it, NULL); + + err: + CMS_ReceiptRequest_free(rr); + return os; +} diff --git a/Libraries/libressl/crypto/cms/cms_io.c b/Libraries/libressl/crypto/cms/cms_io.c new file mode 100644 index 000000000..ceb4ce8ec --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_io.c @@ -0,0 +1,176 @@ +/* $OpenBSD: cms_io.c,v 1.20 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "cms_local.h" + +int +CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + + if ((pos = CMS_get0_content(cms)) == NULL) + return 0; + + if (*pos == NULL) + *pos = ASN1_OCTET_STRING_new(); + if (*pos == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + (*pos)->flags |= ASN1_STRING_FLAG_NDEF; + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + *boundary = &(*pos)->data; + + return 1; +} +LCRYPTO_ALIAS(CMS_stream); + +CMS_ContentInfo * +d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) +{ + return ASN1_item_d2i_bio(&CMS_ContentInfo_it, bp, cms); +} +LCRYPTO_ALIAS(d2i_CMS_bio); + +int +i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) +{ + return ASN1_item_i2d_bio(&CMS_ContentInfo_it, bp, cms); +} +LCRYPTO_ALIAS(i2d_CMS_bio); + + +CMS_ContentInfo * +PEM_read_bio_CMS(BIO *bp, CMS_ContentInfo **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_CMS_ContentInfo, + PEM_STRING_CMS, bp, (void **)x, cb, u); +} + +CMS_ContentInfo * +PEM_read_CMS(FILE *fp, CMS_ContentInfo **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_CMS_ContentInfo, + PEM_STRING_CMS, fp, (void **)x, cb, u); +} + +int +PEM_write_bio_CMS(BIO *bp, const CMS_ContentInfo *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_CMS_ContentInfo, + PEM_STRING_CMS, bp, (void *)x, NULL, NULL, 0, NULL, NULL); +} + +int +PEM_write_CMS(FILE *fp, const CMS_ContentInfo *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_CMS_ContentInfo, + PEM_STRING_CMS, fp, (void *)x, NULL, NULL, 0, NULL, NULL); +} + +BIO * +BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) +{ + return BIO_new_NDEF(out, (ASN1_VALUE *)cms, &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(BIO_new_CMS); + +/* CMS wrappers round generalised stream and MIME routines */ + +int +i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) +{ + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags, + &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(i2d_CMS_bio_stream); + +int +PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) +{ + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags, + "CMS", &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(PEM_write_bio_CMS_stream); + +int +SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) +{ + STACK_OF(X509_ALGOR) *mdalgs = NULL; + int ctype_nid = OBJ_obj2nid(cms->contentType); + int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); + + if (ctype_nid == NID_pkcs7_signed) + mdalgs = cms->d.signedData->digestAlgorithms; + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, ctype_nid, + econt_nid, mdalgs, &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(SMIME_write_CMS); + +CMS_ContentInfo * +SMIME_read_CMS(BIO *bio, BIO **bcont) +{ + return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, + &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(SMIME_read_CMS); diff --git a/Libraries/libressl/crypto/cms/cms_kari.c b/Libraries/libressl/crypto/cms/cms_kari.c new file mode 100644 index 000000000..8ed54e757 --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_kari.c @@ -0,0 +1,492 @@ +/* $OpenBSD: cms_kari.c,v 1.15 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_local.h" +#include "asn1/asn1_local.h" + +/* Key Agreement Recipient Info (KARI) routines */ + +int +CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm) +{ + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerror(CMS_R_NOT_KEY_AGREEMENT); + return 0; + } + if (palg) + *palg = ri->d.kari->keyEncryptionAlgorithm; + if (pukm) + *pukm = ri->d.kari->ukm; + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_alg); + +/* Retrieve recipient encrypted keys from a kari */ + +STACK_OF(CMS_RecipientEncryptedKey) * +CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) +{ + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerror(CMS_R_NOT_KEY_AGREEMENT); + return NULL; + } + return ri->d.kari->recipientEncryptedKeys; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_reks); + +int +CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, + ASN1_INTEGER **sno) +{ + CMS_OriginatorIdentifierOrKey *oik; + + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerror(CMS_R_NOT_KEY_AGREEMENT); + return 0; + } + oik = ri->d.kari->originator; + if (issuer) + *issuer = NULL; + if (sno) + *sno = NULL; + if (keyid) + *keyid = NULL; + if (pubalg) + *pubalg = NULL; + if (pubkey) + *pubkey = NULL; + if (oik->type == CMS_OIK_ISSUER_SERIAL) { + if (issuer) + *issuer = oik->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = oik->d.issuerAndSerialNumber->serialNumber; + } else if (oik->type == CMS_OIK_KEYIDENTIFIER) { + if (keyid) + *keyid = oik->d.subjectKeyIdentifier; + } else if (oik->type == CMS_OIK_PUBKEY) { + if (pubalg) + *pubalg = oik->d.originatorKey->algorithm; + if (pubkey) + *pubkey = oik->d.originatorKey->publicKey; + } else + return 0; + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_orig_id); + +int +CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) +{ + CMS_OriginatorIdentifierOrKey *oik; + + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerror(CMS_R_NOT_KEY_AGREEMENT); + return -2; + } + oik = ri->d.kari->originator; + if (oik->type == CMS_OIK_ISSUER_SERIAL) + return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); + else if (oik->type == CMS_OIK_KEYIDENTIFIER) + return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); + + return -1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_orig_id_cmp); + +int +CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, X509_NAME **issuer, ASN1_INTEGER **sno) +{ + CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + + if (rid->type == CMS_REK_ISSUER_SERIAL) { + if (issuer) + *issuer = rid->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = rid->d.issuerAndSerialNumber->serialNumber; + if (keyid) + *keyid = NULL; + if (tm) + *tm = NULL; + if (other) + *other = NULL; + } else if (rid->type == CMS_REK_KEYIDENTIFIER) { + if (keyid) + *keyid = rid->d.rKeyId->subjectKeyIdentifier; + if (tm) + *tm = rid->d.rKeyId->date; + if (other) + *other = rid->d.rKeyId->other; + if (issuer) + *issuer = NULL; + if (sno) + *sno = NULL; + } else + return 0; + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientEncryptedKey_get0_id); + +int +CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, X509 *cert) +{ + CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + + if (rid->type == CMS_REK_ISSUER_SERIAL) + return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); + else if (rid->type == CMS_REK_KEYIDENTIFIER) + return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); + else + return -1; +} +LCRYPTO_ALIAS(CMS_RecipientEncryptedKey_cert_cmp); + +int +CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) +{ + EVP_PKEY_CTX *pctx; + CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; + + EVP_PKEY_CTX_free(kari->pctx); + kari->pctx = NULL; + if (!pk) + return 1; + pctx = EVP_PKEY_CTX_new(pk, NULL); + if (!pctx || !EVP_PKEY_derive_init(pctx)) + goto err; + kari->pctx = pctx; + return 1; + + err: + EVP_PKEY_CTX_free(pctx); + return 0; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_set0_pkey); + +EVP_CIPHER_CTX * +CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) +{ + if (ri->type == CMS_RECIPINFO_AGREE) + return ri->d.kari->ctx; + return NULL; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_ctx); + +/* + * Derive KEK and decrypt/encrypt with it to produce either the original CEK + * or the encrypted CEK. + */ + +static int +cms_kek_cipher(unsigned char **pout, size_t *poutlen, const unsigned char *in, + size_t inlen, CMS_KeyAgreeRecipientInfo *kari, int enc) +{ + /* Key encryption key */ + unsigned char kek[EVP_MAX_KEY_LENGTH]; + size_t keklen; + int rv = 0; + unsigned char *out = NULL; + int outlen; + + keklen = EVP_CIPHER_CTX_key_length(kari->ctx); + if (keklen > EVP_MAX_KEY_LENGTH) + return 0; + /* Derive KEK */ + if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) + goto err; + /* Set KEK in context */ + if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc)) + goto err; + /* obtain output length of ciphered key */ + if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen)) + goto err; + out = malloc(outlen); + if (out == NULL) + goto err; + if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen)) + goto err; + *pout = out; + *poutlen = (size_t)outlen; + rv = 1; + + err: + explicit_bzero(kek, keklen); + if (!rv) + free(out); + EVP_CIPHER_CTX_reset(kari->ctx); + /* FIXME: WHY IS kari->pctx freed here? /RL */ + EVP_PKEY_CTX_free(kari->pctx); + kari->pctx = NULL; + + return rv; +} + +int +CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek) +{ + int rv = 0; + unsigned char *enckey = NULL, *cek = NULL; + size_t enckeylen; + size_t ceklen; + CMS_EncryptedContentInfo *ec; + + enckeylen = rek->encryptedKey->length; + enckey = rek->encryptedKey->data; + /* Setup all parameters to derive KEK */ + if (!cms_env_asn1_ctrl(ri, 1)) + goto err; + /* Attempt to decrypt CEK */ + if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) + goto err; + ec = cms->d.envelopedData->encryptedContentInfo; + freezero(ec->key, ec->keylen); + ec->key = cek; + ec->keylen = ceklen; + cek = NULL; + rv = 1; + + err: + free(cek); + + return rv; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_kari_decrypt); + +/* Create ephemeral key and initialise context based on it */ +static int +cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *pk) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *ekey = NULL; + int rv = 0; + + pctx = EVP_PKEY_CTX_new(pk, NULL); + if (!pctx) + goto err; + if (EVP_PKEY_keygen_init(pctx) <= 0) + goto err; + if (EVP_PKEY_keygen(pctx, &ekey) <= 0) + goto err; + EVP_PKEY_CTX_free(pctx); + pctx = EVP_PKEY_CTX_new(ekey, NULL); + if (!pctx) + goto err; + if (EVP_PKEY_derive_init(pctx) <= 0) + goto err; + kari->pctx = pctx; + rv = 1; + + err: + if (!rv) + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(ekey); + + return rv; +} + +/* Initialise a kari based on passed certificate and key */ + +int +cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, + unsigned int flags) +{ + CMS_KeyAgreeRecipientInfo *kari; + CMS_RecipientEncryptedKey *rek = NULL; + + ri->d.kari = (CMS_KeyAgreeRecipientInfo *)ASN1_item_new(&CMS_KeyAgreeRecipientInfo_it); + if (!ri->d.kari) + return 0; + ri->type = CMS_RECIPINFO_AGREE; + + kari = ri->d.kari; + kari->version = 3; + + rek = (CMS_RecipientEncryptedKey *)ASN1_item_new(&CMS_RecipientEncryptedKey_it); + if (rek == NULL) + return 0; + + if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { + ASN1_item_free((ASN1_VALUE *)rek, &CMS_RecipientEncryptedKey_it); + return 0; + } + + if (flags & CMS_USE_KEYID) { + rek->rid->type = CMS_REK_KEYIDENTIFIER; + rek->rid->d.rKeyId = (CMS_RecipientKeyIdentifier *)ASN1_item_new(&CMS_RecipientKeyIdentifier_it); + if (rek->rid->d.rKeyId == NULL) + return 0; + if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) + return 0; + } else { + rek->rid->type = CMS_REK_ISSUER_SERIAL; + if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) + return 0; + } + + /* Create ephemeral key */ + if (!cms_kari_create_ephemeral_key(kari, pk)) + return 0; + + EVP_PKEY_up_ref(pk); + rek->pkey = pk; + + return 1; +} + +static int +cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher) +{ + EVP_CIPHER_CTX *ctx = kari->ctx; + const EVP_CIPHER *kekcipher; + int keylen = EVP_CIPHER_key_length(cipher); + + /* If a suitable wrap algorithm is already set nothing to do */ + kekcipher = EVP_CIPHER_CTX_cipher(ctx); + + if (kekcipher) { + if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) + return 0; + return 1; + } + /* + * Pick a cipher based on content encryption cipher. If it is DES3 use + * DES3 wrap otherwise use AES wrap similar to key size. + */ +#ifndef OPENSSL_NO_DES +#if 0 + /* + * XXX - we do not currently support DES3 wrap and probably should just + * drop this code. + */ + if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) + kekcipher = EVP_des_ede3_wrap(); + else +#endif +#endif + if (keylen <= 16) + kekcipher = EVP_aes_128_wrap(); + else if (keylen <= 24) + kekcipher = EVP_aes_192_wrap(); + else + kekcipher = EVP_aes_256_wrap(); + + return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); +} + +/* Encrypt content key in key agreement recipient info */ + +int +cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + CMS_KeyAgreeRecipientInfo *kari; + CMS_EncryptedContentInfo *ec; + CMS_RecipientEncryptedKey *rek; + STACK_OF(CMS_RecipientEncryptedKey) *reks; + int i; + + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerror(CMS_R_NOT_KEY_AGREEMENT); + return 0; + } + kari = ri->d.kari; + reks = kari->recipientEncryptedKeys; + ec = cms->d.envelopedData->encryptedContentInfo; + /* Initialise wrap algorithm parameters */ + if (!cms_wrap_init(kari, ec->cipher)) + return 0; + /* + * If no originator key set up initialise for ephemeral key the public key + * ASN1 structure will set the actual public key value. + */ + if (kari->originator->type == -1) { + CMS_OriginatorIdentifierOrKey *oik = kari->originator; + oik->type = CMS_OIK_PUBKEY; + oik->d.originatorKey = (CMS_OriginatorPublicKey *)ASN1_item_new(&CMS_OriginatorPublicKey_it); + if (!oik->d.originatorKey) + return 0; + } + /* Initialise KDF algorithm */ + if (!cms_env_asn1_ctrl(ri, 0)) + return 0; + /* For each rek, derive KEK, encrypt CEK */ + for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { + unsigned char *enckey; + size_t enckeylen; + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); + if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) + return 0; + if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, + kari, 1)) + return 0; + ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); + } + + return 1; +} diff --git a/Libraries/libressl/crypto/cms/cms_lib.c b/Libraries/libressl/crypto/cms/cms_lib.c new file mode 100644 index 000000000..8a8fdbc8d --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_lib.c @@ -0,0 +1,776 @@ +/* $OpenBSD: cms_lib.c,v 1.24 2023/08/24 04:56:36 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cms_local.h" +#include "x509_local.h" + +CMS_ContentInfo * +d2i_CMS_ContentInfo(CMS_ContentInfo **a, const unsigned char **in, long len) +{ + return (CMS_ContentInfo *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(d2i_CMS_ContentInfo); + +int +i2d_CMS_ContentInfo(CMS_ContentInfo *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(i2d_CMS_ContentInfo); + +CMS_ContentInfo * +CMS_ContentInfo_new(void) +{ + return (CMS_ContentInfo *)ASN1_item_new(&CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(CMS_ContentInfo_new); + +void +CMS_ContentInfo_free(CMS_ContentInfo *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &CMS_ContentInfo_it); +} +LCRYPTO_ALIAS(CMS_ContentInfo_free); + +int +CMS_ContentInfo_print_ctx(BIO *out, CMS_ContentInfo *x, int indent, const ASN1_PCTX *pctx) +{ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, + &CMS_ContentInfo_it, pctx); +} +LCRYPTO_ALIAS(CMS_ContentInfo_print_ctx); + +const ASN1_OBJECT * +CMS_get0_type(const CMS_ContentInfo *cms) +{ + return cms->contentType; +} +LCRYPTO_ALIAS(CMS_get0_type); + +CMS_ContentInfo * +cms_Data_create(void) +{ + CMS_ContentInfo *cms; + + cms = CMS_ContentInfo_new(); + if (cms != NULL) { + cms->contentType = OBJ_nid2obj(NID_pkcs7_data); + /* Never detached */ + CMS_set_detached(cms, 0); + } + return cms; +} + +static BIO * +cms_content_bio(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + + if ((pos = CMS_get0_content(cms)) == NULL) + return NULL; + + /* If content is detached, data goes nowhere: create null BIO. */ + if (*pos == NULL) + return BIO_new(BIO_s_null()); + + /* If content is not detached and was created, return memory BIO. */ + if ((*pos)->flags == ASN1_STRING_FLAG_CONT) + return BIO_new(BIO_s_mem()); + + /* Else content was read in: return read-only BIO for it. */ + return BIO_new_mem_buf((*pos)->data, (*pos)->length); +} + +BIO * +CMS_dataInit(CMS_ContentInfo *cms, BIO *in_content_bio) +{ + BIO *cms_bio = NULL, *content_bio = NULL; + + if ((content_bio = in_content_bio) == NULL) + content_bio = cms_content_bio(cms); + if (content_bio == NULL) { + CMSerror(CMS_R_NO_CONTENT); + goto err; + } + + switch (OBJ_obj2nid(cms->contentType)) { + case NID_pkcs7_data: + return content_bio; + case NID_pkcs7_signed: + if ((cms_bio = cms_SignedData_init_bio(cms)) == NULL) + goto err; + break; + case NID_pkcs7_digest: + if ((cms_bio = cms_DigestedData_init_bio(cms)) == NULL) + goto err; + break; + case NID_pkcs7_encrypted: + if ((cms_bio = cms_EncryptedData_init_bio(cms)) == NULL) + goto err; + break; + case NID_pkcs7_enveloped: + if ((cms_bio = cms_EnvelopedData_init_bio(cms)) == NULL) + goto err; + break; + default: + CMSerror(CMS_R_UNSUPPORTED_TYPE); + goto err; + } + + return BIO_push(cms_bio, content_bio); + + err: + if (content_bio != in_content_bio) + BIO_free(content_bio); + + return NULL; +} +LCRYPTO_ALIAS(CMS_dataInit); + +int +CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + + if (!pos) + return 0; + /* If embedded content find memory BIO and set content */ + if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { + BIO *mbio; + unsigned char *cont; + long contlen; + mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); + if (!mbio) { + CMSerror(CMS_R_CONTENT_NOT_FOUND); + return 0; + } + contlen = BIO_get_mem_data(mbio, &cont); + /* Set bio as read only so its content can't be clobbered */ + BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(mbio, 0); + ASN1_STRING_set0(*pos, cont, contlen); + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + } + + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + case NID_pkcs7_enveloped: + case NID_pkcs7_encrypted: + case NID_id_smime_ct_compressedData: + /* Nothing to do */ + return 1; + + case NID_pkcs7_signed: + return cms_SignedData_final(cms, cmsbio); + + case NID_pkcs7_digest: + return cms_DigestedData_do_final(cms, cmsbio, 0); + + default: + CMSerror(CMS_R_UNSUPPORTED_TYPE); + return 0; + } +} +LCRYPTO_ALIAS(CMS_dataFinal); + +int +CMS_get_version(const CMS_ContentInfo *cms, long *version) +{ + switch (OBJ_obj2nid(cms->contentType)) { + case NID_pkcs7_signed: + *version = cms->d.signedData->version; + return 1; + + case NID_pkcs7_enveloped: + *version = cms->d.envelopedData->version; + return 1; + + case NID_pkcs7_digest: + *version = cms->d.digestedData->version; + return 1; + + case NID_pkcs7_encrypted: + *version = cms->d.encryptedData->version; + return 1; + + case NID_id_smime_ct_authData: + *version = cms->d.authenticatedData->version; + return 1; + + case NID_id_smime_ct_compressedData: + *version = cms->d.compressedData->version; + return 1; + + default: + CMSerror(CMS_R_UNSUPPORTED_TYPE); + return 0; + } +} +LCRYPTO_ALIAS(CMS_get_version); + +int +CMS_SignerInfo_get_version(const CMS_SignerInfo *si, long *version) +{ + *version = si->version; + return 1; +} +LCRYPTO_ALIAS(CMS_SignerInfo_get_version); + +/* + * Return an OCTET STRING pointer to content. This allows it to be accessed + * or set later. + */ + +ASN1_OCTET_STRING ** +CMS_get0_content(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + case NID_pkcs7_data: + return &cms->d.data; + + case NID_pkcs7_signed: + return &cms->d.signedData->encapContentInfo->eContent; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; + + case NID_pkcs7_digest: + return &cms->d.digestedData->encapContentInfo->eContent; + + case NID_pkcs7_encrypted: + return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; + + case NID_id_smime_ct_authData: + return &cms->d.authenticatedData->encapContentInfo->eContent; + + case NID_id_smime_ct_compressedData: + return &cms->d.compressedData->encapContentInfo->eContent; + + default: + if (cms->d.other->type == V_ASN1_OCTET_STRING) + return &cms->d.other->value.octet_string; + CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + } +} + +/* + * Return an ASN1_OBJECT pointer to content type. This allows it to be + * accessed or set later. + */ + +static ASN1_OBJECT ** +cms_get0_econtent_type(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + case NID_pkcs7_signed: + return &cms->d.signedData->encapContentInfo->eContentType; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->encryptedContentInfo->contentType; + + case NID_pkcs7_digest: + return &cms->d.digestedData->encapContentInfo->eContentType; + + case NID_pkcs7_encrypted: + return &cms->d.encryptedData->encryptedContentInfo->contentType; + + case NID_id_smime_ct_authData: + return &cms->d.authenticatedData->encapContentInfo->eContentType; + + case NID_id_smime_ct_compressedData: + return &cms->d.compressedData->encapContentInfo->eContentType; + + default: + CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + } +} + +const ASN1_OBJECT * +CMS_get0_eContentType(CMS_ContentInfo *cms) +{ + ASN1_OBJECT **petype; + + petype = cms_get0_econtent_type(cms); + if (petype) + return *petype; + + return NULL; +} +LCRYPTO_ALIAS(CMS_get0_eContentType); + +int +CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) +{ + ASN1_OBJECT **petype, *etype; + + petype = cms_get0_econtent_type(cms); + if (!petype) + return 0; + if (!oid) + return 1; + etype = OBJ_dup(oid); + if (!etype) + return 0; + ASN1_OBJECT_free(*petype); + *petype = etype; + + return 1; +} +LCRYPTO_ALIAS(CMS_set1_eContentType); + +int +CMS_is_detached(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + + pos = CMS_get0_content(cms); + if (!pos) + return -1; + if (*pos) + return 0; + + return 1; +} +LCRYPTO_ALIAS(CMS_is_detached); + +int +CMS_set_detached(CMS_ContentInfo *cms, int detached) +{ + ASN1_OCTET_STRING **pos; + + pos = CMS_get0_content(cms); + if (!pos) + return 0; + if (detached) { + ASN1_OCTET_STRING_free(*pos); + *pos = NULL; + return 1; + } + if (*pos == NULL) + *pos = ASN1_OCTET_STRING_new(); + if (*pos != NULL) { + /* + * NB: special flag to show content is created and not read in. + */ + (*pos)->flags |= ASN1_STRING_FLAG_CONT; + return 1; + } + CMSerror(ERR_R_MALLOC_FAILURE); + + return 0; +} +LCRYPTO_ALIAS(CMS_set_detached); + +/* Create a digest BIO from an X509_ALGOR structure */ + +BIO * +cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) +{ + BIO *mdbio = NULL; + const ASN1_OBJECT *digestoid; + const EVP_MD *digest; + + X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); + digest = EVP_get_digestbyobj(digestoid); + if (!digest) { + CMSerror(CMS_R_UNKNOWN_DIGEST_ALGORITHM); + goto err; + } + mdbio = BIO_new(BIO_f_md()); + if (mdbio == NULL || !BIO_set_md(mdbio, digest)) { + CMSerror(CMS_R_MD_BIO_INIT_ERROR); + goto err; + } + return mdbio; + + err: + BIO_free(mdbio); + + return NULL; +} + +/* Locate a message digest content from a BIO chain based on SignerInfo */ + +int +cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg) +{ + int nid; + const ASN1_OBJECT *mdoid; + + X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); + nid = OBJ_obj2nid(mdoid); + /* Look for digest type to match signature */ + for (;;) { + EVP_MD_CTX *mtmp; + chain = BIO_find_type(chain, BIO_TYPE_MD); + if (chain == NULL) { + CMSerror(CMS_R_NO_MATCHING_DIGEST); + return 0; + } + BIO_get_md_ctx(chain, &mtmp); + if (EVP_MD_CTX_type(mtmp) == nid + /* + * Workaround for broken implementations that use signature + * algorithm OID instead of digest. + */ + || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) + return EVP_MD_CTX_copy_ex(mctx, mtmp); + chain = BIO_next(chain); + } +} + +static STACK_OF(CMS_CertificateChoices) ** +cms_get0_certificate_choices(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + case NID_pkcs7_signed: + return &cms->d.signedData->certificates; + + case NID_pkcs7_enveloped: + if (cms->d.envelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.envelopedData->originatorInfo->certificates; + + default: + CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + } +} + +CMS_CertificateChoices * +CMS_add0_CertificateChoices(CMS_ContentInfo *cms) +{ + STACK_OF(CMS_CertificateChoices) **pcerts; + CMS_CertificateChoices *cch; + + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return NULL; + if (!*pcerts) + *pcerts = sk_CMS_CertificateChoices_new_null(); + if (!*pcerts) + return NULL; + cch = (CMS_CertificateChoices *)ASN1_item_new(&CMS_CertificateChoices_it); + if (!cch) + return NULL; + if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { + ASN1_item_free((ASN1_VALUE *)cch, &CMS_CertificateChoices_it); + return NULL; + } + + return cch; +} +LCRYPTO_ALIAS(CMS_add0_CertificateChoices); + +int +CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) +{ + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + int i; + + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return 0; + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == CMS_CERTCHOICE_CERT) { + if (!X509_cmp(cch->d.certificate, cert)) { + CMSerror(CMS_R_CERTIFICATE_ALREADY_PRESENT); + return 0; + } + } + } + cch = CMS_add0_CertificateChoices(cms); + if (!cch) + return 0; + cch->type = CMS_CERTCHOICE_CERT; + cch->d.certificate = cert; + + return 1; +} +LCRYPTO_ALIAS(CMS_add0_cert); + +int +CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) +{ + int r; + + r = CMS_add0_cert(cms, cert); + if (r > 0) + X509_up_ref(cert); + + return r; +} +LCRYPTO_ALIAS(CMS_add1_cert); + +static STACK_OF(CMS_RevocationInfoChoice) ** +cms_get0_revocation_choices(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + case NID_pkcs7_signed: + return &cms->d.signedData->crls; + + case NID_pkcs7_enveloped: + if (cms->d.envelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.envelopedData->originatorInfo->crls; + + default: + CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + } +} + +CMS_RevocationInfoChoice * +CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) +{ + STACK_OF(CMS_RevocationInfoChoice) **pcrls; + CMS_RevocationInfoChoice *rch; + + pcrls = cms_get0_revocation_choices(cms); + if (!pcrls) + return NULL; + if (!*pcrls) + *pcrls = sk_CMS_RevocationInfoChoice_new_null(); + if (!*pcrls) + return NULL; + rch = (CMS_RevocationInfoChoice *)ASN1_item_new(&CMS_RevocationInfoChoice_it); + if (!rch) + return NULL; + if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { + ASN1_item_free((ASN1_VALUE *)rch, &CMS_RevocationInfoChoice_it); + return NULL; + } + + return rch; +} +LCRYPTO_ALIAS(CMS_add0_RevocationInfoChoice); + +int +CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) +{ + CMS_RevocationInfoChoice *rch; + + rch = CMS_add0_RevocationInfoChoice(cms); + if (!rch) + return 0; + rch->type = CMS_REVCHOICE_CRL; + rch->d.crl = crl; + + return 1; +} +LCRYPTO_ALIAS(CMS_add0_crl); + +int +CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) +{ + int r; + + r = CMS_add0_crl(cms, crl); + if (r > 0) + X509_CRL_up_ref(crl); + + return r; +} +LCRYPTO_ALIAS(CMS_add1_crl); + +STACK_OF(X509) * +CMS_get1_certs(CMS_ContentInfo *cms) +{ + STACK_OF(X509) *certs = NULL; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + int i; + + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return NULL; + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == 0) { + if (!certs) { + certs = sk_X509_new_null(); + if (!certs) + return NULL; + } + if (!sk_X509_push(certs, cch->d.certificate)) { + sk_X509_pop_free(certs, X509_free); + return NULL; + } + X509_up_ref(cch->d.certificate); + } + } + return certs; +} +LCRYPTO_ALIAS(CMS_get1_certs); + +STACK_OF(X509_CRL) * +CMS_get1_crls(CMS_ContentInfo *cms) +{ + STACK_OF(X509_CRL) *crls = NULL; + STACK_OF(CMS_RevocationInfoChoice) **pcrls; + CMS_RevocationInfoChoice *rch; + int i; + + pcrls = cms_get0_revocation_choices(cms); + if (!pcrls) + return NULL; + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { + rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); + if (rch->type == 0) { + if (!crls) { + crls = sk_X509_CRL_new_null(); + if (!crls) + return NULL; + } + if (!sk_X509_CRL_push(crls, rch->d.crl)) { + sk_X509_CRL_pop_free(crls, X509_CRL_free); + return NULL; + } + X509_CRL_up_ref(rch->d.crl); + } + } + return crls; +} +LCRYPTO_ALIAS(CMS_get1_crls); + +static const ASN1_OCTET_STRING * +cms_X509_get0_subject_key_id(X509 *x) +{ + /* Call for side-effect of computing hash and caching extensions */ + X509_check_purpose(x, -1, -1); + return x->skid; +} + +int +cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) +{ + int ret; + + ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); + if (ret) + return ret; + + return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert)); +} + +int +cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) +{ + const ASN1_OCTET_STRING *cert_keyid = cms_X509_get0_subject_key_id(cert); + + if (cert_keyid == NULL) + return -1; + + return ASN1_OCTET_STRING_cmp(keyid, cert_keyid); +} + +int +cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) +{ + CMS_IssuerAndSerialNumber *ias; + + ias = (CMS_IssuerAndSerialNumber *)ASN1_item_new(&CMS_IssuerAndSerialNumber_it); + if (!ias) + goto err; + if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) + goto err; + if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert))) + goto err; + ASN1_item_free((ASN1_VALUE *)*pias, &CMS_IssuerAndSerialNumber_it); + *pias = ias; + + return 1; + + err: + ASN1_item_free((ASN1_VALUE *)ias, &CMS_IssuerAndSerialNumber_it); + CMSerror(ERR_R_MALLOC_FAILURE); + + return 0; +} + +int +cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) +{ + ASN1_OCTET_STRING *keyid = NULL; + const ASN1_OCTET_STRING *cert_keyid; + + cert_keyid = cms_X509_get0_subject_key_id(cert); + if (cert_keyid == NULL) { + CMSerror(CMS_R_CERTIFICATE_HAS_NO_KEYID); + return 0; + } + keyid = ASN1_STRING_dup(cert_keyid); + if (!keyid) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OCTET_STRING_free(*pkeyid); + *pkeyid = keyid; + + return 1; +} diff --git a/Libraries/libressl/crypto/cms/cms_local.h b/Libraries/libressl/crypto/cms/cms_local.h new file mode 100644 index 000000000..2e3a3637e --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_local.h @@ -0,0 +1,477 @@ +/* $OpenBSD: cms_local.h,v 1.5 2023/08/24 04:56:36 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_LOCAL_H +#define HEADER_CMS_LOCAL_H + +#include + +/* + * Cryptographic message syntax (CMS) structures: taken from RFC3852 + */ + +/* Forward references */ + +typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber; +typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo; +typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier; +typedef struct CMS_SignedData_st CMS_SignedData; +typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat; +typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo; +typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo; +typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; +typedef struct CMS_DigestedData_st CMS_DigestedData; +typedef struct CMS_EncryptedData_st CMS_EncryptedData; +typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; +typedef struct CMS_CompressedData_st CMS_CompressedData; +typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; +typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; +typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey; +typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey; +typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo; +typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier; +typedef struct CMS_KeyAgreeRecipientIdentifier_st + CMS_KeyAgreeRecipientIdentifier; +typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier; +typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; +typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; +typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; +typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; + +struct CMS_ContentInfo_st { + ASN1_OBJECT *contentType; + union { + ASN1_OCTET_STRING *data; + CMS_SignedData *signedData; + CMS_EnvelopedData *envelopedData; + CMS_DigestedData *digestedData; + CMS_EncryptedData *encryptedData; + CMS_AuthenticatedData *authenticatedData; + CMS_CompressedData *compressedData; + ASN1_TYPE *other; + /* Other types ... */ + void *otherData; + } d; +}; + +DECLARE_STACK_OF(CMS_CertificateChoices) + +struct CMS_SignedData_st { + long version; + STACK_OF(X509_ALGOR) *digestAlgorithms; + CMS_EncapsulatedContentInfo *encapContentInfo; + STACK_OF(CMS_CertificateChoices) *certificates; + STACK_OF(CMS_RevocationInfoChoice) *crls; + STACK_OF(CMS_SignerInfo) *signerInfos; +}; + +struct CMS_EncapsulatedContentInfo_st { + ASN1_OBJECT *eContentType; + ASN1_OCTET_STRING *eContent; + /* Set to 1 if incomplete structure only part set up */ + int partial; +}; + +struct CMS_SignerInfo_st { + long version; + CMS_SignerIdentifier *sid; + X509_ALGOR *digestAlgorithm; + STACK_OF(X509_ATTRIBUTE) *signedAttrs; + X509_ALGOR *signatureAlgorithm; + ASN1_OCTET_STRING *signature; + STACK_OF(X509_ATTRIBUTE) *unsignedAttrs; + /* Signing certificate and key */ + X509 *signer; + EVP_PKEY *pkey; + /* Digest and public key context for alternative parameters */ + EVP_MD_CTX *mctx; + EVP_PKEY_CTX *pctx; +}; + +struct CMS_SignerIdentifier_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + ASN1_OCTET_STRING *subjectKeyIdentifier; + } d; +}; + +struct CMS_EnvelopedData_st { + long version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncryptedContentInfo *encryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; +}; + +struct CMS_OriginatorInfo_st { + STACK_OF(CMS_CertificateChoices) *certificates; + STACK_OF(CMS_RevocationInfoChoice) *crls; +}; + +struct CMS_EncryptedContentInfo_st { + ASN1_OBJECT *contentType; + X509_ALGOR *contentEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedContent; + /* Content encryption algorithm and key */ + const EVP_CIPHER *cipher; + unsigned char *key; + size_t keylen; + /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ + int debug; + /* Set to 1 if we have no cert and need extra safety measures for MMA */ + int havenocert; +}; + +struct CMS_RecipientInfo_st { + int type; + union { + CMS_KeyTransRecipientInfo *ktri; + CMS_KeyAgreeRecipientInfo *kari; + CMS_KEKRecipientInfo *kekri; + CMS_PasswordRecipientInfo *pwri; + CMS_OtherRecipientInfo *ori; + } d; +}; + +typedef CMS_SignerIdentifier CMS_RecipientIdentifier; + +struct CMS_KeyTransRecipientInfo_st { + long version; + CMS_RecipientIdentifier *rid; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Recipient Key and cert */ + X509 *recip; + EVP_PKEY *pkey; + /* Public key context for this operation */ + EVP_PKEY_CTX *pctx; +}; + +struct CMS_KeyAgreeRecipientInfo_st { + long version; + CMS_OriginatorIdentifierOrKey *originator; + ASN1_OCTET_STRING *ukm; + X509_ALGOR *keyEncryptionAlgorithm; + STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys; + /* Public key context associated with current operation */ + EVP_PKEY_CTX *pctx; + /* Cipher context for CEK wrapping */ + EVP_CIPHER_CTX *ctx; +}; + +struct CMS_OriginatorIdentifierOrKey_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + ASN1_OCTET_STRING *subjectKeyIdentifier; + CMS_OriginatorPublicKey *originatorKey; + } d; +}; + +struct CMS_OriginatorPublicKey_st { + X509_ALGOR *algorithm; + ASN1_BIT_STRING *publicKey; +}; + +struct CMS_RecipientEncryptedKey_st { + CMS_KeyAgreeRecipientIdentifier *rid; + ASN1_OCTET_STRING *encryptedKey; + /* Public key associated with this recipient */ + EVP_PKEY *pkey; +}; + +struct CMS_KeyAgreeRecipientIdentifier_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + CMS_RecipientKeyIdentifier *rKeyId; + } d; +}; + +struct CMS_RecipientKeyIdentifier_st { + ASN1_OCTET_STRING *subjectKeyIdentifier; + ASN1_GENERALIZEDTIME *date; + CMS_OtherKeyAttribute *other; +}; + +struct CMS_KEKRecipientInfo_st { + long version; + CMS_KEKIdentifier *kekid; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Extra info: symmetric key to use */ + unsigned char *key; + size_t keylen; +}; + +struct CMS_KEKIdentifier_st { + ASN1_OCTET_STRING *keyIdentifier; + ASN1_GENERALIZEDTIME *date; + CMS_OtherKeyAttribute *other; +}; + +struct CMS_PasswordRecipientInfo_st { + long version; + X509_ALGOR *keyDerivationAlgorithm; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Extra info: password to use */ + unsigned char *pass; + size_t passlen; +}; + +struct CMS_OtherRecipientInfo_st { + ASN1_OBJECT *oriType; + ASN1_TYPE *oriValue; +}; + +struct CMS_DigestedData_st { + long version; + X509_ALGOR *digestAlgorithm; + CMS_EncapsulatedContentInfo *encapContentInfo; + ASN1_OCTET_STRING *digest; +}; + +struct CMS_EncryptedData_st { + long version; + CMS_EncryptedContentInfo *encryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; +}; + +struct CMS_AuthenticatedData_st { + long version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + X509_ALGOR *macAlgorithm; + X509_ALGOR *digestAlgorithm; + CMS_EncapsulatedContentInfo *encapContentInfo; + STACK_OF(X509_ATTRIBUTE) *authAttrs; + ASN1_OCTET_STRING *mac; + STACK_OF(X509_ATTRIBUTE) *unauthAttrs; +}; + +struct CMS_CompressedData_st { + long version; + X509_ALGOR *compressionAlgorithm; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncapsulatedContentInfo *encapContentInfo; +}; + +struct CMS_RevocationInfoChoice_st { + int type; + union { + X509_CRL *crl; + CMS_OtherRevocationInfoFormat *other; + } d; +}; + +#define CMS_REVCHOICE_CRL 0 +#define CMS_REVCHOICE_OTHER 1 + +struct CMS_OtherRevocationInfoFormat_st { + ASN1_OBJECT *otherRevInfoFormat; + ASN1_TYPE *otherRevInfo; +}; + +struct CMS_CertificateChoices { + int type; + union { + X509 *certificate; + ASN1_STRING *extendedCertificate; /* Obsolete */ + ASN1_STRING *v1AttrCert; /* Left encoded for now */ + ASN1_STRING *v2AttrCert; /* Left encoded for now */ + CMS_OtherCertificateFormat *other; + } d; +}; + +#define CMS_CERTCHOICE_CERT 0 +#define CMS_CERTCHOICE_EXCERT 1 +#define CMS_CERTCHOICE_V1ACERT 2 +#define CMS_CERTCHOICE_V2ACERT 3 +#define CMS_CERTCHOICE_OTHER 4 + +struct CMS_OtherCertificateFormat_st { + ASN1_OBJECT *otherCertFormat; + ASN1_TYPE *otherCert; +}; + +/* + * This is also defined in pkcs7.h but we duplicate it to allow the CMS code + * to be independent of PKCS#7 + */ + +struct CMS_IssuerAndSerialNumber_st { + X509_NAME *issuer; + ASN1_INTEGER *serialNumber; +}; + +struct CMS_OtherKeyAttribute_st { + ASN1_OBJECT *keyAttrId; + ASN1_TYPE *keyAttr; +}; + +/* ESS structures */ + +#ifdef HEADER_X509V3_H + +struct CMS_ReceiptRequest_st { + ASN1_OCTET_STRING *signedContentIdentifier; + CMS_ReceiptsFrom *receiptsFrom; + STACK_OF(GENERAL_NAMES) *receiptsTo; +}; + +struct CMS_ReceiptsFrom_st { + int type; + union { + long allOrFirstTier; + STACK_OF(GENERAL_NAMES) *receiptList; + } d; +}; +#endif + +struct CMS_Receipt_st { + long version; + ASN1_OBJECT *contentType; + ASN1_OCTET_STRING *signedContentIdentifier; + ASN1_OCTET_STRING *originatorSignatureValue; +}; + +extern const ASN1_ITEM CMS_SignerInfo_it; +extern const ASN1_ITEM CMS_IssuerAndSerialNumber_it; +extern const ASN1_ITEM CMS_Attributes_Sign_it; +extern const ASN1_ITEM CMS_Attributes_Verify_it; +extern const ASN1_ITEM CMS_RecipientInfo_it; +extern const ASN1_ITEM CMS_PasswordRecipientInfo_it; +CMS_IssuerAndSerialNumber *CMS_IssuerAndSerialNumber_new(void); +void CMS_IssuerAndSerialNumber_free(CMS_IssuerAndSerialNumber *a); + +#define CMS_SIGNERINFO_ISSUER_SERIAL 0 +#define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +#define CMS_RECIPINFO_ISSUER_SERIAL 0 +#define CMS_RECIPINFO_KEYIDENTIFIER 1 + +#define CMS_REK_ISSUER_SERIAL 0 +#define CMS_REK_KEYIDENTIFIER 1 + +#define CMS_OIK_ISSUER_SERIAL 0 +#define CMS_OIK_KEYIDENTIFIER 1 +#define CMS_OIK_PUBKEY 2 + +CMS_ContentInfo *cms_Data_create(void); + +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms); +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify); + +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type); +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno); +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); + +CMS_ContentInfo *cms_CompressedData_create(int comp_nid); +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms); + +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg); + +int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert); +int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert); +int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); +int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); + +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms); +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen); + +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); + +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); +int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); +int cms_pkey_get_ri_type(EVP_PKEY *pk); +/* KARI routines */ +int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *pk, unsigned int flags); +int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +/* PWRI routines */ +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + int en_de); + +extern const ASN1_ITEM CMS_CertificateChoices_it; +extern const ASN1_ITEM CMS_DigestedData_it; +extern const ASN1_ITEM CMS_EncryptedData_it; +extern const ASN1_ITEM CMS_EnvelopedData_it; +extern const ASN1_ITEM CMS_KEKRecipientInfo_it; +extern const ASN1_ITEM CMS_KeyAgreeRecipientInfo_it; +extern const ASN1_ITEM CMS_KeyTransRecipientInfo_it; +extern const ASN1_ITEM CMS_OriginatorPublicKey_it; +extern const ASN1_ITEM CMS_OtherKeyAttribute_it; +extern const ASN1_ITEM CMS_Receipt_it; +extern const ASN1_ITEM CMS_ReceiptRequest_it; +extern const ASN1_ITEM CMS_RecipientEncryptedKey_it; +extern const ASN1_ITEM CMS_RecipientKeyIdentifier_it; +extern const ASN1_ITEM CMS_RevocationInfoChoice_it; +extern const ASN1_ITEM CMS_SignedData_it; +extern const ASN1_ITEM CMS_CompressedData_it; + +#endif /* !HEADER_CMS_LOCAL_H */ diff --git a/Libraries/libressl/crypto/cms/cms_pwri.c b/Libraries/libressl/crypto/cms/cms_pwri.c new file mode 100644 index 000000000..9ea7cfdcb --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_pwri.c @@ -0,0 +1,435 @@ +/* $OpenBSD: cms_pwri.c,v 1.29 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include "cms_local.h" +#include "asn1/asn1_local.h" + +int +CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass, + ssize_t passlen) +{ + CMS_PasswordRecipientInfo *pwri; + + if (ri->type != CMS_RECIPINFO_PASS) { + CMSerror(CMS_R_NOT_PWRI); + return 0; + } + + pwri = ri->d.pwri; + pwri->pass = pass; + if (pass && passlen < 0) + passlen = strlen((char *)pass); + pwri->passlen = passlen; + + return 1; +} +LCRYPTO_ALIAS(CMS_RecipientInfo_set0_password); + +CMS_RecipientInfo * +CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, int wrap_nid, + int pbe_nid, unsigned char *pass, ssize_t passlen, + const EVP_CIPHER *kekciph) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + CMS_PasswordRecipientInfo *pwri; + EVP_CIPHER_CTX *ctx = NULL; + X509_ALGOR *encalg = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + int ivlen; + + env = cms_get0_enveloped(cms); + if (!env) + return NULL; + + if (wrap_nid <= 0) + wrap_nid = NID_id_alg_PWRI_KEK; + + if (pbe_nid <= 0) + pbe_nid = NID_id_pbkdf2; + + /* Get from enveloped data */ + if (kekciph == NULL) + kekciph = env->encryptedContentInfo->cipher; + + if (kekciph == NULL) { + CMSerror(CMS_R_NO_CIPHER); + return NULL; + } + if (wrap_nid != NID_id_alg_PWRI_KEK) { + CMSerror(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + return NULL; + } + + /* Setup algorithm identifier for cipher */ + encalg = X509_ALGOR_new(); + if (encalg == NULL) { + goto merr; + } + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + goto merr; + + if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) { + CMSerror(ERR_R_EVP_LIB); + goto err; + } + + ivlen = EVP_CIPHER_CTX_iv_length(ctx); + + if (ivlen > 0) { + arc4random_buf(iv, ivlen); + if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) { + CMSerror(ERR_R_EVP_LIB); + goto err; + } + encalg->parameter = ASN1_TYPE_new(); + if (!encalg->parameter) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) { + CMSerror(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + } + + encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* Initialize recipient info */ + ri = (CMS_RecipientInfo *)ASN1_item_new(&CMS_RecipientInfo_it); + if (ri == NULL) + goto merr; + + ri->d.pwri = (CMS_PasswordRecipientInfo *)ASN1_item_new(&CMS_PasswordRecipientInfo_it); + if (ri->d.pwri == NULL) + goto merr; + ri->type = CMS_RECIPINFO_PASS; + + pwri = ri->d.pwri; + /* Since this is overwritten, free up empty structure already there */ + X509_ALGOR_free(pwri->keyEncryptionAlgorithm); + pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); + if (pwri->keyEncryptionAlgorithm == NULL) + goto merr; + pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); + pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); + if (pwri->keyEncryptionAlgorithm->parameter == NULL) + goto merr; + + if (!ASN1_item_pack(encalg, &X509_ALGOR_it, + &pwri->keyEncryptionAlgorithm->parameter->value.sequence)) + goto merr; + pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; + + X509_ALGOR_free(encalg); + encalg = NULL; + + /* Setup PBE algorithm */ + + pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); + + if (!pwri->keyDerivationAlgorithm) + goto err; + + CMS_RecipientInfo_set0_password(ri, pass, passlen); + pwri->version = 0; + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + return ri; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + err: + EVP_CIPHER_CTX_free(ctx); + if (ri) + ASN1_item_free((ASN1_VALUE *)ri, &CMS_RecipientInfo_it); + X509_ALGOR_free(encalg); + + return NULL; +} +LCRYPTO_ALIAS(CMS_add0_recipient_password); + +/* + * This is an implementation of the key wrapping mechanism in RFC3211, at + * some point this should go into EVP. + */ + +static int +kek_unwrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, + size_t inlen, EVP_CIPHER_CTX *ctx) +{ + size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + unsigned char *tmp; + int outl, rv = 0; + + if (inlen < 2 * blocklen) { + /* too small */ + return 0; + } + if (inlen % blocklen) { + /* Invalid size */ + return 0; + } + if ((tmp = malloc(inlen)) == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + /* setup IV by decrypting last two blocks */ + if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, + in + inlen - 2 * blocklen, blocklen * 2) + /* + * Do a decrypt of last decrypted block to set IV to correct value + * output it to start of buffer so we don't corrupt decrypted block + * this works because buffer is at least two block lengths long. + */ + || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen) + /* Can now decrypt first n - 1 blocks */ + || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen) + + /* Reset IV to original value */ + || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL) + /* Decrypt again */ + || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen)) + goto err; + /* Check check bytes */ + if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) { + /* Check byte failure */ + goto err; + } + if (inlen < (size_t)(tmp[0] - 4)) { + /* Invalid length value */ + goto err; + } + *outlen = (size_t)tmp[0]; + memcpy(out, tmp + 4, *outlen); + rv = 1; + + err: + freezero(tmp, inlen); + + return rv; +} + +static int +kek_wrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, + size_t inlen, EVP_CIPHER_CTX *ctx) +{ + size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + size_t olen; + int dummy; + + /* + * First decide length of output buffer: need header and round up to + * multiple of block length. + */ + olen = (inlen + 4 + blocklen - 1) / blocklen; + olen *= blocklen; + if (olen < 2 * blocklen) { + /* Key too small */ + return 0; + } + if (inlen > 0xFF) { + /* Key too large */ + return 0; + } + if (out) { + /* Set header */ + out[0] = (unsigned char)inlen; + out[1] = in[0] ^ 0xFF; + out[2] = in[1] ^ 0xFF; + out[3] = in[2] ^ 0xFF; + memcpy(out + 4, in, inlen); + /* Add random padding to end */ + if (olen > inlen + 4) + arc4random_buf(out + 4 + inlen, olen - 4 - inlen); + /* Encrypt twice */ + if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) || + !EVP_EncryptUpdate(ctx, out, &dummy, out, olen)) + return 0; + } + + *outlen = olen; + + return 1; +} + +/* Encrypt/Decrypt content key in PWRI recipient info */ + +int +cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + int en_de) +{ + CMS_EncryptedContentInfo *ec; + CMS_PasswordRecipientInfo *pwri; + int r = 0; + X509_ALGOR *algtmp, *kekalg = NULL; + EVP_CIPHER_CTX *kekctx = NULL; + const EVP_CIPHER *kekcipher; + unsigned char *key = NULL; + size_t keylen; + + ec = cms->d.envelopedData->encryptedContentInfo; + + pwri = ri->d.pwri; + + if (!pwri->pass) { + CMSerror(CMS_R_NO_PASSWORD); + return 0; + } + algtmp = pwri->keyEncryptionAlgorithm; + + if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { + CMSerror(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + return 0; + } + + if (algtmp->parameter != NULL && + algtmp->parameter->type == V_ASN1_SEQUENCE && + algtmp->parameter->value.sequence != NULL) + kekalg = ASN1_item_unpack(algtmp->parameter->value.sequence, + &X509_ALGOR_it); + + if (kekalg == NULL) { + CMSerror(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); + return 0; + } + + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + if (!kekcipher) { + CMSerror(CMS_R_UNKNOWN_CIPHER); + return 0; + } + + kekctx = EVP_CIPHER_CTX_new(); + if (kekctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ + if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de)) + goto err; + EVP_CIPHER_CTX_set_padding(kekctx, 0); + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) { + CMSerror(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + + algtmp = pwri->keyDerivationAlgorithm; + + /* Finish password based key derivation to setup key in "ctx" */ + + if (EVP_PBE_CipherInit(algtmp->algorithm, (char *)pwri->pass, + pwri->passlen, algtmp->parameter, kekctx, en_de) < 0) { + CMSerror(ERR_R_EVP_LIB); + goto err; + } + + /* Finally wrap/unwrap the key */ + + if (en_de) { + if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) + goto err; + + key = malloc(keylen); + if (key == NULL) + goto err; + + if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx)) + goto err; + pwri->encryptedKey->data = key; + pwri->encryptedKey->length = keylen; + } else { + key = malloc(pwri->encryptedKey->length); + if (key == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data, + pwri->encryptedKey->length, kekctx)) { + CMSerror(CMS_R_UNWRAP_FAILURE); + goto err; + } + + freezero(ec->key, ec->keylen); + ec->key = key; + ec->keylen = keylen; + } + + r = 1; + + err: + EVP_CIPHER_CTX_free(kekctx); + if (!r) + free(key); + X509_ALGOR_free(kekalg); + + return r; +} diff --git a/Libraries/libressl/crypto/cms/cms_sd.c b/Libraries/libressl/crypto/cms/cms_sd.c new file mode 100644 index 000000000..245822971 --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_sd.c @@ -0,0 +1,1029 @@ +/* $OpenBSD: cms_sd.c,v 1.28 2023/09/11 09:29:30 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_local.h" +#include "asn1/asn1_local.h" +#include "evp/evp_local.h" + +/* CMS SignedData Utilities */ + +static CMS_SignedData * +cms_get0_signed(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { + CMSerror(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); + return NULL; + } + return cms->d.signedData; +} + +static CMS_SignedData * +cms_signed_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.signedData = (CMS_SignedData *)ASN1_item_new(&CMS_SignedData_it); + if (!cms->d.signedData) { + CMSerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + cms->d.signedData->version = 1; + cms->d.signedData->encapContentInfo->eContentType = + OBJ_nid2obj(NID_pkcs7_data); + cms->d.signedData->encapContentInfo->partial = 1; + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); + return cms->d.signedData; + } + return cms_get0_signed(cms); +} + +/* Just initialise SignedData e.g. for certs only structure */ + +int +CMS_SignedData_init(CMS_ContentInfo *cms) +{ + if (cms_signed_data_init(cms)) + return 1; + else + return 0; +} +LCRYPTO_ALIAS(CMS_SignedData_init); + +/* Check structures and fixup version numbers (if necessary) */ + +static void +cms_sd_set_version(CMS_SignedData *sd) +{ + int i; + CMS_CertificateChoices *cch; + CMS_RevocationInfoChoice *rch; + CMS_SignerInfo *si; + + for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { + cch = sk_CMS_CertificateChoices_value(sd->certificates, i); + if (cch->type == CMS_CERTCHOICE_OTHER) { + if (sd->version < 5) + sd->version = 5; + } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { + if (sd->version < 4) + sd->version = 4; + } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { + if (sd->version < 3) + sd->version = 3; + } + } + + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { + rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); + if (rch->type == CMS_REVCHOICE_OTHER) { + if (sd->version < 5) + sd->version = 5; + } + } + + if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) + && (sd->version < 3)) + sd->version = 3; + + for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { + si = sk_CMS_SignerInfo_value(sd->signerInfos, i); + if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + if (si->version < 3) + si->version = 3; + if (sd->version < 3) + sd->version = 3; + } else if (si->version < 1) + si->version = 1; + } + + if (sd->version < 1) + sd->version = 1; +} + +/* Copy an existing messageDigest value */ + +static int +cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) +{ + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *sitmp; + int i; + + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + ASN1_OCTET_STRING *messageDigest; + sitmp = sk_CMS_SignerInfo_value(sinfos, i); + if (sitmp == si) + continue; + if (CMS_signed_get_attr_count(sitmp) < 0) + continue; + if (OBJ_cmp(si->digestAlgorithm->algorithm, + sitmp->digestAlgorithm->algorithm)) + continue; + messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, + OBJ_nid2obj(NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING); + if (!messageDigest) { + CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + return 0; + } + + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, messageDigest, -1)) + return 1; + else + return 0; + } + + CMSerror(CMS_R_NO_MATCHING_DIGEST); + + return 0; +} + +int +cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) +{ + switch (type) { + case CMS_SIGNERINFO_ISSUER_SERIAL: + if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) + return 0; + break; + + case CMS_SIGNERINFO_KEYIDENTIFIER: + if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) + return 0; + break; + + default: + CMSerror(CMS_R_UNKNOWN_ID); + return 0; + } + + sid->type = type; + + return 1; +} + +int +cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) +{ + if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { + if (issuer) + *issuer = sid->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = sid->d.issuerAndSerialNumber->serialNumber; + } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + if (keyid) + *keyid = sid->d.subjectKeyIdentifier; + } else + return 0; + + return 1; +} + +int +cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) +{ + if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) + return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); + else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) + return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); + else + return -1; +} + +static int +cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) +{ + EVP_PKEY *pkey = si->pkey; + int ret; + + if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) + return 1; + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); + if (ret == -2) { + CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + if (ret <= 0) { + CMSerror(CMS_R_CTRL_FAILURE); + return 0; + } + + return 1; +} + +CMS_SignerInfo * +CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, + const EVP_MD *md, unsigned int flags) +{ + CMS_SignedData *sd; + CMS_SignerInfo *si = NULL; + X509_ALGOR *alg; + int i, type; + + if (!X509_check_private_key(signer, pk)) { + CMSerror(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + sd = cms_signed_data_init(cms); + if (!sd) + goto err; + si = (CMS_SignerInfo *)ASN1_item_new(&CMS_SignerInfo_it); + if (!si) + goto merr; + /* Call for side-effect of computing hash and caching extensions */ + X509_check_purpose(signer, -1, -1); + + X509_up_ref(signer); + EVP_PKEY_up_ref(pk); + + si->pkey = pk; + si->signer = signer; + si->mctx = EVP_MD_CTX_new(); + si->pctx = NULL; + + if (si->mctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (flags & CMS_USE_KEYID) { + si->version = 3; + if (sd->version < 3) + sd->version = 3; + type = CMS_SIGNERINFO_KEYIDENTIFIER; + } else { + type = CMS_SIGNERINFO_ISSUER_SERIAL; + si->version = 1; + } + + if (!cms_set1_SignerIdentifier(si->sid, signer, type)) + goto err; + + if (md == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) + goto err; + md = EVP_get_digestbynid(def_nid); + if (md == NULL) { + CMSerror(CMS_R_NO_DEFAULT_DIGEST); + goto err; + } + } + + if (!md) { + CMSerror(CMS_R_NO_DIGEST_SET); + goto err; + } + + X509_ALGOR_set_md(si->digestAlgorithm, md); + + /* See if digest is present in digestAlgorithms */ + for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { + const ASN1_OBJECT *aoid; + alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); + X509_ALGOR_get0(&aoid, NULL, NULL, alg); + if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) + break; + } + + if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { + alg = X509_ALGOR_new(); + if (alg == NULL) + goto merr; + X509_ALGOR_set_md(alg, md); + if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { + X509_ALGOR_free(alg); + goto merr; + } + } + + if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) + goto err; + if (!(flags & CMS_NOATTR)) { + /* + * Initialize signed attributes structure so other attributes + * such as signing time etc are added later even if we add none here. + */ + if (!si->signedAttrs) { + si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); + if (!si->signedAttrs) + goto merr; + } + + if (!(flags & CMS_NOSMIMECAP)) { + STACK_OF(X509_ALGOR) *smcap = NULL; + + i = CMS_add_standard_smimecap(&smcap); + if (i) + i = CMS_add_smimecap(si, smcap); + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + if (!i) + goto merr; + } + if (flags & CMS_REUSE_DIGEST) { + if (!cms_copy_messageDigest(cms, si)) + goto err; + if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && + !CMS_SignerInfo_sign(si)) + goto err; + } + } + + if (!(flags & CMS_NOCERTS)) { + /* NB ignore -1 return for duplicate cert */ + if (!CMS_add1_cert(cms, signer)) + goto merr; + } + + if (flags & CMS_KEY_PARAM) { + if (flags & CMS_NOATTR) { + si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); + if (si->pctx == NULL) + goto err; + if (EVP_PKEY_sign_init(si->pctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) + goto err; + } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, + NULL, pk) <= 0) + goto err; + } + + if (!sd->signerInfos) + sd->signerInfos = sk_CMS_SignerInfo_new_null(); + if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) + goto merr; + + return si; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + err: + ASN1_item_free((ASN1_VALUE *)si, &CMS_SignerInfo_it); + + return NULL; +} +LCRYPTO_ALIAS(CMS_add1_signer); + +static int +cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) +{ + ASN1_TIME *tt; + int r = 0; + + if (t) + tt = t; + else + tt = X509_gmtime_adj(NULL, 0); + + if (!tt) + goto merr; + + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, + tt->type, tt, -1) <= 0) + goto merr; + + r = 1; + + merr: + if (!t) + ASN1_TIME_free(tt); + if (!r) + CMSerror(ERR_R_MALLOC_FAILURE); + + return r; +} + +EVP_PKEY_CTX * +CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si) +{ + return si->pctx; +} +LCRYPTO_ALIAS(CMS_SignerInfo_get0_pkey_ctx); + +EVP_MD_CTX * +CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) +{ + return si->mctx; +} +LCRYPTO_ALIAS(CMS_SignerInfo_get0_md_ctx); + +STACK_OF(CMS_SignerInfo) * +CMS_get0_SignerInfos(CMS_ContentInfo *cms) +{ + CMS_SignedData *sd; + + sd = cms_get0_signed(cms); + if (!sd) + return NULL; + + return sd->signerInfos; +} +LCRYPTO_ALIAS(CMS_get0_SignerInfos); + +STACK_OF(X509) * +CMS_get0_signers(CMS_ContentInfo *cms) +{ + STACK_OF(X509) *signers = NULL; + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *si; + int i; + + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (si->signer) { + if (!signers) { + signers = sk_X509_new_null(); + if (!signers) + return NULL; + } + if (!sk_X509_push(signers, si->signer)) { + sk_X509_free(signers); + return NULL; + } + } + } + + return signers; +} +LCRYPTO_ALIAS(CMS_get0_signers); + +void +CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) +{ + if (signer) { + X509_up_ref(signer); + EVP_PKEY_free(si->pkey); + si->pkey = X509_get_pubkey(signer); + } + X509_free(si->signer); + si->signer = signer; +} +LCRYPTO_ALIAS(CMS_SignerInfo_set1_signer_cert); + +int +CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno) +{ + return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); +} +LCRYPTO_ALIAS(CMS_SignerInfo_get0_signer_id); + +int +CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) +{ + return cms_SignerIdentifier_cert_cmp(si->sid, cert); +} +LCRYPTO_ALIAS(CMS_SignerInfo_cert_cmp); + +int +CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, + unsigned int flags) +{ + CMS_SignedData *sd; + CMS_SignerInfo *si; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) *certs; + X509 *x; + int i, j; + int ret = 0; + + sd = cms_get0_signed(cms); + if (!sd) + return -1; + certs = sd->certificates; + for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { + si = sk_CMS_SignerInfo_value(sd->signerInfos, i); + if (si->signer) + continue; + + for (j = 0; j < sk_X509_num(scerts); j++) { + x = sk_X509_value(scerts, j); + if (CMS_SignerInfo_cert_cmp(si, x) == 0) { + CMS_SignerInfo_set1_signer_cert(si, x); + ret++; + break; + } + } + + if (si->signer || (flags & CMS_NOINTERN)) + continue; + + for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { + cch = sk_CMS_CertificateChoices_value(certs, j); + if (cch->type != 0) + continue; + x = cch->d.certificate; + if (CMS_SignerInfo_cert_cmp(si, x) == 0) { + CMS_SignerInfo_set1_signer_cert(si, x); + ret++; + break; + } + } + } + return ret; +} +LCRYPTO_ALIAS(CMS_set1_signers_certs); + +void +CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, +X509_ALGOR **pdig, X509_ALGOR **psig) +{ + if (pk) + *pk = si->pkey; + if (signer) + *signer = si->signer; + if (pdig) + *pdig = si->digestAlgorithm; + if (psig) + *psig = si->signatureAlgorithm; +} +LCRYPTO_ALIAS(CMS_SignerInfo_get0_algs); + +ASN1_OCTET_STRING * +CMS_SignerInfo_get0_signature(CMS_SignerInfo *si) +{ + return si->signature; +} +LCRYPTO_ALIAS(CMS_SignerInfo_get0_signature); + +static int +cms_SignerInfo_content_sign(CMS_ContentInfo *cms, CMS_SignerInfo *si, BIO *chain) +{ + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + int r = 0; + EVP_PKEY_CTX *pctx = NULL; + + if (mctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!si->pkey) { + CMSerror(CMS_R_NO_PRIVATE_KEY); + goto err; + } + + if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) + goto err; + /* Set SignerInfo algorithm details if we used custom parameter */ + if (si->pctx && !cms_sd_asn1_ctrl(si, 0)) + goto err; + + /* + * If any signed attributes calculate and add messageDigest attribute + */ + + if (CMS_signed_get_attr_count(si) >= 0) { + ASN1_OBJECT *ctype = + cms->d.signedData->encapContentInfo->eContentType; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) + goto err; + if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, md, mdlen)) + goto err; + /* Copy content type across */ + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, ctype, -1) <= 0) + goto err; + if (!CMS_SignerInfo_sign(si)) + goto err; + } else if (si->pctx) { + unsigned char *sig; + size_t siglen; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + pctx = si->pctx; + if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) + goto err; + siglen = EVP_PKEY_size(si->pkey); + sig = malloc(siglen); + if (sig == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) { + free(sig); + goto err; + } + ASN1_STRING_set0(si->signature, sig, siglen); + } else { + unsigned char *sig; + unsigned int siglen; + + sig = malloc(EVP_PKEY_size(si->pkey)); + if (sig == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) { + CMSerror(CMS_R_SIGNFINAL_ERROR); + free(sig); + goto err; + } + ASN1_STRING_set0(si->signature, sig, siglen); + } + + r = 1; + + err: + EVP_MD_CTX_free(mctx); + EVP_PKEY_CTX_free(pctx); + + return r; +} + +int +cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) +{ + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *si; + int i; + + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (!cms_SignerInfo_content_sign(cms, si, chain)) + return 0; + } + cms->d.signedData->encapContentInfo->partial = 0; + + return 1; +} + +int +CMS_SignerInfo_sign(CMS_SignerInfo *si) +{ + const EVP_MD *md; + unsigned char *buf = NULL, *sig = NULL; + int buf_len = 0; + size_t sig_len = 0; + int ret = 0; + + if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL) + goto err; + + if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { + if (!cms_add1_signingTime(si, NULL)) + goto err; + } + + if (si->pctx == NULL) { + EVP_MD_CTX_reset(si->mctx); + if (!EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, si->pkey)) + goto err; + } + + if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { + CMSerror(CMS_R_CTRL_ERROR); + goto err; + } + + if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf, + &CMS_Attributes_Sign_it)) <= 0) { + buf_len = 0; + goto err; + } + if (!EVP_DigestSign(si->mctx, NULL, &sig_len, buf, buf_len)) + goto err; + if ((sig = calloc(1, sig_len)) == NULL) + goto err; + if (!EVP_DigestSign(si->mctx, sig, &sig_len, buf, buf_len)) + goto err; + + if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { + CMSerror(CMS_R_CTRL_ERROR); + goto err; + } + + ASN1_STRING_set0(si->signature, sig, sig_len); + sig = NULL; + + ret = 1; + + err: + if (si->mctx != NULL) + EVP_MD_CTX_reset(si->mctx); + freezero(buf, buf_len); + freezero(sig, sig_len); + + return ret; +} +LCRYPTO_ALIAS(CMS_SignerInfo_sign); + +int +CMS_SignerInfo_verify(CMS_SignerInfo *si) +{ + const EVP_MD *md; + unsigned char *buf = NULL; + int buf_len = 0; + int ret = -1; + + if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL) + goto err; + + if (si->pkey == NULL) { + CMSerror(CMS_R_NO_PUBLIC_KEY); + goto err; + } + + if (si->mctx == NULL) + si->mctx = EVP_MD_CTX_new(); + if (si->mctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_DigestVerifyInit(si->mctx, &si->pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (!cms_sd_asn1_ctrl(si, 1)) + goto err; + + if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf, + &CMS_Attributes_Verify_it)) <= 0) { + buf_len = 0; + goto err; + } + + ret = EVP_DigestVerify(si->mctx, si->signature->data, si->signature->length, + buf, buf_len); + if (ret <= 0) { + CMSerror(CMS_R_VERIFICATION_FAILURE); + goto err; + } + + err: + if (si->mctx != NULL) + EVP_MD_CTX_reset(si->mctx); + freezero(buf, buf_len); + + return ret; +} +LCRYPTO_ALIAS(CMS_SignerInfo_verify); + +/* Create a chain of digest BIOs from a CMS ContentInfo */ + +BIO * +cms_SignedData_init_bio(CMS_ContentInfo *cms) +{ + int i; + CMS_SignedData *sd; + BIO *chain = NULL; + + sd = cms_get0_signed(cms); + if (!sd) + return NULL; + if (cms->d.signedData->encapContentInfo->partial) + cms_sd_set_version(sd); + for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { + X509_ALGOR *digestAlgorithm; + BIO *mdbio; + digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); + mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); + if (!mdbio) + goto err; + if (chain) + BIO_push(chain, mdbio); + else + chain = mdbio; + } + + return chain; + + err: + BIO_free_all(chain); + + return NULL; +} + +int +CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) +{ + ASN1_OCTET_STRING *os = NULL; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + EVP_PKEY_CTX *pkctx = NULL; + int r = -1; + unsigned char mval[EVP_MAX_MD_SIZE]; + unsigned int mlen; + + if (mctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + /* If we have any signed attributes look for messageDigest value */ + if (CMS_signed_get_attr_count(si) >= 0) { + os = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_pkcs9_messageDigest), -3, + V_ASN1_OCTET_STRING); + if (!os) { + CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + goto err; + } + } + + if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) + goto err; + + if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) { + CMSerror(CMS_R_UNABLE_TO_FINALIZE_CONTEXT); + goto err; + } + + /* If messageDigest found compare it */ + + if (os) { + if (mlen != (unsigned int)os->length) { + CMSerror(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); + goto err; + } + + if (memcmp(mval, os->data, mlen)) { + CMSerror(CMS_R_VERIFICATION_FAILURE); + r = 0; + } else + r = 1; + } else { + const EVP_MD *md = EVP_MD_CTX_md(mctx); + + pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); + if (pkctx == NULL) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) + goto err; + si->pctx = pkctx; + if (!cms_sd_asn1_ctrl(si, 1)) + goto err; + r = EVP_PKEY_verify(pkctx, si->signature->data, + si->signature->length, mval, mlen); + if (r <= 0) { + CMSerror(CMS_R_VERIFICATION_FAILURE); + r = 0; + } + } + + err: + EVP_PKEY_CTX_free(pkctx); + EVP_MD_CTX_free(mctx); + + return r; +} +LCRYPTO_ALIAS(CMS_SignerInfo_verify_content); + +int +CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) +{ + unsigned char *smder = NULL; + int smderlen, r; + + smderlen = i2d_X509_ALGORS(algs, &smder); + if (smderlen <= 0) + return 0; + r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, smder, smderlen); + free(smder); + + return r; +} +LCRYPTO_ALIAS(CMS_add_smimecap); + +int +CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, int keysize) +{ + X509_ALGOR *alg; + ASN1_INTEGER *key = NULL; + + if (keysize > 0) { + if ((key = ASN1_INTEGER_new()) == NULL) + return 0; + if (!ASN1_INTEGER_set(key, keysize)) { + ASN1_INTEGER_free(key); + return 0; + } + } + alg = X509_ALGOR_new(); + if (alg == NULL) { + ASN1_INTEGER_free(key); + return 0; + } + + X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), + key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); + if (*algs == NULL) + *algs = sk_X509_ALGOR_new_null(); + if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) { + X509_ALGOR_free(alg); + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(CMS_add_simple_smimecap); + +/* Check to see if a cipher exists and if so add S/MIME capabilities */ + +static int +cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +{ + if (EVP_get_cipherbynid(nid)) + return CMS_add_simple_smimecap(sk, nid, arg); + return 1; +} + +static int +cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +{ + if (EVP_get_digestbynid(nid)) + return CMS_add_simple_smimecap(sk, nid, arg); + return 1; +} + +int +CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) +{ + if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) || + !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) || + !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) || + !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) || + !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) || + !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) || + !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) || + !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) || + !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) || + !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) + return 0; + + return 1; +} +LCRYPTO_ALIAS(CMS_add_standard_smimecap); diff --git a/Libraries/libressl/crypto/cms/cms_smime.c b/Libraries/libressl/crypto/cms/cms_smime.c new file mode 100644 index 000000000..b2930017f --- /dev/null +++ b/Libraries/libressl/crypto/cms/cms_smime.c @@ -0,0 +1,901 @@ +/* $OpenBSD: cms_smime.c,v 1.27 2023/07/08 08:26:26 beck Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "cms_local.h" +#include "asn1/asn1_local.h" + +static BIO * +cms_get_text_bio(BIO *out, unsigned int flags) +{ + BIO *rbio; + + if (out == NULL) + rbio = BIO_new(BIO_s_null()); + else if (flags & CMS_TEXT) { + rbio = BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(rbio, 0); + } else + rbio = out; + + return rbio; +} + +static int +cms_copy_content(BIO *out, BIO *in, unsigned int flags) +{ + unsigned char buf[4096]; + int r = 0, i; + BIO *tmpout; + + tmpout = cms_get_text_bio(out, flags); + + if (tmpout == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read all content through chain to process digest, decrypt etc */ + for (;;) { + i = BIO_read(in, buf, sizeof(buf)); + if (i <= 0) { + if (BIO_method_type(in) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(in)) + goto err; + } + if (i < 0) + goto err; + break; + } + + if (tmpout && (BIO_write(tmpout, buf, i) != i)) + goto err; + } + + if (flags & CMS_TEXT) { + if (!SMIME_text(tmpout, out)) { + CMSerror(CMS_R_SMIME_TEXT_ERROR); + goto err; + } + } + + r = 1; + + err: + if (tmpout != out) + BIO_free(tmpout); + + return r; +} + +static int +check_content(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + + if (!pos || !*pos) { + CMSerror(CMS_R_NO_CONTENT); + return 0; + } + + return 1; +} + +static void +do_free_upto(BIO *f, BIO *upto) +{ + if (upto) { + BIO *tbio; + do { + tbio = BIO_pop(f); + BIO_free(f); + f = tbio; + } + while (f && f != upto); + } else + BIO_free_all(f); +} + +int +CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { + CMSerror(CMS_R_TYPE_NOT_DATA); + return 0; + } + cont = CMS_dataInit(cms, NULL); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + BIO_free_all(cont); + + return r; +} +LCRYPTO_ALIAS(CMS_data); + +CMS_ContentInfo * +CMS_data_create(BIO *in, unsigned int flags) +{ + CMS_ContentInfo *cms; + + cms = cms_Data_create(); + if (!cms) + return NULL; + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + + return NULL; +} +LCRYPTO_ALIAS(CMS_data_create); + +int +CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { + CMSerror(CMS_R_TYPE_NOT_DIGESTED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + if (r) + r = cms_DigestedData_do_final(cms, cont, 1); + do_free_upto(cont, dcont); + + return r; +} +LCRYPTO_ALIAS(CMS_digest_verify); + +CMS_ContentInfo * +CMS_digest_create(BIO *in, const EVP_MD *md, unsigned int flags) +{ + CMS_ContentInfo *cms; + + if (!md) + md = EVP_sha1(); + cms = cms_DigestedData_create(md); + if (!cms) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + + return NULL; +} +LCRYPTO_ALIAS(CMS_digest_create); + +int +CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, + size_t keylen, BIO *dcont, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { + CMSerror(CMS_R_TYPE_NOT_ENCRYPTED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) + return 0; + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + + return r; +} +LCRYPTO_ALIAS(CMS_EncryptedData_decrypt); + +CMS_ContentInfo * +CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen, unsigned int flags) +{ + CMS_ContentInfo *cms; + + if (!cipher) { + CMSerror(CMS_R_NO_CIPHER); + return NULL; + } + cms = CMS_ContentInfo_new(); + if (cms == NULL) + return NULL; + if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) || + CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + + return NULL; +} +LCRYPTO_ALIAS(CMS_EncryptedData_encrypt); + +static int +cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, + STACK_OF(X509) *certs, STACK_OF(X509_CRL) *crls) +{ + X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + X509 *signer; + int i, j, r = 0; + + if (ctx == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); + if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { + CMSerror(CMS_R_STORE_INIT_ERROR); + goto err; + } + X509_STORE_CTX_set_default(ctx, "smime_sign"); + if (crls) + X509_STORE_CTX_set0_crls(ctx, crls); + + i = X509_verify_cert(ctx); + if (i <= 0) { + j = X509_STORE_CTX_get_error(ctx); + CMSerror(CMS_R_CERTIFICATE_VERIFY_ERROR); + ERR_asprintf_error_data("Verify error: %s", + X509_verify_cert_error_string(j)); + goto err; + } + r = 1; + + err: + X509_STORE_CTX_free(ctx); + + return r; +} + +int +CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store, + BIO *dcont, BIO *out, unsigned int flags) +{ + CMS_SignerInfo *si; + STACK_OF(CMS_SignerInfo) *sinfos; + STACK_OF(X509) *cms_certs = NULL; + STACK_OF(X509_CRL) *crls = NULL; + X509 *signer; + int i, scount = 0, ret = 0; + BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; + + if (!dcont && !check_content(cms)) + return 0; + if (dcont && !(flags & CMS_BINARY)) { + const ASN1_OBJECT *coid = CMS_get0_eContentType(cms); + if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF) + flags |= CMS_ASCIICRLF; + } + + /* Attempt to find all signer certificates */ + + sinfos = CMS_get0_SignerInfos(cms); + if (sk_CMS_SignerInfo_num(sinfos) <= 0) { + CMSerror(CMS_R_NO_SIGNERS); + goto err; + } + + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); + if (signer) + scount++; + } + + if (scount != sk_CMS_SignerInfo_num(sinfos)) + scount += CMS_set1_signers_certs(cms, certs, flags); + + if (scount != sk_CMS_SignerInfo_num(sinfos)) { + CMSerror(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); + goto err; + } + + /* Attempt to verify all signers certs */ + + if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { + cms_certs = CMS_get1_certs(cms); + if (!(flags & CMS_NOCRL)) + crls = CMS_get1_crls(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls)) + goto err; + } + } + + /* Attempt to verify all SignerInfo signed attribute signatures */ + + if (!(flags & CMS_NO_ATTR_VERIFY)) { + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (CMS_signed_get_attr_count(si) < 0) + continue; + if (CMS_SignerInfo_verify(si) <= 0) + goto err; + } + } + + /* + * Performance optimization: if the content is a memory BIO then store + * its contents in a temporary read only memory BIO. This avoids + * potentially large numbers of slow copies of data which will occur when + * reading from a read write memory BIO when signatures are calculated. + */ + + if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { + char *ptr; + long len; + + len = BIO_get_mem_data(dcont, &ptr); + tmpin = BIO_new_mem_buf(ptr, len); + if (tmpin == NULL) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err2; + } + } else + tmpin = dcont; + + /* + * If not binary mode and detached generate digests by *writing* through + * the BIO. That makes it possible to canonicalise the input. + */ + if (!(flags & SMIME_BINARY) && dcont) { + /* + * Create output BIO so we can either handle text or to ensure + * included content doesn't override detached content. + */ + tmpout = cms_get_text_bio(out, flags); + if (!tmpout) { + CMSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + cmsbio = CMS_dataInit(cms, tmpout); + if (!cmsbio) + goto err; + /* + * Don't use SMIME_TEXT for verify: it adds headers and we want to + * remove them. + */ + SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT); + + if (flags & CMS_TEXT) { + if (!SMIME_text(tmpout, out)) { + CMSerror(CMS_R_SMIME_TEXT_ERROR); + goto err; + } + } + } else { + cmsbio = CMS_dataInit(cms, tmpin); + if (!cmsbio) + goto err; + + if (!cms_copy_content(out, cmsbio, flags)) + goto err; + + } + if (!(flags & CMS_NO_CONTENT_VERIFY)) { + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { + CMSerror(CMS_R_CONTENT_VERIFY_ERROR); + goto err; + } + } + } + + ret = 1; + + err: + if (!(flags & SMIME_BINARY) && dcont) { + do_free_upto(cmsbio, tmpout); + if (tmpin != dcont) + BIO_free(tmpin); + } else { + if (dcont && (tmpin == dcont)) + do_free_upto(cmsbio, dcont); + else + BIO_free_all(cmsbio); + } + + if (out != tmpout) + BIO_free_all(tmpout); + + err2: + sk_X509_pop_free(cms_certs, X509_free); + sk_X509_CRL_pop_free(crls, X509_CRL_free); + + return ret; +} +LCRYPTO_ALIAS(CMS_verify); + +int +CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags) +{ + int r; + + flags &= ~(CMS_DETACHED | CMS_TEXT); + r = CMS_verify(rcms, certs, store, NULL, NULL, flags); + if (r <= 0) + return r; + + return cms_Receipt_verify(rcms, ocms); +} +LCRYPTO_ALIAS(CMS_verify_receipt); + +CMS_ContentInfo * +CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, + unsigned int flags) +{ + CMS_ContentInfo *cms; + int i; + + cms = CMS_ContentInfo_new(); + if (cms == NULL || !CMS_SignedData_init(cms)) + goto merr; + if (flags & CMS_ASCIICRLF && + !CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) + goto err; + + if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { + CMSerror(CMS_R_ADD_SIGNER_ERROR); + goto err; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *x = sk_X509_value(certs, i); + if (!CMS_add1_cert(cms, x)) + goto merr; + } + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) || + CMS_final(cms, data, NULL, flags)) + return cms; + else + goto err; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + + err: + CMS_ContentInfo_free(cms); + + return NULL; +} +LCRYPTO_ALIAS(CMS_sign); + +CMS_ContentInfo * +CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags) +{ + CMS_SignerInfo *rct_si; + CMS_ContentInfo *cms = NULL; + ASN1_OCTET_STRING **pos, *os; + BIO *rct_cont = NULL; + int r = 0; + + flags &= ~(CMS_STREAM | CMS_TEXT); + /* Not really detached but avoids content being allocated */ + flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; + if (!pkey || !signcert) { + CMSerror(CMS_R_NO_KEY_OR_CERT); + return NULL; + } + + /* Initialize signed data */ + + cms = CMS_sign(NULL, NULL, certs, NULL, flags); + if (!cms) + goto err; + + /* Set inner content type to signed receipt */ + if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) + goto err; + + rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); + if (!rct_si) { + CMSerror(CMS_R_ADD_SIGNER_ERROR); + goto err; + } + + os = cms_encode_Receipt(si); + if (!os) + goto err; + + /* Set content to digest */ + rct_cont = BIO_new_mem_buf(os->data, os->length); + if (!rct_cont) + goto err; + + /* Add msgSigDigest attribute */ + + if (!cms_msgSigDigest_add1(rct_si, si)) + goto err; + + /* Finalize structure */ + if (!CMS_final(cms, rct_cont, NULL, flags)) + goto err; + + /* Set embedded content */ + pos = CMS_get0_content(cms); + *pos = os; + + r = 1; + + err: + BIO_free(rct_cont); + if (r) + return cms; + CMS_ContentInfo_free(cms); + + return NULL; +} +LCRYPTO_ALIAS(CMS_sign_receipt); + +CMS_ContentInfo * +CMS_encrypt(STACK_OF(X509) *certs, BIO *data, const EVP_CIPHER *cipher, + unsigned int flags) +{ + CMS_ContentInfo *cms; + int i; + X509 *recip; + + cms = CMS_EnvelopedData_create(cipher); + if (!cms) + goto merr; + for (i = 0; i < sk_X509_num(certs); i++) { + recip = sk_X509_value(certs, i); + if (!CMS_add1_recipient_cert(cms, recip, flags)) { + CMSerror(CMS_R_RECIPIENT_ERROR); + goto err; + } + } + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) || + CMS_final(cms, data, NULL, flags)) + return cms; + else + goto err; + + merr: + CMSerror(ERR_R_MALLOC_FAILURE); + err: + CMS_ContentInfo_free(cms); + + return NULL; +} +LCRYPTO_ALIAS(CMS_encrypt); + +static int +cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, EVP_PKEY *pk, + X509 *cert) +{ + int i; + STACK_OF(CMS_RecipientEncryptedKey) *reks; + CMS_RecipientEncryptedKey *rek; + + reks = CMS_RecipientInfo_kari_get0_reks(ri); + for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { + int rv; + + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); + if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) + continue; + CMS_RecipientInfo_kari_set0_pkey(ri, pk); + rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); + CMS_RecipientInfo_kari_set0_pkey(ri, NULL); + if (rv > 0) + return 1; + return cert == NULL ? 0 : -1; + } + + return 0; +} + +int +CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r, ri_type; + int debug = 0, match_ri = 0; + + ris = CMS_get0_RecipientInfos(cms); + if (ris) + debug = cms->d.envelopedData->encryptedContentInfo->debug; + ri_type = cms_pkey_get_ri_type(pk); + if (ri_type == CMS_RECIPINFO_NONE) { + CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != ri_type) + continue; + match_ri = 1; + if (ri_type == CMS_RECIPINFO_AGREE) { + r = cms_kari_set1_pkey(cms, ri, pk, cert); + if (r > 0) + return 1; + if (r < 0) + return 0; + } + /* + * If we have a cert try matching RecipientInfo otherwise try them + * all. + */ + else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { + EVP_PKEY_up_ref(pk); + CMS_RecipientInfo_set0_pkey(ri, pk); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_pkey(ri, NULL); + if (cert) { + /* + * If not debugging clear any error and return success to + * avoid leaking of information useful to MMA + */ + if (!debug) { + ERR_clear_error(); + return 1; + } + if (r > 0) + return 1; + CMSerror(CMS_R_DECRYPT_ERROR); + return 0; + } + /* + * If no cert and not debugging don't leave loop after first + * successful decrypt. Always attempt to decrypt all recipients + * to avoid leaking timing of a successful decrypt. + */ + else if (r > 0 && debug) + return 1; + } + } + /* If no cert, key transport and not debugging always return success */ + if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { + ERR_clear_error(); + return 1; + } + + CMSerror(CMS_R_NO_MATCHING_RECIPIENT); + + return 0; +} +LCRYPTO_ALIAS(CMS_decrypt_set1_pkey); + +int +CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, size_t keylen, + const unsigned char *id, size_t idlen) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) + continue; + + /* + * If we have an id try matching RecipientInfo otherwise try them + * all. + */ + if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { + CMS_RecipientInfo_set0_key(ri, key, keylen); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_key(ri, NULL, 0); + if (r > 0) + return 1; + if (id) { + CMSerror(CMS_R_DECRYPT_ERROR); + return 0; + } + ERR_clear_error(); + } + } + + CMSerror(CMS_R_NO_MATCHING_RECIPIENT); + + return 0; +} +LCRYPTO_ALIAS(CMS_decrypt_set1_key); + +int +CMS_decrypt_set1_password(CMS_ContentInfo *cms, unsigned char *pass, + ssize_t passlen) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) + continue; + CMS_RecipientInfo_set0_password(ri, pass, passlen); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_password(ri, NULL, 0); + if (r > 0) + return 1; + } + + CMSerror(CMS_R_NO_MATCHING_RECIPIENT); + + return 0; +} +LCRYPTO_ALIAS(CMS_decrypt_set1_password); + +int +CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, BIO *dcont, + BIO *out, unsigned int flags) +{ + int r; + BIO *cont; + + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { + CMSerror(CMS_R_TYPE_NOT_ENVELOPED_DATA); + return 0; + } + if (!dcont && !check_content(cms)) + return 0; + if (flags & CMS_DEBUG_DECRYPT) + cms->d.envelopedData->encryptedContentInfo->debug = 1; + else + cms->d.envelopedData->encryptedContentInfo->debug = 0; + if (!cert) + cms->d.envelopedData->encryptedContentInfo->havenocert = 1; + else + cms->d.envelopedData->encryptedContentInfo->havenocert = 0; + if (!pk && !cert && !dcont && !out) + return 1; + if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) + return 0; + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + + return r; +} +LCRYPTO_ALIAS(CMS_decrypt); + +int +CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) +{ + BIO *cmsbio; + int ret = 0; + + if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) { + CMSerror(CMS_R_CMS_LIB); + return 0; + } + + SMIME_crlf_copy(data, cmsbio, flags); + + (void)BIO_flush(cmsbio); + + if (!CMS_dataFinal(cms, cmsbio)) { + CMSerror(CMS_R_CMS_DATAFINAL_ERROR); + goto err; + } + + ret = 1; + + err: + do_free_upto(cmsbio, dcont); + + return ret; +} +LCRYPTO_ALIAS(CMS_final); + +int +CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) +{ + CMSerror(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return 0; +} +LCRYPTO_ALIAS(CMS_uncompress); + +CMS_ContentInfo * +CMS_compress(BIO *in, int comp_nid, unsigned int flags) +{ + CMSerror(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; +} +LCRYPTO_ALIAS(CMS_compress); diff --git a/Libraries/libressl/crypto/compat/arc4random.c b/Libraries/libressl/crypto/compat/arc4random.c new file mode 100644 index 000000000..1ec8e1eed --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random.c @@ -0,0 +1,202 @@ +/* $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ChaCha based random number generator for OpenBSD. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KEYSTREAM_ONLY +#include "chacha_private.h" + +#define minimum(a, b) ((a) < (b) ? (a) : (b)) + +#if defined(__GNUC__) || defined(_MSC_VER) +#define inline __inline +#else /* __GNUC__ || _MSC_VER */ +#define inline +#endif /* !__GNUC__ && !_MSC_VER */ + +#define KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) + +#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */ + +/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ +static struct _rs { + size_t rs_have; /* valid bytes at end of rs_buf */ + size_t rs_count; /* bytes till reseed */ +} *rs; + +/* Maybe be preserved in fork children, if _rs_allocate() decides. */ +static struct _rsx { + chacha_ctx rs_chacha; /* chacha context for random keystream */ + u_char rs_buf[RSBUFSZ]; /* keystream blocks */ +} *rsx; + +static inline int _rs_allocate(struct _rs **, struct _rsx **); +static inline void _rs_forkdetect(void); +#include "arc4random.h" + +static inline void _rs_rekey(u_char *dat, size_t datlen); + +static inline void +_rs_init(u_char *buf, size_t n) +{ + if (n < KEYSZ + IVSZ) + return; + + if (rs == NULL) { + if (_rs_allocate(&rs, &rsx) == -1) + _exit(1); + } + + chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8); + chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ); +} + +static void +_rs_stir(void) +{ + u_char rnd[KEYSZ + IVSZ]; + uint32_t rekey_fuzz = 0; + + if (getentropy(rnd, sizeof rnd) == -1) + _getentropy_fail(); + + if (!rs) + _rs_init(rnd, sizeof(rnd)); + else + _rs_rekey(rnd, sizeof(rnd)); + explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */ + + /* invalidate rs_buf */ + rs->rs_have = 0; + memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); + + /* rekey interval should not be predictable */ + chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz, + (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz)); + rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE); +} + +static inline void +_rs_stir_if_needed(size_t len) +{ + _rs_forkdetect(); + if (!rs || rs->rs_count <= len) + _rs_stir(); + if (rs->rs_count <= len) + rs->rs_count = 0; + else + rs->rs_count -= len; +} + +static inline void +_rs_rekey(u_char *dat, size_t datlen) +{ +#ifndef KEYSTREAM_ONLY + memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); +#endif + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf, + rsx->rs_buf, sizeof(rsx->rs_buf)); + /* mix in optional user provided data */ + if (dat) { + size_t i, m; + + m = minimum(datlen, KEYSZ + IVSZ); + for (i = 0; i < m; i++) + rsx->rs_buf[i] ^= dat[i]; + } + /* immediately reinit for backtracking resistance */ + _rs_init(rsx->rs_buf, KEYSZ + IVSZ); + memset(rsx->rs_buf, 0, KEYSZ + IVSZ); + rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ; +} + +static inline void +_rs_random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + u_char *keystream; + size_t m; + + _rs_stir_if_needed(n); + while (n > 0) { + if (rs->rs_have > 0) { + m = minimum(n, rs->rs_have); + keystream = rsx->rs_buf + sizeof(rsx->rs_buf) + - rs->rs_have; + memcpy(buf, keystream, m); + memset(keystream, 0, m); + buf += m; + n -= m; + rs->rs_have -= m; + } + if (rs->rs_have == 0) + _rs_rekey(NULL, 0); + } +} + +static inline void +_rs_random_u32(uint32_t *val) +{ + u_char *keystream; + + _rs_stir_if_needed(sizeof(*val)); + if (rs->rs_have < sizeof(*val)) + _rs_rekey(NULL, 0); + keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have; + memcpy(val, keystream, sizeof(*val)); + memset(keystream, 0, sizeof(*val)); + rs->rs_have -= sizeof(*val); +} + +uint32_t +arc4random(void) +{ + uint32_t val; + + _ARC4_LOCK(); + _rs_random_u32(&val); + _ARC4_UNLOCK(); + return val; +} + +void +arc4random_buf(void *buf, size_t n) +{ + _ARC4_LOCK(); + _rs_random_buf(buf, n); + _ARC4_UNLOCK(); +} diff --git a/Libraries/libressl/crypto/compat/arc4random.h b/Libraries/libressl/crypto/compat/arc4random.h new file mode 100644 index 000000000..ffa32398d --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random.h @@ -0,0 +1,38 @@ +#ifndef LIBCRYPTOCOMPAT_ARC4RANDOM_H +#define LIBCRYPTOCOMPAT_ARC4RANDOM_H + +#include + +#if defined(_AIX) +#include "arc4random_aix.h" + +#elif defined(__FreeBSD__) +#include "arc4random_freebsd.h" + +#elif defined(__hpux) +#include "arc4random_hpux.h" + +#elif defined(__linux__) +#include "arc4random_linux.h" + +#elif defined(__midipix__) +#include "arc4random_linux.h" + +#elif defined(__NetBSD__) +#include "arc4random_netbsd.h" + +#elif defined(__APPLE__) +#include "arc4random_osx.h" + +#elif defined(__sun) +#include "arc4random_solaris.h" + +#elif defined(_WIN32) +#include "arc4random_win.h" + +#else +#error "No arc4random hooks defined for this platform." + +#endif + +#endif diff --git a/Libraries/libressl/crypto/compat/arc4random_aix.h b/Libraries/libressl/crypto/compat/arc4random_aix.h new file mode 100644 index 000000000..3142a1f27 --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_aix.h @@ -0,0 +1,81 @@ +/* $OpenBSD: arc4random_aix.h,v 1.2 2016/06/30 12:19:51 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_freebsd.h b/Libraries/libressl/crypto/compat/arc4random_freebsd.h new file mode 100644 index 000000000..3faa5e4d3 --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_freebsd.h @@ -0,0 +1,87 @@ +/* $OpenBSD: arc4random_freebsd.h,v 1.4 2016/06/30 12:19:51 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +/* + * Unfortunately, pthread_atfork() is broken on FreeBSD (at least 9 and 10) if + * a program does not link to -lthr. Callbacks registered with pthread_atfork() + * appear to fail silently. So, it is not always possible to detect a PID + * wraparound. + */ +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_hpux.h b/Libraries/libressl/crypto/compat/arc4random_hpux.h new file mode 100644 index 000000000..2a3fe8c61 --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_hpux.h @@ -0,0 +1,81 @@ +/* $OpenBSD: arc4random_hpux.h,v 1.3 2016/06/30 12:19:51 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_linux.h b/Libraries/libressl/crypto/compat/arc4random_linux.h new file mode 100644 index 000000000..5e1cf34e6 --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_linux.h @@ -0,0 +1,88 @@ +/* $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +#if defined(__GLIBC__) && !(defined(__UCLIBC__) && !defined(__ARCH_USE_MMU__)) +extern void *__dso_handle; +extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *); +#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle) +#else +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) +#endif + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + /* XXX unusual calls to clone() can bypass checks */ + if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_netbsd.h b/Libraries/libressl/crypto/compat/arc4random_netbsd.h new file mode 100644 index 000000000..611997d54 --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_netbsd.h @@ -0,0 +1,87 @@ +/* $OpenBSD: arc4random_netbsd.h,v 1.3 2016/06/30 12:19:51 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +/* + * Unfortunately, pthread_atfork() is broken on FreeBSD (at least 9 and 10) if + * a program does not link to -lthr. Callbacks registered with pthread_atfork() + * appear to fail silently. So, it is not always possible to detect a PID + * wraparound. + */ +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_osx.h b/Libraries/libressl/crypto/compat/arc4random_osx.h new file mode 100644 index 000000000..818ae6bbf --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_osx.h @@ -0,0 +1,81 @@ +/* $OpenBSD: arc4random_osx.h,v 1.11 2016/06/30 12:19:51 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_solaris.h b/Libraries/libressl/crypto/compat/arc4random_solaris.h new file mode 100644 index 000000000..b1084cda0 --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_solaris.h @@ -0,0 +1,81 @@ +/* $OpenBSD: arc4random_solaris.h,v 1.10 2016/06/30 12:19:51 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +#include +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/Libraries/libressl/crypto/compat/arc4random_uniform.c b/Libraries/libressl/crypto/compat/arc4random_uniform.c new file mode 100644 index 000000000..06cd29c6d --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_uniform.c @@ -0,0 +1,56 @@ +/* $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $ */ + +/* + * Copyright (c) 2008, Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return r % upper_bound; +} diff --git a/Libraries/libressl/crypto/compat/arc4random_win.h b/Libraries/libressl/crypto/compat/arc4random_win.h new file mode 100644 index 000000000..deec8a1ef --- /dev/null +++ b/Libraries/libressl/crypto/compat/arc4random_win.h @@ -0,0 +1,78 @@ +/* $OpenBSD: arc4random_win.h,v 1.6 2016/06/30 12:17:29 bcook Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include + +static volatile HANDLE arc4random_mtx = NULL; + +/* + * Initialize the mutex on the first lock attempt. On collision, each thread + * will attempt to allocate a mutex and compare-and-swap it into place as the + * global mutex. On failure to swap in the global mutex, the mutex is closed. + */ +#define _ARC4_LOCK() { \ + if (!arc4random_mtx) { \ + HANDLE p = CreateMutex(NULL, FALSE, NULL); \ + if (InterlockedCompareExchangePointer((void **)&arc4random_mtx, (void *)p, NULL)) \ + CloseHandle(p); \ + } \ + WaitForSingleObject(arc4random_mtx, INFINITE); \ +} \ + +#define _ARC4_UNLOCK() ReleaseMutex(arc4random_mtx) + +static inline void +_getentropy_fail(void) +{ + TerminateProcess(GetCurrentProcess(), 0); +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + *rsp = VirtualAlloc(NULL, sizeof(**rsp), + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (*rsp == NULL) + return (-1); + + *rsxp = VirtualAlloc(NULL, sizeof(**rsxp), + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (*rsxp == NULL) { + VirtualFree(*rsp, 0, MEM_RELEASE); + *rsp = NULL; + return (-1); + } + return (0); +} + +static inline void +_rs_forkhandler(void) +{ +} + +static inline void +_rs_forkdetect(void) +{ +} diff --git a/Libraries/libressl/crypto/compat/bsd-asprintf.c b/Libraries/libressl/crypto/compat/bsd-asprintf.c new file mode 100644 index 000000000..3728bc53d --- /dev/null +++ b/Libraries/libressl/crypto/compat/bsd-asprintf.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004 Darren Tucker. + * + * Based originally on asprintf.c from OpenBSD: + * Copyright (c) 1997 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HAVE_ASPRINTF + +#include +#include /* for INT_MAX */ +#include +#include /* for vsnprintf */ +#include + +#ifndef VA_COPY +# ifdef HAVE_VA_COPY +# define VA_COPY(dest, src) va_copy(dest, src) +# else +# ifdef HAVE___VA_COPY +# define VA_COPY(dest, src) __va_copy(dest, src) +# else +# define VA_COPY(dest, src) (dest) = (src) +# endif +# endif +#endif + +#define INIT_SZ 128 + +int +vasprintf(char **str, const char *fmt, va_list ap) +{ + int ret; + va_list ap2; + char *string, *newstr; + size_t len; + + if ((string = malloc(INIT_SZ)) == NULL) + goto fail; + + VA_COPY(ap2, ap); + ret = vsnprintf(string, INIT_SZ, fmt, ap2); + va_end(ap2); + if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ + *str = string; + } else if (ret == INT_MAX || ret < 0) { /* Bad length */ + free(string); + goto fail; + } else { /* bigger than initial, realloc allowing for nul */ + len = (size_t)ret + 1; + if ((newstr = realloc(string, len)) == NULL) { + free(string); + goto fail; + } + VA_COPY(ap2, ap); + ret = vsnprintf(newstr, len, fmt, ap2); + va_end(ap2); + if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */ + free(newstr); + goto fail; + } + *str = newstr; + } + return (ret); + +fail: + *str = NULL; + errno = ENOMEM; + return (-1); +} + +int asprintf(char **str, const char *fmt, ...) +{ + va_list ap; + int ret; + + *str = NULL; + va_start(ap, fmt); + ret = vasprintf(str, fmt, ap); + va_end(ap); + + return ret; +} +#endif diff --git a/Libraries/libressl/crypto/compat/chacha_private.h b/Libraries/libressl/crypto/compat/chacha_private.h new file mode 100644 index 000000000..b0427b6b3 --- /dev/null +++ b/Libraries/libressl/crypto/compat/chacha_private.h @@ -0,0 +1,222 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */ + +typedef unsigned char u8; +typedef unsigned int u32; + +typedef struct +{ + u32 input[16]; /* could be compressed */ +} chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +static void +chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +static void +chacha_ivsetup(chacha_ctx *x,const u8 *iv) +{ + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +static void +chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = NULL; + u8 tmp[64]; + u_int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + +#ifndef KEYSTREAM_ONLY + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); +#endif + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; +#ifndef KEYSTREAM_ONLY + m += 64; +#endif + } +} diff --git a/Libraries/libressl/crypto/compat/crypto_lock_win.c b/Libraries/libressl/crypto/compat/crypto_lock_win.c new file mode 100644 index 000000000..b3b1858fd --- /dev/null +++ b/Libraries/libressl/crypto/compat/crypto_lock_win.c @@ -0,0 +1,56 @@ +/* $OpenBSD: crypto_lock.c,v 1.1 2018/11/11 06:41:28 bcook Exp $ */ +/* + * Copyright (c) 2019 Brent Cook + * Copyright (c) 2019 John Norrbin + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +static volatile LPCRITICAL_SECTION locks[CRYPTO_NUM_LOCKS] = { NULL }; + +void +CRYPTO_lock(int mode, int type, const char *file, int line) +{ + if (type < 0 || type >= CRYPTO_NUM_LOCKS) + return; + + if (locks[type] == NULL) { + LPCRITICAL_SECTION lcs = malloc(sizeof(CRITICAL_SECTION)); + if (lcs == NULL) exit(ENOMEM); + InitializeCriticalSection(lcs); + if (InterlockedCompareExchangePointer((PVOID*)&locks[type], (PVOID)lcs, NULL) != NULL) { + DeleteCriticalSection(lcs); + free(lcs); + } + } + + if (mode & CRYPTO_LOCK) + EnterCriticalSection(locks[type]); + else + LeaveCriticalSection(locks[type]); +} + +int +CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line) +{ + /* + * Windows is LLP64. sizeof(LONG) == sizeof(int) on 32-bit and 64-bit. + */ + int ret = InterlockedExchangeAdd((LONG *)pointer, (LONG)amount); + return ret + amount; +} diff --git a/Libraries/libressl/crypto/compat/explicit_bzero.c b/Libraries/libressl/crypto/compat/explicit_bzero.c new file mode 100644 index 000000000..5dd0103cd --- /dev/null +++ b/Libraries/libressl/crypto/compat/explicit_bzero.c @@ -0,0 +1,19 @@ +/* $OpenBSD: explicit_bzero.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */ +/* + * Public domain. + * Written by Matthew Dempsky. + */ + +#include + +__attribute__((weak)) void +__explicit_bzero_hook(void *buf, size_t len) +{ +} + +void +explicit_bzero(void *buf, size_t len) +{ + memset(buf, 0, len); + __explicit_bzero_hook(buf, len); +} diff --git a/Libraries/libressl/crypto/compat/explicit_bzero_win.c b/Libraries/libressl/crypto/compat/explicit_bzero_win.c new file mode 100644 index 000000000..0d09d906a --- /dev/null +++ b/Libraries/libressl/crypto/compat/explicit_bzero_win.c @@ -0,0 +1,13 @@ +/* + * Public domain. + * Win32 explicit_bzero compatibility shim. + */ + +#include +#include + +void +explicit_bzero(void *buf, size_t len) +{ + SecureZeroMemory(buf, len); +} diff --git a/Libraries/libressl/crypto/compat/freezero.c b/Libraries/libressl/crypto/compat/freezero.c new file mode 100644 index 000000000..31face382 --- /dev/null +++ b/Libraries/libressl/crypto/compat/freezero.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek + * Copyright (c) 2012 Matthew Dempsky + * Copyright (c) 2008 Damien Miller + * Copyright (c) 2000 Poul-Henning Kamp + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +void +freezero(void *ptr, size_t sz) +{ + /* This is legal. */ + if (ptr == NULL) + return; + + explicit_bzero(ptr, sz); + free(ptr); +} diff --git a/Libraries/libressl/crypto/compat/getentropy_aix.c b/Libraries/libressl/crypto/compat/getentropy_aix.c new file mode 100644 index 000000000..9d085cf50 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_aix.c @@ -0,0 +1,402 @@ +/* $OpenBSD: getentropy_aix.c,v 1.9 2022/12/26 07:18:50 jmc Exp $ */ + +/* + * Copyright (c) 2015 Michael Felt + * Copyright (c) 2014 Theo de Raadt + * Copyright (c) 2014 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ +/* + * -lperfstat is needed for the pseudo entropy data + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define REPEAT 5 +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +#define HX(a, b) \ + do { \ + if ((a)) \ + HD(errno); \ + else \ + HD(b); \ + } while (0) + +#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) +#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) +#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) + +int getentropy(void *buf, size_t len); + +static int getentropy_urandom(void *buf, size_t len, const char *path, + int devfscheck); +static int getentropy_fallback(void *buf, size_t len); + +int +getentropy(void *buf, size_t len) +{ + int ret = -1; + + if (len > 256) { + errno = EIO; + return (-1); + } + + /* + * Try to get entropy with /dev/urandom + */ + ret = getentropy_urandom(buf, len, "/dev/urandom", 0); + if (ret != -1) + return (ret); + + /* + * Entropy collection via /dev/urandom has failed. + * + * No other API exists for collecting entropy, and we have + * no failsafe way to get it on AIX that is not sensitive + * to resource exhaustion. + * + * We have very few options: + * - Even syslog_r is unsafe to call at this low level, so + * there is no way to alert the user or program. + * - Cannot call abort() because some systems have unsafe + * corefiles. + * - Could raise(SIGKILL) resulting in silent program termination. + * - Return EIO, to hint that arc4random's stir function + * should raise(SIGKILL) + * - Do the best under the circumstances.... + * + * This code path exists to bring light to the issue that AIX + * does not provide a failsafe API for entropy collection. + * + * We hope this demonstrates that AIX should consider + * providing a new failsafe API which works in a chroot or + * when file descriptors are exhausted. + */ +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} + +static int +getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck) +{ + struct stat st; + size_t i; + int fd, flags; + int save_errno = errno; + +start: + + flags = O_RDONLY; +#ifdef O_NOFOLLOW + flags |= O_NOFOLLOW; +#endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + fd = open(path, flags); + if (fd == -1) { + if (errno == EINTR) + goto start; + goto nodevrandom; + } +#ifndef O_CLOEXEC + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif + + /* Lightly verify that the device node looks sane */ + if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { + close(fd); + goto nodevrandom; + } + for (i = 0; i < len; ) { + size_t wanted = len - i; + ssize_t ret = read(fd, (char *)buf + i, wanted); + + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + goto nodevrandom; + } + i += ret; + } + close(fd); + errno = save_errno; + return (0); /* satisfied */ +nodevrandom: + errno = EIO; + return (-1); +} + +static const int cl[] = { + CLOCK_REALTIME, +#ifdef CLOCK_MONOTONIC + CLOCK_MONOTONIC, +#endif +#ifdef CLOCK_MONOTONIC_RAW + CLOCK_MONOTONIC_RAW, +#endif +#ifdef CLOCK_TAI + CLOCK_TAI, +#endif +#ifdef CLOCK_VIRTUAL + CLOCK_VIRTUAL, +#endif +#ifdef CLOCK_UPTIME + CLOCK_UPTIME, +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + CLOCK_PROCESS_CPUTIME_ID, +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + CLOCK_THREAD_CPUTIME_ID, +#endif +}; + +static int +getentropy_fallback(void *buf, size_t len) +{ + uint8_t results[SHA512_DIGEST_LENGTH]; + int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat; + static int cnt; + struct timespec ts; + struct timeval tv; + perfstat_cpu_total_t cpustats; +#ifdef _AIX61 + perfstat_cpu_total_wpar_t cpustats_wpar; +#endif + perfstat_partition_total_t lparstats; + perfstat_disk_total_t diskinfo; + perfstat_netinterface_total_t netinfo; + struct rusage ru; + sigset_t sigset; + struct stat st; + SHA512_CTX ctx; + static pid_t lastpid; + pid_t pid; + size_t i, ii, m; + char *p; + + pid = getpid(); + if (lastpid == pid) { + faster = 1; + repeat = 2; + } else { + faster = 0; + lastpid = pid; + repeat = REPEAT; + } + for (i = 0; i < len; ) { + int j; + SHA512_Init(&ctx); + for (j = 0; j < repeat; j++) { + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HX(perfstat_cpu_total(NULL, &cpustats, + sizeof(cpustats), 1) == -1, cpustats); + +#ifdef _AIX61 + HX(perfstat_cpu_total_wpar(NULL, &cpustats_wpar, + sizeof(cpustats_wpar), 1) == -1, cpustats_wpar); +#endif + + HX(perfstat_partition_total(NULL, &lparstats, + sizeof(lparstats), 1) == -1, lparstats); + + HX(perfstat_disk_total(NULL, &diskinfo, + sizeof(diskinfo), 1) == -1, diskinfo); + + HX(perfstat_netinterface_total(NULL, &netinfo, + sizeof(netinfo), 1) == -1, netinfo); + + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) + HX(clock_gettime(cl[ii], &ts) == -1, ts); + + HX((pid = getpid()) == -1, pid); + HX((pid = getsid(pid)) == -1, pid); + HX((pid = getppid()) == -1, pid); + HX((pid = getpgid(0)) == -1, pid); + HX((e = getpriority(0, 0)) == -1, e); + + if (!faster) { + ts.tv_sec = 0; + ts.tv_nsec = 1; + (void) nanosleep(&ts, NULL); + } + + HX(sigpending(&sigset) == -1, sigset); + HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, + sigset); + + HF(getentropy); /* an addr in this library */ + HF(printf); /* an addr in libc */ + p = (char *)&p; + HD(p); /* an addr on stack */ + p = (char *)&errno; + HD(p); /* the addr of errno */ + + if (i == 0) { + struct sockaddr_storage ss; + struct statvfs stvfs; + struct termios tios; + socklen_t ssl; + off_t off; + + /* + * Prime-sized mappings encourage fragmentation; + * thus exposing some address entropy. + */ + struct mm { + size_t npg; + void *p; + } mm[] = { + { 17, MAP_FAILED }, { 3, MAP_FAILED }, + { 11, MAP_FAILED }, { 2, MAP_FAILED }, + { 5, MAP_FAILED }, { 3, MAP_FAILED }, + { 7, MAP_FAILED }, { 1, MAP_FAILED }, + { 57, MAP_FAILED }, { 3, MAP_FAILED }, + { 131, MAP_FAILED }, { 1, MAP_FAILED }, + }; + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + HX(mm[m].p = mmap(NULL, + mm[m].npg * pgs, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, + (off_t)0), mm[m].p); + if (mm[m].p != MAP_FAILED) { + size_t mo; + + /* Touch some memory... */ + p = mm[m].p; + mo = cnt % + (mm[m].npg * pgs - 1); + p[mo] = 1; + cnt += (int)((long)(mm[m].p) + / pgs); + } + + /* Check cnts and times... */ + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); + ii++) { + HX((e = clock_gettime(cl[ii], + &ts)) == -1, ts); + if (e != -1) + cnt += (int)ts.tv_nsec; + } + + HX((e = getrusage(RUSAGE_SELF, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + if (mm[m].p != MAP_FAILED) + munmap(mm[m].p, mm[m].npg * pgs); + mm[m].p = MAP_FAILED; + } + + HX(stat(".", &st) == -1, st); + HX(statvfs(".", &stvfs) == -1, stvfs); + + HX(stat("/", &st) == -1, st); + HX(statvfs("/", &stvfs) == -1, stvfs); + + HX((e = fstat(0, &st)) == -1, st); + if (e == -1) { + if (S_ISREG(st.st_mode) || + S_ISFIFO(st.st_mode) || + S_ISSOCK(st.st_mode)) { + HX(fstatvfs(0, &stvfs) == -1, + stvfs); + HX((off = lseek(0, (off_t)0, + SEEK_CUR)) < 0, off); + } + if (S_ISCHR(st.st_mode)) { + HX(tcgetattr(0, &tios) == -1, + tios); + } else if (S_ISSOCK(st.st_mode)) { + memset(&ss, 0, sizeof ss); + ssl = sizeof(ss); + HX(getpeername(0, + (void *)&ss, &ssl) == -1, + ss); + } + } + + HX((e = getrusage(RUSAGE_CHILDREN, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } else { + /* Subsequent hashes absorb previous result */ + HD(results); + } + + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HD(cnt); + } + SHA512_Final(results, &ctx); + memcpy((char *)buf + i, results, MINIMUM(sizeof(results), len - i)); + i += MINIMUM(sizeof(results), len - i); + } + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ +} diff --git a/Libraries/libressl/crypto/compat/getentropy_freebsd.c b/Libraries/libressl/crypto/compat/getentropy_freebsd.c new file mode 100644 index 000000000..ea90ffe20 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_freebsd.c @@ -0,0 +1,60 @@ +/* $OpenBSD: getentropy_freebsd.c,v 1.4 2020/10/12 22:08:33 deraadt Exp $ */ + +/* + * Copyright (c) 2014 Pawel Jakub Dawidek + * Copyright (c) 2014 Brent Cook + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include + +#include +#include + +/* + * Derived from lib/libc/gen/arc4random.c from FreeBSD. + */ +static size_t +getentropy_sysctl(u_char *buf, size_t size) +{ + const int mib[2] = { CTL_KERN, KERN_ARND }; + size_t len, done; + + done = 0; + + do { + len = size; + if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) + return (done); + done += len; + buf += len; + size -= len; + } while (size > 0); + + return (done); +} + +int +getentropy(void *buf, size_t len) +{ + if (len <= 256 && getentropy_sysctl(buf, len) == len) + return (0); + + errno = EIO; + return (-1); +} diff --git a/Libraries/libressl/crypto/compat/getentropy_hpux.c b/Libraries/libressl/crypto/compat/getentropy_hpux.c new file mode 100644 index 000000000..7188ae5e1 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_hpux.c @@ -0,0 +1,396 @@ +/* $OpenBSD: getentropy_hpux.c,v 1.8 2021/10/24 21:24:20 deraadt Exp $ */ + +/* + * Copyright (c) 2014 Theo de Raadt + * Copyright (c) 2014 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define REPEAT 5 +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +#define HX(a, b) \ + do { \ + if ((a)) \ + HD(errno); \ + else \ + HD(b); \ + } while (0) + +#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) +#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) +#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) + +int getentropy(void *buf, size_t len); + +static int getentropy_urandom(void *buf, size_t len, const char *path, + int devfscheck); +static int getentropy_fallback(void *buf, size_t len); + +int +getentropy(void *buf, size_t len) +{ + int ret = -1; + + if (len > 256) { + errno = EIO; + return (-1); + } + + /* + * Try to get entropy with /dev/urandom + */ + ret = getentropy_urandom(buf, len, "/dev/urandom", 0); + if (ret != -1) + return (ret); + + /* + * Entropy collection via /dev/urandom has failed. + * + * No other API exists for collecting entropy, and we have + * no failsafe way to get it on hpux that is not sensitive + * to resource exhaustion. + * + * We have very few options: + * - Even syslog_r is unsafe to call at this low level, so + * there is no way to alert the user or program. + * - Cannot call abort() because some systems have unsafe + * corefiles. + * - Could raise(SIGKILL) resulting in silent program termination. + * - Return EIO, to hint that arc4random's stir function + * should raise(SIGKILL) + * - Do the best under the circumstances.... + * + * This code path exists to bring light to the issue that hpux + * does not provide a failsafe API for entropy collection. + * + * We hope this demonstrates that hpux should consider + * providing a new failsafe API which works in a chroot or + * when file descriptors are exhausted. + */ +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} + +static int +getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck) +{ + struct stat st; + size_t i; + int fd, flags; + int save_errno = errno; + +start: + + flags = O_RDONLY; +#ifdef O_NOFOLLOW + flags |= O_NOFOLLOW; +#endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + fd = open(path, flags); + if (fd == -1) { + if (errno == EINTR) + goto start; + goto nodevrandom; + } +#ifndef O_CLOEXEC + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif + + /* Lightly verify that the device node looks sane */ + if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { + close(fd); + goto nodevrandom; + } + for (i = 0; i < len; ) { + size_t wanted = len - i; + ssize_t ret = read(fd, (char *)buf + i, wanted); + + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + goto nodevrandom; + } + i += ret; + } + close(fd); + errno = save_errno; + return (0); /* satisfied */ +nodevrandom: + errno = EIO; + return (-1); +} + +static const int cl[] = { + CLOCK_REALTIME, +#ifdef CLOCK_MONOTONIC + CLOCK_MONOTONIC, +#endif +#ifdef CLOCK_MONOTONIC_RAW + CLOCK_MONOTONIC_RAW, +#endif +#ifdef CLOCK_TAI + CLOCK_TAI, +#endif +#ifdef CLOCK_VIRTUAL + CLOCK_VIRTUAL, +#endif +#ifdef CLOCK_UPTIME + CLOCK_UPTIME, +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + CLOCK_PROCESS_CPUTIME_ID, +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + CLOCK_THREAD_CPUTIME_ID, +#endif +}; + +static int +getentropy_fallback(void *buf, size_t len) +{ + uint8_t results[SHA512_DIGEST_LENGTH]; + int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat; + static int cnt; + struct timespec ts; + struct timeval tv; + struct pst_vminfo pvi; + struct pst_vm_status pvs; + struct pst_dynamic pdy; + struct rusage ru; + sigset_t sigset; + struct stat st; + SHA512_CTX ctx; + static pid_t lastpid; + pid_t pid; + size_t i, ii, m; + char *p; + + pid = getpid(); + if (lastpid == pid) { + faster = 1; + repeat = 2; + } else { + faster = 0; + lastpid = pid; + repeat = REPEAT; + } + for (i = 0; i < len; ) { + int j; + SHA512_Init(&ctx); + for (j = 0; j < repeat; j++) { + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HX(pstat_getvminfo(&pvi, sizeof(pvi), 1, 0) != 1, pvi); + HX(pstat_getprocvm(&pvs, sizeof(pvs), 0, 0) != 1, pvs); + + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) + HX(clock_gettime(cl[ii], &ts) == -1, ts); + + HX((pid = getpid()) == -1, pid); + HX((pid = getsid(pid)) == -1, pid); + HX((pid = getppid()) == -1, pid); + HX((pid = getpgid(0)) == -1, pid); + HX((e = getpriority(0, 0)) == -1, e); + + if(pstat_getdynamic(&pdy, sizeof(pdy), 1, 0) != 1) { + HD(errno); + } else { + HD(pdy.psd_avg_1_min); + HD(pdy.psd_avg_5_min); + HD(pdy.psd_avg_15_min); + } + + if (!faster) { + ts.tv_sec = 0; + ts.tv_nsec = 1; + (void) nanosleep(&ts, NULL); + } + + HX(sigpending(&sigset) == -1, sigset); + HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, + sigset); + + HF(getentropy); /* an addr in this library */ + HF(printf); /* an addr in libc */ + p = (char *)&p; + HD(p); /* an addr on stack */ + p = (char *)&errno; + HD(p); /* the addr of errno */ + + if (i == 0) { + struct sockaddr_storage ss; + struct statvfs stvfs; + struct termios tios; + socklen_t ssl; + off_t off; + + /* + * Prime-sized mappings encourage fragmentation; + * thus exposing some address entropy. + */ + struct mm { + size_t npg; + void *p; + } mm[] = { + { 17, MAP_FAILED }, { 3, MAP_FAILED }, + { 11, MAP_FAILED }, { 2, MAP_FAILED }, + { 5, MAP_FAILED }, { 3, MAP_FAILED }, + { 7, MAP_FAILED }, { 1, MAP_FAILED }, + { 57, MAP_FAILED }, { 3, MAP_FAILED }, + { 131, MAP_FAILED }, { 1, MAP_FAILED }, + }; + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + HX(mm[m].p = mmap(NULL, + mm[m].npg * pgs, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, + (off_t)0), mm[m].p); + if (mm[m].p != MAP_FAILED) { + size_t mo; + + /* Touch some memory... */ + p = mm[m].p; + mo = cnt % + (mm[m].npg * pgs - 1); + p[mo] = 1; + cnt += (int)((long)(mm[m].p) + / pgs); + } + + /* Check cnts and times... */ + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); + ii++) { + HX((e = clock_gettime(cl[ii], + &ts)) == -1, ts); + if (e != -1) + cnt += (int)ts.tv_nsec; + } + + HX((e = getrusage(RUSAGE_SELF, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + if (mm[m].p != MAP_FAILED) + munmap(mm[m].p, mm[m].npg * pgs); + mm[m].p = MAP_FAILED; + } + + HX(stat(".", &st) == -1, st); + HX(statvfs(".", &stvfs) == -1, stvfs); + + HX(stat("/", &st) == -1, st); + HX(statvfs("/", &stvfs) == -1, stvfs); + + HX((e = fstat(0, &st)) == -1, st); + if (e == -1) { + if (S_ISREG(st.st_mode) || + S_ISFIFO(st.st_mode) || + S_ISSOCK(st.st_mode)) { + HX(fstatvfs(0, &stvfs) == -1, + stvfs); + HX((off = lseek(0, (off_t)0, + SEEK_CUR)) < 0, off); + } + if (S_ISCHR(st.st_mode)) { + HX(tcgetattr(0, &tios) == -1, + tios); + } else if (S_ISSOCK(st.st_mode)) { + memset(&ss, 0, sizeof ss); + ssl = sizeof(ss); + HX(getpeername(0, + (void *)&ss, &ssl) == -1, + ss); + } + } + + HX((e = getrusage(RUSAGE_CHILDREN, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } else { + /* Subsequent hashes absorb previous result */ + HD(results); + } + + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HD(cnt); + } + SHA512_Final(results, &ctx); + memcpy((char *)buf + i, results, MINIMUM(sizeof(results), len - i)); + i += MINIMUM(sizeof(results), len - i); + } + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ +} diff --git a/Libraries/libressl/crypto/compat/getentropy_linux.c b/Libraries/libressl/crypto/compat/getentropy_linux.c new file mode 100644 index 000000000..c7c39c234 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_linux.c @@ -0,0 +1,525 @@ +/* $OpenBSD: getentropy_linux.c,v 1.48 2021/10/24 21:24:20 deraadt Exp $ */ + +/* + * Copyright (c) 2014 Theo de Raadt + * Copyright (c) 2014 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#define _POSIX_C_SOURCE 199309L +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#ifdef SYS__sysctl +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef HAVE_GETAUXVAL +#include +#endif +#include + +#define REPEAT 5 +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +#define HX(a, b) \ + do { \ + if ((a)) \ + HD(errno); \ + else \ + HD(b); \ + } while (0) + +#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) +#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) +#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) + +int getentropy(void *buf, size_t len); + +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) +static int getentropy_getrandom(void *buf, size_t len); +#endif +static int getentropy_urandom(void *buf, size_t len); +#ifdef SYS__sysctl +static int getentropy_sysctl(void *buf, size_t len); +#endif +static int getentropy_fallback(void *buf, size_t len); +static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data); + +int +getentropy(void *buf, size_t len) +{ + int ret = -1; + + if (len > 256) { + errno = EIO; + return (-1); + } + +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) + /* + * Try descriptor-less getrandom(), in non-blocking mode. + * + * The design of Linux getrandom is broken. It has an + * uninitialized phase coupled with blocking behaviour, which + * is unacceptable from within a library at boot time without + * possible recovery. See http://bugs.python.org/issue26839#msg267745 + */ + ret = getentropy_getrandom(buf, len); + if (ret != -1) + return (ret); +#endif + + /* + * Try to get entropy with /dev/urandom + * + * This can fail if the process is inside a chroot or if file + * descriptors are exhausted. + */ + ret = getentropy_urandom(buf, len); + if (ret != -1) + return (ret); + +#ifdef SYS__sysctl + /* + * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID. + * sysctl is a failsafe API, so it guarantees a result. This + * should work inside a chroot, or when file descriptors are + * exhausted. + * + * However this can fail if the Linux kernel removes support + * for sysctl. Starting in 2007, there have been efforts to + * deprecate the sysctl API/ABI, and push callers towards use + * of the chroot-unavailable fd-using /proc mechanism -- + * essentially the same problems as /dev/urandom. + * + * Numerous setbacks have been encountered in their deprecation + * schedule, so as of June 2014 the kernel ABI still exists on + * most Linux architectures. The sysctl() stub in libc is missing + * on some systems. There are also reports that some kernels + * spew messages to the console. + */ + ret = getentropy_sysctl(buf, len); + if (ret != -1) + return (ret); +#endif /* SYS__sysctl */ + + /* + * Entropy collection via /dev/urandom and sysctl have failed. + * + * No other API exists for collecting entropy. See the large + * comment block above. + * + * We have very few options: + * - Even syslog_r is unsafe to call at this low level, so + * there is no way to alert the user or program. + * - Cannot call abort() because some systems have unsafe + * corefiles. + * - Could raise(SIGKILL) resulting in silent program termination. + * - Return EIO, to hint that arc4random's stir function + * should raise(SIGKILL) + * - Do the best under the circumstances.... + * + * This code path exists to bring light to the issue that Linux + * still does not provide a failsafe API for entropy collection. + * + * We hope this demonstrates that Linux should either retain their + * sysctl ABI, or consider providing a new failsafe API which + * works in a chroot or when file descriptors are exhausted. + */ +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} + +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) +static int +getentropy_getrandom(void *buf, size_t len) +{ + int pre_errno = errno; + int ret; + if (len > 256) + return (-1); + do { + ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK); + } while (ret == -1 && errno == EINTR); + + if (ret != len) + return (-1); + errno = pre_errno; + return (0); +} +#endif + +static int +getentropy_urandom(void *buf, size_t len) +{ + struct stat st; + size_t i; + int fd, cnt, flags; + int save_errno = errno; + +start: + + flags = O_RDONLY; +#ifdef O_NOFOLLOW + flags |= O_NOFOLLOW; +#endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + fd = open("/dev/urandom", flags); + if (fd == -1) { + if (errno == EINTR) + goto start; + goto nodevrandom; + } +#ifndef O_CLOEXEC + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif + + /* Lightly verify that the device node looks sane */ + if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { + close(fd); + goto nodevrandom; + } + if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) { + close(fd); + goto nodevrandom; + } + for (i = 0; i < len; ) { + size_t wanted = len - i; + ssize_t ret = read(fd, (char *)buf + i, wanted); + + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + goto nodevrandom; + } + i += ret; + } + close(fd); + errno = save_errno; + return (0); /* satisfied */ +nodevrandom: + errno = EIO; + return (-1); +} + +#ifdef SYS__sysctl +static int +getentropy_sysctl(void *buf, size_t len) +{ + static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID }; + size_t i; + int save_errno = errno; + + for (i = 0; i < len; ) { + size_t chunk = MINIMUM(len - i, 16); + + /* SYS__sysctl because some systems already removed sysctl() */ + struct __sysctl_args args = { + .name = mib, + .nlen = 3, + .oldval = (char *)buf + i, + .oldlenp = &chunk, + }; + if (syscall(SYS__sysctl, &args) != 0) + goto sysctlfailed; + i += chunk; + } + errno = save_errno; + return (0); /* satisfied */ +sysctlfailed: + errno = EIO; + return (-1); +} +#endif /* SYS__sysctl */ + +static const int cl[] = { + CLOCK_REALTIME, +#ifdef CLOCK_MONOTONIC + CLOCK_MONOTONIC, +#endif +#ifdef CLOCK_MONOTONIC_RAW + CLOCK_MONOTONIC_RAW, +#endif +#ifdef CLOCK_TAI + CLOCK_TAI, +#endif +#ifdef CLOCK_VIRTUAL + CLOCK_VIRTUAL, +#endif +#ifdef CLOCK_UPTIME + CLOCK_UPTIME, +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + CLOCK_PROCESS_CPUTIME_ID, +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + CLOCK_THREAD_CPUTIME_ID, +#endif +}; + +static int +getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data) +{ + SHA512_CTX *ctx = data; + + SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); + return (0); +} + +static int +getentropy_fallback(void *buf, size_t len) +{ + uint8_t results[SHA512_DIGEST_LENGTH]; + int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; + static int cnt; + struct timespec ts; + struct timeval tv; + struct rusage ru; + sigset_t sigset; + struct stat st; + SHA512_CTX ctx; + static pid_t lastpid; + pid_t pid; + size_t i, ii, m; + char *p; + + pid = getpid(); + if (lastpid == pid) { + faster = 1; + repeat = 2; + } else { + faster = 0; + lastpid = pid; + repeat = REPEAT; + } + for (i = 0; i < len; ) { + int j; + SHA512_Init(&ctx); + for (j = 0; j < repeat; j++) { + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + dl_iterate_phdr(getentropy_phdr, &ctx); + + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) + HX(clock_gettime(cl[ii], &ts) == -1, ts); + + HX((pid = getpid()) == -1, pid); + HX((pid = getsid(pid)) == -1, pid); + HX((pid = getppid()) == -1, pid); + HX((pid = getpgid(0)) == -1, pid); + HX((e = getpriority(0, 0)) == -1, e); + + if (!faster) { + ts.tv_sec = 0; + ts.tv_nsec = 1; + (void) nanosleep(&ts, NULL); + } + + HX(sigpending(&sigset) == -1, sigset); + HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, + sigset); + + HF(getentropy); /* an addr in this library */ + HF(printf); /* an addr in libc */ + p = (char *)&p; + HD(p); /* an addr on stack */ + p = (char *)&errno; + HD(p); /* the addr of errno */ + + if (i == 0) { + struct sockaddr_storage ss; + struct statvfs stvfs; + struct termios tios; + struct statfs stfs; + socklen_t ssl; + off_t off; + + /* + * Prime-sized mappings encourage fragmentation; + * thus exposing some address entropy. + */ + struct mm { + size_t npg; + void *p; + } mm[] = { + { 17, MAP_FAILED }, { 3, MAP_FAILED }, + { 11, MAP_FAILED }, { 2, MAP_FAILED }, + { 5, MAP_FAILED }, { 3, MAP_FAILED }, + { 7, MAP_FAILED }, { 1, MAP_FAILED }, + { 57, MAP_FAILED }, { 3, MAP_FAILED }, + { 131, MAP_FAILED }, { 1, MAP_FAILED }, + }; + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + HX(mm[m].p = mmap(NULL, + mm[m].npg * pgs, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, + (off_t)0), mm[m].p); + if (mm[m].p != MAP_FAILED) { + size_t mo; + + /* Touch some memory... */ + p = mm[m].p; + mo = cnt % + (mm[m].npg * pgs - 1); + p[mo] = 1; + cnt += (int)((long)(mm[m].p) + / pgs); + } + + /* Check cnts and times... */ + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); + ii++) { + HX((e = clock_gettime(cl[ii], + &ts)) == -1, ts); + if (e != -1) + cnt += (int)ts.tv_nsec; + } + + HX((e = getrusage(RUSAGE_SELF, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + if (mm[m].p != MAP_FAILED) + munmap(mm[m].p, mm[m].npg * pgs); + mm[m].p = MAP_FAILED; + } + + HX(stat(".", &st) == -1, st); + HX(statvfs(".", &stvfs) == -1, stvfs); + HX(statfs(".", &stfs) == -1, stfs); + + HX(stat("/", &st) == -1, st); + HX(statvfs("/", &stvfs) == -1, stvfs); + HX(statfs("/", &stfs) == -1, stfs); + + HX((e = fstat(0, &st)) == -1, st); + if (e == -1) { + if (S_ISREG(st.st_mode) || + S_ISFIFO(st.st_mode) || + S_ISSOCK(st.st_mode)) { + HX(fstatvfs(0, &stvfs) == -1, + stvfs); + HX(fstatfs(0, &stfs) == -1, + stfs); + HX((off = lseek(0, (off_t)0, + SEEK_CUR)) < 0, off); + } + if (S_ISCHR(st.st_mode)) { + HX(tcgetattr(0, &tios) == -1, + tios); + } else if (S_ISSOCK(st.st_mode)) { + memset(&ss, 0, sizeof ss); + ssl = sizeof(ss); + HX(getpeername(0, + (void *)&ss, &ssl) == -1, + ss); + } + } + + HX((e = getrusage(RUSAGE_CHILDREN, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } else { + /* Subsequent hashes absorb previous result */ + HD(results); + } + + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HD(cnt); + } +#ifdef HAVE_GETAUXVAL +#ifdef AT_RANDOM + /* Not as random as you think but we take what we are given */ + p = (char *) getauxval(AT_RANDOM); + if (p) + HR(p, 16); +#endif +#ifdef AT_SYSINFO_EHDR + p = (char *) getauxval(AT_SYSINFO_EHDR); + if (p) + HR(p, pgs); +#endif +#ifdef AT_BASE + p = (char *) getauxval(AT_BASE); + if (p) + HD(p); +#endif +#endif + + SHA512_Final(results, &ctx); + memcpy((char *)buf + i, results, MINIMUM(sizeof(results), len - i)); + i += MINIMUM(sizeof(results), len - i); + } + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ +} diff --git a/Libraries/libressl/crypto/compat/getentropy_netbsd.c b/Libraries/libressl/crypto/compat/getentropy_netbsd.c new file mode 100644 index 000000000..5dc89594c --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_netbsd.c @@ -0,0 +1,62 @@ +/* $OpenBSD: getentropy_netbsd.c,v 1.4 2020/10/12 22:08:33 deraadt Exp $ */ + +/* + * Copyright (c) 2014 Pawel Jakub Dawidek + * Copyright (c) 2014 Brent Cook + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include + +#include +#include + +/* + * Derived from lib/libc/gen/arc4random.c from FreeBSD. + */ +static size_t +getentropy_sysctl(u_char *buf, size_t size) +{ + const int mib[2] = { CTL_KERN, KERN_ARND }; + size_t len, done; + + done = 0; + + do { + len = size; + if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) + return (done); + done += len; + buf += len; + size -= len; + } while (size > 0); + + return (done); +} + +int +getentropy(void *buf, size_t len) +{ + if (len <= 256 && + getentropy_sysctl(buf, len) == len) { + return (0); + } + + errno = EIO; + return (-1); +} diff --git a/Libraries/libressl/crypto/compat/getentropy_osx.c b/Libraries/libressl/crypto/compat/getentropy_osx.c new file mode 100644 index 000000000..db028d19b --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_osx.c @@ -0,0 +1,417 @@ +/* $OpenBSD: getentropy_osx.c,v 1.14 2021/10/24 21:24:20 deraadt Exp $ */ + +/* + * Copyright (c) 2014 Theo de Raadt + * Copyright (c) 2014 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if TARGET_OS_OSX +#include +#include +#endif +#include +#include +#if TARGET_OS_OSX +#include +#include +#include +#include +#endif +#include +#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c))) +#define SHA512_Init(xxx) (CC_SHA512_Init((xxx))) +#define SHA512_Final(xxx, yyy) (CC_SHA512_Final((xxx), (yyy))) +#define SHA512_CTX CC_SHA512_CTX +#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH + +#define REPEAT 5 +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +#define HX(a, b) \ + do { \ + if ((a)) \ + HD(errno); \ + else \ + HD(b); \ + } while (0) + +#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) +#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) +#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) + +int getentropy(void *buf, size_t len); + +static int getentropy_urandom(void *buf, size_t len); +static int getentropy_fallback(void *buf, size_t len); + +int +getentropy(void *buf, size_t len) +{ + int ret = -1; + + if (len > 256) { + errno = EIO; + return (-1); + } + + /* + * Try to get entropy with /dev/urandom + * + * This can fail if the process is inside a chroot or if file + * descriptors are exhausted. + */ + ret = getentropy_urandom(buf, len); + if (ret != -1) + return (ret); + + /* + * Entropy collection via /dev/urandom and sysctl have failed. + * + * No other API exists for collecting entropy, and we have + * no failsafe way to get it on OSX that is not sensitive + * to resource exhaustion. + * + * We have very few options: + * - Even syslog_r is unsafe to call at this low level, so + * there is no way to alert the user or program. + * - Cannot call abort() because some systems have unsafe + * corefiles. + * - Could raise(SIGKILL) resulting in silent program termination. + * - Return EIO, to hint that arc4random's stir function + * should raise(SIGKILL) + * - Do the best under the circumstances.... + * + * This code path exists to bring light to the issue that OSX + * does not provide a failsafe API for entropy collection. + * + * We hope this demonstrates that OSX should consider + * providing a new failsafe API which works in a chroot or + * when file descriptors are exhausted. + */ +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} + +static int +getentropy_urandom(void *buf, size_t len) +{ + struct stat st; + size_t i; + int fd, flags; + int save_errno = errno; + +start: + + flags = O_RDONLY; +#ifdef O_NOFOLLOW + flags |= O_NOFOLLOW; +#endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + fd = open("/dev/urandom", flags); + if (fd == -1) { + if (errno == EINTR) + goto start; + goto nodevrandom; + } +#ifndef O_CLOEXEC + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif + + /* Lightly verify that the device node looks sane */ + if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { + close(fd); + goto nodevrandom; + } + for (i = 0; i < len; ) { + size_t wanted = len - i; + ssize_t ret = read(fd, (char *)buf + i, wanted); + + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + goto nodevrandom; + } + i += ret; + } + close(fd); + errno = save_errno; + return (0); /* satisfied */ +nodevrandom: + errno = EIO; + return (-1); +} + +#if TARGET_OS_OSX +static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS }; +static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS }; +static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS }; +#endif +static int kmib[] = { CTL_KERN, KERN_USRSTACK }; +static int hwmib[] = { CTL_HW, HW_USERMEM }; + +static int +getentropy_fallback(void *buf, size_t len) +{ + uint8_t results[SHA512_DIGEST_LENGTH]; + int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; + static int cnt; + struct timespec ts; + struct timeval tv; + struct rusage ru; + sigset_t sigset; + struct stat st; + SHA512_CTX ctx; + static pid_t lastpid; + pid_t pid; + size_t i, ii, m; + char *p; +#if TARGET_OS_OSX + struct tcpstat tcpstat; + struct udpstat udpstat; + struct ipstat ipstat; +#endif + u_int64_t mach_time; + unsigned int idata; + void *addr; + + pid = getpid(); + if (lastpid == pid) { + faster = 1; + repeat = 2; + } else { + faster = 0; + lastpid = pid; + repeat = REPEAT; + } + for (i = 0; i < len; ) { + int j; + SHA512_Init(&ctx); + for (j = 0; j < repeat; j++) { + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + mach_time = mach_absolute_time(); + HD(mach_time); + + ii = sizeof(addr); + HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]), + &addr, &ii, NULL, 0) == -1, addr); + + ii = sizeof(idata); + HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]), + &idata, &ii, NULL, 0) == -1, idata); + +#if TARGET_OS_OSX + ii = sizeof(tcpstat); + HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]), + &tcpstat, &ii, NULL, 0) == -1, tcpstat); + + ii = sizeof(udpstat); + HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]), + &udpstat, &ii, NULL, 0) == -1, udpstat); + + ii = sizeof(ipstat); + HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]), + &ipstat, &ii, NULL, 0) == -1, ipstat); +#endif + + HX((pid = getpid()) == -1, pid); + HX((pid = getsid(pid)) == -1, pid); + HX((pid = getppid()) == -1, pid); + HX((pid = getpgid(0)) == -1, pid); + HX((e = getpriority(0, 0)) == -1, e); + + if (!faster) { + ts.tv_sec = 0; + ts.tv_nsec = 1; + (void) nanosleep(&ts, NULL); + } + + HX(sigpending(&sigset) == -1, sigset); + HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, + sigset); + + HF(getentropy); /* an addr in this library */ + HF(printf); /* an addr in libc */ + p = (char *)&p; + HD(p); /* an addr on stack */ + p = (char *)&errno; + HD(p); /* the addr of errno */ + + if (i == 0) { + struct sockaddr_storage ss; + struct statvfs stvfs; + struct termios tios; + struct statfs stfs; + socklen_t ssl; + off_t off; + + /* + * Prime-sized mappings encourage fragmentation; + * thus exposing some address entropy. + */ + struct mm { + size_t npg; + void *p; + } mm[] = { + { 17, MAP_FAILED }, { 3, MAP_FAILED }, + { 11, MAP_FAILED }, { 2, MAP_FAILED }, + { 5, MAP_FAILED }, { 3, MAP_FAILED }, + { 7, MAP_FAILED }, { 1, MAP_FAILED }, + { 57, MAP_FAILED }, { 3, MAP_FAILED }, + { 131, MAP_FAILED }, { 1, MAP_FAILED }, + }; + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + HX(mm[m].p = mmap(NULL, + mm[m].npg * pgs, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, + (off_t)0), mm[m].p); + if (mm[m].p != MAP_FAILED) { + size_t mo; + + /* Touch some memory... */ + p = mm[m].p; + mo = cnt % + (mm[m].npg * pgs - 1); + p[mo] = 1; + cnt += (int)((long)(mm[m].p) + / pgs); + } + + /* Check cnts and times... */ + mach_time = mach_absolute_time(); + HD(mach_time); + cnt += (int)mach_time; + + HX((e = getrusage(RUSAGE_SELF, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + if (mm[m].p != MAP_FAILED) + munmap(mm[m].p, mm[m].npg * pgs); + mm[m].p = MAP_FAILED; + } + + HX(stat(".", &st) == -1, st); + HX(statvfs(".", &stvfs) == -1, stvfs); + HX(statfs(".", &stfs) == -1, stfs); + + HX(stat("/", &st) == -1, st); + HX(statvfs("/", &stvfs) == -1, stvfs); + HX(statfs("/", &stfs) == -1, stfs); + + HX((e = fstat(0, &st)) == -1, st); + if (e == -1) { + if (S_ISREG(st.st_mode) || + S_ISFIFO(st.st_mode) || + S_ISSOCK(st.st_mode)) { + HX(fstatvfs(0, &stvfs) == -1, + stvfs); + HX(fstatfs(0, &stfs) == -1, + stfs); + HX((off = lseek(0, (off_t)0, + SEEK_CUR)) < 0, off); + } + if (S_ISCHR(st.st_mode)) { + HX(tcgetattr(0, &tios) == -1, + tios); + } else if (S_ISSOCK(st.st_mode)) { + memset(&ss, 0, sizeof ss); + ssl = sizeof(ss); + HX(getpeername(0, + (void *)&ss, &ssl) == -1, + ss); + } + } + + HX((e = getrusage(RUSAGE_CHILDREN, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } else { + /* Subsequent hashes absorb previous result */ + HD(results); + } + + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HD(cnt); + } + + SHA512_Final(results, &ctx); + memcpy((char *)buf + i, results, MINIMUM(sizeof(results), len - i)); + i += MINIMUM(sizeof(results), len - i); + } + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ +} diff --git a/Libraries/libressl/crypto/compat/getentropy_solaris.c b/Libraries/libressl/crypto/compat/getentropy_solaris.c new file mode 100644 index 000000000..e36426caf --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_solaris.c @@ -0,0 +1,422 @@ +/* $OpenBSD: getentropy_solaris.c,v 1.15 2021/10/24 21:24:20 deraadt Exp $ */ + +/* + * Copyright (c) 2014 Theo de Raadt + * Copyright (c) 2014 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SHA512_Init SHA512Init +#define SHA512_Update SHA512Update +#define SHA512_Final SHA512Final + +#include +#include +#include + +#define REPEAT 5 +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +#define HX(a, b) \ + do { \ + if ((a)) \ + HD(errno); \ + else \ + HD(b); \ + } while (0) + +#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) +#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) +#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) + +int getentropy(void *buf, size_t len); + +static int getentropy_urandom(void *buf, size_t len, const char *path, + int devfscheck); +static int getentropy_fallback(void *buf, size_t len); +static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data); + +int +getentropy(void *buf, size_t len) +{ + int ret = -1; + + if (len > 256) { + errno = EIO; + return (-1); + } + + /* + * Try to get entropy with /dev/urandom + * + * Solaris provides /dev/urandom as a symbolic link to + * /devices/pseudo/random@0:urandom which is provided by + * a devfs filesystem. Best practice is to use O_NOFOLLOW, + * so we must try the unpublished name directly. + * + * This can fail if the process is inside a chroot which lacks + * the devfs mount, or if file descriptors are exhausted. + */ + ret = getentropy_urandom(buf, len, + "/devices/pseudo/random@0:urandom", 1); + if (ret != -1) + return (ret); + + /* + * Unfortunately, chroot spaces on Solaris are sometimes setup + * with direct device node of the well-known /dev/urandom name + * (perhaps to avoid dragging all of devfs into the space). + * + * This can fail if the process is inside a chroot or if file + * descriptors are exhausted. + */ + ret = getentropy_urandom(buf, len, "/dev/urandom", 0); + if (ret != -1) + return (ret); + + /* + * Entropy collection via /dev/urandom has failed. + * + * No other API exists for collecting entropy, and we have + * no failsafe way to get it on Solaris that is not sensitive + * to resource exhaustion. + * + * We have very few options: + * - Even syslog_r is unsafe to call at this low level, so + * there is no way to alert the user or program. + * - Cannot call abort() because some systems have unsafe + * corefiles. + * - Could raise(SIGKILL) resulting in silent program termination. + * - Return EIO, to hint that arc4random's stir function + * should raise(SIGKILL) + * - Do the best under the circumstances.... + * + * This code path exists to bring light to the issue that Solaris + * does not provide a failsafe API for entropy collection. + * + * We hope this demonstrates that Solaris should consider + * providing a new failsafe API which works in a chroot or + * when file descriptors are exhausted. + */ +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} + +static int +getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck) +{ + struct stat st; + size_t i; + int fd, flags; + int save_errno = errno; + +start: + + flags = O_RDONLY; +#ifdef O_NOFOLLOW + flags |= O_NOFOLLOW; +#endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + fd = open(path, flags); + if (fd == -1) { + if (errno == EINTR) + goto start; + goto nodevrandom; + } +#ifndef O_CLOEXEC + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif + + /* Lightly verify that the device node looks sane */ + if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) || + (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) { + close(fd); + goto nodevrandom; + } + for (i = 0; i < len; ) { + size_t wanted = len - i; + ssize_t ret = read(fd, (char *)buf + i, wanted); + + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + goto nodevrandom; + } + i += ret; + } + close(fd); + errno = save_errno; + return (0); /* satisfied */ +nodevrandom: + errno = EIO; + return (-1); +} + +static const int cl[] = { + CLOCK_REALTIME, +#ifdef CLOCK_MONOTONIC + CLOCK_MONOTONIC, +#endif +#ifdef CLOCK_MONOTONIC_RAW + CLOCK_MONOTONIC_RAW, +#endif +#ifdef CLOCK_TAI + CLOCK_TAI, +#endif +#ifdef CLOCK_VIRTUAL + CLOCK_VIRTUAL, +#endif +#ifdef CLOCK_UPTIME + CLOCK_UPTIME, +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + CLOCK_PROCESS_CPUTIME_ID, +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + CLOCK_THREAD_CPUTIME_ID, +#endif +}; + +static int +getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data) +{ + SHA512_CTX *ctx = data; + + SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); + return (0); +} + +static int +getentropy_fallback(void *buf, size_t len) +{ + uint8_t results[SHA512_DIGEST_LENGTH]; + int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; + static int cnt; + struct timespec ts; + struct timeval tv; + double loadavg[3]; + struct rusage ru; + sigset_t sigset; + struct stat st; + SHA512_CTX ctx; + static pid_t lastpid; + pid_t pid; + size_t i, ii, m; + char *p; + + pid = getpid(); + if (lastpid == pid) { + faster = 1; + repeat = 2; + } else { + faster = 0; + lastpid = pid; + repeat = REPEAT; + } + for (i = 0; i < len; ) { + int j; + SHA512_Init(&ctx); + for (j = 0; j < repeat; j++) { + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + dl_iterate_phdr(getentropy_phdr, &ctx); + + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) + HX(clock_gettime(cl[ii], &ts) == -1, ts); + + HX((pid = getpid()) == -1, pid); + HX((pid = getsid(pid)) == -1, pid); + HX((pid = getppid()) == -1, pid); + HX((pid = getpgid(0)) == -1, pid); + HX((e = getpriority(0, 0)) == -1, e); + HX((getloadavg(loadavg, 3) == -1), loadavg); + + if (!faster) { + ts.tv_sec = 0; + ts.tv_nsec = 1; + (void) nanosleep(&ts, NULL); + } + + HX(sigpending(&sigset) == -1, sigset); + HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, + sigset); + + HF(getentropy); /* an addr in this library */ + HF(printf); /* an addr in libc */ + p = (char *)&p; + HD(p); /* an addr on stack */ + p = (char *)&errno; + HD(p); /* the addr of errno */ + + if (i == 0) { + struct sockaddr_storage ss; + struct statvfs stvfs; + struct termios tios; + socklen_t ssl; + off_t off; + + /* + * Prime-sized mappings encourage fragmentation; + * thus exposing some address entropy. + */ + struct mm { + size_t npg; + void *p; + } mm[] = { + { 17, MAP_FAILED }, { 3, MAP_FAILED }, + { 11, MAP_FAILED }, { 2, MAP_FAILED }, + { 5, MAP_FAILED }, { 3, MAP_FAILED }, + { 7, MAP_FAILED }, { 1, MAP_FAILED }, + { 57, MAP_FAILED }, { 3, MAP_FAILED }, + { 131, MAP_FAILED }, { 1, MAP_FAILED }, + }; + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + HX(mm[m].p = mmap(NULL, + mm[m].npg * pgs, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, + (off_t)0), mm[m].p); + if (mm[m].p != MAP_FAILED) { + size_t mo; + + /* Touch some memory... */ + p = mm[m].p; + mo = cnt % + (mm[m].npg * pgs - 1); + p[mo] = 1; + cnt += (int)((long)(mm[m].p) + / pgs); + } + + /* Check cnts and times... */ + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); + ii++) { + HX((e = clock_gettime(cl[ii], + &ts)) == -1, ts); + if (e != -1) + cnt += (int)ts.tv_nsec; + } + + HX((e = getrusage(RUSAGE_SELF, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } + + for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { + if (mm[m].p != MAP_FAILED) + munmap(mm[m].p, mm[m].npg * pgs); + mm[m].p = MAP_FAILED; + } + + HX(stat(".", &st) == -1, st); + HX(statvfs(".", &stvfs) == -1, stvfs); + + HX(stat("/", &st) == -1, st); + HX(statvfs("/", &stvfs) == -1, stvfs); + + HX((e = fstat(0, &st)) == -1, st); + if (e == -1) { + if (S_ISREG(st.st_mode) || + S_ISFIFO(st.st_mode) || + S_ISSOCK(st.st_mode)) { + HX(fstatvfs(0, &stvfs) == -1, + stvfs); + HX((off = lseek(0, (off_t)0, + SEEK_CUR)) < 0, off); + } + if (S_ISCHR(st.st_mode)) { + HX(tcgetattr(0, &tios) == -1, + tios); + } else if (S_ISSOCK(st.st_mode)) { + memset(&ss, 0, sizeof ss); + ssl = sizeof(ss); + HX(getpeername(0, + (void *)&ss, &ssl) == -1, + ss); + } + } + + HX((e = getrusage(RUSAGE_CHILDREN, + &ru)) == -1, ru); + if (e != -1) { + cnt += (int)ru.ru_utime.tv_sec; + cnt += (int)ru.ru_utime.tv_usec; + } + } else { + /* Subsequent hashes absorb previous result */ + HD(results); + } + + HX((e = gettimeofday(&tv, NULL)) == -1, tv); + if (e != -1) { + cnt += (int)tv.tv_sec; + cnt += (int)tv.tv_usec; + } + + HD(cnt); + } + SHA512_Final(results, &ctx); + memcpy((char *)buf + i, results, MINIMUM(sizeof(results), len - i)); + i += MINIMUM(sizeof(results), len - i); + } + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ +} diff --git a/Libraries/libressl/crypto/compat/getentropy_win.c b/Libraries/libressl/crypto/compat/getentropy_win.c new file mode 100644 index 000000000..64514b3a3 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getentropy_win.c @@ -0,0 +1,50 @@ +/* $OpenBSD: getentropy_win.c,v 1.6 2020/11/11 10:41:24 bcook Exp $ */ + +/* + * Copyright (c) 2014, Theo de Raadt + * Copyright (c) 2014, Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include +#include +#include +#include + +int getentropy(void *buf, size_t len); + +/* + * On Windows, BCryptGenRandom with BCRYPT_USE_SYSTEM_PREFERRED_RNG is supposed + * to be a well-seeded, cryptographically strong random number generator. + * https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom + */ +int +getentropy(void *buf, size_t len) +{ + if (len > 256) { + errno = EIO; + return (-1); + } + + if (FAILED(BCryptGenRandom(NULL, buf, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { + errno = EIO; + return (-1); + } + + return (0); +} diff --git a/Libraries/libressl/crypto/compat/getopt_long.c b/Libraries/libressl/crypto/compat/getopt_long.c new file mode 100644 index 000000000..546c541b4 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getopt_long.c @@ -0,0 +1,528 @@ +/* $OpenBSD: getopt_long.c,v 1.32 2020/05/27 22:25:09 schwarze Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#if 0 +/* DEF_* only work on initialized (non-COMMON) variables */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + ((char **)nargv)[pos] = nargv[cstart]; + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too, int flags) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match, exact_match, second_partial_match; + + current_argv = place; + match = -1; + exact_match = 0; + second_partial_match = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + exact_match = 1; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* first partial match */ + match = i; + else if ((flags & FLAG_LONGONLY) || + long_options[i].has_arg != long_options[match].has_arg || + long_options[i].flag != long_options[match].flag || + long_options[i].val != long_options[match].val) + second_partial_match = 1; + } + if (!exact_match && second_partial_match) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + if (posixly_correct == -1 || optreset) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too, flags); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (oli = strchr(options, optchar)) == NULL) { + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0, flags); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/Libraries/libressl/crypto/compat/getpagesize.c b/Libraries/libressl/crypto/compat/getpagesize.c new file mode 100644 index 000000000..cbaae92a6 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getpagesize.c @@ -0,0 +1,18 @@ +/* $OpenBSD$ */ + +#include + +#ifdef _WIN32 +#include +#endif + +int +getpagesize(void) { +#ifdef _WIN32 + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return system_info.dwPageSize; +#else + return sysconf(_SC_PAGESIZE); +#endif +} diff --git a/Libraries/libressl/crypto/compat/getprogname_linux.c b/Libraries/libressl/crypto/compat/getprogname_linux.c new file mode 100644 index 000000000..1850e8666 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getprogname_linux.c @@ -0,0 +1,23 @@ +#include + +#include + +const char * +getprogname(void) +{ +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + /* + * Android added getprogname with API 21, so we should not end up here + * with APIs newer than 21. + * https://github.com/aosp-mirror/platform_bionic/blob/1eb6d3/libc/include/stdlib.h#L160 + * + * Since Android is using portions of OpenBSD libc, it should have + * a symbol called __progname. + * https://github.com/aosp-mirror/platform_bionic/commit/692207 + */ + extern const char *__progname; + return __progname; +#else + return program_invocation_short_name; +#endif +} diff --git a/Libraries/libressl/crypto/compat/getprogname_unimpl.c b/Libraries/libressl/crypto/compat/getprogname_unimpl.c new file mode 100644 index 000000000..339c54ae3 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getprogname_unimpl.c @@ -0,0 +1,7 @@ +#include + +const char * +getprogname(void) +{ + return "?"; +} diff --git a/Libraries/libressl/crypto/compat/getprogname_windows.c b/Libraries/libressl/crypto/compat/getprogname_windows.c new file mode 100644 index 000000000..eb04ec055 --- /dev/null +++ b/Libraries/libressl/crypto/compat/getprogname_windows.c @@ -0,0 +1,13 @@ +#include + +#include + +const char * +getprogname(void) +{ + static char progname[MAX_PATH + 1]; + DWORD length = GetModuleFileName(NULL, progname, sizeof (progname) - 1); + if (length < 0) + return "?"; + return progname; +} diff --git a/Libraries/libressl/crypto/compat/posix_win.c b/Libraries/libressl/crypto/compat/posix_win.c new file mode 100644 index 000000000..b3a468721 --- /dev/null +++ b/Libraries/libressl/crypto/compat/posix_win.c @@ -0,0 +1,310 @@ +/* + * Public domain + * + * BSD socket emulation code for Winsock2 + * File IO compatibility shims + * Brent Cook + * Kinichiro Inoguchi + */ + +#define NO_REDEF_POSIX_FUNCTIONS + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +void +posix_perror(const char *s) +{ + fprintf(stderr, "%s: %s\n", s, strerror(errno)); +} + +FILE * +posix_fopen(const char *path, const char *mode) +{ + if (strchr(mode, 'b') == NULL) { + char *bin_mode = NULL; + if (asprintf(&bin_mode, "%sb", mode) == -1) + return NULL; + FILE *f = fopen(path, bin_mode); + free(bin_mode); + return f; + } + + return fopen(path, mode); +} + +int +posix_open(const char *path, ...) +{ + va_list ap; + int mode = 0; + int flags; + + va_start(ap, path); + flags = va_arg(ap, int); + if (flags & O_CREAT) + mode = va_arg(ap, int); + va_end(ap); + + flags |= O_BINARY; + if (flags & O_CLOEXEC) { + flags &= ~O_CLOEXEC; + flags |= O_NOINHERIT; + } + flags &= ~O_NONBLOCK; + return open(path, flags, mode); +} + +char * +posix_fgets(char *s, int size, FILE *stream) +{ + char *ret = fgets(s, size, stream); + if (ret != NULL) { + size_t end = strlen(ret); + if (end >= 2 && ret[end - 2] == '\r' && ret[end - 1] == '\n') { + ret[end - 2] = '\n'; + ret[end - 1] = '\0'; + } + } + return ret; +} + +int +posix_rename(const char *oldpath, const char *newpath) +{ + return MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING) ? 0 : -1; +} + +static int +wsa_errno(int err) +{ + switch (err) { + case WSAENOBUFS: + errno = ENOMEM; + break; + case WSAEACCES: + errno = EACCES; + break; + case WSANOTINITIALISED: + errno = EPERM; + break; + case WSAEHOSTUNREACH: + case WSAENETDOWN: + errno = EIO; + break; + case WSAEFAULT: + errno = EFAULT; + break; + case WSAEINTR: + errno = EINTR; + break; + case WSAEINVAL: + errno = EINVAL; + break; + case WSAEINPROGRESS: + errno = EINPROGRESS; + break; + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + case WSAEOPNOTSUPP: + errno = ENOTSUP; + break; + case WSAEMSGSIZE: + errno = EFBIG; + break; + case WSAENOTSOCK: + errno = ENOTSOCK; + break; + case WSAENOPROTOOPT: + errno = ENOPROTOOPT; + break; + case WSAECONNREFUSED: + errno = ECONNREFUSED; + break; + case WSAEAFNOSUPPORT: + errno = EAFNOSUPPORT; + break; + case WSAEBADF: + errno = EBADF; + break; + case WSAENETRESET: + case WSAENOTCONN: + case WSAECONNABORTED: + case WSAECONNRESET: + case WSAESHUTDOWN: + case WSAETIMEDOUT: + errno = EPIPE; + break; + } + return -1; +} + +/* + * Employ a similar trick to cpython (pycore_fileutils.h) where the CRT report + * handler is disabled while checking if a descriptor is a socket or a file + */ +#if defined _MSC_VER && _MSC_VER >= 1900 + +#include +#include + +static void noop_handler(const wchar_t *expression, const wchar_t *function, + const wchar_t *file, unsigned int line, uintptr_t pReserved) +{ + return; +} + +#define BEGIN_SUPPRESS_IPH \ + _invalid_parameter_handler old_handler = _set_thread_local_invalid_parameter_handler(noop_handler) +#define END_SUPPRESS_IPH \ + _set_thread_local_invalid_parameter_handler(old_handler) + +#else + +#define BEGIN_SUPPRESS_IPH +#define END_SUPPRESS_IPH + +#endif + +static int +is_socket(int fd) +{ + intptr_t hd; + + BEGIN_SUPPRESS_IPH; + hd = _get_osfhandle(fd); + END_SUPPRESS_IPH; + + if (hd == (intptr_t)INVALID_HANDLE_VALUE) { + return 1; /* fd is not file descriptor */ + } + + return 0; +} + +int +posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + int rc = connect(sockfd, addr, addrlen); + if (rc == SOCKET_ERROR) + return wsa_errno(WSAGetLastError()); + return rc; +} + +int +posix_close(int fd) +{ + int rc; + + if (is_socket(fd)) { + if ((rc = closesocket(fd)) == SOCKET_ERROR) { + int err = WSAGetLastError(); + rc = wsa_errno(err); + } + } else { + rc = close(fd); + } + return rc; +} + +ssize_t +posix_read(int fd, void *buf, size_t count) +{ + ssize_t rc; + + if (is_socket(fd)) { + if ((rc = recv(fd, buf, count, 0)) == SOCKET_ERROR) { + int err = WSAGetLastError(); + rc = wsa_errno(err); + } + } else { + rc = read(fd, buf, count); + } + return rc; +} + +ssize_t +posix_write(int fd, const void *buf, size_t count) +{ + ssize_t rc; + if (is_socket(fd)) { + if ((rc = send(fd, buf, count, 0)) == SOCKET_ERROR) { + rc = wsa_errno(WSAGetLastError()); + } + } else { + rc = write(fd, buf, count); + } + return rc; +} + +int +posix_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen) +{ + int rc; + if (is_socket(sockfd)) { + rc = getsockopt(sockfd, level, optname, (char *)optval, optlen); + if (rc != 0) { + rc = wsa_errno(WSAGetLastError()); + } + } else { + rc = -1; + } + return rc; +} + +int +posix_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen) +{ + int rc; + if (is_socket(sockfd)) { + rc = setsockopt(sockfd, level, optname, (char *)optval, optlen); + if (rc != 0) { + rc = wsa_errno(WSAGetLastError()); + } + } else { + rc = -1; + } + return rc; +} + +uid_t getuid(void) +{ + /* Windows fstat sets 0 as st_uid */ + return 0; +} + +#ifdef _MSC_VER +struct timezone; +int gettimeofday(struct timeval * tp, struct timezone * tzp) +{ + /* + * Note: some broken versions only have 8 trailing zero's, the correct + * epoch has 9 trailing zero's + */ + static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tp->tv_sec = (long)((time - EPOCH) / 10000000L); + tp->tv_usec = (long)(system_time.wMilliseconds * 1000); + return 0; +} +#endif diff --git a/Libraries/libressl/crypto/compat/reallocarray.c b/Libraries/libressl/crypto/compat/reallocarray.c new file mode 100644 index 000000000..43f0b6915 --- /dev/null +++ b/Libraries/libressl/crypto/compat/reallocarray.c @@ -0,0 +1,38 @@ +/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} diff --git a/Libraries/libressl/crypto/compat/recallocarray.c b/Libraries/libressl/crypto/compat/recallocarray.c new file mode 100644 index 000000000..7ab2ec5ca --- /dev/null +++ b/Libraries/libressl/crypto/compat/recallocarray.c @@ -0,0 +1,80 @@ +/* $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */ +/* + * Copyright (c) 2008, 2017 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) +{ + size_t oldsize, newsize; + void *newptr; + + if (ptr == NULL) + return calloc(newnmemb, size); + + if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + newnmemb > 0 && SIZE_MAX / newnmemb < size) { + errno = ENOMEM; + return NULL; + } + newsize = newnmemb * size; + + if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { + errno = EINVAL; + return NULL; + } + oldsize = oldnmemb * size; + + /* + * Don't bother too much if we're shrinking just a bit, + * we do not shrink for series of small steps, oh well. + */ + if (newsize <= oldsize) { + size_t d = oldsize - newsize; + + if (d < oldsize / 2 && d < (size_t)getpagesize()) { + memset((char *)ptr + newsize, 0, d); + return ptr; + } + } + + newptr = malloc(newsize); + if (newptr == NULL) + return NULL; + + if (newsize > oldsize) { + memcpy(newptr, ptr, oldsize); + memset((char *)newptr + oldsize, 0, newsize - oldsize); + } else + memcpy(newptr, ptr, newsize); + + explicit_bzero(ptr, oldsize); + free(ptr); + + return newptr; +} diff --git a/Libraries/libressl/crypto/compat/strcasecmp.c b/Libraries/libressl/crypto/compat/strcasecmp.c new file mode 100644 index 000000000..e5da89c9d --- /dev/null +++ b/Libraries/libressl/crypto/compat/strcasecmp.c @@ -0,0 +1,105 @@ +/* $OpenBSD: strcasecmp.c,v 1.7 2015/08/31 02:53:57 guenther Exp $ */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +typedef unsigned char u_char; + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static const u_char charmap[] = { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', + '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', + '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', + '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', + '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', + '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', + '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', + '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', + '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', + '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', + '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', + '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', + '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', + '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', + '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', + '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', +}; + +int +strcasecmp(const char *s1, const char *s2) +{ + const u_char *cm = charmap; + const u_char *us1 = (const u_char *)s1; + const u_char *us2 = (const u_char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return (0); + return (cm[*us1] - cm[*--us2]); +} + +int +strncasecmp(const char *s1, const char *s2, size_t n) +{ + if (n != 0) { + const u_char *cm = charmap; + const u_char *us1 = (const u_char *)s1; + const u_char *us2 = (const u_char *)s2; + + do { + if (cm[*us1] != cm[*us2++]) + return (cm[*us1] - cm[*--us2]); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} diff --git a/Libraries/libressl/crypto/compat/strlcat.c b/Libraries/libressl/crypto/compat/strlcat.c new file mode 100644 index 000000000..c94e90dee --- /dev/null +++ b/Libraries/libressl/crypto/compat/strlcat.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Appends src to string dst of size dsize (unlike strncat, dsize is the + * full size of dst, not space left). At most dsize-1 characters + * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). + * Returns strlen(src) + MIN(dsize, strlen(initial dst)). + * If retval >= dsize, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t dsize) +{ + const char *odst = dst; + const char *osrc = src; + size_t n = dsize; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end. */ + while (n-- != 0 && *dst != '\0') + dst++; + dlen = dst - odst; + n = dsize - dlen; + + if (n-- == 0) + return(dlen + strlen(src)); + while (*src != '\0') { + if (n != 0) { + *dst++ = *src; + n--; + } + src++; + } + *dst = '\0'; + + return(dlen + (src - osrc)); /* count does not include NUL */ +} diff --git a/Libraries/libressl/crypto/compat/strlcpy.c b/Libraries/libressl/crypto/compat/strlcpy.c new file mode 100644 index 000000000..2fa498c39 --- /dev/null +++ b/Libraries/libressl/crypto/compat/strlcpy.c @@ -0,0 +1,50 @@ +/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Copy string src to buffer dst of size dsize. At most dsize-1 + * chars will be copied. Always NUL terminates (unless dsize == 0). + * Returns strlen(src); if retval >= dsize, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t dsize) +{ + const char *osrc = src; + size_t nleft = dsize; + + /* Copy as many bytes as will fit. */ + if (nleft != 0) { + while (--nleft != 0) { + if ((*dst++ = *src++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src. */ + if (nleft == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + + return(src - osrc - 1); /* count does not include NUL */ +} diff --git a/Libraries/libressl/crypto/compat/strndup.c b/Libraries/libressl/crypto/compat/strndup.c new file mode 100644 index 000000000..0f15e4228 --- /dev/null +++ b/Libraries/libressl/crypto/compat/strndup.c @@ -0,0 +1,39 @@ +/* $OpenBSD: strndup.c,v 1.3 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 2010 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +char * +strndup(const char *str, size_t maxlen) +{ + char *copy; + size_t len; + + len = strnlen(str, maxlen); + copy = malloc(len + 1); + if (copy != NULL) { + (void)memcpy(copy, str, len); + copy[len] = '\0'; + } + + return copy; +} diff --git a/Libraries/libressl/crypto/compat/strnlen.c b/Libraries/libressl/crypto/compat/strnlen.c new file mode 100644 index 000000000..84f2d22b6 --- /dev/null +++ b/Libraries/libressl/crypto/compat/strnlen.c @@ -0,0 +1,32 @@ +/* $OpenBSD: strnlen.c,v 1.9 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 2010 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +size_t +strnlen(const char *str, size_t maxlen) +{ + const char *cp; + + for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) + ; + + return (size_t)(cp - str); +} diff --git a/Libraries/libressl/crypto/compat/strsep.c b/Libraries/libressl/crypto/compat/strsep.c new file mode 100644 index 000000000..c5d651145 --- /dev/null +++ b/Libraries/libressl/crypto/compat/strsep.c @@ -0,0 +1,70 @@ +/* $OpenBSD: strsep.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} diff --git a/Libraries/libressl/crypto/compat/strtonum.c b/Libraries/libressl/crypto/compat/strtonum.c new file mode 100644 index 000000000..fdfc72aa7 --- /dev/null +++ b/Libraries/libressl/crypto/compat/strtonum.c @@ -0,0 +1,65 @@ +/* $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} diff --git a/Libraries/libressl/crypto/compat/syslog_r.c b/Libraries/libressl/crypto/compat/syslog_r.c new file mode 100644 index 000000000..d68169ddd --- /dev/null +++ b/Libraries/libressl/crypto/compat/syslog_r.c @@ -0,0 +1,19 @@ +#include + +void +syslog_r(int pri, struct syslog_data *data, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsyslog_r(pri, data, fmt, ap); + va_end(ap); +} + +void +vsyslog_r(int pri, struct syslog_data *data, const char *fmt, va_list ap) +{ +#ifdef HAVE_SYSLOG + vsyslog(pri, fmt, ap); +#endif +} diff --git a/Libraries/libressl/crypto/compat/timegm.c b/Libraries/libressl/crypto/compat/timegm.c new file mode 100644 index 000000000..2658445fc --- /dev/null +++ b/Libraries/libressl/crypto/compat/timegm.c @@ -0,0 +1,220 @@ +/* + * ---------------------------------------------------------------------- + * Copyright © 2005-2014 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ---------------------------------------------------------------------- + */ + +#include +#include +#include + +/* 2000-03-01 (mod 400 year, immediately after feb29 */ +#define LEAPOCH (946684800LL + 86400*(31+29)) + +#define DAYS_PER_400Y (365*400 + 97) +#define DAYS_PER_100Y (365*100 + 24) +#define DAYS_PER_4Y (365*4 + 1) + +static int __month_to_secs(int month, int is_leap) +{ + static const int secs_through_month[] = { + 0, 31*86400, 59*86400, 90*86400, + 120*86400, 151*86400, 181*86400, 212*86400, + 243*86400, 273*86400, 304*86400, 334*86400 }; + int t = secs_through_month[month]; + if (is_leap && month >= 2) t+=86400; + return t; +} + +static long long __year_to_secs(long long year, int *is_leap) +{ + if (year-2ULL <= 136) { + int y = year; + int leaps = (y-68)>>2; + if (!((y-68)&3)) { + leaps--; + if (is_leap) *is_leap = 1; + } else if (is_leap) *is_leap = 0; + return 31536000*(y-70) + 86400*leaps; + } + + int cycles, centuries, leaps, rem; + + if (!is_leap) is_leap = &(int){0}; + cycles = (year-100) / 400; + rem = (year-100) % 400; + if (rem < 0) { + cycles--; + rem += 400; + } + if (!rem) { + *is_leap = 1; + centuries = 0; + leaps = 0; + } else { + if (rem >= 200) { + if (rem >= 300) centuries = 3, rem -= 300; + else centuries = 2, rem -= 200; + } else { + if (rem >= 100) centuries = 1, rem -= 100; + else centuries = 0; + } + if (!rem) { + *is_leap = 0; + leaps = 0; + } else { + leaps = rem / 4U; + rem %= 4U; + *is_leap = !rem; + } + } + + leaps += 97*cycles + 24*centuries - *is_leap; + + return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400; +} + +static long long __tm_to_secs(const struct tm *tm) +{ + int is_leap; + long long year = tm->tm_year; + int month = tm->tm_mon; + if (month >= 12 || month < 0) { + int adj = month / 12; + month %= 12; + if (month < 0) { + adj--; + month += 12; + } + year += adj; + } + long long t = __year_to_secs(year, &is_leap); + t += __month_to_secs(month, is_leap); + t += 86400LL * (tm->tm_mday-1); + t += 3600LL * tm->tm_hour; + t += 60LL * tm->tm_min; + t += tm->tm_sec; + return t; +} + +static int __secs_to_tm(long long t, struct tm *tm) +{ + long long days, secs; + int remdays, remsecs, remyears; + int qc_cycles, c_cycles, q_cycles; + int years, months; + int wday, yday, leap; + static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29}; + + /* Reject time_t values whose year would overflow int */ + if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL) + return -1; + + secs = t - LEAPOCH; + days = secs / 86400; + remsecs = secs % 86400; + if (remsecs < 0) { + remsecs += 86400; + days--; + } + + wday = (3+days)%7; + if (wday < 0) wday += 7; + + qc_cycles = days / DAYS_PER_400Y; + remdays = days % DAYS_PER_400Y; + if (remdays < 0) { + remdays += DAYS_PER_400Y; + qc_cycles--; + } + + c_cycles = remdays / DAYS_PER_100Y; + if (c_cycles == 4) c_cycles--; + remdays -= c_cycles * DAYS_PER_100Y; + + q_cycles = remdays / DAYS_PER_4Y; + if (q_cycles == 25) q_cycles--; + remdays -= q_cycles * DAYS_PER_4Y; + + remyears = remdays / 365; + if (remyears == 4) remyears--; + remdays -= remyears * 365; + + leap = !remyears && (q_cycles || !c_cycles); + yday = remdays + 31 + 28 + leap; + if (yday >= 365+leap) yday -= 365+leap; + + years = remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles; + + for (months=0; days_in_month[months] <= remdays; months++) + remdays -= days_in_month[months]; + + if (years+100 > INT_MAX || years+100 < INT_MIN) + return -1; + + tm->tm_year = years + 100; + tm->tm_mon = months + 2; + if (tm->tm_mon >= 12) { + tm->tm_mon -=12; + tm->tm_year++; + } + tm->tm_mday = remdays + 1; + tm->tm_wday = wday; + tm->tm_yday = yday; + + tm->tm_hour = remsecs / 3600; + tm->tm_min = remsecs / 60 % 60; + tm->tm_sec = remsecs % 60; + + return 0; +} + +#ifdef _WIN32 +struct tm *__gmtime_r(const time_t *t, struct tm *tm) +{ + if (__secs_to_tm(*t, tm) < 0) { + errno = EOVERFLOW; + return 0; + } + tm->tm_isdst = 0; + return tm; +} +#endif + +time_t timegm(struct tm *tm) +{ + struct tm new; + long long t = __tm_to_secs(tm); + if (__secs_to_tm(t, &new) < 0) { + errno = EOVERFLOW; + return -1; + } +#if SIZEOF_TIME_T != 8 + if (t > (long long)INT_MAX || t < (long long)INT_MIN) { + errno = EOVERFLOW; + return -1; + } +#endif + *tm = new; + tm->tm_isdst = 0; + return t; +} diff --git a/Libraries/libressl/crypto/compat/timingsafe_bcmp.c b/Libraries/libressl/crypto/compat/timingsafe_bcmp.c new file mode 100644 index 000000000..552e844e7 --- /dev/null +++ b/Libraries/libressl/crypto/compat/timingsafe_bcmp.c @@ -0,0 +1,29 @@ +/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */ +/* + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ + const unsigned char *p1 = b1, *p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); +} diff --git a/Libraries/libressl/crypto/compat/timingsafe_memcmp.c b/Libraries/libressl/crypto/compat/timingsafe_memcmp.c new file mode 100644 index 000000000..bb210a384 --- /dev/null +++ b/Libraries/libressl/crypto/compat/timingsafe_memcmp.c @@ -0,0 +1,46 @@ +/* $OpenBSD: timingsafe_memcmp.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */ +/* + * Copyright (c) 2014 Google Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +int +timingsafe_memcmp(const void *b1, const void *b2, size_t len) +{ + const unsigned char *p1 = b1, *p2 = b2; + size_t i; + int res = 0, done = 0; + + for (i = 0; i < len; i++) { + /* lt is -1 if p1[i] < p2[i]; else 0. */ + int lt = (p1[i] - p2[i]) >> CHAR_BIT; + + /* gt is -1 if p1[i] > p2[i]; else 0. */ + int gt = (p2[i] - p1[i]) >> CHAR_BIT; + + /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */ + int cmp = lt - gt; + + /* set res = cmp if !done. */ + res |= cmp & ~done; + + /* set done if p1[i] != p2[i]. */ + done |= lt | gt; + } + + return (res); +} diff --git a/Libraries/libressl/crypto/conf/conf_api.c b/Libraries/libressl/crypto/conf/conf_api.c new file mode 100644 index 000000000..6fe071e12 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_api.c @@ -0,0 +1,286 @@ +/* $OpenBSD: conf_api.c,v 1.16 2023/07/08 08:26:26 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#ifndef CONF_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include +#include +#include + +static void value_free_hash_doall_arg(CONF_VALUE *a, + LHASH_OF(CONF_VALUE) *conf); +static void value_free_stack_doall(CONF_VALUE *a); +static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, + LHASH_OF(CONF_VALUE)) +static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) + +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE * +_CONF_get_section(const CONF *conf, const char *section) +{ + CONF_VALUE *v, vv; + + if ((conf == NULL) || (section == NULL)) + return (NULL); + vv.name = NULL; + vv.section = (char *)section; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + return (v); +} +LCRYPTO_ALIAS(_CONF_get_section); + +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) * +_CONF_get_section_values(const CONF *conf, const char *section) +{ + CONF_VALUE *v; + + v = _CONF_get_section(conf, section); + if (v != NULL) + return ((STACK_OF(CONF_VALUE) *)v->value); + else + return (NULL); +} +LCRYPTO_ALIAS(_CONF_get_section_values); + +int +_CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) +{ + CONF_VALUE *v = NULL; + STACK_OF(CONF_VALUE) *ts; + + ts = (STACK_OF(CONF_VALUE) *)section->value; + + value->section = section->section; + if (!sk_CONF_VALUE_push(ts, value)) { + return 0; + } + + v = lh_CONF_VALUE_insert(conf->data, value); + if (v != NULL) { + (void)sk_CONF_VALUE_delete_ptr(ts, v); + free(v->name); + free(v->value); + free(v); + } + return 1; +} +LCRYPTO_ALIAS(_CONF_add_string); + +char * +_CONF_get_string(const CONF *conf, const char *section, const char *name) +{ + CONF_VALUE *v, vv; + + if (name == NULL) + return (NULL); + if (conf != NULL) { + if (section != NULL) { + vv.name = (char *)name; + vv.section = (char *)section; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v != NULL) + return (v->value); + } + vv.section = "default"; + vv.name = (char *)name; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v != NULL) + return (v->value); + else + return (NULL); + } else + return (NULL); +} +LCRYPTO_ALIAS(_CONF_get_string); + +static unsigned long +conf_value_hash(const CONF_VALUE *v) +{ + return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); +} + +static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) + +static int +conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) +{ + int i; + + if (a->section != b->section) { + i = strcmp(a->section, b->section); + if (i) + return (i); + } + if ((a->name != NULL) && (b->name != NULL)) { + i = strcmp(a->name, b->name); + return (i); + } else if (a->name == b->name) + return (0); + else + return ((a->name == NULL)?-1 : 1); +} + +static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) + +int +_CONF_new_data(CONF *conf) +{ + if (conf == NULL) { + return 0; + } + if (conf->data == NULL) + if ((conf->data = lh_CONF_VALUE_new()) == NULL) { + return 0; + } + return 1; +} +LCRYPTO_ALIAS(_CONF_new_data); + +void +_CONF_free_data(CONF *conf) +{ + if (conf == NULL || conf->data == NULL) + return; + + lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make + * sure the 'free()' works as + * expected */ + lh_CONF_VALUE_doall_arg(conf->data, + LHASH_DOALL_ARG_FN(value_free_hash), + LHASH_OF(CONF_VALUE), conf->data); + + /* We now have only 'section' entries in the hash table. + * Due to problems with */ + + lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); + lh_CONF_VALUE_free(conf->data); +} +LCRYPTO_ALIAS(_CONF_free_data); + +static void +value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) +{ + if (a->name != NULL) + (void)lh_CONF_VALUE_delete(conf, a); +} + +static void +value_free_stack_doall(CONF_VALUE *a) +{ + CONF_VALUE *vv; + STACK_OF(CONF_VALUE) *sk; + int i; + + if (a->name != NULL) + return; + + sk = (STACK_OF(CONF_VALUE) *)a->value; + for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { + vv = sk_CONF_VALUE_value(sk, i); + free(vv->value); + free(vv->name); + free(vv); + } + if (sk != NULL) + sk_CONF_VALUE_free(sk); + free(a->section); + free(a); +} + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE * +_CONF_new_section(CONF *conf, const char *section) +{ + STACK_OF(CONF_VALUE) *sk = NULL; + int ok = 0, i; + CONF_VALUE *v = NULL, *vv; + + if ((sk = sk_CONF_VALUE_new_null()) == NULL) + goto err; + if ((v = malloc(sizeof(CONF_VALUE))) == NULL) + goto err; + i = strlen(section) + 1; + if ((v->section = malloc(i)) == NULL) + goto err; + + memcpy(v->section, section, i); + v->name = NULL; + v->value = (char *)sk; + + vv = lh_CONF_VALUE_insert(conf->data, v); + OPENSSL_assert(vv == NULL); + ok = 1; + +err: + if (!ok) { + if (sk != NULL) + sk_CONF_VALUE_free(sk); + free(v); + v = NULL; + } + return (v); +} +LCRYPTO_ALIAS(_CONF_new_section); diff --git a/Libraries/libressl/crypto/conf/conf_def.c b/Libraries/libressl/crypto/conf/conf_def.c new file mode 100644 index 000000000..f2b2c9477 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_def.c @@ -0,0 +1,698 @@ +/* $OpenBSD: conf_def.c,v 1.33 2020/02/17 12:51:48 inoguchi Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "conf_def.h" + +#define MAX_CONF_VALUE_LENGTH 65536 + +static char *eat_ws(CONF *conf, char *p); +static char *eat_alpha_numeric(CONF *conf, char *p); +static void clear_comments(CONF *conf, char *p); +static int str_copy(CONF *conf, char *section, char **to, char *from); +static char *scan_quote(CONF *conf, char *p); +static char *scan_dquote(CONF *conf, char *p); +#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) + +static CONF *def_create(CONF_METHOD *meth); +static int def_init_default(CONF *conf); +static int def_init_WIN32(CONF *conf); +static int def_destroy(CONF *conf); +static int def_destroy_data(CONF *conf); +static int def_load(CONF *conf, const char *name, long *eline); +static int def_load_bio(CONF *conf, BIO *bp, long *eline); +static int def_dump(const CONF *conf, BIO *bp); +static int def_is_number(const CONF *conf, char c); +static int def_to_int(const CONF *conf, char c); + +static CONF_METHOD default_method = { + .name = "OpenSSL default", + .create = def_create, + .init = def_init_default, + .destroy = def_destroy, + .destroy_data = def_destroy_data, + .load_bio = def_load_bio, + .dump = def_dump, + .is_number = def_is_number, + .to_int = def_to_int, + .load = def_load +}; + +static CONF_METHOD WIN32_method = { + "WIN32", + def_create, + def_init_WIN32, + def_destroy, + def_destroy_data, + def_load_bio, + def_dump, + def_is_number, + def_to_int, + def_load +}; + +CONF_METHOD * +NCONF_default(void) +{ + return &default_method; +} + +CONF_METHOD * +NCONF_WIN32(void) +{ + return &WIN32_method; +} + +static CONF * +def_create(CONF_METHOD *meth) +{ + CONF *ret; + + ret = malloc(sizeof(CONF) + sizeof(unsigned short *)); + if (ret) + if (meth->init(ret) == 0) { + free(ret); + ret = NULL; + } + return ret; +} + +static int +def_init_default(CONF *conf) +{ + if (conf == NULL) + return 0; + + conf->meth = &default_method; + conf->meth_data = CONF_type_default; + conf->data = NULL; + + return 1; +} + +static int +def_init_WIN32(CONF *conf) +{ + if (conf == NULL) + return 0; + + conf->meth = &WIN32_method; + conf->meth_data = (void *)CONF_type_win32; + conf->data = NULL; + + return 1; +} + +static int +def_destroy(CONF *conf) +{ + if (def_destroy_data(conf)) { + free(conf); + return 1; + } + return 0; +} + +static int +def_destroy_data(CONF *conf) +{ + if (conf == NULL) + return 0; + _CONF_free_data(conf); + return 1; +} + +static int +def_load(CONF *conf, const char *name, long *line) +{ + int ret; + BIO *in = NULL; + + in = BIO_new_file(name, "rb"); + if (in == NULL) { + if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) + CONFerror(CONF_R_NO_SUCH_FILE); + else + CONFerror(ERR_R_SYS_LIB); + return 0; + } + + ret = def_load_bio(conf, in, line); + BIO_free(in); + + return ret; +} + +static int +def_load_bio(CONF *conf, BIO *in, long *line) +{ +/* The macro BUFSIZE conflicts with a system macro in VxWorks */ +#define CONFBUFSIZE 512 + int bufnum = 0, i, ii; + BUF_MEM *buff = NULL; + char *s, *p, *end; + int again; + long eline = 0; + CONF_VALUE *v = NULL, *tv; + CONF_VALUE *sv = NULL; + char *section = NULL, *buf; + char *start, *psection, *pname; + void *h = (void *)(conf->data); + + if ((buff = BUF_MEM_new()) == NULL) { + CONFerror(ERR_R_BUF_LIB); + goto err; + } + + section = strdup("default"); + if (section == NULL) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (_CONF_new_data(conf) == 0) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + sv = _CONF_new_section(conf, section); + if (sv == NULL) { + CONFerror(CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + + bufnum = 0; + again = 0; + for (;;) { + if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { + CONFerror(ERR_R_BUF_LIB); + goto err; + } + p = &(buff->data[bufnum]); + *p = '\0'; + BIO_gets(in, p, CONFBUFSIZE - 1); + p[CONFBUFSIZE - 1] = '\0'; + ii = i = strlen(p); + if (i == 0 && !again) + break; + again = 0; + while (i > 0) { + if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) + break; + else + i--; + } + /* we removed some trailing stuff so there is a new + * line on the end. */ + if (ii && i == ii) + again = 1; /* long line */ + else { + p[i] = '\0'; + eline++; /* another input line */ + } + + /* we now have a line with trailing \r\n removed */ + + /* i is the number of bytes */ + bufnum += i; + + v = NULL; + /* check for line continuation */ + if (bufnum >= 1) { + /* If we have bytes and the last char '\\' and + * second last char is not '\\' */ + p = &(buff->data[bufnum - 1]); + if (IS_ESC(conf, p[0]) && + ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { + bufnum--; + again = 1; + } + } + if (again) + continue; + bufnum = 0; + buf = buff->data; + + clear_comments(conf, buf); + s = eat_ws(conf, buf); + if (IS_EOF(conf, *s)) + continue; /* blank line */ + if (*s == '[') { + char *ss; + + s++; + start = eat_ws(conf, s); + ss = start; +again: + end = eat_alpha_numeric(conf, ss); + p = eat_ws(conf, end); + if (*p != ']') { + if (*p != '\0' && ss != p) { + ss = p; + goto again; + } + CONFerror(CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end = '\0'; + if (!str_copy(conf, NULL, §ion, start)) + goto err; + if ((sv = _CONF_get_section(conf, section)) == NULL) + sv = _CONF_new_section(conf, section); + if (sv == NULL) { + CONFerror(CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + continue; + } else { + pname = s; + psection = NULL; + end = eat_alpha_numeric(conf, s); + if ((end[0] == ':') && (end[1] == ':')) { + *end = '\0'; + end += 2; + psection = pname; + pname = end; + end = eat_alpha_numeric(conf, end); + } + p = eat_ws(conf, end); + if (*p != '=') { + CONFerror(CONF_R_MISSING_EQUAL_SIGN); + goto err; + } + *end = '\0'; + p++; + start = eat_ws(conf, p); + while (!IS_EOF(conf, *p)) + p++; + p--; + while ((p != start) && (IS_WS(conf, *p))) + p--; + p++; + *p = '\0'; + + if (!(v = malloc(sizeof(CONF_VALUE)))) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (psection == NULL) + psection = section; + v->name = strdup(pname); + v->value = NULL; + if (v->name == NULL) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!str_copy(conf, psection, &(v->value), start)) + goto err; + + if (strcmp(psection, section) != 0) { + if ((tv = _CONF_get_section(conf, psection)) + == NULL) + tv = _CONF_new_section(conf, psection); + if (tv == NULL) { + CONFerror(CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + } else + tv = sv; + + if (_CONF_add_string(conf, tv, v) == 0) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + v = NULL; + } + } + if (buff != NULL) + BUF_MEM_free(buff); + free(section); + return (1); + +err: + if (buff != NULL) + BUF_MEM_free(buff); + free(section); + if (line != NULL) + *line = eline; + ERR_asprintf_error_data("line %ld", eline); + if ((h != conf->data) && (conf->data != NULL)) { + CONF_free(conf->data); + conf->data = NULL; + } + if (v != NULL) { + free(v->name); + free(v->value); + free(v); + } + return (0); +} + +static void +clear_comments(CONF *conf, char *p) +{ + for (;;) { + if (IS_FCOMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (!IS_WS(conf, *p)) { + break; + } + p++; + } + + for (;;) { + if (IS_COMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (IS_DQUOTE(conf, *p)) { + p = scan_dquote(conf, p); + continue; + } + if (IS_QUOTE(conf, *p)) { + p = scan_quote(conf, p); + continue; + } + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (IS_EOF(conf, *p)) + return; + else + p++; + } +} + +static int +str_copy(CONF *conf, char *section, char **pto, char *from) +{ + int q, r,rr = 0, to = 0, len = 0; + char *s, *e, *rp, *p, *rrp, *np, *cp, v; + size_t newsize; + BUF_MEM *buf; + + if ((buf = BUF_MEM_new()) == NULL) + return (0); + + len = strlen(from) + 1; + if (!BUF_MEM_grow(buf, len)) + goto err; + + for (;;) { + if (IS_QUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from) && (*from != q)) { + if (IS_ESC(conf, *from)) { + from++; + if (IS_EOF(conf, *from)) + break; + } + buf->data[to++] = *(from++); + } + if (*from == q) + from++; + } else if (IS_DQUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from)) { + if (*from == q) { + if (*(from + 1) == q) { + from++; + } else { + break; + } + } + buf->data[to++] = *(from++); + } + if (*from == q) + from++; + } else if (IS_ESC(conf, *from)) { + from++; + v = *(from++); + if (IS_EOF(conf, v)) + break; + else if (v == 'r') + v = '\r'; + else if (v == 'n') + v = '\n'; + else if (v == 'b') + v = '\b'; + else if (v == 't') + v = '\t'; + buf->data[to++] = v; + } else if (IS_EOF(conf, *from)) + break; + else if (*from == '$') { + /* try to expand it */ + rrp = NULL; + s = &(from[1]); + if (*s == '{') + q = '}'; + else if (*s == '(') + q = ')'; + else + q = 0; + + if (q) + s++; + cp = section; + e = np = s; + while (IS_ALPHA_NUMERIC(conf, *e)) + e++; + if ((e[0] == ':') && (e[1] == ':')) { + cp = np; + rrp = e; + rr = *e; + *rrp = '\0'; + e += 2; + np = e; + while (IS_ALPHA_NUMERIC(conf, *e)) + e++; + } + r = *e; + *e = '\0'; + rp = e; + if (q) { + if (r != q) { + CONFerror(CONF_R_NO_CLOSE_BRACE); + goto err; + } + e++; + } + /* So at this point we have + * np which is the start of the name string which is + * '\0' terminated. + * cp which is the start of the section string which is + * '\0' terminated. + * e is the 'next point after'. + * r and rr are the chars replaced by the '\0' + * rp and rrp is where 'r' and 'rr' came from. + */ + p = _CONF_get_string(conf, cp, np); + if (rrp != NULL) + *rrp = rr; + *rp = r; + if (p == NULL) { + CONFerror(CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + newsize = strlen(p) + buf->length - (e - from); + if (newsize > MAX_CONF_VALUE_LENGTH) { + CONFerror(CONF_R_VARIABLE_EXPANSION_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean(buf, newsize)) { + CONFerror(CONF_R_MODULE_INITIALIZATION_ERROR); + goto err; + } + while (*p) + buf->data[to++] = *(p++); + + /* Since we change the pointer 'from', we also have + to change the perceived length of the string it + points at. /RL */ + len -= e - from; + from = e; + + /* In case there were no braces or parenthesis around + the variable reference, we have to put back the + character that was replaced with a '\0'. /RL */ + *rp = r; + } else + buf->data[to++] = *(from++); + } + buf->data[to]='\0'; + free(*pto); + *pto = buf->data; + free(buf); + return (1); + +err: + if (buf != NULL) + BUF_MEM_free(buf); + return (0); +} + +static char * +eat_ws(CONF *conf, char *p) +{ + while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) + p++; + return (p); +} + +static char * +eat_alpha_numeric(CONF *conf, char *p) +{ + for (;;) { + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) + return (p); + p++; + } +} + +static char * +scan_quote(CONF *conf, char *p) +{ + int q = *p; + + p++; + while (!(IS_EOF(conf, *p)) && (*p != q)) { + if (IS_ESC(conf, *p)) { + p++; + if (IS_EOF(conf, *p)) + return (p); + } + p++; + } + if (*p == q) + p++; + return (p); +} + + +static char * +scan_dquote(CONF *conf, char *p) +{ + int q = *p; + + p++; + while (!(IS_EOF(conf, *p))) { + if (*p == q) { + if (*(p + 1) == q) { + p++; + } else { + break; + } + } + p++; + } + if (*p == q) + p++; + return (p); +} + +static void +dump_value_doall_arg(CONF_VALUE *a, BIO *out) +{ + if (a->name) + BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); + else + BIO_printf(out, "[[%s]]\n", a->section); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) + +static int +def_dump(const CONF *conf, BIO *out) +{ + lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), + BIO, out); + return 1; +} + +static int +def_is_number(const CONF *conf, char c) +{ + return IS_NUMBER(conf, c); +} + +static int +def_to_int(const CONF *conf, char c) +{ + return c - '0'; +} diff --git a/Libraries/libressl/crypto/conf/conf_def.h b/Libraries/libressl/crypto/conf/conf_def.h new file mode 100644 index 000000000..956e44337 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_def.h @@ -0,0 +1,166 @@ +/* $OpenBSD: conf_def.h,v 1.6 2016/12/21 15:49:29 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* THIS FILE WAS AUTOMAGICALLY GENERATED! + Please modify and use keysets.pl to regenerate it. */ + +__BEGIN_HIDDEN_DECLS + +#define CONF_NUMBER 1 +#define CONF_UPPER 2 +#define CONF_LOWER 4 +#define CONF_UNDER 256 +#define CONF_PUNCTUATION 512 +#define CONF_WS 16 +#define CONF_ESC 32 +#define CONF_QUOTE 64 +#define CONF_DQUOTE 1024 +#define CONF_COMMENT 128 +#define CONF_FCOMMENT 2048 +#define CONF_EOF 8 +#define CONF_HIGHBIT 4096 +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ + CONF_PUNCTUATION) + +#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) +#define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +#define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +#define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +#define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +#define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +#define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +#define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +#define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +#define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) + +static unsigned short CONF_type_default[256] = { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040, + 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, + 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100, + 0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; + +static unsigned short CONF_type_win32[256] = { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000, + 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, + 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100, + 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/conf/conf_err.c b/Libraries/libressl/crypto/conf/conf_err.c new file mode 100644 index 000000000..e6c707ab3 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_err.c @@ -0,0 +1,105 @@ +/* $OpenBSD: conf_err.c,v 1.15 2022/07/12 14:42:48 kn Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason) + +static ERR_STRING_DATA CONF_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA CONF_str_reasons[]= { + {ERR_REASON(CONF_R_ERROR_LOADING_DSO) , "error loading dso"}, + {ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL) , "list cannot be null"}, + {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET), "missing close square bracket"}, + {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN) , "missing equal sign"}, + {ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION), "missing finish function"}, + {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"}, + {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR), "module initialization error"}, + {ERR_REASON(CONF_R_NO_CLOSE_BRACE) , "no close brace"}, + {ERR_REASON(CONF_R_NO_CONF) , "no conf"}, + {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE), "no conf or environment variable"}, + {ERR_REASON(CONF_R_NO_SECTION) , "no section"}, + {ERR_REASON(CONF_R_NO_SUCH_FILE) , "no such file"}, + {ERR_REASON(CONF_R_NO_VALUE) , "no value"}, + {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION), "unable to create new section"}, + {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME) , "unknown module name"}, + {ERR_REASON(CONF_R_VARIABLE_EXPANSION_TOO_LONG), "variable expansion too long"}, + {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"}, + {0, NULL} +}; + +#endif + +void +ERR_load_CONF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) { + ERR_load_strings(0, CONF_str_functs); + ERR_load_strings(0, CONF_str_reasons); + } +#endif +} diff --git a/Libraries/libressl/crypto/conf/conf_lib.c b/Libraries/libressl/crypto/conf/conf_lib.c new file mode 100644 index 000000000..995ba3ef6 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_lib.c @@ -0,0 +1,375 @@ +/* $OpenBSD: conf_lib.c,v 1.15 2017/01/29 17:49:22 beck Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +static CONF_METHOD *default_CONF_method = NULL; + +/* Init a 'CONF' structure from an old LHASH */ + +void +CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) +{ + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + default_CONF_method->init(conf); + conf->data = hash; +} + +/* The following section contains the "CONF classic" functions, + rewritten in terms of the new CONF interface. */ + +int +CONF_set_default_method(CONF_METHOD *meth) +{ + default_CONF_method = meth; + return 1; +} + +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline) +{ + LHASH_OF(CONF_VALUE) *ltmp; + BIO *in = NULL; + + in = BIO_new_file(file, "rb"); + if (in == NULL) { + CONFerror(ERR_R_SYS_LIB); + return NULL; + } + + ltmp = CONF_load_bio(conf, in, eline); + BIO_free(in); + + return ltmp; +} + +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline) +{ + BIO *btmp; + LHASH_OF(CONF_VALUE) *ltmp; + + if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerror(ERR_R_BUF_LIB); + return NULL; + } + ltmp = CONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ltmp; +} + +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline) +{ + CONF ctmp; + int ret; + + CONF_set_nconf(&ctmp, conf); + + ret = NCONF_load_bio(&ctmp, bp, eline); + if (ret) + return ctmp.data; + return NULL; +} + +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section) +{ + if (conf == NULL) { + return NULL; + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_get_section(&ctmp, section); + } +} + +char * +CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name) +{ + if (conf == NULL) { + return NCONF_get_string(NULL, group, name); + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_get_string(&ctmp, group, name); + } +} + +long +CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name) +{ + int status; + long result = 0; + + if (conf == NULL) { + status = NCONF_get_number_e(NULL, group, name, &result); + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + status = NCONF_get_number_e(&ctmp, group, name, &result); + } + + if (status == 0) { + /* This function does not believe in errors... */ + ERR_clear_error(); + } + return result; +} + +void +CONF_free(LHASH_OF(CONF_VALUE) *conf) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + NCONF_free_data(&ctmp); +} + +int +CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) +{ + BIO *btmp; + int ret; + + if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerror(ERR_R_BUF_LIB); + return 0; + } + ret = CONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; +} + +int +CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return NCONF_dump_bio(&ctmp, out); +} + +/* The following section contains the "New CONF" functions. They are + completely centralised around a new CONF structure that may contain + basically anything, but at least a method pointer and a table of data. + These functions are also written in terms of the bridge functions used + by the "CONF classic" functions, for consistency. */ + +CONF * +NCONF_new(CONF_METHOD *meth) +{ + CONF *ret; + + if (meth == NULL) + meth = NCONF_default(); + + ret = meth->create(meth); + if (ret == NULL) { + CONFerror(ERR_R_MALLOC_FAILURE); + return (NULL); + } + + return ret; +} + +void +NCONF_free(CONF *conf) +{ + if (conf == NULL) + return; + conf->meth->destroy(conf); +} + +void +NCONF_free_data(CONF *conf) +{ + if (conf == NULL) + return; + conf->meth->destroy_data(conf); +} + +int +NCONF_load(CONF *conf, const char *file, long *eline) +{ + if (conf == NULL) { + CONFerror(CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load(conf, file, eline); +} + +int +NCONF_load_fp(CONF *conf, FILE *fp, long *eline) +{ + BIO *btmp; + int ret; + + if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerror(ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ret; +} + +int +NCONF_load_bio(CONF *conf, BIO *bp, long *eline) +{ + if (conf == NULL) { + CONFerror(CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load_bio(conf, bp, eline); +} + +STACK_OF(CONF_VALUE) * +NCONF_get_section(const CONF *conf, const char *section) +{ + if (conf == NULL) { + CONFerror(CONF_R_NO_CONF); + return NULL; + } + + if (section == NULL) { + CONFerror(CONF_R_NO_SECTION); + return NULL; + } + + return _CONF_get_section_values(conf, section); +} + +char * +NCONF_get_string(const CONF *conf, const char *group, const char *name) +{ + char *s = _CONF_get_string(conf, group, name); + + /* Since we may get a value from an environment variable even + if conf is NULL, let's check the value first */ + if (s) + return s; + + if (conf == NULL) { + CONFerror(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); + return NULL; + } + CONFerror(CONF_R_NO_VALUE); + ERR_asprintf_error_data("group=%s name=%s", + group ? group : "", name); + return NULL; +} + +int +NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result) +{ + char *str; + + if (result == NULL) { + CONFerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + str = NCONF_get_string(conf, group, name); + + if (str == NULL) + return 0; + + for (*result = 0; conf->meth->is_number(conf, *str); ) { + *result = (*result) * 10 + conf->meth->to_int(conf, *str); + str++; + } + + return 1; +} + +int +NCONF_dump_fp(const CONF *conf, FILE *out) +{ + BIO *btmp; + int ret; + if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerror(ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; +} + +int +NCONF_dump_bio(const CONF *conf, BIO *out) +{ + if (conf == NULL) { + CONFerror(CONF_R_NO_CONF); + return 0; + } + + return conf->meth->dump(conf, out); +} diff --git a/Libraries/libressl/crypto/conf/conf_mall.c b/Libraries/libressl/crypto/conf/conf_mall.c new file mode 100644 index 000000000..18631b3ba --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_mall.c @@ -0,0 +1,82 @@ +/* $OpenBSD: conf_mall.c,v 1.9 2014/07/11 08:44:48 jsing Exp $ */ +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +/* Load all OpenSSL builtin modules */ + +void +OPENSSL_load_builtin_modules(void) +{ + /* Add builtin modules here */ + ASN1_add_oid_module(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_add_conf_module(); +#endif +} diff --git a/Libraries/libressl/crypto/conf/conf_mod.c b/Libraries/libressl/crypto/conf/conf_mod.c new file mode 100644 index 000000000..aab108a26 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_mod.c @@ -0,0 +1,527 @@ +/* $OpenBSD: conf_mod.c,v 1.28 2023/07/20 15:05:30 tb Exp $ */ +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* This structure contains data about supported modules. */ +struct conf_module_st { + /* Name of the module */ + char *name; + /* Init function */ + conf_init_func *init; + /* Finish function */ + conf_finish_func *finish; + /* Number of successfully initialized modules */ + int links; + void *usr_data; +}; + + +/* This structure contains information about modules that have been + * successfully initialized. There may be more than one entry for a + * given module. + */ + +struct conf_imodule_st { + CONF_MODULE *pmod; + char *name; + char *value; + unsigned long flags; + void *usr_data; +}; + +static STACK_OF(CONF_MODULE) *supported_modules = NULL; +static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; + +static void module_free(CONF_MODULE *md); +static void module_finish(CONF_IMODULE *imod); +static int module_run(const CONF *cnf, char *name, char *value, + unsigned long flags); +static CONF_MODULE *module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); +static CONF_MODULE *module_find(char *name); +static int module_init(CONF_MODULE *pmod, char *name, char *value, + const CONF *cnf); + +/* Main function: load modules from a CONF structure */ + +int +CONF_modules_load(const CONF *cnf, const char *appname, unsigned long flags) +{ + STACK_OF(CONF_VALUE) *values; + CONF_VALUE *vl; + char *vsection = NULL; + + int ret, i; + + if (!cnf) + return 1; + + if (appname) + vsection = NCONF_get_string(cnf, NULL, appname); + + if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION))) + vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); + + if (!vsection) { + ERR_clear_error(); + return 1; + } + + values = NCONF_get_section(cnf, vsection); + + if (!values) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + vl = sk_CONF_VALUE_value(values, i); + ret = module_run(cnf, vl->name, vl->value, flags); + if (ret <= 0) + if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) + return ret; + } + + return 1; +} + +int +CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags) +{ + char *file = NULL; + CONF *conf = NULL; + int ret = 0; + conf = NCONF_new(NULL); + if (!conf) + goto err; + + if (filename == NULL) { + file = CONF_get1_default_config_file(); + if (!file) + goto err; + } else + file = (char *)filename; + + if (NCONF_load(conf, file, NULL) <= 0) { + if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && + (ERR_GET_REASON(ERR_peek_last_error()) == + CONF_R_NO_SUCH_FILE)) { + ERR_clear_error(); + ret = 1; + } + goto err; + } + + ret = CONF_modules_load(conf, appname, flags); + +err: + if (filename == NULL) + free(file); + NCONF_free(conf); + + return ret; +} + +static int +module_run(const CONF *cnf, char *name, char *value, unsigned long flags) +{ + CONF_MODULE *md; + int ret; + + if ((md = module_find(name)) == NULL) { + if (!(flags & CONF_MFLAGS_SILENT)) { + CONFerror(CONF_R_UNKNOWN_MODULE_NAME); + ERR_asprintf_error_data("module=%s", name); + } + return -1; + } + + ret = module_init(md, name, value, cnf); + + if (ret <= 0) { + if (!(flags & CONF_MFLAGS_SILENT)) { + CONFerror(CONF_R_MODULE_INITIALIZATION_ERROR); + ERR_asprintf_error_data + ("module=%s, value=%s, retcode=%-8d", + name, value, ret); + } + } + + return ret; +} + +/* add module to list */ +static CONF_MODULE * +module_add(const char *name, conf_init_func *ifunc, conf_finish_func *ffunc) +{ + CONF_MODULE *tmod = NULL; + + if (name == NULL) + return NULL; + if (supported_modules == NULL) + supported_modules = sk_CONF_MODULE_new_null(); + if (supported_modules == NULL) + return NULL; + tmod = malloc(sizeof(CONF_MODULE)); + if (tmod == NULL) + return NULL; + + tmod->name = strdup(name); + tmod->init = ifunc; + tmod->finish = ffunc; + tmod->links = 0; + + if (!sk_CONF_MODULE_push(supported_modules, tmod)) { + free(tmod); + return NULL; + } + + return tmod; +} + +/* Find a module from the list. We allow module names of the + * form modname.XXXX to just search for modname to allow the + * same module to be initialized more than once. + */ + +static CONF_MODULE * +module_find(char *name) +{ + CONF_MODULE *tmod; + int i, nchar; + char *p; + + p = strrchr(name, '.'); + + if (p) + nchar = p - name; + else + nchar = strlen(name); + + for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) { + tmod = sk_CONF_MODULE_value(supported_modules, i); + if (!strncmp(tmod->name, name, nchar)) + return tmod; + } + + return NULL; +} + +/* initialize a module */ +static int +module_init(CONF_MODULE *pmod, char *name, char *value, const CONF *cnf) +{ + int ret = 1; + int init_called = 0; + CONF_IMODULE *imod = NULL; + + /* Otherwise add initialized module to list */ + imod = malloc(sizeof(CONF_IMODULE)); + if (!imod) + goto err; + + imod->pmod = pmod; + imod->name = name ? strdup(name) : NULL; + imod->value = value ? strdup(value) : NULL; + imod->usr_data = NULL; + + if (!imod->name || !imod->value) + goto memerr; + + /* Try to initialize module */ + if (pmod->init) { + ret = pmod->init(imod, cnf); + init_called = 1; + /* Error occurred, exit */ + if (ret <= 0) + goto err; + } + + if (initialized_modules == NULL) { + initialized_modules = sk_CONF_IMODULE_new_null(); + if (!initialized_modules) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!sk_CONF_IMODULE_push(initialized_modules, imod)) { + CONFerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + pmod->links++; + + return ret; + +err: + /* We've started the module so we'd better finish it */ + if (pmod->finish && init_called) + pmod->finish(imod); + +memerr: + if (imod) { + free(imod->name); + free(imod->value); + free(imod); + } + + return -1; +} + +/* Unload any dynamic modules that have a link count of zero: + * i.e. have no active initialized modules. If 'all' is set + * then all modules are unloaded including static ones. + */ + +void +CONF_modules_unload(int all) +{ + int i; + CONF_MODULE *md; + + CONF_modules_finish(); + + /* unload modules in reverse order */ + for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) { + md = sk_CONF_MODULE_value(supported_modules, i); + if (!all) + continue; + /* Since we're working in reverse this is OK */ + (void)sk_CONF_MODULE_delete(supported_modules, i); + module_free(md); + } + if (sk_CONF_MODULE_num(supported_modules) == 0) { + sk_CONF_MODULE_free(supported_modules); + supported_modules = NULL; + } +} + +/* unload a single module */ +static void +module_free(CONF_MODULE *md) +{ + free(md->name); + free(md); +} + +/* finish and free up all modules instances */ + +void +CONF_modules_finish(void) +{ + CONF_IMODULE *imod; + + while (sk_CONF_IMODULE_num(initialized_modules) > 0) { + imod = sk_CONF_IMODULE_pop(initialized_modules); + module_finish(imod); + } + sk_CONF_IMODULE_free(initialized_modules); + initialized_modules = NULL; +} + +/* finish a module instance */ + +static void +module_finish(CONF_IMODULE *imod) +{ + if (imod->pmod->finish) + imod->pmod->finish(imod); + imod->pmod->links--; + free(imod->name); + free(imod->value); + free(imod); +} + +/* Add a static module to OpenSSL */ + +int +CONF_module_add(const char *name, conf_init_func *ifunc, conf_finish_func *ffunc) +{ + return module_add(name, ifunc, ffunc) != NULL; +} + +void +CONF_modules_free(void) +{ + CONF_modules_finish(); + CONF_modules_unload(1); +} + +/* Utility functions */ + +const char * +CONF_imodule_get_name(const CONF_IMODULE *md) +{ + return md->name; +} + +const char * +CONF_imodule_get_value(const CONF_IMODULE *md) +{ + return md->value; +} + +void * +CONF_imodule_get_usr_data(const CONF_IMODULE *md) +{ + return md->usr_data; +} + +void +CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data) +{ + md->usr_data = usr_data; +} + +CONF_MODULE * +CONF_imodule_get_module(const CONF_IMODULE *md) +{ + return md->pmod; +} + +unsigned long +CONF_imodule_get_flags(const CONF_IMODULE *md) +{ + return md->flags; +} + +void +CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags) +{ + md->flags = flags; +} + +void * +CONF_module_get_usr_data(CONF_MODULE *pmod) +{ + return pmod->usr_data; +} + +void +CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) +{ + pmod->usr_data = usr_data; +} + +/* Return default config file name */ + +char * +CONF_get1_default_config_file(void) +{ + char *file = NULL; + + if (asprintf(&file, "%s/openssl.cnf", + X509_get_default_cert_area()) == -1) + return (NULL); + return file; +} + +/* This function takes a list separated by 'sep' and calls the + * callback function giving the start and length of each member + * optionally stripping leading and trailing whitespace. This can + * be used to parse comma separated lists for example. + */ + +int +CONF_parse_list(const char *list_, int sep, int nospc, + int (*list_cb)(const char *elem, int len, void *usr), void *arg) +{ + int ret; + const char *lstart, *tmpend, *p; + + if (list_ == NULL) { + CONFerror(CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list_; + for (;;) { + if (nospc) { + while (*lstart && isspace((unsigned char)*lstart)) + lstart++; + } + p = strchr(lstart, sep); + if (p == lstart || !*lstart) + ret = list_cb(NULL, 0, arg); + else { + if (p) + tmpend = p - 1; + else + tmpend = lstart + strlen(lstart) - 1; + if (nospc) { + while (isspace((unsigned char)*tmpend)) + tmpend--; + } + ret = list_cb(lstart, tmpend - lstart + 1, arg); + } + if (ret <= 0) + return ret; + if (p == NULL) + return 1; + lstart = p + 1; + } +} diff --git a/Libraries/libressl/crypto/conf/conf_sap.c b/Libraries/libressl/crypto/conf/conf_sap.c new file mode 100644 index 000000000..827cf96e7 --- /dev/null +++ b/Libraries/libressl/crypto/conf/conf_sap.c @@ -0,0 +1,154 @@ +/* $OpenBSD: conf_sap.c,v 1.14 2018/03/19 03:56:08 beck Exp $ */ +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +/* This is the automatic configuration loader: it is called automatically by + * OpenSSL when any of a number of standard initialisation functions are called, + * unless this is overridden by calling OPENSSL_no_config() + */ + +static pthread_once_t openssl_configured = PTHREAD_ONCE_INIT; + +static const char *openssl_config_name; + +static void +OPENSSL_config_internal(void) +{ + OPENSSL_load_builtin_modules(); +#ifndef OPENSSL_NO_ENGINE + /* Need to load ENGINEs */ + ENGINE_load_builtin_engines(); +#endif + /* Add others here? */ + + ERR_clear_error(); + if (CONF_modules_load_file(NULL, openssl_config_name, + CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) { + BIO *bio_err; + ERR_load_crypto_strings(); + if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) != NULL) { + BIO_printf(bio_err, "Auto configuration failed\n"); + ERR_print_errors(bio_err); + BIO_free(bio_err); + } + exit(1); + } + + return; +} + +int +OpenSSL_config(const char *config_name) +{ + /* Don't override if NULL */ + /* + * Note - multiple threads calling this with *different* config names + * is probably not advisable. One thread will win, but you don't know + * if it will be the same thread as wins the pthread_once. + */ + if (config_name != NULL) + openssl_config_name = config_name; + + if (OPENSSL_init_crypto(0, NULL) == 0) + return 0; + + if (pthread_once(&openssl_configured, OPENSSL_config_internal) != 0) + return 0; + + return 1; +} + +void +OPENSSL_config(const char *config_name) +{ + (void) OpenSSL_config(config_name); +} + +static void +OPENSSL_no_config_internal(void) +{ +} + +int +OpenSSL_no_config(void) +{ + if (pthread_once(&openssl_configured, OPENSSL_no_config_internal) != 0) + return 0; + + return 1; +} + +void +OPENSSL_no_config(void) +{ + (void) OpenSSL_no_config(); +} diff --git a/Libraries/libressl/crypto/constant_time.h b/Libraries/libressl/crypto/constant_time.h new file mode 100644 index 000000000..ea7dede9d --- /dev/null +++ b/Libraries/libressl/crypto/constant_time.h @@ -0,0 +1,207 @@ +/* $OpenBSD: constant_time.h,v 1.3 2023/04/06 18:43:47 tb Exp $ */ +/*- + * Utilities for constant-time cryptography. + * + * Author: Emilia Kasper (emilia@openssl.org) + * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley + * (Google). + * ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONSTANT_TIME_H +#define HEADER_CONSTANT_TIME_H + +__BEGIN_HIDDEN_DECLS + +/*- + * The boolean methods return a bitmask of all ones (0xff...f) for true + * and 0 for false. This is useful for choosing a value based on the result + * of a conditional in constant time. For example, + * + * if (a < b) { + * c = a; + * } else { + * c = b; + * } + * + * can be written as + * + * unsigned int lt = constant_time_lt(a, b); + * c = constant_time_select(lt, a, b); + */ + +/* + * Returns the given value with the MSB copied to all the other + * bits. Uses the fact that arithmetic shift shifts-in the sign bit. + * However, this is not ensured by the C standard so you may need to + * replace this with something else on odd CPUs. + */ +static inline unsigned int constant_time_msb(unsigned int a); + +/* + * Returns 0xff..f if a < b and 0 otherwise. + */ +static inline unsigned int constant_time_lt(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_lt_8(unsigned int a, + unsigned int b); + +/* + * Returns 0xff..f if a >= b and 0 otherwise. + */ +static inline unsigned int constant_time_ge(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_ge_8(unsigned int a, + unsigned int b); + +/* + * Returns 0xff..f if a == 0 and 0 otherwise. + */ +static inline unsigned int constant_time_is_zero(unsigned int a); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_is_zero_8(unsigned int a); + +/* + * Returns 0xff..f if a == b and 0 otherwise. + */ +static inline unsigned int constant_time_eq(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_eq_8(unsigned int a, + unsigned int b); +/* Signed integers. */ +static inline unsigned int constant_time_eq_int(int a, int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_eq_int_8(int a, int b); + +/*- + * Returns (mask & a) | (~mask & b). + * + * When |mask| is all 1s or all 0s (as returned by the methods above), + * the select methods return either |a| (if |mask| is nonzero) or |b| + * (if |mask| is zero). + */ +static inline unsigned int constant_time_select(unsigned int mask, + unsigned int a, + unsigned int b); +/* Convenience method for unsigned chars. */ +static inline unsigned char constant_time_select_8(unsigned char mask, + unsigned char a, + unsigned char b); +/* Convenience method for signed integers. */ +static inline int constant_time_select_int(unsigned int mask, int a, int b); + +static inline unsigned int constant_time_msb(unsigned int a) +{ + return 0 - (a >> (sizeof(a) * 8 - 1)); +} + +static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) +{ + return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); +} + +static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_lt(a, b)); +} + +static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) +{ + return ~constant_time_lt(a, b); +} + +static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_ge(a, b)); +} + +static inline unsigned int constant_time_is_zero(unsigned int a) +{ + return constant_time_msb(~a & (a - 1)); +} + +static inline unsigned char constant_time_is_zero_8(unsigned int a) +{ + return (unsigned char)(constant_time_is_zero(a)); +} + +static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) +{ + return constant_time_is_zero(a ^ b); +} + +static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_eq(a, b)); +} + +static inline unsigned int constant_time_eq_int(int a, int b) +{ + return constant_time_eq((unsigned)(a), (unsigned)(b)); +} + +static inline unsigned char constant_time_eq_int_8(int a, int b) +{ + return constant_time_eq_8((unsigned)(a), (unsigned)(b)); +} + +static inline unsigned int constant_time_select(unsigned int mask, + unsigned int a, + unsigned int b) +{ + return (mask & a) | (~mask & b); +} + +static inline unsigned char constant_time_select_8(unsigned char mask, + unsigned char a, + unsigned char b) +{ + return (unsigned char)(constant_time_select(mask, a, b)); +} + +static inline int constant_time_select_int(unsigned int mask, int a, int b) +{ + return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); +} + +void err_clear_last_constant_time(int clear); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_CONSTANT_TIME_H */ diff --git a/Libraries/libressl/crypto/cpt_err.c b/Libraries/libressl/crypto/cpt_err.c new file mode 100644 index 000000000..ff4e5c4bc --- /dev/null +++ b/Libraries/libressl/crypto/cpt_err.c @@ -0,0 +1,100 @@ +/* $OpenBSD: cpt_err.c,v 1.15 2023/07/08 08:28:23 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason) + +static ERR_STRING_DATA CRYPTO_str_functs[] = { + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID), "CRYPTO_get_new_dynlockid"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID), "CRYPTO_get_new_lockid"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"}, + {ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX), "DEF_ADD_INDEX"}, + {ERR_FUNC(CRYPTO_F_DEF_GET_CLASS), "DEF_GET_CLASS"}, + {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"}, + {ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"}, + {0, NULL} +}; + +static ERR_STRING_DATA CRYPTO_str_reasons[] = { + {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK), "no dynlock create callback"}, + {0, NULL} +}; + +#endif + +void +ERR_load_CRYPTO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) { + ERR_load_strings(0, CRYPTO_str_functs); + ERR_load_strings(0, CRYPTO_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_CRYPTO_strings); diff --git a/Libraries/libressl/crypto/cpuid-elf-x86_64.S b/Libraries/libressl/crypto/cpuid-elf-x86_64.S new file mode 100644 index 000000000..6dc8e58da --- /dev/null +++ b/Libraries/libressl/crypto/cpuid-elf-x86_64.S @@ -0,0 +1,141 @@ +#include "x86_arch.h" + +.hidden OPENSSL_cpuid_setup +.section .init + endbr64 + call OPENSSL_cpuid_setup + + +.hidden OPENSSL_ia32cap_P + +.text + +.globl OPENSSL_ia32_cpuid +.type OPENSSL_ia32_cpuid,@function +.align 16 +OPENSSL_ia32_cpuid: + endbr64 + movq %rbx,%r8 + + xorl %eax,%eax + cpuid + movl %eax,%r11d + + xorl %eax,%eax + cmpl $1970169159,%ebx + setne %al + movl %eax,%r9d + cmpl $1231384169,%edx + setne %al + orl %eax,%r9d + cmpl $1818588270,%ecx + setne %al + orl %eax,%r9d + jz .Lintel + + cmpl $1752462657,%ebx + setne %al + movl %eax,%r10d + cmpl $1769238117,%edx + setne %al + orl %eax,%r10d + cmpl $1145913699,%ecx + setne %al + orl %eax,%r10d + jnz .Lintel + + + movl $2147483648,%eax + cpuid + cmpl $2147483649,%eax + jb .Lintel + movl %eax,%r10d + movl $2147483649,%eax + cpuid + orl %ecx,%r9d + andl $IA32CAP_MASK1_AMD_XOP,%r9d + orl $1,%r9d + + cmpl $2147483656,%r10d + jb .Lintel + + movl $2147483656,%eax + cpuid + movzbq %cl,%r10 + incq %r10 + + movl $1,%eax + cpuid + btl $IA32CAP_BIT0_HT,%edx + jnc .Lgeneric + shrl $16,%ebx + cmpb %r10b,%bl + ja .Lgeneric + xorl $IA32CAP_MASK0_HT,%edx + jmp .Lgeneric + +.Lintel: + cmpl $4,%r11d + movl $-1,%r10d + jb .Lnocacheinfo + + movl $4,%eax + movl $0,%ecx + cpuid + movl %eax,%r10d + shrl $14,%r10d + andl $4095,%r10d + +.Lnocacheinfo: + movl $1,%eax + cpuid + + andl $(~(IA32CAP_MASK0_INTELP4 | IA32CAP_MASK0_INTEL)),%edx + cmpl $0,%r9d + jne .Lnotintel + + orl $IA32CAP_MASK0_INTEL,%edx + andb $15,%ah + cmpb $15,%ah + jne .Lnotintel + + orl $IA32CAP_MASK0_INTELP4,%edx +.Lnotintel: + btl $IA32CAP_BIT0_HT,%edx + jnc .Lgeneric + xorl $IA32CAP_MASK0_HT,%edx + cmpl $0,%r10d + je .Lgeneric + + orl $IA32CAP_MASK0_HT,%edx + shrl $16,%ebx + cmpb $1,%bl + ja .Lgeneric + xorl $IA32CAP_MASK0_HT,%edx + +.Lgeneric: + andl $IA32CAP_MASK1_AMD_XOP,%r9d + andl $(~IA32CAP_MASK1_AMD_XOP),%ecx + orl %ecx,%r9d + + movl %edx,%r10d + btl $IA32CAP_BIT1_OSXSAVE,%r9d + jnc .Lclear_avx + xorl %ecx,%ecx +.byte 0x0f,0x01,0xd0 + andl $6,%eax + cmpl $6,%eax + je .Ldone +.Lclear_avx: + movl $(~(IA32CAP_MASK1_AVX | IA32CAP_MASK1_FMA3 | IA32CAP_MASK1_AMD_XOP)),%eax + andl %eax,%r9d +.Ldone: + shlq $32,%r9 + movl %r10d,%eax + movq %r8,%rbx + orq %r9,%rax + retq +.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/cpuid-macosx-x86_64.S b/Libraries/libressl/crypto/cpuid-macosx-x86_64.S new file mode 100644 index 000000000..5d3f1a742 --- /dev/null +++ b/Libraries/libressl/crypto/cpuid-macosx-x86_64.S @@ -0,0 +1,137 @@ +#include "x86_arch.h" + +.private_extern _OPENSSL_cpuid_setup +.mod_init_func + .p2align 3 + .quad _OPENSSL_cpuid_setup + + +.private_extern _OPENSSL_ia32cap_P + +.text + +.globl _OPENSSL_ia32_cpuid + +.p2align 4 +_OPENSSL_ia32_cpuid: + movq %rbx,%r8 + + xorl %eax,%eax + cpuid + movl %eax,%r11d + + xorl %eax,%eax + cmpl $1970169159,%ebx + setne %al + movl %eax,%r9d + cmpl $1231384169,%edx + setne %al + orl %eax,%r9d + cmpl $1818588270,%ecx + setne %al + orl %eax,%r9d + jz L$intel + + cmpl $1752462657,%ebx + setne %al + movl %eax,%r10d + cmpl $1769238117,%edx + setne %al + orl %eax,%r10d + cmpl $1145913699,%ecx + setne %al + orl %eax,%r10d + jnz L$intel + + + movl $2147483648,%eax + cpuid + cmpl $2147483649,%eax + jb L$intel + movl %eax,%r10d + movl $2147483649,%eax + cpuid + orl %ecx,%r9d + andl $IA32CAP_MASK1_AMD_XOP,%r9d + orl $1,%r9d + + cmpl $2147483656,%r10d + jb L$intel + + movl $2147483656,%eax + cpuid + movzbq %cl,%r10 + incq %r10 + + movl $1,%eax + cpuid + btl $IA32CAP_BIT0_HT,%edx + jnc L$generic + shrl $16,%ebx + cmpb %r10b,%bl + ja L$generic + xorl $IA32CAP_MASK0_HT,%edx + jmp L$generic + +L$intel: + cmpl $4,%r11d + movl $-1,%r10d + jb L$nocacheinfo + + movl $4,%eax + movl $0,%ecx + cpuid + movl %eax,%r10d + shrl $14,%r10d + andl $4095,%r10d + +L$nocacheinfo: + movl $1,%eax + cpuid + + andl $(~(IA32CAP_MASK0_INTELP4 | IA32CAP_MASK0_INTEL)),%edx + cmpl $0,%r9d + jne L$notintel + + orl $IA32CAP_MASK0_INTEL,%edx + andb $15,%ah + cmpb $15,%ah + jne L$notintel + + orl $IA32CAP_MASK0_INTELP4,%edx +L$notintel: + btl $IA32CAP_BIT0_HT,%edx + jnc L$generic + xorl $IA32CAP_MASK0_HT,%edx + cmpl $0,%r10d + je L$generic + + orl $IA32CAP_MASK0_HT,%edx + shrl $16,%ebx + cmpb $1,%bl + ja L$generic + xorl $IA32CAP_MASK0_HT,%edx + +L$generic: + andl $IA32CAP_MASK1_AMD_XOP,%r9d + andl $(~IA32CAP_MASK1_AMD_XOP),%ecx + orl %ecx,%r9d + + movl %edx,%r10d + btl $IA32CAP_BIT1_OSXSAVE,%r9d + jnc L$clear_avx + xorl %ecx,%ecx +.byte 0x0f,0x01,0xd0 + andl $6,%eax + cmpl $6,%eax + je L$done +L$clear_avx: + movl $(~(IA32CAP_MASK1_AVX | IA32CAP_MASK1_FMA3 | IA32CAP_MASK1_AMD_XOP)),%eax + andl %eax,%r9d +L$done: + shlq $32,%r9 + movl %r10d,%eax + movq %r8,%rbx + orq %r9,%rax + retq + diff --git a/Libraries/libressl/crypto/cpuid-masm-x86_64.S b/Libraries/libressl/crypto/cpuid-masm-x86_64.S new file mode 100644 index 000000000..97dae0a65 --- /dev/null +++ b/Libraries/libressl/crypto/cpuid-masm-x86_64.S @@ -0,0 +1,209 @@ +; 1 "crypto/cpuid-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/cpuid-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/cpuid-masm-x86_64.S.tmp" 2 +EXTERN OPENSSL_cpuid_setup:NEAR + +.CRT$XCU SEGMENT READONLY ALIGN(8) + DQ OPENSSL_cpuid_setup + +EXTERN OPENSSL_ia32cap_P:NEAR + + +.CRT$XCU ENDS +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC OPENSSL_ia32_cpuid + +ALIGN 16 +OPENSSL_ia32_cpuid PROC PUBLIC + mov r8,rbx + + xor eax,eax + cpuid + mov r11d,eax + + xor eax,eax + cmp ebx,0756e6547h + setne al + mov r9d,eax + cmp edx,049656e69h + setne al + or r9d,eax + cmp ecx,06c65746eh + setne al + or r9d,eax + jz $L$intel + + cmp ebx,068747541h + setne al + mov r10d,eax + cmp edx,069746E65h + setne al + or r10d,eax + cmp ecx,0444D4163h + setne al + or r10d,eax + jnz $L$intel + + + mov eax,080000000h + cpuid + cmp eax,080000001h + jb $L$intel + mov r10d,eax + mov eax,080000001h + cpuid + or r9d,ecx + and r9d,(1 SHL 11) + or r9d,1 + + cmp r10d,080000008h + jb $L$intel + + mov eax,080000008h + cpuid + movzx r10,cl + inc r10 + + mov eax,1 + cpuid + bt edx,28 + jnc $L$generic + shr ebx,16 + cmp bl,r10b + ja $L$generic + xor edx,(1 SHL 28) + jmp $L$generic + +$L$intel:: + cmp r11d,4 + mov r10d,-1 + jb $L$nocacheinfo + + mov eax,4 + mov ecx,0 + cpuid + mov r10d,eax + shr r10d,14 + and r10d,0fffh + +$L$nocacheinfo:: + mov eax,1 + cpuid + + and edx,(NOT((1 SHL 20) OR (1 SHL 30))) + cmp r9d,0 + jne $L$notintel + + or edx,(1 SHL 30) + and ah,15 + cmp ah,15 + jne $L$notintel + + or edx,(1 SHL 20) +$L$notintel:: + bt edx,28 + jnc $L$generic + xor edx,(1 SHL 28) + cmp r10d,0 + je $L$generic + + or edx,(1 SHL 28) + shr ebx,16 + cmp bl,1 + ja $L$generic + xor edx,(1 SHL 28) + +$L$generic:: + and r9d,(1 SHL 11) + and ecx,(NOT(1 SHL 11)) + or r9d,ecx + + mov r10d,edx + bt r9d,27 + jnc $L$clear_avx + xor ecx,ecx +DB 00fh,001h,0d0h + and eax,6 + cmp eax,6 + je $L$done +$L$clear_avx:: + mov eax,(NOT((1 SHL 28) OR (1 SHL 12) OR (1 SHL 11))) + and r9d,eax +$L$done:: + shl r9,32 + mov eax,r10d + mov rbx,r8 + or rax,r9 + DB 0F3h,0C3h ;repret +OPENSSL_ia32_cpuid ENDP + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/cpuid-mingw64-x86_64.S b/Libraries/libressl/crypto/cpuid-mingw64-x86_64.S new file mode 100644 index 000000000..cf66d0fd5 --- /dev/null +++ b/Libraries/libressl/crypto/cpuid-mingw64-x86_64.S @@ -0,0 +1,137 @@ +#include "x86_arch.h" + + +.section .ctors + .p2align 3 + .quad OPENSSL_cpuid_setup + + + + +.text + +.globl OPENSSL_ia32_cpuid +.def OPENSSL_ia32_cpuid; .scl 2; .type 32; .endef +.p2align 4 +OPENSSL_ia32_cpuid: + movq %rbx,%r8 + + xorl %eax,%eax + cpuid + movl %eax,%r11d + + xorl %eax,%eax + cmpl $1970169159,%ebx + setne %al + movl %eax,%r9d + cmpl $1231384169,%edx + setne %al + orl %eax,%r9d + cmpl $1818588270,%ecx + setne %al + orl %eax,%r9d + jz .Lintel + + cmpl $1752462657,%ebx + setne %al + movl %eax,%r10d + cmpl $1769238117,%edx + setne %al + orl %eax,%r10d + cmpl $1145913699,%ecx + setne %al + orl %eax,%r10d + jnz .Lintel + + + movl $2147483648,%eax + cpuid + cmpl $2147483649,%eax + jb .Lintel + movl %eax,%r10d + movl $2147483649,%eax + cpuid + orl %ecx,%r9d + andl $IA32CAP_MASK1_AMD_XOP,%r9d + orl $1,%r9d + + cmpl $2147483656,%r10d + jb .Lintel + + movl $2147483656,%eax + cpuid + movzbq %cl,%r10 + incq %r10 + + movl $1,%eax + cpuid + btl $IA32CAP_BIT0_HT,%edx + jnc .Lgeneric + shrl $16,%ebx + cmpb %r10b,%bl + ja .Lgeneric + xorl $IA32CAP_MASK0_HT,%edx + jmp .Lgeneric + +.Lintel: + cmpl $4,%r11d + movl $-1,%r10d + jb .Lnocacheinfo + + movl $4,%eax + movl $0,%ecx + cpuid + movl %eax,%r10d + shrl $14,%r10d + andl $4095,%r10d + +.Lnocacheinfo: + movl $1,%eax + cpuid + + andl $(~(IA32CAP_MASK0_INTELP4 | IA32CAP_MASK0_INTEL)),%edx + cmpl $0,%r9d + jne .Lnotintel + + orl $IA32CAP_MASK0_INTEL,%edx + andb $15,%ah + cmpb $15,%ah + jne .Lnotintel + + orl $IA32CAP_MASK0_INTELP4,%edx +.Lnotintel: + btl $IA32CAP_BIT0_HT,%edx + jnc .Lgeneric + xorl $IA32CAP_MASK0_HT,%edx + cmpl $0,%r10d + je .Lgeneric + + orl $IA32CAP_MASK0_HT,%edx + shrl $16,%ebx + cmpb $1,%bl + ja .Lgeneric + xorl $IA32CAP_MASK0_HT,%edx + +.Lgeneric: + andl $IA32CAP_MASK1_AMD_XOP,%r9d + andl $(~IA32CAP_MASK1_AMD_XOP),%ecx + orl %ecx,%r9d + + movl %edx,%r10d + btl $IA32CAP_BIT1_OSXSAVE,%r9d + jnc .Lclear_avx + xorl %ecx,%ecx +.byte 0x0f,0x01,0xd0 + andl $6,%eax + cmpl $6,%eax + je .Ldone +.Lclear_avx: + movl $(~(IA32CAP_MASK1_AVX | IA32CAP_MASK1_FMA3 | IA32CAP_MASK1_AMD_XOP)),%eax + andl %eax,%r9d +.Ldone: + shlq $32,%r9 + movl %r10d,%eax + movq %r8,%rbx + orq %r9,%rax + retq + diff --git a/Libraries/libressl/crypto/cryptlib.c b/Libraries/libressl/crypto/cryptlib.c new file mode 100644 index 000000000..18f40e544 --- /dev/null +++ b/Libraries/libressl/crypto/cryptlib.c @@ -0,0 +1,384 @@ +/* $OpenBSD: cryptlib.c,v 1.46 2023/07/08 08:28:23 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static void (*locking_callback)(int mode, int type, + const char *file, int line) = NULL; +static int (*add_lock_callback)(int *pointer, int amount, + int type, const char *file, int line) = NULL; + +int +CRYPTO_num_locks(void) +{ + return 1; +} + +unsigned long +(*CRYPTO_get_id_callback(void))(void) +{ + return NULL; +} + +void +CRYPTO_set_id_callback(unsigned long (*func)(void)) +{ + return; +} + +unsigned long +CRYPTO_thread_id(void) +{ + return (unsigned long)pthread_self(); +} + +void +CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num, + const char *file, int line)) +{ + locking_callback = func; +} + +void +(*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, int line) +{ + return locking_callback; +} + +void +CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num, + const char *file, int line)) +{ + add_lock_callback = func; +} + +int +(*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, + const char *file, int line) +{ + return add_lock_callback; +} + +const char * +CRYPTO_get_lock_name(int lock_num) +{ + return ""; +} + +struct CRYPTO_dynlock_value * +CRYPTO_get_dynlock_value(int i) +{ + return NULL; +} + +int CRYPTO_get_new_dynlockid(void) +{ + return 0; +} + +void +CRYPTO_destroy_dynlockid(int i) +{ + return; +} + +int CRYPTO_get_new_lockid(char *name) +{ + return 0; +} + +int +CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) +{ + return 1; +} + +void +(*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) +{ + return NULL; +} + +void +CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) +{ + return; +} + +void +CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) +{ + return; +} + +void +CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *( + *dyn_create_function)(const char *file, int line)) +{ + return; +} + +void +CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)) +{ + return; +} + +void +CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)( + struct CRYPTO_dynlock_value *l, const char *file, int line)) +{ + return; +} + +struct CRYPTO_dynlock_value * +(*CRYPTO_get_dynlock_create_callback(void))( + const char *file, int line) +{ + return NULL; +} + +void +(*CRYPTO_get_dynlock_lock_callback(void))(int mode, + struct CRYPTO_dynlock_value *l, const char *file, int line) +{ + return NULL; +} + +void +(*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line) +{ + return NULL; +} + +void +CRYPTO_THREADID_current(CRYPTO_THREADID *id) +{ + memset(id, 0, sizeof(*id)); + id->val = (unsigned long)pthread_self(); +} +LCRYPTO_ALIAS(CRYPTO_THREADID_current); + +int +CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) +{ + return memcmp(a, b, sizeof(*a)); +} +LCRYPTO_ALIAS(CRYPTO_THREADID_cmp); + +void +CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) +{ + memcpy(dest, src, sizeof(*src)); +} +LCRYPTO_ALIAS(CRYPTO_THREADID_cpy); + +unsigned long +CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) +{ + return id->val; +} +LCRYPTO_ALIAS(CRYPTO_THREADID_hash); + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) + +uint64_t OPENSSL_ia32cap_P; + +uint64_t +OPENSSL_cpu_caps(void) +{ + return OPENSSL_ia32cap_P; +} +LCRYPTO_ALIAS(OPENSSL_cpu_caps); + +#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_CPUID_SETUP +void +OPENSSL_cpuid_setup(void) +{ + static int trigger = 0; + uint64_t OPENSSL_ia32_cpuid(void); + + if (trigger) + return; + trigger = 1; + OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid(); +} +#endif + +#else +uint64_t +OPENSSL_cpu_caps(void) +{ + return 0; +} +LCRYPTO_ALIAS(OPENSSL_cpu_caps); +#endif + +#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) +void +OPENSSL_cpuid_setup(void) +{ +} +#endif + +static void +OPENSSL_showfatal(const char *fmta, ...) +{ + struct syslog_data sdata = SYSLOG_DATA_INIT; + va_list ap; + + va_start(ap, fmta); + vsyslog_r(LOG_INFO|LOG_LOCAL2, &sdata, fmta, ap); + va_end(ap); +} + +void +OpenSSLDie(const char *file, int line, const char *assertion) +{ + OPENSSL_showfatal( + "uid %u cmd %s %s(%d): OpenSSL internal error, assertion failed: %s\n", + getuid(), getprogname(), file, line, assertion); + _exit(1); +} +LCRYPTO_ALIAS(OpenSSLDie); + +int +CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) +{ + size_t i; + const unsigned char *a = in_a; + const unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) + x |= a[i] ^ b[i]; + + return x; +} diff --git a/Libraries/libressl/crypto/cryptlib.h b/Libraries/libressl/crypto/cryptlib.h new file mode 100644 index 000000000..6c3731d97 --- /dev/null +++ b/Libraries/libressl/crypto/cryptlib.h @@ -0,0 +1,84 @@ +/* $OpenBSD: cryptlib.h,v 1.26 2021/11/24 01:12:43 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CRYPTLIB_H +#define HEADER_CRYPTLIB_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define X509_CERT_AREA OPENSSLDIR +#define X509_CERT_DIR OPENSSLDIR "/certs" +#define X509_CERT_FILE OPENSSLDIR "/cert.pem" +#define X509_PRIVATE_DIR OPENSSLDIR "/private" +#define X509_CERT_DIR_EVP "SSL_CERT_DIR" +#define X509_CERT_FILE_EVP "SSL_CERT_FILE" + +#define CTLOG_FILE OPENSSLDIR "/ct_log_list.cnf" +#define CTLOG_FILE_EVP "CTLOG_FILE" + +void OPENSSL_cpuid_setup(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/crypto/crypto.sym b/Libraries/libressl/crypto/crypto.sym new file mode 100644 index 000000000..bb80f34cf --- /dev/null +++ b/Libraries/libressl/crypto/crypto.sym @@ -0,0 +1,3678 @@ +ACCESS_DESCRIPTION_free +ACCESS_DESCRIPTION_it +ACCESS_DESCRIPTION_new +AES_cbc_encrypt +AES_cfb128_encrypt +AES_cfb1_encrypt +AES_cfb8_encrypt +AES_ctr128_encrypt +AES_decrypt +AES_ecb_encrypt +AES_encrypt +AES_ige_encrypt +AES_ofb128_encrypt +AES_set_decrypt_key +AES_set_encrypt_key +AES_unwrap_key +AES_wrap_key +ASIdOrRange_free +ASIdOrRange_it +ASIdOrRange_new +ASIdentifierChoice_free +ASIdentifierChoice_it +ASIdentifierChoice_new +ASIdentifiers_free +ASIdentifiers_it +ASIdentifiers_new +ASN1_ANY_it +ASN1_BIT_STRING_free +ASN1_BIT_STRING_get_bit +ASN1_BIT_STRING_it +ASN1_BIT_STRING_new +ASN1_BIT_STRING_set +ASN1_BIT_STRING_set_bit +ASN1_BMPSTRING_free +ASN1_BMPSTRING_it +ASN1_BMPSTRING_new +ASN1_ENUMERATED_free +ASN1_ENUMERATED_get +ASN1_ENUMERATED_get_int64 +ASN1_ENUMERATED_it +ASN1_ENUMERATED_new +ASN1_ENUMERATED_set +ASN1_ENUMERATED_set_int64 +ASN1_ENUMERATED_to_BN +ASN1_GENERALIZEDTIME_adj +ASN1_GENERALIZEDTIME_check +ASN1_GENERALIZEDTIME_free +ASN1_GENERALIZEDTIME_it +ASN1_GENERALIZEDTIME_new +ASN1_GENERALIZEDTIME_print +ASN1_GENERALIZEDTIME_set +ASN1_GENERALIZEDTIME_set_string +ASN1_GENERALSTRING_free +ASN1_GENERALSTRING_it +ASN1_GENERALSTRING_new +ASN1_IA5STRING_free +ASN1_IA5STRING_it +ASN1_IA5STRING_new +ASN1_INTEGER_cmp +ASN1_INTEGER_dup +ASN1_INTEGER_free +ASN1_INTEGER_get +ASN1_INTEGER_get_int64 +ASN1_INTEGER_get_uint64 +ASN1_INTEGER_it +ASN1_INTEGER_new +ASN1_INTEGER_set +ASN1_INTEGER_set_int64 +ASN1_INTEGER_set_uint64 +ASN1_INTEGER_to_BN +ASN1_NULL_free +ASN1_NULL_it +ASN1_NULL_new +ASN1_OBJECT_create +ASN1_OBJECT_free +ASN1_OBJECT_it +ASN1_OBJECT_new +ASN1_OCTET_STRING_cmp +ASN1_OCTET_STRING_dup +ASN1_OCTET_STRING_free +ASN1_OCTET_STRING_it +ASN1_OCTET_STRING_new +ASN1_OCTET_STRING_set +ASN1_PCTX_free +ASN1_PCTX_get_cert_flags +ASN1_PCTX_get_flags +ASN1_PCTX_get_nm_flags +ASN1_PCTX_get_oid_flags +ASN1_PCTX_get_str_flags +ASN1_PCTX_new +ASN1_PCTX_set_cert_flags +ASN1_PCTX_set_flags +ASN1_PCTX_set_nm_flags +ASN1_PCTX_set_oid_flags +ASN1_PCTX_set_str_flags +ASN1_PRINTABLESTRING_free +ASN1_PRINTABLESTRING_it +ASN1_PRINTABLESTRING_new +ASN1_PRINTABLE_free +ASN1_PRINTABLE_it +ASN1_PRINTABLE_new +ASN1_PRINTABLE_type +ASN1_SEQUENCE_ANY_it +ASN1_SEQUENCE_it +ASN1_SET_ANY_it +ASN1_STRING_TABLE_add +ASN1_STRING_TABLE_cleanup +ASN1_STRING_TABLE_get +ASN1_STRING_cmp +ASN1_STRING_copy +ASN1_STRING_data +ASN1_STRING_dup +ASN1_STRING_free +ASN1_STRING_get0_data +ASN1_STRING_get_default_mask +ASN1_STRING_length +ASN1_STRING_length_set +ASN1_STRING_new +ASN1_STRING_print +ASN1_STRING_print_ex +ASN1_STRING_print_ex_fp +ASN1_STRING_set +ASN1_STRING_set0 +ASN1_STRING_set_by_NID +ASN1_STRING_set_default_mask +ASN1_STRING_set_default_mask_asc +ASN1_STRING_to_UTF8 +ASN1_STRING_type +ASN1_STRING_type_new +ASN1_T61STRING_free +ASN1_T61STRING_it +ASN1_T61STRING_new +ASN1_TIME_adj +ASN1_TIME_check +ASN1_TIME_cmp_time_t +ASN1_TIME_compare +ASN1_TIME_diff +ASN1_TIME_free +ASN1_TIME_it +ASN1_TIME_new +ASN1_TIME_normalize +ASN1_TIME_print +ASN1_TIME_set +ASN1_TIME_set_string +ASN1_TIME_set_string_X509 +ASN1_TIME_set_tm +ASN1_TIME_to_generalizedtime +ASN1_TIME_to_tm +ASN1_TYPE_cmp +ASN1_TYPE_free +ASN1_TYPE_get +ASN1_TYPE_get_int_octetstring +ASN1_TYPE_get_octetstring +ASN1_TYPE_new +ASN1_TYPE_set +ASN1_TYPE_set1 +ASN1_TYPE_set_int_octetstring +ASN1_TYPE_set_octetstring +ASN1_UNIVERSALSTRING_free +ASN1_UNIVERSALSTRING_it +ASN1_UNIVERSALSTRING_new +ASN1_UNIVERSALSTRING_to_string +ASN1_UTCTIME_adj +ASN1_UTCTIME_check +ASN1_UTCTIME_cmp_time_t +ASN1_UTCTIME_free +ASN1_UTCTIME_it +ASN1_UTCTIME_new +ASN1_UTCTIME_print +ASN1_UTCTIME_set +ASN1_UTCTIME_set_string +ASN1_UTF8STRING_free +ASN1_UTF8STRING_it +ASN1_UTF8STRING_new +ASN1_VISIBLESTRING_free +ASN1_VISIBLESTRING_it +ASN1_VISIBLESTRING_new +ASN1_add_oid_module +ASN1_d2i_bio +ASN1_d2i_fp +ASN1_dup +ASN1_generate_nconf +ASN1_generate_v3 +ASN1_get_object +ASN1_i2d_bio +ASN1_i2d_fp +ASN1_item_d2i +ASN1_item_d2i_bio +ASN1_item_d2i_fp +ASN1_item_digest +ASN1_item_dup +ASN1_item_ex_d2i +ASN1_item_ex_free +ASN1_item_ex_i2d +ASN1_item_ex_new +ASN1_item_free +ASN1_item_i2d +ASN1_item_i2d_bio +ASN1_item_i2d_fp +ASN1_item_new +ASN1_item_pack +ASN1_item_print +ASN1_item_sign +ASN1_item_sign_ctx +ASN1_item_unpack +ASN1_item_verify +ASN1_mbstring_copy +ASN1_mbstring_ncopy +ASN1_object_size +ASN1_parse +ASN1_parse_dump +ASN1_put_eoc +ASN1_put_object +ASN1_tag2bit +ASN1_tag2str +ASN1_time_parse +ASN1_time_tm_clamp_notafter +ASN1_time_tm_cmp +ASRange_free +ASRange_it +ASRange_new +AUTHORITY_INFO_ACCESS_free +AUTHORITY_INFO_ACCESS_it +AUTHORITY_INFO_ACCESS_new +AUTHORITY_KEYID_free +AUTHORITY_KEYID_it +AUTHORITY_KEYID_new +BASIC_CONSTRAINTS_free +BASIC_CONSTRAINTS_it +BASIC_CONSTRAINTS_new +BF_cbc_encrypt +BF_cfb64_encrypt +BF_decrypt +BF_ecb_encrypt +BF_encrypt +BF_ofb64_encrypt +BF_set_key +BIGNUM_it +BIO_CONNECT_free +BIO_CONNECT_new +BIO_accept +BIO_callback_ctrl +BIO_clear_flags +BIO_copy_next_retry +BIO_ctrl +BIO_ctrl_get_read_request +BIO_ctrl_get_write_guarantee +BIO_ctrl_pending +BIO_ctrl_reset_read_request +BIO_ctrl_wpending +BIO_debug_callback +BIO_dgram_non_fatal_error +BIO_dump +BIO_dump_cb +BIO_dump_fp +BIO_dump_indent +BIO_dump_indent_cb +BIO_dump_indent_fp +BIO_dup_chain +BIO_f_base64 +BIO_f_buffer +BIO_f_cipher +BIO_f_md +BIO_f_nbio_test +BIO_f_null +BIO_fd_non_fatal_error +BIO_fd_should_retry +BIO_find_type +BIO_free +BIO_free_all +BIO_get_accept_socket +BIO_get_callback +BIO_get_callback_arg +BIO_get_callback_ex +BIO_get_data +BIO_get_ex_data +BIO_get_ex_new_index +BIO_get_host_ip +BIO_get_init +BIO_get_new_index +BIO_get_port +BIO_get_retry_BIO +BIO_get_retry_reason +BIO_get_shutdown +BIO_gethostbyname +BIO_gets +BIO_indent +BIO_int_ctrl +BIO_meth_free +BIO_meth_get_callback_ctrl +BIO_meth_get_create +BIO_meth_get_ctrl +BIO_meth_get_destroy +BIO_meth_get_gets +BIO_meth_get_puts +BIO_meth_get_read +BIO_meth_get_write +BIO_meth_new +BIO_meth_set_callback_ctrl +BIO_meth_set_create +BIO_meth_set_ctrl +BIO_meth_set_destroy +BIO_meth_set_gets +BIO_meth_set_puts +BIO_meth_set_read +BIO_meth_set_write +BIO_method_name +BIO_method_type +BIO_new +BIO_new_CMS +BIO_new_PKCS7 +BIO_new_accept +BIO_new_bio_pair +BIO_new_connect +BIO_new_dgram +BIO_new_fd +BIO_new_file +BIO_new_fp +BIO_new_mem_buf +BIO_new_socket +BIO_next +BIO_number_read +BIO_number_written +BIO_pop +BIO_printf +BIO_ptr_ctrl +BIO_push +BIO_puts +BIO_read +BIO_s_accept +BIO_s_bio +BIO_s_connect +BIO_s_datagram +BIO_s_fd +BIO_s_file +BIO_s_log +BIO_s_mem +BIO_s_null +BIO_s_socket +BIO_set +BIO_set_callback +BIO_set_callback_arg +BIO_set_callback_ex +BIO_set_cipher +BIO_set_data +BIO_set_ex_data +BIO_set_flags +BIO_set_init +BIO_set_next +BIO_set_retry_reason +BIO_set_shutdown +BIO_set_tcp_ndelay +BIO_snprintf +BIO_sock_cleanup +BIO_sock_error +BIO_sock_init +BIO_sock_non_fatal_error +BIO_sock_should_retry +BIO_socket_ioctl +BIO_socket_nbio +BIO_test_flags +BIO_up_ref +BIO_vfree +BIO_vprintf +BIO_vsnprintf +BIO_write +BN_CTX_end +BN_CTX_free +BN_CTX_get +BN_CTX_new +BN_CTX_start +BN_GENCB_call +BN_GENCB_free +BN_GENCB_get_arg +BN_GENCB_new +BN_GENCB_set +BN_GENCB_set_old +BN_MONT_CTX_copy +BN_MONT_CTX_free +BN_MONT_CTX_new +BN_MONT_CTX_set +BN_MONT_CTX_set_locked +BN_abs_is_word +BN_add +BN_add_word +BN_asc2bn +BN_bin2bn +BN_bn2bin +BN_bn2binpad +BN_bn2dec +BN_bn2hex +BN_bn2lebinpad +BN_bn2mpi +BN_clear +BN_clear_bit +BN_clear_free +BN_cmp +BN_consttime_swap +BN_copy +BN_dec2bn +BN_div +BN_div_word +BN_dup +BN_exp +BN_free +BN_from_montgomery +BN_gcd +BN_generate_prime_ex +BN_get_flags +BN_get_rfc2409_prime_1024 +BN_get_rfc2409_prime_768 +BN_get_rfc3526_prime_1536 +BN_get_rfc3526_prime_2048 +BN_get_rfc3526_prime_3072 +BN_get_rfc3526_prime_4096 +BN_get_rfc3526_prime_6144 +BN_get_rfc3526_prime_8192 +BN_get_word +BN_hex2bn +BN_is_bit_set +BN_is_negative +BN_is_odd +BN_is_one +BN_is_prime_ex +BN_is_prime_fasttest_ex +BN_is_word +BN_is_zero +BN_kronecker +BN_lebin2bn +BN_lshift +BN_lshift1 +BN_mask_bits +BN_mod_add +BN_mod_add_quick +BN_mod_exp +BN_mod_exp2_mont +BN_mod_exp_mont +BN_mod_exp_mont_consttime +BN_mod_exp_mont_word +BN_mod_exp_simple +BN_mod_inverse +BN_mod_lshift +BN_mod_lshift1 +BN_mod_lshift1_quick +BN_mod_lshift_quick +BN_mod_mul +BN_mod_mul_montgomery +BN_mod_sqr +BN_mod_sqrt +BN_mod_sub +BN_mod_sub_quick +BN_mod_word +BN_mpi2bn +BN_mul +BN_mul_word +BN_new +BN_nnmod +BN_num_bits +BN_num_bits_word +BN_one +BN_print +BN_print_fp +BN_pseudo_rand +BN_pseudo_rand_range +BN_rand +BN_rand_range +BN_rshift +BN_rshift1 +BN_security_bits +BN_set_bit +BN_set_flags +BN_set_negative +BN_set_word +BN_sqr +BN_sub +BN_sub_word +BN_swap +BN_to_ASN1_ENUMERATED +BN_to_ASN1_INTEGER +BN_to_montgomery +BN_uadd +BN_ucmp +BN_usub +BN_value_one +BN_with_flags +BN_zero +BUF_MEM_free +BUF_MEM_grow +BUF_MEM_grow_clean +BUF_MEM_new +CAST_cbc_encrypt +CAST_cfb64_encrypt +CAST_decrypt +CAST_ecb_encrypt +CAST_encrypt +CAST_ofb64_encrypt +CAST_set_key +CBIGNUM_it +CERTIFICATEPOLICIES_free +CERTIFICATEPOLICIES_it +CERTIFICATEPOLICIES_new +CMAC_CTX_cleanup +CMAC_CTX_copy +CMAC_CTX_free +CMAC_CTX_get0_cipher_ctx +CMAC_CTX_new +CMAC_Final +CMAC_Init +CMAC_Update +CMAC_resume +CMS_ContentInfo_free +CMS_ContentInfo_it +CMS_ContentInfo_new +CMS_ContentInfo_print_ctx +CMS_EncryptedData_decrypt +CMS_EncryptedData_encrypt +CMS_EncryptedData_set1_key +CMS_EnvelopedData_create +CMS_ReceiptRequest_create0 +CMS_ReceiptRequest_free +CMS_ReceiptRequest_get0_values +CMS_ReceiptRequest_it +CMS_ReceiptRequest_new +CMS_RecipientEncryptedKey_cert_cmp +CMS_RecipientEncryptedKey_get0_id +CMS_RecipientInfo_decrypt +CMS_RecipientInfo_encrypt +CMS_RecipientInfo_get0_pkey_ctx +CMS_RecipientInfo_kari_decrypt +CMS_RecipientInfo_kari_get0_alg +CMS_RecipientInfo_kari_get0_ctx +CMS_RecipientInfo_kari_get0_orig_id +CMS_RecipientInfo_kari_get0_reks +CMS_RecipientInfo_kari_orig_id_cmp +CMS_RecipientInfo_kari_set0_pkey +CMS_RecipientInfo_kekri_get0_id +CMS_RecipientInfo_kekri_id_cmp +CMS_RecipientInfo_ktri_cert_cmp +CMS_RecipientInfo_ktri_get0_algs +CMS_RecipientInfo_ktri_get0_signer_id +CMS_RecipientInfo_set0_key +CMS_RecipientInfo_set0_password +CMS_RecipientInfo_set0_pkey +CMS_RecipientInfo_type +CMS_SharedInfo_encode +CMS_SignedData_init +CMS_SignerInfo_cert_cmp +CMS_SignerInfo_get0_algs +CMS_SignerInfo_get0_md_ctx +CMS_SignerInfo_get0_pkey_ctx +CMS_SignerInfo_get0_signature +CMS_SignerInfo_get0_signer_id +CMS_SignerInfo_get_version +CMS_SignerInfo_set1_signer_cert +CMS_SignerInfo_sign +CMS_SignerInfo_verify +CMS_SignerInfo_verify_content +CMS_add0_CertificateChoices +CMS_add0_RevocationInfoChoice +CMS_add0_cert +CMS_add0_crl +CMS_add0_recipient_key +CMS_add0_recipient_password +CMS_add1_ReceiptRequest +CMS_add1_cert +CMS_add1_crl +CMS_add1_recipient_cert +CMS_add1_signer +CMS_add_simple_smimecap +CMS_add_smimecap +CMS_add_standard_smimecap +CMS_compress +CMS_data +CMS_dataFinal +CMS_dataInit +CMS_data_create +CMS_decrypt +CMS_decrypt_set1_key +CMS_decrypt_set1_password +CMS_decrypt_set1_pkey +CMS_digest_create +CMS_digest_verify +CMS_encrypt +CMS_final +CMS_get0_RecipientInfos +CMS_get0_SignerInfos +CMS_get0_content +CMS_get0_eContentType +CMS_get0_signers +CMS_get0_type +CMS_get1_ReceiptRequest +CMS_get1_certs +CMS_get1_crls +CMS_get_version +CMS_is_detached +CMS_set1_eContentType +CMS_set1_signers_certs +CMS_set_detached +CMS_sign +CMS_sign_receipt +CMS_signed_add1_attr +CMS_signed_add1_attr_by_NID +CMS_signed_add1_attr_by_OBJ +CMS_signed_add1_attr_by_txt +CMS_signed_delete_attr +CMS_signed_get0_data_by_OBJ +CMS_signed_get_attr +CMS_signed_get_attr_by_NID +CMS_signed_get_attr_by_OBJ +CMS_signed_get_attr_count +CMS_stream +CMS_uncompress +CMS_unsigned_add1_attr +CMS_unsigned_add1_attr_by_NID +CMS_unsigned_add1_attr_by_OBJ +CMS_unsigned_add1_attr_by_txt +CMS_unsigned_delete_attr +CMS_unsigned_get0_data_by_OBJ +CMS_unsigned_get_attr +CMS_unsigned_get_attr_by_NID +CMS_unsigned_get_attr_by_OBJ +CMS_unsigned_get_attr_count +CMS_verify +CMS_verify_receipt +CONF_dump_bio +CONF_dump_fp +CONF_free +CONF_get1_default_config_file +CONF_get_number +CONF_get_section +CONF_get_string +CONF_imodule_get_flags +CONF_imodule_get_module +CONF_imodule_get_name +CONF_imodule_get_usr_data +CONF_imodule_get_value +CONF_imodule_set_flags +CONF_imodule_set_usr_data +CONF_load +CONF_load_bio +CONF_load_fp +CONF_module_add +CONF_module_get_usr_data +CONF_module_set_usr_data +CONF_modules_finish +CONF_modules_free +CONF_modules_load +CONF_modules_load_file +CONF_modules_unload +CONF_parse_list +CONF_set_default_method +CONF_set_nconf +CRL_DIST_POINTS_free +CRL_DIST_POINTS_it +CRL_DIST_POINTS_new +CRYPTO_THREADID_cmp +CRYPTO_THREADID_cpy +CRYPTO_THREADID_current +CRYPTO_THREADID_get_callback +CRYPTO_THREADID_hash +CRYPTO_THREADID_set_callback +CRYPTO_THREADID_set_numeric +CRYPTO_THREADID_set_pointer +CRYPTO_add_lock +CRYPTO_cbc128_decrypt +CRYPTO_cbc128_encrypt +CRYPTO_ccm128_aad +CRYPTO_ccm128_decrypt +CRYPTO_ccm128_decrypt_ccm64 +CRYPTO_ccm128_encrypt +CRYPTO_ccm128_encrypt_ccm64 +CRYPTO_ccm128_init +CRYPTO_ccm128_setiv +CRYPTO_ccm128_tag +CRYPTO_cfb128_1_encrypt +CRYPTO_cfb128_8_encrypt +CRYPTO_cfb128_encrypt +CRYPTO_chacha_20 +CRYPTO_cleanup_all_ex_data +CRYPTO_ctr128_encrypt +CRYPTO_ctr128_encrypt_ctr32 +CRYPTO_dbg_free +CRYPTO_dbg_get_options +CRYPTO_dbg_malloc +CRYPTO_dbg_realloc +CRYPTO_dbg_set_options +CRYPTO_destroy_dynlockid +CRYPTO_dup_ex_data +CRYPTO_free +CRYPTO_free_ex_data +CRYPTO_free_locked +CRYPTO_gcm128_aad +CRYPTO_gcm128_decrypt +CRYPTO_gcm128_decrypt_ctr32 +CRYPTO_gcm128_encrypt +CRYPTO_gcm128_encrypt_ctr32 +CRYPTO_gcm128_finish +CRYPTO_gcm128_init +CRYPTO_gcm128_new +CRYPTO_gcm128_release +CRYPTO_gcm128_setiv +CRYPTO_gcm128_tag +CRYPTO_get_add_lock_callback +CRYPTO_get_dynlock_create_callback +CRYPTO_get_dynlock_destroy_callback +CRYPTO_get_dynlock_lock_callback +CRYPTO_get_dynlock_value +CRYPTO_get_ex_data +CRYPTO_get_ex_new_index +CRYPTO_get_id_callback +CRYPTO_get_lock_name +CRYPTO_get_locked_mem_ex_functions +CRYPTO_get_locked_mem_functions +CRYPTO_get_locking_callback +CRYPTO_get_mem_debug_functions +CRYPTO_get_mem_debug_options +CRYPTO_get_mem_ex_functions +CRYPTO_get_mem_functions +CRYPTO_get_new_dynlockid +CRYPTO_get_new_lockid +CRYPTO_hchacha_20 +CRYPTO_is_mem_check_on +CRYPTO_lock +CRYPTO_malloc +CRYPTO_malloc_locked +CRYPTO_mem_ctrl +CRYPTO_mem_leaks +CRYPTO_mem_leaks_cb +CRYPTO_mem_leaks_fp +CRYPTO_memcmp +CRYPTO_new_ex_data +CRYPTO_num_locks +CRYPTO_ofb128_encrypt +CRYPTO_poly1305_finish +CRYPTO_poly1305_init +CRYPTO_poly1305_update +CRYPTO_pop_info +CRYPTO_push_info_ +CRYPTO_realloc +CRYPTO_realloc_clean +CRYPTO_remalloc +CRYPTO_remove_all_info +CRYPTO_set_add_lock_callback +CRYPTO_set_dynlock_create_callback +CRYPTO_set_dynlock_destroy_callback +CRYPTO_set_dynlock_lock_callback +CRYPTO_set_ex_data +CRYPTO_set_id_callback +CRYPTO_set_locked_mem_ex_functions +CRYPTO_set_locked_mem_functions +CRYPTO_set_locking_callback +CRYPTO_set_mem_debug_functions +CRYPTO_set_mem_debug_options +CRYPTO_set_mem_ex_functions +CRYPTO_set_mem_functions +CRYPTO_strdup +CRYPTO_thread_id +CRYPTO_xchacha_20 +CRYPTO_xts128_encrypt +CTLOG_STORE_free +CTLOG_STORE_get0_log_by_id +CTLOG_STORE_load_default_file +CTLOG_STORE_load_file +CTLOG_STORE_new +CTLOG_free +CTLOG_get0_log_id +CTLOG_get0_name +CTLOG_get0_public_key +CTLOG_new +CTLOG_new_from_base64 +CT_POLICY_EVAL_CTX_free +CT_POLICY_EVAL_CTX_get0_cert +CT_POLICY_EVAL_CTX_get0_issuer +CT_POLICY_EVAL_CTX_get0_log_store +CT_POLICY_EVAL_CTX_get_time +CT_POLICY_EVAL_CTX_new +CT_POLICY_EVAL_CTX_set1_cert +CT_POLICY_EVAL_CTX_set1_issuer +CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE +CT_POLICY_EVAL_CTX_set_time +Camellia_cbc_encrypt +Camellia_cfb128_encrypt +Camellia_cfb1_encrypt +Camellia_cfb8_encrypt +Camellia_ctr128_encrypt +Camellia_decrypt +Camellia_ecb_encrypt +Camellia_encrypt +Camellia_ofb128_encrypt +Camellia_set_key +ChaCha +ChaCha_set_iv +ChaCha_set_key +DES_cbc_cksum +DES_cbc_encrypt +DES_cfb64_encrypt +DES_cfb_encrypt +DES_check_key +DES_check_key_parity +DES_crypt +DES_decrypt3 +DES_ecb3_encrypt +DES_ecb_encrypt +DES_ede3_cbc_encrypt +DES_ede3_cbcm_encrypt +DES_ede3_cfb64_encrypt +DES_ede3_cfb_encrypt +DES_ede3_ofb64_encrypt +DES_enc_read +DES_enc_write +DES_encrypt1 +DES_encrypt2 +DES_encrypt3 +DES_fcrypt +DES_is_weak_key +DES_key_sched +DES_ncbc_encrypt +DES_ofb64_encrypt +DES_ofb_encrypt +DES_pcbc_encrypt +DES_quad_cksum +DES_random_key +DES_rw_mode +DES_set_key +DES_set_key_checked +DES_set_key_unchecked +DES_set_odd_parity +DES_string_to_2keys +DES_string_to_key +DES_xcbc_encrypt +DH_OpenSSL +DH_bits +DH_check +DH_check_pub_key +DH_clear_flags +DH_compute_key +DH_free +DH_generate_key +DH_generate_parameters +DH_generate_parameters_ex +DH_get0_engine +DH_get0_g +DH_get0_key +DH_get0_p +DH_get0_pqg +DH_get0_priv_key +DH_get0_pub_key +DH_get0_q +DH_get_default_method +DH_get_ex_data +DH_get_ex_new_index +DH_get_length +DH_new +DH_new_method +DH_security_bits +DH_set0_key +DH_set0_pqg +DH_set_default_method +DH_set_ex_data +DH_set_flags +DH_set_length +DH_set_method +DH_size +DH_test_flags +DH_up_ref +DHparams_dup +DHparams_it +DHparams_print +DHparams_print_fp +DIRECTORYSTRING_free +DIRECTORYSTRING_it +DIRECTORYSTRING_new +DISPLAYTEXT_free +DISPLAYTEXT_it +DISPLAYTEXT_new +DIST_POINT_NAME_free +DIST_POINT_NAME_it +DIST_POINT_NAME_new +DIST_POINT_free +DIST_POINT_it +DIST_POINT_new +DIST_POINT_set_dpname +DSAPrivateKey_it +DSAPublicKey_it +DSA_OpenSSL +DSA_SIG_free +DSA_SIG_get0 +DSA_SIG_it +DSA_SIG_new +DSA_SIG_set0 +DSA_bits +DSA_clear_flags +DSA_do_sign +DSA_do_verify +DSA_dup_DH +DSA_free +DSA_generate_key +DSA_generate_parameters +DSA_generate_parameters_ex +DSA_get0_engine +DSA_get0_g +DSA_get0_key +DSA_get0_p +DSA_get0_pqg +DSA_get0_priv_key +DSA_get0_pub_key +DSA_get0_q +DSA_get_default_method +DSA_get_ex_data +DSA_get_ex_new_index +DSA_meth_dup +DSA_meth_free +DSA_meth_get0_name +DSA_meth_new +DSA_meth_set1_name +DSA_meth_set_finish +DSA_meth_set_sign +DSA_new +DSA_new_method +DSA_print +DSA_print_fp +DSA_security_bits +DSA_set0_key +DSA_set0_pqg +DSA_set_default_method +DSA_set_ex_data +DSA_set_flags +DSA_set_method +DSA_sign +DSA_sign_setup +DSA_size +DSA_test_flags +DSA_up_ref +DSA_verify +DSAparams_dup +DSAparams_it +DSAparams_print +DSAparams_print_fp +ECDH_compute_key +ECDH_size +ECDSA_SIG_free +ECDSA_SIG_get0 +ECDSA_SIG_get0_r +ECDSA_SIG_get0_s +ECDSA_SIG_it +ECDSA_SIG_new +ECDSA_SIG_set0 +ECDSA_do_sign +ECDSA_do_verify +ECDSA_sign +ECDSA_size +ECDSA_verify +ECPARAMETERS_free +ECPARAMETERS_it +ECPARAMETERS_new +ECPKPARAMETERS_free +ECPKPARAMETERS_it +ECPKPARAMETERS_new +ECPKParameters_print +ECPKParameters_print_fp +ECParameters_dup +ECParameters_print +ECParameters_print_fp +EC_GFp_mont_method +EC_GFp_simple_method +EC_GROUP_check +EC_GROUP_check_discriminant +EC_GROUP_clear_free +EC_GROUP_cmp +EC_GROUP_copy +EC_GROUP_dup +EC_GROUP_free +EC_GROUP_get0_generator +EC_GROUP_get0_seed +EC_GROUP_get_asn1_flag +EC_GROUP_get_basis_type +EC_GROUP_get_cofactor +EC_GROUP_get_curve +EC_GROUP_get_curve_GFp +EC_GROUP_get_curve_name +EC_GROUP_get_degree +EC_GROUP_get_order +EC_GROUP_get_point_conversion_form +EC_GROUP_get_seed_len +EC_GROUP_have_precompute_mult +EC_GROUP_method_of +EC_GROUP_new +EC_GROUP_new_by_curve_name +EC_GROUP_new_curve_GFp +EC_GROUP_order_bits +EC_GROUP_precompute_mult +EC_GROUP_set_asn1_flag +EC_GROUP_set_curve +EC_GROUP_set_curve_GFp +EC_GROUP_set_curve_name +EC_GROUP_set_generator +EC_GROUP_set_point_conversion_form +EC_GROUP_set_seed +EC_KEY_METHOD_free +EC_KEY_METHOD_get_compute_key +EC_KEY_METHOD_get_init +EC_KEY_METHOD_get_keygen +EC_KEY_METHOD_get_sign +EC_KEY_METHOD_get_verify +EC_KEY_METHOD_new +EC_KEY_METHOD_set_compute_key +EC_KEY_METHOD_set_init +EC_KEY_METHOD_set_keygen +EC_KEY_METHOD_set_sign +EC_KEY_METHOD_set_verify +EC_KEY_OpenSSL +EC_KEY_check_key +EC_KEY_clear_flags +EC_KEY_copy +EC_KEY_dup +EC_KEY_free +EC_KEY_generate_key +EC_KEY_get0_group +EC_KEY_get0_private_key +EC_KEY_get0_public_key +EC_KEY_get_conv_form +EC_KEY_get_default_method +EC_KEY_get_enc_flags +EC_KEY_get_ex_data +EC_KEY_get_flags +EC_KEY_get_method +EC_KEY_new +EC_KEY_new_by_curve_name +EC_KEY_new_method +EC_KEY_precompute_mult +EC_KEY_print +EC_KEY_print_fp +EC_KEY_set_asn1_flag +EC_KEY_set_conv_form +EC_KEY_set_default_method +EC_KEY_set_enc_flags +EC_KEY_set_ex_data +EC_KEY_set_flags +EC_KEY_set_group +EC_KEY_set_method +EC_KEY_set_private_key +EC_KEY_set_public_key +EC_KEY_set_public_key_affine_coordinates +EC_KEY_up_ref +EC_METHOD_get_field_type +EC_POINT_add +EC_POINT_bn2point +EC_POINT_clear_free +EC_POINT_cmp +EC_POINT_copy +EC_POINT_dbl +EC_POINT_dup +EC_POINT_free +EC_POINT_get_Jprojective_coordinates_GFp +EC_POINT_get_affine_coordinates +EC_POINT_get_affine_coordinates_GFp +EC_POINT_hex2point +EC_POINT_invert +EC_POINT_is_at_infinity +EC_POINT_is_on_curve +EC_POINT_make_affine +EC_POINT_method_of +EC_POINT_mul +EC_POINT_new +EC_POINT_oct2point +EC_POINT_point2bn +EC_POINT_point2hex +EC_POINT_point2oct +EC_POINT_set_Jprojective_coordinates_GFp +EC_POINT_set_affine_coordinates +EC_POINT_set_affine_coordinates_GFp +EC_POINT_set_compressed_coordinates +EC_POINT_set_compressed_coordinates_GFp +EC_POINT_set_to_infinity +EC_POINTs_make_affine +EC_POINTs_mul +EC_PRIVATEKEY_free +EC_PRIVATEKEY_it +EC_PRIVATEKEY_new +EC_curve_nid2nist +EC_curve_nist2nid +EC_get_builtin_curves +ED25519_keypair +ED25519_sign +ED25519_verify +EDIPARTYNAME_free +EDIPARTYNAME_it +EDIPARTYNAME_new +ENGINE_by_id +ENGINE_cleanup +ENGINE_ctrl_cmd +ENGINE_ctrl_cmd_string +ENGINE_finish +ENGINE_free +ENGINE_get_default_RSA +ENGINE_get_id +ENGINE_get_name +ENGINE_init +ENGINE_load_builtin_engines +ENGINE_load_dynamic +ENGINE_load_openssl +ENGINE_load_private_key +ENGINE_load_public_key +ENGINE_new +ENGINE_register_all_complete +ENGINE_set_default +ENGINE_set_default_RSA +ERR_add_error_data +ERR_add_error_vdata +ERR_asprintf_error_data +ERR_clear_error +ERR_error_string +ERR_error_string_n +ERR_free_strings +ERR_func_error_string +ERR_get_error +ERR_get_error_line +ERR_get_error_line_data +ERR_get_next_error_library +ERR_get_state +ERR_lib_error_string +ERR_load_ASN1_strings +ERR_load_BIO_strings +ERR_load_BN_strings +ERR_load_BUF_strings +ERR_load_CMS_strings +ERR_load_CONF_strings +ERR_load_CRYPTO_strings +ERR_load_DH_strings +ERR_load_DSA_strings +ERR_load_EC_strings +ERR_load_ERR_strings +ERR_load_EVP_strings +ERR_load_GOST_strings +ERR_load_OBJ_strings +ERR_load_OCSP_strings +ERR_load_PEM_strings +ERR_load_PKCS12_strings +ERR_load_PKCS7_strings +ERR_load_RAND_strings +ERR_load_RSA_strings +ERR_load_TS_strings +ERR_load_UI_strings +ERR_load_X509V3_strings +ERR_load_X509_strings +ERR_load_crypto_strings +ERR_load_strings +ERR_peek_error +ERR_peek_error_line +ERR_peek_error_line_data +ERR_peek_last_error +ERR_peek_last_error_line +ERR_peek_last_error_line_data +ERR_pop_to_mark +ERR_print_errors +ERR_print_errors_cb +ERR_print_errors_fp +ERR_put_error +ERR_reason_error_string +ERR_remove_state +ERR_remove_thread_state +ERR_set_error_data +ERR_set_mark +ERR_unload_strings +ESS_CERT_ID_dup +ESS_CERT_ID_free +ESS_CERT_ID_it +ESS_CERT_ID_new +ESS_ISSUER_SERIAL_dup +ESS_ISSUER_SERIAL_free +ESS_ISSUER_SERIAL_it +ESS_ISSUER_SERIAL_new +ESS_SIGNING_CERT_dup +ESS_SIGNING_CERT_free +ESS_SIGNING_CERT_it +ESS_SIGNING_CERT_new +EVP_AEAD_CTX_cleanup +EVP_AEAD_CTX_free +EVP_AEAD_CTX_init +EVP_AEAD_CTX_new +EVP_AEAD_CTX_open +EVP_AEAD_CTX_seal +EVP_AEAD_key_length +EVP_AEAD_max_overhead +EVP_AEAD_max_tag_len +EVP_AEAD_nonce_length +EVP_BytesToKey +EVP_CIPHER_CTX_block_size +EVP_CIPHER_CTX_buf_noconst +EVP_CIPHER_CTX_cipher +EVP_CIPHER_CTX_cleanup +EVP_CIPHER_CTX_clear_flags +EVP_CIPHER_CTX_copy +EVP_CIPHER_CTX_ctrl +EVP_CIPHER_CTX_encrypting +EVP_CIPHER_CTX_flags +EVP_CIPHER_CTX_free +EVP_CIPHER_CTX_get_app_data +EVP_CIPHER_CTX_get_cipher_data +EVP_CIPHER_CTX_get_iv +EVP_CIPHER_CTX_init +EVP_CIPHER_CTX_iv_length +EVP_CIPHER_CTX_key_length +EVP_CIPHER_CTX_new +EVP_CIPHER_CTX_nid +EVP_CIPHER_CTX_rand_key +EVP_CIPHER_CTX_reset +EVP_CIPHER_CTX_set_app_data +EVP_CIPHER_CTX_set_cipher_data +EVP_CIPHER_CTX_set_flags +EVP_CIPHER_CTX_set_iv +EVP_CIPHER_CTX_set_key_length +EVP_CIPHER_CTX_set_padding +EVP_CIPHER_CTX_test_flags +EVP_CIPHER_asn1_to_param +EVP_CIPHER_block_size +EVP_CIPHER_do_all +EVP_CIPHER_do_all_sorted +EVP_CIPHER_flags +EVP_CIPHER_get_asn1_iv +EVP_CIPHER_iv_length +EVP_CIPHER_key_length +EVP_CIPHER_meth_dup +EVP_CIPHER_meth_free +EVP_CIPHER_meth_new +EVP_CIPHER_meth_set_cleanup +EVP_CIPHER_meth_set_ctrl +EVP_CIPHER_meth_set_do_cipher +EVP_CIPHER_meth_set_flags +EVP_CIPHER_meth_set_get_asn1_params +EVP_CIPHER_meth_set_impl_ctx_size +EVP_CIPHER_meth_set_init +EVP_CIPHER_meth_set_iv_length +EVP_CIPHER_meth_set_set_asn1_params +EVP_CIPHER_nid +EVP_CIPHER_param_to_asn1 +EVP_CIPHER_set_asn1_iv +EVP_CIPHER_type +EVP_Cipher +EVP_CipherFinal +EVP_CipherFinal_ex +EVP_CipherInit +EVP_CipherInit_ex +EVP_CipherUpdate +EVP_DecodeBlock +EVP_DecodeFinal +EVP_DecodeInit +EVP_DecodeUpdate +EVP_DecryptFinal +EVP_DecryptFinal_ex +EVP_DecryptInit +EVP_DecryptInit_ex +EVP_DecryptUpdate +EVP_Digest +EVP_DigestFinal +EVP_DigestFinal_ex +EVP_DigestInit +EVP_DigestInit_ex +EVP_DigestSign +EVP_DigestSignFinal +EVP_DigestSignInit +EVP_DigestUpdate +EVP_DigestVerify +EVP_DigestVerifyFinal +EVP_DigestVerifyInit +EVP_ENCODE_CTX_free +EVP_ENCODE_CTX_new +EVP_EncodeBlock +EVP_EncodeFinal +EVP_EncodeInit +EVP_EncodeUpdate +EVP_EncryptFinal +EVP_EncryptFinal_ex +EVP_EncryptInit +EVP_EncryptInit_ex +EVP_EncryptUpdate +EVP_MD_CTX_cleanup +EVP_MD_CTX_clear_flags +EVP_MD_CTX_copy +EVP_MD_CTX_copy_ex +EVP_MD_CTX_create +EVP_MD_CTX_ctrl +EVP_MD_CTX_destroy +EVP_MD_CTX_free +EVP_MD_CTX_init +EVP_MD_CTX_md +EVP_MD_CTX_md_data +EVP_MD_CTX_new +EVP_MD_CTX_pkey_ctx +EVP_MD_CTX_reset +EVP_MD_CTX_set_flags +EVP_MD_CTX_set_pkey_ctx +EVP_MD_CTX_test_flags +EVP_MD_block_size +EVP_MD_do_all +EVP_MD_do_all_sorted +EVP_MD_flags +EVP_MD_meth_dup +EVP_MD_meth_free +EVP_MD_meth_new +EVP_MD_meth_set_app_datasize +EVP_MD_meth_set_cleanup +EVP_MD_meth_set_copy +EVP_MD_meth_set_ctrl +EVP_MD_meth_set_final +EVP_MD_meth_set_flags +EVP_MD_meth_set_init +EVP_MD_meth_set_input_blocksize +EVP_MD_meth_set_result_size +EVP_MD_meth_set_update +EVP_MD_pkey_type +EVP_MD_size +EVP_MD_type +EVP_OpenFinal +EVP_OpenInit +EVP_PBE_CipherInit +EVP_PBE_alg_add +EVP_PBE_alg_add_type +EVP_PBE_cleanup +EVP_PBE_find +EVP_PKCS82PKEY +EVP_PKEY2PKCS8 +EVP_PKEY_CTX_ctrl +EVP_PKEY_CTX_ctrl_str +EVP_PKEY_CTX_dup +EVP_PKEY_CTX_free +EVP_PKEY_CTX_get0_peerkey +EVP_PKEY_CTX_get0_pkey +EVP_PKEY_CTX_get_app_data +EVP_PKEY_CTX_get_cb +EVP_PKEY_CTX_get_data +EVP_PKEY_CTX_get_keygen_info +EVP_PKEY_CTX_get_operation +EVP_PKEY_CTX_new +EVP_PKEY_CTX_new_id +EVP_PKEY_CTX_set0_keygen_info +EVP_PKEY_CTX_set_app_data +EVP_PKEY_CTX_set_cb +EVP_PKEY_CTX_set_data +EVP_PKEY_add1_attr +EVP_PKEY_add1_attr_by_NID +EVP_PKEY_add1_attr_by_OBJ +EVP_PKEY_add1_attr_by_txt +EVP_PKEY_asn1_add0 +EVP_PKEY_asn1_add_alias +EVP_PKEY_asn1_copy +EVP_PKEY_asn1_find +EVP_PKEY_asn1_find_str +EVP_PKEY_asn1_free +EVP_PKEY_asn1_get0 +EVP_PKEY_asn1_get0_info +EVP_PKEY_asn1_get_count +EVP_PKEY_asn1_new +EVP_PKEY_asn1_set_check +EVP_PKEY_asn1_set_ctrl +EVP_PKEY_asn1_set_free +EVP_PKEY_asn1_set_param +EVP_PKEY_asn1_set_param_check +EVP_PKEY_asn1_set_private +EVP_PKEY_asn1_set_public +EVP_PKEY_asn1_set_public_check +EVP_PKEY_asn1_set_security_bits +EVP_PKEY_assign +EVP_PKEY_base_id +EVP_PKEY_bits +EVP_PKEY_check +EVP_PKEY_cmp +EVP_PKEY_cmp_parameters +EVP_PKEY_copy_parameters +EVP_PKEY_decrypt +EVP_PKEY_decrypt_init +EVP_PKEY_decrypt_old +EVP_PKEY_delete_attr +EVP_PKEY_derive +EVP_PKEY_derive_init +EVP_PKEY_derive_set_peer +EVP_PKEY_encrypt +EVP_PKEY_encrypt_init +EVP_PKEY_encrypt_old +EVP_PKEY_free +EVP_PKEY_get0 +EVP_PKEY_get0_DH +EVP_PKEY_get0_DSA +EVP_PKEY_get0_EC_KEY +EVP_PKEY_get0_RSA +EVP_PKEY_get0_asn1 +EVP_PKEY_get0_hmac +EVP_PKEY_get1_DH +EVP_PKEY_get1_DSA +EVP_PKEY_get1_EC_KEY +EVP_PKEY_get1_RSA +EVP_PKEY_get_attr +EVP_PKEY_get_attr_by_NID +EVP_PKEY_get_attr_by_OBJ +EVP_PKEY_get_attr_count +EVP_PKEY_get_default_digest_nid +EVP_PKEY_get_raw_private_key +EVP_PKEY_get_raw_public_key +EVP_PKEY_id +EVP_PKEY_keygen +EVP_PKEY_keygen_init +EVP_PKEY_meth_add0 +EVP_PKEY_meth_copy +EVP_PKEY_meth_find +EVP_PKEY_meth_free +EVP_PKEY_meth_get0_info +EVP_PKEY_meth_new +EVP_PKEY_meth_set_check +EVP_PKEY_meth_set_cleanup +EVP_PKEY_meth_set_copy +EVP_PKEY_meth_set_ctrl +EVP_PKEY_meth_set_decrypt +EVP_PKEY_meth_set_derive +EVP_PKEY_meth_set_encrypt +EVP_PKEY_meth_set_init +EVP_PKEY_meth_set_keygen +EVP_PKEY_meth_set_param_check +EVP_PKEY_meth_set_paramgen +EVP_PKEY_meth_set_public_check +EVP_PKEY_meth_set_sign +EVP_PKEY_meth_set_signctx +EVP_PKEY_meth_set_verify +EVP_PKEY_meth_set_verify_recover +EVP_PKEY_meth_set_verifyctx +EVP_PKEY_missing_parameters +EVP_PKEY_new +EVP_PKEY_new_CMAC_key +EVP_PKEY_new_mac_key +EVP_PKEY_new_raw_private_key +EVP_PKEY_new_raw_public_key +EVP_PKEY_param_check +EVP_PKEY_paramgen +EVP_PKEY_paramgen_init +EVP_PKEY_print_params +EVP_PKEY_print_private +EVP_PKEY_print_public +EVP_PKEY_public_check +EVP_PKEY_save_parameters +EVP_PKEY_security_bits +EVP_PKEY_set1_DH +EVP_PKEY_set1_DSA +EVP_PKEY_set1_EC_KEY +EVP_PKEY_set1_RSA +EVP_PKEY_set_type +EVP_PKEY_set_type_str +EVP_PKEY_sign +EVP_PKEY_sign_init +EVP_PKEY_size +EVP_PKEY_type +EVP_PKEY_up_ref +EVP_PKEY_verify +EVP_PKEY_verify_init +EVP_PKEY_verify_recover +EVP_PKEY_verify_recover_init +EVP_SealFinal +EVP_SealInit +EVP_SignFinal +EVP_VerifyFinal +EVP_add_cipher +EVP_add_digest +EVP_aead_aes_128_gcm +EVP_aead_aes_256_gcm +EVP_aead_chacha20_poly1305 +EVP_aead_xchacha20_poly1305 +EVP_aes_128_cbc +EVP_aes_128_cbc_hmac_sha1 +EVP_aes_128_ccm +EVP_aes_128_cfb1 +EVP_aes_128_cfb128 +EVP_aes_128_cfb8 +EVP_aes_128_ctr +EVP_aes_128_ecb +EVP_aes_128_gcm +EVP_aes_128_ofb +EVP_aes_128_wrap +EVP_aes_128_xts +EVP_aes_192_cbc +EVP_aes_192_ccm +EVP_aes_192_cfb1 +EVP_aes_192_cfb128 +EVP_aes_192_cfb8 +EVP_aes_192_ctr +EVP_aes_192_ecb +EVP_aes_192_gcm +EVP_aes_192_ofb +EVP_aes_192_wrap +EVP_aes_256_cbc +EVP_aes_256_cbc_hmac_sha1 +EVP_aes_256_ccm +EVP_aes_256_cfb1 +EVP_aes_256_cfb128 +EVP_aes_256_cfb8 +EVP_aes_256_ctr +EVP_aes_256_ecb +EVP_aes_256_gcm +EVP_aes_256_ofb +EVP_aes_256_wrap +EVP_aes_256_xts +EVP_bf_cbc +EVP_bf_cfb64 +EVP_bf_ecb +EVP_bf_ofb +EVP_camellia_128_cbc +EVP_camellia_128_cfb1 +EVP_camellia_128_cfb128 +EVP_camellia_128_cfb8 +EVP_camellia_128_ecb +EVP_camellia_128_ofb +EVP_camellia_192_cbc +EVP_camellia_192_cfb1 +EVP_camellia_192_cfb128 +EVP_camellia_192_cfb8 +EVP_camellia_192_ecb +EVP_camellia_192_ofb +EVP_camellia_256_cbc +EVP_camellia_256_cfb1 +EVP_camellia_256_cfb128 +EVP_camellia_256_cfb8 +EVP_camellia_256_ecb +EVP_camellia_256_ofb +EVP_cast5_cbc +EVP_cast5_cfb64 +EVP_cast5_ecb +EVP_cast5_ofb +EVP_chacha20 +EVP_chacha20_poly1305 +EVP_cleanup +EVP_des_cbc +EVP_des_cfb1 +EVP_des_cfb64 +EVP_des_cfb8 +EVP_des_ecb +EVP_des_ede +EVP_des_ede3 +EVP_des_ede3_cbc +EVP_des_ede3_cfb1 +EVP_des_ede3_cfb64 +EVP_des_ede3_cfb8 +EVP_des_ede3_ecb +EVP_des_ede3_ofb +EVP_des_ede_cbc +EVP_des_ede_cfb64 +EVP_des_ede_ecb +EVP_des_ede_ofb +EVP_des_ofb +EVP_desx_cbc +EVP_enc_null +EVP_get_cipherbyname +EVP_get_digestbyname +EVP_get_pw_prompt +EVP_gost2814789_cfb64 +EVP_gost2814789_cnt +EVP_gost2814789_ecb +EVP_gost2814789imit +EVP_gostr341194 +EVP_idea_cbc +EVP_idea_cfb64 +EVP_idea_ecb +EVP_idea_ofb +EVP_md4 +EVP_md5 +EVP_md5_sha1 +EVP_md_null +EVP_rc2_40_cbc +EVP_rc2_64_cbc +EVP_rc2_cbc +EVP_rc2_cfb64 +EVP_rc2_ecb +EVP_rc2_ofb +EVP_rc4 +EVP_rc4_40 +EVP_rc4_hmac_md5 +EVP_read_pw_string +EVP_read_pw_string_min +EVP_ripemd160 +EVP_set_pw_prompt +EVP_sha1 +EVP_sha224 +EVP_sha256 +EVP_sha384 +EVP_sha3_224 +EVP_sha3_256 +EVP_sha3_384 +EVP_sha3_512 +EVP_sha512 +EVP_sha512_224 +EVP_sha512_256 +EVP_sm3 +EVP_sm4_cbc +EVP_sm4_cfb128 +EVP_sm4_ctr +EVP_sm4_ecb +EVP_sm4_ofb +EVP_streebog256 +EVP_streebog512 +EVP_whirlpool +EXTENDED_KEY_USAGE_free +EXTENDED_KEY_USAGE_it +EXTENDED_KEY_USAGE_new +FIPS_mode +FIPS_mode_set +GENERAL_NAMES_free +GENERAL_NAMES_it +GENERAL_NAMES_new +GENERAL_NAME_cmp +GENERAL_NAME_dup +GENERAL_NAME_free +GENERAL_NAME_get0_otherName +GENERAL_NAME_get0_value +GENERAL_NAME_it +GENERAL_NAME_new +GENERAL_NAME_print +GENERAL_NAME_set0_othername +GENERAL_NAME_set0_value +GENERAL_SUBTREE_free +GENERAL_SUBTREE_it +GENERAL_SUBTREE_new +GOST2814789IMIT +GOST2814789IMIT_Final +GOST2814789IMIT_Init +GOST2814789IMIT_Transform +GOST2814789IMIT_Update +GOSTR341194 +GOSTR341194_Final +GOSTR341194_Init +GOSTR341194_Transform +GOSTR341194_Update +GOST_CIPHER_PARAMS_free +GOST_CIPHER_PARAMS_it +GOST_CIPHER_PARAMS_new +GOST_KEY_check_key +GOST_KEY_free +GOST_KEY_get0_group +GOST_KEY_get0_private_key +GOST_KEY_get0_public_key +GOST_KEY_get_digest +GOST_KEY_get_size +GOST_KEY_new +GOST_KEY_set_digest +GOST_KEY_set_group +GOST_KEY_set_private_key +GOST_KEY_set_public_key +GOST_KEY_set_public_key_affine_coordinates +Gost2814789_cfb64_encrypt +Gost2814789_cnt_encrypt +Gost2814789_ecb_encrypt +Gost2814789_set_key +Gost2814789_set_sbox +HKDF +HKDF_expand +HKDF_extract +HMAC +HMAC_CTX_copy +HMAC_CTX_free +HMAC_CTX_get_md +HMAC_CTX_new +HMAC_CTX_reset +HMAC_CTX_set_flags +HMAC_Final +HMAC_Init +HMAC_Init_ex +HMAC_Update +IPAddressChoice_free +IPAddressChoice_it +IPAddressChoice_new +IPAddressFamily_free +IPAddressFamily_it +IPAddressFamily_new +IPAddressOrRange_free +IPAddressOrRange_it +IPAddressOrRange_new +IPAddressRange_free +IPAddressRange_it +IPAddressRange_new +ISSUING_DIST_POINT_free +ISSUING_DIST_POINT_it +ISSUING_DIST_POINT_new +LONG_it +MD4 +MD4_Final +MD4_Init +MD4_Transform +MD4_Update +MD5 +MD5_Final +MD5_Init +MD5_Transform +MD5_Update +NAME_CONSTRAINTS_check +NAME_CONSTRAINTS_free +NAME_CONSTRAINTS_it +NAME_CONSTRAINTS_new +NCONF_WIN32 +NCONF_default +NCONF_dump_bio +NCONF_dump_fp +NCONF_free +NCONF_free_data +NCONF_get_number_e +NCONF_get_section +NCONF_get_string +NCONF_load +NCONF_load_bio +NCONF_load_fp +NCONF_new +NETSCAPE_SPKAC_free +NETSCAPE_SPKAC_it +NETSCAPE_SPKAC_new +NETSCAPE_SPKI_b64_decode +NETSCAPE_SPKI_b64_encode +NETSCAPE_SPKI_free +NETSCAPE_SPKI_get_pubkey +NETSCAPE_SPKI_it +NETSCAPE_SPKI_new +NETSCAPE_SPKI_print +NETSCAPE_SPKI_set_pubkey +NETSCAPE_SPKI_sign +NETSCAPE_SPKI_verify +NOTICEREF_free +NOTICEREF_it +NOTICEREF_new +OBJ_NAME_add +OBJ_NAME_cleanup +OBJ_NAME_do_all +OBJ_NAME_do_all_sorted +OBJ_NAME_get +OBJ_NAME_init +OBJ_NAME_new_index +OBJ_NAME_remove +OBJ_add_object +OBJ_bsearch_ +OBJ_cleanup +OBJ_cmp +OBJ_create +OBJ_create_objects +OBJ_dup +OBJ_find_sigid_algs +OBJ_find_sigid_by_algs +OBJ_get0_data +OBJ_length +OBJ_ln2nid +OBJ_new_nid +OBJ_nid2ln +OBJ_nid2obj +OBJ_nid2sn +OBJ_obj2nid +OBJ_obj2txt +OBJ_sn2nid +OBJ_txt2nid +OBJ_txt2obj +OCSP_BASICRESP_add1_ext_i2d +OCSP_BASICRESP_add_ext +OCSP_BASICRESP_delete_ext +OCSP_BASICRESP_free +OCSP_BASICRESP_get1_ext_d2i +OCSP_BASICRESP_get_ext +OCSP_BASICRESP_get_ext_by_NID +OCSP_BASICRESP_get_ext_by_OBJ +OCSP_BASICRESP_get_ext_by_critical +OCSP_BASICRESP_get_ext_count +OCSP_BASICRESP_it +OCSP_BASICRESP_new +OCSP_CERTID_dup +OCSP_CERTID_free +OCSP_CERTID_it +OCSP_CERTID_new +OCSP_CERTSTATUS_free +OCSP_CERTSTATUS_it +OCSP_CERTSTATUS_new +OCSP_CRLID_free +OCSP_CRLID_it +OCSP_CRLID_new +OCSP_ONEREQ_add1_ext_i2d +OCSP_ONEREQ_add_ext +OCSP_ONEREQ_delete_ext +OCSP_ONEREQ_free +OCSP_ONEREQ_get1_ext_d2i +OCSP_ONEREQ_get_ext +OCSP_ONEREQ_get_ext_by_NID +OCSP_ONEREQ_get_ext_by_OBJ +OCSP_ONEREQ_get_ext_by_critical +OCSP_ONEREQ_get_ext_count +OCSP_ONEREQ_it +OCSP_ONEREQ_new +OCSP_REQINFO_free +OCSP_REQINFO_it +OCSP_REQINFO_new +OCSP_REQUEST_add1_ext_i2d +OCSP_REQUEST_add_ext +OCSP_REQUEST_delete_ext +OCSP_REQUEST_free +OCSP_REQUEST_get1_ext_d2i +OCSP_REQUEST_get_ext +OCSP_REQUEST_get_ext_by_NID +OCSP_REQUEST_get_ext_by_OBJ +OCSP_REQUEST_get_ext_by_critical +OCSP_REQUEST_get_ext_count +OCSP_REQUEST_it +OCSP_REQUEST_new +OCSP_REQUEST_print +OCSP_REQ_CTX_add1_header +OCSP_REQ_CTX_free +OCSP_REQ_CTX_set1_req +OCSP_RESPBYTES_free +OCSP_RESPBYTES_it +OCSP_RESPBYTES_new +OCSP_RESPDATA_free +OCSP_RESPDATA_it +OCSP_RESPDATA_new +OCSP_RESPID_free +OCSP_RESPID_it +OCSP_RESPID_new +OCSP_RESPONSE_free +OCSP_RESPONSE_it +OCSP_RESPONSE_new +OCSP_RESPONSE_print +OCSP_REVOKEDINFO_free +OCSP_REVOKEDINFO_it +OCSP_REVOKEDINFO_new +OCSP_SERVICELOC_free +OCSP_SERVICELOC_it +OCSP_SERVICELOC_new +OCSP_SIGNATURE_free +OCSP_SIGNATURE_it +OCSP_SIGNATURE_new +OCSP_SINGLERESP_add1_ext_i2d +OCSP_SINGLERESP_add_ext +OCSP_SINGLERESP_delete_ext +OCSP_SINGLERESP_free +OCSP_SINGLERESP_get0_id +OCSP_SINGLERESP_get1_ext_d2i +OCSP_SINGLERESP_get_ext +OCSP_SINGLERESP_get_ext_by_NID +OCSP_SINGLERESP_get_ext_by_OBJ +OCSP_SINGLERESP_get_ext_by_critical +OCSP_SINGLERESP_get_ext_count +OCSP_SINGLERESP_it +OCSP_SINGLERESP_new +OCSP_accept_responses_new +OCSP_archive_cutoff_new +OCSP_basic_add1_cert +OCSP_basic_add1_nonce +OCSP_basic_add1_status +OCSP_basic_sign +OCSP_basic_verify +OCSP_cert_id_new +OCSP_cert_status_str +OCSP_cert_to_id +OCSP_check_nonce +OCSP_check_validity +OCSP_copy_nonce +OCSP_crlID_new +OCSP_crl_reason_str +OCSP_id_cmp +OCSP_id_get0_info +OCSP_id_issuer_cmp +OCSP_onereq_get0_id +OCSP_parse_url +OCSP_request_add0_id +OCSP_request_add1_cert +OCSP_request_add1_nonce +OCSP_request_is_signed +OCSP_request_onereq_count +OCSP_request_onereq_get0 +OCSP_request_set1_name +OCSP_request_sign +OCSP_request_verify +OCSP_resp_count +OCSP_resp_find +OCSP_resp_find_status +OCSP_resp_get0 +OCSP_resp_get0_certs +OCSP_resp_get0_id +OCSP_resp_get0_produced_at +OCSP_resp_get0_respdata +OCSP_resp_get0_signature +OCSP_resp_get0_signer +OCSP_resp_get0_tbs_sigalg +OCSP_response_create +OCSP_response_get1_basic +OCSP_response_status +OCSP_response_status_str +OCSP_sendreq_bio +OCSP_sendreq_nbio +OCSP_sendreq_new +OCSP_single_get0_status +OCSP_url_svcloc_new +OPENSSL_add_all_algorithms_conf +OPENSSL_add_all_algorithms_noconf +OPENSSL_asc2uni +OPENSSL_cleanse +OPENSSL_cleanup +OPENSSL_config +OPENSSL_cpu_caps +OPENSSL_cpuid_setup +OPENSSL_init +OPENSSL_init_crypto +OPENSSL_load_builtin_modules +OPENSSL_no_config +OPENSSL_strcasecmp +OPENSSL_strncasecmp +OPENSSL_uni2asc +OTHERNAME_cmp +OTHERNAME_free +OTHERNAME_it +OTHERNAME_new +OpenSSLDie +OpenSSL_add_all_ciphers +OpenSSL_add_all_digests +OpenSSL_version +OpenSSL_version_num +PBE2PARAM_free +PBE2PARAM_it +PBE2PARAM_new +PBEPARAM_free +PBEPARAM_it +PBEPARAM_new +PBKDF2PARAM_free +PBKDF2PARAM_it +PBKDF2PARAM_new +PEM_ASN1_read +PEM_ASN1_read_bio +PEM_ASN1_write +PEM_ASN1_write_bio +PEM_SignFinal +PEM_SignInit +PEM_SignUpdate +PEM_X509_INFO_read +PEM_X509_INFO_read_bio +PEM_X509_INFO_write_bio +PEM_bytes_read_bio +PEM_def_callback +PEM_dek_info +PEM_do_header +PEM_get_EVP_CIPHER_INFO +PEM_proc_type +PEM_read +PEM_read_CMS +PEM_read_DHparams +PEM_read_DSAPrivateKey +PEM_read_DSA_PUBKEY +PEM_read_DSAparams +PEM_read_ECPKParameters +PEM_read_ECPrivateKey +PEM_read_EC_PUBKEY +PEM_read_PKCS7 +PEM_read_PKCS8 +PEM_read_PKCS8_PRIV_KEY_INFO +PEM_read_PUBKEY +PEM_read_PrivateKey +PEM_read_RSAPrivateKey +PEM_read_RSAPublicKey +PEM_read_RSA_PUBKEY +PEM_read_X509 +PEM_read_X509_AUX +PEM_read_X509_CRL +PEM_read_X509_REQ +PEM_read_bio +PEM_read_bio_CMS +PEM_read_bio_DHparams +PEM_read_bio_DSAPrivateKey +PEM_read_bio_DSA_PUBKEY +PEM_read_bio_DSAparams +PEM_read_bio_ECPKParameters +PEM_read_bio_ECPrivateKey +PEM_read_bio_EC_PUBKEY +PEM_read_bio_PKCS7 +PEM_read_bio_PKCS8 +PEM_read_bio_PKCS8_PRIV_KEY_INFO +PEM_read_bio_PUBKEY +PEM_read_bio_Parameters +PEM_read_bio_PrivateKey +PEM_read_bio_RSAPrivateKey +PEM_read_bio_RSAPublicKey +PEM_read_bio_RSA_PUBKEY +PEM_read_bio_X509 +PEM_read_bio_X509_AUX +PEM_read_bio_X509_CRL +PEM_read_bio_X509_REQ +PEM_write +PEM_write_CMS +PEM_write_DHparams +PEM_write_DSAPrivateKey +PEM_write_DSA_PUBKEY +PEM_write_DSAparams +PEM_write_ECPKParameters +PEM_write_ECPrivateKey +PEM_write_EC_PUBKEY +PEM_write_PKCS7 +PEM_write_PKCS8 +PEM_write_PKCS8PrivateKey +PEM_write_PKCS8PrivateKey_nid +PEM_write_PKCS8_PRIV_KEY_INFO +PEM_write_PUBKEY +PEM_write_PrivateKey +PEM_write_RSAPrivateKey +PEM_write_RSAPublicKey +PEM_write_RSA_PUBKEY +PEM_write_X509 +PEM_write_X509_AUX +PEM_write_X509_CRL +PEM_write_X509_REQ +PEM_write_X509_REQ_NEW +PEM_write_bio +PEM_write_bio_CMS +PEM_write_bio_CMS_stream +PEM_write_bio_DHparams +PEM_write_bio_DSAPrivateKey +PEM_write_bio_DSA_PUBKEY +PEM_write_bio_DSAparams +PEM_write_bio_ECPKParameters +PEM_write_bio_ECPrivateKey +PEM_write_bio_EC_PUBKEY +PEM_write_bio_PKCS7 +PEM_write_bio_PKCS7_stream +PEM_write_bio_PKCS8 +PEM_write_bio_PKCS8PrivateKey +PEM_write_bio_PKCS8PrivateKey_nid +PEM_write_bio_PKCS8_PRIV_KEY_INFO +PEM_write_bio_PUBKEY +PEM_write_bio_Parameters +PEM_write_bio_PrivateKey +PEM_write_bio_PrivateKey_traditional +PEM_write_bio_RSAPrivateKey +PEM_write_bio_RSAPublicKey +PEM_write_bio_RSA_PUBKEY +PEM_write_bio_X509 +PEM_write_bio_X509_AUX +PEM_write_bio_X509_CRL +PEM_write_bio_X509_REQ +PEM_write_bio_X509_REQ_NEW +PKCS12_AUTHSAFES_it +PKCS12_BAGS_free +PKCS12_BAGS_it +PKCS12_BAGS_new +PKCS12_MAC_DATA_free +PKCS12_MAC_DATA_it +PKCS12_MAC_DATA_new +PKCS12_PBE_add +PKCS12_PBE_keyivgen +PKCS12_SAFEBAGS_it +PKCS12_SAFEBAG_create0_p8inf +PKCS12_SAFEBAG_create0_pkcs8 +PKCS12_SAFEBAG_create_cert +PKCS12_SAFEBAG_create_crl +PKCS12_SAFEBAG_create_pkcs8_encrypt +PKCS12_SAFEBAG_free +PKCS12_SAFEBAG_get0_attr +PKCS12_SAFEBAG_get0_attrs +PKCS12_SAFEBAG_get0_p8inf +PKCS12_SAFEBAG_get0_pkcs8 +PKCS12_SAFEBAG_get0_safes +PKCS12_SAFEBAG_get0_type +PKCS12_SAFEBAG_get1_cert +PKCS12_SAFEBAG_get1_crl +PKCS12_SAFEBAG_get_bag_nid +PKCS12_SAFEBAG_get_nid +PKCS12_SAFEBAG_it +PKCS12_SAFEBAG_new +PKCS12_add_CSPName_asc +PKCS12_add_cert +PKCS12_add_friendlyname_asc +PKCS12_add_friendlyname_uni +PKCS12_add_key +PKCS12_add_localkeyid +PKCS12_add_safe +PKCS12_add_safes +PKCS12_create +PKCS12_decrypt_skey +PKCS12_free +PKCS12_gen_mac +PKCS12_get0_mac +PKCS12_get_attr_gen +PKCS12_get_friendlyname +PKCS12_init +PKCS12_it +PKCS12_item_decrypt_d2i +PKCS12_item_i2d_encrypt +PKCS12_item_pack_safebag +PKCS12_key_gen_asc +PKCS12_key_gen_uni +PKCS12_mac_present +PKCS12_new +PKCS12_newpass +PKCS12_pack_authsafes +PKCS12_pack_p7data +PKCS12_pack_p7encdata +PKCS12_parse +PKCS12_pbe_crypt +PKCS12_set_mac +PKCS12_setup_mac +PKCS12_unpack_authsafes +PKCS12_unpack_p7data +PKCS12_unpack_p7encdata +PKCS12_verify_mac +PKCS1_MGF1 +PKCS5_PBE_add +PKCS5_PBE_keyivgen +PKCS5_PBKDF2_HMAC +PKCS5_PBKDF2_HMAC_SHA1 +PKCS5_pbe2_set +PKCS5_pbe2_set_iv +PKCS5_pbe_set +PKCS5_pbe_set0_algor +PKCS5_pbkdf2_set +PKCS5_v2_PBE_keyivgen +PKCS7_ATTR_SIGN_it +PKCS7_ATTR_VERIFY_it +PKCS7_DIGEST_free +PKCS7_DIGEST_it +PKCS7_DIGEST_new +PKCS7_ENCRYPT_free +PKCS7_ENCRYPT_it +PKCS7_ENCRYPT_new +PKCS7_ENC_CONTENT_free +PKCS7_ENC_CONTENT_it +PKCS7_ENC_CONTENT_new +PKCS7_ENVELOPE_free +PKCS7_ENVELOPE_it +PKCS7_ENVELOPE_new +PKCS7_ISSUER_AND_SERIAL_digest +PKCS7_ISSUER_AND_SERIAL_free +PKCS7_ISSUER_AND_SERIAL_it +PKCS7_ISSUER_AND_SERIAL_new +PKCS7_RECIP_INFO_free +PKCS7_RECIP_INFO_get0_alg +PKCS7_RECIP_INFO_it +PKCS7_RECIP_INFO_new +PKCS7_RECIP_INFO_set +PKCS7_SIGNED_free +PKCS7_SIGNED_it +PKCS7_SIGNED_new +PKCS7_SIGNER_INFO_free +PKCS7_SIGNER_INFO_get0_algs +PKCS7_SIGNER_INFO_it +PKCS7_SIGNER_INFO_new +PKCS7_SIGNER_INFO_set +PKCS7_SIGNER_INFO_sign +PKCS7_SIGN_ENVELOPE_free +PKCS7_SIGN_ENVELOPE_it +PKCS7_SIGN_ENVELOPE_new +PKCS7_add0_attrib_signing_time +PKCS7_add1_attrib_digest +PKCS7_add_attrib_content_type +PKCS7_add_attrib_smimecap +PKCS7_add_attribute +PKCS7_add_certificate +PKCS7_add_crl +PKCS7_add_recipient +PKCS7_add_recipient_info +PKCS7_add_signature +PKCS7_add_signed_attribute +PKCS7_add_signer +PKCS7_cert_from_signer_info +PKCS7_content_new +PKCS7_ctrl +PKCS7_dataDecode +PKCS7_dataFinal +PKCS7_dataInit +PKCS7_dataVerify +PKCS7_decrypt +PKCS7_digest_from_attributes +PKCS7_dup +PKCS7_encrypt +PKCS7_final +PKCS7_free +PKCS7_get0_signers +PKCS7_get_attribute +PKCS7_get_issuer_and_serial +PKCS7_get_signed_attribute +PKCS7_get_signer_info +PKCS7_get_smimecap +PKCS7_it +PKCS7_new +PKCS7_print_ctx +PKCS7_set0_type_other +PKCS7_set_attributes +PKCS7_set_cipher +PKCS7_set_content +PKCS7_set_digest +PKCS7_set_signed_attributes +PKCS7_set_type +PKCS7_sign +PKCS7_sign_add_signer +PKCS7_signatureVerify +PKCS7_simple_smimecap +PKCS7_stream +PKCS7_to_TS_TST_INFO +PKCS7_verify +PKCS8_PRIV_KEY_INFO_free +PKCS8_PRIV_KEY_INFO_it +PKCS8_PRIV_KEY_INFO_new +PKCS8_add_keyusage +PKCS8_decrypt +PKCS8_encrypt +PKCS8_get_attr +PKCS8_pkey_add1_attr_by_NID +PKCS8_pkey_get0 +PKCS8_pkey_get0_attrs +PKCS8_pkey_set0 +PKEY_USAGE_PERIOD_free +PKEY_USAGE_PERIOD_it +PKEY_USAGE_PERIOD_new +POLICYINFO_free +POLICYINFO_it +POLICYINFO_new +POLICYQUALINFO_free +POLICYQUALINFO_it +POLICYQUALINFO_new +POLICY_CONSTRAINTS_free +POLICY_CONSTRAINTS_it +POLICY_CONSTRAINTS_new +POLICY_MAPPINGS_it +POLICY_MAPPING_free +POLICY_MAPPING_it +POLICY_MAPPING_new +RAND_SSLeay +RAND_add +RAND_bytes +RAND_cleanup +RAND_file_name +RAND_get_rand_method +RAND_load_file +RAND_poll +RAND_pseudo_bytes +RAND_seed +RAND_set_rand_method +RAND_status +RAND_write_file +RC2_cbc_encrypt +RC2_cfb64_encrypt +RC2_decrypt +RC2_ecb_encrypt +RC2_encrypt +RC2_ofb64_encrypt +RC2_set_key +RC4 +RC4_set_key +RIPEMD160 +RIPEMD160_Final +RIPEMD160_Init +RIPEMD160_Transform +RIPEMD160_Update +RSAPrivateKey_dup +RSAPrivateKey_it +RSAPublicKey_dup +RSAPublicKey_it +RSA_OAEP_PARAMS_free +RSA_OAEP_PARAMS_it +RSA_OAEP_PARAMS_new +RSA_PKCS1_OpenSSL +RSA_PKCS1_SSLeay +RSA_PSS_PARAMS_free +RSA_PSS_PARAMS_it +RSA_PSS_PARAMS_new +RSA_bits +RSA_blinding_off +RSA_blinding_on +RSA_check_key +RSA_clear_flags +RSA_flags +RSA_free +RSA_generate_key +RSA_generate_key_ex +RSA_get0_crt_params +RSA_get0_d +RSA_get0_dmp1 +RSA_get0_dmq1 +RSA_get0_e +RSA_get0_factors +RSA_get0_iqmp +RSA_get0_key +RSA_get0_n +RSA_get0_p +RSA_get0_pss_params +RSA_get0_q +RSA_get_default_method +RSA_get_ex_data +RSA_get_ex_new_index +RSA_get_method +RSA_meth_dup +RSA_meth_free +RSA_meth_get0_app_data +RSA_meth_get0_name +RSA_meth_get_bn_mod_exp +RSA_meth_get_finish +RSA_meth_get_flags +RSA_meth_get_init +RSA_meth_get_keygen +RSA_meth_get_mod_exp +RSA_meth_get_priv_dec +RSA_meth_get_priv_enc +RSA_meth_get_pub_dec +RSA_meth_get_pub_enc +RSA_meth_get_sign +RSA_meth_get_verify +RSA_meth_new +RSA_meth_set0_app_data +RSA_meth_set1_name +RSA_meth_set_bn_mod_exp +RSA_meth_set_finish +RSA_meth_set_flags +RSA_meth_set_init +RSA_meth_set_keygen +RSA_meth_set_mod_exp +RSA_meth_set_priv_dec +RSA_meth_set_priv_enc +RSA_meth_set_pub_dec +RSA_meth_set_pub_enc +RSA_meth_set_sign +RSA_meth_set_verify +RSA_new +RSA_new_method +RSA_padding_add_PKCS1_OAEP +RSA_padding_add_PKCS1_OAEP_mgf1 +RSA_padding_add_PKCS1_PSS +RSA_padding_add_PKCS1_PSS_mgf1 +RSA_padding_add_PKCS1_type_1 +RSA_padding_add_PKCS1_type_2 +RSA_padding_add_none +RSA_padding_check_PKCS1_OAEP +RSA_padding_check_PKCS1_OAEP_mgf1 +RSA_padding_check_PKCS1_type_1 +RSA_padding_check_PKCS1_type_2 +RSA_padding_check_none +RSA_pkey_ctx_ctrl +RSA_print +RSA_print_fp +RSA_private_decrypt +RSA_private_encrypt +RSA_public_decrypt +RSA_public_encrypt +RSA_security_bits +RSA_set0_crt_params +RSA_set0_factors +RSA_set0_key +RSA_set_default_method +RSA_set_ex_data +RSA_set_flags +RSA_set_method +RSA_sign +RSA_sign_ASN1_OCTET_STRING +RSA_size +RSA_test_flags +RSA_up_ref +RSA_verify +RSA_verify_ASN1_OCTET_STRING +RSA_verify_PKCS1_PSS +RSA_verify_PKCS1_PSS_mgf1 +SCT_LIST_free +SCT_LIST_print +SCT_LIST_validate +SCT_free +SCT_get0_extensions +SCT_get0_log_id +SCT_get0_signature +SCT_get_log_entry_type +SCT_get_signature_nid +SCT_get_source +SCT_get_timestamp +SCT_get_validation_status +SCT_get_version +SCT_new +SCT_new_from_base64 +SCT_print +SCT_set0_extensions +SCT_set0_log_id +SCT_set0_signature +SCT_set1_extensions +SCT_set1_log_id +SCT_set1_signature +SCT_set_log_entry_type +SCT_set_signature_nid +SCT_set_source +SCT_set_timestamp +SCT_set_version +SCT_validate +SCT_validation_status_string +SHA1 +SHA1_Final +SHA1_Init +SHA1_Transform +SHA1_Update +SHA224 +SHA224_Final +SHA224_Init +SHA224_Update +SHA256 +SHA256_Final +SHA256_Init +SHA256_Transform +SHA256_Update +SHA384 +SHA384_Final +SHA384_Init +SHA384_Update +SHA512 +SHA512_Final +SHA512_Init +SHA512_Transform +SHA512_Update +SM3_Final +SM3_Init +SM3_Update +SM4_decrypt +SM4_encrypt +SM4_set_key +SMIME_crlf_copy +SMIME_read_CMS +SMIME_read_PKCS7 +SMIME_text +SMIME_write_CMS +SMIME_write_PKCS7 +SSLeay +SSLeay_version +STREEBOG256 +STREEBOG256_Final +STREEBOG256_Init +STREEBOG256_Update +STREEBOG512 +STREEBOG512_Final +STREEBOG512_Init +STREEBOG512_Transform +STREEBOG512_Update +TS_ACCURACY_dup +TS_ACCURACY_free +TS_ACCURACY_get_micros +TS_ACCURACY_get_millis +TS_ACCURACY_get_seconds +TS_ACCURACY_it +TS_ACCURACY_new +TS_ACCURACY_set_micros +TS_ACCURACY_set_millis +TS_ACCURACY_set_seconds +TS_ASN1_INTEGER_print_bio +TS_CONF_get_tsa_section +TS_CONF_load_cert +TS_CONF_load_certs +TS_CONF_load_key +TS_CONF_set_accuracy +TS_CONF_set_certs +TS_CONF_set_clock_precision_digits +TS_CONF_set_def_policy +TS_CONF_set_digests +TS_CONF_set_ess_cert_id_chain +TS_CONF_set_ordering +TS_CONF_set_policies +TS_CONF_set_serial +TS_CONF_set_signer_cert +TS_CONF_set_signer_key +TS_CONF_set_tsa_name +TS_MSG_IMPRINT_dup +TS_MSG_IMPRINT_free +TS_MSG_IMPRINT_get_algo +TS_MSG_IMPRINT_get_msg +TS_MSG_IMPRINT_it +TS_MSG_IMPRINT_new +TS_MSG_IMPRINT_print_bio +TS_MSG_IMPRINT_set_algo +TS_MSG_IMPRINT_set_msg +TS_OBJ_print_bio +TS_REQ_add_ext +TS_REQ_delete_ext +TS_REQ_dup +TS_REQ_ext_free +TS_REQ_free +TS_REQ_get_cert_req +TS_REQ_get_ext +TS_REQ_get_ext_by_NID +TS_REQ_get_ext_by_OBJ +TS_REQ_get_ext_by_critical +TS_REQ_get_ext_count +TS_REQ_get_ext_d2i +TS_REQ_get_exts +TS_REQ_get_msg_imprint +TS_REQ_get_nonce +TS_REQ_get_policy_id +TS_REQ_get_version +TS_REQ_it +TS_REQ_new +TS_REQ_print_bio +TS_REQ_set_cert_req +TS_REQ_set_msg_imprint +TS_REQ_set_nonce +TS_REQ_set_policy_id +TS_REQ_set_version +TS_REQ_to_TS_VERIFY_CTX +TS_RESP_CTX_add_failure_info +TS_RESP_CTX_add_flags +TS_RESP_CTX_add_md +TS_RESP_CTX_add_policy +TS_RESP_CTX_free +TS_RESP_CTX_get_request +TS_RESP_CTX_get_tst_info +TS_RESP_CTX_new +TS_RESP_CTX_set_accuracy +TS_RESP_CTX_set_certs +TS_RESP_CTX_set_clock_precision_digits +TS_RESP_CTX_set_def_policy +TS_RESP_CTX_set_extension_cb +TS_RESP_CTX_set_serial_cb +TS_RESP_CTX_set_signer_cert +TS_RESP_CTX_set_signer_key +TS_RESP_CTX_set_status_info +TS_RESP_CTX_set_status_info_cond +TS_RESP_CTX_set_time_cb +TS_RESP_create_response +TS_RESP_dup +TS_RESP_free +TS_RESP_get_status_info +TS_RESP_get_token +TS_RESP_get_tst_info +TS_RESP_it +TS_RESP_new +TS_RESP_print_bio +TS_RESP_set_status_info +TS_RESP_set_tst_info +TS_RESP_verify_response +TS_RESP_verify_signature +TS_RESP_verify_token +TS_STATUS_INFO_dup +TS_STATUS_INFO_free +TS_STATUS_INFO_get0_failure_info +TS_STATUS_INFO_get0_status +TS_STATUS_INFO_get0_text +TS_STATUS_INFO_it +TS_STATUS_INFO_new +TS_STATUS_INFO_print_bio +TS_STATUS_INFO_set_status +TS_TST_INFO_add_ext +TS_TST_INFO_delete_ext +TS_TST_INFO_dup +TS_TST_INFO_ext_free +TS_TST_INFO_free +TS_TST_INFO_get_accuracy +TS_TST_INFO_get_ext +TS_TST_INFO_get_ext_by_NID +TS_TST_INFO_get_ext_by_OBJ +TS_TST_INFO_get_ext_by_critical +TS_TST_INFO_get_ext_count +TS_TST_INFO_get_ext_d2i +TS_TST_INFO_get_exts +TS_TST_INFO_get_msg_imprint +TS_TST_INFO_get_nonce +TS_TST_INFO_get_ordering +TS_TST_INFO_get_policy_id +TS_TST_INFO_get_serial +TS_TST_INFO_get_time +TS_TST_INFO_get_tsa +TS_TST_INFO_get_version +TS_TST_INFO_it +TS_TST_INFO_new +TS_TST_INFO_print_bio +TS_TST_INFO_set_accuracy +TS_TST_INFO_set_msg_imprint +TS_TST_INFO_set_nonce +TS_TST_INFO_set_ordering +TS_TST_INFO_set_policy_id +TS_TST_INFO_set_serial +TS_TST_INFO_set_time +TS_TST_INFO_set_tsa +TS_TST_INFO_set_version +TS_VERIFY_CTX_add_flags +TS_VERIFY_CTX_cleanup +TS_VERIFY_CTX_free +TS_VERIFY_CTX_new +TS_VERIFY_CTX_set_certs +TS_VERIFY_CTX_set_data +TS_VERIFY_CTX_set_flags +TS_VERIFY_CTX_set_imprint +TS_VERIFY_CTX_set_store +TS_X509_ALGOR_print_bio +TS_ext_print_bio +TXT_DB_create_index +TXT_DB_free +TXT_DB_get_by_index +TXT_DB_insert +TXT_DB_read +TXT_DB_write +UI_OpenSSL +UI_UTIL_read_pw +UI_UTIL_read_pw_string +UI_add_error_string +UI_add_info_string +UI_add_input_boolean +UI_add_input_string +UI_add_user_data +UI_add_verify_string +UI_construct_prompt +UI_create_method +UI_ctrl +UI_destroy_method +UI_dup_error_string +UI_dup_info_string +UI_dup_input_boolean +UI_dup_input_string +UI_dup_verify_string +UI_free +UI_get0_action_string +UI_get0_output_string +UI_get0_result +UI_get0_result_string +UI_get0_test_string +UI_get0_user_data +UI_get_default_method +UI_get_ex_data +UI_get_ex_new_index +UI_get_input_flags +UI_get_method +UI_get_result_maxsize +UI_get_result_minsize +UI_get_string_type +UI_method_get_closer +UI_method_get_flusher +UI_method_get_opener +UI_method_get_prompt_constructor +UI_method_get_reader +UI_method_get_writer +UI_method_set_closer +UI_method_set_flusher +UI_method_set_opener +UI_method_set_prompt_constructor +UI_method_set_reader +UI_method_set_writer +UI_new +UI_new_method +UI_null +UI_process +UI_set_default_method +UI_set_ex_data +UI_set_method +UI_set_result +USERNOTICE_free +USERNOTICE_it +USERNOTICE_new +WHIRLPOOL +WHIRLPOOL_BitUpdate +WHIRLPOOL_Final +WHIRLPOOL_Init +WHIRLPOOL_Update +X25519 +X25519_keypair +X509V3_EXT_CRL_add_conf +X509V3_EXT_CRL_add_nconf +X509V3_EXT_REQ_add_conf +X509V3_EXT_REQ_add_nconf +X509V3_EXT_add +X509V3_EXT_add_alias +X509V3_EXT_add_conf +X509V3_EXT_add_list +X509V3_EXT_add_nconf +X509V3_EXT_add_nconf_sk +X509V3_EXT_cleanup +X509V3_EXT_conf +X509V3_EXT_conf_nid +X509V3_EXT_d2i +X509V3_EXT_get +X509V3_EXT_get_nid +X509V3_EXT_i2d +X509V3_EXT_nconf +X509V3_EXT_nconf_nid +X509V3_EXT_print +X509V3_EXT_print_fp +X509V3_EXT_val_prn +X509V3_NAME_from_section +X509V3_add1_i2d +X509V3_add_standard_extensions +X509V3_add_value +X509V3_add_value_bool +X509V3_add_value_bool_nf +X509V3_add_value_int +X509V3_add_value_uchar +X509V3_conf_free +X509V3_extensions_print +X509V3_get_d2i +X509V3_get_section +X509V3_get_string +X509V3_get_value_bool +X509V3_get_value_int +X509V3_parse_list +X509V3_section_free +X509V3_set_conf_lhash +X509V3_set_ctx +X509V3_set_nconf +X509V3_string_free +X509_ALGORS_it +X509_ALGOR_cmp +X509_ALGOR_dup +X509_ALGOR_free +X509_ALGOR_get0 +X509_ALGOR_it +X509_ALGOR_new +X509_ALGOR_set0 +X509_ALGOR_set_md +X509_ATTRIBUTE_count +X509_ATTRIBUTE_create +X509_ATTRIBUTE_create_by_NID +X509_ATTRIBUTE_create_by_OBJ +X509_ATTRIBUTE_create_by_txt +X509_ATTRIBUTE_dup +X509_ATTRIBUTE_free +X509_ATTRIBUTE_get0_data +X509_ATTRIBUTE_get0_object +X509_ATTRIBUTE_get0_type +X509_ATTRIBUTE_it +X509_ATTRIBUTE_new +X509_ATTRIBUTE_set1_data +X509_ATTRIBUTE_set1_object +X509_CERT_AUX_free +X509_CERT_AUX_it +X509_CERT_AUX_new +X509_CERT_AUX_print +X509_CINF_free +X509_CINF_it +X509_CINF_new +X509_CRL_INFO_free +X509_CRL_INFO_it +X509_CRL_INFO_new +X509_CRL_METHOD_free +X509_CRL_METHOD_new +X509_CRL_add0_revoked +X509_CRL_add1_ext_i2d +X509_CRL_add_ext +X509_CRL_cmp +X509_CRL_delete_ext +X509_CRL_digest +X509_CRL_dup +X509_CRL_free +X509_CRL_get0_by_cert +X509_CRL_get0_by_serial +X509_CRL_get0_extensions +X509_CRL_get0_lastUpdate +X509_CRL_get0_nextUpdate +X509_CRL_get0_signature +X509_CRL_get0_tbs_sigalg +X509_CRL_get_REVOKED +X509_CRL_get_ext +X509_CRL_get_ext_by_NID +X509_CRL_get_ext_by_OBJ +X509_CRL_get_ext_by_critical +X509_CRL_get_ext_count +X509_CRL_get_ext_d2i +X509_CRL_get_issuer +X509_CRL_get_lastUpdate +X509_CRL_get_meth_data +X509_CRL_get_nextUpdate +X509_CRL_get_signature_nid +X509_CRL_get_version +X509_CRL_it +X509_CRL_match +X509_CRL_new +X509_CRL_print +X509_CRL_print_fp +X509_CRL_set1_lastUpdate +X509_CRL_set1_nextUpdate +X509_CRL_set_default_method +X509_CRL_set_issuer_name +X509_CRL_set_lastUpdate +X509_CRL_set_meth_data +X509_CRL_set_nextUpdate +X509_CRL_set_version +X509_CRL_sign +X509_CRL_sign_ctx +X509_CRL_sort +X509_CRL_up_ref +X509_CRL_verify +X509_EXTENSIONS_it +X509_EXTENSION_create_by_NID +X509_EXTENSION_create_by_OBJ +X509_EXTENSION_dup +X509_EXTENSION_free +X509_EXTENSION_get_critical +X509_EXTENSION_get_data +X509_EXTENSION_get_object +X509_EXTENSION_it +X509_EXTENSION_new +X509_EXTENSION_set_critical +X509_EXTENSION_set_data +X509_EXTENSION_set_object +X509_INFO_free +X509_INFO_new +X509_LOOKUP_by_alias +X509_LOOKUP_by_fingerprint +X509_LOOKUP_by_issuer_serial +X509_LOOKUP_by_subject +X509_LOOKUP_ctrl +X509_LOOKUP_file +X509_LOOKUP_free +X509_LOOKUP_hash_dir +X509_LOOKUP_init +X509_LOOKUP_mem +X509_LOOKUP_new +X509_LOOKUP_shutdown +X509_NAME_ENTRIES_it +X509_NAME_ENTRY_create_by_NID +X509_NAME_ENTRY_create_by_OBJ +X509_NAME_ENTRY_create_by_txt +X509_NAME_ENTRY_dup +X509_NAME_ENTRY_free +X509_NAME_ENTRY_get_data +X509_NAME_ENTRY_get_object +X509_NAME_ENTRY_it +X509_NAME_ENTRY_new +X509_NAME_ENTRY_set +X509_NAME_ENTRY_set_data +X509_NAME_ENTRY_set_object +X509_NAME_INTERNAL_it +X509_NAME_add_entry +X509_NAME_add_entry_by_NID +X509_NAME_add_entry_by_OBJ +X509_NAME_add_entry_by_txt +X509_NAME_cmp +X509_NAME_delete_entry +X509_NAME_digest +X509_NAME_dup +X509_NAME_entry_count +X509_NAME_free +X509_NAME_get0_der +X509_NAME_get_entry +X509_NAME_get_index_by_NID +X509_NAME_get_index_by_OBJ +X509_NAME_get_text_by_NID +X509_NAME_get_text_by_OBJ +X509_NAME_hash +X509_NAME_hash_old +X509_NAME_it +X509_NAME_new +X509_NAME_oneline +X509_NAME_print +X509_NAME_print_ex +X509_NAME_print_ex_fp +X509_NAME_set +X509_OBJECT_free +X509_OBJECT_get0_X509 +X509_OBJECT_get0_X509_CRL +X509_OBJECT_get_type +X509_OBJECT_idx_by_subject +X509_OBJECT_new +X509_OBJECT_retrieve_by_subject +X509_OBJECT_retrieve_match +X509_OBJECT_up_ref_count +X509_PKEY_free +X509_PKEY_new +X509_PUBKEY_free +X509_PUBKEY_get +X509_PUBKEY_get0 +X509_PUBKEY_get0_param +X509_PUBKEY_it +X509_PUBKEY_new +X509_PUBKEY_set +X509_PUBKEY_set0_param +X509_PURPOSE_add +X509_PURPOSE_cleanup +X509_PURPOSE_get0 +X509_PURPOSE_get0_name +X509_PURPOSE_get0_sname +X509_PURPOSE_get_by_id +X509_PURPOSE_get_by_sname +X509_PURPOSE_get_count +X509_PURPOSE_get_id +X509_PURPOSE_get_trust +X509_PURPOSE_set +X509_REQ_INFO_free +X509_REQ_INFO_it +X509_REQ_INFO_new +X509_REQ_add1_attr +X509_REQ_add1_attr_by_NID +X509_REQ_add1_attr_by_OBJ +X509_REQ_add1_attr_by_txt +X509_REQ_add_extensions +X509_REQ_add_extensions_nid +X509_REQ_check_private_key +X509_REQ_delete_attr +X509_REQ_digest +X509_REQ_dup +X509_REQ_extension_nid +X509_REQ_free +X509_REQ_get0_pubkey +X509_REQ_get0_signature +X509_REQ_get1_email +X509_REQ_get_attr +X509_REQ_get_attr_by_NID +X509_REQ_get_attr_by_OBJ +X509_REQ_get_attr_count +X509_REQ_get_extension_nids +X509_REQ_get_extensions +X509_REQ_get_pubkey +X509_REQ_get_signature_nid +X509_REQ_get_subject_name +X509_REQ_get_version +X509_REQ_it +X509_REQ_new +X509_REQ_print +X509_REQ_print_ex +X509_REQ_print_fp +X509_REQ_set_extension_nids +X509_REQ_set_pubkey +X509_REQ_set_subject_name +X509_REQ_set_version +X509_REQ_sign +X509_REQ_sign_ctx +X509_REQ_to_X509 +X509_REQ_verify +X509_REVOKED_add1_ext_i2d +X509_REVOKED_add_ext +X509_REVOKED_delete_ext +X509_REVOKED_dup +X509_REVOKED_free +X509_REVOKED_get0_extensions +X509_REVOKED_get0_revocationDate +X509_REVOKED_get0_serialNumber +X509_REVOKED_get_ext +X509_REVOKED_get_ext_by_NID +X509_REVOKED_get_ext_by_OBJ +X509_REVOKED_get_ext_by_critical +X509_REVOKED_get_ext_count +X509_REVOKED_get_ext_d2i +X509_REVOKED_it +X509_REVOKED_new +X509_REVOKED_set_revocationDate +X509_REVOKED_set_serialNumber +X509_SIG_free +X509_SIG_get0 +X509_SIG_getm +X509_SIG_it +X509_SIG_new +X509_STORE_CTX_cleanup +X509_STORE_CTX_free +X509_STORE_CTX_get0_cert +X509_STORE_CTX_get0_chain +X509_STORE_CTX_get0_current_crl +X509_STORE_CTX_get0_current_issuer +X509_STORE_CTX_get0_param +X509_STORE_CTX_get0_parent_ctx +X509_STORE_CTX_get0_store +X509_STORE_CTX_get0_untrusted +X509_STORE_CTX_get1_certs +X509_STORE_CTX_get1_chain +X509_STORE_CTX_get1_crls +X509_STORE_CTX_get1_issuer +X509_STORE_CTX_get_by_subject +X509_STORE_CTX_get_chain +X509_STORE_CTX_get_check_issued +X509_STORE_CTX_get_current_cert +X509_STORE_CTX_get_error +X509_STORE_CTX_get_error_depth +X509_STORE_CTX_get_ex_data +X509_STORE_CTX_get_ex_new_index +X509_STORE_CTX_get_num_untrusted +X509_STORE_CTX_get_obj_by_subject +X509_STORE_CTX_get_verify +X509_STORE_CTX_get_verify_cb +X509_STORE_CTX_init +X509_STORE_CTX_new +X509_STORE_CTX_purpose_inherit +X509_STORE_CTX_set0_crls +X509_STORE_CTX_set0_param +X509_STORE_CTX_set0_trusted_stack +X509_STORE_CTX_set0_untrusted +X509_STORE_CTX_set0_verified_chain +X509_STORE_CTX_set_cert +X509_STORE_CTX_set_chain +X509_STORE_CTX_set_current_cert +X509_STORE_CTX_set_default +X509_STORE_CTX_set_depth +X509_STORE_CTX_set_error +X509_STORE_CTX_set_error_depth +X509_STORE_CTX_set_ex_data +X509_STORE_CTX_set_flags +X509_STORE_CTX_set_purpose +X509_STORE_CTX_set_time +X509_STORE_CTX_set_trust +X509_STORE_CTX_set_verify +X509_STORE_CTX_set_verify_cb +X509_STORE_CTX_trusted_stack +X509_STORE_add_cert +X509_STORE_add_crl +X509_STORE_add_lookup +X509_STORE_free +X509_STORE_get0_objects +X509_STORE_get0_param +X509_STORE_get_check_issued +X509_STORE_get_ex_data +X509_STORE_get_verify +X509_STORE_get_verify_cb +X509_STORE_load_locations +X509_STORE_load_mem +X509_STORE_new +X509_STORE_set1_param +X509_STORE_set_check_issued +X509_STORE_set_default_paths +X509_STORE_set_depth +X509_STORE_set_ex_data +X509_STORE_set_flags +X509_STORE_set_purpose +X509_STORE_set_trust +X509_STORE_set_verify +X509_STORE_set_verify_cb +X509_STORE_up_ref +X509_TRUST_add +X509_TRUST_cleanup +X509_TRUST_get0 +X509_TRUST_get0_name +X509_TRUST_get_by_id +X509_TRUST_get_count +X509_TRUST_get_flags +X509_TRUST_get_trust +X509_TRUST_set +X509_TRUST_set_default +X509_VAL_free +X509_VAL_it +X509_VAL_new +X509_VERIFY_PARAM_add0_policy +X509_VERIFY_PARAM_add0_table +X509_VERIFY_PARAM_add1_host +X509_VERIFY_PARAM_clear_flags +X509_VERIFY_PARAM_free +X509_VERIFY_PARAM_get0 +X509_VERIFY_PARAM_get0_name +X509_VERIFY_PARAM_get0_peername +X509_VERIFY_PARAM_get_count +X509_VERIFY_PARAM_get_depth +X509_VERIFY_PARAM_get_flags +X509_VERIFY_PARAM_get_time +X509_VERIFY_PARAM_inherit +X509_VERIFY_PARAM_lookup +X509_VERIFY_PARAM_new +X509_VERIFY_PARAM_set1 +X509_VERIFY_PARAM_set1_email +X509_VERIFY_PARAM_set1_host +X509_VERIFY_PARAM_set1_ip +X509_VERIFY_PARAM_set1_ip_asc +X509_VERIFY_PARAM_set1_name +X509_VERIFY_PARAM_set1_policies +X509_VERIFY_PARAM_set_auth_level +X509_VERIFY_PARAM_set_depth +X509_VERIFY_PARAM_set_flags +X509_VERIFY_PARAM_set_hostflags +X509_VERIFY_PARAM_set_purpose +X509_VERIFY_PARAM_set_time +X509_VERIFY_PARAM_set_trust +X509_VERIFY_PARAM_table_cleanup +X509_add1_ext_i2d +X509_add1_reject_object +X509_add1_trust_object +X509_add_ext +X509_alias_get0 +X509_alias_set1 +X509_certificate_type +X509_chain_up_ref +X509_check_akid +X509_check_ca +X509_check_email +X509_check_host +X509_check_ip +X509_check_ip_asc +X509_check_issued +X509_check_private_key +X509_check_purpose +X509_check_trust +X509_cmp +X509_cmp_current_time +X509_cmp_time +X509_delete_ext +X509_digest +X509_dup +X509_email_free +X509_find_by_issuer_and_serial +X509_find_by_subject +X509_free +X509_get0_extensions +X509_get0_notAfter +X509_get0_notBefore +X509_get0_pubkey +X509_get0_pubkey_bitstr +X509_get0_serialNumber +X509_get0_signature +X509_get0_tbs_sigalg +X509_get0_uids +X509_get1_email +X509_get1_ocsp +X509_get_X509_PUBKEY +X509_get_default_cert_area +X509_get_default_cert_dir +X509_get_default_cert_dir_env +X509_get_default_cert_file +X509_get_default_cert_file_env +X509_get_default_private_dir +X509_get_ex_data +X509_get_ex_new_index +X509_get_ext +X509_get_ext_by_NID +X509_get_ext_by_OBJ +X509_get_ext_by_critical +X509_get_ext_count +X509_get_ext_d2i +X509_get_extended_key_usage +X509_get_extension_flags +X509_get_issuer_name +X509_get_key_usage +X509_get_pubkey +X509_get_pubkey_parameters +X509_get_serialNumber +X509_get_signature_nid +X509_get_signature_type +X509_get_subject_name +X509_get_version +X509_getm_notAfter +X509_getm_notBefore +X509_gmtime_adj +X509_issuer_and_serial_cmp +X509_issuer_and_serial_hash +X509_issuer_name_cmp +X509_issuer_name_hash +X509_issuer_name_hash_old +X509_it +X509_keyid_get0 +X509_keyid_set1 +X509_load_cert_crl_file +X509_load_cert_file +X509_load_crl_file +X509_new +X509_ocspid_print +X509_print +X509_print_ex +X509_print_ex_fp +X509_print_fp +X509_pubkey_digest +X509_reject_clear +X509_set1_notAfter +X509_set1_notBefore +X509_set_ex_data +X509_set_issuer_name +X509_set_notAfter +X509_set_notBefore +X509_set_pubkey +X509_set_serialNumber +X509_set_subject_name +X509_set_version +X509_sign +X509_sign_ctx +X509_signature_dump +X509_signature_print +X509_subject_name_cmp +X509_subject_name_hash +X509_subject_name_hash_old +X509_supported_extension +X509_time_adj +X509_time_adj_ex +X509_to_X509_REQ +X509_trust_clear +X509_up_ref +X509_verify +X509_verify_cert +X509_verify_cert_error_string +X509at_add1_attr +X509at_add1_attr_by_NID +X509at_add1_attr_by_OBJ +X509at_add1_attr_by_txt +X509at_delete_attr +X509at_get0_data_by_OBJ +X509at_get_attr +X509at_get_attr_by_NID +X509at_get_attr_by_OBJ +X509at_get_attr_count +X509v3_add_ext +X509v3_addr_add_inherit +X509v3_addr_add_prefix +X509v3_addr_add_range +X509v3_addr_canonize +X509v3_addr_get_afi +X509v3_addr_get_range +X509v3_addr_inherits +X509v3_addr_is_canonical +X509v3_addr_subset +X509v3_addr_validate_path +X509v3_addr_validate_resource_set +X509v3_asid_add_id_or_range +X509v3_asid_add_inherit +X509v3_asid_canonize +X509v3_asid_inherits +X509v3_asid_is_canonical +X509v3_asid_subset +X509v3_asid_validate_path +X509v3_asid_validate_resource_set +X509v3_delete_ext +X509v3_get_ext +X509v3_get_ext_by_NID +X509v3_get_ext_by_OBJ +X509v3_get_ext_by_critical +X509v3_get_ext_count +X9_62_CHARACTERISTIC_TWO_free +X9_62_CHARACTERISTIC_TWO_it +X9_62_CHARACTERISTIC_TWO_new +X9_62_CURVE_it +X9_62_FIELDID_it +X9_62_PENTANOMIAL_free +X9_62_PENTANOMIAL_it +X9_62_PENTANOMIAL_new +ZLONG_it +_CONF_add_string +_CONF_free_data +_CONF_get_section +_CONF_get_section_values +_CONF_get_string +_CONF_new_data +_CONF_new_section +a2d_ASN1_OBJECT +a2i_ASN1_ENUMERATED +a2i_ASN1_INTEGER +a2i_ASN1_STRING +a2i_GENERAL_NAME +a2i_IPADDRESS +a2i_IPADDRESS_NC +a2i_ipadd +b2i_PVK_bio +b2i_PrivateKey +b2i_PrivateKey_bio +b2i_PublicKey +b2i_PublicKey_bio +d2i_ACCESS_DESCRIPTION +d2i_ASIdOrRange +d2i_ASIdentifierChoice +d2i_ASIdentifiers +d2i_ASN1_BIT_STRING +d2i_ASN1_BMPSTRING +d2i_ASN1_ENUMERATED +d2i_ASN1_GENERALIZEDTIME +d2i_ASN1_GENERALSTRING +d2i_ASN1_IA5STRING +d2i_ASN1_INTEGER +d2i_ASN1_NULL +d2i_ASN1_OBJECT +d2i_ASN1_OCTET_STRING +d2i_ASN1_PRINTABLE +d2i_ASN1_PRINTABLESTRING +d2i_ASN1_SEQUENCE_ANY +d2i_ASN1_SET_ANY +d2i_ASN1_T61STRING +d2i_ASN1_TIME +d2i_ASN1_TYPE +d2i_ASN1_UINTEGER +d2i_ASN1_UNIVERSALSTRING +d2i_ASN1_UTCTIME +d2i_ASN1_UTF8STRING +d2i_ASN1_VISIBLESTRING +d2i_ASRange +d2i_AUTHORITY_INFO_ACCESS +d2i_AUTHORITY_KEYID +d2i_AutoPrivateKey +d2i_BASIC_CONSTRAINTS +d2i_CERTIFICATEPOLICIES +d2i_CMS_ContentInfo +d2i_CMS_ReceiptRequest +d2i_CMS_bio +d2i_CRL_DIST_POINTS +d2i_DHparams +d2i_DHparams_bio +d2i_DHparams_fp +d2i_DIRECTORYSTRING +d2i_DISPLAYTEXT +d2i_DIST_POINT +d2i_DIST_POINT_NAME +d2i_DSAPrivateKey +d2i_DSAPrivateKey_bio +d2i_DSAPrivateKey_fp +d2i_DSAPublicKey +d2i_DSA_PUBKEY +d2i_DSA_PUBKEY_bio +d2i_DSA_PUBKEY_fp +d2i_DSA_SIG +d2i_DSAparams +d2i_DSAparams_bio +d2i_DSAparams_fp +d2i_ECDSA_SIG +d2i_ECPKPARAMETERS +d2i_ECPKParameters +d2i_ECParameters +d2i_ECPrivateKey +d2i_ECPrivateKey_bio +d2i_ECPrivateKey_fp +d2i_EC_PRIVATEKEY +d2i_EC_PUBKEY +d2i_EC_PUBKEY_bio +d2i_EC_PUBKEY_fp +d2i_EDIPARTYNAME +d2i_ESS_CERT_ID +d2i_ESS_ISSUER_SERIAL +d2i_ESS_SIGNING_CERT +d2i_EXTENDED_KEY_USAGE +d2i_GENERAL_NAME +d2i_GENERAL_NAMES +d2i_GOST_CIPHER_PARAMS +d2i_IPAddressChoice +d2i_IPAddressFamily +d2i_IPAddressOrRange +d2i_IPAddressRange +d2i_ISSUING_DIST_POINT +d2i_NETSCAPE_SPKAC +d2i_NETSCAPE_SPKI +d2i_NOTICEREF +d2i_OCSP_BASICRESP +d2i_OCSP_CERTID +d2i_OCSP_CERTSTATUS +d2i_OCSP_CRLID +d2i_OCSP_ONEREQ +d2i_OCSP_REQINFO +d2i_OCSP_REQUEST +d2i_OCSP_REQUEST_bio +d2i_OCSP_RESPBYTES +d2i_OCSP_RESPDATA +d2i_OCSP_RESPID +d2i_OCSP_RESPONSE +d2i_OCSP_RESPONSE_bio +d2i_OCSP_REVOKEDINFO +d2i_OCSP_SERVICELOC +d2i_OCSP_SIGNATURE +d2i_OCSP_SINGLERESP +d2i_OTHERNAME +d2i_PBE2PARAM +d2i_PBEPARAM +d2i_PBKDF2PARAM +d2i_PKCS12 +d2i_PKCS12_BAGS +d2i_PKCS12_MAC_DATA +d2i_PKCS12_SAFEBAG +d2i_PKCS12_bio +d2i_PKCS12_fp +d2i_PKCS7 +d2i_PKCS7_DIGEST +d2i_PKCS7_ENCRYPT +d2i_PKCS7_ENC_CONTENT +d2i_PKCS7_ENVELOPE +d2i_PKCS7_ISSUER_AND_SERIAL +d2i_PKCS7_RECIP_INFO +d2i_PKCS7_SIGNED +d2i_PKCS7_SIGNER_INFO +d2i_PKCS7_SIGN_ENVELOPE +d2i_PKCS7_bio +d2i_PKCS7_fp +d2i_PKCS8PrivateKey_bio +d2i_PKCS8PrivateKey_fp +d2i_PKCS8_PRIV_KEY_INFO +d2i_PKCS8_PRIV_KEY_INFO_bio +d2i_PKCS8_PRIV_KEY_INFO_fp +d2i_PKCS8_bio +d2i_PKCS8_fp +d2i_PKEY_USAGE_PERIOD +d2i_POLICYINFO +d2i_POLICYQUALINFO +d2i_PUBKEY +d2i_PUBKEY_bio +d2i_PUBKEY_fp +d2i_PrivateKey +d2i_PrivateKey_bio +d2i_PrivateKey_fp +d2i_PublicKey +d2i_RSAPrivateKey +d2i_RSAPrivateKey_bio +d2i_RSAPrivateKey_fp +d2i_RSAPublicKey +d2i_RSAPublicKey_bio +d2i_RSAPublicKey_fp +d2i_RSA_OAEP_PARAMS +d2i_RSA_PSS_PARAMS +d2i_RSA_PUBKEY +d2i_RSA_PUBKEY_bio +d2i_RSA_PUBKEY_fp +d2i_SCT_LIST +d2i_TS_ACCURACY +d2i_TS_MSG_IMPRINT +d2i_TS_MSG_IMPRINT_bio +d2i_TS_MSG_IMPRINT_fp +d2i_TS_REQ +d2i_TS_REQ_bio +d2i_TS_REQ_fp +d2i_TS_RESP +d2i_TS_RESP_bio +d2i_TS_RESP_fp +d2i_TS_STATUS_INFO +d2i_TS_TST_INFO +d2i_TS_TST_INFO_bio +d2i_TS_TST_INFO_fp +d2i_USERNOTICE +d2i_X509 +d2i_X509_ALGOR +d2i_X509_ALGORS +d2i_X509_ATTRIBUTE +d2i_X509_AUX +d2i_X509_CERT_AUX +d2i_X509_CINF +d2i_X509_CRL +d2i_X509_CRL_INFO +d2i_X509_CRL_bio +d2i_X509_CRL_fp +d2i_X509_EXTENSION +d2i_X509_EXTENSIONS +d2i_X509_NAME +d2i_X509_NAME_ENTRY +d2i_X509_PUBKEY +d2i_X509_REQ +d2i_X509_REQ_INFO +d2i_X509_REQ_bio +d2i_X509_REQ_fp +d2i_X509_REVOKED +d2i_X509_SIG +d2i_X509_VAL +d2i_X509_bio +d2i_X509_fp +hex_to_string +i2a_ACCESS_DESCRIPTION +i2a_ASN1_ENUMERATED +i2a_ASN1_INTEGER +i2a_ASN1_OBJECT +i2a_ASN1_STRING +i2b_PVK_bio +i2b_PrivateKey_bio +i2b_PublicKey_bio +i2d_ACCESS_DESCRIPTION +i2d_ASIdOrRange +i2d_ASIdentifierChoice +i2d_ASIdentifiers +i2d_ASN1_BIT_STRING +i2d_ASN1_BMPSTRING +i2d_ASN1_ENUMERATED +i2d_ASN1_GENERALIZEDTIME +i2d_ASN1_GENERALSTRING +i2d_ASN1_IA5STRING +i2d_ASN1_INTEGER +i2d_ASN1_NULL +i2d_ASN1_OBJECT +i2d_ASN1_OCTET_STRING +i2d_ASN1_PRINTABLE +i2d_ASN1_PRINTABLESTRING +i2d_ASN1_SEQUENCE_ANY +i2d_ASN1_SET_ANY +i2d_ASN1_T61STRING +i2d_ASN1_TIME +i2d_ASN1_TYPE +i2d_ASN1_UNIVERSALSTRING +i2d_ASN1_UTCTIME +i2d_ASN1_UTF8STRING +i2d_ASN1_VISIBLESTRING +i2d_ASRange +i2d_AUTHORITY_INFO_ACCESS +i2d_AUTHORITY_KEYID +i2d_BASIC_CONSTRAINTS +i2d_CERTIFICATEPOLICIES +i2d_CMS_ContentInfo +i2d_CMS_ReceiptRequest +i2d_CMS_bio +i2d_CMS_bio_stream +i2d_CRL_DIST_POINTS +i2d_DHparams +i2d_DHparams_bio +i2d_DHparams_fp +i2d_DIRECTORYSTRING +i2d_DISPLAYTEXT +i2d_DIST_POINT +i2d_DIST_POINT_NAME +i2d_DSAPrivateKey +i2d_DSAPrivateKey_bio +i2d_DSAPrivateKey_fp +i2d_DSAPublicKey +i2d_DSA_PUBKEY +i2d_DSA_PUBKEY_bio +i2d_DSA_PUBKEY_fp +i2d_DSA_SIG +i2d_DSAparams +i2d_DSAparams_bio +i2d_DSAparams_fp +i2d_ECDSA_SIG +i2d_ECPKPARAMETERS +i2d_ECPKParameters +i2d_ECParameters +i2d_ECPrivateKey +i2d_ECPrivateKey_bio +i2d_ECPrivateKey_fp +i2d_EC_PRIVATEKEY +i2d_EC_PUBKEY +i2d_EC_PUBKEY_bio +i2d_EC_PUBKEY_fp +i2d_EDIPARTYNAME +i2d_ESS_CERT_ID +i2d_ESS_ISSUER_SERIAL +i2d_ESS_SIGNING_CERT +i2d_EXTENDED_KEY_USAGE +i2d_GENERAL_NAME +i2d_GENERAL_NAMES +i2d_GOST_CIPHER_PARAMS +i2d_IPAddressChoice +i2d_IPAddressFamily +i2d_IPAddressOrRange +i2d_IPAddressRange +i2d_ISSUING_DIST_POINT +i2d_NETSCAPE_SPKAC +i2d_NETSCAPE_SPKI +i2d_NOTICEREF +i2d_OCSP_BASICRESP +i2d_OCSP_CERTID +i2d_OCSP_CERTSTATUS +i2d_OCSP_CRLID +i2d_OCSP_ONEREQ +i2d_OCSP_REQINFO +i2d_OCSP_REQUEST +i2d_OCSP_REQUEST_bio +i2d_OCSP_RESPBYTES +i2d_OCSP_RESPDATA +i2d_OCSP_RESPID +i2d_OCSP_RESPONSE +i2d_OCSP_RESPONSE_bio +i2d_OCSP_REVOKEDINFO +i2d_OCSP_SERVICELOC +i2d_OCSP_SIGNATURE +i2d_OCSP_SINGLERESP +i2d_OTHERNAME +i2d_PBE2PARAM +i2d_PBEPARAM +i2d_PBKDF2PARAM +i2d_PKCS12 +i2d_PKCS12_BAGS +i2d_PKCS12_MAC_DATA +i2d_PKCS12_SAFEBAG +i2d_PKCS12_bio +i2d_PKCS12_fp +i2d_PKCS7 +i2d_PKCS7_DIGEST +i2d_PKCS7_ENCRYPT +i2d_PKCS7_ENC_CONTENT +i2d_PKCS7_ENVELOPE +i2d_PKCS7_ISSUER_AND_SERIAL +i2d_PKCS7_RECIP_INFO +i2d_PKCS7_SIGNED +i2d_PKCS7_SIGNER_INFO +i2d_PKCS7_SIGN_ENVELOPE +i2d_PKCS7_bio +i2d_PKCS7_bio_stream +i2d_PKCS7_fp +i2d_PKCS8PrivateKeyInfo_bio +i2d_PKCS8PrivateKeyInfo_fp +i2d_PKCS8PrivateKey_bio +i2d_PKCS8PrivateKey_fp +i2d_PKCS8PrivateKey_nid_bio +i2d_PKCS8PrivateKey_nid_fp +i2d_PKCS8_PRIV_KEY_INFO +i2d_PKCS8_PRIV_KEY_INFO_bio +i2d_PKCS8_PRIV_KEY_INFO_fp +i2d_PKCS8_bio +i2d_PKCS8_fp +i2d_PKEY_USAGE_PERIOD +i2d_POLICYINFO +i2d_POLICYQUALINFO +i2d_PUBKEY +i2d_PUBKEY_bio +i2d_PUBKEY_fp +i2d_PrivateKey +i2d_PrivateKey_bio +i2d_PrivateKey_fp +i2d_PublicKey +i2d_RSAPrivateKey +i2d_RSAPrivateKey_bio +i2d_RSAPrivateKey_fp +i2d_RSAPublicKey +i2d_RSAPublicKey_bio +i2d_RSAPublicKey_fp +i2d_RSA_OAEP_PARAMS +i2d_RSA_PSS_PARAMS +i2d_RSA_PUBKEY +i2d_RSA_PUBKEY_bio +i2d_RSA_PUBKEY_fp +i2d_SCT_LIST +i2d_TS_ACCURACY +i2d_TS_MSG_IMPRINT +i2d_TS_MSG_IMPRINT_bio +i2d_TS_MSG_IMPRINT_fp +i2d_TS_REQ +i2d_TS_REQ_bio +i2d_TS_REQ_fp +i2d_TS_RESP +i2d_TS_RESP_bio +i2d_TS_RESP_fp +i2d_TS_STATUS_INFO +i2d_TS_TST_INFO +i2d_TS_TST_INFO_bio +i2d_TS_TST_INFO_fp +i2d_USERNOTICE +i2d_X509 +i2d_X509_ALGOR +i2d_X509_ALGORS +i2d_X509_ATTRIBUTE +i2d_X509_AUX +i2d_X509_CERT_AUX +i2d_X509_CINF +i2d_X509_CRL +i2d_X509_CRL_INFO +i2d_X509_CRL_bio +i2d_X509_CRL_fp +i2d_X509_EXTENSION +i2d_X509_EXTENSIONS +i2d_X509_NAME +i2d_X509_NAME_ENTRY +i2d_X509_PUBKEY +i2d_X509_REQ +i2d_X509_REQ_INFO +i2d_X509_REQ_bio +i2d_X509_REQ_fp +i2d_X509_REVOKED +i2d_X509_SIG +i2d_X509_VAL +i2d_X509_bio +i2d_X509_fp +i2d_re_X509_CRL_tbs +i2d_re_X509_REQ_tbs +i2d_re_X509_tbs +i2o_ECPublicKey +i2o_SCT +i2o_SCT_LIST +i2s_ASN1_ENUMERATED +i2s_ASN1_ENUMERATED_TABLE +i2s_ASN1_INTEGER +i2s_ASN1_OCTET_STRING +i2t_ASN1_OBJECT +i2v_ASN1_BIT_STRING +i2v_GENERAL_NAME +i2v_GENERAL_NAMES +idea_cbc_encrypt +idea_cfb64_encrypt +idea_ecb_encrypt +idea_encrypt +idea_ofb64_encrypt +idea_set_decrypt_key +idea_set_encrypt_key +lh_delete +lh_doall +lh_doall_arg +lh_free +lh_insert +lh_new +lh_node_stats +lh_node_stats_bio +lh_node_usage_stats +lh_node_usage_stats_bio +lh_num_items +lh_retrieve +lh_stats +lh_stats_bio +lh_strhash +o2i_ECPublicKey +o2i_SCT +o2i_SCT_LIST +s2i_ASN1_INTEGER +s2i_ASN1_OCTET_STRING +sk_delete +sk_delete_ptr +sk_dup +sk_find +sk_find_ex +sk_free +sk_insert +sk_is_sorted +sk_new +sk_new_null +sk_num +sk_pop +sk_pop_free +sk_push +sk_set +sk_set_cmp_func +sk_shift +sk_sort +sk_unshift +sk_value +sk_zero +string_to_hex +v2i_ASN1_BIT_STRING +v2i_GENERAL_NAME +v2i_GENERAL_NAMES +v2i_GENERAL_NAME_ex diff --git a/Libraries/libressl/crypto/crypto_init.c b/Libraries/libressl/crypto/crypto_init.c new file mode 100644 index 000000000..a2c1c786c --- /dev/null +++ b/Libraries/libressl/crypto/crypto_init.c @@ -0,0 +1,102 @@ +/* $OpenBSD: crypto_init.c,v 1.11 2023/07/08 08:28:23 beck Exp $ */ +/* + * Copyright (c) 2018 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OpenSSL style init */ + +#include +#include + +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include +#include +#include + +#include "cryptlib.h" +#include "x509_issuer_cache.h" + +int OpenSSL_config(const char *); +int OpenSSL_no_config(void); + +static pthread_once_t crypto_init_once = PTHREAD_ONCE_INIT; +static pthread_t crypto_init_thread; +static int crypto_init_cleaned_up; + +static void +OPENSSL_init_crypto_internal(void) +{ + crypto_init_thread = pthread_self(); + + OPENSSL_cpuid_setup(); + ERR_load_crypto_strings(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +} + +int +OPENSSL_init_crypto(uint64_t opts, const void *settings) +{ + if (crypto_init_cleaned_up) { + CRYPTOerror(ERR_R_INIT_FAIL); + return 0; + } + + if (pthread_equal(pthread_self(), crypto_init_thread)) + return 1; /* don't recurse */ + + if (pthread_once(&crypto_init_once, OPENSSL_init_crypto_internal) != 0) + return 0; + + if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) && + (OpenSSL_no_config() == 0)) + return 0; + + if ((opts & OPENSSL_INIT_LOAD_CONFIG) && + (OpenSSL_config(NULL) == 0)) + return 0; + + return 1; +} +LCRYPTO_ALIAS(OPENSSL_init_crypto); + +void +OPENSSL_cleanup(void) +{ + /* This currently calls init... */ + ERR_free_strings(); + + CRYPTO_cleanup_all_ex_data(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + EVP_cleanup(); + + ASN1_STRING_TABLE_cleanup(); + X509V3_EXT_cleanup(); + X509_PURPOSE_cleanup(); + X509_TRUST_cleanup(); + X509_VERIFY_PARAM_table_cleanup(); + + x509_issuer_cache_free(); + + crypto_init_cleaned_up = 1; +} +LCRYPTO_ALIAS(OPENSSL_cleanup); diff --git a/Libraries/libressl/crypto/crypto_internal.h b/Libraries/libressl/crypto/crypto_internal.h new file mode 100644 index 000000000..e5742657d --- /dev/null +++ b/Libraries/libressl/crypto/crypto_internal.h @@ -0,0 +1,153 @@ +/* $OpenBSD: crypto_internal.h,v 1.7 2023/08/15 08:39:27 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#ifndef HEADER_CRYPTO_INTERNAL_H +#define HEADER_CRYPTO_INTERNAL_H + +#define CTASSERT(x) \ + extern char _ctassert[(x) ? 1 : -1] __attribute__((__unused__)) + +/* + * crypto_load_be32toh() loads a 32 bit unsigned big endian value as a 32 bit + * unsigned host endian value, from the specified address in memory. The memory + * address may have any alignment. + */ +#ifndef HAVE_CRYPTO_LOAD_BE32TOH +static inline uint32_t +crypto_load_be32toh(const uint8_t *src) +{ + uint32_t v; + + memcpy(&v, src, sizeof(v)); + + return be32toh(v); +} +#endif + +/* + * crypto_store_htobe32() stores a 32 bit unsigned host endian value as a 32 bit + * unsigned big endian value, at the specified address in memory. The memory + * address may have any alignment. + */ +#ifndef HAVE_CRYPTO_STORE_HTOBE32 +static inline void +crypto_store_htobe32(uint8_t *dst, uint32_t v) +{ + v = htobe32(v); + memcpy(dst, &v, sizeof(v)); +} +#endif + +/* + * crypto_load_be64toh() loads a 64 bit unsigned big endian value as a 64 bit + * unsigned host endian value, from the specified address in memory. The memory + * address may have any alignment. + */ +#ifndef HAVE_CRYPTO_LOAD_BE64TOH +static inline uint64_t +crypto_load_be64toh(const uint8_t *src) +{ + uint64_t v; + + memcpy(&v, src, sizeof(v)); + + return be64toh(v); +} +#endif + +/* + * crypto_store_htobe64() stores a 64 bit unsigned host endian value as a 64 bit + * unsigned big endian value, at the specified address in memory. The memory + * address may have any alignment. + */ +#ifndef HAVE_CRYPTO_STORE_HTOBE64 +static inline void +crypto_store_htobe64(uint8_t *dst, uint64_t v) +{ + v = htobe64(v); + memcpy(dst, &v, sizeof(v)); +} +#endif + +/* + * crypto_load_le32toh() loads a 32 bit unsigned little endian value as a 32 bit + * unsigned host endian value, from the specified address in memory. The memory + * address may have any alignment. + */ +#ifndef HAVE_CRYPTO_LOAD_BE32TOH +static inline uint32_t +crypto_load_le32toh(const uint8_t *src) +{ + uint32_t v; + + memcpy(&v, src, sizeof(v)); + + return le32toh(v); +} +#endif + +/* + * crypto_store_htole32() stores a 32 bit unsigned host endian value as a 32 bit + * unsigned little endian value, at the specified address in memory. The memory + * address may have any alignment. + */ +#ifndef HAVE_CRYPTO_STORE_HTOBE32 +static inline void +crypto_store_htole32(uint8_t *dst, uint32_t v) +{ + v = htole32(v); + memcpy(dst, &v, sizeof(v)); +} +#endif + +#ifndef HAVE_CRYPTO_ROL_U32 +static inline uint32_t +crypto_rol_u32(uint32_t v, size_t shift) +{ + return (v << shift) | (v >> (32 - shift)); +} +#endif + +#ifndef HAVE_CRYPTO_ROR_U32 +static inline uint32_t +crypto_ror_u32(uint32_t v, size_t shift) +{ + return (v << (32 - shift)) | (v >> shift); +} +#endif + +#ifndef HAVE_CRYPTO_ROL_U64 +static inline uint64_t +crypto_rol_u64(uint64_t v, size_t shift) +{ + return (v << shift) | (v >> (64 - shift)); +} +#endif + +#ifndef HAVE_CRYPTO_ROR_U64 +static inline uint64_t +crypto_ror_u64(uint64_t v, size_t shift) +{ + return (v << (64 - shift)) | (v >> shift); +} +#endif + +#endif diff --git a/Libraries/libressl/crypto/crypto_lock.c b/Libraries/libressl/crypto/crypto_lock.c new file mode 100644 index 000000000..59c3933c7 --- /dev/null +++ b/Libraries/libressl/crypto/crypto_lock.c @@ -0,0 +1,96 @@ +/* $OpenBSD: crypto_lock.c,v 1.6 2023/07/08 08:28:23 beck Exp $ */ +/* + * Copyright (c) 2018 Brent Cook + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "crypto_internal.h" + +static pthread_mutex_t locks[] = { + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, +}; + +CTASSERT((sizeof(locks) / sizeof(*locks)) == CRYPTO_NUM_LOCKS); + +void +CRYPTO_lock(int mode, int type, const char *file, int line) +{ + if (type < 0 || type >= CRYPTO_NUM_LOCKS) + return; + + if (mode & CRYPTO_LOCK) + (void) pthread_mutex_lock(&locks[type]); + else if (mode & CRYPTO_UNLOCK) + (void) pthread_mutex_unlock(&locks[type]); +} +LCRYPTO_ALIAS(CRYPTO_lock); + +int +CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line) +{ + int ret; + + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line); + ret = *pointer + amount; + *pointer = ret; + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line); + + return (ret); +} +LCRYPTO_ALIAS(CRYPTO_add_lock); diff --git a/Libraries/libressl/crypto/ct/ct_b64.c b/Libraries/libressl/crypto/ct/ct_b64.c new file mode 100644 index 000000000..101cd1e2b --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_b64.c @@ -0,0 +1,226 @@ +/* $OpenBSD: ct_b64.c,v 1.7 2023/07/08 07:22:58 beck Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com) and Stephen Henson + * (steve@openssl.org) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +#include "bytestring.h" +#include "ct_local.h" + +/* + * Decodes the base64 string |in| into |out|. + * A new string will be malloc'd and assigned to |out|. This will be owned by + * the caller. Do not provide a pre-allocated string in |out|. + */ +static int +ct_base64_decode(const char *in, unsigned char **out) +{ + size_t inlen = strlen(in); + int outlen, i; + unsigned char *outbuf = NULL; + + if (inlen == 0) { + *out = NULL; + return 0; + } + + outlen = (inlen / 4) * 3; + outbuf = malloc(outlen); + if (outbuf == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen); + if (outlen < 0) { + CTerror(CT_R_BASE64_DECODE_ERROR); + goto err; + } + + /* + * Subtract padding bytes from |outlen|. + * Any more than 2 is malformed. + */ + i = 0; + while (in[--inlen] == '=') { + --outlen; + if (++i > 2) + goto err; + } + + *out = outbuf; + return outlen; + err: + free(outbuf); + return -1; +} + +SCT * +SCT_new_from_base64(unsigned char version, const char *logid_base64, + ct_log_entry_type_t entry_type, uint64_t timestamp, + const char *extensions_base64, const char *signature_base64) +{ + unsigned char *dec = NULL; + int declen; + SCT *sct; + CBS cbs; + + if ((sct = SCT_new()) == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* + * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we + * can only construct SCT versions that have been defined. + */ + if (!SCT_set_version(sct, version)) { + CTerror(CT_R_SCT_UNSUPPORTED_VERSION); + goto err; + } + + declen = ct_base64_decode(logid_base64, &dec); + if (declen < 0) { + CTerror(X509_R_BASE64_DECODE_ERROR); + goto err; + } + if (!SCT_set0_log_id(sct, dec, declen)) + goto err; + dec = NULL; + + declen = ct_base64_decode(extensions_base64, &dec); + if (declen < 0) { + CTerror(X509_R_BASE64_DECODE_ERROR); + goto err; + } + SCT_set0_extensions(sct, dec, declen); + dec = NULL; + + declen = ct_base64_decode(signature_base64, &dec); + if (declen < 0) { + CTerror(X509_R_BASE64_DECODE_ERROR); + goto err; + } + + CBS_init(&cbs, dec, declen); + if (!o2i_SCT_signature(sct, &cbs)) + goto err; + free(dec); + dec = NULL; + + SCT_set_timestamp(sct, timestamp); + + if (!SCT_set_log_entry_type(sct, entry_type)) + goto err; + + return sct; + + err: + free(dec); + SCT_free(sct); + return NULL; +} +LCRYPTO_ALIAS(SCT_new_from_base64); + +/* + * Allocate, build and returns a new |ct_log| from input |pkey_base64| + * It returns 1 on success, + * 0 on decoding failure, or invalid parameter if any + * -1 on internal (malloc) failure + */ +int +CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name) +{ + unsigned char *pkey_der = NULL; + int pkey_der_len; + const unsigned char *p; + EVP_PKEY *pkey = NULL; + + if (ct_log == NULL) { + CTerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der); + if (pkey_der_len < 0) { + CTerror(CT_R_LOG_CONF_INVALID_KEY); + return 0; + } + + p = pkey_der; + pkey = d2i_PUBKEY(NULL, &p, pkey_der_len); + free(pkey_der); + if (pkey == NULL) { + CTerror(CT_R_LOG_CONF_INVALID_KEY); + return 0; + } + + *ct_log = CTLOG_new(pkey, name); + if (*ct_log == NULL) { + EVP_PKEY_free(pkey); + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(CTLOG_new_from_base64); diff --git a/Libraries/libressl/crypto/ct/ct_err.c b/Libraries/libressl/crypto/ct/ct_err.c new file mode 100644 index 000000000..2597874bd --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_err.c @@ -0,0 +1,147 @@ +/* $OpenBSD: ct_err.c,v 1.7 2022/07/12 14:42:48 kn Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#ifndef OPENSSL_NO_ERR + +static ERR_STRING_DATA CT_str_functs[] = { + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW, 0), "CTLOG_new"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_BASE64, 0), + "CTLOG_new_from_base64"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_CONF, 0), + "ctlog_new_from_conf"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_CTX_NEW, 0), + "ctlog_store_load_ctx_new"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_FILE, 0), + "CTLOG_STORE_load_file"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_LOG, 0), + "ctlog_store_load_log"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_NEW, 0), "CTLOG_STORE_new"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CT_BASE64_DECODE, 0), "ct_base64_decode"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CT_POLICY_EVAL_CTX_NEW, 0), + "CT_POLICY_EVAL_CTX_new"}, + {ERR_PACK(ERR_LIB_CT, CT_F_CT_V1_LOG_ID_FROM_PKEY, 0), + "ct_v1_log_id_from_pkey"}, + {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT, 0), "i2o_SCT"}, + {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_LIST, 0), "i2o_SCT_LIST"}, + {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_SIGNATURE, 0), "i2o_SCT_signature"}, + {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT, 0), "o2i_SCT"}, + {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_LIST, 0), "o2i_SCT_LIST"}, + {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_SIGNATURE, 0), "o2i_SCT_signature"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_NEW, 0), "SCT_CTX_new"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_VERIFY, 0), "SCT_CTX_verify"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW, 0), "SCT_new"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW_FROM_BASE64, 0), + "SCT_new_from_base64"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET0_LOG_ID, 0), "SCT_set0_log_id"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_EXTENSIONS, 0), + "SCT_set1_extensions"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_LOG_ID, 0), "SCT_set1_log_id"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_SIGNATURE, 0), + "SCT_set1_signature"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_LOG_ENTRY_TYPE, 0), + "SCT_set_log_entry_type"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_SIGNATURE_NID, 0), + "SCT_set_signature_nid"}, + {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_VERSION, 0), "SCT_set_version"}, + {0, NULL} +}; + +static ERR_STRING_DATA CT_str_reasons[] = { + {ERR_PACK(ERR_LIB_CT, 0, CT_R_BASE64_DECODE_ERROR), + "base64 decode error"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_INVALID_LOG_ID_LENGTH), + "invalid log id length"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID), "log conf invalid"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID_KEY), + "log conf invalid key"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_DESCRIPTION), + "log conf missing description"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_KEY), + "log conf missing key"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_KEY_INVALID), "log key invalid"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_FUTURE_TIMESTAMP), + "sct future timestamp"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID), "sct invalid"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID_SIGNATURE), + "sct invalid signature"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LIST_INVALID), "sct list invalid"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LOG_ID_MISMATCH), + "sct log id mismatch"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_NOT_SET), "sct not set"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_UNSUPPORTED_VERSION), + "sct unsupported version"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNRECOGNIZED_SIGNATURE_NID), + "unrecognized signature nid"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_ENTRY_TYPE), + "unsupported entry type"}, + {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_VERSION), + "unsupported version"}, + {0, NULL} +}; + +#endif + +int +ERR_load_CT_strings(void) +{ + if (ERR_func_error_string(CT_str_functs[0].error) == NULL) { + ERR_load_strings(0, CT_str_functs); + ERR_load_strings(0, CT_str_reasons); + } + return 1; +} diff --git a/Libraries/libressl/crypto/ct/ct_local.h b/Libraries/libressl/crypto/ct/ct_local.h new file mode 100644 index 000000000..cd19ed096 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_local.h @@ -0,0 +1,260 @@ +/* $OpenBSD: ct_local.h,v 1.8 2021/12/20 17:19:19 jsing Exp $ */ +/* + * Written by Rob Percival (robpercival@google.com) for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include +#include +#include +#include +#include + +#include "bytestring.h" + +/* Number of bytes in an SCT v1 LogID - see RFC 6962 section 3.2. */ +#define CT_V1_LOG_ID_LEN 32 + +/* Maximum size of an SCT - see RFC 6962 section 3.3. */ +#define MAX_SCT_SIZE 65535 +#define MAX_SCT_LIST_SIZE MAX_SCT_SIZE + +/* + * Macros to write integers in network-byte order. + */ + +#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ + c[1]=(unsigned char)(((s) )&0xff)),c+=2) + +#define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \ + c[1]=(unsigned char)(((l)>> 8)&0xff), \ + c[2]=(unsigned char)(((l) )&0xff)),c+=3) + +#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* Signed Certificate Timestamp */ +struct sct_st { + sct_version_t version; + /* If version is not SCT_VERSION_V1, this contains the encoded SCT */ + unsigned char *sct; + size_t sct_len; + /* + * If version is SCT_VERSION_V1, fields below contain components of + * the SCT + */ + unsigned char *log_id; + size_t log_id_len; + /* + * Note, we cannot distinguish between an unset timestamp, and one + * that is set to 0. However since CT didn't exist in 1970, no real + * SCT should ever be set as such. + */ + uint64_t timestamp; + unsigned char *ext; + size_t ext_len; + unsigned char hash_alg; + unsigned char sig_alg; + unsigned char *sig; + size_t sig_len; + /* Log entry type */ + ct_log_entry_type_t entry_type; + /* Where this SCT was found, e.g. certificate, OCSP response, etc. */ + sct_source_t source; + /* The result of the last attempt to validate this SCT. */ + sct_validation_status_t validation_status; +}; + +/* Miscellaneous data that is useful when verifying an SCT */ +struct sct_ctx_st { + /* Public key */ + EVP_PKEY *pkey; + /* Hash of public key */ + unsigned char *pkeyhash; + size_t pkeyhashlen; + /* For pre-certificate: issuer public key hash */ + unsigned char *ihash; + size_t ihashlen; + /* certificate encoding */ + unsigned char *certder; + size_t certderlen; + /* pre-certificate encoding */ + unsigned char *preder; + size_t prederlen; + /* + * milliseconds since epoch (to check that the SCT isn't from the + * future) + */ + uint64_t epoch_time_in_ms; +}; + +/* Context when evaluating whether a Certificate Transparency policy is met */ +struct ct_policy_eval_ctx_st { + X509 *cert; + X509 *issuer; + CTLOG_STORE *log_store; + /* + * milliseconds since epoch (to check that the SCT isn't from the + * future) + */ + uint64_t epoch_time_in_ms; +}; + +/* + * Creates a new context for verifying an SCT. + */ +SCT_CTX *SCT_CTX_new(void); +/* + * Deletes an SCT verification context. + */ +void SCT_CTX_free(SCT_CTX *sctx); + +/* + * Sets the certificate that the SCT was created for. + * If *cert does not have a poison extension, presigner must be NULL. + * If *cert does not have a poison extension, it may have a single SCT + * (NID_ct_precert_scts) extension. + * If either *cert or *presigner have an AKID (NID_authority_key_identifier) + * extension, both must have one. + * Returns 1 on success, 0 on failure. + */ +int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner); + +/* + * Sets the issuer of the certificate that the SCT was created for. + * This is just a convenience method to save extracting the public key and + * calling SCT_CTX_set1_issuer_pubkey(). + * Issuer must not be NULL. + * Returns 1 on success, 0 on failure. + */ +int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer); + +/* + * Sets the public key of the issuer of the certificate that the SCT was created + * for. + * The public key must not be NULL. + * Returns 1 on success, 0 on failure. + */ +int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey); + +/* + * Sets the public key of the CT log that the SCT is from. + * Returns 1 on success, 0 on failure. + */ +int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey); + +/* + * Sets the time to evaluate the SCT against, in milliseconds since the Unix + * epoch. If the SCT's timestamp is after this time, it will be interpreted as + * having been issued in the future. RFC6962 states that "TLS clients MUST + * reject SCTs whose timestamp is in the future", so an SCT will not validate + * in this case. + */ +void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms); + +/* + * Verifies an SCT with the given context. + * Returns 1 if the SCT verifies successfully; any other value indicates + * failure. See EVP_DigestVerifyFinal() for the meaning of those values. + */ +int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct); + +/* + * Does this SCT have the minimum fields populated to be usable? + * Returns 1 if so, 0 otherwise. + */ +int SCT_is_complete(const SCT *sct); + +/* + * Does this SCT have the signature-related fields populated? + * Returns 1 if so, 0 otherwise. + * This checks that the signature and hash algorithms are set to supported + * values and that the signature field is set. + */ +int SCT_signature_is_complete(const SCT *sct); + +/* + * TODO(RJPercival): Create an SCT_signature struct and make i2o_SCT_signature + * and o2i_SCT_signature conform to the i2d/d2i conventions. + */ + +/* + * Serialize (to TLS format) an |sct| signature and write it to |out|. + * If |out| is null, no signature will be output but the length will be returned. + * If |out| points to a null pointer, a string will be allocated to hold the + * TLS-format signature. It is the responsibility of the caller to free it. + * If |out| points to an allocated string, the signature will be written to it. + * The length of the signature in TLS format will be returned. + */ +int i2o_SCT_signature(const SCT *sct, unsigned char **out); + +/* + * Parses an SCT signature in TLS format and populates the |sct| with it. + * |in| should be a pointer to a string containing the TLS-format signature. + * |in| will be advanced to the end of the signature if parsing succeeds. + * |len| should be the length of the signature in |in|. + * Returns the number of bytes parsed, or a negative integer if an error occurs. + * If an error occurs, the SCT's signature NID may be updated whilst the + * signature field itself remains unset. + */ +int o2i_SCT_signature(SCT *sct, CBS *cbs); + +/* + * Handlers for Certificate Transparency X509v3/OCSP extensions + */ +extern const X509V3_EXT_METHOD v3_ct_scts[3]; diff --git a/Libraries/libressl/crypto/ct/ct_log.c b/Libraries/libressl/crypto/ct/ct_log.c new file mode 100644 index 000000000..eb503a381 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_log.c @@ -0,0 +1,375 @@ +/* $OpenBSD: ct_log.c,v 1.6 2023/07/08 07:22:58 beck Exp $ */ +/* Author: Adam Eijdenberg . */ +/* ==================================================================== + * Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "cryptlib.h" + + +/* + * Information about a CT log server. + */ +struct ctlog_st { + char *name; + uint8_t log_id[CT_V1_HASHLEN]; + EVP_PKEY *public_key; +}; + +/* + * A store for multiple CTLOG instances. + * It takes ownership of any CTLOG instances added to it. + */ +struct ctlog_store_st { + STACK_OF(CTLOG) *logs; +}; + +/* The context when loading a CT log list from a CONF file. */ +typedef struct ctlog_store_load_ctx_st { + CTLOG_STORE *log_store; + CONF *conf; + size_t invalid_log_entries; +} CTLOG_STORE_LOAD_CTX; + +/* + * Creates an empty context for loading a CT log store. + * It should be populated before use. + */ +static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void); + +/* + * Deletes a CT log store load context. + * Does not delete any of the fields. + */ +static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX *ctx); + +static CTLOG_STORE_LOAD_CTX * +ctlog_store_load_ctx_new(void) +{ + CTLOG_STORE_LOAD_CTX *ctx = calloc(1, sizeof(*ctx)); + + if (ctx == NULL) + CTerror(ERR_R_MALLOC_FAILURE); + + return ctx; +} + +static void +ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX *ctx) +{ + free(ctx); +} + +/* Converts a log's public key into a SHA256 log ID */ +static int +ct_v1_log_id_from_pkey(EVP_PKEY *pkey, unsigned char log_id[CT_V1_HASHLEN]) +{ + int ret = 0; + unsigned char *pkey_der = NULL; + int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der); + + if (pkey_der_len <= 0) { + CTerror(CT_R_LOG_KEY_INVALID); + goto err; + } + + SHA256(pkey_der, pkey_der_len, log_id); + ret = 1; + err: + free(pkey_der); + return ret; +} + +CTLOG_STORE * +CTLOG_STORE_new(void) +{ + CTLOG_STORE *ret = calloc(1, sizeof(*ret)); + + if (ret == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->logs = sk_CTLOG_new_null(); + if (ret->logs == NULL) + goto err; + + return ret; + err: + free(ret); + return NULL; +} +LCRYPTO_ALIAS(CTLOG_STORE_new); + +void +CTLOG_STORE_free(CTLOG_STORE *store) +{ + if (store != NULL) { + sk_CTLOG_pop_free(store->logs, CTLOG_free); + free(store); + } +} +LCRYPTO_ALIAS(CTLOG_STORE_free); + +static int +ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section) +{ + const char *description = NCONF_get_string(conf, section, + "description"); + char *pkey_base64; + + if (description == NULL) { + CTerror(CT_R_LOG_CONF_MISSING_DESCRIPTION); + return 0; + } + + pkey_base64 = NCONF_get_string(conf, section, "key"); + if (pkey_base64 == NULL) { + CTerror(CT_R_LOG_CONF_MISSING_KEY); + return 0; + } + + return CTLOG_new_from_base64(ct_log, pkey_base64, description); +} + +int +CTLOG_STORE_load_default_file(CTLOG_STORE *store) +{ + return CTLOG_STORE_load_file(store, CTLOG_FILE); +} +LCRYPTO_ALIAS(CTLOG_STORE_load_default_file); + +/* + * Called by CONF_parse_list, which stops if this returns <= 0, + * Otherwise, one bad log entry would stop loading of any of + * the following log entries. + * It may stop parsing and returns -1 on any internal (malloc) error. + */ +static int +ctlog_store_load_log(const char *log_name, int log_name_len, void *arg) +{ + CTLOG_STORE_LOAD_CTX *load_ctx = arg; + CTLOG *ct_log = NULL; + /* log_name may not be null-terminated, so fix that before using it */ + char *tmp; + int ret = 0; + + /* log_name will be NULL for empty list entries */ + if (log_name == NULL) + return 1; + + tmp = strndup(log_name, log_name_len); + if (tmp == NULL) + goto mem_err; + + ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp); + free(tmp); + + if (ret < 0) { + /* Propagate any internal error */ + return ret; + } + if (ret == 0) { + /* If we can't load this log, record that fact and skip it */ + ++load_ctx->invalid_log_entries; + return 1; + } + + if (!sk_CTLOG_push(load_ctx->log_store->logs, ct_log)) { + goto mem_err; + } + return 1; + + mem_err: + CTLOG_free(ct_log); + CTerror(ERR_R_MALLOC_FAILURE); + return -1; +} + +int +CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file) +{ + int ret = 0; + char *enabled_logs; + CTLOG_STORE_LOAD_CTX* load_ctx = ctlog_store_load_ctx_new(); + + if (load_ctx == NULL) + return 0; + load_ctx->log_store = store; + load_ctx->conf = NCONF_new(NULL); + if (load_ctx->conf == NULL) + goto end; + + if (NCONF_load(load_ctx->conf, file, NULL) <= 0) { + CTerror(CT_R_LOG_CONF_INVALID); + goto end; + } + + enabled_logs = NCONF_get_string(load_ctx->conf, NULL, "enabled_logs"); + if (enabled_logs == NULL) { + CTerror(CT_R_LOG_CONF_INVALID); + goto end; + } + + if (!CONF_parse_list(enabled_logs, ',', 1, ctlog_store_load_log, load_ctx) || + load_ctx->invalid_log_entries > 0) { + CTerror(CT_R_LOG_CONF_INVALID); + goto end; + } + + ret = 1; + end: + NCONF_free(load_ctx->conf); + ctlog_store_load_ctx_free(load_ctx); + return ret; +} +LCRYPTO_ALIAS(CTLOG_STORE_load_file); + +/* + * Initialize a new CTLOG object. + * Takes ownership of the public key. + * Copies the name. + */ +CTLOG * +CTLOG_new(EVP_PKEY *public_key, const char *name) +{ + CTLOG *ret = calloc(1, sizeof(*ret)); + + if (ret == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->name = strdup(name); + if (ret->name == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1) + goto err; + + ret->public_key = public_key; + return ret; + err: + CTLOG_free(ret); + return NULL; +} +LCRYPTO_ALIAS(CTLOG_new); + +/* Frees CT log and associated structures */ +void +CTLOG_free(CTLOG *log) +{ + if (log != NULL) { + free(log->name); + EVP_PKEY_free(log->public_key); + free(log); + } +} +LCRYPTO_ALIAS(CTLOG_free); + +const char * +CTLOG_get0_name(const CTLOG *log) +{ + return log->name; +} +LCRYPTO_ALIAS(CTLOG_get0_name); + +void +CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, size_t *log_id_len) +{ + *log_id = log->log_id; + *log_id_len = CT_V1_HASHLEN; +} +LCRYPTO_ALIAS(CTLOG_get0_log_id); + +EVP_PKEY * +CTLOG_get0_public_key(const CTLOG *log) +{ + return log->public_key; +} +LCRYPTO_ALIAS(CTLOG_get0_public_key); + +/* + * Given a log ID, finds the matching log. + * Returns NULL if no match found. + */ +const CTLOG * +CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, const uint8_t *log_id, + size_t log_id_len) +{ + int i; + + for (i = 0; i < sk_CTLOG_num(store->logs); ++i) { + const CTLOG *log = sk_CTLOG_value(store->logs, i); + if (memcmp(log->log_id, log_id, log_id_len) == 0) + return log; + } + + return NULL; +} +LCRYPTO_ALIAS(CTLOG_STORE_get0_log_by_id); diff --git a/Libraries/libressl/crypto/ct/ct_oct.c b/Libraries/libressl/crypto/ct/ct_oct.c new file mode 100644 index 000000000..1f5e5c75d --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_oct.c @@ -0,0 +1,464 @@ +/* $OpenBSD: ct_oct.c,v 1.9 2023/07/08 07:22:58 beck Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com) and Stephen Henson + * (steve@openssl.org) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include +#include + +#include +#include +#include +#include + +#include "bytestring.h" +#include "ct_local.h" + +int +o2i_SCT_signature(SCT *sct, CBS *cbs) +{ + uint8_t hash_alg, sig_alg; + CBS signature; + + if (sct->version != SCT_VERSION_V1) { + CTerror(CT_R_UNSUPPORTED_VERSION); + return 0; + } + + /* + * Parse a digitally-signed element - see RFC 6962 section 3.2 and + * RFC 5246 sections 4.7 and 7.4.1.4.1. + */ + if (!CBS_get_u8(cbs, &hash_alg)) + goto err_invalid; + if (!CBS_get_u8(cbs, &sig_alg)) + goto err_invalid; + if (!CBS_get_u16_length_prefixed(cbs, &signature)) + goto err_invalid; + if (CBS_len(cbs) != 0) + goto err_invalid; + + /* + * Reject empty signatures since they are invalid for all supported + * algorithms (this really should be done by SCT_set1_signature()). + */ + if (CBS_len(&signature) == 0) + goto err_invalid; + + sct->hash_alg = hash_alg; + sct->sig_alg = sig_alg; + + if (SCT_get_signature_nid(sct) == NID_undef) + goto err_invalid; + + if (!SCT_set1_signature(sct, CBS_data(&signature), CBS_len(&signature))) + return 0; + + return 1; + + err_invalid: + CTerror(CT_R_SCT_INVALID_SIGNATURE); + return 0; +} + +static int +o2i_SCT_internal(SCT **out_sct, CBS *cbs) +{ + SCT *sct = NULL; + uint8_t version; + + *out_sct = NULL; + + if ((sct = SCT_new()) == NULL) + goto err; + + if (CBS_len(cbs) > MAX_SCT_SIZE) + goto err_invalid; + if (!CBS_peek_u8(cbs, &version)) + goto err_invalid; + + sct->version = version; + + if (version == SCT_VERSION_V1) { + CBS extensions, log_id; + uint64_t timestamp; + + /* + * Parse a v1 SignedCertificateTimestamp - see RFC 6962 + * section 3.2. + */ + if (!CBS_get_u8(cbs, &version)) + goto err_invalid; + if (!CBS_get_bytes(cbs, &log_id, CT_V1_LOG_ID_LEN)) + goto err_invalid; + if (!CBS_get_u64(cbs, ×tamp)) + goto err_invalid; + if (!CBS_get_u16_length_prefixed(cbs, &extensions)) + goto err_invalid; + + if (!CBS_stow(&log_id, &sct->log_id, &sct->log_id_len)) + goto err; + + sct->timestamp = timestamp; + + if (!CBS_stow(&extensions, &sct->ext, &sct->ext_len)) + goto err; + + if (!o2i_SCT_signature(sct, cbs)) + goto err; + + if (CBS_len(cbs) != 0) + goto err_invalid; + } else { + /* If not V1 just cache encoding. */ + if (!CBS_stow(cbs, &sct->sct, &sct->sct_len)) + goto err; + } + + *out_sct = sct; + + return 1; + + err_invalid: + CTerror(CT_R_SCT_INVALID); + err: + SCT_free(sct); + + return 0; +} + +SCT * +o2i_SCT(SCT **psct, const unsigned char **in, size_t len) +{ + SCT *sct; + CBS cbs; + + CBS_init(&cbs, *in, len); + + if (psct != NULL) { + SCT_free(*psct); + *psct = NULL; + } + + if (!o2i_SCT_internal(&sct, &cbs)) + return NULL; + + if (psct != NULL) + *psct = sct; + + *in = CBS_data(&cbs); + + return sct; +} +LCRYPTO_ALIAS(o2i_SCT); + +int +i2o_SCT_signature(const SCT *sct, unsigned char **out) +{ + size_t len; + unsigned char *p = NULL, *pstart = NULL; + + if (!SCT_signature_is_complete(sct)) { + CTerror(CT_R_SCT_INVALID_SIGNATURE); + goto err; + } + + if (sct->version != SCT_VERSION_V1) { + CTerror(CT_R_UNSUPPORTED_VERSION); + goto err; + } + + /* + * (1 byte) Hash algorithm + * (1 byte) Signature algorithm + * (2 bytes + ?) Signature + */ + len = 4 + sct->sig_len; + + if (out != NULL) { + if (*out != NULL) { + p = *out; + *out += len; + } else { + pstart = p = malloc(len); + if (p == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + *out = p; + } + + *p++ = sct->hash_alg; + *p++ = sct->sig_alg; + s2n(sct->sig_len, p); + memcpy(p, sct->sig, sct->sig_len); + } + + return len; + err: + free(pstart); + return -1; +} + +int +i2o_SCT(const SCT *sct, unsigned char **out) +{ + size_t len; + unsigned char *p = NULL, *pstart = NULL; + + if (!SCT_is_complete(sct)) { + CTerror(CT_R_SCT_NOT_SET); + goto err; + } + /* + * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes) + * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions + * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2 + * bytes + ?) Signature + */ + if (sct->version == SCT_VERSION_V1) + len = 43 + sct->ext_len + 4 + sct->sig_len; + else + len = sct->sct_len; + + if (out == NULL) + return len; + + if (*out != NULL) { + p = *out; + *out += len; + } else { + pstart = p = malloc(len); + if (p == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + *out = p; + } + + if (sct->version == SCT_VERSION_V1) { + *p++ = sct->version; + memcpy(p, sct->log_id, CT_V1_HASHLEN); + p += CT_V1_HASHLEN; + l2n8(sct->timestamp, p); + s2n(sct->ext_len, p); + if (sct->ext_len > 0) { + memcpy(p, sct->ext, sct->ext_len); + p += sct->ext_len; + } + if (i2o_SCT_signature(sct, &p) <= 0) + goto err; + } else { + memcpy(p, sct->sct, len); + } + + return len; + err: + free(pstart); + return -1; +} +LCRYPTO_ALIAS(i2o_SCT); + +STACK_OF(SCT) * +o2i_SCT_LIST(STACK_OF(SCT) **out_scts, const unsigned char **pp, size_t len) +{ + CBS cbs, cbs_scts, cbs_sct; + STACK_OF(SCT) *scts = NULL; + + CBS_init(&cbs, *pp, len); + + if (CBS_len(&cbs) > MAX_SCT_LIST_SIZE) + goto err_invalid; + if (!CBS_get_u16_length_prefixed(&cbs, &cbs_scts)) + goto err_invalid; + if (CBS_len(&cbs) != 0) + goto err_invalid; + + if (out_scts != NULL) { + SCT_LIST_free(*out_scts); + *out_scts = NULL; + } + + if ((scts = sk_SCT_new_null()) == NULL) + return NULL; + + while (CBS_len(&cbs_scts) > 0) { + SCT *sct; + + if (!CBS_get_u16_length_prefixed(&cbs_scts, &cbs_sct)) + goto err_invalid; + + if (!o2i_SCT_internal(&sct, &cbs_sct)) + goto err; + if (!sk_SCT_push(scts, sct)) { + SCT_free(sct); + goto err; + } + } + + if (out_scts != NULL) + *out_scts = scts; + + *pp = CBS_data(&cbs); + + return scts; + + err_invalid: + CTerror(CT_R_SCT_LIST_INVALID); + err: + SCT_LIST_free(scts); + + return NULL; +} +LCRYPTO_ALIAS(o2i_SCT_LIST); + +int +i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp) +{ + int len, sct_len, i, is_pp_new = 0; + size_t len2; + unsigned char *p = NULL, *p2; + + if (pp != NULL) { + if (*pp == NULL) { + if ((len = i2o_SCT_LIST(a, NULL)) == -1) { + CTerror(CT_R_SCT_LIST_INVALID); + return -1; + } + if ((*pp = malloc(len)) == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return -1; + } + is_pp_new = 1; + } + p = *pp + 2; + } + + len2 = 2; + for (i = 0; i < sk_SCT_num(a); i++) { + if (pp != NULL) { + p2 = p; + p += 2; + if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1) + goto err; + s2n(sct_len, p2); + } else { + if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1) + goto err; + } + len2 += 2 + sct_len; + } + + if (len2 > MAX_SCT_LIST_SIZE) + goto err; + + if (pp != NULL) { + p = *pp; + s2n(len2 - 2, p); + if (!is_pp_new) + *pp += len2; + } + return len2; + + err: + if (is_pp_new) { + free(*pp); + *pp = NULL; + } + return -1; +} +LCRYPTO_ALIAS(i2o_SCT_LIST); + +STACK_OF(SCT) * +d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len) +{ + ASN1_OCTET_STRING *oct = NULL; + STACK_OF(SCT) *sk = NULL; + const unsigned char *p; + + p = *pp; + if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL) + return NULL; + + p = oct->data; + if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL) + *pp += len; + + ASN1_OCTET_STRING_free(oct); + return sk; +} +LCRYPTO_ALIAS(d2i_SCT_LIST); + +int +i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out) +{ + ASN1_OCTET_STRING oct; + int len; + + oct.data = NULL; + if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1) + return -1; + + len = i2d_ASN1_OCTET_STRING(&oct, out); + free(oct.data); + return len; +} +LCRYPTO_ALIAS(i2d_SCT_LIST); diff --git a/Libraries/libressl/crypto/ct/ct_policy.c b/Libraries/libressl/crypto/ct/ct_policy.c new file mode 100644 index 000000000..eb2b31201 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_policy.c @@ -0,0 +1,163 @@ +/* $OpenBSD: ct_policy.c,v 1.6 2023/07/08 07:22:58 beck Exp $ */ +/* + * Implementations of Certificate Transparency SCT policies. + * Written by Rob Percival (robpercival@google.com) for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include +#include +#include + +#include "ct_local.h" + +/* + * Number of seconds in the future that an SCT timestamp can be, by default, + * without being considered invalid. This is added to time() when setting a + * default value for CT_POLICY_EVAL_CTX.epoch_time_in_ms. + * It can be overridden by calling CT_POLICY_EVAL_CTX_set_time(). + */ +static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300; + +CT_POLICY_EVAL_CTX * +CT_POLICY_EVAL_CTX_new(void) +{ + CT_POLICY_EVAL_CTX *ctx = calloc(1, sizeof(CT_POLICY_EVAL_CTX)); + + if (ctx == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* time(NULL) shouldn't ever fail, so don't bother checking for -1. */ + ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) * + 1000; + + return ctx; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_new); + +void +CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx) +{ + if (ctx == NULL) + return; + X509_free(ctx->cert); + X509_free(ctx->issuer); + free(ctx); +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_free); + +int +CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert) +{ + if (!X509_up_ref(cert)) + return 0; + ctx->cert = cert; + return 1; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_set1_cert); + +int +CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer) +{ + if (!X509_up_ref(issuer)) + return 0; + ctx->issuer = issuer; + return 1; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_set1_issuer); + +void +CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_STORE *log_store) +{ + ctx->log_store = log_store; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE); + +void +CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms) +{ + ctx->epoch_time_in_ms = time_in_ms; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_set_time); + +X509 * +CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx) +{ + return ctx->cert; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_get0_cert); + +X509 * +CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx) +{ + return ctx->issuer; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_get0_issuer); + +const CTLOG_STORE * +CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx) +{ + return ctx->log_store; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_get0_log_store); + +uint64_t +CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx) +{ + return ctx->epoch_time_in_ms; +} +LCRYPTO_ALIAS(CT_POLICY_EVAL_CTX_get_time); diff --git a/Libraries/libressl/crypto/ct/ct_prn.c b/Libraries/libressl/crypto/ct/ct_prn.c new file mode 100644 index 000000000..e6931eeb0 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_prn.c @@ -0,0 +1,211 @@ +/* $OpenBSD: ct_prn.c,v 1.7 2023/07/08 07:22:58 beck Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com) and Stephen Henson + * (steve@openssl.org) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include +#include + +#include "ct_local.h" + +/* + * XXX public api in OpenSSL 1.1.0 but this is the only thing that uses it. + * so I am stuffing it here for the moment. + */ +static int +BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen) +{ + int i, j = 0; + + if (datalen < 1) + return 1; + + for (i = 0; i < datalen - 1; i++) { + if (i && !j) + BIO_printf(out, "%*s", indent, ""); + + BIO_printf(out, "%02X:", data[i]); + + j = (j + 1) % width; + if (!j) + BIO_printf(out, "\n"); + } + + if (i && !j) + BIO_printf(out, "%*s", indent, ""); + BIO_printf(out, "%02X", data[datalen - 1]); + return 1; +} + +static void +SCT_signature_algorithms_print(const SCT *sct, BIO *out) +{ + int nid = SCT_get_signature_nid(sct); + + if (nid == NID_undef) + BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg); + else + BIO_printf(out, "%s", OBJ_nid2ln(nid)); +} + +static void +timestamp_print(uint64_t timestamp, BIO *out) +{ + ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new(); + char genstr[20]; + + if (gen == NULL) + return; + ASN1_GENERALIZEDTIME_adj(gen, (time_t)0, (int)(timestamp / 86400000), + (timestamp % 86400000) / 1000); + /* + * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 + * characters long with a final Z. Update it with fractional seconds. + */ + snprintf(genstr, sizeof(genstr), "%.14sZ", ASN1_STRING_get0_data(gen)); + if (ASN1_GENERALIZEDTIME_set_string(gen, genstr)) + ASN1_GENERALIZEDTIME_print(out, gen); + ASN1_GENERALIZEDTIME_free(gen); +} + +const char * +SCT_validation_status_string(const SCT *sct) +{ + switch (SCT_get_validation_status(sct)) { + case SCT_VALIDATION_STATUS_NOT_SET: + return "not set"; + case SCT_VALIDATION_STATUS_UNKNOWN_VERSION: + return "unknown version"; + case SCT_VALIDATION_STATUS_UNKNOWN_LOG: + return "unknown log"; + case SCT_VALIDATION_STATUS_UNVERIFIED: + return "unverified"; + case SCT_VALIDATION_STATUS_INVALID: + return "invalid"; + case SCT_VALIDATION_STATUS_VALID: + return "valid"; + } + return "unknown status"; +} +LCRYPTO_ALIAS(SCT_validation_status_string); + +void +SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *log_store) +{ + const CTLOG *log = NULL; + + if (log_store != NULL) { + log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id, + sct->log_id_len); + } + + BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, ""); + BIO_printf(out, "\n%*sVersion : ", indent + 4, ""); + + if (sct->version != SCT_VERSION_V1) { + BIO_printf(out, "unknown\n%*s", indent + 16, ""); + BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len); + return; + } + + BIO_printf(out, "v1 (0x0)"); + + if (log != NULL) { + BIO_printf(out, "\n%*sLog : %s", indent + 4, "", + CTLOG_get0_name(log)); + } + + BIO_printf(out, "\n%*sLog ID : ", indent + 4, ""); + BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len); + + BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); + timestamp_print(sct->timestamp, out); + + BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); + if (sct->ext_len == 0) + BIO_printf(out, "none"); + else + BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len); + + BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); + SCT_signature_algorithms_print(sct, out); + BIO_printf(out, "\n%*s ", indent + 4, ""); + BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len); +} +LCRYPTO_ALIAS(SCT_print); + +void +SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, + const char *separator, const CTLOG_STORE *log_store) +{ + int sct_count = sk_SCT_num(sct_list); + int i; + + for (i = 0; i < sct_count; ++i) { + SCT *sct = sk_SCT_value(sct_list, i); + + SCT_print(sct, out, indent, log_store); + if (i < sk_SCT_num(sct_list) - 1) + BIO_printf(out, "%s", separator); + } +} +LCRYPTO_ALIAS(SCT_LIST_print); diff --git a/Libraries/libressl/crypto/ct/ct_sct.c b/Libraries/libressl/crypto/ct/ct_sct.c new file mode 100644 index 000000000..4b2716e73 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_sct.c @@ -0,0 +1,507 @@ +/* $OpenBSD: ct_sct.c,v 1.10 2023/07/22 17:02:49 tb Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com), Stephen Henson (steve@openssl.org) + * and Adam Eijdenberg (adam.eijdenberg@gmail.com) for the OpenSSL project 2016. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_CT +# error "CT disabled" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ct_local.h" + +SCT * +SCT_new(void) +{ + SCT *sct = calloc(1, sizeof(*sct)); + + if (sct == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET; + sct->version = SCT_VERSION_NOT_SET; + return sct; +} +LCRYPTO_ALIAS(SCT_new); + +void +SCT_free(SCT *sct) +{ + if (sct == NULL) + return; + + free(sct->log_id); + free(sct->ext); + free(sct->sig); + free(sct->sct); + free(sct); +} +LCRYPTO_ALIAS(SCT_free); + +void +SCT_LIST_free(STACK_OF(SCT) *scts) +{ + sk_SCT_pop_free(scts, SCT_free); +} +LCRYPTO_ALIAS(SCT_LIST_free); + +int +SCT_set_version(SCT *sct, sct_version_t version) +{ + if (version != SCT_VERSION_V1) { + CTerror(CT_R_UNSUPPORTED_VERSION); + return 0; + } + sct->version = version; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + return 1; +} +LCRYPTO_ALIAS(SCT_set_version); + +int +SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type) +{ + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + + switch (entry_type) { + case CT_LOG_ENTRY_TYPE_X509: + case CT_LOG_ENTRY_TYPE_PRECERT: + sct->entry_type = entry_type; + return 1; + case CT_LOG_ENTRY_TYPE_NOT_SET: + break; + } + CTerror(CT_R_UNSUPPORTED_ENTRY_TYPE); + return 0; +} +LCRYPTO_ALIAS(SCT_set_log_entry_type); + +int +SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len) +{ + if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { + CTerror(CT_R_INVALID_LOG_ID_LENGTH); + return 0; + } + + free(sct->log_id); + sct->log_id = log_id; + sct->log_id_len = log_id_len; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + return 1; +} +LCRYPTO_ALIAS(SCT_set0_log_id); + +int +SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len) +{ + if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { + CTerror(CT_R_INVALID_LOG_ID_LENGTH); + return 0; + } + + free(sct->log_id); + sct->log_id = NULL; + sct->log_id_len = 0; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + + if (log_id != NULL && log_id_len > 0) { + sct->log_id = malloc(log_id_len); + if (sct->log_id == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(sct->log_id, log_id, log_id_len); + sct->log_id_len = log_id_len; + } + return 1; +} +LCRYPTO_ALIAS(SCT_set1_log_id); + + +void +SCT_set_timestamp(SCT *sct, uint64_t timestamp) +{ + sct->timestamp = timestamp; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; +} +LCRYPTO_ALIAS(SCT_set_timestamp); + +int +SCT_set_signature_nid(SCT *sct, int nid) +{ + switch (nid) { + case NID_sha256WithRSAEncryption: + sct->hash_alg = 4; /* XXX */ + sct->sig_alg = 1; /* XXX */ + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + return 1; + case NID_ecdsa_with_SHA256: + sct->hash_alg = 4; /* XXX */ + sct->sig_alg = 3; /* XXX */ + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + return 1; + default: + CTerror(CT_R_UNRECOGNIZED_SIGNATURE_NID); + return 0; + } +} +LCRYPTO_ALIAS(SCT_set_signature_nid); + +void +SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len) +{ + free(sct->ext); + sct->ext = ext; + sct->ext_len = ext_len; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; +} +LCRYPTO_ALIAS(SCT_set0_extensions); + +int +SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len) +{ + free(sct->ext); + sct->ext = NULL; + sct->ext_len = 0; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + + if (ext != NULL && ext_len > 0) { + sct->ext = malloc(ext_len); + if (sct->ext == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(sct->ext, ext, ext_len); + sct->ext_len = ext_len; + } + return 1; +} +LCRYPTO_ALIAS(SCT_set1_extensions); + +void +SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len) +{ + free(sct->sig); + sct->sig = sig; + sct->sig_len = sig_len; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; +} +LCRYPTO_ALIAS(SCT_set0_signature); + +int +SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len) +{ + free(sct->sig); + sct->sig = NULL; + sct->sig_len = 0; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + + if (sig != NULL && sig_len > 0) { + sct->sig = malloc(sig_len); + if (sct->sig == NULL) { + CTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(sct->sig, sig, sig_len); + sct->sig_len = sig_len; + } + return 1; +} +LCRYPTO_ALIAS(SCT_set1_signature); + +sct_version_t +SCT_get_version(const SCT *sct) +{ + return sct->version; +} +LCRYPTO_ALIAS(SCT_get_version); + +ct_log_entry_type_t +SCT_get_log_entry_type(const SCT *sct) +{ + return sct->entry_type; +} +LCRYPTO_ALIAS(SCT_get_log_entry_type); + +size_t +SCT_get0_log_id(const SCT *sct, unsigned char **log_id) +{ + *log_id = sct->log_id; + return sct->log_id_len; +} +LCRYPTO_ALIAS(SCT_get0_log_id); + +uint64_t +SCT_get_timestamp(const SCT *sct) +{ + return sct->timestamp; +} +LCRYPTO_ALIAS(SCT_get_timestamp); + +int +SCT_get_signature_nid(const SCT *sct) +{ + if (sct->version == SCT_VERSION_V1) { + /* XXX sigalg numbers */ + if (sct->hash_alg == 4) { + switch (sct->sig_alg) { + case 3: + return NID_ecdsa_with_SHA256; + case 1: + return NID_sha256WithRSAEncryption; + default: + return NID_undef; + } + } + } + return NID_undef; +} +LCRYPTO_ALIAS(SCT_get_signature_nid); + +size_t +SCT_get0_extensions(const SCT *sct, unsigned char **ext) +{ + *ext = sct->ext; + return sct->ext_len; +} +LCRYPTO_ALIAS(SCT_get0_extensions); + +size_t +SCT_get0_signature(const SCT *sct, unsigned char **sig) +{ + *sig = sct->sig; + return sct->sig_len; +} +LCRYPTO_ALIAS(SCT_get0_signature); + +int +SCT_is_complete(const SCT *sct) +{ + switch (sct->version) { + case SCT_VERSION_NOT_SET: + return 0; + case SCT_VERSION_V1: + return sct->log_id != NULL && SCT_signature_is_complete(sct); + default: + return sct->sct != NULL; /* Just need cached encoding */ + } +} + +int +SCT_signature_is_complete(const SCT *sct) +{ + return SCT_get_signature_nid(sct) != NID_undef && + sct->sig != NULL && sct->sig_len > 0; +} + +sct_source_t +SCT_get_source(const SCT *sct) +{ + return sct->source; +} +LCRYPTO_ALIAS(SCT_get_source); + +int +SCT_set_source(SCT *sct, sct_source_t source) +{ + sct->source = source; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; + switch (source) { + case SCT_SOURCE_TLS_EXTENSION: + case SCT_SOURCE_OCSP_STAPLED_RESPONSE: + return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509); + case SCT_SOURCE_X509V3_EXTENSION: + return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT); + case SCT_SOURCE_UNKNOWN: + break; + } + /* if we aren't sure, leave the log entry type alone */ + return 1; +} +LCRYPTO_ALIAS(SCT_set_source); + +sct_validation_status_t +SCT_get_validation_status(const SCT *sct) +{ + return sct->validation_status; +} +LCRYPTO_ALIAS(SCT_get_validation_status); + +int +SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx) +{ + int is_sct_valid = -1; + SCT_CTX *sctx = NULL; + X509_PUBKEY *pub = NULL, *log_pkey = NULL; + const CTLOG *log; + + /* + * With an unrecognized SCT version we don't know what such an SCT means, + * let alone validate one. So we return validation failure (0). + */ + if (sct->version != SCT_VERSION_V1) { + sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION; + return 0; + } + + log = CTLOG_STORE_get0_log_by_id(ctx->log_store, sct->log_id, + sct->log_id_len); + + /* Similarly, an SCT from an unknown log also cannot be validated. */ + if (log == NULL) { + sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG; + return 0; + } + + sctx = SCT_CTX_new(); + if (sctx == NULL) + goto err; + + if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1) + goto err; + if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1) + goto err; + + if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) { + EVP_PKEY *issuer_pkey; + + if (ctx->issuer == NULL) { + sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; + goto end; + } + + if ((issuer_pkey = X509_get0_pubkey(ctx->issuer)) == NULL) + goto err; + + if (X509_PUBKEY_set(&pub, issuer_pkey) != 1) + goto err; + if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1) + goto err; + } + + SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms); + + /* + * XXX: Potential for optimization. This repeats some idempotent heavy + * lifting on the certificate for each candidate SCT, and appears to not + * use any information in the SCT itself, only the certificate is + * processed. So it may make more sense to to do this just once, perhaps + * associated with the shared (by all SCTs) policy eval ctx. + * + * XXX: Failure here is global (SCT independent) and represents either an + * issue with the certificate (e.g. duplicate extensions) or an out of + * memory condition. When the certificate is incompatible with CT, we just + * mark the SCTs invalid, rather than report a failure to determine the + * validation status. That way, callbacks that want to do "soft" SCT + * processing will not abort handshakes with false positive internal + * errors. Since the function does not distinguish between certificate + * issues (peer's fault) and internal problems (out fault) the safe thing + * to do is to report a validation failure and let the callback or + * application decide what to do. + */ + if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1) + sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; + else + sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ? + SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID; + + end: + is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID; + err: + X509_PUBKEY_free(pub); + X509_PUBKEY_free(log_pkey); + SCT_CTX_free(sctx); + + return is_sct_valid; +} +LCRYPTO_ALIAS(SCT_validate); + +int +SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx) +{ + int are_scts_valid = 1; + int sct_count = scts != NULL ? sk_SCT_num(scts) : 0; + int i; + + for (i = 0; i < sct_count; ++i) { + int is_sct_valid = -1; + SCT *sct = sk_SCT_value(scts, i); + + if (sct == NULL) + continue; + + is_sct_valid = SCT_validate(sct, ctx); + if (is_sct_valid < 0) + return is_sct_valid; + are_scts_valid &= is_sct_valid; + } + + return are_scts_valid; +} +LCRYPTO_ALIAS(SCT_LIST_validate); diff --git a/Libraries/libressl/crypto/ct/ct_sct_ctx.c b/Libraries/libressl/crypto/ct/ct_sct_ctx.c new file mode 100644 index 000000000..b2b6d4e26 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_sct_ctx.c @@ -0,0 +1,323 @@ +/* $OpenBSD: ct_sct_ctx.c,v 1.6 2022/06/30 11:14:47 tb Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com) and Stephen Henson + * (steve@openssl.org) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include +#include + +#include +#include +#include + +#include "ct_local.h" + +SCT_CTX * +SCT_CTX_new(void) +{ + SCT_CTX *sctx = calloc(1, sizeof(*sctx)); + + if (sctx == NULL) + CTerror(ERR_R_MALLOC_FAILURE); + + return sctx; +} + +void +SCT_CTX_free(SCT_CTX *sctx) +{ + if (sctx == NULL) + return; + EVP_PKEY_free(sctx->pkey); + free(sctx->pkeyhash); + free(sctx->ihash); + free(sctx->certder); + free(sctx->preder); + free(sctx); +} + +/* + * Finds the index of the first extension with the given NID in cert. + * If there is more than one extension with that NID, *is_duplicated is set to + * 1, otherwise 0 (unless it is NULL). + */ +static int +ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated) +{ + int ret = X509_get_ext_by_NID(cert, nid, -1); + + if (is_duplicated != NULL) + *is_duplicated = ret >= 0 && + X509_get_ext_by_NID(cert, nid, ret) >= 0; + + return ret; +} + +/* + * Modifies a certificate by deleting extensions and copying the issuer and + * AKID from the presigner certificate, if necessary. + * Returns 1 on success, 0 otherwise. + */ +static int +ct_x509_cert_fixup(X509 *cert, X509 *presigner) +{ + int preidx, certidx; + int pre_akid_ext_is_dup, cert_akid_ext_is_dup; + + if (presigner == NULL) + return 1; + + preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier, + &pre_akid_ext_is_dup); + certidx = ct_x509_get_ext(cert, NID_authority_key_identifier, + &cert_akid_ext_is_dup); + + /* An error occurred whilst searching for the extension */ + if (preidx < -1 || certidx < -1) + return 0; + /* Invalid certificate if they contain duplicate extensions */ + if (pre_akid_ext_is_dup || cert_akid_ext_is_dup) + return 0; + /* AKID must be present in both certificate or absent in both */ + if (preidx >= 0 && certidx == -1) + return 0; + if (preidx == -1 && certidx >= 0) + return 0; + /* Copy issuer name */ + if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner))) + return 0; + if (preidx != -1) { + /* Retrieve and copy AKID encoding */ + X509_EXTENSION *preext = X509_get_ext(presigner, preidx); + X509_EXTENSION *certext = X509_get_ext(cert, certidx); + ASN1_OCTET_STRING *preextdata; + + /* Should never happen */ + if (preext == NULL || certext == NULL) + return 0; + preextdata = X509_EXTENSION_get_data(preext); + if (preextdata == NULL || + !X509_EXTENSION_set_data(certext, preextdata)) + return 0; + } + return 1; +} + +int +SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner) +{ + unsigned char *certder = NULL, *preder = NULL; + X509 *pretmp = NULL; + int certderlen = 0, prederlen = 0; + int idx = -1; + int poison_ext_is_dup, sct_ext_is_dup; + int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup); + + /* Duplicate poison extensions are present - error */ + if (poison_ext_is_dup) + goto err; + + /* If *cert doesn't have a poison extension, it isn't a precert */ + if (poison_idx == -1) { + /* cert isn't a precert, so we shouldn't have a presigner */ + if (presigner != NULL) + goto err; + + certderlen = i2d_X509(cert, &certder); + if (certderlen < 0) + goto err; + } + + /* See if cert has a precert SCTs extension */ + idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup); + /* Duplicate SCT extensions are present - error */ + if (sct_ext_is_dup) + goto err; + + if (idx >= 0 && poison_idx >= 0) { + /* + * cert can't both contain SCTs (i.e. have an SCT extension) and be a + * precert (i.e. have a poison extension). + */ + goto err; + } + + if (idx == -1) { + idx = poison_idx; + } + + /* + * If either a poison or SCT extension is present, remove it before encoding + * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see + * RFC5280) from cert, which is what the CT log signed when it produced the + * SCT. + */ + if (idx >= 0) { + X509_EXTENSION *ext; + + /* Take a copy of certificate so we don't modify passed version */ + pretmp = X509_dup(cert); + if (pretmp == NULL) + goto err; + + ext = X509_delete_ext(pretmp, idx); + X509_EXTENSION_free(ext); + + if (!ct_x509_cert_fixup(pretmp, presigner)) + goto err; + + prederlen = i2d_re_X509_tbs(pretmp, &preder); + if (prederlen <= 0) + goto err; + } + + X509_free(pretmp); + + free(sctx->certder); + sctx->certder = certder; + sctx->certderlen = certderlen; + + free(sctx->preder); + sctx->preder = preder; + sctx->prederlen = prederlen; + + return 1; + err: + free(certder); + free(preder); + X509_free(pretmp); + return 0; +} + +static int +ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash, size_t *hash_len) +{ + int ret = 0; + unsigned char *md = NULL, *der = NULL; + int der_len; + unsigned int md_len; + + /* Reuse buffer if possible */ + if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) { + md = *hash; + } else { + md = malloc(SHA256_DIGEST_LENGTH); + if (md == NULL) + goto err; + } + + /* Calculate key hash */ + der_len = i2d_X509_PUBKEY(pkey, &der); + if (der_len <= 0) + goto err; + + if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL)) + goto err; + + if (md != *hash) { + free(*hash); + *hash = md; + *hash_len = SHA256_DIGEST_LENGTH; + } + + md = NULL; + ret = 1; + err: + free(md); + free(der); + return ret; +} + +int +SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer) +{ + return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer)); +} + +int +SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) +{ + return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen); +} + +int +SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) +{ + EVP_PKEY *pkey = X509_PUBKEY_get(pubkey); + + if (pkey == NULL) + return 0; + + if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) { + EVP_PKEY_free(pkey); + return 0; + } + + EVP_PKEY_free(sctx->pkey); + sctx->pkey = pkey; + return 1; +} + +void +SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms) +{ + sctx->epoch_time_in_ms = time_in_ms; +} diff --git a/Libraries/libressl/crypto/ct/ct_vfy.c b/Libraries/libressl/crypto/ct/ct_vfy.c new file mode 100644 index 000000000..424117263 --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_vfy.c @@ -0,0 +1,195 @@ +/* $OpenBSD: ct_vfy.c,v 1.6 2022/01/06 14:34:40 jsing Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com) and Stephen Henson + * (steve@openssl.org) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "ct_local.h" + +typedef enum sct_signature_type_t { + SIGNATURE_TYPE_NOT_SET = -1, + SIGNATURE_TYPE_CERT_TIMESTAMP, + SIGNATURE_TYPE_TREE_HASH +} SCT_SIGNATURE_TYPE; + +/* + * Update encoding for SCT signature verification/generation to supplied + * EVP_MD_CTX. + */ +static int +sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct) +{ + CBB cbb, entry, extensions; + uint8_t *data = NULL; + size_t data_len; + int ret = 0; + + memset(&cbb, 0, sizeof(cbb)); + + if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET) + goto err; + if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL) + goto err; + + if (!CBB_init(&cbb, 0)) + goto err; + + /* + * Build the digitally-signed struct per RFC 6962 section 3.2. + */ + if (!CBB_add_u8(&cbb, sct->version)) + goto err; + if (!CBB_add_u8(&cbb, SIGNATURE_TYPE_CERT_TIMESTAMP)) + goto err; + if (!CBB_add_u64(&cbb, sct->timestamp)) + goto err; + if (!CBB_add_u16(&cbb, sct->entry_type)) + goto err; + + if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT) { + if (!CBB_add_bytes(&cbb, sctx->ihash, sctx->ihashlen)) + goto err; + } + + if (!CBB_add_u24_length_prefixed(&cbb, &entry)) + goto err; + if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT) { + if (sctx->preder == NULL) + goto err; + if (!CBB_add_bytes(&entry, sctx->preder, sctx->prederlen)) + goto err; + } else { + if (sctx->certder == NULL) + goto err; + if (!CBB_add_bytes(&entry, sctx->certder, sctx->certderlen)) + goto err; + } + + if (!CBB_add_u16_length_prefixed(&cbb, &extensions)) + goto err; + if (sct->ext_len > 0) { + if (!CBB_add_bytes(&extensions, sct->ext, sct->ext_len)) + goto err; + } + + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; + + if (!EVP_DigestUpdate(ctx, data, data_len)) + goto err; + + ret = 1; + + err: + CBB_cleanup(&cbb); + free(data); + + return ret; +} + +int +SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) +{ + EVP_MD_CTX *ctx = NULL; + int ret = 0; + + if (!SCT_is_complete(sct) || sctx->pkey == NULL || + sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET || + (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && + sctx->ihash == NULL)) { + CTerror(CT_R_SCT_NOT_SET); + return 0; + } + if (sct->version != SCT_VERSION_V1) { + CTerror(CT_R_SCT_UNSUPPORTED_VERSION); + return 0; + } + if (sct->log_id_len != sctx->pkeyhashlen || + memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) { + CTerror(CT_R_SCT_LOG_ID_MISMATCH); + return 0; + } + if (sct->timestamp > sctx->epoch_time_in_ms) { + CTerror(CT_R_SCT_FUTURE_TIMESTAMP); + return 0; + } + + if ((ctx = EVP_MD_CTX_new()) == NULL) + goto end; + + if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey)) + goto end; + + if (!sct_ctx_update(ctx, sctx, sct)) + goto end; + + /* Verify signature */ + /* If ret < 0 some other error: fall through without setting error */ + if ((ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len)) == 0) + CTerror(CT_R_SCT_INVALID_SIGNATURE); + + end: + EVP_MD_CTX_free(ctx); + + return ret; +} diff --git a/Libraries/libressl/crypto/ct/ct_x509v3.c b/Libraries/libressl/crypto/ct/ct_x509v3.c new file mode 100644 index 000000000..59f2975cd --- /dev/null +++ b/Libraries/libressl/crypto/ct/ct_x509v3.c @@ -0,0 +1,186 @@ +/* $OpenBSD: ct_x509v3.c,v 1.6 2021/12/25 15:42:32 tb Exp $ */ +/* + * Written by Rob Stradling (rob@comodo.com) and Stephen Henson + * (steve@openssl.org) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include + +#include "ct_local.h" + +static char * +i2s_poison(const X509V3_EXT_METHOD *method, void *val) +{ + return strdup("NULL"); +} + +static void * +s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +static int +i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, BIO *out, + int indent) +{ + SCT_LIST_print(sct_list, out, indent, "\n", NULL); + return 1; +} + +static int +set_sct_list_source(STACK_OF(SCT) *s, sct_source_t source) +{ + if (s != NULL) { + int i; + + for (i = 0; i < sk_SCT_num(s); i++) { + int res = SCT_set_source(sk_SCT_value(s, i), source); + + if (res != 1) { + return 0; + } + } + } + return 1; +} + +static STACK_OF(SCT) * +x509_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len) +{ + STACK_OF(SCT) *s = d2i_SCT_LIST(a, pp, len); + + if (set_sct_list_source(s, SCT_SOURCE_X509V3_EXTENSION) != 1) { + SCT_LIST_free(s); + *a = NULL; + return NULL; + } + return s; +} + +static STACK_OF(SCT) * +ocsp_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len) +{ + STACK_OF(SCT) *s = d2i_SCT_LIST(a, pp, len); + + if (set_sct_list_source(s, SCT_SOURCE_OCSP_STAPLED_RESPONSE) != 1) { + SCT_LIST_free(s); + *a = NULL; + return NULL; + } + return s; +} + +/* Handlers for X509v3/OCSP Certificate Transparency extensions */ +const X509V3_EXT_METHOD v3_ct_scts[3] = { + /* X509v3 extension in certificates that contains SCTs */ + [0] = { + .ext_nid = NID_ct_precert_scts, + .ext_flags = 0, + .it = NULL, + .ext_new = NULL, + .ext_free = (X509V3_EXT_FREE)SCT_LIST_free, + .d2i = (X509V3_EXT_D2I)x509_ext_d2i_SCT_LIST, + .i2d = (X509V3_EXT_I2D)i2d_SCT_LIST, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_SCT_LIST, + .r2i = NULL, + .usr_data = NULL, + }, + + /* X509v3 extension to mark a certificate as a pre-certificate */ + [1] = { + .ext_nid = NID_ct_precert_poison, + .ext_flags = 0, + .it = &ASN1_NULL_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = i2s_poison, + .s2i = s2i_poison, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + + /* OCSP extension that contains SCTs */ + [2] = { + .ext_nid = NID_ct_cert_scts, + .ext_flags = 0, + .it = NULL, + .ext_new = NULL, + .ext_free = (X509V3_EXT_FREE)SCT_LIST_free, + .d2i = (X509V3_EXT_D2I)ocsp_ext_d2i_SCT_LIST, + .i2d = (X509V3_EXT_I2D)i2d_SCT_LIST, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_SCT_LIST, + .r2i = NULL, + .usr_data = NULL, + }, +}; diff --git a/Libraries/libressl/crypto/curve25519/curve25519-generic.c b/Libraries/libressl/crypto/curve25519/curve25519-generic.c new file mode 100644 index 000000000..d533731ef --- /dev/null +++ b/Libraries/libressl/crypto/curve25519/curve25519-generic.c @@ -0,0 +1,34 @@ +/* $OpenBSD: curve25519-generic.c,v 1.2 2019/05/11 15:55:52 tb Exp $ */ +/* + * Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP + * 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as + * public domain but this file has the ISC license just to keep licencing + * simple. + * + * The field functions are shared by Ed25519 and X25519 where possible. + */ + +#include "curve25519_internal.h" + +void +x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) +{ + x25519_scalar_mult_generic(out, scalar, point); +} diff --git a/Libraries/libressl/crypto/curve25519/curve25519.c b/Libraries/libressl/crypto/curve25519/curve25519.c new file mode 100644 index 000000000..4e644c428 --- /dev/null +++ b/Libraries/libressl/crypto/curve25519/curve25519.c @@ -0,0 +1,4946 @@ +/* $OpenBSD: curve25519.c,v 1.16 2023/07/08 15:12:49 beck Exp $ */ +/* + * Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP + * 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as + * public domain but this file has the ISC license just to keep licencing + * simple. + * + * The field functions are shared by Ed25519 and X25519 where possible. + */ + +#include +#include +#include + +#include +#include + +#include "curve25519_internal.h" + +static const int64_t kBottom25Bits = 0x1ffffffLL; +static const int64_t kBottom26Bits = 0x3ffffffLL; +static const int64_t kTop39Bits = 0xfffffffffe000000LL; +static const int64_t kTop38Bits = 0xfffffffffc000000LL; + +static uint64_t load_3(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + return result; +} + +static uint64_t load_4(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + return result; +} + +static void fe_frombytes(fe h, const uint8_t *s) { + /* Ignores top bit of h. */ + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits; + carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits; + carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits; + carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits; + carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits; + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits; + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits; + carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* Preconditions: + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + * + * Write p=2^255-19; q=floor(h/p). + * Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + * + * Proof: + * Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + * Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + * + * Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + * Then 0> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + h1 += h0 >> 26; h0 &= kBottom26Bits; + h2 += h1 >> 25; h1 &= kBottom25Bits; + h3 += h2 >> 26; h2 &= kBottom26Bits; + h4 += h3 >> 25; h3 &= kBottom25Bits; + h5 += h4 >> 26; h4 &= kBottom26Bits; + h6 += h5 >> 25; h5 &= kBottom25Bits; + h7 += h6 >> 26; h6 &= kBottom26Bits; + h8 += h7 >> 25; h7 &= kBottom25Bits; + h9 += h8 >> 26; h8 &= kBottom26Bits; + h9 &= kBottom25Bits; + /* h10 = carry9 */ + + /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + * Have h0+...+2^230 h9 between 0 and 2^255-1; + * evidently 2^255 h10-2^255 q = 0. + * Goal: Output h0+...+2^230 h9. */ + + s[0] = h0 >> 0; + s[1] = h0 >> 8; + s[2] = h0 >> 16; + s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2); + s[4] = h1 >> 6; + s[5] = h1 >> 14; + s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3); + s[7] = h2 >> 5; + s[8] = h2 >> 13; + s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5); + s[10] = h3 >> 3; + s[11] = h3 >> 11; + s[12] = (h3 >> 19) | ((uint32_t)(h4) << 6); + s[13] = h4 >> 2; + s[14] = h4 >> 10; + s[15] = h4 >> 18; + s[16] = h5 >> 0; + s[17] = h5 >> 8; + s[18] = h5 >> 16; + s[19] = (h5 >> 24) | ((uint32_t)(h6) << 1); + s[20] = h6 >> 7; + s[21] = h6 >> 15; + s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3); + s[23] = h7 >> 5; + s[24] = h7 >> 13; + s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4); + s[26] = h8 >> 4; + s[27] = h8 >> 12; + s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6); + s[29] = h9 >> 2; + s[30] = h9 >> 10; + s[31] = h9 >> 18; +} + +/* h = f */ +static void fe_copy(fe h, const fe f) { + memmove(h, f, sizeof(int32_t) * 10); +} + +/* h = 0 */ +static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); } + +/* h = 1 */ +static void fe_1(fe h) { + memset(h, 0, sizeof(int32_t) * 10); + h[0] = 1; +} + +/* h = f + g + * Can overlap h with f or g. + * + * Preconditions: + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static void fe_add(fe h, const fe f, const fe g) { + unsigned i; + for (i = 0; i < 10; i++) { + h[i] = f[i] + g[i]; + } +} + +/* h = f - g + * Can overlap h with f or g. + * + * Preconditions: + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static void fe_sub(fe h, const fe f, const fe g) { + unsigned i; + for (i = 0; i < 10; i++) { + h[i] = f[i] - g[i]; + } +} + +/* h = f * g + * Can overlap h with f or g. + * + * Preconditions: + * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + * + * Notes on implementation strategy: + * + * Using schoolbook multiplication. + * Karatsuba would save a little in some cost models. + * + * Most multiplications by 2 and 19 are 32-bit precomputations; + * cheaper than 64-bit postcomputations. + * + * There is one remaining multiplication by 19 in the carry chain; + * one *19 precomputation can be merged into this, + * but the resulting data flow is considerably less clean. + * + * There are 12 carries below. + * 10 of them are 2-way parallelizable and vectorizable. + * Can get away with 11 carries, but then data flow is much deeper. + * + * With tighter constraints on inputs can squeeze carries into int32. */ +static void fe_mul(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; + int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; + int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; + int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; + int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; + int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; + int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; + int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; + int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; + int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + * i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + * i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */ + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits; + carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits; + carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits; + carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* h = f * f + * Can overlap h with f. + * + * Preconditions: + * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + * + * See fe_mul.c for discussion of implementation strategy. */ +static void fe_sq(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + + carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits; + carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits; + + carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits; + carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits; + + carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits; + carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits; + + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits; + + carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits; + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +static void fe_invert(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq(t0, z); + fe_sq(t1, t0); + for (i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t2, t0); + fe_mul(t1, t1, t2); + fe_sq(t2, t1); + for (i = 1; i < 5; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + for (i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + for (i = 1; i < 20; ++i) { + fe_sq(t3, t3); + } + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + for (i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + for (i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + for (i = 1; i < 100; ++i) { + fe_sq(t3, t3); + } + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + for (i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } + fe_mul(out, t1, t0); +} + +/* h = -f + * + * Preconditions: + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */ +static void fe_neg(fe h, const fe f) { + unsigned i; + for (i = 0; i < 10; i++) { + h[i] = -f[i]; + } +} + +/* Replace (f,g) with (g,g) if b == 1; + * replace (f,g) with (f,g) if b == 0. + * + * Preconditions: b in {0,1}. */ +static void fe_cmov(fe f, const fe g, unsigned b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + int32_t x = f[i] ^ g[i]; + x &= b; + f[i] ^= x; + } +} + +/* return 0 if f == 0 + * return 1 if f != 0 + * + * Preconditions: + * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static int fe_isnonzero(const fe f) { + uint8_t s[32]; + fe_tobytes(s, f); + + static const uint8_t zero[32] = {0}; + return timingsafe_memcmp(s, zero, sizeof(zero)) != 0; +} + +/* return 1 if f is in {1,3,5,...,q-2} + * return 0 if f is in {0,2,4,...,q-1} + * + * Preconditions: + * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static int fe_isnegative(const fe f) { + uint8_t s[32]; + fe_tobytes(s, f); + return s[0] & 1; +} + +/* h = 2 * f * f + * Can overlap h with f. + * + * Preconditions: + * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + * + * See fe_mul.c for discussion of implementation strategy. */ +static void fe_sq2(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + + carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits; + carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits; + + carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits; + carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits; + + carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits; + carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits; + + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits; + + carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits; + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +static void fe_pow22523(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + int i; + + fe_sq(t0, z); + fe_sq(t1, t0); + for (i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t0, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + for (i = 1; i < 20; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + for (i = 1; i < 100; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t0, t0); + for (i = 1; i < 2; ++i) { + fe_sq(t0, t0); + } + fe_mul(out, t0, z); +} + +void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h) { + fe recip; + fe x; + fe y; + + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + +static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) { + fe recip; + fe x; + fe y; + + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + +static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729, + -8787816, -6275908, -3247719, -18696448, -12055116}; + +static const fe sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472, + -272473, -25146209, -2005654, 326686, 11406482}; + +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) { + fe u; + fe v; + fe v3; + fe vxx; + fe check; + + fe_frombytes(h->Y, s); + fe_1(h->Z); + fe_sq(u, h->Y); + fe_mul(v, u, d); + fe_sub(u, u, h->Z); /* u = y^2-1 */ + fe_add(v, v, h->Z); /* v = dy^2+1 */ + + fe_sq(v3, v); + fe_mul(v3, v3, v); /* v3 = v^3 */ + fe_sq(h->X, v3); + fe_mul(h->X, h->X, v); + fe_mul(h->X, h->X, u); /* x = uv^7 */ + + fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe_mul(h->X, h->X, v3); + fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe_sq(vxx, h->X); + fe_mul(vxx, vxx, v); + fe_sub(check, vxx, u); /* vx^2-u */ + if (fe_isnonzero(check)) { + fe_add(check, vxx, u); /* vx^2+u */ + if (fe_isnonzero(check)) { + return -1; + } + fe_mul(h->X, h->X, sqrtm1); + } + + if (fe_isnegative(h->X) != (s[31] >> 7)) { + fe_neg(h->X, h->X); + } + + fe_mul(h->T, h->X, h->Y); + return 0; +} + +static void ge_p2_0(ge_p2 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); +} + +static void ge_p3_0(ge_p3 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); +} + +static void ge_cached_0(ge_cached *h) { + fe_1(h->YplusX); + fe_1(h->YminusX); + fe_1(h->Z); + fe_0(h->T2d); +} + +static void ge_precomp_0(ge_precomp *h) { + fe_1(h->yplusx); + fe_1(h->yminusx); + fe_0(h->xy2d); +} + +/* r = p */ +static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); +} + +static const fe d2 = {-21827239, -5839606, -30745221, 13898782, 229458, + 15978800, -12551817, -6495438, 29715968, 9444199}; + +/* r = p */ +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(r->YplusX, p->Y, p->X); + fe_sub(r->YminusX, p->Y, p->X); + fe_copy(r->Z, p->Z); + fe_mul(r->T2d, p->T, d2); +} + +/* r = p */ +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); +} + +/* r = p */ +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); + fe_mul(r->T, p->X, p->Y); +} + +/* r = p */ +static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) { + ge_p3 t; + x25519_ge_p1p1_to_p3(&t, p); + x25519_ge_p3_to_cached(r, &t); +} + +/* r = 2 * p */ +static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe t0; + + fe_sq(r->X, p->X); + fe_sq(r->Z, p->Y); + fe_sq2(r->T, p->Z); + fe_add(r->Y, p->X, p->Y); + fe_sq(t0, r->Y); + fe_add(r->Y, r->Z, r->X); + fe_sub(r->Z, r->Z, r->X); + fe_sub(r->X, t0, r->Y); + fe_sub(r->T, r->T, r->Z); +} + +/* r = 2 * p */ +static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + +/* r = p + q */ +static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yplusx); + fe_mul(r->Y, r->Y, q->yminusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + +/* r = p - q */ +static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yminusx); + fe_mul(r->Y, r->Y, q->yplusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + +/* r = p + q */ +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YplusX); + fe_mul(r->Y, r->Y, q->YminusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + +/* r = p - q */ +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YminusX); + fe_mul(r->Y, r->Y, q->YplusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + +static uint8_t equal(signed char b, signed char c) { + uint8_t ub = b; + uint8_t uc = c; + uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */ + uint32_t y = x; /* 0: yes; 1..255: no */ + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + return y; +} + +static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) { + fe_cmov(t->yplusx, u->yplusx, b); + fe_cmov(t->yminusx, u->yminusx, b); + fe_cmov(t->xy2d, u->xy2d, b); +} + +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) { + /* precomp_table is first expanded into matching |ge_precomp| + * elements. */ + ge_precomp multiples[15]; + + unsigned i; + for (i = 0; i < 15; i++) { + const uint8_t *bytes = &precomp_table[i*(2 * 32)]; + fe x, y; + fe_frombytes(x, bytes); + fe_frombytes(y, bytes + 32); + + ge_precomp *out = &multiples[i]; + fe_add(out->yplusx, y, x); + fe_sub(out->yminusx, y, x); + fe_mul(out->xy2d, x, y); + fe_mul(out->xy2d, out->xy2d, d2); + } + + /* See the comment above |k25519SmallPrecomp| about the structure of the + * precomputed elements. This loop does 64 additions and 64 doublings to + * calculate the result. */ + ge_p3_0(h); + + for (i = 63; i < 64; i--) { + unsigned j; + signed char index = 0; + + for (j = 0; j < 4; j++) { + const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7)); + index |= (bit << j); + } + + ge_precomp e; + ge_precomp_0(&e); + + for (j = 1; j < 16; j++) { + cmov(&e, &multiples[j-1], equal(index, j)); + } + + ge_cached cached; + ge_p1p1 r; + x25519_ge_p3_to_cached(&cached, h); + x25519_ge_add(&r, h, &cached); + x25519_ge_p1p1_to_p3(h, &r); + + ge_madd(&r, h, &e); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#if defined(OPENSSL_SMALL) + +/* This block of code replaces the standard base-point table with a much smaller + * one. The standard table is 30,720 bytes while this one is just 960. + * + * This table contains 15 pairs of group elements, (x, y), where each field + * element is serialised with |fe_tobytes|. If |i| is the index of the group + * element then consider i+1 as a four-bit number: (iâ‚€, iâ‚, iâ‚‚, i₃) (where iâ‚€ + * is the most significant bit). The value of the group element is then: + * (i₀×2^192 + iâ‚×2^128 + i₂×2^64 + i₃)G, where G is the generator. */ +static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = { + 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, + 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, + 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, + 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62, + 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, + 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, + 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61, + 0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c, + 0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c, + 0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5, + 0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3, + 0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18, + 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, + 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, + 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b, + 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, + 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, + 0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb, + 0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c, + 0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e, + 0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e, + 0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a, + 0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43, + 0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53, + 0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8, + 0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89, + 0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef, + 0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60, + 0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a, + 0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8, + 0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54, + 0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b, + 0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd, + 0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, + 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, + 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b, + 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, + 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, + 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07, + 0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa, + 0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a, + 0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84, + 0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc, + 0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42, + 0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0, + 0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0, + 0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a, + 0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5, + 0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c, + 0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27, + 0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31, + 0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c, + 0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87, + 0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0, + 0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23, + 0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2, + 0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87, + 0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d, + 0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b, + 0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d, + 0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6, + 0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84, + 0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04, + 0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19, + 0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b, + 0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a, + 0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea, + 0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30, + 0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7, + 0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa, + 0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5, + 0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71, + 0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab, + 0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb, + 0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c, + 0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25, +}; + +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp); +} + +#else + +/* k25519Precomp[i][j] = (j+1)*256^i*B */ +static const ge_precomp k25519Precomp[32][8] = { + { + { + {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, + 27544626, -11754271, -6079156, 2047605}, + {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, + 5043384, 19500929, -15469378}, + {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, + 29287919, 11864899, -24514362, -4438546}, + }, + { + {-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, + -11717903, -3814571, -358445, -10211303}, + {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, + -15616551, 11189268, -26829678, -5319081}, + {26966642, 11152617, 32442495, 15396054, 14353839, -12752335, + -3128826, -9541118, -15472047, -4166697}, + }, + { + {15636291, -9688557, 24204773, -7912398, 616977, -16685262, + 27787600, -14772189, 28944400, -1550024}, + {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, + 16354577, -11775962, 7689662, 11199574}, + {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, + 7512774, 10017326, -17749093, -9920357}, + }, + { + {-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, + -28926210, 15006023, 3284568, -6276540}, + {23599295, -8306047, -11193664, -7687416, 13236774, 10506355, + 7464579, 9656445, 13059162, 10374397}, + {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, + -3839045, -641708, -101325}, + }, + { + {10861363, 11473154, 27284546, 1981175, -30064349, 12577861, + 32867885, 14515107, -15438304, 10819380}, + {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, + 12483688, -12668491, 5581306}, + {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, + 28542350, 13850243, -23678021, -15815942}, + }, + { + {-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, + -19188627, -15224819, -9818940, -12085777}, + {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, + -15689887, 1762328, 14866737}, + {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, + -28236412, 3959421, 27914454, 4383652}, + }, + { + {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, + 5230134, -23952439, -15175766}, + {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, + 20654025, 16520125, 30598449, 7715701}, + {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, + -31400660, 1370708, 29794553, -1409300}, + }, + { + {14499471, -2729599, -33191113, -4254652, 28494862, 14271267, + 30290735, 10876454, -33154098, 2381726}, + {-7195431, -2655363, -14730155, 462251, -27724326, 3941372, + -6236617, 3696005, -32300832, 15351955}, + {27431194, 8222322, 16448760, -3907995, -18707002, 11938355, + -32961401, -2970515, 29551813, 10109425}, + }, + }, + { + { + {-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, + -2378284, -1627556, 10092783, -4764171}, + {27939166, 14210322, 4677035, 16277044, -22964462, -12398139, + -32508754, 12005538, -17810127, 12803510}, + {17228999, -15661624, -1233527, 300140, -1224870, -11714777, + 30364213, -9038194, 18016357, 4397660}, + }, + { + {-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, + -26619106, 14544525, -17477504, 982639}, + {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, + -4120128, -21047696, 9934963}, + {5793303, 16271923, -24131614, -10116404, 29188560, 1206517, + -14747930, 4559895, -30123922, -10897950}, + }, + { + {-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, + 24191034, 4541697, -13338309, 5500568}, + {12650548, -1497113, 9052871, 11355358, -17680037, -8400164, + -17430592, 12264343, 10874051, 13524335}, + {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, + 5080568, -22528059, 5376628}, + }, + { + {-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, + -22321305, -9447443, 4535768, 1569007}, + {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, + -30494562, 3044290, 31848280, 12543772}, + {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, + -27377195, -2062731, 7718482, 14474653}, + }, + { + {2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, + -7236665, 24316168, -5253567}, + {13741529, 10911568, -33233417, -8603737, -20177830, -1033297, + 33040651, -13424532, -20729456, 8321686}, + {21060490, -2212744, 15712757, -4336099, 1639040, 10656336, + 23845965, -11874838, -9984458, 608372}, + }, + { + {-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, + 1123968, -6780577, 27229399, 23887}, + {-23244140, -294205, -11744728, 14712571, -29465699, -2029617, + 12797024, -6440308, -1633405, 16678954}, + {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, + -1508144, -4795045, -17169265, 4904953}, + }, + { + {24059557, 14617003, 19037157, -15039908, 19766093, -14906429, + 5169211, 16191880, 2128236, -4326833}, + {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, + -29806336, 916033, -6882542, -2986532}, + {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, + 285431, 2763829, 15736322, 4143876}, + }, + { + {2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, + -14594663, 23527084, -16458268}, + {33431127, -11130478, -17838966, -15626900, 8909499, 8376530, + -32625340, 4087881, -15188911, -14416214}, + {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, + 4357868, -4774191, -16323038}, + }, + }, + { + { + {6721966, 13833823, -23523388, -1551314, 26354293, -11863321, + 23365147, -3949732, 7390890, 2759800}, + {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, + -4264057, 1244380, -12919645}, + {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, + 9208236, 15886429, 16489664}, + }, + { + {1996075, 10375649, 14346367, 13311202, -6874135, -16438411, + -13693198, 398369, -30606455, -712933}, + {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, + 13348553, 12076947, -30836462, 5113182}, + {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, + -30341101, -7336386, 13847711, 5387222}, + }, + { + {-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, + 8763061, 3617786, -19600662, 10370991}, + {20246567, -14369378, 22358229, -543712, 18507283, -10413996, + 14554437, -8746092, 32232924, 16763880}, + {9648505, 10094563, 26416693, 14745928, -30374318, -6472621, + 11094161, 15689506, 3140038, -16510092}, + }, + { + {-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, + -27224800, 9448613, -28774454, 366295}, + {19153450, 11523972, -11096490, -6503142, -24647631, 5420647, + 28344573, 8041113, 719605, 11671788}, + {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, + -15266516, 27000813, -10195553}, + }, + { + {-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, + 5336097, 6750977, -14521026}, + {11836410, -3979488, 26297894, 16080799, 23455045, 15735944, + 1695823, -8819122, 8169720, 16220347}, + {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, + -11144307, -2627664, -5990708, -14166033}, + }, + { + {-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, + 27884329, 2847284, 2655861, 1738395}, + {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, + 21651608, -3239336, -19087449, -11005278}, + {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, + 5821408, 10478196, 8544890}, + }, + { + {32173121, -16129311, 24896207, 3921497, 22579056, -3410854, + 19270449, 12217473, 17789017, -3395995}, + {-30552961, -2228401, -15578829, -10147201, 13243889, 517024, + 15479401, -3853233, 30460520, 1052596}, + {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, + 27491595, -4612359, 3179268, -9478891}, + }, + { + {31947069, -14366651, -4640583, -15339921, -15125977, -6039709, + -14756777, -16411740, 19072640, -9511060}, + {11685058, 11822410, 3158003, -13952594, 33402194, -4165066, + 5977896, -5215017, 473099, 5040608}, + {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, + 28326862, 1721092, -19558642, -3131606}, + }, + }, + { + { + {7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, + 8076149, -27868496, 11538389}, + {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, + 8754525, 7446702, -5676054, 5797016}, + {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, + 2014099, -9050574, -2369172, -5877341}, + }, + { + {-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, + 1192730, -3714199, 15123619, 10811505}, + {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, + 15776356, -28886779, -11974553}, + {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, + -20654173, -16484855, 4714547, -9600655}, + }, + { + {15200332, 8368572, 19679101, 15970074, -31872674, 1959451, + 24611599, -4543832, -11745876, 12340220}, + {12876937, -10480056, 33134381, 6590940, -6307776, 14872440, + 9613953, 8241152, 15370987, 9608631}, + {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, + 15866074, -28210621, -8814099}, + }, + { + {26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, + 858697, 20571223, 8420556}, + {14620715, 13067227, -15447274, 8264467, 14106269, 15080814, + 33531827, 12516406, -21574435, -12476749}, + {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, + 7256740, 8791136, 15069930}, + }, + { + {1276410, -9371918, 22949635, -16322807, -23493039, -5702186, + 14711875, 4874229, -30663140, -2331391}, + {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, + -7912378, -33069337, 9234253}, + {20590503, -9018988, 31529744, -7352666, -2706834, 10650548, + 31559055, -11609587, 18979186, 13396066}, + }, + { + {24474287, 4968103, 22267082, 4407354, 24063882, -8325180, + -18816887, 13594782, 33514650, 7021958}, + {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, + -25948728, -3916677, -21480480, 12868082}, + {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, + -21446107, 2244500, -12455797, -8089383}, + }, + { + {-30595528, 13793479, -5852820, 319136, -25723172, -6263899, + 33086546, 8957937, -15233648, 5540521}, + {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, + -23710744, -1568984, -16128528, -14962807}, + {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, + 892185, -11513277, -15205948}, + }, + { + {9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, + 4763127, -19179614, 5867134}, + {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, + 27846559, 5931263, -29749703, -16108455}, + {27461885, -2977536, 22380810, 1815854, -23033753, -3031938, + 7283490, -15148073, -19526700, 7734629}, + }, + }, + { + { + {-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, + 7585295, -3176626, 18549497, 15302069}, + {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, + 10458790, -6418461, -8872242, 8424746}, + {24687205, 8613276, -30667046, -3233545, 1863892, -1830544, + 19206234, 7134917, -11284482, -828919}, + }, + { + {11334899, -9218022, 8025293, 12707519, 17523892, -10476071, + 10243738, -14685461, -5066034, 16498837}, + {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, + -14124238, 6536641, 10543906}, + {-28946384, 15479763, -17466835, 568876, -1497683, 11223454, + -2669190, -16625574, -27235709, 8876771}, + }, + { + {-25742899, -12566864, -15649966, -846607, -33026686, -796288, + -33481822, 15824474, -604426, -9039817}, + {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, + -4890037, 1657394, 3084098}, + {10477963, -7470260, 12119566, -13250805, 29016247, -5365589, + 31280319, 14396151, -30233575, 15272409}, + }, + { + {-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, + -25173957, -12636138, -25014757, 1950504}, + {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, + -8384306, -8767532, 15341279, 8373727}, + {28685821, 7759505, -14378516, -12002860, -31971820, 4079242, + 298136, -10232602, -2878207, 15190420}, + }, + { + {-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, + 8669718, 2742393, -26033313, -6875003}, + {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, + 9291594, -16247779, -12154742, 6048605}, + {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, + 13934231, 5128323, 11213262, 9168384}, + }, + { + {-26280513, 11007847, 19408960, -940758, -18592965, -4328580, + -5088060, -11105150, 20470157, -16398701}, + {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, + -22783952, 14461608, 14042978, 5230683}, + {29969567, -2741594, -16711867, -8552442, 9175486, -2468974, + 21556951, 3506042, -5933891, -12449708}, + }, + { + {-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, + -21284170, 8971513, -28539189, 15326563}, + {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, + -15523050, 15300988, -20514118, 9168260}, + {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, + -28948358, 9601605, 33087103, -9011387}, + }, + { + {-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, + -27444329, -15000531, -5996870, 15664672}, + {23294591, -16632613, -22650781, -8470978, 27844204, 11461195, + 13099750, -2460356, 18151676, 13417686}, + {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, + 1661597, -12551441, 15271676, -15452665}, + }, + }, + { + { + {11433042, -13228665, 8239631, -5279517, -1985436, -725718, + -18698764, 2167544, -6921301, -13440182}, + {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, + -9917708, -8638997, 12215110, 12028277}, + {14098400, 6555944, 23007258, 5757252, -15427832, -12950502, + 30123440, 4617780, -16900089, -655628}, + }, + { + {-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, + -15819999, 10154009, 23973261, -12684474}, + {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, + 18341390, -11419951, 32013174, -10103539}, + {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, + 21911214, 6354752, 4425632, -837822}, + }, + { + {-10433389, -14612966, 22229858, -3091047, -13191166, 776729, + -17415375, -12020462, 4725005, 14044970}, + {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, + -1411784, -19522291, -16109756}, + {-24864089, 12986008, -10898878, -5558584, -11312371, -148526, + 19541418, 8180106, 9282262, 10282508}, + }, + { + {-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, + 15522535, 8372215, 5542595, -10702683}, + {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, + -2781891, 6993761, -18093885, 10114655}, + {-20107055, -929418, 31422704, 10427861, -7110749, 6150669, + -29091755, -11529146, 25953725, -106158}, + }, + { + {-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, + 19390020, 6094296, -3315279, 12831125}, + {-15998678, 7578152, 5310217, 14408357, -33548620, -224739, + 31575954, 6326196, 7381791, -2421839}, + {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, + 6295303, 8082724, -15362489, 12339664}, + }, + { + {27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, + 15768922, 25091167, 14856294}, + {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, + -12695493, -22182473, -9012899}, + {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, + -27260765, 13866390, 30146206, 9142070}, + }, + { + {3924129, -15307516, -13817122, -10054960, 12291820, -668366, + -27702774, 9326384, -8237858, 4171294}, + {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, + 26396185, 3731949, 345228, -5462949}, + {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, + 2031539, -12391231, -16253183, -13582083}, + }, + { + {31016211, -16722429, 26371392, -14451233, -5027349, 14854137, + 17477601, 3842657, 28012650, -16405420}, + {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, + -9189873, 16292057, -8867157, 3507940}, + {29439664, 3537914, 23333589, 6997794, -17555561, -11018068, + -15209202, -15051267, -9164929, 6580396}, + }, + }, + { + { + {-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, + 17860444, -9273846, -2095802, 9304567}, + {20714564, -4336911, 29088195, 7406487, 11426967, -5095705, + 14792667, -14608617, 5289421, -477127}, + {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, + 17271490, 12349094, 26939669, -3752294}, + }, + { + {-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, + -27283495, -12348559, -3698806, 117887}, + {22263325, -6560050, 3984570, -11174646, -15114008, -566785, + 28311253, 5358056, -23319780, 541964}, + {16259219, 3261970, 2309254, -15534474, -16885711, -4581916, + 24134070, -16705829, -13337066, -13552195}, + }, + { + {9378160, -13140186, -22845982, -12745264, 28198281, -7244098, + -2399684, -717351, 690426, 14876244}, + {24977353, -314384, -8223969, -13465086, 28432343, -1176353, + -13068804, -12297348, -22380984, 6618999}, + {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, + 8044829, -13817328, 32239829, -5652762}, + }, + { + {-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, + -10350059, 32779359, 5095274}, + {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, + -24601656, 14506724, 21639561, -2630236}, + {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, + -1289502, -6863535, 17874574, 558605}, + }, + { + {-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, + 33499487, 5080151, 2085892, 5119761}, + {-22205145, -2519528, -16381601, 414691, -25019550, 2170430, + 30634760, -8363614, -31999993, -5759884}, + {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, + 27534430, -7192145, -22351378, 12961482}, + }, + { + {-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, + 16533930, 8206996, -30194652, -5159638}, + {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, + 7031275, 7589640, 8945490}, + {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, + 7251489, -11182180, 24099109, -14456170}, + }, + { + {5019558, -7907470, 4244127, -14714356, -26933272, 6453165, + -19118182, -13289025, -6231896, -10280736}, + {10853594, 10721687, 26480089, 5861829, -22995819, 1972175, + -1866647, -10557898, -3363451, -6441124}, + {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, + -2008168, -13866408, 7421392}, + }, + { + {8139927, -6546497, 32257646, -5890546, 30375719, 1886181, + -21175108, 15441252, 28826358, -4123029}, + {6267086, 9695052, 7709135, -16603597, -32869068, -1886135, + 14795160, -7840124, 13746021, -1742048}, + {28584902, 7787108, -6732942, -15050729, 22846041, -7571236, + -3181936, -363524, 4771362, -8419958}, + }, + }, + { + { + {24949256, 6376279, -27466481, -8174608, -18646154, -9930606, + 33543569, -12141695, 3569627, 11342593}, + {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, + 4608608, 7325975, -14801071}, + {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, + -27400540, 10258390, -17646694, -8186692}, + }, + { + {11431204, 15823007, 26570245, 14329124, 18029990, 4796082, + -31446179, 15580664, 9280358, -3973687}, + {-160783, -10326257, -22855316, -4304997, -20861367, -13621002, + -32810901, -11181622, -15545091, 4387441}, + {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, + -24513992, 8548137, 20617071, -7482001}, + }, + { + {-938825, -3930586, -8714311, 16124718, 24603125, -6225393, + -13775352, -11875822, 24345683, 10325460}, + {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, + 16318175, -1010689, 4766743, 3552007}, + {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, + 14481909, 10988822, -3994762}, + }, + { + {15564307, -14311570, 3101243, 5684148, 30446780, -8051356, + 12677127, -6505343, -8295852, 13296005}, + {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, + 31521204, 9614054, -30000824, 12074674}, + {4771191, -135239, 14290749, -13089852, 27992298, 14998318, + -1413936, -1556716, 29832613, -16391035}, + }, + { + {7064884, -7541174, -19161962, -5067537, -18891269, -2912736, + 25825242, 5293297, -27122660, 13101590}, + {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, + 32512469, -5317593, -30356070, -4190957}, + {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, + 14413974, 9515896, 19568978, 9628812}, + }, + { + {33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, + -6106839, -6291786, 3437740}, + {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, + -22961733, 70104, 7463304, 4176122}, + {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, + -32719404, -5322751, 24216882, 5944158}, + }, + { + {8894125, 7450974, -2664149, -9765752, -28080517, -12389115, + 19345746, 14680796, 11632993, 5847885}, + {26942781, -2315317, 9129564, -4906607, 26024105, 11769399, + -11518837, 6367194, -9727230, 4782140}, + {19916461, -4828410, -22910704, -11414391, 25606324, -5972441, + 33253853, 8220911, 6358847, -1873857}, + }, + { + {801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, + -4480480, -13538503, 1387155}, + {19646058, 5720633, -11416706, 12814209, 11607948, 12749789, + 14147075, 15156355, -21866831, 11835260}, + {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, + 15467869, -26560550, 5052483}, + }, + }, + { + { + {-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, + -12618185, 12228557, -7003677}, + {32944382, 14922211, -22844894, 5188528, 21913450, -8719943, + 4001465, 13238564, -6114803, 8653815}, + {22865569, -4652735, 27603668, -12545395, 14348958, 8234005, + 24808405, 5719875, 28483275, 2841751}, + }, + { + {-16420968, -1113305, -327719, -12107856, 21886282, -15552774, + -1887966, -315658, 19932058, -12739203}, + {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, + 3999228, 13239134, -4777469, -13910208}, + {1382174, -11694719, 17266790, 9194690, -13324356, 9720081, + 20403944, 11284705, -14013818, 3093230}, + }, + { + {16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, + 16271225, -24049421, -6691850}, + {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, + 24123614, 15193618, -21652117, -16739389}, + {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, + 31870908, 14690798, 17361620, 11864968}, + }, + { + {-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, + -12331205, -7486601, -25578460, -16240689}, + {14668462, -12270235, 26039039, 15305210, 25515617, 4542480, + 10453892, 6577524, 9145645, -6443880}, + {5974874, 3053895, -9433049, -10385191, -31865124, 3225009, + -7972642, 3936128, -5652273, -3050304}, + }, + { + {30625386, -4729400, -25555961, -12792866, -20484575, 7695099, + 17097188, -16303496, -27999779, 1803632}, + {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, + 14911344, 12196514, -21405489, 7047412}, + {20093277, 9920966, -11138194, -5343857, 13161587, 12044805, + -32856851, 4124601, -32343828, -10257566}, + }, + { + {-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, + 4752377, -8714640, -21679658, 2288038}, + {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, + 29457502, 14625692, -24819617, 12570232}, + {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, + -21159943, -3498680, -11974704, 4724943}, + }, + { + {17960970, -11775534, -4140968, -9702530, -8876562, -1410617, + -12907383, -8659932, -29576300, 1903856}, + {23134274, -14279132, -10681997, -1611936, 20684485, 15770816, + -12989750, 3190296, 26955097, 14109738}, + {15308788, 5320727, -30113809, -14318877, 22902008, 7767164, + 29425325, -11277562, 31960942, 11934971}, + }, + { + {-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, + 20638173, 4875028, 10491392, 1379718}, + {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, + 33518459, 16176658, 21432314, 12180697}, + {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, + 1465425, 12689540, -10301319, -13872883}, + }, + }, + { + { + {5414091, -15386041, -21007664, 9643570, 12834970, 1186149, + -2622916, -1342231, 26128231, 6032912}, + {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, + 3604025, 8316894, -25875034, -10437358}, + {3296484, 6223048, 24680646, -12246460, -23052020, 5903205, + -8862297, -4639164, 12376617, 3188849}, + }, + { + {29190488, -14659046, 27549113, -1183516, 3520066, -10697301, + 32049515, -7309113, -16109234, -9852307}, + {-14744486, -9309156, 735818, -598978, -20407687, -5057904, + 25246078, -15795669, 18640741, -960977}, + {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, + -31638386, -494430, 10530747, 1053335}, + }, + { + {-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, + -31462369, -2948985, 24018831, 15026644}, + {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, + 25310643, 13003497, -2314791, -15145616}, + {-27419985, -603321, -8043984, -1669117, -26092265, 13987819, + -27297622, 187899, -23166419, -2531735}, + }, + { + {-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, + 9716667, 16266922, -5070217, 726099}, + {29370922, -6053998, 7334071, -15342259, 9385287, 2247707, + -13661962, -4839461, 30007388, -15823341}, + {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, + 730663, 9835848, 4555336}, + }, + { + {-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, + 17693930, 544696, -11985298, 12422646}, + {31117226, -12215734, -13502838, 6561947, -9876867, -12757670, + -5118685, -4096706, 29120153, 13924425}, + {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, + -9383939, -11317700, 7240931, -237388}, + }, + { + {-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, + 1222336, 4389483, 3293637, -15551743}, + {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, + -24319580, 7733547, 12796905, -6335822}, + {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, + -28253339, 3647836, 3222231, -11160462}, + }, + { + {18606113, 1693100, -25448386, -15170272, 4112353, 10045021, + 23603893, -2048234, -7550776, 2484985}, + {9255317, -3131197, -12156162, -1004256, 13098013, -9214866, + 16377220, -2102812, -19802075, -3034702}, + {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, + -31718148, 9936966, -30097688, -10618797}, + }, + { + {21878590, -5001297, 4338336, 13643897, -3036865, 13160960, + 19708896, 5415497, -7360503, -4109293}, + {27736861, 10103576, 12500508, 8502413, -3413016, -9633558, + 10436918, -1550276, -23659143, -8132100}, + {19492550, -12104365, -29681976, -852630, -3208171, 12403437, + 30066266, 8367329, 13243957, 8709688}, + }, + }, + { + { + {12015105, 2801261, 28198131, 10151021, 24818120, -4743133, + -11194191, -5645734, 5150968, 7274186}, + {2831366, -12492146, 1478975, 6122054, 23825128, -12733586, + 31097299, 6083058, 31021603, -9793610}, + {-2529932, -2229646, 445613, 10720828, -13849527, -11505937, + -23507731, 16354465, 15067285, -14147707}, + }, + { + {7840942, 14037873, -33364863, 15934016, -728213, -3642706, + 21403988, 1057586, -19379462, -12403220}, + {915865, -16469274, 15608285, -8789130, -24357026, 6060030, + -17371319, 8410997, -7220461, 16527025}, + {32922597, -556987, 20336074, -16184568, 10903705, -5384487, + 16957574, 52992, 23834301, 6588044}, + }, + { + {32752030, 11232950, 3381995, -8714866, 22652988, -10744103, + 17159699, 16689107, -20314580, -1305992}, + {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, + 7924251, -2752281, 1976123, -7249027}, + {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, + -3371252, 12331345, -8237197}, + }, + { + {8651614, -4477032, -16085636, -4996994, 13002507, 2950805, + 29054427, -5106970, 10008136, -4667901}, + {31486080, 15114593, -14261250, 12951354, 14369431, -7387845, + 16347321, -13662089, 8684155, -10532952}, + {19443825, 11385320, 24468943, -9659068, -23919258, 2187569, + -26263207, -6086921, 31316348, 14219878}, + }, + { + {-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, + 27146014, 6992409, 29126555, 9207390}, + {32382935, 1110093, 18477781, 11028262, -27411763, -7548111, + -4980517, 10843782, -7957600, -14435730}, + {2814918, 7836403, 27519878, -7868156, -20894015, -11553689, + -21494559, 8550130, 28346258, 1994730}, + }, + { + {-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, + -19516951, 7174894, 22628102, 8115180}, + {-30405132, 955511, -11133838, -15078069, -32447087, -13278079, + -25651578, 3317160, -9943017, 930272}, + {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, + 24091212, -1388970, -22765376, -10650715}, + }, + { + {-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, + -14839018, -16554220, -1867018, 8398970}, + {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, + 22981545, -6291273, 18009408, -15772772}, + {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, + 29551787, -3727419, 19288549, 1325865}, + }, + { + {15100157, -15835752, -23923978, -1005098, -26450192, 15509408, + 12376730, -3479146, 33166107, -8042750}, + {20909231, 13023121, -9209752, 16251778, -5778415, -8094914, + 12412151, 10018715, 2213263, -13878373}, + {32529814, -11074689, 30361439, -16689753, -9135940, 1513226, + 22922121, 6382134, -5766928, 8371348}, + }, + }, + { + { + {9923462, 11271500, 12616794, 3544722, -29998368, -1721626, + 12891687, -8193132, -26442943, 10486144}, + {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, + 2610596, -23921530, -11455195}, + {5408411, -1136691, -4969122, 10561668, 24145918, 14240566, + 31319731, -4235541, 19985175, -3436086}, + }, + { + {-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, + -17577068, 8849297, 65030, 8370684}, + {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, + -19442942, 6922164, 12743482, -9800518}, + {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, + 23783145, 11038569, 18800704, 255233}, + }, + { + {-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, + 9066957, 19258688, -14753793}, + {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, + -31934921, 2209390, -1524053, 2055794}, + {580882, 16705327, 5468415, -2683018, -30926419, -14696000, + -7203346, -8994389, -30021019, 7394435}, + }, + { + {23838809, 1822728, -15738443, 15242727, 8318092, -3733104, + -21672180, -3492205, -4821741, 14799921}, + {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, + 13496856, -9056018, 7402518}, + {2286874, -4435931, -20042458, -2008336, -13696227, 5038122, + 11006906, -15760352, 8205061, 1607563}, + }, + { + {14414086, -8002132, 3331830, -3208217, 22249151, -5594188, + 18364661, -2906958, 30019587, -9029278}, + {-27688051, 1585953, -10775053, 931069, -29120221, -11002319, + -14410829, 12029093, 9944378, 8024}, + {4368715, -3709630, 29874200, -15022983, -20230386, -11410704, + -16114594, -999085, -8142388, 5640030}, + }, + { + {10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, + -16694564, 15219798, -14327783}, + {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, + -1173195, -18342183, 9742717}, + {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, + 7406442, 12420155, 1994844}, + }, + { + {14012521, -5024720, -18384453, -9578469, -26485342, -3936439, + -13033478, -10909803, 24319929, -6446333}, + {16412690, -4507367, 10772641, 15929391, -17068788, -4658621, + 10555945, -10484049, -30102368, -4739048}, + {22397382, -7767684, -9293161, -12792868, 17166287, -9755136, + -27333065, 6199366, 21880021, -12250760}, + }, + { + {-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, + 16557151, 8890729, 8840445, 4957760}, + {-15447727, 709327, -6919446, -10870178, -29777922, 6522332, + -21720181, 12130072, -14796503, 5005757}, + {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, + 10183197, -13239326, -16395286, -2176112}, + }, + }, + { + { + {-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, + -32013908, -3057104, 22208662, 2000468}, + {3065073, -1412761, -25598674, -361432, -17683065, -5703415, + -8164212, 11248527, -3691214, -7414184}, + {10379208, -6045554, 8877319, 1473647, -29291284, -12507580, + 16690915, 2553332, -3132688, 16400289}, + }, + { + {15716668, 1254266, -18472690, 7446274, -8448918, 6344164, + -22097271, -7285580, 26894937, 9132066}, + {24158887, 12938817, 11085297, -8177598, -28063478, -4457083, + -30576463, 64452, -6817084, -2692882}, + {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, + -3418511, -4688006, 2364226}, + }, + { + {16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, + -11697457, 15445875, -7798101}, + {29004207, -7867081, 28661402, -640412, -12794003, -7943086, + 31863255, -4135540, -278050, -15759279}, + {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, + 10343412, -6976290, -29828287, -10815811}, + }, + { + {27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, + 15372179, 17293797, 960709}, + {20263915, 11434237, -5765435, 11236810, 13505955, -10857102, + -16111345, 6493122, -19384511, 7639714}, + {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, + 18006287, -16043750, 29994677, -15808121}, + }, + { + {9769828, 5202651, -24157398, -13631392, -28051003, -11561624, + -24613141, -13860782, -31184575, 709464}, + {12286395, 13076066, -21775189, -1176622, -25003198, 4057652, + -32018128, -8890874, 16102007, 13205847}, + {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, + 8525972, 10151379, 10394400}, + }, + { + {4024660, -16137551, 22436262, 12276534, -9099015, -2686099, + 19698229, 11743039, -33302334, 8934414}, + {-15879800, -4525240, -8580747, -2934061, 14634845, -698278, + -9449077, 3137094, -11536886, 11721158}, + {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, + 8835153, -9205489, -1280045}, + }, + { + {-461409, -7830014, 20614118, 16688288, -7514766, -4807119, + 22300304, 505429, 6108462, -6183415}, + {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, + 29880583, -13483331, -26898490, -7867459}, + {-31975283, 5726539, 26934134, 10237677, -3173717, -605053, + 24199304, 3795095, 7592688, -14992079}, + }, + { + {21594432, -14964228, 17466408, -4077222, 32537084, 2739898, + 6407723, 12018833, -28256052, 4298412}, + {-20650503, -11961496, -27236275, 570498, 3767144, -1717540, + 13891942, -1569194, 13717174, 10805743}, + {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, + -796431, 14860609, -26938930, -5863836}, + }, + }, + { + { + {12962541, 5311799, -10060768, 11658280, 18855286, -7954201, + 13286263, -12808704, -4381056, 9882022}, + {18512079, 11319350, -20123124, 15090309, 18818594, 5271736, + -22727904, 3666879, -23967430, -3299429}, + {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, + -10084880, -6661110, -2403099, 5276065}, + }, + { + {30169808, -5317648, 26306206, -11750859, 27814964, 7069267, + 7152851, 3684982, 1449224, 13082861}, + {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, + 15056736, -21016438, -8202000}, + {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, + -26171976, 6482814, -10300080, -11060101}, + }, + { + {32869458, -5408545, 25609743, 15678670, -10687769, -15471071, + 26112421, 2521008, -22664288, 6904815}, + {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, + 3841096, -29003639, -6657642}, + {10340844, -6630377, -18656632, -2278430, 12621151, -13339055, + 30878497, -11824370, -25584551, 5181966}, + }, + { + {25940115, -12658025, 17324188, -10307374, -8671468, 15029094, + 24396252, -16450922, -2322852, -12388574}, + {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, + 12641087, 20603771, -6561742}, + {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, + 1925523, 11914390, 4662781, 7820689}, + }, + { + {12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, + 12172924, 16136752, 15264020}, + {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, + 10658213, 6671822, 19012087, 3772772}, + {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, + -15762884, 20527771, 12988982}, + }, + { + {-14822485, -5797269, -3707987, 12689773, -898983, -10914866, + -24183046, -10564943, 3299665, -12424953}, + {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, + 6461331, -25583147, 8991218}, + {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, + -32948145, 7417950, -30242287, 1507265}, + }, + { + {29692663, 6829891, -10498800, 4334896, 20945975, -11906496, + -28887608, 8209391, 14606362, -10647073}, + {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, + 9761487, 4170404, -2085325}, + {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, + 22186522, 16002000, -14276837, -8400798}, + }, + { + {-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, + -7113572, -9620092, 13240845, 10965870}, + {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, + 4498947, 14147411, 29514390, 4302863}, + {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, + -5061276, -2144373, 17846988, -13971927}, + }, + }, + { + { + {-2244452, -754728, -4597030, -1066309, -6247172, 1455299, + -21647728, -9214789, -5222701, 12650267}, + {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, + 13770293, -19134326, 10958663}, + {22470984, 12369526, 23446014, -5441109, -21520802, -9698723, + -11772496, -11574455, -25083830, 4271862}, + }, + { + {-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, + 75375, -4278529, -32526221, 8469673}, + {15854970, 4148314, -8893890, 7259002, 11666551, 13824734, + -30531198, 2697372, 24154791, -9460943}, + {15446137, -15806644, 29759747, 14019369, 30811221, -9610191, + -31582008, 12840104, 24913809, 9815020}, + }, + { + {-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, + -9103676, 13438769, 18735128, 9466238}, + {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, + -10896103, -22728655, 16199064}, + {14576810, 379472, -26786533, -8317236, -29426508, -10812974, + -102766, 1876699, 30801119, 2164795}, + }, + { + {15995086, 3199873, 13672555, 13712240, -19378835, -4647646, + -13081610, -15496269, -13492807, 1268052}, + {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, + -3470338, -12600221, -17055369, 3565904}, + {29210088, -9419337, -5919792, -4952785, 10834811, -13327726, + -16512102, -10820713, -27162222, -14030531}, + }, + { + {-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, + -29183421, -3769423, 2244111, -14001979}, + {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, + -25673088, -16180800, 13491506, 4641841}, + {10813417, 643330, -19188515, -728916, 30292062, -16600078, + 27548447, -7721242, 14476989, -12767431}, + }, + { + {10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, + -1644259, -27912810, 12651324}, + {-31185513, -813383, 22271204, 11835308, 10201545, 15351028, + 17099662, 3988035, 21721536, -3148940}, + {10202177, -6545839, -31373232, -9574638, -32150642, -8119683, + -12906320, 3852694, 13216206, 14842320}, + }, + { + {-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, + -31500847, 13765824, -27434397, 9900184}, + {14465505, -13833331, -32133984, -14738873, -27443187, 12990492, + 33046193, 15796406, -7051866, -8040114}, + {30924417, -8279620, 6359016, -12816335, 16508377, 9071735, + -25488601, 15413635, 9524356, -7018878}, + }, + { + {12274201, -13175547, 32627641, -1785326, 6736625, 13267305, + 5237659, -5109483, 15663516, 4035784}, + {-2951309, 8903985, 17349946, 601635, -16432815, -4612556, + -13732739, -15889334, -22258478, 4659091}, + {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, + 5736189, 15026997, -2178256, -13455585}, + }, + }, + { + { + {-8858980, -2219056, 28571666, -10155518, -474467, -10105698, + -3801496, 278095, 23440562, -290208}, + {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, + 11551483, -16571960, -7442864}, + {17932739, -12437276, -24039557, 10749060, 11316803, 7535897, + 22503767, 5561594, -3646624, 3898661}, + }, + { + {7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, + 7152530, 21831162, 1245233}, + {26958459, -14658026, 4314586, 8346991, -5677764, 11960072, + -32589295, -620035, -30402091, -16716212}, + {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, + 6280834, 14587357, -22338025, 13987525}, + }, + { + {-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, + -4300898, -5124639, -7469781, -2858068}, + {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, + 6439245, -14581012, 4091397}, + {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, + -19622683, 12092163, 29077877, -14741988}, + }, + { + {5269168, -6859726, -13230211, -8020715, 25932563, 1763552, + -5606110, -5505881, -20017847, 2357889}, + {32264008, -15407652, -5387735, -1160093, -2091322, -3946900, + 23104804, -12869908, 5727338, 189038}, + {14609123, -8954470, -6000566, -16622781, -14577387, -7743898, + -26745169, 10942115, -25888931, -14884697}, + }, + { + {20513500, 5557931, -15604613, 7829531, 26413943, -2019404, + -21378968, 7471781, 13913677, -5137875}, + {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, + -8940970, 14059180, 12878652, 8511905}, + {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, + -30223418, 6812974, 5568676, -3127656}, + }, + { + {11630004, 12144454, 2116339, 13606037, 27378885, 15676917, + -17408753, -13504373, -14395196, 8070818}, + {27117696, -10007378, -31282771, -5570088, 1127282, 12772488, + -29845906, 10483306, -11552749, -1028714}, + {10637467, -5688064, 5674781, 1072708, -26343588, -6982302, + -1683975, 9177853, -27493162, 15431203}, + }, + { + {20525145, 10892566, -12742472, 12779443, -29493034, 16150075, + -28240519, 14943142, -15056790, -7935931}, + {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, + -3239766, -3356550, 9594024}, + {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, + -6492290, 13352335, -10977084}, + }, + { + {-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, + -29783850, -7752482, -13215537, -319204}, + {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, + 15077870, -22750759, 14523817}, + {27406042, -6041657, 27423596, -4497394, 4996214, 10002360, + -28842031, -4545494, -30172742, -4805667}, + }, + }, + { + { + {11374242, 12660715, 17861383, -12540833, 10935568, 1099227, + -13886076, -9091740, -27727044, 11358504}, + {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, + 32676003, 11149336, -26123651, 4985768}, + {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, + 13794114, -19414307, -15621255}, + }, + { + {6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, + 6970005, -1691065, -9004790}, + {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, + -5475723, -16796596, -5031438}, + {-22273315, -13524424, -64685, -4334223, -18605636, -10921968, + -20571065, -7007978, -99853, -10237333}, + }, + { + {17747465, 10039260, 19368299, -4050591, -20630635, -16041286, + 31992683, -15857976, -29260363, -5511971}, + {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, + -3744247, 4882242, -10626905}, + {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, + 3272828, -5190932, -4162409}, + }, + { + {12501286, 4044383, -8612957, -13392385, -32430052, 5136599, + -19230378, -3529697, 330070, -3659409}, + {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, + -8573892, -271295, 12071499}, + {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, + -32769618, 1936675, -5159697, 3829363}, + }, + { + {28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, + -6567787, 26333140, 14267664}, + {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, + 10004786, -8709488, -21761224, 8930324}, + {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, + 1541940, 4757911, -26491501, -16408940}, + }, + { + {13537262, -7759490, -20604840, 10961927, -5922820, -13218065, + -13156584, 6217254, -15943699, 13814990}, + {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, + 9257833, -1956526, -1776914}, + {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, + -29171540, 12361135, -18685978, 4578290}, + }, + { + {24579768, 3711570, 1342322, -11180126, -27005135, 14124956, + -22544529, 14074919, 21964432, 8235257}, + {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, + -2981514, -1669206, 13006806, 2355433}, + {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, + 27202044, 1719366, 1141648, -12796236}, + }, + { + {-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, + 13475066, -3133972, 32674895, 13715045}, + {11423335, -5468059, 32344216, 8962751, 24989809, 9241752, + -13265253, 16086212, -28740881, -15642093}, + {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, + -11709148, 7791794, -27245943, 4383347}, + }, + }, + { + { + {-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, + -4862407, -4906449, 27193557, 6245191}, + {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, + 3260492, 22510453, 8577507}, + {-12632451, 11257346, -32692994, 13548177, -721004, 10879011, + 31168030, 13952092, -29571492, -3635906}, + }, + { + {3877321, -9572739, 32416692, 5405324, -11004407, -13656635, + 3759769, 11935320, 5611860, 8164018}, + {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, + 32003002, -8832289, 5773085, -8422109}, + {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, + 12376320, 31632953, 190926}, + }, + { + {-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, + -8288749, 4508564, -25341555, -3627528}, + {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, + -14786005, -1672488, 827625}, + {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, + -1800575, -14108036, -24878478, 1541286}, + }, + { + {2901347, -1117687, 3880376, -10059388, -17620940, -3612781, + -21802117, -3567481, 20456845, -1885033}, + {27019610, 12299467, -13658288, -1603234, -12861660, -4861471, + -19540150, -5016058, 29439641, 15138866}, + {21536104, -6626420, -32447818, -10690208, -22408077, 5175814, + -5420040, -16361163, 7779328, 109896}, + }, + { + {30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, + 12180118, 23177719, -554075}, + {26572847, 3405927, -31701700, 12890905, -19265668, 5335866, + -6493768, 2378492, 4439158, -13279347}, + {-22716706, 3489070, -9225266, -332753, 18875722, -1140095, + 14819434, -12731527, -17717757, -5461437}, + }, + { + {-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, + -820954, 2177225, 8550082, -15114165}, + {-18473302, 16596775, -381660, 15663611, 22860960, 15585581, + -27844109, -3582739, -23260460, -8428588}, + {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, + -22725137, 15860482, -21902570, 1494193}, + }, + { + {-19562091, -14087393, -25583872, -9299552, 13127842, 759709, + 21923482, 16529112, 8742704, 12967017}, + {-28464899, 1553205, 32536856, -10473729, -24691605, -406174, + -8914625, -2933896, -29903758, 15553883}, + {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, + 14513274, 19375923, -12647961}, + }, + { + {8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, + -6222716, 2862653, 9455043}, + {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, + -2990080, 15511449, 4789663}, + {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, + -5754762, 108893, 23513200, 16652362}, + }, + }, + { + { + {-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, + -6650416, -12936300, -18319198, 10212860}, + {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, + 2600940, -9988298, -12506466}, + {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, + 11344424, 864440, -2499677, -16710063}, + }, + { + {-26432803, 6148329, -17184412, -14474154, 18782929, -275997, + -22561534, 211300, 2719757, 4940997}, + {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, + 21690126, 8518463, 26699843, 5276295}, + {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, + 149635, -15452774, 7159369}, + }, + { + {9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, + 8312176, 22477218, -8403385}, + {18155857, -16504990, 19744716, 9006923, 15154154, -10538976, + 24256460, -4864995, -22548173, 9334109}, + {2986088, -4911893, 10776628, -3473844, 10620590, -7083203, + -21413845, 14253545, -22587149, 536906}, + }, + { + {4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, + 10589625, 10838060, -15420424}, + {-19342404, 867880, 9277171, -3218459, -14431572, -1986443, + 19295826, -15796950, 6378260, 699185}, + {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, + 15693155, -5045064, -13373962}, + }, + { + {-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, + 31730678, -10962840, -3918636, -9669325}, + {10188286, -15770834, -7336361, 13427543, 22223443, 14896287, + 30743455, 7116568, -21786507, 5427593}, + {696102, 13206899, 27047647, -10632082, 15285305, -9853179, + 10798490, -4578720, 19236243, 12477404}, + }, + { + {-11229439, 11243796, -17054270, -8040865, -788228, -8167967, + -3897669, 11180504, -23169516, 7733644}, + {17800790, -14036179, -27000429, -11766671, 23887827, 3149671, + 23466177, -10538171, 10322027, 15313801}, + {26246234, 11968874, 32263343, -5468728, 6830755, -13323031, + -15794704, -101982, -24449242, 10890804}, + }, + { + {-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, + -14982212, 16484931, 25180797, -5334884}, + {-586574, 10376444, -32586414, -11286356, 19801893, 10997610, + 2276632, 9482883, 316878, 13820577}, + {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, + 30756178, -7515054, 30696930, -3712849}, + }, + { + {32988917, -9603412, 12499366, 7910787, -10617257, -11931514, + -7342816, -9985397, -32349517, 7392473}, + {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, + -30409476, -9134995, 25112947, -2926644}, + {-2504044, -436966, 25621774, -5678772, 15085042, -5479877, + -24884878, -13526194, 5537438, -13914319}, + }, + }, + { + { + {-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, + -14876251, -1729667, 31234590, 6090599}, + {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, + 15878753, -6970405, -9034768}, + {-27757857, 247744, -15194774, -9002551, 23288161, -10011936, + -23869595, 6503646, 20650474, 1804084}, + }, + { + {-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, + -10329713, 27842616, -202328}, + {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, + 5031932, -11375082, 12714369}, + {20807691, -7270825, 29286141, 11421711, -27876523, -13868230, + -21227475, 1035546, -19733229, 12796920}, + }, + { + {12076899, -14301286, -8785001, -11848922, -25012791, 16400684, + -17591495, -12899438, 3480665, -15182815}, + {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, + -24363064, -15921875, -33374054, 2771025}, + {-21389266, 421932, 26597266, 6860826, 22486084, -6737172, + -17137485, -4210226, -24552282, 15673397}, + }, + { + {-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, + -20271184, 4733254, 3727144, -12934448}, + {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, + 7975683, 31123697, -10958981}, + {30069250, -11435332, 30434654, 2958439, 18399564, -976289, + 12296869, 9204260, -16432438, 9648165}, + }, + { + {32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, + 5248604, -26008332, -11377501}, + {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, + 15298639, 2662509, -16297073}, + {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, + 32087529, -1222777, 32247248, -14389861}, + }, + { + {14312628, 1221556, 17395390, -8700143, -4945741, -8684635, + -28197744, -9637817, -16027623, -13378845}, + {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, + 9803137, 17597934, 2346211}, + {18510800, 15337574, 26171504, 981392, -22241552, 7827556, + -23491134, -11323352, 3059833, -11782870}, + }, + { + {10141598, 6082907, 17829293, -1947643, 9830092, 13613136, + -25556636, -5544586, -33502212, 3592096}, + {33114168, -15889352, -26525686, -13343397, 33076705, 8716171, + 1151462, 1521897, -982665, -6837803}, + {-32939165, -4255815, 23947181, -324178, -33072974, -12305637, + -16637686, 3891704, 26353178, 693168}, + }, + { + {30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, + -400668, 31375464, 14369965}, + {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, + 32732230, -13108839, 17901441, 16011505}, + {18171223, -11934626, -12500402, 15197122, -11038147, -15230035, + -19172240, -16046376, 8764035, 12309598}, + }, + }, + { + { + {5975908, -5243188, -19459362, -9681747, -11541277, 14015782, + -23665757, 1228319, 17544096, -10593782}, + {5811932, -1715293, 3442887, -2269310, -18367348, -8359541, + -18044043, -15410127, -5565381, 12348900}, + {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, + -24849353, 8141295, -10632534, -585479}, + }, + { + {-12675304, 694026, -5076145, 13300344, 14015258, -14451394, + -9698672, -11329050, 30944593, 1130208}, + {8247766, -6710942, -26562381, -7709309, -14401939, -14648910, + 4652152, 2488540, 23550156, -271232}, + {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, + -5908146, -408818, -137719}, + }, + { + {16091085, -16253926, 18599252, 7340678, 2137637, -1221657, + -3364161, 14550936, 3260525, -7166271}, + {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, + -23028869, -13204905, -12748722, 2701326}, + {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, + -10018363, 9276971, 11329923, 1862132}, + }, + { + {14763076, -15903608, -30918270, 3689867, 3511892, 10313526, + -21951088, 12219231, -9037963, -940300}, + {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, + -2909717, -15438168, 11595570}, + {15214962, 3537601, -26238722, -14058872, 4418657, -15230761, + 13947276, 10730794, -13489462, -4363670}, + }, + { + {-2538306, 7682793, 32759013, 263109, -29984731, -7955452, + -22332124, -10188635, 977108, 699994}, + {-12466472, 4195084, -9211532, 550904, -15565337, 12917920, + 19118110, -439841, -30534533, -14337913}, + {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, + -10051775, 12493932, -5409317}, + }, + { + {-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, + 27218280, 2607121, 29375955, 6024730}, + {842132, -2794693, -4763381, -8722815, 26332018, -12405641, + 11831880, 6985184, -9940361, 2854096}, + {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, + 960770, 12121869, 16648078}, + }, + { + {-15218652, 14667096, -13336229, 2013717, 30598287, -464137, + -31504922, -7882064, 20237806, 2838411}, + {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, + 12544294, -13470457, 1068881, -12499905}, + {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, + -8486907, -2630053, 12521378, 4845654}, + }, + { + {-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, + 3409348, -873400, -6482306, -12885870}, + {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, + 10477734, -1240216, -3113227, 13974498}, + {12966261, 15550616, -32038948, -1615346, 21025980, -629444, + 5642325, 7188737, 18895762, 12629579}, + }, + }, + { + { + {14741879, -14946887, 22177208, -11721237, 1279741, 8058600, + 11758140, 789443, 32195181, 3895677}, + {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, + -3566119, -8982069, 4429647}, + {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, + -7135870, -11642895, 18047436, -15281743}, + }, + { + {-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, + 10993114, -12850837, -17620701, -9408468}, + {21987233, 700364, -24505048, 14972008, -7774265, -5718395, + 32155026, 2581431, -29958985, 8773375}, + {-25568350, 454463, -13211935, 16126715, 25240068, 8594567, + 20656846, 12017935, -7874389, -13920155}, + }, + { + {6028182, 6263078, -31011806, -11301710, -818919, 2461772, + -31841174, -5468042, -1721788, -2776725}, + {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, + -4166698, 28408820, 6816612}, + {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, + 20613181, 13982702, -10339570, 5067943}, + }, + { + {-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, + -19719286, 12746132, 5331210, -10105944}, + {30528811, 3601899, -1957090, 4619785, -27361822, -15436388, + 24180793, -12570394, 27679908, -1648928}, + {9402404, -13957065, 32834043, 10838634, -26580150, -13237195, + 26653274, -8685565, 22611444, -12715406}, + }, + { + {22190590, 1118029, 22736441, 15130463, -30460692, -5991321, + 19189625, -4648942, 4854859, 6622139}, + {-8310738, -2953450, -8262579, -3388049, -10401731, -271929, + 13424426, -3567227, 26404409, 13001963}, + {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, + -26064365, -11621720, -15405155, 11020693}, + }, + { + {1866042, -7949489, -7898649, -10301010, 12483315, 13477547, + 3175636, -12424163, 28761762, 1406734}, + {-448555, -1777666, 13018551, 3194501, -9580420, -11161737, + 24760585, -4347088, 25577411, -13378680}, + {-24290378, 4759345, -690653, -1852816, 2066747, 10693769, + -29595790, 9884936, -9368926, 4745410}, + }, + { + {-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, + -15462008, -11311852, 10931924, -11931931}, + {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, + -22853429, 10856641, -20470770, 13434654}, + {22759489, -10073434, -16766264, -1871422, 13637442, -10168091, + 1765144, -12654326, 28445307, -5364710}, + }, + { + {29875063, 12493613, 2795536, -3786330, 1710620, 15181182, + -10195717, -8788675, 9074234, 1167180}, + {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, + -18716888, -9535498, 3843903, 9367684}, + {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, + 8601684, -139197, 4242895}, + }, + }, + { + { + {22092954, -13191123, -2042793, -11968512, 32186753, -11517388, + -6574341, 2470660, -27417366, 16625501}, + {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, + 2602725, -27351616, 14247413}, + {6314175, -10264892, -32772502, 15957557, -10157730, 168750, + -8618807, 14290061, 27108877, -1180880}, + }, + { + {-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, + 33547976, -11058889, -27148451, 981874}, + {22833440, 9293594, -32649448, -13618667, -9136966, 14756819, + -22928859, -13970780, -10479804, -16197962}, + {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, + 22680049, 13906969, -15933690, 3797899}, + }, + { + {21721356, -4212746, -12206123, 9310182, -3882239, -13653110, + 23740224, -2709232, 20491983, -8042152}, + {9209270, -15135055, -13256557, -6167798, -731016, 15289673, + 25947805, 15286587, 30997318, -6703063}, + {7392032, 16618386, 23946583, -8039892, -13265164, -1533858, + -14197445, -2321576, 17649998, -250080}, + }, + { + {-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, + -15241566, -9525724, -2233253, 7662146}, + {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, + 7335080, -8472199, -3174674, 3440183}, + {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, + 40450, -4431835, 4862400, 1133}, + }, + { + {-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, + 7258061, 311861, -30594991, -7379421}, + {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, + 16527196, 18278453, 15405622}, + {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, + -13313598, 843523, -21875062, 13626197}, + }, + { + {2281448, -13487055, -10915418, -2609910, 1879358, 16164207, + -10783882, 3953792, 13340839, 15928663}, + {31727126, -7179855, -18437503, -8283652, 2875793, -16390330, + -25269894, -7014826, -23452306, 5964753}, + {4100420, -5959452, -17179337, 6017714, -18705837, 12227141, + -26684835, 11344144, 2538215, -7570755}, + }, + { + {-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, + -20474983, 1485421, -629256, -15958862}, + {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, + -20205425, -13191288, 11659922, -11115118}, + {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, + -10170080, 33100372, -1306171}, + }, + { + {15121113, -5201871, -10389905, 15427821, -27509937, -15992507, + 21670947, 4486675, -5931810, -14466380}, + {16166486, -9483733, -11104130, 6023908, -31926798, -1364923, + 2340060, -16254968, -10735770, -10039824}, + {28042865, -3557089, -12126526, 12259706, -3717498, -6945899, + 6766453, -8689599, 18036436, 5803270}, + }, + }, + { + { + {-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, + 4598332, -6159431, -14117438}, + {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, + 696309, 50292, -20095739, 11763584}, + {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, + -12613632, -19773211, -10713562}, + }, + { + {30464590, -11262872, -4127476, -12734478, 19835327, -7105613, + -24396175, 2075773, -17020157, 992471}, + {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, + 8080033, -11574335, -10601610}, + {19598397, 10334610, 12555054, 2555664, 18821899, -10339780, + 21873263, 16014234, 26224780, 16452269}, + }, + { + {-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, + -7618186, -20533829, 3698650}, + {14187449, 3448569, -10636236, -10810935, -22663880, -3433596, + 7268410, -10890444, 27394301, 12015369}, + {19695761, 16087646, 28032085, 12999827, 6817792, 11427614, + 20244189, -1312777, -13259127, -3402461}, + }, + { + {30860103, 12735208, -1888245, -4699734, -16974906, 2256940, + -8166013, 12298312, -8550524, -10393462}, + {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, + -5789354, -15118654, -4976164, 12651793}, + {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, + -13118820, -16517902, 9768698, -2533218}, + }, + { + {-24719459, 1894651, -287698, -4704085, 15348719, -8156530, + 32767513, 12765450, 4940095, 10678226}, + {18860224, 15980149, -18987240, -1562570, -26233012, -11071856, + -7843882, 13944024, -24372348, 16582019}, + {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, + -11704054, 15444560, -11003761, 7989037}, + }, + { + {31490452, 5568061, -2412803, 2182383, -32336847, 4531686, + -32078269, 6200206, -19686113, -14800171}, + {-17308668, -15879940, -31522777, -2831, -32887382, 16375549, + 8680158, -16371713, 28550068, -6857132}, + {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, + -30039981, 4364038, 1155602, 5988841}, + }, + { + {21890435, -13272907, -12624011, 12154349, -7831873, 15300496, + 23148983, -4470481, 24618407, 8283181}, + {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, + 3070187, -7025928, 1466169, 10740210}, + {-1509399, -15488185, -13503385, -10655916, 32799044, 909394, + -13938903, -5779719, -32164649, -15327040}, + }, + { + {3960823, -14267803, -28026090, -15918051, -19404858, 13146868, + 15567327, 951507, -3260321, -573935}, + {24740841, 5052253, -30094131, 8961361, 25877428, 6165135, + -24368180, 14397372, -7380369, -6144105}, + {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, + -15441463, -14453128, -1625486, -6494814}, + }, + }, + { + { + {793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, + -4885251, -9906200, -621852}, + {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, + 1468826, -6171428, -15186581}, + {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, + -30404353, -9871238, -1558923, -9863646}, + }, + { + {10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, + 14783338, -30581476, -15757844}, + {10566929, 12612572, -31944212, 11118703, -12633376, 12362879, + 21752402, 8822496, 24003793, 14264025}, + {27713862, -7355973, -11008240, 9227530, 27050101, 2504721, + 23886875, -13117525, 13958495, -5732453}, + }, + { + {-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, + -31889399, -10041781, 7340521, -15410068}, + {4646514, -8011124, -22766023, -11532654, 23184553, 8566613, + 31366726, -1381061, -15066784, -10375192}, + {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, + 27584817, 3093888, -8843694, 3849921}, + }, + { + {-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, + 32477045, -9017955, 5002294, -15550259}, + {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, + 16489530, 13378448, -25845716, 12741426}, + {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, + 24306472, 15852464, 28834118, -7646072}, + }, + { + {-17335748, -9107057, -24531279, 9434953, -8472084, -583362, + -13090771, 455841, 20461858, 5491305}, + {13669248, -16095482, -12481974, -10203039, -14569770, -11893198, + -24995986, 11293807, -28588204, -9421832}, + {28497928, 6272777, -33022994, 14470570, 8906179, -1225630, + 18504674, -14165166, 29867745, -8795943}, + }, + { + {-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, + -6367600, -13175392, 22853429, -4012011}, + {24191378, 16712145, -13931797, 15217831, 14542237, 1646131, + 18603514, -11037887, 12876623, -2112447}, + {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, + 608397, 16031844, 3723494}, + }, + { + {-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, + 17558842, -7872890, 23896954, -4314245}, + {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, + 7229064, -9919646, -8826859}, + {28816045, 298879, -28165016, -15920938, 19000928, -1665890, + -12680833, -2949325, -18051778, -2082915}, + }, + { + {16000882, -344896, 3493092, -11447198, -29504595, -13159789, + 12577740, 16041268, -19715240, 7847707}, + {10151868, 10572098, 27312476, 7922682, 14825339, 4723128, + -32855931, -6519018, -10020567, 3852848}, + {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, + 16514493, -15932110, 29330899, -15076224}, + }, + }, + { + { + {-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, + 3303702, 15490, -27548796, 12314391}, + {15683520, -6003043, 18109120, -9980648, 15337968, -5997823, + -16717435, 15921866, 16103996, -3731215}, + {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, + -19273607, 5402699, -29815713, -9841101}, + }, + { + {23190676, 2384583, -32714340, 3462154, -29903655, -1529132, + -11266856, 8911517, -25205859, 2739713}, + {21374101, -3554250, -33524649, 9874411, 15377179, 11831242, + -33529904, 6134907, 4931255, 11987849}, + {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, + 13861388, -30076310, 10117930}, + }, + { + {-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, + -6325503, 6704079, 12890019, 15728940}, + {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, + -10428139, 12885167, 8311031}, + {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, + 26423267, 4384730, 1888765, -5435404}, + }, + { + {-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, + -32251644, -12707869, -19464434, -3340243}, + {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, + 14845197, 17151279, -9854116}, + {-24830458, -12733720, -15165978, 10367250, -29530908, -265356, + 22825805, -7087279, -16866484, 16176525}, + }, + { + {-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, + -10363426, -28746253, -10197509}, + {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, + 23632037, -1940610, 32808310, 1099883}, + {15030977, 5768825, -27451236, -2887299, -6427378, -15361371, + -15277896, -6809350, 2051441, -15225865}, + }, + { + {-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, + -14154188, -22686354, 16633660}, + {4577086, -16752288, 13249841, -15304328, 19958763, -14537274, + 18559670, -10759549, 8402478, -9864273}, + {-28406330, -1051581, -26790155, -907698, -17212414, -11030789, + 9453451, -14980072, 17983010, 9967138}, + }, + { + {-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, + 7806337, 17507396, 3651560}, + {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, + 26556809, -5574557, -18553322, -11357135}, + {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, + 8459447, -5605463, -7621941}, + }, + { + {-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, + -849066, 17258084, -7977739}, + {18164541, -10595176, -17154882, -1542417, 19237078, -9745295, + 23357533, -15217008, 26908270, 12150756}, + {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, + -5537701, -32302074, 16215819}, + }, + }, + { + { + {-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, + 32574489, 12532905, -7503072, -8675347}, + {-27343522, -16515468, -27151524, -10722951, 946346, 16291093, + 254968, 7168080, 21676107, -1943028}, + {21260961, -8424752, -16831886, -11920822, -23677961, 3968121, + -3651949, -6215466, -3556191, -7913075}, + }, + { + {16544754, 13250366, -16804428, 15546242, -4583003, 12757258, + -2462308, -8680336, -18907032, -9662799}, + {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, + 26820651, 16690659, 25459437, -4564609}, + {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, + 9142795, -2391602, -6432418, -1644817}, + }, + { + {-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, + -27457225, -16344658, 6335692, 7249989}, + {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, + -30272269, 2682242, 25993170, -12478523}, + {4364628, 5930691, 32304656, -10044554, -8054781, 15091131, + 22857016, -10598955, 31820368, 15075278}, + }, + { + {31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, + -9650886, -17970238, 12833045}, + {19073683, 14851414, -24403169, -11860168, 7625278, 11091125, + -19619190, 2074449, -9413939, 14905377}, + {24483667, -11935567, -2518866, -11547418, -1553130, 15355506, + -25282080, 9253129, 27628530, -7555480}, + }, + { + {17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, + -9157582, -14110875, 15297016}, + {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, + -11864220, 8683221, 2921426}, + {18606791, 11874196, 27155355, -5281482, -24031742, 6265446, + -25178240, -1278924, 4674690, 13890525}, + }, + { + {13609624, 13069022, -27372361, -13055908, 24360586, 9592974, + 14977157, 9835105, 4389687, 288396}, + {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, + 8317628, 23388070, 16052080}, + {12720016, 11937594, -31970060, -5028689, 26900120, 8561328, + -20155687, -11632979, -14754271, -10812892}, + }, + { + {15961858, 14150409, 26716931, -665832, -22794328, 13603569, + 11829573, 7467844, -28822128, 929275}, + {11038231, -11582396, -27310482, -7316562, -10498527, -16307831, + -23479533, -9371869, -21393143, 2465074}, + {20017163, -4323226, 27915242, 1529148, 12396362, 15675764, + 13817261, -9658066, 2463391, -4622140}, + }, + { + {-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, + 9583558, 12851107, 4003896, 12673717}, + {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, + 14741514, -9103726, 7903886, 2348101}, + {24536016, -16515207, 12715592, -3862155, 1511293, 10047386, + -3842346, -7129159, -28377538, 10048127}, + }, + }, + { + { + {-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, + 18873298, -7297090, -32297756, 15221632}, + {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, + -21343950, 2095755, 29769758, 6593415}, + {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, + -6118678, 30958054, 8292160}, + }, + { + {31429822, -13959116, 29173532, 15632448, 12174511, -2760094, + 32808831, 3977186, 26143136, -3148876}, + {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, + -1674433, -3758243, -2304625}, + {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, + -1612713, -1535569, -16664475, 8194478}, + }, + { + {27338066, -7507420, -7414224, 10140405, -19026427, -6589889, + 27277191, 8855376, 28572286, 3005164}, + {26287124, 4821776, 25476601, -4145903, -3764513, -15788984, + -18008582, 1182479, -26094821, -13079595}, + {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, + -21876275, -13982627, 32208683, -1198248}, + }, + { + {-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, + -27315504, -10497842, -27672585, -11539858}, + {15941029, -9405932, -21367050, 8062055, 31876073, -238629, + -15278393, -1444429, 15397331, -4130193}, + {8934485, -13485467, -23286397, -13423241, -32446090, 14047986, + 31170398, -1441021, -27505566, 15087184}, + }, + { + {-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, + -15502406, 11461896, 16788528, -5868942}, + {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, + -3770287, -10323320, 31322514, -11615635}, + {21426655, -5650218, -13648287, -5347537, -28812189, -4920970, + -18275391, -14621414, 13040862, -12112948}, + }, + { + {11293895, 12478086, -27136401, 15083750, -29307421, 14748872, + 14555558, -13417103, 1613711, 4896935}, + {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, + 2825960, -4897045, -23971776, -11267415}, + {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, + 20615400, 12405433, -23753030, -8436416}, + }, + { + {-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, + 4378436, 2432030, 23097949, -566018}, + {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, + 10103221, -18512313, 2424778}, + {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, + 1344109, -3642553, 12412659}, + }, + { + {-24001791, 7690286, 14929416, -168257, -32210835, -13412986, + 24162697, -15326504, -3141501, 11179385}, + {18289522, -14724954, 8056945, 16430056, -21729724, 7842514, + -6001441, -1486897, -18684645, -11443503}, + {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, + 13403813, 11052904, 5219329}, + }, + }, + { + { + {20678546, -8375738, -32671898, 8849123, -5009758, 14574752, + 31186971, -3973730, 9014762, -8579056}, + {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, + -33102500, 9160280, 8473550, -3256838}, + {24900749, 14435722, 17209120, -15292541, -22592275, 9878983, + -7689309, -16335821, -24568481, 11788948}, + }, + { + {-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, + -20037437, 10410733, -24568470, -1458691}, + {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, + 11871841, -12505194, -18513325, 8464118}, + {-23400612, 8348507, -14585951, -861714, -3950205, -6373419, + 14325289, 8628612, 33313881, -8370517}, + }, + { + {-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, + -24805667, -10236854, -8940735, -5818269}, + {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, + 15989197, -12838188, 28358192, -4253904}, + {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, + -16637684, 4072016, -5351664, 5596589}, + }, + { + {-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, + 29266239, 2557221, 1768301, 15373193}, + {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, + -4504991, -24660491, 3442910}, + {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, + 22597931, 7176455, -18585478, 13365930}, + }, + { + {-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, + -8570186, -9689599, -3031667}, + {25008904, -10771599, -4305031, -9638010, 16265036, 15721635, + 683793, -11823784, 15723479, -15163481}, + {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, + 11879682, 5400171, 519526, -1235876}, + }, + { + {22258397, -16332233, -7869817, 14613016, -22520255, -2950923, + -20353881, 7315967, 16648397, 7605640}, + {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, + 23994942, -5281555, -9468848, 4763278}, + {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, + 31088447, -7764523, -11356529, 728112}, + }, + { + {26047220, -11751471, -6900323, -16521798, 24092068, 9158119, + -4273545, -12555558, -29365436, -5498272}, + {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, + 12327945, 10750447, 10014012}, + {-10312768, 3936952, 9156313, -8897683, 16498692, -994647, + -27481051, -666732, 3424691, 7540221}, + }, + { + {30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, + -16317219, -9244265, 15258046}, + {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, + 2711395, 1062915, -5136345}, + {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, + -6066489, 12194497, 32960380, 1459310}, + }, + }, + { + { + {19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, + -6101885, 18638003, -11174937}, + {31395534, 15098109, 26581030, 8030562, -16527914, -5007134, + 9012486, -7584354, -6643087, -5442636}, + {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, + 9677543, -32294889, -6456008}, + }, + { + {-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, + -7839692, -7852844, -8138429}, + {-15236356, -15433509, 7766470, 746860, 26346930, -10221762, + -27333451, 10754588, -9431476, 5203576}, + {31834314, 14135496, -770007, 5159118, 20917671, -16768096, + -7467973, -7337524, 31809243, 7347066}, + }, + { + {-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, + 19797970, -12211255, 15192876, -2087490}, + {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, + 10609330, 12694420, 33473243, -13382104}, + {33184999, 11180355, 15832085, -11385430, -1633671, 225884, + 15089336, -11023903, -6135662, 14480053}, + }, + { + {31308717, -5619998, 31030840, -1897099, 15674547, -6582883, + 5496208, 13685227, 27595050, 8737275}, + {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, + -31008351, -12610604, 26498114, 66511}, + {22644454, -8761729, -16671776, 4884562, -3105614, -13559366, + 30540766, -4286747, -13327787, -7515095}, + }, + { + {-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, + 8205540, 13585437, -17127465, 15115439}, + {23711543, -672915, 31206561, -8362711, 6164647, -9709987, + -33535882, -1426096, 8236921, 16492939}, + {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, + 19574902, 10071562, 6708380, -6222424}, + }, + { + {2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, + 9328700, 29955601, -11678310}, + {3096359, 9271816, -21620864, -15521844, -14847996, -7592937, + -25892142, -12635595, -9917575, 6216608}, + {-32615849, 338663, -25195611, 2510422, -29213566, -13820213, + 24822830, -6146567, -26767480, 7525079}, + }, + { + {-23066649, -13985623, 16133487, -7896178, -3389565, 778788, + -910336, -2782495, -19386633, 11994101}, + {21691500, -13624626, -641331, -14367021, 3285881, -3483596, + -25064666, 9718258, -7477437, 13381418}, + {18445390, -4202236, 14979846, 11622458, -1727110, -3582980, + 23111648, -6375247, 28535282, 15779576}, + }, + { + {30098053, 3089662, -9234387, 16662135, -21306940, 11308411, + -14068454, 12021730, 9955285, -16303356}, + {9734894, -14576830, -7473633, -9138735, 2060392, 11313496, + -18426029, 9924399, 20194861, 13380996}, + {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, + -1984914, 15707771, 26342023, 10146099}, + }, + }, + { + { + {-26016874, -219943, 21339191, -41388, 19745256, -2878700, + -29637280, 2227040, 21612326, -545728}, + {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, + 25764461, 12243797, -20856566, 11649658}, + {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, + 6114064, 33514190, 2333242}, + }, + { + {-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, + -6679750, -12670638, 24350578, -13450001}, + {-4116307, -11271533, -23886186, 4843615, -30088339, 690623, + -31536088, -10406836, 8317860, 12352766}, + {18200138, -14475911, -33087759, -2696619, -23702521, -9102511, + -23552096, -2287550, 20712163, 6719373}, + }, + { + {26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, + -3763210, 26224235, -3297458}, + {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, + 21728352, 9493610, 18620611, -16428628}, + {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, + -5269471, -9725556, -30701573, -16479657}, + }, + { + {-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, + 12248509, -5240639, 13735342, 1934062}, + {25089769, 6742589, 17081145, -13406266, 21909293, -16067981, + -15136294, -3765346, -21277997, 5473616}, + {31883677, -7961101, 1083432, -11572403, 22828471, 13290673, + -7125085, 12469656, 29111212, -5451014}, + }, + { + {24244947, -15050407, -26262976, 2791540, -14997599, 16666678, + 24367466, 6388839, -10295587, 452383}, + {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, + -24236251, -5915248, 15766062, 8407814}, + {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, + -8917023, -4388953, -8067909, 2276718}, + }, + { + {30157918, 12924066, -17712050, 9245753, 19895028, 3368142, + -23827587, 5096219, 22740376, -7303417}, + {2041139, -14256350, 7783687, 13876377, -25946985, -13352459, + 24051124, 13742383, -15637599, 13295222}, + {33338237, -8505733, 12532113, 7977527, 9106186, -1715251, + -17720195, -4612972, -4451357, -14669444}, + }, + { + {-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, + -2469266, -4141880, 7770569, 9620597}, + {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, + -1694323, -33502340, -14767970}, + {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, + 1220118, 30494170, -11440799}, + }, + { + {-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, + -26739026, 926050, -1684339, -13333647}, + {13908495, -3549272, 30919928, -6273825, -21521863, 7989039, + 9021034, 9078865, 3353509, 4033511}, + {-29663431, -15113610, 32259991, -344482, 24295849, -12912123, + 23161163, 8839127, 27485041, 7356032}, + }, + }, + { + { + {9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, + 2625015, 28431036, -16771834}, + {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, + -22545972, 14150565, 15970762, 4099461}, + {29262576, 16756590, 26350592, -8793563, 8529671, -11208050, + 13617293, -9937143, 11465739, 8317062}, + }, + { + {-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, + 14898637, 3848455, 20969334, -5157516}, + {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, + -21610826, -3649888, 11177095, 14989547}, + {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, + 13515641, 2581286, -28487508, 9930240}, + }, + { + {-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, + 18345767, -13403753, 16291481, -5314038}, + {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, + 6957617, 4368891, 9788741}, + {16660756, 7281060, -10830758, 12911820, 20108584, -8101676, + -21722536, -8613148, 16250552, -11111103}, + }, + { + {-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, + 10604807, -30190403, 4782747}, + {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, + -9981571, 4383045, 22546403, 437323}, + {31665577, -12180464, -16186830, 1491339, -18368625, 3294682, + 27343084, 2786261, -30633590, -14097016}, + }, + { + {-14467279, -683715, -33374107, 7448552, 19294360, 14334329, + -19690631, 2355319, -19284671, -6114373}, + {15121312, -15796162, 6377020, -6031361, -10798111, -12957845, + 18952177, 15496498, -29380133, 11754228}, + {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, + 7141596, 11724556, 22761615, -10134141}, + }, + { + {16918416, 11729663, -18083579, 3022987, -31015732, -13339659, + -28741185, -12227393, 32851222, 11717399}, + {11166634, 7338049, -6722523, 4531520, -29468672, -7302055, + 31474879, 3483633, -1193175, -4030831}, + {-185635, 9921305, 31456609, -13536438, -12013818, 13348923, + 33142652, 6546660, -19985279, -3948376}, + }, + { + {-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, + -8537131, -12833048, -30772034, -15486313}, + {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, + -31135347, -16049879, 10928917, 3011958}, + {-6957757, -15594337, 31696059, 334240, 29576716, 14796075, + -30831056, -12805180, 18008031, 10258577}, + }, + { + {-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, + -1853465, 1367120, 25127874, 6671743}, + {29701166, -14373934, -10878120, 9279288, -17568, 13127210, + 21382910, 11042292, 25838796, 4642684}, + {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, + 30468147, -13900640, 18423289, 4177476}, + }, + }, +}; + +static uint8_t negative(signed char b) { + uint32_t x = b; + x >>= 31; /* 1: yes; 0: no */ + return x; +} + +static void table_select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + uint8_t bnegative = negative(b); + uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1); + + ge_precomp_0(t); + cmov(t, &k25519Precomp[pos][0], equal(babs, 1)); + cmov(t, &k25519Precomp[pos][1], equal(babs, 2)); + cmov(t, &k25519Precomp[pos][2], equal(babs, 3)); + cmov(t, &k25519Precomp[pos][3], equal(babs, 4)); + cmov(t, &k25519Precomp[pos][4], equal(babs, 5)); + cmov(t, &k25519Precomp[pos][5], equal(babs, 6)); + cmov(t, &k25519Precomp[pos][6], equal(babs, 7)); + cmov(t, &k25519Precomp[pos][7], equal(babs, 8)); + fe_copy(minust.yplusx, t->yminusx); + fe_copy(minust.yminusx, t->yplusx); + fe_neg(minust.xy2d, t->xy2d); + cmov(t, &minust, bnegative); +} + +/* h = a * B + * where a = a[0]+256*a[1]+...+256^31 a[31] + * B is the Ed25519 base point (x,4/5) with x positive. + * + * Preconditions: + * a[31] <= 127 */ +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge_p3_0(h); + for (i = 1; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#endif + +static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) { + fe_cmov(t->YplusX, u->YplusX, b); + fe_cmov(t->YminusX, u->YminusX, b); + fe_cmov(t->Z, u->Z, b); + fe_cmov(t->T2d, u->T2d, b); +} + +/* r = scalar * A. + * where a = a[0]+256*a[1]+...+256^31 a[31]. */ +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) { + ge_p2 Ai_p2[8]; + ge_cached Ai[16]; + ge_p1p1 t; + + ge_cached_0(&Ai[0]); + x25519_ge_p3_to_cached(&Ai[1], A); + ge_p3_to_p2(&Ai_p2[1], A); + + unsigned i; + for (i = 2; i < 16; i += 2) { + ge_p2_dbl(&t, &Ai_p2[i / 2]); + ge_p1p1_to_cached(&Ai[i], &t); + if (i < 8) { + x25519_ge_p1p1_to_p2(&Ai_p2[i], &t); + } + x25519_ge_add(&t, A, &Ai[i]); + ge_p1p1_to_cached(&Ai[i + 1], &t); + if (i < 7) { + x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t); + } + } + + ge_p2_0(r); + ge_p3 u; + + for (i = 0; i < 256; i += 4) { + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p3(&u, &t); + + uint8_t index = scalar[31 - i/8]; + index >>= 4 - (i & 4); + index &= 0xf; + + unsigned j; + ge_cached selected; + ge_cached_0(&selected); + for (j = 0; j < 16; j++) { + cmov_cached(&selected, &Ai[j], equal(j, index)); + } + + x25519_ge_add(&t, &u, &selected); + x25519_ge_p1p1_to_p2(r, &t); + } +} + +static void slide(signed char *r, const uint8_t *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) { + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } +} + +static const ge_precomp Bi[8] = { + { + {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, + -11754271, -6079156, 2047605}, + {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, + 5043384, 19500929, -15469378}, + {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, + 11864899, -24514362, -4438546}, + }, + { + {15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, + -14772189, 28944400, -1550024}, + {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, + -11775962, 7689662, 11199574}, + {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, + 10017326, -17749093, -9920357}, + }, + { + {10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, + 14515107, -15438304, 10819380}, + {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, + 12483688, -12668491, 5581306}, + {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, + 13850243, -23678021, -15815942}, + }, + { + {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, + 5230134, -23952439, -15175766}, + {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, + 16520125, 30598449, 7715701}, + {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, + 1370708, 29794553, -1409300}, + }, + { + {-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, + -1361450, -13062696, 13821877}, + {-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, + -7212327, 18853322, -14220951}, + {4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, + -10431137, 2207753, -3209784}, + }, + { + {-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, + -663000, -31111463, -16132436}, + {25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, + 15725684, 171356, 6466918}, + {23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, + -14088058, -30714912, 16193877}, + }, + { + {-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, + 4729455, -18074513, 9256800}, + {-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, + 9761698, -19827198, 630305}, + {-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, + -15960994, -2449256, -14291300}, + }, + { + {-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, + 15033784, 25105118, -7894876}, + {-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, + 1573892, -2625887, 2198790, -15804619}, + {-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, + -16236442, -32461234, -12290683}, + }, +}; + +/* r = a * A + b * B + * where a = a[0]+256*a[1]+...+256^31 a[31]. + * and b = b[0]+256*b[1]+...+256^31 b[31]. + * B is the Ed25519 base point (x,4/5) with x positive. */ +static void +ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, + const ge_p3 *A, const uint8_t *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide, a); + slide(bslide, b); + + x25519_ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + x25519_ge_p1p1_to_p3(&A2, &t); + x25519_ge_add(&t, &A2, &Ai[0]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[1], &u); + x25519_ge_add(&t, &A2, &Ai[1]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[2], &u); + x25519_ge_add(&t, &A2, &Ai[2]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[3], &u); + x25519_ge_add(&t, &A2, &Ai[3]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[4], &u); + x25519_ge_add(&t, &A2, &Ai[4]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[5], &u); + x25519_ge_add(&t, &A2, &Ai[5]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[6], &u); + x25519_ge_add(&t, &A2, &Ai[6]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[7], &u); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + x25519_ge_p1p1_to_p2(r, &t); + } +} + +/* The set of scalars is \Z/l + * where l = 2^252 + 27742317777372353535851937790883648493. */ + +/* Input: + * s[0]+256*s[1]+...+256^63*s[63] = s + * + * Output: + * s[0]+256*s[1]+...+256^31*s[31] = s mod l + * where l = 2^252 + 27742317777372353535851937790883648493. + * Overwrites s in place. */ +void +x25519_sc_reduce(uint8_t *s) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* Input: + * a[0]+256*a[1]+...+256^31*a[31] = a + * b[0]+256*b[1]+...+256^31*b[31] = b + * c[0]+256*c[1]+...+256^31*c[31] = c + * + * Output: + * s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + * where l = 2^252 + 27742317777372353535851937790883648493. */ +static void +sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, + const uint8_t *c) +{ + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void ED25519_public_from_private(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH], + const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(private_key, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, az); + ge_p3_tobytes(out_public_key, &A); +} + +void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH], + uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]) { + arc4random_buf(out_private_key, 32); + + ED25519_public_from_private(out_public_key, out_private_key); +} +LCRYPTO_ALIAS(ED25519_keypair); + +int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, + const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH], + const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(private_key, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, az + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t nonce[SHA512_DIGEST_LENGTH]; + SHA512_Final(nonce, &hash_ctx); + + x25519_sc_reduce(nonce); + ge_p3 R; + x25519_ge_scalarmult_base(&R, nonce); + ge_p3_tobytes(out_sig, &R); + + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, out_sig, 32); + SHA512_Update(&hash_ctx, public_key, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t hram[SHA512_DIGEST_LENGTH]; + SHA512_Final(hram, &hash_ctx); + + x25519_sc_reduce(hram); + sc_muladd(out_sig + 32, hram, az, nonce); + + return 1; +} +LCRYPTO_ALIAS(ED25519_sign); + +/* + * Little endian representation of the order of edwards25519, + * see https://www.rfc-editor.org/rfc/rfc7748#section-4.1 + */ +static const uint8_t order[] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +}; + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[ED25519_SIGNATURE_LENGTH], + const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]) { + ge_p3 A; + int i; + if ((signature[63] & 224) != 0 || + x25519_ge_frombytes_vartime(&A, public_key) != 0) { + return 0; + } + + fe_neg(A.X, A.X); + fe_neg(A.T, A.T); + + uint8_t pkcopy[32]; + memcpy(pkcopy, public_key, 32); + uint8_t rcopy[32]; + memcpy(rcopy, signature, 32); + uint8_t scopy[32]; + memcpy(scopy, signature + 32, 32); + + /* + * https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that scopy be + * in the range [0, order) to prevent signature malleability. This value is + * public, so there is no need to make this constant time. + */ + for (i = 31; i >= 0; i--) { + if (scopy[i] > order[i]) + return 0; + if (scopy[i] < order[i]) + break; + if (i == 0) + return 0; + } + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, signature, 32); + SHA512_Update(&hash_ctx, public_key, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t h[SHA512_DIGEST_LENGTH]; + SHA512_Final(h, &hash_ctx); + + x25519_sc_reduce(h); + + ge_p2 R; + ge_double_scalarmult_vartime(&R, h, &A, scopy); + + uint8_t rcheck[32]; + x25519_ge_tobytes(rcheck, &R); + + return timingsafe_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; +} +LCRYPTO_ALIAS(ED25519_verify); + +/* Replace (f,g) with (g,f) if b == 1; + * replace (f,g) with (f,g) if b == 0. + * + * Preconditions: b in {0,1}. */ +static void fe_cswap(fe f, fe g, unsigned int b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + int32_t x = f[i] ^ g[i]; + x &= b; + f[i] ^= x; + g[i] ^= x; + } +} + +/* h = f * 121666 + * Can overlap h with f. + * + * Preconditions: + * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */ +static void fe_mul121666(fe h, fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * (int64_t) 121666; + int64_t h1 = f1 * (int64_t) 121666; + int64_t h2 = f2 * (int64_t) 121666; + int64_t h3 = f3 * (int64_t) 121666; + int64_t h4 = f4 * (int64_t) 121666; + int64_t h5 = f5 * (int64_t) 121666; + int64_t h6 = f6 * (int64_t) 121666; + int64_t h7 = f7 * (int64_t) 121666; + int64_t h8 = f8 * (int64_t) 121666; + int64_t h9 = f9 * (int64_t) 121666; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits; + carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits; + carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits; + carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits; + carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits; + + carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits; + carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits; + carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits; + carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits; + carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +void +x25519_scalar_mult_generic(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { + fe x1, x2, z2, x3, z3, tmp0, tmp1; + + uint8_t e[32]; + memcpy(e, scalar, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + fe_frombytes(x1, point); + fe_1(x2); + fe_0(z2); + fe_copy(x3, x1); + fe_1(z3); + + unsigned swap = 0; + int pos; + for (pos = 254; pos >= 0; --pos) { + unsigned b = 1 & (e[pos / 8] >> (pos & 7)); + swap ^= b; + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + swap = b; + fe_sub(tmp0, x3, z3); + fe_sub(tmp1, x2, z2); + fe_add(x2, x2, z2); + fe_add(z2, x3, z3); + fe_mul(z3, tmp0, x2); + fe_mul(z2, z2, tmp1); + fe_sq(tmp0, tmp1); + fe_sq(tmp1, x2); + fe_add(x3, z3, z2); + fe_sub(z2, z3, z2); + fe_mul(x2, tmp1, tmp0); + fe_sub(tmp1, tmp1, tmp0); + fe_sq(z2, z2); + fe_mul121666(z3, tmp1); + fe_sq(x3, x3); + fe_add(tmp0, tmp0, z3); + fe_mul(z3, x1, z2); + fe_mul(z2, tmp1, tmp0); + } + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + + fe_invert(z2, z2); + fe_mul(x2, x2, z2); + fe_tobytes(out, x2); +} + +#ifdef unused +void +x25519_public_from_private_generic(uint8_t out_public_key[32], + const uint8_t private_key[32]) +{ + uint8_t e[32]; + + memcpy(e, private_key, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, e); + + /* We only need the u-coordinate of the curve25519 point. The map is + * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */ + fe zplusy, zminusy, zminusy_inv; + fe_add(zplusy, A.Z, A.Y); + fe_sub(zminusy, A.Z, A.Y); + fe_invert(zminusy_inv, zminusy); + fe_mul(zplusy, zplusy, zminusy_inv); + fe_tobytes(out_public_key, zplusy); +} +#endif + +void +X25519_public_from_private(uint8_t out_public_key[X25519_KEY_LENGTH], + const uint8_t private_key[X25519_KEY_LENGTH]) +{ + static const uint8_t kMongomeryBasePoint[32] = {9}; + + x25519_scalar_mult(out_public_key, private_key, kMongomeryBasePoint); +} + +void +X25519_keypair(uint8_t out_public_key[X25519_KEY_LENGTH], + uint8_t out_private_key[X25519_KEY_LENGTH]) +{ + /* All X25519 implementations should decode scalars correctly (see + * https://tools.ietf.org/html/rfc7748#section-5). However, if an + * implementation doesn't then it might interoperate with random keys a + * fraction of the time because they'll, randomly, happen to be correctly + * formed. + * + * Thus we do the opposite of the masking here to make sure that our private + * keys are never correctly masked and so, hopefully, any incorrect + * implementations are deterministically broken. + * + * This does not affect security because, although we're throwing away + * entropy, a valid implementation of scalarmult should throw away the exact + * same bits anyway. */ + arc4random_buf(out_private_key, 32); + + out_private_key[0] |= 7; + out_private_key[31] &= 63; + out_private_key[31] |= 128; + + X25519_public_from_private(out_public_key, out_private_key); +} +LCRYPTO_ALIAS(X25519_keypair); + +int +X25519(uint8_t out_shared_key[X25519_KEY_LENGTH], + const uint8_t private_key[X25519_KEY_LENGTH], + const uint8_t peer_public_key[X25519_KEY_LENGTH]) +{ + static const uint8_t kZeros[32] = {0}; + + x25519_scalar_mult(out_shared_key, private_key, peer_public_key); + + /* The all-zero output results when the input is a point of small order. */ + return timingsafe_memcmp(kZeros, out_shared_key, 32) != 0; +} +LCRYPTO_ALIAS(X25519); diff --git a/Libraries/libressl/crypto/curve25519/curve25519_internal.h b/Libraries/libressl/crypto/curve25519/curve25519_internal.h new file mode 100644 index 000000000..abfaaaf52 --- /dev/null +++ b/Libraries/libressl/crypto/curve25519/curve25519_internal.h @@ -0,0 +1,105 @@ +/* $OpenBSD: curve25519_internal.h,v 1.6 2022/11/09 17:45:55 jsing Exp $ */ +/* + * Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_CURVE25519_INTERNAL_H +#define HEADER_CURVE25519_INTERNAL_H + +#include + +__BEGIN_HIDDEN_DECLS + +/* fe means field element. Here the field is \Z/(2^255-19). An element t, + * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 + * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on + * context. */ +typedef int32_t fe[10]; + +/* ge means group element. + + * Here the group is the set of pairs (x,y) of field elements (see fe.h) + * satisfying -x^2 + y^2 = 1 + d x^2y^2 + * where d = -121665/121666. + * + * Representations: + * ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + * ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + * ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + * ge_precomp (Duif): (y+x,y-x,2dxy) */ + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p1p1; + +typedef struct { + fe yplusx; + fe yminusx; + fe xy2d; +} ge_precomp; + +typedef struct { + fe YplusX; + fe YminusX; + fe Z; + fe T2d; +} ge_cached; + +void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h); +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s); +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p); +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_scalarmult_small_precomp(ge_p3 *h, const uint8_t a[32], + const uint8_t precomp_table[15 * 2 * 32]); +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]); +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A); +void x25519_sc_reduce(uint8_t *s); + +void x25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]); + +void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +void x25519_scalar_mult_generic(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); + +void ED25519_public_from_private(uint8_t out_public_key[32], + const uint8_t private_key[32]); + +void X25519_public_from_private(uint8_t out_public_key[32], + const uint8_t private_key[32]); + +__END_HIDDEN_DECLS + +#endif /* HEADER_CURVE25519_INTERNAL_H */ diff --git a/Libraries/libressl/crypto/cversion.c b/Libraries/libressl/crypto/cversion.c new file mode 100644 index 000000000..acb7b7054 --- /dev/null +++ b/Libraries/libressl/crypto/cversion.c @@ -0,0 +1,116 @@ +/* $OpenBSD: cversion.c,v 1.18 2023/07/08 08:28:23 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "cryptlib.h" + +const char * +SSLeay_version(int t) +{ + switch (t) { + case SSLEAY_VERSION: + return OPENSSL_VERSION_TEXT; + case SSLEAY_BUILT_ON: + return("built on: date not available"); + case SSLEAY_CFLAGS: + return("compiler: information not available"); + case SSLEAY_PLATFORM: + return("platform: information not available"); + case SSLEAY_DIR: + return "OPENSSLDIR: \"" OPENSSLDIR "\""; + } + return("not available"); +} +LCRYPTO_ALIAS(SSLeay_version); + +unsigned long +SSLeay(void) +{ + return (SSLEAY_VERSION_NUMBER); +} +LCRYPTO_ALIAS(SSLeay); + +const char * +OpenSSL_version(int t) +{ + switch (t) { + case OPENSSL_VERSION: + return OPENSSL_VERSION_TEXT; + case OPENSSL_BUILT_ON: + return("built on: date not available"); + case OPENSSL_CFLAGS: + return("compiler: information not available"); + case OPENSSL_PLATFORM: + return("platform: information not available"); + case OPENSSL_DIR: + return "OPENSSLDIR: \"" OPENSSLDIR "\""; + case OPENSSL_ENGINES_DIR: + return "ENGINESDIR: N/A"; + } + return("not available"); +} +LCRYPTO_ALIAS(OpenSSL_version); + +unsigned long +OpenSSL_version_num(void) +{ + return SSLeay(); +} +LCRYPTO_ALIAS(OpenSSL_version_num); diff --git a/Libraries/libressl/crypto/des/cbc_cksm.c b/Libraries/libressl/crypto/des/cbc_cksm.c new file mode 100644 index 000000000..afa3f03d9 --- /dev/null +++ b/Libraries/libressl/crypto/des/cbc_cksm.c @@ -0,0 +1,105 @@ +/* $OpenBSD: cbc_cksm.c,v 1.10 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +DES_LONG +DES_cbc_cksum(const unsigned char *in, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec) +{ + DES_LONG tout0, tout1, tin0, tin1; + long l = length; + DES_LONG tin[2]; + unsigned char *out = &(*output)[0]; + const unsigned char *iv = &(*ivec)[0]; + + c2l(iv, tout0); + c2l(iv, tout1); + for (; l > 0; l -= 8) { + if (l >= 8) { + c2l(in, tin0); + c2l(in, tin1); + } else + c2ln(in, tin0, tin1, l); + + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); + /* fix 15/10/91 eay - thanks to keithr@sco.COM */ + tout0 = tin[0]; + tout1 = tin[1]; + } + if (out != NULL) { + l2c(tout0, out); + l2c(tout1, out); + } + tout0 = tin0 = tin1 = tin[0] = tin[1] = 0; + /* + Transform the data in tout1 so that it will + match the return value that the MIT Kerberos + mit_des_cbc_cksum API returns. + */ + tout1 = ((tout1 >> 24L) & 0x000000FF) | + ((tout1 >> 8L) & 0x0000FF00) | + ((tout1 << 8L) & 0x00FF0000) | + ((tout1 << 24L) & 0xFF000000); + return (tout1); +} diff --git a/Libraries/libressl/crypto/des/cbc_enc.c b/Libraries/libressl/crypto/des/cbc_enc.c new file mode 100644 index 000000000..6c1ec7117 --- /dev/null +++ b/Libraries/libressl/crypto/des/cbc_enc.c @@ -0,0 +1,61 @@ +/* $OpenBSD: cbc_enc.c,v 1.4 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define CBC_ENC_C__DONT_UPDATE_IV + +#include "ncbc_enc.c" /* des_cbc_encrypt */ diff --git a/Libraries/libressl/crypto/des/cfb64ede.c b/Libraries/libressl/crypto/des/cfb64ede.c new file mode 100644 index 000000000..e91dbbfc4 --- /dev/null +++ b/Libraries/libressl/crypto/des/cfb64ede.c @@ -0,0 +1,240 @@ +/* $OpenBSD: cfb64ede.c,v 1.12 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +/* The input and output encrypted as though 64bit cfb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ + +void +DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc) +{ + DES_LONG v0, v1; + long l = length; + int n = *num; + DES_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = &(*ivec)[0]; + if (enc) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + c2l(iv, v1); + + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + v0 = ti[0]; + v1 = ti[1]; + + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + iv = &(*ivec)[0]; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + c2l(iv, v1); + + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + v0 = ti[0]; + v1 = ti[1]; + + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + iv = &(*ivec)[0]; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = c = cc = 0; + *num = n; +} + +/* This is compatible with the single key CFB-r for DES, even thought that's + * not what EVP needs. + */ + +void +DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc) +{ + DES_LONG d0, d1, v0, v1; + unsigned long l = length, n = ((unsigned int)numbits + 7)/8; + int num = numbits, i; + DES_LONG ti[2]; + unsigned char *iv; + unsigned char ovec[16]; + + if (num > 64) + return; + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + if (enc) { + while (l >= n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + c2ln(in, d0, d1, n); + in += n; + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + /* 30-08-94 - eay - changed because l>>32 and + * l<<32 are bad under gcc :-( */ + if (num == 32) { + v0 = v1; + v1 = d0; + } else if (num == 64) { + v0 = d0; + v1 = d1; + } else { + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); + /* shift ovec left most of the bits... */ + memmove(ovec, ovec + num/8, + 8 + (num % 8 ? 1 : 0)); + /* now the remaining bits */ + if (num % 8 != 0) { + for (i = 0; i < 8; ++i) { + ovec[i] <<= num % 8; + ovec[i] |= ovec[i + 1] >> + (8 - num % 8); + } + } + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); + } + } + } else { + while (l >= n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + c2ln(in, d0, d1, n); + in += n; + /* 30-08-94 - eay - changed because l>>32 and + * l<<32 are bad under gcc :-( */ + if (num == 32) { + v0 = v1; + v1 = d0; + } else if (num == 64) { + v0 = d0; + v1 = d1; + } else { + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); + /* shift ovec left most of the bits... */ + memmove(ovec, ovec + num/8, + 8 + (num % 8 ? 1 : 0)); + /* now the remaining bits */ + if (num % 8 != 0) { + for (i = 0; i < 8; ++i) { + ovec[i] <<= num % 8; + ovec[i] |= ovec[i + 1] >> + (8 - num % 8); + } + } + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); + } + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; +} diff --git a/Libraries/libressl/crypto/des/cfb64enc.c b/Libraries/libressl/crypto/des/cfb64enc.c new file mode 100644 index 000000000..d7434b9db --- /dev/null +++ b/Libraries/libressl/crypto/des/cfb64enc.c @@ -0,0 +1,122 @@ +/* $OpenBSD: cfb64enc.c,v 1.8 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +/* The input and output encrypted as though 64bit cfb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ + +void +DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc) +{ + DES_LONG v0, v1; + long l = length; + int n = *num; + DES_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = &(*ivec)[0]; + if (enc) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + DES_encrypt1(ti, schedule, DES_ENCRYPT); + iv = &(*ivec)[0]; + v0 = ti[0]; + l2c(v0, iv); + v0 = ti[1]; + l2c(v0, iv); + iv = &(*ivec)[0]; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + DES_encrypt1(ti, schedule, DES_ENCRYPT); + iv = &(*ivec)[0]; + v0 = ti[0]; + l2c(v0, iv); + v0 = ti[1]; + l2c(v0, iv); + iv = &(*ivec)[0]; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = c = cc = 0; + *num = n; +} diff --git a/Libraries/libressl/crypto/des/cfb_enc.c b/Libraries/libressl/crypto/des/cfb_enc.c new file mode 100644 index 000000000..dac86751d --- /dev/null +++ b/Libraries/libressl/crypto/des/cfb_enc.c @@ -0,0 +1,189 @@ +/* $OpenBSD: cfb_enc.c,v 1.16 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" +#include + +/* The input and output are loaded in multiples of 8 bits. + * What this means is that if you hame numbits=12 and length=2 + * the first 12 bits will be retrieved from the first byte and half + * the second. The second 12 bits will come from the 3rd and half the 4th + * byte. + */ +/* Until Aug 1 2003 this function did not correctly implement CFB-r, so it + * will not be compatible with any encryption prior to that date. Ben. */ +void +DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, DES_cblock *ivec, + int enc) +{ + DES_LONG d0, d1, v0, v1; + unsigned long l = length; + int num = numbits/8, n = (numbits + 7)/8, i, rem = numbits % 8; + DES_LONG ti[2]; + unsigned char *iv; +#if BYTE_ORDER != LITTLE_ENDIAN + unsigned char ovec[16]; +#else + unsigned int sh[4]; + unsigned char *ovec = (unsigned char *)sh; +#endif + + if (numbits <= 0 || numbits > 64) + return; + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + if (enc) { + while (l >= (unsigned long)n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + c2ln(in, d0, d1, n); + in += n; + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + /* 30-08-94 - eay - changed because l>>32 and + * l<<32 are bad under gcc :-( */ + if (numbits == 32) { + v0 = v1; + v1 = d0; + } else if (numbits == 64) { + v0 = d0; + v1 = d1; + } else { +#if BYTE_ORDER != LITTLE_ENDIAN + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); +#else + sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; +#endif + if (rem == 0) + memmove(ovec, ovec + num, 8); + else + for (i = 0; i < 8; ++i) + ovec[i] = ovec[i + num] << rem | + ovec[i + num + 1] >> (8 - + rem); +#if BYTE_ORDER == LITTLE_ENDIAN + v0 = sh[0], v1 = sh[1]; +#else + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); +#endif + } + } + } else { + while (l >= (unsigned long)n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + c2ln(in, d0, d1, n); + in += n; + /* 30-08-94 - eay - changed because l>>32 and + * l<<32 are bad under gcc :-( */ + if (numbits == 32) { + v0 = v1; + v1 = d0; + } else if (numbits == 64) { + v0 = d0; + v1 = d1; + } else { +#if BYTE_ORDER != LITTLE_ENDIAN + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); +#else + sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; +#endif + if (rem == 0) + memmove(ovec, ovec + num, 8); + else + for (i = 0; i < 8; ++i) + ovec[i] = ovec[i + num] << rem | + ovec[i + num + 1] >> (8 - + rem); +#if BYTE_ORDER == LITTLE_ENDIAN + v0 = sh[0], v1 = sh[1]; +#else + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); +#endif + } + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; +} diff --git a/Libraries/libressl/crypto/des/des_enc.c b/Libraries/libressl/crypto/des/des_enc.c new file mode 100644 index 000000000..7319639c8 --- /dev/null +++ b/Libraries/libressl/crypto/des/des_enc.c @@ -0,0 +1,392 @@ +/* $OpenBSD: des_enc.c,v 1.15 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" +#include "spr.h" + +#ifndef OPENBSD_DES_ASM + +void +DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) +{ + DES_LONG l, r, t, u; +#ifdef DES_PTR + const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif +#ifndef DES_UNROLL + int i; +#endif + DES_LONG *s; + + r = data[0]; + l = data[1]; + + IP(r, l); + /* Things have been modified so that the initial rotate is + * done outside the loop. This required the + * DES_SPtrans values in sp.h to be rotated 1 bit to the right. + * One perl script later and things have a 5% speed up on a sparc2. + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + * for pointing this out. */ + /* clear the top bits on machines with 8byte longs */ + /* shift left by 2 */ + r = ROTATE(r, 29) & 0xffffffffL; + l = ROTATE(l, 29) & 0xffffffffL; + + s = ks->ks->deslong; + /* I don't know if it is worth the effort of loop unrolling the + * inner loop */ + if (enc) { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#else + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#endif + } else { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 30); /* 16 */ + D_ENCRYPT(r, l, 28); /* 15 */ + D_ENCRYPT(l, r, 26); /* 14 */ + D_ENCRYPT(r, l, 24); /* 13 */ + D_ENCRYPT(l, r, 22); /* 12 */ + D_ENCRYPT(r, l, 20); /* 11 */ + D_ENCRYPT(l, r, 18); /* 10 */ + D_ENCRYPT(r, l, 16); /* 9 */ + D_ENCRYPT(l, r, 14); /* 8 */ + D_ENCRYPT(r, l, 12); /* 7 */ + D_ENCRYPT(l, r, 10); /* 6 */ + D_ENCRYPT(r, l, 8); /* 5 */ + D_ENCRYPT(l, r, 6); /* 4 */ + D_ENCRYPT(r, l, 4); /* 3 */ + D_ENCRYPT(l, r, 2); /* 2 */ + D_ENCRYPT(r, l, 0); /* 1 */ +#else + for (i = 30; i > 0; i -= 4) { + D_ENCRYPT(l, r, i - 0); /* 16 */ + D_ENCRYPT(r, l, i - 2); /* 15 */ + } +#endif + } + + /* rotate and clear the top bits on machines with 8byte longs */ + l = ROTATE(l, 3) & 0xffffffffL; + r = ROTATE(r, 3) & 0xffffffffL; + + FP(r, l); + data[0] = l; + data[1] = r; + l = r = t = u = 0; +} + +void +DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc) +{ + DES_LONG l, r, t, u; +#ifdef DES_PTR + const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif +#ifndef DES_UNROLL + int i; +#endif + DES_LONG *s; + + r = data[0]; + l = data[1]; + + /* Things have been modified so that the initial rotate is + * done outside the loop. This required the + * DES_SPtrans values in sp.h to be rotated 1 bit to the right. + * One perl script later and things have a 5% speed up on a sparc2. + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + * for pointing this out. */ + /* clear the top bits on machines with 8byte longs */ + r = ROTATE(r, 29) & 0xffffffffL; + l = ROTATE(l, 29) & 0xffffffffL; + + s = ks->ks->deslong; + /* I don't know if it is worth the effort of loop unrolling the + * inner loop */ + if (enc) { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#else + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#endif + } else { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 30); /* 16 */ + D_ENCRYPT(r, l, 28); /* 15 */ + D_ENCRYPT(l, r, 26); /* 14 */ + D_ENCRYPT(r, l, 24); /* 13 */ + D_ENCRYPT(l, r, 22); /* 12 */ + D_ENCRYPT(r, l, 20); /* 11 */ + D_ENCRYPT(l, r, 18); /* 10 */ + D_ENCRYPT(r, l, 16); /* 9 */ + D_ENCRYPT(l, r, 14); /* 8 */ + D_ENCRYPT(r, l, 12); /* 7 */ + D_ENCRYPT(l, r, 10); /* 6 */ + D_ENCRYPT(r, l, 8); /* 5 */ + D_ENCRYPT(l, r, 6); /* 4 */ + D_ENCRYPT(r, l, 4); /* 3 */ + D_ENCRYPT(l, r, 2); /* 2 */ + D_ENCRYPT(r, l, 0); /* 1 */ +#else + for (i = 30; i > 0; i -= 4) { + D_ENCRYPT(l, r, i - 0); /* 16 */ + D_ENCRYPT(r, l, i - 2); /* 15 */ + } +#endif + } + /* rotate and clear the top bits on machines with 8byte longs */ + data[0] = ROTATE(l, 3) & 0xffffffffL; + data[1] = ROTATE(r, 3) & 0xffffffffL; + l = r = t = u = 0; +} + +#endif /* OPENBSD_DES_ASM */ + +void +DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3) +{ + DES_LONG l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT); + DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT); + DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void +DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3) +{ + DES_LONG l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT); + DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT); + DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +#ifndef DES_DEFAULT_OPTIONS + +#undef CBC_ENC_C__DONT_UPDATE_IV +#include "ncbc_enc.c" /* DES_ncbc_encrypt */ + +void +DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc) +{ + DES_LONG tin0, tin1; + DES_LONG tout0, tout1, xor0, xor1; + const unsigned char *in; + unsigned char *out; + long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + in = input; + out = output; + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + DES_LONG t0, t1; + + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = t0; + xor1 = t1; + } + if (l != -8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = t0; + xor1 = t1; + } + + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +#endif /* DES_DEFAULT_OPTIONS */ diff --git a/Libraries/libressl/crypto/des/des_local.h b/Libraries/libressl/crypto/des/des_local.h new file mode 100644 index 000000000..f081adedb --- /dev/null +++ b/Libraries/libressl/crypto/des/des_local.h @@ -0,0 +1,398 @@ +/* $OpenBSD: des_local.h,v 1.2 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DES_LOCL_H +#define HEADER_DES_LOCL_H + +#include +#include +#include +#include +#include +#include + +#include + +#include + +__BEGIN_HIDDEN_DECLS + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + +/* used in des_read and des_write */ +#define MAXWRITE (1024*16) +#define BSIZE (MAXWRITE+4) + +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ + case 5: l2|=((DES_LONG)(*(--(c)))); \ + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ + case 1: l1|=((DES_LONG)(*(--(c)))); \ + } \ + } + +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* replacements for htonl and ntohl since I have no idea what to do + * when faced with machines with 8 byte longs. */ +#define HDRSIZE 4 + +#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))) + +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff);\ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff);\ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff);\ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff);\ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff);\ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff);\ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff);\ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff);\ + } \ + } + +static inline uint32_t +ROTATE(uint32_t a, uint32_t n) +{ + return (a >> n) + (a << (32 - n)); +} + +/* Don't worry about the LOAD_DATA() stuff, that is used by + * fcrypt() to add it's little bit to the front */ + +#ifdef DES_FCRYPT + +#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } + +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + t=R^(R>>16L); \ + u=t&E0; t&=E1; \ + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ + tmp=(t<<16); t^=R^s[S+1]; t^=tmp +#else +#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + u=R^s[S ]; \ + t=R^s[S+1] +#endif + +/* The changes to this macro may help or hinder, depending on the + * compiler and the architecture. gcc2 always seems to do well :-). + * Inspired by Dana How + * DO NOT use the alternative version on machines with 8 byte longs. + * It does not seem to work on the Alpha, even when DES_LONG is 4 + * bytes, probably an issue of accessing non-word aligned objects :-( */ +#ifdef DES_PTR + +/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there + * is no reason to not xor all the sub items together. This potentially + * saves a register since things can be xored directly into L */ + +#if defined(DES_RISC1) || defined(DES_RISC2) +#ifdef DES_RISC1 +#define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + u>>=16L; \ + LL^= *(const DES_LONG *)(des_SP +u1); \ + LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ + u3=(int)(u>>8L); \ + u1=(int)u&0xfc; \ + u3&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + t>>=16L; \ + LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ + u3=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u3&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x700+u3); } +#endif +#ifdef DES_RISC2 +#define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + LL^= *(const DES_LONG *)(des_SP +u1); \ + LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ + s1=(int)(u>>16L); \ + s2=(int)(u>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ + LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ + s1=(int)(t>>16L); \ + s2=(int)(t>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ + LL^= *(const DES_LONG *)(des_SP+0x700+s2); } +#endif +#else +#define D_ENCRYPT(LL,R,S) { \ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^= \ + *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } +#endif + +#else /* original version */ + +#if defined(DES_RISC1) || defined(DES_RISC2) +#ifdef DES_RISC1 +#define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + u>>=16L; \ + LL^=DES_SPtrans[0][u1]; \ + LL^=DES_SPtrans[2][u2]; \ + u3=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u3&=0x3f; \ + LL^=DES_SPtrans[4][u1]; \ + LL^=DES_SPtrans[6][u3]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + t>>=16L; \ + LL^=DES_SPtrans[1][u1]; \ + LL^=DES_SPtrans[3][u2]; \ + u3=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u3&=0x3f; \ + LL^=DES_SPtrans[5][u1]; \ + LL^=DES_SPtrans[7][u3]; } +#endif +#ifdef DES_RISC2 +#define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + LL^=DES_SPtrans[0][u1]; \ + LL^=DES_SPtrans[2][u2]; \ + s1=(int)u>>16L; \ + s2=(int)u>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=DES_SPtrans[4][s1]; \ + LL^=DES_SPtrans[6][s2]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + LL^=DES_SPtrans[1][u1]; \ + LL^=DES_SPtrans[3][u2]; \ + s1=(int)t>>16; \ + s2=(int)t>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=DES_SPtrans[5][s1]; \ + LL^=DES_SPtrans[7][s2]; } +#endif + +#else + +#define D_ENCRYPT(LL,R,S) { \ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^= \ + DES_SPtrans[0][(u>> 2L)&0x3f]^ \ + DES_SPtrans[2][(u>>10L)&0x3f]^ \ + DES_SPtrans[4][(u>>18L)&0x3f]^ \ + DES_SPtrans[6][(u>>26L)&0x3f]^ \ + DES_SPtrans[1][(t>> 2L)&0x3f]^ \ + DES_SPtrans[3][(t>>10L)&0x3f]^ \ + DES_SPtrans[5][(t>>18L)&0x3f]^ \ + DES_SPtrans[7][(t>>26L)&0x3f]; } +#endif +#endif + + /* IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + + The output has been subject to swaps of the form + 0 1 -> 3 1 but the odd and even bits have been put into + 2 3 2 0 + different words. The main trick is to remember that + t=((l>>size)^r)&(mask); + r^=t; + l^=(t<>(n))^(b))&(m)), \ + (b)^=(t), \ + (a)^=((t)<<(n))) + +#define IP(l,r) \ + { \ + DES_LONG tt; \ + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ + PERM_OP(l,r,tt,16,0x0000ffffL); \ + PERM_OP(r,l,tt, 2,0x33333333L); \ + PERM_OP(l,r,tt, 8,0x00ff00ffL); \ + PERM_OP(r,l,tt, 1,0x55555555L); \ + } + +#define FP(l,r) \ + { \ + DES_LONG tt; \ + PERM_OP(l,r,tt, 1,0x55555555L); \ + PERM_OP(r,l,tt, 8,0x00ff00ffL); \ + PERM_OP(l,r,tt, 2,0x33333333L); \ + PERM_OP(r,l,tt,16,0x0000ffffL); \ + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ + } + +extern const DES_LONG DES_SPtrans[8][64]; + +void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, + DES_LONG Eswap0, DES_LONG Eswap1); + +#ifdef OPENSSL_SMALL_FOOTPRINT +#undef DES_UNROLL +#endif + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/crypto/des/ecb3_enc.c b/Libraries/libressl/crypto/des/ecb3_enc.c new file mode 100644 index 000000000..129b5fafe --- /dev/null +++ b/Libraries/libressl/crypto/des/ecb3_enc.c @@ -0,0 +1,84 @@ +/* $OpenBSD: ecb3_enc.c,v 1.9 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +void +DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, + int enc) +{ + DES_LONG l0, l1; + DES_LONG ll[2]; + const unsigned char *in = &(*input)[0]; + unsigned char *out = &(*output)[0]; + + c2l(in, l0); + c2l(in, l1); + ll[0] = l0; + ll[1] = l1; + if (enc) + DES_encrypt3(ll, ks1, ks2, ks3); + else + DES_decrypt3(ll, ks1, ks2, ks3); + l0 = ll[0]; + l1 = ll[1]; + l2c(l0, out); + l2c(l1, out); +} diff --git a/Libraries/libressl/crypto/des/ecb_enc.c b/Libraries/libressl/crypto/des/ecb_enc.c new file mode 100644 index 000000000..3599fb812 --- /dev/null +++ b/Libraries/libressl/crypto/des/ecb_enc.c @@ -0,0 +1,82 @@ +/* $OpenBSD: ecb_enc.c,v 1.19 2023/07/31 05:04:06 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" +#include +#include + +void +DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc) +{ + DES_LONG l; + DES_LONG ll[2]; + const unsigned char *in = &(*input)[0]; + unsigned char *out = &(*output)[0]; + + c2l(in, l); + ll[0] = l; + c2l(in, l); + ll[1] = l; + DES_encrypt1(ll, ks, enc); + l = ll[0]; + l2c(l, out); + l = ll[1]; + l2c(l, out); + l = ll[0] = ll[1] = 0; +} diff --git a/Libraries/libressl/crypto/des/ede_cbcm_enc.c b/Libraries/libressl/crypto/des/ede_cbcm_enc.c new file mode 100644 index 000000000..eb6fd4f54 --- /dev/null +++ b/Libraries/libressl/crypto/des/ede_cbcm_enc.c @@ -0,0 +1,189 @@ +/* $OpenBSD: ede_cbcm_enc.c,v 1.9 2023/07/08 07:34:34 jsing Exp $ */ +/* Written by Ben Laurie for the OpenSSL + * project 13 Feb 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + +This is an implementation of Triple DES Cipher Block Chaining with Output +Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom). + +Note that there is a known attack on this by Biham and Knudsen but it takes +a lot of work: + +http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz + +*/ + +#include /* To see if OPENSSL_NO_DESCBCM is defined */ + +#ifndef OPENSSL_NO_DESCBCM +#include "des_local.h" + +void +DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2, + int enc) +{ + DES_LONG tin0, tin1; + DES_LONG tout0, tout1, xor0, xor1, m0, m1; + long l = length; + DES_LONG tin[2]; + unsigned char *iv1, *iv2; + + iv1 = &(*ivec1)[0]; + iv2 = &(*ivec2)[0]; + + if (enc) { + c2l(iv1, m0); + c2l(iv1, m1); + c2l(iv2, tout0); + c2l(iv2, tout1); + for (l -= 8; l >= -7; l -= 8) { + tin[0] = m0; + tin[1] = m1; + DES_encrypt1(tin, ks3, 1); + m0 = tin[0]; + m1 = tin[1]; + + if (l < 0) { + c2ln(in, tin0, tin1, l + 8); + } else { + c2l(in, tin0); + c2l(in, tin1); + } + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt1(tin, ks1, 1); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks2, 0); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks1, 1); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv1 = &(*ivec1)[0]; + l2c(m0, iv1); + l2c(m1, iv1); + + iv2 = &(*ivec2)[0]; + l2c(tout0, iv2); + l2c(tout1, iv2); + } else { + DES_LONG t0, t1; + + c2l(iv1, m0); + c2l(iv1, m1); + c2l(iv2, xor0); + c2l(iv2, xor1); + for (l -= 8; l >= -7; l -= 8) { + tin[0] = m0; + tin[1] = m1; + DES_encrypt1(tin, ks3, 1); + m0 = tin[0]; + m1 = tin[1]; + + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt1(tin, ks1, 0); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks2, 1); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks1, 0); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + if (l < 0) { + l2cn(tout0, tout1, out, l + 8); + } else { + l2c(tout0, out); + l2c(tout1, out); + } + xor0 = t0; + xor1 = t1; + } + + iv1 = &(*ivec1)[0]; + l2c(m0, iv1); + l2c(m1, iv1); + + iv2 = &(*ivec2)[0]; + l2c(xor0, iv2); + l2c(xor1, iv2); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +#endif diff --git a/Libraries/libressl/crypto/des/enc_read.c b/Libraries/libressl/crypto/des/enc_read.c new file mode 100644 index 000000000..8095f265c --- /dev/null +++ b/Libraries/libressl/crypto/des/enc_read.c @@ -0,0 +1,222 @@ +/* $OpenBSD: enc_read.c,v 1.17 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include "des_local.h" + +/* This has some uglies in it but it works - even over sockets. */ +/*extern int errno;*/ +int DES_rw_mode = DES_PCBC_MODE; + +/* + * WARNINGS: + * + * - The data format used by DES_enc_write() and DES_enc_read() + * has a cryptographic weakness: When asked to write more + * than MAXWRITE bytes, DES_enc_write will split the data + * into several chunks that are all encrypted + * using the same IV. So don't use these functions unless you + * are sure you know what you do (in which case you might + * not want to use them anyway). + * + * - This code cannot handle non-blocking sockets. + * + * - This function uses an internal state and thus cannot be + * used on multiple files. + */ + +int +DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv) +{ + /* data to be unencrypted */ + int net_num = 0; + static unsigned char *net = NULL; + /* extra unencrypted data + * for when a block of 100 comes in but is des_read one byte at + * a time. */ + static unsigned char *unnet = NULL; + static int unnet_start = 0; + static int unnet_left = 0; + static unsigned char *tmpbuf = NULL; + int i; + long num = 0, rnum; + unsigned char *p; + + if (tmpbuf == NULL) { + tmpbuf = malloc(BSIZE); + if (tmpbuf == NULL) + return (-1); + } + if (net == NULL) { + net = malloc(BSIZE); + if (net == NULL) + return (-1); + } + if (unnet == NULL) { + unnet = malloc(BSIZE); + if (unnet == NULL) + return (-1); + } + /* left over data from last decrypt */ + if (unnet_left != 0) { + if (unnet_left < len) { + /* we still still need more data but will return + * with the number of bytes we have - should always + * check the return value */ + memcpy(buf, &(unnet[unnet_start]), + unnet_left); + /* eay 26/08/92 I had the next 2 lines + * reversed :-( */ + i = unnet_left; + unnet_start = unnet_left = 0; + } else { + memcpy(buf, &(unnet[unnet_start]), len); + unnet_start += len; + unnet_left -= len; + i = len; + } + return (i); + } + + /* We need to get more data. */ + if (len > MAXWRITE) + len = MAXWRITE; + + /* first - get the length */ + while (net_num < HDRSIZE) { + i = read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); +#ifdef EINTR + if ((i == -1) && (errno == EINTR)) + continue; +#endif + if (i <= 0) + return (0); + net_num += i; + } + + /* we now have at net_num bytes in net */ + p = net; + /* num=0; */ + n2l(p, num); + /* num should be rounded up to the next group of eight + * we make sure that we have read a multiple of 8 bytes from the net. + */ + if ((num > MAXWRITE) || (num < 0)) /* error */ + return (-1); + rnum = (num < 8) ? 8 : ((num + 7)/8*8); + + net_num = 0; + while (net_num < rnum) { + i = read(fd, (void *)&(net[net_num]), rnum - net_num); +#ifdef EINTR + if ((i == -1) && (errno == EINTR)) + continue; +#endif + if (i <= 0) + return (0); + net_num += i; + } + + /* Check if there will be data left over. */ + if (len < num) { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, unnet, num, sched, iv, + DES_DECRYPT); + else + DES_cbc_encrypt(net, unnet, num, sched, iv, + DES_DECRYPT); + memcpy(buf, unnet, len); + unnet_start = len; + unnet_left = num - len; + + /* The following line is done because we return num + * as the number of bytes read. */ + num = len; + } else { + /* >output is a multiple of 8 byes, if len < rnum + * >we must be careful. The user must be aware that this + * >routine will write more bytes than he asked for. + * >The length of the buffer must be correct. + * FIXED - Should be ok now 18-9-90 - eay */ + if (len < rnum) { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, tmpbuf, num, sched, iv, + DES_DECRYPT); + else + DES_cbc_encrypt(net, tmpbuf, num, sched, iv, + DES_DECRYPT); + + /* eay 26/08/92 fix a bug that returned more + * bytes than you asked for (returned len bytes :-( */ + memcpy(buf, tmpbuf, num); + } else { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, buf, num, sched, iv, + DES_DECRYPT); + else + DES_cbc_encrypt(net, buf, num, sched, iv, + DES_DECRYPT); + } + } + return num; +} diff --git a/Libraries/libressl/crypto/des/enc_writ.c b/Libraries/libressl/crypto/des/enc_writ.c new file mode 100644 index 000000000..3def8a8d7 --- /dev/null +++ b/Libraries/libressl/crypto/des/enc_writ.c @@ -0,0 +1,167 @@ +/* $OpenBSD: enc_writ.c,v 1.17 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include "des_local.h" + +/* + * WARNINGS: + * + * - The data format used by DES_enc_write() and DES_enc_read() + * has a cryptographic weakness: When asked to write more + * than MAXWRITE bytes, DES_enc_write will split the data + * into several chunks that are all encrypted + * using the same IV. So don't use these functions unless you + * are sure you know what you do (in which case you might + * not want to use them anyway). + * + * - This code cannot handle non-blocking sockets. + */ + +int +DES_enc_write(int fd, const void *_buf, int len, + DES_key_schedule *sched, DES_cblock *iv) +{ +#ifdef _LIBC + extern unsigned long time(); + extern int write(); +#endif + const unsigned char *buf = _buf; + long rnum; + int i, j, k, outnum; + static unsigned char *outbuf = NULL; + unsigned char shortbuf[8]; + unsigned char *p; + const unsigned char *cp; + static int start = 1; + + if (outbuf == NULL) { + outbuf = malloc(BSIZE + HDRSIZE); + if (outbuf == NULL) + return (-1); + } + /* If we are sending less than 8 bytes, the same char will look + * the same if we don't pad it out with random bytes */ + if (start) { + start = 0; + } + + /* lets recurse if we want to send the data in small chunks */ + if (len > MAXWRITE) { + j = 0; + for (i = 0; i < len; i += k) { + k = DES_enc_write(fd, &(buf[i]), + ((len - i) > MAXWRITE) ? MAXWRITE : (len - i), + sched, iv); + if (k < 0) + return (k); + else + j += k; + } + return (j); + } + + /* write length first */ + p = outbuf; + l2n(len, p); + + /* pad short strings */ + if (len < 8) { + cp = shortbuf; + memcpy(shortbuf, buf, len); + arc4random_buf(shortbuf + len, 8 - len); + rnum = 8; + } else { + cp = buf; + rnum = ((len + 7)/8*8); /* round up to nearest eight */ + } + + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, + sched, iv, DES_ENCRYPT); + else + DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, + sched, iv, DES_ENCRYPT); + + /* output */ + outnum = rnum + HDRSIZE; + + for (j = 0; j < outnum; j += i) { + /* eay 26/08/92 I was not doing writing from where we + * got up to. */ + i = write(fd, (void *)&(outbuf[j]), outnum - j); + if (i == -1) { +#ifdef EINTR + if (errno == EINTR) + i = 0; + else +#endif + /* This is really a bad error - very bad + * It will stuff-up both ends. */ + return (-1); + } + } + + return (len); +} diff --git a/Libraries/libressl/crypto/des/fcrypt.c b/Libraries/libressl/crypto/des/fcrypt.c new file mode 100644 index 000000000..b183ceef1 --- /dev/null +++ b/Libraries/libressl/crypto/des/fcrypt.c @@ -0,0 +1,125 @@ +/* $OpenBSD: fcrypt.c,v 1.15 2023/07/08 07:34:34 jsing Exp $ */ + +#include + +/* This version of crypt has been developed from my MIT compatible + * DES library. + * Eric Young (eay@cryptsoft.com) + */ + +/* Modification by Jens Kupferschmidt (Cu) + * I have included directive PARA for shared memory computers. + * I have included a directive LONGCRYPT to using this routine to cipher + * passwords with more than 8 bytes like HP-UX 10.x it used. The MAXPLEN + * definition is the maximum of length of password and can changed. I have + * defined 24. + */ + +#include "des_local.h" + +/* Added more values to handle illegal salt values the way normal + * crypt() implementations do. The patch was sent by + * Bjorn Gronvall + */ +static unsigned const char con_salt[128] = { + 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, + 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, + 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, + 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, + 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, + 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, + 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, + 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, +}; + +static unsigned const char cov_2char[64] = { + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, + 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, + 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A +}; + +char * +DES_crypt(const char *buf, const char *salt) +{ + static char buff[14]; + + return (DES_fcrypt(buf, salt, buff)); +} + +char * +DES_fcrypt(const char *buf, const char *salt, char *ret) +{ + unsigned int i, j, x, y; + DES_LONG Eswap0, Eswap1; + DES_LONG out[2], ll; + DES_cblock key; + DES_key_schedule ks; + unsigned char bb[9]; + unsigned char *b = bb; + unsigned char c, u; + + /* eay 25/08/92 + * If you call crypt("pwd","*") as often happens when you + * have * as the pwd field in /etc/passwd, the function + * returns *\0xxxxxxxxx + * The \0 makes the string look like * so the pwd "*" would + * crypt to "*". This was found when replacing the crypt in + * our shared libraries. People found that the disabled + * accounts effectively had no passwd :-(. */ + x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]); + Eswap0 = con_salt[x] << 2; + x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]); + Eswap1 = con_salt[x] << 6; +/* EAY +r=strlen(buf); +r=(r+7)/8; +*/ + for (i = 0; i < 8; i++) { + c = *(buf++); + if (!c) + break; + key[i] = (c << 1); + } + for (; i < 8; i++) + key[i] = 0; + + DES_set_key_unchecked(&key, &ks); + fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1); + + ll = out[0]; + l2c(ll, b); + ll = out[1]; + l2c(ll, b); + y = 0; + u = 0x80; + bb[8] = 0; + for (i = 2; i < 13; i++) { + c = 0; + for (j = 0; j < 6; j++) { + c <<= 1; + if (bb[y] & u) + c |= 1; + u >>= 1; + if (!u) { + y++; + u = 0x80; + } + } + ret[i] = cov_2char[c]; + } + ret[13] = '\0'; + return (ret); +} diff --git a/Libraries/libressl/crypto/des/fcrypt_b.c b/Libraries/libressl/crypto/des/fcrypt_b.c new file mode 100644 index 000000000..58c9bc34c --- /dev/null +++ b/Libraries/libressl/crypto/des/fcrypt_b.c @@ -0,0 +1,145 @@ +/* $OpenBSD: fcrypt_b.c,v 1.12 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +/* This version of crypt has been developed from my MIT compatible + * DES library. + * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au + * Eric Young (eay@cryptsoft.com) + */ + +#define DES_FCRYPT +#include "des_local.h" +#undef DES_FCRYPT + +#ifndef OPENBSD_DES_ASM + +#undef PERM_OP +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)), \ + (b)^=(t), \ + (a)^=((t)<<(n))) + +#undef HPERM_OP +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)), \ + (a)=(a)^(t)^(t>>(16-(n)))) \ + +void +fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0, + DES_LONG Eswap1) +{ + DES_LONG l, r, t, u; +#ifdef DES_PTR + const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif + DES_LONG *s; + int j; + DES_LONG E0, E1; + + l = 0; + r = 0; + + s = (DES_LONG *)ks; + E0 = Eswap0; + E1 = Eswap1; + + for (j = 0; j < 25; j++) { +#ifndef DES_UNROLL + int i; + + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#else + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#endif + + t = l; + l = r; + r = t; + } + l = ROTATE(l, 3) & 0xffffffffL; + r = ROTATE(r, 3) & 0xffffffffL; + + PERM_OP(l, r, t, 1, 0x55555555L); + PERM_OP(r, l, t, 8, 0x00ff00ffL); + PERM_OP(l, r, t, 2, 0x33333333L); + PERM_OP(r, l, t, 16, 0x0000ffffL); + PERM_OP(l, r, t, 4, 0x0f0f0f0fL); + + out[0] = r; + out[1] = l; +} + +#endif /* OPENBSD_DES_ASM */ diff --git a/Libraries/libressl/crypto/des/ncbc_enc.c b/Libraries/libressl/crypto/des/ncbc_enc.c new file mode 100644 index 000000000..c4da94c48 --- /dev/null +++ b/Libraries/libressl/crypto/des/ncbc_enc.c @@ -0,0 +1,155 @@ +/* $OpenBSD: ncbc_enc.c,v 1.10 2023/07/08 07:34:34 jsing Exp $ */ +/* + * #included by: + * cbc_enc.c (DES_cbc_encrypt) + * des_enc.c (DES_ncbc_encrypt) + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +#ifdef CBC_ENC_C__DONT_UPDATE_IV +void +DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + DES_key_schedule *_schedule, DES_cblock *ivec, int enc) +#else +void +DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length, + DES_key_schedule *_schedule, DES_cblock *ivec, int enc) +#endif +{ + DES_LONG tin0, tin1; + DES_LONG tout0, tout1, xor0, xor1; + long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } +#ifndef CBC_ENC_C__DONT_UPDATE_IV + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); +#endif + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); +#ifndef CBC_ENC_C__DONT_UPDATE_IV + xor0 = tin0; + xor1 = tin1; +#endif + } +#ifndef CBC_ENC_C__DONT_UPDATE_IV + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); +#endif + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/Libraries/libressl/crypto/des/ofb64ede.c b/Libraries/libressl/crypto/des/ofb64ede.c new file mode 100644 index 000000000..2922fc77f --- /dev/null +++ b/Libraries/libressl/crypto/des/ofb64ede.c @@ -0,0 +1,112 @@ +/* $OpenBSD: ofb64ede.c,v 1.8 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +/* The input and output encrypted as though 64bit ofb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ +void +DES_ede3_ofb64_encrypt(const unsigned char *in, + unsigned char *out, long length, + DES_key_schedule *k1, DES_key_schedule *k2, + DES_key_schedule *k3, DES_cblock *ivec, + int *num) +{ + DES_LONG v0, v1; + int n = *num; + long l = length; + DES_cblock d; + char *dp; + DES_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + /* ti[0]=v0; */ + /* ti[1]=v1; */ + DES_encrypt3(ti, k1, k2, k3); + v0 = ti[0]; + v1 = ti[1]; + + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + } + v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/Libraries/libressl/crypto/des/ofb64enc.c b/Libraries/libressl/crypto/des/ofb64enc.c new file mode 100644 index 000000000..c3b1b8af8 --- /dev/null +++ b/Libraries/libressl/crypto/des/ofb64enc.c @@ -0,0 +1,109 @@ +/* $OpenBSD: ofb64enc.c,v 1.8 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +/* The input and output encrypted as though 64bit ofb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ +void +DES_ofb64_encrypt(const unsigned char *in, + unsigned char *out, long length, + DES_key_schedule *schedule, DES_cblock *ivec, int *num) +{ + DES_LONG v0, v1, t; + int n = *num; + long l = length; + DES_cblock d; + unsigned char *dp; + DES_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + DES_encrypt1(ti, schedule, DES_ENCRYPT); + dp = d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/Libraries/libressl/crypto/des/ofb_enc.c b/Libraries/libressl/crypto/des/ofb_enc.c new file mode 100644 index 000000000..990b927eb --- /dev/null +++ b/Libraries/libressl/crypto/des/ofb_enc.c @@ -0,0 +1,133 @@ +/* $OpenBSD: ofb_enc.c,v 1.8 2023/07/08 07:11:07 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +/* The input and output are loaded in multiples of 8 bits. + * What this means is that if you hame numbits=12 and length=2 + * the first 12 bits will be retrieved from the first byte and half + * the second. The second 12 bits will come from the 3rd and half the 4th + * byte. + */ +void +DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec) +{ + DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7)/8; + DES_LONG mask0, mask1; + long l = length; + int num = numbits; + DES_LONG ti[2]; + unsigned char *iv; + + if (num > 64) + return; + if (num > 32) { + mask0 = 0xffffffffL; + if (num >= 64) + mask1 = mask0; + else + mask1 = (1L << (num - 32)) - 1; + } else { + if (num == 32) + mask0 = 0xffffffffL; + else + mask0 = (1L << num) - 1; + mask1 = 0x00000000L; + } + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + while (l-- > 0) { + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + vv0 = ti[0]; + vv1 = ti[1]; + c2ln(in, d0, d1, n); + in += n; + d0 = (d0 ^ vv0) & mask0; + d1 = (d1 ^ vv1) & mask1; + l2cn(d0, d1, out, n); + out += n; + + if (num == 32) { + v0 = v1; + v1 = vv0; + } else if (num == 64) { + v0 = vv0; + v1 = vv1; + } else if (num > 32) { /* && num != 64 */ + v0 = ((v1 >> (num - 32))|(vv0 << (64 - num))) & + 0xffffffffL; + v1 = ((vv0 >> (num - 32))|(vv1 << (64 - num))) & + 0xffffffffL; + } else /* num < 32 */ { + v0 = ((v0 >> num)|(v1 << (32 - num))) & 0xffffffffL; + v1 = ((v1 >> num)|(vv0 << (32 - num))) & 0xffffffffL; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0; +} diff --git a/Libraries/libressl/crypto/des/pcbc_enc.c b/Libraries/libressl/crypto/des/pcbc_enc.c new file mode 100644 index 000000000..3a420f013 --- /dev/null +++ b/Libraries/libressl/crypto/des/pcbc_enc.c @@ -0,0 +1,116 @@ +/* $OpenBSD: pcbc_enc.c,v 1.9 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +void +DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc) +{ + DES_LONG sin0, sin1, xor0, xor1, tout0, tout1; + DES_LONG tin[2]; + const unsigned char *in; + unsigned char *out, *iv; + + in = input; + out = output; + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, xor0); + c2l(iv, xor1); + for (; length > 0; length -= 8) { + if (length >= 8) { + c2l(in, sin0); + c2l(in, sin1); + } else + c2ln(in, sin0, sin1, length); + tin[0] = sin0 ^ xor0; + tin[1] = sin1 ^ xor1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + tout1 = tin[1]; + xor0 = sin0 ^ tout0; + xor1 = sin1 ^ tout1; + l2c(tout0, out); + l2c(tout1, out); + } + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (; length > 0; length -= 8) { + c2l(in, sin0); + c2l(in, sin1); + tin[0] = sin0; + tin[1] = sin1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + if (length >= 8) { + l2c(tout0, out); + l2c(tout1, out); + } else + l2cn(tout0, tout1, out, length); + xor0 = tout0 ^ sin0; + xor1 = tout1 ^ sin1; + } + } + tin[0] = tin[1] = 0; + sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0; +} diff --git a/Libraries/libressl/crypto/des/qud_cksm.c b/Libraries/libressl/crypto/des/qud_cksm.c new file mode 100644 index 000000000..ab2866826 --- /dev/null +++ b/Libraries/libressl/crypto/des/qud_cksm.c @@ -0,0 +1,125 @@ +/* $OpenBSD: qud_cksm.c,v 1.10 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer + * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 + * This module in only based on the code in this paper and is + * almost definitely not the same as the MIT implementation. + */ +#include "des_local.h" + +/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */ +#define Q_B0(a) (((DES_LONG)(a))) +#define Q_B1(a) (((DES_LONG)(a))<<8) +#define Q_B2(a) (((DES_LONG)(a))<<16) +#define Q_B3(a) (((DES_LONG)(a))<<24) + +/* used to scramble things a bit */ +/* Got the value MIT uses via brute force :-) 2/10/90 eay */ +#define NOISE ((DES_LONG)83653421L) + +DES_LONG +DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed) +{ + DES_LONG z0, z1, t0, t1; + int i; + long l; + const unsigned char *cp; + DES_LONG *lp; + + if (out_count < 1) + out_count = 1; + lp = (DES_LONG *)&(output[0])[0]; + + z0 = Q_B0((*seed)[0])|Q_B1((*seed)[1])|Q_B2((*seed)[2])|Q_B3( + (*seed)[3]); + z1 = Q_B0((*seed)[4])|Q_B1((*seed)[5])|Q_B2((*seed)[6])|Q_B3( + (*seed)[7]); + + for (i = 0; ((i < 4) && (i < out_count)); i++) { + cp = input; + l = length; + while (l > 0) { + if (l > 1) { + t0 = (DES_LONG)(*(cp++)); + t0 |= (DES_LONG)Q_B1(*(cp++)); + l--; + } else + t0 = (DES_LONG)(*(cp++)); + l--; + /* add */ + t0 += z0; + t0 &= 0xffffffffL; + t1 = z1; + /* square, well sort of square */ + z0 = ((((t0*t0) & 0xffffffffL) + + ((t1*t1) & 0xffffffffL)) & 0xffffffffL) % + 0x7fffffffL; + z1 = ((t0*((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) % + 0x7fffffffL; + } + if (lp != NULL) { + /* The MIT library assumes that the checksum is + * composed of 2*out_count 32 bit ints */ + *lp++ = z0; + *lp++ = z1; + } + } + return (z0); +} diff --git a/Libraries/libressl/crypto/des/rand_key.c b/Libraries/libressl/crypto/des/rand_key.c new file mode 100644 index 000000000..aba899fe0 --- /dev/null +++ b/Libraries/libressl/crypto/des/rand_key.c @@ -0,0 +1,68 @@ +/* $OpenBSD: rand_key.c,v 1.9 2023/07/08 07:11:07 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +int +DES_random_key(DES_cblock *ret) +{ + do { + arc4random_buf(ret, sizeof(DES_cblock)); + DES_set_odd_parity(ret); + } while (DES_is_weak_key(ret)); + return (1); +} diff --git a/Libraries/libressl/crypto/des/set_key.c b/Libraries/libressl/crypto/des/set_key.c new file mode 100644 index 000000000..91116c4d1 --- /dev/null +++ b/Libraries/libressl/crypto/des/set_key.c @@ -0,0 +1,407 @@ +/* $OpenBSD: set_key.c,v 1.23 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* set_key.c v 1.4 eay 24/9/91 + * 1.4 Speed up by 400% :-) + * 1.3 added register declarations. + * 1.2 unrolled make_key_sched a bit more + * 1.1 added norm_expand_bits + * 1.0 First working version + */ +#include +#include "des_local.h" + +int DES_check_key = 0; /* defaults to false */ + +static const unsigned char odd_parity[256] = { + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, + 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, 110, + 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, 127, + 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, 143, + 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, 158, + 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, 174, + 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, 191, + 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, 206, + 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, 223, + 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, 239, + 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, 254, +}; + +void +DES_set_odd_parity(DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_KEY_SZ; i++) + (*key)[i] = odd_parity[(*key)[i]]; +} + +int +DES_check_key_parity(const_DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_KEY_SZ; i++) { + if ((*key)[i] != odd_parity[(*key)[i]]) + return (0); + } + return (1); +} + +/* Weak and semi weak keys as taken from + * %A D.W. Davies + * %A W.L. Price + * %T Security for Computer Networks + * %I John Wiley & Sons + * %D 1984 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference + * (and actual cblock values). + */ +#define NUM_WEAK_KEY 16 +static const DES_cblock weak_keys[NUM_WEAK_KEY] = { + /* weak keys */ + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, + /* semi-weak keys */ + {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, + {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, + {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, + {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, + {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, + {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, + {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, + {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, + {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, + {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1}, +}; + +int +DES_is_weak_key(const_DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < NUM_WEAK_KEY; i++) + if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0) + return 1; + return 0; +} + +/* NOW DEFINED IN des_local.h + * See ecb_encrypt.c for a pseudo description of these macros. + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + * (b)^=(t),\ + * (a)=((a)^((t)<<(n)))) + */ + +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)), \ + (a)=(a)^(t)^(t>>(16-(n)))) + +static const DES_LONG des_skb[8][64] = { + { + /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ + 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, + 0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L, + 0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L, + 0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L, + 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, + 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, + 0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L, + 0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L, + 0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L, + 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, + 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, + 0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L, + 0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L, + 0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L, + 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, + 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, + }, { + /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ + 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, + 0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L, + 0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L, + 0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L, + 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, + 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, + 0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L, + 0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L, + 0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L, + 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, + 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, + 0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L, + 0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L, + 0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L, + 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, + 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, + }, { + /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ + 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, + 0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L, + 0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L, + 0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L, + 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, + 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, + 0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L, + 0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L, + 0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L, + 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, + 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, + 0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L, + 0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L, + 0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L, + 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, + 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, + }, { + /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ + 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, + 0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L, + 0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L, + 0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L, + 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, + 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, + 0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L, + 0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L, + 0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L, + 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, + 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, + 0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L, + 0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L, + 0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L, + 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, + 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, + }, { + /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ + 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, + 0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L, + 0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L, + 0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L, + 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, + 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, + 0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L, + 0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L, + 0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L, + 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, + 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, + 0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L, + 0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L, + 0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L, + 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, + 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, + }, { + /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ + 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, + 0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L, + 0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L, + 0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L, + 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, + 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, + 0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L, + 0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L, + 0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L, + 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, + 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, + 0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L, + 0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L, + 0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L, + 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, + 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, + }, { + /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ + 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, + 0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L, + 0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L, + 0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L, + 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, + 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, + 0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L, + 0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L, + 0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L, + 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, + 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, + 0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L, + 0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L, + 0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L, + 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, + 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, + }, { + /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ + 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, + 0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L, + 0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L, + 0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L, + 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, + 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, + 0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L, + 0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L, + 0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L, + 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, + 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, + 0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L, + 0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L, + 0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L, + 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, + 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, + }, +}; + +int +DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule) +{ + if (DES_check_key) { + return DES_set_key_checked(key, schedule); + } else { + DES_set_key_unchecked(key, schedule); + return 0; + } +} + +/* return 0 if key parity is odd (correct), + * return -1 if key parity error, + * return -2 if illegal weak key. + */ +int +DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) +{ + if (!DES_check_key_parity(key)) + return (-1); + if (DES_is_weak_key(key)) + return (-2); + DES_set_key_unchecked(key, schedule); + return 0; +} + +void +DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) +{ + static const int shifts2[16] = {0, 0,1, 1,1, 1,1, 1,0, 1,1, 1,1, 1,1, 0}; + DES_LONG c, d, t, s, t2; + const unsigned char *in; + DES_LONG *k; + int i; + + k = &schedule->ks->deslong[0]; + in = &(*key)[0]; + + c2l(in, c); + c2l(in, d); + + /* do PC1 in 47 simple operations :-) + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + * for the inspiration. :-) */ + PERM_OP(d, c, t, 4, 0x0f0f0f0fL); + HPERM_OP(c, t, -2, 0xcccc0000L); + HPERM_OP(d, t, -2, 0xcccc0000L); + PERM_OP(d, c, t, 1, 0x55555555L); + PERM_OP(c, d, t, 8, 0x00ff00ffL); + PERM_OP(d, c, t, 1, 0x55555555L); + d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | + ((d & 0x00ff0000L) >> 16L)|((c & 0xf0000000L) >> 4L)); + c &= 0x0fffffffL; + + for (i = 0; i < ITERATIONS; i++) { + if (shifts2[i]) { + c = ((c >> 2L)|(c << 26L)); + d = ((d >> 2L)|(d << 26L)); + } else { + c = ((c >> 1L)|(c << 27L)); + d = ((d >> 1L)|(d << 27L)); + } + c &= 0x0fffffffL; + d &= 0x0fffffffL; + /* could be a few less shifts but I am to lazy at this + * point in time to investigate */ + s = des_skb[0][(c)&0x3f]| + des_skb[1][((c >> 6L) & 0x03)|((c >> 7L) & 0x3c)]| + des_skb[2][((c >> 13L) & 0x0f)|((c >> 14L) & 0x30)]| + des_skb[3][((c >> 20L) & 0x01)|((c >> 21L) & 0x06) | + ((c >> 22L) & 0x38)]; + t = des_skb[4][(d)&0x3f]| + des_skb[5][((d >> 7L) & 0x03)|((d >> 8L) & 0x3c)]| + des_skb[6][(d >> 15L) & 0x3f]| + des_skb[7][((d >> 21L) & 0x0f)|((d >> 22L) & 0x30)]; + + /* table contained 0213 4657 */ + t2 = ((t << 16L)|(s & 0x0000ffffL)) & 0xffffffffL; + *(k++) = ROTATE(t2, 30) & 0xffffffffL; + + t2 = ((s >> 16L)|(t & 0xffff0000L)); + *(k++) = ROTATE(t2, 26) & 0xffffffffL; + } +} + +int +DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule) +{ + return (DES_set_key(key, schedule)); +} +/* +#undef des_fixup_key_parity +void des_fixup_key_parity(des_cblock *key) + { + des_set_odd_parity(key); + } +*/ diff --git a/Libraries/libressl/crypto/des/spr.h b/Libraries/libressl/crypto/des/spr.h new file mode 100644 index 000000000..e0f413e46 --- /dev/null +++ b/Libraries/libressl/crypto/des/spr.h @@ -0,0 +1,209 @@ +/* $OpenBSD: spr.h,v 1.8 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +__BEGIN_HIDDEN_DECLS + +const DES_LONG DES_SPtrans[8][64] = { + { +/* nibble 0 */ + 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, + 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, + 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, + 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, + 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, + 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, + 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, + 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, + 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, + 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, + 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, + 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, + 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, + 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, + 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, + 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, + }, { +/* nibble 1 */ + 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, + 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, + 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, + 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, + 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, + 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, + 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, + 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, + 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, + 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, + 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, + 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, + 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, + 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, + 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, + 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, + }, { +/* nibble 2 */ + 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, + 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, + 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, + 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, + 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, + 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, + 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, + 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, + 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, + 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, + 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, + 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, + 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, + 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, + 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, + 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, + }, { +/* nibble 3 */ + 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, + 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, + 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, + 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, + 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, + 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, + 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, + 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, + 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, + 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, + 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, + 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, + 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, + 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, + 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, + 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, + }, { +/* nibble 4 */ + 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, + 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, + 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, + 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, + 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, + 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, + 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, + 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, + 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, + 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, + 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, + 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, + 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, + 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, + 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, + 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, + }, { +/* nibble 5 */ + 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, + 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, + 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, + 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, + 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, + 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, + 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, + 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, + 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, + 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, + 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, + 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, + 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, + 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, + 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, + 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, + }, { +/* nibble 6 */ + 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, + 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, + 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, + 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, + 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, + 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, + 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, + 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, + 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, + 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, + 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, + 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, + 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, + 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, + 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, + 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, + }, { +/* nibble 7 */ + 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, + 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, + 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, + 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, + 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, + 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, + 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, + 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, + 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, + 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, + 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, + 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, + 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, + 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, + }, +}; + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/des/str2key.c b/Libraries/libressl/crypto/des/str2key.c new file mode 100644 index 000000000..dd17a441b --- /dev/null +++ b/Libraries/libressl/crypto/des/str2key.c @@ -0,0 +1,166 @@ +/* $OpenBSD: str2key.c,v 1.13 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "des_local.h" + +void +DES_string_to_key(const char *str, DES_cblock *key) +{ + DES_key_schedule ks; + int i, length; + unsigned char j; + + memset(key, 0, 8); + length = strlen(str); +#ifdef OLD_STR_TO_KEY + for (i = 0; i < length; i++) + (*key)[i % 8] ^= (str[i] << 1); +#else /* MIT COMPATIBLE */ + for (i = 0; i < length; i++) { + j = str[i]; + if ((i % 16) < 8) + (*key)[i % 8] ^= (j << 1); + else { + /* Reverse the bit order 05/05/92 eay */ + j = ((j << 4) & 0xf0)|((j >> 4) & 0x0f); + j = ((j << 2) & 0xcc)|((j >> 2) & 0x33); + j = ((j << 1) & 0xaa)|((j >> 1) & 0x55); + (*key)[7 - (i % 8)] ^= j; + } + } +#endif + DES_set_odd_parity(key); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key)) + (*key)[7] ^= 0xF0; + DES_set_key(key, &ks); +#else + DES_set_key_unchecked(key, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key); + explicit_bzero(&ks, sizeof(ks)); + DES_set_odd_parity(key); +} + +void +DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2) +{ + DES_key_schedule ks; + int i, length; + unsigned char j; + + memset(key1, 0, 8); + memset(key2, 0, 8); + length = strlen(str); +#ifdef OLD_STR_TO_KEY + if (length <= 8) { + for (i = 0; i < length; i++) { + (*key2)[i] = (*key1)[i] = (str[i] << 1); + } + } else { + for (i = 0; i < length; i++) { + if ((i/8) & 1) + (*key2)[i % 8] ^= (str[i] << 1); + else + (*key1)[i % 8] ^= (str[i] << 1); + } + } +#else /* MIT COMPATIBLE */ + for (i = 0; i < length; i++) { + j = str[i]; + if ((i % 32) < 16) { + if ((i % 16) < 8) + (*key1)[i % 8] ^= (j << 1); + else + (*key2)[i % 8] ^= (j << 1); + } else { + j = ((j << 4) & 0xf0)|((j >> 4) & 0x0f); + j = ((j << 2) & 0xcc)|((j >> 2) & 0x33); + j = ((j << 1) & 0xaa)|((j >> 1) & 0x55); + if ((i % 16) < 8) + (*key1)[7 - (i % 8)] ^= j; + else + (*key2)[7 - (i % 8)] ^= j; + } + } + if (length <= 8) + memcpy(key2, key1, 8); +#endif + DES_set_odd_parity(key1); + DES_set_odd_parity(key2); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key1)) + (*key1)[7] ^= 0xF0; + DES_set_key(key1, &ks); +#else + DES_set_key_unchecked(key1, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key2)) + (*key2)[7] ^= 0xF0; + DES_set_key(key2, &ks); +#else + DES_set_key_unchecked(key2, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2); + explicit_bzero(&ks, sizeof(ks)); + DES_set_odd_parity(key1); + DES_set_odd_parity(key2); +} diff --git a/Libraries/libressl/crypto/des/xcbc_enc.c b/Libraries/libressl/crypto/des/xcbc_enc.c new file mode 100644 index 000000000..87f348a9a --- /dev/null +++ b/Libraries/libressl/crypto/des/xcbc_enc.c @@ -0,0 +1,153 @@ +/* $OpenBSD: xcbc_enc.c,v 1.12 2023/07/08 07:34:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_local.h" + +/* RSA's DESX */ + +void +DES_xcbc_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc) +{ + DES_LONG tin0, tin1; + DES_LONG tout0, tout1, xor0, xor1; + DES_LONG inW0, inW1, outW0, outW1; + const unsigned char *in2; + long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + in2 = &(*inw)[0]; + c2l(in2, inW0); + c2l(in2, inW1); + in2 = &(*outw)[0]; + c2l(in2, outW0); + c2l(in2, outW1); + + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0 ^ inW0; + tin[0] = tin0; + tin1 ^= tout1 ^ inW1; + tin[1] = tin1; + DES_encrypt1(tin, schedule, DES_ENCRYPT); + tout0 = tin[0] ^ outW0; + l2c(tout0, out); + tout1 = tin[1] ^ outW1; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0 ^ inW0; + tin[0] = tin0; + tin1 ^= tout1 ^ inW1; + tin[1] = tin1; + DES_encrypt1(tin, schedule, DES_ENCRYPT); + tout0 = tin[0] ^ outW0; + l2c(tout0, out); + tout1 = tin[1] ^ outW1; + l2c(tout1, out); + } + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l > 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0 ^ outW0; + c2l(in, tin1); + tin[1] = tin1 ^ outW1; + DES_encrypt1(tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0 ^ inW0; + tout1 = tin[1] ^ xor1 ^ inW1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0 ^ outW0; + c2l(in, tin1); + tin[1] = tin1 ^ outW1; + DES_encrypt1(tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0 ^ inW0; + tout1 = tin[1] ^ xor1 ^ inW1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + inW0 = inW1 = outW0 = outW1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/Libraries/libressl/crypto/dh/dh_ameth.c b/Libraries/libressl/crypto/dh/dh_ameth.c new file mode 100644 index 000000000..43beb469f --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_ameth.c @@ -0,0 +1,557 @@ +/* $OpenBSD: dh_ameth.c,v 1.39 2023/08/12 07:59:48 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "bn_local.h" +#include "dh_local.h" +#include "evp_local.h" + +static void +dh_free(EVP_PKEY *pkey) +{ + DH_free(pkey->pkey.dh); +} + +static int +dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + X509_ALGOR *algor; + int ptype; + const void *pval; + const ASN1_STRING *astr; + const unsigned char *key, *params, *p; + int key_len, params_len; + ASN1_INTEGER *aint = NULL; + DH *dh = NULL; + int ret = 0; + + if (!X509_PUBKEY_get0_param(NULL, &key, &key_len, &algor, pubkey)) + goto err; + X509_ALGOR_get0(NULL, &ptype, &pval, algor); + + if (ptype != V_ASN1_SEQUENCE) { + DHerror(DH_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + astr = pval; + params = astr->data; + params_len = astr->length; + + p = params; + if ((dh = d2i_DHparams(NULL, &p, params_len)) == NULL) { + DHerror(DH_R_DECODE_ERROR); + goto err; + } + p = key; + if ((aint = d2i_ASN1_INTEGER(NULL, &p, key_len)) == NULL) { + DHerror(DH_R_DECODE_ERROR); + goto err; + } + BN_free(dh->pub_key); + if ((dh->pub_key = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) { + DHerror(DH_R_BN_DECODE_ERROR); + goto err; + } + + if (!EVP_PKEY_assign_DH(pkey, dh)) + goto err; + dh = NULL; + + ret = 1; + + err: + ASN1_INTEGER_free(aint); + DH_free(dh); + + return ret; +} + +static int +dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + const DH *dh = pkey->pkey.dh; + ASN1_STRING *astr = NULL; + int ptype = V_ASN1_SEQUENCE; + ASN1_INTEGER *aint = NULL; + ASN1_OBJECT *aobj; + unsigned char *params = NULL, *key = NULL; + int params_len = 0, key_len = 0; + int ret = 0; + + if ((params_len = i2d_DHparams(dh, ¶ms)) <= 0) { + DHerror(ERR_R_MALLOC_FAILURE); + params_len = 0; + goto err; + } + if ((astr = ASN1_STRING_new()) == NULL) { + DHerror(ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_STRING_set0(astr, params, params_len); + params = NULL; + params_len = 0; + + if ((aint = BN_to_ASN1_INTEGER(dh->pub_key, NULL)) == NULL) + goto err; + if ((key_len = i2d_ASN1_INTEGER(aint, &key)) <= 0) { + DHerror(ERR_R_MALLOC_FAILURE); + key_len = 0; + goto err; + } + + if ((aobj = OBJ_nid2obj(EVP_PKEY_DH)) == NULL) + goto err; + if (!X509_PUBKEY_set0_param(pk, aobj, ptype, astr, key, key_len)) + goto err; + astr = NULL; + key = NULL; + key_len = 0; + + ret = 1; + + err: + ASN1_STRING_free(astr); + ASN1_INTEGER_free(aint); + freezero(params, params_len); + freezero(key, key_len); + + return ret; +} + +/* + * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in + * that the AlgorithmIdentifier contains the parameters, the private key + * is explcitly included and the pubkey must be recalculated. + */ + +static int +dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +{ + const X509_ALGOR *algor; + int ptype; + const void *pval; + const ASN1_STRING *astr; + const unsigned char *key, *params, *p; + int key_len, params_len; + ASN1_INTEGER *aint = NULL; + DH *dh = NULL; + int ret = 0; + + if (!PKCS8_pkey_get0(NULL, &key, &key_len, &algor, p8)) + goto err; + X509_ALGOR_get0(NULL, &ptype, &pval, algor); + + if (ptype != V_ASN1_SEQUENCE) { + DHerror(DH_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + astr = pval; + params = astr->data; + params_len = astr->length; + + p = params; + if ((dh = d2i_DHparams(NULL, &p, params_len)) == NULL) { + DHerror(DH_R_DECODE_ERROR); + goto err; + } + p = key; + if ((aint = d2i_ASN1_INTEGER(NULL, &p, key_len)) == NULL) { + DHerror(DH_R_DECODE_ERROR); + goto err; + } + BN_free(dh->priv_key); + if ((dh->priv_key = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) { + DHerror(DH_R_BN_DECODE_ERROR); + goto err; + } + if (!DH_generate_key(dh)) + goto err; + + if (!EVP_PKEY_assign_DH(pkey, dh)) + goto err; + dh = NULL; + + ret = 1; + + err: + ASN1_INTEGER_free(aint); + DH_free(dh); + + return ret; +} + +static int +dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + const DH *dh = pkey->pkey.dh; + ASN1_STRING *astr = NULL; + int ptype = V_ASN1_SEQUENCE; + ASN1_INTEGER *aint = NULL; + ASN1_OBJECT *aobj; + unsigned char *params = NULL, *key = NULL; + int params_len = 0, key_len = 0; + int ret = 0; + + if ((params_len = i2d_DHparams(dh, ¶ms)) <= 0) { + DHerror(ERR_R_MALLOC_FAILURE); + params_len = 0; + goto err; + } + if ((astr = ASN1_STRING_type_new(V_ASN1_SEQUENCE)) == NULL) { + DHerror(ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_STRING_set0(astr, params, params_len); + params = NULL; + params_len = 0; + + if ((aint = BN_to_ASN1_INTEGER(dh->priv_key, NULL)) == NULL) { + DHerror(DH_R_BN_ERROR); + goto err; + } + if ((key_len = i2d_ASN1_INTEGER(aint, &key)) <= 0) { + DHerror(ERR_R_MALLOC_FAILURE); + key_len = 0; + goto err; + } + + if ((aobj = OBJ_nid2obj(NID_dhKeyAgreement)) == NULL) + goto err; + if (!PKCS8_pkey_set0(p8, aobj, 0, ptype, astr, key, key_len)) + goto err; + astr = NULL; + key = NULL; + key_len = 0; + + ret = 1; + + err: + ASN1_STRING_free(astr); + ASN1_INTEGER_free(aint); + freezero(params, params_len); + freezero(key, key_len); + + return ret; +} + +static int +dh_param_decode(EVP_PKEY *pkey, const unsigned char **params, int params_len) +{ + DH *dh = NULL; + int ret = 0; + + if ((dh = d2i_DHparams(NULL, params, params_len)) == NULL) { + DHerror(ERR_R_DH_LIB); + goto err; + } + if (!EVP_PKEY_assign_DH(pkey, dh)) + goto err; + dh = NULL; + + ret = 1; + + err: + DH_free(dh); + + return ret; +} + +static int +dh_param_encode(const EVP_PKEY *pkey, unsigned char **params) +{ + return i2d_DHparams(pkey->pkey.dh, params); +} + +static int +do_dh_print(BIO *bp, const DH *x, int indent, ASN1_PCTX *ctx, int ptype) +{ + int reason = ERR_R_BUF_LIB, ret = 0; + const char *ktype = NULL; + BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + if (ptype == 2) + ktype = "PKCS#3 DH Private-Key"; + else if (ptype == 1) + ktype = "PKCS#3 DH Public-Key"; + else + ktype = "PKCS#3 DH Parameters"; + + if (x->p == NULL) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) + goto err; + indent += 4; + + if (!bn_printf(bp, priv_key, indent, "private-key:")) + goto err; + if (!bn_printf(bp, pub_key, indent, "public-key:")) + goto err; + + if (!bn_printf(bp, x->p, indent, "prime:")) + goto err; + if (!bn_printf(bp, x->g, indent, "generator:")) + goto err; + if (x->length != 0) { + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_printf(bp, "recommended-private-length: %d bits\n", + (int)x->length) <= 0) + goto err; + } + + ret = 1; + if (0) { + err: + DHerror(reason); + } + return(ret); +} + +static int +dh_size(const EVP_PKEY *pkey) +{ + return DH_size(pkey->pkey.dh); +} + +static int +dh_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.dh->p); +} + +static int +dh_security_bits(const EVP_PKEY *pkey) +{ + return DH_security_bits(pkey->pkey.dh); +} + +static int +dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) || + BN_cmp(a->pkey.dh->g, b->pkey.dh->g)) + return 0; + else + return 1; +} + +static int +dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + BIGNUM *a; + + if ((a = BN_dup(from->pkey.dh->p)) == NULL) + return 0; + BN_free(to->pkey.dh->p); + to->pkey.dh->p = a; + + if ((a = BN_dup(from->pkey.dh->g)) == NULL) + return 0; + BN_free(to->pkey.dh->g); + to->pkey.dh->g = a; + + return 1; +} + +static int +dh_missing_parameters(const EVP_PKEY *pkey) +{ + const DH *dh = pkey->pkey.dh; + + return dh->p == NULL || dh->g == NULL; +} + +static int +dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (dh_cmp_parameters(a, b) == 0) + return 0; + if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0) + return 0; + else + return 1; +} + +static int +dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); +} + +static int +dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); +} + +static int +dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); +} + +int +DHparams_print(BIO *bp, const DH *x) +{ + return do_dh_print(bp, x, 4, NULL, 0); +} +LCRYPTO_ALIAS(DHparams_print); + +int +DHparams_print_fp(FILE *fp, const DH *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DHerror(ERR_R_BUF_LIB); + return 0; + } + + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DHparams_print(b, x); + BIO_free(b); + + return ret; +} +LCRYPTO_ALIAS(DHparams_print_fp); + +static int +dh_pkey_public_check(const EVP_PKEY *pkey) +{ + DH *dh = pkey->pkey.dh; + + if (dh->pub_key == NULL) { + DHerror(DH_R_MISSING_PUBKEY); + return 0; + } + + return DH_check_pub_key_ex(dh, dh->pub_key); +} + +static int +dh_pkey_param_check(const EVP_PKEY *pkey) +{ + DH *dh = pkey->pkey.dh; + + /* + * It would have made more sense to support EVP_PKEY_check() for DH + * keys and call DH_check_ex() there and keeping this as a wrapper + * for DH_param_check_ex(). We follow OpenSSL's choice. + */ + return DH_check_ex(dh); +} + +const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { + .pkey_id = EVP_PKEY_DH, + .pkey_base_id = EVP_PKEY_DH, + + .pem_str = "DH", + .info = "OpenSSL PKCS#3 DH method", + + .pub_decode = dh_pub_decode, + .pub_encode = dh_pub_encode, + .pub_cmp = dh_pub_cmp, + .pub_print = dh_public_print, + + .priv_decode = dh_priv_decode, + .priv_encode = dh_priv_encode, + .priv_print = dh_private_print, + + .pkey_size = dh_size, + .pkey_bits = dh_bits, + .pkey_security_bits = dh_security_bits, + + .param_decode = dh_param_decode, + .param_encode = dh_param_encode, + .param_missing = dh_missing_parameters, + .param_copy = dh_copy_parameters, + .param_cmp = dh_cmp_parameters, + .param_print = dh_param_print, + + .pkey_free = dh_free, + + .pkey_check = NULL, + .pkey_public_check = dh_pkey_public_check, + .pkey_param_check = dh_pkey_param_check, +}; diff --git a/Libraries/libressl/crypto/dh/dh_asn1.c b/Libraries/libressl/crypto/dh/dh_asn1.c new file mode 100644 index 000000000..2e0b054d3 --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_asn1.c @@ -0,0 +1,176 @@ +/* $OpenBSD: dh_asn1.c,v 1.12 2023/07/08 15:29:03 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "dh_local.h" + +/* Override the default free and new methods */ +static int +dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)DH_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + DH_free((DH *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +static const ASN1_AUX DHparams_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = dh_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DHparams_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(DH, p), + .field_name = "p", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DH, g), + .field_name = "g", + .item = &BIGNUM_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(DH, length), + .field_name = "length", + .item = &ZLONG_it, + }, +}; + +const ASN1_ITEM DHparams_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DHparams_seq_tt, + .tcount = sizeof(DHparams_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DHparams_aux, + .size = sizeof(DH), + .sname = "DH", +}; + + +DH * +d2i_DHparams(DH **a, const unsigned char **in, long len) +{ + return (DH *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DHparams_it); +} +LCRYPTO_ALIAS(d2i_DHparams); + +int +i2d_DHparams(const DH *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DHparams_it); +} +LCRYPTO_ALIAS(i2d_DHparams); + +DH * +d2i_DHparams_bio(BIO *bp, DH **a) +{ + return ASN1_item_d2i_bio(&DHparams_it, bp, a); +} +LCRYPTO_ALIAS(d2i_DHparams_bio); + +int +i2d_DHparams_bio(BIO *bp, DH *a) +{ + return ASN1_item_i2d_bio(&DHparams_it, bp, a); +} +LCRYPTO_ALIAS(i2d_DHparams_bio); + +DH * +d2i_DHparams_fp(FILE *fp, DH **a) +{ + return ASN1_item_d2i_fp(&DHparams_it, fp, a); +} +LCRYPTO_ALIAS(d2i_DHparams_fp); + +int +i2d_DHparams_fp(FILE *fp, DH *a) +{ + return ASN1_item_i2d_fp(&DHparams_it, fp, a); +} +LCRYPTO_ALIAS(i2d_DHparams_fp); + +DH * +DHparams_dup(DH *dh) +{ + return ASN1_item_dup(&DHparams_it, dh); +} +LCRYPTO_ALIAS(DHparams_dup); diff --git a/Libraries/libressl/crypto/dh/dh_check.c b/Libraries/libressl/crypto/dh/dh_check.c new file mode 100644 index 000000000..be79c2a04 --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_check.c @@ -0,0 +1,303 @@ +/* $OpenBSD: dh_check.c,v 1.28 2023/07/24 16:25:02 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "bn_local.h" +#include "dh_local.h" + +#define DH_NUMBER_ITERATIONS_FOR_PRIME 64 + +/* + * Check that p is odd and 1 < g < p - 1. The _ex version removes the need of + * inspecting flags and pushes errors on the stack instead. + */ + +int +DH_check_params_ex(const DH *dh) +{ + int flags = 0; + + if (!DH_check_params(dh, &flags)) + return 0; + + if ((flags & DH_CHECK_P_NOT_PRIME) != 0) + DHerror(DH_R_CHECK_P_NOT_PRIME); + if ((flags & DH_NOT_SUITABLE_GENERATOR) != 0) + DHerror(DH_R_NOT_SUITABLE_GENERATOR); + + return flags == 0; +} + +int +DH_check_params(const DH *dh, int *flags) +{ + BIGNUM *max_g = NULL; + int ok = 0; + + *flags = 0; + + if (!BN_is_odd(dh->p)) + *flags |= DH_CHECK_P_NOT_PRIME; + + /* + * Check that 1 < dh->g < p - 1 + */ + + if (BN_cmp(dh->g, BN_value_one()) <= 0) + *flags |= DH_NOT_SUITABLE_GENERATOR; + /* max_g = p - 1 */ + if ((max_g = BN_dup(dh->p)) == NULL) + goto err; + if (!BN_sub_word(max_g, 1)) + goto err; + /* check that g < max_g */ + if (BN_cmp(dh->g, max_g) >= 0) + *flags |= DH_NOT_SUITABLE_GENERATOR; + + ok = 1; + + err: + BN_free(max_g); + + return ok; +} + +/* + * Check that p is a safe prime and that g is a suitable generator. + * The _ex version puts errors on the stack instead of returning flags. + */ + +int +DH_check_ex(const DH *dh) +{ + int flags = 0; + + if (!DH_check(dh, &flags)) + return 0; + + if ((flags & DH_NOT_SUITABLE_GENERATOR) != 0) + DHerror(DH_R_NOT_SUITABLE_GENERATOR); + if ((flags & DH_CHECK_Q_NOT_PRIME) != 0) + DHerror(DH_R_CHECK_Q_NOT_PRIME); + if ((flags & DH_CHECK_INVALID_Q_VALUE) != 0) + DHerror(DH_R_CHECK_INVALID_Q_VALUE); + if ((flags & DH_CHECK_INVALID_J_VALUE) != 0) + DHerror(DH_R_CHECK_INVALID_J_VALUE); + if ((flags & DH_UNABLE_TO_CHECK_GENERATOR) != 0) + DHerror(DH_R_UNABLE_TO_CHECK_GENERATOR); + if ((flags & DH_CHECK_P_NOT_PRIME) != 0) + DHerror(DH_R_CHECK_P_NOT_PRIME); + if ((flags & DH_CHECK_P_NOT_SAFE_PRIME) != 0) + DHerror(DH_R_CHECK_P_NOT_SAFE_PRIME); + + return flags == 0; +} + +int +DH_check(const DH *dh, int *flags) +{ + BN_CTX *ctx = NULL; + int is_prime; + int ok = 0; + + *flags = 0; + + if (!DH_check_params(dh, flags)) + goto err; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + + if (dh->q != NULL) { + BIGNUM *quotient, *residue; + + if ((quotient = BN_CTX_get(ctx)) == NULL) + goto err; + if ((residue = BN_CTX_get(ctx)) == NULL) + goto err; + if ((*flags & DH_NOT_SUITABLE_GENERATOR) == 0) { + /* Check g^q == 1 mod p */ + if (!BN_mod_exp_ct(residue, dh->g, dh->q, dh->p, ctx)) + goto err; + if (!BN_is_one(residue)) + *flags |= DH_NOT_SUITABLE_GENERATOR; + } + is_prime = BN_is_prime_ex(dh->q, DH_NUMBER_ITERATIONS_FOR_PRIME, + ctx, NULL); + if (is_prime < 0) + goto err; + if (is_prime == 0) + *flags |= DH_CHECK_Q_NOT_PRIME; + /* Check p == 1 mod q, i.e., q divides p - 1 */ + if (!BN_div_ct(quotient, residue, dh->p, dh->q, ctx)) + goto err; + if (!BN_is_one(residue)) + *flags |= DH_CHECK_INVALID_Q_VALUE; + if (dh->j != NULL && BN_cmp(dh->j, quotient) != 0) + *flags |= DH_CHECK_INVALID_J_VALUE; + } + + is_prime = BN_is_prime_ex(dh->p, DH_NUMBER_ITERATIONS_FOR_PRIME, + ctx, NULL); + if (is_prime < 0) + goto err; + if (is_prime == 0) + *flags |= DH_CHECK_P_NOT_PRIME; + else if (dh->q == NULL) { + BIGNUM *q; + + if ((q = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_rshift1(q, dh->p)) + goto err; + is_prime = BN_is_prime_ex(q, DH_NUMBER_ITERATIONS_FOR_PRIME, + ctx, NULL); + if (is_prime < 0) + goto err; + if (is_prime == 0) + *flags |= DH_CHECK_P_NOT_SAFE_PRIME; + } + + ok = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; +} +LCRYPTO_ALIAS(DH_check); + +int +DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) +{ + int flags = 0; + + if (!DH_check_pub_key(dh, pub_key, &flags)) + return 0; + + if ((flags & DH_CHECK_PUBKEY_TOO_SMALL) != 0) + DHerror(DH_R_CHECK_PUBKEY_TOO_SMALL); + if ((flags & DH_CHECK_PUBKEY_TOO_LARGE) != 0) + DHerror(DH_R_CHECK_PUBKEY_TOO_LARGE); + if ((flags & DH_CHECK_PUBKEY_INVALID) != 0) + DHerror(DH_R_CHECK_PUBKEY_INVALID); + + return flags == 0; +} + +int +DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *flags) +{ + BN_CTX *ctx = NULL; + BIGNUM *max_pub_key; + int ok = 0; + + *flags = 0; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + if ((max_pub_key = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Check that 1 < pub_key < dh->p - 1 + */ + + if (BN_cmp(pub_key, BN_value_one()) <= 0) + *flags |= DH_CHECK_PUBKEY_TOO_SMALL; + + /* max_pub_key = dh->p - 1 */ + if (!BN_sub(max_pub_key, dh->p, BN_value_one())) + goto err; + + if (BN_cmp(pub_key, max_pub_key) >= 0) + *flags |= DH_CHECK_PUBKEY_TOO_LARGE; + + /* + * If dh->q is set, check that pub_key^q == 1 mod p + */ + + if (dh->q != NULL) { + BIGNUM *residue; + + if ((residue = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_mod_exp_ct(residue, pub_key, dh->q, dh->p, ctx)) + goto err; + if (!BN_is_one(residue)) + *flags |= DH_CHECK_PUBKEY_INVALID; + } + + ok = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ok; +} +LCRYPTO_ALIAS(DH_check_pub_key); diff --git a/Libraries/libressl/crypto/dh/dh_err.c b/Libraries/libressl/crypto/dh/dh_err.c new file mode 100644 index 000000000..f5dda2898 --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_err.c @@ -0,0 +1,114 @@ +/* $OpenBSD: dh_err.c,v 1.19 2023/07/08 15:29:03 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason) + +static ERR_STRING_DATA DH_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA DH_str_reasons[]= + { +{ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"}, +{ERR_REASON(DH_R_BN_DECODE_ERROR) ,"bn decode error"}, +{ERR_REASON(DH_R_BN_ERROR) ,"bn error"}, +{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"}, +{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, +{ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"}, +{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, +{ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"}, +{ERR_REASON(DH_R_NON_FIPS_METHOD) ,"non fips method"}, +{ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"}, +{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"}, +{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"}, +{ERR_REASON(DH_R_CHECK_INVALID_J_VALUE) ,"check invalid j value"}, +{ERR_REASON(DH_R_CHECK_INVALID_Q_VALUE) ,"check invalid q value"}, +{ERR_REASON(DH_R_CHECK_PUBKEY_INVALID) ,"check pubkey invalid"}, +{ERR_REASON(DH_R_CHECK_PUBKEY_TOO_LARGE) ,"check pubkey too large"}, +{ERR_REASON(DH_R_CHECK_PUBKEY_TOO_SMALL) ,"check pubkey too small"}, +{ERR_REASON(DH_R_CHECK_P_NOT_PRIME) ,"check p not prime"}, +{ERR_REASON(DH_R_CHECK_P_NOT_SAFE_PRIME) ,"check p not safe prime"}, +{ERR_REASON(DH_R_CHECK_Q_NOT_PRIME) ,"check q not prime"}, +{ERR_REASON(DH_R_MISSING_PUBKEY) ,"missing pubkey"}, +{ERR_REASON(DH_R_NOT_SUITABLE_GENERATOR) ,"not suitable generator"}, +{ERR_REASON(DH_R_UNABLE_TO_CHECK_GENERATOR),"unable to check generator"}, +{0,NULL} + }; + +#endif + +void ERR_load_DH_strings(void) + { +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DH_str_functs[0].error) == NULL) + { + ERR_load_strings(0,DH_str_functs); + ERR_load_strings(0,DH_str_reasons); + } +#endif + } +LCRYPTO_ALIAS(ERR_load_DH_strings); diff --git a/Libraries/libressl/crypto/dh/dh_gen.c b/Libraries/libressl/crypto/dh/dh_gen.c new file mode 100644 index 000000000..3ffa5d80f --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_gen.c @@ -0,0 +1,197 @@ +/* $OpenBSD: dh_gen.c,v 1.21 2023/07/08 15:29:03 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "bn_local.h" +#include "dh_local.h" + +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + BN_GENCB *cb); + +int +DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) +{ + if (ret->meth->generate_params) + return ret->meth->generate_params(ret, prime_len, generator, cb); + return dh_builtin_genparams(ret, prime_len, generator, cb); +} +LCRYPTO_ALIAS(DH_generate_parameters_ex); + +/* + * We generate DH parameters as follows: + * find a prime q which is prime_len/2 bits long. + * p=(2*q)+1 or (p-1)/2 = q + * For this case, g is a generator if + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + * Since the factors of p-1 are q and 2, we just need to check + * g^2 mod p != 1 and g^q mod p != 1. + * + * Having said all that, + * there is another special case method for the generators 2, 3 and 5. + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 <<<<< does not work for safe primes. + * for 5, p mod 10 == 3 or 7 + * + * Thanks to Phil Karn for the pointers about the + * special generators and for answering some of my questions. + * + * I've implemented the second simple method :-). + * Since DH should be using a safe prime (both p and q are prime), + * this generator function can take a very very long time to run. + */ +/* Actually there is no reason to insist that 'generator' be a generator. + * It's just as OK (and in some sense better) to use a generator of the + * order-q subgroup. + */ +static int +dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) +{ + BIGNUM *t1, *t2; + int g, ok = -1; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + if ((t1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((t2 = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Make sure 'ret' has the necessary elements */ + if (!ret->p && ((ret->p = BN_new()) == NULL)) + goto err; + if (!ret->g && ((ret->g = BN_new()) == NULL)) + goto err; + + if (generator <= 1) { + DHerror(DH_R_BAD_GENERATOR); + goto err; + } + if (generator == DH_GENERATOR_2) { + if (!BN_set_word(t1, 24)) + goto err; + if (!BN_set_word(t2, 11)) + goto err; + g = 2; + } else if (generator == DH_GENERATOR_5) { + if (!BN_set_word(t1, 10)) + goto err; + if (!BN_set_word(t2, 3)) + goto err; + /* BN_set_word(t3,7); just have to miss + * out on these ones :-( */ + g = 5; + } else { + /* + * in the general case, don't worry if 'generator' is a + * generator or not: since we are using safe primes, + * it will generate either an order-q or an order-2q group, + * which both is OK + */ + if (!BN_set_word(t1, 2)) + goto err; + if (!BN_set_word(t2, 1)) + goto err; + g = generator; + } + + if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + if (!BN_set_word(ret->g, g)) + goto err; + ok = 1; +err: + if (ok == -1) { + DHerror(ERR_R_BN_LIB); + ok = 0; + } + + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +DH * +DH_generate_parameters(int prime_len, int generator, + void (*callback)(int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + DH *ret = NULL; + + if ((ret = DH_new()) == NULL) + return NULL; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DH_generate_parameters_ex(ret, prime_len, generator, &cb)) + return ret; + DH_free(ret); + return NULL; +} +LCRYPTO_ALIAS(DH_generate_parameters); diff --git a/Libraries/libressl/crypto/dh/dh_key.c b/Libraries/libressl/crypto/dh/dh_key.c new file mode 100644 index 000000000..050d1143f --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_key.c @@ -0,0 +1,247 @@ +/* $OpenBSD: dh_key.c,v 1.40 2023/08/03 18:53:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "bn_local.h" +#include "dh_local.h" + +static int generate_key(DH *dh); +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int dh_init(DH *dh); +static int dh_finish(DH *dh); + +int +DH_generate_key(DH *dh) +{ + return dh->meth->generate_key(dh); +} +LCRYPTO_ALIAS(DH_generate_key); + +int +DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + return dh->meth->compute_key(key, pub_key, dh); +} +LCRYPTO_ALIAS(DH_compute_key); + +static DH_METHOD dh_ossl = { + .name = "OpenSSL DH Method", + .generate_key = generate_key, + .compute_key = compute_key, + .bn_mod_exp = dh_bn_mod_exp, + .init = dh_init, + .finish = dh_finish, +}; + +const DH_METHOD * +DH_OpenSSL(void) +{ + return &dh_ossl; +} +LCRYPTO_ALIAS(DH_OpenSSL); + +static int +generate_key(DH *dh) +{ + int ok = 0; + unsigned l; + BN_CTX *ctx; + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerror(DH_R_MODULUS_TOO_LARGE); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if ((priv_key = dh->priv_key) == NULL) { + if ((priv_key = BN_new()) == NULL) + goto err; + } + + if ((pub_key = dh->pub_key) == NULL) { + if ((pub_key = BN_new()) == NULL) + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if (!mont) + goto err; + } + + if (dh->priv_key == NULL) { + if (dh->q) { + if (!bn_rand_interval(priv_key, 2, dh->q)) + goto err; + } else { + /* secret exponent length */ + l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; + if (!BN_rand(priv_key, l, 0, 0)) + goto err; + } + } + + if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, priv_key, dh->p, ctx, + mont)) + goto err; + + dh->pub_key = pub_key; + dh->priv_key = priv_key; + ok = 1; + err: + if (ok != 1) + DHerror(ERR_R_BN_LIB); + + if (dh->pub_key == NULL) + BN_free(pub_key); + if (dh->priv_key == NULL) + BN_free(priv_key); + BN_CTX_free(ctx); + + return ok; +} + +static int +compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *tmp; + int ret = -1; + int check_result; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerror(DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + if (dh->priv_key == NULL) { + DHerror(DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); + + if (!mont) + goto err; + } + + if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { + DHerror(DH_R_INVALID_PUBKEY); + goto err; + } + + if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, + mont)) { + DHerror(ERR_R_BN_LIB); + goto err; + } + + ret = BN_bn2bin(tmp, key); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ret; +} + +static int +dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return BN_mod_exp_mont_ct(r, a, p, m, ctx, m_ctx); +} + +static int +dh_init(DH *dh) +{ + dh->flags |= DH_FLAG_CACHE_MONT_P; + return 1; +} + +static int +dh_finish(DH *dh) +{ + BN_MONT_CTX_free(dh->method_mont_p); + return 1; +} diff --git a/Libraries/libressl/crypto/dh/dh_lib.c b/Libraries/libressl/crypto/dh/dh_lib.c new file mode 100644 index 000000000..8d6378768 --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_lib.c @@ -0,0 +1,400 @@ +/* $OpenBSD: dh_lib.c,v 1.41 2023/08/13 12:09:14 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "dh_local.h" + +static const DH_METHOD *default_DH_method = NULL; + +void +DH_set_default_method(const DH_METHOD *meth) +{ + default_DH_method = meth; +} +LCRYPTO_ALIAS(DH_set_default_method); + +const DH_METHOD * +DH_get_default_method(void) +{ + if (!default_DH_method) + default_DH_method = DH_OpenSSL(); + return default_DH_method; +} +LCRYPTO_ALIAS(DH_get_default_method); + +int +DH_set_method(DH *dh, const DH_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DH_METHOD *mtmp; + + mtmp = dh->meth; + if (mtmp->finish) + mtmp->finish(dh); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(dh->engine); + dh->engine = NULL; +#endif + dh->meth = meth; + if (meth->init) + meth->init(dh); + return 1; +} +LCRYPTO_ALIAS(DH_set_method); + +DH * +DH_new(void) +{ + return DH_new_method(NULL); +} +LCRYPTO_ALIAS(DH_new); + +DH * +DH_new_method(ENGINE *engine) +{ + DH *dh; + + if ((dh = calloc(1, sizeof(*dh))) == NULL) { + DHerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + dh->meth = DH_get_default_method(); + dh->flags = dh->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW; + dh->references = 1; + +#ifndef OPENSSL_NO_ENGINE + if (engine != NULL) { + if (!ENGINE_init(engine)) { + DHerror(ERR_R_ENGINE_LIB); + goto err; + } + dh->engine = engine; + } else + dh->engine = ENGINE_get_default_DH(); + if (dh->engine != NULL) { + if ((dh->meth = ENGINE_get_DH(dh->engine)) == NULL) { + DHerror(ERR_R_ENGINE_LIB); + goto err; + } + dh->flags = dh->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW; + } +#endif + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, dh, &dh->ex_data)) + goto err; + if (dh->meth->init != NULL && !dh->meth->init(dh)) + goto err; + + return dh; + + err: + DH_free(dh); + + return NULL; +} +LCRYPTO_ALIAS(DH_new_method); + +void +DH_free(DH *r) +{ + int i; + + if (r == NULL) + return; + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH); + if (i > 0) + return; + + if (r->meth != NULL && r->meth->finish != NULL) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); + + BN_free(r->p); + BN_free(r->g); + BN_free(r->q); + BN_free(r->j); + free(r->seed); + BN_free(r->counter); + BN_free(r->pub_key); + BN_free(r->priv_key); + free(r); +} +LCRYPTO_ALIAS(DH_free); + +int +DH_up_ref(DH *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH); + + return i > 1 ? 1 : 0; +} +LCRYPTO_ALIAS(DH_up_ref); + +int +DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, new_func, + dup_func, free_func); +} +LCRYPTO_ALIAS(DH_get_ex_new_index); + +int +DH_set_ex_data(DH *d, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} +LCRYPTO_ALIAS(DH_set_ex_data); + +void * +DH_get_ex_data(DH *d, int idx) +{ + return CRYPTO_get_ex_data(&d->ex_data, idx); +} +LCRYPTO_ALIAS(DH_get_ex_data); + +int +DH_size(const DH *dh) +{ + return BN_num_bytes(dh->p); +} +LCRYPTO_ALIAS(DH_size); + +int +DH_bits(const DH *dh) +{ + return BN_num_bits(dh->p); +} +LCRYPTO_ALIAS(DH_bits); + +int +DH_security_bits(const DH *dh) +{ + int N = -1; + + if (dh->q != NULL) + N = BN_num_bits(dh->q); + else if (dh->length > 0) + N = dh->length; + + return BN_security_bits(BN_num_bits(dh->p), N); +} +LCRYPTO_ALIAS(DH_security_bits); + +ENGINE * +DH_get0_engine(DH *dh) +{ + return dh->engine; +} +LCRYPTO_ALIAS(DH_get0_engine); + +void +DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} +LCRYPTO_ALIAS(DH_get0_pqg); + +int +DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + dh->length = BN_num_bits(dh->q); + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + return 1; +} +LCRYPTO_ALIAS(DH_set0_pqg); + +void +DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} +LCRYPTO_ALIAS(DH_get0_key); + +int +DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return 1; +} +LCRYPTO_ALIAS(DH_set0_key); + +const BIGNUM * +DH_get0_p(const DH *dh) +{ + return dh->p; +} +LCRYPTO_ALIAS(DH_get0_p); + +const BIGNUM * +DH_get0_q(const DH *dh) +{ + return dh->q; +} +LCRYPTO_ALIAS(DH_get0_q); + +const BIGNUM * +DH_get0_g(const DH *dh) +{ + return dh->g; +} +LCRYPTO_ALIAS(DH_get0_g); + +const BIGNUM * +DH_get0_priv_key(const DH *dh) +{ + return dh->priv_key; +} +LCRYPTO_ALIAS(DH_get0_priv_key); + +const BIGNUM * +DH_get0_pub_key(const DH *dh) +{ + return dh->pub_key; +} +LCRYPTO_ALIAS(DH_get0_pub_key); + +void +DH_clear_flags(DH *dh, int flags) +{ + dh->flags &= ~flags; +} +LCRYPTO_ALIAS(DH_clear_flags); + +int +DH_test_flags(const DH *dh, int flags) +{ + return dh->flags & flags; +} +LCRYPTO_ALIAS(DH_test_flags); + +void +DH_set_flags(DH *dh, int flags) +{ + dh->flags |= flags; +} +LCRYPTO_ALIAS(DH_set_flags); + +long +DH_get_length(const DH *dh) +{ + return dh->length; +} +LCRYPTO_ALIAS(DH_get_length); + +int +DH_set_length(DH *dh, long length) +{ + if (length < 0 || length > INT_MAX) + return 0; + + dh->length = length; + return 1; +} +LCRYPTO_ALIAS(DH_set_length); diff --git a/Libraries/libressl/crypto/dh/dh_local.h b/Libraries/libressl/crypto/dh/dh_local.h new file mode 100644 index 000000000..928f2c0c8 --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_local.h @@ -0,0 +1,117 @@ +/* $OpenBSD: dh_local.h,v 1.3 2022/01/14 08:25:44 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_LOCAL_H +#define HEADER_DH_LOCAL_H + +__BEGIN_HIDDEN_DECLS + +struct dh_method { + const char *name; + /* Methods here */ + int (*generate_key)(DH *dh); + int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh); + int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + int (*init)(DH *dh); + int (*finish)(DH *dh); + int flags; + char *app_data; + /* If this is non-NULL, it will be used to generate parameters */ + int (*generate_params)(DH *dh, int prime_len, int generator, + BN_GENCB *cb); +}; + +struct dh_st { + /* This first argument is used to pick up errors when + * a DH is passed instead of a EVP_PKEY */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x */ + BIGNUM *priv_key; /* x */ + + int flags; + BN_MONT_CTX *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + + int references; + CRYPTO_EX_DATA ex_data; + const DH_METHOD *meth; + ENGINE *engine; +}; + +/* + * Public API in OpenSSL that we only want to use internally. + */ + +int DH_check_params_ex(const DH *dh); +int DH_check_params(const DH *dh, int *flags); +int DH_check_ex(const DH *dh); +int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_DH_LOCAL_H */ diff --git a/Libraries/libressl/crypto/dh/dh_pmeth.c b/Libraries/libressl/crypto/dh/dh_pmeth.c new file mode 100644 index 000000000..7a598da27 --- /dev/null +++ b/Libraries/libressl/crypto/dh/dh_pmeth.c @@ -0,0 +1,266 @@ +/* $OpenBSD: dh_pmeth.c,v 1.13 2022/11/26 16:08:51 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "dh_local.h" +#include "evp_local.h" + +/* DH pkey context structure */ + +typedef struct { + /* Parameter gen parameters */ + int prime_len; + int generator; + int use_dsa; + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ +} DH_PKEY_CTX; + +static int +pkey_dh_init(EVP_PKEY_CTX *ctx) +{ + DH_PKEY_CTX *dctx; + + dctx = malloc(sizeof(DH_PKEY_CTX)); + if (!dctx) + return 0; + dctx->prime_len = 1024; + dctx->generator = 2; + dctx->use_dsa = 0; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int +pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + DH_PKEY_CTX *dctx, *sctx; + + if (!pkey_dh_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->prime_len = sctx->prime_len; + dctx->generator = sctx->generator; + dctx->use_dsa = sctx->use_dsa; + return 1; +} + +static void +pkey_dh_cleanup(EVP_PKEY_CTX *ctx) +{ + DH_PKEY_CTX *dctx = ctx->data; + + free(dctx); +} + +static int +pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + DH_PKEY_CTX *dctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: + if (p1 < 256) + return -2; + dctx->prime_len = p1; + return 1; + + case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: + dctx->generator = p1; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + return 1; + + default: + return -2; + } +} + +static int +pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + long lval; + char *ep; + int len; + + if (!strcmp(type, "dh_paramgen_prime_len")) { + errno = 0; + lval = strtol(value, &ep, 10); + if (value[0] == '\0' || *ep != '\0') + goto not_a_number; + if ((errno == ERANGE && + (lval == LONG_MAX || lval == LONG_MIN)) || + (lval > INT_MAX || lval < INT_MIN)) + goto out_of_range; + len = lval; + return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); + } else if (!strcmp(type, "dh_paramgen_generator")) { + errno = 0; + lval = strtol(value, &ep, 10); + if (value[0] == '\0' || *ep != '\0') + goto not_a_number; + if ((errno == ERANGE && + (lval == LONG_MAX || lval == LONG_MIN)) || + (lval > INT_MAX || lval < INT_MIN)) + goto out_of_range; + len = lval; + return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); + } + +not_a_number: +out_of_range: + return -2; +} + +static int +pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DH *dh = NULL; + DH_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + dh = DH_new(); + if (!dh) + return 0; + ret = DH_generate_parameters_ex(dh, dctx->prime_len, dctx->generator, + pcb); + if (ret) + EVP_PKEY_assign_DH(pkey, dh); + else + DH_free(dh); + return ret; +} + +static int +pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DH *dh = NULL; + + if (ctx->pkey == NULL) { + DHerror(DH_R_NO_PARAMETERS_SET); + return 0; + } + dh = DH_new(); + if (!dh) + return 0; + EVP_PKEY_assign_DH(pkey, dh); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DH_generate_key(pkey->pkey.dh); +} + +static int +pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + int ret; + + if (!ctx->pkey || !ctx->peerkey) { + DHerror(DH_R_KEYS_NOT_SET); + return 0; + } + ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, + ctx->pkey->pkey.dh); + if (ret < 0) + return ret; + *keylen = ret; + return 1; +} + +const EVP_PKEY_METHOD dh_pkey_meth = { + .pkey_id = EVP_PKEY_DH, + .flags = EVP_PKEY_FLAG_AUTOARGLEN, + + .init = pkey_dh_init, + .copy = pkey_dh_copy, + .cleanup = pkey_dh_cleanup, + + .paramgen = pkey_dh_paramgen, + + .keygen = pkey_dh_keygen, + + .derive = pkey_dh_derive, + + .ctrl = pkey_dh_ctrl, + .ctrl_str = pkey_dh_ctrl_str +}; diff --git a/Libraries/libressl/crypto/dsa/dsa_ameth.c b/Libraries/libressl/crypto/dsa/dsa_ameth.c new file mode 100644 index 000000000..4c20b45b1 --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_ameth.c @@ -0,0 +1,737 @@ +/* $OpenBSD: dsa_ameth.c,v 1.55 2023/08/12 07:59:48 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "bn_local.h" +#include "dsa_local.h" +#include "evp_local.h" + +static int +dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + X509_ALGOR *algor; + int ptype; + const void *pval; + const ASN1_STRING *astr; + const unsigned char *key, *params, *p; + int key_len, params_len; + ASN1_INTEGER *aint = NULL; + DSA *dsa = NULL; + int ret = 0; + + if (!X509_PUBKEY_get0_param(NULL, &key, &key_len, &algor, pubkey)) + goto err; + X509_ALGOR_get0(NULL, &ptype, &pval, algor); + + if (ptype == V_ASN1_SEQUENCE) { + astr = pval; + params = astr->data; + params_len = astr->length; + + p = params; + if ((dsa = d2i_DSAparams(NULL, &p, params_len)) == NULL) { + DSAerror(DSA_R_DECODE_ERROR); + goto err; + } + } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { + if ((dsa = DSA_new()) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + p = key; + if ((aint = d2i_ASN1_INTEGER(NULL, &p, key_len)) == NULL) { + DSAerror(DSA_R_DECODE_ERROR); + goto err; + } + BN_free(dsa->pub_key); + if ((dsa->pub_key = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) { + DSAerror(DSA_R_BN_DECODE_ERROR); + goto err; + } + + /* We can only check for key consistency if we have parameters. */ + if (ptype == V_ASN1_SEQUENCE) { + if (!dsa_check_key(dsa)) + goto err; + } + + if (!EVP_PKEY_assign_DSA(pkey, dsa)) + goto err; + dsa = NULL; + + ret = 1; + + err: + ASN1_INTEGER_free(aint); + DSA_free(dsa); + + return ret; +} + +static int +dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + const DSA *dsa = pkey->pkey.dsa; + ASN1_STRING *astr = NULL; + int ptype = V_ASN1_UNDEF; + ASN1_INTEGER *aint = NULL; + ASN1_OBJECT *aobj; + unsigned char *params = NULL, *key = NULL; + int params_len = 0, key_len = 0; + int ret = 0; + + if (pkey->save_parameters > 0 && !EVP_PKEY_missing_parameters(pkey)) { + if ((params_len = i2d_DSAparams(dsa, ¶ms)) <= 0) { + DSAerror(ERR_R_MALLOC_FAILURE); + params_len = 0; + goto err; + } + if ((astr = ASN1_STRING_new()) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_STRING_set0(astr, params, params_len); + params = NULL; + params_len = 0; + ptype = V_ASN1_SEQUENCE; + } + + if ((aint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL)) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if ((key_len = i2d_ASN1_INTEGER(aint, &key)) <= 0) { + DSAerror(ERR_R_MALLOC_FAILURE); + key_len = 0; + goto err; + } + + if ((aobj = OBJ_nid2obj(EVP_PKEY_DSA)) == NULL) + goto err; + if (!X509_PUBKEY_set0_param(pk, aobj, ptype, astr, key, key_len)) + goto err; + astr = NULL; + key = NULL; + key_len = 0; + + ret = 1; + + err: + ASN1_STRING_free(astr); + ASN1_INTEGER_free(aint); + freezero(params, params_len); + freezero(key, key_len); + + return ret; +} + +/* + * In PKCS#8 DSA: you just get a private key integer and parameters in the + * AlgorithmIdentifier the pubkey must be recalculated. + */ +static int +dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +{ + const X509_ALGOR *algor; + int ptype; + const void *pval; + const ASN1_STRING *astr; + const unsigned char *key, *params, *p; + int key_len, params_len; + ASN1_INTEGER *aint = NULL; + BN_CTX *ctx = NULL; + DSA *dsa = NULL; + int ret = 0; + + if (!PKCS8_pkey_get0(NULL, &key, &key_len, &algor, p8)) + goto err; + X509_ALGOR_get0(NULL, &ptype, &pval, algor); + + if (ptype != V_ASN1_SEQUENCE) { + DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + astr = pval; + params = astr->data; + params_len = astr->length; + + p = params; + if ((dsa = d2i_DSAparams(NULL, &p, params_len)) == NULL) { + DSAerror(DSA_R_DECODE_ERROR); + goto err; + } + p = key; + if ((aint = d2i_ASN1_INTEGER(NULL, &p, key_len)) == NULL) { + DSAerror(DSA_R_DECODE_ERROR); + goto err; + } + BN_free(dsa->priv_key); + if ((dsa->priv_key = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) { + DSAerror(DSA_R_BN_DECODE_ERROR); + goto err; + } + + /* Check the key for basic consistency before doing expensive things. */ + if (!dsa_check_key(dsa)) + goto err; + + /* Calculate public key */ + BN_free(dsa->pub_key); + if ((dsa->pub_key = BN_new()) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + + if (!BN_mod_exp_ct(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { + DSAerror(DSA_R_BN_ERROR); + goto err; + } + + if (!EVP_PKEY_assign_DSA(pkey, dsa)) + goto err; + dsa = NULL; + + ret = 1; + + err: + DSA_free(dsa); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + ASN1_INTEGER_free(aint); + + return ret; +} + +static int +dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + const DSA *dsa = pkey->pkey.dsa; + ASN1_STRING *astr = NULL; + int ptype = V_ASN1_SEQUENCE; + ASN1_INTEGER *aint = NULL; + ASN1_OBJECT *aobj; + unsigned char *params = NULL, *key = NULL; + int params_len = 0, key_len = 0; + int ret = 0; + + if ((params_len = i2d_DSAparams(dsa, ¶ms)) <= 0) { + DSAerror(ERR_R_MALLOC_FAILURE); + params_len = 0; + goto err; + } + if ((astr = ASN1_STRING_type_new(V_ASN1_SEQUENCE)) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_STRING_set0(astr, params, params_len); + params = NULL; + params_len = 0; + + if ((aint = BN_to_ASN1_INTEGER(dsa->priv_key, NULL)) == NULL) { + DSAerror(DSA_R_BN_ERROR); + goto err; + } + if ((key_len = i2d_ASN1_INTEGER(aint, &key)) <= 0) { + DSAerror(ERR_R_MALLOC_FAILURE); + key_len = 0; + goto err; + } + + if ((aobj = OBJ_nid2obj(NID_dsa)) == NULL) + goto err; + if (!PKCS8_pkey_set0(p8, aobj, 0, ptype, astr, key, key_len)) + goto err; + astr = NULL; + key = NULL; + key_len = 0; + + ret = 1; + + err: + ASN1_STRING_free(astr); + ASN1_INTEGER_free(aint); + freezero(params, params_len); + freezero(key, key_len); + + return ret; +} + +static int +dsa_size(const EVP_PKEY *pkey) +{ + return DSA_size(pkey->pkey.dsa); +} + +static int +dsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.dsa->p); +} + +static int +dsa_security_bits(const EVP_PKEY *pkey) +{ + return DSA_security_bits(pkey->pkey.dsa); +} + +static int +dsa_missing_parameters(const EVP_PKEY *pkey) +{ + const DSA *dsa = pkey->pkey.dsa; + + return dsa->p == NULL || dsa->q == NULL || dsa->g == NULL; +} + +static int +dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + BIGNUM *a; + + if ((a = BN_dup(from->pkey.dsa->p)) == NULL) + return 0; + BN_free(to->pkey.dsa->p); + to->pkey.dsa->p = a; + + if ((a = BN_dup(from->pkey.dsa->q)) == NULL) + return 0; + BN_free(to->pkey.dsa->q); + to->pkey.dsa->q = a; + + if ((a = BN_dup(from->pkey.dsa->g)) == NULL) + return 0; + BN_free(to->pkey.dsa->g); + to->pkey.dsa->g = a; + return 1; +} + +static int +dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) + return 0; + else + return 1; +} + +static int +dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) + return 0; + else + return 1; +} + +static void +dsa_free(EVP_PKEY *pkey) +{ + DSA_free(pkey->pkey.dsa); +} + +static int +do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) +{ + const char *ktype = NULL; + const BIGNUM *priv_key, *pub_key; + int ret = 0; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + if (ptype == 2) + ktype = "Private-Key"; + else if (ptype == 1) + ktype = "Public-Key"; + else + ktype = "DSA-Parameters"; + + if (priv_key) { + if (!BIO_indent(bp, off, 128)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, + BN_num_bits(x->p)) <= 0) + goto err; + } + + if (!bn_printf(bp, priv_key, off, "priv:")) + goto err; + if (!bn_printf(bp, pub_key, off, "pub: ")) + goto err; + if (!bn_printf(bp, x->p, off, "P: ")) + goto err; + if (!bn_printf(bp, x->q, off, "Q: ")) + goto err; + if (!bn_printf(bp, x->g, off, "G: ")) + goto err; + + ret = 1; + + err: + return ret; +} + +static int +dsa_param_decode(EVP_PKEY *pkey, const unsigned char **params, int params_len) +{ + DSA *dsa = NULL; + int ret = 0; + + if ((dsa = d2i_DSAparams(NULL, params, params_len)) == NULL) { + DSAerror(ERR_R_DSA_LIB); + goto err; + } + if (!dsa_check_key(dsa)) + goto err; + if (!EVP_PKEY_assign_DSA(pkey, dsa)) + goto err; + dsa = NULL; + + ret = 1; + + err: + DSA_free(dsa); + + return ret; +} + +static int +dsa_param_encode(const EVP_PKEY *pkey, unsigned char **params) +{ + return i2d_DSAparams(pkey->pkey.dsa, params); +} + +static int +dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); +} + +static int +dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); +} + +static int +dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); +} + +static int +old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **key, int key_len) +{ + DSA *dsa = NULL; + BN_CTX *ctx = NULL; + BIGNUM *result; + int ret = 0; + + if ((dsa = d2i_DSAPrivateKey(NULL, key, key_len)) == NULL) { + DSAerror(ERR_R_DSA_LIB); + goto err; + } + + if (!dsa_check_key(dsa)) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((result = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Check that p and q are consistent with each other. dsa_check_key() + * ensures that 1 < q < p. Now check that q divides p - 1. + */ + + if (!BN_sub(result, dsa->p, BN_value_one())) + goto err; + if (!BN_mod_ct(result, result, dsa->q, ctx)) + goto err; + if (!BN_is_zero(result)) { + DSAerror(DSA_R_BAD_Q_VALUE); + goto err; + } + + /* + * Check that g generates a multiplicative subgroup of order q. + * We only check that g^q == 1, so the order is a divisor of q. + * Once we know that q is prime, this is enough. + */ + + if (!BN_mod_exp_ct(result, dsa->g, dsa->q, dsa->p, ctx)) + goto err; + if (BN_cmp(result, BN_value_one()) != 0) { + DSAerror(DSA_R_INVALID_PARAMETERS); + goto err; + } + + /* + * Check that q is not a composite number. + */ + + if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) <= 0) { + DSAerror(DSA_R_BAD_Q_VALUE); + goto err; + } + + if (!EVP_PKEY_assign_DSA(pkey, dsa)) + goto err; + dsa = NULL; + + ret = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + DSA_free(dsa); + + return ret; +} + +static int +old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **key) +{ + return i2d_DSAPrivateKey(pkey->pkey.dsa, key); +} + +static int +dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx) +{ + DSA_SIG *dsa_sig; + const unsigned char *p; + + if (!sig) { + if (BIO_puts(bp, "\n") <= 0) + return 0; + else + return 1; + } + p = sig->data; + dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); + if (dsa_sig) { + int rv = 0; + + if (BIO_write(bp, "\n", 1) != 1) + goto err; + + if (!bn_printf(bp, dsa_sig->r, indent, "r: ")) + goto err; + if (!bn_printf(bp, dsa_sig->s, indent, "s: ")) + goto err; + rv = 1; + err: + DSA_SIG_free(dsa_sig); + return rv; + } + return X509_signature_dump(bp, sig, indent); +} + +static int +dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, + EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, + 0); + } + return 1; + +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + *(int *)arg2 = CMS_RECIPINFO_NONE; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 2; + + default: + return -2; + } +} + +/* NB these are sorted in pkey_id order, lowest first */ + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = { + { + .pkey_id = EVP_PKEY_DSA2, + .pkey_base_id = EVP_PKEY_DSA, + .pkey_flags = ASN1_PKEY_ALIAS + }, + + { + .pkey_id = EVP_PKEY_DSA1, + .pkey_base_id = EVP_PKEY_DSA, + .pkey_flags = ASN1_PKEY_ALIAS + }, + + { + .pkey_id = EVP_PKEY_DSA4, + .pkey_base_id = EVP_PKEY_DSA, + .pkey_flags = ASN1_PKEY_ALIAS + }, + + { + .pkey_id = EVP_PKEY_DSA3, + .pkey_base_id = EVP_PKEY_DSA, + .pkey_flags = ASN1_PKEY_ALIAS + }, + + { + .pkey_id = EVP_PKEY_DSA, + .pkey_base_id = EVP_PKEY_DSA, + + .pem_str = "DSA", + .info = "OpenSSL DSA method", + + .pub_decode = dsa_pub_decode, + .pub_encode = dsa_pub_encode, + .pub_cmp = dsa_pub_cmp, + .pub_print = dsa_pub_print, + + .priv_decode = dsa_priv_decode, + .priv_encode = dsa_priv_encode, + .priv_print = dsa_priv_print, + + .pkey_size = dsa_size, + .pkey_bits = dsa_bits, + .pkey_security_bits = dsa_security_bits, + + .param_decode = dsa_param_decode, + .param_encode = dsa_param_encode, + .param_missing = dsa_missing_parameters, + .param_copy = dsa_copy_parameters, + .param_cmp = dsa_cmp_parameters, + .param_print = dsa_param_print, + .sig_print = dsa_sig_print, + + .pkey_free = dsa_free, + .pkey_ctrl = dsa_pkey_ctrl, + .old_priv_decode = old_dsa_priv_decode, + .old_priv_encode = old_dsa_priv_encode + } +}; diff --git a/Libraries/libressl/crypto/dsa/dsa_asn1.c b/Libraries/libressl/crypto/dsa/dsa_asn1.c new file mode 100644 index 000000000..5e4f882cf --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_asn1.c @@ -0,0 +1,476 @@ +/* $OpenBSD: dsa_asn1.c,v 1.31 2023/07/08 14:28:15 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "dsa_local.h" + +/* Override the default new methods */ +static int +sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + DSA_SIG *sig; + + if ((sig = DSA_SIG_new()) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + return 0; + } + *pval = (ASN1_VALUE *)sig; + return 2; + } + return 1; +} + +static const ASN1_AUX DSA_SIG_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = sig_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DSA_SIG_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA_SIG, r), + .field_name = "r", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA_SIG, s), + .field_name = "s", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM DSA_SIG_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DSA_SIG_seq_tt, + .tcount = sizeof(DSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DSA_SIG_aux, + .size = sizeof(DSA_SIG), + .sname = "DSA_SIG", +}; + + +DSA_SIG * +d2i_DSA_SIG(DSA_SIG **a, const unsigned char **in, long len) +{ + return (DSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DSA_SIG_it); +} +LCRYPTO_ALIAS(d2i_DSA_SIG); + +int +i2d_DSA_SIG(const DSA_SIG *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSA_SIG_it); +} +LCRYPTO_ALIAS(i2d_DSA_SIG); + +void +DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} +LCRYPTO_ALIAS(DSA_SIG_get0); + +int +DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + + BN_free(sig->r); + sig->r = r; + BN_free(sig->s); + sig->s = s; + + return 1; +} +LCRYPTO_ALIAS(DSA_SIG_set0); + +/* Override the default free and new methods */ +static int +dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)DSA_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + DSA_free((DSA *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +static const ASN1_AUX DSAPrivateKey_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = dsa_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DSAPrivateKey_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, p), + .field_name = "p", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, q), + .field_name = "q", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, g), + .field_name = "g", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, pub_key), + .field_name = "pub_key", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, priv_key), + .field_name = "priv_key", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM DSAPrivateKey_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DSAPrivateKey_seq_tt, + .tcount = sizeof(DSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DSAPrivateKey_aux, + .size = sizeof(DSA), + .sname = "DSA", +}; + + +DSA * +d2i_DSAPrivateKey(DSA **a, const unsigned char **in, long len) +{ + return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DSAPrivateKey_it); +} +LCRYPTO_ALIAS(d2i_DSAPrivateKey); + +int +i2d_DSAPrivateKey(const DSA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPrivateKey_it); +} +LCRYPTO_ALIAS(i2d_DSAPrivateKey); + +static const ASN1_AUX DSAparams_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = dsa_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DSAparams_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, p), + .field_name = "p", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, q), + .field_name = "q", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, g), + .field_name = "g", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM DSAparams_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DSAparams_seq_tt, + .tcount = sizeof(DSAparams_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DSAparams_aux, + .size = sizeof(DSA), + .sname = "DSA", +}; + + +DSA * +d2i_DSAparams(DSA **a, const unsigned char **in, long len) +{ + return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DSAparams_it); +} +LCRYPTO_ALIAS(d2i_DSAparams); + +int +i2d_DSAparams(const DSA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAparams_it); +} +LCRYPTO_ALIAS(i2d_DSAparams); + +DSA * +d2i_DSAparams_bio(BIO *bp, DSA **a) +{ + return ASN1_item_d2i_bio(&DSAparams_it, bp, a); +} +LCRYPTO_ALIAS(d2i_DSAparams_bio); + +int +i2d_DSAparams_bio(BIO *bp, DSA *a) +{ + return ASN1_item_i2d_bio(&DSAparams_it, bp, a); +} +LCRYPTO_ALIAS(i2d_DSAparams_bio); + +DSA * +d2i_DSAparams_fp(FILE *fp, DSA **a) +{ + return ASN1_item_d2i_fp(&DSAparams_it, fp, a); +} +LCRYPTO_ALIAS(d2i_DSAparams_fp); + +int +i2d_DSAparams_fp(FILE *fp, DSA *a) +{ + return ASN1_item_i2d_fp(&DSAparams_it, fp, a); +} +LCRYPTO_ALIAS(i2d_DSAparams_fp); + +static const ASN1_AUX DSAPublicKey_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = dsa_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DSAPublicKey_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, pub_key), + .field_name = "pub_key", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, p), + .field_name = "p", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, q), + .field_name = "q", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(DSA, g), + .field_name = "g", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM DSAPublicKey_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DSAPublicKey_seq_tt, + .tcount = sizeof(DSAPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DSAPublicKey_aux, + .size = sizeof(DSA), + .sname = "DSA", +}; + +DSA * +d2i_DSAPublicKey(DSA **a, const unsigned char **in, long len) +{ + return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DSAPublicKey_it); +} +LCRYPTO_ALIAS(d2i_DSAPublicKey); + +int +i2d_DSAPublicKey(const DSA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPublicKey_it); +} +LCRYPTO_ALIAS(i2d_DSAPublicKey); + +DSA * +DSAparams_dup(DSA *dsa) +{ + return ASN1_item_dup(&DSAparams_it, dsa); +} +LCRYPTO_ALIAS(DSAparams_dup); + +int +DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, + unsigned int *out_siglen, DSA *dsa) +{ + DSA_SIG *s; + int siglen; + int ret = 0; + + *out_siglen = 0; + + if ((s = DSA_do_sign(dgst, dlen, dsa)) == NULL) + goto err; + + if ((siglen = i2d_DSA_SIG(s, &sig)) < 0) + goto err; + + *out_siglen = siglen; + + ret = 1; + err: + DSA_SIG_free(s); + + return ret; +} +LCRYPTO_ALIAS(DSA_sign); + +/* + * data has already been hashed (probably with SHA or SHA-1). + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int +DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) +{ + DSA_SIG *s = NULL; + unsigned char *der = NULL; + const unsigned char *p; + int ret = -1; + + p = sigbuf; + if ((s = d2i_DSA_SIG(NULL, &p, siglen)) == NULL) + goto err; + + /* Ensure signature uses DER and doesn't have trailing garbage */ + if (i2d_DSA_SIG(s, &der) != siglen) + goto err; + + if (memcmp(der, sigbuf, siglen) != 0) + goto err; + + ret = DSA_do_verify(dgst, dgst_len, s, dsa); + err: + free(der); + DSA_SIG_free(s); + + return ret; +} +LCRYPTO_ALIAS(DSA_verify); diff --git a/Libraries/libressl/crypto/dsa/dsa_err.c b/Libraries/libressl/crypto/dsa/dsa_err.c new file mode 100644 index 000000000..6934fe14f --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_err.c @@ -0,0 +1,104 @@ +/* $OpenBSD: dsa_err.c,v 1.19 2023/07/08 14:28:15 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason) + +static ERR_STRING_DATA DSA_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA DSA_str_reasons[]= + { +{ERR_REASON(DSA_R_BAD_Q_VALUE) ,"bad q value"}, +{ERR_REASON(DSA_R_BN_DECODE_ERROR) ,"bn decode error"}, +{ERR_REASON(DSA_R_BN_ERROR) ,"bn error"}, +{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, +{ERR_REASON(DSA_R_DECODE_ERROR) ,"decode error"}, +{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, +{ERR_REASON(DSA_R_INVALID_PARAMETERS) ,"invalid parameters"}, +{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, +{ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, +{ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"}, +{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD) ,"non fips dsa method"}, +{ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"}, +{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"}, +{0,NULL} + }; + +#endif + +void ERR_load_DSA_strings(void) + { +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) + { + ERR_load_strings(0,DSA_str_functs); + ERR_load_strings(0,DSA_str_reasons); + } +#endif + } +LCRYPTO_ALIAS(ERR_load_DSA_strings); diff --git a/Libraries/libressl/crypto/dsa/dsa_gen.c b/Libraries/libressl/crypto/dsa/dsa_gen.c new file mode 100644 index 000000000..490c7e51b --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_gen.c @@ -0,0 +1,381 @@ +/* $OpenBSD: dsa_gen.c,v 1.30 2023/07/08 14:28:15 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include /* To see if OPENSSL_NO_SHA is defined */ + +#ifndef OPENSSL_NO_SHA + +#include +#include +#include + +#include +#include +#include + +#include "bn_local.h" +#include "dsa_local.h" + +int +DSA_generate_parameters_ex(DSA *ret, int bits, const unsigned char *seed_in, + int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) +{ + if (ret->meth->dsa_paramgen) + return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, + counter_ret, h_ret, cb); + else { + const EVP_MD *evpmd; + size_t qbits; + + if (bits >= 2048) { + qbits = 256; + evpmd = EVP_sha256(); + } else { + qbits = 160; + evpmd = EVP_sha1(); + } + + return dsa_builtin_paramgen(ret, bits, qbits, evpmd, seed_in, + seed_len, NULL, counter_ret, h_ret, cb); + } +} +LCRYPTO_ALIAS(DSA_generate_parameters_ex); + +int +dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, + const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) +{ + int ok = 0; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; + BIGNUM *r0, *W, *X, *c, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int i, k, n = 0, m = 0, qsize = qbits >> 3; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + unsigned int h = 2; + + if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && + qsize != SHA256_DIGEST_LENGTH) + /* invalid q size */ + return 0; + + if (evpmd == NULL) + /* use SHA1 as default */ + evpmd = EVP_sha1(); + + if (bits < 512) + bits = 512; + + bits = (bits + 63) / 64 * 64; + + if (seed_len < (size_t)qsize) { + seed_in = NULL; /* seed buffer too small -- ignore */ + seed_len = 0; + } + /* + * App. 2.2 of FIPS PUB 186 allows larger SEED, + * but our internal buffers are restricted to 160 bits + */ + if (seed_len > (size_t)qsize) + seed_len = qsize; + if (seed_in != NULL) + memcpy(seed, seed_in, seed_len); + else if (seed_len != 0) + goto err; + + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((r0 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((g = BN_CTX_get(ctx)) == NULL) + goto err; + if ((W = BN_CTX_get(ctx)) == NULL) + goto err; + if ((q = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((test = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_lshift(test, BN_value_one(), bits - 1)) + goto err; + + for (;;) { + for (;;) { /* find q */ + int seed_is_random; + + /* step 1 */ + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (seed_len == 0) { + arc4random_buf(seed, qsize); + seed_is_random = 1; + } else { + seed_is_random = 0; + /* use random seed if 'seed_in' turns out + to be bad */ + seed_len = 0; + } + memcpy(buf, seed, qsize); + memcpy(buf2, seed, qsize); + /* precompute "SEED + 1" for step 7: */ + for (i = qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + /* step 2 */ + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) + goto err; + if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) + goto err; + for (i = 0; i < qsize; i++) + md[i] ^= buf2[i]; + + /* step 3 */ + md[0] |= 0x80; + md[qsize - 1] |= 0x01; + if (!BN_bin2bn(md, qsize, q)) + goto err; + + /* step 4 */ + r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, + seed_is_random, cb); + if (r > 0) + break; + if (r != 0) + goto err; + + /* do a callback call */ + /* step 5 */ + } + + if (!BN_GENCB_call(cb, 2, 0)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + + /* step 6 */ + counter = 0; + /* "offset = 2" */ + + n = (bits - 1) / 160; + + for (;;) { + if (counter != 0 && !BN_GENCB_call(cb, 0, counter)) + goto err; + + /* step 7 */ + BN_zero(W); + /* now 'buf' contains "SEED + offset - 1" */ + for (k = 0; k <= n; k++) { + /* obtain "SEED + offset + k" by incrementing: */ + for (i = qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + if (!EVP_Digest(buf, qsize, md ,NULL, evpmd, + NULL)) + goto err; + + /* step 8 */ + if (!BN_bin2bn(md, qsize, r0)) + goto err; + if (!BN_lshift(r0, r0, (qsize << 3) * k)) + goto err; + if (!BN_add(W, W, r0)) + goto err; + } + + /* more of step 8 */ + if (!BN_mask_bits(W, bits - 1)) + goto err; + if (!bn_copy(X, W)) + goto err; + if (!BN_add(X, X, test)) + goto err; + + /* step 9 */ + if (!BN_lshift1(r0, q)) + goto err; + if (!BN_mod_ct(c, X, r0, ctx)) + goto err; + if (!BN_sub(r0, c, BN_value_one())) + goto err; + if (!BN_sub(p, X, r0)) + goto err; + + /* step 10 */ + if (BN_cmp(p, test) >= 0) { + /* step 11 */ + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, + ctx, 1, cb); + if (r > 0) + goto end; /* found it */ + if (r != 0) + goto err; + } + + /* step 13 */ + counter++; + /* "offset = offset + n + 1" */ + + /* step 14 */ + if (counter >= 4096) + break; + } + } +end: + if (!BN_GENCB_call(cb, 2, 1)) + goto err; + + /* We now need to generate g */ + /* Set r0=(p-1)/q */ + if (!BN_sub(test, p, BN_value_one())) + goto err; + if (!BN_div_ct(r0, NULL, test, q, ctx)) + goto err; + + if (!BN_set_word(test, h)) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + for (;;) { + /* g=test^r0%p */ + if (!BN_mod_exp_mont_ct(g, test, r0, p, ctx, mont)) + goto err; + if (!BN_is_one(g)) + break; + if (!BN_add(test, test, BN_value_one())) + goto err; + h++; + } + + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + + ok = 1; +err: + if (ok) { + BN_free(ret->p); + BN_free(ret->q); + BN_free(ret->g); + ret->p = BN_dup(p); + ret->q = BN_dup(q); + ret->g = BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + ok = 0; + goto err; + } + if (counter_ret != NULL) + *counter_ret = counter; + if (h_ret != NULL) + *h_ret = h; + if (seed_out != NULL) + memcpy(seed_out, seed, qsize); + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_MONT_CTX_free(mont); + + return ok; +} + +DSA * +DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, void (*callback)(int, int, void *), + void *cb_arg) +{ + BN_GENCB cb; + DSA *ret; + + if ((ret = DSA_new()) == NULL) + return NULL; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, + counter_ret, h_ret, &cb)) + return ret; + DSA_free(ret); + return NULL; +} +LCRYPTO_ALIAS(DSA_generate_parameters); + +#endif diff --git a/Libraries/libressl/crypto/dsa/dsa_key.c b/Libraries/libressl/crypto/dsa/dsa_key.c new file mode 100644 index 000000000..431748ab7 --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_key.c @@ -0,0 +1,120 @@ +/* $OpenBSD: dsa_key.c,v 1.35 2023/08/03 18:53:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_SHA + +#include +#include + +#include "bn_local.h" +#include "dsa_local.h" + +static int dsa_builtin_keygen(DSA *dsa); + +int +DSA_generate_key(DSA *dsa) +{ + if (dsa->meth->dsa_keygen) + return dsa->meth->dsa_keygen(dsa); + return dsa_builtin_keygen(dsa); +} +LCRYPTO_ALIAS(DSA_generate_key); + +static int +dsa_builtin_keygen(DSA *dsa) +{ + BIGNUM *pub_key = NULL, *priv_key = NULL; + BN_CTX *ctx = NULL; + int ok = 0; + + if ((priv_key = BN_new()) == NULL) + goto err; + if ((pub_key = BN_new()) == NULL) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (!bn_rand_interval(priv_key, 1, dsa->q)) + goto err; + if (!BN_mod_exp_ct(pub_key, dsa->g, priv_key, dsa->p, ctx)) + goto err; + + BN_free(dsa->priv_key); + dsa->priv_key = priv_key; + priv_key = NULL; + + BN_free(dsa->pub_key); + dsa->pub_key = pub_key; + pub_key = NULL; + + ok = 1; + + err: + BN_free(pub_key); + BN_free(priv_key); + BN_CTX_free(ctx); + + return ok; +} +#endif diff --git a/Libraries/libressl/crypto/dsa/dsa_lib.c b/Libraries/libressl/crypto/dsa/dsa_lib.c new file mode 100644 index 000000000..a9d2179ae --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_lib.c @@ -0,0 +1,510 @@ +/* $OpenBSD: dsa_lib.c,v 1.44 2023/08/12 06:14:36 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "dh_local.h" +#include "dsa_local.h" + +static const DSA_METHOD *default_DSA_method = NULL; + +void +DSA_set_default_method(const DSA_METHOD *meth) +{ + default_DSA_method = meth; +} +LCRYPTO_ALIAS(DSA_set_default_method); + +const DSA_METHOD * +DSA_get_default_method(void) +{ + if (!default_DSA_method) + default_DSA_method = DSA_OpenSSL(); + return default_DSA_method; +} +LCRYPTO_ALIAS(DSA_get_default_method); + +DSA * +DSA_new(void) +{ + return DSA_new_method(NULL); +} +LCRYPTO_ALIAS(DSA_new); + +int +DSA_set_method(DSA *dsa, const DSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DSA_METHOD *mtmp; + mtmp = dsa->meth; + if (mtmp->finish) + mtmp->finish(dsa); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(dsa->engine); + dsa->engine = NULL; +#endif + dsa->meth = meth; + if (meth->init) + meth->init(dsa); + return 1; +} +LCRYPTO_ALIAS(DSA_set_method); + +DSA * +DSA_new_method(ENGINE *engine) +{ + DSA *dsa; + + if ((dsa = calloc(1, sizeof(DSA))) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + dsa->meth = DSA_get_default_method(); + dsa->flags = dsa->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; + dsa->references = 1; + +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + DSAerror(ERR_R_ENGINE_LIB); + goto err; + } + dsa->engine = engine; + } else + dsa->engine = ENGINE_get_default_DSA(); + if (dsa->engine != NULL) { + if ((dsa->meth = ENGINE_get_DSA(dsa->engine)) == NULL) { + DSAerror(ERR_R_ENGINE_LIB); + goto err; + } + dsa->flags = dsa->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; + } +#endif + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, dsa, &dsa->ex_data)) + goto err; + if (dsa->meth->init != NULL && !dsa->meth->init(dsa)) + goto err; + + return dsa; + + err: + DSA_free(dsa); + + return NULL; +} +LCRYPTO_ALIAS(DSA_new_method); + +void +DSA_free(DSA *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DSA); + if (i > 0) + return; + + if (r->meth != NULL && r->meth->finish != NULL) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); + + BN_free(r->p); + BN_free(r->q); + BN_free(r->g); + BN_free(r->pub_key); + BN_free(r->priv_key); + BN_free(r->kinv); + BN_free(r->r); + free(r); +} +LCRYPTO_ALIAS(DSA_free); + +int +DSA_up_ref(DSA *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA); + return i > 1 ? 1 : 0; +} +LCRYPTO_ALIAS(DSA_up_ref); + +int +DSA_size(const DSA *r) +{ + DSA_SIG signature; + int ret = 0; + + signature.r = r->q; + signature.s = r->q; + + if ((ret = i2d_DSA_SIG(&signature, NULL)) < 0) + ret = 0; + + return ret; +} +LCRYPTO_ALIAS(DSA_size); + +int +DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp, + new_func, dup_func, free_func); +} +LCRYPTO_ALIAS(DSA_get_ex_new_index); + +int +DSA_set_ex_data(DSA *d, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} +LCRYPTO_ALIAS(DSA_set_ex_data); + +void * +DSA_get_ex_data(DSA *d, int idx) +{ + return CRYPTO_get_ex_data(&d->ex_data, idx); +} +LCRYPTO_ALIAS(DSA_get_ex_data); + +int +DSA_security_bits(const DSA *d) +{ + if (d->p == NULL || d->q == NULL) + return -1; + + return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q)); +} +LCRYPTO_ALIAS(DSA_security_bits); + +#ifndef OPENSSL_NO_DH +DH * +DSA_dup_DH(const DSA *r) +{ + /* + * DSA has p, q, g, optional pub_key, optional priv_key. + * DH has p, optional length, g, optional pub_key, optional priv_key, + * optional q. + */ + DH *ret = NULL; + + if (r == NULL) + goto err; + ret = DH_new(); + if (ret == NULL) + goto err; + if (r->p != NULL) + if ((ret->p = BN_dup(r->p)) == NULL) + goto err; + if (r->q != NULL) { + ret->length = BN_num_bits(r->q); + if ((ret->q = BN_dup(r->q)) == NULL) + goto err; + } + if (r->g != NULL) + if ((ret->g = BN_dup(r->g)) == NULL) + goto err; + if (r->pub_key != NULL) + if ((ret->pub_key = BN_dup(r->pub_key)) == NULL) + goto err; + if (r->priv_key != NULL) + if ((ret->priv_key = BN_dup(r->priv_key)) == NULL) + goto err; + + return ret; + +err: + DH_free(ret); + return NULL; +} +LCRYPTO_ALIAS(DSA_dup_DH); +#endif + +void +DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} +LCRYPTO_ALIAS(DSA_get0_pqg); + +int +DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) || + (d->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(d->p); + d->p = p; + } + if (q != NULL) { + BN_free(d->q); + d->q = q; + } + if (g != NULL) { + BN_free(d->g); + d->g = g; + } + + return 1; +} +LCRYPTO_ALIAS(DSA_set0_pqg); + +void +DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} +LCRYPTO_ALIAS(DSA_get0_key); + +int +DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (d->pub_key == NULL && pub_key == NULL) + return 0; + + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } + + return 1; +} +LCRYPTO_ALIAS(DSA_set0_key); + +const BIGNUM * +DSA_get0_p(const DSA *d) +{ + return d->p; +} +LCRYPTO_ALIAS(DSA_get0_p); + +const BIGNUM * +DSA_get0_q(const DSA *d) +{ + return d->q; +} +LCRYPTO_ALIAS(DSA_get0_q); + +const BIGNUM * +DSA_get0_g(const DSA *d) +{ + return d->g; +} +LCRYPTO_ALIAS(DSA_get0_g); + +const BIGNUM * +DSA_get0_pub_key(const DSA *d) +{ + return d->pub_key; +} +LCRYPTO_ALIAS(DSA_get0_pub_key); + +const BIGNUM * +DSA_get0_priv_key(const DSA *d) +{ + return d->priv_key; +} +LCRYPTO_ALIAS(DSA_get0_priv_key); + +void +DSA_clear_flags(DSA *d, int flags) +{ + d->flags &= ~flags; +} +LCRYPTO_ALIAS(DSA_clear_flags); + +int +DSA_test_flags(const DSA *d, int flags) +{ + return d->flags & flags; +} +LCRYPTO_ALIAS(DSA_test_flags); + +void +DSA_set_flags(DSA *d, int flags) +{ + d->flags |= flags; +} +LCRYPTO_ALIAS(DSA_set_flags); + +ENGINE * +DSA_get0_engine(DSA *d) +{ + return d->engine; +} +LCRYPTO_ALIAS(DSA_get0_engine); + +int +DSA_bits(const DSA *dsa) +{ + return BN_num_bits(dsa->p); +} +LCRYPTO_ALIAS(DSA_bits); + +int +dsa_check_key(const DSA *dsa) +{ + int p_bits, q_bits; + + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + DSAerror(DSA_R_MISSING_PARAMETERS); + return 0; + } + + /* Checking that p and q are primes is expensive. Check they are odd. */ + if (!BN_is_odd(dsa->p) || !BN_is_odd(dsa->q)) { + DSAerror(DSA_R_INVALID_PARAMETERS); + return 0; + } + + /* FIPS 186-4: 1 < g < p. */ + if (BN_cmp(dsa->g, BN_value_one()) <= 0 || + BN_cmp(dsa->g, dsa->p) >= 0) { + DSAerror(DSA_R_INVALID_PARAMETERS); + return 0; + } + + /* We know p and g are positive. The next two checks imply q > 0. */ + if (BN_is_negative(dsa->q)) { + DSAerror(DSA_R_BAD_Q_VALUE); + return 0; + } + + /* FIPS 186-4 only allows three sizes for q. */ + q_bits = BN_num_bits(dsa->q); + if (q_bits != 160 && q_bits != 224 && q_bits != 256) { + DSAerror(DSA_R_BAD_Q_VALUE); + return 0; + } + + /* + * XXX - FIPS 186-4 only allows 1024, 2048, and 3072 bits for p. + * Cap the size to reduce DoS risks. Poor defaults make keys with + * incorrect p sizes >= 512 bits common, so only enforce a weak + * lower bound. + */ + p_bits = BN_num_bits(dsa->p); + if (p_bits > OPENSSL_DSA_MAX_MODULUS_BITS) { + DSAerror(DSA_R_MODULUS_TOO_LARGE); + return 0; + } + if (p_bits < 512) { + DSAerror(DSA_R_INVALID_PARAMETERS); + return 0; + } + + /* The public key must be in the multiplicative group (mod p). */ + if (dsa->pub_key != NULL) { + if (BN_cmp(dsa->pub_key, BN_value_one()) <= 0 || + BN_cmp(dsa->pub_key, dsa->p) >= 0) { + DSAerror(DSA_R_INVALID_PARAMETERS); + return 0; + } + } + + /* The private key must be nonzero and in GF(q). */ + if (dsa->priv_key != NULL) { + if (BN_cmp(dsa->priv_key, BN_value_one()) < 0 || + BN_cmp(dsa->priv_key, dsa->q) >= 0) { + DSAerror(DSA_R_INVALID_PARAMETERS); + return 0; + } + } + + return 1; +} diff --git a/Libraries/libressl/crypto/dsa/dsa_local.h b/Libraries/libressl/crypto/dsa/dsa_local.h new file mode 100644 index 000000000..a413db974 --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_local.h @@ -0,0 +1,120 @@ +/* $OpenBSD: dsa_local.h,v 1.2 2023/03/04 20:54:52 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +__BEGIN_HIDDEN_DECLS + +struct DSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} /* DSA_SIG */; + +struct dsa_method { + char *name; + DSA_SIG *(*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa); + int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); + int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); /* Can be null */ + int (*init)(DSA *dsa); + int (*finish)(DSA *dsa); + int flags; + char *app_data; + /* If this is non-NULL, it is used to generate DSA parameters */ + int (*dsa_paramgen)(DSA *dsa, int bits, const unsigned char *seed, + int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + /* If this is non-NULL, it is used to generate DSA keys */ + int (*dsa_keygen)(DSA *dsa); +} /* DSA_METHOD */; + +struct dsa_st { + /* This first variable is used to pick up errors where + * a DSA is passed instead of of a EVP_PKEY */ + int pad; + long version; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + + int flags; + /* Normally used to cache montgomery values */ + BN_MONT_CTX *method_mont_p; + int references; + CRYPTO_EX_DATA ex_data; + const DSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; +} /* DSA */; + +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, + unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + +int dsa_check_key(const DSA *dsa); + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/dsa/dsa_meth.c b/Libraries/libressl/crypto/dsa/dsa_meth.c new file mode 100644 index 000000000..c84b5287e --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_meth.c @@ -0,0 +1,110 @@ +/* $OpenBSD: dsa_meth.c,v 1.7 2023/07/08 14:28:15 beck Exp $ */ +/* + * Copyright (c) 2018 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "dsa_local.h" + +DSA_METHOD * +DSA_meth_new(const char *name, int flags) +{ + DSA_METHOD *meth; + + if ((meth = calloc(1, sizeof(*meth))) == NULL) + return NULL; + if ((meth->name = strdup(name)) == NULL) { + free(meth); + return NULL; + } + meth->flags = flags; + + return meth; +} +LCRYPTO_ALIAS(DSA_meth_new); + +void +DSA_meth_free(DSA_METHOD *meth) +{ + if (meth == NULL) + return; + + free(meth->name); + free(meth); +} +LCRYPTO_ALIAS(DSA_meth_free); + +DSA_METHOD * +DSA_meth_dup(const DSA_METHOD *meth) +{ + DSA_METHOD *copy; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) + return NULL; + memcpy(copy, meth, sizeof(*copy)); + if ((copy->name = strdup(meth->name)) == NULL) { + free(copy); + return NULL; + } + + return copy; +} +LCRYPTO_ALIAS(DSA_meth_dup); + +const char * +DSA_meth_get0_name(const DSA_METHOD *meth) +{ + return meth->name; +} +LCRYPTO_ALIAS(DSA_meth_get0_name); + +int +DSA_meth_set1_name(DSA_METHOD *meth, const char *name) +{ + char *new_name; + + if ((new_name = strdup(name)) == NULL) { + DSAerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + free(meth->name); + meth->name = new_name; + + return 1; +} +LCRYPTO_ALIAS(DSA_meth_set1_name); + +int +DSA_meth_set_sign(DSA_METHOD *meth, + DSA_SIG *(*sign)(const unsigned char *, int, DSA *)) +{ + meth->dsa_do_sign = sign; + return 1; +} +LCRYPTO_ALIAS(DSA_meth_set_sign); + +int +DSA_meth_set_finish(DSA_METHOD *meth, int (*finish)(DSA *)) +{ + meth->finish = finish; + return 1; +} +LCRYPTO_ALIAS(DSA_meth_set_finish); diff --git a/Libraries/libressl/crypto/dsa/dsa_ossl.c b/Libraries/libressl/crypto/dsa/dsa_ossl.c new file mode 100644 index 000000000..b92d0b8ce --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_ossl.c @@ -0,0 +1,477 @@ +/* $OpenBSD: dsa_ossl.c,v 1.53 2023/08/03 18:53:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include + +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "dsa_local.h" + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, + DSA *dsa); +static int dsa_init(DSA *dsa); +static int dsa_finish(DSA *dsa); + +static DSA_METHOD openssl_dsa_meth = { + .name = "OpenSSL DSA method", + .dsa_do_sign = dsa_do_sign, + .dsa_sign_setup = dsa_sign_setup, + .dsa_do_verify = dsa_do_verify, + .init = dsa_init, + .finish = dsa_finish, +}; + +const DSA_METHOD * +DSA_OpenSSL(void) +{ + return &openssl_dsa_meth; +} +LCRYPTO_ALIAS(DSA_OpenSSL); + +/* + * Since DSA parameters are entirely arbitrary and checking them to be + * consistent is very expensive, we cannot do so on every sign operation. + * Instead, cap the number of retries so we do not loop indefinitely if + * the generator of the multiplicative group happens to be nilpotent. + * The probability of needing a retry with valid parameters is negligible, + * so trying 32 times is amply enough. + */ +#define DSA_MAX_SIGN_ITERATIONS 32 + +static DSA_SIG * +dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + BIGNUM *b = NULL, *bm = NULL, *bxr = NULL, *binv = NULL, *m = NULL; + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BN_CTX *ctx = NULL; + int reason = ERR_R_BN_LIB; + DSA_SIG *ret = NULL; + int attempts = 0; + int noredo = 0; + + if (!dsa_check_key(dsa)) { + reason = DSA_R_INVALID_PARAMETERS; + goto err; + } + + if ((s = BN_new()) == NULL) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((binv = BN_CTX_get(ctx)) == NULL) + goto err; + if ((bm = BN_CTX_get(ctx)) == NULL) + goto err; + if ((bxr = BN_CTX_get(ctx)) == NULL) + goto err; + if ((m = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * If the digest length is greater than N (the bit length of q), the + * leftmost N bits of the digest shall be used, see FIPS 186-3, 4.2. + * In this case the digest length is given in bytes. + */ + if (dlen > BN_num_bytes(dsa->q)) + dlen = BN_num_bytes(dsa->q); + if (BN_bin2bn(dgst, dlen, m) == NULL) + goto err; + + redo: + if (dsa->kinv == NULL || dsa->r == NULL) { + if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) + goto err; + } else { + kinv = dsa->kinv; + dsa->kinv = NULL; + r = dsa->r; + dsa->r = NULL; + noredo = 1; + } + + /* + * Compute: + * + * s = inv(k)(m + xr) mod q + * + * In order to reduce the possibility of a side-channel attack, the + * following is calculated using a blinding value: + * + * s = inv(b)(bm + bxr)inv(k) mod q + * + * Where b is a random value in the range [1, q). + */ + if (!bn_rand_interval(b, 1, dsa->q)) + goto err; + if (BN_mod_inverse_ct(binv, b, dsa->q, ctx) == NULL) + goto err; + + if (!BN_mod_mul(bxr, b, dsa->priv_key, dsa->q, ctx)) /* bx */ + goto err; + if (!BN_mod_mul(bxr, bxr, r, dsa->q, ctx)) /* bxr */ + goto err; + if (!BN_mod_mul(bm, b, m, dsa->q, ctx)) /* bm */ + goto err; + if (!BN_mod_add(s, bxr, bm, dsa->q, ctx)) /* s = bm + bxr */ + goto err; + if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) /* s = b(m + xr)k^-1 */ + goto err; + if (!BN_mod_mul(s, s, binv, dsa->q, ctx)) /* s = (m + xr)k^-1 */ + goto err; + + /* + * Redo if r or s is zero as required by FIPS 186-3: this is very + * unlikely. + */ + if (BN_is_zero(r) || BN_is_zero(s)) { + if (noredo) { + reason = DSA_R_NEED_NEW_SETUP_VALUES; + goto err; + } + if (++attempts > DSA_MAX_SIGN_ITERATIONS) { + reason = DSA_R_INVALID_PARAMETERS; + goto err; + } + goto redo; + } + + if ((ret = DSA_SIG_new()) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + ret->r = r; + ret->s = s; + + err: + if (!ret) { + DSAerror(reason); + BN_free(r); + BN_free(s); + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_free(kinv); + + return ret; +} + +static int +dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +{ + BIGNUM *k = NULL, *l = NULL, *m = NULL, *kinv = NULL, *r = NULL; + BN_CTX *ctx = NULL; + int q_bits; + int ret = 0; + + if (!dsa_check_key(dsa)) + goto err; + + if ((r = BN_new()) == NULL) + goto err; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((k = BN_CTX_get(ctx)) == NULL) + goto err; + if ((l = BN_CTX_get(ctx)) == NULL) + goto err; + if ((m = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Preallocate space */ + q_bits = BN_num_bits(dsa->q); + if (!BN_set_bit(k, q_bits) || + !BN_set_bit(l, q_bits) || + !BN_set_bit(m, q_bits)) + goto err; + + if (!bn_rand_interval(k, 1, dsa->q)) + goto err; + + BN_set_flags(k, BN_FLG_CONSTTIME); + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) + goto err; + } + + /* Compute r = (g^k mod p) mod q */ + + /* + * We do not want timing information to leak the length of k, + * so we compute G^k using an equivalent exponent of fixed + * bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the modulus. + * + * TODO: revisit the bn_copy aiming for a memory access agnostic + * conditional copy. + */ + + if (!BN_add(l, k, dsa->q) || + !BN_add(m, l, dsa->q) || + !bn_copy(k, BN_num_bits(l) > q_bits ? l : m)) + goto err; + + if (dsa->meth->bn_mod_exp != NULL) { + if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx, + dsa->method_mont_p)) + goto err; + } else { + if (!BN_mod_exp_mont_ct(r, dsa->g, k, dsa->p, ctx, + dsa->method_mont_p)) + goto err; + } + + if (!BN_mod_ct(r, r, dsa->q, ctx)) + goto err; + + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv = BN_mod_inverse_ct(NULL, k, dsa->q, ctx)) == NULL) + goto err; + + BN_free(*kinvp); + *kinvp = kinv; + kinv = NULL; + + BN_free(*rp); + *rp = r; + + ret = 1; + + err: + if (!ret) { + DSAerror(ERR_R_BN_LIB); + BN_free(r); + } + BN_CTX_end(ctx); + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} + +static int +dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) +{ + BIGNUM *u1 = NULL, *u2 = NULL, *t1 = NULL; + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + int qbits; + int ret = -1; + + if (!dsa_check_key(dsa)) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((u1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((u2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((t1 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, dsa->q) >= 0) { + ret = 0; + goto err; + } + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || + BN_ucmp(sig->s, dsa->q) >= 0) { + ret = 0; + goto err; + } + + /* Calculate w = inv(s) mod q, saving w in u2. */ + if ((BN_mod_inverse_ct(u2, sig->s, dsa->q, ctx)) == NULL) + goto err; + + /* + * If the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see FIPS 186-4, 4.2. + */ + qbits = BN_num_bits(dsa->q); + if (dgst_len > (qbits >> 3)) + dgst_len = (qbits >> 3); + + /* Save m in u1. */ + if (BN_bin2bn(dgst, dgst_len, u1) == NULL) + goto err; + + /* u1 = m * w mod q */ + if (!BN_mod_mul(u1, u1, u2, dsa->q, ctx)) + goto err; + + /* u2 = r * w mod q */ + if (!BN_mod_mul(u2, sig->r, u2, dsa->q, ctx)) + goto err; + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx); + if (!mont) + goto err; + } + + if (dsa->meth->dsa_mod_exp != NULL) { + if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->g, u1, dsa->pub_key, + u2, dsa->p, ctx, mont)) + goto err; + } else { + if (!BN_mod_exp2_mont(t1, dsa->g, u1, dsa->pub_key, u2, + dsa->p, ctx, mont)) + goto err; + } + + /* let u1 = u1 mod q */ + if (!BN_mod_ct(u1, t1, dsa->q, ctx)) + goto err; + + /* v is in u1 - if the signature is correct, it will be equal to r. */ + ret = BN_ucmp(u1, sig->r) == 0; + + err: + if (ret < 0) + DSAerror(ERR_R_BN_LIB); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ret; +} + +static int +dsa_init(DSA *dsa) +{ + dsa->flags |= DSA_FLAG_CACHE_MONT_P; + return 1; +} + +static int +dsa_finish(DSA *dsa) +{ + BN_MONT_CTX_free(dsa->method_mont_p); + return 1; +} + +DSA_SIG * +DSA_SIG_new(void) +{ + return calloc(1, sizeof(DSA_SIG)); +} +LCRYPTO_ALIAS(DSA_SIG_new); + +void +DSA_SIG_free(DSA_SIG *sig) +{ + if (sig == NULL) + return; + + BN_free(sig->r); + BN_free(sig->s); + free(sig); +} +LCRYPTO_ALIAS(DSA_SIG_free); + +int +DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +{ + return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); +} +LCRYPTO_ALIAS(DSA_sign_setup); + +DSA_SIG * +DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + return dsa->meth->dsa_do_sign(dgst, dlen, dsa); +} +LCRYPTO_ALIAS(DSA_do_sign); + +int +DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) +{ + return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); +} +LCRYPTO_ALIAS(DSA_do_verify); diff --git a/Libraries/libressl/crypto/dsa/dsa_pmeth.c b/Libraries/libressl/crypto/dsa/dsa_pmeth.c new file mode 100644 index 000000000..9b03a2fc3 --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_pmeth.c @@ -0,0 +1,350 @@ +/* $OpenBSD: dsa_pmeth.c,v 1.17 2023/04/25 15:48:48 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "dsa_local.h" +#include "evp_local.h" + +/* DSA pkey context structure */ + +typedef struct { + /* Parameter gen parameters */ + int nbits; /* size of p in bits (default: 1024) */ + int qbits; /* size of q in bits (default: 160) */ + const EVP_MD *pmd; /* MD for parameter generation */ + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ + const EVP_MD *md; /* MD for the signature */ +} DSA_PKEY_CTX; + +static int +pkey_dsa_init(EVP_PKEY_CTX *ctx) +{ + DSA_PKEY_CTX *dctx; + + dctx = malloc(sizeof(DSA_PKEY_CTX)); + if (!dctx) + return 0; + dctx->nbits = 1024; + dctx->qbits = 160; + dctx->pmd = NULL; + dctx->md = NULL; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int +pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + DSA_PKEY_CTX *dctx, *sctx; + + if (!pkey_dsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + dctx->qbits = sctx->qbits; + dctx->pmd = sctx->pmd; + dctx->md = sctx->md; + return 1; +} + +static void +pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) +{ + DSA_PKEY_CTX *dctx = ctx->data; + + free(dctx); +} + +static int +pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *out_siglen, + const unsigned char *tbs, size_t tbslen) +{ + DSA *dsa = ctx->pkey->pkey.dsa; + DSA_PKEY_CTX *dctx = ctx->data; + unsigned int siglen; + + *out_siglen = 0; + + if (tbslen > INT_MAX) + return 0; + + if (dctx->md != NULL) { + if (tbslen != EVP_MD_size(dctx->md)) + return 0; + } + + if (!DSA_sign(0, tbs, tbslen, sig, &siglen, dsa)) + return 0; + + *out_siglen = siglen; + + return 1; +} + +static int +pkey_dsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + DSA *dsa = ctx->pkey->pkey.dsa; + DSA_PKEY_CTX *dctx = ctx->data; + + if (tbslen > INT_MAX || siglen > INT_MAX) + return 0; + + if (dctx->md != NULL) { + if (tbslen != EVP_MD_size(dctx->md)) + return 0; + } + + return DSA_verify(0, tbs, tbslen, sig, siglen, dsa); +} + +static int +pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + DSA_PKEY_CTX *dctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: + if (p1 < 256) + return -2; + dctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: + if (p1 != 160 && p1 != 224 && p1 && p1 != 256) + return -2; + dctx->qbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: + switch (EVP_MD_type((const EVP_MD *)p2)) { + case NID_sha1: + case NID_sha224: + case NID_sha256: + break; + default: + DSAerror(DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + /* ANSI X9.57 and NIST CSOR. */ + switch (EVP_MD_type((const EVP_MD *)p2)) { + case NID_sha1: + case NID_dsa: + case NID_dsaWithSHA: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_sha3_224: + case NID_sha3_256: + case NID_sha3_384: + case NID_sha3_512: + break; + default: + DSAerror(DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = dctx->md; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + DSAerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + default: + return -2; + } +} + +static int +pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + long lval; + char *ep; + + if (!strcmp(type, "dsa_paramgen_bits")) { + int nbits; + + errno = 0; + lval = strtol(value, &ep, 10); + if (value[0] == '\0' || *ep != '\0') + goto not_a_number; + if ((errno == ERANGE && + (lval == LONG_MAX || lval == LONG_MIN)) || + (lval > INT_MAX || lval < INT_MIN)) + goto out_of_range; + nbits = lval; + return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); + } else if (!strcmp(type, "dsa_paramgen_q_bits")) { + int qbits; + + errno = 0; + lval = strtol(value, &ep, 10); + if (value[0] == '\0' || *ep != '\0') + goto not_a_number; + if ((errno == ERANGE && + (lval == LONG_MAX || lval == LONG_MIN)) || + (lval > INT_MAX || lval < INT_MIN)) + goto out_of_range; + qbits = lval; + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, + EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, + qbits, NULL); + } else if (!strcmp(type, "dsa_paramgen_md")) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, + EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, + (void *)EVP_get_digestbyname(value)); + } +not_a_number: +out_of_range: + return -2; +} + +static int +pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa = NULL; + DSA_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + dsa = DSA_new(); + if (!dsa) + return 0; + ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, + NULL, 0, NULL, NULL, NULL, pcb); + if (ret) + EVP_PKEY_assign_DSA(pkey, dsa); + else + DSA_free(dsa); + return ret; +} + +static int +pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa = NULL; + + if (ctx->pkey == NULL) { + DSAerror(DSA_R_NO_PARAMETERS_SET); + return 0; + } + dsa = DSA_new(); + if (!dsa) + return 0; + EVP_PKEY_assign_DSA(pkey, dsa); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DSA_generate_key(pkey->pkey.dsa); +} + +const EVP_PKEY_METHOD dsa_pkey_meth = { + .pkey_id = EVP_PKEY_DSA, + .flags = EVP_PKEY_FLAG_AUTOARGLEN, + + .init = pkey_dsa_init, + .copy = pkey_dsa_copy, + .cleanup = pkey_dsa_cleanup, + + .paramgen = pkey_dsa_paramgen, + + .keygen = pkey_dsa_keygen, + + .sign = pkey_dsa_sign, + + .verify = pkey_dsa_verify, + + .ctrl = pkey_dsa_ctrl, + .ctrl_str = pkey_dsa_ctrl_str +}; diff --git a/Libraries/libressl/crypto/dsa/dsa_prn.c b/Libraries/libressl/crypto/dsa/dsa_prn.c new file mode 100644 index 000000000..f276d8248 --- /dev/null +++ b/Libraries/libressl/crypto/dsa/dsa_prn.c @@ -0,0 +1,135 @@ +/* $OpenBSD: dsa_prn.c,v 1.10 2023/07/08 14:28:15 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +int +DSA_print_fp(FILE *fp, const DSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DSAerror(ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DSA_print(b, x, off); + BIO_free(b); + return ret; +} +LCRYPTO_ALIAS(DSA_print_fp); + +int +DSAparams_print_fp(FILE *fp, const DSA *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DSAerror(ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DSAparams_print(b, x); + BIO_free(b); + return ret; +} +LCRYPTO_ALIAS(DSAparams_print_fp); + +int +DSA_print(BIO *bp, const DSA *x, int off) +{ + EVP_PKEY *pk; + int ret = 0; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + if (!EVP_PKEY_set1_DSA(pk, (DSA *)x)) + goto err; + + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + err: + EVP_PKEY_free(pk); + return ret; +} +LCRYPTO_ALIAS(DSA_print); + +int +DSAparams_print(BIO *bp, const DSA *x) +{ + EVP_PKEY *pk; + int ret = 0; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + if (!EVP_PKEY_set1_DSA(pk, (DSA *)x)) + goto err; + + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + err: + EVP_PKEY_free(pk); + return ret; +} +LCRYPTO_ALIAS(DSAparams_print); diff --git a/Libraries/libressl/crypto/ec/ec_ameth.c b/Libraries/libressl/crypto/ec/ec_ameth.c new file mode 100644 index 000000000..324865870 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_ameth.c @@ -0,0 +1,1071 @@ +/* $OpenBSD: ec_ameth.c,v 1.45 2023/09/24 08:08:54 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "ec_local.h" +#include "evp_local.h" + +#ifndef OPENSSL_NO_CMS +static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); +static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); +#endif + +static void +eckey_param_free(int ptype, void *pval) +{ + if (pval == NULL) + return; + if (ptype == V_ASN1_OBJECT) + ASN1_OBJECT_free(pval); /* XXX - really necessary? */ + else + ASN1_STRING_free(pval); +} + +static int +eckey_get_curve_name(const EC_KEY *eckey, int *nid) +{ + const EC_GROUP *group; + + *nid = NID_undef; + + if ((group = EC_KEY_get0_group(eckey)) == NULL) { + ECerror(EC_R_MISSING_PARAMETERS); + return 0; + } + if (EC_GROUP_get_asn1_flag(group) != 0) + *nid = EC_GROUP_get_curve_name(group); + + return 1; +} + +static int +eckey_to_explicit_params(EC_KEY *eckey, void **out_val) +{ + ASN1_STRING *astr = NULL; + unsigned char *params = NULL; + int params_len = 0; + int ret = 0; + + *out_val = NULL; + + if ((params_len = i2d_ECParameters(eckey, ¶ms)) <= 0) { + ECerror(ERR_R_EC_LIB); + params_len = 0; + goto err; + } + + if ((astr = ASN1_STRING_new()) == NULL) + goto err; + ASN1_STRING_set0(astr, params, params_len); + params = NULL; + params_len = 0; + + *out_val = astr; + astr = NULL; + + ret = 1; + + err: + freezero(params, params_len); + ASN1_STRING_free(astr); + + return ret; +} + +static int +eckey_from_explicit_params(const ASN1_STRING *astr, EC_KEY **out_eckey) +{ + const unsigned char *params = astr->data; + int params_len = astr->length; + + EC_KEY_free(*out_eckey); + if ((*out_eckey = d2i_ECParameters(NULL, ¶ms, params_len)) == NULL) { + ECerror(EC_R_DECODE_ERROR); + return 0; + } + + return 1; +} + +static int +eckey_to_object(const EC_KEY *eckey, void **out_val) +{ + int nid = NID_undef; + + *out_val = NULL; + + if (!eckey_get_curve_name(eckey, &nid)) + return 0; + if ((*out_val = OBJ_nid2obj(nid)) == NULL) + return 0; + + return 1; +} + +static int +eckey_from_object(const ASN1_OBJECT *aobj, EC_KEY **out_eckey) +{ + int nid; + + *out_eckey = NULL; + + if ((nid = OBJ_obj2nid(aobj)) == NID_undef) + return 0; + if ((*out_eckey = EC_KEY_new_by_curve_name(nid)) == NULL) + return 0; + + return 1; +} + +static int +eckey_to_params(EC_KEY *eckey, int *out_type, void **out_val) +{ + int nid; + + *out_type = NID_undef; + *out_val = NULL; + + if (!eckey_get_curve_name(eckey, &nid)) + return 0; + + if (nid == NID_undef) { + *out_type = V_ASN1_SEQUENCE; + return eckey_to_explicit_params(eckey, out_val); + } else { + *out_type = V_ASN1_OBJECT; + return eckey_to_object(eckey, out_val); + } +} + +static int +eckey_from_params(int ptype, const void *pval, EC_KEY **out_eckey) +{ + *out_eckey = NULL; + + if (ptype == V_ASN1_SEQUENCE) + return eckey_from_explicit_params(pval, out_eckey); + if (ptype == V_ASN1_OBJECT) + return eckey_from_object(pval, out_eckey); + + ECerror(EC_R_DECODE_ERROR); + return 0; +} + +static int +eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + int ptype = V_ASN1_UNDEF; + void *pval = NULL; + ASN1_OBJECT *aobj; + unsigned char *key = NULL; + int key_len = 0; + int ret = 0; + + if (!eckey_to_params(eckey, &ptype, &pval)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if ((key_len = i2o_ECPublicKey(eckey, &key)) <= 0) { + key_len = 0; + goto err; + } + if ((aobj = OBJ_nid2obj(EVP_PKEY_EC)) == NULL) + goto err; + if (!X509_PUBKEY_set0_param(pk, aobj, ptype, pval, key, key_len)) + goto err; + pval = NULL; + key = NULL; + key_len = 0; + + ret = 1; + + err: + eckey_param_free(ptype, pval); + freezero(key, key_len); + + return ret; +} + +static int +eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p = NULL; + const void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + int ret = 0; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + goto err; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (!eckey_from_params(ptype, pval, &eckey)) + goto err; + + if (!o2i_ECPublicKey(&eckey, &p, pklen)) { + ECerror(EC_R_DECODE_ERROR); + goto err; + } + if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) + goto err; + eckey = NULL; + + ret = 1; + + err: + EC_KEY_free(eckey); + + return ret; +} + +static int +eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec); + const EC_POINT *pb = EC_KEY_get0_public_key(b->pkey.ec); + int r; + + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) + return 1; + if (r == 1) + return 0; + return -2; +} + +static int +eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p = NULL; + const void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + const X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (!eckey_from_params(ptype, pval, &eckey)) + goto ecliberr; + + /* We have parameters now set private key */ + if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { + ECerror(EC_R_DECODE_ERROR); + goto ecerr; + } + /* calculate public key (if necessary) */ + if (EC_KEY_get0_public_key(eckey) == NULL) { + const BIGNUM *priv_key; + const EC_GROUP *group; + EC_POINT *pub_key; + /* + * the public key was not included in the SEC1 private key => + * calculate the public key + */ + group = EC_KEY_get0_group(eckey); + pub_key = EC_POINT_new(group); + if (pub_key == NULL) { + ECerror(ERR_R_EC_LIB); + goto ecliberr; + } + if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { + EC_POINT_free(pub_key); + ECerror(ERR_R_EC_LIB); + goto ecliberr; + } + priv_key = EC_KEY_get0_private_key(eckey); + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { + EC_POINT_free(pub_key); + ECerror(ERR_R_EC_LIB); + goto ecliberr; + } + if (EC_KEY_set_public_key(eckey, pub_key) == 0) { + EC_POINT_free(pub_key); + ECerror(ERR_R_EC_LIB); + goto ecliberr; + } + EC_POINT_free(pub_key); + } + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecliberr: + ECerror(ERR_R_EC_LIB); + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; +} + +static int +eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + void *pval = NULL; + int ptype = V_ASN1_UNDEF; + ASN1_OBJECT *aobj; + unsigned char *key = NULL; + int key_len = 0; + unsigned int flags; + int ret = 0; + + flags = EC_KEY_get_enc_flags(eckey); + + if (!eckey_to_params(eckey, &ptype, &pval)) { + ECerror(EC_R_DECODE_ERROR); + goto err; + } + + /* PKCS#11 12.11: don't include parameters in the SEC1 private key. */ + EC_KEY_set_enc_flags(eckey, flags | EC_PKEY_NO_PARAMETERS); + + if ((key_len = i2d_ECPrivateKey(eckey, &key)) <= 0) { + ECerror(ERR_R_EC_LIB); + key_len = 0; + goto err; + } + if ((aobj = OBJ_nid2obj(NID_X9_62_id_ecPublicKey)) == NULL) + goto err; + if (!PKCS8_pkey_set0(p8, aobj, 0, ptype, pval, key, key_len)) + goto err; + pval = NULL; + key = NULL; + key_len = 0; + + ret = 1; + + err: + eckey_param_free(ptype, pval); + freezero(key, key_len); + + EC_KEY_set_enc_flags(eckey, flags); + + return ret; +} + +static int +ec_size(const EVP_PKEY *pkey) +{ + return ECDSA_size(pkey->pkey.ec); +} + +static int +ec_bits(const EVP_PKEY *pkey) +{ + const EC_GROUP *group; + + if ((group = EC_KEY_get0_group(pkey->pkey.ec)) == NULL) + return 0; + + return EC_GROUP_order_bits(group); +} + +static int +ec_security_bits(const EVP_PKEY *pkey) +{ + int ecbits = ec_bits(pkey); + + if (ecbits >= 512) + return 256; + if (ecbits >= 384) + return 192; + if (ecbits >= 256) + return 128; + if (ecbits >= 224) + return 112; + if (ecbits >= 160) + return 80; + + return ecbits / 2; +} + +static int +ec_missing_parameters(const EVP_PKEY *pkey) +{ + if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) + return 1; + return 0; +} + +static int +ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec)); +} + +static int +ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec); + const EC_GROUP *group_b = EC_KEY_get0_group(b->pkey.ec); + + if (EC_GROUP_cmp(group_a, group_b, NULL)) + return 0; + else + return 1; +} + +static void +ec_free(EVP_PKEY *pkey) +{ + EC_KEY_free(pkey->pkey.ec); +} + +static int +do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) +{ + const char *ecstr; + int ret = 0, reason = ERR_R_BIO_LIB; + BIGNUM *pub_key = NULL; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + ctx = BN_CTX_new(); + if (ctx == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + if (ktype > 0) { + public_key = EC_KEY_get0_public_key(x); + if (public_key != NULL) { + if ((pub_key = EC_POINT_point2bn(group, public_key, + EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + } + } + if (ktype == 2) { + priv_key = EC_KEY_get0_private_key(x); + } else + priv_key = NULL; + + if (ktype == 2) + ecstr = "Private-Key"; + else if (ktype == 1) + ecstr = "Public-Key"; + else + ecstr = "ECDSA-Parameters"; + + if (!BIO_indent(bp, off, 128)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, + EC_GROUP_order_bits(group)) <= 0) + goto err; + + if (!bn_printf(bp, priv_key, off, "priv:")) + goto err; + if (!bn_printf(bp, pub_key, off, "pub: ")) + goto err; + if (!ECPKParameters_print(bp, group, off)) + goto err; + + ret = 1; + + err: + if (!ret) + ECerror(reason); + BN_free(pub_key); + BN_CTX_free(ctx); + + return (ret); +} + +static int +eckey_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + EC_KEY *eckey; + if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { + ECerror(ERR_R_EC_LIB); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; +} + +static int +eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_ECParameters(pkey->pkey.ec, pder); +} + +static int +eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); +} + +static int +eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); +} + + +static int +eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); +} + +static int +old_ec_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + EC_KEY *ec; + if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { + ECerror(EC_R_DECODE_ERROR); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +static int +old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_ECPrivateKey(pkey->pkey.ec, pder); +} + +static int +ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; + +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + X509_ALGOR *alg1, *alg2; + int snid, hnid; + + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 0) + return ecdh_cms_encrypt(arg2); + else if (arg1 == 1) + return ecdh_cms_decrypt(arg2); + return -2; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + *(int *)arg2 = CMS_RECIPINFO_AGREE; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *) arg2 = NID_sha1; + return 2; + + default: + return -2; + + } + +} + +static int +ec_pkey_check(const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + + if (eckey->priv_key == NULL) { + ECerror(EC_R_MISSING_PRIVATE_KEY); + return 0; + } + + return EC_KEY_check_key(eckey); +} + +static int +ec_pkey_public_check(const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + + /* This also checks the private key, but oh, well... */ + return EC_KEY_check_key(eckey); +} + +static int +ec_pkey_param_check(const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + + if (eckey->group == NULL) { + ECerror(EC_R_MISSING_PARAMETERS); + return 0; + } + + return EC_GROUP_check(eckey->group, NULL); +} + +#ifndef OPENSSL_NO_CMS + +static int +ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg, + ASN1_BIT_STRING *pubkey) +{ + const ASN1_OBJECT *aoid; + int atype; + const void *aval; + int rv = 0; + EVP_PKEY *pkpeer = NULL; + EC_KEY *ecpeer = NULL; + const unsigned char *p; + int plen; + + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) + goto err; + + /* If absent parameters get group from main key */ + if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { + const EC_GROUP *grp; + EVP_PKEY *pk; + + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (!pk) + goto err; + grp = EC_KEY_get0_group(pk->pkey.ec); + ecpeer = EC_KEY_new(); + if (ecpeer == NULL) + goto err; + if (!EC_KEY_set_group(ecpeer, grp)) + goto err; + } else { + if (!eckey_from_params(atype, aval, &ecpeer)) + goto err; + } + + /* We have parameters now set public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_get0_data(pubkey); + if (!p || !plen) + goto err; + if (!o2i_ECPublicKey(&ecpeer, &p, plen)) + goto err; + pkpeer = EVP_PKEY_new(); + if (pkpeer == NULL) + goto err; + EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + EC_KEY_free(ecpeer); + EVP_PKEY_free(pkpeer); + return rv; +} + +/* Set KDF parameters based on KDF NID */ +static int +ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) +{ + int kdf_nid, kdfmd_nid, cofactor; + const EVP_MD *kdf_md; + + if (eckdf_nid == NID_undef) + return 0; + + /* Lookup KDF type, cofactor mode and digest */ + if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) + return 0; + + if (kdf_nid == NID_dh_std_kdf) + cofactor = 0; + else if (kdf_nid == NID_dh_cofactor_kdf) + cofactor = 1; + else + return 0; + + if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) + return 0; + + kdf_md = EVP_get_digestbynid(kdfmd_nid); + if (!kdf_md) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + return 0; + + return 1; +} + +static int +ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *der = NULL; + int plen, keylen; + const EVP_CIPHER *kekcipher; + EVP_CIPHER_CTX *kekctx; + int rv = 0; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + return 0; + + if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { + ECerror(EC_R_KDF_PARAMETER_ERROR); + return 0; + } + + if (alg->parameter->type != V_ASN1_SEQUENCE) + return 0; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (!kekalg) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (!kekctx) + goto err; + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_key_length(kekctx); + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); + if (plen <= 0) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) + goto err; + der = NULL; + + rv = 1; + err: + X509_ALGOR_free(kekalg); + free(der); + return rv; +} + +static int +ecdh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (!alg || !pubkey) + return 0; + if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { + ECerror(EC_R_PEER_KEY_ERROR); + return 0; + } + } + + /* Set ECDH derivation parameters and initialise unwrap context */ + if (!ecdh_cms_set_shared_info(pctx, ri)) { + ECerror(EC_R_SHARED_INFO_ERROR); + return 0; + } + + return 1; +} + +static int +ecdh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + const ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL; + int penclen; + int ecdh_nid, kdf_type, kdf_nid, wrap_nid; + const EVP_MD *kdf_md; + int rv = 0; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + + /* Is everything uninitialised? */ + if (aoid == OBJ_nid2obj(NID_undef)) { + EC_KEY *eckey = pkey->pkey.ec; + unsigned char *p; + + /* Set the key */ + penclen = i2o_ECPublicKey(eckey, NULL); + if (penclen <= 0) + goto err; + penc = malloc(penclen); + if (penc == NULL) + goto err; + p = penc; + penclen = i2o_ECPublicKey(eckey, &p); + if (penclen <= 0) + goto err; + ASN1_STRING_set0(pubkey, penc, penclen); + if (!asn1_abs_set_unused_bits(pubkey, 0)) + goto err; + penc = NULL; + + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), + V_ASN1_UNDEF, NULL); + } + + /* See if custom parameters set */ + kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); + if (kdf_type <= 0) + goto err; + if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) + goto err; + ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); + if (ecdh_nid < 0) + goto err; + else if (ecdh_nid == 0) + ecdh_nid = NID_dh_std_kdf; + else if (ecdh_nid == 1) + ecdh_nid = NID_dh_cofactor_kdf; + + if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { + kdf_type = EVP_PKEY_ECDH_KDF_X9_63; + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else { + /* Unknown KDF */ + goto err; + } + if (kdf_md == NULL) { + /* Fixme later for better MD */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Lookup NID for KDF+cofactor+digest */ + if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) + goto err; + + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_type(ctx); + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (wrap_alg == NULL) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (wrap_alg->parameter == NULL) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); + if (penclen <= 0) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) + goto err; + penc = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (penclen <= 0) + goto err; + wrap_str = ASN1_STRING_new(); + if (wrap_str == NULL) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + free(penc); + X509_ALGOR_free(wrap_alg); + return rv; +} + +#endif + +const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { + .pkey_id = EVP_PKEY_EC, + .pkey_base_id = EVP_PKEY_EC, + + .pem_str = "EC", + .info = "OpenSSL EC algorithm", + + .pub_decode = eckey_pub_decode, + .pub_encode = eckey_pub_encode, + .pub_cmp = eckey_pub_cmp, + .pub_print = eckey_pub_print, + + .priv_decode = eckey_priv_decode, + .priv_encode = eckey_priv_encode, + .priv_print = eckey_priv_print, + + .pkey_size = ec_size, + .pkey_bits = ec_bits, + .pkey_security_bits = ec_security_bits, + + .param_decode = eckey_param_decode, + .param_encode = eckey_param_encode, + .param_missing = ec_missing_parameters, + .param_copy = ec_copy_parameters, + .param_cmp = ec_cmp_parameters, + .param_print = eckey_param_print, + + .pkey_free = ec_free, + .pkey_ctrl = ec_pkey_ctrl, + .old_priv_decode = old_ec_priv_decode, + .old_priv_encode = old_ec_priv_encode, + + .pkey_check = ec_pkey_check, + .pkey_public_check = ec_pkey_public_check, + .pkey_param_check = ec_pkey_param_check, +}; diff --git a/Libraries/libressl/crypto/ec/ec_asn1.c b/Libraries/libressl/crypto/ec/ec_asn1.c new file mode 100644 index 000000000..683ca1741 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_asn1.c @@ -0,0 +1,1411 @@ +/* $OpenBSD: ec_asn1.c,v 1.48 2023/07/07 19:37:53 beck Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include + +#include "asn1_local.h" +#include "ec_local.h" + +int +EC_GROUP_get_basis_type(const EC_GROUP *group) +{ + return 0; +} +LCRYPTO_ALIAS(EC_GROUP_get_basis_type); + +/* some structures needed for the asn1 encoding */ +typedef struct x9_62_pentanomial_st { + long k1; + long k2; + long k3; +} X9_62_PENTANOMIAL; + +typedef struct x9_62_characteristic_two_st { + long m; + ASN1_OBJECT *type; + union { + char *ptr; + /* NID_X9_62_onBasis */ + ASN1_NULL *onBasis; + /* NID_X9_62_tpBasis */ + ASN1_INTEGER *tpBasis; + /* NID_X9_62_ppBasis */ + X9_62_PENTANOMIAL *ppBasis; + /* anything else */ + ASN1_TYPE *other; + } p; +} X9_62_CHARACTERISTIC_TWO; + +typedef struct x9_62_fieldid_st { + ASN1_OBJECT *fieldType; + union { + char *ptr; + /* NID_X9_62_prime_field */ + ASN1_INTEGER *prime; + /* NID_X9_62_characteristic_two_field */ + X9_62_CHARACTERISTIC_TWO *char_two; + /* anything else */ + ASN1_TYPE *other; + } p; +} X9_62_FIELDID; + +typedef struct x9_62_curve_st { + ASN1_OCTET_STRING *a; + ASN1_OCTET_STRING *b; + ASN1_BIT_STRING *seed; +} X9_62_CURVE; + +typedef struct ec_parameters_st { + long version; + X9_62_FIELDID *fieldID; + X9_62_CURVE *curve; + ASN1_OCTET_STRING *base; + ASN1_INTEGER *order; + ASN1_INTEGER *cofactor; +} ECPARAMETERS; + +struct ecpk_parameters_st { + int type; + union { + ASN1_OBJECT *named_curve; + ECPARAMETERS *parameters; + ASN1_NULL *implicitlyCA; + } value; +} /* ECPKPARAMETERS */ ; + +/* SEC1 ECPrivateKey */ +typedef struct ec_privatekey_st { + long version; + ASN1_OCTET_STRING *privateKey; + ECPKPARAMETERS *parameters; + ASN1_BIT_STRING *publicKey; +} EC_PRIVATEKEY; + +/* the OpenSSL ASN.1 definitions */ +static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_PENTANOMIAL, k1), + .field_name = "k1", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_PENTANOMIAL, k2), + .field_name = "k2", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_PENTANOMIAL, k3), + .field_name = "k3", + .item = &LONG_it, + }, +}; + +const ASN1_ITEM X9_62_PENTANOMIAL_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = X9_62_PENTANOMIAL_seq_tt, + .tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(X9_62_PENTANOMIAL), + .sname = "X9_62_PENTANOMIAL", +}; + +X9_62_PENTANOMIAL *X9_62_PENTANOMIAL_new(void); +void X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a); + +X9_62_PENTANOMIAL * +X9_62_PENTANOMIAL_new(void) +{ + return (X9_62_PENTANOMIAL*)ASN1_item_new(&X9_62_PENTANOMIAL_it); +} + +void +X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &X9_62_PENTANOMIAL_it); +} + +static const ASN1_TEMPLATE char_two_def_tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other), + .field_name = "p.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = { + { + .value = NID_X9_62_onBasis, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis), + .field_name = "p.onBasis", + .item = &ASN1_NULL_it, + }, + }, + { + .value = NID_X9_62_tpBasis, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis), + .field_name = "p.tpBasis", + .item = &ASN1_INTEGER_it, + }, + }, + { + .value = NID_X9_62_ppBasis, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis), + .field_name = "p.ppBasis", + .item = &X9_62_PENTANOMIAL_it, + }, + + }, +}; + +static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = { + .flags = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type), + .tbl = X9_62_CHARACTERISTIC_TWO_adbtbl, + .tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &char_two_def_tt, + .null_tt = NULL, +}; + +static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, m), + .field_name = "m", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type), + .field_name = "type", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "X9_62_CHARACTERISTIC_TWO", + .item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb, + }, +}; + +const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = X9_62_CHARACTERISTIC_TWO_seq_tt, + .tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(X9_62_CHARACTERISTIC_TWO), + .sname = "X9_62_CHARACTERISTIC_TWO", +}; + +X9_62_CHARACTERISTIC_TWO *X9_62_CHARACTERISTIC_TWO_new(void); +void X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a); + +X9_62_CHARACTERISTIC_TWO * +X9_62_CHARACTERISTIC_TWO_new(void) +{ + return (X9_62_CHARACTERISTIC_TWO*)ASN1_item_new(&X9_62_CHARACTERISTIC_TWO_it); +} + +void +X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &X9_62_CHARACTERISTIC_TWO_it); +} + +static const ASN1_TEMPLATE fieldID_def_tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_FIELDID, p.other), + .field_name = "p.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = { + { + .value = NID_X9_62_prime_field, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_FIELDID, p.prime), + .field_name = "p.prime", + .item = &ASN1_INTEGER_it, + }, + }, + { + .value = NID_X9_62_characteristic_two_field, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_FIELDID, p.char_two), + .field_name = "p.char_two", + .item = &X9_62_CHARACTERISTIC_TWO_it, + }, + }, +}; + +static const ASN1_ADB X9_62_FIELDID_adb = { + .flags = 0, + .offset = offsetof(X9_62_FIELDID, fieldType), + .tbl = X9_62_FIELDID_adbtbl, + .tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &fieldID_def_tt, + .null_tt = NULL, +}; + +static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_FIELDID, fieldType), + .field_name = "fieldType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "X9_62_FIELDID", + .item = (const ASN1_ITEM *)&X9_62_FIELDID_adb, + }, +}; + +const ASN1_ITEM X9_62_FIELDID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = X9_62_FIELDID_seq_tt, + .tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(X9_62_FIELDID), + .sname = "X9_62_FIELDID", +}; + +static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CURVE, a), + .field_name = "a", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(X9_62_CURVE, b), + .field_name = "b", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(X9_62_CURVE, seed), + .field_name = "seed", + .item = &ASN1_BIT_STRING_it, + }, +}; + +const ASN1_ITEM X9_62_CURVE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = X9_62_CURVE_seq_tt, + .tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(X9_62_CURVE), + .sname = "X9_62_CURVE", +}; + +static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPARAMETERS, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPARAMETERS, fieldID), + .field_name = "fieldID", + .item = &X9_62_FIELDID_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPARAMETERS, curve), + .field_name = "curve", + .item = &X9_62_CURVE_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPARAMETERS, base), + .field_name = "base", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPARAMETERS, order), + .field_name = "order", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ECPARAMETERS, cofactor), + .field_name = "cofactor", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM ECPARAMETERS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ECPARAMETERS_seq_tt, + .tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ECPARAMETERS), + .sname = "ECPARAMETERS", +}; + +ECPARAMETERS *ECPARAMETERS_new(void); +void ECPARAMETERS_free(ECPARAMETERS *a); + +ECPARAMETERS * +ECPARAMETERS_new(void) +{ + return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it); +} + +void +ECPARAMETERS_free(ECPARAMETERS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it); +} + +static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPKPARAMETERS, value.named_curve), + .field_name = "value.named_curve", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPKPARAMETERS, value.parameters), + .field_name = "value.parameters", + .item = &ECPARAMETERS_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECPKPARAMETERS, value.implicitlyCA), + .field_name = "value.implicitlyCA", + .item = &ASN1_NULL_it, + }, +}; + +const ASN1_ITEM ECPKPARAMETERS_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(ECPKPARAMETERS, type), + .templates = ECPKPARAMETERS_ch_tt, + .tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ECPKPARAMETERS), + .sname = "ECPKPARAMETERS", +}; + +ECPKPARAMETERS *ECPKPARAMETERS_new(void); +void ECPKPARAMETERS_free(ECPKPARAMETERS *a); +ECPKPARAMETERS *d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len); +int i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out); + +ECPKPARAMETERS * +d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len) +{ + return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ECPKPARAMETERS_it); +} + +int +i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it); +} + +ECPKPARAMETERS * +ECPKPARAMETERS_new(void) +{ + return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it); +} + +void +ECPKPARAMETERS_free(ECPKPARAMETERS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it); +} + +static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(EC_PRIVATEKEY, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(EC_PRIVATEKEY, privateKey), + .field_name = "privateKey", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(EC_PRIVATEKEY, parameters), + .field_name = "parameters", + .item = &ECPKPARAMETERS_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(EC_PRIVATEKEY, publicKey), + .field_name = "publicKey", + .item = &ASN1_BIT_STRING_it, + }, +}; + +const ASN1_ITEM EC_PRIVATEKEY_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = EC_PRIVATEKEY_seq_tt, + .tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(EC_PRIVATEKEY), + .sname = "EC_PRIVATEKEY", +}; + +EC_PRIVATEKEY *EC_PRIVATEKEY_new(void); +void EC_PRIVATEKEY_free(EC_PRIVATEKEY *a); +EC_PRIVATEKEY *d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len); +int i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out); + +EC_PRIVATEKEY * +d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len) +{ + return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &EC_PRIVATEKEY_it); +} + +int +i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it); +} + +EC_PRIVATEKEY * +EC_PRIVATEKEY_new(void) +{ + return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it); +} + +void +EC_PRIVATEKEY_free(EC_PRIVATEKEY *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it); +} + +/* some declarations of internal function */ + +/* ec_asn1_group2fieldid() sets the values in a X9_62_FIELDID object */ +static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); +/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ +static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); +/* ec_asn1_parameters2group() creates a EC_GROUP object from a + * ECPARAMETERS object */ +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); +/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a + * EC_GROUP object */ +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, ECPARAMETERS *); +/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a + * ECPKPARAMETERS object */ +static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); +/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a + * EC_GROUP object */ +static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, + ECPKPARAMETERS *); + +/* the function definitions */ + +static int +ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) +{ + int ok = 0, nid; + BIGNUM *tmp = NULL; + + if (group == NULL || field == NULL) + return 0; + + /* clear the old values (if necessary) */ + if (field->fieldType != NULL) + ASN1_OBJECT_free(field->fieldType); + if (field->p.other != NULL) + ASN1_TYPE_free(field->p.other); + + nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + /* set OID for the field */ + if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { + ECerror(ERR_R_OBJ_LIB); + goto err; + } + if (nid == NID_X9_62_prime_field) { + if ((tmp = BN_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + /* the parameters are specified by the prime number p */ + if (!EC_GROUP_get_curve(group, tmp, NULL, NULL, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* set the prime number */ + field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); + if (field->p.prime == NULL) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + } else { + ECerror(EC_R_GF2M_NOT_SUPPORTED); + goto err; + } + + ok = 1; + + err: + BN_free(tmp); + return (ok); +} + +static int +ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) +{ + BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; + unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL, + *b_buf = NULL; + size_t len_1, len_2; + unsigned char char_zero = 0; + int ok = 0; + + if (!group || !curve || !curve->a || !curve->b) + return 0; + + if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get a and b */ + if (!EC_GROUP_get_curve(group, NULL, tmp_1, tmp_2, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + len_1 = (size_t) BN_num_bytes(tmp_1); + len_2 = (size_t) BN_num_bytes(tmp_2); + + if (len_1 == 0) { + /* len_1 == 0 => a == 0 */ + a_buf = &char_zero; + len_1 = 1; + } else { + if ((buffer_1 = malloc(len_1)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { + ECerror(ERR_R_BN_LIB); + goto err; + } + a_buf = buffer_1; + } + + if (len_2 == 0) { + /* len_2 == 0 => b == 0 */ + b_buf = &char_zero; + len_2 = 1; + } else { + if ((buffer_2 = malloc(len_2)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { + ECerror(ERR_R_BN_LIB); + goto err; + } + b_buf = buffer_2; + } + + /* set a and b */ + if (!ASN1_STRING_set(curve->a, a_buf, len_1) || + !ASN1_STRING_set(curve->b, b_buf, len_2)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + + ASN1_BIT_STRING_free(curve->seed); + curve->seed = NULL; + + /* set the seed (optional) */ + if (group->seed != NULL) { + if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ASN1_BIT_STRING_set(curve->seed, group->seed, + (int) group->seed_len)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + if (!asn1_abs_set_unused_bits(curve->seed, 0)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + } + + ok = 1; + + err: + free(buffer_1); + free(buffer_2); + BN_free(tmp_1); + BN_free(tmp_2); + return (ok); +} + +static ECPARAMETERS * +ec_asn1_group2parameters(const EC_GROUP *group, ECPARAMETERS *param) +{ + int ok = 0; + size_t len = 0; + ECPARAMETERS *ret = NULL; + BIGNUM *tmp = NULL; + unsigned char *buffer = NULL; + const EC_POINT *point = NULL; + point_conversion_form_t form; + + if ((tmp = BN_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (param == NULL) { + if ((ret = ECPARAMETERS_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = param; + + /* set the version (always one) */ + ret->version = (long) 0x1; + + /* set the fieldID */ + if (!ec_asn1_group2fieldid(group, ret->fieldID)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* set the curve */ + if (!ec_asn1_group2curve(group, ret->curve)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* set the base point */ + if ((point = EC_GROUP_get0_generator(group)) == NULL) { + ECerror(EC_R_UNDEFINED_GENERATOR); + goto err; + } + form = EC_GROUP_get_point_conversion_form(group); + + len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); + if (len == 0) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if ((buffer = malloc(len)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + /* set the order */ + if (!EC_GROUP_get_order(group, tmp, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); + if (ret->order == NULL) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + /* set the cofactor (optional) */ + if (EC_GROUP_get_cofactor(group, tmp, NULL)) { + ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); + if (ret->cofactor == NULL) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + } + ok = 1; + + err: + if (!ok) { + if (ret && !param) + ECPARAMETERS_free(ret); + ret = NULL; + } + BN_free(tmp); + free(buffer); + return (ret); +} + +ECPKPARAMETERS * +ec_asn1_group2pkparameters(const EC_GROUP *group, ECPKPARAMETERS *params) +{ + int ok = 1, tmp; + ECPKPARAMETERS *ret = params; + + if (ret == NULL) { + if ((ret = ECPKPARAMETERS_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + if (ret->type == 0 && ret->value.named_curve) + ASN1_OBJECT_free(ret->value.named_curve); + else if (ret->type == 1 && ret->value.parameters) + ECPARAMETERS_free(ret->value.parameters); + } + + if (EC_GROUP_get_asn1_flag(group)) { + /* + * use the asn1 OID to describe the elliptic curve + * parameters + */ + tmp = EC_GROUP_get_curve_name(group); + if (tmp) { + ret->type = 0; + if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) + ok = 0; + } else + /* we don't know the group => ERROR */ + ok = 0; + } else { + /* use the ECPARAMETERS structure */ + ret->type = 1; + if ((ret->value.parameters = ec_asn1_group2parameters(group, + NULL)) == NULL) + ok = 0; + } + + if (!ok) { + ECPKPARAMETERS_free(ret); + return NULL; + } + return ret; +} + +static EC_GROUP * +ec_asn1_parameters2group(const ECPARAMETERS *params) +{ + int ok = 0, tmp; + EC_GROUP *ret = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + EC_POINT *point = NULL; + long field_bits; + + if (!params->fieldID || !params->fieldID->fieldType || + !params->fieldID->p.ptr) { + ECerror(EC_R_ASN1_ERROR); + goto err; + } + /* now extract the curve parameters a and b */ + if (!params->curve || !params->curve->a || + !params->curve->a->data || !params->curve->b || + !params->curve->b->data) { + ECerror(EC_R_ASN1_ERROR); + goto err; + } + a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); + if (a == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); + if (b == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + /* get the field parameters */ + tmp = OBJ_obj2nid(params->fieldID->fieldType); + if (tmp == NID_X9_62_characteristic_two_field) { + ECerror(EC_R_GF2M_NOT_SUPPORTED); + goto err; + } else if (tmp == NID_X9_62_prime_field) { + /* we have a curve over a prime field */ + /* extract the prime number */ + if (!params->fieldID->p.prime) { + ECerror(EC_R_ASN1_ERROR); + goto err; + } + p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); + if (p == NULL) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + if (BN_is_negative(p) || BN_is_zero(p)) { + ECerror(EC_R_INVALID_FIELD); + goto err; + } + field_bits = BN_num_bits(p); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerror(EC_R_FIELD_TOO_LARGE); + goto err; + } + /* create the EC_GROUP structure */ + ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); + } else { + ECerror(EC_R_INVALID_FIELD); + goto err; + } + + if (ret == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* extract seed (optional) */ + if (params->curve->seed != NULL) { + free(ret->seed); + if (!(ret->seed = malloc(params->curve->seed->length))) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(ret->seed, params->curve->seed->data, + params->curve->seed->length); + ret->seed_len = params->curve->seed->length; + } + if (!params->order || !params->base || !params->base->data) { + ECerror(EC_R_ASN1_ERROR); + goto err; + } + if ((point = EC_POINT_new(ret)) == NULL) + goto err; + + /* set the point conversion form */ + EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) + (params->base->data[0] & ~0x01)); + + /* extract the ec point */ + if (!EC_POINT_oct2point(ret, point, params->base->data, + params->base->length, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* extract the order */ + if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + if (BN_is_negative(a) || BN_is_zero(a)) { + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (BN_num_bits(a) > (int) field_bits + 1) { /* Hasse bound */ + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + /* extract the cofactor (optional) */ + if (params->cofactor == NULL) { + BN_free(b); + b = NULL; + } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + /* set the generator, order and cofactor (if present) */ + if (!EC_GROUP_set_generator(ret, point, a, b)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + ok = 1; + + err: + if (!ok) { + EC_GROUP_free(ret); + ret = NULL; + } + BN_free(p); + BN_free(a); + BN_free(b); + EC_POINT_free(point); + return (ret); +} + +EC_GROUP * +ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) +{ + EC_GROUP *ret = NULL; + int tmp = 0; + + if (params == NULL) { + ECerror(EC_R_MISSING_PARAMETERS); + return NULL; + } + if (params->type == 0) {/* the curve is given by an OID */ + tmp = OBJ_obj2nid(params->value.named_curve); + if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { + ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); + return NULL; + } + EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); + } else if (params->type == 1) { /* the parameters are given by a + * ECPARAMETERS structure */ + ret = ec_asn1_parameters2group(params->value.parameters); + if (!ret) { + ECerror(ERR_R_EC_LIB); + return NULL; + } + EC_GROUP_set_asn1_flag(ret, 0x0); + } else if (params->type == 2) { /* implicitlyCA */ + return NULL; + } else { + ECerror(EC_R_ASN1_ERROR); + return NULL; + } + + return ret; +} + +/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ + +EC_GROUP * +d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) +{ + EC_GROUP *group = NULL; + ECPKPARAMETERS *params; + + if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) { + ECerror(EC_R_D2I_ECPKPARAMETERS_FAILURE); + goto err; + } + if ((group = ec_asn1_pkparameters2group(params)) == NULL) { + ECerror(EC_R_PKPARAMETERS2GROUP_FAILURE); + goto err; + } + + if (a != NULL) { + EC_GROUP_free(*a); + *a = group; + } + + err: + ECPKPARAMETERS_free(params); + return (group); +} +LCRYPTO_ALIAS(d2i_ECPKParameters); + +int +i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) +{ + int ret = 0; + ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); + if (tmp == NULL) { + ECerror(EC_R_GROUP2PKPARAMETERS_FAILURE); + return 0; + } + if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { + ECerror(EC_R_I2D_ECPKPARAMETERS_FAILURE); + ECPKPARAMETERS_free(tmp); + return 0; + } + ECPKPARAMETERS_free(tmp); + return (ret); +} +LCRYPTO_ALIAS(i2d_ECPKParameters); + +/* some EC_KEY functions */ + +EC_KEY * +d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret = NULL; + EC_PRIVATEKEY *priv_key = NULL; + + if ((priv_key = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) { + ECerror(ERR_R_EC_LIB); + return NULL; + } + if (a == NULL || *a == NULL) { + if ((ret = EC_KEY_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = *a; + + if (priv_key->parameters) { + EC_GROUP_free(ret->group); + ret->group = ec_asn1_pkparameters2group(priv_key->parameters); + } + if (ret->group == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + ret->version = priv_key->version; + + if (priv_key->privateKey) { + ret->priv_key = BN_bin2bn( + ASN1_STRING_data(priv_key->privateKey), + ASN1_STRING_length(priv_key->privateKey), + ret->priv_key); + if (ret->priv_key == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + } else { + ECerror(EC_R_MISSING_PRIVATE_KEY); + goto err; + } + + if (ret->pub_key) + EC_POINT_free(ret->pub_key); + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + if (priv_key->publicKey) { + const unsigned char *pub_oct; + size_t pub_oct_len; + + pub_oct = ASN1_STRING_data(priv_key->publicKey); + pub_oct_len = ASN1_STRING_length(priv_key->publicKey); + if (pub_oct == NULL || pub_oct_len <= 0) { + ECerror(EC_R_BUFFER_TOO_SMALL); + goto err; + } + + /* save the point conversion form */ + ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); + if (!EC_POINT_oct2point(ret->group, ret->pub_key, + pub_oct, pub_oct_len, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + } else { + if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, + NULL, NULL, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* Remember the original private-key-only encoding. */ + ret->enc_flag |= EC_PKEY_NO_PUBKEY; + } + + EC_PRIVATEKEY_free(priv_key); + if (a != NULL) + *a = ret; + return (ret); + + err: + if (a == NULL || *a != ret) + EC_KEY_free(ret); + if (priv_key) + EC_PRIVATEKEY_free(priv_key); + + return (NULL); +} +LCRYPTO_ALIAS(d2i_ECPrivateKey); + +int +i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) +{ + int ret = 0, ok = 0; + unsigned char *buffer = NULL; + size_t buf_len = 0, tmp_len; + EC_PRIVATEKEY *priv_key = NULL; + + if (a == NULL || a->group == NULL || a->priv_key == NULL || + (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + priv_key->version = a->version; + + buf_len = (size_t) BN_num_bytes(a->priv_key); + buffer = malloc(buf_len); + if (buffer == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!BN_bn2bin(a->priv_key, buffer)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!ASN1_STRING_set(priv_key->privateKey, buffer, buf_len)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { + if ((priv_key->parameters = ec_asn1_group2pkparameters( + a->group, priv_key->parameters)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + } + if (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key != NULL) { + priv_key->publicKey = ASN1_BIT_STRING_new(); + if (priv_key->publicKey == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + tmp_len = EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, NULL, 0, NULL); + + if (tmp_len > buf_len) { + unsigned char *tmp_buffer = realloc(buffer, tmp_len); + if (!tmp_buffer) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + buffer = tmp_buffer; + buf_len = tmp_len; + } + if (!EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, buffer, buf_len, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (!ASN1_STRING_set(priv_key->publicKey, buffer, buf_len)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + if (!asn1_abs_set_unused_bits(priv_key->publicKey, 0)) { + ECerror(ERR_R_ASN1_LIB); + goto err; + } + } + if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { + ECerror(ERR_R_EC_LIB); + goto err; + } + ok = 1; + err: + free(buffer); + if (priv_key) + EC_PRIVATEKEY_free(priv_key); + return (ok ? ret : 0); +} +LCRYPTO_ALIAS(i2d_ECPrivateKey); + +int +i2d_ECParameters(EC_KEY *a, unsigned char **out) +{ + if (a == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return i2d_ECPKParameters(a->group, out); +} +LCRYPTO_ALIAS(i2d_ECParameters); + +EC_KEY * +d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret; + + if (in == NULL || *in == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (a == NULL || *a == NULL) { + if ((ret = EC_KEY_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + } else + ret = *a; + + if (!d2i_ECPKParameters(&ret->group, in, len)) { + ECerror(ERR_R_EC_LIB); + if (a == NULL || *a != ret) + EC_KEY_free(ret); + return NULL; + } + + if (a != NULL) + *a = ret; + return ret; +} +LCRYPTO_ALIAS(d2i_ECParameters); + +EC_KEY * +o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret = NULL; + + if (a == NULL || (*a) == NULL || (*a)->group == NULL) { + /* An EC_GROUP structure is necessary to set the public key. */ + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ret = *a; + if (ret->pub_key == NULL && + (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return 0; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { + ECerror(ERR_R_EC_LIB); + return 0; + } + /* save the point conversion form */ + ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); + *in += len; + return ret; +} +LCRYPTO_ALIAS(o2i_ECPublicKey); + +int +i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) +{ + size_t buf_len = 0; + int new_buffer = 0; + + if (a == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + buf_len = EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, NULL, 0, NULL); + + if (out == NULL || buf_len == 0) + /* out == NULL => just return the length of the octet string */ + return buf_len; + + if (*out == NULL) { + if ((*out = malloc(buf_len)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return 0; + } + new_buffer = 1; + } + if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, + *out, buf_len, NULL)) { + ECerror(ERR_R_EC_LIB); + if (new_buffer) { + free(*out); + *out = NULL; + } + return 0; + } + if (!new_buffer) + *out += buf_len; + return buf_len; +} +LCRYPTO_ALIAS(i2o_ECPublicKey); diff --git a/Libraries/libressl/crypto/ec/ec_check.c b/Libraries/libressl/crypto/ec/ec_check.c new file mode 100644 index 000000000..0f98ef613 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_check.c @@ -0,0 +1,112 @@ +/* $OpenBSD: ec_check.c,v 1.15 2023/07/07 13:54:45 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ec_local.h" +#include + +int +EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + EC_POINT *point = NULL; + const BIGNUM *order; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + /* check the discriminant */ + if (!EC_GROUP_check_discriminant(group, ctx)) { + ECerror(EC_R_DISCRIMINANT_IS_ZERO); + goto err; + } + /* check the generator */ + if (group->generator == NULL) { + ECerror(EC_R_UNDEFINED_GENERATOR); + goto err; + } + if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { + ECerror(EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + /* check the order of the generator */ + if ((point = EC_POINT_new(group)) == NULL) + goto err; + if ((order = EC_GROUP_get0_order(group)) == NULL) + goto err; + if (BN_is_zero(order)) { + ECerror(EC_R_UNDEFINED_ORDER); + goto err; + } + if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) + goto err; + if (EC_POINT_is_at_infinity(group, point) <= 0) { + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + + ret = 1; + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + EC_POINT_free(point); + + return ret; +} +LCRYPTO_ALIAS(EC_GROUP_check); diff --git a/Libraries/libressl/crypto/ec/ec_curve.c b/Libraries/libressl/crypto/ec/ec_curve.c new file mode 100644 index 000000000..9d19628b3 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_curve.c @@ -0,0 +1,3193 @@ +/* $OpenBSD: ec_curve.c,v 1.42 2023/07/07 13:54:45 beck Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include + +#include + +#include +#include + +#include "ec_local.h" + +/* the nist prime curves */ +static const struct { + uint8_t seed[20]; + uint8_t p[24]; + uint8_t a[24]; + uint8_t b[24]; + uint8_t x[24]; + uint8_t y[24]; + uint8_t order[24]; +} _EC_NIST_PRIME_192 = { + .seed = { + 0x30, 0x45, 0xae, 0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, + 0x95, 0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96, 0xd5, + }, + .p = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c, 0x80, 0xe7, 0x0f, 0xa7, + 0xe9, 0xab, 0x72, 0x24, 0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, + 0xc1, 0x46, 0xb9, 0xb1, + }, + .x = { + 0x18, 0x8d, 0xa8, 0x0e, 0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, + 0x20, 0xeb, 0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd, + 0x82, 0xff, 0x10, 0x12, + }, + .y = { + 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, + 0x11, 0xed, 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, + 0x1e, 0x79, 0x48, 0x11, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14, 0x6b, 0xc9, 0xb1, + 0xb4, 0xd2, 0x28, 0x31, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[28]; + uint8_t a[28]; + uint8_t b[28]; + uint8_t x[28]; + uint8_t y[28]; + uint8_t order[28]; +} _EC_NIST_PRIME_224 = { + .seed = { + 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7, 0xfc, 0xdc, 0x45, + 0xb5, 0x9f, 0xa3, 0xb9, 0xab, 0x8f, 0x6a, 0x94, 0x8b, 0xc5, + }, + .p = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .a = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + }, + .b = { + 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41, + 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, + 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, + }, + .x = { + 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, + 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22, + 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21, + }, + .y = { + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, + 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, + 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, + 0x13, 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[48]; + uint8_t a[48]; + uint8_t b[48]; + uint8_t x[48]; + uint8_t y[48]; + uint8_t order[48]; +} _EC_NIST_PRIME_384 = { + .seed = { + 0xa3, 0x35, 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00, + 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd, 0xac, 0x73, + }, + .p = { + 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, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 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, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e, + 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, + 0xfe, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, + 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d, + 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef, + }, + .x = { + 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, + }, + .y = { + 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, + }, + .order = { + 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 struct { + uint8_t seed[20]; + uint8_t p[66]; + uint8_t a[66]; + uint8_t b[66]; + uint8_t x[66]; + uint8_t y[66]; + uint8_t order[66]; +} _EC_NIST_PRIME_521 = { + .seed = { + 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, + 0x67, 0x17, 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, + }, + .p = { + 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, 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, 0xff, + }, + .a = { + 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, 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, 0xfc, + }, + .b = { + 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 0x1f, + 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, + 0x72, 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, + 0x8e, 0xf1, 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, + 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf, 0x07, + 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 0xf1, 0xef, 0x45, + 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, + }, + .x = { + 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, + }, + .y = { + 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, + }, + .order = { + 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, + }, +}; + +/* the x9.62 prime curves (minus the nist prime curves) */ +static const struct { + uint8_t seed[20]; + uint8_t p[24]; + uint8_t a[24]; + uint8_t b[24]; + uint8_t x[24]; + uint8_t y[24]; + uint8_t order[24]; +} _EC_X9_62_PRIME_192V2 = { + .seed = { + 0x31, 0xa9, 0x2e, 0xe2, 0x02, 0x9f, 0xd1, 0x0d, 0x90, 0x1b, + 0x11, 0x3e, 0x99, 0x07, 0x10, 0xf0, 0xd2, 0x1a, 0xc6, 0xb6, + }, + .p = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0xcc, 0x22, 0xd6, 0xdf, 0xb9, 0x5c, 0x6b, 0x25, 0xe4, 0x9c, + 0x0d, 0x63, 0x64, 0xa4, 0xe5, 0x98, 0x0c, 0x39, 0x3a, 0xa2, + 0x16, 0x68, 0xd9, 0x53, + }, + .x = { + 0xee, 0xa2, 0xba, 0xe7, 0xe1, 0x49, 0x78, 0x42, 0xf2, 0xde, + 0x77, 0x69, 0xcf, 0xe9, 0xc9, 0x89, 0xc0, 0x72, 0xad, 0x69, + 0x6f, 0x48, 0x03, 0x4a, + }, + .y = { + 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, + 0xb8, 0x2a, 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9, + 0x70, 0xb2, 0xde, 0x15, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x5f, 0xb1, 0xa7, 0x24, 0xdc, 0x80, 0x41, 0x86, + 0x48, 0xd8, 0xdd, 0x31, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[24]; + uint8_t a[24]; + uint8_t b[24]; + uint8_t x[24]; + uint8_t y[24]; + uint8_t order[24]; +} _EC_X9_62_PRIME_192V3 = { + .seed = { + 0xc4, 0x69, 0x68, 0x44, 0x35, 0xde, 0xb3, 0x78, 0xc4, 0xb6, + 0x5c, 0xa9, 0x59, 0x1e, 0x2a, 0x57, 0x63, 0x05, 0x9a, 0x2e, + }, + .p = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0x22, 0x12, 0x3d, 0xc2, 0x39, 0x5a, 0x05, 0xca, 0xa7, 0x42, + 0x3d, 0xae, 0xcc, 0xc9, 0x47, 0x60, 0xa7, 0xd4, 0x62, 0x25, + 0x6b, 0xd5, 0x69, 0x16, + }, + .x = { + 0x7d, 0x29, 0x77, 0x81, 0x00, 0xc6, 0x5a, 0x1d, 0xa1, 0x78, + 0x37, 0x16, 0x58, 0x8d, 0xce, 0x2b, 0x8b, 0x4a, 0xee, 0x8e, + 0x22, 0x8f, 0x18, 0x96, + }, + .y = { + 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, + 0xdc, 0xb6, 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76, + 0x48, 0xa9, 0x43, 0xb0, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7a, 0x62, 0xd0, 0x31, 0xc8, 0x3f, 0x42, 0x94, + 0xf6, 0x40, 0xec, 0x13, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[30]; + uint8_t a[30]; + uint8_t b[30]; + uint8_t x[30]; + uint8_t y[30]; + uint8_t order[30]; +} _EC_X9_62_PRIME_239V1 = { + .seed = { + 0xe4, 0x3b, 0xb4, 0x60, 0xf0, 0xb8, 0x0c, 0xc0, 0xc0, 0xb0, + 0x75, 0x79, 0x8e, 0x94, 0x80, 0x60, 0xf8, 0x32, 0x1b, 0x7d, + }, + .p = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0x6b, 0x01, 0x6c, 0x3b, 0xdc, 0xf1, 0x89, 0x41, 0xd0, 0xd6, + 0x54, 0x92, 0x14, 0x75, 0xca, 0x71, 0xa9, 0xdb, 0x2f, 0xb2, + 0x7d, 0x1d, 0x37, 0x79, 0x61, 0x85, 0xc2, 0x94, 0x2c, 0x0a, + }, + .x = { + 0x0f, 0xfa, 0x96, 0x3c, 0xdc, 0xa8, 0x81, 0x6c, 0xcc, 0x33, + 0xb8, 0x64, 0x2b, 0xed, 0xf9, 0x05, 0xc3, 0xd3, 0x58, 0x57, + 0x3d, 0x3f, 0x27, 0xfb, 0xbd, 0x3b, 0x3c, 0xb9, 0xaa, 0xaf, + }, + .y = { + 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, + 0x54, 0xca, 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18, + 0xce, 0x22, 0x6b, 0x39, 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae, + }, + .order = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0x9e, 0x5e, 0x9a, 0x9f, 0x5d, + 0x90, 0x71, 0xfb, 0xd1, 0x52, 0x26, 0x88, 0x90, 0x9d, 0x0b, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[30]; + uint8_t a[30]; + uint8_t b[30]; + uint8_t x[30]; + uint8_t y[30]; + uint8_t order[30]; +} _EC_X9_62_PRIME_239V2 = { + .seed = { + 0xe8, 0xb4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xca, 0x3b, + 0x80, 0x99, 0x98, 0x2b, 0xe0, 0x9f, 0xcb, 0x9a, 0xe6, 0x16, + }, + .p = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0x61, 0x7f, 0xab, 0x68, 0x32, 0x57, 0x6c, 0xbb, 0xfe, 0xd5, + 0x0d, 0x99, 0xf0, 0x24, 0x9c, 0x3f, 0xee, 0x58, 0xb9, 0x4b, + 0xa0, 0x03, 0x8c, 0x7a, 0xe8, 0x4c, 0x8c, 0x83, 0x2f, 0x2c, + }, + .x = { + 0x38, 0xaf, 0x09, 0xd9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xc9, + 0x21, 0xbb, 0x5e, 0x9e, 0x26, 0x29, 0x6a, 0x3c, 0xdc, 0xf2, + 0xf3, 0x57, 0x57, 0xa0, 0xea, 0xfd, 0x87, 0xb8, 0x30, 0xe7, + }, + .y = { + 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, + 0xa0, 0xfc, 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55, + 0xde, 0x6e, 0xf4, 0x60, 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba, + }, + .order = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x00, 0x00, 0xcf, 0xa7, 0xe8, 0x59, 0x43, + 0x77, 0xd4, 0x14, 0xc0, 0x38, 0x21, 0xbc, 0x58, 0x20, 0x63, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[30]; + uint8_t a[30]; + uint8_t b[30]; + uint8_t x[30]; + uint8_t y[30]; + uint8_t order[30]; +} _EC_X9_62_PRIME_239V3 = { + .seed = { + 0x7d, 0x73, 0x74, 0x16, 0x8f, 0xfe, 0x34, 0x71, 0xb6, 0x0a, + 0x85, 0x76, 0x86, 0xa1, 0x94, 0x75, 0xd3, 0xbf, 0xa2, 0xff, + }, + .p = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0x25, 0x57, 0x05, 0xfa, 0x2a, 0x30, 0x66, 0x54, 0xb1, 0xf4, + 0xcb, 0x03, 0xd6, 0xa7, 0x50, 0xa3, 0x0c, 0x25, 0x01, 0x02, + 0xd4, 0x98, 0x87, 0x17, 0xd9, 0xba, 0x15, 0xab, 0x6d, 0x3e, + }, + .x = { + 0x67, 0x68, 0xae, 0x8e, 0x18, 0xbb, 0x92, 0xcf, 0xcf, 0x00, + 0x5c, 0x94, 0x9a, 0xa2, 0xc6, 0xd9, 0x48, 0x53, 0xd0, 0xe6, + 0x60, 0xbb, 0xf8, 0x54, 0xb1, 0xc9, 0x50, 0x5f, 0xe9, 0x5a, + }, + .y = { + 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, + 0x55, 0x2b, 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b, + 0x6e, 0x81, 0x84, 0x99, 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3, + }, + .order = { + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0x97, 0x5d, 0xeb, 0x41, 0xb3, + 0xa6, 0x05, 0x7c, 0x3c, 0x43, 0x21, 0x46, 0x52, 0x65, 0x51, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_X9_62_PRIME_256V1 = { + .seed = { + 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, + 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, + }, + .p = { + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, + }, + .a = { + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc, + }, + .b = { + 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, + 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, + 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, + 0x60, 0x4b, + }, + .x = { + 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, + }, + .y = { + 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, + }, + .order = { + 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, + }, +}; + +/* the secg prime curves (minus the nist and x9.62 prime curves) */ +static const struct { + uint8_t seed[20]; + uint8_t p[14]; + uint8_t a[14]; + uint8_t b[14]; + uint8_t x[14]; + uint8_t y[14]; + uint8_t order[14]; +} _EC_SECG_PRIME_112R1 = { + .seed = { + 0x00, 0xf5, 0x0b, 0x02, 0x8e, 0x4d, 0x69, 0x6e, 0x67, 0x68, + 0x75, 0x61, 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3f, 0xb1, + }, + .p = { + 0xdb, 0x7c, 0x2a, 0xbf, 0x62, 0xe3, 0x5e, 0x66, 0x80, 0x76, + 0xbe, 0xad, 0x20, 0x8b, + }, + .a = { + 0xdb, 0x7c, 0x2a, 0xbf, 0x62, 0xe3, 0x5e, 0x66, 0x80, 0x76, + 0xbe, 0xad, 0x20, 0x88, + }, + .b = { + 0x65, 0x9e, 0xf8, 0xba, 0x04, 0x39, 0x16, 0xee, 0xde, 0x89, + 0x11, 0x70, 0x2b, 0x22, + }, + .x = { + 0x09, 0x48, 0x72, 0x39, 0x99, 0x5a, 0x5e, 0xe7, 0x6b, 0x55, + 0xf9, 0xc2, 0xf0, 0x98, + }, + .y = { + 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, + 0x0f, 0xf7, 0x75, 0x00, + }, + .order = { + 0xdb, 0x7c, 0x2a, 0xbf, 0x62, 0xe3, 0x5e, 0x76, 0x28, 0xdf, + 0xac, 0x65, 0x61, 0xc5, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[14]; + uint8_t a[14]; + uint8_t b[14]; + uint8_t x[14]; + uint8_t y[14]; + uint8_t order[14]; +} _EC_SECG_PRIME_112R2 = { + .seed = { + 0x00, 0x27, 0x57, 0xa1, 0x11, 0x4d, 0x69, 0x6e, 0x67, 0x68, + 0x75, 0x61, 0x51, 0x75, 0x53, 0x16, 0xc0, 0x5e, 0x0b, 0xd4, + }, + .p = { + 0xdb, 0x7c, 0x2a, 0xbf, 0x62, 0xe3, 0x5e, 0x66, 0x80, 0x76, + 0xbe, 0xad, 0x20, 0x8b, + }, + .a = { + 0x61, 0x27, 0xc2, 0x4c, 0x05, 0xf3, 0x8a, 0x0a, 0xaa, 0xf6, + 0x5c, 0x0e, 0xf0, 0x2c, + }, + .b = { + 0x51, 0xde, 0xf1, 0x81, 0x5d, 0xb5, 0xed, 0x74, 0xfc, 0xc3, + 0x4c, 0x85, 0xd7, 0x09, + }, + .x = { + 0x4b, 0xa3, 0x0a, 0xb5, 0xe8, 0x92, 0xb4, 0xe1, 0x64, 0x9d, + 0xd0, 0x92, 0x86, 0x43, + }, + .y = { + 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, + 0x6e, 0x95, 0x6e, 0x97, + }, + .order = { + 0x36, 0xdf, 0x0a, 0xaf, 0xd8, 0xb8, 0xd7, 0x59, 0x7c, 0xa1, + 0x05, 0x20, 0xd0, 0x4b, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[16]; + uint8_t a[16]; + uint8_t b[16]; + uint8_t x[16]; + uint8_t y[16]; + uint8_t order[16]; +} _EC_SECG_PRIME_128R1 = { + .seed = { + 0x00, 0x0e, 0x0d, 0x4d, 0x69, 0x6e, 0x67, 0x68, 0x75, 0x61, + 0x51, 0x75, 0x0c, 0xc0, 0x3a, 0x44, 0x73, 0xd0, 0x36, 0x79, + }, + .p = { + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + }, + .b = { + 0xe8, 0x75, 0x79, 0xc1, 0x10, 0x79, 0xf4, 0x3d, 0xd8, 0x24, + 0x99, 0x3c, 0x2c, 0xee, 0x5e, 0xd3, + }, + .x = { + 0x16, 0x1f, 0xf7, 0x52, 0x8b, 0x89, 0x9b, 0x2d, 0x0c, 0x28, + 0x60, 0x7c, 0xa5, 0x2c, 0x5b, 0x86, + }, + .y = { + 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, + 0xa2, 0x92, 0xdd, 0xed, 0x7a, 0x83, + }, + .order = { + 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x75, 0xa3, + 0x0d, 0x1b, 0x90, 0x38, 0xa1, 0x15, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[16]; + uint8_t a[16]; + uint8_t b[16]; + uint8_t x[16]; + uint8_t y[16]; + uint8_t order[16]; +} _EC_SECG_PRIME_128R2 = { + .seed = { + 0x00, 0x4d, 0x69, 0x6e, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0x12, 0xd8, 0xf0, 0x34, 0x31, 0xfc, 0xe6, 0x3b, 0x88, 0xf4, + }, + .p = { + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .a = { + 0xd6, 0x03, 0x19, 0x98, 0xd1, 0xb3, 0xbb, 0xfe, 0xbf, 0x59, + 0xcc, 0x9b, 0xbf, 0xf9, 0xae, 0xe1, + }, + .b = { + 0x5e, 0xee, 0xfc, 0xa3, 0x80, 0xd0, 0x29, 0x19, 0xdc, 0x2c, + 0x65, 0x58, 0xbb, 0x6d, 0x8a, 0x5d, + }, + .x = { + 0x7b, 0x6a, 0xa5, 0xd8, 0x5e, 0x57, 0x29, 0x83, 0xe6, 0xfb, + 0x32, 0xa7, 0xcd, 0xeb, 0xc1, 0x40, + }, + .y = { + 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, + 0xfe, 0x80, 0x5f, 0xc3, 0x4b, 0x44, + }, + .order = { + 0x3f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xbe, 0x00, + 0x24, 0x72, 0x06, 0x13, 0xb5, 0xa3, + }, +}; + +static const struct { + uint8_t p[21]; + uint8_t a[21]; + uint8_t b[21]; + uint8_t x[21]; + uint8_t y[21]; + uint8_t order[21]; +} _EC_SECG_PRIME_160K1 = { + .p = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xac, + 0x73, + }, + .a = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + }, + .b = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, + }, + .x = { + 0x00, 0x3b, 0x4c, 0x38, 0x2c, 0xe3, 0x7a, 0xa1, 0x92, 0xa4, + 0x01, 0x9e, 0x76, 0x30, 0x36, 0xf4, 0xf5, 0xdd, 0x4d, 0x7e, + 0xbb, + }, + .y = { + 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, + 0xc2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f, + 0xee, + }, + .order = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xb8, 0xfa, 0x16, 0xdf, 0xab, 0x9a, 0xca, 0x16, 0xb6, + 0xb3, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[21]; + uint8_t a[21]; + uint8_t b[21]; + uint8_t x[21]; + uint8_t y[21]; + uint8_t order[21]; +} _EC_SECG_PRIME_160R1 = { + .seed = { + 0x10, 0x53, 0xcd, 0xe4, 0x2c, 0x14, 0xd6, 0x96, 0xe6, 0x76, + 0x87, 0x56, 0x15, 0x17, 0x53, 0x3b, 0xf3, 0xf8, 0x33, 0x45, + }, + .p = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, + 0xff, + }, + .a = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, + 0xfc, + }, + .b = { + 0x00, 0x1c, 0x97, 0xbe, 0xfc, 0x54, 0xbd, 0x7a, 0x8b, 0x65, + 0xac, 0xf8, 0x9f, 0x81, 0xd4, 0xd4, 0xad, 0xc5, 0x65, 0xfa, + 0x45, + }, + .x = { + 0x00, 0x4a, 0x96, 0xb5, 0x68, 0x8e, 0xf5, 0x73, 0x28, 0x46, + 0x64, 0x69, 0x89, 0x68, 0xc3, 0x8b, 0xb9, 0x13, 0xcb, 0xfc, + 0x82, + }, + .y = { + 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, + 0xdc, 0xc9, 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb, + 0x32, + }, + .order = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xf4, 0xc8, 0xf9, 0x27, 0xae, 0xd3, 0xca, 0x75, 0x22, + 0x57, + }, +}; + +static const struct { + uint8_t seed[20]; + uint8_t p[21]; + uint8_t a[21]; + uint8_t b[21]; + uint8_t x[21]; + uint8_t y[21]; + uint8_t order[21]; +} _EC_SECG_PRIME_160R2 = { + .seed = { + 0xb9, 0x9b, 0x99, 0xb0, 0x99, 0xb3, 0x23, 0xe0, 0x27, 0x09, + 0xa4, 0xd6, 0x96, 0xe6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, + }, + .p = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xac, + 0x73, + }, + .a = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xac, + 0x70, + }, + .b = { + 0x00, 0xb4, 0xe1, 0x34, 0xd3, 0xfb, 0x59, 0xeb, 0x8b, 0xab, + 0x57, 0x27, 0x49, 0x04, 0x66, 0x4d, 0x5a, 0xf5, 0x03, 0x88, + 0xba, + }, + .x = { + 0x00, 0x52, 0xdc, 0xb0, 0x34, 0x29, 0x3a, 0x11, 0x7e, 0x1f, + 0x4f, 0xf1, 0x1b, 0x30, 0xf7, 0x19, 0x9d, 0x31, 0x44, 0xce, + 0x6d, + }, + .y = { + 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, + 0x71, 0xfa, 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f, + 0x2e, + }, + .order = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x35, 0x1e, 0xe7, 0x86, 0xa8, 0x18, 0xf3, 0xa1, 0xa1, + 0x6b, + }, +}; + +static const struct { + uint8_t p[24]; + uint8_t a[24]; + uint8_t b[24]; + uint8_t x[24]; + uint8_t y[24]; + uint8_t order[24]; +} _EC_SECG_PRIME_192K1 = { + .p = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xee, 0x37, + }, + .a = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }, + .b = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, + }, + .x = { + 0xdb, 0x4f, 0xf1, 0x0e, 0xc0, 0x57, 0xe9, 0xae, 0x26, 0xb0, + 0x7d, 0x02, 0x80, 0xb7, 0xf4, 0x34, 0x1d, 0xa5, 0xd1, 0xb1, + 0xea, 0xe0, 0x6c, 0x7d, + }, + .y = { + 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, + 0x63, 0xd0, 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88, + 0xd9, 0x5e, 0x2f, 0x9d, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x26, 0xf2, 0xfc, 0x17, 0x0f, 0x69, 0x46, 0x6a, + 0x74, 0xde, 0xfd, 0x8d, + }, +}; + +static const struct { + uint8_t p[29]; + uint8_t a[29]; + uint8_t b[29]; + uint8_t x[29]; + uint8_t y[29]; + uint8_t order[29]; +} _EC_SECG_PRIME_224K1 = { + .p = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xe5, 0x6d, + }, + .a = { + 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, + }, + .b = { + 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, 0x05, + }, + .x = { + 0x00, 0xa1, 0x45, 0x5b, 0x33, 0x4d, 0xf0, 0x99, 0xdf, 0x30, + 0xfc, 0x28, 0xa1, 0x69, 0xa4, 0x67, 0xe9, 0xe4, 0x70, 0x75, + 0xa9, 0x0f, 0x7e, 0x65, 0x0e, 0xb6, 0xb7, 0xa4, 0x5c, + }, + .y = { + 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, + 0xca, 0xfb, 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd, + 0x59, 0xe2, 0xca, 0x4b, 0xdb, 0x55, 0x6d, 0x61, 0xa5, + }, + .order = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xdc, 0xe8, 0xd2, 0xec, 0x61, + 0x84, 0xca, 0xf0, 0xa9, 0x71, 0x76, 0x9f, 0xb1, 0xf7, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_SECG_PRIME_256K1 = { + .p = { + 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, 0xfe, 0xff, 0xff, + 0xfc, 0x2f, + }, + .a = { + 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, 0x00, + }, + .b = { + 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, 0x07, + }, + .x = { + 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, + 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, + 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, + 0x17, 0x98, + }, + .y = { + 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, + 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, + 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, + 0xd4, 0xb8, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, + 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, + 0x41, 0x41, + }, +}; + +/* some wap/wtls curves */ +static const struct { + uint8_t p[15]; + uint8_t a[15]; + uint8_t b[15]; + uint8_t x[15]; + uint8_t y[15]; + uint8_t order[15]; +} _EC_WTLS_8 = { + .p = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0xe7, + }, + .a = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .b = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, + }, + .x = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .y = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, + }, + .order = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xec, 0xea, + 0x55, 0x1a, 0xd8, 0x37, 0xe9, + }, +}; + +static const struct { + uint8_t p[21]; + uint8_t a[21]; + uint8_t b[21]; + uint8_t x[21]; + uint8_t y[21]; + uint8_t order[21]; +} _EC_WTLS_9 = { + .p = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x80, + 0x8f, + }, + .a = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + }, + .b = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, + }, + .x = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, + }, + .y = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, + }, + .order = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xcd, 0xc9, 0x8a, 0xe0, 0xe2, 0xde, 0x57, 0x4a, 0xbf, + 0x33, + }, +}; + +static const struct { + uint8_t p[28]; + uint8_t a[28]; + uint8_t b[28]; + uint8_t x[28]; + uint8_t y[28]; + uint8_t order[28]; +} _EC_WTLS_12 = { + .p = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .a = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + }, + .b = { + 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41, + 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, + 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, + }, + .x = { + 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, + 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22, + 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21, + }, + .y = { + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, + 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, + 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, + 0x13, 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, + }, +}; + +static const struct { + uint8_t p[20]; + uint8_t a[20]; + uint8_t b[20]; + uint8_t x[20]; + uint8_t y[20]; + uint8_t order[20]; +} _EC_brainpoolP160r1 = { + .p = { + 0xe9, 0x5e, 0x4a, 0x5f, 0x73, 0x70, 0x59, 0xdc, 0x60, 0xdf, + 0xc7, 0xad, 0x95, 0xb3, 0xd8, 0x13, 0x95, 0x15, 0x62, 0x0f, + }, + .a = { + 0x34, 0x0e, 0x7b, 0xe2, 0xa2, 0x80, 0xeb, 0x74, 0xe2, 0xbe, + 0x61, 0xba, 0xda, 0x74, 0x5d, 0x97, 0xe8, 0xf7, 0xc3, 0x00, + }, + .b = { + 0x1e, 0x58, 0x9a, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4f, + 0xaa, 0x2d, 0xbd, 0xec, 0x95, 0xc8, 0xd8, 0x67, 0x5e, 0x58, + }, + .x = { + 0xbe, 0xd5, 0xaf, 0x16, 0xea, 0x3f, 0x6a, 0x4f, 0x62, 0x93, + 0x8c, 0x46, 0x31, 0xeb, 0x5a, 0xf7, 0xbd, 0xbc, 0xdb, 0xc3, + }, + .y = { + 0x16, 0x67, 0xcb, 0x47, 0x7a, 0x1a, 0x8e, 0xc3, 0x38, 0xf9, + 0x47, 0x41, 0x66, 0x9c, 0x97, 0x63, 0x16, 0xda, 0x63, 0x21, + }, + .order = { + 0xe9, 0x5e, 0x4a, 0x5f, 0x73, 0x70, 0x59, 0xdc, 0x60, 0xdf, + 0x59, 0x91, 0xd4, 0x50, 0x29, 0x40, 0x9e, 0x60, 0xfc, 0x09, + }, +}; + +static const struct { + uint8_t p[20]; + uint8_t a[20]; + uint8_t b[20]; + uint8_t x[20]; + uint8_t y[20]; + uint8_t order[20]; +} _EC_brainpoolP160t1 = { + .p = { + 0xe9, 0x5e, 0x4a, 0x5f, 0x73, 0x70, 0x59, 0xdc, 0x60, 0xdf, + 0xc7, 0xad, 0x95, 0xb3, 0xd8, 0x13, 0x95, 0x15, 0x62, 0x0f, + }, + .a = { + 0xe9, 0x5e, 0x4a, 0x5f, 0x73, 0x70, 0x59, 0xdc, 0x60, 0xdf, + 0xc7, 0xad, 0x95, 0xb3, 0xd8, 0x13, 0x95, 0x15, 0x62, 0x0c, + }, + .b = { + 0x7a, 0x55, 0x6b, 0x6d, 0xae, 0x53, 0x5b, 0x7b, 0x51, 0xed, + 0x2c, 0x4d, 0x7d, 0xaa, 0x7a, 0x0b, 0x5c, 0x55, 0xf3, 0x80, + }, + .x = { + 0xb1, 0x99, 0xb1, 0x3b, 0x9b, 0x34, 0xef, 0xc1, 0x39, 0x7e, + 0x64, 0xba, 0xeb, 0x05, 0xac, 0xc2, 0x65, 0xff, 0x23, 0x78, + }, + .y = { + 0xad, 0xd6, 0x71, 0x8b, 0x7c, 0x7c, 0x19, 0x61, 0xf0, 0x99, + 0x1b, 0x84, 0x24, 0x43, 0x77, 0x21, 0x52, 0xc9, 0xe0, 0xad, + }, + .order = { + 0xe9, 0x5e, 0x4a, 0x5f, 0x73, 0x70, 0x59, 0xdc, 0x60, 0xdf, + 0x59, 0x91, 0xd4, 0x50, 0x29, 0x40, 0x9e, 0x60, 0xfc, 0x09, + }, +}; + +static const struct { + uint8_t p[24]; + uint8_t a[24]; + uint8_t b[24]; + uint8_t x[24]; + uint8_t y[24]; + uint8_t order[24]; +} _EC_brainpoolP192r1 = { + .p = { + 0xc3, 0x02, 0xf4, 0x1d, 0x93, 0x2a, 0x36, 0xcd, 0xa7, 0xa3, + 0x46, 0x30, 0x93, 0xd1, 0x8d, 0xb7, 0x8f, 0xce, 0x47, 0x6d, + 0xe1, 0xa8, 0x62, 0x97, + }, + .a = { + 0x6a, 0x91, 0x17, 0x40, 0x76, 0xb1, 0xe0, 0xe1, 0x9c, 0x39, + 0xc0, 0x31, 0xfe, 0x86, 0x85, 0xc1, 0xca, 0xe0, 0x40, 0xe5, + 0xc6, 0x9a, 0x28, 0xef, + }, + .b = { + 0x46, 0x9a, 0x28, 0xef, 0x7c, 0x28, 0xcc, 0xa3, 0xdc, 0x72, + 0x1d, 0x04, 0x4f, 0x44, 0x96, 0xbc, 0xca, 0x7e, 0xf4, 0x14, + 0x6f, 0xbf, 0x25, 0xc9, + }, + .x = { + 0xc0, 0xa0, 0x64, 0x7e, 0xaa, 0xb6, 0xa4, 0x87, 0x53, 0xb0, + 0x33, 0xc5, 0x6c, 0xb0, 0xf0, 0x90, 0x0a, 0x2f, 0x5c, 0x48, + 0x53, 0x37, 0x5f, 0xd6, + }, + .y = { + 0x14, 0xb6, 0x90, 0x86, 0x6a, 0xbd, 0x5b, 0xb8, 0x8b, 0x5f, + 0x48, 0x28, 0xc1, 0x49, 0x00, 0x02, 0xe6, 0x77, 0x3f, 0xa2, + 0xfa, 0x29, 0x9b, 0x8f, + }, + .order = { + 0xc3, 0x02, 0xf4, 0x1d, 0x93, 0x2a, 0x36, 0xcd, 0xa7, 0xa3, + 0x46, 0x2f, 0x9e, 0x9e, 0x91, 0x6b, 0x5b, 0xe8, 0xf1, 0x02, + 0x9a, 0xc4, 0xac, 0xc1, + }, +}; + +static const struct { + uint8_t p[24]; + uint8_t a[24]; + uint8_t b[24]; + uint8_t x[24]; + uint8_t y[24]; + uint8_t order[24]; +} _EC_brainpoolP192t1 = { + .p = { + 0xc3, 0x02, 0xf4, 0x1d, 0x93, 0x2a, 0x36, 0xcd, 0xa7, 0xa3, + 0x46, 0x30, 0x93, 0xd1, 0x8d, 0xb7, 0x8f, 0xce, 0x47, 0x6d, + 0xe1, 0xa8, 0x62, 0x97, + }, + .a = { + 0xc3, 0x02, 0xf4, 0x1d, 0x93, 0x2a, 0x36, 0xcd, 0xa7, 0xa3, + 0x46, 0x30, 0x93, 0xd1, 0x8d, 0xb7, 0x8f, 0xce, 0x47, 0x6d, + 0xe1, 0xa8, 0x62, 0x94, + }, + .b = { + 0x13, 0xd5, 0x6f, 0xfa, 0xec, 0x78, 0x68, 0x1e, 0x68, 0xf9, + 0xde, 0xb4, 0x3b, 0x35, 0xbe, 0xc2, 0xfb, 0x68, 0x54, 0x2e, + 0x27, 0x89, 0x7b, 0x79, + }, + .x = { + 0x3a, 0xe9, 0xe5, 0x8c, 0x82, 0xf6, 0x3c, 0x30, 0x28, 0x2e, + 0x1f, 0xe7, 0xbb, 0xf4, 0x3f, 0xa7, 0x2c, 0x44, 0x6a, 0xf6, + 0xf4, 0x61, 0x81, 0x29, + }, + .y = { + 0x09, 0x7e, 0x2c, 0x56, 0x67, 0xc2, 0x22, 0x3a, 0x90, 0x2a, + 0xb5, 0xca, 0x44, 0x9d, 0x00, 0x84, 0xb7, 0xe5, 0xb3, 0xde, + 0x7c, 0xcc, 0x01, 0xc9, + }, + .order = { + 0xc3, 0x02, 0xf4, 0x1d, 0x93, 0x2a, 0x36, 0xcd, 0xa7, 0xa3, + 0x46, 0x2f, 0x9e, 0x9e, 0x91, 0x6b, 0x5b, 0xe8, 0xf1, 0x02, + 0x9a, 0xc4, 0xac, 0xc1, + }, +}; + +static const struct { + uint8_t p[28]; + uint8_t a[28]; + uint8_t b[28]; + uint8_t x[28]; + uint8_t y[28]; + uint8_t order[28]; +} _EC_brainpoolP224r1 = { + .p = { + 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18, + 0x30, 0x25, 0x75, 0xd1, 0xd7, 0x87, 0xb0, 0x9f, 0x07, 0x57, + 0x97, 0xda, 0x89, 0xf5, 0x7e, 0xc8, 0xc0, 0xff, + }, + .a = { + 0x68, 0xa5, 0xe6, 0x2c, 0xa9, 0xce, 0x6c, 0x1c, 0x29, 0x98, + 0x03, 0xa6, 0xc1, 0x53, 0x0b, 0x51, 0x4e, 0x18, 0x2a, 0xd8, + 0xb0, 0x04, 0x2a, 0x59, 0xca, 0xd2, 0x9f, 0x43, + }, + .b = { + 0x25, 0x80, 0xf6, 0x3c, 0xcf, 0xe4, 0x41, 0x38, 0x87, 0x07, + 0x13, 0xb1, 0xa9, 0x23, 0x69, 0xe3, 0x3e, 0x21, 0x35, 0xd2, + 0x66, 0xdb, 0xb3, 0x72, 0x38, 0x6c, 0x40, 0x0b, + }, + .x = { + 0x0d, 0x90, 0x29, 0xad, 0x2c, 0x7e, 0x5c, 0xf4, 0x34, 0x08, + 0x23, 0xb2, 0xa8, 0x7d, 0xc6, 0x8c, 0x9e, 0x4c, 0xe3, 0x17, + 0x4c, 0x1e, 0x6e, 0xfd, 0xee, 0x12, 0xc0, 0x7d, + }, + .y = { + 0x58, 0xaa, 0x56, 0xf7, 0x72, 0xc0, 0x72, 0x6f, 0x24, 0xc6, + 0xb8, 0x9e, 0x4e, 0xcd, 0xac, 0x24, 0x35, 0x4b, 0x9e, 0x99, + 0xca, 0xa3, 0xf6, 0xd3, 0x76, 0x14, 0x02, 0xcd, + }, + .order = { + 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18, + 0x30, 0x25, 0x75, 0xd0, 0xfb, 0x98, 0xd1, 0x16, 0xbc, 0x4b, + 0x6d, 0xde, 0xbc, 0xa3, 0xa5, 0xa7, 0x93, 0x9f, + }, +}; + +static const struct { + uint8_t p[28]; + uint8_t a[28]; + uint8_t b[28]; + uint8_t x[28]; + uint8_t y[28]; + uint8_t order[28]; +} _EC_brainpoolP224t1 = { + .p = { + 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18, + 0x30, 0x25, 0x75, 0xd1, 0xd7, 0x87, 0xb0, 0x9f, 0x07, 0x57, + 0x97, 0xda, 0x89, 0xf5, 0x7e, 0xc8, 0xc0, 0xff, + }, + .a = { + 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18, + 0x30, 0x25, 0x75, 0xd1, 0xd7, 0x87, 0xb0, 0x9f, 0x07, 0x57, + 0x97, 0xda, 0x89, 0xf5, 0x7e, 0xc8, 0xc0, 0xfc, + }, + .b = { + 0x4b, 0x33, 0x7d, 0x93, 0x41, 0x04, 0xcd, 0x7b, 0xef, 0x27, + 0x1b, 0xf6, 0x0c, 0xed, 0x1e, 0xd2, 0x0d, 0xa1, 0x4c, 0x08, + 0xb3, 0xbb, 0x64, 0xf1, 0x8a, 0x60, 0x88, 0x8d, + }, + .x = { + 0x6a, 0xb1, 0xe3, 0x44, 0xce, 0x25, 0xff, 0x38, 0x96, 0x42, + 0x4e, 0x7f, 0xfe, 0x14, 0x76, 0x2e, 0xcb, 0x49, 0xf8, 0x92, + 0x8a, 0xc0, 0xc7, 0x60, 0x29, 0xb4, 0xd5, 0x80, + }, + .y = { + 0x03, 0x74, 0xe9, 0xf5, 0x14, 0x3e, 0x56, 0x8c, 0xd2, 0x3f, + 0x3f, 0x4d, 0x7c, 0x0d, 0x4b, 0x1e, 0x41, 0xc8, 0xcc, 0x0d, + 0x1c, 0x6a, 0xbd, 0x5f, 0x1a, 0x46, 0xdb, 0x4c, + }, + .order = { + 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18, + 0x30, 0x25, 0x75, 0xd0, 0xfb, 0x98, 0xd1, 0x16, 0xbc, 0x4b, + 0x6d, 0xde, 0xbc, 0xa3, 0xa5, 0xa7, 0x93, 0x9f, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_brainpoolP256r1 = { + .p = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, + 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, 0x6e, 0x3b, 0xf6, 0x23, + 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e, + 0x53, 0x77, + }, + .a = { + 0x7d, 0x5a, 0x09, 0x75, 0xfc, 0x2c, 0x30, 0x57, 0xee, 0xf6, + 0x75, 0x30, 0x41, 0x7a, 0xff, 0xe7, 0xfb, 0x80, 0x55, 0xc1, + 0x26, 0xdc, 0x5c, 0x6c, 0xe9, 0x4a, 0x4b, 0x44, 0xf3, 0x30, + 0xb5, 0xd9, + }, + .b = { + 0x26, 0xdc, 0x5c, 0x6c, 0xe9, 0x4a, 0x4b, 0x44, 0xf3, 0x30, + 0xb5, 0xd9, 0xbb, 0xd7, 0x7c, 0xbf, 0x95, 0x84, 0x16, 0x29, + 0x5c, 0xf7, 0xe1, 0xce, 0x6b, 0xcc, 0xdc, 0x18, 0xff, 0x8c, + 0x07, 0xb6, + }, + .x = { + 0x8b, 0xd2, 0xae, 0xb9, 0xcb, 0x7e, 0x57, 0xcb, 0x2c, 0x4b, + 0x48, 0x2f, 0xfc, 0x81, 0xb7, 0xaf, 0xb9, 0xde, 0x27, 0xe1, + 0xe3, 0xbd, 0x23, 0xc2, 0x3a, 0x44, 0x53, 0xbd, 0x9a, 0xce, + 0x32, 0x62, + }, + .y = { + 0x54, 0x7e, 0xf8, 0x35, 0xc3, 0xda, 0xc4, 0xfd, 0x97, 0xf8, + 0x46, 0x1a, 0x14, 0x61, 0x1d, 0xc9, 0xc2, 0x77, 0x45, 0x13, + 0x2d, 0xed, 0x8e, 0x54, 0x5c, 0x1d, 0x54, 0xc7, 0x2f, 0x04, + 0x69, 0x97, + }, + .order = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, + 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x71, 0x8c, 0x39, 0x7a, 0xa3, + 0xb5, 0x61, 0xa6, 0xf7, 0x90, 0x1e, 0x0e, 0x82, 0x97, 0x48, + 0x56, 0xa7, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_brainpoolP256t1 = { + .p = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, + 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, 0x6e, 0x3b, 0xf6, 0x23, + 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e, + 0x53, 0x77, + }, + .a = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, + 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, 0x6e, 0x3b, 0xf6, 0x23, + 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e, + 0x53, 0x74, + }, + .b = { + 0x66, 0x2c, 0x61, 0xc4, 0x30, 0xd8, 0x4e, 0xa4, 0xfe, 0x66, + 0xa7, 0x73, 0x3d, 0x0b, 0x76, 0xb7, 0xbf, 0x93, 0xeb, 0xc4, + 0xaf, 0x2f, 0x49, 0x25, 0x6a, 0xe5, 0x81, 0x01, 0xfe, 0xe9, + 0x2b, 0x04, + }, + .x = { + 0xa3, 0xe8, 0xeb, 0x3c, 0xc1, 0xcf, 0xe7, 0xb7, 0x73, 0x22, + 0x13, 0xb2, 0x3a, 0x65, 0x61, 0x49, 0xaf, 0xa1, 0x42, 0xc4, + 0x7a, 0xaf, 0xbc, 0x2b, 0x79, 0xa1, 0x91, 0x56, 0x2e, 0x13, + 0x05, 0xf4, + }, + .y = { + 0x2d, 0x99, 0x6c, 0x82, 0x34, 0x39, 0xc5, 0x6d, 0x7f, 0x7b, + 0x22, 0xe1, 0x46, 0x44, 0x41, 0x7e, 0x69, 0xbc, 0xb6, 0xde, + 0x39, 0xd0, 0x27, 0x00, 0x1d, 0xab, 0xe8, 0xf3, 0x5b, 0x25, + 0xc9, 0xbe, + }, + .order = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, + 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x71, 0x8c, 0x39, 0x7a, 0xa3, + 0xb5, 0x61, 0xa6, 0xf7, 0x90, 0x1e, 0x0e, 0x82, 0x97, 0x48, + 0x56, 0xa7, + }, +}; + +static const struct { + uint8_t p[40]; + uint8_t a[40]; + uint8_t b[40]; + uint8_t x[40]; + uint8_t y[40]; + uint8_t order[40]; +} _EC_brainpoolP320r1 = { + .p = { + 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c, + 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa6, + 0xf6, 0xf4, 0x0d, 0xef, 0x4f, 0x92, 0xb9, 0xec, 0x78, 0x93, + 0xec, 0x28, 0xfc, 0xd4, 0x12, 0xb1, 0xf1, 0xb3, 0x2e, 0x27, + }, + .a = { + 0x3e, 0xe3, 0x0b, 0x56, 0x8f, 0xba, 0xb0, 0xf8, 0x83, 0xcc, + 0xeb, 0xd4, 0x6d, 0x3f, 0x3b, 0xb8, 0xa2, 0xa7, 0x35, 0x13, + 0xf5, 0xeb, 0x79, 0xda, 0x66, 0x19, 0x0e, 0xb0, 0x85, 0xff, + 0xa9, 0xf4, 0x92, 0xf3, 0x75, 0xa9, 0x7d, 0x86, 0x0e, 0xb4, + }, + .b = { + 0x52, 0x08, 0x83, 0x94, 0x9d, 0xfd, 0xbc, 0x42, 0xd3, 0xad, + 0x19, 0x86, 0x40, 0x68, 0x8a, 0x6f, 0xe1, 0x3f, 0x41, 0x34, + 0x95, 0x54, 0xb4, 0x9a, 0xcc, 0x31, 0xdc, 0xcd, 0x88, 0x45, + 0x39, 0x81, 0x6f, 0x5e, 0xb4, 0xac, 0x8f, 0xb1, 0xf1, 0xa6, + }, + .x = { + 0x43, 0xbd, 0x7e, 0x9a, 0xfb, 0x53, 0xd8, 0xb8, 0x52, 0x89, + 0xbc, 0xc4, 0x8e, 0xe5, 0xbf, 0xe6, 0xf2, 0x01, 0x37, 0xd1, + 0x0a, 0x08, 0x7e, 0xb6, 0xe7, 0x87, 0x1e, 0x2a, 0x10, 0xa5, + 0x99, 0xc7, 0x10, 0xaf, 0x8d, 0x0d, 0x39, 0xe2, 0x06, 0x11, + }, + .y = { + 0x14, 0xfd, 0xd0, 0x55, 0x45, 0xec, 0x1c, 0xc8, 0xab, 0x40, + 0x93, 0x24, 0x7f, 0x77, 0x27, 0x5e, 0x07, 0x43, 0xff, 0xed, + 0x11, 0x71, 0x82, 0xea, 0xa9, 0xc7, 0x78, 0x77, 0xaa, 0xac, + 0x6a, 0xc7, 0xd3, 0x52, 0x45, 0xd1, 0x69, 0x2e, 0x8e, 0xe1, + }, + .order = { + 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c, + 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa5, + 0xb6, 0x8f, 0x12, 0xa3, 0x2d, 0x48, 0x2e, 0xc7, 0xee, 0x86, + 0x58, 0xe9, 0x86, 0x91, 0x55, 0x5b, 0x44, 0xc5, 0x93, 0x11, + }, +}; + +static const struct { + uint8_t p[40]; + uint8_t a[40]; + uint8_t b[40]; + uint8_t x[40]; + uint8_t y[40]; + uint8_t order[40]; +} _EC_brainpoolP320t1 = { + .p = { + 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c, + 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa6, + 0xf6, 0xf4, 0x0d, 0xef, 0x4f, 0x92, 0xb9, 0xec, 0x78, 0x93, + 0xec, 0x28, 0xfc, 0xd4, 0x12, 0xb1, 0xf1, 0xb3, 0x2e, 0x27, + }, + .a = { + 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c, + 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa6, + 0xf6, 0xf4, 0x0d, 0xef, 0x4f, 0x92, 0xb9, 0xec, 0x78, 0x93, + 0xec, 0x28, 0xfc, 0xd4, 0x12, 0xb1, 0xf1, 0xb3, 0x2e, 0x24, + }, + .b = { + 0xa7, 0xf5, 0x61, 0xe0, 0x38, 0xeb, 0x1e, 0xd5, 0x60, 0xb3, + 0xd1, 0x47, 0xdb, 0x78, 0x20, 0x13, 0x06, 0x4c, 0x19, 0xf2, + 0x7e, 0xd2, 0x7c, 0x67, 0x80, 0xaa, 0xf7, 0x7f, 0xb8, 0xa5, + 0x47, 0xce, 0xb5, 0xb4, 0xfe, 0xf4, 0x22, 0x34, 0x03, 0x53, + }, + .x = { + 0x92, 0x5b, 0xe9, 0xfb, 0x01, 0xaf, 0xc6, 0xfb, 0x4d, 0x3e, + 0x7d, 0x49, 0x90, 0x01, 0x0f, 0x81, 0x34, 0x08, 0xab, 0x10, + 0x6c, 0x4f, 0x09, 0xcb, 0x7e, 0xe0, 0x78, 0x68, 0xcc, 0x13, + 0x6f, 0xff, 0x33, 0x57, 0xf6, 0x24, 0xa2, 0x1b, 0xed, 0x52, + }, + .y = { + 0x63, 0xba, 0x3a, 0x7a, 0x27, 0x48, 0x3e, 0xbf, 0x66, 0x71, + 0xdb, 0xef, 0x7a, 0xbb, 0x30, 0xeb, 0xee, 0x08, 0x4e, 0x58, + 0xa0, 0xb0, 0x77, 0xad, 0x42, 0xa5, 0xa0, 0x98, 0x9d, 0x1e, + 0xe7, 0x1b, 0x1b, 0x9b, 0xc0, 0x45, 0x5f, 0xb0, 0xd2, 0xc3, + }, + .order = { + 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c, + 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa5, + 0xb6, 0x8f, 0x12, 0xa3, 0x2d, 0x48, 0x2e, 0xc7, 0xee, 0x86, + 0x58, 0xe9, 0x86, 0x91, 0x55, 0x5b, 0x44, 0xc5, 0x93, 0x11, + }, +}; + +static const struct { + uint8_t p[48]; + uint8_t a[48]; + uint8_t b[48]; + uint8_t x[48]; + uint8_t y[48]; + uint8_t order[48]; +} _EC_brainpoolP384r1 = { + .p = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, + 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09, + 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7, + 0x11, 0x23, 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71, + 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x53, + }, + .a = { + 0x7b, 0xc3, 0x82, 0xc6, 0x3d, 0x8c, 0x15, 0x0c, 0x3c, 0x72, + 0x08, 0x0a, 0xce, 0x05, 0xaf, 0xa0, 0xc2, 0xbe, 0xa2, 0x8e, + 0x4f, 0xb2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xef, 0xba, 0x91, + 0xf9, 0x0f, 0x8a, 0xa5, 0x81, 0x4a, 0x50, 0x3a, 0xd4, 0xeb, + 0x04, 0xa8, 0xc7, 0xdd, 0x22, 0xce, 0x28, 0x26, + }, + .b = { + 0x04, 0xa8, 0xc7, 0xdd, 0x22, 0xce, 0x28, 0x26, 0x8b, 0x39, + 0xb5, 0x54, 0x16, 0xf0, 0x44, 0x7c, 0x2f, 0xb7, 0x7d, 0xe1, + 0x07, 0xdc, 0xd2, 0xa6, 0x2e, 0x88, 0x0e, 0xa5, 0x3e, 0xeb, + 0x62, 0xd5, 0x7c, 0xb4, 0x39, 0x02, 0x95, 0xdb, 0xc9, 0x94, + 0x3a, 0xb7, 0x86, 0x96, 0xfa, 0x50, 0x4c, 0x11, + }, + .x = { + 0x1d, 0x1c, 0x64, 0xf0, 0x68, 0xcf, 0x45, 0xff, 0xa2, 0xa6, + 0x3a, 0x81, 0xb7, 0xc1, 0x3f, 0x6b, 0x88, 0x47, 0xa3, 0xe7, + 0x7e, 0xf1, 0x4f, 0xe3, 0xdb, 0x7f, 0xca, 0xfe, 0x0c, 0xbd, + 0x10, 0xe8, 0xe8, 0x26, 0xe0, 0x34, 0x36, 0xd6, 0x46, 0xaa, + 0xef, 0x87, 0xb2, 0xe2, 0x47, 0xd4, 0xaf, 0x1e, + }, + .y = { + 0x8a, 0xbe, 0x1d, 0x75, 0x20, 0xf9, 0xc2, 0xa4, 0x5c, 0xb1, + 0xeb, 0x8e, 0x95, 0xcf, 0xd5, 0x52, 0x62, 0xb7, 0x0b, 0x29, + 0xfe, 0xec, 0x58, 0x64, 0xe1, 0x9c, 0x05, 0x4f, 0xf9, 0x91, + 0x29, 0x28, 0x0e, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11, + 0x42, 0x82, 0x03, 0x41, 0x26, 0x3c, 0x53, 0x15, + }, + .order = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, + 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09, + 0xed, 0x54, 0x56, 0xb3, 0x1f, 0x16, 0x6e, 0x6c, 0xac, 0x04, + 0x25, 0xa7, 0xcf, 0x3a, 0xb6, 0xaf, 0x6b, 0x7f, 0xc3, 0x10, + 0x3b, 0x88, 0x32, 0x02, 0xe9, 0x04, 0x65, 0x65, + }, +}; + +static const struct { + uint8_t p[48]; + uint8_t a[48]; + uint8_t b[48]; + uint8_t x[48]; + uint8_t y[48]; + uint8_t order[48]; +} _EC_brainpoolP384t1 = { + .p = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, + 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09, + 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7, + 0x11, 0x23, 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71, + 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x53, + }, + .a = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, + 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09, + 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7, + 0x11, 0x23, 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71, + 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x50, + }, + .b = { + 0x7f, 0x51, 0x9e, 0xad, 0xa7, 0xbd, 0xa8, 0x1b, 0xd8, 0x26, + 0xdb, 0xa6, 0x47, 0x91, 0x0f, 0x8c, 0x4b, 0x93, 0x46, 0xed, + 0x8c, 0xcd, 0xc6, 0x4e, 0x4b, 0x1a, 0xbd, 0x11, 0x75, 0x6d, + 0xce, 0x1d, 0x20, 0x74, 0xaa, 0x26, 0x3b, 0x88, 0x80, 0x5c, + 0xed, 0x70, 0x35, 0x5a, 0x33, 0xb4, 0x71, 0xee, + }, + .x = { + 0x18, 0xde, 0x98, 0xb0, 0x2d, 0xb9, 0xa3, 0x06, 0xf2, 0xaf, + 0xcd, 0x72, 0x35, 0xf7, 0x2a, 0x81, 0x9b, 0x80, 0xab, 0x12, + 0xeb, 0xd6, 0x53, 0x17, 0x24, 0x76, 0xfe, 0xcd, 0x46, 0x2a, + 0xab, 0xff, 0xc4, 0xff, 0x19, 0x1b, 0x94, 0x6a, 0x5f, 0x54, + 0xd8, 0xd0, 0xaa, 0x2f, 0x41, 0x88, 0x08, 0xcc, + }, + .y = { + 0x25, 0xab, 0x05, 0x69, 0x62, 0xd3, 0x06, 0x51, 0xa1, 0x14, + 0xaf, 0xd2, 0x75, 0x5a, 0xd3, 0x36, 0x74, 0x7f, 0x93, 0x47, + 0x5b, 0x7a, 0x1f, 0xca, 0x3b, 0x88, 0xf2, 0xb6, 0xa2, 0x08, + 0xcc, 0xfe, 0x46, 0x94, 0x08, 0x58, 0x4d, 0xc2, 0xb2, 0x91, + 0x26, 0x75, 0xbf, 0x5b, 0x9e, 0x58, 0x29, 0x28, + }, + .order = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, + 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09, + 0xed, 0x54, 0x56, 0xb3, 0x1f, 0x16, 0x6e, 0x6c, 0xac, 0x04, + 0x25, 0xa7, 0xcf, 0x3a, 0xb6, 0xaf, 0x6b, 0x7f, 0xc3, 0x10, + 0x3b, 0x88, 0x32, 0x02, 0xe9, 0x04, 0x65, 0x65, + }, +}; + +static const struct { + uint8_t p[64]; + uint8_t a[64]; + uint8_t b[64]; + uint8_t x[64]; + uint8_t y[64]; + uint8_t order[64]; +} _EC_brainpoolP512r1 = { + .p = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, + 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3, + 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, + 0x08, 0x71, 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42, + 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, 0x28, 0x81, + 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56, + 0x58, 0x3a, 0x48, 0xf3, + }, + .a = { + 0x78, 0x30, 0xa3, 0x31, 0x8b, 0x60, 0x3b, 0x89, 0xe2, 0x32, + 0x71, 0x45, 0xac, 0x23, 0x4c, 0xc5, 0x94, 0xcb, 0xdd, 0x8d, + 0x3d, 0xf9, 0x16, 0x10, 0xa8, 0x34, 0x41, 0xca, 0xea, 0x98, + 0x63, 0xbc, 0x2d, 0xed, 0x5d, 0x5a, 0xa8, 0x25, 0x3a, 0xa1, + 0x0a, 0x2e, 0xf1, 0xc9, 0x8b, 0x9a, 0xc8, 0xb5, 0x7f, 0x11, + 0x17, 0xa7, 0x2b, 0xf2, 0xc7, 0xb9, 0xe7, 0xc1, 0xac, 0x4d, + 0x77, 0xfc, 0x94, 0xca, + }, + .b = { + 0x3d, 0xf9, 0x16, 0x10, 0xa8, 0x34, 0x41, 0xca, 0xea, 0x98, + 0x63, 0xbc, 0x2d, 0xed, 0x5d, 0x5a, 0xa8, 0x25, 0x3a, 0xa1, + 0x0a, 0x2e, 0xf1, 0xc9, 0x8b, 0x9a, 0xc8, 0xb5, 0x7f, 0x11, + 0x17, 0xa7, 0x2b, 0xf2, 0xc7, 0xb9, 0xe7, 0xc1, 0xac, 0x4d, + 0x77, 0xfc, 0x94, 0xca, 0xdc, 0x08, 0x3e, 0x67, 0x98, 0x40, + 0x50, 0xb7, 0x5e, 0xba, 0xe5, 0xdd, 0x28, 0x09, 0xbd, 0x63, + 0x80, 0x16, 0xf7, 0x23, + }, + .x = { + 0x81, 0xae, 0xe4, 0xbd, 0xd8, 0x2e, 0xd9, 0x64, 0x5a, 0x21, + 0x32, 0x2e, 0x9c, 0x4c, 0x6a, 0x93, 0x85, 0xed, 0x9f, 0x70, + 0xb5, 0xd9, 0x16, 0xc1, 0xb4, 0x3b, 0x62, 0xee, 0xf4, 0xd0, + 0x09, 0x8e, 0xff, 0x3b, 0x1f, 0x78, 0xe2, 0xd0, 0xd4, 0x8d, + 0x50, 0xd1, 0x68, 0x7b, 0x93, 0xb9, 0x7d, 0x5f, 0x7c, 0x6d, + 0x50, 0x47, 0x40, 0x6a, 0x5e, 0x68, 0x8b, 0x35, 0x22, 0x09, + 0xbc, 0xb9, 0xf8, 0x22, + }, + .y = { + 0x7d, 0xde, 0x38, 0x5d, 0x56, 0x63, 0x32, 0xec, 0xc0, 0xea, + 0xbf, 0xa9, 0xcf, 0x78, 0x22, 0xfd, 0xf2, 0x09, 0xf7, 0x00, + 0x24, 0xa5, 0x7b, 0x1a, 0xa0, 0x00, 0xc5, 0x5b, 0x88, 0x1f, + 0x81, 0x11, 0xb2, 0xdc, 0xde, 0x49, 0x4a, 0x5f, 0x48, 0x5e, + 0x5b, 0xca, 0x4b, 0xd8, 0x8a, 0x27, 0x63, 0xae, 0xd1, 0xca, + 0x2b, 0x2f, 0xa8, 0xf0, 0x54, 0x06, 0x78, 0xcd, 0x1e, 0x0f, + 0x3a, 0xd8, 0x08, 0x92, + }, + .order = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, + 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3, + 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, + 0x08, 0x70, 0x55, 0x3e, 0x5c, 0x41, 0x4c, 0xa9, 0x26, 0x19, + 0x41, 0x86, 0x61, 0x19, 0x7f, 0xac, 0x10, 0x47, 0x1d, 0xb1, + 0xd3, 0x81, 0x08, 0x5d, 0xda, 0xdd, 0xb5, 0x87, 0x96, 0x82, + 0x9c, 0xa9, 0x00, 0x69, + }, +}; + +static const struct { + uint8_t p[64]; + uint8_t a[64]; + uint8_t b[64]; + uint8_t x[64]; + uint8_t y[64]; + uint8_t order[64]; +} _EC_brainpoolP512t1 = { + .p = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, + 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3, + 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, + 0x08, 0x71, 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42, + 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, 0x28, 0x81, + 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56, + 0x58, 0x3a, 0x48, 0xf3, + }, + .a = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, + 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3, + 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, + 0x08, 0x71, 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42, + 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, 0x28, 0x81, + 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56, + 0x58, 0x3a, 0x48, 0xf0, + }, + .b = { + 0x7c, 0xbb, 0xbc, 0xf9, 0x44, 0x1c, 0xfa, 0xb7, 0x6e, 0x18, + 0x90, 0xe4, 0x68, 0x84, 0xea, 0xe3, 0x21, 0xf7, 0x0c, 0x0b, + 0xcb, 0x49, 0x81, 0x52, 0x78, 0x97, 0x50, 0x4b, 0xec, 0x3e, + 0x36, 0xa6, 0x2b, 0xcd, 0xfa, 0x23, 0x04, 0x97, 0x65, 0x40, + 0xf6, 0x45, 0x00, 0x85, 0xf2, 0xda, 0xe1, 0x45, 0xc2, 0x25, + 0x53, 0xb4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0e, 0xa2, 0x57, + 0x18, 0x67, 0x42, 0x3e, + }, + .x = { + 0x64, 0x0e, 0xce, 0x5c, 0x12, 0x78, 0x87, 0x17, 0xb9, 0xc1, + 0xba, 0x06, 0xcb, 0xc2, 0xa6, 0xfe, 0xba, 0x85, 0x84, 0x24, + 0x58, 0xc5, 0x6d, 0xde, 0x9d, 0xb1, 0x75, 0x8d, 0x39, 0xc0, + 0x31, 0x3d, 0x82, 0xba, 0x51, 0x73, 0x5c, 0xdb, 0x3e, 0xa4, + 0x99, 0xaa, 0x77, 0xa7, 0xd6, 0x94, 0x3a, 0x64, 0xf7, 0xa3, + 0xf2, 0x5f, 0xe2, 0x6f, 0x06, 0xb5, 0x1b, 0xaa, 0x26, 0x96, + 0xfa, 0x90, 0x35, 0xda, + }, + .y = { + 0x5b, 0x53, 0x4b, 0xd5, 0x95, 0xf5, 0xaf, 0x0f, 0xa2, 0xc8, + 0x92, 0x37, 0x6c, 0x84, 0xac, 0xe1, 0xbb, 0x4e, 0x30, 0x19, + 0xb7, 0x16, 0x34, 0xc0, 0x11, 0x31, 0x15, 0x9c, 0xae, 0x03, + 0xce, 0xe9, 0xd9, 0x93, 0x21, 0x84, 0xbe, 0xef, 0x21, 0x6b, + 0xd7, 0x1d, 0xf2, 0xda, 0xdf, 0x86, 0xa6, 0x27, 0x30, 0x6e, + 0xcf, 0xf9, 0x6d, 0xbb, 0x8b, 0xac, 0xe1, 0x98, 0xb6, 0x1e, + 0x00, 0xf8, 0xb3, 0x32, + }, + .order = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, + 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3, + 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, + 0x08, 0x70, 0x55, 0x3e, 0x5c, 0x41, 0x4c, 0xa9, 0x26, 0x19, + 0x41, 0x86, 0x61, 0x19, 0x7f, 0xac, 0x10, 0x47, 0x1d, 0xb1, + 0xd3, 0x81, 0x08, 0x5d, 0xda, 0xdd, 0xb5, 0x87, 0x96, 0x82, + 0x9c, 0xa9, 0x00, 0x69, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_FRP256v1 = { + .p = { + 0xf1, 0xfd, 0x17, 0x8c, 0x0b, 0x3a, 0xd5, 0x8f, 0x10, 0x12, + 0x6d, 0xe8, 0xce, 0x42, 0x43, 0x5b, 0x39, 0x61, 0xad, 0xbc, + 0xab, 0xc8, 0xca, 0x6d, 0xe8, 0xfc, 0xf3, 0x53, 0xd8, 0x6e, + 0x9c, 0x03, + }, + .a = { + 0xf1, 0xfd, 0x17, 0x8c, 0x0b, 0x3a, 0xd5, 0x8f, 0x10, 0x12, + 0x6d, 0xe8, 0xce, 0x42, 0x43, 0x5b, 0x39, 0x61, 0xad, 0xbc, + 0xab, 0xc8, 0xca, 0x6d, 0xe8, 0xfc, 0xf3, 0x53, 0xd8, 0x6e, + 0x9c, 0x00, + }, + .b = { + 0xee, 0x35, 0x3f, 0xca, 0x54, 0x28, 0xa9, 0x30, 0x0d, 0x4a, + 0xba, 0x75, 0x4a, 0x44, 0xc0, 0x0f, 0xdf, 0xec, 0x0c, 0x9a, + 0xe4, 0xb1, 0xa1, 0x80, 0x30, 0x75, 0xed, 0x96, 0x7b, 0x7b, + 0xb7, 0x3f, + }, + .x = { + 0xb6, 0xb3, 0xd4, 0xc3, 0x56, 0xc1, 0x39, 0xeb, 0x31, 0x18, + 0x3d, 0x47, 0x49, 0xd4, 0x23, 0x95, 0x8c, 0x27, 0xd2, 0xdc, + 0xaf, 0x98, 0xb7, 0x01, 0x64, 0xc9, 0x7a, 0x2d, 0xd9, 0x8f, + 0x5c, 0xff, + }, + .y = { + 0x61, 0x42, 0xe0, 0xf7, 0xc8, 0xb2, 0x04, 0x91, 0x1f, 0x92, + 0x71, 0xf0, 0xf3, 0xec, 0xef, 0x8c, 0x27, 0x01, 0xc3, 0x07, + 0xe8, 0xe4, 0xc9, 0xe1, 0x83, 0x11, 0x5a, 0x15, 0x54, 0x06, + 0x2c, 0xfb, + }, + .order = { + 0xf1, 0xfd, 0x17, 0x8c, 0x0b, 0x3a, 0xd5, 0x8f, 0x10, 0x12, + 0x6d, 0xe8, 0xce, 0x42, 0x43, 0x5b, 0x53, 0xdc, 0x67, 0xe1, + 0x40, 0xd2, 0xbf, 0x94, 0x1f, 0xfd, 0xd4, 0x59, 0xc6, 0xd6, + 0x55, 0xe1, + }, +}; + +#ifndef OPENSSL_NO_GOST +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_GOST_2001_Test = { + .p = { + 0x80, 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, + 0x04, 0x31, + }, + .a = { + 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, 0x07, + }, + .b = { + 0x5f, 0xbf, 0xf4, 0x98, 0xaa, 0x93, 0x8c, 0xe7, 0x39, 0xb8, + 0xe0, 0x22, 0xfb, 0xaf, 0xef, 0x40, 0x56, 0x3f, 0x6e, 0x6a, + 0x34, 0x72, 0xfc, 0x2a, 0x51, 0x4c, 0x0c, 0xe9, 0xda, 0xe2, + 0x3b, 0x7e, + }, + .x = { + 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, 0x02, + }, + .y = { + 0x08, 0xe2, 0xa8, 0xa0, 0xe6, 0x51, 0x47, 0xd4, 0xbd, 0x63, + 0x16, 0x03, 0x0e, 0x16, 0xd1, 0x9c, 0x85, 0xc9, 0x7f, 0x0a, + 0x9c, 0xa2, 0x67, 0x12, 0x2b, 0x96, 0xab, 0xbc, 0xea, 0x7e, + 0x8f, 0xc8, + }, + .order = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0xfe, 0x8a, 0x18, + 0x92, 0x97, 0x61, 0x54, 0xc5, 0x9c, 0xfc, 0x19, 0x3a, 0xcc, + 0xf5, 0xb3, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_GOST_2001_CryptoPro_A = { + .p = { + 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, + 0xfd, 0x97, + }, + .a = { + 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, + 0xfd, 0x94, + }, + .b = { + 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, 0xa6, + }, + .x = { + 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, 0x01, + }, + .y = { + 0x8d, 0x91, 0xe4, 0x71, 0xe0, 0x98, 0x9c, 0xda, 0x27, 0xdf, + 0x50, 0x5a, 0x45, 0x3f, 0x2b, 0x76, 0x35, 0x29, 0x4f, 0x2d, + 0xdf, 0x23, 0xe3, 0xb1, 0x22, 0xac, 0xc9, 0x9c, 0x9e, 0x9f, + 0x1e, 0x14, + }, + .order = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6c, 0x61, 0x10, 0x70, + 0x99, 0x5a, 0xd1, 0x00, 0x45, 0x84, 0x1b, 0x09, 0xb7, 0x61, + 0xb8, 0x93, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_GOST_2001_CryptoPro_B = { + .p = { + 0x80, 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, + 0x0c, 0x99, + }, + .a = { + 0x80, 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, + 0x0c, 0x96, + }, + .b = { + 0x3e, 0x1a, 0xf4, 0x19, 0xa2, 0x69, 0xa5, 0xf8, 0x66, 0xa7, + 0xd3, 0xc2, 0x5c, 0x3d, 0xf8, 0x0a, 0xe9, 0x79, 0x25, 0x93, + 0x73, 0xff, 0x2b, 0x18, 0x2f, 0x49, 0xd4, 0xce, 0x7e, 0x1b, + 0xbc, 0x8b, + }, + .x = { + 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, 0x01, + }, + .y = { + 0x3f, 0xa8, 0x12, 0x43, 0x59, 0xf9, 0x66, 0x80, 0xb8, 0x3d, + 0x1c, 0x3e, 0xb2, 0xc0, 0x70, 0xe5, 0xc5, 0x45, 0xc9, 0x85, + 0x8d, 0x03, 0xec, 0xfb, 0x74, 0x4b, 0xf8, 0xd7, 0x17, 0x71, + 0x7e, 0xfc, + }, + .order = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x70, 0x0c, 0xff, + 0xf1, 0xa6, 0x24, 0xe5, 0xe4, 0x97, 0x16, 0x1b, 0xcc, 0x8a, + 0x19, 0x8f, + }, +}; + +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_GOST_2001_CryptoPro_C = { + .p = { + 0x9b, 0x9f, 0x60, 0x5f, 0x5a, 0x85, 0x81, 0x07, 0xab, 0x1e, + 0xc8, 0x5e, 0x6b, 0x41, 0xc8, 0xaa, 0xcf, 0x84, 0x6e, 0x86, + 0x78, 0x90, 0x51, 0xd3, 0x79, 0x98, 0xf7, 0xb9, 0x02, 0x2d, + 0x75, 0x9b, + }, + .a = { + 0x9b, 0x9f, 0x60, 0x5f, 0x5a, 0x85, 0x81, 0x07, 0xab, 0x1e, + 0xc8, 0x5e, 0x6b, 0x41, 0xc8, 0xaa, 0xcf, 0x84, 0x6e, 0x86, + 0x78, 0x90, 0x51, 0xd3, 0x79, 0x98, 0xf7, 0xb9, 0x02, 0x2d, + 0x75, 0x98, + }, + .b = { + 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, + 0x80, 0x5a, + }, + .x = { + 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, 0x00, + }, + .y = { + 0x41, 0xec, 0xe5, 0x57, 0x43, 0x71, 0x1a, 0x8c, 0x3c, 0xbf, + 0x37, 0x83, 0xcd, 0x08, 0xc0, 0xee, 0x4d, 0x4d, 0xc4, 0x40, + 0xd4, 0x64, 0x1a, 0x8f, 0x36, 0x6e, 0x55, 0x0d, 0xfd, 0xb3, + 0xbb, 0x67, + }, + .order = { + 0x9b, 0x9f, 0x60, 0x5f, 0x5a, 0x85, 0x81, 0x07, 0xab, 0x1e, + 0xc8, 0x5e, 0x6b, 0x41, 0xc8, 0xaa, 0x58, 0x2c, 0xa3, 0x51, + 0x1e, 0xdd, 0xfb, 0x74, 0xf0, 0x2f, 0x3a, 0x65, 0x98, 0x98, + 0x0b, 0xb9, + }, +}; + +/* + * This curve is defined in two birationally equal forms: canonical and Twisted + * Edwards. We do calculations in canonical (Weierstrass) form. + */ +static const struct { + uint8_t p[32]; + uint8_t a[32]; + uint8_t b[32]; + uint8_t x[32]; + uint8_t y[32]; + uint8_t order[32]; +} _EC_GOST_2012_256_TC26_A = { + .p = { + 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, + 0xfd, 0x97, + }, + .a = { + 0xc2, 0x17, 0x3f, 0x15, 0x13, 0x98, 0x16, 0x73, 0xaf, 0x48, + 0x92, 0xc2, 0x30, 0x35, 0xa2, 0x7c, 0xe2, 0x5e, 0x20, 0x13, + 0xbf, 0x95, 0xaa, 0x33, 0xb2, 0x2c, 0x65, 0x6f, 0x27, 0x7e, + 0x73, 0x35, + }, + .b = { + 0x29, 0x5f, 0x9b, 0xae, 0x74, 0x28, 0xed, 0x9c, 0xcc, 0x20, + 0xe7, 0xc3, 0x59, 0xa9, 0xd4, 0x1a, 0x22, 0xfc, 0xcd, 0x91, + 0x08, 0xe1, 0x7b, 0xf7, 0xba, 0x93, 0x37, 0xa6, 0xf8, 0xae, + 0x95, 0x13, + }, + .x = { + 0x91, 0xe3, 0x84, 0x43, 0xa5, 0xe8, 0x2c, 0x0d, 0x88, 0x09, + 0x23, 0x42, 0x57, 0x12, 0xb2, 0xbb, 0x65, 0x8b, 0x91, 0x96, + 0x93, 0x2e, 0x02, 0xc7, 0x8b, 0x25, 0x82, 0xfe, 0x74, 0x2d, + 0xaa, 0x28, + }, + .y = { + 0x32, 0x87, 0x94, 0x23, 0xab, 0x1a, 0x03, 0x75, 0x89, 0x57, + 0x86, 0xc4, 0xbb, 0x46, 0xe9, 0x56, 0x5f, 0xde, 0x0b, 0x53, + 0x44, 0x76, 0x67, 0x40, 0xaf, 0x26, 0x8a, 0xdb, 0x32, 0x32, + 0x2e, 0x5c, + }, + .order = { + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd8, 0xcd, 0xdf, + 0xc8, 0x7b, 0x66, 0x35, 0xc1, 0x15, 0xaf, 0x55, 0x6c, 0x36, + 0x0c, 0x67, + }, +}; + +static const struct { + uint8_t p[64]; + uint8_t a[64]; + uint8_t b[64]; + uint8_t x[64]; + uint8_t y[64]; + uint8_t order[64]; +} _EC_GOST_2012_512_Test = { + .p = { + 0x45, 0x31, 0xac, 0xd1, 0xfe, 0x00, 0x23, 0xc7, 0x55, 0x0d, + 0x26, 0x7b, 0x6b, 0x2f, 0xee, 0x80, 0x92, 0x2b, 0x14, 0xb2, + 0xff, 0xb9, 0x0f, 0x04, 0xd4, 0xeb, 0x7c, 0x09, 0xb5, 0xd2, + 0xd1, 0x5d, 0xf1, 0xd8, 0x52, 0x74, 0x1a, 0xf4, 0x70, 0x4a, + 0x04, 0x58, 0x04, 0x7e, 0x80, 0xe4, 0x54, 0x6d, 0x35, 0xb8, + 0x33, 0x6f, 0xac, 0x22, 0x4d, 0xd8, 0x16, 0x64, 0xbb, 0xf5, + 0x28, 0xbe, 0x63, 0x73, + }, + .a = { + 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, 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, 0x00, 0x07, + }, + .b = { + 0x1c, 0xff, 0x08, 0x06, 0xa3, 0x11, 0x16, 0xda, 0x29, 0xd8, + 0xcf, 0xa5, 0x4e, 0x57, 0xeb, 0x74, 0x8b, 0xc5, 0xf3, 0x77, + 0xe4, 0x94, 0x00, 0xfd, 0xd7, 0x88, 0xb6, 0x49, 0xec, 0xa1, + 0xac, 0x43, 0x61, 0x83, 0x40, 0x13, 0xb2, 0xad, 0x73, 0x22, + 0x48, 0x0a, 0x89, 0xca, 0x58, 0xe0, 0xcf, 0x74, 0xbc, 0x9e, + 0x54, 0x0c, 0x2a, 0xdd, 0x68, 0x97, 0xfa, 0xd0, 0xa3, 0x08, + 0x4f, 0x30, 0x2a, 0xdc, + }, + .x = { + 0x24, 0xd1, 0x9c, 0xc6, 0x45, 0x72, 0xee, 0x30, 0xf3, 0x96, + 0xbf, 0x6e, 0xbb, 0xfd, 0x7a, 0x6c, 0x52, 0x13, 0xb3, 0xb3, + 0xd7, 0x05, 0x7c, 0xc8, 0x25, 0xf9, 0x10, 0x93, 0xa6, 0x8c, + 0xd7, 0x62, 0xfd, 0x60, 0x61, 0x12, 0x62, 0xcd, 0x83, 0x8d, + 0xc6, 0xb6, 0x0a, 0xa7, 0xee, 0xe8, 0x04, 0xe2, 0x8b, 0xc8, + 0x49, 0x97, 0x7f, 0xac, 0x33, 0xb4, 0xb5, 0x30, 0xf1, 0xb1, + 0x20, 0x24, 0x8a, 0x9a, + }, + .y = { + 0x2b, 0xb3, 0x12, 0xa4, 0x3b, 0xd2, 0xce, 0x6e, 0x0d, 0x02, + 0x06, 0x13, 0xc8, 0x57, 0xac, 0xdd, 0xcf, 0xbf, 0x06, 0x1e, + 0x91, 0xe5, 0xf2, 0xc3, 0xf3, 0x24, 0x47, 0xc2, 0x59, 0xf3, + 0x9b, 0x2c, 0x83, 0xab, 0x15, 0x6d, 0x77, 0xf1, 0x49, 0x6b, + 0xf7, 0xeb, 0x33, 0x51, 0xe1, 0xee, 0x4e, 0x43, 0xdc, 0x1a, + 0x18, 0xb9, 0x1b, 0x24, 0x64, 0x0b, 0x6d, 0xbb, 0x92, 0xcb, + 0x1a, 0xdd, 0x37, 0x1e, + }, + .order = { + 0x45, 0x31, 0xac, 0xd1, 0xfe, 0x00, 0x23, 0xc7, 0x55, 0x0d, + 0x26, 0x7b, 0x6b, 0x2f, 0xee, 0x80, 0x92, 0x2b, 0x14, 0xb2, + 0xff, 0xb9, 0x0f, 0x04, 0xd4, 0xeb, 0x7c, 0x09, 0xb5, 0xd2, + 0xd1, 0x5d, 0xa8, 0x2f, 0x2d, 0x7e, 0xcb, 0x1d, 0xba, 0xc7, + 0x19, 0x90, 0x5c, 0x5e, 0xec, 0xc4, 0x23, 0xf1, 0xd8, 0x6e, + 0x25, 0xed, 0xbe, 0x23, 0xc5, 0x95, 0xd6, 0x44, 0xaa, 0xf1, + 0x87, 0xe6, 0xe6, 0xdf, + }, +}; + +static const struct { + uint8_t p[64]; + uint8_t a[64]; + uint8_t b[64]; + uint8_t x[64]; + uint8_t y[64]; + uint8_t order[64]; +} _EC_GOST_2012_512_TC26_A = { + .p = { + 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, 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, 0xfd, 0xc7, + }, + .a = { + 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, 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, 0xfd, 0xc4, + }, + .b = { + 0xe8, 0xc2, 0x50, 0x5d, 0xed, 0xfc, 0x86, 0xdd, 0xc1, 0xbd, + 0x0b, 0x2b, 0x66, 0x67, 0xf1, 0xda, 0x34, 0xb8, 0x25, 0x74, + 0x76, 0x1c, 0xb0, 0xe8, 0x79, 0xbd, 0x08, 0x1c, 0xfd, 0x0b, + 0x62, 0x65, 0xee, 0x3c, 0xb0, 0x90, 0xf3, 0x0d, 0x27, 0x61, + 0x4c, 0xb4, 0x57, 0x40, 0x10, 0xda, 0x90, 0xdd, 0x86, 0x2e, + 0xf9, 0xd4, 0xeb, 0xee, 0x47, 0x61, 0x50, 0x31, 0x90, 0x78, + 0x5a, 0x71, 0xc7, 0x60, + }, + .x = { + 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, 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, 0x00, 0x03, + }, + .y = { + 0x75, 0x03, 0xcf, 0xe8, 0x7a, 0x83, 0x6a, 0xe3, 0xa6, 0x1b, + 0x88, 0x16, 0xe2, 0x54, 0x50, 0xe6, 0xce, 0x5e, 0x1c, 0x93, + 0xac, 0xf1, 0xab, 0xc1, 0x77, 0x80, 0x64, 0xfd, 0xcb, 0xef, + 0xa9, 0x21, 0xdf, 0x16, 0x26, 0xbe, 0x4f, 0xd0, 0x36, 0xe9, + 0x3d, 0x75, 0xe6, 0xa5, 0x0e, 0x3a, 0x41, 0xe9, 0x80, 0x28, + 0xfe, 0x5f, 0xc2, 0x35, 0xf5, 0xb8, 0x89, 0xa5, 0x89, 0xcb, + 0x52, 0x15, 0xf2, 0xa4, + }, + .order = { + 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, 0x27, 0xe6, 0x95, 0x32, 0xf4, 0x8d, 0x89, 0x11, + 0x6f, 0xf2, 0x2b, 0x8d, 0x4e, 0x05, 0x60, 0x60, 0x9b, 0x4b, + 0x38, 0xab, 0xfa, 0xd2, 0xb8, 0x5d, 0xca, 0xcd, 0xb1, 0x41, + 0x1f, 0x10, 0xb2, 0x75, + }, +}; + +static const struct { + uint8_t p[64]; + uint8_t a[64]; + uint8_t b[64]; + uint8_t x[64]; + uint8_t y[64]; + uint8_t order[64]; +} _EC_GOST_2012_512_TC26_B = { + .p = { + 0x80, 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, 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, 0x6f, + }, + .a = { + 0x80, 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, 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, 0x6c, + }, + .b = { + 0x68, 0x7d, 0x1b, 0x45, 0x9d, 0xc8, 0x41, 0x45, 0x7e, 0x3e, + 0x06, 0xcf, 0x6f, 0x5e, 0x25, 0x17, 0xb9, 0x7c, 0x7d, 0x61, + 0x4a, 0xf1, 0x38, 0xbc, 0xbf, 0x85, 0xdc, 0x80, 0x6c, 0x4b, + 0x28, 0x9f, 0x3e, 0x96, 0x5d, 0x2d, 0xb1, 0x41, 0x6d, 0x21, + 0x7f, 0x8b, 0x27, 0x6f, 0xad, 0x1a, 0xb6, 0x9c, 0x50, 0xf7, + 0x8b, 0xee, 0x1f, 0xa3, 0x10, 0x6e, 0xfb, 0x8c, 0xcb, 0xc7, + 0xc5, 0x14, 0x01, 0x16, + }, + .x = { + 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, 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, 0x00, 0x02, + }, + .y = { + 0x1a, 0x8f, 0x7e, 0xda, 0x38, 0x9b, 0x09, 0x4c, 0x2c, 0x07, + 0x1e, 0x36, 0x47, 0xa8, 0x94, 0x0f, 0x3c, 0x12, 0x3b, 0x69, + 0x75, 0x78, 0xc2, 0x13, 0xbe, 0x6d, 0xd9, 0xe6, 0xc8, 0xec, + 0x73, 0x35, 0xdc, 0xb2, 0x28, 0xfd, 0x1e, 0xdf, 0x4a, 0x39, + 0x15, 0x2c, 0xbc, 0xaa, 0xf8, 0xc0, 0x39, 0x88, 0x28, 0x04, + 0x10, 0x55, 0xf9, 0x4c, 0xee, 0xec, 0x7e, 0x21, 0x34, 0x07, + 0x80, 0xfe, 0x41, 0xbd, + }, + .order = { + 0x80, 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, 0x01, 0x49, 0xa1, 0xec, 0x14, 0x25, 0x65, 0xa5, 0x45, + 0xac, 0xfd, 0xb7, 0x7b, 0xd9, 0xd4, 0x0c, 0xfa, 0x8b, 0x99, + 0x67, 0x12, 0x10, 0x1b, 0xea, 0x0e, 0xc6, 0x34, 0x6c, 0x54, + 0x37, 0x4f, 0x25, 0xbd, + }, +}; + +/* + * This curve is defined in two birationally equal forms: canonical and Twisted + * Edwards. We do calculations in canonical (Weierstrass) form. + */ +static const struct { + uint8_t p[64]; + uint8_t a[64]; + uint8_t b[64]; + uint8_t x[64]; + uint8_t y[64]; + uint8_t order[64]; +} _EC_GOST_2012_512_TC26_C = { + .p = { + 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, 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, 0xfd, 0xc7, + }, + .a = { + 0xdc, 0x92, 0x03, 0xe5, 0x14, 0xa7, 0x21, 0x87, 0x54, 0x85, + 0xa5, 0x29, 0xd2, 0xc7, 0x22, 0xfb, 0x18, 0x7b, 0xc8, 0x98, + 0x0e, 0xb8, 0x66, 0x64, 0x4d, 0xe4, 0x1c, 0x68, 0xe1, 0x43, + 0x06, 0x45, 0x46, 0xe8, 0x61, 0xc0, 0xe2, 0xc9, 0xed, 0xd9, + 0x2a, 0xde, 0x71, 0xf4, 0x6f, 0xcf, 0x50, 0xff, 0x2a, 0xd9, + 0x7f, 0x95, 0x1f, 0xda, 0x9f, 0x2a, 0x2e, 0xb6, 0x54, 0x6f, + 0x39, 0x68, 0x9b, 0xd3, + }, + .b = { + 0xb4, 0xc4, 0xee, 0x28, 0xce, 0xbc, 0x6c, 0x2c, 0x8a, 0xc1, + 0x29, 0x52, 0xcf, 0x37, 0xf1, 0x6a, 0xc7, 0xef, 0xb6, 0xa9, + 0xf6, 0x9f, 0x4b, 0x57, 0xff, 0xda, 0x2e, 0x4f, 0x0d, 0xe5, + 0xad, 0xe0, 0x38, 0xcb, 0xc2, 0xff, 0xf7, 0x19, 0xd2, 0xc1, + 0x8d, 0xe0, 0x28, 0x4b, 0x8b, 0xfe, 0xf3, 0xb5, 0x2b, 0x8c, + 0xc7, 0xa5, 0xf5, 0xbf, 0x0a, 0x3c, 0x8d, 0x23, 0x19, 0xa5, + 0x31, 0x25, 0x57, 0xe1, + }, + .x = { + 0xe2, 0xe3, 0x1e, 0xdf, 0xc2, 0x3d, 0xe7, 0xbd, 0xeb, 0xe2, + 0x41, 0xce, 0x59, 0x3e, 0xf5, 0xde, 0x22, 0x95, 0xb7, 0xa9, + 0xcb, 0xae, 0xf0, 0x21, 0xd3, 0x85, 0xf7, 0x07, 0x4c, 0xea, + 0x04, 0x3a, 0xa2, 0x72, 0x72, 0xa7, 0xae, 0x60, 0x2b, 0xf2, + 0xa7, 0xb9, 0x03, 0x3d, 0xb9, 0xed, 0x36, 0x10, 0xc6, 0xfb, + 0x85, 0x48, 0x7e, 0xae, 0x97, 0xaa, 0xc5, 0xbc, 0x79, 0x28, + 0xc1, 0x95, 0x01, 0x48, + }, + .y = { + 0xf5, 0xce, 0x40, 0xd9, 0x5b, 0x5e, 0xb8, 0x99, 0xab, 0xbc, + 0xcf, 0xf5, 0x91, 0x1c, 0xb8, 0x57, 0x79, 0x39, 0x80, 0x4d, + 0x65, 0x27, 0x37, 0x8b, 0x8c, 0x10, 0x8c, 0x3d, 0x20, 0x90, + 0xff, 0x9b, 0xe1, 0x8e, 0x2d, 0x33, 0xe3, 0x02, 0x1e, 0xd2, + 0xef, 0x32, 0xd8, 0x58, 0x22, 0x42, 0x3b, 0x63, 0x04, 0xf7, + 0x26, 0xaa, 0x85, 0x4b, 0xae, 0x07, 0xd0, 0x39, 0x6e, 0x9a, + 0x9a, 0xdd, 0xc4, 0x0f, + }, + .order = { + 0x3f, 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, 0xc9, 0x8c, 0xdb, 0xa4, 0x65, 0x06, 0xab, 0x00, + 0x4c, 0x33, 0xa9, 0xff, 0x51, 0x47, 0x50, 0x2c, 0xc8, 0xed, + 0xa9, 0xe7, 0xa7, 0x69, 0xa1, 0x26, 0x94, 0x62, 0x3c, 0xef, + 0x47, 0xf0, 0x23, 0xed, + }, +}; +#endif + +static const struct ec_list_element { + const char *comment; + int nid; + int seed_len; + int param_len; + unsigned int cofactor; + const uint8_t *seed; + const uint8_t *p; + const uint8_t *a; + const uint8_t *b; + const uint8_t *x; + const uint8_t *y; + const uint8_t *order; +} curve_list[] = { + /* secg curves */ + { + .comment = "SECG/WTLS curve over a 112 bit prime field", + .nid = NID_secp112r1, + .seed_len = sizeof(_EC_SECG_PRIME_112R1.seed), + .param_len = sizeof(_EC_SECG_PRIME_112R1.p), + .seed = _EC_SECG_PRIME_112R1.seed, + .p = _EC_SECG_PRIME_112R1.p, + .a = _EC_SECG_PRIME_112R1.a, + .b = _EC_SECG_PRIME_112R1.b, + .x = _EC_SECG_PRIME_112R1.x, + .y = _EC_SECG_PRIME_112R1.y, + .order = _EC_SECG_PRIME_112R1.order, + .cofactor = 1, + }, + { + .comment = "SECG curve over a 112 bit prime field", + .nid = NID_secp112r2, + .seed_len = sizeof(_EC_SECG_PRIME_112R2.seed), + .param_len = sizeof(_EC_SECG_PRIME_112R2.p), + .seed = _EC_SECG_PRIME_112R2.seed, + .p = _EC_SECG_PRIME_112R2.p, + .a = _EC_SECG_PRIME_112R2.a, + .b = _EC_SECG_PRIME_112R2.b, + .x = _EC_SECG_PRIME_112R2.x, + .y = _EC_SECG_PRIME_112R2.y, + .order = _EC_SECG_PRIME_112R2.order, + .cofactor = 4, + }, + { + .comment = "SECG curve over a 128 bit prime field", + .nid = NID_secp128r1, + .seed_len = sizeof(_EC_SECG_PRIME_128R1.seed), + .param_len = sizeof(_EC_SECG_PRIME_128R1.p), + .seed = _EC_SECG_PRIME_128R1.seed, + .p = _EC_SECG_PRIME_128R1.p, + .a = _EC_SECG_PRIME_128R1.a, + .b = _EC_SECG_PRIME_128R1.b, + .x = _EC_SECG_PRIME_128R1.x, + .y = _EC_SECG_PRIME_128R1.y, + .order = _EC_SECG_PRIME_128R1.order, + .cofactor = 1, + }, + { + .comment = "SECG curve over a 128 bit prime field", + .nid = NID_secp128r2, + .seed_len = sizeof(_EC_SECG_PRIME_128R2.seed), + .param_len = sizeof(_EC_SECG_PRIME_128R2.p), + .seed = _EC_SECG_PRIME_128R2.seed, + .p = _EC_SECG_PRIME_128R2.p, + .a = _EC_SECG_PRIME_128R2.a, + .b = _EC_SECG_PRIME_128R2.b, + .x = _EC_SECG_PRIME_128R2.x, + .y = _EC_SECG_PRIME_128R2.y, + .order = _EC_SECG_PRIME_128R2.order, + .cofactor = 4, + }, + { + .comment = "SECG curve over a 160 bit prime field", + .nid = NID_secp160k1, + .param_len = sizeof(_EC_SECG_PRIME_160K1.p), + .p = _EC_SECG_PRIME_160K1.p, + .a = _EC_SECG_PRIME_160K1.a, + .b = _EC_SECG_PRIME_160K1.b, + .x = _EC_SECG_PRIME_160K1.x, + .y = _EC_SECG_PRIME_160K1.y, + .order = _EC_SECG_PRIME_160K1.order, + .cofactor = 1, + }, + { + .comment = "SECG curve over a 160 bit prime field", + .nid = NID_secp160r1, + .seed_len = sizeof(_EC_SECG_PRIME_160R1.seed), + .param_len = sizeof(_EC_SECG_PRIME_160R1.p), + .seed = _EC_SECG_PRIME_160R1.seed, + .p = _EC_SECG_PRIME_160R1.p, + .a = _EC_SECG_PRIME_160R1.a, + .b = _EC_SECG_PRIME_160R1.b, + .x = _EC_SECG_PRIME_160R1.x, + .y = _EC_SECG_PRIME_160R1.y, + .order = _EC_SECG_PRIME_160R1.order, + .cofactor = 1, + }, + { + .comment = "SECG/WTLS curve over a 160 bit prime field", + .nid = NID_secp160r2, + .seed_len = sizeof(_EC_SECG_PRIME_160R2.seed), + .param_len = sizeof(_EC_SECG_PRIME_160R2.p), + .seed = _EC_SECG_PRIME_160R2.seed, + .p = _EC_SECG_PRIME_160R2.p, + .a = _EC_SECG_PRIME_160R2.a, + .b = _EC_SECG_PRIME_160R2.b, + .x = _EC_SECG_PRIME_160R2.x, + .y = _EC_SECG_PRIME_160R2.y, + .order = _EC_SECG_PRIME_160R2.order, + .cofactor = 1, + }, + /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ + { + .comment = "SECG curve over a 192 bit prime field", + .nid = NID_secp192k1, + .param_len = sizeof(_EC_SECG_PRIME_192K1.p), + .p = _EC_SECG_PRIME_192K1.p, + .a = _EC_SECG_PRIME_192K1.a, + .b = _EC_SECG_PRIME_192K1.b, + .x = _EC_SECG_PRIME_192K1.x, + .y = _EC_SECG_PRIME_192K1.y, + .order = _EC_SECG_PRIME_192K1.order, + .cofactor = 1, + }, + { + .comment = "SECG curve over a 224 bit prime field", + .nid = NID_secp224k1, + .param_len = sizeof(_EC_SECG_PRIME_224K1.p), + .p = _EC_SECG_PRIME_224K1.p, + .a = _EC_SECG_PRIME_224K1.a, + .b = _EC_SECG_PRIME_224K1.b, + .x = _EC_SECG_PRIME_224K1.x, + .y = _EC_SECG_PRIME_224K1.y, + .order = _EC_SECG_PRIME_224K1.order, + .cofactor = 1, + }, + { + .comment = "NIST/SECG curve over a 224 bit prime field", + .nid = NID_secp224r1, + .seed_len = sizeof(_EC_NIST_PRIME_224.seed), + .param_len = sizeof(_EC_NIST_PRIME_224.p), + .seed = _EC_NIST_PRIME_224.seed, + .p = _EC_NIST_PRIME_224.p, + .a = _EC_NIST_PRIME_224.a, + .b = _EC_NIST_PRIME_224.b, + .x = _EC_NIST_PRIME_224.x, + .y = _EC_NIST_PRIME_224.y, + .order = _EC_NIST_PRIME_224.order, + .cofactor = 1, + }, + { + .comment = "SECG curve over a 256 bit prime field", + .nid = NID_secp256k1, + .param_len = sizeof(_EC_SECG_PRIME_256K1.p), + .p = _EC_SECG_PRIME_256K1.p, + .a = _EC_SECG_PRIME_256K1.a, + .b = _EC_SECG_PRIME_256K1.b, + .x = _EC_SECG_PRIME_256K1.x, + .y = _EC_SECG_PRIME_256K1.y, + .order = _EC_SECG_PRIME_256K1.order, + .cofactor = 1, + }, + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + { + .comment = "NIST/SECG curve over a 384 bit prime field", + .nid = NID_secp384r1, + .seed_len = sizeof(_EC_NIST_PRIME_384.seed), + .param_len = sizeof(_EC_NIST_PRIME_384.p), + .seed = _EC_NIST_PRIME_384.seed, + .p = _EC_NIST_PRIME_384.p, + .a = _EC_NIST_PRIME_384.a, + .b = _EC_NIST_PRIME_384.b, + .x = _EC_NIST_PRIME_384.x, + .y = _EC_NIST_PRIME_384.y, + .order = _EC_NIST_PRIME_384.order, + .cofactor = 1, + }, + { + .comment = "NIST/SECG curve over a 521 bit prime field", + .nid = NID_secp521r1, + .seed_len = sizeof(_EC_NIST_PRIME_521.seed), + .param_len = sizeof(_EC_NIST_PRIME_521.p), + .seed = _EC_NIST_PRIME_521.seed, + .p = _EC_NIST_PRIME_521.p, + .a = _EC_NIST_PRIME_521.a, + .b = _EC_NIST_PRIME_521.b, + .x = _EC_NIST_PRIME_521.x, + .y = _EC_NIST_PRIME_521.y, + .order = _EC_NIST_PRIME_521.order, + .cofactor = 1, + }, + /* X9.62 curves */ + { + .comment = "NIST/X9.62/SECG curve over a 192 bit prime field", + .nid = NID_X9_62_prime192v1, + .seed_len = sizeof(_EC_NIST_PRIME_192.seed), + .param_len = sizeof(_EC_NIST_PRIME_192.p), + .seed = _EC_NIST_PRIME_192.seed, + .p = _EC_NIST_PRIME_192.p, + .a = _EC_NIST_PRIME_192.a, + .b = _EC_NIST_PRIME_192.b, + .x = _EC_NIST_PRIME_192.x, + .y = _EC_NIST_PRIME_192.y, + .order = _EC_NIST_PRIME_192.order, + .cofactor = 1, + }, + { + .comment = "X9.62 curve over a 192 bit prime field", + .nid = NID_X9_62_prime192v2, + .seed_len = sizeof(_EC_X9_62_PRIME_192V2.seed), + .param_len = sizeof(_EC_X9_62_PRIME_192V2.p), + .seed = _EC_X9_62_PRIME_192V2.seed, + .p = _EC_X9_62_PRIME_192V2.p, + .a = _EC_X9_62_PRIME_192V2.a, + .b = _EC_X9_62_PRIME_192V2.b, + .x = _EC_X9_62_PRIME_192V2.x, + .y = _EC_X9_62_PRIME_192V2.y, + .order = _EC_X9_62_PRIME_192V2.order, + .cofactor = 1, + }, + { + .comment = "X9.62 curve over a 192 bit prime field", + .nid = NID_X9_62_prime192v3, + .seed_len = sizeof(_EC_X9_62_PRIME_192V3.seed), + .param_len = sizeof(_EC_X9_62_PRIME_192V3.p), + .seed = _EC_X9_62_PRIME_192V3.seed, + .p = _EC_X9_62_PRIME_192V3.p, + .a = _EC_X9_62_PRIME_192V3.a, + .b = _EC_X9_62_PRIME_192V3.b, + .x = _EC_X9_62_PRIME_192V3.x, + .y = _EC_X9_62_PRIME_192V3.y, + .order = _EC_X9_62_PRIME_192V3.order, + .cofactor = 1, + }, + { + .comment = "X9.62 curve over a 239 bit prime field", + .nid = NID_X9_62_prime239v1, + .seed_len = sizeof(_EC_X9_62_PRIME_239V1.seed), + .param_len = sizeof(_EC_X9_62_PRIME_239V1.p), + .seed = _EC_X9_62_PRIME_239V1.seed, + .p = _EC_X9_62_PRIME_239V1.p, + .a = _EC_X9_62_PRIME_239V1.a, + .b = _EC_X9_62_PRIME_239V1.b, + .x = _EC_X9_62_PRIME_239V1.x, + .y = _EC_X9_62_PRIME_239V1.y, + .order = _EC_X9_62_PRIME_239V1.order, + .cofactor = 1, + }, + { + .comment = "X9.62 curve over a 239 bit prime field", + .nid = NID_X9_62_prime239v2, + .seed_len = sizeof(_EC_X9_62_PRIME_239V2.seed), + .param_len = sizeof(_EC_X9_62_PRIME_239V2.p), + .seed = _EC_X9_62_PRIME_239V2.seed, + .p = _EC_X9_62_PRIME_239V2.p, + .a = _EC_X9_62_PRIME_239V2.a, + .b = _EC_X9_62_PRIME_239V2.b, + .x = _EC_X9_62_PRIME_239V2.x, + .y = _EC_X9_62_PRIME_239V2.y, + .order = _EC_X9_62_PRIME_239V2.order, + .cofactor = 1, + }, + { + .comment = "X9.62 curve over a 239 bit prime field", + .nid = NID_X9_62_prime239v3, + .seed_len = sizeof(_EC_X9_62_PRIME_239V3.seed), + .param_len = sizeof(_EC_X9_62_PRIME_239V3.p), + .seed = _EC_X9_62_PRIME_239V3.seed, + .p = _EC_X9_62_PRIME_239V3.p, + .a = _EC_X9_62_PRIME_239V3.a, + .b = _EC_X9_62_PRIME_239V3.b, + .x = _EC_X9_62_PRIME_239V3.x, + .y = _EC_X9_62_PRIME_239V3.y, + .order = _EC_X9_62_PRIME_239V3.order, + .cofactor = 1, + }, + { + .comment = "X9.62/SECG curve over a 256 bit prime field", + .nid = NID_X9_62_prime256v1, + .seed_len = sizeof(_EC_X9_62_PRIME_256V1.seed), + .param_len = sizeof(_EC_X9_62_PRIME_256V1.p), + .seed = _EC_X9_62_PRIME_256V1.seed, + .p = _EC_X9_62_PRIME_256V1.p, + .a = _EC_X9_62_PRIME_256V1.a, + .b = _EC_X9_62_PRIME_256V1.b, + .x = _EC_X9_62_PRIME_256V1.x, + .y = _EC_X9_62_PRIME_256V1.y, + .order = _EC_X9_62_PRIME_256V1.order, + .cofactor = 1, + }, + { + .comment = "SECG/WTLS curve over a 112 bit prime field", + .nid = NID_wap_wsg_idm_ecid_wtls6, + .seed_len = sizeof(_EC_SECG_PRIME_112R1.seed), + .param_len = sizeof(_EC_SECG_PRIME_112R1.p), + .seed = _EC_SECG_PRIME_112R1.seed, + .p = _EC_SECG_PRIME_112R1.p, + .a = _EC_SECG_PRIME_112R1.a, + .b = _EC_SECG_PRIME_112R1.b, + .x = _EC_SECG_PRIME_112R1.x, + .y = _EC_SECG_PRIME_112R1.y, + .order = _EC_SECG_PRIME_112R1.order, + .cofactor = 1, + }, + { + .comment = "SECG/WTLS curve over a 160 bit prime field", + .nid = NID_wap_wsg_idm_ecid_wtls7, + .seed_len = sizeof(_EC_SECG_PRIME_160R2.seed), + .param_len = sizeof(_EC_SECG_PRIME_160R2.p), + .seed = _EC_SECG_PRIME_160R2.seed, + .p = _EC_SECG_PRIME_160R2.p, + .a = _EC_SECG_PRIME_160R2.a, + .b = _EC_SECG_PRIME_160R2.b, + .x = _EC_SECG_PRIME_160R2.x, + .y = _EC_SECG_PRIME_160R2.y, + .order = _EC_SECG_PRIME_160R2.order, + .cofactor = 1, + }, + { + .comment = "WTLS curve over a 112 bit prime field", + .nid = NID_wap_wsg_idm_ecid_wtls8, + .param_len = sizeof(_EC_WTLS_8.p), + .p = _EC_WTLS_8.p, + .a = _EC_WTLS_8.a, + .b = _EC_WTLS_8.b, + .x = _EC_WTLS_8.x, + .y = _EC_WTLS_8.y, + .order = _EC_WTLS_8.order, + .cofactor = 1, + }, + { + .comment = "WTLS curve over a 160 bit prime field", + .nid = NID_wap_wsg_idm_ecid_wtls9, + .param_len = sizeof(_EC_WTLS_9.p), + .p = _EC_WTLS_9.p, + .a = _EC_WTLS_9.a, + .b = _EC_WTLS_9.b, + .x = _EC_WTLS_9.x, + .y = _EC_WTLS_9.y, + .order = _EC_WTLS_9.order, + .cofactor = 1, + }, + { + .comment = "WTLS curve over a 224 bit prime field", + .nid = NID_wap_wsg_idm_ecid_wtls12, + .param_len = sizeof(_EC_WTLS_12.p), + .p = _EC_WTLS_12.p, + .a = _EC_WTLS_12.a, + .b = _EC_WTLS_12.b, + .x = _EC_WTLS_12.x, + .y = _EC_WTLS_12.y, + .order = _EC_WTLS_12.order, + .cofactor = 1, + }, + /* RFC 5639 curves */ + { + .comment = "RFC 5639 curve over a 160 bit prime field", + .nid = NID_brainpoolP160r1, + .param_len = sizeof(_EC_brainpoolP160r1.p), + .p = _EC_brainpoolP160r1.p, + .a = _EC_brainpoolP160r1.a, + .b = _EC_brainpoolP160r1.b, + .x = _EC_brainpoolP160r1.x, + .y = _EC_brainpoolP160r1.y, + .order = _EC_brainpoolP160r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 160 bit prime field", + .nid = NID_brainpoolP160t1, + .param_len = sizeof(_EC_brainpoolP160t1.p), + .p = _EC_brainpoolP160t1.p, + .a = _EC_brainpoolP160t1.a, + .b = _EC_brainpoolP160t1.b, + .x = _EC_brainpoolP160t1.x, + .y = _EC_brainpoolP160t1.y, + .order = _EC_brainpoolP160t1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 192 bit prime field", + .nid = NID_brainpoolP192r1, + .param_len = sizeof(_EC_brainpoolP192r1.p), + .p = _EC_brainpoolP192r1.p, + .a = _EC_brainpoolP192r1.a, + .b = _EC_brainpoolP192r1.b, + .x = _EC_brainpoolP192r1.x, + .y = _EC_brainpoolP192r1.y, + .order = _EC_brainpoolP192r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 192 bit prime field", + .nid = NID_brainpoolP192t1, + .param_len = sizeof(_EC_brainpoolP192t1.p), + .p = _EC_brainpoolP192t1.p, + .a = _EC_brainpoolP192t1.a, + .b = _EC_brainpoolP192t1.b, + .x = _EC_brainpoolP192t1.x, + .y = _EC_brainpoolP192t1.y, + .order = _EC_brainpoolP192t1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 224 bit prime field", + .nid = NID_brainpoolP224r1, + .param_len = sizeof(_EC_brainpoolP224r1.p), + .p = _EC_brainpoolP224r1.p, + .a = _EC_brainpoolP224r1.a, + .b = _EC_brainpoolP224r1.b, + .x = _EC_brainpoolP224r1.x, + .y = _EC_brainpoolP224r1.y, + .order = _EC_brainpoolP224r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 224 bit prime field", + .nid = NID_brainpoolP224t1, + .param_len = sizeof(_EC_brainpoolP224t1.p), + .p = _EC_brainpoolP224t1.p, + .a = _EC_brainpoolP224t1.a, + .b = _EC_brainpoolP224t1.b, + .x = _EC_brainpoolP224t1.x, + .y = _EC_brainpoolP224t1.y, + .order = _EC_brainpoolP224t1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 256 bit prime field", + .nid = NID_brainpoolP256r1, + .param_len = sizeof(_EC_brainpoolP256r1.p), + .p = _EC_brainpoolP256r1.p, + .a = _EC_brainpoolP256r1.a, + .b = _EC_brainpoolP256r1.b, + .x = _EC_brainpoolP256r1.x, + .y = _EC_brainpoolP256r1.y, + .order = _EC_brainpoolP256r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 256 bit prime field", + .nid = NID_brainpoolP256t1, + .param_len = sizeof(_EC_brainpoolP256t1.p), + .p = _EC_brainpoolP256t1.p, + .a = _EC_brainpoolP256t1.a, + .b = _EC_brainpoolP256t1.b, + .x = _EC_brainpoolP256t1.x, + .y = _EC_brainpoolP256t1.y, + .order = _EC_brainpoolP256t1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 320 bit prime field", + .nid = NID_brainpoolP320r1, + .param_len = sizeof(_EC_brainpoolP320r1.p), + .p = _EC_brainpoolP320r1.p, + .a = _EC_brainpoolP320r1.a, + .b = _EC_brainpoolP320r1.b, + .x = _EC_brainpoolP320r1.x, + .y = _EC_brainpoolP320r1.y, + .order = _EC_brainpoolP320r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 320 bit prime field", + .nid = NID_brainpoolP320t1, + .param_len = sizeof(_EC_brainpoolP320t1.p), + .p = _EC_brainpoolP320t1.p, + .a = _EC_brainpoolP320t1.a, + .b = _EC_brainpoolP320t1.b, + .x = _EC_brainpoolP320t1.x, + .y = _EC_brainpoolP320t1.y, + .order = _EC_brainpoolP320t1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 384 bit prime field", + .nid = NID_brainpoolP384r1, + .param_len = sizeof(_EC_brainpoolP384r1.p), + .p = _EC_brainpoolP384r1.p, + .a = _EC_brainpoolP384r1.a, + .b = _EC_brainpoolP384r1.b, + .x = _EC_brainpoolP384r1.x, + .y = _EC_brainpoolP384r1.y, + .order = _EC_brainpoolP384r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 384 bit prime field", + .nid = NID_brainpoolP384t1, + .param_len = sizeof(_EC_brainpoolP384t1.p), + .p = _EC_brainpoolP384t1.p, + .a = _EC_brainpoolP384t1.a, + .b = _EC_brainpoolP384t1.b, + .x = _EC_brainpoolP384t1.x, + .y = _EC_brainpoolP384t1.y, + .order = _EC_brainpoolP384t1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 512 bit prime field", + .nid = NID_brainpoolP512r1, + .param_len = sizeof(_EC_brainpoolP512r1.p), + .p = _EC_brainpoolP512r1.p, + .a = _EC_brainpoolP512r1.a, + .b = _EC_brainpoolP512r1.b, + .x = _EC_brainpoolP512r1.x, + .y = _EC_brainpoolP512r1.y, + .order = _EC_brainpoolP512r1.order, + .cofactor = 1, + }, + { + .comment = "RFC 5639 curve over a 512 bit prime field", + .nid = NID_brainpoolP512t1, + .param_len = sizeof(_EC_brainpoolP512t1.p), + .p = _EC_brainpoolP512t1.p, + .a = _EC_brainpoolP512t1.a, + .b = _EC_brainpoolP512t1.b, + .x = _EC_brainpoolP512t1.x, + .y = _EC_brainpoolP512t1.y, + .order = _EC_brainpoolP512t1.order, + .cofactor = 1, + }, + /* ANSSI */ + { + .comment = "FRP256v1", + .nid = NID_FRP256v1, + .param_len = sizeof(_EC_FRP256v1.p), + .p = _EC_FRP256v1.p, + .a = _EC_FRP256v1.a, + .b = _EC_FRP256v1.b, + .x = _EC_FRP256v1.x, + .y = _EC_FRP256v1.y, + .order = _EC_FRP256v1.order, + .cofactor = 1, + }, +#ifndef OPENSSL_NO_GOST + /* GOST R 34.10-2001 */ + { + .comment = "GOST R 34.10-2001 Test Curve", + .nid = NID_id_GostR3410_2001_TestParamSet, + .param_len = sizeof(_EC_GOST_2001_Test.p), + .p = _EC_GOST_2001_Test.p, + .a = _EC_GOST_2001_Test.a, + .b = _EC_GOST_2001_Test.b, + .x = _EC_GOST_2001_Test.x, + .y = _EC_GOST_2001_Test.y, + .order = _EC_GOST_2001_Test.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2001 CryptoPro-A", + .nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_A.p), + .p = _EC_GOST_2001_CryptoPro_A.p, + .a = _EC_GOST_2001_CryptoPro_A.a, + .b = _EC_GOST_2001_CryptoPro_A.b, + .x = _EC_GOST_2001_CryptoPro_A.x, + .y = _EC_GOST_2001_CryptoPro_A.y, + .order = _EC_GOST_2001_CryptoPro_A.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2001 CryptoPro-B", + .nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_B.p), + .p = _EC_GOST_2001_CryptoPro_B.p, + .a = _EC_GOST_2001_CryptoPro_B.a, + .b = _EC_GOST_2001_CryptoPro_B.b, + .x = _EC_GOST_2001_CryptoPro_B.x, + .y = _EC_GOST_2001_CryptoPro_B.y, + .order = _EC_GOST_2001_CryptoPro_B.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2001 CryptoPro-C", + .nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_C.p), + .p = _EC_GOST_2001_CryptoPro_C.p, + .a = _EC_GOST_2001_CryptoPro_C.a, + .b = _EC_GOST_2001_CryptoPro_C.b, + .x = _EC_GOST_2001_CryptoPro_C.x, + .y = _EC_GOST_2001_CryptoPro_C.y, + .order = _EC_GOST_2001_CryptoPro_C.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2001 CryptoPro-XchA", + .nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_A.p), + .p = _EC_GOST_2001_CryptoPro_A.p, + .a = _EC_GOST_2001_CryptoPro_A.a, + .b = _EC_GOST_2001_CryptoPro_A.b, + .x = _EC_GOST_2001_CryptoPro_A.x, + .y = _EC_GOST_2001_CryptoPro_A.y, + .order = _EC_GOST_2001_CryptoPro_A.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2001 CryptoPro-XchB", + .nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_C.p), + .p = _EC_GOST_2001_CryptoPro_C.p, + .a = _EC_GOST_2001_CryptoPro_C.a, + .b = _EC_GOST_2001_CryptoPro_C.b, + .x = _EC_GOST_2001_CryptoPro_C.x, + .y = _EC_GOST_2001_CryptoPro_C.y, + .order = _EC_GOST_2001_CryptoPro_C.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 256 TC26-A", + .nid = NID_id_tc26_gost_3410_12_256_paramSetA, + .param_len = sizeof(_EC_GOST_2012_256_TC26_A.p), + .p = _EC_GOST_2012_256_TC26_A.p, + .a = _EC_GOST_2012_256_TC26_A.a, + .b = _EC_GOST_2012_256_TC26_A.b, + .x = _EC_GOST_2012_256_TC26_A.x, + .y = _EC_GOST_2012_256_TC26_A.y, + .order = _EC_GOST_2012_256_TC26_A.order, + .cofactor = 4, + }, + { + .comment = "GOST R 34.10-2012 256 TC26-B", + .nid = NID_id_tc26_gost_3410_12_256_paramSetB, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_A.p), + .p = _EC_GOST_2001_CryptoPro_A.p, + .a = _EC_GOST_2001_CryptoPro_A.a, + .b = _EC_GOST_2001_CryptoPro_A.b, + .x = _EC_GOST_2001_CryptoPro_A.x, + .y = _EC_GOST_2001_CryptoPro_A.y, + .order = _EC_GOST_2001_CryptoPro_A.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 256 TC26-C", + .nid = NID_id_tc26_gost_3410_12_256_paramSetC, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_B.p), + .p = _EC_GOST_2001_CryptoPro_B.p, + .a = _EC_GOST_2001_CryptoPro_B.a, + .b = _EC_GOST_2001_CryptoPro_B.b, + .x = _EC_GOST_2001_CryptoPro_B.x, + .y = _EC_GOST_2001_CryptoPro_B.y, + .order = _EC_GOST_2001_CryptoPro_B.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 256 TC26-D", + .nid = NID_id_tc26_gost_3410_12_256_paramSetD, + .param_len = sizeof(_EC_GOST_2001_CryptoPro_C.p), + .p = _EC_GOST_2001_CryptoPro_C.p, + .a = _EC_GOST_2001_CryptoPro_C.a, + .b = _EC_GOST_2001_CryptoPro_C.b, + .x = _EC_GOST_2001_CryptoPro_C.x, + .y = _EC_GOST_2001_CryptoPro_C.y, + .order = _EC_GOST_2001_CryptoPro_C.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 512 Test Curve", + .nid = NID_id_tc26_gost_3410_12_512_paramSetTest, + .param_len = sizeof(_EC_GOST_2012_512_Test.p), + .p = _EC_GOST_2012_512_Test.p, + .a = _EC_GOST_2012_512_Test.a, + .b = _EC_GOST_2012_512_Test.b, + .x = _EC_GOST_2012_512_Test.x, + .y = _EC_GOST_2012_512_Test.y, + .order = _EC_GOST_2012_512_Test.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 512 TC26-A", + .nid = NID_id_tc26_gost_3410_12_512_paramSetA, + .param_len = sizeof(_EC_GOST_2012_512_TC26_A.p), + .p = _EC_GOST_2012_512_TC26_A.p, + .a = _EC_GOST_2012_512_TC26_A.a, + .b = _EC_GOST_2012_512_TC26_A.b, + .x = _EC_GOST_2012_512_TC26_A.x, + .y = _EC_GOST_2012_512_TC26_A.y, + .order = _EC_GOST_2012_512_TC26_A.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 512 TC26-B", + .nid = NID_id_tc26_gost_3410_12_512_paramSetB, + .param_len = sizeof(_EC_GOST_2012_512_TC26_B.p), + .p = _EC_GOST_2012_512_TC26_B.p, + .a = _EC_GOST_2012_512_TC26_B.a, + .b = _EC_GOST_2012_512_TC26_B.b, + .x = _EC_GOST_2012_512_TC26_B.x, + .y = _EC_GOST_2012_512_TC26_B.y, + .order = _EC_GOST_2012_512_TC26_B.order, + .cofactor = 1, + }, + { + .comment = "GOST R 34.10-2012 512 TC26-C", + .nid = NID_id_tc26_gost_3410_12_512_paramSetC, + .param_len = sizeof(_EC_GOST_2012_512_TC26_C.p), + .p = _EC_GOST_2012_512_TC26_C.p, + .a = _EC_GOST_2012_512_TC26_C.a, + .b = _EC_GOST_2012_512_TC26_C.b, + .x = _EC_GOST_2012_512_TC26_C.x, + .y = _EC_GOST_2012_512_TC26_C.y, + .order = _EC_GOST_2012_512_TC26_C.order, + .cofactor = 4, + }, +#endif +}; + +#define CURVE_LIST_LENGTH (sizeof(curve_list) / sizeof(curve_list[0])) + +static EC_GROUP * +ec_group_new_from_data(const struct ec_list_element *curve) +{ + EC_GROUP *group = NULL, *ret = NULL; + EC_POINT *generator = NULL; + BN_CTX *ctx = NULL; + BIGNUM *p, *a, *b, *x, *y, *order, *cofactor; + + if ((ctx = BN_CTX_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + BN_CTX_start(ctx); + + if ((p = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((a = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((b = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((x = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((y = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((order = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((cofactor = BN_CTX_get(ctx)) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + if (BN_bin2bn(curve->p, curve->param_len, p) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (BN_bin2bn(curve->a, curve->param_len, a) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (BN_bin2bn(curve->b, curve->param_len, b) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + EC_GROUP_set_curve_name(group, curve->nid); + + if ((generator = EC_POINT_new(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (BN_bin2bn(curve->x, curve->param_len, x) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (BN_bin2bn(curve->y, curve->param_len, y) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (BN_bin2bn(curve->order, curve->param_len, order) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (!BN_set_word(cofactor, curve->cofactor)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!EC_GROUP_set_generator(group, generator, order, cofactor)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + if (curve->seed != NULL) { + if (!EC_GROUP_set_seed(group, curve->seed, curve->seed_len)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + } + + ret = group; + group = NULL; + + err: + EC_GROUP_free(group); + EC_POINT_free(generator); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ret; +} + +EC_GROUP * +EC_GROUP_new_by_curve_name(int nid) +{ + size_t i; + + if (nid <= 0) + return NULL; + + for (i = 0; i < CURVE_LIST_LENGTH; i++) { + if (curve_list[i].nid == nid) + return ec_group_new_from_data(&curve_list[i]); + } + + ECerror(EC_R_UNKNOWN_GROUP); + return NULL; +} +LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name); + +size_t +EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) +{ + size_t i, min; + + if (r == NULL || nitems == 0) + return CURVE_LIST_LENGTH; + + min = nitems < CURVE_LIST_LENGTH ? nitems : CURVE_LIST_LENGTH; + + for (i = 0; i < min; i++) { + r[i].nid = curve_list[i].nid; + r[i].comment = curve_list[i].comment; + } + + return CURVE_LIST_LENGTH; +} +LCRYPTO_ALIAS(EC_get_builtin_curves); + +static const struct { + const char *name; + int nid; +} nist_curves[] = { + { "B-163", NID_sect163r2 }, + { "B-233", NID_sect233r1 }, + { "B-283", NID_sect283r1 }, + { "B-409", NID_sect409r1 }, + { "B-571", NID_sect571r1 }, + { "K-163", NID_sect163k1 }, + { "K-233", NID_sect233k1 }, + { "K-283", NID_sect283k1 }, + { "K-409", NID_sect409k1 }, + { "K-571", NID_sect571k1 }, + { "P-192", NID_X9_62_prime192v1 }, + { "P-224", NID_secp224r1 }, + { "P-256", NID_X9_62_prime256v1 }, + { "P-384", NID_secp384r1 }, + { "P-521", NID_secp521r1 } +}; + +const char * +EC_curve_nid2nist(int nid) +{ + size_t i; + + for (i = 0; i < sizeof(nist_curves) / sizeof(nist_curves[0]); i++) { + if (nist_curves[i].nid == nid) + return nist_curves[i].name; + } + + return NULL; +} +LCRYPTO_ALIAS(EC_curve_nid2nist); + +int +EC_curve_nist2nid(const char *name) +{ + size_t i; + + for (i = 0; i < sizeof(nist_curves) / sizeof(nist_curves[0]); i++) { + if (strcmp(nist_curves[i].name, name) == 0) + return nist_curves[i].nid; + } + + return NID_undef; +} +LCRYPTO_ALIAS(EC_curve_nist2nid); diff --git a/Libraries/libressl/crypto/ec/ec_cvt.c b/Libraries/libressl/crypto/ec/ec_cvt.c new file mode 100644 index 000000000..5b196dd67 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_cvt.c @@ -0,0 +1,103 @@ +/* $OpenBSD: ec_cvt.c,v 1.12 2023/07/07 13:54:45 beck Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include + +#include +#include "ec_local.h" + +static EC_GROUP * +ec_group_new_curve(const EC_METHOD *method, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + EC_GROUP *group; + + if ((group = EC_GROUP_new(method)) == NULL) + goto err; + + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + goto err; + + return group; + + err: + EC_GROUP_free(group); + + return NULL; +} + +EC_GROUP * +EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + return ec_group_new_curve(EC_GFp_mont_method(), p, a, b, ctx); +} +LCRYPTO_ALIAS(EC_GROUP_new_curve_GFp); diff --git a/Libraries/libressl/crypto/ec/ec_err.c b/Libraries/libressl/crypto/ec/ec_err.c new file mode 100644 index 000000000..9f2253ddd --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_err.c @@ -0,0 +1,151 @@ +/* $OpenBSD: ec_err.c,v 1.18 2023/07/28 09:28:37 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason) + +static ERR_STRING_DATA EC_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA EC_str_reasons[] = +{ + {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"}, + {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"}, + {ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"}, + {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"}, + {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), "d2i ecpkparameters failure"}, + {ERR_REASON(EC_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, + {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"}, + {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"}, + {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, + {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), "group2pkparameters failure"}, + {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), "i2d ecpkparameters failure"}, + {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, + {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, + {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"}, + {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"}, + {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"}, + {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"}, + {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, + {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"}, + {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, + {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, + {ERR_REASON(EC_R_INVALID_KEY), "invalid key"}, + {ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"}, + {ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"}, + {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, + {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, + {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, + {ERR_REASON(EC_R_KDF_FAILED), "kdf failed"}, + {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, + {ERR_REASON(EC_R_KEY_TRUNCATION), "key would be truncated"}, + {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, + {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"}, + {ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, + {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"}, + {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), "not a supported NIST prime"}, + {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"}, + {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"}, + {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"}, + {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, + {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"}, + {ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, + {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"}, + {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"}, + {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"}, + {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, + {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, + {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, + {ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"}, + {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, + {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, + {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, + {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"}, + {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"}, + {0, NULL} +}; + +#endif + +void +ERR_load_EC_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { + ERR_load_strings(0, EC_str_functs); + ERR_load_strings(0, EC_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_EC_strings); diff --git a/Libraries/libressl/crypto/ec/ec_key.c b/Libraries/libressl/crypto/ec/ec_key.c new file mode 100644 index 000000000..d9ddd5d79 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_key.c @@ -0,0 +1,553 @@ +/* $OpenBSD: ec_key.c,v 1.37 2023/08/03 18:53:56 tb Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include + +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include + +#include "bn_local.h" +#include "ec_local.h" + +EC_KEY * +EC_KEY_new(void) +{ + return EC_KEY_new_method(NULL); +} +LCRYPTO_ALIAS(EC_KEY_new); + +EC_KEY * +EC_KEY_new_by_curve_name(int nid) +{ + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) + return NULL; + ret->group = EC_GROUP_new_by_curve_name(nid); + if (ret->group == NULL) { + EC_KEY_free(ret); + return NULL; + } + if (ret->meth->set_group != NULL && + ret->meth->set_group(ret, ret->group) == 0) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} +LCRYPTO_ALIAS(EC_KEY_new_by_curve_name); + +void +EC_KEY_free(EC_KEY *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); + if (i > 0) + return; + + if (r->meth != NULL && r->meth->finish != NULL) + r->meth->finish(r); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(r->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); + + EC_GROUP_free(r->group); + EC_POINT_free(r->pub_key); + BN_free(r->priv_key); + + freezero(r, sizeof(EC_KEY)); +} +LCRYPTO_ALIAS(EC_KEY_free); + +EC_KEY * +EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) +{ + if (dest == NULL || src == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (src->meth != dest->meth) { + if (dest->meth != NULL && dest->meth->finish != NULL) + dest->meth->finish(dest); +#ifndef OPENSSL_NO_ENGINE + if (ENGINE_finish(dest->engine) == 0) + return 0; + dest->engine = NULL; +#endif + } + /* copy the parameters */ + if (src->group) { + const EC_METHOD *meth = EC_GROUP_method_of(src->group); + /* clear the old group */ + EC_GROUP_free(dest->group); + dest->group = EC_GROUP_new(meth); + if (dest->group == NULL) + return NULL; + if (!EC_GROUP_copy(dest->group, src->group)) + return NULL; + } + /* copy the public key */ + if (src->pub_key && src->group) { + EC_POINT_free(dest->pub_key); + dest->pub_key = EC_POINT_new(src->group); + if (dest->pub_key == NULL) + return NULL; + if (!EC_POINT_copy(dest->pub_key, src->pub_key)) + return NULL; + } + /* copy the private key */ + if (src->priv_key) { + if (dest->priv_key == NULL) { + dest->priv_key = BN_new(); + if (dest->priv_key == NULL) + return NULL; + } + if (!bn_copy(dest->priv_key, src->priv_key)) + return NULL; + } + + /* copy the rest */ + dest->enc_flag = src->enc_flag; + dest->conv_form = src->conv_form; + dest->version = src->version; + dest->flags = src->flags; + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data, + &((EC_KEY *)src)->ex_data)) /* XXX const */ + return NULL; + + if (src->meth != dest->meth) { +#ifndef OPENSSL_NO_ENGINE + if (src->engine != NULL && ENGINE_init(src->engine) == 0) + return 0; + dest->engine = src->engine; +#endif + dest->meth = src->meth; + } + + if (src->meth != NULL && src->meth->copy != NULL && + src->meth->copy(dest, src) == 0) + return 0; + + return dest; +} +LCRYPTO_ALIAS(EC_KEY_copy); + +EC_KEY * +EC_KEY_dup(const EC_KEY *ec_key) +{ + EC_KEY *ret; + + if ((ret = EC_KEY_new_method(ec_key->engine)) == NULL) + return NULL; + if (EC_KEY_copy(ret, ec_key) == NULL) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} +LCRYPTO_ALIAS(EC_KEY_dup); + +int +EC_KEY_up_ref(EC_KEY *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); + return ((i > 1) ? 1 : 0); +} +LCRYPTO_ALIAS(EC_KEY_up_ref); + +int +EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&r->ex_data, idx, arg); +} +LCRYPTO_ALIAS(EC_KEY_set_ex_data); + +void * +EC_KEY_get_ex_data(const EC_KEY *r, int idx) +{ + return CRYPTO_get_ex_data(&r->ex_data, idx); +} +LCRYPTO_ALIAS(EC_KEY_get_ex_data); + +int +EC_KEY_generate_key(EC_KEY *eckey) +{ + if (eckey->meth->keygen != NULL) + return eckey->meth->keygen(eckey); + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; +} +LCRYPTO_ALIAS(EC_KEY_generate_key); + +int +ec_key_gen(EC_KEY *eckey) +{ + BIGNUM *priv_key = NULL; + EC_POINT *pub_key = NULL; + const BIGNUM *order; + int ret = 0; + + if (eckey == NULL || eckey->group == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if ((priv_key = BN_new()) == NULL) + goto err; + if ((pub_key = EC_POINT_new(eckey->group)) == NULL) + goto err; + + if ((order = EC_GROUP_get0_order(eckey->group)) == NULL) + goto err; + if (!bn_rand_interval(priv_key, 1, order)) + goto err; + if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) + goto err; + + BN_free(eckey->priv_key); + eckey->priv_key = priv_key; + priv_key = NULL; + + EC_POINT_free(eckey->pub_key); + eckey->pub_key = pub_key; + pub_key = NULL; + + ret = 1; + + err: + EC_POINT_free(pub_key); + BN_free(priv_key); + + return ret; +} + +int +EC_KEY_check_key(const EC_KEY *eckey) +{ + BN_CTX *ctx = NULL; + EC_POINT *point = NULL; + const BIGNUM *order; + int ret = 0; + + if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) { + ECerror(EC_R_POINT_AT_INFINITY); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if ((point = EC_POINT_new(eckey->group)) == NULL) + goto err; + + /* Ensure public key is on the elliptic curve. */ + if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { + ECerror(EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + /* Ensure public key multiplied by the order is the point at infinity. */ + if ((order = EC_GROUP_get0_order(eckey->group)) == NULL) { + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_is_at_infinity(eckey->group, point) <= 0) { + ECerror(EC_R_WRONG_ORDER); + goto err; + } + + /* + * If the private key is present, ensure that the private key multiplied + * by the generator matches the public key. + */ + if (eckey->priv_key != NULL) { + if (BN_cmp(eckey->priv_key, order) >= 0) { + ECerror(EC_R_WRONG_ORDER); + goto err; + } + if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, + NULL, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, + ctx) != 0) { + ECerror(EC_R_INVALID_PRIVATE_KEY); + goto err; + } + } + + ret = 1; + + err: + BN_CTX_free(ctx); + EC_POINT_free(point); + + return ret; +} +LCRYPTO_ALIAS(EC_KEY_check_key); + +int +EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) +{ + BN_CTX *ctx = NULL; + EC_POINT *point = NULL; + BIGNUM *tx, *ty; + int ret = 0; + + if (key == NULL || key->group == NULL || x == NULL || y == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((tx = BN_CTX_get(ctx)) == NULL) + goto err; + if ((ty = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((point = EC_POINT_new(key->group)) == NULL) + goto err; + + if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx)) + goto err; + + /* + * Check if retrieved coordinates match originals: if not values are + * out of range. + */ + if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { + ECerror(EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + if (!EC_KEY_set_public_key(key, point)) + goto err; + if (EC_KEY_check_key(key) == 0) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); + + return ret; +} +LCRYPTO_ALIAS(EC_KEY_set_public_key_affine_coordinates); + +const EC_GROUP * +EC_KEY_get0_group(const EC_KEY *key) +{ + return key->group; +} +LCRYPTO_ALIAS(EC_KEY_get0_group); + +int +EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) +{ + if (key->meth->set_group != NULL && + key->meth->set_group(key, group) == 0) + return 0; + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return (key->group == NULL) ? 0 : 1; +} +LCRYPTO_ALIAS(EC_KEY_set_group); + +const BIGNUM * +EC_KEY_get0_private_key(const EC_KEY *key) +{ + return key->priv_key; +} +LCRYPTO_ALIAS(EC_KEY_get0_private_key); + +int +EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) +{ + if (key->meth->set_private != NULL && + key->meth->set_private(key, priv_key) == 0) + return 0; + + BN_free(key->priv_key); + if ((key->priv_key = BN_dup(priv_key)) == NULL) + return 0; + + return 1; +} +LCRYPTO_ALIAS(EC_KEY_set_private_key); + +const EC_POINT * +EC_KEY_get0_public_key(const EC_KEY *key) +{ + return key->pub_key; +} +LCRYPTO_ALIAS(EC_KEY_get0_public_key); + +int +EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) +{ + if (key->meth->set_public != NULL && + key->meth->set_public(key, pub_key) == 0) + return 0; + + EC_POINT_free(key->pub_key); + if ((key->pub_key = EC_POINT_dup(pub_key, key->group)) == NULL) + return 0; + + return 1; +} +LCRYPTO_ALIAS(EC_KEY_set_public_key); + +unsigned int +EC_KEY_get_enc_flags(const EC_KEY *key) +{ + return key->enc_flag; +} +LCRYPTO_ALIAS(EC_KEY_get_enc_flags); + +void +EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) +{ + key->enc_flag = flags; +} +LCRYPTO_ALIAS(EC_KEY_set_enc_flags); + +point_conversion_form_t +EC_KEY_get_conv_form(const EC_KEY *key) +{ + return key->conv_form; +} +LCRYPTO_ALIAS(EC_KEY_get_conv_form); + +void +EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) +{ + key->conv_form = cform; + if (key->group != NULL) + EC_GROUP_set_point_conversion_form(key->group, cform); +} +LCRYPTO_ALIAS(EC_KEY_set_conv_form); + +void +EC_KEY_set_asn1_flag(EC_KEY *key, int flag) +{ + if (key->group != NULL) + EC_GROUP_set_asn1_flag(key->group, flag); +} +LCRYPTO_ALIAS(EC_KEY_set_asn1_flag); + +int +EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) +{ + if (key->group == NULL) + return 0; + return EC_GROUP_precompute_mult(key->group, ctx); +} +LCRYPTO_ALIAS(EC_KEY_precompute_mult); + +int +EC_KEY_get_flags(const EC_KEY *key) +{ + return key->flags; +} +LCRYPTO_ALIAS(EC_KEY_get_flags); + +void +EC_KEY_set_flags(EC_KEY *key, int flags) +{ + key->flags |= flags; +} +LCRYPTO_ALIAS(EC_KEY_set_flags); + +void +EC_KEY_clear_flags(EC_KEY *key, int flags) +{ + key->flags &= ~flags; +} +LCRYPTO_ALIAS(EC_KEY_clear_flags); diff --git a/Libraries/libressl/crypto/ec/ec_kmeth.c b/Libraries/libressl/crypto/ec/ec_kmeth.c new file mode 100644 index 000000000..38aca0028 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_kmeth.c @@ -0,0 +1,353 @@ +/* $OpenBSD: ec_kmeth.c,v 1.12 2023/07/28 09:28:37 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include + +#include "bn_local.h" +#include "ec_local.h" +#include "ecdsa_local.h" + +static const EC_KEY_METHOD openssl_ec_key_method = { + .name = "OpenSSL EC_KEY method", + .flags = 0, + + .init = NULL, + .finish = NULL, + .copy = NULL, + + .set_group = NULL, + .set_private = NULL, + .set_public = NULL, + + .keygen = ec_key_gen, + .compute_key = ecdh_compute_key, + + .sign = ecdsa_sign, + .sign_setup = ecdsa_sign_setup, + .sign_sig = ecdsa_sign_sig, + + .verify = ecdsa_verify, + .verify_sig = ecdsa_verify_sig, +}; + +const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; + +const EC_KEY_METHOD * +EC_KEY_OpenSSL(void) +{ + return &openssl_ec_key_method; +} +LCRYPTO_ALIAS(EC_KEY_OpenSSL); + +const EC_KEY_METHOD * +EC_KEY_get_default_method(void) +{ + return default_ec_key_meth; +} +LCRYPTO_ALIAS(EC_KEY_get_default_method); + +void +EC_KEY_set_default_method(const EC_KEY_METHOD *meth) +{ + if (meth == NULL) + default_ec_key_meth = &openssl_ec_key_method; + else + default_ec_key_meth = meth; +} +LCRYPTO_ALIAS(EC_KEY_set_default_method); + +const EC_KEY_METHOD * +EC_KEY_get_method(const EC_KEY *key) +{ + return key->meth; +} +LCRYPTO_ALIAS(EC_KEY_get_method); + +int +EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) +{ + void (*finish)(EC_KEY *key) = key->meth->finish; + + if (finish != NULL) + finish(key); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(key->engine); + key->engine = NULL; +#endif + + key->meth = meth; + if (meth->init != NULL) + return meth->init(key); + return 1; +} +LCRYPTO_ALIAS(EC_KEY_set_method); + +EC_KEY * +EC_KEY_new_method(ENGINE *engine) +{ + EC_KEY *ret; + + if ((ret = calloc(1, sizeof(EC_KEY))) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->meth = EC_KEY_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine != NULL) { + if (!ENGINE_init(engine)) { + ECerror(ERR_R_ENGINE_LIB); + goto err; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_EC(); + if (ret->engine) { + ret->meth = ENGINE_get_EC(ret->engine); + if (ret->meth == NULL) { + ECerror(ERR_R_ENGINE_LIB); + goto err; + } + } +#endif + ret->version = 1; + ret->flags = 0; + ret->group = NULL; + ret->pub_key = NULL; + ret->priv_key = NULL; + ret->enc_flag = 0; + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; + ret->references = 1; + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) + goto err; + if (ret->meth->init != NULL && ret->meth->init(ret) == 0) + goto err; + + return ret; + + err: + EC_KEY_free(ret); + return NULL; +} +LCRYPTO_ALIAS(EC_KEY_new_method); + +EC_KEY_METHOD * +EC_KEY_METHOD_new(const EC_KEY_METHOD *meth) +{ + EC_KEY_METHOD *ret; + + if ((ret = calloc(1, sizeof(*meth))) == NULL) + return NULL; + if (meth != NULL) + *ret = *meth; + ret->flags |= EC_KEY_METHOD_DYNAMIC; + return ret; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_new); + +void +EC_KEY_METHOD_free(EC_KEY_METHOD *meth) +{ + if (meth == NULL) + return; + if (meth->flags & EC_KEY_METHOD_DYNAMIC) + free(meth); +} +LCRYPTO_ALIAS(EC_KEY_METHOD_free); + +void +EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, const EC_POINT *pub_key)) +{ + meth->init = init; + meth->finish = finish; + meth->copy = copy; + meth->set_group = set_group; + meth->set_private = set_private; + meth->set_public = set_public; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_set_init); + +void +EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, int (*keygen)(EC_KEY *key)) +{ + meth->keygen = keygen; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_set_keygen); + +void +EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, + const EC_KEY *ecdh)) +{ + meth->compute_key = ckey; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_set_compute_key); + +void +EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, + int dgst_len, const BIGNUM *in_kinv, + const BIGNUM *in_r, EC_KEY *eckey)) +{ + meth->sign = sign; + meth->sign_setup = sign_setup; + meth->sign_sig = sign_sig; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_set_sign); + +void +EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey)) +{ + meth->verify = verify; + meth->verify_sig = verify_sig; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_set_verify); + + +void +EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, + int (**pinit)(EC_KEY *key), + void (**pfinish)(EC_KEY *key), + int (**pcopy)(EC_KEY *dest, const EC_KEY *src), + int (**pset_group)(EC_KEY *key, const EC_GROUP *grp), + int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key), + int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key)) +{ + if (pinit != NULL) + *pinit = meth->init; + if (pfinish != NULL) + *pfinish = meth->finish; + if (pcopy != NULL) + *pcopy = meth->copy; + if (pset_group != NULL) + *pset_group = meth->set_group; + if (pset_private != NULL) + *pset_private = meth->set_private; + if (pset_public != NULL) + *pset_public = meth->set_public; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_get_init); + +void +EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *key)) +{ + if (pkeygen != NULL) + *pkeygen = meth->keygen; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_get_keygen); + +void +EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, + int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, + const EC_KEY *ecdh)) +{ + if (pck != NULL) + *pck = meth->compute_key; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_get_compute_key); + +void +EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, + int (**psign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), + int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, + int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey)) +{ + if (psign != NULL) + *psign = meth->sign; + if (psign_setup != NULL) + *psign_setup = meth->sign_setup; + if (psign_sig != NULL) + *psign_sig = meth->sign_sig; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_get_sign); + +void +EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey)) +{ + if (pverify != NULL) + *pverify = meth->verify; + if (pverify_sig != NULL) + *pverify_sig = meth->verify_sig; +} +LCRYPTO_ALIAS(EC_KEY_METHOD_get_verify); diff --git a/Libraries/libressl/crypto/ec/ec_lib.c b/Libraries/libressl/crypto/ec/ec_lib.c new file mode 100644 index 000000000..00a4a703f --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_lib.c @@ -0,0 +1,1331 @@ +/* $OpenBSD: ec_lib.c,v 1.65 2023/07/25 06:57:26 tb Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include + +#include +#include + +#include "bn_local.h" +#include "ec_local.h" + +/* functions for EC_GROUP objects */ + +EC_GROUP * +EC_GROUP_new(const EC_METHOD *meth) +{ + EC_GROUP *ret; + + if (meth == NULL) { + ECerror(EC_R_SLOT_FULL); + return NULL; + } + if (meth->group_init == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + ret = malloc(sizeof *ret); + if (ret == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->meth = meth; + + ret->generator = NULL; + BN_init(&ret->order); + BN_init(&ret->cofactor); + + ret->curve_name = 0; + ret->asn1_flag = OPENSSL_EC_NAMED_CURVE; + ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; + + ret->seed = NULL; + ret->seed_len = 0; + + if (!meth->group_init(ret)) { + free(ret); + return NULL; + } + return ret; +} +LCRYPTO_ALIAS(EC_GROUP_new); + + +void +EC_GROUP_free(EC_GROUP *group) +{ + if (group == NULL) + return; + + if (group->meth->group_finish != NULL) + group->meth->group_finish(group); + + EC_POINT_free(group->generator); + BN_free(&group->order); + BN_free(&group->cofactor); + + freezero(group->seed, group->seed_len); + freezero(group, sizeof *group); +} +LCRYPTO_ALIAS(EC_GROUP_free); + +void +EC_GROUP_clear_free(EC_GROUP *group) +{ + EC_GROUP_free(group); +} + +int +EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + if (dest->meth->group_copy == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (dest->meth != src->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) + return 1; + + if (src->generator != NULL) { + if (dest->generator == NULL) { + dest->generator = EC_POINT_new(dest); + if (dest->generator == NULL) + return 0; + } + if (!EC_POINT_copy(dest->generator, src->generator)) + return 0; + } else { + /* src->generator == NULL */ + EC_POINT_free(dest->generator); + dest->generator = NULL; + } + + if (!bn_copy(&dest->order, &src->order)) + return 0; + if (!bn_copy(&dest->cofactor, &src->cofactor)) + return 0; + + dest->curve_name = src->curve_name; + dest->asn1_flag = src->asn1_flag; + dest->asn1_form = src->asn1_form; + + if (src->seed) { + free(dest->seed); + dest->seed = malloc(src->seed_len); + if (dest->seed == NULL) + return 0; + memcpy(dest->seed, src->seed, src->seed_len); + dest->seed_len = src->seed_len; + } else { + free(dest->seed); + dest->seed = NULL; + dest->seed_len = 0; + } + + + return dest->meth->group_copy(dest, src); +} +LCRYPTO_ALIAS(EC_GROUP_copy); + + +EC_GROUP * +EC_GROUP_dup(const EC_GROUP *a) +{ + EC_GROUP *t = NULL; + + if ((a != NULL) && ((t = EC_GROUP_new(a->meth)) != NULL) && + (!EC_GROUP_copy(t, a))) { + EC_GROUP_free(t); + t = NULL; + } + return t; +} +LCRYPTO_ALIAS(EC_GROUP_dup); + + +const EC_METHOD * +EC_GROUP_method_of(const EC_GROUP *group) +{ + return group->meth; +} +LCRYPTO_ALIAS(EC_GROUP_method_of); + + +int +EC_METHOD_get_field_type(const EC_METHOD *meth) +{ + return meth->field_type; +} +LCRYPTO_ALIAS(EC_METHOD_get_field_type); + +/* + * If there is a user-provided cofactor, sanity check and use it. Otherwise + * try computing the cofactor from generator order n and field cardinality q. + * This works for all curves of cryptographic interest. + * + * Hasse's theorem: | h * n - (q + 1) | <= 2 * sqrt(q) + * + * So: h_min = (q + 1 - 2*sqrt(q)) / n and h_max = (q + 1 + 2*sqrt(q)) / n and + * therefore h_max - h_min = 4*sqrt(q) / n. So if n > 4*sqrt(q) holds, there is + * only one possible value for h: + * + * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil + * + * Otherwise, zero cofactor and return success. + */ +static int +ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor) +{ + BN_CTX *ctx = NULL; + BIGNUM *cofactor; + int ret = 0; + + BN_zero(&group->cofactor); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + if ((cofactor = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Unfortunately, the cofactor is an optional field in many standards. + * Internally, the library uses a 0 cofactor as a marker for "unknown + * cofactor". So accept in_cofactor == NULL or in_cofactor >= 0. + */ + if (in_cofactor != NULL && !BN_is_zero(in_cofactor)) { + if (BN_is_negative(in_cofactor)) { + ECerror(EC_R_UNKNOWN_COFACTOR); + goto err; + } + if (!bn_copy(cofactor, in_cofactor)) + goto err; + goto done; + } + + /* + * If the cofactor is too large, we cannot guess it and default to zero. + * The RHS of below is a strict overestimate of log(4 * sqrt(q)). + */ + if (BN_num_bits(&group->order) <= + (BN_num_bits(&group->field) + 1) / 2 + 3) + goto done; + + /* + * Compute + * h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2) / n \rfloor. + */ + + /* h = n/2 */ + if (!BN_rshift1(cofactor, &group->order)) + goto err; + /* h = 1 + n/2 */ + if (!BN_add_word(cofactor, 1)) + goto err; + /* h = q + 1 + n/2 */ + if (!BN_add(cofactor, cofactor, &group->field)) + goto err; + /* h = (q + 1 + n/2) / n */ + if (!BN_div_ct(cofactor, NULL, cofactor, &group->order, ctx)) + goto err; + + done: + /* Use Hasse's theorem to bound the cofactor. */ + if (BN_num_bits(cofactor) > BN_num_bits(&group->field) + 1) { + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + + if (!bn_copy(&group->cofactor, cofactor)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ret; +} + +int +EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor) +{ + if (generator == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* Require group->field >= 1. */ + if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) { + ECerror(EC_R_INVALID_FIELD); + return 0; + } + + /* + * Require order > 1 and enforce an upper bound of at most one bit more + * than the field cardinality due to Hasse's theorem. + */ + if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 || + BN_num_bits(order) > BN_num_bits(&group->field) + 1) { + ECerror(EC_R_INVALID_GROUP_ORDER); + return 0; + } + + if (group->generator == NULL) { + group->generator = EC_POINT_new(group); + if (group->generator == NULL) + return 0; + } + if (!EC_POINT_copy(group->generator, generator)) + return 0; + + if (!bn_copy(&group->order, order)) + return 0; + + if (!ec_set_cofactor(group, cofactor)) + return 0; + + return 1; +} +LCRYPTO_ALIAS(EC_GROUP_set_generator); + + +const EC_POINT * +EC_GROUP_get0_generator(const EC_GROUP *group) +{ + return group->generator; +} +LCRYPTO_ALIAS(EC_GROUP_get0_generator); + +int +EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) +{ + if (!bn_copy(order, &group->order)) + return 0; + + return !BN_is_zero(order); +} +LCRYPTO_ALIAS(EC_GROUP_get_order); + +const BIGNUM * +EC_GROUP_get0_order(const EC_GROUP *group) +{ + return &group->order; +} + +int +EC_GROUP_order_bits(const EC_GROUP *group) +{ + return group->meth->group_order_bits(group); +} +LCRYPTO_ALIAS(EC_GROUP_order_bits); + +int +EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) +{ + if (!bn_copy(cofactor, &group->cofactor)) + return 0; + + return !BN_is_zero(&group->cofactor); +} +LCRYPTO_ALIAS(EC_GROUP_get_cofactor); + + +void +EC_GROUP_set_curve_name(EC_GROUP *group, int nid) +{ + group->curve_name = nid; +} +LCRYPTO_ALIAS(EC_GROUP_set_curve_name); + + +int +EC_GROUP_get_curve_name(const EC_GROUP *group) +{ + return group->curve_name; +} +LCRYPTO_ALIAS(EC_GROUP_get_curve_name); + + +void +EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) +{ + group->asn1_flag = flag; +} +LCRYPTO_ALIAS(EC_GROUP_set_asn1_flag); + + +int +EC_GROUP_get_asn1_flag(const EC_GROUP *group) +{ + return group->asn1_flag; +} +LCRYPTO_ALIAS(EC_GROUP_get_asn1_flag); + + +void +EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form) +{ + group->asn1_form = form; +} +LCRYPTO_ALIAS(EC_GROUP_set_point_conversion_form); + + +point_conversion_form_t +EC_GROUP_get_point_conversion_form(const EC_GROUP *group) +{ + return group->asn1_form; +} +LCRYPTO_ALIAS(EC_GROUP_get_point_conversion_form); + + +size_t +EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) +{ + if (group->seed) { + free(group->seed); + group->seed = NULL; + group->seed_len = 0; + } + if (!len || !p) + return 1; + + if ((group->seed = malloc(len)) == NULL) + return 0; + memcpy(group->seed, p, len); + group->seed_len = len; + + return len; +} +LCRYPTO_ALIAS(EC_GROUP_set_seed); + + +unsigned char * +EC_GROUP_get0_seed(const EC_GROUP *group) +{ + return group->seed; +} +LCRYPTO_ALIAS(EC_GROUP_get0_seed); + + +size_t +EC_GROUP_get_seed_len(const EC_GROUP *group) +{ + return group->seed_len; +} +LCRYPTO_ALIAS(EC_GROUP_get_seed_len); + +int +EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->group_set_curve == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + ret = group->meth->group_set_curve(group, p, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_GROUP_set_curve); + +int +EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->group_get_curve == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + ret = group->meth->group_get_curve(group, p, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_GROUP_get_curve); + +int +EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + return EC_GROUP_set_curve(group, p, a, b, ctx); +} + +int +EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *ctx) +{ + return EC_GROUP_get_curve(group, p, a, b, ctx); +} + +int +EC_GROUP_get_degree(const EC_GROUP *group) +{ + if (group->meth->group_get_degree == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_degree(group); +} +LCRYPTO_ALIAS(EC_GROUP_get_degree); + + +int +EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->group_check_discriminant == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + ret = group->meth->group_check_discriminant(group, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_GROUP_check_discriminant); + + +int +EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) +{ + int r = 0; + BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; + BN_CTX *ctx_new = NULL; + + /* compare the field types */ + if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != + EC_METHOD_get_field_type(EC_GROUP_method_of(b))) + return 1; + /* compare the curve name (if present in both) */ + if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && + EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) + return 1; + + if (!ctx) + ctx_new = ctx = BN_CTX_new(); + if (!ctx) + return -1; + + BN_CTX_start(ctx); + if ((a1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((a2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((a3 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b3 = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * XXX This approach assumes that the external representation of + * curves over the same field type is the same. + */ + if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || + !b->meth->group_get_curve(b, b1, b2, b3, ctx)) + r = 1; + + if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) + r = 1; + + /* XXX EC_POINT_cmp() assumes that the methods are equal */ + if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), + EC_GROUP_get0_generator(b), ctx)) + r = 1; + + if (!r) { + /* compare the order and cofactor */ + if (!EC_GROUP_get_order(a, a1, ctx) || + !EC_GROUP_get_order(b, b1, ctx) || + !EC_GROUP_get_cofactor(a, a2, ctx) || + !EC_GROUP_get_cofactor(b, b2, ctx)) + goto err; + if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) + r = 1; + } + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + + return r; + + err: + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + return -1; +} +LCRYPTO_ALIAS(EC_GROUP_cmp); + +/* + * Coordinate blinding for EC_POINT. + * + * The underlying EC_METHOD can optionally implement this function: + * underlying implementations should return 0 on errors, or 1 on success. + * + * This wrapper returns 1 in case the underlying EC_METHOD does not support + * coordinate blinding. + */ +int +ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) +{ + if (group->meth->blind_coordinates == NULL) + return 1; + + return group->meth->blind_coordinates(group, p, ctx); +} + +EC_POINT * +EC_POINT_new(const EC_GROUP *group) +{ + EC_POINT *ret; + + if (group == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (group->meth->point_init == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + ret = malloc(sizeof *ret); + if (ret == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->meth = group->meth; + + if (!ret->meth->point_init(ret)) { + free(ret); + return NULL; + } + return ret; +} +LCRYPTO_ALIAS(EC_POINT_new); + +void +EC_POINT_free(EC_POINT *point) +{ + if (point == NULL) + return; + + if (point->meth->point_finish != NULL) + point->meth->point_finish(point); + + freezero(point, sizeof *point); +} +LCRYPTO_ALIAS(EC_POINT_free); + +void +EC_POINT_clear_free(EC_POINT *point) +{ + EC_POINT_free(point); +} + +int +EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (dest->meth->point_copy == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (dest->meth != src->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) + return 1; + return dest->meth->point_copy(dest, src); +} +LCRYPTO_ALIAS(EC_POINT_copy); + +EC_POINT * +EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) +{ + EC_POINT *t; + int r; + + if (a == NULL) + return NULL; + + t = EC_POINT_new(group); + if (t == NULL) + return (NULL); + r = EC_POINT_copy(t, a); + if (!r) { + EC_POINT_free(t); + return NULL; + } else + return t; +} +LCRYPTO_ALIAS(EC_POINT_dup); + +const EC_METHOD * +EC_POINT_method_of(const EC_POINT *point) +{ + return point->meth; +} +LCRYPTO_ALIAS(EC_POINT_method_of); + +int +EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) +{ + if (group->meth->point_set_to_infinity == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_to_infinity(group, point); +} +LCRYPTO_ALIAS(EC_POINT_set_to_infinity); + +int +EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_set_Jprojective_coordinates == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + if (!group->meth->point_set_Jprojective_coordinates(group, point, + x, y, z, ctx)) + goto err; + + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { + ECerror(EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + ret = 1; + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} + +int +EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_get_Jprojective_coordinates == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->point_get_Jprojective_coordinates(group, point, + x, y, z, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} + +int +EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) +{ + return EC_POINT_set_Jprojective_coordinates(group, point, x, y, z, ctx); +} + +int +EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) +{ + return EC_POINT_get_Jprojective_coordinates(group, point, x, y, z, ctx); +} + +int +EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_set_affine_coordinates == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) + goto err; + + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { + ECerror(EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + ret = 1; + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates); + +int +EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) +{ + return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); +} + +int +EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_get_affine_coordinates == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates); + +int +EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx) +{ + return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); +} + +int +EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->add == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != r->meth || group->meth != a->meth || + group->meth != b->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->add(group, r, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_add); + +int +EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->dbl == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != r->meth || r->meth != a->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->dbl(group, r, a, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_dbl); + +int +EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->invert == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != a->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->invert(group, a, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_invert); + +int +EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +{ + if (group->meth->is_at_infinity == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->is_at_infinity(group, point); +} +LCRYPTO_ALIAS(EC_POINT_is_at_infinity); + +int +EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = -1; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->is_on_curve == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->is_on_curve(group, point, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_is_on_curve); + +int +EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = -1; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_cmp == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != a->meth || a->meth != b->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->point_cmp(group, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_cmp); + +int +EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->make_affine == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->make_affine(group, point, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_make_affine); + +int +EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + size_t i; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->points_make_affine == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + } + ret = group->meth->points_make_affine(group, num, points, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINTs_make_affine); + +int +EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + /* Only num == 0 and num == 1 is supported. */ + if (group->meth->mul_generator_ct == NULL || + group->meth->mul_single_ct == NULL || + group->meth->mul_double_nonct == NULL || + num > 1) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + + if (num == 1 && points != NULL && scalars != NULL) { + /* Either bP or aG + bP, this is sane. */ + ret = EC_POINT_mul(group, r, scalar, points[0], scalars[0], ctx); + } else if (scalar != NULL && points == NULL && scalars == NULL) { + /* aG, this is sane */ + ret = EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); + } else { + /* anything else is an error */ + ECerror(ERR_R_EC_LIB); + goto err; + } + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINTs_mul); + +int +EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->mul_generator_ct == NULL || + group->meth->mul_single_ct == NULL || + group->meth->mul_double_nonct == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + + if (g_scalar != NULL && point == NULL && p_scalar == NULL) { + /* + * In this case we want to compute g_scalar * GeneratorPoint: + * this codepath is reached most prominently by (ephemeral) key + * generation of EC cryptosystems (i.e. ECDSA keygen and sign + * setup, ECDH keygen/first half), where the scalar is always + * secret. This is why we ignore if BN_FLG_CONSTTIME is actually + * set and we always call the constant time version. + */ + ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx); + } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) { + /* + * In this case we want to compute p_scalar * GenericPoint: + * this codepath is reached most prominently by the second half + * of ECDH, where the secret scalar is multiplied by the peer's + * public point. To protect the secret scalar, we ignore if + * BN_FLG_CONSTTIME is actually set and we always call the + * constant time version. + */ + ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx); + } else if (g_scalar != NULL && point != NULL && p_scalar != NULL) { + /* + * In this case we want to compute + * g_scalar * GeneratorPoint + p_scalar * GenericPoint: + * this codepath is reached most prominently by ECDSA signature + * verification. So we call the non-ct version. + */ + ret = group->meth->mul_double_nonct(group, r, g_scalar, + p_scalar, point, ctx); + } else { + /* Anything else is an error. */ + ECerror(ERR_R_EC_LIB); + goto err; + } + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_mul); + +int +EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in) +{ + return 1; +} +LCRYPTO_ALIAS(EC_GROUP_precompute_mult); + +int +EC_GROUP_have_precompute_mult(const EC_GROUP *group) +{ + return 0; +} +LCRYPTO_ALIAS(EC_GROUP_have_precompute_mult); + +int +ec_group_simple_order_bits(const EC_GROUP *group) +{ + /* XXX change group->order to a pointer? */ +#if 0 + if (group->order == NULL) + return 0; +#endif + return BN_num_bits(&group->order); +} + +EC_KEY * +ECParameters_dup(EC_KEY *key) +{ + const unsigned char *p; + unsigned char *der = NULL; + EC_KEY *dup = NULL; + int len; + + if (key == NULL) + return NULL; + + if ((len = i2d_ECParameters(key, &der)) <= 0) + return NULL; + + p = der; + dup = d2i_ECParameters(NULL, &p, len); + freezero(der, len); + + return dup; +} +LCRYPTO_ALIAS(ECParameters_dup); diff --git a/Libraries/libressl/crypto/ec/ec_local.h b/Libraries/libressl/crypto/ec/ec_local.h new file mode 100644 index 000000000..3252eeb1c --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_local.h @@ -0,0 +1,365 @@ +/* $OpenBSD: ec_local.h,v 1.26 2023/07/28 15:50:33 tb Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include + +#include +#include +#include + +#include "bn_local.h" + +__BEGIN_HIDDEN_DECLS + +#if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +#endif + +struct ec_method_st { + int field_type; + + int (*group_init)(EC_GROUP *); + void (*group_finish)(EC_GROUP *); + int (*group_copy)(EC_GROUP *, const EC_GROUP *); + + int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); + + int (*group_get_degree)(const EC_GROUP *); + int (*group_order_bits)(const EC_GROUP *); + int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *); + + int (*point_init)(EC_POINT *); + void (*point_finish)(EC_POINT *); + int (*point_copy)(EC_POINT *, const EC_POINT *); + + int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *); + int (*point_set_Jprojective_coordinates)(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); + int (*point_get_Jprojective_coordinates)(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); + int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, BN_CTX *); + int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BN_CTX *); + int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, BN_CTX *); + + size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, unsigned char *buf, size_t len, + BN_CTX *); + int (*oct2point)(const EC_GROUP *, EC_POINT *, const unsigned char *buf, + size_t len, BN_CTX *); + + int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); + int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); + int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *); + + int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *); + int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *); + int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); + + int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *); + int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], + BN_CTX *); + + int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r, + const BIGNUM *scalar, BN_CTX *); + int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, const EC_POINT *point, BN_CTX *); + int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *g_scalar, const BIGNUM *p_scalar, + const EC_POINT *point, BN_CTX *); + + /* + * Internal methods. + */ + + /* + * These can be used by 'add' and 'dbl' so that the same implementations + * of point operations can be used with different optimized versions of + * expensive field operations. + */ + int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + + /* Encode to and decode from other forms (e.g. Montgomery). */ + int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + + int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *); + int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx); +} /* EC_METHOD */; + +struct ec_group_st { + /* + * Methods and members exposed via the public API. + */ + + const EC_METHOD *meth; + + EC_POINT *generator; /* Optional */ + BIGNUM order; + BIGNUM cofactor; + + int curve_name; /* Optional NID for named curve. */ + + /* ASN.1 encoding controls. */ + int asn1_flag; + point_conversion_form_t asn1_form; + + /* Optional seed for parameters (appears in ASN.1). */ + unsigned char *seed; + size_t seed_len; + + /* + * Internal methods and members. Handled by the method functions, even + * if they appear to be generic. + */ + + /* + * Field specification. For GF(p) this is the modulus; for GF(2^m), + * this is the irreducible polynomial defining the field. + */ + BIGNUM field; + + /* + * Curve coefficients. In characteristic > 3, the curve is defined by a + * Weierstrass equation of the form y^2 = x^3 + a*x + b. + */ + BIGNUM a, b; + + /* Enables optimized point arithmetics for special case. */ + int a_is_minus3; + + /* Montgomery context and values used by EC_GFp_mont_method. */ + BN_MONT_CTX *mont_ctx; + BIGNUM *mont_one; + + int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *); +} /* EC_GROUP */; + +struct ec_key_st { + const EC_KEY_METHOD *meth; + ENGINE *engine; + + int version; + + EC_GROUP *group; + + EC_POINT *pub_key; + BIGNUM *priv_key; + + unsigned int enc_flag; + point_conversion_form_t conv_form; + + int references; + int flags; + + CRYPTO_EX_DATA ex_data; +} /* EC_KEY */; + +struct ec_point_st { + const EC_METHOD *meth; + + /* + * All members except 'meth' are handled by the method functions, + * even if they appear generic. + */ + + /* + * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3) + * if Z != 0 + */ + BIGNUM X; + BIGNUM Y; + BIGNUM Z; + int Z_is_one; /* enable optimized point arithmetics for special case */ +} /* EC_POINT */; + +/* method functions in ec_mult.c + * (ec_lib.c uses these as defaults if group->method->mul is 0) */ +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); + +/* method functions in ecp_smpl.c */ +int ec_GFp_simple_group_init(EC_GROUP *); +void ec_GFp_simple_group_finish(EC_GROUP *); +int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_degree(const EC_GROUP *); +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ec_GFp_simple_point_init(EC_POINT *); +void ec_GFp_simple_point_finish(EC_POINT *); +int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); +int ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, BN_CTX *); +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BN_CTX *); +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, BN_CTX *); +size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); +int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); +int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); +int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); +int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); +int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); +int ec_GFp_simple_mul_generator_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *); +int ec_GFp_simple_mul_single_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, + const EC_POINT *point, BN_CTX *); +int ec_GFp_simple_mul_double_nonct(const EC_GROUP *, EC_POINT *r, const BIGNUM *g_scalar, + const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *); + +int ec_group_simple_order_bits(const EC_GROUP *group); +int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); + +/* EC_METHOD definitions */ + +struct ec_key_method_st { + const char *name; + int32_t flags; + int (*init)(EC_KEY *key); + void (*finish)(EC_KEY *key); + int (*copy)(EC_KEY *dest, const EC_KEY *src); + int (*set_group)(EC_KEY *key, const EC_GROUP *grp); + int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); + int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); + int (*keygen)(EC_KEY *key); + int (*compute_key)(unsigned char **out, size_t *out_len, + const EC_POINT *pub_key, const EC_KEY *ecdh); + int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, const BIGNUM *kinv, + const BIGNUM *r, EC_KEY *eckey); + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey); + int (*verify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); + int (*verify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); +} /* EC_KEY_METHOD */; + +#define EC_KEY_METHOD_DYNAMIC 1 + +int ec_key_gen(EC_KEY *eckey); +int ecdh_compute_key(unsigned char **out, size_t *out_len, + const EC_POINT *pub_key, const EC_KEY *ecdh); +int ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); +int ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +/* + * ECDH Key Derivation Function as defined in ANSI X9.63. + */ +int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, + size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md); + +int EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx); +int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); + +/* Public API in OpenSSL */ +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/ec/ec_mult.c b/Libraries/libressl/crypto/ec/ec_mult.c new file mode 100644 index 000000000..a0e97437b --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_mult.c @@ -0,0 +1,450 @@ +/* $OpenBSD: ec_mult.c,v 1.31 2023/06/24 17:49:44 jsing Exp $ */ +/* + * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include + +#include "ec_local.h" + +/* + * This file implements the wNAF-based interleaving multi-exponentation method + * (); + * for multiplication with precomputation, we use wNAF splitting + * (). + */ + +/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. + * This is an array r[] of values that are either zero or odd with an + * absolute value less than 2^w satisfying + * scalar = \sum_j r[j]*2^j + * where at most one of any w+1 consecutive digits is non-zero + * with the exception that the most significant digit may be only + * w-1 zeros away from that next non-zero digit. + */ +static signed char * +compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) +{ + int window_val; + int ok = 0; + signed char *r = NULL; + int sign = 1; + int bit, next_bit, mask; + size_t len = 0, j; + + if (BN_is_zero(scalar)) { + r = malloc(1); + if (!r) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + r[0] = 0; + *ret_len = 1; + return r; + } + if (w <= 0 || w > 7) { + /* 'signed char' can represent integers with + * absolute values less than 2^7 */ + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + bit = 1 << w; /* at most 128 */ + next_bit = bit << 1; /* at most 256 */ + mask = next_bit - 1; /* at most 255 */ + + if (BN_is_negative(scalar)) { + sign = -1; + } + if (scalar->d == NULL || scalar->top == 0) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + len = BN_num_bits(scalar); + r = malloc(len + 1); /* modified wNAF may be one digit longer than + * binary representation (*ret_len will be + * set to the actual length, i.e. at most + * BN_num_bits(scalar) + 1) */ + if (r == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + window_val = scalar->d[0] & mask; + j = 0; + while ((window_val != 0) || (j + w + 1 < len)) { + /* if j+w+1 >= len, window_val will not increase */ + int digit = 0; + + /* 0 <= window_val <= 2^(w+1) */ + if (window_val & 1) { + /* 0 < window_val < 2^(w+1) */ + if (window_val & bit) { + digit = window_val - next_bit; /* -2^w < digit < 0 */ + +#if 1 /* modified wNAF */ + if (j + w + 1 >= len) { + /* + * special case for generating + * modified wNAFs: no new bits will + * be added into window_val, so using + * a positive digit here will + * decrease the total length of the + * representation + */ + + digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ + } +#endif + } else { + digit = window_val; /* 0 < digit < 2^w */ + } + + if (digit <= -bit || digit >= bit || !(digit & 1)) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + window_val -= digit; + + /* + * now window_val is 0 or 2^(w+1) in standard wNAF + * generation; for modified window NAFs, it may also + * be 2^w + */ + if (window_val != 0 && window_val != next_bit && window_val != bit) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + r[j++] = sign * digit; + + window_val >>= 1; + window_val += bit * BN_is_bit_set(scalar, j + w); + + if (window_val > next_bit) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (j > len + 1) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + len = j; + ok = 1; + + err: + if (!ok) { + free(r); + r = NULL; + } + if (ok) + *ret_len = len; + return r; +} + + +/* TODO: table should be optimised for the wNAF-based implementation, + * sometimes smaller windows will give better performance + * (thus the boundaries should be increased) + */ +#define EC_window_bits_for_scalar_size(b) \ + ((size_t) \ + ((b) >= 2000 ? 6 : \ + (b) >= 800 ? 5 : \ + (b) >= 300 ? 4 : \ + (b) >= 70 ? 3 : \ + (b) >= 20 ? 2 : \ + 1)) + +/* Compute + * \sum scalars[i]*points[i], + * also including + * scalar*generator + * in the addition if scalar != NULL + */ +int +ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) +{ + const EC_POINT *generator = NULL; + EC_POINT *tmp = NULL; + size_t totalnum; + size_t numblocks = 0; /* for wNAF splitting */ + size_t i, j; + int k; + int r_is_inverted = 0; + int r_is_at_infinity = 1; + size_t *wsize = NULL; /* individual window sizes */ + signed char **wNAF = NULL; /* individual wNAFs */ + signed char *tmp_wNAF = NULL; + size_t *wNAF_len = NULL; + size_t max_len = 0; + size_t num_val; + EC_POINT **val = NULL; /* precomputation */ + EC_POINT **v; + EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or + * 'pre_comp->points' */ + int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be + * treated like other scalars, i.e. + * precomputation is not available */ + int ret = 0; + + if (group->meth != r->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if ((scalar == NULL) && (num == 0)) { + return EC_POINT_set_to_infinity(group, r); + } + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + + if (scalar != NULL) { + generator = EC_GROUP_get0_generator(group); + if (generator == NULL) { + ECerror(EC_R_UNDEFINED_GENERATOR); + goto err; + } + + numblocks = 1; + num_scalar = 1; /* treat 'scalar' like 'num'-th + * element of 'scalars' */ + } + totalnum = num + numblocks; + + /* includes space for pivot */ + wNAF = reallocarray(NULL, (totalnum + 1), sizeof wNAF[0]); + if (wNAF == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + wNAF[0] = NULL; /* preliminary pivot */ + + wsize = reallocarray(NULL, totalnum, sizeof wsize[0]); + wNAF_len = reallocarray(NULL, totalnum, sizeof wNAF_len[0]); + val_sub = reallocarray(NULL, totalnum, sizeof val_sub[0]); + + if (wsize == NULL || wNAF_len == NULL || val_sub == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* num_val will be the total number of temporarily precomputed points */ + num_val = 0; + + for (i = 0; i < num + num_scalar; i++) { + size_t bits; + + bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); + wsize[i] = EC_window_bits_for_scalar_size(bits); + num_val += (size_t) 1 << (wsize[i] - 1); + wNAF[i + 1] = NULL; /* make sure we always have a pivot */ + wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]); + if (wNAF[i] == NULL) + goto err; + if (wNAF_len[i] > max_len) + max_len = wNAF_len[i]; + } + + if (numblocks) { + /* we go here iff scalar != NULL */ + + if (num_scalar != 1) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + /* + * All points we precompute now go into a single array 'val'. + * 'val_sub[i]' is a pointer to the subarray for the i-th point, or + * to a subarray of 'pre_comp->points' if we already have + * precomputation. + */ + val = reallocarray(NULL, (num_val + 1), sizeof val[0]); + if (val == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + val[num_val] = NULL; /* pivot element */ + + /* allocate points for precomputation */ + v = val; + for (i = 0; i < num + num_scalar; i++) { + val_sub[i] = v; + for (j = 0; j < ((size_t) 1 << (wsize[i] - 1)); j++) { + *v = EC_POINT_new(group); + if (*v == NULL) + goto err; + v++; + } + } + if (!(v == val + num_val)) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(tmp = EC_POINT_new(group))) + goto err; + + /* + * prepare precomputed values: val_sub[i][0] := points[i] + * val_sub[i][1] := 3 * points[i] val_sub[i][2] := 5 * points[i] ... + */ + for (i = 0; i < num + num_scalar; i++) { + if (i < num) { + if (!EC_POINT_copy(val_sub[i][0], points[i])) + goto err; + } else { + if (!EC_POINT_copy(val_sub[i][0], generator)) + goto err; + } + + if (wsize[i] > 1) { + if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) + goto err; + for (j = 1; j < ((size_t) 1 << (wsize[i] - 1)); j++) { + if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) + goto err; + } + } + } + + if (!EC_POINTs_make_affine(group, num_val, val, ctx)) + goto err; + + r_is_at_infinity = 1; + + for (k = max_len - 1; k >= 0; k--) { + if (!r_is_at_infinity) { + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + } + for (i = 0; i < totalnum; i++) { + if (wNAF_len[i] > (size_t) k) { + int digit = wNAF[i][k]; + int is_neg; + + if (digit) { + is_neg = digit < 0; + + if (is_neg) + digit = -digit; + + if (is_neg != r_is_inverted) { + if (!r_is_at_infinity) { + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + r_is_inverted = !r_is_inverted; + } + /* digit > 0 */ + + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) + goto err; + r_is_at_infinity = 0; + } else { + if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) + goto err; + } + } + } + } + } + + if (r_is_at_infinity) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + } else { + if (r_is_inverted) + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + + ret = 1; + + err: + EC_POINT_free(tmp); + free(wsize); + free(wNAF_len); + free(tmp_wNAF); + if (wNAF != NULL) { + signed char **w; + + for (w = wNAF; *w != NULL; w++) + free(*w); + + free(wNAF); + } + if (val != NULL) { + for (v = val; *v != NULL; v++) + EC_POINT_free(*v); + free(val); + } + free(val_sub); + return ret; +} diff --git a/Libraries/libressl/crypto/ec/ec_oct.c b/Libraries/libressl/crypto/ec/ec_oct.c new file mode 100644 index 000000000..9308d409c --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_oct.c @@ -0,0 +1,170 @@ +/* $OpenBSD: ec_oct.c,v 1.16 2023/07/07 19:37:53 beck Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include + +#include +#include + +#include "ec_local.h" + +int +EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, int y_bit, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_set_compressed_coordinates == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->point_set_compressed_coordinates(group, point, + x, y_bit, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates); + +int +EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, int y_bit, BN_CTX *ctx) +{ + return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx); +} + +size_t +EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, unsigned char *buf, size_t len, + BN_CTX *ctx_in) +{ + BN_CTX *ctx; + size_t ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point2oct == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->point2oct(group, point, form, buf, len, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_point2oct); + +int +EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, BN_CTX *ctx_in) +{ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->oct2point == NULL) { + ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + if (group->meth != point->meth) { + ECerror(EC_R_INCOMPATIBLE_OBJECTS); + goto err; + } + ret = group->meth->oct2point(group, point, buf, len, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_oct2point); diff --git a/Libraries/libressl/crypto/ec/ec_pmeth.c b/Libraries/libressl/crypto/ec/ec_pmeth.c new file mode 100644 index 000000000..d3bf7e8cd --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_pmeth.c @@ -0,0 +1,524 @@ +/* $OpenBSD: ec_pmeth.c,v 1.19 2023/07/28 15:50:33 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "ec_local.h" +#include "evp_local.h" + +/* EC pkey context structure */ + +typedef struct { + /* Key and paramgen group */ + EC_GROUP *gen_group; + /* message digest */ + const EVP_MD *md; + /* Duplicate key if custom cofactor needed */ + EC_KEY *co_key; + /* Cofactor mode */ + signed char cofactor_mode; + /* KDF (if any) to use for ECDH */ + char kdf_type; + /* Message digest to use for key derivation */ + const EVP_MD *kdf_md; + /* User key material */ + unsigned char *kdf_ukm; + size_t kdf_ukmlen; + /* KDF output length */ + size_t kdf_outlen; +} EC_PKEY_CTX; + +static int +pkey_ec_init(EVP_PKEY_CTX *ctx) +{ + EC_PKEY_CTX *dctx; + + if ((dctx = calloc(1, sizeof(EC_PKEY_CTX))) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + dctx->cofactor_mode = -1; + dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE; + + ctx->data = dctx; + + return 1; +} + +static int +pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + EC_PKEY_CTX *dctx, *sctx; + if (!pkey_ec_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + if (sctx->gen_group) { + dctx->gen_group = EC_GROUP_dup(sctx->gen_group); + if (!dctx->gen_group) + return 0; + } + dctx->md = sctx->md; + + if (sctx->co_key) { + dctx->co_key = EC_KEY_dup(sctx->co_key); + if (!dctx->co_key) + return 0; + } + dctx->kdf_type = sctx->kdf_type; + dctx->kdf_md = sctx->kdf_md; + dctx->kdf_outlen = sctx->kdf_outlen; + if (sctx->kdf_ukm) { + if ((dctx->kdf_ukm = calloc(1, sctx->kdf_ukmlen)) == NULL) + return 0; + memcpy(dctx->kdf_ukm, sctx->kdf_ukm, sctx->kdf_ukmlen); + } else + dctx->kdf_ukm = NULL; + + dctx->kdf_ukmlen = sctx->kdf_ukmlen; + + return 1; +} + +static void +pkey_ec_cleanup(EVP_PKEY_CTX *ctx) +{ + EC_PKEY_CTX *dctx = ctx->data; + + if (dctx != NULL) { + EC_GROUP_free(dctx->gen_group); + EC_KEY_free(dctx->co_key); + free(dctx->kdf_ukm); + free(dctx); + ctx->data = NULL; + } +} + +static int +pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + unsigned int sltmp; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (!sig) { + *siglen = ECDSA_size(ec); + return 1; + } else if (*siglen < (size_t) ECDSA_size(ec)) { + ECerror(EC_R_BUFFER_TOO_SMALL); + return 0; + } + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); + if (ret <= 0) + return ret; + *siglen = (size_t) sltmp; + return 1; +} + +static int +pkey_ec_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); + + return ret; +} + +static int +pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + EC_KEY *eckey; + EC_PKEY_CTX *dctx = ctx->data; + + if (!ctx->pkey || !ctx->peerkey) { + ECerror(EC_R_KEYS_NOT_SET); + return 0; + } + + eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec; + if (!key) { + const EC_GROUP *group; + group = EC_KEY_get0_group(eckey); + *keylen = (EC_GROUP_get_degree(group) + 7) / 8; + return 1; + } + pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + /* + * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is + * not an error, the result is truncated. + */ + + outlen = *keylen; + + ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); + if (ret <= 0) + return 0; + + *keylen = ret; + + return 1; +} + +static int +pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + EC_PKEY_CTX *dctx = ctx->data; + unsigned char *ktmp = NULL; + size_t ktmplen; + int rv = 0; + + if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE) + return pkey_ec_derive(ctx, key, keylen); + + if (!key) { + *keylen = dctx->kdf_outlen; + return 1; + } + if (*keylen != dctx->kdf_outlen) + return 0; + if (!pkey_ec_derive(ctx, NULL, &ktmplen)) + return 0; + if ((ktmp = calloc(1, ktmplen)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + return 0; + } + if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) + goto err; + /* Do KDF stuff */ + if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, dctx->kdf_ukm, + dctx->kdf_ukmlen, dctx->kdf_md)) + goto err; + rv = 1; + + err: + freezero(ktmp, ktmplen); + + return rv; +} + +static int +pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + EC_PKEY_CTX *dctx = ctx->data; + EC_GROUP *group; + + switch (type) { + case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: + group = EC_GROUP_new_by_curve_name(p1); + if (group == NULL) { + ECerror(EC_R_INVALID_CURVE); + return 0; + } + EC_GROUP_free(dctx->gen_group); + dctx->gen_group = group; + return 1; + + case EVP_PKEY_CTRL_EC_PARAM_ENC: + if (!dctx->gen_group) { + ECerror(EC_R_NO_PARAMETERS_SET); + return 0; + } + EC_GROUP_set_asn1_flag(dctx->gen_group, p1); + return 1; + + case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: + if (p1 == -2) { + if (dctx->cofactor_mode != -1) + return dctx->cofactor_mode; + else { + EC_KEY *ec_key = ctx->pkey->pkey.ec; + return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; + } + } else if (p1 < -1 || p1 > 1) + return -2; + dctx->cofactor_mode = p1; + if (p1 != -1) { + EC_KEY *ec_key = ctx->pkey->pkey.ec; + if (!ec_key->group) + return -2; + /* If cofactor is 1 cofactor mode does nothing */ + if (BN_is_one(&ec_key->group->cofactor)) + return 1; + if (!dctx->co_key) { + dctx->co_key = EC_KEY_dup(ec_key); + if (!dctx->co_key) + return 0; + } + if (p1) + EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); + else + EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); + } else { + EC_KEY_free(dctx->co_key); + dctx->co_key = NULL; + } + return 1; + + case EVP_PKEY_CTRL_EC_KDF_TYPE: + if (p1 == -2) + return dctx->kdf_type; + if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63) + return -2; + dctx->kdf_type = p1; + return 1; + + case EVP_PKEY_CTRL_EC_KDF_MD: + dctx->kdf_md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_EC_KDF_MD: + *(const EVP_MD **)p2 = dctx->kdf_md; + return 1; + + case EVP_PKEY_CTRL_EC_KDF_OUTLEN: + if (p1 <= 0) + return -2; + dctx->kdf_outlen = (size_t)p1; + return 1; + + case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: + *(int *)p2 = dctx->kdf_outlen; + return 1; + + case EVP_PKEY_CTRL_EC_KDF_UKM: + free(dctx->kdf_ukm); + dctx->kdf_ukm = p2; + if (p2) + dctx->kdf_ukmlen = p1; + else + dctx->kdf_ukmlen = 0; + return 1; + + case EVP_PKEY_CTRL_GET_EC_KDF_UKM: + *(unsigned char **)p2 = dctx->kdf_ukm; + return dctx->kdf_ukmlen; + + case EVP_PKEY_CTRL_MD: + /* RFC 3279, RFC 5758 and NIST CSOR. */ + if (EVP_MD_type((const EVP_MD *) p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *) p2) != NID_ecdsa_with_SHA1 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha256 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha384 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha512 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha3_224 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha3_256 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha3_384 && + EVP_MD_type((const EVP_MD *) p2) != NID_sha3_512) { + ECerror(EC_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = dctx->md; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + default: + return -2; + + } +} + +static int +pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + if (!strcmp(type, "ec_paramgen_curve")) { + int nid; + nid = EC_curve_nist2nid(value); + if (nid == NID_undef) + nid = OBJ_sn2nid(value); + if (nid == NID_undef) + nid = OBJ_ln2nid(value); + if (nid == NID_undef) { + ECerror(EC_R_INVALID_CURVE); + return 0; + } + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); + } else if (strcmp(type, "ec_param_enc") == 0) { + int param_enc; + if (strcmp(value, "explicit") == 0) + param_enc = 0; + else if (strcmp(value, "named_curve") == 0) + param_enc = OPENSSL_EC_NAMED_CURVE; + else + return -2; + return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); + } else if (strcmp(type, "ecdh_kdf_md") == 0) { + const EVP_MD *md; + if ((md = EVP_get_digestbyname(value)) == NULL) { + ECerror(EC_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); + } else if (strcmp(type, "ecdh_cofactor_mode") == 0) { + int co_mode; + co_mode = atoi(value); + return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode); + } + return -2; +} + +static int +pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec = NULL; + EC_PKEY_CTX *dctx = ctx->data; + int ret = 0; + if (dctx->gen_group == NULL) { + ECerror(EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + ret = EC_KEY_set_group(ec, dctx->gen_group); + if (ret) + EVP_PKEY_assign_EC_KEY(pkey, ec); + else + EC_KEY_free(ec); + return ret; +} + +static int +pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec = NULL; + EC_PKEY_CTX *dctx = ctx->data; + + if (ctx->pkey == NULL && dctx->gen_group == NULL) { + ECerror(EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (ec == NULL) + return 0; + if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { + EC_KEY_free(ec); + return 0; + } + /* Note: if error is returned, we count on caller to free pkey->pkey.ec */ + if (ctx->pkey != NULL) { + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + } else { + if (!EC_KEY_set_group(ec, dctx->gen_group)) + return 0; + } + + return EC_KEY_generate_key(ec); +} + +const EVP_PKEY_METHOD ec_pkey_meth = { + .pkey_id = EVP_PKEY_EC, + + .init = pkey_ec_init, + .copy = pkey_ec_copy, + .cleanup = pkey_ec_cleanup, + + .paramgen = pkey_ec_paramgen, + + .keygen = pkey_ec_keygen, + + .sign = pkey_ec_sign, + + .verify = pkey_ec_verify, + + .derive = pkey_ec_kdf_derive, + + .ctrl = pkey_ec_ctrl, + .ctrl_str = pkey_ec_ctrl_str +}; diff --git a/Libraries/libressl/crypto/ec/ec_print.c b/Libraries/libressl/crypto/ec/ec_print.c new file mode 100644 index 000000000..312770f66 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ec_print.c @@ -0,0 +1,182 @@ +/* $OpenBSD: ec_print.c,v 1.13 2023/07/07 13:54:45 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ec_local.h" + +BIGNUM * +EC_POINT_point2bn(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, BIGNUM *ret, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + + buf_len = EC_POINT_point2oct(group, point, form, + NULL, 0, ctx); + if (buf_len == 0) + return NULL; + + if ((buf = malloc(buf_len)) == NULL) + return NULL; + + if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { + free(buf); + return NULL; + } + ret = BN_bin2bn(buf, buf_len, ret); + + free(buf); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_point2bn); + +EC_POINT * +EC_POINT_bn2point(const EC_GROUP *group, + const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + EC_POINT *ret; + + if ((buf_len = BN_num_bytes(bn)) == 0) + return NULL; + buf = malloc(buf_len); + if (buf == NULL) + return NULL; + + if (!BN_bn2bin(bn, buf)) { + free(buf); + return NULL; + } + if (point == NULL) { + if ((ret = EC_POINT_new(group)) == NULL) { + free(buf); + return NULL; + } + } else + ret = point; + + if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { + if (point == NULL) + EC_POINT_free(ret); + free(buf); + return NULL; + } + free(buf); + return ret; +} +LCRYPTO_ALIAS(EC_POINT_bn2point); + +static const char *HEX_DIGITS = "0123456789ABCDEF"; + +/* the return value must be freed (using free()) */ +char * +EC_POINT_point2hex(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, BN_CTX *ctx) +{ + char *ret, *p; + size_t buf_len = 0, i; + unsigned char *buf, *pbuf; + + buf_len = EC_POINT_point2oct(group, point, form, + NULL, 0, ctx); + if (buf_len == 0 || buf_len + 1 == 0) + return NULL; + + if ((buf = malloc(buf_len)) == NULL) + return NULL; + + if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { + free(buf); + return NULL; + } + ret = reallocarray(NULL, buf_len + 1, 2); + if (ret == NULL) { + free(buf); + return NULL; + } + p = ret; + pbuf = buf; + for (i = buf_len; i > 0; i--) { + int v = (int) *(pbuf++); + *(p++) = HEX_DIGITS[v >> 4]; + *(p++) = HEX_DIGITS[v & 0x0F]; + } + *p = '\0'; + + free(buf); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_point2hex); + +EC_POINT * +EC_POINT_hex2point(const EC_GROUP *group, const char *buf, + EC_POINT *point, BN_CTX *ctx) +{ + EC_POINT *ret = NULL; + BIGNUM *tmp_bn = NULL; + + if (BN_hex2bn(&tmp_bn, buf) == 0) + return NULL; + + ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); + + BN_free(tmp_bn); + + return ret; +} +LCRYPTO_ALIAS(EC_POINT_hex2point); diff --git a/Libraries/libressl/crypto/ec/eck_prn.c b/Libraries/libressl/crypto/ec/eck_prn.c new file mode 100644 index 000000000..6e89bfa73 --- /dev/null +++ b/Libraries/libressl/crypto/ec/eck_prn.c @@ -0,0 +1,353 @@ +/* $OpenBSD: eck_prn.c,v 1.28 2023/07/07 13:54:45 beck Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include +#include + +#include +#include +#include +#include + +#include "ec_local.h" + +int +ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECPKParameters_print(b, x, off); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(ECPKParameters_print_fp); + +int +EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerror(ERR_R_BIO_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = EC_KEY_print(b, x, off); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(EC_KEY_print_fp); + +int +ECParameters_print_fp(FILE *fp, const EC_KEY *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerror(ERR_R_BIO_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECParameters_print(b, x); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(ECParameters_print_fp); + +int +EC_KEY_print(BIO *bp, const EC_KEY *x, int off) +{ + EVP_PKEY *pk; + int ret = 0; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + if (!EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *) x)) + goto err; + + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + err: + EVP_PKEY_free(pk); + return ret; +} +LCRYPTO_ALIAS(EC_KEY_print); + +int +ECParameters_print(BIO *bp, const EC_KEY *x) +{ + EVP_PKEY *pk; + int ret = 0; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + if (!EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *) x)) + goto err; + + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + err: + EVP_PKEY_free(pk); + return ret; +} +LCRYPTO_ALIAS(ECParameters_print); + +static int +print_bin(BIO *fp, const char *str, const unsigned char *num, + size_t len, int off); + +static int +ecpk_print_asn1_parameters(BIO *bp, const EC_GROUP *group, int off) +{ + const char *nist_name; + int nid; + int ret = 0; + + if (!BIO_indent(bp, off, 128)) { + ECerror(ERR_R_BIO_LIB); + goto err; + } + + if ((nid = EC_GROUP_get_curve_name(group)) == NID_undef) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + + if (BIO_printf(bp, "ASN1 OID: %s\n", OBJ_nid2sn(nid)) <= 0) { + ECerror(ERR_R_BIO_LIB); + goto err; + } + + if ((nist_name = EC_curve_nid2nist(nid)) != NULL) { + if (!BIO_indent(bp, off, 128)) { + ECerror(ERR_R_BIO_LIB); + goto err; + } + if (BIO_printf(bp, "NIST CURVE: %s\n", nist_name) <= 0) { + ECerror(ERR_R_BIO_LIB); + goto err; + } + } + + ret = 1; + err: + + return ret; +} + +static int +ecpk_print_explicit_parameters(BIO *bp, const EC_GROUP *group, int off) +{ + BN_CTX *ctx = NULL; + const BIGNUM *order; + BIGNUM *p, *a, *b, *cofactor; + BIGNUM *gen = NULL; + const EC_POINT *generator; + const char *conversion_form; + const unsigned char *seed; + size_t seed_len; + point_conversion_form_t form; + int nid; + int ret = 0; + + if ((ctx = BN_CTX_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((cofactor = BN_CTX_get(ctx)) == NULL) + goto err; + if ((gen = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if ((order = EC_GROUP_get0_order(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (!EC_GROUP_get_cofactor(group, cofactor, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + if ((generator = EC_GROUP_get0_generator(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + form = EC_GROUP_get_point_conversion_form(group); + if (EC_POINT_point2bn(group, generator, form, gen, ctx) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + if (!BIO_indent(bp, off, 128)) + goto err; + + nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(nid)) <= 0) + goto err; + + if (!bn_printf(bp, p, off, "Prime:")) + goto err; + if (!bn_printf(bp, a, off, "A: ")) + goto err; + if (!bn_printf(bp, b, off, "B: ")) + goto err; + + if (form == POINT_CONVERSION_COMPRESSED) + conversion_form = "compressed"; + else if (form == POINT_CONVERSION_UNCOMPRESSED) + conversion_form = "uncompressed"; + else if (form == POINT_CONVERSION_HYBRID) + conversion_form = "hybrid"; + else + conversion_form = "unknown"; + if (!bn_printf(bp, gen, off, "Generator (%s):", conversion_form)) + goto err; + + if (!bn_printf(bp, order, off, "Order: ")) + goto err; + if (!bn_printf(bp, cofactor, off, "Cofactor: ")) + goto err; + if ((seed = EC_GROUP_get0_seed(group)) != NULL) { + seed_len = EC_GROUP_get_seed_len(group); + if (!print_bin(bp, "Seed:", seed, seed_len, off)) + goto err; + } + + ret = 1; + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ret; +} + +int +ECPKParameters_print(BIO *bp, const EC_GROUP *group, int off) +{ + if (group == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_GROUP_get_asn1_flag(group)) + return ecpk_print_asn1_parameters(bp, group, off); + + return ecpk_print_explicit_parameters(bp, group, off); +} +LCRYPTO_ALIAS(ECPKParameters_print); + +static int +print_bin(BIO *fp, const char *name, const unsigned char *buf, + size_t len, int off) +{ + size_t i; + char str[128]; + + if (buf == NULL) + return 1; + if (off) { + if (off > 128) + off = 128; + memset(str, ' ', off); + if (BIO_write(fp, str, off) <= 0) + return 0; + } + if (BIO_printf(fp, "%s", name) <= 0) + return 0; + + for (i = 0; i < len; i++) { + if ((i % 15) == 0) { + str[0] = '\n'; + memset(&(str[1]), ' ', off + 4); + if (BIO_write(fp, str, off + 1 + 4) <= 0) + return 0; + } + if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= 0) + return 0; + } + if (BIO_write(fp, "\n", 1) <= 0) + return 0; + + return 1; +} diff --git a/Libraries/libressl/crypto/ec/ecp_mont.c b/Libraries/libressl/crypto/ec/ecp_mont.c new file mode 100644 index 000000000..76d1f578e --- /dev/null +++ b/Libraries/libressl/crypto/ec/ecp_mont.c @@ -0,0 +1,272 @@ +/* $OpenBSD: ecp_mont.c,v 1.30 2023/07/07 13:54:45 beck Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include "ec_local.h" + +static void +ec_GFp_mont_group_clear(EC_GROUP *group) +{ + BN_MONT_CTX_free(group->mont_ctx); + group->mont_ctx = NULL; + + BN_free(group->mont_one); + group->mont_one = NULL; +} + +static int +ec_GFp_mont_group_init(EC_GROUP *group) +{ + int ok; + + ok = ec_GFp_simple_group_init(group); + group->mont_ctx = NULL; + group->mont_one = NULL; + return ok; +} + +static void +ec_GFp_mont_group_finish(EC_GROUP *group) +{ + ec_GFp_mont_group_clear(group); + ec_GFp_simple_group_finish(group); +} + +static int +ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + ec_GFp_mont_group_clear(dest); + + if (!ec_GFp_simple_group_copy(dest, src)) + return 0; + + if (src->mont_ctx != NULL) { + dest->mont_ctx = BN_MONT_CTX_new(); + if (dest->mont_ctx == NULL) + return 0; + if (!BN_MONT_CTX_copy(dest->mont_ctx, src->mont_ctx)) + goto err; + } + if (src->mont_one != NULL) { + dest->mont_one = BN_dup(src->mont_one); + if (dest->mont_one == NULL) + goto err; + } + return 1; + + err: + if (dest->mont_ctx != NULL) { + BN_MONT_CTX_free(dest->mont_ctx); + dest->mont_ctx = NULL; + } + return 0; +} + +static int +ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + BN_MONT_CTX *mont = NULL; + BIGNUM *one = NULL; + int ret = 0; + + ec_GFp_mont_group_clear(group); + + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + one = BN_new(); + if (one == NULL) + goto err; + if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) + goto err; + + group->mont_ctx = mont; + mont = NULL; + group->mont_one = one; + one = NULL; + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + if (!ret) + ec_GFp_mont_group_clear(group); + + err: + BN_MONT_CTX_free(mont); + BN_free(one); + + return ret; +} + +static int +ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->mont_ctx == NULL) { + ECerror(EC_R_NOT_INITIALIZED); + return 0; + } + return BN_mod_mul_montgomery(r, a, b, group->mont_ctx, ctx); +} + +static int +ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + if (group->mont_ctx == NULL) { + ECerror(EC_R_NOT_INITIALIZED); + return 0; + } + return BN_mod_mul_montgomery(r, a, a, group->mont_ctx, ctx); +} + +static int +ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + if (group->mont_ctx == NULL) { + ECerror(EC_R_NOT_INITIALIZED); + return 0; + } + return BN_to_montgomery(r, a, group->mont_ctx, ctx); +} + +static int +ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + if (group->mont_ctx == NULL) { + ECerror(EC_R_NOT_INITIALIZED); + return 0; + } + return BN_from_montgomery(r, a, group->mont_ctx, ctx); +} + +static int +ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx) +{ + if (group->mont_one == NULL) { + ECerror(EC_R_NOT_INITIALIZED); + return 0; + } + if (!bn_copy(r, group->mont_one)) + return 0; + + return 1; +} + +static const EC_METHOD ec_GFp_mont_method = { + .field_type = NID_X9_62_prime_field, + .group_init = ec_GFp_mont_group_init, + .group_finish = ec_GFp_mont_group_finish, + .group_copy = ec_GFp_mont_group_copy, + .group_set_curve = ec_GFp_mont_group_set_curve, + .group_get_curve = ec_GFp_simple_group_get_curve, + .group_get_degree = ec_GFp_simple_group_get_degree, + .group_order_bits = ec_group_simple_order_bits, + .group_check_discriminant = ec_GFp_simple_group_check_discriminant, + .point_init = ec_GFp_simple_point_init, + .point_finish = ec_GFp_simple_point_finish, + .point_copy = ec_GFp_simple_point_copy, + .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity, + .point_set_Jprojective_coordinates = + ec_GFp_simple_set_Jprojective_coordinates, + .point_get_Jprojective_coordinates = + ec_GFp_simple_get_Jprojective_coordinates, + .point_set_affine_coordinates = + ec_GFp_simple_point_set_affine_coordinates, + .point_get_affine_coordinates = + ec_GFp_simple_point_get_affine_coordinates, + .point_set_compressed_coordinates = + ec_GFp_simple_set_compressed_coordinates, + .point2oct = ec_GFp_simple_point2oct, + .oct2point = ec_GFp_simple_oct2point, + .add = ec_GFp_simple_add, + .dbl = ec_GFp_simple_dbl, + .invert = ec_GFp_simple_invert, + .is_at_infinity = ec_GFp_simple_is_at_infinity, + .is_on_curve = ec_GFp_simple_is_on_curve, + .point_cmp = ec_GFp_simple_cmp, + .make_affine = ec_GFp_simple_make_affine, + .points_make_affine = ec_GFp_simple_points_make_affine, + .mul_generator_ct = ec_GFp_simple_mul_generator_ct, + .mul_single_ct = ec_GFp_simple_mul_single_ct, + .mul_double_nonct = ec_GFp_simple_mul_double_nonct, + .field_mul = ec_GFp_mont_field_mul, + .field_sqr = ec_GFp_mont_field_sqr, + .field_encode = ec_GFp_mont_field_encode, + .field_decode = ec_GFp_mont_field_decode, + .field_set_to_one = ec_GFp_mont_field_set_to_one, + .blind_coordinates = ec_GFp_simple_blind_coordinates, +}; + +const EC_METHOD * +EC_GFp_mont_method(void) +{ + return &ec_GFp_mont_method; +} +LCRYPTO_ALIAS(EC_GFp_mont_method); diff --git a/Libraries/libressl/crypto/ec/ecp_oct.c b/Libraries/libressl/crypto/ec/ecp_oct.c new file mode 100644 index 000000000..b3cf44165 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ecp_oct.c @@ -0,0 +1,365 @@ +/* $OpenBSD: ecp_oct.c,v 1.21 2023/04/18 18:29:32 tb Exp $ */ +/* Includes code written by Lenka Fibikova + * for the OpenSSL project. + * Includes code written by Bodo Moeller for the OpenSSL project. +*/ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include "ec_local.h" + +int +ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x_, int y_bit, BN_CTX *ctx) +{ + BIGNUM *tmp1, *tmp2, *x, *y; + int ret = 0; + + /* clear error queue */ + ERR_clear_error(); + + y_bit = (y_bit != 0); + + BN_CTX_start(ctx); + + if ((tmp1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + if ((y = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Recover y. We have a Weierstrass equation y^2 = x^3 + a*x + b, so + * y is one of the square roots of x^3 + a*x + b. + */ + + /* tmp1 := x^3 */ + if (!BN_nnmod(x, x_, &group->field, ctx)) + goto err; + if (group->meth->field_decode == NULL) { + /* field_{sqr,mul} work on standard representation */ + if (!group->meth->field_sqr(group, tmp2, x_, ctx)) + goto err; + if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) + goto err; + } else { + if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) + goto err; + if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) + goto err; + } + + /* tmp1 := tmp1 + a*x */ + if (group->a_is_minus3) { + if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) + goto err; + if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) + goto err; + if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } else { + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) + goto err; + if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) + goto err; + } else { + /* field_mul works on standard representation */ + if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) + goto err; + } + + if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } + + /* tmp1 := tmp1 + b */ + if (group->meth->field_decode != NULL) { + if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) + goto err; + if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } else { + if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) + goto err; + } + + if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { + ERR_clear_error(); + ECerror(EC_R_INVALID_COMPRESSED_POINT); + } else + ECerror(ERR_R_BN_LIB); + goto err; + } + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) { + ECerror(EC_R_INVALID_COMPRESSION_BIT); + goto err; + } + if (!BN_usub(y, &group->field, y)) + goto err; + if (y_bit != BN_is_odd(y)) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +size_t +ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx) +{ + BIGNUM *x, *y; + size_t field_len, i, skip; + size_t ret = 0; + + if (form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED && + form != POINT_CONVERSION_HYBRID) { + ECerror(EC_R_INVALID_FORM); + return 0; + } + + if (EC_POINT_is_at_infinity(group, point) > 0) { + /* encodes to a single 0 octet */ + if (buf != NULL) { + if (len < 1) { + ECerror(EC_R_BUFFER_TOO_SMALL); + return 0; + } + buf[0] = 0; + } + return 1; + } + + /* ret := required output buffer length */ + field_len = BN_num_bytes(&group->field); + ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + BN_CTX_start(ctx); + + /* if 'buf' is NULL, just return required length */ + if (buf != NULL) { + if (len < ret) { + ECerror(EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + if ((y = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx)) + goto err; + + if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) + buf[0] = form + 1; + else + buf[0] = form; + + i = 1; + + skip = field_len - BN_num_bytes(x); + if (skip > field_len) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(x, buf + i); + i += skip; + if (i != 1 + field_len) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) { + skip = field_len - BN_num_bytes(y); + if (skip > field_len) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(y, buf + i); + i += skip; + } + if (i != ret) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + point_conversion_form_t form; + int y_bit; + BIGNUM *x, *y; + size_t field_len, enc_len; + int ret = 0; + + if (len == 0) { + ECerror(EC_R_BUFFER_TOO_SMALL); + return 0; + } + form = buf[0]; + y_bit = form & 1; + form = form & ~1U; + if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerror(EC_R_INVALID_ENCODING); + return 0; + } + if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { + ECerror(EC_R_INVALID_ENCODING); + return 0; + } + if (form == 0) { + if (len != 1) { + ECerror(EC_R_INVALID_ENCODING); + return 0; + } + return EC_POINT_set_to_infinity(group, point); + } + field_len = BN_num_bytes(&group->field); + enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + if (len != enc_len) { + ECerror(EC_R_INVALID_ENCODING); + return 0; + } + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + if ((y = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_bin2bn(buf + 1, field_len, x)) + goto err; + if (BN_ucmp(x, &group->field) >= 0) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + if (form == POINT_CONVERSION_COMPRESSED) { + /* + * EC_POINT_set_compressed_coordinates checks that the point + * is on the curve as required by X9.62. + */ + if (!EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx)) + goto err; + } else { + if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) + goto err; + if (BN_ucmp(y, &group->field) >= 0) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + if (form == POINT_CONVERSION_HYBRID) { + if (y_bit != BN_is_odd(y)) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + } + /* + * EC_POINT_set_affine_coordinates checks that the point is + * on the curve as required by X9.62. + */ + if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} diff --git a/Libraries/libressl/crypto/ec/ecp_smpl.c b/Libraries/libressl/crypto/ec/ecp_smpl.c new file mode 100644 index 000000000..018aedfd4 --- /dev/null +++ b/Libraries/libressl/crypto/ec/ecp_smpl.c @@ -0,0 +1,1560 @@ +/* $OpenBSD: ecp_smpl.c,v 1.56 2023/08/03 18:53:56 tb Exp $ */ +/* Includes code written by Lenka Fibikova + * for the OpenSSL project. + * Includes code written by Bodo Moeller for the OpenSSL project. +*/ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include "bn_local.h" +#include "ec_local.h" + +/* + * Most method functions in this file are designed to work with + * non-trivial representations of field elements if necessary + * (see ecp_mont.c): while standard modular addition and subtraction + * are used, the field_mul and field_sqr methods will be used for + * multiplication, and field_encode and field_decode (if defined) + * will be used for converting between representations. + * + * Functions ec_GFp_simple_points_make_affine() and + * ec_GFp_simple_point_get_affine_coordinates() specifically assume + * that if a non-trivial representation is used, it is a Montgomery + * representation (i.e. 'encoding' means multiplying by some factor R). + */ + +int +ec_GFp_simple_group_init(EC_GROUP *group) +{ + BN_init(&group->field); + BN_init(&group->a); + BN_init(&group->b); + group->a_is_minus3 = 0; + return 1; +} + +void +ec_GFp_simple_group_finish(EC_GROUP *group) +{ + BN_free(&group->field); + BN_free(&group->a); + BN_free(&group->b); +} + +int +ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + if (!bn_copy(&dest->field, &src->field)) + return 0; + if (!bn_copy(&dest->a, &src->a)) + return 0; + if (!bn_copy(&dest->b, &src->b)) + return 0; + + dest->a_is_minus3 = src->a_is_minus3; + + return 1; +} + +static int +ec_decode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx) +{ + if (bn == NULL) + return 1; + + if (group->meth->field_decode != NULL) + return group->meth->field_decode(group, bn, x, ctx); + + return bn_copy(bn, x); +} + +static int +ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx) +{ + if (!BN_nnmod(bn, x, &group->field, ctx)) + return 0; + + if (group->meth->field_encode != NULL) + return group->meth->field_encode(group, bn, bn, ctx); + + return 1; +} + +static int +ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one, + const BIGNUM *z, BN_CTX *ctx) +{ + if (!BN_nnmod(bn, z, &group->field, ctx)) + return 0; + + *is_one = BN_is_one(bn); + if (*is_one && group->meth->field_set_to_one != NULL) + return group->meth->field_set_to_one(group, bn, ctx); + + if (group->meth->field_encode != NULL) + return group->meth->field_encode(group, bn, bn, ctx); + + return 1; +} + +int +ec_GFp_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + BIGNUM *a_plus_3; + int ret = 0; + + /* p must be a prime > 3 */ + if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { + ECerror(EC_R_INVALID_FIELD); + return 0; + } + + BN_CTX_start(ctx); + + if ((a_plus_3 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!bn_copy(&group->field, p)) + goto err; + BN_set_negative(&group->field, 0); + + if (!ec_encode_scalar(group, &group->a, a, ctx)) + goto err; + if (!ec_encode_scalar(group, &group->b, b, ctx)) + goto err; + + if (!BN_set_word(a_plus_3, 3)) + goto err; + if (!BN_mod_add(a_plus_3, a_plus_3, a, &group->field, ctx)) + goto err; + + group->a_is_minus3 = BN_is_zero(a_plus_3); + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + if (p != NULL) { + if (!bn_copy(p, &group->field)) + return 0; + } + if (!ec_decode_scalar(group, a, &group->a, ctx)) + return 0; + if (!ec_decode_scalar(group, b, &group->b, ctx)) + return 0; + + return 1; +} + +int +ec_GFp_simple_group_get_degree(const EC_GROUP *group) +{ + return BN_num_bits(&group->field); +} + +int +ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +{ + BIGNUM *p, *a, *b, *discriminant; + int ret = 0; + + BN_CTX_start(ctx); + + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((discriminant = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!EC_GROUP_get_curve(group, p, a, b, ctx)) + goto err; + + /* + * Check that the discriminant 4a^3 + 27b^2 is non-zero modulo p. + */ + + if (BN_is_zero(a) && BN_is_zero(b)) + goto err; + if (BN_is_zero(a) || BN_is_zero(b)) + goto done; + + /* Compute the discriminant: first 4a^3, then 27b^2, then their sum. */ + if (!BN_mod_sqr(discriminant, a, p, ctx)) + goto err; + if (!BN_mod_mul(discriminant, discriminant, a, p, ctx)) + goto err; + if (!BN_lshift(discriminant, discriminant, 2)) + goto err; + + if (!BN_mod_sqr(b, b, p, ctx)) + goto err; + if (!BN_mul_word(b, 27)) + goto err; + + if (!BN_mod_add(discriminant, discriminant, b, p, ctx)) + goto err; + + if (BN_is_zero(discriminant)) + goto err; + + done: + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_point_init(EC_POINT * point) +{ + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + point->Z_is_one = 0; + + return 1; +} + +void +ec_GFp_simple_point_finish(EC_POINT *point) +{ + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); + point->Z_is_one = 0; +} + +int +ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (!bn_copy(&dest->X, &src->X)) + return 0; + if (!bn_copy(&dest->Y, &src->Y)) + return 0; + if (!bn_copy(&dest->Z, &src->Z)) + return 0; + dest->Z_is_one = src->Z_is_one; + + return 1; +} + +int +ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point) +{ + point->Z_is_one = 0; + BN_zero(&point->Z); + return 1; +} + +int +ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx) +{ + int ret = 0; + + /* + * Setting individual coordinates allows the creation of bad points. + * EC_POINT_set_Jprojective_coordinates() checks at the API boundary. + */ + + if (x != NULL) { + if (!ec_encode_scalar(group, &point->X, x, ctx)) + goto err; + } + if (y != NULL) { + if (!ec_encode_scalar(group, &point->Y, y, ctx)) + goto err; + } + if (z != NULL) { + if (!ec_encode_z_coordinate(group, &point->Z, &point->Z_is_one, + z, ctx)) + goto err; + } + + ret = 1; + + err: + return ret; +} + +int +ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) +{ + int ret = 0; + + if (!ec_decode_scalar(group, x, &point->X, ctx)) + goto err; + if (!ec_decode_scalar(group, y, &point->Y, ctx)) + goto err; + if (!ec_decode_scalar(group, z, &point->Z, ctx)) + goto err; + + ret = 1; + + err: + return ret; +} + +int +ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) +{ + if (x == NULL || y == NULL) { + /* unlike for projective coordinates, we do not tolerate this */ + ECerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return EC_POINT_set_Jprojective_coordinates(group, point, x, y, + BN_value_one(), ctx); +} + +int +ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx) +{ + BIGNUM *z, *Z, *Z_1, *Z_2, *Z_3; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, point) > 0) { + ECerror(EC_R_POINT_AT_INFINITY); + return 0; + } + + BN_CTX_start(ctx); + + if ((z = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Z = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Z_1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Z_2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Z_3 = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Convert from projective coordinates (X, Y, Z) into (X/Z^2, Y/Z^3). */ + + if (!ec_decode_scalar(group, z, &point->Z, ctx)) + goto err; + + if (BN_is_one(z)) { + if (!ec_decode_scalar(group, x, &point->X, ctx)) + goto err; + if (!ec_decode_scalar(group, y, &point->Y, ctx)) + goto err; + goto done; + } + + if (BN_mod_inverse_ct(Z_1, z, &group->field, ctx) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (group->meth->field_encode == NULL) { + /* field_sqr works on standard representation */ + if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) + goto err; + } else { + if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) + goto err; + } + + if (x != NULL) { + /* + * in the Montgomery case, field_mul will cancel out + * Montgomery factor in X: + */ + if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) + goto err; + } + if (y != NULL) { + if (group->meth->field_encode == NULL) { + /* field_mul works on standard representation */ + if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) + goto err; + } else { + if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) + goto err; + } + + /* + * in the Montgomery case, field_mul will cancel out + * Montgomery factor in Y: + */ + if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) + goto err; + } + + done: + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; + const BIGNUM *p; + int ret = 0; + + if (a == b) + return EC_POINT_dbl(group, r, a, ctx); + if (EC_POINT_is_at_infinity(group, a) > 0) + return EC_POINT_copy(r, b); + if (EC_POINT_is_at_infinity(group, b) > 0) + return EC_POINT_copy(r, a); + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + BN_CTX_start(ctx); + + if ((n0 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((n1 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((n2 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((n3 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((n4 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((n5 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((n6 = BN_CTX_get(ctx)) == NULL) + goto end; + + /* + * Note that in this function we must not read components of 'a' or + * 'b' once we have written the corresponding components of 'r'. ('r' + * might be one of 'a' or 'b'.) + */ + + /* n1, n2 */ + if (b->Z_is_one) { + if (!bn_copy(n1, &a->X)) + goto end; + if (!bn_copy(n2, &a->Y)) + goto end; + /* n1 = X_a */ + /* n2 = Y_a */ + } else { + if (!field_sqr(group, n0, &b->Z, ctx)) + goto end; + if (!field_mul(group, n1, &a->X, n0, ctx)) + goto end; + /* n1 = X_a * Z_b^2 */ + + if (!field_mul(group, n0, n0, &b->Z, ctx)) + goto end; + if (!field_mul(group, n2, &a->Y, n0, ctx)) + goto end; + /* n2 = Y_a * Z_b^3 */ + } + + /* n3, n4 */ + if (a->Z_is_one) { + if (!bn_copy(n3, &b->X)) + goto end; + if (!bn_copy(n4, &b->Y)) + goto end; + /* n3 = X_b */ + /* n4 = Y_b */ + } else { + if (!field_sqr(group, n0, &a->Z, ctx)) + goto end; + if (!field_mul(group, n3, &b->X, n0, ctx)) + goto end; + /* n3 = X_b * Z_a^2 */ + + if (!field_mul(group, n0, n0, &a->Z, ctx)) + goto end; + if (!field_mul(group, n4, &b->Y, n0, ctx)) + goto end; + /* n4 = Y_b * Z_a^3 */ + } + + /* n5, n6 */ + if (!BN_mod_sub_quick(n5, n1, n3, p)) + goto end; + if (!BN_mod_sub_quick(n6, n2, n4, p)) + goto end; + /* n5 = n1 - n3 */ + /* n6 = n2 - n4 */ + + if (BN_is_zero(n5)) { + if (BN_is_zero(n6)) { + /* a is the same point as b */ + BN_CTX_end(ctx); + ret = EC_POINT_dbl(group, r, a, ctx); + ctx = NULL; + goto end; + } else { + /* a is the inverse of b */ + BN_zero(&r->Z); + r->Z_is_one = 0; + ret = 1; + goto end; + } + } + /* 'n7', 'n8' */ + if (!BN_mod_add_quick(n1, n1, n3, p)) + goto end; + if (!BN_mod_add_quick(n2, n2, n4, p)) + goto end; + /* 'n7' = n1 + n3 */ + /* 'n8' = n2 + n4 */ + + /* Z_r */ + if (a->Z_is_one && b->Z_is_one) { + if (!bn_copy(&r->Z, n5)) + goto end; + } else { + if (a->Z_is_one) { + if (!bn_copy(n0, &b->Z)) + goto end; + } else if (b->Z_is_one) { + if (!bn_copy(n0, &a->Z)) + goto end; + } else { + if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) + goto end; + } + if (!field_mul(group, &r->Z, n0, n5, ctx)) + goto end; + } + r->Z_is_one = 0; + /* Z_r = Z_a * Z_b * n5 */ + + /* X_r */ + if (!field_sqr(group, n0, n6, ctx)) + goto end; + if (!field_sqr(group, n4, n5, ctx)) + goto end; + if (!field_mul(group, n3, n1, n4, ctx)) + goto end; + if (!BN_mod_sub_quick(&r->X, n0, n3, p)) + goto end; + /* X_r = n6^2 - n5^2 * 'n7' */ + + /* 'n9' */ + if (!BN_mod_lshift1_quick(n0, &r->X, p)) + goto end; + if (!BN_mod_sub_quick(n0, n3, n0, p)) + goto end; + /* n9 = n5^2 * 'n7' - 2 * X_r */ + + /* Y_r */ + if (!field_mul(group, n0, n0, n6, ctx)) + goto end; + if (!field_mul(group, n5, n4, n5, ctx)) + goto end; /* now n5 is n5^3 */ + if (!field_mul(group, n1, n2, n5, ctx)) + goto end; + if (!BN_mod_sub_quick(n0, n0, n1, p)) + goto end; + if (BN_is_odd(n0)) + if (!BN_add(n0, n0, p)) + goto end; + /* now 0 <= n0 < 2*p, and n0 is even */ + if (!BN_rshift1(&r->Y, n0)) + goto end; + /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ + + ret = 1; + + end: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BIGNUM *n0, *n1, *n2, *n3; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, a) > 0) + return EC_POINT_set_to_infinity(group, r); + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + BN_CTX_start(ctx); + + if ((n0 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n3 = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Note that in this function we must not read components of 'a' once + * we have written the corresponding components of 'r'. ('r' might + * the same as 'a'.) + */ + + /* n1 */ + if (a->Z_is_one) { + if (!field_sqr(group, n0, &a->X, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n1, n0, p)) + goto err; + if (!BN_mod_add_quick(n0, n0, n1, p)) + goto err; + if (!BN_mod_add_quick(n1, n0, &group->a, p)) + goto err; + /* n1 = 3 * X_a^2 + a_curve */ + } else if (group->a_is_minus3) { + if (!field_sqr(group, n1, &a->Z, ctx)) + goto err; + if (!BN_mod_add_quick(n0, &a->X, n1, p)) + goto err; + if (!BN_mod_sub_quick(n2, &a->X, n1, p)) + goto err; + if (!field_mul(group, n1, n0, n2, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n0, n1, p)) + goto err; + if (!BN_mod_add_quick(n1, n0, n1, p)) + goto err; + /* + * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) = 3 * X_a^2 - 3 * + * Z_a^4 + */ + } else { + if (!field_sqr(group, n0, &a->X, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n1, n0, p)) + goto err; + if (!BN_mod_add_quick(n0, n0, n1, p)) + goto err; + if (!field_sqr(group, n1, &a->Z, ctx)) + goto err; + if (!field_sqr(group, n1, n1, ctx)) + goto err; + if (!field_mul(group, n1, n1, &group->a, ctx)) + goto err; + if (!BN_mod_add_quick(n1, n1, n0, p)) + goto err; + /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ + } + + /* Z_r */ + if (a->Z_is_one) { + if (!bn_copy(n0, &a->Y)) + goto err; + } else { + if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) + goto err; + } + if (!BN_mod_lshift1_quick(&r->Z, n0, p)) + goto err; + r->Z_is_one = 0; + /* Z_r = 2 * Y_a * Z_a */ + + /* n2 */ + if (!field_sqr(group, n3, &a->Y, ctx)) + goto err; + if (!field_mul(group, n2, &a->X, n3, ctx)) + goto err; + if (!BN_mod_lshift_quick(n2, n2, 2, p)) + goto err; + /* n2 = 4 * X_a * Y_a^2 */ + + /* X_r */ + if (!BN_mod_lshift1_quick(n0, n2, p)) + goto err; + if (!field_sqr(group, &r->X, n1, ctx)) + goto err; + if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) + goto err; + /* X_r = n1^2 - 2 * n2 */ + + /* n3 */ + if (!field_sqr(group, n0, n3, ctx)) + goto err; + if (!BN_mod_lshift_quick(n3, n0, 3, p)) + goto err; + /* n3 = 8 * Y_a^4 */ + + /* Y_r */ + if (!BN_mod_sub_quick(n0, n2, &r->X, p)) + goto err; + if (!field_mul(group, n0, n1, n0, ctx)) + goto err; + if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) + goto err; + /* Y_r = n1 * (n2 - X_r) - n3 */ + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (EC_POINT_is_at_infinity(group, point) > 0 || BN_is_zero(&point->Y)) + /* point is its own inverse */ + return 1; + + return BN_usub(&point->Y, &group->field, &point->Y); +} + +int +ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +{ + return BN_is_zero(&point->Z); +} + +int +ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BIGNUM *rh, *tmp, *Z4, *Z6; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, point) > 0) + return 1; + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + BN_CTX_start(ctx); + + if ((rh = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Z4 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Z6 = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * We have a curve defined by a Weierstrass equation y^2 = x^3 + a*x + * + b. The point to consider is given in Jacobian projective + * coordinates where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). + * Substituting this and multiplying by Z^6 transforms the above + * equation into Y^2 = X^3 + a*X*Z^4 + b*Z^6. To test this, we add up + * the right-hand side in 'rh'. + */ + + /* rh := X^2 */ + if (!field_sqr(group, rh, &point->X, ctx)) + goto err; + + if (!point->Z_is_one) { + if (!field_sqr(group, tmp, &point->Z, ctx)) + goto err; + if (!field_sqr(group, Z4, tmp, ctx)) + goto err; + if (!field_mul(group, Z6, Z4, tmp, ctx)) + goto err; + + /* rh := (rh + a*Z^4)*X */ + if (group->a_is_minus3) { + if (!BN_mod_lshift1_quick(tmp, Z4, p)) + goto err; + if (!BN_mod_add_quick(tmp, tmp, Z4, p)) + goto err; + if (!BN_mod_sub_quick(rh, rh, tmp, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + } else { + if (!field_mul(group, tmp, Z4, &group->a, ctx)) + goto err; + if (!BN_mod_add_quick(rh, rh, tmp, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + } + + /* rh := rh + b*Z^6 */ + if (!field_mul(group, tmp, &group->b, Z6, ctx)) + goto err; + if (!BN_mod_add_quick(rh, rh, tmp, p)) + goto err; + } else { + /* point->Z_is_one */ + + /* rh := (rh + a)*X */ + if (!BN_mod_add_quick(rh, rh, &group->a, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + /* rh := rh + b */ + if (!BN_mod_add_quick(rh, rh, &group->b, p)) + goto err; + } + + /* 'lh' := Y^2 */ + if (!field_sqr(group, tmp, &point->Y, ctx)) + goto err; + + ret = (0 == BN_ucmp(tmp, rh)); + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) +{ + /* + * return values: -1 error 0 equal (in affine coordinates) 1 + * not equal + */ + + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + BIGNUM *tmp1, *tmp2, *Za23, *Zb23; + const BIGNUM *tmp1_, *tmp2_; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, a) > 0) + return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1; + + if (EC_POINT_is_at_infinity(group, b) > 0) + return 1; + + if (a->Z_is_one && b->Z_is_one) + return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + + BN_CTX_start(ctx); + + if ((tmp1 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((tmp2 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((Za23 = BN_CTX_get(ctx)) == NULL) + goto end; + if ((Zb23 = BN_CTX_get(ctx)) == NULL) + goto end; + + /* + * We have to decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, + * Y_b/Z_b^3), or equivalently, whether (X_a*Z_b^2, Y_a*Z_b^3) = + * (X_b*Z_a^2, Y_b*Z_a^3). + */ + + if (!b->Z_is_one) { + if (!field_sqr(group, Zb23, &b->Z, ctx)) + goto end; + if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) + goto end; + tmp1_ = tmp1; + } else + tmp1_ = &a->X; + if (!a->Z_is_one) { + if (!field_sqr(group, Za23, &a->Z, ctx)) + goto end; + if (!field_mul(group, tmp2, &b->X, Za23, ctx)) + goto end; + tmp2_ = tmp2; + } else + tmp2_ = &b->X; + + /* compare X_a*Z_b^2 with X_b*Z_a^2 */ + if (BN_cmp(tmp1_, tmp2_) != 0) { + ret = 1; /* points differ */ + goto end; + } + if (!b->Z_is_one) { + if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) + goto end; + if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) + goto end; + /* tmp1_ = tmp1 */ + } else + tmp1_ = &a->Y; + if (!a->Z_is_one) { + if (!field_mul(group, Za23, Za23, &a->Z, ctx)) + goto end; + if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) + goto end; + /* tmp2_ = tmp2 */ + } else + tmp2_ = &b->Y; + + /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ + if (BN_cmp(tmp1_, tmp2_) != 0) { + ret = 1; /* points differ */ + goto end; + } + /* points are equal */ + ret = 0; + + end: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + BIGNUM *x, *y; + int ret = 0; + + if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0) + return 1; + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + if ((y = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx)) + goto err; + if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) + goto err; + if (!point->Z_is_one) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +int +ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) +{ + BIGNUM *tmp0, *tmp1; + size_t pow2 = 0; + BIGNUM **heap = NULL; + size_t i; + int ret = 0; + + if (num == 0) + return 1; + + BN_CTX_start(ctx); + + if ((tmp0 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp1 = BN_CTX_get(ctx)) == NULL) + goto err; + + /* + * Before converting the individual points, compute inverses of all Z + * values. Modular inversion is rather slow, but luckily we can do + * with a single explicit inversion, plus about 3 multiplications per + * input value. + */ + + pow2 = 1; + while (num > pow2) + pow2 <<= 1; + /* + * Now pow2 is the smallest power of 2 satifsying pow2 >= num. We + * need twice that. + */ + pow2 <<= 1; + + heap = reallocarray(NULL, pow2, sizeof heap[0]); + if (heap == NULL) + goto err; + + /* + * The array is used as a binary tree, exactly as in heapsort: + * + * heap[1] heap[2] heap[3] heap[4] heap[5] + * heap[6] heap[7] heap[8]heap[9] heap[10]heap[11] + * heap[12]heap[13] heap[14] heap[15] + * + * We put the Z's in the last line; then we set each other node to the + * product of its two child-nodes (where empty or 0 entries are + * treated as ones); then we invert heap[1]; then we invert each + * other node by replacing it by the product of its parent (after + * inversion) and its sibling (before inversion). + */ + heap[0] = NULL; + for (i = pow2 / 2 - 1; i > 0; i--) + heap[i] = NULL; + for (i = 0; i < num; i++) + heap[pow2 / 2 + i] = &points[i]->Z; + for (i = pow2 / 2 + num; i < pow2; i++) + heap[i] = NULL; + + /* set each node to the product of its children */ + for (i = pow2 / 2 - 1; i > 0; i--) { + heap[i] = BN_new(); + if (heap[i] == NULL) + goto err; + + if (heap[2 * i] != NULL) { + if ((heap[2 * i + 1] == NULL) || BN_is_zero(heap[2 * i + 1])) { + if (!bn_copy(heap[i], heap[2 * i])) + goto err; + } else { + if (BN_is_zero(heap[2 * i])) { + if (!bn_copy(heap[i], heap[2 * i + 1])) + goto err; + } else { + if (!group->meth->field_mul(group, heap[i], + heap[2 * i], heap[2 * i + 1], ctx)) + goto err; + } + } + } + } + + /* invert heap[1] */ + if (!BN_is_zero(heap[1])) { + if (BN_mod_inverse_ct(heap[1], heap[1], &group->field, ctx) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + } + if (group->meth->field_encode != NULL) { + /* + * in the Montgomery case, we just turned R*H (representing + * H) into 1/(R*H), but we need R*(1/H) (representing + * 1/H); i.e. we have need to multiply by the Montgomery + * factor twice + */ + if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) + goto err; + if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) + goto err; + } + /* set other heap[i]'s to their inverses */ + for (i = 2; i < pow2 / 2 + num; i += 2) { + /* i is even */ + if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) { + if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx)) + goto err; + if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx)) + goto err; + if (!bn_copy(heap[i], tmp0)) + goto err; + if (!bn_copy(heap[i + 1], tmp1)) + goto err; + } else { + if (!bn_copy(heap[i], heap[i / 2])) + goto err; + } + } + + /* + * we have replaced all non-zero Z's by their inverses, now fix up + * all the points + */ + for (i = 0; i < num; i++) { + EC_POINT *p = points[i]; + + if (!BN_is_zero(&p->Z)) { + /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ + + if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) + goto err; + if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) + goto err; + + if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) + goto err; + if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) + goto err; + + if (group->meth->field_set_to_one != NULL) { + if (!group->meth->field_set_to_one(group, &p->Z, ctx)) + goto err; + } else { + if (!BN_one(&p->Z)) + goto err; + } + p->Z_is_one = 1; + } + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + if (heap != NULL) { + /* + * heap[pow2/2] .. heap[pow2-1] have not been allocated + * locally! + */ + for (i = pow2 / 2 - 1; i > 0; i--) { + BN_free(heap[i]); + } + free(heap); + } + return ret; +} + +int +ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + return BN_mod_mul(r, a, b, &group->field, ctx); +} + +int +ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ + return BN_mod_sqr(r, a, &group->field, ctx); +} + +/* + * Apply randomization of EC point projective coordinates: + * + * (X, Y, Z) = (lambda^2 * X, lambda^3 * Y, lambda * Z) + * + * where lambda is in the interval [1, group->field). + */ +int +ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) +{ + BIGNUM *lambda = NULL; + BIGNUM *tmp = NULL; + int ret = 0; + + BN_CTX_start(ctx); + if ((lambda = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Generate lambda in [1, group->field). */ + if (!bn_rand_interval(lambda, 1, &group->field)) + goto err; + + if (group->meth->field_encode != NULL && + !group->meth->field_encode(group, lambda, lambda, ctx)) + goto err; + + /* Z = lambda * Z */ + if (!group->meth->field_mul(group, &p->Z, lambda, &p->Z, ctx)) + goto err; + + /* tmp = lambda^2 */ + if (!group->meth->field_sqr(group, tmp, lambda, ctx)) + goto err; + + /* X = lambda^2 * X */ + if (!group->meth->field_mul(group, &p->X, tmp, &p->X, ctx)) + goto err; + + /* tmp = lambda^3 */ + if (!group->meth->field_mul(group, tmp, tmp, lambda, ctx)) + goto err; + + /* Y = lambda^3 * Y */ + if (!group->meth->field_mul(group, &p->Y, tmp, &p->Y, ctx)) + goto err; + + /* Disable optimized arithmetics after replacing Z by lambda * Z. */ + p->Z_is_one = 0; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +#define EC_POINT_BN_set_flags(P, flags) do { \ + BN_set_flags(&(P)->X, (flags)); \ + BN_set_flags(&(P)->Y, (flags)); \ + BN_set_flags(&(P)->Z, (flags)); \ +} while(0) + +#define EC_POINT_CSWAP(c, a, b, w, t) do { \ + if (!BN_swap_ct(c, &(a)->X, &(b)->X, w) || \ + !BN_swap_ct(c, &(a)->Y, &(b)->Y, w) || \ + !BN_swap_ct(c, &(a)->Z, &(b)->Z, w)) \ + goto err; \ + t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ + (a)->Z_is_one ^= (t); \ + (b)->Z_is_one ^= (t); \ +} while(0) + +/* + * This function computes (in constant time) a point multiplication over the + * EC group. + * + * At a high level, it is Montgomery ladder with conditional swaps. + * + * It performs either a fixed point multiplication + * (scalar * generator) + * when point is NULL, or a variable point multiplication + * (scalar * point) + * when point is not NULL. + * + * scalar should be in the range [0,n) otherwise all constant time bets are off. + * + * NB: This says nothing about EC_POINT_add and EC_POINT_dbl, + * which of course are not constant time themselves. + * + * The product is stored in r. + * + * Returns 1 on success, 0 otherwise. + */ +static int +ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + const EC_POINT *point, BN_CTX *ctx) +{ + int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; + EC_POINT *s = NULL; + BIGNUM *k = NULL; + BIGNUM *lambda = NULL; + BIGNUM *cardinality = NULL; + int ret = 0; + + BN_CTX_start(ctx); + + if ((s = EC_POINT_new(group)) == NULL) + goto err; + + if (point == NULL) { + if (!EC_POINT_copy(s, group->generator)) + goto err; + } else { + if (!EC_POINT_copy(s, point)) + goto err; + } + + EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); + + if ((cardinality = BN_CTX_get(ctx)) == NULL) + goto err; + if ((lambda = BN_CTX_get(ctx)) == NULL) + goto err; + if ((k = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_mul(cardinality, &group->order, &group->cofactor, ctx)) + goto err; + + /* + * Group cardinalities are often on a word boundary. + * So when we pad the scalar, some timing diff might + * pop if it needs to be expanded due to carries. + * So expand ahead of time. + */ + cardinality_bits = BN_num_bits(cardinality); + group_top = cardinality->top; + if (!bn_wexpand(k, group_top + 2) || + !bn_wexpand(lambda, group_top + 2)) + goto err; + + if (!bn_copy(k, scalar)) + goto err; + + BN_set_flags(k, BN_FLG_CONSTTIME); + + if (BN_num_bits(k) > cardinality_bits || BN_is_negative(k)) { + /* + * This is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(k, k, cardinality, ctx)) + goto err; + } + + if (!BN_add(lambda, k, cardinality)) + goto err; + BN_set_flags(lambda, BN_FLG_CONSTTIME); + if (!BN_add(k, lambda, cardinality)) + goto err; + /* + * lambda := scalar + cardinality + * k := scalar + 2*cardinality + */ + kbit = BN_is_bit_set(lambda, cardinality_bits); + if (!BN_swap_ct(kbit, k, lambda, group_top + 2)) + goto err; + + group_top = group->field.top; + if (!bn_wexpand(&s->X, group_top) || + !bn_wexpand(&s->Y, group_top) || + !bn_wexpand(&s->Z, group_top) || + !bn_wexpand(&r->X, group_top) || + !bn_wexpand(&r->Y, group_top) || + !bn_wexpand(&r->Z, group_top)) + goto err; + + /* + * Apply coordinate blinding for EC_POINT if the underlying EC_METHOD + * implements it. + */ + if (!ec_point_blind_coordinates(group, s, ctx)) + goto err; + + /* top bit is a 1, in a fixed pos */ + if (!EC_POINT_copy(r, s)) + goto err; + + EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME); + + if (!EC_POINT_dbl(group, s, s, ctx)) + goto err; + + pbit = 0; + + /* + * The ladder step, with branches, is + * + * k[i] == 0: S = add(R, S), R = dbl(R) + * k[i] == 1: R = add(S, R), S = dbl(S) + * + * Swapping R, S conditionally on k[i] leaves you with state + * + * k[i] == 0: T, U = R, S + * k[i] == 1: T, U = S, R + * + * Then perform the ECC ops. + * + * U = add(T, U) + * T = dbl(T) + * + * Which leaves you with state + * + * k[i] == 0: U = add(R, S), T = dbl(R) + * k[i] == 1: U = add(S, R), T = dbl(S) + * + * Swapping T, U conditionally on k[i] leaves you with state + * + * k[i] == 0: R, S = T, U + * k[i] == 1: R, S = U, T + * + * Which leaves you with state + * + * k[i] == 0: S = add(R, S), R = dbl(R) + * k[i] == 1: R = add(S, R), S = dbl(S) + * + * So we get the same logic, but instead of a branch it's a + * conditional swap, followed by ECC ops, then another conditional swap. + * + * Optimization: The end of iteration i and start of i-1 looks like + * + * ... + * CSWAP(k[i], R, S) + * ECC + * CSWAP(k[i], R, S) + * (next iteration) + * CSWAP(k[i-1], R, S) + * ECC + * CSWAP(k[i-1], R, S) + * ... + * + * So instead of two contiguous swaps, you can merge the condition + * bits and do a single swap. + * + * k[i] k[i-1] Outcome + * 0 0 No Swap + * 0 1 Swap + * 1 0 Swap + * 1 1 No Swap + * + * This is XOR. pbit tracks the previous bit of k. + */ + + for (i = cardinality_bits - 1; i >= 0; i--) { + kbit = BN_is_bit_set(k, i) ^ pbit; + EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one); + if (!EC_POINT_add(group, s, r, s, ctx)) + goto err; + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + /* + * pbit logic merges this cswap with that of the + * next iteration + */ + pbit ^= kbit; + } + /* one final cswap to move the right value into r */ + EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one); + + ret = 1; + + err: + EC_POINT_free(s); + BN_CTX_end(ctx); + + return ret; +} + +#undef EC_POINT_BN_set_flags +#undef EC_POINT_CSWAP + +int +ec_GFp_simple_mul_generator_ct(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, BN_CTX *ctx) +{ + return ec_GFp_simple_mul_ct(group, r, scalar, NULL, ctx); +} + +int +ec_GFp_simple_mul_single_ct(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) +{ + return ec_GFp_simple_mul_ct(group, r, scalar, point, ctx); +} + +int +ec_GFp_simple_mul_double_nonct(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *g_scalar, const BIGNUM *p_scalar, const EC_POINT *point, + BN_CTX *ctx) +{ + return ec_wNAF_mul(group, r, g_scalar, 1, &point, &p_scalar, ctx); +} + +static const EC_METHOD ec_GFp_simple_method = { + .field_type = NID_X9_62_prime_field, + .group_init = ec_GFp_simple_group_init, + .group_finish = ec_GFp_simple_group_finish, + .group_copy = ec_GFp_simple_group_copy, + .group_set_curve = ec_GFp_simple_group_set_curve, + .group_get_curve = ec_GFp_simple_group_get_curve, + .group_get_degree = ec_GFp_simple_group_get_degree, + .group_order_bits = ec_group_simple_order_bits, + .group_check_discriminant = ec_GFp_simple_group_check_discriminant, + .point_init = ec_GFp_simple_point_init, + .point_finish = ec_GFp_simple_point_finish, + .point_copy = ec_GFp_simple_point_copy, + .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity, + .point_set_Jprojective_coordinates = + ec_GFp_simple_set_Jprojective_coordinates, + .point_get_Jprojective_coordinates = + ec_GFp_simple_get_Jprojective_coordinates, + .point_set_affine_coordinates = + ec_GFp_simple_point_set_affine_coordinates, + .point_get_affine_coordinates = + ec_GFp_simple_point_get_affine_coordinates, + .point_set_compressed_coordinates = + ec_GFp_simple_set_compressed_coordinates, + .point2oct = ec_GFp_simple_point2oct, + .oct2point = ec_GFp_simple_oct2point, + .add = ec_GFp_simple_add, + .dbl = ec_GFp_simple_dbl, + .invert = ec_GFp_simple_invert, + .is_at_infinity = ec_GFp_simple_is_at_infinity, + .is_on_curve = ec_GFp_simple_is_on_curve, + .point_cmp = ec_GFp_simple_cmp, + .make_affine = ec_GFp_simple_make_affine, + .points_make_affine = ec_GFp_simple_points_make_affine, + .mul_generator_ct = ec_GFp_simple_mul_generator_ct, + .mul_single_ct = ec_GFp_simple_mul_single_ct, + .mul_double_nonct = ec_GFp_simple_mul_double_nonct, + .field_mul = ec_GFp_simple_field_mul, + .field_sqr = ec_GFp_simple_field_sqr, + .blind_coordinates = ec_GFp_simple_blind_coordinates, +}; + +const EC_METHOD * +EC_GFp_simple_method(void) +{ + return &ec_GFp_simple_method; +} +LCRYPTO_ALIAS(EC_GFp_simple_method); diff --git a/Libraries/libressl/crypto/ec/ecx_methods.c b/Libraries/libressl/crypto/ec/ecx_methods.c new file mode 100644 index 000000000..4bb8b786a --- /dev/null +++ b/Libraries/libressl/crypto/ec/ecx_methods.c @@ -0,0 +1,897 @@ +/* $OpenBSD: ecx_methods.c,v 1.9 2023/07/22 19:33:25 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "bytestring.h" +#include "curve25519_internal.h" +#include "evp_local.h" + +/* + * EVP PKEY and PKEY ASN.1 methods Ed25519 and X25519. + * + * RFC 7748 - Elliptic Curves for Security. + * RFC 8032 - Edwards-Curve Digital Signature Algorithm (EdDSA). + */ + +#define ED25519_BITS 253 +#define ED25519_SECURITY_BITS 128 +#define ED25519_SIG_SIZE 64 + +#define X25519_BITS 253 +#define X25519_SECURITY_BITS 128 + +static int +ecx_key_len(int nid) +{ + switch (nid) { + case NID_ED25519: + return ED25519_KEYLEN; + case NID_X25519: + return X25519_KEYLEN; + } + + return 0; +} + +static struct ecx_key_st * +ecx_key_new(int nid) +{ + struct ecx_key_st *ecx_key; + int key_len; + + if ((key_len = ecx_key_len(nid)) == 0) + return NULL; + + if ((ecx_key = calloc(1, sizeof(*ecx_key))) == NULL) + return NULL; + + ecx_key->nid = nid; + ecx_key->key_len = key_len; + + return ecx_key; +} + +static void +ecx_key_clear(struct ecx_key_st *ecx_key) +{ + freezero(ecx_key->priv_key, ecx_key->priv_key_len); + ecx_key->priv_key = NULL; + ecx_key->priv_key_len = 0; + + freezero(ecx_key->pub_key, ecx_key->pub_key_len); + ecx_key->pub_key = NULL; + ecx_key->pub_key_len = 0; +} + +static void +ecx_key_free(struct ecx_key_st *ecx_key) +{ + if (ecx_key == NULL) + return; + + ecx_key_clear(ecx_key); + + freezero(ecx_key, sizeof(*ecx_key)); +} + +static int +ecx_key_generate(struct ecx_key_st *ecx_key) +{ + uint8_t *pub_key = NULL, *priv_key = NULL; + int ret = 0; + + ecx_key_clear(ecx_key); + + if ((pub_key = calloc(1, ecx_key->key_len)) == NULL) + goto err; + if ((priv_key = calloc(1, ecx_key->key_len)) == NULL) + goto err; + + switch (ecx_key->nid) { + case NID_ED25519: + ED25519_keypair(pub_key, priv_key); + break; + case NID_X25519: + X25519_keypair(pub_key, priv_key); + break; + default: + goto err; + } + + ecx_key->priv_key = priv_key; + ecx_key->priv_key_len = ecx_key->key_len; + priv_key = NULL; + + ecx_key->pub_key = pub_key; + ecx_key->pub_key_len = ecx_key->key_len; + pub_key = NULL; + + ret = 1; + + err: + freezero(pub_key, ecx_key->key_len); + freezero(priv_key, ecx_key->key_len); + + return ret; +} + +static int +ecx_key_set_priv(struct ecx_key_st *ecx_key, const uint8_t *priv_key, + size_t priv_key_len) +{ + uint8_t *pub_key = NULL; + CBS cbs; + + ecx_key_clear(ecx_key); + + if (priv_key_len != ecx_key->key_len) + goto err; + + if ((pub_key = calloc(1, ecx_key->key_len)) == NULL) + goto err; + + switch (ecx_key->nid) { + case NID_ED25519: + ED25519_public_from_private(pub_key, priv_key); + break; + case NID_X25519: + X25519_public_from_private(pub_key, priv_key); + break; + default: + goto err; + } + + CBS_init(&cbs, priv_key, priv_key_len); + if (!CBS_stow(&cbs, &ecx_key->priv_key, &ecx_key->priv_key_len)) + goto err; + + ecx_key->pub_key = pub_key; + ecx_key->pub_key_len = ecx_key->key_len; + pub_key = NULL; + + err: + freezero(pub_key, ecx_key->key_len); + + return 1; +} + +static int +ecx_key_set_pub(struct ecx_key_st *ecx_key, const uint8_t *pub_key, + size_t pub_key_len) +{ + CBS cbs; + + ecx_key_clear(ecx_key); + + if (pub_key_len != ecx_key->key_len) + return 0; + + CBS_init(&cbs, pub_key, pub_key_len); + if (!CBS_stow(&cbs, &ecx_key->pub_key, &ecx_key->pub_key_len)) + return 0; + + return 1; +} + +static int +ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *xpubkey) +{ + struct ecx_key_st *ecx_key = NULL; + X509_ALGOR *algor; + int algor_type; + const uint8_t *param; + int param_len; + int ret = 0; + + if (!X509_PUBKEY_get0_param(NULL, ¶m, ¶m_len, &algor, xpubkey)) + goto err; + + /* Ensure that parameters have not been specified in the encoding. */ + if (algor != NULL) { + X509_ALGOR_get0(NULL, &algor_type, NULL, algor); + if (algor_type != V_ASN1_UNDEF) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + } + + if (param == NULL || param_len != ecx_key_len(pkey->ameth->pkey_id)) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + + if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) + goto err; + if (!ecx_key_set_pub(ecx_key, param, param_len)) + goto err; + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) + goto err; + ecx_key = NULL; + + ret = 1; + + err: + ecx_key_free(ecx_key); + + return ret; +} + +static int +ecx_pub_encode(X509_PUBKEY *xpubkey, const EVP_PKEY *pkey) +{ + const struct ecx_key_st *ecx_key = pkey->pkey.ecx; + uint8_t *pub_key = NULL; + size_t pub_key_len = 0; + ASN1_OBJECT *aobj; + CBS cbs; + int ret = 0; + + if (ecx_key == NULL) { + ECerror(EC_R_INVALID_KEY); + goto err; + } + + if (ecx_key->pub_key_len != ecx_key->key_len) + goto err; + + if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL) + goto err; + + CBS_init(&cbs, ecx_key->pub_key, ecx_key->pub_key_len); + if (!CBS_stow(&cbs, &pub_key, &pub_key_len)) + goto err; + + if (!X509_PUBKEY_set0_param(xpubkey, aobj, V_ASN1_UNDEF, NULL, + pub_key, pub_key_len)) + goto err; + + pub_key = NULL; + pub_key_len = 0; + + ret = 1; + + err: + free(pub_key); + + return ret; +} + +static int +ecx_pub_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2) +{ + if (pkey1->pkey.ecx == NULL || pkey1->pkey.ecx->pub_key == NULL) + return -2; + if (pkey2->pkey.ecx == NULL || pkey2->pkey.ecx->pub_key == NULL) + return -2; + if (pkey1->pkey.ecx->pub_key_len != pkey2->pkey.ecx->pub_key_len) + return -2; + + return timingsafe_memcmp(pkey1->pkey.ecx->pub_key, pkey2->pkey.ecx->pub_key, + pkey1->pkey.ecx->pub_key_len) == 0; +} + +/* Reimplementation of ASN1_buf_print() that adds a secondary indent of 4. */ +static int +ecx_buf_print(BIO *bio, const uint8_t *buf, size_t buf_len, int indent) +{ + uint8_t u8; + size_t octets = 0; + const char *sep = ":", *nl = ""; + CBS cbs; + + if (indent > 60) + indent = 60; + indent += 4; + if (indent < 0) + indent = 0; + + CBS_init(&cbs, buf, buf_len); + while (CBS_len(&cbs) > 0) { + if (!CBS_get_u8(&cbs, &u8)) + return 0; + if (octets++ % 15 == 0) { + if (BIO_printf(bio, "%s%*s", nl, indent, "") < 0) + return 0; + nl = "\n"; + } + if (CBS_len(&cbs) == 0) + sep = ""; + if (BIO_printf(bio, "%02x%s", u8, sep) <= 0) + return 0; + } + + if (BIO_printf(bio, "\n") <= 0) + return 0; + + return 1; +} + +static int +ecx_pub_print(BIO *bio, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + struct ecx_key_st *ecx_key = pkey->pkey.ecx; + const char *name; + + if ((name = OBJ_nid2ln(pkey->ameth->pkey_id)) == NULL) + return 0; + + if (ecx_key == NULL || ecx_key->pub_key == NULL) + return BIO_printf(bio, "%*s\n", + indent, "") > 0; + + if (BIO_printf(bio, "%*s%s Public-Key:\n", indent, "", name) <= 0) + return 0; + if (BIO_printf(bio, "%*spub:\n", indent, "") <= 0) + return 0; + if (!ecx_buf_print(bio, ecx_key->pub_key, ecx_key->pub_key_len, indent)) + return 0; + + return 1; +} + +static int +ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8pki) +{ + struct ecx_key_st *ecx_key = NULL; + ASN1_OCTET_STRING *aos = NULL; + const X509_ALGOR *algor; + int algor_type; + const uint8_t *param; + int param_len; + int ret = 0; + + if (!PKCS8_pkey_get0(NULL, ¶m, ¶m_len, &algor, p8pki)) + goto err; + if ((aos = d2i_ASN1_OCTET_STRING(NULL, ¶m, param_len)) == NULL) + goto err; + + /* Ensure that parameters have not been specified in the encoding. */ + if (algor != NULL) { + X509_ALGOR_get0(NULL, &algor_type, NULL, algor); + if (algor_type != V_ASN1_UNDEF) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + } + + if (ASN1_STRING_get0_data(aos) == NULL || + ASN1_STRING_length(aos) != ecx_key_len(pkey->ameth->pkey_id)) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + + if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) + goto err; + if (!ecx_key_set_priv(ecx_key, ASN1_STRING_get0_data(aos), + ASN1_STRING_length(aos))) + goto err; + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) + goto err; + ecx_key = NULL; + + ret = 1; + + err: + ASN1_OCTET_STRING_free(aos); + ecx_key_free(ecx_key); + + return ret; +} + +static int +ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8pki, const EVP_PKEY *pkey) +{ + struct ecx_key_st *ecx_key = pkey->pkey.ecx; + ASN1_OCTET_STRING *aos = NULL; + ASN1_OBJECT *aobj; + uint8_t *der = NULL; + int der_len = 0; + int ret = 0; + + if (ecx_key == NULL || ecx_key->priv_key == NULL) { + ECerror(EC_R_INVALID_PRIVATE_KEY); + goto err; + } + + if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL) + goto err; + + if ((aos = ASN1_OCTET_STRING_new()) == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(aos, ecx_key->priv_key, + ecx_key->priv_key_len)) + goto err; + if ((der_len = i2d_ASN1_OCTET_STRING(aos, &der)) < 0) + goto err; + if (!PKCS8_pkey_set0(p8pki, aobj, 0, V_ASN1_UNDEF, NULL, der, der_len)) + goto err; + + der = NULL; + der_len = 0; + + ret = 1; + + err: + freezero(der, der_len); + ASN1_OCTET_STRING_free(aos); + + return ret; +} + +static int +ecx_priv_print(BIO *bio, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + struct ecx_key_st *ecx_key = pkey->pkey.ecx; + const char *name; + + if ((name = OBJ_nid2ln(pkey->ameth->pkey_id)) == NULL) + return 0; + + if (ecx_key == NULL || ecx_key->priv_key == NULL) + return BIO_printf(bio, "%*s\n", + indent, "") > 0; + + if (BIO_printf(bio, "%*s%s Private-Key:\n", indent, "", name) <= 0) + return 0; + if (BIO_printf(bio, "%*spriv:\n", indent, "") <= 0) + return 0; + if (!ecx_buf_print(bio, ecx_key->priv_key, ecx_key->priv_key_len, indent)) + return 0; + if (BIO_printf(bio, "%*spub:\n", indent, "") <= 0) + return 0; + if (!ecx_buf_print(bio, ecx_key->pub_key, ecx_key->pub_key_len, indent)) + return 0; + + return 1; +} + +static int +ecx_size(const EVP_PKEY *pkey) +{ + return ecx_key_len(pkey->ameth->pkey_id); +} + +static int +ecx_sig_size(const EVP_PKEY *pkey) +{ + switch (pkey->ameth->pkey_id) { + case EVP_PKEY_ED25519: + return ED25519_SIG_SIZE; + } + return 0; +} + +static int +ecx_bits(const EVP_PKEY *pkey) +{ + switch (pkey->ameth->pkey_id) { + case EVP_PKEY_ED25519: + return ED25519_BITS; + case EVP_PKEY_X25519: + return X25519_BITS; + } + return 0; +} + +static int +ecx_security_bits(const EVP_PKEY *pkey) +{ + switch (pkey->ameth->pkey_id) { + case EVP_PKEY_ED25519: + return ED25519_SECURITY_BITS; + case EVP_PKEY_X25519: + return X25519_SECURITY_BITS; + } + return 0; +} + +static int +ecx_param_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2) +{ + /* No parameters, so always equivalent. */ + return 1; +} + +static void +ecx_free(EVP_PKEY *pkey) +{ + struct ecx_key_st *ecx_key = pkey->pkey.ecx; + + ecx_key_free(ecx_key); +} + +static int +ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + /* Not supported. */ + return -2; +} + +static int +ecx_sign_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + /* PureEdDSA does its own hashing. */ + *(int *)arg2 = NID_undef; + return 2; + } + return -2; +} + +static int +ecx_set_priv_key(EVP_PKEY *pkey, const uint8_t *priv, size_t len) +{ + struct ecx_key_st *ecx_key = NULL; + int ret = 0; + + if (priv == NULL || len != ecx_key_len(pkey->ameth->pkey_id)) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + + if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) + goto err; + if (!ecx_key_set_priv(ecx_key, priv, len)) + goto err; + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) + goto err; + ecx_key = NULL; + + ret = 1; + + err: + ecx_key_free(ecx_key); + + return ret; +} + +static int +ecx_set_pub_key(EVP_PKEY *pkey, const uint8_t *pub, size_t len) +{ + struct ecx_key_st *ecx_key = NULL; + int ret = 0; + + if (pub == NULL || len != ecx_key_len(pkey->ameth->pkey_id)) { + ECerror(EC_R_INVALID_ENCODING); + goto err; + } + + if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) + goto err; + if (!ecx_key_set_pub(ecx_key, pub, len)) + goto err; + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) + goto err; + ecx_key = NULL; + + ret = 1; + + err: + ecx_key_free(ecx_key); + + return ret; +} + +static int +ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *out_priv, size_t *out_len) +{ + struct ecx_key_st *ecx_key = pkey->pkey.ecx; + CBS cbs; + + if (out_priv == NULL) { + *out_len = ecx_key_len(pkey->ameth->pkey_id); + return 1; + } + + if (ecx_key == NULL || ecx_key->priv_key == NULL) + return 0; + + CBS_init(&cbs, ecx_key->priv_key, ecx_key->priv_key_len); + if (!CBS_write_bytes(&cbs, out_priv, *out_len, out_len)) + return 0; + + return 1; +} + +static int +ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *out_pub, size_t *out_len) +{ + struct ecx_key_st *ecx_key = pkey->pkey.ecx; + CBS cbs; + + if (out_pub == NULL) { + *out_len = ecx_key_len(pkey->ameth->pkey_id); + return 1; + } + + if (ecx_key == NULL || ecx_key->pub_key == NULL) + return 0; + + CBS_init(&cbs, ecx_key->pub_key, ecx_key->pub_key_len); + if (!CBS_write_bytes(&cbs, out_pub, *out_len, out_len)) + return 0; + + return 1; +} + +static int +pkey_ecx_keygen(EVP_PKEY_CTX *pkey_ctx, EVP_PKEY *pkey) +{ + struct ecx_key_st *ecx_key = NULL; + int ret = 0; + + if ((ecx_key = ecx_key_new(pkey_ctx->pmeth->pkey_id)) == NULL) + goto err; + if (!ecx_key_generate(ecx_key)) + goto err; + if (!EVP_PKEY_assign(pkey, pkey_ctx->pmeth->pkey_id, ecx_key)) + goto err; + ecx_key = NULL; + + ret = 1; + + err: + ecx_key_free(ecx_key); + + return ret; +} + +static int +pkey_ecx_derive(EVP_PKEY_CTX *pkey_ctx, unsigned char *out_key, + size_t *out_key_len) +{ + struct ecx_key_st *ecx_key, *ecx_peer_key; + + if (pkey_ctx->pkey == NULL || pkey_ctx->peerkey == NULL) { + ECerror(EC_R_KEYS_NOT_SET); + return 0; + } + + if ((ecx_key = pkey_ctx->pkey->pkey.ecx) == NULL) { + ECerror(EC_R_INVALID_PRIVATE_KEY); + return 0; + } + if (ecx_key->priv_key == NULL) { + ECerror(EC_R_INVALID_PRIVATE_KEY); + return 0; + } + + if ((ecx_peer_key = pkey_ctx->peerkey->pkey.ecx) == NULL) { + ECerror(EC_R_INVALID_PEER_KEY); + return 0; + } + + if (out_key != NULL) { + if (!X25519(out_key, ecx_key->priv_key, ecx_peer_key->pub_key)) + return 0; + } + + *out_key_len = X25519_KEYLEN; + + return 1; +} + +static int +pkey_ecx_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2) +{ + if (op == EVP_PKEY_CTRL_PEER_KEY) + return 1; + + return -2; +} + +static int +ecx_item_verify(EVP_MD_CTX *md_ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *algor, ASN1_BIT_STRING *abs, EVP_PKEY *pkey) +{ + const ASN1_OBJECT *aobj; + int nid, param_type; + + X509_ALGOR_get0(&aobj, ¶m_type, NULL, algor); + + nid = OBJ_obj2nid(aobj); + + if (nid != NID_ED25519 || param_type != V_ASN1_UNDEF) { + ECerror(EC_R_INVALID_ENCODING); + return -1; + } + + if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey)) + return -1; + + return 2; +} + +static int +ecx_item_sign(EVP_MD_CTX *md_ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *abs) +{ + ASN1_OBJECT *aobj; + + if ((aobj = OBJ_nid2obj(NID_ED25519)) == NULL) + return 0; + + if (!X509_ALGOR_set0(algor1, aobj, V_ASN1_UNDEF, NULL)) + return 0; + + if (algor2 != NULL) { + if (!X509_ALGOR_set0(algor2, aobj, V_ASN1_UNDEF, NULL)) + return 0; + } + + /* Tell ASN1_item_sign_ctx() that identifiers are set and it needs to sign. */ + return 3; +} + +static int +pkey_ecx_digestsign(EVP_MD_CTX *md_ctx, unsigned char *out_sig, + size_t *out_sig_len, const unsigned char *message, size_t message_len) +{ + struct ecx_key_st *ecx_key; + EVP_PKEY_CTX *pkey_ctx; + + pkey_ctx = EVP_MD_CTX_pkey_ctx(md_ctx); + ecx_key = pkey_ctx->pkey->pkey.ecx; + + if (out_sig == NULL) { + *out_sig_len = ecx_sig_size(pkey_ctx->pkey); + return 1; + } + if (*out_sig_len < ecx_sig_size(pkey_ctx->pkey)) { + ECerror(EC_R_BUFFER_TOO_SMALL); + return 0; + } + + if (ecx_key == NULL) + return 0; + if (ecx_key->priv_key == NULL || ecx_key->pub_key == NULL) + return 0; + + if (!ED25519_sign(out_sig, message, message_len, ecx_key->pub_key, + ecx_key->priv_key)) + return 0; + + *out_sig_len = ecx_sig_size(pkey_ctx->pkey); + + return 1; +} + +static int +pkey_ecx_digestverify(EVP_MD_CTX *md_ctx, const unsigned char *sig, + size_t sig_len, const unsigned char *message, size_t message_len) +{ + struct ecx_key_st *ecx_key; + EVP_PKEY_CTX *pkey_ctx; + + pkey_ctx = EVP_MD_CTX_pkey_ctx(md_ctx); + ecx_key = pkey_ctx->pkey->pkey.ecx; + + if (ecx_key == NULL || ecx_key->pub_key == NULL) + return -1; + if (sig_len != ecx_sig_size(pkey_ctx->pkey)) + return -1; + + return ED25519_verify(message, message_len, sig, ecx_key->pub_key); +} + +static int +pkey_ecx_ed_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2) +{ + switch (op) { + case EVP_PKEY_CTRL_MD: + /* PureEdDSA does its own hashing. */ + if (arg2 != NULL && (const EVP_MD *)arg2 != EVP_md_null()) { + ECerror(EC_R_INVALID_DIGEST_TYPE); + return 0; + } + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + return 1; + } + return -2; +} + +const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { + .pkey_id = EVP_PKEY_X25519, + .pkey_base_id = EVP_PKEY_X25519, + .pkey_flags = 0, + .pem_str = "X25519", + .info = "OpenSSL X25519 algorithm", + + .pub_decode = ecx_pub_decode, + .pub_encode = ecx_pub_encode, + .pub_cmp = ecx_pub_cmp, + .pub_print = ecx_pub_print, + + .priv_decode = ecx_priv_decode, + .priv_encode = ecx_priv_encode, + .priv_print = ecx_priv_print, + + .pkey_size = ecx_size, + .pkey_bits = ecx_bits, + .pkey_security_bits = ecx_security_bits, + + .param_cmp = ecx_param_cmp, + + .pkey_free = ecx_free, + .pkey_ctrl = ecx_ctrl, + + .set_priv_key = ecx_set_priv_key, + .set_pub_key = ecx_set_pub_key, + .get_priv_key = ecx_get_priv_key, + .get_pub_key = ecx_get_pub_key, +}; + +const EVP_PKEY_METHOD x25519_pkey_meth = { + .pkey_id = EVP_PKEY_X25519, + .keygen = pkey_ecx_keygen, + .derive = pkey_ecx_derive, + .ctrl = pkey_ecx_ctrl, +}; + +const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { + .pkey_id = EVP_PKEY_ED25519, + .pkey_base_id = EVP_PKEY_ED25519, + .pkey_flags = 0, + .pem_str = "ED25519", + .info = "OpenSSL ED25519 algorithm", + + .pub_decode = ecx_pub_decode, + .pub_encode = ecx_pub_encode, + .pub_cmp = ecx_pub_cmp, + .pub_print = ecx_pub_print, + + .priv_decode = ecx_priv_decode, + .priv_encode = ecx_priv_encode, + .priv_print = ecx_priv_print, + + .pkey_size = ecx_sig_size, + .pkey_bits = ecx_bits, + .pkey_security_bits = ecx_security_bits, + + .param_cmp = ecx_param_cmp, + + .pkey_free = ecx_free, + .pkey_ctrl = ecx_sign_ctrl, + + .item_verify = ecx_item_verify, + .item_sign = ecx_item_sign, + + .set_priv_key = ecx_set_priv_key, + .set_pub_key = ecx_set_pub_key, + .get_priv_key = ecx_get_priv_key, + .get_pub_key = ecx_get_pub_key, +}; + +const EVP_PKEY_METHOD ed25519_pkey_meth = { + .pkey_id = EVP_PKEY_ED25519, + .flags = EVP_PKEY_FLAG_SIGCTX_CUSTOM, + .keygen = pkey_ecx_keygen, + .ctrl = pkey_ecx_ed_ctrl, + .digestsign = pkey_ecx_digestsign, + .digestverify = pkey_ecx_digestverify, +}; diff --git a/Libraries/libressl/crypto/ecdh/ecdh.c b/Libraries/libressl/crypto/ecdh/ecdh.c new file mode 100644 index 000000000..b0a8e60a2 --- /dev/null +++ b/Libraries/libressl/crypto/ecdh/ecdh.c @@ -0,0 +1,281 @@ +/* $OpenBSD: ecdh.c,v 1.10 2023/07/28 09:31:21 tb Exp $ */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "ec_local.h" + +/* + * Key derivation function from X9.63/SECG. + */ + +/* Way more than we will ever need */ +#define ECDH_KDF_MAX (1 << 30) + +int +ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, + size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md) +{ + EVP_MD_CTX *mctx = NULL; + unsigned int i; + size_t mdlen; + unsigned char ctr[4]; + int rv = 0; + + if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX || + Zlen > ECDH_KDF_MAX) + return 0; + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) + return 0; + mdlen = EVP_MD_size(md); + for (i = 1;; i++) { + unsigned char mtmp[EVP_MAX_MD_SIZE]; + if (!EVP_DigestInit_ex(mctx, md, NULL)) + goto err; + ctr[3] = i & 0xFF; + ctr[2] = (i >> 8) & 0xFF; + ctr[1] = (i >> 16) & 0xFF; + ctr[0] = (i >> 24) & 0xFF; + if (!EVP_DigestUpdate(mctx, Z, Zlen)) + goto err; + if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr))) + goto err; + if (!EVP_DigestUpdate(mctx, sinfo, sinfolen)) + goto err; + if (outlen >= mdlen) { + if (!EVP_DigestFinal(mctx, out, NULL)) + goto err; + outlen -= mdlen; + if (outlen == 0) + break; + out += mdlen; + } else { + if (!EVP_DigestFinal(mctx, mtmp, NULL)) + goto err; + memcpy(out, mtmp, outlen); + explicit_bzero(mtmp, mdlen); + break; + } + } + rv = 1; + + err: + EVP_MD_CTX_free(mctx); + + return rv; +} + +/* + * Based on the ECKAS-DH1 and ECSVDP-DH primitives in the IEEE 1363 standard. + */ +int +ecdh_compute_key(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, + const EC_KEY *ecdh) +{ + BN_CTX *ctx; + BIGNUM *x; + const BIGNUM *priv_key; + const EC_GROUP *group; + EC_POINT *point = NULL; + unsigned char *buf = NULL; + int buf_len = 0; + int ret = 0; + + *out = NULL; + *out_len = 0; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((group = EC_KEY_get0_group(ecdh)) == NULL) + goto err; + + if (EC_POINT_is_on_curve(group, pub_key, ctx) <= 0) + goto err; + + if ((point = EC_POINT_new(group)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((priv_key = EC_KEY_get0_private_key(ecdh)) == NULL) { + ECerror(EC_R_MISSING_PRIVATE_KEY); + goto err; + } + + if (!EC_POINT_mul(group, point, NULL, pub_key, priv_key, ctx)) { + ECerror(EC_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + if (!EC_POINT_get_affine_coordinates(group, point, x, NULL, ctx)) { + ECerror(EC_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + if ((buf_len = ECDH_size(ecdh)) < BN_num_bytes(x)) { + ECerror(ERR_R_INTERNAL_ERROR); + goto err; + } + if ((buf = calloc(1, buf_len)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (BN_bn2binpad(x, buf, buf_len) != buf_len) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + *out = buf; + *out_len = buf_len; + buf = NULL; + buf_len = 0; + + ret = 1; + + err: + EC_POINT_free(point); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + freezero(buf, buf_len); + + return ret; +} + +int +ECDH_compute_key(void *out, size_t out_len, const EC_POINT *pub_key, + EC_KEY *eckey, + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *out_len)) +{ + unsigned char *secret = NULL; + size_t secret_len = 0; + int ret = 0; + + if (eckey->meth->compute_key == NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + goto err; + } + + if (out_len > INT_MAX) { + ECerror(EC_R_INVALID_OUTPUT_LENGTH); + goto err; + } + + if (!eckey->meth->compute_key(&secret, &secret_len, pub_key, eckey)) + goto err; + + memset(out, 0, out_len); + if (KDF != NULL) { + if (KDF(secret, secret_len, out, &out_len) == NULL) { + ECerror(EC_R_KDF_FAILED); + goto err; + } + } else { + if (out_len < secret_len) { + /* The resulting key would be truncated. */ + ECerror(EC_R_KEY_TRUNCATION); + goto err; + } + out_len = secret_len; + memcpy(out, secret, out_len); + } + + if (out_len > INT_MAX) { + ECerror(EC_R_INVALID_OUTPUT_LENGTH); + goto err; + } + + ret = out_len; + + err: + freezero(secret, secret_len); + + return ret; +} +LCRYPTO_ALIAS(ECDH_compute_key); + +int +ECDH_size(const EC_KEY *d) +{ + return (EC_GROUP_get_degree(EC_KEY_get0_group(d)) + 7) / 8; +} +LCRYPTO_ALIAS(ECDH_size); diff --git a/Libraries/libressl/crypto/ecdsa/ecdsa.c b/Libraries/libressl/crypto/ecdsa/ecdsa.c new file mode 100644 index 000000000..52f504499 --- /dev/null +++ b/Libraries/libressl/crypto/ecdsa/ecdsa.c @@ -0,0 +1,774 @@ +/* $OpenBSD: ecdsa.c,v 1.18 2023/08/08 13:09:28 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "ec_local.h" +#include "ecdsa_local.h" + +static const ASN1_TEMPLATE ECDSA_SIG_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECDSA_SIG, r), + .field_name = "r", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ECDSA_SIG, s), + .field_name = "s", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM ECDSA_SIG_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ECDSA_SIG_seq_tt, + .tcount = sizeof(ECDSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ECDSA_SIG), + .sname = "ECDSA_SIG", +}; + +ECDSA_SIG * +d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len) +{ + return (ECDSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ECDSA_SIG_it); +} +LCRYPTO_ALIAS(d2i_ECDSA_SIG); + +int +i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECDSA_SIG_it); +} +LCRYPTO_ALIAS(i2d_ECDSA_SIG); + +ECDSA_SIG * +ECDSA_SIG_new(void) +{ + return (ECDSA_SIG *)ASN1_item_new(&ECDSA_SIG_it); +} +LCRYPTO_ALIAS(ECDSA_SIG_new); + +void +ECDSA_SIG_free(ECDSA_SIG *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ECDSA_SIG_it); +} +LCRYPTO_ALIAS(ECDSA_SIG_free); + +void +ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} +LCRYPTO_ALIAS(ECDSA_SIG_get0); + +const BIGNUM * +ECDSA_SIG_get0_r(const ECDSA_SIG *sig) +{ + return sig->r; +} +LCRYPTO_ALIAS(ECDSA_SIG_get0_r); + +const BIGNUM * +ECDSA_SIG_get0_s(const ECDSA_SIG *sig) +{ + return sig->s; +} +LCRYPTO_ALIAS(ECDSA_SIG_get0_s); + +int +ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + + BN_free(sig->r); + BN_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} +LCRYPTO_ALIAS(ECDSA_SIG_set0); + +int +ECDSA_size(const EC_KEY *key) +{ + const EC_GROUP *group; + const BIGNUM *order = NULL; + ECDSA_SIG sig; + int ret = 0; + + if (key == NULL) + goto err; + + if ((group = EC_KEY_get0_group(key)) == NULL) + goto err; + + if ((order = EC_GROUP_get0_order(group)) == NULL) + goto err; + + sig.r = (BIGNUM *)order; + sig.s = (BIGNUM *)order; + + if ((ret = i2d_ECDSA_SIG(&sig, NULL)) < 0) + ret = 0; + + err: + return ret; +} +LCRYPTO_ALIAS(ECDSA_size); + +/* + * FIPS 186-5, section 6.4.1, step 2: convert hashed message into an integer. + * Use the order_bits leftmost bits if it exceeds the group order. + */ +static int +ecdsa_prepare_digest(const unsigned char *digest, int digest_len, + const EC_KEY *key, BIGNUM *e) +{ + const EC_GROUP *group; + int digest_bits, order_bits; + + if (BN_bin2bn(digest, digest_len, e) == NULL) { + ECerror(ERR_R_BN_LIB); + return 0; + } + + if ((group = EC_KEY_get0_group(key)) == NULL) + return 0; + order_bits = EC_GROUP_order_bits(group); + + digest_bits = 8 * digest_len; + if (digest_bits <= order_bits) + return 1; + + return BN_rshift(e, e, digest_bits - order_bits); +} + +int +ecdsa_sign(int type, const unsigned char *digest, int digest_len, + unsigned char *signature, unsigned int *signature_len, const BIGNUM *kinv, + const BIGNUM *r, EC_KEY *key) +{ + ECDSA_SIG *sig = NULL; + int out_len = 0; + int ret = 0; + + if (kinv != NULL || r != NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + goto err; + } + + if ((sig = ECDSA_do_sign(digest, digest_len, key)) == NULL) + goto err; + + if ((out_len = i2d_ECDSA_SIG(sig, &signature)) < 0) { + out_len = 0; + goto err; + } + + ret = 1; + + err: + *signature_len = out_len; + ECDSA_SIG_free(sig); + + return ret; +} + +int +ECDSA_sign(int type, const unsigned char *digest, int digest_len, + unsigned char *signature, unsigned int *signature_len, EC_KEY *key) +{ + if (key->meth->sign == NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; + } + return key->meth->sign(type, digest, digest_len, signature, + signature_len, NULL, NULL, key); +} +LCRYPTO_ALIAS(ECDSA_sign); + +/* + * FIPS 186-5, section 6.4.1, steps 3-8 and 11: Generate k, calculate r and + * kinv. If r == 0, try again with a new random k. + */ + +int +ecdsa_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv, BIGNUM **out_r) +{ + const EC_GROUP *group; + EC_POINT *point = NULL; + BN_CTX *ctx = NULL; + BIGNUM *k = NULL, *r = NULL; + const BIGNUM *order; + BIGNUM *x; + int order_bits; + int ret = 0; + + BN_free(*out_kinv); + *out_kinv = NULL; + + BN_free(*out_r); + *out_r = NULL; + + if (key == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if ((group = EC_KEY_get0_group(key)) == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if ((k = BN_new()) == NULL) + goto err; + if ((r = BN_new()) == NULL) + goto err; + + if ((ctx = in_ctx) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((point = EC_POINT_new(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if ((order = EC_GROUP_get0_order(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + if (BN_cmp(order, BN_value_one()) <= 0) { + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + + /* Reject curves with an order that is smaller than 80 bits. */ + if ((order_bits = BN_num_bits(order)) < 80) { + ECerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + + /* Preallocate space. */ + if (!BN_set_bit(k, order_bits) || + !BN_set_bit(r, order_bits) || + !BN_set_bit(x, order_bits)) + goto err; + + /* Step 11: repeat until r != 0. */ + do { + /* Step 3: generate random k. */ + if (!bn_rand_interval(k, 1, order)) + goto err; + + /* Step 5: P = k * G. */ + if (!EC_POINT_mul(group, point, k, NULL, NULL, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* Steps 6 (and 7): from P = (x, y) retain the x-coordinate. */ + if (!EC_POINT_get_affine_coordinates(group, point, x, NULL, + ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* Step 8: r = x (mod order). */ + if (!BN_nnmod(r, x, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + } while (BN_is_zero(r)); + + /* Step 4: calculate kinv. */ + if (BN_mod_inverse_ct(k, k, order, ctx) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + *out_kinv = k; + k = NULL; + + *out_r = r; + r = NULL; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (ctx != in_ctx) + BN_CTX_free(ctx); + BN_free(k); + BN_free(r); + EC_POINT_free(point); + + return ret; +} + +static int +ECDSA_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv, + BIGNUM **out_r) +{ + if (key->meth->sign_setup == NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; + } + return key->meth->sign_setup(key, in_ctx, out_kinv, out_r); +} + +/* + * FIPS 186-5, section 6.4.1, step 9: compute s = inv(k)(e + xr) mod order. + * In order to reduce the possibility of a side-channel attack, the following + * is calculated using a random blinding value b in [1, order): + * s = inv(b)(be + bxr)inv(k) mod order. + */ + +static int +ecdsa_compute_s(BIGNUM **out_s, const BIGNUM *e, const BIGNUM *kinv, + const BIGNUM *r, const EC_KEY *key, BN_CTX *ctx) +{ + const EC_GROUP *group; + const BIGNUM *order, *priv_key; + BIGNUM *b, *binv, *be, *bxr; + BIGNUM *s = NULL; + int ret = 0; + + *out_s = NULL; + + BN_CTX_start(ctx); + + if ((group = EC_KEY_get0_group(key)) == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if ((order = EC_GROUP_get0_order(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if ((priv_key = EC_KEY_get0_private_key(key)) == NULL) { + ECerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((binv = BN_CTX_get(ctx)) == NULL) + goto err; + if ((be = BN_CTX_get(ctx)) == NULL) + goto err; + if ((bxr = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((s = BN_new()) == NULL) + goto err; + + /* + * In a valid ECDSA signature, r must be in [1, order). Since r can be + * caller provided - either directly or by replacing sign_setup() - we + * can't rely on this being the case. + */ + if (BN_cmp(r, BN_value_one()) < 0 || BN_cmp(r, order) >= 0) { + ECerror(EC_R_BAD_SIGNATURE); + goto err; + } + + if (!bn_rand_interval(b, 1, order)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_mul(bxr, bxr, r, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_mul(be, b, e, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_add(s, be, bxr, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + /* s = b(e + xr)k^-1 */ + if (!BN_mod_mul(s, s, kinv, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + /* s = (e + xr)k^-1 */ + if (!BN_mod_mul(s, s, binv, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + /* Step 11: if s == 0 start over. */ + if (!BN_is_zero(s)) { + *out_s = s; + s = NULL; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + BN_free(s); + + return ret; +} + +/* + * It is too expensive to check curve parameters on every sign operation. + * Instead, cap the number of retries. A single retry is very unlikely, so + * allowing 32 retries is amply enough. + */ +#define ECDSA_MAX_SIGN_ITERATIONS 32 + +/* + * FIPS 186-5: Section 6.4.1: ECDSA signature generation, steps 2-12. + * The caller provides the hash of the message, thus performs step 1. + * Step 10, zeroing k and kinv, is done by BN_free(). + */ + +ECDSA_SIG * +ecdsa_sign_sig(const unsigned char *digest, int digest_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *key) +{ + BN_CTX *ctx = NULL; + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BIGNUM *e; + int attempts = 0; + ECDSA_SIG *sig = NULL; + + if (in_kinv != NULL || in_r != NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Step 2: convert hash into an integer. */ + if (!ecdsa_prepare_digest(digest, digest_len, key, e)) + goto err; + + do { + /* Steps 3-8: calculate kinv and r. */ + if (!ECDSA_sign_setup(key, ctx, &kinv, &r)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + /* + * Steps 9 and 11: if s is non-NULL, we have a valid signature. + */ + if (!ecdsa_compute_s(&s, e, kinv, r, key, ctx)) + goto err; + if (s != NULL) + break; + + if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) { + ECerror(EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + } while (1); + + /* Step 12: output (r, s). */ + if ((sig = ECDSA_SIG_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ECDSA_SIG_set0(sig, r, s)) { + ECDSA_SIG_free(sig); + goto err; + } + r = NULL; + s = NULL; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_free(kinv); + BN_free(r); + BN_free(s); + + return sig; +} + +ECDSA_SIG * +ECDSA_do_sign(const unsigned char *digest, int digest_len, EC_KEY *key) +{ + if (key->meth->sign_sig == NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; + } + return key->meth->sign_sig(digest, digest_len, NULL, NULL, key); +} +LCRYPTO_ALIAS(ECDSA_do_sign); + +int +ecdsa_verify(int type, const unsigned char *digest, int digest_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *key) +{ + ECDSA_SIG *s; + unsigned char *der = NULL; + const unsigned char *p; + int der_len = 0; + int ret = -1; + + if ((s = ECDSA_SIG_new()) == NULL) + goto err; + + p = sigbuf; + if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) + goto err; + + /* Ensure signature uses DER and doesn't have trailing garbage. */ + if ((der_len = i2d_ECDSA_SIG(s, &der)) != sig_len) + goto err; + if (timingsafe_memcmp(sigbuf, der, der_len)) + goto err; + + ret = ECDSA_do_verify(digest, digest_len, s, key); + + err: + freezero(der, der_len); + ECDSA_SIG_free(s); + + return ret; +} + +int +ECDSA_verify(int type, const unsigned char *digest, int digest_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *key) +{ + if (key->meth->verify == NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; + } + return key->meth->verify(type, digest, digest_len, sigbuf, sig_len, key); +} +LCRYPTO_ALIAS(ECDSA_verify); + +/* + * FIPS 186-5, section 6.4.2: ECDSA signature verification. + * The caller provides us with the hash of the message, so has performed step 2. + */ + +int +ecdsa_verify_sig(const unsigned char *digest, int digest_len, + const ECDSA_SIG *sig, EC_KEY *key) +{ + const EC_GROUP *group; + const EC_POINT *pub_key; + EC_POINT *point = NULL; + const BIGNUM *order; + BN_CTX *ctx = NULL; + BIGNUM *e, *sinv, *u, *v, *x; + int ret = -1; + + if (key == NULL || sig == NULL) { + ECerror(EC_R_MISSING_PARAMETERS); + goto err; + } + if ((group = EC_KEY_get0_group(key)) == NULL) { + ECerror(EC_R_MISSING_PARAMETERS); + goto err; + } + if ((pub_key = EC_KEY_get0_public_key(key)) == NULL) { + ECerror(EC_R_MISSING_PARAMETERS); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + if ((sinv = BN_CTX_get(ctx)) == NULL) + goto err; + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + if ((v = BN_CTX_get(ctx)) == NULL) + goto err; + if ((x = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((order = EC_GROUP_get0_order(group)) == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + + /* Step 1: verify that r and s are in the range [1, order). */ + if (BN_cmp(sig->r, BN_value_one()) < 0 || BN_cmp(sig->r, order) >= 0) { + ECerror(EC_R_BAD_SIGNATURE); + ret = 0; + goto err; + } + if (BN_cmp(sig->s, BN_value_one()) < 0 || BN_cmp(sig->s, order) >= 0) { + ECerror(EC_R_BAD_SIGNATURE); + ret = 0; + goto err; + } + + /* Step 3: convert the hash into an integer. */ + if (!ecdsa_prepare_digest(digest, digest_len, key, e)) + goto err; + + /* Step 4: compute the inverse of s modulo order. */ + if (BN_mod_inverse_ct(sinv, sig->s, order, ctx) == NULL) { + ECerror(ERR_R_BN_LIB); + goto err; + } + /* Step 5: compute u = s^-1 * e and v = s^-1 * r (modulo order). */ + if (!BN_mod_mul(u, e, sinv, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_mul(v, sig->r, sinv, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + /* + * Steps 6 and 7: compute R = G * u + pub_key * v = (x, y). Reject if + * it's the point at infinity - getting affine coordinates fails. Keep + * the x coordinate. + */ + if ((point = EC_POINT_new(group)) == NULL) { + ECerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, point, u, pub_key, v, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_get_affine_coordinates(group, point, x, NULL, ctx)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* Step 8: convert x to a number in [0, order). */ + if (!BN_nnmod(x, x, order, ctx)) { + ECerror(ERR_R_BN_LIB); + goto err; + } + + /* Step 9: the signature is valid iff the x-coordinate is equal to r. */ + ret = (BN_cmp(x, sig->r) == 0); + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); + + return ret; +} + +int +ECDSA_do_verify(const unsigned char *digest, int digest_len, + const ECDSA_SIG *sig, EC_KEY *key) +{ + if (key->meth->verify_sig == NULL) { + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; + } + return key->meth->verify_sig(digest, digest_len, sig, key); +} +LCRYPTO_ALIAS(ECDSA_do_verify); diff --git a/Libraries/libressl/crypto/ecdsa/ecdsa_local.h b/Libraries/libressl/crypto/ecdsa/ecdsa_local.h new file mode 100644 index 000000000..cc3af3e10 --- /dev/null +++ b/Libraries/libressl/crypto/ecdsa/ecdsa_local.h @@ -0,0 +1,81 @@ +/* $OpenBSD: ecdsa_local.h,v 1.2 2023/07/28 15:50:33 tb Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ECS_LOCAL_H +#define HEADER_ECS_LOCAL_H + +#include + +__BEGIN_HIDDEN_DECLS + +struct ECDSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +}; + +int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *in_ctx, BIGNUM **out_kinv, + BIGNUM **out_r); +int ecdsa_sign(int type, const unsigned char *digest, int digest_len, + unsigned char *signature, unsigned int *signature_len, const BIGNUM *kinv, + const BIGNUM *r, EC_KEY *eckey); +ECDSA_SIG *ecdsa_sign_sig(const unsigned char *digest, int digest_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_ECS_LOCAL_H */ diff --git a/Libraries/libressl/crypto/empty.c b/Libraries/libressl/crypto/empty.c new file mode 100644 index 000000000..e69de29bb diff --git a/Libraries/libressl/crypto/engine/engine_stubs.c b/Libraries/libressl/crypto/engine/engine_stubs.c new file mode 100644 index 000000000..3621da80e --- /dev/null +++ b/Libraries/libressl/crypto/engine/engine_stubs.c @@ -0,0 +1,125 @@ +/* $OpenBSD: engine_stubs.c,v 1.1 2023/07/21 09:04:23 tb Exp $ */ + +/* + * Written by Theo Buehler. Public domain. + */ + +#include + +#ifdef OPENSSL_NO_ENGINE + +void +ENGINE_load_builtin_engines(void) +{ +} + +void +ENGINE_load_dynamic(void) +{ +} + +void +ENGINE_load_openssl(void) +{ +} + +int +ENGINE_register_all_complete(void) +{ + return 0; +} + +void +ENGINE_cleanup(void) +{ +} + +ENGINE * +ENGINE_new(void) +{ + return NULL; +} + +int +ENGINE_free(ENGINE *engine) +{ + return 0; +} + +int +ENGINE_init(ENGINE *engine) +{ + return 0; +} + +int +ENGINE_finish(ENGINE *engine) +{ + return 0; +} + +ENGINE * +ENGINE_by_id(const char *id) +{ + return NULL; +} + +const char * +ENGINE_get_id(const ENGINE *engine) +{ + return ""; +} + +const char * +ENGINE_get_name(const ENGINE *engine) +{ + return ""; +} + +int +ENGINE_set_default(ENGINE *engine, unsigned int flags) +{ + return 0; +} + +ENGINE * +ENGINE_get_default_RSA(void) +{ + return NULL; +} + +int +ENGINE_set_default_RSA(ENGINE *engine) +{ + return 0; +} + +int +ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, long i, void *p, + void (*f)(void), int cmd_optional) +{ + return 0; +} + +int +ENGINE_ctrl_cmd_string(ENGINE *engine, const char *cmd, const char *arg, + int cmd_optional) +{ + return 0; +} + +EVP_PKEY * +ENGINE_load_private_key(ENGINE *engine, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + return NULL; +} + +EVP_PKEY * +ENGINE_load_public_key(ENGINE *engine, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + return NULL; +} + +#endif diff --git a/Libraries/libressl/crypto/err/err.c b/Libraries/libressl/crypto/err/err.c new file mode 100644 index 000000000..4b4be213b --- /dev/null +++ b/Libraries/libressl/crypto/err/err.c @@ -0,0 +1,1196 @@ +/* $OpenBSD: err.c,v 1.56 2023/07/28 10:23:19 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +DECLARE_LHASH_OF(ERR_STRING_DATA); +DECLARE_LHASH_OF(ERR_STATE); + +typedef struct st_ERR_FNS ERR_FNS; + +static void err_load_strings(int lib, ERR_STRING_DATA *str); + +static void ERR_STATE_free(ERR_STATE *s); +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA ERR_str_libraries[] = { + {ERR_PACK(ERR_LIB_NONE,0,0), "unknown library"}, + {ERR_PACK(ERR_LIB_SYS,0,0), "system library"}, + {ERR_PACK(ERR_LIB_BN,0,0), "bignum routines"}, + {ERR_PACK(ERR_LIB_RSA,0,0), "rsa routines"}, + {ERR_PACK(ERR_LIB_DH,0,0), "Diffie-Hellman routines"}, + {ERR_PACK(ERR_LIB_EVP,0,0), "digital envelope routines"}, + {ERR_PACK(ERR_LIB_BUF,0,0), "memory buffer routines"}, + {ERR_PACK(ERR_LIB_OBJ,0,0), "object identifier routines"}, + {ERR_PACK(ERR_LIB_PEM,0,0), "PEM routines"}, + {ERR_PACK(ERR_LIB_DSA,0,0), "dsa routines"}, + {ERR_PACK(ERR_LIB_X509,0,0), "x509 certificate routines"}, + {ERR_PACK(ERR_LIB_ASN1,0,0), "asn1 encoding routines"}, + {ERR_PACK(ERR_LIB_CONF,0,0), "configuration file routines"}, + {ERR_PACK(ERR_LIB_CRYPTO,0,0), "common libcrypto routines"}, + {ERR_PACK(ERR_LIB_EC,0,0), "elliptic curve routines"}, + {ERR_PACK(ERR_LIB_SSL,0,0), "SSL routines"}, + {ERR_PACK(ERR_LIB_BIO,0,0), "BIO routines"}, + {ERR_PACK(ERR_LIB_PKCS7,0,0), "PKCS7 routines"}, + {ERR_PACK(ERR_LIB_X509V3,0,0), "X509 V3 routines"}, + {ERR_PACK(ERR_LIB_PKCS12,0,0), "PKCS12 routines"}, + {ERR_PACK(ERR_LIB_RAND,0,0), "random number generator"}, + {ERR_PACK(ERR_LIB_DSO,0,0), "DSO support routines"}, + {ERR_PACK(ERR_LIB_TS,0,0), "time stamp routines"}, + {ERR_PACK(ERR_LIB_ENGINE,0,0), "engine routines"}, + {ERR_PACK(ERR_LIB_OCSP,0,0), "OCSP routines"}, + {ERR_PACK(ERR_LIB_FIPS,0,0), "FIPS routines"}, + {ERR_PACK(ERR_LIB_CMS,0,0), "CMS routines"}, + {ERR_PACK(ERR_LIB_HMAC,0,0), "HMAC routines"}, + {ERR_PACK(ERR_LIB_GOST,0,0), "GOST routines"}, + {0, NULL}, +}; + +static ERR_STRING_DATA ERR_str_functs[] = { + {ERR_PACK(0,SYS_F_FOPEN, 0), "fopen"}, + {ERR_PACK(0,SYS_F_CONNECT, 0), "connect"}, + {ERR_PACK(0,SYS_F_GETSERVBYNAME, 0), "getservbyname"}, + {ERR_PACK(0,SYS_F_SOCKET, 0), "socket"}, + {ERR_PACK(0,SYS_F_IOCTLSOCKET, 0), "ioctl"}, + {ERR_PACK(0,SYS_F_BIND, 0), "bind"}, + {ERR_PACK(0,SYS_F_LISTEN, 0), "listen"}, + {ERR_PACK(0,SYS_F_ACCEPT, 0), "accept"}, + {ERR_PACK(0,SYS_F_OPENDIR, 0), "opendir"}, + {ERR_PACK(0,SYS_F_FREAD, 0), "fread"}, + {0, NULL}, +}; + +static ERR_STRING_DATA ERR_str_reasons[] = { + {ERR_R_SYS_LIB, "system lib"}, + {ERR_R_BN_LIB, "BN lib"}, + {ERR_R_RSA_LIB, "RSA lib"}, + {ERR_R_DH_LIB, "DH lib"}, + {ERR_R_EVP_LIB, "EVP lib"}, + {ERR_R_BUF_LIB, "BUF lib"}, + {ERR_R_OBJ_LIB, "OBJ lib"}, + {ERR_R_PEM_LIB, "PEM lib"}, + {ERR_R_DSA_LIB, "DSA lib"}, + {ERR_R_X509_LIB, "X509 lib"}, + {ERR_R_ASN1_LIB, "ASN1 lib"}, + {ERR_R_CONF_LIB, "CONF lib"}, + {ERR_R_CRYPTO_LIB, "CRYPTO lib"}, + {ERR_R_EC_LIB, "EC lib"}, + {ERR_R_SSL_LIB, "SSL lib"}, + {ERR_R_BIO_LIB, "BIO lib"}, + {ERR_R_PKCS7_LIB, "PKCS7 lib"}, + {ERR_R_X509V3_LIB, "X509V3 lib"}, + {ERR_R_PKCS12_LIB, "PKCS12 lib"}, + {ERR_R_RAND_LIB, "RAND lib"}, + {ERR_R_DSO_LIB, "DSO lib"}, + {ERR_R_ENGINE_LIB, "ENGINE lib"}, + {ERR_R_OCSP_LIB, "OCSP lib"}, + {ERR_R_TS_LIB, "TS lib"}, + + {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, + {ERR_R_BAD_ASN1_OBJECT_HEADER, "bad asn1 object header"}, + {ERR_R_BAD_GET_ASN1_OBJECT_CALL, "bad get asn1 object call"}, + {ERR_R_EXPECTING_AN_ASN1_SEQUENCE, "expecting an asn1 sequence"}, + {ERR_R_ASN1_LENGTH_MISMATCH, "asn1 length mismatch"}, + {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, + + {ERR_R_FATAL, "fatal"}, + {ERR_R_MALLOC_FAILURE, "malloc failure"}, + {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, "called a function you should not call"}, + {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"}, + {ERR_R_INTERNAL_ERROR, "internal error"}, + {ERR_R_DISABLED , "called a function that was disabled at compile-time"}, + {ERR_R_INIT_FAIL, "initialization failure"}, + + {0, NULL}, +}; +#endif + + +/* Define the predeclared (but externally opaque) "ERR_FNS" type */ +struct st_ERR_FNS { + /* Works on the "error_hash" string table */ + LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create); + void (*cb_err_del)(void); + ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *); + /* Works on the "thread_hash" error-state table */ + LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create); + void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash); + ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *); + ERR_STATE *(*cb_thread_set_item)(ERR_STATE *); + void (*cb_thread_del_item)(const ERR_STATE *); + /* Returns the next available error "library" numbers */ + int (*cb_get_next_lib)(void); +}; + +/* Predeclarations of the "err_defaults" functions */ +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create); +static void int_err_del(void); +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); +static LHASH_OF(ERR_STATE) *int_thread_get(int create); +static void int_thread_release(LHASH_OF(ERR_STATE) **hash); +static ERR_STATE *int_thread_get_item(const ERR_STATE *); +static ERR_STATE *int_thread_set_item(ERR_STATE *); +static void int_thread_del_item(const ERR_STATE *); +static int int_err_get_next_lib(void); + +/* The static ERR_FNS table using these defaults functions */ +static const ERR_FNS err_defaults = { + int_err_get, + int_err_del, + int_err_get_item, + int_err_set_item, + int_err_del_item, + int_thread_get, + int_thread_release, + int_thread_get_item, + int_thread_set_item, + int_thread_del_item, + int_err_get_next_lib +}; + +/* The replacable table of ERR_FNS functions we use at run-time */ +static const ERR_FNS *err_fns = NULL; + +/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ +#define ERRFN(a) err_fns->cb_##a + +/* The internal state used by "err_defaults" - as such, the setting, reading, + * creating, and deleting of this data should only be permitted via the + * "err_defaults" functions. This way, a linked module can completely defer all + * ERR state operation (together with requisite locking) to the implementations + * and state in the loading application. */ +static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; +static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; +static int int_thread_hash_references = 0; +static int int_err_library_number = ERR_LIB_USER; + +static pthread_t err_init_thread; + +/* Internal function that checks whether "err_fns" is set and if not, sets it to + * the defaults. */ +static void +err_fns_check(void) +{ + if (err_fns) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!err_fns) + err_fns = &err_defaults; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} + +/* These are the callbacks provided to "lh_new()" when creating the LHASH tables + * internal to the "err_defaults" implementation. */ + +static unsigned long get_error_values(int inc, int top, const char **file, + int *line, const char **data, int *flags); + +/* The internal functions used in the "err_defaults" implementation */ + +static unsigned long +err_string_data_hash(const ERR_STRING_DATA *a) +{ + unsigned long ret, l; + + l = a->error; + ret = l^ERR_GET_LIB(l)^ERR_GET_FUNC(l); + return (ret^ret % 19*13); +} +static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA) + +static int +err_string_data_cmp(const ERR_STRING_DATA *a, const ERR_STRING_DATA *b) +{ + return (int)(a->error - b->error); +} +static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA) + +static +LHASH_OF(ERR_STRING_DATA) *int_err_get(int create) +{ + LHASH_OF(ERR_STRING_DATA) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_error_hash && create) { + CRYPTO_push_info("int_err_get (err.c)"); + int_error_hash = lh_ERR_STRING_DATA_new(); + CRYPTO_pop_info(); + } + if (int_error_hash) + ret = int_error_hash; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + +static void +int_err_del(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (int_error_hash) { + lh_ERR_STRING_DATA_free(int_error_hash); + int_error_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} + +static ERR_STRING_DATA * +int_err_get_item(const ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get)(0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static ERR_STRING_DATA * +int_err_set_item(ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get)(1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static ERR_STRING_DATA * +int_err_del_item(ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get)(0); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_delete(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static unsigned long +err_state_hash(const ERR_STATE *a) +{ + return CRYPTO_THREADID_hash(&a->tid) * 13; +} +static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE) + +static int +err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) +{ + return CRYPTO_THREADID_cmp(&a->tid, &b->tid); +} +static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE) + +static +LHASH_OF(ERR_STATE) *int_thread_get(int create) +{ + LHASH_OF(ERR_STATE) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_thread_hash && create) { + CRYPTO_push_info("int_thread_get (err.c)"); + int_thread_hash = lh_ERR_STATE_new(); + CRYPTO_pop_info(); + } + if (int_thread_hash) { + int_thread_hash_references++; + ret = int_thread_hash; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; +} + +static void +int_thread_release(LHASH_OF(ERR_STATE) **hash) +{ + int i; + + if (hash == NULL || *hash == NULL) + return; + + i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); + if (i > 0) + return; + + *hash = NULL; +} + +static ERR_STATE * +int_thread_get_item(const ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get)(0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release)(&hash); + return p; +} + +static ERR_STATE * +int_thread_set_item(ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get)(1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release)(&hash); + return p; +} + +static void +int_thread_del_item(const ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get)(0); + if (!hash) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_delete(hash, d); + /* make sure we don't leak memory */ + if (int_thread_hash_references == 1 && + int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) { + lh_ERR_STATE_free(int_thread_hash); + int_thread_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release)(&hash); + if (p) + ERR_STATE_free(p); +} + +static int +int_err_get_next_lib(void) +{ + int ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + ret = int_err_library_number++; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + + +#ifndef OPENSSL_NO_ERR +#define NUM_SYS_STR_REASONS 127 +#define LEN_SYS_STR_REASON 32 + +static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; +/* SYS_str_reasons is filled with copies of strerror() results at + * initialization. + * 'errno' values up to 127 should cover all usual errors, + * others will be displayed numerically by ERR_error_string. + * It is crucial that we have something for each reason code + * that occurs in ERR_str_reasons, or bogus reason strings + * will be returned for SYSerror(which always gets an errno + * value and never one of those 'standard' reason codes. */ + +static void +build_SYS_str_reasons(void) +{ + /* malloc cannot be used here, use static storage instead */ + static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; + int i; + static int init = 1; + int save_errno; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + if (!init) { + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + return; + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!init) { + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return; + } + + /* strerror(3) will set errno to EINVAL when i is an unknown errno. */ + save_errno = errno; + for (i = 1; i <= NUM_SYS_STR_REASONS; i++) { + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; + + str->error = (unsigned long)i; + if (str->string == NULL) { + char (*dest)[LEN_SYS_STR_REASON] = + &(strerror_tab[i - 1]); + const char *src = strerror(i); + if (src != NULL) { + strlcpy(*dest, src, sizeof *dest); + str->string = *dest; + } + } + if (str->string == NULL) + str->string = "unknown"; + } + errno = save_errno; + + /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, + * as required by ERR_load_strings. */ + + init = 0; + + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} +#endif + +#define err_clear_data(p,i) \ + do { \ + if (((p)->err_data[i] != NULL) && \ + (p)->err_data_flags[i] & ERR_TXT_MALLOCED) { \ + free((p)->err_data[i]); \ + (p)->err_data[i] = NULL; \ + } \ + (p)->err_data_flags[i] = 0; \ + } while(0) + +#define err_clear(p,i) \ + do { \ + (p)->err_flags[i] = 0; \ + (p)->err_buffer[i] = 0; \ + err_clear_data(p, i); \ + (p)->err_file[i] = NULL; \ + (p)->err_line[i] = -1; \ + } while(0) + +static void +ERR_STATE_free(ERR_STATE *s) +{ + int i; + + if (s == NULL) + return; + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear_data(s, i); + } + free(s); +} + +void +ERR_load_ERR_strings_internal(void) +{ + err_init_thread = pthread_self(); + err_fns_check(); +#ifndef OPENSSL_NO_ERR + err_load_strings(0, ERR_str_libraries); + err_load_strings(0, ERR_str_reasons); + err_load_strings(ERR_LIB_SYS, ERR_str_functs); + build_SYS_str_reasons(); + err_load_strings(ERR_LIB_SYS, SYS_str_reasons); +#endif +} + + +void +ERR_load_ERR_strings(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + if (pthread_equal(pthread_self(), err_init_thread)) + return; /* don't recurse */ + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + (void) pthread_once(&once, ERR_load_ERR_strings_internal); +} +LCRYPTO_ALIAS(ERR_load_ERR_strings); + +static void +err_load_strings(int lib, ERR_STRING_DATA *str) +{ + while (str->error) { + if (lib) + str->error |= ERR_PACK(lib, 0, 0); + ERRFN(err_set_item)(str); + str++; + } +} + +void +ERR_load_strings(int lib, ERR_STRING_DATA *str) +{ + ERR_load_ERR_strings(); + err_load_strings(lib, str); +} +LCRYPTO_ALIAS(ERR_load_strings); + +void +ERR_unload_strings(int lib, ERR_STRING_DATA *str) +{ + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + while (str->error) { + if (lib) + str->error |= ERR_PACK(lib, 0, 0); + ERRFN(err_del_item)(str); + str++; + } +} +LCRYPTO_ALIAS(ERR_unload_strings); + +void +ERR_free_strings(void) +{ + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + err_fns_check(); + ERRFN(err_del)(); +} +LCRYPTO_ALIAS(ERR_free_strings); + +/********************************************************/ + +void +ERR_put_error(int lib, int func, int reason, const char *file, int line) +{ + ERR_STATE *es; + int save_errno = errno; + + es = ERR_get_state(); + + es->top = (es->top + 1) % ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; + es->err_flags[es->top] = 0; + es->err_buffer[es->top] = ERR_PACK(lib, func, reason); + es->err_file[es->top] = file; + es->err_line[es->top] = line; + err_clear_data(es, es->top); + errno = save_errno; +} +LCRYPTO_ALIAS(ERR_put_error); + +void +ERR_clear_error(void) +{ + int i; + ERR_STATE *es; + + es = ERR_get_state(); + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(es, i); + } + es->top = es->bottom = 0; +} +LCRYPTO_ALIAS(ERR_clear_error); + + +unsigned long +ERR_get_error(void) +{ + return (get_error_values(1, 0, NULL, NULL, NULL, NULL)); +} +LCRYPTO_ALIAS(ERR_get_error); + +unsigned long +ERR_get_error_line(const char **file, int *line) +{ + return (get_error_values(1, 0, file, line, NULL, NULL)); +} +LCRYPTO_ALIAS(ERR_get_error_line); + +unsigned long +ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(1, 0, file, line, data, flags)); +} +LCRYPTO_ALIAS(ERR_get_error_line_data); + + +unsigned long +ERR_peek_error(void) +{ + return (get_error_values(0, 0, NULL, NULL, NULL, NULL)); +} +LCRYPTO_ALIAS(ERR_peek_error); + +unsigned long +ERR_peek_error_line(const char **file, int *line) +{ + return (get_error_values(0, 0, file, line, NULL, NULL)); +} +LCRYPTO_ALIAS(ERR_peek_error_line); + +unsigned long +ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(0, 0, file, line, data, flags)); +} +LCRYPTO_ALIAS(ERR_peek_error_line_data); + +unsigned long +ERR_peek_last_error(void) +{ + return (get_error_values(0, 1, NULL, NULL, NULL, NULL)); +} +LCRYPTO_ALIAS(ERR_peek_last_error); + +unsigned long +ERR_peek_last_error_line(const char **file, int *line) +{ + return (get_error_values(0, 1, file, line, NULL, NULL)); +} +LCRYPTO_ALIAS(ERR_peek_last_error_line); + +unsigned long +ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(0, 1, file, line, data, flags)); +} +LCRYPTO_ALIAS(ERR_peek_last_error_line_data); + +static unsigned long +get_error_values(int inc, int top, const char **file, int *line, + const char **data, int *flags) +{ + int i = 0; + ERR_STATE *es; + unsigned long ret; + + es = ERR_get_state(); + + if (inc && top) { + if (file) + *file = ""; + if (line) + *line = 0; + if (data) + *data = ""; + if (flags) + *flags = 0; + + return ERR_R_INTERNAL_ERROR; + } + + if (es->bottom == es->top) + return 0; + if (top) + i = es->top; /* last error */ + else + i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ + + ret = es->err_buffer[i]; + if (inc) { + es->bottom = i; + es->err_buffer[i] = 0; + } + + if ((file != NULL) && (line != NULL)) { + if (es->err_file[i] == NULL) { + *file = "NA"; + if (line != NULL) + *line = 0; + } else { + *file = es->err_file[i]; + if (line != NULL) + *line = es->err_line[i]; + } + } + + if (data == NULL) { + if (inc) { + err_clear_data(es, i); + } + } else { + if (es->err_data[i] == NULL) { + *data = ""; + if (flags != NULL) + *flags = 0; + } else { + *data = es->err_data[i]; + if (flags != NULL) + *flags = es->err_data_flags[i]; + } + } + return ret; +} + +void +ERR_error_string_n(unsigned long e, char *buf, size_t len) +{ + char lsbuf[30], fsbuf[30], rsbuf[30]; + const char *ls, *fs, *rs; + int l, f, r, ret; + + l = ERR_GET_LIB(e); + f = ERR_GET_FUNC(e); + r = ERR_GET_REASON(e); + + ls = ERR_lib_error_string(e); + fs = ERR_func_error_string(e); + rs = ERR_reason_error_string(e); + + if (ls == NULL) { + (void) snprintf(lsbuf, sizeof(lsbuf), "lib(%d)", l); + ls = lsbuf; + } + if (fs == NULL) { + (void) snprintf(fsbuf, sizeof(fsbuf), "func(%d)", f); + fs = fsbuf; + } + if (rs == NULL) { + (void) snprintf(rsbuf, sizeof(rsbuf), "reason(%d)", r); + rs = rsbuf; + } + + ret = snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs); + if (ret == -1) + return; /* can't happen, and can't do better if it does */ + if (ret >= len) { + /* output may be truncated; make sure we always have 5 + * colon-separated fields, i.e. 4 colons ... */ +#define NUM_COLONS 4 + if (len > NUM_COLONS) /* ... if possible */ + { + int i; + char *s = buf; + + for (i = 0; i < NUM_COLONS; i++) { + char *colon = strchr(s, ':'); + if (colon == NULL || + colon > &buf[len - 1] - NUM_COLONS + i) { + /* set colon no. i at last possible position + * (buf[len-1] is the terminating 0)*/ + colon = &buf[len - 1] - NUM_COLONS + i; + *colon = ':'; + } + s = colon + 1; + } + } + } +} +LCRYPTO_ALIAS(ERR_error_string_n); + +/* BAD for multi-threading: uses a local buffer if ret == NULL */ +/* ERR_error_string_n should be used instead for ret != NULL + * as ERR_error_string cannot know how large the buffer is */ +char * +ERR_error_string(unsigned long e, char *ret) +{ + static char buf[256]; + + if (ret == NULL) + ret = buf; + ERR_error_string_n(e, ret, 256); + + return ret; +} +LCRYPTO_ALIAS(ERR_error_string); + +const char * +ERR_lib_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p; + unsigned long l; + + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + + err_fns_check(); + l = ERR_GET_LIB(e); + d.error = ERR_PACK(l, 0, 0); + p = ERRFN(err_get_item)(&d); + return ((p == NULL) ? NULL : p->string); +} +LCRYPTO_ALIAS(ERR_lib_error_string); + +const char * +ERR_func_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p; + unsigned long l, f; + + err_fns_check(); + l = ERR_GET_LIB(e); + f = ERR_GET_FUNC(e); + d.error = ERR_PACK(l, f, 0); + p = ERRFN(err_get_item)(&d); + return ((p == NULL) ? NULL : p->string); +} +LCRYPTO_ALIAS(ERR_func_error_string); + +const char * +ERR_reason_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p = NULL; + unsigned long l, r; + + err_fns_check(); + l = ERR_GET_LIB(e); + r = ERR_GET_REASON(e); + d.error = ERR_PACK(l, 0, r); + p = ERRFN(err_get_item)(&d); + if (!p) { + d.error = ERR_PACK(0, 0, r); + p = ERRFN(err_get_item)(&d); + } + return ((p == NULL) ? NULL : p->string); +} +LCRYPTO_ALIAS(ERR_reason_error_string); + +void +ERR_remove_thread_state(const CRYPTO_THREADID *id) +{ + ERR_STATE tmp; + + if (id) + CRYPTO_THREADID_cpy(&tmp.tid, id); + else + CRYPTO_THREADID_current(&tmp.tid); + err_fns_check(); + /* thread_del_item automatically destroys the LHASH if the number of + * items reaches zero. */ + ERRFN(thread_del_item)(&tmp); +} +LCRYPTO_ALIAS(ERR_remove_thread_state); + +void +ERR_remove_state(unsigned long pid) +{ + ERR_remove_thread_state(NULL); +} +LCRYPTO_ALIAS(ERR_remove_state); + +ERR_STATE * +ERR_get_state(void) +{ + static ERR_STATE fallback; + ERR_STATE *ret, tmp, *tmpp = NULL; + int i; + CRYPTO_THREADID tid; + + err_fns_check(); + CRYPTO_THREADID_current(&tid); + CRYPTO_THREADID_cpy(&tmp.tid, &tid); + ret = ERRFN(thread_get_item)(&tmp); + + /* ret == the error state, if NULL, make a new one */ + if (ret == NULL) { + ret = malloc(sizeof(ERR_STATE)); + if (ret == NULL) + return (&fallback); + CRYPTO_THREADID_cpy(&ret->tid, &tid); + ret->top = 0; + ret->bottom = 0; + for (i = 0; i < ERR_NUM_ERRORS; i++) { + ret->err_data[i] = NULL; + ret->err_data_flags[i] = 0; + } + tmpp = ERRFN(thread_set_item)(ret); + /* To check if insertion failed, do a get. */ + if (ERRFN(thread_get_item)(ret) != ret) { + ERR_STATE_free(ret); /* could not insert it */ + return (&fallback); + } + /* If a race occurred in this function and we came second, tmpp + * is the first one that we just replaced. */ + if (tmpp) + ERR_STATE_free(tmpp); + } + return ret; +} +LCRYPTO_ALIAS(ERR_get_state); + +int +ERR_get_next_error_library(void) +{ + err_fns_check(); + return ERRFN(get_next_lib)(); +} +LCRYPTO_ALIAS(ERR_get_next_error_library); + +void +ERR_set_error_data(char *data, int flags) +{ + ERR_STATE *es; + int i; + + es = ERR_get_state(); + + i = es->top; + if (i == 0) + i = ERR_NUM_ERRORS - 1; + + err_clear_data(es, i); + es->err_data[i] = data; + es->err_data_flags[i] = flags; +} +LCRYPTO_ALIAS(ERR_set_error_data); + +void +ERR_asprintf_error_data(char * format, ...) +{ + char *errbuf = NULL; + va_list ap; + int r; + + va_start(ap, format); + r = vasprintf(&errbuf, format, ap); + va_end(ap); + if (r == -1) + ERR_set_error_data("malloc failed", ERR_TXT_STRING); + else + ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING); +} +LCRYPTO_ALIAS(ERR_asprintf_error_data); + +void +ERR_add_error_vdata(int num, va_list args) +{ + char format[129]; + char *errbuf; + int i; + + format[0] = '\0'; + for (i = 0; i < num; i++) { + if (strlcat(format, "%s", sizeof(format)) >= sizeof(format)) { + ERR_set_error_data("too many errors", ERR_TXT_STRING); + return; + } + } + if (vasprintf(&errbuf, format, args) == -1) + ERR_set_error_data("malloc failed", ERR_TXT_STRING); + else + ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING); +} + +void +ERR_add_error_data(int num, ...) +{ + va_list args; + va_start(args, num); + ERR_add_error_vdata(num, args); + va_end(args); +} + +int +ERR_set_mark(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + + if (es->bottom == es->top) + return 0; + es->err_flags[es->top] |= ERR_FLAG_MARK; + return 1; +} +LCRYPTO_ALIAS(ERR_set_mark); + +int +ERR_pop_to_mark(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + + while (es->bottom != es->top && + (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { + err_clear(es, es->top); + es->top -= 1; + if (es->top == -1) + es->top = ERR_NUM_ERRORS - 1; + } + + if (es->bottom == es->top) + return 0; + es->err_flags[es->top]&=~ERR_FLAG_MARK; + return 1; +} +LCRYPTO_ALIAS(ERR_pop_to_mark); + +void +err_clear_last_constant_time(int clear) +{ + ERR_STATE *es; + int top; + + es = ERR_get_state(); + if (es == NULL) + return; + + top = es->top; + + es->err_flags[top] &= ~(0 - clear); + es->err_buffer[top] &= ~(0UL - clear); + es->err_file[top] = (const char *)((uintptr_t)es->err_file[top] & + ~((uintptr_t)0 - clear)); + es->err_line[top] |= 0 - clear; + + es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS; +} diff --git a/Libraries/libressl/crypto/err/err_all.c b/Libraries/libressl/crypto/err/err_all.c new file mode 100644 index 000000000..2c8a273f1 --- /dev/null +++ b/Libraries/libressl/crypto/err/err_all.c @@ -0,0 +1,163 @@ +/* $OpenBSD: err_all.c,v 1.32 2023/07/28 09:46:36 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_EC +#include +#endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_GOST +#include +#endif + +void ERR_load_ERR_strings_internal(void); + +static void +ERR_load_crypto_strings_internal(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_ERR_strings_internal(); /* include error strings for SYSerr */ + + ERR_load_ASN1_strings(); + ERR_load_BIO_strings(); + ERR_load_BN_strings(); + ERR_load_BUF_strings(); +#ifndef OPENSSL_NO_CMS + ERR_load_CMS_strings(); +#endif + ERR_load_CONF_strings(); + ERR_load_CRYPTO_strings(); +#ifndef OPENSSL_NO_CT + ERR_load_CT_strings(); +#endif +#ifndef OPENSSL_NO_DH + ERR_load_DH_strings(); +#endif +#ifndef OPENSSL_NO_DSA + ERR_load_DSA_strings(); +#endif +#ifndef OPENSSL_NO_EC + ERR_load_EC_strings(); +#endif +#ifndef OPENSSL_NO_ENGINE + ERR_load_ENGINE_strings(); +#endif + ERR_load_EVP_strings(); +#ifndef OPENSSL_NO_GOST + ERR_load_GOST_strings(); +#endif + ERR_load_KDF_strings(); + ERR_load_OBJ_strings(); + ERR_load_OCSP_strings(); + ERR_load_PEM_strings(); + ERR_load_PKCS12_strings(); + ERR_load_PKCS7_strings(); + ERR_load_RAND_strings(); +#ifndef OPENSSL_NO_RSA + ERR_load_RSA_strings(); +#endif + ERR_load_TS_strings(); + ERR_load_UI_strings(); + ERR_load_X509V3_strings(); + ERR_load_X509_strings(); +#endif +} + +void +ERR_load_crypto_strings(void) +{ + static pthread_once_t loaded = PTHREAD_ONCE_INIT; + (void) pthread_once(&loaded, ERR_load_crypto_strings_internal); +} +LCRYPTO_ALIAS(ERR_load_crypto_strings); diff --git a/Libraries/libressl/crypto/err/err_prn.c b/Libraries/libressl/crypto/err/err_prn.c new file mode 100644 index 000000000..d60cfdcb9 --- /dev/null +++ b/Libraries/libressl/crypto/err/err_prn.c @@ -0,0 +1,122 @@ +/* $OpenBSD: err_prn.c,v 1.20 2023/07/07 13:54:45 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include + +#include "bio_local.h" + +void +ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), void *u) +{ + unsigned long l; + char buf[256]; + char buf2[4096]; + const char *file, *data; + int line, flags; + unsigned long es; + CRYPTO_THREADID cur; + + CRYPTO_THREADID_current(&cur); + es = CRYPTO_THREADID_hash(&cur); + while ((l = ERR_get_error_line_data(&file, &line, &data, + &flags)) != 0) { + ERR_error_string_n(l, buf, sizeof buf); + (void) snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, + buf, file, line, (flags & ERR_TXT_STRING) ? data : ""); + if (cb(buf2, strlen(buf2), u) <= 0) + break; /* abort outputting the error report */ + } +} +LCRYPTO_ALIAS(ERR_print_errors_cb); + +static int +print_fp(const char *str, size_t len, void *fp) +{ + BIO bio; + + BIO_set(&bio, BIO_s_file()); + BIO_set_fp(&bio, fp, BIO_NOCLOSE); + + return BIO_printf(&bio, "%s", str); +} + +void +ERR_print_errors_fp(FILE *fp) +{ + ERR_print_errors_cb(print_fp, fp); +} +LCRYPTO_ALIAS(ERR_print_errors_fp); + +static int +print_bio(const char *str, size_t len, void *bp) +{ + return BIO_write((BIO *)bp, str, len); +} + +void +ERR_print_errors(BIO *bp) +{ + ERR_print_errors_cb(print_bio, bp); +} +LCRYPTO_ALIAS(ERR_print_errors); diff --git a/Libraries/libressl/crypto/evp/bio_b64.c b/Libraries/libressl/crypto/evp/bio_b64.c new file mode 100644 index 000000000..3c47628f5 --- /dev/null +++ b/Libraries/libressl/crypto/evp/bio_b64.c @@ -0,0 +1,571 @@ +/* $OpenBSD: bio_b64.c,v 1.28 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include + +#include "bio_local.h" +#include "evp_local.h" + +static int b64_write(BIO *h, const char *buf, int num); +static int b64_read(BIO *h, char *buf, int size); +static int b64_puts(BIO *h, const char *str); +/*static int b64_gets(BIO *h, char *str, int size); */ +static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int b64_new(BIO *h); +static int b64_free(BIO *data); +static long b64_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); +#define B64_BLOCK_SIZE 1024 +#define B64_BLOCK_SIZE2 768 +#define B64_NONE 0 +#define B64_ENCODE 1 +#define B64_DECODE 2 + +typedef struct b64_struct { + /*BIO *bio; moved to the BIO structure */ + int buf_len; + int buf_off; + int tmp_len; /* used to find the start when decoding */ + int tmp_nl; /* If true, scan until '\n' */ + int encode; + int start; /* have we started decoding yet? */ + int cont; /* <= 0 when finished */ + EVP_ENCODE_CTX base64; + char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; + char tmp[B64_BLOCK_SIZE]; +} BIO_B64_CTX; + +static const BIO_METHOD methods_b64 = { + .type = BIO_TYPE_BASE64, + .name = "base64 encoding", + .bwrite = b64_write, + .bread = b64_read, + .bputs = b64_puts, + .ctrl = b64_ctrl, + .create = b64_new, + .destroy = b64_free, + .callback_ctrl = b64_callback_ctrl +}; + +const BIO_METHOD * +BIO_f_base64(void) +{ + return (&methods_b64); +} + +static int +b64_new(BIO *bi) +{ + BIO_B64_CTX *ctx; + + ctx = malloc(sizeof(BIO_B64_CTX)); + if (ctx == NULL) + return (0); + + ctx->buf_len = 0; + ctx->tmp_len = 0; + ctx->tmp_nl = 0; + ctx->buf_off = 0; + ctx->cont = 1; + ctx->start = 1; + ctx->encode = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + bi->num = 0; + return (1); +} + +static int +b64_free(BIO *a) +{ + if (a == NULL) + return (0); + free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int +b64_read(BIO *b, char *out, int outl) +{ + int ret = 0, i, ii, j, k, x, n, num, ret_code = 0; + BIO_B64_CTX *ctx; + unsigned char *p, *q; + + if (out == NULL) + return (0); + ctx = (BIO_B64_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + + if (ctx->encode != B64_DECODE) { + ctx->encode = B64_DECODE; + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->tmp_len = 0; + EVP_DecodeInit(&(ctx->base64)); + } + + /* First check if there are bytes decoded/encoded */ + if (ctx->buf_len > 0) { + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf)); + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret = i; + out += i; + outl -= i; + ctx->buf_off += i; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + } + + /* At this point, we have room of outl bytes and an empty + * buffer, so we should read in some more. */ + + ret_code = 0; + while (outl > 0) { + if (ctx->cont <= 0) + break; + + i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]), + B64_BLOCK_SIZE - ctx->tmp_len); + + if (i <= 0) { + ret_code = i; + + /* Should we continue next time we are called? */ + if (!BIO_should_retry(b->next_bio)) { + ctx->cont = i; + /* If buffer empty break */ + if (ctx->tmp_len == 0) + break; + /* Fall through and process what we have */ + else + i = 0; + } + /* else we retry and add more data to buffer */ + else + break; + } + i += ctx->tmp_len; + ctx->tmp_len = i; + + /* We need to scan, a line at a time until we + * have a valid line if we are starting. */ + if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) { + /* ctx->start=1; */ + ctx->tmp_len = 0; + } else if (ctx->start) { + q = p =(unsigned char *)ctx->tmp; + num = 0; + for (j = 0; j < i; j++) { + if (*(q++) != '\n') + continue; + + /* due to a previous very long line, + * we need to keep on scanning for a '\n' + * before we even start looking for + * base64 encoded stuff. */ + if (ctx->tmp_nl) { + p = q; + ctx->tmp_nl = 0; + continue; + } + + k = EVP_DecodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, + &num, p, q - p); + if ((k <= 0) && (num == 0) && (ctx->start)) + EVP_DecodeInit(&ctx->base64); + else { + if (p != (unsigned char *) + &(ctx->tmp[0])) { + i -= (p - (unsigned char *) + &(ctx->tmp[0])); + for (x = 0; x < i; x++) + ctx->tmp[x] = p[x]; + } + EVP_DecodeInit(&ctx->base64); + ctx->start = 0; + break; + } + p = q; + } + + /* we fell off the end without starting */ + if ((j == i) && (num == 0)) { + /* Is this is one long chunk?, if so, keep on + * reading until a new line. */ + if (p == (unsigned char *)&(ctx->tmp[0])) { + /* Check buffer full */ + if (i == B64_BLOCK_SIZE) { + ctx->tmp_nl = 1; + ctx->tmp_len = 0; + } + } + else if (p != q) /* finished on a '\n' */ + { + n = q - p; + for (ii = 0; ii < n; ii++) + ctx->tmp[ii] = p[ii]; + ctx->tmp_len = n; + } + /* else finished on a '\n' */ + continue; + } else { + ctx->tmp_len = 0; + } + } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) { + /* If buffer isn't full and we can retry then + * restart to read in more data. + */ + continue; + } + + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + int z, jj; + + jj = i & ~3; /* process per 4 */ + z = EVP_DecodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, jj); + if (jj > 2) { + if (ctx->tmp[jj-1] == '=') { + z--; + if (ctx->tmp[jj-2] == '=') + z--; + } + } + /* z is now number of output bytes and jj is the + * number consumed */ + if (jj != i) { + memmove(ctx->tmp, &ctx->tmp[jj], i - jj); + ctx->tmp_len = i - jj; + } + ctx->buf_len = 0; + if (z > 0) { + ctx->buf_len = z; + } + i = z; + } else { + i = EVP_DecodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)ctx->tmp, i); + ctx->tmp_len = 0; + } + ctx->buf_off = 0; + if (i < 0) { + ret_code = 0; + ctx->buf_len = 0; + break; + } + + if (ctx->buf_len <= outl) + i = ctx->buf_len; + else + i = outl; + + memcpy(out, ctx->buf, i); + ret += i; + ctx->buf_off = i; + if (ctx->buf_off == ctx->buf_len) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + outl -= i; + out += i; + } + /* BIO_clear_retry_flags(b); */ + BIO_copy_next_retry(b); + return ((ret == 0) ? ret_code : ret); +} + +static int +b64_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + int n; + int i; + BIO_B64_CTX *ctx; + + ctx = (BIO_B64_CTX *)b->ptr; + BIO_clear_retry_flags(b); + + if (ctx->encode != B64_ENCODE) { + ctx->encode = B64_ENCODE; + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->tmp_len = 0; + EVP_EncodeInit(&(ctx->base64)); + } + + OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + n = ctx->buf_len - ctx->buf_off; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (i); + } + OPENSSL_assert(i <= n); + ctx->buf_off += i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + n -= i; + } + /* at this point all pending data has been written */ + ctx->buf_off = 0; + ctx->buf_len = 0; + + if ((in == NULL) || (inl <= 0)) + return (0); + + while (inl > 0) { + n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; + + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if (ctx->tmp_len > 0) { + OPENSSL_assert(ctx->tmp_len <= 3); + n = 3 - ctx->tmp_len; + /* There's a theoretical possibility for this */ + if (n > inl) + n = inl; + memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); + ctx->tmp_len += n; + ret += n; + if (ctx->tmp_len < 3) + break; + ctx->buf_len = EVP_EncodeBlock( + (unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, ctx->tmp_len); + OPENSSL_assert(ctx->buf_len <= + (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + /* Since we're now done using the temporary + buffer, the length should be 0'd */ + ctx->tmp_len = 0; + } else { + if (n < 3) { + memcpy(ctx->tmp, in, n); + ctx->tmp_len = n; + ret += n; + break; + } + n -= n % 3; + ctx->buf_len = EVP_EncodeBlock( + (unsigned char *)ctx->buf, + (const unsigned char *)in, n); + OPENSSL_assert(ctx->buf_len <= + (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; + } + } else { + if (!EVP_EncodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n)) + return ((ret == 0) ? -1 : ret); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; + } + inl -= n; + in += n; + + ctx->buf_off = 0; + n = ctx->buf_len; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return ((ret == 0) ? i : ret); + } + OPENSSL_assert(i <= n); + n -= i; + ctx->buf_off += i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + } + ctx->buf_len = 0; + ctx->buf_off = 0; + } + return (ret); +} + +static long +b64_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_B64_CTX *ctx; + long ret = 1; + int i; + + ctx = (BIO_B64_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->cont = 1; + ctx->start = 1; + ctx->encode = B64_NONE; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_WPENDING: /* More to write in buffer */ + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret = ctx->buf_len - ctx->buf_off; + if ((ret == 0) && (ctx->encode != B64_NONE) && + (ctx->base64.num != 0)) + ret = 1; + else if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ +again: + while (ctx->buf_len != ctx->buf_off) { + i = b64_write(b, NULL, 0); + if (i < 0) + return i; + } + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if (ctx->tmp_len != 0) { + ctx->buf_len = EVP_EncodeBlock( + (unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, + ctx->tmp_len); + ctx->buf_off = 0; + ctx->tmp_len = 0; + goto again; + } + } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) { + ctx->buf_off = 0; + EVP_EncodeFinal(&(ctx->base64), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + /* push out the bytes */ + goto again; + } + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_DUP: + break; + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_SET: + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long +b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int +b64_puts(BIO *b, const char *str) +{ + return b64_write(b, str, strlen(str)); +} diff --git a/Libraries/libressl/crypto/evp/bio_enc.c b/Libraries/libressl/crypto/evp/bio_enc.c new file mode 100644 index 000000000..d2132adb4 --- /dev/null +++ b/Libraries/libressl/crypto/evp/bio_enc.c @@ -0,0 +1,418 @@ +/* $OpenBSD: bio_enc.c,v 1.29 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include + +#include "bio_local.h" +#include "evp_local.h" + +static int enc_write(BIO *h, const char *buf, int num); +static int enc_read(BIO *h, char *buf, int size); +/*static int enc_puts(BIO *h, const char *str); */ +/*static int enc_gets(BIO *h, char *str, int size); */ +static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int enc_new(BIO *h); +static int enc_free(BIO *data); +static long enc_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fps); +#define ENC_BLOCK_SIZE (1024*4) +#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2) + +typedef struct enc_struct { + int buf_len; + int buf_off; + int cont; /* <= 0 when finished */ + int finished; + int ok; /* bad decrypt */ + EVP_CIPHER_CTX cipher; + /* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate + * can return up to a block more data than is presented to it + */ + char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2]; +} BIO_ENC_CTX; + +static const BIO_METHOD methods_enc = { + .type = BIO_TYPE_CIPHER, + .name = "cipher", + .bwrite = enc_write, + .bread = enc_read, + .ctrl = enc_ctrl, + .create = enc_new, + .destroy = enc_free, + .callback_ctrl = enc_callback_ctrl +}; + +const BIO_METHOD * +BIO_f_cipher(void) +{ + return (&methods_enc); +} + +static int +enc_new(BIO *bi) +{ + BIO_ENC_CTX *ctx; + + ctx = malloc(sizeof(BIO_ENC_CTX)); + if (ctx == NULL) + return (0); + EVP_CIPHER_CTX_init(&ctx->cipher); + + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->ok = 1; + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int +enc_free(BIO *a) +{ + BIO_ENC_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_ENC_CTX *)a->ptr; + EVP_CIPHER_CTX_cleanup(&(b->cipher)); + freezero(a->ptr, sizeof(BIO_ENC_CTX)); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int +enc_read(BIO *b, char *out, int outl) +{ + int ret = 0, i; + BIO_ENC_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_ENC_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + /* First check if there are bytes decoded/encoded */ + if (ctx->buf_len > 0) { + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret = i; + out += i; + outl -= i; + ctx->buf_off += i; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + } + + /* At this point, we have room of outl bytes and an empty + * buffer, so we should read in some more. */ + + while (outl > 0) { + if (ctx->cont <= 0) + break; + + /* read in at IV offset, read the EVP_Cipher + * documentation about why */ + i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE); + + if (i <= 0) { + /* Should be continue next time we are called? */ + if (!BIO_should_retry(b->next_bio)) { + ctx->cont = i; + i = EVP_CipherFinal_ex(&(ctx->cipher), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + ctx->ok = i; + ctx->buf_off = 0; + } else { + ret = (ret == 0) ? i : ret; + break; + } + } else { + EVP_CipherUpdate(&(ctx->cipher), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)&(ctx->buf[BUF_OFFSET]), i); + ctx->cont = 1; + /* Note: it is possible for EVP_CipherUpdate to + * decrypt zero bytes because this is or looks like + * the final block: if this happens we should retry + * and either read more data or decrypt the final + * block + */ + if (ctx->buf_len == 0) + continue; + } + + if (ctx->buf_len <= outl) + i = ctx->buf_len; + else + i = outl; + if (i <= 0) + break; + memcpy(out, ctx->buf, i); + ret += i; + ctx->buf_off = i; + outl -= i; + out += i; + } + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return ((ret == 0) ? ctx->cont : ret); +} + +static int +enc_write(BIO *b, const char *in, int inl) +{ + int ret = 0, n, i; + BIO_ENC_CTX *ctx; + + ctx = (BIO_ENC_CTX *)b->ptr; + ret = inl; + + BIO_clear_retry_flags(b); + n = ctx->buf_len - ctx->buf_off; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (i); + } + ctx->buf_off += i; + n -= i; + } + /* at this point all pending data has been written */ + + if ((in == NULL) || (inl <= 0)) + return (0); + + ctx->buf_off = 0; + while (inl > 0) { + n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl; + EVP_CipherUpdate(&(ctx->cipher), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n); + inl -= n; + in += n; + + ctx->buf_off = 0; + n = ctx->buf_len; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (ret == inl) ? i : ret - inl; + } + n -= i; + ctx->buf_off += i; + } + ctx->buf_len = 0; + ctx->buf_off = 0; + } + BIO_copy_next_retry(b); + return (ret); +} + +static long +enc_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_ENC_CTX *ctx, *dctx; + long ret = 1; + int i; + EVP_CIPHER_CTX **c_ctx; + + ctx = (BIO_ENC_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->ok = 1; + ctx->finished = 0; + EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL, + ctx->cipher.encrypt); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_WPENDING: + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ +again: + while (ctx->buf_len != ctx->buf_off) { + i = enc_write(b, NULL, 0); + if (i < 0) + return i; + } + + if (!ctx->finished) { + ctx->finished = 1; + ctx->buf_off = 0; + ret = EVP_CipherFinal_ex(&(ctx->cipher), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + ctx->ok = (int)ret; + if (ret <= 0) + break; + + /* push out the bytes */ + goto again; + } + + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_GET_CIPHER_STATUS: + ret = (long)ctx->ok; + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_C_GET_CIPHER_CTX: + c_ctx = (EVP_CIPHER_CTX **)ptr; + (*c_ctx) = &(ctx->cipher); + b->init = 1; + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + dctx = (BIO_ENC_CTX *)dbio->ptr; + EVP_CIPHER_CTX_init(&dctx->cipher); + ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher); + if (ret) + dbio->init = 1; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long +enc_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +int +BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int e) +{ + BIO_ENC_CTX *ctx; + long (*cb)(BIO *, int, const char *, int, long, long); + + if (b == NULL) + return 0; + + if ((ctx = BIO_get_data(b)) == NULL) + return 0; + + if ((cb = BIO_get_callback(b)) != NULL) { + if (cb(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) + <= 0) + return 0; + } + + BIO_set_init(b, 1); + + if (!EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e)) + return 0; + + if (cb != NULL) + return cb(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); + + return 1; +} diff --git a/Libraries/libressl/crypto/evp/bio_md.c b/Libraries/libressl/crypto/evp/bio_md.c new file mode 100644 index 000000000..ccfcd1ea1 --- /dev/null +++ b/Libraries/libressl/crypto/evp/bio_md.c @@ -0,0 +1,280 @@ +/* $OpenBSD: bio_md.c,v 1.21 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include + +#include "bio_local.h" +#include "evp_local.h" + +/* BIO_put and BIO_get both add to the digest, + * BIO_gets returns the digest */ + +static int md_write(BIO *h, char const *buf, int num); +static int md_read(BIO *h, char *buf, int size); +/*static int md_puts(BIO *h, const char *str); */ +static int md_gets(BIO *h, char *str, int size); +static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int md_new(BIO *h); +static int md_free(BIO *data); +static long md_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); + +static const BIO_METHOD methods_md = { + .type = BIO_TYPE_MD, + .name = "message digest", + .bwrite = md_write, + .bread = md_read, + .bgets = md_gets, + .ctrl = md_ctrl, + .create = md_new, + .destroy = md_free, + .callback_ctrl = md_callback_ctrl +}; + +const BIO_METHOD * +BIO_f_md(void) +{ + return (&methods_md); +} + +static int +md_new(BIO *bi) +{ + EVP_MD_CTX *ctx; + + ctx = EVP_MD_CTX_create(); + if (ctx == NULL) + return (0); + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int +md_free(BIO *a) +{ + if (a == NULL) + return (0); + EVP_MD_CTX_destroy(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int +md_read(BIO *b, char *out, int outl) +{ + int ret = 0; + EVP_MD_CTX *ctx; + + if (out == NULL) + return (0); + ctx = b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + ret = BIO_read(b->next_bio, out, outl); + if (b->init) { + if (ret > 0) { + if (EVP_DigestUpdate(ctx, (unsigned char *)out, + (unsigned int)ret) <= 0) + return (-1); + } + } + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int +md_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + EVP_MD_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = b->ptr; + + if ((ctx != NULL) && (b->next_bio != NULL)) + ret = BIO_write(b->next_bio, in, inl); + if (b->init) { + if (ret > 0) { + if (!EVP_DigestUpdate(ctx, (const unsigned char *)in, + (unsigned int)ret)) { + BIO_clear_retry_flags(b); + return 0; + } + } + } + if (b->next_bio != NULL) { + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + } + return (ret); +} + +static long +md_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + EVP_MD_CTX *ctx, *dctx, **pctx; + const EVP_MD **ppmd; + EVP_MD *md; + long ret = 1; + BIO *dbio; + + ctx = b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (b->init) + ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL); + else + ret = 0; + if (ret > 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_GET_MD: + if (b->init) { + ppmd = ptr; + *ppmd = ctx->digest; + } else + ret = 0; + break; + case BIO_C_GET_MD_CTX: + pctx = ptr; + *pctx = ctx; + b->init = 1; + break; + case BIO_C_SET_MD_CTX: + if (b->init) + b->ptr = ptr; + else + ret = 0; + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_C_SET_MD: + md = ptr; + ret = EVP_DigestInit_ex(ctx, md, NULL); + if (ret > 0) + b->init = 1; + break; + case BIO_CTRL_DUP: + dbio = ptr; + dctx = dbio->ptr; + if (!EVP_MD_CTX_copy_ex(dctx, ctx)) + return 0; + b->init = 1; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long +md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int +md_gets(BIO *bp, char *buf, int size) +{ + EVP_MD_CTX *ctx; + unsigned int ret; + + ctx = bp->ptr; + if (size < ctx->digest->md_size) + return (0); + if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0) + return -1; + + return ((int)ret); +} + +/* +static int md_puts(bp,str) +BIO *bp; +char *str; + { + return(-1); + } +*/ diff --git a/Libraries/libressl/crypto/evp/c_all.c b/Libraries/libressl/crypto/evp/c_all.c new file mode 100644 index 000000000..871abe6e9 --- /dev/null +++ b/Libraries/libressl/crypto/evp/c_all.c @@ -0,0 +1,329 @@ +/* $OpenBSD: c_all.c,v 1.32 2023/07/24 10:24:58 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include +#include + +#include "cryptlib.h" + +static void +OpenSSL_add_all_ciphers_internal(void) +{ +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cfb()); + EVP_add_cipher(EVP_des_cfb1()); + EVP_add_cipher(EVP_des_cfb8()); + EVP_add_cipher(EVP_des_ede_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb1()); + EVP_add_cipher(EVP_des_ede3_cfb8()); + + EVP_add_cipher(EVP_des_ofb()); + EVP_add_cipher(EVP_des_ede_ofb()); + EVP_add_cipher(EVP_des_ede3_ofb()); + + EVP_add_cipher(EVP_desx_cbc()); + EVP_add_cipher_alias(SN_desx_cbc, "DESX"); + EVP_add_cipher_alias(SN_desx_cbc, "desx"); + + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher_alias(SN_des_cbc, "DES"); + EVP_add_cipher_alias(SN_des_cbc, "des"); + EVP_add_cipher(EVP_des_ede_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); + EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); + EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); + + EVP_add_cipher(EVP_des_ecb()); + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); +#endif + +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); + EVP_add_cipher(EVP_rc4_40()); +#ifndef OPENSSL_NO_MD5 + EVP_add_cipher(EVP_rc4_hmac_md5()); +#endif +#endif + +#ifndef OPENSSL_NO_IDEA + EVP_add_cipher(EVP_idea_ecb()); + EVP_add_cipher(EVP_idea_cfb()); + EVP_add_cipher(EVP_idea_ofb()); + EVP_add_cipher(EVP_idea_cbc()); + EVP_add_cipher_alias(SN_idea_cbc, "IDEA"); + EVP_add_cipher_alias(SN_idea_cbc, "idea"); +#endif + +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_ecb()); + EVP_add_cipher(EVP_rc2_cfb()); + EVP_add_cipher(EVP_rc2_ofb()); + EVP_add_cipher(EVP_rc2_cbc()); + EVP_add_cipher(EVP_rc2_40_cbc()); + EVP_add_cipher(EVP_rc2_64_cbc()); + EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); + EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); +#endif + +#ifndef OPENSSL_NO_BF + EVP_add_cipher(EVP_bf_ecb()); + EVP_add_cipher(EVP_bf_cfb()); + EVP_add_cipher(EVP_bf_ofb()); + EVP_add_cipher(EVP_bf_cbc()); + EVP_add_cipher_alias(SN_bf_cbc, "BF"); + EVP_add_cipher_alias(SN_bf_cbc, "bf"); + EVP_add_cipher_alias(SN_bf_cbc, "blowfish"); +#endif + +#ifndef OPENSSL_NO_CAST + EVP_add_cipher(EVP_cast5_ecb()); + EVP_add_cipher(EVP_cast5_cfb()); + EVP_add_cipher(EVP_cast5_ofb()); + EVP_add_cipher(EVP_cast5_cbc()); + EVP_add_cipher_alias(SN_cast5_cbc, "CAST"); + EVP_add_cipher_alias(SN_cast5_cbc, "cast"); + EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc"); + EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc"); +#endif + +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_ecb()); + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_128_ccm()); + EVP_add_cipher(EVP_aes_128_cfb()); + EVP_add_cipher(EVP_aes_128_cfb1()); + EVP_add_cipher(EVP_aes_128_cfb8()); + EVP_add_cipher(EVP_aes_128_ofb()); + EVP_add_cipher(EVP_aes_128_ctr()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_128_wrap()); + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); + EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); + EVP_add_cipher(EVP_aes_192_ecb()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_192_ccm()); + EVP_add_cipher(EVP_aes_192_cfb()); + EVP_add_cipher(EVP_aes_192_cfb1()); + EVP_add_cipher(EVP_aes_192_cfb8()); + EVP_add_cipher(EVP_aes_192_ofb()); + EVP_add_cipher(EVP_aes_192_ctr()); + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher(EVP_aes_192_wrap()); + EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); + EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); + EVP_add_cipher(EVP_aes_256_ecb()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_256_ccm()); + EVP_add_cipher(EVP_aes_256_cfb()); + EVP_add_cipher(EVP_aes_256_cfb1()); + EVP_add_cipher(EVP_aes_256_cfb8()); + EVP_add_cipher(EVP_aes_256_ofb()); + EVP_add_cipher(EVP_aes_256_ctr()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_256_wrap()); + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +#endif +#endif + +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_ecb()); + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_128_cfb()); + EVP_add_cipher(EVP_camellia_128_cfb1()); + EVP_add_cipher(EVP_camellia_128_cfb8()); + EVP_add_cipher(EVP_camellia_128_ofb()); + EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128"); + EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128"); + EVP_add_cipher(EVP_camellia_192_ecb()); + EVP_add_cipher(EVP_camellia_192_cbc()); + EVP_add_cipher(EVP_camellia_192_cfb()); + EVP_add_cipher(EVP_camellia_192_cfb1()); + EVP_add_cipher(EVP_camellia_192_cfb8()); + EVP_add_cipher(EVP_camellia_192_ofb()); + EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192"); + EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192"); + EVP_add_cipher(EVP_camellia_256_ecb()); + EVP_add_cipher(EVP_camellia_256_cbc()); + EVP_add_cipher(EVP_camellia_256_cfb()); + EVP_add_cipher(EVP_camellia_256_cfb1()); + EVP_add_cipher(EVP_camellia_256_cfb8()); + EVP_add_cipher(EVP_camellia_256_ofb()); + EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); + EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); +#endif + +#ifndef OPENSSL_NO_CHACHA + EVP_add_cipher(EVP_chacha20()); +#endif +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + EVP_add_cipher(EVP_chacha20_poly1305()); +#endif + +#ifndef OPENSSL_NO_GOST + EVP_add_cipher(EVP_gost2814789_ecb()); + EVP_add_cipher(EVP_gost2814789_cfb64()); + EVP_add_cipher(EVP_gost2814789_cnt()); +#endif + +#ifndef OPENSSL_NO_SM4 + EVP_add_cipher(EVP_sm4_ecb()); + EVP_add_cipher(EVP_sm4_cbc()); + EVP_add_cipher(EVP_sm4_cfb()); + EVP_add_cipher(EVP_sm4_ofb()); + EVP_add_cipher(EVP_sm4_ctr()); + EVP_add_cipher_alias(SN_sm4_cbc, "SM4"); + EVP_add_cipher_alias(SN_sm4_cbc, "sm4"); +#endif +} + +void +OpenSSL_add_all_ciphers(void) +{ + static pthread_once_t add_all_ciphers_once = PTHREAD_ONCE_INIT; + (void) pthread_once(&add_all_ciphers_once, OpenSSL_add_all_ciphers_internal); +} + +static void +OpenSSL_add_all_digests_internal(void) +{ +#ifndef OPENSSL_NO_MD4 + EVP_add_digest(EVP_md4()); +#endif + +#ifndef OPENSSL_NO_MD5 + EVP_add_digest(EVP_md5()); + EVP_add_digest(EVP_md5_sha1()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); +#endif + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_digest(EVP_sha1()); + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +#endif + +#ifndef OPENSSL_NO_GOST + EVP_add_digest(EVP_gostr341194()); + EVP_add_digest(EVP_gost2814789imit()); + EVP_add_digest(EVP_streebog256()); + EVP_add_digest(EVP_streebog512()); +#endif +#ifndef OPENSSL_NO_RIPEMD + EVP_add_digest(EVP_ripemd160()); + EVP_add_digest_alias(SN_ripemd160, "ripemd"); + EVP_add_digest_alias(SN_ripemd160, "rmd160"); +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); + EVP_add_digest(EVP_sha512_224()); + EVP_add_digest(EVP_sha512_256()); +#endif +#ifndef OPENSSL_NO_SHA3 + EVP_add_digest(EVP_sha3_224()); + EVP_add_digest(EVP_sha3_256()); + EVP_add_digest(EVP_sha3_384()); + EVP_add_digest(EVP_sha3_512()); +#endif +#ifndef OPENSSL_NO_SM3 + EVP_add_digest(EVP_sm3()); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL + EVP_add_digest(EVP_whirlpool()); +#endif +} + +void +OpenSSL_add_all_digests(void) +{ + static pthread_once_t add_all_digests_once = PTHREAD_ONCE_INIT; + (void) pthread_once(&add_all_digests_once, OpenSSL_add_all_digests_internal); +} + +void +OPENSSL_add_all_algorithms_noconf(void) +{ + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +} + +void +OPENSSL_add_all_algorithms_conf(void) +{ + OPENSSL_add_all_algorithms_noconf(); + OPENSSL_config(NULL); +} diff --git a/Libraries/libressl/crypto/evp/cipher_method_lib.c b/Libraries/libressl/crypto/evp/cipher_method_lib.c new file mode 100644 index 000000000..c3f510fcc --- /dev/null +++ b/Libraries/libressl/crypto/evp/cipher_method_lib.c @@ -0,0 +1,178 @@ +/* $OpenBSD: cipher_method_lib.c,v 1.10 2023/07/07 19:37:53 beck Exp $ */ +/* + * Written by Richard Levitte (levitte@openssl.org) for the OpenSSL project + * 2015. + */ +/* ==================================================================== + * Copyright (c) 2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include "evp_local.h" + +EVP_CIPHER * +EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) +{ + EVP_CIPHER *cipher; + + if ((cipher = calloc(1, sizeof(*cipher))) == NULL) + return NULL; + + cipher->nid = cipher_type; + cipher->block_size = block_size; + cipher->key_len = key_len; + + return cipher; +} + +EVP_CIPHER * +EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) +{ + EVP_CIPHER *copy; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) + return NULL; + + *copy = *cipher; + + return copy; +} + +void +EVP_CIPHER_meth_free(EVP_CIPHER *cipher) +{ + free(cipher); +} + +int +EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) +{ + cipher->iv_len = iv_len; + + return 1; +} + +int +EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) +{ + cipher->flags = flags; + + return 1; +} + +int +EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size) +{ + cipher->ctx_size = ctx_size; + + return 1; +} + +int +EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc)) +{ + cipher->init = init; + + return 1; +} + +int +EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl)) +{ + cipher->do_cipher = do_cipher; + + return 1; +} + +int +EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup)(EVP_CIPHER_CTX *)) +{ + cipher->cleanup = cleanup; + + return 1; +} + +int +EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)) +{ + cipher->set_asn1_parameters = set_asn1_parameters; + + return 1; +} + +int +EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)) +{ + cipher->get_asn1_parameters = get_asn1_parameters; + + return 1; +} + +int +EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr)) +{ + cipher->ctrl = ctrl; + + return 1; +} diff --git a/Libraries/libressl/crypto/evp/digest.c b/Libraries/libressl/crypto/evp/digest.c new file mode 100644 index 000000000..ca3fb219c --- /dev/null +++ b/Libraries/libressl/crypto/evp/digest.c @@ -0,0 +1,429 @@ +/* $OpenBSD: digest.c,v 1.38 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "evp_local.h" + +int +EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) +{ + EVP_MD_CTX_init(ctx); + return EVP_DigestInit_ex(ctx, type, NULL); +} + +int +EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) +{ + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + +#ifndef OPENSSL_NO_ENGINE + /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts + * so this context may already have an ENGINE! Try to avoid releasing + * the previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unnecessary. */ + if (ctx->engine && ctx->digest && (!type || + (type && (type->type == ctx->digest->type)))) + goto skip_to_init; + if (type) { + /* Ensure an ENGINE left lying around from last time is cleared + * (the previous check attempted to avoid this if the same + * ENGINE and EVP_MD could be used). */ + ENGINE_finish(ctx->engine); + if (impl != NULL) { + if (!ENGINE_init(impl)) { + EVPerror(EVP_R_INITIALIZATION_ERROR); + return 0; + } + } else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_digest_engine(type->type); + if (impl != NULL) { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_MD *d = ENGINE_get_digest(impl, type->type); + if (d == NULL) { + /* Same comment from evp_enc.c */ + EVPerror(EVP_R_INITIALIZATION_ERROR); + ENGINE_finish(impl); + return 0; + } + /* We'll use the ENGINE's private digest definition */ + type = d; + /* Store the ENGINE functional reference so we know + * 'type' came from an ENGINE and we need to release + * it when done. */ + ctx->engine = impl; + } else + ctx->engine = NULL; + } else if (!ctx->digest) { + EVPerror(EVP_R_NO_DIGEST_SET); + return 0; + } +#endif + if (ctx->digest != type) { + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && + !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { + freezero(ctx->md_data, ctx->digest->ctx_size); + ctx->md_data = NULL; + } + ctx->digest = type; + if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { + ctx->update = type->update; + ctx->md_data = calloc(1, type->ctx_size); + if (ctx->md_data == NULL) { + EVP_PKEY_CTX_free(ctx->pctx); + ctx->pctx = NULL; + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + } + } +#ifndef OPENSSL_NO_ENGINE +skip_to_init: +#endif + if (ctx->pctx) { + int r; + r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); + if (r <= 0 && (r != -2)) + return 0; + } + if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) + return 1; + return ctx->digest->init(ctx); +} + +int +EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return ctx->update(ctx, data, count); +} + +/* The caller can assume that this removes any secret data from the context */ +int +EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ + int ret; + + ret = EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return ret; +} + +/* The caller can assume that this removes any secret data from the context */ +int +EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ + int ret; + + if ((size_t)ctx->digest->md_size > EVP_MAX_MD_SIZE) { + EVPerror(EVP_R_TOO_LARGE); + return 0; + } + ret = ctx->digest->final(ctx, md); + if (size != NULL) + *size = ctx->digest->md_size; + if (ctx->digest->cleanup) { + ctx->digest->cleanup(ctx); + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + } + memset(ctx->md_data, 0, ctx->digest->ctx_size); + return ret; +} + +int +EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) +{ + EVP_MD_CTX_init(out); + return EVP_MD_CTX_copy_ex(out, in); +} + +int +EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) +{ + unsigned char *tmp_buf; + + if ((in == NULL) || (in->digest == NULL)) { + EVPerror(EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a digest context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) { + EVPerror(ERR_R_ENGINE_LIB); + return 0; + } +#endif + + if (out->digest == in->digest) { + tmp_buf = out->md_data; + EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); + } else + tmp_buf = NULL; + EVP_MD_CTX_cleanup(out); + memcpy(out, in, sizeof *out); + out->md_data = NULL; + out->pctx = NULL; + + /* + * Because of the EVP_PKEY_CTX_dup() below, EVP_MD_CTX_cleanup() needs + * to free out->pctx in all cases (even if this flag is set on in). + */ + EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + + if (in->md_data && out->digest->ctx_size) { + if (tmp_buf) { + out->md_data = tmp_buf; + } else { + out->md_data = calloc(1, out->digest->ctx_size); + if (out->md_data == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + } + memcpy(out->md_data, in->md_data, out->digest->ctx_size); + } + + out->update = in->update; + + if (in->pctx) { + out->pctx = EVP_PKEY_CTX_dup(in->pctx); + if (!out->pctx) { + EVP_MD_CTX_cleanup(out); + return 0; + } + } + + if (out->digest->copy) + return out->digest->copy(out, in); + + return 1; +} + +int +EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl) +{ + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); + ret = EVP_DigestInit_ex(&ctx, type, impl) && + EVP_DigestUpdate(&ctx, data, count) && + EVP_DigestFinal_ex(&ctx, md, size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + +EVP_MD_CTX * +EVP_MD_CTX_new(void) +{ + return calloc(1, sizeof(EVP_MD_CTX)); +} + +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + if (ctx == NULL) + return; + + EVP_MD_CTX_cleanup(ctx); + + free(ctx); +} + +void +EVP_MD_CTX_init(EVP_MD_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +int +EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +{ + return EVP_MD_CTX_cleanup(ctx); +} + +EVP_MD_CTX * +EVP_MD_CTX_create(void) +{ + return EVP_MD_CTX_new(); +} + +void +EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_free(ctx); +} + +/* This call frees resources associated with the context */ +int +EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) +{ + /* + * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, + * because sometimes only copies of the context are ever finalised. + */ + if (ctx->digest && ctx->digest->cleanup && + !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) + ctx->digest->cleanup(ctx); + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && + !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) + freezero(ctx->md_data, ctx->digest->ctx_size); + /* + * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was + * called and its strange API contract implies we don't own ctx->pctx. + */ + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) + EVP_PKEY_CTX_free(ctx->pctx); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(ctx->engine); +#endif + memset(ctx, 0, sizeof(*ctx)); + + return 1; +} + +int +EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +{ + int ret; + + if (!ctx->digest) { + EVPerror(EVP_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->digest->md_ctrl) { + EVPerror(EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->digest->md_ctrl(ctx, type, arg, ptr); + if (ret == -1) { + EVPerror(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + return ret; +} diff --git a/Libraries/libressl/crypto/evp/e_aes.c b/Libraries/libressl/crypto/evp/e_aes.c new file mode 100644 index 000000000..3d357f011 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_aes.c @@ -0,0 +1,2602 @@ +/* $OpenBSD: e_aes.c,v 1.54 2023/09/28 11:29:10 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_AES +#include +#include +#include + +#include "evp_local.h" +#include "modes_local.h" + +typedef struct { + AES_KEY ks; + block128_f block; + union { + cbc128_f cbc; + ctr128_f ctr; + } stream; +} EVP_AES_KEY; + +typedef struct { + AES_KEY ks; /* AES key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + GCM128_CONTEXT gcm; + unsigned char *iv; /* Temporary IV store */ + int ivlen; /* IV length */ + int taglen; + int iv_gen; /* It is OK to generate IVs */ + int tls_aad_len; /* TLS AAD length */ + ctr128_f ctr; +} EVP_AES_GCM_CTX; + +typedef struct { + AES_KEY ks1, ks2; /* AES key schedules to use */ + XTS128_CONTEXT xts; + void (*stream)(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +} EVP_AES_XTS_CTX; + +typedef struct { + AES_KEY ks; /* AES key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + int tag_set; /* Set if tag is valid */ + int len_set; /* Set if message length set */ + int L, M; /* L and M parameters from RFC3610 */ + CCM128_CONTEXT ccm; + ccm128_f str; +} EVP_AES_CCM_CTX; + +#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) + +#ifdef VPAES_ASM +int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void vpaes_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void vpaes_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void vpaes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int enc); +#endif +#ifdef BSAES_ASM +void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, const unsigned char ivec[16]); +void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +#endif +#ifdef AES_CTR_ASM +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + const unsigned char ivec[AES_BLOCK_SIZE]); +#endif +#ifdef AES_XTS_ASM +void AES_xts_encrypt(const char *inp, char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); +void AES_xts_decrypt(const char *inp, char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); +#endif + +#if defined(AES_ASM) && ( \ + ((defined(__i386) || defined(__i386__) || \ + defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +#include "x86_arch.h" + +#ifdef VPAES_ASM +#define VPAES_CAPABLE (OPENSSL_cpu_caps() & CPUCAP_MASK_SSSE3) +#endif +#ifdef BSAES_ASM +#define BSAES_CAPABLE VPAES_CAPABLE +#endif +/* + * AES-NI section + */ +#define AESNI_CAPABLE (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI) + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aesni_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, int enc); +void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int enc); + +void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, const unsigned char *ivec); + +void aesni_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_ccm64_encrypt_blocks (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, const unsigned char ivec[16], + unsigned char cmac[16]); + +void aesni_ccm64_decrypt_blocks (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, const unsigned char ivec[16], + unsigned char cmac[16]); + +static int +aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && + !enc) { + ret = aesni_set_decrypt_key(key, ctx->key_len * 8, + ctx->cipher_data); + dat->block = (block128_f)aesni_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f)aesni_cbc_encrypt : NULL; + } else { + ret = aesni_set_encrypt_key(key, ctx->key_len * 8, + ctx->cipher_data); + dat->block = (block128_f)aesni_encrypt; + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks; + else + dat->stream.cbc = NULL; + } + + if (ret < 0) { + EVPerror(EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int +aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, + ctx->encrypt); + + return 1; +} + +static int +aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + + if (len < bl) + return 1; + + aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); + + return 1; +} + +static int +aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + + if (!iv && !key) + return 1; + if (key) { + aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f)aesni_encrypt); + gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks; + /* If we have an iv can set it directly, otherwise use + * saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +static int +aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + + if (!iv && !key) + return 1; + + if (key) { + /* key_len is two AES keys */ + if (enc) { + aesni_set_encrypt_key(key, ctx->key_len * 4, + &xctx->ks1); + xctx->xts.block1 = (block128_f)aesni_encrypt; + xctx->stream = aesni_xts_encrypt; + } else { + aesni_set_decrypt_key(key, ctx->key_len * 4, + &xctx->ks1); + xctx->xts.block1 = (block128_f)aesni_decrypt; + xctx->stream = aesni_xts_decrypt; + } + + aesni_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2); + xctx->xts.block2 = (block128_f)aesni_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +static int +aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + + if (!iv && !key) + return 1; + if (key) { + aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f)aesni_encrypt); + cctx->str = enc ? (ccm128_f)aesni_ccm64_encrypt_blocks : + (ccm128_f)aesni_ccm64_decrypt_blocks; + cctx->key_set = 1; + } + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +#endif + +static int +aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && + !enc) +#ifdef BSAES_CAPABLE + if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) { + ret = AES_set_decrypt_key(key, ctx->key_len * 8, + &dat->ks); + dat->block = (block128_f)AES_decrypt; + dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt; + } else +#endif +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, + &dat->ks); + dat->block = (block128_f)vpaes_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f)vpaes_cbc_encrypt : NULL; + } else +#endif + { + ret = AES_set_decrypt_key(key, ctx->key_len * 8, + &dat->ks); + dat->block = (block128_f)AES_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f)AES_cbc_encrypt : NULL; + } else +#ifdef BSAES_CAPABLE + if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) { + ret = AES_set_encrypt_key(key, ctx->key_len * 8, + &dat->ks); + dat->block = (block128_f)AES_encrypt; + dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks; + } else +#endif +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, + &dat->ks); + dat->block = (block128_f)vpaes_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f)vpaes_cbc_encrypt : NULL; + } else +#endif + { + ret = AES_set_encrypt_key(key, ctx->key_len * 8, + &dat->ks); + dat->block = (block128_f)AES_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f)AES_cbc_encrypt : NULL; +#ifdef AES_CTR_ASM + if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt; +#endif + } + + if (ret < 0) { + EVPerror(EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int +aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (dat->stream.cbc) + (*dat->stream.cbc)(in, out, len, &dat->ks, ctx->iv, + ctx->encrypt); + else if (ctx->encrypt) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, + dat->block); + else + CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, + dat->block); + + return 1; +} + +static int +aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + size_t i; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (len < bl) + return 1; + + for (i = 0, len -= bl; i <= len; i += bl) + (*dat->block)(in + i, out + i, &dat->ks); + + return 1; +} + +static int +aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num, + dat->block); + return 1; +} + +static int +aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num, + ctx->encrypt, dat->block); + return 1; +} + +static int +aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num, + ctx->encrypt, dat->block); + return 1; +} + +static int +aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) { + CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, ctx->iv, + &ctx->num, ctx->encrypt, dat->block); + return 1; + } + + while (len >= MAXBITCHUNK) { + CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK*8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + len -= MAXBITCHUNK; + in += MAXBITCHUNK; + out += MAXBITCHUNK; + } + if (len) + CRYPTO_cfb128_1_encrypt(in, out, len*8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + + return 1; +} + +static int +aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + unsigned int num = ctx->num; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (dat->stream.ctr) + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->stream.ctr); + else + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->block); + ctx->num = (size_t)num; + return 1; +} + + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_cbc = { + .nid = NID_aes_128_cbc, + .block_size = 16, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = aesni_init_key, + .do_cipher = aesni_cbc_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_cbc = { + .nid = NID_aes_128_cbc, + .block_size = 16, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = aes_init_key, + .do_cipher = aes_cbc_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_cbc(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_cbc : &aes_128_cbc; +#else + return &aes_128_cbc; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_ecb = { + .nid = NID_aes_128_ecb, + .block_size = 16, + .key_len = 16, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = aesni_init_key, + .do_cipher = aesni_ecb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_ecb = { + .nid = NID_aes_128_ecb, + .block_size = 16, + .key_len = 16, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = aes_init_key, + .do_cipher = aes_ecb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_ecb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_ecb : &aes_128_ecb; +#else + return &aes_128_ecb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_ofb = { + .nid = NID_aes_128_ofb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_ofb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_ofb = { + .nid = NID_aes_128_ofb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = aes_init_key, + .do_cipher = aes_ofb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_ofb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_ofb : &aes_128_ofb; +#else + return &aes_128_ofb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_cfb = { + .nid = NID_aes_128_cfb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_cfb = { + .nid = NID_aes_128_cfb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_cfb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_cfb : &aes_128_cfb; +#else + return &aes_128_cfb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_cfb1 = { + .nid = NID_aes_128_cfb1, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb1_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_cfb1 = { + .nid = NID_aes_128_cfb1, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb1_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_cfb1(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_cfb1 : &aes_128_cfb1; +#else + return &aes_128_cfb1; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_cfb8 = { + .nid = NID_aes_128_cfb8, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb8_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_cfb8 = { + .nid = NID_aes_128_cfb8, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb8_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_cfb8(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_cfb8 : &aes_128_cfb8; +#else + return &aes_128_cfb8; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_ctr = { + .nid = NID_aes_128_ctr, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = aesni_init_key, + .do_cipher = aes_ctr_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_128_ctr = { + .nid = NID_aes_128_ctr, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = aes_init_key, + .do_cipher = aes_ctr_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_128_ctr(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_ctr : &aes_128_ctr; +#else + return &aes_128_ctr; +#endif +} + + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_cbc = { + .nid = NID_aes_192_cbc, + .block_size = 16, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = aesni_init_key, + .do_cipher = aesni_cbc_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_cbc = { + .nid = NID_aes_192_cbc, + .block_size = 16, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = aes_init_key, + .do_cipher = aes_cbc_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_cbc(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_cbc : &aes_192_cbc; +#else + return &aes_192_cbc; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_ecb = { + .nid = NID_aes_192_ecb, + .block_size = 16, + .key_len = 24, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = aesni_init_key, + .do_cipher = aesni_ecb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_ecb = { + .nid = NID_aes_192_ecb, + .block_size = 16, + .key_len = 24, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = aes_init_key, + .do_cipher = aes_ecb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_ecb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_ecb : &aes_192_ecb; +#else + return &aes_192_ecb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_ofb = { + .nid = NID_aes_192_ofb128, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_ofb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_ofb = { + .nid = NID_aes_192_ofb128, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = aes_init_key, + .do_cipher = aes_ofb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_ofb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_ofb : &aes_192_ofb; +#else + return &aes_192_ofb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_cfb = { + .nid = NID_aes_192_cfb128, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_cfb = { + .nid = NID_aes_192_cfb128, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_cfb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_cfb : &aes_192_cfb; +#else + return &aes_192_cfb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_cfb1 = { + .nid = NID_aes_192_cfb1, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb1_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_cfb1 = { + .nid = NID_aes_192_cfb1, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb1_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_cfb1(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_cfb1 : &aes_192_cfb1; +#else + return &aes_192_cfb1; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_cfb8 = { + .nid = NID_aes_192_cfb8, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb8_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_cfb8 = { + .nid = NID_aes_192_cfb8, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb8_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_cfb8(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_cfb8 : &aes_192_cfb8; +#else + return &aes_192_cfb8; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_ctr = { + .nid = NID_aes_192_ctr, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = aesni_init_key, + .do_cipher = aes_ctr_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_192_ctr = { + .nid = NID_aes_192_ctr, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = aes_init_key, + .do_cipher = aes_ctr_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_192_ctr(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_ctr : &aes_192_ctr; +#else + return &aes_192_ctr; +#endif +} + + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_cbc = { + .nid = NID_aes_256_cbc, + .block_size = 16, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = aesni_init_key, + .do_cipher = aesni_cbc_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_cbc = { + .nid = NID_aes_256_cbc, + .block_size = 16, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = aes_init_key, + .do_cipher = aes_cbc_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_cbc(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_cbc : &aes_256_cbc; +#else + return &aes_256_cbc; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_ecb = { + .nid = NID_aes_256_ecb, + .block_size = 16, + .key_len = 32, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = aesni_init_key, + .do_cipher = aesni_ecb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_ecb = { + .nid = NID_aes_256_ecb, + .block_size = 16, + .key_len = 32, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = aes_init_key, + .do_cipher = aes_ecb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_ecb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_ecb : &aes_256_ecb; +#else + return &aes_256_ecb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_ofb = { + .nid = NID_aes_256_ofb128, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_ofb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_ofb = { + .nid = NID_aes_256_ofb128, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = aes_init_key, + .do_cipher = aes_ofb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_ofb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_ofb : &aes_256_ofb; +#else + return &aes_256_ofb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_cfb = { + .nid = NID_aes_256_cfb128, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_cfb = { + .nid = NID_aes_256_cfb128, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_cfb(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_cfb : &aes_256_cfb; +#else + return &aes_256_cfb; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_cfb1 = { + .nid = NID_aes_256_cfb1, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb1_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_cfb1 = { + .nid = NID_aes_256_cfb1, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb1_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_cfb1(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_cfb1 : &aes_256_cfb1; +#else + return &aes_256_cfb1; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_cfb8 = { + .nid = NID_aes_256_cfb8, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aesni_init_key, + .do_cipher = aes_cfb8_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_cfb8 = { + .nid = NID_aes_256_cfb8, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CFB_MODE, + .init = aes_init_key, + .do_cipher = aes_cfb8_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_cfb8(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_cfb8 : &aes_256_cfb8; +#else + return &aes_256_cfb8; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_ctr = { + .nid = NID_aes_256_ctr, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = aesni_init_key, + .do_cipher = aes_ctr_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; +#endif + +static const EVP_CIPHER aes_256_ctr = { + .nid = NID_aes_256_ctr, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = aes_init_key, + .do_cipher = aes_ctr_cipher, + .ctx_size = sizeof(EVP_AES_KEY), +}; + +const EVP_CIPHER * +EVP_aes_256_ctr(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_ctr : &aes_256_ctr; +#else + return &aes_256_ctr; +#endif +} + +static int +aes_gcm_cleanup(EVP_CIPHER_CTX *c) +{ + EVP_AES_GCM_CTX *gctx = c->cipher_data; + + if (gctx->iv != c->iv) + free(gctx->iv); + + explicit_bzero(gctx, sizeof(*gctx)); + + return 1; +} + +/* increment counter (64-bit int) by 1 */ +static void +ctr64_inc(unsigned char *counter) +{ + int n = 8; + unsigned char c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +static int +aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_GCM_CTX *gctx = c->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + gctx->key_set = 0; + gctx->iv_set = 0; + if (c->cipher->iv_len == 0) { + EVPerror(EVP_R_INVALID_IV_LENGTH); + return 0; + } + gctx->ivlen = c->cipher->iv_len; + gctx->iv = c->iv; + gctx->taglen = -1; + gctx->iv_gen = 0; + gctx->tls_aad_len = -1; + return 1; + + case EVP_CTRL_AEAD_GET_IVLEN: + *(int *)ptr = gctx->ivlen; + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg <= 0) + return 0; + /* Allocate memory for IV if needed */ + if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { + if (gctx->iv != c->iv) + free(gctx->iv); + gctx->iv = malloc(arg); + if (!gctx->iv) + return 0; + } + gctx->ivlen = arg; + return 1; + + case EVP_CTRL_GCM_SET_TAG: + if (arg <= 0 || arg > 16 || c->encrypt) + return 0; + memcpy(c->buf, ptr, arg); + gctx->taglen = arg; + return 1; + + case EVP_CTRL_GCM_GET_TAG: + if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) + return 0; + memcpy(ptr, c->buf, arg); + return 1; + + case EVP_CTRL_GCM_SET_IV_FIXED: + /* Special case: -1 length restores whole IV */ + if (arg == -1) { + memcpy(gctx->iv, ptr, gctx->ivlen); + gctx->iv_gen = 1; + return 1; + } + /* Fixed field must be at least 4 bytes and invocation field + * at least 8. + */ + if ((arg < 4) || (gctx->ivlen - arg) < 8) + return 0; + if (arg) + memcpy(gctx->iv, ptr, arg); + if (c->encrypt) + arc4random_buf(gctx->iv + arg, gctx->ivlen - arg); + gctx->iv_gen = 1; + return 1; + + case EVP_CTRL_GCM_IV_GEN: + if (gctx->iv_gen == 0 || gctx->key_set == 0) + return 0; + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) + arg = gctx->ivlen; + memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); + /* Invocation field will be at least 8 bytes in size and + * so no need to check wrap around or increment more than + * last 8 bytes. + */ + ctr64_inc(gctx->iv + gctx->ivlen - 8); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_GCM_SET_IV_INV: + if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) + return 0; + memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_AEAD_TLS1_AAD: + /* Save the AAD for later use */ + if (arg != 13) + return 0; + memcpy(c->buf, ptr, arg); + gctx->tls_aad_len = arg; + { + unsigned int len = c->buf[arg - 2] << 8 | + c->buf[arg - 1]; + + /* Correct length for explicit IV */ + if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) + return 0; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + + /* If decrypting correct for tag too */ + if (!c->encrypt) { + if (len < EVP_GCM_TLS_TAG_LEN) + return 0; + len -= EVP_GCM_TLS_TAG_LEN; + } + c->buf[arg - 2] = len >> 8; + c->buf[arg - 1] = len & 0xff; + } + /* Extra padding: tag appended to record */ + return EVP_GCM_TLS_TAG_LEN; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_GCM_CTX *gctx_out = out->cipher_data; + + if (gctx->gcm.key) { + if (gctx->gcm.key != &gctx->ks) + return 0; + gctx_out->gcm.key = &gctx_out->ks; + } + + if (gctx->iv == c->iv) { + gctx_out->iv = out->iv; + } else { + if ((gctx_out->iv = calloc(1, gctx->ivlen)) == NULL) + return 0; + memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + + } +} + +static ctr128_f +aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx, + const unsigned char *key, size_t key_len) +{ +#ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) { + AES_set_encrypt_key(key, key_len * 8, aes_key); + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt); + return (ctr128_f)bsaes_ctr32_encrypt_blocks; + } else +#endif +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + vpaes_set_encrypt_key(key, key_len * 8, aes_key); + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt); + return NULL; + } else +#endif + (void)0; /* terminate potentially open 'else' */ + + AES_set_encrypt_key(key, key_len * 8, aes_key); + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt); +#ifdef AES_CTR_ASM + return (ctr128_f)AES_ctr32_encrypt; +#else + return NULL; +#endif +} + +static int +aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + + if (!iv && !key) + return 1; + if (key) { + gctx->ctr = aes_gcm_set_key(&gctx->ks, &gctx->gcm, + key, ctx->key_len); + + /* If we have an iv can set it directly, otherwise use + * saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +/* Handle TLS GCM packet format. This consists of the last portion of the IV + * followed by the payload and finally the tag. On encrypt generate IV, + * encrypt payload and write the tag. On verify retrieve IV, decrypt payload + * and verify tag. + */ + +static int +aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + int rv = -1; + + /* Encrypt/decrypt must be performed in place */ + if (out != in || + len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) + return -1; + + /* Set IV from start of buffer or generate IV and write to start + * of buffer. + */ + if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? + EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, + EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) + goto err; + + /* Use saved AAD */ + if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) + goto err; + + /* Fix buffer and length to point to payload */ + in += EVP_GCM_TLS_EXPLICIT_IV_LEN; + out += EVP_GCM_TLS_EXPLICIT_IV_LEN; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + if (ctx->encrypt) { + /* Encrypt payload */ + if (gctx->ctr) { + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in, out, + len, gctx->ctr)) + goto err; + } else { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) + goto err; + } + out += len; + + /* Finally write tag */ + CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); + rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + } else { + /* Decrypt */ + if (gctx->ctr) { + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in, out, + len, gctx->ctr)) + goto err; + } else { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) + goto err; + } + /* Retrieve tag */ + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); + + /* If tag mismatch wipe buffer */ + if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { + explicit_bzero(out, len); + goto err; + } + rv = len; + } + +err: + gctx->iv_set = 0; + gctx->tls_aad_len = -1; + return rv; +} + +static int +aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + + /* If not set up, return error */ + if (!gctx->key_set) + return -1; + + if (gctx->tls_aad_len >= 0) + return aes_gcm_tls_cipher(ctx, out, in, len); + + if (!gctx->iv_set) + return -1; + + if (in) { + if (out == NULL) { + if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) + return -1; + } else if (ctx->encrypt) { + if (gctx->ctr) { + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, + in, out, len, gctx->ctr)) + return -1; + } else { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, + in, out, len)) + return -1; + } + } else { + if (gctx->ctr) { + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, + in, out, len, gctx->ctr)) + return -1; + } else { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, + in, out, len)) + return -1; + } + } + return len; + } else { + if (!ctx->encrypt) { + if (gctx->taglen < 0) + return -1; + if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, + gctx->taglen) != 0) + return -1; + gctx->iv_set = 0; + return 0; + } + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); + gctx->taglen = 16; + + /* Don't reuse the IV */ + gctx->iv_set = 0; + return 0; + } + +} + +#define CUSTOM_FLAGS \ + ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \ + EVP_CIPH_FLAG_CUSTOM_IV_LENGTH | \ + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | \ + EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY ) + + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_gcm = { + .nid = NID_aes_128_gcm, + .block_size = 1, + .key_len = 16, + .iv_len = 12, + .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, + .init = aesni_gcm_init_key, + .do_cipher = aes_gcm_cipher, + .cleanup = aes_gcm_cleanup, + .ctx_size = sizeof(EVP_AES_GCM_CTX), + .ctrl = aes_gcm_ctrl, +}; +#endif + +static const EVP_CIPHER aes_128_gcm = { + .nid = NID_aes_128_gcm, + .block_size = 1, + .key_len = 16, + .iv_len = 12, + .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, + .init = aes_gcm_init_key, + .do_cipher = aes_gcm_cipher, + .cleanup = aes_gcm_cleanup, + .ctx_size = sizeof(EVP_AES_GCM_CTX), + .ctrl = aes_gcm_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_128_gcm(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_gcm : &aes_128_gcm; +#else + return &aes_128_gcm; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_gcm = { + .nid = NID_aes_192_gcm, + .block_size = 1, + .key_len = 24, + .iv_len = 12, + .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, + .init = aesni_gcm_init_key, + .do_cipher = aes_gcm_cipher, + .cleanup = aes_gcm_cleanup, + .ctx_size = sizeof(EVP_AES_GCM_CTX), + .ctrl = aes_gcm_ctrl, +}; +#endif + +static const EVP_CIPHER aes_192_gcm = { + .nid = NID_aes_192_gcm, + .block_size = 1, + .key_len = 24, + .iv_len = 12, + .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, + .init = aes_gcm_init_key, + .do_cipher = aes_gcm_cipher, + .cleanup = aes_gcm_cleanup, + .ctx_size = sizeof(EVP_AES_GCM_CTX), + .ctrl = aes_gcm_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_192_gcm(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_gcm : &aes_192_gcm; +#else + return &aes_192_gcm; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_gcm = { + .nid = NID_aes_256_gcm, + .block_size = 1, + .key_len = 32, + .iv_len = 12, + .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, + .init = aesni_gcm_init_key, + .do_cipher = aes_gcm_cipher, + .cleanup = aes_gcm_cleanup, + .ctx_size = sizeof(EVP_AES_GCM_CTX), + .ctrl = aes_gcm_ctrl, +}; +#endif + +static const EVP_CIPHER aes_256_gcm = { + .nid = NID_aes_256_gcm, + .block_size = 1, + .key_len = 32, + .iv_len = 12, + .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, + .init = aes_gcm_init_key, + .do_cipher = aes_gcm_cipher, + .cleanup = aes_gcm_cleanup, + .ctx_size = sizeof(EVP_AES_GCM_CTX), + .ctrl = aes_gcm_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_256_gcm(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_gcm : &aes_256_gcm; +#else + return &aes_256_gcm; +#endif +} + +static int +aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_XTS_CTX *xctx = c->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + /* + * key1 and key2 are used as an indicator both key and IV + * are set + */ + xctx->xts.key1 = NULL; + xctx->xts.key2 = NULL; + return 1; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_XTS_CTX *xctx_out = out->cipher_data; + + if (xctx->xts.key1) { + if (xctx->xts.key1 != &xctx->ks1) + return 0; + xctx_out->xts.key1 = &xctx_out->ks1; + } + if (xctx->xts.key2) { + if (xctx->xts.key2 != &xctx->ks2) + return 0; + xctx_out->xts.key2 = &xctx_out->ks2; + } + return 1; + } + } + return -1; +} + +static int +aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + + if (!iv && !key) + return 1; + + if (key) do { +#ifdef AES_XTS_ASM + xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; +#else + xctx->stream = NULL; +#endif + /* key_len is two AES keys */ +#ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) + xctx->stream = enc ? bsaes_xts_encrypt : + bsaes_xts_decrypt; + else +#endif +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + if (enc) { + vpaes_set_encrypt_key(key, ctx->key_len * 4, + &xctx->ks1); + xctx->xts.block1 = (block128_f)vpaes_encrypt; + } else { + vpaes_set_decrypt_key(key, ctx->key_len * 4, + &xctx->ks1); + xctx->xts.block1 = (block128_f)vpaes_decrypt; + } + + vpaes_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2); + xctx->xts.block2 = (block128_f)vpaes_encrypt; + + xctx->xts.key1 = &xctx->ks1; + break; + } else +#endif + (void)0; /* terminate potentially open 'else' */ + + if (enc) { + AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f)AES_encrypt; + } else { + AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f)AES_decrypt; + } + + AES_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2); + xctx->xts.block2 = (block128_f)AES_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } while (0); + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +static int +aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + + if (!xctx->xts.key1 || !xctx->xts.key2) + return 0; + if (!out || !in || len < AES_BLOCK_SIZE) + return 0; + + if (xctx->stream) + (*xctx->stream)(in, out, len, xctx->xts.key1, xctx->xts.key2, + ctx->iv); + else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, + ctx->encrypt)) + return 0; + return 1; +} + +#define XTS_FLAGS \ + ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \ + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY ) + + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_xts = { + .nid = NID_aes_128_xts, + .block_size = 1, + .key_len = 2 * 16, + .iv_len = 16, + .flags = XTS_FLAGS | EVP_CIPH_XTS_MODE, + .init = aesni_xts_init_key, + .do_cipher = aes_xts_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_XTS_CTX), + .ctrl = aes_xts_ctrl, +}; +#endif + +static const EVP_CIPHER aes_128_xts = { + .nid = NID_aes_128_xts, + .block_size = 1, + .key_len = 2 * 16, + .iv_len = 16, + .flags = XTS_FLAGS | EVP_CIPH_XTS_MODE, + .init = aes_xts_init_key, + .do_cipher = aes_xts_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_XTS_CTX), + .ctrl = aes_xts_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_128_xts(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_xts : &aes_128_xts; +#else + return &aes_128_xts; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_xts = { + .nid = NID_aes_256_xts, + .block_size = 1, + .key_len = 2 * 32, + .iv_len = 16, + .flags = XTS_FLAGS | EVP_CIPH_XTS_MODE, + .init = aesni_xts_init_key, + .do_cipher = aes_xts_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_XTS_CTX), + .ctrl = aes_xts_ctrl, +}; +#endif + +static const EVP_CIPHER aes_256_xts = { + .nid = NID_aes_256_xts, + .block_size = 1, + .key_len = 2 * 32, + .iv_len = 16, + .flags = XTS_FLAGS | EVP_CIPH_XTS_MODE, + .init = aes_xts_init_key, + .do_cipher = aes_xts_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_XTS_CTX), + .ctrl = aes_xts_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_256_xts(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_xts : &aes_256_xts; +#else + return &aes_256_xts; +#endif +} + +static int +aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_CCM_CTX *cctx = c->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + cctx->key_set = 0; + cctx->iv_set = 0; + cctx->L = 8; + cctx->M = 12; + cctx->tag_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_AEAD_GET_IVLEN: + *(int *)ptr = 15 - cctx->L; + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: + arg = 15 - arg; + + case EVP_CTRL_CCM_SET_L: + if (arg < 2 || arg > 8) + return 0; + cctx->L = arg; + return 1; + + case EVP_CTRL_CCM_SET_TAG: + if ((arg & 1) || arg < 4 || arg > 16) + return 0; + if ((c->encrypt && ptr) || (!c->encrypt && !ptr)) + return 0; + if (ptr) { + cctx->tag_set = 1; + memcpy(c->buf, ptr, arg); + } + cctx->M = arg; + return 1; + + case EVP_CTRL_CCM_GET_TAG: + if (!c->encrypt || !cctx->tag_set) + return 0; + if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) + return 0; + cctx->tag_set = 0; + cctx->iv_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_CCM_CTX *cctx_out = out->cipher_data; + + if (cctx->ccm.key) { + if (cctx->ccm.key != &cctx->ks) + return 0; + cctx_out->ccm.key = &cctx_out->ks; + } + return 1; + } + + default: + return -1; + } +} + +static int +aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + + if (!iv && !key) + return 1; + if (key) do { +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f)vpaes_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + break; + } +#endif + AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f)AES_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + } while (0); + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +static int +aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + CCM128_CONTEXT *ccm = &cctx->ccm; + + /* If not set up, return error */ + if (!cctx->iv_set && !cctx->key_set) + return -1; + if (!ctx->encrypt && !cctx->tag_set) + return -1; + + if (!out) { + if (!in) { + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, + len)) + return -1; + cctx->len_set = 1; + return len; + } + /* If have AAD need message length */ + if (!cctx->len_set && len) + return -1; + CRYPTO_ccm128_aad(ccm, in, len); + return len; + } + /* EVP_*Final() doesn't return any data */ + if (!in) + return 0; + /* If not set length yet do it */ + if (!cctx->len_set) { + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + } + if (ctx->encrypt) { + if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, + cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) + return -1; + cctx->tag_set = 1; + return len; + } else { + int rv = -1; + if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, + cctx->str) : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { + unsigned char tag[16]; + if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { + if (!memcmp(tag, ctx->buf, cctx->M)) + rv = len; + } + } + if (rv == -1) + explicit_bzero(out, len); + cctx->iv_set = 0; + cctx->tag_set = 0; + cctx->len_set = 0; + return rv; + } + +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_128_ccm = { + .nid = NID_aes_128_ccm, + .block_size = 1, + .key_len = 16, + .iv_len = 12, + .flags = CUSTOM_FLAGS | EVP_CIPH_CCM_MODE, + .init = aesni_ccm_init_key, + .do_cipher = aes_ccm_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_CCM_CTX), + .ctrl = aes_ccm_ctrl, +}; +#endif + +static const EVP_CIPHER aes_128_ccm = { + .nid = NID_aes_128_ccm, + .block_size = 1, + .key_len = 16, + .iv_len = 12, + .flags = CUSTOM_FLAGS | EVP_CIPH_CCM_MODE, + .init = aes_ccm_init_key, + .do_cipher = aes_ccm_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_CCM_CTX), + .ctrl = aes_ccm_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_128_ccm(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_128_ccm : &aes_128_ccm; +#else + return &aes_128_ccm; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_192_ccm = { + .nid = NID_aes_192_ccm, + .block_size = 1, + .key_len = 24, + .iv_len = 12, + .flags = CUSTOM_FLAGS | EVP_CIPH_CCM_MODE, + .init = aesni_ccm_init_key, + .do_cipher = aes_ccm_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_CCM_CTX), + .ctrl = aes_ccm_ctrl, +}; +#endif + +static const EVP_CIPHER aes_192_ccm = { + .nid = NID_aes_192_ccm, + .block_size = 1, + .key_len = 24, + .iv_len = 12, + .flags = CUSTOM_FLAGS | EVP_CIPH_CCM_MODE, + .init = aes_ccm_init_key, + .do_cipher = aes_ccm_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_CCM_CTX), + .ctrl = aes_ccm_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_192_ccm(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_192_ccm : &aes_192_ccm; +#else + return &aes_192_ccm; +#endif +} + +#ifdef AESNI_CAPABLE +static const EVP_CIPHER aesni_256_ccm = { + .nid = NID_aes_256_ccm, + .block_size = 1, + .key_len = 32, + .iv_len = 12, + .flags = CUSTOM_FLAGS | EVP_CIPH_CCM_MODE, + .init = aesni_ccm_init_key, + .do_cipher = aes_ccm_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_CCM_CTX), + .ctrl = aes_ccm_ctrl, +}; +#endif + +static const EVP_CIPHER aes_256_ccm = { + .nid = NID_aes_256_ccm, + .block_size = 1, + .key_len = 32, + .iv_len = 12, + .flags = CUSTOM_FLAGS | EVP_CIPH_CCM_MODE, + .init = aes_ccm_init_key, + .do_cipher = aes_ccm_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_CCM_CTX), + .ctrl = aes_ccm_ctrl, +}; + +const EVP_CIPHER * +EVP_aes_256_ccm(void) +{ +#ifdef AESNI_CAPABLE + return AESNI_CAPABLE ? &aesni_256_ccm : &aes_256_ccm; +#else + return &aes_256_ccm; +#endif +} + +#define EVP_AEAD_AES_GCM_TAG_LEN 16 + +struct aead_aes_gcm_ctx { + union { + double align; + AES_KEY ks; + } ks; + GCM128_CONTEXT gcm; + ctr128_f ctr; + unsigned char tag_len; +}; + +static int +aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len, + size_t tag_len) +{ + struct aead_aes_gcm_ctx *gcm_ctx; + const size_t key_bits = key_len * 8; + + /* EVP_AEAD_CTX_init should catch this. */ + if (key_bits != 128 && key_bits != 256) { + EVPerror(EVP_R_BAD_KEY_LENGTH); + return 0; + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) + tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + + if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) { + EVPerror(EVP_R_TAG_TOO_LARGE); + return 0; + } + + if ((gcm_ctx = calloc(1, sizeof(struct aead_aes_gcm_ctx))) == NULL) + return 0; + +#ifdef AESNI_CAPABLE + if (AESNI_CAPABLE) { + aesni_set_encrypt_key(key, key_bits, &gcm_ctx->ks.ks); + CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks, + (block128_f)aesni_encrypt); + gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; + } else +#endif + { + gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, + key, key_len); + } + gcm_ctx->tag_len = tag_len; + ctx->aead_state = gcm_ctx; + + return 1; +} + +static void +aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx) +{ + struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + + freezero(gcm_ctx, sizeof(*gcm_ctx)); +} + +static int +aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, + size_t max_out_len, const unsigned char *nonce, size_t nonce_len, + const unsigned char *in, size_t in_len, const unsigned char *ad, + size_t ad_len) +{ + const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + GCM128_CONTEXT gcm; + size_t bulk = 0; + + if (max_out_len < in_len + gcm_ctx->tag_len) { + EVPerror(EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); + + if (nonce_len == 0) { + EVPerror(EVP_R_INVALID_IV_LENGTH); + return 0; + } + CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); + + if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len)) + return 0; + + if (gcm_ctx->ctr) { + if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, + in_len - bulk, gcm_ctx->ctr)) + return 0; + } else { + if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk, + in_len - bulk)) + return 0; + } + + CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len); + *out_len = in_len + gcm_ctx->tag_len; + + return 1; +} + +static int +aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, + size_t max_out_len, const unsigned char *nonce, size_t nonce_len, + const unsigned char *in, size_t in_len, const unsigned char *ad, + size_t ad_len) +{ + const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN]; + GCM128_CONTEXT gcm; + size_t plaintext_len; + size_t bulk = 0; + + if (in_len < gcm_ctx->tag_len) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + + plaintext_len = in_len - gcm_ctx->tag_len; + + if (max_out_len < plaintext_len) { + EVPerror(EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); + + if (nonce_len == 0) { + EVPerror(EVP_R_INVALID_IV_LENGTH); + return 0; + } + CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); + + if (CRYPTO_gcm128_aad(&gcm, ad, ad_len)) + return 0; + + if (gcm_ctx->ctr) { + if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, + in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr)) + return 0; + } else { + if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk, + in_len - bulk - gcm_ctx->tag_len)) + return 0; + } + + CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len); + if (timingsafe_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + + *out_len = plaintext_len; + + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm = { + .key_len = 16, + .nonce_len = 12, + .overhead = EVP_AEAD_AES_GCM_TAG_LEN, + .max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN, + + .init = aead_aes_gcm_init, + .cleanup = aead_aes_gcm_cleanup, + .seal = aead_aes_gcm_seal, + .open = aead_aes_gcm_open, +}; + +static const EVP_AEAD aead_aes_256_gcm = { + .key_len = 32, + .nonce_len = 12, + .overhead = EVP_AEAD_AES_GCM_TAG_LEN, + .max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN, + + .init = aead_aes_gcm_init, + .cleanup = aead_aes_gcm_cleanup, + .seal = aead_aes_gcm_seal, + .open = aead_aes_gcm_open, +}; + +const EVP_AEAD * +EVP_aead_aes_128_gcm(void) +{ + return &aead_aes_128_gcm; +} + +const EVP_AEAD * +EVP_aead_aes_256_gcm(void) +{ + return &aead_aes_256_gcm; +} + +typedef struct { + union { + double align; + AES_KEY ks; + } ks; + unsigned char *iv; +} EVP_AES_WRAP_CTX; + +static int +aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_WRAP_CTX *wctx = (EVP_AES_WRAP_CTX *)ctx->cipher_data; + + if (iv == NULL && key == NULL) + return 1; + + if (key != NULL) { + if (ctx->encrypt) + AES_set_encrypt_key(key, 8 * ctx->key_len, + &wctx->ks.ks); + else + AES_set_decrypt_key(key, 8 * ctx->key_len, + &wctx->ks.ks); + + if (iv == NULL) + wctx->iv = NULL; + } + + if (iv != NULL) { + memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + wctx->iv = ctx->iv; + } + + return 1; +} + +static int +aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inlen) +{ + EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; + int ret; + + if (in == NULL) + return 0; + + if (inlen % 8 != 0) + return -1; + if (ctx->encrypt && inlen < 8) + return -1; + if (!ctx->encrypt && inlen < 16) + return -1; + if (inlen > INT_MAX) + return -1; + + if (out == NULL) { + if (ctx->encrypt) + return inlen + 8; + else + return inlen - 8; + } + + if (ctx->encrypt) + ret = AES_wrap_key(&wctx->ks.ks, wctx->iv, out, in, + (unsigned int)inlen); + else + ret = AES_unwrap_key(&wctx->ks.ks, wctx->iv, out, in, + (unsigned int)inlen); + + return ret != 0 ? ret : -1; +} + +static int +aes_wrap_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_WRAP_CTX *wctx = c->cipher_data; + + switch (type) { + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_WRAP_CTX *wctx_out = out->cipher_data; + + if (wctx->iv != NULL) { + if (c->iv != wctx->iv) + return 0; + + wctx_out->iv = out->iv; + } + + return 1; + } + } + + return -1; +} + +#define WRAP_FLAGS \ + ( EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | \ + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 | \ + EVP_CIPH_CUSTOM_COPY ) + +static const EVP_CIPHER aes_128_wrap = { + .nid = NID_id_aes128_wrap, + .block_size = 8, + .key_len = 16, + .iv_len = 8, + .flags = WRAP_FLAGS, + .init = aes_wrap_init_key, + .do_cipher = aes_wrap_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_WRAP_CTX), + .set_asn1_parameters = NULL, + .get_asn1_parameters = NULL, + .ctrl = aes_wrap_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_aes_128_wrap(void) +{ + return &aes_128_wrap; +} + +static const EVP_CIPHER aes_192_wrap = { + .nid = NID_id_aes192_wrap, + .block_size = 8, + .key_len = 24, + .iv_len = 8, + .flags = WRAP_FLAGS, + .init = aes_wrap_init_key, + .do_cipher = aes_wrap_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_WRAP_CTX), + .set_asn1_parameters = NULL, + .get_asn1_parameters = NULL, + .ctrl = aes_wrap_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_aes_192_wrap(void) +{ + return &aes_192_wrap; +} + +static const EVP_CIPHER aes_256_wrap = { + .nid = NID_id_aes256_wrap, + .block_size = 8, + .key_len = 32, + .iv_len = 8, + .flags = WRAP_FLAGS, + .init = aes_wrap_init_key, + .do_cipher = aes_wrap_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_AES_WRAP_CTX), + .set_asn1_parameters = NULL, + .get_asn1_parameters = NULL, + .ctrl = aes_wrap_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_aes_256_wrap(void) +{ + return &aes_256_wrap; +} + +#endif diff --git a/Libraries/libressl/crypto/evp/e_aes_cbc_hmac_sha1.c b/Libraries/libressl/crypto/evp/e_aes_cbc_hmac_sha1.c new file mode 100644 index 000000000..09a73da74 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -0,0 +1,604 @@ +/* $OpenBSD: e_aes_cbc_hmac_sha1.c,v 1.19 2023/07/07 19:37:53 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include + +#include + +#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1) + +#include +#include +#include +#include + +#include "constant_time.h" +#include "evp_local.h" + +#define TLS1_1_VERSION 0x0302 + +typedef struct { + AES_KEY ks; + SHA_CTX head, tail, md; + size_t payload_length; /* AAD length in decrypt case */ + union { + unsigned int tls_ver; + unsigned char tls_aad[16]; /* 13 used */ + } aux; +} EVP_AES_HMAC_SHA1; + +#define NO_PAYLOAD_LENGTH ((size_t)-1) + +#if defined(AES_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +#include "x86_arch.h" + +#if defined(__GNUC__) && __GNUC__>=2 +# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; }) +#endif + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); + +void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int enc); + +void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks, + const AES_KEY *key, unsigned char iv[16], SHA_CTX *ctx, const void *in0); + +#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data) + +static int +aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + int ret; + + if (enc) + ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); + else + ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); + + SHA1_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return ret < 0 ? 0 : 1; +} + +#define STITCHED_CALL + +#if !defined(STITCHED_CALL) +#define aes_off 0 +#endif + +void sha1_block_data_order (void *c, const void *p, size_t len); + +static void +sha1_update(SHA_CTX *c, const void *data, size_t len) +{ + const unsigned char *ptr = data; + size_t res; + + if ((res = c->num)) { + res = SHA_CBLOCK - res; + if (len < res) + res = len; + SHA1_Update(c, ptr, res); + ptr += res; + len -= res; + } + + res = len % SHA_CBLOCK; + len -= res; + + if (len) { + sha1_block_data_order(c, ptr, len / SHA_CBLOCK); + + ptr += len; + c->Nh += len >> 29; + c->Nl += len <<= 3; + if (c->Nl < (unsigned int)len) + c->Nh++; + } + + if (res) + SHA1_Update(c, ptr, res); +} + +#ifdef SHA1_Update +#undef SHA1_Update +#endif +#define SHA1_Update sha1_update + +static int +aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + unsigned int l; + size_t plen = key->payload_length, + iv = 0, /* explicit IV in TLS 1.1 and later */ + sha_off = 0; +#if defined(STITCHED_CALL) + size_t aes_off = 0, blocks; + + sha_off = SHA_CBLOCK - key->md.num; +#endif + + key->payload_length = NO_PAYLOAD_LENGTH; + + if (len % AES_BLOCK_SIZE) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; + else if (len != ((plen + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE) & + -AES_BLOCK_SIZE)) + return 0; + else if (key->aux.tls_ver >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + +#if defined(STITCHED_CALL) + if (plen > (sha_off + iv) && + (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { + SHA1_Update(&key->md, in + iv, sha_off); + + aesni_cbc_sha1_enc(in, out, blocks, &key->ks, + ctx->iv, &key->md, in + iv + sha_off); + blocks *= SHA_CBLOCK; + aes_off += blocks; + sha_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + sha_off = 0; + } +#endif + sha_off += iv; + SHA1_Update(&key->md, in + sha_off, plen - sha_off); + + if (plen != len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + aes_off, in + aes_off, + plen - aes_off); + + /* calculate HMAC and append it to payload */ + SHA1_Final(out + plen, &key->md); + key->md = key->tail; + SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH); + SHA1_Final(out + plen, &key->md); + + /* pad the payload|hmac */ + plen += SHA_DIGEST_LENGTH; + for (l = len - plen - 1; plen < len; plen++) + out[plen] = l; + + /* encrypt HMAC|padding at once */ + aesni_cbc_encrypt(out + aes_off, out + aes_off, + len - aes_off, &key->ks, ctx->iv, 1); + } else { + aesni_cbc_encrypt(in + aes_off, out + aes_off, + len - aes_off, &key->ks, ctx->iv, 1); + } + } else { + union { + unsigned int u[SHA_DIGEST_LENGTH/sizeof(unsigned int)]; + unsigned char c[32 + SHA_DIGEST_LENGTH]; + } mac, *pmac; + + /* arrange cache line alignment */ + pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32)); + + /* decrypt HMAC|padding at once */ + aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); + + if (plen == 0 || plen == NO_PAYLOAD_LENGTH) { + SHA1_Update(&key->md, out, len); + } else if (plen < 4) { + return 0; + } else { /* "TLS" mode of operation */ + size_t inp_len, mask, j, i; + unsigned int res, maxpad, pad, bitlen; + int ret = 1; + union { + unsigned int u[SHA_LBLOCK]; + unsigned char c[SHA_CBLOCK]; + } + *data = (void *)key->md.data; + + if ((key->aux.tls_aad[plen - 4] << 8 | + key->aux.tls_aad[plen - 3]) >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + + if (len < (iv + SHA_DIGEST_LENGTH + 1)) + return 0; + + /* omit explicit iv */ + out += iv; + len -= iv; + + /* figure out payload length */ + pad = out[len - 1]; + maxpad = len - (SHA_DIGEST_LENGTH + 1); + maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); + maxpad &= 255; + + ret &= constant_time_ge(maxpad, pad); + + inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); + mask = (0 - ((inp_len - len) >> + (sizeof(inp_len) * 8 - 1))); + inp_len &= mask; + ret &= (int)mask; + + key->aux.tls_aad[plen - 2] = inp_len >> 8; + key->aux.tls_aad[plen - 1] = inp_len; + + /* calculate HMAC */ + key->md = key->head; + SHA1_Update(&key->md, key->aux.tls_aad, plen); + +#if 1 + len -= SHA_DIGEST_LENGTH; /* amend mac */ + if (len >= (256 + SHA_CBLOCK)) { + j = (len - (256 + SHA_CBLOCK)) & + (0 - SHA_CBLOCK); + j += SHA_CBLOCK - key->md.num; + SHA1_Update(&key->md, out, j); + out += j; + len -= j; + inp_len -= j; + } + + /* but pretend as if we hashed padded payload */ + bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ +#ifdef BSWAP + bitlen = BSWAP(bitlen); +#else + mac.c[0] = 0; + mac.c[1] = (unsigned char)(bitlen >> 16); + mac.c[2] = (unsigned char)(bitlen >> 8); + mac.c[3] = (unsigned char)bitlen; + bitlen = mac.u[0]; +#endif + + pmac->u[0] = 0; + pmac->u[1] = 0; + pmac->u[2] = 0; + pmac->u[3] = 0; + pmac->u[4] = 0; + + for (res = key->md.num, j = 0; j < len; j++) { + size_t c = out[j]; + mask = (j - inp_len) >> (sizeof(j) * 8 - 8); + c &= mask; + c |= 0x80 & ~mask & + ~((inp_len - j) >> (sizeof(j) * 8 - 8)); + data->c[res++] = (unsigned char)c; + + if (res != SHA_CBLOCK) + continue; + + /* j is not incremented yet */ + mask = 0 - ((inp_len + 7 - j) >> + (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen&mask; + sha1_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 72) >> + (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + res = 0; + } + + for (i = res; i < SHA_CBLOCK; i++, j++) + data->c[i] = 0; + + if (res > SHA_CBLOCK - 8) { + mask = 0 - ((inp_len + 8 - j) >> + (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha1_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 73) >> + (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + + memset(data, 0, SHA_CBLOCK); + j += 64; + } + data->u[SHA_LBLOCK - 1] = bitlen; + sha1_block_data_order(&key->md, data, 1); + mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + +#ifdef BSWAP + pmac->u[0] = BSWAP(pmac->u[0]); + pmac->u[1] = BSWAP(pmac->u[1]); + pmac->u[2] = BSWAP(pmac->u[2]); + pmac->u[3] = BSWAP(pmac->u[3]); + pmac->u[4] = BSWAP(pmac->u[4]); +#else + for (i = 0; i < 5; i++) { + res = pmac->u[i]; + pmac->c[4 * i + 0] = (unsigned char)(res >> 24); + pmac->c[4 * i + 1] = (unsigned char)(res >> 16); + pmac->c[4 * i + 2] = (unsigned char)(res >> 8); + pmac->c[4 * i + 3] = (unsigned char)res; + } +#endif + len += SHA_DIGEST_LENGTH; +#else + SHA1_Update(&key->md, out, inp_len); + res = key->md.num; + SHA1_Final(pmac->c, &key->md); + + { + unsigned int inp_blocks, pad_blocks; + + /* but pretend as if we hashed padded payload */ + inp_blocks = 1 + ((SHA_CBLOCK - 9 - res) >> + (sizeof(res) * 8 - 1)); + res += (unsigned int)(len - inp_len); + pad_blocks = res / SHA_CBLOCK; + res %= SHA_CBLOCK; + pad_blocks += 1 + ((SHA_CBLOCK - 9 - res) >> + (sizeof(res) * 8 - 1)); + for (; inp_blocks < pad_blocks; inp_blocks++) + sha1_block_data_order(&key->md, + data, 1); + } +#endif + key->md = key->tail; + SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH); + SHA1_Final(pmac->c, &key->md); + + /* verify HMAC */ + out += inp_len; + len -= inp_len; +#if 1 + { + unsigned char *p = + out + len - 1 - maxpad - SHA_DIGEST_LENGTH; + size_t off = out - p; + unsigned int c, cmask; + + maxpad += SHA_DIGEST_LENGTH; + for (res = 0, i = 0, j = 0; j < maxpad; j++) { + c = p[j]; + cmask = ((int)(j - off - + SHA_DIGEST_LENGTH)) >> + (sizeof(int) * 8 - 1); + res |= (c ^ pad) & ~cmask; /* ... and padding */ + cmask &= ((int)(off - 1 - j)) >> + (sizeof(int) * 8 - 1); + res |= (c ^ pmac->c[i]) & cmask; + i += 1 & cmask; + } + maxpad -= SHA_DIGEST_LENGTH; + + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + } +#else + for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++) + res |= out[i] ^ pmac->c[i]; + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + + /* verify padding */ + pad = (pad & ~res) | (maxpad & res); + out = out + len - 1 - pad; + for (res = 0, i = 0; i < pad; i++) + res |= out[i] ^ pad; + + res = (0 - res) >> (sizeof(res) * 8 - 1); + ret &= (int)~res; +#endif + return ret; + } + } + + return 1; +} + +static int +aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset(hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + SHA1_Init(&key->head); + SHA1_Update(&key->head, ptr, arg); + SHA1_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + SHA1_Init(&key->head); + SHA1_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + SHA1_Init(&key->tail); + SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + explicit_bzero(hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len; + + /* RFC 5246, 6.2.3.3: additional data has length 13 */ + if (arg != 13) + return -1; + + len = p[arg - 2] << 8 | p[arg - 1]; + + if (ctx->encrypt) { + key->payload_length = len; + if ((key->aux.tls_ver = p[arg - 4] << 8 | + p[arg - 3]) >= TLS1_1_VERSION) { + len -= AES_BLOCK_SIZE; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->md = key->head; + SHA1_Update(&key->md, p, arg); + + return (int)(((len + SHA_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - len); + } else { + memcpy(key->aux.tls_aad, ptr, arg); + key->payload_length = arg; + + return SHA_DIGEST_LENGTH; + } + } + default: + return -1; + } +} + +static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { +#ifdef NID_aes_128_cbc_hmac_sha1 + .nid = NID_aes_128_cbc_hmac_sha1, +#else + .nid = NID_undef, +#endif + .block_size = 16, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER, + .init = aesni_cbc_hmac_sha1_init_key, + .do_cipher = aesni_cbc_hmac_sha1_cipher, + .ctx_size = sizeof(EVP_AES_HMAC_SHA1), + .ctrl = aesni_cbc_hmac_sha1_ctrl +}; + +static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { +#ifdef NID_aes_256_cbc_hmac_sha1 + .nid = NID_aes_256_cbc_hmac_sha1, +#else + .nid = NID_undef, +#endif + .block_size = 16, + .key_len = 32, + .iv_len = 16, + .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER, + .init = aesni_cbc_hmac_sha1_init_key, + .do_cipher = aesni_cbc_hmac_sha1_cipher, + .ctx_size = sizeof(EVP_AES_HMAC_SHA1), + .ctrl = aesni_cbc_hmac_sha1_ctrl +}; + +const EVP_CIPHER * +EVP_aes_128_cbc_hmac_sha1(void) +{ + return (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI) ? + &aesni_128_cbc_hmac_sha1_cipher : NULL; +} + +const EVP_CIPHER * +EVP_aes_256_cbc_hmac_sha1(void) +{ + return (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI) ? + &aesni_256_cbc_hmac_sha1_cipher : NULL; +} +#else +const EVP_CIPHER * +EVP_aes_128_cbc_hmac_sha1(void) +{ + return NULL; +} + +const EVP_CIPHER * +EVP_aes_256_cbc_hmac_sha1(void) +{ + return NULL; +} +#endif +#endif diff --git a/Libraries/libressl/crypto/evp/e_bf.c b/Libraries/libressl/crypto/evp/e_bf.c new file mode 100644 index 000000000..9146a531e --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_bf.c @@ -0,0 +1,247 @@ +/* $OpenBSD: e_bf.c,v 1.17 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_BF + +#include +#include +#include + +#include "evp_local.h" + +typedef struct { + BF_KEY ks; +} EVP_BF_KEY; + +#define data(ctx) ((EVP_BF_KEY *)(ctx)->cipher_data) + +static int +bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int +bf_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + BF_cbc_encrypt(in, out, (long)chunk, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + BF_cbc_encrypt(in, out, (long)inl, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +bf_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + BF_cfb64_encrypt(in, out, (long)chunk, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +bf_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + BF_ecb_encrypt(in + i, out + i, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +bf_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + BF_ofb64_encrypt(in, out, (long)chunk, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + BF_ofb64_encrypt(in, out, (long)inl, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER bf_cbc = { + .nid = NID_bf_cbc, + .block_size = 8, + .key_len = 16, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE, + .init = bf_init_key, + .do_cipher = bf_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_BF_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_bf_cbc(void) +{ + return &bf_cbc; +} + +static const EVP_CIPHER bf_cfb64 = { + .nid = NID_bf_cfb64, + .block_size = 1, + .key_len = 16, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CFB_MODE, + .init = bf_init_key, + .do_cipher = bf_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_BF_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_bf_cfb64(void) +{ + return &bf_cfb64; +} + +static const EVP_CIPHER bf_ofb = { + .nid = NID_bf_ofb64, + .block_size = 1, + .key_len = 16, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_OFB_MODE, + .init = bf_init_key, + .do_cipher = bf_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_BF_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_bf_ofb(void) +{ + return &bf_ofb; +} + +static const EVP_CIPHER bf_ecb = { + .nid = NID_bf_ecb, + .block_size = 8, + .key_len = 16, + .iv_len = 0, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ECB_MODE, + .init = bf_init_key, + .do_cipher = bf_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_BF_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_bf_ecb(void) +{ + return &bf_ecb; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_camellia.c b/Libraries/libressl/crypto/evp/e_camellia.c new file mode 100644 index 000000000..cec7649e3 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_camellia.c @@ -0,0 +1,823 @@ +/* $OpenBSD: e_camellia.c,v 1.18 2023/07/07 19:37:53 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#ifndef OPENSSL_NO_CAMELLIA +#include +#include +#include + +#include "evp_local.h" + +/* Camellia subkey Structure */ +typedef struct { + CAMELLIA_KEY ks; +} EVP_CAMELLIA_KEY; + +/* Attribute operation for Camellia */ +#define data(ctx) ((EVP_CAMELLIA_KEY *)(ctx)->cipher_data) + +static int +camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret; + + ret = Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data); + + if (ret < 0) { + EVPerror(EVP_R_CAMELLIA_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int +camellia_128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + Camellia_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Camellia_cbc_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +camellia_128_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb128_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +camellia_128_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + Camellia_ecb_encrypt(in + i, out + i, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +camellia_128_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + Camellia_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Camellia_ofb128_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER camellia_128_cbc = { + .nid = NID_camellia_128_cbc, + .block_size = 16, + .key_len = 16, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CBC_MODE, + .init = camellia_init_key, + .do_cipher = camellia_128_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_128_cbc(void) +{ + return &camellia_128_cbc; +} + +static const EVP_CIPHER camellia_128_cfb128 = { + .nid = NID_camellia_128_cfb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_128_cfb128_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_128_cfb128(void) +{ + return &camellia_128_cfb128; +} + +static const EVP_CIPHER camellia_128_ofb = { + .nid = NID_camellia_128_ofb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = 0 | EVP_CIPH_OFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_128_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_128_ofb(void) +{ + return &camellia_128_ofb; +} + +static const EVP_CIPHER camellia_128_ecb = { + .nid = NID_camellia_128_ecb, + .block_size = 16, + .key_len = 16, + .iv_len = 0, + .flags = 0 | EVP_CIPH_ECB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_128_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_128_ecb(void) +{ + return &camellia_128_ecb; +} + +static int +camellia_192_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + Camellia_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Camellia_cbc_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +camellia_192_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb128_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +camellia_192_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + Camellia_ecb_encrypt(in + i, out + i, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +camellia_192_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + Camellia_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Camellia_ofb128_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER camellia_192_cbc = { + .nid = NID_camellia_192_cbc, + .block_size = 16, + .key_len = 24, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CBC_MODE, + .init = camellia_init_key, + .do_cipher = camellia_192_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_192_cbc(void) +{ + return &camellia_192_cbc; +} + +static const EVP_CIPHER camellia_192_cfb128 = { + .nid = NID_camellia_192_cfb128, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_192_cfb128_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_192_cfb128(void) +{ + return &camellia_192_cfb128; +} + +static const EVP_CIPHER camellia_192_ofb = { + .nid = NID_camellia_192_ofb128, + .block_size = 1, + .key_len = 24, + .iv_len = 16, + .flags = 0 | EVP_CIPH_OFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_192_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_192_ofb(void) +{ + return &camellia_192_ofb; +} + +static const EVP_CIPHER camellia_192_ecb = { + .nid = NID_camellia_192_ecb, + .block_size = 16, + .key_len = 24, + .iv_len = 0, + .flags = 0 | EVP_CIPH_ECB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_192_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_192_ecb(void) +{ + return &camellia_192_ecb; +} + +static int +camellia_256_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + Camellia_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Camellia_cbc_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +camellia_256_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb128_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +camellia_256_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + Camellia_ecb_encrypt(in + i, out + i, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +camellia_256_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + Camellia_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Camellia_ofb128_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER camellia_256_cbc = { + .nid = NID_camellia_256_cbc, + .block_size = 16, + .key_len = 32, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CBC_MODE, + .init = camellia_init_key, + .do_cipher = camellia_256_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_256_cbc(void) +{ + return &camellia_256_cbc; +} + +static const EVP_CIPHER camellia_256_cfb128 = { + .nid = NID_camellia_256_cfb128, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_256_cfb128_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_256_cfb128(void) +{ + return &camellia_256_cfb128; +} + +static const EVP_CIPHER camellia_256_ofb = { + .nid = NID_camellia_256_ofb128, + .block_size = 1, + .key_len = 32, + .iv_len = 16, + .flags = 0 | EVP_CIPH_OFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_256_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_256_ofb(void) +{ + return &camellia_256_ofb; +} + +static const EVP_CIPHER camellia_256_ecb = { + .nid = NID_camellia_256_ecb, + .block_size = 16, + .key_len = 32, + .iv_len = 0, + .flags = 0 | EVP_CIPH_ECB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_256_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_256_ecb(void) +{ + return &camellia_256_ecb; +} + +static int +camellia_128_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + chunk >>= 3; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb1_encrypt(in, out, ((1 == 1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ? chunk * 8 : chunk), &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER camellia_128_cfb1 = { + .nid = NID_camellia_128_cfb1, + .block_size = 1, + .key_len = 128/8, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_128_cfb1_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_128_cfb1(void) +{ + return &camellia_128_cfb1; +} + +static int +camellia_192_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + chunk >>= 3; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb1_encrypt(in, out, ((1 == 1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ? chunk * 8 : chunk), &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER camellia_192_cfb1 = { + .nid = NID_camellia_192_cfb1, + .block_size = 1, + .key_len = 192/8, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_192_cfb1_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_192_cfb1(void) +{ + return &camellia_192_cfb1; +} + +static int +camellia_256_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + chunk >>= 3; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb1_encrypt(in, out, ((1 == 1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ? chunk * 8 : chunk), &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER camellia_256_cfb1 = { + .nid = NID_camellia_256_cfb1, + .block_size = 1, + .key_len = 256/8, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_256_cfb1_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_256_cfb1(void) +{ + return &camellia_256_cfb1; +} + + +static int +camellia_128_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb8_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER camellia_128_cfb8 = { + .nid = NID_camellia_128_cfb8, + .block_size = 1, + .key_len = 128/8, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_128_cfb8_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_128_cfb8(void) +{ + return &camellia_128_cfb8; +} + +static int +camellia_192_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb8_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER camellia_192_cfb8 = { + .nid = NID_camellia_192_cfb8, + .block_size = 1, + .key_len = 192/8, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_192_cfb8_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_192_cfb8(void) +{ + return &camellia_192_cfb8; +} + +static int +camellia_256_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Camellia_cfb8_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER camellia_256_cfb8 = { + .nid = NID_camellia_256_cfb8, + .block_size = 1, + .key_len = 256/8, + .iv_len = 16, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = camellia_init_key, + .do_cipher = camellia_256_cfb8_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAMELLIA_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_camellia_256_cfb8(void) +{ + return &camellia_256_cfb8; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_cast.c b/Libraries/libressl/crypto/evp/e_cast.c new file mode 100644 index 000000000..a0e52dfdf --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_cast.c @@ -0,0 +1,247 @@ +/* $OpenBSD: e_cast.c,v 1.16 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_CAST + +#include +#include +#include + +#include "evp_local.h" + +typedef struct { + CAST_KEY ks; +} EVP_CAST_KEY; + +#define data(ctx) ((EVP_CAST_KEY *)(ctx)->cipher_data) + +static int +cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int +cast5_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + CAST_cbc_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + CAST_cbc_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +cast5_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + CAST_cfb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +cast5_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + CAST_ecb_encrypt(in + i, out + i, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +cast5_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + CAST_ofb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + CAST_ofb64_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER cast5_cbc = { + .nid = NID_cast5_cbc, + .block_size = 8, + .key_len = CAST_KEY_LENGTH, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE, + .init = cast_init_key, + .do_cipher = cast5_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAST_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_cast5_cbc(void) +{ + return &cast5_cbc; +} + +static const EVP_CIPHER cast5_cfb64 = { + .nid = NID_cast5_cfb64, + .block_size = 1, + .key_len = CAST_KEY_LENGTH, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CFB_MODE, + .init = cast_init_key, + .do_cipher = cast5_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAST_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_cast5_cfb64(void) +{ + return &cast5_cfb64; +} + +static const EVP_CIPHER cast5_ofb = { + .nid = NID_cast5_ofb64, + .block_size = 1, + .key_len = CAST_KEY_LENGTH, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_OFB_MODE, + .init = cast_init_key, + .do_cipher = cast5_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAST_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_cast5_ofb(void) +{ + return &cast5_ofb; +} + +static const EVP_CIPHER cast5_ecb = { + .nid = NID_cast5_ecb, + .block_size = 8, + .key_len = CAST_KEY_LENGTH, + .iv_len = 0, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ECB_MODE, + .init = cast_init_key, + .do_cipher = cast5_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_CAST_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_cast5_ecb(void) +{ + return &cast5_ecb; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_chacha.c b/Libraries/libressl/crypto/evp/e_chacha.c new file mode 100644 index 000000000..5cd03c7c8 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_chacha.c @@ -0,0 +1,76 @@ +/* $OpenBSD: e_chacha.c,v 1.13 2023/08/24 04:20:57 tb Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef OPENSSL_NO_CHACHA + +#include +#include +#include + +#include "evp_local.h" + +static int +chacha_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *openssl_iv, int enc) +{ + if (key != NULL) + ChaCha_set_key((ChaCha_ctx *)ctx->cipher_data, key, + EVP_CIPHER_CTX_key_length(ctx) * 8); + if (openssl_iv != NULL) { + const unsigned char *iv = openssl_iv + 8; + const unsigned char *counter = openssl_iv; + + ChaCha_set_iv((ChaCha_ctx *)ctx->cipher_data, iv, counter); + } + return 1; +} + +static int +chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + size_t len) +{ + ChaCha((ChaCha_ctx *)ctx->cipher_data, out, in, len); + return 1; +} + +static const EVP_CIPHER chacha20_cipher = { + .nid = NID_chacha20, + .block_size = 1, + .key_len = 32, + /* + * The 16-byte EVP IV is split into 4 little-endian 4-byte words + * evpiv[15:12] evpiv[11:8] evpiv[7:4] evpiv[3:0] + * iv[1] iv[0] counter[1] counter[0] + * and passed as iv[] and counter[] to ChaCha_set_iv(). + */ + .iv_len = 16, + .flags = EVP_CIPH_STREAM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CUSTOM_IV, + .init = chacha_init, + .do_cipher = chacha_cipher, + .ctx_size = sizeof(ChaCha_ctx) +}; + +const EVP_CIPHER * +EVP_chacha20(void) +{ + return (&chacha20_cipher); +} + +#endif diff --git a/Libraries/libressl/crypto/evp/e_chacha20poly1305.c b/Libraries/libressl/crypto/evp/e_chacha20poly1305.c new file mode 100644 index 000000000..4a393c245 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_chacha20poly1305.c @@ -0,0 +1,618 @@ +/* $OpenBSD: e_chacha20poly1305.c,v 1.32 2023/09/28 11:29:10 tb Exp $ */ + +/* + * Copyright (c) 2022 Joel Sing + * Copyright (c) 2015 Reyk Floter + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + +#include +#include +#include +#include + +#include "bytestring.h" +#include "evp_local.h" + +#define POLY1305_TAG_LEN 16 + +#define CHACHA20_CONSTANT_LEN 4 +#define CHACHA20_IV_LEN 8 +#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN) +#define XCHACHA20_NONCE_LEN 24 + +struct aead_chacha20_poly1305_ctx { + unsigned char key[32]; + unsigned char tag_len; +}; + +static int +aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key, + size_t key_len, size_t tag_len) +{ + struct aead_chacha20_poly1305_ctx *c20_ctx; + + if (tag_len == 0) + tag_len = POLY1305_TAG_LEN; + + if (tag_len > POLY1305_TAG_LEN) { + EVPerror(EVP_R_TOO_LARGE); + return 0; + } + + /* Internal error - EVP_AEAD_CTX_init should catch this. */ + if (key_len != sizeof(c20_ctx->key)) + return 0; + + c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx)); + if (c20_ctx == NULL) + return 0; + + memcpy(&c20_ctx->key[0], key, key_len); + c20_ctx->tag_len = tag_len; + ctx->aead_state = c20_ctx; + + return 1; +} + +static void +aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) +{ + struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + + freezero(c20_ctx, sizeof(*c20_ctx)); +} + +static void +poly1305_update_with_length(poly1305_state *poly1305, + const unsigned char *data, size_t data_len) +{ + size_t j = data_len; + unsigned char length_bytes[8]; + unsigned i; + + for (i = 0; i < sizeof(length_bytes); i++) { + length_bytes[i] = j; + j >>= 8; + } + + if (data != NULL) + CRYPTO_poly1305_update(poly1305, data, data_len); + CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); +} + +static void +poly1305_pad16(poly1305_state *poly1305, size_t data_len) +{ + static const unsigned char zero_pad16[16]; + size_t pad_len; + + /* pad16() is defined in RFC 8439 2.8.1. */ + if ((pad_len = data_len % 16) == 0) + return; + + CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len); +} + +static void +poly1305_update_with_pad16(poly1305_state *poly1305, + const unsigned char *data, size_t data_len) +{ + CRYPTO_poly1305_update(poly1305, data, data_len); + poly1305_pad16(poly1305, data_len); +} + +static int +aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len) +{ + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + unsigned char poly1305_key[32]; + poly1305_state poly1305; + const unsigned char *iv; + uint64_t ctr; + + if (max_out_len < in_len + c20_ctx->tag_len) { + EVPerror(EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != ctx->aead->nonce_len) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + + ctr = (uint64_t)((uint32_t)(nonce[0]) | (uint32_t)(nonce[1]) << 8 | + (uint32_t)(nonce[2]) << 16 | (uint32_t)(nonce[3]) << 24) << 32; + iv = nonce + CHACHA20_CONSTANT_LEN; + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, iv, ctr); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1); + poly1305_update_with_pad16(&poly1305, out, in_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, in_len); + + if (c20_ctx->tag_len != POLY1305_TAG_LEN) { + unsigned char tag[POLY1305_TAG_LEN]; + CRYPTO_poly1305_finish(&poly1305, tag); + memcpy(out + in_len, tag, c20_ctx->tag_len); + *out_len = in_len + c20_ctx->tag_len; + return 1; + } + + CRYPTO_poly1305_finish(&poly1305, out + in_len); + *out_len = in_len + POLY1305_TAG_LEN; + return 1; +} + +static int +aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len) +{ + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + unsigned char mac[POLY1305_TAG_LEN]; + unsigned char poly1305_key[32]; + const unsigned char *iv = nonce; + poly1305_state poly1305; + size_t plaintext_len; + uint64_t ctr = 0; + + if (in_len < c20_ctx->tag_len) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != ctx->aead->nonce_len) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + + plaintext_len = in_len - c20_ctx->tag_len; + + if (max_out_len < plaintext_len) { + EVPerror(EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + ctr = (uint64_t)((uint32_t)(nonce[0]) | (uint32_t)(nonce[1]) << 8 | + (uint32_t)(nonce[2]) << 16 | (uint32_t)(nonce[3]) << 24) << 32; + iv = nonce + CHACHA20_CONSTANT_LEN; + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, iv, ctr); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + poly1305_update_with_pad16(&poly1305, in, plaintext_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, plaintext_len); + + CRYPTO_poly1305_finish(&poly1305, mac); + + if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + + CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, iv, ctr + 1); + *out_len = plaintext_len; + return 1; +} + +static int +aead_xchacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len) +{ + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + unsigned char poly1305_key[32]; + unsigned char subkey[32]; + poly1305_state poly1305; + + if (max_out_len < in_len + c20_ctx->tag_len) { + EVPerror(EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != ctx->aead->nonce_len) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + + CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce); + + CRYPTO_chacha_20(out, in, in_len, subkey, nonce + 16, 1); + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), + subkey, nonce + 16, 0); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + poly1305_update_with_pad16(&poly1305, out, in_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, in_len); + + if (c20_ctx->tag_len != POLY1305_TAG_LEN) { + unsigned char tag[POLY1305_TAG_LEN]; + CRYPTO_poly1305_finish(&poly1305, tag); + memcpy(out + in_len, tag, c20_ctx->tag_len); + *out_len = in_len + c20_ctx->tag_len; + return 1; + } + + CRYPTO_poly1305_finish(&poly1305, out + in_len); + *out_len = in_len + POLY1305_TAG_LEN; + return 1; +} + +static int +aead_xchacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len) +{ + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + unsigned char mac[POLY1305_TAG_LEN]; + unsigned char poly1305_key[32]; + unsigned char subkey[32]; + poly1305_state poly1305; + size_t plaintext_len; + + if (in_len < c20_ctx->tag_len) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != ctx->aead->nonce_len) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + + plaintext_len = in_len - c20_ctx->tag_len; + + if (max_out_len < plaintext_len) { + EVPerror(EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce); + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), + subkey, nonce + 16, 0); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + poly1305_update_with_pad16(&poly1305, in, plaintext_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, plaintext_len); + + CRYPTO_poly1305_finish(&poly1305, mac); + if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + + CRYPTO_chacha_20(out, in, plaintext_len, subkey, nonce + 16, 1); + + *out_len = plaintext_len; + return 1; +} + +/* RFC 8439 */ +static const EVP_AEAD aead_chacha20_poly1305 = { + .key_len = 32, + .nonce_len = CHACHA20_NONCE_LEN, + .overhead = POLY1305_TAG_LEN, + .max_tag_len = POLY1305_TAG_LEN, + + .init = aead_chacha20_poly1305_init, + .cleanup = aead_chacha20_poly1305_cleanup, + .seal = aead_chacha20_poly1305_seal, + .open = aead_chacha20_poly1305_open, +}; + +const EVP_AEAD * +EVP_aead_chacha20_poly1305() +{ + return &aead_chacha20_poly1305; +} + +static const EVP_AEAD aead_xchacha20_poly1305 = { + .key_len = 32, + .nonce_len = XCHACHA20_NONCE_LEN, + .overhead = POLY1305_TAG_LEN, + .max_tag_len = POLY1305_TAG_LEN, + + .init = aead_chacha20_poly1305_init, + .cleanup = aead_chacha20_poly1305_cleanup, + .seal = aead_xchacha20_poly1305_seal, + .open = aead_xchacha20_poly1305_open, +}; + +const EVP_AEAD * +EVP_aead_xchacha20_poly1305() +{ + return &aead_xchacha20_poly1305; +} + +struct chacha20_poly1305_ctx { + ChaCha_ctx chacha; + poly1305_state poly1305; + + unsigned char key[32]; + unsigned char nonce[CHACHA20_NONCE_LEN]; + size_t nonce_len; + unsigned char tag[POLY1305_TAG_LEN]; + size_t tag_len; + + size_t ad_len; + size_t in_len; + + int in_ad; + int started; +}; + +static int +chacha20_poly1305_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int encrypt) +{ + struct chacha20_poly1305_ctx *cpx = ctx->cipher_data; + uint8_t *data; + CBB cbb; + int ret = 0; + + memset(&cbb, 0, sizeof(cbb)); + + if (key == NULL && iv == NULL) + goto done; + + cpx->started = 0; + + if (key != NULL) + memcpy(cpx->key, key, sizeof(cpx->key)); + + if (iv != NULL) { + /* + * Left zero pad if configured nonce length is less than ChaCha + * nonce length. + */ + if (!CBB_init_fixed(&cbb, cpx->nonce, sizeof(cpx->nonce))) + goto err; + if (!CBB_add_space(&cbb, &data, sizeof(cpx->nonce) - cpx->nonce_len)) + goto err; + if (!CBB_add_bytes(&cbb, iv, cpx->nonce_len)) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; + } + + done: + ret = 1; + + err: + CBB_cleanup(&cbb); + + return ret; +} + +static int +chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + struct chacha20_poly1305_ctx *cpx = ctx->cipher_data; + + /* + * Since we're making AEAD work within the constraints of EVP_CIPHER... + * If in is non-NULL then this is an update, while if in is NULL then + * this is a final. If in is non-NULL but out is NULL, then the input + * being provided is associated data. Plus we have to handle encryption + * (sealing) and decryption (opening) in the same function. + */ + + if (!cpx->started) { + unsigned char poly1305_key[32]; + const unsigned char *iv; + uint64_t ctr; + + ctr = (uint64_t)((uint32_t)(cpx->nonce[0]) | + (uint32_t)(cpx->nonce[1]) << 8 | + (uint32_t)(cpx->nonce[2]) << 16 | + (uint32_t)(cpx->nonce[3]) << 24) << 32; + iv = cpx->nonce + CHACHA20_CONSTANT_LEN; + + ChaCha_set_key(&cpx->chacha, cpx->key, 8 * sizeof(cpx->key)); + ChaCha_set_iv(&cpx->chacha, iv, NULL); + + /* See chacha.c for details re handling of counter. */ + cpx->chacha.input[12] = (uint32_t)ctr; + cpx->chacha.input[13] = (uint32_t)(ctr >> 32); + + memset(poly1305_key, 0, sizeof(poly1305_key)); + ChaCha(&cpx->chacha, poly1305_key, poly1305_key, + sizeof(poly1305_key)); + CRYPTO_poly1305_init(&cpx->poly1305, poly1305_key); + + /* Mark remaining key block as used. */ + cpx->chacha.unused = 0; + + cpx->ad_len = 0; + cpx->in_len = 0; + cpx->in_ad = 0; + + cpx->started = 1; + } + + if (len > SIZE_MAX - cpx->in_len) { + EVPerror(EVP_R_TOO_LARGE); + return 0; + } + + /* Disallow authenticated data after plaintext/ciphertext. */ + if (cpx->in_len > 0 && in != NULL && out == NULL) + return -1; + + if (cpx->in_ad && (in == NULL || out != NULL)) { + poly1305_pad16(&cpx->poly1305, cpx->ad_len); + cpx->in_ad = 0; + } + + /* Update with AD or plaintext/ciphertext. */ + if (in != NULL) { + if (out == NULL) { + cpx->ad_len += len; + cpx->in_ad = 1; + } else { + ChaCha(&cpx->chacha, out, in, len); + cpx->in_len += len; + } + if (ctx->encrypt && out != NULL) + CRYPTO_poly1305_update(&cpx->poly1305, out, len); + else + CRYPTO_poly1305_update(&cpx->poly1305, in, len); + + return len; + } + + /* Final. */ + poly1305_pad16(&cpx->poly1305, cpx->in_len); + poly1305_update_with_length(&cpx->poly1305, NULL, cpx->ad_len); + poly1305_update_with_length(&cpx->poly1305, NULL, cpx->in_len); + + if (ctx->encrypt) { + CRYPTO_poly1305_finish(&cpx->poly1305, cpx->tag); + cpx->tag_len = sizeof(cpx->tag); + } else { + unsigned char tag[POLY1305_TAG_LEN]; + + /* Ensure that a tag has been provided. */ + if (cpx->tag_len <= 0) + return -1; + + CRYPTO_poly1305_finish(&cpx->poly1305, tag); + if (timingsafe_memcmp(tag, cpx->tag, cpx->tag_len) != 0) + return -1; + } + + cpx->started = 0; + + return len; +} + +static int +chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct chacha20_poly1305_ctx *cpx = ctx->cipher_data; + + explicit_bzero(cpx, sizeof(*cpx)); + + return 1; +} + +static int +chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + struct chacha20_poly1305_ctx *cpx = ctx->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + memset(cpx, 0, sizeof(*cpx)); + cpx->nonce_len = sizeof(cpx->nonce); + return 1; + + case EVP_CTRL_AEAD_GET_IVLEN: + if (cpx->nonce_len > INT_MAX) + return 0; + *(int *)ptr = (int)cpx->nonce_len; + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg <= 0 || arg > sizeof(cpx->nonce)) + return 0; + cpx->nonce_len = arg; + return 1; + + case EVP_CTRL_AEAD_SET_TAG: + if (ctx->encrypt) + return 0; + if (arg <= 0 || arg > sizeof(cpx->tag)) + return 0; + if (ptr != NULL) { + memcpy(cpx->tag, ptr, arg); + cpx->tag_len = arg; + } + return 1; + + case EVP_CTRL_AEAD_GET_TAG: + if (!ctx->encrypt) + return 0; + if (arg <= 0 || arg > cpx->tag_len) + return 0; + memcpy(ptr, cpx->tag, arg); + return 1; + + case EVP_CTRL_AEAD_SET_IV_FIXED: + if (arg != sizeof(cpx->nonce)) + return 0; + memcpy(cpx->nonce, ptr, arg); + return 1; + } + + return 0; +} + +static const EVP_CIPHER cipher_chacha20_poly1305 = { + .nid = NID_chacha20_poly1305, + .block_size = 1, + .key_len = 32, + .iv_len = 12, + .flags = EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | + EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_IV_LENGTH | + EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_CUSTOM_CIPHER | + EVP_CIPH_FLAG_DEFAULT_ASN1, + .init = chacha20_poly1305_init, + .do_cipher = chacha20_poly1305_cipher, + .cleanup = chacha20_poly1305_cleanup, + .ctx_size = sizeof(struct chacha20_poly1305_ctx), + .ctrl = chacha20_poly1305_ctrl, +}; + +const EVP_CIPHER * +EVP_chacha20_poly1305(void) +{ + return &cipher_chacha20_poly1305; +} + +#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ diff --git a/Libraries/libressl/crypto/evp/e_des.c b/Libraries/libressl/crypto/evp/e_des.c new file mode 100644 index 000000000..64d098ca1 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_des.c @@ -0,0 +1,355 @@ +/* $OpenBSD: e_des.c,v 1.22 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_DES + +#include +#include +#include + +#include "evp_local.h" + +static int +des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + + DES_set_key_unchecked(deskey, ctx->cipher_data); + return 1; +} + +static int +des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_RAND_KEY: + if (DES_random_key((DES_cblock *)ptr) == 0) + return 0; + return 1; + + default: + return -1; + } +} + +static int +des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), + ctx->cipher_data, ctx->encrypt); + + return 1; +} + +static int +des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_ofb64_encrypt(in, out, (long)chunk, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + return 1; +} + +static int +des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_ncbc_encrypt(in, out, (long)chunk, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int +des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_cfb64_encrypt(in, out, (long)chunk, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + return 1; +} + +/* Although we have a CFB-r implementation for DES, it doesn't pack the right + way, so wrap it here */ +static int +des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + unsigned char c[1], d[1]; + size_t chunk = LONG_MAX / 8; + size_t n; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + for (n = 0; n < chunk*8; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + out[n / 8] = (out[n / 8] & + ~(0x80 >> (unsigned int)(n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_cfb_encrypt(in, out, 8, (long)chunk, + ctx->cipher_data, (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static const EVP_CIPHER des_cbc = { + .nid = NID_des_cbc, + .block_size = 8, + .key_len = 8, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CBC_MODE, + .init = des_init_key, + .do_cipher = des_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_key_schedule), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_cbc(void) +{ + return &des_cbc; +} + +static const EVP_CIPHER des_cfb64 = { + .nid = NID_des_cfb64, + .block_size = 1, + .key_len = 8, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_init_key, + .do_cipher = des_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_key_schedule), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_cfb64(void) +{ + return &des_cfb64; +} + +static const EVP_CIPHER des_ofb = { + .nid = NID_des_ofb64, + .block_size = 1, + .key_len = 8, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_OFB_MODE, + .init = des_init_key, + .do_cipher = des_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_key_schedule), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ofb(void) +{ + return &des_ofb; +} + +static const EVP_CIPHER des_ecb = { + .nid = NID_des_ecb, + .block_size = 8, + .key_len = 8, + .iv_len = 0, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_ECB_MODE, + .init = des_init_key, + .do_cipher = des_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_key_schedule), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ecb(void) +{ + return &des_ecb; +} + +static const EVP_CIPHER des_cfb1 = { + .nid = NID_des_cfb1, + .block_size = 1, + .key_len = 8, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_init_key, + .do_cipher = des_cfb1_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_key_schedule), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_cfb1(void) +{ + return &des_cfb1; +} + +static const EVP_CIPHER des_cfb8 = { + .nid = NID_des_cfb8, + .block_size = 1, + .key_len = 8, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_init_key, + .do_cipher = des_cfb8_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_key_schedule), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_cfb8(void) +{ + return &des_cfb8; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_des3.c b/Libraries/libressl/crypto/evp/e_des3.c new file mode 100644 index 000000000..3e6c5234c --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_des3.c @@ -0,0 +1,495 @@ +/* $OpenBSD: e_des3.c,v 1.28 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_DES + +#include +#include +#include + +#include "evp_local.h" + +typedef struct { + DES_key_schedule ks1;/* key schedule */ + DES_key_schedule ks2;/* key schedule (for ede) */ + DES_key_schedule ks3;/* key schedule (for ede3) */ +} DES_EDE_KEY; + +#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) + +static int +des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + + DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); + DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); + memcpy(&data(ctx)->ks3, &data(ctx)->ks1, + sizeof(data(ctx)->ks1)); + return 1; +} + +static int +des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + + + DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); + DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); + DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3); + return 1; +} + +static int +des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + DES_cblock *deskey = ptr; + + switch (type) { + case EVP_CTRL_RAND_KEY: + if (DES_random_key(deskey) == 0) + return 0; + if (c->key_len >= 16 && DES_random_key(deskey + 1) == 0) + return 0; + if (c->key_len >= 24 && DES_random_key(deskey + 2) == 0) + return 0; + return 1; + + default: + return -1; + } +} + +static int +des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i), + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, ctx->encrypt); + + return 1; +} + +static int +des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_ede3_ofb64_encrypt(in, out, (long)chunk, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_ede3_ofb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num); + + return 1; +} + +static int +des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_ede3_cbc_encrypt(in, out, (long)chunk, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_ede3_cbc_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int +des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_ede3_cfb64_encrypt(in, out, (long)chunk, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + return 1; +} + +/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right + way, so wrap it here */ +static int +des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + unsigned char c[1], d[1]; + size_t n; + + if (!(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS)) + inl *= 8; + + for (n = 0; n < inl; ++n) { + c[0] = (in[n/8]&(1 << (7 - n % 8))) ? 0x80 : 0; + DES_ede3_cfb_encrypt(c, d, 1, 1, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + + return 1; +} + +static int +des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + DES_ede3_cfb_encrypt(in, out, 8, (long)chunk, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + if (inl) + DES_ede3_cfb_encrypt(in, out, 8, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static const EVP_CIPHER des_ede_cbc = { + .nid = NID_des_ede_cbc, + .block_size = 8, + .key_len = 16, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CBC_MODE, + .init = des_ede_init_key, + .do_cipher = des_ede_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede_cbc(void) +{ + return &des_ede_cbc; +} + +static const EVP_CIPHER des_ede_cfb64 = { + .nid = NID_des_ede_cfb64, + .block_size = 1, + .key_len = 16, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_ede_init_key, + .do_cipher = des_ede_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede_cfb64(void) +{ + return &des_ede_cfb64; +} + +static const EVP_CIPHER des_ede_ofb = { + .nid = NID_des_ede_ofb64, + .block_size = 1, + .key_len = 16, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_OFB_MODE, + .init = des_ede_init_key, + .do_cipher = des_ede_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede_ofb(void) +{ + return &des_ede_ofb; +} + +static const EVP_CIPHER des_ede_ecb = { + .nid = NID_des_ede_ecb, + .block_size = 8, + .key_len = 16, + .iv_len = 0, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_ECB_MODE, + .init = des_ede_init_key, + .do_cipher = des_ede_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede_ecb(void) +{ + return &des_ede_ecb; +} + + +#define des_ede3_cfb64_cipher des_ede_cfb64_cipher +#define des_ede3_ofb_cipher des_ede_ofb_cipher +#define des_ede3_cbc_cipher des_ede_cbc_cipher +#define des_ede3_ecb_cipher des_ede_ecb_cipher + +static const EVP_CIPHER des_ede3_cbc = { + .nid = NID_des_ede3_cbc, + .block_size = 8, + .key_len = 24, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CBC_MODE, + .init = des_ede3_init_key, + .do_cipher = des_ede3_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede3_cbc(void) +{ + return &des_ede3_cbc; +} + +static const EVP_CIPHER des_ede3_cfb64 = { + .nid = NID_des_ede3_cfb64, + .block_size = 1, + .key_len = 24, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_ede3_init_key, + .do_cipher = des_ede3_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede3_cfb64(void) +{ + return &des_ede3_cfb64; +} + +static const EVP_CIPHER des_ede3_ofb = { + .nid = NID_des_ede3_ofb64, + .block_size = 1, + .key_len = 24, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_OFB_MODE, + .init = des_ede3_init_key, + .do_cipher = des_ede3_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede3_ofb(void) +{ + return &des_ede3_ofb; +} + +static const EVP_CIPHER des_ede3_ecb = { + .nid = NID_des_ede3_ecb, + .block_size = 8, + .key_len = 24, + .iv_len = 0, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_ECB_MODE, + .init = des_ede3_init_key, + .do_cipher = des_ede3_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede3_ecb(void) +{ + return &des_ede3_ecb; +} + + +static const EVP_CIPHER des_ede3_cfb1 = { + .nid = NID_des_ede3_cfb1, + .block_size = 1, + .key_len = 24, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_ede3_init_key, + .do_cipher = des_ede3_cfb1_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede3_cfb1(void) +{ + return &des_ede3_cfb1; +} + + +static const EVP_CIPHER des_ede3_cfb8 = { + .nid = NID_des_ede3_cfb8, + .block_size = 1, + .key_len = 24, + .iv_len = 8, + .flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE, + .init = des_ede3_init_key, + .do_cipher = des_ede3_cfb8_cipher, + .cleanup = NULL, + .ctx_size = sizeof(DES_EDE_KEY), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = des3_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_des_ede3_cfb8(void) +{ + return &des_ede3_cfb8; +} + +const EVP_CIPHER * +EVP_des_ede(void) +{ + return &des_ede_ecb; +} + +const EVP_CIPHER * +EVP_des_ede3(void) +{ + return &des_ede3_ecb; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_gost2814789.c b/Libraries/libressl/crypto/evp/e_gost2814789.c new file mode 100644 index 000000000..359cf5e4c --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_gost2814789.c @@ -0,0 +1,315 @@ +/* $OpenBSD: e_gost2814789.c,v 1.13 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include + +#include "evp_local.h" + +typedef struct { + GOST2814789_KEY ks; + int param_nid; +} EVP_GOST2814789_CTX; + +static int +gost2814789_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_GOST2814789_CTX *c = ctx->cipher_data; + + return Gost2814789_set_key(&c->ks, key, ctx->key_len * 8); +} + +static int +gost2814789_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + EVP_GOST2814789_CTX *c = ctx->cipher_data; + + switch (type) { + case EVP_CTRL_PBE_PRF_NID: + if (ptr != NULL) { + *((int *)ptr) = NID_id_HMACGostR3411_94; + return 1; + } else { + return 0; + } + case EVP_CTRL_INIT: + /* Default value to have any s-box set at all */ + c->param_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; + return Gost2814789_set_sbox(&c->ks, c->param_nid); + case EVP_CTRL_GOST_SET_SBOX: + return Gost2814789_set_sbox(&c->ks, arg); + default: + return -1; + } +} + +int +gost2814789_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) +{ + int len = 0; + unsigned char *buf = NULL; + unsigned char *p = NULL; + EVP_GOST2814789_CTX *c = ctx->cipher_data; + ASN1_OCTET_STRING *os = NULL; + GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); + + if (gcp == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + if (ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len) == 0) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerror(ERR_R_ASN1_LIB); + return 0; + } + ASN1_OBJECT_free(gcp->enc_param_set); + gcp->enc_param_set = OBJ_nid2obj(c->param_nid); + + len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); + p = buf = malloc(len); + if (buf == NULL) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + i2d_GOST_CIPHER_PARAMS(gcp, &p); + GOST_CIPHER_PARAMS_free(gcp); + + os = ASN1_OCTET_STRING_new(); + if (os == NULL) { + free(buf); + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + if (ASN1_OCTET_STRING_set(os, buf, len) == 0) { + ASN1_OCTET_STRING_free(os); + free(buf); + GOSTerror(ERR_R_ASN1_LIB); + return 0; + } + free(buf); + + ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); + return 1; +} + +int +gost2814789_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) +{ + int ret = -1; + int len; + GOST_CIPHER_PARAMS *gcp = NULL; + EVP_GOST2814789_CTX *c = ctx->cipher_data; + unsigned char *p; + + if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) + return ret; + + p = params->value.sequence->data; + + gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p, + params->value.sequence->length); + + len = gcp->iv->length; + if (len != ctx->cipher->iv_len) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerror(GOST_R_INVALID_IV_LENGTH); + return -1; + } + + if (!Gost2814789_set_sbox(&c->ks, OBJ_obj2nid(gcp->enc_param_set))) { + GOST_CIPHER_PARAMS_free(gcp); + return -1; + } + c->param_nid = OBJ_obj2nid(gcp->enc_param_set); + + memcpy(ctx->oiv, gcp->iv->data, len); + memcpy(ctx->iv, gcp->iv->data, len); + + GOST_CIPHER_PARAMS_free(gcp); + + return 1; +} + +static int +gost2814789_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + Gost2814789_ecb_encrypt(in + i, out + i, &((EVP_GOST2814789_CTX *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +gost2814789_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + Gost2814789_cfb64_encrypt(in, out, chunk, &((EVP_GOST2814789_CTX *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +gost2814789_cnt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + EVP_GOST2814789_CTX *c = ctx->cipher_data; + + while (inl >= EVP_MAXCHUNK) { + Gost2814789_cnt_encrypt(in, out, EVP_MAXCHUNK, &c->ks, + ctx->iv, ctx->buf, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + Gost2814789_cnt_encrypt(in, out, inl, &c->ks, ctx->iv, ctx->buf, + &ctx->num); + return 1; +} + +/* gost89 is CFB-64 */ +#define NID_gost89_cfb64 NID_id_Gost28147_89 + +static const EVP_CIPHER gost2814789_ecb = { + .nid = NID_gost89_ecb, + .block_size = 8, + .key_len = 32, + .iv_len = 0, + .flags = EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT | EVP_CIPH_ECB_MODE, + .init = gost2814789_init_key, + .do_cipher = gost2814789_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_GOST2814789_CTX), + .set_asn1_parameters = gost2814789_set_asn1_params, + .get_asn1_parameters = gost2814789_get_asn1_params, + .ctrl = gost2814789_ctl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_gost2814789_ecb(void) +{ + return &gost2814789_ecb; +} + +static const EVP_CIPHER gost2814789_cfb64 = { + .nid = NID_gost89_cfb64, + .block_size = 1, + .key_len = 32, + .iv_len = 8, + .flags = EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT | EVP_CIPH_CFB_MODE, + .init = gost2814789_init_key, + .do_cipher = gost2814789_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_GOST2814789_CTX), + .set_asn1_parameters = gost2814789_set_asn1_params, + .get_asn1_parameters = gost2814789_get_asn1_params, + .ctrl = gost2814789_ctl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_gost2814789_cfb64(void) +{ + return &gost2814789_cfb64; +} + +static const EVP_CIPHER gost2814789_cnt = { + .nid = NID_gost89_cnt, + .block_size = 1, + .key_len = 32, + .iv_len = 8, + .flags = EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT | EVP_CIPH_OFB_MODE, + .init = gost2814789_init_key, + .do_cipher = gost2814789_cnt_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_GOST2814789_CTX), + .set_asn1_parameters = gost2814789_set_asn1_params, + .get_asn1_parameters = gost2814789_get_asn1_params, + .ctrl = gost2814789_ctl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_gost2814789_cnt(void) +{ + return &gost2814789_cnt; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_idea.c b/Libraries/libressl/crypto/evp/e_idea.c new file mode 100644 index 000000000..b2129dc99 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_idea.c @@ -0,0 +1,266 @@ +/* $OpenBSD: e_idea.c,v 1.20 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_IDEA + +#include +#include +#include + +#include "evp_local.h" + +/* NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a special + * case + */ + +static int +idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (!enc) { + if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) + enc = 1; + else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) + enc = 1; + } + if (enc) + idea_set_encrypt_key(key, ctx->cipher_data); + else { + IDEA_KEY_SCHEDULE tmp; + + idea_set_encrypt_key(key, &tmp); + idea_set_decrypt_key(&tmp, ctx->cipher_data); + explicit_bzero((unsigned char *)&tmp, + sizeof(IDEA_KEY_SCHEDULE)); + } + return 1; +} + +static int +idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + idea_ecb_encrypt(in + i, out + i, ctx->cipher_data); + + return 1; +} + +typedef struct { + IDEA_KEY_SCHEDULE ks; +} EVP_IDEA_KEY; + +static int +idea_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + idea_cbc_encrypt(in, out, (long)chunk, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + idea_cbc_encrypt(in, out, (long)inl, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +idea_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + idea_ofb64_encrypt(in, out, (long)chunk, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + idea_ofb64_encrypt(in, out, (long)inl, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static int +idea_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + idea_cfb64_encrypt(in, out, (long)chunk, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static const EVP_CIPHER idea_cbc = { + .nid = NID_idea_cbc, + .block_size = 8, + .key_len = 16, + .iv_len = 8, + .flags = 0 | EVP_CIPH_CBC_MODE, + .init = idea_init_key, + .do_cipher = idea_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(IDEA_KEY_SCHEDULE), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_idea_cbc(void) +{ + return &idea_cbc; +} + +static const EVP_CIPHER idea_cfb64 = { + .nid = NID_idea_cfb64, + .block_size = 1, + .key_len = 16, + .iv_len = 8, + .flags = 0 | EVP_CIPH_CFB_MODE, + .init = idea_init_key, + .do_cipher = idea_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(IDEA_KEY_SCHEDULE), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_idea_cfb64(void) +{ + return &idea_cfb64; +} + +static const EVP_CIPHER idea_ofb = { + .nid = NID_idea_ofb64, + .block_size = 1, + .key_len = 16, + .iv_len = 8, + .flags = 0 | EVP_CIPH_OFB_MODE, + .init = idea_init_key, + .do_cipher = idea_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(IDEA_KEY_SCHEDULE), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_idea_ofb(void) +{ + return &idea_ofb; +} + +static const EVP_CIPHER idea_ecb = { + .nid = NID_idea_ecb, + .block_size = 8, + .key_len = 16, + .iv_len = 0, + .flags = 0 | EVP_CIPH_ECB_MODE, + .init = idea_init_key, + .do_cipher = idea_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(IDEA_KEY_SCHEDULE), + .set_asn1_parameters = EVP_CIPHER_set_asn1_iv, + .get_asn1_parameters = EVP_CIPHER_get_asn1_iv, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_idea_ecb(void) +{ + return &idea_ecb; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_null.c b/Libraries/libressl/crypto/evp/e_null.c new file mode 100644 index 000000000..f30c207ff --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_null.c @@ -0,0 +1,107 @@ +/* $OpenBSD: e_null.c,v 1.18 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include + +#include "evp_local.h" + +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + +static const EVP_CIPHER n_cipher = { + NID_undef, + 1, 0, 0, + 0, + null_init_key, + null_cipher, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; + +const EVP_CIPHER * +EVP_enc_null(void) +{ + return (&n_cipher); +} + +static int +null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + /* memset(&(ctx->c),0,sizeof(ctx->c));*/ + return 1; +} + +static int +null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + if (in != out) + memcpy((char *)out, (const char *)in, inl); + return 1; +} diff --git a/Libraries/libressl/crypto/evp/e_rc2.c b/Libraries/libressl/crypto/evp/e_rc2.c new file mode 100644 index 000000000..32559e223 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_rc2.c @@ -0,0 +1,411 @@ +/* $OpenBSD: e_rc2.c,v 1.22 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_RC2 + +#include +#include +#include +#include + +#include "evp_local.h" + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); +static int rc2_magic_to_meth(int i); +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct { + int key_bits; /* effective key bits */ + RC2_KEY ks; /* key schedule */ +} EVP_RC2_KEY; + +#define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data) + +static int +rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + RC2_cbc_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + RC2_cbc_encrypt(in, out, (long)inl, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +rc2_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + RC2_cfb64_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +rc2_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + RC2_ecb_encrypt(in + i, out + i, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +rc2_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = LONG_MAX & ~0xff; + + while (inl >= chunk) { + RC2_ofb64_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= chunk; + in += chunk; + out += chunk; + } + + if (inl) + RC2_ofb64_encrypt(in, out, (long)inl, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER rc2_cbc = { + .nid = NID_rc2_cbc, + .block_size = 8, + .key_len = RC2_KEY_LENGTH, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_CBC_MODE, + .init = rc2_init_key, + .do_cipher = rc2_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_RC2_KEY), + .set_asn1_parameters = rc2_set_asn1_type_and_iv, + .get_asn1_parameters = rc2_get_asn1_type_and_iv, + .ctrl = rc2_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_rc2_cbc(void) +{ + return &rc2_cbc; +} + +static const EVP_CIPHER rc2_cfb64 = { + .nid = NID_rc2_cfb64, + .block_size = 1, + .key_len = RC2_KEY_LENGTH, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_CFB_MODE, + .init = rc2_init_key, + .do_cipher = rc2_cfb64_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_RC2_KEY), + .set_asn1_parameters = rc2_set_asn1_type_and_iv, + .get_asn1_parameters = rc2_get_asn1_type_and_iv, + .ctrl = rc2_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_rc2_cfb64(void) +{ + return &rc2_cfb64; +} + +static const EVP_CIPHER rc2_ofb = { + .nid = NID_rc2_ofb64, + .block_size = 1, + .key_len = RC2_KEY_LENGTH, + .iv_len = 8, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_OFB_MODE, + .init = rc2_init_key, + .do_cipher = rc2_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_RC2_KEY), + .set_asn1_parameters = rc2_set_asn1_type_and_iv, + .get_asn1_parameters = rc2_get_asn1_type_and_iv, + .ctrl = rc2_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_rc2_ofb(void) +{ + return &rc2_ofb; +} + +static const EVP_CIPHER rc2_ecb = { + .nid = NID_rc2_ecb, + .block_size = 8, + .key_len = RC2_KEY_LENGTH, + .iv_len = 0, + .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_ECB_MODE, + .init = rc2_init_key, + .do_cipher = rc2_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_RC2_KEY), + .set_asn1_parameters = rc2_set_asn1_type_and_iv, + .get_asn1_parameters = rc2_get_asn1_type_and_iv, + .ctrl = rc2_ctrl, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_rc2_ecb(void) +{ + return &rc2_ecb; +} + +#define RC2_40_MAGIC 0xa0 +#define RC2_64_MAGIC 0x78 +#define RC2_128_MAGIC 0x3a + +static const EVP_CIPHER r2_64_cbc_cipher = { + NID_rc2_64_cbc, + 8, 8 /* 64 bit */, 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_RC2_KEY), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL +}; + +static const EVP_CIPHER r2_40_cbc_cipher = { + NID_rc2_40_cbc, + 8, 5 /* 40 bit */, 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_RC2_KEY), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL +}; + +const EVP_CIPHER * +EVP_rc2_64_cbc(void) +{ + return (&r2_64_cbc_cipher); +} + +const EVP_CIPHER * +EVP_rc2_40_cbc(void) +{ + return (&r2_40_cbc_cipher); +} + +static int +rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + key, data(ctx)->key_bits); + return 1; +} + +static int +rc2_meth_to_magic(EVP_CIPHER_CTX *e) +{ + int i; + + if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0) + return (0); + if (i == 128) + return (RC2_128_MAGIC); + else if (i == 64) + return (RC2_64_MAGIC); + else if (i == 40) + return (RC2_40_MAGIC); + else + return (0); +} + +static int +rc2_magic_to_meth(int i) +{ + if (i == RC2_128_MAGIC) + return 128; + else if (i == RC2_64_MAGIC) + return 64; + else if (i == RC2_40_MAGIC) + return 40; + else { + EVPerror(EVP_R_UNSUPPORTED_KEY_SIZE); + return (0); + } +} + +static int +rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + long num = 0; + int i = 0; + int key_bits; + unsigned int l; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + if (l > sizeof(iv)) { + EVPerror(EVP_R_IV_TOO_LARGE); + return -1; + } + i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); + if (i != (int)l) + return (-1); + key_bits = rc2_magic_to_meth((int)num); + if (!key_bits) + return (-1); + if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) + return -1; + if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, + key_bits, NULL) <= 0) + return -1; + if (!EVP_CIPHER_CTX_set_key_length(c, key_bits / 8)) + return -1; + } + return (i); +} + +static int +rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + long num; + int i = 0, j; + + if (type != NULL) { + num = rc2_meth_to_magic(c); + j = EVP_CIPHER_CTX_iv_length(c); + i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); + } + return (i); +} + +static int +rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_INIT: + data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; + return 1; + + case EVP_CTRL_GET_RC2_KEY_BITS: + *(int *)ptr = data(c)->key_bits; + return 1; + + case EVP_CTRL_SET_RC2_KEY_BITS: + if (arg > 0) { + data(c)->key_bits = arg; + return 1; + } + return 0; + +#ifdef PBE_PRF_TEST + case EVP_CTRL_PBE_PRF_NID: + *(int *)ptr = NID_hmacWithMD5; + return 1; +#endif + + default: + return -1; + } +} + +#endif diff --git a/Libraries/libressl/crypto/evp/e_rc4.c b/Libraries/libressl/crypto/evp/e_rc4.c new file mode 100644 index 000000000..2503d3704 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_rc4.c @@ -0,0 +1,140 @@ +/* $OpenBSD: e_rc4.c,v 1.17 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#ifndef OPENSSL_NO_RC4 + +#include +#include +#include + +#include "evp_local.h" + +/* FIXME: surely this is available elsewhere? */ +#define EVP_RC4_KEY_SIZE 16 + +typedef struct { + RC4_KEY ks; /* working key */ +} EVP_RC4_KEY; + +#define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data) + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + +static const EVP_CIPHER r4_cipher = { + NID_rc4, + 1, EVP_RC4_KEY_SIZE, 0, + EVP_CIPH_VARIABLE_LENGTH, + rc4_init_key, + rc4_cipher, + NULL, + sizeof(EVP_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static const EVP_CIPHER r4_40_cipher = { + NID_rc4_40, + 1, 5 /* 40 bit */, 0, + EVP_CIPH_VARIABLE_LENGTH, + rc4_init_key, + rc4_cipher, + NULL, + sizeof(EVP_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +const EVP_CIPHER * +EVP_rc4(void) +{ + return (&r4_cipher); +} + +const EVP_CIPHER * +EVP_rc4_40(void) +{ + return (&r4_40_cipher); +} + +static int +rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int +rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + RC4(&data(ctx)->ks, inl, in, out); + return 1; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_rc4_hmac_md5.c b/Libraries/libressl/crypto/evp/e_rc4_hmac_md5.c new file mode 100644 index 000000000..bcf8daea6 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_rc4_hmac_md5.c @@ -0,0 +1,307 @@ +/* $OpenBSD: e_rc4_hmac_md5.c,v 1.12 2023/07/07 19:37:53 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include + +#include + +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) + +#include +#include +#include +#include + +#include "evp_local.h" + +/* FIXME: surely this is available elsewhere? */ +#define EVP_RC4_KEY_SIZE 16 + +typedef struct { + RC4_KEY ks; + MD5_CTX head, tail, md; + size_t payload_length; +} EVP_RC4_HMAC_MD5; + +#define NO_PAYLOAD_LENGTH ((size_t)-1) + +void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out, + MD5_CTX *ctx, const void *inp, size_t blocks); + +#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data) + +static int +rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); + + RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey); + + MD5_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return 1; +} + +#if !defined(OPENSSL_NO_ASM) && defined(RC4_MD5_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) && \ + !(defined(__APPLE__) && defined(__MACH__)) +#define STITCHED_CALL +#include "x86_arch.h" +#endif + +#if !defined(STITCHED_CALL) +#define rc4_off 0 +#define md5_off 0 +#endif + +static int +rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); +#if defined(STITCHED_CALL) + size_t rc4_off = 32-1-(key->ks.x&(32-1)), /* 32 is $MOD from rc4_md5-x86_64.pl */ + md5_off = MD5_CBLOCK - key->md.num, + blocks; + unsigned int l; +#endif + size_t plen = key->payload_length; + + if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH)) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; +#if defined(STITCHED_CALL) + /* cipher has to "fall behind" */ + if (rc4_off > md5_off) + md5_off += MD5_CBLOCK; + + if (plen > md5_off && + (blocks = (plen - md5_off) / MD5_CBLOCK) && + (OPENSSL_cpu_caps() & CPUCAP_MASK_INTELP4) == 0) { + MD5_Update(&key->md, in, md5_off); + RC4(&key->ks, rc4_off, in, out); + + rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, + &key->md, in + md5_off, blocks); + blocks *= MD5_CBLOCK; + rc4_off += blocks; + md5_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + rc4_off = 0; + md5_off = 0; + } +#endif + MD5_Update(&key->md, in + md5_off, plen - md5_off); + + if (plen!=len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + rc4_off, in + rc4_off, + plen - rc4_off); + + /* calculate HMAC and append it to payload */ + MD5_Final(out + plen, &key->md); + key->md = key->tail; + MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH); + MD5_Final(out + plen, &key->md); + + /* encrypt HMAC at once */ + RC4(&key->ks, len - rc4_off, out + rc4_off, + out + rc4_off); + } else { + RC4(&key->ks, len - rc4_off, in + rc4_off, + out + rc4_off); + } + } else { + unsigned char mac[MD5_DIGEST_LENGTH]; +#if defined(STITCHED_CALL) + /* digest has to "fall behind" */ + if (md5_off > rc4_off) + rc4_off += 2*MD5_CBLOCK; + else + rc4_off += MD5_CBLOCK; + + if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) && + (OPENSSL_cpu_caps() & CPUCAP_MASK_INTELP4) == 0) { + RC4(&key->ks, rc4_off, in, out); + MD5_Update(&key->md, out, md5_off); + + rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, + &key->md, out + md5_off, blocks); + blocks *= MD5_CBLOCK; + rc4_off += blocks; + md5_off += blocks; + l = (key->md.Nl + (blocks << 3)) & 0xffffffffU; + if (l < key->md.Nl) + key->md.Nh++; + key->md.Nl = l; + key->md.Nh += blocks >> 29; + } else { + md5_off = 0; + rc4_off = 0; + } +#endif + /* decrypt HMAC at once */ + RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); + if (plen!=NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ + MD5_Update(&key->md, out + md5_off, plen - md5_off); + + /* calculate HMAC and verify it */ + MD5_Final(mac, &key->md); + key->md = key->tail; + MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH); + MD5_Final(mac, &key->md); + + if (memcmp(out + plen, mac, MD5_DIGEST_LENGTH)) + return 0; + } else { + MD5_Update(&key->md, out + md5_off, len - md5_off); + } + } + + key->payload_length = NO_PAYLOAD_LENGTH; + + return 1; +} + +static int +rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset (hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + MD5_Init(&key->head); + MD5_Update(&key->head, ptr, arg); + MD5_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + MD5_Init(&key->head); + MD5_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + MD5_Init(&key->tail); + MD5_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len = p[arg - 2] << 8 | p[arg - 1]; + + if (!ctx->encrypt) { + if (len < MD5_DIGEST_LENGTH) + return -1; + len -= MD5_DIGEST_LENGTH; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->payload_length = len; + key->md = key->head; + MD5_Update(&key->md, p, arg); + + return MD5_DIGEST_LENGTH; + } + default: + return -1; + } +} + +static EVP_CIPHER r4_hmac_md5_cipher = { +#ifdef NID_rc4_hmac_md5 + NID_rc4_hmac_md5, +#else + NID_undef, +#endif + 1, EVP_RC4_KEY_SIZE, 0, + EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH|EVP_CIPH_FLAG_AEAD_CIPHER, + rc4_hmac_md5_init_key, + rc4_hmac_md5_cipher, + NULL, + sizeof(EVP_RC4_HMAC_MD5), + NULL, + NULL, + rc4_hmac_md5_ctrl, + NULL +}; + +const EVP_CIPHER * +EVP_rc4_hmac_md5(void) +{ + return (&r4_hmac_md5_cipher); +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_sm4.c b/Libraries/libressl/crypto/evp/e_sm4.c new file mode 100644 index 000000000..c1664db39 --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_sm4.c @@ -0,0 +1,267 @@ +/* $OpenBSD: e_sm4.c,v 1.9 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2017, 2019 Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef OPENSSL_NO_SM4 +#include +#include +#include + +#include "evp_local.h" + +typedef struct { + SM4_KEY ks; +} EVP_SM4_KEY; + +static int +sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + SM4_set_key(key, ctx->cipher_data); + return 1; +} + +static void +sm4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SM4_KEY *key, unsigned char *ivec, const int enc) +{ + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, + (block128_f)SM4_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, + (block128_f)SM4_decrypt); +} + +static void +sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, + const SM4_KEY *key, unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, + (block128_f)SM4_encrypt); +} + +static void +sm4_ecb_encrypt(const unsigned char *in, unsigned char *out, const SM4_KEY *key, + const int enc) +{ + if (enc) + SM4_encrypt(in, out, key); + else + SM4_decrypt(in, out, key); +} + +static void +sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, + const SM4_KEY *key, unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, + (block128_f)SM4_encrypt); +} + +static int +sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + sm4_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + sm4_cbc_encrypt(in, out, inl, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); + + return 1; +} + +static int +sm4_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t chunk = EVP_MAXCHUNK; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + sm4_cfb128_encrypt(in, out, chunk, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int +sm4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + size_t i, bl; + + bl = ctx->cipher->block_size; + + if (inl < bl) + return 1; + + inl -= bl; + + for (i = 0; i <= inl; i += bl) + sm4_ecb_encrypt(in + i, out + i, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->encrypt); + + return 1; +} + +static int +sm4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + sm4_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + + if (inl) + sm4_ofb128_encrypt(in, out, inl, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); + + return 1; +} + +static const EVP_CIPHER sm4_cbc = { + .nid = NID_sm4_cbc, + .block_size = 16, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, + .init = sm4_init_key, + .do_cipher = sm4_cbc_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_SM4_KEY), + .set_asn1_parameters = 0, + .get_asn1_parameters = 0, + .ctrl = 0, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_sm4_cbc(void) +{ + return &sm4_cbc; +} + +static const EVP_CIPHER sm4_cfb128 = { + .nid = NID_sm4_cfb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE, + .init = sm4_init_key, + .do_cipher = sm4_cfb128_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_SM4_KEY), + .set_asn1_parameters = 0, + .get_asn1_parameters = 0, + .ctrl = 0, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_sm4_cfb128(void) +{ + return &sm4_cfb128; +} + +static const EVP_CIPHER sm4_ofb = { + .nid = NID_sm4_ofb128, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE, + .init = sm4_init_key, + .do_cipher = sm4_ofb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_SM4_KEY), + .set_asn1_parameters = 0, + .get_asn1_parameters = 0, + .ctrl = 0, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_sm4_ofb(void) +{ + return &sm4_ofb; +} + +static const EVP_CIPHER sm4_ecb = { + .nid = NID_sm4_ecb, + .block_size = 16, + .key_len = 16, + .iv_len = 0, + .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, + .init = sm4_init_key, + .do_cipher = sm4_ecb_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_SM4_KEY), + .set_asn1_parameters = 0, + .get_asn1_parameters = 0, + .ctrl = 0, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_sm4_ecb(void) +{ + return &sm4_ecb; +} + +static int +sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + size_t len) +{ + EVP_SM4_KEY *key = ((EVP_SM4_KEY *)(ctx)->cipher_data); + + CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf, + &ctx->num, (block128_f)SM4_encrypt); + return 1; +} + +static const EVP_CIPHER sm4_ctr_mode = { + .nid = NID_sm4_ctr, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = sm4_init_key, + .do_cipher = sm4_ctr_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_SM4_KEY), + .set_asn1_parameters = NULL, + .get_asn1_parameters = NULL, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_sm4_ctr(void) +{ + return &sm4_ctr_mode; +} +#endif diff --git a/Libraries/libressl/crypto/evp/e_xcbc_d.c b/Libraries/libressl/crypto/evp/e_xcbc_d.c new file mode 100644 index 000000000..32f9f2eaa --- /dev/null +++ b/Libraries/libressl/crypto/evp/e_xcbc_d.c @@ -0,0 +1,137 @@ +/* $OpenBSD: e_xcbc_d.c,v 1.15 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_DES + +#include +#include +#include + +#include "evp_local.h" + +static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + + +typedef struct { + DES_key_schedule ks;/* key schedule */ + DES_cblock inw; + DES_cblock outw; +} DESX_CBC_KEY; + +#define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data) + +static const EVP_CIPHER d_xcbc_cipher = { + NID_desx_cbc, + 8, 24, 8, + EVP_CIPH_CBC_MODE, + desx_cbc_init_key, + desx_cbc_cipher, + NULL, + sizeof(DESX_CBC_KEY), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL, + NULL +}; + +const EVP_CIPHER * +EVP_desx_cbc(void) +{ + return (&d_xcbc_cipher); +} + +static int +desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + + DES_set_key_unchecked(deskey, &data(ctx)->ks); + memcpy(&data(ctx)->inw[0], &key[8], 8); + memcpy(&data(ctx)->outw[0], &key[16], 8); + + return 1; +} + +static int +desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw, + &data(ctx)->outw, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw, + &data(ctx)->outw, ctx->encrypt); + return 1; +} +#endif diff --git a/Libraries/libressl/crypto/evp/encode.c b/Libraries/libressl/crypto/evp/encode.c new file mode 100644 index 000000000..c62a1dea8 --- /dev/null +++ b/Libraries/libressl/crypto/evp/encode.c @@ -0,0 +1,414 @@ +/* $OpenBSD: encode.c,v 1.32 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include "evp_local.h" + +static unsigned char conv_ascii2bin(unsigned char a); +#define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) + +/* 64 char lines + * pad input with 0 + * left over chars are set to = + * 1 byte => xx== + * 2 bytes => xxx= + * 3 bytes => xxxx + */ +#define BIN_PER_LINE (64/4*3) +#define CHUNKS_PER_LINE (64/4) +#define CHAR_PER_LINE (64+1) + +static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ +abcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* 0xF0 is a EOLN + * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). + * 0xF2 is EOF + * 0xE0 is ignore at start of line. + * 0xFF is error + */ + +#define B64_EOLN 0xF0 +#define B64_CR 0xF1 +#define B64_EOF 0xF2 +#define B64_WS 0xE0 +#define B64_ERROR 0xFF +#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) +#define B64_BASE64(a) !B64_NOT_BASE64(a) + +static const unsigned char data_ascii2bin[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +static unsigned char +conv_ascii2bin(unsigned char a) +{ + if (a & 0x80) + return B64_ERROR; + return data_ascii2bin[a]; +} + +EVP_ENCODE_CTX * +EVP_ENCODE_CTX_new(void) +{ + return calloc(1, sizeof(EVP_ENCODE_CTX)); +} + +void +EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + free(ctx); +} + +void +EVP_EncodeInit(EVP_ENCODE_CTX *ctx) +{ + ctx->length = 48; + ctx->num = 0; + ctx->line_num = 0; +} + +int +EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int i, j; + size_t total = 0; + + *outl = 0; + if (inl <= 0) + return 0; + OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); + if (ctx->length - ctx->num > inl) { + memcpy(&(ctx->enc_data[ctx->num]), in, inl); + ctx->num += inl; + return 1; + } + if (ctx->num != 0) { + i = ctx->length - ctx->num; + memcpy(&(ctx->enc_data[ctx->num]), in, i); + in += i; + inl -= i; + j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); + ctx->num = 0; + out += j; + *(out++) = '\n'; + *out = '\0'; + total = j + 1; + } + while (inl >= ctx->length && total <= INT_MAX) { + j = EVP_EncodeBlock(out, in, ctx->length); + in += ctx->length; + inl -= ctx->length; + out += j; + *(out++) = '\n'; + *out = '\0'; + total += j + 1; + } + if (total > INT_MAX) { + /* Too much output data! */ + *outl = 0; + return 0; + } + if (inl != 0) + memcpy(&(ctx->enc_data[0]), in, inl); + ctx->num = inl; + *outl = total; + + return 1; +} + +void +EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) +{ + unsigned int ret = 0; + + if (ctx->num != 0) { + ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); + out[ret++] = '\n'; + out[ret] = '\0'; + ctx->num = 0; + } + *outl = ret; +} + +int +EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) +{ + int i, ret = 0; + unsigned long l; + + for (i = dlen; i > 0; i -= 3) { + if (i >= 3) { + l = (((unsigned long)f[0]) << 16L) | + (((unsigned long)f[1]) << 8L) | f[2]; + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = conv_bin2ascii(l >> 6L); + *(t++) = conv_bin2ascii(l ); + } else { + l = ((unsigned long)f[0]) << 16L; + if (i == 2) + l |= ((unsigned long)f[1] << 8L); + + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(t++) = '='; + } + ret += 4; + f += 3; + } + + *t = '\0'; + return (ret); +} + +void +EVP_DecodeInit(EVP_ENCODE_CTX *ctx) +{ + ctx->num = 0; + ctx->length = 0; + ctx->line_num = 0; + ctx->expect_nl = 0; +} + +int +EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len; + unsigned char *d; + + n = ctx->num; + d = ctx->enc_data; + + if (n > 0 && d[n - 1] == '=') { + eof++; + if (n > 1 && d[n - 2] == '=') + eof++; + } + + /* Legacy behaviour: an empty input chunk signals end of input. */ + if (inl == 0) { + rv = 0; + goto end; + } + + for (i = 0; i < inl; i++) { + tmp = *(in++); + v = conv_ascii2bin(tmp); + if (v == B64_ERROR) { + rv = -1; + goto end; + } + + if (tmp == '=') { + eof++; + } else if (eof > 0 && B64_BASE64(v)) { + /* More data after padding. */ + rv = -1; + goto end; + } + + if (eof > 2) { + rv = -1; + goto end; + } + + if (v == B64_EOF) { + seof = 1; + goto tail; + } + + /* Only save valid base64 characters. */ + if (B64_BASE64(v)) { + if (n >= 64) { + /* + * We increment n once per loop, and empty the + * buffer as soon as we reach 64 characters, so + * this can only happen if someone's manually + * messed with the ctx. Refuse to write any + * more data. + */ + rv = -1; + goto end; + } + OPENSSL_assert(n < (int)sizeof(ctx->enc_data)); + d[n++] = tmp; + } + + if (n == 64) { + decoded_len = EVP_DecodeBlock(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += decoded_len - eof; + out += decoded_len - eof; + } + } + + /* + * Legacy behaviour: if the current line is a full base64-block (i.e., + * has 0 mod 4 base64 characters), it is processed immediately. We keep + * this behaviour as applications may not be calling EVP_DecodeFinal + * properly. + */ + tail: + if (n > 0) { + if ((n & 3) == 0) { + decoded_len = EVP_DecodeBlock(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += (decoded_len - eof); + } else if (seof) { + /* EOF in the middle of a base64 block. */ + rv = -1; + goto end; + } + } + + rv = seof || (n == 0 && eof) ? 0 : 1; + end: + /* Legacy behaviour. This should probably rather be zeroed on error. */ + *outl = ret; + ctx->num = n; + return (rv); +} + +int +EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) +{ + int i, ret = 0, a, b, c, d; + unsigned long l; + + /* trim white space from the start of the line. */ + while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { + f++; + n--; + } + + /* strip off stuff at the end of the line + * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */ + while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) + n--; + + if (n % 4 != 0) + return (-1); + + for (i = 0; i < n; i += 4) { + a = conv_ascii2bin(*(f++)); + b = conv_ascii2bin(*(f++)); + c = conv_ascii2bin(*(f++)); + d = conv_ascii2bin(*(f++)); + if ((a & 0x80) || (b & 0x80) || + (c & 0x80) || (d & 0x80)) + return (-1); + l = ((((unsigned long)a) << 18L) | + (((unsigned long)b) << 12L) | + (((unsigned long)c) << 6L) | + (((unsigned long)d))); + *(t++) = (unsigned char)(l >> 16L) & 0xff; + *(t++) = (unsigned char)(l >> 8L) & 0xff; + *(t++) = (unsigned char)(l) & 0xff; + ret += 3; + } + return (ret); +} + +int +EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + *outl = 0; + if (ctx->num != 0) { + i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num); + if (i < 0) + return (-1); + ctx->num = 0; + *outl = i; + return (1); + } else + return (1); +} diff --git a/Libraries/libressl/crypto/evp/evp_aead.c b/Libraries/libressl/crypto/evp/evp_aead.c new file mode 100644 index 000000000..3579533e5 --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_aead.c @@ -0,0 +1,160 @@ +/* $OpenBSD: evp_aead.c,v 1.10 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "evp_local.h" + +size_t +EVP_AEAD_key_length(const EVP_AEAD *aead) +{ + return aead->key_len; +} + +size_t +EVP_AEAD_nonce_length(const EVP_AEAD *aead) +{ + return aead->nonce_len; +} + +size_t +EVP_AEAD_max_overhead(const EVP_AEAD *aead) +{ + return aead->overhead; +} + +size_t +EVP_AEAD_max_tag_len(const EVP_AEAD *aead) +{ + return aead->max_tag_len; +} + +int +EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const unsigned char *key, size_t key_len, size_t tag_len, ENGINE *impl) +{ + ctx->aead = aead; + if (key_len != aead->key_len) { + EVPerror(EVP_R_UNSUPPORTED_KEY_SIZE); + return 0; + } + return aead->init(ctx, key, key_len, tag_len); +} + +void +EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) +{ + if (ctx->aead == NULL) + return; + ctx->aead->cleanup(ctx); + ctx->aead = NULL; +} + +EVP_AEAD_CTX * +EVP_AEAD_CTX_new(void) +{ + return calloc(1, sizeof(EVP_AEAD_CTX)); +} + +void +EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx) +{ + if (ctx == NULL) + return; + + EVP_AEAD_CTX_cleanup(ctx); + free(ctx); +} + +/* check_alias returns 0 if out points within the buffer determined by in + * and in_len and 1 otherwise. + * + * When processing, there's only an issue if out points within in[:in_len] + * and isn't equal to in. If that's the case then writing the output will + * stomp input that hasn't been read yet. + * + * This function checks for that case. */ +static int +check_alias(const unsigned char *in, size_t in_len, const unsigned char *out) +{ + if (out <= in) + return 1; + if (in + in_len <= out) + return 1; + return 0; +} + +int +EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, + size_t max_out_len, const unsigned char *nonce, size_t nonce_len, + const unsigned char *in, size_t in_len, const unsigned char *ad, + size_t ad_len) +{ + size_t possible_out_len = in_len + ctx->aead->overhead; + + /* Overflow. */ + if (possible_out_len < in_len) { + EVPerror(EVP_R_TOO_LARGE); + goto error; + } + + if (!check_alias(in, in_len, out)) { + EVPerror(EVP_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (ctx->aead->seal(ctx, out, out_len, max_out_len, nonce, nonce_len, + in, in_len, ad, ad_len)) { + return 1; + } + +error: + /* In the event of an error, clear the output buffer so that a caller + * that doesn't check the return value doesn't send raw data. */ + memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int +EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, + size_t max_out_len, const unsigned char *nonce, size_t nonce_len, + const unsigned char *in, size_t in_len, const unsigned char *ad, + size_t ad_len) +{ + if (!check_alias(in, in_len, out)) { + EVPerror(EVP_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len, + in, in_len, ad, ad_len)) { + return 1; + } + +error: + /* In the event of an error, clear the output buffer so that a caller + * that doesn't check the return value doesn't try and process bad + * data. */ + memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} diff --git a/Libraries/libressl/crypto/evp/evp_enc.c b/Libraries/libressl/crypto/evp/evp_enc.c new file mode 100644 index 000000000..7534b4c9d --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_enc.c @@ -0,0 +1,725 @@ +/* $OpenBSD: evp_enc.c,v 1.53 2023/09/10 16:53:56 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "evp_local.h" + +int +EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc) +{ + if (cipher != NULL) + EVP_CIPHER_CTX_cleanup(ctx); + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} + +int +EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, const unsigned char *iv, int enc) +{ + if (enc == -1) + enc = ctx->encrypt; + else { + if (enc) + enc = 1; + ctx->encrypt = enc; + } +#ifndef OPENSSL_NO_ENGINE + /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts + * so this context may already have an ENGINE! Try to avoid releasing + * the previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unnecessary. */ + if (ctx->engine && ctx->cipher && + (!cipher || (cipher && (cipher->nid == ctx->cipher->nid)))) + goto skip_to_init; +#endif + if (cipher) { + /* Ensure a context left lying around from last time is cleared + * (the previous check attempted to avoid this if the same + * ENGINE and EVP_CIPHER could be used). */ + if (ctx->cipher) { + unsigned long flags = ctx->flags; + EVP_CIPHER_CTX_cleanup(ctx); + /* Restore encrypt and flags */ + ctx->encrypt = enc; + ctx->flags = flags; + } +#ifndef OPENSSL_NO_ENGINE + if (impl) { + if (!ENGINE_init(impl)) { + EVPerror(EVP_R_INITIALIZATION_ERROR); + return 0; + } + } else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_cipher_engine(cipher->nid); + if (impl) { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_CIPHER *c = + ENGINE_get_cipher(impl, cipher->nid); + if (!c) { + EVPerror(EVP_R_INITIALIZATION_ERROR); + return 0; + } + /* We'll use the ENGINE's private cipher definition */ + cipher = c; + /* Store the ENGINE functional reference so we know + * 'cipher' came from an ENGINE and we need to release + * it when done. */ + ctx->engine = impl; + } else + ctx->engine = NULL; +#endif + + ctx->cipher = cipher; + if (ctx->cipher->ctx_size) { + ctx->cipher_data = calloc(1, ctx->cipher->ctx_size); + if (ctx->cipher_data == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + ctx->cipher_data = NULL; + } + ctx->key_len = cipher->key_len; + ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + EVPerror(EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + } else if (!ctx->cipher) { + EVPerror(EVP_R_NO_CIPHER_SET); + return 0; + } +#ifndef OPENSSL_NO_ENGINE +skip_to_init: +#endif + /* we assume block size is a power of 2 in *cryptUpdate */ + if (ctx->cipher->block_size != 1 && + ctx->cipher->block_size != 8 && + ctx->cipher->block_size != 16) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + return 0; + } + + if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) && + EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) { + EVPerror(EVP_R_WRAP_MODE_NOT_ALLOWED); + return 0; + } + + if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch (EVP_CIPHER_CTX_mode(ctx)) { + + case EVP_CIPH_STREAM_CIPHER: + case EVP_CIPH_ECB_MODE: + break; + + case EVP_CIPH_CFB_MODE: + case EVP_CIPH_OFB_MODE: + + ctx->num = 0; + /* fall-through */ + + case EVP_CIPH_CBC_MODE: + + if ((size_t)EVP_CIPHER_CTX_iv_length(ctx) > + sizeof(ctx->iv)) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + if (iv) + memcpy(ctx->oiv, iv, + EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, + EVP_CIPHER_CTX_iv_length(ctx)); + break; + + case EVP_CIPH_CTR_MODE: + ctx->num = 0; + /* Don't reuse IV for CTR mode */ + if (iv) + memcpy(ctx->iv, iv, + EVP_CIPHER_CTX_iv_length(ctx)); + break; + + default: + return 0; + break; + } + } + + if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if (!ctx->cipher->init(ctx, key, iv, enc)) + return 0; + } + ctx->buf_len = 0; + ctx->final_used = 0; + ctx->block_mask = ctx->cipher->block_size - 1; + return 1; +} + +int +EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + if (ctx->encrypt) + return EVP_EncryptUpdate(ctx, out, outl, in, inl); + else + return EVP_DecryptUpdate(ctx, out, outl, in, inl); +} + +int +EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + if (ctx->encrypt) + return EVP_EncryptFinal_ex(ctx, out, outl); + else + return EVP_DecryptFinal_ex(ctx, out, outl); +} + +__warn_references(EVP_CipherFinal, + "EVP_CipherFinal is often misused, please use EVP_CipherFinal_ex and EVP_CIPHER_CTX_cleanup"); + +int +EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + if (ctx->encrypt) + ret = EVP_EncryptFinal_ex(ctx, out, outl); + else + ret = EVP_DecryptFinal_ex(ctx, out, outl); + return ret; +} + +int +EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit(ctx, cipher, key, iv, 1); +} + +int +EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); +} + +int +EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit(ctx, cipher, key, iv, 0); +} + +int +EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); +} + +int +EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int i, j, bl; + + *outl = 0; + + if (inl < 0) + return 0; + + if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE) + return 1; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->do_cipher(ctx, out, in, inl); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + + if (ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { + if (ctx->cipher->do_cipher(ctx, out, in, inl)) { + *outl = inl; + return 1; + } else { + *outl = 0; + return 0; + } + } + i = ctx->buf_len; + bl = ctx->cipher->block_size; + if ((size_t)bl > sizeof(ctx->buf)) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + *outl = 0; + return 0; + } + if (i != 0) { + if (bl - i > inl) { + memcpy(&(ctx->buf[i]), in, inl); + ctx->buf_len += inl; + *outl = 0; + return 1; + } else { + j = bl - i; + + /* + * Once we've processed the first j bytes from in, the + * amount of data left that is a multiple of the block + * length is (inl - j) & ~(bl - 1). Ensure this plus + * the block processed from ctx-buf doesn't overflow. + */ + if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) { + EVPerror(EVP_R_TOO_LARGE); + return 0; + } + memcpy(&(ctx->buf[i]), in, j); + if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl)) + return 0; + inl -= j; + in += j; + out += bl; + *outl = bl; + } + } else + *outl = 0; + i = inl&(bl - 1); + inl -= i; + if (inl > 0) { + if (!ctx->cipher->do_cipher(ctx, out, in, inl)) + return 0; + *outl += inl; + } + + if (i != 0) + memcpy(ctx->buf, &(in[inl]), i); + ctx->buf_len = i; + return 1; +} + +__warn_references(EVP_EncryptFinal, + "EVP_EncryptFinal is often misused, please use EVP_EncryptFinal_ex and EVP_CIPHER_CTX_cleanup"); + +int +EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + + ret = EVP_EncryptFinal_ex(ctx, out, outl); + return ret; +} + +int +EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int n, ret; + unsigned int i, b, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + ret = ctx->cipher->do_cipher(ctx, out, NULL, 0); + if (ret < 0) + return 0; + else + *outl = ret; + return 1; + } + + b = ctx->cipher->block_size; + if (b > sizeof ctx->buf) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + return 0; + } + if (b == 1) { + *outl = 0; + return 1; + } + bl = ctx->buf_len; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (bl) { + EVPerror(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *outl = 0; + return 1; + } + + n = b - bl; + for (i = bl; i < b; i++) + ctx->buf[i] = n; + ret = ctx->cipher->do_cipher(ctx, out, ctx->buf, b); + + + if (ret) + *outl = b; + + return ret; +} + +int +EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int fix_len; + unsigned int b; + + *outl = 0; + + if (inl < 0) + return 0; + + if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE) + return 1; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + fix_len = ctx->cipher->do_cipher(ctx, out, in, inl); + if (fix_len < 0) { + *outl = 0; + return 0; + } else + *outl = fix_len; + return 1; + } + + if (ctx->flags & EVP_CIPH_NO_PADDING) + return EVP_EncryptUpdate(ctx, out, outl, in, inl); + + b = ctx->cipher->block_size; + if (b > sizeof ctx->final) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + return 0; + } + + if (ctx->final_used) { + /* + * final_used is only ever set if buf_len is 0. Therefore the + * maximum length output we will ever see from EVP_EncryptUpdate + * is inl & ~(b - 1). Since final_used is set, the final output + * length is (inl & ~(b - 1)) + b. Ensure it doesn't overflow. + */ + if ((inl & ~(b - 1)) > INT_MAX - b) { + EVPerror(EVP_R_TOO_LARGE); + return 0; + } + memcpy(out, ctx->final, b); + out += b; + fix_len = 1; + } else + fix_len = 0; + + + if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) + return 0; + + /* if we have 'decrypted' a multiple of block size, make sure + * we have a copy of this last block */ + if (b > 1 && !ctx->buf_len) { + *outl -= b; + ctx->final_used = 1; + memcpy(ctx->final, &out[*outl], b); + } else + ctx->final_used = 0; + + if (fix_len) + *outl += b; + + return 1; +} + +__warn_references(EVP_DecryptFinal, + "EVP_DecryptFinal is often misused, please use EVP_DecryptFinal_ex and EVP_CIPHER_CTX_cleanup"); + +int +EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + + ret = EVP_DecryptFinal_ex(ctx, out, outl); + return ret; +} + +int +EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i, n; + unsigned int b; + *outl = 0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->do_cipher(ctx, out, NULL, 0); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + + b = ctx->cipher->block_size; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (ctx->buf_len) { + EVPerror(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *outl = 0; + return 1; + } + if (b > 1) { + if (ctx->buf_len || !ctx->final_used) { + EVPerror(EVP_R_WRONG_FINAL_BLOCK_LENGTH); + return (0); + } + if (b > sizeof ctx->final) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + return 0; + } + n = ctx->final[b - 1]; + if (n == 0 || n > (int)b) { + EVPerror(EVP_R_BAD_DECRYPT); + return (0); + } + for (i = 0; i < n; i++) { + if (ctx->final[--b] != n) { + EVPerror(EVP_R_BAD_DECRYPT); + return (0); + } + } + n = ctx->cipher->block_size - n; + for (i = 0; i < n; i++) + out[i] = ctx->final[i]; + *outl = n; + } else + *outl = 0; + return (1); +} + +EVP_CIPHER_CTX * +EVP_CIPHER_CTX_new(void) +{ + return calloc(1, sizeof(EVP_CIPHER_CTX)); +} + +void +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + if (ctx == NULL) + return; + + EVP_CIPHER_CTX_cleanup(ctx); + + free(ctx); +} + +void +EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) +{ + memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); +} + +int +EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *a) +{ + return EVP_CIPHER_CTX_cleanup(a); +} + +int +EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) +{ + if (c->cipher != NULL) { + /* XXX - Avoid leaks, so ignore return value of cleanup()... */ + if (c->cipher->cleanup != NULL) + c->cipher->cleanup(c); + if (c->cipher_data != NULL) + explicit_bzero(c->cipher_data, c->cipher->ctx_size); + } + + /* XXX - store size of cipher_data so we can always freezero(). */ + free(c->cipher_data); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(c->engine); +#endif + + explicit_bzero(c, sizeof(EVP_CIPHER_CTX)); + + return 1; +} + +int +EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) +{ + if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) + return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, + keylen, NULL); + if (c->key_len == keylen) + return 1; + if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { + c->key_len = keylen; + return 1; + } + EVPerror(EVP_R_INVALID_KEY_LENGTH); + return 0; +} + +int +EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) +{ + if (pad) + ctx->flags &= ~EVP_CIPH_NO_PADDING; + else + ctx->flags |= EVP_CIPH_NO_PADDING; + return 1; +} + +int +EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + int ret; + + if (!ctx->cipher) { + EVPerror(EVP_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->cipher->ctrl) { + EVPerror(EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, type, arg, ptr); + if (ret == -1) { + EVPerror(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + return ret; +} + +int +EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) +{ + if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) + return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); + arc4random_buf(key, ctx->key_len); + return 1; +} + +int +EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) +{ + if ((in == NULL) || (in->cipher == NULL)) { + EVPerror(EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a cipher context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) { + EVPerror(ERR_R_ENGINE_LIB); + return 0; + } +#endif + + EVP_CIPHER_CTX_cleanup(out); + memcpy(out, in, sizeof *out); + + if (in->cipher_data && in->cipher->ctx_size) { + out->cipher_data = calloc(1, in->cipher->ctx_size); + if (out->cipher_data == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); + } + + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) { + if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, + 0, out)) { + /* + * If the custom copy control failed, assume that there + * may still be pointers copied in the cipher_data that + * we do not own. This may result in a leak from a bad + * custom copy control, but that's preferable to a + * double free... + */ + freezero(out->cipher_data, in->cipher->ctx_size); + out->cipher_data = NULL; + return 0; + } + } + + return 1; +} diff --git a/Libraries/libressl/crypto/evp/evp_err.c b/Libraries/libressl/crypto/evp/evp_err.c new file mode 100644 index 000000000..039e17e6c --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_err.c @@ -0,0 +1,166 @@ +/* $OpenBSD: evp_err.c,v 1.32 2023/07/07 19:37:53 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason) + +static ERR_STRING_DATA EVP_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA EVP_str_reasons[] = { + {ERR_REASON(EVP_R_AES_IV_SETUP_FAILED) , "aes iv setup failed"}, + {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED) , "aes key setup failed"}, + {ERR_REASON(EVP_R_ASN1_LIB) , "asn1 lib"}, + {ERR_REASON(EVP_R_BAD_BLOCK_LENGTH) , "bad block length"}, + {ERR_REASON(EVP_R_BAD_DECRYPT) , "bad decrypt"}, + {ERR_REASON(EVP_R_BAD_KEY_LENGTH) , "bad key length"}, + {ERR_REASON(EVP_R_BN_DECODE_ERROR) , "bn decode error"}, + {ERR_REASON(EVP_R_BN_PUBKEY_ERROR) , "bn pubkey error"}, + {ERR_REASON(EVP_R_BUFFER_TOO_SMALL) , "buffer too small"}, + {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), "camellia key setup failed"}, + {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"}, + {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) , "command not supported"}, + {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED) , "ctrl not implemented"}, + {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), "ctrl operation not implemented"}, + {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), "data not multiple of block length"}, + {ERR_REASON(EVP_R_DECODE_ERROR) , "decode error"}, + {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) , "different key types"}, + {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) , "different parameters"}, + {ERR_REASON(EVP_R_DISABLED_FOR_FIPS) , "disabled for fips"}, + {ERR_REASON(EVP_R_ENCODE_ERROR) , "encode error"}, + {ERR_REASON(EVP_R_ERROR_LOADING_SECTION) , "error loading section"}, + {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"}, + {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"}, + {ERR_REASON(EVP_R_EXPECTING_AN_HMAC_KEY), "expecting an hmac key"}, + {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) , "expecting an rsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) , "expecting a dh key"}, + {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) , "expecting a dsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) , "expecting a ecdsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) , "expecting a ec key"}, + {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(EVP_R_GET_RAW_KEY_FAILED) , "get raw key failed"}, + {ERR_REASON(EVP_R_INITIALIZATION_ERROR) , "initialization error"}, + {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) , "input not initialized"}, + {ERR_REASON(EVP_R_INVALID_DIGEST) , "invalid digest"}, + {ERR_REASON(EVP_R_INVALID_FIPS_MODE) , "invalid fips mode"}, + {ERR_REASON(EVP_R_INVALID_IV_LENGTH) , "invalid iv length"}, + {ERR_REASON(EVP_R_INVALID_KEY_LENGTH) , "invalid key length"}, + {ERR_REASON(EVP_R_INVALID_OPERATION) , "invalid operation"}, + {ERR_REASON(EVP_R_IV_TOO_LARGE) , "iv too large"}, + {ERR_REASON(EVP_R_KEYGEN_FAILURE) , "keygen failure"}, + {ERR_REASON(EVP_R_KEY_SETUP_FAILED) , "key setup failed"}, + {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"}, + {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) , "method not supported"}, + {ERR_REASON(EVP_R_MISSING_PARAMETERS) , "missing parameters"}, + {ERR_REASON(EVP_R_NO_CIPHER_SET) , "no cipher set"}, + {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST) , "no default digest"}, + {ERR_REASON(EVP_R_NO_DIGEST_SET) , "no digest set"}, + {ERR_REASON(EVP_R_NO_DSA_PARAMETERS) , "no dsa parameters"}, + {ERR_REASON(EVP_R_NO_KEY_SET) , "no key set"}, + {ERR_REASON(EVP_R_NO_OPERATION_SET) , "no operation set"}, + {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), "no sign function configured"}, + {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), "no verify function configured"}, + {ERR_REASON(EVP_R_ONLY_ONESHOT_SUPPORTED), "only oneshot supported"}, + {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, + {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, + {ERR_REASON(EVP_R_OUTPUT_ALIASES_INPUT) , "output aliases input"}, + {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), "pkcs8 unknown broken type"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, + {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) , "public key not rsa"}, + {ERR_REASON(EVP_R_TAG_TOO_LARGE) , "tag too large"}, + {ERR_REASON(EVP_R_TOO_LARGE) , "too large"}, + {ERR_REASON(EVP_R_UNKNOWN_CIPHER) , "unknown cipher"}, + {ERR_REASON(EVP_R_UNKNOWN_DIGEST) , "unknown digest"}, + {ERR_REASON(EVP_R_UNKNOWN_OPTION) , "unknown option"}, + {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) , "unknown pbe algorithm"}, + {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS), "unsuported number of rounds"}, + {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) , "unsupported algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) , "unsupported cipher"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) , "unsupported keylength"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), "unsupported key derivation function"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE) , "unsupported key size"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRF) , "unsupported prf"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), "unsupported private key algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) , "unsupported salt type"}, + {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"}, + {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, + {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) , "wrong public key type"}, + {0, NULL} +}; + +#endif + +void +ERR_load_EVP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) { + ERR_load_strings(0, EVP_str_functs); + ERR_load_strings(0, EVP_str_reasons); + } +#endif +} diff --git a/Libraries/libressl/crypto/evp/evp_key.c b/Libraries/libressl/crypto/evp/evp_key.c new file mode 100644 index 000000000..2f6e7e70c --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_key.c @@ -0,0 +1,212 @@ +/* $OpenBSD: evp_key.c,v 1.30 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "evp_local.h" + +/* should be init to zeros. */ +static char prompt_string[80]; + +void +EVP_set_pw_prompt(const char *prompt) +{ + if (prompt == NULL) + prompt_string[0] = '\0'; + else { + strlcpy(prompt_string, prompt, sizeof(prompt_string)); + } +} + +char * +EVP_get_pw_prompt(void) +{ + if (prompt_string[0] == '\0') + return (NULL); + else + return (prompt_string); +} + +int +EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) +{ + return EVP_read_pw_string_min(buf, 0, len, prompt, verify); +} + +int +EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, + int verify) +{ + int ret; + char buff[BUFSIZ]; + UI *ui; + + if (len > BUFSIZ) + len = BUFSIZ; + /* Ensure that 0 <= min <= len - 1. In particular, 1 <= len. */ + if (min < 0 || len - 1 < min) + return -1; + if ((prompt == NULL) && (prompt_string[0] != '\0')) + prompt = prompt_string; + ui = UI_new(); + if (ui == NULL) + return -1; + if (UI_add_input_string(ui, prompt, 0, buf, min, len - 1) < 0) + return -1; + if (verify) { + if (UI_add_verify_string(ui, prompt, 0, buff, min, len - 1, buf) + < 0) + return -1; + } + ret = UI_process(ui); + UI_free(ui); + explicit_bzero(buff, BUFSIZ); + return ret; +} + +int +EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, int datal, + int count, unsigned char *key, unsigned char *iv) +{ + EVP_MD_CTX c; + unsigned char md_buf[EVP_MAX_MD_SIZE]; + int niv, nkey, addmd = 0; + unsigned int mds = 0, i; + int rv = 0; + + nkey = type->key_len; + niv = type->iv_len; + + if ((size_t)nkey > EVP_MAX_KEY_LENGTH) { + EVPerror(EVP_R_BAD_KEY_LENGTH); + return 0; + } + if ((size_t)niv > EVP_MAX_IV_LENGTH) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + + if (data == NULL) + return (nkey); + + EVP_MD_CTX_init(&c); + for (;;) { + if (!EVP_DigestInit_ex(&c, md, NULL)) + goto err; + if (addmd++) + if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) + goto err; + if (!EVP_DigestUpdate(&c, data, datal)) + goto err; + if (salt != NULL) + if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) + goto err; + if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) + goto err; + + for (i = 1; i < (unsigned int)count; i++) { + if (!EVP_DigestInit_ex(&c, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) + goto err; + if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) + goto err; + } + i = 0; + if (nkey) { + for (;;) { + if (nkey == 0) + break; + if (i == mds) + break; + if (key != NULL) + *(key++) = md_buf[i]; + nkey--; + i++; + } + } + if (niv && (i != mds)) { + for (;;) { + if (niv == 0) + break; + if (i == mds) + break; + if (iv != NULL) + *(iv++) = md_buf[i]; + niv--; + i++; + } + } + if ((nkey == 0) && (niv == 0)) + break; + } + rv = type->key_len; + +err: + EVP_MD_CTX_cleanup(&c); + explicit_bzero(md_buf, sizeof md_buf); + return rv; +} diff --git a/Libraries/libressl/crypto/evp/evp_lib.c b/Libraries/libressl/crypto/evp/evp_lib.c new file mode 100644 index 000000000..f4e46aea4 --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_lib.c @@ -0,0 +1,572 @@ +/* $OpenBSD: evp_lib.c,v 1.28 2023/09/28 11:29:10 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include + +#include "asn1_local.h" +#include "evp_local.h" + +int +EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->set_asn1_parameters != NULL) + ret = c->cipher->set_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret = EVP_CIPHER_set_asn1_iv(c, type); + else + ret = -1; + return (ret); +} + +int +EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->get_asn1_parameters != NULL) + ret = c->cipher->get_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret = EVP_CIPHER_get_asn1_iv(c, type); + else + ret = -1; + return (ret); +} + +int +EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int l; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + if (l > sizeof(c->iv)) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + i = ASN1_TYPE_get_octetstring(type, c->oiv, l); + if (i != (int)l) + return (-1); + else if (i > 0) + memcpy(c->iv, c->oiv, l); + } + return (i); +} + +int +EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int j; + + if (type != NULL) { + j = EVP_CIPHER_CTX_iv_length(c); + if (j > sizeof(c->iv)) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + i = ASN1_TYPE_set_octetstring(type, c->oiv, j); + } + return (i); +} + +/* Convert the various cipher NIDs and dummies to a proper OID NID */ +int +EVP_CIPHER_type(const EVP_CIPHER *ctx) +{ + int nid; + ASN1_OBJECT *otmp; + nid = EVP_CIPHER_nid(ctx); + + switch (nid) { + case NID_rc2_cbc: + case NID_rc2_64_cbc: + case NID_rc2_40_cbc: + return NID_rc2_cbc; + + case NID_rc4: + case NID_rc4_40: + return NID_rc4; + + case NID_aes_128_cfb128: + case NID_aes_128_cfb8: + case NID_aes_128_cfb1: + return NID_aes_128_cfb128; + + case NID_aes_192_cfb128: + case NID_aes_192_cfb8: + case NID_aes_192_cfb1: + return NID_aes_192_cfb128; + + case NID_aes_256_cfb128: + case NID_aes_256_cfb8: + case NID_aes_256_cfb1: + return NID_aes_256_cfb128; + + case NID_des_cfb64: + case NID_des_cfb8: + case NID_des_cfb1: + return NID_des_cfb64; + + case NID_des_ede3_cfb64: + case NID_des_ede3_cfb8: + case NID_des_ede3_cfb1: + return NID_des_cfb64; + + default: + /* Check it has an OID and it is valid */ + otmp = OBJ_nid2obj(nid); + if (!otmp || !otmp->data) + nid = NID_undef; + ASN1_OBJECT_free(otmp); + return nid; + } +} + +int +EVP_CIPHER_block_size(const EVP_CIPHER *e) +{ + return e->block_size; +} + +int +EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->block_size; +} + +int +EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + unsigned int inl) +{ + return ctx->cipher->do_cipher(ctx, out, in, inl); +} + +const EVP_CIPHER * +EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher; +} + +int +EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) +{ + return ctx->encrypt; +} + +unsigned long +EVP_CIPHER_flags(const EVP_CIPHER *cipher) +{ + return cipher->flags; +} + +unsigned long +EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->flags; +} + +void * +EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) +{ + return ctx->app_data; +} + +void +EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +void * +EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher_data; +} + +void * +EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) +{ + void *old_cipher_data; + + old_cipher_data = ctx->cipher_data; + ctx->cipher_data = cipher_data; + + return old_cipher_data; +} + +int +EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) +{ + return cipher->iv_len; +} + +int +EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) +{ + int iv_length = 0; + + if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_IV_LENGTH) == 0) + return ctx->cipher->iv_len; + + /* + * XXX - sanity would suggest to pass the size of the pointer along, + * but unfortunately we have to match the other crowd. + */ + if (EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, 0, + &iv_length) != 1) + return -1; + + return iv_length; +} + +unsigned char * +EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) +{ + return ctx->buf; +} + +int +EVP_CIPHER_key_length(const EVP_CIPHER *cipher) +{ + return cipher->key_len; +} + +int +EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) +{ + return ctx->key_len; +} + +int +EVP_CIPHER_nid(const EVP_CIPHER *cipher) +{ + return cipher->nid; +} + +int +EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->nid; +} + +int +EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len) +{ + if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) + return 0; + if (len > EVP_MAX_IV_LENGTH) + return 0; /* sanity check; shouldn't happen */ + /* + * Skip the memcpy entirely when the requested IV length is zero, + * since the iv pointer may be NULL or invalid. + */ + if (len != 0) { + if (iv == NULL) + return 0; + memcpy(iv, ctx->iv, len); + } + return 1; +} + +int +EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len) +{ + if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) + return 0; + if (len > EVP_MAX_IV_LENGTH) + return 0; /* sanity check; shouldn't happen */ + /* + * Skip the memcpy entirely when the requested IV length is zero, + * since the iv pointer may be NULL or invalid. + */ + if (len != 0) { + if (iv == NULL) + return 0; + memcpy(ctx->iv, iv, len); + } + return 1; +} + +int +EVP_MD_block_size(const EVP_MD *md) +{ + return md->block_size; +} + +int +EVP_MD_type(const EVP_MD *md) +{ + return md->type; +} + +int +EVP_MD_pkey_type(const EVP_MD *md) +{ + return md->pkey_type; +} + +int +EVP_MD_size(const EVP_MD *md) +{ + if (!md) { + EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL); + return -1; + } + return md->md_size; +} + +unsigned long +EVP_MD_flags(const EVP_MD *md) +{ + return md->flags; +} + +EVP_MD * +EVP_MD_meth_new(int md_type, int pkey_type) +{ + EVP_MD *md; + + if ((md = calloc(1, sizeof(*md))) == NULL) + return NULL; + + md->type = md_type; + md->pkey_type = pkey_type; + + return md; +} + +EVP_MD * +EVP_MD_meth_dup(const EVP_MD *md) +{ + EVP_MD *to; + + if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) == NULL) + return NULL; + + memcpy(to, md, sizeof(*to)); + + return to; +} + +void +EVP_MD_meth_free(EVP_MD *md) +{ + freezero(md, sizeof(*md)); +} + +int +EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize) +{ + md->block_size = blocksize; + return 1; +} + +int +EVP_MD_meth_set_result_size(EVP_MD *md, int result_size) +{ + md->md_size = result_size; + return 1; +} + +int +EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize) +{ + md->ctx_size = datasize; + return 1; +} + +int +EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags) +{ + md->flags = flags; + return 1; +} + +int +EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)) +{ + md->init = init; + return 1; +} + +int +EVP_MD_meth_set_update(EVP_MD *md, + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)) +{ + md->update = update; + return 1; +} + +int +EVP_MD_meth_set_final(EVP_MD *md, + int (*final)(EVP_MD_CTX *ctx, unsigned char *md)) +{ + md->final = final; + return 1; +} + +int +EVP_MD_meth_set_copy(EVP_MD *md, + int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)) +{ + md->copy = copy; + return 1; +} + +int +EVP_MD_meth_set_cleanup(EVP_MD *md, + int (*cleanup)(EVP_MD_CTX *ctx)) +{ + md->cleanup = cleanup; + return 1; +} + +int +EVP_MD_meth_set_ctrl(EVP_MD *md, + int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)) +{ + md->md_ctrl = ctrl; + return 1; +} + +const EVP_MD * +EVP_MD_CTX_md(const EVP_MD_CTX *ctx) +{ + if (!ctx) + return NULL; + return ctx->digest; +} + +void * +EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) +{ + return ctx->md_data; +} + +EVP_PKEY_CTX * +EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) +{ + return ctx->pctx; +} + +void +EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) +{ + if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + } else { + EVP_PKEY_CTX_free(ctx->pctx); + } + + ctx->pctx = pctx; + + if (pctx != NULL) { + /* + * For unclear reasons it was decided that the caller keeps + * ownership of pctx. So a flag was invented to make sure we + * don't free it in EVP_MD_CTX_cleanup(). We also need to + * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag + * isn't public... + */ + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + } +} + +void +EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void +EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int +EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} + +void +EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void +EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int +EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} diff --git a/Libraries/libressl/crypto/evp/evp_local.h b/Libraries/libressl/crypto/evp/evp_local.h new file mode 100644 index 000000000..015fbb50a --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_local.h @@ -0,0 +1,330 @@ +/* $OpenBSD: evp_local.h,v 1.5 2023/09/28 11:29:10 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_EVP_LOCAL_H +#define HEADER_EVP_LOCAL_H + +__BEGIN_HIDDEN_DECLS + +/* XXX - move these to evp.h after unlock. */ +#define EVP_CTRL_GET_IVLEN 0x25 +#define EVP_CIPH_FLAG_CUSTOM_IV_LENGTH 0x400000 + +#define EVP_CTRL_AEAD_GET_IVLEN EVP_CTRL_GET_IVLEN + +/* + * Don't free md_ctx->pctx in EVP_MD_CTX_cleanup(). Needed for ownership + * handling in EVP_MD_CTX_set_pkey_ctx(). + */ +#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400 + +typedef int evp_sign_method(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, unsigned int *siglen, + void *key); +typedef int evp_verify_method(int type, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, + void *key); + +struct ecx_key_st { + int nid; + int key_len; + uint8_t *priv_key; + size_t priv_key_len; + uint8_t *pub_key; + size_t pub_key_len; +}; + +/* Type needs to be a bit field + * Sub-type needs to be for variations on the method, as in, can it do + * arbitrary encryption.... */ +struct evp_pkey_st { + int type; + int save_type; + int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + union { + void *ptr; +#ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +#endif +#ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +#endif +#ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +#endif +#ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ + struct ecx_key_st *ecx; /* ECX */ +#endif +#ifndef OPENSSL_NO_GOST + struct gost_key_st *gost; /* GOST */ +#endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} /* EVP_PKEY */; + +struct evp_md_st { + int type; + int pkey_type; + int md_size; + unsigned long flags; + int (*init)(EVP_MD_CTX *ctx); + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); + int (*final)(EVP_MD_CTX *ctx, unsigned char *md); + int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from); + int (*cleanup)(EVP_MD_CTX *ctx); + + int block_size; + int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +} /* EVP_MD */; + +struct evp_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); +} /* EVP_MD_CTX */; + +struct evp_cipher_st { + int nid; + int block_size; + int key_len; /* Default value for variable length ciphers */ + int iv_len; + unsigned long flags; /* Various flags */ + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); /* init key */ + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl);/* encrypt/decrypt data */ + int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ + int ctx_size; /* how big ctx->cipher_data needs to be */ + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */ + void *app_data; /* Application data */ +} /* EVP_CIPHER */; + +struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */ + int num; /* used by cfb/ofb/ctr mode */ + + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */ +} /* EVP_CIPHER_CTX */; + +struct evp_Encode_Ctx_st { + + int num; /* number saved in a partial encode/decode */ + int length; /* The length is either the output line length + * (in input bytes) or the shortest input line + * length that is ok. Once decoding begins, + * the length is adjusted up each time a longer + * line is decoded */ + unsigned char enc_data[80]; /* data to encode */ + int line_num; /* number read on current line */ + int expect_nl; +} /* EVP_ENCODE_CTX */; + +#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2)) + +struct evp_pkey_ctx_st { + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Actual operation */ + int operation; + /* Algorithm specific data */ + void *data; + /* Application specific data */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; +} /* EVP_PKEY_CTX */; + +#define EVP_PKEY_FLAG_DYNAMIC 1 + +struct evp_pkey_method_st { + int pkey_id; + int flags; + + int (*init)(EVP_PKEY_CTX *ctx); + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup)(EVP_PKEY_CTX *ctx); + + int (*paramgen_init)(EVP_PKEY_CTX *ctx); + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*keygen_init)(EVP_PKEY_CTX *ctx); + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*sign_init)(EVP_PKEY_CTX *ctx); + int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + + int (*verify_init)(EVP_PKEY_CTX *ctx); + int (*verify)(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + + int (*verify_recover_init)(EVP_PKEY_CTX *ctx); + int (*verify_recover)(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + + int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + + int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, + int siglen, EVP_MD_CTX *mctx); + + int (*encrypt_init)(EVP_PKEY_CTX *ctx); + int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + + int (*decrypt_init)(EVP_PKEY_CTX *ctx); + int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + + int (*derive_init)(EVP_PKEY_CTX *ctx); + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value); + + int (*digestsign)(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, size_t tbslen); + + int (*check)(EVP_PKEY *pkey); + int (*public_check)(EVP_PKEY *pkey); + int (*param_check)(EVP_PKEY *pkey); +} /* EVP_PKEY_METHOD */; + +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); + +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de); + +/* EVP_AEAD represents a specific AEAD algorithm. */ +struct evp_aead_st { + unsigned char key_len; + unsigned char nonce_len; + unsigned char overhead; + unsigned char max_tag_len; + + int (*init)(struct evp_aead_ctx_st*, const unsigned char *key, + size_t key_len, size_t tag_len); + void (*cleanup)(struct evp_aead_ctx_st*); + + int (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len); + + int (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len); +}; + +/* An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key + * and message-independent IV. */ +struct evp_aead_ctx_st { + const EVP_AEAD *aead; + /* aead_state is an opaque pointer to the AEAD specific state. */ + void *aead_state; +}; + +int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str); +int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex); +int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md_name); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_EVP_LOCAL_H */ diff --git a/Libraries/libressl/crypto/evp/evp_pbe.c b/Libraries/libressl/crypto/evp/evp_pbe.c new file mode 100644 index 000000000..4a23a98f8 --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_pbe.c @@ -0,0 +1,312 @@ +/* $OpenBSD: evp_pbe.c,v 1.29 2023/07/07 19:37:53 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "evp_local.h" + +/* Password based encryption (PBE) functions */ + +DECLARE_STACK_OF(EVP_PBE_CTL) +static STACK_OF(EVP_PBE_CTL) *pbe_algs; + +/* Setup a cipher context from a PBE algorithm */ + +typedef struct { + int pbe_type; + int pbe_nid; + int cipher_nid; + int md_nid; + EVP_PBE_KEYGEN *keygen; +} EVP_PBE_CTL; + +static const EVP_PBE_CTL builtin_pbe[] = { + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, +#endif + + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, +#endif + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + + + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, + {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, + {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_12_256, -1, NID_id_tc26_gost3411_2012_256, 0}, + {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_12_512, -1, NID_id_tc26_gost3411_2012_512, 0}, +}; + +int +EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) +{ + const EVP_CIPHER *cipher; + const EVP_MD *md; + int cipher_nid, md_nid; + EVP_PBE_KEYGEN *keygen; + + if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), + &cipher_nid, &md_nid, &keygen)) { + char obj_tmp[80]; + EVPerror(EVP_R_UNKNOWN_PBE_ALGORITHM); + if (!pbe_obj) + strlcpy(obj_tmp, "NULL", sizeof obj_tmp); + else + i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); + ERR_asprintf_error_data("TYPE=%s", obj_tmp); + return 0; + } + + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + if (cipher_nid == -1) + cipher = NULL; + else { + cipher = EVP_get_cipherbynid(cipher_nid); + if (!cipher) { + EVPerror(EVP_R_UNKNOWN_CIPHER); + return 0; + } + } + + if (md_nid == -1) + md = NULL; + else { + md = EVP_get_digestbynid(md_nid); + if (!md) { + EVPerror(EVP_R_UNKNOWN_DIGEST); + return 0; + } + } + + if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { + EVPerror(EVP_R_KEYGEN_FAILURE); + return 0; + } + return 1; +} + +static int pbe2_cmp_BSEARCH_CMP_FN(const void *, const void *); +static int pbe2_cmp(EVP_PBE_CTL const *, EVP_PBE_CTL const *); +static EVP_PBE_CTL *OBJ_bsearch_pbe2(EVP_PBE_CTL *key, EVP_PBE_CTL const *base, int num); + +static int +pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) +{ + int ret = pbe1->pbe_type - pbe2->pbe_type; + + if (ret) + return ret; + else + return pbe1->pbe_nid - pbe2->pbe_nid; +} + + +static int +pbe2_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + EVP_PBE_CTL const *a = a_; + EVP_PBE_CTL const *b = b_; + return pbe2_cmp(a, b); +} + +static EVP_PBE_CTL * +OBJ_bsearch_pbe2(EVP_PBE_CTL *key, EVP_PBE_CTL const *base, int num) +{ + return (EVP_PBE_CTL *)OBJ_bsearch_(key, base, num, sizeof(EVP_PBE_CTL), + pbe2_cmp_BSEARCH_CMP_FN); +} + +static int +pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b) +{ + int ret = (*a)->pbe_type - (*b)->pbe_type; + + if (ret) + return ret; + else + return (*a)->pbe_nid - (*b)->pbe_nid; +} + +/* Add a PBE algorithm */ + +int +EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, + EVP_PBE_KEYGEN *keygen) +{ + EVP_PBE_CTL *pbe_tmp; + + if (pbe_algs == NULL) { + pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); + if (pbe_algs == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + } + pbe_tmp = malloc(sizeof(EVP_PBE_CTL)); + if (pbe_tmp == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + pbe_tmp->pbe_type = pbe_type; + pbe_tmp->pbe_nid = pbe_nid; + pbe_tmp->cipher_nid = cipher_nid; + pbe_tmp->md_nid = md_nid; + pbe_tmp->keygen = keygen; + + if (sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp) == 0) { + free(pbe_tmp); + EVPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +int +EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen) +{ + int cipher_nid, md_nid; + + if (cipher) + cipher_nid = EVP_CIPHER_nid(cipher); + else + cipher_nid = -1; + if (md) + md_nid = EVP_MD_type(md); + else + md_nid = -1; + + return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, + cipher_nid, md_nid, keygen); +} + +int +EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) +{ + EVP_PBE_CTL *pbetmp = NULL, pbelu; + int i; + if (pbe_nid == NID_undef) + return 0; + + pbelu.pbe_type = type; + pbelu.pbe_nid = pbe_nid; + + if (pbe_algs) { + i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); + if (i != -1) + pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i); + } + if (pbetmp == NULL) { + pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, + sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL)); + } + if (pbetmp == NULL) + return 0; + if (pcnid) + *pcnid = pbetmp->cipher_nid; + if (pmnid) + *pmnid = pbetmp->md_nid; + if (pkeygen) + *pkeygen = pbetmp->keygen; + return 1; +} + +static void +free_evp_pbe_ctl(EVP_PBE_CTL *pbe) +{ + free(pbe); +} + +void +EVP_PBE_cleanup(void) +{ + sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); + pbe_algs = NULL; +} diff --git a/Libraries/libressl/crypto/evp/evp_pkey.c b/Libraries/libressl/crypto/evp/evp_pkey.c new file mode 100644 index 000000000..9e29a1ae6 --- /dev/null +++ b/Libraries/libressl/crypto/evp/evp_pkey.c @@ -0,0 +1,209 @@ +/* $OpenBSD: evp_pkey.c,v 1.27 2023/07/07 19:37:53 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +#include "asn1_local.h" +#include "evp_local.h" + +/* Extract a private key from a PKCS8 structure */ + +EVP_PKEY * +EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) +{ + EVP_PKEY *pkey = NULL; + const ASN1_OBJECT *algoid; + char obj_tmp[80]; + + if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) + return NULL; + + if (!(pkey = EVP_PKEY_new())) { + EVPerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { + EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + i2t_ASN1_OBJECT(obj_tmp, 80, algoid); + ERR_asprintf_error_data("TYPE=%s", obj_tmp); + goto error; + } + + if (pkey->ameth->priv_decode) { + if (!pkey->ameth->priv_decode(pkey, p8)) { + EVPerror(EVP_R_PRIVATE_KEY_DECODE_ERROR); + goto error; + } + } else { + EVPerror(EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } + + return pkey; + +error: + EVP_PKEY_free(pkey); + return NULL; +} + +/* Turn a private key into a PKCS8 structure */ + +PKCS8_PRIV_KEY_INFO * +EVP_PKEY2PKCS8(EVP_PKEY *pkey) +{ + PKCS8_PRIV_KEY_INFO *p8; + + if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { + EVPerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (pkey->ameth) { + if (pkey->ameth->priv_encode) { + if (!pkey->ameth->priv_encode(p8, pkey)) { + EVPerror(EVP_R_PRIVATE_KEY_ENCODE_ERROR); + goto error; + } + } else { + EVPerror(EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } + } else { + EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + goto error; + } + return p8; + +error: + PKCS8_PRIV_KEY_INFO_free(p8); + return NULL; +} + +/* EVP_PKEY attribute functions */ + +int +EVP_PKEY_get_attr_count(const EVP_PKEY *key) +{ + return X509at_get_attr_count(key->attributes); +} + +int +EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(key->attributes, nid, lastpos); +} + +int +EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos); +} + +X509_ATTRIBUTE * +EVP_PKEY_get_attr(const EVP_PKEY *key, int loc) +{ + return X509at_get_attr(key->attributes, loc); +} + +X509_ATTRIBUTE * +EVP_PKEY_delete_attr(EVP_PKEY *key, int loc) +{ + return X509at_delete_attr(key->attributes, loc); +} + +int +EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&key->attributes, attr)) + return 1; + return 0; +} + +int +EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len)) + return 1; + return 0; +} + +int +EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len)) + return 1; + return 0; +} + +int +EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, + bytes, len)) + return 1; + return 0; +} diff --git a/Libraries/libressl/crypto/evp/m_gost2814789.c b/Libraries/libressl/crypto/evp/m_gost2814789.c new file mode 100644 index 000000000..9b8a09e5a --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_gost2814789.c @@ -0,0 +1,113 @@ +/* $OpenBSD: m_gost2814789.c,v 1.6 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#ifndef OPENSSL_NO_GOST + +#include +#include +#include + +#include "evp_local.h" + +static int +gost2814789_init(EVP_MD_CTX *ctx) +{ + return GOST2814789IMIT_Init(ctx->md_data, + NID_id_Gost28147_89_CryptoPro_A_ParamSet); +} + +static int +gost2814789_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return GOST2814789IMIT_Update(ctx->md_data, data, count); +} + +static int +gost2814789_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return GOST2814789IMIT_Final(md, ctx->md_data); +} + +static int +gost2814789_md_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) +{ + GOST2814789IMIT_CTX *gctx = ctx->md_data; + + switch (cmd) { + case EVP_MD_CTRL_SET_KEY: + return Gost2814789_set_key(&gctx->cipher, p2, p1); + case EVP_MD_CTRL_GOST_SET_SBOX: + return Gost2814789_set_sbox(&gctx->cipher, p1); + } + return -2; +} + +static const EVP_MD gost2814789imit_md = { + .type = NID_id_Gost28147_89_MAC, + .pkey_type = NID_undef, + .md_size = GOST2814789IMIT_LENGTH, + .flags = 0, + .init = gost2814789_init, + .update = gost2814789_update, + .final = gost2814789_final, + .block_size = GOST2814789IMIT_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(GOST2814789IMIT_CTX), + .md_ctrl = gost2814789_md_ctrl, +}; + +const EVP_MD * +EVP_gost2814789imit(void) +{ + return (&gost2814789imit_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/m_gostr341194.c b/Libraries/libressl/crypto/evp/m_gostr341194.c new file mode 100644 index 000000000..723349a0d --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_gostr341194.c @@ -0,0 +1,100 @@ +/* $OpenBSD: m_gostr341194.c,v 1.7 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST + +#include +#include +#include + +#include "evp_local.h" + +static int +gostr341194_init(EVP_MD_CTX *ctx) +{ + return GOSTR341194_Init(ctx->md_data, + NID_id_GostR3411_94_CryptoProParamSet); +} + +static int +gostr341194_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return GOSTR341194_Update(ctx->md_data, data, count); +} + +static int +gostr341194_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return GOSTR341194_Final(md, ctx->md_data); +} + +static const EVP_MD gostr341194_md = { + .type = NID_id_GostR3411_94, + .pkey_type = NID_undef, + .md_size = GOSTR341194_LENGTH, + .flags = 0, + .init = gostr341194_init, + .update = gostr341194_update, + .final = gostr341194_final, + .block_size = GOSTR341194_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(GOSTR341194_CTX), +}; + +const EVP_MD * +EVP_gostr341194(void) +{ + return (&gostr341194_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/m_md4.c b/Libraries/libressl/crypto/evp/m_md4.c new file mode 100644 index 000000000..199dba848 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_md4.c @@ -0,0 +1,113 @@ +/* $OpenBSD: m_md4.c,v 1.21 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#ifndef OPENSSL_NO_MD4 + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +static int +init(EVP_MD_CTX *ctx) +{ + return MD4_Init(ctx->md_data); +} + +static int +update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD4_Update(ctx->md_data, data, count); +} + +static int +final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD4_Final(md, ctx->md_data); +} + +static const EVP_MD md4_md = { + .type = NID_md4, + .pkey_type = NID_md4WithRSAEncryption, + .md_size = MD4_DIGEST_LENGTH, + .flags = 0, + .init = init, + .update = update, + .final = final, + .copy = NULL, + .cleanup = NULL, + .block_size = MD4_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(MD4_CTX), +}; + +const EVP_MD * +EVP_md4(void) +{ + return (&md4_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/m_md5.c b/Libraries/libressl/crypto/evp/m_md5.c new file mode 100644 index 000000000..0dfad89aa --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_md5.c @@ -0,0 +1,113 @@ +/* $OpenBSD: m_md5.c,v 1.20 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#ifndef OPENSSL_NO_MD5 + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +static int +init(EVP_MD_CTX *ctx) +{ + return MD5_Init(ctx->md_data); +} + +static int +update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD5_Update(ctx->md_data, data, count); +} + +static int +final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD5_Final(md, ctx->md_data); +} + +static const EVP_MD md5_md = { + .type = NID_md5, + .pkey_type = NID_md5WithRSAEncryption, + .md_size = MD5_DIGEST_LENGTH, + .flags = 0, + .init = init, + .update = update, + .final = final, + .copy = NULL, + .cleanup = NULL, + .block_size = MD5_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(MD5_CTX), +}; + +const EVP_MD * +EVP_md5(void) +{ + return (&md5_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/m_md5_sha1.c b/Libraries/libressl/crypto/evp/m_md5_sha1.c new file mode 100644 index 000000000..7dd1ae127 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_md5_sha1.c @@ -0,0 +1,89 @@ +/* $OpenBSD: m_md5_sha1.c,v 1.8 2023/09/02 04:55:18 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +struct md5_sha1_ctx { + MD5_CTX md5; + SHA_CTX sha1; +}; + +static int +md5_sha1_init(EVP_MD_CTX *ctx) +{ + struct md5_sha1_ctx *mdctx = ctx->md_data; + + if (!MD5_Init(&mdctx->md5)) + return 0; + if (!SHA1_Init(&mdctx->sha1)) + return 0; + + return 1; +} + +static int +md5_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + struct md5_sha1_ctx *mdctx = ctx->md_data; + + if (!MD5_Update(&mdctx->md5, data, count)) + return 0; + if (!SHA1_Update(&mdctx->sha1, data, count)) + return 0; + + return 1; +} + +static int +md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *out) +{ + struct md5_sha1_ctx *mdctx = ctx->md_data; + + if (!MD5_Final(out, &mdctx->md5)) + return 0; + if (!SHA1_Final(out + MD5_DIGEST_LENGTH, &mdctx->sha1)) + return 0; + + return 1; +} + +static const EVP_MD md5_sha1_md = { + .type = NID_md5_sha1, + .pkey_type = NID_md5_sha1, + .md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, + .flags = 0, + .init = md5_sha1_init, + .update = md5_sha1_update, + .final = md5_sha1_final, + .block_size = MD5_CBLOCK, /* MD5_CBLOCK == SHA_CBLOCK */ + .ctx_size = sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), +}; + +const EVP_MD * +EVP_md5_sha1(void) +{ + return &md5_sha1_md; +} diff --git a/Libraries/libressl/crypto/evp/m_null.c b/Libraries/libressl/crypto/evp/m_null.c new file mode 100644 index 000000000..28634d2da --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_null.c @@ -0,0 +1,103 @@ +/* $OpenBSD: m_null.c,v 1.14 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "evp_local.h" + +static int +init(EVP_MD_CTX *ctx) +{ + return 1; +} + +static int +update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return 1; +} + +static int +final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return 1; +} + +static const EVP_MD null_md = { + .type = NID_undef, + .pkey_type = NID_undef, + .md_size = 0, + .flags = 0, + .init = init, + .update = update, + .final = final, + .copy = NULL, + .cleanup = NULL, + .block_size = 0, + .ctx_size = sizeof(EVP_MD *), +}; + +const EVP_MD * +EVP_md_null(void) +{ + return (&null_md); +} diff --git a/Libraries/libressl/crypto/evp/m_ripemd.c b/Libraries/libressl/crypto/evp/m_ripemd.c new file mode 100644 index 000000000..638d0cd27 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_ripemd.c @@ -0,0 +1,113 @@ +/* $OpenBSD: m_ripemd.c,v 1.17 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#ifndef OPENSSL_NO_RIPEMD + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +static int +init(EVP_MD_CTX *ctx) +{ + return RIPEMD160_Init(ctx->md_data); +} + +static int +update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return RIPEMD160_Update(ctx->md_data, data, count); +} + +static int +final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return RIPEMD160_Final(md, ctx->md_data); +} + +static const EVP_MD ripemd160_md = { + .type = NID_ripemd160, + .pkey_type = NID_ripemd160WithRSA, + .md_size = RIPEMD160_DIGEST_LENGTH, + .flags = 0, + .init = init, + .update = update, + .final = final, + .copy = NULL, + .cleanup = NULL, + .block_size = RIPEMD160_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX), +}; + +const EVP_MD * +EVP_ripemd160(void) +{ + return (&ripemd160_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/m_sha1.c b/Libraries/libressl/crypto/evp/m_sha1.c new file mode 100644 index 000000000..c65e0515c --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_sha1.c @@ -0,0 +1,351 @@ +/* $OpenBSD: m_sha1.c,v 1.25 2023/07/07 19:37:53 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#ifndef OPENSSL_NO_SHA + +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" +#include "sha_internal.h" + +static int +sha1_init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int +sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int +sha1_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD sha1_md = { + .type = NID_sha1, + .pkey_type = NID_sha1WithRSAEncryption, + .md_size = SHA_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha1_init, + .update = sha1_update, + .final = sha1_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD * +EVP_sha1(void) +{ + return &sha1_md; +} +#endif + +#ifndef OPENSSL_NO_SHA256 +static int +sha224_init(EVP_MD_CTX *ctx) +{ + return SHA224_Init(ctx->md_data); +} + +static int +sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + /* + * Even though there're separate SHA224_[Update|Final], we call + * SHA256 functions even in SHA224 context. This is what happens + * there anyway, so we can spare few CPU cycles:-) + */ + return SHA256_Update(ctx->md_data, data, count); +} + +static int +sha224_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA224_Final(md, ctx->md_data); +} + +static const EVP_MD sha224_md = { + .type = NID_sha224, + .pkey_type = NID_sha224WithRSAEncryption, + .md_size = SHA224_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha224_init, + .update = sha224_update, + .final = sha224_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA256_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA256_CTX), +}; + +const EVP_MD * +EVP_sha224(void) +{ + return &sha224_md; +} + +static int +sha256_init(EVP_MD_CTX *ctx) +{ + return SHA256_Init(ctx->md_data); +} + +static int +sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA256_Update(ctx->md_data, data, count); +} + +static int +sha256_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA256_Final(md, ctx->md_data); +} + +static const EVP_MD sha256_md = { + .type = NID_sha256, + .pkey_type = NID_sha256WithRSAEncryption, + .md_size = SHA256_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha256_init, + .update = sha256_update, + .final = sha256_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA256_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA256_CTX), +}; + +const EVP_MD * +EVP_sha256(void) +{ + return &sha256_md; +} +#endif /* ifndef OPENSSL_NO_SHA256 */ + +#ifndef OPENSSL_NO_SHA512 +static int +sha384_init(EVP_MD_CTX *ctx) +{ + return SHA384_Init(ctx->md_data); +} + +static int +sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + /* See comment in SHA224/256 section */ + return SHA512_Update(ctx->md_data, data, count); +} + +static int +sha384_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA384_Final(md, ctx->md_data); +} + +static const EVP_MD sha384_md = { + .type = NID_sha384, + .pkey_type = NID_sha384WithRSAEncryption, + .md_size = SHA384_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha384_init, + .update = sha384_update, + .final = sha384_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA512_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD * +EVP_sha384(void) +{ + return &sha384_md; +} + +static int +sha512_init(EVP_MD_CTX *ctx) +{ + return SHA512_Init(ctx->md_data); +} + +static int +sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA512_Update(ctx->md_data, data, count); +} + +static int +sha512_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA512_Final(md, ctx->md_data); +} + +static const EVP_MD sha512_md = { + .type = NID_sha512, + .pkey_type = NID_sha512WithRSAEncryption, + .md_size = SHA512_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha512_init, + .update = sha512_update, + .final = sha512_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA512_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD * +EVP_sha512(void) +{ + return &sha512_md; +} + +static int +sha512_224_init(EVP_MD_CTX *ctx) +{ + return SHA512_224_Init(ctx->md_data); +} + +static int +sha512_224_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA512_224_Update(ctx->md_data, data, count); +} + +static int +sha512_224_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA512_224_Final(md, ctx->md_data); +} + +static const EVP_MD sha512_224_md = { + .type = NID_sha512_224, + .pkey_type = NID_sha512_224WithRSAEncryption, + .md_size = SHA512_224_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha512_224_init, + .update = sha512_224_update, + .final = sha512_224_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA512_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD * +EVP_sha512_224(void) +{ + return &sha512_224_md; +} + +static int +sha512_256_init(EVP_MD_CTX *ctx) +{ + return SHA512_256_Init(ctx->md_data); +} + +static int +sha512_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA512_256_Update(ctx->md_data, data, count); +} + +static int +sha512_256_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA512_256_Final(md, ctx->md_data); +} + +static const EVP_MD sha512_256_md = { + .type = NID_sha512_256, + .pkey_type = NID_sha512_256WithRSAEncryption, + .md_size = SHA512_256_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha512_256_init, + .update = sha512_256_update, + .final = sha512_256_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA512_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD * +EVP_sha512_256(void) +{ + return &sha512_256_md; +} +#endif /* ifndef OPENSSL_NO_SHA512 */ diff --git a/Libraries/libressl/crypto/evp/m_sha3.c b/Libraries/libressl/crypto/evp/m_sha3.c new file mode 100644 index 000000000..67f94f795 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_sha3.c @@ -0,0 +1,173 @@ +/* $OpenBSD: m_sha3.c,v 1.3 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "evp_local.h" +#include "sha3_internal.h" + +static int +sha3_224_init(EVP_MD_CTX *ctx) +{ + return sha3_init(ctx->md_data, SHA3_224_DIGEST_LENGTH); +} + +static int +sha3_224_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return sha3_update(ctx->md_data, data, count); +} + +static int +sha3_224_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return sha3_final(md, ctx->md_data); +} + +static const EVP_MD sha3_224_md = { + .type = NID_sha3_224, + .pkey_type = NID_RSA_SHA3_224, + .md_size = SHA3_224_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha3_224_init, + .update = sha3_224_update, + .final = sha3_224_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA3_224_BLOCK_SIZE, + .ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx), +}; + +const EVP_MD * +EVP_sha3_224(void) +{ + return &sha3_224_md; +} + +static int +sha3_256_init(EVP_MD_CTX *ctx) +{ + return sha3_init(ctx->md_data, SHA3_256_DIGEST_LENGTH); +} + +static int +sha3_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return sha3_update(ctx->md_data, data, count); +} + +static int +sha3_256_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return sha3_final(md, ctx->md_data); +} + +static const EVP_MD sha3_256_md = { + .type = NID_sha3_256, + .pkey_type = NID_RSA_SHA3_256, + .md_size = SHA3_256_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha3_256_init, + .update = sha3_256_update, + .final = sha3_256_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA3_256_BLOCK_SIZE, + .ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx), +}; + +const EVP_MD * +EVP_sha3_256(void) +{ + return &sha3_256_md; +} + +static int +sha3_384_init(EVP_MD_CTX *ctx) +{ + return sha3_init(ctx->md_data, SHA3_384_DIGEST_LENGTH); +} + +static int +sha3_384_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return sha3_update(ctx->md_data, data, count); +} + +static int +sha3_384_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return sha3_final(md, ctx->md_data); +} + +static const EVP_MD sha3_384_md = { + .type = NID_sha3_384, + .pkey_type = NID_RSA_SHA3_384, + .md_size = SHA3_384_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha3_384_init, + .update = sha3_384_update, + .final = sha3_384_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA3_384_BLOCK_SIZE, + .ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx), +}; + +const EVP_MD * +EVP_sha3_384(void) +{ + return &sha3_384_md; +} + +static int +sha3_512_init(EVP_MD_CTX *ctx) +{ + return sha3_init(ctx->md_data, SHA3_512_DIGEST_LENGTH); +} + +static int +sha3_512_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return sha3_update(ctx->md_data, data, count); +} + +static int +sha3_512_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return sha3_final(md, ctx->md_data); +} + +static const EVP_MD sha3_512_md = { + .type = NID_sha3_512, + .pkey_type = NID_RSA_SHA3_512, + .md_size = SHA3_512_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sha3_512_init, + .update = sha3_512_update, + .final = sha3_512_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SHA3_512_BLOCK_SIZE, + .ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx), +}; + +const EVP_MD * +EVP_sha3_512(void) +{ + return &sha3_512_md; +} diff --git a/Libraries/libressl/crypto/evp/m_sigver.c b/Libraries/libressl/crypto/evp/m_sigver.c new file mode 100644 index 000000000..47c01f784 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_sigver.c @@ -0,0 +1,257 @@ +/* $OpenBSD: m_sigver.c,v 1.13 2023/07/07 19:37:53 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "evp_local.h" + +static int +update_oneshot_only(EVP_MD_CTX *ctx, const void *data, size_t datalen) +{ + EVPerror(EVP_R_ONLY_ONESHOT_SUPPORTED); + return 0; +} + +static int +do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, + ENGINE *e, EVP_PKEY *pkey, int ver) +{ + if (ctx->pctx == NULL) + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return 0; + + if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { + if (type == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } + + if (type == NULL) { + EVPerror(EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + } + + if (ver) { + if (ctx->pctx->pmeth->verifyctx_init) { + if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, + ctx) <=0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; + } else if (ctx->pctx->pmeth->digestverify != NULL) { + ctx->pctx->operation = EVP_PKEY_OP_VERIFY; + ctx->update = update_oneshot_only; + } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) + return 0; + } else { + if (ctx->pctx->pmeth->signctx_init) { + if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; + } else if (ctx->pctx->pmeth->digestsign != NULL) { + ctx->pctx->operation = EVP_PKEY_OP_SIGN; + ctx->update = update_oneshot_only; + } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) + return 0; + } + if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) + return 0; + if (pctx) + *pctx = ctx->pctx; + if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) + return 1; + if (!EVP_DigestInit_ex(ctx, type, e)) + return 0; + return 1; +} + +int +EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, + ENGINE *e, EVP_PKEY *pkey) +{ + return do_sigver_init(ctx, pctx, type, e, pkey, 0); +} + +int +EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, + ENGINE *e, EVP_PKEY *pkey) +{ + return do_sigver_init(ctx, pctx, type, e, pkey, 1); +} + +int +EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) +{ + EVP_PKEY_CTX *pctx = ctx->pctx; + int sctx; + int r = 0; + + if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { + EVP_PKEY_CTX *dctx; + + if (sigret == NULL) + return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); + + /* XXX - support EVP_MD_CTX_FLAG_FINALISE? */ + if ((dctx = EVP_PKEY_CTX_dup(ctx->pctx)) == NULL) + return 0; + r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); + EVP_PKEY_CTX_free(dctx); + + return r; + } + + if (ctx->pctx->pmeth->signctx) + sctx = 1; + else + sctx = 0; + if (sigret) { + EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + return 0; + if (sctx) + r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, + sigret, siglen, &tmp_ctx); + else + r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (sctx || !r) + return r; + if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) + return 0; + } else { + if (sctx) { + if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, + siglen, ctx) <= 0) + return 0; + } else { + int s = EVP_MD_size(ctx->digest); + if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, + NULL, s) <= 0) + return 0; + } + } + return 1; +} + +int +EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (ctx->pctx->pmeth->digestsign != NULL) + return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, + tbs, tbslen); + + if (sigret != NULL) { + if (EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) + return 0; + } + + return EVP_DigestSignFinal(ctx, sigret, siglen); +} + +int +EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen) +{ + EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + int r; + unsigned int mdlen = 0; + int vctx; + + if (ctx->pctx->pmeth->verifyctx) + vctx = 1; + else + vctx = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + return -1; + if (vctx) { + r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig, + siglen, &tmp_ctx); + } else + r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (vctx || !r) + return r; + return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); +} + +int +EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (ctx->pctx->pmeth->digestverify != NULL) + return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, + tbs, tbslen); + + if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) + return -1; + + return EVP_DigestVerifyFinal(ctx, sigret, siglen); +} diff --git a/Libraries/libressl/crypto/evp/m_sm3.c b/Libraries/libressl/crypto/evp/m_sm3.c new file mode 100644 index 000000000..ea30d8d22 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_sm3.c @@ -0,0 +1,68 @@ +/* $OpenBSD: m_sm3.c,v 1.6 2023/07/07 19:37:53 beck Exp $ */ +/* + * Copyright (c) 2018, Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef OPENSSL_NO_SM3 +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +static int +sm3_init(EVP_MD_CTX *ctx) +{ + return SM3_Init(ctx->md_data); +} + +static int +sm3_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SM3_Update(ctx->md_data, data, count); +} + +static int +sm3_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SM3_Final(md, ctx->md_data); +} + +static const EVP_MD sm3_md = { + .type = NID_sm3, + .pkey_type = NID_sm3WithRSAEncryption, + .md_size = SM3_DIGEST_LENGTH, + .flags = EVP_MD_FLAG_DIGALGID_ABSENT, + .init = sm3_init, + .update = sm3_update, + .final = sm3_final, + .copy = NULL, + .cleanup = NULL, + .block_size = SM3_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(SM3_CTX), +}; + +const EVP_MD * +EVP_sm3(void) +{ + return &sm3_md; +} + +#endif /* OPENSSL_NO_SM3 */ diff --git a/Libraries/libressl/crypto/evp/m_streebog.c b/Libraries/libressl/crypto/evp/m_streebog.c new file mode 100644 index 000000000..48fa65864 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_streebog.c @@ -0,0 +1,133 @@ +/* $OpenBSD: m_streebog.c,v 1.7 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#ifndef OPENSSL_NO_GOST + +#include +#include +#include + +#include "evp_local.h" + +static int +streebog_init256(EVP_MD_CTX *ctx) +{ + return STREEBOG256_Init(ctx->md_data); +} + +static int +streebog_update256(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return STREEBOG256_Update(ctx->md_data, data, count); +} + +static int +streebog_final256(EVP_MD_CTX *ctx, unsigned char *md) +{ + return STREEBOG256_Final(md, ctx->md_data); +} + +static int +streebog_init512(EVP_MD_CTX *ctx) +{ + return STREEBOG512_Init(ctx->md_data); +} + +static int +streebog_update512(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return STREEBOG512_Update(ctx->md_data, data, count); +} + +static int +streebog_final512(EVP_MD_CTX *ctx, unsigned char *md) +{ + return STREEBOG512_Final(md, ctx->md_data); +} + +static const EVP_MD streebog256_md = { + .type = NID_id_tc26_gost3411_2012_256, + .pkey_type = NID_undef, + .md_size = STREEBOG256_LENGTH, + .flags = 0, + .init = streebog_init256, + .update = streebog_update256, + .final = streebog_final256, + .block_size = STREEBOG_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(STREEBOG_CTX), +}; + +static const EVP_MD streebog512_md = { + .type = NID_id_tc26_gost3411_2012_512, + .pkey_type = NID_undef, + .md_size = STREEBOG512_LENGTH, + .flags = 0, + .init = streebog_init512, + .update = streebog_update512, + .final = streebog_final512, + .block_size = STREEBOG_CBLOCK, + .ctx_size = sizeof(EVP_MD *) + sizeof(STREEBOG_CTX), +}; + +const EVP_MD * +EVP_streebog256(void) +{ + return (&streebog256_md); +} + +const EVP_MD * +EVP_streebog512(void) +{ + return (&streebog512_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/m_wp.c b/Libraries/libressl/crypto/evp/m_wp.c new file mode 100644 index 000000000..44d13b148 --- /dev/null +++ b/Libraries/libressl/crypto/evp/m_wp.c @@ -0,0 +1,53 @@ +/* $OpenBSD: m_wp.c,v 1.13 2023/07/07 19:37:54 beck Exp $ */ + +#include + +#include + +#ifndef OPENSSL_NO_WHIRLPOOL + +#include +#include +#include +#include + +#include "evp_local.h" + +static int +init(EVP_MD_CTX *ctx) +{ + return WHIRLPOOL_Init(ctx->md_data); +} + +static int +update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return WHIRLPOOL_Update(ctx->md_data, data, count); +} + +static int +final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return WHIRLPOOL_Final(md, ctx->md_data); +} + +static const EVP_MD whirlpool_md = { + .type = NID_whirlpool, + .pkey_type = 0, + .md_size = WHIRLPOOL_DIGEST_LENGTH, + .flags = 0, + .init = init, + .update = update, + .final = final, + .copy = NULL, + .cleanup = NULL, + .block_size = WHIRLPOOL_BBLOCK / 8, + .ctx_size = sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX), +}; + +const EVP_MD * +EVP_whirlpool(void) +{ + return (&whirlpool_md); +} +#endif diff --git a/Libraries/libressl/crypto/evp/names.c b/Libraries/libressl/crypto/evp/names.c new file mode 100644 index 000000000..5242892e9 --- /dev/null +++ b/Libraries/libressl/crypto/evp/names.c @@ -0,0 +1,240 @@ +/* $OpenBSD: names.c,v 1.21 2023/08/26 02:59:13 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "evp_local.h" + +extern int obj_cleanup_defer; +void check_defer(int nid); + +int +EVP_add_cipher(const EVP_CIPHER *c) +{ + int r; + + if (c == NULL) + return 0; + + r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH, + (const char *)c); + if (r == 0) + return (0); + check_defer(c->nid); + r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH, + (const char *)c); + return (r); +} + +int +EVP_add_digest(const EVP_MD *md) +{ + int r; + const char *name; + + name = OBJ_nid2sn(md->type); + r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md); + if (r == 0) + return (0); + check_defer(md->type); + r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH, + (const char *)md); + if (r == 0) + return (0); + + if (md->pkey_type && md->type != md->pkey_type) { + r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), + OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS, name); + if (r == 0) + return (0); + check_defer(md->pkey_type); + r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), + OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS, name); + } + return (r); +} + +const EVP_CIPHER * +EVP_get_cipherbyname(const char *name) +{ + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + + return (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); +} + +const EVP_MD * +EVP_get_digestbyname(const char *name) +{ + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + + return (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); +} + +void +EVP_cleanup(void) +{ + OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); + OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); + /* The above calls will only clean out the contents of the name + hash table, but not the hash table itself. The following line + does that part. -- Richard Levitte */ + OBJ_NAME_cleanup(-1); + + EVP_PBE_cleanup(); + if (obj_cleanup_defer == 2) { + obj_cleanup_defer = 0; + OBJ_cleanup(); + } +} + +struct doall_cipher { + void *arg; + void (*fn)(const EVP_CIPHER *ciph, const char *from, const char *to, + void *arg); +}; + +static void +do_all_cipher_fn(const OBJ_NAME *nm, void *arg) +{ + struct doall_cipher *dc = arg; + + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg); +} + +void +EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg) +{ + struct doall_cipher dc; + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); +} + +void +EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg) +{ + struct doall_cipher dc; + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, + do_all_cipher_fn, &dc); +} + +struct doall_md { + void *arg; + void (*fn)(const EVP_MD *ciph, const char *from, const char *to, + void *arg); +}; + +static void +do_all_md_fn(const OBJ_NAME *nm, void *arg) +{ + struct doall_md *dc = arg; + + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg); +} + +void +EVP_MD_do_all(void (*fn)(const EVP_MD *md, const char *from, const char *to, + void *x), void *arg) +{ + struct doall_md dc; + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); +} + +void +EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md, + const char *from, const char *to, void *x), void *arg) +{ + struct doall_md dc; + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); +} diff --git a/Libraries/libressl/crypto/evp/p5_crpt.c b/Libraries/libressl/crypto/evp/p5_crpt.c new file mode 100644 index 000000000..d26439ad2 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p5_crpt.c @@ -0,0 +1,163 @@ +/* $OpenBSD: p5_crpt.c,v 1.23 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include + +#include "evp_local.h" + +/* Doesn't do anything now: Builtin PBE algorithms in static table. + */ + +void +PKCS5_PBE_add(void) +{ +} + +int +PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de) +{ + EVP_MD_CTX ctx; + unsigned char md_tmp[EVP_MAX_MD_SIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + int i; + PBEPARAM *pbe; + int saltlen, iter; + unsigned char *salt; + const unsigned char *pbuf; + int mdsize; + int rv = 0; + + /* Extract useful info from parameter */ + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + EVPerror(EVP_R_DECODE_ERROR); + return 0; + } + + mdsize = EVP_MD_size(md); + if (mdsize < 0) + return 0; + + pbuf = param->value.sequence->data; + if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { + EVPerror(EVP_R_DECODE_ERROR); + return 0; + } + + if (!pbe->iter) + iter = 1; + else if ((iter = ASN1_INTEGER_get(pbe->iter)) <= 0) { + EVPerror(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS); + PBEPARAM_free(pbe); + return 0; + } + salt = pbe->salt->data; + saltlen = pbe->salt->length; + + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + EVP_MD_CTX_init(&ctx); + + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, pass, passlen)) + goto err; + if (!EVP_DigestUpdate(&ctx, salt, saltlen)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) + goto err; + for (i = 1; i < iter; i++) { + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize)) + goto err; + if (!EVP_DigestFinal_ex (&ctx, md_tmp, NULL)) + goto err; + } + if ((size_t)EVP_CIPHER_key_length(cipher) > sizeof(md_tmp)) { + EVPerror(EVP_R_BAD_KEY_LENGTH); + goto err; + } + memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); + if ((size_t)EVP_CIPHER_iv_length(cipher) > 16) { + EVPerror(EVP_R_IV_TOO_LARGE); + goto err; + } + memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), + EVP_CIPHER_iv_length(cipher)); + if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) + goto err; + explicit_bzero(md_tmp, EVP_MAX_MD_SIZE); + explicit_bzero(key, EVP_MAX_KEY_LENGTH); + explicit_bzero(iv, EVP_MAX_IV_LENGTH); + rv = 1; +err: + EVP_MD_CTX_cleanup(&ctx); + PBEPARAM_free(pbe); + return rv; +} diff --git a/Libraries/libressl/crypto/evp/p5_crpt2.c b/Libraries/libressl/crypto/evp/p5_crpt2.c new file mode 100644 index 000000000..3c66af931 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p5_crpt2.c @@ -0,0 +1,307 @@ +/* $OpenBSD: p5_crpt2.c,v 1.27 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include + +#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA) + +#include +#include +#include +#include + +#include "evp_local.h" +#include "hmac_local.h" + +/* This is an implementation of PKCS#5 v2.0 password based encryption key + * derivation function PBKDF2. + * SHA1 version verified against test vectors posted by Peter Gutmann + * to the PKCS-TNG mailing list. + */ + +int +PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, + int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out) +{ + unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; + int cplen, j, k, tkeylen, mdlen; + unsigned long i = 1; + HMAC_CTX hctx_tpl, hctx; + + mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; + + HMAC_CTX_init(&hctx_tpl); + p = out; + tkeylen = keylen; + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + while (tkeylen) { + if (tkeylen > mdlen) + cplen = mdlen; + else + cplen = tkeylen; + /* We are unlikely to ever use more than 256 blocks (5120 bits!) + * but just in case... + */ + itmp[0] = (unsigned char)((i >> 24) & 0xff); + itmp[1] = (unsigned char)((i >> 16) & 0xff); + itmp[2] = (unsigned char)((i >> 8) & 0xff); + itmp[3] = (unsigned char)(i & 0xff); + if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + if (!HMAC_Update(&hctx, salt, saltlen) || + !HMAC_Update(&hctx, itmp, 4) || + !HMAC_Final(&hctx, digtmp, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + HMAC_CTX_cleanup(&hctx); + return 0; + } + HMAC_CTX_cleanup(&hctx); + memcpy(p, digtmp, cplen); + for (j = 1; j < iter; j++) { + if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + if (!HMAC_Update(&hctx, digtmp, mdlen) || + !HMAC_Final(&hctx, digtmp, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + HMAC_CTX_cleanup(&hctx); + return 0; + } + HMAC_CTX_cleanup(&hctx); + for (k = 0; k < cplen; k++) + p[k] ^= digtmp[k]; + } + tkeylen -= cplen; + i++; + p += cplen; + } + HMAC_CTX_cleanup(&hctx_tpl); + return 1; +} + +int +PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, + int saltlen, int iter, int keylen, unsigned char *out) +{ + return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, + EVP_sha1(), keylen, out); +} + +/* Now the key derivation function itself. This is a bit evil because + * it has to check the ASN1 parameters are valid: and there are quite a + * few of them... + */ + +int +PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de) +{ + const unsigned char *pbuf; + int plen; + PBE2PARAM *pbe2 = NULL; + const EVP_CIPHER *cipher; + + int rv = 0; + + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + EVPerror(EVP_R_DECODE_ERROR); + goto err; + } + + pbuf = param->value.sequence->data; + plen = param->value.sequence->length; + if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { + EVPerror(EVP_R_DECODE_ERROR); + goto err; + } + + /* See if we recognise the key derivation function */ + + if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { + EVPerror(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + goto err; + } + + /* lets see if we recognise the encryption algorithm. + */ + + cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); + + if (!cipher) { + EVPerror(EVP_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* Fixup cipher based on AlgorithmIdentifier */ + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) + goto err; + if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { + EVPerror(EVP_R_CIPHER_PARAMETER_ERROR); + goto err; + } + rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen, + pbe2->keyfunc->parameter, c, md, en_de); + +err: + PBE2PARAM_free(pbe2); + return rv; +} + +int +PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de) +{ + unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; + const unsigned char *pbuf; + int saltlen, iter, plen; + int rv = 0; + unsigned int keylen = 0; + int prf_nid, hmac_md_nid; + PBKDF2PARAM *kdf = NULL; + const EVP_MD *prfmd; + + if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { + EVPerror(EVP_R_NO_CIPHER_SET); + return 0; + } + keylen = EVP_CIPHER_CTX_key_length(ctx); + if (keylen > sizeof key) { + EVPerror(EVP_R_BAD_KEY_LENGTH); + return 0; + } + + /* Decode parameter */ + + if (!param || (param->type != V_ASN1_SEQUENCE)) { + EVPerror(EVP_R_DECODE_ERROR); + return 0; + } + + pbuf = param->value.sequence->data; + plen = param->value.sequence->length; + + if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) { + EVPerror(EVP_R_DECODE_ERROR); + return 0; + } + + /* Now check the parameters of the kdf */ + + if (kdf->keylength && + (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){ + EVPerror(EVP_R_UNSUPPORTED_KEYLENGTH); + goto err; + } + + if (kdf->prf) + prf_nid = OBJ_obj2nid(kdf->prf->algorithm); + else + prf_nid = NID_hmacWithSHA1; + + if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) { + EVPerror(EVP_R_UNSUPPORTED_PRF); + goto err; + } + + prfmd = EVP_get_digestbynid(hmac_md_nid); + if (prfmd == NULL) { + EVPerror(EVP_R_UNSUPPORTED_PRF); + goto err; + } + + if (kdf->salt->type != V_ASN1_OCTET_STRING) { + EVPerror(EVP_R_UNSUPPORTED_SALT_TYPE); + goto err; + } + + /* it seems that its all OK */ + salt = kdf->salt->value.octet_string->data; + saltlen = kdf->salt->value.octet_string->length; + if ((iter = ASN1_INTEGER_get(kdf->iter)) <= 0) { + EVPerror(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS); + goto err; + } + if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, + keylen, key)) + goto err; + rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); + +err: + explicit_bzero(key, keylen); + PBKDF2PARAM_free(kdf); + return rv; +} + +#endif diff --git a/Libraries/libressl/crypto/evp/p_dec.c b/Libraries/libressl/crypto/evp/p_dec.c new file mode 100644 index 000000000..d55b48b77 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_dec.c @@ -0,0 +1,94 @@ +/* $OpenBSD: p_dec.c,v 1.15 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +int +EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, + EVP_PKEY *priv) +{ + int ret = -1; + +#ifndef OPENSSL_NO_RSA + if (priv->type != EVP_PKEY_RSA) { +#endif + EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA); +#ifndef OPENSSL_NO_RSA + goto err; + } + + ret = RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa, + RSA_PKCS1_PADDING); + +err: +#endif + return (ret); +} diff --git a/Libraries/libressl/crypto/evp/p_enc.c b/Libraries/libressl/crypto/evp/p_enc.c new file mode 100644 index 000000000..1abaf0b26 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_enc.c @@ -0,0 +1,91 @@ +/* $OpenBSD: p_enc.c,v 1.15 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +int +EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len, + EVP_PKEY *pubk) +{ + int ret = 0; + +#ifndef OPENSSL_NO_RSA + if (pubk->type != EVP_PKEY_RSA) { +#endif + EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA); +#ifndef OPENSSL_NO_RSA + goto err; + } + ret = RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa, RSA_PKCS1_PADDING); +err: +#endif + return (ret); +} diff --git a/Libraries/libressl/crypto/evp/p_lib.c b/Libraries/libressl/crypto/evp/p_lib.c new file mode 100644 index 000000000..23ec8e603 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_lib.c @@ -0,0 +1,681 @@ +/* $OpenBSD: p_lib.c,v 1.37 2023/09/10 17:32:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "asn1_local.h" +#include "evp_local.h" + +static void EVP_PKEY_free_it(EVP_PKEY *x); + +int +EVP_PKEY_bits(const EVP_PKEY *pkey) +{ + if (pkey && pkey->ameth && pkey->ameth->pkey_bits) + return pkey->ameth->pkey_bits(pkey); + return 0; +} + +int +EVP_PKEY_security_bits(const EVP_PKEY *pkey) +{ + if (pkey == NULL) + return 0; + if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL) + return -2; + + return pkey->ameth->pkey_security_bits(pkey); +} + +int +EVP_PKEY_size(const EVP_PKEY *pkey) +{ + if (pkey && pkey->ameth && pkey->ameth->pkey_size) + return pkey->ameth->pkey_size(pkey); + return 0; +} + +int +EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) +{ +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + int ret = pkey->save_parameters; + + if (mode >= 0) + pkey->save_parameters = mode; + return (ret); + } +#endif +#ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) { + int ret = pkey->save_parameters; + + if (mode >= 0) + pkey->save_parameters = mode; + return (ret); + } +#endif + return (0); +} + +int +EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + if (to->type != from->type) { + EVPerror(EVP_R_DIFFERENT_KEY_TYPES); + goto err; + } + + if (EVP_PKEY_missing_parameters(from)) { + EVPerror(EVP_R_MISSING_PARAMETERS); + goto err; + } + if (from->ameth && from->ameth->param_copy) + return from->ameth->param_copy(to, from); + +err: + return 0; +} + +int +EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) +{ + if (pkey->ameth && pkey->ameth->param_missing) + return pkey->ameth->param_missing(pkey); + return 0; +} + +int +EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (a->type != b->type) + return -1; + if (a->ameth && a->ameth->param_cmp) + return a->ameth->param_cmp(a, b); + return -2; +} + +int +EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (a->type != b->type) + return -1; + + if (a->ameth) { + int ret; + /* Compare parameters if the algorithm has them */ + if (a->ameth->param_cmp) { + ret = a->ameth->param_cmp(a, b); + if (ret <= 0) + return ret; + } + + if (a->ameth->pub_cmp) + return a->ameth->pub_cmp(a, b); + } + + return -2; +} + +EVP_PKEY * +EVP_PKEY_new(void) +{ + EVP_PKEY *ret; + + ret = malloc(sizeof(EVP_PKEY)); + if (ret == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->type = EVP_PKEY_NONE; + ret->save_type = EVP_PKEY_NONE; + ret->references = 1; + ret->ameth = NULL; + ret->engine = NULL; + ret->pkey.ptr = NULL; + ret->attributes = NULL; + ret->save_parameters = 1; + return (ret); +} + +int +EVP_PKEY_up_ref(EVP_PKEY *pkey) +{ + int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + return ((refs > 1) ? 1 : 0); +} + +/* Setup a public key ASN1 method and ENGINE from a NID or a string. + * If pkey is NULL just return 1 or 0 if the algorithm exists. + */ + +static int +pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE **eptr = NULL; + + if (e == NULL) + eptr = &e; + + if (pkey) { + if (pkey->pkey.ptr) + EVP_PKEY_free_it(pkey); + /* If key type matches and a method exists then this + * lookup has succeeded once so just indicate success. + */ + if ((type == pkey->save_type) && pkey->ameth) + return 1; +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(pkey->engine); + pkey->engine = NULL; +#endif + } + if (str) + ameth = EVP_PKEY_asn1_find_str(eptr, str, len); + else + ameth = EVP_PKEY_asn1_find(eptr, type); +#ifndef OPENSSL_NO_ENGINE + if (pkey == NULL && eptr != NULL) + ENGINE_finish(e); +#endif + if (!ameth) { + EVPerror(EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + if (pkey) { + pkey->ameth = ameth; + pkey->engine = e; + + pkey->type = pkey->ameth->pkey_id; + pkey->save_type = type; + } + return 1; +} + +int +EVP_PKEY_set_type(EVP_PKEY *pkey, int type) +{ + return pkey_set_type(pkey, NULL, type, NULL, -1); +} + +EVP_PKEY * +EVP_PKEY_new_raw_private_key(int type, ENGINE *engine, + const unsigned char *private_key, size_t len) +{ + EVP_PKEY *ret; + + if ((ret = EVP_PKEY_new()) == NULL) + goto err; + + if (!pkey_set_type(ret, engine, type, NULL, -1)) + goto err; + + if (ret->ameth->set_priv_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + if (!ret->ameth->set_priv_key(ret, private_key, len)) { + EVPerror(EVP_R_KEY_SETUP_FAILED); + goto err; + } + + return ret; + + err: + EVP_PKEY_free(ret); + + return NULL; +} + +EVP_PKEY * +EVP_PKEY_new_raw_public_key(int type, ENGINE *engine, + const unsigned char *public_key, size_t len) +{ + EVP_PKEY *ret; + + if ((ret = EVP_PKEY_new()) == NULL) + goto err; + + if (!pkey_set_type(ret, engine, type, NULL, -1)) + goto err; + + if (ret->ameth->set_pub_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + if (!ret->ameth->set_pub_key(ret, public_key, len)) { + EVPerror(EVP_R_KEY_SETUP_FAILED); + goto err; + } + + return ret; + + err: + EVP_PKEY_free(ret); + + return NULL; +} + +int +EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, + unsigned char *out_private_key, size_t *out_len) +{ + if (pkey->ameth->get_priv_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (!pkey->ameth->get_priv_key(pkey, out_private_key, out_len)) { + EVPerror(EVP_R_GET_RAW_KEY_FAILED); + return 0; + } + + return 1; +} + +int +EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, + unsigned char *out_public_key, size_t *out_len) +{ + if (pkey->ameth->get_pub_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (!pkey->ameth->get_pub_key(pkey, out_public_key, out_len)) { + EVPerror(EVP_R_GET_RAW_KEY_FAILED); + return 0; + } + + return 1; +} + +EVP_PKEY * +EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, + const EVP_CIPHER *cipher) +{ + EVP_PKEY *ret = NULL; + CMAC_CTX *cmctx = NULL; + + if ((ret = EVP_PKEY_new()) == NULL) + goto err; + if ((cmctx = CMAC_CTX_new()) == NULL) + goto err; + + if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) + goto err; + + if (!CMAC_Init(cmctx, priv, len, cipher, e)) { + EVPerror(EVP_R_KEY_SETUP_FAILED); + goto err; + } + + ret->pkey.ptr = cmctx; + + return ret; + + err: + EVP_PKEY_free(ret); + CMAC_CTX_free(cmctx); + return NULL; +} + +int +EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) +{ + return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len); +} + +int +EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) +{ + if (!EVP_PKEY_set_type(pkey, type)) + return 0; + pkey->pkey.ptr = key; + return (key != NULL); +} + +void * +EVP_PKEY_get0(const EVP_PKEY *pkey) +{ + return pkey->pkey.ptr; +} + +const unsigned char * +EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len) +{ + ASN1_OCTET_STRING *os; + + if (pkey->type != EVP_PKEY_HMAC) { + EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY); + return NULL; + } + + os = EVP_PKEY_get0(pkey); + *len = os->length; + + return os->data; +} + +#ifndef OPENSSL_NO_RSA +RSA * +EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA_PSS) + return pkey->pkey.rsa; + + EVPerror(EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; +} + +RSA * +EVP_PKEY_get1_RSA(EVP_PKEY *pkey) +{ + RSA *rsa; + + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) + return NULL; + + RSA_up_ref(rsa); + + return rsa; +} + +int +EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) +{ + int ret = EVP_PKEY_assign_RSA(pkey, key); + if (ret != 0) + RSA_up_ref(key); + return ret; +} +#endif + +#ifndef OPENSSL_NO_DSA +DSA * +EVP_PKEY_get0_DSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DSA) { + EVPerror(EVP_R_EXPECTING_A_DSA_KEY); + return NULL; + } + return pkey->pkey.dsa; +} + +DSA * +EVP_PKEY_get1_DSA(EVP_PKEY *pkey) +{ + DSA *dsa; + + if ((dsa = EVP_PKEY_get0_DSA(pkey)) == NULL) + return NULL; + + DSA_up_ref(dsa); + + return dsa; +} + +int +EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) +{ + int ret = EVP_PKEY_assign_DSA(pkey, key); + if (ret != 0) + DSA_up_ref(key); + return ret; +} +#endif + +#ifndef OPENSSL_NO_EC +EC_KEY * +EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_EC) { + EVPerror(EVP_R_EXPECTING_A_EC_KEY); + return NULL; + } + return pkey->pkey.ec; +} + +EC_KEY * +EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +{ + EC_KEY *key; + + if ((key = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) + return NULL; + + EC_KEY_up_ref(key); + + return key; +} + +int +EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) +{ + int ret = EVP_PKEY_assign_EC_KEY(pkey, key); + if (ret != 0) + EC_KEY_up_ref(key); + return ret; +} +#endif + + +#ifndef OPENSSL_NO_DH +DH * +EVP_PKEY_get0_DH(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DH) { + EVPerror(EVP_R_EXPECTING_A_DH_KEY); + return NULL; + } + return pkey->pkey.dh; +} + +DH * +EVP_PKEY_get1_DH(EVP_PKEY *pkey) +{ + DH *dh; + + if ((dh = EVP_PKEY_get0_DH(pkey)) == NULL) + return NULL; + + DH_up_ref(dh); + + return dh; +} + +int +EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) +{ + int ret = EVP_PKEY_assign_DH(pkey, key); + if (ret != 0) + DH_up_ref(key); + return ret; +} +#endif + +int +EVP_PKEY_type(int type) +{ + int ret; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e; + ameth = EVP_PKEY_asn1_find(&e, type); + if (ameth) + ret = ameth->pkey_id; + else + ret = NID_undef; +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(e); +#endif + return ret; +} + +int +EVP_PKEY_id(const EVP_PKEY *pkey) +{ + return pkey->type; +} + +int +EVP_PKEY_base_id(const EVP_PKEY *pkey) +{ + return EVP_PKEY_type(pkey->type); +} + +void +EVP_PKEY_free(EVP_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY); + if (i > 0) + return; + + EVP_PKEY_free_it(x); + if (x->attributes) + sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); + free(x); +} + +static void +EVP_PKEY_free_it(EVP_PKEY *x) +{ + if (x->ameth && x->ameth->pkey_free) { + x->ameth->pkey_free(x); + x->pkey.ptr = NULL; + } +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(x->engine); + x->engine = NULL; +#endif +} + +static int +unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr) +{ + if (!BIO_indent(out, indent, 128)) + return 0; + BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)); + return 1; +} + +int +EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->pub_print) + return pkey->ameth->pub_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Public Key"); +} + +int +EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->priv_print) + return pkey->ameth->priv_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Private Key"); +} + +int +EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->param_print) + return pkey->ameth->param_print(out, pkey, indent, pctx); + return unsup_alg(out, pkey, indent, "Parameters"); +} + +int +EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) +{ + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return -2; + return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, + 0, pnid); +} diff --git a/Libraries/libressl/crypto/evp/p_open.c b/Libraries/libressl/crypto/evp/p_open.c new file mode 100644 index 000000000..d18548e3f --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_open.c @@ -0,0 +1,128 @@ +/* $OpenBSD: p_open.c,v 1.23 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_RSA + +#include +#include +#include +#include +#include + +#include "evp_local.h" + +int +EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv) +{ + unsigned char *key = NULL; + int i, size = 0, ret = 0; + + if (type) { + EVP_CIPHER_CTX_init(ctx); + if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL)) + return 0; + } + + if (!priv) + return 1; + + if (priv->type != EVP_PKEY_RSA) { + EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA); + goto err; + } + + size = RSA_size(priv->pkey.rsa); + key = malloc(size + 2); + if (key == NULL) { + /* ERROR */ + EVPerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + i = EVP_PKEY_decrypt_old(key, ek, ekl, priv); + if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { + /* ERROR */ + goto err; + } + if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) + goto err; + + ret = 1; + +err: + freezero(key, size); + return (ret); +} + +int +EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + i = EVP_DecryptFinal_ex(ctx, out, outl); + if (i) + i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); + return (i); +} +#endif diff --git a/Libraries/libressl/crypto/evp/p_seal.c b/Libraries/libressl/crypto/evp/p_seal.c new file mode 100644 index 000000000..b98da9436 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_seal.c @@ -0,0 +1,124 @@ +/* $OpenBSD: p_seal.c,v 1.16 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +int +EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek, + int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk) +{ + unsigned char key[EVP_MAX_KEY_LENGTH]; + int i; + + if (type) { + EVP_CIPHER_CTX_init(ctx); + if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL)) + return 0; + } + if ((npubk <= 0) || !pubk) + return 1; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + return 0; + if (EVP_CIPHER_CTX_iv_length(ctx)) + arc4random_buf(iv, EVP_CIPHER_CTX_iv_length(ctx)); + + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) + return 0; + + for (i = 0; i < npubk; i++) { + ekl[i] = EVP_PKEY_encrypt_old(ek[i], key, + EVP_CIPHER_CTX_key_length(ctx), pubk[i]); + if (ekl[i] <= 0) + return (-1); + } + return (npubk); +} + +/* MACRO +void EVP_SealUpdate(ctx,out,outl,in,inl) +EVP_CIPHER_CTX *ctx; +unsigned char *out; +int *outl; +unsigned char *in; +int inl; + { + EVP_EncryptUpdate(ctx,out,outl,in,inl); + } +*/ + +int +EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + i = EVP_EncryptFinal_ex(ctx, out, outl); + if (i) + i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL); + return i; +} diff --git a/Libraries/libressl/crypto/evp/p_sign.c b/Libraries/libressl/crypto/evp/p_sign.c new file mode 100644 index 000000000..f7c21178a --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_sign.c @@ -0,0 +1,104 @@ +/* $OpenBSD: p_sign.c,v 1.19 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include "evp_local.h" + +int +EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, + EVP_PKEY *pkey) +{ + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + size_t sltmp; + int ret = 0; + + *siglen = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) + goto err; + EVP_MD_CTX_cleanup(&tmp_ctx); + + sltmp = (size_t)EVP_PKEY_size(pkey); + + if ((pkctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) + goto err; + if (EVP_PKEY_sign_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) + goto err; + *siglen = sltmp; + + ret = 1; + + err: + EVP_PKEY_CTX_free(pkctx); + return ret; +} diff --git a/Libraries/libressl/crypto/evp/p_verify.c b/Libraries/libressl/crypto/evp/p_verify.c new file mode 100644 index 000000000..da7ab5425 --- /dev/null +++ b/Libraries/libressl/crypto/evp/p_verify.c @@ -0,0 +1,97 @@ +/* $OpenBSD: p_verify.c,v 1.18 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include "evp_local.h" + +int +EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey) +{ + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + int ret = 0; + + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) + goto err; + EVP_MD_CTX_cleanup(&tmp_ctx); + + ret = -1; + if ((pkctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + ret = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); + + err: + EVP_PKEY_CTX_free(pkctx); + return ret; +} diff --git a/Libraries/libressl/crypto/evp/pmeth_fn.c b/Libraries/libressl/crypto/evp/pmeth_fn.c new file mode 100644 index 000000000..a304752e6 --- /dev/null +++ b/Libraries/libressl/crypto/evp/pmeth_fn.c @@ -0,0 +1,345 @@ +/* $OpenBSD: pmeth_fn.c,v 1.9 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +#include "evp_local.h" + +#define M_check_autoarg(ctx, arg, arglen, err) \ + if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \ + { \ + size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ + if (!arg) \ + { \ + *arglen = pksize; \ + return 1; \ + } \ + else if (*arglen < pksize) \ + { \ + EVPerror(EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\ + return 0; \ + } \ + } + +int +EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_SIGN; + if (!ctx->pmeth->sign_init) + return 1; + ret = ctx->pmeth->sign_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) + return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); +} + +int +EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + if (!ctx->pmeth->verify_init) + return 1; + ret = ctx->pmeth->verify_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); +} + +int +EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + if (!ctx->pmeth->verify_recover_init) + return 1; + ret = ctx->pmeth->verify_recover_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) + return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); +} + +int +EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + if (!ctx->pmeth->encrypt_init) + return 1; + ret = ctx->pmeth->encrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int +EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + if (!ctx->pmeth->decrypt_init) + return 1; + ret = ctx->pmeth->decrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + +int +EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + if (!ctx->pmeth->derive_init) + return 1; + ret = ctx->pmeth->derive_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) +{ + int ret; + + if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive || + ctx->pmeth->encrypt || ctx->pmeth->decrypt) || + !ctx->pmeth->ctrl) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE && + ctx->operation != EVP_PKEY_OP_ENCRYPT && + ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (!ctx->pkey) { + EVPerror(EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) { + EVPerror(EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are + * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + * (different key types) is impossible here because it is checked earlier. + * -2 is OK for us here, as well as 1, so we can check for 0 only. */ + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { + EVPerror(EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) { + ctx->peerkey = NULL; + return ret; + } + + CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY); + return 1; +} + +int +EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) + return ctx->pmeth->derive(ctx, key, pkeylen); +} diff --git a/Libraries/libressl/crypto/evp/pmeth_gn.c b/Libraries/libressl/crypto/evp/pmeth_gn.c new file mode 100644 index 000000000..b4c0395d9 --- /dev/null +++ b/Libraries/libressl/crypto/evp/pmeth_gn.c @@ -0,0 +1,288 @@ +/* $OpenBSD: pmeth_gn.c,v 1.13 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "asn1_local.h" +#include "bn_local.h" +#include "evp_local.h" + +int +EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_PARAMGEN; + if (!ctx->pmeth->paramgen_init) + return 1; + ret = ctx->pmeth->paramgen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (!ppkey) + return -1; + + if (!*ppkey) + *ppkey = EVP_PKEY_new(); + + ret = ctx->pmeth->paramgen(ctx, *ppkey); + if (ret <= 0) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; +} + +int +EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + if (!ctx->pmeth->keygen_init) + return 1; + ret = ctx->pmeth->keygen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int +EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) { + EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (!ppkey) + return -1; + + if (!*ppkey) + *ppkey = EVP_PKEY_new(); + + ret = ctx->pmeth->keygen(ctx, *ppkey); + if (ret <= 0) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; +} + +void +EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) +{ + ctx->pkey_gencb = cb; +} + +EVP_PKEY_gen_cb * +EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) +{ + return ctx->pkey_gencb; +} + +/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB + * style callbacks. + */ + +static int +trans_cb(int a, int b, BN_GENCB *gcb) +{ + EVP_PKEY_CTX *ctx = gcb->arg; + ctx->keygen_info[0] = a; + ctx->keygen_info[1] = b; + return ctx->pkey_gencb(ctx); +} + +void +evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) +{ + BN_GENCB_set(cb, trans_cb, ctx); +} + +int +EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) +{ + if (idx == -1) + return ctx->keygen_info_count; + if (idx < 0 || idx > ctx->keygen_info_count) + return 0; + return ctx->keygen_info[idx]; +} + +EVP_PKEY * +EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen) +{ + EVP_PKEY_CTX *mac_ctx = NULL; + EVP_PKEY *mac_key = NULL; + + mac_ctx = EVP_PKEY_CTX_new_id(type, e); + if (!mac_ctx) + return NULL; + if (EVP_PKEY_keygen_init(mac_ctx) <= 0) + goto merr; + if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, keylen, (void *)key) <= 0) + goto merr; + if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) + goto merr; + +merr: + EVP_PKEY_CTX_free(mac_ctx); + return mac_key; +} + +int +EVP_PKEY_check(EVP_PKEY_CTX *ctx) +{ + EVP_PKEY *pkey; + + if ((pkey = ctx->pkey) == NULL) { + EVPerror(EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pmeth->check != NULL) + return ctx->pmeth->check(pkey); + + if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + return pkey->ameth->pkey_check(pkey); +} + +int +EVP_PKEY_public_check(EVP_PKEY_CTX *ctx) +{ + EVP_PKEY *pkey; + + if ((pkey = ctx->pkey) == NULL) { + EVPerror(EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pmeth->public_check != NULL) + return ctx->pmeth->public_check(pkey); + + if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + return pkey->ameth->pkey_public_check(pkey); +} + +int +EVP_PKEY_param_check(EVP_PKEY_CTX *ctx) +{ + EVP_PKEY *pkey; + + if ((pkey = ctx->pkey) == NULL) { + EVPerror(EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pmeth->param_check != NULL) + return ctx->pmeth->param_check(pkey); + + if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + return pkey->ameth->pkey_param_check(pkey); +} diff --git a/Libraries/libressl/crypto/evp/pmeth_lib.c b/Libraries/libressl/crypto/evp/pmeth_lib.c new file mode 100644 index 000000000..b480a574f --- /dev/null +++ b/Libraries/libressl/crypto/evp/pmeth_lib.c @@ -0,0 +1,627 @@ +/* $OpenBSD: pmeth_lib.c,v 1.33 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "asn1_local.h" +#include "evp_local.h" + +DECLARE_STACK_OF(EVP_PKEY_METHOD) +STACK_OF(EVP_PKEY_METHOD) *pkey_app_methods = NULL; + +extern const EVP_PKEY_METHOD cmac_pkey_meth; +extern const EVP_PKEY_METHOD dh_pkey_meth; +extern const EVP_PKEY_METHOD dsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth; +extern const EVP_PKEY_METHOD ed25519_pkey_meth; +extern const EVP_PKEY_METHOD gostimit_pkey_meth; +extern const EVP_PKEY_METHOD gostr01_pkey_meth; +extern const EVP_PKEY_METHOD hkdf_pkey_meth; +extern const EVP_PKEY_METHOD hmac_pkey_meth; +extern const EVP_PKEY_METHOD rsa_pkey_meth; +extern const EVP_PKEY_METHOD rsa_pss_pkey_meth; +extern const EVP_PKEY_METHOD x25519_pkey_meth; + +static const EVP_PKEY_METHOD *pkey_methods[] = { + &cmac_pkey_meth, + &dh_pkey_meth, + &dsa_pkey_meth, + &ec_pkey_meth, + &ed25519_pkey_meth, + &gostimit_pkey_meth, + &gostr01_pkey_meth, + &hkdf_pkey_meth, + &hmac_pkey_meth, + &rsa_pkey_meth, + &rsa_pss_pkey_meth, + &x25519_pkey_meth, +}; + +static const size_t pkey_methods_count = + sizeof(pkey_methods) / sizeof(pkey_methods[0]); + +int +evp_pkey_meth_get_count(void) +{ + int num = pkey_methods_count; + + if (pkey_app_methods != NULL) + num += sk_EVP_PKEY_METHOD_num(pkey_app_methods); + + return num; +} + +const EVP_PKEY_METHOD * +evp_pkey_meth_get0(int idx) +{ + int num = pkey_methods_count; + + if (idx < 0) + return NULL; + if (idx < num) + return pkey_methods[idx]; + + idx -= num; + + return sk_EVP_PKEY_METHOD_value(pkey_app_methods, idx); +} + +const EVP_PKEY_METHOD * +EVP_PKEY_meth_find(int type) +{ + const EVP_PKEY_METHOD *pmeth; + int i; + + for (i = evp_pkey_meth_get_count() - 1; i >= 0; i--) { + pmeth = evp_pkey_meth_get0(i); + if (pmeth->pkey_id == type) + return pmeth; + } + + return NULL; +} + +static EVP_PKEY_CTX * +evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *engine, int id) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + const EVP_PKEY_METHOD *pmeth; + + if (id == -1) { + if (pkey == NULL || pkey->ameth == NULL) + return NULL; + id = pkey->ameth->pkey_id; + } +#ifndef OPENSSL_NO_ENGINE + if (pkey != NULL && pkey->engine != NULL) + engine = pkey->engine; + /* Try to find an ENGINE which implements this method. */ + if (engine != NULL) { + if (!ENGINE_init(engine)) { + EVPerror(ERR_R_ENGINE_LIB); + return NULL; + } + } else + engine = ENGINE_get_pkey_meth_engine(id); + + /* Look up method handler in ENGINE or use internal tables. */ + if (engine != NULL) + pmeth = ENGINE_get_pkey_meth(engine, id); + else +#endif + pmeth = EVP_PKEY_meth_find(id); + + if (pmeth == NULL) { + EVPerror(EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + + if ((pkey_ctx = calloc(1, sizeof(*pkey_ctx))) == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + goto err; + } + pkey_ctx->engine = engine; + engine = NULL; + pkey_ctx->pmeth = pmeth; + pkey_ctx->operation = EVP_PKEY_OP_UNDEFINED; + if ((pkey_ctx->pkey = pkey) != NULL) + EVP_PKEY_up_ref(pkey_ctx->pkey); + + if (pmeth->init != NULL) { + if (pmeth->init(pkey_ctx) <= 0) + goto err; + } + + return pkey_ctx; + + err: + EVP_PKEY_CTX_free(pkey_ctx); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(engine); +#endif + + return NULL; +} + +EVP_PKEY_METHOD* +EVP_PKEY_meth_new(int id, int flags) +{ + EVP_PKEY_METHOD *pmeth; + + if ((pmeth = calloc(1, sizeof(EVP_PKEY_METHOD))) == NULL) + return NULL; + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + + return pmeth; +} + +void +EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth) +{ + if (ppkey_id) + *ppkey_id = meth->pkey_id; + if (pflags) + *pflags = meth->flags; +} + +void +EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) +{ + EVP_PKEY_METHOD preserve; + + preserve.pkey_id = dst->pkey_id; + preserve.flags = dst->flags; + + *dst = *src; + + dst->pkey_id = preserve.pkey_id; + dst->flags = preserve.flags; +} + +void +EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) +{ + if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) + free(pmeth); +} + +EVP_PKEY_CTX * +EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *engine) +{ + return evp_pkey_ctx_new(pkey, engine, -1); +} + +EVP_PKEY_CTX * +EVP_PKEY_CTX_new_id(int id, ENGINE *engine) +{ + return evp_pkey_ctx_new(NULL, engine, id); +} + +EVP_PKEY_CTX * +EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) +{ + EVP_PKEY_CTX *rctx = NULL; + + if (pctx->pmeth == NULL || pctx->pmeth->copy == NULL) + goto err; +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a pkey context using an ENGINE */ + if (pctx->engine != NULL && !ENGINE_init(pctx->engine)) { + EVPerror(ERR_R_ENGINE_LIB); + goto err; + } +#endif + if ((rctx = calloc(1, sizeof(*rctx))) == NULL) { + EVPerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + rctx->pmeth = pctx->pmeth; +#ifndef OPENSSL_NO_ENGINE + rctx->engine = pctx->engine; +#endif + + if ((rctx->pkey = pctx->pkey) != NULL) + EVP_PKEY_up_ref(rctx->pkey); + if ((rctx->peerkey = pctx->peerkey) != NULL) + EVP_PKEY_up_ref(rctx->peerkey); + + rctx->operation = pctx->operation; + + if (pctx->pmeth->copy(rctx, pctx) <= 0) + goto err; + + return rctx; + + err: + EVP_PKEY_CTX_free(rctx); + return NULL; +} + +int +EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) +{ + if (pkey_app_methods == NULL) { + pkey_app_methods = sk_EVP_PKEY_METHOD_new(NULL); + if (pkey_app_methods == NULL) + return 0; + } + + if (!sk_EVP_PKEY_METHOD_push(pkey_app_methods, pmeth)) + return 0; + + return 1; +} + +void +EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(ctx->engine); +#endif + free(ctx); +} + +int +EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, + int p1, void *p2) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + EVPerror(EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) + return -1; + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + EVPerror(EVP_R_NO_OPERATION_SET); + return -1; + } + + if ((optype != -1) && !(ctx->operation & optype)) { + EVPerror(EVP_R_INVALID_OPERATION); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + + if (ret == -2) + EVPerror(EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; + +} + +int +EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { + EVPerror(EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!strcmp(name, "digest")) { + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_MD, value); + } + return ctx->pmeth->ctrl_str(ctx, name, value); +} + +int +EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str) +{ + size_t len; + + if ((len = strlen(str)) > INT_MAX) + return -1; + + return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str); +} + +int +EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hexstr) +{ + unsigned char *hex = NULL; + long length; + int ret = 0; + + if ((hex = string_to_hex(hexstr, &length)) == NULL) + goto err; + if (length < 0 || length > INT_MAX) { + ret = -1; + goto err; + } + + ret = ctx->pmeth->ctrl(ctx, cmd, length, hex); + + err: + free(hex); + return ret; +} + +int +EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md_name) +{ + const EVP_MD *md; + + if ((md = EVP_get_digestbyname(md_name)) == NULL) { + EVPerror(EVP_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)md); +} + +int +EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) +{ + return ctx->operation; +} + +void +EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) +{ + ctx->keygen_info = dat; + ctx->keygen_info_count = datlen; +} + +void +EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) +{ + ctx->data = data; +} + +void * +EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) +{ + return ctx->data; +} + +EVP_PKEY * +EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) +{ + return ctx->pkey; +} + +EVP_PKEY * +EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) +{ + return ctx->peerkey; +} + +void +EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +void * +EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) +{ + return ctx->app_data; +} + +void +EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init)(EVP_PKEY_CTX *ctx)) +{ + pmeth->init = init; +} + +void +EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)) +{ + pmeth->copy = copy; +} + +void +EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup)(EVP_PKEY_CTX *ctx)) +{ + pmeth->cleanup = cleanup; +} + +void +EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init)(EVP_PKEY_CTX *ctx), + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) +{ + pmeth->paramgen_init = paramgen_init; + pmeth->paramgen = paramgen; +} + +void +EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init)(EVP_PKEY_CTX *ctx), + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) +{ + pmeth->keygen_init = keygen_init; + pmeth->keygen = keygen; +} + +void +EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init)(EVP_PKEY_CTX *ctx), + int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)) +{ + pmeth->sign_init = sign_init; + pmeth->sign = sign; +} + +void +EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init)(EVP_PKEY_CTX *ctx), + int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen)) +{ + pmeth->verify_init = verify_init; + pmeth->verify = verify; +} + +void +EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init)(EVP_PKEY_CTX *ctx), + int (*verify_recover)(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)) +{ + pmeth->verify_recover_init = verify_recover_init; + pmeth->verify_recover = verify_recover; +} + +void +EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx)) +{ + pmeth->signctx_init = signctx_init; + pmeth->signctx = signctx; +} + +void +EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx)) +{ + pmeth->verifyctx_init = verifyctx_init; + pmeth->verifyctx = verifyctx; +} + +void +EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init)(EVP_PKEY_CTX *ctx), + int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)) +{ + pmeth->encrypt_init = encrypt_init; + pmeth->encrypt = encryptfn; +} + +void +EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init)(EVP_PKEY_CTX *ctx), + int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)) +{ + pmeth->decrypt_init = decrypt_init; + pmeth->decrypt = decrypt; +} + +void +EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init)(EVP_PKEY_CTX *ctx), + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)) +{ + pmeth->derive_init = derive_init; + pmeth->derive = derive; +} + +void +EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), + int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)) +{ + pmeth->ctrl = ctrl; + pmeth->ctrl_str = ctrl_str; +} + +void +EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, int (*check)(EVP_PKEY *pkey)) +{ + pmeth->check = check; +} + +void +EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth, + int (*public_check)(EVP_PKEY *pkey)) +{ + pmeth->public_check = public_check; +} + +void +EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth, + int (*param_check)(EVP_PKEY *pkey)) +{ + pmeth->param_check = param_check; +} diff --git a/Libraries/libressl/crypto/ex_data.c b/Libraries/libressl/crypto/ex_data.c new file mode 100644 index 000000000..17db16e58 --- /dev/null +++ b/Libraries/libressl/crypto/ex_data.c @@ -0,0 +1,637 @@ +/* $OpenBSD: ex_data.c,v 1.23 2023/07/28 10:19:20 tb Exp $ */ + +/* + * Overhaul notes; + * + * This code is now *mostly* thread-safe. It is now easier to understand in what + * ways it is safe and in what ways it is not, which is an improvement. Firstly, + * all per-class stacks and index-counters for ex_data are stored in the same + * global LHASH table (keyed by class). This hash table uses locking for all + * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be + * called when no other threads can possibly race against it (even if it was + * locked, the race would mean it's possible the hash table might have been + * recreated after the cleanup). As classes can only be added to the hash table, + * and within each class, the stack of methods can only be incremented, the + * locking mechanics are simpler than they would otherwise be. For example, the + * new/dup/free ex_data functions will lock the hash table, copy the method + * pointers it needs from the relevant class, then unlock the hash table before + * actually applying those method pointers to the task of the new/dup/free + * operations. As they can't be removed from the method-stack, only + * supplemented, there's no race conditions associated with using them outside + * the lock. The get/set_ex_data functions are not locked because they do not + * involve this global state at all - they operate directly with a previously + * obtained per-class method index and a particular "ex_data" variable. These + * variables are usually instantiated per-context (eg. each RSA structure has + * one) so locking on read/write access to that variable can be locked locally + * if required (eg. using the "RSA" lock to synchronise access to a + * per-RSA-structure ex_data variable if required). + * [Geoff] + */ + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +typedef struct crypto_ex_data_func_st { + long argl; /* Arbitrary long */ + void *argp; /* Arbitrary void * */ + CRYPTO_EX_new *new_func; + CRYPTO_EX_free *free_func; + CRYPTO_EX_dup *dup_func; +} CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) +#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) + +/* An opaque type representing an implementation of "ex_data" support */ +typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; + +/* What an "implementation of ex_data functionality" looks like */ +struct st_CRYPTO_EX_DATA_IMPL { + /*********************/ + /* GLOBAL OPERATIONS */ + /* Return a new class index */ + int (*cb_new_class)(void); + /* Cleanup all state used by the implementation */ + void (*cb_cleanup)(void); + /************************/ + /* PER-CLASS OPERATIONS */ + /* Get a new method index within a class */ + int (*cb_get_new_index)(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + /* Initialise a new CRYPTO_EX_DATA of a given class */ + int (*cb_new_ex_data)(int class_index, void *obj, + CRYPTO_EX_DATA *ad); + /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */ + int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); + /* Cleanup a CRYPTO_EX_DATA of a given class */ + void (*cb_free_ex_data)(int class_index, void *obj, + CRYPTO_EX_DATA *ad); +}; + +/* The implementation we use at run-time */ +static const CRYPTO_EX_DATA_IMPL *impl = NULL; + +/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg. + * EX_IMPL(get_new_index)(...); +*/ +#define EX_IMPL(a) impl->cb_##a + +/* Predeclare the "default" ex_data implementation */ +static int int_new_class(void); +static void int_cleanup(void); +static int int_get_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +static int int_new_ex_data(int class_index, void *obj, + CRYPTO_EX_DATA *ad); +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +static void int_free_ex_data(int class_index, void *obj, + CRYPTO_EX_DATA *ad); + +static CRYPTO_EX_DATA_IMPL impl_default = { + int_new_class, + int_cleanup, + int_get_new_index, + int_new_ex_data, + int_dup_ex_data, + int_free_ex_data +}; + +/* Internal function that checks whether "impl" is set and if not, sets it to + * the default. */ +static void +impl_check(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!impl) + impl = &impl_default; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); +} +/* A macro wrapper for impl_check that first uses a non-locked test before + * invoking the function (which checks again inside a lock). */ +#define IMPL_CHECK if(!impl) impl_check(); + +/****************************************************************************/ +/* Interal (default) implementation of "ex_data" support. API functions are + * further down. */ + +/* The type that represents what each "class" used to implement locally. A STACK + * of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is the global + * value representing the class that is used to distinguish these items. */ +typedef struct st_ex_class_item { + int class_index; + STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + int meth_num; +} EX_CLASS_ITEM; + +/* When assigning new class indexes, this is our counter */ +#define CRYPTO_EX_INDEX_USER 100 +static int ex_class = CRYPTO_EX_INDEX_USER; + +/* The global hash table of EX_CLASS_ITEM items */ +DECLARE_LHASH_OF(EX_CLASS_ITEM); +static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL; + +/* The callbacks required in the "ex_data" hash table */ +static unsigned long +ex_class_item_hash(const EX_CLASS_ITEM *a) +{ + return a->class_index; +} + +static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM) + +static int +ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) +{ + return a->class_index - b->class_index; +} + +static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM) + +/* Internal functions used by the "impl_default" implementation to access the + * state */ + +static int +ex_data_check(void) +{ + int toret = 1; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!ex_data && + (ex_data = lh_EX_CLASS_ITEM_new()) == NULL) + toret = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} +/* This macros helps reduce the locking from repeated checks because the + * ex_data_check() function checks ex_data again inside a lock. */ +#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail} + +/* This "inner" callback is used by the callback function that follows it */ +static void +def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs) +{ + free(funcs); +} + +/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from + * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do + * any locking. */ +static void +def_cleanup_cb(void *a_void) +{ + EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void; + sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb); + free(item); +} + +/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a + * given class. Handles locking. */ +static EX_CLASS_ITEM * +def_get_class(int class_index) +{ + EX_CLASS_ITEM d, *p, *gen; + EX_DATA_CHECK(return NULL;) + d.class_index = class_index; + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); + if (!p) { + gen = malloc(sizeof(EX_CLASS_ITEM)); + if (gen) { + gen->class_index = class_index; + gen->meth_num = 1; + gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + if (!gen->meth) + free(gen); + else { + /* Because we're inside the ex_data lock, the + * return value from the insert will be NULL */ + (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); + p = gen; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + if (!p) + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return p; +} + +/* Add a new method to the given EX_CLASS_ITEM and return the corresponding + * index (or -1 for error). Handles locking. */ +static int +def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + int toret = -1; + CRYPTO_EX_DATA_FUNCS *a = malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + + if (!a) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return -1; + } + a->argl = argl; + a->argp = argp; + a->new_func = new_func; + a->dup_func = dup_func; + a->free_func = free_func; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) { + if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + free(a); + goto err; + } + } + toret = item->meth_num++; + (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); +err: + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/**************************************************************/ +/* The functions in the default CRYPTO_EX_DATA_IMPL structure */ + +static int +int_new_class(void) +{ + int toret; + + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + toret = ex_class++; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +static void +int_cleanup(void) +{ + EX_DATA_CHECK(return;) + lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb); + lh_EX_CLASS_ITEM_free(ex_data); + ex_data = NULL; + impl = NULL; +} + +static int +int_get_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + EX_CLASS_ITEM *item = def_get_class(class_index); + + if (!item) + return -1; + return def_add_index(item, argl, argp, new_func, dup_func, free_func); +} + +/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in + * the lock, then using them outside the lock. NB: Thread-safety only applies to + * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad' + * itself. */ +static int +int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + int mx, i; + void *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + EX_CLASS_ITEM *item = def_get_class(class_index); + + if (!item) + /* error is already set */ + return 0; + ad->sk = NULL; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + if (mx > 0) { + storage = reallocarray(NULL, mx, sizeof(CRYPTO_EX_DATA_FUNCS*)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value( + item->meth, i); + } +skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < mx; i++) { + if (storage[i] && storage[i]->new_func) { + ptr = CRYPTO_get_ex_data(ad, i); + storage[i]->new_func(obj, ptr, ad, i, + storage[i]->argl, storage[i]->argp); + } + } + free(storage); + return 1; +} + +/* Same thread-safety notes as for "int_new_ex_data" */ +static int +int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from) +{ + int mx, j, i; + char *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + EX_CLASS_ITEM *item; + + if (!from->sk) + /* 'to' should be "blank" which *is* just like 'from' */ + return 1; + if ((item = def_get_class(class_index)) == NULL) + return 0; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + j = sk_void_num(from->sk); + if (j < mx) + mx = j; + if (mx > 0) { + storage = reallocarray(NULL, mx, sizeof(CRYPTO_EX_DATA_FUNCS*)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value( + item->meth, i); + } +skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < mx; i++) { + ptr = CRYPTO_get_ex_data(from, i); + if (storage[i] && storage[i]->dup_func) + storage[i]->dup_func(to, from, &ptr, i, + storage[i]->argl, storage[i]->argp); + CRYPTO_set_ex_data(to, i, ptr); + } + free(storage); + return 1; +} + +/* Same thread-safety notes as for "int_new_ex_data" */ +static void +int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + int mx, i; + EX_CLASS_ITEM *item; + void *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + + if ((item = def_get_class(class_index)) == NULL) + return; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + if (mx > 0) { + storage = reallocarray(NULL, mx, sizeof(CRYPTO_EX_DATA_FUNCS*)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value( + item->meth, i); + } +skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return; + } + for (i = 0; i < mx; i++) { + if (storage[i] && storage[i]->free_func) { + ptr = CRYPTO_get_ex_data(ad, i); + storage[i]->free_func(obj, ptr, ad, i, + storage[i]->argl, storage[i]->argp); + } + } + free(storage); + if (ad->sk) { + sk_void_free(ad->sk); + ad->sk = NULL; + } +} + +/********************************************************************/ +/* API functions that defer all "state" operations to the "ex_data" + * implementation we have set. */ + +/* Release all "ex_data" state to prevent memory leaks. This can't be made + * thread-safe without overhauling a lot of stuff, and shouldn't really be + * called under potential race-conditions anyway (it's for program shutdown + * after all). */ +void +CRYPTO_cleanup_all_ex_data(void) +{ + IMPL_CHECK + EX_IMPL(cleanup)(); +} +LCRYPTO_ALIAS(CRYPTO_cleanup_all_ex_data); + +/* Inside an existing class, get/register a new index. */ +int +CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + int ret = -1; + + IMPL_CHECK + ret = EX_IMPL(get_new_index)(class_index, + argl, argp, new_func, dup_func, free_func); + return ret; +} +LCRYPTO_ALIAS(CRYPTO_get_ex_new_index); + +/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including + * calling new() callbacks for each index in the class used by this variable */ +int +CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + IMPL_CHECK + return EX_IMPL(new_ex_data)(class_index, obj, ad); +} +LCRYPTO_ALIAS(CRYPTO_new_ex_data); + +/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for + * each index in the class used by this variable */ +int +CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from) +{ + IMPL_CHECK + return EX_IMPL(dup_ex_data)(class_index, to, from); +} +LCRYPTO_ALIAS(CRYPTO_dup_ex_data); + +/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for + * each index in the class used by this variable */ +void +CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + IMPL_CHECK + EX_IMPL(free_ex_data)(class_index, obj, ad); +} +LCRYPTO_ALIAS(CRYPTO_free_ex_data); + +/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a + * particular index in the class used by this variable */ +int +CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) +{ + int i; + + if (ad->sk == NULL) { + if ((ad->sk = sk_void_new_null()) == NULL) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return (0); + } + } + i = sk_void_num(ad->sk); + + while (i <= idx) { + if (!sk_void_push(ad->sk, NULL)) { + CRYPTOerror(ERR_R_MALLOC_FAILURE); + return (0); + } + i++; + } + sk_void_set(ad->sk, idx, val); + return (1); +} +LCRYPTO_ALIAS(CRYPTO_set_ex_data); + +/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a + * particular index in the class used by this variable */ +void * +CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) +{ + if (ad->sk == NULL) + return (0); + else if (idx >= sk_void_num(ad->sk)) + return (0); + else + return (sk_void_value(ad->sk, idx)); +} +LCRYPTO_ALIAS(CRYPTO_get_ex_data); diff --git a/Libraries/libressl/crypto/gost/gost2814789.c b/Libraries/libressl/crypto/gost/gost2814789.c new file mode 100644 index 000000000..dac3a8eab --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost2814789.c @@ -0,0 +1,480 @@ +/* $OpenBSD: gost2814789.c,v 1.9 2023/07/08 14:30:44 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include + +#include "gost_local.h" + +static inline unsigned int +f(const GOST2814789_KEY *c, unsigned int x) +{ + return c->k87[(x>>24) & 255] | c->k65[(x>>16) & 255]| + c->k43[(x>> 8) & 255] | c->k21[(x ) & 255]; +} + +void +Gost2814789_encrypt(const unsigned char *in, unsigned char *out, + const GOST2814789_KEY *key) +{ + unsigned int n1, n2; /* As named in the GOST */ + + c2l(in, n1); + c2l(in, n2); + + /* Instead of swapping halves, swap names each round */ + n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]); + n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]); + n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]); + n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]); + + n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]); + n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]); + n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]); + n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]); + + n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]); + n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]); + n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]); + n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]); + + n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]); + n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]); + n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]); + n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]); + + l2c(n2, out); + l2c(n1, out); +} + +void +Gost2814789_decrypt(const unsigned char *in, unsigned char *out, + const GOST2814789_KEY *key) +{ + unsigned int n1, n2; /* As named in the GOST */ + + c2l(in, n1); + c2l(in, n2); + + /* Instead of swapping halves, swap names each round */ + n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]); + n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]); + n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]); + n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]); + + n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]); + n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]); + n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]); + n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]); + + n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]); + n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]); + n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]); + n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]); + + n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]); + n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]); + n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]); + n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]); + + l2c(n2, out); + l2c(n1, out); +} + +static void +Gost2814789_mac(const unsigned char *in, unsigned char *mac, + GOST2814789_KEY *key) +{ + unsigned int n1, n2; /* As named in the GOST */ + unsigned char *p; + int i; + + for (i = 0; i < 8; i++) + mac[i] ^= in[i]; + + p = mac; + c2l(p, n1); + c2l(p, n2); + + /* Instead of swapping halves, swap names each round */ + n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]); + n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]); + n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]); + n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]); + + n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]); + n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]); + n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]); + n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]); + + p = mac; + l2c(n1, p); + l2c(n2, p); +} + +void +Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out, + GOST2814789_KEY *key, const int enc) +{ + if (key->key_meshing && key->count == 1024) { + Gost2814789_cryptopro_key_mesh(key); + key->count = 0; + } + + if (enc) + Gost2814789_encrypt(in, out, key); + else + Gost2814789_decrypt(in, out, key); +} +LCRYPTO_ALIAS(Gost2814789_ecb_encrypt); + +static inline void +Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key) +{ + if (key->key_meshing && key->count == 1024) { + Gost2814789_cryptopro_key_mesh(key); + Gost2814789_encrypt(iv, iv, key); + key->count = 0; + } + Gost2814789_encrypt(iv, iv, key); + key->count += 8; +} + +static inline void +Gost2814789_mac_mesh(const unsigned char *data, unsigned char *mac, + GOST2814789_KEY *key) +{ + if (key->key_meshing && key->count == 1024) { + Gost2814789_cryptopro_key_mesh(key); + key->count = 0; + } + Gost2814789_mac(data, mac, key); + key->count += 8; +} + +void +Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out, + size_t len, GOST2814789_KEY *key, unsigned char *ivec, int *num, + const int enc) +{ + unsigned int n; + size_t l = 0; + + n = *num; + + if (enc) { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (8 % sizeof(size_t) == 0) do { /* always true actually */ + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 8; + } +#ifdef __STRICT_ALIGNMENT + if (((size_t)in | (size_t)out | (size_t)ivec) % + sizeof(size_t) != 0) + break; +#endif + while (len >= 8) { + Gost2814789_encrypt_mesh(ivec, key); + for (; n < 8; n += sizeof(size_t)) { + *(size_t*)(out + n) = + *(size_t*)(ivec + n) ^= + *(size_t*)(in + n); + } + len -= 8; + out += 8; + in += 8; + n = 0; + } + if (len) { + Gost2814789_encrypt_mesh(ivec, key); + while (len--) { + out[n] = ivec[n] ^= in[n]; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l= 8) { + Gost2814789_encrypt_mesh(ivec, key); + for (; n < 8; n += sizeof(size_t)) { + size_t t = *(size_t*)(in + n); + *(size_t*)(out + n) = + *(size_t*)(ivec + n) ^ t; + *(size_t*)(ivec + n) = t; + } + len -= 8; + out += 8; + in += 8; + n = 0; + } + if (len) { + Gost2814789_encrypt_mesh(ivec, key); + while (len--) { + unsigned char c; + + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + unsigned char c; + + if (n == 0) { + Gost2814789_encrypt_mesh(ivec, key); + } + out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c; + ++l; + n = (n + 1) % 8; + } + *num = n; + } +} +LCRYPTO_ALIAS(Gost2814789_cfb64_encrypt); + +static inline void +Gost2814789_cnt_next(unsigned char *ivec, unsigned char *out, + GOST2814789_KEY *key) +{ + unsigned char *p = ivec, *p2 = ivec; + unsigned int val, val2; + + if (key->count == 0) + Gost2814789_encrypt(ivec, ivec, key); + + if (key->key_meshing && key->count == 1024) { + Gost2814789_cryptopro_key_mesh(key); + Gost2814789_encrypt(ivec, ivec, key); + key->count = 0; + } + + c2l(p, val); + val2 = val + 0x01010101; + l2c(val2, p2); + + c2l(p, val); + val2 = val + 0x01010104; + if (val > val2) /* overflow */ + val2++; + l2c(val2, p2); + + Gost2814789_encrypt(ivec, out, key); + key->count += 8; +} + +void +Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, size_t len, + GOST2814789_KEY *key, unsigned char *ivec, unsigned char *cnt_buf, int *num) +{ + unsigned int n; + size_t l = 0; + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (8 % sizeof(size_t) == 0) do { /* always true actually */ + while (n && len) { + *(out++) = *(in++) ^ cnt_buf[n]; + --len; + n = (n + 1) % 8; + } + +#ifdef __STRICT_ALIGNMENT + if (((size_t)in | (size_t)out | (size_t)ivec) % + sizeof(size_t) != 0) + break; +#endif + while (len >= 8) { + Gost2814789_cnt_next(ivec, cnt_buf, key); + for (; n < 8; n += sizeof(size_t)) + *(size_t *)(out + n) = *(size_t *)(in + n) ^ + *(size_t *)(cnt_buf + n); + len -= 8; + out += 8; + in += 8; + n = 0; + } + if (len) { + Gost2814789_cnt_next(ivec, cnt_buf, key); + while (len--) { + out[n] = in[n] ^ cnt_buf[n]; + ++n; + } + } + *num = n; + return; + } while(0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n==0) + Gost2814789_cnt_next(ivec, cnt_buf, key); + out[l] = in[l] ^ cnt_buf[n]; + ++l; + n = (n + 1) % 8; + } + + *num=n; +} +LCRYPTO_ALIAS(Gost2814789_cnt_encrypt); + +int +GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid) +{ + c->Nl = c->Nh = c->num = 0; + memset(c->mac, 0, 8); + return Gost2814789_set_sbox(&c->cipher, nid); +} +LCRYPTO_ALIAS(GOST2814789IMIT_Init); + +static void +GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx, + const unsigned char *p, size_t num) +{ + int i; + + for (i = 0; i < num; i++) { + Gost2814789_mac_mesh(p, ctx->mac, &ctx->cipher); + p += 8; + } +} + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CBLOCK GOST2814789IMIT_CBLOCK +#define HASH_LONG GOST2814789IMIT_LONG +#define HASH_CTX GOST2814789IMIT_CTX +#define HASH_UPDATE GOST2814789IMIT_Update +#define HASH_TRANSFORM GOST2814789IMIT_Transform +#define HASH_NO_FINAL 1 +#define HASH_BLOCK_DATA_ORDER GOST2814789IMIT_block_data_order + +#include "md32_common.h" +LCRYPTO_ALIAS(GOST2814789IMIT_Update); +LCRYPTO_ALIAS(GOST2814789IMIT_Transform); + +int +GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c) +{ + if (c->num) { + memset(c->data + c->num, 0, 8 - c->num); + Gost2814789_mac_mesh(c->data, c->mac, &c->cipher); + } + if (c->Nl <= 8 * 8 && c->Nl > 0 && c->Nh == 0) { + memset(c->data, 0, 8); + Gost2814789_mac_mesh(c->data, c->mac, &c->cipher); + } + memcpy(md, c->mac, 4); + return 1; +} +LCRYPTO_ALIAS(GOST2814789IMIT_Final); + +unsigned char * +GOST2814789IMIT(const unsigned char *d, size_t n, unsigned char *md, int nid, + const unsigned char *key, const unsigned char *iv) +{ + GOST2814789IMIT_CTX c; + static unsigned char m[GOST2814789IMIT_LENGTH]; + + if (md == NULL) + md = m; + GOST2814789IMIT_Init(&c, nid); + memcpy(c.mac, iv, 8); + Gost2814789_set_key(&c.cipher, key, 256); + GOST2814789IMIT_Update(&c, d, n); + GOST2814789IMIT_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} +LCRYPTO_ALIAS(GOST2814789IMIT); + +#endif diff --git a/Libraries/libressl/crypto/gost/gost89_keywrap.c b/Libraries/libressl/crypto/gost/gost89_keywrap.c new file mode 100644 index 000000000..9bfc5b4ce --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost89_keywrap.c @@ -0,0 +1,138 @@ +/* $OpenBSD: gost89_keywrap.c,v 1.4 2022/11/26 16:08:53 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST + +#include + +#include "gost_local.h" + +static void +key_diversify_crypto_pro(GOST2814789_KEY *ctx, const unsigned char *inputKey, + const unsigned char *ukm, unsigned char *outputKey) +{ + unsigned long k, s1, s2; + int i, mask; + unsigned char S[8]; + unsigned char *p; + + memcpy(outputKey, inputKey, 32); + for (i = 0; i < 8; i++) { + /* Make array of integers from key */ + /* Compute IV S */ + s1 = 0, s2 = 0; + p = outputKey; + for (mask = 1; mask < 256; mask <<= 1) { + c2l(p, k); + if (mask & ukm[i]) { + s1 += k; + } else { + s2 += k; + } + } + p = S; + l2c (s1, p); + l2c (s2, p); + Gost2814789_set_key(ctx, outputKey, 256); + mask = 0; + Gost2814789_cfb64_encrypt(outputKey, outputKey, 32, ctx, S, + &mask, 1); + } +} + +int +gost_key_wrap_crypto_pro(int nid, const unsigned char *keyExchangeKey, + const unsigned char *ukm, const unsigned char *sessionKey, + unsigned char *wrappedKey) +{ + GOST2814789_KEY ctx; + unsigned char kek_ukm[32]; + + Gost2814789_set_sbox(&ctx, nid); + key_diversify_crypto_pro(&ctx, keyExchangeKey, ukm, kek_ukm); + Gost2814789_set_key(&ctx, kek_ukm, 256); + memcpy(wrappedKey, ukm, 8); + Gost2814789_encrypt(sessionKey + 0, wrappedKey + 8 + 0, &ctx); + Gost2814789_encrypt(sessionKey + 8, wrappedKey + 8 + 8, &ctx); + Gost2814789_encrypt(sessionKey + 16, wrappedKey + 8 + 16, &ctx); + Gost2814789_encrypt(sessionKey + 24, wrappedKey + 8 + 24, &ctx); + GOST2814789IMIT(sessionKey, 32, wrappedKey + 40, nid, kek_ukm, ukm); + return 1; +} + +int +gost_key_unwrap_crypto_pro(int nid, const unsigned char *keyExchangeKey, + const unsigned char *wrappedKey, unsigned char *sessionKey) +{ + unsigned char kek_ukm[32], cek_mac[4]; + GOST2814789_KEY ctx; + + Gost2814789_set_sbox(&ctx, nid); + /* First 8 bytes of wrapped Key is ukm */ + key_diversify_crypto_pro(&ctx, keyExchangeKey, wrappedKey, kek_ukm); + Gost2814789_set_key(&ctx, kek_ukm, 256); + Gost2814789_decrypt(wrappedKey + 8 + 0, sessionKey + 0, &ctx); + Gost2814789_decrypt(wrappedKey + 8 + 8, sessionKey + 8, &ctx); + Gost2814789_decrypt(wrappedKey + 8 + 16, sessionKey + 16, &ctx); + Gost2814789_decrypt(wrappedKey + 8 + 24, sessionKey + 24, &ctx); + + GOST2814789IMIT(sessionKey, 32, cek_mac, nid, kek_ukm, wrappedKey); + if (memcmp(cek_mac, wrappedKey + 40, 4)) + return 0; + + return 1; +} + +#endif diff --git a/Libraries/libressl/crypto/gost/gost89_params.c b/Libraries/libressl/crypto/gost/gost89_params.c new file mode 100644 index 000000000..ef9c9cde6 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost89_params.c @@ -0,0 +1,246 @@ +/* $OpenBSD: gost89_params.c,v 1.4 2023/07/08 14:30:44 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include + +#include "gost_local.h" + +/* Substitution blocks from test examples for GOST R 34.11-94*/ +static const gost_subst_block GostR3411_94_TestParamSet = { + {0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}, + {0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC}, + {0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE}, + {0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2}, + {0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3}, + {0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB}, + {0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9}, + {0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3} +}; + +/* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */ +static const gost_subst_block GostR3411_94_CryptoProParamSet = { + {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC}, + {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB}, + {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3}, + {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5}, + {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3}, + {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD}, + {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8}, + {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF} +}; + +/* Test paramset from GOST 28147 */ +gost_subst_block Gost28147_TestParamSet = { + {0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8}, + {0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD}, + {0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4}, + {0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4}, + {0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8}, + {0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB}, + {0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5}, + {0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6} +}; + + +/* 1.2.643.2.2.31.1 */ +static const gost_subst_block Gost28147_CryptoProParamSetA = { + {0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4}, + {0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE}, + {0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6}, + {0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6}, + {0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6}, + {0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9}, + {0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1}, + {0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5} +}; + +/* 1.2.643.2.2.31.2 */ +static const gost_subst_block Gost28147_CryptoProParamSetB = { + {0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC}, + {0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE}, + {0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5}, + {0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3}, + {0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8}, + {0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4}, + {0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE}, + {0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF} +}; + +/* 1.2.643.2.2.31.3 */ +static const gost_subst_block Gost28147_CryptoProParamSetC = { + {0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8}, + {0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7}, + {0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD}, + {0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7}, + {0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4}, + {0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB}, + {0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3}, + {0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3} +}; + +/* 1.2.643.2.2.31.4 */ +static const gost_subst_block Gost28147_CryptoProParamSetD = { + {0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE}, + {0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7}, + {0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6}, + {0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1}, + {0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8}, + {0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2}, + {0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1}, + {0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3} +}; + +static const gost_subst_block Gost28147_TC26ParamSetZ = { + {0x1,0x7,0xe,0xd,0x0,0x5,0x8,0x3,0x4,0xf,0xa,0x6,0x9,0xc,0xb,0x2}, + {0x8,0xe,0x2,0x5,0x6,0x9,0x1,0xc,0xf,0x4,0xb,0x0,0xd,0xa,0x3,0x7}, + {0x5,0xd,0xf,0x6,0x9,0x2,0xc,0xa,0xb,0x7,0x8,0x1,0x4,0x3,0xe,0x0}, + {0x7,0xf,0x5,0xa,0x8,0x1,0x6,0xd,0x0,0x9,0x3,0xe,0xb,0x4,0x2,0xc}, + {0xc,0x8,0x2,0x1,0xd,0x4,0xf,0x6,0x7,0x0,0xa,0x5,0x3,0xe,0x9,0xb}, + {0xb,0x3,0x5,0x8,0x2,0xf,0xa,0xd,0xe,0x1,0x7,0x4,0xc,0x9,0x6,0x0}, + {0x6,0x8,0x2,0x3,0x9,0xa,0x5,0xc,0x1,0xe,0x4,0x7,0xb,0xd,0x0,0xf}, + {0xc,0x4,0x6,0x2,0xa,0x5,0xb,0x9,0xe,0x8,0xd,0x7,0x0,0x3,0xf,0x1} +}; + +static const unsigned char CryptoProKeyMeshingKey[] = { + 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23, + 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4, + 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12, + 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B +}; + +static const struct gost89_parameters_info { + int nid; + const gost_subst_block *sblock; + int key_meshing; +} gost_cipher_list[] = +{ + {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1}, + {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1}, + {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1}, + {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1}, + {NID_id_tc26_gost_28147_param_Z,&Gost28147_TC26ParamSetZ,1}, + {NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,0}, + {NID_id_GostR3411_94_TestParamSet,&GostR3411_94_TestParamSet,0}, + {NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0}, + {NID_undef,NULL,0} +}; + +int +Gost2814789_set_sbox(GOST2814789_KEY *key, int nid) +{ + int i; + const gost_subst_block *b = NULL; + unsigned int t; + + for (i = 0; gost_cipher_list[i].nid != NID_undef; i++) { + if (gost_cipher_list[i].nid != nid) + continue; + + b = gost_cipher_list[i].sblock; + key->key_meshing = gost_cipher_list[i].key_meshing; + break; + } + + if (b == NULL) + return 0; + + for (i = 0; i < 256; i++) { + t = (unsigned int)(b->k8[i >> 4] <<4 | b->k7 [i & 15]) << 24; + key->k87[i] = (t << 11) | (t >> 21); + t = (unsigned int)(b->k6[i >> 4] <<4 | b->k5 [i & 15]) << 16; + key->k65[i] = (t << 11) | (t >> 21); + t = (unsigned int)(b->k4[i >> 4] <<4 | b->k3 [i & 15]) << 8; + key->k43[i] = (t << 11) | (t >> 21); + t = (unsigned int)(b->k2[i >> 4] <<4 | b->k1 [i & 15]) << 0; + key->k21[i] = (t << 11) | (t >> 21); + } + + return 1; +} +LCRYPTO_ALIAS(Gost2814789_set_sbox); + +int +Gost2814789_set_key(GOST2814789_KEY *key, const unsigned char *userKey, + const int bits) +{ + int i; + + if (bits != 256) + return 0; + + for (i = 0; i < 8; i++) + c2l(userKey, key->key[i]); + + key->count = 0; + + return 1; +} +LCRYPTO_ALIAS(Gost2814789_set_key); + +void +Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key) +{ + unsigned char newkey[32]; + + Gost2814789_decrypt(CryptoProKeyMeshingKey + 0, newkey + 0, key); + Gost2814789_decrypt(CryptoProKeyMeshingKey + 8, newkey + 8, key); + Gost2814789_decrypt(CryptoProKeyMeshingKey + 16, newkey + 16, key); + Gost2814789_decrypt(CryptoProKeyMeshingKey + 24, newkey + 24, key); + + Gost2814789_set_key(key, newkey, 256); +} +#endif diff --git a/Libraries/libressl/crypto/gost/gost89imit_ameth.c b/Libraries/libressl/crypto/gost/gost89imit_ameth.c new file mode 100644 index 000000000..e300b5280 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost89imit_ameth.c @@ -0,0 +1,89 @@ +/* $OpenBSD: gost89imit_ameth.c,v 1.4 2022/11/26 16:08:53 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#ifndef OPENSSL_NO_GOST +#include + +#include "asn1_local.h" +#include "evp_local.h" + +static void +mackey_free_gost(EVP_PKEY *pk) +{ + free(pk->pkey.ptr); +} + +static int +mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_id_Gost28147_89_MAC; + return 2; + } + return -2; +} + +const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth = { + .pkey_id = EVP_PKEY_GOSTIMIT, + .pkey_base_id = EVP_PKEY_GOSTIMIT, + .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, + + .pem_str = "GOST-MAC", + .info = "GOST 28147-89 MAC", + + .pkey_free = mackey_free_gost, + .pkey_ctrl = mac_ctrl_gost, +}; + +#endif diff --git a/Libraries/libressl/crypto/gost/gost89imit_pmeth.c b/Libraries/libressl/crypto/gost/gost89imit_pmeth.c new file mode 100644 index 000000000..63b7ef59e --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost89imit_pmeth.c @@ -0,0 +1,248 @@ +/* $OpenBSD: gost89imit_pmeth.c,v 1.5 2022/11/26 16:08:53 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include +#include /* For string_to_hex */ + +#include "evp_local.h" +#include "gost_local.h" + +struct gost_mac_pmeth_data { + EVP_MD *md; + unsigned char key[32]; + unsigned key_set :1; +}; + +static int +pkey_gost_mac_init(EVP_PKEY_CTX *ctx) +{ + struct gost_mac_pmeth_data *data; + + data = calloc(1, sizeof(struct gost_mac_pmeth_data)); + if (data == NULL) + return 0; + EVP_PKEY_CTX_set_data(ctx, data); + return 1; +} + +static void +pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + free(data); +} + +static int +pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + struct gost_mac_pmeth_data *dst_data, *src_data; + + if (pkey_gost_mac_init(dst) == 0) + return 0; + + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + + *dst_data = *src_data; + + return 1; +} + +static int +pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + unsigned char *keydata; + + if (!data->key_set) { + GOSTerror(GOST_R_MAC_KEY_NOT_SET); + return 0; + } + + keydata = malloc(32); + if (keydata == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(keydata, data->key, 32); + EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); + + return 1; +} + +static int +pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + + switch (type) { + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { + GOSTerror(GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + data->md = p2; + return 1; + + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (p1 != 32) { + GOSTerror(GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + memcpy(data->key, p2, 32); + data->key_set = 1; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + { + EVP_MD_CTX *mctx = p2; + void *key; + + if (!data->key_set) { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (pkey == NULL) { + GOSTerror(GOST_R_MAC_KEY_NOT_SET); + return 0; + } + key = EVP_PKEY_get0(pkey); + if (key == NULL) { + GOSTerror(GOST_R_MAC_KEY_NOT_SET); + return 0; + } + } else { + key = &(data->key); + } + if (mctx->digest->md_ctrl == NULL) + return 0; + return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32 * 8, + key); + } + + } + + return -2; +} + +static int +pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + if (value == NULL) + return 0; + if (strcmp(type, "key") == 0) { + void *p = (void *)value; + return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + strlen(value), p); + } + if (strcmp(type, "hexkey") == 0) { + unsigned char *key; + int r; + long keylen; + + key = string_to_hex(value, &keylen); + if (key == NULL) + return 0; + r = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, + key); + free(key); + return r; + } + return -2; +} + +static int +pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + return 1; +} + +static int +pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + /* for platforms where sizeof(int) != sizeof(size_t)*/ + unsigned int tmpsiglen = *siglen; + int ret; + + if (sig == NULL) { + *siglen = 4; + return 1; + } + + ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen); + *siglen = tmpsiglen; + return ret; +} + +const EVP_PKEY_METHOD gostimit_pkey_meth = { + .pkey_id = EVP_PKEY_GOSTIMIT, + + .init = pkey_gost_mac_init, + .cleanup = pkey_gost_mac_cleanup, + .copy = pkey_gost_mac_copy, + + .keygen = pkey_gost_mac_keygen, + + .signctx_init = pkey_gost_mac_signctx_init, + .signctx = pkey_gost_mac_signctx, + + .ctrl = pkey_gost_mac_ctrl, + .ctrl_str = pkey_gost_mac_ctrl_str, +}; + +#endif diff --git a/Libraries/libressl/crypto/gost/gost_asn1.c b/Libraries/libressl/crypto/gost/gost_asn1.c new file mode 100644 index 000000000..28e3a58e5 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost_asn1.c @@ -0,0 +1,299 @@ +/********************************************************************** + * gost_keytrans.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * ASN1 structure definition for GOST key transport * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include + +#include "gost_local.h" +#include "gost_asn1.h" + +static const ASN1_TEMPLATE GOST_KEY_TRANSPORT_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_TRANSPORT, key_info), + .field_name = "key_info", + .item = &GOST_KEY_INFO_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(GOST_KEY_TRANSPORT, key_agreement_info), + .field_name = "key_agreement_info", + .item = &GOST_KEY_AGREEMENT_INFO_it, + }, +}; + +const ASN1_ITEM GOST_KEY_TRANSPORT_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GOST_KEY_TRANSPORT_seq_tt, + .tcount = sizeof(GOST_KEY_TRANSPORT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GOST_KEY_TRANSPORT), + .sname = "GOST_KEY_TRANSPORT", +}; + +GOST_KEY_TRANSPORT * +d2i_GOST_KEY_TRANSPORT(GOST_KEY_TRANSPORT **a, const unsigned char **in, long len) +{ + return (GOST_KEY_TRANSPORT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GOST_KEY_TRANSPORT_it); +} + +int +i2d_GOST_KEY_TRANSPORT(GOST_KEY_TRANSPORT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_TRANSPORT_it); +} + +GOST_KEY_TRANSPORT * +GOST_KEY_TRANSPORT_new(void) +{ + return (GOST_KEY_TRANSPORT *)ASN1_item_new(&GOST_KEY_TRANSPORT_it); +} + +void +GOST_KEY_TRANSPORT_free(GOST_KEY_TRANSPORT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_TRANSPORT_it); +} + +static const ASN1_TEMPLATE GOST_KEY_INFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_INFO, encrypted_key), + .field_name = "encrypted_key", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_INFO, imit), + .field_name = "imit", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM GOST_KEY_INFO_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GOST_KEY_INFO_seq_tt, + .tcount = sizeof(GOST_KEY_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GOST_KEY_INFO), + .sname = "GOST_KEY_INFO", +}; + +GOST_KEY_INFO * +d2i_GOST_KEY_INFO(GOST_KEY_INFO **a, const unsigned char **in, long len) +{ + return (GOST_KEY_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GOST_KEY_INFO_it); +} + +int +i2d_GOST_KEY_INFO(GOST_KEY_INFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_INFO_it); +} + +GOST_KEY_INFO * +GOST_KEY_INFO_new(void) +{ + return (GOST_KEY_INFO *)ASN1_item_new(&GOST_KEY_INFO_it); +} + +void +GOST_KEY_INFO_free(GOST_KEY_INFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_INFO_it); +} + +static const ASN1_TEMPLATE GOST_KEY_AGREEMENT_INFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_AGREEMENT_INFO, cipher), + .field_name = "cipher", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(GOST_KEY_AGREEMENT_INFO, ephem_key), + .field_name = "ephem_key", + .item = &X509_PUBKEY_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_AGREEMENT_INFO, eph_iv), + .field_name = "eph_iv", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM GOST_KEY_AGREEMENT_INFO_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GOST_KEY_AGREEMENT_INFO_seq_tt, + .tcount = sizeof(GOST_KEY_AGREEMENT_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GOST_KEY_AGREEMENT_INFO), + .sname = "GOST_KEY_AGREEMENT_INFO", +}; + +GOST_KEY_AGREEMENT_INFO * +d2i_GOST_KEY_AGREEMENT_INFO(GOST_KEY_AGREEMENT_INFO **a, const unsigned char **in, long len) +{ + return (GOST_KEY_AGREEMENT_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GOST_KEY_AGREEMENT_INFO_it); +} + +int +i2d_GOST_KEY_AGREEMENT_INFO(GOST_KEY_AGREEMENT_INFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_AGREEMENT_INFO_it); +} + +GOST_KEY_AGREEMENT_INFO * +GOST_KEY_AGREEMENT_INFO_new(void) +{ + return (GOST_KEY_AGREEMENT_INFO *)ASN1_item_new(&GOST_KEY_AGREEMENT_INFO_it); +} + +void +GOST_KEY_AGREEMENT_INFO_free(GOST_KEY_AGREEMENT_INFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_AGREEMENT_INFO_it); +} + + +static const ASN1_TEMPLATE GOST_KEY_PARAMS_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_PARAMS, key_params), + .field_name = "key_params", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_KEY_PARAMS, hash_params), + .field_name = "hash_params", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(GOST_KEY_PARAMS, cipher_params), + .field_name = "cipher_params", + .item = &ASN1_OBJECT_it, + }, +}; + +const ASN1_ITEM GOST_KEY_PARAMS_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GOST_KEY_PARAMS_seq_tt, + .tcount = sizeof(GOST_KEY_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GOST_KEY_PARAMS), + .sname = "GOST_KEY_PARAMS", +}; + +GOST_KEY_PARAMS * +d2i_GOST_KEY_PARAMS(GOST_KEY_PARAMS **a, const unsigned char **in, long len) +{ + return (GOST_KEY_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GOST_KEY_PARAMS_it); +} + +int +i2d_GOST_KEY_PARAMS(GOST_KEY_PARAMS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_PARAMS_it); +} + +GOST_KEY_PARAMS * +GOST_KEY_PARAMS_new(void) +{ + return (GOST_KEY_PARAMS *)ASN1_item_new(&GOST_KEY_PARAMS_it); +} + +void +GOST_KEY_PARAMS_free(GOST_KEY_PARAMS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_PARAMS_it); +} + +static const ASN1_TEMPLATE GOST_CIPHER_PARAMS_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_CIPHER_PARAMS, iv), + .field_name = "iv", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(GOST_CIPHER_PARAMS, enc_param_set), + .field_name = "enc_param_set", + .item = &ASN1_OBJECT_it, + }, +}; + +const ASN1_ITEM GOST_CIPHER_PARAMS_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GOST_CIPHER_PARAMS_seq_tt, + .tcount = sizeof(GOST_CIPHER_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GOST_CIPHER_PARAMS), + .sname = "GOST_CIPHER_PARAMS", +}; + +GOST_CIPHER_PARAMS * +d2i_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS **a, const unsigned char **in, long len) +{ + return (GOST_CIPHER_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GOST_CIPHER_PARAMS_it); +} +LCRYPTO_ALIAS(d2i_GOST_CIPHER_PARAMS); + +int +i2d_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_CIPHER_PARAMS_it); +} +LCRYPTO_ALIAS(i2d_GOST_CIPHER_PARAMS); + +GOST_CIPHER_PARAMS * +GOST_CIPHER_PARAMS_new(void) +{ + return (GOST_CIPHER_PARAMS *)ASN1_item_new(&GOST_CIPHER_PARAMS_it); +} +LCRYPTO_ALIAS(GOST_CIPHER_PARAMS_new); + +void +GOST_CIPHER_PARAMS_free(GOST_CIPHER_PARAMS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GOST_CIPHER_PARAMS_it); +} +LCRYPTO_ALIAS(GOST_CIPHER_PARAMS_free); + +#endif diff --git a/Libraries/libressl/crypto/gost/gost_asn1.h b/Libraries/libressl/crypto/gost/gost_asn1.h new file mode 100644 index 000000000..7cabfc79c --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost_asn1.h @@ -0,0 +1,107 @@ +/* $OpenBSD: gost_asn1.h,v 1.3 2016/12/21 15:49:29 jsing Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_GOST_ASN1_H +#define HEADER_GOST_ASN1_H + +#include + +__BEGIN_HIDDEN_DECLS + +typedef struct { + ASN1_OCTET_STRING *encrypted_key; + ASN1_OCTET_STRING *imit; +} GOST_KEY_INFO; + +GOST_KEY_INFO *GOST_KEY_INFO_new(void); +void GOST_KEY_INFO_free(GOST_KEY_INFO *a); +GOST_KEY_INFO *d2i_GOST_KEY_INFO(GOST_KEY_INFO **a, const unsigned char **in, long len); +int i2d_GOST_KEY_INFO(GOST_KEY_INFO *a, unsigned char **out); +extern const ASN1_ITEM GOST_KEY_INFO_it; + +typedef struct { + ASN1_OBJECT *cipher; + X509_PUBKEY *ephem_key; + ASN1_OCTET_STRING *eph_iv; +} GOST_KEY_AGREEMENT_INFO; + +GOST_KEY_AGREEMENT_INFO *GOST_KEY_AGREEMENT_INFO_new(void); +void GOST_KEY_AGREEMENT_INFO_free(GOST_KEY_AGREEMENT_INFO *a); +GOST_KEY_AGREEMENT_INFO *d2i_GOST_KEY_AGREEMENT_INFO(GOST_KEY_AGREEMENT_INFO **a, const unsigned char **in, long len); +int i2d_GOST_KEY_AGREEMENT_INFO(GOST_KEY_AGREEMENT_INFO *a, unsigned char **out); +extern const ASN1_ITEM GOST_KEY_AGREEMENT_INFO_it; + +typedef struct { + GOST_KEY_INFO *key_info; + GOST_KEY_AGREEMENT_INFO *key_agreement_info; +} GOST_KEY_TRANSPORT; + +GOST_KEY_TRANSPORT *GOST_KEY_TRANSPORT_new(void); +void GOST_KEY_TRANSPORT_free(GOST_KEY_TRANSPORT *a); +GOST_KEY_TRANSPORT *d2i_GOST_KEY_TRANSPORT(GOST_KEY_TRANSPORT **a, const unsigned char **in, long len); +int i2d_GOST_KEY_TRANSPORT(GOST_KEY_TRANSPORT *a, unsigned char **out); +extern const ASN1_ITEM GOST_KEY_TRANSPORT_it; + +typedef struct { + ASN1_OBJECT *key_params; + ASN1_OBJECT *hash_params; + ASN1_OBJECT *cipher_params; +} GOST_KEY_PARAMS; + +GOST_KEY_PARAMS *GOST_KEY_PARAMS_new(void); +void GOST_KEY_PARAMS_free(GOST_KEY_PARAMS *a); +GOST_KEY_PARAMS *d2i_GOST_KEY_PARAMS(GOST_KEY_PARAMS **a, const unsigned char **in, long len); +int i2d_GOST_KEY_PARAMS(GOST_KEY_PARAMS *a, unsigned char **out); +extern const ASN1_ITEM GOST_KEY_PARAMS_it; + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/crypto/gost/gost_err.c b/Libraries/libressl/crypto/gost/gost_err.c new file mode 100644 index 000000000..380f60289 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost_err.c @@ -0,0 +1,106 @@ +/* crypto/gost/gost_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_GOST,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_GOST,0,reason) + +static ERR_STRING_DATA GOST_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA GOST_str_reasons[] = { + {ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"}, + {ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"}, + {ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"}, + {ERR_REASON(GOST_R_CTRL_CALL_FAILED) ,"ctrl call failed"}, + {ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"}, + {ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"}, + {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"}, + {ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"}, + {ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, + {ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"}, + {ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"}, + {ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"}, + {ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"}, + {ERR_REASON(GOST_R_MAC_KEY_NOT_SET) ,"mac key not set"}, + {ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"}, + {ERR_REASON(GOST_R_NO_PEER_KEY) ,"no peer key"}, + {ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"}, + {ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"}, + {ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"}, + {ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"}, + {ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"}, + {ERR_REASON(GOST_R_UKM_NOT_SET) ,"ukm not set"}, + {0, NULL} +}; +#endif + +void +ERR_load_GOST_strings(void) { +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(GOST_str_functs[0].error) == NULL) { + ERR_load_strings(0,GOST_str_functs); + ERR_load_strings(0,GOST_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_GOST_strings); diff --git a/Libraries/libressl/crypto/gost/gost_local.h b/Libraries/libressl/crypto/gost/gost_local.h new file mode 100644 index 000000000..db07d06f0 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gost_local.h @@ -0,0 +1,116 @@ +/* $OpenBSD: gost_local.h,v 1.3 2023/07/28 15:50:33 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_GOST_LOCAL_H +#define HEADER_GOST_LOCAL_H + +#include + +__BEGIN_HIDDEN_DECLS + +/* Internal representation of GOST substitution blocks */ +typedef struct { + unsigned char k8[16]; + unsigned char k7[16]; + unsigned char k6[16]; + unsigned char k5[16]; + unsigned char k4[16]; + unsigned char k3[16]; + unsigned char k2[16]; + unsigned char k1[16]; +} gost_subst_block; + +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4) +# define l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4) +#else +#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) +#endif + +extern void Gost2814789_encrypt(const unsigned char *in, unsigned char *out, + const GOST2814789_KEY *key); +extern void Gost2814789_decrypt(const unsigned char *in, unsigned char *out, + const GOST2814789_KEY *key); +extern void Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key); + +/* GOST 28147-89 key wrapping */ +extern int gost_key_unwrap_crypto_pro(int nid, + const unsigned char *keyExchangeKey, const unsigned char *wrappedKey, + unsigned char *sessionKey); +extern int gost_key_wrap_crypto_pro(int nid, + const unsigned char *keyExchangeKey, const unsigned char *ukm, + const unsigned char *sessionKey, unsigned char *wrappedKey); +/* Pkey part */ +extern int gost2001_compute_public(GOST_KEY *ec); +extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); +extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); +extern int gost2001_keygen(GOST_KEY *ec); +extern int VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, + GOST_KEY *priv_key, const BIGNUM *ukm); +extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); +extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); + +/* GOST R 34.10 parameters */ +extern int GostR3410_get_md_digest(int nid); +extern int GostR3410_get_pk_digest(int nid); +extern int GostR3410_256_param_id(const char *value); +extern int GostR3410_512_param_id(const char *value); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_GOST_LOCAL_H */ diff --git a/Libraries/libressl/crypto/gost/gostr341001.c b/Libraries/libressl/crypto/gost/gostr341001.c new file mode 100644 index 000000000..1c34626a4 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gostr341001.c @@ -0,0 +1,403 @@ +/* $OpenBSD: gostr341001.c,v 1.12 2023/07/05 11:37:45 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include + +#include "bn_local.h" +#include "ecdsa_local.h" +#include "gost_local.h" + +/* Convert little-endian byte array into bignum */ +BIGNUM * +GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn) +{ + unsigned char temp[64]; + int i; + + if (len > 64) + return NULL; + + for (i = 0; i < len; i++) { + temp[len - 1 - i] = buf[i]; + } + + return BN_bin2bn(temp, len, bn); +} + +int +GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len) +{ + unsigned char temp[64]; + int i, bytes; + + bytes = BN_num_bytes(bn); + if (len > 64 || bytes > len) + return 0; + + BN_bn2bin(bn, temp); + + for (i = 0; i < bytes; i++) { + buf[bytes - 1 - i] = temp[i]; + } + + memset(buf + bytes, 0, len - bytes); + + return 1; +} + +int +gost2001_compute_public(GOST_KEY *ec) +{ + const EC_GROUP *group = GOST_KEY_get0_group(ec); + EC_POINT *pub_key = NULL; + const BIGNUM *priv_key = NULL; + BN_CTX *ctx = NULL; + int ok = 0; + + if (group == NULL) { + GOSTerror(GOST_R_KEY_IS_NOT_INITIALIZED); + return 0; + } + ctx = BN_CTX_new(); + if (ctx == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(ctx); + if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL) + goto err; + + pub_key = EC_POINT_new(group); + if (pub_key == NULL) + goto err; + if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0) + goto err; + if (GOST_KEY_set_public_key(ec, pub_key) == 0) + goto err; + ok = 1; + + if (ok == 0) { +err: + GOSTerror(ERR_R_EC_LIB); + } + EC_POINT_free(pub_key); + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +ECDSA_SIG * +gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey) +{ + ECDSA_SIG *newsig = NULL; + BIGNUM *order = NULL; + const EC_GROUP *group; + const BIGNUM *priv_key; + BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, *k = + NULL, *e = NULL; + EC_POINT *C = NULL; + BN_CTX *ctx = BN_CTX_new(); + int ok = 0; + + if (ctx == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + BN_CTX_start(ctx); + newsig = ECDSA_SIG_new(); + if (newsig == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + s = newsig->s; + r = newsig->r; + group = GOST_KEY_get0_group(eckey); + if ((order = BN_CTX_get(ctx)) == NULL) + goto err; + if (EC_GROUP_get_order(group, order, ctx) == 0) + goto err; + priv_key = GOST_KEY_get0_private_key(eckey); + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + if (BN_mod_ct(e, md, order, ctx) == 0) + goto err; + if (BN_is_zero(e)) { + if (!BN_one(e)) + goto err; + } + if ((k = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((C = EC_POINT_new(group)) == NULL) + goto err; + do { + do { + if (!BN_rand_range(k, order)) { + GOSTerror(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + goto err; + } + /* + * We do not want timing information to leak the length + * of k, so we compute G*k using an equivalent scalar + * of fixed bit-length. + */ + if (BN_add(k, k, order) == 0) + goto err; + if (BN_num_bits(k) <= BN_num_bits(order)) + if (BN_add(k, k, order) == 0) + goto err; + + if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_get_affine_coordinates(group, C, X, + NULL, ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (BN_nnmod(r, X, order, ctx) == 0) + goto err; + } while (BN_is_zero(r)); + /* s = (r*priv_key+k*e) mod order */ + if (tmp == NULL) { + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + } + if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0) + goto err; + if (tmp2 == NULL) { + if ((tmp2 = BN_CTX_get(ctx)) == NULL) + goto err; + } + if (BN_mod_mul(tmp2, k, e, order, ctx) == 0) + goto err; + if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0) + goto err; + } while (BN_is_zero(s)); + ok = 1; + +err: + EC_POINT_free(C); + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ok == 0) { + ECDSA_SIG_free(newsig); + newsig = NULL; + } + return newsig; +} + +int +gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec) +{ + BN_CTX *ctx = BN_CTX_new(); + const EC_GROUP *group = GOST_KEY_get0_group(ec); + BIGNUM *order; + BIGNUM *e = NULL, *R = NULL, *v = NULL, *z1 = NULL, *z2 = NULL; + BIGNUM *X = NULL, *tmp = NULL; + EC_POINT *C = NULL; + const EC_POINT *pub_key = NULL; + int ok = 0; + + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + if ((order = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + if ((z1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((z2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((R = BN_CTX_get(ctx)) == NULL) + goto err; + if ((v = BN_CTX_get(ctx)) == NULL) + goto err; + + if (EC_GROUP_get_order(group, order, ctx) == 0) + goto err; + pub_key = GOST_KEY_get0_public_key(ec); + if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || + BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) { + GOSTerror(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + goto err; + } + + if (BN_mod_ct(e, md, order, ctx) == 0) + goto err; + if (BN_is_zero(e)) { + if (!BN_one(e)) + goto err; + } + if ((v = BN_mod_inverse_ct(v, e, order, ctx)) == NULL) + goto err; + if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0) + goto err; + if (BN_sub(tmp, order, sig->r) == 0) + goto err; + if (BN_mod_mul(z2, tmp, v, order, ctx) == 0) + goto err; + if ((C = EC_POINT_new(group)) == NULL) + goto err; + if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_get_affine_coordinates(group, C, X, NULL, ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (BN_mod_ct(R, X, order, ctx) == 0) + goto err; + if (BN_cmp(R, sig->r) != 0) { + GOSTerror(GOST_R_SIGNATURE_MISMATCH); + } else { + ok = 1; + } +err: + EC_POINT_free(C); + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +/* Implementation of CryptoPro VKO 34.10-2001 algorithm */ +int +VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key, + const BIGNUM *ukm) +{ + BIGNUM *p = NULL, *order = NULL; + const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); + const EC_GROUP *group = GOST_KEY_get0_group(priv_key); + const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); + EC_POINT *pnt; + BN_CTX *ctx = NULL; + int ok = 0; + + pnt = EC_POINT_new(group); + if (pnt == NULL) + goto err; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((order = BN_CTX_get(ctx)) == NULL) + goto err; + if (EC_GROUP_get_order(group, order, ctx) == 0) + goto err; + if (BN_mod_mul(p, key, ukm, order, ctx) == 0) + goto err; + if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0) + goto err; + if (EC_POINT_get_affine_coordinates(group, pnt, X, Y, ctx) == 0) + goto err; + ok = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + EC_POINT_free(pnt); + return ok; +} + +int +gost2001_keygen(GOST_KEY *ec) +{ + BIGNUM *order = BN_new(), *d = BN_new(); + const EC_GROUP *group = GOST_KEY_get0_group(ec); + int rc = 0; + + if (order == NULL || d == NULL) + goto err; + if (EC_GROUP_get_order(group, order, NULL) == 0) + goto err; + + do { + if (BN_rand_range(d, order) == 0) { + GOSTerror(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + goto err; + } + } while (BN_is_zero(d)); + + if (GOST_KEY_set_private_key(ec, d) == 0) + goto err; + rc = gost2001_compute_public(ec); + +err: + BN_free(d); + BN_free(order); + return rc; +} +#endif diff --git a/Libraries/libressl/crypto/gost/gostr341001_ameth.c b/Libraries/libressl/crypto/gost/gostr341001_ameth.c new file mode 100644 index 000000000..9ef7cdf46 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gostr341001_ameth.c @@ -0,0 +1,721 @@ +/* $OpenBSD: gostr341001_ameth.c,v 1.20 2022/11/26 16:08:53 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include +#include +#include +#include + + +#include "asn1_local.h" +#include "evp_local.h" +#include "gost_local.h" +#include "gost_asn1.h" + +static void +pkey_free_gost01(EVP_PKEY *key) +{ + GOST_KEY_free(key->pkey.gost); +} + +/* + * Parses GOST algorithm parameters from X509_ALGOR and + * modifies pkey setting NID and parameters + */ +static int +decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len) +{ + int param_nid = NID_undef, digest_nid = NID_undef; + GOST_KEY_PARAMS *gkp = NULL; + EC_GROUP *group; + GOST_KEY *ec; + + gkp = d2i_GOST_KEY_PARAMS(NULL, p, len); + if (gkp == NULL) { + GOSTerror(GOST_R_BAD_PKEY_PARAMETERS_FORMAT); + return 0; + } + param_nid = OBJ_obj2nid(gkp->key_params); + digest_nid = OBJ_obj2nid(gkp->hash_params); + GOST_KEY_PARAMS_free(gkp); + + ec = pkey->pkey.gost; + if (ec == NULL) { + ec = GOST_KEY_new(); + if (ec == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + if (EVP_PKEY_assign_GOST(pkey, ec) == 0) + return 0; + } + + group = EC_GROUP_new_by_curve_name(param_nid); + if (group == NULL) { + GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); + return 0; + } + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (GOST_KEY_set_group(ec, group) == 0) { + EC_GROUP_free(group); + return 0; + } + EC_GROUP_free(group); + if (GOST_KEY_set_digest(ec, digest_nid) == 0) + return 0; + return 1; +} + +static ASN1_STRING * +encode_gost01_algor_params(const EVP_PKEY *key) +{ + ASN1_STRING *params = ASN1_STRING_new(); + GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); + int pkey_param_nid = NID_undef; + + if (params == NULL || gkp == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + + pkey_param_nid = + EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost)); + gkp->key_params = OBJ_nid2obj(pkey_param_nid); + gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost)); + /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */ + params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); + if (params->length <= 0) { + GOSTerror(ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + params->type = V_ASN1_SEQUENCE; +err: + GOST_KEY_PARAMS_free(gkp); + return params; +} + +static int +pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const GOST_KEY *ea = a->pkey.gost; + const GOST_KEY *eb = b->pkey.gost; + const EC_POINT *ka, *kb; + int ret = 0; + + if (ea == NULL || eb == NULL) + return 0; + ka = GOST_KEY_get0_public_key(ea); + kb = GOST_KEY_get0_public_key(eb); + if (ka == NULL || kb == NULL) + return 0; + ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL)); + return ret; +} + +static int +pkey_size_gost01(const EVP_PKEY *pk) +{ + if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) + return 128; + return 64; +} + +static int +pkey_bits_gost01(const EVP_PKEY *pk) +{ + if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) + return 512; + return 256; +} + +static int +pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) +{ + X509_ALGOR *palg = NULL; + const unsigned char *pubkey_buf = NULL; + const unsigned char *p; + ASN1_OBJECT *palgobj = NULL; + int pub_len; + BIGNUM *X, *Y; + ASN1_OCTET_STRING *octet = NULL; + int len; + int ret; + int ptype = V_ASN1_UNDEF; + ASN1_STRING *pval = NULL; + + if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub) + == 0) + return 0; + (void)EVP_PKEY_assign_GOST(pk, NULL); + X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg); + if (ptype != V_ASN1_SEQUENCE) { + GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); + return 0; + } + p = pval->data; + if (decode_gost01_algor_params(pk, &p, pval->length) == 0) { + GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); + return 0; + } + + octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); + if (octet == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + len = octet->length / 2; + + X = GOST_le2bn(octet->data, len, NULL); + Y = GOST_le2bn(octet->data + len, len, NULL); + + ASN1_OCTET_STRING_free(octet); + + ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); + if (ret == 0) + GOSTerror(ERR_R_EC_LIB); + + BN_free(X); + BN_free(Y); + + return ret; +} + +static int +pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) +{ + ASN1_OBJECT *algobj = NULL; + ASN1_OCTET_STRING *octet = NULL; + ASN1_STRING *params = NULL; + void *pval = NULL; + unsigned char *buf = NULL, *sptr; + int key_size, ret = 0; + const EC_POINT *pub_key; + BIGNUM *X = NULL, *Y = NULL; + const GOST_KEY *ec = pk->pkey.gost; + int ptype = V_ASN1_UNDEF; + + algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); + if (pk->save_parameters) { + params = encode_gost01_algor_params(pk); + if (params == NULL) + return 0; + pval = params; + ptype = V_ASN1_SEQUENCE; + } + + key_size = GOST_KEY_get_size(ec); + + pub_key = GOST_KEY_get0_public_key(ec); + if (pub_key == NULL) { + GOSTerror(GOST_R_PUBLIC_KEY_UNDEFINED); + goto err; + } + + octet = ASN1_OCTET_STRING_new(); + if (octet == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + ret = ASN1_STRING_set(octet, NULL, 2 * key_size); + if (ret == 0) { + GOSTerror(ERR_R_INTERNAL_ERROR); + goto err; + } + + sptr = ASN1_STRING_data(octet); + + X = BN_new(); + Y = BN_new(); + if (X == NULL || Y == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EC_POINT_get_affine_coordinates(GOST_KEY_get0_group(ec), + pub_key, X, Y, NULL) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + + GOST_bn2le(X, sptr, key_size); + GOST_bn2le(Y, sptr + key_size, key_size); + + BN_free(Y); + BN_free(X); + + ret = i2d_ASN1_OCTET_STRING(octet, &buf); + ASN1_BIT_STRING_free(octet); + if (ret < 0) + return 0; + + return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); + +err: + BN_free(Y); + BN_free(X); + ASN1_BIT_STRING_free(octet); + ASN1_STRING_free(params); + return 0; +} + +static int +param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) +{ + int param_nid = + EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); + + if (BIO_indent(out, indent, 128) == 0) + return 0; + BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); + if (BIO_indent(out, indent, 128) == 0) + return 0; + BIO_printf(out, "Digest Algorithm: %s\n", + OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); + return 1; +} + +static int +pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) +{ + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *X, *Y; + const EC_POINT *pubkey; + const EC_GROUP *group; + + if (ctx == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(ctx); + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Y = BN_CTX_get(ctx)) == NULL) + goto err; + pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); + group = GOST_KEY_get0_group(pkey->pkey.gost); + if (EC_POINT_get_affine_coordinates(group, pubkey, X, Y, ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (BIO_indent(out, indent, 128) == 0) + goto err; + BIO_printf(out, "Public key:\n"); + if (BIO_indent(out, indent + 3, 128) == 0) + goto err; + BIO_printf(out, "X:"); + BN_print(out, X); + BIO_printf(out, "\n"); + if (BIO_indent(out, indent + 3, 128) == 0) + goto err; + BIO_printf(out, "Y:"); + BN_print(out, Y); + BIO_printf(out, "\n"); + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return param_print_gost01(out, pkey, indent, pctx); + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 0; +} + +static int +priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) +{ + const BIGNUM *key; + + if (BIO_indent(out, indent, 128) == 0) + return 0; + BIO_printf(out, "Private key: "); + key = GOST_KEY_get0_private_key(pkey->pkey.gost); + if (key == NULL) + BIO_printf(out, "data; + if (decode_gost01_algor_params(pk, &p, pval->length) == 0) { + GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); + return 0; + } + p = pkey_buf; + if (V_ASN1_OCTET_STRING == *p) { + /* New format - Little endian octet string */ + ASN1_OCTET_STRING *s = + d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); + + if (s == NULL) { + GOSTerror(EVP_R_DECODE_ERROR); + ASN1_STRING_free(s); + return 0; + } + + pk_num = GOST_le2bn(s->data, s->length, NULL); + ASN1_STRING_free(s); + } else { + priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); + if (priv_key == NULL) + return 0; + ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); + ASN1_INTEGER_free(priv_key); + if (ret == 0) { + GOSTerror(EVP_R_DECODE_ERROR); + return 0; + } + } + + ec = pk->pkey.gost; + if (ec == NULL) { + ec = GOST_KEY_new(); + if (ec == NULL) { + BN_free(pk_num); + return 0; + } + if (EVP_PKEY_assign_GOST(pk, ec) == 0) { + BN_free(pk_num); + GOST_KEY_free(ec); + return 0; + } + } + if (GOST_KEY_set_private_key(ec, pk_num) == 0) { + BN_free(pk_num); + return 0; + } + ret = 0; + if (EVP_PKEY_missing_parameters(pk) == 0) + ret = gost2001_compute_public(ec) != 0; + BN_free(pk_num); + + return ret; +} + +static int +priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) +{ + ASN1_OBJECT *algobj = + OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); + ASN1_STRING *params = encode_gost01_algor_params(pk); + unsigned char *priv_buf = NULL; + int priv_len; + ASN1_INTEGER *asn1key = NULL; + + if (params == NULL) + return 0; + + asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), + NULL); + if (asn1key == NULL) { + ASN1_STRING_free(params); + return 0; + } + priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); + ASN1_INTEGER_free(asn1key); + return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, + priv_len); +} + +static int +param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) +{ + ASN1_STRING *params = encode_gost01_algor_params(pkey); + int len; + + if (params == NULL) + return 0; + len = params->length; + if (pder != NULL) + memcpy(*pder, params->data, params->length); + ASN1_STRING_free(params); + return len; +} + +static int +param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) +{ + ASN1_OBJECT *obj = NULL; + int nid; + GOST_KEY *ec; + EC_GROUP *group; + int ret; + + /* New format */ + if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) + return decode_gost01_algor_params(pkey, pder, derlen); + + /* Compatibility */ + if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + + ec = GOST_KEY_new(); + if (ec == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) { + GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); + GOST_KEY_free(ec); + return 0; + } + + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (GOST_KEY_set_group(ec, group) == 0) { + GOSTerror(ERR_R_EC_LIB); + EC_GROUP_free(group); + GOST_KEY_free(ec); + return 0; + } + EC_GROUP_free(group); + if (GOST_KEY_set_digest(ec, + NID_id_GostR3411_94_CryptoProParamSet) == 0) { + GOSTerror(GOST_R_INVALID_DIGEST_TYPE); + GOST_KEY_free(ec); + return 0; + } + ret = EVP_PKEY_assign_GOST(pkey, ec); + if (ret == 0) + GOST_KEY_free(ec); + return ret; +} + +static int +param_missing_gost01(const EVP_PKEY *pk) +{ + const GOST_KEY *ec = pk->pkey.gost; + + if (ec == NULL) + return 1; + if (GOST_KEY_get0_group(ec) == NULL) + return 1; + if (GOST_KEY_get_digest(ec) == NID_undef) + return 1; + return 0; +} + +static int +param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) +{ + GOST_KEY *eto = to->pkey.gost; + const GOST_KEY *efrom = from->pkey.gost; + int ret = 1; + + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { + GOSTerror(GOST_R_INCOMPATIBLE_ALGORITHMS); + return 0; + } + if (efrom == NULL) { + GOSTerror(GOST_R_KEY_PARAMETERS_MISSING); + return 0; + } + if (eto == NULL) { + eto = GOST_KEY_new(); + if (eto == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { + GOST_KEY_free(eto); + return 0; + } + } + GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); + GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); + if (GOST_KEY_get0_private_key(eto) != NULL) + ret = gost2001_compute_public(eto); + + return ret; +} + +static int +param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != + EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) + return 0; + + if (GOST_KEY_get_digest(a->pkey.gost) != + GOST_KEY_get_digest(b->pkey.gost)) + return 0; + + return 1; +} + +static int +pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; + int digest = GOST_KEY_get_digest(pkey->pkey.gost); + + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg3); + break; + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = GostR3410_get_md_digest(digest); + return 2; + + default: + return -2; + } + + if (alg1) + X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0); + if (alg2) + X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0); + if (alg3) { + ASN1_STRING *params = encode_gost01_algor_params(pkey); + if (params == NULL) { + return -1; + } + X509_ALGOR_set0(alg3, + OBJ_nid2obj(GostR3410_get_pk_digest(digest)), + V_ASN1_SEQUENCE, params); + } + + return 1; +} + +const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[] = { + { + .pkey_id = EVP_PKEY_GOSTR01, + .pkey_base_id = EVP_PKEY_GOSTR01, + .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, + + .pem_str = "GOST2001", + .info = "GOST R 34.10-2001", + + .pkey_free = pkey_free_gost01, + .pkey_ctrl = pkey_ctrl_gost01, + + .priv_decode = priv_decode_gost01, + .priv_encode = priv_encode_gost01, + .priv_print = priv_print_gost01, + + .param_decode = param_decode_gost01, + .param_encode = param_encode_gost01, + .param_missing = param_missing_gost01, + .param_copy = param_copy_gost01, + .param_cmp = param_cmp_gost01, + .param_print = param_print_gost01, + + .pub_decode = pub_decode_gost01, + .pub_encode = pub_encode_gost01, + .pub_cmp = pub_cmp_gost01, + .pub_print = pub_print_gost01, + .pkey_size = pkey_size_gost01, + .pkey_bits = pkey_bits_gost01, + }, + { + .pkey_id = EVP_PKEY_GOSTR12_256, + .pkey_base_id = EVP_PKEY_GOSTR01, + .pkey_flags = ASN1_PKEY_ALIAS + }, + { + .pkey_id = EVP_PKEY_GOSTR12_512, + .pkey_base_id = EVP_PKEY_GOSTR01, + .pkey_flags = ASN1_PKEY_ALIAS + }, +}; + +#endif diff --git a/Libraries/libressl/crypto/gost/gostr341001_key.c b/Libraries/libressl/crypto/gost/gostr341001_key.c new file mode 100644 index 000000000..0170ab44b --- /dev/null +++ b/Libraries/libressl/crypto/gost/gostr341001_key.c @@ -0,0 +1,334 @@ +/* $OpenBSD: gostr341001_key.c,v 1.14 2023/07/24 17:08:53 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include +#include +#include "gost_local.h" + +struct gost_key_st { + EC_GROUP *group; + + EC_POINT *pub_key; + BIGNUM *priv_key; + + int references; + + int digest_nid; +}; + +GOST_KEY * +GOST_KEY_new(void) +{ + GOST_KEY *ret; + + ret = malloc(sizeof(GOST_KEY)); + if (ret == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->group = NULL; + ret->pub_key = NULL; + ret->priv_key = NULL; + ret->references = 1; + ret->digest_nid = NID_undef; + return (ret); +} +LCRYPTO_ALIAS(GOST_KEY_new); + +void +GOST_KEY_free(GOST_KEY *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); + if (i > 0) + return; + + EC_GROUP_free(r->group); + EC_POINT_free(r->pub_key); + BN_free(r->priv_key); + + freezero(r, sizeof(GOST_KEY)); +} +LCRYPTO_ALIAS(GOST_KEY_free); + +int +GOST_KEY_check_key(const GOST_KEY *key) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *order = NULL; + EC_POINT *point = NULL; + + if (key == NULL || key->group == NULL || key->pub_key == NULL) { + GOSTerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (EC_POINT_is_at_infinity(key->group, key->pub_key) != 0) { + GOSTerror(EC_R_POINT_AT_INFINITY); + goto err; + } + if ((ctx = BN_CTX_new()) == NULL) + goto err; + if ((point = EC_POINT_new(key->group)) == NULL) + goto err; + + /* testing whether the pub_key is on the elliptic curve */ + if (EC_POINT_is_on_curve(key->group, key->pub_key, ctx) <= 0) { + GOSTerror(EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + /* testing whether pub_key * order is the point at infinity */ + if ((order = BN_new()) == NULL) + goto err; + if (EC_GROUP_get_order(key->group, order, ctx) == 0) { + GOSTerror(EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (EC_POINT_mul(key->group, point, NULL, key->pub_key, order, + ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_is_at_infinity(key->group, point) == 0) { + GOSTerror(EC_R_WRONG_ORDER); + goto err; + } + /* + * in case the priv_key is present : check if generator * priv_key == + * pub_key + */ + if (key->priv_key != NULL) { + if (BN_cmp(key->priv_key, order) >= 0) { + GOSTerror(EC_R_WRONG_ORDER); + goto err; + } + if (EC_POINT_mul(key->group, point, key->priv_key, NULL, NULL, + ctx) == 0) { + GOSTerror(ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(key->group, point, key->pub_key, ctx) != 0) { + GOSTerror(EC_R_INVALID_PRIVATE_KEY); + goto err; + } + } + ok = 1; +err: + BN_free(order); + BN_CTX_free(ctx); + EC_POINT_free(point); + return (ok); +} +LCRYPTO_ALIAS(GOST_KEY_check_key); + +int +GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y) +{ + BN_CTX *ctx = NULL; + BIGNUM *tx, *ty; + EC_POINT *point = NULL; + int ok = 0; + + if (key == NULL || key->group == NULL || x == NULL || y == NULL) { + GOSTerror(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + + point = EC_POINT_new(key->group); + if (point == NULL) + goto err; + + if ((tx = BN_CTX_get(ctx)) == NULL) + goto err; + if ((ty = BN_CTX_get(ctx)) == NULL) + goto err; + if (EC_POINT_set_affine_coordinates(key->group, point, x, y, + ctx) == 0) + goto err; + if (EC_POINT_get_affine_coordinates(key->group, point, tx, ty, + ctx) == 0) + goto err; + /* + * Check if retrieved coordinates match originals: if not, values are + * out of range. + */ + if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { + GOSTerror(EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + if (GOST_KEY_set_public_key(key, point) == 0) + goto err; + + if (GOST_KEY_check_key(key) == 0) + goto err; + + ok = 1; + +err: + EC_POINT_free(point); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; + +} +LCRYPTO_ALIAS(GOST_KEY_set_public_key_affine_coordinates); + +const EC_GROUP * +GOST_KEY_get0_group(const GOST_KEY *key) +{ + return key->group; +} +LCRYPTO_ALIAS(GOST_KEY_get0_group); + +int +GOST_KEY_set_group(GOST_KEY *key, const EC_GROUP *group) +{ + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return (key->group == NULL) ? 0 : 1; +} +LCRYPTO_ALIAS(GOST_KEY_set_group); + +const BIGNUM * +GOST_KEY_get0_private_key(const GOST_KEY *key) +{ + return key->priv_key; +} +LCRYPTO_ALIAS(GOST_KEY_get0_private_key); + +int +GOST_KEY_set_private_key(GOST_KEY *key, const BIGNUM *priv_key) +{ + BN_free(key->priv_key); + key->priv_key = BN_dup(priv_key); + return (key->priv_key == NULL) ? 0 : 1; +} +LCRYPTO_ALIAS(GOST_KEY_set_private_key); + +const EC_POINT * +GOST_KEY_get0_public_key(const GOST_KEY *key) +{ + return key->pub_key; +} +LCRYPTO_ALIAS(GOST_KEY_get0_public_key); + +int +GOST_KEY_set_public_key(GOST_KEY *key, const EC_POINT *pub_key) +{ + EC_POINT_free(key->pub_key); + key->pub_key = EC_POINT_dup(pub_key, key->group); + return (key->pub_key == NULL) ? 0 : 1; +} +LCRYPTO_ALIAS(GOST_KEY_set_public_key); + +int +GOST_KEY_get_digest(const GOST_KEY *key) +{ + return key->digest_nid; +} +LCRYPTO_ALIAS(GOST_KEY_get_digest); +int +GOST_KEY_set_digest(GOST_KEY *key, int digest_nid) +{ + if (digest_nid == NID_id_GostR3411_94_CryptoProParamSet || + digest_nid == NID_id_tc26_gost3411_2012_256 || + digest_nid == NID_id_tc26_gost3411_2012_512) { + key->digest_nid = digest_nid; + return 1; + } + + return 0; +} +LCRYPTO_ALIAS(GOST_KEY_set_digest); + +size_t +GOST_KEY_get_size(const GOST_KEY *r) +{ + int i; + BIGNUM *order = NULL; + const EC_GROUP *group; + + if (r == NULL) + return 0; + group = GOST_KEY_get0_group(r); + if (group == NULL) + return 0; + + if ((order = BN_new()) == NULL) + return 0; + + if (EC_GROUP_get_order(group, order, NULL) == 0) { + BN_free(order); + return 0; + } + + i = BN_num_bytes(order); + BN_free(order); + return (i); +} +LCRYPTO_ALIAS(GOST_KEY_get_size); +#endif diff --git a/Libraries/libressl/crypto/gost/gostr341001_params.c b/Libraries/libressl/crypto/gost/gostr341001_params.c new file mode 100644 index 000000000..ca8a27d71 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gostr341001_params.c @@ -0,0 +1,132 @@ +/* $OpenBSD: gostr341001_params.c,v 1.5 2022/11/26 16:08:53 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include + +#include "gost_local.h" + +int +GostR3410_get_md_digest(int nid) +{ + if (nid == NID_id_GostR3411_94_CryptoProParamSet) + return NID_id_GostR3411_94; + return nid; +} + +int +GostR3410_get_pk_digest(int nid) +{ + switch (nid) { + case NID_id_GostR3411_94_CryptoProParamSet: + return NID_id_GostR3410_2001; + case NID_id_tc26_gost3411_2012_256: + return NID_id_tc26_gost3410_2012_256; + case NID_id_tc26_gost3411_2012_512: + return NID_id_tc26_gost3410_2012_512; + default: + return NID_undef; + } +} + +typedef struct GostR3410_params { + const char *name; + int nid; +} GostR3410_params; + +static const GostR3410_params GostR3410_256_params[] = { + { "A", NID_id_GostR3410_2001_CryptoPro_A_ParamSet }, + { "B", NID_id_GostR3410_2001_CryptoPro_B_ParamSet }, + { "C", NID_id_GostR3410_2001_CryptoPro_C_ParamSet }, + { "0", NID_id_GostR3410_2001_TestParamSet }, + { "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet }, + { "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet }, + { NULL, NID_undef }, +}; + +static const GostR3410_params GostR3410_512_params[] = { + { "A", NID_id_tc26_gost_3410_12_512_paramSetA }, + { "B", NID_id_tc26_gost_3410_12_512_paramSetB }, + { NULL, NID_undef }, +}; + +int +GostR3410_256_param_id(const char *value) +{ + int i; + + for (i = 0; GostR3410_256_params[i].nid != NID_undef; i++) { + if (strcasecmp(GostR3410_256_params[i].name, value) == 0) + return GostR3410_256_params[i].nid; + } + + return NID_undef; +} + +int +GostR3410_512_param_id(const char *value) +{ + int i; + + for (i = 0; GostR3410_512_params[i].nid != NID_undef; i++) { + if (strcasecmp(GostR3410_512_params[i].name, value) == 0) + return GostR3410_512_params[i].nid; + } + + return NID_undef; +} + +#endif diff --git a/Libraries/libressl/crypto/gost/gostr341001_pmeth.c b/Libraries/libressl/crypto/gost/gostr341001_pmeth.c new file mode 100644 index 000000000..c5e05bec6 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gostr341001_pmeth.c @@ -0,0 +1,705 @@ +/* $OpenBSD: gostr341001_pmeth.c,v 1.19 2023/07/28 15:50:33 tb Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include +#include +#include +#include + +#include "ecdsa_local.h" +#include "evp_local.h" +#include "gost_local.h" +#include "gost_asn1.h" + +static ECDSA_SIG * +unpack_signature_cp(const unsigned char *sig, size_t siglen) +{ + ECDSA_SIG *s; + + s = ECDSA_SIG_new(); + if (s == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + BN_bin2bn(sig, siglen / 2, s->s); + BN_bin2bn(sig + siglen / 2, siglen / 2, s->r); + return s; +} + +static int +pack_signature_cp(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen) +{ + int r_len = BN_num_bytes(s->r); + int s_len = BN_num_bytes(s->s); + + if (r_len > order || s_len > order) + return 0; + + *siglen = 2 * order; + + memset(sig, 0, *siglen); + BN_bn2bin(s->s, sig + order - s_len); + BN_bn2bin(s->r, sig + 2 * order - r_len); + ECDSA_SIG_free(s); + return 1; +} + +static ECDSA_SIG * +unpack_signature_le(const unsigned char *sig, size_t siglen) +{ + ECDSA_SIG *s; + + s = ECDSA_SIG_new(); + if (s == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + GOST_le2bn(sig, siglen / 2, s->r); + GOST_le2bn(sig + siglen / 2, siglen / 2, s->s); + return s; +} + +static int +pack_signature_le(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen) +{ + *siglen = 2 * order; + memset(sig, 0, *siglen); + GOST_bn2le(s->r, sig, order); + GOST_bn2le(s->s, sig + order, order); + ECDSA_SIG_free(s); + return 1; +} + +struct gost_pmeth_data { + int sign_param_nid; /* Should be set whenever parameters are filled */ + int digest_nid; + EVP_MD *md; + unsigned char *shared_ukm; + int peer_key_used; + int sig_format; +}; + +static int +pkey_gost01_init(EVP_PKEY_CTX *ctx) +{ + struct gost_pmeth_data *data; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + + data = calloc(1, sizeof(struct gost_pmeth_data)); + if (data == NULL) + return 0; + + if (pkey != NULL && pkey->pkey.gost != NULL) { + data->sign_param_nid = + EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); + data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost); + } + EVP_PKEY_CTX_set_data(ctx, data); + return 1; +} + +/* Copies contents of gost_pmeth_data structure */ +static int +pkey_gost01_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + struct gost_pmeth_data *dst_data, *src_data; + + if (pkey_gost01_init(dst) == 0) + return 0; + + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + *dst_data = *src_data; + if (src_data->shared_ukm != NULL) + dst_data->shared_ukm = NULL; + return 1; +} + +/* Frees up gost_pmeth_data structure */ +static void +pkey_gost01_cleanup(EVP_PKEY_CTX *ctx) +{ + struct gost_pmeth_data *data; + + if ((data = EVP_PKEY_CTX_get_data(ctx)) == NULL) + return; + + free(data->shared_ukm); + free(data); +} + +static int +pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + EC_GROUP *group = NULL; + GOST_KEY *gost = NULL; + int ret = 0; + + if (data->sign_param_nid == NID_undef || + data->digest_nid == NID_undef) { + GOSTerror(GOST_R_NO_PARAMETERS_SET); + return 0; + } + + group = EC_GROUP_new_by_curve_name(data->sign_param_nid); + if (group == NULL) + goto done; + + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + + gost = GOST_KEY_new(); + if (gost == NULL) + goto done; + + if (GOST_KEY_set_digest(gost, data->digest_nid) == 0) + goto done; + + if (GOST_KEY_set_group(gost, group) != 0) + ret = EVP_PKEY_assign_GOST(pkey, gost); + +done: + if (ret == 0) + GOST_KEY_free(gost); + EC_GROUP_free(group); + return ret; +} + +static int +pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + if (pkey_gost01_paramgen(ctx, pkey) == 0) + return 0; + return gost2001_keygen(pkey->pkey.gost) != 0; +} + +static int +pkey_gost01_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbs_len) +{ + ECDSA_SIG *unpacked_sig = NULL; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); + BIGNUM *md; + size_t size; + int ret; + + if (pkey == NULL || pkey->pkey.gost == NULL) + return 0; + size = GOST_KEY_get_size(pkey->pkey.gost); + + if (siglen == NULL) + return 0; + if (sig == NULL) { + *siglen = 2 * size; + return 1; + } else if (*siglen < 2 * size) { + GOSTerror(EC_R_BUFFER_TOO_SMALL); + return 0; + } + if (tbs_len != 32 && tbs_len != 64) { + GOSTerror(EVP_R_BAD_BLOCK_LENGTH); + return 0; + } + md = GOST_le2bn(tbs, tbs_len, NULL); + if (md == NULL) + return 0; + unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost); + BN_free(md); + if (unpacked_sig == NULL) { + return 0; + } + switch (pctx->sig_format) { + case GOST_SIG_FORMAT_SR_BE: + ret = pack_signature_cp(unpacked_sig, size, sig, siglen); + break; + case GOST_SIG_FORMAT_RS_LE: + ret = pack_signature_le(unpacked_sig, size, sig, siglen); + break; + default: + ret = -1; + break; + } + if (ret <= 0) + ECDSA_SIG_free(unpacked_sig); + return ret; +} + +static int +pkey_gost01_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbs_len) +{ + int ok = 0; + EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); + struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); + ECDSA_SIG *s = NULL; + BIGNUM *md; + + if (pub_key == NULL) + return 0; + switch (pctx->sig_format) { + case GOST_SIG_FORMAT_SR_BE: + s = unpack_signature_cp(sig, siglen); + break; + case GOST_SIG_FORMAT_RS_LE: + s = unpack_signature_le(sig, siglen); + break; + } + if (s == NULL) + return 0; + md = GOST_le2bn(tbs, tbs_len, NULL); + if (md == NULL) + goto err; + ok = gost2001_do_verify(md, s, pub_key->pkey.gost); + +err: + BN_free(md); + ECDSA_SIG_free(s); + return ok; +} + +static int +gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm, + unsigned char *key) +{ + unsigned char hashbuf[128]; + int digest_nid; + int ret = 0; + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *UKM, *X, *Y; + + if (ctx == NULL) + return 0; + + BN_CTX_start(ctx); + if ((UKM = BN_CTX_get(ctx)) == NULL) + goto err; + if ((X = BN_CTX_get(ctx)) == NULL) + goto err; + if ((Y = BN_CTX_get(ctx)) == NULL) + goto err; + + GOST_le2bn(ukm, 8, UKM); + + digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost); + if (VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, + UKM) == 0) + goto err; + + switch (digest_nid) { + case NID_id_GostR3411_94_CryptoProParamSet: + GOST_bn2le(X, hashbuf, 32); + GOST_bn2le(Y, hashbuf + 32, 32); + GOSTR341194(hashbuf, 64, key, digest_nid); + ret = 1; + break; + case NID_id_tc26_gost3411_2012_256: + GOST_bn2le(X, hashbuf, 32); + GOST_bn2le(Y, hashbuf + 32, 32); + STREEBOG256(hashbuf, 64, key); + ret = 1; + break; + case NID_id_tc26_gost3411_2012_512: + GOST_bn2le(X, hashbuf, 64); + GOST_bn2le(Y, hashbuf + 64, 64); + STREEBOG256(hashbuf, 128, key); + ret = 1; + break; + default: + ret = -2; + break; + } +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + +int +pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, + const unsigned char *in, size_t in_len) +{ + const unsigned char *p = in; + EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); + GOST_KEY_TRANSPORT *gkt = NULL; + int ret = 0; + unsigned char wrappedKey[44]; + unsigned char sharedKey[32]; + EVP_PKEY *eph_key = NULL, *peerkey = NULL; + int nid; + + if (key == NULL) { + *key_len = 32; + return 1; + } + gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len); + if (gkt == NULL) { + GOSTerror(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); + return -1; + } + + /* If key transport structure contains public key, use it */ + eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); + if (eph_key != NULL) { + if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) { + GOSTerror(GOST_R_INCOMPATIBLE_PEER_KEY); + goto err; + } + } else { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, + NULL) <= 0) { + GOSTerror(GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + peerkey = EVP_PKEY_CTX_get0_peerkey(pctx); + if (peerkey == NULL) { + GOSTerror(GOST_R_NO_PEER_KEY); + goto err; + } + + nid = OBJ_obj2nid(gkt->key_agreement_info->cipher); + + if (gkt->key_agreement_info->eph_iv->length != 8) { + GOSTerror(GOST_R_INVALID_IV_LENGTH); + goto err; + } + memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8); + if (gkt->key_info->encrypted_key->length != 32) { + GOSTerror(EVP_R_BAD_KEY_LENGTH); + goto err; + } + memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); + if (gkt->key_info->imit->length != 4) { + GOSTerror(ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); + if (gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey) <= 0) + goto err; + if (gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key) == 0) { + GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + + ret = 1; +err: + EVP_PKEY_free(eph_key); + GOST_KEY_TRANSPORT_free(gkt); + return ret; +} + +int +pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + /* + * Public key of peer in the ctx field peerkey + * Our private key in the ctx pkey + * ukm is in the algorithm specific context data + */ + EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); + EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + + if (data->shared_ukm == NULL) { + GOSTerror(GOST_R_UKM_NOT_SET); + return 0; + } + + if (key == NULL) { + *keylen = 32; + return 32; + } + + if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, key) <= 0) + return 0; + + *keylen = 32; + return 1; +} + +int +pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, + const unsigned char *key, size_t key_len) +{ + GOST_KEY_TRANSPORT *gkt = NULL; + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); + unsigned char ukm[8], shared_key[32], crypted_key[44]; + int ret = 0; + int key_is_ephemeral; + EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); + int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; + + if (data->shared_ukm != NULL) { + memcpy(ukm, data->shared_ukm, 8); + } else /* if (out != NULL) */ { + arc4random_buf(ukm, 8); + } + /* Check for private key in the peer_key of context */ + if (sec_key) { + key_is_ephemeral = 0; + if (GOST_KEY_get0_private_key(sec_key->pkey.gost) == 0) { + GOSTerror(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + goto err; + } + } else { + key_is_ephemeral = 1; + if (out != NULL) { + GOST_KEY *tmp_key; + + sec_key = EVP_PKEY_new(); + if (sec_key == NULL) + goto err; + tmp_key = GOST_KEY_new(); + if (tmp_key == NULL) + goto err; + if (EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), + tmp_key) == 0) { + GOST_KEY_free(tmp_key); + goto err; + } + if (EVP_PKEY_copy_parameters(sec_key, pubk) == 0) + goto err; + if (gost2001_keygen(sec_key->pkey.gost) == 0) { + goto err; + } + } + } + + if (out != NULL) { + if (gost01_VKO_key(pubk, sec_key, ukm, shared_key) <= 0) + goto err; + gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, + crypted_key); + } + gkt = GOST_KEY_TRANSPORT_new(); + if (gkt == NULL) + goto err; + if (ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) == 0) + goto err; + if (ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, + 4) == 0) + goto err; + if (ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, + 32) == 0) + goto err; + if (key_is_ephemeral) { + if (X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key, + out != NULL ? sec_key : pubk) == 0) { + GOSTerror(GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + goto err; + } + } + ASN1_OBJECT_free(gkt->key_agreement_info->cipher); + gkt->key_agreement_info->cipher = OBJ_nid2obj(nid); + if (key_is_ephemeral) + EVP_PKEY_free(sec_key); + else { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, + NULL) <= 0) { + GOSTerror(GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0) + ret = 1; + GOST_KEY_TRANSPORT_free(gkt); + return ret; + +err: + if (key_is_ephemeral) + EVP_PKEY_free(sec_key); + GOST_KEY_TRANSPORT_free(gkt); + return -1; +} + + +static int +pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); + + switch (type) { + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type(p2) != + GostR3410_get_md_digest(pctx->digest_nid)) { + GOSTerror(GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + pctx->md = p2; + return 1; + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_DIGESTINIT: + return 1; + + case EVP_PKEY_CTRL_GOST_PARAMSET: + pctx->sign_param_nid = (int)p1; + return 1; + + case EVP_PKEY_CTRL_SET_IV: + { + char *ukm = malloc(p1); + + if (ukm == NULL) { + GOSTerror(ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(ukm, p2, p1); + free(pctx->shared_ukm); + pctx->shared_ukm = ukm; + return 1; + } + + case EVP_PKEY_CTRL_PEER_KEY: + if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ + return 1; + if (p1 == 2) /* TLS: peer key used? */ + return pctx->peer_key_used; + if (p1 == 3) /* TLS: peer key used! */ + return (pctx->peer_key_used = 1); + return -2; + case EVP_PKEY_CTRL_GOST_SIG_FORMAT: + switch (p1) { + case GOST_SIG_FORMAT_SR_BE: + case GOST_SIG_FORMAT_RS_LE: + pctx->sig_format = p1; + return 1; + default: + return 0; + } + break; + case EVP_PKEY_CTRL_GOST_SET_DIGEST: + pctx->digest_nid = (int)p1; + return 1; + case EVP_PKEY_CTRL_GOST_GET_DIGEST: + *(int *)p2 = pctx->digest_nid; + return 1; + default: + return -2; + } +} + +static int +pkey_gost01_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + int param_nid = NID_undef; + int digest_nid = NID_undef; + + if (strcmp(type, "paramset") == 0) { + if (value == NULL) + return 0; + if (pkey_gost01_ctrl(ctx, EVP_PKEY_CTRL_GOST_GET_DIGEST, 0, + &digest_nid) == 0) + return 0; + if (digest_nid == NID_id_tc26_gost3411_2012_512) + param_nid = GostR3410_512_param_id(value); + else + param_nid = GostR3410_256_param_id(value); + if (param_nid == NID_undef) + param_nid = OBJ_txt2nid(value); + if (param_nid == NID_undef) + return 0; + + return pkey_gost01_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } + if (strcmp(type, "dgst") == 0) { + if (value == NULL) + return 0; + else if (strcmp(value, "gost94") == 0 || + strcmp(value, "md_gost94") == 0) + digest_nid = NID_id_GostR3411_94_CryptoProParamSet; + else if (strcmp(value, "streebog256") == 0) + digest_nid = NID_id_tc26_gost3411_2012_256; + else if (strcmp(value, "streebog512") == 0) + digest_nid = NID_id_tc26_gost3411_2012_512; + + if (digest_nid == NID_undef) + return 0; + + return pkey_gost01_ctrl(ctx, EVP_PKEY_CTRL_GOST_SET_DIGEST, + digest_nid, NULL); + } + return -2; +} + +const EVP_PKEY_METHOD gostr01_pkey_meth = { + .pkey_id = EVP_PKEY_GOSTR01, + + .init = pkey_gost01_init, + .copy = pkey_gost01_copy, + .cleanup = pkey_gost01_cleanup, + + .paramgen = pkey_gost01_paramgen, + .keygen = pkey_gost01_keygen, + .sign = pkey_gost01_sign, + .verify = pkey_gost01_verify, + + .encrypt = pkey_gost01_encrypt, + .decrypt = pkey_gost01_decrypt, + .derive = pkey_gost01_derive, + + .ctrl = pkey_gost01_ctrl, + .ctrl_str = pkey_gost01_ctrl_str, +}; +#endif diff --git a/Libraries/libressl/crypto/gost/gostr341194.c b/Libraries/libressl/crypto/gost/gostr341194.c new file mode 100644 index 000000000..311c30453 --- /dev/null +++ b/Libraries/libressl/crypto/gost/gostr341194.c @@ -0,0 +1,278 @@ +/* $OpenBSD: gostr341194.c,v 1.7 2023/07/08 14:30:44 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include + +#include "gost_local.h" + +/* Following functions are various bit meshing routines used in + * GOST R 34.11-94 algorithms */ +static void +swap_bytes(unsigned char *w, unsigned char *k) +{ + int i, j; + + for (i = 0; i < 4; i++) + for (j = 0; j < 8; j++) + k[i + 4 * j] = w[8 * i + j]; +} + +/* was A_A */ +static void +circle_xor8(const unsigned char *w, unsigned char *k) +{ + unsigned char buf[8]; + int i; + + memcpy(buf, w, 8); + memmove(k, w + 8, 24); + for (i = 0; i < 8; i++) + k[i + 24] = buf[i] ^ k[i]; +} + +/* was R_R */ +static void +transform_3(unsigned char *data) +{ + unsigned short int acc; + + acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) | + ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8); + memmove(data, data + 2, 30); + data[30] = acc & 0xff; + data[31] = acc >> 8; +} + +/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/ +static int +add_blocks(int n, unsigned char *left, const unsigned char *right) +{ + int i; + int carry = 0; + int sum; + + for (i = 0; i < n; i++) { + sum = (int)left[i] + (int)right[i] + carry; + left[i] = sum & 0xff; + carry = sum >> 8; + } + return carry; +} + +/* Xor two sequences of bytes */ +static void +xor_blocks(unsigned char *result, const unsigned char *a, + const unsigned char *b, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + result[i] = a[i] ^ b[i]; +} + +/* + * Calculate H(i+1) = Hash(Hi,Mi) + * Where H and M are 32 bytes long + */ +static int +hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M) +{ + unsigned char U[32], W[32], V[32], S[32], Key[32]; + int i; + + /* Compute first key */ + xor_blocks(W, H, M, 32); + swap_bytes(W, Key); + /* Encrypt first 8 bytes of H with first key */ + Gost2814789_set_key(&c->cipher, Key, 256); + Gost2814789_encrypt(H, S, &c->cipher); + + /* Compute second key */ + circle_xor8(H, U); + circle_xor8(M, V); + circle_xor8(V, V); + xor_blocks(W, U, V, 32); + swap_bytes(W, Key); + /* encrypt second 8 bytes of H with second key */ + Gost2814789_set_key(&c->cipher, Key, 256); + Gost2814789_encrypt(H+8, S+8, &c->cipher); + + /* compute third key */ + circle_xor8(U, U); + U[31] = ~U[31]; + U[29] = ~U[29]; + U[28] = ~U[28]; + U[24] = ~U[24]; + U[23] = ~U[23]; + U[20] = ~U[20]; + U[18] = ~U[18]; + U[17] = ~U[17]; + U[14] = ~U[14]; + U[12] = ~U[12]; + U[10] = ~U[10]; + U[8] = ~U[8]; + U[7] = ~U[7]; + U[5] = ~U[5]; + U[3] = ~U[3]; + U[1] = ~U[1]; + circle_xor8(V, V); + circle_xor8(V, V); + xor_blocks(W, U, V, 32); + swap_bytes(W, Key); + /* encrypt third 8 bytes of H with third key */ + Gost2814789_set_key(&c->cipher, Key, 256); + Gost2814789_encrypt(H+16, S+16, &c->cipher); + + /* Compute fourth key */ + circle_xor8(U, U); + circle_xor8(V, V); + circle_xor8(V, V); + xor_blocks(W, U, V, 32); + swap_bytes(W, Key); + /* Encrypt last 8 bytes with fourth key */ + Gost2814789_set_key(&c->cipher, Key, 256); + Gost2814789_encrypt(H+24, S+24, &c->cipher); + + for (i = 0; i < 12; i++) + transform_3(S); + xor_blocks(S, S, M, 32); + transform_3(S); + xor_blocks(S, S, H, 32); + for (i = 0; i < 61; i++) + transform_3(S); + memcpy(H, S, 32); + return 1; +} + +int +GOSTR341194_Init(GOSTR341194_CTX *c, int nid) +{ + memset(c, 0, sizeof(*c)); + return Gost2814789_set_sbox(&c->cipher, nid); +} +LCRYPTO_ALIAS(GOSTR341194_Init); + +static void +GOSTR341194_block_data_order(GOSTR341194_CTX *ctx, const unsigned char *p, + size_t num) +{ + int i; + + for (i = 0; i < num; i++) { + hash_step(ctx, ctx->H, p); + add_blocks(32, ctx->S, p); + p += 32; + } +} + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CBLOCK GOSTR341194_CBLOCK +#define HASH_LONG GOSTR341194_LONG +#define HASH_CTX GOSTR341194_CTX +#define HASH_UPDATE GOSTR341194_Update +#define HASH_TRANSFORM GOSTR341194_Transform +#define HASH_NO_FINAL 1 +#define HASH_BLOCK_DATA_ORDER GOSTR341194_block_data_order + +#include "md32_common.h" +LCRYPTO_ALIAS(GOSTR341194_Update); +LCRYPTO_ALIAS(GOSTR341194_Transform); + +int +GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX * c) +{ + unsigned char *p = (unsigned char *)c->data; + unsigned char T[32]; + + if (c->num > 0) { + memset(p + c->num, 0, 32 - c->num); + hash_step(c, c->H, p); + add_blocks(32, c->S, p); + } + + p = T; + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); + memset(p, 0, 32 - 8); + hash_step(c, c->H, T); + hash_step(c, c->H, c->S); + + memcpy(md, c->H, 32); + + return 1; +} +LCRYPTO_ALIAS(GOSTR341194_Final); + +unsigned char * +GOSTR341194(const unsigned char *d, size_t n, unsigned char *md, int nid) +{ + GOSTR341194_CTX c; + static unsigned char m[GOSTR341194_LENGTH]; + + if (md == NULL) + md = m; + if (!GOSTR341194_Init(&c, nid)) + return 0; + GOSTR341194_Update(&c, d, n); + GOSTR341194_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} +LCRYPTO_ALIAS(GOSTR341194); +#endif diff --git a/Libraries/libressl/crypto/gost/streebog.c b/Libraries/libressl/crypto/gost/streebog.c new file mode 100644 index 000000000..60c575794 --- /dev/null +++ b/Libraries/libressl/crypto/gost/streebog.c @@ -0,0 +1,1487 @@ +/* $OpenBSD: streebog.c,v 1.9 2023/07/08 14:30:44 beck Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_GOST +#include +#include +#include + +#include "gost_local.h" + +static const STREEBOG_LONG64 A_PI_table[8][256] = { + { /* 0 */ + U64(0xd01f715b5c7ef8e6), U64(0x16fa240980778325), + U64(0xa8a42e857ee049c8), U64(0x6ac1068fa186465b), + U64(0x6e417bd7a2e9320b), U64(0x665c8167a437daab), + U64(0x7666681aa89617f6), U64(0x4b959163700bdcf5), + U64(0xf14be6b78df36248), U64(0xc585bd689a625cff), + U64(0x9557d7fca67d82cb), U64(0x89f0b969af6dd366), + U64(0xb0833d48749f6c35), U64(0xa1998c23b1ecbc7c), + U64(0x8d70c431ac02a736), U64(0xd6dfbc2fd0a8b69e), + U64(0x37aeb3e551fa198b), U64(0x0b7d128a40b5cf9c), + U64(0x5a8f2008b5780cbc), U64(0xedec882284e333e5), + U64(0xd25fc177d3c7c2ce), U64(0x5e0f5d50b61778ec), + U64(0x1d873683c0c24cb9), U64(0xad040bcbb45d208c), + U64(0x2f89a0285b853c76), U64(0x5732fff6791b8d58), + U64(0x3e9311439ef6ec3f), U64(0xc9183a809fd3c00f), + U64(0x83adf3f5260a01ee), U64(0xa6791941f4e8ef10), + U64(0x103ae97d0ca1cd5d), U64(0x2ce948121dee1b4a), + U64(0x39738421dbf2bf53), U64(0x093da2a6cf0cf5b4), + U64(0xcd9847d89cbcb45f), U64(0xf9561c078b2d8ae8), + U64(0x9c6a755a6971777f), U64(0xbc1ebaa0712ef0c5), + U64(0x72e61542abf963a6), U64(0x78bb5fde229eb12e), + U64(0x14ba94250fceb90d), U64(0x844d6697630e5282), + U64(0x98ea08026a1e032f), U64(0xf06bbea144217f5c), + U64(0xdb6263d11ccb377a), U64(0x641c314b2b8ee083), + U64(0x320e96ab9b4770cf), U64(0x1ee7deb986a96b85), + U64(0xe96cf57a878c47b5), U64(0xfdd6615f8842feb8), + U64(0xc83862965601dd1b), U64(0x2ea9f83e92572162), + U64(0xf876441142ff97fc), U64(0xeb2c455608357d9d), + U64(0x5612a7e0b0c9904c), U64(0x6c01cbfb2d500823), + U64(0x4548a6a7fa037a2d), U64(0xabc4c6bf388b6ef4), + U64(0xbade77d4fdf8bebd), U64(0x799b07c8eb4cac3a), + U64(0x0c9d87e805b19cf0), U64(0xcb588aac106afa27), + U64(0xea0c1d40c1e76089), U64(0x2869354a1e816f1a), + U64(0xff96d17307fbc490), U64(0x9f0a9d602f1a5043), + U64(0x96373fc6e016a5f7), U64(0x5292dab8b3a6e41c), + U64(0x9b8ae0382c752413), U64(0x4f15ec3b7364a8a5), + U64(0x3fb349555724f12b), U64(0xc7c50d4415db66d7), + U64(0x92b7429ee379d1a7), U64(0xd37f99611a15dfda), + U64(0x231427c05e34a086), U64(0xa439a96d7b51d538), + U64(0xb403401077f01865), U64(0xdda2aea5901d7902), + U64(0x0a5d4a9c8967d288), U64(0xc265280adf660f93), + U64(0x8bb0094520d4e94e), U64(0x2a29856691385532), + U64(0x42a833c5bf072941), U64(0x73c64d54622b7eb2), + U64(0x07e095624504536c), U64(0x8a905153e906f45a), + U64(0x6f6123c16b3b2f1f), U64(0xc6e55552dc097bc3), + U64(0x4468feb133d16739), U64(0xe211e7f0c7398829), + U64(0xa2f96419f7879b40), U64(0x19074bdbc3ad38e9), + U64(0xf4ebc3f9474e0b0c), U64(0x43886bd376d53455), + U64(0xd8028beb5aa01046), U64(0x51f23282f5cdc320), + U64(0xe7b1c2be0d84e16d), U64(0x081dfab006dee8a0), + U64(0x3b33340d544b857b), U64(0x7f5bcabc679ae242), + U64(0x0edd37c48a08a6d8), U64(0x81ed43d9a9b33bc6), + U64(0xb1a3655ebd4d7121), U64(0x69a1eeb5e7ed6167), + U64(0xf6ab73d5c8f73124), U64(0x1a67a3e185c61fd5), + U64(0x2dc91004d43c065e), U64(0x0240b02c8fb93a28), + U64(0x90f7f2b26cc0eb8f), U64(0x3cd3a16f114fd617), + U64(0xaae49ea9f15973e0), U64(0x06c0cd748cd64e78), + U64(0xda423bc7d5192a6e), U64(0xc345701c16b41287), + U64(0x6d2193ede4821537), U64(0xfcf639494190e3ac), + U64(0x7c3b228621f1c57e), U64(0xfb16ac2b0494b0c0), + U64(0xbf7e529a3745d7f9), U64(0x6881b6a32e3f7c73), + U64(0xca78d2bad9b8e733), U64(0xbbfe2fc2342aa3a9), + U64(0x0dbddffecc6381e4), U64(0x70a6a56e2440598e), + U64(0xe4d12a844befc651), U64(0x8c509c2765d0ba22), + U64(0xee8c6018c28814d9), U64(0x17da7c1f49a59e31), + U64(0x609c4c1328e194d3), U64(0xb3e3d57232f44b09), + U64(0x91d7aaa4a512f69b), U64(0x0ffd6fd243dabbcc), + U64(0x50d26a943c1fde34), U64(0x6be15e9968545b4f), + U64(0x94778fea6faf9fdf), U64(0x2b09dd7058ea4826), + U64(0x677cd9716de5c7bf), U64(0x49d5214fffb2e6dd), + U64(0x0360e83a466b273c), U64(0x1fc786af4f7b7691), + U64(0xa0b9d435783ea168), U64(0xd49f0c035f118cb6), + U64(0x01205816c9d21d14), U64(0xac2453dd7d8f3d98), + U64(0x545217cc3f70aa64), U64(0x26b4028e9489c9c2), + U64(0xdec2469fd6765e3e), U64(0x04807d58036f7450), + U64(0xe5f17292823ddb45), U64(0xf30b569b024a5860), + U64(0x62dcfc3fa758aefb), U64(0xe84cad6c4e5e5aa1), + U64(0xccb81fce556ea94b), U64(0x53b282ae7a74f908), + U64(0x1b47fbf74c1402c1), U64(0x368eebf39828049f), + U64(0x7afbeff2ad278b06), U64(0xbe5e0a8cfe97caed), + U64(0xcfd8f7f413058e77), U64(0xf78b2bc301252c30), + U64(0x4d555c17fcdd928d), U64(0x5f2f05467fc565f8), + U64(0x24f4b2a21b30f3ea), U64(0x860dd6bbecb768aa), + U64(0x4c750401350f8f99), U64(0x0000000000000000), + U64(0xecccd0344d312ef1), U64(0xb5231806be220571), + U64(0xc105c030990d28af), U64(0x653c695de25cfd97), + U64(0x159acc33c61ca419), U64(0xb89ec7f872418495), + U64(0xa9847693b73254dc), U64(0x58cf90243ac13694), + U64(0x59efc832f3132b80), U64(0x5c4fed7c39ae42c4), + U64(0x828dabe3efd81cfa), U64(0xd13f294d95ace5f2), + U64(0x7d1b7a90e823d86a), U64(0xb643f03cf849224d), + U64(0x3df3f979d89dcb03), U64(0x7426d836272f2dde), + U64(0xdfe21e891fa4432a), U64(0x3a136c1b9d99986f), + U64(0xfa36f43dcd46add4), U64(0xc025982650df35bb), + U64(0x856d3e81aadc4f96), U64(0xc4a5e57e53b041eb), + U64(0x4708168b75ba4005), U64(0xaf44bbe73be41aa4), + U64(0x971767d029c4b8e3), U64(0xb9be9feebb939981), + U64(0x215497ecd18d9aae), U64(0x316e7e91dd2c57f3), + U64(0xcef8afe2dad79363), U64(0x3853dc371220a247), + U64(0x35ee03c9de4323a3), U64(0xe6919aa8c456fc79), + U64(0xe05157dc4880b201), U64(0x7bdbb7e464f59612), + U64(0x127a59518318f775), U64(0x332ecebd52956ddb), + U64(0x8f30741d23bb9d1e), U64(0xd922d3fd93720d52), + U64(0x7746300c61440ae2), U64(0x25d4eab4d2e2eefe), + U64(0x75068020eefd30ca), U64(0x135a01474acaea61), + U64(0x304e268714fe4ae7), U64(0xa519f17bb283c82c), + U64(0xdc82f6b359cf6416), U64(0x5baf781e7caa11a8), + U64(0xb2c38d64fb26561d), U64(0x34ce5bdf17913eb7), + U64(0x5d6fb56af07c5fd0), U64(0x182713cd0a7f25fd), + U64(0x9e2ac576e6c84d57), U64(0x9aaab82ee5a73907), + U64(0xa3d93c0f3e558654), U64(0x7e7b92aaae48ff56), + U64(0x872d8ead256575be), U64(0x41c8dbfff96c0e7d), + U64(0x99ca5014a3cc1e3b), U64(0x40e883e930be1369), + U64(0x1ca76e95091051ad), U64(0x4e35b42dbab6b5b1), + U64(0x05a0254ecabd6944), U64(0xe1710fca8152af15), + U64(0xf22b0e8dcb984574), U64(0xb763a82a319b3f59), + U64(0x63fca4296e8ab3ef), U64(0x9d4a2d4ca0a36a6b), + U64(0xe331bfe60eeb953d), U64(0xd5bf541596c391a2), + U64(0xf5cb9bef8e9c1618), U64(0x46284e9dbc685d11), + U64(0x2074cffa185f87ba), U64(0xbd3ee2b6b8fcedd1), + U64(0xae64e3f1f23607b0), U64(0xfeb68965ce29d984), + U64(0x55724fdaf6a2b770), U64(0x29496d5cd753720e), + U64(0xa75941573d3af204), U64(0x8e102c0bea69800a), + U64(0x111ab16bc573d049), U64(0xd7ffe439197aab8a), + U64(0xefac380e0b5a09cd), U64(0x48f579593660fbc9), + U64(0x22347fd697e6bd92), U64(0x61bc1405e13389c7), + U64(0x4ab5c975b9d9c1e1), U64(0x80cd1bcf606126d2), + U64(0x7186fd78ed92449a), U64(0x93971a882aabccb3), + U64(0x88d0e17f66bfce72), U64(0x27945a985d5bd4d6) + }, { /* 1 */ + U64(0xde553f8c05a811c8), U64(0x1906b59631b4f565), + U64(0x436e70d6b1964ff7), U64(0x36d343cb8b1e9d85), + U64(0x843dfacc858aab5a), U64(0xfdfc95c299bfc7f9), + U64(0x0f634bdea1d51fa2), U64(0x6d458b3b76efb3cd), + U64(0x85c3f77cf8593f80), U64(0x3c91315fbe737cb2), + U64(0x2148b03366ace398), U64(0x18f8b8264c6761bf), + U64(0xc830c1c495c9fb0f), U64(0x981a76102086a0aa), + U64(0xaa16012142f35760), U64(0x35cc54060c763cf6), + U64(0x42907d66cc45db2d), U64(0x8203d44b965af4bc), + U64(0x3d6f3cefc3a0e868), U64(0xbc73ff69d292bda7), + U64(0x8722ed0102e20a29), U64(0x8f8185e8cd34deb7), + U64(0x9b0561dda7ee01d9), U64(0x5335a0193227fad6), + U64(0xc9cecc74e81a6fd5), U64(0x54f5832e5c2431ea), + U64(0x99e47ba05d553470), U64(0xf7bee756acd226ce), + U64(0x384e05a5571816fd), U64(0xd1367452a47d0e6a), + U64(0xf29fde1c386ad85b), U64(0x320c77316275f7ca), + U64(0xd0c879e2d9ae9ab0), U64(0xdb7406c69110ef5d), + U64(0x45505e51a2461011), U64(0xfc029872e46c5323), + U64(0xfa3cb6f5f7bc0cc5), U64(0x031f17cd8768a173), + U64(0xbd8df2d9af41297d), U64(0x9d3b4f5ab43e5e3f), + U64(0x4071671b36feee84), U64(0x716207e7d3e3b83d), + U64(0x48d20ff2f9283a1a), U64(0x27769eb4757cbc7e), + U64(0x5c56ebc793f2e574), U64(0xa48b474f9ef5dc18), + U64(0x52cbada94ff46e0c), U64(0x60c7da982d8199c6), + U64(0x0e9d466edc068b78), U64(0x4eec2175eaf865fc), + U64(0x550b8e9e21f7a530), U64(0x6b7ba5bc653fec2b), + U64(0x5eb7f1ba6949d0dd), U64(0x57ea94e3db4c9099), + U64(0xf640eae6d101b214), U64(0xdd4a284182c0b0bb), + U64(0xff1d8fbf6304f250), U64(0xb8accb933bf9d7e8), + U64(0xe8867c478eb68c4d), U64(0x3f8e2692391bddc1), + U64(0xcb2fd60912a15a7c), U64(0xaec935dbab983d2f), + U64(0xf55ffd2b56691367), U64(0x80e2ce366ce1c115), + U64(0x179bf3f8edb27e1d), U64(0x01fe0db07dd394da), + U64(0xda8a0b76ecc37b87), U64(0x44ae53e1df9584cb), + U64(0xb310b4b77347a205), U64(0xdfab323c787b8512), + U64(0x3b511268d070b78e), U64(0x65e6e3d2b9396753), + U64(0x6864b271e2574d58), U64(0x259784c98fc789d7), + U64(0x02e11a7dfabb35a9), U64(0x8841a6dfa337158b), + U64(0x7ade78c39b5dcdd0), U64(0xb7cf804d9a2cc84a), + U64(0x20b6bd831b7f7742), U64(0x75bd331d3a88d272), + U64(0x418f6aab4b2d7a5e), U64(0xd9951cbb6babdaf4), + U64(0xb6318dfde7ff5c90), U64(0x1f389b112264aa83), + U64(0x492c024284fbaec0), U64(0xe33a0363c608f9a0), + U64(0x2688930408af28a4), U64(0xc7538a1a341ce4ad), + U64(0x5da8e677ee2171ae), U64(0x8c9e92254a5c7fc4), + U64(0x63d8cd55aae938b5), U64(0x29ebd8daa97a3706), + U64(0x959827b37be88aa1), U64(0x1484e4356adadf6e), + U64(0xa7945082199d7d6b), U64(0xbf6ce8a455fa1cd4), + U64(0x9cc542eac9edcae5), U64(0x79c16f0e1c356ca3), + U64(0x89bfab6fdee48151), U64(0xd4174d1830c5f0ff), + U64(0x9258048415eb419d), U64(0x6139d72850520d1c), + U64(0x6a85a80c18ec78f1), U64(0xcd11f88e0171059a), + U64(0xcceff53e7ca29140), U64(0xd229639f2315af19), + U64(0x90b91ef9ef507434), U64(0x5977d28d074a1be1), + U64(0x311360fce51d56b9), U64(0xc093a92d5a1f2f91), + U64(0x1a19a25bb6dc5416), U64(0xeb996b8a09de2d3e), + U64(0xfee3820f1ed7668a), U64(0xd7085ad5b7ad518c), + U64(0x7fff41890fe53345), U64(0xec5948bd67dde602), + U64(0x2fd5f65dbaaa68e0), U64(0xa5754affe32648c2), + U64(0xf8ddac880d07396c), U64(0x6fa491468c548664), + U64(0x0c7c5c1326bdbed1), U64(0x4a33158f03930fb3), + U64(0x699abfc19f84d982), U64(0xe4fa2054a80b329c), + U64(0x6707f9af438252fa), U64(0x08a368e9cfd6d49e), + U64(0x47b1442c58fd25b8), U64(0xbbb3dc5ebc91769b), + U64(0x1665fe489061eac7), U64(0x33f27a811fa66310), + U64(0x93a609346838d547), U64(0x30ed6d4c98cec263), + U64(0x1dd9816cd8df9f2a), U64(0x94662a03063b1e7b), + U64(0x83fdd9fbeb896066), U64(0x7b207573e68e590a), + U64(0x5f49fc0a149a4407), U64(0x343259b671a5a82c), + U64(0xfbc2bb458a6f981f), U64(0xc272b350a0a41a38), + U64(0x3aaf1fd8ada32354), U64(0x6cbb868b0b3c2717), + U64(0xa2b569c88d2583fe), U64(0xf180c9d1bf027928), + U64(0xaf37386bd64ba9f5), U64(0x12bacab2790a8088), + U64(0x4c0d3b0810435055), U64(0xb2eeb9070e9436df), + U64(0xc5b29067cea7d104), U64(0xdcb425f1ff132461), + U64(0x4f122cc5972bf126), U64(0xac282fa651230886), + U64(0xe7e537992f6393ef), U64(0xe61b3a2952b00735), + U64(0x709c0a57ae302ce7), U64(0xe02514ae416058d3), + U64(0xc44c9dd7b37445de), U64(0x5a68c5408022ba92), + U64(0x1c278cdca50c0bf0), U64(0x6e5a9cf6f18712be), + U64(0x86dce0b17f319ef3), U64(0x2d34ec2040115d49), + U64(0x4bcd183f7e409b69), U64(0x2815d56ad4a9a3dc), + U64(0x24698979f2141d0d), U64(0x0000000000000000), + U64(0x1ec696a15fb73e59), U64(0xd86b110b16784e2e), + U64(0x8e7f8858b0e74a6d), U64(0x063e2e8713d05fe6), + U64(0xe2c40ed3bbdb6d7a), U64(0xb1f1aeca89fc97ac), + U64(0xe1db191e3cb3cc09), U64(0x6418ee62c4eaf389), + U64(0xc6ad87aa49cf7077), U64(0xd6f65765ca7ec556), + U64(0x9afb6c6dda3d9503), U64(0x7ce05644888d9236), + U64(0x8d609f95378feb1e), U64(0x23a9aa4e9c17d631), + U64(0x6226c0e5d73aac6f), U64(0x56149953a69f0443), + U64(0xeeb852c09d66d3ab), U64(0x2b0ac2a753c102af), + U64(0x07c023376e03cb3c), U64(0x2ccae1903dc2c993), + U64(0xd3d76e2f5ec63bc3), U64(0x9e2458973356ff4c), + U64(0xa66a5d32644ee9b1), U64(0x0a427294356de137), + U64(0x783f62be61e6f879), U64(0x1344c70204d91452), + U64(0x5b96c8f0fdf12e48), U64(0xa90916ecc59bf613), + U64(0xbe92e5142829880e), U64(0x727d102a548b194e), + U64(0x1be7afebcb0fc0cc), U64(0x3e702b2244c8491b), + U64(0xd5e940a84d166425), U64(0x66f9f41f3e51c620), + U64(0xabe80c913f20c3ba), U64(0xf07ec461c2d1edf2), + U64(0xf361d3ac45b94c81), U64(0x0521394a94b8fe95), + U64(0xadd622162cf09c5c), U64(0xe97871f7f3651897), + U64(0xf4a1f09b2bba87bd), U64(0x095d6559b2054044), + U64(0x0bbc7f2448be75ed), U64(0x2af4cf172e129675), + U64(0x157ae98517094bb4), U64(0x9fda55274e856b96), + U64(0x914713499283e0ee), U64(0xb952c623462a4332), + U64(0x74433ead475b46a8), U64(0x8b5eb112245fb4f8), + U64(0xa34b6478f0f61724), U64(0x11a5dd7ffe6221fb), + U64(0xc16da49d27ccbb4b), U64(0x76a224d0bde07301), + U64(0x8aa0bca2598c2022), U64(0x4df336b86d90c48f), + U64(0xea67663a740db9e4), U64(0xef465f70e0b54771), + U64(0x39b008152acb8227), U64(0x7d1e5bf4f55e06ec), + U64(0x105bd0cf83b1b521), U64(0x775c2960c033e7db), + U64(0x7e014c397236a79f), U64(0x811cc386113255cf), + U64(0xeda7450d1a0e72d8), U64(0x5889df3d7a998f3b), + U64(0x2e2bfbedc779fc3a), U64(0xce0eef438619a4e9), + U64(0x372d4e7bf6cd095f), U64(0x04df34fae96b6a4f), + U64(0xf923a13870d4adb6), U64(0xa1aa7e050a4d228d), + U64(0xa8f71b5cb84862c9), U64(0xb52e9a306097fde3), + U64(0x0d8251a35b6e2a0b), U64(0x2257a7fee1c442eb), + U64(0x73831d9a29588d94), U64(0x51d4ba64c89ccf7f), + U64(0x502ab7d4b54f5ba5), U64(0x97793dce8153bf08), + U64(0xe5042de4d5d8a646), U64(0x9687307efc802bd2), + U64(0xa05473b5779eb657), U64(0xb4d097801d446939), + U64(0xcff0e2f3fbca3033), U64(0xc38cbee0dd778ee2), + U64(0x464f499c252eb162), U64(0xcad1dbb96f72cea6), + U64(0xba4dd1eec142e241), U64(0xb00fa37af42f0376) + }, { /* 2 */ + U64(0xcce4cd3aa968b245), U64(0x089d5484e80b7faf), + U64(0x638246c1b3548304), U64(0xd2fe0ec8c2355492), + U64(0xa7fbdf7ff2374eee), U64(0x4df1600c92337a16), + U64(0x84e503ea523b12fb), U64(0x0790bbfd53ab0c4a), + U64(0x198a780f38f6ea9d), U64(0x2ab30c8f55ec48cb), + U64(0xe0f7fed6b2c49db5), U64(0xb6ecf3f422cadbdc), + U64(0x409c9a541358df11), U64(0xd3ce8a56dfde3fe3), + U64(0xc3e9224312c8c1a0), U64(0x0d6dfa58816ba507), + U64(0xddf3e1b179952777), U64(0x04c02a42748bb1d9), + U64(0x94c2abff9f2decb8), U64(0x4f91752da8f8acf4), + U64(0x78682befb169bf7b), U64(0xe1c77a48af2ff6c4), + U64(0x0c5d7ec69c80ce76), U64(0x4cc1e4928fd81167), + U64(0xfeed3d24d9997b62), U64(0x518bb6dfc3a54a23), + U64(0x6dbf2d26151f9b90), U64(0xb5bc624b05ea664f), + U64(0xe86aaa525acfe21a), U64(0x4801ced0fb53a0be), + U64(0xc91463e6c00868ed), U64(0x1027a815cd16fe43), + U64(0xf67069a0319204cd), U64(0xb04ccc976c8abce7), + U64(0xc0b9b3fc35e87c33), U64(0xf380c77c58f2de65), + U64(0x50bb3241de4e2152), U64(0xdf93f490435ef195), + U64(0xf1e0d25d62390887), U64(0xaf668bfb1a3c3141), + U64(0xbc11b251f00a7291), U64(0x73a5eed47e427d47), + U64(0x25bee3f6ee4c3b2e), U64(0x43cc0beb34786282), + U64(0xc824e778dde3039c), U64(0xf97d86d98a327728), + U64(0xf2b043e24519b514), U64(0xe297ebf7880f4b57), + U64(0x3a94a49a98fab688), U64(0x868516cb68f0c419), + U64(0xeffa11af0964ee50), U64(0xa4ab4ec0d517f37d), + U64(0xa9c6b498547c567a), U64(0x8e18424f80fbbbb6), + U64(0x0bcdc53bcf2bc23c), U64(0x137739aaea3643d0), + U64(0x2c1333ec1bac2ff0), U64(0x8d48d3f0a7db0625), + U64(0x1e1ac3f26b5de6d7), U64(0xf520f81f16b2b95e), + U64(0x9f0f6ec450062e84), U64(0x0130849e1deb6b71), + U64(0xd45e31ab8c7533a9), U64(0x652279a2fd14e43f), + U64(0x3209f01e70f1c927), U64(0xbe71a770cac1a473), + U64(0x0e3d6be7a64b1894), U64(0x7ec8148cff29d840), + U64(0xcb7476c7fac3be0f), U64(0x72956a4a63a91636), + U64(0x37f95ec21991138f), U64(0x9e3fea5a4ded45f5), + U64(0x7b38ba50964902e8), U64(0x222e580bbde73764), + U64(0x61e253e0899f55e6), U64(0xfc8d2805e352ad80), + U64(0x35994be3235ac56d), U64(0x09add01af5e014de), + U64(0x5e8659a6780539c6), U64(0xb17c48097161d796), + U64(0x026015213acbd6e2), U64(0xd1ae9f77e515e901), + U64(0xb7dc776a3f21b0ad), U64(0xaba6a1b96eb78098), + U64(0x9bcf4486248d9f5d), U64(0x582666c536455efd), + U64(0xfdbdac9bfeb9c6f1), U64(0xc47999be4163cdea), + U64(0x765540081722a7ef), U64(0x3e548ed8ec710751), + U64(0x3d041f67cb51bac2), U64(0x7958af71ac82d40a), + U64(0x36c9da5c047a78fe), U64(0xed9a048e33af38b2), + U64(0x26ee7249c96c86bd), U64(0x900281bdeba65d61), + U64(0x11172c8bd0fd9532), U64(0xea0abf73600434f8), + U64(0x42fc8f75299309f3), U64(0x34a9cf7d3eb1ae1c), + U64(0x2b838811480723ba), U64(0x5ce64c8742ceef24), + U64(0x1adae9b01fd6570e), U64(0x3c349bf9d6bad1b3), + U64(0x82453c891c7b75c0), U64(0x97923a40b80d512b), + U64(0x4a61dbf1c198765c), U64(0xb48ce6d518010d3e), + U64(0xcfb45c858e480fd6), U64(0xd933cbf30d1e96ae), + U64(0xd70ea014ab558e3a), U64(0xc189376228031742), + U64(0x9262949cd16d8b83), U64(0xeb3a3bed7def5f89), + U64(0x49314a4ee6b8cbcf), U64(0xdcc3652f647e4c06), + U64(0xda635a4c2a3e2b3d), U64(0x470c21a940f3d35b), + U64(0x315961a157d174b4), U64(0x6672e81dda3459ac), + U64(0x5b76f77a1165e36e), U64(0x445cb01667d36ec8), + U64(0xc5491d205c88a69b), U64(0x456c34887a3805b9), + U64(0xffddb9bac4721013), U64(0x99af51a71e4649bf), + U64(0xa15be01cbc7729d5), U64(0x52db2760e485f7b0), + U64(0x8c78576eba306d54), U64(0xae560f6507d75a30), + U64(0x95f22f6182c687c9), U64(0x71c5fbf54489aba5), + U64(0xca44f259e728d57e), U64(0x88b87d2ccebbdc8d), + U64(0xbab18d32be4a15aa), U64(0x8be8ec93e99b611e), + U64(0x17b713e89ebdf209), U64(0xb31c5d284baa0174), + U64(0xeeca9531148f8521), U64(0xb8d198138481c348), + U64(0x8988f9b2d350b7fc), U64(0xb9e11c8d996aa839), + U64(0x5a4673e40c8e881f), U64(0x1687977683569978), + U64(0xbf4123eed72acf02), U64(0x4ea1f1b3b513c785), + U64(0xe767452be16f91ff), U64(0x7505d1b730021a7c), + U64(0xa59bca5ec8fc980c), U64(0xad069eda20f7e7a3), + U64(0x38f4b1bba231606a), U64(0x60d2d77e94743e97), + U64(0x9affc0183966f42c), U64(0x248e6768f3a7505f), + U64(0xcdd449a4b483d934), U64(0x87b59255751baf68), + U64(0x1bea6d2e023d3c7f), U64(0x6b1f12455b5ffcab), + U64(0x743555292de9710d), U64(0xd8034f6d10f5fddf), + U64(0xc6198c9f7ba81b08), U64(0xbb8109aca3a17edb), + U64(0xfa2d1766ad12cabb), U64(0xc729080166437079), + U64(0x9c5fff7b77269317), U64(0x0000000000000000), + U64(0x15d706c9a47624eb), U64(0x6fdf38072fd44d72), + U64(0x5fb6dd3865ee52b7), U64(0xa33bf53d86bcff37), + U64(0xe657c1b5fc84fa8e), U64(0xaa962527735cebe9), + U64(0x39c43525bfda0b1b), U64(0x204e4d2a872ce186), + U64(0x7a083ece8ba26999), U64(0x554b9c9db72efbfa), + U64(0xb22cd9b656416a05), U64(0x96a2bedea5e63a5a), + U64(0x802529a826b0a322), U64(0x8115ad363b5bc853), + U64(0x8375b81701901eb1), U64(0x3069e53f4a3a1fc5), + U64(0xbd2136cfede119e0), U64(0x18bafc91251d81ec), + U64(0x1d4a524d4c7d5b44), U64(0x05f0aedc6960daa8), + U64(0x29e39d3072ccf558), U64(0x70f57f6b5962c0d4), + U64(0x989fd53903ad22ce), U64(0xf84d024797d91c59), + U64(0x547b1803aac5908b), U64(0xf0d056c37fd263f6), + U64(0xd56eb535919e58d8), U64(0x1c7ad6d351963035), + U64(0x2e7326cd2167f912), U64(0xac361a443d1c8cd2), + U64(0x697f076461942a49), U64(0x4b515f6fdc731d2d), + U64(0x8ad8680df4700a6f), U64(0x41ac1eca0eb3b460), + U64(0x7d988533d80965d3), U64(0xa8f6300649973d0b), + U64(0x7765c4960ac9cc9e), U64(0x7ca801adc5e20ea2), + U64(0xdea3700e5eb59ae4), U64(0xa06b6482a19c42a4), + U64(0x6a2f96db46b497da), U64(0x27def6d7d487edcc), + U64(0x463ca5375d18b82a), U64(0xa6cb5be1efdc259f), + U64(0x53eba3fef96e9cc1), U64(0xce84d81b93a364a7), + U64(0xf4107c810b59d22f), U64(0x333974806d1aa256), + U64(0x0f0def79bba073e5), U64(0x231edc95a00c5c15), + U64(0xe437d494c64f2c6c), U64(0x91320523f64d3610), + U64(0x67426c83c7df32dd), U64(0x6eefbc99323f2603), + U64(0x9d6f7be56acdf866), U64(0x5916e25b2bae358c), + U64(0x7ff89012e2c2b331), U64(0x035091bf2720bd93), + U64(0x561b0d22900e4669), U64(0x28d319ae6f279e29), + U64(0x2f43a2533c8c9263), U64(0xd09e1be9f8fe8270), + U64(0xf740ed3e2c796fbc), U64(0xdb53ded237d5404c), + U64(0x62b2c25faebfe875), U64(0x0afd41a5d2c0a94d), + U64(0x6412fd3ce0ff8f4e), U64(0xe3a76f6995e42026), + U64(0x6c8fa9b808f4f0e1), U64(0xc2d9a6dd0f23aad1), + U64(0x8f28c6d19d10d0c7), U64(0x85d587744fd0798a), + U64(0xa20b71a39b579446), U64(0x684f83fa7c7f4138), + U64(0xe507500adba4471d), U64(0x3f640a46f19a6c20), + U64(0x1247bd34f7dd28a1), U64(0x2d23b77206474481), + U64(0x93521002cc86e0f2), U64(0x572b89bc8de52d18), + U64(0xfb1d93f8b0f9a1ca), U64(0xe95a2ecc4724896b), + U64(0x3ba420048511ddf9), U64(0xd63e248ab6bee54b), + U64(0x5dd6c8195f258455), U64(0x06a03f634e40673b), + U64(0x1f2a476c76b68da6), U64(0x217ec9b49ac78af7), + U64(0xecaa80102e4453c3), U64(0x14e78257b99d4f9a) + }, { /* 3 */ + U64(0x20329b2cc87bba05), U64(0x4f5eb6f86546a531), + U64(0xd4f44775f751b6b1), U64(0x8266a47b850dfa8b), + U64(0xbb986aa15a6ca985), U64(0xc979eb08f9ae0f99), + U64(0x2da6f447a2375ea1), U64(0x1e74275dcd7d8576), + U64(0xbc20180a800bc5f8), U64(0xb4a2f701b2dc65be), + U64(0xe726946f981b6d66), U64(0x48e6c453bf21c94c), + U64(0x42cad9930f0a4195), U64(0xefa47b64aacccd20), + U64(0x71180a8960409a42), U64(0x8bb3329bf6a44e0c), + U64(0xd34c35de2d36dacc), U64(0xa92f5b7cbc23dc96), + U64(0xb31a85aa68bb09c3), U64(0x13e04836a73161d2), + U64(0xb24dfc4129c51d02), U64(0x8ae44b70b7da5acd), + U64(0xe671ed84d96579a7), U64(0xa4bb3417d66f3832), + U64(0x4572ab38d56d2de8), U64(0xb1b47761ea47215c), + U64(0xe81c09cf70aba15d), U64(0xffbdb872ce7f90ac), + U64(0xa8782297fd5dc857), U64(0x0d946f6b6a4ce4a4), + U64(0xe4df1f4f5b995138), U64(0x9ebc71edca8c5762), + U64(0x0a2c1dc0b02b88d9), U64(0x3b503c115d9d7b91), + U64(0xc64376a8111ec3a2), U64(0xcec199a323c963e4), + U64(0xdc76a87ec58616f7), U64(0x09d596e073a9b487), + U64(0x14583a9d7d560daf), U64(0xf4c6dc593f2a0cb4), + U64(0xdd21d19584f80236), U64(0x4a4836983ddde1d3), + U64(0xe58866a41ae745f9), U64(0xf591a5b27e541875), + U64(0x891dc05074586693), U64(0x5b068c651810a89e), + U64(0xa30346bc0c08544f), U64(0x3dbf3751c684032d), + U64(0x2a1e86ec785032dc), U64(0xf73f5779fca830ea), + U64(0xb60c05ca30204d21), U64(0x0cc316802b32f065), + U64(0x8770241bdd96be69), U64(0xb861e18199ee95db), + U64(0xf805cad91418fcd1), U64(0x29e70dccbbd20e82), + U64(0xc7140f435060d763), U64(0x0f3a9da0e8b0cc3b), + U64(0xa2543f574d76408e), U64(0xbd7761e1c175d139), + U64(0x4b1f4f737ca3f512), U64(0x6dc2df1f2fc137ab), + U64(0xf1d05c3967b14856), U64(0xa742bf3715ed046c), + U64(0x654030141d1697ed), U64(0x07b872abda676c7d), + U64(0x3ce84eba87fa17ec), U64(0xc1fb0403cb79afdf), + U64(0x3e46bc7105063f73), U64(0x278ae987121cd678), + U64(0xa1adb4778ef47cd0), U64(0x26dd906c5362c2b9), + U64(0x05168060589b44e2), U64(0xfbfc41f9d79ac08f), + U64(0x0e6de44ba9ced8fa), U64(0x9feb08068bf243a3), + U64(0x7b341749d06b129b), U64(0x229c69e74a87929a), + U64(0xe09ee6c4427c011b), U64(0x5692e30e725c4c3a), + U64(0xda99a33e5e9f6e4b), U64(0x353dd85af453a36b), + U64(0x25241b4c90e0fee7), U64(0x5de987258309d022), + U64(0xe230140fc0802984), U64(0x93281e86a0c0b3c6), + U64(0xf229d719a4337408), U64(0x6f6c2dd4ad3d1f34), + U64(0x8ea5b2fbae3f0aee), U64(0x8331dd90c473ee4a), + U64(0x346aa1b1b52db7aa), U64(0xdf8f235e06042aa9), + U64(0xcc6f6b68a1354b7b), U64(0x6c95a6f46ebf236a), + U64(0x52d31a856bb91c19), U64(0x1a35ded6d498d555), + U64(0xf37eaef2e54d60c9), U64(0x72e181a9a3c2a61c), + U64(0x98537aad51952fde), U64(0x16f6c856ffaa2530), + U64(0xd960281e9d1d5215), U64(0x3a0745fa1ce36f50), + U64(0x0b7b642bf1559c18), U64(0x59a87eae9aec8001), + U64(0x5e100c05408bec7c), U64(0x0441f98b19e55023), + U64(0xd70dcc5534d38aef), U64(0x927f676de1bea707), + U64(0x9769e70db925e3e5), U64(0x7a636ea29115065a), + U64(0x468b201816ef11b6), U64(0xab81a9b73edff409), + U64(0xc0ac7de88a07bb1e), U64(0x1f235eb68c0391b7), + U64(0x6056b074458dd30f), U64(0xbe8eeac102f7ed67), + U64(0xcd381283e04b5fba), U64(0x5cbefecec277c4e3), + U64(0xd21b4c356c48ce0d), U64(0x1019c31664b35d8c), + U64(0x247362a7d19eea26), U64(0xebe582efb3299d03), + U64(0x02aef2cb82fc289f), U64(0x86275df09ce8aaa8), + U64(0x28b07427faac1a43), U64(0x38a9b7319e1f47cf), + U64(0xc82e92e3b8d01b58), U64(0x06ef0b409b1978bc), + U64(0x62f842bfc771fb90), U64(0x9904034610eb3b1f), + U64(0xded85ab5477a3e68), U64(0x90d195a663428f98), + U64(0x5384636e2ac708d8), U64(0xcbd719c37b522706), + U64(0xae9729d76644b0eb), U64(0x7c8c65e20a0c7ee6), + U64(0x80c856b007f1d214), U64(0x8c0b40302cc32271), + U64(0xdbcedad51fe17a8a), U64(0x740e8ae938dbdea0), + U64(0xa615c6dc549310ad), U64(0x19cc55f6171ae90b), + U64(0x49b1bdb8fe5fdd8d), U64(0xed0a89af2830e5bf), + U64(0x6a7aadb4f5a65bd6), U64(0x7e22972988f05679), + U64(0xf952b3325566e810), U64(0x39fecedadf61530e), + U64(0x6101c99f04f3c7ce), U64(0x2e5f7f6761b562ff), + U64(0xf08725d226cf5c97), U64(0x63af3b54860fef51), + U64(0x8ff2cb10ef411e2f), U64(0x884ab9bb35267252), + U64(0x4df04433e7ba8dae), U64(0x9afd8866d3690741), + U64(0x66b9bb34de94abb3), U64(0x9baaf18d92171380), + U64(0x543c11c5f0a064a5), U64(0x17a1b1bdbed431f1), + U64(0xb5f58eeaf3a2717f), U64(0xc355f6c849858740), + U64(0xec5df044694ef17e), U64(0xd83751f5dc6346d4), + U64(0xfc4433520dfdacf2), U64(0x0000000000000000), + U64(0x5a51f58e596ebc5f), U64(0x3285aaf12e34cf16), + U64(0x8d5c39db6dbd36b0), U64(0x12b731dde64f7513), + U64(0x94906c2d7aa7dfbb), U64(0x302b583aacc8e789), + U64(0x9d45facd090e6b3c), U64(0x2165e2c78905aec4), + U64(0x68d45f7f775a7349), U64(0x189b2c1d5664fdca), + U64(0xe1c99f2f030215da), U64(0x6983269436246788), + U64(0x8489af3b1e148237), U64(0xe94b702431d5b59c), + U64(0x33d2d31a6f4adbd7), U64(0xbfd9932a4389f9a6), + U64(0xb0e30e8aab39359d), U64(0xd1e2c715afcaf253), + U64(0x150f43763c28196e), U64(0xc4ed846393e2eb3d), + U64(0x03f98b20c3823c5e), U64(0xfd134ab94c83b833), + U64(0x556b682eb1de7064), U64(0x36c4537a37d19f35), + U64(0x7559f30279a5ca61), U64(0x799ae58252973a04), + U64(0x9c12832648707ffd), U64(0x78cd9c6913e92ec5), + U64(0x1d8dac7d0effb928), U64(0x439da0784e745554), + U64(0x413352b3cc887dcb), U64(0xbacf134a1b12bd44), + U64(0x114ebafd25cd494d), U64(0x2f08068c20cb763e), + U64(0x76a07822ba27f63f), U64(0xeab2fb04f25789c2), + U64(0xe3676de481fe3d45), U64(0x1b62a73d95e6c194), + U64(0x641749ff5c68832c), U64(0xa5ec4dfc97112cf3), + U64(0xf6682e92bdd6242b), U64(0x3f11c59a44782bb2), + U64(0x317c21d1edb6f348), U64(0xd65ab5be75ad9e2e), + U64(0x6b2dd45fb4d84f17), U64(0xfaab381296e4d44e), + U64(0xd0b5befeeeb4e692), U64(0x0882ef0b32d7a046), + U64(0x512a91a5a83b2047), U64(0x963e9ee6f85bf724), + U64(0x4e09cf132438b1f0), U64(0x77f701c9fb59e2fe), + U64(0x7ddb1c094b726a27), U64(0x5f4775ee01f5f8bd), + U64(0x9186ec4d223c9b59), U64(0xfeeac1998f01846d), + U64(0xac39db1ce4b89874), U64(0xb75b7c21715e59e0), + U64(0xafc0503c273aa42a), U64(0x6e3b543fec430bf5), + U64(0x704f7362213e8e83), U64(0x58ff0745db9294c0), + U64(0x67eec2df9feabf72), U64(0xa0facd9ccf8a6811), + U64(0xb936986ad890811a), U64(0x95c715c63bd9cb7a), + U64(0xca8060283a2c33c7), U64(0x507de84ee9453486), + U64(0x85ded6d05f6a96f6), U64(0x1cdad5964f81ade9), + U64(0xd5a33e9eb62fa270), U64(0x40642b588df6690a), + U64(0x7f75eec2c98e42b8), U64(0x2cf18dace3494a60), + U64(0x23cb100c0bf9865b), U64(0xeef3028febb2d9e1), + U64(0x4425d2d394133929), U64(0xaad6d05c7fa1e0c8), + U64(0xad6ea2f7a5c68cb5), U64(0xc2028f2308fb9381), + U64(0x819f2f5b468fc6d5), U64(0xc5bafd88d29cfffc), + U64(0x47dc59f357910577), U64(0x2b49ff07392e261d), + U64(0x57c59ae5332258fb), U64(0x73b6f842e2bcb2dd), + U64(0xcf96e04862b77725), U64(0x4ca73dd8a6c4996f), + U64(0x015779eb417e14c1), U64(0x37932a9176af8bf4) + }, { /* 4 */ + U64(0x190a2c9b249df23e), U64(0x2f62f8b62263e1e9), + U64(0x7a7f754740993655), U64(0x330b7ba4d5564d9f), + U64(0x4c17a16a46672582), U64(0xb22f08eb7d05f5b8), + U64(0x535f47f40bc148cc), U64(0x3aec5d27d4883037), + U64(0x10ed0a1825438f96), U64(0x516101f72c233d17), + U64(0x13cc6f949fd04eae), U64(0x739853c441474bfd), + U64(0x653793d90d3f5b1b), U64(0x5240647b96b0fc2f), + U64(0x0c84890ad27623e0), U64(0xd7189b32703aaea3), + U64(0x2685de3523bd9c41), U64(0x99317c5b11bffefa), + U64(0x0d9baa854f079703), U64(0x70b93648fbd48ac5), + U64(0xa80441fce30bc6be), U64(0x7287704bdc36ff1e), + U64(0xb65384ed33dc1f13), U64(0xd36417343ee34408), + U64(0x39cd38ab6e1bf10f), U64(0x5ab861770a1f3564), + U64(0x0ebacf09f594563b), U64(0xd04572b884708530), + U64(0x3cae9722bdb3af47), U64(0x4a556b6f2f5cbaf2), + U64(0xe1704f1f76c4bd74), U64(0x5ec4ed7144c6dfcf), + U64(0x16afc01d4c7810e6), U64(0x283f113cd629ca7a), + U64(0xaf59a8761741ed2d), U64(0xeed5a3991e215fac), + U64(0x3bf37ea849f984d4), U64(0xe413e096a56ce33c), + U64(0x2c439d3a98f020d1), U64(0x637559dc6404c46b), + U64(0x9e6c95d1e5f5d569), U64(0x24bb9836045fe99a), + U64(0x44efa466dac8ecc9), U64(0xc6eab2a5c80895d6), + U64(0x803b50c035220cc4), U64(0x0321658cba93c138), + U64(0x8f9ebc465dc7ee1c), U64(0xd15a5137190131d3), + U64(0x0fa5ec8668e5e2d8), U64(0x91c979578d1037b1), + U64(0x0642ca05693b9f70), U64(0xefca80168350eb4f), + U64(0x38d21b24f36a45ec), U64(0xbeab81e1af73d658), + U64(0x8cbfd9cae7542f24), U64(0xfd19cc0d81f11102), + U64(0x0ac6430fbb4dbc90), U64(0x1d76a09d6a441895), + U64(0x2a01573ff1cbbfa1), U64(0xb572e161894fde2b), + U64(0x8124734fa853b827), U64(0x614b1fdf43e6b1b0), + U64(0x68ac395c4238cc18), U64(0x21d837bfd7f7b7d2), + U64(0x20c714304a860331), U64(0x5cfaab726324aa14), + U64(0x74c5ba4eb50d606e), U64(0xf3a3030474654739), + U64(0x23e671bcf015c209), U64(0x45f087e947b9582a), + U64(0xd8bd77b418df4c7b), U64(0xe06f6c90ebb50997), + U64(0x0bd96080263c0873), U64(0x7e03f9410e40dcfe), + U64(0xb8e94be4c6484928), U64(0xfb5b0608e8ca8e72), + U64(0x1a2b49179e0e3306), U64(0x4e29e76961855059), + U64(0x4f36c4e6fcf4e4ba), U64(0x49740ee395cf7bca), + U64(0xc2963ea386d17f7d), U64(0x90d65ad810618352), + U64(0x12d34c1b02a1fa4d), U64(0xfa44258775bb3a91), + U64(0x18150f14b9ec46dd), U64(0x1491861e6b9a653d), + U64(0x9a1019d7ab2c3fc2), U64(0x3668d42d06fe13d7), + U64(0xdcc1fbb25606a6d0), U64(0x969490dd795a1c22), + U64(0x3549b1a1bc6dd2ef), U64(0xc94f5e23a0ed770e), + U64(0xb9f6686b5b39fdcb), U64(0xc4d4f4a6efeae00d), + U64(0xe732851a1fff2204), U64(0x94aad6de5eb869f9), + U64(0x3f8ff2ae07206e7f), U64(0xfe38a9813b62d03a), + U64(0xa7a1ad7a8bee2466), U64(0x7b6056c8dde882b6), + U64(0x302a1e286fc58ca7), U64(0x8da0fa457a259bc7), + U64(0xb3302b64e074415b), U64(0x5402ae7eff8b635f), + U64(0x08f8050c9cafc94b), U64(0xae468bf98a3059ce), + U64(0x88c355cca98dc58f), U64(0xb10e6d67c7963480), + U64(0xbad70de7e1aa3cf3), U64(0xbfb4a26e320262bb), + U64(0xcb711820870f02d5), U64(0xce12b7a954a75c9d), + U64(0x563ce87dd8691684), U64(0x9f73b65e7884618a), + U64(0x2b1e74b06cba0b42), U64(0x47cec1ea605b2df1), + U64(0x1c698312f735ac76), U64(0x5fdbcefed9b76b2c), + U64(0x831a354c8fb1cdfc), U64(0x820516c312c0791f), + U64(0xb74ca762aeadabf0), U64(0xfc06ef821c80a5e1), + U64(0x5723cbf24518a267), U64(0x9d4df05d5f661451), + U64(0x588627742dfd40bf), U64(0xda8331b73f3d39a0), + U64(0x17b0e392d109a405), U64(0xf965400bcf28fba9), + U64(0x7c3dbf4229a2a925), U64(0x023e460327e275db), + U64(0x6cd0b55a0ce126b3), U64(0xe62da695828e96e7), + U64(0x42ad6e63b3f373b9), U64(0xe50cc319381d57df), + U64(0xc5cbd729729b54ee), U64(0x46d1e265fd2a9912), + U64(0x6428b056904eeff8), U64(0x8be23040131e04b7), + U64(0x6709d5da2add2ec0), U64(0x075de98af44a2b93), + U64(0x8447dcc67bfbe66f), U64(0x6616f655b7ac9a23), + U64(0xd607b8bded4b1a40), U64(0x0563af89d3a85e48), + U64(0x3db1b4ad20c21ba4), U64(0x11f22997b8323b75), + U64(0x292032b34b587e99), U64(0x7f1cdace9331681d), + U64(0x8e819fc9c0b65aff), U64(0xa1e3677fe2d5bb16), + U64(0xcd33d225ee349da5), U64(0xd9a2543b85aef898), + U64(0x795e10cbfa0af76d), U64(0x25a4bbb9992e5d79), + U64(0x78413344677b438e), U64(0xf0826688cef68601), + U64(0xd27b34bba392f0eb), U64(0x551d8df162fad7bc), + U64(0x1e57c511d0d7d9ad), U64(0xdeffbdb171e4d30b), + U64(0xf4feea8e802f6caa), U64(0xa480c8f6317de55e), + U64(0xa0fc44f07fa40ff5), U64(0x95b5f551c3c9dd1a), + U64(0x22f952336d6476ea), U64(0x0000000000000000), + U64(0xa6be8ef5169f9085), U64(0xcc2cf1aa73452946), + U64(0x2e7ddb39bf12550a), U64(0xd526dd3157d8db78), + U64(0x486b2d6c08becf29), U64(0x9b0f3a58365d8b21), + U64(0xac78cdfaadd22c15), U64(0xbc95c7e28891a383), + U64(0x6a927f5f65dab9c3), U64(0xc3891d2c1ba0cb9e), + U64(0xeaa92f9f50f8b507), U64(0xcf0d9426c9d6e87e), + U64(0xca6e3baf1a7eb636), U64(0xab25247059980786), + U64(0x69b31ad3df4978fb), U64(0xe2512a93cc577c4c), + U64(0xff278a0ea61364d9), U64(0x71a615c766a53e26), + U64(0x89dc764334fc716c), U64(0xf87a638452594f4a), + U64(0xf2bc208be914f3da), U64(0x8766b94ac1682757), + U64(0xbbc82e687cdb8810), U64(0x626a7a53f9757088), + U64(0xa2c202f358467a2e), U64(0x4d0882e5db169161), + U64(0x09e7268301de7da8), U64(0xe897699c771ac0dc), + U64(0xc8507dac3d9cc3ed), U64(0xc0a878a0a1330aa6), + U64(0x978bb352e42ba8c1), U64(0xe9884a13ea6b743f), + U64(0x279afdbabecc28a2), U64(0x047c8c064ed9eaab), + U64(0x507e2278b15289f4), U64(0x599904fbb08cf45c), + U64(0xbd8ae46d15e01760), U64(0x31353da7f2b43844), + U64(0x8558ff49e68a528c), U64(0x76fbfc4d92ef15b5), + U64(0x3456922e211c660c), U64(0x86799ac55c1993b4), + U64(0x3e90d1219a51da9c), U64(0x2d5cbeb505819432), + U64(0x982e5fd48cce4a19), U64(0xdb9c1238a24c8d43), + U64(0xd439febecaa96f9b), U64(0x418c0bef0960b281), + U64(0x158ea591f6ebd1de), U64(0x1f48e69e4da66d4e), + U64(0x8afd13cf8e6fb054), U64(0xf5e1c9011d5ed849), + U64(0xe34e091c5126c8af), U64(0xad67ee7530a398f6), + U64(0x43b24dec2e82c75a), U64(0x75da99c1287cd48d), + U64(0x92e81cdb3783f689), U64(0xa3dd217cc537cecd), + U64(0x60543c50de970553), U64(0x93f73f54aaf2426a), + U64(0xa91b62737e7a725d), U64(0xf19d4507538732e2), + U64(0x77e4dfc20f9ea156), U64(0x7d229ccdb4d31dc6), + U64(0x1b346a98037f87e5), U64(0xedf4c615a4b29e94), + U64(0x4093286094110662), U64(0xb0114ee85ae78063), + U64(0x6ff1d0d6b672e78b), U64(0x6dcf96d591909250), + U64(0xdfe09e3eec9567e8), U64(0x3214582b4827f97c), + U64(0xb46dc2ee143e6ac8), U64(0xf6c0ac8da7cd1971), + U64(0xebb60c10cd8901e4), U64(0xf7df8f023abcad92), + U64(0x9c52d3d2c217a0b2), U64(0x6b8d5cd0f8ab0d20), + U64(0x3777f7a29b8fa734), U64(0x011f238f9d71b4e3), + U64(0xc1b75b2f3c42be45), U64(0x5de588fdfe551ef7), + U64(0x6eeef3592b035368), U64(0xaa3a07ffc4e9b365), + U64(0xecebe59a39c32a77), U64(0x5ba742f8976e8187), + U64(0x4b4a48e0b22d0e11), U64(0xddded83dcb771233), + U64(0xa59feb79ac0c51bd), U64(0xc7f5912a55792135) + }, { /* 5 */ + U64(0x6d6ae04668a9b08a), U64(0x3ab3f04b0be8c743), + U64(0xe51e166b54b3c908), U64(0xbe90a9eb35c2f139), + U64(0xb2c7066637f2bec1), U64(0xaa6945613392202c), + U64(0x9a28c36f3b5201eb), U64(0xddce5a93ab536994), + U64(0x0e34133ef6382827), U64(0x52a02ba1ec55048b), + U64(0xa2f88f97c4b2a177), U64(0x8640e513ca2251a5), + U64(0xcdf1d36258137622), U64(0xfe6cb708dedf8ddb), + U64(0x8a174a9ec8121e5d), U64(0x679896036b81560e), + U64(0x59ed033395795fee), U64(0x1dd778ab8b74edaf), + U64(0xee533ef92d9f926d), U64(0x2a8c79baf8a8d8f5), + U64(0x6bcf398e69b119f6), U64(0xe20491742fafdd95), + U64(0x276488e0809c2aec), U64(0xea955b82d88f5cce), + U64(0x7102c63a99d9e0c4), U64(0xf9763017a5c39946), + U64(0x429fa2501f151b3d), U64(0x4659c72bea05d59e), + U64(0x984b7fdccf5a6634), U64(0xf742232953fbb161), + U64(0x3041860e08c021c7), U64(0x747bfd9616cd9386), + U64(0x4bb1367192312787), U64(0x1b72a1638a6c44d3), + U64(0x4a0e68a6e8359a66), U64(0x169a5039f258b6ca), + U64(0xb98a2ef44edee5a4), U64(0xd9083fe85e43a737), + U64(0x967f6ce239624e13), U64(0x8874f62d3c1a7982), + U64(0x3c1629830af06e3f), U64(0x9165ebfd427e5a8e), + U64(0xb5dd81794ceeaa5c), U64(0x0de8f15a7834f219), + U64(0x70bd98ede3dd5d25), U64(0xaccc9ca9328a8950), + U64(0x56664eda1945ca28), U64(0x221db34c0f8859ae), + U64(0x26dbd637fa98970d), U64(0x1acdffb4f068f932), + U64(0x4585254f64090fa0), U64(0x72de245e17d53afa), + U64(0x1546b25d7c546cf4), U64(0x207e0ffffb803e71), + U64(0xfaaad2732bcf4378), U64(0xb462dfae36ea17bd), + U64(0xcf926fd1ac1b11fd), U64(0xe0672dc7dba7ba4a), + U64(0xd3fa49ad5d6b41b3), U64(0x8ba81449b216a3bc), + U64(0x14f9ec8a0650d115), U64(0x40fc1ee3eb1d7ce2), + U64(0x23a2ed9b758ce44f), U64(0x782c521b14fddc7e), + U64(0x1c68267cf170504e), U64(0xbcf31558c1ca96e6), + U64(0xa781b43b4ba6d235), U64(0xf6fd7dfe29ff0c80), + U64(0xb0a4bad5c3fad91e), U64(0xd199f51ea963266c), + U64(0x414340349119c103), U64(0x5405f269ed4dadf7), + U64(0xabd61bb649969dcd), U64(0x6813dbeae7bdc3c8), + U64(0x65fb2ab09f8931d1), U64(0xf1e7fae152e3181d), + U64(0xc1a67cef5a2339da), U64(0x7a4feea8e0f5bba1), + U64(0x1e0b9acf05783791), U64(0x5b8ebf8061713831), + U64(0x80e53cdbcb3af8d9), U64(0x7e898bd315e57502), + U64(0xc6bcfbf0213f2d47), U64(0x95a38e86b76e942d), + U64(0x092e94218d243cba), U64(0x8339debf453622e7), + U64(0xb11be402b9fe64ff), U64(0x57d9100d634177c9), + U64(0xcc4e8db52217cbc3), U64(0x3b0cae9c71ec7aa2), + U64(0xfb158ca451cbfe99), U64(0x2b33276d82ac6514), + U64(0x01bf5ed77a04bde1), U64(0xc5601994af33f779), + U64(0x75c4a3416cc92e67), U64(0xf3844652a6eb7fc2), + U64(0x3487e375fdd0ef64), U64(0x18ae430704609eed), + U64(0x4d14efb993298efb), U64(0x815a620cb13e4538), + U64(0x125c354207487869), U64(0x9eeea614ce42cf48), + U64(0xce2d3106d61fac1c), U64(0xbbe99247bad6827b), + U64(0x071a871f7b1c149d), U64(0x2e4a1cc10db81656), + U64(0x77a71ff298c149b8), U64(0x06a5d9c80118a97c), + U64(0xad73c27e488e34b1), U64(0x443a7b981e0db241), + U64(0xe3bbcfa355ab6074), U64(0x0af276450328e684), + U64(0x73617a896dd1871b), U64(0x58525de4ef7de20f), + U64(0xb7be3dcab8e6cd83), U64(0x19111dd07e64230c), + U64(0x842359a03e2a367a), U64(0x103f89f1f3401fb6), + U64(0xdc710444d157d475), U64(0xb835702334da5845), + U64(0x4320fc876511a6dc), U64(0xd026abc9d3679b8d), + U64(0x17250eee885c0b2b), U64(0x90dab52a387ae76f), + U64(0x31fed8d972c49c26), U64(0x89cba8fa461ec463), + U64(0x2ff5421677bcabb7), U64(0x396f122f85e41d7d), + U64(0xa09b332430bac6a8), U64(0xc888e8ced7070560), + U64(0xaeaf201ac682ee8f), U64(0x1180d7268944a257), + U64(0xf058a43628e7a5fc), U64(0xbd4c4b8fbbce2b07), + U64(0xa1246df34abe7b49), U64(0x7d5569b79be9af3c), + U64(0xa9b5a705bd9efa12), U64(0xdb6b835baa4bc0e8), + U64(0x05793bac8f147342), U64(0x21c1512881848390), + U64(0xfdb0556c50d357e5), U64(0x613d4fcb6a99ff72), + U64(0x03dce2648e0cda3e), U64(0xe949b9e6568386f0), + U64(0xfc0f0bbb2ad7ea04), U64(0x6a70675913b5a417), + U64(0x7f36d5046fe1c8e3), U64(0x0c57af8d02304ff8), + U64(0x32223abdfcc84618), U64(0x0891caf6f720815b), + U64(0xa63eeaec31a26fd4), U64(0x2507345374944d33), + U64(0x49d28ac266394058), U64(0xf5219f9aa7f3d6be), + U64(0x2d96fea583b4cc68), U64(0x5a31e1571b7585d0), + U64(0x8ed12fe53d02d0fe), U64(0xdfade6205f5b0e4b), + U64(0x4cabb16ee92d331a), U64(0x04c6657bf510cea3), + U64(0xd73c2cd6a87b8f10), U64(0xe1d87310a1a307ab), + U64(0x6cd5be9112ad0d6b), U64(0x97c032354366f3f2), + U64(0xd4e0ceb22677552e), U64(0x0000000000000000), + U64(0x29509bde76a402cb), U64(0xc27a9e8bd42fe3e4), + U64(0x5ef7842cee654b73), U64(0xaf107ecdbc86536e), + U64(0x3fcacbe784fcb401), U64(0xd55f90655c73e8cf), + U64(0xe6c2f40fdabf1336), U64(0xe8f6e7312c873b11), + U64(0xeb2a0555a28be12f), U64(0xe4a148bc2eb774e9), + U64(0x9b979db84156bc0a), U64(0x6eb60222e6a56ab4), + U64(0x87ffbbc4b026ec44), U64(0xc703a5275b3b90a6), + U64(0x47e699fc9001687f), U64(0x9c8d1aa73a4aa897), + U64(0x7cea3760e1ed12dd), U64(0x4ec80ddd1d2554c5), + U64(0x13e36b957d4cc588), U64(0x5d2b66486069914d), + U64(0x92b90999cc7280b0), U64(0x517cc9c56259deb5), + U64(0xc937b619ad03b881), U64(0xec30824ad997f5b2), + U64(0xa45d565fc5aa080b), U64(0xd6837201d27f32f1), + U64(0x635ef3789e9198ad), U64(0x531f75769651b96a), + U64(0x4f77530a6721e924), U64(0x486dd4151c3dfdb9), + U64(0x5f48dafb9461f692), U64(0x375b011173dc355a), + U64(0x3da9775470f4d3de), U64(0x8d0dcd81b30e0ac0), + U64(0x36e45fc609d888bb), U64(0x55baacbe97491016), + U64(0x8cb29356c90ab721), U64(0x76184125e2c5f459), + U64(0x99f4210bb55edbd5), U64(0x6f095cf59ca1d755), + U64(0x9f51f8c3b44672a9), U64(0x3538bda287d45285), + U64(0x50c39712185d6354), U64(0xf23b1885dcefc223), + U64(0x79930ccc6ef9619f), U64(0xed8fdc9da3934853), + U64(0xcb540aaa590bdf5e), U64(0x5c94389f1a6d2cac), + U64(0xe77daad8a0bbaed7), U64(0x28efc5090ca0bf2a), + U64(0xbf2ff73c4fc64cd8), U64(0xb37858b14df60320), + U64(0xf8c96ec0dfc724a7), U64(0x828680683f329f06), + U64(0x941cd051cd6a29cc), U64(0xc3c5c05cae2b5e05), + U64(0xb601631dc2e27062), U64(0xc01922382027843b), + U64(0x24b86a840e90f0d2), U64(0xd245177a276ffc52), + U64(0x0f8b4de98c3c95c6), U64(0x3e759530fef809e0), + U64(0x0b4d2892792c5b65), U64(0xc4df4743d5374a98), + U64(0xa5e20888bfaeb5ea), U64(0xba56cc90c0d23f9a), + U64(0x38d04cf8ffe0a09c), U64(0x62e1adafe495254c), + U64(0x0263bcb3f40867df), U64(0xcaeb547d230f62bf), + U64(0x6082111c109d4293), U64(0xdad4dd8cd04f7d09), + U64(0xefec602e579b2f8c), U64(0x1fb4c4187f7c8a70), + U64(0xffd3e9dfa4db303a), U64(0x7bf0b07f9af10640), + U64(0xf49ec14dddf76b5f), U64(0x8f6e713247066d1f), + U64(0x339d646a86ccfbf9), U64(0x64447467e58d8c30), + U64(0x2c29a072f9b07189), U64(0xd8b7613f24471ad6), + U64(0x6627c8d41185ebef), U64(0xa347d140beb61c96), + U64(0xde12b8f7255fb3aa), U64(0x9d324470404e1576), + U64(0x9306574eb6763d51), U64(0xa80af9d2c79a47f3), + U64(0x859c0777442e8b9b), U64(0x69ac853d9db97e29) + }, { /* 6 */ + U64(0xc3407dfc2de6377e), U64(0x5b9e93eea4256f77), + U64(0xadb58fdd50c845e0), U64(0x5219ff11a75bed86), + U64(0x356b61cfd90b1de9), U64(0xfb8f406e25abe037), + U64(0x7a5a0231c0f60796), U64(0x9d3cd216e1f5020b), + U64(0x0c6550fb6b48d8f3), U64(0xf57508c427ff1c62), + U64(0x4ad35ffa71cb407d), U64(0x6290a2da1666aa6d), + U64(0xe284ec2349355f9f), U64(0xb3c307c53d7c84ec), + U64(0x05e23c0468365a02), U64(0x190bac4d6c9ebfa8), + U64(0x94bbbee9e28b80fa), U64(0xa34fc777529cb9b5), + U64(0xcc7b39f095bcd978), U64(0x2426addb0ce532e3), + U64(0x7e79329312ce4fc7), U64(0xab09a72eebec2917), + U64(0xf8d15499f6b9d6c2), U64(0x1a55b8babf8c895d), + U64(0xdb8add17fb769a85), U64(0xb57f2f368658e81b), + U64(0x8acd36f18f3f41f6), U64(0x5ce3b7bba50f11d3), + U64(0x114dcc14d5ee2f0a), U64(0xb91a7fcded1030e8), + U64(0x81d5425fe55de7a1), U64(0xb6213bc1554adeee), + U64(0x80144ef95f53f5f2), U64(0x1e7688186db4c10c), + U64(0x3b912965db5fe1bc), U64(0xc281715a97e8252d), + U64(0x54a5d7e21c7f8171), U64(0x4b12535ccbc5522e), + U64(0x1d289cefbea6f7f9), U64(0x6ef5f2217d2e729e), + U64(0xe6a7dc819b0d17ce), U64(0x1b94b41c05829b0e), + U64(0x33d7493c622f711e), U64(0xdcf7f942fa5ce421), + U64(0x600fba8b7f7a8ecb), U64(0x46b60f011a83988e), + U64(0x235b898e0dcf4c47), U64(0x957ab24f588592a9), + U64(0x4354330572b5c28c), U64(0xa5f3ef84e9b8d542), + U64(0x8c711e02341b2d01), U64(0x0b1874ae6a62a657), + U64(0x1213d8e306fc19ff), U64(0xfe6d7c6a4d9dba35), + U64(0x65ed868f174cd4c9), U64(0x88522ea0e6236550), + U64(0x899322065c2d7703), U64(0xc01e690bfef4018b), + U64(0x915982ed8abddaf8), U64(0xbe675b98ec3a4e4c), + U64(0xa996bf7f82f00db1), U64(0xe1daf8d49a27696a), + U64(0x2effd5d3dc8986e7), U64(0xd153a51f2b1a2e81), + U64(0x18caa0ebd690adfb), U64(0x390e3134b243c51a), + U64(0x2778b92cdff70416), U64(0x029f1851691c24a6), + U64(0x5e7cafeacc133575), U64(0xfa4e4cc89fa5f264), + U64(0x5a5f9f481e2b7d24), U64(0x484c47ab18d764db), + U64(0x400a27f2a1a7f479), U64(0xaeeb9b2a83da7315), + U64(0x721c626879869734), U64(0x042330a2d2384851), + U64(0x85f672fd3765aff0), U64(0xba446b3a3e02061d), + U64(0x73dd6ecec3888567), U64(0xffac70ccf793a866), + U64(0xdfa9edb5294ed2d4), U64(0x6c6aea7014325638), + U64(0x834a5a0e8c41c307), U64(0xcdba35562fb2cb2b), + U64(0x0ad97808d06cb404), U64(0x0f3b440cb85aee06), + U64(0xe5f9c876481f213b), U64(0x98deee1289c35809), + U64(0x59018bbfcd394bd1), U64(0xe01bf47220297b39), + U64(0xde68e1139340c087), U64(0x9fa3ca4788e926ad), + U64(0xbb85679c840c144e), U64(0x53d8f3b71d55ffd5), + U64(0x0da45c5dd146caa0), U64(0x6f34fe87c72060cd), + U64(0x57fbc315cf6db784), U64(0xcee421a1fca0fdde), + U64(0x3d2d0196607b8d4b), U64(0x642c8a29ad42c69a), + U64(0x14aff010bdd87508), U64(0xac74837beac657b3), + U64(0x3216459ad821634d), U64(0x3fb219c70967a9ed), + U64(0x06bc28f3bb246cf7), U64(0xf2082c9126d562c6), + U64(0x66b39278c45ee23c), U64(0xbd394f6f3f2878b9), + U64(0xfd33689d9e8f8cc0), U64(0x37f4799eb017394f), + U64(0x108cc0b26fe03d59), U64(0xda4bd1b1417888d6), + U64(0xb09d1332ee6eb219), U64(0x2f3ed975668794b4), + U64(0x58c0871977375982), U64(0x7561463d78ace990), + U64(0x09876cff037e82f1), U64(0x7fb83e35a8c05d94), + U64(0x26b9b58a65f91645), U64(0xef20b07e9873953f), + U64(0x3148516d0b3355b8), U64(0x41cb2b541ba9e62a), + U64(0x790416c613e43163), U64(0xa011d380818e8f40), + U64(0x3a5025c36151f3ef), U64(0xd57095bdf92266d0), + U64(0x498d4b0da2d97688), U64(0x8b0c3a57353153a5), + U64(0x21c491df64d368e1), U64(0x8f2f0af5e7091bf4), + U64(0x2da1c1240f9bb012), U64(0xc43d59a92ccc49da), + U64(0xbfa6573e56345c1f), U64(0x828b56a8364fd154), + U64(0x9a41f643e0df7caf), U64(0xbcf843c985266aea), + U64(0x2b1de9d7b4bfdce5), U64(0x20059d79dedd7ab2), + U64(0x6dabe6d6ae3c446b), U64(0x45e81bf6c991ae7b), + U64(0x6351ae7cac68b83e), U64(0xa432e32253b6c711), + U64(0xd092a9b991143cd2), U64(0xcac711032e98b58f), + U64(0xd8d4c9e02864ac70), U64(0xc5fc550f96c25b89), + U64(0xd7ef8dec903e4276), U64(0x67729ede7e50f06f), + U64(0xeac28c7af045cf3d), U64(0xb15c1f945460a04a), + U64(0x9cfddeb05bfb1058), U64(0x93c69abce3a1fe5e), + U64(0xeb0380dc4a4bdd6e), U64(0xd20db1e8f8081874), + U64(0x229a8528b7c15e14), U64(0x44291750739fbc28), + U64(0xd3ccbd4e42060a27), U64(0xf62b1c33f4ed2a97), + U64(0x86a8660ae4779905), U64(0xd62e814a2a305025), + U64(0x477703a7a08d8add), U64(0x7b9b0e977af815c5), + U64(0x78c51a60a9ea2330), U64(0xa6adfb733aaae3b7), + U64(0x97e5aa1e3199b60f), U64(0x0000000000000000), + U64(0xf4b404629df10e31), U64(0x5564db44a6719322), + U64(0x9207961a59afec0d), U64(0x9624a6b88b97a45c), + U64(0x363575380a192b1c), U64(0x2c60cd82b595a241), + U64(0x7d272664c1dc7932), U64(0x7142769faa94a1c1), + U64(0xa1d0df263b809d13), U64(0x1630e841d4c451ae), + U64(0xc1df65ad44fa13d8), U64(0x13d2d445bcf20bac), + U64(0xd915c546926abe23), U64(0x38cf3d92084dd749), + U64(0xe766d0272103059d), U64(0xc7634d5effde7f2f), + U64(0x077d2455012a7ea4), U64(0xedbfa82ff16fb199), + U64(0xaf2a978c39d46146), U64(0x42953fa3c8bbd0df), + U64(0xcb061da59496a7dc), U64(0x25e7a17db6eb20b0), + U64(0x34aa6d6963050fba), U64(0xa76cf7d580a4f1e4), + U64(0xf7ea10954ee338c4), U64(0xfcf2643b24819e93), + U64(0xcf252d0746aeef8d), U64(0x4ef06f58a3f3082c), + U64(0x563acfb37563a5d7), U64(0x5086e740ce47c920), + U64(0x2982f186dda3f843), U64(0x87696aac5e798b56), + U64(0x5d22bb1d1f010380), U64(0x035e14f7d31236f5), + U64(0x3cec0d30da759f18), U64(0xf3c920379cdb7095), + U64(0xb8db736b571e22bb), U64(0xdd36f5e44052f672), + U64(0xaac8ab8851e23b44), U64(0xa857b3d938fe1fe2), + U64(0x17f1e4e76eca43fd), U64(0xec7ea4894b61a3ca), + U64(0x9e62c6e132e734fe), U64(0xd4b1991b432c7483), + U64(0x6ad6c283af163acf), U64(0x1ce9904904a8e5aa), + U64(0x5fbda34c761d2726), U64(0xf910583f4cb7c491), + U64(0xc6a241f845d06d7c), U64(0x4f3163fe19fd1a7f), + U64(0xe99c988d2357f9c8), U64(0x8eee06535d0709a7), + U64(0x0efa48aa0254fc55), U64(0xb4be23903c56fa48), + U64(0x763f52caabbedf65), U64(0xeee1bcd8227d876c), + U64(0xe345e085f33b4dcc), U64(0x3e731561b369bbbe), + U64(0x2843fd2067adea10), U64(0x2adce5710eb1ceb6), + U64(0xb7e03767ef44ccbd), U64(0x8db012a48e153f52), + U64(0x61ceb62dc5749c98), U64(0xe85d942b9959eb9b), + U64(0x4c6f7709caef2c8a), U64(0x84377e5b8d6bbda3), + U64(0x30895dcbb13d47eb), U64(0x74a04a9bc2a2fbc3), + U64(0x6b17ce251518289c), U64(0xe438c4d0f2113368), + U64(0x1fb784bed7bad35f), U64(0x9b80fae55ad16efc), + U64(0x77fe5e6c11b0cd36), U64(0xc858095247849129), + U64(0x08466059b97090a2), U64(0x01c10ca6ba0e1253), + U64(0x6988d6747c040c3a), U64(0x6849dad2c60a1e69), + U64(0x5147ebe67449db73), U64(0xc99905f4fd8a837a), + U64(0x991fe2b433cd4a5a), U64(0xf09734c04fc94660), + U64(0xa28ecbd1e892abe6), U64(0xf1563866f5c75433), + U64(0x4dae7baf70e13ed9), U64(0x7ce62ac27bd26b61), + U64(0x70837a39109ab392), U64(0x90988e4b30b3c8ab), + U64(0xb2020b63877296bf), U64(0x156efcb607d6675b) + }, { /* 7 */ + U64(0xe63f55ce97c331d0), U64(0x25b506b0015bba16), + U64(0xc8706e29e6ad9ba8), U64(0x5b43d3775d521f6a), + U64(0x0bfa3d577035106e), U64(0xab95fc172afb0e66), + U64(0xf64b63979e7a3276), U64(0xf58b4562649dad4b), + U64(0x48f7c3dbae0c83f1), U64(0xff31916642f5c8c5), + U64(0xcbb048dc1c4a0495), U64(0x66b8f83cdf622989), + U64(0x35c130e908e2b9b0), U64(0x7c761a61f0b34fa1), + U64(0x3601161cf205268d), U64(0x9e54ccfe2219b7d6), + U64(0x8b7d90a538940837), U64(0x9cd403588ea35d0b), + U64(0xbc3c6fea9ccc5b5a), U64(0xe5ff733b6d24aeed), + U64(0xceed22de0f7eb8d2), U64(0xec8581cab1ab545e), + U64(0xb96105e88ff8e71d), U64(0x8ca03501871a5ead), + U64(0x76ccce65d6db2a2f), U64(0x5883f582a7b58057), + U64(0x3f7be4ed2e8adc3e), U64(0x0fe7be06355cd9c9), + U64(0xee054e6c1d11be83), U64(0x1074365909b903a6), + U64(0x5dde9f80b4813c10), U64(0x4a770c7d02b6692c), + U64(0x5379c8d5d7809039), U64(0xb4067448161ed409), + U64(0x5f5e5026183bd6cd), U64(0xe898029bf4c29df9), + U64(0x7fb63c940a54d09c), U64(0xc5171f897f4ba8bc), + U64(0xa6f28db7b31d3d72), U64(0x2e4f3be7716eaa78), + U64(0x0d6771a099e63314), U64(0x82076254e41bf284), + U64(0x2f0fd2b42733df98), U64(0x5c9e76d3e2dc49f0), + U64(0x7aeb569619606cdb), U64(0x83478b07b2468764), + U64(0xcfadcb8d5923cd32), U64(0x85dac7f05b95a41e), + U64(0xb5469d1b4043a1e9), U64(0xb821ecbbd9a592fd), + U64(0x1b8e0b0e798c13c8), U64(0x62a57b6d9a0be02e), + U64(0xfcf1b793b81257f8), U64(0x9d94ea0bd8fe28eb), + U64(0x4cea408aeb654a56), U64(0x23284a47e888996c), + U64(0x2d8f1d128b893545), U64(0xf4cbac3132c0d8ab), + U64(0xbd7c86b9ca912eba), U64(0x3a268eef3dbe6079), + U64(0xf0d62f6077a9110c), U64(0x2735c916ade150cb), + U64(0x89fd5f03942ee2ea), U64(0x1acee25d2fd16628), + U64(0x90f39bab41181bff), U64(0x430dfe8cde39939f), + U64(0xf70b8ac4c8274796), U64(0x1c53aeaac6024552), + U64(0x13b410acf35e9c9b), U64(0xa532ab4249faa24f), + U64(0x2b1251e5625a163f), U64(0xd7e3e676da4841c7), + U64(0xa7b264e4e5404892), U64(0xda8497d643ae72d3), + U64(0x861ae105a1723b23), U64(0x38a6414991048aa4), + U64(0x6578dec92585b6b4), U64(0x0280cfa6acbaeadd), + U64(0x88bdb650c273970a), U64(0x9333bd5ebbff84c2), + U64(0x4e6a8f2c47dfa08b), U64(0x321c954db76cef2a), + U64(0x418d312a72837942), U64(0xb29b38bfffcdf773), + U64(0x6c022c38f90a4c07), U64(0x5a033a240b0f6a8a), + U64(0x1f93885f3ce5da6f), U64(0xc38a537e96988bc6), + U64(0x39e6a81ac759ff44), U64(0x29929e43cee0fce2), + U64(0x40cdd87924de0ca2), U64(0xe9d8ebc8a29fe819), + U64(0x0c2798f3cfbb46f4), U64(0x55e484223e53b343), + U64(0x4650948ecd0d2fd8), U64(0x20e86cb2126f0651), + U64(0x6d42c56baf5739e7), U64(0xa06fc1405ace1e08), + U64(0x7babbfc54f3d193b), U64(0x424d17df8864e67f), + U64(0xd8045870ef14980e), U64(0xc6d7397c85ac3781), + U64(0x21a885e1443273b1), U64(0x67f8116f893f5c69), + U64(0x24f5efe35706cff6), U64(0xd56329d076f2ab1a), + U64(0x5e1eb9754e66a32d), U64(0x28d2771098bd8902), + U64(0x8f6013f47dfdc190), U64(0x17a993fdb637553c), + U64(0xe0a219397e1012aa), U64(0x786b9930b5da8606), + U64(0x6e82e39e55b0a6da), U64(0x875a0856f72f4ec3), + U64(0x3741ff4fa458536d), U64(0xac4859b3957558fc), + U64(0x7ef6d5c75c09a57c), U64(0xc04a758b6c7f14fb), + U64(0xf9acdd91ab26ebbf), U64(0x7391a467c5ef9668), + U64(0x335c7c1ee1319aca), U64(0xa91533b18641e4bb), + U64(0xe4bf9a683b79db0d), U64(0x8e20faa72ba0b470), + U64(0x51f907737b3a7ae4), U64(0x2268a314bed5ec8c), + U64(0xd944b123b949edee), U64(0x31dcb3b84d8b7017), + U64(0xd3fe65279f218860), U64(0x097af2f1dc8ffab3), + U64(0x9b09a6fc312d0b91), U64(0xcc6ded78a3c4520f), + U64(0x3481d9ba5ebfcc50), U64(0x4f2a667f1182d56b), + U64(0xdfd9fdd4509ace94), U64(0x26752045fbbc252b), + U64(0xbffc491f662bc467), U64(0xdd593272fc202449), + U64(0x3cbbc218d46d4303), U64(0x91b372f817456e1f), + U64(0x681faf69bc6385a0), U64(0xb686bbeebaa43ed4), + U64(0x1469b5084cd0ca01), U64(0x98c98009cbca94ac), + U64(0x6438379a73d8c354), U64(0xc2caba2dc0c5fe26), + U64(0x3e3b0dbe78d7a9de), U64(0x50b9ee202d670f04), + U64(0x4590b27b37eab0e5), U64(0x6025b4cb36b10af3), + U64(0xfb2c1237079c0162), U64(0xa12f28130c936be8), + U64(0x4b37e52e54eb1ccc), U64(0x083a1ba28ad28f53), + U64(0xc10a9cd83a22611b), U64(0x9f1425ad7444c236), + U64(0x069d4cf7e9d3237a), U64(0xedc56899e7f621be), + U64(0x778c273680865fcf), U64(0x309c5aeb1bd605f7), + U64(0x8de0dc52d1472b4d), U64(0xf8ec34c2fd7b9e5f), + U64(0xea18cd3d58787724), U64(0xaad515447ca67b86), + U64(0x9989695a9d97e14c), U64(0x0000000000000000), + U64(0xf196c63321f464ec), U64(0x71116bc169557cb5), + U64(0xaf887f466f92c7c1), U64(0x972e3e0ffe964d65), + U64(0x190ec4a8d536f915), U64(0x95aef1a9522ca7b8), + U64(0xdc19db21aa7d51a9), U64(0x94ee18fa0471d258), + U64(0x8087adf248a11859), U64(0xc457f6da2916dd5c), + U64(0xfa6cfb6451c17482), U64(0xf256e0c6db13fbd1), + U64(0x6a9f60cf10d96f7d), U64(0x4daaa9d9bd383fb6), + U64(0x03c026f5fae79f3d), U64(0xde99148706c7bb74), + U64(0x2a52b8b6340763df), U64(0x6fc20acd03edd33a), + U64(0xd423c08320afdefa), U64(0xbbe1ca4e23420dc0), + U64(0x966ed75ca8cb3885), U64(0xeb58246e0e2502c4), + U64(0x055d6a021334bc47), U64(0xa47242111fa7d7af), + U64(0xe3623fcc84f78d97), U64(0x81c744a11efc6db9), + U64(0xaec8961539cfb221), U64(0xf31609958d4e8e31), + U64(0x63e5923ecc5695ce), U64(0x47107ddd9b505a38), + U64(0xa3afe7b5a0298135), U64(0x792b7063e387f3e6), + U64(0x0140e953565d75e0), U64(0x12f4f9ffa503e97b), + U64(0x750ce8902c3cb512), U64(0xdbc47e8515f30733), + U64(0x1ed3610c6ab8af8f), U64(0x5239218681dde5d9), + U64(0xe222d69fd2aaf877), U64(0xfe71783514a8bd25), + U64(0xcaf0a18f4a177175), U64(0x61655d9860ec7f13), + U64(0xe77fbc9dc19e4430), U64(0x2ccff441ddd440a5), + U64(0x16e97aaee06a20dc), U64(0xa855dae2d01c915b), + U64(0x1d1347f9905f30b2), U64(0xb7c652bdecf94b34), + U64(0xd03e43d265c6175d), U64(0xfdb15ec0ee4f2218), + U64(0x57644b8492e9599e), U64(0x07dda5a4bf8e569a), + U64(0x54a46d71680ec6a3), U64(0x5624a2d7c4b42c7e), + U64(0xbebca04c3076b187), U64(0x7d36f332a6ee3a41), + U64(0x3b6667bc6be31599), U64(0x695f463aea3ef040), + U64(0xad08b0e0c3282d1c), U64(0xb15b1e4a052a684e), + U64(0x44d05b2861b7c505), U64(0x15295c5b1a8dbfe1), + U64(0x744c01c37a61c0f2), U64(0x59c31cd1f1e8f5b7), + U64(0xef45a73f4b4ccb63), U64(0x6bdf899c46841a9d), + U64(0x3dfb2b4b823036e3), U64(0xa2ef0ee6f674f4d5), + U64(0x184e2dfb836b8cf5), U64(0x1134df0a5fe47646), + U64(0xbaa1231d751f7820), U64(0xd17eaa81339b62bd), + U64(0xb01bf71953771dae), U64(0x849a2ea30dc8d1fe), + U64(0x705182923f080955), U64(0x0ea757556301ac29), + U64(0x041d83514569c9a7), U64(0x0abad4042668658e), + U64(0x49b72a88f851f611), U64(0x8a3d79f66ec97dd7), + U64(0xcd2d042bf59927ef), U64(0xc930877ab0f0ee48), + U64(0x9273540deda2f122), U64(0xc797d02fd3f14261), + U64(0xe1e2f06a284d674a), U64(0xd2be8c74c97cfd80), + U64(0x9a494faf67707e71), U64(0xb3dbd1eca9908293), + U64(0x72d14d3493b2e388), U64(0xd6a30f258c153427) + }, +}; + +static const STREEBOG_LONG64 C16[12][8] = { + { + U64(0xdd806559f2a64507), U64(0x05767436cc744d23), + U64(0xa2422a08a460d315), U64(0x4b7ce09192676901), + U64(0x714eb88d7585c4fc), U64(0x2f6a76432e45d016), + U64(0xebcb2f81c0657c1f), U64(0xb1085bda1ecadae9) + }, { + U64(0xe679047021b19bb7), U64(0x55dda21bd7cbcd56), + U64(0x5cb561c2db0aa7ca), U64(0x9ab5176b12d69958), + U64(0x61d55e0f16b50131), U64(0xf3feea720a232b98), + U64(0x4fe39d460f70b5d7), U64(0x6fa3b58aa99d2f1a) + }, { + U64(0x991e96f50aba0ab2), U64(0xc2b6f443867adb31), + U64(0xc1c93a376062db09), U64(0xd3e20fe490359eb1), + U64(0xf2ea7514b1297b7b), U64(0x06f15e5f529c1f8b), + U64(0x0a39fc286a3d8435), U64(0xf574dcac2bce2fc7) + }, { + U64(0x220cbebc84e3d12e), U64(0x3453eaa193e837f1), + U64(0xd8b71333935203be), U64(0xa9d72c82ed03d675), + U64(0x9d721cad685e353f), U64(0x488e857e335c3c7d), + U64(0xf948e1a05d71e4dd), U64(0xef1fdfb3e81566d2) + }, { + U64(0x601758fd7c6cfe57), U64(0x7a56a27ea9ea63f5), + U64(0xdfff00b723271a16), U64(0xbfcd1747253af5a3), + U64(0x359e35d7800fffbd), U64(0x7f151c1f1686104a), + U64(0x9a3f410c6ca92363), U64(0x4bea6bacad474799) + }, { + U64(0xfa68407a46647d6e), U64(0xbf71c57236904f35), + U64(0x0af21f66c2bec6b6), U64(0xcffaa6b71c9ab7b4), + U64(0x187f9ab49af08ec6), U64(0x2d66c4f95142a46c), + U64(0x6fa4c33b7a3039c0), U64(0xae4faeae1d3ad3d9) + }, { + U64(0x8886564d3a14d493), U64(0x3517454ca23c4af3), + U64(0x06476983284a0504), U64(0x0992abc52d822c37), + U64(0xd3473e33197a93c9), U64(0x399ec6c7e6bf87c9), + U64(0x51ac86febf240954), U64(0xf4c70e16eeaac5ec) + }, { + U64(0xa47f0dd4bf02e71e), U64(0x36acc2355951a8d9), + U64(0x69d18d2bd1a5c42f), U64(0xf4892bcb929b0690), + U64(0x89b4443b4ddbc49a), U64(0x4eb7f8719c36de1e), + U64(0x03e7aa020c6e4141), U64(0x9b1f5b424d93c9a7) + }, { + U64(0x7261445183235adb), U64(0x0e38dc92cb1f2a60), + U64(0x7b2b8a9aa6079c54), U64(0x800a440bdbb2ceb1), + U64(0x3cd955b7e00d0984), U64(0x3a7d3a1b25894224), + U64(0x944c9ad8ec165fde), U64(0x378f5a541631229b) + }, { + U64(0x74b4c7fb98459ced), U64(0x3698fad1153bb6c3), + U64(0x7a1e6c303b7652f4), U64(0x9fe76702af69334b), + U64(0x1fffe18a1b336103), U64(0x8941e71cff8a78db), + U64(0x382ae548b2e4f3f3), U64(0xabbedea680056f52) + }, { + U64(0x6bcaa4cd81f32d1b), U64(0xdea2594ac06fd85d), + U64(0xefbacd1d7d476e98), U64(0x8a1d71efea48b9ca), + U64(0x2001802114846679), U64(0xd8fa6bbbebab0761), + U64(0x3002c6cd635afe94), U64(0x7bcd9ed0efc889fb) + }, { + U64(0x48bc924af11bd720), U64(0xfaf417d5d9b21b99), + U64(0xe71da4aa88e12852), U64(0x5d80ef9d1891cc86), + U64(0xf82012d430219f9b), U64(0xcda43c32bcdf1d77), + U64(0xd21380b00449b17a), U64(0x378ee767f11631ba) + }, +}; + +#define B(x,i,j) (((STREEBOG_LONG64)(*(((const unsigned char *)(&x))+i)))<<(j*8)) +#define PULL64(x) (B(x,0,0)|B(x,1,1)|B(x,2,2)|B(x,3,3)|B(x,4,4)|B(x,5,5)|B(x,6,6)|B(x,7,7)) +#define SWAB64(x) (B(x,0,7)|B(x,1,6)|B(x,2,5)|B(x,3,4)|B(x,4,3)|B(x,5,2)|B(x,6,1)|B(x,7,0)) + +static inline STREEBOG_LONG64 +multipermute(const STREEBOG_LONG64 *in, int i) +{ + STREEBOG_LONG64 t = 0; + + t ^= A_PI_table[0][(in[0] >> (i * 8)) & 0xff]; + t ^= A_PI_table[1][(in[1] >> (i * 8)) & 0xff]; + t ^= A_PI_table[2][(in[2] >> (i * 8)) & 0xff]; + t ^= A_PI_table[3][(in[3] >> (i * 8)) & 0xff]; + t ^= A_PI_table[4][(in[4] >> (i * 8)) & 0xff]; + t ^= A_PI_table[5][(in[5] >> (i * 8)) & 0xff]; + t ^= A_PI_table[6][(in[6] >> (i * 8)) & 0xff]; + t ^= A_PI_table[7][(in[7] >> (i * 8)) & 0xff]; + + return t; +} + +static void +transform(STREEBOG_LONG64 *out, const STREEBOG_LONG64 *a, + const STREEBOG_LONG64 *b) +{ + STREEBOG_LONG64 tmp[8]; + + tmp[0] = a[0] ^ b[0]; + tmp[1] = a[1] ^ b[1]; + tmp[2] = a[2] ^ b[2]; + tmp[3] = a[3] ^ b[3]; + tmp[4] = a[4] ^ b[4]; + tmp[5] = a[5] ^ b[5]; + tmp[6] = a[6] ^ b[6]; + tmp[7] = a[7] ^ b[7]; + + out[0] = multipermute(tmp, 0); + out[1] = multipermute(tmp, 1); + out[2] = multipermute(tmp, 2); + out[3] = multipermute(tmp, 3); + out[4] = multipermute(tmp, 4); + out[5] = multipermute(tmp, 5); + out[6] = multipermute(tmp, 6); + out[7] = multipermute(tmp, 7); +} + +static inline void +gN(STREEBOG_LONG64 *h, STREEBOG_LONG64 *m, STREEBOG_LONG64 *N) +{ + STREEBOG_LONG64 K[8]; + STREEBOG_LONG64 T[8]; + int i; + + transform(K, h, N); + + transform(T, K, m); + transform(K, K, C16[0]); + for (i = 1; i < 12; i++) { + transform(T, K, T); + transform(K, K, C16[i]); + } + + h[0] ^= T[0] ^ K[0] ^ m[0]; + h[1] ^= T[1] ^ K[1] ^ m[1]; + h[2] ^= T[2] ^ K[2] ^ m[2]; + h[3] ^= T[3] ^ K[3] ^ m[3]; + h[4] ^= T[4] ^ K[4] ^ m[4]; + h[5] ^= T[5] ^ K[5] ^ m[5]; + h[6] ^= T[6] ^ K[6] ^ m[6]; + h[7] ^= T[7] ^ K[7] ^ m[7]; +} + + +static void +streebog_single_block(STREEBOG_CTX *ctx, const unsigned char *in, size_t num) +{ + STREEBOG_LONG64 M[8], l; + STREEBOG_LONG64 CF; + int i; + + for (i = 0; i < 8; i++) + M[i] = PULL64(in[i*8]); + + gN(ctx->h, M, ctx->N); + + l = ctx->N[0]; + ctx->N[0] += num; + + if (ctx->N[0] < l || ctx->N[0] < num) { + for (i = 1; i < 8; i++) { + ctx->N[i]++; + if (ctx->N[i] != 0) + break; + } + } + + CF = 0; + ctx->Sigma[0] += M[0]; + for (i = 1; i < 8; i++) { + if (ctx->Sigma[i-1] != M[i-1]) + CF = (ctx->Sigma[i-1] < M[i-1]); + ctx->Sigma[i] += M[i] + CF; + } +} + + + +static void +streebog_block_data_order(STREEBOG_CTX *ctx, const unsigned char *in, + size_t num) +{ + int i; + + for (i = 0; i < num; i++) + streebog_single_block(ctx, in + i * STREEBOG_CBLOCK, 64 * 8); +} + +int +STREEBOG512_Final(unsigned char *md, STREEBOG_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + STREEBOG_LONG64 Z[STREEBOG_LBLOCK] = {0}; + int n; + + if (c->num == STREEBOG_CBLOCK) { + streebog_block_data_order(c, p, 1); + c->num -= STREEBOG_CBLOCK; + } + + n = c->num; + p[n++] = 1; + memset(p + n, 0, STREEBOG_CBLOCK - n); + + streebog_single_block(c, p, c->num * 8); + + gN(c->h, c->N, Z); + gN(c->h, c->Sigma, Z); + + for (n = 0; n < STREEBOG_LBLOCK; n++) + c->h[n] = SWAB64(c->h[n]); + + if (md == NULL) + return 0; + + switch (c->md_len) { + /* Let compiler decide if it's appropriate to unroll... */ + case STREEBOG256_LENGTH: + for (n = 0; n < STREEBOG256_LENGTH / 8; n++) { + STREEBOG_LONG64 t = c->h[4+n]; + +#if BYTE_ORDER == BIG_ENDIAN + *(md++) = (unsigned char)(t); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 56); +#else + *(md++) = (unsigned char)(t >> 56); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t); +#endif + } + break; + case STREEBOG512_LENGTH: + for (n = 0; n < STREEBOG512_LENGTH / 8; n++) { + STREEBOG_LONG64 t = c->h[n]; + +#if BYTE_ORDER == BIG_ENDIAN + *(md++) = (unsigned char)(t); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 56); +#else + *(md++) = (unsigned char)(t >> 56); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t); +#endif + } + break; + /* ... as well as make sure md_len is not abused. */ + default: + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(STREEBOG512_Final); + +int +STREEBOG256_Final(unsigned char *md, STREEBOG_CTX * c) +{ + return STREEBOG512_Final(md, c); +} +LCRYPTO_ALIAS(STREEBOG256_Final); + +int +STREEBOG512_Update(STREEBOG_CTX *c, const void *_data, size_t len) +{ + unsigned char *p = (unsigned char *)c->data; + const unsigned char *data = (const unsigned char *)_data; + + if (len == 0) + return 1; + + if (c->num != 0) { + size_t n = STREEBOG_CBLOCK - c->num; + + if (len < n) { + memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return 1; + } else { + memcpy(p + c->num, data, n); + c->num = 0; + len -= n; + data += n; + streebog_block_data_order(c, p, 1); + } + } + + if (len >= STREEBOG_CBLOCK) { + streebog_block_data_order(c, data, len / STREEBOG_CBLOCK); + data += len; + len %= STREEBOG_CBLOCK; + data -= len; + } + + if (len != 0) { + memcpy(p, data, len); + c->num = (int)len; + } + + return 1; +} +LCRYPTO_ALIAS(STREEBOG512_Update); + +int +STREEBOG256_Update(STREEBOG_CTX *c, const void *data, size_t len) +{ + return STREEBOG512_Update(c, data, len); +} +LCRYPTO_ALIAS(STREEBOG256_Update); + +void +STREEBOG512_Transform(STREEBOG_CTX *c, const unsigned char *data) +{ + streebog_block_data_order(c, data, 1); +} +LCRYPTO_ALIAS(STREEBOG512_Transform); + +int +STREEBOG256_Init(STREEBOG_CTX *c) +{ + memset(c, 0, sizeof(*c)); + memset(c->h, 1, sizeof(c->h)); + + c->md_len = STREEBOG256_LENGTH; + return 1; +} +LCRYPTO_ALIAS(STREEBOG256_Init); + +int +STREEBOG512_Init(STREEBOG_CTX *c) +{ + memset(c, 0, sizeof(*c)); + memset(c->h, 0, sizeof(c->h)); + + c->num = 0; + c->md_len = STREEBOG512_LENGTH; + return 1; +} +LCRYPTO_ALIAS(STREEBOG512_Init); + +unsigned char * +STREEBOG256(const unsigned char *d, size_t n, unsigned char *md) +{ + STREEBOG_CTX c; + static unsigned char m[STREEBOG256_LENGTH]; + + if (md == NULL) + md = m; + STREEBOG256_Init(&c); + STREEBOG256_Update(&c, d, n); + STREEBOG256_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} +LCRYPTO_ALIAS(STREEBOG256); + +unsigned char * +STREEBOG512(const unsigned char *d, size_t n, unsigned char *md) +{ + STREEBOG_CTX c; + static unsigned char m[STREEBOG512_LENGTH]; + + if (md == NULL) + md = m; + STREEBOG512_Init(&c); + STREEBOG512_Update(&c, d, n); + STREEBOG512_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} +LCRYPTO_ALIAS(STREEBOG512); + +#endif diff --git a/Libraries/libressl/crypto/hidden/crypto_namespace.h b/Libraries/libressl/crypto/hidden/crypto_namespace.h new file mode 100644 index 000000000..85e62ba03 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/crypto_namespace.h @@ -0,0 +1,51 @@ +/* $OpenBSD: crypto_namespace.h,v 1.2 2023/02/16 08:38:17 tb Exp $ */ +/* + * Copyright (c) 2016 Philip Guenther + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CRYPTO_NAMESPACE_H_ +#define _LIBCRYPTO_CRYPTO_NAMESPACE_H_ + +/* + * If marked as 'used', then internal calls use the name with prefix "_lcry_" + * and we alias that to the normal name *and* the name with prefix "_libre_"; + * external calls use the latter name. + */ + +#ifdef _MSC_VER +# define LCRYPTO_UNUSED(x) +# define LCRYPTO_USED(x) +# define LCRYPTO_ALIAS1(pre, x) +# define LCRYPTO_ALIAS(x) +#else +#ifdef LIBRESSL_NAMESPACE +# define LCRYPTO_UNUSED(x) typeof(x) x __attribute__((deprecated)) +#ifdef LIBRESSL_CRYPTO_NAMESPACE +# define LCRYPTO_USED(x) __attribute__((visibility("hidden"))) \ + typeof(x) x asm("_lcry_"#x) +# define LCRYPTO_ALIAS1(pre,x) asm(".global "#pre#x"; "#pre#x" = _lcry_"#x) +# define LCRYPTO_ALIAS(x) LCRYPTO_ALIAS1(,x); LCRYPTO_ALIAS1(_libre_,x) +#else +# define LCRYPTO_USED(x) typeof(x) x asm("_libre_"#x) +#endif +#else +# define LCRYPTO_UNUSED(x) +# define LCRYPTO_USED(x) +# define LCRYPTO_ALIAS1(pre,x) +# define LCRYPTO_ALIAS(x) asm("") +#endif +#endif /* _MSC_VER */ + +#endif /* _LIBCRYPTO_CRYPTO_NAMESPACE_H_ */ diff --git a/Libraries/libressl/crypto/hidden/openssl/asn1.h b/Libraries/libressl/crypto/hidden/openssl/asn1.h new file mode 100644 index 000000000..fb1393f2a --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/asn1.h @@ -0,0 +1,253 @@ +/* $OpenBSD: asn1.h,v 1.6 2023/07/28 10:33:13 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_ASN1_H +#define _LIBCRYPTO_ASN1_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/asn1.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(d2i_ASN1_SEQUENCE_ANY); +LCRYPTO_USED(i2d_ASN1_SEQUENCE_ANY); +LCRYPTO_USED(d2i_ASN1_SET_ANY); +LCRYPTO_USED(i2d_ASN1_SET_ANY); +LCRYPTO_USED(ASN1_TYPE_new); +LCRYPTO_USED(ASN1_TYPE_free); +LCRYPTO_USED(d2i_ASN1_TYPE); +LCRYPTO_USED(i2d_ASN1_TYPE); +LCRYPTO_USED(ASN1_TYPE_get); +LCRYPTO_USED(ASN1_TYPE_set); +LCRYPTO_USED(ASN1_TYPE_set1); +LCRYPTO_USED(ASN1_TYPE_cmp); +LCRYPTO_USED(ASN1_OBJECT_new); +LCRYPTO_USED(ASN1_OBJECT_free); +LCRYPTO_USED(i2d_ASN1_OBJECT); +LCRYPTO_USED(d2i_ASN1_OBJECT); +LCRYPTO_USED(ASN1_STRING_new); +LCRYPTO_USED(ASN1_STRING_free); +LCRYPTO_USED(ASN1_STRING_copy); +LCRYPTO_USED(ASN1_STRING_dup); +LCRYPTO_USED(ASN1_STRING_type_new); +LCRYPTO_USED(ASN1_STRING_cmp); +LCRYPTO_USED(ASN1_STRING_set); +LCRYPTO_USED(ASN1_STRING_set0); +LCRYPTO_USED(ASN1_STRING_length); +LCRYPTO_USED(ASN1_STRING_length_set); +LCRYPTO_USED(ASN1_STRING_type); +LCRYPTO_USED(ASN1_STRING_data); +LCRYPTO_USED(ASN1_STRING_get0_data); +LCRYPTO_USED(ASN1_BIT_STRING_new); +LCRYPTO_USED(ASN1_BIT_STRING_free); +LCRYPTO_USED(d2i_ASN1_BIT_STRING); +LCRYPTO_USED(i2d_ASN1_BIT_STRING); +LCRYPTO_USED(ASN1_BIT_STRING_set); +LCRYPTO_USED(ASN1_BIT_STRING_set_bit); +LCRYPTO_USED(ASN1_BIT_STRING_get_bit); +LCRYPTO_USED(ASN1_INTEGER_new); +LCRYPTO_USED(ASN1_INTEGER_free); +LCRYPTO_USED(d2i_ASN1_INTEGER); +LCRYPTO_USED(i2d_ASN1_INTEGER); +LCRYPTO_USED(d2i_ASN1_UINTEGER); +LCRYPTO_USED(ASN1_INTEGER_dup); +LCRYPTO_USED(ASN1_INTEGER_cmp); +LCRYPTO_USED(ASN1_ENUMERATED_new); +LCRYPTO_USED(ASN1_ENUMERATED_free); +LCRYPTO_USED(d2i_ASN1_ENUMERATED); +LCRYPTO_USED(i2d_ASN1_ENUMERATED); +LCRYPTO_USED(ASN1_UTCTIME_check); +LCRYPTO_USED(ASN1_UTCTIME_set); +LCRYPTO_USED(ASN1_UTCTIME_adj); +LCRYPTO_USED(ASN1_UTCTIME_set_string); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_check); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_set); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_adj); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_set_string); +LCRYPTO_USED(ASN1_OCTET_STRING_new); +LCRYPTO_USED(ASN1_OCTET_STRING_free); +LCRYPTO_USED(d2i_ASN1_OCTET_STRING); +LCRYPTO_USED(i2d_ASN1_OCTET_STRING); +LCRYPTO_USED(ASN1_OCTET_STRING_dup); +LCRYPTO_USED(ASN1_OCTET_STRING_cmp); +LCRYPTO_USED(ASN1_OCTET_STRING_set); +LCRYPTO_USED(ASN1_VISIBLESTRING_new); +LCRYPTO_USED(ASN1_VISIBLESTRING_free); +LCRYPTO_USED(d2i_ASN1_VISIBLESTRING); +LCRYPTO_USED(i2d_ASN1_VISIBLESTRING); +LCRYPTO_USED(ASN1_UNIVERSALSTRING_new); +LCRYPTO_USED(ASN1_UNIVERSALSTRING_free); +LCRYPTO_USED(d2i_ASN1_UNIVERSALSTRING); +LCRYPTO_USED(i2d_ASN1_UNIVERSALSTRING); +LCRYPTO_USED(ASN1_UTF8STRING_new); +LCRYPTO_USED(ASN1_UTF8STRING_free); +LCRYPTO_USED(d2i_ASN1_UTF8STRING); +LCRYPTO_USED(i2d_ASN1_UTF8STRING); +LCRYPTO_USED(ASN1_NULL_new); +LCRYPTO_USED(ASN1_NULL_free); +LCRYPTO_USED(d2i_ASN1_NULL); +LCRYPTO_USED(i2d_ASN1_NULL); +LCRYPTO_USED(ASN1_BMPSTRING_new); +LCRYPTO_USED(ASN1_BMPSTRING_free); +LCRYPTO_USED(d2i_ASN1_BMPSTRING); +LCRYPTO_USED(i2d_ASN1_BMPSTRING); +LCRYPTO_USED(ASN1_PRINTABLE_new); +LCRYPTO_USED(ASN1_PRINTABLE_free); +LCRYPTO_USED(d2i_ASN1_PRINTABLE); +LCRYPTO_USED(i2d_ASN1_PRINTABLE); +LCRYPTO_USED(DIRECTORYSTRING_new); +LCRYPTO_USED(DIRECTORYSTRING_free); +LCRYPTO_USED(d2i_DIRECTORYSTRING); +LCRYPTO_USED(i2d_DIRECTORYSTRING); +LCRYPTO_USED(DISPLAYTEXT_new); +LCRYPTO_USED(DISPLAYTEXT_free); +LCRYPTO_USED(d2i_DISPLAYTEXT); +LCRYPTO_USED(i2d_DISPLAYTEXT); +LCRYPTO_USED(ASN1_PRINTABLESTRING_new); +LCRYPTO_USED(ASN1_PRINTABLESTRING_free); +LCRYPTO_USED(d2i_ASN1_PRINTABLESTRING); +LCRYPTO_USED(i2d_ASN1_PRINTABLESTRING); +LCRYPTO_USED(ASN1_T61STRING_new); +LCRYPTO_USED(ASN1_T61STRING_free); +LCRYPTO_USED(d2i_ASN1_T61STRING); +LCRYPTO_USED(i2d_ASN1_T61STRING); +LCRYPTO_USED(ASN1_IA5STRING_new); +LCRYPTO_USED(ASN1_IA5STRING_free); +LCRYPTO_USED(d2i_ASN1_IA5STRING); +LCRYPTO_USED(i2d_ASN1_IA5STRING); +LCRYPTO_USED(ASN1_GENERALSTRING_new); +LCRYPTO_USED(ASN1_GENERALSTRING_free); +LCRYPTO_USED(d2i_ASN1_GENERALSTRING); +LCRYPTO_USED(i2d_ASN1_GENERALSTRING); +LCRYPTO_USED(ASN1_UTCTIME_new); +LCRYPTO_USED(ASN1_UTCTIME_free); +LCRYPTO_USED(d2i_ASN1_UTCTIME); +LCRYPTO_USED(i2d_ASN1_UTCTIME); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_new); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_free); +LCRYPTO_USED(d2i_ASN1_GENERALIZEDTIME); +LCRYPTO_USED(i2d_ASN1_GENERALIZEDTIME); +LCRYPTO_USED(ASN1_TIME_new); +LCRYPTO_USED(ASN1_TIME_free); +LCRYPTO_USED(d2i_ASN1_TIME); +LCRYPTO_USED(i2d_ASN1_TIME); +LCRYPTO_USED(ASN1_TIME_to_tm); +LCRYPTO_USED(ASN1_TIME_compare); +LCRYPTO_USED(ASN1_TIME_cmp_time_t); +LCRYPTO_USED(ASN1_TIME_normalize); +LCRYPTO_USED(ASN1_TIME_set_string_X509); +LCRYPTO_USED(ASN1_TIME_diff); +LCRYPTO_USED(ASN1_TIME_set); +LCRYPTO_USED(ASN1_TIME_set_tm); +LCRYPTO_USED(ASN1_TIME_adj); +LCRYPTO_USED(ASN1_TIME_check); +LCRYPTO_USED(ASN1_TIME_to_generalizedtime); +LCRYPTO_USED(ASN1_TIME_set_string); +LCRYPTO_USED(i2a_ASN1_INTEGER); +LCRYPTO_USED(a2i_ASN1_INTEGER); +LCRYPTO_USED(i2a_ASN1_ENUMERATED); +LCRYPTO_USED(a2i_ASN1_ENUMERATED); +LCRYPTO_USED(i2a_ASN1_OBJECT); +LCRYPTO_USED(a2i_ASN1_STRING); +LCRYPTO_USED(i2a_ASN1_STRING); +LCRYPTO_USED(i2t_ASN1_OBJECT); +LCRYPTO_USED(a2d_ASN1_OBJECT); +LCRYPTO_USED(ASN1_OBJECT_create); +LCRYPTO_USED(ASN1_INTEGER_get_uint64); +LCRYPTO_USED(ASN1_INTEGER_set_uint64); +LCRYPTO_USED(ASN1_INTEGER_get_int64); +LCRYPTO_USED(ASN1_INTEGER_set_int64); +LCRYPTO_USED(ASN1_INTEGER_set); +LCRYPTO_USED(ASN1_INTEGER_get); +LCRYPTO_USED(BN_to_ASN1_INTEGER); +LCRYPTO_USED(ASN1_INTEGER_to_BN); +LCRYPTO_USED(ASN1_ENUMERATED_get_int64); +LCRYPTO_USED(ASN1_ENUMERATED_set_int64); +LCRYPTO_USED(ASN1_ENUMERATED_set); +LCRYPTO_USED(ASN1_ENUMERATED_get); +LCRYPTO_USED(BN_to_ASN1_ENUMERATED); +LCRYPTO_USED(ASN1_ENUMERATED_to_BN); +LCRYPTO_USED(ASN1_PRINTABLE_type); +LCRYPTO_USED(ASN1_get_object); +LCRYPTO_USED(ASN1_put_object); +LCRYPTO_USED(ASN1_put_eoc); +LCRYPTO_USED(ASN1_object_size); +LCRYPTO_USED(ASN1_item_dup); +LCRYPTO_USED(ASN1_d2i_fp); +LCRYPTO_USED(ASN1_item_d2i_fp); +LCRYPTO_USED(ASN1_i2d_fp); +LCRYPTO_USED(ASN1_item_i2d_fp); +LCRYPTO_USED(ASN1_STRING_print_ex_fp); +LCRYPTO_USED(ASN1_STRING_to_UTF8); +LCRYPTO_USED(ASN1_d2i_bio); +LCRYPTO_USED(ASN1_item_d2i_bio); +LCRYPTO_USED(ASN1_i2d_bio); +LCRYPTO_USED(ASN1_item_i2d_bio); +LCRYPTO_USED(ASN1_UTCTIME_print); +LCRYPTO_USED(ASN1_GENERALIZEDTIME_print); +LCRYPTO_USED(ASN1_TIME_print); +LCRYPTO_USED(ASN1_STRING_print); +LCRYPTO_USED(ASN1_STRING_print_ex); +LCRYPTO_USED(ASN1_parse); +LCRYPTO_USED(ASN1_parse_dump); +LCRYPTO_USED(ASN1_tag2bit); +LCRYPTO_USED(ASN1_tag2str); +LCRYPTO_USED(ASN1_UNIVERSALSTRING_to_string); +LCRYPTO_USED(ASN1_TYPE_set_octetstring); +LCRYPTO_USED(ASN1_TYPE_get_octetstring); +LCRYPTO_USED(ASN1_TYPE_set_int_octetstring); +LCRYPTO_USED(ASN1_TYPE_get_int_octetstring); +LCRYPTO_USED(ASN1_item_pack); +LCRYPTO_USED(ASN1_item_unpack); +LCRYPTO_USED(ASN1_STRING_set_default_mask); +LCRYPTO_USED(ASN1_STRING_set_default_mask_asc); +LCRYPTO_USED(ASN1_STRING_get_default_mask); +LCRYPTO_USED(ASN1_mbstring_copy); +LCRYPTO_USED(ASN1_mbstring_ncopy); +LCRYPTO_USED(ASN1_STRING_set_by_NID); +LCRYPTO_USED(ASN1_STRING_TABLE_get); +LCRYPTO_USED(ASN1_STRING_TABLE_add); +LCRYPTO_USED(ASN1_STRING_TABLE_cleanup); +LCRYPTO_USED(ASN1_item_new); +LCRYPTO_USED(ASN1_item_free); +LCRYPTO_USED(ASN1_item_d2i); +LCRYPTO_USED(ASN1_item_i2d); +LCRYPTO_USED(ASN1_add_oid_module); +LCRYPTO_USED(ASN1_generate_nconf); +LCRYPTO_USED(ASN1_generate_v3); +LCRYPTO_USED(ASN1_item_print); +LCRYPTO_USED(ASN1_PCTX_new); +LCRYPTO_USED(ASN1_PCTX_free); +LCRYPTO_USED(ASN1_PCTX_get_flags); +LCRYPTO_USED(ASN1_PCTX_set_flags); +LCRYPTO_USED(ASN1_PCTX_get_nm_flags); +LCRYPTO_USED(ASN1_PCTX_set_nm_flags); +LCRYPTO_USED(ASN1_PCTX_get_cert_flags); +LCRYPTO_USED(ASN1_PCTX_set_cert_flags); +LCRYPTO_USED(ASN1_PCTX_get_oid_flags); +LCRYPTO_USED(ASN1_PCTX_set_oid_flags); +LCRYPTO_USED(ASN1_PCTX_get_str_flags); +LCRYPTO_USED(ASN1_PCTX_set_str_flags); +LCRYPTO_USED(SMIME_crlf_copy); +LCRYPTO_USED(SMIME_text); +LCRYPTO_USED(ERR_load_ASN1_strings); +LCRYPTO_USED(ASN1_time_parse); +LCRYPTO_USED(ASN1_time_tm_cmp); + +#endif /* _LIBCRYPTO_ASN1_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/asn1t.h b/Libraries/libressl/crypto/hidden/openssl/asn1t.h new file mode 100644 index 000000000..666dea564 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/asn1t.h @@ -0,0 +1,33 @@ +/* $OpenBSD: asn1t.h,v 1.3 2023/07/28 10:00:10 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_ASN1T_H +#define _LIBCRYPTO_ASN1T_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/asn1t.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(ASN1_item_ex_new); +LCRYPTO_USED(ASN1_item_ex_free); +LCRYPTO_USED(ASN1_item_ex_d2i); +LCRYPTO_USED(ASN1_item_ex_i2d); + +#endif /* _LIBCRYPTO_ASN1T_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/bio.h b/Libraries/libressl/crypto/hidden/openssl/bio.h new file mode 100644 index 000000000..f7e7cd3d8 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/bio.h @@ -0,0 +1,146 @@ +/* $OpenBSD: bio.h,v 1.4 2023/07/28 10:13:50 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_BIO_H +#define _LIBCRYPTO_BIO_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/bio.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(BIO_set_flags); +LCRYPTO_USED(BIO_test_flags); +LCRYPTO_USED(BIO_clear_flags); +LCRYPTO_USED(BIO_get_callback); +LCRYPTO_USED(BIO_set_callback); +LCRYPTO_USED(BIO_get_callback_ex); +LCRYPTO_USED(BIO_set_callback_ex); +LCRYPTO_USED(BIO_get_callback_arg); +LCRYPTO_USED(BIO_set_callback_arg); +LCRYPTO_USED(BIO_method_name); +LCRYPTO_USED(BIO_method_type); +LCRYPTO_USED(BIO_meth_new); +LCRYPTO_USED(BIO_meth_free); +LCRYPTO_USED(BIO_meth_get_write); +LCRYPTO_USED(BIO_meth_set_write); +LCRYPTO_USED(BIO_meth_get_read); +LCRYPTO_USED(BIO_meth_set_read); +LCRYPTO_USED(BIO_meth_get_puts); +LCRYPTO_USED(BIO_meth_set_puts); +LCRYPTO_USED(BIO_meth_get_gets); +LCRYPTO_USED(BIO_meth_set_gets); +LCRYPTO_USED(BIO_meth_get_ctrl); +LCRYPTO_USED(BIO_meth_set_ctrl); +LCRYPTO_USED(BIO_meth_get_create); +LCRYPTO_USED(BIO_meth_set_create); +LCRYPTO_USED(BIO_meth_get_destroy); +LCRYPTO_USED(BIO_meth_set_destroy); +LCRYPTO_USED(BIO_meth_get_callback_ctrl); +LCRYPTO_USED(BIO_meth_set_callback_ctrl); +LCRYPTO_USED(BIO_ctrl_pending); +LCRYPTO_USED(BIO_ctrl_wpending); +LCRYPTO_USED(BIO_ctrl_get_write_guarantee); +LCRYPTO_USED(BIO_ctrl_get_read_request); +LCRYPTO_USED(BIO_ctrl_reset_read_request); +LCRYPTO_USED(BIO_set_ex_data); +LCRYPTO_USED(BIO_get_ex_data); +LCRYPTO_USED(BIO_number_read); +LCRYPTO_USED(BIO_number_written); +LCRYPTO_USED(BIO_get_new_index); +LCRYPTO_USED(BIO_s_file); +LCRYPTO_USED(BIO_new_file); +LCRYPTO_USED(BIO_new_fp); +LCRYPTO_USED(BIO_new); +LCRYPTO_USED(BIO_set); +LCRYPTO_USED(BIO_free); +LCRYPTO_USED(BIO_up_ref); +LCRYPTO_USED(BIO_get_data); +LCRYPTO_USED(BIO_set_data); +LCRYPTO_USED(BIO_get_init); +LCRYPTO_USED(BIO_set_init); +LCRYPTO_USED(BIO_get_shutdown); +LCRYPTO_USED(BIO_set_shutdown); +LCRYPTO_USED(BIO_vfree); +LCRYPTO_USED(BIO_read); +LCRYPTO_USED(BIO_gets); +LCRYPTO_USED(BIO_write); +LCRYPTO_USED(BIO_puts); +LCRYPTO_USED(BIO_indent); +LCRYPTO_USED(BIO_ctrl); +LCRYPTO_USED(BIO_callback_ctrl); +LCRYPTO_USED(BIO_ptr_ctrl); +LCRYPTO_USED(BIO_int_ctrl); +LCRYPTO_USED(BIO_push); +LCRYPTO_USED(BIO_pop); +LCRYPTO_USED(BIO_free_all); +LCRYPTO_USED(BIO_find_type); +LCRYPTO_USED(BIO_next); +LCRYPTO_USED(BIO_set_next); +LCRYPTO_USED(BIO_get_retry_BIO); +LCRYPTO_USED(BIO_get_retry_reason); +LCRYPTO_USED(BIO_set_retry_reason); +LCRYPTO_USED(BIO_dup_chain); +LCRYPTO_USED(BIO_debug_callback); +LCRYPTO_USED(BIO_s_mem); +LCRYPTO_USED(BIO_new_mem_buf); +LCRYPTO_USED(BIO_s_socket); +LCRYPTO_USED(BIO_s_connect); +LCRYPTO_USED(BIO_s_accept); +LCRYPTO_USED(BIO_s_fd); +LCRYPTO_USED(BIO_s_log); +LCRYPTO_USED(BIO_s_bio); +LCRYPTO_USED(BIO_s_null); +LCRYPTO_USED(BIO_f_null); +LCRYPTO_USED(BIO_f_buffer); +LCRYPTO_USED(BIO_f_nbio_test); +LCRYPTO_USED(BIO_s_datagram); +LCRYPTO_USED(BIO_sock_should_retry); +LCRYPTO_USED(BIO_sock_non_fatal_error); +LCRYPTO_USED(BIO_dgram_non_fatal_error); +LCRYPTO_USED(BIO_fd_should_retry); +LCRYPTO_USED(BIO_fd_non_fatal_error); +LCRYPTO_USED(BIO_dump); +LCRYPTO_USED(BIO_dump_indent); +LCRYPTO_USED(BIO_dump_fp); +LCRYPTO_USED(BIO_dump_indent_fp); +LCRYPTO_USED(BIO_gethostbyname); +LCRYPTO_USED(BIO_sock_error); +LCRYPTO_USED(BIO_socket_ioctl); +LCRYPTO_USED(BIO_socket_nbio); +LCRYPTO_USED(BIO_get_port); +LCRYPTO_USED(BIO_get_host_ip); +LCRYPTO_USED(BIO_get_accept_socket); +LCRYPTO_USED(BIO_accept); +LCRYPTO_USED(BIO_sock_init); +LCRYPTO_USED(BIO_sock_cleanup); +LCRYPTO_USED(BIO_set_tcp_ndelay); +LCRYPTO_USED(BIO_new_socket); +LCRYPTO_USED(BIO_new_dgram); +LCRYPTO_USED(BIO_new_fd); +LCRYPTO_USED(BIO_new_connect); +LCRYPTO_USED(BIO_new_accept); +LCRYPTO_USED(BIO_copy_next_retry); +LCRYPTO_USED(BIO_printf); +LCRYPTO_USED(BIO_vprintf); +LCRYPTO_USED(BIO_snprintf); +LCRYPTO_USED(BIO_vsnprintf); +LCRYPTO_USED(ERR_load_BIO_strings); + +#endif /* _LIBCRYPTO_BIO_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/bn.h b/Libraries/libressl/crypto/hidden/openssl/bn.h new file mode 100644 index 000000000..9942cf6fc --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/bn.h @@ -0,0 +1,143 @@ +/* $OpenBSD: bn.h,v 1.4 2023/07/29 03:13:38 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_BN_H +#define _LIBCRYPTO_BN_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/bn.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(BN_set_flags); +LCRYPTO_USED(BN_get_flags); +LCRYPTO_USED(BN_with_flags); +LCRYPTO_USED(BN_GENCB_new); +LCRYPTO_USED(BN_GENCB_free); +LCRYPTO_USED(BN_GENCB_call); +LCRYPTO_USED(BN_GENCB_set_old); +LCRYPTO_USED(BN_GENCB_set); +LCRYPTO_USED(BN_GENCB_get_arg); +LCRYPTO_USED(BN_abs_is_word); +LCRYPTO_USED(BN_is_zero); +LCRYPTO_USED(BN_is_one); +LCRYPTO_USED(BN_is_word); +LCRYPTO_USED(BN_is_odd); +LCRYPTO_USED(BN_zero); +LCRYPTO_USED(BN_one); +LCRYPTO_USED(BN_value_one); +LCRYPTO_USED(BN_CTX_new); +LCRYPTO_USED(BN_CTX_free); +LCRYPTO_USED(BN_CTX_start); +LCRYPTO_USED(BN_CTX_get); +LCRYPTO_USED(BN_CTX_end); +LCRYPTO_USED(BN_rand); +LCRYPTO_USED(BN_pseudo_rand); +LCRYPTO_USED(BN_rand_range); +LCRYPTO_USED(BN_pseudo_rand_range); +LCRYPTO_USED(BN_num_bits); +LCRYPTO_USED(BN_num_bits_word); +LCRYPTO_USED(BN_new); +LCRYPTO_USED(BN_clear_free); +LCRYPTO_USED(BN_copy); +LCRYPTO_USED(BN_swap); +LCRYPTO_USED(BN_bin2bn); +LCRYPTO_USED(BN_bn2bin); +LCRYPTO_USED(BN_bn2binpad); +LCRYPTO_USED(BN_lebin2bn); +LCRYPTO_USED(BN_bn2lebinpad); +LCRYPTO_USED(BN_mpi2bn); +LCRYPTO_USED(BN_bn2mpi); +LCRYPTO_USED(BN_sub); +LCRYPTO_USED(BN_usub); +LCRYPTO_USED(BN_uadd); +LCRYPTO_USED(BN_add); +LCRYPTO_USED(BN_mul); +LCRYPTO_USED(BN_sqr); +LCRYPTO_USED(BN_set_negative); +LCRYPTO_USED(BN_is_negative); +LCRYPTO_USED(BN_nnmod); +LCRYPTO_USED(BN_mod_add); +LCRYPTO_USED(BN_mod_add_quick); +LCRYPTO_USED(BN_mod_sub); +LCRYPTO_USED(BN_mod_sub_quick); +LCRYPTO_USED(BN_mod_mul); +LCRYPTO_USED(BN_mod_sqr); +LCRYPTO_USED(BN_mod_lshift1); +LCRYPTO_USED(BN_mod_lshift1_quick); +LCRYPTO_USED(BN_mod_lshift); +LCRYPTO_USED(BN_mod_lshift_quick); +LCRYPTO_USED(BN_mod_word); +LCRYPTO_USED(BN_div_word); +LCRYPTO_USED(BN_mul_word); +LCRYPTO_USED(BN_add_word); +LCRYPTO_USED(BN_sub_word); +LCRYPTO_USED(BN_set_word); +LCRYPTO_USED(BN_get_word); +LCRYPTO_USED(BN_cmp); +LCRYPTO_USED(BN_free); +LCRYPTO_USED(BN_is_bit_set); +LCRYPTO_USED(BN_lshift); +LCRYPTO_USED(BN_lshift1); +LCRYPTO_USED(BN_exp); +LCRYPTO_USED(BN_mod_exp_mont_consttime); +LCRYPTO_USED(BN_mod_exp_mont_word); +LCRYPTO_USED(BN_mod_exp2_mont); +LCRYPTO_USED(BN_mod_exp_simple); +LCRYPTO_USED(BN_mask_bits); +LCRYPTO_USED(BN_print_fp); +LCRYPTO_USED(BN_print); +LCRYPTO_USED(BN_rshift); +LCRYPTO_USED(BN_rshift1); +LCRYPTO_USED(BN_clear); +LCRYPTO_USED(BN_dup); +LCRYPTO_USED(BN_ucmp); +LCRYPTO_USED(BN_set_bit); +LCRYPTO_USED(BN_clear_bit); +LCRYPTO_USED(BN_bn2hex); +LCRYPTO_USED(BN_bn2dec); +LCRYPTO_USED(BN_hex2bn); +LCRYPTO_USED(BN_dec2bn); +LCRYPTO_USED(BN_asc2bn); +LCRYPTO_USED(BN_kronecker); +LCRYPTO_USED(BN_mod_sqrt); +LCRYPTO_USED(BN_consttime_swap); +LCRYPTO_USED(BN_security_bits); +LCRYPTO_USED(BN_generate_prime_ex); +LCRYPTO_USED(BN_is_prime_ex); +LCRYPTO_USED(BN_is_prime_fasttest_ex); +LCRYPTO_USED(BN_MONT_CTX_new); +LCRYPTO_USED(BN_mod_mul_montgomery); +LCRYPTO_USED(BN_to_montgomery); +LCRYPTO_USED(BN_from_montgomery); +LCRYPTO_USED(BN_MONT_CTX_free); +LCRYPTO_USED(BN_MONT_CTX_set); +LCRYPTO_USED(BN_MONT_CTX_copy); +LCRYPTO_USED(BN_MONT_CTX_set_locked); +LCRYPTO_USED(BN_get_rfc2409_prime_768); +LCRYPTO_USED(BN_get_rfc2409_prime_1024); +LCRYPTO_USED(BN_get_rfc3526_prime_1536); +LCRYPTO_USED(BN_get_rfc3526_prime_2048); +LCRYPTO_USED(BN_get_rfc3526_prime_3072); +LCRYPTO_USED(BN_get_rfc3526_prime_4096); +LCRYPTO_USED(BN_get_rfc3526_prime_6144); +LCRYPTO_USED(BN_get_rfc3526_prime_8192); +LCRYPTO_USED(ERR_load_BN_strings); + +#endif /* _LIBCRYPTO_BN_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/buffer.h b/Libraries/libressl/crypto/hidden/openssl/buffer.h new file mode 100644 index 000000000..8dd86277f --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/buffer.h @@ -0,0 +1,34 @@ +/* $OpenBSD: buffer.h,v 1.1 2023/07/08 08:26:26 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_BUFFER_H +#define _LIBCRYPTO_BUFFER_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/buffer.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(BUF_MEM_new); +LCRYPTO_USED(BUF_MEM_free); +LCRYPTO_USED(BUF_MEM_grow); +LCRYPTO_USED(BUF_MEM_grow_clean); +LCRYPTO_USED(ERR_load_BUF_strings); + +#endif /* _LIBCRYPTO_BUFFER_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/cast.h b/Libraries/libressl/crypto/hidden/openssl/cast.h new file mode 100644 index 000000000..68cf61826 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/cast.h @@ -0,0 +1,36 @@ +/* $OpenBSD: cast.h,v 1.1 2023/07/08 10:44:00 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CAST_H +#define _LIBCRYPTO_CAST_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/cast.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(CAST_set_key); +LCRYPTO_USED(CAST_ecb_encrypt); +LCRYPTO_USED(CAST_encrypt); +LCRYPTO_USED(CAST_decrypt); +LCRYPTO_USED(CAST_cbc_encrypt); +LCRYPTO_USED(CAST_cfb64_encrypt); +LCRYPTO_USED(CAST_ofb64_encrypt); + +#endif /* _LIBCRYPTO_CAST_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/chacha.h b/Libraries/libressl/crypto/hidden/openssl/chacha.h new file mode 100644 index 000000000..a9f3b7e90 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/chacha.h @@ -0,0 +1,35 @@ +/* $OpenBSD: chacha.h,v 1.3 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CHACHA_H +#define _LIBCRYPTO_CHACHA_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/chacha.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(ChaCha_set_key); +LCRYPTO_USED(ChaCha_set_iv); +LCRYPTO_USED(ChaCha); +LCRYPTO_USED(CRYPTO_chacha_20); +LCRYPTO_USED(CRYPTO_xchacha_20); +LCRYPTO_USED(CRYPTO_hchacha_20); + +#endif /* _LIBCRYPTO_CHACHA_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/cmac.h b/Libraries/libressl/crypto/hidden/openssl/cmac.h new file mode 100644 index 000000000..cefdb4f6e --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/cmac.h @@ -0,0 +1,38 @@ +/* $OpenBSD: cmac.h,v 1.1 2023/07/08 14:27:14 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CMAC_H +#define _LIBCRYPTO_CMAC_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/cmac.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(CMAC_CTX_new); +LCRYPTO_USED(CMAC_CTX_cleanup); +LCRYPTO_USED(CMAC_CTX_free); +LCRYPTO_USED(CMAC_CTX_get0_cipher_ctx); +LCRYPTO_USED(CMAC_CTX_copy); +LCRYPTO_USED(CMAC_Init); +LCRYPTO_USED(CMAC_Update); +LCRYPTO_USED(CMAC_Final); +LCRYPTO_USED(CMAC_resume); + +#endif /* _LIBCRYPTO_CMAC_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/cms.h b/Libraries/libressl/crypto/hidden/openssl/cms.h new file mode 100644 index 000000000..0f450e603 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/cms.h @@ -0,0 +1,148 @@ +/* $OpenBSD: cms.h,v 1.2 2023/07/28 10:28:02 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CMS_H +#define _LIBCRYPTO_CMS_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/cms.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(CMS_ContentInfo_new); +LCRYPTO_USED(CMS_ContentInfo_free); +LCRYPTO_USED(d2i_CMS_ContentInfo); +LCRYPTO_USED(i2d_CMS_ContentInfo); +LCRYPTO_USED(CMS_ReceiptRequest_new); +LCRYPTO_USED(CMS_ReceiptRequest_free); +LCRYPTO_USED(d2i_CMS_ReceiptRequest); +LCRYPTO_USED(i2d_CMS_ReceiptRequest); +LCRYPTO_USED(CMS_ContentInfo_print_ctx); +LCRYPTO_USED(CMS_get0_type); +LCRYPTO_USED(CMS_get_version); +LCRYPTO_USED(CMS_SignerInfo_get_version); +LCRYPTO_USED(CMS_dataInit); +LCRYPTO_USED(CMS_dataFinal); +LCRYPTO_USED(CMS_is_detached); +LCRYPTO_USED(CMS_set_detached); +LCRYPTO_USED(CMS_stream); +LCRYPTO_USED(d2i_CMS_bio); +LCRYPTO_USED(i2d_CMS_bio); +LCRYPTO_USED(BIO_new_CMS); +LCRYPTO_USED(i2d_CMS_bio_stream); +LCRYPTO_USED(PEM_write_bio_CMS_stream); +LCRYPTO_USED(SMIME_read_CMS); +LCRYPTO_USED(SMIME_write_CMS); +LCRYPTO_USED(CMS_final); +LCRYPTO_USED(CMS_sign); +LCRYPTO_USED(CMS_sign_receipt); +LCRYPTO_USED(CMS_data); +LCRYPTO_USED(CMS_data_create); +LCRYPTO_USED(CMS_digest_verify); +LCRYPTO_USED(CMS_digest_create); +LCRYPTO_USED(CMS_EncryptedData_decrypt); +LCRYPTO_USED(CMS_EncryptedData_encrypt); +LCRYPTO_USED(CMS_EncryptedData_set1_key); +LCRYPTO_USED(CMS_verify); +LCRYPTO_USED(CMS_verify_receipt); +LCRYPTO_USED(CMS_get0_signers); +LCRYPTO_USED(CMS_encrypt); +LCRYPTO_USED(CMS_decrypt); +LCRYPTO_USED(CMS_decrypt_set1_pkey); +LCRYPTO_USED(CMS_decrypt_set1_key); +LCRYPTO_USED(CMS_decrypt_set1_password); +LCRYPTO_USED(CMS_get0_RecipientInfos); +LCRYPTO_USED(CMS_RecipientInfo_type); +LCRYPTO_USED(CMS_RecipientInfo_get0_pkey_ctx); +LCRYPTO_USED(CMS_EnvelopedData_create); +LCRYPTO_USED(CMS_add1_recipient_cert); +LCRYPTO_USED(CMS_RecipientInfo_set0_pkey); +LCRYPTO_USED(CMS_RecipientInfo_ktri_cert_cmp); +LCRYPTO_USED(CMS_RecipientInfo_ktri_get0_algs); +LCRYPTO_USED(CMS_RecipientInfo_ktri_get0_signer_id); +LCRYPTO_USED(CMS_add0_recipient_key); +LCRYPTO_USED(CMS_RecipientInfo_kekri_get0_id); +LCRYPTO_USED(CMS_RecipientInfo_set0_key); +LCRYPTO_USED(CMS_RecipientInfo_kekri_id_cmp); +LCRYPTO_USED(CMS_RecipientInfo_set0_password); +LCRYPTO_USED(CMS_add0_recipient_password); +LCRYPTO_USED(CMS_RecipientInfo_decrypt); +LCRYPTO_USED(CMS_RecipientInfo_encrypt); +LCRYPTO_USED(CMS_uncompress); +LCRYPTO_USED(CMS_compress); +LCRYPTO_USED(CMS_set1_eContentType); +LCRYPTO_USED(CMS_get0_eContentType); +LCRYPTO_USED(CMS_add0_CertificateChoices); +LCRYPTO_USED(CMS_add0_cert); +LCRYPTO_USED(CMS_add1_cert); +LCRYPTO_USED(CMS_get1_certs); +LCRYPTO_USED(CMS_add0_RevocationInfoChoice); +LCRYPTO_USED(CMS_add0_crl); +LCRYPTO_USED(CMS_add1_crl); +LCRYPTO_USED(CMS_get1_crls); +LCRYPTO_USED(CMS_SignedData_init); +LCRYPTO_USED(CMS_add1_signer); +LCRYPTO_USED(CMS_SignerInfo_get0_pkey_ctx); +LCRYPTO_USED(CMS_SignerInfo_get0_md_ctx); +LCRYPTO_USED(CMS_get0_SignerInfos); +LCRYPTO_USED(CMS_SignerInfo_set1_signer_cert); +LCRYPTO_USED(CMS_SignerInfo_get0_signer_id); +LCRYPTO_USED(CMS_SignerInfo_cert_cmp); +LCRYPTO_USED(CMS_set1_signers_certs); +LCRYPTO_USED(CMS_SignerInfo_get0_algs); +LCRYPTO_USED(CMS_SignerInfo_get0_signature); +LCRYPTO_USED(CMS_SignerInfo_sign); +LCRYPTO_USED(CMS_SignerInfo_verify); +LCRYPTO_USED(CMS_SignerInfo_verify_content); +LCRYPTO_USED(CMS_add_smimecap); +LCRYPTO_USED(CMS_add_simple_smimecap); +LCRYPTO_USED(CMS_add_standard_smimecap); +LCRYPTO_USED(CMS_signed_get_attr_count); +LCRYPTO_USED(CMS_signed_get_attr_by_NID); +LCRYPTO_USED(CMS_signed_get_attr_by_OBJ); +LCRYPTO_USED(CMS_signed_get_attr); +LCRYPTO_USED(CMS_signed_delete_attr); +LCRYPTO_USED(CMS_signed_add1_attr); +LCRYPTO_USED(CMS_signed_add1_attr_by_OBJ); +LCRYPTO_USED(CMS_signed_add1_attr_by_NID); +LCRYPTO_USED(CMS_signed_add1_attr_by_txt); +LCRYPTO_USED(CMS_signed_get0_data_by_OBJ); +LCRYPTO_USED(CMS_unsigned_get_attr_count); +LCRYPTO_USED(CMS_unsigned_get_attr_by_NID); +LCRYPTO_USED(CMS_unsigned_get_attr_by_OBJ); +LCRYPTO_USED(CMS_unsigned_get_attr); +LCRYPTO_USED(CMS_unsigned_delete_attr); +LCRYPTO_USED(CMS_unsigned_add1_attr); +LCRYPTO_USED(CMS_unsigned_add1_attr_by_OBJ); +LCRYPTO_USED(CMS_unsigned_add1_attr_by_NID); +LCRYPTO_USED(CMS_unsigned_add1_attr_by_txt); +LCRYPTO_USED(CMS_unsigned_get0_data_by_OBJ); +LCRYPTO_USED(CMS_RecipientInfo_kari_get0_alg); +LCRYPTO_USED(CMS_RecipientInfo_kari_get0_reks); +LCRYPTO_USED(CMS_RecipientInfo_kari_get0_orig_id); +LCRYPTO_USED(CMS_RecipientInfo_kari_orig_id_cmp); +LCRYPTO_USED(CMS_RecipientEncryptedKey_get0_id); +LCRYPTO_USED(CMS_RecipientEncryptedKey_cert_cmp); +LCRYPTO_USED(CMS_RecipientInfo_kari_set0_pkey); +LCRYPTO_USED(CMS_RecipientInfo_kari_get0_ctx); +LCRYPTO_USED(CMS_RecipientInfo_kari_decrypt); +LCRYPTO_USED(CMS_SharedInfo_encode); +LCRYPTO_USED(ERR_load_CMS_strings); + +#endif /* _LIBCRYPTO_CMS_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/conf_api.h b/Libraries/libressl/crypto/hidden/openssl/conf_api.h new file mode 100644 index 000000000..5ff895661 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/conf_api.h @@ -0,0 +1,36 @@ +/* $OpenBSD: conf_api.h,v 1.1 2023/07/08 08:26:26 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CONF_API_H +#define _LIBCRYPTO_CONF_API_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/conf_api.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(_CONF_new_section); +LCRYPTO_USED(_CONF_get_section); +LCRYPTO_USED(_CONF_get_section_values); +LCRYPTO_USED(_CONF_add_string); +LCRYPTO_USED(_CONF_get_string); +LCRYPTO_USED(_CONF_new_data); +LCRYPTO_USED(_CONF_free_data); + +#endif /* _LIBCRYPTO_CONF_API_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/crypto.h b/Libraries/libressl/crypto/hidden/openssl/crypto.h new file mode 100644 index 000000000..dc0b7a02b --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/crypto.h @@ -0,0 +1,76 @@ +/* $OpenBSD: crypto.h,v 1.2 2023/07/28 10:19:20 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CRYPTO_H +#define _LIBCRYPTO_CRYPTO_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/crypto.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(OpenSSL_version); +LCRYPTO_USED(OpenSSL_version_num); +LCRYPTO_USED(SSLeay_version); +LCRYPTO_USED(SSLeay); +LCRYPTO_USED(CRYPTO_get_ex_new_index); +LCRYPTO_USED(CRYPTO_new_ex_data); +LCRYPTO_USED(CRYPTO_dup_ex_data); +LCRYPTO_USED(CRYPTO_free_ex_data); +LCRYPTO_USED(CRYPTO_set_ex_data); +LCRYPTO_USED(CRYPTO_get_ex_data); +LCRYPTO_USED(CRYPTO_cleanup_all_ex_data); +LCRYPTO_USED(CRYPTO_lock); +LCRYPTO_USED(CRYPTO_add_lock); +LCRYPTO_USED(CRYPTO_THREADID_current); +LCRYPTO_USED(CRYPTO_THREADID_cmp); +LCRYPTO_USED(CRYPTO_THREADID_cpy); +LCRYPTO_USED(CRYPTO_THREADID_hash); +LCRYPTO_USED(CRYPTO_set_mem_functions); +LCRYPTO_USED(CRYPTO_set_locked_mem_functions); +LCRYPTO_USED(CRYPTO_set_mem_ex_functions); +LCRYPTO_USED(CRYPTO_set_locked_mem_ex_functions); +LCRYPTO_USED(CRYPTO_set_mem_debug_functions); +LCRYPTO_USED(CRYPTO_get_mem_functions); +LCRYPTO_USED(CRYPTO_get_locked_mem_functions); +LCRYPTO_USED(CRYPTO_get_mem_ex_functions); +LCRYPTO_USED(CRYPTO_get_locked_mem_ex_functions); +LCRYPTO_USED(CRYPTO_get_mem_debug_functions); +LCRYPTO_USED(CRYPTO_realloc_clean); +LCRYPTO_USED(CRYPTO_remalloc); +LCRYPTO_USED(CRYPTO_set_mem_debug_options); +LCRYPTO_USED(CRYPTO_get_mem_debug_options); +LCRYPTO_USED(CRYPTO_push_info_); +LCRYPTO_USED(CRYPTO_pop_info); +LCRYPTO_USED(CRYPTO_remove_all_info); +LCRYPTO_USED(CRYPTO_dbg_malloc); +LCRYPTO_USED(CRYPTO_dbg_realloc); +LCRYPTO_USED(CRYPTO_dbg_free); +LCRYPTO_USED(CRYPTO_dbg_set_options); +LCRYPTO_USED(CRYPTO_dbg_get_options); +LCRYPTO_USED(CRYPTO_mem_leaks_fp); +LCRYPTO_USED(CRYPTO_mem_leaks); +LCRYPTO_USED(CRYPTO_mem_leaks_cb); +LCRYPTO_USED(OpenSSLDie); +LCRYPTO_USED(OPENSSL_cpu_caps); +LCRYPTO_USED(OPENSSL_init_crypto); +LCRYPTO_USED(OPENSSL_cleanup); +LCRYPTO_USED(ERR_load_CRYPTO_strings); + +#endif /* _LIBCRYPTO_CRYPTO_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/ct.h b/Libraries/libressl/crypto/hidden/openssl/ct.h new file mode 100644 index 000000000..a1c9b338e --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/ct.h @@ -0,0 +1,85 @@ +/* $OpenBSD: ct.h,v 1.1 2023/07/08 07:22:58 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CT_H +#define _LIBCRYPTO_CT_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/ct.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(CT_POLICY_EVAL_CTX_new); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_free); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_get0_cert); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_set1_cert); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_get0_issuer); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_set1_issuer); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_get0_log_store); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_get_time); +LCRYPTO_USED(CT_POLICY_EVAL_CTX_set_time); +LCRYPTO_USED(SCT_new); +LCRYPTO_USED(SCT_new_from_base64); +LCRYPTO_USED(SCT_free); +LCRYPTO_USED(SCT_LIST_free); +LCRYPTO_USED(SCT_get_version); +LCRYPTO_USED(SCT_set_version); +LCRYPTO_USED(SCT_get_log_entry_type); +LCRYPTO_USED(SCT_set_log_entry_type); +LCRYPTO_USED(SCT_get0_log_id); +LCRYPTO_USED(SCT_set0_log_id); +LCRYPTO_USED(SCT_set1_log_id); +LCRYPTO_USED(SCT_get_timestamp); +LCRYPTO_USED(SCT_set_timestamp); +LCRYPTO_USED(SCT_get_signature_nid); +LCRYPTO_USED(SCT_set_signature_nid); +LCRYPTO_USED(SCT_get0_extensions); +LCRYPTO_USED(SCT_set0_extensions); +LCRYPTO_USED(SCT_set1_extensions); +LCRYPTO_USED(SCT_get0_signature); +LCRYPTO_USED(SCT_set0_signature); +LCRYPTO_USED(SCT_set1_signature); +LCRYPTO_USED(SCT_get_source); +LCRYPTO_USED(SCT_set_source); +LCRYPTO_USED(SCT_validation_status_string); +LCRYPTO_USED(SCT_print); +LCRYPTO_USED(SCT_LIST_print); +LCRYPTO_USED(SCT_get_validation_status); +LCRYPTO_USED(SCT_validate); +LCRYPTO_USED(SCT_LIST_validate); +LCRYPTO_USED(i2o_SCT_LIST); +LCRYPTO_USED(o2i_SCT_LIST); +LCRYPTO_USED(i2d_SCT_LIST); +LCRYPTO_USED(d2i_SCT_LIST); +LCRYPTO_USED(i2o_SCT); +LCRYPTO_USED(o2i_SCT); +LCRYPTO_USED(CTLOG_new); +LCRYPTO_USED(CTLOG_new_from_base64); +LCRYPTO_USED(CTLOG_free); +LCRYPTO_USED(CTLOG_get0_name); +LCRYPTO_USED(CTLOG_get0_log_id); +LCRYPTO_USED(CTLOG_get0_public_key); +LCRYPTO_USED(CTLOG_STORE_new); +LCRYPTO_USED(CTLOG_STORE_free); +LCRYPTO_USED(CTLOG_STORE_get0_log_by_id); +LCRYPTO_USED(CTLOG_STORE_load_file); +LCRYPTO_USED(CTLOG_STORE_load_default_file); + +#endif /* _LIBCRYPTO_CT_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/curve25519.h b/Libraries/libressl/crypto/hidden/openssl/curve25519.h new file mode 100644 index 000000000..3afa324e0 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/curve25519.h @@ -0,0 +1,34 @@ +/* $OpenBSD: curve25519.h,v 1.1 2023/07/08 15:12:49 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_CURVE25519_H +#define _LIBCRYPTO_CURVE25519_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/curve25519.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(X25519_keypair); +LCRYPTO_USED(X25519); +LCRYPTO_USED(ED25519_keypair); +LCRYPTO_USED(ED25519_sign); +LCRYPTO_USED(ED25519_verify); + +#endif /* _LIBCRYPTO_CURVE25519_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/dh.h b/Libraries/libressl/crypto/hidden/openssl/dh.h new file mode 100644 index 000000000..7e6d57815 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/dh.h @@ -0,0 +1,74 @@ +/* $OpenBSD: dh.h,v 1.1 2023/07/08 15:29:04 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_DH_H +#define _LIBCRYPTO_DH_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/dh.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(d2i_DHparams_bio); +LCRYPTO_USED(i2d_DHparams_bio); +LCRYPTO_USED(d2i_DHparams_fp); +LCRYPTO_USED(i2d_DHparams_fp); +LCRYPTO_USED(DHparams_dup); +LCRYPTO_USED(DH_OpenSSL); +LCRYPTO_USED(DH_set_default_method); +LCRYPTO_USED(DH_get_default_method); +LCRYPTO_USED(DH_set_method); +LCRYPTO_USED(DH_new_method); +LCRYPTO_USED(DH_new); +LCRYPTO_USED(DH_free); +LCRYPTO_USED(DH_up_ref); +LCRYPTO_USED(DH_size); +LCRYPTO_USED(DH_bits); +LCRYPTO_USED(DH_get_ex_new_index); +LCRYPTO_USED(DH_set_ex_data); +LCRYPTO_USED(DH_get_ex_data); +LCRYPTO_USED(DH_security_bits); +LCRYPTO_USED(DH_get0_engine); +LCRYPTO_USED(DH_get0_pqg); +LCRYPTO_USED(DH_set0_pqg); +LCRYPTO_USED(DH_get0_key); +LCRYPTO_USED(DH_set0_key); +LCRYPTO_USED(DH_get0_p); +LCRYPTO_USED(DH_get0_q); +LCRYPTO_USED(DH_get0_g); +LCRYPTO_USED(DH_get0_priv_key); +LCRYPTO_USED(DH_get0_pub_key); +LCRYPTO_USED(DH_clear_flags); +LCRYPTO_USED(DH_test_flags); +LCRYPTO_USED(DH_set_flags); +LCRYPTO_USED(DH_get_length); +LCRYPTO_USED(DH_set_length); +LCRYPTO_USED(DH_generate_parameters); +LCRYPTO_USED(DH_generate_parameters_ex); +LCRYPTO_USED(DH_check); +LCRYPTO_USED(DH_check_pub_key); +LCRYPTO_USED(DH_generate_key); +LCRYPTO_USED(DH_compute_key); +LCRYPTO_USED(d2i_DHparams); +LCRYPTO_USED(i2d_DHparams); +LCRYPTO_USED(DHparams_print_fp); +LCRYPTO_USED(DHparams_print); +LCRYPTO_USED(ERR_load_DH_strings); + +#endif /* _LIBCRYPTO_DH_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/dsa.h b/Libraries/libressl/crypto/hidden/openssl/dsa.h new file mode 100644 index 000000000..b2b0058cb --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/dsa.h @@ -0,0 +1,94 @@ +/* $OpenBSD: dsa.h,v 1.1 2023/07/08 14:28:15 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_DSA_H +#define _LIBCRYPTO_DSA_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/dsa.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(d2i_DSAparams_bio); +LCRYPTO_USED(i2d_DSAparams_bio); +LCRYPTO_USED(d2i_DSAparams_fp); +LCRYPTO_USED(i2d_DSAparams_fp); +LCRYPTO_USED(DSAparams_dup); +LCRYPTO_USED(DSA_SIG_new); +LCRYPTO_USED(DSA_SIG_free); +LCRYPTO_USED(i2d_DSA_SIG); +LCRYPTO_USED(d2i_DSA_SIG); +LCRYPTO_USED(DSA_SIG_get0); +LCRYPTO_USED(DSA_SIG_set0); +LCRYPTO_USED(DSA_do_sign); +LCRYPTO_USED(DSA_do_verify); +LCRYPTO_USED(DSA_OpenSSL); +LCRYPTO_USED(DSA_set_default_method); +LCRYPTO_USED(DSA_get_default_method); +LCRYPTO_USED(DSA_set_method); +LCRYPTO_USED(DSA_new); +LCRYPTO_USED(DSA_new_method); +LCRYPTO_USED(DSA_free); +LCRYPTO_USED(DSA_up_ref); +LCRYPTO_USED(DSA_size); +LCRYPTO_USED(DSA_bits); +LCRYPTO_USED(DSA_sign_setup); +LCRYPTO_USED(DSA_sign); +LCRYPTO_USED(DSA_verify); +LCRYPTO_USED(DSA_get_ex_new_index); +LCRYPTO_USED(DSA_set_ex_data); +LCRYPTO_USED(DSA_get_ex_data); +LCRYPTO_USED(DSA_security_bits); +LCRYPTO_USED(d2i_DSAPublicKey); +LCRYPTO_USED(i2d_DSAPublicKey); +LCRYPTO_USED(d2i_DSAPrivateKey); +LCRYPTO_USED(i2d_DSAPrivateKey); +LCRYPTO_USED(d2i_DSAparams); +LCRYPTO_USED(i2d_DSAparams); +LCRYPTO_USED(DSA_generate_parameters); +LCRYPTO_USED(DSA_generate_parameters_ex); +LCRYPTO_USED(DSA_generate_key); +LCRYPTO_USED(DSAparams_print); +LCRYPTO_USED(DSA_print); +LCRYPTO_USED(DSAparams_print_fp); +LCRYPTO_USED(DSA_print_fp); +LCRYPTO_USED(DSA_dup_DH); +LCRYPTO_USED(DSA_get0_pqg); +LCRYPTO_USED(DSA_set0_pqg); +LCRYPTO_USED(DSA_get0_key); +LCRYPTO_USED(DSA_set0_key); +LCRYPTO_USED(DSA_get0_p); +LCRYPTO_USED(DSA_get0_q); +LCRYPTO_USED(DSA_get0_g); +LCRYPTO_USED(DSA_get0_pub_key); +LCRYPTO_USED(DSA_get0_priv_key); +LCRYPTO_USED(DSA_clear_flags); +LCRYPTO_USED(DSA_test_flags); +LCRYPTO_USED(DSA_set_flags); +LCRYPTO_USED(DSA_get0_engine); +LCRYPTO_USED(DSA_meth_new); +LCRYPTO_USED(DSA_meth_free); +LCRYPTO_USED(DSA_meth_dup); +LCRYPTO_USED(DSA_meth_get0_name); +LCRYPTO_USED(DSA_meth_set1_name); +LCRYPTO_USED(DSA_meth_set_sign); +LCRYPTO_USED(DSA_meth_set_finish); +LCRYPTO_USED(ERR_load_DSA_strings); + +#endif /* _LIBCRYPTO_DSA_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/ec.h b/Libraries/libressl/crypto/hidden/openssl/ec.h new file mode 100644 index 000000000..4e82f4846 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/ec.h @@ -0,0 +1,165 @@ +/* $OpenBSD: ec.h,v 1.4 2023/07/28 09:25:12 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_EC_H +#define _LIBCRYPTO_EC_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/ec.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(EC_GFp_simple_method); +LCRYPTO_USED(EC_GFp_mont_method); +LCRYPTO_USED(EC_GROUP_new); +LCRYPTO_USED(EC_GROUP_free); +LCRYPTO_USED(EC_GROUP_copy); +LCRYPTO_USED(EC_GROUP_dup); +LCRYPTO_USED(EC_GROUP_method_of); +LCRYPTO_USED(EC_METHOD_get_field_type); +LCRYPTO_USED(EC_GROUP_set_generator); +LCRYPTO_USED(EC_GROUP_get0_generator); +LCRYPTO_USED(EC_GROUP_get_order); +LCRYPTO_USED(EC_GROUP_order_bits); +LCRYPTO_USED(EC_GROUP_get_cofactor); +LCRYPTO_USED(EC_GROUP_set_curve_name); +LCRYPTO_USED(EC_GROUP_get_curve_name); +LCRYPTO_USED(EC_GROUP_set_asn1_flag); +LCRYPTO_USED(EC_GROUP_get_asn1_flag); +LCRYPTO_USED(EC_GROUP_set_point_conversion_form); +LCRYPTO_USED(EC_GROUP_get_point_conversion_form); +LCRYPTO_USED(EC_GROUP_get0_seed); +LCRYPTO_USED(EC_GROUP_get_seed_len); +LCRYPTO_USED(EC_GROUP_set_seed); +LCRYPTO_USED(EC_GROUP_set_curve); +LCRYPTO_USED(EC_GROUP_get_curve); +LCRYPTO_USED(EC_GROUP_get_degree); +LCRYPTO_USED(EC_GROUP_check); +LCRYPTO_USED(EC_GROUP_check_discriminant); +LCRYPTO_USED(EC_GROUP_cmp); +LCRYPTO_USED(EC_GROUP_new_curve_GFp); +LCRYPTO_USED(EC_GROUP_new_by_curve_name); +LCRYPTO_USED(EC_get_builtin_curves); +LCRYPTO_USED(EC_curve_nid2nist); +LCRYPTO_USED(EC_curve_nist2nid); +LCRYPTO_USED(EC_POINT_new); +LCRYPTO_USED(EC_POINT_free); +LCRYPTO_USED(EC_POINT_copy); +LCRYPTO_USED(EC_POINT_dup); +LCRYPTO_USED(EC_POINT_method_of); +LCRYPTO_USED(EC_POINT_set_to_infinity); +LCRYPTO_USED(EC_POINT_set_affine_coordinates); +LCRYPTO_USED(EC_POINT_get_affine_coordinates); +LCRYPTO_USED(EC_POINT_set_compressed_coordinates); +LCRYPTO_USED(EC_POINT_point2oct); +LCRYPTO_USED(EC_POINT_oct2point); +LCRYPTO_USED(EC_POINT_point2bn); +LCRYPTO_USED(EC_POINT_bn2point); +LCRYPTO_USED(EC_POINT_point2hex); +LCRYPTO_USED(EC_POINT_hex2point); +LCRYPTO_USED(EC_POINT_add); +LCRYPTO_USED(EC_POINT_dbl); +LCRYPTO_USED(EC_POINT_invert); +LCRYPTO_USED(EC_POINT_is_at_infinity); +LCRYPTO_USED(EC_POINT_is_on_curve); +LCRYPTO_USED(EC_POINT_cmp); +LCRYPTO_USED(EC_POINT_make_affine); +LCRYPTO_USED(EC_POINTs_make_affine); +LCRYPTO_USED(EC_POINTs_mul); +LCRYPTO_USED(EC_POINT_mul); +LCRYPTO_USED(EC_GROUP_precompute_mult); +LCRYPTO_USED(EC_GROUP_have_precompute_mult); +LCRYPTO_USED(EC_GROUP_get_basis_type); +LCRYPTO_USED(d2i_ECPKParameters); +LCRYPTO_USED(i2d_ECPKParameters); +LCRYPTO_USED(ECPKParameters_print); +LCRYPTO_USED(ECPKParameters_print_fp); +LCRYPTO_USED(EC_KEY_new); +LCRYPTO_USED(EC_KEY_get_flags); +LCRYPTO_USED(EC_KEY_set_flags); +LCRYPTO_USED(EC_KEY_clear_flags); +LCRYPTO_USED(EC_KEY_new_by_curve_name); +LCRYPTO_USED(EC_KEY_free); +LCRYPTO_USED(EC_KEY_copy); +LCRYPTO_USED(EC_KEY_dup); +LCRYPTO_USED(EC_KEY_up_ref); +LCRYPTO_USED(EC_KEY_get0_group); +LCRYPTO_USED(EC_KEY_set_group); +LCRYPTO_USED(EC_KEY_get0_private_key); +LCRYPTO_USED(EC_KEY_set_private_key); +LCRYPTO_USED(EC_KEY_get0_public_key); +LCRYPTO_USED(EC_KEY_set_public_key); +LCRYPTO_USED(EC_KEY_get_enc_flags); +LCRYPTO_USED(EC_KEY_set_enc_flags); +LCRYPTO_USED(EC_KEY_get_conv_form); +LCRYPTO_USED(EC_KEY_set_conv_form); +LCRYPTO_USED(EC_KEY_set_asn1_flag); +LCRYPTO_USED(EC_KEY_precompute_mult); +LCRYPTO_USED(EC_KEY_generate_key); +LCRYPTO_USED(EC_KEY_check_key); +LCRYPTO_USED(EC_KEY_set_public_key_affine_coordinates); +LCRYPTO_USED(d2i_ECPrivateKey); +LCRYPTO_USED(i2d_ECPrivateKey); +LCRYPTO_USED(d2i_ECParameters); +LCRYPTO_USED(i2d_ECParameters); +LCRYPTO_USED(o2i_ECPublicKey); +LCRYPTO_USED(i2o_ECPublicKey); +LCRYPTO_USED(ECParameters_print); +LCRYPTO_USED(EC_KEY_print); +LCRYPTO_USED(ECParameters_print_fp); +LCRYPTO_USED(EC_KEY_print_fp); +LCRYPTO_USED(EC_KEY_set_ex_data); +LCRYPTO_USED(EC_KEY_get_ex_data); +LCRYPTO_USED(EC_KEY_OpenSSL); +LCRYPTO_USED(EC_KEY_get_default_method); +LCRYPTO_USED(EC_KEY_set_default_method); +LCRYPTO_USED(EC_KEY_get_method); +LCRYPTO_USED(EC_KEY_set_method); +LCRYPTO_USED(EC_KEY_new_method); +LCRYPTO_USED(ECDH_size); +LCRYPTO_USED(ECDH_compute_key); +LCRYPTO_USED(ECDSA_SIG_new); +LCRYPTO_USED(ECDSA_SIG_free); +LCRYPTO_USED(i2d_ECDSA_SIG); +LCRYPTO_USED(d2i_ECDSA_SIG); +LCRYPTO_USED(ECDSA_SIG_get0_r); +LCRYPTO_USED(ECDSA_SIG_get0_s); +LCRYPTO_USED(ECDSA_SIG_get0); +LCRYPTO_USED(ECDSA_SIG_set0); +LCRYPTO_USED(ECDSA_size); +LCRYPTO_USED(ECDSA_do_sign); +LCRYPTO_USED(ECDSA_do_verify); +LCRYPTO_USED(ECDSA_sign); +LCRYPTO_USED(ECDSA_verify); +LCRYPTO_USED(EC_KEY_METHOD_new); +LCRYPTO_USED(EC_KEY_METHOD_free); +LCRYPTO_USED(EC_KEY_METHOD_set_init); +LCRYPTO_USED(EC_KEY_METHOD_set_keygen); +LCRYPTO_USED(EC_KEY_METHOD_set_compute_key); +LCRYPTO_USED(EC_KEY_METHOD_set_sign); +LCRYPTO_USED(EC_KEY_METHOD_set_verify); +LCRYPTO_USED(EC_KEY_METHOD_get_init); +LCRYPTO_USED(EC_KEY_METHOD_get_keygen); +LCRYPTO_USED(EC_KEY_METHOD_get_compute_key); +LCRYPTO_USED(EC_KEY_METHOD_get_sign); +LCRYPTO_USED(EC_KEY_METHOD_get_verify); +LCRYPTO_USED(ECParameters_dup); +LCRYPTO_USED(ERR_load_EC_strings); + +#endif /* _LIBCRYPTO_EC_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/err.h b/Libraries/libressl/crypto/hidden/openssl/err.h new file mode 100644 index 000000000..036ead8c0 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/err.h @@ -0,0 +1,61 @@ +/* $OpenBSD: err.h,v 1.4 2023/07/28 10:23:19 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_ERR_H +#define _LIBCRYPTO_ERR_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/err.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(ERR_put_error); +LCRYPTO_USED(ERR_set_error_data); +LCRYPTO_USED(ERR_get_error); +LCRYPTO_USED(ERR_get_error_line); +LCRYPTO_USED(ERR_get_error_line_data); +LCRYPTO_USED(ERR_peek_error); +LCRYPTO_USED(ERR_peek_error_line); +LCRYPTO_USED(ERR_peek_error_line_data); +LCRYPTO_USED(ERR_peek_last_error); +LCRYPTO_USED(ERR_peek_last_error_line); +LCRYPTO_USED(ERR_peek_last_error_line_data); +LCRYPTO_USED(ERR_clear_error); +LCRYPTO_USED(ERR_error_string); +LCRYPTO_USED(ERR_error_string_n); +LCRYPTO_USED(ERR_lib_error_string); +LCRYPTO_USED(ERR_func_error_string); +LCRYPTO_USED(ERR_reason_error_string); +LCRYPTO_USED(ERR_print_errors_cb); +LCRYPTO_USED(ERR_print_errors_fp); +LCRYPTO_USED(ERR_print_errors); +LCRYPTO_USED(ERR_asprintf_error_data); +LCRYPTO_USED(ERR_load_strings); +LCRYPTO_USED(ERR_unload_strings); +LCRYPTO_USED(ERR_load_ERR_strings); +LCRYPTO_USED(ERR_load_crypto_strings); +LCRYPTO_USED(ERR_free_strings); +LCRYPTO_USED(ERR_remove_thread_state); +LCRYPTO_USED(ERR_remove_state); +LCRYPTO_USED(ERR_get_state); +LCRYPTO_USED(ERR_get_next_error_library); +LCRYPTO_USED(ERR_set_mark); +LCRYPTO_USED(ERR_pop_to_mark); + +#endif /* _LIBCRYPTO_ERR_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/gost.h b/Libraries/libressl/crypto/hidden/openssl/gost.h new file mode 100644 index 000000000..e30e6611a --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/gost.h @@ -0,0 +1,71 @@ +/* $OpenBSD: gost.h,v 1.1 2023/07/08 14:30:44 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_GOST_H +#define _LIBCRYPTO_GOST_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/gost.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(Gost2814789_set_sbox); +LCRYPTO_USED(Gost2814789_set_key); +LCRYPTO_USED(Gost2814789_ecb_encrypt); +LCRYPTO_USED(Gost2814789_cfb64_encrypt); +LCRYPTO_USED(Gost2814789_cnt_encrypt); +LCRYPTO_USED(GOST_CIPHER_PARAMS_new); +LCRYPTO_USED(GOST_CIPHER_PARAMS_free); +LCRYPTO_USED(d2i_GOST_CIPHER_PARAMS); +LCRYPTO_USED(i2d_GOST_CIPHER_PARAMS); +LCRYPTO_USED(GOST2814789IMIT_Init); +LCRYPTO_USED(GOST2814789IMIT_Update); +LCRYPTO_USED(GOST2814789IMIT_Final); +LCRYPTO_USED(GOST2814789IMIT_Transform); +LCRYPTO_USED(GOST2814789IMIT); +LCRYPTO_USED(GOSTR341194_Init); +LCRYPTO_USED(GOSTR341194_Update); +LCRYPTO_USED(GOSTR341194_Final); +LCRYPTO_USED(GOSTR341194_Transform); +LCRYPTO_USED(GOSTR341194); +LCRYPTO_USED(STREEBOG256_Init); +LCRYPTO_USED(STREEBOG256_Update); +LCRYPTO_USED(STREEBOG256_Final); +LCRYPTO_USED(STREEBOG256); +LCRYPTO_USED(STREEBOG512_Init); +LCRYPTO_USED(STREEBOG512_Update); +LCRYPTO_USED(STREEBOG512_Final); +LCRYPTO_USED(STREEBOG512_Transform); +LCRYPTO_USED(STREEBOG512); +LCRYPTO_USED(GOST_KEY_new); +LCRYPTO_USED(GOST_KEY_free); +LCRYPTO_USED(GOST_KEY_check_key); +LCRYPTO_USED(GOST_KEY_set_public_key_affine_coordinates); +LCRYPTO_USED(GOST_KEY_get0_group); +LCRYPTO_USED(GOST_KEY_set_group); +LCRYPTO_USED(GOST_KEY_get_digest); +LCRYPTO_USED(GOST_KEY_set_digest); +LCRYPTO_USED(GOST_KEY_get0_private_key); +LCRYPTO_USED(GOST_KEY_set_private_key); +LCRYPTO_USED(GOST_KEY_get0_public_key); +LCRYPTO_USED(GOST_KEY_set_public_key); +LCRYPTO_USED(GOST_KEY_get_size); +LCRYPTO_USED(ERR_load_GOST_strings); + +#endif /* _LIBCRYPTO_GOST_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/hkdf.h b/Libraries/libressl/crypto/hidden/openssl/hkdf.h new file mode 100644 index 000000000..0c01cf3e6 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/hkdf.h @@ -0,0 +1,32 @@ +/* $OpenBSD: hkdf.h,v 1.2 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_HKDF_H +#define _LIBCRYPTO_HKDF_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/hkdf.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(HKDF); +LCRYPTO_USED(HKDF_extract); +LCRYPTO_USED(HKDF_expand); + +#endif /* _LIBCRYPTO_HKDF_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/hmac.h b/Libraries/libressl/crypto/hidden/openssl/hmac.h new file mode 100644 index 000000000..ecf8aa999 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/hmac.h @@ -0,0 +1,40 @@ +/* $OpenBSD: hmac.h,v 1.2 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2016 Philip Guenther + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_HMAC_H_ +#define _LIBCRYPTO_HMAC_H_ + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/hmac.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(HMAC_CTX_new); +LCRYPTO_USED(HMAC_CTX_free); +LCRYPTO_UNUSED(HMAC_CTX_reset); +LCRYPTO_UNUSED(HMAC_Init); +LCRYPTO_USED(HMAC_Init_ex); +LCRYPTO_USED(HMAC_Update); +LCRYPTO_USED(HMAC_Final); +LCRYPTO_USED(HMAC); +LCRYPTO_USED(HMAC_CTX_copy); +LCRYPTO_USED(HMAC_CTX_set_flags); +LCRYPTO_USED(HMAC_CTX_get_md); + +#endif /* _LIBCRYPTO_HMAC_H_ */ diff --git a/Libraries/libressl/crypto/hidden/openssl/idea.h b/Libraries/libressl/crypto/hidden/openssl/idea.h new file mode 100644 index 000000000..93b20a9cc --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/idea.h @@ -0,0 +1,36 @@ +/* $OpenBSD: idea.h,v 1.2 2023/07/29 03:13:38 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_IDEA_H +#define _LIBCRYPTO_IDEA_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/idea.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(idea_ecb_encrypt); +LCRYPTO_USED(idea_set_encrypt_key); +LCRYPTO_USED(idea_set_decrypt_key); +LCRYPTO_USED(idea_cbc_encrypt); +LCRYPTO_USED(idea_cfb64_encrypt); +LCRYPTO_USED(idea_ofb64_encrypt); +LCRYPTO_USED(idea_encrypt); + +#endif /* _LIBCRYPTO_IDEA_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/lhash.h b/Libraries/libressl/crypto/hidden/openssl/lhash.h new file mode 100644 index 000000000..151f154a4 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/lhash.h @@ -0,0 +1,44 @@ +/* $OpenBSD: lhash.h,v 1.2 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_LHASH_H +#define _LIBCRYPTO_LHASH_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/lhash.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(lh_new); +LCRYPTO_USED(lh_free); +LCRYPTO_USED(lh_insert); +LCRYPTO_USED(lh_delete); +LCRYPTO_USED(lh_retrieve); +LCRYPTO_USED(lh_doall); +LCRYPTO_USED(lh_doall_arg); +LCRYPTO_USED(lh_strhash); +LCRYPTO_USED(lh_num_items); +LCRYPTO_USED(lh_stats); +LCRYPTO_USED(lh_node_stats); +LCRYPTO_USED(lh_node_usage_stats); +LCRYPTO_USED(lh_stats_bio); +LCRYPTO_USED(lh_node_stats_bio); +LCRYPTO_USED(lh_node_usage_stats_bio); + +#endif /* _LIBCRYPTO_LHASH_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/md4.h b/Libraries/libressl/crypto/hidden/openssl/md4.h new file mode 100644 index 000000000..c5fc22c47 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/md4.h @@ -0,0 +1,34 @@ +/* $OpenBSD: md4.h,v 1.1 2023/07/08 10:45:57 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_MD4_H +#define _LIBCRYPTO_MD4_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/md4.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(MD4_Init); +LCRYPTO_USED(MD4_Update); +LCRYPTO_USED(MD4_Final); +LCRYPTO_USED(MD4); +LCRYPTO_USED(MD4_Transform); + +#endif /* _LIBCRYPTO_MD4_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/md5.h b/Libraries/libressl/crypto/hidden/openssl/md5.h new file mode 100644 index 000000000..3dfade7f7 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/md5.h @@ -0,0 +1,34 @@ +/* $OpenBSD: md5.h,v 1.1 2023/07/08 10:45:57 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_MD5_H +#define _LIBCRYPTO_MD5_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/md5.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(MD5_Init); +LCRYPTO_USED(MD5_Update); +LCRYPTO_USED(MD5_Final); +LCRYPTO_USED(MD5); +LCRYPTO_USED(MD5_Transform); + +#endif /* _LIBCRYPTO_MD5_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/modes.h b/Libraries/libressl/crypto/hidden/openssl/modes.h new file mode 100644 index 000000000..4162861be --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/modes.h @@ -0,0 +1,57 @@ +/* $OpenBSD: modes.h,v 1.1 2023/07/08 14:56:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_MODES_H +#define _LIBCRYPTO_MODES_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/modes.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(CRYPTO_cbc128_encrypt); +LCRYPTO_USED(CRYPTO_cbc128_decrypt); +LCRYPTO_USED(CRYPTO_ctr128_encrypt); +LCRYPTO_USED(CRYPTO_ctr128_encrypt_ctr32); +LCRYPTO_USED(CRYPTO_ofb128_encrypt); +LCRYPTO_USED(CRYPTO_cfb128_encrypt); +LCRYPTO_USED(CRYPTO_cfb128_8_encrypt); +LCRYPTO_USED(CRYPTO_cfb128_1_encrypt); +LCRYPTO_USED(CRYPTO_gcm128_new); +LCRYPTO_USED(CRYPTO_gcm128_init); +LCRYPTO_USED(CRYPTO_gcm128_setiv); +LCRYPTO_USED(CRYPTO_gcm128_aad); +LCRYPTO_USED(CRYPTO_gcm128_encrypt); +LCRYPTO_USED(CRYPTO_gcm128_decrypt); +LCRYPTO_USED(CRYPTO_gcm128_encrypt_ctr32); +LCRYPTO_USED(CRYPTO_gcm128_decrypt_ctr32); +LCRYPTO_USED(CRYPTO_gcm128_finish); +LCRYPTO_USED(CRYPTO_gcm128_tag); +LCRYPTO_USED(CRYPTO_gcm128_release); +LCRYPTO_USED(CRYPTO_ccm128_init); +LCRYPTO_USED(CRYPTO_ccm128_setiv); +LCRYPTO_USED(CRYPTO_ccm128_aad); +LCRYPTO_USED(CRYPTO_ccm128_encrypt); +LCRYPTO_USED(CRYPTO_ccm128_decrypt); +LCRYPTO_USED(CRYPTO_ccm128_encrypt_ccm64); +LCRYPTO_USED(CRYPTO_ccm128_decrypt_ccm64); +LCRYPTO_USED(CRYPTO_ccm128_tag); +LCRYPTO_USED(CRYPTO_xts128_encrypt); + +#endif /* _LIBCRYPTO_MODES_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/objects.h b/Libraries/libressl/crypto/hidden/openssl/objects.h new file mode 100644 index 000000000..ba5bf8e25 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/objects.h @@ -0,0 +1,59 @@ +/* $OpenBSD: objects.h,v 1.2 2023/07/28 10:25:05 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_OBJECTS_H +#define _LIBCRYPTO_OBJECTS_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/objects.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(OBJ_NAME_init); +LCRYPTO_USED(OBJ_NAME_new_index); +LCRYPTO_USED(OBJ_NAME_get); +LCRYPTO_USED(OBJ_NAME_add); +LCRYPTO_USED(OBJ_NAME_remove); +LCRYPTO_USED(OBJ_NAME_cleanup); +LCRYPTO_USED(OBJ_NAME_do_all); +LCRYPTO_USED(OBJ_NAME_do_all_sorted); +LCRYPTO_USED(OBJ_dup); +LCRYPTO_USED(OBJ_nid2obj); +LCRYPTO_USED(OBJ_nid2ln); +LCRYPTO_USED(OBJ_nid2sn); +LCRYPTO_USED(OBJ_obj2nid); +LCRYPTO_USED(OBJ_txt2obj); +LCRYPTO_USED(OBJ_obj2txt); +LCRYPTO_USED(OBJ_txt2nid); +LCRYPTO_USED(OBJ_ln2nid); +LCRYPTO_USED(OBJ_sn2nid); +LCRYPTO_USED(OBJ_cmp); +LCRYPTO_USED(OBJ_bsearch_); +LCRYPTO_USED(OBJ_new_nid); +LCRYPTO_USED(OBJ_add_object); +LCRYPTO_USED(OBJ_create); +LCRYPTO_USED(OBJ_cleanup); +LCRYPTO_USED(OBJ_create_objects); +LCRYPTO_USED(OBJ_length); +LCRYPTO_USED(OBJ_get0_data); +LCRYPTO_USED(OBJ_find_sigid_algs); +LCRYPTO_USED(OBJ_find_sigid_by_algs); +LCRYPTO_USED(ERR_load_OBJ_strings); + +#endif /* _LIBCRYPTO_OBJECTS_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/ocsp.h b/Libraries/libressl/crypto/hidden/openssl/ocsp.h new file mode 100644 index 000000000..654696224 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/ocsp.h @@ -0,0 +1,190 @@ +/* $OpenBSD: ocsp.h,v 1.1 2023/07/08 10:44:00 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_OCSP_H +#define _LIBCRYPTO_OCSP_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/ocsp.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(OCSP_RESPID_new); +LCRYPTO_USED(OCSP_RESPID_free); +LCRYPTO_USED(d2i_OCSP_RESPID); +LCRYPTO_USED(i2d_OCSP_RESPID); +LCRYPTO_USED(OCSP_CERTID_dup); +LCRYPTO_USED(OCSP_sendreq_bio); +LCRYPTO_USED(OCSP_sendreq_new); +LCRYPTO_USED(OCSP_sendreq_nbio); +LCRYPTO_USED(OCSP_REQ_CTX_free); +LCRYPTO_USED(OCSP_REQ_CTX_set1_req); +LCRYPTO_USED(OCSP_REQ_CTX_add1_header); +LCRYPTO_USED(OCSP_cert_to_id); +LCRYPTO_USED(OCSP_cert_id_new); +LCRYPTO_USED(OCSP_request_add0_id); +LCRYPTO_USED(OCSP_request_add1_nonce); +LCRYPTO_USED(OCSP_basic_add1_nonce); +LCRYPTO_USED(OCSP_check_nonce); +LCRYPTO_USED(OCSP_copy_nonce); +LCRYPTO_USED(OCSP_request_set1_name); +LCRYPTO_USED(OCSP_request_add1_cert); +LCRYPTO_USED(OCSP_request_sign); +LCRYPTO_USED(OCSP_response_status); +LCRYPTO_USED(OCSP_response_get1_basic); +LCRYPTO_USED(OCSP_resp_get0_signature); +LCRYPTO_USED(OCSP_resp_get0_tbs_sigalg); +LCRYPTO_USED(OCSP_resp_get0_respdata); +LCRYPTO_USED(OCSP_resp_get0_signer); +LCRYPTO_USED(OCSP_resp_count); +LCRYPTO_USED(OCSP_resp_get0); +LCRYPTO_USED(OCSP_resp_get0_produced_at); +LCRYPTO_USED(OCSP_resp_get0_certs); +LCRYPTO_USED(OCSP_resp_get0_id); +LCRYPTO_USED(OCSP_resp_find); +LCRYPTO_USED(OCSP_single_get0_status); +LCRYPTO_USED(OCSP_resp_find_status); +LCRYPTO_USED(OCSP_check_validity); +LCRYPTO_USED(OCSP_request_verify); +LCRYPTO_USED(OCSP_parse_url); +LCRYPTO_USED(OCSP_id_issuer_cmp); +LCRYPTO_USED(OCSP_id_cmp); +LCRYPTO_USED(OCSP_request_onereq_count); +LCRYPTO_USED(OCSP_request_onereq_get0); +LCRYPTO_USED(OCSP_onereq_get0_id); +LCRYPTO_USED(OCSP_id_get0_info); +LCRYPTO_USED(OCSP_request_is_signed); +LCRYPTO_USED(OCSP_response_create); +LCRYPTO_USED(OCSP_basic_add1_status); +LCRYPTO_USED(OCSP_basic_add1_cert); +LCRYPTO_USED(OCSP_basic_sign); +LCRYPTO_USED(OCSP_crlID_new); +LCRYPTO_USED(OCSP_accept_responses_new); +LCRYPTO_USED(OCSP_archive_cutoff_new); +LCRYPTO_USED(OCSP_url_svcloc_new); +LCRYPTO_USED(OCSP_REQUEST_get_ext_count); +LCRYPTO_USED(OCSP_REQUEST_get_ext_by_NID); +LCRYPTO_USED(OCSP_REQUEST_get_ext_by_OBJ); +LCRYPTO_USED(OCSP_REQUEST_get_ext_by_critical); +LCRYPTO_USED(OCSP_REQUEST_get_ext); +LCRYPTO_USED(OCSP_REQUEST_delete_ext); +LCRYPTO_USED(OCSP_REQUEST_get1_ext_d2i); +LCRYPTO_USED(OCSP_REQUEST_add1_ext_i2d); +LCRYPTO_USED(OCSP_REQUEST_add_ext); +LCRYPTO_USED(OCSP_ONEREQ_get_ext_count); +LCRYPTO_USED(OCSP_ONEREQ_get_ext_by_NID); +LCRYPTO_USED(OCSP_ONEREQ_get_ext_by_OBJ); +LCRYPTO_USED(OCSP_ONEREQ_get_ext_by_critical); +LCRYPTO_USED(OCSP_ONEREQ_get_ext); +LCRYPTO_USED(OCSP_ONEREQ_delete_ext); +LCRYPTO_USED(OCSP_ONEREQ_get1_ext_d2i); +LCRYPTO_USED(OCSP_ONEREQ_add1_ext_i2d); +LCRYPTO_USED(OCSP_ONEREQ_add_ext); +LCRYPTO_USED(OCSP_BASICRESP_get_ext_count); +LCRYPTO_USED(OCSP_BASICRESP_get_ext_by_NID); +LCRYPTO_USED(OCSP_BASICRESP_get_ext_by_OBJ); +LCRYPTO_USED(OCSP_BASICRESP_get_ext_by_critical); +LCRYPTO_USED(OCSP_BASICRESP_get_ext); +LCRYPTO_USED(OCSP_BASICRESP_delete_ext); +LCRYPTO_USED(OCSP_BASICRESP_get1_ext_d2i); +LCRYPTO_USED(OCSP_BASICRESP_add1_ext_i2d); +LCRYPTO_USED(OCSP_BASICRESP_add_ext); +LCRYPTO_USED(OCSP_SINGLERESP_get_ext_count); +LCRYPTO_USED(OCSP_SINGLERESP_get_ext_by_NID); +LCRYPTO_USED(OCSP_SINGLERESP_get_ext_by_OBJ); +LCRYPTO_USED(OCSP_SINGLERESP_get_ext_by_critical); +LCRYPTO_USED(OCSP_SINGLERESP_get_ext); +LCRYPTO_USED(OCSP_SINGLERESP_delete_ext); +LCRYPTO_USED(OCSP_SINGLERESP_get1_ext_d2i); +LCRYPTO_USED(OCSP_SINGLERESP_add1_ext_i2d); +LCRYPTO_USED(OCSP_SINGLERESP_add_ext); +LCRYPTO_USED(OCSP_SINGLERESP_get0_id); +LCRYPTO_USED(OCSP_SINGLERESP_new); +LCRYPTO_USED(OCSP_SINGLERESP_free); +LCRYPTO_USED(d2i_OCSP_SINGLERESP); +LCRYPTO_USED(i2d_OCSP_SINGLERESP); +LCRYPTO_USED(OCSP_CERTSTATUS_new); +LCRYPTO_USED(OCSP_CERTSTATUS_free); +LCRYPTO_USED(d2i_OCSP_CERTSTATUS); +LCRYPTO_USED(i2d_OCSP_CERTSTATUS); +LCRYPTO_USED(OCSP_REVOKEDINFO_new); +LCRYPTO_USED(OCSP_REVOKEDINFO_free); +LCRYPTO_USED(d2i_OCSP_REVOKEDINFO); +LCRYPTO_USED(i2d_OCSP_REVOKEDINFO); +LCRYPTO_USED(OCSP_BASICRESP_new); +LCRYPTO_USED(OCSP_BASICRESP_free); +LCRYPTO_USED(d2i_OCSP_BASICRESP); +LCRYPTO_USED(i2d_OCSP_BASICRESP); +LCRYPTO_USED(OCSP_RESPDATA_new); +LCRYPTO_USED(OCSP_RESPDATA_free); +LCRYPTO_USED(d2i_OCSP_RESPDATA); +LCRYPTO_USED(i2d_OCSP_RESPDATA); +LCRYPTO_USED(OCSP_RESPID_new); +LCRYPTO_USED(OCSP_RESPID_free); +LCRYPTO_USED(d2i_OCSP_RESPID); +LCRYPTO_USED(i2d_OCSP_RESPID); +LCRYPTO_USED(OCSP_RESPONSE_new); +LCRYPTO_USED(OCSP_RESPONSE_free); +LCRYPTO_USED(d2i_OCSP_RESPONSE); +LCRYPTO_USED(i2d_OCSP_RESPONSE); +LCRYPTO_USED(d2i_OCSP_RESPONSE_bio); +LCRYPTO_USED(i2d_OCSP_RESPONSE_bio); +LCRYPTO_USED(OCSP_RESPBYTES_new); +LCRYPTO_USED(OCSP_RESPBYTES_free); +LCRYPTO_USED(d2i_OCSP_RESPBYTES); +LCRYPTO_USED(i2d_OCSP_RESPBYTES); +LCRYPTO_USED(OCSP_ONEREQ_new); +LCRYPTO_USED(OCSP_ONEREQ_free); +LCRYPTO_USED(d2i_OCSP_ONEREQ); +LCRYPTO_USED(i2d_OCSP_ONEREQ); +LCRYPTO_USED(OCSP_CERTID_new); +LCRYPTO_USED(OCSP_CERTID_free); +LCRYPTO_USED(d2i_OCSP_CERTID); +LCRYPTO_USED(i2d_OCSP_CERTID); +LCRYPTO_USED(OCSP_REQUEST_new); +LCRYPTO_USED(OCSP_REQUEST_free); +LCRYPTO_USED(d2i_OCSP_REQUEST); +LCRYPTO_USED(i2d_OCSP_REQUEST); +LCRYPTO_USED(d2i_OCSP_REQUEST_bio); +LCRYPTO_USED(i2d_OCSP_REQUEST_bio); +LCRYPTO_USED(OCSP_SIGNATURE_new); +LCRYPTO_USED(OCSP_SIGNATURE_free); +LCRYPTO_USED(d2i_OCSP_SIGNATURE); +LCRYPTO_USED(i2d_OCSP_SIGNATURE); +LCRYPTO_USED(OCSP_REQINFO_new); +LCRYPTO_USED(OCSP_REQINFO_free); +LCRYPTO_USED(d2i_OCSP_REQINFO); +LCRYPTO_USED(i2d_OCSP_REQINFO); +LCRYPTO_USED(OCSP_CRLID_new); +LCRYPTO_USED(OCSP_CRLID_free); +LCRYPTO_USED(d2i_OCSP_CRLID); +LCRYPTO_USED(i2d_OCSP_CRLID); +LCRYPTO_USED(OCSP_SERVICELOC_new); +LCRYPTO_USED(OCSP_SERVICELOC_free); +LCRYPTO_USED(d2i_OCSP_SERVICELOC); +LCRYPTO_USED(i2d_OCSP_SERVICELOC); +LCRYPTO_USED(OCSP_response_status_str); +LCRYPTO_USED(OCSP_cert_status_str); +LCRYPTO_USED(OCSP_crl_reason_str); +LCRYPTO_USED(OCSP_REQUEST_print); +LCRYPTO_USED(OCSP_RESPONSE_print); +LCRYPTO_USED(OCSP_basic_verify); +LCRYPTO_USED(ERR_load_OCSP_strings); + +#endif /* _LIBCRYPTO_OCSP_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/pem.h b/Libraries/libressl/crypto/hidden/openssl/pem.h new file mode 100644 index 000000000..5838f07f4 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/pem.h @@ -0,0 +1,149 @@ +/* $OpenBSD: pem.h,v 1.2 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_PEM_H +#define _LIBCRYPTO_PEM_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/pem.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(PEM_get_EVP_CIPHER_INFO); +LCRYPTO_USED(PEM_do_header); +LCRYPTO_USED(PEM_read_bio); +LCRYPTO_USED(PEM_write_bio); +LCRYPTO_USED(PEM_bytes_read_bio); +LCRYPTO_USED(PEM_ASN1_read_bio); +LCRYPTO_USED(PEM_ASN1_write_bio); +LCRYPTO_USED(PEM_X509_INFO_read_bio); +LCRYPTO_USED(PEM_X509_INFO_write_bio); +LCRYPTO_USED(PEM_read); +LCRYPTO_USED(PEM_write); +LCRYPTO_USED(PEM_ASN1_read); +LCRYPTO_USED(PEM_ASN1_write); +LCRYPTO_USED(PEM_X509_INFO_read); +LCRYPTO_USED(PEM_SignInit); +LCRYPTO_USED(PEM_SignUpdate); +LCRYPTO_USED(PEM_SignFinal); +LCRYPTO_USED(PEM_def_callback); +LCRYPTO_USED(PEM_proc_type); +LCRYPTO_USED(PEM_dek_info); +LCRYPTO_USED(PEM_read_X509); +LCRYPTO_USED(PEM_read_bio_X509); +LCRYPTO_USED(PEM_write_X509); +LCRYPTO_USED(PEM_write_bio_X509); +LCRYPTO_USED(PEM_read_X509_AUX); +LCRYPTO_USED(PEM_read_bio_X509_AUX); +LCRYPTO_USED(PEM_write_X509_AUX); +LCRYPTO_USED(PEM_write_bio_X509_AUX); +LCRYPTO_USED(PEM_read_X509_REQ); +LCRYPTO_USED(PEM_read_bio_X509_REQ); +LCRYPTO_USED(PEM_write_X509_REQ); +LCRYPTO_USED(PEM_write_bio_X509_REQ); +LCRYPTO_USED(PEM_write_X509_REQ_NEW); +LCRYPTO_USED(PEM_write_bio_X509_REQ_NEW); +LCRYPTO_USED(PEM_read_X509_CRL); +LCRYPTO_USED(PEM_read_bio_X509_CRL); +LCRYPTO_USED(PEM_write_X509_CRL); +LCRYPTO_USED(PEM_write_bio_X509_CRL); +LCRYPTO_USED(PEM_read_PKCS7); +LCRYPTO_USED(PEM_read_bio_PKCS7); +LCRYPTO_USED(PEM_write_PKCS7); +LCRYPTO_USED(PEM_write_bio_PKCS7); +LCRYPTO_USED(PEM_read_PKCS8); +LCRYPTO_USED(PEM_read_bio_PKCS8); +LCRYPTO_USED(PEM_write_PKCS8); +LCRYPTO_USED(PEM_write_bio_PKCS8); +LCRYPTO_USED(PEM_read_PKCS8_PRIV_KEY_INFO); +LCRYPTO_USED(PEM_read_bio_PKCS8_PRIV_KEY_INFO); +LCRYPTO_USED(PEM_write_PKCS8_PRIV_KEY_INFO); +LCRYPTO_USED(PEM_write_bio_PKCS8_PRIV_KEY_INFO); +LCRYPTO_USED(PEM_read_RSAPrivateKey); +LCRYPTO_USED(PEM_read_bio_RSAPrivateKey); +LCRYPTO_USED(PEM_write_RSAPrivateKey); +LCRYPTO_USED(PEM_write_bio_RSAPrivateKey); +LCRYPTO_USED(PEM_read_RSAPublicKey); +LCRYPTO_USED(PEM_read_bio_RSAPublicKey); +LCRYPTO_USED(PEM_write_RSAPublicKey); +LCRYPTO_USED(PEM_write_bio_RSAPublicKey); +LCRYPTO_USED(PEM_read_RSA_PUBKEY); +LCRYPTO_USED(PEM_read_bio_RSA_PUBKEY); +LCRYPTO_USED(PEM_write_RSA_PUBKEY); +LCRYPTO_USED(PEM_write_bio_RSA_PUBKEY); +LCRYPTO_USED(PEM_read_DSAPrivateKey); +LCRYPTO_USED(PEM_read_bio_DSAPrivateKey); +LCRYPTO_USED(PEM_write_DSAPrivateKey); +LCRYPTO_USED(PEM_write_bio_DSAPrivateKey); +LCRYPTO_USED(PEM_read_DSA_PUBKEY); +LCRYPTO_USED(PEM_read_bio_DSA_PUBKEY); +LCRYPTO_USED(PEM_write_DSA_PUBKEY); +LCRYPTO_USED(PEM_write_bio_DSA_PUBKEY); +LCRYPTO_USED(PEM_read_DSAparams); +LCRYPTO_USED(PEM_read_bio_DSAparams); +LCRYPTO_USED(PEM_write_DSAparams); +LCRYPTO_USED(PEM_write_bio_DSAparams); +LCRYPTO_USED(PEM_read_ECPKParameters); +LCRYPTO_USED(PEM_read_bio_ECPKParameters); +LCRYPTO_USED(PEM_write_ECPKParameters); +LCRYPTO_USED(PEM_write_bio_ECPKParameters); +LCRYPTO_USED(PEM_read_ECPrivateKey); +LCRYPTO_USED(PEM_read_bio_ECPrivateKey); +LCRYPTO_USED(PEM_write_ECPrivateKey); +LCRYPTO_USED(PEM_write_bio_ECPrivateKey); +LCRYPTO_USED(PEM_read_EC_PUBKEY); +LCRYPTO_USED(PEM_read_bio_EC_PUBKEY); +LCRYPTO_USED(PEM_write_EC_PUBKEY); +LCRYPTO_USED(PEM_write_bio_EC_PUBKEY); +LCRYPTO_USED(PEM_read_DHparams); +LCRYPTO_USED(PEM_read_bio_DHparams); +LCRYPTO_USED(PEM_write_DHparams); +LCRYPTO_USED(PEM_write_bio_DHparams); +LCRYPTO_USED(PEM_read_PrivateKey); +LCRYPTO_USED(PEM_read_bio_PrivateKey); +LCRYPTO_USED(PEM_write_PrivateKey); +LCRYPTO_USED(PEM_write_bio_PrivateKey); +LCRYPTO_USED(PEM_read_PUBKEY); +LCRYPTO_USED(PEM_read_bio_PUBKEY); +LCRYPTO_USED(PEM_write_PUBKEY); +LCRYPTO_USED(PEM_write_bio_PUBKEY); +LCRYPTO_USED(PEM_write_bio_PrivateKey_traditional); +LCRYPTO_USED(PEM_write_bio_PKCS8PrivateKey_nid); +LCRYPTO_USED(PEM_write_bio_PKCS8PrivateKey); +LCRYPTO_USED(i2d_PKCS8PrivateKey_bio); +LCRYPTO_USED(i2d_PKCS8PrivateKey_nid_bio); +LCRYPTO_USED(d2i_PKCS8PrivateKey_bio); +LCRYPTO_USED(i2d_PKCS8PrivateKey_fp); +LCRYPTO_USED(i2d_PKCS8PrivateKey_nid_fp); +LCRYPTO_USED(PEM_write_PKCS8PrivateKey_nid); +LCRYPTO_USED(d2i_PKCS8PrivateKey_fp); +LCRYPTO_USED(PEM_write_PKCS8PrivateKey); +LCRYPTO_USED(PEM_read_bio_Parameters); +LCRYPTO_USED(PEM_write_bio_Parameters); +LCRYPTO_USED(b2i_PrivateKey); +LCRYPTO_USED(b2i_PublicKey); +LCRYPTO_USED(b2i_PrivateKey_bio); +LCRYPTO_USED(b2i_PublicKey_bio); +LCRYPTO_USED(i2b_PrivateKey_bio); +LCRYPTO_USED(i2b_PublicKey_bio); +LCRYPTO_USED(b2i_PVK_bio); +LCRYPTO_USED(i2b_PVK_bio); +LCRYPTO_USED(ERR_load_PEM_strings); + +#endif /* _LIBCRYPTO_PEM_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/pkcs12.h b/Libraries/libressl/crypto/hidden/openssl/pkcs12.h new file mode 100644 index 000000000..9a2dffa35 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/pkcs12.h @@ -0,0 +1,106 @@ +/* $OpenBSD: pkcs12.h,v 1.2 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_PKCS12_H +#define _LIBCRYPTO_PKCS12_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/pkcs12.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(PKCS12_SAFEBAG_get0_attr); +LCRYPTO_USED(PKCS12_SAFEBAG_get0_attrs); +LCRYPTO_USED(PKCS12_SAFEBAG_get_nid); +LCRYPTO_USED(PKCS12_SAFEBAG_get_bag_nid); +LCRYPTO_USED(PKCS12_SAFEBAG_get1_cert); +LCRYPTO_USED(PKCS12_SAFEBAG_get1_crl); +LCRYPTO_USED(PKCS8_get_attr); +LCRYPTO_USED(PKCS12_mac_present); +LCRYPTO_USED(PKCS12_get0_mac); +LCRYPTO_USED(PKCS12_SAFEBAG_create_cert); +LCRYPTO_USED(PKCS12_SAFEBAG_create_crl); +LCRYPTO_USED(PKCS12_SAFEBAG_create0_p8inf); +LCRYPTO_USED(PKCS12_SAFEBAG_create0_pkcs8); +LCRYPTO_USED(PKCS12_SAFEBAG_create_pkcs8_encrypt); +LCRYPTO_USED(PKCS12_SAFEBAG_get0_p8inf); +LCRYPTO_USED(PKCS12_SAFEBAG_get0_pkcs8); +LCRYPTO_USED(PKCS12_SAFEBAG_get0_safes); +LCRYPTO_USED(PKCS12_SAFEBAG_get0_type); +LCRYPTO_USED(PKCS12_item_pack_safebag); +LCRYPTO_USED(PKCS8_decrypt); +LCRYPTO_USED(PKCS12_decrypt_skey); +LCRYPTO_USED(PKCS8_encrypt); +LCRYPTO_USED(PKCS12_pack_p7data); +LCRYPTO_USED(PKCS12_unpack_p7data); +LCRYPTO_USED(PKCS12_pack_p7encdata); +LCRYPTO_USED(PKCS12_unpack_p7encdata); +LCRYPTO_USED(PKCS12_pack_authsafes); +LCRYPTO_USED(PKCS12_unpack_authsafes); +LCRYPTO_USED(PKCS12_add_localkeyid); +LCRYPTO_USED(PKCS12_add_friendlyname_asc); +LCRYPTO_USED(PKCS12_add_CSPName_asc); +LCRYPTO_USED(PKCS12_add_friendlyname_uni); +LCRYPTO_USED(PKCS8_add_keyusage); +LCRYPTO_USED(PKCS12_get_attr_gen); +LCRYPTO_USED(PKCS12_get_friendlyname); +LCRYPTO_USED(PKCS12_pbe_crypt); +LCRYPTO_USED(PKCS12_item_decrypt_d2i); +LCRYPTO_USED(PKCS12_item_i2d_encrypt); +LCRYPTO_USED(PKCS12_init); +LCRYPTO_USED(PKCS12_key_gen_asc); +LCRYPTO_USED(PKCS12_key_gen_uni); +LCRYPTO_USED(PKCS12_PBE_keyivgen); +LCRYPTO_USED(PKCS12_gen_mac); +LCRYPTO_USED(PKCS12_verify_mac); +LCRYPTO_USED(PKCS12_set_mac); +LCRYPTO_USED(PKCS12_setup_mac); +LCRYPTO_USED(OPENSSL_asc2uni); +LCRYPTO_USED(OPENSSL_uni2asc); +LCRYPTO_USED(PKCS12_new); +LCRYPTO_USED(PKCS12_free); +LCRYPTO_USED(d2i_PKCS12); +LCRYPTO_USED(i2d_PKCS12); +LCRYPTO_USED(PKCS12_MAC_DATA_new); +LCRYPTO_USED(PKCS12_MAC_DATA_free); +LCRYPTO_USED(d2i_PKCS12_MAC_DATA); +LCRYPTO_USED(i2d_PKCS12_MAC_DATA); +LCRYPTO_USED(PKCS12_SAFEBAG_new); +LCRYPTO_USED(PKCS12_SAFEBAG_free); +LCRYPTO_USED(d2i_PKCS12_SAFEBAG); +LCRYPTO_USED(i2d_PKCS12_SAFEBAG); +LCRYPTO_USED(PKCS12_BAGS_new); +LCRYPTO_USED(PKCS12_BAGS_free); +LCRYPTO_USED(d2i_PKCS12_BAGS); +LCRYPTO_USED(i2d_PKCS12_BAGS); +LCRYPTO_USED(PKCS12_PBE_add); +LCRYPTO_USED(PKCS12_parse); +LCRYPTO_USED(PKCS12_create); +LCRYPTO_USED(PKCS12_add_cert); +LCRYPTO_USED(PKCS12_add_key); +LCRYPTO_USED(PKCS12_add_safe); +LCRYPTO_USED(PKCS12_add_safes); +LCRYPTO_USED(i2d_PKCS12_bio); +LCRYPTO_USED(i2d_PKCS12_fp); +LCRYPTO_USED(d2i_PKCS12_bio); +LCRYPTO_USED(d2i_PKCS12_fp); +LCRYPTO_USED(PKCS12_newpass); +LCRYPTO_USED(ERR_load_PKCS12_strings); + +#endif /* _LIBCRYPTO_PKCS12_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/pkcs7.h b/Libraries/libressl/crypto/hidden/openssl/pkcs7.h new file mode 100644 index 000000000..f12b5df17 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/pkcs7.h @@ -0,0 +1,129 @@ +/* $OpenBSD: pkcs7.h,v 1.3 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_PKCS7_H +#define _LIBCRYPTO_PKCS7_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/pkcs7.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(PKCS7_ISSUER_AND_SERIAL_new); +LCRYPTO_USED(PKCS7_ISSUER_AND_SERIAL_free); +LCRYPTO_USED(d2i_PKCS7_ISSUER_AND_SERIAL); +LCRYPTO_USED(i2d_PKCS7_ISSUER_AND_SERIAL); +LCRYPTO_USED(PKCS7_ISSUER_AND_SERIAL_digest); +LCRYPTO_USED(d2i_PKCS7_fp); +LCRYPTO_USED(i2d_PKCS7_fp); +LCRYPTO_USED(PKCS7_dup); +LCRYPTO_USED(d2i_PKCS7_bio); +LCRYPTO_USED(i2d_PKCS7_bio); +LCRYPTO_USED(i2d_PKCS7_bio_stream); +LCRYPTO_USED(PEM_write_bio_PKCS7_stream); +LCRYPTO_USED(PKCS7_SIGNER_INFO_new); +LCRYPTO_USED(PKCS7_SIGNER_INFO_free); +LCRYPTO_USED(d2i_PKCS7_SIGNER_INFO); +LCRYPTO_USED(i2d_PKCS7_SIGNER_INFO); +LCRYPTO_USED(PKCS7_RECIP_INFO_new); +LCRYPTO_USED(PKCS7_RECIP_INFO_free); +LCRYPTO_USED(d2i_PKCS7_RECIP_INFO); +LCRYPTO_USED(i2d_PKCS7_RECIP_INFO); +LCRYPTO_USED(PKCS7_SIGNED_new); +LCRYPTO_USED(PKCS7_SIGNED_free); +LCRYPTO_USED(d2i_PKCS7_SIGNED); +LCRYPTO_USED(i2d_PKCS7_SIGNED); +LCRYPTO_USED(PKCS7_ENC_CONTENT_new); +LCRYPTO_USED(PKCS7_ENC_CONTENT_free); +LCRYPTO_USED(d2i_PKCS7_ENC_CONTENT); +LCRYPTO_USED(i2d_PKCS7_ENC_CONTENT); +LCRYPTO_USED(PKCS7_ENVELOPE_new); +LCRYPTO_USED(PKCS7_ENVELOPE_free); +LCRYPTO_USED(d2i_PKCS7_ENVELOPE); +LCRYPTO_USED(i2d_PKCS7_ENVELOPE); +LCRYPTO_USED(PKCS7_SIGN_ENVELOPE_new); +LCRYPTO_USED(PKCS7_SIGN_ENVELOPE_free); +LCRYPTO_USED(d2i_PKCS7_SIGN_ENVELOPE); +LCRYPTO_USED(i2d_PKCS7_SIGN_ENVELOPE); +LCRYPTO_USED(PKCS7_DIGEST_new); +LCRYPTO_USED(PKCS7_DIGEST_free); +LCRYPTO_USED(d2i_PKCS7_DIGEST); +LCRYPTO_USED(i2d_PKCS7_DIGEST); +LCRYPTO_USED(PKCS7_ENCRYPT_new); +LCRYPTO_USED(PKCS7_ENCRYPT_free); +LCRYPTO_USED(d2i_PKCS7_ENCRYPT); +LCRYPTO_USED(i2d_PKCS7_ENCRYPT); +LCRYPTO_USED(PKCS7_new); +LCRYPTO_USED(PKCS7_free); +LCRYPTO_USED(d2i_PKCS7); +LCRYPTO_USED(i2d_PKCS7); +LCRYPTO_USED(PKCS7_print_ctx); +LCRYPTO_USED(PKCS7_ctrl); +LCRYPTO_USED(PKCS7_set_type); +LCRYPTO_USED(PKCS7_set0_type_other); +LCRYPTO_USED(PKCS7_set_content); +LCRYPTO_USED(PKCS7_SIGNER_INFO_set); +LCRYPTO_USED(PKCS7_SIGNER_INFO_sign); +LCRYPTO_USED(PKCS7_add_signer); +LCRYPTO_USED(PKCS7_add_certificate); +LCRYPTO_USED(PKCS7_add_crl); +LCRYPTO_USED(PKCS7_content_new); +LCRYPTO_USED(PKCS7_dataVerify); +LCRYPTO_USED(PKCS7_signatureVerify); +LCRYPTO_USED(PKCS7_dataInit); +LCRYPTO_USED(PKCS7_dataFinal); +LCRYPTO_USED(PKCS7_dataDecode); +LCRYPTO_USED(PKCS7_add_signature); +LCRYPTO_USED(PKCS7_cert_from_signer_info); +LCRYPTO_USED(PKCS7_set_digest); +LCRYPTO_USED(PKCS7_get_signer_info); +LCRYPTO_USED(PKCS7_add_recipient); +LCRYPTO_USED(PKCS7_SIGNER_INFO_get0_algs); +LCRYPTO_USED(PKCS7_RECIP_INFO_get0_alg); +LCRYPTO_USED(PKCS7_add_recipient_info); +LCRYPTO_USED(PKCS7_RECIP_INFO_set); +LCRYPTO_USED(PKCS7_set_cipher); +LCRYPTO_USED(PKCS7_stream); +LCRYPTO_USED(PKCS7_get_issuer_and_serial); +LCRYPTO_USED(PKCS7_digest_from_attributes); +LCRYPTO_USED(PKCS7_add_signed_attribute); +LCRYPTO_USED(PKCS7_add_attribute); +LCRYPTO_USED(PKCS7_get_attribute); +LCRYPTO_USED(PKCS7_get_signed_attribute); +LCRYPTO_USED(PKCS7_set_signed_attributes); +LCRYPTO_USED(PKCS7_set_attributes); +LCRYPTO_USED(PKCS7_sign); +LCRYPTO_USED(PKCS7_sign_add_signer); +LCRYPTO_USED(PKCS7_final); +LCRYPTO_USED(PKCS7_verify); +LCRYPTO_USED(PKCS7_get0_signers); +LCRYPTO_USED(PKCS7_encrypt); +LCRYPTO_USED(PKCS7_decrypt); +LCRYPTO_USED(PKCS7_add_attrib_smimecap); +LCRYPTO_USED(PKCS7_get_smimecap); +LCRYPTO_USED(PKCS7_simple_smimecap); +LCRYPTO_USED(PKCS7_add_attrib_content_type); +LCRYPTO_USED(PKCS7_add0_attrib_signing_time); +LCRYPTO_USED(PKCS7_add1_attrib_digest); +LCRYPTO_USED(SMIME_write_PKCS7); +LCRYPTO_USED(SMIME_read_PKCS7); +LCRYPTO_USED(BIO_new_PKCS7); +LCRYPTO_USED(ERR_load_PKCS7_strings); + +#endif /* _LIBCRYPTO_PKCS7_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/poly1305.h b/Libraries/libressl/crypto/hidden/openssl/poly1305.h new file mode 100644 index 000000000..7a459cb5a --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/poly1305.h @@ -0,0 +1,32 @@ +/* $OpenBSD: poly1305.h,v 1.2 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_POLY1305_H +#define _LIBCRYPTO_POLY1305_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/poly1305.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(CRYPTO_poly1305_init); +LCRYPTO_USED(CRYPTO_poly1305_update); +LCRYPTO_USED(CRYPTO_poly1305_finish); + +#endif /* _LIBCRYPTO_POLY1305_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/rand.h b/Libraries/libressl/crypto/hidden/openssl/rand.h new file mode 100644 index 000000000..978d10f70 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/rand.h @@ -0,0 +1,33 @@ +/* $OpenBSD: rand.h,v 1.3 2023/07/28 09:53:55 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_RAND_H +#define _LIBCRYPTO_RAND_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/rand.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(RAND_set_rand_method); +LCRYPTO_USED(RAND_get_rand_method); +LCRYPTO_USED(RAND_SSLeay); +LCRYPTO_USED(ERR_load_RAND_strings); + +#endif /* _LIBCRYPTO_RAND_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/rc2.h b/Libraries/libressl/crypto/hidden/openssl/rc2.h new file mode 100644 index 000000000..c08c38d7c --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/rc2.h @@ -0,0 +1,36 @@ +/* $OpenBSD: rc2.h,v 1.1 2023/07/07 13:40:44 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_RC2_H +#define _LIBCRYPTO_RC2_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/rc2.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(RC2_set_key); +LCRYPTO_USED(RC2_ecb_encrypt); +LCRYPTO_USED(RC2_encrypt); +LCRYPTO_USED(RC2_decrypt); +LCRYPTO_USED(RC2_cbc_encrypt); +LCRYPTO_USED(RC2_cfb64_encrypt); +LCRYPTO_USED(RC2_ofb64_encrypt); + +#endif /* _LIBCRYPTO_RC2_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/rsa.h b/Libraries/libressl/crypto/hidden/openssl/rsa.h new file mode 100644 index 000000000..ff47101a0 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/rsa.h @@ -0,0 +1,141 @@ +/* $OpenBSD: rsa.h,v 1.2 2023/07/28 10:05:16 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_RSA_H +#define _LIBCRYPTO_RSA_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/rsa.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(RSA_new); +LCRYPTO_USED(RSA_new_method); +LCRYPTO_USED(RSA_bits); +LCRYPTO_USED(RSA_size); +LCRYPTO_USED(RSA_generate_key); +LCRYPTO_USED(RSA_generate_key_ex); +LCRYPTO_USED(RSA_check_key); +LCRYPTO_USED(RSA_public_encrypt); +LCRYPTO_USED(RSA_private_encrypt); +LCRYPTO_USED(RSA_public_decrypt); +LCRYPTO_USED(RSA_private_decrypt); +LCRYPTO_USED(RSA_free); +LCRYPTO_USED(RSA_up_ref); +LCRYPTO_USED(RSA_flags); +LCRYPTO_USED(RSA_set_default_method); +LCRYPTO_USED(RSA_get_default_method); +LCRYPTO_USED(RSA_get_method); +LCRYPTO_USED(RSA_set_method); +LCRYPTO_USED(RSA_PKCS1_OpenSSL); +LCRYPTO_USED(RSA_PKCS1_SSLeay); +LCRYPTO_USED(RSA_pkey_ctx_ctrl); +LCRYPTO_USED(d2i_RSAPublicKey); +LCRYPTO_USED(i2d_RSAPublicKey); +LCRYPTO_USED(d2i_RSAPrivateKey); +LCRYPTO_USED(i2d_RSAPrivateKey); +LCRYPTO_USED(RSA_PSS_PARAMS_new); +LCRYPTO_USED(RSA_PSS_PARAMS_free); +LCRYPTO_USED(d2i_RSA_PSS_PARAMS); +LCRYPTO_USED(i2d_RSA_PSS_PARAMS); +LCRYPTO_USED(RSA_OAEP_PARAMS_new); +LCRYPTO_USED(RSA_OAEP_PARAMS_free); +LCRYPTO_USED(d2i_RSA_OAEP_PARAMS); +LCRYPTO_USED(i2d_RSA_OAEP_PARAMS); +LCRYPTO_USED(RSA_print_fp); +LCRYPTO_USED(RSA_print); +LCRYPTO_USED(RSA_sign); +LCRYPTO_USED(RSA_verify); +LCRYPTO_USED(RSA_sign_ASN1_OCTET_STRING); +LCRYPTO_USED(RSA_verify_ASN1_OCTET_STRING); +LCRYPTO_USED(RSA_blinding_on); +LCRYPTO_USED(RSA_blinding_off); +LCRYPTO_USED(RSA_padding_add_PKCS1_type_1); +LCRYPTO_USED(RSA_padding_check_PKCS1_type_1); +LCRYPTO_USED(RSA_padding_add_PKCS1_type_2); +LCRYPTO_USED(RSA_padding_check_PKCS1_type_2); +LCRYPTO_USED(PKCS1_MGF1); +LCRYPTO_USED(RSA_padding_add_PKCS1_OAEP); +LCRYPTO_USED(RSA_padding_check_PKCS1_OAEP); +LCRYPTO_USED(RSA_padding_add_PKCS1_OAEP_mgf1); +LCRYPTO_USED(RSA_padding_check_PKCS1_OAEP_mgf1); +LCRYPTO_USED(RSA_padding_add_none); +LCRYPTO_USED(RSA_padding_check_none); +LCRYPTO_USED(RSA_verify_PKCS1_PSS); +LCRYPTO_USED(RSA_padding_add_PKCS1_PSS); +LCRYPTO_USED(RSA_verify_PKCS1_PSS_mgf1); +LCRYPTO_USED(RSA_padding_add_PKCS1_PSS_mgf1); +LCRYPTO_USED(RSA_get_ex_new_index); +LCRYPTO_USED(RSA_set_ex_data); +LCRYPTO_USED(RSA_get_ex_data); +LCRYPTO_USED(RSA_security_bits); +LCRYPTO_USED(RSA_get0_key); +LCRYPTO_USED(RSA_set0_key); +LCRYPTO_USED(RSA_get0_crt_params); +LCRYPTO_USED(RSA_set0_crt_params); +LCRYPTO_USED(RSA_get0_factors); +LCRYPTO_USED(RSA_set0_factors); +LCRYPTO_USED(RSA_get0_n); +LCRYPTO_USED(RSA_get0_e); +LCRYPTO_USED(RSA_get0_d); +LCRYPTO_USED(RSA_get0_p); +LCRYPTO_USED(RSA_get0_q); +LCRYPTO_USED(RSA_get0_dmp1); +LCRYPTO_USED(RSA_get0_dmq1); +LCRYPTO_USED(RSA_get0_iqmp); +LCRYPTO_USED(RSA_get0_pss_params); +LCRYPTO_USED(RSA_clear_flags); +LCRYPTO_USED(RSA_test_flags); +LCRYPTO_USED(RSA_set_flags); +LCRYPTO_USED(RSAPublicKey_dup); +LCRYPTO_USED(RSAPrivateKey_dup); +LCRYPTO_USED(RSA_meth_new); +LCRYPTO_USED(RSA_meth_free); +LCRYPTO_USED(RSA_meth_dup); +LCRYPTO_USED(RSA_meth_set1_name); +LCRYPTO_USED(RSA_meth_set_priv_enc); +LCRYPTO_USED(RSA_meth_set_priv_dec); +LCRYPTO_USED(RSA_meth_get_finish); +LCRYPTO_USED(RSA_meth_set_finish); +LCRYPTO_USED(RSA_meth_set_pub_enc); +LCRYPTO_USED(RSA_meth_set_pub_dec); +LCRYPTO_USED(RSA_meth_set_mod_exp); +LCRYPTO_USED(RSA_meth_set_bn_mod_exp); +LCRYPTO_USED(RSA_meth_set_init); +LCRYPTO_USED(RSA_meth_set_keygen); +LCRYPTO_USED(RSA_meth_set_flags); +LCRYPTO_USED(RSA_meth_set0_app_data); +LCRYPTO_USED(RSA_meth_get0_name); +LCRYPTO_USED(RSA_meth_get_pub_enc); +LCRYPTO_USED(RSA_meth_get_pub_dec); +LCRYPTO_USED(RSA_meth_get_priv_enc); +LCRYPTO_USED(RSA_meth_get_priv_dec); +LCRYPTO_USED(RSA_meth_get_mod_exp); +LCRYPTO_USED(RSA_meth_get_bn_mod_exp); +LCRYPTO_USED(RSA_meth_get_init); +LCRYPTO_USED(RSA_meth_get_keygen); +LCRYPTO_USED(RSA_meth_get_flags); +LCRYPTO_USED(RSA_meth_get0_app_data); +LCRYPTO_USED(RSA_meth_get_sign); +LCRYPTO_USED(RSA_meth_set_sign); +LCRYPTO_USED(RSA_meth_get_verify); +LCRYPTO_USED(RSA_meth_set_verify); +LCRYPTO_USED(ERR_load_RSA_strings); + +#endif /* _LIBCRYPTO_RSA_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/sha.h b/Libraries/libressl/crypto/hidden/openssl/sha.h new file mode 100644 index 000000000..ee5879320 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/sha.h @@ -0,0 +1,52 @@ +/* $OpenBSD: sha.h,v 1.1 2023/07/08 12:24:10 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_SHA_H +#define _LIBCRYPTO_SHA_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/sha.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(SHA1_Init); +LCRYPTO_USED(SHA1_Update); +LCRYPTO_USED(SHA1_Final); +LCRYPTO_USED(SHA1); +LCRYPTO_USED(SHA1_Transform); +LCRYPTO_USED(SHA224_Init); +LCRYPTO_USED(SHA224_Update); +LCRYPTO_USED(SHA224_Final); +LCRYPTO_USED(SHA224); +LCRYPTO_USED(SHA256_Init); +LCRYPTO_USED(SHA256_Update); +LCRYPTO_USED(SHA256_Final); +LCRYPTO_USED(SHA256); +LCRYPTO_USED(SHA256_Transform); +LCRYPTO_USED(SHA384_Init); +LCRYPTO_USED(SHA384_Update); +LCRYPTO_USED(SHA384_Final); +LCRYPTO_USED(SHA384); +LCRYPTO_USED(SHA512_Init); +LCRYPTO_USED(SHA512_Update); +LCRYPTO_USED(SHA512_Final); +LCRYPTO_USED(SHA512); +LCRYPTO_USED(SHA512_Transform); + +#endif /* _LIBCRYPTO_SHA_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/sm3.h b/Libraries/libressl/crypto/hidden/openssl/sm3.h new file mode 100644 index 000000000..12a0e1ad1 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/sm3.h @@ -0,0 +1,32 @@ +/* $OpenBSD: sm3.h,v 1.3 2023/07/08 06:13:08 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_SM3_H +#define _LIBCRYPTO_SM3_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/sm3.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(SM3_Init); +LCRYPTO_USED(SM3_Update); +LCRYPTO_USED(SM3_Final); + +#endif /* _LIBCRYPTO_SM3_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/sm4.h b/Libraries/libressl/crypto/hidden/openssl/sm4.h new file mode 100644 index 000000000..1b80e5cbc --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/sm4.h @@ -0,0 +1,32 @@ +/* $OpenBSD: sm4.h,v 1.2 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_SM4_H +#define _LIBCRYPTO_SM4_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/sm4.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(SM4_set_key); +LCRYPTO_USED(SM4_decrypt); +LCRYPTO_USED(SM4_encrypt); + +#endif /* _LIBCRYPTO_SM4_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/stack.h b/Libraries/libressl/crypto/hidden/openssl/stack.h new file mode 100644 index 000000000..38bb02e86 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/stack.h @@ -0,0 +1,50 @@ +/* $OpenBSD: stack.h,v 1.2 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_STACK_H +#define _LIBCRYPTO_STACK_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/stack.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(sk_num); +LCRYPTO_USED(sk_value); +LCRYPTO_USED(sk_set); +LCRYPTO_USED(sk_new); +LCRYPTO_USED(sk_new_null); +LCRYPTO_USED(sk_free); +LCRYPTO_USED(sk_pop_free); +LCRYPTO_USED(sk_insert); +LCRYPTO_USED(sk_delete); +LCRYPTO_USED(sk_delete_ptr); +LCRYPTO_USED(sk_find); +LCRYPTO_USED(sk_find_ex); +LCRYPTO_USED(sk_push); +LCRYPTO_USED(sk_unshift); +LCRYPTO_USED(sk_shift); +LCRYPTO_USED(sk_pop); +LCRYPTO_USED(sk_zero); +LCRYPTO_USED(sk_set_cmp_func); +LCRYPTO_USED(sk_dup); +LCRYPTO_USED(sk_sort); +LCRYPTO_USED(sk_is_sorted); + +#endif /* _LIBCRYPTO_STACK_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/ts.h b/Libraries/libressl/crypto/hidden/openssl/ts.h new file mode 100644 index 000000000..0acad2137 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/ts.h @@ -0,0 +1,217 @@ +/* $OpenBSD: ts.h,v 1.3 2023/07/28 09:53:55 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_TS_H +#define _LIBCRYPTO_TS_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/ts.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(TS_REQ_new); +LCRYPTO_USED(TS_REQ_free); +LCRYPTO_USED(i2d_TS_REQ); +LCRYPTO_USED(d2i_TS_REQ); +LCRYPTO_USED(TS_REQ_dup); +LCRYPTO_USED(d2i_TS_REQ_fp); +LCRYPTO_USED(i2d_TS_REQ_fp); +LCRYPTO_USED(d2i_TS_REQ_bio); +LCRYPTO_USED(i2d_TS_REQ_bio); +LCRYPTO_USED(TS_MSG_IMPRINT_new); +LCRYPTO_USED(TS_MSG_IMPRINT_free); +LCRYPTO_USED(i2d_TS_MSG_IMPRINT); +LCRYPTO_USED(d2i_TS_MSG_IMPRINT); +LCRYPTO_USED(TS_MSG_IMPRINT_dup); +LCRYPTO_USED(d2i_TS_MSG_IMPRINT_fp); +LCRYPTO_USED(i2d_TS_MSG_IMPRINT_fp); +LCRYPTO_USED(d2i_TS_MSG_IMPRINT_bio); +LCRYPTO_USED(i2d_TS_MSG_IMPRINT_bio); +LCRYPTO_USED(TS_RESP_new); +LCRYPTO_USED(TS_RESP_free); +LCRYPTO_USED(i2d_TS_RESP); +LCRYPTO_USED(d2i_TS_RESP); +LCRYPTO_USED(PKCS7_to_TS_TST_INFO); +LCRYPTO_USED(TS_RESP_dup); +LCRYPTO_USED(d2i_TS_RESP_fp); +LCRYPTO_USED(i2d_TS_RESP_fp); +LCRYPTO_USED(d2i_TS_RESP_bio); +LCRYPTO_USED(i2d_TS_RESP_bio); +LCRYPTO_USED(TS_STATUS_INFO_new); +LCRYPTO_USED(TS_STATUS_INFO_free); +LCRYPTO_USED(i2d_TS_STATUS_INFO); +LCRYPTO_USED(d2i_TS_STATUS_INFO); +LCRYPTO_USED(TS_STATUS_INFO_dup); +LCRYPTO_USED(TS_TST_INFO_new); +LCRYPTO_USED(TS_TST_INFO_free); +LCRYPTO_USED(i2d_TS_TST_INFO); +LCRYPTO_USED(d2i_TS_TST_INFO); +LCRYPTO_USED(TS_TST_INFO_dup); +LCRYPTO_USED(d2i_TS_TST_INFO_fp); +LCRYPTO_USED(i2d_TS_TST_INFO_fp); +LCRYPTO_USED(d2i_TS_TST_INFO_bio); +LCRYPTO_USED(i2d_TS_TST_INFO_bio); +LCRYPTO_USED(TS_ACCURACY_new); +LCRYPTO_USED(TS_ACCURACY_free); +LCRYPTO_USED(i2d_TS_ACCURACY); +LCRYPTO_USED(d2i_TS_ACCURACY); +LCRYPTO_USED(TS_ACCURACY_dup); +LCRYPTO_USED(ESS_ISSUER_SERIAL_new); +LCRYPTO_USED(ESS_ISSUER_SERIAL_free); +LCRYPTO_USED(i2d_ESS_ISSUER_SERIAL); +LCRYPTO_USED(d2i_ESS_ISSUER_SERIAL); +LCRYPTO_USED(ESS_ISSUER_SERIAL_dup); +LCRYPTO_USED(ESS_CERT_ID_new); +LCRYPTO_USED(ESS_CERT_ID_free); +LCRYPTO_USED(i2d_ESS_CERT_ID); +LCRYPTO_USED(d2i_ESS_CERT_ID); +LCRYPTO_USED(ESS_CERT_ID_dup); +LCRYPTO_USED(ESS_SIGNING_CERT_new); +LCRYPTO_USED(ESS_SIGNING_CERT_free); +LCRYPTO_USED(i2d_ESS_SIGNING_CERT); +LCRYPTO_USED(d2i_ESS_SIGNING_CERT); +LCRYPTO_USED(ESS_SIGNING_CERT_dup); +LCRYPTO_USED(TS_REQ_set_version); +LCRYPTO_USED(TS_REQ_get_version); +LCRYPTO_USED(TS_REQ_set_msg_imprint); +LCRYPTO_USED(TS_REQ_get_msg_imprint); +LCRYPTO_USED(TS_MSG_IMPRINT_set_algo); +LCRYPTO_USED(TS_MSG_IMPRINT_get_algo); +LCRYPTO_USED(TS_MSG_IMPRINT_set_msg); +LCRYPTO_USED(TS_MSG_IMPRINT_get_msg); +LCRYPTO_USED(TS_REQ_set_policy_id); +LCRYPTO_USED(TS_REQ_get_policy_id); +LCRYPTO_USED(TS_REQ_set_nonce); +LCRYPTO_USED(TS_REQ_get_nonce); +LCRYPTO_USED(TS_REQ_set_cert_req); +LCRYPTO_USED(TS_REQ_get_cert_req); +LCRYPTO_USED(TS_REQ_get_exts); +LCRYPTO_USED(TS_REQ_ext_free); +LCRYPTO_USED(TS_REQ_get_ext_count); +LCRYPTO_USED(TS_REQ_get_ext_by_NID); +LCRYPTO_USED(TS_REQ_get_ext_by_OBJ); +LCRYPTO_USED(TS_REQ_get_ext_by_critical); +LCRYPTO_USED(TS_REQ_get_ext); +LCRYPTO_USED(TS_REQ_delete_ext); +LCRYPTO_USED(TS_REQ_add_ext); +LCRYPTO_USED(TS_REQ_get_ext_d2i); +LCRYPTO_USED(TS_REQ_print_bio); +LCRYPTO_USED(TS_RESP_set_status_info); +LCRYPTO_USED(TS_RESP_get_status_info); +LCRYPTO_USED(TS_STATUS_INFO_get0_failure_info); +LCRYPTO_USED(TS_STATUS_INFO_get0_text); +LCRYPTO_USED(TS_STATUS_INFO_get0_status); +LCRYPTO_USED(TS_STATUS_INFO_set_status); +LCRYPTO_USED(TS_RESP_set_tst_info); +LCRYPTO_USED(TS_RESP_get_token); +LCRYPTO_USED(TS_RESP_get_tst_info); +LCRYPTO_USED(TS_TST_INFO_set_version); +LCRYPTO_USED(TS_TST_INFO_get_version); +LCRYPTO_USED(TS_TST_INFO_set_policy_id); +LCRYPTO_USED(TS_TST_INFO_get_policy_id); +LCRYPTO_USED(TS_TST_INFO_set_msg_imprint); +LCRYPTO_USED(TS_TST_INFO_get_msg_imprint); +LCRYPTO_USED(TS_TST_INFO_set_serial); +LCRYPTO_USED(TS_TST_INFO_get_serial); +LCRYPTO_USED(TS_TST_INFO_set_time); +LCRYPTO_USED(TS_TST_INFO_get_time); +LCRYPTO_USED(TS_TST_INFO_set_accuracy); +LCRYPTO_USED(TS_TST_INFO_get_accuracy); +LCRYPTO_USED(TS_ACCURACY_set_seconds); +LCRYPTO_USED(TS_ACCURACY_get_seconds); +LCRYPTO_USED(TS_ACCURACY_set_millis); +LCRYPTO_USED(TS_ACCURACY_get_millis); +LCRYPTO_USED(TS_ACCURACY_set_micros); +LCRYPTO_USED(TS_ACCURACY_get_micros); +LCRYPTO_USED(TS_TST_INFO_set_ordering); +LCRYPTO_USED(TS_TST_INFO_get_ordering); +LCRYPTO_USED(TS_TST_INFO_set_nonce); +LCRYPTO_USED(TS_TST_INFO_get_nonce); +LCRYPTO_USED(TS_TST_INFO_set_tsa); +LCRYPTO_USED(TS_TST_INFO_get_tsa); +LCRYPTO_USED(TS_TST_INFO_get_exts); +LCRYPTO_USED(TS_TST_INFO_ext_free); +LCRYPTO_USED(TS_TST_INFO_get_ext_count); +LCRYPTO_USED(TS_TST_INFO_get_ext_by_NID); +LCRYPTO_USED(TS_TST_INFO_get_ext_by_OBJ); +LCRYPTO_USED(TS_TST_INFO_get_ext_by_critical); +LCRYPTO_USED(TS_TST_INFO_get_ext); +LCRYPTO_USED(TS_TST_INFO_delete_ext); +LCRYPTO_USED(TS_TST_INFO_add_ext); +LCRYPTO_USED(TS_TST_INFO_get_ext_d2i); +LCRYPTO_USED(TS_RESP_CTX_new); +LCRYPTO_USED(TS_RESP_CTX_free); +LCRYPTO_USED(TS_RESP_CTX_set_signer_cert); +LCRYPTO_USED(TS_RESP_CTX_set_signer_key); +LCRYPTO_USED(TS_RESP_CTX_set_def_policy); +LCRYPTO_USED(TS_RESP_CTX_set_certs); +LCRYPTO_USED(TS_RESP_CTX_add_policy); +LCRYPTO_USED(TS_RESP_CTX_add_md); +LCRYPTO_USED(TS_RESP_CTX_set_accuracy); +LCRYPTO_USED(TS_RESP_CTX_set_clock_precision_digits); +LCRYPTO_USED(TS_RESP_CTX_add_flags); +LCRYPTO_USED(TS_RESP_CTX_set_serial_cb); +LCRYPTO_USED(TS_RESP_CTX_set_time_cb); +LCRYPTO_USED(TS_RESP_CTX_set_extension_cb); +LCRYPTO_USED(TS_RESP_CTX_set_status_info); +LCRYPTO_USED(TS_RESP_CTX_set_status_info_cond); +LCRYPTO_USED(TS_RESP_CTX_add_failure_info); +LCRYPTO_USED(TS_RESP_CTX_get_request); +LCRYPTO_USED(TS_RESP_CTX_get_tst_info); +LCRYPTO_USED(TS_RESP_create_response); +LCRYPTO_USED(TS_RESP_verify_signature); +LCRYPTO_USED(TS_RESP_verify_response); +LCRYPTO_USED(TS_RESP_verify_token); +LCRYPTO_USED(TS_VERIFY_CTX_new); +LCRYPTO_USED(TS_VERIFY_CTX_free); +LCRYPTO_USED(TS_VERIFY_CTX_cleanup); +LCRYPTO_USED(TS_VERIFY_CTX_add_flags); +LCRYPTO_USED(TS_VERIFY_CTX_set_flags); +LCRYPTO_USED(TS_VERIFY_CTX_set_data); +LCRYPTO_USED(TS_VERIFY_CTX_set_store); +LCRYPTO_USED(TS_VERIFY_CTX_set_certs); +LCRYPTO_USED(TS_VERIFY_CTX_set_imprint); +LCRYPTO_USED(TS_REQ_to_TS_VERIFY_CTX); +LCRYPTO_USED(TS_RESP_print_bio); +LCRYPTO_USED(TS_STATUS_INFO_print_bio); +LCRYPTO_USED(TS_TST_INFO_print_bio); +LCRYPTO_USED(TS_ASN1_INTEGER_print_bio); +LCRYPTO_USED(TS_OBJ_print_bio); +LCRYPTO_USED(TS_ext_print_bio); +LCRYPTO_USED(TS_X509_ALGOR_print_bio); +LCRYPTO_USED(TS_MSG_IMPRINT_print_bio); +LCRYPTO_USED(TS_CONF_load_cert); +LCRYPTO_USED(TS_CONF_load_certs); +LCRYPTO_USED(TS_CONF_load_key); +LCRYPTO_USED(TS_CONF_get_tsa_section); +LCRYPTO_USED(TS_CONF_set_serial); +LCRYPTO_USED(TS_CONF_set_signer_cert); +LCRYPTO_USED(TS_CONF_set_certs); +LCRYPTO_USED(TS_CONF_set_signer_key); +LCRYPTO_USED(TS_CONF_set_def_policy); +LCRYPTO_USED(TS_CONF_set_policies); +LCRYPTO_USED(TS_CONF_set_digests); +LCRYPTO_USED(TS_CONF_set_accuracy); +LCRYPTO_USED(TS_CONF_set_clock_precision_digits); +LCRYPTO_USED(TS_CONF_set_ordering); +LCRYPTO_USED(TS_CONF_set_tsa_name); +LCRYPTO_USED(TS_CONF_set_ess_cert_id_chain); +LCRYPTO_USED(ERR_load_TS_strings); + +#endif /* _LIBCRYPTO_TS_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/txt_db.h b/Libraries/libressl/crypto/hidden/openssl/txt_db.h new file mode 100644 index 000000000..f93dbc67d --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/txt_db.h @@ -0,0 +1,35 @@ +/* $OpenBSD: txt_db.h,v 1.1 2023/07/08 11:28:03 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_TXT_DB_H +#define _LIBCRYPTO_TXT_DB_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/txt_db.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(TXT_DB_read); +LCRYPTO_USED(TXT_DB_write); +LCRYPTO_USED(TXT_DB_create_index); +LCRYPTO_USED(TXT_DB_free); +LCRYPTO_USED(TXT_DB_get_by_index); +LCRYPTO_USED(TXT_DB_insert); + +#endif /* _LIBCRYPTO_TXT_DB_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/ui.h b/Libraries/libressl/crypto/hidden/openssl/ui.h new file mode 100644 index 000000000..f6c749f7b --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/ui.h @@ -0,0 +1,83 @@ +/* $OpenBSD: ui.h,v 1.3 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_UI_H +#define _LIBCRYPTO_UI_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/ui.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(UI_new); +LCRYPTO_USED(UI_new_method); +LCRYPTO_USED(UI_free); +LCRYPTO_USED(UI_add_input_string); +LCRYPTO_USED(UI_dup_input_string); +LCRYPTO_USED(UI_add_verify_string); +LCRYPTO_USED(UI_dup_verify_string); +LCRYPTO_USED(UI_add_input_boolean); +LCRYPTO_USED(UI_dup_input_boolean); +LCRYPTO_USED(UI_add_info_string); +LCRYPTO_USED(UI_dup_info_string); +LCRYPTO_USED(UI_add_error_string); +LCRYPTO_USED(UI_dup_error_string); +LCRYPTO_USED(UI_construct_prompt); +LCRYPTO_USED(UI_add_user_data); +LCRYPTO_USED(UI_get0_user_data); +LCRYPTO_USED(UI_get0_result); +LCRYPTO_USED(UI_process); +LCRYPTO_USED(UI_ctrl); +LCRYPTO_USED(UI_get_ex_new_index); +LCRYPTO_USED(UI_set_ex_data); +LCRYPTO_USED(UI_get_ex_data); +LCRYPTO_USED(UI_set_default_method); +LCRYPTO_USED(UI_get_default_method); +LCRYPTO_USED(UI_get_method); +LCRYPTO_USED(UI_set_method); +LCRYPTO_USED(UI_OpenSSL); +LCRYPTO_USED(UI_null); +LCRYPTO_USED(UI_create_method); +LCRYPTO_USED(UI_destroy_method); +LCRYPTO_USED(UI_method_set_opener); +LCRYPTO_USED(UI_method_set_writer); +LCRYPTO_USED(UI_method_set_flusher); +LCRYPTO_USED(UI_method_set_reader); +LCRYPTO_USED(UI_method_set_closer); +LCRYPTO_USED(UI_method_set_prompt_constructor); +LCRYPTO_USED(UI_method_get_opener); +LCRYPTO_USED(UI_method_get_writer); +LCRYPTO_USED(UI_method_get_flusher); +LCRYPTO_USED(UI_method_get_reader); +LCRYPTO_USED(UI_method_get_closer); +LCRYPTO_USED(UI_get_string_type); +LCRYPTO_USED(UI_get_input_flags); +LCRYPTO_USED(UI_get0_output_string); +LCRYPTO_USED(UI_get0_action_string); +LCRYPTO_USED(UI_get0_result_string); +LCRYPTO_USED(UI_get0_test_string); +LCRYPTO_USED(UI_get_result_minsize); +LCRYPTO_USED(UI_get_result_maxsize); +LCRYPTO_USED(UI_set_result); +LCRYPTO_USED(UI_UTIL_read_pw_string); +LCRYPTO_USED(UI_UTIL_read_pw); +LCRYPTO_USED(ERR_load_UI_strings); +LCRYPTO_USED(UI_method_get_prompt_constructor); + +#endif /* _LIBCRYPTO_UI_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/x509.h b/Libraries/libressl/crypto/hidden/openssl/x509.h new file mode 100644 index 000000000..13bd5b533 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/x509.h @@ -0,0 +1,283 @@ +/* $OpenBSD: x509.h,v 1.3 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_X509_H +#define _LIBCRYPTO_X509_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/x509.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(X509_CRL_up_ref); +LCRYPTO_USED(i2d_re_X509_CRL_tbs); +LCRYPTO_USED(X509_get_X509_PUBKEY); +LCRYPTO_USED(X509_verify_cert_error_string); +LCRYPTO_USED(X509_verify); +LCRYPTO_USED(X509_REQ_verify); +LCRYPTO_USED(NETSCAPE_SPKI_verify); +LCRYPTO_USED(NETSCAPE_SPKI_b64_decode); +LCRYPTO_USED(NETSCAPE_SPKI_b64_encode); +LCRYPTO_USED(NETSCAPE_SPKI_get_pubkey); +LCRYPTO_USED(NETSCAPE_SPKI_set_pubkey); +LCRYPTO_USED(X509_sign); +LCRYPTO_USED(X509_sign_ctx); +LCRYPTO_USED(X509_REQ_sign); +LCRYPTO_USED(X509_REQ_sign_ctx); +LCRYPTO_USED(X509_CRL_sign); +LCRYPTO_USED(X509_CRL_sign_ctx); +LCRYPTO_USED(NETSCAPE_SPKI_sign); +LCRYPTO_USED(X509_pubkey_digest); +LCRYPTO_USED(X509_digest); +LCRYPTO_USED(X509_CRL_digest); +LCRYPTO_USED(X509_REQ_digest); +LCRYPTO_USED(X509_NAME_digest); +LCRYPTO_USED(d2i_X509_fp); +LCRYPTO_USED(i2d_X509_fp); +LCRYPTO_USED(d2i_X509_CRL_fp); +LCRYPTO_USED(i2d_X509_CRL_fp); +LCRYPTO_USED(d2i_X509_REQ_fp); +LCRYPTO_USED(i2d_X509_REQ_fp); +LCRYPTO_USED(d2i_RSAPrivateKey_fp); +LCRYPTO_USED(i2d_RSAPrivateKey_fp); +LCRYPTO_USED(d2i_RSAPublicKey_fp); +LCRYPTO_USED(i2d_RSAPublicKey_fp); +LCRYPTO_USED(d2i_DSAPrivateKey_fp); +LCRYPTO_USED(i2d_DSAPrivateKey_fp); +LCRYPTO_USED(d2i_ECPrivateKey_fp); +LCRYPTO_USED(i2d_ECPrivateKey_fp); +LCRYPTO_USED(d2i_PKCS8_fp); +LCRYPTO_USED(i2d_PKCS8_fp); +LCRYPTO_USED(d2i_PKCS8_PRIV_KEY_INFO_fp); +LCRYPTO_USED(i2d_PKCS8_PRIV_KEY_INFO_fp); +LCRYPTO_USED(i2d_PKCS8PrivateKeyInfo_fp); +LCRYPTO_USED(i2d_PrivateKey_fp); +LCRYPTO_USED(d2i_PrivateKey_fp); +LCRYPTO_USED(d2i_X509_bio); +LCRYPTO_USED(i2d_X509_bio); +LCRYPTO_USED(d2i_X509_CRL_bio); +LCRYPTO_USED(i2d_X509_CRL_bio); +LCRYPTO_USED(d2i_X509_REQ_bio); +LCRYPTO_USED(i2d_X509_REQ_bio); +LCRYPTO_USED(d2i_RSAPrivateKey_bio); +LCRYPTO_USED(i2d_RSAPrivateKey_bio); +LCRYPTO_USED(d2i_RSAPublicKey_bio); +LCRYPTO_USED(i2d_RSAPublicKey_bio); +LCRYPTO_USED(d2i_DSAPrivateKey_bio); +LCRYPTO_USED(i2d_DSAPrivateKey_bio); +LCRYPTO_USED(d2i_ECPrivateKey_bio); +LCRYPTO_USED(i2d_ECPrivateKey_bio); +LCRYPTO_USED(d2i_PKCS8_bio); +LCRYPTO_USED(i2d_PKCS8_bio); +LCRYPTO_USED(d2i_PKCS8_PRIV_KEY_INFO_bio); +LCRYPTO_USED(i2d_PKCS8_PRIV_KEY_INFO_bio); +LCRYPTO_USED(i2d_PKCS8PrivateKeyInfo_bio); +LCRYPTO_USED(i2d_PrivateKey_bio); +LCRYPTO_USED(d2i_PrivateKey_bio); +LCRYPTO_USED(X509_cmp_time); +LCRYPTO_USED(X509_cmp_current_time); +LCRYPTO_USED(X509_time_adj); +LCRYPTO_USED(X509_time_adj_ex); +LCRYPTO_USED(X509_gmtime_adj); +LCRYPTO_USED(X509_get_default_cert_area); +LCRYPTO_USED(X509_get_default_cert_dir); +LCRYPTO_USED(X509_get_default_cert_file); +LCRYPTO_USED(X509_get_default_cert_dir_env); +LCRYPTO_USED(X509_get_default_cert_file_env); +LCRYPTO_USED(X509_get_default_private_dir); +LCRYPTO_USED(X509_to_X509_REQ); +LCRYPTO_USED(X509_REQ_to_X509); +LCRYPTO_USED(X509_get_pubkey_parameters); +LCRYPTO_USED(X509_TRUST_set_default); +LCRYPTO_USED(X509_TRUST_set); +LCRYPTO_USED(X509_NAME_oneline); +LCRYPTO_USED(X509_get0_extensions); +LCRYPTO_USED(X509_get0_tbs_sigalg); +LCRYPTO_USED(X509_get0_uids); +LCRYPTO_USED(X509_set_version); +LCRYPTO_USED(X509_get_version); +LCRYPTO_USED(X509_set_serialNumber); +LCRYPTO_USED(X509_get_serialNumber); +LCRYPTO_USED(X509_get0_serialNumber); +LCRYPTO_USED(X509_set_issuer_name); +LCRYPTO_USED(X509_get_issuer_name); +LCRYPTO_USED(X509_set_subject_name); +LCRYPTO_USED(X509_get_subject_name); +LCRYPTO_USED(X509_set_notBefore); +LCRYPTO_USED(X509_set1_notBefore); +LCRYPTO_USED(X509_set_notAfter); +LCRYPTO_USED(X509_set1_notAfter); +LCRYPTO_USED(X509_get0_notBefore); +LCRYPTO_USED(X509_getm_notBefore); +LCRYPTO_USED(X509_get0_notAfter); +LCRYPTO_USED(X509_getm_notAfter); +LCRYPTO_USED(X509_set_pubkey); +LCRYPTO_USED(X509_get_pubkey); +LCRYPTO_USED(X509_get0_pubkey); +LCRYPTO_USED(X509_get0_pubkey_bitstr); +LCRYPTO_USED(X509_certificate_type); +LCRYPTO_USED(X509_get_signature_type); +LCRYPTO_USED(X509_REQ_set_version); +LCRYPTO_USED(X509_REQ_get_version); +LCRYPTO_USED(X509_REQ_set_subject_name); +LCRYPTO_USED(X509_REQ_get_subject_name); +LCRYPTO_USED(X509_REQ_set_pubkey); +LCRYPTO_USED(X509_REQ_get_pubkey); +LCRYPTO_USED(i2d_re_X509_REQ_tbs); +LCRYPTO_USED(X509_REQ_get0_pubkey); +LCRYPTO_USED(X509_REQ_extension_nid); +LCRYPTO_USED(X509_REQ_get_extension_nids); +LCRYPTO_USED(X509_REQ_set_extension_nids); +LCRYPTO_USED(X509_REQ_get_extensions); +LCRYPTO_USED(X509_REQ_add_extensions_nid); +LCRYPTO_USED(X509_REQ_add_extensions); +LCRYPTO_USED(X509_REQ_get_attr_count); +LCRYPTO_USED(X509_REQ_get_attr_by_NID); +LCRYPTO_USED(X509_REQ_get_attr_by_OBJ); +LCRYPTO_USED(X509_REQ_get_attr); +LCRYPTO_USED(X509_REQ_delete_attr); +LCRYPTO_USED(X509_REQ_add1_attr); +LCRYPTO_USED(X509_REQ_add1_attr_by_OBJ); +LCRYPTO_USED(X509_REQ_add1_attr_by_NID); +LCRYPTO_USED(X509_REQ_add1_attr_by_txt); +LCRYPTO_USED(X509_CRL_set_version); +LCRYPTO_USED(X509_CRL_set_issuer_name); +LCRYPTO_USED(X509_CRL_set_lastUpdate); +LCRYPTO_USED(X509_CRL_set1_lastUpdate); +LCRYPTO_USED(X509_CRL_set_nextUpdate); +LCRYPTO_USED(X509_CRL_set1_nextUpdate); +LCRYPTO_USED(X509_CRL_sort); +LCRYPTO_USED(X509_REVOKED_get0_extensions); +LCRYPTO_USED(X509_REVOKED_get0_revocationDate); +LCRYPTO_USED(X509_REVOKED_get0_serialNumber); +LCRYPTO_USED(X509_REVOKED_set_revocationDate); +LCRYPTO_USED(X509_REVOKED_set_serialNumber); +LCRYPTO_USED(X509_REQ_check_private_key); +LCRYPTO_USED(X509_check_private_key); +LCRYPTO_USED(X509_issuer_and_serial_cmp); +LCRYPTO_USED(X509_issuer_and_serial_hash); +LCRYPTO_USED(X509_issuer_name_cmp); +LCRYPTO_USED(X509_issuer_name_hash); +LCRYPTO_USED(X509_subject_name_cmp); +LCRYPTO_USED(X509_subject_name_hash); +LCRYPTO_USED(X509_issuer_name_hash_old); +LCRYPTO_USED(X509_subject_name_hash_old); +LCRYPTO_USED(X509_cmp); +LCRYPTO_USED(X509_NAME_cmp); +LCRYPTO_USED(X509_NAME_hash); +LCRYPTO_USED(X509_NAME_hash_old); +LCRYPTO_USED(X509_CRL_cmp); +LCRYPTO_USED(X509_CRL_match); +LCRYPTO_USED(X509_NAME_entry_count); +LCRYPTO_USED(X509_NAME_get_text_by_NID); +LCRYPTO_USED(X509_NAME_get_text_by_OBJ); +LCRYPTO_USED(X509_NAME_get_index_by_NID); +LCRYPTO_USED(X509_NAME_get_index_by_OBJ); +LCRYPTO_USED(X509_NAME_get_entry); +LCRYPTO_USED(X509_NAME_delete_entry); +LCRYPTO_USED(X509_NAME_add_entry); +LCRYPTO_USED(X509_NAME_add_entry_by_OBJ); +LCRYPTO_USED(X509_NAME_add_entry_by_NID); +LCRYPTO_USED(X509_NAME_ENTRY_create_by_txt); +LCRYPTO_USED(X509_NAME_ENTRY_create_by_NID); +LCRYPTO_USED(X509_NAME_add_entry_by_txt); +LCRYPTO_USED(X509_NAME_ENTRY_create_by_OBJ); +LCRYPTO_USED(X509_NAME_ENTRY_set_object); +LCRYPTO_USED(X509_NAME_ENTRY_set_data); +LCRYPTO_USED(X509_NAME_ENTRY_get_object); +LCRYPTO_USED(X509_NAME_ENTRY_get_data); +LCRYPTO_USED(X509_NAME_ENTRY_set); +LCRYPTO_USED(X509v3_get_ext_count); +LCRYPTO_USED(X509v3_get_ext_by_NID); +LCRYPTO_USED(X509v3_get_ext_by_OBJ); +LCRYPTO_USED(X509v3_get_ext_by_critical); +LCRYPTO_USED(X509v3_get_ext); +LCRYPTO_USED(X509v3_delete_ext); +LCRYPTO_USED(X509v3_add_ext); +LCRYPTO_USED(X509_get_ext_count); +LCRYPTO_USED(X509_get_ext_by_NID); +LCRYPTO_USED(X509_get_ext_by_OBJ); +LCRYPTO_USED(X509_get_ext_by_critical); +LCRYPTO_USED(X509_get_ext); +LCRYPTO_USED(X509_delete_ext); +LCRYPTO_USED(X509_add_ext); +LCRYPTO_USED(X509_get_ext_d2i); +LCRYPTO_USED(X509_add1_ext_i2d); +LCRYPTO_USED(X509_CRL_get_ext_count); +LCRYPTO_USED(X509_CRL_get_ext_by_NID); +LCRYPTO_USED(X509_CRL_get_ext_by_OBJ); +LCRYPTO_USED(X509_CRL_get_ext_by_critical); +LCRYPTO_USED(X509_CRL_get_ext); +LCRYPTO_USED(X509_CRL_delete_ext); +LCRYPTO_USED(X509_CRL_add_ext); +LCRYPTO_USED(X509_CRL_get_ext_d2i); +LCRYPTO_USED(X509_CRL_add1_ext_i2d); +LCRYPTO_USED(X509_REVOKED_get_ext_count); +LCRYPTO_USED(X509_REVOKED_get_ext_by_NID); +LCRYPTO_USED(X509_REVOKED_get_ext_by_OBJ); +LCRYPTO_USED(X509_REVOKED_get_ext_by_critical); +LCRYPTO_USED(X509_REVOKED_get_ext); +LCRYPTO_USED(X509_REVOKED_delete_ext); +LCRYPTO_USED(X509_REVOKED_add_ext); +LCRYPTO_USED(X509_REVOKED_get_ext_d2i); +LCRYPTO_USED(X509_REVOKED_add1_ext_i2d); +LCRYPTO_USED(X509_EXTENSION_create_by_NID); +LCRYPTO_USED(X509_EXTENSION_create_by_OBJ); +LCRYPTO_USED(X509_EXTENSION_set_object); +LCRYPTO_USED(X509_EXTENSION_set_critical); +LCRYPTO_USED(X509_EXTENSION_set_data); +LCRYPTO_USED(X509_EXTENSION_get_object); +LCRYPTO_USED(X509_EXTENSION_get_data); +LCRYPTO_USED(X509_EXTENSION_get_critical); +LCRYPTO_USED(X509at_get_attr_count); +LCRYPTO_USED(X509at_get_attr_by_NID); +LCRYPTO_USED(X509at_get_attr_by_OBJ); +LCRYPTO_USED(X509at_get_attr); +LCRYPTO_USED(X509at_delete_attr); +LCRYPTO_USED(X509at_add1_attr); +LCRYPTO_USED(X509at_add1_attr_by_OBJ); +LCRYPTO_USED(X509at_add1_attr_by_NID); +LCRYPTO_USED(X509at_add1_attr_by_txt); +LCRYPTO_USED(X509at_get0_data_by_OBJ); +LCRYPTO_USED(X509_ATTRIBUTE_create_by_NID); +LCRYPTO_USED(X509_ATTRIBUTE_create_by_OBJ); +LCRYPTO_USED(X509_ATTRIBUTE_create_by_txt); +LCRYPTO_USED(X509_ATTRIBUTE_set1_object); +LCRYPTO_USED(X509_ATTRIBUTE_set1_data); +LCRYPTO_USED(X509_ATTRIBUTE_get0_data); +LCRYPTO_USED(X509_ATTRIBUTE_count); +LCRYPTO_USED(X509_ATTRIBUTE_get0_object); +LCRYPTO_USED(X509_ATTRIBUTE_get0_type); +LCRYPTO_USED(X509_verify_cert); +LCRYPTO_USED(X509_find_by_issuer_and_serial); +LCRYPTO_USED(X509_find_by_subject); +LCRYPTO_USED(X509_check_trust); +LCRYPTO_USED(X509_TRUST_get_count); +LCRYPTO_USED(X509_TRUST_get0); +LCRYPTO_USED(X509_TRUST_get_by_id); +LCRYPTO_USED(X509_TRUST_add); +LCRYPTO_USED(X509_TRUST_cleanup); +LCRYPTO_USED(X509_TRUST_get_flags); +LCRYPTO_USED(X509_TRUST_get0_name); +LCRYPTO_USED(X509_TRUST_get_trust); +LCRYPTO_USED(X509_up_ref); +LCRYPTO_USED(X509_chain_up_ref); +LCRYPTO_USED(ERR_load_X509_strings); + +#endif /* _LIBCRYPTO_X509_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/x509_vfy.h b/Libraries/libressl/crypto/hidden/openssl/x509_vfy.h new file mode 100644 index 000000000..b5f2ac1a8 --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/x509_vfy.h @@ -0,0 +1,156 @@ +/* $OpenBSD: x509_vfy.h,v 1.6 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_X509_VFY_H +#define _LIBCRYPTO_X509_VFY_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/x509_vfy.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(X509_STORE_set_depth); +LCRYPTO_USED(X509_STORE_CTX_set_depth); +LCRYPTO_USED(X509_OBJECT_new); +LCRYPTO_USED(X509_OBJECT_free); +LCRYPTO_USED(X509_OBJECT_idx_by_subject); +LCRYPTO_USED(X509_OBJECT_retrieve_by_subject); +LCRYPTO_USED(X509_OBJECT_retrieve_match); +LCRYPTO_USED(X509_OBJECT_up_ref_count); +LCRYPTO_USED(X509_OBJECT_get_type); +LCRYPTO_USED(X509_OBJECT_get0_X509); +LCRYPTO_USED(X509_OBJECT_get0_X509_CRL); +LCRYPTO_USED(X509_STORE_new); +LCRYPTO_USED(X509_STORE_free); +LCRYPTO_USED(X509_STORE_up_ref); +LCRYPTO_USED(X509_STORE_get0_objects); +LCRYPTO_USED(X509_STORE_get_ex_data); +LCRYPTO_USED(X509_STORE_set_ex_data); +LCRYPTO_USED(X509_STORE_set_flags); +LCRYPTO_USED(X509_STORE_set_purpose); +LCRYPTO_USED(X509_STORE_set_trust); +LCRYPTO_USED(X509_STORE_set1_param); +LCRYPTO_USED(X509_STORE_get0_param); +LCRYPTO_USED(X509_STORE_get_verify_cb); +LCRYPTO_USED(X509_STORE_set_verify_cb); +LCRYPTO_USED(X509_STORE_get_check_issued); +LCRYPTO_USED(X509_STORE_set_check_issued); +LCRYPTO_USED(X509_STORE_CTX_get_check_issued); +LCRYPTO_USED(X509_STORE_CTX_new); +LCRYPTO_USED(X509_STORE_CTX_get1_issuer); +LCRYPTO_USED(X509_STORE_CTX_free); +LCRYPTO_USED(X509_STORE_CTX_init); +LCRYPTO_USED(X509_STORE_CTX_get0_cert); +LCRYPTO_USED(X509_STORE_CTX_get0_chain); +LCRYPTO_USED(X509_STORE_CTX_get0_store); +LCRYPTO_USED(X509_STORE_CTX_get0_untrusted); +LCRYPTO_USED(X509_STORE_CTX_set0_untrusted); +LCRYPTO_USED(X509_STORE_CTX_get1_certs); +LCRYPTO_USED(X509_STORE_CTX_get1_crls); +LCRYPTO_USED(X509_STORE_CTX_trusted_stack); +LCRYPTO_USED(X509_STORE_CTX_set0_trusted_stack); +LCRYPTO_USED(X509_STORE_CTX_cleanup); +LCRYPTO_USED(X509_STORE_add_lookup); +LCRYPTO_USED(X509_LOOKUP_hash_dir); +LCRYPTO_USED(X509_LOOKUP_file); +LCRYPTO_USED(X509_LOOKUP_mem); +LCRYPTO_USED(X509_STORE_add_cert); +LCRYPTO_USED(X509_STORE_add_crl); +LCRYPTO_USED(X509_STORE_CTX_get_by_subject); +LCRYPTO_USED(X509_STORE_CTX_get_obj_by_subject); +LCRYPTO_USED(X509_LOOKUP_ctrl); +LCRYPTO_USED(X509_load_cert_file); +LCRYPTO_USED(X509_load_crl_file); +LCRYPTO_USED(X509_load_cert_crl_file); +LCRYPTO_USED(X509_LOOKUP_new); +LCRYPTO_USED(X509_LOOKUP_free); +LCRYPTO_USED(X509_LOOKUP_init); +LCRYPTO_USED(X509_LOOKUP_by_subject); +LCRYPTO_USED(X509_LOOKUP_by_issuer_serial); +LCRYPTO_USED(X509_LOOKUP_by_fingerprint); +LCRYPTO_USED(X509_LOOKUP_by_alias); +LCRYPTO_USED(X509_LOOKUP_shutdown); +LCRYPTO_USED(X509_STORE_load_locations); +LCRYPTO_USED(X509_STORE_load_mem); +LCRYPTO_USED(X509_STORE_set_default_paths); +LCRYPTO_USED(X509_STORE_CTX_get_ex_new_index); +LCRYPTO_USED(X509_STORE_CTX_set_ex_data); +LCRYPTO_USED(X509_STORE_CTX_get_ex_data); +LCRYPTO_USED(X509_STORE_CTX_get_error); +LCRYPTO_USED(X509_STORE_CTX_set_error); +LCRYPTO_USED(X509_STORE_CTX_get_error_depth); +LCRYPTO_USED(X509_STORE_CTX_set_error_depth); +LCRYPTO_USED(X509_STORE_CTX_get_current_cert); +LCRYPTO_USED(X509_STORE_CTX_set_current_cert); +LCRYPTO_USED(X509_STORE_CTX_get0_current_issuer); +LCRYPTO_USED(X509_STORE_CTX_get0_current_crl); +LCRYPTO_USED(X509_STORE_CTX_get0_parent_ctx); +LCRYPTO_USED(X509_STORE_CTX_get_chain); +LCRYPTO_USED(X509_STORE_CTX_get1_chain); +LCRYPTO_USED(X509_STORE_CTX_set_cert); +LCRYPTO_USED(X509_STORE_CTX_set_chain); +LCRYPTO_USED(X509_STORE_CTX_set0_crls); +LCRYPTO_USED(X509_STORE_CTX_set_purpose); +LCRYPTO_USED(X509_STORE_CTX_set_trust); +LCRYPTO_USED(X509_STORE_CTX_purpose_inherit); +LCRYPTO_USED(X509_STORE_CTX_set_flags); +LCRYPTO_USED(X509_STORE_CTX_set_time); +LCRYPTO_USED(X509_STORE_CTX_set0_verified_chain); +LCRYPTO_USED(X509_STORE_CTX_get_verify); +LCRYPTO_USED(X509_STORE_CTX_set_verify); +LCRYPTO_USED(X509_STORE_CTX_get_verify_cb); +LCRYPTO_USED(X509_STORE_CTX_set_verify_cb); +LCRYPTO_USED(X509_STORE_set_verify); +LCRYPTO_USED(X509_STORE_get_verify); +LCRYPTO_USED(X509_STORE_CTX_get_num_untrusted); +LCRYPTO_USED(X509_STORE_CTX_get0_param); +LCRYPTO_USED(X509_STORE_CTX_set0_param); +LCRYPTO_USED(X509_STORE_CTX_set_default); +LCRYPTO_USED(X509_VERIFY_PARAM_new); +LCRYPTO_USED(X509_VERIFY_PARAM_free); +LCRYPTO_USED(X509_VERIFY_PARAM_inherit); +LCRYPTO_USED(X509_VERIFY_PARAM_set1); +LCRYPTO_USED(X509_VERIFY_PARAM_set1_name); +LCRYPTO_USED(X509_VERIFY_PARAM_set_flags); +LCRYPTO_USED(X509_VERIFY_PARAM_clear_flags); +LCRYPTO_USED(X509_VERIFY_PARAM_get_flags); +LCRYPTO_USED(X509_VERIFY_PARAM_set_purpose); +LCRYPTO_USED(X509_VERIFY_PARAM_set_trust); +LCRYPTO_USED(X509_VERIFY_PARAM_set_depth); +LCRYPTO_USED(X509_VERIFY_PARAM_set_auth_level); +LCRYPTO_USED(X509_VERIFY_PARAM_get_time); +LCRYPTO_USED(X509_VERIFY_PARAM_set_time); +LCRYPTO_USED(X509_VERIFY_PARAM_add0_policy); +LCRYPTO_USED(X509_VERIFY_PARAM_set1_policies); +LCRYPTO_USED(X509_VERIFY_PARAM_get_depth); +LCRYPTO_USED(X509_VERIFY_PARAM_set1_host); +LCRYPTO_USED(X509_VERIFY_PARAM_add1_host); +LCRYPTO_USED(X509_VERIFY_PARAM_set_hostflags); +LCRYPTO_USED(X509_VERIFY_PARAM_get0_peername); +LCRYPTO_USED(X509_VERIFY_PARAM_set1_email); +LCRYPTO_USED(X509_VERIFY_PARAM_set1_ip); +LCRYPTO_USED(X509_VERIFY_PARAM_set1_ip_asc); +LCRYPTO_USED(X509_VERIFY_PARAM_get0_name); +LCRYPTO_USED(X509_VERIFY_PARAM_get0); +LCRYPTO_USED(X509_VERIFY_PARAM_get_count); +LCRYPTO_USED(X509_VERIFY_PARAM_add0_table); +LCRYPTO_USED(X509_VERIFY_PARAM_lookup); +LCRYPTO_USED(X509_VERIFY_PARAM_table_cleanup); + +#endif /* _LIBCRYPTO_X509_VFY_H */ diff --git a/Libraries/libressl/crypto/hidden/openssl/x509v3.h b/Libraries/libressl/crypto/hidden/openssl/x509v3.h new file mode 100644 index 000000000..a85c5c26a --- /dev/null +++ b/Libraries/libressl/crypto/hidden/openssl/x509v3.h @@ -0,0 +1,265 @@ +/* $OpenBSD: x509v3.h,v 1.5 2023/07/05 21:14:54 bcook Exp $ */ +/* + * Copyright (c) 2022 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBCRYPTO_X509V3_H +#define _LIBCRYPTO_X509V3_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/x509v3.h" +#endif +#include "crypto_namespace.h" + +LCRYPTO_USED(BASIC_CONSTRAINTS_new); +LCRYPTO_USED(BASIC_CONSTRAINTS_free); +LCRYPTO_USED(d2i_BASIC_CONSTRAINTS); +LCRYPTO_USED(i2d_BASIC_CONSTRAINTS); +LCRYPTO_USED(AUTHORITY_KEYID_new); +LCRYPTO_USED(AUTHORITY_KEYID_free); +LCRYPTO_USED(d2i_AUTHORITY_KEYID); +LCRYPTO_USED(i2d_AUTHORITY_KEYID); +LCRYPTO_USED(PKEY_USAGE_PERIOD_new); +LCRYPTO_USED(PKEY_USAGE_PERIOD_free); +LCRYPTO_USED(d2i_PKEY_USAGE_PERIOD); +LCRYPTO_USED(i2d_PKEY_USAGE_PERIOD); +LCRYPTO_USED(GENERAL_NAME_new); +LCRYPTO_USED(GENERAL_NAME_free); +LCRYPTO_USED(d2i_GENERAL_NAME); +LCRYPTO_USED(i2d_GENERAL_NAME); +LCRYPTO_USED(GENERAL_NAME_dup); +LCRYPTO_USED(GENERAL_NAME_cmp); +LCRYPTO_USED(v2i_ASN1_BIT_STRING); +LCRYPTO_USED(i2v_ASN1_BIT_STRING); +LCRYPTO_USED(i2v_GENERAL_NAME); +LCRYPTO_USED(GENERAL_NAME_print); +LCRYPTO_USED(GENERAL_NAMES_new); +LCRYPTO_USED(GENERAL_NAMES_free); +LCRYPTO_USED(d2i_GENERAL_NAMES); +LCRYPTO_USED(i2d_GENERAL_NAMES); +LCRYPTO_USED(i2v_GENERAL_NAMES); +LCRYPTO_USED(v2i_GENERAL_NAMES); +LCRYPTO_USED(OTHERNAME_new); +LCRYPTO_USED(OTHERNAME_free); +LCRYPTO_USED(d2i_OTHERNAME); +LCRYPTO_USED(i2d_OTHERNAME); +LCRYPTO_USED(EDIPARTYNAME_new); +LCRYPTO_USED(EDIPARTYNAME_free); +LCRYPTO_USED(d2i_EDIPARTYNAME); +LCRYPTO_USED(i2d_EDIPARTYNAME); +LCRYPTO_USED(OTHERNAME_cmp); +LCRYPTO_USED(GENERAL_NAME_set0_value); +LCRYPTO_USED(GENERAL_NAME_get0_value); +LCRYPTO_USED(GENERAL_NAME_set0_othername); +LCRYPTO_USED(GENERAL_NAME_get0_otherName); +LCRYPTO_USED(i2s_ASN1_OCTET_STRING); +LCRYPTO_USED(s2i_ASN1_OCTET_STRING); +LCRYPTO_USED(EXTENDED_KEY_USAGE_new); +LCRYPTO_USED(EXTENDED_KEY_USAGE_free); +LCRYPTO_USED(d2i_EXTENDED_KEY_USAGE); +LCRYPTO_USED(i2d_EXTENDED_KEY_USAGE); +LCRYPTO_USED(i2a_ACCESS_DESCRIPTION); +LCRYPTO_USED(CERTIFICATEPOLICIES_new); +LCRYPTO_USED(CERTIFICATEPOLICIES_free); +LCRYPTO_USED(d2i_CERTIFICATEPOLICIES); +LCRYPTO_USED(i2d_CERTIFICATEPOLICIES); +LCRYPTO_USED(POLICYINFO_new); +LCRYPTO_USED(POLICYINFO_free); +LCRYPTO_USED(d2i_POLICYINFO); +LCRYPTO_USED(i2d_POLICYINFO); +LCRYPTO_USED(POLICYQUALINFO_new); +LCRYPTO_USED(POLICYQUALINFO_free); +LCRYPTO_USED(d2i_POLICYQUALINFO); +LCRYPTO_USED(i2d_POLICYQUALINFO); +LCRYPTO_USED(USERNOTICE_new); +LCRYPTO_USED(USERNOTICE_free); +LCRYPTO_USED(d2i_USERNOTICE); +LCRYPTO_USED(i2d_USERNOTICE); +LCRYPTO_USED(NOTICEREF_new); +LCRYPTO_USED(NOTICEREF_free); +LCRYPTO_USED(d2i_NOTICEREF); +LCRYPTO_USED(i2d_NOTICEREF); +LCRYPTO_USED(CRL_DIST_POINTS_new); +LCRYPTO_USED(CRL_DIST_POINTS_free); +LCRYPTO_USED(d2i_CRL_DIST_POINTS); +LCRYPTO_USED(i2d_CRL_DIST_POINTS); +LCRYPTO_USED(DIST_POINT_new); +LCRYPTO_USED(DIST_POINT_free); +LCRYPTO_USED(d2i_DIST_POINT); +LCRYPTO_USED(i2d_DIST_POINT); +LCRYPTO_USED(DIST_POINT_NAME_new); +LCRYPTO_USED(DIST_POINT_NAME_free); +LCRYPTO_USED(d2i_DIST_POINT_NAME); +LCRYPTO_USED(i2d_DIST_POINT_NAME); +LCRYPTO_USED(ISSUING_DIST_POINT_new); +LCRYPTO_USED(ISSUING_DIST_POINT_free); +LCRYPTO_USED(d2i_ISSUING_DIST_POINT); +LCRYPTO_USED(i2d_ISSUING_DIST_POINT); +LCRYPTO_USED(DIST_POINT_set_dpname); +LCRYPTO_USED(NAME_CONSTRAINTS_check); +LCRYPTO_USED(ACCESS_DESCRIPTION_new); +LCRYPTO_USED(ACCESS_DESCRIPTION_free); +LCRYPTO_USED(d2i_ACCESS_DESCRIPTION); +LCRYPTO_USED(i2d_ACCESS_DESCRIPTION); +LCRYPTO_USED(AUTHORITY_INFO_ACCESS_new); +LCRYPTO_USED(AUTHORITY_INFO_ACCESS_free); +LCRYPTO_USED(d2i_AUTHORITY_INFO_ACCESS); +LCRYPTO_USED(i2d_AUTHORITY_INFO_ACCESS); +LCRYPTO_USED(POLICY_MAPPING_new); +LCRYPTO_USED(POLICY_MAPPING_free); +LCRYPTO_USED(GENERAL_SUBTREE_new); +LCRYPTO_USED(GENERAL_SUBTREE_free); +LCRYPTO_USED(NAME_CONSTRAINTS_new); +LCRYPTO_USED(NAME_CONSTRAINTS_free); +LCRYPTO_USED(POLICY_CONSTRAINTS_new); +LCRYPTO_USED(POLICY_CONSTRAINTS_free); +LCRYPTO_USED(a2i_GENERAL_NAME); +LCRYPTO_USED(v2i_GENERAL_NAME); +LCRYPTO_USED(v2i_GENERAL_NAME_ex); +LCRYPTO_USED(X509V3_conf_free); +LCRYPTO_USED(X509V3_EXT_nconf_nid); +LCRYPTO_USED(X509V3_EXT_nconf); +LCRYPTO_USED(X509V3_EXT_add_nconf_sk); +LCRYPTO_USED(X509V3_EXT_add_nconf); +LCRYPTO_USED(X509V3_EXT_REQ_add_nconf); +LCRYPTO_USED(X509V3_EXT_CRL_add_nconf); +LCRYPTO_USED(X509V3_EXT_conf_nid); +LCRYPTO_USED(X509V3_EXT_conf); +LCRYPTO_USED(X509V3_EXT_add_conf); +LCRYPTO_USED(X509V3_EXT_REQ_add_conf); +LCRYPTO_USED(X509V3_EXT_CRL_add_conf); +LCRYPTO_USED(X509V3_add_value_bool_nf); +LCRYPTO_USED(X509V3_get_value_bool); +LCRYPTO_USED(X509V3_get_value_int); +LCRYPTO_USED(X509V3_set_nconf); +LCRYPTO_USED(X509V3_set_conf_lhash); +LCRYPTO_USED(X509V3_get_string); +LCRYPTO_USED(X509V3_get_section); +LCRYPTO_USED(X509V3_string_free); +LCRYPTO_USED(X509V3_section_free); +LCRYPTO_USED(X509V3_set_ctx); +LCRYPTO_USED(X509V3_add_value); +LCRYPTO_USED(X509V3_add_value_uchar); +LCRYPTO_USED(X509V3_add_value_bool); +LCRYPTO_USED(X509V3_add_value_int); +LCRYPTO_USED(i2s_ASN1_INTEGER); +LCRYPTO_USED(s2i_ASN1_INTEGER); +LCRYPTO_USED(i2s_ASN1_ENUMERATED); +LCRYPTO_USED(i2s_ASN1_ENUMERATED_TABLE); +LCRYPTO_USED(X509V3_EXT_add); +LCRYPTO_USED(X509V3_EXT_add_list); +LCRYPTO_USED(X509V3_EXT_add_alias); +LCRYPTO_USED(X509V3_EXT_cleanup); +LCRYPTO_USED(X509V3_EXT_get); +LCRYPTO_USED(X509V3_EXT_get_nid); +LCRYPTO_USED(X509V3_add_standard_extensions); +LCRYPTO_USED(X509V3_parse_list); +LCRYPTO_USED(X509V3_EXT_d2i); +LCRYPTO_USED(X509V3_get_d2i); +LCRYPTO_USED(X509V3_EXT_i2d); +LCRYPTO_USED(X509V3_add1_i2d); +LCRYPTO_USED(hex_to_string); +LCRYPTO_USED(string_to_hex); +LCRYPTO_USED(X509V3_EXT_val_prn); +LCRYPTO_USED(X509V3_EXT_print); +LCRYPTO_USED(X509V3_EXT_print_fp); +LCRYPTO_USED(X509V3_extensions_print); +LCRYPTO_USED(X509_check_ca); +LCRYPTO_USED(X509_check_purpose); +LCRYPTO_USED(X509_supported_extension); +LCRYPTO_USED(X509_PURPOSE_set); +LCRYPTO_USED(X509_check_issued); +LCRYPTO_USED(X509_check_akid); +LCRYPTO_USED(X509_PURPOSE_get_count); +LCRYPTO_USED(X509_PURPOSE_get0); +LCRYPTO_USED(X509_PURPOSE_get_by_sname); +LCRYPTO_USED(X509_PURPOSE_get_by_id); +LCRYPTO_USED(X509_PURPOSE_add); +LCRYPTO_USED(X509_PURPOSE_get0_name); +LCRYPTO_USED(X509_PURPOSE_get0_sname); +LCRYPTO_USED(X509_PURPOSE_get_trust); +LCRYPTO_USED(X509_PURPOSE_cleanup); +LCRYPTO_USED(X509_PURPOSE_get_id); +LCRYPTO_USED(X509_get_extension_flags); +LCRYPTO_USED(X509_get_key_usage); +LCRYPTO_USED(X509_get_extended_key_usage); +LCRYPTO_USED(X509_get1_email); +LCRYPTO_USED(X509_REQ_get1_email); +LCRYPTO_USED(X509_email_free); +LCRYPTO_USED(X509_get1_ocsp); +LCRYPTO_USED(X509_check_host); +LCRYPTO_USED(X509_check_email); +LCRYPTO_USED(X509_check_ip); +LCRYPTO_USED(X509_check_ip_asc); +LCRYPTO_USED(a2i_IPADDRESS); +LCRYPTO_USED(a2i_IPADDRESS_NC); +LCRYPTO_USED(a2i_ipadd); +LCRYPTO_USED(X509V3_NAME_from_section); +LCRYPTO_USED(ASRange_new); +LCRYPTO_USED(ASRange_free); +LCRYPTO_USED(d2i_ASRange); +LCRYPTO_USED(i2d_ASRange); +LCRYPTO_USED(ASIdOrRange_new); +LCRYPTO_USED(ASIdOrRange_free); +LCRYPTO_USED(d2i_ASIdOrRange); +LCRYPTO_USED(i2d_ASIdOrRange); +LCRYPTO_USED(ASIdentifierChoice_new); +LCRYPTO_USED(ASIdentifierChoice_free); +LCRYPTO_USED(d2i_ASIdentifierChoice); +LCRYPTO_USED(i2d_ASIdentifierChoice); +LCRYPTO_USED(ASIdentifiers_new); +LCRYPTO_USED(ASIdentifiers_free); +LCRYPTO_USED(d2i_ASIdentifiers); +LCRYPTO_USED(i2d_ASIdentifiers); +LCRYPTO_USED(IPAddressRange_new); +LCRYPTO_USED(IPAddressRange_free); +LCRYPTO_USED(d2i_IPAddressRange); +LCRYPTO_USED(i2d_IPAddressRange); +LCRYPTO_USED(IPAddressOrRange_new); +LCRYPTO_USED(IPAddressOrRange_free); +LCRYPTO_USED(d2i_IPAddressOrRange); +LCRYPTO_USED(i2d_IPAddressOrRange); +LCRYPTO_USED(IPAddressChoice_new); +LCRYPTO_USED(IPAddressChoice_free); +LCRYPTO_USED(d2i_IPAddressChoice); +LCRYPTO_USED(i2d_IPAddressChoice); +LCRYPTO_USED(IPAddressFamily_new); +LCRYPTO_USED(IPAddressFamily_free); +LCRYPTO_USED(d2i_IPAddressFamily); +LCRYPTO_USED(i2d_IPAddressFamily); +LCRYPTO_USED(X509v3_asid_add_inherit); +LCRYPTO_USED(X509v3_asid_add_id_or_range); +LCRYPTO_USED(X509v3_addr_add_inherit); +LCRYPTO_USED(X509v3_addr_add_prefix); +LCRYPTO_USED(X509v3_addr_add_range); +LCRYPTO_USED(X509v3_addr_get_afi); +LCRYPTO_USED(X509v3_addr_get_range); +LCRYPTO_USED(X509v3_asid_is_canonical); +LCRYPTO_USED(X509v3_addr_is_canonical); +LCRYPTO_USED(X509v3_asid_canonize); +LCRYPTO_USED(X509v3_addr_canonize); +LCRYPTO_USED(X509v3_asid_inherits); +LCRYPTO_USED(X509v3_addr_inherits); +LCRYPTO_USED(X509v3_asid_subset); +LCRYPTO_USED(X509v3_addr_subset); +LCRYPTO_USED(X509v3_asid_validate_path); +LCRYPTO_USED(X509v3_addr_validate_path); +LCRYPTO_USED(X509v3_asid_validate_resource_set); +LCRYPTO_USED(X509v3_addr_validate_resource_set); +LCRYPTO_USED(ERR_load_X509V3_strings); + +#endif /* _LIBCRYPTO_X509V3_H */ diff --git a/Libraries/libressl/crypto/hkdf/hkdf.c b/Libraries/libressl/crypto/hkdf/hkdf.c new file mode 100644 index 000000000..4f9c9e566 --- /dev/null +++ b/Libraries/libressl/crypto/hkdf/hkdf.c @@ -0,0 +1,123 @@ +/* $OpenBSD: hkdf.c,v 1.10 2023/07/07 13:54:46 beck Exp $ */ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include + +#include "evp_local.h" +#include "hmac_local.h" + +/* https://tools.ietf.org/html/rfc5869#section-2 */ +int +HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len, const uint8_t *info, size_t info_len) +{ + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prk_len; + + if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt, + salt_len)) + return 0; + if (!HKDF_expand(out_key, out_len, digest, prk, prk_len, info, + info_len)) + return 0; + + return 1; +} +LCRYPTO_ALIAS(HKDF); + +/* https://tools.ietf.org/html/rfc5869#section-2.2 */ +int +HKDF_extract(uint8_t *out_key, size_t *out_len, + const EVP_MD *digest, const uint8_t *secret, size_t secret_len, + const uint8_t *salt, size_t salt_len) +{ + unsigned int len; + + /* + * If salt is not given, HashLength zeros are used. However, HMAC does + * that internally already so we can ignore it. + */ + if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) == + NULL) { + CRYPTOerror(ERR_R_CRYPTO_LIB); + return 0; + } + *out_len = len; + return 1; +} +LCRYPTO_ALIAS(HKDF_extract); + +/* https://tools.ietf.org/html/rfc5869#section-2.3 */ +int +HKDF_expand(uint8_t *out_key, size_t out_len, + const EVP_MD *digest, const uint8_t *prk, size_t prk_len, + const uint8_t *info, size_t info_len) +{ + const size_t digest_len = EVP_MD_size(digest); + uint8_t previous[EVP_MAX_MD_SIZE]; + size_t n, done = 0; + unsigned int i; + int ret = 0; + HMAC_CTX hmac; + + /* Expand key material to desired length. */ + n = (out_len + digest_len - 1) / digest_len; + if (out_len + digest_len < out_len || n > 255) { + CRYPTOerror(EVP_R_TOO_LARGE); + return 0; + } + + HMAC_CTX_init(&hmac); + if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) + goto out; + + for (i = 0; i < n; i++) { + uint8_t ctr = i + 1; + size_t todo; + + if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) || + !HMAC_Update(&hmac, previous, digest_len))) + goto out; + + if (!HMAC_Update(&hmac, info, info_len) || + !HMAC_Update(&hmac, &ctr, 1) || + !HMAC_Final(&hmac, previous, NULL)) + goto out; + + todo = digest_len; + if (todo > out_len - done) + todo = out_len - done; + + memcpy(out_key + done, previous, todo); + done += todo; + } + + ret = 1; + + out: + HMAC_CTX_cleanup(&hmac); + explicit_bzero(previous, sizeof(previous)); + if (ret != 1) + CRYPTOerror(ERR_R_CRYPTO_LIB); + return ret; +} +LCRYPTO_ALIAS(HKDF_expand); diff --git a/Libraries/libressl/crypto/hmac/hm_ameth.c b/Libraries/libressl/crypto/hmac/hm_ameth.c new file mode 100644 index 000000000..7e6ad6d69 --- /dev/null +++ b/Libraries/libressl/crypto/hmac/hm_ameth.c @@ -0,0 +1,171 @@ +/* $OpenBSD: hm_ameth.c,v 1.19 2022/11/26 16:08:53 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include + +#include "asn1_local.h" +#include "bytestring.h" +#include "evp_local.h" +#include "hmac_local.h" + +static int +hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + /* The ameth pub_cmp must return 1 on match, 0 on mismatch. */ + return ASN1_OCTET_STRING_cmp(a->pkey.ptr, b->pkey.ptr) == 0; +} + +static int +hmac_size(const EVP_PKEY *pkey) +{ + return EVP_MAX_MD_SIZE; +} + +static void +hmac_key_free(EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *os; + + if ((os = pkey->pkey.ptr) == NULL) + return; + + if (os->data != NULL) + explicit_bzero(os->data, os->length); + + ASN1_OCTET_STRING_free(os); +} + +static int +hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 1; + default: + return -2; + } +} + +static int +hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, size_t len) +{ + ASN1_OCTET_STRING *os = NULL; + + if (pkey->pkey.ptr != NULL) + goto err; + + if (len > INT_MAX) + goto err; + + if ((os = ASN1_OCTET_STRING_new()) == NULL) + goto err; + + if (!ASN1_OCTET_STRING_set(os, priv, len)) + goto err; + + pkey->pkey.ptr = os; + + return 1; + + err: + ASN1_OCTET_STRING_free(os); + + return 0; +} + +static int +hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, size_t *len) +{ + ASN1_OCTET_STRING *os; + CBS cbs; + + if ((os = pkey->pkey.ptr) == NULL) + return 0; + + if (priv == NULL) { + *len = os->length; + return 1; + } + + CBS_init(&cbs, os->data, os->length); + return CBS_write_bytes(&cbs, priv, *len, len); +} + +const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { + .pkey_id = EVP_PKEY_HMAC, + .pkey_base_id = EVP_PKEY_HMAC, + + .pem_str = "HMAC", + .info = "OpenSSL HMAC method", + + .pub_cmp = hmac_pkey_public_cmp, + + .pkey_size = hmac_size, + + .pkey_free = hmac_key_free, + .pkey_ctrl = hmac_pkey_ctrl, + + .set_priv_key = hmac_set_priv_key, + .get_priv_key = hmac_get_priv_key, +}; diff --git a/Libraries/libressl/crypto/hmac/hm_pmeth.c b/Libraries/libressl/crypto/hmac/hm_pmeth.c new file mode 100644 index 000000000..bb043d1a2 --- /dev/null +++ b/Libraries/libressl/crypto/hmac/hm_pmeth.c @@ -0,0 +1,254 @@ +/* $OpenBSD: hm_pmeth.c,v 1.15 2022/11/26 16:08:53 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "evp_local.h" +#include "hmac_local.h" + +/* HMAC pkey context structure */ + +typedef struct { + const EVP_MD *md; /* MD for HMAC use */ + ASN1_OCTET_STRING ktmp; /* Temp storage for key */ + HMAC_CTX ctx; +} HMAC_PKEY_CTX; + +static int +pkey_hmac_init(EVP_PKEY_CTX *ctx) +{ + HMAC_PKEY_CTX *hctx; + + if ((hctx = calloc(1, sizeof(HMAC_PKEY_CTX))) == NULL) + return 0; + + hctx->ktmp.type = V_ASN1_OCTET_STRING; + HMAC_CTX_init(&hctx->ctx); + + ctx->data = hctx; + ctx->keygen_info_count = 0; + + return 1; +} + +static int +pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + HMAC_PKEY_CTX *sctx, *dctx; + + if (!pkey_hmac_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->md = sctx->md; + HMAC_CTX_init(&dctx->ctx); + if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx)) + return 0; + if (sctx->ktmp.data) { + if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data, + sctx->ktmp.length)) + return 0; + } + return 1; +} + +static void +pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) +{ + HMAC_PKEY_CTX *hctx; + + if ((hctx = ctx->data) == NULL) + return; + + HMAC_CTX_cleanup(&hctx->ctx); + freezero(hctx->ktmp.data, hctx->ktmp.length); + free(hctx); +} + +static int +pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *hkey = NULL; + HMAC_PKEY_CTX *hctx = ctx->data; + + if (!hctx->ktmp.data) + return 0; + hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); + if (!hkey) + return 0; + EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); + + return 1; +} + +static int +int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + HMAC_PKEY_CTX *hctx = ctx->pctx->data; + + if (!HMAC_Update(&hctx->ctx, data, count)) + return 0; + return 1; +} + +static int +hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + + HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT); + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int +hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + unsigned int hlen; + HMAC_PKEY_CTX *hctx = ctx->data; + int l = EVP_MD_CTX_size(mctx); + + if (l < 0) + return 0; + *siglen = l; + if (!sig) + return 1; + + if (!HMAC_Final(&hctx->ctx, sig, &hlen)) + return 0; + *siglen = (size_t)hlen; + return 1; +} + +static int +pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + ASN1_OCTET_STRING *key; + + switch (type) { + case EVP_PKEY_CTRL_SET_MAC_KEY: + if ((!p2 && p1 > 0) || (p1 < -1)) + return 0; + if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) + return 0; + break; + + case EVP_PKEY_CTRL_MD: + hctx->md = p2; + break; + + case EVP_PKEY_CTRL_DIGESTINIT: + key = ctx->pkey->pkey.ptr; + if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, + ctx->engine)) + return 0; + break; + + default: + return -2; + } + return 1; +} + +static int +pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + if (!value) + return 0; + if (!strcmp(type, "key")) { + void *p = (void *)value; + return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p); + } + if (!strcmp(type, "hexkey")) { + unsigned char *key; + int r; + long keylen; + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + free(key); + return r; + } + return -2; +} + +const EVP_PKEY_METHOD hmac_pkey_meth = { + .pkey_id = EVP_PKEY_HMAC, + + .init = pkey_hmac_init, + .copy = pkey_hmac_copy, + .cleanup = pkey_hmac_cleanup, + + .keygen = pkey_hmac_keygen, + + .signctx_init = hmac_signctx_init, + .signctx = hmac_signctx, + + .ctrl = pkey_hmac_ctrl, + .ctrl_str = pkey_hmac_ctrl_str +}; diff --git a/Libraries/libressl/crypto/hmac/hmac.c b/Libraries/libressl/crypto/hmac/hmac.c new file mode 100644 index 000000000..ea3a1b4a4 --- /dev/null +++ b/Libraries/libressl/crypto/hmac/hmac.c @@ -0,0 +1,293 @@ +/* $OpenBSD: hmac.c,v 1.31 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include + +#include "evp_local.h" +#include "hmac_local.h" + +int +HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, + ENGINE *impl) +{ + int i, j, reset = 0; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + /* If we are changing MD then we must have a key */ + if (md != NULL && md != ctx->md && (key == NULL || len < 0)) + return 0; + + if (md != NULL) { + reset = 1; + ctx->md = md; + } else if (ctx->md != NULL) + md = ctx->md; + else + return 0; + + if (key != NULL) { + reset = 1; + j = EVP_MD_block_size(md); + if ((size_t)j > sizeof(ctx->key)) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + goto err; + } + if (j < len) { + if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx, key, len)) + goto err; + if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, + &ctx->key_length)) + goto err; + } else { + if (len < 0 || (size_t)len > sizeof(ctx->key)) { + EVPerror(EVP_R_BAD_KEY_LENGTH); + goto err; + } + memcpy(ctx->key, key, len); + ctx->key_length = len; + } + if (ctx->key_length != HMAC_MAX_MD_CBLOCK) + memset(&ctx->key[ctx->key_length], 0, + HMAC_MAX_MD_CBLOCK - ctx->key_length); + } + + if (reset) { + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x36 ^ ctx->key[i]; + if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) + goto err; + + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x5c ^ ctx->key[i]; + if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) + goto err; + } + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) + goto err; + return 1; +err: + return 0; +} +LCRYPTO_ALIAS(HMAC_Init_ex); + +int +HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) +{ + if (key && md) + HMAC_CTX_init(ctx); + return HMAC_Init_ex(ctx, key, len, md, NULL); +} + +int +HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) +{ + if (ctx->md == NULL) + return 0; + + return EVP_DigestUpdate(&ctx->md_ctx, data, len); +} +LCRYPTO_ALIAS(HMAC_Update); + +int +HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) +{ + unsigned int i; + unsigned char buf[EVP_MAX_MD_SIZE]; + + if (ctx->md == NULL) + goto err; + + if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx, buf, i)) + goto err; + if (!EVP_DigestFinal_ex(&ctx->md_ctx, md, len)) + goto err; + return 1; +err: + return 0; +} +LCRYPTO_ALIAS(HMAC_Final); + +HMAC_CTX * +HMAC_CTX_new(void) +{ + HMAC_CTX *ctx; + + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) + return NULL; + + HMAC_CTX_init(ctx); + + return ctx; +} +LCRYPTO_ALIAS(HMAC_CTX_new); + +void +HMAC_CTX_free(HMAC_CTX *ctx) +{ + if (ctx == NULL) + return; + + HMAC_CTX_cleanup(ctx); + + free(ctx); +} +LCRYPTO_ALIAS(HMAC_CTX_free); + +int +HMAC_CTX_reset(HMAC_CTX *ctx) +{ + HMAC_CTX_cleanup(ctx); + HMAC_CTX_init(ctx); + return 1; +} + +void +HMAC_CTX_init(HMAC_CTX *ctx) +{ + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); + ctx->md = NULL; +} + +int +HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) +{ + if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx)) + goto err; + memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK); + dctx->key_length = sctx->key_length; + dctx->md = sctx->md; + return 1; +err: + return 0; +} +LCRYPTO_ALIAS(HMAC_CTX_copy); + +void +HMAC_CTX_cleanup(HMAC_CTX *ctx) +{ + EVP_MD_CTX_cleanup(&ctx->i_ctx); + EVP_MD_CTX_cleanup(&ctx->o_ctx); + EVP_MD_CTX_cleanup(&ctx->md_ctx); + explicit_bzero(ctx, sizeof(*ctx)); +} + +void +HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) +{ + EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); +} +LCRYPTO_ALIAS(HMAC_CTX_set_flags); + +const EVP_MD * +HMAC_CTX_get_md(const HMAC_CTX *ctx) +{ + return ctx->md; +} +LCRYPTO_ALIAS(HMAC_CTX_get_md); + +unsigned char * +HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, + size_t n, unsigned char *md, unsigned int *md_len) +{ + HMAC_CTX c; + static unsigned char m[EVP_MAX_MD_SIZE]; + const unsigned char dummy_key[1] = { 0 }; + + if (md == NULL) + md = m; + if (key == NULL) { + key = dummy_key; + key_len = 0; + } + HMAC_CTX_init(&c); + if (!HMAC_Init_ex(&c, key, key_len, evp_md, NULL)) + goto err; + if (!HMAC_Update(&c, d, n)) + goto err; + if (!HMAC_Final(&c, md, md_len)) + goto err; + HMAC_CTX_cleanup(&c); + return md; +err: + HMAC_CTX_cleanup(&c); + return NULL; +} +LCRYPTO_ALIAS(HMAC); diff --git a/Libraries/libressl/crypto/hmac/hmac_local.h b/Libraries/libressl/crypto/hmac/hmac_local.h new file mode 100644 index 000000000..e06cd6a6c --- /dev/null +++ b/Libraries/libressl/crypto/hmac/hmac_local.h @@ -0,0 +1,83 @@ +/* $OpenBSD: hmac_local.h,v 1.4 2022/11/26 16:08:53 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_LOCAL_H +#define HEADER_HMAC_LOCAL_H + +#include + +#include + +#include "evp_local.h" + +__BEGIN_HIDDEN_DECLS + +struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} /* HMAC_CTX */; + +void HMAC_CTX_init(HMAC_CTX *ctx); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_HMAC_LOCAL_H */ diff --git a/Libraries/libressl/crypto/idea/i_cbc.c b/Libraries/libressl/crypto/idea/i_cbc.c new file mode 100644 index 000000000..d75134063 --- /dev/null +++ b/Libraries/libressl/crypto/idea/i_cbc.c @@ -0,0 +1,176 @@ +/* $OpenBSD: i_cbc.c,v 1.6 2023/07/08 10:44:00 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_local.h" + +void +idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int encrypt) +{ + unsigned long tin0, tin1; + unsigned long tout0, tout1, xor0, xor1; + long l = length; + unsigned long tin[2]; + + if (encrypt) { + n2l(iv, tout0); + n2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) + { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0]; + l2n(tout0, out); + tout1 = tin[1]; + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0]; + l2n(tout0, out); + tout1 = tin[1]; + l2n(tout1, out); + } + l2n(tout0, iv); + l2n(tout1, iv); + } else { + n2l(iv, xor0); + n2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) + { + n2l(in, tin0); + tin[0] = tin0; + n2l(in, tin1); + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + tin[0] = tin0; + n2l(in, tin1); + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, iv); + l2n(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +LCRYPTO_ALIAS(idea_cbc_encrypt); + +void +idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key) +{ + IDEA_INT *p; + unsigned long x1, x2, x3, x4, t0, t1, ul; + + x2 = d[0]; + x1 = (x2 >> 16); + x4 = d[1]; + x3 = (x4 >> 16); + + p = &(key->data[0][0]); + + E_IDEA(0); + E_IDEA(1); + E_IDEA(2); + E_IDEA(3); + E_IDEA(4); + E_IDEA(5); + E_IDEA(6); + E_IDEA(7); + + x1 &= 0xffff; + idea_mul(x1, x1, *p, ul); + p++; + + t0 = x3 + *(p++); + t1 = x2 + *(p++); + + x4 &= 0xffff; + idea_mul(x4, x4, *p, ul); + + d[0] = (t0 & 0xffff)|((x1 & 0xffff) << 16); + d[1] = (x4 & 0xffff)|((t1 & 0xffff) << 16); +} +LCRYPTO_ALIAS(idea_encrypt); diff --git a/Libraries/libressl/crypto/idea/i_cfb64.c b/Libraries/libressl/crypto/idea/i_cfb64.c new file mode 100644 index 000000000..a1a543f61 --- /dev/null +++ b/Libraries/libressl/crypto/idea/i_cfb64.c @@ -0,0 +1,124 @@ +/* $OpenBSD: i_cfb64.c,v 1.6 2023/07/08 10:44:00 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_local.h" + +/* The input and output encrypted as though 64bit cfb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ + +void +idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *schedule, + unsigned char *ivec, int *num, int encrypt) +{ + unsigned long v0, v1, t; + int n = *num; + long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + idea_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + idea_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} +LCRYPTO_ALIAS(idea_cfb64_encrypt); diff --git a/Libraries/libressl/crypto/idea/i_ecb.c b/Libraries/libressl/crypto/idea/i_ecb.c new file mode 100644 index 000000000..9f7db232b --- /dev/null +++ b/Libraries/libressl/crypto/idea/i_ecb.c @@ -0,0 +1,80 @@ +/* $OpenBSD: i_ecb.c,v 1.7 2023/07/28 10:35:14 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_local.h" +#include + +void +idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks) +{ + unsigned long l0, l1, d[2]; + + n2l(in, l0); + d[0] = l0; + n2l(in, l1); + d[1] = l1; + idea_encrypt(d, ks); + l0 = d[0]; + l2n(l0, out); + l1 = d[1]; + l2n(l1, out); + l0 = l1 = d[0] = d[1] = 0; +} +LCRYPTO_ALIAS(idea_ecb_encrypt); diff --git a/Libraries/libressl/crypto/idea/i_ofb64.c b/Libraries/libressl/crypto/idea/i_ofb64.c new file mode 100644 index 000000000..5af394ef7 --- /dev/null +++ b/Libraries/libressl/crypto/idea/i_ofb64.c @@ -0,0 +1,111 @@ +/* $OpenBSD: i_ofb64.c,v 1.6 2023/07/08 10:44:00 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_local.h" + +/* The input and output encrypted as though 64bit ofb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ +void +idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *schedule, + unsigned char *ivec, int *num) +{ + unsigned long v0, v1, t; + int n = *num; + long l = length; + unsigned char d[8]; + char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + idea_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} +LCRYPTO_ALIAS(idea_ofb64_encrypt); diff --git a/Libraries/libressl/crypto/idea/i_skey.c b/Libraries/libressl/crypto/idea/i_skey.c new file mode 100644 index 000000000..ad349bba5 --- /dev/null +++ b/Libraries/libressl/crypto/idea/i_skey.c @@ -0,0 +1,169 @@ +/* $OpenBSD: i_skey.c,v 1.7 2023/07/08 10:44:00 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "idea_local.h" + +static IDEA_INT inverse(unsigned int xin); +void +idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) +{ + int i; + IDEA_INT *kt, *kf, r0, r1, r2; + + kt = &(ks->data[0][0]); + n2s(key, kt[0]); + n2s(key, kt[1]); + n2s(key, kt[2]); + n2s(key, kt[3]); + n2s(key, kt[4]); + n2s(key, kt[5]); + n2s(key, kt[6]); + n2s(key, kt[7]); + + kf = kt; + kt += 8; + for (i = 0; i < 6; i++) + { + r2 = kf[1]; + r1 = kf[2]; + *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[3]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[4]; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[5]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[6]; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[7]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[0]; + if (i >= 5) + break; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; + kf += 8; + } +} +LCRYPTO_ALIAS(idea_set_encrypt_key); + +void +idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) +{ + int r; + IDEA_INT *fp, *tp, t; + + tp = &(dk->data[0][0]); + fp = &(ek->data[8][0]); + for (r = 0; r < 9; r++) + { + *(tp++) = inverse(fp[0]); + *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); + *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); + *(tp++) = inverse(fp[3]); + if (r == 8) + break; + fp -= 6; + *(tp++) = fp[4]; + *(tp++) = fp[5]; + } + + tp = &(dk->data[0][0]); + t = tp[1]; + tp[1] = tp[2]; + tp[2] = t; + + t = tp[49]; + tp[49] = tp[50]; + tp[50] = t; +} +LCRYPTO_ALIAS(idea_set_decrypt_key); + +/* taken directly from the 'paper' I'll have a look at it later */ +static IDEA_INT +inverse(unsigned int xin) +{ + long n1, n2, q, r, b1, b2, t; + + if (xin == 0) + b2 = 0; + else { + n1 = 0x10001; + n2 = xin; + b2 = 1; + b1 = 0; + + do { + r = (n1 % n2); + q = (n1 - r)/n2; + if (r == 0) { + if (b2 < 0) + b2 = 0x10001 + b2; + } else { + n1 = n2; + n2 = r; + t = b2; + b2 = b1 - q*b2; + b1 = t; + } + } while (r != 0); + } + return ((IDEA_INT)b2); +} diff --git a/Libraries/libressl/crypto/idea/idea_local.h b/Libraries/libressl/crypto/idea/idea_local.h new file mode 100644 index 000000000..c7fd3271a --- /dev/null +++ b/Libraries/libressl/crypto/idea/idea_local.h @@ -0,0 +1,149 @@ +/* $OpenBSD: idea_local.h,v 1.2 2023/07/07 12:51:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* The new form of this macro (check if the a*b == 0) was suggested by + * Colin Plumb */ +/* Removal of the inner if from from Wei Dai 24/4/96 */ +#define idea_mul(r,a,b,ul) \ +ul=(unsigned long)a*b; \ +if (ul != 0) \ + { \ + r=(ul&0xffff)-(ul>>16); \ + r-=((r)>>16); \ + } \ +else \ + r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ + +/* 7/12/95 - Many thanks to Rhys Weatherley + * for pointing out that I was assuming little endian + * byte order for all quantities what idea + * actually used bigendian. No where in the spec does it mention + * this, it is all in terms of 16 bit numbers and even the example + * does not use byte streams for the input example :-(. + * If you byte swap each pair of input, keys and iv, the functions + * would produce the output as the old version :-(. + */ + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff);\ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff);\ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff);\ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff);\ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff);\ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff);\ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff);\ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff);\ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#undef s2n +#define s2n(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) + +#undef n2s +#define n2s(c,l) (l =((IDEA_INT)(*((c)++)))<< 8L, \ + l|=((IDEA_INT)(*((c)++))) ) + +#define E_IDEA(num) \ + x1&=0xffff; \ + idea_mul(x1,x1,*p,ul); p++; \ + x2+= *(p++); \ + x3+= *(p++); \ + x4&=0xffff; \ + idea_mul(x4,x4,*p,ul); p++; \ + t0=(x1^x3)&0xffff; \ + idea_mul(t0,t0,*p,ul); p++; \ + t1=(t0+(x2^x4))&0xffff; \ + idea_mul(t1,t1,*p,ul); p++; \ + t0+=t1; \ + x1^=t1; \ + x4^=t0; \ + ul=x2^t0; /* do the swap to x3 */ \ + x2=x3^t1; \ + x3=ul; diff --git a/Libraries/libressl/crypto/kdf/hkdf_evp.c b/Libraries/libressl/crypto/kdf/hkdf_evp.c new file mode 100644 index 000000000..b33e2e0a2 --- /dev/null +++ b/Libraries/libressl/crypto/kdf/hkdf_evp.c @@ -0,0 +1,276 @@ +/* $OpenBSD: hkdf_evp.c,v 1.20 2023/06/26 08:57:17 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2016-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "evp_local.h" + +#define HKDF_MAXBUF 1024 + +typedef struct { + int mode; + const EVP_MD *md; + unsigned char *salt; + size_t salt_len; + unsigned char *key; + size_t key_len; + unsigned char info[HKDF_MAXBUF]; + size_t info_len; +} HKDF_PKEY_CTX; + +static int +pkey_hkdf_init(EVP_PKEY_CTX *ctx) +{ + HKDF_PKEY_CTX *kctx; + + if ((kctx = calloc(1, sizeof(*kctx))) == NULL) { + KDFerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + ctx->data = kctx; + + return 1; +} + +static void +pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx) +{ + HKDF_PKEY_CTX *kctx = ctx->data; + + freezero(kctx->salt, kctx->salt_len); + freezero(kctx->key, kctx->key_len); + freezero(kctx, sizeof(*kctx)); +} + +static int +pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + HKDF_PKEY_CTX *kctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_HKDF_MD: + if (p2 == NULL) + return 0; + + kctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_HKDF_MODE: + kctx->mode = p1; + return 1; + + case EVP_PKEY_CTRL_HKDF_SALT: + if (p1 == 0 || p2 == NULL) + return 1; + + if (p1 < 0) + return 0; + + freezero(kctx->salt, kctx->salt_len); + if ((kctx->salt = malloc(p1)) == NULL) + return 0; + memcpy(kctx->salt, p2, p1); + + kctx->salt_len = p1; + return 1; + + case EVP_PKEY_CTRL_HKDF_KEY: + if (p1 < 0) + return 0; + + freezero(kctx->key, kctx->key_len); + kctx->key = NULL; + kctx->key_len = 0; + + /* Match OpenSSL's behavior. */ + if (p1 == 0 || p2 == NULL) + return 0; + + if ((kctx->key = malloc(p1)) == NULL) + return 0; + memcpy(kctx->key, p2, p1); + + kctx->key_len = p1; + return 1; + + case EVP_PKEY_CTRL_HKDF_INFO: + if (p1 == 0 || p2 == NULL) + return 1; + + if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len)) + return 0; + + memcpy(kctx->info + kctx->info_len, p2, p1); + kctx->info_len += p1; + return 1; + + default: + return -2; + } +} + +static int +pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value) +{ + if (strcmp(type, "mode") == 0) { + int mode; + + if (strcmp(value, "EXTRACT_AND_EXPAND") == 0) + mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND; + else if (strcmp(value, "EXTRACT_ONLY") == 0) + mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; + else if (strcmp(value, "EXPAND_ONLY") == 0) + mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; + else + return 0; + + return EVP_PKEY_CTX_hkdf_mode(ctx, mode); + } + + if (strcmp(type, "md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MD, value); + + if (strcmp(type, "salt") == 0) + return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, + value); + + if (strcmp(type, "hexsalt") == 0) + return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, + value); + + if (strcmp(type, "key") == 0) + return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); + + if (strcmp(type, "hexkey") == 0) + return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); + + if (strcmp(type, "info") == 0) + return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, + value); + + if (strcmp(type, "hexinfo") == 0) + return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, + value); + + KDFerror(KDF_R_UNKNOWN_PARAMETER_TYPE); + return -2; +} + +static int +pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx) +{ + HKDF_PKEY_CTX *kctx = ctx->data; + + freezero(kctx->key, kctx->key_len); + freezero(kctx->salt, kctx->salt_len); + explicit_bzero(kctx, sizeof(*kctx)); + + return 1; +} + +static int +pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + HKDF_PKEY_CTX *kctx = ctx->data; + + if (kctx->md == NULL) { + KDFerror(KDF_R_MISSING_MESSAGE_DIGEST); + return 0; + } + if (kctx->key == NULL) { + KDFerror(KDF_R_MISSING_KEY); + return 0; + } + + switch (kctx->mode) { + case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: + return HKDF(key, *keylen, kctx->md, kctx->key, kctx->key_len, + kctx->salt, kctx->salt_len, kctx->info, kctx->info_len); + + case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: + if (key == NULL) { + *keylen = EVP_MD_size(kctx->md); + return 1; + } + return HKDF_extract(key, keylen, kctx->md, kctx->key, + kctx->key_len, kctx->salt, kctx->salt_len); + + case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: + return HKDF_expand(key, *keylen, kctx->md, kctx->key, + kctx->key_len, kctx->info, kctx->info_len); + + default: + return 0; + } +} + +const EVP_PKEY_METHOD hkdf_pkey_meth = { + .pkey_id = EVP_PKEY_HKDF, + .flags = 0, + + .init = pkey_hkdf_init, + .copy = NULL, + .cleanup = pkey_hkdf_cleanup, + + .derive_init = pkey_hkdf_derive_init, + .derive = pkey_hkdf_derive, + .ctrl = pkey_hkdf_ctrl, + .ctrl_str = pkey_hkdf_ctrl_str, +}; diff --git a/Libraries/libressl/crypto/kdf/kdf_err.c b/Libraries/libressl/crypto/kdf/kdf_err.c new file mode 100644 index 000000000..4dd323701 --- /dev/null +++ b/Libraries/libressl/crypto/kdf/kdf_err.c @@ -0,0 +1,89 @@ +/* $OpenBSD: kdf_err.c,v 1.9 2022/07/12 14:42:49 kn Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#ifndef OPENSSL_NO_ERR + +static ERR_STRING_DATA KDF_str_functs[] = { + {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"}, + {0, NULL}, +}; + +static ERR_STRING_DATA KDF_str_reasons[] = { + {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_KEY), "missing key"}, + {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_MESSAGE_DIGEST), + "missing message digest"}, + {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE), + "unknown parameter type"}, + {0, NULL}, +}; + +#endif + +int +ERR_load_KDF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(KDF_str_functs[0].error) == NULL) { + ERR_load_strings(0, KDF_str_functs); + ERR_load_strings(0, KDF_str_reasons); + } +#endif + return 1; +} diff --git a/Libraries/libressl/crypto/lhash/lh_stats.c b/Libraries/libressl/crypto/lhash/lh_stats.c new file mode 100644 index 000000000..123792a2a --- /dev/null +++ b/Libraries/libressl/crypto/lhash/lh_stats.c @@ -0,0 +1,263 @@ +/* $OpenBSD: lh_stats.c,v 1.13 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include + +#ifdef OPENSSL_NO_BIO + +void +lh_stats(LHASH *lh, FILE *out) +{ + fprintf(out, "num_items = %lu\n", lh->num_items); + fprintf(out, "num_nodes = %u\n", lh->num_nodes); + fprintf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); + fprintf(out, "num_expands = %lu\n", lh->num_expands); + fprintf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); + fprintf(out, "num_contracts = %lu\n", lh->num_contracts); + fprintf(out, "num_contract_reallocs = %lu\n", + lh->num_contract_reallocs); + fprintf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); + fprintf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); + fprintf(out, "num_insert = %lu\n", lh->num_insert); + fprintf(out, "num_replace = %lu\n", lh->num_replace); + fprintf(out, "num_delete = %lu\n", lh->num_delete); + fprintf(out, "num_no_delete = %lu\n", lh->num_no_delete); + fprintf(out, "num_retrieve = %lu\n", lh->num_retrieve); + fprintf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); + fprintf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); +#if 0 + fprintf(out, "p = %u\n", lh->p); + fprintf(out, "pmax = %u\n", lh->pmax); + fprintf(out, "up_load = %lu\n", lh->up_load); + fprintf(out, "down_load = %lu\n", lh->down_load); +#endif +} +LCRYPTO_ALIAS(lh_stats); + +void +lh_node_stats(LHASH *lh, FILE *out) +{ + LHASH_NODE *n; + unsigned int i, num; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + fprintf(out, "node %6u -> %3u\n", i, num); + } +} +LCRYPTO_ALIAS(lh_node_stats); + +void +lh_node_usage_stats(LHASH *lh, FILE *out) +{ + LHASH_NODE *n; + unsigned long num; + unsigned int i; + unsigned long total = 0, n_used = 0; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + if (num != 0) { + n_used++; + total += num; + } + } + fprintf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); + fprintf(out, "%lu items\n", total); + if (n_used == 0) + return; + fprintf(out, "load %d.%02d actual load %d.%02d\n", + (int)(total / lh->num_nodes), + (int)((total % lh->num_nodes) * 100 / lh->num_nodes), + (int)(total / n_used), + (int)((total % n_used) * 100 / n_used)); +} +LCRYPTO_ALIAS(lh_node_usage_stats); + +#else + +void +lh_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_stats_bio(lh, bp); + BIO_free(bp); +end:; +} +LCRYPTO_ALIAS(lh_stats); + +void +lh_node_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_node_stats_bio(lh, bp); + BIO_free(bp); +end:; +} +LCRYPTO_ALIAS(lh_node_stats); + +void +lh_node_usage_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_node_usage_stats_bio(lh, bp); + BIO_free(bp); +end:; +} +LCRYPTO_ALIAS(lh_node_usage_stats); + + +void +lh_stats_bio(const _LHASH *lh, BIO *out) +{ + BIO_printf(out, "num_items = %lu\n", lh->num_items); + BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); + BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); + BIO_printf(out, "num_expands = %lu\n", lh->num_expands); + BIO_printf(out, "num_expand_reallocs = %lu\n", + lh->num_expand_reallocs); + BIO_printf(out, "num_contracts = %lu\n", lh->num_contracts); + BIO_printf(out, "num_contract_reallocs = %lu\n", + lh->num_contract_reallocs); + BIO_printf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); + BIO_printf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); + BIO_printf(out, "num_insert = %lu\n", lh->num_insert); + BIO_printf(out, "num_replace = %lu\n", lh->num_replace); + BIO_printf(out, "num_delete = %lu\n", lh->num_delete); + BIO_printf(out, "num_no_delete = %lu\n", lh->num_no_delete); + BIO_printf(out, "num_retrieve = %lu\n", lh->num_retrieve); + BIO_printf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); + BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); +#if 0 + BIO_printf(out, "p = %u\n", lh->p); + BIO_printf(out, "pmax = %u\n", lh->pmax); + BIO_printf(out, "up_load = %lu\n", lh->up_load); + BIO_printf(out, "down_load = %lu\n", lh->down_load); +#endif +} +LCRYPTO_ALIAS(lh_stats_bio); + +void +lh_node_stats_bio(const _LHASH *lh, BIO *out) +{ + LHASH_NODE *n; + unsigned int i, num; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + BIO_printf(out, "node %6u -> %3u\n", i, num); + } +} +LCRYPTO_ALIAS(lh_node_stats_bio); + +void +lh_node_usage_stats_bio(const _LHASH *lh, BIO *out) +{ + LHASH_NODE *n; + unsigned long num; + unsigned int i; + unsigned long total = 0, n_used = 0; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + if (num != 0) { + n_used++; + total += num; + } + } + BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); + BIO_printf(out, "%lu items\n", total); + if (n_used == 0) + return; + BIO_printf(out, "load %d.%02d actual load %d.%02d\n", + (int)(total / lh->num_nodes), + (int)((total % lh->num_nodes) * 100 / lh->num_nodes), + (int)(total / n_used), + (int)((total % n_used) * 100 / n_used)); +} +LCRYPTO_ALIAS(lh_node_usage_stats_bio); + +#endif diff --git a/Libraries/libressl/crypto/lhash/lhash.c b/Libraries/libressl/crypto/lhash/lhash.c new file mode 100644 index 000000000..3adec71ed --- /dev/null +++ b/Libraries/libressl/crypto/lhash/lhash.c @@ -0,0 +1,443 @@ +/* $OpenBSD: lhash.c,v 1.20 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Code for dynamic hash table routines + * Author - Eric Young v 2.0 + * + * 2.2 eay - added #include "crypto.h" so the memory leak checking code is + * present. eay 18-Jun-98 + * + * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98 + * + * 2.0 eay - Fixed a bug that occurred when using lh_delete + * from inside lh_doall(). As entries were deleted, + * the 'table' was 'contract()ed', making some entries + * jump from the end of the table to the start, there by + * skipping the lh_doall() processing. eay - 4/12/95 + * + * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs + * were not being free()ed. 21/11/95 + * + * 1.8 eay - Put the stats routines into a separate file, lh_stats.c + * 19/09/95 + * + * 1.7 eay - Removed the fputs() for realloc failures - the code + * should silently tolerate them. I have also fixed things + * lint complained about 04/05/95 + * + * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92 + * + * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992 + * + * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91 + * + * 1.3 eay - Fixed a few lint problems 19/3/1991 + * + * 1.2 eay - Fixed lh_doall problem 13/3/1991 + * + * 1.1 eay - Added lh_doall + * + * 1.0 eay - First version + */ +#include +#include +#include + +#include + +#include +#include + +#undef MIN_NODES +#define MIN_NODES 16 +#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ +#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ + +static void expand(_LHASH *lh); +static void contract(_LHASH *lh); +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); + +_LHASH * +lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) +{ + _LHASH *ret; + + if ((ret = calloc(1, sizeof(_LHASH))) == NULL) + return NULL; + if ((ret->b = calloc(MIN_NODES, sizeof(LHASH_NODE *))) == NULL) { + free(ret); + return NULL; + } + ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c); + ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h); + ret->num_nodes = MIN_NODES / 2; + ret->num_alloc_nodes = MIN_NODES; + ret->pmax = MIN_NODES / 2; + ret->up_load = UP_LOAD; + ret->down_load = DOWN_LOAD; + + return (ret); +} +LCRYPTO_ALIAS(lh_new); + +void +lh_free(_LHASH *lh) +{ + unsigned int i; + LHASH_NODE *n, *nn; + + if (lh == NULL) + return; + + for (i = 0; i < lh->num_nodes; i++) { + n = lh->b[i]; + while (n != NULL) { + nn = n->next; + free(n); + n = nn; + } + } + free(lh->b); + free(lh); +} +LCRYPTO_ALIAS(lh_free); + +void * +lh_insert(_LHASH *lh, void *data) +{ + unsigned long hash; + LHASH_NODE *nn, **rn; + void *ret; + + lh->error = 0; + if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) + expand(lh); + + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + if ((nn = malloc(sizeof(LHASH_NODE))) == NULL) { + lh->error++; + return (NULL); + } + nn->data = data; + nn->next = NULL; +#ifndef OPENSSL_NO_HASH_COMP + nn->hash = hash; +#endif + *rn = nn; + ret = NULL; + lh->num_insert++; + lh->num_items++; + } + else /* replace same key */ + { + ret = (*rn)->data; + (*rn)->data = data; + lh->num_replace++; + } + return (ret); +} +LCRYPTO_ALIAS(lh_insert); + +void * +lh_delete(_LHASH *lh, const void *data) +{ + unsigned long hash; + LHASH_NODE *nn, **rn; + void *ret; + + lh->error = 0; + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + lh->num_no_delete++; + return (NULL); + } else { + nn= *rn; + *rn = nn->next; + ret = nn->data; + free(nn); + lh->num_delete++; + } + + lh->num_items--; + if ((lh->num_nodes > MIN_NODES) && + (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))) + contract(lh); + + return (ret); +} +LCRYPTO_ALIAS(lh_delete); + +void * +lh_retrieve(_LHASH *lh, const void *data) +{ + unsigned long hash; + LHASH_NODE **rn; + void *ret; + + lh->error = 0; + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + lh->num_retrieve_miss++; + return (NULL); + } else { + ret = (*rn)->data; + lh->num_retrieve++; + } + return (ret); +} +LCRYPTO_ALIAS(lh_retrieve); + +static void +doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, + LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) +{ + int i; + LHASH_NODE *a, *n; + + if (lh == NULL) + return; + + /* reverse the order so we search from 'top to bottom' + * We were having memory leaks otherwise */ + for (i = lh->num_nodes - 1; i >= 0; i--) { + a = lh->b[i]; + while (a != NULL) { + /* 28/05/91 - eay - n added so items can be deleted + * via lh_doall */ + /* 22/05/08 - ben - eh? since a is not passed, + * this should not be needed */ + n = a->next; + if (use_arg) + func_arg(a->data, arg); + else + func(a->data); + a = n; + } + } +} + +void +lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) +{ + doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); +} +LCRYPTO_ALIAS(lh_doall); + +void +lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) +{ + doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); +} +LCRYPTO_ALIAS(lh_doall_arg); + +static void +expand(_LHASH *lh) +{ + LHASH_NODE **n, **n1, **n2, *np; + unsigned int p, i, j; + unsigned long hash, nni; + + lh->num_nodes++; + lh->num_expands++; + p = (int)lh->p++; + n1 = &(lh->b[p]); + n2 = &(lh->b[p + (int)lh->pmax]); + *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ + nni = lh->num_alloc_nodes; + + for (np = *n1; np != NULL; ) { +#ifndef OPENSSL_NO_HASH_COMP + hash = np->hash; +#else + hash = lh->hash(np->data); + lh->num_hash_calls++; +#endif + if ((hash % nni) != p) { /* move it */ + *n1 = (*n1)->next; + np->next= *n2; + *n2 = np; + } else + n1 = &((*n1)->next); + np= *n1; + } + + if ((lh->p) >= lh->pmax) { + j = (int)lh->num_alloc_nodes * 2; + n = reallocarray(lh->b, j, sizeof(LHASH_NODE *)); + if (n == NULL) { +/* fputs("realloc error in lhash", stderr); */ + lh->error++; + lh->p = 0; + return; + } + /* else */ + for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */ + n[i] = NULL; /* 02/03/92 eay */ + lh->pmax = lh->num_alloc_nodes; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + lh->b = n; + } +} + +static void +contract(_LHASH *lh) +{ + LHASH_NODE **n, *n1, *np; + + np = lh->b[lh->p + lh->pmax - 1]; + lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ + if (lh->p == 0) { + n = reallocarray(lh->b, lh->pmax, sizeof(LHASH_NODE *)); + if (n == NULL) { +/* fputs("realloc error in lhash", stderr); */ + lh->error++; + return; + } + lh->num_contract_reallocs++; + lh->num_alloc_nodes /= 2; + lh->pmax /= 2; + lh->p = lh->pmax - 1; + lh->b = n; + } else + lh->p--; + + lh->num_nodes--; + lh->num_contracts++; + + n1 = lh->b[(int)lh->p]; + if (n1 == NULL) + lh->b[(int)lh->p] = np; + else { + while (n1->next != NULL) + n1 = n1->next; + n1->next = np; + } +} + +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) +{ + LHASH_NODE **ret, *n1; + unsigned long hash, nn; + LHASH_COMP_FN_TYPE cf; + + hash = (*(lh->hash))(data); + lh->num_hash_calls++; + *rhash = hash; + + nn = hash % lh->pmax; + if (nn < lh->p) + nn = hash % lh->num_alloc_nodes; + + cf = lh->comp; + ret = &(lh->b[(int)nn]); + for (n1 = *ret; n1 != NULL; n1 = n1->next) { +#ifndef OPENSSL_NO_HASH_COMP + lh->num_hash_comps++; + if (n1->hash != hash) { + ret = &(n1->next); + continue; + } +#endif + lh->num_comp_calls++; + if (cf(n1->data, data) == 0) + break; + ret = &(n1->next); + } + return (ret); +} + +/* The following hash seems to work very well on normal text strings + * no collisions on /usr/dict/words and it distributes on %2^n quite + * well, not as good as MD5, but still good. + */ +unsigned long +lh_strhash(const char *c) +{ + unsigned long ret = 0; + unsigned long n, v; + unsigned int r; + + if (c == NULL || *c == '\0') + return ret; + + n = 0x100; + while (*c) { + v = n | *c; + n += 0x100; + if ((r = ((v >> 2) ^ v) & 0x0f) != 0) + ret = (ret << r) | (ret >> (32 - r)); + ret &= 0xFFFFFFFFUL; + ret ^= v * v; + c++; + } + return (ret >> 16) ^ ret; +} +LCRYPTO_ALIAS(lh_strhash); + +unsigned long +lh_num_items(const _LHASH *lh) +{ + return lh ? lh->num_items : 0; +} +LCRYPTO_ALIAS(lh_num_items); diff --git a/Libraries/libressl/crypto/malloc-wrapper.c b/Libraries/libressl/crypto/malloc-wrapper.c new file mode 100644 index 000000000..4d57f00b2 --- /dev/null +++ b/Libraries/libressl/crypto/malloc-wrapper.c @@ -0,0 +1,205 @@ +/* $OpenBSD: malloc-wrapper.c,v 1.8 2023/07/08 08:28:23 beck Exp $ */ +/* + * Copyright (c) 2014 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include + +#include + +int +CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t), + void (*f)(void *)) +{ + return 0; +} +LCRYPTO_ALIAS(CRYPTO_set_mem_functions); + +int +CRYPTO_set_mem_ex_functions(void *(*m)(size_t, const char *, int), + void *(*r)(void *, size_t, const char *, int), void (*f)(void *)) +{ + return 0; +} +LCRYPTO_ALIAS(CRYPTO_set_mem_ex_functions); + +int +CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *)) +{ + return 0; +} +LCRYPTO_ALIAS(CRYPTO_set_locked_mem_functions); + +int +CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t, const char *, int), + void (*f)(void *)) +{ + return 0; +} +LCRYPTO_ALIAS(CRYPTO_set_locked_mem_ex_functions); + +int +CRYPTO_set_mem_debug_functions(void (*m)(void *, int, const char *, int, int), + void (*r)(void *, void *, int, const char *, int, int), + void (*f)(void *, int), void (*so)(long), long (*go)(void)) +{ + return 0; +} +LCRYPTO_ALIAS(CRYPTO_set_mem_debug_functions); + + +void +CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t), + void (**f)(void *)) +{ + if (m != NULL) + *m = malloc; + if (r != NULL) + *r = realloc; + if (f != NULL) + *f = free; +} +LCRYPTO_ALIAS(CRYPTO_get_mem_functions); + +void +CRYPTO_get_mem_ex_functions(void *(**m)(size_t, const char *, int), + void *(**r)(void *, size_t, const char *, int), void (**f)(void *)) +{ + if (m != NULL) + *m = NULL; + if (r != NULL) + *r = NULL; + if (f != NULL) + *f = free; +} +LCRYPTO_ALIAS(CRYPTO_get_mem_ex_functions); + +void +CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)) +{ + if (m != NULL) + *m = malloc; + if (f != NULL) + *f = free; +} +LCRYPTO_ALIAS(CRYPTO_get_locked_mem_functions); + +void +CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t, const char *, int), + void (**f)(void *)) +{ + if (m != NULL) + *m = NULL; + if (f != NULL) + *f = free; +} +LCRYPTO_ALIAS(CRYPTO_get_locked_mem_ex_functions); + +void +CRYPTO_get_mem_debug_functions(void (**m)(void *, int, const char *, int, int), + void (**r)(void *, void *, int, const char *, int, int), + void (**f)(void *, int), void (**so)(long), long (**go)(void)) +{ + if (m != NULL) + *m = NULL; + if (r != NULL) + *r = NULL; + if (f != NULL) + *f = NULL; + if (so != NULL) + *so = NULL; + if (go != NULL) + *go = NULL; +} +LCRYPTO_ALIAS(CRYPTO_get_mem_debug_functions); + + +void * +CRYPTO_malloc_locked(int num, const char *file, int line) +{ + if (num <= 0) + return NULL; + return malloc(num); +} + +void +CRYPTO_free_locked(void *ptr) +{ + free(ptr); +} + +void * +CRYPTO_malloc(int num, const char *file, int line) +{ + if (num <= 0) + return NULL; + return malloc(num); +} + +char * +CRYPTO_strdup(const char *str, const char *file, int line) +{ + return strdup(str); +} + +void * +CRYPTO_realloc(void *ptr, int num, const char *file, int line) +{ + if (num <= 0) + return NULL; + return realloc(ptr, num); +} + +void * +CRYPTO_realloc_clean(void *ptr, int old_len, int num, const char *file, + int line) +{ + if (num <= 0) + return NULL; + /* Original does not support shrinking. */ + if (num < old_len) + return NULL; + return recallocarray(ptr, old_len, num, 1); +} +LCRYPTO_ALIAS(CRYPTO_realloc_clean); + +void +CRYPTO_free(void *ptr) +{ + free(ptr); +} + +void * +CRYPTO_remalloc(void *a, int num, const char *file, int line) +{ + free(a); + return malloc(num); +} +LCRYPTO_ALIAS(CRYPTO_remalloc); + +void +CRYPTO_set_mem_debug_options(long bits) +{ + return; +} +LCRYPTO_ALIAS(CRYPTO_set_mem_debug_options); + +long +CRYPTO_get_mem_debug_options(void) +{ + return 0; +} +LCRYPTO_ALIAS(CRYPTO_get_mem_debug_options); diff --git a/Libraries/libressl/crypto/md32_common.h b/Libraries/libressl/crypto/md32_common.h new file mode 100644 index 000000000..f61c49f03 --- /dev/null +++ b/Libraries/libressl/crypto/md32_common.h @@ -0,0 +1,309 @@ +/* $OpenBSD: md32_common.h,v 1.26 2023/08/10 07:15:23 jsing Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +/* + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at least 32 bit wide. + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * either { + * HASH_LONG data[HASH_LBLOCK]; + * unsigned char data[HASH_CBLOCK]; + * }; + * unsigned int num; + * ... + * } HASH_CTX; + * data[] vector is expected to be zeroed upon first call to + * HASH_UPDATE. + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_DATA_ORDER + * name of "block" function capable of treating *unaligned* input + * message in original (data) byte order, implemented externally. + * HASH_MAKE_STRING + * macro convering context variables to an ASCII hash string. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + * + * + */ + +#include + +#include + +#include "crypto_internal.h" + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +#error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +#error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +#error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +#error "HASH_CTX must be defined!" +#endif + +#if !defined(HASH_UPDATE) && !defined(HASH_NO_UPDATE) +#error "HASH_UPDATE must be defined!" +#endif +#if !defined(HASH_TRANSFORM) && !defined(HASH_NO_TRANSFORM) +#error "HASH_TRANSFORM must be defined!" +#endif +#if !defined(HASH_FINAL) && !defined(HASH_NO_FINAL) +#error "HASH_FINAL or HASH_NO_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif + +#define ROTATE(a, n) crypto_rol_u32(a, n) + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if (defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__)) + /* + * This gives ~30-40% performance improvement in SHA-256 compiled + * with gcc [on P4]. Well, first macro to be frank. We can pull + * this trick on x86* platforms only, because these CPUs can fetch + * unaligned data without raising an exception. + */ +# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r=(l); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + *((unsigned int *)(c))=r; (c)+=4; }) +# endif +#endif + +#ifndef HOST_c2l +#define HOST_c2l(c,l) do {l =(((unsigned long)(*((c)++)))<<24); \ + l|=(((unsigned long)(*((c)++)))<<16); \ + l|=(((unsigned long)(*((c)++)))<< 8); \ + l|=(((unsigned long)(*((c)++))) ); \ + } while (0) +#endif +#ifndef HOST_l2c +#define HOST_l2c(l,c) do {*((c)++)=(unsigned char)(((l)>>24)&0xff); \ + *((c)++)=(unsigned char)(((l)>>16)&0xff); \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff); \ + *((c)++)=(unsigned char)(((l) )&0xff); \ + } while (0) +#endif + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4) +#endif + +#ifndef HOST_c2l +#define HOST_c2l(c,l) do {l =(((unsigned long)(*((c)++))) ); \ + l|=(((unsigned long)(*((c)++)))<< 8); \ + l|=(((unsigned long)(*((c)++)))<<16); \ + l|=(((unsigned long)(*((c)++)))<<24); \ + } while (0) +#endif +#ifndef HOST_l2c +#define HOST_l2c(l,c) do {*((c)++)=(unsigned char)(((l) )&0xff); \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff); \ + *((c)++)=(unsigned char)(((l)>>16)&0xff); \ + *((c)++)=(unsigned char)(((l)>>24)&0xff); \ + } while (0) +#endif + +#endif + +/* + * Time for some action:-) + */ + +#ifndef HASH_NO_UPDATE +int +HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + HASH_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((HASH_LONG)len) << 3))&0xffffffffUL; + /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to + * Wei Dai for pointing it out. */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + memcpy (p + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER (c, p, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset (p,0,HASH_CBLOCK); /* keep it zeroed */ + } else { + memcpy (p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len/HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER (c, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy (p, data, len); + } + return 1; +} +#endif + +#ifndef HASH_NO_TRANSFORM +void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) +{ + HASH_BLOCK_DATA_ORDER (c, data, 1); +} +#endif + +#ifndef HASH_NO_FINAL +int HASH_FINAL (unsigned char *md, HASH_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (HASH_CBLOCK - 8)) { + memset (p + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER (c, p, 1); + } + memset (p + n, 0, HASH_CBLOCK - 8 - n); + + p += HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + HOST_l2c(c->Nh, p); + HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); +#endif + p -= HASH_CBLOCK; + HASH_BLOCK_DATA_ORDER (c, p, 1); + c->num = 0; + memset (p, 0, HASH_CBLOCK); + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#else + HASH_MAKE_STRING(c, md); +#endif + + return 1; +} +#endif diff --git a/Libraries/libressl/crypto/md4/md4.c b/Libraries/libressl/crypto/md4/md4.c new file mode 100644 index 000000000..12e3ac71d --- /dev/null +++ b/Libraries/libressl/crypto/md4/md4.c @@ -0,0 +1,264 @@ +/* $OpenBSD: md4.c,v 1.7 2023/08/10 13:41:56 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include + +__BEGIN_HIDDEN_DECLS + +void md4_block_data_order (MD4_CTX *c, const void *p, size_t num); + +__END_HIDDEN_DECLS + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD4_LONG +#define HASH_CTX MD4_CTX +#define HASH_CBLOCK MD4_CBLOCK +#define HASH_UPDATE MD4_Update +#define HASH_TRANSFORM MD4_Transform +#define HASH_FINAL MD4_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; HOST_l2c(ll,(s)); \ + ll=(c)->B; HOST_l2c(ll,(s)); \ + ll=(c)->C; HOST_l2c(ll,(s)); \ + ll=(c)->D; HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md4_block_data_order + +#include "md32_common.h" +LCRYPTO_ALIAS(MD4_Update); +LCRYPTO_ALIAS(MD4_Final); +LCRYPTO_ALIAS(MD4_Transform); + +/* +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z)))) +*/ + +/* As pointed out by Wei Dai , the above can be + * simplified to the code below. Wei attributes these optimizations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define H(b,c,d) ((b) ^ (c) ^ (d)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); }; + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); };\ + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); }; + +/* Implemented from RFC1186 The MD4 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +int +MD4_Init(MD4_CTX *c) +{ + memset (c, 0, sizeof(*c)); + c->A = INIT_DATA_A; + c->B = INIT_DATA_B; + c->C = INIT_DATA_C; + c->D = INIT_DATA_D; + return 1; +} +LCRYPTO_ALIAS(MD4_Init); + +#ifndef md4_block_data_order +#ifdef X +#undef X +#endif +void +md4_block_data_order(MD4_CTX *c, const void *data_, size_t num) +{ + const unsigned char *data = data_; + unsigned int A, B, C, D, l; + unsigned int X0, X1, X2, X3, X4, X5, X6, X7, + X8, X9, X10, X11, X12, X13, X14, X15; + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--; ) { + HOST_c2l(data, l); + X0 = l; + HOST_c2l(data, l); + X1 = l; + /* Round 0 */ + R0(A, B, C, D, X0, 3, 0); + HOST_c2l(data, l); + X2 = l; + R0(D, A, B, C, X1, 7, 0); + HOST_c2l(data, l); + X3 = l; + R0(C, D, A, B, X2, 11, 0); + HOST_c2l(data, l); + X4 = l; + R0(B, C, D, A, X3, 19, 0); + HOST_c2l(data, l); + X5 = l; + R0(A, B, C, D, X4, 3, 0); + HOST_c2l(data, l); + X6 = l; + R0(D, A, B, C, X5, 7, 0); + HOST_c2l(data, l); + X7 = l; + R0(C, D, A, B, X6, 11, 0); + HOST_c2l(data, l); + X8 = l; + R0(B, C, D, A, X7, 19, 0); + HOST_c2l(data, l); + X9 = l; + R0(A, B, C, D, X8, 3, 0); + HOST_c2l(data, l); + X10 = l; + R0(D, A,B, C,X9, 7, 0); + HOST_c2l(data, l); + X11 = l; + R0(C, D,A, B,X10, 11, 0); + HOST_c2l(data, l); + X12 = l; + R0(B, C,D, A,X11, 19, 0); + HOST_c2l(data, l); + X13 = l; + R0(A, B,C, D,X12, 3, 0); + HOST_c2l(data, l); + X14 = l; + R0(D, A,B, C,X13, 7, 0); + HOST_c2l(data, l); + X15 = l; + R0(C, D,A, B,X14, 11, 0); + R0(B, C,D, A,X15, 19, 0); + /* Round 1 */ + R1(A, B, C, D, X0, 3, 0x5A827999L); + R1(D, A, B, C, X4, 5, 0x5A827999L); + R1(C, D, A, B, X8, 9, 0x5A827999L); + R1(B, C, D, A, X12, 13, 0x5A827999L); + R1(A, B, C, D, X1, 3, 0x5A827999L); + R1(D, A, B, C, X5, 5, 0x5A827999L); + R1(C, D, A, B, X9, 9, 0x5A827999L); + R1(B, C, D, A, X13, 13, 0x5A827999L); + R1(A, B, C, D, X2, 3, 0x5A827999L); + R1(D, A, B, C, X6, 5, 0x5A827999L); + R1(C, D, A, B, X10, 9, 0x5A827999L); + R1(B, C, D, A, X14, 13, 0x5A827999L); + R1(A, B, C, D, X3, 3, 0x5A827999L); + R1(D, A, B, C, X7, 5, 0x5A827999L); + R1(C, D, A, B, X11, 9, 0x5A827999L); + R1(B, C, D, A, X15, 13, 0x5A827999L); + /* Round 2 */ + R2(A, B, C, D, X0, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X8, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X4, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X12, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X2, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X10, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X6, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X14, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X1, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X9, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X5, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X13, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X3, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X11, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X7, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X15, 15, 0x6ED9EBA1L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} +#endif + +unsigned char * +MD4(const unsigned char *d, size_t n, unsigned char *md) +{ + MD4_CTX c; + static unsigned char m[MD4_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD4_Init(&c)) + return NULL; + MD4_Update(&c, d, n); + MD4_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} +LCRYPTO_ALIAS(MD4); diff --git a/Libraries/libressl/crypto/md5/md5-elf-x86_64.S b/Libraries/libressl/crypto/md5/md5-elf-x86_64.S new file mode 100644 index 000000000..8fc10c9f1 --- /dev/null +++ b/Libraries/libressl/crypto/md5/md5-elf-x86_64.S @@ -0,0 +1,673 @@ +#include "x86_arch.h" +.text +.align 16 + +.globl md5_block_asm_data_order +.type md5_block_asm_data_order,@function +md5_block_asm_data_order: + endbr64 + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r14 + pushq %r15 +.Lprologue: + + + + + movq %rdi,%rbp + shlq $6,%rdx + leaq (%rsi,%rdx,1),%rdi + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + + + + + + + + cmpq %rdi,%rsi + je .Lend + + +.Lloop: + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r14d + movl %edx,%r15d + movl 0(%rsi),%r10d + movl %edx,%r11d + xorl %ecx,%r11d + leal -680876936(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 4(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -389564586(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 8(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal 606105819(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 12(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1044525330(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 16(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal -176418897(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 20(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal 1200080426(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 24(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1473231341(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 28(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -45705983(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 32(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1770035416(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 36(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -1958414417(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 40(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -42063(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 44(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1990404162(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 48(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1804603682(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 52(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -40341101(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 56(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1502002290(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 60(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal 1236535329(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 0(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + movl 4(%rsi),%r10d + movl %edx,%r11d + movl %edx,%r12d + notl %r11d + leal -165796510(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 24(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1069501632(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 44(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 643717713(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -373897302(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 20(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -701558691(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 40(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal 38016083(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 60(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -660478335(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 16(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -405537848(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 36(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal 568446438(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 56(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1019803690(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 12(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -187363961(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 32(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal 1163531501(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 52(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -1444681467(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 8(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -51403784(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 28(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 1735328473(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 48(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -1926607734(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + movl 20(%rsi),%r10d + movl %ecx,%r11d + leal -378558(%rax,%r10,1),%eax + movl 32(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -2022574463(%rdx,%r10,1),%edx + movl 44(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 1839030562(%rcx,%r10,1),%ecx + movl 56(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -35309556(%rbx,%r10,1),%ebx + movl 4(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -1530992060(%rax,%r10,1),%eax + movl 16(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal 1272893353(%rdx,%r10,1),%edx + movl 28(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -155497632(%rcx,%r10,1),%ecx + movl 40(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -1094730640(%rbx,%r10,1),%ebx + movl 52(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal 681279174(%rax,%r10,1),%eax + movl 0(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -358537222(%rdx,%r10,1),%edx + movl 12(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -722521979(%rcx,%r10,1),%ecx + movl 24(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal 76029189(%rbx,%r10,1),%ebx + movl 36(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -640364487(%rax,%r10,1),%eax + movl 48(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -421815835(%rdx,%r10,1),%edx + movl 60(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 530742520(%rcx,%r10,1),%ecx + movl 8(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -995338651(%rbx,%r10,1),%ebx + movl 0(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + movl 0(%rsi),%r10d + movl $4294967295,%r11d + xorl %edx,%r11d + leal -198630844(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 28(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal 1126891415(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 56(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1416354905(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 20(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -57434055(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 48(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1700485571(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 12(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1894986606(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 40(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1051523(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 4(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -2054922799(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 32(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1873313359(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 60(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -30611744(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 24(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1560198380(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 52(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal 1309151649(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 16(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal -145523070(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 44(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1120210379(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 8(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal 718787259(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 36(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -343485551(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 0(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + + addl %r8d,%eax + addl %r9d,%ebx + addl %r14d,%ecx + addl %r15d,%edx + + + addq $64,%rsi + cmpq %rdi,%rsi + jb .Lloop + + +.Lend: + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + movq (%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r12 + movq 24(%rsp),%rbx + movq 32(%rsp),%rbp + addq $40,%rsp +.Lepilogue: + retq +.size md5_block_asm_data_order,.-md5_block_asm_data_order +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/md5/md5-macosx-x86_64.S b/Libraries/libressl/crypto/md5/md5-macosx-x86_64.S new file mode 100644 index 000000000..b4fcd181d --- /dev/null +++ b/Libraries/libressl/crypto/md5/md5-macosx-x86_64.S @@ -0,0 +1,669 @@ +#include "x86_arch.h" +.text +.p2align 4 + +.globl _md5_block_asm_data_order + +_md5_block_asm_data_order: + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r14 + pushq %r15 +L$prologue: + + + + + movq %rdi,%rbp + shlq $6,%rdx + leaq (%rsi,%rdx,1),%rdi + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + + + + + + + + cmpq %rdi,%rsi + je L$end + + +L$loop: + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r14d + movl %edx,%r15d + movl 0(%rsi),%r10d + movl %edx,%r11d + xorl %ecx,%r11d + leal -680876936(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 4(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -389564586(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 8(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal 606105819(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 12(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1044525330(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 16(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal -176418897(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 20(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal 1200080426(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 24(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1473231341(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 28(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -45705983(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 32(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1770035416(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 36(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -1958414417(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 40(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -42063(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 44(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1990404162(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 48(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1804603682(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 52(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -40341101(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 56(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1502002290(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 60(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal 1236535329(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 0(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + movl 4(%rsi),%r10d + movl %edx,%r11d + movl %edx,%r12d + notl %r11d + leal -165796510(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 24(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1069501632(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 44(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 643717713(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -373897302(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 20(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -701558691(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 40(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal 38016083(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 60(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -660478335(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 16(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -405537848(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 36(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal 568446438(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 56(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1019803690(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 12(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -187363961(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 32(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal 1163531501(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 52(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -1444681467(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 8(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -51403784(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 28(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 1735328473(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 48(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -1926607734(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + movl 20(%rsi),%r10d + movl %ecx,%r11d + leal -378558(%rax,%r10,1),%eax + movl 32(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -2022574463(%rdx,%r10,1),%edx + movl 44(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 1839030562(%rcx,%r10,1),%ecx + movl 56(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -35309556(%rbx,%r10,1),%ebx + movl 4(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -1530992060(%rax,%r10,1),%eax + movl 16(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal 1272893353(%rdx,%r10,1),%edx + movl 28(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -155497632(%rcx,%r10,1),%ecx + movl 40(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -1094730640(%rbx,%r10,1),%ebx + movl 52(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal 681279174(%rax,%r10,1),%eax + movl 0(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -358537222(%rdx,%r10,1),%edx + movl 12(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -722521979(%rcx,%r10,1),%ecx + movl 24(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal 76029189(%rbx,%r10,1),%ebx + movl 36(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -640364487(%rax,%r10,1),%eax + movl 48(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -421815835(%rdx,%r10,1),%edx + movl 60(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 530742520(%rcx,%r10,1),%ecx + movl 8(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -995338651(%rbx,%r10,1),%ebx + movl 0(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + movl 0(%rsi),%r10d + movl $4294967295,%r11d + xorl %edx,%r11d + leal -198630844(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 28(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal 1126891415(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 56(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1416354905(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 20(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -57434055(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 48(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1700485571(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 12(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1894986606(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 40(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1051523(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 4(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -2054922799(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 32(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1873313359(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 60(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -30611744(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 24(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1560198380(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 52(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal 1309151649(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 16(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal -145523070(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 44(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1120210379(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 8(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal 718787259(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 36(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -343485551(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 0(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + + addl %r8d,%eax + addl %r9d,%ebx + addl %r14d,%ecx + addl %r15d,%edx + + + addq $64,%rsi + cmpq %rdi,%rsi + jb L$loop + + +L$end: + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + movq (%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r12 + movq 24(%rsp),%rbx + movq 32(%rsp),%rbp + addq $40,%rsp +L$epilogue: + retq + diff --git a/Libraries/libressl/crypto/md5/md5-masm-x86_64.S b/Libraries/libressl/crypto/md5/md5-masm-x86_64.S new file mode 100644 index 000000000..85d0bcb97 --- /dev/null +++ b/Libraries/libressl/crypto/md5/md5-masm-x86_64.S @@ -0,0 +1,753 @@ +; 1 "crypto/md5/md5-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/md5/md5-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/md5/md5-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' +ALIGN 16 + +PUBLIC md5_block_asm_data_order + +md5_block_asm_data_order PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_md5_block_asm_data_order:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + + push rbp + push rbx + push r12 + push r14 + push r15 +$L$prologue:: + + + + + mov rbp,rdi + shl rdx,6 + lea rdi,QWORD PTR[rdx*1+rsi] + mov eax,DWORD PTR[rbp] + mov ebx,DWORD PTR[4+rbp] + mov ecx,DWORD PTR[8+rbp] + mov edx,DWORD PTR[12+rbp] + + + + + + + + cmp rsi,rdi + je $L$end + + +$L$loop:: + mov r8d,eax + mov r9d,ebx + mov r14d,ecx + mov r15d,edx + mov r10d,DWORD PTR[rsi] + mov r11d,edx + xor r11d,ecx + lea eax,DWORD PTR[((-680876936))+r10*1+rax] + and r11d,ebx + xor r11d,edx + mov r10d,DWORD PTR[4+rsi] + add eax,r11d + rol eax,7 + mov r11d,ecx + add eax,ebx + xor r11d,ebx + lea edx,DWORD PTR[((-389564586))+r10*1+rdx] + and r11d,eax + xor r11d,ecx + mov r10d,DWORD PTR[8+rsi] + add edx,r11d + rol edx,12 + mov r11d,ebx + add edx,eax + xor r11d,eax + lea ecx,DWORD PTR[606105819+r10*1+rcx] + and r11d,edx + xor r11d,ebx + mov r10d,DWORD PTR[12+rsi] + add ecx,r11d + rol ecx,17 + mov r11d,eax + add ecx,edx + xor r11d,edx + lea ebx,DWORD PTR[((-1044525330))+r10*1+rbx] + and r11d,ecx + xor r11d,eax + mov r10d,DWORD PTR[16+rsi] + add ebx,r11d + rol ebx,22 + mov r11d,edx + add ebx,ecx + xor r11d,ecx + lea eax,DWORD PTR[((-176418897))+r10*1+rax] + and r11d,ebx + xor r11d,edx + mov r10d,DWORD PTR[20+rsi] + add eax,r11d + rol eax,7 + mov r11d,ecx + add eax,ebx + xor r11d,ebx + lea edx,DWORD PTR[1200080426+r10*1+rdx] + and r11d,eax + xor r11d,ecx + mov r10d,DWORD PTR[24+rsi] + add edx,r11d + rol edx,12 + mov r11d,ebx + add edx,eax + xor r11d,eax + lea ecx,DWORD PTR[((-1473231341))+r10*1+rcx] + and r11d,edx + xor r11d,ebx + mov r10d,DWORD PTR[28+rsi] + add ecx,r11d + rol ecx,17 + mov r11d,eax + add ecx,edx + xor r11d,edx + lea ebx,DWORD PTR[((-45705983))+r10*1+rbx] + and r11d,ecx + xor r11d,eax + mov r10d,DWORD PTR[32+rsi] + add ebx,r11d + rol ebx,22 + mov r11d,edx + add ebx,ecx + xor r11d,ecx + lea eax,DWORD PTR[1770035416+r10*1+rax] + and r11d,ebx + xor r11d,edx + mov r10d,DWORD PTR[36+rsi] + add eax,r11d + rol eax,7 + mov r11d,ecx + add eax,ebx + xor r11d,ebx + lea edx,DWORD PTR[((-1958414417))+r10*1+rdx] + and r11d,eax + xor r11d,ecx + mov r10d,DWORD PTR[40+rsi] + add edx,r11d + rol edx,12 + mov r11d,ebx + add edx,eax + xor r11d,eax + lea ecx,DWORD PTR[((-42063))+r10*1+rcx] + and r11d,edx + xor r11d,ebx + mov r10d,DWORD PTR[44+rsi] + add ecx,r11d + rol ecx,17 + mov r11d,eax + add ecx,edx + xor r11d,edx + lea ebx,DWORD PTR[((-1990404162))+r10*1+rbx] + and r11d,ecx + xor r11d,eax + mov r10d,DWORD PTR[48+rsi] + add ebx,r11d + rol ebx,22 + mov r11d,edx + add ebx,ecx + xor r11d,ecx + lea eax,DWORD PTR[1804603682+r10*1+rax] + and r11d,ebx + xor r11d,edx + mov r10d,DWORD PTR[52+rsi] + add eax,r11d + rol eax,7 + mov r11d,ecx + add eax,ebx + xor r11d,ebx + lea edx,DWORD PTR[((-40341101))+r10*1+rdx] + and r11d,eax + xor r11d,ecx + mov r10d,DWORD PTR[56+rsi] + add edx,r11d + rol edx,12 + mov r11d,ebx + add edx,eax + xor r11d,eax + lea ecx,DWORD PTR[((-1502002290))+r10*1+rcx] + and r11d,edx + xor r11d,ebx + mov r10d,DWORD PTR[60+rsi] + add ecx,r11d + rol ecx,17 + mov r11d,eax + add ecx,edx + xor r11d,edx + lea ebx,DWORD PTR[1236535329+r10*1+rbx] + and r11d,ecx + xor r11d,eax + mov r10d,DWORD PTR[rsi] + add ebx,r11d + rol ebx,22 + mov r11d,edx + add ebx,ecx + mov r10d,DWORD PTR[4+rsi] + mov r11d,edx + mov r12d,edx + not r11d + lea eax,DWORD PTR[((-165796510))+r10*1+rax] + and r12d,ebx + and r11d,ecx + mov r10d,DWORD PTR[24+rsi] + or r12d,r11d + mov r11d,ecx + add eax,r12d + mov r12d,ecx + rol eax,5 + add eax,ebx + not r11d + lea edx,DWORD PTR[((-1069501632))+r10*1+rdx] + and r12d,eax + and r11d,ebx + mov r10d,DWORD PTR[44+rsi] + or r12d,r11d + mov r11d,ebx + add edx,r12d + mov r12d,ebx + rol edx,9 + add edx,eax + not r11d + lea ecx,DWORD PTR[643717713+r10*1+rcx] + and r12d,edx + and r11d,eax + mov r10d,DWORD PTR[rsi] + or r12d,r11d + mov r11d,eax + add ecx,r12d + mov r12d,eax + rol ecx,14 + add ecx,edx + not r11d + lea ebx,DWORD PTR[((-373897302))+r10*1+rbx] + and r12d,ecx + and r11d,edx + mov r10d,DWORD PTR[20+rsi] + or r12d,r11d + mov r11d,edx + add ebx,r12d + mov r12d,edx + rol ebx,20 + add ebx,ecx + not r11d + lea eax,DWORD PTR[((-701558691))+r10*1+rax] + and r12d,ebx + and r11d,ecx + mov r10d,DWORD PTR[40+rsi] + or r12d,r11d + mov r11d,ecx + add eax,r12d + mov r12d,ecx + rol eax,5 + add eax,ebx + not r11d + lea edx,DWORD PTR[38016083+r10*1+rdx] + and r12d,eax + and r11d,ebx + mov r10d,DWORD PTR[60+rsi] + or r12d,r11d + mov r11d,ebx + add edx,r12d + mov r12d,ebx + rol edx,9 + add edx,eax + not r11d + lea ecx,DWORD PTR[((-660478335))+r10*1+rcx] + and r12d,edx + and r11d,eax + mov r10d,DWORD PTR[16+rsi] + or r12d,r11d + mov r11d,eax + add ecx,r12d + mov r12d,eax + rol ecx,14 + add ecx,edx + not r11d + lea ebx,DWORD PTR[((-405537848))+r10*1+rbx] + and r12d,ecx + and r11d,edx + mov r10d,DWORD PTR[36+rsi] + or r12d,r11d + mov r11d,edx + add ebx,r12d + mov r12d,edx + rol ebx,20 + add ebx,ecx + not r11d + lea eax,DWORD PTR[568446438+r10*1+rax] + and r12d,ebx + and r11d,ecx + mov r10d,DWORD PTR[56+rsi] + or r12d,r11d + mov r11d,ecx + add eax,r12d + mov r12d,ecx + rol eax,5 + add eax,ebx + not r11d + lea edx,DWORD PTR[((-1019803690))+r10*1+rdx] + and r12d,eax + and r11d,ebx + mov r10d,DWORD PTR[12+rsi] + or r12d,r11d + mov r11d,ebx + add edx,r12d + mov r12d,ebx + rol edx,9 + add edx,eax + not r11d + lea ecx,DWORD PTR[((-187363961))+r10*1+rcx] + and r12d,edx + and r11d,eax + mov r10d,DWORD PTR[32+rsi] + or r12d,r11d + mov r11d,eax + add ecx,r12d + mov r12d,eax + rol ecx,14 + add ecx,edx + not r11d + lea ebx,DWORD PTR[1163531501+r10*1+rbx] + and r12d,ecx + and r11d,edx + mov r10d,DWORD PTR[52+rsi] + or r12d,r11d + mov r11d,edx + add ebx,r12d + mov r12d,edx + rol ebx,20 + add ebx,ecx + not r11d + lea eax,DWORD PTR[((-1444681467))+r10*1+rax] + and r12d,ebx + and r11d,ecx + mov r10d,DWORD PTR[8+rsi] + or r12d,r11d + mov r11d,ecx + add eax,r12d + mov r12d,ecx + rol eax,5 + add eax,ebx + not r11d + lea edx,DWORD PTR[((-51403784))+r10*1+rdx] + and r12d,eax + and r11d,ebx + mov r10d,DWORD PTR[28+rsi] + or r12d,r11d + mov r11d,ebx + add edx,r12d + mov r12d,ebx + rol edx,9 + add edx,eax + not r11d + lea ecx,DWORD PTR[1735328473+r10*1+rcx] + and r12d,edx + and r11d,eax + mov r10d,DWORD PTR[48+rsi] + or r12d,r11d + mov r11d,eax + add ecx,r12d + mov r12d,eax + rol ecx,14 + add ecx,edx + not r11d + lea ebx,DWORD PTR[((-1926607734))+r10*1+rbx] + and r12d,ecx + and r11d,edx + mov r10d,DWORD PTR[rsi] + or r12d,r11d + mov r11d,edx + add ebx,r12d + mov r12d,edx + rol ebx,20 + add ebx,ecx + mov r10d,DWORD PTR[20+rsi] + mov r11d,ecx + lea eax,DWORD PTR[((-378558))+r10*1+rax] + mov r10d,DWORD PTR[32+rsi] + xor r11d,edx + xor r11d,ebx + add eax,r11d + rol eax,4 + mov r11d,ebx + add eax,ebx + lea edx,DWORD PTR[((-2022574463))+r10*1+rdx] + mov r10d,DWORD PTR[44+rsi] + xor r11d,ecx + xor r11d,eax + add edx,r11d + rol edx,11 + mov r11d,eax + add edx,eax + lea ecx,DWORD PTR[1839030562+r10*1+rcx] + mov r10d,DWORD PTR[56+rsi] + xor r11d,ebx + xor r11d,edx + add ecx,r11d + rol ecx,16 + mov r11d,edx + add ecx,edx + lea ebx,DWORD PTR[((-35309556))+r10*1+rbx] + mov r10d,DWORD PTR[4+rsi] + xor r11d,eax + xor r11d,ecx + add ebx,r11d + rol ebx,23 + mov r11d,ecx + add ebx,ecx + lea eax,DWORD PTR[((-1530992060))+r10*1+rax] + mov r10d,DWORD PTR[16+rsi] + xor r11d,edx + xor r11d,ebx + add eax,r11d + rol eax,4 + mov r11d,ebx + add eax,ebx + lea edx,DWORD PTR[1272893353+r10*1+rdx] + mov r10d,DWORD PTR[28+rsi] + xor r11d,ecx + xor r11d,eax + add edx,r11d + rol edx,11 + mov r11d,eax + add edx,eax + lea ecx,DWORD PTR[((-155497632))+r10*1+rcx] + mov r10d,DWORD PTR[40+rsi] + xor r11d,ebx + xor r11d,edx + add ecx,r11d + rol ecx,16 + mov r11d,edx + add ecx,edx + lea ebx,DWORD PTR[((-1094730640))+r10*1+rbx] + mov r10d,DWORD PTR[52+rsi] + xor r11d,eax + xor r11d,ecx + add ebx,r11d + rol ebx,23 + mov r11d,ecx + add ebx,ecx + lea eax,DWORD PTR[681279174+r10*1+rax] + mov r10d,DWORD PTR[rsi] + xor r11d,edx + xor r11d,ebx + add eax,r11d + rol eax,4 + mov r11d,ebx + add eax,ebx + lea edx,DWORD PTR[((-358537222))+r10*1+rdx] + mov r10d,DWORD PTR[12+rsi] + xor r11d,ecx + xor r11d,eax + add edx,r11d + rol edx,11 + mov r11d,eax + add edx,eax + lea ecx,DWORD PTR[((-722521979))+r10*1+rcx] + mov r10d,DWORD PTR[24+rsi] + xor r11d,ebx + xor r11d,edx + add ecx,r11d + rol ecx,16 + mov r11d,edx + add ecx,edx + lea ebx,DWORD PTR[76029189+r10*1+rbx] + mov r10d,DWORD PTR[36+rsi] + xor r11d,eax + xor r11d,ecx + add ebx,r11d + rol ebx,23 + mov r11d,ecx + add ebx,ecx + lea eax,DWORD PTR[((-640364487))+r10*1+rax] + mov r10d,DWORD PTR[48+rsi] + xor r11d,edx + xor r11d,ebx + add eax,r11d + rol eax,4 + mov r11d,ebx + add eax,ebx + lea edx,DWORD PTR[((-421815835))+r10*1+rdx] + mov r10d,DWORD PTR[60+rsi] + xor r11d,ecx + xor r11d,eax + add edx,r11d + rol edx,11 + mov r11d,eax + add edx,eax + lea ecx,DWORD PTR[530742520+r10*1+rcx] + mov r10d,DWORD PTR[8+rsi] + xor r11d,ebx + xor r11d,edx + add ecx,r11d + rol ecx,16 + mov r11d,edx + add ecx,edx + lea ebx,DWORD PTR[((-995338651))+r10*1+rbx] + mov r10d,DWORD PTR[rsi] + xor r11d,eax + xor r11d,ecx + add ebx,r11d + rol ebx,23 + mov r11d,ecx + add ebx,ecx + mov r10d,DWORD PTR[rsi] + mov r11d,0ffffffffh + xor r11d,edx + lea eax,DWORD PTR[((-198630844))+r10*1+rax] + or r11d,ebx + xor r11d,ecx + add eax,r11d + mov r10d,DWORD PTR[28+rsi] + mov r11d,0ffffffffh + rol eax,6 + xor r11d,ecx + add eax,ebx + lea edx,DWORD PTR[1126891415+r10*1+rdx] + or r11d,eax + xor r11d,ebx + add edx,r11d + mov r10d,DWORD PTR[56+rsi] + mov r11d,0ffffffffh + rol edx,10 + xor r11d,ebx + add edx,eax + lea ecx,DWORD PTR[((-1416354905))+r10*1+rcx] + or r11d,edx + xor r11d,eax + add ecx,r11d + mov r10d,DWORD PTR[20+rsi] + mov r11d,0ffffffffh + rol ecx,15 + xor r11d,eax + add ecx,edx + lea ebx,DWORD PTR[((-57434055))+r10*1+rbx] + or r11d,ecx + xor r11d,edx + add ebx,r11d + mov r10d,DWORD PTR[48+rsi] + mov r11d,0ffffffffh + rol ebx,21 + xor r11d,edx + add ebx,ecx + lea eax,DWORD PTR[1700485571+r10*1+rax] + or r11d,ebx + xor r11d,ecx + add eax,r11d + mov r10d,DWORD PTR[12+rsi] + mov r11d,0ffffffffh + rol eax,6 + xor r11d,ecx + add eax,ebx + lea edx,DWORD PTR[((-1894986606))+r10*1+rdx] + or r11d,eax + xor r11d,ebx + add edx,r11d + mov r10d,DWORD PTR[40+rsi] + mov r11d,0ffffffffh + rol edx,10 + xor r11d,ebx + add edx,eax + lea ecx,DWORD PTR[((-1051523))+r10*1+rcx] + or r11d,edx + xor r11d,eax + add ecx,r11d + mov r10d,DWORD PTR[4+rsi] + mov r11d,0ffffffffh + rol ecx,15 + xor r11d,eax + add ecx,edx + lea ebx,DWORD PTR[((-2054922799))+r10*1+rbx] + or r11d,ecx + xor r11d,edx + add ebx,r11d + mov r10d,DWORD PTR[32+rsi] + mov r11d,0ffffffffh + rol ebx,21 + xor r11d,edx + add ebx,ecx + lea eax,DWORD PTR[1873313359+r10*1+rax] + or r11d,ebx + xor r11d,ecx + add eax,r11d + mov r10d,DWORD PTR[60+rsi] + mov r11d,0ffffffffh + rol eax,6 + xor r11d,ecx + add eax,ebx + lea edx,DWORD PTR[((-30611744))+r10*1+rdx] + or r11d,eax + xor r11d,ebx + add edx,r11d + mov r10d,DWORD PTR[24+rsi] + mov r11d,0ffffffffh + rol edx,10 + xor r11d,ebx + add edx,eax + lea ecx,DWORD PTR[((-1560198380))+r10*1+rcx] + or r11d,edx + xor r11d,eax + add ecx,r11d + mov r10d,DWORD PTR[52+rsi] + mov r11d,0ffffffffh + rol ecx,15 + xor r11d,eax + add ecx,edx + lea ebx,DWORD PTR[1309151649+r10*1+rbx] + or r11d,ecx + xor r11d,edx + add ebx,r11d + mov r10d,DWORD PTR[16+rsi] + mov r11d,0ffffffffh + rol ebx,21 + xor r11d,edx + add ebx,ecx + lea eax,DWORD PTR[((-145523070))+r10*1+rax] + or r11d,ebx + xor r11d,ecx + add eax,r11d + mov r10d,DWORD PTR[44+rsi] + mov r11d,0ffffffffh + rol eax,6 + xor r11d,ecx + add eax,ebx + lea edx,DWORD PTR[((-1120210379))+r10*1+rdx] + or r11d,eax + xor r11d,ebx + add edx,r11d + mov r10d,DWORD PTR[8+rsi] + mov r11d,0ffffffffh + rol edx,10 + xor r11d,ebx + add edx,eax + lea ecx,DWORD PTR[718787259+r10*1+rcx] + or r11d,edx + xor r11d,eax + add ecx,r11d + mov r10d,DWORD PTR[36+rsi] + mov r11d,0ffffffffh + rol ecx,15 + xor r11d,eax + add ecx,edx + lea ebx,DWORD PTR[((-343485551))+r10*1+rbx] + or r11d,ecx + xor r11d,edx + add ebx,r11d + mov r10d,DWORD PTR[rsi] + mov r11d,0ffffffffh + rol ebx,21 + xor r11d,edx + add ebx,ecx + + add eax,r8d + add ebx,r9d + add ecx,r14d + add edx,r15d + + + add rsi,64 + cmp rsi,rdi + jb $L$loop + + +$L$end:: + mov DWORD PTR[rbp],eax + mov DWORD PTR[4+rbp],ebx + mov DWORD PTR[8+rbp],ecx + mov DWORD PTR[12+rbp],edx + + mov r15,QWORD PTR[rsp] + mov r14,QWORD PTR[8+rsp] + mov r12,QWORD PTR[16+rsp] + mov rbx,QWORD PTR[24+rsp] + mov rbp,QWORD PTR[32+rsp] + add rsp,40 +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_md5_block_asm_data_order:: +md5_block_asm_data_order ENDP + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/md5/md5-mingw64-x86_64.S b/Libraries/libressl/crypto/md5/md5-mingw64-x86_64.S new file mode 100644 index 000000000..5a611f52d --- /dev/null +++ b/Libraries/libressl/crypto/md5/md5-mingw64-x86_64.S @@ -0,0 +1,679 @@ +#include "x86_arch.h" +.text +.p2align 4 + +.globl md5_block_asm_data_order +.def md5_block_asm_data_order; .scl 2; .type 32; .endef +md5_block_asm_data_order: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_md5_block_asm_data_order: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r14 + pushq %r15 +.Lprologue: + + + + + movq %rdi,%rbp + shlq $6,%rdx + leaq (%rsi,%rdx,1),%rdi + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + + + + + + + + cmpq %rdi,%rsi + je .Lend + + +.Lloop: + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r14d + movl %edx,%r15d + movl 0(%rsi),%r10d + movl %edx,%r11d + xorl %ecx,%r11d + leal -680876936(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 4(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -389564586(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 8(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal 606105819(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 12(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1044525330(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 16(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal -176418897(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 20(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal 1200080426(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 24(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1473231341(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 28(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -45705983(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 32(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1770035416(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 36(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -1958414417(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 40(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -42063(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 44(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1990404162(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 48(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1804603682(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 52(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -40341101(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 56(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1502002290(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 60(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal 1236535329(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 0(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + movl 4(%rsi),%r10d + movl %edx,%r11d + movl %edx,%r12d + notl %r11d + leal -165796510(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 24(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1069501632(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 44(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 643717713(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -373897302(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 20(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -701558691(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 40(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal 38016083(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 60(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -660478335(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 16(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -405537848(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 36(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal 568446438(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 56(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1019803690(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 12(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -187363961(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 32(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal 1163531501(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 52(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -1444681467(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 8(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -51403784(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 28(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 1735328473(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 48(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -1926607734(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + movl 20(%rsi),%r10d + movl %ecx,%r11d + leal -378558(%rax,%r10,1),%eax + movl 32(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -2022574463(%rdx,%r10,1),%edx + movl 44(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 1839030562(%rcx,%r10,1),%ecx + movl 56(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -35309556(%rbx,%r10,1),%ebx + movl 4(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -1530992060(%rax,%r10,1),%eax + movl 16(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal 1272893353(%rdx,%r10,1),%edx + movl 28(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -155497632(%rcx,%r10,1),%ecx + movl 40(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -1094730640(%rbx,%r10,1),%ebx + movl 52(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal 681279174(%rax,%r10,1),%eax + movl 0(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -358537222(%rdx,%r10,1),%edx + movl 12(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -722521979(%rcx,%r10,1),%ecx + movl 24(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal 76029189(%rbx,%r10,1),%ebx + movl 36(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -640364487(%rax,%r10,1),%eax + movl 48(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -421815835(%rdx,%r10,1),%edx + movl 60(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 530742520(%rcx,%r10,1),%ecx + movl 8(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -995338651(%rbx,%r10,1),%ebx + movl 0(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + movl 0(%rsi),%r10d + movl $4294967295,%r11d + xorl %edx,%r11d + leal -198630844(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 28(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal 1126891415(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 56(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1416354905(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 20(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -57434055(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 48(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1700485571(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 12(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1894986606(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 40(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1051523(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 4(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -2054922799(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 32(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1873313359(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 60(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -30611744(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 24(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1560198380(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 52(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal 1309151649(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 16(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal -145523070(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 44(%rsi),%r10d + movl $4294967295,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1120210379(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 8(%rsi),%r10d + movl $4294967295,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal 718787259(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 36(%rsi),%r10d + movl $4294967295,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -343485551(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 0(%rsi),%r10d + movl $4294967295,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + + addl %r8d,%eax + addl %r9d,%ebx + addl %r14d,%ecx + addl %r15d,%edx + + + addq $64,%rsi + cmpq %rdi,%rsi + jb .Lloop + + +.Lend: + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + movq (%rsp),%r15 + movq 8(%rsp),%r14 + movq 16(%rsp),%r12 + movq 24(%rsp),%rbx + movq 32(%rsp),%rbp + addq $40,%rsp +.Lepilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_md5_block_asm_data_order: diff --git a/Libraries/libressl/crypto/md5/md5.c b/Libraries/libressl/crypto/md5/md5.c new file mode 100644 index 000000000..c2ee2958d --- /dev/null +++ b/Libraries/libressl/crypto/md5/md5.c @@ -0,0 +1,362 @@ +/* $OpenBSD: md5.c,v 1.18 2023/08/15 08:39:27 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include + +#include "crypto_internal.h" + +/* Ensure that MD5_LONG and uint32_t are equivalent size. */ +CTASSERT(sizeof(MD5_LONG) == sizeof(uint32_t)); + +#ifdef MD5_ASM +void md5_block_asm_data_order(MD5_CTX *c, const void *p, size_t num); +#define md5_block_data_order md5_block_asm_data_order +#endif + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD5_LONG +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK MD5_CBLOCK +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_BLOCK_DATA_ORDER md5_block_data_order + +#define HASH_NO_UPDATE +#define HASH_NO_TRANSFORM +#define HASH_NO_FINAL + +#include "md32_common.h" + +/* +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) +*/ + +/* As pointed out by Wei Dai , the above can be + * simplified to the code below. Wei attributes these optimizations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b,c,d) ((b) ^ (c) ^ (d)) +#define I(b,c,d) (((~(d)) | (b)) ^ (c)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; };\ + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R3(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+I((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +/* Implemented from RFC1321 The MD5 Message-Digest Algorithm. */ + +#ifndef MD5_ASM +static void +md5_block_data_order(MD5_CTX *c, const void *_in, size_t num) +{ + const uint8_t *in = _in; + MD5_LONG A, B, C, D; + MD5_LONG X0, X1, X2, X3, X4, X5, X6, X7, + X8, X9, X10, X11, X12, X13, X14, X15; + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--; ) { + X0 = crypto_load_le32toh(&in[0 * 4]); + X1 = crypto_load_le32toh(&in[1 * 4]); + X2 = crypto_load_le32toh(&in[2 * 4]); + X3 = crypto_load_le32toh(&in[3 * 4]); + X4 = crypto_load_le32toh(&in[4 * 4]); + X5 = crypto_load_le32toh(&in[5 * 4]); + X6 = crypto_load_le32toh(&in[6 * 4]); + X7 = crypto_load_le32toh(&in[7 * 4]); + X8 = crypto_load_le32toh(&in[8 * 4]); + X9 = crypto_load_le32toh(&in[9 * 4]); + X10 = crypto_load_le32toh(&in[10 * 4]); + X11 = crypto_load_le32toh(&in[11 * 4]); + X12 = crypto_load_le32toh(&in[12 * 4]); + X13 = crypto_load_le32toh(&in[13 * 4]); + X14 = crypto_load_le32toh(&in[14 * 4]); + X15 = crypto_load_le32toh(&in[15 * 4]); + in += MD5_CBLOCK; + + /* Round 0 */ + R0(A, B, C, D, X0, 7, 0xd76aa478L); + R0(D, A, B, C, X1, 12, 0xe8c7b756L); + R0(C, D, A, B, X2, 17, 0x242070dbL); + R0(B, C, D, A, X3, 22, 0xc1bdceeeL); + R0(A, B, C, D, X4, 7, 0xf57c0fafL); + R0(D, A, B, C, X5, 12, 0x4787c62aL); + R0(C, D, A, B, X6, 17, 0xa8304613L); + R0(B, C, D, A, X7, 22, 0xfd469501L); + R0(A, B, C, D, X8, 7, 0x698098d8L); + R0(D, A, B, C, X9, 12, 0x8b44f7afL); + R0(C, D, A, B, X10, 17, 0xffff5bb1L); + R0(B, C, D, A, X11, 22, 0x895cd7beL); + R0(A, B, C, D, X12, 7, 0x6b901122L); + R0(D, A, B, C, X13, 12, 0xfd987193L); + R0(C, D, A, B, X14, 17, 0xa679438eL); + R0(B, C, D, A, X15, 22, 0x49b40821L); + /* Round 1 */ + R1(A, B, C, D, X1, 5, 0xf61e2562L); + R1(D, A, B, C, X6, 9, 0xc040b340L); + R1(C, D, A, B, X11, 14, 0x265e5a51L); + R1(B, C, D, A, X0, 20, 0xe9b6c7aaL); + R1(A, B, C, D, X5, 5, 0xd62f105dL); + R1(D, A, B, C, X10, 9, 0x02441453L); + R1(C, D, A, B, X15, 14, 0xd8a1e681L); + R1(B, C, D, A, X4, 20, 0xe7d3fbc8L); + R1(A, B, C, D, X9, 5, 0x21e1cde6L); + R1(D, A, B, C, X14, 9, 0xc33707d6L); + R1(C, D, A, B, X3, 14, 0xf4d50d87L); + R1(B, C, D, A, X8, 20, 0x455a14edL); + R1(A, B, C, D, X13, 5, 0xa9e3e905L); + R1(D, A, B, C, X2, 9, 0xfcefa3f8L); + R1(C, D, A, B, X7, 14, 0x676f02d9L); + R1(B, C, D, A, X12, 20, 0x8d2a4c8aL); + /* Round 2 */ + R2(A, B, C, D, X5, 4, 0xfffa3942L); + R2(D, A, B, C, X8, 11, 0x8771f681L); + R2(C, D, A, B, X11, 16, 0x6d9d6122L); + R2(B, C, D, A, X14, 23, 0xfde5380cL); + R2(A, B, C, D, X1, 4, 0xa4beea44L); + R2(D, A, B, C, X4, 11, 0x4bdecfa9L); + R2(C, D, A, B, X7, 16, 0xf6bb4b60L); + R2(B, C, D, A, X10, 23, 0xbebfbc70L); + R2(A, B, C, D, X13, 4, 0x289b7ec6L); + R2(D, A, B, C, X0, 11, 0xeaa127faL); + R2(C, D, A, B, X3, 16, 0xd4ef3085L); + R2(B, C, D, A, X6, 23, 0x04881d05L); + R2(A, B, C, D, X9, 4, 0xd9d4d039L); + R2(D, A, B, C, X12, 11, 0xe6db99e5L); + R2(C, D, A, B, X15, 16, 0x1fa27cf8L); + R2(B, C, D, A, X2, 23, 0xc4ac5665L); + /* Round 3 */ + R3(A, B, C, D, X0, 6, 0xf4292244L); + R3(D, A, B, C, X7, 10, 0x432aff97L); + R3(C, D, A, B, X14, 15, 0xab9423a7L); + R3(B, C, D, A, X5, 21, 0xfc93a039L); + R3(A, B, C, D, X12, 6, 0x655b59c3L); + R3(D, A, B, C, X3, 10, 0x8f0ccc92L); + R3(C, D, A, B, X10, 15, 0xffeff47dL); + R3(B, C, D, A, X1, 21, 0x85845dd1L); + R3(A, B, C, D, X8, 6, 0x6fa87e4fL); + R3(D, A, B, C, X15, 10, 0xfe2ce6e0L); + R3(C, D, A, B, X6, 15, 0xa3014314L); + R3(B, C, D, A, X13, 21, 0x4e0811a1L); + R3(A, B, C, D, X4, 6, 0xf7537e82L); + R3(D, A, B, C, X11, 10, 0xbd3af235L); + R3(C, D, A, B, X2, 15, 0x2ad7d2bbL); + R3(B, C, D, A, X9, 21, 0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} +#endif + +int +MD5_Init(MD5_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + c->A = 0x67452301UL; + c->B = 0xefcdab89UL; + c->C = 0x98badcfeUL; + c->D = 0x10325476UL; + + return 1; +} +LCRYPTO_ALIAS(MD5_Init); + +int +MD5_Update(MD5_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + MD5_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((MD5_LONG)len) << 3))&0xffffffffUL; + /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to + * Wei Dai for pointing it out. */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh+=(MD5_LONG)(len>>29); /* might cause compiler warning on 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= MD5_CBLOCK || len + n >= MD5_CBLOCK) { + memcpy(p + n, data, MD5_CBLOCK - n); + md5_block_data_order(c, p, 1); + n = MD5_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset(p, 0, MD5_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len/MD5_CBLOCK; + if (n > 0) { + md5_block_data_order(c, data, n); + n *= MD5_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} +LCRYPTO_ALIAS(MD5_Update); + +void +MD5_Transform(MD5_CTX *c, const unsigned char *data) +{ + md5_block_data_order(c, data, 1); +} +LCRYPTO_ALIAS(MD5_Transform); + +int +MD5_Final(unsigned char *md, MD5_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (MD5_CBLOCK - 8)) { + memset(p + n, 0, MD5_CBLOCK - n); + n = 0; + md5_block_data_order(c, p, 1); + } + + memset(p + n, 0, MD5_CBLOCK - 8 - n); + c->data[MD5_LBLOCK - 2] = htole32(c->Nl); + c->data[MD5_LBLOCK - 1] = htole32(c->Nh); + + md5_block_data_order(c, p, 1); + c->num = 0; + memset(p, 0, MD5_CBLOCK); + + crypto_store_htole32(&md[0 * 4], c->A); + crypto_store_htole32(&md[1 * 4], c->B); + crypto_store_htole32(&md[2 * 4], c->C); + crypto_store_htole32(&md[3 * 4], c->D); + + return 1; +} +LCRYPTO_ALIAS(MD5_Final); + +unsigned char * +MD5(const unsigned char *d, size_t n, unsigned char *md) +{ + MD5_CTX c; + static unsigned char m[MD5_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD5_Init(&c)) + return NULL; + MD5_Update(&c, d, n); + MD5_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} +LCRYPTO_ALIAS(MD5); diff --git a/Libraries/libressl/crypto/mem_clr.c b/Libraries/libressl/crypto/mem_clr.c new file mode 100644 index 000000000..9ee5e65a2 --- /dev/null +++ b/Libraries/libressl/crypto/mem_clr.c @@ -0,0 +1,11 @@ +/* $OpenBSD: mem_clr.c,v 1.4 2014/06/12 15:49:27 deraadt Exp $ */ + +/* Ted Unangst places this file in the public domain. */ +#include +#include + +void +OPENSSL_cleanse(void *ptr, size_t len) +{ + explicit_bzero(ptr, len); +} diff --git a/Libraries/libressl/crypto/mem_dbg.c b/Libraries/libressl/crypto/mem_dbg.c new file mode 100644 index 000000000..e2eacebe1 --- /dev/null +++ b/Libraries/libressl/crypto/mem_dbg.c @@ -0,0 +1,209 @@ +/* $OpenBSD: mem_dbg.c,v 1.25 2023/07/08 08:28:23 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include + +int +CRYPTO_mem_ctrl(int mode) +{ + return (CRYPTO_MEM_CHECK_OFF); +} + +int +CRYPTO_is_mem_check_on(void) +{ + return (0); +} + + +void +CRYPTO_dbg_set_options(long bits) +{ + return; +} +LCRYPTO_ALIAS(CRYPTO_dbg_set_options); + +long +CRYPTO_dbg_get_options(void) +{ + return (0); +} +LCRYPTO_ALIAS(CRYPTO_dbg_get_options); + +int +CRYPTO_push_info_(const char *info, const char *file, int line) +{ + return (0); +} +LCRYPTO_ALIAS(CRYPTO_push_info_); + +int +CRYPTO_pop_info(void) +{ + return (0); +} +LCRYPTO_ALIAS(CRYPTO_pop_info); + +int +CRYPTO_remove_all_info(void) +{ + return (0); +} +LCRYPTO_ALIAS(CRYPTO_remove_all_info); + +void +CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, + int before_p) +{ + OPENSSL_assert("CRYPTO_dbg_malloc is no longer permitted"); +} +LCRYPTO_ALIAS(CRYPTO_dbg_malloc); + +void +CRYPTO_dbg_free(void *addr, int before_p) +{ + OPENSSL_assert("CRYPTO_dbg_free is no longer permitted"); +} +LCRYPTO_ALIAS(CRYPTO_dbg_free); + +void +CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, + const char *file, int line, int before_p) +{ + OPENSSL_assert("CRYPTO_dbg_realloc is no longer permitted"); +} +LCRYPTO_ALIAS(CRYPTO_dbg_realloc); + +int +CRYPTO_mem_leaks(BIO *b) +{ + return -1; +} +LCRYPTO_ALIAS(CRYPTO_mem_leaks); + +int +CRYPTO_mem_leaks_fp(FILE *fp) +{ + return -1; +} +LCRYPTO_ALIAS(CRYPTO_mem_leaks_fp); + + +int +CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) +{ + return -1; +} +LCRYPTO_ALIAS(CRYPTO_mem_leaks_cb); diff --git a/Libraries/libressl/crypto/modes/cbc128.c b/Libraries/libressl/crypto/modes/cbc128.c new file mode 100644 index 000000000..f8ebf79a8 --- /dev/null +++ b/Libraries/libressl/crypto/modes/cbc128.c @@ -0,0 +1,214 @@ +/* $OpenBSD: cbc128.c,v 1.8 2023/07/08 14:56:54 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_local.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#undef STRICT_ALIGNMENT +#ifdef __STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 +#else +#define STRICT_ALIGNMENT 0 +#endif + +void +CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + const unsigned char *iv = ivec; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (STRICT_ALIGNMENT && + ((size_t)in|(size_t)out|(size_t)ivec) % sizeof(size_t) != 0) { + while (len >= 16) { + for (n = 0; n < 16; ++n) + out[n] = in[n] ^ iv[n]; + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } else { + while (len >= 16) { + for (n = 0; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(iv + n); + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } +#endif + while (len) { + for (n = 0; n < 16 && n < len; ++n) + out[n] = in[n] ^ iv[n]; + for (; n < 16; ++n) + out[n] = iv[n]; + (*block)(out, out, key); + iv = out; + if (len <= 16) + break; + len -= 16; + in += 16; + out += 16; + } + memmove(ivec, iv, 16); +} +LCRYPTO_ALIAS(CRYPTO_cbc128_encrypt); + +void +CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + union { + size_t t[16/sizeof(size_t)]; + unsigned char c[16]; + } tmp; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (in != out) { + const unsigned char *iv = ivec; + + if (STRICT_ALIGNMENT && + ((size_t)in|(size_t)out|(size_t)ivec) % sizeof(size_t) != + 0) { + while (len >= 16) { + (*block)(in, out, key); + for (n = 0; n < 16; ++n) + out[n] ^= iv[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } else if (16 % sizeof(size_t) == 0) { /* always true */ + while (len >= 16) { + size_t *out_t = (size_t *)out, + *iv_t = (size_t *)iv; + + (*block)(in, out, key); + for (n = 0; n < 16/sizeof(size_t); n++) + out_t[n] ^= iv_t[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + memmove(ivec, iv, 16); + } else { + if (STRICT_ALIGNMENT && + ((size_t)in|(size_t)out|(size_t)ivec) % sizeof(size_t) != + 0) { + unsigned char c; + while (len >= 16) { + (*block)(in, tmp.c, key); + for (n = 0; n < 16; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } else if (16 % sizeof(size_t) == 0) { /* always true */ + while (len >= 16) { + size_t c, *out_t = (size_t *)out, + *ivec_t = (size_t *)ivec; + const size_t *in_t = (const size_t *)in; + + (*block)(in, tmp.c, key); + for (n = 0; n < 16/sizeof(size_t); n++) { + c = in_t[n]; + out_t[n] = tmp.t[n] ^ ivec_t[n]; + ivec_t[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } + } +#endif + while (len) { + unsigned char c; + (*block)(in, tmp.c, key); + for (n = 0; n < 16 && n < len; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + if (len <= 16) { + for (; n < 16; ++n) + ivec[n] = in[n]; + break; + } + len -= 16; + in += 16; + out += 16; + } +} +LCRYPTO_ALIAS(CRYPTO_cbc128_decrypt); diff --git a/Libraries/libressl/crypto/modes/ccm128.c b/Libraries/libressl/crypto/modes/ccm128.c new file mode 100644 index 000000000..68c5cce5d --- /dev/null +++ b/Libraries/libressl/crypto/modes/ccm128.c @@ -0,0 +1,498 @@ +/* $OpenBSD: ccm128.c,v 1.8 2023/07/08 14:56:54 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "modes_local.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +/* First you setup M and L parameters and pass the key schedule. + * This is called once per session setup... */ +void +CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, block128_f block) +{ + memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c)); + ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2)/2) & 7) << 3; + ctx->blocks = 0; + ctx->block = block; + ctx->key = key; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_init); + +/* !!! Following interfaces are to be called *once* per packet !!! */ + +/* Then you setup per-message nonce and pass the length of the message */ +int +CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, + const unsigned char *nonce, size_t nlen, size_t mlen) +{ + unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */ + + if (nlen < (14 - L)) + return -1; /* nonce is too short */ + + if (sizeof(mlen) == 8 && L >= 3) { + ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen)*8))); + ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen)*8))); + ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen)*8))); + ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen)*8))); + } else + ctx->nonce.u[1] = 0; + + ctx->nonce.c[12] = (u8)(mlen >> 24); + ctx->nonce.c[13] = (u8)(mlen >> 16); + ctx->nonce.c[14] = (u8)(mlen >> 8); + ctx->nonce.c[15] = (u8)mlen; + + ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ + memcpy(&ctx->nonce.c[1], nonce, 14 - L); + + return 0; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_setiv); + +/* Then you pass additional authentication data, this is optional */ +void +CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, + const unsigned char *aad, size_t alen) +{ + unsigned int i; + block128_f block = ctx->block; + + if (alen == 0) + return; + + ctx->nonce.c[0] |= 0x40; /* set Adata flag */ + (*block)(ctx->nonce.c, ctx->cmac.c, ctx->key), + ctx->blocks++; + + if (alen < (0x10000 - 0x100)) { + ctx->cmac.c[0] ^= (u8)(alen >> 8); + ctx->cmac.c[1] ^= (u8)alen; + i = 2; + } else if (sizeof(alen) == 8 && + alen >= (size_t)1 << (32 % (sizeof(alen)*8))) { + ctx->cmac.c[0] ^= 0xFF; + ctx->cmac.c[1] ^= 0xFF; + ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen)*8))); + ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen)*8))); + ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen)*8))); + ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen)*8))); + ctx->cmac.c[6] ^= (u8)(alen >> 24); + ctx->cmac.c[7] ^= (u8)(alen >> 16); + ctx->cmac.c[8] ^= (u8)(alen >> 8); + ctx->cmac.c[9] ^= (u8)alen; + i = 10; + } else { + ctx->cmac.c[0] ^= 0xFF; + ctx->cmac.c[1] ^= 0xFE; + ctx->cmac.c[2] ^= (u8)(alen >> 24); + ctx->cmac.c[3] ^= (u8)(alen >> 16); + ctx->cmac.c[4] ^= (u8)(alen >> 8); + ctx->cmac.c[5] ^= (u8)alen; + i = 6; + } + + do { + for (; i < 16 && alen; ++i, ++aad, --alen) + ctx->cmac.c[i] ^= *aad; + (*block)(ctx->cmac.c, ctx->cmac.c, ctx->key), + ctx->blocks++; + i = 0; + } while (alen); +} +LCRYPTO_ALIAS(CRYPTO_ccm128_aad); + +/* Finally you encrypt or decrypt the message */ + +/* counter part of nonce may not be larger than L*8 bits, + * L is not larger than 8, therefore 64-bit counter... */ +static void +ctr64_inc(unsigned char *counter) +{ + unsigned int n = 8; + u8 c; + + counter += 8; + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +int +CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block)(ctx->nonce.c, ctx->cmac.c, key), + ctx->blocks++; + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; /* length mismatch */ + + ctx->blocks += ((len + 15) >> 3)|1; + if (ctx->blocks > (U64(1) << 61)) + return -2; /* too much data */ + + while (len >= 16) { +#ifdef __STRICT_ALIGNMENT + union { + u64 u[2]; + u8 c[16]; + } temp; + + memcpy(temp.c, inp, 16); + ctx->cmac.u[0] ^= temp.u[0]; + ctx->cmac.u[1] ^= temp.u[1]; +#else + ctx->cmac.u[0] ^= ((u64 *)inp)[0]; + ctx->cmac.u[1] ^= ((u64 *)inp)[1]; +#endif + (*block)(ctx->cmac.c, ctx->cmac.c, key); + (*block)(ctx->nonce.c, scratch.c, key); + ctr64_inc(ctx->nonce.c); +#ifdef __STRICT_ALIGNMENT + temp.u[0] ^= scratch.u[0]; + temp.u[1] ^= scratch.u[1]; + memcpy(out, temp.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; + ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; +#endif + inp += 16; + out += 16; + len -= 16; + } + + if (len) { + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= inp[i]; + (*block)(ctx->cmac.c, ctx->cmac.c, key); + (*block)(ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + out[i] = scratch.c[i] ^ inp[i]; + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block)(ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_encrypt); + +int +CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block)(ctx->nonce.c, ctx->cmac.c, key); + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; + + while (len >= 16) { +#ifdef __STRICT_ALIGNMENT + union { + u64 u[2]; + u8 c[16]; + } temp; +#endif + (*block)(ctx->nonce.c, scratch.c, key); + ctr64_inc(ctx->nonce.c); +#ifdef __STRICT_ALIGNMENT + memcpy(temp.c, inp, 16); + ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); + ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); + memcpy(out, scratch.c, 16); +#else + ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ + ((u64 *)inp)[0]); + ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ + ((u64 *)inp)[1]); +#endif + (*block)(ctx->cmac.c, ctx->cmac.c, key); + + inp += 16; + out += 16; + len -= 16; + } + + if (len) { + (*block)(ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); + (*block)(ctx->cmac.c, ctx->cmac.c, key); + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block)(ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_decrypt); + +static void +ctr64_add(unsigned char *counter, size_t inc) +{ + size_t n = 8, val = 0; + + counter += 8; + do { + --n; + val += counter[n] + (inc & 0xff); + counter[n] = (unsigned char)val; + val >>= 8; /* carry bit */ + inc >>= 8; + } while (n && (inc || val)); +} + +int +CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, ccm128_f stream) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block)(ctx->nonce.c, ctx->cmac.c, key), + ctx->blocks++; + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; /* length mismatch */ + + ctx->blocks += ((len + 15) >> 3)|1; + if (ctx->blocks > (U64(1) << 61)) + return -2; /* too much data */ + + if ((n = len/16)) { + (*stream)(inp, out, n, key, ctx->nonce.c, ctx->cmac.c); + n *= 16; + inp += n; + out += n; + len -= n; + if (len) + ctr64_add(ctx->nonce.c, n/16); + } + + if (len) { + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= inp[i]; + (*block)(ctx->cmac.c, ctx->cmac.c, key); + (*block)(ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + out[i] = scratch.c[i] ^ inp[i]; + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block)(ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_encrypt_ccm64); + +int +CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, ccm128_f stream) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block)(ctx->nonce.c, ctx->cmac.c, key); + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; + + if ((n = len/16)) { + (*stream)(inp, out, n, key, ctx->nonce.c, ctx->cmac.c); + n *= 16; + inp += n; + out += n; + len -= n; + if (len) + ctr64_add(ctx->nonce.c, n/16); + } + + if (len) { + (*block)(ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); + (*block)(ctx->cmac.c, ctx->cmac.c, key); + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block)(ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_decrypt_ccm64); + +size_t +CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */ + + M *= 2; + M += 2; + if (len != M) + return 0; + memcpy(tag, ctx->cmac.c, M); + return M; +} +LCRYPTO_ALIAS(CRYPTO_ccm128_tag); diff --git a/Libraries/libressl/crypto/modes/cfb128.c b/Libraries/libressl/crypto/modes/cfb128.c new file mode 100644 index 000000000..931353a62 --- /dev/null +++ b/Libraries/libressl/crypto/modes/cfb128.c @@ -0,0 +1,251 @@ +/* $OpenBSD: cfb128.c,v 1.7 2023/07/08 14:56:54 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_local.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +/* The input and output encrypted as though 128bit cfb mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num; + */ +void +CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + unsigned int n; + size_t l = 0; + + n = *num; + + if (enc) { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) + do { /* always true actually */ + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 16; + } +#ifdef __STRICT_ALIGNMENT + if (((size_t)in|(size_t)out|(size_t)ivec) % + sizeof(size_t) != 0) + break; +#endif + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + *(size_t *)(out + n) = + *(size_t *)(ivec + n) ^= *(size_t *)(in + + n); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + out[n] = ivec[n] ^= in[n]; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block)(ivec, ivec, key); + } + out[l] = ivec[n] ^= in[l]; + ++l; + n = (n + 1) % 16; + } + *num = n; + } else { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) + do { /* always true actually */ + while (n && len) { + unsigned char c; + *(out++) = ivec[n] ^ (c = *(in++)); + ivec[n] = c; + --len; + n = (n + 1) % 16; + } +#ifdef __STRICT_ALIGNMENT + if (((size_t)in|(size_t)out|(size_t)ivec) % + sizeof(size_t) != 0) + break; +#endif + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t t = *(size_t *)(in + n); + *(size_t *)(out + n) = *(size_t *)(ivec + + n) ^ t; + *(size_t *)(ivec + n) = t; + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + unsigned char c; + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + unsigned char c; + if (n == 0) { + (*block)(ivec, ivec, key); + } + out[l] = ivec[n] ^ (c = in[l]); + ivec[n] = c; + ++l; + n = (n + 1) % 16; + } + *num = n; + } +} +LCRYPTO_ALIAS(CRYPTO_cfb128_encrypt); + +/* This expects a single block of size nbits for both in and out. Note that + it corrupts any extra bits in the last byte of out */ +static void +cfbr_encrypt_block(const unsigned char *in, unsigned char *out, + int nbits, const void *key, + unsigned char ivec[16], int enc, + block128_f block) +{ + int n, rem, num; + unsigned char ovec[16*2 + 1]; /* +1 because we dererefence (but don't use) one byte off the end */ + + if (nbits <= 0 || nbits > 128) + return; + + /* fill in the first half of the new IV with the current IV */ + memcpy(ovec, ivec, 16); + /* construct the new IV */ + (*block)(ivec, ivec, key); + num = (nbits + 7)/8; + if (enc) /* encrypt the input */ + for (n = 0; n < num; ++n) + out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); + else /* decrypt the input */ + for (n = 0; n < num; ++n) + out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; + /* shift ovec left... */ + rem = nbits % 8; + num = nbits/8; + if (rem == 0) + memcpy(ivec, ovec + num, 16); + else + for (n = 0; n < 16; ++n) + ivec[n] = ovec[n + num] << rem | + ovec[n + num + 1] >> (8 - rem); + + /* it is not necessary to cleanse ovec, since the IV is not secret */ +} + +/* N.B. This expects the input to be packed, MS bit first */ +void +CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + unsigned char c[1], d[1]; + + for (n = 0; n < bits; ++n) + { + c[0] = (in[n/8] & (1 << (7 - n % 8))) ? 0x80 : 0; + cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); + out[n/8] = (out[n/8] & ~(1 << (unsigned int)(7 - n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } +} +LCRYPTO_ALIAS(CRYPTO_cfb128_1_encrypt); + +void +CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + + for (n = 0; n < length; ++n) + cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); +} +LCRYPTO_ALIAS(CRYPTO_cfb128_8_encrypt); diff --git a/Libraries/libressl/crypto/modes/ctr128.c b/Libraries/libressl/crypto/modes/ctr128.c new file mode 100644 index 000000000..6d507dfc3 --- /dev/null +++ b/Libraries/libressl/crypto/modes/ctr128.c @@ -0,0 +1,267 @@ +/* $OpenBSD: ctr128.c,v 1.11 2023/07/08 14:56:54 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_local.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* NOTE: the IV/counter CTR mode is big-endian. The code itself + * is endian-neutral. */ + +/* increment counter (128-bit int) by 1 */ +static void +ctr128_inc(unsigned char *counter) +{ + u32 n = 16; + u8 c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +#if !defined(OPENSSL_SMALL_FOOTPRINT) +static void +ctr128_inc_aligned(unsigned char *counter) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + ctr128_inc(counter); +#else + size_t *data, c, n; + data = (size_t *)counter; + n = 16 / sizeof(size_t); + do { + --n; + c = data[n]; + ++c; + data[n] = c; + if (c) + return; + } while (n); +#endif +} +#endif + +/* The input encrypted as though 128bit counter mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num, and the + * encrypted counter is kept in ecount_buf. Both *num and + * ecount_buf must be initialised with zeros before the first + * call to CRYPTO_ctr128_encrypt(). + * + * This algorithm assumes that the counter is in the x lower bits + * of the IV (ivec), and that the application has full control over + * overflow and the rest of the IV. This implementation takes NO + * responsibility for checking that the counter doesn't overflow + * into the rest of the IV when incremented. + */ +void +CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(*num < 16); + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) + do { /* always true actually */ + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + +#ifdef __STRICT_ALIGNMENT + if (((size_t)in|(size_t)out|(size_t)ivec) % + sizeof(size_t) != 0) + break; +#endif + while (len >= 16) { + (*block)(ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + for (; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + + n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + } + out[l] = in[l] ^ ecount_buf[n]; + ++l; + n = (n + 1) % 16; + } + + *num = n; +} +LCRYPTO_ALIAS(CRYPTO_ctr128_encrypt); + +/* increment upper 96 bits of 128-bit counter by 1 */ +static void +ctr96_inc(unsigned char *counter) +{ + u32 n = 12; + u8 c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +void +CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, ctr128_f func) +{ + unsigned int n, ctr32; + + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + + ctr32 = GETU32(ivec + 12); + while (len >= 16) { + size_t blocks = len/16; + /* + * 1<<28 is just a not-so-small yet not-so-large number... + * Below condition is practically never met, but it has to + * be checked for code correctness. + */ + if (sizeof(size_t) > sizeof(unsigned int) && + blocks > (1U << 28)) + blocks = (1U << 28); + /* + * As (*func) operates on 32-bit counter, caller + * has to handle overflow. 'if' below detects the + * overflow, which is then handled by limiting the + * amount of blocks to the exact overflow point... + */ + ctr32 += (u32)blocks; + if (ctr32 < blocks) { + blocks -= ctr32; + ctr32 = 0; + } + (*func)(in, out, blocks, key, ivec); + /* (*ctr) does not update ivec, caller does: */ + PUTU32(ivec + 12, ctr32); + /* ... overflow was detected, propagate carry. */ + if (ctr32 == 0) + ctr96_inc(ivec); + blocks *= 16; + len -= blocks; + out += blocks; + in += blocks; + } + if (len) { + memset(ecount_buf, 0, 16); + (*func)(ecount_buf, ecount_buf, 1, key, ivec); + ++ctr32; + PUTU32(ivec + 12, ctr32); + if (ctr32 == 0) + ctr96_inc(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + + *num = n; +} +LCRYPTO_ALIAS(CRYPTO_ctr128_encrypt_ctr32); diff --git a/Libraries/libressl/crypto/modes/gcm128.c b/Libraries/libressl/crypto/modes/gcm128.c new file mode 100644 index 000000000..cbda8ad09 --- /dev/null +++ b/Libraries/libressl/crypto/modes/gcm128.c @@ -0,0 +1,1355 @@ +/* $OpenBSD: gcm128.c,v 1.26 2023/08/10 07:18:43 jsing Exp $ */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include +#include "modes_local.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#if defined(BSWAP4) && defined(__STRICT_ALIGNMENT) +/* redefine, because alignment is ensured */ +#undef GETU32 +#define GETU32(p) BSWAP4(*(const u32 *)(p)) +#endif + +#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16)) +#define REDUCE1BIT(V) \ + do { \ + if (sizeof(size_t)==8) { \ + u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \ + V.lo = (V.hi<<63)|(V.lo>>1); \ + V.hi = (V.hi>>1 )^T; \ + } else { \ + u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \ + V.lo = (V.hi<<63)|(V.lo>>1); \ + V.hi = (V.hi>>1 )^((u64)T<<32); \ + } \ + } while(0) + +/* + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8. 8 is effectively reserved for testing purposes. + * TABLE_BITS>1 are lookup-table-driven implementations referred to as + * "Shoup's" in GCM specification. In other words OpenSSL does not cover + * whole spectrum of possible table driven implementations. Why? In + * non-"Shoup's" case memory access pattern is segmented in such manner, + * that it's trivial to see that cache timing information can reveal + * fair portion of intermediate hash value. Given that ciphertext is + * always available to attacker, it's possible for him to attempt to + * deduce secret parameter H and if successful, tamper with messages + * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's + * not as trivial, but there is no reason to believe that it's resistant + * to cache-timing attack. And the thing about "8-bit" implementation is + * that it consumes 16 (sixteen) times more memory, 4KB per individual + * key + 1KB shared. Well, on pros side it should be twice as fast as + * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version + * was observed to run ~75% faster, closer to 100% for commercial + * compilers... Yet "4-bit" procedure is preferred, because it's + * believed to provide better security-performance balance and adequate + * all-round performance. "All-round" refers to things like: + * + * - shorter setup time effectively improves overall timing for + * handling short messages; + * - larger table allocation can become unbearable because of VM + * subsystem penalties (for example on Windows large enough free + * results in VM working set trimming, meaning that consequent + * malloc would immediately incur working set expansion); + * - larger table has larger cache footprint, which can affect + * performance of other code paths (not necessarily even from same + * thread in Hyper-Threading world); + * + * Value of 1 is not appropriate for performance reasons. + */ +#if TABLE_BITS==8 + +static void +gcm_init_8bit(u128 Htable[256], u64 H[2]) +{ + int i, j; + u128 V; + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + + for (Htable[128] = V, i = 64; i > 0; i >>= 1) { + REDUCE1BIT(V); + Htable[i] = V; + } + + for (i = 2; i < 256; i <<= 1) { + u128 *Hi = Htable + i, H0 = *Hi; + for (j = 1; j < i; ++j) { + Hi[j].hi = H0.hi ^ Htable[j].hi; + Hi[j].lo = H0.lo ^ Htable[j].lo; + } + } +} + +static void +gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) +{ + u128 Z = { 0, 0}; + const u8 *xi = (const u8 *)Xi + 15; + size_t rem, n = *xi; + static const size_t rem_8bit[256] = { + PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), + PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), + PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56), + PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E), + PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66), + PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E), + PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076), + PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E), + PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06), + PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E), + PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416), + PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E), + PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626), + PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E), + PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836), + PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E), + PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6), + PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE), + PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6), + PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE), + PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6), + PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE), + PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6), + PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE), + PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86), + PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E), + PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496), + PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E), + PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6), + PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE), + PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6), + PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE), + PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346), + PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E), + PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56), + PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E), + PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66), + PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E), + PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176), + PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E), + PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06), + PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E), + PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516), + PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E), + PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726), + PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E), + PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936), + PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E), + PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6), + PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE), + PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6), + PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE), + PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6), + PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE), + PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6), + PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE), + PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86), + PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E), + PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596), + PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E), + PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6), + PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE), + PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6), + PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) }; + + while (1) { + Z.hi ^= Htable[n].hi; + Z.lo ^= Htable[n].lo; + + if ((u8 *)Xi == xi) + break; + + n = *(--xi); + + rem = (size_t)Z.lo & 0xff; + Z.lo = (Z.hi << 56)|(Z.lo >> 8); + Z.hi = (Z.hi >> 8); +#if SIZE_MAX == 0xffffffffffffffff + Z.hi ^= rem_8bit[rem]; +#else + Z.hi ^= (u64)rem_8bit[rem] << 32; +#endif + } + + Xi[0] = htobe64(Z.hi); + Xi[1] = htobe64(Z.lo); +} +#define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) + +#elif TABLE_BITS==4 + +static void +gcm_init_4bit(u128 Htable[16], u64 H[2]) +{ + u128 V; +#if defined(OPENSSL_SMALL_FOOTPRINT) + int i; +#endif + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + +#if defined(OPENSSL_SMALL_FOOTPRINT) + for (Htable[8] = V, i = 4; i > 0; i >>= 1) { + REDUCE1BIT(V); + Htable[i] = V; + } + + for (i = 2; i < 16; i <<= 1) { + u128 *Hi = Htable + i; + int j; + for (V = *Hi, j = 1; j < i; ++j) { + Hi[j].hi = V.hi ^ Htable[j].hi; + Hi[j].lo = V.lo ^ Htable[j].lo; + } + } +#else + Htable[8] = V; + REDUCE1BIT(V); + Htable[4] = V; + REDUCE1BIT(V); + Htable[2] = V; + REDUCE1BIT(V); + Htable[1] = V; + Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo; + V = Htable[4]; + Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo; + Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo; + Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo; + V = Htable[8]; + Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo; + Htable[10].hi = V.hi ^ Htable[2].hi, + Htable[10].lo = V.lo ^ Htable[2].lo; + Htable[11].hi = V.hi ^ Htable[3].hi, + Htable[11].lo = V.lo ^ Htable[3].lo; + Htable[12].hi = V.hi ^ Htable[4].hi, + Htable[12].lo = V.lo ^ Htable[4].lo; + Htable[13].hi = V.hi ^ Htable[5].hi, + Htable[13].lo = V.lo ^ Htable[5].lo; + Htable[14].hi = V.hi ^ Htable[6].hi, + Htable[14].lo = V.lo ^ Htable[6].lo; + Htable[15].hi = V.hi ^ Htable[7].hi, + Htable[15].lo = V.lo ^ Htable[7].lo; +#endif +#if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm)) + /* + * ARM assembler expects specific dword order in Htable. + */ + { + int j; +#if BYTE_ORDER == LITTLE_ENDIAN + for (j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo; + Htable[j].lo = V.hi; + } +#else /* BIG_ENDIAN */ + for (j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo << 32|V.lo >> 32; + Htable[j].lo = V.hi << 32|V.hi >> 32; + } +#endif + } +#endif +} + +#ifndef GHASH_ASM +static const size_t rem_4bit[16] = { + PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460), + PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0), + PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560), + PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) }; + +static void +gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) +{ + u128 Z; + int cnt = 15; + size_t rem, nlo, nhi; + + nlo = ((const u8 *)Xi)[15]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi = Htable[nlo].hi; + Z.lo = Htable[nlo].lo; + + while (1) { + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60)|(Z.lo >> 4); + Z.hi = (Z.hi >> 4); +#if SIZE_MAX == 0xffffffffffffffff + Z.hi ^= rem_4bit[rem]; +#else + Z.hi ^= (u64)rem_4bit[rem] << 32; +#endif + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) + break; + + nlo = ((const u8 *)Xi)[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60)|(Z.lo >> 4); + Z.hi = (Z.hi >> 4); +#if SIZE_MAX == 0xffffffffffffffff + Z.hi ^= rem_4bit[rem]; +#else + Z.hi ^= (u64)rem_4bit[rem] << 32; +#endif + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + Xi[0] = htobe64(Z.hi); + Xi[1] = htobe64(Z.lo); +} + +#if !defined(OPENSSL_SMALL_FOOTPRINT) +/* + * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for + * details... Compiler-generated code doesn't seem to give any + * performance improvement, at least not on x86[_64]. It's here + * mostly as reference and a placeholder for possible future + * non-trivial optimization[s]... + */ +static void +gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) +{ + u128 Z; + int cnt; + size_t rem, nlo, nhi; + +#if 1 + do { + cnt = 15; + nlo = ((const u8 *)Xi)[15]; + nlo ^= inp[15]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi = Htable[nlo].hi; + Z.lo = Htable[nlo].lo; + + while (1) { + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60)|(Z.lo >> 4); + Z.hi = (Z.hi >> 4); +#if SIZE_MAX == 0xffffffffffffffff + Z.hi ^= rem_4bit[rem]; +#else + Z.hi ^= (u64)rem_4bit[rem] << 32; +#endif + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) + break; + + nlo = ((const u8 *)Xi)[cnt]; + nlo ^= inp[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60)|(Z.lo >> 4); + Z.hi = (Z.hi >> 4); +#if SIZE_MAX == 0xffffffffffffffff + Z.hi ^= rem_4bit[rem]; +#else + Z.hi ^= (u64)rem_4bit[rem] << 32; +#endif + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } +#else + /* + * Extra 256+16 bytes per-key plus 512 bytes shared tables + * [should] give ~50% improvement... One could have PACK()-ed + * the rem_8bit even here, but the priority is to minimize + * cache footprint... + */ + u128 Hshr4[16]; /* Htable shifted right by 4 bits */ + u8 Hshl4[16]; /* Htable shifted left by 4 bits */ + static const unsigned short rem_8bit[256] = { + 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E, + 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E, + 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E, + 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E, + 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E, + 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E, + 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E, + 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E, + 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE, + 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE, + 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE, + 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE, + 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E, + 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E, + 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE, + 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE, + 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E, + 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E, + 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E, + 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E, + 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E, + 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E, + 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E, + 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E, + 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE, + 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE, + 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE, + 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE, + 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E, + 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E, + 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE, + 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE }; + /* + * This pre-processing phase slows down procedure by approximately + * same time as it makes each loop spin faster. In other words + * single block performance is approximately same as straightforward + * "4-bit" implementation, and then it goes only faster... + */ + for (cnt = 0; cnt < 16; ++cnt) { + Z.hi = Htable[cnt].hi; + Z.lo = Htable[cnt].lo; + Hshr4[cnt].lo = (Z.hi << 60)|(Z.lo >> 4); + Hshr4[cnt].hi = (Z.hi >> 4); + Hshl4[cnt] = (u8)(Z.lo << 4); + } + + do { + for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) { + nlo = ((const u8 *)Xi)[cnt]; + nlo ^= inp[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + + rem = (size_t)Z.lo & 0xff; + + Z.lo = (Z.hi << 56)|(Z.lo >> 8); + Z.hi = (Z.hi >> 8); + + Z.hi ^= Hshr4[nhi].hi; + Z.lo ^= Hshr4[nhi].lo; + Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48; + } + + nlo = ((const u8 *)Xi)[0]; + nlo ^= inp[0]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + + rem = (size_t)Z.lo & 0xf; + + Z.lo = (Z.hi << 60)|(Z.lo >> 4); + Z.hi = (Z.hi >> 4); + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48; +#endif + + Xi[0] = htobe64(Z.hi); + Xi[1] = htobe64(Z.lo); + } while (inp += 16, len -= 16); +} +#endif +#else +void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +#endif + +#define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) +#if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT) +#define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len) +/* GHASH_CHUNK is "stride parameter" missioned to mitigate cache + * trashing effect. In other words idea is to hash data while it's + * still in L1 cache after encryption pass... */ +#define GHASH_CHUNK (3*1024) +#endif + +#else /* TABLE_BITS */ + +static void +gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) +{ + u128 V, Z = { 0,0 }; + long X; + int i, j; + const long *xi = (const long *)Xi; + + V.hi = H[0]; /* H is in host byte order, no byte swapping */ + V.lo = H[1]; + + for (j = 0; j < 16/sizeof(long); ++j) { +#if BYTE_ORDER == LITTLE_ENDIAN +#if SIZE_MAX == 0xffffffffffffffff +#ifdef BSWAP8 + X = (long)(BSWAP8(xi[j])); +#else + const u8 *p = (const u8 *)(xi + j); + X = (long)((u64)GETU32(p) << 32|GETU32(p + 4)); +#endif +#else + const u8 *p = (const u8 *)(xi + j); + X = (long)GETU32(p); +#endif +#else /* BIG_ENDIAN */ + X = xi[j]; +#endif + + for (i = 0; i < 8*sizeof(long); ++i, X <<= 1) { + u64 M = (u64)(X >> (8*sizeof(long) - 1)); + Z.hi ^= V.hi & M; + Z.lo ^= V.lo & M; + + REDUCE1BIT(V); + } + } + + Xi[0] = htobe64(Z.hi); + Xi[1] = htobe64(Z.lo); +} +#define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) + +#endif + +#if defined(GHASH_ASM) && \ + (defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +#include "x86_arch.h" +#endif + +#if TABLE_BITS==4 && defined(GHASH_ASM) +# if (defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define GHASH_ASM_X86_OR_64 +# define GCM_FUNCREF_4BIT + +void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define GHASH_ASM_X86 +void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); + +void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +# elif defined(__arm__) || defined(__arm) +# include "arm_arch.h" +# if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) +# define GHASH_ASM_ARM +# define GCM_FUNCREF_4BIT +void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +# endif +#endif + +#ifdef GCM_FUNCREF_4BIT +# undef GCM_MUL +# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) +# ifdef GHASH +# undef GHASH +# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len) +# endif +#endif + +void +CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->block = block; + ctx->key = key; + + (*block)(ctx->H.c, ctx->H.c, key); + + /* H is stored in host byte order */ + ctx->H.u[0] = be64toh(ctx->H.u[0]); + ctx->H.u[1] = be64toh(ctx->H.u[1]); + +#if TABLE_BITS==8 + gcm_init_8bit(ctx->Htable, ctx->H.u); +#elif TABLE_BITS==4 +# if defined(GHASH_ASM_X86_OR_64) +# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2) + /* check FXSR and PCLMULQDQ bits */ + if ((OPENSSL_cpu_caps() & (CPUCAP_MASK_FXSR | CPUCAP_MASK_PCLMUL)) == + (CPUCAP_MASK_FXSR | CPUCAP_MASK_PCLMUL)) { + gcm_init_clmul(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_clmul; + ctx->ghash = gcm_ghash_clmul; + return; + } +# endif + gcm_init_4bit(ctx->Htable, ctx->H.u); +# if defined(GHASH_ASM_X86) /* x86 only */ +# if defined(OPENSSL_IA32_SSE2) + if (OPENSSL_cpu_caps() & CPUCAP_MASK_SSE) { /* check SSE bit */ +# else + if (OPENSSL_cpu_caps() & CPUCAP_MASK_MMX) { /* check MMX bit */ +# endif + ctx->gmult = gcm_gmult_4bit_mmx; + ctx->ghash = gcm_ghash_4bit_mmx; + } else { + ctx->gmult = gcm_gmult_4bit_x86; + ctx->ghash = gcm_ghash_4bit_x86; + } +# else + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; +# endif +# elif defined(GHASH_ASM_ARM) + if (OPENSSL_armcap_P & ARMV7_NEON) { + ctx->gmult = gcm_gmult_neon; + ctx->ghash = gcm_ghash_neon; + } else { + gcm_init_4bit(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; + } +# else + gcm_init_4bit(ctx->Htable, ctx->H.u); +# endif +#endif +} +LCRYPTO_ALIAS(CRYPTO_gcm128_init); + +void +CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, size_t len) +{ + unsigned int ctr; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + ctx->Yi.u[0] = 0; + ctx->Yi.u[1] = 0; + ctx->Xi.u[0] = 0; + ctx->Xi.u[1] = 0; + ctx->len.u[0] = 0; /* AAD length */ + ctx->len.u[1] = 0; /* message length */ + ctx->ares = 0; + ctx->mres = 0; + + if (len == 12) { + memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[15] = 1; + ctr = 1; + } else { + size_t i; + u64 len0 = len; + + while (len >= 16) { + for (i = 0; i < 16; ++i) + ctx->Yi.c[i] ^= iv[i]; + GCM_MUL(ctx, Yi); + iv += 16; + len -= 16; + } + if (len) { + for (i = 0; i < len; ++i) + ctx->Yi.c[i] ^= iv[i]; + GCM_MUL(ctx, Yi); + } + len0 <<= 3; + ctx->Yi.u[1] ^= htobe64(len0); + + GCM_MUL(ctx, Yi); + + ctr = be32toh(ctx->Yi.d[3]); + } + + (*ctx->block)(ctx->Yi.c, ctx->EK0.c, ctx->key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); +} +LCRYPTO_ALIAS(CRYPTO_gcm128_setiv); + +int +CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, size_t len) +{ + size_t i; + unsigned int n; + u64 alen = ctx->len.u[0]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p)(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + if (ctx->len.u[1]) + return -2; + + alen += len; + if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) + return -1; + ctx->len.u[0] = alen; + + n = ctx->ares; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(aad++); + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->ares = n; + return 0; + } + } + +#ifdef GHASH + if ((i = (len & (size_t)-16))) { + GHASH(ctx, aad, i); + aad += i; + len -= i; + } +#else + while (len >= 16) { + for (i = 0; i < 16; ++i) + ctx->Xi.c[i] ^= aad[i]; + GCM_MUL(ctx, Xi); + aad += 16; + len -= 16; + } +#endif + if (len) { + n = (unsigned int)len; + for (i = 0; i < len; ++i) + ctx->Xi.c[i] ^= aad[i]; + } + + ctx->ares = n; + return 0; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_aad); + +int +CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + block128_f block = ctx->block; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p)(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to encrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = be32toh(ctx->Yi.d[3]); + + n = ctx->mres; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) + do { /* always true actually */ + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ + ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#ifdef __STRICT_ALIGNMENT + if (((size_t)in|(size_t)out) % sizeof(size_t) != 0) + break; +#endif +#if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + while (j) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + for (i = 0; i < 16/sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ + ctx->EKi.t[i]; + out += 16; + in += 16; + j -= 16; + } + GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); + len -= GHASH_CHUNK; + } + if ((i = (len & (size_t)-16))) { + size_t j = i; + + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + for (i = 0; i < 16/sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ + ctx->EKi.t[i]; + out += 16; + in += 16; + len -= 16; + } + GHASH(ctx, out - j, j); + } +#else + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + for (i = 0; i < 16/sizeof(size_t); ++i) + ctx->Xi.t[i] ^= + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +#endif + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ + ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; + } while (0); +#endif + for (i = 0; i < len; ++i) { + if (n == 0) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + } + ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; + n = (n + 1) % 16; + if (n == 0) + GCM_MUL(ctx, Xi); + } + + ctx->mres = n; + return 0; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_encrypt); + +int +CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + block128_f block = ctx->block; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p)(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to decrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = be32toh(ctx->Yi.d[3]); + + n = ctx->mres; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) + do { /* always true actually */ + if (n) { + while (n && len) { + u8 c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#ifdef __STRICT_ALIGNMENT + if (((size_t)in|(size_t)out) % sizeof(size_t) != 0) + break; +#endif +#if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + GHASH(ctx, in, GHASH_CHUNK); + while (j) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + for (i = 0; i < 16/sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ + ctx->EKi.t[i]; + out += 16; + in += 16; + j -= 16; + } + len -= GHASH_CHUNK; + } + if ((i = (len & (size_t)-16))) { + GHASH(ctx, in, i); + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + for (i = 0; i < 16/sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ + ctx->EKi.t[i]; + out += 16; + in += 16; + len -= 16; + } + } +#else + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + for (i = 0; i < 16/sizeof(size_t); ++i) { + size_t c = in[i]; + out[i] = c ^ ctx->EKi.t[i]; + ctx->Xi.t[i] ^= c; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +#endif + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + + while (len--) { + u8 c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; + } while (0); +#endif + for (i = 0; i < len; ++i) { + u8 c; + if (n == 0) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + } + c = in[i]; + out[i] = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + n = (n + 1) % 16; + if (n == 0) + GCM_MUL(ctx, Xi); + } + + ctx->mres = n; + return 0; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_decrypt); + +int +CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream) +{ + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p)(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to encrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = be32toh(ctx->Yi.d[3]); + + n = ctx->mres; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) + while (len >= GHASH_CHUNK) { + (*stream)(in, out, GHASH_CHUNK/16, key, ctx->Yi.c); + ctr += GHASH_CHUNK/16; + ctx->Yi.d[3] = htobe32(ctr); + GHASH(ctx, out, GHASH_CHUNK); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + if ((i = (len & (size_t)-16))) { + size_t j = i/16; + + (*stream)(in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + ctx->Yi.d[3] = htobe32(ctr); + in += i; + len -= i; +#if defined(GHASH) + GHASH(ctx, out, i); + out += i; +#else + while (j--) { + for (i = 0; i < 16; ++i) + ctx->Xi.c[i] ^= out[i]; + GCM_MUL(ctx, Xi); + out += 16; + } +#endif + } + if (len) { + (*ctx->block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_encrypt_ctr32); + +int +CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream) +{ + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p)(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to decrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = be32toh(ctx->Yi.d[3]); + + n = ctx->mres; + if (n) { + while (n && len) { + u8 c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) + while (len >= GHASH_CHUNK) { + GHASH(ctx, in, GHASH_CHUNK); + (*stream)(in, out, GHASH_CHUNK/16, key, ctx->Yi.c); + ctr += GHASH_CHUNK/16; + ctx->Yi.d[3] = htobe32(ctr); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + if ((i = (len & (size_t)-16))) { + size_t j = i/16; + +#if defined(GHASH) + GHASH(ctx, in, i); +#else + while (j--) { + size_t k; + for (k = 0; k < 16; ++k) + ctx->Xi.c[k] ^= in[k]; + GCM_MUL(ctx, Xi); + in += 16; + } + j = i/16; + in -= i; +#endif + (*stream)(in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + ctx->Yi.d[3] = htobe32(ctr); + out += i; + in += i; + len -= i; + } + if (len) { + (*ctx->block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = htobe32(ctr); + while (len--) { + u8 c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_decrypt_ctr32); + +int +CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len) +{ + u64 alen = ctx->len.u[0] << 3; + u64 clen = ctx->len.u[1] << 3; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + if (ctx->mres || ctx->ares) + GCM_MUL(ctx, Xi); + + ctx->Xi.u[0] ^= htobe64(alen); + ctx->Xi.u[1] ^= htobe64(clen); + GCM_MUL(ctx, Xi); + + ctx->Xi.u[0] ^= ctx->EK0.u[0]; + ctx->Xi.u[1] ^= ctx->EK0.u[1]; + + if (tag && len <= sizeof(ctx->Xi)) + return memcmp(ctx->Xi.c, tag, len); + else + return -1; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_finish); + +void +CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + CRYPTO_gcm128_finish(ctx, NULL, 0); + memcpy(tag, ctx->Xi.c, + len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); +} +LCRYPTO_ALIAS(CRYPTO_gcm128_tag); + +GCM128_CONTEXT * +CRYPTO_gcm128_new(void *key, block128_f block) +{ + GCM128_CONTEXT *ret; + + if ((ret = malloc(sizeof(GCM128_CONTEXT)))) + CRYPTO_gcm128_init(ret, key, block); + + return ret; +} +LCRYPTO_ALIAS(CRYPTO_gcm128_new); + +void +CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) +{ + freezero(ctx, sizeof(*ctx)); +} +LCRYPTO_ALIAS(CRYPTO_gcm128_release); diff --git a/Libraries/libressl/crypto/modes/ghash-elf-armv4.S b/Libraries/libressl/crypto/modes/ghash-elf-armv4.S new file mode 100644 index 000000000..af42593de --- /dev/null +++ b/Libraries/libressl/crypto/modes/ghash-elf-armv4.S @@ -0,0 +1,412 @@ +#include "arm_arch.h" + +.text +.syntax unified +.code 32 + +.type rem_4bit,%object +.align 5 +rem_4bit: +.short 0x0000,0x1C20,0x3840,0x2460 +.short 0x7080,0x6CA0,0x48C0,0x54E0 +.short 0xE100,0xFD20,0xD940,0xC560 +.short 0x9180,0x8DA0,0xA9C0,0xB5E0 +.size rem_4bit,.-rem_4bit + +.type rem_4bit_get,%function +rem_4bit_get: + sub r2,pc,#8 + sub r2,r2,#32 @ &rem_4bit + b .Lrem_4bit_got + nop +.size rem_4bit_get,.-rem_4bit_get + +.global gcm_ghash_4bit +.type gcm_ghash_4bit,%function +gcm_ghash_4bit: + sub r12,pc,#8 + add r3,r2,r3 @ r3 to point at the end + stmdb sp!,{r3-r11,lr} @ save r3/end too + sub r12,r12,#48 @ &rem_4bit + + ldmia r12,{r4-r11} @ copy rem_4bit ... + stmdb sp!,{r4-r11} @ ... to stack + + ldrb r12,[r2,#15] + ldrb r14,[r0,#15] +.Louter: + eor r12,r12,r14 + and r14,r12,#0xf0 + and r12,r12,#0x0f + mov r3,#14 + + add r7,r1,r12,lsl#4 + ldmia r7,{r4-r7} @ load Htbl[nlo] + add r11,r1,r14 + ldrb r12,[r2,#14] + + and r14,r4,#0xf @ rem + ldmia r11,{r8-r11} @ load Htbl[nhi] + add r14,r14,r14 + eor r4,r8,r4,lsr#4 + ldrh r8,[sp,r14] @ rem_4bit[rem] + eor r4,r4,r5,lsl#28 + ldrb r14,[r0,#14] + eor r5,r9,r5,lsr#4 + eor r5,r5,r6,lsl#28 + eor r6,r10,r6,lsr#4 + eor r6,r6,r7,lsl#28 + eor r7,r11,r7,lsr#4 + eor r12,r12,r14 + and r14,r12,#0xf0 + and r12,r12,#0x0f + eor r7,r7,r8,lsl#16 + +.Linner: + add r11,r1,r12,lsl#4 + and r12,r4,#0xf @ rem + subs r3,r3,#1 + add r12,r12,r12 + ldmia r11,{r8-r11} @ load Htbl[nlo] + eor r4,r8,r4,lsr#4 + eor r4,r4,r5,lsl#28 + eor r5,r9,r5,lsr#4 + eor r5,r5,r6,lsl#28 + ldrh r8,[sp,r12] @ rem_4bit[rem] + eor r6,r10,r6,lsr#4 + ldrbpl r12,[r2,r3] + eor r6,r6,r7,lsl#28 + eor r7,r11,r7,lsr#4 + + add r11,r1,r14 + and r14,r4,#0xf @ rem + eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem] + add r14,r14,r14 + ldmia r11,{r8-r11} @ load Htbl[nhi] + eor r4,r8,r4,lsr#4 + ldrbpl r8,[r0,r3] + eor r4,r4,r5,lsl#28 + eor r5,r9,r5,lsr#4 + ldrh r9,[sp,r14] + eor r5,r5,r6,lsl#28 + eor r6,r10,r6,lsr#4 + eor r6,r6,r7,lsl#28 + eorpl r12,r12,r8 + eor r7,r11,r7,lsr#4 + andpl r14,r12,#0xf0 + andpl r12,r12,#0x0f + eor r7,r7,r9,lsl#16 @ ^= rem_4bit[rem] + bpl .Linner + + ldr r3,[sp,#32] @ re-load r3/end + add r2,r2,#16 + mov r14,r4 +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r4,r4 + str r4,[r0,#12] +#elif defined(__ARMEB__) + str r4,[r0,#12] +#else + mov r9,r4,lsr#8 + strb r4,[r0,#12+3] + mov r10,r4,lsr#16 + strb r9,[r0,#12+2] + mov r11,r4,lsr#24 + strb r10,[r0,#12+1] + strb r11,[r0,#12] +#endif + cmp r2,r3 +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r5,r5 + str r5,[r0,#8] +#elif defined(__ARMEB__) + str r5,[r0,#8] +#else + mov r9,r5,lsr#8 + strb r5,[r0,#8+3] + mov r10,r5,lsr#16 + strb r9,[r0,#8+2] + mov r11,r5,lsr#24 + strb r10,[r0,#8+1] + strb r11,[r0,#8] +#endif + ldrbne r12,[r2,#15] +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r6,r6 + str r6,[r0,#4] +#elif defined(__ARMEB__) + str r6,[r0,#4] +#else + mov r9,r6,lsr#8 + strb r6,[r0,#4+3] + mov r10,r6,lsr#16 + strb r9,[r0,#4+2] + mov r11,r6,lsr#24 + strb r10,[r0,#4+1] + strb r11,[r0,#4] +#endif + +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r7,r7 + str r7,[r0,#0] +#elif defined(__ARMEB__) + str r7,[r0,#0] +#else + mov r9,r7,lsr#8 + strb r7,[r0,#0+3] + mov r10,r7,lsr#16 + strb r9,[r0,#0+2] + mov r11,r7,lsr#24 + strb r10,[r0,#0+1] + strb r11,[r0,#0] +#endif + + bne .Louter + + add sp,sp,#36 +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + .word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size gcm_ghash_4bit,.-gcm_ghash_4bit + +.global gcm_gmult_4bit +.type gcm_gmult_4bit,%function +gcm_gmult_4bit: + stmdb sp!,{r4-r11,lr} + ldrb r12,[r0,#15] + b rem_4bit_get +.Lrem_4bit_got: + and r14,r12,#0xf0 + and r12,r12,#0x0f + mov r3,#14 + + add r7,r1,r12,lsl#4 + ldmia r7,{r4-r7} @ load Htbl[nlo] + ldrb r12,[r0,#14] + + add r11,r1,r14 + and r14,r4,#0xf @ rem + ldmia r11,{r8-r11} @ load Htbl[nhi] + add r14,r14,r14 + eor r4,r8,r4,lsr#4 + ldrh r8,[r2,r14] @ rem_4bit[rem] + eor r4,r4,r5,lsl#28 + eor r5,r9,r5,lsr#4 + eor r5,r5,r6,lsl#28 + eor r6,r10,r6,lsr#4 + eor r6,r6,r7,lsl#28 + eor r7,r11,r7,lsr#4 + and r14,r12,#0xf0 + eor r7,r7,r8,lsl#16 + and r12,r12,#0x0f + +.Loop: + add r11,r1,r12,lsl#4 + and r12,r4,#0xf @ rem + subs r3,r3,#1 + add r12,r12,r12 + ldmia r11,{r8-r11} @ load Htbl[nlo] + eor r4,r8,r4,lsr#4 + eor r4,r4,r5,lsl#28 + eor r5,r9,r5,lsr#4 + eor r5,r5,r6,lsl#28 + ldrh r8,[r2,r12] @ rem_4bit[rem] + eor r6,r10,r6,lsr#4 + ldrbpl r12,[r0,r3] + eor r6,r6,r7,lsl#28 + eor r7,r11,r7,lsr#4 + + add r11,r1,r14 + and r14,r4,#0xf @ rem + eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem] + add r14,r14,r14 + ldmia r11,{r8-r11} @ load Htbl[nhi] + eor r4,r8,r4,lsr#4 + eor r4,r4,r5,lsl#28 + eor r5,r9,r5,lsr#4 + ldrh r8,[r2,r14] @ rem_4bit[rem] + eor r5,r5,r6,lsl#28 + eor r6,r10,r6,lsr#4 + eor r6,r6,r7,lsl#28 + eor r7,r11,r7,lsr#4 + andpl r14,r12,#0xf0 + andpl r12,r12,#0x0f + eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem] + bpl .Loop +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r4,r4 + str r4,[r0,#12] +#elif defined(__ARMEB__) + str r4,[r0,#12] +#else + mov r9,r4,lsr#8 + strb r4,[r0,#12+3] + mov r10,r4,lsr#16 + strb r9,[r0,#12+2] + mov r11,r4,lsr#24 + strb r10,[r0,#12+1] + strb r11,[r0,#12] +#endif + +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r5,r5 + str r5,[r0,#8] +#elif defined(__ARMEB__) + str r5,[r0,#8] +#else + mov r9,r5,lsr#8 + strb r5,[r0,#8+3] + mov r10,r5,lsr#16 + strb r9,[r0,#8+2] + mov r11,r5,lsr#24 + strb r10,[r0,#8+1] + strb r11,[r0,#8] +#endif + +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r6,r6 + str r6,[r0,#4] +#elif defined(__ARMEB__) + str r6,[r0,#4] +#else + mov r9,r6,lsr#8 + strb r6,[r0,#4+3] + mov r10,r6,lsr#16 + strb r9,[r0,#4+2] + mov r11,r6,lsr#24 + strb r10,[r0,#4+1] + strb r11,[r0,#4] +#endif + +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev r7,r7 + str r7,[r0,#0] +#elif defined(__ARMEB__) + str r7,[r0,#0] +#else + mov r9,r7,lsr#8 + strb r7,[r0,#0+3] + mov r10,r7,lsr#16 + strb r9,[r0,#0+2] + mov r11,r7,lsr#24 + strb r10,[r0,#0+1] + strb r11,[r0,#0] +#endif + +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + .word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size gcm_gmult_4bit,.-gcm_gmult_4bit +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) +.fpu neon + +.global gcm_gmult_neon +.type gcm_gmult_neon,%function +.align 4 +gcm_gmult_neon: + sub r1,#16 @ point at H in GCM128_CTX + vld1.64 d29,[r0,:64]!@ load Xi + vmov.i32 d5,#0xe1 @ our irreducible polynomial + vld1.64 d28,[r0,:64]! + vshr.u64 d5,#32 + vldmia r1,{d0-d1} @ load H + veor q12,q12 +#ifdef __ARMEL__ + vrev64.8 q14,q14 +#endif + veor q13,q13 + veor q11,q11 + mov r1,#16 + veor q10,q10 + mov r3,#16 + veor d2,d2 + vdup.8 d4,d28[0] @ broadcast lowest byte + b .Linner_neon +.size gcm_gmult_neon,.-gcm_gmult_neon + +.global gcm_ghash_neon +.type gcm_ghash_neon,%function +.align 4 +gcm_ghash_neon: + vld1.64 d21,[r0,:64]! @ load Xi + vmov.i32 d5,#0xe1 @ our irreducible polynomial + vld1.64 d20,[r0,:64]! + vshr.u64 d5,#32 + vldmia r0,{d0-d1} @ load H + veor q12,q12 + nop +#ifdef __ARMEL__ + vrev64.8 q10,q10 +#endif +.Louter_neon: + vld1.64 d29,[r2]! @ load inp + veor q13,q13 + vld1.64 d28,[r2]! + veor q11,q11 + mov r1,#16 +#ifdef __ARMEL__ + vrev64.8 q14,q14 +#endif + veor d2,d2 + veor q14,q10 @ inp^=Xi + veor q10,q10 + vdup.8 d4,d28[0] @ broadcast lowest byte +.Linner_neon: + subs r1,r1,#1 + vmull.p8 q9,d1,d4 @ H.lo·Xi[i] + vmull.p8 q8,d0,d4 @ H.hi·Xi[i] + vext.8 q14,q12,#1 @ IN>>=8 + + veor q10,q13 @ modulo-scheduled part + vshl.i64 d22,#48 + vdup.8 d4,d28[0] @ broadcast lowest byte + veor d3,d18,d20 + + veor d21,d22 + vuzp.8 q9,q8 + vsli.8 d2,d3,#1 @ compose the "carry" byte + vext.8 q10,q12,#1 @ Z>>=8 + + vmull.p8 q11,d2,d5 @ "carry"·0xe1 + vshr.u8 d2,d3,#7 @ save Z's bottom bit + vext.8 q13,q9,q12,#1 @ Qlo>>=8 + veor q10,q8 + bne .Linner_neon + + veor q10,q13 @ modulo-scheduled artefact + vshl.i64 d22,#48 + veor d21,d22 + + @ finalization, normalize Z:Zo + vand d2,d5 @ suffices to mask the bit + vshr.u64 d3,d20,#63 + vshl.i64 q10,#1 + subs r3,#16 + vorr q10,q1 @ Z=Z:Zo<<1 + bne .Louter_neon + +#ifdef __ARMEL__ + vrev64.8 q10,q10 +#endif + sub r0,#16 + vst1.64 d21,[r0,:64]! @ write out Xi + vst1.64 d20,[r0,:64] + + .word 0xe12fff1e +.size gcm_ghash_neon,.-gcm_ghash_neon +#endif +.asciz "GHASH for ARMv4/NEON, CRYPTOGAMS by " +.align 2 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/modes/ghash-elf-x86_64.S b/Libraries/libressl/crypto/modes/ghash-elf-x86_64.S new file mode 100644 index 000000000..039cd4961 --- /dev/null +++ b/Libraries/libressl/crypto/modes/ghash-elf-x86_64.S @@ -0,0 +1,1033 @@ +#include "x86_arch.h" +.text + +.globl gcm_gmult_4bit +.type gcm_gmult_4bit,@function +.align 16 +gcm_gmult_4bit: + pushq %rbx + pushq %rbp + pushq %r12 +.Lgmult_prologue: + + movzbq 15(%rdi),%r8 + leaq .Lrem_4bit(%rip),%r11 + xorq %rax,%rax + xorq %rbx,%rbx + movb %r8b,%al + movb %r8b,%bl + shlb $4,%al + movq $14,%rcx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + andb $240,%bl + movq %r8,%rdx + jmp .Loop1 + +.align 16 +.Loop1: + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + movb (%rdi,%rcx,1),%al + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + movb %al,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + shlb $4,%al + xorq %r10,%r8 + decq %rcx + js .Lbreak1 + + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $240,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + jmp .Loop1 + +.align 16 +.Lbreak1: + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $240,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + xorq %r10,%r8 + xorq (%r11,%rdx,8),%r9 + + bswapq %r8 + bswapq %r9 + movq %r8,8(%rdi) + movq %r9,(%rdi) + + movq 16(%rsp),%rbx + leaq 24(%rsp),%rsp +.Lgmult_epilogue: + retq +.size gcm_gmult_4bit,.-gcm_gmult_4bit +.globl gcm_ghash_4bit +.type gcm_ghash_4bit,@function +.align 16 +gcm_ghash_4bit: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $280,%rsp +.Lghash_prologue: + movq %rdx,%r14 + movq %rcx,%r15 + subq $-128,%rsi + leaq 16+128(%rsp),%rbp + xorl %edx,%edx + movq 0+0-128(%rsi),%r8 + movq 0+8-128(%rsi),%rax + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq 16+0-128(%rsi),%r9 + shlb $4,%dl + movq 16+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,0(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,0(%rbp) + movq 32+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,0-128(%rbp) + movq 32+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,1(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,8(%rbp) + movq 48+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,8-128(%rbp) + movq 48+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,2(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,16(%rbp) + movq 64+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,16-128(%rbp) + movq 64+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,3(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,24(%rbp) + movq 80+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,24-128(%rbp) + movq 80+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,4(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,32(%rbp) + movq 96+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,32-128(%rbp) + movq 96+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,5(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,40(%rbp) + movq 112+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,40-128(%rbp) + movq 112+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,6(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,48(%rbp) + movq 128+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,48-128(%rbp) + movq 128+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,7(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,56(%rbp) + movq 144+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,56-128(%rbp) + movq 144+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,8(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,64(%rbp) + movq 160+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,64-128(%rbp) + movq 160+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,9(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,72(%rbp) + movq 176+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,72-128(%rbp) + movq 176+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,10(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,80(%rbp) + movq 192+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,80-128(%rbp) + movq 192+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,11(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,88(%rbp) + movq 208+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,88-128(%rbp) + movq 208+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,12(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,96(%rbp) + movq 224+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,96-128(%rbp) + movq 224+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,13(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,104(%rbp) + movq 240+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,104-128(%rbp) + movq 240+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,14(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,112(%rbp) + shlb $4,%dl + movq %rax,112-128(%rbp) + shlq $60,%r10 + movb %dl,15(%rsp) + orq %r10,%rbx + movq %r9,120(%rbp) + movq %rbx,120-128(%rbp) + addq $-128,%rsi + movq 8(%rdi),%r8 + movq 0(%rdi),%r9 + addq %r14,%r15 + leaq .Lrem_8bit(%rip),%r11 + jmp .Louter_loop +.align 16 +.Louter_loop: + xorq (%r14),%r9 + movq 8(%r14),%rdx + leaq 16(%r14),%r14 + xorq %r8,%rdx + movq %r9,(%rdi) + movq %rdx,8(%rdi) + shrq $32,%rdx + xorq %rax,%rax + roll $8,%edx + movb %dl,%al + movzbl %dl,%ebx + shlb $4,%al + shrl $4,%ebx + roll $8,%edx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + movb %dl,%al + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + xorq %r8,%r12 + movq %r9,%r10 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 8(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 0(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + andl $240,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl -4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + movzwq (%r11,%r12,2),%r12 + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + shlq $48,%r12 + xorq %r10,%r8 + xorq %r12,%r9 + movzbq %r8b,%r13 + shrq $4,%r8 + movq %r9,%r10 + shlb $4,%r13b + shrq $4,%r9 + xorq 8(%rsi,%rcx,1),%r8 + movzwq (%r11,%r13,2),%r13 + shlq $60,%r10 + xorq (%rsi,%rcx,1),%r9 + xorq %r10,%r8 + shlq $48,%r13 + bswapq %r8 + xorq %r13,%r9 + bswapq %r9 + cmpq %r15,%r14 + jb .Louter_loop + movq %r8,8(%rdi) + movq %r9,(%rdi) + + leaq 280(%rsp),%rsi + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lghash_epilogue: + retq +.size gcm_ghash_4bit,.-gcm_ghash_4bit +.globl gcm_init_clmul +.type gcm_init_clmul,@function +.align 16 +gcm_init_clmul: + endbr64 + movdqu (%rsi),%xmm2 + pshufd $78,%xmm2,%xmm2 + + + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + + + pand .L0x1c2_polynomial(%rip),%xmm5 + pxor %xmm5,%xmm2 + + + movdqa %xmm2,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + movdqu %xmm2,(%rdi) + movdqu %xmm0,16(%rdi) + retq +.size gcm_init_clmul,.-gcm_init_clmul +.globl gcm_gmult_clmul +.type gcm_gmult_clmul,@function +.align 16 +gcm_gmult_clmul: + endbr64 + movdqu (%rdi),%xmm0 + movdqa .Lbswap_mask(%rip),%xmm5 + movdqu (%rsi),%xmm2 +.byte 102,15,56,0,197 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + retq +.size gcm_gmult_clmul,.-gcm_gmult_clmul +.globl gcm_ghash_clmul +.type gcm_ghash_clmul,@function +.align 16 +gcm_ghash_clmul: + endbr64 + movdqa .Lbswap_mask(%rip),%xmm5 + + movdqu (%rdi),%xmm0 + movdqu (%rsi),%xmm2 +.byte 102,15,56,0,197 + + subq $16,%rcx + jz .Lodd_tail + + movdqu 16(%rsi),%xmm8 + + + + + + movdqu (%rdx),%xmm3 + movdqu 16(%rdx),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + pxor %xmm3,%xmm0 + movdqa %xmm6,%xmm7 + pshufd $78,%xmm6,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm6,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,242,0 +.byte 102,15,58,68,250,17 +.byte 102,15,58,68,220,0 + pxor %xmm6,%xmm3 + pxor %xmm7,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm7 + pxor %xmm4,%xmm6 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm8,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm8,%xmm4 + + leaq 32(%rdx),%rdx + subq $32,%rcx + jbe .Leven_tail + +.Lmod_loop: +.byte 102,65,15,58,68,192,0 +.byte 102,65,15,58,68,200,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqu (%rdx),%xmm3 + pxor %xmm6,%xmm0 + pxor %xmm7,%xmm1 + + movdqu 16(%rdx),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + + movdqa %xmm6,%xmm7 + pshufd $78,%xmm6,%xmm9 + pshufd $78,%xmm2,%xmm10 + pxor %xmm6,%xmm9 + pxor %xmm2,%xmm10 + pxor %xmm3,%xmm1 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 +.byte 102,15,58,68,242,0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + +.byte 102,15,58,68,250,17 + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + +.byte 102,69,15,58,68,202,0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm8,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm8,%xmm4 + + pxor %xmm6,%xmm9 + pxor %xmm7,%xmm9 + movdqa %xmm9,%xmm10 + psrldq $8,%xmm9 + pslldq $8,%xmm10 + pxor %xmm9,%xmm7 + pxor %xmm10,%xmm6 + + leaq 32(%rdx),%rdx + subq $32,%rcx + ja .Lmod_loop + +.Leven_tail: +.byte 102,65,15,58,68,192,0 +.byte 102,65,15,58,68,200,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm6,%xmm0 + pxor %xmm7,%xmm1 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + testq %rcx,%rcx + jnz .Ldone + +.Lodd_tail: + movdqu (%rdx),%xmm3 +.byte 102,15,56,0,221 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 +.Ldone: +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + retq +.LSEH_end_gcm_ghash_clmul: +.size gcm_ghash_clmul,.-gcm_ghash_clmul +.section .rodata +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.L0x1c2_polynomial: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.align 64 +.type .Lrem_4bit,@object +.Lrem_4bit: +.long 0,0,0,471859200,0,943718400,0,610271232 +.long 0,1887436800,0,1822425088,0,1220542464,0,1423966208 +.long 0,3774873600,0,4246732800,0,3644850176,0,3311403008 +.long 0,2441084928,0,2376073216,0,2847932416,0,3051356160 +.type .Lrem_8bit,@object +.Lrem_8bit: +.value 0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E +.value 0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E +.value 0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E +.value 0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E +.value 0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E +.value 0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E +.value 0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E +.value 0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E +.value 0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE +.value 0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE +.value 0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE +.value 0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE +.value 0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E +.value 0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E +.value 0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE +.value 0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE +.value 0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E +.value 0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E +.value 0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E +.value 0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E +.value 0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E +.value 0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E +.value 0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E +.value 0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E +.value 0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE +.value 0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE +.value 0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE +.value 0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE +.value 0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E +.value 0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E +.value 0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE +.value 0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE +.align 64 +.text +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/modes/ghash-macosx-x86_64.S b/Libraries/libressl/crypto/modes/ghash-macosx-x86_64.S new file mode 100644 index 000000000..e6840a781 --- /dev/null +++ b/Libraries/libressl/crypto/modes/ghash-macosx-x86_64.S @@ -0,0 +1,1027 @@ +#include "x86_arch.h" +.text + +.globl _gcm_gmult_4bit + +.p2align 4 +_gcm_gmult_4bit: + pushq %rbx + pushq %rbp + pushq %r12 +L$gmult_prologue: + + movzbq 15(%rdi),%r8 + leaq L$rem_4bit(%rip),%r11 + xorq %rax,%rax + xorq %rbx,%rbx + movb %r8b,%al + movb %r8b,%bl + shlb $4,%al + movq $14,%rcx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + andb $240,%bl + movq %r8,%rdx + jmp L$oop1 + +.p2align 4 +L$oop1: + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + movb (%rdi,%rcx,1),%al + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + movb %al,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + shlb $4,%al + xorq %r10,%r8 + decq %rcx + js L$break1 + + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $240,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + jmp L$oop1 + +.p2align 4 +L$break1: + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $240,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + xorq %r10,%r8 + xorq (%r11,%rdx,8),%r9 + + bswapq %r8 + bswapq %r9 + movq %r8,8(%rdi) + movq %r9,(%rdi) + + movq 16(%rsp),%rbx + leaq 24(%rsp),%rsp +L$gmult_epilogue: + retq + +.globl _gcm_ghash_4bit + +.p2align 4 +_gcm_ghash_4bit: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $280,%rsp +L$ghash_prologue: + movq %rdx,%r14 + movq %rcx,%r15 + subq $-128,%rsi + leaq 16+128(%rsp),%rbp + xorl %edx,%edx + movq 0+0-128(%rsi),%r8 + movq 0+8-128(%rsi),%rax + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq 16+0-128(%rsi),%r9 + shlb $4,%dl + movq 16+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,0(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,0(%rbp) + movq 32+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,0-128(%rbp) + movq 32+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,1(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,8(%rbp) + movq 48+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,8-128(%rbp) + movq 48+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,2(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,16(%rbp) + movq 64+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,16-128(%rbp) + movq 64+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,3(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,24(%rbp) + movq 80+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,24-128(%rbp) + movq 80+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,4(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,32(%rbp) + movq 96+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,32-128(%rbp) + movq 96+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,5(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,40(%rbp) + movq 112+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,40-128(%rbp) + movq 112+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,6(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,48(%rbp) + movq 128+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,48-128(%rbp) + movq 128+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,7(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,56(%rbp) + movq 144+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,56-128(%rbp) + movq 144+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,8(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,64(%rbp) + movq 160+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,64-128(%rbp) + movq 160+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,9(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,72(%rbp) + movq 176+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,72-128(%rbp) + movq 176+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,10(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,80(%rbp) + movq 192+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,80-128(%rbp) + movq 192+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,11(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,88(%rbp) + movq 208+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,88-128(%rbp) + movq 208+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,12(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,96(%rbp) + movq 224+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,96-128(%rbp) + movq 224+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,13(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,104(%rbp) + movq 240+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,104-128(%rbp) + movq 240+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,14(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,112(%rbp) + shlb $4,%dl + movq %rax,112-128(%rbp) + shlq $60,%r10 + movb %dl,15(%rsp) + orq %r10,%rbx + movq %r9,120(%rbp) + movq %rbx,120-128(%rbp) + addq $-128,%rsi + movq 8(%rdi),%r8 + movq 0(%rdi),%r9 + addq %r14,%r15 + leaq L$rem_8bit(%rip),%r11 + jmp L$outer_loop +.p2align 4 +L$outer_loop: + xorq (%r14),%r9 + movq 8(%r14),%rdx + leaq 16(%r14),%r14 + xorq %r8,%rdx + movq %r9,(%rdi) + movq %rdx,8(%rdi) + shrq $32,%rdx + xorq %rax,%rax + roll $8,%edx + movb %dl,%al + movzbl %dl,%ebx + shlb $4,%al + shrl $4,%ebx + roll $8,%edx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + movb %dl,%al + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + xorq %r8,%r12 + movq %r9,%r10 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 8(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 0(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + andl $240,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl -4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + movzwq (%r11,%r12,2),%r12 + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + shlq $48,%r12 + xorq %r10,%r8 + xorq %r12,%r9 + movzbq %r8b,%r13 + shrq $4,%r8 + movq %r9,%r10 + shlb $4,%r13b + shrq $4,%r9 + xorq 8(%rsi,%rcx,1),%r8 + movzwq (%r11,%r13,2),%r13 + shlq $60,%r10 + xorq (%rsi,%rcx,1),%r9 + xorq %r10,%r8 + shlq $48,%r13 + bswapq %r8 + xorq %r13,%r9 + bswapq %r9 + cmpq %r15,%r14 + jb L$outer_loop + movq %r8,8(%rdi) + movq %r9,(%rdi) + + leaq 280(%rsp),%rsi + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$ghash_epilogue: + retq + +.globl _gcm_init_clmul + +.p2align 4 +_gcm_init_clmul: + movdqu (%rsi),%xmm2 + pshufd $78,%xmm2,%xmm2 + + + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + + + pand L$0x1c2_polynomial(%rip),%xmm5 + pxor %xmm5,%xmm2 + + + movdqa %xmm2,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + movdqu %xmm2,(%rdi) + movdqu %xmm0,16(%rdi) + retq + +.globl _gcm_gmult_clmul + +.p2align 4 +_gcm_gmult_clmul: + movdqu (%rdi),%xmm0 + movdqa L$bswap_mask(%rip),%xmm5 + movdqu (%rsi),%xmm2 +.byte 102,15,56,0,197 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + retq + +.globl _gcm_ghash_clmul + +.p2align 4 +_gcm_ghash_clmul: + movdqa L$bswap_mask(%rip),%xmm5 + + movdqu (%rdi),%xmm0 + movdqu (%rsi),%xmm2 +.byte 102,15,56,0,197 + + subq $16,%rcx + jz L$odd_tail + + movdqu 16(%rsi),%xmm8 + + + + + + movdqu (%rdx),%xmm3 + movdqu 16(%rdx),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + pxor %xmm3,%xmm0 + movdqa %xmm6,%xmm7 + pshufd $78,%xmm6,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm6,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,242,0 +.byte 102,15,58,68,250,17 +.byte 102,15,58,68,220,0 + pxor %xmm6,%xmm3 + pxor %xmm7,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm7 + pxor %xmm4,%xmm6 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm8,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm8,%xmm4 + + leaq 32(%rdx),%rdx + subq $32,%rcx + jbe L$even_tail + +L$mod_loop: +.byte 102,65,15,58,68,192,0 +.byte 102,65,15,58,68,200,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqu (%rdx),%xmm3 + pxor %xmm6,%xmm0 + pxor %xmm7,%xmm1 + + movdqu 16(%rdx),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + + movdqa %xmm6,%xmm7 + pshufd $78,%xmm6,%xmm9 + pshufd $78,%xmm2,%xmm10 + pxor %xmm6,%xmm9 + pxor %xmm2,%xmm10 + pxor %xmm3,%xmm1 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 +.byte 102,15,58,68,242,0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + +.byte 102,15,58,68,250,17 + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + +.byte 102,69,15,58,68,202,0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm8,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm8,%xmm4 + + pxor %xmm6,%xmm9 + pxor %xmm7,%xmm9 + movdqa %xmm9,%xmm10 + psrldq $8,%xmm9 + pslldq $8,%xmm10 + pxor %xmm9,%xmm7 + pxor %xmm10,%xmm6 + + leaq 32(%rdx),%rdx + subq $32,%rcx + ja L$mod_loop + +L$even_tail: +.byte 102,65,15,58,68,192,0 +.byte 102,65,15,58,68,200,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm6,%xmm0 + pxor %xmm7,%xmm1 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + testq %rcx,%rcx + jnz L$done + +L$odd_tail: + movdqu (%rdx),%xmm3 +.byte 102,15,56,0,221 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 +L$done: +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + retq +L$SEH_end_gcm_ghash_clmul: + +.p2align 6 +L$bswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +L$0x1c2_polynomial: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.p2align 6 + +L$rem_4bit: +.long 0,0,0,471859200,0,943718400,0,610271232 +.long 0,1887436800,0,1822425088,0,1220542464,0,1423966208 +.long 0,3774873600,0,4246732800,0,3644850176,0,3311403008 +.long 0,2441084928,0,2376073216,0,2847932416,0,3051356160 + +L$rem_8bit: +.value 0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E +.value 0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E +.value 0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E +.value 0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E +.value 0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E +.value 0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E +.value 0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E +.value 0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E +.value 0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE +.value 0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE +.value 0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE +.value 0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE +.value 0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E +.value 0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E +.value 0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE +.value 0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE +.value 0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E +.value 0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E +.value 0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E +.value 0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E +.value 0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E +.value 0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E +.value 0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E +.value 0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E +.value 0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE +.value 0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE +.value 0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE +.value 0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE +.value 0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E +.value 0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E +.value 0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE +.value 0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE + +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 diff --git a/Libraries/libressl/crypto/modes/ghash-masm-x86_64.S b/Libraries/libressl/crypto/modes/ghash-masm-x86_64.S new file mode 100644 index 000000000..09ee8e0f3 --- /dev/null +++ b/Libraries/libressl/crypto/modes/ghash-masm-x86_64.S @@ -0,0 +1,1256 @@ +; 1 "crypto/modes/ghash-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/modes/ghash-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/modes/ghash-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC gcm_gmult_4bit + +ALIGN 16 +gcm_gmult_4bit PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_gcm_gmult_4bit:: + mov rdi,rcx + mov rsi,rdx + + + push rbx + push rbp + push r12 +$L$gmult_prologue:: + + movzx r8,BYTE PTR[15+rdi] + lea r11,QWORD PTR[$L$rem_4bit] + xor rax,rax + xor rbx,rbx + mov al,r8b + mov bl,r8b + shl al,4 + mov rcx,14 + mov r8,QWORD PTR[8+rax*1+rsi] + mov r9,QWORD PTR[rax*1+rsi] + and bl,0f0h + mov rdx,r8 + jmp $L$oop1 + +ALIGN 16 +$L$oop1:: + shr r8,4 + and rdx,0fh + mov r10,r9 + mov al,BYTE PTR[rcx*1+rdi] + shr r9,4 + xor r8,QWORD PTR[8+rbx*1+rsi] + shl r10,60 + xor r9,QWORD PTR[rbx*1+rsi] + mov bl,al + xor r9,QWORD PTR[rdx*8+r11] + mov rdx,r8 + shl al,4 + xor r8,r10 + dec rcx + js $L$break1 + + shr r8,4 + and rdx,0fh + mov r10,r9 + shr r9,4 + xor r8,QWORD PTR[8+rax*1+rsi] + shl r10,60 + xor r9,QWORD PTR[rax*1+rsi] + and bl,0f0h + xor r9,QWORD PTR[rdx*8+r11] + mov rdx,r8 + xor r8,r10 + jmp $L$oop1 + +ALIGN 16 +$L$break1:: + shr r8,4 + and rdx,0fh + mov r10,r9 + shr r9,4 + xor r8,QWORD PTR[8+rax*1+rsi] + shl r10,60 + xor r9,QWORD PTR[rax*1+rsi] + and bl,0f0h + xor r9,QWORD PTR[rdx*8+r11] + mov rdx,r8 + xor r8,r10 + + shr r8,4 + and rdx,0fh + mov r10,r9 + shr r9,4 + xor r8,QWORD PTR[8+rbx*1+rsi] + shl r10,60 + xor r9,QWORD PTR[rbx*1+rsi] + xor r8,r10 + xor r9,QWORD PTR[rdx*8+r11] + + bswap r8 + bswap r9 + mov QWORD PTR[8+rdi],r8 + mov QWORD PTR[rdi],r9 + + mov rbx,QWORD PTR[16+rsp] + lea rsp,QWORD PTR[24+rsp] +$L$gmult_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_gmult_4bit:: +gcm_gmult_4bit ENDP +PUBLIC gcm_ghash_4bit + +ALIGN 16 +gcm_ghash_4bit PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_gcm_ghash_4bit:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + sub rsp,280 +$L$ghash_prologue:: + mov r14,rdx + mov r15,rcx + sub rsi,-128 + lea rbp,QWORD PTR[((16+128))+rsp] + xor edx,edx + mov r8,QWORD PTR[((0+0-128))+rsi] + mov rax,QWORD PTR[((0+8-128))+rsi] + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov r9,QWORD PTR[((16+0-128))+rsi] + shl dl,4 + mov rbx,QWORD PTR[((16+8-128))+rsi] + shl r10,60 + mov BYTE PTR[rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[rbp],r8 + mov r8,QWORD PTR[((32+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((0-128))+rbp],rax + mov rax,QWORD PTR[((32+8-128))+rsi] + shl r10,60 + mov BYTE PTR[1+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[8+rbp],r9 + mov r9,QWORD PTR[((48+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((8-128))+rbp],rbx + mov rbx,QWORD PTR[((48+8-128))+rsi] + shl r10,60 + mov BYTE PTR[2+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[16+rbp],r8 + mov r8,QWORD PTR[((64+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((16-128))+rbp],rax + mov rax,QWORD PTR[((64+8-128))+rsi] + shl r10,60 + mov BYTE PTR[3+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[24+rbp],r9 + mov r9,QWORD PTR[((80+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((24-128))+rbp],rbx + mov rbx,QWORD PTR[((80+8-128))+rsi] + shl r10,60 + mov BYTE PTR[4+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[32+rbp],r8 + mov r8,QWORD PTR[((96+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((32-128))+rbp],rax + mov rax,QWORD PTR[((96+8-128))+rsi] + shl r10,60 + mov BYTE PTR[5+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[40+rbp],r9 + mov r9,QWORD PTR[((112+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((40-128))+rbp],rbx + mov rbx,QWORD PTR[((112+8-128))+rsi] + shl r10,60 + mov BYTE PTR[6+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[48+rbp],r8 + mov r8,QWORD PTR[((128+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((48-128))+rbp],rax + mov rax,QWORD PTR[((128+8-128))+rsi] + shl r10,60 + mov BYTE PTR[7+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[56+rbp],r9 + mov r9,QWORD PTR[((144+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((56-128))+rbp],rbx + mov rbx,QWORD PTR[((144+8-128))+rsi] + shl r10,60 + mov BYTE PTR[8+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[64+rbp],r8 + mov r8,QWORD PTR[((160+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((64-128))+rbp],rax + mov rax,QWORD PTR[((160+8-128))+rsi] + shl r10,60 + mov BYTE PTR[9+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[72+rbp],r9 + mov r9,QWORD PTR[((176+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((72-128))+rbp],rbx + mov rbx,QWORD PTR[((176+8-128))+rsi] + shl r10,60 + mov BYTE PTR[10+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[80+rbp],r8 + mov r8,QWORD PTR[((192+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((80-128))+rbp],rax + mov rax,QWORD PTR[((192+8-128))+rsi] + shl r10,60 + mov BYTE PTR[11+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[88+rbp],r9 + mov r9,QWORD PTR[((208+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((88-128))+rbp],rbx + mov rbx,QWORD PTR[((208+8-128))+rsi] + shl r10,60 + mov BYTE PTR[12+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[96+rbp],r8 + mov r8,QWORD PTR[((224+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((96-128))+rbp],rax + mov rax,QWORD PTR[((224+8-128))+rsi] + shl r10,60 + mov BYTE PTR[13+rsp],dl + or rbx,r10 + mov dl,al + shr rax,4 + mov r10,r8 + shr r8,4 + mov QWORD PTR[104+rbp],r9 + mov r9,QWORD PTR[((240+0-128))+rsi] + shl dl,4 + mov QWORD PTR[((104-128))+rbp],rbx + mov rbx,QWORD PTR[((240+8-128))+rsi] + shl r10,60 + mov BYTE PTR[14+rsp],dl + or rax,r10 + mov dl,bl + shr rbx,4 + mov r10,r9 + shr r9,4 + mov QWORD PTR[112+rbp],r8 + shl dl,4 + mov QWORD PTR[((112-128))+rbp],rax + shl r10,60 + mov BYTE PTR[15+rsp],dl + or rbx,r10 + mov QWORD PTR[120+rbp],r9 + mov QWORD PTR[((120-128))+rbp],rbx + add rsi,-128 + mov r8,QWORD PTR[8+rdi] + mov r9,QWORD PTR[rdi] + add r15,r14 + lea r11,QWORD PTR[$L$rem_8bit] + jmp $L$outer_loop +ALIGN 16 +$L$outer_loop:: + xor r9,QWORD PTR[r14] + mov rdx,QWORD PTR[8+r14] + lea r14,QWORD PTR[16+r14] + xor rdx,r8 + mov QWORD PTR[rdi],r9 + mov QWORD PTR[8+rdi],rdx + shr rdx,32 + xor rax,rax + rol edx,8 + mov al,dl + movzx ebx,dl + shl al,4 + shr ebx,4 + rol edx,8 + mov r8,QWORD PTR[8+rax*1+rsi] + mov r9,QWORD PTR[rax*1+rsi] + mov al,dl + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + xor r12,r8 + mov r10,r9 + shr r8,8 + movzx r12,r12b + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + mov edx,DWORD PTR[8+rdi] + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + mov edx,DWORD PTR[4+rdi] + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + mov edx,DWORD PTR[rdi] + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + shr ecx,4 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r12,WORD PTR[r12*2+r11] + movzx ebx,dl + shl al,4 + movzx r13,BYTE PTR[rcx*1+rsp] + shr ebx,4 + shl r12,48 + xor r13,r8 + mov r10,r9 + xor r9,r12 + shr r8,8 + movzx r13,r13b + shr r9,8 + xor r8,QWORD PTR[((-128))+rcx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rcx*8+rbp] + rol edx,8 + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + mov al,dl + xor r8,r10 + movzx r13,WORD PTR[r13*2+r11] + movzx ecx,dl + shl al,4 + movzx r12,BYTE PTR[rbx*1+rsp] + and ecx,240 + shl r13,48 + xor r12,r8 + mov r10,r9 + xor r9,r13 + shr r8,8 + movzx r12,r12b + mov edx,DWORD PTR[((-4))+rdi] + shr r9,8 + xor r8,QWORD PTR[((-128))+rbx*8+rbp] + shl r10,56 + xor r9,QWORD PTR[rbx*8+rbp] + movzx r12,WORD PTR[r12*2+r11] + xor r8,QWORD PTR[8+rax*1+rsi] + xor r9,QWORD PTR[rax*1+rsi] + shl r12,48 + xor r8,r10 + xor r9,r12 + movzx r13,r8b + shr r8,4 + mov r10,r9 + shl r13b,4 + shr r9,4 + xor r8,QWORD PTR[8+rcx*1+rsi] + movzx r13,WORD PTR[r13*2+r11] + shl r10,60 + xor r9,QWORD PTR[rcx*1+rsi] + xor r8,r10 + shl r13,48 + bswap r8 + xor r9,r13 + bswap r9 + cmp r14,r15 + jb $L$outer_loop + mov QWORD PTR[8+rdi],r8 + mov QWORD PTR[rdi],r9 + + lea rsi,QWORD PTR[280+rsp] + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$ghash_epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_ghash_4bit:: +gcm_ghash_4bit ENDP +PUBLIC gcm_init_clmul + +ALIGN 16 +gcm_init_clmul PROC PUBLIC + movdqu xmm2,XMMWORD PTR[rdx] + pshufd xmm2,xmm2,78 + + + pshufd xmm4,xmm2,255 + movdqa xmm3,xmm2 + psllq xmm2,1 + pxor xmm5,xmm5 + psrlq xmm3,63 + pcmpgtd xmm5,xmm4 + pslldq xmm3,8 + por xmm2,xmm3 + + + pand xmm5,XMMWORD PTR[$L$0x1c2_polynomial] + pxor xmm2,xmm5 + + + movdqa xmm0,xmm2 + movdqa xmm1,xmm0 + pshufd xmm3,xmm0,78 + pshufd xmm4,xmm2,78 + pxor xmm3,xmm0 + pxor xmm4,xmm2 +DB 102,15,58,68,194,0 +DB 102,15,58,68,202,17 +DB 102,15,58,68,220,0 + pxor xmm3,xmm0 + pxor xmm3,xmm1 + + movdqa xmm4,xmm3 + psrldq xmm3,8 + pslldq xmm4,8 + pxor xmm1,xmm3 + pxor xmm0,xmm4 + + movdqa xmm3,xmm0 + psllq xmm0,1 + pxor xmm0,xmm3 + psllq xmm0,5 + pxor xmm0,xmm3 + psllq xmm0,57 + movdqa xmm4,xmm0 + pslldq xmm0,8 + psrldq xmm4,8 + pxor xmm0,xmm3 + pxor xmm1,xmm4 + + + movdqa xmm4,xmm0 + psrlq xmm0,5 + pxor xmm0,xmm4 + psrlq xmm0,1 + pxor xmm0,xmm4 + pxor xmm4,xmm1 + psrlq xmm0,1 + pxor xmm0,xmm4 + movdqu XMMWORD PTR[rcx],xmm2 + movdqu XMMWORD PTR[16+rcx],xmm0 + DB 0F3h,0C3h ;repret +gcm_init_clmul ENDP +PUBLIC gcm_gmult_clmul + +ALIGN 16 +gcm_gmult_clmul PROC PUBLIC + movdqu xmm0,XMMWORD PTR[rcx] + movdqa xmm5,XMMWORD PTR[$L$bswap_mask] + movdqu xmm2,XMMWORD PTR[rdx] +DB 102,15,56,0,197 + movdqa xmm1,xmm0 + pshufd xmm3,xmm0,78 + pshufd xmm4,xmm2,78 + pxor xmm3,xmm0 + pxor xmm4,xmm2 +DB 102,15,58,68,194,0 +DB 102,15,58,68,202,17 +DB 102,15,58,68,220,0 + pxor xmm3,xmm0 + pxor xmm3,xmm1 + + movdqa xmm4,xmm3 + psrldq xmm3,8 + pslldq xmm4,8 + pxor xmm1,xmm3 + pxor xmm0,xmm4 + + movdqa xmm3,xmm0 + psllq xmm0,1 + pxor xmm0,xmm3 + psllq xmm0,5 + pxor xmm0,xmm3 + psllq xmm0,57 + movdqa xmm4,xmm0 + pslldq xmm0,8 + psrldq xmm4,8 + pxor xmm0,xmm3 + pxor xmm1,xmm4 + + + movdqa xmm4,xmm0 + psrlq xmm0,5 + pxor xmm0,xmm4 + psrlq xmm0,1 + pxor xmm0,xmm4 + pxor xmm4,xmm1 + psrlq xmm0,1 + pxor xmm0,xmm4 +DB 102,15,56,0,197 + movdqu XMMWORD PTR[rcx],xmm0 + DB 0F3h,0C3h ;repret +gcm_gmult_clmul ENDP +PUBLIC gcm_ghash_clmul + +ALIGN 16 +gcm_ghash_clmul PROC PUBLIC +$L$SEH_begin_gcm_ghash_clmul:: + +DB 048h,083h,0ech,058h +DB 00fh,029h,034h,024h +DB 00fh,029h,07ch,024h,010h +DB 044h,00fh,029h,044h,024h,020h +DB 044h,00fh,029h,04ch,024h,030h +DB 044h,00fh,029h,054h,024h,040h + movdqa xmm5,XMMWORD PTR[$L$bswap_mask] + + movdqu xmm0,XMMWORD PTR[rcx] + movdqu xmm2,XMMWORD PTR[rdx] +DB 102,15,56,0,197 + + sub r9,010h + jz $L$odd_tail + + movdqu xmm8,XMMWORD PTR[16+rdx] + + + + + + movdqu xmm3,XMMWORD PTR[r8] + movdqu xmm6,XMMWORD PTR[16+r8] +DB 102,15,56,0,221 +DB 102,15,56,0,245 + pxor xmm0,xmm3 + movdqa xmm7,xmm6 + pshufd xmm3,xmm6,78 + pshufd xmm4,xmm2,78 + pxor xmm3,xmm6 + pxor xmm4,xmm2 +DB 102,15,58,68,242,0 +DB 102,15,58,68,250,17 +DB 102,15,58,68,220,0 + pxor xmm3,xmm6 + pxor xmm3,xmm7 + + movdqa xmm4,xmm3 + psrldq xmm3,8 + pslldq xmm4,8 + pxor xmm7,xmm3 + pxor xmm6,xmm4 + movdqa xmm1,xmm0 + pshufd xmm3,xmm0,78 + pshufd xmm4,xmm8,78 + pxor xmm3,xmm0 + pxor xmm4,xmm8 + + lea r8,QWORD PTR[32+r8] + sub r9,020h + jbe $L$even_tail + +$L$mod_loop:: +DB 102,65,15,58,68,192,0 +DB 102,65,15,58,68,200,17 +DB 102,15,58,68,220,0 + pxor xmm3,xmm0 + pxor xmm3,xmm1 + + movdqa xmm4,xmm3 + psrldq xmm3,8 + pslldq xmm4,8 + pxor xmm1,xmm3 + pxor xmm0,xmm4 + movdqu xmm3,XMMWORD PTR[r8] + pxor xmm0,xmm6 + pxor xmm1,xmm7 + + movdqu xmm6,XMMWORD PTR[16+r8] +DB 102,15,56,0,221 +DB 102,15,56,0,245 + + movdqa xmm7,xmm6 + pshufd xmm9,xmm6,78 + pshufd xmm10,xmm2,78 + pxor xmm9,xmm6 + pxor xmm10,xmm2 + pxor xmm1,xmm3 + + movdqa xmm3,xmm0 + psllq xmm0,1 + pxor xmm0,xmm3 + psllq xmm0,5 + pxor xmm0,xmm3 +DB 102,15,58,68,242,0 + psllq xmm0,57 + movdqa xmm4,xmm0 + pslldq xmm0,8 + psrldq xmm4,8 + pxor xmm0,xmm3 + pxor xmm1,xmm4 + +DB 102,15,58,68,250,17 + movdqa xmm4,xmm0 + psrlq xmm0,5 + pxor xmm0,xmm4 + psrlq xmm0,1 + pxor xmm0,xmm4 + pxor xmm4,xmm1 + psrlq xmm0,1 + pxor xmm0,xmm4 + +DB 102,69,15,58,68,202,0 + movdqa xmm1,xmm0 + pshufd xmm3,xmm0,78 + pshufd xmm4,xmm8,78 + pxor xmm3,xmm0 + pxor xmm4,xmm8 + + pxor xmm9,xmm6 + pxor xmm9,xmm7 + movdqa xmm10,xmm9 + psrldq xmm9,8 + pslldq xmm10,8 + pxor xmm7,xmm9 + pxor xmm6,xmm10 + + lea r8,QWORD PTR[32+r8] + sub r9,020h + ja $L$mod_loop + +$L$even_tail:: +DB 102,65,15,58,68,192,0 +DB 102,65,15,58,68,200,17 +DB 102,15,58,68,220,0 + pxor xmm3,xmm0 + pxor xmm3,xmm1 + + movdqa xmm4,xmm3 + psrldq xmm3,8 + pslldq xmm4,8 + pxor xmm1,xmm3 + pxor xmm0,xmm4 + pxor xmm0,xmm6 + pxor xmm1,xmm7 + + movdqa xmm3,xmm0 + psllq xmm0,1 + pxor xmm0,xmm3 + psllq xmm0,5 + pxor xmm0,xmm3 + psllq xmm0,57 + movdqa xmm4,xmm0 + pslldq xmm0,8 + psrldq xmm4,8 + pxor xmm0,xmm3 + pxor xmm1,xmm4 + + + movdqa xmm4,xmm0 + psrlq xmm0,5 + pxor xmm0,xmm4 + psrlq xmm0,1 + pxor xmm0,xmm4 + pxor xmm4,xmm1 + psrlq xmm0,1 + pxor xmm0,xmm4 + test r9,r9 + jnz $L$done + +$L$odd_tail:: + movdqu xmm3,XMMWORD PTR[r8] +DB 102,15,56,0,221 + pxor xmm0,xmm3 + movdqa xmm1,xmm0 + pshufd xmm3,xmm0,78 + pshufd xmm4,xmm2,78 + pxor xmm3,xmm0 + pxor xmm4,xmm2 +DB 102,15,58,68,194,0 +DB 102,15,58,68,202,17 +DB 102,15,58,68,220,0 + pxor xmm3,xmm0 + pxor xmm3,xmm1 + + movdqa xmm4,xmm3 + psrldq xmm3,8 + pslldq xmm4,8 + pxor xmm1,xmm3 + pxor xmm0,xmm4 + + movdqa xmm3,xmm0 + psllq xmm0,1 + pxor xmm0,xmm3 + psllq xmm0,5 + pxor xmm0,xmm3 + psllq xmm0,57 + movdqa xmm4,xmm0 + pslldq xmm0,8 + psrldq xmm4,8 + pxor xmm0,xmm3 + pxor xmm1,xmm4 + + + movdqa xmm4,xmm0 + psrlq xmm0,5 + pxor xmm0,xmm4 + psrlq xmm0,1 + pxor xmm0,xmm4 + pxor xmm4,xmm1 + psrlq xmm0,1 + pxor xmm0,xmm4 +$L$done:: +DB 102,15,56,0,197 + movdqu XMMWORD PTR[rcx],xmm0 + movaps xmm6,XMMWORD PTR[rsp] + movaps xmm7,XMMWORD PTR[16+rsp] + movaps xmm8,XMMWORD PTR[32+rsp] + movaps xmm9,XMMWORD PTR[48+rsp] + movaps xmm10,XMMWORD PTR[64+rsp] + add rsp,058h + DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_ghash_clmul:: +gcm_ghash_clmul ENDP +ALIGN 64 +$L$bswap_mask:: +DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +$L$0x1c2_polynomial:: +DB 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0c2h +ALIGN 64 + +$L$rem_4bit:: + DD 0,0,0,471859200,0,943718400,0,610271232 + DD 0,1887436800,0,1822425088,0,1220542464,0,1423966208 + DD 0,3774873600,0,4246732800,0,3644850176,0,3311403008 + DD 0,2441084928,0,2376073216,0,2847932416,0,3051356160 + +$L$rem_8bit:: + DW 00000h,001C2h,00384h,00246h,00708h,006CAh,0048Ch,0054Eh + DW 00E10h,00FD2h,00D94h,00C56h,00918h,008DAh,00A9Ch,00B5Eh + DW 01C20h,01DE2h,01FA4h,01E66h,01B28h,01AEAh,018ACh,0196Eh + DW 01230h,013F2h,011B4h,01076h,01538h,014FAh,016BCh,0177Eh + DW 03840h,03982h,03BC4h,03A06h,03F48h,03E8Ah,03CCCh,03D0Eh + DW 03650h,03792h,035D4h,03416h,03158h,0309Ah,032DCh,0331Eh + DW 02460h,025A2h,027E4h,02626h,02368h,022AAh,020ECh,0212Eh + DW 02A70h,02BB2h,029F4h,02836h,02D78h,02CBAh,02EFCh,02F3Eh + DW 07080h,07142h,07304h,072C6h,07788h,0764Ah,0740Ch,075CEh + DW 07E90h,07F52h,07D14h,07CD6h,07998h,0785Ah,07A1Ch,07BDEh + DW 06CA0h,06D62h,06F24h,06EE6h,06BA8h,06A6Ah,0682Ch,069EEh + DW 062B0h,06372h,06134h,060F6h,065B8h,0647Ah,0663Ch,067FEh + DW 048C0h,04902h,04B44h,04A86h,04FC8h,04E0Ah,04C4Ch,04D8Eh + DW 046D0h,04712h,04554h,04496h,041D8h,0401Ah,0425Ch,0439Eh + DW 054E0h,05522h,05764h,056A6h,053E8h,0522Ah,0506Ch,051AEh + DW 05AF0h,05B32h,05974h,058B6h,05DF8h,05C3Ah,05E7Ch,05FBEh + DW 0E100h,0E0C2h,0E284h,0E346h,0E608h,0E7CAh,0E58Ch,0E44Eh + DW 0EF10h,0EED2h,0EC94h,0ED56h,0E818h,0E9DAh,0EB9Ch,0EA5Eh + DW 0FD20h,0FCE2h,0FEA4h,0FF66h,0FA28h,0FBEAh,0F9ACh,0F86Eh + DW 0F330h,0F2F2h,0F0B4h,0F176h,0F438h,0F5FAh,0F7BCh,0F67Eh + DW 0D940h,0D882h,0DAC4h,0DB06h,0DE48h,0DF8Ah,0DDCCh,0DC0Eh + DW 0D750h,0D692h,0D4D4h,0D516h,0D058h,0D19Ah,0D3DCh,0D21Eh + DW 0C560h,0C4A2h,0C6E4h,0C726h,0C268h,0C3AAh,0C1ECh,0C02Eh + DW 0CB70h,0CAB2h,0C8F4h,0C936h,0CC78h,0CDBAh,0CFFCh,0CE3Eh + DW 09180h,09042h,09204h,093C6h,09688h,0974Ah,0950Ch,094CEh + DW 09F90h,09E52h,09C14h,09DD6h,09898h,0995Ah,09B1Ch,09ADEh + DW 08DA0h,08C62h,08E24h,08FE6h,08AA8h,08B6Ah,0892Ch,088EEh + DW 083B0h,08272h,08034h,081F6h,084B8h,0857Ah,0873Ch,086FEh + DW 0A9C0h,0A802h,0AA44h,0AB86h,0AEC8h,0AF0Ah,0AD4Ch,0AC8Eh + DW 0A7D0h,0A612h,0A454h,0A596h,0A0D8h,0A11Ah,0A35Ch,0A29Eh + DW 0B5E0h,0B422h,0B664h,0B7A6h,0B2E8h,0B32Ah,0B16Ch,0B0AEh + DW 0BBF0h,0BA32h,0B874h,0B9B6h,0BCF8h,0BD3Ah,0BF7Ch,0BEBEh + +DB 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52 +DB 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 +DB 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 +DB 114,103,62,0 +ALIGN 64 +EXTERN __imp_RtlVirtualUnwind:NEAR + +ALIGN 16 +se_handler PROC PRIVATE + push rsi + push rdi + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + pushfq + sub rsp,64 + + mov rax,QWORD PTR[120+r8] + mov rbx,QWORD PTR[248+r8] + + mov rsi,QWORD PTR[8+r9] + mov r11,QWORD PTR[56+r9] + + mov r10d,DWORD PTR[r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jb $L$in_prologue + + mov rax,QWORD PTR[152+r8] + + mov r10d,DWORD PTR[4+r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jae $L$in_prologue + + lea rax,QWORD PTR[24+rax] + + mov rbx,QWORD PTR[((-8))+rax] + mov rbp,QWORD PTR[((-16))+rax] + mov r12,QWORD PTR[((-24))+rax] + mov QWORD PTR[144+r8],rbx + mov QWORD PTR[160+r8],rbp + mov QWORD PTR[216+r8],r12 + +$L$in_prologue:: + mov rdi,QWORD PTR[8+rax] + mov rsi,QWORD PTR[16+rax] + mov QWORD PTR[152+r8],rax + mov QWORD PTR[168+r8],rsi + mov QWORD PTR[176+r8],rdi + + mov rdi,QWORD PTR[40+r9] + mov rsi,r8 + mov ecx,154 + DD 0a548f3fch + + mov rsi,r9 + xor rcx,rcx + mov rdx,QWORD PTR[8+rsi] + mov r8,QWORD PTR[rsi] + mov r9,QWORD PTR[16+rsi] + mov r10,QWORD PTR[40+rsi] + lea r11,QWORD PTR[56+rsi] + lea r12,QWORD PTR[24+rsi] + mov QWORD PTR[32+rsp],r10 + mov QWORD PTR[40+rsp],r11 + mov QWORD PTR[48+rsp],r12 + mov QWORD PTR[56+rsp],rcx + call QWORD PTR[__imp_RtlVirtualUnwind] + + mov eax,1 + add rsp,64 + popfq + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + pop rdi + pop rsi + DB 0F3h,0C3h ;repret +se_handler ENDP + +.text$ ENDS +.pdata SEGMENT READONLY ALIGN(4) +ALIGN 4 + DD imagerel $L$SEH_begin_gcm_gmult_4bit + DD imagerel $L$SEH_end_gcm_gmult_4bit + DD imagerel $L$SEH_info_gcm_gmult_4bit + + DD imagerel $L$SEH_begin_gcm_ghash_4bit + DD imagerel $L$SEH_end_gcm_ghash_4bit + DD imagerel $L$SEH_info_gcm_ghash_4bit + + DD imagerel $L$SEH_begin_gcm_ghash_clmul + DD imagerel $L$SEH_end_gcm_ghash_clmul + DD imagerel $L$SEH_info_gcm_ghash_clmul + +.pdata ENDS +.xdata SEGMENT READONLY ALIGN(8) +ALIGN 8 +$L$SEH_info_gcm_gmult_4bit:: +DB 9,0,0,0 + DD imagerel se_handler + DD imagerel $L$gmult_prologue,imagerel $L$gmult_epilogue +$L$SEH_info_gcm_ghash_4bit:: +DB 9,0,0,0 + DD imagerel se_handler + DD imagerel $L$ghash_prologue,imagerel $L$ghash_epilogue +$L$SEH_info_gcm_ghash_clmul:: +DB 001h,01fh,00bh,000h +DB 01fh,0a8h,004h,000h +DB 019h,098h,003h,000h +DB 013h,088h,002h,000h +DB 00dh,078h,001h,000h +DB 008h,068h,000h,000h +DB 004h,0a2h,000h,000h + +.xdata ENDS +END + diff --git a/Libraries/libressl/crypto/modes/ghash-mingw64-x86_64.S b/Libraries/libressl/crypto/modes/ghash-mingw64-x86_64.S new file mode 100644 index 000000000..cd0823b45 --- /dev/null +++ b/Libraries/libressl/crypto/modes/ghash-mingw64-x86_64.S @@ -0,0 +1,1175 @@ +#include "x86_arch.h" +.text + +.globl gcm_gmult_4bit +.def gcm_gmult_4bit; .scl 2; .type 32; .endef +.p2align 4 +gcm_gmult_4bit: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_gcm_gmult_4bit: + movq %rcx,%rdi + movq %rdx,%rsi + + pushq %rbx + pushq %rbp + pushq %r12 +.Lgmult_prologue: + + movzbq 15(%rdi),%r8 + leaq .Lrem_4bit(%rip),%r11 + xorq %rax,%rax + xorq %rbx,%rbx + movb %r8b,%al + movb %r8b,%bl + shlb $4,%al + movq $14,%rcx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + andb $240,%bl + movq %r8,%rdx + jmp .Loop1 + +.p2align 4 +.Loop1: + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + movb (%rdi,%rcx,1),%al + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + movb %al,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + shlb $4,%al + xorq %r10,%r8 + decq %rcx + js .Lbreak1 + + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $240,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + jmp .Loop1 + +.p2align 4 +.Lbreak1: + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $240,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + + shrq $4,%r8 + andq $15,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + xorq %r10,%r8 + xorq (%r11,%rdx,8),%r9 + + bswapq %r8 + bswapq %r9 + movq %r8,8(%rdi) + movq %r9,(%rdi) + + movq 16(%rsp),%rbx + leaq 24(%rsp),%rsp +.Lgmult_epilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_gcm_gmult_4bit: +.globl gcm_ghash_4bit +.def gcm_ghash_4bit; .scl 2; .type 32; .endef +.p2align 4 +gcm_ghash_4bit: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_gcm_ghash_4bit: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $280,%rsp +.Lghash_prologue: + movq %rdx,%r14 + movq %rcx,%r15 + subq $-128,%rsi + leaq 16+128(%rsp),%rbp + xorl %edx,%edx + movq 0+0-128(%rsi),%r8 + movq 0+8-128(%rsi),%rax + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq 16+0-128(%rsi),%r9 + shlb $4,%dl + movq 16+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,0(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,0(%rbp) + movq 32+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,0-128(%rbp) + movq 32+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,1(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,8(%rbp) + movq 48+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,8-128(%rbp) + movq 48+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,2(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,16(%rbp) + movq 64+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,16-128(%rbp) + movq 64+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,3(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,24(%rbp) + movq 80+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,24-128(%rbp) + movq 80+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,4(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,32(%rbp) + movq 96+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,32-128(%rbp) + movq 96+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,5(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,40(%rbp) + movq 112+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,40-128(%rbp) + movq 112+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,6(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,48(%rbp) + movq 128+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,48-128(%rbp) + movq 128+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,7(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,56(%rbp) + movq 144+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,56-128(%rbp) + movq 144+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,8(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,64(%rbp) + movq 160+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,64-128(%rbp) + movq 160+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,9(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,72(%rbp) + movq 176+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,72-128(%rbp) + movq 176+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,10(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,80(%rbp) + movq 192+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,80-128(%rbp) + movq 192+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,11(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,88(%rbp) + movq 208+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,88-128(%rbp) + movq 208+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,12(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,96(%rbp) + movq 224+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,96-128(%rbp) + movq 224+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,13(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,104(%rbp) + movq 240+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,104-128(%rbp) + movq 240+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,14(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,112(%rbp) + shlb $4,%dl + movq %rax,112-128(%rbp) + shlq $60,%r10 + movb %dl,15(%rsp) + orq %r10,%rbx + movq %r9,120(%rbp) + movq %rbx,120-128(%rbp) + addq $-128,%rsi + movq 8(%rdi),%r8 + movq 0(%rdi),%r9 + addq %r14,%r15 + leaq .Lrem_8bit(%rip),%r11 + jmp .Louter_loop +.p2align 4 +.Louter_loop: + xorq (%r14),%r9 + movq 8(%r14),%rdx + leaq 16(%r14),%r14 + xorq %r8,%rdx + movq %r9,(%rdi) + movq %rdx,8(%rdi) + shrq $32,%rdx + xorq %rax,%rax + roll $8,%edx + movb %dl,%al + movzbl %dl,%ebx + shlb $4,%al + shrl $4,%ebx + roll $8,%edx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + movb %dl,%al + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + xorq %r8,%r12 + movq %r9,%r10 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 8(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 0(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + andl $240,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl -4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + movzwq (%r11,%r12,2),%r12 + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + shlq $48,%r12 + xorq %r10,%r8 + xorq %r12,%r9 + movzbq %r8b,%r13 + shrq $4,%r8 + movq %r9,%r10 + shlb $4,%r13b + shrq $4,%r9 + xorq 8(%rsi,%rcx,1),%r8 + movzwq (%r11,%r13,2),%r13 + shlq $60,%r10 + xorq (%rsi,%rcx,1),%r9 + xorq %r10,%r8 + shlq $48,%r13 + bswapq %r8 + xorq %r13,%r9 + bswapq %r9 + cmpq %r15,%r14 + jb .Louter_loop + movq %r8,8(%rdi) + movq %r9,(%rdi) + + leaq 280(%rsp),%rsi + movq 0(%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lghash_epilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_gcm_ghash_4bit: +.globl gcm_init_clmul +.def gcm_init_clmul; .scl 2; .type 32; .endef +.p2align 4 +gcm_init_clmul: + movdqu (%rdx),%xmm2 + pshufd $78,%xmm2,%xmm2 + + + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + + + pand .L0x1c2_polynomial(%rip),%xmm5 + pxor %xmm5,%xmm2 + + + movdqa %xmm2,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + movdqu %xmm2,(%rcx) + movdqu %xmm0,16(%rcx) + retq + +.globl gcm_gmult_clmul +.def gcm_gmult_clmul; .scl 2; .type 32; .endef +.p2align 4 +gcm_gmult_clmul: + movdqu (%rcx),%xmm0 + movdqa .Lbswap_mask(%rip),%xmm5 + movdqu (%rdx),%xmm2 +.byte 102,15,56,0,197 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%rcx) + retq + +.globl gcm_ghash_clmul +.def gcm_ghash_clmul; .scl 2; .type 32; .endef +.p2align 4 +gcm_ghash_clmul: +.LSEH_begin_gcm_ghash_clmul: + +.byte 0x48,0x83,0xec,0x58 +.byte 0x0f,0x29,0x34,0x24 +.byte 0x0f,0x29,0x7c,0x24,0x10 +.byte 0x44,0x0f,0x29,0x44,0x24,0x20 +.byte 0x44,0x0f,0x29,0x4c,0x24,0x30 +.byte 0x44,0x0f,0x29,0x54,0x24,0x40 + movdqa .Lbswap_mask(%rip),%xmm5 + + movdqu (%rcx),%xmm0 + movdqu (%rdx),%xmm2 +.byte 102,15,56,0,197 + + subq $16,%r9 + jz .Lodd_tail + + movdqu 16(%rdx),%xmm8 + + + + + + movdqu (%r8),%xmm3 + movdqu 16(%r8),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + pxor %xmm3,%xmm0 + movdqa %xmm6,%xmm7 + pshufd $78,%xmm6,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm6,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,242,0 +.byte 102,15,58,68,250,17 +.byte 102,15,58,68,220,0 + pxor %xmm6,%xmm3 + pxor %xmm7,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm7 + pxor %xmm4,%xmm6 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm8,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm8,%xmm4 + + leaq 32(%r8),%r8 + subq $32,%r9 + jbe .Leven_tail + +.Lmod_loop: +.byte 102,65,15,58,68,192,0 +.byte 102,65,15,58,68,200,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqu (%r8),%xmm3 + pxor %xmm6,%xmm0 + pxor %xmm7,%xmm1 + + movdqu 16(%r8),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + + movdqa %xmm6,%xmm7 + pshufd $78,%xmm6,%xmm9 + pshufd $78,%xmm2,%xmm10 + pxor %xmm6,%xmm9 + pxor %xmm2,%xmm10 + pxor %xmm3,%xmm1 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 +.byte 102,15,58,68,242,0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + +.byte 102,15,58,68,250,17 + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + +.byte 102,69,15,58,68,202,0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm8,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm8,%xmm4 + + pxor %xmm6,%xmm9 + pxor %xmm7,%xmm9 + movdqa %xmm9,%xmm10 + psrldq $8,%xmm9 + pslldq $8,%xmm10 + pxor %xmm9,%xmm7 + pxor %xmm10,%xmm6 + + leaq 32(%r8),%r8 + subq $32,%r9 + ja .Lmod_loop + +.Leven_tail: +.byte 102,65,15,58,68,192,0 +.byte 102,65,15,58,68,200,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm6,%xmm0 + pxor %xmm7,%xmm1 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + testq %r9,%r9 + jnz .Ldone + +.Lodd_tail: + movdqu (%r8),%xmm3 +.byte 102,15,56,0,221 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $5,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm4 + pslldq $8,%xmm0 + psrldq $8,%xmm4 + pxor %xmm3,%xmm0 + pxor %xmm4,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm0 +.Ldone: +.byte 102,15,56,0,197 + movdqu %xmm0,(%rcx) + movaps (%rsp),%xmm6 + movaps 16(%rsp),%xmm7 + movaps 32(%rsp),%xmm8 + movaps 48(%rsp),%xmm9 + movaps 64(%rsp),%xmm10 + addq $88,%rsp + retq +.LSEH_end_gcm_ghash_clmul: + +.p2align 6 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.L0x1c2_polynomial: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.p2align 6 + +.Lrem_4bit: +.long 0,0,0,471859200,0,943718400,0,610271232 +.long 0,1887436800,0,1822425088,0,1220542464,0,1423966208 +.long 0,3774873600,0,4246732800,0,3644850176,0,3311403008 +.long 0,2441084928,0,2376073216,0,2847932416,0,3051356160 + +.Lrem_8bit: +.value 0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E +.value 0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E +.value 0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E +.value 0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E +.value 0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E +.value 0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E +.value 0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E +.value 0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E +.value 0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE +.value 0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE +.value 0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE +.value 0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE +.value 0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E +.value 0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E +.value 0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE +.value 0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE +.value 0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E +.value 0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E +.value 0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E +.value 0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E +.value 0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E +.value 0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E +.value 0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E +.value 0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E +.value 0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE +.value 0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE +.value 0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE +.value 0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE +.value 0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E +.value 0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E +.value 0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE +.value 0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE + +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 + +.def se_handler; .scl 3; .type 32; .endef +.p2align 4 +se_handler: + pushq %rsi + pushq %rdi + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushfq + subq $64,%rsp + + movq 120(%r8),%rax + movq 248(%r8),%rbx + + movq 8(%r9),%rsi + movq 56(%r9),%r11 + + movl 0(%r11),%r10d + leaq (%rsi,%r10,1),%r10 + cmpq %r10,%rbx + jb .Lin_prologue + + movq 152(%r8),%rax + + movl 4(%r11),%r10d + leaq (%rsi,%r10,1),%r10 + cmpq %r10,%rbx + jae .Lin_prologue + + leaq 24(%rax),%rax + + movq -8(%rax),%rbx + movq -16(%rax),%rbp + movq -24(%rax),%r12 + movq %rbx,144(%r8) + movq %rbp,160(%r8) + movq %r12,216(%r8) + +.Lin_prologue: + movq 8(%rax),%rdi + movq 16(%rax),%rsi + movq %rax,152(%r8) + movq %rsi,168(%r8) + movq %rdi,176(%r8) + + movq 40(%r9),%rdi + movq %r8,%rsi + movl $154,%ecx +.long 0xa548f3fc + + movq %r9,%rsi + xorq %rcx,%rcx + movq 8(%rsi),%rdx + movq 0(%rsi),%r8 + movq 16(%rsi),%r9 + movq 40(%rsi),%r10 + leaq 56(%rsi),%r11 + leaq 24(%rsi),%r12 + movq %r10,32(%rsp) + movq %r11,40(%rsp) + movq %r12,48(%rsp) + movq %rcx,56(%rsp) + call *__imp_RtlVirtualUnwind(%rip) + + movl $1,%eax + addq $64,%rsp + popfq + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %rdi + popq %rsi + retq + + +.section .pdata +.p2align 2 +.rva .LSEH_begin_gcm_gmult_4bit +.rva .LSEH_end_gcm_gmult_4bit +.rva .LSEH_info_gcm_gmult_4bit + +.rva .LSEH_begin_gcm_ghash_4bit +.rva .LSEH_end_gcm_ghash_4bit +.rva .LSEH_info_gcm_ghash_4bit + +.rva .LSEH_begin_gcm_ghash_clmul +.rva .LSEH_end_gcm_ghash_clmul +.rva .LSEH_info_gcm_ghash_clmul + +.section .xdata +.p2align 3 +.LSEH_info_gcm_gmult_4bit: +.byte 9,0,0,0 +.rva se_handler +.rva .Lgmult_prologue,.Lgmult_epilogue +.LSEH_info_gcm_ghash_4bit: +.byte 9,0,0,0 +.rva se_handler +.rva .Lghash_prologue,.Lghash_epilogue +.LSEH_info_gcm_ghash_clmul: +.byte 0x01,0x1f,0x0b,0x00 +.byte 0x1f,0xa8,0x04,0x00 +.byte 0x19,0x98,0x03,0x00 +.byte 0x13,0x88,0x02,0x00 +.byte 0x0d,0x78,0x01,0x00 +.byte 0x08,0x68,0x00,0x00 +.byte 0x04,0xa2,0x00,0x00 diff --git a/Libraries/libressl/crypto/modes/modes_local.h b/Libraries/libressl/crypto/modes/modes_local.h new file mode 100644 index 000000000..852ba1922 --- /dev/null +++ b/Libraries/libressl/crypto/modes/modes_local.h @@ -0,0 +1,123 @@ +/* $OpenBSD: modes_local.h,v 1.2 2023/07/08 14:55:36 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use is governed by OpenSSL license. + * ==================================================================== + */ + +#include + +#include + +#include + +__BEGIN_HIDDEN_DECLS + +#if defined(_LP64) +typedef long i64; +typedef unsigned long u64; +#define U64(C) C##UL +#else +typedef long long i64; +typedef unsigned long long u64; +#define U64(C) C##ULL +#endif + +typedef unsigned int u32; +typedef unsigned char u8; + +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +#if defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# define BSWAP8(x) ({ u64 ret=(x); \ + asm ("bswapq %0" \ + : "+r"(ret)); ret; }) +# define BSWAP4(x) ({ u32 ret=(x); \ + asm ("bswapl %0" \ + : "+r"(ret)); ret; }) +# elif (defined(__i386) || defined(__i386__)) +# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ + asm ("bswapl %0; bswapl %1" \ + : "+r"(hi),"+r"(lo)); \ + (u64)hi<<32|lo; }) +# define BSWAP4(x) ({ u32 ret=(x); \ + asm ("bswapl %0" \ + : "+r"(ret)); ret; }) +# elif (defined(__arm__) || defined(__arm)) && !defined(__STRICT_ALIGNMENT) +# if (__ARM_ARCH >= 6) +# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ + asm ("rev %0,%0; rev %1,%1" \ + : "+r"(hi),"+r"(lo)); \ + (u64)hi<<32|lo; }) +# define BSWAP4(x) ({ u32 ret; \ + asm ("rev %0,%1" \ + : "=r"(ret) : "r"((u32)(x))); \ + ret; }) +# endif +# endif +#endif +#endif + +#if defined(BSWAP4) && !defined(__STRICT_ALIGNMENT) +#define GETU32(p) BSWAP4(*(const u32 *)(p)) +#define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) +#else +#define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) +#define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) +#endif + +/* GCM definitions */ + +typedef struct { + u64 hi, lo; +} u128; + +#ifdef TABLE_BITS +#undef TABLE_BITS +#endif +/* + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8 [or 1]. For further information see gcm128.c. + */ +#define TABLE_BITS 4 + +struct gcm128_context { + /* Following 6 names follow names in GCM specification */ + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + size_t t[16/sizeof(size_t)]; + } Yi, EKi, EK0, len, Xi, H; + /* Relative position of Xi, H and pre-computed Htable is used + * in some assembler modules, i.e. don't change the order! */ +#if TABLE_BITS==8 + u128 Htable[256]; +#else + u128 Htable[16]; + void (*gmult)(u64 Xi[2], const u128 Htable[16]); + void (*ghash)(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +#endif + unsigned int mres, ares; + block128_f block; + void *key; +}; + +struct xts128_context { + void *key1, *key2; + block128_f block1, block2; +}; + +struct ccm128_context { + union { + u64 u[2]; + u8 c[16]; + } nonce, cmac; + u64 blocks; + block128_f block; + void *key; +}; + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/modes/ofb128.c b/Libraries/libressl/crypto/modes/ofb128.c new file mode 100644 index 000000000..42afd29d5 --- /dev/null +++ b/Libraries/libressl/crypto/modes/ofb128.c @@ -0,0 +1,124 @@ +/* $OpenBSD: ofb128.c,v 1.7 2023/07/08 14:56:54 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_local.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +/* The input and output encrypted as though 128bit ofb mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num; + */ +void +CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block) +{ + unsigned int n; + size_t l = 0; + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) + do { /* always true actually */ + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n + 1) % 16; + } +#ifdef __STRICT_ALIGNMENT + if (((size_t)in|(size_t)out|(size_t)ivec) % + sizeof(size_t) != 0) + break; +#endif + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(ivec + + n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + out[n] = in[n] ^ ivec[n]; + ++n; + } + } + *num = n; + return; + } while (0); + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block)(ivec, ivec, key); + } + out[l] = in[l] ^ ivec[n]; + ++l; + n = (n + 1) % 16; + } + + *num = n; +} +LCRYPTO_ALIAS(CRYPTO_ofb128_encrypt); diff --git a/Libraries/libressl/crypto/modes/xts128.c b/Libraries/libressl/crypto/modes/xts128.c new file mode 100644 index 000000000..7516acf85 --- /dev/null +++ b/Libraries/libressl/crypto/modes/xts128.c @@ -0,0 +1,197 @@ +/* $OpenBSD: xts128.c,v 1.12 2023/07/08 14:56:54 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "modes_local.h" + +#include +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +int +CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc) +{ + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + } tweak, scratch; + unsigned int i; + + if (len < 16) + return -1; + + memcpy(tweak.c, iv, 16); + + (*ctx->block2)(tweak.c, tweak.c, ctx->key2); + + if (!enc && (len % 16)) + len -= 16; + + while (len >= 16) { +#ifdef __STRICT_ALIGNMENT + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; +#else + scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0]; + scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1]; +#endif + (*ctx->block1)(scratch.c, scratch.c, ctx->key1); +#ifdef __STRICT_ALIGNMENT + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0]; + ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1]; +#endif + inp += 16; + out += 16; + len -= 16; + + if (len == 0) + return 0; + +#if BYTE_ORDER == LITTLE_ENDIAN + unsigned int carry, res; + + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak.u[0] = (tweak.u[0] << 1) ^ res; + tweak.u[1] = (tweak.u[1] << 1)|carry; +#else /* BIG_ENDIAN */ + size_t c; + + for (c = 0, i = 0; i < 16; ++i) { + /*+ substitutes for |, because c is 1 bit */ + c += ((size_t)tweak.c[i]) << 1; + tweak.c[i] = (u8)c; + c = c >> 8; + } + tweak.c[0] ^= (u8)(0x87 & (0 - c)); +#endif + } + if (enc) { + for (i = 0; i < len; ++i) { + u8 ch = inp[i]; + out[i] = scratch.c[i]; + scratch.c[i] = ch; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1)(scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out - 16, scratch.c, 16); + } else { + union { + u64 u[2]; + u8 c[16]; + } tweak1; + +#if BYTE_ORDER == LITTLE_ENDIAN + unsigned int carry, res; + + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak1.u[0] = (tweak.u[0] << 1) ^ res; + tweak1.u[1] = (tweak.u[1] << 1)|carry; +#else + size_t c; + + for (c = 0, i = 0; i < 16; ++i) { + /*+ substitutes for |, because c is 1 bit */ + c += ((size_t)tweak.c[i]) << 1; + tweak1.c[i] = (u8)c; + c = c >> 8; + } + tweak1.c[0] ^= (u8)(0x87 & (0 - c)); +#endif +#ifdef __STRICT_ALIGNMENT + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; +#else + scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0]; + scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1]; +#endif + (*ctx->block1)(scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; + + for (i = 0; i < len; ++i) { + u8 ch = inp[16 + i]; + out[16 + i] = scratch.c[i]; + scratch.c[i] = ch; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1)(scratch.c, scratch.c, ctx->key1); +#ifdef __STRICT_ALIGNMENT + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0]; + ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1]; +#endif + } + + return 0; +} +LCRYPTO_ALIAS(CRYPTO_xts128_encrypt); diff --git a/Libraries/libressl/crypto/o_fips.c b/Libraries/libressl/crypto/o_fips.c new file mode 100644 index 000000000..b1487e3be --- /dev/null +++ b/Libraries/libressl/crypto/o_fips.c @@ -0,0 +1,76 @@ +/* $OpenBSD: o_fips.c,v 1.6 2021/10/23 13:57:00 schwarze Exp $ */ +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL + * project 2011. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "cryptlib.h" + +int +FIPS_mode(void) +{ + return 0; +} + +int +FIPS_mode_set(int r) +{ + if (r == 0) + return 1; + CRYPTOerror(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED); + return 0; +} diff --git a/Libraries/libressl/crypto/o_init.c b/Libraries/libressl/crypto/o_init.c new file mode 100644 index 000000000..2f819eac9 --- /dev/null +++ b/Libraries/libressl/crypto/o_init.c @@ -0,0 +1,10 @@ +/* $OpenBSD: o_init.c,v 1.8 2014/06/12 15:49:27 deraadt Exp $ */ +/* Ted Unangst places this file in the public domain. */ + +#include + +void +OPENSSL_init(void) +{ + +} diff --git a/Libraries/libressl/crypto/o_str.c b/Libraries/libressl/crypto/o_str.c new file mode 100644 index 000000000..f05889e4c --- /dev/null +++ b/Libraries/libressl/crypto/o_str.c @@ -0,0 +1,21 @@ +/* $OpenBSD: o_str.c,v 1.9 2014/07/09 20:22:14 tedu Exp $ */ +/* + * Written by Theo de Raadt. Public domain. + */ + +#include + +int OPENSSL_strcasecmp(const char *str1, const char *str2); +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n); + +int +OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) +{ + return strncasecmp(str1, str2, n); +} + +int +OPENSSL_strcasecmp(const char *str1, const char *str2) +{ + return strcasecmp(str1, str2); +} diff --git a/Libraries/libressl/crypto/objects/o_names.c b/Libraries/libressl/crypto/objects/o_names.c new file mode 100644 index 000000000..48b95d676 --- /dev/null +++ b/Libraries/libressl/crypto/objects/o_names.c @@ -0,0 +1,363 @@ +/* $OpenBSD: o_names.c,v 1.24 2023/07/08 12:27:51 beck Exp $ */ +#include +#include +#include + +#include + +#include +#include +#include +#include + +/* I use the ex_data stuff to manage the identifiers for the obj_name_types + * that applications may define. I only really use the free function field. + */ +DECLARE_LHASH_OF(OBJ_NAME); +static LHASH_OF(OBJ_NAME) *names_lh = NULL; +static int names_type_num = OBJ_NAME_TYPE_NUM; + +typedef struct name_funcs_st { + unsigned long (*hash_func)(const char *name); + int (*cmp_func)(const char *a, const char *b); + void (*free_func)(const char *, int, const char *); +} NAME_FUNCS; + +DECLARE_STACK_OF(NAME_FUNCS) + +static STACK_OF(NAME_FUNCS) *name_funcs_stack; + +/* The LHASH callbacks now use the raw "void *" prototypes and do per-variable + * casting in the functions. This prevents function pointer casting without the + * need for macro-generated wrapper functions. */ + +/* static unsigned long obj_name_hash(OBJ_NAME *a); */ +static unsigned long obj_name_hash(const void *a_void); +/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ +static int obj_name_cmp(const void *a_void, const void *b_void); + +static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) +static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) + +int +OBJ_NAME_init(void) +{ + if (names_lh != NULL) + return (1); + names_lh = lh_OBJ_NAME_new(); + return (names_lh != NULL); +} +LCRYPTO_ALIAS(OBJ_NAME_init); + +int +OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), + int (*cmp_func)(const char *, const char *), + void (*free_func)(const char *, int, const char *)) +{ + int ret; + int i; + NAME_FUNCS *name_funcs; + + if (name_funcs_stack == NULL) + name_funcs_stack = sk_NAME_FUNCS_new_null(); + if (name_funcs_stack == NULL) + return (0); + + ret = names_type_num; + names_type_num++; + for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { + name_funcs = malloc(sizeof(NAME_FUNCS)); + if (!name_funcs) { + OBJerror(ERR_R_MALLOC_FAILURE); + return (0); + } + name_funcs->hash_func = lh_strhash; + name_funcs->cmp_func = strcmp; + name_funcs->free_func = NULL; + if (sk_NAME_FUNCS_push(name_funcs_stack, name_funcs) == 0) { + free(name_funcs); + OBJerror(ERR_R_MALLOC_FAILURE); + return (0); + } + } + name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); + if (hash_func != NULL) + name_funcs->hash_func = hash_func; + if (cmp_func != NULL) + name_funcs->cmp_func = cmp_func; + if (free_func != NULL) + name_funcs->free_func = free_func; + return (ret); +} +LCRYPTO_ALIAS(OBJ_NAME_new_index); + +/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ +static int +obj_name_cmp(const void *a_void, const void *b_void) +{ + int ret; + const OBJ_NAME *a = (const OBJ_NAME *)a_void; + const OBJ_NAME *b = (const OBJ_NAME *)b_void; + + ret = a->type - b->type; + if (ret == 0) { + if ((name_funcs_stack != NULL) && + (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { + ret = sk_NAME_FUNCS_value(name_funcs_stack, + a->type)->cmp_func(a->name, b->name); + } else + ret = strcmp(a->name, b->name); + } + return (ret); +} + +/* static unsigned long obj_name_hash(OBJ_NAME *a) */ +static unsigned long +obj_name_hash(const void *a_void) +{ + unsigned long ret; + const OBJ_NAME *a = (const OBJ_NAME *)a_void; + + if ((name_funcs_stack != NULL) && + (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { + ret = sk_NAME_FUNCS_value(name_funcs_stack, + a->type)->hash_func(a->name); + } else { + ret = lh_strhash(a->name); + } + ret ^= a->type; + return (ret); +} + +const char * +OBJ_NAME_get(const char *name, int type) +{ + OBJ_NAME on, *ret; + int num = 0, alias; + + if (name == NULL) + return (NULL); + if ((names_lh == NULL) && !OBJ_NAME_init()) + return (NULL); + + alias = type&OBJ_NAME_ALIAS; + type&= ~OBJ_NAME_ALIAS; + + on.name = name; + on.type = type; + + for (;;) { + ret = lh_OBJ_NAME_retrieve(names_lh, &on); + if (ret == NULL) + return (NULL); + if ((ret->alias) && !alias) { + if (++num > 10) + return (NULL); + on.name = ret->data; + } else { + return (ret->data); + } + } +} +LCRYPTO_ALIAS(OBJ_NAME_get); + +int +OBJ_NAME_add(const char *name, int type, const char *data) +{ + OBJ_NAME *onp, *ret; + int alias; + + if ((names_lh == NULL) && !OBJ_NAME_init()) + return (0); + + alias = type & OBJ_NAME_ALIAS; + type &= ~OBJ_NAME_ALIAS; + + onp = malloc(sizeof(OBJ_NAME)); + if (onp == NULL) { + /* ERROR */ + return (0); + } + + onp->name = name; + onp->alias = alias; + onp->type = type; + onp->data = data; + + ret = lh_OBJ_NAME_insert(names_lh, onp); + if (ret != NULL) { + /* free things */ + if ((name_funcs_stack != NULL) && + (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { + /* XXX: I'm not sure I understand why the free + * function should get three arguments... + * -- Richard Levitte + */ + sk_NAME_FUNCS_value( + name_funcs_stack, ret->type)->free_func( + ret->name, ret->type, ret->data); + } + free(ret); + } else { + if (lh_OBJ_NAME_error(names_lh)) { + free(onp); + /* ERROR */ + return (0); + } + } + return (1); +} +LCRYPTO_ALIAS(OBJ_NAME_add); + +int +OBJ_NAME_remove(const char *name, int type) +{ + OBJ_NAME on, *ret; + + if (names_lh == NULL) + return (0); + + type &= ~OBJ_NAME_ALIAS; + on.name = name; + on.type = type; + ret = lh_OBJ_NAME_delete(names_lh, &on); + if (ret != NULL) { + /* free things */ + if ((name_funcs_stack != NULL) && + (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { + /* XXX: I'm not sure I understand why the free + * function should get three arguments... + * -- Richard Levitte + */ + sk_NAME_FUNCS_value( + name_funcs_stack, ret->type)->free_func( + ret->name, ret->type, ret->data); + } + free(ret); + return (1); + } else + return (0); +} +LCRYPTO_ALIAS(OBJ_NAME_remove); + +struct doall { + int type; + void (*fn)(const OBJ_NAME *, void *arg); + void *arg; +}; + +static void +do_all_fn_doall_arg(const OBJ_NAME *name, struct doall *d) +{ + if (name->type == d->type) + d->fn(name, d->arg); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) + +void +OBJ_NAME_do_all(int type, void (*fn)(const OBJ_NAME *, void *arg), void *arg) +{ + struct doall d; + + d.type = type; + d.fn = fn; + d.arg = arg; + + lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), + struct doall, &d); +} +LCRYPTO_ALIAS(OBJ_NAME_do_all); + +struct doall_sorted { + int type; + int n; + const OBJ_NAME **names; +}; + +static void +do_all_sorted_fn(const OBJ_NAME *name, void *d_) +{ + struct doall_sorted *d = d_; + + if (name->type != d->type) + return; + + d->names[d->n++] = name; +} + +static int +do_all_sorted_cmp(const void *n1_, const void *n2_) +{ + const OBJ_NAME * const *n1 = n1_; + const OBJ_NAME * const *n2 = n2_; + + return strcmp((*n1)->name, (*n2)->name); +} + +void +OBJ_NAME_do_all_sorted(int type, void (*fn)(const OBJ_NAME *, void *arg), + void *arg) +{ + struct doall_sorted d; + int n; + + d.type = type; + d.names = reallocarray(NULL, lh_OBJ_NAME_num_items(names_lh), + sizeof *d.names); + d.n = 0; + if (d.names != NULL) { + OBJ_NAME_do_all(type, do_all_sorted_fn, &d); + + qsort((void *)d.names, d.n, sizeof *d.names, do_all_sorted_cmp); + + for (n = 0; n < d.n; ++n) + fn(d.names[n], arg); + + free(d.names); + } +} +LCRYPTO_ALIAS(OBJ_NAME_do_all_sorted); + +static int free_type; + +static void +names_lh_free_doall(OBJ_NAME *onp) +{ + if (onp == NULL) + return; + + if (free_type < 0 || free_type == onp->type) + OBJ_NAME_remove(onp->name, onp->type); +} + +static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) + +static void +name_funcs_free(NAME_FUNCS *ptr) +{ + free(ptr); +} + +void +OBJ_NAME_cleanup(int type) +{ + unsigned long down_load; + + if (names_lh == NULL) + return; + + free_type = type; + down_load = lh_OBJ_NAME_down_load(names_lh); + lh_OBJ_NAME_down_load(names_lh) = 0; + + lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free)); + if (type < 0) { + lh_OBJ_NAME_free(names_lh); + sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free); + names_lh = NULL; + name_funcs_stack = NULL; + } else + lh_OBJ_NAME_down_load(names_lh) = down_load; +} +LCRYPTO_ALIAS(OBJ_NAME_cleanup); diff --git a/Libraries/libressl/crypto/objects/obj_dat.c b/Libraries/libressl/crypto/objects/obj_dat.c new file mode 100644 index 000000000..6cfbf8f77 --- /dev/null +++ b/Libraries/libressl/crypto/objects/obj_dat.c @@ -0,0 +1,698 @@ +/* $OpenBSD: obj_dat.c,v 1.61 2023/09/05 14:59:00 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "asn1_local.h" + +/* obj_dat.h is generated from objects.h by obj_dat.pl */ +#include "obj_dat.h" + +static int sn_cmp_BSEARCH_CMP_FN(const void *, const void *); +static int sn_cmp(const ASN1_OBJECT * const *, unsigned int const *); +static unsigned int *OBJ_bsearch_sn(const ASN1_OBJECT * *key, unsigned int const *base, int num); +static int ln_cmp_BSEARCH_CMP_FN(const void *, const void *); +static int ln_cmp(const ASN1_OBJECT * const *, unsigned int const *); +static unsigned int *OBJ_bsearch_ln(const ASN1_OBJECT * *key, unsigned int const *base, int num); +static int obj_cmp_BSEARCH_CMP_FN(const void *, const void *); +static int obj_cmp(const ASN1_OBJECT * const *, unsigned int const *); +static unsigned int *OBJ_bsearch_obj(const ASN1_OBJECT * *key, unsigned int const *base, int num); + +#define ADDED_DATA 0 +#define ADDED_SNAME 1 +#define ADDED_LNAME 2 +#define ADDED_NID 3 + +typedef struct added_obj_st { + int type; + ASN1_OBJECT *obj; +} ADDED_OBJ; +DECLARE_LHASH_OF(ADDED_OBJ); + +static int new_nid = NUM_NID; +static LHASH_OF(ADDED_OBJ) *added = NULL; + +static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b) +{ + return (strcmp((*a)->sn, nid_objs[*b].sn)); +} + + +static int +sn_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + const ASN1_OBJECT * const *a = a_; + unsigned int const *b = b_; + return sn_cmp(a, b); +} + +static unsigned int * +OBJ_bsearch_sn(const ASN1_OBJECT * *key, unsigned int const *base, int num) +{ + return (unsigned int *)OBJ_bsearch_(key, base, num, sizeof(unsigned int), + sn_cmp_BSEARCH_CMP_FN); +} + +static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b) +{ + return (strcmp((*a)->ln, nid_objs[*b].ln)); +} + + +static int +ln_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + const ASN1_OBJECT * const *a = a_; + unsigned int const *b = b_; + return ln_cmp(a, b); +} + +static unsigned int * +OBJ_bsearch_ln(const ASN1_OBJECT * *key, unsigned int const *base, int num) +{ + return (unsigned int *)OBJ_bsearch_(key, base, num, sizeof(unsigned int), + ln_cmp_BSEARCH_CMP_FN); +} + +static unsigned long +added_obj_hash(const ADDED_OBJ *ca) +{ + const ASN1_OBJECT *a; + int i; + unsigned long ret = 0; + unsigned char *p; + + a = ca->obj; + switch (ca->type) { + case ADDED_DATA: + ret = a->length << 20L; + p = (unsigned char *)a->data; + for (i = 0; i < a->length; i++) + ret ^= p[i] << ((i * 3) % 24); + break; + case ADDED_SNAME: + ret = lh_strhash(a->sn); + break; + case ADDED_LNAME: + ret = lh_strhash(a->ln); + break; + case ADDED_NID: + ret = a->nid; + break; + default: + return 0; + } + ret &= 0x3fffffffL; + ret |= ca->type << 30L; + return (ret); +} +static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) + +static int +added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) +{ + const ASN1_OBJECT *a, *b; + int cmp; + + if ((cmp = ca->type - cb->type) != 0) + return cmp; + + a = ca->obj; + b = cb->obj; + switch (ca->type) { + case ADDED_DATA: + return OBJ_cmp(a, b); + case ADDED_SNAME: + if (a->sn == NULL) + return -1; + if (b->sn == NULL) + return 1; + return strcmp(a->sn, b->sn); + case ADDED_LNAME: + if (a->ln == NULL) + return -1; + if (b->ln == NULL) + return 1; + return strcmp(a->ln, b->ln); + case ADDED_NID: + return a->nid - b->nid; + default: + return 0; + } +} +static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) + +static void +cleanup1_doall(ADDED_OBJ *a) +{ + a->obj->nid = 0; + a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA; +} + +static void cleanup2_doall(ADDED_OBJ *a) +{ + a->obj->nid++; +} + +static void +cleanup3_doall(ADDED_OBJ *a) +{ + if (--a->obj->nid == 0) + ASN1_OBJECT_free(a->obj); + free(a); +} + +static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) + +/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting + * to use freed up OIDs. If necessary the actual freeing up of OIDs is + * delayed. + */ + +int obj_cleanup_defer = 0; + +void +check_defer(int nid) +{ + if (!obj_cleanup_defer && nid >= NUM_NID) + obj_cleanup_defer = 1; +} + +void +OBJ_cleanup(void) +{ + if (obj_cleanup_defer) { + obj_cleanup_defer = 2; + return; + } + if (added == NULL) + return; + lh_ADDED_OBJ_down_load(added) = 0; + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ + lh_ADDED_OBJ_free(added); + added = NULL; +} +LCRYPTO_ALIAS(OBJ_cleanup); + +int +OBJ_new_nid(int num) +{ + int i; + + i = new_nid; + new_nid += num; + return (i); +} +LCRYPTO_ALIAS(OBJ_new_nid); + +int +OBJ_add_object(const ASN1_OBJECT *obj) +{ + ASN1_OBJECT *o = NULL; + ADDED_OBJ *ao[4] = {NULL, NULL, NULL, NULL}, *aop; + int i; + + if (added == NULL) + added = lh_ADDED_OBJ_new(); + if (added == NULL) + goto err; + if (obj == NULL || obj->nid == NID_undef) + goto err; + if ((o = OBJ_dup(obj)) == NULL) + goto err; + if (!(ao[ADDED_NID] = malloc(sizeof(ADDED_OBJ)))) + goto err2; + if ((o->length != 0) && (obj->data != NULL)) + if (!(ao[ADDED_DATA] = malloc(sizeof(ADDED_OBJ)))) + goto err2; + if (o->sn != NULL) + if (!(ao[ADDED_SNAME] = malloc(sizeof(ADDED_OBJ)))) + goto err2; + if (o->ln != NULL) + if (!(ao[ADDED_LNAME] = malloc(sizeof(ADDED_OBJ)))) + goto err2; + + for (i = ADDED_DATA; i <= ADDED_NID; i++) { + if (ao[i] != NULL) { + ao[i]->type = i; + ao[i]->obj = o; + aop = lh_ADDED_OBJ_insert(added, ao[i]); + /* memory leak, but should not normally matter */ + free(aop); + } + } + o->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + + return (o->nid); + + err2: + OBJerror(ERR_R_MALLOC_FAILURE); + err: + for (i = ADDED_DATA; i <= ADDED_NID; i++) + free(ao[i]); + ASN1_OBJECT_free(o); + return (NID_undef); +} +LCRYPTO_ALIAS(OBJ_add_object); + +ASN1_OBJECT * +OBJ_nid2obj(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerror(OBJ_R_UNKNOWN_NID); + return (NULL); + } + return ((ASN1_OBJECT *)&(nid_objs[n])); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj); + else { + OBJerror(OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} +LCRYPTO_ALIAS(OBJ_nid2obj); + +const char * +OBJ_nid2sn(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerror(OBJ_R_UNKNOWN_NID); + return (NULL); + } + return (nid_objs[n].sn); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->sn); + else { + OBJerror(OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} +LCRYPTO_ALIAS(OBJ_nid2sn); + +const char * +OBJ_nid2ln(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerror(OBJ_R_UNKNOWN_NID); + return (NULL); + } + return (nid_objs[n].ln); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->ln); + else { + OBJerror(OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} +LCRYPTO_ALIAS(OBJ_nid2ln); + +static int +obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp) +{ + const ASN1_OBJECT *a = *ap; + const ASN1_OBJECT *b = &nid_objs[*bp]; + + return OBJ_cmp(a, b); +} + +static int +obj_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + const ASN1_OBJECT * const *a = a_; + unsigned int const *b = b_; + return obj_cmp(a, b); +} + +static unsigned int * +OBJ_bsearch_obj(const ASN1_OBJECT * *key, unsigned int const *base, int num) +{ + return (unsigned int *)OBJ_bsearch_(key, base, num, sizeof(unsigned int), + obj_cmp_BSEARCH_CMP_FN); +} + +int +OBJ_obj2nid(const ASN1_OBJECT *a) +{ + const unsigned int *op; + ADDED_OBJ ad, *adp; + + if (a == NULL || a->length == 0) + return (NID_undef); + if (a->nid != NID_undef) + return (a->nid); + + if (added != NULL) { + ad.type = ADDED_DATA; + ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */ + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} +LCRYPTO_ALIAS(OBJ_obj2nid); + +/* Convert an object name into an ASN1_OBJECT + * if "noname" is not set then search for short and long names first. + * This will convert the "dotted" form into an object: unlike OBJ_txt2nid + * it can be used with any objects, not just registered ones. + */ + +ASN1_OBJECT * +OBJ_txt2obj(const char *s, int no_name) +{ + int nid; + + if (!no_name) { + if (((nid = OBJ_sn2nid(s)) != NID_undef) || + ((nid = OBJ_ln2nid(s)) != NID_undef) ) + return OBJ_nid2obj(nid); + } + + return t2i_ASN1_OBJECT_internal(s); +} +LCRYPTO_ALIAS(OBJ_txt2obj); + +int +OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *aobj, int no_name) +{ + return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, no_name); +} +LCRYPTO_ALIAS(OBJ_obj2txt); + +int +OBJ_txt2nid(const char *s) +{ + ASN1_OBJECT *obj; + int nid; + + obj = OBJ_txt2obj(s, 0); + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + return nid; +} +LCRYPTO_ALIAS(OBJ_txt2nid); + +int +OBJ_ln2nid(const char *s) +{ + ASN1_OBJECT o; + const ASN1_OBJECT *oo = &o; + ADDED_OBJ ad, *adp; + const unsigned int *op; + + o.ln = s; + if (added != NULL) { + ad.type = ADDED_LNAME; + ad.obj = &o; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} +LCRYPTO_ALIAS(OBJ_ln2nid); + +int +OBJ_sn2nid(const char *s) +{ + ASN1_OBJECT o; + const ASN1_OBJECT *oo = &o; + ADDED_OBJ ad, *adp; + const unsigned int *op; + + o.sn = s; + if (added != NULL) { + ad.type = ADDED_SNAME; + ad.obj = &o; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} +LCRYPTO_ALIAS(OBJ_sn2nid); + +const void * +OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp)(const void *, const void *)) +{ + return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); +} +LCRYPTO_ALIAS(OBJ_bsearch_); + +const void * +OBJ_bsearch_ex_(const void *key, const void *base_, int num, int size, + int (*cmp)(const void *, const void *), int flags) +{ + const char *base = base_; + int l, h, i = 0, c = 0; + const char *p = NULL; + + if (num == 0) + return (NULL); + l = 0; + h = num; + while (l < h) { + i = (l + h) / 2; + p = &(base[i * size]); + c = (*cmp)(key, p); + if (c < 0) + h = i; + else if (c > 0) + l = i + 1; + else + break; + } + if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) + p = NULL; + else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { + while (i > 0 && (*cmp)(key, &(base[(i - 1) * size])) == 0) + i--; + p = &(base[i * size]); + } + return (p); +} + +int +OBJ_create_objects(BIO *in) +{ + char buf[512]; + int i, num = 0; + char *o, *s, *l = NULL; + + for (;;) { + s = o = NULL; + i = BIO_gets(in, buf, 512); + if (i <= 0) + return (num); + buf[i - 1] = '\0'; + if (!isalnum((unsigned char)buf[0])) + return (num); + o = s=buf; + while (isdigit((unsigned char)*s) || (*s == '.')) + s++; + if (*s != '\0') { + *(s++) = '\0'; + while (isspace((unsigned char)*s)) + s++; + if (*s == '\0') + s = NULL; + else { + l = s; + while ((*l != '\0') && + !isspace((unsigned char)*l)) + l++; + if (*l != '\0') { + *(l++) = '\0'; + while (isspace((unsigned char)*l)) + l++; + if (*l == '\0') + l = NULL; + } else + l = NULL; + } + } else + s = NULL; + if ((o == NULL) || (*o == '\0')) + return (num); + if (!OBJ_create(o, s, l)) + return (num); + num++; + } + /* return(num); */ +} +LCRYPTO_ALIAS(OBJ_create_objects); + +int +OBJ_create(const char *oid, const char *sn, const char *ln) +{ + int ok = 0; + ASN1_OBJECT *op = NULL; + unsigned char *buf; + int i; + + i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); + if (i <= 0) + return (0); + + if ((buf = malloc(i)) == NULL) { + OBJerror(ERR_R_MALLOC_FAILURE); + return (0); + } + i = a2d_ASN1_OBJECT(buf, i, oid, -1); + if (i == 0) + goto err; + op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); + if (op == NULL) + goto err; + ok = OBJ_add_object(op); + + err: + ASN1_OBJECT_free(op); + free(buf); + return (ok); +} +LCRYPTO_ALIAS(OBJ_create); + +size_t +OBJ_length(const ASN1_OBJECT *obj) +{ + if (obj == NULL) + return 0; + + if (obj->length < 0) + return 0; + + return obj->length; +} +LCRYPTO_ALIAS(OBJ_length); + +const unsigned char * +OBJ_get0_data(const ASN1_OBJECT *obj) +{ + if (obj == NULL) + return NULL; + + return obj->data; +} +LCRYPTO_ALIAS(OBJ_get0_data); diff --git a/Libraries/libressl/crypto/objects/obj_dat.h b/Libraries/libressl/crypto/objects/obj_dat.h new file mode 100644 index 000000000..578725ab3 --- /dev/null +++ b/Libraries/libressl/crypto/objects/obj_dat.h @@ -0,0 +1,5835 @@ +/* crypto/objects/obj_dat.h */ + +/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the + * following command: + * perl obj_dat.pl obj_mac.h obj_dat.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define NUM_NID 1053 +#define NUM_SN 1046 +#define NUM_LN 1046 +#define NUM_OBJ 975 + +static const unsigned char lvalues[6949]={ +0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05, /* [ 21] OBJ_md5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04, /* [ 29] OBJ_rc4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 37] OBJ_rsaEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 46] OBJ_md2WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 55] OBJ_md5WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 64] OBJ_pbeWithMD2AndDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 73] OBJ_pbeWithMD5AndDES_CBC */ +0x55, /* [ 82] OBJ_X500 */ +0x55,0x04, /* [ 83] OBJ_X509 */ +0x55,0x04,0x03, /* [ 85] OBJ_commonName */ +0x55,0x04,0x06, /* [ 88] OBJ_countryName */ +0x55,0x04,0x07, /* [ 91] OBJ_localityName */ +0x55,0x04,0x08, /* [ 94] OBJ_stateOrProvinceName */ +0x55,0x04,0x0A, /* [ 97] OBJ_organizationName */ +0x55,0x04,0x0B, /* [100] OBJ_organizationalUnitName */ +0x55,0x08,0x01,0x01, /* [103] OBJ_rsa */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07, /* [107] OBJ_pkcs7 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [115] OBJ_pkcs7_data */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [124] OBJ_pkcs7_signed */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [133] OBJ_pkcs7_enveloped */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [142] OBJ_pkcs7_signedAndEnveloped */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [151] OBJ_pkcs7_digest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [160] OBJ_pkcs7_encrypted */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03, /* [169] OBJ_pkcs3 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [177] OBJ_dhKeyAgreement */ +0x2B,0x0E,0x03,0x02,0x06, /* [186] OBJ_des_ecb */ +0x2B,0x0E,0x03,0x02,0x09, /* [191] OBJ_des_cfb64 */ +0x2B,0x0E,0x03,0x02,0x07, /* [196] OBJ_des_cbc */ +0x2B,0x0E,0x03,0x02,0x11, /* [201] OBJ_des_ede_ecb */ +0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [206] OBJ_idea_cbc */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02, /* [217] OBJ_rc2_cbc */ +0x2B,0x0E,0x03,0x02,0x12, /* [225] OBJ_sha */ +0x2B,0x0E,0x03,0x02,0x0F, /* [230] OBJ_shaWithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07, /* [235] OBJ_des_ede3_cbc */ +0x2B,0x0E,0x03,0x02,0x08, /* [243] OBJ_des_ofb64 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09, /* [248] OBJ_pkcs9 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [256] OBJ_pkcs9_emailAddress */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [265] OBJ_pkcs9_unstructuredName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [274] OBJ_pkcs9_contentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [283] OBJ_pkcs9_messageDigest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [292] OBJ_pkcs9_signingTime */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [301] OBJ_pkcs9_countersignature */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [310] OBJ_pkcs9_challengePassword */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [319] OBJ_pkcs9_unstructuredAddress */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [328] OBJ_pkcs9_extCertAttributes */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42, /* [337] OBJ_netscape */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01, /* [344] OBJ_netscape_cert_extension */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02, /* [352] OBJ_netscape_data_type */ +0x2B,0x0E,0x03,0x02,0x1A, /* [360] OBJ_sha1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [365] OBJ_sha1WithRSAEncryption */ +0x2B,0x0E,0x03,0x02,0x0D, /* [374] OBJ_dsaWithSHA */ +0x2B,0x0E,0x03,0x02,0x0C, /* [379] OBJ_dsa_2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [384] OBJ_pbeWithSHA1AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [393] OBJ_id_pbkdf2 */ +0x2B,0x0E,0x03,0x02,0x1B, /* [402] OBJ_dsaWithSHA1_2 */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [407] OBJ_netscape_cert_type */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [416] OBJ_netscape_base_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [425] OBJ_netscape_revocation_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [434] OBJ_netscape_ca_revocation_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [443] OBJ_netscape_renewal_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [452] OBJ_netscape_ca_policy_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [461] OBJ_netscape_ssl_server_name */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [470] OBJ_netscape_comment */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [479] OBJ_netscape_cert_sequence */ +0x55,0x1D, /* [488] OBJ_id_ce */ +0x55,0x1D,0x0E, /* [490] OBJ_subject_key_identifier */ +0x55,0x1D,0x0F, /* [493] OBJ_key_usage */ +0x55,0x1D,0x10, /* [496] OBJ_private_key_usage_period */ +0x55,0x1D,0x11, /* [499] OBJ_subject_alt_name */ +0x55,0x1D,0x12, /* [502] OBJ_issuer_alt_name */ +0x55,0x1D,0x13, /* [505] OBJ_basic_constraints */ +0x55,0x1D,0x14, /* [508] OBJ_crl_number */ +0x55,0x1D,0x20, /* [511] OBJ_certificate_policies */ +0x55,0x1D,0x23, /* [514] OBJ_authority_key_identifier */ +0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [517] OBJ_bf_cbc */ +0x55,0x08,0x03,0x65, /* [526] OBJ_mdc2 */ +0x55,0x08,0x03,0x64, /* [530] OBJ_mdc2WithRSA */ +0x55,0x04,0x2A, /* [534] OBJ_givenName */ +0x55,0x04,0x04, /* [537] OBJ_surname */ +0x55,0x04,0x2B, /* [540] OBJ_initials */ +0x55,0x1D,0x1F, /* [543] OBJ_crl_distribution_points */ +0x2B,0x0E,0x03,0x02,0x03, /* [546] OBJ_md5WithRSA */ +0x55,0x04,0x05, /* [551] OBJ_serialNumber */ +0x55,0x04,0x0C, /* [554] OBJ_title */ +0x55,0x04,0x0D, /* [557] OBJ_description */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [560] OBJ_cast5_cbc */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [569] OBJ_pbeWithMD5AndCast5_CBC */ +0x2A,0x86,0x48,0xCE,0x38,0x04,0x03, /* [578] OBJ_dsaWithSHA1 */ +0x2B,0x0E,0x03,0x02,0x1D, /* [585] OBJ_sha1WithRSA */ +0x2A,0x86,0x48,0xCE,0x38,0x04,0x01, /* [590] OBJ_dsa */ +0x2B,0x24,0x03,0x02,0x01, /* [597] OBJ_ripemd160 */ +0x2B,0x24,0x03,0x03,0x01,0x02, /* [602] OBJ_ripemd160WithRSA */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08, /* [608] OBJ_rc5_cbc */ +0x29,0x01,0x01,0x85,0x1A,0x01, /* [616] OBJ_rle_compression */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */ +0x55,0x1D,0x25, /* [633] OBJ_ext_key_usage */ +0x2B,0x06,0x01,0x05,0x05,0x07, /* [636] OBJ_id_pkix */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03, /* [642] OBJ_id_kp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, /* [649] OBJ_server_auth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02, /* [657] OBJ_client_auth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03, /* [665] OBJ_code_sign */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04, /* [673] OBJ_email_protect */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08, /* [681] OBJ_time_stamp */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */ +0x55,0x1D,0x1B, /* [748] OBJ_delta_crl */ +0x55,0x1D,0x15, /* [751] OBJ_crl_reason */ +0x55,0x1D,0x18, /* [754] OBJ_invalidity_date */ +0x2B,0x65,0x01,0x04,0x01, /* [757] OBJ_sxnet */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07, /* [954] OBJ_hmacWithSHA1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, /* [962] OBJ_id_qt_cps */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, /* [970] OBJ_id_qt_unotice */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */ +0x55,0x04,0x29, /* [1033] OBJ_name */ +0x55,0x04,0x2E, /* [1036] OBJ_dnQualifier */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01, /* [1039] OBJ_id_pe */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30, /* [1046] OBJ_id_ad */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [1053] OBJ_info_access */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [1061] OBJ_ad_OCSP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [1069] OBJ_ad_ca_issuers */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [1077] OBJ_OCSP_sign */ +0x2A, /* [1085] OBJ_member_body */ +0x2A,0x86,0x48, /* [1086] OBJ_ISO_US */ +0x2A,0x86,0x48,0xCE,0x38, /* [1089] OBJ_X9_57 */ +0x2A,0x86,0x48,0xCE,0x38,0x04, /* [1094] OBJ_X9cm */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, /* [1100] OBJ_pkcs1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05, /* [1108] OBJ_pkcs5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04, /* [1866] OBJ_md4 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00, /* [1874] OBJ_id_pkix_mod */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02, /* [1881] OBJ_id_qt */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04, /* [1888] OBJ_id_it */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05, /* [1895] OBJ_id_pkip */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06, /* [1902] OBJ_id_alg */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07, /* [1909] OBJ_id_cmc */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08, /* [1916] OBJ_id_on */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09, /* [1923] OBJ_id_pda */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A, /* [1930] OBJ_id_aca */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B, /* [1937] OBJ_id_qcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C, /* [1944] OBJ_id_cct */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01, /* [1951] OBJ_id_pkix1_explicit_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02, /* [1959] OBJ_id_pkix1_implicit_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03, /* [1967] OBJ_id_pkix1_explicit_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04, /* [1975] OBJ_id_pkix1_implicit_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05, /* [1983] OBJ_id_mod_crmf */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06, /* [1991] OBJ_id_mod_cmc */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07, /* [1999] OBJ_id_mod_kea_profile_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08, /* [2007] OBJ_id_mod_kea_profile_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09, /* [2015] OBJ_id_mod_cmp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A, /* [2023] OBJ_id_mod_qualified_cert_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B, /* [2031] OBJ_id_mod_qualified_cert_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C, /* [2039] OBJ_id_mod_attribute_cert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D, /* [2047] OBJ_id_mod_timestamp_protocol */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E, /* [2055] OBJ_id_mod_ocsp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F, /* [2063] OBJ_id_mod_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10, /* [2071] OBJ_id_mod_cmp2000 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02, /* [2079] OBJ_biometricInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03, /* [2087] OBJ_qcStatements */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04, /* [2095] OBJ_ac_auditEntity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05, /* [2103] OBJ_ac_targeting */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06, /* [2111] OBJ_aaControls */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07, /* [2119] OBJ_sbgp_ipAddrBlock */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08, /* [2127] OBJ_sbgp_autonomousSysNum */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09, /* [2135] OBJ_sbgp_routerIdentifier */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03, /* [2143] OBJ_textNotice */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, /* [2151] OBJ_ipsecEndSystem */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06, /* [2159] OBJ_ipsecTunnel */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07, /* [2167] OBJ_ipsecUser */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A, /* [2175] OBJ_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01, /* [2183] OBJ_id_it_caProtEncCert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02, /* [2191] OBJ_id_it_signKeyPairTypes */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03, /* [2199] OBJ_id_it_encKeyPairTypes */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04, /* [2207] OBJ_id_it_preferredSymmAlg */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05, /* [2215] OBJ_id_it_caKeyUpdateInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06, /* [2223] OBJ_id_it_currentCRL */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07, /* [2231] OBJ_id_it_unsupportedOIDs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08, /* [2239] OBJ_id_it_subscriptionRequest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09, /* [2247] OBJ_id_it_subscriptionResponse */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A, /* [2255] OBJ_id_it_keyPairParamReq */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B, /* [2263] OBJ_id_it_keyPairParamRep */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C, /* [2271] OBJ_id_it_revPassphrase */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D, /* [2279] OBJ_id_it_implicitConfirm */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E, /* [2287] OBJ_id_it_confirmWaitTime */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F, /* [2295] OBJ_id_it_origPKIMessage */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01, /* [2303] OBJ_id_regCtrl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02, /* [2311] OBJ_id_regInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01, /* [2391] OBJ_id_alg_des40 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02, /* [2399] OBJ_id_alg_noSignature */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03, /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04, /* [2415] OBJ_id_alg_dh_pop */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01, /* [2423] OBJ_id_cmc_statusInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02, /* [2431] OBJ_id_cmc_identification */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03, /* [2439] OBJ_id_cmc_identityProof */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04, /* [2447] OBJ_id_cmc_dataReturn */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05, /* [2455] OBJ_id_cmc_transactionId */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06, /* [2463] OBJ_id_cmc_senderNonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07, /* [2471] OBJ_id_cmc_recipientNonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08, /* [2479] OBJ_id_cmc_addExtensions */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09, /* [2487] OBJ_id_cmc_encryptedPOP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A, /* [2495] OBJ_id_cmc_decryptedPOP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B, /* [2503] OBJ_id_cmc_lraPOPWitness */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F, /* [2511] OBJ_id_cmc_getCert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10, /* [2519] OBJ_id_cmc_getCRL */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11, /* [2527] OBJ_id_cmc_revokeRequest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12, /* [2535] OBJ_id_cmc_regInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13, /* [2543] OBJ_id_cmc_responseInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15, /* [2551] OBJ_id_cmc_queryPending */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16, /* [2559] OBJ_id_cmc_popLinkRandom */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17, /* [2567] OBJ_id_cmc_popLinkWitness */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18, /* [2575] OBJ_id_cmc_confirmCertAcceptance */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01, /* [2583] OBJ_id_on_personalData */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01, /* [2591] OBJ_id_pda_dateOfBirth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02, /* [2599] OBJ_id_pda_placeOfBirth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03, /* [2607] OBJ_id_pda_gender */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04, /* [2615] OBJ_id_pda_countryOfCitizenship */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05, /* [2623] OBJ_id_pda_countryOfResidence */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01, /* [2631] OBJ_id_aca_authenticationInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02, /* [2639] OBJ_id_aca_accessIdentity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03, /* [2647] OBJ_id_aca_chargingIdentity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04, /* [2655] OBJ_id_aca_group */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05, /* [2663] OBJ_id_aca_role */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01, /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01, /* [2679] OBJ_id_cct_crs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02, /* [2687] OBJ_id_cct_PKIData */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03, /* [2695] OBJ_id_cct_PKIResponse */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03, /* [2703] OBJ_ad_timeStamping */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04, /* [2711] OBJ_ad_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */ +0x2B,0x0E,0x03,0x02, /* [2818] OBJ_algorithm */ +0x2B,0x0E,0x03,0x02,0x0B, /* [2822] OBJ_rsaSignature */ +0x55,0x08, /* [2827] OBJ_X500algorithms */ +0x2B, /* [2829] OBJ_org */ +0x2B,0x06, /* [2830] OBJ_dod */ +0x2B,0x06,0x01, /* [2832] OBJ_iana */ +0x2B,0x06,0x01,0x01, /* [2835] OBJ_Directory */ +0x2B,0x06,0x01,0x02, /* [2839] OBJ_Management */ +0x2B,0x06,0x01,0x03, /* [2843] OBJ_Experimental */ +0x2B,0x06,0x01,0x04, /* [2847] OBJ_Private */ +0x2B,0x06,0x01,0x05, /* [2851] OBJ_Security */ +0x2B,0x06,0x01,0x06, /* [2855] OBJ_SNMPv2 */ +0x2B,0x06,0x01,0x07, /* [2859] OBJ_Mail */ +0x2B,0x06,0x01,0x04,0x01, /* [2863] OBJ_Enterprises */ +0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */ +0x55,0x01,0x05, /* [2897] OBJ_selected_attribute_types */ +0x55,0x01,0x05,0x37, /* [2900] OBJ_clearance */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A, /* [2913] OBJ_ac_proxying */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B, /* [2921] OBJ_sinfo_access */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06, /* [2929] OBJ_id_aca_encAttrs */ +0x55,0x04,0x48, /* [2937] OBJ_role */ +0x55,0x1D,0x24, /* [2940] OBJ_policy_constraints */ +0x55,0x1D,0x37, /* [2943] OBJ_target_information */ +0x55,0x1D,0x38, /* [2946] OBJ_no_rev_avail */ +0x2A,0x86,0x48,0xCE,0x3D, /* [2949] OBJ_ansi_X9_62 */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01, /* [2954] OBJ_X9_62_prime_field */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02, /* [2961] OBJ_X9_62_characteristic_two_field */ +0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, /* [2968] OBJ_X9_62_id_ecPublicKey */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01, /* [2975] OBJ_X9_62_prime192v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02, /* [2983] OBJ_X9_62_prime192v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03, /* [2991] OBJ_X9_62_prime192v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04, /* [2999] OBJ_X9_62_prime239v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05, /* [3007] OBJ_X9_62_prime239v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06, /* [3015] OBJ_X9_62_prime239v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07, /* [3023] OBJ_X9_62_prime256v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, /* [3031] OBJ_ecdsa_with_SHA1 */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */ +0x55,0x1D,0x17, /* [3155] OBJ_hold_instruction_code */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [3158] OBJ_hold_instruction_none */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [3165] OBJ_hold_instruction_call_issuer */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [3172] OBJ_hold_instruction_reject */ +0x09, /* [3179] OBJ_data */ +0x09,0x92,0x26, /* [3180] OBJ_pss */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C, /* [3183] OBJ_ucl */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64, /* [3190] OBJ_pilot */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */ +0x55,0x04,0x2D, /* [3844] OBJ_x500UniqueIdentifier */ +0x2B,0x06,0x01,0x07,0x01, /* [3847] OBJ_mime_mhs */ +0x2B,0x06,0x01,0x07,0x01,0x01, /* [3852] OBJ_mime_mhs_headings */ +0x2B,0x06,0x01,0x07,0x01,0x02, /* [3858] OBJ_mime_mhs_bodies */ +0x2B,0x06,0x01,0x07,0x01,0x01,0x01, /* [3864] OBJ_id_hex_partial_message */ +0x2B,0x06,0x01,0x07,0x01,0x01,0x02, /* [3871] OBJ_id_hex_multipart_message */ +0x55,0x04,0x2C, /* [3878] OBJ_generationQualifier */ +0x55,0x04,0x41, /* [3881] OBJ_pseudonym */ +0x67,0x2A, /* [3884] OBJ_id_set */ +0x67,0x2A,0x00, /* [3886] OBJ_set_ctype */ +0x67,0x2A,0x01, /* [3889] OBJ_set_msgExt */ +0x67,0x2A,0x03, /* [3892] OBJ_set_attr */ +0x67,0x2A,0x05, /* [3895] OBJ_set_policy */ +0x67,0x2A,0x07, /* [3898] OBJ_set_certExt */ +0x67,0x2A,0x08, /* [3901] OBJ_set_brand */ +0x67,0x2A,0x00,0x00, /* [3904] OBJ_setct_PANData */ +0x67,0x2A,0x00,0x01, /* [3908] OBJ_setct_PANToken */ +0x67,0x2A,0x00,0x02, /* [3912] OBJ_setct_PANOnly */ +0x67,0x2A,0x00,0x03, /* [3916] OBJ_setct_OIData */ +0x67,0x2A,0x00,0x04, /* [3920] OBJ_setct_PI */ +0x67,0x2A,0x00,0x05, /* [3924] OBJ_setct_PIData */ +0x67,0x2A,0x00,0x06, /* [3928] OBJ_setct_PIDataUnsigned */ +0x67,0x2A,0x00,0x07, /* [3932] OBJ_setct_HODInput */ +0x67,0x2A,0x00,0x08, /* [3936] OBJ_setct_AuthResBaggage */ +0x67,0x2A,0x00,0x09, /* [3940] OBJ_setct_AuthRevReqBaggage */ +0x67,0x2A,0x00,0x0A, /* [3944] OBJ_setct_AuthRevResBaggage */ +0x67,0x2A,0x00,0x0B, /* [3948] OBJ_setct_CapTokenSeq */ +0x67,0x2A,0x00,0x0C, /* [3952] OBJ_setct_PInitResData */ +0x67,0x2A,0x00,0x0D, /* [3956] OBJ_setct_PI_TBS */ +0x67,0x2A,0x00,0x0E, /* [3960] OBJ_setct_PResData */ +0x67,0x2A,0x00,0x10, /* [3964] OBJ_setct_AuthReqTBS */ +0x67,0x2A,0x00,0x11, /* [3968] OBJ_setct_AuthResTBS */ +0x67,0x2A,0x00,0x12, /* [3972] OBJ_setct_AuthResTBSX */ +0x67,0x2A,0x00,0x13, /* [3976] OBJ_setct_AuthTokenTBS */ +0x67,0x2A,0x00,0x14, /* [3980] OBJ_setct_CapTokenData */ +0x67,0x2A,0x00,0x15, /* [3984] OBJ_setct_CapTokenTBS */ +0x67,0x2A,0x00,0x16, /* [3988] OBJ_setct_AcqCardCodeMsg */ +0x67,0x2A,0x00,0x17, /* [3992] OBJ_setct_AuthRevReqTBS */ +0x67,0x2A,0x00,0x18, /* [3996] OBJ_setct_AuthRevResData */ +0x67,0x2A,0x00,0x19, /* [4000] OBJ_setct_AuthRevResTBS */ +0x67,0x2A,0x00,0x1A, /* [4004] OBJ_setct_CapReqTBS */ +0x67,0x2A,0x00,0x1B, /* [4008] OBJ_setct_CapReqTBSX */ +0x67,0x2A,0x00,0x1C, /* [4012] OBJ_setct_CapResData */ +0x67,0x2A,0x00,0x1D, /* [4016] OBJ_setct_CapRevReqTBS */ +0x67,0x2A,0x00,0x1E, /* [4020] OBJ_setct_CapRevReqTBSX */ +0x67,0x2A,0x00,0x1F, /* [4024] OBJ_setct_CapRevResData */ +0x67,0x2A,0x00,0x20, /* [4028] OBJ_setct_CredReqTBS */ +0x67,0x2A,0x00,0x21, /* [4032] OBJ_setct_CredReqTBSX */ +0x67,0x2A,0x00,0x22, /* [4036] OBJ_setct_CredResData */ +0x67,0x2A,0x00,0x23, /* [4040] OBJ_setct_CredRevReqTBS */ +0x67,0x2A,0x00,0x24, /* [4044] OBJ_setct_CredRevReqTBSX */ +0x67,0x2A,0x00,0x25, /* [4048] OBJ_setct_CredRevResData */ +0x67,0x2A,0x00,0x26, /* [4052] OBJ_setct_PCertReqData */ +0x67,0x2A,0x00,0x27, /* [4056] OBJ_setct_PCertResTBS */ +0x67,0x2A,0x00,0x28, /* [4060] OBJ_setct_BatchAdminReqData */ +0x67,0x2A,0x00,0x29, /* [4064] OBJ_setct_BatchAdminResData */ +0x67,0x2A,0x00,0x2A, /* [4068] OBJ_setct_CardCInitResTBS */ +0x67,0x2A,0x00,0x2B, /* [4072] OBJ_setct_MeAqCInitResTBS */ +0x67,0x2A,0x00,0x2C, /* [4076] OBJ_setct_RegFormResTBS */ +0x67,0x2A,0x00,0x2D, /* [4080] OBJ_setct_CertReqData */ +0x67,0x2A,0x00,0x2E, /* [4084] OBJ_setct_CertReqTBS */ +0x67,0x2A,0x00,0x2F, /* [4088] OBJ_setct_CertResData */ +0x67,0x2A,0x00,0x30, /* [4092] OBJ_setct_CertInqReqTBS */ +0x67,0x2A,0x00,0x31, /* [4096] OBJ_setct_ErrorTBS */ +0x67,0x2A,0x00,0x32, /* [4100] OBJ_setct_PIDualSignedTBE */ +0x67,0x2A,0x00,0x33, /* [4104] OBJ_setct_PIUnsignedTBE */ +0x67,0x2A,0x00,0x34, /* [4108] OBJ_setct_AuthReqTBE */ +0x67,0x2A,0x00,0x35, /* [4112] OBJ_setct_AuthResTBE */ +0x67,0x2A,0x00,0x36, /* [4116] OBJ_setct_AuthResTBEX */ +0x67,0x2A,0x00,0x37, /* [4120] OBJ_setct_AuthTokenTBE */ +0x67,0x2A,0x00,0x38, /* [4124] OBJ_setct_CapTokenTBE */ +0x67,0x2A,0x00,0x39, /* [4128] OBJ_setct_CapTokenTBEX */ +0x67,0x2A,0x00,0x3A, /* [4132] OBJ_setct_AcqCardCodeMsgTBE */ +0x67,0x2A,0x00,0x3B, /* [4136] OBJ_setct_AuthRevReqTBE */ +0x67,0x2A,0x00,0x3C, /* [4140] OBJ_setct_AuthRevResTBE */ +0x67,0x2A,0x00,0x3D, /* [4144] OBJ_setct_AuthRevResTBEB */ +0x67,0x2A,0x00,0x3E, /* [4148] OBJ_setct_CapReqTBE */ +0x67,0x2A,0x00,0x3F, /* [4152] OBJ_setct_CapReqTBEX */ +0x67,0x2A,0x00,0x40, /* [4156] OBJ_setct_CapResTBE */ +0x67,0x2A,0x00,0x41, /* [4160] OBJ_setct_CapRevReqTBE */ +0x67,0x2A,0x00,0x42, /* [4164] OBJ_setct_CapRevReqTBEX */ +0x67,0x2A,0x00,0x43, /* [4168] OBJ_setct_CapRevResTBE */ +0x67,0x2A,0x00,0x44, /* [4172] OBJ_setct_CredReqTBE */ +0x67,0x2A,0x00,0x45, /* [4176] OBJ_setct_CredReqTBEX */ +0x67,0x2A,0x00,0x46, /* [4180] OBJ_setct_CredResTBE */ +0x67,0x2A,0x00,0x47, /* [4184] OBJ_setct_CredRevReqTBE */ +0x67,0x2A,0x00,0x48, /* [4188] OBJ_setct_CredRevReqTBEX */ +0x67,0x2A,0x00,0x49, /* [4192] OBJ_setct_CredRevResTBE */ +0x67,0x2A,0x00,0x4A, /* [4196] OBJ_setct_BatchAdminReqTBE */ +0x67,0x2A,0x00,0x4B, /* [4200] OBJ_setct_BatchAdminResTBE */ +0x67,0x2A,0x00,0x4C, /* [4204] OBJ_setct_RegFormReqTBE */ +0x67,0x2A,0x00,0x4D, /* [4208] OBJ_setct_CertReqTBE */ +0x67,0x2A,0x00,0x4E, /* [4212] OBJ_setct_CertReqTBEX */ +0x67,0x2A,0x00,0x4F, /* [4216] OBJ_setct_CertResTBE */ +0x67,0x2A,0x00,0x50, /* [4220] OBJ_setct_CRLNotificationTBS */ +0x67,0x2A,0x00,0x51, /* [4224] OBJ_setct_CRLNotificationResTBS */ +0x67,0x2A,0x00,0x52, /* [4228] OBJ_setct_BCIDistributionTBS */ +0x67,0x2A,0x01,0x01, /* [4232] OBJ_setext_genCrypt */ +0x67,0x2A,0x01,0x03, /* [4236] OBJ_setext_miAuth */ +0x67,0x2A,0x01,0x04, /* [4240] OBJ_setext_pinSecure */ +0x67,0x2A,0x01,0x05, /* [4244] OBJ_setext_pinAny */ +0x67,0x2A,0x01,0x07, /* [4248] OBJ_setext_track2 */ +0x67,0x2A,0x01,0x08, /* [4252] OBJ_setext_cv */ +0x67,0x2A,0x05,0x00, /* [4256] OBJ_set_policy_root */ +0x67,0x2A,0x07,0x00, /* [4260] OBJ_setCext_hashedRoot */ +0x67,0x2A,0x07,0x01, /* [4264] OBJ_setCext_certType */ +0x67,0x2A,0x07,0x02, /* [4268] OBJ_setCext_merchData */ +0x67,0x2A,0x07,0x03, /* [4272] OBJ_setCext_cCertRequired */ +0x67,0x2A,0x07,0x04, /* [4276] OBJ_setCext_tunneling */ +0x67,0x2A,0x07,0x05, /* [4280] OBJ_setCext_setExt */ +0x67,0x2A,0x07,0x06, /* [4284] OBJ_setCext_setQualf */ +0x67,0x2A,0x07,0x07, /* [4288] OBJ_setCext_PGWYcapabilities */ +0x67,0x2A,0x07,0x08, /* [4292] OBJ_setCext_TokenIdentifier */ +0x67,0x2A,0x07,0x09, /* [4296] OBJ_setCext_Track2Data */ +0x67,0x2A,0x07,0x0A, /* [4300] OBJ_setCext_TokenType */ +0x67,0x2A,0x07,0x0B, /* [4304] OBJ_setCext_IssuerCapabilities */ +0x67,0x2A,0x03,0x00, /* [4308] OBJ_setAttr_Cert */ +0x67,0x2A,0x03,0x01, /* [4312] OBJ_setAttr_PGWYcap */ +0x67,0x2A,0x03,0x02, /* [4316] OBJ_setAttr_TokenType */ +0x67,0x2A,0x03,0x03, /* [4320] OBJ_setAttr_IssCap */ +0x67,0x2A,0x03,0x00,0x00, /* [4324] OBJ_set_rootKeyThumb */ +0x67,0x2A,0x03,0x00,0x01, /* [4329] OBJ_set_addPolicy */ +0x67,0x2A,0x03,0x02,0x01, /* [4334] OBJ_setAttr_Token_EMV */ +0x67,0x2A,0x03,0x02,0x02, /* [4339] OBJ_setAttr_Token_B0Prime */ +0x67,0x2A,0x03,0x03,0x03, /* [4344] OBJ_setAttr_IssCap_CVM */ +0x67,0x2A,0x03,0x03,0x04, /* [4349] OBJ_setAttr_IssCap_T2 */ +0x67,0x2A,0x03,0x03,0x05, /* [4354] OBJ_setAttr_IssCap_Sig */ +0x67,0x2A,0x03,0x03,0x03,0x01, /* [4359] OBJ_setAttr_GenCryptgrm */ +0x67,0x2A,0x03,0x03,0x04,0x01, /* [4365] OBJ_setAttr_T2Enc */ +0x67,0x2A,0x03,0x03,0x04,0x02, /* [4371] OBJ_setAttr_T2cleartxt */ +0x67,0x2A,0x03,0x03,0x05,0x01, /* [4377] OBJ_setAttr_TokICCsig */ +0x67,0x2A,0x03,0x03,0x05,0x02, /* [4383] OBJ_setAttr_SecDevSig */ +0x67,0x2A,0x08,0x01, /* [4389] OBJ_set_brand_IATA_ATA */ +0x67,0x2A,0x08,0x1E, /* [4393] OBJ_set_brand_Diners */ +0x67,0x2A,0x08,0x22, /* [4397] OBJ_set_brand_AmericanExpress */ +0x67,0x2A,0x08,0x23, /* [4401] OBJ_set_brand_JCB */ +0x67,0x2A,0x08,0x04, /* [4405] OBJ_set_brand_Visa */ +0x67,0x2A,0x08,0x05, /* [4409] OBJ_set_brand_MasterCard */ +0x67,0x2A,0x08,0xAE,0x7B, /* [4413] OBJ_set_brand_Novus */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A, /* [4418] OBJ_des_cdmf */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */ +0x67, /* [4435] OBJ_international_organizations */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */ +0x55,0x04,0x09, /* [4456] OBJ_streetAddress */ +0x55,0x04,0x11, /* [4459] OBJ_postalCode */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15, /* [4462] OBJ_id_ppl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E, /* [4469] OBJ_proxyCertInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00, /* [4477] OBJ_id_ppl_anyLanguage */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01, /* [4485] OBJ_id_ppl_inheritAll */ +0x55,0x1D,0x1E, /* [4493] OBJ_name_constraints */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02, /* [4496] OBJ_Independent */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */ +0x2B, /* [4576] OBJ_identified_organization */ +0x2B,0x81,0x04, /* [4577] OBJ_certicom_arc */ +0x67,0x2B, /* [4580] OBJ_wap */ +0x67,0x2B,0x01, /* [4582] OBJ_wap_wsg */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [4585] OBJ_X9_62_id_characteristic_two_basis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01, /* [4620] OBJ_X9_62_c2pnb163v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02, /* [4628] OBJ_X9_62_c2pnb163v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03, /* [4636] OBJ_X9_62_c2pnb163v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04, /* [4644] OBJ_X9_62_c2pnb176v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05, /* [4652] OBJ_X9_62_c2tnb191v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06, /* [4660] OBJ_X9_62_c2tnb191v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07, /* [4668] OBJ_X9_62_c2tnb191v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08, /* [4676] OBJ_X9_62_c2onb191v4 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09, /* [4684] OBJ_X9_62_c2onb191v5 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A, /* [4692] OBJ_X9_62_c2pnb208w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B, /* [4700] OBJ_X9_62_c2tnb239v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C, /* [4708] OBJ_X9_62_c2tnb239v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D, /* [4716] OBJ_X9_62_c2tnb239v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E, /* [4724] OBJ_X9_62_c2onb239v4 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F, /* [4732] OBJ_X9_62_c2onb239v5 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10, /* [4740] OBJ_X9_62_c2pnb272w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11, /* [4748] OBJ_X9_62_c2pnb304w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12, /* [4756] OBJ_X9_62_c2tnb359v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13, /* [4764] OBJ_X9_62_c2pnb368w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14, /* [4772] OBJ_X9_62_c2tnb431r1 */ +0x2B,0x81,0x04,0x00,0x06, /* [4780] OBJ_secp112r1 */ +0x2B,0x81,0x04,0x00,0x07, /* [4785] OBJ_secp112r2 */ +0x2B,0x81,0x04,0x00,0x1C, /* [4790] OBJ_secp128r1 */ +0x2B,0x81,0x04,0x00,0x1D, /* [4795] OBJ_secp128r2 */ +0x2B,0x81,0x04,0x00,0x09, /* [4800] OBJ_secp160k1 */ +0x2B,0x81,0x04,0x00,0x08, /* [4805] OBJ_secp160r1 */ +0x2B,0x81,0x04,0x00,0x1E, /* [4810] OBJ_secp160r2 */ +0x2B,0x81,0x04,0x00,0x1F, /* [4815] OBJ_secp192k1 */ +0x2B,0x81,0x04,0x00,0x20, /* [4820] OBJ_secp224k1 */ +0x2B,0x81,0x04,0x00,0x21, /* [4825] OBJ_secp224r1 */ +0x2B,0x81,0x04,0x00,0x0A, /* [4830] OBJ_secp256k1 */ +0x2B,0x81,0x04,0x00,0x22, /* [4835] OBJ_secp384r1 */ +0x2B,0x81,0x04,0x00,0x23, /* [4840] OBJ_secp521r1 */ +0x2B,0x81,0x04,0x00,0x04, /* [4845] OBJ_sect113r1 */ +0x2B,0x81,0x04,0x00,0x05, /* [4850] OBJ_sect113r2 */ +0x2B,0x81,0x04,0x00,0x16, /* [4855] OBJ_sect131r1 */ +0x2B,0x81,0x04,0x00,0x17, /* [4860] OBJ_sect131r2 */ +0x2B,0x81,0x04,0x00,0x01, /* [4865] OBJ_sect163k1 */ +0x2B,0x81,0x04,0x00,0x02, /* [4870] OBJ_sect163r1 */ +0x2B,0x81,0x04,0x00,0x0F, /* [4875] OBJ_sect163r2 */ +0x2B,0x81,0x04,0x00,0x18, /* [4880] OBJ_sect193r1 */ +0x2B,0x81,0x04,0x00,0x19, /* [4885] OBJ_sect193r2 */ +0x2B,0x81,0x04,0x00,0x1A, /* [4890] OBJ_sect233k1 */ +0x2B,0x81,0x04,0x00,0x1B, /* [4895] OBJ_sect233r1 */ +0x2B,0x81,0x04,0x00,0x03, /* [4900] OBJ_sect239k1 */ +0x2B,0x81,0x04,0x00,0x10, /* [4905] OBJ_sect283k1 */ +0x2B,0x81,0x04,0x00,0x11, /* [4910] OBJ_sect283r1 */ +0x2B,0x81,0x04,0x00,0x24, /* [4915] OBJ_sect409k1 */ +0x2B,0x81,0x04,0x00,0x25, /* [4920] OBJ_sect409r1 */ +0x2B,0x81,0x04,0x00,0x26, /* [4925] OBJ_sect571k1 */ +0x2B,0x81,0x04,0x00,0x27, /* [4930] OBJ_sect571r1 */ +0x67,0x2B,0x01,0x04,0x01, /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */ +0x67,0x2B,0x01,0x04,0x03, /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */ +0x67,0x2B,0x01,0x04,0x04, /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */ +0x67,0x2B,0x01,0x04,0x05, /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */ +0x67,0x2B,0x01,0x04,0x06, /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */ +0x67,0x2B,0x01,0x04,0x07, /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */ +0x67,0x2B,0x01,0x04,0x08, /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */ +0x67,0x2B,0x01,0x04,0x09, /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */ +0x67,0x2B,0x01,0x04,0x0A, /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */ +0x67,0x2B,0x01,0x04,0x0B, /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */ +0x67,0x2B,0x01,0x04,0x0C, /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */ +0x55,0x1D,0x20,0x00, /* [4990] OBJ_any_policy */ +0x55,0x1D,0x21, /* [4994] OBJ_policy_mappings */ +0x55,0x1D,0x36, /* [4997] OBJ_inhibit_any_policy */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01, /* [5033] OBJ_camellia_128_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15, /* [5041] OBJ_camellia_192_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29, /* [5049] OBJ_camellia_256_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04, /* [5057] OBJ_camellia_128_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18, /* [5065] OBJ_camellia_192_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C, /* [5073] OBJ_camellia_256_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03, /* [5081] OBJ_camellia_128_ofb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17, /* [5089] OBJ_camellia_192_ofb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B, /* [5097] OBJ_camellia_256_ofb128 */ +0x55,0x1D,0x09, /* [5105] OBJ_subject_directory_attributes */ +0x55,0x1D,0x1C, /* [5108] OBJ_issuing_distribution_point */ +0x55,0x1D,0x1D, /* [5111] OBJ_certificate_issuer */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [5114] OBJ_kisa */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [5120] OBJ_seed_ecb */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [5128] OBJ_seed_cbc */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [5136] OBJ_seed_ofb128 */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [5144] OBJ_seed_cfb128 */ +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01, /* [5152] OBJ_hmac_md5 */ +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02, /* [5160] OBJ_hmac_sha1 */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10, /* [5186] OBJ_id_it_suppLangTags */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05, /* [5194] OBJ_caRepository */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02, /* [5251] OBJ_ecdsa_with_Recommended */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, /* [5258] OBJ_ecdsa_with_Specified */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01, /* [5265] OBJ_ecdsa_with_SHA224 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, /* [5273] OBJ_ecdsa_with_SHA256 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03, /* [5281] OBJ_ecdsa_with_SHA384 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04, /* [5289] OBJ_ecdsa_with_SHA512 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [5297] OBJ_hmacWithMD5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08, /* [5305] OBJ_hmacWithSHA224 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09, /* [5313] OBJ_hmacWithSHA256 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A, /* [5321] OBJ_hmacWithSHA384 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B, /* [5329] OBJ_hmacWithSHA512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */ +0x28,0xCF,0x06,0x03,0x00,0x37, /* [5355] OBJ_whirlpool */ +0x2A,0x85,0x03,0x02,0x02, /* [5361] OBJ_cryptopro */ +0x2A,0x85,0x03,0x02,0x09, /* [5366] OBJ_cryptocom */ +0x2A,0x85,0x03,0x02,0x02,0x03, /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */ +0x2A,0x85,0x03,0x02,0x02,0x04, /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */ +0x2A,0x85,0x03,0x02,0x02,0x09, /* [5383] OBJ_id_GostR3411_94 */ +0x2A,0x85,0x03,0x02,0x02,0x0A, /* [5389] OBJ_id_HMACGostR3411_94 */ +0x2A,0x85,0x03,0x02,0x02,0x13, /* [5395] OBJ_id_GostR3410_2001 */ +0x2A,0x85,0x03,0x02,0x02,0x14, /* [5401] OBJ_id_GostR3410_94 */ +0x2A,0x85,0x03,0x02,0x02,0x15, /* [5407] OBJ_id_Gost28147_89 */ +0x2A,0x85,0x03,0x02,0x02,0x16, /* [5413] OBJ_id_Gost28147_89_MAC */ +0x2A,0x85,0x03,0x02,0x02,0x17, /* [5419] OBJ_id_GostR3411_94_prf */ +0x2A,0x85,0x03,0x02,0x02,0x62, /* [5425] OBJ_id_GostR3410_2001DH */ +0x2A,0x85,0x03,0x02,0x02,0x63, /* [5431] OBJ_id_GostR3410_94DH */ +0x2A,0x85,0x03,0x02,0x02,0x0E,0x01, /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */ +0x2A,0x85,0x03,0x02,0x02,0x0E,0x00, /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */ +0x2A,0x85,0x03,0x02,0x02,0x1E,0x00, /* [5451] OBJ_id_GostR3411_94_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1E,0x01, /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x00, /* [5465] OBJ_id_Gost28147_89_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x01, /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x02, /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x03, /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x04, /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x05, /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x06, /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x07, /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x00, /* [5521] OBJ_id_GostR3410_94_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x02, /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x03, /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x04, /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x05, /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x01, /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x02, /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x03, /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x00, /* [5577] OBJ_id_GostR3410_2001_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x01, /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x02, /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x03, /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x24,0x00, /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x24,0x01, /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x01, /* [5619] OBJ_id_GostR3410_94_a */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x02, /* [5626] OBJ_id_GostR3410_94_aBis */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x03, /* [5633] OBJ_id_GostR3410_94_b */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x04, /* [5640] OBJ_id_GostR3410_94_bBis */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01, /* [5647] OBJ_id_Gost28147_89_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03, /* [5655] OBJ_id_GostR3410_94_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04, /* [5663] OBJ_id_GostR3410_2001_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */ +0x55,0x1D,0x2E, /* [5704] OBJ_freshest_crl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [5707] OBJ_id_on_permanentIdentifier */ +0x55,0x04,0x0E, /* [5715] OBJ_searchGuide */ +0x55,0x04,0x0F, /* [5718] OBJ_businessCategory */ +0x55,0x04,0x10, /* [5721] OBJ_postalAddress */ +0x55,0x04,0x12, /* [5724] OBJ_postOfficeBox */ +0x55,0x04,0x13, /* [5727] OBJ_physicalDeliveryOfficeName */ +0x55,0x04,0x14, /* [5730] OBJ_telephoneNumber */ +0x55,0x04,0x15, /* [5733] OBJ_telexNumber */ +0x55,0x04,0x16, /* [5736] OBJ_teletexTerminalIdentifier */ +0x55,0x04,0x17, /* [5739] OBJ_facsimileTelephoneNumber */ +0x55,0x04,0x18, /* [5742] OBJ_x121Address */ +0x55,0x04,0x19, /* [5745] OBJ_internationaliSDNNumber */ +0x55,0x04,0x1A, /* [5748] OBJ_registeredAddress */ +0x55,0x04,0x1B, /* [5751] OBJ_destinationIndicator */ +0x55,0x04,0x1C, /* [5754] OBJ_preferredDeliveryMethod */ +0x55,0x04,0x1D, /* [5757] OBJ_presentationAddress */ +0x55,0x04,0x1E, /* [5760] OBJ_supportedApplicationContext */ +0x55,0x04,0x1F, /* [5763] OBJ_member */ +0x55,0x04,0x20, /* [5766] OBJ_owner */ +0x55,0x04,0x21, /* [5769] OBJ_roleOccupant */ +0x55,0x04,0x22, /* [5772] OBJ_seeAlso */ +0x55,0x04,0x23, /* [5775] OBJ_userPassword */ +0x55,0x04,0x24, /* [5778] OBJ_userCertificate */ +0x55,0x04,0x25, /* [5781] OBJ_cACertificate */ +0x55,0x04,0x26, /* [5784] OBJ_authorityRevocationList */ +0x55,0x04,0x27, /* [5787] OBJ_certificateRevocationList */ +0x55,0x04,0x28, /* [5790] OBJ_crossCertificatePair */ +0x55,0x04,0x2F, /* [5793] OBJ_enhancedSearchGuide */ +0x55,0x04,0x30, /* [5796] OBJ_protocolInformation */ +0x55,0x04,0x31, /* [5799] OBJ_distinguishedName */ +0x55,0x04,0x32, /* [5802] OBJ_uniqueMember */ +0x55,0x04,0x33, /* [5805] OBJ_houseIdentifier */ +0x55,0x04,0x34, /* [5808] OBJ_supportedAlgorithms */ +0x55,0x04,0x35, /* [5811] OBJ_deltaRevocationList */ +0x55,0x04,0x36, /* [5814] OBJ_dmdName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */ +0x55,0x1D,0x25,0x00, /* [5942] OBJ_anyExtendedKeyUsage */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */ +0x2B,0x24, /* [5973] OBJ_teletrust */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01, /* [5975] OBJ_brainpool */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5982] OBJ_brainpoolP160r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5991] OBJ_brainpoolP160t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [6000] OBJ_brainpoolP192r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6009] OBJ_brainpoolP192t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6018] OBJ_brainpoolP224r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6027] OBJ_brainpoolP224t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6036] OBJ_brainpoolP256r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6045] OBJ_brainpoolP256t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6054] OBJ_brainpoolP320r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6063] OBJ_brainpoolP320t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6072] OBJ_brainpoolP384r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6081] OBJ_brainpoolP384t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6090] OBJ_brainpoolP512r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6099] OBJ_brainpoolP512t1 */ +0x2A,0x81,0x7A,0x01,0x81,0x5F,0x65,0x82,0x00,0x01,/* [6108] OBJ_FRP256v1 */ +0x2A,0x85,0x03,0x07,0x01, /* [6118] OBJ_tc26 */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x02, /* [6123] OBJ_id_tc26_gost3411_2012_256 */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x03, /* [6131] OBJ_id_tc26_gost3411_2012_512 */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x01,/* [6139] OBJ_id_tc26_gost_3410_12_512_paramSetA */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x02,/* [6148] OBJ_id_tc26_gost_3410_12_512_paramSetB */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,0x01,/* [6157] OBJ_id_tc26_gost_28147_param_Z */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x01, /* [6166] OBJ_id_tc26_gost3410_2012_256 */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x02, /* [6174] OBJ_id_tc26_gost3410_2012_512 */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x02, /* [6182] OBJ_id_tc26_signwithdigest_gost3410_2012_256 */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x03, /* [6190] OBJ_id_tc26_signwithdigest_gost3410_2012_512 */ +0x2B,0x65,0x6E, /* [6198] OBJ_X25519 */ +0x2B,0x65,0x6F, /* [6201] OBJ_X448 */ +0x2B,0x65,0x70, /* [6204] OBJ_Ed25519 */ +0x2B,0x65,0x71, /* [6207] OBJ_Ed448 */ +0x2B,0x65,0x72, /* [6210] OBJ_Ed25519ph */ +0x2B,0x65,0x73, /* [6213] OBJ_Ed448ph */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,/* [6216] OBJ_jurisdictionLocalityName */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,/* [6227] OBJ_jurisdictionStateOrProvinceName */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,/* [6238] OBJ_jurisdictionCountryName */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11, /* [6249] OBJ_sm3 */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x78, /* [6257] OBJ_sm3WithRSAEncryption */ +0x2A,0x81,0x1C, /* [6265] OBJ_ISO_CN */ +0x2A,0x81,0x1C,0xCF,0x55, /* [6268] OBJ_oscca */ +0x2A,0x81,0x1C,0xCF,0x55,0x01, /* [6273] OBJ_sm_scheme */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x01, /* [6279] OBJ_sm4_ecb */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x02, /* [6287] OBJ_sm4_cbc */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03, /* [6295] OBJ_sm4_ofb128 */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [6303] OBJ_sm4_cfb128 */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x05, /* [6311] OBJ_sm4_cfb1 */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x06, /* [6319] OBJ_sm4_cfb8 */ +0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x07, /* [6327] OBJ_sm4_ctr */ +0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,/* [6335] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x00, /* [6344] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x01, /* [6350] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x02, /* [6356] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x03, /* [6362] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */ +0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,/* [6368] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x00, /* [6377] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x01, /* [6383] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x02, /* [6389] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x03, /* [6395] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,/* [6401] OBJ_pSpecified */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x01,/* [6410] OBJ_id_tc26_gost_3410_12_256_paramSetA */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x02,/* [6419] OBJ_id_tc26_gost_3410_12_256_paramSetB */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x03,/* [6428] OBJ_id_tc26_gost_3410_12_256_paramSetC */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04,/* [6437] OBJ_id_tc26_gost_3410_12_256_paramSetD */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x00,/* [6446] OBJ_id_tc26_gost_3410_12_512_paramSetTest */ +0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x03,/* [6455] OBJ_id_tc26_gost_3410_12_512_paramSetC */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x01, /* [6464] OBJ_id_tc26_hmac_gost_3411_12_256 */ +0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x02, /* [6472] OBJ_id_tc26_hmac_gost_3411_12_512 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x18,/* [6480] OBJ_id_ct_routeOriginAuthz */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1A,/* [6491] OBJ_id_ct_rpkiManifest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x23,/* [6502] OBJ_id_ct_rpkiGhostbusters */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x24,/* [6513] OBJ_id_ct_resourceTaggedAttest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0E, /* [6524] OBJ_id_cp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x1C, /* [6531] OBJ_sbgp_ipAddrBlockv2 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x1D, /* [6539] OBJ_sbgp_autonomousSysNumv2 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0E,0x02, /* [6547] OBJ_ipAddr_asNumber */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0E,0x03, /* [6555] OBJ_ipAddr_asNumberv2 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0A, /* [6563] OBJ_rpkiManifest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0B, /* [6571] OBJ_signedObject */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0D, /* [6579] OBJ_rpkiNotify */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x2F,/* [6587] OBJ_id_ct_geofeedCSVwithCRLF */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x30,/* [6598] OBJ_id_ct_signedChecklist */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1E, /* [6609] OBJ_id_kp_bgpsec_router */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x18, /* [6617] OBJ_tlsfeature */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x31,/* [6625] OBJ_id_ct_ASPA */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,/* [6636] OBJ_ct_precert_scts */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03,/* [6646] OBJ_ct_precert_poison */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04,/* [6656] OBJ_ct_precert_signer */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05,/* [6666] OBJ_ct_cert_scts */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x2F,/* [6676] OBJ_id_smime_aa_signingCertificateV2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x32,/* [6687] OBJ_id_ct_signedTAL */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0F,/* [6698] OBJ_sha512_224WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x10,/* [6707] OBJ_sha512_256WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [6716] OBJ_hmacWithSHA512_224 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [6724] OBJ_hmacWithSHA512_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x05,/* [6732] OBJ_sha512_224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x06,/* [6741] OBJ_sha512_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x07,/* [6750] OBJ_sha3_224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x08,/* [6759] OBJ_sha3_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x09,/* [6768] OBJ_sha3_384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0A,/* [6777] OBJ_sha3_512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0D,/* [6786] OBJ_hmac_sha3_224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0E,/* [6795] OBJ_hmac_sha3_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0F,/* [6804] OBJ_hmac_sha3_384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x10,/* [6813] OBJ_hmac_sha3_512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x03,/* [6822] OBJ_dsa_with_SHA384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x04,/* [6831] OBJ_dsa_with_SHA512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x05,/* [6840] OBJ_dsa_with_SHA3_224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x06,/* [6849] OBJ_dsa_with_SHA3_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x07,/* [6858] OBJ_dsa_with_SHA3_384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x08,/* [6867] OBJ_dsa_with_SHA3_512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x09,/* [6876] OBJ_ecdsa_with_SHA3_224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0A,/* [6885] OBJ_ecdsa_with_SHA3_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0B,/* [6894] OBJ_ecdsa_with_SHA3_384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0C,/* [6903] OBJ_ecdsa_with_SHA3_512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0D,/* [6912] OBJ_RSA_SHA3_224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0E,/* [6921] OBJ_RSA_SHA3_256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0F,/* [6930] OBJ_RSA_SHA3_384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x10,/* [6939] OBJ_RSA_SHA3_512 */ +}; + +static const ASN1_OBJECT nid_objs[NUM_NID]={ +{"UNDEF","undefined",NID_undef,0,NULL,0}, +{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[0]),0}, +{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[6]),0}, +{"MD2","md2",NID_md2,8,&(lvalues[13]),0}, +{"MD5","md5",NID_md5,8,&(lvalues[21]),0}, +{"RC4","rc4",NID_rc4,8,&(lvalues[29]),0}, +{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[37]),0}, +{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9, + &(lvalues[46]),0}, +{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9, + &(lvalues[55]),0}, +{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9, + &(lvalues[64]),0}, +{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9, + &(lvalues[73]),0}, +{"X500","directory services (X.500)",NID_X500,1,&(lvalues[82]),0}, +{"X509","X509",NID_X509,2,&(lvalues[83]),0}, +{"CN","commonName",NID_commonName,3,&(lvalues[85]),0}, +{"C","countryName",NID_countryName,3,&(lvalues[88]),0}, +{"L","localityName",NID_localityName,3,&(lvalues[91]),0}, +{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[94]),0}, +{"O","organizationName",NID_organizationName,3,&(lvalues[97]),0}, +{"OU","organizationalUnitName",NID_organizationalUnitName,3, + &(lvalues[100]),0}, +{"RSA","rsa",NID_rsa,4,&(lvalues[103]),0}, +{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[107]),0}, +{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[115]),0}, +{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9, + &(lvalues[124]),0}, +{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9, + &(lvalues[133]),0}, +{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData", + NID_pkcs7_signedAndEnveloped,9,&(lvalues[142]),0}, +{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9, + &(lvalues[151]),0}, +{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9, + &(lvalues[160]),0}, +{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[169]),0}, +{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9, + &(lvalues[177]),0}, +{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[186]),0}, +{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[191]),0}, +{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[196]),0}, +{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[201]),0}, +{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0}, +{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[206]),0}, +{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0}, +{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0}, +{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[217]),0}, +{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0}, +{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0}, +{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0}, +{"SHA","sha",NID_sha,5,&(lvalues[225]),0}, +{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5, + &(lvalues[230]),0}, +{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0}, +{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[235]),0}, +{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[243]),0}, +{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0}, +{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[248]),0}, +{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9, + &(lvalues[256]),0}, +{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9, + &(lvalues[265]),0}, +{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[274]),0}, +{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9, + &(lvalues[283]),0}, +{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[292]),0}, +{"countersignature","countersignature",NID_pkcs9_countersignature,9, + &(lvalues[301]),0}, +{"challengePassword","challengePassword",NID_pkcs9_challengePassword, + 9,&(lvalues[310]),0}, +{"unstructuredAddress","unstructuredAddress", + NID_pkcs9_unstructuredAddress,9,&(lvalues[319]),0}, +{"extendedCertificateAttributes","extendedCertificateAttributes", + NID_pkcs9_extCertAttributes,9,&(lvalues[328]),0}, +{"Netscape","Netscape Communications Corp.",NID_netscape,7, + &(lvalues[337]),0}, +{"nsCertExt","Netscape Certificate Extension", + NID_netscape_cert_extension,8,&(lvalues[344]),0}, +{"nsDataType","Netscape Data Type",NID_netscape_data_type,8, + &(lvalues[352]),0}, +{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0}, +{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0}, +{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0}, +{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0}, +{"SHA1","sha1",NID_sha1,5,&(lvalues[360]),0}, +{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9, + &(lvalues[365]),0}, +{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[374]),0}, +{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[379]),0}, +{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC, + 9,&(lvalues[384]),0}, +{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[393]),0}, +{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[402]),0}, +{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9, + &(lvalues[407]),0}, +{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9, + &(lvalues[416]),0}, +{"nsRevocationUrl","Netscape Revocation Url", + NID_netscape_revocation_url,9,&(lvalues[425]),0}, +{"nsCaRevocationUrl","Netscape CA Revocation Url", + NID_netscape_ca_revocation_url,9,&(lvalues[434]),0}, +{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9, + &(lvalues[443]),0}, +{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url, + 9,&(lvalues[452]),0}, +{"nsSslServerName","Netscape SSL Server Name", + NID_netscape_ssl_server_name,9,&(lvalues[461]),0}, +{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[470]),0}, +{"nsCertSequence","Netscape Certificate Sequence", + NID_netscape_cert_sequence,9,&(lvalues[479]),0}, +{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0}, +{"id-ce","id-ce",NID_id_ce,2,&(lvalues[488]),0}, +{"subjectKeyIdentifier","X509v3 Subject Key Identifier", + NID_subject_key_identifier,3,&(lvalues[490]),0}, +{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[493]),0}, +{"privateKeyUsagePeriod","X509v3 Private Key Usage Period", + NID_private_key_usage_period,3,&(lvalues[496]),0}, +{"subjectAltName","X509v3 Subject Alternative Name", + NID_subject_alt_name,3,&(lvalues[499]),0}, +{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name, + 3,&(lvalues[502]),0}, +{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints, + 3,&(lvalues[505]),0}, +{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[508]),0}, +{"certificatePolicies","X509v3 Certificate Policies", + NID_certificate_policies,3,&(lvalues[511]),0}, +{"authorityKeyIdentifier","X509v3 Authority Key Identifier", + NID_authority_key_identifier,3,&(lvalues[514]),0}, +{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[517]),0}, +{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0}, +{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0}, +{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0}, +{"MDC2","mdc2",NID_mdc2,4,&(lvalues[526]),0}, +{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[530]),0}, +{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0}, +{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0}, +{"GN","givenName",NID_givenName,3,&(lvalues[534]),0}, +{"SN","surname",NID_surname,3,&(lvalues[537]),0}, +{"initials","initials",NID_initials,3,&(lvalues[540]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"crlDistributionPoints","X509v3 CRL Distribution Points", + NID_crl_distribution_points,3,&(lvalues[543]),0}, +{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[546]),0}, +{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[551]),0}, +{"title","title",NID_title,3,&(lvalues[554]),0}, +{"description","description",NID_description,3,&(lvalues[557]),0}, +{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[560]),0}, +{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0}, +{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0}, +{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0}, +{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC", + NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[569]),0}, +{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[578]),0}, +{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0}, +{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[585]),0}, +{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[590]),0}, +{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[597]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6, + &(lvalues[602]),0}, +{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[608]),0}, +{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0}, +{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0}, +{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0}, +{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0}, +{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0}, +{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3, + &(lvalues[633]),0}, +{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0}, +{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0}, +{"serverAuth","TLS Web Server Authentication",NID_server_auth,8, + &(lvalues[649]),0}, +{"clientAuth","TLS Web Client Authentication",NID_client_auth,8, + &(lvalues[657]),0}, +{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0}, +{"emailProtection","E-mail Protection",NID_email_protect,8, + &(lvalues[673]),0}, +{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0}, +{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10, + &(lvalues[689]),0}, +{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10, + &(lvalues[699]),0}, +{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10, + &(lvalues[709]),0}, +{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0}, +{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10, + &(lvalues[729]),0}, +{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0}, +{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3, + &(lvalues[748]),0}, +{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0}, +{"invalidityDate","Invalidity Date",NID_invalidity_date,3, + &(lvalues[754]),0}, +{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0}, +{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4", + NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0}, +{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4", + NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0}, +{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC", + NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0}, +{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC", + NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0}, +{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC", + NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0}, +{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC", + NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0}, +{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0}, +{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag, + 11,&(lvalues[833]),0}, +{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0}, +{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0}, +{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0}, +{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11, + &(lvalues[877]),0}, +{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0}, +{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0}, +{"x509Certificate","x509Certificate",NID_x509Certificate,10, + &(lvalues[906]),0}, +{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10, + &(lvalues[916]),0}, +{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0}, +{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0}, +{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0}, +{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0}, +{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0}, +{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8, + &(lvalues[970]),0}, +{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0}, +{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9, + &(lvalues[978]),0}, +{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9, + &(lvalues[987]),0}, +{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9, + &(lvalues[996]),0}, +{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9, + &(lvalues[1005]),0}, +{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10, + &(lvalues[1014]),0}, +{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0}, +{"name","name",NID_name,3,&(lvalues[1033]),0}, +{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0}, +{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0}, +{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0}, +{"authorityInfoAccess","Authority Information Access",NID_info_access, + 8,&(lvalues[1053]),0}, +{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0}, +{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0}, +{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0}, +{"ISO","iso",NID_iso,0,NULL,0}, +{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0}, +{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0}, +{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0}, +{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0}, +{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0}, +{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0}, +{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0}, +{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0}, +{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0}, +{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0}, +{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0}, +{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0}, +{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0}, +{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0}, +{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11, + &(lvalues[1195]),0}, +{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11, + &(lvalues[1206]),0}, +{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11, + &(lvalues[1217]),0}, +{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3, + 11,&(lvalues[1228]),0}, +{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88", + NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0}, +{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97", + NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0}, +{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88", + NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0}, +{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97", + NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0}, +{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt, + 11,&(lvalues[1283]),0}, +{"id-smime-ct-authData","id-smime-ct-authData", + NID_id_smime_ct_authData,11,&(lvalues[1294]),0}, +{"id-smime-ct-publishCert","id-smime-ct-publishCert", + NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0}, +{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo, + 11,&(lvalues[1316]),0}, +{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo, + 11,&(lvalues[1327]),0}, +{"id-smime-ct-contentInfo","id-smime-ct-contentInfo", + NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0}, +{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData", + NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0}, +{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData", + NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0}, +{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest", + NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0}, +{"id-smime-aa-securityLabel","id-smime-aa-securityLabel", + NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0}, +{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory", + NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0}, +{"id-smime-aa-contentHint","id-smime-aa-contentHint", + NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0}, +{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest", + NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0}, +{"id-smime-aa-encapContentType","id-smime-aa-encapContentType", + NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0}, +{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier", + NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0}, +{"id-smime-aa-macValue","id-smime-aa-macValue", + NID_id_smime_aa_macValue,11,&(lvalues[1448]),0}, +{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels", + NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0}, +{"id-smime-aa-contentReference","id-smime-aa-contentReference", + NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0}, +{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref", + NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0}, +{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate", + NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0}, +{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts", + NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0}, +{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken", + NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0}, +{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId", + NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0}, +{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType", + NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0}, +{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation", + NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0}, +{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr", + NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0}, +{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert", + NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0}, +{"id-smime-aa-ets-contentTimestamp", + "id-smime-aa-ets-contentTimestamp", + NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0}, +{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs", + NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0}, +{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs", + NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0}, +{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues", + NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0}, +{"id-smime-aa-ets-revocationValues", + "id-smime-aa-ets-revocationValues", + NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0}, +{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp", + NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0}, +{"id-smime-aa-ets-certCRLTimestamp", + "id-smime-aa-ets-certCRLTimestamp", + NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0}, +{"id-smime-aa-ets-archiveTimeStamp", + "id-smime-aa-ets-archiveTimeStamp", + NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0}, +{"id-smime-aa-signatureType","id-smime-aa-signatureType", + NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0}, +{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc", + NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0}, +{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES", + NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0}, +{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2", + NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0}, +{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap", + NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0}, +{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap", + NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0}, +{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11, + &(lvalues[1734]),0}, +{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap", + NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0}, +{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap", + NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0}, +{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11, + &(lvalues[1767]),0}, +{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri", + NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0}, +{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice", + NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0}, +{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin", + NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0}, +{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt", + NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0}, +{"id-smime-cti-ets-proofOfDelivery", + "id-smime-cti-ets-proofOfDelivery", + NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0}, +{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender", + NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0}, +{"id-smime-cti-ets-proofOfApproval", + "id-smime-cti-ets-proofOfApproval", + NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0}, +{"id-smime-cti-ets-proofOfCreation", + "id-smime-cti-ets-proofOfCreation", + NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0}, +{"MD4","md4",NID_md4,8,&(lvalues[1866]),0}, +{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0}, +{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0}, +{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0}, +{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0}, +{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0}, +{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0}, +{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0}, +{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0}, +{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0}, +{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0}, +{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0}, +{"id-pkix1-explicit-88","id-pkix1-explicit-88", + NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0}, +{"id-pkix1-implicit-88","id-pkix1-implicit-88", + NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0}, +{"id-pkix1-explicit-93","id-pkix1-explicit-93", + NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0}, +{"id-pkix1-implicit-93","id-pkix1-implicit-93", + NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0}, +{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0}, +{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0}, +{"id-mod-kea-profile-88","id-mod-kea-profile-88", + NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0}, +{"id-mod-kea-profile-93","id-mod-kea-profile-93", + NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0}, +{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0}, +{"id-mod-qualified-cert-88","id-mod-qualified-cert-88", + NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0}, +{"id-mod-qualified-cert-93","id-mod-qualified-cert-93", + NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0}, +{"id-mod-attribute-cert","id-mod-attribute-cert", + NID_id_mod_attribute_cert,8,&(lvalues[2039]),0}, +{"id-mod-timestamp-protocol","id-mod-timestamp-protocol", + NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0}, +{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0}, +{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0}, +{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8, + &(lvalues[2071]),0}, +{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0}, +{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0}, +{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8, + &(lvalues[2095]),0}, +{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0}, +{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0}, +{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8, + &(lvalues[2119]),0}, +{"sbgp-autonomousSysNum","sbgp-autonomousSysNum", + NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0}, +{"sbgp-routerIdentifier","sbgp-routerIdentifier", + NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0}, +{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0}, +{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8, + &(lvalues[2151]),0}, +{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0}, +{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0}, +{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0}, +{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert, + 8,&(lvalues[2183]),0}, +{"id-it-signKeyPairTypes","id-it-signKeyPairTypes", + NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0}, +{"id-it-encKeyPairTypes","id-it-encKeyPairTypes", + NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0}, +{"id-it-preferredSymmAlg","id-it-preferredSymmAlg", + NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0}, +{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo", + NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0}, +{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8, + &(lvalues[2223]),0}, +{"id-it-unsupportedOIDs","id-it-unsupportedOIDs", + NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0}, +{"id-it-subscriptionRequest","id-it-subscriptionRequest", + NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0}, +{"id-it-subscriptionResponse","id-it-subscriptionResponse", + NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0}, +{"id-it-keyPairParamReq","id-it-keyPairParamReq", + NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0}, +{"id-it-keyPairParamRep","id-it-keyPairParamRep", + NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0}, +{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase, + 8,&(lvalues[2271]),0}, +{"id-it-implicitConfirm","id-it-implicitConfirm", + NID_id_it_implicitConfirm,8,&(lvalues[2279]),0}, +{"id-it-confirmWaitTime","id-it-confirmWaitTime", + NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0}, +{"id-it-origPKIMessage","id-it-origPKIMessage", + NID_id_it_origPKIMessage,8,&(lvalues[2295]),0}, +{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0}, +{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0}, +{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken, + 9,&(lvalues[2319]),0}, +{"id-regCtrl-authenticator","id-regCtrl-authenticator", + NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0}, +{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo", + NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0}, +{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions", + NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0}, +{"id-regCtrl-oldCertID","id-regCtrl-oldCertID", + NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0}, +{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey", + NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0}, +{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs", + NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0}, +{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9, + &(lvalues[2382]),0}, +{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0}, +{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8, + &(lvalues[2399]),0}, +{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1", + NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0}, +{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0}, +{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8, + &(lvalues[2423]),0}, +{"id-cmc-identification","id-cmc-identification", + NID_id_cmc_identification,8,&(lvalues[2431]),0}, +{"id-cmc-identityProof","id-cmc-identityProof", + NID_id_cmc_identityProof,8,&(lvalues[2439]),0}, +{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8, + &(lvalues[2447]),0}, +{"id-cmc-transactionId","id-cmc-transactionId", + NID_id_cmc_transactionId,8,&(lvalues[2455]),0}, +{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8, + &(lvalues[2463]),0}, +{"id-cmc-recipientNonce","id-cmc-recipientNonce", + NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0}, +{"id-cmc-addExtensions","id-cmc-addExtensions", + NID_id_cmc_addExtensions,8,&(lvalues[2479]),0}, +{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP, + 8,&(lvalues[2487]),0}, +{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP, + 8,&(lvalues[2495]),0}, +{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness", + NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0}, +{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8, + &(lvalues[2511]),0}, +{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0}, +{"id-cmc-revokeRequest","id-cmc-revokeRequest", + NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0}, +{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8, + &(lvalues[2535]),0}, +{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo, + 8,&(lvalues[2543]),0}, +{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending, + 8,&(lvalues[2551]),0}, +{"id-cmc-popLinkRandom","id-cmc-popLinkRandom", + NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0}, +{"id-cmc-popLinkWitness","id-cmc-popLinkWitness", + NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0}, +{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance", + NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0}, +{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8, + &(lvalues[2583]),0}, +{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8, + &(lvalues[2591]),0}, +{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth, + 8,&(lvalues[2599]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0}, +{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship", + NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0}, +{"id-pda-countryOfResidence","id-pda-countryOfResidence", + NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0}, +{"id-aca-authenticationInfo","id-aca-authenticationInfo", + NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0}, +{"id-aca-accessIdentity","id-aca-accessIdentity", + NID_id_aca_accessIdentity,8,&(lvalues[2639]),0}, +{"id-aca-chargingIdentity","id-aca-chargingIdentity", + NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0}, +{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0}, +{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0}, +{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1", + NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0}, +{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0}, +{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8, + &(lvalues[2687]),0}, +{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8, + &(lvalues[2695]),0}, +{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8, + &(lvalues[2703]),0}, +{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0}, +{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9, + &(lvalues[2719]),0}, +{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0}, +{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0}, +{"acceptableResponses","Acceptable OCSP Responses", + NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0}, +{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0}, +{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff, + 9,&(lvalues[2764]),0}, +{"serviceLocator","OCSP Service Locator", + NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0}, +{"extendedStatus","Extended OCSP Status", + NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0}, +{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0}, +{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0}, +{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9, + &(lvalues[2809]),0}, +{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0}, +{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0}, +{"X500algorithms","directory services - algorithms", + NID_X500algorithms,2,&(lvalues[2827]),0}, +{"ORG","org",NID_org,1,&(lvalues[2829]),0}, +{"DOD","dod",NID_dod,2,&(lvalues[2830]),0}, +{"IANA","iana",NID_iana,3,&(lvalues[2832]),0}, +{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0}, +{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0}, +{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0}, +{"private","Private",NID_Private,4,&(lvalues[2847]),0}, +{"security","Security",NID_Security,4,&(lvalues[2851]),0}, +{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0}, +{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0}, +{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0}, +{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0}, +{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0}, +{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0}, +{"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0}, +{"selected-attribute-types","Selected Attribute Types", + NID_selected_attribute_types,3,&(lvalues[2897]),0}, +{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0}, +{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9, + &(lvalues[2904]),0}, +{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0}, +{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8, + &(lvalues[2921]),0}, +{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8, + &(lvalues[2929]),0}, +{"role","role",NID_role,3,&(lvalues[2937]),0}, +{"policyConstraints","X509v3 Policy Constraints", + NID_policy_constraints,3,&(lvalues[2940]),0}, +{"targetInformation","X509v3 AC Targeting",NID_target_information,3, + &(lvalues[2943]),0}, +{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3, + &(lvalues[2946]),0}, +{"NULL","NULL",NID_ccitt,0,NULL,0}, +{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0}, +{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0}, +{"characteristic-two-field","characteristic-two-field", + NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0}, +{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7, + &(lvalues[2968]),0}, +{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0}, +{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0}, +{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0}, +{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0}, +{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0}, +{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0}, +{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0}, +{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7, + &(lvalues[3031]),0}, +{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0}, +{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0}, +{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0}, +{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0}, +{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0}, +{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0}, +{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0}, +{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0}, +{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0}, +{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0}, +{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0}, +{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0}, +{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0}, +{"holdInstructionCode","Hold Instruction Code", + NID_hold_instruction_code,3,&(lvalues[3155]),0}, +{"holdInstructionNone","Hold Instruction None", + NID_hold_instruction_none,7,&(lvalues[3158]),0}, +{"holdInstructionCallIssuer","Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0}, +{"holdInstructionReject","Hold Instruction Reject", + NID_hold_instruction_reject,7,&(lvalues[3172]),0}, +{"data","data",NID_data,1,&(lvalues[3179]),0}, +{"pss","pss",NID_pss,3,&(lvalues[3180]),0}, +{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0}, +{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0}, +{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9, + &(lvalues[3198]),0}, +{"pilotAttributeSyntax","pilotAttributeSyntax", + NID_pilotAttributeSyntax,9,&(lvalues[3207]),0}, +{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9, + &(lvalues[3216]),0}, +{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0}, +{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10, + &(lvalues[3234]),0}, +{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax", + NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0}, +{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0}, +{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0}, +{"account","account",NID_account,10,&(lvalues[3274]),0}, +{"document","document",NID_document,10,&(lvalues[3284]),0}, +{"room","room",NID_room,10,&(lvalues[3294]),0}, +{"documentSeries","documentSeries",NID_documentSeries,10, + &(lvalues[3304]),0}, +{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10, + &(lvalues[3314]),0}, +{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0}, +{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject, + 10,&(lvalues[3334]),0}, +{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10, + &(lvalues[3344]),0}, +{"simpleSecurityObject","simpleSecurityObject", + NID_simpleSecurityObject,10,&(lvalues[3354]),0}, +{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10, + &(lvalues[3364]),0}, +{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0}, +{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData, + 10,&(lvalues[3384]),0}, +{"UID","userId",NID_userId,10,&(lvalues[3394]),0}, +{"textEncodedORAddress","textEncodedORAddress", + NID_textEncodedORAddress,10,&(lvalues[3404]),0}, +{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0}, +{"info","info",NID_info,10,&(lvalues[3424]),0}, +{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10, + &(lvalues[3434]),0}, +{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0}, +{"photo","photo",NID_photo,10,&(lvalues[3454]),0}, +{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0}, +{"host","host",NID_host,10,&(lvalues[3474]),0}, +{"manager","manager",NID_manager,10,&(lvalues[3484]),0}, +{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10, + &(lvalues[3494]),0}, +{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0}, +{"documentVersion","documentVersion",NID_documentVersion,10, + &(lvalues[3514]),0}, +{"documentAuthor","documentAuthor",NID_documentAuthor,10, + &(lvalues[3524]),0}, +{"documentLocation","documentLocation",NID_documentLocation,10, + &(lvalues[3534]),0}, +{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber, + 10,&(lvalues[3544]),0}, +{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0}, +{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0}, +{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10, + &(lvalues[3574]),0}, +{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10, + &(lvalues[3584]),0}, +{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0}, +{"pilotAttributeType27","pilotAttributeType27", + NID_pilotAttributeType27,10,&(lvalues[3604]),0}, +{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0}, +{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0}, +{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0}, +{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0}, +{"associatedDomain","associatedDomain",NID_associatedDomain,10, + &(lvalues[3654]),0}, +{"associatedName","associatedName",NID_associatedName,10, + &(lvalues[3664]),0}, +{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10, + &(lvalues[3674]),0}, +{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0}, +{"mobileTelephoneNumber","mobileTelephoneNumber", + NID_mobileTelephoneNumber,10,&(lvalues[3694]),0}, +{"pagerTelephoneNumber","pagerTelephoneNumber", + NID_pagerTelephoneNumber,10,&(lvalues[3704]),0}, +{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName, + 10,&(lvalues[3714]),0}, +{"organizationalStatus","organizationalStatus", + NID_organizationalStatus,10,&(lvalues[3724]),0}, +{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0}, +{"mailPreferenceOption","mailPreferenceOption", + NID_mailPreferenceOption,10,&(lvalues[3744]),0}, +{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0}, +{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0}, +{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10, + &(lvalues[3774]),0}, +{"subtreeMinimumQuality","subtreeMinimumQuality", + NID_subtreeMinimumQuality,10,&(lvalues[3784]),0}, +{"subtreeMaximumQuality","subtreeMaximumQuality", + NID_subtreeMaximumQuality,10,&(lvalues[3794]),0}, +{"personalSignature","personalSignature",NID_personalSignature,10, + &(lvalues[3804]),0}, +{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0}, +{"audio","audio",NID_audio,10,&(lvalues[3824]),0}, +{"documentPublisher","documentPublisher",NID_documentPublisher,10, + &(lvalues[3834]),0}, +{"x500UniqueIdentifier","x500UniqueIdentifier", + NID_x500UniqueIdentifier,3,&(lvalues[3844]),0}, +{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0}, +{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6, + &(lvalues[3852]),0}, +{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6, + &(lvalues[3858]),0}, +{"id-hex-partial-message","id-hex-partial-message", + NID_id_hex_partial_message,7,&(lvalues[3864]),0}, +{"id-hex-multipart-message","id-hex-multipart-message", + NID_id_hex_multipart_message,7,&(lvalues[3871]),0}, +{"generationQualifier","generationQualifier",NID_generationQualifier, + 3,&(lvalues[3878]),0}, +{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"id-set","Secure Electronic Transactions",NID_id_set,2, + &(lvalues[3884]),0}, +{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0}, +{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0}, +{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0}, +{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0}, +{"set-certExt","certificate extensions",NID_set_certExt,3, + &(lvalues[3898]),0}, +{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0}, +{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0}, +{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4, + &(lvalues[3908]),0}, +{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0}, +{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0}, +{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0}, +{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0}, +{"setct-PIDataUnsigned","setct-PIDataUnsigned", + NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0}, +{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4, + &(lvalues[3932]),0}, +{"setct-AuthResBaggage","setct-AuthResBaggage", + NID_setct_AuthResBaggage,4,&(lvalues[3936]),0}, +{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage", + NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0}, +{"setct-AuthRevResBaggage","setct-AuthRevResBaggage", + NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0}, +{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4, + &(lvalues[3948]),0}, +{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4, + &(lvalues[3952]),0}, +{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0}, +{"setct-PResData","setct-PResData",NID_setct_PResData,4, + &(lvalues[3960]),0}, +{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4, + &(lvalues[3964]),0}, +{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4, + &(lvalues[3968]),0}, +{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4, + &(lvalues[3972]),0}, +{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4, + &(lvalues[3976]),0}, +{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4, + &(lvalues[3980]),0}, +{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4, + &(lvalues[3984]),0}, +{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg", + NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0}, +{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS, + 4,&(lvalues[3992]),0}, +{"setct-AuthRevResData","setct-AuthRevResData", + NID_setct_AuthRevResData,4,&(lvalues[3996]),0}, +{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS, + 4,&(lvalues[4000]),0}, +{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4, + &(lvalues[4004]),0}, +{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4, + &(lvalues[4008]),0}, +{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4, + &(lvalues[4012]),0}, +{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4, + &(lvalues[4016]),0}, +{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX, + 4,&(lvalues[4020]),0}, +{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData, + 4,&(lvalues[4024]),0}, +{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4, + &(lvalues[4028]),0}, +{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4, + &(lvalues[4032]),0}, +{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4, + &(lvalues[4036]),0}, +{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS, + 4,&(lvalues[4040]),0}, +{"setct-CredRevReqTBSX","setct-CredRevReqTBSX", + NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0}, +{"setct-CredRevResData","setct-CredRevResData", + NID_setct_CredRevResData,4,&(lvalues[4048]),0}, +{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4, + &(lvalues[4052]),0}, +{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4, + &(lvalues[4056]),0}, +{"setct-BatchAdminReqData","setct-BatchAdminReqData", + NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0}, +{"setct-BatchAdminResData","setct-BatchAdminResData", + NID_setct_BatchAdminResData,4,&(lvalues[4064]),0}, +{"setct-CardCInitResTBS","setct-CardCInitResTBS", + NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0}, +{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS", + NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0}, +{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS, + 4,&(lvalues[4076]),0}, +{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4, + &(lvalues[4080]),0}, +{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4, + &(lvalues[4084]),0}, +{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4, + &(lvalues[4088]),0}, +{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS, + 4,&(lvalues[4092]),0}, +{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4, + &(lvalues[4096]),0}, +{"setct-PIDualSignedTBE","setct-PIDualSignedTBE", + NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0}, +{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE, + 4,&(lvalues[4104]),0}, +{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4, + &(lvalues[4108]),0}, +{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4, + &(lvalues[4112]),0}, +{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4, + &(lvalues[4116]),0}, +{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4, + &(lvalues[4120]),0}, +{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4, + &(lvalues[4124]),0}, +{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4, + &(lvalues[4128]),0}, +{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE", + NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0}, +{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE, + 4,&(lvalues[4136]),0}, +{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE, + 4,&(lvalues[4140]),0}, +{"setct-AuthRevResTBEB","setct-AuthRevResTBEB", + NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0}, +{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4, + &(lvalues[4148]),0}, +{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4, + &(lvalues[4152]),0}, +{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4, + &(lvalues[4156]),0}, +{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4, + &(lvalues[4160]),0}, +{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX, + 4,&(lvalues[4164]),0}, +{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4, + &(lvalues[4168]),0}, +{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4, + &(lvalues[4172]),0}, +{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4, + &(lvalues[4176]),0}, +{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4, + &(lvalues[4180]),0}, +{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE, + 4,&(lvalues[4184]),0}, +{"setct-CredRevReqTBEX","setct-CredRevReqTBEX", + NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0}, +{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE, + 4,&(lvalues[4192]),0}, +{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE", + NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0}, +{"setct-BatchAdminResTBE","setct-BatchAdminResTBE", + NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0}, +{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE, + 4,&(lvalues[4204]),0}, +{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4, + &(lvalues[4208]),0}, +{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4, + &(lvalues[4212]),0}, +{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4, + &(lvalues[4216]),0}, +{"setct-CRLNotificationTBS","setct-CRLNotificationTBS", + NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0}, +{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS", + NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0}, +{"setct-BCIDistributionTBS","setct-BCIDistributionTBS", + NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0}, +{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4, + &(lvalues[4232]),0}, +{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4, + &(lvalues[4236]),0}, +{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4, + &(lvalues[4240]),0}, +{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0}, +{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0}, +{"setext-cv","additional verification",NID_setext_cv,4, + &(lvalues[4252]),0}, +{"set-policy-root","set-policy-root",NID_set_policy_root,4, + &(lvalues[4256]),0}, +{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4, + &(lvalues[4260]),0}, +{"setCext-certType","setCext-certType",NID_setCext_certType,4, + &(lvalues[4264]),0}, +{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4, + &(lvalues[4268]),0}, +{"setCext-cCertRequired","setCext-cCertRequired", + NID_setCext_cCertRequired,4,&(lvalues[4272]),0}, +{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4, + &(lvalues[4276]),0}, +{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4, + &(lvalues[4280]),0}, +{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4, + &(lvalues[4284]),0}, +{"setCext-PGWYcapabilities","setCext-PGWYcapabilities", + NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0}, +{"setCext-TokenIdentifier","setCext-TokenIdentifier", + NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0}, +{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4, + &(lvalues[4296]),0}, +{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4, + &(lvalues[4300]),0}, +{"setCext-IssuerCapabilities","setCext-IssuerCapabilities", + NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0}, +{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0}, +{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap, + 4,&(lvalues[4312]),0}, +{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4, + &(lvalues[4316]),0}, +{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4, + &(lvalues[4320]),0}, +{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5, + &(lvalues[4324]),0}, +{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0}, +{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5, + &(lvalues[4334]),0}, +{"setAttr-Token-B0Prime","setAttr-Token-B0Prime", + NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0}, +{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5, + &(lvalues[4344]),0}, +{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5, + &(lvalues[4349]),0}, +{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5, + &(lvalues[4354]),0}, +{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm, + 6,&(lvalues[4359]),0}, +{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6, + &(lvalues[4365]),0}, +{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6, + &(lvalues[4371]),0}, +{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6, + &(lvalues[4377]),0}, +{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig, + 6,&(lvalues[4383]),0}, +{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4, + &(lvalues[4389]),0}, +{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4, + &(lvalues[4393]),0}, +{"set-brand-AmericanExpress","set-brand-AmericanExpress", + NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0}, +{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0}, +{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4, + &(lvalues[4405]),0}, +{"set-brand-MasterCard","set-brand-MasterCard", + NID_set_brand_MasterCard,4,&(lvalues[4409]),0}, +{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5, + &(lvalues[4413]),0}, +{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0}, +{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET", + NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0}, +{"ITU-T","itu-t",NID_itu_t,0,NULL,0}, +{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0}, +{"international-organizations","International Organizations", + NID_international_organizations,1,&(lvalues[4435]),0}, +{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login, + 10,&(lvalues[4436]),0}, +{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10, + &(lvalues[4446]),0}, +{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0}, +{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0}, +{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0}, +{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0}, +{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0}, +{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0}, +{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0}, +{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0}, +{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0}, +{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0}, +{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0}, +{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0}, +{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0}, +{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8, + &(lvalues[4469]),0}, +{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8, + &(lvalues[4477]),0}, +{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8, + &(lvalues[4485]),0}, +{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3, + &(lvalues[4493]),0}, +{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0}, +{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9, + &(lvalues[4504]),0}, +{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9, + &(lvalues[4513]),0}, +{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9, + &(lvalues[4522]),0}, +{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9, + &(lvalues[4531]),0}, +{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0}, +{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0}, +{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0}, +{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0}, +{"identified-organization","identified-organization", + NID_identified_organization,1,&(lvalues[4576]),0}, +{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0}, +{"wap","wap",NID_wap,2,&(lvalues[4580]),0}, +{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0}, +{"id-characteristic-two-basis","id-characteristic-two-basis", + NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0}, +{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0}, +{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0}, +{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0}, +{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0}, +{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0}, +{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0}, +{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0}, +{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0}, +{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0}, +{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0}, +{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0}, +{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0}, +{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0}, +{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0}, +{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0}, +{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0}, +{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0}, +{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0}, +{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0}, +{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0}, +{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0}, +{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0}, +{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0}, +{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0}, +{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0}, +{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0}, +{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0}, +{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0}, +{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0}, +{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0}, +{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0}, +{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0}, +{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0}, +{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0}, +{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0}, +{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0}, +{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0}, +{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0}, +{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0}, +{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0}, +{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0}, +{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0}, +{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0}, +{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0}, +{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0}, +{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0}, +{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0}, +{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0}, +{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0}, +{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0}, +{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0}, +{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0}, +{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0}, +{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0}, +{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1", + NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0}, +{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3", + NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0}, +{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4", + NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0}, +{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5", + NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0}, +{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6", + NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0}, +{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7", + NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0}, +{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8", + NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0}, +{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9", + NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0}, +{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10", + NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0}, +{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11", + NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0}, +{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12", + NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0}, +{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0}, +{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3, + &(lvalues[4994]),0}, +{"inhibitAnyPolicy","X509v3 Inhibit Any Policy", + NID_inhibit_any_policy,3,&(lvalues[4997]),0}, +{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0}, +{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0}, +{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11, + &(lvalues[5000]),0}, +{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11, + &(lvalues[5011]),0}, +{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11, + &(lvalues[5022]),0}, +{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8, + &(lvalues[5033]),0}, +{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8, + &(lvalues[5041]),0}, +{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8, + &(lvalues[5049]),0}, +{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8, + &(lvalues[5057]),0}, +{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8, + &(lvalues[5065]),0}, +{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8, + &(lvalues[5073]),0}, +{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0}, +{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0}, +{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0}, +{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0}, +{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0}, +{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0}, +{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8, + &(lvalues[5081]),0}, +{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8, + &(lvalues[5089]),0}, +{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8, + &(lvalues[5097]),0}, +{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes", + NID_subject_directory_attributes,3,&(lvalues[5105]),0}, +{"issuingDistributionPoint","X509v3 Issuing Distribution Point", + NID_issuing_distribution_point,3,&(lvalues[5108]),0}, +{"certificateIssuer","X509v3 Certificate Issuer", + NID_certificate_issuer,3,&(lvalues[5111]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0}, +{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0}, +{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0}, +{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0}, +{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0}, +{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0}, +{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9, + &(lvalues[5168]),0}, +{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9, + &(lvalues[5177]),0}, +{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8, + &(lvalues[5186]),0}, +{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0}, +{"id-smime-ct-compressedData","id-smime-ct-compressedData", + NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0}, +{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF", + NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0}, +{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9, + &(lvalues[5224]),0}, +{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9, + &(lvalues[5233]),0}, +{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9, + &(lvalues[5242]),0}, +{"ecdsa-with-Recommended","ecdsa-with-Recommended", + NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0}, +{"ecdsa-with-Specified","ecdsa-with-Specified", + NID_ecdsa_with_Specified,7,&(lvalues[5258]),0}, +{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8, + &(lvalues[5265]),0}, +{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8, + &(lvalues[5273]),0}, +{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8, + &(lvalues[5281]),0}, +{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8, + &(lvalues[5289]),0}, +{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0}, +{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8, + &(lvalues[5305]),0}, +{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8, + &(lvalues[5313]),0}, +{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8, + &(lvalues[5321]),0}, +{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8, + &(lvalues[5329]),0}, +{"id-dsa-with-sha224","dsa_with_SHA224",NID_dsa_with_SHA224,9, + &(lvalues[5337]),0}, +{"id-dsa-with-sha256","dsa_with_SHA256",NID_dsa_with_SHA256,9, + &(lvalues[5346]),0}, +{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0}, +{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0}, +{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0}, +{"id-GostR3411-94-with-GostR3410-2001", + "GOST R 34.11-94 with GOST R 34.10-2001", + NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0}, +{"id-GostR3411-94-with-GostR3410-94", + "GOST R 34.11-94 with GOST R 34.10-94", + NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0}, +{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0}, +{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6, + &(lvalues[5389]),0}, +{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6, + &(lvalues[5395]),0}, +{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0}, +{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0}, +{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0}, +{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6, + &(lvalues[5413]),0}, +{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6, + &(lvalues[5419]),0}, +{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH, + 6,&(lvalues[5425]),0}, +{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6, + &(lvalues[5431]),0}, +{"id-Gost28147-89-CryptoPro-KeyMeshing", + "id-Gost28147-89-CryptoPro-KeyMeshing", + NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0}, +{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing", + NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0}, +{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet", + NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0}, +{"id-GostR3411-94-CryptoProParamSet", + "id-GostR3411-94-CryptoProParamSet", + NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0}, +{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet", + NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0}, +{"id-Gost28147-89-CryptoPro-A-ParamSet", + "id-Gost28147-89-CryptoPro-A-ParamSet", + NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0}, +{"id-Gost28147-89-CryptoPro-B-ParamSet", + "id-Gost28147-89-CryptoPro-B-ParamSet", + NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0}, +{"id-Gost28147-89-CryptoPro-C-ParamSet", + "id-Gost28147-89-CryptoPro-C-ParamSet", + NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0}, +{"id-Gost28147-89-CryptoPro-D-ParamSet", + "id-Gost28147-89-CryptoPro-D-ParamSet", + NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0}, +{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]), + 0}, +{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]), + 0}, +{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0}, +{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet", + NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0}, +{"id-GostR3410-94-CryptoPro-A-ParamSet", + "id-GostR3410-94-CryptoPro-A-ParamSet", + NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0}, +{"id-GostR3410-94-CryptoPro-B-ParamSet", + "id-GostR3410-94-CryptoPro-B-ParamSet", + NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0}, +{"id-GostR3410-94-CryptoPro-C-ParamSet", + "id-GostR3410-94-CryptoPro-C-ParamSet", + NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0}, +{"id-GostR3410-94-CryptoPro-D-ParamSet", + "id-GostR3410-94-CryptoPro-D-ParamSet", + NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0}, +{"id-GostR3410-94-CryptoPro-XchA-ParamSet", + "id-GostR3410-94-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0}, +{"id-GostR3410-94-CryptoPro-XchB-ParamSet", + "id-GostR3410-94-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0}, +{"id-GostR3410-94-CryptoPro-XchC-ParamSet", + "id-GostR3410-94-CryptoPro-XchC-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0}, +{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet", + NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0}, +{"id-GostR3410-2001-CryptoPro-A-ParamSet", + "id-GostR3410-2001-CryptoPro-A-ParamSet", + NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0}, +{"id-GostR3410-2001-CryptoPro-B-ParamSet", + "id-GostR3410-2001-CryptoPro-B-ParamSet", + NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0}, +{"id-GostR3410-2001-CryptoPro-C-ParamSet", + "id-GostR3410-2001-CryptoPro-C-ParamSet", + NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0}, +{"id-GostR3410-2001-CryptoPro-XchA-ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0}, + +{"id-GostR3410-2001-CryptoPro-XchB-ParamSet", + "id-GostR3410-2001-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0}, + +{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7, + &(lvalues[5619]),0}, +{"id-GostR3410-94-aBis","id-GostR3410-94-aBis", + NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0}, +{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7, + &(lvalues[5633]),0}, +{"id-GostR3410-94-bBis","id-GostR3410-94-bBis", + NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0}, +{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet", + NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0}, +{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8, + &(lvalues[5655]),0}, +{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8, + &(lvalues[5663]),0}, +{"id-GostR3411-94-with-GostR3410-94-cc", + "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0}, +{"id-GostR3411-94-with-GostR3410-2001-cc", + "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0}, +{"id-GostR3410-2001-ParamSet-cc", + "GOST R 3410-2001 Parameter Set Cryptocom", + NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0}, +{"HMAC","hmac",NID_hmac,0,NULL,0}, +{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9, + &(lvalues[5695]),0}, +{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3, + &(lvalues[5704]),0}, +{"id-on-permanentIdentifier","Permanent Identifier", + NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0}, +{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0}, +{"businessCategory","businessCategory",NID_businessCategory,3, + &(lvalues[5718]),0}, +{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0}, +{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0}, +{"physicalDeliveryOfficeName","physicalDeliveryOfficeName", + NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0}, +{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3, + &(lvalues[5730]),0}, +{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0}, +{"teletexTerminalIdentifier","teletexTerminalIdentifier", + NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0}, +{"facsimileTelephoneNumber","facsimileTelephoneNumber", + NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0}, +{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0}, +{"internationaliSDNNumber","internationaliSDNNumber", + NID_internationaliSDNNumber,3,&(lvalues[5745]),0}, +{"registeredAddress","registeredAddress",NID_registeredAddress,3, + &(lvalues[5748]),0}, +{"destinationIndicator","destinationIndicator", + NID_destinationIndicator,3,&(lvalues[5751]),0}, +{"preferredDeliveryMethod","preferredDeliveryMethod", + NID_preferredDeliveryMethod,3,&(lvalues[5754]),0}, +{"presentationAddress","presentationAddress",NID_presentationAddress, + 3,&(lvalues[5757]),0}, +{"supportedApplicationContext","supportedApplicationContext", + NID_supportedApplicationContext,3,&(lvalues[5760]),0}, +{"member","member",NID_member,3,&(lvalues[5763]),0}, +{"owner","owner",NID_owner,3,&(lvalues[5766]),0}, +{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0}, +{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0}, +{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0}, +{"userCertificate","userCertificate",NID_userCertificate,3, + &(lvalues[5778]),0}, +{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0}, +{"authorityRevocationList","authorityRevocationList", + NID_authorityRevocationList,3,&(lvalues[5784]),0}, +{"certificateRevocationList","certificateRevocationList", + NID_certificateRevocationList,3,&(lvalues[5787]),0}, +{"crossCertificatePair","crossCertificatePair", + NID_crossCertificatePair,3,&(lvalues[5790]),0}, +{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide, + 3,&(lvalues[5793]),0}, +{"protocolInformation","protocolInformation",NID_protocolInformation, + 3,&(lvalues[5796]),0}, +{"distinguishedName","distinguishedName",NID_distinguishedName,3, + &(lvalues[5799]),0}, +{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0}, +{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3, + &(lvalues[5805]),0}, +{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms, + 3,&(lvalues[5808]),0}, +{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList, + 3,&(lvalues[5811]),0}, +{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0}, +{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11, + &(lvalues[5817]),0}, +{"CMAC","cmac",NID_cmac,0,NULL,0}, +{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0}, +{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0}, +{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9, + &(lvalues[5846]),0}, +{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0}, +{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0}, +{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9, + &(lvalues[5873]),0}, +{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0}, +{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0}, +{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9, + &(lvalues[5900]),0}, +{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0}, +{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0}, +{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0}, +{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap, + 11,&(lvalues[5909]),0}, +{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap, + 11,&(lvalues[5920]),0}, +{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap, + 11,&(lvalues[5931]),0}, +{"anyExtendedKeyUsage","Any Extended Key Usage", + NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0}, +{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0}, +{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0}, +{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0}, +{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0}, +{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0}, +{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1", + NID_aes_128_cbc_hmac_sha1,0,NULL,0}, +{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1", + NID_aes_192_cbc_hmac_sha1,0,NULL,0}, +{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1", + NID_aes_256_cbc_hmac_sha1,0,NULL,0}, +{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0}, +{"teletrust","teletrust",NID_teletrust,2,&(lvalues[5973]),0}, +{"brainpool","brainpool",NID_brainpool,7,&(lvalues[5975]),0}, +{"brainpoolP160r1","brainpoolP160r1",NID_brainpoolP160r1,9, + &(lvalues[5982]),0}, +{"brainpoolP160t1","brainpoolP160t1",NID_brainpoolP160t1,9, + &(lvalues[5991]),0}, +{"brainpoolP192r1","brainpoolP192r1",NID_brainpoolP192r1,9, + &(lvalues[6000]),0}, +{"brainpoolP192t1","brainpoolP192t1",NID_brainpoolP192t1,9, + &(lvalues[6009]),0}, +{"brainpoolP224r1","brainpoolP224r1",NID_brainpoolP224r1,9, + &(lvalues[6018]),0}, +{"brainpoolP224t1","brainpoolP224t1",NID_brainpoolP224t1,9, + &(lvalues[6027]),0}, +{"brainpoolP256r1","brainpoolP256r1",NID_brainpoolP256r1,9, + &(lvalues[6036]),0}, +{"brainpoolP256t1","brainpoolP256t1",NID_brainpoolP256t1,9, + &(lvalues[6045]),0}, +{"brainpoolP320r1","brainpoolP320r1",NID_brainpoolP320r1,9, + &(lvalues[6054]),0}, +{"brainpoolP320t1","brainpoolP320t1",NID_brainpoolP320t1,9, + &(lvalues[6063]),0}, +{"brainpoolP384r1","brainpoolP384r1",NID_brainpoolP384r1,9, + &(lvalues[6072]),0}, +{"brainpoolP384t1","brainpoolP384t1",NID_brainpoolP384t1,9, + &(lvalues[6081]),0}, +{"brainpoolP512r1","brainpoolP512r1",NID_brainpoolP512r1,9, + &(lvalues[6090]),0}, +{"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9, + &(lvalues[6099]),0}, +{"FRP256v1","FRP256v1",NID_FRP256v1,10,&(lvalues[6108]),0}, +{"ChaCha","chacha",NID_chacha20,0,NULL,0}, +{"gost89-ecb","gost89-ecb",NID_gost89_ecb,0,NULL,0}, +{"gost89-cbc","gost89-cbc",NID_gost89_cbc,0,NULL,0}, +{"tc26","tc26",NID_tc26,5,&(lvalues[6118]),0}, +{"streebog256","GOST R 34.11-2012 (256 bit)", + NID_id_tc26_gost3411_2012_256,8,&(lvalues[6123]),0}, +{"streebog512","GOST R 34-11-2012 (512 bit)", + NID_id_tc26_gost3411_2012_512,8,&(lvalues[6131]),0}, +{"id-tc26-gost-3410-12-512-paramSetA", + "GOST R 34.10-2012 (512 bit) ParamSet A", + NID_id_tc26_gost_3410_12_512_paramSetA,9,&(lvalues[6139]),0}, +{"id-tc26-gost-3410-12-512-paramSetB", + "GOST R 34.10-2012 (512 bit) ParamSet B", + NID_id_tc26_gost_3410_12_512_paramSetB,9,&(lvalues[6148]),0}, +{"id-tc26-gost-28147-param-Z","id-tc26-gost-28147-param-Z", + NID_id_tc26_gost_28147_param_Z,9,&(lvalues[6157]),0}, +{"id-tc26-gost3410-2012-256","GOST R 34.10-2012 (256 bit)", + NID_id_tc26_gost3410_2012_256,8,&(lvalues[6166]),0}, +{"id-tc26-gost3410-2012-512","GOST R 34.10-2012 (512 bit)", + NID_id_tc26_gost3410_2012_512,8,&(lvalues[6174]),0}, +{"id-tc26-signwithdigest-gost3410-2012-256", + "GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)", + NID_id_tc26_signwithdigest_gost3410_2012_256,8,&(lvalues[6182]),0}, +{"id-tc26-signwithdigest-gost3410-2012-512", + "GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)", + NID_id_tc26_signwithdigest_gost3410_2012_512,8,&(lvalues[6190]),0}, +{"X25519","X25519",NID_X25519,3,&(lvalues[6198]),0}, +{"X448","X448",NID_X448,3,&(lvalues[6201]),0}, +{"Ed25519","Ed25519",NID_Ed25519,3,&(lvalues[6204]),0}, +{"Ed448","Ed448",NID_Ed448,3,&(lvalues[6207]),0}, +{"Ed25519ph","Ed25519ph",NID_Ed25519ph,3,&(lvalues[6210]),0}, +{"Ed448ph","Ed448ph",NID_Ed448ph,3,&(lvalues[6213]),0}, +{"jurisdictionLocalityName","jurisdictionLocalityName", + NID_jurisdictionLocalityName,11,&(lvalues[6216]),0}, +{"jurisdictionStateOrProvinceName","jurisdictionStateOrProvinceName", + NID_jurisdictionStateOrProvinceName,11,&(lvalues[6227]),0}, +{"jurisdictionCountryName","jurisdictionCountryName", + NID_jurisdictionCountryName,11,&(lvalues[6238]),0}, +{"KxRSA","kx-rsa",NID_kx_rsa,0,NULL,0}, +{"KxECDHE","kx-ecdhe",NID_kx_ecdhe,0,NULL,0}, +{"KxDHE","kx-dhe",NID_kx_dhe,0,NULL,0}, +{"KxGOST","kx-gost",NID_kx_gost,0,NULL,0}, +{"AuthRSA","auth-rsa",NID_auth_rsa,0,NULL,0}, +{"AuthECDSA","auth-ecdsa",NID_auth_ecdsa,0,NULL,0}, +{"AuthGOST01","auth-gost01",NID_auth_gost01,0,NULL,0}, +{"AuthNULL","auth-null",NID_auth_null,0,NULL,0}, +{"ChaCha20-Poly1305","chacha20-poly1305",NID_chacha20_poly1305,0,NULL,0}, +{"SM3","sm3",NID_sm3,8,&(lvalues[6249]),0}, +{"RSA-SM3","sm3WithRSAEncryption",NID_sm3WithRSAEncryption,8, + &(lvalues[6257]),0}, +{"ISO-CN","ISO CN Member Body",NID_ISO_CN,3,&(lvalues[6265]),0}, +{"oscca","oscca",NID_oscca,5,&(lvalues[6268]),0}, +{"sm-scheme","sm-scheme",NID_sm_scheme,6,&(lvalues[6273]),0}, +{"SM4-ECB","sm4-ecb",NID_sm4_ecb,8,&(lvalues[6279]),0}, +{"SM4-CBC","sm4-cbc",NID_sm4_cbc,8,&(lvalues[6287]),0}, +{"SM4-OFB","sm4-ofb",NID_sm4_ofb128,8,&(lvalues[6295]),0}, +{"SM4-CFB","sm4-cfb",NID_sm4_cfb128,8,&(lvalues[6303]),0}, +{"SM4-CFB1","sm4-cfb1",NID_sm4_cfb1,8,&(lvalues[6311]),0}, +{"SM4-CFB8","sm4-cfb8",NID_sm4_cfb8,8,&(lvalues[6319]),0}, +{"SM4-CTR","sm4-ctr",NID_sm4_ctr,8,&(lvalues[6327]),0}, +{"dhSinglePass-stdDH-sha1kdf-scheme", + "dhSinglePass-stdDH-sha1kdf-scheme", + NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6335]),0}, +{"dhSinglePass-stdDH-sha224kdf-scheme", + "dhSinglePass-stdDH-sha224kdf-scheme", + NID_dhSinglePass_stdDH_sha224kdf_scheme,6,&(lvalues[6344]),0}, +{"dhSinglePass-stdDH-sha256kdf-scheme", + "dhSinglePass-stdDH-sha256kdf-scheme", + NID_dhSinglePass_stdDH_sha256kdf_scheme,6,&(lvalues[6350]),0}, +{"dhSinglePass-stdDH-sha384kdf-scheme", + "dhSinglePass-stdDH-sha384kdf-scheme", + NID_dhSinglePass_stdDH_sha384kdf_scheme,6,&(lvalues[6356]),0}, +{"dhSinglePass-stdDH-sha512kdf-scheme", + "dhSinglePass-stdDH-sha512kdf-scheme", + NID_dhSinglePass_stdDH_sha512kdf_scheme,6,&(lvalues[6362]),0}, +{"dhSinglePass-cofactorDH-sha1kdf-scheme", + "dhSinglePass-cofactorDH-sha1kdf-scheme", + NID_dhSinglePass_cofactorDH_sha1kdf_scheme,9,&(lvalues[6368]),0}, +{"dhSinglePass-cofactorDH-sha224kdf-scheme", + "dhSinglePass-cofactorDH-sha224kdf-scheme", + NID_dhSinglePass_cofactorDH_sha224kdf_scheme,6,&(lvalues[6377]),0}, +{"dhSinglePass-cofactorDH-sha256kdf-scheme", + "dhSinglePass-cofactorDH-sha256kdf-scheme", + NID_dhSinglePass_cofactorDH_sha256kdf_scheme,6,&(lvalues[6383]),0}, +{"dhSinglePass-cofactorDH-sha384kdf-scheme", + "dhSinglePass-cofactorDH-sha384kdf-scheme", + NID_dhSinglePass_cofactorDH_sha384kdf_scheme,6,&(lvalues[6389]),0}, +{"dhSinglePass-cofactorDH-sha512kdf-scheme", + "dhSinglePass-cofactorDH-sha512kdf-scheme", + NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6395]),0}, +{"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0}, +{"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0}, +{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6401]),0}, +{"id-tc26-gost-3410-12-256-paramSetA", + "GOST R 34.10-2012 (256 bit) ParamSet A", + NID_id_tc26_gost_3410_12_256_paramSetA,9,&(lvalues[6410]),0}, +{"id-tc26-gost-3410-12-256-paramSetB", + "GOST R 34.10-2012 (256 bit) ParamSet B", + NID_id_tc26_gost_3410_12_256_paramSetB,9,&(lvalues[6419]),0}, +{"id-tc26-gost-3410-12-256-paramSetC", + "GOST R 34.10-2012 (256 bit) ParamSet C", + NID_id_tc26_gost_3410_12_256_paramSetC,9,&(lvalues[6428]),0}, +{"id-tc26-gost-3410-12-256-paramSetD", + "GOST R 34.10-2012 (256 bit) ParamSet D", + NID_id_tc26_gost_3410_12_256_paramSetD,9,&(lvalues[6437]),0}, +{"id-tc26-gost-3410-12-512-paramSetTest", + "GOST R 34.10-2012 (512 bit) testing parameter set", + NID_id_tc26_gost_3410_12_512_paramSetTest,9,&(lvalues[6446]),0}, +{"id-tc26-gost-3410-12-512-paramSetC", + "GOST R 34.10-2012 (512 bit) ParamSet C", + NID_id_tc26_gost_3410_12_512_paramSetC,9,&(lvalues[6455]),0}, +{"id-tc26-hmac-gost-3411-12-256","HMAC STREEBOG 256", + NID_id_tc26_hmac_gost_3411_12_256,8,&(lvalues[6464]),0}, +{"id-tc26-hmac-gost-3411-12-512","HMAC STREEBOG 512", + NID_id_tc26_hmac_gost_3411_12_512,8,&(lvalues[6472]),0}, +{"id-ct-routeOriginAuthz","id-ct-routeOriginAuthz", + NID_id_ct_routeOriginAuthz,11,&(lvalues[6480]),0}, +{"id-ct-rpkiManifest","id-ct-rpkiManifest",NID_id_ct_rpkiManifest,11, + &(lvalues[6491]),0}, +{"id-ct-rpkiGhostbusters","id-ct-rpkiGhostbusters", + NID_id_ct_rpkiGhostbusters,11,&(lvalues[6502]),0}, +{"id-ct-resourceTaggedAttest","id-ct-resourceTaggedAttest", + NID_id_ct_resourceTaggedAttest,11,&(lvalues[6513]),0}, +{"id-cp","id-cp",NID_id_cp,7,&(lvalues[6524]),0}, +{"sbgp-ipAddrBlockv2","sbgp-ipAddrBlockv2",NID_sbgp_ipAddrBlockv2,8, + &(lvalues[6531]),0}, +{"sbgp-autonomousSysNumv2","sbgp-autonomousSysNumv2", + NID_sbgp_autonomousSysNumv2,8,&(lvalues[6539]),0}, +{"ipAddr-asNumber","ipAddr-asNumber",NID_ipAddr_asNumber,8, + &(lvalues[6547]),0}, +{"ipAddr-asNumberv2","ipAddr-asNumberv2",NID_ipAddr_asNumberv2,8, + &(lvalues[6555]),0}, +{"rpkiManifest","RPKI Manifest",NID_rpkiManifest,8,&(lvalues[6563]),0}, +{"signedObject","Signed Object",NID_signedObject,8,&(lvalues[6571]),0}, +{"rpkiNotify","RPKI Notify",NID_rpkiNotify,8,&(lvalues[6579]),0}, +{"id-ct-geofeedCSVwithCRLF","id-ct-geofeedCSVwithCRLF", + NID_id_ct_geofeedCSVwithCRLF,11,&(lvalues[6587]),0}, +{"id-ct-signedChecklist","id-ct-signedChecklist", + NID_id_ct_signedChecklist,11,&(lvalues[6598]),0}, +{"id-kp-bgpsec-router","BGPsec Router",NID_id_kp_bgpsec_router,8, + &(lvalues[6609]),0}, +{"tlsfeature","TLS Feature",NID_tlsfeature,8,&(lvalues[6617]),0}, +{"id-ct-ASPA","id-ct-ASPA",NID_id_ct_ASPA,11,&(lvalues[6625]),0}, +{"ct_precert_scts","CT Precertificate SCTs",NID_ct_precert_scts,10, + &(lvalues[6636]),0}, +{"ct_precert_poison","CT Precertificate Poison",NID_ct_precert_poison, + 10,&(lvalues[6646]),0}, +{"ct_precert_signer","CT Precertificate Signer",NID_ct_precert_signer, + 10,&(lvalues[6656]),0}, +{"ct_cert_scts","CT Certificate SCTs",NID_ct_cert_scts,10, + &(lvalues[6666]),0}, +{"HKDF","hkdf",NID_hkdf,0,NULL,0}, +{"id-smime-aa-signingCertificateV2", + "id-smime-aa-signingCertificateV2", + NID_id_smime_aa_signingCertificateV2,11,&(lvalues[6676]),0}, +{"id-ct-signedTAL","id-ct-signedTAL",NID_id_ct_signedTAL,11, + &(lvalues[6687]),0}, +{"RSA-SHA512/224","sha512-224WithRSAEncryption", + NID_sha512_224WithRSAEncryption,9,&(lvalues[6698]),0}, +{"RSA-SHA512/256","sha512-256WithRSAEncryption", + NID_sha512_256WithRSAEncryption,9,&(lvalues[6707]),0}, +{"hmacWithSHA512-224","hmacWithSHA512-224",NID_hmacWithSHA512_224,8, + &(lvalues[6716]),0}, +{"hmacWithSHA512-256","hmacWithSHA512-256",NID_hmacWithSHA512_256,8, + &(lvalues[6724]),0}, +{"SHA512-224","sha512-224",NID_sha512_224,9,&(lvalues[6732]),0}, +{"SHA512-256","sha512-256",NID_sha512_256,9,&(lvalues[6741]),0}, +{"SHA3-224","sha3-224",NID_sha3_224,9,&(lvalues[6750]),0}, +{"SHA3-256","sha3-256",NID_sha3_256,9,&(lvalues[6759]),0}, +{"SHA3-384","sha3-384",NID_sha3_384,9,&(lvalues[6768]),0}, +{"SHA3-512","sha3-512",NID_sha3_512,9,&(lvalues[6777]),0}, +{"id-hmacWithSHA3-224","hmac-sha3-224",NID_hmac_sha3_224,9, + &(lvalues[6786]),0}, +{"id-hmacWithSHA3-256","hmac-sha3-256",NID_hmac_sha3_256,9, + &(lvalues[6795]),0}, +{"id-hmacWithSHA3-384","hmac-sha3-384",NID_hmac_sha3_384,9, + &(lvalues[6804]),0}, +{"id-hmacWithSHA3-512","hmac-sha3-512",NID_hmac_sha3_512,9, + &(lvalues[6813]),0}, +{"id-dsa-with-sha384","dsa_with_SHA384",NID_dsa_with_SHA384,9, + &(lvalues[6822]),0}, +{"id-dsa-with-sha512","dsa_with_SHA512",NID_dsa_with_SHA512,9, + &(lvalues[6831]),0}, +{"id-dsa-with-sha3-224","dsa_with_SHA3-224",NID_dsa_with_SHA3_224,9, + &(lvalues[6840]),0}, +{"id-dsa-with-sha3-256","dsa_with_SHA3-256",NID_dsa_with_SHA3_256,9, + &(lvalues[6849]),0}, +{"id-dsa-with-sha3-384","dsa_with_SHA3-384",NID_dsa_with_SHA3_384,9, + &(lvalues[6858]),0}, +{"id-dsa-with-sha3-512","dsa_with_SHA3-512",NID_dsa_with_SHA3_512,9, + &(lvalues[6867]),0}, +{"id-ecdsa-with-sha3-224","ecdsa_with_SHA3-224", + NID_ecdsa_with_SHA3_224,9,&(lvalues[6876]),0}, +{"id-ecdsa-with-sha3-256","ecdsa_with_SHA3-256", + NID_ecdsa_with_SHA3_256,9,&(lvalues[6885]),0}, +{"id-ecdsa-with-sha3-384","ecdsa_with_SHA3-384", + NID_ecdsa_with_SHA3_384,9,&(lvalues[6894]),0}, +{"id-ecdsa-with-sha3-512","ecdsa_with_SHA3-512", + NID_ecdsa_with_SHA3_512,9,&(lvalues[6903]),0}, +{"id-rsassa-pkcs1-v1_5-with-sha3-224","RSA-SHA3-224",NID_RSA_SHA3_224, + 9,&(lvalues[6912]),0}, +{"id-rsassa-pkcs1-v1_5-with-sha3-256","RSA-SHA3-256",NID_RSA_SHA3_256, + 9,&(lvalues[6921]),0}, +{"id-rsassa-pkcs1-v1_5-with-sha3-384","RSA-SHA3-384",NID_RSA_SHA3_384, + 9,&(lvalues[6930]),0}, +{"id-rsassa-pkcs1-v1_5-with-sha3-512","RSA-SHA3-512",NID_RSA_SHA3_512, + 9,&(lvalues[6939]),0}, +}; + +static const unsigned int sn_objs[NUM_SN]={ +364, /* "AD_DVCS" */ +419, /* "AES-128-CBC" */ +916, /* "AES-128-CBC-HMAC-SHA1" */ +421, /* "AES-128-CFB" */ +650, /* "AES-128-CFB1" */ +653, /* "AES-128-CFB8" */ +904, /* "AES-128-CTR" */ +418, /* "AES-128-ECB" */ +420, /* "AES-128-OFB" */ +913, /* "AES-128-XTS" */ +423, /* "AES-192-CBC" */ +917, /* "AES-192-CBC-HMAC-SHA1" */ +425, /* "AES-192-CFB" */ +651, /* "AES-192-CFB1" */ +654, /* "AES-192-CFB8" */ +905, /* "AES-192-CTR" */ +422, /* "AES-192-ECB" */ +424, /* "AES-192-OFB" */ +427, /* "AES-256-CBC" */ +918, /* "AES-256-CBC-HMAC-SHA1" */ +429, /* "AES-256-CFB" */ +652, /* "AES-256-CFB1" */ +655, /* "AES-256-CFB8" */ +906, /* "AES-256-CTR" */ +426, /* "AES-256-ECB" */ +428, /* "AES-256-OFB" */ +914, /* "AES-256-XTS" */ +964, /* "AuthECDSA" */ +965, /* "AuthGOST01" */ +966, /* "AuthNULL" */ +963, /* "AuthRSA" */ +91, /* "BF-CBC" */ +93, /* "BF-CFB" */ +92, /* "BF-ECB" */ +94, /* "BF-OFB" */ +14, /* "C" */ +751, /* "CAMELLIA-128-CBC" */ +757, /* "CAMELLIA-128-CFB" */ +760, /* "CAMELLIA-128-CFB1" */ +763, /* "CAMELLIA-128-CFB8" */ +754, /* "CAMELLIA-128-ECB" */ +766, /* "CAMELLIA-128-OFB" */ +752, /* "CAMELLIA-192-CBC" */ +758, /* "CAMELLIA-192-CFB" */ +761, /* "CAMELLIA-192-CFB1" */ +764, /* "CAMELLIA-192-CFB8" */ +755, /* "CAMELLIA-192-ECB" */ +767, /* "CAMELLIA-192-OFB" */ +753, /* "CAMELLIA-256-CBC" */ +759, /* "CAMELLIA-256-CFB" */ +762, /* "CAMELLIA-256-CFB1" */ +765, /* "CAMELLIA-256-CFB8" */ +756, /* "CAMELLIA-256-ECB" */ +768, /* "CAMELLIA-256-OFB" */ +108, /* "CAST5-CBC" */ +110, /* "CAST5-CFB" */ +109, /* "CAST5-ECB" */ +111, /* "CAST5-OFB" */ +894, /* "CMAC" */ +13, /* "CN" */ +141, /* "CRLReason" */ +417, /* "CSPName" */ +937, /* "ChaCha" */ +967, /* "ChaCha20-Poly1305" */ +367, /* "CrlID" */ +391, /* "DC" */ +31, /* "DES-CBC" */ +643, /* "DES-CDMF" */ +30, /* "DES-CFB" */ +656, /* "DES-CFB1" */ +657, /* "DES-CFB8" */ +29, /* "DES-ECB" */ +32, /* "DES-EDE" */ +43, /* "DES-EDE-CBC" */ +60, /* "DES-EDE-CFB" */ +62, /* "DES-EDE-OFB" */ +33, /* "DES-EDE3" */ +44, /* "DES-EDE3-CBC" */ +61, /* "DES-EDE3-CFB" */ +658, /* "DES-EDE3-CFB1" */ +659, /* "DES-EDE3-CFB8" */ +63, /* "DES-EDE3-OFB" */ +45, /* "DES-OFB" */ +80, /* "DESX-CBC" */ +380, /* "DOD" */ +116, /* "DSA" */ +66, /* "DSA-SHA" */ +113, /* "DSA-SHA1" */ +70, /* "DSA-SHA1-old" */ +67, /* "DSA-old" */ +297, /* "DVCS" */ +952, /* "Ed25519" */ +954, /* "Ed25519ph" */ +953, /* "Ed448" */ +955, /* "Ed448ph" */ +936, /* "FRP256v1" */ +99, /* "GN" */ +1022, /* "HKDF" */ +855, /* "HMAC" */ +780, /* "HMAC-MD5" */ +781, /* "HMAC-SHA1" */ +381, /* "IANA" */ +34, /* "IDEA-CBC" */ +35, /* "IDEA-CFB" */ +36, /* "IDEA-ECB" */ +46, /* "IDEA-OFB" */ +181, /* "ISO" */ +970, /* "ISO-CN" */ +183, /* "ISO-US" */ +645, /* "ITU-T" */ +646, /* "JOINT-ISO-ITU-T" */ +773, /* "KISA" */ +961, /* "KxDHE" */ +960, /* "KxECDHE" */ +962, /* "KxGOST" */ +959, /* "KxRSA" */ +15, /* "L" */ +856, /* "LocalKeySet" */ + 3, /* "MD2" */ +257, /* "MD4" */ + 4, /* "MD5" */ +114, /* "MD5-SHA1" */ +95, /* "MDC2" */ +911, /* "MGF1" */ +388, /* "Mail" */ +393, /* "NULL" */ +404, /* "NULL" */ +57, /* "Netscape" */ +366, /* "Nonce" */ +17, /* "O" */ +178, /* "OCSP" */ +180, /* "OCSPSigning" */ +379, /* "ORG" */ +18, /* "OU" */ +749, /* "Oakley-EC2N-3" */ +750, /* "Oakley-EC2N-4" */ + 9, /* "PBE-MD2-DES" */ +168, /* "PBE-MD2-RC2-64" */ +10, /* "PBE-MD5-DES" */ +169, /* "PBE-MD5-RC2-64" */ +147, /* "PBE-SHA1-2DES" */ +146, /* "PBE-SHA1-3DES" */ +170, /* "PBE-SHA1-DES" */ +148, /* "PBE-SHA1-RC2-128" */ +149, /* "PBE-SHA1-RC2-40" */ +68, /* "PBE-SHA1-RC2-64" */ +144, /* "PBE-SHA1-RC4-128" */ +145, /* "PBE-SHA1-RC4-40" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +992, /* "PSPECIFIED" */ +98, /* "RC2-40-CBC" */ +166, /* "RC2-64-CBC" */ +37, /* "RC2-CBC" */ +39, /* "RC2-CFB" */ +38, /* "RC2-ECB" */ +40, /* "RC2-OFB" */ + 5, /* "RC4" */ +97, /* "RC4-40" */ +915, /* "RC4-HMAC-MD5" */ +120, /* "RC5-CBC" */ +122, /* "RC5-CFB" */ +121, /* "RC5-ECB" */ +123, /* "RC5-OFB" */ +117, /* "RIPEMD160" */ +124, /* "RLE" */ +19, /* "RSA" */ + 7, /* "RSA-MD2" */ +396, /* "RSA-MD4" */ + 8, /* "RSA-MD5" */ +96, /* "RSA-MDC2" */ +104, /* "RSA-NP-MD5" */ +119, /* "RSA-RIPEMD160" */ +42, /* "RSA-SHA" */ +65, /* "RSA-SHA1" */ +115, /* "RSA-SHA1-2" */ +671, /* "RSA-SHA224" */ +668, /* "RSA-SHA256" */ +669, /* "RSA-SHA384" */ +670, /* "RSA-SHA512" */ +1025, /* "RSA-SHA512/224" */ +1026, /* "RSA-SHA512/256" */ +969, /* "RSA-SM3" */ +919, /* "RSAES-OAEP" */ +912, /* "RSASSA-PSS" */ +777, /* "SEED-CBC" */ +779, /* "SEED-CFB" */ +776, /* "SEED-ECB" */ +778, /* "SEED-OFB" */ +41, /* "SHA" */ +64, /* "SHA1" */ +675, /* "SHA224" */ +672, /* "SHA256" */ +1031, /* "SHA3-224" */ +1032, /* "SHA3-256" */ +1033, /* "SHA3-384" */ +1034, /* "SHA3-512" */ +673, /* "SHA384" */ +674, /* "SHA512" */ +1029, /* "SHA512-224" */ +1030, /* "SHA512-256" */ +968, /* "SM3" */ +974, /* "SM4-CBC" */ +976, /* "SM4-CFB" */ +977, /* "SM4-CFB1" */ +978, /* "SM4-CFB8" */ +979, /* "SM4-CTR" */ +973, /* "SM4-ECB" */ +975, /* "SM4-OFB" */ +188, /* "SMIME" */ +167, /* "SMIME-CAPS" */ +100, /* "SN" */ +16, /* "ST" */ +143, /* "SXNetID" */ +458, /* "UID" */ + 0, /* "UNDEF" */ +950, /* "X25519" */ +951, /* "X448" */ +11, /* "X500" */ +378, /* "X500algorithms" */ +12, /* "X509" */ +184, /* "X9-57" */ +185, /* "X9cm" */ +125, /* "ZLIB" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +368, /* "acceptableResponses" */ +446, /* "account" */ +363, /* "ad_timestamping" */ +376, /* "algorithm" */ +405, /* "ansi-X9-62" */ +910, /* "anyExtendedKeyUsage" */ +746, /* "anyPolicy" */ +370, /* "archiveCutoff" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +177, /* "authorityInfoAccess" */ +90, /* "authorityKeyIdentifier" */ +882, /* "authorityRevocationList" */ +87, /* "basicConstraints" */ +365, /* "basicOCSPResponse" */ +285, /* "biometricInfo" */ +921, /* "brainpool" */ +922, /* "brainpoolP160r1" */ +923, /* "brainpoolP160t1" */ +924, /* "brainpoolP192r1" */ +925, /* "brainpoolP192t1" */ +926, /* "brainpoolP224r1" */ +927, /* "brainpoolP224t1" */ +928, /* "brainpoolP256r1" */ +929, /* "brainpoolP256t1" */ +930, /* "brainpoolP320r1" */ +931, /* "brainpoolP320t1" */ +932, /* "brainpoolP384r1" */ +933, /* "brainpoolP384t1" */ +934, /* "brainpoolP512r1" */ +935, /* "brainpoolP512t1" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +179, /* "caIssuers" */ +785, /* "caRepository" */ +443, /* "caseIgnoreIA5StringSyntax" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +771, /* "certificateIssuer" */ +89, /* "certificatePolicies" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +130, /* "clientAuth" */ +131, /* "codeSigning" */ +50, /* "contentType" */ +53, /* "countersignature" */ +153, /* "crlBag" */ +103, /* "crlDistributionPoints" */ +88, /* "crlNumber" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +1021, /* "ct_cert_scts" */ +1019, /* "ct_precert_poison" */ +1018, /* "ct_precert_scts" */ +1020, /* "ct_precert_signer" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcobject" */ +140, /* "deltaCRL" */ +891, /* "deltaRevocationList" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +991, /* "dh-cofactor-kdf" */ +990, /* "dh-std-kdf" */ +28, /* "dhKeyAgreement" */ +985, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ +986, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ +987, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ +988, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ +989, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ +980, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ +981, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ +982, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ +983, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ +984, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ +382, /* "directory" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +392, /* "domain" */ +452, /* "domainRelatedObject" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +132, /* "emailProtection" */ +885, /* "enhancedSearchGuide" */ +389, /* "enterprises" */ +384, /* "experimental" */ +172, /* "extReq" */ +56, /* "extendedCertificateAttributes" */ +126, /* "extendedKeyUsage" */ +372, /* "extendedStatus" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +857, /* "freshestCRL" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +509, /* "generationQualifier" */ +815, /* "gost-mac" */ +811, /* "gost2001" */ +851, /* "gost2001cc" */ +813, /* "gost89" */ +939, /* "gost89-cbc" */ +814, /* "gost89-cnt" */ +938, /* "gost89-ecb" */ +812, /* "gost94" */ +850, /* "gost94cc" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +1027, /* "hmacWithSHA512-224" */ +1028, /* "hmacWithSHA512-256" */ +432, /* "holdInstructionCallIssuer" */ +430, /* "holdInstructionCode" */ +431, /* "holdInstructionNone" */ +433, /* "holdInstructionReject" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +783, /* "id-DHBasedMac" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +849, /* "id-Gost28147-89-cc" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +854, /* "id-GostR3410-2001-ParamSet-cc" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +817, /* "id-GostR3410-2001DH" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +818, /* "id-GostR3410-94DH" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +807, /* "id-GostR3411-94-with-GostR3410-2001" */ +853, /* "id-GostR3411-94-with-GostR3410-2001-cc" */ +808, /* "id-GostR3411-94-with-GostR3410-94" */ +852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ +810, /* "id-HMACGostR3411-94" */ +782, /* "id-PasswordBasedMAC" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +896, /* "id-aes128-CCM" */ +895, /* "id-aes128-GCM" */ +788, /* "id-aes128-wrap" */ +897, /* "id-aes128-wrap-pad" */ +899, /* "id-aes192-CCM" */ +898, /* "id-aes192-GCM" */ +789, /* "id-aes192-wrap" */ +900, /* "id-aes192-wrap-pad" */ +902, /* "id-aes256-CCM" */ +901, /* "id-aes256-GCM" */ +790, /* "id-aes256-wrap" */ +903, /* "id-aes256-wrap-pad" */ +262, /* "id-alg" */ +893, /* "id-alg-PWRI-KEK" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +907, /* "id-camellia128-wrap" */ +908, /* "id-camellia192-wrap" */ +909, /* "id-camellia256-wrap" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +1005, /* "id-cp" */ +1017, /* "id-ct-ASPA" */ +787, /* "id-ct-asciiTextWithCRLF" */ +1013, /* "id-ct-geofeedCSVwithCRLF" */ +1004, /* "id-ct-resourceTaggedAttest" */ +1001, /* "id-ct-routeOriginAuthz" */ +1003, /* "id-ct-rpkiGhostbusters" */ +1002, /* "id-ct-rpkiManifest" */ +1014, /* "id-ct-signedChecklist" */ +1024, /* "id-ct-signedTAL" */ +802, /* "id-dsa-with-sha224" */ +803, /* "id-dsa-with-sha256" */ +1041, /* "id-dsa-with-sha3-224" */ +1042, /* "id-dsa-with-sha3-256" */ +1043, /* "id-dsa-with-sha3-384" */ +1044, /* "id-dsa-with-sha3-512" */ +1039, /* "id-dsa-with-sha384" */ +1040, /* "id-dsa-with-sha512" */ +408, /* "id-ecPublicKey" */ +1045, /* "id-ecdsa-with-sha3-224" */ +1046, /* "id-ecdsa-with-sha3-256" */ +1047, /* "id-ecdsa-with-sha3-384" */ +1048, /* "id-ecdsa-with-sha3-512" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +1035, /* "id-hmacWithSHA3-224" */ +1036, /* "id-hmacWithSHA3-256" */ +1037, /* "id-hmacWithSHA3-384" */ +1038, /* "id-hmacWithSHA3-512" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +1015, /* "id-kp-bgpsec-router" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +858, /* "id-on-permanentIdentifier" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +664, /* "id-ppl-anyLanguage" */ +667, /* "id-ppl-independent" */ +665, /* "id-ppl-inheritAll" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +164, /* "id-qt-cps" */ +165, /* "id-qt-unotice" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +1049, /* "id-rsassa-pkcs1-v1_5-with-sha3-224" */ +1050, /* "id-rsassa-pkcs1-v1_5-with-sha3-256" */ +1051, /* "id-rsassa-pkcs1-v1_5-with-sha3-384" */ +1052, /* "id-rsassa-pkcs1-v1_5-with-sha3-512" */ +512, /* "id-set" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +1023, /* "id-smime-aa-signingCertificateV2" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +945, /* "id-tc26-gost-28147-param-Z" */ +993, /* "id-tc26-gost-3410-12-256-paramSetA" */ +994, /* "id-tc26-gost-3410-12-256-paramSetB" */ +995, /* "id-tc26-gost-3410-12-256-paramSetC" */ +996, /* "id-tc26-gost-3410-12-256-paramSetD" */ +943, /* "id-tc26-gost-3410-12-512-paramSetA" */ +944, /* "id-tc26-gost-3410-12-512-paramSetB" */ +998, /* "id-tc26-gost-3410-12-512-paramSetC" */ +997, /* "id-tc26-gost-3410-12-512-paramSetTest" */ +946, /* "id-tc26-gost3410-2012-256" */ +947, /* "id-tc26-gost3410-2012-512" */ +999, /* "id-tc26-hmac-gost-3411-12-256" */ +1000, /* "id-tc26-hmac-gost-3411-12-512" */ +948, /* "id-tc26-signwithdigest-gost3410-2012-256" */ +949, /* "id-tc26-signwithdigest-gost3410-2012-512" */ +676, /* "identified-organization" */ +461, /* "info" */ +748, /* "inhibitAnyPolicy" */ +101, /* "initials" */ +647, /* "international-organizations" */ +869, /* "internationaliSDNNumber" */ +142, /* "invalidityDate" */ +1008, /* "ipAddr-asNumber" */ +1009, /* "ipAddr-asNumberv2" */ +294, /* "ipsecEndSystem" */ +295, /* "ipsecTunnel" */ +296, /* "ipsecUser" */ +86, /* "issuerAltName" */ +770, /* "issuingDistributionPoint" */ +492, /* "janetMailbox" */ +958, /* "jurisdictionCountryName" */ +956, /* "jurisdictionLocalityName" */ +957, /* "jurisdictionStateOrProvinceName" */ +150, /* "keyBag" */ +83, /* "keyUsage" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +480, /* "mXRecord" */ +460, /* "mail" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ +809, /* "md_gost94" */ +875, /* "member" */ +182, /* "member-body" */ +51, /* "messageDigest" */ +383, /* "mgmt" */ +504, /* "mime-mhs" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +136, /* "msCTLSign" */ +135, /* "msCodeCom" */ +134, /* "msCodeInd" */ +138, /* "msEFS" */ +171, /* "msExtReq" */ +137, /* "msSGC" */ +648, /* "msSmartcardLogin" */ +649, /* "msUPN" */ +481, /* "nSRecord" */ +173, /* "name" */ +666, /* "nameConstraints" */ +369, /* "noCheck" */ +403, /* "noRevAvail" */ +72, /* "nsBaseUrl" */ +76, /* "nsCaPolicyUrl" */ +74, /* "nsCaRevocationUrl" */ +58, /* "nsCertExt" */ +79, /* "nsCertSequence" */ +71, /* "nsCertType" */ +78, /* "nsComment" */ +59, /* "nsDataType" */ +75, /* "nsRenewalUrl" */ +73, /* "nsRevocationUrl" */ +139, /* "nsSGC" */ +77, /* "nsSslServerName" */ +681, /* "onBasis" */ +491, /* "organizationalStatus" */ +971, /* "oscca" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +489, /* "pagerTelephoneNumber" */ +374, /* "path" */ +112, /* "pbeWithMD5AndCast5CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ + 2, /* "pkcs" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +401, /* "policyConstraints" */ +747, /* "policyMappings" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +816, /* "prf-gostr3411-94" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +385, /* "private" */ +84, /* "privateKeyUsagePeriod" */ +886, /* "protocolInformation" */ +663, /* "proxyCertInfo" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +870, /* "registeredAddress" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ +1010, /* "rpkiManifest" */ +1012, /* "rpkiNotify" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ + 1, /* "rsadsi" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +1007, /* "sbgp-autonomousSysNumv2" */ +290, /* "sbgp-ipAddrBlock" */ +1006, /* "sbgp-ipAddrBlockv2" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +386, /* "security" */ +878, /* "seeAlso" */ +394, /* "selected-attribute-types" */ +105, /* "serialNumber" */ +129, /* "serverAuth" */ +371, /* "serviceLocator" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +517, /* "set-certExt" */ +513, /* "set-ctype" */ +514, /* "set-msgExt" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +631, /* "setAttr-GenCryptgrm" */ +623, /* "setAttr-IssCap" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +621, /* "setAttr-PGWYcap" */ +635, /* "setAttr-SecDevSig" */ +632, /* "setAttr-T2Enc" */ +633, /* "setAttr-T2cleartxt" */ +634, /* "setAttr-TokICCsig" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +606, /* "setext-cv" */ +601, /* "setext-genCrypt" */ +602, /* "setext-miAuth" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +1011, /* "signedObject" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +972, /* "sm-scheme" */ +387, /* "snmpv2" */ +941, /* "streebog256" */ +942, /* "streebog512" */ +660, /* "street" */ +85, /* "subjectAltName" */ +769, /* "subjectDirectoryAttributes" */ +398, /* "subjectInfoAccess" */ +82, /* "subjectKeyIdentifier" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +402, /* "targetInformation" */ +940, /* "tc26" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +920, /* "teletrust" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +133, /* "timeStamping" */ +106, /* "title" */ +1016, /* "tlsfeature" */ +682, /* "tpBasis" */ +375, /* "trustRoot" */ +436, /* "ucl" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +}; + +static const unsigned int ln_objs[NUM_LN]={ +363, /* "AD Time Stamping" */ +405, /* "ANSI X9.62" */ +368, /* "Acceptable OCSP Responses" */ +910, /* "Any Extended Key Usage" */ +664, /* "Any language" */ +177, /* "Authority Information Access" */ +1015, /* "BGPsec Router" */ +365, /* "Basic OCSP Response" */ +285, /* "Biometric Info" */ +179, /* "CA Issuers" */ +785, /* "CA Repository" */ +1021, /* "CT Certificate SCTs" */ +1019, /* "CT Precertificate Poison" */ +1018, /* "CT Precertificate SCTs" */ +1020, /* "CT Precertificate Signer" */ +131, /* "Code Signing" */ +783, /* "Diffie-Hellman based MAC" */ +382, /* "Directory" */ +392, /* "Domain" */ +132, /* "E-mail Protection" */ +952, /* "Ed25519" */ +954, /* "Ed25519ph" */ +953, /* "Ed448" */ +955, /* "Ed448ph" */ +389, /* "Enterprises" */ +384, /* "Experimental" */ +372, /* "Extended OCSP Status" */ +172, /* "Extension Request" */ +936, /* "FRP256v1" */ +813, /* "GOST 28147-89" */ +849, /* "GOST 28147-89 Cryptocom ParamSet" */ +815, /* "GOST 28147-89 MAC" */ +851, /* "GOST 34.10-2001 Cryptocom" */ +850, /* "GOST 34.10-94 Cryptocom" */ +942, /* "GOST R 34-11-2012 (512 bit)" */ +811, /* "GOST R 34.10-2001" */ +817, /* "GOST R 34.10-2001 DH" */ +946, /* "GOST R 34.10-2012 (256 bit)" */ +993, /* "GOST R 34.10-2012 (256 bit) ParamSet A" */ +994, /* "GOST R 34.10-2012 (256 bit) ParamSet B" */ +995, /* "GOST R 34.10-2012 (256 bit) ParamSet C" */ +996, /* "GOST R 34.10-2012 (256 bit) ParamSet D" */ +947, /* "GOST R 34.10-2012 (512 bit)" */ +943, /* "GOST R 34.10-2012 (512 bit) ParamSet A" */ +944, /* "GOST R 34.10-2012 (512 bit) ParamSet B" */ +998, /* "GOST R 34.10-2012 (512 bit) ParamSet C" */ +997, /* "GOST R 34.10-2012 (512 bit) testing parameter set" */ +812, /* "GOST R 34.10-94" */ +818, /* "GOST R 34.10-94 DH" */ +941, /* "GOST R 34.11-2012 (256 bit)" */ +948, /* "GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)" */ +949, /* "GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)" */ +809, /* "GOST R 34.11-94" */ +816, /* "GOST R 34.11-94 PRF" */ +807, /* "GOST R 34.11-94 with GOST R 34.10-2001" */ +853, /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ +808, /* "GOST R 34.11-94 with GOST R 34.10-94" */ +852, /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ +854, /* "GOST R 3410-2001 Parameter Set Cryptocom" */ +810, /* "HMAC GOST 34.11-94" */ +999, /* "HMAC STREEBOG 256" */ +1000, /* "HMAC STREEBOG 512" */ +432, /* "Hold Instruction Call Issuer" */ +430, /* "Hold Instruction Code" */ +431, /* "Hold Instruction None" */ +433, /* "Hold Instruction Reject" */ +634, /* "ICC or token signature" */ +294, /* "IPSec End System" */ +295, /* "IPSec Tunnel" */ +296, /* "IPSec User" */ +970, /* "ISO CN Member Body" */ +182, /* "ISO Member Body" */ +183, /* "ISO US Member Body" */ +667, /* "Independent" */ +665, /* "Inherit all" */ +647, /* "International Organizations" */ +142, /* "Invalidity Date" */ +504, /* "MIME MHS" */ +388, /* "Mail" */ +383, /* "Management" */ +417, /* "Microsoft CSP Name" */ +135, /* "Microsoft Commercial Code Signing" */ +138, /* "Microsoft Encrypted File System" */ +171, /* "Microsoft Extension Request" */ +134, /* "Microsoft Individual Code Signing" */ +856, /* "Microsoft Local Key set" */ +137, /* "Microsoft Server Gated Crypto" */ +648, /* "Microsoft Smartcardlogin" */ +136, /* "Microsoft Trust List Signing" */ +649, /* "Microsoft Universal Principal Name" */ +393, /* "NULL" */ +404, /* "NULL" */ +72, /* "Netscape Base Url" */ +76, /* "Netscape CA Policy Url" */ +74, /* "Netscape CA Revocation Url" */ +71, /* "Netscape Cert Type" */ +58, /* "Netscape Certificate Extension" */ +79, /* "Netscape Certificate Sequence" */ +78, /* "Netscape Comment" */ +57, /* "Netscape Communications Corp." */ +59, /* "Netscape Data Type" */ +75, /* "Netscape Renewal Url" */ +73, /* "Netscape Revocation Url" */ +77, /* "Netscape SSL Server Name" */ +139, /* "Netscape Server Gated Crypto" */ +178, /* "OCSP" */ +370, /* "OCSP Archive Cutoff" */ +367, /* "OCSP CRL ID" */ +369, /* "OCSP No Check" */ +366, /* "OCSP Nonce" */ +371, /* "OCSP Service Locator" */ +180, /* "OCSP Signing" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +858, /* "Permanent Identifier" */ +164, /* "Policy Qualifier CPS" */ +165, /* "Policy Qualifier User Notice" */ +385, /* "Private" */ +663, /* "Proxy Certificate Information" */ +1010, /* "RPKI Manifest" */ +1012, /* "RPKI Notify" */ + 1, /* "RSA Data Security, Inc." */ + 2, /* "RSA Data Security, Inc. PKCS" */ +1049, /* "RSA-SHA3-224" */ +1050, /* "RSA-SHA3-256" */ +1051, /* "RSA-SHA3-384" */ +1052, /* "RSA-SHA3-512" */ +188, /* "S/MIME" */ +167, /* "S/MIME Capabilities" */ +387, /* "SNMPv2" */ +512, /* "Secure Electronic Transactions" */ +386, /* "Security" */ +394, /* "Selected Attribute Types" */ +1011, /* "Signed Object" */ +143, /* "Strong Extranet ID" */ +398, /* "Subject Information Access" */ +1016, /* "TLS Feature" */ +130, /* "TLS Web Client Authentication" */ +129, /* "TLS Web Server Authentication" */ +133, /* "Time Stamping" */ +375, /* "Trust Root" */ +950, /* "X25519" */ +951, /* "X448" */ +12, /* "X509" */ +402, /* "X509v3 AC Targeting" */ +746, /* "X509v3 Any Policy" */ +90, /* "X509v3 Authority Key Identifier" */ +87, /* "X509v3 Basic Constraints" */ +103, /* "X509v3 CRL Distribution Points" */ +88, /* "X509v3 CRL Number" */ +141, /* "X509v3 CRL Reason Code" */ +771, /* "X509v3 Certificate Issuer" */ +89, /* "X509v3 Certificate Policies" */ +140, /* "X509v3 Delta CRL Indicator" */ +126, /* "X509v3 Extended Key Usage" */ +857, /* "X509v3 Freshest CRL" */ +748, /* "X509v3 Inhibit Any Policy" */ +86, /* "X509v3 Issuer Alternative Name" */ +770, /* "X509v3 Issuing Distribution Point" */ +83, /* "X509v3 Key Usage" */ +666, /* "X509v3 Name Constraints" */ +403, /* "X509v3 No Revocation Available" */ +401, /* "X509v3 Policy Constraints" */ +747, /* "X509v3 Policy Mappings" */ +84, /* "X509v3 Private Key Usage Period" */ +85, /* "X509v3 Subject Alternative Name" */ +769, /* "X509v3 Subject Directory Attributes" */ +82, /* "X509v3 Subject Key Identifier" */ +184, /* "X9.57" */ +185, /* "X9.57 CM ?" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +446, /* "account" */ +364, /* "ad dvcs" */ +606, /* "additional verification" */ +419, /* "aes-128-cbc" */ +916, /* "aes-128-cbc-hmac-sha1" */ +896, /* "aes-128-ccm" */ +421, /* "aes-128-cfb" */ +650, /* "aes-128-cfb1" */ +653, /* "aes-128-cfb8" */ +904, /* "aes-128-ctr" */ +418, /* "aes-128-ecb" */ +895, /* "aes-128-gcm" */ +420, /* "aes-128-ofb" */ +913, /* "aes-128-xts" */ +423, /* "aes-192-cbc" */ +917, /* "aes-192-cbc-hmac-sha1" */ +899, /* "aes-192-ccm" */ +425, /* "aes-192-cfb" */ +651, /* "aes-192-cfb1" */ +654, /* "aes-192-cfb8" */ +905, /* "aes-192-ctr" */ +422, /* "aes-192-ecb" */ +898, /* "aes-192-gcm" */ +424, /* "aes-192-ofb" */ +427, /* "aes-256-cbc" */ +918, /* "aes-256-cbc-hmac-sha1" */ +902, /* "aes-256-ccm" */ +429, /* "aes-256-cfb" */ +652, /* "aes-256-cfb1" */ +655, /* "aes-256-cfb8" */ +906, /* "aes-256-ctr" */ +426, /* "aes-256-ecb" */ +901, /* "aes-256-gcm" */ +428, /* "aes-256-ofb" */ +914, /* "aes-256-xts" */ +376, /* "algorithm" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +964, /* "auth-ecdsa" */ +965, /* "auth-gost01" */ +966, /* "auth-null" */ +963, /* "auth-rsa" */ +882, /* "authorityRevocationList" */ +91, /* "bf-cbc" */ +93, /* "bf-cfb" */ +92, /* "bf-ecb" */ +94, /* "bf-ofb" */ +921, /* "brainpool" */ +922, /* "brainpoolP160r1" */ +923, /* "brainpoolP160t1" */ +924, /* "brainpoolP192r1" */ +925, /* "brainpoolP192t1" */ +926, /* "brainpoolP224r1" */ +927, /* "brainpoolP224t1" */ +928, /* "brainpoolP256r1" */ +929, /* "brainpoolP256t1" */ +930, /* "brainpoolP320r1" */ +931, /* "brainpoolP320t1" */ +932, /* "brainpoolP384r1" */ +933, /* "brainpoolP384t1" */ +934, /* "brainpoolP512r1" */ +935, /* "brainpoolP512t1" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +751, /* "camellia-128-cbc" */ +757, /* "camellia-128-cfb" */ +760, /* "camellia-128-cfb1" */ +763, /* "camellia-128-cfb8" */ +754, /* "camellia-128-ecb" */ +766, /* "camellia-128-ofb" */ +752, /* "camellia-192-cbc" */ +758, /* "camellia-192-cfb" */ +761, /* "camellia-192-cfb1" */ +764, /* "camellia-192-cfb8" */ +755, /* "camellia-192-ecb" */ +767, /* "camellia-192-ofb" */ +753, /* "camellia-256-cbc" */ +759, /* "camellia-256-cfb" */ +762, /* "camellia-256-cfb1" */ +765, /* "camellia-256-cfb8" */ +756, /* "camellia-256-ecb" */ +768, /* "camellia-256-ofb" */ +443, /* "caseIgnoreIA5StringSyntax" */ +108, /* "cast5-cbc" */ +110, /* "cast5-cfb" */ +109, /* "cast5-ecb" */ +111, /* "cast5-ofb" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +517, /* "certificate extensions" */ +883, /* "certificateRevocationList" */ +937, /* "chacha" */ +967, /* "chacha20-poly1305" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +633, /* "cleartext track 2" */ +894, /* "cmac" */ +13, /* "commonName" */ +513, /* "content types" */ +50, /* "contentType" */ +53, /* "countersignature" */ +14, /* "countryName" */ +153, /* "crlBag" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcObject" */ +891, /* "deltaRevocationList" */ +31, /* "des-cbc" */ +643, /* "des-cdmf" */ +30, /* "des-cfb" */ +656, /* "des-cfb1" */ +657, /* "des-cfb8" */ +29, /* "des-ecb" */ +32, /* "des-ede" */ +43, /* "des-ede-cbc" */ +60, /* "des-ede-cfb" */ +62, /* "des-ede-ofb" */ +33, /* "des-ede3" */ +44, /* "des-ede3-cbc" */ +61, /* "des-ede3-cfb" */ +658, /* "des-ede3-cfb1" */ +659, /* "des-ede3-cfb8" */ +63, /* "des-ede3-ofb" */ +45, /* "des-ofb" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +80, /* "desx-cbc" */ +991, /* "dh-cofactor-kdf" */ +990, /* "dh-std-kdf" */ +28, /* "dhKeyAgreement" */ +985, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ +986, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ +987, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ +988, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ +989, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ +980, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ +981, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ +982, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ +983, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ +984, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ +11, /* "directory services (X.500)" */ +378, /* "directory services - algorithms" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +380, /* "dod" */ +391, /* "domainComponent" */ +452, /* "domainRelatedObject" */ +116, /* "dsaEncryption" */ +67, /* "dsaEncryption-old" */ +66, /* "dsaWithSHA" */ +113, /* "dsaWithSHA1" */ +70, /* "dsaWithSHA1-old" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +1041, /* "dsa_with_SHA3-224" */ +1042, /* "dsa_with_SHA3-256" */ +1043, /* "dsa_with_SHA3-384" */ +1044, /* "dsa_with_SHA3-512" */ +1039, /* "dsa_with_SHA384" */ +1040, /* "dsa_with_SHA512" */ +297, /* "dvcs" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +1045, /* "ecdsa_with_SHA3-224" */ +1046, /* "ecdsa_with_SHA3-256" */ +1047, /* "ecdsa_with_SHA3-384" */ +1048, /* "ecdsa_with_SHA3-512" */ +48, /* "emailAddress" */ +632, /* "encrypted track 2" */ +885, /* "enhancedSearchGuide" */ +56, /* "extendedCertificateAttributes" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +631, /* "generate cryptogram" */ +509, /* "generationQualifier" */ +601, /* "generic cryptogram" */ +99, /* "givenName" */ +939, /* "gost89-cbc" */ +814, /* "gost89-cnt" */ +938, /* "gost89-ecb" */ +1022, /* "hkdf" */ +855, /* "hmac" */ +780, /* "hmac-md5" */ +781, /* "hmac-sha1" */ +1035, /* "hmac-sha3-224" */ +1036, /* "hmac-sha3-256" */ +1037, /* "hmac-sha3-384" */ +1038, /* "hmac-sha3-512" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +1027, /* "hmacWithSHA512-224" */ +1028, /* "hmacWithSHA512-256" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +381, /* "iana" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +788, /* "id-aes128-wrap" */ +897, /* "id-aes128-wrap-pad" */ +789, /* "id-aes192-wrap" */ +900, /* "id-aes192-wrap-pad" */ +790, /* "id-aes256-wrap" */ +903, /* "id-aes256-wrap-pad" */ +262, /* "id-alg" */ +893, /* "id-alg-PWRI-KEK" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +907, /* "id-camellia128-wrap" */ +908, /* "id-camellia192-wrap" */ +909, /* "id-camellia256-wrap" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +1005, /* "id-cp" */ +1017, /* "id-ct-ASPA" */ +787, /* "id-ct-asciiTextWithCRLF" */ +1013, /* "id-ct-geofeedCSVwithCRLF" */ +1004, /* "id-ct-resourceTaggedAttest" */ +1001, /* "id-ct-routeOriginAuthz" */ +1003, /* "id-ct-rpkiGhostbusters" */ +1002, /* "id-ct-rpkiManifest" */ +1014, /* "id-ct-signedChecklist" */ +1024, /* "id-ct-signedTAL" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +1023, /* "id-smime-aa-signingCertificateV2" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +945, /* "id-tc26-gost-28147-param-Z" */ +34, /* "idea-cbc" */ +35, /* "idea-cfb" */ +36, /* "idea-ecb" */ +46, /* "idea-ofb" */ +676, /* "identified-organization" */ +461, /* "info" */ +101, /* "initials" */ +869, /* "internationaliSDNNumber" */ +1008, /* "ipAddr-asNumber" */ +1009, /* "ipAddr-asNumberv2" */ +749, /* "ipsec3" */ +750, /* "ipsec4" */ +181, /* "iso" */ +623, /* "issuer capabilities" */ +645, /* "itu-t" */ +492, /* "janetMailbox" */ +646, /* "joint-iso-itu-t" */ +958, /* "jurisdictionCountryName" */ +956, /* "jurisdictionLocalityName" */ +957, /* "jurisdictionStateOrProvinceName" */ +150, /* "keyBag" */ +773, /* "kisa" */ +961, /* "kx-dhe" */ +960, /* "kx-ecdhe" */ +962, /* "kx-gost" */ +959, /* "kx-rsa" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +15, /* "localityName" */ +480, /* "mXRecord" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ + 3, /* "md2" */ + 7, /* "md2WithRSAEncryption" */ +257, /* "md4" */ +396, /* "md4WithRSAEncryption" */ + 4, /* "md5" */ +114, /* "md5-sha1" */ +104, /* "md5WithRSA" */ + 8, /* "md5WithRSAEncryption" */ +95, /* "mdc2" */ +96, /* "mdc2WithRSA" */ +875, /* "member" */ +602, /* "merchant initiated auth" */ +514, /* "message extensions" */ +51, /* "messageDigest" */ +911, /* "mgf1" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +481, /* "nSRecord" */ +173, /* "name" */ +681, /* "onBasis" */ +379, /* "org" */ +17, /* "organizationName" */ +491, /* "organizationalStatus" */ +18, /* "organizationalUnitName" */ +971, /* "oscca" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +992, /* "pSpecified" */ +489, /* "pagerTelephoneNumber" */ +782, /* "password based MAC" */ +374, /* "path" */ +621, /* "payment gateway capabilities" */ + 9, /* "pbeWithMD2AndDES-CBC" */ +168, /* "pbeWithMD2AndRC2-CBC" */ +112, /* "pbeWithMD5AndCast5CBC" */ +10, /* "pbeWithMD5AndDES-CBC" */ +169, /* "pbeWithMD5AndRC2-CBC" */ +148, /* "pbeWithSHA1And128BitRC2-CBC" */ +144, /* "pbeWithSHA1And128BitRC4" */ +147, /* "pbeWithSHA1And2-KeyTripleDES-CBC" */ +146, /* "pbeWithSHA1And3-KeyTripleDES-CBC" */ +149, /* "pbeWithSHA1And40BitRC2-CBC" */ +145, /* "pbeWithSHA1And40BitRC4" */ +170, /* "pbeWithSHA1AndDES-CBC" */ +68, /* "pbeWithSHA1AndRC2-CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +886, /* "protocolInformation" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +98, /* "rc2-40-cbc" */ +166, /* "rc2-64-cbc" */ +37, /* "rc2-cbc" */ +39, /* "rc2-cfb" */ +38, /* "rc2-ecb" */ +40, /* "rc2-ofb" */ + 5, /* "rc4" */ +97, /* "rc4-40" */ +915, /* "rc4-hmac-md5" */ +120, /* "rc5-cbc" */ +122, /* "rc5-cfb" */ +121, /* "rc5-ecb" */ +123, /* "rc5-ofb" */ +870, /* "registeredAddress" */ +460, /* "rfc822Mailbox" */ +117, /* "ripemd160" */ +119, /* "ripemd160WithRSA" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ +19, /* "rsa" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ +919, /* "rsaesOaep" */ +912, /* "rsassaPss" */ +124, /* "run length compression" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +1007, /* "sbgp-autonomousSysNumv2" */ +290, /* "sbgp-ipAddrBlock" */ +1006, /* "sbgp-ipAddrBlockv2" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +635, /* "secure device signature" */ +878, /* "seeAlso" */ +777, /* "seed-cbc" */ +779, /* "seed-cfb" */ +776, /* "seed-ecb" */ +778, /* "seed-ofb" */ +105, /* "serialNumber" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +41, /* "sha" */ +64, /* "sha1" */ +115, /* "sha1WithRSA" */ +65, /* "sha1WithRSAEncryption" */ +675, /* "sha224" */ +671, /* "sha224WithRSAEncryption" */ +672, /* "sha256" */ +668, /* "sha256WithRSAEncryption" */ +1031, /* "sha3-224" */ +1032, /* "sha3-256" */ +1033, /* "sha3-384" */ +1034, /* "sha3-512" */ +673, /* "sha384" */ +669, /* "sha384WithRSAEncryption" */ +674, /* "sha512" */ +1029, /* "sha512-224" */ +1025, /* "sha512-224WithRSAEncryption" */ +1030, /* "sha512-256" */ +1026, /* "sha512-256WithRSAEncryption" */ +670, /* "sha512WithRSAEncryption" */ +42, /* "shaWithRSAEncryption" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +972, /* "sm-scheme" */ +968, /* "sm3" */ +969, /* "sm3WithRSAEncryption" */ +974, /* "sm4-cbc" */ +976, /* "sm4-cfb" */ +977, /* "sm4-cfb1" */ +978, /* "sm4-cfb8" */ +979, /* "sm4-ctr" */ +973, /* "sm4-ecb" */ +975, /* "sm4-ofb" */ +16, /* "stateOrProvinceName" */ +660, /* "streetAddress" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +100, /* "surname" */ +940, /* "tc26" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +920, /* "teletrust" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +106, /* "title" */ +682, /* "tpBasis" */ +436, /* "ucl" */ + 0, /* "undefined" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +458, /* "userId" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +125, /* "zlib compression" */ +}; + +static const unsigned int obj_objs[NUM_OBJ]={ + 0, /* OBJ_undef 0 */ +181, /* OBJ_iso 1 */ +393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ +404, /* OBJ_ccitt OBJ_itu_t */ +645, /* OBJ_itu_t 0 */ +646, /* OBJ_joint_iso_itu_t 2 */ +434, /* OBJ_data 0 9 */ +182, /* OBJ_member_body 1 2 */ +379, /* OBJ_org 1 3 */ +676, /* OBJ_identified_organization 1 3 */ +11, /* OBJ_X500 2 5 */ +647, /* OBJ_international_organizations 2 23 */ +380, /* OBJ_dod 1 3 6 */ +920, /* OBJ_teletrust 1 3 36 */ +12, /* OBJ_X509 2 5 4 */ +378, /* OBJ_X500algorithms 2 5 8 */ +81, /* OBJ_id_ce 2 5 29 */ +512, /* OBJ_id_set 2 23 42 */ +678, /* OBJ_wap 2 23 43 */ +435, /* OBJ_pss 0 9 2342 */ +970, /* OBJ_ISO_CN 1 2 156 */ +183, /* OBJ_ISO_US 1 2 840 */ +381, /* OBJ_iana 1 3 6 1 */ +950, /* OBJ_X25519 1 3 101 110 */ +951, /* OBJ_X448 1 3 101 111 */ +952, /* OBJ_Ed25519 1 3 101 112 */ +953, /* OBJ_Ed448 1 3 101 113 */ +954, /* OBJ_Ed25519ph 1 3 101 114 */ +955, /* OBJ_Ed448ph 1 3 101 115 */ +677, /* OBJ_certicom_arc 1 3 132 */ +394, /* OBJ_selected_attribute_types 2 5 1 5 */ +13, /* OBJ_commonName 2 5 4 3 */ +100, /* OBJ_surname 2 5 4 4 */ +105, /* OBJ_serialNumber 2 5 4 5 */ +14, /* OBJ_countryName 2 5 4 6 */ +15, /* OBJ_localityName 2 5 4 7 */ +16, /* OBJ_stateOrProvinceName 2 5 4 8 */ +660, /* OBJ_streetAddress 2 5 4 9 */ +17, /* OBJ_organizationName 2 5 4 10 */ +18, /* OBJ_organizationalUnitName 2 5 4 11 */ +106, /* OBJ_title 2 5 4 12 */ +107, /* OBJ_description 2 5 4 13 */ +859, /* OBJ_searchGuide 2 5 4 14 */ +860, /* OBJ_businessCategory 2 5 4 15 */ +861, /* OBJ_postalAddress 2 5 4 16 */ +661, /* OBJ_postalCode 2 5 4 17 */ +862, /* OBJ_postOfficeBox 2 5 4 18 */ +863, /* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ +864, /* OBJ_telephoneNumber 2 5 4 20 */ +865, /* OBJ_telexNumber 2 5 4 21 */ +866, /* OBJ_teletexTerminalIdentifier 2 5 4 22 */ +867, /* OBJ_facsimileTelephoneNumber 2 5 4 23 */ +868, /* OBJ_x121Address 2 5 4 24 */ +869, /* OBJ_internationaliSDNNumber 2 5 4 25 */ +870, /* OBJ_registeredAddress 2 5 4 26 */ +871, /* OBJ_destinationIndicator 2 5 4 27 */ +872, /* OBJ_preferredDeliveryMethod 2 5 4 28 */ +873, /* OBJ_presentationAddress 2 5 4 29 */ +874, /* OBJ_supportedApplicationContext 2 5 4 30 */ +875, /* OBJ_member 2 5 4 31 */ +876, /* OBJ_owner 2 5 4 32 */ +877, /* OBJ_roleOccupant 2 5 4 33 */ +878, /* OBJ_seeAlso 2 5 4 34 */ +879, /* OBJ_userPassword 2 5 4 35 */ +880, /* OBJ_userCertificate 2 5 4 36 */ +881, /* OBJ_cACertificate 2 5 4 37 */ +882, /* OBJ_authorityRevocationList 2 5 4 38 */ +883, /* OBJ_certificateRevocationList 2 5 4 39 */ +884, /* OBJ_crossCertificatePair 2 5 4 40 */ +173, /* OBJ_name 2 5 4 41 */ +99, /* OBJ_givenName 2 5 4 42 */ +101, /* OBJ_initials 2 5 4 43 */ +509, /* OBJ_generationQualifier 2 5 4 44 */ +503, /* OBJ_x500UniqueIdentifier 2 5 4 45 */ +174, /* OBJ_dnQualifier 2 5 4 46 */ +885, /* OBJ_enhancedSearchGuide 2 5 4 47 */ +886, /* OBJ_protocolInformation 2 5 4 48 */ +887, /* OBJ_distinguishedName 2 5 4 49 */ +888, /* OBJ_uniqueMember 2 5 4 50 */ +889, /* OBJ_houseIdentifier 2 5 4 51 */ +890, /* OBJ_supportedAlgorithms 2 5 4 52 */ +891, /* OBJ_deltaRevocationList 2 5 4 53 */ +892, /* OBJ_dmdName 2 5 4 54 */ +510, /* OBJ_pseudonym 2 5 4 65 */ +400, /* OBJ_role 2 5 4 72 */ +769, /* OBJ_subject_directory_attributes 2 5 29 9 */ +82, /* OBJ_subject_key_identifier 2 5 29 14 */ +83, /* OBJ_key_usage 2 5 29 15 */ +84, /* OBJ_private_key_usage_period 2 5 29 16 */ +85, /* OBJ_subject_alt_name 2 5 29 17 */ +86, /* OBJ_issuer_alt_name 2 5 29 18 */ +87, /* OBJ_basic_constraints 2 5 29 19 */ +88, /* OBJ_crl_number 2 5 29 20 */ +141, /* OBJ_crl_reason 2 5 29 21 */ +430, /* OBJ_hold_instruction_code 2 5 29 23 */ +142, /* OBJ_invalidity_date 2 5 29 24 */ +140, /* OBJ_delta_crl 2 5 29 27 */ +770, /* OBJ_issuing_distribution_point 2 5 29 28 */ +771, /* OBJ_certificate_issuer 2 5 29 29 */ +666, /* OBJ_name_constraints 2 5 29 30 */ +103, /* OBJ_crl_distribution_points 2 5 29 31 */ +89, /* OBJ_certificate_policies 2 5 29 32 */ +747, /* OBJ_policy_mappings 2 5 29 33 */ +90, /* OBJ_authority_key_identifier 2 5 29 35 */ +401, /* OBJ_policy_constraints 2 5 29 36 */ +126, /* OBJ_ext_key_usage 2 5 29 37 */ +857, /* OBJ_freshest_crl 2 5 29 46 */ +748, /* OBJ_inhibit_any_policy 2 5 29 54 */ +402, /* OBJ_target_information 2 5 29 55 */ +403, /* OBJ_no_rev_avail 2 5 29 56 */ +513, /* OBJ_set_ctype 2 23 42 0 */ +514, /* OBJ_set_msgExt 2 23 42 1 */ +515, /* OBJ_set_attr 2 23 42 3 */ +516, /* OBJ_set_policy 2 23 42 5 */ +517, /* OBJ_set_certExt 2 23 42 7 */ +518, /* OBJ_set_brand 2 23 42 8 */ +679, /* OBJ_wap_wsg 2 23 43 1 */ +382, /* OBJ_Directory 1 3 6 1 1 */ +383, /* OBJ_Management 1 3 6 1 2 */ +384, /* OBJ_Experimental 1 3 6 1 3 */ +385, /* OBJ_Private 1 3 6 1 4 */ +386, /* OBJ_Security 1 3 6 1 5 */ +387, /* OBJ_SNMPv2 1 3 6 1 6 */ +388, /* OBJ_Mail 1 3 6 1 7 */ +376, /* OBJ_algorithm 1 3 14 3 2 */ +395, /* OBJ_clearance 2 5 1 5 55 */ +19, /* OBJ_rsa 2 5 8 1 1 */ +96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */ +95, /* OBJ_mdc2 2 5 8 3 101 */ +746, /* OBJ_any_policy 2 5 29 32 0 */ +910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 0 */ +519, /* OBJ_setct_PANData 2 23 42 0 0 */ +520, /* OBJ_setct_PANToken 2 23 42 0 1 */ +521, /* OBJ_setct_PANOnly 2 23 42 0 2 */ +522, /* OBJ_setct_OIData 2 23 42 0 3 */ +523, /* OBJ_setct_PI 2 23 42 0 4 */ +524, /* OBJ_setct_PIData 2 23 42 0 5 */ +525, /* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ +526, /* OBJ_setct_HODInput 2 23 42 0 7 */ +527, /* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ +528, /* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ +529, /* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ +530, /* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ +531, /* OBJ_setct_PInitResData 2 23 42 0 12 */ +532, /* OBJ_setct_PI_TBS 2 23 42 0 13 */ +533, /* OBJ_setct_PResData 2 23 42 0 14 */ +534, /* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ +535, /* OBJ_setct_AuthResTBS 2 23 42 0 17 */ +536, /* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ +537, /* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ +538, /* OBJ_setct_CapTokenData 2 23 42 0 20 */ +539, /* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ +540, /* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ +541, /* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ +542, /* OBJ_setct_AuthRevResData 2 23 42 0 24 */ +543, /* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ +544, /* OBJ_setct_CapReqTBS 2 23 42 0 26 */ +545, /* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ +546, /* OBJ_setct_CapResData 2 23 42 0 28 */ +547, /* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ +548, /* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ +549, /* OBJ_setct_CapRevResData 2 23 42 0 31 */ +550, /* OBJ_setct_CredReqTBS 2 23 42 0 32 */ +551, /* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ +552, /* OBJ_setct_CredResData 2 23 42 0 34 */ +553, /* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ +554, /* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ +555, /* OBJ_setct_CredRevResData 2 23 42 0 37 */ +556, /* OBJ_setct_PCertReqData 2 23 42 0 38 */ +557, /* OBJ_setct_PCertResTBS 2 23 42 0 39 */ +558, /* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ +559, /* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ +560, /* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ +561, /* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ +562, /* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ +563, /* OBJ_setct_CertReqData 2 23 42 0 45 */ +564, /* OBJ_setct_CertReqTBS 2 23 42 0 46 */ +565, /* OBJ_setct_CertResData 2 23 42 0 47 */ +566, /* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ +567, /* OBJ_setct_ErrorTBS 2 23 42 0 49 */ +568, /* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ +569, /* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ +570, /* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ +571, /* OBJ_setct_AuthResTBE 2 23 42 0 53 */ +572, /* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ +573, /* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ +574, /* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ +575, /* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ +576, /* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ +577, /* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ +578, /* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ +579, /* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ +580, /* OBJ_setct_CapReqTBE 2 23 42 0 62 */ +581, /* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ +582, /* OBJ_setct_CapResTBE 2 23 42 0 64 */ +583, /* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ +584, /* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ +585, /* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ +586, /* OBJ_setct_CredReqTBE 2 23 42 0 68 */ +587, /* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ +588, /* OBJ_setct_CredResTBE 2 23 42 0 70 */ +589, /* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ +590, /* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ +591, /* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ +592, /* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ +593, /* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ +594, /* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ +595, /* OBJ_setct_CertReqTBE 2 23 42 0 77 */ +596, /* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ +597, /* OBJ_setct_CertResTBE 2 23 42 0 79 */ +598, /* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ +599, /* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ +600, /* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ +601, /* OBJ_setext_genCrypt 2 23 42 1 1 */ +602, /* OBJ_setext_miAuth 2 23 42 1 3 */ +603, /* OBJ_setext_pinSecure 2 23 42 1 4 */ +604, /* OBJ_setext_pinAny 2 23 42 1 5 */ +605, /* OBJ_setext_track2 2 23 42 1 7 */ +606, /* OBJ_setext_cv 2 23 42 1 8 */ +620, /* OBJ_setAttr_Cert 2 23 42 3 0 */ +621, /* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ +622, /* OBJ_setAttr_TokenType 2 23 42 3 2 */ +623, /* OBJ_setAttr_IssCap 2 23 42 3 3 */ +607, /* OBJ_set_policy_root 2 23 42 5 0 */ +608, /* OBJ_setCext_hashedRoot 2 23 42 7 0 */ +609, /* OBJ_setCext_certType 2 23 42 7 1 */ +610, /* OBJ_setCext_merchData 2 23 42 7 2 */ +611, /* OBJ_setCext_cCertRequired 2 23 42 7 3 */ +612, /* OBJ_setCext_tunneling 2 23 42 7 4 */ +613, /* OBJ_setCext_setExt 2 23 42 7 5 */ +614, /* OBJ_setCext_setQualf 2 23 42 7 6 */ +615, /* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ +616, /* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ +617, /* OBJ_setCext_Track2Data 2 23 42 7 9 */ +618, /* OBJ_setCext_TokenType 2 23 42 7 10 */ +619, /* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ +636, /* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ +640, /* OBJ_set_brand_Visa 2 23 42 8 4 */ +641, /* OBJ_set_brand_MasterCard 2 23 42 8 5 */ +637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ +638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ +639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ +971, /* OBJ_oscca 1 2 156 10197 */ +805, /* OBJ_cryptopro 1 2 643 2 2 */ +806, /* OBJ_cryptocom 1 2 643 2 9 */ +940, /* OBJ_tc26 1 2 643 7 1 */ +184, /* OBJ_X9_57 1 2 840 10040 */ +405, /* OBJ_ansi_X9_62 1 2 840 10045 */ +389, /* OBJ_Enterprises 1 3 6 1 4 1 */ +504, /* OBJ_mime_mhs 1 3 6 1 7 1 */ +104, /* OBJ_md5WithRSA 1 3 14 3 2 3 */ +29, /* OBJ_des_ecb 1 3 14 3 2 6 */ +31, /* OBJ_des_cbc 1 3 14 3 2 7 */ +45, /* OBJ_des_ofb64 1 3 14 3 2 8 */ +30, /* OBJ_des_cfb64 1 3 14 3 2 9 */ +377, /* OBJ_rsaSignature 1 3 14 3 2 11 */ +67, /* OBJ_dsa_2 1 3 14 3 2 12 */ +66, /* OBJ_dsaWithSHA 1 3 14 3 2 13 */ +42, /* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ +32, /* OBJ_des_ede_ecb 1 3 14 3 2 17 */ +41, /* OBJ_sha 1 3 14 3 2 18 */ +64, /* OBJ_sha1 1 3 14 3 2 26 */ +70, /* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ +115, /* OBJ_sha1WithRSA 1 3 14 3 2 29 */ +117, /* OBJ_ripemd160 1 3 36 3 2 1 */ +143, /* OBJ_sxnet 1 3 101 1 4 1 */ +721, /* OBJ_sect163k1 1 3 132 0 1 */ +722, /* OBJ_sect163r1 1 3 132 0 2 */ +728, /* OBJ_sect239k1 1 3 132 0 3 */ +717, /* OBJ_sect113r1 1 3 132 0 4 */ +718, /* OBJ_sect113r2 1 3 132 0 5 */ +704, /* OBJ_secp112r1 1 3 132 0 6 */ +705, /* OBJ_secp112r2 1 3 132 0 7 */ +709, /* OBJ_secp160r1 1 3 132 0 8 */ +708, /* OBJ_secp160k1 1 3 132 0 9 */ +714, /* OBJ_secp256k1 1 3 132 0 10 */ +723, /* OBJ_sect163r2 1 3 132 0 15 */ +729, /* OBJ_sect283k1 1 3 132 0 16 */ +730, /* OBJ_sect283r1 1 3 132 0 17 */ +719, /* OBJ_sect131r1 1 3 132 0 22 */ +720, /* OBJ_sect131r2 1 3 132 0 23 */ +724, /* OBJ_sect193r1 1 3 132 0 24 */ +725, /* OBJ_sect193r2 1 3 132 0 25 */ +726, /* OBJ_sect233k1 1 3 132 0 26 */ +727, /* OBJ_sect233r1 1 3 132 0 27 */ +706, /* OBJ_secp128r1 1 3 132 0 28 */ +707, /* OBJ_secp128r2 1 3 132 0 29 */ +710, /* OBJ_secp160r2 1 3 132 0 30 */ +711, /* OBJ_secp192k1 1 3 132 0 31 */ +712, /* OBJ_secp224k1 1 3 132 0 32 */ +713, /* OBJ_secp224r1 1 3 132 0 33 */ +715, /* OBJ_secp384r1 1 3 132 0 34 */ +716, /* OBJ_secp521r1 1 3 132 0 35 */ +731, /* OBJ_sect409k1 1 3 132 0 36 */ +732, /* OBJ_sect409r1 1 3 132 0 37 */ +733, /* OBJ_sect571k1 1 3 132 0 38 */ +734, /* OBJ_sect571r1 1 3 132 0 39 */ +624, /* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ +625, /* OBJ_set_addPolicy 2 23 42 3 0 1 */ +626, /* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ +627, /* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ +628, /* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ +629, /* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ +630, /* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ +642, /* OBJ_set_brand_Novus 2 23 42 8 6011 */ +735, /* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ +736, /* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ +737, /* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ +738, /* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ +739, /* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ +740, /* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ +741, /* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ +742, /* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ +743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ +744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ +745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ +804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ +124, /* OBJ_rle_compression 1 1 1 1 666 1 */ +972, /* OBJ_sm_scheme 1 2 156 10197 1 */ +773, /* OBJ_kisa 1 2 410 200004 */ +807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ +808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ +809, /* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ +810, /* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ +811, /* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ +812, /* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ +813, /* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ +815, /* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ +816, /* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ +817, /* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ +818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ + 1, /* OBJ_rsadsi 1 2 840 113549 */ +185, /* OBJ_X9cm 1 2 840 10040 4 */ +127, /* OBJ_id_pkix 1 3 6 1 5 5 7 */ +505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ +506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ +119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ +981, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */ +982, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */ +983, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */ +984, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */ +986, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */ +987, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */ +988, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */ +989, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */ +631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ +632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ +633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ +634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ +635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ +436, /* OBJ_ucl 0 9 2342 19200300 */ +820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ +819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ +845, /* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ +846, /* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ +847, /* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ +848, /* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ +821, /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ +822, /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ +823, /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ +824, /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ +825, /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ +826, /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ +827, /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ +828, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ +829, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ +830, /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ +831, /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ +832, /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ +833, /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ +834, /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ +835, /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ +836, /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ +837, /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ +838, /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ +839, /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ +840, /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ +841, /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ +842, /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ +843, /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ +844, /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ + 2, /* OBJ_pkcs 1 2 840 113549 1 */ +431, /* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ +432, /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ +433, /* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ +116, /* OBJ_dsa 1 2 840 10040 4 1 */ +113, /* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ +406, /* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ +407, /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ +408, /* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ +416, /* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ +791, /* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ +792, /* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ +258, /* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ +175, /* OBJ_id_pe 1 3 6 1 5 5 7 1 */ +259, /* OBJ_id_qt 1 3 6 1 5 5 7 2 */ +128, /* OBJ_id_kp 1 3 6 1 5 5 7 3 */ +260, /* OBJ_id_it 1 3 6 1 5 5 7 4 */ +261, /* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ +262, /* OBJ_id_alg 1 3 6 1 5 5 7 6 */ +263, /* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ +264, /* OBJ_id_on 1 3 6 1 5 5 7 8 */ +265, /* OBJ_id_pda 1 3 6 1 5 5 7 9 */ +266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ +267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ +268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ +1005, /* OBJ_id_cp 1 3 6 1 5 5 7 14 */ +662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ +176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ +507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ +508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ +921, /* OBJ_brainpool 1 3 36 3 3 2 8 1 */ +57, /* OBJ_netscape 2 16 840 1 113730 */ +754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ +766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ +757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ +755, /* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ +767, /* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ +758, /* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ +756, /* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ +768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ +759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ +437, /* OBJ_pilot 0 9 2342 19200300 100 */ +973, /* OBJ_sm4_ecb 1 2 156 10197 1 104 1 */ +974, /* OBJ_sm4_cbc 1 2 156 10197 1 104 2 */ +975, /* OBJ_sm4_ofb128 1 2 156 10197 1 104 3 */ +976, /* OBJ_sm4_cfb128 1 2 156 10197 1 104 4 */ +977, /* OBJ_sm4_cfb1 1 2 156 10197 1 104 5 */ +978, /* OBJ_sm4_cfb8 1 2 156 10197 1 104 6 */ +979, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ +968, /* OBJ_sm3 1 2 156 10197 1 401 */ +969, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */ +776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ +777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ +779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ +778, /* OBJ_seed_ofb128 1 2 410 200004 1 6 */ +852, /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ +853, /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ +850, /* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ +851, /* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ +849, /* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ +854, /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ +946, /* OBJ_id_tc26_gost3410_2012_256 1 2 643 7 1 1 1 1 */ +947, /* OBJ_id_tc26_gost3410_2012_512 1 2 643 7 1 1 1 2 */ +941, /* OBJ_id_tc26_gost3411_2012_256 1 2 643 7 1 1 2 2 */ +942, /* OBJ_id_tc26_gost3411_2012_512 1 2 643 7 1 1 2 3 */ +948, /* OBJ_id_tc26_signwithdigest_gost3410_2012_256 1 2 643 7 1 1 3 2 */ +949, /* OBJ_id_tc26_signwithdigest_gost3410_2012_512 1 2 643 7 1 1 3 3 */ +999, /* OBJ_id_tc26_hmac_gost_3411_12_256 1 2 643 7 1 1 4 1 */ +1000, /* OBJ_id_tc26_hmac_gost_3411_12_512 1 2 643 7 1 1 4 2 */ +186, /* OBJ_pkcs1 1 2 840 113549 1 1 */ +27, /* OBJ_pkcs3 1 2 840 113549 1 3 */ +187, /* OBJ_pkcs5 1 2 840 113549 1 5 */ +20, /* OBJ_pkcs7 1 2 840 113549 1 7 */ +47, /* OBJ_pkcs9 1 2 840 113549 1 9 */ + 3, /* OBJ_md2 1 2 840 113549 2 2 */ +257, /* OBJ_md4 1 2 840 113549 2 4 */ + 4, /* OBJ_md5 1 2 840 113549 2 5 */ +797, /* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ +163, /* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ +798, /* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ +799, /* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ +800, /* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ +801, /* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ +1027, /* OBJ_hmacWithSHA512_224 1 2 840 113549 2 12 */ +1028, /* OBJ_hmacWithSHA512_256 1 2 840 113549 2 13 */ +37, /* OBJ_rc2_cbc 1 2 840 113549 3 2 */ + 5, /* OBJ_rc4 1 2 840 113549 3 4 */ +44, /* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ +120, /* OBJ_rc5_cbc 1 2 840 113549 3 8 */ +643, /* OBJ_des_cdmf 1 2 840 113549 3 10 */ +680, /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ +684, /* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ +685, /* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ +686, /* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ +687, /* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ +688, /* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ +689, /* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ +690, /* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ +691, /* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ +692, /* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ +693, /* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ +694, /* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ +695, /* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ +696, /* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ +697, /* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ +698, /* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ +699, /* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ +700, /* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ +701, /* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ +702, /* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ +703, /* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ +409, /* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ +410, /* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ +411, /* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ +412, /* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ +413, /* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ +414, /* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ +415, /* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ +793, /* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ +794, /* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ +795, /* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ +796, /* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ +269, /* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ +270, /* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ +271, /* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ +272, /* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ +273, /* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ +274, /* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ +275, /* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ +276, /* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ +277, /* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ +278, /* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ +279, /* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ +280, /* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ +281, /* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ +282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ +283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ +284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ +177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ +285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ +286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ +287, /* OBJ_ac_auditEntity 1 3 6 1 5 5 7 1 4 */ +288, /* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ +289, /* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ +290, /* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ +291, /* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ +292, /* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ +397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ +398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ +663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ +1016, /* OBJ_tlsfeature 1 3 6 1 5 5 7 1 24 */ +1006, /* OBJ_sbgp_ipAddrBlockv2 1 3 6 1 5 5 7 1 28 */ +1007, /* OBJ_sbgp_autonomousSysNumv2 1 3 6 1 5 5 7 1 29 */ +164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ +165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ +293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ +129, /* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ +130, /* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ +131, /* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ +132, /* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ +294, /* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ +295, /* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ +296, /* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ +133, /* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ +180, /* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ +297, /* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ +1015, /* OBJ_id_kp_bgpsec_router 1 3 6 1 5 5 7 3 30 */ +298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ +299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ +300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ +301, /* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ +302, /* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ +303, /* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ +304, /* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ +305, /* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ +306, /* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ +307, /* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ +308, /* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ +309, /* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ +310, /* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ +311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ +312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ +784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ +313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ +314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ +323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ +324, /* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ +325, /* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ +326, /* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ +327, /* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ +328, /* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ +329, /* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ +330, /* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ +331, /* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ +332, /* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ +333, /* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ +334, /* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ +335, /* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ +336, /* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ +337, /* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ +338, /* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ +339, /* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ +340, /* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ +341, /* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ +342, /* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ +343, /* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ +344, /* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ +345, /* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ +346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ +347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ +858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ +348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ +349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ +351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ +352, /* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ +353, /* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ +354, /* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ +355, /* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ +356, /* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ +357, /* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ +358, /* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ +399, /* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ +359, /* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ +360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ +361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ +362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ +1008, /* OBJ_ipAddr_asNumber 1 3 6 1 5 5 7 14 2 */ +1009, /* OBJ_ipAddr_asNumberv2 1 3 6 1 5 5 7 14 3 */ +664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ +665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ +667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ +178, /* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ +179, /* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ +363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ +364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ +785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ +1010, /* OBJ_rpkiManifest 1 3 6 1 5 5 7 48 10 */ +1011, /* OBJ_signedObject 1 3 6 1 5 5 7 48 11 */ +1012, /* OBJ_rpkiNotify 1 3 6 1 5 5 7 48 13 */ +780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ +781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ +58, /* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ +59, /* OBJ_netscape_data_type 2 16 840 1 113730 2 */ +438, /* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ +439, /* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ +440, /* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ +441, /* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ +993, /* OBJ_id_tc26_gost_3410_12_256_paramSetA 1 2 643 7 1 2 1 1 1 */ +994, /* OBJ_id_tc26_gost_3410_12_256_paramSetB 1 2 643 7 1 2 1 1 2 */ +995, /* OBJ_id_tc26_gost_3410_12_256_paramSetC 1 2 643 7 1 2 1 1 3 */ +996, /* OBJ_id_tc26_gost_3410_12_256_paramSetD 1 2 643 7 1 2 1 1 4 */ +997, /* OBJ_id_tc26_gost_3410_12_512_paramSetTest 1 2 643 7 1 2 1 2 0 */ +943, /* OBJ_id_tc26_gost_3410_12_512_paramSetA 1 2 643 7 1 2 1 2 1 */ +944, /* OBJ_id_tc26_gost_3410_12_512_paramSetB 1 2 643 7 1 2 1 2 2 */ +998, /* OBJ_id_tc26_gost_3410_12_512_paramSetC 1 2 643 7 1 2 1 2 3 */ +945, /* OBJ_id_tc26_gost_28147_param_Z 1 2 643 7 1 2 5 1 1 */ +108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ +112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ +782, /* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ +783, /* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ + 6, /* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ + 7, /* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ +396, /* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ + 8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ +65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ +644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ +919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */ +911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */ +992, /* OBJ_pSpecified 1 2 840 113549 1 1 9 */ +912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */ +668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ +669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ +670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ +671, /* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ +1025, /* OBJ_sha512_224WithRSAEncryption 1 2 840 113549 1 1 15 */ +1026, /* OBJ_sha512_256WithRSAEncryption 1 2 840 113549 1 1 16 */ +28, /* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ + 9, /* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ +10, /* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ +168, /* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ +169, /* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ +170, /* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ +68, /* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ +69, /* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ +161, /* OBJ_pbes2 1 2 840 113549 1 5 13 */ +162, /* OBJ_pbmac1 1 2 840 113549 1 5 14 */ +21, /* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ +22, /* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ +23, /* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ +24, /* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ +25, /* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ +26, /* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ +48, /* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ +49, /* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ +50, /* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ +51, /* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ +52, /* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ +53, /* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ +54, /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ +55, /* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ +56, /* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ +172, /* OBJ_ext_req 1 2 840 113549 1 9 14 */ +167, /* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ +188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ +156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ +157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ +681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ +682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ +683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ +417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ +856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ +390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ +91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ +315, /* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ +316, /* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ +317, /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ +318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ +319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ +320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ +321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ +322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ +365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ +366, /* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ +367, /* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ +368, /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ +369, /* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ +370, /* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ +371, /* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ +372, /* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ +373, /* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ +374, /* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ +375, /* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ +922, /* OBJ_brainpoolP160r1 1 3 36 3 3 2 8 1 1 1 */ +923, /* OBJ_brainpoolP160t1 1 3 36 3 3 2 8 1 1 2 */ +924, /* OBJ_brainpoolP192r1 1 3 36 3 3 2 8 1 1 3 */ +925, /* OBJ_brainpoolP192t1 1 3 36 3 3 2 8 1 1 4 */ +926, /* OBJ_brainpoolP224r1 1 3 36 3 3 2 8 1 1 5 */ +927, /* OBJ_brainpoolP224t1 1 3 36 3 3 2 8 1 1 6 */ +928, /* OBJ_brainpoolP256r1 1 3 36 3 3 2 8 1 1 7 */ +929, /* OBJ_brainpoolP256t1 1 3 36 3 3 2 8 1 1 8 */ +930, /* OBJ_brainpoolP320r1 1 3 36 3 3 2 8 1 1 9 */ +931, /* OBJ_brainpoolP320t1 1 3 36 3 3 2 8 1 1 10 */ +932, /* OBJ_brainpoolP384r1 1 3 36 3 3 2 8 1 1 11 */ +933, /* OBJ_brainpoolP384t1 1 3 36 3 3 2 8 1 1 12 */ +934, /* OBJ_brainpoolP512r1 1 3 36 3 3 2 8 1 1 13 */ +935, /* OBJ_brainpoolP512t1 1 3 36 3 3 2 8 1 1 14 */ +980, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */ +985, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */ +418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ +419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ +420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ +421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ +788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ +895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */ +896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */ +897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */ +422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ +423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ +424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ +425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ +789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ +898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */ +899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */ +900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */ +426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ +427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ +428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ +429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ +790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ +901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */ +902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */ +903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */ +672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ +673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ +674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ +675, /* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ +1029, /* OBJ_sha512_224 2 16 840 1 101 3 4 2 5 */ +1030, /* OBJ_sha512_256 2 16 840 1 101 3 4 2 6 */ +1031, /* OBJ_sha3_224 2 16 840 1 101 3 4 2 7 */ +1032, /* OBJ_sha3_256 2 16 840 1 101 3 4 2 8 */ +1033, /* OBJ_sha3_384 2 16 840 1 101 3 4 2 9 */ +1034, /* OBJ_sha3_512 2 16 840 1 101 3 4 2 10 */ +1035, /* OBJ_hmac_sha3_224 2 16 840 1 101 3 4 2 13 */ +1036, /* OBJ_hmac_sha3_256 2 16 840 1 101 3 4 2 14 */ +1037, /* OBJ_hmac_sha3_384 2 16 840 1 101 3 4 2 15 */ +1038, /* OBJ_hmac_sha3_512 2 16 840 1 101 3 4 2 16 */ +802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ +803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ +1039, /* OBJ_dsa_with_SHA384 2 16 840 1 101 3 4 3 3 */ +1040, /* OBJ_dsa_with_SHA512 2 16 840 1 101 3 4 3 4 */ +1041, /* OBJ_dsa_with_SHA3_224 2 16 840 1 101 3 4 3 5 */ +1042, /* OBJ_dsa_with_SHA3_256 2 16 840 1 101 3 4 3 6 */ +1043, /* OBJ_dsa_with_SHA3_384 2 16 840 1 101 3 4 3 7 */ +1044, /* OBJ_dsa_with_SHA3_512 2 16 840 1 101 3 4 3 8 */ +1045, /* OBJ_ecdsa_with_SHA3_224 2 16 840 1 101 3 4 3 9 */ +1046, /* OBJ_ecdsa_with_SHA3_256 2 16 840 1 101 3 4 3 10 */ +1047, /* OBJ_ecdsa_with_SHA3_384 2 16 840 1 101 3 4 3 11 */ +1048, /* OBJ_ecdsa_with_SHA3_512 2 16 840 1 101 3 4 3 12 */ +1049, /* OBJ_RSA_SHA3_224 2 16 840 1 101 3 4 3 13 */ +1050, /* OBJ_RSA_SHA3_256 2 16 840 1 101 3 4 3 14 */ +1051, /* OBJ_RSA_SHA3_384 2 16 840 1 101 3 4 3 15 */ +1052, /* OBJ_RSA_SHA3_512 2 16 840 1 101 3 4 3 16 */ +71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ +72, /* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ +73, /* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ +74, /* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ +75, /* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ +76, /* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ +77, /* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ +78, /* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ +79, /* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ +139, /* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ +458, /* OBJ_userId 0 9 2342 19200300 100 1 1 */ +459, /* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ +460, /* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ +461, /* OBJ_info 0 9 2342 19200300 100 1 4 */ +462, /* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ +463, /* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ +464, /* OBJ_photo 0 9 2342 19200300 100 1 7 */ +465, /* OBJ_userClass 0 9 2342 19200300 100 1 8 */ +466, /* OBJ_host 0 9 2342 19200300 100 1 9 */ +467, /* OBJ_manager 0 9 2342 19200300 100 1 10 */ +468, /* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ +469, /* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ +470, /* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ +471, /* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ +472, /* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ +473, /* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ +474, /* OBJ_secretary 0 9 2342 19200300 100 1 21 */ +475, /* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ +476, /* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ +477, /* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ +391, /* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ +478, /* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ +479, /* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ +480, /* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ +481, /* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ +482, /* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ +483, /* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ +484, /* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ +485, /* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ +486, /* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ +487, /* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ +488, /* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ +489, /* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ +490, /* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ +491, /* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ +492, /* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ +493, /* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ +494, /* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ +495, /* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ +496, /* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ +497, /* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ +498, /* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ +499, /* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ +500, /* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ +501, /* OBJ_audio 0 9 2342 19200300 100 1 55 */ +502, /* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ +442, /* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ +443, /* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ +444, /* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ +445, /* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ +446, /* OBJ_account 0 9 2342 19200300 100 4 5 */ +447, /* OBJ_document 0 9 2342 19200300 100 4 6 */ +448, /* OBJ_room 0 9 2342 19200300 100 4 7 */ +449, /* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ +392, /* OBJ_Domain 0 9 2342 19200300 100 4 13 */ +450, /* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ +451, /* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ +452, /* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ +453, /* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ +454, /* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ +455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ +456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ +457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ +936, /* OBJ_FRP256v1 1 2 250 1 223 101 256 1 */ +189, /* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ +190, /* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ +191, /* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ +192, /* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ +193, /* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ +194, /* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ +195, /* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ +158, /* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ +159, /* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ +160, /* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ +144, /* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ +145, /* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ +146, /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ +147, /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ +148, /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ +149, /* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ +171, /* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ +134, /* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ +135, /* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ +136, /* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ +137, /* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ +138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ +648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ +649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ +1018, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */ +1019, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */ +1020, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */ +1021, /* OBJ_ct_cert_scts 1 3 6 1 4 1 11129 2 4 5 */ +751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ +752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ +753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ +907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */ +908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */ +909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 4 */ +196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ +197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ +198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ +199, /* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ +200, /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ +201, /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ +202, /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ +203, /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ +204, /* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ +205, /* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ +206, /* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ +207, /* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ +208, /* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ +209, /* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ +210, /* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ +211, /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ +786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ +1001, /* OBJ_id_ct_routeOriginAuthz 1 2 840 113549 1 9 16 1 24 */ +1002, /* OBJ_id_ct_rpkiManifest 1 2 840 113549 1 9 16 1 26 */ +787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ +1003, /* OBJ_id_ct_rpkiGhostbusters 1 2 840 113549 1 9 16 1 35 */ +1004, /* OBJ_id_ct_resourceTaggedAttest 1 2 840 113549 1 9 16 1 36 */ +1013, /* OBJ_id_ct_geofeedCSVwithCRLF 1 2 840 113549 1 9 16 1 47 */ +1014, /* OBJ_id_ct_signedChecklist 1 2 840 113549 1 9 16 1 48 */ +1017, /* OBJ_id_ct_ASPA 1 2 840 113549 1 9 16 1 49 */ +1024, /* OBJ_id_ct_signedTAL 1 2 840 113549 1 9 16 1 50 */ +212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ +213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ +214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ +215, /* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ +216, /* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ +217, /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ +218, /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ +219, /* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ +220, /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ +221, /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ +222, /* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ +223, /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ +224, /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ +225, /* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ +226, /* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ +227, /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ +228, /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ +229, /* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ +230, /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ +231, /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ +232, /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ +233, /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ +234, /* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ +235, /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ +236, /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ +237, /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ +238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ +239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ +240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ +1023, /* OBJ_id_smime_aa_signingCertificateV2 1 2 840 113549 1 9 16 2 47 */ +241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ +242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ +243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ +244, /* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ +245, /* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ +246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ +247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ +125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ +893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */ +248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ +249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ +250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ +251, /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ +252, /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ +253, /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ +254, /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ +255, /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ +256, /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ +150, /* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ +151, /* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ +152, /* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ +153, /* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ +154, /* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ +155, /* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ +34, /* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ +956, /* OBJ_jurisdictionLocalityName 1 3 6 1 4 1 311 60 2 1 1 */ +957, /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */ +958, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */ +}; + diff --git a/Libraries/libressl/crypto/objects/obj_err.c b/Libraries/libressl/crypto/objects/obj_err.c new file mode 100644 index 000000000..04cb4218c --- /dev/null +++ b/Libraries/libressl/crypto/objects/obj_err.c @@ -0,0 +1,91 @@ +/* $OpenBSD: obj_err.c,v 1.14 2023/07/08 12:27:51 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason) + +static ERR_STRING_DATA OBJ_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA OBJ_str_reasons[] = { + {ERR_REASON(OBJ_R_MALLOC_FAILURE) , "malloc failure"}, + {ERR_REASON(OBJ_R_UNKNOWN_NID) , "unknown nid"}, + {0, NULL} +}; + +#endif + +void +ERR_load_OBJ_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) { + ERR_load_strings(0, OBJ_str_functs); + ERR_load_strings(0, OBJ_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_OBJ_strings); diff --git a/Libraries/libressl/crypto/objects/obj_lib.c b/Libraries/libressl/crypto/objects/obj_lib.c new file mode 100644 index 000000000..45062dbd4 --- /dev/null +++ b/Libraries/libressl/crypto/objects/obj_lib.c @@ -0,0 +1,135 @@ +/* $OpenBSD: obj_lib.c,v 1.19 2023/08/17 09:13:01 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include + +#include "asn1_local.h" + +ASN1_OBJECT * +OBJ_dup(const ASN1_OBJECT *o) +{ + ASN1_OBJECT *r; + char *ln = NULL, *sn = NULL; + unsigned char *data = NULL; + + if (o == NULL) + return (NULL); + if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) + return((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of + duplication is this??? */ + + r = ASN1_OBJECT_new(); + if (r == NULL) { + OBJerror(ERR_R_ASN1_LIB); + return (NULL); + } + data = malloc(o->length); + if (data == NULL) + goto err; + if (o->data != NULL) + memcpy(data, o->data, o->length); + /* once data attached to object it remains const */ + r->data = data; + r->length = o->length; + r->nid = o->nid; + r->ln = r->sn = NULL; + if (o->ln != NULL) { + ln = strdup(o->ln); + if (ln == NULL) + goto err; + r->ln = ln; + } + + if (o->sn != NULL) { + sn = strdup(o->sn); + if (sn == NULL) + goto err; + r->sn = sn; + } + r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA); + return (r); + + err: + OBJerror(ERR_R_MALLOC_FAILURE); + free(ln); + free(sn); + free(data); + free(r); + return (NULL); +} +LCRYPTO_ALIAS(OBJ_dup); + +int +OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) +{ + int cmp; + + if ((cmp = a->length - b->length) != 0) + return cmp; + if (a->length == 0) + return 0; + return memcmp(a->data, b->data, a->length); +} +LCRYPTO_ALIAS(OBJ_cmp); diff --git a/Libraries/libressl/crypto/objects/obj_xref.c b/Libraries/libressl/crypto/objects/obj_xref.c new file mode 100644 index 000000000..0fca228ed --- /dev/null +++ b/Libraries/libressl/crypto/objects/obj_xref.c @@ -0,0 +1,312 @@ +/* $OpenBSD: obj_xref.c,v 1.13 2023/07/28 10:25:05 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +/* + * Map between signature nids and pairs of (hash, pkey) nids. If the hash nid + * is NID_undef, this indicates to ASN1_item_{sign,verify}() that the pkey's + * ASN.1 method needs to handle algorithm identifiers and part of the message + * digest. + */ + +static const struct { + int sign_nid; + int hash_nid; + int pkey_nid; +} nid_triple[] = { + { + .sign_nid = NID_md2WithRSAEncryption, + .hash_nid = NID_md2, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_md5WithRSAEncryption, + .hash_nid = NID_md5, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_shaWithRSAEncryption, + .hash_nid = NID_sha, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_sha1WithRSAEncryption, + .hash_nid = NID_sha1, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_dsaWithSHA, + .hash_nid = NID_sha, + .pkey_nid = NID_dsa, + }, + { + .sign_nid = NID_dsaWithSHA1_2, + .hash_nid = NID_sha1, + .pkey_nid = NID_dsa_2, + }, + { + .sign_nid = NID_mdc2WithRSA, + .hash_nid = NID_mdc2, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_md5WithRSA, + .hash_nid = NID_md5, + .pkey_nid = NID_rsa, + }, + { + .sign_nid = NID_dsaWithSHA1, + .hash_nid = NID_sha1, + .pkey_nid = NID_dsa, + }, + { + .sign_nid = NID_sha1WithRSA, + .hash_nid = NID_sha1, + .pkey_nid = NID_rsa, + }, + { + .sign_nid = NID_ripemd160WithRSA, + .hash_nid = NID_ripemd160, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_md4WithRSAEncryption, + .hash_nid = NID_md4, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_ecdsa_with_SHA1, + .hash_nid = NID_sha1, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_sha256WithRSAEncryption, + .hash_nid = NID_sha256, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_sha384WithRSAEncryption, + .hash_nid = NID_sha384, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_sha512WithRSAEncryption, + .hash_nid = NID_sha512, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_sha224WithRSAEncryption, + .hash_nid = NID_sha224, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_ecdsa_with_Recommended, + .hash_nid = NID_undef, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_ecdsa_with_Specified, + .hash_nid = NID_undef, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_ecdsa_with_SHA224, + .hash_nid = NID_sha224, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_ecdsa_with_SHA256, + .hash_nid = NID_sha256, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_ecdsa_with_SHA384, + .hash_nid = NID_sha384, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_ecdsa_with_SHA512, + .hash_nid = NID_sha512, + .pkey_nid = NID_X9_62_id_ecPublicKey, + }, + { + .sign_nid = NID_dsa_with_SHA224, + .hash_nid = NID_sha224, + .pkey_nid = NID_dsa, + }, + { + .sign_nid = NID_dsa_with_SHA256, + .hash_nid = NID_sha256, + .pkey_nid = NID_dsa, + }, + { + .sign_nid = NID_id_GostR3411_94_with_GostR3410_2001, + .hash_nid = NID_id_GostR3411_94, + .pkey_nid = NID_id_GostR3410_2001, + }, + { + .sign_nid = NID_id_GostR3411_94_with_GostR3410_94, + .hash_nid = NID_id_GostR3411_94, + .pkey_nid = NID_id_GostR3410_94, + }, + { + .sign_nid = NID_id_GostR3411_94_with_GostR3410_94_cc, + .hash_nid = NID_id_GostR3411_94, + .pkey_nid = NID_id_GostR3410_94_cc, + }, + { + .sign_nid = NID_id_GostR3411_94_with_GostR3410_2001_cc, + .hash_nid = NID_id_GostR3411_94, + .pkey_nid = NID_id_GostR3410_2001_cc, + }, + { + .sign_nid = NID_rsassaPss, + .hash_nid = NID_undef, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_id_tc26_signwithdigest_gost3410_2012_256, + .hash_nid = NID_id_tc26_gost3411_2012_256, + .pkey_nid = NID_id_GostR3410_2001, + }, + { + .sign_nid = NID_id_tc26_signwithdigest_gost3410_2012_512, + .hash_nid = NID_id_tc26_gost3411_2012_512, + .pkey_nid = NID_id_GostR3410_2001, + }, + { + .sign_nid = NID_Ed25519, + .hash_nid = NID_undef, + .pkey_nid = NID_Ed25519, + }, + { + .sign_nid = NID_dhSinglePass_stdDH_sha1kdf_scheme, + .hash_nid = NID_sha1, + .pkey_nid = NID_dh_std_kdf, + }, + { + .sign_nid = NID_dhSinglePass_stdDH_sha224kdf_scheme, + .hash_nid = NID_sha224, + .pkey_nid = NID_dh_std_kdf, + }, + { + .sign_nid = NID_dhSinglePass_stdDH_sha256kdf_scheme, + .hash_nid = NID_sha256, + .pkey_nid = NID_dh_std_kdf, + }, + { + .sign_nid = NID_dhSinglePass_stdDH_sha384kdf_scheme, + .hash_nid = NID_sha384, + .pkey_nid = NID_dh_std_kdf, + }, + { + .sign_nid = NID_dhSinglePass_stdDH_sha512kdf_scheme, + .hash_nid = NID_sha512, + .pkey_nid = NID_dh_std_kdf, + }, + { + .sign_nid = NID_dhSinglePass_cofactorDH_sha1kdf_scheme, + .hash_nid = NID_sha1, + .pkey_nid = NID_dh_cofactor_kdf, + }, + { + .sign_nid = NID_dhSinglePass_cofactorDH_sha224kdf_scheme, + .hash_nid = NID_sha224, + .pkey_nid = NID_dh_cofactor_kdf, + }, + { + .sign_nid = NID_dhSinglePass_cofactorDH_sha256kdf_scheme, + .hash_nid = NID_sha256, + .pkey_nid = NID_dh_cofactor_kdf, + }, + { + .sign_nid = NID_dhSinglePass_cofactorDH_sha384kdf_scheme, + .hash_nid = NID_sha384, + .pkey_nid = NID_dh_cofactor_kdf, + }, + { + .sign_nid = NID_dhSinglePass_cofactorDH_sha512kdf_scheme, + .hash_nid = NID_sha512, + .pkey_nid = NID_dh_cofactor_kdf, + }, + { + .sign_nid = NID_RSA_SHA3_224, + .hash_nid = NID_sha3_224, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_RSA_SHA3_256, + .hash_nid = NID_sha3_256, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_RSA_SHA3_384, + .hash_nid = NID_sha3_384, + .pkey_nid = NID_rsaEncryption, + }, + { + .sign_nid = NID_RSA_SHA3_512, + .hash_nid = NID_sha3_512, + .pkey_nid = NID_rsaEncryption, + }, +}; + +#define N_NID_TRIPLES (sizeof(nid_triple) / sizeof(nid_triple[0])) + +int +OBJ_find_sigid_algs(int sign_nid, int *hash_nid, int *pkey_nid) +{ + size_t i; + + for (i = 0; i < N_NID_TRIPLES; i++) { + if (sign_nid != nid_triple[i].sign_nid) + continue; + + if (hash_nid != NULL) + *hash_nid = nid_triple[i].hash_nid; + if (pkey_nid != NULL) + *pkey_nid = nid_triple[i].pkey_nid; + + return 1; + } + + return 0; +} +LCRYPTO_ALIAS(OBJ_find_sigid_algs); + +int +OBJ_find_sigid_by_algs(int *sign_nid, int hash_nid, int pkey_nid) +{ + size_t i; + + for (i = 0; i < N_NID_TRIPLES; i++) { + if (hash_nid != nid_triple[i].hash_nid) + continue; + if (pkey_nid != nid_triple[i].pkey_nid) + continue; + + if (sign_nid != NULL) + *sign_nid = nid_triple[i].sign_nid; + + return 1; + } + + return 0; +} +LCRYPTO_ALIAS(OBJ_find_sigid_by_algs); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_asn.c b/Libraries/libressl/crypto/ocsp/ocsp_asn.c new file mode 100644 index 000000000..4fbdd5fd7 --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_asn.c @@ -0,0 +1,1051 @@ +/* $OpenBSD: ocsp_asn.c,v 1.11 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include + +#include "ocsp_local.h" + +static const ASN1_TEMPLATE OCSP_SIGNATURE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_SIGNATURE, signatureAlgorithm), + .field_name = "signatureAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_SIGNATURE, signature), + .field_name = "signature", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_SIGNATURE, certs), + .field_name = "certs", + .item = &X509_it, + }, +}; + +const ASN1_ITEM OCSP_SIGNATURE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_SIGNATURE_seq_tt, + .tcount = sizeof(OCSP_SIGNATURE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_SIGNATURE), + .sname = "OCSP_SIGNATURE", +}; + + +OCSP_SIGNATURE * +d2i_OCSP_SIGNATURE(OCSP_SIGNATURE **a, const unsigned char **in, long len) +{ + return (OCSP_SIGNATURE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_SIGNATURE_it); +} +LCRYPTO_ALIAS(d2i_OCSP_SIGNATURE); + +int +i2d_OCSP_SIGNATURE(OCSP_SIGNATURE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_SIGNATURE_it); +} +LCRYPTO_ALIAS(i2d_OCSP_SIGNATURE); + +OCSP_SIGNATURE * +OCSP_SIGNATURE_new(void) +{ + return (OCSP_SIGNATURE *)ASN1_item_new(&OCSP_SIGNATURE_it); +} +LCRYPTO_ALIAS(OCSP_SIGNATURE_new); + +void +OCSP_SIGNATURE_free(OCSP_SIGNATURE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_SIGNATURE_it); +} +LCRYPTO_ALIAS(OCSP_SIGNATURE_free); + +static const ASN1_TEMPLATE OCSP_CERTID_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_CERTID, hashAlgorithm), + .field_name = "hashAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_CERTID, issuerNameHash), + .field_name = "issuerNameHash", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_CERTID, issuerKeyHash), + .field_name = "issuerKeyHash", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_CERTID, serialNumber), + .field_name = "serialNumber", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM OCSP_CERTID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_CERTID_seq_tt, + .tcount = sizeof(OCSP_CERTID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_CERTID), + .sname = "OCSP_CERTID", +}; + + +OCSP_CERTID * +d2i_OCSP_CERTID(OCSP_CERTID **a, const unsigned char **in, long len) +{ + return (OCSP_CERTID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_CERTID_it); +} +LCRYPTO_ALIAS(d2i_OCSP_CERTID); + +int +i2d_OCSP_CERTID(OCSP_CERTID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_CERTID_it); +} +LCRYPTO_ALIAS(i2d_OCSP_CERTID); + +OCSP_CERTID * +OCSP_CERTID_new(void) +{ + return (OCSP_CERTID *)ASN1_item_new(&OCSP_CERTID_it); +} +LCRYPTO_ALIAS(OCSP_CERTID_new); + +void +OCSP_CERTID_free(OCSP_CERTID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_CERTID_it); +} +LCRYPTO_ALIAS(OCSP_CERTID_free); + +static const ASN1_TEMPLATE OCSP_ONEREQ_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_ONEREQ, reqCert), + .field_name = "reqCert", + .item = &OCSP_CERTID_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_ONEREQ, singleRequestExtensions), + .field_name = "singleRequestExtensions", + .item = &X509_EXTENSION_it, + }, +}; + +const ASN1_ITEM OCSP_ONEREQ_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_ONEREQ_seq_tt, + .tcount = sizeof(OCSP_ONEREQ_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_ONEREQ), + .sname = "OCSP_ONEREQ", +}; + + +OCSP_ONEREQ * +d2i_OCSP_ONEREQ(OCSP_ONEREQ **a, const unsigned char **in, long len) +{ + return (OCSP_ONEREQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_ONEREQ_it); +} +LCRYPTO_ALIAS(d2i_OCSP_ONEREQ); + +int +i2d_OCSP_ONEREQ(OCSP_ONEREQ *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_ONEREQ_it); +} +LCRYPTO_ALIAS(i2d_OCSP_ONEREQ); + +OCSP_ONEREQ * +OCSP_ONEREQ_new(void) +{ + return (OCSP_ONEREQ *)ASN1_item_new(&OCSP_ONEREQ_it); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_new); + +void +OCSP_ONEREQ_free(OCSP_ONEREQ *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_ONEREQ_it); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_free); + +static const ASN1_TEMPLATE OCSP_REQINFO_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_REQINFO, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(OCSP_REQINFO, requestorName), + .field_name = "requestorName", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(OCSP_REQINFO, requestList), + .field_name = "requestList", + .item = &OCSP_ONEREQ_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(OCSP_REQINFO, requestExtensions), + .field_name = "requestExtensions", + .item = &X509_EXTENSION_it, + }, +}; + +const ASN1_ITEM OCSP_REQINFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_REQINFO_seq_tt, + .tcount = sizeof(OCSP_REQINFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_REQINFO), + .sname = "OCSP_REQINFO", +}; + + +OCSP_REQINFO * +d2i_OCSP_REQINFO(OCSP_REQINFO **a, const unsigned char **in, long len) +{ + return (OCSP_REQINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_REQINFO_it); +} +LCRYPTO_ALIAS(d2i_OCSP_REQINFO); + +int +i2d_OCSP_REQINFO(OCSP_REQINFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_REQINFO_it); +} +LCRYPTO_ALIAS(i2d_OCSP_REQINFO); + +OCSP_REQINFO * +OCSP_REQINFO_new(void) +{ + return (OCSP_REQINFO *)ASN1_item_new(&OCSP_REQINFO_it); +} +LCRYPTO_ALIAS(OCSP_REQINFO_new); + +void +OCSP_REQINFO_free(OCSP_REQINFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_REQINFO_it); +} +LCRYPTO_ALIAS(OCSP_REQINFO_free); + +static const ASN1_TEMPLATE OCSP_REQUEST_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_REQUEST, tbsRequest), + .field_name = "tbsRequest", + .item = &OCSP_REQINFO_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_REQUEST, optionalSignature), + .field_name = "optionalSignature", + .item = &OCSP_SIGNATURE_it, + }, +}; + +const ASN1_ITEM OCSP_REQUEST_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_REQUEST_seq_tt, + .tcount = sizeof(OCSP_REQUEST_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_REQUEST), + .sname = "OCSP_REQUEST", +}; + +OCSP_REQUEST * +d2i_OCSP_REQUEST(OCSP_REQUEST **a, const unsigned char **in, long len) +{ + return (OCSP_REQUEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_REQUEST_it); +} +LCRYPTO_ALIAS(d2i_OCSP_REQUEST); + +int +i2d_OCSP_REQUEST(OCSP_REQUEST *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_REQUEST_it); +} +LCRYPTO_ALIAS(i2d_OCSP_REQUEST); + +OCSP_REQUEST * +d2i_OCSP_REQUEST_bio(BIO *bp, OCSP_REQUEST **a) +{ + return ASN1_item_d2i_bio(&OCSP_REQUEST_it, bp, a); +} +LCRYPTO_ALIAS(d2i_OCSP_REQUEST_bio); + +int +i2d_OCSP_REQUEST_bio(BIO *bp, OCSP_REQUEST *a) +{ + return ASN1_item_i2d_bio(&OCSP_REQUEST_it, bp, a); +} +LCRYPTO_ALIAS(i2d_OCSP_REQUEST_bio); + +OCSP_REQUEST * +OCSP_REQUEST_new(void) +{ + return (OCSP_REQUEST *)ASN1_item_new(&OCSP_REQUEST_it); +} +LCRYPTO_ALIAS(OCSP_REQUEST_new); + +void +OCSP_REQUEST_free(OCSP_REQUEST *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_REQUEST_it); +} +LCRYPTO_ALIAS(OCSP_REQUEST_free); + +/* OCSP_RESPONSE templates */ + +static const ASN1_TEMPLATE OCSP_RESPBYTES_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_RESPBYTES, responseType), + .field_name = "responseType", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_RESPBYTES, response), + .field_name = "response", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM OCSP_RESPBYTES_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_RESPBYTES_seq_tt, + .tcount = sizeof(OCSP_RESPBYTES_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_RESPBYTES), + .sname = "OCSP_RESPBYTES", +}; + + +OCSP_RESPBYTES * +d2i_OCSP_RESPBYTES(OCSP_RESPBYTES **a, const unsigned char **in, long len) +{ + return (OCSP_RESPBYTES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_RESPBYTES_it); +} +LCRYPTO_ALIAS(d2i_OCSP_RESPBYTES); + +int +i2d_OCSP_RESPBYTES(OCSP_RESPBYTES *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPBYTES_it); +} +LCRYPTO_ALIAS(i2d_OCSP_RESPBYTES); + +OCSP_RESPBYTES * +OCSP_RESPBYTES_new(void) +{ + return (OCSP_RESPBYTES *)ASN1_item_new(&OCSP_RESPBYTES_it); +} +LCRYPTO_ALIAS(OCSP_RESPBYTES_new); + +void +OCSP_RESPBYTES_free(OCSP_RESPBYTES *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPBYTES_it); +} +LCRYPTO_ALIAS(OCSP_RESPBYTES_free); + +static const ASN1_TEMPLATE OCSP_RESPONSE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_RESPONSE, responseStatus), + .field_name = "responseStatus", + .item = &ASN1_ENUMERATED_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_RESPONSE, responseBytes), + .field_name = "responseBytes", + .item = &OCSP_RESPBYTES_it, + }, +}; + +const ASN1_ITEM OCSP_RESPONSE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_RESPONSE_seq_tt, + .tcount = sizeof(OCSP_RESPONSE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_RESPONSE), + .sname = "OCSP_RESPONSE", +}; + + +OCSP_RESPONSE * +d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len) +{ + return (OCSP_RESPONSE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_RESPONSE_it); +} +LCRYPTO_ALIAS(d2i_OCSP_RESPONSE); + +int +i2d_OCSP_RESPONSE(OCSP_RESPONSE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPONSE_it); +} +LCRYPTO_ALIAS(i2d_OCSP_RESPONSE); + +OCSP_RESPONSE * +d2i_OCSP_RESPONSE_bio(BIO *bp, OCSP_RESPONSE **a) +{ + return ASN1_item_d2i_bio(&OCSP_RESPONSE_it, bp, a); +} +LCRYPTO_ALIAS(d2i_OCSP_RESPONSE_bio); + +int +i2d_OCSP_RESPONSE_bio(BIO *bp, OCSP_RESPONSE *a) +{ + return ASN1_item_i2d_bio(&OCSP_RESPONSE_it, bp, a); +} +LCRYPTO_ALIAS(i2d_OCSP_RESPONSE_bio); + +OCSP_RESPONSE * +OCSP_RESPONSE_new(void) +{ + return (OCSP_RESPONSE *)ASN1_item_new(&OCSP_RESPONSE_it); +} +LCRYPTO_ALIAS(OCSP_RESPONSE_new); + +void +OCSP_RESPONSE_free(OCSP_RESPONSE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPONSE_it); +} +LCRYPTO_ALIAS(OCSP_RESPONSE_free); + +static const ASN1_TEMPLATE OCSP_RESPID_ch_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 1, + .offset = offsetof(OCSP_RESPID, value.byName), + .field_name = "value.byName", + .item = &X509_NAME_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 2, + .offset = offsetof(OCSP_RESPID, value.byKey), + .field_name = "value.byKey", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM OCSP_RESPID_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(OCSP_RESPID, type), + .templates = OCSP_RESPID_ch_tt, + .tcount = sizeof(OCSP_RESPID_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_RESPID), + .sname = "OCSP_RESPID", +}; + + +OCSP_RESPID * +d2i_OCSP_RESPID(OCSP_RESPID **a, const unsigned char **in, long len) +{ + return (OCSP_RESPID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_RESPID_it); +} +LCRYPTO_ALIAS(d2i_OCSP_RESPID); + +int +i2d_OCSP_RESPID(OCSP_RESPID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPID_it); +} +LCRYPTO_ALIAS(i2d_OCSP_RESPID); + +OCSP_RESPID * +OCSP_RESPID_new(void) +{ + return (OCSP_RESPID *)ASN1_item_new(&OCSP_RESPID_it); +} +LCRYPTO_ALIAS(OCSP_RESPID_new); + +void +OCSP_RESPID_free(OCSP_RESPID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPID_it); +} +LCRYPTO_ALIAS(OCSP_RESPID_free); + +static const ASN1_TEMPLATE OCSP_REVOKEDINFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_REVOKEDINFO, revocationTime), + .field_name = "revocationTime", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_REVOKEDINFO, revocationReason), + .field_name = "revocationReason", + .item = &ASN1_ENUMERATED_it, + }, +}; + +const ASN1_ITEM OCSP_REVOKEDINFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_REVOKEDINFO_seq_tt, + .tcount = sizeof(OCSP_REVOKEDINFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_REVOKEDINFO), + .sname = "OCSP_REVOKEDINFO", +}; + + +OCSP_REVOKEDINFO * +d2i_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO **a, const unsigned char **in, long len) +{ + return (OCSP_REVOKEDINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_REVOKEDINFO_it); +} +LCRYPTO_ALIAS(d2i_OCSP_REVOKEDINFO); + +int +i2d_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_REVOKEDINFO_it); +} +LCRYPTO_ALIAS(i2d_OCSP_REVOKEDINFO); + +OCSP_REVOKEDINFO * +OCSP_REVOKEDINFO_new(void) +{ + return (OCSP_REVOKEDINFO *)ASN1_item_new(&OCSP_REVOKEDINFO_it); +} +LCRYPTO_ALIAS(OCSP_REVOKEDINFO_new); + +void +OCSP_REVOKEDINFO_free(OCSP_REVOKEDINFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_REVOKEDINFO_it); +} +LCRYPTO_ALIAS(OCSP_REVOKEDINFO_free); + +static const ASN1_TEMPLATE OCSP_CERTSTATUS_ch_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 0, + .offset = offsetof(OCSP_CERTSTATUS, value.good), + .field_name = "value.good", + .item = &ASN1_NULL_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 1, + .offset = offsetof(OCSP_CERTSTATUS, value.revoked), + .field_name = "value.revoked", + .item = &OCSP_REVOKEDINFO_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = 2, + .offset = offsetof(OCSP_CERTSTATUS, value.unknown), + .field_name = "value.unknown", + .item = &ASN1_NULL_it, + }, +}; + +const ASN1_ITEM OCSP_CERTSTATUS_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(OCSP_CERTSTATUS, type), + .templates = OCSP_CERTSTATUS_ch_tt, + .tcount = sizeof(OCSP_CERTSTATUS_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_CERTSTATUS), + .sname = "OCSP_CERTSTATUS", +}; + + +OCSP_CERTSTATUS * +d2i_OCSP_CERTSTATUS(OCSP_CERTSTATUS **a, const unsigned char **in, long len) +{ + return (OCSP_CERTSTATUS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_CERTSTATUS_it); +} +LCRYPTO_ALIAS(d2i_OCSP_CERTSTATUS); + +int +i2d_OCSP_CERTSTATUS(OCSP_CERTSTATUS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_CERTSTATUS_it); +} +LCRYPTO_ALIAS(i2d_OCSP_CERTSTATUS); + +OCSP_CERTSTATUS * +OCSP_CERTSTATUS_new(void) +{ + return (OCSP_CERTSTATUS *)ASN1_item_new(&OCSP_CERTSTATUS_it); +} +LCRYPTO_ALIAS(OCSP_CERTSTATUS_new); + +void +OCSP_CERTSTATUS_free(OCSP_CERTSTATUS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_CERTSTATUS_it); +} +LCRYPTO_ALIAS(OCSP_CERTSTATUS_free); + +static const ASN1_TEMPLATE OCSP_SINGLERESP_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_SINGLERESP, certId), + .field_name = "certId", + .item = &OCSP_CERTID_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_SINGLERESP, certStatus), + .field_name = "certStatus", + .item = &OCSP_CERTSTATUS_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_SINGLERESP, thisUpdate), + .field_name = "thisUpdate", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_SINGLERESP, nextUpdate), + .field_name = "nextUpdate", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(OCSP_SINGLERESP, singleExtensions), + .field_name = "singleExtensions", + .item = &X509_EXTENSION_it, + }, +}; + +const ASN1_ITEM OCSP_SINGLERESP_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_SINGLERESP_seq_tt, + .tcount = sizeof(OCSP_SINGLERESP_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_SINGLERESP), + .sname = "OCSP_SINGLERESP", +}; + + +OCSP_SINGLERESP * +d2i_OCSP_SINGLERESP(OCSP_SINGLERESP **a, const unsigned char **in, long len) +{ + return (OCSP_SINGLERESP *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_SINGLERESP_it); +} +LCRYPTO_ALIAS(d2i_OCSP_SINGLERESP); + +int +i2d_OCSP_SINGLERESP(OCSP_SINGLERESP *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_SINGLERESP_it); +} +LCRYPTO_ALIAS(i2d_OCSP_SINGLERESP); + +OCSP_SINGLERESP * +OCSP_SINGLERESP_new(void) +{ + return (OCSP_SINGLERESP *)ASN1_item_new(&OCSP_SINGLERESP_it); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_new); + +void +OCSP_SINGLERESP_free(OCSP_SINGLERESP *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_SINGLERESP_it); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_free); + +static const ASN1_TEMPLATE OCSP_RESPDATA_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_RESPDATA, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_RESPDATA, responderId), + .field_name = "responderId", + .item = &OCSP_RESPID_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_RESPDATA, producedAt), + .field_name = "producedAt", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(OCSP_RESPDATA, responses), + .field_name = "responses", + .item = &OCSP_SINGLERESP_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(OCSP_RESPDATA, responseExtensions), + .field_name = "responseExtensions", + .item = &X509_EXTENSION_it, + }, +}; + +const ASN1_ITEM OCSP_RESPDATA_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_RESPDATA_seq_tt, + .tcount = sizeof(OCSP_RESPDATA_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_RESPDATA), + .sname = "OCSP_RESPDATA", +}; + + +OCSP_RESPDATA * +d2i_OCSP_RESPDATA(OCSP_RESPDATA **a, const unsigned char **in, long len) +{ + return (OCSP_RESPDATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_RESPDATA_it); +} +LCRYPTO_ALIAS(d2i_OCSP_RESPDATA); + +int +i2d_OCSP_RESPDATA(OCSP_RESPDATA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPDATA_it); +} +LCRYPTO_ALIAS(i2d_OCSP_RESPDATA); + +OCSP_RESPDATA * +OCSP_RESPDATA_new(void) +{ + return (OCSP_RESPDATA *)ASN1_item_new(&OCSP_RESPDATA_it); +} +LCRYPTO_ALIAS(OCSP_RESPDATA_new); + +void +OCSP_RESPDATA_free(OCSP_RESPDATA *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPDATA_it); +} +LCRYPTO_ALIAS(OCSP_RESPDATA_free); + +static const ASN1_TEMPLATE OCSP_BASICRESP_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_BASICRESP, tbsResponseData), + .field_name = "tbsResponseData", + .item = &OCSP_RESPDATA_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_BASICRESP, signatureAlgorithm), + .field_name = "signatureAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_BASICRESP, signature), + .field_name = "signature", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_BASICRESP, certs), + .field_name = "certs", + .item = &X509_it, + }, +}; + +const ASN1_ITEM OCSP_BASICRESP_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_BASICRESP_seq_tt, + .tcount = sizeof(OCSP_BASICRESP_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_BASICRESP), + .sname = "OCSP_BASICRESP", +}; + + +OCSP_BASICRESP * +d2i_OCSP_BASICRESP(OCSP_BASICRESP **a, const unsigned char **in, long len) +{ + return (OCSP_BASICRESP *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_BASICRESP_it); +} +LCRYPTO_ALIAS(d2i_OCSP_BASICRESP); + +int +i2d_OCSP_BASICRESP(OCSP_BASICRESP *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_BASICRESP_it); +} +LCRYPTO_ALIAS(i2d_OCSP_BASICRESP); + +OCSP_BASICRESP * +OCSP_BASICRESP_new(void) +{ + return (OCSP_BASICRESP *)ASN1_item_new(&OCSP_BASICRESP_it); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_new); + +void +OCSP_BASICRESP_free(OCSP_BASICRESP *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_BASICRESP_it); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_free); + +static const ASN1_TEMPLATE OCSP_CRLID_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_CRLID, crlUrl), + .field_name = "crlUrl", + .item = &ASN1_IA5STRING_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(OCSP_CRLID, crlNum), + .field_name = "crlNum", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(OCSP_CRLID, crlTime), + .field_name = "crlTime", + .item = &ASN1_GENERALIZEDTIME_it, + }, +}; + +const ASN1_ITEM OCSP_CRLID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_CRLID_seq_tt, + .tcount = sizeof(OCSP_CRLID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_CRLID), + .sname = "OCSP_CRLID", +}; + + +OCSP_CRLID * +d2i_OCSP_CRLID(OCSP_CRLID **a, const unsigned char **in, long len) +{ + return (OCSP_CRLID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_CRLID_it); +} +LCRYPTO_ALIAS(d2i_OCSP_CRLID); + +int +i2d_OCSP_CRLID(OCSP_CRLID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_CRLID_it); +} +LCRYPTO_ALIAS(i2d_OCSP_CRLID); + +OCSP_CRLID * +OCSP_CRLID_new(void) +{ + return (OCSP_CRLID *)ASN1_item_new(&OCSP_CRLID_it); +} +LCRYPTO_ALIAS(OCSP_CRLID_new); + +void +OCSP_CRLID_free(OCSP_CRLID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_CRLID_it); +} +LCRYPTO_ALIAS(OCSP_CRLID_free); + +static const ASN1_TEMPLATE OCSP_SERVICELOC_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OCSP_SERVICELOC, issuer), + .field_name = "issuer", + .item = &X509_NAME_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(OCSP_SERVICELOC, locator), + .field_name = "locator", + .item = &ACCESS_DESCRIPTION_it, + }, +}; + +const ASN1_ITEM OCSP_SERVICELOC_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OCSP_SERVICELOC_seq_tt, + .tcount = sizeof(OCSP_SERVICELOC_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OCSP_SERVICELOC), + .sname = "OCSP_SERVICELOC", +}; + + +OCSP_SERVICELOC * +d2i_OCSP_SERVICELOC(OCSP_SERVICELOC **a, const unsigned char **in, long len) +{ + return (OCSP_SERVICELOC *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OCSP_SERVICELOC_it); +} +LCRYPTO_ALIAS(d2i_OCSP_SERVICELOC); + +int +i2d_OCSP_SERVICELOC(OCSP_SERVICELOC *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_SERVICELOC_it); +} +LCRYPTO_ALIAS(i2d_OCSP_SERVICELOC); + +OCSP_SERVICELOC * +OCSP_SERVICELOC_new(void) +{ + return (OCSP_SERVICELOC *)ASN1_item_new(&OCSP_SERVICELOC_it); +} +LCRYPTO_ALIAS(OCSP_SERVICELOC_new); + +void +OCSP_SERVICELOC_free(OCSP_SERVICELOC *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OCSP_SERVICELOC_it); +} +LCRYPTO_ALIAS(OCSP_SERVICELOC_free); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_cl.c b/Libraries/libressl/crypto/ocsp/ocsp_cl.c new file mode 100644 index 000000000..89113f78b --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_cl.c @@ -0,0 +1,469 @@ +/* $OpenBSD: ocsp_cl.c,v 1.23 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was transfered to Richard Levitte from CertCo by Kathy + Weinhold in mid-spring 2000 to be included in OpenSSL or released + as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ocsp_local.h" + +/* Utility functions related to sending OCSP requests and extracting + * relevant information from the response. + */ + +/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ + * pointer: useful if we want to add extensions. + */ +OCSP_ONEREQ * +OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) +{ + OCSP_ONEREQ *one; + + if ((one = OCSP_ONEREQ_new()) == NULL) + goto err; + if (req != NULL) { + if (!sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) + goto err; + } + OCSP_CERTID_free(one->reqCert); + one->reqCert = cid; + return one; + + err: + OCSP_ONEREQ_free(one); + return NULL; +} +LCRYPTO_ALIAS(OCSP_request_add0_id); + +/* Set requestorName from an X509_NAME structure */ +int +OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) +{ + GENERAL_NAME *gen; + + gen = GENERAL_NAME_new(); + if (gen == NULL) + return 0; + if (!X509_NAME_set(&gen->d.directoryName, nm)) { + GENERAL_NAME_free(gen); + return 0; + } + gen->type = GEN_DIRNAME; + if (req->tbsRequest->requestorName) + GENERAL_NAME_free(req->tbsRequest->requestorName); + req->tbsRequest->requestorName = gen; + return 1; +} +LCRYPTO_ALIAS(OCSP_request_set1_name); + +/* Add a certificate to an OCSP request */ +int +OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) +{ + OCSP_SIGNATURE *sig; + + if (!req->optionalSignature) + req->optionalSignature = OCSP_SIGNATURE_new(); + sig = req->optionalSignature; + if (!sig) + return 0; + if (!cert) + return 1; + if (!sig->certs && !(sig->certs = sk_X509_new_null())) + return 0; + + if (!sk_X509_push(sig->certs, cert)) + return 0; + X509_up_ref(cert); + return 1; +} +LCRYPTO_ALIAS(OCSP_request_add1_cert); + +/* Sign an OCSP request set the requestorName to the subject + * name of an optional signers certificate and include one + * or more optional certificates in the request. Behaves + * like PKCS7_sign(). + */ +int +OCSP_request_sign(OCSP_REQUEST *req, X509 *signer, EVP_PKEY *key, + const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags) +{ + int i; + OCSP_SIGNATURE *sig; + X509 *x; + + if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) + goto err; + + if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) + goto err; + if (key) { + if (!X509_check_private_key(signer, key)) { + OCSPerror(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + if (!OCSP_REQUEST_sign(req, key, dgst)) + goto err; + } + + if (!(flags & OCSP_NOCERTS)) { + if (!OCSP_request_add1_cert(req, signer)) + goto err; + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + if (!OCSP_request_add1_cert(req, x)) + goto err; + } + } + + return 1; + +err: + OCSP_SIGNATURE_free(req->optionalSignature); + req->optionalSignature = NULL; + return 0; +} +LCRYPTO_ALIAS(OCSP_request_sign); + +/* Get response status */ +int +OCSP_response_status(OCSP_RESPONSE *resp) +{ + return ASN1_ENUMERATED_get(resp->responseStatus); +} +LCRYPTO_ALIAS(OCSP_response_status); + +/* Extract basic response from OCSP_RESPONSE or NULL if + * no basic response present. + */ +OCSP_BASICRESP * +OCSP_response_get1_basic(OCSP_RESPONSE *resp) +{ + OCSP_RESPBYTES *rb; + + rb = resp->responseBytes; + if (!rb) { + OCSPerror(OCSP_R_NO_RESPONSE_DATA); + return NULL; + } + if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { + OCSPerror(OCSP_R_NOT_BASIC_RESPONSE); + return NULL; + } + + return ASN1_item_unpack(rb->response, &OCSP_BASICRESP_it); +} +LCRYPTO_ALIAS(OCSP_response_get1_basic); + +/* Return number of OCSP_SINGLERESP responses present in + * a basic response. + */ +int +OCSP_resp_count(OCSP_BASICRESP *bs) +{ + if (!bs) + return -1; + return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses); +} +LCRYPTO_ALIAS(OCSP_resp_count); + +/* Extract an OCSP_SINGLERESP response with a given index */ +OCSP_SINGLERESP * +OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) +{ + if (!bs) + return NULL; + return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx); +} +LCRYPTO_ALIAS(OCSP_resp_get0); + +const ASN1_GENERALIZEDTIME * +OCSP_resp_get0_produced_at(const OCSP_BASICRESP *bs) +{ + return bs->tbsResponseData->producedAt; +} +LCRYPTO_ALIAS(OCSP_resp_get0_produced_at); + +const STACK_OF(X509) * +OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) +{ + return bs->certs; +} +LCRYPTO_ALIAS(OCSP_resp_get0_certs); + +int +OCSP_resp_get0_id(const OCSP_BASICRESP *bs, const ASN1_OCTET_STRING **pid, + const X509_NAME **pname) +{ + const OCSP_RESPID *rid = bs->tbsResponseData->responderId; + + if (rid->type == V_OCSP_RESPID_NAME) { + *pname = rid->value.byName; + *pid = NULL; + } else if (rid->type == V_OCSP_RESPID_KEY) { + *pid = rid->value.byKey; + *pname = NULL; + } else { + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(OCSP_resp_get0_id); + +const ASN1_OCTET_STRING * +OCSP_resp_get0_signature(const OCSP_BASICRESP *bs) +{ + return bs->signature; +} +LCRYPTO_ALIAS(OCSP_resp_get0_signature); + +const X509_ALGOR * +OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs) +{ + return bs->signatureAlgorithm; +} +LCRYPTO_ALIAS(OCSP_resp_get0_tbs_sigalg); + +const OCSP_RESPDATA * +OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs) +{ + return bs->tbsResponseData; +} +LCRYPTO_ALIAS(OCSP_resp_get0_respdata); + +/* Look single response matching a given certificate ID */ +int +OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) +{ + int i; + STACK_OF(OCSP_SINGLERESP) *sresp; + OCSP_SINGLERESP *single; + + if (!bs) + return -1; + if (last < 0) + last = 0; + else + last++; + sresp = bs->tbsResponseData->responses; + for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) { + single = sk_OCSP_SINGLERESP_value(sresp, i); + if (!OCSP_id_cmp(id, single->certId)) + return i; + } + return -1; +} +LCRYPTO_ALIAS(OCSP_resp_find); + +/* Extract status information from an OCSP_SINGLERESP structure. + * Note: the revtime and reason values are only set if the + * certificate status is revoked. Returns numerical value of + * status. + */ +int +OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd) +{ + int ret; + OCSP_CERTSTATUS *cst; + + if (!single) + return -1; + cst = single->certStatus; + ret = cst->type; + if (ret == V_OCSP_CERTSTATUS_REVOKED) { + OCSP_REVOKEDINFO *rev = cst->value.revoked; + + if (revtime) + *revtime = rev->revocationTime; + if (reason) { + if (rev->revocationReason) + *reason = ASN1_ENUMERATED_get( + rev->revocationReason); + else + *reason = -1; + } + } + if (thisupd) + *thisupd = single->thisUpdate; + if (nextupd) + *nextupd = single->nextUpdate; + return ret; +} +LCRYPTO_ALIAS(OCSP_single_get0_status); + +/* This function combines the previous ones: look up a certificate ID and + * if found extract status information. Return 0 is successful. + */ +int +OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd) +{ + int i; + OCSP_SINGLERESP *single; + + i = OCSP_resp_find(bs, id, -1); + /* Maybe check for multiple responses and give an error? */ + if (i < 0) + return 0; + single = OCSP_resp_get0(bs, i); + i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); + if (status) + *status = i; + return 1; +} +LCRYPTO_ALIAS(OCSP_resp_find_status); + +/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will + * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid + * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time. + * Also to avoid accepting very old responses without a nextUpdate field an optional maxage + * parameter specifies the maximum age the thisUpdate field can be. + */ +int +OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) +{ + time_t t_now, t_tmp; + struct tm tm_this, tm_next, tm_tmp; + + time(&t_now); + + /* + * Times must explicitly be a GENERALIZEDTIME as per section + * 4.2.2.1 of RFC 6960 - It is invalid to accept other times + * (such as UTCTIME permitted/required by RFC 5280 for certificates) + */ + + /* Check thisUpdate is valid and not more than nsec in the future */ + if (ASN1_time_parse(thisupd->data, thisupd->length, &tm_this, + V_ASN1_GENERALIZEDTIME) != V_ASN1_GENERALIZEDTIME) { + OCSPerror(OCSP_R_ERROR_IN_THISUPDATE_FIELD); + return 0; + } else { + t_tmp = t_now + nsec; + if (gmtime_r(&t_tmp, &tm_tmp) == NULL) + return 0; + if (ASN1_time_tm_cmp(&tm_this, &tm_tmp) > 0) { + OCSPerror(OCSP_R_STATUS_NOT_YET_VALID); + return 0; + } + + /* + * If maxsec specified check thisUpdate is not more than maxsec + * in the past + */ + if (maxsec >= 0) { + t_tmp = t_now - maxsec; + if (gmtime_r(&t_tmp, &tm_tmp) == NULL) + return 0; + if (ASN1_time_tm_cmp(&tm_this, &tm_tmp) < 0) { + OCSPerror(OCSP_R_STATUS_TOO_OLD); + return 0; + } + } + } + + if (!nextupd) + return 1; + + /* Check nextUpdate is valid and not more than nsec in the past */ + if (ASN1_time_parse(nextupd->data, nextupd->length, &tm_next, + V_ASN1_GENERALIZEDTIME) != V_ASN1_GENERALIZEDTIME) { + OCSPerror(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); + return 0; + } else { + t_tmp = t_now - nsec; + if (gmtime_r(&t_tmp, &tm_tmp) == NULL) + return 0; + if (ASN1_time_tm_cmp(&tm_next, &tm_tmp) < 0) { + OCSPerror(OCSP_R_STATUS_EXPIRED); + return 0; + } + } + + /* Also don't allow nextUpdate to precede thisUpdate */ + if (ASN1_time_tm_cmp(&tm_next, &tm_this) < 0) { + OCSPerror(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(OCSP_check_validity); + +const OCSP_CERTID * +OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) +{ + return single->certId; +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get0_id); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_err.c b/Libraries/libressl/crypto/ocsp/ocsp_err.c new file mode 100644 index 000000000..865091f54 --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_err.c @@ -0,0 +1,119 @@ +/* $OpenBSD: ocsp_err.c,v 1.10 2023/07/08 10:44:00 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason) + +static ERR_STRING_DATA OCSP_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA OCSP_str_reasons[]= { + {ERR_REASON(OCSP_R_BAD_DATA) , "bad data"}, + {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(OCSP_R_DIGEST_ERR) , "digest err"}, + {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), "error in nextupdate field"}, + {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD), "error in thisupdate field"}, + {ERR_REASON(OCSP_R_ERROR_PARSING_URL) , "error parsing url"}, + {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE), "missing ocspsigning usage"}, + {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), "nextupdate before thisupdate"}, + {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE) , "not basic response"}, + {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"}, + {ERR_REASON(OCSP_R_NO_CONTENT) , "no content"}, + {ERR_REASON(OCSP_R_NO_PUBLIC_KEY) , "no public key"}, + {ERR_REASON(OCSP_R_NO_RESPONSE_DATA) , "no response data"}, + {ERR_REASON(OCSP_R_NO_REVOKED_TIME) , "no revoked time"}, + {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"}, + {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED) , "request not signed"}, + {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA), "response contains no revocation data"}, + {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED) , "root ca not trusted"}, + {ERR_REASON(OCSP_R_SERVER_READ_ERROR) , "server read error"}, + {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"}, + {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR), "server response parse error"}, + {ERR_REASON(OCSP_R_SERVER_WRITE_ERROR) , "server write error"}, + {ERR_REASON(OCSP_R_SIGNATURE_FAILURE) , "signature failure"}, + {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"}, + {ERR_REASON(OCSP_R_STATUS_EXPIRED) , "status expired"}, + {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID) , "status not yet valid"}, + {ERR_REASON(OCSP_R_STATUS_TOO_OLD) , "status too old"}, + {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"}, + {ERR_REASON(OCSP_R_UNKNOWN_NID) , "unknown nid"}, + {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE), "unsupported requestorname type"}, + {0, NULL} +}; + +#endif + +void +ERR_load_OCSP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) { + ERR_load_strings(0, OCSP_str_functs); + ERR_load_strings(0, OCSP_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_OCSP_strings); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_ext.c b/Libraries/libressl/crypto/ocsp/ocsp_ext.c new file mode 100644 index 000000000..9f8cb74b6 --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_ext.c @@ -0,0 +1,612 @@ +/* $OpenBSD: ocsp_ext.c,v 1.23 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was transfered to Richard Levitte from CertCo by Kathy + Weinhold in mid-spring 2000 to be included in OpenSSL or released + as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "ocsp_local.h" +#include "x509_local.h" + +/* Standard wrapper functions for extensions */ + +/* OCSP request extensions */ + +int +OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) +{ + return X509v3_get_ext_count(x->tbsRequest->requestExtensions); +} +LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_count); + +int +OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions, nid, + lastpos); +} +LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_by_NID); + +int +OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions, obj, + lastpos); +} +LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_by_OBJ); + +int +OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions, + crit, lastpos); +} +LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_by_critical); + +X509_EXTENSION * +OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) +{ + return X509v3_get_ext(x->tbsRequest->requestExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_REQUEST_get_ext); + +X509_EXTENSION * +OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) +{ + return X509v3_delete_ext(x->tbsRequest->requestExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_REQUEST_delete_ext); + +void * +OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); +} +LCRYPTO_ALIAS(OCSP_REQUEST_get1_ext_d2i); + +int +OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, + crit, flags); +} +LCRYPTO_ALIAS(OCSP_REQUEST_add1_ext_i2d); + +int +OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, + loc) != NULL; +} +LCRYPTO_ALIAS(OCSP_REQUEST_add_ext); + +/* Single extensions */ + +int +OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) +{ + return X509v3_get_ext_count(x->singleRequestExtensions); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_count); + +int +OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_by_NID); + +int +OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_by_OBJ); + +int +OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(x->singleRequestExtensions, crit, + lastpos); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_by_critical); + +X509_EXTENSION * +OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) +{ + return X509v3_get_ext(x->singleRequestExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext); + +X509_EXTENSION * +OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) +{ + return X509v3_delete_ext(x->singleRequestExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_delete_ext); + +void * +OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_get1_ext_d2i); + +int +OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, + flags); +} +LCRYPTO_ALIAS(OCSP_ONEREQ_add1_ext_i2d); + +int +OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL; +} +LCRYPTO_ALIAS(OCSP_ONEREQ_add_ext); + +/* OCSP Basic response */ + +int +OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) +{ + return X509v3_get_ext_count(x->tbsResponseData->responseExtensions); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_count); + +int +OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions, + nid, lastpos); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_by_NID); + +int +OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions, + obj, lastpos); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_by_OBJ); + +int +OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical( + x->tbsResponseData->responseExtensions, crit, lastpos); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_by_critical); + +X509_EXTENSION * +OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) +{ + return X509v3_get_ext(x->tbsResponseData->responseExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext); + +X509_EXTENSION * +OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) +{ + return X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_delete_ext); + +void * +OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, + crit, idx); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_get1_ext_d2i); + +int +OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, + value, crit, flags); +} +LCRYPTO_ALIAS(OCSP_BASICRESP_add1_ext_i2d); + +int +OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, + loc) != NULL; +} +LCRYPTO_ALIAS(OCSP_BASICRESP_add_ext); + +/* OCSP single response extensions */ + +int +OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) +{ + return X509v3_get_ext_count(x->singleExtensions); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_count); + +int +OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_by_NID); + +int +OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_by_OBJ); + +int +OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_by_critical); + +X509_EXTENSION * +OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) +{ + return X509v3_get_ext(x->singleExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext); + +X509_EXTENSION * +OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) +{ + return X509v3_delete_ext(x->singleExtensions, loc); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_delete_ext); + +void * +OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_get1_ext_d2i); + +int +OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_add1_ext_i2d); + +int +OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL; +} +LCRYPTO_ALIAS(OCSP_SINGLERESP_add_ext); + +/* Nonce handling functions */ + +/* Add a nonce to an extension stack. A nonce can be specified or if NULL + * a random nonce will be generated. + * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the + * nonce, previous versions used the raw nonce. + */ + +static int +ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len) +{ + unsigned char *tmpval; + ASN1_OCTET_STRING os; + int ret = 0; + + if (len <= 0) + len = OCSP_DEFAULT_NONCE_LENGTH; + /* Create the OCTET STRING manually by writing out the header and + * appending the content octets. This avoids an extra memory allocation + * operation in some cases. Applications should *NOT* do this because + * it relies on library internals. + */ + os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); + os.data = malloc(os.length); + if (os.data == NULL) + goto err; + tmpval = os.data; + ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); + if (val) + memcpy(tmpval, val, len); + else + arc4random_buf(tmpval, len); + if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, &os, 0, + X509V3_ADD_REPLACE)) + goto err; + ret = 1; + +err: + free(os.data); + return ret; +} + +/* Add nonce to an OCSP request */ +int +OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) +{ + return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); +} +LCRYPTO_ALIAS(OCSP_request_add1_nonce); + +/* Same as above but for a response */ +int +OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) +{ + return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, + len); +} +LCRYPTO_ALIAS(OCSP_basic_add1_nonce); + +/* Check nonce validity in a request and response. + * Return value reflects result: + * 1: nonces present and equal. + * 2: nonces both absent. + * 3: nonce present in response only. + * 0: nonces both present and not equal. + * -1: nonce in request only. + * + * For most responders clients can check return > 0. + * If responder doesn't handle nonces return != 0 may be + * necessary. return == 0 is always an error. + */ +int +OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) +{ + /* + * Since we are only interested in the presence or absence of + * the nonce and comparing its value there is no need to use + * the X509V3 routines: this way we can avoid them allocating an + * ASN1_OCTET_STRING structure for the value which would be + * freed immediately anyway. + */ + int req_idx, resp_idx; + X509_EXTENSION *req_ext, *resp_ext; + + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, + NID_id_pkix_OCSP_Nonce, -1); + /* Check both absent */ + if (req_idx < 0 && resp_idx < 0) + return 2; + /* Check in request only */ + if (req_idx >= 0 && resp_idx < 0) + return -1; + /* Check in response but not request */ + if (req_idx < 0 && resp_idx >= 0) + return 3; + /* Otherwise nonce in request and response so retrieve the extensions */ + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); + if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) + return 0; + return 1; +} +LCRYPTO_ALIAS(OCSP_check_nonce); + +/* Copy the nonce value (if any) from an OCSP request to + * a response. + */ +int +OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) +{ + X509_EXTENSION *req_ext; + int req_idx; + + /* Check for nonce in request */ + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + /* If no nonce that's OK */ + if (req_idx < 0) + return 2; + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + return OCSP_BASICRESP_add_ext(resp, req_ext, -1); +} +LCRYPTO_ALIAS(OCSP_copy_nonce); + +X509_EXTENSION * +OCSP_crlID_new(const char *url, long *n, char *tim) +{ + X509_EXTENSION *x = NULL; + OCSP_CRLID *cid = NULL; + + if (!(cid = OCSP_CRLID_new())) + goto err; + if (url) { + if (!(cid->crlUrl = ASN1_IA5STRING_new())) + goto err; + if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) + goto err; + } + if (n) { + if (!(cid->crlNum = ASN1_INTEGER_new())) + goto err; + if (!(ASN1_INTEGER_set(cid->crlNum, *n))) + goto err; + } + if (tim) { + if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) + goto err; + if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) + goto err; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); + +err: + if (cid) + OCSP_CRLID_free(cid); + return x; +} +LCRYPTO_ALIAS(OCSP_crlID_new); + +/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ +X509_EXTENSION * +OCSP_accept_responses_new(char **oids) +{ + int nid; + STACK_OF(ASN1_OBJECT) *sk = NULL; + ASN1_OBJECT *o = NULL; + X509_EXTENSION *x = NULL; + + if (!(sk = sk_ASN1_OBJECT_new_null())) + return NULL; + while (oids && *oids) { + if ((nid = OBJ_txt2nid(*oids)) != NID_undef && + (o = OBJ_nid2obj(nid))) + if (sk_ASN1_OBJECT_push(sk, o) == 0) { + sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); + return NULL; + } + oids++; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); + sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); + return x; +} +LCRYPTO_ALIAS(OCSP_accept_responses_new); + +/* ArchiveCutoff ::= GeneralizedTime */ +X509_EXTENSION * +OCSP_archive_cutoff_new(char* tim) +{ + X509_EXTENSION *x = NULL; + ASN1_GENERALIZEDTIME *gt = NULL; + + if (!(gt = ASN1_GENERALIZEDTIME_new())) + return NULL; + if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) + goto err; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); + +err: + if (gt) + ASN1_GENERALIZEDTIME_free(gt); + return x; +} +LCRYPTO_ALIAS(OCSP_archive_cutoff_new); + +/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently + * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This + * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. + */ +X509_EXTENSION * +OCSP_url_svcloc_new(X509_NAME* issuer, const char **urls) +{ + X509_EXTENSION *x = NULL; + ASN1_IA5STRING *ia5 = NULL; + OCSP_SERVICELOC *sloc = NULL; + ACCESS_DESCRIPTION *ad = NULL; + + if (!(sloc = OCSP_SERVICELOC_new())) + goto err; + if (!(sloc->issuer = X509_NAME_dup(issuer))) + goto err; + if (urls && *urls && + !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) + goto err; + while (urls && *urls) { + if (!(ad = ACCESS_DESCRIPTION_new())) + goto err; + if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) + goto err; + if (!(ad->location = GENERAL_NAME_new())) + goto err; + if (!(ia5 = ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) + goto err; + ad->location->type = GEN_URI; + ad->location->d.ia5 = ia5; + ia5 = NULL; + if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) + goto err; + ad = NULL; + urls++; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); + +err: + if (ia5) + ASN1_IA5STRING_free(ia5); + if (ad) + ACCESS_DESCRIPTION_free(ad); + if (sloc) + OCSP_SERVICELOC_free(sloc); + return x; +} +LCRYPTO_ALIAS(OCSP_url_svcloc_new); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_ht.c b/Libraries/libressl/crypto/ocsp/ocsp_ht.c new file mode 100644 index 000000000..bf735c72a --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_ht.c @@ -0,0 +1,469 @@ +/* $OpenBSD: ocsp_ht.c,v 1.26 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Stateful OCSP request code, supporting non-blocking I/O */ + +/* Opaque OCSP request status structure */ + +struct ocsp_req_ctx_st { + int state; /* Current I/O state */ + unsigned char *iobuf; /* Line buffer */ + int iobuflen; /* Line buffer length */ + BIO *io; /* BIO to perform I/O with */ + BIO *mem; /* Memory BIO response is built into */ + unsigned long asn1_len; /* ASN1 length of response */ +}; + +#define OCSP_MAX_REQUEST_LENGTH (100 * 1024) +#define OCSP_MAX_LINE_LEN 4096; + +/* OCSP states */ + +/* If set no reading should be performed */ +#define OHS_NOREAD 0x1000 +/* Error condition */ +#define OHS_ERROR (0 | OHS_NOREAD) +/* First line being read */ +#define OHS_FIRSTLINE 1 +/* MIME headers being read */ +#define OHS_HEADERS 2 +/* OCSP initial header (tag + length) being read */ +#define OHS_ASN1_HEADER 3 +/* OCSP content octets being read */ +#define OHS_ASN1_CONTENT 4 +/* Request being sent */ +#define OHS_ASN1_WRITE (6 | OHS_NOREAD) +/* Request being flushed */ +#define OHS_ASN1_FLUSH (7 | OHS_NOREAD) +/* Completed */ +#define OHS_DONE (8 | OHS_NOREAD) + + +static int parse_http_line1(char *line); + +void +OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) +{ + if (rctx == NULL) + return; + + BIO_free(rctx->mem); + free(rctx->iobuf); + free(rctx); +} +LCRYPTO_ALIAS(OCSP_REQ_CTX_free); + +int +OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) +{ + if (BIO_printf(rctx->mem, "Content-Type: application/ocsp-request\r\n" + "Content-Length: %d\r\n\r\n", i2d_OCSP_REQUEST(req, NULL)) <= 0) + return 0; + if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) + return 0; + rctx->state = OHS_ASN1_WRITE; + rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); + return 1; +} +LCRYPTO_ALIAS(OCSP_REQ_CTX_set1_req); + +int +OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, const char *name, + const char *value) +{ + if (!name) + return 0; + if (BIO_puts(rctx->mem, name) <= 0) + return 0; + if (value) { + if (BIO_write(rctx->mem, ": ", 2) != 2) + return 0; + if (BIO_puts(rctx->mem, value) <= 0) + return 0; + } + if (BIO_write(rctx->mem, "\r\n", 2) != 2) + return 0; + return 1; +} +LCRYPTO_ALIAS(OCSP_REQ_CTX_add1_header); + +OCSP_REQ_CTX * +OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, int maxline) +{ + OCSP_REQ_CTX *rctx; + + rctx = malloc(sizeof(OCSP_REQ_CTX)); + if (rctx == NULL) + return NULL; + rctx->state = OHS_ERROR; + if ((rctx->mem = BIO_new(BIO_s_mem())) == NULL) { + free(rctx); + return NULL; + } + rctx->io = io; + rctx->asn1_len = 0; + if (maxline > 0) + rctx->iobuflen = maxline; + else + rctx->iobuflen = OCSP_MAX_LINE_LEN; + rctx->iobuf = malloc(rctx->iobuflen); + if (!rctx->iobuf) { + BIO_free(rctx->mem); + free(rctx); + return NULL; + } + if (!path) + path = "/"; + + if (BIO_printf(rctx->mem, "POST %s HTTP/1.0\r\n", path) <= 0) { + free(rctx->iobuf); + BIO_free(rctx->mem); + free(rctx); + return NULL; + } + + if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) { + free(rctx->iobuf); + BIO_free(rctx->mem); + free(rctx); + return NULL; + } + + return rctx; +} +LCRYPTO_ALIAS(OCSP_sendreq_new); + +/* Parse the HTTP response. This will look like this: + * "HTTP/1.0 200 OK". We need to obtain the numeric code and + * (optional) informational message. + */ +static int +parse_http_line1(char *line) +{ + int retcode; + char *p, *q, *r; + + /* Skip to first white space (passed protocol info) */ + for (p = line; *p && !isspace((unsigned char)*p); p++) + continue; + if (!*p) { + OCSPerror(OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Skip past white space to start of response code */ + while (*p && isspace((unsigned char)*p)) + p++; + if (!*p) { + OCSPerror(OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Find end of response code: first whitespace after start of code */ + for (q = p; *q && !isspace((unsigned char)*q); q++) + continue; + if (!*q) { + OCSPerror(OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Set end of response code and start of message */ + *q++ = 0; + + /* Attempt to parse numeric code */ + retcode = strtoul(p, &r, 10); + + if (*r) + return 0; + + /* Skip over any leading white space in message */ + while (*q && isspace((unsigned char)*q)) + q++; + if (*q) { + /* Finally zap any trailing white space in message (include + * CRLF) */ + + /* We know q has a non white space character so this is OK */ + for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) + *r = 0; + } + if (retcode != 200) { + OCSPerror(OCSP_R_SERVER_RESPONSE_ERROR); + if (!*q) + ERR_asprintf_error_data("Code=%s", p); + else + ERR_asprintf_error_data("Code=%s,Reason=%s", p, q); + return 0; + } + + return 1; +} + +int +OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) +{ + int i, n; + const unsigned char *p; + +next_io: + if (!(rctx->state & OHS_NOREAD)) { + n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + return 0; + } + + /* Write data to memory BIO */ + if (BIO_write(rctx->mem, rctx->iobuf, n) != n) + return 0; + } + + switch (rctx->state) { + case OHS_ASN1_WRITE: + n = BIO_get_mem_data(rctx->mem, &p); + i = BIO_write(rctx->io, + p + (n - rctx->asn1_len), rctx->asn1_len); + if (i <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len -= i; + if (rctx->asn1_len > 0) + goto next_io; + + rctx->state = OHS_ASN1_FLUSH; + + (void)BIO_reset(rctx->mem); + /* FALLTHROUGH */ + + case OHS_ASN1_FLUSH: + i = BIO_flush(rctx->io); + if (i > 0) { + rctx->state = OHS_FIRSTLINE; + goto next_io; + } + + if (BIO_should_retry(rctx->io)) + return -1; + + rctx->state = OHS_ERROR; + return 0; + + case OHS_ERROR: + return 0; + + case OHS_FIRSTLINE: + case OHS_HEADERS: + /* Attempt to read a line in */ +next_line: + /* Due to &%^*$" memory BIO behaviour with BIO_gets we + * have to check there's a complete line in there before + * calling BIO_gets or we'll just get a partial read. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if ((n <= 0) || !memchr(p, '\n', n)) { + if (n >= rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + goto next_io; + } + n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); + if (n <= 0) { + if (BIO_should_retry(rctx->mem)) + goto next_io; + rctx->state = OHS_ERROR; + return 0; + } + + /* Don't allow excessive lines */ + if (n == rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + + /* First line */ + if (rctx->state == OHS_FIRSTLINE) { + if (parse_http_line1((char *)rctx->iobuf)) { + rctx->state = OHS_HEADERS; + goto next_line; + } else { + rctx->state = OHS_ERROR; + return 0; + } + } else { + /* Look for blank line: end of headers */ + for (p = rctx->iobuf; *p; p++) { + if ((*p != '\r') && (*p != '\n')) + break; + } + if (*p) + goto next_line; + + rctx->state = OHS_ASN1_HEADER; + } + /* FALLTRHOUGH */ + + case OHS_ASN1_HEADER: + /* Now reading ASN1 header: can read at least 2 bytes which + * is enough for ASN1 SEQUENCE header and either length field + * or at least the length of the length field. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if (n < 2) + goto next_io; + + /* Check it is an ASN1 SEQUENCE */ + if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { + rctx->state = OHS_ERROR; + return 0; + } + + /* Check out length field */ + if (*p & 0x80) { + /* If MSB set on initial length octet we can now + * always read 6 octets: make sure we have them. + */ + if (n < 6) + goto next_io; + n = *p & 0x7F; + /* Not NDEF or excessive length */ + if (!n || (n > 4)) { + rctx->state = OHS_ERROR; + return 0; + } + p++; + rctx->asn1_len = 0; + for (i = 0; i < n; i++) { + rctx->asn1_len <<= 8; + rctx->asn1_len |= *p++; + } + + if (rctx->asn1_len > OCSP_MAX_REQUEST_LENGTH) { + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len += n + 2; + } else + rctx->asn1_len = *p + 2; + + rctx->state = OHS_ASN1_CONTENT; + + /* FALLTHROUGH */ + + case OHS_ASN1_CONTENT: + n = BIO_get_mem_data(rctx->mem, &p); + if (n < (int)rctx->asn1_len) + goto next_io; + + *presp = d2i_OCSP_RESPONSE(NULL, &p, rctx->asn1_len); + if (*presp) { + rctx->state = OHS_DONE; + return 1; + } + + rctx->state = OHS_ERROR; + return 0; + + case OHS_DONE: + return 1; + } + + return 0; +} +LCRYPTO_ALIAS(OCSP_sendreq_nbio); + +/* Blocking OCSP request handler: now a special case of non-blocking I/O */ +OCSP_RESPONSE * +OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) +{ + OCSP_RESPONSE *resp = NULL; + OCSP_REQ_CTX *ctx; + int rv; + + ctx = OCSP_sendreq_new(b, path, req, -1); + if (ctx == NULL) + return NULL; + + do { + rv = OCSP_sendreq_nbio(&resp, ctx); + } while ((rv == -1) && BIO_should_retry(b)); + + OCSP_REQ_CTX_free(ctx); + + if (rv) + return resp; + + return NULL; +} +LCRYPTO_ALIAS(OCSP_sendreq_bio); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_lib.c b/Libraries/libressl/crypto/ocsp/ocsp_lib.c new file mode 100644 index 000000000..d3eada2ba --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_lib.c @@ -0,0 +1,249 @@ +/* $OpenBSD: ocsp_lib.c,v 1.26 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was transfered to Richard Levitte from CertCo by Kathy + Weinhold in mid-spring 2000 to be included in OpenSSL or released + as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ocsp_local.h" + +/* Convert a certificate and its issuer to an OCSP_CERTID */ + +OCSP_CERTID * +OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, const X509 *issuer) +{ + X509_NAME *iname; + const ASN1_INTEGER *serial; + ASN1_BIT_STRING *ikey; + +#ifndef OPENSSL_NO_SHA1 + if (!dgst) + dgst = EVP_sha1(); +#endif + if (subject) { + iname = X509_get_issuer_name(subject); + serial = X509_get0_serialNumber(subject); + } else { + iname = X509_get_subject_name(issuer); + serial = NULL; + } + if ((ikey = X509_get0_pubkey_bitstr(issuer)) == NULL) + return NULL; + + return OCSP_cert_id_new(dgst, iname, ikey, serial); +} +LCRYPTO_ALIAS(OCSP_cert_to_id); + +OCSP_CERTID * +OCSP_cert_id_new(const EVP_MD *dgst, const X509_NAME *issuerName, + const ASN1_BIT_STRING *issuerKey, const ASN1_INTEGER *serialNumber) +{ + int nid; + unsigned int i; + X509_ALGOR *alg; + OCSP_CERTID *cid = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!(cid = OCSP_CERTID_new())) + goto err; + + alg = cid->hashAlgorithm; + if (alg->algorithm != NULL) + ASN1_OBJECT_free(alg->algorithm); + if ((nid = EVP_MD_type(dgst)) == NID_undef) { + OCSPerror(OCSP_R_UNKNOWN_NID); + goto err; + } + if (!(alg->algorithm = OBJ_nid2obj(nid))) + goto err; + if ((alg->parameter = ASN1_TYPE_new()) == NULL) + goto err; + alg->parameter->type = V_ASN1_NULL; + + if (!X509_NAME_digest(issuerName, dgst, md, &i)) + goto digerr; + if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) + goto err; + + /* Calculate the issuerKey hash, excluding tag and length */ + if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) + goto err; + + if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) + goto err; + + if (serialNumber) { + ASN1_INTEGER_free(cid->serialNumber); + if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) + goto err; + } + return cid; + +digerr: + OCSPerror(OCSP_R_DIGEST_ERR); +err: + if (cid) + OCSP_CERTID_free(cid); + return NULL; +} +LCRYPTO_ALIAS(OCSP_cert_id_new); + +int +OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) +{ + int ret; + + ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); + if (ret) + return ret; + ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); + if (ret) + return ret; + return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); +} +LCRYPTO_ALIAS(OCSP_id_issuer_cmp); + +int +OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) +{ + int ret; + + ret = OCSP_id_issuer_cmp(a, b); + if (ret) + return ret; + return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); +} +LCRYPTO_ALIAS(OCSP_id_cmp); + +/* Parse a URL and split it up into host, port and path components and whether + * it is SSL. + */ +int +OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl) +{ + char *host, *path, *port, *tmp; + + *phost = *pport = *ppath = NULL; + *pssl = 0; + + if (strncmp(url, "https://", 8) == 0) { + *pssl = 1; + host = strdup(url + 8); + } else if (strncmp(url, "http://", 7) == 0) + host = strdup(url + 7); + else { + OCSPerror(OCSP_R_ERROR_PARSING_URL); + return 0; + } + if (host == NULL) { + OCSPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + if ((tmp = strchr(host, '/')) != NULL) { + path = strdup(tmp); + *tmp = '\0'; + } else + path = strdup("/"); + + if ((tmp = strchr(host, ':')) != NULL ) { + port = strdup(tmp + 1); + *tmp = '\0'; + } else { + if (*pssl) + port = strdup("443"); + else + port = strdup("80"); + } + + if (path == NULL || port == NULL) { + free(host); + free(path); + free(port); + OCSPerror(ERR_R_MALLOC_FAILURE); + return 0; + } + + *phost = host; + *ppath = path; + *pport = port; + return 1; +} +LCRYPTO_ALIAS(OCSP_parse_url); + +OCSP_CERTID * +OCSP_CERTID_dup(OCSP_CERTID *x) +{ + return ASN1_item_dup(&OCSP_CERTID_it, x); +} +LCRYPTO_ALIAS(OCSP_CERTID_dup); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_local.h b/Libraries/libressl/crypto/ocsp/ocsp_local.h new file mode 100644 index 000000000..bd933b191 --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_local.h @@ -0,0 +1,291 @@ +/* $OpenBSD: ocsp_local.h,v 1.2 2022/01/14 08:32:26 tb Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was transfered to Richard Levitte from CertCo by Kathy + Weinhold in mid-spring 2000 to be included in OpenSSL or released + as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OCSP_LOCAL_H +#define HEADER_OCSP_LOCAL_H + +__BEGIN_HIDDEN_DECLS + +/* CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of Issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) + * serialNumber CertificateSerialNumber } + */ +struct ocsp_cert_id_st { + X509_ALGOR *hashAlgorithm; + ASN1_OCTET_STRING *issuerNameHash; + ASN1_OCTET_STRING *issuerKeyHash; + ASN1_INTEGER *serialNumber; +} /* OCSP_CERTID */; + +/* Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + */ +struct ocsp_one_request_st { + OCSP_CERTID *reqCert; + STACK_OF(X509_EXTENSION) *singleRequestExtensions; +} /* OCSP_ONEREQ */; + +/* TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + */ +struct ocsp_req_info_st { + ASN1_INTEGER *version; + GENERAL_NAME *requestorName; + STACK_OF(OCSP_ONEREQ) *requestList; + STACK_OF(X509_EXTENSION) *requestExtensions; +} /* OCSP_REQINFO */; + +/* Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ +struct ocsp_signature_st { + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} /* OCSP_SIGNATURE */; + +/* OCSPRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + */ +struct ocsp_request_st { + OCSP_REQINFO *tbsRequest; + OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ +} /* OCSP_REQUEST */; + +/* OCSPResponseStatus ::= ENUMERATED { + * successful (0), --Response has valid confirmations + * malformedRequest (1), --Illegal confirmation request + * internalError (2), --Internal error in issuer + * tryLater (3), --Try again later + * --(4) is not used + * sigRequired (5), --Must sign the request + * unauthorized (6) --Request unauthorized + * } + */ + +/* ResponseBytes ::= SEQUENCE { + * responseType OBJECT IDENTIFIER, + * response OCTET STRING } + */ +struct ocsp_resp_bytes_st { + ASN1_OBJECT *responseType; + ASN1_OCTET_STRING *response; +} /* OCSP_RESPBYTES */; + +/* OCSPResponse ::= SEQUENCE { + * responseStatus OCSPResponseStatus, + * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } + */ +struct ocsp_response_st { + ASN1_ENUMERATED *responseStatus; + OCSP_RESPBYTES *responseBytes; +}; + +/* ResponderID ::= CHOICE { + * byName [1] Name, + * byKey [2] KeyHash } + */ +struct ocsp_responder_id_st { + int type; + union { + X509_NAME* byName; + ASN1_OCTET_STRING *byKey; + } value; +}; + +/* KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key + * --(excluding the tag and length fields) + */ + +/* RevokedInfo ::= SEQUENCE { + * revocationTime GeneralizedTime, + * revocationReason [0] EXPLICIT CRLReason OPTIONAL } + */ +struct ocsp_revoked_info_st { + ASN1_GENERALIZEDTIME *revocationTime; + ASN1_ENUMERATED *revocationReason; +} /* OCSP_REVOKEDINFO */; + +/* CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + */ +struct ocsp_cert_status_st { + int type; + union { + ASN1_NULL *good; + OCSP_REVOKEDINFO *revoked; + ASN1_NULL *unknown; + } value; +} /* OCSP_CERTSTATUS */; + +/* SingleResponse ::= SEQUENCE { + * certID CertID, + * certStatus CertStatus, + * thisUpdate GeneralizedTime, + * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, + * singleExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +struct ocsp_single_response_st { + OCSP_CERTID *certId; + OCSP_CERTSTATUS *certStatus; + ASN1_GENERALIZEDTIME *thisUpdate; + ASN1_GENERALIZEDTIME *nextUpdate; + STACK_OF(X509_EXTENSION) *singleExtensions; +} /* OCSP_SINGLERESP */; + +/* ResponseData ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * responderID ResponderID, + * producedAt GeneralizedTime, + * responses SEQUENCE OF SingleResponse, + * responseExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +struct ocsp_response_data_st { + ASN1_INTEGER *version; + OCSP_RESPID *responderId; + ASN1_GENERALIZEDTIME *producedAt; + STACK_OF(OCSP_SINGLERESP) *responses; + STACK_OF(X509_EXTENSION) *responseExtensions; +} /* OCSP_RESPDATA */; + +/* BasicOCSPResponse ::= SEQUENCE { + * tbsResponseData ResponseData, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ + /* Note 1: + The value for "signature" is specified in the OCSP rfc2560 as follows: + "The value for the signature SHALL be computed on the hash of the DER + encoding ResponseData." This means that you must hash the DER-encoded + tbsResponseData, and then run it through a crypto-signing function, which + will (at least w/RSA) do a hash-'n'-private-encrypt operation. This seems + a bit odd, but that's the spec. Also note that the data structures do not + leave anywhere to independently specify the algorithm used for the initial + hash. So, we look at the signature-specification algorithm, and try to do + something intelligent. -- Kathy Weinhold, CertCo */ + /* Note 2: + It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open + for interpretation. I've done tests against another responder, and found + that it doesn't do the double hashing that the RFC seems to say one + should. Therefore, all relevant functions take a flag saying which + variant should be used. -- Richard Levitte, OpenSSL team and CeloCom */ +struct ocsp_basic_response_st { + OCSP_RESPDATA *tbsResponseData; + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} /* OCSP_BASICRESP */; + +/* CrlID ::= SEQUENCE { + * crlUrl [0] EXPLICIT IA5String OPTIONAL, + * crlNum [1] EXPLICIT INTEGER OPTIONAL, + * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } + */ +struct ocsp_crl_id_st { + ASN1_IA5STRING *crlUrl; + ASN1_INTEGER *crlNum; + ASN1_GENERALIZEDTIME *crlTime; +} /* OCSP_CRLID */; + +/* ServiceLocator ::= SEQUENCE { + * issuer Name, + * locator AuthorityInfoAccessSyntax OPTIONAL } + */ +struct ocsp_service_locator_st { + X509_NAME* issuer; + STACK_OF(ACCESS_DESCRIPTION) *locator; +} /* OCSP_SERVICELOC */; + +#define OCSP_REQUEST_sign(o,pkey,md) \ + ASN1_item_sign(&OCSP_REQINFO_it, \ + (o)->optionalSignature->signatureAlgorithm, NULL, \ + (o)->optionalSignature->signature,o->tbsRequest, (pkey), (md)) + +#define OCSP_BASICRESP_sign(o,pkey,md,d) \ + ASN1_item_sign(&OCSP_RESPDATA_it,o->signatureAlgorithm,NULL, \ + (o)->signature,(o)->tbsResponseData,(pkey),(md)) + +#define OCSP_REQUEST_verify(a,r) \ + ASN1_item_verify(&OCSP_REQINFO_it, \ + (a)->optionalSignature->signatureAlgorithm, \ + (a)->optionalSignature->signature, (a)->tbsRequest, (r)) + +#define OCSP_BASICRESP_verify(a,r,d) \ + ASN1_item_verify(&OCSP_RESPDATA_it, \ + (a)->signatureAlgorithm, (a)->signature, (a)->tbsResponseData, (r)) + +__END_HIDDEN_DECLS + +#endif /* !HEADER_OCSP_LOCAL_H */ diff --git a/Libraries/libressl/crypto/ocsp/ocsp_prn.c b/Libraries/libressl/crypto/ocsp/ocsp_prn.c new file mode 100644 index 000000000..7e3175b61 --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_prn.c @@ -0,0 +1,319 @@ +/* $OpenBSD: ocsp_prn.c,v 1.10 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was originally part of ocsp.c and was transfered to Richard + Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included + in OpenSSL or released as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include "ocsp_local.h" + +static int +ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent) +{ + BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); + indent += 2; + BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); + i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); + BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); + i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); + BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); + i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); + BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); + i2a_ASN1_INTEGER(bp, a->serialNumber); + BIO_printf(bp, "\n"); + return 1; +} + +typedef struct { + long t; + const char *m; +} OCSP_TBLSTR; + +static const char * +table2string(long s, const OCSP_TBLSTR *ts, int len) +{ + const OCSP_TBLSTR *p; + + for (p = ts; p < ts + len; p++) + if (p->t == s) + return p->m; + return "(UNKNOWN)"; +} + +const char * +OCSP_response_status_str(long s) +{ + static const OCSP_TBLSTR rstat_tbl[] = { + { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" }, + { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" }, + { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" }, + { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" }, + { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" }, + { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } + }; + return table2string(s, rstat_tbl, 6); +} +LCRYPTO_ALIAS(OCSP_response_status_str); + +const char * +OCSP_cert_status_str(long s) +{ + static const OCSP_TBLSTR cstat_tbl[] = { + { V_OCSP_CERTSTATUS_GOOD, "good" }, + { V_OCSP_CERTSTATUS_REVOKED, "revoked" }, + { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } + }; + return table2string(s, cstat_tbl, 3); +} +LCRYPTO_ALIAS(OCSP_cert_status_str); + +const char * +OCSP_crl_reason_str(long s) +{ + static const OCSP_TBLSTR reason_tbl[] = { + { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" }, + { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" }, + { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" }, + { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" }, + { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" }, + { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" }, + { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" }, + { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } + }; + return table2string(s, reason_tbl, 8); +} +LCRYPTO_ALIAS(OCSP_crl_reason_str); + +int +OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags) +{ + int i; + long l; + OCSP_CERTID* cid = NULL; + OCSP_ONEREQ *one = NULL; + OCSP_REQINFO *inf = o->tbsRequest; + OCSP_SIGNATURE *sig = o->optionalSignature; + + if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) + goto err; + l = ASN1_INTEGER_get(inf->version); + if (BIO_printf(bp, " Version: %lu (0x%lx)", l+1, l) <= 0) + goto err; + if (inf->requestorName != NULL) { + if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) + goto err; + GENERAL_NAME_print(bp, inf->requestorName); + } + if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) + goto err; + for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { + one = sk_OCSP_ONEREQ_value(inf->requestList, i); + cid = one->reqCert; + ocsp_certid_print(bp, cid, 8); + if (!X509V3_extensions_print(bp, "Request Single Extensions", + one->singleRequestExtensions, flags, 8)) + goto err; + } + if (!X509V3_extensions_print(bp, "Request Extensions", + inf->requestExtensions, flags, 4)) + goto err; + if (sig) { + if (X509_signature_print(bp, sig->signatureAlgorithm, + sig->signature) == 0) + goto err; + for (i = 0; i < sk_X509_num(sig->certs); i++) { + if (X509_print(bp, sk_X509_value(sig->certs, i)) == 0) + goto err; + if (PEM_write_bio_X509(bp, + sk_X509_value(sig->certs, i)) == 0) + goto err; + } + } + return 1; + +err: + return 0; +} +LCRYPTO_ALIAS(OCSP_REQUEST_print); + +int +OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags) +{ + int i, ret = 0; + long l; + OCSP_CERTID *cid = NULL; + OCSP_BASICRESP *br = NULL; + OCSP_RESPID *rid = NULL; + OCSP_RESPDATA *rd = NULL; + OCSP_CERTSTATUS *cst = NULL; + OCSP_REVOKEDINFO *rev = NULL; + OCSP_SINGLERESP *single = NULL; + OCSP_RESPBYTES *rb = o->responseBytes; + + if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) + goto err; + l = ASN1_ENUMERATED_get(o->responseStatus); + if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", + OCSP_response_status_str(l), l) <= 0) + goto err; + if (rb == NULL) + return 1; + if (BIO_puts(bp, " Response Type: ") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) + goto err; + if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { + BIO_puts(bp, " (unknown response type)\n"); + return 1; + } + + i = ASN1_STRING_length(rb->response); + if (!(br = OCSP_response_get1_basic(o))) + goto err; + rd = br->tbsResponseData; + l = ASN1_INTEGER_get(rd->version); + if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l+1, l) <= 0) + goto err; + if (BIO_puts(bp, " Responder Id: ") <= 0) + goto err; + + rid = rd->responderId; + switch (rid->type) { + case V_OCSP_RESPID_NAME: + X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); + break; + case V_OCSP_RESPID_KEY: + i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); + break; + } + + if (BIO_printf(bp, "\n Produced At: ")<=0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) + goto err; + if (BIO_printf(bp, "\n Responses:\n") <= 0) + goto err; + for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { + if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) + continue; + single = sk_OCSP_SINGLERESP_value(rd->responses, i); + cid = single->certId; + if (ocsp_certid_print(bp, cid, 4) <= 0) + goto err; + cst = single->certStatus; + if (BIO_printf(bp, " Cert Status: %s", + OCSP_cert_status_str(cst->type)) <= 0) + goto err; + if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { + rev = cst->value.revoked; + if (BIO_printf(bp, "\n Revocation Time: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, + rev->revocationTime)) + goto err; + if (rev->revocationReason) { + l = ASN1_ENUMERATED_get(rev->revocationReason); + if (BIO_printf(bp, + "\n Revocation Reason: %s (0x%lx)", + OCSP_crl_reason_str(l), l) <= 0) + goto err; + } + } + if (BIO_printf(bp, "\n This Update: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) + goto err; + if (single->nextUpdate) { + if (BIO_printf(bp, "\n Next Update: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + if (!X509V3_extensions_print(bp, "Response Single Extensions", + single->singleExtensions, flags, 8)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!X509V3_extensions_print(bp, "Response Extensions", + rd->responseExtensions, flags, 4)) + goto err; + if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= + 0) + goto err; + + for (i = 0; i < sk_X509_num(br->certs); i++) { + X509_print(bp, sk_X509_value(br->certs, i)); + PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); + } + + ret = 1; + +err: + OCSP_BASICRESP_free(br); + return ret; +} +LCRYPTO_ALIAS(OCSP_RESPONSE_print); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_srv.c b/Libraries/libressl/crypto/ocsp/ocsp_srv.c new file mode 100644 index 000000000..77c5e2e0f --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_srv.c @@ -0,0 +1,285 @@ +/* $OpenBSD: ocsp_srv.c,v 1.13 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "ocsp_local.h" + +/* Utility functions related to sending OCSP responses and extracting + * relevant information from the request. + */ + +int +OCSP_request_onereq_count(OCSP_REQUEST *req) +{ + return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList); +} +LCRYPTO_ALIAS(OCSP_request_onereq_count); + +OCSP_ONEREQ * +OCSP_request_onereq_get0(OCSP_REQUEST *req, int i) +{ + return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i); +} +LCRYPTO_ALIAS(OCSP_request_onereq_get0); + +OCSP_CERTID * +OCSP_onereq_get0_id(OCSP_ONEREQ *one) +{ + return one->reqCert; +} +LCRYPTO_ALIAS(OCSP_onereq_get0_id); + +int +OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, ASN1_INTEGER **pserial, OCSP_CERTID *cid) +{ + if (!cid) + return 0; + if (pmd) + *pmd = cid->hashAlgorithm->algorithm; + if (piNameHash) + *piNameHash = cid->issuerNameHash; + if (pikeyHash) + *pikeyHash = cid->issuerKeyHash; + if (pserial) + *pserial = cid->serialNumber; + return 1; +} +LCRYPTO_ALIAS(OCSP_id_get0_info); + +int +OCSP_request_is_signed(OCSP_REQUEST *req) +{ + if (req->optionalSignature) + return 1; + return 0; +} +LCRYPTO_ALIAS(OCSP_request_is_signed); + +/* Create an OCSP response and encode an optional basic response */ +OCSP_RESPONSE * +OCSP_response_create(int status, OCSP_BASICRESP *bs) +{ + OCSP_RESPONSE *rsp = NULL; + + if (!(rsp = OCSP_RESPONSE_new())) + goto err; + if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) + goto err; + if (!bs) + return rsp; + if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) + goto err; + rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); + if (!ASN1_item_pack(bs, &OCSP_BASICRESP_it, + &rsp->responseBytes->response)) + goto err; + return rsp; + +err: + if (rsp) + OCSP_RESPONSE_free(rsp); + return NULL; +} +LCRYPTO_ALIAS(OCSP_response_create); + +OCSP_SINGLERESP * +OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid, int status, + int reason, ASN1_TIME *revtime, ASN1_TIME *thisupd, ASN1_TIME *nextupd) +{ + OCSP_SINGLERESP *single = NULL; + OCSP_CERTSTATUS *cs; + OCSP_REVOKEDINFO *ri; + + if (!rsp->tbsResponseData->responses && + !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null())) + goto err; + + if (!(single = OCSP_SINGLERESP_new())) + goto err; + + if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate)) + goto err; + if (nextupd && + !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate)) + goto err; + + OCSP_CERTID_free(single->certId); + + if (!(single->certId = OCSP_CERTID_dup(cid))) + goto err; + + cs = single->certStatus; + switch (cs->type = status) { + case V_OCSP_CERTSTATUS_REVOKED: + if (!revtime) { + OCSPerror(OCSP_R_NO_REVOKED_TIME); + goto err; + } + if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) + goto err; + if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime)) + goto err; + if (reason != OCSP_REVOKED_STATUS_NOSTATUS) { + if (!(ri->revocationReason = ASN1_ENUMERATED_new())) + goto err; + if (!(ASN1_ENUMERATED_set(ri->revocationReason, + reason))) + goto err; + } + break; + + case V_OCSP_CERTSTATUS_GOOD: + cs->value.good = ASN1_NULL_new(); + break; + + case V_OCSP_CERTSTATUS_UNKNOWN: + cs->value.unknown = ASN1_NULL_new(); + break; + + default: + goto err; + } + if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single))) + goto err; + return single; + +err: + OCSP_SINGLERESP_free(single); + return NULL; +} +LCRYPTO_ALIAS(OCSP_basic_add1_status); + +/* Add a certificate to an OCSP request */ +int +OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) +{ + if (!resp->certs && !(resp->certs = sk_X509_new_null())) + return 0; + + if (!sk_X509_push(resp->certs, cert)) + return 0; + X509_up_ref(cert); + return 1; +} +LCRYPTO_ALIAS(OCSP_basic_add1_cert); + +int +OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, + const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags) +{ + int i; + OCSP_RESPID *rid; + + if (!X509_check_private_key(signer, key)) { + OCSPerror(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + if (!(flags & OCSP_NOCERTS)) { + if (!OCSP_basic_add1_cert(brsp, signer)) + goto err; + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *tmpcert = sk_X509_value(certs, i); + if (!OCSP_basic_add1_cert(brsp, tmpcert)) + goto err; + } + } + + rid = brsp->tbsResponseData->responderId; + if (flags & OCSP_RESPID_KEY) { + unsigned char md[SHA_DIGEST_LENGTH]; + + X509_pubkey_digest(signer, EVP_sha1(), md, NULL); + if (!(rid->value.byKey = ASN1_OCTET_STRING_new())) + goto err; + if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, + SHA_DIGEST_LENGTH))) + goto err; + rid->type = V_OCSP_RESPID_KEY; + } else { + if (!X509_NAME_set(&rid->value.byName, + X509_get_subject_name(signer))) + goto err; + rid->type = V_OCSP_RESPID_NAME; + } + + if (!(flags & OCSP_NOTIME) && + !ASN1_GENERALIZEDTIME_set(brsp->tbsResponseData->producedAt, time(NULL))) + goto err; + + /* Right now, I think that not doing double hashing is the right + thing. -- Richard Levitte */ + + if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) + goto err; + + return 1; + +err: + return 0; +} +LCRYPTO_ALIAS(OCSP_basic_sign); diff --git a/Libraries/libressl/crypto/ocsp/ocsp_vfy.c b/Libraries/libressl/crypto/ocsp/ocsp_vfy.c new file mode 100644 index 000000000..d197fe4ea --- /dev/null +++ b/Libraries/libressl/crypto/ocsp/ocsp_vfy.c @@ -0,0 +1,475 @@ +/* $OpenBSD: ocsp_vfy.c,v 1.23 2023/07/08 10:44:00 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include "ocsp_local.h" +#include "x509_local.h" + +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, + STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags); +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, + unsigned long flags); +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret); +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, + STACK_OF(OCSP_SINGLERESP) *sresp); +static int ocsp_check_delegated(X509 *x, int flags); +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, + X509_NAME *nm, STACK_OF(X509) *certs, X509_STORE *st, + unsigned long flags); + +/* Verify a basic response message */ +int +OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, + unsigned long flags) +{ + X509 *signer, *x; + STACK_OF(X509) *chain = NULL; + STACK_OF(X509) *untrusted = NULL; + X509_STORE_CTX ctx; + int i, ret = 0; + + ret = ocsp_find_signer(&signer, bs, certs, st, flags); + if (!ret) { + OCSPerror(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + goto end; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) { + EVP_PKEY *skey; + + skey = X509_get0_pubkey(signer); + if (skey) { + ret = OCSP_BASICRESP_verify(bs, skey, 0); + } + if (!skey || ret <= 0) { + OCSPerror(OCSP_R_SIGNATURE_FAILURE); + goto end; + } + } + if (!(flags & OCSP_NOVERIFY)) { + int init_res; + + if (flags & OCSP_NOCHAIN) { + untrusted = NULL; + } else if (bs->certs && certs) { + untrusted = sk_X509_dup(bs->certs); + for (i = 0; i < sk_X509_num(certs); i++) { + if (!sk_X509_push(untrusted, + sk_X509_value(certs, i))) { + OCSPerror(ERR_R_MALLOC_FAILURE); + goto end; + } + } + } else if (certs != NULL) { + untrusted = certs; + } else { + untrusted = bs->certs; + } + init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); + if (!init_res) { + ret = -1; + OCSPerror(ERR_R_X509_LIB); + goto end; + } + + if (X509_STORE_CTX_set_purpose(&ctx, + X509_PURPOSE_OCSP_HELPER) == 0) { + X509_STORE_CTX_cleanup(&ctx); + ret = -1; + goto end; + } + ret = X509_verify_cert(&ctx); + chain = X509_STORE_CTX_get1_chain(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) { + i = X509_STORE_CTX_get_error(&ctx); + OCSPerror(OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_asprintf_error_data("Verify error:%s", + X509_verify_cert_error_string(i)); + goto end; + } + if (flags & OCSP_NOCHECKS) { + ret = 1; + goto end; + } + /* At this point we have a valid certificate chain + * need to verify it against the OCSP issuer criteria. + */ + ret = ocsp_check_issuer(bs, chain, flags); + + /* If fatal error or valid match then finish */ + if (ret != 0) + goto end; + + /* Easy case: explicitly trusted. Get root CA and + * check for explicit trust + */ + if (flags & OCSP_NOEXPLICIT) + goto end; + + x = sk_X509_value(chain, sk_X509_num(chain) - 1); + if (X509_check_trust(x, NID_OCSP_sign, 0) != + X509_TRUST_TRUSTED) { + OCSPerror(OCSP_R_ROOT_CA_NOT_TRUSTED); + goto end; + } + ret = 1; + } + +end: + if (chain) + sk_X509_pop_free(chain, X509_free); + if (bs->certs && certs) + sk_X509_free(untrusted); + return ret; +} +LCRYPTO_ALIAS(OCSP_basic_verify); + +int +OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, + STACK_OF(X509) *extra_certs) +{ + return ocsp_find_signer(signer, bs, extra_certs, NULL, 0) > 0; +} +LCRYPTO_ALIAS(OCSP_resp_get0_signer); + +static int +ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags) +{ + X509 *signer; + OCSP_RESPID *rid = bs->tbsResponseData->responderId; + + if ((signer = ocsp_find_signer_sk(certs, rid))) { + *psigner = signer; + return 2; + } + if (!(flags & OCSP_NOINTERN) && + (signer = ocsp_find_signer_sk(bs->certs, rid))) { + *psigner = signer; + return 1; + } + /* Maybe lookup from store if by subject name */ + + *psigner = NULL; + return 0; +} + +static X509 * +ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) +{ + int i; + unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; + X509 *x; + + /* Easy if lookup by name */ + if (id->type == V_OCSP_RESPID_NAME) + return X509_find_by_subject(certs, id->value.byName); + + /* Lookup by key hash */ + + /* If key hash isn't SHA1 length then forget it */ + if (id->value.byKey->length != SHA_DIGEST_LENGTH) + return NULL; + keyhash = id->value.byKey->data; + /* Calculate hash of each key and compare */ + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); + if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) + return x; + } + return NULL; +} + +static int +ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, + unsigned long flags) +{ + STACK_OF(OCSP_SINGLERESP) *sresp; + X509 *signer, *sca; + OCSP_CERTID *caid = NULL; + int i; + + sresp = bs->tbsResponseData->responses; + + if (sk_X509_num(chain) <= 0) { + OCSPerror(OCSP_R_NO_CERTIFICATES_IN_CHAIN); + return -1; + } + + /* See if the issuer IDs match. */ + i = ocsp_check_ids(sresp, &caid); + + /* If ID mismatch or other error then return */ + if (i <= 0) + return i; + + signer = sk_X509_value(chain, 0); + /* Check to see if OCSP responder CA matches request CA */ + if (sk_X509_num(chain) > 1) { + sca = sk_X509_value(chain, 1); + i = ocsp_match_issuerid(sca, caid, sresp); + if (i < 0) + return i; + if (i) { + /* We have a match, if extensions OK then success */ + if (ocsp_check_delegated(signer, flags)) + return 1; + return 0; + } + } + + /* Otherwise check if OCSP request signed directly by request CA */ + return ocsp_match_issuerid(signer, caid, sresp); +} + +/* Check the issuer certificate IDs for equality. If there is a mismatch with the same + * algorithm then there's no point trying to match any certificates against the issuer. + * If the issuer IDs all match then we just need to check equality against one of them. + */ +static int +ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) +{ + OCSP_CERTID *tmpid, *cid; + int i, idcount; + + idcount = sk_OCSP_SINGLERESP_num(sresp); + if (idcount <= 0) { + OCSPerror(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); + return -1; + } + + cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; + + *ret = NULL; + + for (i = 1; i < idcount; i++) { + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; + /* Check to see if IDs match */ + if (OCSP_id_issuer_cmp(cid, tmpid)) { + return 0; + } + } + + /* All IDs match: only need to check one ID */ + *ret = cid; + return 1; +} + +static int +ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, + STACK_OF(OCSP_SINGLERESP) *sresp) +{ + /* If only one ID to match then do it */ + if (cid) { + const EVP_MD *dgst; + X509_NAME *iname; + int mdlen; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!(dgst = + EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) { + OCSPerror(OCSP_R_UNKNOWN_MESSAGE_DIGEST); + return -1; + } + + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; + if (cid->issuerNameHash->length != mdlen || + cid->issuerKeyHash->length != mdlen) + return 0; + iname = X509_get_subject_name(cert); + if (!X509_NAME_digest(iname, dgst, md, NULL)) + return -1; + if (memcmp(md, cid->issuerNameHash->data, mdlen)) + return 0; + X509_pubkey_digest(cert, dgst, md, NULL); + if (memcmp(md, cid->issuerKeyHash->data, mdlen)) + return 0; + + return 1; + } else { + /* We have to match the whole lot */ + int i, ret; + OCSP_CERTID *tmpid; + + for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; + ret = ocsp_match_issuerid(cert, tmpid, NULL); + if (ret <= 0) + return ret; + } + return 1; + } +} + +static int +ocsp_check_delegated(X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN)) + return 1; + OCSPerror(OCSP_R_MISSING_OCSPSIGNING_USAGE); + return 0; +} + +/* Verify an OCSP request. This is fortunately much easier than OCSP + * response verify. Just find the signers certificate and verify it + * against a given trust value. + */ +int +OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, + unsigned long flags) +{ + X509 *signer; + X509_NAME *nm; + GENERAL_NAME *gen; + int ret; + X509_STORE_CTX ctx; + + if (!req->optionalSignature) { + OCSPerror(OCSP_R_REQUEST_NOT_SIGNED); + return 0; + } + gen = req->tbsRequest->requestorName; + if (!gen || gen->type != GEN_DIRNAME) { + OCSPerror(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); + return 0; + } + nm = gen->d.directoryName; + ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); + if (ret <= 0) { + OCSPerror(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + return 0; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) { + EVP_PKEY *skey; + + if ((skey = X509_get0_pubkey(signer)) == NULL) + return 0; + ret = OCSP_REQUEST_verify(req, skey); + if (ret <= 0) { + OCSPerror(OCSP_R_SIGNATURE_FAILURE); + return 0; + } + } + if (!(flags & OCSP_NOVERIFY)) { + int init_res; + + if (flags & OCSP_NOCHAIN) + init_res = X509_STORE_CTX_init(&ctx, store, signer, + NULL); + else + init_res = X509_STORE_CTX_init(&ctx, store, signer, + req->optionalSignature->certs); + if (!init_res) { + OCSPerror(ERR_R_X509_LIB); + return 0; + } + + if (X509_STORE_CTX_set_purpose(&ctx, + X509_PURPOSE_OCSP_HELPER) == 0 || + X509_STORE_CTX_set_trust(&ctx, + X509_TRUST_OCSP_REQUEST) == 0) { + X509_STORE_CTX_cleanup(&ctx); + return 0; + } + ret = X509_verify_cert(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) { + ret = X509_STORE_CTX_get_error(&ctx); + OCSPerror(OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_asprintf_error_data("Verify error:%s", + X509_verify_cert_error_string(ret)); + return 0; + } + } + return 1; +} +LCRYPTO_ALIAS(OCSP_request_verify); + +static int +ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, + STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags) +{ + X509 *signer; + + if (!(flags & OCSP_NOINTERN)) { + signer = X509_find_by_subject(req->optionalSignature->certs, nm); + if (signer) { + *psigner = signer; + return 1; + } + } + + signer = X509_find_by_subject(certs, nm); + if (signer) { + *psigner = signer; + return 2; + } + return 0; +} diff --git a/Libraries/libressl/crypto/pem/pem_all.c b/Libraries/libressl/crypto/pem/pem_all.c new file mode 100644 index 000000000..21e325b9f --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_all.c @@ -0,0 +1,704 @@ +/* $OpenBSD: pem_all.c,v 1.21 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif + +#ifndef OPENSSL_NO_RSA +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); +#endif +#ifndef OPENSSL_NO_DSA +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); +#endif + +#ifndef OPENSSL_NO_EC +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); +#endif + + +X509_REQ * +PEM_read_X509_REQ(FILE *fp, X509_REQ **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_X509_REQ, PEM_STRING_X509_REQ, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_X509_REQ); + +int +PEM_write_X509_REQ(FILE *fp, X509_REQ *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_X509_REQ); + +X509_REQ * +PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_REQ, PEM_STRING_X509_REQ, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_X509_REQ); + +int +PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_X509_REQ); + +int +PEM_write_X509_REQ_NEW(FILE *fp, X509_REQ *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ_OLD, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_X509_REQ_NEW); + +int +PEM_write_bio_X509_REQ_NEW(BIO *bp, X509_REQ *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ_OLD, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_X509_REQ_NEW); + +X509_CRL * +PEM_read_X509_CRL(FILE *fp, X509_CRL **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_X509_CRL, PEM_STRING_X509_CRL, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_X509_CRL); + +int +PEM_write_X509_CRL(FILE *fp, X509_CRL *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_X509_CRL, PEM_STRING_X509_CRL, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_X509_CRL); + +X509_CRL * +PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_CRL, PEM_STRING_X509_CRL, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_X509_CRL); + +int +PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_CRL, PEM_STRING_X509_CRL, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_X509_CRL); + +PKCS7 * +PEM_read_PKCS7(FILE *fp, PKCS7 **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_PKCS7, PEM_STRING_PKCS7, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_PKCS7); + +int +PEM_write_PKCS7(FILE *fp, PKCS7 *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_PKCS7, PEM_STRING_PKCS7, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_PKCS7); + +PKCS7 * +PEM_read_bio_PKCS7(BIO *bp, PKCS7 **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_PKCS7, PEM_STRING_PKCS7, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_PKCS7); + +int +PEM_write_bio_PKCS7(BIO *bp, PKCS7 *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PKCS7, PEM_STRING_PKCS7, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_PKCS7); + +#ifndef OPENSSL_NO_RSA + +/* We treat RSA or DSA private keys as a special case. + * + * For private keys we read in an EVP_PKEY structure with + * PEM_read_bio_PrivateKey() and extract the relevant private + * key: this means can handle "traditional" and PKCS#8 formats + * transparently. + */ + +static RSA * +pkey_get_rsa(EVP_PKEY *key, RSA **rsa) +{ + RSA *rtmp; + + if (!key) + return NULL; + rtmp = EVP_PKEY_get1_RSA(key); + EVP_PKEY_free(key); + if (!rtmp) + return NULL; + if (rsa) { + RSA_free(*rsa); + *rsa = rtmp; + } + return rtmp; +} + +RSA * +PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} +LCRYPTO_ALIAS(PEM_read_RSAPrivateKey); + +int +PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey, PEM_STRING_RSA, fp, + x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_RSAPrivateKey); + +RSA * +PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} +LCRYPTO_ALIAS(PEM_read_bio_RSAPrivateKey); + +int +PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey, PEM_STRING_RSA, bp, + x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_bio_RSAPrivateKey); + +RSA * +PEM_read_RSAPublicKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_RSAPublicKey, PEM_STRING_RSA_PUBLIC, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_RSAPublicKey); + +int +PEM_write_RSAPublicKey(FILE *fp, const RSA *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_RSAPublicKey, PEM_STRING_RSA_PUBLIC, fp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_RSAPublicKey); + +RSA * +PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_RSAPublicKey, PEM_STRING_RSA_PUBLIC, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_RSAPublicKey); + +int +PEM_write_bio_RSAPublicKey(BIO *bp, const RSA *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPublicKey, PEM_STRING_RSA_PUBLIC, bp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_RSAPublicKey); + +RSA * +PEM_read_RSA_PUBKEY(FILE *fp, RSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_RSA_PUBKEY, PEM_STRING_PUBLIC, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_RSA_PUBKEY); + +int +PEM_write_RSA_PUBKEY(FILE *fp, RSA *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_RSA_PUBKEY, PEM_STRING_PUBLIC, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_RSA_PUBKEY); + +RSA * +PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_RSA_PUBKEY, PEM_STRING_PUBLIC, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_RSA_PUBKEY); + +int +PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSA_PUBKEY, PEM_STRING_PUBLIC, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_RSA_PUBKEY); + +#endif + +#ifndef OPENSSL_NO_DSA + +static DSA * +pkey_get_dsa(EVP_PKEY *key, DSA **dsa) +{ + DSA *dtmp; + + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_DSA(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (dsa) { + DSA_free(*dsa); + *dsa = dtmp; + } + return dtmp; +} + +DSA * +PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} +LCRYPTO_ALIAS(PEM_read_DSAPrivateKey); + +int +PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey, PEM_STRING_DSA, fp, + x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_DSAPrivateKey); + +DSA * +PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} +LCRYPTO_ALIAS(PEM_read_bio_DSAPrivateKey); + +int +PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey, PEM_STRING_DSA, bp, + x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_bio_DSAPrivateKey); + +DSA * +PEM_read_DSA_PUBKEY(FILE *fp, DSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_DSA_PUBKEY, PEM_STRING_PUBLIC, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_DSA_PUBKEY); + +int +PEM_write_DSA_PUBKEY(FILE *fp, DSA *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_DSA_PUBKEY, PEM_STRING_PUBLIC, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_DSA_PUBKEY); + +int +PEM_write_bio_DSA_PUBKEY(BIO *bp, DSA *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSA_PUBKEY, PEM_STRING_PUBLIC, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_DSA_PUBKEY); + +DSA * +PEM_read_bio_DSA_PUBKEY(BIO *bp, DSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_DSA_PUBKEY, PEM_STRING_PUBLIC, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_DSA_PUBKEY); + +DSA * +PEM_read_DSAparams(FILE *fp, DSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_DSAparams, PEM_STRING_DSAPARAMS, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_DSAparams); + +int +PEM_write_DSAparams(FILE *fp, const DSA *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_DSAparams, PEM_STRING_DSAPARAMS, fp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_DSAparams); + +DSA * +PEM_read_bio_DSAparams(BIO *bp, DSA **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAparams, PEM_STRING_DSAPARAMS, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_DSAparams); + +int +PEM_write_bio_DSAparams(BIO *bp, const DSA *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAparams, PEM_STRING_DSAPARAMS, bp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_DSAparams); + +#endif + + +#ifndef OPENSSL_NO_EC +static EC_KEY * +pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) +{ + EC_KEY *dtmp; + + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_EC_KEY(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (eckey) { + EC_KEY_free(*eckey); + *eckey = dtmp; + } + return dtmp; +} + +EC_GROUP * +PEM_read_ECPKParameters(FILE *fp, EC_GROUP **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_ECPKParameters, PEM_STRING_ECPARAMETERS, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_ECPKParameters); + +int +PEM_write_ECPKParameters(FILE *fp, const EC_GROUP *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_ECPKParameters, PEM_STRING_ECPARAMETERS, fp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_ECPKParameters); + +EC_GROUP * +PEM_read_bio_ECPKParameters(BIO *bp, EC_GROUP **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_ECPKParameters, PEM_STRING_ECPARAMETERS, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_ECPKParameters); + +int +PEM_write_bio_ECPKParameters(BIO *bp, const EC_GROUP *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPKParameters, PEM_STRING_ECPARAMETERS, bp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_ECPKParameters); + +EC_KEY * +PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ +} +LCRYPTO_ALIAS(PEM_read_ECPrivateKey); + +int +PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey, PEM_STRING_ECPRIVATEKEY, fp, + x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_ECPrivateKey); + +EC_KEY * +PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_eckey(pktmp, key); /* will free pktmp */ +} +LCRYPTO_ALIAS(PEM_read_bio_ECPrivateKey); + +int +PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey, PEM_STRING_ECPRIVATEKEY, bp, + x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_bio_ECPrivateKey); + +EC_KEY * +PEM_read_EC_PUBKEY(FILE *fp, EC_KEY **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_EC_PUBKEY, PEM_STRING_PUBLIC, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_EC_PUBKEY); + +int +PEM_write_EC_PUBKEY(FILE *fp, EC_KEY *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_EC_PUBKEY, PEM_STRING_PUBLIC, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_EC_PUBKEY); + +EC_KEY * +PEM_read_bio_EC_PUBKEY(BIO *bp, EC_KEY **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_EC_PUBKEY, PEM_STRING_PUBLIC, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_EC_PUBKEY); + +int +PEM_write_bio_EC_PUBKEY(BIO *bp, EC_KEY *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_EC_PUBKEY, PEM_STRING_PUBLIC, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_EC_PUBKEY); + +#endif + +#ifndef OPENSSL_NO_DH + +DH * +PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_DHparams, PEM_STRING_DHPARAMS, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_DHparams); + +int +PEM_write_DHparams(FILE *fp, const DH *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_DHparams, PEM_STRING_DHPARAMS, fp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_DHparams); + +DH * +PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_DHparams, PEM_STRING_DHPARAMS, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_DHparams); + +int +PEM_write_bio_DHparams(BIO *bp, const DH *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_DHparams, PEM_STRING_DHPARAMS, bp, + (void *)x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_DHparams); + +#endif + +EVP_PKEY * +PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_PUBKEY, PEM_STRING_PUBLIC, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_PUBKEY); + +int +PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_PUBKEY, PEM_STRING_PUBLIC, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_PUBKEY); + +EVP_PKEY * +PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_PUBKEY, PEM_STRING_PUBLIC, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_PUBKEY); + +int +PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PUBKEY, PEM_STRING_PUBLIC, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_PUBKEY); diff --git a/Libraries/libressl/crypto/pem/pem_err.c b/Libraries/libressl/crypto/pem/pem_err.c new file mode 100644 index 000000000..a94e2d5eb --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_err.c @@ -0,0 +1,117 @@ +/* $OpenBSD: pem_err.c,v 1.14 2023/07/07 13:40:44 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason) + +static ERR_STRING_DATA PEM_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA PEM_str_reasons[] = { + {ERR_REASON(PEM_R_BAD_BASE64_DECODE) , "bad base64 decode"}, + {ERR_REASON(PEM_R_BAD_DECRYPT) , "bad decrypt"}, + {ERR_REASON(PEM_R_BAD_END_LINE) , "bad end line"}, + {ERR_REASON(PEM_R_BAD_IV_CHARS) , "bad iv chars"}, + {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER) , "bad magic number"}, + {ERR_REASON(PEM_R_BAD_PASSWORD_READ) , "bad password read"}, + {ERR_REASON(PEM_R_BAD_VERSION_NUMBER) , "bad version number"}, + {ERR_REASON(PEM_R_BIO_WRITE_FAILURE) , "bio write failure"}, + {ERR_REASON(PEM_R_CIPHER_IS_NULL) , "cipher is null"}, + {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY), "error converting private key"}, + {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB), "expecting private key blob"}, + {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), "expecting public key blob"}, + {ERR_REASON(PEM_R_INCONSISTENT_HEADER) , "inconsistent header"}, + {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), "keyblob header parse error"}, + {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT) , "keyblob too short"}, + {ERR_REASON(PEM_R_NOT_DEK_INFO) , "not dek info"}, + {ERR_REASON(PEM_R_NOT_ENCRYPTED) , "not encrypted"}, + {ERR_REASON(PEM_R_NOT_PROC_TYPE) , "not proc type"}, + {ERR_REASON(PEM_R_NO_START_LINE) , "no start line"}, + {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD), "problems getting password"}, + {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA) , "public key no rsa"}, + {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT) , "pvk data too short"}, + {ERR_REASON(PEM_R_PVK_TOO_SHORT) , "pvk too short"}, + {ERR_REASON(PEM_R_READ_KEY) , "read key"}, + {ERR_REASON(PEM_R_SHORT_HEADER) , "short header"}, + {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER) , "unsupported cipher"}, + {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"}, + {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS), "unsupported key components"}, + {0, NULL} +}; + +#endif + +void +ERR_load_PEM_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) { + ERR_load_strings(0, PEM_str_functs); + ERR_load_strings(0, PEM_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_PEM_strings); diff --git a/Libraries/libressl/crypto/pem/pem_info.c b/Libraries/libressl/crypto/pem/pem_info.c new file mode 100644 index 000000000..b979c79b3 --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_info.c @@ -0,0 +1,387 @@ +/* $OpenBSD: pem_info.c,v 1.27 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "evp_local.h" + +STACK_OF(X509_INFO) * +PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, + void *u) +{ + BIO *b; + STACK_OF(X509_INFO) *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_X509_INFO_read_bio(b, sk, cb, u); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(PEM_X509_INFO_read); + +STACK_OF(X509_INFO) * +PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, + void *u) +{ + X509_INFO *xi = NULL; + char *name = NULL, *header = NULL; + void *pp; + unsigned char *data = NULL; + const unsigned char *p; + long len; + int ok = 0; + int num_in, ptype, raw; + STACK_OF(X509_INFO) *ret = sk; + d2i_of_void *d2i = NULL; + + if (ret == NULL) { + if ((ret = sk_X509_INFO_new_null()) == NULL) { + PEMerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + } + num_in = sk_X509_INFO_num(ret); + + if ((xi = X509_INFO_new()) == NULL) + goto err; + for (;;) { + raw = 0; + ptype = 0; + if (!PEM_read_bio(bp, &name, &header, &data, &len)) { + if (ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) { + ERR_clear_error(); + break; + } + goto err; + } + if ((strcmp(name, PEM_STRING_X509) == 0) || + (strcmp(name, PEM_STRING_X509_OLD) == 0)) { + d2i = (D2I_OF(void))d2i_X509; + if (xi->x509 != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + } + pp = &(xi->x509); + } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) { + d2i = (D2I_OF(void))d2i_X509_AUX; + if (xi->x509 != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + } + pp = &(xi->x509); + } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { + d2i = (D2I_OF(void))d2i_X509_CRL; + if (xi->crl != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + } + pp = &(xi->crl); + } else +#ifndef OPENSSL_NO_RSA + if (strcmp(name, PEM_STRING_RSA) == 0) { + d2i = (D2I_OF(void))d2i_RSAPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + } + xi->enc_data = NULL; + xi->enc_len = 0; + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_RSA; + pp = &xi->x_pkey->dec_pkey; + if (strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif +#ifndef OPENSSL_NO_DSA + if (strcmp(name, PEM_STRING_DSA) == 0) { + d2i = (D2I_OF(void))d2i_DSAPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + } + xi->enc_data = NULL; + xi->enc_len = 0; + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_DSA; + pp = &xi->x_pkey->dec_pkey; + if (strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif +#ifndef OPENSSL_NO_EC + if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { + d2i = (D2I_OF(void))d2i_ECPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + } + xi->enc_data = NULL; + xi->enc_len = 0; + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_EC; + pp = &xi->x_pkey->dec_pkey; + if (strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif + { + d2i = NULL; + pp = NULL; + } + + if (d2i != NULL) { + if (!raw) { + EVP_CIPHER_INFO cipher; + + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + p = data; + if (ptype) { + if (!d2i_PrivateKey(ptype, pp, &p, + len)) { + PEMerror(ERR_R_ASN1_LIB); + goto err; + } + } else if (d2i(pp, &p, len) == NULL) { + PEMerror(ERR_R_ASN1_LIB); + goto err; + } + } else { /* encrypted RSA data */ + if (!PEM_get_EVP_CIPHER_INFO(header, + &xi->enc_cipher)) + goto err; + xi->enc_data = (char *)data; + xi->enc_len = (int)len; + data = NULL; + } + } else { + /* unknown */ + } + free(name); + free(header); + free(data); + name = NULL; + header = NULL; + data = NULL; + } + + /* if the last one hasn't been pushed yet and there is anything + * in it then add it to the stack ... + */ + if ((xi->x509 != NULL) || (xi->crl != NULL) || + (xi->x_pkey != NULL) || (xi->enc_data != NULL)) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + xi = NULL; + } + ok = 1; + +err: + if (!ok) { + while (sk_X509_INFO_num(ret) > num_in) + X509_INFO_free(sk_X509_INFO_pop(ret)); + if (ret != sk) + sk_X509_INFO_free(ret); + ret = NULL; + } + X509_INFO_free(xi); + free(name); + free(header); + free(data); + + return ret; +} +LCRYPTO_ALIAS(PEM_X509_INFO_read_bio); + + +/* A TJH addition */ +int +PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + EVP_CIPHER_CTX ctx; + int i, ret = 0; + unsigned char *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char *iv = NULL; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + PEMerror(PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + /* now for the fun part ... if we have a private key then + * we have to be able to handle a not-yet-decrypted key + * being written out correctly ... if it is decrypted or + * it is non-encrypted then we use the base code + */ + if (xi->x_pkey != NULL) { + if ((xi->enc_data != NULL) && (xi->enc_len > 0) ) { + if (enc == NULL) { + PEMerror(PEM_R_CIPHER_IS_NULL); + goto err; + } + + /* copy from weirdo names into more normal things */ + iv = xi->enc_cipher.iv; + data = (unsigned char *)xi->enc_data; + i = xi->enc_len; + + /* we take the encryption data from the + * internal stuff rather than what the + * user has passed us ... as we have to + * match exactly for some strange reason + */ + objstr = OBJ_nid2sn( + EVP_CIPHER_nid(xi->enc_cipher.cipher)); + if (objstr == NULL) { + PEMerror(PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* create the right magic header stuff */ + if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 > + sizeof buf) { + PEMerror(ASN1_R_BUFFER_TOO_SMALL); + goto err; + } + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); + + /* use the normal code to write things out */ + i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); + if (i <= 0) + goto err; + } else { + /* Add DSA/DH */ +#ifndef OPENSSL_NO_RSA + /* normal optionally encrypted stuff */ + if (PEM_write_bio_RSAPrivateKey(bp, + xi->x_pkey->dec_pkey->pkey.rsa, + enc, kstr, klen, cb, u) <= 0) + goto err; +#endif + } + } + + /* if we have a certificate then write it out now */ + if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) + goto err; + + /* we are ignoring anything else that is loaded into the X509_INFO + * structure for the moment ... as I don't need it so I'm not + * coding it here and Eric can do it when this makes it into the + * base library --tjh + */ + + ret = 1; + +err: + explicit_bzero((char *)&ctx, sizeof(ctx)); + explicit_bzero(buf, PEM_BUFSIZE); + return (ret); +} +LCRYPTO_ALIAS(PEM_X509_INFO_write_bio); diff --git a/Libraries/libressl/crypto/pem/pem_lib.c b/Libraries/libressl/crypto/pem/pem_lib.c new file mode 100644 index 000000000..3f23a0131 --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_lib.c @@ -0,0 +1,873 @@ +/* $OpenBSD: pem_lib.c,v 1.53 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DES +#include +#endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "asn1_local.h" +#include "evp_local.h" + +#define MIN_LENGTH 4 + +static int load_iv(char **fromp, unsigned char *to, int num); +static int check_pem(const char *nm, const char *name); +int pem_check_suffix(const char *pem_str, const char *suffix); + +/* XXX LSSL ABI XXX return value and `num' ought to be size_t */ +int +PEM_def_callback(char *buf, int num, int w, void *key) +{ + size_t l; + int i; + const char *prompt; + + if (num < 0) + return -1; + + if (key) { + l = strlen(key); + if (l > (size_t)num) + l = (size_t)num; + memcpy(buf, key, l); + return (int)l; + } + + prompt = EVP_get_pw_prompt(); + if (prompt == NULL) + prompt = "Enter PEM pass phrase:"; + + for (;;) { + i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w); + if (i != 0) { + PEMerror(PEM_R_PROBLEMS_GETTING_PASSWORD); + memset(buf, 0, num); + return (-1); + } + l = strlen(buf); + if (l < MIN_LENGTH) { + fprintf(stderr, "phrase is too short, " + "needs to be at least %zu chars\n", + (size_t)MIN_LENGTH); + } else + break; + } + return (int)l; +} +LCRYPTO_ALIAS(PEM_def_callback); + +void +PEM_proc_type(char *buf, int type) +{ + const char *str; + + if (type == PEM_TYPE_ENCRYPTED) + str = "ENCRYPTED"; + else if (type == PEM_TYPE_MIC_CLEAR) + str = "MIC-CLEAR"; + else if (type == PEM_TYPE_MIC_ONLY) + str = "MIC-ONLY"; + else + str = "BAD-TYPE"; + + strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); + strlcat(buf, str, PEM_BUFSIZE); + strlcat(buf, "\n", PEM_BUFSIZE); +} +LCRYPTO_ALIAS(PEM_proc_type); + +void +PEM_dek_info(char *buf, const char *type, int len, char *str) +{ + static const unsigned char map[17] = "0123456789ABCDEF"; + long i; + int j; + + strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); + strlcat(buf, type, PEM_BUFSIZE); + strlcat(buf, ",", PEM_BUFSIZE); + j = strlen(buf); + if (j + (len * 2) + 1 > PEM_BUFSIZE) + return; + for (i = 0; i < len; i++) { + buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; + buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; + } + buf[j + i * 2] = '\n'; + buf[j + i * 2 + 1] = '\0'; +} +LCRYPTO_ALIAS(PEM_dek_info); + +void * +PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(PEM_ASN1_read); + +static int +check_pem(const char *nm, const char *name) +{ + /* Normal matching nm and name */ + if (!strcmp(nm, name)) + return 1; + + /* Make PEM_STRING_EVP_PKEY match any private key */ + + if (!strcmp(name, PEM_STRING_EVP_PKEY)) { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + if (!strcmp(nm, PEM_STRING_PKCS8)) + return 1; + if (!strcmp(nm, PEM_STRING_PKCS8INF)) + return 1; + slen = pem_check_suffix(nm, "PRIVATE KEY"); + if (slen > 0) { + /* NB: ENGINE implementations wont contain + * a deprecated old private key decode function + * so don't look for them. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (ameth && ameth->old_priv_decode) + return 1; + } + return 0; + } + + if (!strcmp(name, PEM_STRING_PARAMETERS)) { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + slen = pem_check_suffix(nm, "PARAMETERS"); + if (slen > 0) { + ENGINE *e; + ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); + if (ameth) { + int r; + if (ameth->param_decode) + r = 1; + else + r = 0; +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(e); +#endif + return r; + } + } + return 0; + } + + /* Permit older strings */ + + if (!strcmp(nm, PEM_STRING_X509_OLD) && + !strcmp(name, PEM_STRING_X509)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && + !strcmp(name, PEM_STRING_X509_REQ)) + return 1; + + /* Allow normal certs to be read as trusted certs */ + if (!strcmp(nm, PEM_STRING_X509) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_OLD) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + /* Some CAs use PKCS#7 with CERTIFICATE headers */ + if (!strcmp(nm, PEM_STRING_X509) && + !strcmp(name, PEM_STRING_PKCS7)) + return 1; + + if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && + !strcmp(name, PEM_STRING_PKCS7)) + return 1; + +#ifndef OPENSSL_NO_CMS + if (strcmp(nm, PEM_STRING_X509) == 0 && + strcmp(name, PEM_STRING_CMS) == 0) + return 1; + + /* Allow CMS to be read from PKCS#7 headers */ + if (strcmp(nm, PEM_STRING_PKCS7) == 0 && + strcmp(name, PEM_STRING_CMS) == 0) + return 1; +#endif + + return 0; +} + +int +PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, void *u) +{ + EVP_CIPHER_INFO cipher; + char *nm = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ret = 0; + + for (;;) { + if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { + if (ERR_GET_REASON(ERR_peek_error()) == + PEM_R_NO_START_LINE) + ERR_asprintf_error_data("Expecting: %s", name); + return 0; + } + if (check_pem(nm, name)) + break; + free(nm); + free(header); + free(data); + } + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + + *pdata = data; + *plen = len; + + if (pnm) + *pnm = nm; + + ret = 1; + +err: + if (!ret || !pnm) + free(nm); + free(header); + if (!ret) + free(data); + return ret; +} +LCRYPTO_ALIAS(PEM_bytes_read_bio); + +int +PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(PEM_ASN1_write); + +int +PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) +{ + EVP_CIPHER_CTX ctx; + int dsize = 0, i, j, ret = 0; + unsigned char *p, *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + PEMerror(PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + PEMerror(ERR_R_ASN1_LIB); + dsize = 0; + goto err; + } + /* dzise + 8 bytes are needed */ + /* actually it needs the cipher block size extra... */ + data = malloc(dsize + 20); + if (data == NULL) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + if (kstr == NULL) { + if (callback == NULL) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else + klen = (*callback)(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerror(PEM_R_READ_KEY); + goto err; + } + kstr = (unsigned char *)buf; + } + if ((size_t)enc->iv_len > sizeof(iv)) { + PEMerror(EVP_R_IV_TOO_LARGE); + goto err; + } + arc4random_buf(iv, enc->iv_len); /* Generate a salt */ + /* The 'iv' is used as the iv and as a salt. It is + * NOT taken from the BytesToKey function */ + if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, + key, NULL)) + goto err; + + if (kstr == (unsigned char *)buf) + explicit_bzero(buf, PEM_BUFSIZE); + + if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 > sizeof buf) { + PEMerror(ASN1_R_BUFFER_TOO_SMALL); + goto err; + } + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); + /* k=strlen(buf); */ + + EVP_CIPHER_CTX_init(&ctx); + ret = 1; + if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) || + !EVP_EncryptUpdate(&ctx, data, &j, data, i) || + !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) + ret = 0; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + goto err; + i += j; + } else { + ret = 1; + buf[0] = '\0'; + } + i = PEM_write_bio(bp, name, buf, data, i); + if (i <= 0) + ret = 0; +err: + explicit_bzero(key, sizeof(key)); + explicit_bzero(iv, sizeof(iv)); + explicit_bzero((char *)&ctx, sizeof(ctx)); + explicit_bzero(buf, PEM_BUFSIZE); + freezero(data, (unsigned int)dsize); + return (ret); +} +LCRYPTO_ALIAS(PEM_ASN1_write_bio); + +int +PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, + pem_password_cb *callback, void *u) +{ + int i, j, o, klen; + long len; + EVP_CIPHER_CTX ctx; + unsigned char key[EVP_MAX_KEY_LENGTH]; + char buf[PEM_BUFSIZE]; + + len = *plen; + + if (cipher->cipher == NULL) + return (1); + if (callback == NULL) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u); + else + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + PEMerror(PEM_R_BAD_PASSWORD_READ); + return (0); + } + if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), + (unsigned char *)buf, klen, 1, key, NULL)) + return 0; + + j = (int)len; + EVP_CIPHER_CTX_init(&ctx); + o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, + &(cipher->iv[0])); + if (o) + o = EVP_DecryptUpdate(&ctx, data, &i, data, j); + if (o) + o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); + EVP_CIPHER_CTX_cleanup(&ctx); + explicit_bzero((char *)buf, sizeof(buf)); + explicit_bzero((char *)key, sizeof(key)); + if (!o) { + PEMerror(PEM_R_BAD_DECRYPT); + return (0); + } + *plen = j + i; + return (1); +} +LCRYPTO_ALIAS(PEM_do_header); + +int +PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) +{ + const EVP_CIPHER *enc = NULL; + char *p, c; + char **header_pp = &header; + + cipher->cipher = NULL; + if ((header == NULL) || (*header == '\0') || (*header == '\n')) + return (1); + if (strncmp(header, "Proc-Type: ", 11) != 0) { + PEMerror(PEM_R_NOT_PROC_TYPE); + return (0); + } + header += 11; + if (*header != '4') + return (0); + header++; + if (*header != ',') + return (0); + header++; + if (strncmp(header, "ENCRYPTED", 9) != 0) { + PEMerror(PEM_R_NOT_ENCRYPTED); + return (0); + } + for (; (*header != '\n') && (*header != '\0'); header++) + ; + if (*header == '\0') { + PEMerror(PEM_R_SHORT_HEADER); + return (0); + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + PEMerror(PEM_R_NOT_DEK_INFO); + return (0); + } + header += 10; + + p = header; + for (;;) { + c= *header; + if (!( ((c >= 'A') && (c <= 'Z')) || (c == '-') || + ((c >= '0') && (c <= '9')))) + break; + header++; + } + *header = '\0'; + cipher->cipher = enc = EVP_get_cipherbyname(p); + *header = c; + header++; + + if (enc == NULL) { + PEMerror(PEM_R_UNSUPPORTED_ENCRYPTION); + return (0); + } + if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len)) + return (0); + + return (1); +} +LCRYPTO_ALIAS(PEM_get_EVP_CIPHER_INFO); + +static int +load_iv(char **fromp, unsigned char *to, int num) +{ + int v, i; + char *from; + + from= *fromp; + for (i = 0; i < num; i++) + to[i] = 0; + num *= 2; + for (i = 0; i < num; i++) { + if ((*from >= '0') && (*from <= '9')) + v = *from - '0'; + else if ((*from >= 'A') && (*from <= 'F')) + v = *from - 'A' + 10; + else if ((*from >= 'a') && (*from <= 'f')) + v = *from - 'a' + 10; + else { + PEMerror(PEM_R_BAD_IV_CHARS); + return (0); + } + from++; + to[i / 2] |= v << (long)((!(i & 1)) * 4); + } + + *fromp = from; + return (1); +} + +int +PEM_write(FILE *fp, const char *name, const char *header, + const unsigned char *data, long len) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_write_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(PEM_write); + +int +PEM_write_bio(BIO *bp, const char *name, const char *header, + const unsigned char *data, long len) +{ + int nlen, n, i, j, outl; + unsigned char *buf = NULL; + EVP_ENCODE_CTX ctx; + int reason = ERR_R_BUF_LIB; + + EVP_EncodeInit(&ctx); + nlen = strlen(name); + + if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + + if (header != NULL && (i = strlen(header)) > 0) { + if ((BIO_write(bp, header, i) != i) || + (BIO_write(bp, "\n", 1) != 1)) + goto err; + } + + buf = reallocarray(NULL, PEM_BUFSIZE, 8); + if (buf == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + i = j = 0; + while (len > 0) { + n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); + if (!EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n)) + goto err; + if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + i += outl; + len -= n; + j += n; + } + EVP_EncodeFinal(&ctx, buf, &outl); + if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + freezero(buf, PEM_BUFSIZE * 8); + buf = NULL; + if ((BIO_write(bp, "-----END ", 9) != 9) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + return (i + outl); + +err: + freezero(buf, PEM_BUFSIZE * 8); + PEMerror(reason); + return (0); +} +LCRYPTO_ALIAS(PEM_write_bio); + +int +PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(PEM_read); + +int +PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, + long *len) +{ + EVP_ENCODE_CTX ctx; + int end = 0, i, k, bl = 0, hl = 0, nohead = 0; + char buf[256]; + BUF_MEM *nameB; + BUF_MEM *headerB; + BUF_MEM *dataB, *tmpB; + + nameB = BUF_MEM_new(); + headerB = BUF_MEM_new(); + dataB = BUF_MEM_new(); + if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + PEMerror(ERR_R_MALLOC_FAILURE); + return (0); + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + PEMerror(PEM_R_NO_START_LINE); + goto err; + } + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (strncmp(buf, "-----BEGIN ", 11) == 0) { + i = strlen(&(buf[11])); + + if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) + continue; + if (!BUF_MEM_grow(nameB, i + 9)) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + headerB->data[0] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (buf[0] == '\n') + break; + if (!BUF_MEM_grow(headerB, hl + i + 9)) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + dataB->data[0] = '\0'; + if (!nohead) { + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (i != 65) + end = 1; + if (strncmp(buf, "-----END ", 9) == 0) + break; + if (i > 65) + break; + if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(&(dataB->data[bl]), buf, i); + dataB->data[bl + i] = '\0'; + bl += i; + if (end) { + buf[0] = '\0'; + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + break; + } + } + } else { + tmpB = headerB; + headerB = dataB; + dataB = tmpB; + bl = hl; + } + i = strlen(nameB->data); + if ((strncmp(buf, "-----END ", 9) != 0) || + (strncmp(nameB->data, &(buf[9]), i) != 0) || + (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { + PEMerror(PEM_R_BAD_END_LINE); + goto err; + } + + EVP_DecodeInit(&ctx); + i = EVP_DecodeUpdate(&ctx, + (unsigned char *)dataB->data, &bl, + (unsigned char *)dataB->data, bl); + if (i < 0) { + PEMerror(PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + PEMerror(PEM_R_BAD_BASE64_DECODE); + goto err; + } + bl += k; + + if (bl == 0) + goto err; + *name = nameB->data; + *header = headerB->data; + *data = (unsigned char *)dataB->data; + *len = bl; + free(nameB); + free(headerB); + free(dataB); + return (1); + +err: + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + return (0); +} +LCRYPTO_ALIAS(PEM_read_bio); + +/* Check pem string and return prefix length. + * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" + * the return value is 3 for the string "RSA". + */ + +int +pem_check_suffix(const char *pem_str, const char *suffix) +{ + int pem_len = strlen(pem_str); + int suffix_len = strlen(suffix); + const char *p; + + if (suffix_len + 1 >= pem_len) + return 0; + p = pem_str + pem_len - suffix_len; + if (strcmp(p, suffix)) + return 0; + p--; + if (*p != ' ') + return 0; + return p - pem_str; +} diff --git a/Libraries/libressl/crypto/pem/pem_oth.c b/Libraries/libressl/crypto/pem/pem_oth.c new file mode 100644 index 000000000..2dca978ef --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_oth.c @@ -0,0 +1,88 @@ +/* $OpenBSD: pem_oth.c,v 1.9 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include + +/* Handle 'other' PEMs: not private keys */ + +void * +PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u) +{ + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + char *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) + return NULL; + p = data; + ret = d2i(x, &p, len); + if (ret == NULL) + PEMerror(ERR_R_ASN1_LIB); + free(data); + return (ret); +} +LCRYPTO_ALIAS(PEM_ASN1_read_bio); diff --git a/Libraries/libressl/crypto/pem/pem_pk8.c b/Libraries/libressl/crypto/pem/pem_pk8.c new file mode 100644 index 000000000..6d0c0cbd5 --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_pk8.c @@ -0,0 +1,324 @@ +/* $OpenBSD: pem_pk8.c,v 1.14 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); + +/* These functions write a private key in PKCS#8 format: it is a "drop in" + * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' + * is NULL then it uses the unencrypted private key form. The 'nid' versions + * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. + */ + +int +PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, char *kstr, + int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_bio_PKCS8PrivateKey_nid); + +int +PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_bio_PKCS8PrivateKey); + +int +i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_bio); + +int +i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_nid_bio); + +static int +do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + int ret; + + if (!(p8inf = EVP_PKEY2PKCS8(x))) { + PEMerror(PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + if (!cb) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerror(PEM_R_READ_KEY); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 0; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) + explicit_bzero(buf, klen); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (isder) + ret = i2d_PKCS8_bio(bp, p8); + else + ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + return ret; + } else { + if (isder) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } +} + +EVP_PKEY * +d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + int klen; + EVP_PKEY *ret; + char psbuf[PEM_BUFSIZE]; + + p8 = d2i_PKCS8_bio(bp, NULL); + if (!p8) + return NULL; + if (cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + PEMerror(PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + return NULL; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if (!p8inf) + return NULL; + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (!ret) + return NULL; + if (x) { + EVP_PKEY_free(*x); + *x = ret; + } + return ret; +} +LCRYPTO_ALIAS(d2i_PKCS8PrivateKey_bio); + + +int +i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_fp); + +int +i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, char *kstr, + int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_nid_fp); + +int +PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, char *kstr, + int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_PKCS8PrivateKey_nid); + +int +PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_PKCS8PrivateKey); + +static int +do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + BIO *bp; + int ret; + + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + BIO_free(bp); + return ret; +} + +EVP_PKEY * +d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + BIO *bp; + EVP_PKEY *ret; + + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerror(ERR_R_BUF_LIB); + return NULL; + } + ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); + BIO_free(bp); + return ret; +} +LCRYPTO_ALIAS(d2i_PKCS8PrivateKey_fp); + +X509_SIG * +PEM_read_PKCS8(FILE *fp, X509_SIG **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_X509_SIG, PEM_STRING_PKCS8, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_PKCS8); + +int +PEM_write_PKCS8(FILE *fp, X509_SIG *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_X509_SIG, PEM_STRING_PKCS8, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_PKCS8); + +X509_SIG * +PEM_read_bio_PKCS8(BIO *bp, X509_SIG **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_SIG, PEM_STRING_PKCS8, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_PKCS8); + +int +PEM_write_bio_PKCS8(BIO *bp, X509_SIG *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_SIG, PEM_STRING_PKCS8, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_PKCS8); + +PKCS8_PRIV_KEY_INFO * +PEM_read_PKCS8_PRIV_KEY_INFO(FILE *fp, PKCS8_PRIV_KEY_INFO **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_PKCS8_PRIV_KEY_INFO); + +int +PEM_write_PKCS8_PRIV_KEY_INFO(FILE *fp, PKCS8_PRIV_KEY_INFO *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_PKCS8_PRIV_KEY_INFO); + +PKCS8_PRIV_KEY_INFO * +PEM_read_bio_PKCS8_PRIV_KEY_INFO(BIO *bp, PKCS8_PRIV_KEY_INFO **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_PKCS8_PRIV_KEY_INFO); + +int +PEM_write_bio_PKCS8_PRIV_KEY_INFO(BIO *bp, PKCS8_PRIV_KEY_INFO *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_PKCS8_PRIV_KEY_INFO); diff --git a/Libraries/libressl/crypto/pem/pem_pkey.c b/Libraries/libressl/crypto/pem/pem_pkey.c new file mode 100644 index 000000000..296195213 --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_pkey.c @@ -0,0 +1,267 @@ +/* $OpenBSD: pem_pkey.c,v 1.27 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "asn1_local.h" +#include "evp_local.h" + +int pem_check_suffix(const char *pem_str, const char *suffix); + +EVP_PKEY * +PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + int slen; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, + bp, cb, u)) + return NULL; + p = data; + + if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + EVP_PKEY_free(*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8; + int klen; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_X509_SIG(NULL, &p, len); + if (!p8) + goto p8err; + if (cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + PEMerror(PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + goto err; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + EVP_PKEY_free(*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (!ameth || !ameth->old_priv_decode) + goto p8err; + ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); + } + +p8err: + if (ret == NULL) + PEMerror(ERR_R_ASN1_LIB); +err: + free(nm); + freezero(data, len); + return (ret); +} +LCRYPTO_ALIAS(PEM_read_bio_PrivateKey); + +int +PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + if (x->ameth == NULL || x->ameth->priv_encode != NULL) + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *)kstr, klen, cb, u); + + return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, + u); +} +LCRYPTO_ALIAS(PEM_write_bio_PrivateKey); + +int +PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + char pem_str[80]; + + (void) snprintf(pem_str, sizeof(pem_str), "%s PRIVATE KEY", + x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_str, bp, x, enc, kstr, klen, cb, u); +} +LCRYPTO_ALIAS(PEM_write_bio_PrivateKey_traditional); + +EVP_PKEY * +PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + int slen; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, + bp, 0, NULL)) + return NULL; + p = data; + + if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { + ret = EVP_PKEY_new(); + if (!ret) + goto err; + if (!EVP_PKEY_set_type_str(ret, nm, slen) || + !ret->ameth->param_decode || + !ret->ameth->param_decode(ret, &p, len)) { + EVP_PKEY_free(ret); + ret = NULL; + goto err; + } + if (x) { + EVP_PKEY_free(*x); + *x = ret; + } + } + +err: + if (ret == NULL) + PEMerror(ERR_R_ASN1_LIB); + free(nm); + free(data); + return (ret); +} +LCRYPTO_ALIAS(PEM_read_bio_Parameters); + +int +PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +{ + char pem_str[80]; + + if (!x->ameth || !x->ameth->param_encode) + return 0; + + (void) snprintf(pem_str, sizeof(pem_str), "%s PARAMETERS", + x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, + pem_str, bp, x, NULL, NULL, 0, 0, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_Parameters); + +EVP_PKEY * +PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + BIO *b; + EVP_PKEY *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio_PrivateKey(b, x, cb, u); + BIO_free(b); + return (ret); +} +LCRYPTO_ALIAS(PEM_read_PrivateKey); + +int +PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + BIO *b; + int ret; + + if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { + PEMerror(ERR_R_BUF_LIB); + return 0; + } + ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; +} +LCRYPTO_ALIAS(PEM_write_PrivateKey); diff --git a/Libraries/libressl/crypto/pem/pem_sign.c b/Libraries/libressl/crypto/pem/pem_sign.c new file mode 100644 index 000000000..461f95744 --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_sign.c @@ -0,0 +1,108 @@ +/* $OpenBSD: pem_sign.c,v 1.15 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include + +int +PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +{ + return EVP_DigestInit_ex(ctx, type, NULL); +} +LCRYPTO_ALIAS(PEM_SignInit); + +int +PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, + unsigned int count) +{ + return EVP_DigestUpdate(ctx, data, count); +} +LCRYPTO_ALIAS(PEM_SignUpdate); + +int +PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, + EVP_PKEY *pkey) +{ + unsigned char *m; + int i, ret = 0; + unsigned int m_len; + + m = malloc(EVP_PKEY_size(pkey) + 2); + if (m == NULL) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0) + goto err; + + i = EVP_EncodeBlock(sigret, m, m_len); + *siglen = i; + ret = 1; + +err: + /* ctx has been zeroed by EVP_SignFinal() */ + free(m); + return (ret); +} +LCRYPTO_ALIAS(PEM_SignFinal); diff --git a/Libraries/libressl/crypto/pem/pem_x509.c b/Libraries/libressl/crypto/pem/pem_x509.c new file mode 100644 index 000000000..0016413b5 --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_x509.c @@ -0,0 +1,98 @@ +/* $OpenBSD: pem_x509.c,v 1.9 2023/07/07 13:40:44 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include +#include + + +X509 * +PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_X509, PEM_STRING_X509, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_X509); + +int +PEM_write_X509(FILE *fp, X509 *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_X509, PEM_STRING_X509, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_X509); + +X509 * +PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_X509); + +int +PEM_write_bio_X509(BIO *bp, X509 *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509, PEM_STRING_X509, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_X509); diff --git a/Libraries/libressl/crypto/pem/pem_xaux.c b/Libraries/libressl/crypto/pem/pem_xaux.c new file mode 100644 index 000000000..5f44a2b5e --- /dev/null +++ b/Libraries/libressl/crypto/pem/pem_xaux.c @@ -0,0 +1,98 @@ +/* $OpenBSD: pem_xaux.c,v 1.11 2023/07/07 13:40:44 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include +#include + + +X509 * +PEM_read_X509_AUX(FILE *fp, X509 **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_X509_AUX, PEM_STRING_X509_TRUSTED, fp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_X509_AUX); + +int +PEM_write_X509_AUX(FILE *fp, X509 *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_X509_AUX, PEM_STRING_X509_TRUSTED, fp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_X509_AUX); + +X509 * +PEM_read_bio_X509_AUX(BIO *bp, X509 **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_AUX, PEM_STRING_X509_TRUSTED, bp, + (void **)x, cb, u); +} +LCRYPTO_ALIAS(PEM_read_bio_X509_AUX); + +int +PEM_write_bio_X509_AUX(BIO *bp, X509 *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_AUX, PEM_STRING_X509_TRUSTED, bp, + x, NULL, NULL, 0, NULL, NULL); +} +LCRYPTO_ALIAS(PEM_write_bio_X509_AUX); diff --git a/Libraries/libressl/crypto/pem/pvkfmt.c b/Libraries/libressl/crypto/pem/pvkfmt.c new file mode 100644 index 000000000..816d8b7dc --- /dev/null +++ b/Libraries/libressl/crypto/pem/pvkfmt.c @@ -0,0 +1,944 @@ +/* $OpenBSD: pvkfmt.c,v 1.27 2023/07/07 13:40:44 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB + * and PRIVATEKEYBLOB). + */ + +#include +#include + +#include + +#include +#include +#include + +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) +#include +#include + +#include "bn_local.h" +#include "dsa_local.h" +#include "evp_local.h" +#include "rsa_local.h" + +/* Utility function: read a DWORD (4 byte unsigned integer) in little endian + * format + */ + +static unsigned int +read_ledword(const unsigned char **in) +{ + const unsigned char *p = *in; + unsigned int ret; + + ret = *p++; + ret |= (*p++ << 8); + ret |= (*p++ << 16); + ret |= (*p++ << 24); + *in = p; + return ret; +} + +/* Read a BIGNUM in little endian format. The docs say that this should take up + * bitlen/8 bytes. + */ + +static int +read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) +{ + const unsigned char *p; + unsigned char *tmpbuf, *q; + unsigned int i; + + p = *in + nbyte - 1; + tmpbuf = malloc(nbyte); + if (!tmpbuf) + return 0; + q = tmpbuf; + for (i = 0; i < nbyte; i++) + *q++ = *p--; + *r = BN_bin2bn(tmpbuf, nbyte, NULL); + free(tmpbuf); + if (*r) { + *in += nbyte; + return 1; + } else + return 0; +} + + +/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ + +#define MS_PUBLICKEYBLOB 0x6 +#define MS_PRIVATEKEYBLOB 0x7 +#define MS_RSA1MAGIC 0x31415352L +#define MS_RSA2MAGIC 0x32415352L +#define MS_DSS1MAGIC 0x31535344L +#define MS_DSS2MAGIC 0x32535344L + +#define MS_KEYALG_RSA_KEYX 0xa400 +#define MS_KEYALG_DSS_SIGN 0x2200 + +#define MS_KEYTYPE_KEYX 0x1 +#define MS_KEYTYPE_SIGN 0x2 + +/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ +#define MS_PVKMAGIC 0xb0b5f11eL +/* Salt length for PVK files */ +#define PVK_SALTLEN 0x10 + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); + +static int +do_blob_header(const unsigned char **in, unsigned int length, + unsigned int *pmagic, unsigned int *pbitlen, int *pisdss, int *pispub) +{ + const unsigned char *p = *in; + + if (length < 16) + return 0; + /* bType */ + if (*p == MS_PUBLICKEYBLOB) { + if (*pispub == 0) { + PEMerror(PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + *pispub = 1; + } else if (*p == MS_PRIVATEKEYBLOB) { + if (*pispub == 1) { + PEMerror(PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + *pispub = 0; + } else + return 0; + p++; + /* Version */ + if (*p++ != 0x2) { + PEMerror(PEM_R_BAD_VERSION_NUMBER); + return 0; + } + /* Ignore reserved, aiKeyAlg */ + p += 6; + *pmagic = read_ledword(&p); + *pbitlen = read_ledword(&p); + if (*pbitlen > 65536) { + PEMerror(PEM_R_INCONSISTENT_HEADER); + return 0; + } + *pisdss = 0; + switch (*pmagic) { + + case MS_DSS1MAGIC: + *pisdss = 1; + case MS_RSA1MAGIC: + if (*pispub == 0) { + PEMerror(PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + break; + + case MS_DSS2MAGIC: + *pisdss = 1; + case MS_RSA2MAGIC: + if (*pispub == 1) { + PEMerror(PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + break; + + default: + PEMerror(PEM_R_BAD_MAGIC_NUMBER); + return -1; + } + *in = p; + return 1; +} + +static unsigned int +blob_length(unsigned bitlen, int isdss, int ispub) +{ + unsigned int nbyte, hnbyte; + + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + if (isdss) { + + /* Expected length: 20 for q + 3 components bitlen each + 24 + * for seed structure. + */ + if (ispub) + return 44 + 3 * nbyte; + /* Expected length: 20 for q, priv, 2 bitlen components + 24 + * for seed structure. + */ + else + return 64 + 2 * nbyte; + } else { + /* Expected length: 4 for 'e' + 'n' */ + if (ispub) + return 4 + nbyte; + else + /* Expected length: 4 for 'e' and 7 other components. + * 2 components are bitlen size, 5 are bitlen/2 + */ + return 4 + 2*nbyte + 5*hnbyte; + } + +} + +static EVP_PKEY * +do_b2i(const unsigned char **in, unsigned int length, int ispub) +{ + const unsigned char *p = *in; + unsigned int bitlen, magic; + int isdss; + + if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) { + PEMerror(PEM_R_KEYBLOB_HEADER_PARSE_ERROR); + return NULL; + } + length -= 16; + if (length < blob_length(bitlen, isdss, ispub)) { + PEMerror(PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + if (isdss) + return b2i_dss(&p, length, bitlen, ispub); + else + return b2i_rsa(&p, length, bitlen, ispub); +} + +static EVP_PKEY * +do_b2i_bio(BIO *in, int ispub) +{ + const unsigned char *p; + unsigned char hdr_buf[16], *buf = NULL; + unsigned int bitlen, magic, length; + int isdss; + EVP_PKEY *ret = NULL; + + if (BIO_read(in, hdr_buf, 16) != 16) { + PEMerror(PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + p = hdr_buf; + if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) + return NULL; + + length = blob_length(bitlen, isdss, ispub); + buf = malloc(length); + if (!buf) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (BIO_read(in, buf, length) != (int)length) { + PEMerror(PEM_R_KEYBLOB_TOO_SHORT); + goto err; + } + + if (isdss) + ret = b2i_dss(&p, length, bitlen, ispub); + else + ret = b2i_rsa(&p, length, bitlen, ispub); + + err: + free(buf); + return ret; +} + +static EVP_PKEY * +b2i_dss(const unsigned char **in, unsigned int length, unsigned int bitlen, + int ispub) +{ + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + DSA *dsa = NULL; + BN_CTX *ctx = NULL; + unsigned int nbyte; + + nbyte = (bitlen + 7) >> 3; + + dsa = DSA_new(); + ret = EVP_PKEY_new(); + if (!dsa || !ret) + goto err; + if (!read_lebn(&p, nbyte, &dsa->p)) + goto err; + if (!read_lebn(&p, 20, &dsa->q)) + goto err; + if (!read_lebn(&p, nbyte, &dsa->g)) + goto err; + if (ispub) { + if (!read_lebn(&p, nbyte, &dsa->pub_key)) + goto err; + } else { + if (!read_lebn(&p, 20, &dsa->priv_key)) + goto err; + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) + goto err; + if (!(ctx = BN_CTX_new())) + goto err; + if (!BN_mod_exp_ct(dsa->pub_key, dsa->g, + dsa->priv_key, dsa->p, ctx)) + goto err; + BN_CTX_free(ctx); + } + + EVP_PKEY_set1_DSA(ret, dsa); + DSA_free(dsa); + *in = p; + return ret; + + err: + PEMerror(ERR_R_MALLOC_FAILURE); + DSA_free(dsa); + EVP_PKEY_free(ret); + BN_CTX_free(ctx); + return NULL; +} + +static EVP_PKEY * +b2i_rsa(const unsigned char **in, unsigned int length, unsigned int bitlen, + int ispub) +{ + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + RSA *rsa = NULL; + unsigned int nbyte, hnbyte; + + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + rsa = RSA_new(); + ret = EVP_PKEY_new(); + if (!rsa || !ret) + goto err; + rsa->e = BN_new(); + if (!rsa->e) + goto err; + if (!BN_set_word(rsa->e, read_ledword(&p))) + goto err; + if (!read_lebn(&p, nbyte, &rsa->n)) + goto err; + if (!ispub) { + if (!read_lebn(&p, hnbyte, &rsa->p)) + goto err; + if (!read_lebn(&p, hnbyte, &rsa->q)) + goto err; + if (!read_lebn(&p, hnbyte, &rsa->dmp1)) + goto err; + if (!read_lebn(&p, hnbyte, &rsa->dmq1)) + goto err; + if (!read_lebn(&p, hnbyte, &rsa->iqmp)) + goto err; + if (!read_lebn(&p, nbyte, &rsa->d)) + goto err; + } + + EVP_PKEY_set1_RSA(ret, rsa); + RSA_free(rsa); + *in = p; + return ret; + + err: + PEMerror(ERR_R_MALLOC_FAILURE); + RSA_free(rsa); + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY * +b2i_PrivateKey(const unsigned char **in, long length) +{ + return do_b2i(in, length, 0); +} +LCRYPTO_ALIAS(b2i_PrivateKey); + +EVP_PKEY * +b2i_PublicKey(const unsigned char **in, long length) +{ + return do_b2i(in, length, 1); +} +LCRYPTO_ALIAS(b2i_PublicKey); + +EVP_PKEY * +b2i_PrivateKey_bio(BIO *in) +{ + return do_b2i_bio(in, 0); +} +LCRYPTO_ALIAS(b2i_PrivateKey_bio); + +EVP_PKEY * +b2i_PublicKey_bio(BIO *in) +{ + return do_b2i_bio(in, 1); +} +LCRYPTO_ALIAS(b2i_PublicKey_bio); + +static void +write_ledword(unsigned char **out, unsigned int dw) +{ + unsigned char *p = *out; + + *p++ = dw & 0xff; + *p++ = (dw >> 8) & 0xff; + *p++ = (dw >> 16) & 0xff; + *p++ = (dw >> 24) & 0xff; + *out = p; +} + +static void +write_lebn(unsigned char **out, const BIGNUM *bn, int len) +{ + int nb, i; + unsigned char *p = *out, *q, c; + + nb = BN_num_bytes(bn); + BN_bn2bin(bn, p); + q = p + nb - 1; + /* In place byte order reversal */ + for (i = 0; i < nb / 2; i++) { + c = *p; + *p++ = *q; + *q-- = c; + } + *out += nb; + /* Pad with zeroes if we have to */ + if (len > 0) { + len -= nb; + if (len > 0) { + memset(*out, 0, len); + *out += len; + } + } +} + + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub); +static void write_dsa(unsigned char **out, DSA *dsa, int ispub); + +static int +do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) +{ + unsigned char *p; + unsigned int bitlen, magic = 0, keyalg; + int outlen, noinc = 0; + + if (pk->type == EVP_PKEY_DSA) { + bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic); + keyalg = MS_KEYALG_DSS_SIGN; + } else if (pk->type == EVP_PKEY_RSA) { + bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic); + keyalg = MS_KEYALG_RSA_KEYX; + } else + return -1; + if (bitlen == 0) + return -1; + outlen = 16 + blob_length(bitlen, + keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); + if (out == NULL) + return outlen; + if (*out) + p = *out; + else { + p = malloc(outlen); + if (!p) + return -1; + *out = p; + noinc = 1; + } + if (ispub) + *p++ = MS_PUBLICKEYBLOB; + else + *p++ = MS_PRIVATEKEYBLOB; + *p++ = 0x2; + *p++ = 0; + *p++ = 0; + write_ledword(&p, keyalg); + write_ledword(&p, magic); + write_ledword(&p, bitlen); + if (keyalg == MS_KEYALG_DSS_SIGN) + write_dsa(&p, pk->pkey.dsa, ispub); + else + write_rsa(&p, pk->pkey.rsa, ispub); + if (!noinc) + *out += outlen; + return outlen; +} + +static int +do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) +{ + unsigned char *tmp = NULL; + int outlen, wrlen; + + outlen = do_i2b(&tmp, pk, ispub); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + free(tmp); + if (wrlen == outlen) + return outlen; + return -1; +} + +static int +check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) +{ + int bitlen; + + bitlen = BN_num_bits(dsa->p); + if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) || + (BN_num_bits(dsa->g) > bitlen)) + goto err; + if (ispub) { + if (BN_num_bits(dsa->pub_key) > bitlen) + goto err; + *pmagic = MS_DSS1MAGIC; + } else { + if (BN_num_bits(dsa->priv_key) > 160) + goto err; + *pmagic = MS_DSS2MAGIC; + } + + return bitlen; + + err: + PEMerror(PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static int +check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) +{ + int nbyte, hnbyte, bitlen; + + if (BN_num_bits(rsa->e) > 32) + goto err; + bitlen = BN_num_bits(rsa->n); + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + if (ispub) { + *pmagic = MS_RSA1MAGIC; + return bitlen; + } else { + *pmagic = MS_RSA2MAGIC; + /* For private key each component must fit within nbyte or + * hnbyte. + */ + if (BN_num_bytes(rsa->d) > nbyte) + goto err; + if ((BN_num_bytes(rsa->iqmp) > hnbyte) || + (BN_num_bytes(rsa->p) > hnbyte) || + (BN_num_bytes(rsa->q) > hnbyte) || + (BN_num_bytes(rsa->dmp1) > hnbyte) || + (BN_num_bytes(rsa->dmq1) > hnbyte)) + goto err; + } + return bitlen; + + err: + PEMerror(PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static void +write_rsa(unsigned char **out, RSA *rsa, int ispub) +{ + int nbyte, hnbyte; + + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + write_lebn(out, rsa->e, 4); + write_lebn(out, rsa->n, -1); + if (ispub) + return; + write_lebn(out, rsa->p, hnbyte); + write_lebn(out, rsa->q, hnbyte); + write_lebn(out, rsa->dmp1, hnbyte); + write_lebn(out, rsa->dmq1, hnbyte); + write_lebn(out, rsa->iqmp, hnbyte); + write_lebn(out, rsa->d, nbyte); +} + +static void +write_dsa(unsigned char **out, DSA *dsa, int ispub) +{ + int nbyte; + + nbyte = BN_num_bytes(dsa->p); + write_lebn(out, dsa->p, nbyte); + write_lebn(out, dsa->q, 20); + write_lebn(out, dsa->g, nbyte); + if (ispub) + write_lebn(out, dsa->pub_key, nbyte); + else + write_lebn(out, dsa->priv_key, 20); + /* Set "invalid" for seed structure values */ + memset(*out, 0xff, 24); + *out += 24; + return; +} + +int +i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) +{ + return do_i2b_bio(out, pk, 0); +} +LCRYPTO_ALIAS(i2b_PrivateKey_bio); + +int +i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) +{ + return do_i2b_bio(out, pk, 1); +} +LCRYPTO_ALIAS(i2b_PublicKey_bio); + +#ifndef OPENSSL_NO_RC4 + +static int +do_PVK_header(const unsigned char **in, unsigned int length, int skip_magic, + unsigned int *psaltlen, unsigned int *pkeylen) +{ + const unsigned char *p = *in; + unsigned int pvk_magic, is_encrypted; + + if (skip_magic) { + if (length < 20) { + PEMerror(PEM_R_PVK_TOO_SHORT); + return 0; + } + length -= 20; + } else { + if (length < 24) { + PEMerror(PEM_R_PVK_TOO_SHORT); + return 0; + } + length -= 24; + pvk_magic = read_ledword(&p); + if (pvk_magic != MS_PVKMAGIC) { + PEMerror(PEM_R_BAD_MAGIC_NUMBER); + return 0; + } + } + /* Skip reserved */ + p += 4; + /*keytype = */read_ledword(&p); + is_encrypted = read_ledword(&p); + *psaltlen = read_ledword(&p); + *pkeylen = read_ledword(&p); + if (*psaltlen > 65536 || *pkeylen > 65536) { + PEMerror(PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + + if (is_encrypted && !*psaltlen) { + PEMerror(PEM_R_INCONSISTENT_HEADER); + return 0; + } + + *in = p; + return 1; +} + +static int +derive_pvk_key(unsigned char *key, const unsigned char *salt, + unsigned int saltlen, const unsigned char *pass, int passlen) +{ + EVP_MD_CTX mctx; + int rv = 1; + + EVP_MD_CTX_init(&mctx); + if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) || + !EVP_DigestUpdate(&mctx, salt, saltlen) || + !EVP_DigestUpdate(&mctx, pass, passlen) || + !EVP_DigestFinal_ex(&mctx, key, NULL)) + rv = 0; + + EVP_MD_CTX_cleanup(&mctx); + return rv; +} + +static EVP_PKEY * +do_PVK_body(const unsigned char **in, unsigned int saltlen, + unsigned int keylen, pem_password_cb *cb, void *u) +{ + EVP_PKEY *ret = NULL; + const unsigned char *p = *in; + unsigned int magic; + unsigned char *enctmp = NULL, *q; + EVP_CIPHER_CTX *cctx = NULL; + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (saltlen) { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + int enctmplen, inlen; + + if (cb) + inlen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (inlen <= 0) { + PEMerror(PEM_R_BAD_PASSWORD_READ); + goto err; + } + enctmp = malloc(keylen + 8); + if (!enctmp) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf, + inlen)) { + goto err; + } + p += saltlen; + /* Copy BLOBHEADER across, decrypt rest */ + memcpy(enctmp, p, 8); + p += 8; + if (keylen < 8) { + PEMerror(PEM_R_PVK_TOO_SHORT); + goto err; + } + inlen = keylen - 8; + q = enctmp + 8; + if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto err; + if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen)) + goto err; + if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen)) + goto err; + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { + q = enctmp + 8; + memset(keybuf + 5, 0, 11); + if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, + NULL)) + goto err; + explicit_bzero(keybuf, 20); + if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen)) + goto err; + if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, + &enctmplen)) + goto err; + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { + PEMerror(PEM_R_BAD_DECRYPT); + goto err; + } + } else + explicit_bzero(keybuf, 20); + p = enctmp; + } + + ret = b2i_PrivateKey(&p, keylen); + + err: + EVP_CIPHER_CTX_free(cctx); + if (enctmp && saltlen) + free(enctmp); + return ret; +} + + +EVP_PKEY * +b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) +{ + unsigned char pvk_hdr[24], *buf = NULL; + const unsigned char *p; + size_t buflen; + EVP_PKEY *ret = NULL; + unsigned int saltlen, keylen; + + if (BIO_read(in, pvk_hdr, 24) != 24) { + PEMerror(PEM_R_PVK_DATA_TOO_SHORT); + return NULL; + } + p = pvk_hdr; + + if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) + return 0; + buflen = keylen + saltlen; + buf = malloc(buflen); + if (!buf) { + PEMerror(ERR_R_MALLOC_FAILURE); + return 0; + } + p = buf; + if (BIO_read(in, buf, buflen) != buflen) { + PEMerror(PEM_R_PVK_DATA_TOO_SHORT); + goto err; + } + ret = do_PVK_body(&p, saltlen, keylen, cb, u); + + err: + freezero(buf, buflen); + return ret; +} +LCRYPTO_ALIAS(b2i_PVK_bio); + +static int +i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb, + void *u) +{ + int outlen = 24, pklen; + unsigned char *p = NULL, *start = NULL, *salt = NULL; + EVP_CIPHER_CTX *cctx = NULL; + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (enclevel != 0) + outlen += PVK_SALTLEN; + pklen = do_i2b(NULL, pk, 0); + if (pklen < 0) + goto err; + outlen += pklen; + start = p = malloc(outlen); + if (!p) { + PEMerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + write_ledword(&p, MS_PVKMAGIC); + write_ledword(&p, 0); + if (pk->type == EVP_PKEY_DSA) + write_ledword(&p, MS_KEYTYPE_SIGN); + else + write_ledword(&p, MS_KEYTYPE_KEYX); + write_ledword(&p, enclevel ? 1 : 0); + write_ledword(&p, enclevel ? PVK_SALTLEN : 0); + write_ledword(&p, pklen); + if (enclevel != 0) { + arc4random_buf(p, PVK_SALTLEN); + salt = p; + p += PVK_SALTLEN; + } + do_i2b(&p, pk, 0); + if (enclevel != 0) { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + int enctmplen, inlen; + if (cb) + inlen = cb(psbuf, PEM_BUFSIZE, 1, u); + else + inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); + if (inlen <= 0) { + PEMerror(PEM_R_BAD_PASSWORD_READ); + goto err; + } + if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, + (unsigned char *)psbuf, inlen)) + goto err; + if (enclevel == 1) + memset(keybuf + 5, 0, 11); + p = salt + PVK_SALTLEN + 8; + if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto err; + explicit_bzero(keybuf, 20); + if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8)) + goto err; + if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen)) + goto err; + } + EVP_CIPHER_CTX_free(cctx); + *out = start; + return outlen; + + err: + EVP_CIPHER_CTX_free(cctx); + free(start); + return -1; +} + +int +i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u) +{ + unsigned char *tmp = NULL; + int outlen, wrlen; + + outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + free(tmp); + if (wrlen != outlen) { + PEMerror(PEM_R_BIO_WRITE_FAILURE); + return -1; + } + return outlen; +} +LCRYPTO_ALIAS(i2b_PVK_bio); + +#endif + +#endif diff --git a/Libraries/libressl/crypto/pkcs12/p12_add.c b/Libraries/libressl/crypto/pkcs12/p12_add.c new file mode 100644 index 000000000..93c7c7221 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_add.c @@ -0,0 +1,220 @@ +/* $OpenBSD: p12_add.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "pkcs12_local.h" + +/* Pack an object into an OCTET STRING and turn into a safebag */ + +PKCS12_SAFEBAG * +PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1, int nid2) +{ + PKCS12_BAGS *bag; + PKCS12_SAFEBAG *safebag; + + if (!(bag = PKCS12_BAGS_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(nid1); + if (!ASN1_item_pack(obj, it, &bag->value.octet)) { + PKCS12error(ERR_R_MALLOC_FAILURE); + PKCS12_BAGS_free(bag); + return NULL; + } + if (!(safebag = PKCS12_SAFEBAG_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + PKCS12_BAGS_free(bag); + return NULL; + } + safebag->value.bag = bag; + safebag->type = OBJ_nid2obj(nid2); + return safebag; +} +LCRYPTO_ALIAS(PKCS12_item_pack_safebag); + +/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ +PKCS7 * +PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) +{ + PKCS7 *p7; + + if (!(p7 = PKCS7_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + p7->type = OBJ_nid2obj(NID_pkcs7_data); + if (!(p7->d.data = ASN1_OCTET_STRING_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ASN1_item_pack(sk, &PKCS12_SAFEBAGS_it, &p7->d.data)) { + PKCS12error(PKCS12_R_CANT_PACK_STRUCTURE); + goto err; + } + return p7; + +err: + PKCS7_free(p7); + return NULL; +} +LCRYPTO_ALIAS(PKCS12_pack_p7data); + +/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ +STACK_OF(PKCS12_SAFEBAG) * +PKCS12_unpack_p7data(PKCS7 *p7) +{ + if (!PKCS7_type_is_data(p7)) { + PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } + return ASN1_item_unpack(p7->d.data, &PKCS12_SAFEBAGS_it); +} +LCRYPTO_ALIAS(PKCS12_unpack_p7data); + +/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ + +PKCS7 * +PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, STACK_OF(PKCS12_SAFEBAG) *bags) +{ + PKCS7 *p7; + X509_ALGOR *pbe; + const EVP_CIPHER *pbe_ciph; + + if (!(p7 = PKCS7_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { + PKCS12error(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); + goto err; + } + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); + else + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + + if (!pbe) { + PKCS12error(ERR_R_MALLOC_FAILURE); + goto err; + } + X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); + p7->d.encrypted->enc_data->algorithm = pbe; + ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); + if (!(p7->d.encrypted->enc_data->enc_data = PKCS12_item_i2d_encrypt( + pbe, &PKCS12_SAFEBAGS_it, pass, passlen, bags, 1))) { + PKCS12error(PKCS12_R_ENCRYPT_ERROR); + goto err; + } + + return p7; + +err: + PKCS7_free(p7); + return NULL; +} +LCRYPTO_ALIAS(PKCS12_pack_p7encdata); + +STACK_OF(PKCS12_SAFEBAG) * +PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen) +{ + if (!PKCS7_type_is_encrypted(p7)) + return NULL; + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, + &PKCS12_SAFEBAGS_it, pass, passlen, + p7->d.encrypted->enc_data->enc_data, 1); +} +LCRYPTO_ALIAS(PKCS12_unpack_p7encdata); + +PKCS8_PRIV_KEY_INFO * +PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, const char *pass, int passlen) +{ + return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); +} +LCRYPTO_ALIAS(PKCS12_decrypt_skey); + +int +PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) +{ + if (ASN1_item_pack(safes, &PKCS12_AUTHSAFES_it, + &p12->authsafes->d.data)) + return 1; + return 0; +} +LCRYPTO_ALIAS(PKCS12_pack_authsafes); + +STACK_OF(PKCS7) * +PKCS12_unpack_authsafes(const PKCS12 *p12) +{ + if (!PKCS7_type_is_data(p12->authsafes)) { + PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } + return ASN1_item_unpack(p12->authsafes->d.data, + &PKCS12_AUTHSAFES_it); +} +LCRYPTO_ALIAS(PKCS12_unpack_authsafes); diff --git a/Libraries/libressl/crypto/pkcs12/p12_asn.c b/Libraries/libressl/crypto/pkcs12/p12_asn.c new file mode 100644 index 000000000..a9decccb5 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_asn.c @@ -0,0 +1,491 @@ +/* $OpenBSD: p12_asn.c,v 1.14 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "pkcs12_local.h" + +/* PKCS#12 ASN1 module */ + +static const ASN1_TEMPLATE PKCS12_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS12, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS12, authsafes), + .field_name = "authsafes", + .item = &PKCS7_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS12, mac), + .field_name = "mac", + .item = &PKCS12_MAC_DATA_it, + }, +}; + +const ASN1_ITEM PKCS12_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS12_seq_tt, + .tcount = sizeof(PKCS12_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS12), + .sname = "PKCS12", +}; + + +PKCS12 * +d2i_PKCS12(PKCS12 **a, const unsigned char **in, long len) +{ + return (PKCS12 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS12_it); +} +LCRYPTO_ALIAS(d2i_PKCS12); + +int +i2d_PKCS12(PKCS12 *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_it); +} +LCRYPTO_ALIAS(i2d_PKCS12); + +PKCS12 * +PKCS12_new(void) +{ + return (PKCS12 *)ASN1_item_new(&PKCS12_it); +} +LCRYPTO_ALIAS(PKCS12_new); + +void +PKCS12_free(PKCS12 *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS12_it); +} +LCRYPTO_ALIAS(PKCS12_free); + +static const ASN1_TEMPLATE PKCS12_MAC_DATA_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS12_MAC_DATA, dinfo), + .field_name = "dinfo", + .item = &X509_SIG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS12_MAC_DATA, salt), + .field_name = "salt", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS12_MAC_DATA, iter), + .field_name = "iter", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM PKCS12_MAC_DATA_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS12_MAC_DATA_seq_tt, + .tcount = sizeof(PKCS12_MAC_DATA_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS12_MAC_DATA), + .sname = "PKCS12_MAC_DATA", +}; + + +PKCS12_MAC_DATA * +d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, const unsigned char **in, long len) +{ + return (PKCS12_MAC_DATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS12_MAC_DATA_it); +} +LCRYPTO_ALIAS(d2i_PKCS12_MAC_DATA); + +int +i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_MAC_DATA_it); +} +LCRYPTO_ALIAS(i2d_PKCS12_MAC_DATA); + +PKCS12_MAC_DATA * +PKCS12_MAC_DATA_new(void) +{ + return (PKCS12_MAC_DATA *)ASN1_item_new(&PKCS12_MAC_DATA_it); +} +LCRYPTO_ALIAS(PKCS12_MAC_DATA_new); + +void +PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS12_MAC_DATA_it); +} +LCRYPTO_ALIAS(PKCS12_MAC_DATA_free); + +static const ASN1_TEMPLATE bag_default_tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_BAGS, value.other), + .field_name = "value.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE PKCS12_BAGS_adbtbl[] = { + { + .value = NID_x509Certificate, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_BAGS, value.x509cert), + .field_name = "value.x509cert", + .item = &ASN1_OCTET_STRING_it, + }, + + }, + { + .value = NID_x509Crl, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_BAGS, value.x509crl), + .field_name = "value.x509crl", + .item = &ASN1_OCTET_STRING_it, + }, + + }, + { + .value = NID_sdsiCertificate, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_BAGS, value.sdsicert), + .field_name = "value.sdsicert", + .item = &ASN1_IA5STRING_it, + }, + + }, +}; + +static const ASN1_ADB PKCS12_BAGS_adb = { + .flags = 0, + .offset = offsetof(PKCS12_BAGS, type), + .tbl = PKCS12_BAGS_adbtbl, + .tblcount = sizeof(PKCS12_BAGS_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &bag_default_tt, + .null_tt = NULL, +}; + +static const ASN1_TEMPLATE PKCS12_BAGS_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS12_BAGS, type), + .field_name = "type", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "PKCS12_BAGS", + .item = (const ASN1_ITEM *)&PKCS12_BAGS_adb, + }, +}; + +const ASN1_ITEM PKCS12_BAGS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS12_BAGS_seq_tt, + .tcount = sizeof(PKCS12_BAGS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS12_BAGS), + .sname = "PKCS12_BAGS", +}; + + +PKCS12_BAGS * +d2i_PKCS12_BAGS(PKCS12_BAGS **a, const unsigned char **in, long len) +{ + return (PKCS12_BAGS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS12_BAGS_it); +} +LCRYPTO_ALIAS(d2i_PKCS12_BAGS); + +int +i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_BAGS_it); +} +LCRYPTO_ALIAS(i2d_PKCS12_BAGS); + +PKCS12_BAGS * +PKCS12_BAGS_new(void) +{ + return (PKCS12_BAGS *)ASN1_item_new(&PKCS12_BAGS_it); +} +LCRYPTO_ALIAS(PKCS12_BAGS_new); + +void +PKCS12_BAGS_free(PKCS12_BAGS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS12_BAGS_it); +} +LCRYPTO_ALIAS(PKCS12_BAGS_free); + +static const ASN1_TEMPLATE safebag_default_tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.other), + .field_name = "value.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE PKCS12_SAFEBAG_adbtbl[] = { + { + .value = NID_keyBag, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.keybag), + .field_name = "value.keybag", + .item = &PKCS8_PRIV_KEY_INFO_it, + }, + + }, + { + .value = NID_pkcs8ShroudedKeyBag, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.shkeybag), + .field_name = "value.shkeybag", + .item = &X509_SIG_it, + }, + + }, + { + .value = NID_safeContentsBag, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.safes), + .field_name = "value.safes", + .item = &PKCS12_SAFEBAG_it, + }, + }, + { + .value = NID_certBag, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.bag), + .field_name = "value.bag", + .item = &PKCS12_BAGS_it, + }, + + }, + { + .value = NID_crlBag, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.bag), + .field_name = "value.bag", + .item = &PKCS12_BAGS_it, + }, + + }, + { + .value = NID_secretBag, + .tt = { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, value.bag), + .field_name = "value.bag", + .item = &PKCS12_BAGS_it, + }, + + }, +}; + +static const ASN1_ADB PKCS12_SAFEBAG_adb = { + .flags = 0, + .offset = offsetof(PKCS12_SAFEBAG, type), + .tbl = PKCS12_SAFEBAG_adbtbl, + .tblcount = sizeof(PKCS12_SAFEBAG_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &safebag_default_tt, + .null_tt = NULL, +}; + +static const ASN1_TEMPLATE PKCS12_SAFEBAG_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, type), + .field_name = "type", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "PKCS12_SAFEBAG", + .item = (const ASN1_ITEM *)&PKCS12_SAFEBAG_adb, + }, + { + .flags = ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS12_SAFEBAG, attrib), + .field_name = "attrib", + .item = &X509_ATTRIBUTE_it, + }, +}; + +const ASN1_ITEM PKCS12_SAFEBAG_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS12_SAFEBAG_seq_tt, + .tcount = sizeof(PKCS12_SAFEBAG_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS12_SAFEBAG), + .sname = "PKCS12_SAFEBAG", +}; + + +PKCS12_SAFEBAG * +d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, const unsigned char **in, long len) +{ + return (PKCS12_SAFEBAG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS12_SAFEBAG_it); +} +LCRYPTO_ALIAS(d2i_PKCS12_SAFEBAG); + +int +i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_SAFEBAG_it); +} +LCRYPTO_ALIAS(i2d_PKCS12_SAFEBAG); + +PKCS12_SAFEBAG * +PKCS12_SAFEBAG_new(void) +{ + return (PKCS12_SAFEBAG *)ASN1_item_new(&PKCS12_SAFEBAG_it); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_new); + +void +PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS12_SAFEBAG_it); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_free); + +/* SEQUENCE OF SafeBag */ +static const ASN1_TEMPLATE PKCS12_SAFEBAGS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "PKCS12_SAFEBAGS", + .item = &PKCS12_SAFEBAG_it, +}; + +const ASN1_ITEM PKCS12_SAFEBAGS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &PKCS12_SAFEBAGS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "PKCS12_SAFEBAGS", +}; + +/* Authsafes: SEQUENCE OF PKCS7 */ +static const ASN1_TEMPLATE PKCS12_AUTHSAFES_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "PKCS12_AUTHSAFES", + .item = &PKCS7_it, +}; + +const ASN1_ITEM PKCS12_AUTHSAFES_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &PKCS12_AUTHSAFES_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "PKCS12_AUTHSAFES", +}; diff --git a/Libraries/libressl/crypto/pkcs12/p12_attr.c b/Libraries/libressl/crypto/pkcs12/p12_attr.c new file mode 100644 index 000000000..d43b205a0 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_attr.c @@ -0,0 +1,164 @@ +/* $OpenBSD: p12_attr.c,v 1.20 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include "pkcs12_local.h" +#include "x509_local.h" + +/* Add a local keyid to a safebag */ + +int +PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID, + V_ASN1_OCTET_STRING, name, namelen)) + return 1; + else + return 0; +} +LCRYPTO_ALIAS(PKCS12_add_localkeyid); + +/* Add key usage to PKCS#8 structure */ + +int +PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage) +{ + unsigned char us_val = (unsigned char)usage; + + return PKCS8_pkey_add1_attr_by_NID(p8, NID_key_usage, V_ASN1_BIT_STRING, + &us_val, 1); +} +LCRYPTO_ALIAS(PKCS8_add_keyusage); + +/* Add a friendlyname to a safebag */ + +int +PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, + MBSTRING_ASC, (unsigned char *)name, namelen)) + return 1; + else + return 0; +} +LCRYPTO_ALIAS(PKCS12_add_friendlyname_asc); + + +int +PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, + int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, + MBSTRING_BMP, name, namelen)) + return 1; + else + return 0; +} +LCRYPTO_ALIAS(PKCS12_add_friendlyname_uni); + +int +PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name, + MBSTRING_ASC, (unsigned char *)name, namelen)) + return 1; + else + return 0; +} +LCRYPTO_ALIAS(PKCS12_add_CSPName_asc); + +ASN1_TYPE * +PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid) +{ + X509_ATTRIBUTE *attrib; + int i; + + if (!attrs) + return NULL; + for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { + attrib = sk_X509_ATTRIBUTE_value(attrs, i); + if (OBJ_obj2nid(attrib->object) == attr_nid) + return sk_ASN1_TYPE_value(attrib->set, 0); + } + return NULL; +} +LCRYPTO_ALIAS(PKCS12_get_attr_gen); + +char * +PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) +{ + const ASN1_TYPE *atype; + + if (!(atype = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName))) + return NULL; + if (atype->type != V_ASN1_BMPSTRING) + return NULL; + return OPENSSL_uni2asc(atype->value.bmpstring->data, + atype->value.bmpstring->length); +} +LCRYPTO_ALIAS(PKCS12_get_friendlyname); + +const STACK_OF(X509_ATTRIBUTE) * +PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag) +{ + return bag->attrib; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get0_attrs); diff --git a/Libraries/libressl/crypto/pkcs12/p12_crpt.c b/Libraries/libressl/crypto/pkcs12/p12_crpt.c new file mode 100644 index 000000000..e7d30101c --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_crpt.c @@ -0,0 +1,123 @@ +/* $OpenBSD: p12_crpt.c,v 1.17 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +/* PKCS#12 PBE algorithms now in static table */ + +void +PKCS12_PBE_add(void) +{ +} +LCRYPTO_ALIAS(PKCS12_PBE_add); + +int +PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de) +{ + PBEPARAM *pbe; + int saltlen, iter, ret; + unsigned char *salt; + const unsigned char *pbuf; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + + /* Extract useful info from parameter */ + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + PKCS12error(PKCS12_R_DECODE_ERROR); + return 0; + } + + pbuf = param->value.sequence->data; + if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { + PKCS12error(PKCS12_R_DECODE_ERROR); + return 0; + } + + if (!pbe->iter) + iter = 1; + else if ((iter = ASN1_INTEGER_get(pbe->iter)) <= 0) { + PKCS12error(PKCS12_R_DECODE_ERROR); + PBEPARAM_free(pbe); + return 0; + } + salt = pbe->salt->data; + saltlen = pbe->salt->length; + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID, + iter, EVP_CIPHER_key_length(cipher), key, md)) { + PKCS12error(PKCS12_R_KEY_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID, + iter, EVP_CIPHER_iv_length(cipher), iv, md)) { + PKCS12error(PKCS12_R_IV_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + PBEPARAM_free(pbe); + ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); + explicit_bzero(key, EVP_MAX_KEY_LENGTH); + explicit_bzero(iv, EVP_MAX_IV_LENGTH); + return ret; +} +LCRYPTO_ALIAS(PKCS12_PBE_keyivgen); diff --git a/Libraries/libressl/crypto/pkcs12/p12_crt.c b/Libraries/libressl/crypto/pkcs12/p12_crt.c new file mode 100644 index 000000000..90a0cbe55 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_crt.c @@ -0,0 +1,357 @@ +/* $OpenBSD: p12_crt.c,v 1.23 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "pkcs12_local.h" + +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag); + +static int +copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) +{ + int idx; + X509_ATTRIBUTE *attr; + + idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); + if (idx < 0) + return 1; + attr = EVP_PKEY_get_attr(pkey, idx); + if (!X509at_add1_attr(&bag->attrib, attr)) + return 0; + return 1; +} + +PKCS12 * +PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, + int keytype) +{ + PKCS12 *p12 = NULL; + STACK_OF(PKCS7) *safes = NULL; + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + PKCS12_SAFEBAG *bag = NULL; + int i; + unsigned char keyid[EVP_MAX_MD_SIZE]; + unsigned int keyidlen = 0; + + /* Set defaults */ + if (!nid_cert) { + nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; + } + if (!nid_key) + nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if (!iter) + iter = PKCS12_DEFAULT_ITER; + if (!mac_iter) + mac_iter = 1; + + if (!pkey && !cert && !ca) { + PKCS12error(PKCS12_R_INVALID_NULL_ARGUMENT); + return NULL; + } + + if (pkey && cert) { + if (!X509_check_private_key(cert, pkey)) + return NULL; + if (!X509_digest(cert, EVP_sha1(), keyid, &keyidlen)) + return NULL; + } + + if (cert) { + bag = PKCS12_add_cert(&bags, cert); + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + goto err; + if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + } + + /* Add all other certificates */ + for (i = 0; i < sk_X509_num(ca); i++) { + if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) + goto err; + } + + if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass)) + goto err; + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + + if (pkey) { + bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); + + if (!bag) + goto err; + + if (!copy_bag_attr(bag, pkey, NID_ms_csp_name)) + goto err; + if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) + goto err; + + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + goto err; + if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + } + + if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) + goto err; + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + + p12 = PKCS12_add_safes(safes, 0); + + if (!p12) + goto err; + + sk_PKCS7_pop_free(safes, PKCS7_free); + + safes = NULL; + + if ((mac_iter != -1) && + !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL)) + goto err; + + return p12; + +err: + if (p12) + PKCS12_free(p12); + if (safes) + sk_PKCS7_pop_free(safes, PKCS7_free); + if (bags) + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + return NULL; +} +LCRYPTO_ALIAS(PKCS12_create); + +PKCS12_SAFEBAG * +PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) +{ + PKCS12_SAFEBAG *bag = NULL; + char *name; + int namelen = -1; + unsigned char *keyid; + int keyidlen = -1; + + /* Add user certificate */ + if (!(bag = PKCS12_x5092certbag(cert))) + goto err; + + /* Use friendlyName and localKeyID in certificate. + * (if present) + */ + name = (char *)X509_alias_get0(cert, &namelen); + if (name && !PKCS12_add_friendlyname(bag, name, namelen)) + goto err; + + keyid = X509_keyid_get0(cert, &keyidlen); + + if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + +err: + if (bag) + PKCS12_SAFEBAG_free(bag); + + return NULL; +} +LCRYPTO_ALIAS(PKCS12_add_cert); + +PKCS12_SAFEBAG * +PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key, int key_usage, + int iter, int nid_key, const char *pass) +{ + PKCS12_SAFEBAG *bag = NULL; + PKCS8_PRIV_KEY_INFO *p8 = NULL; + + /* Make a PKCS#8 structure */ + if (!(p8 = EVP_PKEY2PKCS8(key))) + goto err; + if (key_usage && !PKCS8_add_keyusage(p8, key_usage)) + goto err; + if (nid_key != -1) { + bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, + NULL, 0, iter, p8); + PKCS8_PRIV_KEY_INFO_free(p8); + p8 = NULL; + } else { + bag = PKCS12_SAFEBAG_create0_p8inf(p8); + if (bag != NULL) + p8 = NULL; + } + + if (!bag) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + +err: + if (bag) + PKCS12_SAFEBAG_free(bag); + if (p8) + PKCS8_PRIV_KEY_INFO_free(p8); + + return NULL; +} +LCRYPTO_ALIAS(PKCS12_add_key); + +int +PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int nid_safe, int iter, const char *pass) +{ + PKCS7 *p7 = NULL; + int free_safes = 0; + + if (!*psafes) { + *psafes = sk_PKCS7_new_null(); + if (!*psafes) + return 0; + free_safes = 1; + } else + free_safes = 0; + + if (nid_safe == 0) + nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC; + + if (nid_safe == -1) + p7 = PKCS12_pack_p7data(bags); + else + p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, + iter, bags); + if (!p7) + goto err; + + if (!sk_PKCS7_push(*psafes, p7)) + goto err; + + return 1; + +err: + if (free_safes) { + sk_PKCS7_free(*psafes); + *psafes = NULL; + } + + if (p7) + PKCS7_free(p7); + + return 0; +} +LCRYPTO_ALIAS(PKCS12_add_safe); + +static int +pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag) +{ + int free_bags; + + if (!pbags) + return 1; + if (!*pbags) { + *pbags = sk_PKCS12_SAFEBAG_new_null(); + if (!*pbags) + return 0; + free_bags = 1; + } else + free_bags = 0; + + if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) { + if (free_bags) { + sk_PKCS12_SAFEBAG_free(*pbags); + *pbags = NULL; + } + return 0; + } + + return 1; +} + +PKCS12 * +PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) +{ + PKCS12 *p12; + + if (nid_p7 <= 0) + nid_p7 = NID_pkcs7_data; + p12 = PKCS12_init(nid_p7); + + if (!p12) + return NULL; + + if (!PKCS12_pack_authsafes(p12, safes)) { + PKCS12_free(p12); + return NULL; + } + + return p12; +} +LCRYPTO_ALIAS(PKCS12_add_safes); diff --git a/Libraries/libressl/crypto/pkcs12/p12_decr.c b/Libraries/libressl/crypto/pkcs12/p12_decr.c new file mode 100644 index 000000000..ea7f6a5ff --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_decr.c @@ -0,0 +1,189 @@ +/* $OpenBSD: p12_decr.c,v 1.24 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +#include "evp_local.h" + +/* Encrypt/Decrypt a buffer based on password and algor, result in a + * malloc'ed buffer + */ + +unsigned char * +PKCS12_pbe_crypt(const X509_ALGOR *algor, const char *pass, int passlen, + const unsigned char *in, int inlen, unsigned char **data, int *datalen, + int en_de) +{ + unsigned char *out; + int outlen, i; + EVP_CIPHER_CTX ctx; + + EVP_CIPHER_CTX_init(&ctx); + /* Decrypt data */ + if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, + algor->parameter, &ctx, en_de)) { + out = NULL; + PKCS12error(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); + goto err; + } + + if (!(out = malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { + PKCS12error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) { + free(out); + out = NULL; + PKCS12error(ERR_R_EVP_LIB); + goto err; + } + + outlen = i; + if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) { + free(out); + out = NULL; + PKCS12error(PKCS12_R_PKCS12_CIPHERFINAL_ERROR); + goto err; + } + outlen += i; + if (datalen) + *datalen = outlen; + if (data) + *data = out; + +err: + EVP_CIPHER_CTX_cleanup(&ctx); + return out; + +} +LCRYPTO_ALIAS(PKCS12_pbe_crypt); + +/* Decrypt an OCTET STRING and decode ASN1 structure + * if zbuf set zero buffer after use. + */ + +void * +PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, const ASN1_OCTET_STRING *oct, int zbuf) +{ + unsigned char *out; + const unsigned char *p; + void *ret; + int outlen; + + if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, + &out, &outlen, 0)) { + PKCS12error(PKCS12_R_PKCS12_PBE_CRYPT_ERROR); + return NULL; + } + p = out; + ret = ASN1_item_d2i(NULL, &p, outlen, it); + if (zbuf) + explicit_bzero(out, outlen); + if (!ret) + PKCS12error(PKCS12_R_DECODE_ERROR); + free(out); + return ret; +} +LCRYPTO_ALIAS(PKCS12_item_decrypt_d2i); + +/* Encode ASN1 structure and encrypt, return OCTET STRING + * if zbuf set zero encoding. + */ + +ASN1_OCTET_STRING * +PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf) +{ + ASN1_OCTET_STRING *oct; + unsigned char *in = NULL; + int inlen; + + if (!(oct = ASN1_OCTET_STRING_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + inlen = ASN1_item_i2d(obj, &in, it); + if (!in) { + PKCS12error(PKCS12_R_ENCODE_ERROR); + goto err; + } + if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data, + &oct->length, 1)) { + PKCS12error(PKCS12_R_ENCRYPT_ERROR); + goto err; + } + if (zbuf) + explicit_bzero(in, inlen); + free(in); + return oct; + +err: + free(in); + ASN1_OCTET_STRING_free(oct); + return NULL; +} +LCRYPTO_ALIAS(PKCS12_item_i2d_encrypt); + +IMPLEMENT_PKCS12_STACK_OF(PKCS7) diff --git a/Libraries/libressl/crypto/pkcs12/p12_init.c b/Libraries/libressl/crypto/pkcs12/p12_init.c new file mode 100644 index 000000000..09ff0d559 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_init.c @@ -0,0 +1,101 @@ +/* $OpenBSD: p12_init.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "pkcs12_local.h" + +/* Initialise a PKCS12 structure to take data */ + +PKCS12 * +PKCS12_init(int mode) +{ + PKCS12 *pkcs12; + + if (!(pkcs12 = PKCS12_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!ASN1_INTEGER_set(pkcs12->version, 3)) + goto err; + if ((pkcs12->authsafes->type = OBJ_nid2obj(mode)) == NULL) + goto err; + switch (mode) { + case NID_pkcs7_data: + if (!(pkcs12->authsafes->d.data = + ASN1_OCTET_STRING_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + PKCS12error(PKCS12_R_UNSUPPORTED_PKCS12_MODE); + goto err; + } + + return pkcs12; + +err: + if (pkcs12 != NULL) + PKCS12_free(pkcs12); + return NULL; +} +LCRYPTO_ALIAS(PKCS12_init); diff --git a/Libraries/libressl/crypto/pkcs12/p12_key.c b/Libraries/libressl/crypto/pkcs12/p12_key.c new file mode 100644 index 000000000..8812f1c06 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_key.c @@ -0,0 +1,197 @@ +/* $OpenBSD: p12_key.c,v 1.34 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +#include "evp_local.h" + +/* PKCS12 compatible key/IV generation */ +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +int +PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, unsigned char *out, + const EVP_MD *md_type) +{ + int ret; + unsigned char *unipass; + int uniplen; + + if (!pass) { + unipass = NULL; + uniplen = 0; + } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return 0; + } + ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, + id, iter, n, out, md_type); + if (ret <= 0) + return 0; + freezero(unipass, uniplen); + return ret; +} +LCRYPTO_ALIAS(PKCS12_key_gen_asc); + +int +PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, unsigned char *out, + const EVP_MD *md_type) +{ + EVP_MD_CTX *ctx = NULL; + unsigned char *B = NULL, *D = NULL, *I = NULL, *Ai = NULL; + unsigned char *p; + int Slen, Plen, Ilen; + int i, j, u, v; + int ret = 0; + + if ((ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if ((v = EVP_MD_block_size(md_type)) <= 0) + goto err; + if ((u = EVP_MD_size(md_type)) <= 0) + goto err; + + if ((D = malloc(v)) == NULL) + goto err; + if ((Ai = malloc(u)) == NULL) + goto err; + if ((B = malloc(v + 1)) == NULL) + goto err; + + Slen = v * ((saltlen + v - 1) / v); + + Plen = 0; + if (passlen) + Plen = v * ((passlen + v - 1) / v); + + Ilen = Slen + Plen; + + if ((I = malloc(Ilen)) == NULL) + goto err; + + for (i = 0; i < v; i++) + D[i] = id; + + p = I; + for (i = 0; i < Slen; i++) + *p++ = salt[i % saltlen]; + for (i = 0; i < Plen; i++) + *p++ = pass[i % passlen]; + + for (;;) { + if (!EVP_DigestInit_ex(ctx, md_type, NULL)) + goto err; + if (!EVP_DigestUpdate(ctx, D, v)) + goto err; + if (!EVP_DigestUpdate(ctx, I, Ilen)) + goto err; + if (!EVP_DigestFinal_ex(ctx, Ai, NULL)) + goto err; + for (j = 1; j < iter; j++) { + if (!EVP_DigestInit_ex(ctx, md_type, NULL)) + goto err; + if (!EVP_DigestUpdate(ctx, Ai, u)) + goto err; + if (!EVP_DigestFinal_ex(ctx, Ai, NULL)) + goto err; + } + memcpy(out, Ai, min(n, u)); + if (u >= n) { + ret = 1; + goto end; + } + n -= u; + out += u; + for (j = 0; j < v; j++) + B[j] = Ai[j % u]; + + for (j = 0; j < Ilen; j += v) { + uint16_t c = 1; + int k; + + /* Work out I[j] = I[j] + B + 1. */ + for (k = v - 1; k >= 0; k--) { + c += I[j + k] + B[k]; + I[j + k] = (unsigned char)c; + c >>= 8; + } + } + } + + err: + PKCS12error(ERR_R_MALLOC_FAILURE); + + end: + free(Ai); + free(B); + free(D); + free(I); + EVP_MD_CTX_free(ctx); + + return ret; +} +LCRYPTO_ALIAS(PKCS12_key_gen_uni); diff --git a/Libraries/libressl/crypto/pkcs12/p12_kiss.c b/Libraries/libressl/crypto/pkcs12/p12_kiss.c new file mode 100644 index 000000000..48bbd137c --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_kiss.c @@ -0,0 +1,299 @@ +/* $OpenBSD: p12_kiss.c,v 1.27 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "pkcs12_local.h" + +/* Simplified PKCS#12 routines */ + +static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +/* Parse and decrypt a PKCS#12 structure returning user key, user cert + * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, + * or it should point to a valid STACK structure. pkey and cert can be + * passed unitialised. + */ + +int +PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca) +{ + STACK_OF(X509) *ocerts = NULL; + X509 *x = NULL; + + if (pkey != NULL) + *pkey = NULL; + if (cert != NULL) + *cert = NULL; + + if (p12 == NULL) { + PKCS12error(PKCS12_R_INVALID_NULL_PKCS12_POINTER); + goto err; + } + + /* Check the mac */ + + /* If password is zero length or NULL then try verifying both cases + * to determine which password is correct. The reason for this is that + * under PKCS#12 password based encryption no password and a zero length + * password are two different things... + */ + + if (pass == NULL || *pass == '\0') { + if (PKCS12_verify_mac(p12, NULL, 0)) + pass = NULL; + else if (PKCS12_verify_mac(p12, "", 0)) + pass = ""; + else { + PKCS12error(PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + } else if (!PKCS12_verify_mac(p12, pass, -1)) { + PKCS12error(PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + + /* Allocate stack for other certificates */ + if ((ocerts = sk_X509_new_null()) == NULL) { + PKCS12error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { + PKCS12error(PKCS12_R_PARSE_ERROR); + goto err; + } + + while ((x = sk_X509_pop(ocerts)) != NULL) { + if (pkey != NULL && *pkey != NULL && + cert != NULL && *cert == NULL) { + ERR_set_mark(); + if (X509_check_private_key(x, *pkey)) { + *cert = x; + x = NULL; + } + ERR_pop_to_mark(); + } + + if (ca != NULL && x != NULL) { + if (*ca == NULL) + *ca = sk_X509_new_null(); + if (*ca == NULL) + goto err; + if (!sk_X509_push(*ca, x)) + goto err; + x = NULL; + } + X509_free(x); + x = NULL; + } + + sk_X509_pop_free(ocerts, X509_free); + + return 1; + +err: + if (pkey != NULL) + EVP_PKEY_free(*pkey); + if (cert != NULL) + X509_free(*cert); + X509_free(x); + sk_X509_pop_free(ocerts, X509_free); + + return 0; +} +LCRYPTO_ALIAS(PKCS12_parse); + +/* Parse the outer PKCS#12 structure */ + +static int +parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, + STACK_OF(X509) *ocerts) +{ + STACK_OF(PKCS7) *asafes; + STACK_OF(PKCS12_SAFEBAG) *bags; + int i, bagnid; + PKCS7 *p7; + + if (!(asafes = PKCS12_unpack_authsafes(p12))) + return 0; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, pass, passlen); + } else + continue; + if (!bags) { + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + } + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 1; +} + +static int +parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + int i; + + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), pass, passlen, + pkey, ocerts)) + return 0; + } + return 1; +} + +static int +parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, + STACK_OF(X509) *ocerts) +{ + PKCS8_PRIV_KEY_INFO *p8; + X509 *x509; + const ASN1_TYPE *attrib; + ASN1_BMPSTRING *fname = NULL; + ASN1_OCTET_STRING *lkid = NULL; + + if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName))) + fname = attrib->value.bmpstring; + + if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID))) + lkid = attrib->value.octet_string; + + switch (OBJ_obj2nid(bag->type)) { + case NID_keyBag: + if (!pkey || *pkey) + return 1; + if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) + return 0; + break; + + case NID_pkcs8ShroudedKeyBag: + if (!pkey || *pkey) + return 1; + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) + return 0; + *pkey = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (!(*pkey)) + return 0; + break; + + case NID_certBag: + if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate ) + return 1; + if (!(x509 = PKCS12_certbag2x509(bag))) + return 0; + if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { + X509_free(x509); + return 0; + } + if (fname) { + int len, r; + unsigned char *data = NULL; + len = ASN1_STRING_to_UTF8(&data, fname); + if (len >= 0) { + r = X509_alias_set1(x509, data, len); + free(data); + if (!r) { + X509_free(x509); + return 0; + } + } + } + + if (!sk_X509_push(ocerts, x509)) { + X509_free(x509); + return 0; + } + + break; + + case NID_safeContentsBag: + return parse_bags(bag->value.safes, pass, passlen, + pkey, ocerts); + break; + + default: + return 1; + break; + } + return 1; +} diff --git a/Libraries/libressl/crypto/pkcs12/p12_mutl.c b/Libraries/libressl/crypto/pkcs12/p12_mutl.c new file mode 100644 index 000000000..f0e6df9eb --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_mutl.c @@ -0,0 +1,263 @@ +/* $OpenBSD: p12_mutl.c,v 1.35 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_HMAC + +#include +#include +#include + +#include "evp_local.h" +#include "hmac_local.h" +#include "pkcs12_local.h" +#include "x509_local.h" + +int +PKCS12_mac_present(const PKCS12 *p12) +{ + return p12->mac != NULL; +} +LCRYPTO_ALIAS(PKCS12_mac_present); + +void +PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, const X509_ALGOR **pmacalg, + const ASN1_OCTET_STRING **psalt, const ASN1_INTEGER **piter, + const PKCS12 *p12) +{ + if (p12->mac == NULL) { + if (pmac != NULL) + *pmac = NULL; + if (pmacalg != NULL) + *pmacalg = NULL; + if (psalt != NULL) + *psalt = NULL; + if (piter != NULL) + *piter = NULL; + return; + } + + if (pmac != NULL) + *pmac = p12->mac->dinfo->digest; + if (pmacalg != NULL) + *pmacalg = p12->mac->dinfo->algor; + if (psalt != NULL) + *psalt = p12->mac->salt; + if (piter != NULL) + *piter = p12->mac->iter; +} +LCRYPTO_ALIAS(PKCS12_get0_mac); + +/* Generate a MAC */ +int +PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen) +{ + const EVP_MD *md_type; + HMAC_CTX *hmac = NULL; + unsigned char key[EVP_MAX_MD_SIZE], *salt; + int saltlen, iter; + int md_size; + int ret = 0; + + if (!PKCS7_type_is_data(p12->authsafes)) { + PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); + goto err; + } + + salt = p12->mac->salt->data; + saltlen = p12->mac->salt->length; + + iter = 1; + if (p12->mac->iter != NULL) { + if ((iter = ASN1_INTEGER_get(p12->mac->iter)) <= 0) { + PKCS12error(PKCS12_R_DECODE_ERROR); + goto err; + } + } + + md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm); + if (md_type == NULL) { + PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); + goto err; + } + + if ((md_size = EVP_MD_size(md_type)) < 0) + goto err; + + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, + md_size, key, md_type)) { + PKCS12error(PKCS12_R_KEY_GEN_ERROR); + goto err; + } + + if ((hmac = HMAC_CTX_new()) == NULL) + goto err; + if (!HMAC_Init_ex(hmac, key, md_size, md_type, NULL)) + goto err; + if (!HMAC_Update(hmac, p12->authsafes->d.data->data, + p12->authsafes->d.data->length)) + goto err; + if (!HMAC_Final(hmac, mac, maclen)) + goto err; + + ret = 1; + + err: + explicit_bzero(key, sizeof(key)); + HMAC_CTX_free(hmac); + + return ret; +} +LCRYPTO_ALIAS(PKCS12_gen_mac); + +/* Verify the mac */ +int +PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + + if (p12->mac == NULL) { + PKCS12error(PKCS12_R_MAC_ABSENT); + return 0; + } + if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { + PKCS12error(PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) || + memcmp(mac, p12->mac->dinfo->digest->data, maclen)) + return 0; + return 1; +} +LCRYPTO_ALIAS(PKCS12_verify_mac); + +/* Set a mac */ + +int +PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, const EVP_MD *md_type) +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + + if (!md_type) + md_type = EVP_sha1(); + if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == + PKCS12_ERROR) { + PKCS12error(PKCS12_R_MAC_SETUP_ERROR); + return 0; + } + if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { + PKCS12error(PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if (!(ASN1_STRING_set(p12->mac->dinfo->digest, mac, maclen))) { + PKCS12error(PKCS12_R_MAC_STRING_SET_ERROR); + return 0; + } + return 1; +} +LCRYPTO_ALIAS(PKCS12_set_mac); + +/* Set up a mac structure */ +int +PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, + const EVP_MD *md_type) +{ + PKCS12_MAC_DATA_free(p12->mac); + if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) + return PKCS12_ERROR; + if (iter > 1) { + if (!(p12->mac->iter = ASN1_INTEGER_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return 0; + } + } + if (!saltlen) + saltlen = PKCS12_SALT_LEN; + if (!(p12->mac->salt->data = malloc(saltlen))) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->salt->length = saltlen; + if (!salt) + arc4random_buf(p12->mac->salt->data, saltlen); + else + memcpy(p12->mac->salt->data, salt, saltlen); + p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); + if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; + + return 1; +} +LCRYPTO_ALIAS(PKCS12_setup_mac); +#endif diff --git a/Libraries/libressl/crypto/pkcs12/p12_npas.c b/Libraries/libressl/crypto/pkcs12/p12_npas.c new file mode 100644 index 000000000..30dd2ef8c --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_npas.c @@ -0,0 +1,249 @@ +/* $OpenBSD: p12_npas.c,v 1.18 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +#include "pkcs12_local.h" +#include "x509_local.h" + +/* PKCS#12 password change routine */ + +static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass); +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, + const char *newpass); +static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, + const char *newpass); +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); + +/* + * Change the password on a PKCS#12 structure. + */ + +int +PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass) +{ + /* Check for NULL PKCS12 structure */ + + if (!p12) { + PKCS12error(PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; + } + + /* Check the mac */ + + if (!PKCS12_verify_mac(p12, oldpass, -1)) { + PKCS12error(PKCS12_R_MAC_VERIFY_FAILURE); + return 0; + } + + if (!newpass_p12(p12, oldpass, newpass)) { + PKCS12error(PKCS12_R_PARSE_ERROR); + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(PKCS12_newpass); + +/* Parse the outer PKCS#12 structure */ + +static int +newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) +{ + STACK_OF(PKCS7) *asafes, *newsafes; + STACK_OF(PKCS12_SAFEBAG) *bags; + int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; + PKCS7 *p7, *p7new; + ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + + if (!(asafes = PKCS12_unpack_authsafes(p12))) + return 0; + if (!(newsafes = sk_PKCS7_new_null())) + return 0; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); + if (!alg_get(p7->d.encrypted->enc_data->algorithm, + &pbe_nid, &pbe_iter, &pbe_saltlen)) { + sk_PKCS12_SAFEBAG_pop_free(bags, + PKCS12_SAFEBAG_free); + bags = NULL; + } + } else + continue; + if (bags == NULL) + goto err; + if (!newpass_bags(bags, oldpass, newpass)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + goto err; + } + /* Repack bag in same form with new password */ + if (bagnid == NID_pkcs7_data) + p7new = PKCS12_pack_p7data(bags); + else + p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, + NULL, pbe_saltlen, pbe_iter, bags); + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + if (p7new == NULL) + goto err; + if (sk_PKCS7_push(newsafes, p7new) == 0) + goto err; + } + sk_PKCS7_pop_free(asafes, PKCS7_free); + + /* Repack safe: save old safe in case of error */ + + p12_data_tmp = p12->authsafes->d.data; + if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) { + p12->authsafes->d.data = p12_data_tmp; + goto err; + } + if (!PKCS12_pack_authsafes(p12, newsafes)) + goto saferr; + + if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) + goto saferr; + if (!(macnew = ASN1_OCTET_STRING_new())) + goto saferr; + if (!ASN1_OCTET_STRING_set(macnew, mac, maclen)) + goto saferr; + ASN1_OCTET_STRING_free(p12->mac->dinfo->digest); + p12->mac->dinfo->digest = macnew; + ASN1_OCTET_STRING_free(p12_data_tmp); + + return 1; + +saferr: + /* Restore old safe */ + ASN1_OCTET_STRING_free(p12->authsafes->d.data); + ASN1_OCTET_STRING_free(macnew); + p12->authsafes->d.data = p12_data_tmp; + return 0; + +err: + sk_PKCS7_pop_free(asafes, PKCS7_free); + sk_PKCS7_pop_free(newsafes, PKCS7_free); + return 0; +} + + +static int +newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, + const char *newpass) +{ + int i; + + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), + oldpass, newpass)) + return 0; + } + return 1; +} + +/* Change password of safebag: only needs handle shrouded keybags */ + +static int +newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, const char *newpass) +{ + PKCS8_PRIV_KEY_INFO *p8; + X509_SIG *p8new; + int p8_nid, p8_saltlen, p8_iter; + + if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag) + return 1; + + if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) + return 0; + if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, + &p8_saltlen)) + return 0; + if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, + p8_iter, p8))) return 0; + X509_SIG_free(bag->value.shkeybag); + bag->value.shkeybag = p8new; + return 1; +} + +static int +alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) +{ + PBEPARAM *pbe; + const unsigned char *p; + + p = alg->parameter->value.sequence->data; + pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); + if (!pbe) + return 0; + *pnid = OBJ_obj2nid(alg->algorithm); + *piter = ASN1_INTEGER_get(pbe->iter); + *psaltlen = pbe->salt->length; + PBEPARAM_free(pbe); + return 1; +} diff --git a/Libraries/libressl/crypto/pkcs12/p12_p8d.c b/Libraries/libressl/crypto/pkcs12/p12_p8d.c new file mode 100644 index 000000000..dd5e8d987 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_p8d.c @@ -0,0 +1,71 @@ +/* $OpenBSD: p12_p8d.c,v 1.11 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include "x509_local.h" + +PKCS8_PRIV_KEY_INFO * +PKCS8_decrypt(const X509_SIG *p8, const char *pass, int passlen) +{ + return PKCS12_item_decrypt_d2i(p8->algor, + &PKCS8_PRIV_KEY_INFO_it, pass, passlen, p8->digest, 1); +} +LCRYPTO_ALIAS(PKCS8_decrypt); diff --git a/Libraries/libressl/crypto/pkcs12/p12_p8e.c b/Libraries/libressl/crypto/pkcs12/p12_p8e.c new file mode 100644 index 000000000..87c4be56a --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_p8e.c @@ -0,0 +1,103 @@ +/* $OpenBSD: p12_p8e.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "x509_local.h" + +X509_SIG * +PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + int passlen, unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf) +{ + X509_SIG *p8 = NULL; + X509_ALGOR *pbe; + + if (!(p8 = X509_SIG_new())) { + PKCS12error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (pbe_nid == -1) + pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); + else + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + if (!pbe) { + PKCS12error(ERR_R_ASN1_LIB); + goto err; + } + X509_ALGOR_free(p8->algor); + p8->algor = pbe; + ASN1_OCTET_STRING_free(p8->digest); + p8->digest = PKCS12_item_i2d_encrypt(pbe, + &PKCS8_PRIV_KEY_INFO_it, pass, passlen, p8inf, 1); + if (!p8->digest) { + PKCS12error(PKCS12_R_ENCRYPT_ERROR); + goto err; + } + + return p8; + +err: + X509_SIG_free(p8); + return NULL; +} +LCRYPTO_ALIAS(PKCS8_encrypt); diff --git a/Libraries/libressl/crypto/pkcs12/p12_sbag.c b/Libraries/libressl/crypto/pkcs12/p12_sbag.c new file mode 100644 index 000000000..b7772b67b --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_sbag.c @@ -0,0 +1,240 @@ +/* $OpenBSD: p12_sbag.c,v 1.8 2023/02/16 08:38:17 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999-2018. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include "pkcs12_local.h" +#include "x509_local.h" + +const ASN1_TYPE * +PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, int attr_nid) +{ + return PKCS12_get_attr_gen(bag->attrib, attr_nid); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get0_attr); + +ASN1_TYPE * +PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid) +{ + return PKCS12_get_attr_gen(p8->attributes, attr_nid); +} +LCRYPTO_ALIAS(PKCS8_get_attr); + +const PKCS8_PRIV_KEY_INFO * +PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag) +{ + if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag) + return NULL; + + return bag->value.keybag; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get0_p8inf); + +const X509_SIG * +PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag) +{ + if (PKCS12_SAFEBAG_get_nid(bag) != NID_pkcs8ShroudedKeyBag) + return NULL; + + return bag->value.shkeybag; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get0_pkcs8); + +const STACK_OF(PKCS12_SAFEBAG) * +PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag) +{ + if (PKCS12_SAFEBAG_get_nid(bag) != NID_safeContentsBag) + return NULL; + + return bag->value.safes; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get0_safes); + +const ASN1_OBJECT * +PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag) +{ + return bag->type; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get0_type); + +int +PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag) +{ + return OBJ_obj2nid(bag->type); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get_nid); + +int +PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag) +{ + int bag_type; + + bag_type = PKCS12_SAFEBAG_get_nid(bag); + + if (bag_type == NID_certBag || bag_type == NID_crlBag || + bag_type == NID_secretBag) + return OBJ_obj2nid(bag->value.bag->type); + + return -1; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get_bag_nid); + +X509 * +PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag) +{ + if (OBJ_obj2nid(bag->type) != NID_certBag) + return NULL; + if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate) + return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, &X509_it); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get1_cert); + +X509_CRL * +PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag) +{ + if (OBJ_obj2nid(bag->type) != NID_crlBag) + return NULL; + if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl) + return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, &X509_CRL_it); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_get1_crl); + +PKCS12_SAFEBAG * +PKCS12_SAFEBAG_create_cert(X509 *x509) +{ + return PKCS12_item_pack_safebag(x509, &X509_it, + NID_x509Certificate, NID_certBag); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_create_cert); + +PKCS12_SAFEBAG * +PKCS12_SAFEBAG_create_crl(X509_CRL *crl) +{ + return PKCS12_item_pack_safebag(crl, &X509_CRL_it, + NID_x509Crl, NID_crlBag); +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_create_crl); + +/* Turn PKCS8 object into a keybag */ + +PKCS12_SAFEBAG * +PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8) +{ + PKCS12_SAFEBAG *bag; + + if ((bag = PKCS12_SAFEBAG_new()) == NULL) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + bag->type = OBJ_nid2obj(NID_keyBag); + bag->value.keybag = p8; + + return bag; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_create0_p8inf); + +/* Turn PKCS8 object into a shrouded keybag */ + +PKCS12_SAFEBAG * +PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8) +{ + PKCS12_SAFEBAG *bag; + + /* Set up the safe bag */ + if ((bag = PKCS12_SAFEBAG_new()) == NULL) { + PKCS12error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); + bag->value.shkeybag = p8; + + return bag; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_create0_pkcs8); + +PKCS12_SAFEBAG * +PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8info) +{ + const EVP_CIPHER *pbe_ciph; + X509_SIG *p8; + PKCS12_SAFEBAG *bag; + + if ((pbe_ciph = EVP_get_cipherbynid(pbe_nid)) != NULL) + pbe_nid = -1; + + if ((p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, + iter, p8info)) == NULL) + return NULL; + + if ((bag = PKCS12_SAFEBAG_create0_pkcs8(p8)) == NULL) { + X509_SIG_free(p8); + return NULL; + } + + return bag; +} +LCRYPTO_ALIAS(PKCS12_SAFEBAG_create_pkcs8_encrypt); diff --git a/Libraries/libressl/crypto/pkcs12/p12_utl.c b/Libraries/libressl/crypto/pkcs12/p12_utl.c new file mode 100644 index 000000000..72692a9ea --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/p12_utl.c @@ -0,0 +1,157 @@ +/* $OpenBSD: p12_utl.c,v 1.21 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include + +#include "pkcs12_local.h" + +/* Cheap and nasty Unicode stuff */ + +unsigned char * +OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen) +{ + size_t ulen, i; + unsigned char *unitmp; + + if (asclen < 0) + ulen = strlen(asc); + else + ulen = (size_t)asclen; + ulen++; + if (ulen == 0) /* unlikely overflow */ + return NULL; + if ((unitmp = reallocarray(NULL, ulen, 2)) == NULL) + return NULL; + ulen *= 2; + /* XXX This interface ought to use unsigned types */ + if (ulen > INT_MAX) { + free(unitmp); + return NULL; + } + for (i = 0; i < ulen - 2; i += 2) { + unitmp[i] = 0; + unitmp[i + 1] = *asc++; + } + /* Make result double-NUL terminated */ + unitmp[ulen - 2] = 0; + unitmp[ulen - 1] = 0; + if (unilen) + *unilen = ulen; + if (uni) + *uni = unitmp; + return unitmp; +} +LCRYPTO_ALIAS(OPENSSL_asc2uni); + +char * +OPENSSL_uni2asc(const unsigned char *uni, int unilen) +{ + size_t asclen, u16len, i; + char *asctmp; + + if (unilen < 0) + return NULL; + + asclen = u16len = (size_t)unilen / 2; + /* If no terminating NUL, allow for one */ + if (unilen == 0 || uni[unilen - 1] != '\0') + asclen++; + if ((asctmp = malloc(asclen)) == NULL) + return NULL; + /* Skip first zero byte */ + uni++; + for (i = 0; i < u16len; i++) { + asctmp[i] = *uni; + uni += 2; + } + asctmp[asclen - 1] = '\0'; + return asctmp; +} +LCRYPTO_ALIAS(OPENSSL_uni2asc); + +int +i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) +{ + return ASN1_item_i2d_bio(&PKCS12_it, bp, p12); +} +LCRYPTO_ALIAS(i2d_PKCS12_bio); + +int +i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) +{ + return ASN1_item_i2d_fp(&PKCS12_it, fp, p12); +} +LCRYPTO_ALIAS(i2d_PKCS12_fp); + +PKCS12 * +d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) +{ + return ASN1_item_d2i_bio(&PKCS12_it, bp, p12); +} +LCRYPTO_ALIAS(d2i_PKCS12_bio); + +PKCS12 * +d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) +{ + return ASN1_item_d2i_fp(&PKCS12_it, fp, p12); +} +LCRYPTO_ALIAS(d2i_PKCS12_fp); diff --git a/Libraries/libressl/crypto/pkcs12/pk12err.c b/Libraries/libressl/crypto/pkcs12/pk12err.c new file mode 100644 index 000000000..3af03528a --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/pk12err.c @@ -0,0 +1,111 @@ +/* $OpenBSD: pk12err.c,v 1.14 2023/02/16 08:38:17 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason) + +static ERR_STRING_DATA PKCS12_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA PKCS12_str_reasons[]= { + {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, + {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"}, + {ERR_REASON(PKCS12_R_DECODE_ERROR) , "decode error"}, + {ERR_REASON(PKCS12_R_ENCODE_ERROR) , "encode error"}, + {ERR_REASON(PKCS12_R_ENCRYPT_ERROR) , "encrypt error"}, + {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE), "error setting encrypted data type"}, + {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER), "invalid null pkcs12 pointer"}, + {ERR_REASON(PKCS12_R_IV_GEN_ERROR) , "iv gen error"}, + {ERR_REASON(PKCS12_R_KEY_GEN_ERROR) , "key gen error"}, + {ERR_REASON(PKCS12_R_MAC_ABSENT) , "mac absent"}, + {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"}, + {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR) , "mac setup error"}, + {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"}, + {ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR) , "mac verify error"}, + {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE) , "mac verify failure"}, + {ERR_REASON(PKCS12_R_PARSE_ERROR) , "parse error"}, + {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), "pkcs12 algor cipherinit error"}, + {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR), "pkcs12 cipherfinal error"}, + {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"}, + {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), "unknown digest algorithm"}, + {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"}, + {0, NULL} +}; + +#endif + +void +ERR_load_PKCS12_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) { + ERR_load_strings(0, PKCS12_str_functs); + ERR_load_strings(0, PKCS12_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_PKCS12_strings); diff --git a/Libraries/libressl/crypto/pkcs12/pkcs12_local.h b/Libraries/libressl/crypto/pkcs12/pkcs12_local.h new file mode 100644 index 000000000..1d6f0558e --- /dev/null +++ b/Libraries/libressl/crypto/pkcs12/pkcs12_local.h @@ -0,0 +1,101 @@ +/* $OpenBSD: pkcs12_local.h,v 1.3 2022/11/26 17:23:18 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PKCS12_LOCAL_H +#define HEADER_PKCS12_LOCAL_H + +__BEGIN_HIDDEN_DECLS + +struct PKCS12_MAC_DATA_st { + X509_SIG *dinfo; + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; /* defaults to 1 */ +}; + +struct PKCS12_st { + ASN1_INTEGER *version; + PKCS12_MAC_DATA *mac; + PKCS7 *authsafes; +}; + +struct PKCS12_SAFEBAG_st { + ASN1_OBJECT *type; + union { + struct pkcs12_bag_st *bag; /* secret, crl and certbag */ + struct pkcs8_priv_key_info_st *keybag; /* keybag */ + X509_SIG *shkeybag; /* shrouded key bag */ + STACK_OF(PKCS12_SAFEBAG) *safes; + ASN1_TYPE *other; + } value; + STACK_OF(X509_ATTRIBUTE) *attrib; +}; + +struct pkcs12_bag_st { + ASN1_OBJECT *type; + union { + ASN1_OCTET_STRING *x509cert; + ASN1_OCTET_STRING *x509crl; + ASN1_OCTET_STRING *octet; + ASN1_IA5STRING *sdsicert; + ASN1_TYPE *other; /* Secret or other bag */ + } value; +}; + +__END_HIDDEN_DECLS + +#endif /* !HEADER_PKCS12_LOCAL_H */ diff --git a/Libraries/libressl/crypto/pkcs7/pk7_asn1.c b/Libraries/libressl/crypto/pkcs7/pk7_asn1.c new file mode 100644 index 000000000..27f410302 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pk7_asn1.c @@ -0,0 +1,1041 @@ +/* $OpenBSD: pk7_asn1.c,v 1.17 2023/04/25 18:04:03 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +/* PKCS#7 ASN1 module */ + +/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ + +static const ASN1_TEMPLATE p7default_tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS7, d.other), + .field_name = "d.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE PKCS7_adbtbl[] = { + { + .value = NID_pkcs7_data, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(PKCS7, d.data), + .field_name = "d.data", + .item = &ASN1_OCTET_STRING_NDEF_it, + }, + + }, + { + .value = NID_pkcs7_signed, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(PKCS7, d.sign), + .field_name = "d.sign", + .item = &PKCS7_SIGNED_it, + }, + + }, + { + .value = NID_pkcs7_enveloped, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(PKCS7, d.enveloped), + .field_name = "d.enveloped", + .item = &PKCS7_ENVELOPE_it, + }, + + }, + { + .value = NID_pkcs7_signedAndEnveloped, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(PKCS7, d.signed_and_enveloped), + .field_name = "d.signed_and_enveloped", + .item = &PKCS7_SIGN_ENVELOPE_it, + }, + + }, + { + .value = NID_pkcs7_digest, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(PKCS7, d.digest), + .field_name = "d.digest", + .item = &PKCS7_DIGEST_it, + }, + + }, + { + .value = NID_pkcs7_encrypted, + .tt = { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, + .tag = 0, + .offset = offsetof(PKCS7, d.encrypted), + .field_name = "d.encrypted", + .item = &PKCS7_ENCRYPT_it, + }, + + }, +}; + +static const ASN1_ADB PKCS7_adb = { + .flags = 0, + .offset = offsetof(PKCS7, type), + .tbl = PKCS7_adbtbl, + .tblcount = sizeof(PKCS7_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &p7default_tt, + .null_tt = NULL, +}; + +/* PKCS#7 streaming support */ +static int +pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + PKCS7 **pp7 = (PKCS7 **)pval; + + switch (operation) { + case ASN1_OP_STREAM_PRE: + if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) + return 0; + /* FALLTHROUGH */ + + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) + return 0; + break; + } + return 1; +} + +static const ASN1_AUX PKCS7_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = pk7_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE PKCS7_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7, type), + .field_name = "type", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "PKCS7", + .item = (const ASN1_ITEM *)&PKCS7_adb, + }, +}; + +const ASN1_ITEM PKCS7_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_seq_tt, + .tcount = sizeof(PKCS7_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &PKCS7_aux, + .size = sizeof(PKCS7), + .sname = "PKCS7", +}; + + +PKCS7 * +d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) +{ + return (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_it); +} +LCRYPTO_ALIAS(d2i_PKCS7); + +int +i2d_PKCS7(PKCS7 *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_it); +} +LCRYPTO_ALIAS(i2d_PKCS7); + +PKCS7 * +PKCS7_new(void) +{ + return (PKCS7 *)ASN1_item_new(&PKCS7_it); +} +LCRYPTO_ALIAS(PKCS7_new); + +void +PKCS7_free(PKCS7 *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_it); +} +LCRYPTO_ALIAS(PKCS7_free); + +PKCS7 * +PKCS7_dup(PKCS7 *x) +{ + return ASN1_item_dup(&PKCS7_it, x); +} +LCRYPTO_ALIAS(PKCS7_dup); + +static const ASN1_TEMPLATE PKCS7_SIGNED_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNED, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(PKCS7_SIGNED, md_algs), + .field_name = "md_algs", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNED, contents), + .field_name = "contents", + .item = &PKCS7_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS7_SIGNED, cert), + .field_name = "cert", + .item = &X509_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(PKCS7_SIGNED, crl), + .field_name = "crl", + .item = &X509_CRL_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(PKCS7_SIGNED, signer_info), + .field_name = "signer_info", + .item = &PKCS7_SIGNER_INFO_it, + }, +}; + +const ASN1_ITEM PKCS7_SIGNED_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_SIGNED_seq_tt, + .tcount = sizeof(PKCS7_SIGNED_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_SIGNED), + .sname = "PKCS7_SIGNED", +}; + + +PKCS7_SIGNED * +d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len) +{ + return (PKCS7_SIGNED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_SIGNED_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_SIGNED); + +int +i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNED_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_SIGNED); + +PKCS7_SIGNED * +PKCS7_SIGNED_new(void) +{ + return (PKCS7_SIGNED *)ASN1_item_new(&PKCS7_SIGNED_it); +} +LCRYPTO_ALIAS(PKCS7_SIGNED_new); + +void +PKCS7_SIGNED_free(PKCS7_SIGNED *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNED_it); +} +LCRYPTO_ALIAS(PKCS7_SIGNED_free); + +/* Minor tweak to operation: free up EVP_PKEY */ +static int +si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; + EVP_PKEY_free(si->pkey); + } + return 1; +} + +static const ASN1_AUX PKCS7_SIGNER_INFO_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = si_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE PKCS7_SIGNER_INFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNER_INFO, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNER_INFO, issuer_and_serial), + .field_name = "issuer_and_serial", + .item = &PKCS7_ISSUER_AND_SERIAL_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNER_INFO, digest_alg), + .field_name = "digest_alg", + .item = &X509_ALGOR_it, + }, + /* NB this should be a SET OF but we use a SEQUENCE OF so the + * original order * is retained when the structure is reencoded. + * Since the attributes are implicitly tagged this will not affect + * the encoding. + */ + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS7_SIGNER_INFO, auth_attr), + .field_name = "auth_attr", + .item = &X509_ATTRIBUTE_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNER_INFO, digest_enc_alg), + .field_name = "digest_enc_alg", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGNER_INFO, enc_digest), + .field_name = "enc_digest", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(PKCS7_SIGNER_INFO, unauth_attr), + .field_name = "unauth_attr", + .item = &X509_ATTRIBUTE_it, + }, +}; + +const ASN1_ITEM PKCS7_SIGNER_INFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_SIGNER_INFO_seq_tt, + .tcount = sizeof(PKCS7_SIGNER_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &PKCS7_SIGNER_INFO_aux, + .size = sizeof(PKCS7_SIGNER_INFO), + .sname = "PKCS7_SIGNER_INFO", +}; + + +PKCS7_SIGNER_INFO * +d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len) +{ + return (PKCS7_SIGNER_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_SIGNER_INFO_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_SIGNER_INFO); + +int +i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNER_INFO_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_SIGNER_INFO); + +PKCS7_SIGNER_INFO * +PKCS7_SIGNER_INFO_new(void) +{ + return (PKCS7_SIGNER_INFO *)ASN1_item_new(&PKCS7_SIGNER_INFO_it); +} +LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_new); + +void +PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNER_INFO_it); +} +LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_free); + +static const ASN1_TEMPLATE PKCS7_ISSUER_AND_SERIAL_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, issuer), + .field_name = "issuer", + .item = &X509_NAME_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, serial), + .field_name = "serial", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_ISSUER_AND_SERIAL_seq_tt, + .tcount = sizeof(PKCS7_ISSUER_AND_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_ISSUER_AND_SERIAL), + .sname = "PKCS7_ISSUER_AND_SERIAL", +}; + + +PKCS7_ISSUER_AND_SERIAL * +d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len) +{ + return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_ISSUER_AND_SERIAL_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_ISSUER_AND_SERIAL); + +int +i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ISSUER_AND_SERIAL_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_ISSUER_AND_SERIAL); + +PKCS7_ISSUER_AND_SERIAL * +PKCS7_ISSUER_AND_SERIAL_new(void) +{ + return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_new(&PKCS7_ISSUER_AND_SERIAL_it); +} +LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_new); + +void +PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ISSUER_AND_SERIAL_it); +} +LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_free); + +static const ASN1_TEMPLATE PKCS7_ENVELOPE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ENVELOPE, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(PKCS7_ENVELOPE, recipientinfo), + .field_name = "recipientinfo", + .item = &PKCS7_RECIP_INFO_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ENVELOPE, enc_data), + .field_name = "enc_data", + .item = &PKCS7_ENC_CONTENT_it, + }, +}; + +const ASN1_ITEM PKCS7_ENVELOPE_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_ENVELOPE_seq_tt, + .tcount = sizeof(PKCS7_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_ENVELOPE), + .sname = "PKCS7_ENVELOPE", +}; + + +PKCS7_ENVELOPE * +d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len) +{ + return (PKCS7_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_ENVELOPE_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_ENVELOPE); + +int +i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENVELOPE_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_ENVELOPE); + +PKCS7_ENVELOPE * +PKCS7_ENVELOPE_new(void) +{ + return (PKCS7_ENVELOPE *)ASN1_item_new(&PKCS7_ENVELOPE_it); +} +LCRYPTO_ALIAS(PKCS7_ENVELOPE_new); + +void +PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENVELOPE_it); +} +LCRYPTO_ALIAS(PKCS7_ENVELOPE_free); + +/* Minor tweak to operation: free up X509 */ +static int +ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; + X509_free(ri->cert); + } + return 1; +} + +static const ASN1_AUX PKCS7_RECIP_INFO_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = ri_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE PKCS7_RECIP_INFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_RECIP_INFO, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_RECIP_INFO, issuer_and_serial), + .field_name = "issuer_and_serial", + .item = &PKCS7_ISSUER_AND_SERIAL_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_RECIP_INFO, key_enc_algor), + .field_name = "key_enc_algor", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_RECIP_INFO, enc_key), + .field_name = "enc_key", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM PKCS7_RECIP_INFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_RECIP_INFO_seq_tt, + .tcount = sizeof(PKCS7_RECIP_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &PKCS7_RECIP_INFO_aux, + .size = sizeof(PKCS7_RECIP_INFO), + .sname = "PKCS7_RECIP_INFO", +}; + + +PKCS7_RECIP_INFO * +d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len) +{ + return (PKCS7_RECIP_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_RECIP_INFO_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_RECIP_INFO); + +int +i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_RECIP_INFO_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_RECIP_INFO); + +PKCS7_RECIP_INFO * +PKCS7_RECIP_INFO_new(void) +{ + return (PKCS7_RECIP_INFO *)ASN1_item_new(&PKCS7_RECIP_INFO_it); +} +LCRYPTO_ALIAS(PKCS7_RECIP_INFO_new); + +void +PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_RECIP_INFO_it); +} +LCRYPTO_ALIAS(PKCS7_RECIP_INFO_free); + +static const ASN1_TEMPLATE PKCS7_ENC_CONTENT_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ENC_CONTENT, content_type), + .field_name = "content_type", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ENC_CONTENT, algorithm), + .field_name = "algorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS7_ENC_CONTENT, enc_data), + .field_name = "enc_data", + .item = &ASN1_OCTET_STRING_NDEF_it, + }, +}; + +const ASN1_ITEM PKCS7_ENC_CONTENT_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_ENC_CONTENT_seq_tt, + .tcount = sizeof(PKCS7_ENC_CONTENT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_ENC_CONTENT), + .sname = "PKCS7_ENC_CONTENT", +}; + + +PKCS7_ENC_CONTENT * +d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len) +{ + return (PKCS7_ENC_CONTENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_ENC_CONTENT_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_ENC_CONTENT); + +int +i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENC_CONTENT_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_ENC_CONTENT); + +PKCS7_ENC_CONTENT * +PKCS7_ENC_CONTENT_new(void) +{ + return (PKCS7_ENC_CONTENT *)ASN1_item_new(&PKCS7_ENC_CONTENT_it); +} +LCRYPTO_ALIAS(PKCS7_ENC_CONTENT_new); + +void +PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENC_CONTENT_it); +} +LCRYPTO_ALIAS(PKCS7_ENC_CONTENT_free); + +static const ASN1_TEMPLATE PKCS7_SIGN_ENVELOPE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, recipientinfo), + .field_name = "recipientinfo", + .item = &PKCS7_RECIP_INFO_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, md_algs), + .field_name = "md_algs", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, enc_data), + .field_name = "enc_data", + .item = &PKCS7_ENC_CONTENT_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, cert), + .field_name = "cert", + .item = &X509_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, crl), + .field_name = "crl", + .item = &X509_CRL_it, + }, + { + .flags = ASN1_TFLG_SET_OF, + .tag = 0, + .offset = offsetof(PKCS7_SIGN_ENVELOPE, signer_info), + .field_name = "signer_info", + .item = &PKCS7_SIGNER_INFO_it, + }, +}; + +const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_SIGN_ENVELOPE_seq_tt, + .tcount = sizeof(PKCS7_SIGN_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_SIGN_ENVELOPE), + .sname = "PKCS7_SIGN_ENVELOPE", +}; + + +PKCS7_SIGN_ENVELOPE * +d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len) +{ + return (PKCS7_SIGN_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_SIGN_ENVELOPE_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_SIGN_ENVELOPE); + +int +i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGN_ENVELOPE_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_SIGN_ENVELOPE); + +PKCS7_SIGN_ENVELOPE * +PKCS7_SIGN_ENVELOPE_new(void) +{ + return (PKCS7_SIGN_ENVELOPE *)ASN1_item_new(&PKCS7_SIGN_ENVELOPE_it); +} +LCRYPTO_ALIAS(PKCS7_SIGN_ENVELOPE_new); + +void +PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGN_ENVELOPE_it); +} +LCRYPTO_ALIAS(PKCS7_SIGN_ENVELOPE_free); + +static const ASN1_TEMPLATE PKCS7_ENCRYPT_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ENCRYPT, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_ENCRYPT, enc_data), + .field_name = "enc_data", + .item = &PKCS7_ENC_CONTENT_it, + }, +}; + +const ASN1_ITEM PKCS7_ENCRYPT_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_ENCRYPT_seq_tt, + .tcount = sizeof(PKCS7_ENCRYPT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_ENCRYPT), + .sname = "PKCS7_ENCRYPT", +}; + + +PKCS7_ENCRYPT * +d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len) +{ + return (PKCS7_ENCRYPT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_ENCRYPT_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_ENCRYPT); + +int +i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENCRYPT_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_ENCRYPT); + +PKCS7_ENCRYPT * +PKCS7_ENCRYPT_new(void) +{ + return (PKCS7_ENCRYPT *)ASN1_item_new(&PKCS7_ENCRYPT_it); +} +LCRYPTO_ALIAS(PKCS7_ENCRYPT_new); + +void +PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENCRYPT_it); +} +LCRYPTO_ALIAS(PKCS7_ENCRYPT_free); + +static const ASN1_TEMPLATE PKCS7_DIGEST_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_DIGEST, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_DIGEST, md), + .field_name = "md", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_DIGEST, contents), + .field_name = "contents", + .item = &PKCS7_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PKCS7_DIGEST, digest), + .field_name = "digest", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM PKCS7_DIGEST_it = { + .itype = ASN1_ITYPE_NDEF_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKCS7_DIGEST_seq_tt, + .tcount = sizeof(PKCS7_DIGEST_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKCS7_DIGEST), + .sname = "PKCS7_DIGEST", +}; + + +PKCS7_DIGEST * +d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len) +{ + return (PKCS7_DIGEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKCS7_DIGEST_it); +} +LCRYPTO_ALIAS(d2i_PKCS7_DIGEST); + +int +i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_DIGEST_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_DIGEST); + +PKCS7_DIGEST * +PKCS7_DIGEST_new(void) +{ + return (PKCS7_DIGEST *)ASN1_item_new(&PKCS7_DIGEST_it); +} +LCRYPTO_ALIAS(PKCS7_DIGEST_new); + +void +PKCS7_DIGEST_free(PKCS7_DIGEST *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKCS7_DIGEST_it); +} +LCRYPTO_ALIAS(PKCS7_DIGEST_free); + +/* Specials for authenticated attributes */ + +/* When signing attributes we want to reorder them to match the sorted + * encoding. + */ + +static const ASN1_TEMPLATE PKCS7_ATTR_SIGN_item_tt = { + .flags = ASN1_TFLG_SET_ORDER, + .tag = 0, + .offset = 0, + .field_name = "PKCS7_ATTRIBUTES", + .item = &X509_ATTRIBUTE_it, +}; + +const ASN1_ITEM PKCS7_ATTR_SIGN_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &PKCS7_ATTR_SIGN_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "PKCS7_ATTR_SIGN", +}; + +/* When verifying attributes we need to use the received order. So + * we use SEQUENCE OF and tag it to SET OF + */ + +static const ASN1_TEMPLATE PKCS7_ATTR_VERIFY_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, + .tag = V_ASN1_SET, + .offset = 0, + .field_name = "PKCS7_ATTRIBUTES", + .item = &X509_ATTRIBUTE_it, +}; + +const ASN1_ITEM PKCS7_ATTR_VERIFY_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &PKCS7_ATTR_VERIFY_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "PKCS7_ATTR_VERIFY", +}; + + +int +PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx) +{ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, + &PKCS7_it, pctx); +} +LCRYPTO_ALIAS(PKCS7_print_ctx); + +PKCS7 * +d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) +{ + return ASN1_item_d2i_bio(&PKCS7_it, bp, p7); +} +LCRYPTO_ALIAS(d2i_PKCS7_bio); + +int +i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) +{ + return ASN1_item_i2d_bio(&PKCS7_it, bp, p7); +} +LCRYPTO_ALIAS(i2d_PKCS7_bio); + +PKCS7 * +d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) +{ + return ASN1_item_d2i_fp(&PKCS7_it, fp, p7); +} +LCRYPTO_ALIAS(d2i_PKCS7_fp); + +int +i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) +{ + return ASN1_item_i2d_fp(&PKCS7_it, fp, p7); +} +LCRYPTO_ALIAS(i2d_PKCS7_fp); + +int +PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, unsigned int *len) +{ + return(ASN1_item_digest(&PKCS7_ISSUER_AND_SERIAL_it, type, + (char *)data, md, len)); +} +LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_digest); diff --git a/Libraries/libressl/crypto/pkcs7/pk7_attr.c b/Libraries/libressl/crypto/pkcs7/pk7_attr.c new file mode 100644 index 000000000..5eff5241e --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pk7_attr.c @@ -0,0 +1,178 @@ +/* $OpenBSD: pk7_attr.c,v 1.14 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap) +{ + ASN1_STRING *seq; + if (!(seq = ASN1_STRING_new())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, + &X509_ALGORS_it); + return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, seq); +} +LCRYPTO_ALIAS(PKCS7_add_attrib_smimecap); + +STACK_OF(X509_ALGOR) * +PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *cap; + const unsigned char *p; + + cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities); + if (!cap || (cap->type != V_ASN1_SEQUENCE)) + return NULL; + p = cap->value.sequence->data; + return (STACK_OF(X509_ALGOR) *) + ASN1_item_d2i(NULL, &p, cap->value.sequence->length, + &X509_ALGORS_it); +} +LCRYPTO_ALIAS(PKCS7_get_smimecap); + +/* Basic smime-capabilities OID and optional integer arg */ +int +PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + X509_ALGOR *alg; + + if (!(alg = X509_ALGOR_new())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = OBJ_nid2obj(nid); + if (arg > 0) { + ASN1_INTEGER *nbit; + + if (!(alg->parameter = ASN1_TYPE_new())) + goto err; + if (!(nbit = ASN1_INTEGER_new())) + goto err; + if (!ASN1_INTEGER_set(nbit, arg)) { + ASN1_INTEGER_free(nbit); + goto err; + } + alg->parameter->value.integer = nbit; + alg->parameter->type = V_ASN1_INTEGER; + } + if (sk_X509_ALGOR_push(sk, alg) == 0) + goto err; + return 1; + +err: + PKCS7error(ERR_R_MALLOC_FAILURE); + X509_ALGOR_free(alg); + return 0; +} +LCRYPTO_ALIAS(PKCS7_simple_smimecap); + +int +PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) +{ + if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType)) + return 0; + if (!coid) + coid = OBJ_nid2obj(NID_pkcs7_data); + return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, coid); +} +LCRYPTO_ALIAS(PKCS7_add_attrib_content_type); + +int +PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) +{ + if (!t && !(t = X509_gmtime_adj(NULL, 0))) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, + V_ASN1_UTCTIME, t); +} +LCRYPTO_ALIAS(PKCS7_add0_attrib_signing_time); + +int +PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, const unsigned char *md, + int mdlen) +{ + ASN1_OCTET_STRING *os; + + os = ASN1_OCTET_STRING_new(); + if (!os) + return 0; + if (!ASN1_STRING_set(os, md, mdlen) || + !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, os)) { + ASN1_OCTET_STRING_free(os); + return 0; + } + return 1; +} +LCRYPTO_ALIAS(PKCS7_add1_attrib_digest); diff --git a/Libraries/libressl/crypto/pkcs7/pk7_doit.c b/Libraries/libressl/crypto/pkcs7/pk7_doit.c new file mode 100644 index 000000000..d5edaedbd --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pk7_doit.c @@ -0,0 +1,1264 @@ +/* $OpenBSD: pk7_doit.c,v 1.52 2023/03/09 18:20:10 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "evp_local.h" +#include "x509_local.h" + +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value); +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); + +static int +PKCS7_type_is_other(PKCS7* p7) +{ + int isOther = 1; + + int nid = OBJ_obj2nid(p7->type); + + switch (nid ) { + case NID_pkcs7_data: + case NID_pkcs7_signed: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_digest: + case NID_pkcs7_encrypted: + isOther = 0; + break; + default: + isOther = 1; + } + + return isOther; + +} + +static ASN1_OCTET_STRING * +PKCS7_get_octet_string(PKCS7 *p7) +{ + if (PKCS7_type_is_data(p7)) + return p7->d.data; + if (PKCS7_type_is_other(p7) && p7->d.other && + (p7->d.other->type == V_ASN1_OCTET_STRING)) + return p7->d.other->value.octet_string; + return NULL; +} + +static int +PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) +{ + BIO *btmp; + const EVP_MD *md; + + if ((btmp = BIO_new(BIO_f_md())) == NULL) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) { + PKCS7error(PKCS7_R_UNKNOWN_DIGEST_TYPE); + goto err; + } + + if (BIO_set_md(btmp, md) <= 0) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + + if (*pbio == NULL) + *pbio = btmp; + else if (!BIO_push(*pbio, btmp)) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + btmp = NULL; + + return 1; + +err: + BIO_free(btmp); + return 0; + +} + +static int +pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkey = NULL; + unsigned char *ek = NULL; + int ret = 0; + size_t eklen; + + pkey = X509_get_pubkey(ri->cert); + if (!pkey) + return 0; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { + PKCS7error(PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) + goto err; + + ek = malloc(eklen); + + if (ek == NULL) { + PKCS7error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) + goto err; + + ASN1_STRING_set0(ri->enc_key, ek, eklen); + ek = NULL; + + ret = 1; + +err: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(pctx); + free(ek); + return ret; +} + + +static int +pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, PKCS7_RECIP_INFO *ri, + EVP_PKEY *pkey, size_t fixlen) +{ + EVP_PKEY_CTX *pctx = NULL; + unsigned char *ek = NULL; + size_t eklen; + + int ret = -1; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return -1; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { + PKCS7error(PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, NULL, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) + goto err; + + ek = malloc(eklen); + if (ek == NULL) { + PKCS7error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, ek, &eklen, ri->enc_key->data, + ri->enc_key->length) <= 0 || eklen == 0 || + (fixlen != 0 && eklen != fixlen)) { + ret = 0; + PKCS7error(ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + + freezero(*pek, *peklen); + + *pek = ek; + *peklen = eklen; + +err: + EVP_PKEY_CTX_free(pctx); + if (!ret && ek) + free(ek); + + return ret; +} + +BIO * +PKCS7_dataInit(PKCS7 *p7, BIO *bio) +{ + int i; + BIO *out = NULL, *btmp = NULL; + X509_ALGOR *xa = NULL; + const EVP_CIPHER *evp_cipher = NULL; + STACK_OF(X509_ALGOR) *md_sk = NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; + X509_ALGOR *xalg = NULL; + PKCS7_RECIP_INFO *ri = NULL; + ASN1_OCTET_STRING *os = NULL; + + if (p7 == NULL) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + /* + * The content field in the PKCS7 ContentInfo is optional, + * but that really only applies to inner content (precisely, + * detached signatures). + * + * When reading content, missing outer content is therefore + * treated as an error. + * + * When creating content, PKCS7_content_new() must be called + * before calling this method, so a NULL p7->d is always + * an error. + */ + if (p7->d.ptr == NULL) { + PKCS7error(PKCS7_R_NO_CONTENT); + return NULL; + } + + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_signed: + md_sk = p7->d.sign->md_algs; + os = PKCS7_get_octet_string(p7->d.sign->contents); + break; + case NID_pkcs7_signedAndEnveloped: + rsk = p7->d.signed_and_enveloped->recipientinfo; + md_sk = p7->d.signed_and_enveloped->md_algs; + xalg = p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; + if (evp_cipher == NULL) { + PKCS7error(PKCS7_R_CIPHER_NOT_INITIALIZED); + goto err; + } + break; + case NID_pkcs7_enveloped: + rsk = p7->d.enveloped->recipientinfo; + xalg = p7->d.enveloped->enc_data->algorithm; + evp_cipher = p7->d.enveloped->enc_data->cipher; + if (evp_cipher == NULL) { + PKCS7error(PKCS7_R_CIPHER_NOT_INITIALIZED); + goto err; + } + break; + case NID_pkcs7_digest: + xa = p7->d.digest->md; + os = PKCS7_get_octet_string(p7->d.digest->contents); + break; + case NID_pkcs7_data: + break; + default: + PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) + if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) + goto err; + + if (xa && !PKCS7_bio_add_digest(&out, xa)) + goto err; + + if (evp_cipher != NULL) { + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + int keylen, ivlen; + EVP_CIPHER_CTX *ctx; + + if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + BIO_get_cipher_ctx(btmp, &ctx); + keylen = EVP_CIPHER_key_length(evp_cipher); + ivlen = EVP_CIPHER_iv_length(evp_cipher); + xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); + if (ivlen > 0) + arc4random_buf(iv, ivlen); + if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, + NULL, 1) <= 0) + goto err; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + goto err; + if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) + goto err; + + if (ivlen > 0) { + if (xalg->parameter == NULL) { + xalg->parameter = ASN1_TYPE_new(); + if (xalg->parameter == NULL) + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) + goto err; + } + + /* Lets do the pub key stuff :-) */ + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) + goto err; + } + explicit_bzero(key, keylen); + + if (out == NULL) + out = btmp; + else + BIO_push(out, btmp); + btmp = NULL; + } + + if (bio == NULL) { + if (PKCS7_is_detached(p7)) + bio = BIO_new(BIO_s_null()); + else if (os && os->length > 0) + bio = BIO_new_mem_buf(os->data, os->length); + if (bio == NULL) { + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; + BIO_set_mem_eof_return(bio, 0); + } + } + if (out) + BIO_push(out, bio); + else + out = bio; + bio = NULL; + if (0) { +err: + if (out != NULL) + BIO_free_all(out); + if (btmp != NULL) + BIO_free_all(btmp); + out = NULL; + } + return (out); +} +LCRYPTO_ALIAS(PKCS7_dataInit); + +static int +pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) +{ + int ret; + + ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, + pcert->cert_info->issuer); + if (ret) + return ret; + return ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, + ri->issuer_and_serial->serial); +} + +/* int */ +BIO * +PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) +{ + int i, j; + BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; + X509_ALGOR *xa; + ASN1_OCTET_STRING *data_body = NULL; + const EVP_MD *evp_md; + const EVP_CIPHER *evp_cipher = NULL; + EVP_CIPHER_CTX *evp_ctx = NULL; + X509_ALGOR *enc_alg = NULL; + STACK_OF(X509_ALGOR) *md_sk = NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; + PKCS7_RECIP_INFO *ri = NULL; + unsigned char *ek = NULL, *tkey = NULL; + int eklen = 0, tkeylen = 0; + + if (p7 == NULL) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if (p7->d.ptr == NULL) { + PKCS7error(PKCS7_R_NO_CONTENT); + return NULL; + } + + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_signed: + data_body = PKCS7_get_octet_string(p7->d.sign->contents); + md_sk = p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + rsk = p7->d.signed_and_enveloped->recipientinfo; + md_sk = p7->d.signed_and_enveloped->md_algs; + data_body = p7->d.signed_and_enveloped->enc_data->enc_data; + enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) { + PKCS7error(PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + break; + case NID_pkcs7_enveloped: + rsk = p7->d.enveloped->recipientinfo; + enc_alg = p7->d.enveloped->enc_data->algorithm; + data_body = p7->d.enveloped->enc_data->enc_data; + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) { + PKCS7error(PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + break; + default: + PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + /* We will be checking the signature */ + if (md_sk != NULL) { + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { + xa = sk_X509_ALGOR_value(md_sk, i); + if ((btmp = BIO_new(BIO_f_md())) == NULL) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + + j = OBJ_obj2nid(xa->algorithm); + evp_md = EVP_get_digestbynid(j); + if (evp_md == NULL) { + PKCS7error(PKCS7_R_UNKNOWN_DIGEST_TYPE); + goto err; + } + + if (BIO_set_md(btmp, evp_md) <= 0) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + if (out == NULL) + out = btmp; + else + BIO_push(out, btmp); + btmp = NULL; + } + } + + if (evp_cipher != NULL) { + if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { + PKCS7error(ERR_R_BIO_LIB); + goto err; + } + + /* It was encrypted, we need to decrypt the secret key + * with the private key */ + + /* Find the recipientInfo which matches the passed certificate + * (if any) + */ + if (pcert) { + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + if (!pkcs7_cmp_ri(ri, pcert)) + break; + ri = NULL; + } + if (ri == NULL) { + PKCS7error(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); + goto err; + } + } + + /* If we haven't got a certificate try each ri in turn */ + if (pcert == NULL) { + /* Always attempt to decrypt all rinfo even + * after success as a defence against MMA timing + * attacks. + */ + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, + EVP_CIPHER_key_length(evp_cipher)) < 0) + goto err; + ERR_clear_error(); + } + } else { + /* Only exit on fatal errors, not decrypt failure */ + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0) + goto err; + ERR_clear_error(); + } + + evp_ctx = NULL; + BIO_get_cipher_ctx(etmp, &evp_ctx); + if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, + NULL, 0) <= 0) + goto err; + if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) + goto err; + /* Generate random key as MMA defence */ + tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); + tkey = malloc(tkeylen); + if (!tkey) + goto err; + if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) + goto err; + if (ek == NULL) { + ek = tkey; + eklen = tkeylen; + tkey = NULL; + } + + if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { + /* Some S/MIME clients don't use the same key + * and effective key length. The key length is + * determined by the size of the decrypted RSA key. + */ + if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { + /* Use random key as MMA defence */ + freezero(ek, eklen); + ek = tkey; + eklen = tkeylen; + tkey = NULL; + } + } + /* Clear errors so we don't leak information useful in MMA */ + ERR_clear_error(); + if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) + goto err; + + freezero(ek, eklen); + ek = NULL; + freezero(tkey, tkeylen); + tkey = NULL; + + if (out == NULL) + out = etmp; + else + BIO_push(out, etmp); + etmp = NULL; + } + + if (PKCS7_is_detached(p7) || (in_bio != NULL)) { + bio = in_bio; + } else { + if (data_body != NULL && data_body->length > 0) + bio = BIO_new_mem_buf(data_body->data, data_body->length); + else { + bio = BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(bio, 0); + } + if (bio == NULL) + goto err; + } + BIO_push(out, bio); + + if (0) { +err: + freezero(ek, eklen); + freezero(tkey, tkeylen); + if (out != NULL) + BIO_free_all(out); + if (btmp != NULL) + BIO_free_all(btmp); + if (etmp != NULL) + BIO_free_all(etmp); + out = NULL; + } + return (out); +} +LCRYPTO_ALIAS(PKCS7_dataDecode); + +static BIO * +PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) +{ + for (;;) { + bio = BIO_find_type(bio, BIO_TYPE_MD); + if (bio == NULL) { + PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + return NULL; + } + BIO_get_md_ctx(bio, pmd); + if (*pmd == NULL) { + PKCS7error(ERR_R_INTERNAL_ERROR); + return NULL; + } + if (EVP_MD_CTX_type(*pmd) == nid) + return bio; + bio = BIO_next(bio); + } + return NULL; +} + +static int +do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) +{ + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + + /* Add signing time if not already present */ + if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { + if (!PKCS7_add0_attrib_signing_time(si, NULL)) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + } + + /* Add digest */ + if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { + PKCS7error(ERR_R_EVP_LIB); + return 0; + } + if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Now sign the attributes */ + if (!PKCS7_SIGNER_INFO_sign(si)) + return 0; + + return 1; +} + + +int +PKCS7_dataFinal(PKCS7 *p7, BIO *bio) +{ + int ret = 0; + int i, j; + BIO *btmp; + PKCS7_SIGNER_INFO *si; + EVP_MD_CTX *mdc, ctx_tmp; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; + ASN1_OCTET_STRING *os = NULL; + + if (p7 == NULL) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (p7->d.ptr == NULL) { + PKCS7error(PKCS7_R_NO_CONTENT); + return 0; + } + + EVP_MD_CTX_init(&ctx_tmp); + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_data: + os = p7->d.data; + break; + case NID_pkcs7_signedAndEnveloped: + /* XXX */ + si_sk = p7->d.signed_and_enveloped->signer_info; + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (!os) { + os = ASN1_OCTET_STRING_new(); + if (!os) { + PKCS7error(ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.signed_and_enveloped->enc_data->enc_data = os; + } + break; + case NID_pkcs7_enveloped: + /* XXX */ + os = p7->d.enveloped->enc_data->enc_data; + if (!os) { + os = ASN1_OCTET_STRING_new(); + if (!os) { + PKCS7error(ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.enveloped->enc_data->enc_data = os; + } + break; + case NID_pkcs7_signed: + si_sk = p7->d.sign->signer_info; + os = PKCS7_get_octet_string(p7->d.sign->contents); + if (!PKCS7_is_detached(p7) && os == NULL) { + PKCS7error(PKCS7_R_DECODE_ERROR); + goto err; + } + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { + ASN1_OCTET_STRING_free(os); + os = NULL; + p7->d.sign->contents->d.data = NULL; + } + break; + + case NID_pkcs7_digest: + os = PKCS7_get_octet_string(p7->d.digest->contents); + if (os == NULL) { + PKCS7error(PKCS7_R_DECODE_ERROR); + goto err; + } + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.digest->contents) && + p7->detached) { + ASN1_OCTET_STRING_free(os); + os = NULL; + p7->d.digest->contents->d.data = NULL; + } + break; + + default: + PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + if (si_sk != NULL) { + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { + si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); + if (si->pkey == NULL) + continue; + + j = OBJ_obj2nid(si->digest_alg->algorithm); + + if ((btmp = PKCS7_find_digest(&mdc, bio, j)) == NULL) + goto err; + + /* We now have the EVP_MD_CTX, lets do the + * signing. */ + if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) + goto err; + + sk = si->auth_attr; + + /* If there are attributes, we add the digest + * attribute and only sign the attributes */ + if (sk_X509_ATTRIBUTE_num(sk) > 0) { + if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) + goto err; + } else { + unsigned char *abuf = NULL; + unsigned int abuflen; + abuflen = EVP_PKEY_size(si->pkey); + abuf = malloc(abuflen); + if (!abuf) + goto err; + + if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, + si->pkey)) { + PKCS7error(ERR_R_EVP_LIB); + goto err; + } + ASN1_STRING_set0(si->enc_digest, abuf, abuflen); + } + } + } else if (i == NID_pkcs7_digest) { + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + + if (!PKCS7_find_digest(&mdc, bio, + OBJ_obj2nid(p7->d.digest->md->algorithm))) + goto err; + if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) + goto err; + if (ASN1_STRING_set(p7->d.digest->digest, md_data, + md_len) == 0) + goto err; + } + + if (!PKCS7_is_detached(p7)) { + /* + * NOTE: only reach os == NULL here because detached + * digested data support is broken? + */ + if (os == NULL) + goto err; + if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { + char *cont; + long contlen; + + btmp = BIO_find_type(bio, BIO_TYPE_MEM); + if (btmp == NULL) { + PKCS7error(PKCS7_R_UNABLE_TO_FIND_MEM_BIO); + goto err; + } + contlen = BIO_get_mem_data(btmp, &cont); + /* + * Mark the BIO read only then we can use its copy + * of the data instead of making an extra copy. + */ + BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(btmp, 0); + ASN1_STRING_set0(os, (unsigned char *)cont, contlen); + } + } + ret = 1; +err: + EVP_MD_CTX_cleanup(&ctx_tmp); + return (ret); +} +LCRYPTO_ALIAS(PKCS7_dataFinal); + +int +PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) +{ + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; + size_t siglen; + const EVP_MD *md = NULL; + + md = EVP_get_digestbyobj(si->digest_alg->algorithm); + if (md == NULL) + return 0; + + EVP_MD_CTX_init(&mctx); + if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { + PKCS7error(PKCS7_R_CTRL_ERROR); + goto err; + } + + alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, + &PKCS7_ATTR_SIGN_it); + if (!abuf) + goto err; + if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) + goto err; + free(abuf); + abuf = NULL; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + abuf = malloc(siglen); + if (!abuf) + goto err; + if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { + PKCS7error(PKCS7_R_CTRL_ERROR); + goto err; + } + + EVP_MD_CTX_cleanup(&mctx); + + ASN1_STRING_set0(si->enc_digest, abuf, siglen); + + return 1; + +err: + free(abuf); + EVP_MD_CTX_cleanup(&mctx); + return 0; +} +LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_sign); + +int +PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, + PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + PKCS7_ISSUER_AND_SERIAL *ias; + int ret = 0, i; + STACK_OF(X509) *cert; + X509 *x509; + + if (p7 == NULL) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (p7->d.ptr == NULL) { + PKCS7error(PKCS7_R_NO_CONTENT); + return 0; + } + + if (PKCS7_type_is_signed(p7)) { + cert = p7->d.sign->cert; + } else if (PKCS7_type_is_signedAndEnveloped(p7)) { + cert = p7->d.signed_and_enveloped->cert; + } else { + PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + /* XXXX */ + ias = si->issuer_and_serial; + + x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); + + /* were we able to find the cert in passed to us */ + if (x509 == NULL) { + PKCS7error(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); + goto err; + } + + /* Lets verify */ + if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { + PKCS7error(ERR_R_X509_LIB); + goto err; + } + if (X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN) == 0) { + X509_STORE_CTX_cleanup(ctx); + goto err; + } + i = X509_verify_cert(ctx); + if (i <= 0) { + PKCS7error(ERR_R_X509_LIB); + X509_STORE_CTX_cleanup(ctx); + goto err; + } + X509_STORE_CTX_cleanup(ctx); + + return PKCS7_signatureVerify(bio, p7, si, x509); +err: + + return ret; +} +LCRYPTO_ALIAS(PKCS7_dataVerify); + +int +PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509) +{ + ASN1_OCTET_STRING *os; + EVP_MD_CTX mdc_tmp, *mdc; + int ret = 0, i; + int md_type; + STACK_OF(X509_ATTRIBUTE) *sk; + BIO *btmp; + EVP_PKEY *pkey; + + EVP_MD_CTX_init(&mdc_tmp); + + if (!PKCS7_type_is_signed(p7) && + !PKCS7_type_is_signedAndEnveloped(p7)) { + PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + + md_type = OBJ_obj2nid(si->digest_alg->algorithm); + + btmp = bio; + for (;;) { + if ((btmp == NULL) || + ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { + PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + BIO_get_md_ctx(btmp, &mdc); + if (mdc == NULL) { + PKCS7error(ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_MD_CTX_type(mdc) == md_type) + break; + /* Workaround for some broken clients that put the signature + * OID instead of the digest OID in digest_alg->algorithm + */ + if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) + break; + btmp = BIO_next(btmp); + } + + /* mdc is the digest ctx that we want, unless there are attributes, + * in which case the digest is the signed attributes */ + if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) + goto err; + + sk = si->auth_attr; + if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { + unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; + unsigned int md_len; + int alen; + ASN1_OCTET_STRING *message_digest; + + if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) + goto err; + message_digest = PKCS7_digest_from_attributes(sk); + if (!message_digest) { + PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + if ((message_digest->length != (int)md_len) || + (memcmp(message_digest->data, md_dat, md_len))) { + PKCS7error(PKCS7_R_DIGEST_FAILURE); + ret = -1; + goto err; + } + + if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), + NULL)) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, + &PKCS7_ATTR_VERIFY_it); + if (alen <= 0) { + PKCS7error(ERR_R_ASN1_LIB); + ret = -1; + goto err; + } + if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) + goto err; + + free(abuf); + } + + os = si->enc_digest; + pkey = X509_get_pubkey(x509); + if (!pkey) { + ret = -1; + goto err; + } + + i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); + EVP_PKEY_free(pkey); + if (i <= 0) { + PKCS7error(PKCS7_R_SIGNATURE_FAILURE); + ret = -1; + goto err; + } else + ret = 1; +err: + EVP_MD_CTX_cleanup(&mdc_tmp); + return (ret); +} +LCRYPTO_ALIAS(PKCS7_signatureVerify); + +PKCS7_ISSUER_AND_SERIAL * +PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) +{ + STACK_OF(PKCS7_RECIP_INFO) *rsk; + PKCS7_RECIP_INFO *ri; + int i; + + i = OBJ_obj2nid(p7->type); + if (i != NID_pkcs7_signedAndEnveloped) + return NULL; + if (p7->d.signed_and_enveloped == NULL) + return NULL; + rsk = p7->d.signed_and_enveloped->recipientinfo; + if (rsk == NULL) + return NULL; + ri = sk_PKCS7_RECIP_INFO_value(rsk, 0); + if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) + return (NULL); + ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); + return (ri->issuer_and_serial); +} +LCRYPTO_ALIAS(PKCS7_get_issuer_and_serial); + +ASN1_TYPE * +PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) +{ + return (get_attribute(si->auth_attr, nid)); +} +LCRYPTO_ALIAS(PKCS7_get_signed_attribute); + +ASN1_TYPE * +PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) +{ + return (get_attribute(si->unauth_attr, nid)); +} +LCRYPTO_ALIAS(PKCS7_get_attribute); + +static ASN1_TYPE * +get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) +{ + int i; + X509_ATTRIBUTE *xa; + ASN1_OBJECT *o; + + o = OBJ_nid2obj(nid); + if (!o || !sk) + return (NULL); + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + xa = sk_X509_ATTRIBUTE_value(sk, i); + if (OBJ_cmp(xa->object, o) == 0) + return (sk_ASN1_TYPE_value(xa->set, 0)); + } + return (NULL); +} + +ASN1_OCTET_STRING * +PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) +{ + ASN1_TYPE *astype; + + if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) + return NULL; + if (astype->type != V_ASN1_OCTET_STRING) + return NULL; + return astype->value.octet_string; +} +LCRYPTO_ALIAS(PKCS7_digest_from_attributes); + +int +PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk) +{ + int i; + + if (p7si->auth_attr != NULL) + sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, + X509_ATTRIBUTE_free); + p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); + if (p7si->auth_attr == NULL) + return 0; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i)))) + == NULL) + return (0); + } + return (1); +} +LCRYPTO_ALIAS(PKCS7_set_signed_attributes); + +int +PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) +{ + int i; + + if (p7si->unauth_attr != NULL) + sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, + X509_ATTRIBUTE_free); + p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); + if (p7si->unauth_attr == NULL) + return 0; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i)))) + == NULL) + return (0); + } + return (1); +} +LCRYPTO_ALIAS(PKCS7_set_attributes); + +int +PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) +{ + return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); +} +LCRYPTO_ALIAS(PKCS7_add_signed_attribute); + +int +PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value) +{ + return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); +} +LCRYPTO_ALIAS(PKCS7_add_attribute); + +static int +add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value) +{ + X509_ATTRIBUTE *attr = NULL; + + if (*sk == NULL) { + *sk = sk_X509_ATTRIBUTE_new_null(); + if (*sk == NULL) + return 0; +new_attrib: + if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) + return 0; + if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + } else { + int i; + + for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { + attr = sk_X509_ATTRIBUTE_value(*sk, i); + if (OBJ_obj2nid(attr->object) == nid) { + X509_ATTRIBUTE_free(attr); + attr = X509_ATTRIBUTE_create(nid, atrtype, + value); + if (attr == NULL) + return 0; + if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + goto end; + } + } + goto new_attrib; + } +end: + return (1); +} diff --git a/Libraries/libressl/crypto/pkcs7/pk7_lib.c b/Libraries/libressl/crypto/pkcs7/pk7_lib.c new file mode 100644 index 000000000..6eda698c9 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pk7_lib.c @@ -0,0 +1,674 @@ +/* $OpenBSD: pk7_lib.c,v 1.26 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "asn1_local.h" +#include "evp_local.h" +#include "x509_local.h" + +long +PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) +{ + int nid; + long ret; + + nid = OBJ_obj2nid(p7->type); + + switch (cmd) { + case PKCS7_OP_SET_DETACHED_SIGNATURE: + if (nid == NID_pkcs7_signed) { + ret = p7->detached = (int)larg; + if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { + ASN1_OCTET_STRING *os; + os = p7->d.sign->contents->d.data; + ASN1_OCTET_STRING_free(os); + p7->d.sign->contents->d.data = NULL; + } + } else { + PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ret = 0; + } + break; + case PKCS7_OP_GET_DETACHED_SIGNATURE: + if (nid == NID_pkcs7_signed) { + if (!p7->d.sign || !p7->d.sign->contents->d.ptr) + ret = 1; + else + ret = 0; + + p7->detached = ret; + } else { + PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ret = 0; + } + + break; + default: + PKCS7error(PKCS7_R_UNKNOWN_OPERATION); + ret = 0; + } + return (ret); +} +LCRYPTO_ALIAS(PKCS7_ctrl); + +int +PKCS7_content_new(PKCS7 *p7, int type) +{ + PKCS7 *ret = NULL; + + if ((ret = PKCS7_new()) == NULL) + goto err; + if (!PKCS7_set_type(ret, type)) + goto err; + if (!PKCS7_set_content(p7, ret)) + goto err; + + return (1); +err: + if (ret != NULL) + PKCS7_free(ret); + return (0); +} +LCRYPTO_ALIAS(PKCS7_content_new); + +int +PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) +{ + int i; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + if (p7->d.sign->contents != NULL) + PKCS7_free(p7->d.sign->contents); + p7->d.sign->contents = p7_data; + break; + case NID_pkcs7_digest: + if (p7->d.digest->contents != NULL) + PKCS7_free(p7->d.digest->contents); + p7->d.digest->contents = p7_data; + break; + case NID_pkcs7_data: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_encrypted: + default: + PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + return (1); +err: + return (0); +} +LCRYPTO_ALIAS(PKCS7_set_content); + +int +PKCS7_set_type(PKCS7 *p7, int type) +{ + ASN1_OBJECT *obj; + + /*PKCS7_content_free(p7);*/ + obj=OBJ_nid2obj(type); /* will not fail */ + + switch (type) { + case NID_pkcs7_signed: + p7->type = obj; + if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { + PKCS7_SIGNED_free(p7->d.sign); + p7->d.sign = NULL; + goto err; + } + break; + case NID_pkcs7_data: + p7->type = obj; + if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) + goto err; + break; + case NID_pkcs7_signedAndEnveloped: + p7->type = obj; + if ((p7->d.signed_and_enveloped = + PKCS7_SIGN_ENVELOPE_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) + goto err; + p7->d.signed_and_enveloped->enc_data->content_type = + OBJ_nid2obj(NID_pkcs7_data); + break; + case NID_pkcs7_enveloped: + p7->type = obj; + if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) + goto err; + p7->d.enveloped->enc_data->content_type = + OBJ_nid2obj(NID_pkcs7_data); + break; + case NID_pkcs7_encrypted: + p7->type = obj; + if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) + goto err; + p7->d.encrypted->enc_data->content_type = + OBJ_nid2obj(NID_pkcs7_data); + break; + + case NID_pkcs7_digest: + p7->type = obj; + if ((p7->d.digest = PKCS7_DIGEST_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) + goto err; + break; + default: + PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + return (1); +err: + return (0); +} +LCRYPTO_ALIAS(PKCS7_set_type); + +int +PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) +{ + p7->type = OBJ_nid2obj(type); + p7->d.other = other; + return 1; +} +LCRYPTO_ALIAS(PKCS7_set0_type_other); + +int +PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) +{ + int i, j, nid; + X509_ALGOR *alg; + STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; + STACK_OF(X509_ALGOR) *md_sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + signer_sk = p7->d.sign->signer_info; + md_sk = p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + signer_sk = p7->d.signed_and_enveloped->signer_info; + md_sk = p7->d.signed_and_enveloped->md_algs; + break; + default: + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + nid = OBJ_obj2nid(psi->digest_alg->algorithm); + + /* If the digest is not currently listed, add it */ + j = 0; + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { + alg = sk_X509_ALGOR_value(md_sk, i); + if (OBJ_obj2nid(alg->algorithm) == nid) { + j = 1; + break; + } + } + if (!j) /* we need to add another algorithm */ + { + if (!(alg = X509_ALGOR_new()) || + !(alg->parameter = ASN1_TYPE_new())) { + X509_ALGOR_free(alg); + PKCS7error(ERR_R_MALLOC_FAILURE); + return (0); + } + alg->algorithm = OBJ_nid2obj(nid); + alg->parameter->type = V_ASN1_NULL; + if (!sk_X509_ALGOR_push(md_sk, alg)) { + X509_ALGOR_free(alg); + return 0; + } + } + + if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) + return 0; + return (1); +} +LCRYPTO_ALIAS(PKCS7_add_signer); + +int +PKCS7_add_certificate(PKCS7 *p7, X509 *x509) +{ + int i; + STACK_OF(X509) **sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + sk = &(p7->d.sign->cert); + break; + case NID_pkcs7_signedAndEnveloped: + sk = &(p7->d.signed_and_enveloped->cert); + break; + default: + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (*sk == NULL) + *sk = sk_X509_new_null(); + if (*sk == NULL) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(*sk, x509)) { + X509_free(x509); + return 0; + } + return (1); +} +LCRYPTO_ALIAS(PKCS7_add_certificate); + +int +PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) +{ + int i; + STACK_OF(X509_CRL) **sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + sk = &(p7->d.sign->crl); + break; + case NID_pkcs7_signedAndEnveloped: + sk = &(p7->d.signed_and_enveloped->crl); + break; + default: + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (*sk == NULL) + *sk = sk_X509_CRL_new_null(); + if (*sk == NULL) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(*sk, crl)) { + X509_CRL_free(crl); + return 0; + } + return (1); +} +LCRYPTO_ALIAS(PKCS7_add_crl); + +int +PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst) +{ + int ret; + + /* We now need to add another PKCS7_SIGNER_INFO entry */ + if (!ASN1_INTEGER_set(p7i->version, 1)) + goto err; + if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509))) + goto err; + + /* because ASN1_INTEGER_set is used to set a 'long' we will do + * things the ugly way. */ + ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + if (!(p7i->issuer_and_serial->serial = + ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + goto err; + + /* lets keep the pkey around for a while */ + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + p7i->pkey = pkey; + + /* Set the algorithms */ + + X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), + V_ASN1_NULL, NULL); + + if (pkey->ameth && pkey->ameth->pkey_ctrl) { + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, + 0, p7i); + if (ret > 0) + return 1; + if (ret != -2) { + PKCS7error(PKCS7_R_SIGNING_CTRL_FAILURE); + return 0; + } + } + PKCS7error(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); +err: + return 0; +} +LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_set); + +PKCS7_SIGNER_INFO * +PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) +{ + PKCS7_SIGNER_INFO *si = NULL; + + if (dgst == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) + goto err; + dgst = EVP_get_digestbynid(def_nid); + if (dgst == NULL) { + PKCS7error(PKCS7_R_NO_DEFAULT_DIGEST); + goto err; + } + } + + if ((si = PKCS7_SIGNER_INFO_new()) == NULL) + goto err; + if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) + goto err; + if (!PKCS7_add_signer(p7, si)) + goto err; + return (si); +err: + if (si) + PKCS7_SIGNER_INFO_free(si); + return (NULL); +} +LCRYPTO_ALIAS(PKCS7_add_signature); + +int +PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) +{ + if (PKCS7_type_is_digest(p7)) { + if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + p7->d.digest->md->parameter->type = V_ASN1_NULL; + p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); + return 1; + } + + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return 1; +} +LCRYPTO_ALIAS(PKCS7_set_digest); + +STACK_OF(PKCS7_SIGNER_INFO) * +PKCS7_get_signer_info(PKCS7 *p7) +{ + if (p7 == NULL || p7->d.ptr == NULL) + return (NULL); + if (PKCS7_type_is_signed(p7)) { + return (p7->d.sign->signer_info); + } else if (PKCS7_type_is_signedAndEnveloped(p7)) { + return (p7->d.signed_and_enveloped->signer_info); + } else + return (NULL); +} +LCRYPTO_ALIAS(PKCS7_get_signer_info); + +void +PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig) +{ + if (pk) + *pk = si->pkey; + if (pdig) + *pdig = si->digest_alg; + if (psig) + *psig = si->digest_enc_alg; +} +LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_get0_algs); + +void +PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) +{ + if (penc) + *penc = ri->key_enc_algor; +} +LCRYPTO_ALIAS(PKCS7_RECIP_INFO_get0_alg); + +PKCS7_RECIP_INFO * +PKCS7_add_recipient(PKCS7 *p7, X509 *x509) +{ + PKCS7_RECIP_INFO *ri; + + if ((ri = PKCS7_RECIP_INFO_new()) == NULL) + goto err; + if (!PKCS7_RECIP_INFO_set(ri, x509)) + goto err; + if (!PKCS7_add_recipient_info(p7, ri)) + goto err; + return ri; +err: + if (ri) + PKCS7_RECIP_INFO_free(ri); + return NULL; +} +LCRYPTO_ALIAS(PKCS7_add_recipient); + +int +PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) +{ + int i; + STACK_OF(PKCS7_RECIP_INFO) *sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signedAndEnveloped: + sk = p7->d.signed_and_enveloped->recipientinfo; + break; + case NID_pkcs7_enveloped: + sk = p7->d.enveloped->recipientinfo; + break; + default: + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) + return 0; + return (1); +} +LCRYPTO_ALIAS(PKCS7_add_recipient_info); + +int +PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) +{ + int ret; + EVP_PKEY *pkey = NULL; + if (!ASN1_INTEGER_set(p7i->version, 0)) + return 0; + if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509))) + return 0; + + ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + if (!(p7i->issuer_and_serial->serial = + ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + return 0; + + pkey = X509_get_pubkey(x509); + + if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { + PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, + 0, p7i); + if (ret == -2) { + PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + if (ret <= 0) { + PKCS7error(PKCS7_R_ENCRYPTION_CTRL_FAILURE); + goto err; + } + + EVP_PKEY_free(pkey); + + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + p7i->cert = x509; + + return 1; + +err: + EVP_PKEY_free(pkey); + return 0; +} +LCRYPTO_ALIAS(PKCS7_RECIP_INFO_set); + +X509 * +PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + if (PKCS7_type_is_signed(p7)) + return(X509_find_by_issuer_and_serial(p7->d.sign->cert, + si->issuer_and_serial->issuer, + si->issuer_and_serial->serial)); + else + return (NULL); +} +LCRYPTO_ALIAS(PKCS7_cert_from_signer_info); + +int +PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) +{ + int i; + PKCS7_ENC_CONTENT *ec; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signedAndEnveloped: + ec = p7->d.signed_and_enveloped->enc_data; + break; + case NID_pkcs7_enveloped: + ec = p7->d.enveloped->enc_data; + break; + default: + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + /* Check cipher OID exists and has data in it*/ + i = EVP_CIPHER_type(cipher); + if (i == NID_undef) { + PKCS7error(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return (0); + } + + ec->cipher = cipher; + return 1; +} +LCRYPTO_ALIAS(PKCS7_set_cipher); + +int +PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) +{ + ASN1_OCTET_STRING *os = NULL; + + switch (OBJ_obj2nid(p7->type)) { + case NID_pkcs7_data: + os = p7->d.data; + break; + + case NID_pkcs7_signedAndEnveloped: + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (os == NULL) { + os = ASN1_OCTET_STRING_new(); + p7->d.signed_and_enveloped->enc_data->enc_data = os; + } + break; + + case NID_pkcs7_enveloped: + os = p7->d.enveloped->enc_data->enc_data; + if (os == NULL) { + os = ASN1_OCTET_STRING_new(); + p7->d.enveloped->enc_data->enc_data = os; + } + break; + + case NID_pkcs7_signed: + os = p7->d.sign->contents->d.data; + break; + + default: + os = NULL; + break; + } + + if (os == NULL) + return 0; + + os->flags |= ASN1_STRING_FLAG_NDEF; + *boundary = &os->data; + + return 1; +} +LCRYPTO_ALIAS(PKCS7_stream); diff --git a/Libraries/libressl/crypto/pkcs7/pk7_mime.c b/Libraries/libressl/crypto/pkcs7/pk7_mime.c new file mode 100644 index 000000000..f00e18c7e --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pk7_mime.c @@ -0,0 +1,107 @@ +/* $OpenBSD: pk7_mime.c,v 1.19 2023/05/02 09:56:12 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +#include +#include + +#include "asn1_local.h" + +/* PKCS#7 wrappers round generalised stream and MIME routines */ +BIO * +BIO_new_PKCS7(BIO *out, PKCS7 *p7) +{ + return BIO_new_NDEF(out, (ASN1_VALUE *)p7, &PKCS7_it); +} +LCRYPTO_ALIAS(BIO_new_PKCS7); + +int +i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) +{ + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags, &PKCS7_it); +} +LCRYPTO_ALIAS(i2d_PKCS7_bio_stream); + +int +PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) +{ + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags, + "PKCS7", &PKCS7_it); +} +LCRYPTO_ALIAS(PEM_write_bio_PKCS7_stream); + +int +SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) +{ + STACK_OF(X509_ALGOR) *mdalgs = NULL; + int ctype_nid; + + if ((ctype_nid = OBJ_obj2nid(p7->type)) == NID_pkcs7_signed) + mdalgs = p7->d.sign->md_algs; + + flags ^= SMIME_OLDMIME; + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, + ctype_nid, NID_undef, mdalgs, &PKCS7_it); +} +LCRYPTO_ALIAS(SMIME_write_PKCS7); + +PKCS7 * +SMIME_read_PKCS7(BIO *bio, BIO **bcont) +{ + return (PKCS7 *)SMIME_read_ASN1(bio, bcont, &PKCS7_it); +} +LCRYPTO_ALIAS(SMIME_read_PKCS7); diff --git a/Libraries/libressl/crypto/pkcs7/pk7_smime.c b/Libraries/libressl/crypto/pkcs7/pk7_smime.c new file mode 100644 index 000000000..c113ac395 --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pk7_smime.c @@ -0,0 +1,599 @@ +/* $OpenBSD: pk7_smime.c,v 1.26 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Simple PKCS#7 processing functions */ + +#include + +#include +#include +#include + +#include "x509_local.h" + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); + +PKCS7 * +PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, + int flags) +{ + PKCS7 *p7; + int i; + + if (!(p7 = PKCS7_new())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) + goto err; + + if (!PKCS7_content_new(p7, NID_pkcs7_data)) + goto err; + + if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { + PKCS7error(PKCS7_R_PKCS7_ADD_SIGNER_ERROR); + goto err; + } + + if (!(flags & PKCS7_NOCERTS)) { + for (i = 0; i < sk_X509_num(certs); i++) { + if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) + goto err; + } + } + + if (flags & PKCS7_DETACHED) + PKCS7_set_detached(p7, 1); + + if (flags & (PKCS7_STREAM|PKCS7_PARTIAL)) + return p7; + + if (PKCS7_final(p7, data, flags)) + return p7; + +err: + PKCS7_free(p7); + return NULL; +} +LCRYPTO_ALIAS(PKCS7_sign); + +int +PKCS7_final(PKCS7 *p7, BIO *data, int flags) +{ + BIO *p7bio; + int ret = 0; + + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + + SMIME_crlf_copy(data, p7bio, flags); + + (void)BIO_flush(p7bio); + + if (!PKCS7_dataFinal(p7, p7bio)) { + PKCS7error(PKCS7_R_PKCS7_DATASIGN); + goto err; + } + + ret = 1; + +err: + BIO_free_all(p7bio); + + return ret; +} +LCRYPTO_ALIAS(PKCS7_final); + +/* Check to see if a cipher exists and if so add S/MIME capabilities */ + +static int +add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + if (EVP_get_cipherbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; +} + +static int +add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + if (EVP_get_digestbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; +} + +PKCS7_SIGNER_INFO * +PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags) +{ + PKCS7_SIGNER_INFO *si = NULL; + STACK_OF(X509_ALGOR) *smcap = NULL; + + if (!X509_check_private_key(signcert, pkey)) { + PKCS7error(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + + if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) { + PKCS7error(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); + return NULL; + } + + if (!(flags & PKCS7_NOCERTS)) { + if (!PKCS7_add_certificate(p7, signcert)) + goto err; + } + + if (!(flags & PKCS7_NOATTR)) { + if (!PKCS7_add_attrib_content_type(si, NULL)) + goto err; + /* Add SMIMECapabilities */ + if (!(flags & PKCS7_NOSMIMECAP)) { + if (!(smcap = sk_X509_ALGOR_new_null())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) || + !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) || + !add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_256, -1) || + !add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_512, -1) || + !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) || + !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) || + !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) || + !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) || + !add_cipher_smcap(smcap, NID_rc2_cbc, 128) || + !add_cipher_smcap(smcap, NID_rc2_cbc, 64) || + !add_cipher_smcap(smcap, NID_des_cbc, -1) || + !add_cipher_smcap(smcap, NID_rc2_cbc, 40) || + !PKCS7_add_attrib_smimecap(si, smcap)) + goto err; + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + smcap = NULL; + } + if (flags & PKCS7_REUSE_DIGEST) { + if (!pkcs7_copy_existing_digest(p7, si)) + goto err; + if (!(flags & PKCS7_PARTIAL) && + !PKCS7_SIGNER_INFO_sign(si)) + goto err; + } + } + return si; + +err: + if (smcap) + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + return NULL; +} +LCRYPTO_ALIAS(PKCS7_sign_add_signer); + +/* Search for a digest matching SignerInfo digest type and if found + * copy across. + */ + +static int +pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + int i; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *sitmp; + ASN1_OCTET_STRING *osdig = NULL; + + sinfos = PKCS7_get_signer_info(p7); + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + if (si == sitmp) + break; + if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) + continue; + if (!OBJ_cmp(si->digest_alg->algorithm, + sitmp->digest_alg->algorithm)) { + osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); + break; + } + + } + + if (osdig) + return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); + + PKCS7error(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); + return 0; +} + +int +PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, + BIO *out, int flags) +{ + STACK_OF(X509) *signers; + X509 *signer; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + X509_STORE_CTX cert_ctx; + char buf[4096]; + int i, j = 0, k, ret = 0; + BIO *p7bio; + BIO *tmpin, *tmpout; + + if (!p7) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (!PKCS7_type_is_signed(p7)) { + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return 0; + } + + /* Check for no data and no content: no data to verify signature */ + if (PKCS7_get_detached(p7) && !indata) { + PKCS7error(PKCS7_R_NO_CONTENT); + return 0; + } + + /* + * Very old Netscape illegally included empty content with + * a detached signature. Very old users should upgrade. + */ + /* Check for data and content: two sets of data */ + if (!PKCS7_get_detached(p7) && indata) { + PKCS7error(PKCS7_R_CONTENT_AND_DATA_PRESENT); + return 0; + } + + sinfos = PKCS7_get_signer_info(p7); + + if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { + PKCS7error(PKCS7_R_NO_SIGNATURES_ON_DATA); + return 0; + } + + + signers = PKCS7_get0_signers(p7, certs, flags); + + if (!signers) + return 0; + + /* Now verify the certificates */ + + if (!(flags & PKCS7_NOVERIFY)) + for (k = 0; k < sk_X509_num(signers); k++) { + signer = sk_X509_value (signers, k); + if (!(flags & PKCS7_NOCHAIN)) { + if (!X509_STORE_CTX_init(&cert_ctx, store, + signer, p7->d.sign->cert)) { + PKCS7error(ERR_R_X509_LIB); + sk_X509_free(signers); + return 0; + } + if (X509_STORE_CTX_set_default(&cert_ctx, + "smime_sign") == 0) { + sk_X509_free(signers); + return 0; + } + } else if (!X509_STORE_CTX_init(&cert_ctx, store, + signer, NULL)) { + PKCS7error(ERR_R_X509_LIB); + sk_X509_free(signers); + return 0; + } + if (!(flags & PKCS7_NOCRL)) + X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); + i = X509_verify_cert(&cert_ctx); + if (i <= 0) + j = X509_STORE_CTX_get_error(&cert_ctx); + X509_STORE_CTX_cleanup(&cert_ctx); + if (i <= 0) { + PKCS7error(PKCS7_R_CERTIFICATE_VERIFY_ERROR); + ERR_asprintf_error_data("Verify error:%s", + X509_verify_cert_error_string(j)); + sk_X509_free(signers); + return 0; + } + /* Check for revocation status here */ + } + + /* + * Performance optimization: if the content is a memory BIO then + * store its contents in a temporary read only memory BIO. This + * avoids potentially large numbers of slow copies of data which will + * occur when reading from a read write memory BIO when signatures + * are calculated. + */ + if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) { + char *ptr; + long len; + + len = BIO_get_mem_data(indata, &ptr); + tmpin = BIO_new_mem_buf(ptr, len); + if (tmpin == NULL) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return 0; + } + } else + tmpin = indata; + + + if (!(p7bio = PKCS7_dataInit(p7, tmpin))) + goto err; + + if (flags & PKCS7_TEXT) { + if (!(tmpout = BIO_new(BIO_s_mem()))) { + PKCS7error(ERR_R_MALLOC_FAILURE); + goto err; + } + BIO_set_mem_eof_return(tmpout, 0); + } else + tmpout = out; + + /* We now have to 'read' from p7bio to calculate digests etc. */ + for (;;) { + i = BIO_read(p7bio, buf, sizeof(buf)); + if (i <= 0) + break; + if (tmpout) + BIO_write(tmpout, buf, i); + } + + if (flags & PKCS7_TEXT) { + if (!SMIME_text(tmpout, out)) { + PKCS7error(PKCS7_R_SMIME_TEXT_ERROR); + BIO_free(tmpout); + goto err; + } + BIO_free(tmpout); + } + + /* Now Verify All Signatures */ + if (!(flags & PKCS7_NOSIGS)) + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + signer = sk_X509_value (signers, i); + j = PKCS7_signatureVerify(p7bio, p7, si, signer); + if (j <= 0) { + PKCS7error(PKCS7_R_SIGNATURE_FAILURE); + goto err; + } + } + + ret = 1; + +err: + if (tmpin == indata) { + if (indata) + BIO_pop(p7bio); + } + BIO_free_all(p7bio); + sk_X509_free(signers); + + return ret; +} +LCRYPTO_ALIAS(PKCS7_verify); + +STACK_OF(X509) * +PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) +{ + STACK_OF(X509) *signers; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + PKCS7_ISSUER_AND_SERIAL *ias; + X509 *signer; + int i; + + if (!p7) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if (!PKCS7_type_is_signed(p7)) { + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return NULL; + } + + /* Collect all the signers together */ + sinfos = PKCS7_get_signer_info(p7); + if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { + PKCS7error(PKCS7_R_NO_SIGNERS); + return 0; + } + + if (!(signers = sk_X509_new_null())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + ias = si->issuer_and_serial; + signer = NULL; + /* If any certificates passed they take priority */ + if (certs) + signer = X509_find_by_issuer_and_serial (certs, + ias->issuer, ias->serial); + if (!signer && !(flags & PKCS7_NOINTERN) && p7->d.sign->cert) + signer = + X509_find_by_issuer_and_serial(p7->d.sign->cert, + ias->issuer, ias->serial); + if (!signer) { + PKCS7error(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); + sk_X509_free(signers); + return 0; + } + + if (!sk_X509_push(signers, signer)) { + sk_X509_free(signers); + return NULL; + } + } + return signers; +} +LCRYPTO_ALIAS(PKCS7_get0_signers); + +/* Build a complete PKCS#7 enveloped data */ + +PKCS7 * +PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags) +{ + PKCS7 *p7; + BIO *p7bio = NULL; + int i; + X509 *x509; + + if (!(p7 = PKCS7_new())) { + PKCS7error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) + goto err; + if (!PKCS7_set_cipher(p7, cipher)) { + PKCS7error(PKCS7_R_ERROR_SETTING_CIPHER); + goto err; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + x509 = sk_X509_value(certs, i); + if (!PKCS7_add_recipient(p7, x509)) { + PKCS7error(PKCS7_R_ERROR_ADDING_RECIPIENT); + goto err; + } + } + + if (flags & PKCS7_STREAM) + return p7; + + if (PKCS7_final(p7, in, flags)) + return p7; + +err: + BIO_free_all(p7bio); + PKCS7_free(p7); + return NULL; +} +LCRYPTO_ALIAS(PKCS7_encrypt); + +int +PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) +{ + BIO *tmpmem; + int ret, i; + char buf[4096]; + + if (!p7) { + PKCS7error(PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (!PKCS7_type_is_enveloped(p7)) { + PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); + return 0; + } + + if (cert && !X509_check_private_key(cert, pkey)) { + PKCS7error(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return 0; + } + + if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { + PKCS7error(PKCS7_R_DECRYPT_ERROR); + return 0; + } + + if (flags & PKCS7_TEXT) { + BIO *tmpbuf; + + /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ + if (!(tmpbuf = BIO_new(BIO_f_buffer()))) { + PKCS7error(ERR_R_MALLOC_FAILURE); + BIO_free_all(tmpmem); + return 0; + } + BIO_push(tmpbuf, tmpmem); + ret = SMIME_text(tmpbuf, data); + if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + BIO_free_all(tmpbuf); + return ret; + } else { + for (;;) { + i = BIO_read(tmpmem, buf, sizeof(buf)); + if (i <= 0) { + ret = 1; + if (BIO_method_type(tmpmem) == + BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + break; + } + if (BIO_write(data, buf, i) != i) { + ret = 0; + break; + } + } + BIO_free_all(tmpmem); + return ret; + } +} +LCRYPTO_ALIAS(PKCS7_decrypt); diff --git a/Libraries/libressl/crypto/pkcs7/pkcs7err.c b/Libraries/libressl/crypto/pkcs7/pkcs7err.c new file mode 100644 index 000000000..d3ca0ec6d --- /dev/null +++ b/Libraries/libressl/crypto/pkcs7/pkcs7err.c @@ -0,0 +1,143 @@ +/* $OpenBSD: pkcs7err.c,v 1.15 2023/02/16 08:38:17 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason) + +static ERR_STRING_DATA PKCS7_str_functs[]= { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA PKCS7_str_reasons[]= { + {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), "cipher has no object identifier"}, + {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"}, + {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT), "content and data present"}, + {ERR_REASON(PKCS7_R_CTRL_ERROR) , "ctrl error"}, + {ERR_REASON(PKCS7_R_DECODE_ERROR) , "decode error"}, + {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH), "decrypted key is wrong length"}, + {ERR_REASON(PKCS7_R_DECRYPT_ERROR) , "decrypt error"}, + {ERR_REASON(PKCS7_R_DIGEST_FAILURE) , "digest failure"}, + {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"}, + {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), "encryption not supported for this key type"}, + {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"}, + {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"}, + {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) , "invalid mime type"}, + {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"}, + {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, + {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR) , "mime parse error"}, + {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, + {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO), "missing ceripend info"}, + {ERR_REASON(PKCS7_R_NO_CONTENT) , "no content"}, + {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) , "no content type"}, + {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST) , "no default digest"}, + {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), "no matching digest type found"}, + {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE), "no multipart body failure"}, + {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, + {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), "no recipient matches certificate"}, + {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY), "no recipient matches key"}, + {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"}, + {ERR_REASON(PKCS7_R_NO_SIGNERS) , "no signers"}, + {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) , "no sig content type"}, + {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), "operation not supported on this type"}, + {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"}, + {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"}, + {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) , "pkcs7 datafinal"}, + {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR), "pkcs7 datafinal error"}, + {ERR_REASON(PKCS7_R_PKCS7_DATASIGN) , "pkcs7 datasign"}, + {ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR) , "pkcs7 parse error"}, + {ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"}, + {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"}, + {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) , "signature failure"}, + {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"}, + {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"}, + {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), "signing not supported for this key type"}, + {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, + {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) , "smime text error"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), "unable to find certificate"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), "unable to find message digest"}, + {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE) , "unknown digest type"}, + {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION) , "unknown operation"}, + {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"}, + {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, + {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE) , "wrong content type"}, + {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE) , "wrong pkcs7 type"}, + {0, NULL} +}; + +#endif + +void +ERR_load_PKCS7_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) { + ERR_load_strings(0, PKCS7_str_functs); + ERR_load_strings(0, PKCS7_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_PKCS7_strings); diff --git a/Libraries/libressl/crypto/poly1305/poly1305-donna.c b/Libraries/libressl/crypto/poly1305/poly1305-donna.c new file mode 100644 index 000000000..773ea4ebe --- /dev/null +++ b/Libraries/libressl/crypto/poly1305/poly1305-donna.c @@ -0,0 +1,321 @@ +/* $OpenBSD: poly1305-donna.c,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */ +/* + * Public Domain poly1305 from Andrew Moon + * Based on poly1305-donna.c, poly1305-donna-32.h and poly1305-donna.h from: + * https://github.com/floodyberry/poly1305-donna + */ + +#include + +static inline void poly1305_init(poly1305_context *ctx, + const unsigned char key[32]); +static inline void poly1305_update(poly1305_context *ctx, + const unsigned char *m, size_t bytes); +static inline void poly1305_finish(poly1305_context *ctx, + unsigned char mac[16]); + +/* + * poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication + * and 64 bit addition. + */ + +#define poly1305_block_size 16 + +/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */ +typedef struct poly1305_state_internal_t { + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + size_t leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ +static unsigned long +U8TO32(const unsigned char *p) +{ + return (((unsigned long)(p[0] & 0xff)) | + ((unsigned long)(p[1] & 0xff) << 8) | + ((unsigned long)(p[2] & 0xff) << 16) | + ((unsigned long)(p[3] & 0xff) << 24)); +} + +/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ +static void +U32TO8(unsigned char *p, unsigned long v) +{ + p[0] = (v) & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; +} + +static inline void +poly1305_init(poly1305_context *ctx, const unsigned char key[32]) +{ + poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + st->r[0] = (U8TO32(&key[0])) & 0x3ffffff; + st->r[1] = (U8TO32(&key[3]) >> 2) & 0x3ffff03; + st->r[2] = (U8TO32(&key[6]) >> 4) & 0x3ffc0ff; + st->r[3] = (U8TO32(&key[9]) >> 6) & 0x3f03fff; + st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + st->pad[0] = U8TO32(&key[16]); + st->pad[1] = U8TO32(&key[20]); + st->pad[2] = U8TO32(&key[24]); + st->pad[3] = U8TO32(&key[28]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) +{ + const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */ + unsigned long r0, r1, r2, r3, r4; + unsigned long s1, s2, s3, s4; + unsigned long h0, h1, h2, h3, h4; + unsigned long long d0, d1, d2, d3, d4; + unsigned long c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (U8TO32(m + 0)) & 0x3ffffff; + h1 += (U8TO32(m + 3) >> 2) & 0x3ffffff; + h2 += (U8TO32(m + 6) >> 4) & 0x3ffffff; + h3 += (U8TO32(m + 9) >> 6) & 0x3ffffff; + h4 += (U8TO32(m + 12) >> 8) | hibit; + + /* h *= r */ + d0 = ((unsigned long long)h0 * r0) + + ((unsigned long long)h1 * s4) + + ((unsigned long long)h2 * s3) + + ((unsigned long long)h3 * s2) + + ((unsigned long long)h4 * s1); + d1 = ((unsigned long long)h0 * r1) + + ((unsigned long long)h1 * r0) + + ((unsigned long long)h2 * s4) + + ((unsigned long long)h3 * s3) + + ((unsigned long long)h4 * s2); + d2 = ((unsigned long long)h0 * r2) + + ((unsigned long long)h1 * r1) + + ((unsigned long long)h2 * r0) + + ((unsigned long long)h3 * s4) + + ((unsigned long long)h4 * s3); + d3 = ((unsigned long long)h0 * r3) + + ((unsigned long long)h1 * r2) + + ((unsigned long long)h2 * r1) + + ((unsigned long long)h3 * r0) + + ((unsigned long long)h4 * s4); + d4 = ((unsigned long long)h0 * r4) + + ((unsigned long long)h1 * r3) + + ((unsigned long long)h2 * r2) + + ((unsigned long long)h3 * r1) + + ((unsigned long long)h4 * r0); + + /* (partial) h %= p */ + c = (unsigned long)(d0 >> 26); + h0 = (unsigned long)d0 & 0x3ffffff; + d1 += c; + c = (unsigned long)(d1 >> 26); + h1 = (unsigned long)d1 & 0x3ffffff; + d2 += c; + c = (unsigned long)(d2 >> 26); + h2 = (unsigned long)d2 & 0x3ffffff; + d3 += c; + c = (unsigned long)(d3 >> 26); + h3 = (unsigned long)d3 & 0x3ffffff; + d4 += c; + c = (unsigned long)(d4 >> 26); + h4 = (unsigned long)d4 & 0x3ffffff; + h0 += c * 5; + c = (h0 >> 26); + h0 = h0 & 0x3ffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +static inline void +poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) +{ + poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; + size_t i; + + /* handle leftover */ + if (st->leftover) { + size_t want = (poly1305_block_size - st->leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + st->buffer[st->leftover + i] = m[i]; + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) + return; + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + size_t want = (bytes & ~(poly1305_block_size - 1)); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) + st->buffer[st->leftover + i] = m[i]; + st->leftover += bytes; + } +} + +static inline void +poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) +{ + poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; + unsigned long h0, h1, h2, h3, h4, c; + unsigned long g0, g1, g2, g3, g4; + unsigned long long f; + unsigned long mask; + + /* process the remaining block */ + if (st->leftover) { + size_t i = st->leftover; + st->buffer[i++] = 1; + for (; i < poly1305_block_size; i++) + st->buffer[i] = 0; + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += c; + c = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += c; + c = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += c; + c = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += c * 5; + c = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + c; + c = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + c; + c = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + c; + c = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + c - (1 << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long)h0 + st->pad[0]; + h0 = (unsigned long)f; + f = (unsigned long long)h1 + st->pad[1] + (f >> 32); + h1 = (unsigned long)f; + f = (unsigned long long)h2 + st->pad[2] + (f >> 32); + h2 = (unsigned long)f; + f = (unsigned long long)h3 + st->pad[3] + (f >> 32); + h3 = (unsigned long)f; + + U32TO8(mac + 0, h0); + U32TO8(mac + 4, h1); + U32TO8(mac + 8, h2); + U32TO8(mac + 12, h3); + + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->r[3] = 0; + st->r[4] = 0; + st->pad[0] = 0; + st->pad[1] = 0; + st->pad[2] = 0; + st->pad[3] = 0; +} diff --git a/Libraries/libressl/crypto/poly1305/poly1305.c b/Libraries/libressl/crypto/poly1305/poly1305.c new file mode 100644 index 000000000..a34e8f8e8 --- /dev/null +++ b/Libraries/libressl/crypto/poly1305/poly1305.c @@ -0,0 +1,41 @@ +/* $OpenBSD: poly1305.c,v 1.4 2023/07/07 12:01:32 beck Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "poly1305-donna.c" + +void +CRYPTO_poly1305_init(poly1305_context *ctx, const unsigned char key[32]) +{ + poly1305_init(ctx, key); +} +LCRYPTO_ALIAS(CRYPTO_poly1305_init); + +void +CRYPTO_poly1305_update(poly1305_context *ctx, const unsigned char *in, + size_t len) +{ + poly1305_update(ctx, in, len); +} +LCRYPTO_ALIAS(CRYPTO_poly1305_update); + +void +CRYPTO_poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) +{ + poly1305_finish(ctx, mac); +} +LCRYPTO_ALIAS(CRYPTO_poly1305_finish); diff --git a/Libraries/libressl/crypto/rand/rand_err.c b/Libraries/libressl/crypto/rand/rand_err.c new file mode 100644 index 000000000..b156c0c87 --- /dev/null +++ b/Libraries/libressl/crypto/rand/rand_err.c @@ -0,0 +1,94 @@ +/* $OpenBSD: rand_err.c,v 1.17 2023/07/07 12:01:32 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason) + +static ERR_STRING_DATA RAND_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA RAND_str_reasons[] = { + {ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"}, + {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, + {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, + {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET), "no fips random method set"}, + {ERR_REASON(RAND_R_PRNG_NOT_SEEDED) , "PRNG not seeded"}, + {0, NULL} +}; + +#endif + +void +ERR_load_RAND_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { + ERR_load_strings(0, RAND_str_functs); + ERR_load_strings(0, RAND_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_RAND_strings); diff --git a/Libraries/libressl/crypto/rand/rand_lib.c b/Libraries/libressl/crypto/rand/rand_lib.c new file mode 100644 index 000000000..5c5df98c9 --- /dev/null +++ b/Libraries/libressl/crypto/rand/rand_lib.c @@ -0,0 +1,104 @@ +/* $OpenBSD: rand_lib.c,v 1.22 2023/07/07 19:37:54 beck Exp $ */ +/* + * Copyright (c) 2014 Ted Unangst + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include + +/* + * The useful functions in this file are at the bottom. + */ +int +RAND_set_rand_method(const RAND_METHOD *meth) +{ + return 1; +} +LCRYPTO_ALIAS(RAND_set_rand_method); + +const RAND_METHOD * +RAND_get_rand_method(void) +{ + return NULL; +} +LCRYPTO_ALIAS(RAND_get_rand_method); + +RAND_METHOD * +RAND_SSLeay(void) +{ + return NULL; +} +LCRYPTO_ALIAS(RAND_SSLeay); + +#ifndef OPENSSL_NO_ENGINE +int +RAND_set_rand_engine(ENGINE *engine) +{ + return 1; +} +LCRYPTO_ALIAS(RAND_set_rand_engine); +#endif + +void +RAND_cleanup(void) +{ + +} + +void +RAND_seed(const void *buf, int num) +{ + +} + +void +RAND_add(const void *buf, int num, double entropy) +{ + +} + +int +RAND_status(void) +{ + return 1; +} + +int +RAND_poll(void) +{ + return 1; +} + +/* + * Hurray. You've made it to the good parts. + */ +int +RAND_bytes(unsigned char *buf, int num) +{ + if (num > 0) + arc4random_buf(buf, num); + return 1; +} + +int +RAND_pseudo_bytes(unsigned char *buf, int num) +{ + if (num > 0) + arc4random_buf(buf, num); + return 1; +} diff --git a/Libraries/libressl/crypto/rand/randfile.c b/Libraries/libressl/crypto/rand/randfile.c new file mode 100644 index 000000000..00008af75 --- /dev/null +++ b/Libraries/libressl/crypto/rand/randfile.c @@ -0,0 +1,143 @@ +/* $OpenBSD: randfile.c,v 1.44 2023/07/07 19:37:54 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#undef BUFSIZE +#define BUFSIZE 1024 +#define RAND_DATA 1024 + +/* Note that these functions should not be used. */ + +int +RAND_load_file(const char *file, long bytes) +{ + /* the "whole" file */ + if (bytes == -1) + return 123456; + else + return bytes; +} + +int +RAND_write_file(const char *file) +{ + unsigned char buf[BUFSIZE]; + int i, ret = 0; + FILE *out = NULL; + int n, fd; + struct stat sb; + + /* + * If this file is a device, avoid opening it. + * XXX TOCTOU + */ + if (stat(file, &sb) != -1 && + (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))) { + return (1); + } + + fd = open(file, O_WRONLY|O_CREAT, 0600); + if (fd == -1) + return (1); + out = fdopen(fd, "wb"); + + if (out == NULL) { + close(fd); + return (1); + } + + n = RAND_DATA; + for (;;) { + i = (n > BUFSIZE) ? BUFSIZE : n; + n -= BUFSIZE; + arc4random_buf(buf, i); + i = fwrite(buf, 1, i, out); + if (i <= 0) { + ret = 0; + break; + } + ret += i; + if (n <= 0) + break; + } + + fclose(out); + explicit_bzero(buf, BUFSIZE); + return ret; +} + +const char * +RAND_file_name(char * buf, size_t size) +{ + if (strlcpy(buf, "/dev/urandom", size) >= size) + return (NULL); + return buf; +} diff --git a/Libraries/libressl/crypto/rc2/rc2_cbc.c b/Libraries/libressl/crypto/rc2/rc2_cbc.c new file mode 100644 index 000000000..1d8e2def9 --- /dev/null +++ b/Libraries/libressl/crypto/rc2/rc2_cbc.c @@ -0,0 +1,236 @@ +/* $OpenBSD: rc2_cbc.c,v 1.8 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_local.h" + +void +RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int encrypt) +{ + unsigned long tin0, tin1; + unsigned long tout0, tout1, xor0, xor1; + long l = length; + unsigned long tin[2]; + + if (encrypt) { + c2l(iv, tout0); + c2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) + { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) + { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +LCRYPTO_ALIAS(RC2_cbc_encrypt); + +void +RC2_encrypt(unsigned long *d, RC2_KEY *key) +{ + int i, n; + RC2_INT *p0, *p1; + RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT)l & 0xffff; + x1 = (RC2_INT)(l >> 16L); + l = d[1]; + x2 = (RC2_INT)l & 0xffff; + x3 = (RC2_INT)(l >> 16L); + + n = 3; + i = 5; + + p0 = p1 = &(key->data[0]); + for (;;) { + t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; + x0 = (t << 1)|(t >> 15); + t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; + x1 = (t << 2)|(t >> 14); + t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; + x2 = (t << 3)|(t >> 13); + t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; + x3 = (t << 5)|(t >> 11); + + if (--i == 0) { + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; + + x0 += p1[x3 & 0x3f]; + x1 += p1[x0 & 0x3f]; + x2 += p1[x1 & 0x3f]; + x3 += p1[x2 & 0x3f]; + } + } + + d[0] = (unsigned long)(x0 & 0xffff)|((unsigned long)(x1 & 0xffff) << + 16L); + d[1] = (unsigned long)(x2 & 0xffff)|((unsigned long)(x3 & 0xffff) << + 16L); +} +LCRYPTO_ALIAS(RC2_encrypt); + +void +RC2_decrypt(unsigned long *d, RC2_KEY *key) +{ + int i, n; + RC2_INT *p0, *p1; + RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT)l & 0xffff; + x1 = (RC2_INT)(l >> 16L); + l = d[1]; + x2 = (RC2_INT)l & 0xffff; + x3 = (RC2_INT)(l >> 16L); + + n = 3; + i = 5; + + p0 = &(key->data[63]); + p1 = &(key->data[0]); + for (;;) { + t = ((x3 << 11)|(x3 >> 5)) & 0xffff; + x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff; + t = ((x2 << 13)|(x2 >> 3)) & 0xffff; + x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff; + t = ((x1 << 14)|(x1 >> 2)) & 0xffff; + x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff; + t = ((x0 << 15)|(x0 >> 1)) & 0xffff; + x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff; + + if (--i == 0) { + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; + + x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; + x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; + x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; + x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; + } + } + + d[0] = (unsigned long)(x0 & 0xffff)|((unsigned long)(x1 & 0xffff) << + 16L); + d[1] = (unsigned long)(x2 & 0xffff)|((unsigned long)(x3 & 0xffff) << + 16L); +} +LCRYPTO_ALIAS(RC2_decrypt); diff --git a/Libraries/libressl/crypto/rc2/rc2_ecb.c b/Libraries/libressl/crypto/rc2/rc2_ecb.c new file mode 100644 index 000000000..6a3c8098e --- /dev/null +++ b/Libraries/libressl/crypto/rc2/rc2_ecb.c @@ -0,0 +1,91 @@ +/* $OpenBSD: rc2_ecb.c,v 1.9 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_local.h" +#include + +/* RC2 as implemented frm a posting from + * Newsgroups: sci.crypt + * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann) + * Subject: Specification for Ron Rivests Cipher No.2 + * Message-ID: <4fk39f$f70@net.auckland.ac.nz> + * Date: 11 Feb 1996 06:45:03 GMT + */ + +void +RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks, + int encrypt) +{ + unsigned long l, d[2]; + + c2l(in, l); + d[0] = l; + c2l(in, l); + d[1] = l; + if (encrypt) + RC2_encrypt(d, ks); + else + RC2_decrypt(d, ks); + l = d[0]; + l2c(l, out); + l = d[1]; + l2c(l, out); + l = d[0] = d[1] = 0; +} +LCRYPTO_ALIAS(RC2_ecb_encrypt); diff --git a/Libraries/libressl/crypto/rc2/rc2_local.h b/Libraries/libressl/crypto/rc2/rc2_local.h new file mode 100644 index 000000000..64c9c5388 --- /dev/null +++ b/Libraries/libressl/crypto/rc2/rc2_local.h @@ -0,0 +1,155 @@ +/* $OpenBSD: rc2_local.h,v 1.2 2023/07/07 08:29:37 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff);\ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff);\ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff);\ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff);\ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff);\ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff);\ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff);\ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff);\ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff);\ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff);\ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff);\ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff);\ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff);\ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff);\ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff);\ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff);\ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#define C_RC2(n) \ + t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ + x0=(t<<1)|(t>>15); \ + t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ + x1=(t<<2)|(t>>14); \ + t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ + x2=(t<<3)|(t>>13); \ + t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ + x3=(t<<5)|(t>>11); diff --git a/Libraries/libressl/crypto/rc2/rc2_skey.c b/Libraries/libressl/crypto/rc2/rc2_skey.c new file mode 100644 index 000000000..d33c02da8 --- /dev/null +++ b/Libraries/libressl/crypto/rc2/rc2_skey.c @@ -0,0 +1,142 @@ +/* $OpenBSD: rc2_skey.c,v 1.15 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "rc2_local.h" + +static const unsigned char key_table[256]={ + 0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79, + 0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e, + 0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5, + 0x87,0xb3,0x4f,0x13,0x61,0x45,0x6d,0x8d,0x09,0x81,0x7d,0x32, + 0xbd,0x8f,0x40,0xeb,0x86,0xb7,0x7b,0x0b,0xf0,0x95,0x21,0x22, + 0x5c,0x6b,0x4e,0x82,0x54,0xd6,0x65,0x93,0xce,0x60,0xb2,0x1c, + 0x73,0x56,0xc0,0x14,0xa7,0x8c,0xf1,0xdc,0x12,0x75,0xca,0x1f, + 0x3b,0xbe,0xe4,0xd1,0x42,0x3d,0xd4,0x30,0xa3,0x3c,0xb6,0x26, + 0x6f,0xbf,0x0e,0xda,0x46,0x69,0x07,0x57,0x27,0xf2,0x1d,0x9b, + 0xbc,0x94,0x43,0x03,0xf8,0x11,0xc7,0xf6,0x90,0xef,0x3e,0xe7, + 0x06,0xc3,0xd5,0x2f,0xc8,0x66,0x1e,0xd7,0x08,0xe8,0xea,0xde, + 0x80,0x52,0xee,0xf7,0x84,0xaa,0x72,0xac,0x35,0x4d,0x6a,0x2a, + 0x96,0x1a,0xd2,0x71,0x5a,0x15,0x49,0x74,0x4b,0x9f,0xd0,0x5e, + 0x04,0x18,0xa4,0xec,0xc2,0xe0,0x41,0x6e,0x0f,0x51,0xcb,0xcc, + 0x24,0x91,0xaf,0x50,0xa1,0xf4,0x70,0x39,0x99,0x7c,0x3a,0x85, + 0x23,0xb8,0xb4,0x7a,0xfc,0x02,0x36,0x5b,0x25,0x55,0x97,0x31, + 0x2d,0x5d,0xfa,0x98,0xe3,0x8a,0x92,0xae,0x05,0xdf,0x29,0x10, + 0x67,0x6c,0xba,0xc9,0xd3,0x00,0xe6,0xcf,0xe1,0x9e,0xa8,0x2c, + 0x63,0x16,0x01,0x3f,0x58,0xe2,0x89,0xa9,0x0d,0x38,0x34,0x1b, + 0xab,0x33,0xff,0xb0,0xbb,0x48,0x0c,0x5f,0xb9,0xb1,0xcd,0x2e, + 0xc5,0xf3,0xdb,0x47,0xe5,0xa5,0x9c,0x77,0x0a,0xa6,0x20,0x68, + 0xfe,0x7f,0xc1,0xad, + }; + +/* It has come to my attention that there are 2 versions of the RC2 + * key schedule. One which is normal, and anther which has a hook to + * use a reduced key length. + * BSAFE uses the 'retarded' version. What I previously shipped is + * the same as specifying 1024 for the 'bits' parameter. Bsafe uses + * a version where the bits parameter is the same as len*8 */ +void +RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) +{ + int i, j; + unsigned char *k; + RC2_INT *ki; + unsigned int c, d; + + k = (unsigned char *)&(key->data[0]); + *k = 0; /* for if there is a zero length key */ + + if (len > 128) + len = 128; + if (bits <= 0) + bits = 1024; + if (bits > 1024) + bits = 1024; + + for (i = 0; i < len; i++) + k[i] = data[i]; + + /* expand table */ + d = k[len - 1]; + j = 0; + for (i = len; i < 128; i++, j++) + { + d = key_table[(k[j] + d) & 0xff]; + k[i] = d; + } + + /* hmm.... key reduction to 'bits' bits */ + + j = (bits + 7) >> 3; + i = 128 - j; + c = (0xff >> (-bits & 0x07)); + + d = key_table[k[i] & c]; + k[i] = d; + while (i--) { + d = key_table[k[i + j] ^ d]; + k[i] = d; + } + + /* copy from bytes into RC2_INT's */ + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) + *(ki--) = ((k[i] << 8)|k[i - 1]) & 0xffff; +} +LCRYPTO_ALIAS(RC2_set_key); diff --git a/Libraries/libressl/crypto/rc2/rc2cfb64.c b/Libraries/libressl/crypto/rc2/rc2cfb64.c new file mode 100644 index 000000000..21266c430 --- /dev/null +++ b/Libraries/libressl/crypto/rc2/rc2cfb64.c @@ -0,0 +1,124 @@ +/* $OpenBSD: rc2cfb64.c,v 1.8 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_local.h" + +/* The input and output encrypted as though 64bit cfb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ + +void +RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int encrypt) +{ + unsigned long v0, v1, t; + int n = *num; + long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC2_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC2_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} +LCRYPTO_ALIAS(RC2_cfb64_encrypt); diff --git a/Libraries/libressl/crypto/rc2/rc2ofb64.c b/Libraries/libressl/crypto/rc2/rc2ofb64.c new file mode 100644 index 000000000..73d8323e9 --- /dev/null +++ b/Libraries/libressl/crypto/rc2/rc2ofb64.c @@ -0,0 +1,111 @@ +/* $OpenBSD: rc2ofb64.c,v 1.8 2023/07/07 13:40:44 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_local.h" + +/* The input and output encrypted as though 64bit ofb mode is being + * used. The extra state information to record how much of the + * 64bit block we have used is contained in *num; + */ +void +RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num) +{ + unsigned long v0, v1, t; + int n = *num; + long l = length; + unsigned char d[8]; + char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + RC2_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} +LCRYPTO_ALIAS(RC2_ofb64_encrypt); diff --git a/Libraries/libressl/crypto/rc4/rc4-elf-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-elf-x86_64.S new file mode 100644 index 000000000..aa7f8ca18 --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-elf-x86_64.S @@ -0,0 +1,598 @@ +#include "x86_arch.h" +.text + +.hidden OPENSSL_ia32cap_P + +.globl RC4 +.type RC4,@function +.align 16 +RC4: + endbr64 + orq %rsi,%rsi + jne .Lentry + retq +.Lentry: + pushq %rbx + pushq %r12 + pushq %r13 +.Lprologue: + movq %rsi,%r11 + movq %rdx,%r12 + movq %rcx,%r13 + xorq %r10,%r10 + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%r10b + movb -4(%rdi),%cl + cmpl $-1,256(%rdi) + je .LRC4_CHAR + movl OPENSSL_ia32cap_P(%rip),%r8d + xorq %rbx,%rbx + incb %r10b + subq %r10,%rbx + subq %r12,%r13 + movl (%rdi,%r10,4),%eax + testq $-16,%r11 + jz .Lloop1 + btl $IA32CAP_BIT0_INTEL,%r8d + jc .Lintel + andq $7,%rbx + leaq 1(%r10),%rsi + jz .Loop8 + subq %rbx,%r11 +.Loop8_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %rbx + jnz .Loop8_warmup + + leaq 1(%r10),%rsi + jmp .Loop8 +.align 16 +.Loop8: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 0(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,0(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,4(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 8(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,8(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 12(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,12(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 16(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,16(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 20(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,20(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 24(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,24(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%sil + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl -4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,28(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%r10b + rorq $8,%r8 + subq $8,%r11 + + xorq (%r12),%r8 + movq %r8,(%r13,%r12,1) + leaq 8(%r12),%r12 + + testq $-8,%r11 + jnz .Loop8 + cmpq $0,%r11 + jne .Lloop1 + jmp .Lexit + +.align 16 +.Lintel: + testq $-32,%r11 + jz .Lloop1 + andq $15,%rbx + jz .Loop16_is_hot + subq %rbx,%r11 +.Loop16_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %rbx + jnz .Loop16_warmup + + movq %rcx,%rbx + xorq %rcx,%rcx + movb %bl,%cl + +.Loop16_is_hot: + leaq (%rdi,%r10,4),%rsi + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + jmp .Loop16_enter +.align 16 +.Loop16: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm2 + psllq $8,%xmm1 + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + pxor %xmm1,%xmm2 + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + movdqu %xmm2,(%r13,%r12,1) + leaq 16(%r12),%r12 +.Loop16_enter: + movl (%rdi,%rcx,4),%edx + pxor %xmm1,%xmm1 + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 8(%rsi),%eax + movzbl %bl,%ebx + movl %edx,4(%rsi) + addb %al,%cl + pinsrw $0,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 12(%rsi),%ebx + movzbl %al,%eax + movl %edx,8(%rsi) + addb %bl,%cl + pinsrw $1,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 16(%rsi),%eax + movzbl %bl,%ebx + movl %edx,12(%rsi) + addb %al,%cl + pinsrw $1,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 20(%rsi),%ebx + movzbl %al,%eax + movl %edx,16(%rsi) + addb %bl,%cl + pinsrw $2,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 24(%rsi),%eax + movzbl %bl,%ebx + movl %edx,20(%rsi) + addb %al,%cl + pinsrw $2,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 28(%rsi),%ebx + movzbl %al,%eax + movl %edx,24(%rsi) + addb %bl,%cl + pinsrw $3,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 32(%rsi),%eax + movzbl %bl,%ebx + movl %edx,28(%rsi) + addb %al,%cl + pinsrw $3,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 36(%rsi),%ebx + movzbl %al,%eax + movl %edx,32(%rsi) + addb %bl,%cl + pinsrw $4,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 40(%rsi),%eax + movzbl %bl,%ebx + movl %edx,36(%rsi) + addb %al,%cl + pinsrw $4,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 44(%rsi),%ebx + movzbl %al,%eax + movl %edx,40(%rsi) + addb %bl,%cl + pinsrw $5,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 48(%rsi),%eax + movzbl %bl,%ebx + movl %edx,44(%rsi) + addb %al,%cl + pinsrw $5,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 52(%rsi),%ebx + movzbl %al,%eax + movl %edx,48(%rsi) + addb %bl,%cl + pinsrw $6,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 56(%rsi),%eax + movzbl %bl,%ebx + movl %edx,52(%rsi) + addb %al,%cl + pinsrw $6,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 60(%rsi),%ebx + movzbl %al,%eax + movl %edx,56(%rsi) + addb %bl,%cl + pinsrw $7,(%rdi,%rax,4),%xmm0 + addb $16,%r10b + movdqu (%r12),%xmm2 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movzbl %bl,%ebx + movl %edx,60(%rsi) + leaq (%rdi,%r10,4),%rsi + pinsrw $7,(%rdi,%rbx,4),%xmm1 + movl (%rsi),%eax + movq %rcx,%rbx + xorq %rcx,%rcx + subq $16,%r11 + movb %bl,%cl + testq $-16,%r11 + jnz .Loop16 + + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + movdqu %xmm2,(%r13,%r12,1) + leaq 16(%r12),%r12 + + cmpq $0,%r11 + jne .Lloop1 + jmp .Lexit + +.align 16 +.Lloop1: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %r11 + jnz .Lloop1 + jmp .Lexit + +.align 16 +.LRC4_CHAR: + addb $1,%r10b + movzbl (%rdi,%r10,1),%eax + testq $-8,%r11 + jz .Lcloop1 + jmp .Lcloop8 +.align 16 +.Lcloop8: + movl (%r12),%r8d + movl 4(%r12),%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov0 + movq %rax,%rbx +.Lcmov0: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov1 + movq %rbx,%rax +.Lcmov1: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov2 + movq %rax,%rbx +.Lcmov2: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov3 + movq %rbx,%rax +.Lcmov3: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov4 + movq %rax,%rbx +.Lcmov4: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov5 + movq %rbx,%rax +.Lcmov5: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov6 + movq %rax,%rbx +.Lcmov6: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov7 + movq %rbx,%rax +.Lcmov7: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + leaq -8(%r11),%r11 + movl %r8d,(%r13) + leaq 8(%r12),%r12 + movl %r9d,4(%r13) + leaq 8(%r13),%r13 + + testq $-8,%r11 + jnz .Lcloop8 + cmpq $0,%r11 + jne .Lcloop1 + jmp .Lexit +.align 16 +.Lcloop1: + addb %al,%cl + movzbl %cl,%ecx + movzbl (%rdi,%rcx,1),%edx + movb %al,(%rdi,%rcx,1) + movb %dl,(%rdi,%r10,1) + addb %al,%dl + addb $1,%r10b + movzbl %dl,%edx + movzbl %r10b,%r10d + movzbl (%rdi,%rdx,1),%edx + movzbl (%rdi,%r10,1),%eax + xorb (%r12),%dl + leaq 1(%r12),%r12 + movb %dl,(%r13) + leaq 1(%r13),%r13 + subq $1,%r11 + jnz .Lcloop1 + jmp .Lexit + +.align 16 +.Lexit: + subb $1,%r10b + movl %r10d,-8(%rdi) + movl %ecx,-4(%rdi) + + movq (%rsp),%r13 + movq 8(%rsp),%r12 + movq 16(%rsp),%rbx + addq $24,%rsp +.Lepilogue: + retq +.size RC4,.-RC4 +.globl RC4_set_key +.type RC4_set_key,@function +.align 16 +RC4_set_key: + endbr64 + leaq 8(%rdi),%rdi + leaq (%rdx,%rsi,1),%rdx + negq %rsi + movq %rsi,%rcx + xorl %eax,%eax + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + + movl OPENSSL_ia32cap_P(%rip),%r8d + btl $IA32CAP_BIT0_INTELP4,%r8d + jc .Lc1stloop + jmp .Lw1stloop + +.align 16 +.Lw1stloop: + movl %eax,(%rdi,%rax,4) + addb $1,%al + jnc .Lw1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.align 16 +.Lw2ndloop: + movl (%rdi,%r9,4),%r10d + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movl (%rdi,%r8,4),%r11d + cmovzq %rcx,%rsi + movl %r10d,(%rdi,%r8,4) + movl %r11d,(%rdi,%r9,4) + addb $1,%r9b + jnc .Lw2ndloop + jmp .Lexit_key + +.align 16 +.Lc1stloop: + movb %al,(%rdi,%rax,1) + addb $1,%al + jnc .Lc1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.align 16 +.Lc2ndloop: + movb (%rdi,%r9,1),%r10b + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movb (%rdi,%r8,1),%r11b + jnz .Lcnowrap + movq %rcx,%rsi +.Lcnowrap: + movb %r10b,(%rdi,%r8,1) + movb %r11b,(%rdi,%r9,1) + addb $1,%r9b + jnc .Lc2ndloop + movl $-1,256(%rdi) + +.align 16 +.Lexit_key: + xorl %eax,%eax + movl %eax,-8(%rdi) + movl %eax,-4(%rdi) + retq +.size RC4_set_key,.-RC4_set_key +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/rc4/rc4-macosx-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-macosx-x86_64.S new file mode 100644 index 000000000..50f40fdeb --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-macosx-x86_64.S @@ -0,0 +1,592 @@ +#include "x86_arch.h" +.text + +.private_extern _OPENSSL_ia32cap_P + +.globl _RC4 + +.p2align 4 +_RC4: orq %rsi,%rsi + jne L$entry + retq +L$entry: + pushq %rbx + pushq %r12 + pushq %r13 +L$prologue: + movq %rsi,%r11 + movq %rdx,%r12 + movq %rcx,%r13 + xorq %r10,%r10 + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%r10b + movb -4(%rdi),%cl + cmpl $-1,256(%rdi) + je L$RC4_CHAR + movl _OPENSSL_ia32cap_P(%rip),%r8d + xorq %rbx,%rbx + incb %r10b + subq %r10,%rbx + subq %r12,%r13 + movl (%rdi,%r10,4),%eax + testq $-16,%r11 + jz L$loop1 + btl $IA32CAP_BIT0_INTEL,%r8d + jc L$intel + andq $7,%rbx + leaq 1(%r10),%rsi + jz L$oop8 + subq %rbx,%r11 +L$oop8_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %rbx + jnz L$oop8_warmup + + leaq 1(%r10),%rsi + jmp L$oop8 +.p2align 4 +L$oop8: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 0(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,0(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,4(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 8(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,8(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 12(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,12(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 16(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,16(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 20(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,20(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 24(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,24(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%sil + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl -4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,28(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%r10b + rorq $8,%r8 + subq $8,%r11 + + xorq (%r12),%r8 + movq %r8,(%r13,%r12,1) + leaq 8(%r12),%r12 + + testq $-8,%r11 + jnz L$oop8 + cmpq $0,%r11 + jne L$loop1 + jmp L$exit + +.p2align 4 +L$intel: + testq $-32,%r11 + jz L$loop1 + andq $15,%rbx + jz L$oop16_is_hot + subq %rbx,%r11 +L$oop16_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %rbx + jnz L$oop16_warmup + + movq %rcx,%rbx + xorq %rcx,%rcx + movb %bl,%cl + +L$oop16_is_hot: + leaq (%rdi,%r10,4),%rsi + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + jmp L$oop16_enter +.p2align 4 +L$oop16: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm2 + psllq $8,%xmm1 + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + pxor %xmm1,%xmm2 + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + movdqu %xmm2,(%r13,%r12,1) + leaq 16(%r12),%r12 +L$oop16_enter: + movl (%rdi,%rcx,4),%edx + pxor %xmm1,%xmm1 + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 8(%rsi),%eax + movzbl %bl,%ebx + movl %edx,4(%rsi) + addb %al,%cl + pinsrw $0,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 12(%rsi),%ebx + movzbl %al,%eax + movl %edx,8(%rsi) + addb %bl,%cl + pinsrw $1,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 16(%rsi),%eax + movzbl %bl,%ebx + movl %edx,12(%rsi) + addb %al,%cl + pinsrw $1,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 20(%rsi),%ebx + movzbl %al,%eax + movl %edx,16(%rsi) + addb %bl,%cl + pinsrw $2,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 24(%rsi),%eax + movzbl %bl,%ebx + movl %edx,20(%rsi) + addb %al,%cl + pinsrw $2,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 28(%rsi),%ebx + movzbl %al,%eax + movl %edx,24(%rsi) + addb %bl,%cl + pinsrw $3,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 32(%rsi),%eax + movzbl %bl,%ebx + movl %edx,28(%rsi) + addb %al,%cl + pinsrw $3,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 36(%rsi),%ebx + movzbl %al,%eax + movl %edx,32(%rsi) + addb %bl,%cl + pinsrw $4,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 40(%rsi),%eax + movzbl %bl,%ebx + movl %edx,36(%rsi) + addb %al,%cl + pinsrw $4,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 44(%rsi),%ebx + movzbl %al,%eax + movl %edx,40(%rsi) + addb %bl,%cl + pinsrw $5,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 48(%rsi),%eax + movzbl %bl,%ebx + movl %edx,44(%rsi) + addb %al,%cl + pinsrw $5,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 52(%rsi),%ebx + movzbl %al,%eax + movl %edx,48(%rsi) + addb %bl,%cl + pinsrw $6,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 56(%rsi),%eax + movzbl %bl,%ebx + movl %edx,52(%rsi) + addb %al,%cl + pinsrw $6,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 60(%rsi),%ebx + movzbl %al,%eax + movl %edx,56(%rsi) + addb %bl,%cl + pinsrw $7,(%rdi,%rax,4),%xmm0 + addb $16,%r10b + movdqu (%r12),%xmm2 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movzbl %bl,%ebx + movl %edx,60(%rsi) + leaq (%rdi,%r10,4),%rsi + pinsrw $7,(%rdi,%rbx,4),%xmm1 + movl (%rsi),%eax + movq %rcx,%rbx + xorq %rcx,%rcx + subq $16,%r11 + movb %bl,%cl + testq $-16,%r11 + jnz L$oop16 + + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + movdqu %xmm2,(%r13,%r12,1) + leaq 16(%r12),%r12 + + cmpq $0,%r11 + jne L$loop1 + jmp L$exit + +.p2align 4 +L$loop1: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %r11 + jnz L$loop1 + jmp L$exit + +.p2align 4 +L$RC4_CHAR: + addb $1,%r10b + movzbl (%rdi,%r10,1),%eax + testq $-8,%r11 + jz L$cloop1 + jmp L$cloop8 +.p2align 4 +L$cloop8: + movl (%r12),%r8d + movl 4(%r12),%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne L$cmov0 + movq %rax,%rbx +L$cmov0: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne L$cmov1 + movq %rbx,%rax +L$cmov1: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne L$cmov2 + movq %rax,%rbx +L$cmov2: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne L$cmov3 + movq %rbx,%rax +L$cmov3: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne L$cmov4 + movq %rax,%rbx +L$cmov4: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne L$cmov5 + movq %rbx,%rax +L$cmov5: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne L$cmov6 + movq %rax,%rbx +L$cmov6: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne L$cmov7 + movq %rbx,%rax +L$cmov7: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + leaq -8(%r11),%r11 + movl %r8d,(%r13) + leaq 8(%r12),%r12 + movl %r9d,4(%r13) + leaq 8(%r13),%r13 + + testq $-8,%r11 + jnz L$cloop8 + cmpq $0,%r11 + jne L$cloop1 + jmp L$exit +.p2align 4 +L$cloop1: + addb %al,%cl + movzbl %cl,%ecx + movzbl (%rdi,%rcx,1),%edx + movb %al,(%rdi,%rcx,1) + movb %dl,(%rdi,%r10,1) + addb %al,%dl + addb $1,%r10b + movzbl %dl,%edx + movzbl %r10b,%r10d + movzbl (%rdi,%rdx,1),%edx + movzbl (%rdi,%r10,1),%eax + xorb (%r12),%dl + leaq 1(%r12),%r12 + movb %dl,(%r13) + leaq 1(%r13),%r13 + subq $1,%r11 + jnz L$cloop1 + jmp L$exit + +.p2align 4 +L$exit: + subb $1,%r10b + movl %r10d,-8(%rdi) + movl %ecx,-4(%rdi) + + movq (%rsp),%r13 + movq 8(%rsp),%r12 + movq 16(%rsp),%rbx + addq $24,%rsp +L$epilogue: + retq + +.globl _RC4_set_key + +.p2align 4 +_RC4_set_key: + leaq 8(%rdi),%rdi + leaq (%rdx,%rsi,1),%rdx + negq %rsi + movq %rsi,%rcx + xorl %eax,%eax + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + + movl _OPENSSL_ia32cap_P(%rip),%r8d + btl $IA32CAP_BIT0_INTELP4,%r8d + jc L$c1stloop + jmp L$w1stloop + +.p2align 4 +L$w1stloop: + movl %eax,(%rdi,%rax,4) + addb $1,%al + jnc L$w1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.p2align 4 +L$w2ndloop: + movl (%rdi,%r9,4),%r10d + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movl (%rdi,%r8,4),%r11d + cmovzq %rcx,%rsi + movl %r10d,(%rdi,%r8,4) + movl %r11d,(%rdi,%r9,4) + addb $1,%r9b + jnc L$w2ndloop + jmp L$exit_key + +.p2align 4 +L$c1stloop: + movb %al,(%rdi,%rax,1) + addb $1,%al + jnc L$c1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.p2align 4 +L$c2ndloop: + movb (%rdi,%r9,1),%r10b + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movb (%rdi,%r8,1),%r11b + jnz L$cnowrap + movq %rcx,%rsi +L$cnowrap: + movb %r10b,(%rdi,%r8,1) + movb %r11b,(%rdi,%r9,1) + addb $1,%r9b + jnc L$c2ndloop + movl $-1,256(%rdi) + +.p2align 4 +L$exit_key: + xorl %eax,%eax + movl %eax,-8(%rdi) + movl %eax,-4(%rdi) + retq + diff --git a/Libraries/libressl/crypto/rc4/rc4-masm-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-masm-x86_64.S new file mode 100644 index 000000000..89371cea1 --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-masm-x86_64.S @@ -0,0 +1,691 @@ +; 1 "crypto/rc4/rc4-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/rc4/rc4-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/rc4/rc4-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' +EXTERN OPENSSL_ia32cap_P:NEAR + + +PUBLIC RC4 + +ALIGN 16 +RC4 PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_RC4:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + or rsi,rsi + jne $L$entry + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$entry:: + push rbx + push r12 + push r13 +$L$prologue:: + mov r11,rsi + mov r12,rdx + mov r13,rcx + xor r10,r10 + xor rcx,rcx + + lea rdi,QWORD PTR[8+rdi] + mov r10b,BYTE PTR[((-8))+rdi] + mov cl,BYTE PTR[((-4))+rdi] + cmp DWORD PTR[256+rdi],-1 + je $L$RC4_CHAR + mov r8d,DWORD PTR[OPENSSL_ia32cap_P] + xor rbx,rbx + inc r10b + sub rbx,r10 + sub r13,r12 + mov eax,DWORD PTR[r10*4+rdi] + test r11,-16 + jz $L$loop1 + bt r8d,30 + jc $L$intel + and rbx,7 + lea rsi,QWORD PTR[1+r10] + jz $L$oop8 + sub r11,rbx +$L$oop8_warmup:: + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov DWORD PTR[r10*4+rdi],edx + add al,dl + inc r10b + mov edx,DWORD PTR[rax*4+rdi] + mov eax,DWORD PTR[r10*4+rdi] + xor dl,BYTE PTR[r12] + mov BYTE PTR[r12*1+r13],dl + lea r12,QWORD PTR[1+r12] + dec rbx + jnz $L$oop8_warmup + + lea rsi,QWORD PTR[1+r10] + jmp $L$oop8 +ALIGN 16 +$L$oop8:: + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov ebx,DWORD PTR[rsi*4+rdi] + ror r8,8 + mov DWORD PTR[r10*4+rdi],edx + add dl,al + mov r8b,BYTE PTR[rdx*4+rdi] + add cl,bl + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + mov eax,DWORD PTR[4+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[4+r10*4+rdi],edx + add dl,bl + mov r8b,BYTE PTR[rdx*4+rdi] + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov ebx,DWORD PTR[8+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[8+r10*4+rdi],edx + add dl,al + mov r8b,BYTE PTR[rdx*4+rdi] + add cl,bl + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + mov eax,DWORD PTR[12+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[12+r10*4+rdi],edx + add dl,bl + mov r8b,BYTE PTR[rdx*4+rdi] + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov ebx,DWORD PTR[16+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[16+r10*4+rdi],edx + add dl,al + mov r8b,BYTE PTR[rdx*4+rdi] + add cl,bl + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + mov eax,DWORD PTR[20+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[20+r10*4+rdi],edx + add dl,bl + mov r8b,BYTE PTR[rdx*4+rdi] + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov ebx,DWORD PTR[24+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[24+r10*4+rdi],edx + add dl,al + mov r8b,BYTE PTR[rdx*4+rdi] + add sil,8 + add cl,bl + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + mov eax,DWORD PTR[((-4))+rsi*4+rdi] + ror r8,8 + mov DWORD PTR[28+r10*4+rdi],edx + add dl,bl + mov r8b,BYTE PTR[rdx*4+rdi] + add r10b,8 + ror r8,8 + sub r11,8 + + xor r8,QWORD PTR[r12] + mov QWORD PTR[r12*1+r13],r8 + lea r12,QWORD PTR[8+r12] + + test r11,-8 + jnz $L$oop8 + cmp r11,0 + jne $L$loop1 + jmp $L$exit + +ALIGN 16 +$L$intel:: + test r11,-32 + jz $L$loop1 + and rbx,15 + jz $L$oop16_is_hot + sub r11,rbx +$L$oop16_warmup:: + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov DWORD PTR[r10*4+rdi],edx + add al,dl + inc r10b + mov edx,DWORD PTR[rax*4+rdi] + mov eax,DWORD PTR[r10*4+rdi] + xor dl,BYTE PTR[r12] + mov BYTE PTR[r12*1+r13],dl + lea r12,QWORD PTR[1+r12] + dec rbx + jnz $L$oop16_warmup + + mov rbx,rcx + xor rcx,rcx + mov cl,bl + +$L$oop16_is_hot:: + lea rsi,QWORD PTR[r10*4+rdi] + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + pxor xmm0,xmm0 + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[4+rsi] + movzx eax,al + mov DWORD PTR[rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],0 + jmp $L$oop16_enter +ALIGN 16 +$L$oop16:: + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + pxor xmm2,xmm0 + psllq xmm1,8 + pxor xmm0,xmm0 + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[4+rsi] + movzx eax,al + mov DWORD PTR[rsi],edx + pxor xmm2,xmm1 + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],0 + movdqu XMMWORD PTR[r12*1+r13],xmm2 + lea r12,QWORD PTR[16+r12] +$L$oop16_enter:: + mov edx,DWORD PTR[rcx*4+rdi] + pxor xmm1,xmm1 + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[8+rsi] + movzx ebx,bl + mov DWORD PTR[4+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],0 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[12+rsi] + movzx eax,al + mov DWORD PTR[8+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],1 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[16+rsi] + movzx ebx,bl + mov DWORD PTR[12+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],1 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[20+rsi] + movzx eax,al + mov DWORD PTR[16+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],2 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[24+rsi] + movzx ebx,bl + mov DWORD PTR[20+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],2 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[28+rsi] + movzx eax,al + mov DWORD PTR[24+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],3 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[32+rsi] + movzx ebx,bl + mov DWORD PTR[28+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],3 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[36+rsi] + movzx eax,al + mov DWORD PTR[32+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],4 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[40+rsi] + movzx ebx,bl + mov DWORD PTR[36+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],4 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[44+rsi] + movzx eax,al + mov DWORD PTR[40+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],5 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[48+rsi] + movzx ebx,bl + mov DWORD PTR[44+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],5 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[52+rsi] + movzx eax,al + mov DWORD PTR[48+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],6 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + mov eax,DWORD PTR[56+rsi] + movzx ebx,bl + mov DWORD PTR[52+rsi],edx + add cl,al + pinsrw xmm1,WORD PTR[rbx*4+rdi],6 + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + add al,dl + mov ebx,DWORD PTR[60+rsi] + movzx eax,al + mov DWORD PTR[56+rsi],edx + add cl,bl + pinsrw xmm0,WORD PTR[rax*4+rdi],7 + add r10b,16 + movdqu xmm2,XMMWORD PTR[r12] + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],ebx + add bl,dl + movzx ebx,bl + mov DWORD PTR[60+rsi],edx + lea rsi,QWORD PTR[r10*4+rdi] + pinsrw xmm1,WORD PTR[rbx*4+rdi],7 + mov eax,DWORD PTR[rsi] + mov rbx,rcx + xor rcx,rcx + sub r11,16 + mov cl,bl + test r11,-16 + jnz $L$oop16 + + psllq xmm1,8 + pxor xmm2,xmm0 + pxor xmm2,xmm1 + movdqu XMMWORD PTR[r12*1+r13],xmm2 + lea r12,QWORD PTR[16+r12] + + cmp r11,0 + jne $L$loop1 + jmp $L$exit + +ALIGN 16 +$L$loop1:: + add cl,al + mov edx,DWORD PTR[rcx*4+rdi] + mov DWORD PTR[rcx*4+rdi],eax + mov DWORD PTR[r10*4+rdi],edx + add al,dl + inc r10b + mov edx,DWORD PTR[rax*4+rdi] + mov eax,DWORD PTR[r10*4+rdi] + xor dl,BYTE PTR[r12] + mov BYTE PTR[r12*1+r13],dl + lea r12,QWORD PTR[1+r12] + dec r11 + jnz $L$loop1 + jmp $L$exit + +ALIGN 16 +$L$RC4_CHAR:: + add r10b,1 + movzx eax,BYTE PTR[r10*1+rdi] + test r11,-8 + jz $L$cloop1 + jmp $L$cloop8 +ALIGN 16 +$L$cloop8:: + mov r8d,DWORD PTR[r12] + mov r9d,DWORD PTR[4+r12] + add cl,al + lea rsi,QWORD PTR[1+r10] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx esi,sil + movzx ebx,BYTE PTR[rsi*1+rdi] + mov BYTE PTR[rcx*1+rdi],al + cmp rcx,rsi + mov BYTE PTR[r10*1+rdi],dl + jne $L$cmov0 + mov rbx,rax +$L$cmov0:: + add dl,al + xor r8b,BYTE PTR[rdx*1+rdi] + ror r8d,8 + add cl,bl + lea r10,QWORD PTR[1+rsi] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx r10d,r10b + movzx eax,BYTE PTR[r10*1+rdi] + mov BYTE PTR[rcx*1+rdi],bl + cmp rcx,r10 + mov BYTE PTR[rsi*1+rdi],dl + jne $L$cmov1 + mov rax,rbx +$L$cmov1:: + add dl,bl + xor r8b,BYTE PTR[rdx*1+rdi] + ror r8d,8 + add cl,al + lea rsi,QWORD PTR[1+r10] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx esi,sil + movzx ebx,BYTE PTR[rsi*1+rdi] + mov BYTE PTR[rcx*1+rdi],al + cmp rcx,rsi + mov BYTE PTR[r10*1+rdi],dl + jne $L$cmov2 + mov rbx,rax +$L$cmov2:: + add dl,al + xor r8b,BYTE PTR[rdx*1+rdi] + ror r8d,8 + add cl,bl + lea r10,QWORD PTR[1+rsi] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx r10d,r10b + movzx eax,BYTE PTR[r10*1+rdi] + mov BYTE PTR[rcx*1+rdi],bl + cmp rcx,r10 + mov BYTE PTR[rsi*1+rdi],dl + jne $L$cmov3 + mov rax,rbx +$L$cmov3:: + add dl,bl + xor r8b,BYTE PTR[rdx*1+rdi] + ror r8d,8 + add cl,al + lea rsi,QWORD PTR[1+r10] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx esi,sil + movzx ebx,BYTE PTR[rsi*1+rdi] + mov BYTE PTR[rcx*1+rdi],al + cmp rcx,rsi + mov BYTE PTR[r10*1+rdi],dl + jne $L$cmov4 + mov rbx,rax +$L$cmov4:: + add dl,al + xor r9b,BYTE PTR[rdx*1+rdi] + ror r9d,8 + add cl,bl + lea r10,QWORD PTR[1+rsi] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx r10d,r10b + movzx eax,BYTE PTR[r10*1+rdi] + mov BYTE PTR[rcx*1+rdi],bl + cmp rcx,r10 + mov BYTE PTR[rsi*1+rdi],dl + jne $L$cmov5 + mov rax,rbx +$L$cmov5:: + add dl,bl + xor r9b,BYTE PTR[rdx*1+rdi] + ror r9d,8 + add cl,al + lea rsi,QWORD PTR[1+r10] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx esi,sil + movzx ebx,BYTE PTR[rsi*1+rdi] + mov BYTE PTR[rcx*1+rdi],al + cmp rcx,rsi + mov BYTE PTR[r10*1+rdi],dl + jne $L$cmov6 + mov rbx,rax +$L$cmov6:: + add dl,al + xor r9b,BYTE PTR[rdx*1+rdi] + ror r9d,8 + add cl,bl + lea r10,QWORD PTR[1+rsi] + movzx edx,BYTE PTR[rcx*1+rdi] + movzx r10d,r10b + movzx eax,BYTE PTR[r10*1+rdi] + mov BYTE PTR[rcx*1+rdi],bl + cmp rcx,r10 + mov BYTE PTR[rsi*1+rdi],dl + jne $L$cmov7 + mov rax,rbx +$L$cmov7:: + add dl,bl + xor r9b,BYTE PTR[rdx*1+rdi] + ror r9d,8 + lea r11,QWORD PTR[((-8))+r11] + mov DWORD PTR[r13],r8d + lea r12,QWORD PTR[8+r12] + mov DWORD PTR[4+r13],r9d + lea r13,QWORD PTR[8+r13] + + test r11,-8 + jnz $L$cloop8 + cmp r11,0 + jne $L$cloop1 + jmp $L$exit +ALIGN 16 +$L$cloop1:: + add cl,al + movzx ecx,cl + movzx edx,BYTE PTR[rcx*1+rdi] + mov BYTE PTR[rcx*1+rdi],al + mov BYTE PTR[r10*1+rdi],dl + add dl,al + add r10b,1 + movzx edx,dl + movzx r10d,r10b + movzx edx,BYTE PTR[rdx*1+rdi] + movzx eax,BYTE PTR[r10*1+rdi] + xor dl,BYTE PTR[r12] + lea r12,QWORD PTR[1+r12] + mov BYTE PTR[r13],dl + lea r13,QWORD PTR[1+r13] + sub r11,1 + jnz $L$cloop1 + jmp $L$exit + +ALIGN 16 +$L$exit:: + sub r10b,1 + mov DWORD PTR[((-8))+rdi],r10d + mov DWORD PTR[((-4))+rdi],ecx + + mov r13,QWORD PTR[rsp] + mov r12,QWORD PTR[8+rsp] + mov rbx,QWORD PTR[16+rsp] + add rsp,24 +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_RC4:: +RC4 ENDP +PUBLIC RC4_set_key + +ALIGN 16 +RC4_set_key PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_RC4_set_key:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + + lea rdi,QWORD PTR[8+rdi] + lea rdx,QWORD PTR[rsi*1+rdx] + neg rsi + mov rcx,rsi + xor eax,eax + xor r9,r9 + xor r10,r10 + xor r11,r11 + + mov r8d,DWORD PTR[OPENSSL_ia32cap_P] + bt r8d,20 + jc $L$c1stloop + jmp $L$w1stloop + +ALIGN 16 +$L$w1stloop:: + mov DWORD PTR[rax*4+rdi],eax + add al,1 + jnc $L$w1stloop + + xor r9,r9 + xor r8,r8 +ALIGN 16 +$L$w2ndloop:: + mov r10d,DWORD PTR[r9*4+rdi] + add r8b,BYTE PTR[rsi*1+rdx] + add r8b,r10b + add rsi,1 + mov r11d,DWORD PTR[r8*4+rdi] + cmovz rsi,rcx + mov DWORD PTR[r8*4+rdi],r10d + mov DWORD PTR[r9*4+rdi],r11d + add r9b,1 + jnc $L$w2ndloop + jmp $L$exit_key + +ALIGN 16 +$L$c1stloop:: + mov BYTE PTR[rax*1+rdi],al + add al,1 + jnc $L$c1stloop + + xor r9,r9 + xor r8,r8 +ALIGN 16 +$L$c2ndloop:: + mov r10b,BYTE PTR[r9*1+rdi] + add r8b,BYTE PTR[rsi*1+rdx] + add r8b,r10b + add rsi,1 + mov r11b,BYTE PTR[r8*1+rdi] + jnz $L$cnowrap + mov rsi,rcx +$L$cnowrap:: + mov BYTE PTR[r8*1+rdi],r10b + mov BYTE PTR[r9*1+rdi],r11b + add r9b,1 + jnc $L$c2ndloop + mov DWORD PTR[256+rdi],-1 + +ALIGN 16 +$L$exit_key:: + xor eax,eax + mov DWORD PTR[((-8))+rdi],eax + mov DWORD PTR[((-4))+rdi],eax + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_RC4_set_key:: +RC4_set_key ENDP + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/rc4/rc4-md5-elf-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-md5-elf-x86_64.S new file mode 100644 index 000000000..9381ff7bc --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-md5-elf-x86_64.S @@ -0,0 +1,1264 @@ +#include "x86_arch.h" +.text +.align 16 + +.globl rc4_md5_enc +.type rc4_md5_enc,@function +rc4_md5_enc: + endbr64 + cmpq $0,%r9 + je .Labort + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $40,%rsp +.Lbody: + movq %rcx,%r11 + movq %r9,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %r8,%r15 + xorq %rbp,%rbp + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%bpl + movb -4(%rdi),%cl + + incb %bpl + subq %r13,%r14 + movl (%rdi,%rbp,4),%eax + addb %al,%cl + leaq (%rdi,%rbp,4),%rsi + shlq $6,%r12 + addq %r15,%r12 + movq %r12,16(%rsp) + + movq %r11,24(%rsp) + movl 0(%r11),%r8d + movl 4(%r11),%r9d + movl 8(%r11),%r10d + movl 12(%r11),%r11d + jmp .Loop + +.align 16 +.Loop: + movl %r8d,0(%rsp) + movl %r9d,4(%rsp) + movl %r10d,8(%rsp) + movl %r11d,%r12d + movl %r11d,12(%rsp) + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $3614090360,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,0(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 4(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $3905402710,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,4(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $606105819,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,8(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 12(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $3250441966,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,12(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $4118548399,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,16(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 20(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1200080426,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,20(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $2821735955,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,24(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 28(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $4249261313,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,28(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $1770035416,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,32(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 36(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $2336552879,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,36(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $4294925233,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,40(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 44(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $2304563134,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,44(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $1804603682,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,48(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 52(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $4254626195,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,52(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $2792965006,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,56(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu (%r13),%xmm2 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 60(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $1236535329,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,60(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r10d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4129170786,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 24(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $3225465664,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $643717713,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 0(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $3921069994,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $3593408605,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 40(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $38016083,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $3634488961,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 16(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $3889429448,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $568446438,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 56(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $3275163606,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $4107603335,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 32(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1163531501,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $2850285829,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 8(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $4243563512,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $1735328473,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 16(%r13),%xmm3 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 48(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $2368359562,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $4294588738,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,0(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 32(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $2272392833,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,4(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $1839030562,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,8(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 56(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $4259657740,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,12(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $2763975236,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,16(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 16(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1272893353,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,20(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $4139469664,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,24(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 40(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $3200236656,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,28(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $681279174,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,32(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 0(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $3936430074,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,36(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $3572445317,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,40(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 24(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $76029189,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,44(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $3654602809,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,48(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 48(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $3873151461,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,52(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $530742520,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,56(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 32(%r13),%xmm4 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 8(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $3299628645,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,60(%rsi) + addb %al,%cl + roll $23,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm1,%xmm4 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4096336452,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 28(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $1126891415,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $2878612391,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 20(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $4237533241,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $1700485571,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 12(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $2399980690,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $4293915773,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 4(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $2240044497,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $1873313359,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 60(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $4264355552,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $2734768916,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 52(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1309151649,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $4149444226,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 44(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $3174756917,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $718787259,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 48(%r13),%xmm5 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 36(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $3951481745,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rbp,%rsi + xorq %rbp,%rbp + movb %sil,%bpl + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm1,%xmm5 + addl 0(%rsp),%r8d + addl 4(%rsp),%r9d + addl 8(%rsp),%r10d + addl 12(%rsp),%r11d + + movdqu %xmm2,(%r14,%r13,1) + movdqu %xmm3,16(%r14,%r13,1) + movdqu %xmm4,32(%r14,%r13,1) + movdqu %xmm5,48(%r14,%r13,1) + leaq 64(%r15),%r15 + leaq 64(%r13),%r13 + cmpq 16(%rsp),%r15 + jb .Loop + + movq 24(%rsp),%r12 + subb %al,%cl + movl %r8d,0(%r12) + movl %r9d,4(%r12) + movl %r10d,8(%r12) + movl %r11d,12(%r12) + subb $1,%bpl + movl %ebp,-8(%rdi) + movl %ecx,-4(%rdi) + + movq 40(%rsp),%r15 + movq 48(%rsp),%r14 + movq 56(%rsp),%r13 + movq 64(%rsp),%r12 + movq 72(%rsp),%rbp + movq 80(%rsp),%rbx + leaq 88(%rsp),%rsp +.Lepilogue: +.Labort: + retq +.size rc4_md5_enc,.-rc4_md5_enc +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/rc4/rc4-md5-macosx-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-md5-macosx-x86_64.S new file mode 100644 index 000000000..a8f6955fa --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-md5-macosx-x86_64.S @@ -0,0 +1,1260 @@ +#include "x86_arch.h" +.text +.p2align 4 + +.globl _rc4_md5_enc + +_rc4_md5_enc: + cmpq $0,%r9 + je L$abort + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $40,%rsp +L$body: + movq %rcx,%r11 + movq %r9,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %r8,%r15 + xorq %rbp,%rbp + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%bpl + movb -4(%rdi),%cl + + incb %bpl + subq %r13,%r14 + movl (%rdi,%rbp,4),%eax + addb %al,%cl + leaq (%rdi,%rbp,4),%rsi + shlq $6,%r12 + addq %r15,%r12 + movq %r12,16(%rsp) + + movq %r11,24(%rsp) + movl 0(%r11),%r8d + movl 4(%r11),%r9d + movl 8(%r11),%r10d + movl 12(%r11),%r11d + jmp L$oop + +.p2align 4 +L$oop: + movl %r8d,0(%rsp) + movl %r9d,4(%rsp) + movl %r10d,8(%rsp) + movl %r11d,%r12d + movl %r11d,12(%rsp) + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $3614090360,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,0(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 4(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $3905402710,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,4(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $606105819,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,8(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 12(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $3250441966,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,12(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $4118548399,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,16(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 20(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1200080426,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,20(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $2821735955,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,24(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 28(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $4249261313,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,28(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $1770035416,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,32(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 36(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $2336552879,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,36(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $4294925233,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,40(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 44(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $2304563134,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,44(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $1804603682,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,48(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 52(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $4254626195,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,52(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $2792965006,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,56(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu (%r13),%xmm2 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 60(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $1236535329,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,60(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r10d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4129170786,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 24(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $3225465664,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $643717713,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 0(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $3921069994,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $3593408605,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 40(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $38016083,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $3634488961,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 16(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $3889429448,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $568446438,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 56(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $3275163606,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $4107603335,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 32(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1163531501,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $2850285829,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 8(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $4243563512,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $1735328473,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 16(%r13),%xmm3 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 48(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $2368359562,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $4294588738,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,0(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 32(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $2272392833,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,4(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $1839030562,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,8(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 56(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $4259657740,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,12(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $2763975236,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,16(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 16(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1272893353,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,20(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $4139469664,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,24(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 40(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $3200236656,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,28(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $681279174,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,32(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 0(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $3936430074,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,36(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $3572445317,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,40(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 24(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $76029189,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,44(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $3654602809,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,48(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 48(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $3873151461,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,52(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $530742520,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,56(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 32(%r13),%xmm4 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 8(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $3299628645,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,60(%rsi) + addb %al,%cl + roll $23,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm1,%xmm4 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4096336452,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 28(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $1126891415,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $2878612391,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 20(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $4237533241,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $1700485571,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 12(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $2399980690,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $4293915773,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 4(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $2240044497,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $1873313359,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 60(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $4264355552,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $2734768916,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 52(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1309151649,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $4149444226,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 44(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $3174756917,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $718787259,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 48(%r13),%xmm5 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 36(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $3951481745,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rbp,%rsi + xorq %rbp,%rbp + movb %sil,%bpl + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm1,%xmm5 + addl 0(%rsp),%r8d + addl 4(%rsp),%r9d + addl 8(%rsp),%r10d + addl 12(%rsp),%r11d + + movdqu %xmm2,(%r14,%r13,1) + movdqu %xmm3,16(%r14,%r13,1) + movdqu %xmm4,32(%r14,%r13,1) + movdqu %xmm5,48(%r14,%r13,1) + leaq 64(%r15),%r15 + leaq 64(%r13),%r13 + cmpq 16(%rsp),%r15 + jb L$oop + + movq 24(%rsp),%r12 + subb %al,%cl + movl %r8d,0(%r12) + movl %r9d,4(%r12) + movl %r10d,8(%r12) + movl %r11d,12(%r12) + subb $1,%bpl + movl %ebp,-8(%rdi) + movl %ecx,-4(%rdi) + + movq 40(%rsp),%r15 + movq 48(%rsp),%r14 + movq 56(%rsp),%r13 + movq 64(%rsp),%r12 + movq 72(%rsp),%rbp + movq 80(%rsp),%rbx + leaq 88(%rsp),%rsp +L$epilogue: +L$abort: + retq + diff --git a/Libraries/libressl/crypto/rc4/rc4-md5-masm-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-md5-masm-x86_64.S new file mode 100644 index 000000000..0d2e8d55d --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-md5-masm-x86_64.S @@ -0,0 +1,1347 @@ +; 1 "crypto/rc4/rc4-md5-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/rc4/rc4-md5-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/rc4/rc4-md5-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' +ALIGN 16 + +PUBLIC rc4_md5_enc + +rc4_md5_enc PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_rc4_md5_enc:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + mov r8,QWORD PTR[40+rsp] + mov r9,QWORD PTR[48+rsp] + + + cmp r9,0 + je $L$abort + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + sub rsp,40 +$L$body:: + mov r11,rcx + mov r12,r9 + mov r13,rsi + mov r14,rdx + mov r15,r8 + xor rbp,rbp + xor rcx,rcx + + lea rdi,QWORD PTR[8+rdi] + mov bpl,BYTE PTR[((-8))+rdi] + mov cl,BYTE PTR[((-4))+rdi] + + inc bpl + sub r14,r13 + mov eax,DWORD PTR[rbp*4+rdi] + add cl,al + lea rsi,QWORD PTR[rbp*4+rdi] + shl r12,6 + add r12,r15 + mov QWORD PTR[16+rsp],r12 + + mov QWORD PTR[24+rsp],r11 + mov r8d,DWORD PTR[r11] + mov r9d,DWORD PTR[4+r11] + mov r10d,DWORD PTR[8+r11] + mov r11d,DWORD PTR[12+r11] + jmp $L$oop + +ALIGN 16 +$L$oop:: + mov DWORD PTR[rsp],r8d + mov DWORD PTR[4+rsp],r9d + mov DWORD PTR[8+rsp],r10d + mov r12d,r11d + mov DWORD PTR[12+rsp],r11d + pxor xmm0,xmm0 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r8d,DWORD PTR[r15] + add al,dl + mov ebx,DWORD PTR[4+rsi] + add r8d,3614090360 + xor r12d,r11d + movzx eax,al + mov DWORD PTR[rsi],edx + add r8d,r12d + add cl,bl + rol r8d,7 + mov r12d,r10d + movd xmm0,DWORD PTR[rax*4+rdi] + + add r8d,r9d + pxor xmm1,xmm1 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r11d,DWORD PTR[4+r15] + add bl,dl + mov eax,DWORD PTR[8+rsi] + add r11d,3905402710 + xor r12d,r10d + movzx ebx,bl + mov DWORD PTR[4+rsi],edx + add r11d,r12d + add cl,al + rol r11d,12 + mov r12d,r9d + movd xmm1,DWORD PTR[rbx*4+rdi] + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r10d,DWORD PTR[8+r15] + add al,dl + mov ebx,DWORD PTR[12+rsi] + add r10d,606105819 + xor r12d,r9d + movzx eax,al + mov DWORD PTR[8+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,17 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],1 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r9d,DWORD PTR[12+r15] + add bl,dl + mov eax,DWORD PTR[16+rsi] + add r9d,3250441966 + xor r12d,r8d + movzx ebx,bl + mov DWORD PTR[12+rsi],edx + add r9d,r12d + add cl,al + rol r9d,22 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],1 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r8d,DWORD PTR[16+r15] + add al,dl + mov ebx,DWORD PTR[20+rsi] + add r8d,4118548399 + xor r12d,r11d + movzx eax,al + mov DWORD PTR[16+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,7 + mov r12d,r10d + pinsrw xmm0,WORD PTR[rax*4+rdi],2 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r11d,DWORD PTR[20+r15] + add bl,dl + mov eax,DWORD PTR[24+rsi] + add r11d,1200080426 + xor r12d,r10d + movzx ebx,bl + mov DWORD PTR[20+rsi],edx + add r11d,r12d + add cl,al + rol r11d,12 + mov r12d,r9d + pinsrw xmm1,WORD PTR[rbx*4+rdi],2 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r10d,DWORD PTR[24+r15] + add al,dl + mov ebx,DWORD PTR[28+rsi] + add r10d,2821735955 + xor r12d,r9d + movzx eax,al + mov DWORD PTR[24+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,17 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],3 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r9d,DWORD PTR[28+r15] + add bl,dl + mov eax,DWORD PTR[32+rsi] + add r9d,4249261313 + xor r12d,r8d + movzx ebx,bl + mov DWORD PTR[28+rsi],edx + add r9d,r12d + add cl,al + rol r9d,22 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],3 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r8d,DWORD PTR[32+r15] + add al,dl + mov ebx,DWORD PTR[36+rsi] + add r8d,1770035416 + xor r12d,r11d + movzx eax,al + mov DWORD PTR[32+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,7 + mov r12d,r10d + pinsrw xmm0,WORD PTR[rax*4+rdi],4 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r11d,DWORD PTR[36+r15] + add bl,dl + mov eax,DWORD PTR[40+rsi] + add r11d,2336552879 + xor r12d,r10d + movzx ebx,bl + mov DWORD PTR[36+rsi],edx + add r11d,r12d + add cl,al + rol r11d,12 + mov r12d,r9d + pinsrw xmm1,WORD PTR[rbx*4+rdi],4 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r10d,DWORD PTR[40+r15] + add al,dl + mov ebx,DWORD PTR[44+rsi] + add r10d,4294925233 + xor r12d,r9d + movzx eax,al + mov DWORD PTR[40+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,17 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],5 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r9d,DWORD PTR[44+r15] + add bl,dl + mov eax,DWORD PTR[48+rsi] + add r9d,2304563134 + xor r12d,r8d + movzx ebx,bl + mov DWORD PTR[44+rsi],edx + add r9d,r12d + add cl,al + rol r9d,22 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],5 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r8d,DWORD PTR[48+r15] + add al,dl + mov ebx,DWORD PTR[52+rsi] + add r8d,1804603682 + xor r12d,r11d + movzx eax,al + mov DWORD PTR[48+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,7 + mov r12d,r10d + pinsrw xmm0,WORD PTR[rax*4+rdi],6 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r11d,DWORD PTR[52+r15] + add bl,dl + mov eax,DWORD PTR[56+rsi] + add r11d,4254626195 + xor r12d,r10d + movzx ebx,bl + mov DWORD PTR[52+rsi],edx + add r11d,r12d + add cl,al + rol r11d,12 + mov r12d,r9d + pinsrw xmm1,WORD PTR[rbx*4+rdi],6 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r10d,DWORD PTR[56+r15] + add al,dl + mov ebx,DWORD PTR[60+rsi] + add r10d,2792965006 + xor r12d,r9d + movzx eax,al + mov DWORD PTR[56+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,17 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],7 + + add r10d,r11d + movdqu xmm2,XMMWORD PTR[r13] + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r9d,DWORD PTR[60+r15] + add bl,dl + mov eax,DWORD PTR[64+rsi] + add r9d,1236535329 + xor r12d,r8d + movzx ebx,bl + mov DWORD PTR[60+rsi],edx + add r9d,r12d + add cl,al + rol r9d,22 + mov r12d,r10d + pinsrw xmm1,WORD PTR[rbx*4+rdi],7 + + add r9d,r10d + psllq xmm1,8 + pxor xmm2,xmm0 + pxor xmm2,xmm1 + pxor xmm0,xmm0 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r8d,DWORD PTR[4+r15] + add al,dl + mov ebx,DWORD PTR[68+rsi] + add r8d,4129170786 + xor r12d,r10d + movzx eax,al + mov DWORD PTR[64+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,5 + mov r12d,r9d + movd xmm0,DWORD PTR[rax*4+rdi] + + add r8d,r9d + pxor xmm1,xmm1 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r11d,DWORD PTR[24+r15] + add bl,dl + mov eax,DWORD PTR[72+rsi] + add r11d,3225465664 + xor r12d,r9d + movzx ebx,bl + mov DWORD PTR[68+rsi],edx + add r11d,r12d + add cl,al + rol r11d,9 + mov r12d,r8d + movd xmm1,DWORD PTR[rbx*4+rdi] + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r10d,DWORD PTR[44+r15] + add al,dl + mov ebx,DWORD PTR[76+rsi] + add r10d,643717713 + xor r12d,r8d + movzx eax,al + mov DWORD PTR[72+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,14 + mov r12d,r11d + pinsrw xmm0,WORD PTR[rax*4+rdi],1 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r9d,DWORD PTR[r15] + add bl,dl + mov eax,DWORD PTR[80+rsi] + add r9d,3921069994 + xor r12d,r11d + movzx ebx,bl + mov DWORD PTR[76+rsi],edx + add r9d,r12d + add cl,al + rol r9d,20 + mov r12d,r10d + pinsrw xmm1,WORD PTR[rbx*4+rdi],1 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r8d,DWORD PTR[20+r15] + add al,dl + mov ebx,DWORD PTR[84+rsi] + add r8d,3593408605 + xor r12d,r10d + movzx eax,al + mov DWORD PTR[80+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,5 + mov r12d,r9d + pinsrw xmm0,WORD PTR[rax*4+rdi],2 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r11d,DWORD PTR[40+r15] + add bl,dl + mov eax,DWORD PTR[88+rsi] + add r11d,38016083 + xor r12d,r9d + movzx ebx,bl + mov DWORD PTR[84+rsi],edx + add r11d,r12d + add cl,al + rol r11d,9 + mov r12d,r8d + pinsrw xmm1,WORD PTR[rbx*4+rdi],2 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r10d,DWORD PTR[60+r15] + add al,dl + mov ebx,DWORD PTR[92+rsi] + add r10d,3634488961 + xor r12d,r8d + movzx eax,al + mov DWORD PTR[88+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,14 + mov r12d,r11d + pinsrw xmm0,WORD PTR[rax*4+rdi],3 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r9d,DWORD PTR[16+r15] + add bl,dl + mov eax,DWORD PTR[96+rsi] + add r9d,3889429448 + xor r12d,r11d + movzx ebx,bl + mov DWORD PTR[92+rsi],edx + add r9d,r12d + add cl,al + rol r9d,20 + mov r12d,r10d + pinsrw xmm1,WORD PTR[rbx*4+rdi],3 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r8d,DWORD PTR[36+r15] + add al,dl + mov ebx,DWORD PTR[100+rsi] + add r8d,568446438 + xor r12d,r10d + movzx eax,al + mov DWORD PTR[96+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,5 + mov r12d,r9d + pinsrw xmm0,WORD PTR[rax*4+rdi],4 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r11d,DWORD PTR[56+r15] + add bl,dl + mov eax,DWORD PTR[104+rsi] + add r11d,3275163606 + xor r12d,r9d + movzx ebx,bl + mov DWORD PTR[100+rsi],edx + add r11d,r12d + add cl,al + rol r11d,9 + mov r12d,r8d + pinsrw xmm1,WORD PTR[rbx*4+rdi],4 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r10d,DWORD PTR[12+r15] + add al,dl + mov ebx,DWORD PTR[108+rsi] + add r10d,4107603335 + xor r12d,r8d + movzx eax,al + mov DWORD PTR[104+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,14 + mov r12d,r11d + pinsrw xmm0,WORD PTR[rax*4+rdi],5 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r9d,DWORD PTR[32+r15] + add bl,dl + mov eax,DWORD PTR[112+rsi] + add r9d,1163531501 + xor r12d,r11d + movzx ebx,bl + mov DWORD PTR[108+rsi],edx + add r9d,r12d + add cl,al + rol r9d,20 + mov r12d,r10d + pinsrw xmm1,WORD PTR[rbx*4+rdi],5 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r11d + add r8d,DWORD PTR[52+r15] + add al,dl + mov ebx,DWORD PTR[116+rsi] + add r8d,2850285829 + xor r12d,r10d + movzx eax,al + mov DWORD PTR[112+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,5 + mov r12d,r9d + pinsrw xmm0,WORD PTR[rax*4+rdi],6 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r10d + add r11d,DWORD PTR[8+r15] + add bl,dl + mov eax,DWORD PTR[120+rsi] + add r11d,4243563512 + xor r12d,r9d + movzx ebx,bl + mov DWORD PTR[116+rsi],edx + add r11d,r12d + add cl,al + rol r11d,9 + mov r12d,r8d + pinsrw xmm1,WORD PTR[rbx*4+rdi],6 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + and r12d,r9d + add r10d,DWORD PTR[28+r15] + add al,dl + mov ebx,DWORD PTR[124+rsi] + add r10d,1735328473 + xor r12d,r8d + movzx eax,al + mov DWORD PTR[120+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,14 + mov r12d,r11d + pinsrw xmm0,WORD PTR[rax*4+rdi],7 + + add r10d,r11d + movdqu xmm3,XMMWORD PTR[16+r13] + add bpl,32 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + and r12d,r8d + add r9d,DWORD PTR[48+r15] + add bl,dl + mov eax,DWORD PTR[rbp*4+rdi] + add r9d,2368359562 + xor r12d,r11d + movzx ebx,bl + mov DWORD PTR[124+rsi],edx + add r9d,r12d + add cl,al + rol r9d,20 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],7 + + add r9d,r10d + mov rsi,rcx + xor rcx,rcx + mov cl,sil + lea rsi,QWORD PTR[rbp*4+rdi] + psllq xmm1,8 + pxor xmm3,xmm0 + pxor xmm3,xmm1 + pxor xmm0,xmm0 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r9d + add r8d,DWORD PTR[20+r15] + add al,dl + mov ebx,DWORD PTR[4+rsi] + add r8d,4294588738 + movzx eax,al + add r8d,r12d + mov DWORD PTR[rsi],edx + add cl,bl + rol r8d,4 + mov r12d,r10d + movd xmm0,DWORD PTR[rax*4+rdi] + + add r8d,r9d + pxor xmm1,xmm1 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r8d + add r11d,DWORD PTR[32+r15] + add bl,dl + mov eax,DWORD PTR[8+rsi] + add r11d,2272392833 + movzx ebx,bl + add r11d,r12d + mov DWORD PTR[4+rsi],edx + add cl,al + rol r11d,11 + mov r12d,r9d + movd xmm1,DWORD PTR[rbx*4+rdi] + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r11d + add r10d,DWORD PTR[44+r15] + add al,dl + mov ebx,DWORD PTR[12+rsi] + add r10d,1839030562 + movzx eax,al + add r10d,r12d + mov DWORD PTR[8+rsi],edx + add cl,bl + rol r10d,16 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],1 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r10d + add r9d,DWORD PTR[56+r15] + add bl,dl + mov eax,DWORD PTR[16+rsi] + add r9d,4259657740 + movzx ebx,bl + add r9d,r12d + mov DWORD PTR[12+rsi],edx + add cl,al + rol r9d,23 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],1 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r9d + add r8d,DWORD PTR[4+r15] + add al,dl + mov ebx,DWORD PTR[20+rsi] + add r8d,2763975236 + movzx eax,al + add r8d,r12d + mov DWORD PTR[16+rsi],edx + add cl,bl + rol r8d,4 + mov r12d,r10d + pinsrw xmm0,WORD PTR[rax*4+rdi],2 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r8d + add r11d,DWORD PTR[16+r15] + add bl,dl + mov eax,DWORD PTR[24+rsi] + add r11d,1272893353 + movzx ebx,bl + add r11d,r12d + mov DWORD PTR[20+rsi],edx + add cl,al + rol r11d,11 + mov r12d,r9d + pinsrw xmm1,WORD PTR[rbx*4+rdi],2 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r11d + add r10d,DWORD PTR[28+r15] + add al,dl + mov ebx,DWORD PTR[28+rsi] + add r10d,4139469664 + movzx eax,al + add r10d,r12d + mov DWORD PTR[24+rsi],edx + add cl,bl + rol r10d,16 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],3 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r10d + add r9d,DWORD PTR[40+r15] + add bl,dl + mov eax,DWORD PTR[32+rsi] + add r9d,3200236656 + movzx ebx,bl + add r9d,r12d + mov DWORD PTR[28+rsi],edx + add cl,al + rol r9d,23 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],3 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r9d + add r8d,DWORD PTR[52+r15] + add al,dl + mov ebx,DWORD PTR[36+rsi] + add r8d,681279174 + movzx eax,al + add r8d,r12d + mov DWORD PTR[32+rsi],edx + add cl,bl + rol r8d,4 + mov r12d,r10d + pinsrw xmm0,WORD PTR[rax*4+rdi],4 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r8d + add r11d,DWORD PTR[r15] + add bl,dl + mov eax,DWORD PTR[40+rsi] + add r11d,3936430074 + movzx ebx,bl + add r11d,r12d + mov DWORD PTR[36+rsi],edx + add cl,al + rol r11d,11 + mov r12d,r9d + pinsrw xmm1,WORD PTR[rbx*4+rdi],4 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r11d + add r10d,DWORD PTR[12+r15] + add al,dl + mov ebx,DWORD PTR[44+rsi] + add r10d,3572445317 + movzx eax,al + add r10d,r12d + mov DWORD PTR[40+rsi],edx + add cl,bl + rol r10d,16 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],5 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r10d + add r9d,DWORD PTR[24+r15] + add bl,dl + mov eax,DWORD PTR[48+rsi] + add r9d,76029189 + movzx ebx,bl + add r9d,r12d + mov DWORD PTR[44+rsi],edx + add cl,al + rol r9d,23 + mov r12d,r11d + pinsrw xmm1,WORD PTR[rbx*4+rdi],5 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r9d + add r8d,DWORD PTR[36+r15] + add al,dl + mov ebx,DWORD PTR[52+rsi] + add r8d,3654602809 + movzx eax,al + add r8d,r12d + mov DWORD PTR[48+rsi],edx + add cl,bl + rol r8d,4 + mov r12d,r10d + pinsrw xmm0,WORD PTR[rax*4+rdi],6 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r8d + add r11d,DWORD PTR[48+r15] + add bl,dl + mov eax,DWORD PTR[56+rsi] + add r11d,3873151461 + movzx ebx,bl + add r11d,r12d + mov DWORD PTR[52+rsi],edx + add cl,al + rol r11d,11 + mov r12d,r9d + pinsrw xmm1,WORD PTR[rbx*4+rdi],6 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],eax + xor r12d,r11d + add r10d,DWORD PTR[60+r15] + add al,dl + mov ebx,DWORD PTR[60+rsi] + add r10d,530742520 + movzx eax,al + add r10d,r12d + mov DWORD PTR[56+rsi],edx + add cl,bl + rol r10d,16 + mov r12d,r8d + pinsrw xmm0,WORD PTR[rax*4+rdi],7 + + add r10d,r11d + movdqu xmm4,XMMWORD PTR[32+r13] + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],ebx + xor r12d,r10d + add r9d,DWORD PTR[8+r15] + add bl,dl + mov eax,DWORD PTR[64+rsi] + add r9d,3299628645 + movzx ebx,bl + add r9d,r12d + mov DWORD PTR[60+rsi],edx + add cl,al + rol r9d,23 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],7 + + add r9d,r10d + psllq xmm1,8 + pxor xmm4,xmm0 + pxor xmm4,xmm1 + pxor xmm0,xmm0 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r9d + add r8d,DWORD PTR[r15] + add al,dl + mov ebx,DWORD PTR[68+rsi] + add r8d,4096336452 + movzx eax,al + xor r12d,r10d + mov DWORD PTR[64+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,6 + mov r12d,-1 + movd xmm0,DWORD PTR[rax*4+rdi] + + add r8d,r9d + pxor xmm1,xmm1 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r8d + add r11d,DWORD PTR[28+r15] + add bl,dl + mov eax,DWORD PTR[72+rsi] + add r11d,1126891415 + movzx ebx,bl + xor r12d,r9d + mov DWORD PTR[68+rsi],edx + add r11d,r12d + add cl,al + rol r11d,10 + mov r12d,-1 + movd xmm1,DWORD PTR[rbx*4+rdi] + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r11d + add r10d,DWORD PTR[56+r15] + add al,dl + mov ebx,DWORD PTR[76+rsi] + add r10d,2878612391 + movzx eax,al + xor r12d,r8d + mov DWORD PTR[72+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,15 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],1 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r10d + add r9d,DWORD PTR[20+r15] + add bl,dl + mov eax,DWORD PTR[80+rsi] + add r9d,4237533241 + movzx ebx,bl + xor r12d,r11d + mov DWORD PTR[76+rsi],edx + add r9d,r12d + add cl,al + rol r9d,21 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],1 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r9d + add r8d,DWORD PTR[48+r15] + add al,dl + mov ebx,DWORD PTR[84+rsi] + add r8d,1700485571 + movzx eax,al + xor r12d,r10d + mov DWORD PTR[80+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,6 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],2 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r8d + add r11d,DWORD PTR[12+r15] + add bl,dl + mov eax,DWORD PTR[88+rsi] + add r11d,2399980690 + movzx ebx,bl + xor r12d,r9d + mov DWORD PTR[84+rsi],edx + add r11d,r12d + add cl,al + rol r11d,10 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],2 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r11d + add r10d,DWORD PTR[40+r15] + add al,dl + mov ebx,DWORD PTR[92+rsi] + add r10d,4293915773 + movzx eax,al + xor r12d,r8d + mov DWORD PTR[88+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,15 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],3 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r10d + add r9d,DWORD PTR[4+r15] + add bl,dl + mov eax,DWORD PTR[96+rsi] + add r9d,2240044497 + movzx ebx,bl + xor r12d,r11d + mov DWORD PTR[92+rsi],edx + add r9d,r12d + add cl,al + rol r9d,21 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],3 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r9d + add r8d,DWORD PTR[32+r15] + add al,dl + mov ebx,DWORD PTR[100+rsi] + add r8d,1873313359 + movzx eax,al + xor r12d,r10d + mov DWORD PTR[96+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,6 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],4 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r8d + add r11d,DWORD PTR[60+r15] + add bl,dl + mov eax,DWORD PTR[104+rsi] + add r11d,4264355552 + movzx ebx,bl + xor r12d,r9d + mov DWORD PTR[100+rsi],edx + add r11d,r12d + add cl,al + rol r11d,10 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],4 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r11d + add r10d,DWORD PTR[24+r15] + add al,dl + mov ebx,DWORD PTR[108+rsi] + add r10d,2734768916 + movzx eax,al + xor r12d,r8d + mov DWORD PTR[104+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,15 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],5 + + add r10d,r11d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r10d + add r9d,DWORD PTR[52+r15] + add bl,dl + mov eax,DWORD PTR[112+rsi] + add r9d,1309151649 + movzx ebx,bl + xor r12d,r11d + mov DWORD PTR[108+rsi],edx + add r9d,r12d + add cl,al + rol r9d,21 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],5 + + add r9d,r10d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r11d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r9d + add r8d,DWORD PTR[16+r15] + add al,dl + mov ebx,DWORD PTR[116+rsi] + add r8d,4149444226 + movzx eax,al + xor r12d,r10d + mov DWORD PTR[112+rsi],edx + add r8d,r12d + add cl,bl + rol r8d,6 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],6 + + add r8d,r9d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r10d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r8d + add r11d,DWORD PTR[44+r15] + add bl,dl + mov eax,DWORD PTR[120+rsi] + add r11d,3174756917 + movzx ebx,bl + xor r12d,r9d + mov DWORD PTR[116+rsi],edx + add r11d,r12d + add cl,al + rol r11d,10 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],6 + + add r11d,r8d + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r9d + mov DWORD PTR[rcx*4+rdi],eax + or r12d,r11d + add r10d,DWORD PTR[8+r15] + add al,dl + mov ebx,DWORD PTR[124+rsi] + add r10d,718787259 + movzx eax,al + xor r12d,r8d + mov DWORD PTR[120+rsi],edx + add r10d,r12d + add cl,bl + rol r10d,15 + mov r12d,-1 + pinsrw xmm0,WORD PTR[rax*4+rdi],7 + + add r10d,r11d + movdqu xmm5,XMMWORD PTR[48+r13] + add bpl,32 + mov edx,DWORD PTR[rcx*4+rdi] + xor r12d,r8d + mov DWORD PTR[rcx*4+rdi],ebx + or r12d,r10d + add r9d,DWORD PTR[36+r15] + add bl,dl + mov eax,DWORD PTR[rbp*4+rdi] + add r9d,3951481745 + movzx ebx,bl + xor r12d,r11d + mov DWORD PTR[124+rsi],edx + add r9d,r12d + add cl,al + rol r9d,21 + mov r12d,-1 + pinsrw xmm1,WORD PTR[rbx*4+rdi],7 + + add r9d,r10d + mov rsi,rbp + xor rbp,rbp + mov bpl,sil + mov rsi,rcx + xor rcx,rcx + mov cl,sil + lea rsi,QWORD PTR[rbp*4+rdi] + psllq xmm1,8 + pxor xmm5,xmm0 + pxor xmm5,xmm1 + add r8d,DWORD PTR[rsp] + add r9d,DWORD PTR[4+rsp] + add r10d,DWORD PTR[8+rsp] + add r11d,DWORD PTR[12+rsp] + + movdqu XMMWORD PTR[r13*1+r14],xmm2 + movdqu XMMWORD PTR[16+r13*1+r14],xmm3 + movdqu XMMWORD PTR[32+r13*1+r14],xmm4 + movdqu XMMWORD PTR[48+r13*1+r14],xmm5 + lea r15,QWORD PTR[64+r15] + lea r13,QWORD PTR[64+r13] + cmp r15,QWORD PTR[16+rsp] + jb $L$oop + + mov r12,QWORD PTR[24+rsp] + sub cl,al + mov DWORD PTR[r12],r8d + mov DWORD PTR[4+r12],r9d + mov DWORD PTR[8+r12],r10d + mov DWORD PTR[12+r12],r11d + sub bpl,1 + mov DWORD PTR[((-8))+rdi],ebp + mov DWORD PTR[((-4))+rdi],ecx + + mov r15,QWORD PTR[40+rsp] + mov r14,QWORD PTR[48+rsp] + mov r13,QWORD PTR[56+rsp] + mov r12,QWORD PTR[64+rsp] + mov rbp,QWORD PTR[72+rsp] + mov rbx,QWORD PTR[80+rsp] + lea rsp,QWORD PTR[88+rsp] +$L$epilogue:: +$L$abort:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_rc4_md5_enc:: +rc4_md5_enc ENDP + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/rc4/rc4-md5-mingw64-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-md5-mingw64-x86_64.S new file mode 100644 index 000000000..e11d3148d --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-md5-mingw64-x86_64.S @@ -0,0 +1,1273 @@ +#include "x86_arch.h" +.text +.p2align 4 + +.globl rc4_md5_enc +.def rc4_md5_enc; .scl 2; .type 32; .endef +rc4_md5_enc: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_rc4_md5_enc: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + movq 40(%rsp),%r8 + movq 48(%rsp),%r9 + + cmpq $0,%r9 + je .Labort + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $40,%rsp +.Lbody: + movq %rcx,%r11 + movq %r9,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %r8,%r15 + xorq %rbp,%rbp + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%bpl + movb -4(%rdi),%cl + + incb %bpl + subq %r13,%r14 + movl (%rdi,%rbp,4),%eax + addb %al,%cl + leaq (%rdi,%rbp,4),%rsi + shlq $6,%r12 + addq %r15,%r12 + movq %r12,16(%rsp) + + movq %r11,24(%rsp) + movl 0(%r11),%r8d + movl 4(%r11),%r9d + movl 8(%r11),%r10d + movl 12(%r11),%r11d + jmp .Loop + +.p2align 4 +.Loop: + movl %r8d,0(%rsp) + movl %r9d,4(%rsp) + movl %r10d,8(%rsp) + movl %r11d,%r12d + movl %r11d,12(%rsp) + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $3614090360,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,0(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 4(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $3905402710,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,4(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $606105819,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,8(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 12(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $3250441966,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,12(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $4118548399,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,16(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 20(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1200080426,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,20(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $2821735955,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,24(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 28(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $4249261313,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,28(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $1770035416,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,32(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 36(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $2336552879,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,36(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $4294925233,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,40(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 44(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $2304563134,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,44(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $1804603682,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,48(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 52(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $4254626195,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,52(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $2792965006,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,56(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu (%r13),%xmm2 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 60(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $1236535329,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,60(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r10d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4129170786,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 24(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $3225465664,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $643717713,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 0(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $3921069994,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $3593408605,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 40(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $38016083,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $3634488961,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 16(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $3889429448,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $568446438,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 56(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $3275163606,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $4107603335,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 32(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1163531501,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $2850285829,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 8(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $4243563512,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $1735328473,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 16(%r13),%xmm3 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 48(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $2368359562,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $4294588738,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,0(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 32(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $2272392833,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,4(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $1839030562,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,8(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 56(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $4259657740,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,12(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $2763975236,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,16(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 16(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1272893353,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,20(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $4139469664,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,24(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 40(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $3200236656,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,28(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $681279174,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,32(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 0(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $3936430074,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,36(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $3572445317,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,40(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 24(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $76029189,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,44(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $3654602809,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,48(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 48(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $3873151461,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,52(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $530742520,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,56(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 32(%r13),%xmm4 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 8(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $3299628645,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,60(%rsi) + addb %al,%cl + roll $23,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm1,%xmm4 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4096336452,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 28(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $1126891415,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $2878612391,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 20(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $4237533241,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $1700485571,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 12(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $2399980690,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $4293915773,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 4(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $2240044497,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $1873313359,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 60(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $4264355552,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $2734768916,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 52(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1309151649,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $4149444226,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 44(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $3174756917,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $718787259,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 48(%r13),%xmm5 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 36(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $3951481745,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rbp,%rsi + xorq %rbp,%rbp + movb %sil,%bpl + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm1,%xmm5 + addl 0(%rsp),%r8d + addl 4(%rsp),%r9d + addl 8(%rsp),%r10d + addl 12(%rsp),%r11d + + movdqu %xmm2,(%r14,%r13,1) + movdqu %xmm3,16(%r14,%r13,1) + movdqu %xmm4,32(%r14,%r13,1) + movdqu %xmm5,48(%r14,%r13,1) + leaq 64(%r15),%r15 + leaq 64(%r13),%r13 + cmpq 16(%rsp),%r15 + jb .Loop + + movq 24(%rsp),%r12 + subb %al,%cl + movl %r8d,0(%r12) + movl %r9d,4(%r12) + movl %r10d,8(%r12) + movl %r11d,12(%r12) + subb $1,%bpl + movl %ebp,-8(%rdi) + movl %ecx,-4(%rdi) + + movq 40(%rsp),%r15 + movq 48(%rsp),%r14 + movq 56(%rsp),%r13 + movq 64(%rsp),%r12 + movq 72(%rsp),%rbp + movq 80(%rsp),%rbx + leaq 88(%rsp),%rsp +.Lepilogue: +.Labort: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_rc4_md5_enc: diff --git a/Libraries/libressl/crypto/rc4/rc4-mingw64-x86_64.S b/Libraries/libressl/crypto/rc4/rc4-mingw64-x86_64.S new file mode 100644 index 000000000..4750a7789 --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4-mingw64-x86_64.S @@ -0,0 +1,615 @@ +#include "x86_arch.h" +.text + + + +.globl RC4 +.def RC4; .scl 2; .type 32; .endef +.p2align 4 +RC4: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_RC4: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + orq %rsi,%rsi + jne .Lentry + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.Lentry: + pushq %rbx + pushq %r12 + pushq %r13 +.Lprologue: + movq %rsi,%r11 + movq %rdx,%r12 + movq %rcx,%r13 + xorq %r10,%r10 + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%r10b + movb -4(%rdi),%cl + cmpl $-1,256(%rdi) + je .LRC4_CHAR + movl OPENSSL_ia32cap_P(%rip),%r8d + xorq %rbx,%rbx + incb %r10b + subq %r10,%rbx + subq %r12,%r13 + movl (%rdi,%r10,4),%eax + testq $-16,%r11 + jz .Lloop1 + btl $IA32CAP_BIT0_INTEL,%r8d + jc .Lintel + andq $7,%rbx + leaq 1(%r10),%rsi + jz .Loop8 + subq %rbx,%r11 +.Loop8_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %rbx + jnz .Loop8_warmup + + leaq 1(%r10),%rsi + jmp .Loop8 +.p2align 4 +.Loop8: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 0(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,0(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,4(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 8(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,8(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 12(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,12(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 16(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,16(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 20(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,20(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 24(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,24(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%sil + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl -4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,28(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%r10b + rorq $8,%r8 + subq $8,%r11 + + xorq (%r12),%r8 + movq %r8,(%r13,%r12,1) + leaq 8(%r12),%r12 + + testq $-8,%r11 + jnz .Loop8 + cmpq $0,%r11 + jne .Lloop1 + jmp .Lexit + +.p2align 4 +.Lintel: + testq $-32,%r11 + jz .Lloop1 + andq $15,%rbx + jz .Loop16_is_hot + subq %rbx,%r11 +.Loop16_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %rbx + jnz .Loop16_warmup + + movq %rcx,%rbx + xorq %rcx,%rcx + movb %bl,%cl + +.Loop16_is_hot: + leaq (%rdi,%r10,4),%rsi + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + jmp .Loop16_enter +.p2align 4 +.Loop16: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm2 + psllq $8,%xmm1 + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + pxor %xmm1,%xmm2 + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + movdqu %xmm2,(%r13,%r12,1) + leaq 16(%r12),%r12 +.Loop16_enter: + movl (%rdi,%rcx,4),%edx + pxor %xmm1,%xmm1 + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 8(%rsi),%eax + movzbl %bl,%ebx + movl %edx,4(%rsi) + addb %al,%cl + pinsrw $0,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 12(%rsi),%ebx + movzbl %al,%eax + movl %edx,8(%rsi) + addb %bl,%cl + pinsrw $1,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 16(%rsi),%eax + movzbl %bl,%ebx + movl %edx,12(%rsi) + addb %al,%cl + pinsrw $1,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 20(%rsi),%ebx + movzbl %al,%eax + movl %edx,16(%rsi) + addb %bl,%cl + pinsrw $2,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 24(%rsi),%eax + movzbl %bl,%ebx + movl %edx,20(%rsi) + addb %al,%cl + pinsrw $2,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 28(%rsi),%ebx + movzbl %al,%eax + movl %edx,24(%rsi) + addb %bl,%cl + pinsrw $3,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 32(%rsi),%eax + movzbl %bl,%ebx + movl %edx,28(%rsi) + addb %al,%cl + pinsrw $3,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 36(%rsi),%ebx + movzbl %al,%eax + movl %edx,32(%rsi) + addb %bl,%cl + pinsrw $4,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 40(%rsi),%eax + movzbl %bl,%ebx + movl %edx,36(%rsi) + addb %al,%cl + pinsrw $4,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 44(%rsi),%ebx + movzbl %al,%eax + movl %edx,40(%rsi) + addb %bl,%cl + pinsrw $5,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 48(%rsi),%eax + movzbl %bl,%ebx + movl %edx,44(%rsi) + addb %al,%cl + pinsrw $5,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 52(%rsi),%ebx + movzbl %al,%eax + movl %edx,48(%rsi) + addb %bl,%cl + pinsrw $6,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 56(%rsi),%eax + movzbl %bl,%ebx + movl %edx,52(%rsi) + addb %al,%cl + pinsrw $6,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 60(%rsi),%ebx + movzbl %al,%eax + movl %edx,56(%rsi) + addb %bl,%cl + pinsrw $7,(%rdi,%rax,4),%xmm0 + addb $16,%r10b + movdqu (%r12),%xmm2 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movzbl %bl,%ebx + movl %edx,60(%rsi) + leaq (%rdi,%r10,4),%rsi + pinsrw $7,(%rdi,%rbx,4),%xmm1 + movl (%rsi),%eax + movq %rcx,%rbx + xorq %rcx,%rcx + subq $16,%r11 + movb %bl,%cl + testq $-16,%r11 + jnz .Loop16 + + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + movdqu %xmm2,(%r13,%r12,1) + leaq 16(%r12),%r12 + + cmpq $0,%r11 + jne .Lloop1 + jmp .Lexit + +.p2align 4 +.Lloop1: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r13,%r12,1) + leaq 1(%r12),%r12 + decq %r11 + jnz .Lloop1 + jmp .Lexit + +.p2align 4 +.LRC4_CHAR: + addb $1,%r10b + movzbl (%rdi,%r10,1),%eax + testq $-8,%r11 + jz .Lcloop1 + jmp .Lcloop8 +.p2align 4 +.Lcloop8: + movl (%r12),%r8d + movl 4(%r12),%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov0 + movq %rax,%rbx +.Lcmov0: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov1 + movq %rbx,%rax +.Lcmov1: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov2 + movq %rax,%rbx +.Lcmov2: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov3 + movq %rbx,%rax +.Lcmov3: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov4 + movq %rax,%rbx +.Lcmov4: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov5 + movq %rbx,%rax +.Lcmov5: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov6 + movq %rax,%rbx +.Lcmov6: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov7 + movq %rbx,%rax +.Lcmov7: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + leaq -8(%r11),%r11 + movl %r8d,(%r13) + leaq 8(%r12),%r12 + movl %r9d,4(%r13) + leaq 8(%r13),%r13 + + testq $-8,%r11 + jnz .Lcloop8 + cmpq $0,%r11 + jne .Lcloop1 + jmp .Lexit +.p2align 4 +.Lcloop1: + addb %al,%cl + movzbl %cl,%ecx + movzbl (%rdi,%rcx,1),%edx + movb %al,(%rdi,%rcx,1) + movb %dl,(%rdi,%r10,1) + addb %al,%dl + addb $1,%r10b + movzbl %dl,%edx + movzbl %r10b,%r10d + movzbl (%rdi,%rdx,1),%edx + movzbl (%rdi,%r10,1),%eax + xorb (%r12),%dl + leaq 1(%r12),%r12 + movb %dl,(%r13) + leaq 1(%r13),%r13 + subq $1,%r11 + jnz .Lcloop1 + jmp .Lexit + +.p2align 4 +.Lexit: + subb $1,%r10b + movl %r10d,-8(%rdi) + movl %ecx,-4(%rdi) + + movq (%rsp),%r13 + movq 8(%rsp),%r12 + movq 16(%rsp),%rbx + addq $24,%rsp +.Lepilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_RC4: +.globl RC4_set_key +.def RC4_set_key; .scl 2; .type 32; .endef +.p2align 4 +RC4_set_key: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_RC4_set_key: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + + leaq 8(%rdi),%rdi + leaq (%rdx,%rsi,1),%rdx + negq %rsi + movq %rsi,%rcx + xorl %eax,%eax + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + + movl OPENSSL_ia32cap_P(%rip),%r8d + btl $IA32CAP_BIT0_INTELP4,%r8d + jc .Lc1stloop + jmp .Lw1stloop + +.p2align 4 +.Lw1stloop: + movl %eax,(%rdi,%rax,4) + addb $1,%al + jnc .Lw1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.p2align 4 +.Lw2ndloop: + movl (%rdi,%r9,4),%r10d + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movl (%rdi,%r8,4),%r11d + cmovzq %rcx,%rsi + movl %r10d,(%rdi,%r8,4) + movl %r11d,(%rdi,%r9,4) + addb $1,%r9b + jnc .Lw2ndloop + jmp .Lexit_key + +.p2align 4 +.Lc1stloop: + movb %al,(%rdi,%rax,1) + addb $1,%al + jnc .Lc1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.p2align 4 +.Lc2ndloop: + movb (%rdi,%r9,1),%r10b + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movb (%rdi,%r8,1),%r11b + jnz .Lcnowrap + movq %rcx,%rsi +.Lcnowrap: + movb %r10b,(%rdi,%r8,1) + movb %r11b,(%rdi,%r9,1) + addb $1,%r9b + jnc .Lc2ndloop + movl $-1,256(%rdi) + +.p2align 4 +.Lexit_key: + xorl %eax,%eax + movl %eax,-8(%rdi) + movl %eax,-4(%rdi) + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_RC4_set_key: diff --git a/Libraries/libressl/crypto/rc4/rc4_enc.c b/Libraries/libressl/crypto/rc4/rc4_enc.c new file mode 100644 index 000000000..3763bfa3c --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4_enc.c @@ -0,0 +1,254 @@ +/* $OpenBSD: rc4_enc.c,v 1.18 2022/11/26 16:08:54 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include "rc4_local.h" + +/* RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void +RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata) +{ + RC4_INT *d; + RC4_INT x, y,tx, ty; + size_t i; + + x = key->x; + y = key->y; + d = key->data; + +#if defined(RC4_CHUNK) + /* + * The original reason for implementing this(*) was the fact that + * pre-21164a Alpha CPUs don't have byte load/store instructions + * and e.g. a byte store has to be done with 64-bit load, shift, + * and, or and finally 64-bit store. Peaking data and operating + * at natural word size made it possible to reduce amount of + * instructions as well as to perform early read-ahead without + * suffering from RAW (read-after-write) hazard. This resulted + * in ~40%(**) performance improvement on 21064 box with gcc. + * But it's not only Alpha users who win here:-) Thanks to the + * early-n-wide read-ahead this implementation also exhibits + * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending + * on sizeof(RC4_INT)). + * + * (*) "this" means code which recognizes the case when input + * and output pointers appear to be aligned at natural CPU + * word boundary + * (**) i.e. according to 'apps/openssl speed rc4' benchmark, + * crypto/rc4/rc4speed.c exhibits almost 70% speed-up... + * + * Caveats. + * + * - RC4_CHUNK="unsigned long long" should be a #1 choice for + * UltraSPARC. Unfortunately gcc generates very slow code + * (2.5-3 times slower than one generated by Sun's WorkShop + * C) and therefore gcc (at least 2.95 and earlier) should + * always be told that RC4_CHUNK="unsigned long". + * + * + */ + +# define RC4_STEP ( \ + x=(x+1) &0xff, \ + tx=d[x], \ + y=(tx+y)&0xff, \ + ty=d[y], \ + d[y]=tx, \ + d[x]=ty, \ + (RC4_CHUNK)d[(tx+ty)&0xff]\ + ) + + if ((((size_t)indata & (sizeof(RC4_CHUNK) - 1)) | + ((size_t)outdata & (sizeof(RC4_CHUNK) - 1))) == 0 ) { + RC4_CHUNK ichunk, otp; + + /* + * I reckon we can afford to implement both endian + * cases and to decide which way to take at run-time + * because the machine code appears to be very compact + * and redundant 1-2KB is perfectly tolerable (i.e. + * in case the compiler fails to eliminate it:-). By + * suggestion from Terrel Larson . + * + * Special notes. + * + * - compilers (those I've tried) don't seem to have + * problems eliminating either the operators guarded + * by "if (sizeof(RC4_CHUNK)==8)" or the condition + * expressions themselves so I've got 'em to replace + * corresponding #ifdefs from the previous version; + * - I chose to let the redundant switch cases when + * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed + * before); + * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in + * [LB]ESHFT guards against "shift is out of range" + * warnings when sizeof(RC4_CHUNK)!=8 + * + * + */ +#if BYTE_ORDER == BIG_ENDIAN +# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { + ichunk = *(RC4_CHUNK *)indata; + otp = RC4_STEP << BESHFT(0); + otp |= RC4_STEP << BESHFT(1); + otp |= RC4_STEP << BESHFT(2); + otp |= RC4_STEP << BESHFT(3); + if (sizeof(RC4_CHUNK) == 8) { + otp |= RC4_STEP << BESHFT(4); + otp |= RC4_STEP << BESHFT(5); + otp |= RC4_STEP << BESHFT(6); + otp |= RC4_STEP << BESHFT(7); + } + *(RC4_CHUNK *)outdata = otp^ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } +#else +# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { + ichunk = *(RC4_CHUNK *)indata; + otp = RC4_STEP; + otp |= RC4_STEP << 8; + otp |= RC4_STEP << 16; + otp |= RC4_STEP << 24; + if (sizeof(RC4_CHUNK) == 8) { + otp |= RC4_STEP << LESHFT(4); + otp |= RC4_STEP << LESHFT(5); + otp |= RC4_STEP << LESHFT(6); + otp |= RC4_STEP << LESHFT(7); + } + *(RC4_CHUNK *)outdata = otp ^ ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } +#endif + } +#endif +#define LOOP(in,out) \ + x=((x+1)&0xff); \ + tx=d[x]; \ + y=(tx+y)&0xff; \ + d[x]=ty=d[y]; \ + d[y]=tx; \ + (out) = d[(tx+ty)&0xff]^ (in); + +#ifndef RC4_INDEX +#define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++)) +#else +#define RC4_LOOP(a,b,i) LOOP(a[i],b[i]) +#endif + + i = len >> 3; + if (i) { + for (;;) { + RC4_LOOP(indata, outdata, 0); + RC4_LOOP(indata, outdata, 1); + RC4_LOOP(indata, outdata, 2); + RC4_LOOP(indata, outdata, 3); + RC4_LOOP(indata, outdata, 4); + RC4_LOOP(indata, outdata, 5); + RC4_LOOP(indata, outdata, 6); + RC4_LOOP(indata, outdata, 7); +#ifdef RC4_INDEX + indata += 8; + outdata += 8; +#endif + if (--i == 0) + break; + } + } + i = len&0x07; + if (i) { + for (;;) { + RC4_LOOP(indata, outdata, 0); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 1); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 2); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 3); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 4); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 5); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 6); + if (--i == 0) + break; + } + } + key->x = x; + key->y = y; +} diff --git a/Libraries/libressl/crypto/rc4/rc4_local.h b/Libraries/libressl/crypto/rc4/rc4_local.h new file mode 100644 index 000000000..61d08a4d9 --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4_local.h @@ -0,0 +1,5 @@ +/* $OpenBSD: rc4_local.h,v 1.1 2022/11/26 16:08:54 tb Exp $ */ + +#ifndef HEADER_RC4_LOCL_H +#define HEADER_RC4_LOCL_H +#endif diff --git a/Libraries/libressl/crypto/rc4/rc4_skey.c b/Libraries/libressl/crypto/rc4/rc4_skey.c new file mode 100644 index 000000000..5833c7bd0 --- /dev/null +++ b/Libraries/libressl/crypto/rc4/rc4_skey.c @@ -0,0 +1,99 @@ +/* $OpenBSD: rc4_skey.c,v 1.16 2023/07/28 10:35:14 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "rc4_local.h" + +/* RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void +RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +{ + RC4_INT tmp; + int id1, id2; + RC4_INT *d; + unsigned int i; + + d = &(key->data[0]); + key->x = 0; + key->y = 0; + id1 = id2 = 0; + +#define SK_LOOP(d,n) { \ + tmp=d[(n)]; \ + id2 = (data[id1] + tmp + id2) & 0xff; \ + if (++id1 == len) id1=0; \ + d[(n)]=d[id2]; \ + d[id2]=tmp; } + + for (i = 0; i < 256; i++) + d[i] = i; + for (i = 0; i < 256; i += 4) { + SK_LOOP(d, i + 0); + SK_LOOP(d, i + 1); + SK_LOOP(d, i + 2); + SK_LOOP(d, i + 3); + } +} diff --git a/Libraries/libressl/crypto/ripemd/ripemd.c b/Libraries/libressl/crypto/ripemd/ripemd.c new file mode 100644 index 000000000..344d9f668 --- /dev/null +++ b/Libraries/libressl/crypto/ripemd/ripemd.c @@ -0,0 +1,442 @@ +/* $OpenBSD: ripemd.c,v 1.7 2023/08/10 12:27:35 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include +#include +#include + +/* + * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c + * FOR EXPLANATIONS ON FOLLOWING "CODE." + * + */ +#ifdef RMD160_ASM +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) +# define ripemd160_block_data_order ripemd160_block_asm_data_order +# endif +#endif + +__BEGIN_HIDDEN_DECLS + +void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p, size_t num); + +__END_HIDDEN_DECLS + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG RIPEMD160_LONG +#define HASH_CTX RIPEMD160_CTX +#define HASH_CBLOCK RIPEMD160_CBLOCK +#define HASH_UPDATE RIPEMD160_Update +#define HASH_TRANSFORM RIPEMD160_Transform +#define HASH_FINAL RIPEMD160_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; HOST_l2c(ll,(s)); \ + ll=(c)->B; HOST_l2c(ll,(s)); \ + ll=(c)->C; HOST_l2c(ll,(s)); \ + ll=(c)->D; HOST_l2c(ll,(s)); \ + ll=(c)->E; HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order + +#include "md32_common.h" + +#if 0 +#define F1(x,y,z) ((x)^(y)^(z)) +#define F2(x,y,z) (((x)&(y))|((~x)&z)) +#define F3(x,y,z) (((x)|(~y))^(z)) +#define F4(x,y,z) (((x)&(z))|((y)&(~(z)))) +#define F5(x,y,z) ((x)^((y)|(~(z)))) +#else +/* + * Transformed F2 and F4 are courtesy of Wei Dai + */ +#define F1(x,y,z) ((x) ^ (y) ^ (z)) +#define F2(x,y,z) ((((y) ^ (z)) & (x)) ^ (z)) +#define F3(x,y,z) (((~(y)) | (x)) ^ (z)) +#define F4(x,y,z) ((((x) ^ (y)) & (z)) ^ (y)) +#define F5(x,y,z) (((~(z)) | (y)) ^ (x)) +#endif + +#define RIPEMD160_A 0x67452301L +#define RIPEMD160_B 0xEFCDAB89L +#define RIPEMD160_C 0x98BADCFEL +#define RIPEMD160_D 0x10325476L +#define RIPEMD160_E 0xC3D2E1F0L + +#define KL0 0x00000000L +#define KL1 0x5A827999L +#define KL2 0x6ED9EBA1L +#define KL3 0x8F1BBCDCL +#define KL4 0xA953FD4EL + +#define KR0 0x50A28BE6L +#define KR1 0x5C4DD124L +#define KR2 0x6D703EF3L +#define KR3 0x7A6D76E9L +#define KR4 0x00000000L + +#define RIP1(a,b,c,d,e,w,s) { \ + a+=F1(b,c,d)+w; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP2(a,b,c,d,e,w,s,K) { \ + a+=F2(b,c,d)+w+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP3(a,b,c,d,e,w,s,K) { \ + a+=F3(b,c,d)+w+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP4(a,b,c,d,e,w,s,K) { \ + a+=F4(b,c,d)+w+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP5(a,b,c,d,e,w,s,K) { \ + a+=F5(b,c,d)+w+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +# ifdef RMD160_ASM +void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num); +# define ripemd160_block ripemd160_block_x86 +# else +void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num); +# endif + +int +RIPEMD160_Init(RIPEMD160_CTX *c) +{ + memset (c, 0, sizeof(*c)); + c->A = RIPEMD160_A; + c->B = RIPEMD160_B; + c->C = RIPEMD160_C; + c->D = RIPEMD160_D; + c->E = RIPEMD160_E; + return 1; +} + +#ifndef ripemd160_block_data_order +void +ripemd160_block_data_order(RIPEMD160_CTX *ctx, const void *p, size_t num) +{ + const unsigned char *data = p; + unsigned int A, B, C, D, E; + unsigned int a, b, c, d, e, l; + unsigned int X0, X1, X2, X3, X4, X5, X6, X7, + X8, X9, X10, X11, X12, X13, X14, X15; + + for (; num--; ) { + + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + + HOST_c2l(data, l); + X0 = l; + HOST_c2l(data, l); + X1 = l; + RIP1(A, B, C, D, E, X0, 11); + HOST_c2l(data, l); + X2 = l; + RIP1(E, A, B, C, D, X1, 14); + HOST_c2l(data, l); + X3 = l; + RIP1(D, E, A, B, C, X2, 15); + HOST_c2l(data, l); + X4 = l; + RIP1(C, D, E, A, B, X3, 12); + HOST_c2l(data, l); + X5 = l; + RIP1(B, C, D, E, A, X4, 5); + HOST_c2l(data, l); + X6 = l; + RIP1(A, B, C, D, E, X5, 8); + HOST_c2l(data, l); + X7 = l; + RIP1(E, A, B, C, D, X6, 7); + HOST_c2l(data, l); + X8 = l; + RIP1(D, E, A, B, C, X7, 9); + HOST_c2l(data, l); + X9 = l; + RIP1(C, D, E, A, B, X8, 11); + HOST_c2l(data, l); + X10 = l; + RIP1(B, C, D, E, A, X9, 13); + HOST_c2l(data, l); + X11 = l; + RIP1(A, B, C, D, E, X10, 14); + HOST_c2l(data, l); + X12 = l; + RIP1(E, A, B, C, D, X11, 15); + HOST_c2l(data, l); + X13 = l; + RIP1(D, E, A, B, C, X12, 6); + HOST_c2l(data, l); + X14 = l; + RIP1(C, D, E, A, B, X13, 7); + HOST_c2l(data, l); + X15 = l; + RIP1(B, C, D, E, A, X14, 9); + RIP1(A, B, C, D, E, X15, 8); + + RIP2(E, A, B, C, D, X7, 7, KL1); + RIP2(D, E, A, B, C, X4, 6, KL1); + RIP2(C, D, E, A, B, X13, 8, KL1); + RIP2(B, C, D, E, A, X1, 13, KL1); + RIP2(A, B, C, D, E, X10, 11, KL1); + RIP2(E, A, B, C, D, X6, 9, KL1); + RIP2(D, E, A, B, C, X15, 7, KL1); + RIP2(C, D, E, A, B, X3, 15, KL1); + RIP2(B, C, D, E, A, X12, 7, KL1); + RIP2(A, B, C, D, E, X0, 12, KL1); + RIP2(E, A, B, C, D, X9, 15, KL1); + RIP2(D, E, A, B, C, X5, 9, KL1); + RIP2(C, D, E, A, B, X2, 11, KL1); + RIP2(B, C, D, E, A, X14, 7, KL1); + RIP2(A, B, C, D, E, X11, 13, KL1); + RIP2(E, A, B, C, D, X8, 12, KL1); + + RIP3(D, E, A, B, C, X3, 11, KL2); + RIP3(C, D, E, A, B, X10, 13, KL2); + RIP3(B, C, D, E, A, X14, 6, KL2); + RIP3(A, B, C, D, E, X4, 7, KL2); + RIP3(E, A, B, C, D, X9, 14, KL2); + RIP3(D, E, A, B, C, X15, 9, KL2); + RIP3(C, D, E, A, B, X8, 13, KL2); + RIP3(B, C, D, E, A, X1, 15, KL2); + RIP3(A, B, C, D, E, X2, 14, KL2); + RIP3(E, A, B, C, D, X7, 8, KL2); + RIP3(D, E, A, B, C, X0, 13, KL2); + RIP3(C, D, E, A, B, X6, 6, KL2); + RIP3(B, C, D, E, A, X13, 5, KL2); + RIP3(A, B, C, D, E, X11, 12, KL2); + RIP3(E, A, B, C, D, X5, 7, KL2); + RIP3(D, E, A, B, C, X12, 5, KL2); + + RIP4(C, D, E, A, B, X1, 11, KL3); + RIP4(B, C, D, E, A, X9, 12, KL3); + RIP4(A, B, C, D, E, X11, 14, KL3); + RIP4(E, A, B, C, D, X10, 15, KL3); + RIP4(D, E, A, B, C, X0, 14, KL3); + RIP4(C, D, E, A, B, X8, 15, KL3); + RIP4(B, C, D, E, A, X12, 9, KL3); + RIP4(A, B, C, D, E, X4, 8, KL3); + RIP4(E, A, B, C, D, X13, 9, KL3); + RIP4(D, E, A, B, C, X3, 14, KL3); + RIP4(C, D, E, A, B, X7, 5, KL3); + RIP4(B, C, D, E, A, X15, 6, KL3); + RIP4(A, B, C, D, E, X14, 8, KL3); + RIP4(E, A, B, C, D, X5, 6, KL3); + RIP4(D, E, A, B, C, X6, 5, KL3); + RIP4(C, D, E, A, B, X2, 12, KL3); + + RIP5(B, C, D, E, A, X4, 9, KL4); + RIP5(A, B, C, D, E, X0, 15, KL4); + RIP5(E, A, B, C, D, X5, 5, KL4); + RIP5(D, E, A, B, C, X9, 11, KL4); + RIP5(C, D, E, A, B, X7, 6, KL4); + RIP5(B, C, D, E, A, X12, 8, KL4); + RIP5(A, B, C, D, E, X2, 13, KL4); + RIP5(E, A, B, C, D, X10, 12, KL4); + RIP5(D, E, A, B, C, X14, 5, KL4); + RIP5(C, D, E, A, B, X1, 12, KL4); + RIP5(B, C, D, E, A, X3, 13, KL4); + RIP5(A, B, C, D, E, X8, 14, KL4); + RIP5(E, A, B, C, D, X11, 11, KL4); + RIP5(D, E, A, B, C, X6, 8, KL4); + RIP5(C, D, E, A, B, X15, 5, KL4); + RIP5(B, C, D, E, A, X13, 6, KL4); + + a = A; + b = B; + c = C; + d = D; + e = E; + /* Do other half */ + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + + RIP5(A, B, C, D, E, X5, 8, KR0); + RIP5(E, A, B, C, D, X14, 9, KR0); + RIP5(D, E, A, B, C, X7, 9, KR0); + RIP5(C, D, E, A, B, X0, 11, KR0); + RIP5(B, C, D, E, A, X9, 13, KR0); + RIP5(A, B, C, D, E, X2, 15, KR0); + RIP5(E, A, B, C, D, X11, 15, KR0); + RIP5(D, E, A, B, C, X4, 5, KR0); + RIP5(C, D, E, A, B, X13, 7, KR0); + RIP5(B, C, D, E, A, X6, 7, KR0); + RIP5(A, B, C, D, E, X15, 8, KR0); + RIP5(E, A, B, C, D, X8, 11, KR0); + RIP5(D, E, A, B, C, X1, 14, KR0); + RIP5(C, D, E, A, B, X10, 14, KR0); + RIP5(B, C, D, E, A, X3, 12, KR0); + RIP5(A, B, C, D, E, X12, 6, KR0); + + RIP4(E, A, B, C, D, X6, 9, KR1); + RIP4(D, E, A, B, C, X11, 13, KR1); + RIP4(C, D, E, A, B, X3, 15, KR1); + RIP4(B, C, D, E, A, X7, 7, KR1); + RIP4(A, B, C, D, E, X0, 12, KR1); + RIP4(E, A, B, C, D, X13, 8, KR1); + RIP4(D, E, A, B, C, X5, 9, KR1); + RIP4(C, D, E, A, B, X10, 11, KR1); + RIP4(B, C, D, E, A, X14, 7, KR1); + RIP4(A, B, C, D, E, X15, 7, KR1); + RIP4(E, A, B, C, D, X8, 12, KR1); + RIP4(D, E, A, B, C, X12, 7, KR1); + RIP4(C, D, E, A, B, X4, 6, KR1); + RIP4(B, C, D, E, A, X9, 15, KR1); + RIP4(A, B, C, D, E, X1, 13, KR1); + RIP4(E, A, B, C, D, X2, 11, KR1); + + RIP3(D, E, A, B, C, X15, 9, KR2); + RIP3(C, D, E, A, B, X5, 7, KR2); + RIP3(B, C, D, E, A, X1, 15, KR2); + RIP3(A, B, C, D, E, X3, 11, KR2); + RIP3(E, A, B, C, D, X7, 8, KR2); + RIP3(D, E, A, B, C, X14, 6, KR2); + RIP3(C, D, E, A, B, X6, 6, KR2); + RIP3(B, C, D, E, A, X9, 14, KR2); + RIP3(A, B, C, D, E, X11, 12, KR2); + RIP3(E, A, B, C, D, X8, 13, KR2); + RIP3(D, E, A, B, C, X12, 5, KR2); + RIP3(C, D, E, A, B, X2, 14, KR2); + RIP3(B, C, D, E, A, X10, 13, KR2); + RIP3(A, B, C, D, E, X0, 13, KR2); + RIP3(E, A, B, C, D, X4, 7, KR2); + RIP3(D, E, A, B, C, X13, 5, KR2); + + RIP2(C, D, E, A, B, X8, 15, KR3); + RIP2(B, C, D, E, A, X6, 5, KR3); + RIP2(A, B, C, D, E, X4, 8, KR3); + RIP2(E, A, B, C, D, X1, 11, KR3); + RIP2(D, E, A, B, C, X3, 14, KR3); + RIP2(C, D, E, A, B, X11, 14, KR3); + RIP2(B, C, D, E, A, X15, 6, KR3); + RIP2(A, B, C, D, E, X0, 14, KR3); + RIP2(E, A, B, C, D, X5, 6, KR3); + RIP2(D, E, A, B, C, X12, 9, KR3); + RIP2(C, D, E, A, B, X2, 12, KR3); + RIP2(B, C, D, E, A, X13, 9, KR3); + RIP2(A, B, C, D, E, X9, 12, KR3); + RIP2(E, A, B, C, D, X7, 5, KR3); + RIP2(D, E, A, B, C, X10, 15, KR3); + RIP2(C, D, E, A, B, X14, 8, KR3); + + RIP1(B, C, D, E, A, X12, 8); + RIP1(A, B, C, D, E, X15, 5); + RIP1(E, A, B, C, D, X10, 12); + RIP1(D, E, A, B, C, X4, 9); + RIP1(C, D, E, A, B, X1, 12); + RIP1(B, C, D, E, A, X5, 5); + RIP1(A, B, C, D, E, X8, 14); + RIP1(E, A, B, C, D, X7, 6); + RIP1(D, E, A, B, C, X6, 8); + RIP1(C, D, E, A, B, X2, 13); + RIP1(B, C, D, E, A, X13, 6); + RIP1(A, B, C, D, E, X14, 5); + RIP1(E, A, B, C, D, X0, 15); + RIP1(D, E, A, B, C, X3, 13); + RIP1(C, D, E, A, B, X9, 11); + RIP1(B, C, D, E, A, X11, 11); + + D = ctx->B + c + D; + ctx->B = ctx->C + d + E; + ctx->C = ctx->D + e + A; + ctx->D = ctx->E + a + B; + ctx->E = ctx->A + b + C; + ctx->A = D; + + } +} +#endif + +unsigned char * +RIPEMD160(const unsigned char *d, size_t n, + unsigned char *md) +{ + RIPEMD160_CTX c; + static unsigned char m[RIPEMD160_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!RIPEMD160_Init(&c)) + return NULL; + RIPEMD160_Update(&c, d, n); + RIPEMD160_Final(md, &c); + explicit_bzero(&c, sizeof(c)); + return (md); +} diff --git a/Libraries/libressl/crypto/rsa/rsa_ameth.c b/Libraries/libressl/crypto/rsa/rsa_ameth.c new file mode 100644 index 000000000..ae38c205a --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_ameth.c @@ -0,0 +1,1143 @@ +/* $OpenBSD: rsa_ameth.c,v 1.33 2023/08/12 08:02:43 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "bn_local.h" +#include "cryptlib.h" +#include "evp_local.h" +#include "rsa_local.h" + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_sign(CMS_SignerInfo *si); +static int rsa_cms_verify(CMS_SignerInfo *si); +static int rsa_cms_decrypt(CMS_RecipientInfo *ri); +static int rsa_cms_encrypt(CMS_RecipientInfo *ri); +#endif + +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); + +/* Set any parameters associated with pkey */ +static int +rsa_param_encode(const EVP_PKEY *pkey, ASN1_STRING **pstr, int *pstrtype) +{ + const RSA *rsa = pkey->pkey.rsa; + + *pstr = NULL; + + /* If RSA it's just NULL type */ + if (pkey->ameth->pkey_id != EVP_PKEY_RSA_PSS) { + *pstrtype = V_ASN1_NULL; + return 1; + } + + /* If no PSS parameters we omit parameters entirely */ + if (rsa->pss == NULL) { + *pstrtype = V_ASN1_UNDEF; + return 1; + } + + /* Encode PSS parameters */ + if (ASN1_item_pack(rsa->pss, &RSA_PSS_PARAMS_it, pstr) == NULL) + return 0; + + *pstrtype = V_ASN1_SEQUENCE; + return 1; +} + +/* Decode any parameters and set them in RSA structure */ +static int +rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) +{ + const ASN1_OBJECT *algoid; + const void *algp; + int algptype; + + X509_ALGOR_get0(&algoid, &algptype, &algp, alg); + if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) + return 1; + if (algptype == V_ASN1_UNDEF) + return 1; + if (algptype != V_ASN1_SEQUENCE) { + RSAerror(RSA_R_INVALID_PSS_PARAMETERS); + return 0; + } + rsa->pss = rsa_pss_decode(alg); + if (rsa->pss == NULL) + return 0; + return 1; +} + +static int +rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + ASN1_STRING *str = NULL; + int strtype; + unsigned char *penc = NULL; + int penclen = 0; + ASN1_OBJECT *aobj; + + if (!rsa_param_encode(pkey, &str, &strtype)) + goto err; + if ((penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc)) <= 0) { + penclen = 0; + goto err; + } + if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL) + goto err; + if (!X509_PUBKEY_set0_param(pk, aobj, strtype, str, penc, penclen)) + goto err; + + return 1; + + err: + ASN1_STRING_free(str); + freezero(penc, penclen); + + return 0; +} + +static int +rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p; + int pklen; + X509_ALGOR *alg; + RSA *rsa = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) + return 0; + if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { + RSAerror(ERR_R_RSA_LIB); + return 0; + } + if (!rsa_param_decode(rsa, alg)) { + RSA_free(rsa); + return 0; + } + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) { + RSA_free(rsa); + return 0; + } + return 1; +} + +static int +rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 || + BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) + return 0; + + return 1; +} + +static int +old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) +{ + RSA *rsa; + + if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) { + RSAerror(ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); + return 1; +} + +static int +old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); +} + +static int +rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *str = NULL; + ASN1_OBJECT *aobj; + int strtype; + unsigned char *rk = NULL; + int rklen = 0; + + if (!rsa_param_encode(pkey, &str, &strtype)) + goto err; + if ((rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk)) <= 0) { + RSAerror(ERR_R_MALLOC_FAILURE); + rklen = 0; + goto err; + } + if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL) + goto err; + if (!PKCS8_pkey_set0(p8, aobj, 0, strtype, str, rk, rklen)) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + return 1; + + err: + ASN1_STRING_free(str); + freezero(rk, rklen); + + return 0; +} + +static int +rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p; + RSA *rsa; + int pklen; + const X509_ALGOR *alg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8)) + return 0; + rsa = d2i_RSAPrivateKey(NULL, &p, pklen); + if (rsa == NULL) { + RSAerror(ERR_R_RSA_LIB); + return 0; + } + if (!rsa_param_decode(rsa, alg)) { + RSA_free(rsa); + return 0; + } + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); + + return 1; +} + +static int +rsa_size(const EVP_PKEY *pkey) +{ + return RSA_size(pkey->pkey.rsa); +} + +static int +rsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.rsa->n); +} + +static int +rsa_security_bits(const EVP_PKEY *pkey) +{ + return RSA_security_bits(pkey->pkey.rsa); +} + +static void +rsa_free(EVP_PKEY *pkey) +{ + RSA_free(pkey->pkey.rsa); +} + +static X509_ALGOR * +rsa_mgf1_decode(X509_ALGOR *alg) +{ + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) + return NULL; + + return ASN1_TYPE_unpack_sequence(&X509_ALGOR_it, alg->parameter); +} + +static RSA_PSS_PARAMS * +rsa_pss_decode(const X509_ALGOR *alg) +{ + RSA_PSS_PARAMS *pss; + + pss = ASN1_TYPE_unpack_sequence(&RSA_PSS_PARAMS_it, alg->parameter); + if (pss == NULL) + return NULL; + + if (pss->maskGenAlgorithm != NULL) { + pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + if (pss->maskHash == NULL) { + RSA_PSS_PARAMS_free(pss); + return NULL; + } + } + + return pss; +} + +static int +rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, int indent) +{ + int rv = 0; + X509_ALGOR *maskHash = NULL; + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (pss_key) { + if (pss == NULL) { + if (BIO_puts(bp, "No PSS parameter restrictions\n") <= 0) + return 0; + return 1; + } else { + if (BIO_puts(bp, "PSS parameter restrictions:") <= 0) + return 0; + } + } else if (pss == NULL) { + if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0) + return 0; + return 1; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + if (pss_key) + indent += 2; + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Hash Algorithm: ") <= 0) + goto err; + + if (pss->hashAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "sha1 (default)") <= 0) { + goto err; + } + + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (!BIO_indent(bp, indent, 128)) + goto err; + + if (BIO_puts(bp, "Mask Algorithm: ") <= 0) + goto err; + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) + goto err; + if (BIO_puts(bp, " with ") <= 0) + goto err; + maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + if (maskHash != NULL) { + if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "INVALID") <= 0) { + goto err; + } + } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_printf(bp, "%s Salt Length: 0x", pss_key ? "Minimum" : "") <= 0) + goto err; + if (pss->saltLength) { + if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) + goto err; + } else if (BIO_puts(bp, "14 (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Trailer Field: 0x") <= 0) + goto err; + if (pss->trailerField) { + if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) + goto err; + } else if (BIO_puts(bp, "BC (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + rv = 1; + + err: + X509_ALGOR_free(maskHash); + return rv; + +} + +static int +pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) +{ + const RSA *x = pkey->pkey.rsa; + char *str; + const char *s; + int ret = 0, mod_len = 0; + + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (BIO_printf(bp, "%s ", pkey_is_pss(pkey) ? "RSA-PSS" : "RSA") <= 0) + goto err; + + if (priv && x->d != NULL) { + if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) <= 0) + goto err; + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) + goto err; + str = "Modulus:"; + s = "Exponent:"; + } + if (!bn_printf(bp, x->n, off, "%s", str)) + goto err; + if (!bn_printf(bp, x->e, off, "%s", s)) + goto err; + if (priv) { + if (!bn_printf(bp, x->d, off, "privateExponent:")) + goto err; + if (!bn_printf(bp, x->p, off, "prime1:")) + goto err; + if (!bn_printf(bp, x->q, off, "prime2:")) + goto err; + if (!bn_printf(bp, x->dmp1, off, "exponent1:")) + goto err; + if (!bn_printf(bp, x->dmq1, off, "exponent2:")) + goto err; + if (!bn_printf(bp, x->iqmp, off, "coefficient:")) + goto err; + } + if (pkey_is_pss(pkey) && !rsa_pss_param_print(bp, 1, x->pss, off)) + goto err; + ret = 1; + err: + return ret; +} + +static int +rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return pkey_rsa_print(bp, pkey, indent, 0); +} + +static int +rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) +{ + return pkey_rsa_print(bp, pkey, indent, 1); +} + +static int +rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx) +{ + if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { + int rv; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); + + rv = rsa_pss_param_print(bp, 0, pss, indent); + RSA_PSS_PARAMS_free(pss); + if (!rv) + return 0; + } else if (!sig && BIO_puts(bp, "\n") <= 0) { + return 0; + } + if (sig) + return X509_signature_dump(bp, sig, indent); + return 1; +} + +static int +rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + X509_ALGOR *alg = NULL; + const EVP_MD *md; + const EVP_MD *mgf1md; + int min_saltlen; + + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (pkey_is_pss(pkey)) + return -2; + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg); + break; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + return rsa_cms_sign(arg2); + else if (arg1 == 1) + return rsa_cms_verify(arg2); + break; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (pkey_is_pss(pkey)) + return -2; + if (arg1 == 0) + return rsa_cms_encrypt(arg2); + else if (arg1 == 1) + return rsa_cms_decrypt(arg2); + break; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + if (pkey_is_pss(pkey)) + return -2; + *(int *)arg2 = CMS_RECIPINFO_TRANS; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + if (pkey->pkey.rsa->pss != NULL) { + if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md, + &min_saltlen)) { + RSAerror(ERR_R_INTERNAL_ERROR); + return 0; + } + *(int *)arg2 = EVP_MD_type(md); + /* Return of 2 indicates this MD is mandatory */ + return 2; + } + *(int *)arg2 = NID_sha256; + return 1; + + default: + return -2; + } + + if (alg) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, 0); + + return 1; +} + +/* Allocate and set algorithm ID from EVP_MD, defaults to SHA1. */ +static int +rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) +{ + if (md == NULL || EVP_MD_type(md) == NID_sha1) + return 1; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + return 0; + X509_ALGOR_set_md(*palg, md); + return 1; +} + +/* Allocate and set MGF1 algorithm ID from EVP_MD. */ +static int +rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) +{ + X509_ALGOR *algtmp = NULL; + ASN1_STRING *stmp = NULL; + + *palg = NULL; + if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1) + return 1; + /* need to embed algorithm ID inside another */ + if (!rsa_md_to_algor(&algtmp, mgf1md)) + goto err; + if (ASN1_item_pack(algtmp, &X509_ALGOR_it, &stmp) == NULL) + goto err; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + goto err; + X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + stmp = NULL; + err: + ASN1_STRING_free(stmp); + X509_ALGOR_free(algtmp); + if (*palg) + return 1; + return 0; +} + +/* Convert algorithm ID to EVP_MD, defaults to SHA1. */ +static const EVP_MD * +rsa_algor_to_md(X509_ALGOR *alg) +{ + const EVP_MD *md; + + if (!alg) + return EVP_sha1(); + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) + RSAerror(RSA_R_UNKNOWN_DIGEST); + return md; +} + +/* + * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter, + * suitable for setting an AlgorithmIdentifier. + */ +static RSA_PSS_PARAMS * +rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) +{ + const EVP_MD *sigmd, *mgf1md; + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); + int saltlen; + + if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) + return NULL; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + return NULL; + if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) + return NULL; + if (saltlen == -1) { + saltlen = EVP_MD_size(sigmd); + } else if (saltlen == -2 || saltlen == -3) { + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; + if ((EVP_PKEY_bits(pk) & 0x7) == 1) + saltlen--; + if (saltlen < 0) + return NULL; + } + + return rsa_pss_params_create(sigmd, mgf1md, saltlen); +} + +RSA_PSS_PARAMS * +rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, int saltlen) +{ + RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); + + if (pss == NULL) + goto err; + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (pss->saltLength == NULL) + goto err; + if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) + goto err; + } + if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) + goto err; + if (mgf1md == NULL) + mgf1md = sigmd; + if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) + goto err; + if (!rsa_md_to_algor(&pss->maskHash, mgf1md)) + goto err; + return pss; + err: + RSA_PSS_PARAMS_free(pss); + return NULL; +} + +static ASN1_STRING * +rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) +{ + RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); + ASN1_STRING *os; + + if (pss == NULL) + return NULL; + + os = ASN1_item_pack(pss, &RSA_PSS_PARAMS_it, NULL); + RSA_PSS_PARAMS_free(pss); + return os; +} + +/* + * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL + * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are + * passed to pkctx instead. + */ + +static int +rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + X509_ALGOR *sigalg, EVP_PKEY *pkey) +{ + int rv = -1; + int saltlen; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_PSS_PARAMS *pss; + + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { + RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + /* Decode PSS parameters */ + pss = rsa_pss_decode(sigalg); + + if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { + RSAerror(RSA_R_INVALID_PSS_PARAMETERS); + goto err; + } + + /* We have all parameters now set up context */ + if (pkey) { + if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) + goto err; + } else { + const EVP_MD *checkmd; + if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) + goto err; + if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { + RSAerror(RSA_R_DIGEST_DOES_NOT_MATCH); + goto err; + } + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + /* Carry on */ + rv = 1; + + err: + RSA_PSS_PARAMS_free(pss); + return rv; +} + +int +rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, + const EVP_MD **pmgf1md, int *psaltlen) +{ + if (pss == NULL) + return 0; + *pmd = rsa_algor_to_md(pss->hashAlgorithm); + if (*pmd == NULL) + return 0; + *pmgf1md = rsa_algor_to_md(pss->maskHash); + if (*pmgf1md == NULL) + return 0; + if (pss->saltLength) { + *psaltlen = ASN1_INTEGER_get(pss->saltLength); + if (*psaltlen < 0) { + RSAerror(RSA_R_INVALID_SALT_LENGTH); + return 0; + } + } else { + *psaltlen = 20; + } + + /* + * low-level routines support only trailer field 0xbc (value 1) and + * PKCS#1 says we should reject any other value anyway. + */ + if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { + RSAerror(RSA_R_INVALID_TRAILER); + return 0; + } + + return 1; +} + +#ifndef OPENSSL_NO_CMS +static int +rsa_cms_verify(CMS_SignerInfo *si) +{ + int nid, nid2; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + nid = OBJ_obj2nid(alg->algorithm); + if (nid == EVP_PKEY_RSA_PSS) + return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); + /* Only PSS allowed for PSS keys */ + if (pkey_ctx_is_pss(pkctx)) { + RSAerror(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if (nid == NID_rsaEncryption) + return 1; + /* Workaround for some implementation that use a signature OID */ + if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { + if (nid2 == NID_rsaEncryption) + return 1; + } + return 0; +} +#endif + +/* + * Customised RSA item verification routine. This is called when a signature + * is encountered requiring special handling. We currently only handle PSS. + */ +static int +rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey) +{ + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { + RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { + /* Carry on */ + return 2; + } + return -1; +} + +#ifndef OPENSSL_NO_CMS +static int +rsa_cms_sign(CMS_SignerInfo *si) +{ + int pad_mode = RSA_PKCS1_PADDING; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + ASN1_STRING *os = NULL; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + if (pkctx) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* We don't support it */ + if (pad_mode != RSA_PKCS1_PSS_PADDING) + return 0; + os = rsa_ctx_to_pss_string(pkctx); + if (!os) + return 0; + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); + return 1; +} +#endif + +static int +rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) +{ + EVP_PKEY_CTX *pkctx = ctx->pctx; + int pad_mode; + + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + if (pad_mode == RSA_PKCS1_PADDING) + return 2; + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + ASN1_STRING *os1 = NULL; + os1 = rsa_ctx_to_pss_string(pkctx); + if (!os1) + return 0; + /* Duplicate parameters if we have to */ + if (alg2) { + ASN1_STRING *os2 = ASN1_STRING_dup(os1); + if (!os2) { + ASN1_STRING_free(os1); + return 0; + } + X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS), + V_ASN1_SEQUENCE, os2); + } + X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS), + V_ASN1_SEQUENCE, os1); + return 3; + } + return 2; +} + +static int +rsa_pkey_check(const EVP_PKEY *pkey) +{ + return RSA_check_key(pkey->pkey.rsa); +} + +#ifndef OPENSSL_NO_CMS +static RSA_OAEP_PARAMS * +rsa_oaep_decode(const X509_ALGOR *alg) +{ + RSA_OAEP_PARAMS *oaep; + + oaep = ASN1_TYPE_unpack_sequence(&RSA_OAEP_PARAMS_it, alg->parameter); + if (oaep == NULL) + return NULL; + + if (oaep->maskGenFunc != NULL) { + oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc); + if (oaep->maskHash == NULL) { + RSA_OAEP_PARAMS_free(oaep); + return NULL; + } + } + return oaep; +} + +static int +rsa_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pkctx; + X509_ALGOR *cmsalg; + int nid; + int rv = -1; + unsigned char *label = NULL; + int labellen = 0; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_OAEP_PARAMS *oaep; + + pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pkctx == NULL) + return 0; + if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) + return -1; + nid = OBJ_obj2nid(cmsalg->algorithm); + if (nid == NID_rsaEncryption) + return 1; + if (nid != NID_rsaesOaep) { + RSAerror(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); + return -1; + } + /* Decode OAEP parameters */ + oaep = rsa_oaep_decode(cmsalg); + + if (oaep == NULL) { + RSAerror(RSA_R_INVALID_OAEP_PARAMETERS); + goto err; + } + + mgf1md = rsa_algor_to_md(oaep->maskHash); + if (mgf1md == NULL) + goto err; + md = rsa_algor_to_md(oaep->hashFunc); + if (md == NULL) + goto err; + + if (oaep->pSourceFunc != NULL) { + X509_ALGOR *plab = oaep->pSourceFunc; + + if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { + RSAerror(RSA_R_UNSUPPORTED_LABEL_SOURCE); + goto err; + } + if (plab->parameter->type != V_ASN1_OCTET_STRING) { + RSAerror(RSA_R_INVALID_LABEL); + goto err; + } + + label = plab->parameter->value.octet_string->data; + + /* Stop label being freed when OAEP parameters are freed */ + /* XXX - this leaks label on error... */ + plab->parameter->value.octet_string->data = NULL; + labellen = plab->parameter->value.octet_string->length; + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + goto err; + + rv = 1; + + err: + RSA_OAEP_PARAMS_free(oaep); + return rv; +} + +static int +rsa_cms_encrypt(CMS_RecipientInfo *ri) +{ + const EVP_MD *md, *mgf1md; + RSA_OAEP_PARAMS *oaep = NULL; + ASN1_STRING *os = NULL; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; + unsigned char *label; + + if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) + return 0; + if (pkctx) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* Not supported */ + if (pad_mode != RSA_PKCS1_OAEP_PADDING) + return 0; + if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) + goto err; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); + if (labellen < 0) + goto err; + oaep = RSA_OAEP_PARAMS_new(); + if (oaep == NULL) + goto err; + if (!rsa_md_to_algor(&oaep->hashFunc, md)) + goto err; + if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) + goto err; + if (labellen > 0) { + ASN1_OCTET_STRING *los; + oaep->pSourceFunc = X509_ALGOR_new(); + if (oaep->pSourceFunc == NULL) + goto err; + los = ASN1_OCTET_STRING_new(); + if (los == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(los, label, labellen)) { + ASN1_OCTET_STRING_free(los); + goto err; + } + X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), + V_ASN1_OCTET_STRING, los); + } + /* create string with pss parameter encoding. */ + if (!ASN1_item_pack(oaep, &RSA_OAEP_PARAMS_it, &os)) + goto err; + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); + os = NULL; + rv = 1; + err: + RSA_OAEP_PARAMS_free(oaep); + ASN1_STRING_free(os); + return rv; +} +#endif + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { + { + .pkey_id = EVP_PKEY_RSA, + .pkey_base_id = EVP_PKEY_RSA, + .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, + + .pem_str = "RSA", + .info = "OpenSSL RSA method", + + .pub_decode = rsa_pub_decode, + .pub_encode = rsa_pub_encode, + .pub_cmp = rsa_pub_cmp, + .pub_print = rsa_pub_print, + + .priv_decode = rsa_priv_decode, + .priv_encode = rsa_priv_encode, + .priv_print = rsa_priv_print, + + .pkey_size = rsa_size, + .pkey_bits = rsa_bits, + .pkey_security_bits = rsa_security_bits, + + .sig_print = rsa_sig_print, + + .pkey_free = rsa_free, + .pkey_ctrl = rsa_pkey_ctrl, + .old_priv_decode = old_rsa_priv_decode, + .old_priv_encode = old_rsa_priv_encode, + .item_verify = rsa_item_verify, + .item_sign = rsa_item_sign, + + .pkey_check = rsa_pkey_check, + }, + + { + .pkey_id = EVP_PKEY_RSA2, + .pkey_base_id = EVP_PKEY_RSA, + .pkey_flags = ASN1_PKEY_ALIAS, + + .pkey_check = rsa_pkey_check, + }, +}; + +const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { + .pkey_id = EVP_PKEY_RSA_PSS, + .pkey_base_id = EVP_PKEY_RSA_PSS, + .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, + + .pem_str = "RSA-PSS", + .info = "OpenSSL RSA-PSS method", + + .pub_decode = rsa_pub_decode, + .pub_encode = rsa_pub_encode, + .pub_cmp = rsa_pub_cmp, + .pub_print = rsa_pub_print, + + .priv_decode = rsa_priv_decode, + .priv_encode = rsa_priv_encode, + .priv_print = rsa_priv_print, + + .pkey_size = rsa_size, + .pkey_bits = rsa_bits, + .pkey_security_bits = rsa_security_bits, + + .sig_print = rsa_sig_print, + + .pkey_free = rsa_free, + .pkey_ctrl = rsa_pkey_ctrl, + .item_verify = rsa_item_verify, + .item_sign = rsa_item_sign +}; diff --git a/Libraries/libressl/crypto/rsa/rsa_asn1.c b/Libraries/libressl/crypto/rsa/rsa_asn1.c new file mode 100644 index 000000000..0f6d8c49f --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_asn1.c @@ -0,0 +1,422 @@ +/* $OpenBSD: rsa_asn1.c,v 1.17 2023/07/08 12:26:45 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "rsa_local.h" + +/* Override the default free and new methods */ +static int +rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)RSA_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + RSA_free((RSA *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +static const ASN1_AUX RSAPrivateKey_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = rsa_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE RSAPrivateKey_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, version), + .field_name = "version", + .item = &LONG_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, n), + .field_name = "n", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, e), + .field_name = "e", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, d), + .field_name = "d", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, p), + .field_name = "p", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, q), + .field_name = "q", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, dmp1), + .field_name = "dmp1", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, dmq1), + .field_name = "dmq1", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, iqmp), + .field_name = "iqmp", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM RSAPrivateKey_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = RSAPrivateKey_seq_tt, + .tcount = sizeof(RSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &RSAPrivateKey_aux, + .size = sizeof(RSA), + .sname = "RSA", +}; + + +static const ASN1_AUX RSAPublicKey_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = rsa_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE RSAPublicKey_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, n), + .field_name = "n", + .item = &BIGNUM_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(RSA, e), + .field_name = "e", + .item = &BIGNUM_it, + }, +}; + +const ASN1_ITEM RSAPublicKey_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = RSAPublicKey_seq_tt, + .tcount = sizeof(RSAPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &RSAPublicKey_aux, + .size = sizeof(RSA), + .sname = "RSA", +}; + +static int +rsa_pss_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + /* Free up maskHash */ + if (operation == ASN1_OP_FREE_PRE) { + RSA_PSS_PARAMS *pss = (RSA_PSS_PARAMS *)*pval; + X509_ALGOR_free(pss->maskHash); + } + return 1; +} + +static const ASN1_AUX RSA_PSS_PARAMS_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = rsa_pss_cb, + .enc_offset = 0, +}; + +static const ASN1_TEMPLATE RSA_PSS_PARAMS_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(RSA_PSS_PARAMS, hashAlgorithm), + .field_name = "hashAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(RSA_PSS_PARAMS, maskGenAlgorithm), + .field_name = "maskGenAlgorithm", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(RSA_PSS_PARAMS, saltLength), + .field_name = "saltLength", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 3, + .offset = offsetof(RSA_PSS_PARAMS, trailerField), + .field_name = "trailerField", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM RSA_PSS_PARAMS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = RSA_PSS_PARAMS_seq_tt, + .tcount = sizeof(RSA_PSS_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &RSA_PSS_PARAMS_aux, + .size = sizeof(RSA_PSS_PARAMS), + .sname = "RSA_PSS_PARAMS", +}; + +RSA_PSS_PARAMS * +d2i_RSA_PSS_PARAMS(RSA_PSS_PARAMS **a, const unsigned char **in, long len) +{ + return (RSA_PSS_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &RSA_PSS_PARAMS_it); +} +LCRYPTO_ALIAS(d2i_RSA_PSS_PARAMS); + +int +i2d_RSA_PSS_PARAMS(RSA_PSS_PARAMS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSA_PSS_PARAMS_it); +} +LCRYPTO_ALIAS(i2d_RSA_PSS_PARAMS); + +RSA_PSS_PARAMS * +RSA_PSS_PARAMS_new(void) +{ + return (RSA_PSS_PARAMS *)ASN1_item_new(&RSA_PSS_PARAMS_it); +} +LCRYPTO_ALIAS(RSA_PSS_PARAMS_new); + +void +RSA_PSS_PARAMS_free(RSA_PSS_PARAMS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &RSA_PSS_PARAMS_it); +} +LCRYPTO_ALIAS(RSA_PSS_PARAMS_free); + +static int +rsa_oaep_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + /* Free up maskHash */ + if (operation == ASN1_OP_FREE_PRE) { + RSA_OAEP_PARAMS *oaep = (RSA_OAEP_PARAMS *)*pval; + X509_ALGOR_free(oaep->maskHash); + } + return 1; +} + +static const ASN1_AUX RSA_OAEP_PARAMS_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = rsa_oaep_cb, + .enc_offset = 0, +}; + +static const ASN1_TEMPLATE RSA_OAEP_PARAMS_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(RSA_OAEP_PARAMS, hashFunc), + .field_name = "hashFunc", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(RSA_OAEP_PARAMS, maskGenFunc), + .field_name = "maskGenFunc", + .item = &X509_ALGOR_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(RSA_OAEP_PARAMS, pSourceFunc), + .field_name = "pSourceFunc", + .item = &X509_ALGOR_it, + }, +}; + +const ASN1_ITEM RSA_OAEP_PARAMS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = RSA_OAEP_PARAMS_seq_tt, + .tcount = sizeof(RSA_OAEP_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &RSA_OAEP_PARAMS_aux, + .size = sizeof(RSA_OAEP_PARAMS), + .sname = "RSA_OAEP_PARAMS", +}; + + +RSA_OAEP_PARAMS * +d2i_RSA_OAEP_PARAMS(RSA_OAEP_PARAMS **a, const unsigned char **in, long len) +{ + return (RSA_OAEP_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &RSA_OAEP_PARAMS_it); +} +LCRYPTO_ALIAS(d2i_RSA_OAEP_PARAMS); + +int +i2d_RSA_OAEP_PARAMS(RSA_OAEP_PARAMS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSA_OAEP_PARAMS_it); +} +LCRYPTO_ALIAS(i2d_RSA_OAEP_PARAMS); + +RSA_OAEP_PARAMS * +RSA_OAEP_PARAMS_new(void) +{ + return (RSA_OAEP_PARAMS *)ASN1_item_new(&RSA_OAEP_PARAMS_it); +} +LCRYPTO_ALIAS(RSA_OAEP_PARAMS_new); + +void +RSA_OAEP_PARAMS_free(RSA_OAEP_PARAMS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &RSA_OAEP_PARAMS_it); +} +LCRYPTO_ALIAS(RSA_OAEP_PARAMS_free); + +RSA * +d2i_RSAPrivateKey(RSA **a, const unsigned char **in, long len) +{ + return (RSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &RSAPrivateKey_it); +} +LCRYPTO_ALIAS(d2i_RSAPrivateKey); + +int +i2d_RSAPrivateKey(const RSA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSAPrivateKey_it); +} +LCRYPTO_ALIAS(i2d_RSAPrivateKey); + + +RSA * +d2i_RSAPublicKey(RSA **a, const unsigned char **in, long len) +{ + return (RSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &RSAPublicKey_it); +} +LCRYPTO_ALIAS(d2i_RSAPublicKey); + +int +i2d_RSAPublicKey(const RSA *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSAPublicKey_it); +} +LCRYPTO_ALIAS(i2d_RSAPublicKey); + +RSA * +RSAPublicKey_dup(RSA *rsa) +{ + return ASN1_item_dup(&RSAPublicKey_it, rsa); +} +LCRYPTO_ALIAS(RSAPublicKey_dup); + +RSA * +RSAPrivateKey_dup(RSA *rsa) +{ + return ASN1_item_dup(&RSAPrivateKey_it, rsa); +} +LCRYPTO_ALIAS(RSAPrivateKey_dup); diff --git a/Libraries/libressl/crypto/rsa/rsa_blinding.c b/Libraries/libressl/crypto/rsa/rsa_blinding.c new file mode 100644 index 000000000..cac5bd91d --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_blinding.c @@ -0,0 +1,361 @@ +/* $OpenBSD: rsa_blinding.c,v 1.3 2023/08/09 12:09:06 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include + +#include "bn_local.h" +#include "rsa_local.h" + +#define BN_BLINDING_COUNTER 32 + +struct bn_blinding_st { + BIGNUM *A; + BIGNUM *Ai; + BIGNUM *e; + BIGNUM *mod; + pthread_t tid; + int counter; + BN_MONT_CTX *m_ctx; + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +}; + +BN_BLINDING * +BN_BLINDING_new(const BIGNUM *e, const BIGNUM *mod, BN_CTX *ctx, + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx) +{ + BN_BLINDING *ret = NULL; + + if ((ret = calloc(1, sizeof(BN_BLINDING))) == NULL) { + BNerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if ((ret->A = BN_new()) == NULL) + goto err; + if ((ret->Ai = BN_new()) == NULL) + goto err; + if ((ret->e = BN_dup(e)) == NULL) + goto err; + if ((ret->mod = BN_dup(mod)) == NULL) + goto err; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(ret->mod, BN_FLG_CONSTTIME); + + /* Update on first use. */ + ret->counter = BN_BLINDING_COUNTER - 1; + ret->tid = pthread_self(); + + if (bn_mod_exp != NULL) + ret->bn_mod_exp = bn_mod_exp; + if (m_ctx != NULL) + ret->m_ctx = m_ctx; + + return ret; + + err: + BN_BLINDING_free(ret); + + return NULL; +} + +void +BN_BLINDING_free(BN_BLINDING *r) +{ + if (r == NULL) + return; + + BN_free(r->A); + BN_free(r->Ai); + BN_free(r->e); + BN_free(r->mod); + free(r); +} + +static int +BN_BLINDING_setup(BN_BLINDING *b, BN_CTX *ctx) +{ + if (!bn_rand_interval(b->A, 1, b->mod)) + return 0; + if (BN_mod_inverse_ct(b->Ai, b->A, b->mod, ctx) == NULL) + return 0; + + if (b->bn_mod_exp != NULL && b->m_ctx != NULL) { + if (!b->bn_mod_exp(b->A, b->A, b->e, b->mod, ctx, b->m_ctx)) + return 0; + } else { + if (!BN_mod_exp_ct(b->A, b->A, b->e, b->mod, ctx)) + return 0; + } + + return 1; +} + +static int +BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) +{ + int ret = 0; + + if (++b->counter >= BN_BLINDING_COUNTER) { + if (!BN_BLINDING_setup(b, ctx)) + goto err; + b->counter = 0; + } else { + if (!BN_mod_sqr(b->A, b->A, b->mod, ctx)) + goto err; + if (!BN_mod_sqr(b->Ai, b->Ai, b->mod, ctx)) + goto err; + } + + ret = 1; + + err: + return ret; +} + +int +BN_BLINDING_convert(BIGNUM *n, BIGNUM *inv, BN_BLINDING *b, BN_CTX *ctx) +{ + int ret = 0; + + if (!BN_BLINDING_update(b, ctx)) + goto err; + + if (inv != NULL) { + if (!bn_copy(inv, b->Ai)) + goto err; + } + + ret = BN_mod_mul(n, n, b->A, b->mod, ctx); + + err: + return ret; +} + +int +BN_BLINDING_invert(BIGNUM *n, const BIGNUM *inv, BN_BLINDING *b, BN_CTX *ctx) +{ + if (inv == NULL) + inv = b->Ai; + + return BN_mod_mul(n, n, inv, b->mod, ctx); +} + +int +BN_BLINDING_is_local(BN_BLINDING *b) +{ + return pthread_equal(pthread_self(), b->tid) != 0; +} + +static BIGNUM * +rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, const BIGNUM *q, + BN_CTX *ctx) +{ + BIGNUM *ret = NULL, *r0, *r1, *r2; + + if (d == NULL || p == NULL || q == NULL) + return NULL; + + BN_CTX_start(ctx); + if ((r0 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r2 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_sub(r1, p, BN_value_one())) + goto err; + if (!BN_sub(r2, q, BN_value_one())) + goto err; + if (!BN_mul(r0, r1, r2, ctx)) + goto err; + + ret = BN_mod_inverse_ct(NULL, d, r0, ctx); +err: + BN_CTX_end(ctx); + return ret; +} + +BN_BLINDING * +RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) +{ + BIGNUM *e = NULL; + BIGNUM n; + BN_CTX *ctx = NULL; + BN_BLINDING *ret = NULL; + + if ((ctx = in_ctx) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + + if ((e = rsa->e) == NULL) + e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); + if (e == NULL) { + RSAerror(RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + + BN_init(&n); + BN_with_flags(&n, rsa->n, BN_FLG_CONSTTIME); + + if ((ret = BN_BLINDING_new(e, &n, ctx, rsa->meth->bn_mod_exp, + rsa->_method_mod_n)) == NULL) { + RSAerror(ERR_R_BN_LIB); + goto err; + } + + err: + BN_CTX_end(ctx); + if (ctx != in_ctx) + BN_CTX_free(ctx); + if (e != rsa->e) + BN_free(e); + + return ret; +} + +void +RSA_blinding_off(RSA *rsa) +{ + BN_BLINDING_free(rsa->blinding); + rsa->blinding = NULL; + rsa->flags |= RSA_FLAG_NO_BLINDING; +} +LCRYPTO_ALIAS(RSA_blinding_off); + +int +RSA_blinding_on(RSA *rsa, BN_CTX *ctx) +{ + int ret = 0; + + if (rsa->blinding != NULL) + RSA_blinding_off(rsa); + + rsa->blinding = RSA_setup_blinding(rsa, ctx); + if (rsa->blinding == NULL) + goto err; + + rsa->flags &= ~RSA_FLAG_NO_BLINDING; + ret = 1; +err: + return (ret); +} +LCRYPTO_ALIAS(RSA_blinding_on); diff --git a/Libraries/libressl/crypto/rsa/rsa_chk.c b/Libraries/libressl/crypto/rsa/rsa_chk.c new file mode 100644 index 000000000..b7666e0fe --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_chk.c @@ -0,0 +1,223 @@ +/* $OpenBSD: rsa_chk.c,v 1.18 2023/07/08 12:26:45 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +#include "bn_local.h" +#include "rsa_local.h" + +int +RSA_check_key(const RSA *key) +{ + BIGNUM *i, *j, *k, *l, *m; + BN_CTX *ctx; + int r; + int ret = 1; + + if (!key->p || !key->q || !key->n || !key->e || !key->d) { + RSAerror(RSA_R_VALUE_MISSING); + return 0; + } + + i = BN_new(); + j = BN_new(); + k = BN_new(); + l = BN_new(); + m = BN_new(); + ctx = BN_CTX_new(); + if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || + ctx == NULL) { + ret = -1; + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BN_is_one(key->e)) { + ret = 0; + RSAerror(RSA_R_BAD_E_VALUE); + } + if (!BN_is_odd(key->e)) { + ret = 0; + RSAerror(RSA_R_BAD_E_VALUE); + } + + /* p prime? */ + r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL); + if (r != 1) { + ret = r; + if (r != 0) + goto err; + RSAerror(RSA_R_P_NOT_PRIME); + } + + /* q prime? */ + r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL); + if (r != 1) { + ret = r; + if (r != 0) + goto err; + RSAerror(RSA_R_Q_NOT_PRIME); + } + + /* n = p*q? */ + r = BN_mul(i, key->p, key->q, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (BN_cmp(i, key->n) != 0) { + ret = 0; + RSAerror(RSA_R_N_DOES_NOT_EQUAL_P_Q); + } + + /* d*e = 1 mod lcm(p-1,q-1)? */ + + r = BN_sub(i, key->p, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + r = BN_sub(j, key->q, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + + /* now compute k = lcm(i,j) */ + r = BN_mul(l, i, j, ctx); + if (!r) { + ret = -1; + goto err; + } + r = BN_gcd_ct(m, i, j, ctx); + if (!r) { + ret = -1; + goto err; + } + r = BN_div_ct(k, NULL, l, m, ctx); /* remainder is 0 */ + if (!r) { + ret = -1; + goto err; + } + + r = BN_mod_mul(i, key->d, key->e, k, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (!BN_is_one(i)) { + ret = 0; + RSAerror(RSA_R_D_E_NOT_CONGRUENT_TO_1); + } + + if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { + /* dmp1 = d mod (p-1)? */ + r = BN_sub(i, key->p, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + + r = BN_mod_ct(j, key->d, i, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (BN_cmp(j, key->dmp1) != 0) { + ret = 0; + RSAerror(RSA_R_DMP1_NOT_CONGRUENT_TO_D); + } + + /* dmq1 = d mod (q-1)? */ + r = BN_sub(i, key->q, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + + r = BN_mod_ct(j, key->d, i, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (BN_cmp(j, key->dmq1) != 0) { + ret = 0; + RSAerror(RSA_R_DMQ1_NOT_CONGRUENT_TO_D); + } + + /* iqmp = q^-1 mod p? */ + if (BN_mod_inverse_ct(i, key->q, key->p, ctx) == NULL) { + ret = -1; + goto err; + } + + if (BN_cmp(i, key->iqmp) != 0) { + ret = 0; + RSAerror(RSA_R_IQMP_NOT_INVERSE_OF_Q); + } + } + +err: + BN_free(i); + BN_free(j); + BN_free(k); + BN_free(l); + BN_free(m); + BN_CTX_free(ctx); + + return (ret); +} +LCRYPTO_ALIAS(RSA_check_key); diff --git a/Libraries/libressl/crypto/rsa/rsa_eay.c b/Libraries/libressl/crypto/rsa/rsa_eay.c new file mode 100644 index 000000000..c2e1e22f9 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_eay.c @@ -0,0 +1,902 @@ +/* $OpenBSD: rsa_eay.c,v 1.65 2023/08/09 12:09:06 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include + +#include "bn_local.h" +#include "rsa_local.h" + +static int +rsa_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, j, k, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerror(RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerror(RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerror(RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = malloc(num); + + if (f == NULL || ret == NULL || buf == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + break; +#ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); + break; +#endif + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + default: + RSAerror(RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j = BN_num_bytes(ret); + i = BN_bn2bin(ret, &(to[num - j])); + for (k = 0; k < num - i; k++) + to[k] = 0; + + r = num; +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + freezero(buf, num); + return r; +} + +static BN_BLINDING * +rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) +{ + BN_BLINDING *ret; + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_RSA); + + if (rsa->blinding == NULL) { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + + if (rsa->blinding == NULL) + rsa->blinding = RSA_setup_blinding(rsa, ctx); + } + + if ((ret = rsa->blinding) == NULL) + goto err; + + /* + * We need a shared blinding. Accesses require locks and a copy of the + * blinding factor needs to be retained on use. + */ + if ((*local = BN_BLINDING_is_local(ret)) == 0) { + if (rsa->mt_blinding == NULL) { + if (!got_write_lock) { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + } + + if (rsa->mt_blinding == NULL) + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + } + ret = rsa->mt_blinding; + } + + err: + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RSA); + else + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + + return ret; +} + +static int +rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, BN_CTX *ctx) +{ + if (unblind == NULL) + /* + * Local blinding: store the unblinding factor + * in BN_BLINDING. + */ + return BN_BLINDING_convert(f, NULL, b, ctx); + else { + /* + * Shared blinding: store the unblinding factor + * outside BN_BLINDING. + */ + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_convert(f, unblind, b, ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +static int +rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, BN_CTX *ctx) +{ + /* + * For local blinding, unblind is set to NULL, and BN_BLINDING_invert() + * will use the unblinding factor stored in BN_BLINDING. + * If BN_BLINDING is shared between threads, unblind must be non-null: + * BN_BLINDING_invert() will then use the local unblinding factor, + * and will only read the modulus from BN_BLINDING. + * In both cases it's safe to access the blinding without a lock. + */ + return BN_BLINDING_invert(f, unblind, b, ctx); +} + +/* signing */ +static int +rsa_private_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + BIGNUM *f, *ret, *res; + int i, j, k, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = malloc(num); + + if (f == NULL || ret == NULL || buf == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); + break; + case RSA_X931_PADDING: + i = RSA_padding_add_X931(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + default: + RSAerror(RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + (rsa->p != NULL && rsa->q != NULL && rsa->dmp1 != NULL && + rsa->dmq1 != NULL && rsa->iqmp != NULL)) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM d; + + BN_init(&d); + BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(ret, f, &d, rsa->n, ctx, + rsa->_method_mod_n)) { + goto err; + } + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + if (padding == RSA_X931_PADDING) { + if (!BN_sub(f, rsa->n, ret)) + goto err; + if (BN_cmp(ret, f) > 0) + res = f; + else + res = ret; + } else + res = ret; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j = BN_num_bytes(res); + i = BN_bn2bin(res, &(to[num - j])); + for (k = 0; k < num - i; k++) + to[k] = 0; + + r = num; +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + freezero(buf, num); + return r; +} + +static int +rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int j, num = 0, r = -1; + unsigned char *p; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = malloc(num); + + if (!f || !ret || !buf) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) { + RSAerror(RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from, (int)flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerror(ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + /* do the decrypt */ + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + (rsa->p != NULL && rsa->q != NULL && rsa->dmp1 != NULL && + rsa->dmq1 != NULL && rsa->iqmp != NULL)) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM d; + + BN_init(&d); + BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(ret, f, &d, rsa->n, ctx, + rsa->_method_mod_n)) { + goto err; + } + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + p = buf; + j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */ + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); + break; +#ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); + break; +#endif + case RSA_NO_PADDING: + r = RSA_padding_check_none(to, num, buf, j, num); + break; + default: + RSAerror(RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerror(RSA_R_PADDING_CHECK_FAILED); + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + freezero(buf, num); + return r; +} + +/* signature verification */ +static int +rsa_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, num = 0, r = -1; + unsigned char *p; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerror(RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerror(RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerror(RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = malloc(num); + + if (!f || !ret || !buf) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) { + RSAerror(RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from, flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + if (padding == RSA_X931_PADDING && (ret->d[0] & 0xf) != 12) + if (!BN_sub(ret, rsa->n, ret)) + goto err; + + p = buf; + i = BN_bn2bin(ret, p); + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); + break; + case RSA_X931_PADDING: + r = RSA_padding_check_X931(to, num, buf, i, num); + break; + case RSA_NO_PADDING: + r = RSA_padding_check_none(to, num, buf, i, num); + break; + default: + RSAerror(RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerror(RSA_R_PADDING_CHECK_FAILED); + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + freezero(buf, num); + return r; +} + +static int +rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + BIGNUM *r1, *m1, *vrfy; + BIGNUM dmp1, dmq1, c, pr1; + int ret = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + if (r1 == NULL || m1 == NULL || vrfy == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + { + BIGNUM p, q; + + /* + * Make sure BN_mod_inverse in Montgomery initialization uses the + * BN_FLG_CONSTTIME flag + */ + BN_init(&p); + BN_init(&q); + BN_with_flags(&p, rsa->p, BN_FLG_CONSTTIME); + BN_with_flags(&q, rsa->q, BN_FLG_CONSTTIME); + + if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, + CRYPTO_LOCK_RSA, &p, ctx) || + !BN_MONT_CTX_set_locked(&rsa->_method_mod_q, + CRYPTO_LOCK_RSA, &q, ctx)) { + goto err; + } + } + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + + /* compute I mod q */ + BN_init(&c); + BN_with_flags(&c, I, BN_FLG_CONSTTIME); + + if (!BN_mod_ct(r1, &c, rsa->q, ctx)) + goto err; + + /* compute r1^dmq1 mod q */ + BN_init(&dmq1); + BN_with_flags(&dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(m1, r1, &dmq1, rsa->q, ctx, + rsa->_method_mod_q)) + goto err; + + /* compute I mod p */ + BN_init(&c); + BN_with_flags(&c, I, BN_FLG_CONSTTIME); + + if (!BN_mod_ct(r1, &c, rsa->p, ctx)) + goto err; + + /* compute r1^dmp1 mod p */ + BN_init(&dmp1); + BN_with_flags(&dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(r0, r1, &dmp1, rsa->p, ctx, + rsa->_method_mod_p)) + goto err; + + if (!BN_sub(r0, r0, m1)) + goto err; + + /* + * This will help stop the size of r0 increasing, which does + * affect the multiply if it optimised for a power of 2 size + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + + if (!BN_mul(r1, r0, rsa->iqmp, ctx)) + goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + BN_init(&pr1); + BN_with_flags(&pr1, r1, BN_FLG_CONSTTIME); + + if (!BN_mod_ct(r0, &pr1, rsa->p, ctx)) + goto err; + + /* + * If p < q it is occasionally possible for the correction of + * adding 'p' if r0 is negative above to leave the result still + * negative. This can break the private key operations: the following + * second correction should *always* correct this rare occurrence. + * This will *never* happen with OpenSSL generated keys because + * they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + if (!BN_mul(r1, r0, rsa->q, ctx)) + goto err; + if (!BN_add(r0, r1, m1)) + goto err; + + if (rsa->e && rsa->n) { + if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + /* + * If 'I' was greater than (or equal to) rsa->n, the operation + * will be equivalent to using 'I mod n'. However, the result of + * the verify will *always* be less than 'n' so we don't check + * for absolute equality, just congruency. + */ + if (!BN_sub(vrfy, vrfy, I)) + goto err; + if (!BN_mod_ct(vrfy, vrfy, rsa->n, ctx)) + goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) + goto err; + if (!BN_is_zero(vrfy)) { + /* + * 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) + * mod_exp and return that instead. + */ + BIGNUM d; + + BN_init(&d); + BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(r0, I, &d, rsa->n, ctx, + rsa->_method_mod_n)) { + goto err; + } + } + } + ret = 1; +err: + BN_CTX_end(ctx); + return ret; +} + +static int +rsa_init(RSA *rsa) +{ + rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; + return 1; +} + +static int +rsa_finish(RSA *rsa) +{ + BN_MONT_CTX_free(rsa->_method_mod_n); + BN_MONT_CTX_free(rsa->_method_mod_p); + BN_MONT_CTX_free(rsa->_method_mod_q); + + return 1; +} + +static const RSA_METHOD rsa_pkcs1_meth = { + .name = "OpenSSL PKCS#1 RSA", + .rsa_pub_enc = rsa_public_encrypt, + .rsa_pub_dec = rsa_public_decrypt, /* signature verification */ + .rsa_priv_enc = rsa_private_encrypt, /* signing */ + .rsa_priv_dec = rsa_private_decrypt, + .rsa_mod_exp = rsa_mod_exp, + .bn_mod_exp = BN_mod_exp_mont_ct, /* XXX probably we should not use Montgomery if e == 3 */ + .init = rsa_init, + .finish = rsa_finish, +}; + +const RSA_METHOD * +RSA_PKCS1_OpenSSL(void) +{ + return &rsa_pkcs1_meth; +} +LCRYPTO_ALIAS(RSA_PKCS1_OpenSSL); + +const RSA_METHOD * +RSA_PKCS1_SSLeay(void) +{ + return RSA_PKCS1_OpenSSL(); +} +LCRYPTO_ALIAS(RSA_PKCS1_SSLeay); + +int +RSA_bits(const RSA *r) +{ + return BN_num_bits(r->n); +} +LCRYPTO_ALIAS(RSA_bits); + +int +RSA_size(const RSA *r) +{ + return BN_num_bytes(r->n); +} +LCRYPTO_ALIAS(RSA_size); + +int +RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + return rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding); +} +LCRYPTO_ALIAS(RSA_public_encrypt); + +int +RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + return rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding); +} +LCRYPTO_ALIAS(RSA_private_encrypt); + +int +RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + return rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding); +} +LCRYPTO_ALIAS(RSA_private_decrypt); + +int +RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + return rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding); +} +LCRYPTO_ALIAS(RSA_public_decrypt); + +int +RSA_flags(const RSA *r) +{ + return r == NULL ? 0 : r->meth->flags; +} +LCRYPTO_ALIAS(RSA_flags); diff --git a/Libraries/libressl/crypto/rsa/rsa_err.c b/Libraries/libressl/crypto/rsa/rsa_err.c new file mode 100644 index 000000000..8b5416890 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_err.c @@ -0,0 +1,158 @@ +/* $OpenBSD: rsa_err.c,v 1.22 2023/07/08 12:26:45 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason) + +static ERR_STRING_DATA RSA_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA RSA_str_reasons[] = { + {ERR_REASON(RSA_R_ALGORITHM_MISMATCH) , "algorithm mismatch"}, + {ERR_REASON(RSA_R_BAD_E_VALUE) , "bad e value"}, + {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"}, + {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT) , "bad pad byte count"}, + {ERR_REASON(RSA_R_BAD_SIGNATURE) , "bad signature"}, + {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01) , "block type is not 01"}, + {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02) , "block type is not 02"}, + {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN), "data greater than mod len"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE) , "data too large"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), "data too large for key size"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), "data too large for modulus"}, + {ERR_REASON(RSA_R_DATA_TOO_SMALL) , "data too small"}, + {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), "data too small for key size"}, + {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH) , "digest does not match"}, + {ERR_REASON(RSA_R_DIGEST_NOT_ALLOWED) , "digest not allowed"}, + {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), "digest too big for rsa key"}, + {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"}, + {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"}, + {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"}, + {ERR_REASON(RSA_R_FIRST_OCTET_INVALID) , "first octet invalid"}, + {ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "illegal or unsupported padding mode"}, + {ERR_REASON(RSA_R_INVALID_DIGEST) , "invalid digest"}, + {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) , "invalid digest length"}, + {ERR_REASON(RSA_R_INVALID_HEADER) , "invalid header"}, + {ERR_REASON(RSA_R_INVALID_LABEL) , "invalid label"}, + {ERR_REASON(RSA_R_INVALID_KEYBITS) , "invalid keybits"}, + {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"}, + {ERR_REASON(RSA_R_INVALID_MGF1_MD) , "invalid mgf1 md"}, + {ERR_REASON(RSA_R_INVALID_OAEP_PARAMETERS), "invalid oaep parameters"}, + {ERR_REASON(RSA_R_INVALID_PADDING) , "invalid padding"}, + {ERR_REASON(RSA_R_INVALID_PADDING_MODE) , "invalid padding mode"}, + {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"}, + {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN) , "invalid pss saltlen"}, + {ERR_REASON(RSA_R_INVALID_SALT_LENGTH) , "invalid salt length"}, + {ERR_REASON(RSA_R_INVALID_TRAILER) , "invalid trailer"}, + {ERR_REASON(RSA_R_INVALID_X931_DIGEST) , "invalid x931 digest"}, + {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) , "iqmp not inverse of q"}, + {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) , "key size too small"}, + {ERR_REASON(RSA_R_LAST_OCTET_INVALID) , "last octet invalid"}, + {ERR_REASON(RSA_R_MGF1_DIGEST_NOT_ALLOWED), "mgf1 digest not allowed"}, + {ERR_REASON(RSA_R_MODULUS_TOO_LARGE) , "modulus too large"}, + {ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD) , "non fips rsa method"}, + {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) , "no public exponent"}, + {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING), "null before block missing"}, + {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) , "n does not equal p q"}, + {ERR_REASON(RSA_R_OAEP_DECODING_ERROR) , "oaep decoding error"}, + {ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), "operation not allowed in fips mode"}, + {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, + {ERR_REASON(RSA_R_PADDING_CHECK_FAILED) , "padding check failed"}, + {ERR_REASON(RSA_R_PSS_SALTLEN_TOO_SMALL) , "pss saltlen too small"}, + {ERR_REASON(RSA_R_P_NOT_PRIME) , "p not prime"}, + {ERR_REASON(RSA_R_Q_NOT_PRIME) , "q not prime"}, + {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), "rsa operations not supported"}, + {ERR_REASON(RSA_R_SLEN_CHECK_FAILED) , "salt length check failed"}, + {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED) , "salt length recovery failed"}, + {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) , "sslv3 rollback attack"}, + {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), "the asn1 object identifier is not known for this md"}, + {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"}, + {ERR_REASON(RSA_R_UNKNOWN_DIGEST) , "unknown digest"}, + {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST) , "unknown mask digest"}, + {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) , "unknown padding type"}, + {ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST) , "unknown pss digest"}, + {ERR_REASON(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE), "unsupported encryption type"}, + {ERR_REASON(RSA_R_UNSUPPORTED_LABEL_SOURCE), "unsupported label source"}, + {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM), "unsupported mask algorithm"}, + {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER), "unsupported mask parameter"}, + {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE), "unsupported signature type"}, + {ERR_REASON(RSA_R_VALUE_MISSING) , "value missing"}, + {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {0, NULL} +}; + +#endif + +void +ERR_load_RSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, RSA_str_functs); + ERR_load_strings(0, RSA_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_RSA_strings); diff --git a/Libraries/libressl/crypto/rsa/rsa_gen.c b/Libraries/libressl/crypto/rsa/rsa_gen.c new file mode 100644 index 000000000..ff64eb2f0 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_gen.c @@ -0,0 +1,257 @@ +/* $OpenBSD: rsa_gen.c,v 1.30 2023/07/08 12:26:45 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include + +#include "bn_local.h" +#include "rsa_local.h" + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); + +int +RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) +{ + if (rsa->meth->rsa_keygen) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); + return rsa_builtin_keygen(rsa, bits, e_value, cb); +} +LCRYPTO_ALIAS(RSA_generate_key_ex); + +static int +rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) +{ + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; + BIGNUM pr0, d, p; + int bitsp, bitsq, ok = -1, n = 0; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + if ((r0 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r2 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r3 = BN_CTX_get(ctx)) == NULL) + goto err; + + bitsp = (bits + 1) / 2; + bitsq = bits - bitsp; + + /* We need the RSA components non-NULL */ + if (!rsa->n && ((rsa->n = BN_new()) == NULL)) + goto err; + if (!rsa->d && ((rsa->d = BN_new()) == NULL)) + goto err; + if (!rsa->e && ((rsa->e = BN_new()) == NULL)) + goto err; + if (!rsa->p && ((rsa->p = BN_new()) == NULL)) + goto err; + if (!rsa->q && ((rsa->q = BN_new()) == NULL)) + goto err; + if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) + goto err; + if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) + goto err; + if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) + goto err; + + if (!bn_copy(rsa->e, e_value)) + goto err; + + /* generate p and q */ + for (;;) { + if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2, rsa->p, BN_value_one())) + goto err; + if (!BN_gcd_ct(r1, r2, rsa->e, ctx)) + goto err; + if (BN_is_one(r1)) + break; + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) { + /* + * When generating ridiculously small keys, we can get stuck + * continually regenerating the same prime values. Check for + * this and bail if it happens 3 times. + */ + unsigned int degenerate = 0; + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, + cb)) + goto err; + } while (BN_cmp(rsa->p, rsa->q) == 0 && + ++degenerate < 3); + if (degenerate == 3) { + ok = 0; /* we set our own err */ + RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; + if (!BN_gcd_ct(r1, r2, rsa->e, ctx)) + goto err; + if (BN_is_one(r1)) + break; + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + if (BN_cmp(rsa->p, rsa->q) < 0) { + tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + /* calculate n */ + if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1, rsa->p, BN_value_one())) /* p-1 */ + goto err; + if (!BN_sub(r2, rsa->q, BN_value_one())) /* q-1 */ + goto err; + if (!BN_mul(r0, r1, r2, ctx)) /* (p-1)(q-1) */ + goto err; + + BN_init(&pr0); + BN_with_flags(&pr0, r0, BN_FLG_CONSTTIME); + + if (BN_mod_inverse_ct(rsa->d, rsa->e, &pr0, ctx) == NULL) /* d */ + goto err; + + /* set up d for correct BN_FLG_CONSTTIME flag */ + BN_init(&d); + BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); + + /* calculate d mod (p-1) */ + if (!BN_mod_ct(rsa->dmp1, &d, r1, ctx)) + goto err; + + /* calculate d mod (q-1) */ + if (!BN_mod_ct(rsa->dmq1, &d, r2, ctx)) + goto err; + + /* calculate inverse of q mod p */ + BN_init(&p); + BN_with_flags(&p, rsa->p, BN_FLG_CONSTTIME); + if (BN_mod_inverse_ct(rsa->iqmp, rsa->q, &p, ctx) == NULL) + goto err; + + ok = 1; +err: + if (ok == -1) { + RSAerror(ERR_LIB_BN); + ok = 0; + } + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ok; +} + +RSA * +RSA_generate_key(int bits, unsigned long e_value, + void (*callback)(int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + int i; + RSA *rsa = RSA_new(); + BIGNUM *e = BN_new(); + + if (!rsa || !e) + goto err; + + /* The problem is when building with 8, 16, or 32 BN_ULONG, + * unsigned long can be larger */ + for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) { + if (e_value & (1UL << i)) + if (BN_set_bit(e, i) == 0) + goto err; + } + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (RSA_generate_key_ex(rsa, bits, e, &cb)) { + BN_free(e); + return rsa; + } +err: + BN_free(e); + RSA_free(rsa); + + return 0; +} +LCRYPTO_ALIAS(RSA_generate_key); diff --git a/Libraries/libressl/crypto/rsa/rsa_lib.c b/Libraries/libressl/crypto/rsa/rsa_lib.c new file mode 100644 index 000000000..fbd2c2274 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_lib.c @@ -0,0 +1,460 @@ +/* $OpenBSD: rsa_lib.c,v 1.48 2023/07/28 10:05:16 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "evp_local.h" +#include "rsa_local.h" + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +static const RSA_METHOD *default_RSA_meth = NULL; + +RSA * +RSA_new(void) +{ + RSA *r = RSA_new_method(NULL); + + return r; +} +LCRYPTO_ALIAS(RSA_new); + +void +RSA_set_default_method(const RSA_METHOD *meth) +{ + default_RSA_meth = meth; +} +LCRYPTO_ALIAS(RSA_set_default_method); + +const RSA_METHOD * +RSA_get_default_method(void) +{ + if (default_RSA_meth == NULL) + default_RSA_meth = RSA_PKCS1_SSLeay(); + + return default_RSA_meth; +} +LCRYPTO_ALIAS(RSA_get_default_method); + +const RSA_METHOD * +RSA_get_method(const RSA *rsa) +{ + return rsa->meth; +} +LCRYPTO_ALIAS(RSA_get_method); + +int +RSA_set_method(RSA *rsa, const RSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const RSA_METHOD *mtmp; + + mtmp = rsa->meth; + if (mtmp->finish) + mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(rsa->engine); + rsa->engine = NULL; +#endif + rsa->meth = meth; + if (meth->init) + meth->init(rsa); + return 1; +} +LCRYPTO_ALIAS(RSA_set_method); + +RSA * +RSA_new_method(ENGINE *engine) +{ + RSA *ret; + + if ((ret = calloc(1, sizeof(RSA))) == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = RSA_get_default_method(); + +#ifndef OPENSSL_NO_ENGINE + if (engine != NULL) { + if (!ENGINE_init(engine)) { + RSAerror(ERR_R_ENGINE_LIB); + goto err; + } + ret->engine = engine; + } else { + ret->engine = ENGINE_get_default_RSA(); + } + + if (ret->engine != NULL) { + if ((ret->meth = ENGINE_get_RSA(ret->engine)) == NULL) { + RSAerror(ERR_R_ENGINE_LIB); + goto err; + } + } +#endif + + ret->references = 1; + ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) + goto err; + + if (ret->meth->init != NULL && !ret->meth->init(ret)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); + goto err; + } + + return ret; + + err: +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(ret->engine); +#endif + free(ret); + + return NULL; +} +LCRYPTO_ALIAS(RSA_new_method); + +void +RSA_free(RSA *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA); + if (i > 0) + return; + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); + + BN_free(r->n); + BN_free(r->e); + BN_free(r->d); + BN_free(r->p); + BN_free(r->q); + BN_free(r->dmp1); + BN_free(r->dmq1); + BN_free(r->iqmp); + BN_BLINDING_free(r->blinding); + BN_BLINDING_free(r->mt_blinding); + RSA_PSS_PARAMS_free(r->pss); + free(r); +} +LCRYPTO_ALIAS(RSA_free); + +int +RSA_up_ref(RSA *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); + return i > 1 ? 1 : 0; +} +LCRYPTO_ALIAS(RSA_up_ref); + +int +RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, + new_func, dup_func, free_func); +} +LCRYPTO_ALIAS(RSA_get_ex_new_index); + +int +RSA_set_ex_data(RSA *r, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&r->ex_data, idx, arg); +} +LCRYPTO_ALIAS(RSA_set_ex_data); + +void * +RSA_get_ex_data(const RSA *r, int idx) +{ + return CRYPTO_get_ex_data(&r->ex_data, idx); +} +LCRYPTO_ALIAS(RSA_get_ex_data); + +int +RSA_security_bits(const RSA *rsa) +{ + return BN_security_bits(RSA_bits(rsa), -1); +} +LCRYPTO_ALIAS(RSA_security_bits); + +void +RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} +LCRYPTO_ALIAS(RSA_get0_key); + +int +RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) + return 0; + + if (n != NULL) { + BN_free(r->n); + r->n = n; + } + if (e != NULL) { + BN_free(r->e); + r->e = e; + } + if (d != NULL) { + BN_free(r->d); + r->d = d; + } + + return 1; +} +LCRYPTO_ALIAS(RSA_set0_key); + +void +RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} +LCRYPTO_ALIAS(RSA_get0_crt_params); + +int +RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + if ((r->dmp1 == NULL && dmp1 == NULL) || + (r->dmq1 == NULL && dmq1 == NULL) || + (r->iqmp == NULL && iqmp == NULL)) + return 0; + + if (dmp1 != NULL) { + BN_free(r->dmp1); + r->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(r->dmq1); + r->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(r->iqmp); + r->iqmp = iqmp; + } + + return 1; +} +LCRYPTO_ALIAS(RSA_set0_crt_params); + +void +RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} +LCRYPTO_ALIAS(RSA_get0_factors); + +int +RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) + return 0; + + if (p != NULL) { + BN_free(r->p); + r->p = p; + } + if (q != NULL) { + BN_free(r->q); + r->q = q; + } + + return 1; +} +LCRYPTO_ALIAS(RSA_set0_factors); + +const BIGNUM * +RSA_get0_n(const RSA *r) +{ + return r->n; +} +LCRYPTO_ALIAS(RSA_get0_n); + +const BIGNUM * +RSA_get0_e(const RSA *r) +{ + return r->e; +} +LCRYPTO_ALIAS(RSA_get0_e); + +const BIGNUM * +RSA_get0_d(const RSA *r) +{ + return r->d; +} +LCRYPTO_ALIAS(RSA_get0_d); + +const BIGNUM * +RSA_get0_p(const RSA *r) +{ + return r->p; +} +LCRYPTO_ALIAS(RSA_get0_p); + +const BIGNUM * +RSA_get0_q(const RSA *r) +{ + return r->q; +} +LCRYPTO_ALIAS(RSA_get0_q); + +const BIGNUM * +RSA_get0_dmp1(const RSA *r) +{ + return r->dmp1; +} +LCRYPTO_ALIAS(RSA_get0_dmp1); + +const BIGNUM * +RSA_get0_dmq1(const RSA *r) +{ + return r->dmq1; +} +LCRYPTO_ALIAS(RSA_get0_dmq1); + +const BIGNUM * +RSA_get0_iqmp(const RSA *r) +{ + return r->iqmp; +} +LCRYPTO_ALIAS(RSA_get0_iqmp); + +const RSA_PSS_PARAMS * +RSA_get0_pss_params(const RSA *r) +{ + return r->pss; +} +LCRYPTO_ALIAS(RSA_get0_pss_params); + +void +RSA_clear_flags(RSA *r, int flags) +{ + r->flags &= ~flags; +} +LCRYPTO_ALIAS(RSA_clear_flags); + +int +RSA_test_flags(const RSA *r, int flags) +{ + return r->flags & flags; +} +LCRYPTO_ALIAS(RSA_test_flags); + +void +RSA_set_flags(RSA *r, int flags) +{ + r->flags |= flags; +} +LCRYPTO_ALIAS(RSA_set_flags); + +int +RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) +{ + /* Return an error if the key type is not RSA or RSA-PSS. */ + if (ctx != NULL && ctx->pmeth != NULL && + ctx->pmeth->pkey_id != EVP_PKEY_RSA && + ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); +} +LCRYPTO_ALIAS(RSA_pkey_ctx_ctrl); diff --git a/Libraries/libressl/crypto/rsa/rsa_local.h b/Libraries/libressl/crypto/rsa/rsa_local.h new file mode 100644 index 000000000..51ed92590 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_local.h @@ -0,0 +1,165 @@ +/* $OpenBSD: rsa_local.h,v 1.6 2023/08/09 12:09:06 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +__BEGIN_HIDDEN_DECLS + +#define RSA_MIN_MODULUS_BITS 512 + +/* Macros to test if a pkey or ctx is for a PSS key */ +#define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) +#define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) + +struct rsa_meth_st { + char *name; + int (*rsa_pub_enc)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_pub_dec)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_enc)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_dec)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_mod_exp)(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); /* Can be null */ + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); /* Can be null */ + int (*init)(RSA *rsa); /* called at new */ + int (*finish)(RSA *rsa); /* called at free */ + int flags; /* RSA_METHOD_FLAG_* things */ + char *app_data; /* may be needed! */ +/* New sign and verify functions: some libraries don't allow arbitrary data + * to be signed/verified: this allows them to be used. Note: for this to work + * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used + * RSA_sign(), RSA_verify() should be used instead. Note: for backwards + * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER + * option is set in 'flags'. + */ + int (*rsa_sign)(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa); + int (*rsa_verify)(int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); +/* If this callback is NULL, the builtin software RSA key-gen will be used. This + * is for behavioural compatibility whilst the code gets rewired, but one day + * it would be nice to assume there are no such things as "builtin software" + * implementations. */ + int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +}; + +struct rsa_st { + /* The first parameter is used to pickup errors where + * this is passed instead of aEVP_PKEY, it is set to 0 */ + int pad; + long version; + const RSA_METHOD *meth; + + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + + /* Parameter restrictions for PSS only keys. */ + RSA_PSS_PARAMS *pss; + + /* be careful using this if the RSA structure is shared */ + CRYPTO_EX_DATA ex_data; + int references; + int flags; + + /* Used to cache montgomery values */ + BN_MONT_CTX *_method_mod_n; + BN_MONT_CTX *_method_mod_p; + BN_MONT_CTX *_method_mod_q; + + /* all BIGNUM values are actually in the following data, if it is not + * NULL */ + BN_BLINDING *blinding; + BN_BLINDING *mt_blinding; +}; + +RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, + int saltlen); +int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, + const EVP_MD **pmgf1md, int *psaltlen); + +extern int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, RSA *rsa); + +int RSA_padding_add_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *e, const BIGNUM *mod, BN_CTX *ctx, + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_convert(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_is_local(BN_BLINDING *b); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/rsa/rsa_meth.c b/Libraries/libressl/crypto/rsa/rsa_meth.c new file mode 100644 index 000000000..71608caa0 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_meth.c @@ -0,0 +1,309 @@ +/* $OpenBSD: rsa_meth.c,v 1.7 2023/07/08 12:26:45 beck Exp $ */ +/* + * Copyright (c) 2018 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "rsa_local.h" + +RSA_METHOD * +RSA_meth_new(const char *name, int flags) +{ + RSA_METHOD *meth; + + if ((meth = calloc(1, sizeof(*meth))) == NULL) + return NULL; + if ((meth->name = strdup(name)) == NULL) { + free(meth); + return NULL; + } + meth->flags = flags; + + return meth; +} +LCRYPTO_ALIAS(RSA_meth_new); + +void +RSA_meth_free(RSA_METHOD *meth) +{ + if (meth == NULL) + return; + + free(meth->name); + free(meth); +} +LCRYPTO_ALIAS(RSA_meth_free); + +RSA_METHOD * +RSA_meth_dup(const RSA_METHOD *meth) +{ + RSA_METHOD *copy; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) + return NULL; + memcpy(copy, meth, sizeof(*copy)); + if ((copy->name = strdup(meth->name)) == NULL) { + free(copy); + return NULL; + } + + return copy; +} +LCRYPTO_ALIAS(RSA_meth_dup); + +int +RSA_meth_set1_name(RSA_METHOD *meth, const char *name) +{ + char *new_name; + + if ((new_name = strdup(name)) == NULL) + return 0; + free(meth->name); + meth->name = new_name; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set1_name); + +int +(*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa) +{ + return meth->finish; +} +LCRYPTO_ALIAS(RSA_meth_get_finish); + +int +RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_priv_enc = priv_enc; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_priv_enc); + +int +RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_priv_dec = priv_dec; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_priv_dec); + +int +RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa)) +{ + meth->finish = finish; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_finish); + +int +RSA_meth_set_pub_enc(RSA_METHOD *meth, int (*pub_enc)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_pub_enc = pub_enc; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_pub_enc); + +int +RSA_meth_set_pub_dec(RSA_METHOD *meth, int (*pub_dec)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_pub_dec = pub_dec; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_pub_dec); + +int +RSA_meth_set_mod_exp(RSA_METHOD *meth, int (*mod_exp)(BIGNUM *r0, + const BIGNUM *i, RSA *rsa, BN_CTX *ctx)) +{ + meth->rsa_mod_exp = mod_exp; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_mod_exp); + +int +RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, int (*bn_mod_exp)(BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx)) +{ + meth->bn_mod_exp = bn_mod_exp; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_bn_mod_exp); + +int +RSA_meth_set_init(RSA_METHOD *meth, int (*init)(RSA *rsa)) +{ + meth->init = init; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_init); + +int +RSA_meth_set_keygen(RSA_METHOD *meth, int (*keygen)(RSA *rsa, int bits, + BIGNUM *e, BN_GENCB *cb)) +{ + meth->rsa_keygen = keygen; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_keygen); + +int +RSA_meth_set_flags(RSA_METHOD *meth, int flags) +{ + meth->flags = flags; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_flags); + +int +RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) +{ + meth->app_data = app_data; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set0_app_data); + +const char * +RSA_meth_get0_name(const RSA_METHOD *meth) +{ + return meth->name; +} +LCRYPTO_ALIAS(RSA_meth_get0_name); + +int +(*RSA_meth_get_pub_enc(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_pub_enc; +} +LCRYPTO_ALIAS(RSA_meth_get_pub_enc); + +int +(*RSA_meth_get_pub_dec(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_pub_dec; +} +LCRYPTO_ALIAS(RSA_meth_get_pub_dec); + +int +(*RSA_meth_get_priv_enc(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_priv_enc; +} +LCRYPTO_ALIAS(RSA_meth_get_priv_enc); + +int +(*RSA_meth_get_priv_dec(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_priv_dec; +} +LCRYPTO_ALIAS(RSA_meth_get_priv_dec); + +int +(*RSA_meth_get_mod_exp(const RSA_METHOD *meth))(BIGNUM *r0, const BIGNUM *i, + RSA *rsa, BN_CTX *ctx) +{ + return meth->rsa_mod_exp; +} +LCRYPTO_ALIAS(RSA_meth_get_mod_exp); + +int +(*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))(BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return meth->bn_mod_exp; +} +LCRYPTO_ALIAS(RSA_meth_get_bn_mod_exp); + +int +(*RSA_meth_get_init(const RSA_METHOD *meth))(RSA *rsa) +{ + return meth->init; +} +LCRYPTO_ALIAS(RSA_meth_get_init); + +int +(*RSA_meth_get_keygen(const RSA_METHOD *meth))(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb) +{ + return meth->rsa_keygen; +} +LCRYPTO_ALIAS(RSA_meth_get_keygen); + +int +RSA_meth_get_flags(const RSA_METHOD *meth) +{ + return meth->flags; +} +LCRYPTO_ALIAS(RSA_meth_get_flags); + +void * +RSA_meth_get0_app_data(const RSA_METHOD *meth) +{ + return meth->app_data; +} +LCRYPTO_ALIAS(RSA_meth_get0_app_data); + +int +(*RSA_meth_get_sign(const RSA_METHOD *meth))(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa) +{ + return meth->rsa_sign; +} +LCRYPTO_ALIAS(RSA_meth_get_sign); + +int +RSA_meth_set_sign(RSA_METHOD *meth, int (*sign)(int type, + const unsigned char *m, unsigned int m_length, unsigned char *sigret, + unsigned int *siglen, const RSA *rsa)) +{ + meth->rsa_sign = sign; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_sign); + +int +(*RSA_meth_get_verify(const RSA_METHOD *meth))(int dtype, + const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa) +{ + return meth->rsa_verify; +} +LCRYPTO_ALIAS(RSA_meth_get_verify); + +int +RSA_meth_set_verify(RSA_METHOD *meth, int (*verify)(int dtype, + const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)) +{ + meth->rsa_verify = verify; + return 1; +} +LCRYPTO_ALIAS(RSA_meth_set_verify); diff --git a/Libraries/libressl/crypto/rsa/rsa_none.c b/Libraries/libressl/crypto/rsa/rsa_none.c new file mode 100644 index 000000000..9c53dcf59 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_none.c @@ -0,0 +1,98 @@ +/* $OpenBSD: rsa_none.c,v 1.12 2023/07/08 12:26:45 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include + +int +RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *from, + int flen) +{ + if (flen > tlen) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (flen < tlen) { + RSAerror(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); + return 0; + } + + memcpy(to, from, flen); + return 1; +} +LCRYPTO_ALIAS(RSA_padding_add_none); + +int +RSA_padding_check_none(unsigned char *to, int tlen, const unsigned char *from, + int flen, int num) +{ + if (flen > tlen) { + RSAerror(RSA_R_DATA_TOO_LARGE); + return -1; + } + + memset(to, 0, tlen - flen); + memcpy(to + tlen - flen, from, flen); + return tlen; +} +LCRYPTO_ALIAS(RSA_padding_check_none); diff --git a/Libraries/libressl/crypto/rsa/rsa_oaep.c b/Libraries/libressl/crypto/rsa/rsa_oaep.c new file mode 100644 index 000000000..c2c3a61da --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_oaep.c @@ -0,0 +1,363 @@ +/* $OpenBSD: rsa_oaep.c,v 1.37 2023/07/08 12:26:45 beck Exp $ */ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ + +/* See Victor Shoup, "OAEP reconsidered," Nov. 2000, + * + * for problems with the security proof for the + * original OAEP scheme, which EME-OAEP is based on. + * + * A new proof can be found in E. Fujisaki, T. Okamoto, + * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!", + * Dec. 2000, . + * The new proof has stronger requirements for the + * underlying permutation: "partial-one-wayness" instead + * of one-wayness. For the RSA function, this is + * an equivalent notion. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "constant_time.h" +#include "evp_local.h" +#include "rsa_local.h" + +int +RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, const unsigned char *param, int plen) +{ + return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, param, + plen, NULL, NULL); +} +LCRYPTO_ALIAS(RSA_padding_add_PKCS1_OAEP); + +int +RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md) +{ + int i, emlen = tlen - 1; + unsigned char *db, *seed; + unsigned char *dbmask = NULL; + unsigned char seedmask[EVP_MAX_MD_SIZE]; + int mdlen, dbmask_len = 0; + int rv = 0; + + if (md == NULL) + md = EVP_sha1(); + if (mgf1md == NULL) + mgf1md = md; + + if ((mdlen = EVP_MD_size(md)) <= 0) + goto err; + + if (flen > emlen - 2 * mdlen - 1) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + + if (emlen < 2 * mdlen + 1) { + RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + to[0] = 0; + seed = to + 1; + db = to + mdlen + 1; + + if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) + goto err; + + memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); + db[emlen - flen - mdlen - 1] = 0x01; + memcpy(db + emlen - flen - mdlen, from, flen); + arc4random_buf(seed, mdlen); + + dbmask_len = emlen - mdlen; + if ((dbmask = malloc(dbmask_len)) == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) + goto err; + for (i = 0; i < dbmask_len; i++) + db[i] ^= dbmask[i]; + if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) + goto err; + for (i = 0; i < mdlen; i++) + seed[i] ^= seedmask[i]; + + rv = 1; + + err: + explicit_bzero(seedmask, sizeof(seedmask)); + freezero(dbmask, dbmask_len); + + return rv; +} +LCRYPTO_ALIAS(RSA_padding_add_PKCS1_OAEP_mgf1); + +int +RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num, const unsigned char *param, + int plen) +{ + return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, + param, plen, NULL, NULL); +} +LCRYPTO_ALIAS(RSA_padding_check_PKCS1_OAEP); + +int +RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num, const unsigned char *param, + int plen, const EVP_MD *md, const EVP_MD *mgf1md) +{ + int i, dblen = 0, mlen = -1, one_index = 0, msg_index; + unsigned int good = 0, found_one_byte, mask; + const unsigned char *maskedseed, *maskeddb; + unsigned char seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE]; + unsigned char *db = NULL, *em = NULL; + int mdlen; + + if (md == NULL) + md = EVP_sha1(); + if (mgf1md == NULL) + mgf1md = md; + + if ((mdlen = EVP_MD_size(md)) <= 0) + return -1; + + if (tlen <= 0 || flen <= 0) + return -1; + + /* + * |num| is the length of the modulus; |flen| is the length of the + * encoded message. Therefore, for any |from| that was obtained by + * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, + * |num| >= 2 * |mdlen| + 2 must hold for the modulus irrespective + * of the ciphertext, see PKCS #1 v2.2, section 7.1.2. + * This does not leak any side-channel information. + */ + if (num < flen || num < 2 * mdlen + 2) { + RSAerror(RSA_R_OAEP_DECODING_ERROR); + return -1; + } + + dblen = num - mdlen - 1; + if ((db = malloc(dblen)) == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto cleanup; + } + if ((em = malloc(num)) == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto cleanup; + } + + /* + * Caller is encouraged to pass zero-padded message created with + * BN_bn2binpad. Trouble is that since we can't read out of |from|'s + * bounds, it's impossible to have an invariant memory access pattern + * in case |from| was not zero-padded in advance. + */ + for (from += flen, em += num, i = 0; i < num; i++) { + mask = ~constant_time_is_zero(flen); + flen -= 1 & mask; + from -= 1 & mask; + *--em = *from & mask; + } + + /* + * The first byte must be zero, however we must not leak if this is + * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA + * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). + */ + good = constant_time_is_zero(em[0]); + + maskedseed = em + 1; + maskeddb = em + 1 + mdlen; + + if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) + goto cleanup; + for (i = 0; i < mdlen; i++) + seed[i] ^= maskedseed[i]; + + if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) + goto cleanup; + for (i = 0; i < dblen; i++) + db[i] ^= maskeddb[i]; + + if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) + goto cleanup; + + good &= constant_time_is_zero(timingsafe_memcmp(db, phash, mdlen)); + + found_one_byte = 0; + for (i = mdlen; i < dblen; i++) { + /* + * Padding consists of a number of 0-bytes, followed by a 1. + */ + unsigned int equals1 = constant_time_eq(db[i], 1); + unsigned int equals0 = constant_time_is_zero(db[i]); + + one_index = constant_time_select_int(~found_one_byte & equals1, + i, one_index); + found_one_byte |= equals1; + good &= (found_one_byte | equals0); + } + + good &= found_one_byte; + + /* + * At this point |good| is zero unless the plaintext was valid, + * so plaintext-awareness ensures timing side-channels are no longer a + * concern. + */ + msg_index = one_index + 1; + mlen = dblen - msg_index; + + /* + * For good measure, do this check in constant time as well. + */ + good &= constant_time_ge(tlen, mlen); + + /* + * Even though we can't fake result's length, we can pretend copying + * |tlen| bytes where |mlen| bytes would be real. The last |tlen| of + * |dblen| bytes are viewed as a circular buffer starting at |tlen|-|mlen'|, + * where |mlen'| is the "saturated" |mlen| value. Deducing information + * about failure or |mlen| would require an attacker to observe + * memory access patterns with byte granularity *as it occurs*. It + * should be noted that failure is indistinguishable from normal + * operation if |tlen| is fixed by protocol. + */ + tlen = constant_time_select_int(constant_time_lt(dblen - mdlen - 1, tlen), + dblen - mdlen - 1, tlen); + msg_index = constant_time_select_int(good, msg_index, dblen - tlen); + mlen = dblen - msg_index; + for (mask = good, i = 0; i < tlen; i++) { + unsigned int equals = constant_time_eq(msg_index, dblen); + + msg_index -= tlen & equals; /* rewind at EOF */ + mask &= ~equals; /* mask = 0 at EOF */ + to[i] = constant_time_select_8(mask, db[msg_index++], to[i]); + } + + /* + * To avoid chosen ciphertext attacks, the error message should not + * reveal which kind of decoding error happened. + */ + RSAerror(RSA_R_OAEP_DECODING_ERROR); + err_clear_last_constant_time(1 & good); + + cleanup: + explicit_bzero(seed, sizeof(seed)); + freezero(db, dblen); + freezero(em, num); + + return constant_time_select_int(good, mlen, -1); +} +LCRYPTO_ALIAS(RSA_padding_check_PKCS1_OAEP_mgf1); + +int +PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst) +{ + long i, outlen = 0; + unsigned char cnt[4]; + EVP_MD_CTX c; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdlen; + int rv = -1; + + EVP_MD_CTX_init(&c); + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + goto err; + for (i = 0; outlen < len; i++) { + cnt[0] = (unsigned char)((i >> 24) & 255); + cnt[1] = (unsigned char)((i >> 16) & 255); + cnt[2] = (unsigned char)((i >> 8)) & 255; + cnt[3] = (unsigned char)(i & 255); + if (!EVP_DigestInit_ex(&c, dgst, NULL) || + !EVP_DigestUpdate(&c, seed, seedlen) || + !EVP_DigestUpdate(&c, cnt, 4)) + goto err; + if (outlen + mdlen <= len) { + if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL)) + goto err; + outlen += mdlen; + } else { + if (!EVP_DigestFinal_ex(&c, md, NULL)) + goto err; + memcpy(mask + outlen, md, len - outlen); + outlen = len; + } + } + rv = 0; + err: + EVP_MD_CTX_cleanup(&c); + return rv; +} +LCRYPTO_ALIAS(PKCS1_MGF1); diff --git a/Libraries/libressl/crypto/rsa/rsa_pk1.c b/Libraries/libressl/crypto/rsa/rsa_pk1.c new file mode 100644 index 000000000..38f7c0be0 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_pk1.c @@ -0,0 +1,217 @@ +/* $OpenBSD: rsa_pk1.c,v 1.16 2023/07/08 12:26:45 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include +#include + +int +RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 1; /* Private Key BT (Block Type) */ + + /* pad out with 0xff data */ + j = tlen - 3 - flen; + memset(p, 0xff, j); + p += j; + *(p++) = '\0'; + memcpy(p, from, flen); + + return 1; +} +LCRYPTO_ALIAS(RSA_padding_add_PKCS1_type_1); + +int +RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i, j; + const unsigned char *p; + + p = from; + if (num != flen + 1 || *(p++) != 01) { + RSAerror(RSA_R_BLOCK_TYPE_IS_NOT_01); + return -1; + } + + /* scan over padding data */ + j = flen - 1; /* one for type. */ + for (i = 0; i < j; i++) { + if (*p != 0xff) { + /* should decrypt to 0xff */ + if (*p == 0) { + p++; + break; + } else { + RSAerror(RSA_R_BAD_FIXED_HEADER_DECRYPT); + return -1; + } + } + p++; + } + + if (i == j) { + RSAerror(RSA_R_NULL_BEFORE_BLOCK_MISSING); + return -1; + } + + if (i < 8) { + RSAerror(RSA_R_BAD_PAD_BYTE_COUNT); + return -1; + } + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerror(RSA_R_DATA_TOO_LARGE); + return -1; + } + memcpy(to, p, j); + + return j; +} +LCRYPTO_ALIAS(RSA_padding_check_PKCS1_type_1); + +int +RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + + if (flen > tlen - 11) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - flen; + + arc4random_buf(p, j); + for (i = 0; i < j; i++) { + while (*p == '\0') + arc4random_buf(p, 1); + p++; + } + + *(p++) = '\0'; + + memcpy(p, from, flen); + return 1; +} +LCRYPTO_ALIAS(RSA_padding_add_PKCS1_type_2); + +int +RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i, j; + const unsigned char *p; + + p = from; + if (num != flen + 1 || *(p++) != 02) { + RSAerror(RSA_R_BLOCK_TYPE_IS_NOT_02); + return -1; + } + + /* scan over padding data */ + j = flen - 1; /* one for type. */ + for (i = 0; i < j; i++) + if (*(p++) == 0) + break; + + if (i == j) { + RSAerror(RSA_R_NULL_BEFORE_BLOCK_MISSING); + return -1; + } + + if (i < 8) { + RSAerror(RSA_R_BAD_PAD_BYTE_COUNT); + return -1; + } + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerror(RSA_R_DATA_TOO_LARGE); + return -1; + } + memcpy(to, p, j); + + return j; +} +LCRYPTO_ALIAS(RSA_padding_check_PKCS1_type_2); diff --git a/Libraries/libressl/crypto/rsa/rsa_pmeth.c b/Libraries/libressl/crypto/rsa/rsa_pmeth.c new file mode 100644 index 000000000..cb82b0908 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_pmeth.c @@ -0,0 +1,879 @@ +/* $OpenBSD: rsa_pmeth.c,v 1.39 2023/07/08 12:26:45 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "bn_local.h" +#include "evp_local.h" +#include "rsa_local.h" + +/* RSA pkey context structure */ + +typedef struct { + /* Key gen parameters */ + int nbits; + BIGNUM *pub_exp; + /* Keygen callback info */ + int gentmp[2]; + /* RSA padding mode */ + int pad_mode; + /* message digest */ + const EVP_MD *md; + /* message digest for MGF1 */ + const EVP_MD *mgf1md; + /* PSS salt length */ + int saltlen; + /* Minimum salt length or -1 if no PSS parameter restriction */ + int min_saltlen; + /* Temp buffer */ + unsigned char *tbuf; + /* OAEP label */ + unsigned char *oaep_label; + size_t oaep_labellen; +} RSA_PKEY_CTX; + +/* True if PSS parameters are restricted */ +#define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1) + +static int +pkey_rsa_init(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx; + + if ((rctx = calloc(1, sizeof(RSA_PKEY_CTX))) == NULL) + return 0; + + rctx->nbits = 2048; + + if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) + rctx->pad_mode = RSA_PKCS1_PSS_PADDING; + else + rctx->pad_mode = RSA_PKCS1_PADDING; + + /* Maximum for sign, auto for verify */ + rctx->saltlen = RSA_PSS_SALTLEN_AUTO; + rctx->min_saltlen = -1; + + ctx->data = rctx; + ctx->keygen_info = rctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int +pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + RSA_PKEY_CTX *dctx, *sctx; + + if (!pkey_rsa_init(dst)) + return 0; + + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp != NULL) { + BN_free(dctx->pub_exp); + if ((dctx->pub_exp = BN_dup(sctx->pub_exp)) == NULL) + return 0; + } + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + dctx->mgf1md = sctx->mgf1md; + if (sctx->oaep_label != NULL) { + free(dctx->oaep_label); + if ((dctx->oaep_label = calloc(1, sctx->oaep_labellen)) == NULL) + return 0; + memcpy(dctx->oaep_label, sctx->oaep_label, sctx->oaep_labellen); + dctx->oaep_labellen = sctx->oaep_labellen; + } + + return 1; +} + +static int +setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) +{ + if (ctx->tbuf != NULL) + return 1; + if ((ctx->tbuf = calloc(1, EVP_PKEY_size(pk->pkey))) == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static void +pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx) { + BN_free(rctx->pub_exp); + free(rctx->tbuf); + free(rctx->oaep_label); + free(rctx); + } +} + +static int +pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + + if (rctx->md) { + if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + RSAerror(RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } + + if (rctx->pad_mode == RSA_X931_PADDING) { + if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { + RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if (!setup_tbuf(rctx, ctx)) { + RSAerror(ERR_R_MALLOC_FAILURE); + return -1; + } + memcpy(rctx->tbuf, tbs, tbslen); + rctx->tbuf[tbslen] = + RSA_X931_hash_id(EVP_MD_type(rctx->md)); + ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, + rsa, RSA_X931_PADDING); + } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { + unsigned int sltmp; + + ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, + &sltmp, rsa); + if (ret <= 0) + return ret; + ret = sltmp; + } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, + tbs, rctx->md, rctx->mgf1md, rctx->saltlen)) + return -1; + ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, + sig, rsa, RSA_NO_PADDING); + } else { + return -1; + } + } else { + ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, + rctx->pad_mode); + } + if (ret < 0) + return ret; + *siglen = ret; + return 1; +} + +static int +pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx->md) { + if (rctx->pad_mode == RSA_X931_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, + ctx->pkey->pkey.rsa, RSA_X931_PADDING); + if (ret < 1) + return 0; + ret--; + if (rctx->tbuf[ret] != + RSA_X931_hash_id(EVP_MD_type(rctx->md))) { + RSAerror(RSA_R_ALGORITHM_MISMATCH); + return 0; + } + if (ret != EVP_MD_size(rctx->md)) { + RSAerror(RSA_R_INVALID_DIGEST_LENGTH); + return 0; + } + if (rout) + memcpy(rout, rctx->tbuf, ret); + } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { + size_t sltmp; + + ret = int_rsa_verify(EVP_MD_type(rctx->md), NULL, 0, + rout, &sltmp, sig, siglen, ctx->pkey->pkey.rsa); + if (ret <= 0) + return 0; + ret = sltmp; + } else { + return -1; + } + } else { + ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, + rctx->pad_mode); + } + if (ret < 0) + return ret; + *routlen = ret; + return 1; +} + +static int +pkey_rsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + size_t rslen; + + if (rctx->md) { + if (rctx->pad_mode == RSA_PKCS1_PADDING) + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + sig, siglen, rsa); + if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + RSAerror(RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } + if (rctx->pad_mode == RSA_X931_PADDING) { + if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, + siglen) <= 0) + return 0; + } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { + int ret; + + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, RSA_NO_PADDING); + if (ret <= 0) + return 0; + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md, + rctx->mgf1md, rctx->tbuf, rctx->saltlen); + if (ret <= 0) + return 0; + return 1; + } else { + return -1; + } + } else { + int ret; + + if (!setup_tbuf(rctx, ctx)) + return -1; + + if ((ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa, + rctx->pad_mode)) <= 0) + return 0; + + rslen = ret; + } + + if (rslen != tbslen || timingsafe_bcmp(tbs, rctx->tbuf, rslen)) + return 0; + + return 1; +} + +static int +pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + RSA_PKEY_CTX *rctx = ctx->data; + int ret; + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + int klen = RSA_size(ctx->pkey->pkey.rsa); + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, + in, inlen, rctx->oaep_label, rctx->oaep_labellen, + rctx->md, rctx->mgf1md)) + return -1; + ret = RSA_public_encrypt(klen, rctx->tbuf, out, + ctx->pkey->pkey.rsa, RSA_NO_PADDING); + } else { + ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + } + if (ret < 0) + return ret; + *outlen = ret; + return 1; +} + +static int +pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_private_decrypt(inlen, in, rctx->tbuf, + ctx->pkey->pkey.rsa, RSA_NO_PADDING); + if (ret <= 0) + return ret; + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, + ret, ret, rctx->oaep_label, rctx->oaep_labellen, rctx->md, + rctx->mgf1md); + } else { + ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + } + if (ret < 0) + return ret; + *outlen = ret; + return 1; +} + +static int +check_padding_md(const EVP_MD *md, int padding) +{ + if (md == NULL) + return 1; + + if (padding == RSA_NO_PADDING) { + RSAerror(RSA_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) { + if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { + RSAerror(RSA_R_INVALID_X931_DIGEST); + return 0; + } + } else { + /* List of all supported RSA digests. */ + /* RFC 8017 and NIST CSOR. */ + switch(EVP_MD_type(md)) { + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_sha512_224: + case NID_sha512_256: + case NID_sha3_224: + case NID_sha3_256: + case NID_sha3_384: + case NID_sha3_512: + case NID_md5: + case NID_md5_sha1: + case NID_md4: + case NID_ripemd160: + return 1; + + default: + RSAerror(RSA_R_INVALID_DIGEST); + return 0; + } + } + + return 1; +} + +static int +pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + RSA_PKEY_CTX *rctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_RSA_PADDING: + if (p1 >= RSA_PKCS1_PADDING && p1 <= RSA_PKCS1_PSS_PADDING) { + if (!check_padding_md(rctx->md, p1)) + return 0; + if (p1 == RSA_PKCS1_PSS_PADDING) { + if (!(ctx->operation & + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } else if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) { + goto bad_pad; + } + if (p1 == RSA_PKCS1_OAEP_PADDING) { + if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + } + bad_pad: + RSAerror(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return -2; + + case EVP_PKEY_CTRL_GET_RSA_PADDING: + *(int *)p2 = rctx->pad_mode; + return 1; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { + RSAerror(RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { + *(int *)p2 = rctx->saltlen; + } else { + if (p1 < RSA_PSS_SALTLEN_MAX) + return -2; + if (rsa_pss_restricted(rctx)) { + if (p1 == RSA_PSS_SALTLEN_AUTO && + ctx->operation == EVP_PKEY_OP_VERIFY) { + RSAerror(RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + if ((p1 == RSA_PSS_SALTLEN_DIGEST && + rctx->min_saltlen > EVP_MD_size(rctx->md)) || + (p1 >= 0 && p1 < rctx->min_saltlen)) { + RSAerror(RSA_R_PSS_SALTLEN_TOO_SMALL); + return 0; + } + } + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < RSA_MIN_MODULUS_BITS) { + RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); + return -2; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || + BN_is_one((BIGNUM *)p2)) { + RSAerror(RSA_R_BAD_E_VALUE); + return -2; + } + BN_free(rctx->pub_exp); + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_MD: + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerror(RSA_R_INVALID_PADDING_MODE); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) + *(const EVP_MD **)p2 = rctx->md; + else + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) + return 0; + if (rsa_pss_restricted(rctx)) { + if (EVP_MD_type(rctx->md) == EVP_MD_type(p2)) + return 1; + RSAerror(RSA_R_DIGEST_NOT_ALLOWED); + return 0; + } + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = rctx->md; + return 1; + + case EVP_PKEY_CTRL_RSA_MGF1_MD: + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && + rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerror(RSA_R_INVALID_MGF1_MD); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { + if (rctx->mgf1md) + *(const EVP_MD **)p2 = rctx->mgf1md; + else + *(const EVP_MD **)p2 = rctx->md; + } else { + if (rsa_pss_restricted(rctx)) { + if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2)) + return 1; + RSAerror(RSA_R_MGF1_DIGEST_NOT_ALLOWED); + return 0; + } + rctx->mgf1md = p2; + } + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerror(RSA_R_INVALID_PADDING_MODE); + return -2; + } + free(rctx->oaep_label); + if (p2 != NULL && p1 > 0) { + rctx->oaep_label = p2; + rctx->oaep_labellen = p1; + } else { + rctx->oaep_label = NULL; + rctx->oaep_labellen = 0; + } + return 1; + + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerror(RSA_R_INVALID_PADDING_MODE); + return -2; + } + *(unsigned char **)p2 = rctx->oaep_label; + return rctx->oaep_labellen; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_SIGN: +#endif + return 1; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_ENCRYPT: +#endif + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return 1; + + /* fall through */ + case EVP_PKEY_CTRL_PEER_KEY: + RSAerror(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + + default: + return -2; + + } +} + +static int +pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) +{ + if (!value) { + RSAerror(RSA_R_VALUE_MISSING); + return 0; + } + if (!strcmp(type, "rsa_padding_mode")) { + int pm; + if (!strcmp(value, "pkcs1")) + pm = RSA_PKCS1_PADDING; + else if (!strcmp(value, "none")) + pm = RSA_NO_PADDING; + else if (!strcmp(value, "oeap")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "oaep")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "x931")) + pm = RSA_X931_PADDING; + else if (!strcmp(value, "pss")) + pm = RSA_PKCS1_PSS_PADDING; + else { + RSAerror(RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (strcmp(type, "rsa_pss_saltlen") == 0) { + int saltlen; + + if (!strcmp(value, "digest")) + saltlen = RSA_PSS_SALTLEN_DIGEST; + else if (!strcmp(value, "max")) + saltlen = RSA_PSS_SALTLEN_MAX; + else if (!strcmp(value, "auto")) + saltlen = RSA_PSS_SALTLEN_AUTO; + else + saltlen = atoi(value); + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); + } + + if (strcmp(type, "rsa_keygen_bits") == 0) { + int nbits = atoi(value); + + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); + } + + if (strcmp(type, "rsa_keygen_pubexp") == 0) { + BIGNUM *pubexp = NULL; + int ret; + + if (!BN_asc2bn(&pubexp, value)) + return 0; + ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); + if (ret <= 0) + BN_free(pubexp); + return ret; + } + + if (strcmp(type, "rsa_mgf1_md") == 0) + return EVP_PKEY_CTX_md(ctx, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, value); + + if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) { + if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_MGF1_MD, value); + + if (strcmp(type, "rsa_pss_keygen_md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_MD, value); + + if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) { + int saltlen = atoi(value); + + return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen); + } + } + + if (strcmp(type, "rsa_oaep_md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, value); + + if (strcmp(type, "rsa_oaep_label") == 0) { + unsigned char *lab; + long lablen; + int ret; + + if ((lab = string_to_hex(value, &lablen)) == NULL) + return 0; + ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); + if (ret <= 0) + free(lab); + + return ret; + } + + return -2; +} + +/* Set PSS parameters when generating a key, if necessary. */ +static int +rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return 1; + + /* If all parameters are default values then do not set PSS. */ + if (rctx->md == NULL && rctx->mgf1md == NULL && + rctx->saltlen == RSA_PSS_SALTLEN_AUTO) + return 1; + + rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md, + rctx->saltlen == RSA_PSS_SALTLEN_AUTO ? 0 : rctx->saltlen); + if (rsa->pss == NULL) + return 0; + + return 1; +} + +static int +pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + + if (rctx->pub_exp == NULL) { + if ((rctx->pub_exp = BN_new()) == NULL) + return 0; + if (!BN_set_word(rctx->pub_exp, RSA_F4)) + return 0; + } + if ((rsa = RSA_new()) == NULL) + return 0; + if (ctx->pkey_gencb != NULL) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else { + pcb = NULL; + } + ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); + if (ret > 0 && !rsa_set_pss_param(rsa, ctx)) { + RSA_free(rsa); + return 0; + } + if (ret > 0) + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa); + else + RSA_free(rsa); + return ret; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + .pkey_id = EVP_PKEY_RSA, + .flags = EVP_PKEY_FLAG_AUTOARGLEN, + + .init = pkey_rsa_init, + .copy = pkey_rsa_copy, + .cleanup = pkey_rsa_cleanup, + + .keygen = pkey_rsa_keygen, + + .sign = pkey_rsa_sign, + + .verify = pkey_rsa_verify, + + .verify_recover = pkey_rsa_verifyrecover, + + .encrypt = pkey_rsa_encrypt, + + .decrypt = pkey_rsa_decrypt, + + .ctrl = pkey_rsa_ctrl, + .ctrl_str = pkey_rsa_ctrl_str +}; + +/* + * Called for PSS sign or verify initialisation: checks PSS parameter + * sanity and sets any restrictions on key usage. + */ + +static int +pkey_pss_init(EVP_PKEY_CTX *ctx) +{ + RSA *rsa; + RSA_PKEY_CTX *rctx = ctx->data; + const EVP_MD *md; + const EVP_MD *mgf1md; + int min_saltlen, max_saltlen; + + /* Should never happen */ + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return 0; + rsa = ctx->pkey->pkey.rsa; + + /* If no restrictions just return */ + if (rsa->pss == NULL) + return 1; + + /* Get and check parameters */ + if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) + return 0; + + /* See if minimum salt length exceeds maximum possible */ + max_saltlen = RSA_size(rsa) - EVP_MD_size(md); + if ((RSA_bits(rsa) & 0x7) == 1) + max_saltlen--; + if (min_saltlen > max_saltlen) { + RSAerror(RSA_R_INVALID_SALT_LENGTH); + return 0; + } + rctx->min_saltlen = min_saltlen; + + /* + * Set PSS restrictions as defaults: we can then block any attempt to + * use invalid values in pkey_rsa_ctrl + */ + + rctx->md = md; + rctx->mgf1md = mgf1md; + rctx->saltlen = min_saltlen; + + return 1; +} + +const EVP_PKEY_METHOD rsa_pss_pkey_meth = { + .pkey_id = EVP_PKEY_RSA_PSS, + .flags = EVP_PKEY_FLAG_AUTOARGLEN, + + .init = pkey_rsa_init, + .copy = pkey_rsa_copy, + .cleanup = pkey_rsa_cleanup, + + .keygen = pkey_rsa_keygen, + + .sign_init = pkey_pss_init, + .sign = pkey_rsa_sign, + + .verify_init = pkey_pss_init, + .verify = pkey_rsa_verify, + + .ctrl = pkey_rsa_ctrl, + .ctrl_str = pkey_rsa_ctrl_str +}; diff --git a/Libraries/libressl/crypto/rsa/rsa_prn.c b/Libraries/libressl/crypto/rsa/rsa_prn.c new file mode 100644 index 000000000..178356366 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_prn.c @@ -0,0 +1,99 @@ +/* $OpenBSD: rsa_prn.c,v 1.10 2023/07/08 12:26:45 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +int +RSA_print_fp(FILE *fp, const RSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + RSAerror(ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = RSA_print(b, x, off); + BIO_free(b); + return ret; +} +LCRYPTO_ALIAS(RSA_print_fp); + +int +RSA_print(BIO *bp, const RSA *x, int off) +{ + EVP_PKEY *pk; + int ret = 0; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + if (!EVP_PKEY_set1_RSA(pk, (RSA *)x)) + goto err; + + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + err: + EVP_PKEY_free(pk); + return ret; +} +LCRYPTO_ALIAS(RSA_print); diff --git a/Libraries/libressl/crypto/rsa/rsa_pss.c b/Libraries/libressl/crypto/rsa/rsa_pss.c new file mode 100644 index 000000000..0860409be --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_pss.c @@ -0,0 +1,288 @@ +/* $OpenBSD: rsa_pss.c,v 1.17 2023/07/08 12:26:45 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "evp_local.h" +#include "rsa_local.h" + +static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +int +RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, const EVP_MD *Hash, + const unsigned char *EM, int sLen) +{ + return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen); +} +LCRYPTO_ALIAS(RSA_verify_PKCS1_PSS); + +int +RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, const unsigned char *EM, + int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + const unsigned char *H; + unsigned char *DB = NULL; + EVP_MD_CTX ctx; + unsigned char H_[EVP_MAX_MD_SIZE]; + + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /* + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is autorecovered from signature + * -N reserved + */ + if (sLen == -1) + sLen = hLen; + else if (sLen == -2) + sLen = -2; + else if (sLen < -2) { + RSAerror(RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + RSAerror(RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < (hLen + sLen + 2)) { + /* sLen can be small negative */ + RSAerror(RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + RSAerror(RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = malloc(maskedDBLen); + if (!DB) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) + goto err; + for (i = 0; i < maskedDBLen; i++) + DB[i] ^= EM[i]; + if (MSBits) + DB[0] &= 0xFF >> (8 - MSBits); + for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) + ; + if (DB[i++] != 0x1) { + RSAerror(RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen >= 0 && (maskedDBLen - i) != sLen) { + RSAerror(RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || + !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) || + !EVP_DigestUpdate(&ctx, mHash, hLen)) + goto err; + if (maskedDBLen - i) { + if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i)) + goto err; + } + if (!EVP_DigestFinal_ex(&ctx, H_, NULL)) + goto err; + if (timingsafe_bcmp(H_, H, hLen)) { + RSAerror(RSA_R_BAD_SIGNATURE); + ret = 0; + } else + ret = 1; + +err: + free(DB); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} +LCRYPTO_ALIAS(RSA_verify_PKCS1_PSS_mgf1); + +int +RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, int sLen) +{ + return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen); +} +LCRYPTO_ALIAS(RSA_padding_add_PKCS1_PSS); + +int +RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + unsigned char *H, *salt = NULL, *p; + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /* + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is maximized + * -N reserved + */ + if (sLen == -1) + sLen = hLen; + else if (sLen == -2) + sLen = -2; + else if (sLen < -2) { + RSAerror(RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + *EM++ = 0; + emLen--; + } + if (sLen == -2) + sLen = emLen - hLen - 2; + else if (emLen < (hLen + sLen + 2)) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + if (sLen > 0) { + salt = malloc(sLen); + if (!salt) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + arc4random_buf(salt, sLen); + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || + !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) || + !EVP_DigestUpdate(&ctx, mHash, hLen)) + goto err; + if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, H, NULL)) + goto err; + + /* Generate dbMask in place then perform XOR on it */ + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) + goto err; + + p = EM; + + /* + * Initial PS XORs with all zeroes which is a NOP so just update + * pointer. Note from a test above this value is guaranteed to + * be non-negative. + */ + p += emLen - sLen - hLen - 2; + *p++ ^= 0x1; + if (sLen > 0) { + for (i = 0; i < sLen; i++) + *p++ ^= salt[i]; + } + if (MSBits) + EM[0] &= 0xFF >> (8 - MSBits); + + /* H is already in place so just set final 0xbc */ + EM[emLen - 1] = 0xbc; + + ret = 1; + +err: + free(salt); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} +LCRYPTO_ALIAS(RSA_padding_add_PKCS1_PSS_mgf1); diff --git a/Libraries/libressl/crypto/rsa/rsa_saos.c b/Libraries/libressl/crypto/rsa/rsa_saos.c new file mode 100644 index 000000000..07a4f5d65 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_saos.c @@ -0,0 +1,143 @@ +/* $OpenBSD: rsa_saos.c,v 1.25 2023/07/08 12:26:45 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include + +int +RSA_sign_ASN1_OCTET_STRING(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, RSA *rsa) +{ + ASN1_OCTET_STRING sig; + int i, j, ret = 1; + unsigned char *p, *s; + + sig.type = V_ASN1_OCTET_STRING; + sig.length = m_len; + sig.data = (unsigned char *)m; + + i = i2d_ASN1_OCTET_STRING(&sig, NULL); + j = RSA_size(rsa); + if (i > (j - RSA_PKCS1_PADDING_SIZE)) { + RSAerror(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return 0; + } + s = malloc(j + 1); + if (s == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + return 0; + } + p = s; + i2d_ASN1_OCTET_STRING(&sig, &p); + i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + ret = 0; + else + *siglen = i; + + freezero(s, (unsigned int)j + 1); + return ret; +} +LCRYPTO_ALIAS(RSA_sign_ASN1_OCTET_STRING); + +int +RSA_verify_ASN1_OCTET_STRING(int dtype, const unsigned char *m, + unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +{ + int i, ret = 0; + unsigned char *s; + const unsigned char *p; + ASN1_OCTET_STRING *sig = NULL; + + if (siglen != (unsigned int)RSA_size(rsa)) { + RSAerror(RSA_R_WRONG_SIGNATURE_LENGTH); + return 0; + } + + s = malloc(siglen); + if (s == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + + if (i <= 0) + goto err; + + p = s; + sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i); + if (sig == NULL) + goto err; + + if ((unsigned int)sig->length != m_len || + timingsafe_bcmp(m, sig->data, m_len) != 0) { + RSAerror(RSA_R_BAD_SIGNATURE); + } else + ret = 1; +err: + ASN1_OCTET_STRING_free(sig); + freezero(s, (unsigned int)siglen); + return ret; +} +LCRYPTO_ALIAS(RSA_verify_ASN1_OCTET_STRING); diff --git a/Libraries/libressl/crypto/rsa/rsa_sign.c b/Libraries/libressl/crypto/rsa/rsa_sign.c new file mode 100644 index 000000000..535676861 --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_sign.c @@ -0,0 +1,280 @@ +/* $OpenBSD: rsa_sign.c,v 1.36 2023/07/08 12:26:45 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "rsa_local.h" +#include "x509_local.h" + +/* Size of an SSL signature: MD5+SHA1 */ +#define SSL_SIG_LENGTH 36 + +static int encode_pkcs1(unsigned char **, int *, int , const unsigned char *, + unsigned int); + +/* + * encode_pkcs1 encodes a DigestInfo prefix of hash `type' and digest `m', as + * described in EMSA-PKCS-v1_5-ENCODE, RFC 8017 section 9. step 2. This + * encodes the DigestInfo (T and tLen) but does not add the padding. + * + * On success, it returns one and sets `*out' to a newly allocated buffer + * containing the result and `*out_len' to its length. Freeing `*out' is + * the caller's responsibility. Failure is indicated by zero. + */ +static int +encode_pkcs1(unsigned char **out, int *out_len, int type, + const unsigned char *m, unsigned int m_len) +{ + X509_SIG sig; + X509_ALGOR algor; + ASN1_TYPE parameter; + ASN1_OCTET_STRING digest; + uint8_t *der = NULL; + int len; + + sig.algor = &algor; + if ((sig.algor->algorithm = OBJ_nid2obj(type)) == NULL) { + RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + if (sig.algor->algorithm->length == 0) { + RSAerror( + RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + return 0; + } + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ + sig.digest->length = m_len; + + if ((len = i2d_X509_SIG(&sig, &der)) < 0) + return 0; + + *out = der; + *out_len = len; + + return 1; +} + +int +RSA_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, RSA *rsa) +{ + const unsigned char *encoded = NULL; + unsigned char *tmps = NULL; + int encrypt_len, encoded_len = 0, ret = 0; + + if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign != NULL) + return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); + + /* Compute the encoded digest. */ + if (type == NID_md5_sha1) { + /* + * NID_md5_sha1 corresponds to the MD5/SHA1 combination in + * TLS 1.1 and earlier. It has no DigestInfo wrapper but + * otherwise is RSASSA-PKCS-v1.5. + */ + if (m_len != SSL_SIG_LENGTH) { + RSAerror(RSA_R_INVALID_DIGEST_LENGTH); + return 0; + } + encoded_len = SSL_SIG_LENGTH; + encoded = m; + } else { + if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len)) + goto err; + encoded = tmps; + } + if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { + RSAerror(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + goto err; + } + if ((encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, + rsa, RSA_PKCS1_PADDING)) <= 0) + goto err; + + *siglen = encrypt_len; + ret = 1; + + err: + freezero(tmps, (size_t)encoded_len); + return (ret); +} +LCRYPTO_ALIAS(RSA_sign); + +/* + * int_rsa_verify verifies an RSA signature in `sigbuf' using `rsa'. It may be + * called in two modes. If `rm' is NULL, it verifies the signature for the + * digest `m'. Otherwise, it recovers the digest from the signature, writing the + * digest to `rm' and the length to `*prm_len'. `type' is the NID of the digest + * algorithm to use. It returns one on successful verification and zero + * otherwise. + */ +int +int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, + unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, + size_t siglen, RSA *rsa) +{ + unsigned char *decrypt_buf, *encoded = NULL; + int decrypt_len, encoded_len = 0, ret = 0; + + if (siglen != (size_t)RSA_size(rsa)) { + RSAerror(RSA_R_WRONG_SIGNATURE_LENGTH); + return 0; + } + + /* Recover the encoded digest. */ + if ((decrypt_buf = malloc(siglen)) == NULL) { + RSAerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if ((decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, + rsa, RSA_PKCS1_PADDING)) <= 0) + goto err; + + if (type == NID_md5_sha1) { + /* + * NID_md5_sha1 corresponds to the MD5/SHA1 combination in + * TLS 1.1 and earlier. It has no DigestInfo wrapper but + * otherwise is RSASSA-PKCS1-v1_5. + */ + if (decrypt_len != SSL_SIG_LENGTH) { + RSAerror(RSA_R_INVALID_DIGEST_LENGTH); + goto err; + } + + if (rm != NULL) { + memcpy(rm, decrypt_buf, SSL_SIG_LENGTH); + *prm_len = SSL_SIG_LENGTH; + } else { + if (m_len != SSL_SIG_LENGTH) { + RSAerror(RSA_R_INVALID_MESSAGE_LENGTH); + goto err; + } + if (timingsafe_bcmp(decrypt_buf, + m, SSL_SIG_LENGTH) != 0) { + RSAerror(RSA_R_BAD_SIGNATURE); + goto err; + } + } + } else { + /* + * If recovering the digest, extract a digest-sized output from + * the end of `decrypt_buf' for `encode_pkcs1', then compare the + * decryption output as in a standard verification. + */ + if (rm != NULL) { + const EVP_MD *md; + + if ((md = EVP_get_digestbynid(type)) == NULL) { + RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE); + goto err; + } + if ((m_len = EVP_MD_size(md)) > (size_t)decrypt_len) { + RSAerror(RSA_R_INVALID_DIGEST_LENGTH); + goto err; + } + m = decrypt_buf + decrypt_len - m_len; + } + + /* Construct the encoded digest and ensure it matches */ + if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len)) + goto err; + + if (encoded_len != decrypt_len || + timingsafe_bcmp(encoded, decrypt_buf, encoded_len) != 0) { + RSAerror(RSA_R_BAD_SIGNATURE); + goto err; + } + + /* Output the recovered digest. */ + if (rm != NULL) { + memcpy(rm, m, m_len); + *prm_len = m_len; + } + } + + ret = 1; + err: + freezero(encoded, (size_t)encoded_len); + freezero(decrypt_buf, siglen); + return ret; +} + +int +RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +{ + if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, + rsa); + + return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); +} +LCRYPTO_ALIAS(RSA_verify); diff --git a/Libraries/libressl/crypto/rsa/rsa_x931.c b/Libraries/libressl/crypto/rsa/rsa_x931.c new file mode 100644 index 000000000..52f3f803b --- /dev/null +++ b/Libraries/libressl/crypto/rsa/rsa_x931.c @@ -0,0 +1,164 @@ +/* $OpenBSD: rsa_x931.c,v 1.12 2023/05/05 12:19:37 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +int +RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *from, + int flen) +{ + int j; + unsigned char *p; + + /* + * Absolute minimum amount of padding is 1 header nibble, 1 padding + * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. + */ + j = tlen - flen - 2; + + if (j < 0) { + RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return -1; + } + + p = (unsigned char *)to; + + /* If no padding start and end nibbles are in one byte */ + if (j == 0) + *p++ = 0x6A; + else { + *p++ = 0x6B; + if (j > 1) { + memset(p, 0xBB, j - 1); + p += j - 1; + } + *p++ = 0xBA; + } + memcpy(p, from, flen); + p += flen; + *p = 0xCC; + return 1; +} + +int +RSA_padding_check_X931(unsigned char *to, int tlen, const unsigned char *from, + int flen, int num) +{ + int i = 0, j; + const unsigned char *p = from; + + if (num != flen || (*p != 0x6A && *p != 0x6B)) { + RSAerror(RSA_R_INVALID_HEADER); + return -1; + } + + if (*p++ == 0x6B) { + j = flen - 3; + for (i = 0; i < j; i++) { + unsigned char c = *p++; + if (c == 0xBA) + break; + if (c != 0xBB) { + RSAerror(RSA_R_INVALID_PADDING); + return -1; + } + } + + if (i == 0) { + RSAerror(RSA_R_INVALID_PADDING); + return -1; + } + + j -= i; + } else + j = flen - 2; + + if (j < 0 || p[j] != 0xCC) { + RSAerror(RSA_R_INVALID_TRAILER); + return -1; + } + + memcpy(to, p, j); + + return j; +} + +/* Translate between X931 hash ids and NIDs */ + +int +RSA_X931_hash_id(int nid) +{ + switch (nid) { + case NID_sha1: + return 0x33; + case NID_sha256: + return 0x34; + case NID_sha384: + return 0x36; + case NID_sha512: + return 0x35; + } + + return -1; +} diff --git a/Libraries/libressl/crypto/sha/sha1-elf-armv4.S b/Libraries/libressl/crypto/sha/sha1-elf-armv4.S new file mode 100644 index 000000000..5aeaf7c6b --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1-elf-armv4.S @@ -0,0 +1,455 @@ +#include "arm_arch.h" + +.text + +.global sha1_block_data_order +.type sha1_block_data_order,%function + +.align 2 +sha1_block_data_order: + stmdb sp!,{r4-r12,lr} + add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 + ldmia r0,{r3,r4,r5,r6,r7} +.Lloop: + ldr r8,.LK_00_19 + mov r14,sp + sub sp,sp,#15*4 + mov r5,r5,ror#30 + mov r6,r6,ror#30 + mov r7,r7,ror#30 @ [6] +.L_00_15: +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r7,r8,r7,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r5,r6 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r7,r8,r7,ror#2 @ E+=K_00_19 + eor r10,r5,r6 @ F_xx_xx + add r7,r7,r3,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r4,r10,ror#2 + add r7,r7,r9 @ E+=X[i] + eor r10,r10,r6,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r7,r7,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r6,r8,r6,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r4,r5 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r6,r8,r6,ror#2 @ E+=K_00_19 + eor r10,r4,r5 @ F_xx_xx + add r6,r6,r7,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r3,r10,ror#2 + add r6,r6,r9 @ E+=X[i] + eor r10,r10,r5,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r6,r6,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r5,r8,r5,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r3,r4 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r5,r8,r5,ror#2 @ E+=K_00_19 + eor r10,r3,r4 @ F_xx_xx + add r5,r5,r6,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r7,r10,ror#2 + add r5,r5,r9 @ E+=X[i] + eor r10,r10,r4,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r5,r5,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r4,r8,r4,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r7,r3 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r4,r8,r4,ror#2 @ E+=K_00_19 + eor r10,r7,r3 @ F_xx_xx + add r4,r4,r5,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r6,r10,ror#2 + add r4,r4,r9 @ E+=X[i] + eor r10,r10,r3,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r4,r4,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r3,r8,r3,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r6,r7 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r3,r8,r3,ror#2 @ E+=K_00_19 + eor r10,r6,r7 @ F_xx_xx + add r3,r3,r4,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r5,r10,ror#2 + add r3,r3,r9 @ E+=X[i] + eor r10,r10,r7,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r3,r3,r10 @ E+=F_00_19(B,C,D) + teq r14,sp + bne .L_00_15 @ [((11+4)*5+2)*3] + sub sp,sp,#25*4 +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r7,r8,r7,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r5,r6 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r7,r8,r7,ror#2 @ E+=K_00_19 + eor r10,r5,r6 @ F_xx_xx + add r7,r7,r3,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r4,r10,ror#2 + add r7,r7,r9 @ E+=X[i] + eor r10,r10,r6,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r7,r7,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r3,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + eor r10,r10,r5,ror#2 @ F_00_19(B,C,D) + add r6,r6,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r7,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + eor r10,r10,r4,ror#2 @ F_00_19(B,C,D) + add r5,r5,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r6,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + eor r10,r10,r3,ror#2 @ F_00_19(B,C,D) + add r4,r4,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r5,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + eor r10,r10,r7,ror#2 @ F_00_19(B,C,D) + add r3,r3,r10 @ E+=F_00_19(B,C,D) + + ldr r8,.LK_20_39 @ [+15+16*4] + cmn sp,#0 @ [+3], clear carry to denote 20_39 +.L_20_39_or_60_79: + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r7,r8,r7,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r5,r6 @ F_xx_xx + mov r9,r9,ror#31 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r4,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r7,r7,r9 @ E+=X[i] + add r7,r7,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r3,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + add r6,r6,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r7,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + add r5,r5,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r6,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + add r4,r4,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r5,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + add r3,r3,r10 @ E+=F_20_39(B,C,D) + teq r14,sp @ preserve carry + bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4] + bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes + + ldr r8,.LK_40_59 + sub sp,sp,#20*4 @ [+2] +.L_40_59: + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r7,r8,r7,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r5,r6 @ F_xx_xx + mov r9,r9,ror#31 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r4,r10,ror#2 @ F_xx_xx + and r11,r5,r6 @ F_xx_xx + add r7,r7,r9 @ E+=X[i] + add r7,r7,r10 @ E+=F_40_59(B,C,D) + add r7,r7,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r3,r10,ror#2 @ F_xx_xx + and r11,r4,r5 @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + add r6,r6,r10 @ E+=F_40_59(B,C,D) + add r6,r6,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r7,r10,ror#2 @ F_xx_xx + and r11,r3,r4 @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + add r5,r5,r10 @ E+=F_40_59(B,C,D) + add r5,r5,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r6,r10,ror#2 @ F_xx_xx + and r11,r7,r3 @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + add r4,r4,r10 @ E+=F_40_59(B,C,D) + add r4,r4,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r5,r10,ror#2 @ F_xx_xx + and r11,r6,r7 @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + add r3,r3,r10 @ E+=F_40_59(B,C,D) + add r3,r3,r11,ror#2 + teq r14,sp + bne .L_40_59 @ [+((12+5)*5+2)*4] + + ldr r8,.LK_60_79 + sub sp,sp,#20*4 + cmp sp,#0 @ set carry to denote 60_79 + b .L_20_39_or_60_79 @ [+4], spare 300 bytes +.L_done: + add sp,sp,#80*4 @ "deallocate" stack frame + ldmia r0,{r8,r9,r10,r11,r12} + add r3,r8,r3 + add r4,r9,r4 + add r5,r10,r5,ror#2 + add r6,r11,r6,ror#2 + add r7,r12,r7,ror#2 + stmia r0,{r3,r4,r5,r6,r7} + teq r1,r2 + bne .Lloop @ [+18], total 1307 + +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + .word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.align 2 +.LK_00_19: .word 0x5a827999 +.LK_20_39: .word 0x6ed9eba1 +.LK_40_59: .word 0x8f1bbcdc +.LK_60_79: .word 0xca62c1d6 +.size sha1_block_data_order,.-sha1_block_data_order +.asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by " +.align 2 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha1-elf-x86_64.S b/Libraries/libressl/crypto/sha/sha1-elf-x86_64.S new file mode 100644 index 000000000..3240e9ec6 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1-elf-x86_64.S @@ -0,0 +1,2494 @@ +#include "x86_arch.h" +.text + +.hidden OPENSSL_ia32cap_P + +.globl sha1_block_data_order +.type sha1_block_data_order,@function +.align 16 +sha1_block_data_order: + endbr64 + movl OPENSSL_ia32cap_P+0(%rip),%r9d + movl OPENSSL_ia32cap_P+4(%rip),%r8d + testl $IA32CAP_MASK1_SSSE3,%r8d + jz .Lialu + jmp _ssse3_shortcut + +.align 16 +.Lialu: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + movq %rsp,%r11 + movq %rdi,%r8 + subq $72,%rsp + movq %rsi,%r9 + andq $-64,%rsp + movq %rdx,%r10 + movq %r11,64(%rsp) +.Lprologue: + + movl 0(%r8),%esi + movl 4(%r8),%edi + movl 8(%r8),%r11d + movl 12(%r8),%r12d + movl 16(%r8),%r13d + jmp .Lloop + +.align 16 +.Lloop: + movl 0(%r9),%edx + bswapl %edx + movl %edx,0(%rsp) + movl %r11d,%eax + movl 4(%r9),%ebp + movl %esi,%ecx + xorl %r12d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r13,1),%r13d + andl %edi,%eax + movl %ebp,4(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 8(%r9),%edx + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r12,1),%r12d + andl %esi,%eax + movl %edx,8(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 12(%r9),%ebp + movl %r12d,%ecx + xorl %edi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r11,1),%r11d + andl %r13d,%eax + movl %ebp,12(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 16(%r9),%edx + movl %r11d,%ecx + xorl %esi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rdi,1),%edi + andl %r12d,%eax + movl %edx,16(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 20(%r9),%ebp + movl %edi,%ecx + xorl %r13d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rsi,1),%esi + andl %r11d,%eax + movl %ebp,20(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl %r11d,%eax + movl 24(%r9),%edx + movl %esi,%ecx + xorl %r12d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r13,1),%r13d + andl %edi,%eax + movl %edx,24(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 28(%r9),%ebp + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r12,1),%r12d + andl %esi,%eax + movl %ebp,28(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 32(%r9),%edx + movl %r12d,%ecx + xorl %edi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r11,1),%r11d + andl %r13d,%eax + movl %edx,32(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 36(%r9),%ebp + movl %r11d,%ecx + xorl %esi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rdi,1),%edi + andl %r12d,%eax + movl %ebp,36(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 40(%r9),%edx + movl %edi,%ecx + xorl %r13d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rsi,1),%esi + andl %r11d,%eax + movl %edx,40(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl %r11d,%eax + movl 44(%r9),%ebp + movl %esi,%ecx + xorl %r12d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r13,1),%r13d + andl %edi,%eax + movl %ebp,44(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 48(%r9),%edx + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r12,1),%r12d + andl %esi,%eax + movl %edx,48(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 52(%r9),%ebp + movl %r12d,%ecx + xorl %edi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r11,1),%r11d + andl %r13d,%eax + movl %ebp,52(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 56(%r9),%edx + movl %r11d,%ecx + xorl %esi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rdi,1),%edi + andl %r12d,%eax + movl %edx,56(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 60(%r9),%ebp + movl %edi,%ecx + xorl %r13d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rsi,1),%esi + andl %r11d,%eax + movl %ebp,60(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 0(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 8(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 32(%rsp),%edx + andl %edi,%eax + leal 1518500249(%rbp,%r13,1),%r13d + xorl 52(%rsp),%edx + xorl %r12d,%eax + roll $1,%edx + addl %ecx,%r13d + roll $30,%edi + movl %edx,0(%rsp) + addl %eax,%r13d + movl 4(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 12(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 36(%rsp),%ebp + andl %esi,%eax + leal 1518500249(%rdx,%r12,1),%r12d + xorl 56(%rsp),%ebp + xorl %r11d,%eax + roll $1,%ebp + addl %ecx,%r12d + roll $30,%esi + movl %ebp,4(%rsp) + addl %eax,%r12d + movl 8(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 16(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + andl %r13d,%eax + leal 1518500249(%rbp,%r11,1),%r11d + xorl 60(%rsp),%edx + xorl %edi,%eax + roll $1,%edx + addl %ecx,%r11d + roll $30,%r13d + movl %edx,8(%rsp) + addl %eax,%r11d + movl 12(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 20(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + xorl 0(%rsp),%ebp + xorl %esi,%eax + roll $1,%ebp + addl %ecx,%edi + roll $30,%r12d + movl %ebp,12(%rsp) + addl %eax,%edi + movl 16(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 24(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 48(%rsp),%edx + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + xorl 4(%rsp),%edx + xorl %r13d,%eax + roll $1,%edx + addl %ecx,%esi + roll $30,%r11d + movl %edx,16(%rsp) + addl %eax,%esi + movl 20(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 28(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r13,1),%r13d + xorl 52(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 8(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 32(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r12,1),%r12d + xorl 56(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 12(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 36(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r11,1),%r11d + xorl 60(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 16(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 40(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rdi,1),%edi + xorl 0(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 20(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 44(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rsi,1),%esi + xorl 4(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 24(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,36(%rsp) + movl 40(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 48(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r13,1),%r13d + xorl 8(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 28(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,40(%rsp) + movl 44(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 52(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r12,1),%r12d + xorl 12(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 32(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,44(%rsp) + movl 48(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 56(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r11,1),%r11d + xorl 16(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 36(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,48(%rsp) + movl 52(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 60(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rdi,1),%edi + xorl 20(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 40(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,52(%rsp) + movl 56(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 0(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rsi,1),%esi + xorl 24(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 44(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,56(%rsp) + movl 60(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r13,1),%r13d + xorl 28(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 48(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,60(%rsp) + movl 0(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r12,1),%r12d + xorl 32(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 52(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,0(%rsp) + movl 4(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r11,1),%r11d + xorl 36(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 56(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,4(%rsp) + movl 8(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 16(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rdi,1),%edi + xorl 40(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 60(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,8(%rsp) + movl 12(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 20(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rsi,1),%esi + xorl 44(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 0(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,12(%rsp) + movl 16(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r13,1),%r13d + xorl 48(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 4(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,16(%rsp) + movl 20(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r12,1),%r12d + xorl 52(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 8(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r11,1),%r11d + xorl 56(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 12(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rdi,1),%edi + xorl 60(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 16(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 40(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rsi,1),%esi + xorl 0(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 20(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %r11d,%eax + movl %r11d,%ebx + xorl 44(%rsp),%ebp + andl %r12d,%eax + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%ebx + leal -1894007588(%rdx,%r13,1),%r13d + roll $5,%ecx + xorl 24(%rsp),%ebp + addl %eax,%r13d + andl %edi,%ebx + roll $1,%ebp + addl %ebx,%r13d + roll $30,%edi + movl %ebp,36(%rsp) + addl %ecx,%r13d + movl 40(%rsp),%edx + movl %edi,%eax + movl %edi,%ebx + xorl 48(%rsp),%edx + andl %r11d,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + xorl %r11d,%ebx + leal -1894007588(%rbp,%r12,1),%r12d + roll $5,%ecx + xorl 28(%rsp),%edx + addl %eax,%r12d + andl %esi,%ebx + roll $1,%edx + addl %ebx,%r12d + roll $30,%esi + movl %edx,40(%rsp) + addl %ecx,%r12d + movl 44(%rsp),%ebp + movl %esi,%eax + movl %esi,%ebx + xorl 52(%rsp),%ebp + andl %edi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + xorl %edi,%ebx + leal -1894007588(%rdx,%r11,1),%r11d + roll $5,%ecx + xorl 32(%rsp),%ebp + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%ebp + addl %ebx,%r11d + roll $30,%r13d + movl %ebp,44(%rsp) + addl %ecx,%r11d + movl 48(%rsp),%edx + movl %r13d,%eax + movl %r13d,%ebx + xorl 56(%rsp),%edx + andl %esi,%eax + movl %r11d,%ecx + xorl 16(%rsp),%edx + xorl %esi,%ebx + leal -1894007588(%rbp,%rdi,1),%edi + roll $5,%ecx + xorl 36(%rsp),%edx + addl %eax,%edi + andl %r12d,%ebx + roll $1,%edx + addl %ebx,%edi + roll $30,%r12d + movl %edx,48(%rsp) + addl %ecx,%edi + movl 52(%rsp),%ebp + movl %r12d,%eax + movl %r12d,%ebx + xorl 60(%rsp),%ebp + andl %r13d,%eax + movl %edi,%ecx + xorl 20(%rsp),%ebp + xorl %r13d,%ebx + leal -1894007588(%rdx,%rsi,1),%esi + roll $5,%ecx + xorl 40(%rsp),%ebp + addl %eax,%esi + andl %r11d,%ebx + roll $1,%ebp + addl %ebx,%esi + roll $30,%r11d + movl %ebp,52(%rsp) + addl %ecx,%esi + movl 56(%rsp),%edx + movl %r11d,%eax + movl %r11d,%ebx + xorl 0(%rsp),%edx + andl %r12d,%eax + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %r12d,%ebx + leal -1894007588(%rbp,%r13,1),%r13d + roll $5,%ecx + xorl 44(%rsp),%edx + addl %eax,%r13d + andl %edi,%ebx + roll $1,%edx + addl %ebx,%r13d + roll $30,%edi + movl %edx,56(%rsp) + addl %ecx,%r13d + movl 60(%rsp),%ebp + movl %edi,%eax + movl %edi,%ebx + xorl 4(%rsp),%ebp + andl %r11d,%eax + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %r11d,%ebx + leal -1894007588(%rdx,%r12,1),%r12d + roll $5,%ecx + xorl 48(%rsp),%ebp + addl %eax,%r12d + andl %esi,%ebx + roll $1,%ebp + addl %ebx,%r12d + roll $30,%esi + movl %ebp,60(%rsp) + addl %ecx,%r12d + movl 0(%rsp),%edx + movl %esi,%eax + movl %esi,%ebx + xorl 8(%rsp),%edx + andl %edi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + xorl %edi,%ebx + leal -1894007588(%rbp,%r11,1),%r11d + roll $5,%ecx + xorl 52(%rsp),%edx + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%edx + addl %ebx,%r11d + roll $30,%r13d + movl %edx,0(%rsp) + addl %ecx,%r11d + movl 4(%rsp),%ebp + movl %r13d,%eax + movl %r13d,%ebx + xorl 12(%rsp),%ebp + andl %esi,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + xorl %esi,%ebx + leal -1894007588(%rdx,%rdi,1),%edi + roll $5,%ecx + xorl 56(%rsp),%ebp + addl %eax,%edi + andl %r12d,%ebx + roll $1,%ebp + addl %ebx,%edi + roll $30,%r12d + movl %ebp,4(%rsp) + addl %ecx,%edi + movl 8(%rsp),%edx + movl %r12d,%eax + movl %r12d,%ebx + xorl 16(%rsp),%edx + andl %r13d,%eax + movl %edi,%ecx + xorl 40(%rsp),%edx + xorl %r13d,%ebx + leal -1894007588(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl 60(%rsp),%edx + addl %eax,%esi + andl %r11d,%ebx + roll $1,%edx + addl %ebx,%esi + roll $30,%r11d + movl %edx,8(%rsp) + addl %ecx,%esi + movl 12(%rsp),%ebp + movl %r11d,%eax + movl %r11d,%ebx + xorl 20(%rsp),%ebp + andl %r12d,%eax + movl %esi,%ecx + xorl 44(%rsp),%ebp + xorl %r12d,%ebx + leal -1894007588(%rdx,%r13,1),%r13d + roll $5,%ecx + xorl 0(%rsp),%ebp + addl %eax,%r13d + andl %edi,%ebx + roll $1,%ebp + addl %ebx,%r13d + roll $30,%edi + movl %ebp,12(%rsp) + addl %ecx,%r13d + movl 16(%rsp),%edx + movl %edi,%eax + movl %edi,%ebx + xorl 24(%rsp),%edx + andl %r11d,%eax + movl %r13d,%ecx + xorl 48(%rsp),%edx + xorl %r11d,%ebx + leal -1894007588(%rbp,%r12,1),%r12d + roll $5,%ecx + xorl 4(%rsp),%edx + addl %eax,%r12d + andl %esi,%ebx + roll $1,%edx + addl %ebx,%r12d + roll $30,%esi + movl %edx,16(%rsp) + addl %ecx,%r12d + movl 20(%rsp),%ebp + movl %esi,%eax + movl %esi,%ebx + xorl 28(%rsp),%ebp + andl %edi,%eax + movl %r12d,%ecx + xorl 52(%rsp),%ebp + xorl %edi,%ebx + leal -1894007588(%rdx,%r11,1),%r11d + roll $5,%ecx + xorl 8(%rsp),%ebp + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%ebp + addl %ebx,%r11d + roll $30,%r13d + movl %ebp,20(%rsp) + addl %ecx,%r11d + movl 24(%rsp),%edx + movl %r13d,%eax + movl %r13d,%ebx + xorl 32(%rsp),%edx + andl %esi,%eax + movl %r11d,%ecx + xorl 56(%rsp),%edx + xorl %esi,%ebx + leal -1894007588(%rbp,%rdi,1),%edi + roll $5,%ecx + xorl 12(%rsp),%edx + addl %eax,%edi + andl %r12d,%ebx + roll $1,%edx + addl %ebx,%edi + roll $30,%r12d + movl %edx,24(%rsp) + addl %ecx,%edi + movl 28(%rsp),%ebp + movl %r12d,%eax + movl %r12d,%ebx + xorl 36(%rsp),%ebp + andl %r13d,%eax + movl %edi,%ecx + xorl 60(%rsp),%ebp + xorl %r13d,%ebx + leal -1894007588(%rdx,%rsi,1),%esi + roll $5,%ecx + xorl 16(%rsp),%ebp + addl %eax,%esi + andl %r11d,%ebx + roll $1,%ebp + addl %ebx,%esi + roll $30,%r11d + movl %ebp,28(%rsp) + addl %ecx,%esi + movl 32(%rsp),%edx + movl %r11d,%eax + movl %r11d,%ebx + xorl 40(%rsp),%edx + andl %r12d,%eax + movl %esi,%ecx + xorl 0(%rsp),%edx + xorl %r12d,%ebx + leal -1894007588(%rbp,%r13,1),%r13d + roll $5,%ecx + xorl 20(%rsp),%edx + addl %eax,%r13d + andl %edi,%ebx + roll $1,%edx + addl %ebx,%r13d + roll $30,%edi + movl %edx,32(%rsp) + addl %ecx,%r13d + movl 36(%rsp),%ebp + movl %edi,%eax + movl %edi,%ebx + xorl 44(%rsp),%ebp + andl %r11d,%eax + movl %r13d,%ecx + xorl 4(%rsp),%ebp + xorl %r11d,%ebx + leal -1894007588(%rdx,%r12,1),%r12d + roll $5,%ecx + xorl 24(%rsp),%ebp + addl %eax,%r12d + andl %esi,%ebx + roll $1,%ebp + addl %ebx,%r12d + roll $30,%esi + movl %ebp,36(%rsp) + addl %ecx,%r12d + movl 40(%rsp),%edx + movl %esi,%eax + movl %esi,%ebx + xorl 48(%rsp),%edx + andl %edi,%eax + movl %r12d,%ecx + xorl 8(%rsp),%edx + xorl %edi,%ebx + leal -1894007588(%rbp,%r11,1),%r11d + roll $5,%ecx + xorl 28(%rsp),%edx + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%edx + addl %ebx,%r11d + roll $30,%r13d + movl %edx,40(%rsp) + addl %ecx,%r11d + movl 44(%rsp),%ebp + movl %r13d,%eax + movl %r13d,%ebx + xorl 52(%rsp),%ebp + andl %esi,%eax + movl %r11d,%ecx + xorl 12(%rsp),%ebp + xorl %esi,%ebx + leal -1894007588(%rdx,%rdi,1),%edi + roll $5,%ecx + xorl 32(%rsp),%ebp + addl %eax,%edi + andl %r12d,%ebx + roll $1,%ebp + addl %ebx,%edi + roll $30,%r12d + movl %ebp,44(%rsp) + addl %ecx,%edi + movl 48(%rsp),%edx + movl %r12d,%eax + movl %r12d,%ebx + xorl 56(%rsp),%edx + andl %r13d,%eax + movl %edi,%ecx + xorl 16(%rsp),%edx + xorl %r13d,%ebx + leal -1894007588(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl 36(%rsp),%edx + addl %eax,%esi + andl %r11d,%ebx + roll $1,%edx + addl %ebx,%esi + roll $30,%r11d + movl %edx,48(%rsp) + addl %ecx,%esi + movl 52(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 60(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r13,1),%r13d + xorl 20(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 40(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,52(%rsp) + movl 56(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 0(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r12,1),%r12d + xorl 24(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 44(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,56(%rsp) + movl 60(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 4(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rdx,%r11,1),%r11d + xorl 28(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 48(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,60(%rsp) + movl 0(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 8(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rdi,1),%edi + xorl 32(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 52(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,0(%rsp) + movl 4(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 12(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rsi,1),%esi + xorl 36(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 56(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,4(%rsp) + movl 8(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 16(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r13,1),%r13d + xorl 40(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 60(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,8(%rsp) + movl 12(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 20(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r12,1),%r12d + xorl 44(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 0(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,12(%rsp) + movl 16(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 24(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rbp,%r11,1),%r11d + xorl 48(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 4(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,16(%rsp) + movl 20(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 28(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rdi,1),%edi + xorl 52(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 8(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 32(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rsi,1),%esi + xorl 56(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 12(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 36(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r13,1),%r13d + xorl 60(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 16(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 40(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r12,1),%r12d + xorl 0(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 20(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 44(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rdx,%r11,1),%r11d + xorl 4(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 24(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,36(%rsp) + movl 40(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 48(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rdi,1),%edi + xorl 8(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 28(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,40(%rsp) + movl 44(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 52(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rsi,1),%esi + xorl 12(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 32(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,44(%rsp) + movl 48(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 56(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r13,1),%r13d + xorl 16(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 36(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,48(%rsp) + movl 52(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 60(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r12,1),%r12d + xorl 20(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 40(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl 56(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 0(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rbp,%r11,1),%r11d + xorl 24(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 44(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl 60(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rdi,1),%edi + xorl 28(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 48(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl %r11d,%eax + leal -899497514(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl %r13d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + addl 0(%r8),%esi + addl 4(%r8),%edi + addl 8(%r8),%r11d + addl 12(%r8),%r12d + addl 16(%r8),%r13d + movl %esi,0(%r8) + movl %edi,4(%r8) + movl %r11d,8(%r8) + movl %r12d,12(%r8) + movl %r13d,16(%r8) + + subq $1,%r10 + leaq 64(%r9),%r9 + jnz .Lloop + + movq 64(%rsp),%rsi + movq (%rsi),%r13 + movq 8(%rsi),%r12 + movq 16(%rsi),%rbp + movq 24(%rsi),%rbx + leaq 32(%rsi),%rsp +.Lepilogue: + retq +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_data_order_ssse3,@function +.align 16 +sha1_block_data_order_ssse3: +_ssse3_shortcut: + endbr64 + pushq %rbx + pushq %rbp + pushq %r12 + leaq -64(%rsp),%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX(%rip),%r11 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + + movdqa 64(%r11),%xmm6 + movdqa 0(%r11),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 +.byte 102,15,56,0,222 + paddd %xmm9,%xmm0 + paddd %xmm9,%xmm1 + paddd %xmm9,%xmm2 + movdqa %xmm0,0(%rsp) + psubd %xmm9,%xmm0 + movdqa %xmm1,16(%rsp) + psubd %xmm9,%xmm1 + movdqa %xmm2,32(%rsp) + psubd %xmm9,%xmm2 + jmp .Loop_ssse3 +.align 16 +.Loop_ssse3: + movdqa %xmm1,%xmm4 + addl 0(%rsp),%ebp + xorl %edx,%ecx + movdqa %xmm3,%xmm8 +.byte 102,15,58,15,224,8 + movl %eax,%edi + roll $5,%eax + paddd %xmm3,%xmm9 + andl %ecx,%esi + xorl %edx,%ecx + psrldq $4,%xmm8 + xorl %edx,%esi + addl %eax,%ebp + pxor %xmm0,%xmm4 + rorl $2,%ebx + addl %esi,%ebp + pxor %xmm2,%xmm8 + addl 4(%rsp),%edx + xorl %ecx,%ebx + movl %ebp,%esi + roll $5,%ebp + pxor %xmm8,%xmm4 + andl %ebx,%edi + xorl %ecx,%ebx + movdqa %xmm9,48(%rsp) + xorl %ecx,%edi + addl %ebp,%edx + movdqa %xmm4,%xmm10 + movdqa %xmm4,%xmm8 + rorl $7,%eax + addl %edi,%edx + addl 8(%rsp),%ecx + xorl %ebx,%eax + pslldq $12,%xmm10 + paddd %xmm4,%xmm4 + movl %edx,%edi + roll $5,%edx + andl %eax,%esi + xorl %ebx,%eax + psrld $31,%xmm8 + xorl %ebx,%esi + addl %edx,%ecx + movdqa %xmm10,%xmm9 + rorl $7,%ebp + addl %esi,%ecx + psrld $30,%xmm10 + por %xmm8,%xmm4 + addl 12(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%esi + roll $5,%ecx + pslld $2,%xmm9 + pxor %xmm10,%xmm4 + andl %ebp,%edi + xorl %eax,%ebp + movdqa 0(%r11),%xmm10 + xorl %eax,%edi + addl %ecx,%ebx + pxor %xmm9,%xmm4 + rorl $7,%edx + addl %edi,%ebx + movdqa %xmm2,%xmm5 + addl 16(%rsp),%eax + xorl %ebp,%edx + movdqa %xmm4,%xmm9 +.byte 102,15,58,15,233,8 + movl %ebx,%edi + roll $5,%ebx + paddd %xmm4,%xmm10 + andl %edx,%esi + xorl %ebp,%edx + psrldq $4,%xmm9 + xorl %ebp,%esi + addl %ebx,%eax + pxor %xmm1,%xmm5 + rorl $7,%ecx + addl %esi,%eax + pxor %xmm3,%xmm9 + addl 20(%rsp),%ebp + xorl %edx,%ecx + movl %eax,%esi + roll $5,%eax + pxor %xmm9,%xmm5 + andl %ecx,%edi + xorl %edx,%ecx + movdqa %xmm10,0(%rsp) + xorl %edx,%edi + addl %eax,%ebp + movdqa %xmm5,%xmm8 + movdqa %xmm5,%xmm9 + rorl $7,%ebx + addl %edi,%ebp + addl 24(%rsp),%edx + xorl %ecx,%ebx + pslldq $12,%xmm8 + paddd %xmm5,%xmm5 + movl %ebp,%edi + roll $5,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + psrld $31,%xmm9 + xorl %ecx,%esi + addl %ebp,%edx + movdqa %xmm8,%xmm10 + rorl $7,%eax + addl %esi,%edx + psrld $30,%xmm8 + por %xmm9,%xmm5 + addl 28(%rsp),%ecx + xorl %ebx,%eax + movl %edx,%esi + roll $5,%edx + pslld $2,%xmm10 + pxor %xmm8,%xmm5 + andl %eax,%edi + xorl %ebx,%eax + movdqa 16(%r11),%xmm8 + xorl %ebx,%edi + addl %edx,%ecx + pxor %xmm10,%xmm5 + rorl $7,%ebp + addl %edi,%ecx + movdqa %xmm3,%xmm6 + addl 32(%rsp),%ebx + xorl %eax,%ebp + movdqa %xmm5,%xmm10 +.byte 102,15,58,15,242,8 + movl %ecx,%edi + roll $5,%ecx + paddd %xmm5,%xmm8 + andl %ebp,%esi + xorl %eax,%ebp + psrldq $4,%xmm10 + xorl %eax,%esi + addl %ecx,%ebx + pxor %xmm2,%xmm6 + rorl $7,%edx + addl %esi,%ebx + pxor %xmm4,%xmm10 + addl 36(%rsp),%eax + xorl %ebp,%edx + movl %ebx,%esi + roll $5,%ebx + pxor %xmm10,%xmm6 + andl %edx,%edi + xorl %ebp,%edx + movdqa %xmm8,16(%rsp) + xorl %ebp,%edi + addl %ebx,%eax + movdqa %xmm6,%xmm9 + movdqa %xmm6,%xmm10 + rorl $7,%ecx + addl %edi,%eax + addl 40(%rsp),%ebp + xorl %edx,%ecx + pslldq $12,%xmm9 + paddd %xmm6,%xmm6 + movl %eax,%edi + roll $5,%eax + andl %ecx,%esi + xorl %edx,%ecx + psrld $31,%xmm10 + xorl %edx,%esi + addl %eax,%ebp + movdqa %xmm9,%xmm8 + rorl $7,%ebx + addl %esi,%ebp + psrld $30,%xmm9 + por %xmm10,%xmm6 + addl 44(%rsp),%edx + xorl %ecx,%ebx + movl %ebp,%esi + roll $5,%ebp + pslld $2,%xmm8 + pxor %xmm9,%xmm6 + andl %ebx,%edi + xorl %ecx,%ebx + movdqa 16(%r11),%xmm9 + xorl %ecx,%edi + addl %ebp,%edx + pxor %xmm8,%xmm6 + rorl $7,%eax + addl %edi,%edx + movdqa %xmm4,%xmm7 + addl 48(%rsp),%ecx + xorl %ebx,%eax + movdqa %xmm6,%xmm8 +.byte 102,15,58,15,251,8 + movl %edx,%edi + roll $5,%edx + paddd %xmm6,%xmm9 + andl %eax,%esi + xorl %ebx,%eax + psrldq $4,%xmm8 + xorl %ebx,%esi + addl %edx,%ecx + pxor %xmm3,%xmm7 + rorl $7,%ebp + addl %esi,%ecx + pxor %xmm5,%xmm8 + addl 52(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%esi + roll $5,%ecx + pxor %xmm8,%xmm7 + andl %ebp,%edi + xorl %eax,%ebp + movdqa %xmm9,32(%rsp) + xorl %eax,%edi + addl %ecx,%ebx + movdqa %xmm7,%xmm10 + movdqa %xmm7,%xmm8 + rorl $7,%edx + addl %edi,%ebx + addl 56(%rsp),%eax + xorl %ebp,%edx + pslldq $12,%xmm10 + paddd %xmm7,%xmm7 + movl %ebx,%edi + roll $5,%ebx + andl %edx,%esi + xorl %ebp,%edx + psrld $31,%xmm8 + xorl %ebp,%esi + addl %ebx,%eax + movdqa %xmm10,%xmm9 + rorl $7,%ecx + addl %esi,%eax + psrld $30,%xmm10 + por %xmm8,%xmm7 + addl 60(%rsp),%ebp + xorl %edx,%ecx + movl %eax,%esi + roll $5,%eax + pslld $2,%xmm9 + pxor %xmm10,%xmm7 + andl %ecx,%edi + xorl %edx,%ecx + movdqa 16(%r11),%xmm10 + xorl %edx,%edi + addl %eax,%ebp + pxor %xmm9,%xmm7 + rorl $7,%ebx + addl %edi,%ebp + movdqa %xmm7,%xmm9 + addl 0(%rsp),%edx + pxor %xmm4,%xmm0 +.byte 102,68,15,58,15,206,8 + xorl %ecx,%ebx + movl %ebp,%edi + roll $5,%ebp + pxor %xmm1,%xmm0 + andl %ebx,%esi + xorl %ecx,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm7,%xmm10 + xorl %ecx,%esi + addl %ebp,%edx + pxor %xmm9,%xmm0 + rorl $7,%eax + addl %esi,%edx + addl 4(%rsp),%ecx + xorl %ebx,%eax + movdqa %xmm0,%xmm9 + movdqa %xmm10,48(%rsp) + movl %edx,%esi + roll $5,%edx + andl %eax,%edi + xorl %ebx,%eax + pslld $2,%xmm0 + xorl %ebx,%edi + addl %edx,%ecx + psrld $30,%xmm9 + rorl $7,%ebp + addl %edi,%ecx + addl 8(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%edi + roll $5,%ecx + por %xmm9,%xmm0 + andl %ebp,%esi + xorl %eax,%ebp + movdqa %xmm0,%xmm10 + xorl %eax,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edx + movl %ebx,%esi + roll $5,%ebx + andl %edx,%edi + xorl %ebp,%edx + xorl %ebp,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 16(%rsp),%ebp + pxor %xmm5,%xmm1 +.byte 102,68,15,58,15,215,8 + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + pxor %xmm2,%xmm1 + xorl %ecx,%esi + addl %eax,%ebp + movdqa %xmm8,%xmm9 + paddd %xmm0,%xmm8 + rorl $7,%ebx + addl %esi,%ebp + pxor %xmm10,%xmm1 + addl 20(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm1,%xmm10 + movdqa %xmm8,0(%rsp) + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm1 + addl 24(%rsp),%ecx + xorl %ebx,%esi + psrld $30,%xmm10 + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + por %xmm10,%xmm1 + addl 28(%rsp),%ebx + xorl %eax,%edi + movdqa %xmm1,%xmm8 + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 32(%rsp),%eax + pxor %xmm6,%xmm2 +.byte 102,68,15,58,15,192,8 + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + pxor %xmm3,%xmm2 + xorl %edx,%esi + addl %ebx,%eax + movdqa 32(%r11),%xmm10 + paddd %xmm1,%xmm9 + rorl $7,%ecx + addl %esi,%eax + pxor %xmm8,%xmm2 + addl 36(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm8 + movdqa %xmm9,16(%rsp) + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + pslld $2,%xmm2 + addl 40(%rsp),%edx + xorl %ecx,%esi + psrld $30,%xmm8 + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + por %xmm8,%xmm2 + addl 44(%rsp),%ecx + xorl %ebx,%edi + movdqa %xmm2,%xmm9 + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 48(%rsp),%ebx + pxor %xmm7,%xmm3 +.byte 102,68,15,58,15,201,8 + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + pxor %xmm4,%xmm3 + xorl %ebp,%esi + addl %ecx,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm2,%xmm10 + rorl $7,%edx + addl %esi,%ebx + pxor %xmm9,%xmm3 + addl 52(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm9 + movdqa %xmm10,32(%rsp) + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + pslld $2,%xmm3 + addl 56(%rsp),%ebp + xorl %edx,%esi + psrld $30,%xmm9 + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + por %xmm9,%xmm3 + addl 60(%rsp),%edx + xorl %ecx,%edi + movdqa %xmm3,%xmm10 + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 0(%rsp),%ecx + pxor %xmm0,%xmm4 +.byte 102,68,15,58,15,210,8 + xorl %ebx,%esi + movl %edx,%edi + roll $5,%edx + pxor %xmm5,%xmm4 + xorl %eax,%esi + addl %edx,%ecx + movdqa %xmm8,%xmm9 + paddd %xmm3,%xmm8 + rorl $7,%ebp + addl %esi,%ecx + pxor %xmm10,%xmm4 + addl 4(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm10 + movdqa %xmm8,48(%rsp) + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + pslld $2,%xmm4 + addl 8(%rsp),%eax + xorl %ebp,%esi + psrld $30,%xmm10 + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + por %xmm10,%xmm4 + addl 12(%rsp),%ebp + xorl %edx,%edi + movdqa %xmm4,%xmm8 + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 16(%rsp),%edx + pxor %xmm1,%xmm5 +.byte 102,68,15,58,15,195,8 + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + pxor %xmm6,%xmm5 + xorl %ebx,%esi + addl %ebp,%edx + movdqa %xmm9,%xmm10 + paddd %xmm4,%xmm9 + rorl $7,%eax + addl %esi,%edx + pxor %xmm8,%xmm5 + addl 20(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm8 + movdqa %xmm9,0(%rsp) + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + pslld $2,%xmm5 + addl 24(%rsp),%ebx + xorl %eax,%esi + psrld $30,%xmm8 + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + por %xmm8,%xmm5 + addl 28(%rsp),%eax + xorl %ebp,%edi + movdqa %xmm5,%xmm9 + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + movl %ecx,%edi + pxor %xmm2,%xmm6 +.byte 102,68,15,58,15,204,8 + xorl %edx,%ecx + addl 32(%rsp),%ebp + andl %edx,%edi + pxor %xmm7,%xmm6 + andl %ecx,%esi + rorl $7,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm5,%xmm10 + addl %edi,%ebp + movl %eax,%edi + pxor %xmm9,%xmm6 + roll $5,%eax + addl %esi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movdqa %xmm6,%xmm9 + movdqa %xmm10,16(%rsp) + movl %ebx,%esi + xorl %ecx,%ebx + addl 36(%rsp),%edx + andl %ecx,%esi + pslld $2,%xmm6 + andl %ebx,%edi + rorl $7,%eax + psrld $30,%xmm9 + addl %esi,%edx + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + por %xmm9,%xmm6 + movl %eax,%edi + xorl %ebx,%eax + movdqa %xmm6,%xmm10 + addl 40(%rsp),%ecx + andl %ebx,%edi + andl %eax,%esi + rorl $7,%ebp + addl %edi,%ecx + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movl %ebp,%esi + xorl %eax,%ebp + addl 44(%rsp),%ebx + andl %eax,%esi + andl %ebp,%edi + rorl $7,%edx + addl %esi,%ebx + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movl %edx,%edi + pxor %xmm3,%xmm7 +.byte 102,68,15,58,15,213,8 + xorl %ebp,%edx + addl 48(%rsp),%eax + andl %ebp,%edi + pxor %xmm0,%xmm7 + andl %edx,%esi + rorl $7,%ecx + movdqa 48(%r11),%xmm9 + paddd %xmm6,%xmm8 + addl %edi,%eax + movl %ebx,%edi + pxor %xmm10,%xmm7 + roll $5,%ebx + addl %esi,%eax + xorl %ebp,%edx + addl %ebx,%eax + movdqa %xmm7,%xmm10 + movdqa %xmm8,32(%rsp) + movl %ecx,%esi + xorl %edx,%ecx + addl 52(%rsp),%ebp + andl %edx,%esi + pslld $2,%xmm7 + andl %ecx,%edi + rorl $7,%ebx + psrld $30,%xmm10 + addl %esi,%ebp + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + por %xmm10,%xmm7 + movl %ebx,%edi + xorl %ecx,%ebx + movdqa %xmm7,%xmm8 + addl 56(%rsp),%edx + andl %ecx,%edi + andl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movl %eax,%esi + xorl %ebx,%eax + addl 60(%rsp),%ecx + andl %ebx,%esi + andl %eax,%edi + rorl $7,%ebp + addl %esi,%ecx + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movl %ebp,%edi + pxor %xmm4,%xmm0 +.byte 102,68,15,58,15,198,8 + xorl %eax,%ebp + addl 0(%rsp),%ebx + andl %eax,%edi + pxor %xmm1,%xmm0 + andl %ebp,%esi + rorl $7,%edx + movdqa %xmm9,%xmm10 + paddd %xmm7,%xmm9 + addl %edi,%ebx + movl %ecx,%edi + pxor %xmm8,%xmm0 + roll $5,%ecx + addl %esi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movdqa %xmm0,%xmm8 + movdqa %xmm9,48(%rsp) + movl %edx,%esi + xorl %ebp,%edx + addl 4(%rsp),%eax + andl %ebp,%esi + pslld $2,%xmm0 + andl %edx,%edi + rorl $7,%ecx + psrld $30,%xmm8 + addl %esi,%eax + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %ebp,%edx + addl %ebx,%eax + por %xmm8,%xmm0 + movl %ecx,%edi + xorl %edx,%ecx + movdqa %xmm0,%xmm9 + addl 8(%rsp),%ebp + andl %edx,%edi + andl %ecx,%esi + rorl $7,%ebx + addl %edi,%ebp + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movl %ebx,%esi + xorl %ecx,%ebx + addl 12(%rsp),%edx + andl %ecx,%esi + andl %ebx,%edi + rorl $7,%eax + addl %esi,%edx + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movl %eax,%edi + pxor %xmm5,%xmm1 +.byte 102,68,15,58,15,207,8 + xorl %ebx,%eax + addl 16(%rsp),%ecx + andl %ebx,%edi + pxor %xmm2,%xmm1 + andl %eax,%esi + rorl $7,%ebp + movdqa %xmm10,%xmm8 + paddd %xmm0,%xmm10 + addl %edi,%ecx + movl %edx,%edi + pxor %xmm9,%xmm1 + roll $5,%edx + addl %esi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movdqa %xmm1,%xmm9 + movdqa %xmm10,0(%rsp) + movl %ebp,%esi + xorl %eax,%ebp + addl 20(%rsp),%ebx + andl %eax,%esi + pslld $2,%xmm1 + andl %ebp,%edi + rorl $7,%edx + psrld $30,%xmm9 + addl %esi,%ebx + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + por %xmm9,%xmm1 + movl %edx,%edi + xorl %ebp,%edx + movdqa %xmm1,%xmm10 + addl 24(%rsp),%eax + andl %ebp,%edi + andl %edx,%esi + rorl $7,%ecx + addl %edi,%eax + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %ebp,%edx + addl %ebx,%eax + movl %ecx,%esi + xorl %edx,%ecx + addl 28(%rsp),%ebp + andl %edx,%esi + andl %ecx,%edi + rorl $7,%ebx + addl %esi,%ebp + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movl %ebx,%edi + pxor %xmm6,%xmm2 +.byte 102,68,15,58,15,208,8 + xorl %ecx,%ebx + addl 32(%rsp),%edx + andl %ecx,%edi + pxor %xmm3,%xmm2 + andl %ebx,%esi + rorl $7,%eax + movdqa %xmm8,%xmm9 + paddd %xmm1,%xmm8 + addl %edi,%edx + movl %ebp,%edi + pxor %xmm10,%xmm2 + roll $5,%ebp + addl %esi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movdqa %xmm2,%xmm10 + movdqa %xmm8,16(%rsp) + movl %eax,%esi + xorl %ebx,%eax + addl 36(%rsp),%ecx + andl %ebx,%esi + pslld $2,%xmm2 + andl %eax,%edi + rorl $7,%ebp + psrld $30,%xmm10 + addl %esi,%ecx + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + por %xmm10,%xmm2 + movl %ebp,%edi + xorl %eax,%ebp + movdqa %xmm2,%xmm8 + addl 40(%rsp),%ebx + andl %eax,%edi + andl %ebp,%esi + rorl $7,%edx + addl %edi,%ebx + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movl %edx,%esi + xorl %ebp,%edx + addl 44(%rsp),%eax + andl %ebp,%esi + andl %edx,%edi + rorl $7,%ecx + addl %esi,%eax + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %ebp,%edx + addl %ebx,%eax + addl 48(%rsp),%ebp + pxor %xmm7,%xmm3 +.byte 102,68,15,58,15,193,8 + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + pxor %xmm4,%xmm3 + xorl %ecx,%esi + addl %eax,%ebp + movdqa %xmm9,%xmm10 + paddd %xmm2,%xmm9 + rorl $7,%ebx + addl %esi,%ebp + pxor %xmm8,%xmm3 + addl 52(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm3,%xmm8 + movdqa %xmm9,32(%rsp) + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm3 + addl 56(%rsp),%ecx + xorl %ebx,%esi + psrld $30,%xmm8 + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + por %xmm8,%xmm3 + addl 60(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 0(%rsp),%eax + paddd %xmm3,%xmm10 + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + movdqa %xmm10,48(%rsp) + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 4(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 8(%rsp),%edx + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + addl 12(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + cmpq %r10,%r9 + je .Ldone_ssse3 + movdqa 64(%r11),%xmm6 + movdqa 0(%r11),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %eax,%esi +.byte 102,15,56,0,206 + movl %ecx,%edi + roll $5,%ecx + paddd %xmm9,%xmm0 + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + movdqa %xmm0,0(%rsp) + addl 20(%rsp),%eax + xorl %ebp,%edi + psubd %xmm9,%xmm0 + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 24(%rsp),%ebp + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + addl 28(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 32(%rsp),%ecx + xorl %ebx,%esi +.byte 102,15,56,0,214 + movl %edx,%edi + roll $5,%edx + paddd %xmm9,%xmm1 + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + movdqa %xmm1,16(%rsp) + addl 36(%rsp),%ebx + xorl %eax,%edi + psubd %xmm9,%xmm1 + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 40(%rsp),%eax + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 44(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 48(%rsp),%edx + xorl %ecx,%esi +.byte 102,15,56,0,222 + movl %ebp,%edi + roll $5,%ebp + paddd %xmm9,%xmm2 + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + movdqa %xmm2,32(%rsp) + addl 52(%rsp),%ecx + xorl %ebx,%edi + psubd %xmm9,%xmm2 + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 56(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 60(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + jmp .Loop_ssse3 + +.align 16 +.Ldone_ssse3: + addl 16(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 20(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 24(%rsp),%ebp + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + addl 28(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 32(%rsp),%ecx + xorl %ebx,%esi + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + addl 36(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 40(%rsp),%eax + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 44(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 48(%rsp),%edx + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + addl 52(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 56(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 60(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + leaq 64(%rsp),%rsi + movq 0(%rsi),%r12 + movq 8(%rsi),%rbp + movq 16(%rsi),%rbx + leaq 24(%rsi),%rsp +.Lepilogue_ssse3: + retq +.size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3 +.section .rodata +.align 64 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.text +.align 64 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha1-macosx-x86_64.S b/Libraries/libressl/crypto/sha/sha1-macosx-x86_64.S new file mode 100644 index 000000000..04a8affbf --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1-macosx-x86_64.S @@ -0,0 +1,2488 @@ +#include "x86_arch.h" +.text + +.private_extern _OPENSSL_ia32cap_P + +.globl _sha1_block_data_order + +.p2align 4 +_sha1_block_data_order: + movl _OPENSSL_ia32cap_P+0(%rip),%r9d + movl _OPENSSL_ia32cap_P+4(%rip),%r8d + testl $IA32CAP_MASK1_SSSE3,%r8d + jz L$ialu + jmp _ssse3_shortcut + +.p2align 4 +L$ialu: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + movq %rsp,%r11 + movq %rdi,%r8 + subq $72,%rsp + movq %rsi,%r9 + andq $-64,%rsp + movq %rdx,%r10 + movq %r11,64(%rsp) +L$prologue: + + movl 0(%r8),%esi + movl 4(%r8),%edi + movl 8(%r8),%r11d + movl 12(%r8),%r12d + movl 16(%r8),%r13d + jmp L$loop + +.p2align 4 +L$loop: + movl 0(%r9),%edx + bswapl %edx + movl %edx,0(%rsp) + movl %r11d,%eax + movl 4(%r9),%ebp + movl %esi,%ecx + xorl %r12d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r13,1),%r13d + andl %edi,%eax + movl %ebp,4(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 8(%r9),%edx + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r12,1),%r12d + andl %esi,%eax + movl %edx,8(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 12(%r9),%ebp + movl %r12d,%ecx + xorl %edi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r11,1),%r11d + andl %r13d,%eax + movl %ebp,12(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 16(%r9),%edx + movl %r11d,%ecx + xorl %esi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rdi,1),%edi + andl %r12d,%eax + movl %edx,16(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 20(%r9),%ebp + movl %edi,%ecx + xorl %r13d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rsi,1),%esi + andl %r11d,%eax + movl %ebp,20(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl %r11d,%eax + movl 24(%r9),%edx + movl %esi,%ecx + xorl %r12d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r13,1),%r13d + andl %edi,%eax + movl %edx,24(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 28(%r9),%ebp + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r12,1),%r12d + andl %esi,%eax + movl %ebp,28(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 32(%r9),%edx + movl %r12d,%ecx + xorl %edi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r11,1),%r11d + andl %r13d,%eax + movl %edx,32(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 36(%r9),%ebp + movl %r11d,%ecx + xorl %esi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rdi,1),%edi + andl %r12d,%eax + movl %ebp,36(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 40(%r9),%edx + movl %edi,%ecx + xorl %r13d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rsi,1),%esi + andl %r11d,%eax + movl %edx,40(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl %r11d,%eax + movl 44(%r9),%ebp + movl %esi,%ecx + xorl %r12d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r13,1),%r13d + andl %edi,%eax + movl %ebp,44(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 48(%r9),%edx + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r12,1),%r12d + andl %esi,%eax + movl %edx,48(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 52(%r9),%ebp + movl %r12d,%ecx + xorl %edi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r11,1),%r11d + andl %r13d,%eax + movl %ebp,52(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 56(%r9),%edx + movl %r11d,%ecx + xorl %esi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rdi,1),%edi + andl %r12d,%eax + movl %edx,56(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 60(%r9),%ebp + movl %edi,%ecx + xorl %r13d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rsi,1),%esi + andl %r11d,%eax + movl %ebp,60(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 0(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 8(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 32(%rsp),%edx + andl %edi,%eax + leal 1518500249(%rbp,%r13,1),%r13d + xorl 52(%rsp),%edx + xorl %r12d,%eax + roll $1,%edx + addl %ecx,%r13d + roll $30,%edi + movl %edx,0(%rsp) + addl %eax,%r13d + movl 4(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 12(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 36(%rsp),%ebp + andl %esi,%eax + leal 1518500249(%rdx,%r12,1),%r12d + xorl 56(%rsp),%ebp + xorl %r11d,%eax + roll $1,%ebp + addl %ecx,%r12d + roll $30,%esi + movl %ebp,4(%rsp) + addl %eax,%r12d + movl 8(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 16(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + andl %r13d,%eax + leal 1518500249(%rbp,%r11,1),%r11d + xorl 60(%rsp),%edx + xorl %edi,%eax + roll $1,%edx + addl %ecx,%r11d + roll $30,%r13d + movl %edx,8(%rsp) + addl %eax,%r11d + movl 12(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 20(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + xorl 0(%rsp),%ebp + xorl %esi,%eax + roll $1,%ebp + addl %ecx,%edi + roll $30,%r12d + movl %ebp,12(%rsp) + addl %eax,%edi + movl 16(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 24(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 48(%rsp),%edx + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + xorl 4(%rsp),%edx + xorl %r13d,%eax + roll $1,%edx + addl %ecx,%esi + roll $30,%r11d + movl %edx,16(%rsp) + addl %eax,%esi + movl 20(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 28(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r13,1),%r13d + xorl 52(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 8(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 32(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r12,1),%r12d + xorl 56(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 12(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 36(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r11,1),%r11d + xorl 60(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 16(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 40(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rdi,1),%edi + xorl 0(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 20(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 44(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rsi,1),%esi + xorl 4(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 24(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,36(%rsp) + movl 40(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 48(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r13,1),%r13d + xorl 8(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 28(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,40(%rsp) + movl 44(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 52(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r12,1),%r12d + xorl 12(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 32(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,44(%rsp) + movl 48(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 56(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r11,1),%r11d + xorl 16(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 36(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,48(%rsp) + movl 52(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 60(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rdi,1),%edi + xorl 20(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 40(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,52(%rsp) + movl 56(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 0(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rsi,1),%esi + xorl 24(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 44(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,56(%rsp) + movl 60(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r13,1),%r13d + xorl 28(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 48(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,60(%rsp) + movl 0(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r12,1),%r12d + xorl 32(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 52(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,0(%rsp) + movl 4(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r11,1),%r11d + xorl 36(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 56(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,4(%rsp) + movl 8(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 16(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rdi,1),%edi + xorl 40(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 60(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,8(%rsp) + movl 12(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 20(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rsi,1),%esi + xorl 44(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 0(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,12(%rsp) + movl 16(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r13,1),%r13d + xorl 48(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 4(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,16(%rsp) + movl 20(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r12,1),%r12d + xorl 52(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 8(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r11,1),%r11d + xorl 56(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 12(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rdi,1),%edi + xorl 60(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 16(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 40(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rsi,1),%esi + xorl 0(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 20(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %r11d,%eax + movl %r11d,%ebx + xorl 44(%rsp),%ebp + andl %r12d,%eax + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%ebx + leal -1894007588(%rdx,%r13,1),%r13d + roll $5,%ecx + xorl 24(%rsp),%ebp + addl %eax,%r13d + andl %edi,%ebx + roll $1,%ebp + addl %ebx,%r13d + roll $30,%edi + movl %ebp,36(%rsp) + addl %ecx,%r13d + movl 40(%rsp),%edx + movl %edi,%eax + movl %edi,%ebx + xorl 48(%rsp),%edx + andl %r11d,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + xorl %r11d,%ebx + leal -1894007588(%rbp,%r12,1),%r12d + roll $5,%ecx + xorl 28(%rsp),%edx + addl %eax,%r12d + andl %esi,%ebx + roll $1,%edx + addl %ebx,%r12d + roll $30,%esi + movl %edx,40(%rsp) + addl %ecx,%r12d + movl 44(%rsp),%ebp + movl %esi,%eax + movl %esi,%ebx + xorl 52(%rsp),%ebp + andl %edi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + xorl %edi,%ebx + leal -1894007588(%rdx,%r11,1),%r11d + roll $5,%ecx + xorl 32(%rsp),%ebp + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%ebp + addl %ebx,%r11d + roll $30,%r13d + movl %ebp,44(%rsp) + addl %ecx,%r11d + movl 48(%rsp),%edx + movl %r13d,%eax + movl %r13d,%ebx + xorl 56(%rsp),%edx + andl %esi,%eax + movl %r11d,%ecx + xorl 16(%rsp),%edx + xorl %esi,%ebx + leal -1894007588(%rbp,%rdi,1),%edi + roll $5,%ecx + xorl 36(%rsp),%edx + addl %eax,%edi + andl %r12d,%ebx + roll $1,%edx + addl %ebx,%edi + roll $30,%r12d + movl %edx,48(%rsp) + addl %ecx,%edi + movl 52(%rsp),%ebp + movl %r12d,%eax + movl %r12d,%ebx + xorl 60(%rsp),%ebp + andl %r13d,%eax + movl %edi,%ecx + xorl 20(%rsp),%ebp + xorl %r13d,%ebx + leal -1894007588(%rdx,%rsi,1),%esi + roll $5,%ecx + xorl 40(%rsp),%ebp + addl %eax,%esi + andl %r11d,%ebx + roll $1,%ebp + addl %ebx,%esi + roll $30,%r11d + movl %ebp,52(%rsp) + addl %ecx,%esi + movl 56(%rsp),%edx + movl %r11d,%eax + movl %r11d,%ebx + xorl 0(%rsp),%edx + andl %r12d,%eax + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %r12d,%ebx + leal -1894007588(%rbp,%r13,1),%r13d + roll $5,%ecx + xorl 44(%rsp),%edx + addl %eax,%r13d + andl %edi,%ebx + roll $1,%edx + addl %ebx,%r13d + roll $30,%edi + movl %edx,56(%rsp) + addl %ecx,%r13d + movl 60(%rsp),%ebp + movl %edi,%eax + movl %edi,%ebx + xorl 4(%rsp),%ebp + andl %r11d,%eax + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %r11d,%ebx + leal -1894007588(%rdx,%r12,1),%r12d + roll $5,%ecx + xorl 48(%rsp),%ebp + addl %eax,%r12d + andl %esi,%ebx + roll $1,%ebp + addl %ebx,%r12d + roll $30,%esi + movl %ebp,60(%rsp) + addl %ecx,%r12d + movl 0(%rsp),%edx + movl %esi,%eax + movl %esi,%ebx + xorl 8(%rsp),%edx + andl %edi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + xorl %edi,%ebx + leal -1894007588(%rbp,%r11,1),%r11d + roll $5,%ecx + xorl 52(%rsp),%edx + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%edx + addl %ebx,%r11d + roll $30,%r13d + movl %edx,0(%rsp) + addl %ecx,%r11d + movl 4(%rsp),%ebp + movl %r13d,%eax + movl %r13d,%ebx + xorl 12(%rsp),%ebp + andl %esi,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + xorl %esi,%ebx + leal -1894007588(%rdx,%rdi,1),%edi + roll $5,%ecx + xorl 56(%rsp),%ebp + addl %eax,%edi + andl %r12d,%ebx + roll $1,%ebp + addl %ebx,%edi + roll $30,%r12d + movl %ebp,4(%rsp) + addl %ecx,%edi + movl 8(%rsp),%edx + movl %r12d,%eax + movl %r12d,%ebx + xorl 16(%rsp),%edx + andl %r13d,%eax + movl %edi,%ecx + xorl 40(%rsp),%edx + xorl %r13d,%ebx + leal -1894007588(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl 60(%rsp),%edx + addl %eax,%esi + andl %r11d,%ebx + roll $1,%edx + addl %ebx,%esi + roll $30,%r11d + movl %edx,8(%rsp) + addl %ecx,%esi + movl 12(%rsp),%ebp + movl %r11d,%eax + movl %r11d,%ebx + xorl 20(%rsp),%ebp + andl %r12d,%eax + movl %esi,%ecx + xorl 44(%rsp),%ebp + xorl %r12d,%ebx + leal -1894007588(%rdx,%r13,1),%r13d + roll $5,%ecx + xorl 0(%rsp),%ebp + addl %eax,%r13d + andl %edi,%ebx + roll $1,%ebp + addl %ebx,%r13d + roll $30,%edi + movl %ebp,12(%rsp) + addl %ecx,%r13d + movl 16(%rsp),%edx + movl %edi,%eax + movl %edi,%ebx + xorl 24(%rsp),%edx + andl %r11d,%eax + movl %r13d,%ecx + xorl 48(%rsp),%edx + xorl %r11d,%ebx + leal -1894007588(%rbp,%r12,1),%r12d + roll $5,%ecx + xorl 4(%rsp),%edx + addl %eax,%r12d + andl %esi,%ebx + roll $1,%edx + addl %ebx,%r12d + roll $30,%esi + movl %edx,16(%rsp) + addl %ecx,%r12d + movl 20(%rsp),%ebp + movl %esi,%eax + movl %esi,%ebx + xorl 28(%rsp),%ebp + andl %edi,%eax + movl %r12d,%ecx + xorl 52(%rsp),%ebp + xorl %edi,%ebx + leal -1894007588(%rdx,%r11,1),%r11d + roll $5,%ecx + xorl 8(%rsp),%ebp + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%ebp + addl %ebx,%r11d + roll $30,%r13d + movl %ebp,20(%rsp) + addl %ecx,%r11d + movl 24(%rsp),%edx + movl %r13d,%eax + movl %r13d,%ebx + xorl 32(%rsp),%edx + andl %esi,%eax + movl %r11d,%ecx + xorl 56(%rsp),%edx + xorl %esi,%ebx + leal -1894007588(%rbp,%rdi,1),%edi + roll $5,%ecx + xorl 12(%rsp),%edx + addl %eax,%edi + andl %r12d,%ebx + roll $1,%edx + addl %ebx,%edi + roll $30,%r12d + movl %edx,24(%rsp) + addl %ecx,%edi + movl 28(%rsp),%ebp + movl %r12d,%eax + movl %r12d,%ebx + xorl 36(%rsp),%ebp + andl %r13d,%eax + movl %edi,%ecx + xorl 60(%rsp),%ebp + xorl %r13d,%ebx + leal -1894007588(%rdx,%rsi,1),%esi + roll $5,%ecx + xorl 16(%rsp),%ebp + addl %eax,%esi + andl %r11d,%ebx + roll $1,%ebp + addl %ebx,%esi + roll $30,%r11d + movl %ebp,28(%rsp) + addl %ecx,%esi + movl 32(%rsp),%edx + movl %r11d,%eax + movl %r11d,%ebx + xorl 40(%rsp),%edx + andl %r12d,%eax + movl %esi,%ecx + xorl 0(%rsp),%edx + xorl %r12d,%ebx + leal -1894007588(%rbp,%r13,1),%r13d + roll $5,%ecx + xorl 20(%rsp),%edx + addl %eax,%r13d + andl %edi,%ebx + roll $1,%edx + addl %ebx,%r13d + roll $30,%edi + movl %edx,32(%rsp) + addl %ecx,%r13d + movl 36(%rsp),%ebp + movl %edi,%eax + movl %edi,%ebx + xorl 44(%rsp),%ebp + andl %r11d,%eax + movl %r13d,%ecx + xorl 4(%rsp),%ebp + xorl %r11d,%ebx + leal -1894007588(%rdx,%r12,1),%r12d + roll $5,%ecx + xorl 24(%rsp),%ebp + addl %eax,%r12d + andl %esi,%ebx + roll $1,%ebp + addl %ebx,%r12d + roll $30,%esi + movl %ebp,36(%rsp) + addl %ecx,%r12d + movl 40(%rsp),%edx + movl %esi,%eax + movl %esi,%ebx + xorl 48(%rsp),%edx + andl %edi,%eax + movl %r12d,%ecx + xorl 8(%rsp),%edx + xorl %edi,%ebx + leal -1894007588(%rbp,%r11,1),%r11d + roll $5,%ecx + xorl 28(%rsp),%edx + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%edx + addl %ebx,%r11d + roll $30,%r13d + movl %edx,40(%rsp) + addl %ecx,%r11d + movl 44(%rsp),%ebp + movl %r13d,%eax + movl %r13d,%ebx + xorl 52(%rsp),%ebp + andl %esi,%eax + movl %r11d,%ecx + xorl 12(%rsp),%ebp + xorl %esi,%ebx + leal -1894007588(%rdx,%rdi,1),%edi + roll $5,%ecx + xorl 32(%rsp),%ebp + addl %eax,%edi + andl %r12d,%ebx + roll $1,%ebp + addl %ebx,%edi + roll $30,%r12d + movl %ebp,44(%rsp) + addl %ecx,%edi + movl 48(%rsp),%edx + movl %r12d,%eax + movl %r12d,%ebx + xorl 56(%rsp),%edx + andl %r13d,%eax + movl %edi,%ecx + xorl 16(%rsp),%edx + xorl %r13d,%ebx + leal -1894007588(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl 36(%rsp),%edx + addl %eax,%esi + andl %r11d,%ebx + roll $1,%edx + addl %ebx,%esi + roll $30,%r11d + movl %edx,48(%rsp) + addl %ecx,%esi + movl 52(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 60(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r13,1),%r13d + xorl 20(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 40(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,52(%rsp) + movl 56(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 0(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r12,1),%r12d + xorl 24(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 44(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,56(%rsp) + movl 60(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 4(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rdx,%r11,1),%r11d + xorl 28(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 48(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,60(%rsp) + movl 0(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 8(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rdi,1),%edi + xorl 32(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 52(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,0(%rsp) + movl 4(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 12(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rsi,1),%esi + xorl 36(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 56(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,4(%rsp) + movl 8(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 16(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r13,1),%r13d + xorl 40(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 60(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,8(%rsp) + movl 12(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 20(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r12,1),%r12d + xorl 44(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 0(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,12(%rsp) + movl 16(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 24(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rbp,%r11,1),%r11d + xorl 48(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 4(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,16(%rsp) + movl 20(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 28(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rdi,1),%edi + xorl 52(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 8(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 32(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rsi,1),%esi + xorl 56(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 12(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 36(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r13,1),%r13d + xorl 60(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 16(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 40(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r12,1),%r12d + xorl 0(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 20(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 44(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rdx,%r11,1),%r11d + xorl 4(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 24(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,36(%rsp) + movl 40(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 48(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rdi,1),%edi + xorl 8(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 28(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,40(%rsp) + movl 44(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 52(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rsi,1),%esi + xorl 12(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 32(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,44(%rsp) + movl 48(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 56(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r13,1),%r13d + xorl 16(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 36(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,48(%rsp) + movl 52(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 60(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r12,1),%r12d + xorl 20(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 40(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl 56(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 0(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rbp,%r11,1),%r11d + xorl 24(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 44(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl 60(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rdi,1),%edi + xorl 28(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 48(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl %r11d,%eax + leal -899497514(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl %r13d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + addl 0(%r8),%esi + addl 4(%r8),%edi + addl 8(%r8),%r11d + addl 12(%r8),%r12d + addl 16(%r8),%r13d + movl %esi,0(%r8) + movl %edi,4(%r8) + movl %r11d,8(%r8) + movl %r12d,12(%r8) + movl %r13d,16(%r8) + + subq $1,%r10 + leaq 64(%r9),%r9 + jnz L$loop + + movq 64(%rsp),%rsi + movq (%rsi),%r13 + movq 8(%rsi),%r12 + movq 16(%rsi),%rbp + movq 24(%rsi),%rbx + leaq 32(%rsi),%rsp +L$epilogue: + retq + + +.p2align 4 +sha1_block_data_order_ssse3: +_ssse3_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + leaq -64(%rsp),%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX(%rip),%r11 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + + movdqa 64(%r11),%xmm6 + movdqa 0(%r11),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 +.byte 102,15,56,0,222 + paddd %xmm9,%xmm0 + paddd %xmm9,%xmm1 + paddd %xmm9,%xmm2 + movdqa %xmm0,0(%rsp) + psubd %xmm9,%xmm0 + movdqa %xmm1,16(%rsp) + psubd %xmm9,%xmm1 + movdqa %xmm2,32(%rsp) + psubd %xmm9,%xmm2 + jmp L$oop_ssse3 +.p2align 4 +L$oop_ssse3: + movdqa %xmm1,%xmm4 + addl 0(%rsp),%ebp + xorl %edx,%ecx + movdqa %xmm3,%xmm8 +.byte 102,15,58,15,224,8 + movl %eax,%edi + roll $5,%eax + paddd %xmm3,%xmm9 + andl %ecx,%esi + xorl %edx,%ecx + psrldq $4,%xmm8 + xorl %edx,%esi + addl %eax,%ebp + pxor %xmm0,%xmm4 + rorl $2,%ebx + addl %esi,%ebp + pxor %xmm2,%xmm8 + addl 4(%rsp),%edx + xorl %ecx,%ebx + movl %ebp,%esi + roll $5,%ebp + pxor %xmm8,%xmm4 + andl %ebx,%edi + xorl %ecx,%ebx + movdqa %xmm9,48(%rsp) + xorl %ecx,%edi + addl %ebp,%edx + movdqa %xmm4,%xmm10 + movdqa %xmm4,%xmm8 + rorl $7,%eax + addl %edi,%edx + addl 8(%rsp),%ecx + xorl %ebx,%eax + pslldq $12,%xmm10 + paddd %xmm4,%xmm4 + movl %edx,%edi + roll $5,%edx + andl %eax,%esi + xorl %ebx,%eax + psrld $31,%xmm8 + xorl %ebx,%esi + addl %edx,%ecx + movdqa %xmm10,%xmm9 + rorl $7,%ebp + addl %esi,%ecx + psrld $30,%xmm10 + por %xmm8,%xmm4 + addl 12(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%esi + roll $5,%ecx + pslld $2,%xmm9 + pxor %xmm10,%xmm4 + andl %ebp,%edi + xorl %eax,%ebp + movdqa 0(%r11),%xmm10 + xorl %eax,%edi + addl %ecx,%ebx + pxor %xmm9,%xmm4 + rorl $7,%edx + addl %edi,%ebx + movdqa %xmm2,%xmm5 + addl 16(%rsp),%eax + xorl %ebp,%edx + movdqa %xmm4,%xmm9 +.byte 102,15,58,15,233,8 + movl %ebx,%edi + roll $5,%ebx + paddd %xmm4,%xmm10 + andl %edx,%esi + xorl %ebp,%edx + psrldq $4,%xmm9 + xorl %ebp,%esi + addl %ebx,%eax + pxor %xmm1,%xmm5 + rorl $7,%ecx + addl %esi,%eax + pxor %xmm3,%xmm9 + addl 20(%rsp),%ebp + xorl %edx,%ecx + movl %eax,%esi + roll $5,%eax + pxor %xmm9,%xmm5 + andl %ecx,%edi + xorl %edx,%ecx + movdqa %xmm10,0(%rsp) + xorl %edx,%edi + addl %eax,%ebp + movdqa %xmm5,%xmm8 + movdqa %xmm5,%xmm9 + rorl $7,%ebx + addl %edi,%ebp + addl 24(%rsp),%edx + xorl %ecx,%ebx + pslldq $12,%xmm8 + paddd %xmm5,%xmm5 + movl %ebp,%edi + roll $5,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + psrld $31,%xmm9 + xorl %ecx,%esi + addl %ebp,%edx + movdqa %xmm8,%xmm10 + rorl $7,%eax + addl %esi,%edx + psrld $30,%xmm8 + por %xmm9,%xmm5 + addl 28(%rsp),%ecx + xorl %ebx,%eax + movl %edx,%esi + roll $5,%edx + pslld $2,%xmm10 + pxor %xmm8,%xmm5 + andl %eax,%edi + xorl %ebx,%eax + movdqa 16(%r11),%xmm8 + xorl %ebx,%edi + addl %edx,%ecx + pxor %xmm10,%xmm5 + rorl $7,%ebp + addl %edi,%ecx + movdqa %xmm3,%xmm6 + addl 32(%rsp),%ebx + xorl %eax,%ebp + movdqa %xmm5,%xmm10 +.byte 102,15,58,15,242,8 + movl %ecx,%edi + roll $5,%ecx + paddd %xmm5,%xmm8 + andl %ebp,%esi + xorl %eax,%ebp + psrldq $4,%xmm10 + xorl %eax,%esi + addl %ecx,%ebx + pxor %xmm2,%xmm6 + rorl $7,%edx + addl %esi,%ebx + pxor %xmm4,%xmm10 + addl 36(%rsp),%eax + xorl %ebp,%edx + movl %ebx,%esi + roll $5,%ebx + pxor %xmm10,%xmm6 + andl %edx,%edi + xorl %ebp,%edx + movdqa %xmm8,16(%rsp) + xorl %ebp,%edi + addl %ebx,%eax + movdqa %xmm6,%xmm9 + movdqa %xmm6,%xmm10 + rorl $7,%ecx + addl %edi,%eax + addl 40(%rsp),%ebp + xorl %edx,%ecx + pslldq $12,%xmm9 + paddd %xmm6,%xmm6 + movl %eax,%edi + roll $5,%eax + andl %ecx,%esi + xorl %edx,%ecx + psrld $31,%xmm10 + xorl %edx,%esi + addl %eax,%ebp + movdqa %xmm9,%xmm8 + rorl $7,%ebx + addl %esi,%ebp + psrld $30,%xmm9 + por %xmm10,%xmm6 + addl 44(%rsp),%edx + xorl %ecx,%ebx + movl %ebp,%esi + roll $5,%ebp + pslld $2,%xmm8 + pxor %xmm9,%xmm6 + andl %ebx,%edi + xorl %ecx,%ebx + movdqa 16(%r11),%xmm9 + xorl %ecx,%edi + addl %ebp,%edx + pxor %xmm8,%xmm6 + rorl $7,%eax + addl %edi,%edx + movdqa %xmm4,%xmm7 + addl 48(%rsp),%ecx + xorl %ebx,%eax + movdqa %xmm6,%xmm8 +.byte 102,15,58,15,251,8 + movl %edx,%edi + roll $5,%edx + paddd %xmm6,%xmm9 + andl %eax,%esi + xorl %ebx,%eax + psrldq $4,%xmm8 + xorl %ebx,%esi + addl %edx,%ecx + pxor %xmm3,%xmm7 + rorl $7,%ebp + addl %esi,%ecx + pxor %xmm5,%xmm8 + addl 52(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%esi + roll $5,%ecx + pxor %xmm8,%xmm7 + andl %ebp,%edi + xorl %eax,%ebp + movdqa %xmm9,32(%rsp) + xorl %eax,%edi + addl %ecx,%ebx + movdqa %xmm7,%xmm10 + movdqa %xmm7,%xmm8 + rorl $7,%edx + addl %edi,%ebx + addl 56(%rsp),%eax + xorl %ebp,%edx + pslldq $12,%xmm10 + paddd %xmm7,%xmm7 + movl %ebx,%edi + roll $5,%ebx + andl %edx,%esi + xorl %ebp,%edx + psrld $31,%xmm8 + xorl %ebp,%esi + addl %ebx,%eax + movdqa %xmm10,%xmm9 + rorl $7,%ecx + addl %esi,%eax + psrld $30,%xmm10 + por %xmm8,%xmm7 + addl 60(%rsp),%ebp + xorl %edx,%ecx + movl %eax,%esi + roll $5,%eax + pslld $2,%xmm9 + pxor %xmm10,%xmm7 + andl %ecx,%edi + xorl %edx,%ecx + movdqa 16(%r11),%xmm10 + xorl %edx,%edi + addl %eax,%ebp + pxor %xmm9,%xmm7 + rorl $7,%ebx + addl %edi,%ebp + movdqa %xmm7,%xmm9 + addl 0(%rsp),%edx + pxor %xmm4,%xmm0 +.byte 102,68,15,58,15,206,8 + xorl %ecx,%ebx + movl %ebp,%edi + roll $5,%ebp + pxor %xmm1,%xmm0 + andl %ebx,%esi + xorl %ecx,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm7,%xmm10 + xorl %ecx,%esi + addl %ebp,%edx + pxor %xmm9,%xmm0 + rorl $7,%eax + addl %esi,%edx + addl 4(%rsp),%ecx + xorl %ebx,%eax + movdqa %xmm0,%xmm9 + movdqa %xmm10,48(%rsp) + movl %edx,%esi + roll $5,%edx + andl %eax,%edi + xorl %ebx,%eax + pslld $2,%xmm0 + xorl %ebx,%edi + addl %edx,%ecx + psrld $30,%xmm9 + rorl $7,%ebp + addl %edi,%ecx + addl 8(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%edi + roll $5,%ecx + por %xmm9,%xmm0 + andl %ebp,%esi + xorl %eax,%ebp + movdqa %xmm0,%xmm10 + xorl %eax,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edx + movl %ebx,%esi + roll $5,%ebx + andl %edx,%edi + xorl %ebp,%edx + xorl %ebp,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 16(%rsp),%ebp + pxor %xmm5,%xmm1 +.byte 102,68,15,58,15,215,8 + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + pxor %xmm2,%xmm1 + xorl %ecx,%esi + addl %eax,%ebp + movdqa %xmm8,%xmm9 + paddd %xmm0,%xmm8 + rorl $7,%ebx + addl %esi,%ebp + pxor %xmm10,%xmm1 + addl 20(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm1,%xmm10 + movdqa %xmm8,0(%rsp) + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm1 + addl 24(%rsp),%ecx + xorl %ebx,%esi + psrld $30,%xmm10 + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + por %xmm10,%xmm1 + addl 28(%rsp),%ebx + xorl %eax,%edi + movdqa %xmm1,%xmm8 + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 32(%rsp),%eax + pxor %xmm6,%xmm2 +.byte 102,68,15,58,15,192,8 + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + pxor %xmm3,%xmm2 + xorl %edx,%esi + addl %ebx,%eax + movdqa 32(%r11),%xmm10 + paddd %xmm1,%xmm9 + rorl $7,%ecx + addl %esi,%eax + pxor %xmm8,%xmm2 + addl 36(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm8 + movdqa %xmm9,16(%rsp) + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + pslld $2,%xmm2 + addl 40(%rsp),%edx + xorl %ecx,%esi + psrld $30,%xmm8 + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + por %xmm8,%xmm2 + addl 44(%rsp),%ecx + xorl %ebx,%edi + movdqa %xmm2,%xmm9 + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 48(%rsp),%ebx + pxor %xmm7,%xmm3 +.byte 102,68,15,58,15,201,8 + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + pxor %xmm4,%xmm3 + xorl %ebp,%esi + addl %ecx,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm2,%xmm10 + rorl $7,%edx + addl %esi,%ebx + pxor %xmm9,%xmm3 + addl 52(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm9 + movdqa %xmm10,32(%rsp) + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + pslld $2,%xmm3 + addl 56(%rsp),%ebp + xorl %edx,%esi + psrld $30,%xmm9 + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + por %xmm9,%xmm3 + addl 60(%rsp),%edx + xorl %ecx,%edi + movdqa %xmm3,%xmm10 + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 0(%rsp),%ecx + pxor %xmm0,%xmm4 +.byte 102,68,15,58,15,210,8 + xorl %ebx,%esi + movl %edx,%edi + roll $5,%edx + pxor %xmm5,%xmm4 + xorl %eax,%esi + addl %edx,%ecx + movdqa %xmm8,%xmm9 + paddd %xmm3,%xmm8 + rorl $7,%ebp + addl %esi,%ecx + pxor %xmm10,%xmm4 + addl 4(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm10 + movdqa %xmm8,48(%rsp) + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + pslld $2,%xmm4 + addl 8(%rsp),%eax + xorl %ebp,%esi + psrld $30,%xmm10 + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + por %xmm10,%xmm4 + addl 12(%rsp),%ebp + xorl %edx,%edi + movdqa %xmm4,%xmm8 + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 16(%rsp),%edx + pxor %xmm1,%xmm5 +.byte 102,68,15,58,15,195,8 + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + pxor %xmm6,%xmm5 + xorl %ebx,%esi + addl %ebp,%edx + movdqa %xmm9,%xmm10 + paddd %xmm4,%xmm9 + rorl $7,%eax + addl %esi,%edx + pxor %xmm8,%xmm5 + addl 20(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm8 + movdqa %xmm9,0(%rsp) + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + pslld $2,%xmm5 + addl 24(%rsp),%ebx + xorl %eax,%esi + psrld $30,%xmm8 + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + por %xmm8,%xmm5 + addl 28(%rsp),%eax + xorl %ebp,%edi + movdqa %xmm5,%xmm9 + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + movl %ecx,%edi + pxor %xmm2,%xmm6 +.byte 102,68,15,58,15,204,8 + xorl %edx,%ecx + addl 32(%rsp),%ebp + andl %edx,%edi + pxor %xmm7,%xmm6 + andl %ecx,%esi + rorl $7,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm5,%xmm10 + addl %edi,%ebp + movl %eax,%edi + pxor %xmm9,%xmm6 + roll $5,%eax + addl %esi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movdqa %xmm6,%xmm9 + movdqa %xmm10,16(%rsp) + movl %ebx,%esi + xorl %ecx,%ebx + addl 36(%rsp),%edx + andl %ecx,%esi + pslld $2,%xmm6 + andl %ebx,%edi + rorl $7,%eax + psrld $30,%xmm9 + addl %esi,%edx + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + por %xmm9,%xmm6 + movl %eax,%edi + xorl %ebx,%eax + movdqa %xmm6,%xmm10 + addl 40(%rsp),%ecx + andl %ebx,%edi + andl %eax,%esi + rorl $7,%ebp + addl %edi,%ecx + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movl %ebp,%esi + xorl %eax,%ebp + addl 44(%rsp),%ebx + andl %eax,%esi + andl %ebp,%edi + rorl $7,%edx + addl %esi,%ebx + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movl %edx,%edi + pxor %xmm3,%xmm7 +.byte 102,68,15,58,15,213,8 + xorl %ebp,%edx + addl 48(%rsp),%eax + andl %ebp,%edi + pxor %xmm0,%xmm7 + andl %edx,%esi + rorl $7,%ecx + movdqa 48(%r11),%xmm9 + paddd %xmm6,%xmm8 + addl %edi,%eax + movl %ebx,%edi + pxor %xmm10,%xmm7 + roll $5,%ebx + addl %esi,%eax + xorl %ebp,%edx + addl %ebx,%eax + movdqa %xmm7,%xmm10 + movdqa %xmm8,32(%rsp) + movl %ecx,%esi + xorl %edx,%ecx + addl 52(%rsp),%ebp + andl %edx,%esi + pslld $2,%xmm7 + andl %ecx,%edi + rorl $7,%ebx + psrld $30,%xmm10 + addl %esi,%ebp + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + por %xmm10,%xmm7 + movl %ebx,%edi + xorl %ecx,%ebx + movdqa %xmm7,%xmm8 + addl 56(%rsp),%edx + andl %ecx,%edi + andl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movl %eax,%esi + xorl %ebx,%eax + addl 60(%rsp),%ecx + andl %ebx,%esi + andl %eax,%edi + rorl $7,%ebp + addl %esi,%ecx + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movl %ebp,%edi + pxor %xmm4,%xmm0 +.byte 102,68,15,58,15,198,8 + xorl %eax,%ebp + addl 0(%rsp),%ebx + andl %eax,%edi + pxor %xmm1,%xmm0 + andl %ebp,%esi + rorl $7,%edx + movdqa %xmm9,%xmm10 + paddd %xmm7,%xmm9 + addl %edi,%ebx + movl %ecx,%edi + pxor %xmm8,%xmm0 + roll $5,%ecx + addl %esi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movdqa %xmm0,%xmm8 + movdqa %xmm9,48(%rsp) + movl %edx,%esi + xorl %ebp,%edx + addl 4(%rsp),%eax + andl %ebp,%esi + pslld $2,%xmm0 + andl %edx,%edi + rorl $7,%ecx + psrld $30,%xmm8 + addl %esi,%eax + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %ebp,%edx + addl %ebx,%eax + por %xmm8,%xmm0 + movl %ecx,%edi + xorl %edx,%ecx + movdqa %xmm0,%xmm9 + addl 8(%rsp),%ebp + andl %edx,%edi + andl %ecx,%esi + rorl $7,%ebx + addl %edi,%ebp + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movl %ebx,%esi + xorl %ecx,%ebx + addl 12(%rsp),%edx + andl %ecx,%esi + andl %ebx,%edi + rorl $7,%eax + addl %esi,%edx + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movl %eax,%edi + pxor %xmm5,%xmm1 +.byte 102,68,15,58,15,207,8 + xorl %ebx,%eax + addl 16(%rsp),%ecx + andl %ebx,%edi + pxor %xmm2,%xmm1 + andl %eax,%esi + rorl $7,%ebp + movdqa %xmm10,%xmm8 + paddd %xmm0,%xmm10 + addl %edi,%ecx + movl %edx,%edi + pxor %xmm9,%xmm1 + roll $5,%edx + addl %esi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movdqa %xmm1,%xmm9 + movdqa %xmm10,0(%rsp) + movl %ebp,%esi + xorl %eax,%ebp + addl 20(%rsp),%ebx + andl %eax,%esi + pslld $2,%xmm1 + andl %ebp,%edi + rorl $7,%edx + psrld $30,%xmm9 + addl %esi,%ebx + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + por %xmm9,%xmm1 + movl %edx,%edi + xorl %ebp,%edx + movdqa %xmm1,%xmm10 + addl 24(%rsp),%eax + andl %ebp,%edi + andl %edx,%esi + rorl $7,%ecx + addl %edi,%eax + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %ebp,%edx + addl %ebx,%eax + movl %ecx,%esi + xorl %edx,%ecx + addl 28(%rsp),%ebp + andl %edx,%esi + andl %ecx,%edi + rorl $7,%ebx + addl %esi,%ebp + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movl %ebx,%edi + pxor %xmm6,%xmm2 +.byte 102,68,15,58,15,208,8 + xorl %ecx,%ebx + addl 32(%rsp),%edx + andl %ecx,%edi + pxor %xmm3,%xmm2 + andl %ebx,%esi + rorl $7,%eax + movdqa %xmm8,%xmm9 + paddd %xmm1,%xmm8 + addl %edi,%edx + movl %ebp,%edi + pxor %xmm10,%xmm2 + roll $5,%ebp + addl %esi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movdqa %xmm2,%xmm10 + movdqa %xmm8,16(%rsp) + movl %eax,%esi + xorl %ebx,%eax + addl 36(%rsp),%ecx + andl %ebx,%esi + pslld $2,%xmm2 + andl %eax,%edi + rorl $7,%ebp + psrld $30,%xmm10 + addl %esi,%ecx + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + por %xmm10,%xmm2 + movl %ebp,%edi + xorl %eax,%ebp + movdqa %xmm2,%xmm8 + addl 40(%rsp),%ebx + andl %eax,%edi + andl %ebp,%esi + rorl $7,%edx + addl %edi,%ebx + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movl %edx,%esi + xorl %ebp,%edx + addl 44(%rsp),%eax + andl %ebp,%esi + andl %edx,%edi + rorl $7,%ecx + addl %esi,%eax + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %ebp,%edx + addl %ebx,%eax + addl 48(%rsp),%ebp + pxor %xmm7,%xmm3 +.byte 102,68,15,58,15,193,8 + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + pxor %xmm4,%xmm3 + xorl %ecx,%esi + addl %eax,%ebp + movdqa %xmm9,%xmm10 + paddd %xmm2,%xmm9 + rorl $7,%ebx + addl %esi,%ebp + pxor %xmm8,%xmm3 + addl 52(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm3,%xmm8 + movdqa %xmm9,32(%rsp) + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm3 + addl 56(%rsp),%ecx + xorl %ebx,%esi + psrld $30,%xmm8 + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + por %xmm8,%xmm3 + addl 60(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 0(%rsp),%eax + paddd %xmm3,%xmm10 + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + movdqa %xmm10,48(%rsp) + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 4(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 8(%rsp),%edx + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + addl 12(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + cmpq %r10,%r9 + je L$done_ssse3 + movdqa 64(%r11),%xmm6 + movdqa 0(%r11),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %eax,%esi +.byte 102,15,56,0,206 + movl %ecx,%edi + roll $5,%ecx + paddd %xmm9,%xmm0 + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + movdqa %xmm0,0(%rsp) + addl 20(%rsp),%eax + xorl %ebp,%edi + psubd %xmm9,%xmm0 + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 24(%rsp),%ebp + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + addl 28(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 32(%rsp),%ecx + xorl %ebx,%esi +.byte 102,15,56,0,214 + movl %edx,%edi + roll $5,%edx + paddd %xmm9,%xmm1 + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + movdqa %xmm1,16(%rsp) + addl 36(%rsp),%ebx + xorl %eax,%edi + psubd %xmm9,%xmm1 + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 40(%rsp),%eax + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 44(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 48(%rsp),%edx + xorl %ecx,%esi +.byte 102,15,56,0,222 + movl %ebp,%edi + roll $5,%ebp + paddd %xmm9,%xmm2 + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + movdqa %xmm2,32(%rsp) + addl 52(%rsp),%ecx + xorl %ebx,%edi + psubd %xmm9,%xmm2 + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 56(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 60(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + jmp L$oop_ssse3 + +.p2align 4 +L$done_ssse3: + addl 16(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 20(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 24(%rsp),%ebp + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + addl 28(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 32(%rsp),%ecx + xorl %ebx,%esi + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + addl 36(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 40(%rsp),%eax + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 44(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 48(%rsp),%edx + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + addl 52(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 56(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 60(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + leaq 64(%rsp),%rsi + movq 0(%rsi),%r12 + movq 8(%rsi),%rbp + movq 16(%rsi),%rbx + leaq 24(%rsi),%rsp +L$epilogue_ssse3: + retq + +.p2align 6 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 diff --git a/Libraries/libressl/crypto/sha/sha1-masm-x86_64.S b/Libraries/libressl/crypto/sha/sha1-masm-x86_64.S new file mode 100644 index 000000000..f520b5a86 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1-masm-x86_64.S @@ -0,0 +1,2746 @@ +; 1 "crypto/sha/sha1-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/sha/sha1-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/sha/sha1-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' +EXTERN OPENSSL_ia32cap_P:NEAR + + +PUBLIC sha1_block_data_order + +ALIGN 16 +sha1_block_data_order PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha1_block_data_order:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + + mov r9d,DWORD PTR[((OPENSSL_ia32cap_P+0))] + mov r8d,DWORD PTR[((OPENSSL_ia32cap_P+4))] + test r8d,(1 SHL 9) + jz $L$ialu + jmp _ssse3_shortcut + +ALIGN 16 +$L$ialu:: + push rbx + push rbp + push r12 + push r13 + mov r11,rsp + mov r8,rdi + sub rsp,72 + mov r9,rsi + and rsp,-64 + mov r10,rdx + mov QWORD PTR[64+rsp],r11 +$L$prologue:: + + mov esi,DWORD PTR[r8] + mov edi,DWORD PTR[4+r8] + mov r11d,DWORD PTR[8+r8] + mov r12d,DWORD PTR[12+r8] + mov r13d,DWORD PTR[16+r8] + jmp $L$loop + +ALIGN 16 +$L$loop:: + mov edx,DWORD PTR[r9] + bswap edx + mov DWORD PTR[rsp],edx + mov eax,r11d + mov ebp,DWORD PTR[4+r9] + mov ecx,esi + xor eax,r12d + bswap ebp + rol ecx,5 + lea r13d,DWORD PTR[1518500249+r13*1+rdx] + and eax,edi + mov DWORD PTR[4+rsp],ebp + add r13d,ecx + xor eax,r12d + rol edi,30 + add r13d,eax + mov eax,edi + mov edx,DWORD PTR[8+r9] + mov ecx,r13d + xor eax,r11d + bswap edx + rol ecx,5 + lea r12d,DWORD PTR[1518500249+r12*1+rbp] + and eax,esi + mov DWORD PTR[8+rsp],edx + add r12d,ecx + xor eax,r11d + rol esi,30 + add r12d,eax + mov eax,esi + mov ebp,DWORD PTR[12+r9] + mov ecx,r12d + xor eax,edi + bswap ebp + rol ecx,5 + lea r11d,DWORD PTR[1518500249+r11*1+rdx] + and eax,r13d + mov DWORD PTR[12+rsp],ebp + add r11d,ecx + xor eax,edi + rol r13d,30 + add r11d,eax + mov eax,r13d + mov edx,DWORD PTR[16+r9] + mov ecx,r11d + xor eax,esi + bswap edx + rol ecx,5 + lea edi,DWORD PTR[1518500249+rdi*1+rbp] + and eax,r12d + mov DWORD PTR[16+rsp],edx + add edi,ecx + xor eax,esi + rol r12d,30 + add edi,eax + mov eax,r12d + mov ebp,DWORD PTR[20+r9] + mov ecx,edi + xor eax,r13d + bswap ebp + rol ecx,5 + lea esi,DWORD PTR[1518500249+rsi*1+rdx] + and eax,r11d + mov DWORD PTR[20+rsp],ebp + add esi,ecx + xor eax,r13d + rol r11d,30 + add esi,eax + mov eax,r11d + mov edx,DWORD PTR[24+r9] + mov ecx,esi + xor eax,r12d + bswap edx + rol ecx,5 + lea r13d,DWORD PTR[1518500249+r13*1+rbp] + and eax,edi + mov DWORD PTR[24+rsp],edx + add r13d,ecx + xor eax,r12d + rol edi,30 + add r13d,eax + mov eax,edi + mov ebp,DWORD PTR[28+r9] + mov ecx,r13d + xor eax,r11d + bswap ebp + rol ecx,5 + lea r12d,DWORD PTR[1518500249+r12*1+rdx] + and eax,esi + mov DWORD PTR[28+rsp],ebp + add r12d,ecx + xor eax,r11d + rol esi,30 + add r12d,eax + mov eax,esi + mov edx,DWORD PTR[32+r9] + mov ecx,r12d + xor eax,edi + bswap edx + rol ecx,5 + lea r11d,DWORD PTR[1518500249+r11*1+rbp] + and eax,r13d + mov DWORD PTR[32+rsp],edx + add r11d,ecx + xor eax,edi + rol r13d,30 + add r11d,eax + mov eax,r13d + mov ebp,DWORD PTR[36+r9] + mov ecx,r11d + xor eax,esi + bswap ebp + rol ecx,5 + lea edi,DWORD PTR[1518500249+rdi*1+rdx] + and eax,r12d + mov DWORD PTR[36+rsp],ebp + add edi,ecx + xor eax,esi + rol r12d,30 + add edi,eax + mov eax,r12d + mov edx,DWORD PTR[40+r9] + mov ecx,edi + xor eax,r13d + bswap edx + rol ecx,5 + lea esi,DWORD PTR[1518500249+rsi*1+rbp] + and eax,r11d + mov DWORD PTR[40+rsp],edx + add esi,ecx + xor eax,r13d + rol r11d,30 + add esi,eax + mov eax,r11d + mov ebp,DWORD PTR[44+r9] + mov ecx,esi + xor eax,r12d + bswap ebp + rol ecx,5 + lea r13d,DWORD PTR[1518500249+r13*1+rdx] + and eax,edi + mov DWORD PTR[44+rsp],ebp + add r13d,ecx + xor eax,r12d + rol edi,30 + add r13d,eax + mov eax,edi + mov edx,DWORD PTR[48+r9] + mov ecx,r13d + xor eax,r11d + bswap edx + rol ecx,5 + lea r12d,DWORD PTR[1518500249+r12*1+rbp] + and eax,esi + mov DWORD PTR[48+rsp],edx + add r12d,ecx + xor eax,r11d + rol esi,30 + add r12d,eax + mov eax,esi + mov ebp,DWORD PTR[52+r9] + mov ecx,r12d + xor eax,edi + bswap ebp + rol ecx,5 + lea r11d,DWORD PTR[1518500249+r11*1+rdx] + and eax,r13d + mov DWORD PTR[52+rsp],ebp + add r11d,ecx + xor eax,edi + rol r13d,30 + add r11d,eax + mov eax,r13d + mov edx,DWORD PTR[56+r9] + mov ecx,r11d + xor eax,esi + bswap edx + rol ecx,5 + lea edi,DWORD PTR[1518500249+rdi*1+rbp] + and eax,r12d + mov DWORD PTR[56+rsp],edx + add edi,ecx + xor eax,esi + rol r12d,30 + add edi,eax + mov eax,r12d + mov ebp,DWORD PTR[60+r9] + mov ecx,edi + xor eax,r13d + bswap ebp + rol ecx,5 + lea esi,DWORD PTR[1518500249+rsi*1+rdx] + and eax,r11d + mov DWORD PTR[60+rsp],ebp + add esi,ecx + xor eax,r13d + rol r11d,30 + add esi,eax + mov edx,DWORD PTR[rsp] + mov eax,r11d + mov ecx,esi + xor edx,DWORD PTR[8+rsp] + xor eax,r12d + rol ecx,5 + xor edx,DWORD PTR[32+rsp] + and eax,edi + lea r13d,DWORD PTR[1518500249+r13*1+rbp] + xor edx,DWORD PTR[52+rsp] + xor eax,r12d + rol edx,1 + add r13d,ecx + rol edi,30 + mov DWORD PTR[rsp],edx + add r13d,eax + mov ebp,DWORD PTR[4+rsp] + mov eax,edi + mov ecx,r13d + xor ebp,DWORD PTR[12+rsp] + xor eax,r11d + rol ecx,5 + xor ebp,DWORD PTR[36+rsp] + and eax,esi + lea r12d,DWORD PTR[1518500249+r12*1+rdx] + xor ebp,DWORD PTR[56+rsp] + xor eax,r11d + rol ebp,1 + add r12d,ecx + rol esi,30 + mov DWORD PTR[4+rsp],ebp + add r12d,eax + mov edx,DWORD PTR[8+rsp] + mov eax,esi + mov ecx,r12d + xor edx,DWORD PTR[16+rsp] + xor eax,edi + rol ecx,5 + xor edx,DWORD PTR[40+rsp] + and eax,r13d + lea r11d,DWORD PTR[1518500249+r11*1+rbp] + xor edx,DWORD PTR[60+rsp] + xor eax,edi + rol edx,1 + add r11d,ecx + rol r13d,30 + mov DWORD PTR[8+rsp],edx + add r11d,eax + mov ebp,DWORD PTR[12+rsp] + mov eax,r13d + mov ecx,r11d + xor ebp,DWORD PTR[20+rsp] + xor eax,esi + rol ecx,5 + xor ebp,DWORD PTR[44+rsp] + and eax,r12d + lea edi,DWORD PTR[1518500249+rdi*1+rdx] + xor ebp,DWORD PTR[rsp] + xor eax,esi + rol ebp,1 + add edi,ecx + rol r12d,30 + mov DWORD PTR[12+rsp],ebp + add edi,eax + mov edx,DWORD PTR[16+rsp] + mov eax,r12d + mov ecx,edi + xor edx,DWORD PTR[24+rsp] + xor eax,r13d + rol ecx,5 + xor edx,DWORD PTR[48+rsp] + and eax,r11d + lea esi,DWORD PTR[1518500249+rsi*1+rbp] + xor edx,DWORD PTR[4+rsp] + xor eax,r13d + rol edx,1 + add esi,ecx + rol r11d,30 + mov DWORD PTR[16+rsp],edx + add esi,eax + mov ebp,DWORD PTR[20+rsp] + mov eax,r11d + mov ecx,esi + xor ebp,DWORD PTR[28+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[1859775393+r13*1+rdx] + xor ebp,DWORD PTR[52+rsp] + xor eax,r12d + add r13d,ecx + xor ebp,DWORD PTR[8+rsp] + rol edi,30 + add r13d,eax + rol ebp,1 + mov DWORD PTR[20+rsp],ebp + mov edx,DWORD PTR[24+rsp] + mov eax,edi + mov ecx,r13d + xor edx,DWORD PTR[32+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[1859775393+r12*1+rbp] + xor edx,DWORD PTR[56+rsp] + xor eax,r11d + add r12d,ecx + xor edx,DWORD PTR[12+rsp] + rol esi,30 + add r12d,eax + rol edx,1 + mov DWORD PTR[24+rsp],edx + mov ebp,DWORD PTR[28+rsp] + mov eax,esi + mov ecx,r12d + xor ebp,DWORD PTR[36+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[1859775393+r11*1+rdx] + xor ebp,DWORD PTR[60+rsp] + xor eax,edi + add r11d,ecx + xor ebp,DWORD PTR[16+rsp] + rol r13d,30 + add r11d,eax + rol ebp,1 + mov DWORD PTR[28+rsp],ebp + mov edx,DWORD PTR[32+rsp] + mov eax,r13d + mov ecx,r11d + xor edx,DWORD PTR[40+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[1859775393+rdi*1+rbp] + xor edx,DWORD PTR[rsp] + xor eax,esi + add edi,ecx + xor edx,DWORD PTR[20+rsp] + rol r12d,30 + add edi,eax + rol edx,1 + mov DWORD PTR[32+rsp],edx + mov ebp,DWORD PTR[36+rsp] + mov eax,r12d + mov ecx,edi + xor ebp,DWORD PTR[44+rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[1859775393+rsi*1+rdx] + xor ebp,DWORD PTR[4+rsp] + xor eax,r13d + add esi,ecx + xor ebp,DWORD PTR[24+rsp] + rol r11d,30 + add esi,eax + rol ebp,1 + mov DWORD PTR[36+rsp],ebp + mov edx,DWORD PTR[40+rsp] + mov eax,r11d + mov ecx,esi + xor edx,DWORD PTR[48+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[1859775393+r13*1+rbp] + xor edx,DWORD PTR[8+rsp] + xor eax,r12d + add r13d,ecx + xor edx,DWORD PTR[28+rsp] + rol edi,30 + add r13d,eax + rol edx,1 + mov DWORD PTR[40+rsp],edx + mov ebp,DWORD PTR[44+rsp] + mov eax,edi + mov ecx,r13d + xor ebp,DWORD PTR[52+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[1859775393+r12*1+rdx] + xor ebp,DWORD PTR[12+rsp] + xor eax,r11d + add r12d,ecx + xor ebp,DWORD PTR[32+rsp] + rol esi,30 + add r12d,eax + rol ebp,1 + mov DWORD PTR[44+rsp],ebp + mov edx,DWORD PTR[48+rsp] + mov eax,esi + mov ecx,r12d + xor edx,DWORD PTR[56+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[1859775393+r11*1+rbp] + xor edx,DWORD PTR[16+rsp] + xor eax,edi + add r11d,ecx + xor edx,DWORD PTR[36+rsp] + rol r13d,30 + add r11d,eax + rol edx,1 + mov DWORD PTR[48+rsp],edx + mov ebp,DWORD PTR[52+rsp] + mov eax,r13d + mov ecx,r11d + xor ebp,DWORD PTR[60+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[1859775393+rdi*1+rdx] + xor ebp,DWORD PTR[20+rsp] + xor eax,esi + add edi,ecx + xor ebp,DWORD PTR[40+rsp] + rol r12d,30 + add edi,eax + rol ebp,1 + mov DWORD PTR[52+rsp],ebp + mov edx,DWORD PTR[56+rsp] + mov eax,r12d + mov ecx,edi + xor edx,DWORD PTR[rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[1859775393+rsi*1+rbp] + xor edx,DWORD PTR[24+rsp] + xor eax,r13d + add esi,ecx + xor edx,DWORD PTR[44+rsp] + rol r11d,30 + add esi,eax + rol edx,1 + mov DWORD PTR[56+rsp],edx + mov ebp,DWORD PTR[60+rsp] + mov eax,r11d + mov ecx,esi + xor ebp,DWORD PTR[4+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[1859775393+r13*1+rdx] + xor ebp,DWORD PTR[28+rsp] + xor eax,r12d + add r13d,ecx + xor ebp,DWORD PTR[48+rsp] + rol edi,30 + add r13d,eax + rol ebp,1 + mov DWORD PTR[60+rsp],ebp + mov edx,DWORD PTR[rsp] + mov eax,edi + mov ecx,r13d + xor edx,DWORD PTR[8+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[1859775393+r12*1+rbp] + xor edx,DWORD PTR[32+rsp] + xor eax,r11d + add r12d,ecx + xor edx,DWORD PTR[52+rsp] + rol esi,30 + add r12d,eax + rol edx,1 + mov DWORD PTR[rsp],edx + mov ebp,DWORD PTR[4+rsp] + mov eax,esi + mov ecx,r12d + xor ebp,DWORD PTR[12+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[1859775393+r11*1+rdx] + xor ebp,DWORD PTR[36+rsp] + xor eax,edi + add r11d,ecx + xor ebp,DWORD PTR[56+rsp] + rol r13d,30 + add r11d,eax + rol ebp,1 + mov DWORD PTR[4+rsp],ebp + mov edx,DWORD PTR[8+rsp] + mov eax,r13d + mov ecx,r11d + xor edx,DWORD PTR[16+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[1859775393+rdi*1+rbp] + xor edx,DWORD PTR[40+rsp] + xor eax,esi + add edi,ecx + xor edx,DWORD PTR[60+rsp] + rol r12d,30 + add edi,eax + rol edx,1 + mov DWORD PTR[8+rsp],edx + mov ebp,DWORD PTR[12+rsp] + mov eax,r12d + mov ecx,edi + xor ebp,DWORD PTR[20+rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[1859775393+rsi*1+rdx] + xor ebp,DWORD PTR[44+rsp] + xor eax,r13d + add esi,ecx + xor ebp,DWORD PTR[rsp] + rol r11d,30 + add esi,eax + rol ebp,1 + mov DWORD PTR[12+rsp],ebp + mov edx,DWORD PTR[16+rsp] + mov eax,r11d + mov ecx,esi + xor edx,DWORD PTR[24+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[1859775393+r13*1+rbp] + xor edx,DWORD PTR[48+rsp] + xor eax,r12d + add r13d,ecx + xor edx,DWORD PTR[4+rsp] + rol edi,30 + add r13d,eax + rol edx,1 + mov DWORD PTR[16+rsp],edx + mov ebp,DWORD PTR[20+rsp] + mov eax,edi + mov ecx,r13d + xor ebp,DWORD PTR[28+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[1859775393+r12*1+rdx] + xor ebp,DWORD PTR[52+rsp] + xor eax,r11d + add r12d,ecx + xor ebp,DWORD PTR[8+rsp] + rol esi,30 + add r12d,eax + rol ebp,1 + mov DWORD PTR[20+rsp],ebp + mov edx,DWORD PTR[24+rsp] + mov eax,esi + mov ecx,r12d + xor edx,DWORD PTR[32+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[1859775393+r11*1+rbp] + xor edx,DWORD PTR[56+rsp] + xor eax,edi + add r11d,ecx + xor edx,DWORD PTR[12+rsp] + rol r13d,30 + add r11d,eax + rol edx,1 + mov DWORD PTR[24+rsp],edx + mov ebp,DWORD PTR[28+rsp] + mov eax,r13d + mov ecx,r11d + xor ebp,DWORD PTR[36+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[1859775393+rdi*1+rdx] + xor ebp,DWORD PTR[60+rsp] + xor eax,esi + add edi,ecx + xor ebp,DWORD PTR[16+rsp] + rol r12d,30 + add edi,eax + rol ebp,1 + mov DWORD PTR[28+rsp],ebp + mov edx,DWORD PTR[32+rsp] + mov eax,r12d + mov ecx,edi + xor edx,DWORD PTR[40+rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[1859775393+rsi*1+rbp] + xor edx,DWORD PTR[rsp] + xor eax,r13d + add esi,ecx + xor edx,DWORD PTR[20+rsp] + rol r11d,30 + add esi,eax + rol edx,1 + mov DWORD PTR[32+rsp],edx + mov ebp,DWORD PTR[36+rsp] + mov eax,r11d + mov ebx,r11d + xor ebp,DWORD PTR[44+rsp] + and eax,r12d + mov ecx,esi + xor ebp,DWORD PTR[4+rsp] + xor ebx,r12d + lea r13d,DWORD PTR[((-1894007588))+r13*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[24+rsp] + add r13d,eax + and ebx,edi + rol ebp,1 + add r13d,ebx + rol edi,30 + mov DWORD PTR[36+rsp],ebp + add r13d,ecx + mov edx,DWORD PTR[40+rsp] + mov eax,edi + mov ebx,edi + xor edx,DWORD PTR[48+rsp] + and eax,r11d + mov ecx,r13d + xor edx,DWORD PTR[8+rsp] + xor ebx,r11d + lea r12d,DWORD PTR[((-1894007588))+r12*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[28+rsp] + add r12d,eax + and ebx,esi + rol edx,1 + add r12d,ebx + rol esi,30 + mov DWORD PTR[40+rsp],edx + add r12d,ecx + mov ebp,DWORD PTR[44+rsp] + mov eax,esi + mov ebx,esi + xor ebp,DWORD PTR[52+rsp] + and eax,edi + mov ecx,r12d + xor ebp,DWORD PTR[12+rsp] + xor ebx,edi + lea r11d,DWORD PTR[((-1894007588))+r11*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[32+rsp] + add r11d,eax + and ebx,r13d + rol ebp,1 + add r11d,ebx + rol r13d,30 + mov DWORD PTR[44+rsp],ebp + add r11d,ecx + mov edx,DWORD PTR[48+rsp] + mov eax,r13d + mov ebx,r13d + xor edx,DWORD PTR[56+rsp] + and eax,esi + mov ecx,r11d + xor edx,DWORD PTR[16+rsp] + xor ebx,esi + lea edi,DWORD PTR[((-1894007588))+rdi*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[36+rsp] + add edi,eax + and ebx,r12d + rol edx,1 + add edi,ebx + rol r12d,30 + mov DWORD PTR[48+rsp],edx + add edi,ecx + mov ebp,DWORD PTR[52+rsp] + mov eax,r12d + mov ebx,r12d + xor ebp,DWORD PTR[60+rsp] + and eax,r13d + mov ecx,edi + xor ebp,DWORD PTR[20+rsp] + xor ebx,r13d + lea esi,DWORD PTR[((-1894007588))+rsi*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[40+rsp] + add esi,eax + and ebx,r11d + rol ebp,1 + add esi,ebx + rol r11d,30 + mov DWORD PTR[52+rsp],ebp + add esi,ecx + mov edx,DWORD PTR[56+rsp] + mov eax,r11d + mov ebx,r11d + xor edx,DWORD PTR[rsp] + and eax,r12d + mov ecx,esi + xor edx,DWORD PTR[24+rsp] + xor ebx,r12d + lea r13d,DWORD PTR[((-1894007588))+r13*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[44+rsp] + add r13d,eax + and ebx,edi + rol edx,1 + add r13d,ebx + rol edi,30 + mov DWORD PTR[56+rsp],edx + add r13d,ecx + mov ebp,DWORD PTR[60+rsp] + mov eax,edi + mov ebx,edi + xor ebp,DWORD PTR[4+rsp] + and eax,r11d + mov ecx,r13d + xor ebp,DWORD PTR[28+rsp] + xor ebx,r11d + lea r12d,DWORD PTR[((-1894007588))+r12*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[48+rsp] + add r12d,eax + and ebx,esi + rol ebp,1 + add r12d,ebx + rol esi,30 + mov DWORD PTR[60+rsp],ebp + add r12d,ecx + mov edx,DWORD PTR[rsp] + mov eax,esi + mov ebx,esi + xor edx,DWORD PTR[8+rsp] + and eax,edi + mov ecx,r12d + xor edx,DWORD PTR[32+rsp] + xor ebx,edi + lea r11d,DWORD PTR[((-1894007588))+r11*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[52+rsp] + add r11d,eax + and ebx,r13d + rol edx,1 + add r11d,ebx + rol r13d,30 + mov DWORD PTR[rsp],edx + add r11d,ecx + mov ebp,DWORD PTR[4+rsp] + mov eax,r13d + mov ebx,r13d + xor ebp,DWORD PTR[12+rsp] + and eax,esi + mov ecx,r11d + xor ebp,DWORD PTR[36+rsp] + xor ebx,esi + lea edi,DWORD PTR[((-1894007588))+rdi*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[56+rsp] + add edi,eax + and ebx,r12d + rol ebp,1 + add edi,ebx + rol r12d,30 + mov DWORD PTR[4+rsp],ebp + add edi,ecx + mov edx,DWORD PTR[8+rsp] + mov eax,r12d + mov ebx,r12d + xor edx,DWORD PTR[16+rsp] + and eax,r13d + mov ecx,edi + xor edx,DWORD PTR[40+rsp] + xor ebx,r13d + lea esi,DWORD PTR[((-1894007588))+rsi*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[60+rsp] + add esi,eax + and ebx,r11d + rol edx,1 + add esi,ebx + rol r11d,30 + mov DWORD PTR[8+rsp],edx + add esi,ecx + mov ebp,DWORD PTR[12+rsp] + mov eax,r11d + mov ebx,r11d + xor ebp,DWORD PTR[20+rsp] + and eax,r12d + mov ecx,esi + xor ebp,DWORD PTR[44+rsp] + xor ebx,r12d + lea r13d,DWORD PTR[((-1894007588))+r13*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[rsp] + add r13d,eax + and ebx,edi + rol ebp,1 + add r13d,ebx + rol edi,30 + mov DWORD PTR[12+rsp],ebp + add r13d,ecx + mov edx,DWORD PTR[16+rsp] + mov eax,edi + mov ebx,edi + xor edx,DWORD PTR[24+rsp] + and eax,r11d + mov ecx,r13d + xor edx,DWORD PTR[48+rsp] + xor ebx,r11d + lea r12d,DWORD PTR[((-1894007588))+r12*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[4+rsp] + add r12d,eax + and ebx,esi + rol edx,1 + add r12d,ebx + rol esi,30 + mov DWORD PTR[16+rsp],edx + add r12d,ecx + mov ebp,DWORD PTR[20+rsp] + mov eax,esi + mov ebx,esi + xor ebp,DWORD PTR[28+rsp] + and eax,edi + mov ecx,r12d + xor ebp,DWORD PTR[52+rsp] + xor ebx,edi + lea r11d,DWORD PTR[((-1894007588))+r11*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[8+rsp] + add r11d,eax + and ebx,r13d + rol ebp,1 + add r11d,ebx + rol r13d,30 + mov DWORD PTR[20+rsp],ebp + add r11d,ecx + mov edx,DWORD PTR[24+rsp] + mov eax,r13d + mov ebx,r13d + xor edx,DWORD PTR[32+rsp] + and eax,esi + mov ecx,r11d + xor edx,DWORD PTR[56+rsp] + xor ebx,esi + lea edi,DWORD PTR[((-1894007588))+rdi*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[12+rsp] + add edi,eax + and ebx,r12d + rol edx,1 + add edi,ebx + rol r12d,30 + mov DWORD PTR[24+rsp],edx + add edi,ecx + mov ebp,DWORD PTR[28+rsp] + mov eax,r12d + mov ebx,r12d + xor ebp,DWORD PTR[36+rsp] + and eax,r13d + mov ecx,edi + xor ebp,DWORD PTR[60+rsp] + xor ebx,r13d + lea esi,DWORD PTR[((-1894007588))+rsi*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[16+rsp] + add esi,eax + and ebx,r11d + rol ebp,1 + add esi,ebx + rol r11d,30 + mov DWORD PTR[28+rsp],ebp + add esi,ecx + mov edx,DWORD PTR[32+rsp] + mov eax,r11d + mov ebx,r11d + xor edx,DWORD PTR[40+rsp] + and eax,r12d + mov ecx,esi + xor edx,DWORD PTR[rsp] + xor ebx,r12d + lea r13d,DWORD PTR[((-1894007588))+r13*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[20+rsp] + add r13d,eax + and ebx,edi + rol edx,1 + add r13d,ebx + rol edi,30 + mov DWORD PTR[32+rsp],edx + add r13d,ecx + mov ebp,DWORD PTR[36+rsp] + mov eax,edi + mov ebx,edi + xor ebp,DWORD PTR[44+rsp] + and eax,r11d + mov ecx,r13d + xor ebp,DWORD PTR[4+rsp] + xor ebx,r11d + lea r12d,DWORD PTR[((-1894007588))+r12*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[24+rsp] + add r12d,eax + and ebx,esi + rol ebp,1 + add r12d,ebx + rol esi,30 + mov DWORD PTR[36+rsp],ebp + add r12d,ecx + mov edx,DWORD PTR[40+rsp] + mov eax,esi + mov ebx,esi + xor edx,DWORD PTR[48+rsp] + and eax,edi + mov ecx,r12d + xor edx,DWORD PTR[8+rsp] + xor ebx,edi + lea r11d,DWORD PTR[((-1894007588))+r11*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[28+rsp] + add r11d,eax + and ebx,r13d + rol edx,1 + add r11d,ebx + rol r13d,30 + mov DWORD PTR[40+rsp],edx + add r11d,ecx + mov ebp,DWORD PTR[44+rsp] + mov eax,r13d + mov ebx,r13d + xor ebp,DWORD PTR[52+rsp] + and eax,esi + mov ecx,r11d + xor ebp,DWORD PTR[12+rsp] + xor ebx,esi + lea edi,DWORD PTR[((-1894007588))+rdi*1+rdx] + rol ecx,5 + xor ebp,DWORD PTR[32+rsp] + add edi,eax + and ebx,r12d + rol ebp,1 + add edi,ebx + rol r12d,30 + mov DWORD PTR[44+rsp],ebp + add edi,ecx + mov edx,DWORD PTR[48+rsp] + mov eax,r12d + mov ebx,r12d + xor edx,DWORD PTR[56+rsp] + and eax,r13d + mov ecx,edi + xor edx,DWORD PTR[16+rsp] + xor ebx,r13d + lea esi,DWORD PTR[((-1894007588))+rsi*1+rbp] + rol ecx,5 + xor edx,DWORD PTR[36+rsp] + add esi,eax + and ebx,r11d + rol edx,1 + add esi,ebx + rol r11d,30 + mov DWORD PTR[48+rsp],edx + add esi,ecx + mov ebp,DWORD PTR[52+rsp] + mov eax,r11d + mov ecx,esi + xor ebp,DWORD PTR[60+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[((-899497514))+r13*1+rdx] + xor ebp,DWORD PTR[20+rsp] + xor eax,r12d + add r13d,ecx + xor ebp,DWORD PTR[40+rsp] + rol edi,30 + add r13d,eax + rol ebp,1 + mov DWORD PTR[52+rsp],ebp + mov edx,DWORD PTR[56+rsp] + mov eax,edi + mov ecx,r13d + xor edx,DWORD PTR[rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[((-899497514))+r12*1+rbp] + xor edx,DWORD PTR[24+rsp] + xor eax,r11d + add r12d,ecx + xor edx,DWORD PTR[44+rsp] + rol esi,30 + add r12d,eax + rol edx,1 + mov DWORD PTR[56+rsp],edx + mov ebp,DWORD PTR[60+rsp] + mov eax,esi + mov ecx,r12d + xor ebp,DWORD PTR[4+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[((-899497514))+r11*1+rdx] + xor ebp,DWORD PTR[28+rsp] + xor eax,edi + add r11d,ecx + xor ebp,DWORD PTR[48+rsp] + rol r13d,30 + add r11d,eax + rol ebp,1 + mov DWORD PTR[60+rsp],ebp + mov edx,DWORD PTR[rsp] + mov eax,r13d + mov ecx,r11d + xor edx,DWORD PTR[8+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[((-899497514))+rdi*1+rbp] + xor edx,DWORD PTR[32+rsp] + xor eax,esi + add edi,ecx + xor edx,DWORD PTR[52+rsp] + rol r12d,30 + add edi,eax + rol edx,1 + mov DWORD PTR[rsp],edx + mov ebp,DWORD PTR[4+rsp] + mov eax,r12d + mov ecx,edi + xor ebp,DWORD PTR[12+rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[((-899497514))+rsi*1+rdx] + xor ebp,DWORD PTR[36+rsp] + xor eax,r13d + add esi,ecx + xor ebp,DWORD PTR[56+rsp] + rol r11d,30 + add esi,eax + rol ebp,1 + mov DWORD PTR[4+rsp],ebp + mov edx,DWORD PTR[8+rsp] + mov eax,r11d + mov ecx,esi + xor edx,DWORD PTR[16+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[((-899497514))+r13*1+rbp] + xor edx,DWORD PTR[40+rsp] + xor eax,r12d + add r13d,ecx + xor edx,DWORD PTR[60+rsp] + rol edi,30 + add r13d,eax + rol edx,1 + mov DWORD PTR[8+rsp],edx + mov ebp,DWORD PTR[12+rsp] + mov eax,edi + mov ecx,r13d + xor ebp,DWORD PTR[20+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[((-899497514))+r12*1+rdx] + xor ebp,DWORD PTR[44+rsp] + xor eax,r11d + add r12d,ecx + xor ebp,DWORD PTR[rsp] + rol esi,30 + add r12d,eax + rol ebp,1 + mov DWORD PTR[12+rsp],ebp + mov edx,DWORD PTR[16+rsp] + mov eax,esi + mov ecx,r12d + xor edx,DWORD PTR[24+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[((-899497514))+r11*1+rbp] + xor edx,DWORD PTR[48+rsp] + xor eax,edi + add r11d,ecx + xor edx,DWORD PTR[4+rsp] + rol r13d,30 + add r11d,eax + rol edx,1 + mov DWORD PTR[16+rsp],edx + mov ebp,DWORD PTR[20+rsp] + mov eax,r13d + mov ecx,r11d + xor ebp,DWORD PTR[28+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[((-899497514))+rdi*1+rdx] + xor ebp,DWORD PTR[52+rsp] + xor eax,esi + add edi,ecx + xor ebp,DWORD PTR[8+rsp] + rol r12d,30 + add edi,eax + rol ebp,1 + mov DWORD PTR[20+rsp],ebp + mov edx,DWORD PTR[24+rsp] + mov eax,r12d + mov ecx,edi + xor edx,DWORD PTR[32+rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[((-899497514))+rsi*1+rbp] + xor edx,DWORD PTR[56+rsp] + xor eax,r13d + add esi,ecx + xor edx,DWORD PTR[12+rsp] + rol r11d,30 + add esi,eax + rol edx,1 + mov DWORD PTR[24+rsp],edx + mov ebp,DWORD PTR[28+rsp] + mov eax,r11d + mov ecx,esi + xor ebp,DWORD PTR[36+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[((-899497514))+r13*1+rdx] + xor ebp,DWORD PTR[60+rsp] + xor eax,r12d + add r13d,ecx + xor ebp,DWORD PTR[16+rsp] + rol edi,30 + add r13d,eax + rol ebp,1 + mov DWORD PTR[28+rsp],ebp + mov edx,DWORD PTR[32+rsp] + mov eax,edi + mov ecx,r13d + xor edx,DWORD PTR[40+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[((-899497514))+r12*1+rbp] + xor edx,DWORD PTR[rsp] + xor eax,r11d + add r12d,ecx + xor edx,DWORD PTR[20+rsp] + rol esi,30 + add r12d,eax + rol edx,1 + mov DWORD PTR[32+rsp],edx + mov ebp,DWORD PTR[36+rsp] + mov eax,esi + mov ecx,r12d + xor ebp,DWORD PTR[44+rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[((-899497514))+r11*1+rdx] + xor ebp,DWORD PTR[4+rsp] + xor eax,edi + add r11d,ecx + xor ebp,DWORD PTR[24+rsp] + rol r13d,30 + add r11d,eax + rol ebp,1 + mov DWORD PTR[36+rsp],ebp + mov edx,DWORD PTR[40+rsp] + mov eax,r13d + mov ecx,r11d + xor edx,DWORD PTR[48+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[((-899497514))+rdi*1+rbp] + xor edx,DWORD PTR[8+rsp] + xor eax,esi + add edi,ecx + xor edx,DWORD PTR[28+rsp] + rol r12d,30 + add edi,eax + rol edx,1 + mov DWORD PTR[40+rsp],edx + mov ebp,DWORD PTR[44+rsp] + mov eax,r12d + mov ecx,edi + xor ebp,DWORD PTR[52+rsp] + xor eax,r11d + rol ecx,5 + lea esi,DWORD PTR[((-899497514))+rsi*1+rdx] + xor ebp,DWORD PTR[12+rsp] + xor eax,r13d + add esi,ecx + xor ebp,DWORD PTR[32+rsp] + rol r11d,30 + add esi,eax + rol ebp,1 + mov DWORD PTR[44+rsp],ebp + mov edx,DWORD PTR[48+rsp] + mov eax,r11d + mov ecx,esi + xor edx,DWORD PTR[56+rsp] + xor eax,edi + rol ecx,5 + lea r13d,DWORD PTR[((-899497514))+r13*1+rbp] + xor edx,DWORD PTR[16+rsp] + xor eax,r12d + add r13d,ecx + xor edx,DWORD PTR[36+rsp] + rol edi,30 + add r13d,eax + rol edx,1 + mov DWORD PTR[48+rsp],edx + mov ebp,DWORD PTR[52+rsp] + mov eax,edi + mov ecx,r13d + xor ebp,DWORD PTR[60+rsp] + xor eax,esi + rol ecx,5 + lea r12d,DWORD PTR[((-899497514))+r12*1+rdx] + xor ebp,DWORD PTR[20+rsp] + xor eax,r11d + add r12d,ecx + xor ebp,DWORD PTR[40+rsp] + rol esi,30 + add r12d,eax + rol ebp,1 + mov edx,DWORD PTR[56+rsp] + mov eax,esi + mov ecx,r12d + xor edx,DWORD PTR[rsp] + xor eax,r13d + rol ecx,5 + lea r11d,DWORD PTR[((-899497514))+r11*1+rbp] + xor edx,DWORD PTR[24+rsp] + xor eax,edi + add r11d,ecx + xor edx,DWORD PTR[44+rsp] + rol r13d,30 + add r11d,eax + rol edx,1 + mov ebp,DWORD PTR[60+rsp] + mov eax,r13d + mov ecx,r11d + xor ebp,DWORD PTR[4+rsp] + xor eax,r12d + rol ecx,5 + lea edi,DWORD PTR[((-899497514))+rdi*1+rdx] + xor ebp,DWORD PTR[28+rsp] + xor eax,esi + add edi,ecx + xor ebp,DWORD PTR[48+rsp] + rol r12d,30 + add edi,eax + rol ebp,1 + mov eax,r12d + mov ecx,edi + xor eax,r11d + lea esi,DWORD PTR[((-899497514))+rsi*1+rbp] + rol ecx,5 + xor eax,r13d + add esi,ecx + rol r11d,30 + add esi,eax + add esi,DWORD PTR[r8] + add edi,DWORD PTR[4+r8] + add r11d,DWORD PTR[8+r8] + add r12d,DWORD PTR[12+r8] + add r13d,DWORD PTR[16+r8] + mov DWORD PTR[r8],esi + mov DWORD PTR[4+r8],edi + mov DWORD PTR[8+r8],r11d + mov DWORD PTR[12+r8],r12d + mov DWORD PTR[16+r8],r13d + + sub r10,1 + lea r9,QWORD PTR[64+r9] + jnz $L$loop + + mov rsi,QWORD PTR[64+rsp] + mov r13,QWORD PTR[rsi] + mov r12,QWORD PTR[8+rsi] + mov rbp,QWORD PTR[16+rsi] + mov rbx,QWORD PTR[24+rsi] + lea rsp,QWORD PTR[32+rsi] +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha1_block_data_order:: +sha1_block_data_order ENDP + +ALIGN 16 +sha1_block_data_order_ssse3 PROC PRIVATE + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha1_block_data_order_ssse3:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + +_ssse3_shortcut:: + push rbx + push rbp + push r12 + lea rsp,QWORD PTR[((-144))+rsp] + movaps XMMWORD PTR[(64+0)+rsp],xmm6 + movaps XMMWORD PTR[(64+16)+rsp],xmm7 + movaps XMMWORD PTR[(64+32)+rsp],xmm8 + movaps XMMWORD PTR[(64+48)+rsp],xmm9 + movaps XMMWORD PTR[(64+64)+rsp],xmm10 +$L$prologue_ssse3:: + mov r8,rdi + mov r9,rsi + mov r10,rdx + + shl r10,6 + add r10,r9 + lea r11,QWORD PTR[K_XX_XX] + + mov eax,DWORD PTR[r8] + mov ebx,DWORD PTR[4+r8] + mov ecx,DWORD PTR[8+r8] + mov edx,DWORD PTR[12+r8] + mov esi,ebx + mov ebp,DWORD PTR[16+r8] + + movdqa xmm6,XMMWORD PTR[64+r11] + movdqa xmm9,XMMWORD PTR[r11] + movdqu xmm0,XMMWORD PTR[r9] + movdqu xmm1,XMMWORD PTR[16+r9] + movdqu xmm2,XMMWORD PTR[32+r9] + movdqu xmm3,XMMWORD PTR[48+r9] +DB 102,15,56,0,198 + add r9,64 +DB 102,15,56,0,206 +DB 102,15,56,0,214 +DB 102,15,56,0,222 + paddd xmm0,xmm9 + paddd xmm1,xmm9 + paddd xmm2,xmm9 + movdqa XMMWORD PTR[rsp],xmm0 + psubd xmm0,xmm9 + movdqa XMMWORD PTR[16+rsp],xmm1 + psubd xmm1,xmm9 + movdqa XMMWORD PTR[32+rsp],xmm2 + psubd xmm2,xmm9 + jmp $L$oop_ssse3 +ALIGN 16 +$L$oop_ssse3:: + movdqa xmm4,xmm1 + add ebp,DWORD PTR[rsp] + xor ecx,edx + movdqa xmm8,xmm3 +DB 102,15,58,15,224,8 + mov edi,eax + rol eax,5 + paddd xmm9,xmm3 + and esi,ecx + xor ecx,edx + psrldq xmm8,4 + xor esi,edx + add ebp,eax + pxor xmm4,xmm0 + ror ebx,2 + add ebp,esi + pxor xmm8,xmm2 + add edx,DWORD PTR[4+rsp] + xor ebx,ecx + mov esi,ebp + rol ebp,5 + pxor xmm4,xmm8 + and edi,ebx + xor ebx,ecx + movdqa XMMWORD PTR[48+rsp],xmm9 + xor edi,ecx + add edx,ebp + movdqa xmm10,xmm4 + movdqa xmm8,xmm4 + ror eax,7 + add edx,edi + add ecx,DWORD PTR[8+rsp] + xor eax,ebx + pslldq xmm10,12 + paddd xmm4,xmm4 + mov edi,edx + rol edx,5 + and esi,eax + xor eax,ebx + psrld xmm8,31 + xor esi,ebx + add ecx,edx + movdqa xmm9,xmm10 + ror ebp,7 + add ecx,esi + psrld xmm10,30 + por xmm4,xmm8 + add ebx,DWORD PTR[12+rsp] + xor ebp,eax + mov esi,ecx + rol ecx,5 + pslld xmm9,2 + pxor xmm4,xmm10 + and edi,ebp + xor ebp,eax + movdqa xmm10,XMMWORD PTR[r11] + xor edi,eax + add ebx,ecx + pxor xmm4,xmm9 + ror edx,7 + add ebx,edi + movdqa xmm5,xmm2 + add eax,DWORD PTR[16+rsp] + xor edx,ebp + movdqa xmm9,xmm4 +DB 102,15,58,15,233,8 + mov edi,ebx + rol ebx,5 + paddd xmm10,xmm4 + and esi,edx + xor edx,ebp + psrldq xmm9,4 + xor esi,ebp + add eax,ebx + pxor xmm5,xmm1 + ror ecx,7 + add eax,esi + pxor xmm9,xmm3 + add ebp,DWORD PTR[20+rsp] + xor ecx,edx + mov esi,eax + rol eax,5 + pxor xmm5,xmm9 + and edi,ecx + xor ecx,edx + movdqa XMMWORD PTR[rsp],xmm10 + xor edi,edx + add ebp,eax + movdqa xmm8,xmm5 + movdqa xmm9,xmm5 + ror ebx,7 + add ebp,edi + add edx,DWORD PTR[24+rsp] + xor ebx,ecx + pslldq xmm8,12 + paddd xmm5,xmm5 + mov edi,ebp + rol ebp,5 + and esi,ebx + xor ebx,ecx + psrld xmm9,31 + xor esi,ecx + add edx,ebp + movdqa xmm10,xmm8 + ror eax,7 + add edx,esi + psrld xmm8,30 + por xmm5,xmm9 + add ecx,DWORD PTR[28+rsp] + xor eax,ebx + mov esi,edx + rol edx,5 + pslld xmm10,2 + pxor xmm5,xmm8 + and edi,eax + xor eax,ebx + movdqa xmm8,XMMWORD PTR[16+r11] + xor edi,ebx + add ecx,edx + pxor xmm5,xmm10 + ror ebp,7 + add ecx,edi + movdqa xmm6,xmm3 + add ebx,DWORD PTR[32+rsp] + xor ebp,eax + movdqa xmm10,xmm5 +DB 102,15,58,15,242,8 + mov edi,ecx + rol ecx,5 + paddd xmm8,xmm5 + and esi,ebp + xor ebp,eax + psrldq xmm10,4 + xor esi,eax + add ebx,ecx + pxor xmm6,xmm2 + ror edx,7 + add ebx,esi + pxor xmm10,xmm4 + add eax,DWORD PTR[36+rsp] + xor edx,ebp + mov esi,ebx + rol ebx,5 + pxor xmm6,xmm10 + and edi,edx + xor edx,ebp + movdqa XMMWORD PTR[16+rsp],xmm8 + xor edi,ebp + add eax,ebx + movdqa xmm9,xmm6 + movdqa xmm10,xmm6 + ror ecx,7 + add eax,edi + add ebp,DWORD PTR[40+rsp] + xor ecx,edx + pslldq xmm9,12 + paddd xmm6,xmm6 + mov edi,eax + rol eax,5 + and esi,ecx + xor ecx,edx + psrld xmm10,31 + xor esi,edx + add ebp,eax + movdqa xmm8,xmm9 + ror ebx,7 + add ebp,esi + psrld xmm9,30 + por xmm6,xmm10 + add edx,DWORD PTR[44+rsp] + xor ebx,ecx + mov esi,ebp + rol ebp,5 + pslld xmm8,2 + pxor xmm6,xmm9 + and edi,ebx + xor ebx,ecx + movdqa xmm9,XMMWORD PTR[16+r11] + xor edi,ecx + add edx,ebp + pxor xmm6,xmm8 + ror eax,7 + add edx,edi + movdqa xmm7,xmm4 + add ecx,DWORD PTR[48+rsp] + xor eax,ebx + movdqa xmm8,xmm6 +DB 102,15,58,15,251,8 + mov edi,edx + rol edx,5 + paddd xmm9,xmm6 + and esi,eax + xor eax,ebx + psrldq xmm8,4 + xor esi,ebx + add ecx,edx + pxor xmm7,xmm3 + ror ebp,7 + add ecx,esi + pxor xmm8,xmm5 + add ebx,DWORD PTR[52+rsp] + xor ebp,eax + mov esi,ecx + rol ecx,5 + pxor xmm7,xmm8 + and edi,ebp + xor ebp,eax + movdqa XMMWORD PTR[32+rsp],xmm9 + xor edi,eax + add ebx,ecx + movdqa xmm10,xmm7 + movdqa xmm8,xmm7 + ror edx,7 + add ebx,edi + add eax,DWORD PTR[56+rsp] + xor edx,ebp + pslldq xmm10,12 + paddd xmm7,xmm7 + mov edi,ebx + rol ebx,5 + and esi,edx + xor edx,ebp + psrld xmm8,31 + xor esi,ebp + add eax,ebx + movdqa xmm9,xmm10 + ror ecx,7 + add eax,esi + psrld xmm10,30 + por xmm7,xmm8 + add ebp,DWORD PTR[60+rsp] + xor ecx,edx + mov esi,eax + rol eax,5 + pslld xmm9,2 + pxor xmm7,xmm10 + and edi,ecx + xor ecx,edx + movdqa xmm10,XMMWORD PTR[16+r11] + xor edi,edx + add ebp,eax + pxor xmm7,xmm9 + ror ebx,7 + add ebp,edi + movdqa xmm9,xmm7 + add edx,DWORD PTR[rsp] + pxor xmm0,xmm4 +DB 102,68,15,58,15,206,8 + xor ebx,ecx + mov edi,ebp + rol ebp,5 + pxor xmm0,xmm1 + and esi,ebx + xor ebx,ecx + movdqa xmm8,xmm10 + paddd xmm10,xmm7 + xor esi,ecx + add edx,ebp + pxor xmm0,xmm9 + ror eax,7 + add edx,esi + add ecx,DWORD PTR[4+rsp] + xor eax,ebx + movdqa xmm9,xmm0 + movdqa XMMWORD PTR[48+rsp],xmm10 + mov esi,edx + rol edx,5 + and edi,eax + xor eax,ebx + pslld xmm0,2 + xor edi,ebx + add ecx,edx + psrld xmm9,30 + ror ebp,7 + add ecx,edi + add ebx,DWORD PTR[8+rsp] + xor ebp,eax + mov edi,ecx + rol ecx,5 + por xmm0,xmm9 + and esi,ebp + xor ebp,eax + movdqa xmm10,xmm0 + xor esi,eax + add ebx,ecx + ror edx,7 + add ebx,esi + add eax,DWORD PTR[12+rsp] + xor edx,ebp + mov esi,ebx + rol ebx,5 + and edi,edx + xor edx,ebp + xor edi,ebp + add eax,ebx + ror ecx,7 + add eax,edi + add ebp,DWORD PTR[16+rsp] + pxor xmm1,xmm5 +DB 102,68,15,58,15,215,8 + xor esi,edx + mov edi,eax + rol eax,5 + pxor xmm1,xmm2 + xor esi,ecx + add ebp,eax + movdqa xmm9,xmm8 + paddd xmm8,xmm0 + ror ebx,7 + add ebp,esi + pxor xmm1,xmm10 + add edx,DWORD PTR[20+rsp] + xor edi,ecx + mov esi,ebp + rol ebp,5 + movdqa xmm10,xmm1 + movdqa XMMWORD PTR[rsp],xmm8 + xor edi,ebx + add edx,ebp + ror eax,7 + add edx,edi + pslld xmm1,2 + add ecx,DWORD PTR[24+rsp] + xor esi,ebx + psrld xmm10,30 + mov edi,edx + rol edx,5 + xor esi,eax + add ecx,edx + ror ebp,7 + add ecx,esi + por xmm1,xmm10 + add ebx,DWORD PTR[28+rsp] + xor edi,eax + movdqa xmm8,xmm1 + mov esi,ecx + rol ecx,5 + xor edi,ebp + add ebx,ecx + ror edx,7 + add ebx,edi + add eax,DWORD PTR[32+rsp] + pxor xmm2,xmm6 +DB 102,68,15,58,15,192,8 + xor esi,ebp + mov edi,ebx + rol ebx,5 + pxor xmm2,xmm3 + xor esi,edx + add eax,ebx + movdqa xmm10,XMMWORD PTR[32+r11] + paddd xmm9,xmm1 + ror ecx,7 + add eax,esi + pxor xmm2,xmm8 + add ebp,DWORD PTR[36+rsp] + xor edi,edx + mov esi,eax + rol eax,5 + movdqa xmm8,xmm2 + movdqa XMMWORD PTR[16+rsp],xmm9 + xor edi,ecx + add ebp,eax + ror ebx,7 + add ebp,edi + pslld xmm2,2 + add edx,DWORD PTR[40+rsp] + xor esi,ecx + psrld xmm8,30 + mov edi,ebp + rol ebp,5 + xor esi,ebx + add edx,ebp + ror eax,7 + add edx,esi + por xmm2,xmm8 + add ecx,DWORD PTR[44+rsp] + xor edi,ebx + movdqa xmm9,xmm2 + mov esi,edx + rol edx,5 + xor edi,eax + add ecx,edx + ror ebp,7 + add ecx,edi + add ebx,DWORD PTR[48+rsp] + pxor xmm3,xmm7 +DB 102,68,15,58,15,201,8 + xor esi,eax + mov edi,ecx + rol ecx,5 + pxor xmm3,xmm4 + xor esi,ebp + add ebx,ecx + movdqa xmm8,xmm10 + paddd xmm10,xmm2 + ror edx,7 + add ebx,esi + pxor xmm3,xmm9 + add eax,DWORD PTR[52+rsp] + xor edi,ebp + mov esi,ebx + rol ebx,5 + movdqa xmm9,xmm3 + movdqa XMMWORD PTR[32+rsp],xmm10 + xor edi,edx + add eax,ebx + ror ecx,7 + add eax,edi + pslld xmm3,2 + add ebp,DWORD PTR[56+rsp] + xor esi,edx + psrld xmm9,30 + mov edi,eax + rol eax,5 + xor esi,ecx + add ebp,eax + ror ebx,7 + add ebp,esi + por xmm3,xmm9 + add edx,DWORD PTR[60+rsp] + xor edi,ecx + movdqa xmm10,xmm3 + mov esi,ebp + rol ebp,5 + xor edi,ebx + add edx,ebp + ror eax,7 + add edx,edi + add ecx,DWORD PTR[rsp] + pxor xmm4,xmm0 +DB 102,68,15,58,15,210,8 + xor esi,ebx + mov edi,edx + rol edx,5 + pxor xmm4,xmm5 + xor esi,eax + add ecx,edx + movdqa xmm9,xmm8 + paddd xmm8,xmm3 + ror ebp,7 + add ecx,esi + pxor xmm4,xmm10 + add ebx,DWORD PTR[4+rsp] + xor edi,eax + mov esi,ecx + rol ecx,5 + movdqa xmm10,xmm4 + movdqa XMMWORD PTR[48+rsp],xmm8 + xor edi,ebp + add ebx,ecx + ror edx,7 + add ebx,edi + pslld xmm4,2 + add eax,DWORD PTR[8+rsp] + xor esi,ebp + psrld xmm10,30 + mov edi,ebx + rol ebx,5 + xor esi,edx + add eax,ebx + ror ecx,7 + add eax,esi + por xmm4,xmm10 + add ebp,DWORD PTR[12+rsp] + xor edi,edx + movdqa xmm8,xmm4 + mov esi,eax + rol eax,5 + xor edi,ecx + add ebp,eax + ror ebx,7 + add ebp,edi + add edx,DWORD PTR[16+rsp] + pxor xmm5,xmm1 +DB 102,68,15,58,15,195,8 + xor esi,ecx + mov edi,ebp + rol ebp,5 + pxor xmm5,xmm6 + xor esi,ebx + add edx,ebp + movdqa xmm10,xmm9 + paddd xmm9,xmm4 + ror eax,7 + add edx,esi + pxor xmm5,xmm8 + add ecx,DWORD PTR[20+rsp] + xor edi,ebx + mov esi,edx + rol edx,5 + movdqa xmm8,xmm5 + movdqa XMMWORD PTR[rsp],xmm9 + xor edi,eax + add ecx,edx + ror ebp,7 + add ecx,edi + pslld xmm5,2 + add ebx,DWORD PTR[24+rsp] + xor esi,eax + psrld xmm8,30 + mov edi,ecx + rol ecx,5 + xor esi,ebp + add ebx,ecx + ror edx,7 + add ebx,esi + por xmm5,xmm8 + add eax,DWORD PTR[28+rsp] + xor edi,ebp + movdqa xmm9,xmm5 + mov esi,ebx + rol ebx,5 + xor edi,edx + add eax,ebx + ror ecx,7 + add eax,edi + mov edi,ecx + pxor xmm6,xmm2 +DB 102,68,15,58,15,204,8 + xor ecx,edx + add ebp,DWORD PTR[32+rsp] + and edi,edx + pxor xmm6,xmm7 + and esi,ecx + ror ebx,7 + movdqa xmm8,xmm10 + paddd xmm10,xmm5 + add ebp,edi + mov edi,eax + pxor xmm6,xmm9 + rol eax,5 + add ebp,esi + xor ecx,edx + add ebp,eax + movdqa xmm9,xmm6 + movdqa XMMWORD PTR[16+rsp],xmm10 + mov esi,ebx + xor ebx,ecx + add edx,DWORD PTR[36+rsp] + and esi,ecx + pslld xmm6,2 + and edi,ebx + ror eax,7 + psrld xmm9,30 + add edx,esi + mov esi,ebp + rol ebp,5 + add edx,edi + xor ebx,ecx + add edx,ebp + por xmm6,xmm9 + mov edi,eax + xor eax,ebx + movdqa xmm10,xmm6 + add ecx,DWORD PTR[40+rsp] + and edi,ebx + and esi,eax + ror ebp,7 + add ecx,edi + mov edi,edx + rol edx,5 + add ecx,esi + xor eax,ebx + add ecx,edx + mov esi,ebp + xor ebp,eax + add ebx,DWORD PTR[44+rsp] + and esi,eax + and edi,ebp + ror edx,7 + add ebx,esi + mov esi,ecx + rol ecx,5 + add ebx,edi + xor ebp,eax + add ebx,ecx + mov edi,edx + pxor xmm7,xmm3 +DB 102,68,15,58,15,213,8 + xor edx,ebp + add eax,DWORD PTR[48+rsp] + and edi,ebp + pxor xmm7,xmm0 + and esi,edx + ror ecx,7 + movdqa xmm9,XMMWORD PTR[48+r11] + paddd xmm8,xmm6 + add eax,edi + mov edi,ebx + pxor xmm7,xmm10 + rol ebx,5 + add eax,esi + xor edx,ebp + add eax,ebx + movdqa xmm10,xmm7 + movdqa XMMWORD PTR[32+rsp],xmm8 + mov esi,ecx + xor ecx,edx + add ebp,DWORD PTR[52+rsp] + and esi,edx + pslld xmm7,2 + and edi,ecx + ror ebx,7 + psrld xmm10,30 + add ebp,esi + mov esi,eax + rol eax,5 + add ebp,edi + xor ecx,edx + add ebp,eax + por xmm7,xmm10 + mov edi,ebx + xor ebx,ecx + movdqa xmm8,xmm7 + add edx,DWORD PTR[56+rsp] + and edi,ecx + and esi,ebx + ror eax,7 + add edx,edi + mov edi,ebp + rol ebp,5 + add edx,esi + xor ebx,ecx + add edx,ebp + mov esi,eax + xor eax,ebx + add ecx,DWORD PTR[60+rsp] + and esi,ebx + and edi,eax + ror ebp,7 + add ecx,esi + mov esi,edx + rol edx,5 + add ecx,edi + xor eax,ebx + add ecx,edx + mov edi,ebp + pxor xmm0,xmm4 +DB 102,68,15,58,15,198,8 + xor ebp,eax + add ebx,DWORD PTR[rsp] + and edi,eax + pxor xmm0,xmm1 + and esi,ebp + ror edx,7 + movdqa xmm10,xmm9 + paddd xmm9,xmm7 + add ebx,edi + mov edi,ecx + pxor xmm0,xmm8 + rol ecx,5 + add ebx,esi + xor ebp,eax + add ebx,ecx + movdqa xmm8,xmm0 + movdqa XMMWORD PTR[48+rsp],xmm9 + mov esi,edx + xor edx,ebp + add eax,DWORD PTR[4+rsp] + and esi,ebp + pslld xmm0,2 + and edi,edx + ror ecx,7 + psrld xmm8,30 + add eax,esi + mov esi,ebx + rol ebx,5 + add eax,edi + xor edx,ebp + add eax,ebx + por xmm0,xmm8 + mov edi,ecx + xor ecx,edx + movdqa xmm9,xmm0 + add ebp,DWORD PTR[8+rsp] + and edi,edx + and esi,ecx + ror ebx,7 + add ebp,edi + mov edi,eax + rol eax,5 + add ebp,esi + xor ecx,edx + add ebp,eax + mov esi,ebx + xor ebx,ecx + add edx,DWORD PTR[12+rsp] + and esi,ecx + and edi,ebx + ror eax,7 + add edx,esi + mov esi,ebp + rol ebp,5 + add edx,edi + xor ebx,ecx + add edx,ebp + mov edi,eax + pxor xmm1,xmm5 +DB 102,68,15,58,15,207,8 + xor eax,ebx + add ecx,DWORD PTR[16+rsp] + and edi,ebx + pxor xmm1,xmm2 + and esi,eax + ror ebp,7 + movdqa xmm8,xmm10 + paddd xmm10,xmm0 + add ecx,edi + mov edi,edx + pxor xmm1,xmm9 + rol edx,5 + add ecx,esi + xor eax,ebx + add ecx,edx + movdqa xmm9,xmm1 + movdqa XMMWORD PTR[rsp],xmm10 + mov esi,ebp + xor ebp,eax + add ebx,DWORD PTR[20+rsp] + and esi,eax + pslld xmm1,2 + and edi,ebp + ror edx,7 + psrld xmm9,30 + add ebx,esi + mov esi,ecx + rol ecx,5 + add ebx,edi + xor ebp,eax + add ebx,ecx + por xmm1,xmm9 + mov edi,edx + xor edx,ebp + movdqa xmm10,xmm1 + add eax,DWORD PTR[24+rsp] + and edi,ebp + and esi,edx + ror ecx,7 + add eax,edi + mov edi,ebx + rol ebx,5 + add eax,esi + xor edx,ebp + add eax,ebx + mov esi,ecx + xor ecx,edx + add ebp,DWORD PTR[28+rsp] + and esi,edx + and edi,ecx + ror ebx,7 + add ebp,esi + mov esi,eax + rol eax,5 + add ebp,edi + xor ecx,edx + add ebp,eax + mov edi,ebx + pxor xmm2,xmm6 +DB 102,68,15,58,15,208,8 + xor ebx,ecx + add edx,DWORD PTR[32+rsp] + and edi,ecx + pxor xmm2,xmm3 + and esi,ebx + ror eax,7 + movdqa xmm9,xmm8 + paddd xmm8,xmm1 + add edx,edi + mov edi,ebp + pxor xmm2,xmm10 + rol ebp,5 + add edx,esi + xor ebx,ecx + add edx,ebp + movdqa xmm10,xmm2 + movdqa XMMWORD PTR[16+rsp],xmm8 + mov esi,eax + xor eax,ebx + add ecx,DWORD PTR[36+rsp] + and esi,ebx + pslld xmm2,2 + and edi,eax + ror ebp,7 + psrld xmm10,30 + add ecx,esi + mov esi,edx + rol edx,5 + add ecx,edi + xor eax,ebx + add ecx,edx + por xmm2,xmm10 + mov edi,ebp + xor ebp,eax + movdqa xmm8,xmm2 + add ebx,DWORD PTR[40+rsp] + and edi,eax + and esi,ebp + ror edx,7 + add ebx,edi + mov edi,ecx + rol ecx,5 + add ebx,esi + xor ebp,eax + add ebx,ecx + mov esi,edx + xor edx,ebp + add eax,DWORD PTR[44+rsp] + and esi,ebp + and edi,edx + ror ecx,7 + add eax,esi + mov esi,ebx + rol ebx,5 + add eax,edi + xor edx,ebp + add eax,ebx + add ebp,DWORD PTR[48+rsp] + pxor xmm3,xmm7 +DB 102,68,15,58,15,193,8 + xor esi,edx + mov edi,eax + rol eax,5 + pxor xmm3,xmm4 + xor esi,ecx + add ebp,eax + movdqa xmm10,xmm9 + paddd xmm9,xmm2 + ror ebx,7 + add ebp,esi + pxor xmm3,xmm8 + add edx,DWORD PTR[52+rsp] + xor edi,ecx + mov esi,ebp + rol ebp,5 + movdqa xmm8,xmm3 + movdqa XMMWORD PTR[32+rsp],xmm9 + xor edi,ebx + add edx,ebp + ror eax,7 + add edx,edi + pslld xmm3,2 + add ecx,DWORD PTR[56+rsp] + xor esi,ebx + psrld xmm8,30 + mov edi,edx + rol edx,5 + xor esi,eax + add ecx,edx + ror ebp,7 + add ecx,esi + por xmm3,xmm8 + add ebx,DWORD PTR[60+rsp] + xor edi,eax + mov esi,ecx + rol ecx,5 + xor edi,ebp + add ebx,ecx + ror edx,7 + add ebx,edi + add eax,DWORD PTR[rsp] + paddd xmm10,xmm3 + xor esi,ebp + mov edi,ebx + rol ebx,5 + xor esi,edx + movdqa XMMWORD PTR[48+rsp],xmm10 + add eax,ebx + ror ecx,7 + add eax,esi + add ebp,DWORD PTR[4+rsp] + xor edi,edx + mov esi,eax + rol eax,5 + xor edi,ecx + add ebp,eax + ror ebx,7 + add ebp,edi + add edx,DWORD PTR[8+rsp] + xor esi,ecx + mov edi,ebp + rol ebp,5 + xor esi,ebx + add edx,ebp + ror eax,7 + add edx,esi + add ecx,DWORD PTR[12+rsp] + xor edi,ebx + mov esi,edx + rol edx,5 + xor edi,eax + add ecx,edx + ror ebp,7 + add ecx,edi + cmp r9,r10 + je $L$done_ssse3 + movdqa xmm6,XMMWORD PTR[64+r11] + movdqa xmm9,XMMWORD PTR[r11] + movdqu xmm0,XMMWORD PTR[r9] + movdqu xmm1,XMMWORD PTR[16+r9] + movdqu xmm2,XMMWORD PTR[32+r9] + movdqu xmm3,XMMWORD PTR[48+r9] +DB 102,15,56,0,198 + add r9,64 + add ebx,DWORD PTR[16+rsp] + xor esi,eax +DB 102,15,56,0,206 + mov edi,ecx + rol ecx,5 + paddd xmm0,xmm9 + xor esi,ebp + add ebx,ecx + ror edx,7 + add ebx,esi + movdqa XMMWORD PTR[rsp],xmm0 + add eax,DWORD PTR[20+rsp] + xor edi,ebp + psubd xmm0,xmm9 + mov esi,ebx + rol ebx,5 + xor edi,edx + add eax,ebx + ror ecx,7 + add eax,edi + add ebp,DWORD PTR[24+rsp] + xor esi,edx + mov edi,eax + rol eax,5 + xor esi,ecx + add ebp,eax + ror ebx,7 + add ebp,esi + add edx,DWORD PTR[28+rsp] + xor edi,ecx + mov esi,ebp + rol ebp,5 + xor edi,ebx + add edx,ebp + ror eax,7 + add edx,edi + add ecx,DWORD PTR[32+rsp] + xor esi,ebx +DB 102,15,56,0,214 + mov edi,edx + rol edx,5 + paddd xmm1,xmm9 + xor esi,eax + add ecx,edx + ror ebp,7 + add ecx,esi + movdqa XMMWORD PTR[16+rsp],xmm1 + add ebx,DWORD PTR[36+rsp] + xor edi,eax + psubd xmm1,xmm9 + mov esi,ecx + rol ecx,5 + xor edi,ebp + add ebx,ecx + ror edx,7 + add ebx,edi + add eax,DWORD PTR[40+rsp] + xor esi,ebp + mov edi,ebx + rol ebx,5 + xor esi,edx + add eax,ebx + ror ecx,7 + add eax,esi + add ebp,DWORD PTR[44+rsp] + xor edi,edx + mov esi,eax + rol eax,5 + xor edi,ecx + add ebp,eax + ror ebx,7 + add ebp,edi + add edx,DWORD PTR[48+rsp] + xor esi,ecx +DB 102,15,56,0,222 + mov edi,ebp + rol ebp,5 + paddd xmm2,xmm9 + xor esi,ebx + add edx,ebp + ror eax,7 + add edx,esi + movdqa XMMWORD PTR[32+rsp],xmm2 + add ecx,DWORD PTR[52+rsp] + xor edi,ebx + psubd xmm2,xmm9 + mov esi,edx + rol edx,5 + xor edi,eax + add ecx,edx + ror ebp,7 + add ecx,edi + add ebx,DWORD PTR[56+rsp] + xor esi,eax + mov edi,ecx + rol ecx,5 + xor esi,ebp + add ebx,ecx + ror edx,7 + add ebx,esi + add eax,DWORD PTR[60+rsp] + xor edi,ebp + mov esi,ebx + rol ebx,5 + xor edi,edx + add eax,ebx + ror ecx,7 + add eax,edi + add eax,DWORD PTR[r8] + add esi,DWORD PTR[4+r8] + add ecx,DWORD PTR[8+r8] + add edx,DWORD PTR[12+r8] + mov DWORD PTR[r8],eax + add ebp,DWORD PTR[16+r8] + mov DWORD PTR[4+r8],esi + mov ebx,esi + mov DWORD PTR[8+r8],ecx + mov DWORD PTR[12+r8],edx + mov DWORD PTR[16+r8],ebp + jmp $L$oop_ssse3 + +ALIGN 16 +$L$done_ssse3:: + add ebx,DWORD PTR[16+rsp] + xor esi,eax + mov edi,ecx + rol ecx,5 + xor esi,ebp + add ebx,ecx + ror edx,7 + add ebx,esi + add eax,DWORD PTR[20+rsp] + xor edi,ebp + mov esi,ebx + rol ebx,5 + xor edi,edx + add eax,ebx + ror ecx,7 + add eax,edi + add ebp,DWORD PTR[24+rsp] + xor esi,edx + mov edi,eax + rol eax,5 + xor esi,ecx + add ebp,eax + ror ebx,7 + add ebp,esi + add edx,DWORD PTR[28+rsp] + xor edi,ecx + mov esi,ebp + rol ebp,5 + xor edi,ebx + add edx,ebp + ror eax,7 + add edx,edi + add ecx,DWORD PTR[32+rsp] + xor esi,ebx + mov edi,edx + rol edx,5 + xor esi,eax + add ecx,edx + ror ebp,7 + add ecx,esi + add ebx,DWORD PTR[36+rsp] + xor edi,eax + mov esi,ecx + rol ecx,5 + xor edi,ebp + add ebx,ecx + ror edx,7 + add ebx,edi + add eax,DWORD PTR[40+rsp] + xor esi,ebp + mov edi,ebx + rol ebx,5 + xor esi,edx + add eax,ebx + ror ecx,7 + add eax,esi + add ebp,DWORD PTR[44+rsp] + xor edi,edx + mov esi,eax + rol eax,5 + xor edi,ecx + add ebp,eax + ror ebx,7 + add ebp,edi + add edx,DWORD PTR[48+rsp] + xor esi,ecx + mov edi,ebp + rol ebp,5 + xor esi,ebx + add edx,ebp + ror eax,7 + add edx,esi + add ecx,DWORD PTR[52+rsp] + xor edi,ebx + mov esi,edx + rol edx,5 + xor edi,eax + add ecx,edx + ror ebp,7 + add ecx,edi + add ebx,DWORD PTR[56+rsp] + xor esi,eax + mov edi,ecx + rol ecx,5 + xor esi,ebp + add ebx,ecx + ror edx,7 + add ebx,esi + add eax,DWORD PTR[60+rsp] + xor edi,ebp + mov esi,ebx + rol ebx,5 + xor edi,edx + add eax,ebx + ror ecx,7 + add eax,edi + add eax,DWORD PTR[r8] + add esi,DWORD PTR[4+r8] + add ecx,DWORD PTR[8+r8] + mov DWORD PTR[r8],eax + add edx,DWORD PTR[12+r8] + mov DWORD PTR[4+r8],esi + add ebp,DWORD PTR[16+r8] + mov DWORD PTR[8+r8],ecx + mov DWORD PTR[12+r8],edx + mov DWORD PTR[16+r8],ebp + movaps xmm6,XMMWORD PTR[((64+0))+rsp] + movaps xmm7,XMMWORD PTR[((64+16))+rsp] + movaps xmm8,XMMWORD PTR[((64+32))+rsp] + movaps xmm9,XMMWORD PTR[((64+48))+rsp] + movaps xmm10,XMMWORD PTR[((64+64))+rsp] + lea rsi,QWORD PTR[144+rsp] + mov r12,QWORD PTR[rsi] + mov rbp,QWORD PTR[8+rsi] + mov rbx,QWORD PTR[16+rsi] + lea rsp,QWORD PTR[24+rsi] +$L$epilogue_ssse3:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha1_block_data_order_ssse3:: +sha1_block_data_order_ssse3 ENDP +ALIGN 64 +K_XX_XX:: + DD 05a827999h,05a827999h,05a827999h,05a827999h + DD 06ed9eba1h,06ed9eba1h,06ed9eba1h,06ed9eba1h + DD 08f1bbcdch,08f1bbcdch,08f1bbcdch,08f1bbcdch + DD 0ca62c1d6h,0ca62c1d6h,0ca62c1d6h,0ca62c1d6h + DD 000010203h,004050607h,008090a0bh,00c0d0e0fh +DB 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115 +DB 102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44 +DB 32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60 +DB 97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114 +DB 103,62,0 +ALIGN 64 +EXTERN __imp_RtlVirtualUnwind:NEAR + +ALIGN 16 +se_handler PROC PRIVATE + push rsi + push rdi + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + pushfq + sub rsp,64 + + mov rax,QWORD PTR[120+r8] + mov rbx,QWORD PTR[248+r8] + + lea r10,QWORD PTR[$L$prologue] + cmp rbx,r10 + jb $L$common_seh_tail + + mov rax,QWORD PTR[152+r8] + + lea r10,QWORD PTR[$L$epilogue] + cmp rbx,r10 + jae $L$common_seh_tail + + mov rax,QWORD PTR[64+rax] + lea rax,QWORD PTR[32+rax] + + mov rbx,QWORD PTR[((-8))+rax] + mov rbp,QWORD PTR[((-16))+rax] + mov r12,QWORD PTR[((-24))+rax] + mov r13,QWORD PTR[((-32))+rax] + mov QWORD PTR[144+r8],rbx + mov QWORD PTR[160+r8],rbp + mov QWORD PTR[216+r8],r12 + mov QWORD PTR[224+r8],r13 + + jmp $L$common_seh_tail +se_handler ENDP + + +ALIGN 16 +ssse3_handler PROC PRIVATE + push rsi + push rdi + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + pushfq + sub rsp,64 + + mov rax,QWORD PTR[120+r8] + mov rbx,QWORD PTR[248+r8] + + mov rsi,QWORD PTR[8+r9] + mov r11,QWORD PTR[56+r9] + + mov r10d,DWORD PTR[r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jb $L$common_seh_tail + + mov rax,QWORD PTR[152+r8] + + mov r10d,DWORD PTR[4+r11] + lea r10,QWORD PTR[r10*1+rsi] + cmp rbx,r10 + jae $L$common_seh_tail + + lea rsi,QWORD PTR[64+rax] + lea rdi,QWORD PTR[512+r8] + mov ecx,10 + DD 0a548f3fch + lea rax,QWORD PTR[168+rax] + + mov rbx,QWORD PTR[((-8))+rax] + mov rbp,QWORD PTR[((-16))+rax] + mov r12,QWORD PTR[((-24))+rax] + mov QWORD PTR[144+r8],rbx + mov QWORD PTR[160+r8],rbp + mov QWORD PTR[216+r8],r12 + +$L$common_seh_tail:: + mov rdi,QWORD PTR[8+rax] + mov rsi,QWORD PTR[16+rax] + mov QWORD PTR[152+r8],rax + mov QWORD PTR[168+r8],rsi + mov QWORD PTR[176+r8],rdi + + mov rdi,QWORD PTR[40+r9] + mov rsi,r8 + mov ecx,154 + DD 0a548f3fch + + mov rsi,r9 + xor rcx,rcx + mov rdx,QWORD PTR[8+rsi] + mov r8,QWORD PTR[rsi] + mov r9,QWORD PTR[16+rsi] + mov r10,QWORD PTR[40+rsi] + lea r11,QWORD PTR[56+rsi] + lea r12,QWORD PTR[24+rsi] + mov QWORD PTR[32+rsp],r10 + mov QWORD PTR[40+rsp],r11 + mov QWORD PTR[48+rsp],r12 + mov QWORD PTR[56+rsp],rcx + call QWORD PTR[__imp_RtlVirtualUnwind] + + mov eax,1 + add rsp,64 + popfq + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + pop rdi + pop rsi + DB 0F3h,0C3h ;repret +ssse3_handler ENDP + +.text$ ENDS +.pdata SEGMENT READONLY ALIGN(4) +ALIGN 4 + DD imagerel $L$SEH_begin_sha1_block_data_order + DD imagerel $L$SEH_end_sha1_block_data_order + DD imagerel $L$SEH_info_sha1_block_data_order + DD imagerel $L$SEH_begin_sha1_block_data_order_ssse3 + DD imagerel $L$SEH_end_sha1_block_data_order_ssse3 + DD imagerel $L$SEH_info_sha1_block_data_order_ssse3 +.pdata ENDS +.xdata SEGMENT READONLY ALIGN(8) +ALIGN 8 +$L$SEH_info_sha1_block_data_order:: +DB 9,0,0,0 + DD imagerel se_handler +$L$SEH_info_sha1_block_data_order_ssse3:: +DB 9,0,0,0 + DD imagerel ssse3_handler + DD imagerel $L$prologue_ssse3,imagerel $L$epilogue_ssse3 + +.xdata ENDS +END + diff --git a/Libraries/libressl/crypto/sha/sha1-mingw64-x86_64.S b/Libraries/libressl/crypto/sha/sha1-mingw64-x86_64.S new file mode 100644 index 000000000..3ce9fc9ba --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1-mingw64-x86_64.S @@ -0,0 +1,2664 @@ +#include "x86_arch.h" +.text + + + +.globl sha1_block_data_order +.def sha1_block_data_order; .scl 2; .type 32; .endef +.p2align 4 +sha1_block_data_order: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_sha1_block_data_order: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + + movl OPENSSL_ia32cap_P+0(%rip),%r9d + movl OPENSSL_ia32cap_P+4(%rip),%r8d + testl $IA32CAP_MASK1_SSSE3,%r8d + jz .Lialu + jmp _ssse3_shortcut + +.p2align 4 +.Lialu: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + movq %rsp,%r11 + movq %rdi,%r8 + subq $72,%rsp + movq %rsi,%r9 + andq $-64,%rsp + movq %rdx,%r10 + movq %r11,64(%rsp) +.Lprologue: + + movl 0(%r8),%esi + movl 4(%r8),%edi + movl 8(%r8),%r11d + movl 12(%r8),%r12d + movl 16(%r8),%r13d + jmp .Lloop + +.p2align 4 +.Lloop: + movl 0(%r9),%edx + bswapl %edx + movl %edx,0(%rsp) + movl %r11d,%eax + movl 4(%r9),%ebp + movl %esi,%ecx + xorl %r12d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r13,1),%r13d + andl %edi,%eax + movl %ebp,4(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 8(%r9),%edx + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r12,1),%r12d + andl %esi,%eax + movl %edx,8(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 12(%r9),%ebp + movl %r12d,%ecx + xorl %edi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r11,1),%r11d + andl %r13d,%eax + movl %ebp,12(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 16(%r9),%edx + movl %r11d,%ecx + xorl %esi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rdi,1),%edi + andl %r12d,%eax + movl %edx,16(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 20(%r9),%ebp + movl %edi,%ecx + xorl %r13d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rsi,1),%esi + andl %r11d,%eax + movl %ebp,20(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl %r11d,%eax + movl 24(%r9),%edx + movl %esi,%ecx + xorl %r12d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r13,1),%r13d + andl %edi,%eax + movl %edx,24(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 28(%r9),%ebp + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r12,1),%r12d + andl %esi,%eax + movl %ebp,28(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 32(%r9),%edx + movl %r12d,%ecx + xorl %edi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r11,1),%r11d + andl %r13d,%eax + movl %edx,32(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 36(%r9),%ebp + movl %r11d,%ecx + xorl %esi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rdi,1),%edi + andl %r12d,%eax + movl %ebp,36(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 40(%r9),%edx + movl %edi,%ecx + xorl %r13d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rsi,1),%esi + andl %r11d,%eax + movl %edx,40(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl %r11d,%eax + movl 44(%r9),%ebp + movl %esi,%ecx + xorl %r12d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r13,1),%r13d + andl %edi,%eax + movl %ebp,44(%rsp) + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl %edi,%eax + movl 48(%r9),%edx + movl %r13d,%ecx + xorl %r11d,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%r12,1),%r12d + andl %esi,%eax + movl %edx,48(%rsp) + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl %esi,%eax + movl 52(%r9),%ebp + movl %r12d,%ecx + xorl %edi,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%r11,1),%r11d + andl %r13d,%eax + movl %ebp,52(%rsp) + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl %r13d,%eax + movl 56(%r9),%edx + movl %r11d,%ecx + xorl %esi,%eax + bswapl %edx + roll $5,%ecx + leal 1518500249(%rbp,%rdi,1),%edi + andl %r12d,%eax + movl %edx,56(%rsp) + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl %r12d,%eax + movl 60(%r9),%ebp + movl %edi,%ecx + xorl %r13d,%eax + bswapl %ebp + roll $5,%ecx + leal 1518500249(%rdx,%rsi,1),%esi + andl %r11d,%eax + movl %ebp,60(%rsp) + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 0(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 8(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 32(%rsp),%edx + andl %edi,%eax + leal 1518500249(%rbp,%r13,1),%r13d + xorl 52(%rsp),%edx + xorl %r12d,%eax + roll $1,%edx + addl %ecx,%r13d + roll $30,%edi + movl %edx,0(%rsp) + addl %eax,%r13d + movl 4(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 12(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 36(%rsp),%ebp + andl %esi,%eax + leal 1518500249(%rdx,%r12,1),%r12d + xorl 56(%rsp),%ebp + xorl %r11d,%eax + roll $1,%ebp + addl %ecx,%r12d + roll $30,%esi + movl %ebp,4(%rsp) + addl %eax,%r12d + movl 8(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 16(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + andl %r13d,%eax + leal 1518500249(%rbp,%r11,1),%r11d + xorl 60(%rsp),%edx + xorl %edi,%eax + roll $1,%edx + addl %ecx,%r11d + roll $30,%r13d + movl %edx,8(%rsp) + addl %eax,%r11d + movl 12(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 20(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + xorl 0(%rsp),%ebp + xorl %esi,%eax + roll $1,%ebp + addl %ecx,%edi + roll $30,%r12d + movl %ebp,12(%rsp) + addl %eax,%edi + movl 16(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 24(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 48(%rsp),%edx + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + xorl 4(%rsp),%edx + xorl %r13d,%eax + roll $1,%edx + addl %ecx,%esi + roll $30,%r11d + movl %edx,16(%rsp) + addl %eax,%esi + movl 20(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 28(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r13,1),%r13d + xorl 52(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 8(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 32(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r12,1),%r12d + xorl 56(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 12(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 36(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r11,1),%r11d + xorl 60(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 16(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 40(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rdi,1),%edi + xorl 0(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 20(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 44(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rsi,1),%esi + xorl 4(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 24(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,36(%rsp) + movl 40(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 48(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r13,1),%r13d + xorl 8(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 28(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,40(%rsp) + movl 44(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 52(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r12,1),%r12d + xorl 12(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 32(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,44(%rsp) + movl 48(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 56(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r11,1),%r11d + xorl 16(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 36(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,48(%rsp) + movl 52(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 60(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rdi,1),%edi + xorl 20(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 40(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,52(%rsp) + movl 56(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 0(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rsi,1),%esi + xorl 24(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 44(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,56(%rsp) + movl 60(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r13,1),%r13d + xorl 28(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 48(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,60(%rsp) + movl 0(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r12,1),%r12d + xorl 32(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 52(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,0(%rsp) + movl 4(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r11,1),%r11d + xorl 36(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 56(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,4(%rsp) + movl 8(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 16(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rdi,1),%edi + xorl 40(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 60(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,8(%rsp) + movl 12(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 20(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rsi,1),%esi + xorl 44(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 0(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,12(%rsp) + movl 16(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r13,1),%r13d + xorl 48(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 4(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,16(%rsp) + movl 20(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal 1859775393(%rdx,%r12,1),%r12d + xorl 52(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 8(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%r11,1),%r11d + xorl 56(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 12(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal 1859775393(%rdx,%rdi,1),%edi + xorl 60(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 16(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 40(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal 1859775393(%rbp,%rsi,1),%esi + xorl 0(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 20(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %r11d,%eax + movl %r11d,%ebx + xorl 44(%rsp),%ebp + andl %r12d,%eax + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%ebx + leal -1894007588(%rdx,%r13,1),%r13d + roll $5,%ecx + xorl 24(%rsp),%ebp + addl %eax,%r13d + andl %edi,%ebx + roll $1,%ebp + addl %ebx,%r13d + roll $30,%edi + movl %ebp,36(%rsp) + addl %ecx,%r13d + movl 40(%rsp),%edx + movl %edi,%eax + movl %edi,%ebx + xorl 48(%rsp),%edx + andl %r11d,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + xorl %r11d,%ebx + leal -1894007588(%rbp,%r12,1),%r12d + roll $5,%ecx + xorl 28(%rsp),%edx + addl %eax,%r12d + andl %esi,%ebx + roll $1,%edx + addl %ebx,%r12d + roll $30,%esi + movl %edx,40(%rsp) + addl %ecx,%r12d + movl 44(%rsp),%ebp + movl %esi,%eax + movl %esi,%ebx + xorl 52(%rsp),%ebp + andl %edi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + xorl %edi,%ebx + leal -1894007588(%rdx,%r11,1),%r11d + roll $5,%ecx + xorl 32(%rsp),%ebp + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%ebp + addl %ebx,%r11d + roll $30,%r13d + movl %ebp,44(%rsp) + addl %ecx,%r11d + movl 48(%rsp),%edx + movl %r13d,%eax + movl %r13d,%ebx + xorl 56(%rsp),%edx + andl %esi,%eax + movl %r11d,%ecx + xorl 16(%rsp),%edx + xorl %esi,%ebx + leal -1894007588(%rbp,%rdi,1),%edi + roll $5,%ecx + xorl 36(%rsp),%edx + addl %eax,%edi + andl %r12d,%ebx + roll $1,%edx + addl %ebx,%edi + roll $30,%r12d + movl %edx,48(%rsp) + addl %ecx,%edi + movl 52(%rsp),%ebp + movl %r12d,%eax + movl %r12d,%ebx + xorl 60(%rsp),%ebp + andl %r13d,%eax + movl %edi,%ecx + xorl 20(%rsp),%ebp + xorl %r13d,%ebx + leal -1894007588(%rdx,%rsi,1),%esi + roll $5,%ecx + xorl 40(%rsp),%ebp + addl %eax,%esi + andl %r11d,%ebx + roll $1,%ebp + addl %ebx,%esi + roll $30,%r11d + movl %ebp,52(%rsp) + addl %ecx,%esi + movl 56(%rsp),%edx + movl %r11d,%eax + movl %r11d,%ebx + xorl 0(%rsp),%edx + andl %r12d,%eax + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %r12d,%ebx + leal -1894007588(%rbp,%r13,1),%r13d + roll $5,%ecx + xorl 44(%rsp),%edx + addl %eax,%r13d + andl %edi,%ebx + roll $1,%edx + addl %ebx,%r13d + roll $30,%edi + movl %edx,56(%rsp) + addl %ecx,%r13d + movl 60(%rsp),%ebp + movl %edi,%eax + movl %edi,%ebx + xorl 4(%rsp),%ebp + andl %r11d,%eax + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %r11d,%ebx + leal -1894007588(%rdx,%r12,1),%r12d + roll $5,%ecx + xorl 48(%rsp),%ebp + addl %eax,%r12d + andl %esi,%ebx + roll $1,%ebp + addl %ebx,%r12d + roll $30,%esi + movl %ebp,60(%rsp) + addl %ecx,%r12d + movl 0(%rsp),%edx + movl %esi,%eax + movl %esi,%ebx + xorl 8(%rsp),%edx + andl %edi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + xorl %edi,%ebx + leal -1894007588(%rbp,%r11,1),%r11d + roll $5,%ecx + xorl 52(%rsp),%edx + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%edx + addl %ebx,%r11d + roll $30,%r13d + movl %edx,0(%rsp) + addl %ecx,%r11d + movl 4(%rsp),%ebp + movl %r13d,%eax + movl %r13d,%ebx + xorl 12(%rsp),%ebp + andl %esi,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + xorl %esi,%ebx + leal -1894007588(%rdx,%rdi,1),%edi + roll $5,%ecx + xorl 56(%rsp),%ebp + addl %eax,%edi + andl %r12d,%ebx + roll $1,%ebp + addl %ebx,%edi + roll $30,%r12d + movl %ebp,4(%rsp) + addl %ecx,%edi + movl 8(%rsp),%edx + movl %r12d,%eax + movl %r12d,%ebx + xorl 16(%rsp),%edx + andl %r13d,%eax + movl %edi,%ecx + xorl 40(%rsp),%edx + xorl %r13d,%ebx + leal -1894007588(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl 60(%rsp),%edx + addl %eax,%esi + andl %r11d,%ebx + roll $1,%edx + addl %ebx,%esi + roll $30,%r11d + movl %edx,8(%rsp) + addl %ecx,%esi + movl 12(%rsp),%ebp + movl %r11d,%eax + movl %r11d,%ebx + xorl 20(%rsp),%ebp + andl %r12d,%eax + movl %esi,%ecx + xorl 44(%rsp),%ebp + xorl %r12d,%ebx + leal -1894007588(%rdx,%r13,1),%r13d + roll $5,%ecx + xorl 0(%rsp),%ebp + addl %eax,%r13d + andl %edi,%ebx + roll $1,%ebp + addl %ebx,%r13d + roll $30,%edi + movl %ebp,12(%rsp) + addl %ecx,%r13d + movl 16(%rsp),%edx + movl %edi,%eax + movl %edi,%ebx + xorl 24(%rsp),%edx + andl %r11d,%eax + movl %r13d,%ecx + xorl 48(%rsp),%edx + xorl %r11d,%ebx + leal -1894007588(%rbp,%r12,1),%r12d + roll $5,%ecx + xorl 4(%rsp),%edx + addl %eax,%r12d + andl %esi,%ebx + roll $1,%edx + addl %ebx,%r12d + roll $30,%esi + movl %edx,16(%rsp) + addl %ecx,%r12d + movl 20(%rsp),%ebp + movl %esi,%eax + movl %esi,%ebx + xorl 28(%rsp),%ebp + andl %edi,%eax + movl %r12d,%ecx + xorl 52(%rsp),%ebp + xorl %edi,%ebx + leal -1894007588(%rdx,%r11,1),%r11d + roll $5,%ecx + xorl 8(%rsp),%ebp + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%ebp + addl %ebx,%r11d + roll $30,%r13d + movl %ebp,20(%rsp) + addl %ecx,%r11d + movl 24(%rsp),%edx + movl %r13d,%eax + movl %r13d,%ebx + xorl 32(%rsp),%edx + andl %esi,%eax + movl %r11d,%ecx + xorl 56(%rsp),%edx + xorl %esi,%ebx + leal -1894007588(%rbp,%rdi,1),%edi + roll $5,%ecx + xorl 12(%rsp),%edx + addl %eax,%edi + andl %r12d,%ebx + roll $1,%edx + addl %ebx,%edi + roll $30,%r12d + movl %edx,24(%rsp) + addl %ecx,%edi + movl 28(%rsp),%ebp + movl %r12d,%eax + movl %r12d,%ebx + xorl 36(%rsp),%ebp + andl %r13d,%eax + movl %edi,%ecx + xorl 60(%rsp),%ebp + xorl %r13d,%ebx + leal -1894007588(%rdx,%rsi,1),%esi + roll $5,%ecx + xorl 16(%rsp),%ebp + addl %eax,%esi + andl %r11d,%ebx + roll $1,%ebp + addl %ebx,%esi + roll $30,%r11d + movl %ebp,28(%rsp) + addl %ecx,%esi + movl 32(%rsp),%edx + movl %r11d,%eax + movl %r11d,%ebx + xorl 40(%rsp),%edx + andl %r12d,%eax + movl %esi,%ecx + xorl 0(%rsp),%edx + xorl %r12d,%ebx + leal -1894007588(%rbp,%r13,1),%r13d + roll $5,%ecx + xorl 20(%rsp),%edx + addl %eax,%r13d + andl %edi,%ebx + roll $1,%edx + addl %ebx,%r13d + roll $30,%edi + movl %edx,32(%rsp) + addl %ecx,%r13d + movl 36(%rsp),%ebp + movl %edi,%eax + movl %edi,%ebx + xorl 44(%rsp),%ebp + andl %r11d,%eax + movl %r13d,%ecx + xorl 4(%rsp),%ebp + xorl %r11d,%ebx + leal -1894007588(%rdx,%r12,1),%r12d + roll $5,%ecx + xorl 24(%rsp),%ebp + addl %eax,%r12d + andl %esi,%ebx + roll $1,%ebp + addl %ebx,%r12d + roll $30,%esi + movl %ebp,36(%rsp) + addl %ecx,%r12d + movl 40(%rsp),%edx + movl %esi,%eax + movl %esi,%ebx + xorl 48(%rsp),%edx + andl %edi,%eax + movl %r12d,%ecx + xorl 8(%rsp),%edx + xorl %edi,%ebx + leal -1894007588(%rbp,%r11,1),%r11d + roll $5,%ecx + xorl 28(%rsp),%edx + addl %eax,%r11d + andl %r13d,%ebx + roll $1,%edx + addl %ebx,%r11d + roll $30,%r13d + movl %edx,40(%rsp) + addl %ecx,%r11d + movl 44(%rsp),%ebp + movl %r13d,%eax + movl %r13d,%ebx + xorl 52(%rsp),%ebp + andl %esi,%eax + movl %r11d,%ecx + xorl 12(%rsp),%ebp + xorl %esi,%ebx + leal -1894007588(%rdx,%rdi,1),%edi + roll $5,%ecx + xorl 32(%rsp),%ebp + addl %eax,%edi + andl %r12d,%ebx + roll $1,%ebp + addl %ebx,%edi + roll $30,%r12d + movl %ebp,44(%rsp) + addl %ecx,%edi + movl 48(%rsp),%edx + movl %r12d,%eax + movl %r12d,%ebx + xorl 56(%rsp),%edx + andl %r13d,%eax + movl %edi,%ecx + xorl 16(%rsp),%edx + xorl %r13d,%ebx + leal -1894007588(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl 36(%rsp),%edx + addl %eax,%esi + andl %r11d,%ebx + roll $1,%edx + addl %ebx,%esi + roll $30,%r11d + movl %edx,48(%rsp) + addl %ecx,%esi + movl 52(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 60(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r13,1),%r13d + xorl 20(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 40(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,52(%rsp) + movl 56(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 0(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r12,1),%r12d + xorl 24(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 44(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,56(%rsp) + movl 60(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 4(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rdx,%r11,1),%r11d + xorl 28(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 48(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,60(%rsp) + movl 0(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 8(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rdi,1),%edi + xorl 32(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 52(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,0(%rsp) + movl 4(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 12(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rsi,1),%esi + xorl 36(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 56(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,4(%rsp) + movl 8(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 16(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r13,1),%r13d + xorl 40(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 60(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,8(%rsp) + movl 12(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 20(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r12,1),%r12d + xorl 44(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 0(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl %ebp,12(%rsp) + movl 16(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 24(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rbp,%r11,1),%r11d + xorl 48(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 4(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl %edx,16(%rsp) + movl 20(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 28(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rdi,1),%edi + xorl 52(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 8(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %ebp,20(%rsp) + movl 24(%rsp),%edx + movl %r12d,%eax + movl %edi,%ecx + xorl 32(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rsi,1),%esi + xorl 56(%rsp),%edx + xorl %r13d,%eax + addl %ecx,%esi + xorl 12(%rsp),%edx + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + movl %edx,24(%rsp) + movl 28(%rsp),%ebp + movl %r11d,%eax + movl %esi,%ecx + xorl 36(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r13,1),%r13d + xorl 60(%rsp),%ebp + xorl %r12d,%eax + addl %ecx,%r13d + xorl 16(%rsp),%ebp + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + movl %ebp,28(%rsp) + movl 32(%rsp),%edx + movl %edi,%eax + movl %r13d,%ecx + xorl 40(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r12,1),%r12d + xorl 0(%rsp),%edx + xorl %r11d,%eax + addl %ecx,%r12d + xorl 20(%rsp),%edx + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + movl %edx,32(%rsp) + movl 36(%rsp),%ebp + movl %esi,%eax + movl %r12d,%ecx + xorl 44(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rdx,%r11,1),%r11d + xorl 4(%rsp),%ebp + xorl %edi,%eax + addl %ecx,%r11d + xorl 24(%rsp),%ebp + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + movl %ebp,36(%rsp) + movl 40(%rsp),%edx + movl %r13d,%eax + movl %r11d,%ecx + xorl 48(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rbp,%rdi,1),%edi + xorl 8(%rsp),%edx + xorl %esi,%eax + addl %ecx,%edi + xorl 28(%rsp),%edx + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + movl %edx,40(%rsp) + movl 44(%rsp),%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl 52(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rsi,1),%esi + xorl 12(%rsp),%ebp + xorl %r13d,%eax + addl %ecx,%esi + xorl 32(%rsp),%ebp + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + movl %ebp,44(%rsp) + movl 48(%rsp),%edx + movl %r11d,%eax + movl %esi,%ecx + xorl 56(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + leal -899497514(%rbp,%r13,1),%r13d + xorl 16(%rsp),%edx + xorl %r12d,%eax + addl %ecx,%r13d + xorl 36(%rsp),%edx + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + movl %edx,48(%rsp) + movl 52(%rsp),%ebp + movl %edi,%eax + movl %r13d,%ecx + xorl 60(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + leal -899497514(%rdx,%r12,1),%r12d + xorl 20(%rsp),%ebp + xorl %r11d,%eax + addl %ecx,%r12d + xorl 40(%rsp),%ebp + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + movl 56(%rsp),%edx + movl %esi,%eax + movl %r12d,%ecx + xorl 0(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + leal -899497514(%rbp,%r11,1),%r11d + xorl 24(%rsp),%edx + xorl %edi,%eax + addl %ecx,%r11d + xorl 44(%rsp),%edx + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + movl 60(%rsp),%ebp + movl %r13d,%eax + movl %r11d,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + leal -899497514(%rdx,%rdi,1),%edi + xorl 28(%rsp),%ebp + xorl %esi,%eax + addl %ecx,%edi + xorl 48(%rsp),%ebp + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %r12d,%eax + movl %edi,%ecx + xorl %r11d,%eax + leal -899497514(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl %r13d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + addl 0(%r8),%esi + addl 4(%r8),%edi + addl 8(%r8),%r11d + addl 12(%r8),%r12d + addl 16(%r8),%r13d + movl %esi,0(%r8) + movl %edi,4(%r8) + movl %r11d,8(%r8) + movl %r12d,12(%r8) + movl %r13d,16(%r8) + + subq $1,%r10 + leaq 64(%r9),%r9 + jnz .Lloop + + movq 64(%rsp),%rsi + movq (%rsi),%r13 + movq 8(%rsi),%r12 + movq 16(%rsi),%rbp + movq 24(%rsi),%rbx + leaq 32(%rsi),%rsp +.Lepilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_sha1_block_data_order: +.def sha1_block_data_order_ssse3; .scl 3; .type 32; .endef +.p2align 4 +sha1_block_data_order_ssse3: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_sha1_block_data_order_ssse3: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + +_ssse3_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + leaq -144(%rsp),%rsp + movaps %xmm6,64+0(%rsp) + movaps %xmm7,64+16(%rsp) + movaps %xmm8,64+32(%rsp) + movaps %xmm9,64+48(%rsp) + movaps %xmm10,64+64(%rsp) +.Lprologue_ssse3: + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX(%rip),%r11 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + + movdqa 64(%r11),%xmm6 + movdqa 0(%r11),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 +.byte 102,15,56,0,222 + paddd %xmm9,%xmm0 + paddd %xmm9,%xmm1 + paddd %xmm9,%xmm2 + movdqa %xmm0,0(%rsp) + psubd %xmm9,%xmm0 + movdqa %xmm1,16(%rsp) + psubd %xmm9,%xmm1 + movdqa %xmm2,32(%rsp) + psubd %xmm9,%xmm2 + jmp .Loop_ssse3 +.p2align 4 +.Loop_ssse3: + movdqa %xmm1,%xmm4 + addl 0(%rsp),%ebp + xorl %edx,%ecx + movdqa %xmm3,%xmm8 +.byte 102,15,58,15,224,8 + movl %eax,%edi + roll $5,%eax + paddd %xmm3,%xmm9 + andl %ecx,%esi + xorl %edx,%ecx + psrldq $4,%xmm8 + xorl %edx,%esi + addl %eax,%ebp + pxor %xmm0,%xmm4 + rorl $2,%ebx + addl %esi,%ebp + pxor %xmm2,%xmm8 + addl 4(%rsp),%edx + xorl %ecx,%ebx + movl %ebp,%esi + roll $5,%ebp + pxor %xmm8,%xmm4 + andl %ebx,%edi + xorl %ecx,%ebx + movdqa %xmm9,48(%rsp) + xorl %ecx,%edi + addl %ebp,%edx + movdqa %xmm4,%xmm10 + movdqa %xmm4,%xmm8 + rorl $7,%eax + addl %edi,%edx + addl 8(%rsp),%ecx + xorl %ebx,%eax + pslldq $12,%xmm10 + paddd %xmm4,%xmm4 + movl %edx,%edi + roll $5,%edx + andl %eax,%esi + xorl %ebx,%eax + psrld $31,%xmm8 + xorl %ebx,%esi + addl %edx,%ecx + movdqa %xmm10,%xmm9 + rorl $7,%ebp + addl %esi,%ecx + psrld $30,%xmm10 + por %xmm8,%xmm4 + addl 12(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%esi + roll $5,%ecx + pslld $2,%xmm9 + pxor %xmm10,%xmm4 + andl %ebp,%edi + xorl %eax,%ebp + movdqa 0(%r11),%xmm10 + xorl %eax,%edi + addl %ecx,%ebx + pxor %xmm9,%xmm4 + rorl $7,%edx + addl %edi,%ebx + movdqa %xmm2,%xmm5 + addl 16(%rsp),%eax + xorl %ebp,%edx + movdqa %xmm4,%xmm9 +.byte 102,15,58,15,233,8 + movl %ebx,%edi + roll $5,%ebx + paddd %xmm4,%xmm10 + andl %edx,%esi + xorl %ebp,%edx + psrldq $4,%xmm9 + xorl %ebp,%esi + addl %ebx,%eax + pxor %xmm1,%xmm5 + rorl $7,%ecx + addl %esi,%eax + pxor %xmm3,%xmm9 + addl 20(%rsp),%ebp + xorl %edx,%ecx + movl %eax,%esi + roll $5,%eax + pxor %xmm9,%xmm5 + andl %ecx,%edi + xorl %edx,%ecx + movdqa %xmm10,0(%rsp) + xorl %edx,%edi + addl %eax,%ebp + movdqa %xmm5,%xmm8 + movdqa %xmm5,%xmm9 + rorl $7,%ebx + addl %edi,%ebp + addl 24(%rsp),%edx + xorl %ecx,%ebx + pslldq $12,%xmm8 + paddd %xmm5,%xmm5 + movl %ebp,%edi + roll $5,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + psrld $31,%xmm9 + xorl %ecx,%esi + addl %ebp,%edx + movdqa %xmm8,%xmm10 + rorl $7,%eax + addl %esi,%edx + psrld $30,%xmm8 + por %xmm9,%xmm5 + addl 28(%rsp),%ecx + xorl %ebx,%eax + movl %edx,%esi + roll $5,%edx + pslld $2,%xmm10 + pxor %xmm8,%xmm5 + andl %eax,%edi + xorl %ebx,%eax + movdqa 16(%r11),%xmm8 + xorl %ebx,%edi + addl %edx,%ecx + pxor %xmm10,%xmm5 + rorl $7,%ebp + addl %edi,%ecx + movdqa %xmm3,%xmm6 + addl 32(%rsp),%ebx + xorl %eax,%ebp + movdqa %xmm5,%xmm10 +.byte 102,15,58,15,242,8 + movl %ecx,%edi + roll $5,%ecx + paddd %xmm5,%xmm8 + andl %ebp,%esi + xorl %eax,%ebp + psrldq $4,%xmm10 + xorl %eax,%esi + addl %ecx,%ebx + pxor %xmm2,%xmm6 + rorl $7,%edx + addl %esi,%ebx + pxor %xmm4,%xmm10 + addl 36(%rsp),%eax + xorl %ebp,%edx + movl %ebx,%esi + roll $5,%ebx + pxor %xmm10,%xmm6 + andl %edx,%edi + xorl %ebp,%edx + movdqa %xmm8,16(%rsp) + xorl %ebp,%edi + addl %ebx,%eax + movdqa %xmm6,%xmm9 + movdqa %xmm6,%xmm10 + rorl $7,%ecx + addl %edi,%eax + addl 40(%rsp),%ebp + xorl %edx,%ecx + pslldq $12,%xmm9 + paddd %xmm6,%xmm6 + movl %eax,%edi + roll $5,%eax + andl %ecx,%esi + xorl %edx,%ecx + psrld $31,%xmm10 + xorl %edx,%esi + addl %eax,%ebp + movdqa %xmm9,%xmm8 + rorl $7,%ebx + addl %esi,%ebp + psrld $30,%xmm9 + por %xmm10,%xmm6 + addl 44(%rsp),%edx + xorl %ecx,%ebx + movl %ebp,%esi + roll $5,%ebp + pslld $2,%xmm8 + pxor %xmm9,%xmm6 + andl %ebx,%edi + xorl %ecx,%ebx + movdqa 16(%r11),%xmm9 + xorl %ecx,%edi + addl %ebp,%edx + pxor %xmm8,%xmm6 + rorl $7,%eax + addl %edi,%edx + movdqa %xmm4,%xmm7 + addl 48(%rsp),%ecx + xorl %ebx,%eax + movdqa %xmm6,%xmm8 +.byte 102,15,58,15,251,8 + movl %edx,%edi + roll $5,%edx + paddd %xmm6,%xmm9 + andl %eax,%esi + xorl %ebx,%eax + psrldq $4,%xmm8 + xorl %ebx,%esi + addl %edx,%ecx + pxor %xmm3,%xmm7 + rorl $7,%ebp + addl %esi,%ecx + pxor %xmm5,%xmm8 + addl 52(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%esi + roll $5,%ecx + pxor %xmm8,%xmm7 + andl %ebp,%edi + xorl %eax,%ebp + movdqa %xmm9,32(%rsp) + xorl %eax,%edi + addl %ecx,%ebx + movdqa %xmm7,%xmm10 + movdqa %xmm7,%xmm8 + rorl $7,%edx + addl %edi,%ebx + addl 56(%rsp),%eax + xorl %ebp,%edx + pslldq $12,%xmm10 + paddd %xmm7,%xmm7 + movl %ebx,%edi + roll $5,%ebx + andl %edx,%esi + xorl %ebp,%edx + psrld $31,%xmm8 + xorl %ebp,%esi + addl %ebx,%eax + movdqa %xmm10,%xmm9 + rorl $7,%ecx + addl %esi,%eax + psrld $30,%xmm10 + por %xmm8,%xmm7 + addl 60(%rsp),%ebp + xorl %edx,%ecx + movl %eax,%esi + roll $5,%eax + pslld $2,%xmm9 + pxor %xmm10,%xmm7 + andl %ecx,%edi + xorl %edx,%ecx + movdqa 16(%r11),%xmm10 + xorl %edx,%edi + addl %eax,%ebp + pxor %xmm9,%xmm7 + rorl $7,%ebx + addl %edi,%ebp + movdqa %xmm7,%xmm9 + addl 0(%rsp),%edx + pxor %xmm4,%xmm0 +.byte 102,68,15,58,15,206,8 + xorl %ecx,%ebx + movl %ebp,%edi + roll $5,%ebp + pxor %xmm1,%xmm0 + andl %ebx,%esi + xorl %ecx,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm7,%xmm10 + xorl %ecx,%esi + addl %ebp,%edx + pxor %xmm9,%xmm0 + rorl $7,%eax + addl %esi,%edx + addl 4(%rsp),%ecx + xorl %ebx,%eax + movdqa %xmm0,%xmm9 + movdqa %xmm10,48(%rsp) + movl %edx,%esi + roll $5,%edx + andl %eax,%edi + xorl %ebx,%eax + pslld $2,%xmm0 + xorl %ebx,%edi + addl %edx,%ecx + psrld $30,%xmm9 + rorl $7,%ebp + addl %edi,%ecx + addl 8(%rsp),%ebx + xorl %eax,%ebp + movl %ecx,%edi + roll $5,%ecx + por %xmm9,%xmm0 + andl %ebp,%esi + xorl %eax,%ebp + movdqa %xmm0,%xmm10 + xorl %eax,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edx + movl %ebx,%esi + roll $5,%ebx + andl %edx,%edi + xorl %ebp,%edx + xorl %ebp,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 16(%rsp),%ebp + pxor %xmm5,%xmm1 +.byte 102,68,15,58,15,215,8 + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + pxor %xmm2,%xmm1 + xorl %ecx,%esi + addl %eax,%ebp + movdqa %xmm8,%xmm9 + paddd %xmm0,%xmm8 + rorl $7,%ebx + addl %esi,%ebp + pxor %xmm10,%xmm1 + addl 20(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm1,%xmm10 + movdqa %xmm8,0(%rsp) + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm1 + addl 24(%rsp),%ecx + xorl %ebx,%esi + psrld $30,%xmm10 + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + por %xmm10,%xmm1 + addl 28(%rsp),%ebx + xorl %eax,%edi + movdqa %xmm1,%xmm8 + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 32(%rsp),%eax + pxor %xmm6,%xmm2 +.byte 102,68,15,58,15,192,8 + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + pxor %xmm3,%xmm2 + xorl %edx,%esi + addl %ebx,%eax + movdqa 32(%r11),%xmm10 + paddd %xmm1,%xmm9 + rorl $7,%ecx + addl %esi,%eax + pxor %xmm8,%xmm2 + addl 36(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm8 + movdqa %xmm9,16(%rsp) + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + pslld $2,%xmm2 + addl 40(%rsp),%edx + xorl %ecx,%esi + psrld $30,%xmm8 + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + por %xmm8,%xmm2 + addl 44(%rsp),%ecx + xorl %ebx,%edi + movdqa %xmm2,%xmm9 + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 48(%rsp),%ebx + pxor %xmm7,%xmm3 +.byte 102,68,15,58,15,201,8 + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + pxor %xmm4,%xmm3 + xorl %ebp,%esi + addl %ecx,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm2,%xmm10 + rorl $7,%edx + addl %esi,%ebx + pxor %xmm9,%xmm3 + addl 52(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm9 + movdqa %xmm10,32(%rsp) + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + pslld $2,%xmm3 + addl 56(%rsp),%ebp + xorl %edx,%esi + psrld $30,%xmm9 + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + por %xmm9,%xmm3 + addl 60(%rsp),%edx + xorl %ecx,%edi + movdqa %xmm3,%xmm10 + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 0(%rsp),%ecx + pxor %xmm0,%xmm4 +.byte 102,68,15,58,15,210,8 + xorl %ebx,%esi + movl %edx,%edi + roll $5,%edx + pxor %xmm5,%xmm4 + xorl %eax,%esi + addl %edx,%ecx + movdqa %xmm8,%xmm9 + paddd %xmm3,%xmm8 + rorl $7,%ebp + addl %esi,%ecx + pxor %xmm10,%xmm4 + addl 4(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm10 + movdqa %xmm8,48(%rsp) + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + pslld $2,%xmm4 + addl 8(%rsp),%eax + xorl %ebp,%esi + psrld $30,%xmm10 + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + por %xmm10,%xmm4 + addl 12(%rsp),%ebp + xorl %edx,%edi + movdqa %xmm4,%xmm8 + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 16(%rsp),%edx + pxor %xmm1,%xmm5 +.byte 102,68,15,58,15,195,8 + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + pxor %xmm6,%xmm5 + xorl %ebx,%esi + addl %ebp,%edx + movdqa %xmm9,%xmm10 + paddd %xmm4,%xmm9 + rorl $7,%eax + addl %esi,%edx + pxor %xmm8,%xmm5 + addl 20(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm8 + movdqa %xmm9,0(%rsp) + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + pslld $2,%xmm5 + addl 24(%rsp),%ebx + xorl %eax,%esi + psrld $30,%xmm8 + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + por %xmm8,%xmm5 + addl 28(%rsp),%eax + xorl %ebp,%edi + movdqa %xmm5,%xmm9 + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + movl %ecx,%edi + pxor %xmm2,%xmm6 +.byte 102,68,15,58,15,204,8 + xorl %edx,%ecx + addl 32(%rsp),%ebp + andl %edx,%edi + pxor %xmm7,%xmm6 + andl %ecx,%esi + rorl $7,%ebx + movdqa %xmm10,%xmm8 + paddd %xmm5,%xmm10 + addl %edi,%ebp + movl %eax,%edi + pxor %xmm9,%xmm6 + roll $5,%eax + addl %esi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movdqa %xmm6,%xmm9 + movdqa %xmm10,16(%rsp) + movl %ebx,%esi + xorl %ecx,%ebx + addl 36(%rsp),%edx + andl %ecx,%esi + pslld $2,%xmm6 + andl %ebx,%edi + rorl $7,%eax + psrld $30,%xmm9 + addl %esi,%edx + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + por %xmm9,%xmm6 + movl %eax,%edi + xorl %ebx,%eax + movdqa %xmm6,%xmm10 + addl 40(%rsp),%ecx + andl %ebx,%edi + andl %eax,%esi + rorl $7,%ebp + addl %edi,%ecx + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movl %ebp,%esi + xorl %eax,%ebp + addl 44(%rsp),%ebx + andl %eax,%esi + andl %ebp,%edi + rorl $7,%edx + addl %esi,%ebx + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movl %edx,%edi + pxor %xmm3,%xmm7 +.byte 102,68,15,58,15,213,8 + xorl %ebp,%edx + addl 48(%rsp),%eax + andl %ebp,%edi + pxor %xmm0,%xmm7 + andl %edx,%esi + rorl $7,%ecx + movdqa 48(%r11),%xmm9 + paddd %xmm6,%xmm8 + addl %edi,%eax + movl %ebx,%edi + pxor %xmm10,%xmm7 + roll $5,%ebx + addl %esi,%eax + xorl %ebp,%edx + addl %ebx,%eax + movdqa %xmm7,%xmm10 + movdqa %xmm8,32(%rsp) + movl %ecx,%esi + xorl %edx,%ecx + addl 52(%rsp),%ebp + andl %edx,%esi + pslld $2,%xmm7 + andl %ecx,%edi + rorl $7,%ebx + psrld $30,%xmm10 + addl %esi,%ebp + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + por %xmm10,%xmm7 + movl %ebx,%edi + xorl %ecx,%ebx + movdqa %xmm7,%xmm8 + addl 56(%rsp),%edx + andl %ecx,%edi + andl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movl %eax,%esi + xorl %ebx,%eax + addl 60(%rsp),%ecx + andl %ebx,%esi + andl %eax,%edi + rorl $7,%ebp + addl %esi,%ecx + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movl %ebp,%edi + pxor %xmm4,%xmm0 +.byte 102,68,15,58,15,198,8 + xorl %eax,%ebp + addl 0(%rsp),%ebx + andl %eax,%edi + pxor %xmm1,%xmm0 + andl %ebp,%esi + rorl $7,%edx + movdqa %xmm9,%xmm10 + paddd %xmm7,%xmm9 + addl %edi,%ebx + movl %ecx,%edi + pxor %xmm8,%xmm0 + roll $5,%ecx + addl %esi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movdqa %xmm0,%xmm8 + movdqa %xmm9,48(%rsp) + movl %edx,%esi + xorl %ebp,%edx + addl 4(%rsp),%eax + andl %ebp,%esi + pslld $2,%xmm0 + andl %edx,%edi + rorl $7,%ecx + psrld $30,%xmm8 + addl %esi,%eax + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %ebp,%edx + addl %ebx,%eax + por %xmm8,%xmm0 + movl %ecx,%edi + xorl %edx,%ecx + movdqa %xmm0,%xmm9 + addl 8(%rsp),%ebp + andl %edx,%edi + andl %ecx,%esi + rorl $7,%ebx + addl %edi,%ebp + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movl %ebx,%esi + xorl %ecx,%ebx + addl 12(%rsp),%edx + andl %ecx,%esi + andl %ebx,%edi + rorl $7,%eax + addl %esi,%edx + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movl %eax,%edi + pxor %xmm5,%xmm1 +.byte 102,68,15,58,15,207,8 + xorl %ebx,%eax + addl 16(%rsp),%ecx + andl %ebx,%edi + pxor %xmm2,%xmm1 + andl %eax,%esi + rorl $7,%ebp + movdqa %xmm10,%xmm8 + paddd %xmm0,%xmm10 + addl %edi,%ecx + movl %edx,%edi + pxor %xmm9,%xmm1 + roll $5,%edx + addl %esi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + movdqa %xmm1,%xmm9 + movdqa %xmm10,0(%rsp) + movl %ebp,%esi + xorl %eax,%ebp + addl 20(%rsp),%ebx + andl %eax,%esi + pslld $2,%xmm1 + andl %ebp,%edi + rorl $7,%edx + psrld $30,%xmm9 + addl %esi,%ebx + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + por %xmm9,%xmm1 + movl %edx,%edi + xorl %ebp,%edx + movdqa %xmm1,%xmm10 + addl 24(%rsp),%eax + andl %ebp,%edi + andl %edx,%esi + rorl $7,%ecx + addl %edi,%eax + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %ebp,%edx + addl %ebx,%eax + movl %ecx,%esi + xorl %edx,%ecx + addl 28(%rsp),%ebp + andl %edx,%esi + andl %ecx,%edi + rorl $7,%ebx + addl %esi,%ebp + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %edx,%ecx + addl %eax,%ebp + movl %ebx,%edi + pxor %xmm6,%xmm2 +.byte 102,68,15,58,15,208,8 + xorl %ecx,%ebx + addl 32(%rsp),%edx + andl %ecx,%edi + pxor %xmm3,%xmm2 + andl %ebx,%esi + rorl $7,%eax + movdqa %xmm8,%xmm9 + paddd %xmm1,%xmm8 + addl %edi,%edx + movl %ebp,%edi + pxor %xmm10,%xmm2 + roll $5,%ebp + addl %esi,%edx + xorl %ecx,%ebx + addl %ebp,%edx + movdqa %xmm2,%xmm10 + movdqa %xmm8,16(%rsp) + movl %eax,%esi + xorl %ebx,%eax + addl 36(%rsp),%ecx + andl %ebx,%esi + pslld $2,%xmm2 + andl %eax,%edi + rorl $7,%ebp + psrld $30,%xmm10 + addl %esi,%ecx + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %ebx,%eax + addl %edx,%ecx + por %xmm10,%xmm2 + movl %ebp,%edi + xorl %eax,%ebp + movdqa %xmm2,%xmm8 + addl 40(%rsp),%ebx + andl %eax,%edi + andl %ebp,%esi + rorl $7,%edx + addl %edi,%ebx + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %eax,%ebp + addl %ecx,%ebx + movl %edx,%esi + xorl %ebp,%edx + addl 44(%rsp),%eax + andl %ebp,%esi + andl %edx,%edi + rorl $7,%ecx + addl %esi,%eax + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %ebp,%edx + addl %ebx,%eax + addl 48(%rsp),%ebp + pxor %xmm7,%xmm3 +.byte 102,68,15,58,15,193,8 + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + pxor %xmm4,%xmm3 + xorl %ecx,%esi + addl %eax,%ebp + movdqa %xmm9,%xmm10 + paddd %xmm2,%xmm9 + rorl $7,%ebx + addl %esi,%ebp + pxor %xmm8,%xmm3 + addl 52(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm3,%xmm8 + movdqa %xmm9,32(%rsp) + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm3 + addl 56(%rsp),%ecx + xorl %ebx,%esi + psrld $30,%xmm8 + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + por %xmm8,%xmm3 + addl 60(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 0(%rsp),%eax + paddd %xmm3,%xmm10 + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + movdqa %xmm10,48(%rsp) + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 4(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 8(%rsp),%edx + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + addl 12(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + cmpq %r10,%r9 + je .Ldone_ssse3 + movdqa 64(%r11),%xmm6 + movdqa 0(%r11),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %eax,%esi +.byte 102,15,56,0,206 + movl %ecx,%edi + roll $5,%ecx + paddd %xmm9,%xmm0 + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + movdqa %xmm0,0(%rsp) + addl 20(%rsp),%eax + xorl %ebp,%edi + psubd %xmm9,%xmm0 + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 24(%rsp),%ebp + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + addl 28(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 32(%rsp),%ecx + xorl %ebx,%esi +.byte 102,15,56,0,214 + movl %edx,%edi + roll $5,%edx + paddd %xmm9,%xmm1 + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + movdqa %xmm1,16(%rsp) + addl 36(%rsp),%ebx + xorl %eax,%edi + psubd %xmm9,%xmm1 + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 40(%rsp),%eax + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 44(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 48(%rsp),%edx + xorl %ecx,%esi +.byte 102,15,56,0,222 + movl %ebp,%edi + roll $5,%ebp + paddd %xmm9,%xmm2 + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + movdqa %xmm2,32(%rsp) + addl 52(%rsp),%ecx + xorl %ebx,%edi + psubd %xmm9,%xmm2 + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 56(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 60(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + jmp .Loop_ssse3 + +.p2align 4 +.Ldone_ssse3: + addl 16(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 20(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 24(%rsp),%ebp + xorl %edx,%esi + movl %eax,%edi + roll $5,%eax + xorl %ecx,%esi + addl %eax,%ebp + rorl $7,%ebx + addl %esi,%ebp + addl 28(%rsp),%edx + xorl %ecx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ebx,%edi + addl %ebp,%edx + rorl $7,%eax + addl %edi,%edx + addl 32(%rsp),%ecx + xorl %ebx,%esi + movl %edx,%edi + roll $5,%edx + xorl %eax,%esi + addl %edx,%ecx + rorl $7,%ebp + addl %esi,%ecx + addl 36(%rsp),%ebx + xorl %eax,%edi + movl %ecx,%esi + roll $5,%ecx + xorl %ebp,%edi + addl %ecx,%ebx + rorl $7,%edx + addl %edi,%ebx + addl 40(%rsp),%eax + xorl %ebp,%esi + movl %ebx,%edi + roll $5,%ebx + xorl %edx,%esi + addl %ebx,%eax + rorl $7,%ecx + addl %esi,%eax + addl 44(%rsp),%ebp + xorl %edx,%edi + movl %eax,%esi + roll $5,%eax + xorl %ecx,%edi + addl %eax,%ebp + rorl $7,%ebx + addl %edi,%ebp + addl 48(%rsp),%edx + xorl %ecx,%esi + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%esi + addl %ebp,%edx + rorl $7,%eax + addl %esi,%edx + addl 52(%rsp),%ecx + xorl %ebx,%edi + movl %edx,%esi + roll $5,%edx + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%ebp + addl %edi,%ecx + addl 56(%rsp),%ebx + xorl %eax,%esi + movl %ecx,%edi + roll $5,%ecx + xorl %ebp,%esi + addl %ecx,%ebx + rorl $7,%edx + addl %esi,%ebx + addl 60(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + xorl %edx,%edi + addl %ebx,%eax + rorl $7,%ecx + addl %edi,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movaps 64+0(%rsp),%xmm6 + movaps 64+16(%rsp),%xmm7 + movaps 64+32(%rsp),%xmm8 + movaps 64+48(%rsp),%xmm9 + movaps 64+64(%rsp),%xmm10 + leaq 144(%rsp),%rsi + movq 0(%rsi),%r12 + movq 8(%rsi),%rbp + movq 16(%rsi),%rbx + leaq 24(%rsi),%rsp +.Lepilogue_ssse3: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_sha1_block_data_order_ssse3: +.p2align 6 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 + +.def se_handler; .scl 3; .type 32; .endef +.p2align 4 +se_handler: + pushq %rsi + pushq %rdi + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushfq + subq $64,%rsp + + movq 120(%r8),%rax + movq 248(%r8),%rbx + + leaq .Lprologue(%rip),%r10 + cmpq %r10,%rbx + jb .Lcommon_seh_tail + + movq 152(%r8),%rax + + leaq .Lepilogue(%rip),%r10 + cmpq %r10,%rbx + jae .Lcommon_seh_tail + + movq 64(%rax),%rax + leaq 32(%rax),%rax + + movq -8(%rax),%rbx + movq -16(%rax),%rbp + movq -24(%rax),%r12 + movq -32(%rax),%r13 + movq %rbx,144(%r8) + movq %rbp,160(%r8) + movq %r12,216(%r8) + movq %r13,224(%r8) + + jmp .Lcommon_seh_tail + + +.def ssse3_handler; .scl 3; .type 32; .endef +.p2align 4 +ssse3_handler: + pushq %rsi + pushq %rdi + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushfq + subq $64,%rsp + + movq 120(%r8),%rax + movq 248(%r8),%rbx + + movq 8(%r9),%rsi + movq 56(%r9),%r11 + + movl 0(%r11),%r10d + leaq (%rsi,%r10,1),%r10 + cmpq %r10,%rbx + jb .Lcommon_seh_tail + + movq 152(%r8),%rax + + movl 4(%r11),%r10d + leaq (%rsi,%r10,1),%r10 + cmpq %r10,%rbx + jae .Lcommon_seh_tail + + leaq 64(%rax),%rsi + leaq 512(%r8),%rdi + movl $10,%ecx +.long 0xa548f3fc + leaq 168(%rax),%rax + + movq -8(%rax),%rbx + movq -16(%rax),%rbp + movq -24(%rax),%r12 + movq %rbx,144(%r8) + movq %rbp,160(%r8) + movq %r12,216(%r8) + +.Lcommon_seh_tail: + movq 8(%rax),%rdi + movq 16(%rax),%rsi + movq %rax,152(%r8) + movq %rsi,168(%r8) + movq %rdi,176(%r8) + + movq 40(%r9),%rdi + movq %r8,%rsi + movl $154,%ecx +.long 0xa548f3fc + + movq %r9,%rsi + xorq %rcx,%rcx + movq 8(%rsi),%rdx + movq 0(%rsi),%r8 + movq 16(%rsi),%r9 + movq 40(%rsi),%r10 + leaq 56(%rsi),%r11 + leaq 24(%rsi),%r12 + movq %r10,32(%rsp) + movq %r11,40(%rsp) + movq %r12,48(%rsp) + movq %rcx,56(%rsp) + call *__imp_RtlVirtualUnwind(%rip) + + movl $1,%eax + addq $64,%rsp + popfq + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %rdi + popq %rsi + retq + + +.section .pdata +.p2align 2 +.rva .LSEH_begin_sha1_block_data_order +.rva .LSEH_end_sha1_block_data_order +.rva .LSEH_info_sha1_block_data_order +.rva .LSEH_begin_sha1_block_data_order_ssse3 +.rva .LSEH_end_sha1_block_data_order_ssse3 +.rva .LSEH_info_sha1_block_data_order_ssse3 +.section .xdata +.p2align 3 +.LSEH_info_sha1_block_data_order: +.byte 9,0,0,0 +.rva se_handler +.LSEH_info_sha1_block_data_order_ssse3: +.byte 9,0,0,0 +.rva ssse3_handler +.rva .Lprologue_ssse3,.Lepilogue_ssse3 diff --git a/Libraries/libressl/crypto/sha/sha1-mips.S b/Libraries/libressl/crypto/sha/sha1-mips.S new file mode 100644 index 000000000..dddb57850 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1-mips.S @@ -0,0 +1,1663 @@ +.text + +.set noat +.set noreorder +.align 5 +.globl sha1_block_data_order +.ent sha1_block_data_order +sha1_block_data_order: + .frame $29,16*4,$31 + .mask 3237937152,-4 + .set noreorder + sub $29,16*4 + sw $31,(16-1)*4($29) + sw $30,(16-2)*4($29) + sw $23,(16-3)*4($29) + sw $22,(16-4)*4($29) + sw $21,(16-5)*4($29) + sw $20,(16-6)*4($29) + sw $19,(16-7)*4($29) + sw $18,(16-8)*4($29) + sw $17,(16-9)*4($29) + sw $16,(16-10)*4($29) + sll $6,6 + add $6,$5 + sw $6,0($29) + lw $1,0($4) + lw $2,4($4) + lw $3,8($4) + lw $7,12($4) + b .Loop + lw $24,16($4) +.align 4 +.Loop: + .set reorder + lwl $8,3($5) + lui $31,0x5a82 + lwr $8,0($5) + ori $31,0x7999 # K_00_19 + srl $25,$8,24 # byte swap(0) + srl $6,$8,8 + andi $30,$8,0xFF00 + sll $8,$8,24 + andi $6,0xFF00 + sll $30,$30,8 + or $8,$25 + or $6,$30 + or $8,$6 + lwl $9,1*4+3($5) + sll $25,$1,5 # 0 + addu $24,$31 + lwr $9,1*4+0($5) + srl $6,$1,27 + addu $24,$25 + xor $25,$3,$7 + addu $24,$6 + sll $30,$2,30 + and $25,$2 + srl $2,$2,2 + xor $25,$7 + addu $24,$8 + or $2,$30 + addu $24,$25 + srl $25,$9,24 # byte swap(1) + srl $6,$9,8 + andi $30,$9,0xFF00 + sll $9,$9,24 + andi $6,0xFF00 + sll $30,$30,8 + or $9,$25 + or $6,$30 + or $9,$6 + lwl $10,2*4+3($5) + sll $25,$24,5 # 1 + addu $7,$31 + lwr $10,2*4+0($5) + srl $6,$24,27 + addu $7,$25 + xor $25,$2,$3 + addu $7,$6 + sll $30,$1,30 + and $25,$1 + srl $1,$1,2 + xor $25,$3 + addu $7,$9 + or $1,$30 + addu $7,$25 + srl $25,$10,24 # byte swap(2) + srl $6,$10,8 + andi $30,$10,0xFF00 + sll $10,$10,24 + andi $6,0xFF00 + sll $30,$30,8 + or $10,$25 + or $6,$30 + or $10,$6 + lwl $11,3*4+3($5) + sll $25,$7,5 # 2 + addu $3,$31 + lwr $11,3*4+0($5) + srl $6,$7,27 + addu $3,$25 + xor $25,$1,$2 + addu $3,$6 + sll $30,$24,30 + and $25,$24 + srl $24,$24,2 + xor $25,$2 + addu $3,$10 + or $24,$30 + addu $3,$25 + srl $25,$11,24 # byte swap(3) + srl $6,$11,8 + andi $30,$11,0xFF00 + sll $11,$11,24 + andi $6,0xFF00 + sll $30,$30,8 + or $11,$25 + or $6,$30 + or $11,$6 + lwl $12,4*4+3($5) + sll $25,$3,5 # 3 + addu $2,$31 + lwr $12,4*4+0($5) + srl $6,$3,27 + addu $2,$25 + xor $25,$24,$1 + addu $2,$6 + sll $30,$7,30 + and $25,$7 + srl $7,$7,2 + xor $25,$1 + addu $2,$11 + or $7,$30 + addu $2,$25 + srl $25,$12,24 # byte swap(4) + srl $6,$12,8 + andi $30,$12,0xFF00 + sll $12,$12,24 + andi $6,0xFF00 + sll $30,$30,8 + or $12,$25 + or $6,$30 + or $12,$6 + lwl $13,5*4+3($5) + sll $25,$2,5 # 4 + addu $1,$31 + lwr $13,5*4+0($5) + srl $6,$2,27 + addu $1,$25 + xor $25,$7,$24 + addu $1,$6 + sll $30,$3,30 + and $25,$3 + srl $3,$3,2 + xor $25,$24 + addu $1,$12 + or $3,$30 + addu $1,$25 + srl $25,$13,24 # byte swap(5) + srl $6,$13,8 + andi $30,$13,0xFF00 + sll $13,$13,24 + andi $6,0xFF00 + sll $30,$30,8 + or $13,$25 + or $6,$30 + or $13,$6 + lwl $14,6*4+3($5) + sll $25,$1,5 # 5 + addu $24,$31 + lwr $14,6*4+0($5) + srl $6,$1,27 + addu $24,$25 + xor $25,$3,$7 + addu $24,$6 + sll $30,$2,30 + and $25,$2 + srl $2,$2,2 + xor $25,$7 + addu $24,$13 + or $2,$30 + addu $24,$25 + srl $25,$14,24 # byte swap(6) + srl $6,$14,8 + andi $30,$14,0xFF00 + sll $14,$14,24 + andi $6,0xFF00 + sll $30,$30,8 + or $14,$25 + or $6,$30 + or $14,$6 + lwl $15,7*4+3($5) + sll $25,$24,5 # 6 + addu $7,$31 + lwr $15,7*4+0($5) + srl $6,$24,27 + addu $7,$25 + xor $25,$2,$3 + addu $7,$6 + sll $30,$1,30 + and $25,$1 + srl $1,$1,2 + xor $25,$3 + addu $7,$14 + or $1,$30 + addu $7,$25 + srl $25,$15,24 # byte swap(7) + srl $6,$15,8 + andi $30,$15,0xFF00 + sll $15,$15,24 + andi $6,0xFF00 + sll $30,$30,8 + or $15,$25 + or $6,$30 + or $15,$6 + lwl $16,8*4+3($5) + sll $25,$7,5 # 7 + addu $3,$31 + lwr $16,8*4+0($5) + srl $6,$7,27 + addu $3,$25 + xor $25,$1,$2 + addu $3,$6 + sll $30,$24,30 + and $25,$24 + srl $24,$24,2 + xor $25,$2 + addu $3,$15 + or $24,$30 + addu $3,$25 + srl $25,$16,24 # byte swap(8) + srl $6,$16,8 + andi $30,$16,0xFF00 + sll $16,$16,24 + andi $6,0xFF00 + sll $30,$30,8 + or $16,$25 + or $6,$30 + or $16,$6 + lwl $17,9*4+3($5) + sll $25,$3,5 # 8 + addu $2,$31 + lwr $17,9*4+0($5) + srl $6,$3,27 + addu $2,$25 + xor $25,$24,$1 + addu $2,$6 + sll $30,$7,30 + and $25,$7 + srl $7,$7,2 + xor $25,$1 + addu $2,$16 + or $7,$30 + addu $2,$25 + srl $25,$17,24 # byte swap(9) + srl $6,$17,8 + andi $30,$17,0xFF00 + sll $17,$17,24 + andi $6,0xFF00 + sll $30,$30,8 + or $17,$25 + or $6,$30 + or $17,$6 + lwl $18,10*4+3($5) + sll $25,$2,5 # 9 + addu $1,$31 + lwr $18,10*4+0($5) + srl $6,$2,27 + addu $1,$25 + xor $25,$7,$24 + addu $1,$6 + sll $30,$3,30 + and $25,$3 + srl $3,$3,2 + xor $25,$24 + addu $1,$17 + or $3,$30 + addu $1,$25 + srl $25,$18,24 # byte swap(10) + srl $6,$18,8 + andi $30,$18,0xFF00 + sll $18,$18,24 + andi $6,0xFF00 + sll $30,$30,8 + or $18,$25 + or $6,$30 + or $18,$6 + lwl $19,11*4+3($5) + sll $25,$1,5 # 10 + addu $24,$31 + lwr $19,11*4+0($5) + srl $6,$1,27 + addu $24,$25 + xor $25,$3,$7 + addu $24,$6 + sll $30,$2,30 + and $25,$2 + srl $2,$2,2 + xor $25,$7 + addu $24,$18 + or $2,$30 + addu $24,$25 + srl $25,$19,24 # byte swap(11) + srl $6,$19,8 + andi $30,$19,0xFF00 + sll $19,$19,24 + andi $6,0xFF00 + sll $30,$30,8 + or $19,$25 + or $6,$30 + or $19,$6 + lwl $20,12*4+3($5) + sll $25,$24,5 # 11 + addu $7,$31 + lwr $20,12*4+0($5) + srl $6,$24,27 + addu $7,$25 + xor $25,$2,$3 + addu $7,$6 + sll $30,$1,30 + and $25,$1 + srl $1,$1,2 + xor $25,$3 + addu $7,$19 + or $1,$30 + addu $7,$25 + srl $25,$20,24 # byte swap(12) + srl $6,$20,8 + andi $30,$20,0xFF00 + sll $20,$20,24 + andi $6,0xFF00 + sll $30,$30,8 + or $20,$25 + or $6,$30 + or $20,$6 + lwl $21,13*4+3($5) + sll $25,$7,5 # 12 + addu $3,$31 + lwr $21,13*4+0($5) + srl $6,$7,27 + addu $3,$25 + xor $25,$1,$2 + addu $3,$6 + sll $30,$24,30 + and $25,$24 + srl $24,$24,2 + xor $25,$2 + addu $3,$20 + or $24,$30 + addu $3,$25 + srl $25,$21,24 # byte swap(13) + srl $6,$21,8 + andi $30,$21,0xFF00 + sll $21,$21,24 + andi $6,0xFF00 + sll $30,$30,8 + or $21,$25 + or $6,$30 + or $21,$6 + lwl $22,14*4+3($5) + sll $25,$3,5 # 13 + addu $2,$31 + lwr $22,14*4+0($5) + srl $6,$3,27 + addu $2,$25 + xor $25,$24,$1 + addu $2,$6 + sll $30,$7,30 + and $25,$7 + srl $7,$7,2 + xor $25,$1 + addu $2,$21 + or $7,$30 + addu $2,$25 + srl $25,$22,24 # byte swap(14) + srl $6,$22,8 + andi $30,$22,0xFF00 + sll $22,$22,24 + andi $6,0xFF00 + sll $30,$30,8 + or $22,$25 + or $6,$30 + or $22,$6 + lwl $23,15*4+3($5) + sll $25,$2,5 # 14 + addu $1,$31 + lwr $23,15*4+0($5) + srl $6,$2,27 + addu $1,$25 + xor $25,$7,$24 + addu $1,$6 + sll $30,$3,30 + and $25,$3 + srl $3,$3,2 + xor $25,$24 + addu $1,$22 + or $3,$30 + addu $1,$25 + srl $25,$23,24 # byte swap(15) + srl $6,$23,8 + andi $30,$23,0xFF00 + sll $23,$23,24 + andi $6,0xFF00 + sll $30,$30,8 + or $23,$25 + or $23,$6 + or $23,$30 + xor $8,$10 + sll $25,$1,5 # 15 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $8,$16 + xor $25,$3,$7 + addu $24,$6 + xor $8,$21 + sll $30,$2,30 + and $25,$2 + srl $6,$8,31 + addu $8,$8 + srl $2,$2,2 + xor $25,$7 + or $8,$6 + addu $24,$23 + or $2,$30 + addu $24,$25 + xor $9,$11 + sll $25,$24,5 # 16 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $9,$17 + xor $25,$2,$3 + addu $7,$6 + xor $9,$22 + sll $30,$1,30 + and $25,$1 + srl $6,$9,31 + addu $9,$9 + srl $1,$1,2 + xor $25,$3 + or $9,$6 + addu $7,$8 + or $1,$30 + addu $7,$25 + xor $10,$12 + sll $25,$7,5 # 17 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $10,$18 + xor $25,$1,$2 + addu $3,$6 + xor $10,$23 + sll $30,$24,30 + and $25,$24 + srl $6,$10,31 + addu $10,$10 + srl $24,$24,2 + xor $25,$2 + or $10,$6 + addu $3,$9 + or $24,$30 + addu $3,$25 + xor $11,$13 + sll $25,$3,5 # 18 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $11,$19 + xor $25,$24,$1 + addu $2,$6 + xor $11,$8 + sll $30,$7,30 + and $25,$7 + srl $6,$11,31 + addu $11,$11 + srl $7,$7,2 + xor $25,$1 + or $11,$6 + addu $2,$10 + or $7,$30 + addu $2,$25 + xor $12,$14 + sll $25,$2,5 # 19 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $12,$20 + xor $25,$7,$24 + addu $1,$6 + xor $12,$9 + sll $30,$3,30 + and $25,$3 + srl $6,$12,31 + addu $12,$12 + srl $3,$3,2 + xor $25,$24 + or $12,$6 + addu $1,$11 + or $3,$30 + addu $1,$25 + lui $31,0x6ed9 + ori $31,0xeba1 # K_20_39 + xor $13,$15 + sll $25,$1,5 # 20 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $13,$21 + xor $25,$3,$7 + addu $24,$6 + xor $13,$10 + sll $30,$2,30 + xor $25,$2 + srl $6,$13,31 + addu $13,$13 + srl $2,$2,2 + addu $24,$12 + or $13,$6 + or $2,$30 + addu $24,$25 + xor $14,$16 + sll $25,$24,5 # 21 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $14,$22 + xor $25,$2,$3 + addu $7,$6 + xor $14,$11 + sll $30,$1,30 + xor $25,$1 + srl $6,$14,31 + addu $14,$14 + srl $1,$1,2 + addu $7,$13 + or $14,$6 + or $1,$30 + addu $7,$25 + xor $15,$17 + sll $25,$7,5 # 22 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $15,$23 + xor $25,$1,$2 + addu $3,$6 + xor $15,$12 + sll $30,$24,30 + xor $25,$24 + srl $6,$15,31 + addu $15,$15 + srl $24,$24,2 + addu $3,$14 + or $15,$6 + or $24,$30 + addu $3,$25 + xor $16,$18 + sll $25,$3,5 # 23 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $16,$8 + xor $25,$24,$1 + addu $2,$6 + xor $16,$13 + sll $30,$7,30 + xor $25,$7 + srl $6,$16,31 + addu $16,$16 + srl $7,$7,2 + addu $2,$15 + or $16,$6 + or $7,$30 + addu $2,$25 + xor $17,$19 + sll $25,$2,5 # 24 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $17,$9 + xor $25,$7,$24 + addu $1,$6 + xor $17,$14 + sll $30,$3,30 + xor $25,$3 + srl $6,$17,31 + addu $17,$17 + srl $3,$3,2 + addu $1,$16 + or $17,$6 + or $3,$30 + addu $1,$25 + xor $18,$20 + sll $25,$1,5 # 25 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $18,$10 + xor $25,$3,$7 + addu $24,$6 + xor $18,$15 + sll $30,$2,30 + xor $25,$2 + srl $6,$18,31 + addu $18,$18 + srl $2,$2,2 + addu $24,$17 + or $18,$6 + or $2,$30 + addu $24,$25 + xor $19,$21 + sll $25,$24,5 # 26 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $19,$11 + xor $25,$2,$3 + addu $7,$6 + xor $19,$16 + sll $30,$1,30 + xor $25,$1 + srl $6,$19,31 + addu $19,$19 + srl $1,$1,2 + addu $7,$18 + or $19,$6 + or $1,$30 + addu $7,$25 + xor $20,$22 + sll $25,$7,5 # 27 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $20,$12 + xor $25,$1,$2 + addu $3,$6 + xor $20,$17 + sll $30,$24,30 + xor $25,$24 + srl $6,$20,31 + addu $20,$20 + srl $24,$24,2 + addu $3,$19 + or $20,$6 + or $24,$30 + addu $3,$25 + xor $21,$23 + sll $25,$3,5 # 28 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $21,$13 + xor $25,$24,$1 + addu $2,$6 + xor $21,$18 + sll $30,$7,30 + xor $25,$7 + srl $6,$21,31 + addu $21,$21 + srl $7,$7,2 + addu $2,$20 + or $21,$6 + or $7,$30 + addu $2,$25 + xor $22,$8 + sll $25,$2,5 # 29 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $22,$14 + xor $25,$7,$24 + addu $1,$6 + xor $22,$19 + sll $30,$3,30 + xor $25,$3 + srl $6,$22,31 + addu $22,$22 + srl $3,$3,2 + addu $1,$21 + or $22,$6 + or $3,$30 + addu $1,$25 + xor $23,$9 + sll $25,$1,5 # 30 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $23,$15 + xor $25,$3,$7 + addu $24,$6 + xor $23,$20 + sll $30,$2,30 + xor $25,$2 + srl $6,$23,31 + addu $23,$23 + srl $2,$2,2 + addu $24,$22 + or $23,$6 + or $2,$30 + addu $24,$25 + xor $8,$10 + sll $25,$24,5 # 31 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $8,$16 + xor $25,$2,$3 + addu $7,$6 + xor $8,$21 + sll $30,$1,30 + xor $25,$1 + srl $6,$8,31 + addu $8,$8 + srl $1,$1,2 + addu $7,$23 + or $8,$6 + or $1,$30 + addu $7,$25 + xor $9,$11 + sll $25,$7,5 # 32 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $9,$17 + xor $25,$1,$2 + addu $3,$6 + xor $9,$22 + sll $30,$24,30 + xor $25,$24 + srl $6,$9,31 + addu $9,$9 + srl $24,$24,2 + addu $3,$8 + or $9,$6 + or $24,$30 + addu $3,$25 + xor $10,$12 + sll $25,$3,5 # 33 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $10,$18 + xor $25,$24,$1 + addu $2,$6 + xor $10,$23 + sll $30,$7,30 + xor $25,$7 + srl $6,$10,31 + addu $10,$10 + srl $7,$7,2 + addu $2,$9 + or $10,$6 + or $7,$30 + addu $2,$25 + xor $11,$13 + sll $25,$2,5 # 34 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $11,$19 + xor $25,$7,$24 + addu $1,$6 + xor $11,$8 + sll $30,$3,30 + xor $25,$3 + srl $6,$11,31 + addu $11,$11 + srl $3,$3,2 + addu $1,$10 + or $11,$6 + or $3,$30 + addu $1,$25 + xor $12,$14 + sll $25,$1,5 # 35 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $12,$20 + xor $25,$3,$7 + addu $24,$6 + xor $12,$9 + sll $30,$2,30 + xor $25,$2 + srl $6,$12,31 + addu $12,$12 + srl $2,$2,2 + addu $24,$11 + or $12,$6 + or $2,$30 + addu $24,$25 + xor $13,$15 + sll $25,$24,5 # 36 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $13,$21 + xor $25,$2,$3 + addu $7,$6 + xor $13,$10 + sll $30,$1,30 + xor $25,$1 + srl $6,$13,31 + addu $13,$13 + srl $1,$1,2 + addu $7,$12 + or $13,$6 + or $1,$30 + addu $7,$25 + xor $14,$16 + sll $25,$7,5 # 37 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $14,$22 + xor $25,$1,$2 + addu $3,$6 + xor $14,$11 + sll $30,$24,30 + xor $25,$24 + srl $6,$14,31 + addu $14,$14 + srl $24,$24,2 + addu $3,$13 + or $14,$6 + or $24,$30 + addu $3,$25 + xor $15,$17 + sll $25,$3,5 # 38 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $15,$23 + xor $25,$24,$1 + addu $2,$6 + xor $15,$12 + sll $30,$7,30 + xor $25,$7 + srl $6,$15,31 + addu $15,$15 + srl $7,$7,2 + addu $2,$14 + or $15,$6 + or $7,$30 + addu $2,$25 + xor $16,$18 + sll $25,$2,5 # 39 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $16,$8 + xor $25,$7,$24 + addu $1,$6 + xor $16,$13 + sll $30,$3,30 + xor $25,$3 + srl $6,$16,31 + addu $16,$16 + srl $3,$3,2 + addu $1,$15 + or $16,$6 + or $3,$30 + addu $1,$25 + lui $31,0x8f1b + ori $31,0xbcdc # K_40_59 + xor $17,$19 + sll $25,$1,5 # 40 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $17,$9 + and $25,$3,$7 + addu $24,$6 + xor $17,$14 + sll $30,$2,30 + addu $24,$25 + srl $6,$17,31 + xor $25,$3,$7 + addu $17,$17 + and $25,$2 + srl $2,$2,2 + or $17,$6 + addu $24,$16 + or $2,$30 + addu $24,$25 + xor $18,$20 + sll $25,$24,5 # 41 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $18,$10 + and $25,$2,$3 + addu $7,$6 + xor $18,$15 + sll $30,$1,30 + addu $7,$25 + srl $6,$18,31 + xor $25,$2,$3 + addu $18,$18 + and $25,$1 + srl $1,$1,2 + or $18,$6 + addu $7,$17 + or $1,$30 + addu $7,$25 + xor $19,$21 + sll $25,$7,5 # 42 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $19,$11 + and $25,$1,$2 + addu $3,$6 + xor $19,$16 + sll $30,$24,30 + addu $3,$25 + srl $6,$19,31 + xor $25,$1,$2 + addu $19,$19 + and $25,$24 + srl $24,$24,2 + or $19,$6 + addu $3,$18 + or $24,$30 + addu $3,$25 + xor $20,$22 + sll $25,$3,5 # 43 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $20,$12 + and $25,$24,$1 + addu $2,$6 + xor $20,$17 + sll $30,$7,30 + addu $2,$25 + srl $6,$20,31 + xor $25,$24,$1 + addu $20,$20 + and $25,$7 + srl $7,$7,2 + or $20,$6 + addu $2,$19 + or $7,$30 + addu $2,$25 + xor $21,$23 + sll $25,$2,5 # 44 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $21,$13 + and $25,$7,$24 + addu $1,$6 + xor $21,$18 + sll $30,$3,30 + addu $1,$25 + srl $6,$21,31 + xor $25,$7,$24 + addu $21,$21 + and $25,$3 + srl $3,$3,2 + or $21,$6 + addu $1,$20 + or $3,$30 + addu $1,$25 + xor $22,$8 + sll $25,$1,5 # 45 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $22,$14 + and $25,$3,$7 + addu $24,$6 + xor $22,$19 + sll $30,$2,30 + addu $24,$25 + srl $6,$22,31 + xor $25,$3,$7 + addu $22,$22 + and $25,$2 + srl $2,$2,2 + or $22,$6 + addu $24,$21 + or $2,$30 + addu $24,$25 + xor $23,$9 + sll $25,$24,5 # 46 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $23,$15 + and $25,$2,$3 + addu $7,$6 + xor $23,$20 + sll $30,$1,30 + addu $7,$25 + srl $6,$23,31 + xor $25,$2,$3 + addu $23,$23 + and $25,$1 + srl $1,$1,2 + or $23,$6 + addu $7,$22 + or $1,$30 + addu $7,$25 + xor $8,$10 + sll $25,$7,5 # 47 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $8,$16 + and $25,$1,$2 + addu $3,$6 + xor $8,$21 + sll $30,$24,30 + addu $3,$25 + srl $6,$8,31 + xor $25,$1,$2 + addu $8,$8 + and $25,$24 + srl $24,$24,2 + or $8,$6 + addu $3,$23 + or $24,$30 + addu $3,$25 + xor $9,$11 + sll $25,$3,5 # 48 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $9,$17 + and $25,$24,$1 + addu $2,$6 + xor $9,$22 + sll $30,$7,30 + addu $2,$25 + srl $6,$9,31 + xor $25,$24,$1 + addu $9,$9 + and $25,$7 + srl $7,$7,2 + or $9,$6 + addu $2,$8 + or $7,$30 + addu $2,$25 + xor $10,$12 + sll $25,$2,5 # 49 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $10,$18 + and $25,$7,$24 + addu $1,$6 + xor $10,$23 + sll $30,$3,30 + addu $1,$25 + srl $6,$10,31 + xor $25,$7,$24 + addu $10,$10 + and $25,$3 + srl $3,$3,2 + or $10,$6 + addu $1,$9 + or $3,$30 + addu $1,$25 + xor $11,$13 + sll $25,$1,5 # 50 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $11,$19 + and $25,$3,$7 + addu $24,$6 + xor $11,$8 + sll $30,$2,30 + addu $24,$25 + srl $6,$11,31 + xor $25,$3,$7 + addu $11,$11 + and $25,$2 + srl $2,$2,2 + or $11,$6 + addu $24,$10 + or $2,$30 + addu $24,$25 + xor $12,$14 + sll $25,$24,5 # 51 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $12,$20 + and $25,$2,$3 + addu $7,$6 + xor $12,$9 + sll $30,$1,30 + addu $7,$25 + srl $6,$12,31 + xor $25,$2,$3 + addu $12,$12 + and $25,$1 + srl $1,$1,2 + or $12,$6 + addu $7,$11 + or $1,$30 + addu $7,$25 + xor $13,$15 + sll $25,$7,5 # 52 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $13,$21 + and $25,$1,$2 + addu $3,$6 + xor $13,$10 + sll $30,$24,30 + addu $3,$25 + srl $6,$13,31 + xor $25,$1,$2 + addu $13,$13 + and $25,$24 + srl $24,$24,2 + or $13,$6 + addu $3,$12 + or $24,$30 + addu $3,$25 + xor $14,$16 + sll $25,$3,5 # 53 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $14,$22 + and $25,$24,$1 + addu $2,$6 + xor $14,$11 + sll $30,$7,30 + addu $2,$25 + srl $6,$14,31 + xor $25,$24,$1 + addu $14,$14 + and $25,$7 + srl $7,$7,2 + or $14,$6 + addu $2,$13 + or $7,$30 + addu $2,$25 + xor $15,$17 + sll $25,$2,5 # 54 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $15,$23 + and $25,$7,$24 + addu $1,$6 + xor $15,$12 + sll $30,$3,30 + addu $1,$25 + srl $6,$15,31 + xor $25,$7,$24 + addu $15,$15 + and $25,$3 + srl $3,$3,2 + or $15,$6 + addu $1,$14 + or $3,$30 + addu $1,$25 + xor $16,$18 + sll $25,$1,5 # 55 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $16,$8 + and $25,$3,$7 + addu $24,$6 + xor $16,$13 + sll $30,$2,30 + addu $24,$25 + srl $6,$16,31 + xor $25,$3,$7 + addu $16,$16 + and $25,$2 + srl $2,$2,2 + or $16,$6 + addu $24,$15 + or $2,$30 + addu $24,$25 + xor $17,$19 + sll $25,$24,5 # 56 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $17,$9 + and $25,$2,$3 + addu $7,$6 + xor $17,$14 + sll $30,$1,30 + addu $7,$25 + srl $6,$17,31 + xor $25,$2,$3 + addu $17,$17 + and $25,$1 + srl $1,$1,2 + or $17,$6 + addu $7,$16 + or $1,$30 + addu $7,$25 + xor $18,$20 + sll $25,$7,5 # 57 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $18,$10 + and $25,$1,$2 + addu $3,$6 + xor $18,$15 + sll $30,$24,30 + addu $3,$25 + srl $6,$18,31 + xor $25,$1,$2 + addu $18,$18 + and $25,$24 + srl $24,$24,2 + or $18,$6 + addu $3,$17 + or $24,$30 + addu $3,$25 + xor $19,$21 + sll $25,$3,5 # 58 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $19,$11 + and $25,$24,$1 + addu $2,$6 + xor $19,$16 + sll $30,$7,30 + addu $2,$25 + srl $6,$19,31 + xor $25,$24,$1 + addu $19,$19 + and $25,$7 + srl $7,$7,2 + or $19,$6 + addu $2,$18 + or $7,$30 + addu $2,$25 + xor $20,$22 + sll $25,$2,5 # 59 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $20,$12 + and $25,$7,$24 + addu $1,$6 + xor $20,$17 + sll $30,$3,30 + addu $1,$25 + srl $6,$20,31 + xor $25,$7,$24 + addu $20,$20 + and $25,$3 + srl $3,$3,2 + or $20,$6 + addu $1,$19 + or $3,$30 + addu $1,$25 + lui $31,0xca62 + ori $31,0xc1d6 # K_60_79 + xor $21,$23 + sll $25,$1,5 # 60 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $21,$13 + xor $25,$3,$7 + addu $24,$6 + xor $21,$18 + sll $30,$2,30 + xor $25,$2 + srl $6,$21,31 + addu $21,$21 + srl $2,$2,2 + addu $24,$20 + or $21,$6 + or $2,$30 + addu $24,$25 + xor $22,$8 + sll $25,$24,5 # 61 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $22,$14 + xor $25,$2,$3 + addu $7,$6 + xor $22,$19 + sll $30,$1,30 + xor $25,$1 + srl $6,$22,31 + addu $22,$22 + srl $1,$1,2 + addu $7,$21 + or $22,$6 + or $1,$30 + addu $7,$25 + xor $23,$9 + sll $25,$7,5 # 62 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $23,$15 + xor $25,$1,$2 + addu $3,$6 + xor $23,$20 + sll $30,$24,30 + xor $25,$24 + srl $6,$23,31 + addu $23,$23 + srl $24,$24,2 + addu $3,$22 + or $23,$6 + or $24,$30 + addu $3,$25 + xor $8,$10 + sll $25,$3,5 # 63 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $8,$16 + xor $25,$24,$1 + addu $2,$6 + xor $8,$21 + sll $30,$7,30 + xor $25,$7 + srl $6,$8,31 + addu $8,$8 + srl $7,$7,2 + addu $2,$23 + or $8,$6 + or $7,$30 + addu $2,$25 + xor $9,$11 + sll $25,$2,5 # 64 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $9,$17 + xor $25,$7,$24 + addu $1,$6 + xor $9,$22 + sll $30,$3,30 + xor $25,$3 + srl $6,$9,31 + addu $9,$9 + srl $3,$3,2 + addu $1,$8 + or $9,$6 + or $3,$30 + addu $1,$25 + xor $10,$12 + sll $25,$1,5 # 65 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $10,$18 + xor $25,$3,$7 + addu $24,$6 + xor $10,$23 + sll $30,$2,30 + xor $25,$2 + srl $6,$10,31 + addu $10,$10 + srl $2,$2,2 + addu $24,$9 + or $10,$6 + or $2,$30 + addu $24,$25 + xor $11,$13 + sll $25,$24,5 # 66 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $11,$19 + xor $25,$2,$3 + addu $7,$6 + xor $11,$8 + sll $30,$1,30 + xor $25,$1 + srl $6,$11,31 + addu $11,$11 + srl $1,$1,2 + addu $7,$10 + or $11,$6 + or $1,$30 + addu $7,$25 + xor $12,$14 + sll $25,$7,5 # 67 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $12,$20 + xor $25,$1,$2 + addu $3,$6 + xor $12,$9 + sll $30,$24,30 + xor $25,$24 + srl $6,$12,31 + addu $12,$12 + srl $24,$24,2 + addu $3,$11 + or $12,$6 + or $24,$30 + addu $3,$25 + xor $13,$15 + sll $25,$3,5 # 68 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $13,$21 + xor $25,$24,$1 + addu $2,$6 + xor $13,$10 + sll $30,$7,30 + xor $25,$7 + srl $6,$13,31 + addu $13,$13 + srl $7,$7,2 + addu $2,$12 + or $13,$6 + or $7,$30 + addu $2,$25 + xor $14,$16 + sll $25,$2,5 # 69 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $14,$22 + xor $25,$7,$24 + addu $1,$6 + xor $14,$11 + sll $30,$3,30 + xor $25,$3 + srl $6,$14,31 + addu $14,$14 + srl $3,$3,2 + addu $1,$13 + or $14,$6 + or $3,$30 + addu $1,$25 + xor $15,$17 + sll $25,$1,5 # 70 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $15,$23 + xor $25,$3,$7 + addu $24,$6 + xor $15,$12 + sll $30,$2,30 + xor $25,$2 + srl $6,$15,31 + addu $15,$15 + srl $2,$2,2 + addu $24,$14 + or $15,$6 + or $2,$30 + addu $24,$25 + xor $16,$18 + sll $25,$24,5 # 71 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $16,$8 + xor $25,$2,$3 + addu $7,$6 + xor $16,$13 + sll $30,$1,30 + xor $25,$1 + srl $6,$16,31 + addu $16,$16 + srl $1,$1,2 + addu $7,$15 + or $16,$6 + or $1,$30 + addu $7,$25 + xor $17,$19 + sll $25,$7,5 # 72 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $17,$9 + xor $25,$1,$2 + addu $3,$6 + xor $17,$14 + sll $30,$24,30 + xor $25,$24 + srl $6,$17,31 + addu $17,$17 + srl $24,$24,2 + addu $3,$16 + or $17,$6 + or $24,$30 + addu $3,$25 + xor $18,$20 + sll $25,$3,5 # 73 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $18,$10 + xor $25,$24,$1 + addu $2,$6 + xor $18,$15 + sll $30,$7,30 + xor $25,$7 + srl $6,$18,31 + addu $18,$18 + srl $7,$7,2 + addu $2,$17 + or $18,$6 + or $7,$30 + addu $2,$25 + xor $19,$21 + sll $25,$2,5 # 74 + addu $1,$31 + srl $6,$2,27 + addu $1,$25 + xor $19,$11 + xor $25,$7,$24 + addu $1,$6 + xor $19,$16 + sll $30,$3,30 + xor $25,$3 + srl $6,$19,31 + addu $19,$19 + srl $3,$3,2 + addu $1,$18 + or $19,$6 + or $3,$30 + addu $1,$25 + xor $20,$22 + sll $25,$1,5 # 75 + addu $24,$31 + srl $6,$1,27 + addu $24,$25 + xor $20,$12 + xor $25,$3,$7 + addu $24,$6 + xor $20,$17 + sll $30,$2,30 + xor $25,$2 + srl $6,$20,31 + addu $20,$20 + srl $2,$2,2 + addu $24,$19 + or $20,$6 + or $2,$30 + addu $24,$25 + xor $21,$23 + sll $25,$24,5 # 76 + addu $7,$31 + srl $6,$24,27 + addu $7,$25 + xor $21,$13 + xor $25,$2,$3 + addu $7,$6 + xor $21,$18 + sll $30,$1,30 + xor $25,$1 + srl $6,$21,31 + addu $21,$21 + srl $1,$1,2 + addu $7,$20 + or $21,$6 + or $1,$30 + addu $7,$25 + xor $22,$8 + sll $25,$7,5 # 77 + addu $3,$31 + srl $6,$7,27 + addu $3,$25 + xor $22,$14 + xor $25,$1,$2 + addu $3,$6 + xor $22,$19 + sll $30,$24,30 + xor $25,$24 + srl $6,$22,31 + addu $22,$22 + srl $24,$24,2 + addu $3,$21 + or $22,$6 + or $24,$30 + addu $3,$25 + xor $23,$9 + sll $25,$3,5 # 78 + addu $2,$31 + srl $6,$3,27 + addu $2,$25 + xor $23,$15 + xor $25,$24,$1 + addu $2,$6 + xor $23,$20 + sll $30,$7,30 + xor $25,$7 + srl $6,$23,31 + addu $23,$23 + srl $7,$7,2 + addu $2,$22 + or $23,$6 + or $7,$30 + addu $2,$25 + lw $8,0($4) + sll $25,$2,5 # 79 + addu $1,$31 + lw $9,4($4) + srl $6,$2,27 + addu $1,$25 + lw $10,8($4) + xor $25,$7,$24 + addu $1,$6 + lw $11,12($4) + sll $30,$3,30 + xor $25,$3 + lw $12,16($4) + srl $3,$3,2 + addu $1,$23 + or $3,$30 + addu $1,$25 + add $5,64 + lw $6,0($29) + + addu $1,$8 + addu $2,$9 + sw $1,0($4) + addu $3,$10 + addu $7,$11 + sw $2,4($4) + addu $24,$12 + sw $3,8($4) + sw $7,12($4) + sw $24,16($4) + .set noreorder + bne $5,$6,.Loop + nop + + .set noreorder + lw $31,(16-1)*4($29) + lw $30,(16-2)*4($29) + lw $23,(16-3)*4($29) + lw $22,(16-4)*4($29) + lw $21,(16-5)*4($29) + lw $20,(16-6)*4($29) + lw $19,(16-7)*4($29) + lw $18,(16-8)*4($29) + lw $17,(16-9)*4($29) + lw $16,(16-10)*4($29) + jr $31 + add $29,16*4 +.end sha1_block_data_order +.rdata +.asciiz "SHA1 for MIPS, CRYPTOGAMS by " +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha1.c b/Libraries/libressl/crypto/sha/sha1.c new file mode 100644 index 000000000..4b48653bd --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha1.c @@ -0,0 +1,476 @@ +/* $OpenBSD: sha1.c,v 1.12 2023/08/10 07:15:23 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include + +#include +#include + +#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA) + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK SHA_CBLOCK + +#define HASH_BLOCK_DATA_ORDER sha1_block_data_order +#define Xupdate(a, ix, ia, ib, ic, id) ( (a)=(ia^ib^ic^id), \ + ix=(a)=ROTATE((a),1) \ + ) + +#ifndef SHA1_ASM +static +#endif +void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num); + +#define HASH_NO_UPDATE +#define HASH_NO_TRANSFORM +#define HASH_NO_FINAL + +#include "md32_common.h" + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +/* As pointed out by Wei Dai , F() below can be + * simplified to the code in F_00_19. Wei attributes these optimisations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) + * I've just become aware of another tweak to be made, again from Wei Dai, + * in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b, c, d) ((b) ^ (c) ^ (d)) +#define F_40_59(b, c, d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b, c, d) F_20_39(b, c, d) + + +#define BODY_00_15(i, a, b, c, d, e, f, xi) \ + (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + Xupdate(f, xi, xa, xb, xc, xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + Xupdate(f, xi, xa, xb, xc, xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + Xupdate(f, xa, xa, xb, xc, xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + Xupdate(f, xa, xa, xb, xc, xd); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + Xupdate(f, xa, xa, xb, xc, xd); \ + (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#if !defined(SHA1_ASM) +#include +static void +sha1_block_data_order(SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = p; + unsigned int A, B, C, D, E, T, l; + unsigned int X0, X1, X2, X3, X4, X5, X6, X7, + X8, X9, X10, X11, X12, X13, X14, X15; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + + if (BYTE_ORDER != LITTLE_ENDIAN && + sizeof(SHA_LONG) == 4 && ((size_t)p % 4) == 0) { + const SHA_LONG *W = (const SHA_LONG *)data; + + X0 = W[0]; + X1 = W[1]; + BODY_00_15( 0, A, B, C, D, E, T, X0); + X2 = W[2]; + BODY_00_15( 1, T, A, B, C, D, E, X1); + X3 = W[3]; + BODY_00_15( 2, E, T, A, B, C, D, X2); + X4 = W[4]; + BODY_00_15( 3, D, E, T, A, B, C, X3); + X5 = W[5]; + BODY_00_15( 4, C, D, E, T, A, B, X4); + X6 = W[6]; + BODY_00_15( 5, B, C, D, E, T, A, X5); + X7 = W[7]; + BODY_00_15( 6, A, B, C, D, E, T, X6); + X8 = W[8]; + BODY_00_15( 7, T, A, B, C, D, E, X7); + X9 = W[9]; + BODY_00_15( 8, E, T, A, B, C, D, X8); + X10 = W[10]; + BODY_00_15( 9, D, E, T, A, B, C, X9); + X11 = W[11]; + BODY_00_15(10, C, D, E, T, A, B, X10); + X12 = W[12]; + BODY_00_15(11, B, C, D, E, T, A, X11); + X13 = W[13]; + BODY_00_15(12, A, B, C, D, E, T, X12); + X14 = W[14]; + BODY_00_15(13, T, A, B, C, D, E, X13); + X15 = W[15]; + BODY_00_15(14, E, T, A, B, C, D, X14); + BODY_00_15(15, D, E, T, A, B, C, X15); + + data += SHA_CBLOCK; + } else { + HOST_c2l(data, l); + X0 = l; + HOST_c2l(data, l); + X1 = l; + BODY_00_15( 0, A, B, C, D, E, T, X0); + HOST_c2l(data, l); + X2 = l; + BODY_00_15( 1, T, A, B, C, D, E, X1); + HOST_c2l(data, l); + X3 = l; + BODY_00_15( 2, E, T, A, B, C, D, X2); + HOST_c2l(data, l); + X4 = l; + BODY_00_15( 3, D, E, T, A, B, C, X3); + HOST_c2l(data, l); + X5 = l; + BODY_00_15( 4, C, D, E, T, A, B, X4); + HOST_c2l(data, l); + X6 = l; + BODY_00_15( 5, B, C, D, E, T, A, X5); + HOST_c2l(data, l); + X7 = l; + BODY_00_15( 6, A, B, C, D, E, T, X6); + HOST_c2l(data, l); + X8 = l; + BODY_00_15( 7, T, A, B, C, D, E, X7); + HOST_c2l(data, l); + X9 = l; + BODY_00_15( 8, E, T, A, B, C, D, X8); + HOST_c2l(data, l); + X10 = l; + BODY_00_15( 9, D, E, T, A, B, C, X9); + HOST_c2l(data, l); + X11 = l; + BODY_00_15(10, C, D, E, T, A, B, X10); + HOST_c2l(data, l); + X12 = l; + BODY_00_15(11, B, C, D, E, T, A, X11); + HOST_c2l(data, l); + X13 = l; + BODY_00_15(12, A, B, C, D, E, T, X12); + HOST_c2l(data, l); + X14 = l; + BODY_00_15(13, T, A, B, C, D, E, X13); + HOST_c2l(data, l); + X15 = l; + BODY_00_15(14, E, T, A, B, C, D, X14); + BODY_00_15(15, D, E, T, A, B, C, X15); + } + + BODY_16_19(16, C, D, E, T, A, B, X0, X0, X2, X8, X13); + BODY_16_19(17, B, C, D, E, T, A, X1, X1, X3, X9, X14); + BODY_16_19(18, A, B, C, D, E, T, X2, X2, X4, X10, X15); + BODY_16_19(19, T, A, B, C, D, E, X3, X3, X5, X11, X0); + + BODY_20_31(20, E, T, A, B, C, D, X4, X4, X6, X12, X1); + BODY_20_31(21, D, E, T, A, B, C, X5, X5, X7, X13, X2); + BODY_20_31(22, C, D, E, T, A, B, X6, X6, X8, X14, X3); + BODY_20_31(23, B, C, D, E, T, A, X7, X7, X9, X15, X4); + BODY_20_31(24, A, B, C, D, E, T, X8, X8, X10, X0, X5); + BODY_20_31(25, T, A, B, C, D, E, X9, X9, X11, X1, X6); + BODY_20_31(26, E, T, A, B, C, D, X10, X10, X12, X2, X7); + BODY_20_31(27, D, E, T, A, B, C, X11, X11, X13, X3, X8); + BODY_20_31(28, C, D, E, T, A, B, X12, X12, X14, X4, X9); + BODY_20_31(29, B, C, D, E, T, A, X13, X13, X15, X5, X10); + BODY_20_31(30, A, B, C, D, E, T, X14, X14, X0, X6, X11); + BODY_20_31(31, T, A, B, C, D, E, X15, X15, X1, X7, X12); + + BODY_32_39(32, E, T, A, B, C, D, X0, X2, X8, X13); + BODY_32_39(33, D, E, T, A, B, C, X1, X3, X9, X14); + BODY_32_39(34, C, D, E, T, A, B, X2, X4, X10, X15); + BODY_32_39(35, B, C, D, E, T, A, X3, X5, X11, X0); + BODY_32_39(36, A, B, C, D, E, T, X4, X6, X12, X1); + BODY_32_39(37, T, A, B, C, D, E, X5, X7, X13, X2); + BODY_32_39(38, E, T, A, B, C, D, X6, X8, X14, X3); + BODY_32_39(39, D, E, T, A, B, C, X7, X9, X15, X4); + + BODY_40_59(40, C, D, E, T, A, B, X8, X10, X0, X5); + BODY_40_59(41, B, C, D, E, T, A, X9, X11, X1, X6); + BODY_40_59(42, A, B, C, D, E, T, X10, X12, X2, X7); + BODY_40_59(43, T, A, B, C, D, E, X11, X13, X3, X8); + BODY_40_59(44, E, T, A, B, C, D, X12, X14, X4, X9); + BODY_40_59(45, D, E, T, A, B, C, X13, X15, X5, X10); + BODY_40_59(46, C, D, E, T, A, B, X14, X0, X6, X11); + BODY_40_59(47, B, C, D, E, T, A, X15, X1, X7, X12); + BODY_40_59(48, A, B, C, D, E, T, X0, X2, X8, X13); + BODY_40_59(49, T, A, B, C, D, E, X1, X3, X9, X14); + BODY_40_59(50, E, T, A, B, C, D, X2, X4, X10, X15); + BODY_40_59(51, D, E, T, A, B, C, X3, X5, X11, X0); + BODY_40_59(52, C, D, E, T, A, B, X4, X6, X12, X1); + BODY_40_59(53, B, C, D, E, T, A, X5, X7, X13, X2); + BODY_40_59(54, A, B, C, D, E, T, X6, X8, X14, X3); + BODY_40_59(55, T, A, B, C, D, E, X7, X9, X15, X4); + BODY_40_59(56, E, T, A, B, C, D, X8, X10, X0, X5); + BODY_40_59(57, D, E, T, A, B, C, X9, X11, X1, X6); + BODY_40_59(58, C, D, E, T, A, B, X10, X12, X2, X7); + BODY_40_59(59, B, C, D, E, T, A, X11, X13, X3, X8); + + BODY_60_79(60, A, B, C, D, E, T, X12, X14, X4, X9); + BODY_60_79(61, T, A, B, C, D, E, X13, X15, X5, X10); + BODY_60_79(62, E, T, A, B, C, D, X14, X0, X6, X11); + BODY_60_79(63, D, E, T, A, B, C, X15, X1, X7, X12); + BODY_60_79(64, C, D, E, T, A, B, X0, X2, X8, X13); + BODY_60_79(65, B, C, D, E, T, A, X1, X3, X9, X14); + BODY_60_79(66, A, B, C, D, E, T, X2, X4, X10, X15); + BODY_60_79(67, T, A, B, C, D, E, X3, X5, X11, X0); + BODY_60_79(68, E, T, A, B, C, D, X4, X6, X12, X1); + BODY_60_79(69, D, E, T, A, B, C, X5, X7, X13, X2); + BODY_60_79(70, C, D, E, T, A, B, X6, X8, X14, X3); + BODY_60_79(71, B, C, D, E, T, A, X7, X9, X15, X4); + BODY_60_79(72, A, B, C, D, E, T, X8, X10, X0, X5); + BODY_60_79(73, T, A, B, C, D, E, X9, X11, X1, X6); + BODY_60_79(74, E, T, A, B, C, D, X10, X12, X2, X7); + BODY_60_79(75, D, E, T, A, B, C, X11, X13, X3, X8); + BODY_60_79(76, C, D, E, T, A, B, X12, X14, X4, X9); + BODY_60_79(77, B, C, D, E, T, A, X13, X15, X5, X10); + BODY_60_79(78, A, B, C, D, E, T, X14, X0, X6, X11); + BODY_60_79(79, T, A, B, C, D, E, X15, X1, X7, X12); + + c->h0 = (c->h0 + E)&0xffffffffL; + c->h1 = (c->h1 + T)&0xffffffffL; + c->h2 = (c->h2 + A)&0xffffffffL; + c->h3 = (c->h3 + B)&0xffffffffL; + c->h4 = (c->h4 + C)&0xffffffffL; + + if (--num == 0) + break; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +#endif + + +int +SHA1_Init(SHA_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + c->h0 = 0x67452301UL; + c->h1 = 0xefcdab89UL; + c->h2 = 0x98badcfeUL; + c->h3 = 0x10325476UL; + c->h4 = 0xc3d2e1f0UL; + + return 1; +} +LCRYPTO_ALIAS(SHA1_Init); + +int +SHA1_Update(SHA_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + SHA_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((SHA_LONG)len) << 3))&0xffffffffUL; + /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to + * Wei Dai for pointing it out. */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh+=(SHA_LONG)(len>>29); /* might cause compiler warning on 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= SHA_CBLOCK || len + n >= SHA_CBLOCK) { + memcpy(p + n, data, SHA_CBLOCK - n); + sha1_block_data_order(c, p, 1); + n = SHA_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset(p,0,SHA_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len/SHA_CBLOCK; + if (n > 0) { + sha1_block_data_order(c, data, n); + n *= SHA_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} +LCRYPTO_ALIAS(SHA1_Update); + +void +SHA1_Transform(SHA_CTX *c, const unsigned char *data) +{ + sha1_block_data_order(c, data, 1); +} +LCRYPTO_ALIAS(SHA1_Transform); + +int +SHA1_Final(unsigned char *md, SHA_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + unsigned long ll; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (SHA_CBLOCK - 8)) { + memset(p + n, 0, SHA_CBLOCK - n); + n = 0; + sha1_block_data_order(c, p, 1); + } + memset(p + n, 0, SHA_CBLOCK - 8 - n); + + p += SHA_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + HOST_l2c(c->Nh, p); + HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); +#endif + p -= SHA_CBLOCK; + sha1_block_data_order(c, p, 1); + c->num = 0; + memset(p, 0, SHA_CBLOCK); + + ll = c->h0; + HOST_l2c(ll, md); + ll = c->h1; + HOST_l2c(ll, md); + ll = c->h2; + HOST_l2c(ll, md); + ll = c->h3; + HOST_l2c(ll, md); + ll = c->h4; + HOST_l2c(ll, md); + + return 1; +} +LCRYPTO_ALIAS(SHA1_Final); + +unsigned char * +SHA1(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + + if (!SHA1_Init(&c)) + return NULL; + SHA1_Update(&c, d, n); + SHA1_Final(md, &c); + + explicit_bzero(&c, sizeof(c)); + + return (md); +} +LCRYPTO_ALIAS(SHA1); + +#endif diff --git a/Libraries/libressl/crypto/sha/sha256-elf-armv4.S b/Libraries/libressl/crypto/sha/sha256-elf-armv4.S new file mode 100644 index 000000000..9b155c7db --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256-elf-armv4.S @@ -0,0 +1,1520 @@ +#include "arm_arch.h" + +.text +.code 32 + +.type K256,%object +.align 5 +K256: +.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.size K256,.-K256 + +.global sha256_block_data_order +.type sha256_block_data_order,%function +sha256_block_data_order: + sub r3,pc,#8 @ sha256_block_data_order + add r2,r1,r2,lsl#6 @ len to point at the end of inp + stmdb sp!,{r0,r1,r2,r4-r11,lr} + ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} + sub r14,r3,#256 @ K256 + sub sp,sp,#16*4 @ alloca(X[16]) +.Loop: +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 0 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r8,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r8,ror#11 + eor r2,r9,r10 +#if 0>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 0==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r8,ror#25 @ Sigma1(e) + and r2,r2,r8 + str r3,[sp,#0*4] + add r3,r3,r0 + eor r2,r2,r10 @ Ch(e,f,g) + add r3,r3,r11 + mov r11,r4,ror#2 + add r3,r3,r2 + eor r11,r11,r4,ror#13 + add r3,r3,r12 + eor r11,r11,r4,ror#22 @ Sigma0(a) +#if 0>=15 + ldr r1,[sp,#2*4] @ from BODY_16_xx +#endif + orr r0,r4,r5 + and r2,r4,r5 + and r0,r0,r6 + add r11,r11,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r7,r7,r3 + add r11,r11,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 1 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r7,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r7,ror#11 + eor r2,r8,r9 +#if 1>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 1==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r7,ror#25 @ Sigma1(e) + and r2,r2,r7 + str r3,[sp,#1*4] + add r3,r3,r0 + eor r2,r2,r9 @ Ch(e,f,g) + add r3,r3,r10 + mov r10,r11,ror#2 + add r3,r3,r2 + eor r10,r10,r11,ror#13 + add r3,r3,r12 + eor r10,r10,r11,ror#22 @ Sigma0(a) +#if 1>=15 + ldr r1,[sp,#3*4] @ from BODY_16_xx +#endif + orr r0,r11,r4 + and r2,r11,r4 + and r0,r0,r5 + add r10,r10,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r6,r6,r3 + add r10,r10,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 2 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r6,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r6,ror#11 + eor r2,r7,r8 +#if 2>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 2==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r6,ror#25 @ Sigma1(e) + and r2,r2,r6 + str r3,[sp,#2*4] + add r3,r3,r0 + eor r2,r2,r8 @ Ch(e,f,g) + add r3,r3,r9 + mov r9,r10,ror#2 + add r3,r3,r2 + eor r9,r9,r10,ror#13 + add r3,r3,r12 + eor r9,r9,r10,ror#22 @ Sigma0(a) +#if 2>=15 + ldr r1,[sp,#4*4] @ from BODY_16_xx +#endif + orr r0,r10,r11 + and r2,r10,r11 + and r0,r0,r4 + add r9,r9,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r5,r5,r3 + add r9,r9,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 3 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r5,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r5,ror#11 + eor r2,r6,r7 +#if 3>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 3==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r5,ror#25 @ Sigma1(e) + and r2,r2,r5 + str r3,[sp,#3*4] + add r3,r3,r0 + eor r2,r2,r7 @ Ch(e,f,g) + add r3,r3,r8 + mov r8,r9,ror#2 + add r3,r3,r2 + eor r8,r8,r9,ror#13 + add r3,r3,r12 + eor r8,r8,r9,ror#22 @ Sigma0(a) +#if 3>=15 + ldr r1,[sp,#5*4] @ from BODY_16_xx +#endif + orr r0,r9,r10 + and r2,r9,r10 + and r0,r0,r11 + add r8,r8,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r4,r4,r3 + add r8,r8,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 4 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r4,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r4,ror#11 + eor r2,r5,r6 +#if 4>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 4==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r4,ror#25 @ Sigma1(e) + and r2,r2,r4 + str r3,[sp,#4*4] + add r3,r3,r0 + eor r2,r2,r6 @ Ch(e,f,g) + add r3,r3,r7 + mov r7,r8,ror#2 + add r3,r3,r2 + eor r7,r7,r8,ror#13 + add r3,r3,r12 + eor r7,r7,r8,ror#22 @ Sigma0(a) +#if 4>=15 + ldr r1,[sp,#6*4] @ from BODY_16_xx +#endif + orr r0,r8,r9 + and r2,r8,r9 + and r0,r0,r10 + add r7,r7,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r11,r11,r3 + add r7,r7,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 5 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r11,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r11,ror#11 + eor r2,r4,r5 +#if 5>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 5==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r11,ror#25 @ Sigma1(e) + and r2,r2,r11 + str r3,[sp,#5*4] + add r3,r3,r0 + eor r2,r2,r5 @ Ch(e,f,g) + add r3,r3,r6 + mov r6,r7,ror#2 + add r3,r3,r2 + eor r6,r6,r7,ror#13 + add r3,r3,r12 + eor r6,r6,r7,ror#22 @ Sigma0(a) +#if 5>=15 + ldr r1,[sp,#7*4] @ from BODY_16_xx +#endif + orr r0,r7,r8 + and r2,r7,r8 + and r0,r0,r9 + add r6,r6,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r10,r10,r3 + add r6,r6,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 6 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r10,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r10,ror#11 + eor r2,r11,r4 +#if 6>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 6==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r10,ror#25 @ Sigma1(e) + and r2,r2,r10 + str r3,[sp,#6*4] + add r3,r3,r0 + eor r2,r2,r4 @ Ch(e,f,g) + add r3,r3,r5 + mov r5,r6,ror#2 + add r3,r3,r2 + eor r5,r5,r6,ror#13 + add r3,r3,r12 + eor r5,r5,r6,ror#22 @ Sigma0(a) +#if 6>=15 + ldr r1,[sp,#8*4] @ from BODY_16_xx +#endif + orr r0,r6,r7 + and r2,r6,r7 + and r0,r0,r8 + add r5,r5,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r9,r9,r3 + add r5,r5,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 7 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r9,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r9,ror#11 + eor r2,r10,r11 +#if 7>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 7==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r9,ror#25 @ Sigma1(e) + and r2,r2,r9 + str r3,[sp,#7*4] + add r3,r3,r0 + eor r2,r2,r11 @ Ch(e,f,g) + add r3,r3,r4 + mov r4,r5,ror#2 + add r3,r3,r2 + eor r4,r4,r5,ror#13 + add r3,r3,r12 + eor r4,r4,r5,ror#22 @ Sigma0(a) +#if 7>=15 + ldr r1,[sp,#9*4] @ from BODY_16_xx +#endif + orr r0,r5,r6 + and r2,r5,r6 + and r0,r0,r7 + add r4,r4,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r8,r8,r3 + add r4,r4,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 8 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r8,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r8,ror#11 + eor r2,r9,r10 +#if 8>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 8==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r8,ror#25 @ Sigma1(e) + and r2,r2,r8 + str r3,[sp,#8*4] + add r3,r3,r0 + eor r2,r2,r10 @ Ch(e,f,g) + add r3,r3,r11 + mov r11,r4,ror#2 + add r3,r3,r2 + eor r11,r11,r4,ror#13 + add r3,r3,r12 + eor r11,r11,r4,ror#22 @ Sigma0(a) +#if 8>=15 + ldr r1,[sp,#10*4] @ from BODY_16_xx +#endif + orr r0,r4,r5 + and r2,r4,r5 + and r0,r0,r6 + add r11,r11,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r7,r7,r3 + add r11,r11,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 9 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r7,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r7,ror#11 + eor r2,r8,r9 +#if 9>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 9==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r7,ror#25 @ Sigma1(e) + and r2,r2,r7 + str r3,[sp,#9*4] + add r3,r3,r0 + eor r2,r2,r9 @ Ch(e,f,g) + add r3,r3,r10 + mov r10,r11,ror#2 + add r3,r3,r2 + eor r10,r10,r11,ror#13 + add r3,r3,r12 + eor r10,r10,r11,ror#22 @ Sigma0(a) +#if 9>=15 + ldr r1,[sp,#11*4] @ from BODY_16_xx +#endif + orr r0,r11,r4 + and r2,r11,r4 + and r0,r0,r5 + add r10,r10,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r6,r6,r3 + add r10,r10,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 10 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r6,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r6,ror#11 + eor r2,r7,r8 +#if 10>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 10==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r6,ror#25 @ Sigma1(e) + and r2,r2,r6 + str r3,[sp,#10*4] + add r3,r3,r0 + eor r2,r2,r8 @ Ch(e,f,g) + add r3,r3,r9 + mov r9,r10,ror#2 + add r3,r3,r2 + eor r9,r9,r10,ror#13 + add r3,r3,r12 + eor r9,r9,r10,ror#22 @ Sigma0(a) +#if 10>=15 + ldr r1,[sp,#12*4] @ from BODY_16_xx +#endif + orr r0,r10,r11 + and r2,r10,r11 + and r0,r0,r4 + add r9,r9,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r5,r5,r3 + add r9,r9,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 11 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r5,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r5,ror#11 + eor r2,r6,r7 +#if 11>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 11==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r5,ror#25 @ Sigma1(e) + and r2,r2,r5 + str r3,[sp,#11*4] + add r3,r3,r0 + eor r2,r2,r7 @ Ch(e,f,g) + add r3,r3,r8 + mov r8,r9,ror#2 + add r3,r3,r2 + eor r8,r8,r9,ror#13 + add r3,r3,r12 + eor r8,r8,r9,ror#22 @ Sigma0(a) +#if 11>=15 + ldr r1,[sp,#13*4] @ from BODY_16_xx +#endif + orr r0,r9,r10 + and r2,r9,r10 + and r0,r0,r11 + add r8,r8,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r4,r4,r3 + add r8,r8,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 12 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r4,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r4,ror#11 + eor r2,r5,r6 +#if 12>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 12==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r4,ror#25 @ Sigma1(e) + and r2,r2,r4 + str r3,[sp,#12*4] + add r3,r3,r0 + eor r2,r2,r6 @ Ch(e,f,g) + add r3,r3,r7 + mov r7,r8,ror#2 + add r3,r3,r2 + eor r7,r7,r8,ror#13 + add r3,r3,r12 + eor r7,r7,r8,ror#22 @ Sigma0(a) +#if 12>=15 + ldr r1,[sp,#14*4] @ from BODY_16_xx +#endif + orr r0,r8,r9 + and r2,r8,r9 + and r0,r0,r10 + add r7,r7,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r11,r11,r3 + add r7,r7,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 13 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r11,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r11,ror#11 + eor r2,r4,r5 +#if 13>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 13==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r11,ror#25 @ Sigma1(e) + and r2,r2,r11 + str r3,[sp,#13*4] + add r3,r3,r0 + eor r2,r2,r5 @ Ch(e,f,g) + add r3,r3,r6 + mov r6,r7,ror#2 + add r3,r3,r2 + eor r6,r6,r7,ror#13 + add r3,r3,r12 + eor r6,r6,r7,ror#22 @ Sigma0(a) +#if 13>=15 + ldr r1,[sp,#15*4] @ from BODY_16_xx +#endif + orr r0,r7,r8 + and r2,r7,r8 + and r0,r0,r9 + add r6,r6,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r10,r10,r3 + add r6,r6,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 14 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r10,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r10,ror#11 + eor r2,r11,r4 +#if 14>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 14==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r10,ror#25 @ Sigma1(e) + and r2,r2,r10 + str r3,[sp,#14*4] + add r3,r3,r0 + eor r2,r2,r4 @ Ch(e,f,g) + add r3,r3,r5 + mov r5,r6,ror#2 + add r3,r3,r2 + eor r5,r5,r6,ror#13 + add r3,r3,r12 + eor r5,r5,r6,ror#22 @ Sigma0(a) +#if 14>=15 + ldr r1,[sp,#0*4] @ from BODY_16_xx +#endif + orr r0,r6,r7 + and r2,r6,r7 + and r0,r0,r8 + add r5,r5,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r9,r9,r3 + add r5,r5,r0 +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r3,[r1],#4 +#else + ldrb r3,[r1,#3] @ 15 + ldrb r12,[r1,#2] + ldrb r2,[r1,#1] + ldrb r0,[r1],#4 + orr r3,r3,r12,lsl#8 + orr r3,r3,r2,lsl#16 + orr r3,r3,r0,lsl#24 +#endif + mov r0,r9,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r9,ror#11 + eor r2,r10,r11 +#if 15>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 15==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r9,ror#25 @ Sigma1(e) + and r2,r2,r9 + str r3,[sp,#15*4] + add r3,r3,r0 + eor r2,r2,r11 @ Ch(e,f,g) + add r3,r3,r4 + mov r4,r5,ror#2 + add r3,r3,r2 + eor r4,r4,r5,ror#13 + add r3,r3,r12 + eor r4,r4,r5,ror#22 @ Sigma0(a) +#if 15>=15 + ldr r1,[sp,#1*4] @ from BODY_16_xx +#endif + orr r0,r5,r6 + and r2,r5,r6 + and r0,r0,r7 + add r4,r4,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r8,r8,r3 + add r4,r4,r0 +.Lrounds_16_xx: + @ ldr r1,[sp,#1*4] @ 16 + ldr r12,[sp,#14*4] + mov r0,r1,ror#7 + ldr r3,[sp,#0*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#9*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r8,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r8,ror#11 + eor r2,r9,r10 +#if 16>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 16==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r8,ror#25 @ Sigma1(e) + and r2,r2,r8 + str r3,[sp,#0*4] + add r3,r3,r0 + eor r2,r2,r10 @ Ch(e,f,g) + add r3,r3,r11 + mov r11,r4,ror#2 + add r3,r3,r2 + eor r11,r11,r4,ror#13 + add r3,r3,r12 + eor r11,r11,r4,ror#22 @ Sigma0(a) +#if 16>=15 + ldr r1,[sp,#2*4] @ from BODY_16_xx +#endif + orr r0,r4,r5 + and r2,r4,r5 + and r0,r0,r6 + add r11,r11,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r7,r7,r3 + add r11,r11,r0 + @ ldr r1,[sp,#2*4] @ 17 + ldr r12,[sp,#15*4] + mov r0,r1,ror#7 + ldr r3,[sp,#1*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#10*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r7,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r7,ror#11 + eor r2,r8,r9 +#if 17>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 17==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r7,ror#25 @ Sigma1(e) + and r2,r2,r7 + str r3,[sp,#1*4] + add r3,r3,r0 + eor r2,r2,r9 @ Ch(e,f,g) + add r3,r3,r10 + mov r10,r11,ror#2 + add r3,r3,r2 + eor r10,r10,r11,ror#13 + add r3,r3,r12 + eor r10,r10,r11,ror#22 @ Sigma0(a) +#if 17>=15 + ldr r1,[sp,#3*4] @ from BODY_16_xx +#endif + orr r0,r11,r4 + and r2,r11,r4 + and r0,r0,r5 + add r10,r10,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r6,r6,r3 + add r10,r10,r0 + @ ldr r1,[sp,#3*4] @ 18 + ldr r12,[sp,#0*4] + mov r0,r1,ror#7 + ldr r3,[sp,#2*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#11*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r6,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r6,ror#11 + eor r2,r7,r8 +#if 18>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 18==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r6,ror#25 @ Sigma1(e) + and r2,r2,r6 + str r3,[sp,#2*4] + add r3,r3,r0 + eor r2,r2,r8 @ Ch(e,f,g) + add r3,r3,r9 + mov r9,r10,ror#2 + add r3,r3,r2 + eor r9,r9,r10,ror#13 + add r3,r3,r12 + eor r9,r9,r10,ror#22 @ Sigma0(a) +#if 18>=15 + ldr r1,[sp,#4*4] @ from BODY_16_xx +#endif + orr r0,r10,r11 + and r2,r10,r11 + and r0,r0,r4 + add r9,r9,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r5,r5,r3 + add r9,r9,r0 + @ ldr r1,[sp,#4*4] @ 19 + ldr r12,[sp,#1*4] + mov r0,r1,ror#7 + ldr r3,[sp,#3*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#12*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r5,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r5,ror#11 + eor r2,r6,r7 +#if 19>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 19==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r5,ror#25 @ Sigma1(e) + and r2,r2,r5 + str r3,[sp,#3*4] + add r3,r3,r0 + eor r2,r2,r7 @ Ch(e,f,g) + add r3,r3,r8 + mov r8,r9,ror#2 + add r3,r3,r2 + eor r8,r8,r9,ror#13 + add r3,r3,r12 + eor r8,r8,r9,ror#22 @ Sigma0(a) +#if 19>=15 + ldr r1,[sp,#5*4] @ from BODY_16_xx +#endif + orr r0,r9,r10 + and r2,r9,r10 + and r0,r0,r11 + add r8,r8,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r4,r4,r3 + add r8,r8,r0 + @ ldr r1,[sp,#5*4] @ 20 + ldr r12,[sp,#2*4] + mov r0,r1,ror#7 + ldr r3,[sp,#4*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#13*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r4,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r4,ror#11 + eor r2,r5,r6 +#if 20>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 20==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r4,ror#25 @ Sigma1(e) + and r2,r2,r4 + str r3,[sp,#4*4] + add r3,r3,r0 + eor r2,r2,r6 @ Ch(e,f,g) + add r3,r3,r7 + mov r7,r8,ror#2 + add r3,r3,r2 + eor r7,r7,r8,ror#13 + add r3,r3,r12 + eor r7,r7,r8,ror#22 @ Sigma0(a) +#if 20>=15 + ldr r1,[sp,#6*4] @ from BODY_16_xx +#endif + orr r0,r8,r9 + and r2,r8,r9 + and r0,r0,r10 + add r7,r7,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r11,r11,r3 + add r7,r7,r0 + @ ldr r1,[sp,#6*4] @ 21 + ldr r12,[sp,#3*4] + mov r0,r1,ror#7 + ldr r3,[sp,#5*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#14*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r11,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r11,ror#11 + eor r2,r4,r5 +#if 21>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 21==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r11,ror#25 @ Sigma1(e) + and r2,r2,r11 + str r3,[sp,#5*4] + add r3,r3,r0 + eor r2,r2,r5 @ Ch(e,f,g) + add r3,r3,r6 + mov r6,r7,ror#2 + add r3,r3,r2 + eor r6,r6,r7,ror#13 + add r3,r3,r12 + eor r6,r6,r7,ror#22 @ Sigma0(a) +#if 21>=15 + ldr r1,[sp,#7*4] @ from BODY_16_xx +#endif + orr r0,r7,r8 + and r2,r7,r8 + and r0,r0,r9 + add r6,r6,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r10,r10,r3 + add r6,r6,r0 + @ ldr r1,[sp,#7*4] @ 22 + ldr r12,[sp,#4*4] + mov r0,r1,ror#7 + ldr r3,[sp,#6*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#15*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r10,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r10,ror#11 + eor r2,r11,r4 +#if 22>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 22==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r10,ror#25 @ Sigma1(e) + and r2,r2,r10 + str r3,[sp,#6*4] + add r3,r3,r0 + eor r2,r2,r4 @ Ch(e,f,g) + add r3,r3,r5 + mov r5,r6,ror#2 + add r3,r3,r2 + eor r5,r5,r6,ror#13 + add r3,r3,r12 + eor r5,r5,r6,ror#22 @ Sigma0(a) +#if 22>=15 + ldr r1,[sp,#8*4] @ from BODY_16_xx +#endif + orr r0,r6,r7 + and r2,r6,r7 + and r0,r0,r8 + add r5,r5,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r9,r9,r3 + add r5,r5,r0 + @ ldr r1,[sp,#8*4] @ 23 + ldr r12,[sp,#5*4] + mov r0,r1,ror#7 + ldr r3,[sp,#7*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#0*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r9,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r9,ror#11 + eor r2,r10,r11 +#if 23>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 23==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r9,ror#25 @ Sigma1(e) + and r2,r2,r9 + str r3,[sp,#7*4] + add r3,r3,r0 + eor r2,r2,r11 @ Ch(e,f,g) + add r3,r3,r4 + mov r4,r5,ror#2 + add r3,r3,r2 + eor r4,r4,r5,ror#13 + add r3,r3,r12 + eor r4,r4,r5,ror#22 @ Sigma0(a) +#if 23>=15 + ldr r1,[sp,#9*4] @ from BODY_16_xx +#endif + orr r0,r5,r6 + and r2,r5,r6 + and r0,r0,r7 + add r4,r4,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r8,r8,r3 + add r4,r4,r0 + @ ldr r1,[sp,#9*4] @ 24 + ldr r12,[sp,#6*4] + mov r0,r1,ror#7 + ldr r3,[sp,#8*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#1*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r8,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r8,ror#11 + eor r2,r9,r10 +#if 24>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 24==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r8,ror#25 @ Sigma1(e) + and r2,r2,r8 + str r3,[sp,#8*4] + add r3,r3,r0 + eor r2,r2,r10 @ Ch(e,f,g) + add r3,r3,r11 + mov r11,r4,ror#2 + add r3,r3,r2 + eor r11,r11,r4,ror#13 + add r3,r3,r12 + eor r11,r11,r4,ror#22 @ Sigma0(a) +#if 24>=15 + ldr r1,[sp,#10*4] @ from BODY_16_xx +#endif + orr r0,r4,r5 + and r2,r4,r5 + and r0,r0,r6 + add r11,r11,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r7,r7,r3 + add r11,r11,r0 + @ ldr r1,[sp,#10*4] @ 25 + ldr r12,[sp,#7*4] + mov r0,r1,ror#7 + ldr r3,[sp,#9*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#2*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r7,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r7,ror#11 + eor r2,r8,r9 +#if 25>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 25==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r7,ror#25 @ Sigma1(e) + and r2,r2,r7 + str r3,[sp,#9*4] + add r3,r3,r0 + eor r2,r2,r9 @ Ch(e,f,g) + add r3,r3,r10 + mov r10,r11,ror#2 + add r3,r3,r2 + eor r10,r10,r11,ror#13 + add r3,r3,r12 + eor r10,r10,r11,ror#22 @ Sigma0(a) +#if 25>=15 + ldr r1,[sp,#11*4] @ from BODY_16_xx +#endif + orr r0,r11,r4 + and r2,r11,r4 + and r0,r0,r5 + add r10,r10,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r6,r6,r3 + add r10,r10,r0 + @ ldr r1,[sp,#11*4] @ 26 + ldr r12,[sp,#8*4] + mov r0,r1,ror#7 + ldr r3,[sp,#10*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#3*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r6,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r6,ror#11 + eor r2,r7,r8 +#if 26>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 26==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r6,ror#25 @ Sigma1(e) + and r2,r2,r6 + str r3,[sp,#10*4] + add r3,r3,r0 + eor r2,r2,r8 @ Ch(e,f,g) + add r3,r3,r9 + mov r9,r10,ror#2 + add r3,r3,r2 + eor r9,r9,r10,ror#13 + add r3,r3,r12 + eor r9,r9,r10,ror#22 @ Sigma0(a) +#if 26>=15 + ldr r1,[sp,#12*4] @ from BODY_16_xx +#endif + orr r0,r10,r11 + and r2,r10,r11 + and r0,r0,r4 + add r9,r9,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r5,r5,r3 + add r9,r9,r0 + @ ldr r1,[sp,#12*4] @ 27 + ldr r12,[sp,#9*4] + mov r0,r1,ror#7 + ldr r3,[sp,#11*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#4*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r5,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r5,ror#11 + eor r2,r6,r7 +#if 27>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 27==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r5,ror#25 @ Sigma1(e) + and r2,r2,r5 + str r3,[sp,#11*4] + add r3,r3,r0 + eor r2,r2,r7 @ Ch(e,f,g) + add r3,r3,r8 + mov r8,r9,ror#2 + add r3,r3,r2 + eor r8,r8,r9,ror#13 + add r3,r3,r12 + eor r8,r8,r9,ror#22 @ Sigma0(a) +#if 27>=15 + ldr r1,[sp,#13*4] @ from BODY_16_xx +#endif + orr r0,r9,r10 + and r2,r9,r10 + and r0,r0,r11 + add r8,r8,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r4,r4,r3 + add r8,r8,r0 + @ ldr r1,[sp,#13*4] @ 28 + ldr r12,[sp,#10*4] + mov r0,r1,ror#7 + ldr r3,[sp,#12*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#5*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r4,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r4,ror#11 + eor r2,r5,r6 +#if 28>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 28==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r4,ror#25 @ Sigma1(e) + and r2,r2,r4 + str r3,[sp,#12*4] + add r3,r3,r0 + eor r2,r2,r6 @ Ch(e,f,g) + add r3,r3,r7 + mov r7,r8,ror#2 + add r3,r3,r2 + eor r7,r7,r8,ror#13 + add r3,r3,r12 + eor r7,r7,r8,ror#22 @ Sigma0(a) +#if 28>=15 + ldr r1,[sp,#14*4] @ from BODY_16_xx +#endif + orr r0,r8,r9 + and r2,r8,r9 + and r0,r0,r10 + add r7,r7,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r11,r11,r3 + add r7,r7,r0 + @ ldr r1,[sp,#14*4] @ 29 + ldr r12,[sp,#11*4] + mov r0,r1,ror#7 + ldr r3,[sp,#13*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#6*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r11,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r11,ror#11 + eor r2,r4,r5 +#if 29>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 29==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r11,ror#25 @ Sigma1(e) + and r2,r2,r11 + str r3,[sp,#13*4] + add r3,r3,r0 + eor r2,r2,r5 @ Ch(e,f,g) + add r3,r3,r6 + mov r6,r7,ror#2 + add r3,r3,r2 + eor r6,r6,r7,ror#13 + add r3,r3,r12 + eor r6,r6,r7,ror#22 @ Sigma0(a) +#if 29>=15 + ldr r1,[sp,#15*4] @ from BODY_16_xx +#endif + orr r0,r7,r8 + and r2,r7,r8 + and r0,r0,r9 + add r6,r6,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r10,r10,r3 + add r6,r6,r0 + @ ldr r1,[sp,#15*4] @ 30 + ldr r12,[sp,#12*4] + mov r0,r1,ror#7 + ldr r3,[sp,#14*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#7*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r10,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r10,ror#11 + eor r2,r11,r4 +#if 30>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 30==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r10,ror#25 @ Sigma1(e) + and r2,r2,r10 + str r3,[sp,#14*4] + add r3,r3,r0 + eor r2,r2,r4 @ Ch(e,f,g) + add r3,r3,r5 + mov r5,r6,ror#2 + add r3,r3,r2 + eor r5,r5,r6,ror#13 + add r3,r3,r12 + eor r5,r5,r6,ror#22 @ Sigma0(a) +#if 30>=15 + ldr r1,[sp,#0*4] @ from BODY_16_xx +#endif + orr r0,r6,r7 + and r2,r6,r7 + and r0,r0,r8 + add r5,r5,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r9,r9,r3 + add r5,r5,r0 + @ ldr r1,[sp,#0*4] @ 31 + ldr r12,[sp,#13*4] + mov r0,r1,ror#7 + ldr r3,[sp,#15*4] + eor r0,r0,r1,ror#18 + ldr r2,[sp,#8*4] + eor r0,r0,r1,lsr#3 @ sigma0(X[i+1]) + mov r1,r12,ror#17 + add r3,r3,r0 + eor r1,r1,r12,ror#19 + add r3,r3,r2 + eor r1,r1,r12,lsr#10 @ sigma1(X[i+14]) + @ add r3,r3,r1 + mov r0,r9,ror#6 + ldr r12,[r14],#4 @ *K256++ + eor r0,r0,r9,ror#11 + eor r2,r10,r11 +#if 31>=16 + add r3,r3,r1 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) && !defined(__STRICT_ALIGNMENT) + rev r3,r3 +#endif +#if 31==15 + str r1,[sp,#17*4] @ leave room for r1 +#endif + eor r0,r0,r9,ror#25 @ Sigma1(e) + and r2,r2,r9 + str r3,[sp,#15*4] + add r3,r3,r0 + eor r2,r2,r11 @ Ch(e,f,g) + add r3,r3,r4 + mov r4,r5,ror#2 + add r3,r3,r2 + eor r4,r4,r5,ror#13 + add r3,r3,r12 + eor r4,r4,r5,ror#22 @ Sigma0(a) +#if 31>=15 + ldr r1,[sp,#1*4] @ from BODY_16_xx +#endif + orr r0,r5,r6 + and r2,r5,r6 + and r0,r0,r7 + add r4,r4,r3 + orr r0,r0,r2 @ Maj(a,b,c) + add r8,r8,r3 + add r4,r4,r0 + and r12,r12,#0xff + cmp r12,#0xf2 + bne .Lrounds_16_xx + + ldr r3,[sp,#16*4] @ pull ctx + ldr r0,[r3,#0] + ldr r2,[r3,#4] + ldr r12,[r3,#8] + add r4,r4,r0 + ldr r0,[r3,#12] + add r5,r5,r2 + ldr r2,[r3,#16] + add r6,r6,r12 + ldr r12,[r3,#20] + add r7,r7,r0 + ldr r0,[r3,#24] + add r8,r8,r2 + ldr r2,[r3,#28] + add r9,r9,r12 + ldr r1,[sp,#17*4] @ pull inp + ldr r12,[sp,#18*4] @ pull inp+len + add r10,r10,r0 + add r11,r11,r2 + stmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} + cmp r1,r12 + sub r14,r14,#256 @ rewind Ktbl + bne .Loop + + add sp,sp,#19*4 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + .word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size sha256_block_data_order,.-sha256_block_data_order +.asciz "SHA256 block transform for ARMv4, CRYPTOGAMS by " +.align 2 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha256-elf-x86_64.S b/Libraries/libressl/crypto/sha/sha256-elf-x86_64.S new file mode 100644 index 000000000..b976181a0 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256-elf-x86_64.S @@ -0,0 +1,1785 @@ +#include "x86_arch.h" +.text + +.globl sha256_block_data_order +.type sha256_block_data_order,@function +.align 16 +sha256_block_data_order: + endbr64 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $64+32,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %r11,64+24(%rsp) +.Lprologue: + + leaq K256(%rip),%rbp + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + jmp .Lloop + +.align 16 +.Lloop: + xorq %rdi,%rdi + movl 0(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,0(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 4(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,4(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 8(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,8(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 12(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,12(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 16(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,16(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 20(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,20(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 24(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,24(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 28(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,28(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + movl 32(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,32(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 36(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,36(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 40(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,40(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 44(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,44(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 48(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,48(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 52(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,52(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 56(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,56(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 60(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,60(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: + movl 4(%rsp),%r13d + movl 56(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 36(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 0(%rsp),%r12d + movl %r8d,%r13d + addl %r14d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,0(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 8(%rsp),%r13d + movl 60(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 40(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 4(%rsp),%r12d + movl %edx,%r13d + addl %r14d,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,4(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 12(%rsp),%r13d + movl 0(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 44(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 8(%rsp),%r12d + movl %ecx,%r13d + addl %r14d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,8(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 16(%rsp),%r13d + movl 4(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 48(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 12(%rsp),%r12d + movl %ebx,%r13d + addl %r14d,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,12(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 20(%rsp),%r13d + movl 8(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 52(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 16(%rsp),%r12d + movl %eax,%r13d + addl %r14d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,16(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 24(%rsp),%r13d + movl 12(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 56(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 20(%rsp),%r12d + movl %r11d,%r13d + addl %r14d,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,20(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 28(%rsp),%r13d + movl 16(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 60(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 24(%rsp),%r12d + movl %r10d,%r13d + addl %r14d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,24(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 32(%rsp),%r13d + movl 20(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 0(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 28(%rsp),%r12d + movl %r9d,%r13d + addl %r14d,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,28(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + movl 36(%rsp),%r13d + movl 24(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 4(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 32(%rsp),%r12d + movl %r8d,%r13d + addl %r14d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,32(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 40(%rsp),%r13d + movl 28(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 8(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 36(%rsp),%r12d + movl %edx,%r13d + addl %r14d,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,36(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 44(%rsp),%r13d + movl 32(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 12(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 40(%rsp),%r12d + movl %ecx,%r13d + addl %r14d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,40(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 48(%rsp),%r13d + movl 36(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 16(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 44(%rsp),%r12d + movl %ebx,%r13d + addl %r14d,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,44(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 52(%rsp),%r13d + movl 40(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 20(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 48(%rsp),%r12d + movl %eax,%r13d + addl %r14d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,48(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 56(%rsp),%r13d + movl 44(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 24(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 52(%rsp),%r12d + movl %r11d,%r13d + addl %r14d,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,52(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 60(%rsp),%r13d + movl 48(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 28(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 56(%rsp),%r12d + movl %r10d,%r13d + addl %r14d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,56(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 0(%rsp),%r13d + movl 52(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 32(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 60(%rsp),%r12d + movl %r9d,%r13d + addl %r14d,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,60(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + cmpq $64,%rdi + jb .Lrounds_16_xx + + movq 64+0(%rsp),%rdi + leaq 64(%rsi),%rsi + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop + + movq 64+24(%rsp),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue: + retq +.size sha256_block_data_order,.-sha256_block_data_order +.section .rodata +.align 64 +.type K256,@object +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.text +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha256-macosx-x86_64.S b/Libraries/libressl/crypto/sha/sha256-macosx-x86_64.S new file mode 100644 index 000000000..4b468b7fc --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256-macosx-x86_64.S @@ -0,0 +1,1779 @@ +#include "x86_arch.h" +.text + +.globl _sha256_block_data_order + +.p2align 4 +_sha256_block_data_order: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $64+32,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %r11,64+24(%rsp) +L$prologue: + + leaq K256(%rip),%rbp + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + jmp L$loop + +.p2align 4 +L$loop: + xorq %rdi,%rdi + movl 0(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,0(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 4(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,4(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 8(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,8(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 12(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,12(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 16(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,16(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 20(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,20(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 24(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,24(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 28(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,28(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + movl 32(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,32(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 36(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,36(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 40(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,40(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 44(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,44(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 48(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,48(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 52(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,52(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 56(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,56(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 60(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,60(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + jmp L$rounds_16_xx +.p2align 4 +L$rounds_16_xx: + movl 4(%rsp),%r13d + movl 56(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 36(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 0(%rsp),%r12d + movl %r8d,%r13d + addl %r14d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,0(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 8(%rsp),%r13d + movl 60(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 40(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 4(%rsp),%r12d + movl %edx,%r13d + addl %r14d,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,4(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 12(%rsp),%r13d + movl 0(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 44(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 8(%rsp),%r12d + movl %ecx,%r13d + addl %r14d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,8(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 16(%rsp),%r13d + movl 4(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 48(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 12(%rsp),%r12d + movl %ebx,%r13d + addl %r14d,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,12(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 20(%rsp),%r13d + movl 8(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 52(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 16(%rsp),%r12d + movl %eax,%r13d + addl %r14d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,16(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 24(%rsp),%r13d + movl 12(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 56(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 20(%rsp),%r12d + movl %r11d,%r13d + addl %r14d,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,20(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 28(%rsp),%r13d + movl 16(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 60(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 24(%rsp),%r12d + movl %r10d,%r13d + addl %r14d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,24(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 32(%rsp),%r13d + movl 20(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 0(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 28(%rsp),%r12d + movl %r9d,%r13d + addl %r14d,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,28(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + movl 36(%rsp),%r13d + movl 24(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 4(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 32(%rsp),%r12d + movl %r8d,%r13d + addl %r14d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,32(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 40(%rsp),%r13d + movl 28(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 8(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 36(%rsp),%r12d + movl %edx,%r13d + addl %r14d,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,36(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 44(%rsp),%r13d + movl 32(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 12(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 40(%rsp),%r12d + movl %ecx,%r13d + addl %r14d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,40(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 48(%rsp),%r13d + movl 36(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 16(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 44(%rsp),%r12d + movl %ebx,%r13d + addl %r14d,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,44(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 52(%rsp),%r13d + movl 40(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 20(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 48(%rsp),%r12d + movl %eax,%r13d + addl %r14d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,48(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 56(%rsp),%r13d + movl 44(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 24(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 52(%rsp),%r12d + movl %r11d,%r13d + addl %r14d,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,52(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 60(%rsp),%r13d + movl 48(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 28(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 56(%rsp),%r12d + movl %r10d,%r13d + addl %r14d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,56(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 0(%rsp),%r13d + movl 52(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 32(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 60(%rsp),%r12d + movl %r9d,%r13d + addl %r14d,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,60(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + cmpq $64,%rdi + jb L$rounds_16_xx + + movq 64+0(%rsp),%rdi + leaq 64(%rsi),%rsi + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb L$loop + + movq 64+24(%rsp),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$epilogue: + retq + +.p2align 6 + +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 diff --git a/Libraries/libressl/crypto/sha/sha256-masm-x86_64.S b/Libraries/libressl/crypto/sha/sha256-masm-x86_64.S new file mode 100644 index 000000000..7c182f90b --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256-masm-x86_64.S @@ -0,0 +1,1864 @@ +; 1 "crypto/sha/sha256-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/sha/sha256-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/sha/sha256-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC sha256_block_data_order + +ALIGN 16 +sha256_block_data_order PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha256_block_data_order:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov r11,rsp + shl rdx,4 + sub rsp,16*4+4*8 + lea rdx,QWORD PTR[rdx*4+rsi] + and rsp,-64 + mov QWORD PTR[((64+0))+rsp],rdi + mov QWORD PTR[((64+8))+rsp],rsi + mov QWORD PTR[((64+16))+rsp],rdx + mov QWORD PTR[((64+24))+rsp],r11 +$L$prologue:: + + lea rbp,QWORD PTR[K256] + + mov eax,DWORD PTR[rdi] + mov ebx,DWORD PTR[4+rdi] + mov ecx,DWORD PTR[8+rdi] + mov edx,DWORD PTR[12+rdi] + mov r8d,DWORD PTR[16+rdi] + mov r9d,DWORD PTR[20+rdi] + mov r10d,DWORD PTR[24+rdi] + mov r11d,DWORD PTR[28+rdi] + jmp $L$loop + +ALIGN 16 +$L$loop:: + xor rdi,rdi + mov r12d,DWORD PTR[rsi] + mov r13d,r8d + mov r14d,eax + bswap r12d + ror r13d,14 + mov r15d,r9d + mov DWORD PTR[rsp],r12d + + ror r14d,9 + xor r13d,r8d + xor r15d,r10d + + ror r13d,5 + add r12d,r11d + xor r14d,eax + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r8d + mov r11d,ebx + + ror r14d,11 + xor r13d,r8d + xor r15d,r10d + + xor r11d,ecx + xor r14d,eax + add r12d,r15d + mov r15d,ebx + + ror r13d,6 + and r11d,eax + and r15d,ecx + + ror r14d,2 + add r12d,r13d + add r11d,r15d + + add edx,r12d + add r11d,r12d + lea rdi,QWORD PTR[1+rdi] + add r11d,r14d + + mov r12d,DWORD PTR[4+rsi] + mov r13d,edx + mov r14d,r11d + bswap r12d + ror r13d,14 + mov r15d,r8d + mov DWORD PTR[4+rsp],r12d + + ror r14d,9 + xor r13d,edx + xor r15d,r9d + + ror r13d,5 + add r12d,r10d + xor r14d,r11d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,edx + mov r10d,eax + + ror r14d,11 + xor r13d,edx + xor r15d,r9d + + xor r10d,ebx + xor r14d,r11d + add r12d,r15d + mov r15d,eax + + ror r13d,6 + and r10d,r11d + and r15d,ebx + + ror r14d,2 + add r12d,r13d + add r10d,r15d + + add ecx,r12d + add r10d,r12d + lea rdi,QWORD PTR[1+rdi] + add r10d,r14d + + mov r12d,DWORD PTR[8+rsi] + mov r13d,ecx + mov r14d,r10d + bswap r12d + ror r13d,14 + mov r15d,edx + mov DWORD PTR[8+rsp],r12d + + ror r14d,9 + xor r13d,ecx + xor r15d,r8d + + ror r13d,5 + add r12d,r9d + xor r14d,r10d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ecx + mov r9d,r11d + + ror r14d,11 + xor r13d,ecx + xor r15d,r8d + + xor r9d,eax + xor r14d,r10d + add r12d,r15d + mov r15d,r11d + + ror r13d,6 + and r9d,r10d + and r15d,eax + + ror r14d,2 + add r12d,r13d + add r9d,r15d + + add ebx,r12d + add r9d,r12d + lea rdi,QWORD PTR[1+rdi] + add r9d,r14d + + mov r12d,DWORD PTR[12+rsi] + mov r13d,ebx + mov r14d,r9d + bswap r12d + ror r13d,14 + mov r15d,ecx + mov DWORD PTR[12+rsp],r12d + + ror r14d,9 + xor r13d,ebx + xor r15d,edx + + ror r13d,5 + add r12d,r8d + xor r14d,r9d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ebx + mov r8d,r10d + + ror r14d,11 + xor r13d,ebx + xor r15d,edx + + xor r8d,r11d + xor r14d,r9d + add r12d,r15d + mov r15d,r10d + + ror r13d,6 + and r8d,r9d + and r15d,r11d + + ror r14d,2 + add r12d,r13d + add r8d,r15d + + add eax,r12d + add r8d,r12d + lea rdi,QWORD PTR[1+rdi] + add r8d,r14d + + mov r12d,DWORD PTR[16+rsi] + mov r13d,eax + mov r14d,r8d + bswap r12d + ror r13d,14 + mov r15d,ebx + mov DWORD PTR[16+rsp],r12d + + ror r14d,9 + xor r13d,eax + xor r15d,ecx + + ror r13d,5 + add r12d,edx + xor r14d,r8d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,eax + mov edx,r9d + + ror r14d,11 + xor r13d,eax + xor r15d,ecx + + xor edx,r10d + xor r14d,r8d + add r12d,r15d + mov r15d,r9d + + ror r13d,6 + and edx,r8d + and r15d,r10d + + ror r14d,2 + add r12d,r13d + add edx,r15d + + add r11d,r12d + add edx,r12d + lea rdi,QWORD PTR[1+rdi] + add edx,r14d + + mov r12d,DWORD PTR[20+rsi] + mov r13d,r11d + mov r14d,edx + bswap r12d + ror r13d,14 + mov r15d,eax + mov DWORD PTR[20+rsp],r12d + + ror r14d,9 + xor r13d,r11d + xor r15d,ebx + + ror r13d,5 + add r12d,ecx + xor r14d,edx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r11d + mov ecx,r8d + + ror r14d,11 + xor r13d,r11d + xor r15d,ebx + + xor ecx,r9d + xor r14d,edx + add r12d,r15d + mov r15d,r8d + + ror r13d,6 + and ecx,edx + and r15d,r9d + + ror r14d,2 + add r12d,r13d + add ecx,r15d + + add r10d,r12d + add ecx,r12d + lea rdi,QWORD PTR[1+rdi] + add ecx,r14d + + mov r12d,DWORD PTR[24+rsi] + mov r13d,r10d + mov r14d,ecx + bswap r12d + ror r13d,14 + mov r15d,r11d + mov DWORD PTR[24+rsp],r12d + + ror r14d,9 + xor r13d,r10d + xor r15d,eax + + ror r13d,5 + add r12d,ebx + xor r14d,ecx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r10d + mov ebx,edx + + ror r14d,11 + xor r13d,r10d + xor r15d,eax + + xor ebx,r8d + xor r14d,ecx + add r12d,r15d + mov r15d,edx + + ror r13d,6 + and ebx,ecx + and r15d,r8d + + ror r14d,2 + add r12d,r13d + add ebx,r15d + + add r9d,r12d + add ebx,r12d + lea rdi,QWORD PTR[1+rdi] + add ebx,r14d + + mov r12d,DWORD PTR[28+rsi] + mov r13d,r9d + mov r14d,ebx + bswap r12d + ror r13d,14 + mov r15d,r10d + mov DWORD PTR[28+rsp],r12d + + ror r14d,9 + xor r13d,r9d + xor r15d,r11d + + ror r13d,5 + add r12d,eax + xor r14d,ebx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r9d + mov eax,ecx + + ror r14d,11 + xor r13d,r9d + xor r15d,r11d + + xor eax,edx + xor r14d,ebx + add r12d,r15d + mov r15d,ecx + + ror r13d,6 + and eax,ebx + and r15d,edx + + ror r14d,2 + add r12d,r13d + add eax,r15d + + add r8d,r12d + add eax,r12d + lea rdi,QWORD PTR[1+rdi] + add eax,r14d + + mov r12d,DWORD PTR[32+rsi] + mov r13d,r8d + mov r14d,eax + bswap r12d + ror r13d,14 + mov r15d,r9d + mov DWORD PTR[32+rsp],r12d + + ror r14d,9 + xor r13d,r8d + xor r15d,r10d + + ror r13d,5 + add r12d,r11d + xor r14d,eax + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r8d + mov r11d,ebx + + ror r14d,11 + xor r13d,r8d + xor r15d,r10d + + xor r11d,ecx + xor r14d,eax + add r12d,r15d + mov r15d,ebx + + ror r13d,6 + and r11d,eax + and r15d,ecx + + ror r14d,2 + add r12d,r13d + add r11d,r15d + + add edx,r12d + add r11d,r12d + lea rdi,QWORD PTR[1+rdi] + add r11d,r14d + + mov r12d,DWORD PTR[36+rsi] + mov r13d,edx + mov r14d,r11d + bswap r12d + ror r13d,14 + mov r15d,r8d + mov DWORD PTR[36+rsp],r12d + + ror r14d,9 + xor r13d,edx + xor r15d,r9d + + ror r13d,5 + add r12d,r10d + xor r14d,r11d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,edx + mov r10d,eax + + ror r14d,11 + xor r13d,edx + xor r15d,r9d + + xor r10d,ebx + xor r14d,r11d + add r12d,r15d + mov r15d,eax + + ror r13d,6 + and r10d,r11d + and r15d,ebx + + ror r14d,2 + add r12d,r13d + add r10d,r15d + + add ecx,r12d + add r10d,r12d + lea rdi,QWORD PTR[1+rdi] + add r10d,r14d + + mov r12d,DWORD PTR[40+rsi] + mov r13d,ecx + mov r14d,r10d + bswap r12d + ror r13d,14 + mov r15d,edx + mov DWORD PTR[40+rsp],r12d + + ror r14d,9 + xor r13d,ecx + xor r15d,r8d + + ror r13d,5 + add r12d,r9d + xor r14d,r10d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ecx + mov r9d,r11d + + ror r14d,11 + xor r13d,ecx + xor r15d,r8d + + xor r9d,eax + xor r14d,r10d + add r12d,r15d + mov r15d,r11d + + ror r13d,6 + and r9d,r10d + and r15d,eax + + ror r14d,2 + add r12d,r13d + add r9d,r15d + + add ebx,r12d + add r9d,r12d + lea rdi,QWORD PTR[1+rdi] + add r9d,r14d + + mov r12d,DWORD PTR[44+rsi] + mov r13d,ebx + mov r14d,r9d + bswap r12d + ror r13d,14 + mov r15d,ecx + mov DWORD PTR[44+rsp],r12d + + ror r14d,9 + xor r13d,ebx + xor r15d,edx + + ror r13d,5 + add r12d,r8d + xor r14d,r9d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ebx + mov r8d,r10d + + ror r14d,11 + xor r13d,ebx + xor r15d,edx + + xor r8d,r11d + xor r14d,r9d + add r12d,r15d + mov r15d,r10d + + ror r13d,6 + and r8d,r9d + and r15d,r11d + + ror r14d,2 + add r12d,r13d + add r8d,r15d + + add eax,r12d + add r8d,r12d + lea rdi,QWORD PTR[1+rdi] + add r8d,r14d + + mov r12d,DWORD PTR[48+rsi] + mov r13d,eax + mov r14d,r8d + bswap r12d + ror r13d,14 + mov r15d,ebx + mov DWORD PTR[48+rsp],r12d + + ror r14d,9 + xor r13d,eax + xor r15d,ecx + + ror r13d,5 + add r12d,edx + xor r14d,r8d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,eax + mov edx,r9d + + ror r14d,11 + xor r13d,eax + xor r15d,ecx + + xor edx,r10d + xor r14d,r8d + add r12d,r15d + mov r15d,r9d + + ror r13d,6 + and edx,r8d + and r15d,r10d + + ror r14d,2 + add r12d,r13d + add edx,r15d + + add r11d,r12d + add edx,r12d + lea rdi,QWORD PTR[1+rdi] + add edx,r14d + + mov r12d,DWORD PTR[52+rsi] + mov r13d,r11d + mov r14d,edx + bswap r12d + ror r13d,14 + mov r15d,eax + mov DWORD PTR[52+rsp],r12d + + ror r14d,9 + xor r13d,r11d + xor r15d,ebx + + ror r13d,5 + add r12d,ecx + xor r14d,edx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r11d + mov ecx,r8d + + ror r14d,11 + xor r13d,r11d + xor r15d,ebx + + xor ecx,r9d + xor r14d,edx + add r12d,r15d + mov r15d,r8d + + ror r13d,6 + and ecx,edx + and r15d,r9d + + ror r14d,2 + add r12d,r13d + add ecx,r15d + + add r10d,r12d + add ecx,r12d + lea rdi,QWORD PTR[1+rdi] + add ecx,r14d + + mov r12d,DWORD PTR[56+rsi] + mov r13d,r10d + mov r14d,ecx + bswap r12d + ror r13d,14 + mov r15d,r11d + mov DWORD PTR[56+rsp],r12d + + ror r14d,9 + xor r13d,r10d + xor r15d,eax + + ror r13d,5 + add r12d,ebx + xor r14d,ecx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r10d + mov ebx,edx + + ror r14d,11 + xor r13d,r10d + xor r15d,eax + + xor ebx,r8d + xor r14d,ecx + add r12d,r15d + mov r15d,edx + + ror r13d,6 + and ebx,ecx + and r15d,r8d + + ror r14d,2 + add r12d,r13d + add ebx,r15d + + add r9d,r12d + add ebx,r12d + lea rdi,QWORD PTR[1+rdi] + add ebx,r14d + + mov r12d,DWORD PTR[60+rsi] + mov r13d,r9d + mov r14d,ebx + bswap r12d + ror r13d,14 + mov r15d,r10d + mov DWORD PTR[60+rsp],r12d + + ror r14d,9 + xor r13d,r9d + xor r15d,r11d + + ror r13d,5 + add r12d,eax + xor r14d,ebx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r9d + mov eax,ecx + + ror r14d,11 + xor r13d,r9d + xor r15d,r11d + + xor eax,edx + xor r14d,ebx + add r12d,r15d + mov r15d,ecx + + ror r13d,6 + and eax,ebx + and r15d,edx + + ror r14d,2 + add r12d,r13d + add eax,r15d + + add r8d,r12d + add eax,r12d + lea rdi,QWORD PTR[1+rdi] + add eax,r14d + + jmp $L$rounds_16_xx +ALIGN 16 +$L$rounds_16_xx:: + mov r13d,DWORD PTR[4+rsp] + mov r14d,DWORD PTR[56+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[36+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[rsp] + mov r13d,r8d + add r12d,r14d + mov r14d,eax + ror r13d,14 + mov r15d,r9d + mov DWORD PTR[rsp],r12d + + ror r14d,9 + xor r13d,r8d + xor r15d,r10d + + ror r13d,5 + add r12d,r11d + xor r14d,eax + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r8d + mov r11d,ebx + + ror r14d,11 + xor r13d,r8d + xor r15d,r10d + + xor r11d,ecx + xor r14d,eax + add r12d,r15d + mov r15d,ebx + + ror r13d,6 + and r11d,eax + and r15d,ecx + + ror r14d,2 + add r12d,r13d + add r11d,r15d + + add edx,r12d + add r11d,r12d + lea rdi,QWORD PTR[1+rdi] + add r11d,r14d + + mov r13d,DWORD PTR[8+rsp] + mov r14d,DWORD PTR[60+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[40+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[4+rsp] + mov r13d,edx + add r12d,r14d + mov r14d,r11d + ror r13d,14 + mov r15d,r8d + mov DWORD PTR[4+rsp],r12d + + ror r14d,9 + xor r13d,edx + xor r15d,r9d + + ror r13d,5 + add r12d,r10d + xor r14d,r11d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,edx + mov r10d,eax + + ror r14d,11 + xor r13d,edx + xor r15d,r9d + + xor r10d,ebx + xor r14d,r11d + add r12d,r15d + mov r15d,eax + + ror r13d,6 + and r10d,r11d + and r15d,ebx + + ror r14d,2 + add r12d,r13d + add r10d,r15d + + add ecx,r12d + add r10d,r12d + lea rdi,QWORD PTR[1+rdi] + add r10d,r14d + + mov r13d,DWORD PTR[12+rsp] + mov r14d,DWORD PTR[rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[44+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[8+rsp] + mov r13d,ecx + add r12d,r14d + mov r14d,r10d + ror r13d,14 + mov r15d,edx + mov DWORD PTR[8+rsp],r12d + + ror r14d,9 + xor r13d,ecx + xor r15d,r8d + + ror r13d,5 + add r12d,r9d + xor r14d,r10d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ecx + mov r9d,r11d + + ror r14d,11 + xor r13d,ecx + xor r15d,r8d + + xor r9d,eax + xor r14d,r10d + add r12d,r15d + mov r15d,r11d + + ror r13d,6 + and r9d,r10d + and r15d,eax + + ror r14d,2 + add r12d,r13d + add r9d,r15d + + add ebx,r12d + add r9d,r12d + lea rdi,QWORD PTR[1+rdi] + add r9d,r14d + + mov r13d,DWORD PTR[16+rsp] + mov r14d,DWORD PTR[4+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[48+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[12+rsp] + mov r13d,ebx + add r12d,r14d + mov r14d,r9d + ror r13d,14 + mov r15d,ecx + mov DWORD PTR[12+rsp],r12d + + ror r14d,9 + xor r13d,ebx + xor r15d,edx + + ror r13d,5 + add r12d,r8d + xor r14d,r9d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ebx + mov r8d,r10d + + ror r14d,11 + xor r13d,ebx + xor r15d,edx + + xor r8d,r11d + xor r14d,r9d + add r12d,r15d + mov r15d,r10d + + ror r13d,6 + and r8d,r9d + and r15d,r11d + + ror r14d,2 + add r12d,r13d + add r8d,r15d + + add eax,r12d + add r8d,r12d + lea rdi,QWORD PTR[1+rdi] + add r8d,r14d + + mov r13d,DWORD PTR[20+rsp] + mov r14d,DWORD PTR[8+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[52+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[16+rsp] + mov r13d,eax + add r12d,r14d + mov r14d,r8d + ror r13d,14 + mov r15d,ebx + mov DWORD PTR[16+rsp],r12d + + ror r14d,9 + xor r13d,eax + xor r15d,ecx + + ror r13d,5 + add r12d,edx + xor r14d,r8d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,eax + mov edx,r9d + + ror r14d,11 + xor r13d,eax + xor r15d,ecx + + xor edx,r10d + xor r14d,r8d + add r12d,r15d + mov r15d,r9d + + ror r13d,6 + and edx,r8d + and r15d,r10d + + ror r14d,2 + add r12d,r13d + add edx,r15d + + add r11d,r12d + add edx,r12d + lea rdi,QWORD PTR[1+rdi] + add edx,r14d + + mov r13d,DWORD PTR[24+rsp] + mov r14d,DWORD PTR[12+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[56+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[20+rsp] + mov r13d,r11d + add r12d,r14d + mov r14d,edx + ror r13d,14 + mov r15d,eax + mov DWORD PTR[20+rsp],r12d + + ror r14d,9 + xor r13d,r11d + xor r15d,ebx + + ror r13d,5 + add r12d,ecx + xor r14d,edx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r11d + mov ecx,r8d + + ror r14d,11 + xor r13d,r11d + xor r15d,ebx + + xor ecx,r9d + xor r14d,edx + add r12d,r15d + mov r15d,r8d + + ror r13d,6 + and ecx,edx + and r15d,r9d + + ror r14d,2 + add r12d,r13d + add ecx,r15d + + add r10d,r12d + add ecx,r12d + lea rdi,QWORD PTR[1+rdi] + add ecx,r14d + + mov r13d,DWORD PTR[28+rsp] + mov r14d,DWORD PTR[16+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[60+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[24+rsp] + mov r13d,r10d + add r12d,r14d + mov r14d,ecx + ror r13d,14 + mov r15d,r11d + mov DWORD PTR[24+rsp],r12d + + ror r14d,9 + xor r13d,r10d + xor r15d,eax + + ror r13d,5 + add r12d,ebx + xor r14d,ecx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r10d + mov ebx,edx + + ror r14d,11 + xor r13d,r10d + xor r15d,eax + + xor ebx,r8d + xor r14d,ecx + add r12d,r15d + mov r15d,edx + + ror r13d,6 + and ebx,ecx + and r15d,r8d + + ror r14d,2 + add r12d,r13d + add ebx,r15d + + add r9d,r12d + add ebx,r12d + lea rdi,QWORD PTR[1+rdi] + add ebx,r14d + + mov r13d,DWORD PTR[32+rsp] + mov r14d,DWORD PTR[20+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[28+rsp] + mov r13d,r9d + add r12d,r14d + mov r14d,ebx + ror r13d,14 + mov r15d,r10d + mov DWORD PTR[28+rsp],r12d + + ror r14d,9 + xor r13d,r9d + xor r15d,r11d + + ror r13d,5 + add r12d,eax + xor r14d,ebx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r9d + mov eax,ecx + + ror r14d,11 + xor r13d,r9d + xor r15d,r11d + + xor eax,edx + xor r14d,ebx + add r12d,r15d + mov r15d,ecx + + ror r13d,6 + and eax,ebx + and r15d,edx + + ror r14d,2 + add r12d,r13d + add eax,r15d + + add r8d,r12d + add eax,r12d + lea rdi,QWORD PTR[1+rdi] + add eax,r14d + + mov r13d,DWORD PTR[36+rsp] + mov r14d,DWORD PTR[24+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[4+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[32+rsp] + mov r13d,r8d + add r12d,r14d + mov r14d,eax + ror r13d,14 + mov r15d,r9d + mov DWORD PTR[32+rsp],r12d + + ror r14d,9 + xor r13d,r8d + xor r15d,r10d + + ror r13d,5 + add r12d,r11d + xor r14d,eax + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r8d + mov r11d,ebx + + ror r14d,11 + xor r13d,r8d + xor r15d,r10d + + xor r11d,ecx + xor r14d,eax + add r12d,r15d + mov r15d,ebx + + ror r13d,6 + and r11d,eax + and r15d,ecx + + ror r14d,2 + add r12d,r13d + add r11d,r15d + + add edx,r12d + add r11d,r12d + lea rdi,QWORD PTR[1+rdi] + add r11d,r14d + + mov r13d,DWORD PTR[40+rsp] + mov r14d,DWORD PTR[28+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[8+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[36+rsp] + mov r13d,edx + add r12d,r14d + mov r14d,r11d + ror r13d,14 + mov r15d,r8d + mov DWORD PTR[36+rsp],r12d + + ror r14d,9 + xor r13d,edx + xor r15d,r9d + + ror r13d,5 + add r12d,r10d + xor r14d,r11d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,edx + mov r10d,eax + + ror r14d,11 + xor r13d,edx + xor r15d,r9d + + xor r10d,ebx + xor r14d,r11d + add r12d,r15d + mov r15d,eax + + ror r13d,6 + and r10d,r11d + and r15d,ebx + + ror r14d,2 + add r12d,r13d + add r10d,r15d + + add ecx,r12d + add r10d,r12d + lea rdi,QWORD PTR[1+rdi] + add r10d,r14d + + mov r13d,DWORD PTR[44+rsp] + mov r14d,DWORD PTR[32+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[12+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[40+rsp] + mov r13d,ecx + add r12d,r14d + mov r14d,r10d + ror r13d,14 + mov r15d,edx + mov DWORD PTR[40+rsp],r12d + + ror r14d,9 + xor r13d,ecx + xor r15d,r8d + + ror r13d,5 + add r12d,r9d + xor r14d,r10d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ecx + mov r9d,r11d + + ror r14d,11 + xor r13d,ecx + xor r15d,r8d + + xor r9d,eax + xor r14d,r10d + add r12d,r15d + mov r15d,r11d + + ror r13d,6 + and r9d,r10d + and r15d,eax + + ror r14d,2 + add r12d,r13d + add r9d,r15d + + add ebx,r12d + add r9d,r12d + lea rdi,QWORD PTR[1+rdi] + add r9d,r14d + + mov r13d,DWORD PTR[48+rsp] + mov r14d,DWORD PTR[36+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[16+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[44+rsp] + mov r13d,ebx + add r12d,r14d + mov r14d,r9d + ror r13d,14 + mov r15d,ecx + mov DWORD PTR[44+rsp],r12d + + ror r14d,9 + xor r13d,ebx + xor r15d,edx + + ror r13d,5 + add r12d,r8d + xor r14d,r9d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,ebx + mov r8d,r10d + + ror r14d,11 + xor r13d,ebx + xor r15d,edx + + xor r8d,r11d + xor r14d,r9d + add r12d,r15d + mov r15d,r10d + + ror r13d,6 + and r8d,r9d + and r15d,r11d + + ror r14d,2 + add r12d,r13d + add r8d,r15d + + add eax,r12d + add r8d,r12d + lea rdi,QWORD PTR[1+rdi] + add r8d,r14d + + mov r13d,DWORD PTR[52+rsp] + mov r14d,DWORD PTR[40+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[20+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[48+rsp] + mov r13d,eax + add r12d,r14d + mov r14d,r8d + ror r13d,14 + mov r15d,ebx + mov DWORD PTR[48+rsp],r12d + + ror r14d,9 + xor r13d,eax + xor r15d,ecx + + ror r13d,5 + add r12d,edx + xor r14d,r8d + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,eax + mov edx,r9d + + ror r14d,11 + xor r13d,eax + xor r15d,ecx + + xor edx,r10d + xor r14d,r8d + add r12d,r15d + mov r15d,r9d + + ror r13d,6 + and edx,r8d + and r15d,r10d + + ror r14d,2 + add r12d,r13d + add edx,r15d + + add r11d,r12d + add edx,r12d + lea rdi,QWORD PTR[1+rdi] + add edx,r14d + + mov r13d,DWORD PTR[56+rsp] + mov r14d,DWORD PTR[44+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[24+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[52+rsp] + mov r13d,r11d + add r12d,r14d + mov r14d,edx + ror r13d,14 + mov r15d,eax + mov DWORD PTR[52+rsp],r12d + + ror r14d,9 + xor r13d,r11d + xor r15d,ebx + + ror r13d,5 + add r12d,ecx + xor r14d,edx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r11d + mov ecx,r8d + + ror r14d,11 + xor r13d,r11d + xor r15d,ebx + + xor ecx,r9d + xor r14d,edx + add r12d,r15d + mov r15d,r8d + + ror r13d,6 + and ecx,edx + and r15d,r9d + + ror r14d,2 + add r12d,r13d + add ecx,r15d + + add r10d,r12d + add ecx,r12d + lea rdi,QWORD PTR[1+rdi] + add ecx,r14d + + mov r13d,DWORD PTR[60+rsp] + mov r14d,DWORD PTR[48+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[28+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[56+rsp] + mov r13d,r10d + add r12d,r14d + mov r14d,ecx + ror r13d,14 + mov r15d,r11d + mov DWORD PTR[56+rsp],r12d + + ror r14d,9 + xor r13d,r10d + xor r15d,eax + + ror r13d,5 + add r12d,ebx + xor r14d,ecx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r10d + mov ebx,edx + + ror r14d,11 + xor r13d,r10d + xor r15d,eax + + xor ebx,r8d + xor r14d,ecx + add r12d,r15d + mov r15d,edx + + ror r13d,6 + and ebx,ecx + and r15d,r8d + + ror r14d,2 + add r12d,r13d + add ebx,r15d + + add r9d,r12d + add ebx,r12d + lea rdi,QWORD PTR[1+rdi] + add ebx,r14d + + mov r13d,DWORD PTR[rsp] + mov r14d,DWORD PTR[52+rsp] + mov r12d,r13d + mov r15d,r14d + + ror r12d,11 + xor r12d,r13d + shr r13d,3 + + ror r12d,7 + xor r13d,r12d + mov r12d,DWORD PTR[32+rsp] + + ror r15d,2 + xor r15d,r14d + shr r14d,10 + + ror r15d,17 + add r12d,r13d + xor r14d,r15d + + add r12d,DWORD PTR[60+rsp] + mov r13d,r9d + add r12d,r14d + mov r14d,ebx + ror r13d,14 + mov r15d,r10d + mov DWORD PTR[60+rsp],r12d + + ror r14d,9 + xor r13d,r9d + xor r15d,r11d + + ror r13d,5 + add r12d,eax + xor r14d,ebx + + add r12d,DWORD PTR[rdi*4+rbp] + and r15d,r9d + mov eax,ecx + + ror r14d,11 + xor r13d,r9d + xor r15d,r11d + + xor eax,edx + xor r14d,ebx + add r12d,r15d + mov r15d,ecx + + ror r13d,6 + and eax,ebx + and r15d,edx + + ror r14d,2 + add r12d,r13d + add eax,r15d + + add r8d,r12d + add eax,r12d + lea rdi,QWORD PTR[1+rdi] + add eax,r14d + + cmp rdi,64 + jb $L$rounds_16_xx + + mov rdi,QWORD PTR[((64+0))+rsp] + lea rsi,QWORD PTR[64+rsi] + + add eax,DWORD PTR[rdi] + add ebx,DWORD PTR[4+rdi] + add ecx,DWORD PTR[8+rdi] + add edx,DWORD PTR[12+rdi] + add r8d,DWORD PTR[16+rdi] + add r9d,DWORD PTR[20+rdi] + add r10d,DWORD PTR[24+rdi] + add r11d,DWORD PTR[28+rdi] + + cmp rsi,QWORD PTR[((64+16))+rsp] + + mov DWORD PTR[rdi],eax + mov DWORD PTR[4+rdi],ebx + mov DWORD PTR[8+rdi],ecx + mov DWORD PTR[12+rdi],edx + mov DWORD PTR[16+rdi],r8d + mov DWORD PTR[20+rdi],r9d + mov DWORD PTR[24+rdi],r10d + mov DWORD PTR[28+rdi],r11d + jb $L$loop + + mov rsi,QWORD PTR[((64+24))+rsp] + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha256_block_data_order:: +sha256_block_data_order ENDP +ALIGN 64 + +K256:: + DD 0428a2f98h,071374491h,0b5c0fbcfh,0e9b5dba5h + DD 03956c25bh,059f111f1h,0923f82a4h,0ab1c5ed5h + DD 0d807aa98h,012835b01h,0243185beh,0550c7dc3h + DD 072be5d74h,080deb1feh,09bdc06a7h,0c19bf174h + DD 0e49b69c1h,0efbe4786h,00fc19dc6h,0240ca1cch + DD 02de92c6fh,04a7484aah,05cb0a9dch,076f988dah + DD 0983e5152h,0a831c66dh,0b00327c8h,0bf597fc7h + DD 0c6e00bf3h,0d5a79147h,006ca6351h,014292967h + DD 027b70a85h,02e1b2138h,04d2c6dfch,053380d13h + DD 0650a7354h,0766a0abbh,081c2c92eh,092722c85h + DD 0a2bfe8a1h,0a81a664bh,0c24b8b70h,0c76c51a3h + DD 0d192e819h,0d6990624h,0f40e3585h,0106aa070h + DD 019a4c116h,01e376c08h,02748774ch,034b0bcb5h + DD 0391c0cb3h,04ed8aa4ah,05b9cca4fh,0682e6ff3h + DD 0748f82eeh,078a5636fh,084c87814h,08cc70208h + DD 090befffah,0a4506cebh,0bef9a3f7h,0c67178f2h + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/sha/sha256-mingw64-x86_64.S b/Libraries/libressl/crypto/sha/sha256-mingw64-x86_64.S new file mode 100644 index 000000000..3de981b88 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256-mingw64-x86_64.S @@ -0,0 +1,1790 @@ +#include "x86_arch.h" +.text + +.globl sha256_block_data_order +.def sha256_block_data_order; .scl 2; .type 32; .endef +.p2align 4 +sha256_block_data_order: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_sha256_block_data_order: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $64+32,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %r11,64+24(%rsp) +.Lprologue: + + leaq K256(%rip),%rbp + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + jmp .Lloop + +.p2align 4 +.Lloop: + xorq %rdi,%rdi + movl 0(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,0(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 4(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,4(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 8(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,8(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 12(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,12(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 16(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,16(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 20(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,20(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 24(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,24(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 28(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,28(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + movl 32(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,32(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 36(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,36(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 40(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,40(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 44(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,44(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 48(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,48(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 52(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,52(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 56(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,56(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 60(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,60(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + jmp .Lrounds_16_xx +.p2align 4 +.Lrounds_16_xx: + movl 4(%rsp),%r13d + movl 56(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 36(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 0(%rsp),%r12d + movl %r8d,%r13d + addl %r14d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,0(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 8(%rsp),%r13d + movl 60(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 40(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 4(%rsp),%r12d + movl %edx,%r13d + addl %r14d,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,4(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 12(%rsp),%r13d + movl 0(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 44(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 8(%rsp),%r12d + movl %ecx,%r13d + addl %r14d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,8(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 16(%rsp),%r13d + movl 4(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 48(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 12(%rsp),%r12d + movl %ebx,%r13d + addl %r14d,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,12(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 20(%rsp),%r13d + movl 8(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 52(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 16(%rsp),%r12d + movl %eax,%r13d + addl %r14d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,16(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 24(%rsp),%r13d + movl 12(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 56(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 20(%rsp),%r12d + movl %r11d,%r13d + addl %r14d,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,20(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 28(%rsp),%r13d + movl 16(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 60(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 24(%rsp),%r12d + movl %r10d,%r13d + addl %r14d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,24(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 32(%rsp),%r13d + movl 20(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 0(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 28(%rsp),%r12d + movl %r9d,%r13d + addl %r14d,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,28(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + movl 36(%rsp),%r13d + movl 24(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 4(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 32(%rsp),%r12d + movl %r8d,%r13d + addl %r14d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + movl %r12d,32(%rsp) + + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %eax,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r8d,%r15d + movl %ebx,%r11d + + rorl $11,%r14d + xorl %r8d,%r13d + xorl %r10d,%r15d + + xorl %ecx,%r11d + xorl %eax,%r14d + addl %r15d,%r12d + movl %ebx,%r15d + + rorl $6,%r13d + andl %eax,%r11d + andl %ecx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r11d + + addl %r12d,%edx + addl %r12d,%r11d + leaq 1(%rdi),%rdi + addl %r14d,%r11d + + movl 40(%rsp),%r13d + movl 28(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 8(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 36(%rsp),%r12d + movl %edx,%r13d + addl %r14d,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%r15d + movl %r12d,36(%rsp) + + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r11d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %edx,%r15d + movl %eax,%r10d + + rorl $11,%r14d + xorl %edx,%r13d + xorl %r9d,%r15d + + xorl %ebx,%r10d + xorl %r11d,%r14d + addl %r15d,%r12d + movl %eax,%r15d + + rorl $6,%r13d + andl %r11d,%r10d + andl %ebx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r10d + + addl %r12d,%ecx + addl %r12d,%r10d + leaq 1(%rdi),%rdi + addl %r14d,%r10d + + movl 44(%rsp),%r13d + movl 32(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 12(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 40(%rsp),%r12d + movl %ecx,%r13d + addl %r14d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + movl %r12d,40(%rsp) + + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r10d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ecx,%r15d + movl %r11d,%r9d + + rorl $11,%r14d + xorl %ecx,%r13d + xorl %r8d,%r15d + + xorl %eax,%r9d + xorl %r10d,%r14d + addl %r15d,%r12d + movl %r11d,%r15d + + rorl $6,%r13d + andl %r10d,%r9d + andl %eax,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r9d + + addl %r12d,%ebx + addl %r12d,%r9d + leaq 1(%rdi),%rdi + addl %r14d,%r9d + + movl 48(%rsp),%r13d + movl 36(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 16(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 44(%rsp),%r12d + movl %ebx,%r13d + addl %r14d,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%r15d + movl %r12d,44(%rsp) + + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + rorl $5,%r13d + addl %r8d,%r12d + xorl %r9d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %ebx,%r15d + movl %r10d,%r8d + + rorl $11,%r14d + xorl %ebx,%r13d + xorl %edx,%r15d + + xorl %r11d,%r8d + xorl %r9d,%r14d + addl %r15d,%r12d + movl %r10d,%r15d + + rorl $6,%r13d + andl %r9d,%r8d + andl %r11d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%r8d + + addl %r12d,%eax + addl %r12d,%r8d + leaq 1(%rdi),%rdi + addl %r14d,%r8d + + movl 52(%rsp),%r13d + movl 40(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 20(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 48(%rsp),%r12d + movl %eax,%r13d + addl %r14d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + movl %r12d,48(%rsp) + + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %r8d,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %eax,%r15d + movl %r9d,%edx + + rorl $11,%r14d + xorl %eax,%r13d + xorl %ecx,%r15d + + xorl %r10d,%edx + xorl %r8d,%r14d + addl %r15d,%r12d + movl %r9d,%r15d + + rorl $6,%r13d + andl %r8d,%edx + andl %r10d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%edx + + addl %r12d,%r11d + addl %r12d,%edx + leaq 1(%rdi),%rdi + addl %r14d,%edx + + movl 56(%rsp),%r13d + movl 44(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 24(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 52(%rsp),%r12d + movl %r11d,%r13d + addl %r14d,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%r15d + movl %r12d,52(%rsp) + + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + rorl $5,%r13d + addl %ecx,%r12d + xorl %edx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r11d,%r15d + movl %r8d,%ecx + + rorl $11,%r14d + xorl %r11d,%r13d + xorl %ebx,%r15d + + xorl %r9d,%ecx + xorl %edx,%r14d + addl %r15d,%r12d + movl %r8d,%r15d + + rorl $6,%r13d + andl %edx,%ecx + andl %r9d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ecx + + addl %r12d,%r10d + addl %r12d,%ecx + leaq 1(%rdi),%rdi + addl %r14d,%ecx + + movl 60(%rsp),%r13d + movl 48(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 28(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 56(%rsp),%r12d + movl %r10d,%r13d + addl %r14d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + movl %r12d,56(%rsp) + + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %ecx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r10d,%r15d + movl %edx,%ebx + + rorl $11,%r14d + xorl %r10d,%r13d + xorl %eax,%r15d + + xorl %r8d,%ebx + xorl %ecx,%r14d + addl %r15d,%r12d + movl %edx,%r15d + + rorl $6,%r13d + andl %ecx,%ebx + andl %r8d,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%ebx + + addl %r12d,%r9d + addl %r12d,%ebx + leaq 1(%rdi),%rdi + addl %r14d,%ebx + + movl 0(%rsp),%r13d + movl 52(%rsp),%r14d + movl %r13d,%r12d + movl %r14d,%r15d + + rorl $11,%r12d + xorl %r13d,%r12d + shrl $3,%r13d + + rorl $7,%r12d + xorl %r12d,%r13d + movl 32(%rsp),%r12d + + rorl $2,%r15d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + addl %r13d,%r12d + xorl %r15d,%r14d + + addl 60(%rsp),%r12d + movl %r9d,%r13d + addl %r14d,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%r15d + movl %r12d,60(%rsp) + + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + rorl $5,%r13d + addl %eax,%r12d + xorl %ebx,%r14d + + addl (%rbp,%rdi,4),%r12d + andl %r9d,%r15d + movl %ecx,%eax + + rorl $11,%r14d + xorl %r9d,%r13d + xorl %r11d,%r15d + + xorl %edx,%eax + xorl %ebx,%r14d + addl %r15d,%r12d + movl %ecx,%r15d + + rorl $6,%r13d + andl %ebx,%eax + andl %edx,%r15d + + rorl $2,%r14d + addl %r13d,%r12d + addl %r15d,%eax + + addl %r12d,%r8d + addl %r12d,%eax + leaq 1(%rdi),%rdi + addl %r14d,%eax + + cmpq $64,%rdi + jb .Lrounds_16_xx + + movq 64+0(%rsp),%rdi + leaq 64(%rsi),%rsi + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop + + movq 64+24(%rsp),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_sha256_block_data_order: +.p2align 6 + +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 diff --git a/Libraries/libressl/crypto/sha/sha256-mips.S b/Libraries/libressl/crypto/sha/sha256-mips.S new file mode 100644 index 000000000..3070f55e6 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256-mips.S @@ -0,0 +1,1997 @@ +.text +.set noat +#if !defined(__vxworks) || defined(__pic__) +.option pic2 +#endif + +.align 5 +.globl sha256_block_data_order +.ent sha256_block_data_order +sha256_block_data_order: + .frame $29,128,$31 + .mask 3237937152,-4 + .set noreorder + .cpload $25 + sub $29,128 + sw $31,128-1*4($29) + sw $30,128-2*4($29) + sw $23,128-3*4($29) + sw $22,128-4*4($29) + sw $21,128-5*4($29) + sw $20,128-6*4($29) + sw $19,128-7*4($29) + sw $18,128-8*4($29) + sw $17,128-9*4($29) + sw $16,128-10*4($29) + sll $23,$6,6 + .set reorder + la $6,K256 # PIC-ified 'load address' + + lw $1,0*4($4) # load context + lw $2,1*4($4) + lw $3,2*4($4) + lw $7,3*4($4) + lw $24,4*4($4) + lw $25,5*4($4) + lw $30,6*4($4) + lw $31,7*4($4) + + add $23,$5 # pointer to the end of input + sw $23,16*4($29) + b .Loop + +.align 5 +.Loop: + lwl $8,3($5) + lwr $8,0($5) + lwl $9,7($5) + lwr $9,4($5) + srl $13,$8,24 # byte swap(0) + srl $14,$8,8 + andi $15,$8,0xFF00 + sll $8,$8,24 + andi $14,0xFF00 + sll $15,$15,8 + or $8,$13 + or $14,$15 + or $8,$14 + addu $12,$8,$31 # 0 + srl $31,$24,6 + xor $15,$25,$30 + sll $14,$24,7 + and $15,$24 + srl $13,$24,11 + xor $31,$14 + sll $14,$24,21 + xor $31,$13 + srl $13,$24,25 + xor $31,$14 + sll $14,$24,26 + xor $31,$13 + xor $15,$30 # Ch(e,f,g) + xor $13,$14,$31 # Sigma1(e) + + srl $31,$1,2 + addu $12,$15 + lw $15,0($6) # K[0] + sll $14,$1,10 + addu $12,$13 + srl $13,$1,13 + xor $31,$14 + sll $14,$1,19 + xor $31,$13 + srl $13,$1,22 + xor $31,$14 + sll $14,$1,30 + xor $31,$13 + sw $8,0($29) # offload to ring buffer + xor $31,$14 # Sigma0(a) + + or $13,$1,$2 + and $14,$1,$2 + and $13,$3 + or $14,$13 # Maj(a,b,c) + addu $12,$15 # +=K[0] + addu $31,$14 + + addu $7,$12 + addu $31,$12 + lwl $10,11($5) + lwr $10,8($5) + srl $14,$9,24 # byte swap(1) + srl $15,$9,8 + andi $16,$9,0xFF00 + sll $9,$9,24 + andi $15,0xFF00 + sll $16,$16,8 + or $9,$14 + or $15,$16 + or $9,$15 + addu $13,$9,$30 # 1 + srl $30,$7,6 + xor $16,$24,$25 + sll $15,$7,7 + and $16,$7 + srl $14,$7,11 + xor $30,$15 + sll $15,$7,21 + xor $30,$14 + srl $14,$7,25 + xor $30,$15 + sll $15,$7,26 + xor $30,$14 + xor $16,$25 # Ch(e,f,g) + xor $14,$15,$30 # Sigma1(e) + + srl $30,$31,2 + addu $13,$16 + lw $16,4($6) # K[1] + sll $15,$31,10 + addu $13,$14 + srl $14,$31,13 + xor $30,$15 + sll $15,$31,19 + xor $30,$14 + srl $14,$31,22 + xor $30,$15 + sll $15,$31,30 + xor $30,$14 + sw $9,4($29) # offload to ring buffer + xor $30,$15 # Sigma0(a) + + or $14,$31,$1 + and $15,$31,$1 + and $14,$2 + or $15,$14 # Maj(a,b,c) + addu $13,$16 # +=K[1] + addu $30,$15 + + addu $3,$13 + addu $30,$13 + lwl $11,15($5) + lwr $11,12($5) + srl $15,$10,24 # byte swap(2) + srl $16,$10,8 + andi $17,$10,0xFF00 + sll $10,$10,24 + andi $16,0xFF00 + sll $17,$17,8 + or $10,$15 + or $16,$17 + or $10,$16 + addu $14,$10,$25 # 2 + srl $25,$3,6 + xor $17,$7,$24 + sll $16,$3,7 + and $17,$3 + srl $15,$3,11 + xor $25,$16 + sll $16,$3,21 + xor $25,$15 + srl $15,$3,25 + xor $25,$16 + sll $16,$3,26 + xor $25,$15 + xor $17,$24 # Ch(e,f,g) + xor $15,$16,$25 # Sigma1(e) + + srl $25,$30,2 + addu $14,$17 + lw $17,8($6) # K[2] + sll $16,$30,10 + addu $14,$15 + srl $15,$30,13 + xor $25,$16 + sll $16,$30,19 + xor $25,$15 + srl $15,$30,22 + xor $25,$16 + sll $16,$30,30 + xor $25,$15 + sw $10,8($29) # offload to ring buffer + xor $25,$16 # Sigma0(a) + + or $15,$30,$31 + and $16,$30,$31 + and $15,$1 + or $16,$15 # Maj(a,b,c) + addu $14,$17 # +=K[2] + addu $25,$16 + + addu $2,$14 + addu $25,$14 + lwl $12,19($5) + lwr $12,16($5) + srl $16,$11,24 # byte swap(3) + srl $17,$11,8 + andi $18,$11,0xFF00 + sll $11,$11,24 + andi $17,0xFF00 + sll $18,$18,8 + or $11,$16 + or $17,$18 + or $11,$17 + addu $15,$11,$24 # 3 + srl $24,$2,6 + xor $18,$3,$7 + sll $17,$2,7 + and $18,$2 + srl $16,$2,11 + xor $24,$17 + sll $17,$2,21 + xor $24,$16 + srl $16,$2,25 + xor $24,$17 + sll $17,$2,26 + xor $24,$16 + xor $18,$7 # Ch(e,f,g) + xor $16,$17,$24 # Sigma1(e) + + srl $24,$25,2 + addu $15,$18 + lw $18,12($6) # K[3] + sll $17,$25,10 + addu $15,$16 + srl $16,$25,13 + xor $24,$17 + sll $17,$25,19 + xor $24,$16 + srl $16,$25,22 + xor $24,$17 + sll $17,$25,30 + xor $24,$16 + sw $11,12($29) # offload to ring buffer + xor $24,$17 # Sigma0(a) + + or $16,$25,$30 + and $17,$25,$30 + and $16,$31 + or $17,$16 # Maj(a,b,c) + addu $15,$18 # +=K[3] + addu $24,$17 + + addu $1,$15 + addu $24,$15 + lwl $13,23($5) + lwr $13,20($5) + srl $17,$12,24 # byte swap(4) + srl $18,$12,8 + andi $19,$12,0xFF00 + sll $12,$12,24 + andi $18,0xFF00 + sll $19,$19,8 + or $12,$17 + or $18,$19 + or $12,$18 + addu $16,$12,$7 # 4 + srl $7,$1,6 + xor $19,$2,$3 + sll $18,$1,7 + and $19,$1 + srl $17,$1,11 + xor $7,$18 + sll $18,$1,21 + xor $7,$17 + srl $17,$1,25 + xor $7,$18 + sll $18,$1,26 + xor $7,$17 + xor $19,$3 # Ch(e,f,g) + xor $17,$18,$7 # Sigma1(e) + + srl $7,$24,2 + addu $16,$19 + lw $19,16($6) # K[4] + sll $18,$24,10 + addu $16,$17 + srl $17,$24,13 + xor $7,$18 + sll $18,$24,19 + xor $7,$17 + srl $17,$24,22 + xor $7,$18 + sll $18,$24,30 + xor $7,$17 + sw $12,16($29) # offload to ring buffer + xor $7,$18 # Sigma0(a) + + or $17,$24,$25 + and $18,$24,$25 + and $17,$30 + or $18,$17 # Maj(a,b,c) + addu $16,$19 # +=K[4] + addu $7,$18 + + addu $31,$16 + addu $7,$16 + lwl $14,27($5) + lwr $14,24($5) + srl $18,$13,24 # byte swap(5) + srl $19,$13,8 + andi $20,$13,0xFF00 + sll $13,$13,24 + andi $19,0xFF00 + sll $20,$20,8 + or $13,$18 + or $19,$20 + or $13,$19 + addu $17,$13,$3 # 5 + srl $3,$31,6 + xor $20,$1,$2 + sll $19,$31,7 + and $20,$31 + srl $18,$31,11 + xor $3,$19 + sll $19,$31,21 + xor $3,$18 + srl $18,$31,25 + xor $3,$19 + sll $19,$31,26 + xor $3,$18 + xor $20,$2 # Ch(e,f,g) + xor $18,$19,$3 # Sigma1(e) + + srl $3,$7,2 + addu $17,$20 + lw $20,20($6) # K[5] + sll $19,$7,10 + addu $17,$18 + srl $18,$7,13 + xor $3,$19 + sll $19,$7,19 + xor $3,$18 + srl $18,$7,22 + xor $3,$19 + sll $19,$7,30 + xor $3,$18 + sw $13,20($29) # offload to ring buffer + xor $3,$19 # Sigma0(a) + + or $18,$7,$24 + and $19,$7,$24 + and $18,$25 + or $19,$18 # Maj(a,b,c) + addu $17,$20 # +=K[5] + addu $3,$19 + + addu $30,$17 + addu $3,$17 + lwl $15,31($5) + lwr $15,28($5) + srl $19,$14,24 # byte swap(6) + srl $20,$14,8 + andi $21,$14,0xFF00 + sll $14,$14,24 + andi $20,0xFF00 + sll $21,$21,8 + or $14,$19 + or $20,$21 + or $14,$20 + addu $18,$14,$2 # 6 + srl $2,$30,6 + xor $21,$31,$1 + sll $20,$30,7 + and $21,$30 + srl $19,$30,11 + xor $2,$20 + sll $20,$30,21 + xor $2,$19 + srl $19,$30,25 + xor $2,$20 + sll $20,$30,26 + xor $2,$19 + xor $21,$1 # Ch(e,f,g) + xor $19,$20,$2 # Sigma1(e) + + srl $2,$3,2 + addu $18,$21 + lw $21,24($6) # K[6] + sll $20,$3,10 + addu $18,$19 + srl $19,$3,13 + xor $2,$20 + sll $20,$3,19 + xor $2,$19 + srl $19,$3,22 + xor $2,$20 + sll $20,$3,30 + xor $2,$19 + sw $14,24($29) # offload to ring buffer + xor $2,$20 # Sigma0(a) + + or $19,$3,$7 + and $20,$3,$7 + and $19,$24 + or $20,$19 # Maj(a,b,c) + addu $18,$21 # +=K[6] + addu $2,$20 + + addu $25,$18 + addu $2,$18 + lwl $16,35($5) + lwr $16,32($5) + srl $20,$15,24 # byte swap(7) + srl $21,$15,8 + andi $22,$15,0xFF00 + sll $15,$15,24 + andi $21,0xFF00 + sll $22,$22,8 + or $15,$20 + or $21,$22 + or $15,$21 + addu $19,$15,$1 # 7 + srl $1,$25,6 + xor $22,$30,$31 + sll $21,$25,7 + and $22,$25 + srl $20,$25,11 + xor $1,$21 + sll $21,$25,21 + xor $1,$20 + srl $20,$25,25 + xor $1,$21 + sll $21,$25,26 + xor $1,$20 + xor $22,$31 # Ch(e,f,g) + xor $20,$21,$1 # Sigma1(e) + + srl $1,$2,2 + addu $19,$22 + lw $22,28($6) # K[7] + sll $21,$2,10 + addu $19,$20 + srl $20,$2,13 + xor $1,$21 + sll $21,$2,19 + xor $1,$20 + srl $20,$2,22 + xor $1,$21 + sll $21,$2,30 + xor $1,$20 + sw $15,28($29) # offload to ring buffer + xor $1,$21 # Sigma0(a) + + or $20,$2,$3 + and $21,$2,$3 + and $20,$7 + or $21,$20 # Maj(a,b,c) + addu $19,$22 # +=K[7] + addu $1,$21 + + addu $24,$19 + addu $1,$19 + lwl $17,39($5) + lwr $17,36($5) + srl $21,$16,24 # byte swap(8) + srl $22,$16,8 + andi $23,$16,0xFF00 + sll $16,$16,24 + andi $22,0xFF00 + sll $23,$23,8 + or $16,$21 + or $22,$23 + or $16,$22 + addu $20,$16,$31 # 8 + srl $31,$24,6 + xor $23,$25,$30 + sll $22,$24,7 + and $23,$24 + srl $21,$24,11 + xor $31,$22 + sll $22,$24,21 + xor $31,$21 + srl $21,$24,25 + xor $31,$22 + sll $22,$24,26 + xor $31,$21 + xor $23,$30 # Ch(e,f,g) + xor $21,$22,$31 # Sigma1(e) + + srl $31,$1,2 + addu $20,$23 + lw $23,32($6) # K[8] + sll $22,$1,10 + addu $20,$21 + srl $21,$1,13 + xor $31,$22 + sll $22,$1,19 + xor $31,$21 + srl $21,$1,22 + xor $31,$22 + sll $22,$1,30 + xor $31,$21 + sw $16,32($29) # offload to ring buffer + xor $31,$22 # Sigma0(a) + + or $21,$1,$2 + and $22,$1,$2 + and $21,$3 + or $22,$21 # Maj(a,b,c) + addu $20,$23 # +=K[8] + addu $31,$22 + + addu $7,$20 + addu $31,$20 + lwl $18,43($5) + lwr $18,40($5) + srl $22,$17,24 # byte swap(9) + srl $23,$17,8 + andi $8,$17,0xFF00 + sll $17,$17,24 + andi $23,0xFF00 + sll $8,$8,8 + or $17,$22 + or $23,$8 + or $17,$23 + addu $21,$17,$30 # 9 + srl $30,$7,6 + xor $8,$24,$25 + sll $23,$7,7 + and $8,$7 + srl $22,$7,11 + xor $30,$23 + sll $23,$7,21 + xor $30,$22 + srl $22,$7,25 + xor $30,$23 + sll $23,$7,26 + xor $30,$22 + xor $8,$25 # Ch(e,f,g) + xor $22,$23,$30 # Sigma1(e) + + srl $30,$31,2 + addu $21,$8 + lw $8,36($6) # K[9] + sll $23,$31,10 + addu $21,$22 + srl $22,$31,13 + xor $30,$23 + sll $23,$31,19 + xor $30,$22 + srl $22,$31,22 + xor $30,$23 + sll $23,$31,30 + xor $30,$22 + sw $17,36($29) # offload to ring buffer + xor $30,$23 # Sigma0(a) + + or $22,$31,$1 + and $23,$31,$1 + and $22,$2 + or $23,$22 # Maj(a,b,c) + addu $21,$8 # +=K[9] + addu $30,$23 + + addu $3,$21 + addu $30,$21 + lwl $19,47($5) + lwr $19,44($5) + srl $23,$18,24 # byte swap(10) + srl $8,$18,8 + andi $9,$18,0xFF00 + sll $18,$18,24 + andi $8,0xFF00 + sll $9,$9,8 + or $18,$23 + or $8,$9 + or $18,$8 + addu $22,$18,$25 # 10 + srl $25,$3,6 + xor $9,$7,$24 + sll $8,$3,7 + and $9,$3 + srl $23,$3,11 + xor $25,$8 + sll $8,$3,21 + xor $25,$23 + srl $23,$3,25 + xor $25,$8 + sll $8,$3,26 + xor $25,$23 + xor $9,$24 # Ch(e,f,g) + xor $23,$8,$25 # Sigma1(e) + + srl $25,$30,2 + addu $22,$9 + lw $9,40($6) # K[10] + sll $8,$30,10 + addu $22,$23 + srl $23,$30,13 + xor $25,$8 + sll $8,$30,19 + xor $25,$23 + srl $23,$30,22 + xor $25,$8 + sll $8,$30,30 + xor $25,$23 + sw $18,40($29) # offload to ring buffer + xor $25,$8 # Sigma0(a) + + or $23,$30,$31 + and $8,$30,$31 + and $23,$1 + or $8,$23 # Maj(a,b,c) + addu $22,$9 # +=K[10] + addu $25,$8 + + addu $2,$22 + addu $25,$22 + lwl $20,51($5) + lwr $20,48($5) + srl $8,$19,24 # byte swap(11) + srl $9,$19,8 + andi $10,$19,0xFF00 + sll $19,$19,24 + andi $9,0xFF00 + sll $10,$10,8 + or $19,$8 + or $9,$10 + or $19,$9 + addu $23,$19,$24 # 11 + srl $24,$2,6 + xor $10,$3,$7 + sll $9,$2,7 + and $10,$2 + srl $8,$2,11 + xor $24,$9 + sll $9,$2,21 + xor $24,$8 + srl $8,$2,25 + xor $24,$9 + sll $9,$2,26 + xor $24,$8 + xor $10,$7 # Ch(e,f,g) + xor $8,$9,$24 # Sigma1(e) + + srl $24,$25,2 + addu $23,$10 + lw $10,44($6) # K[11] + sll $9,$25,10 + addu $23,$8 + srl $8,$25,13 + xor $24,$9 + sll $9,$25,19 + xor $24,$8 + srl $8,$25,22 + xor $24,$9 + sll $9,$25,30 + xor $24,$8 + sw $19,44($29) # offload to ring buffer + xor $24,$9 # Sigma0(a) + + or $8,$25,$30 + and $9,$25,$30 + and $8,$31 + or $9,$8 # Maj(a,b,c) + addu $23,$10 # +=K[11] + addu $24,$9 + + addu $1,$23 + addu $24,$23 + lwl $21,55($5) + lwr $21,52($5) + srl $9,$20,24 # byte swap(12) + srl $10,$20,8 + andi $11,$20,0xFF00 + sll $20,$20,24 + andi $10,0xFF00 + sll $11,$11,8 + or $20,$9 + or $10,$11 + or $20,$10 + addu $8,$20,$7 # 12 + srl $7,$1,6 + xor $11,$2,$3 + sll $10,$1,7 + and $11,$1 + srl $9,$1,11 + xor $7,$10 + sll $10,$1,21 + xor $7,$9 + srl $9,$1,25 + xor $7,$10 + sll $10,$1,26 + xor $7,$9 + xor $11,$3 # Ch(e,f,g) + xor $9,$10,$7 # Sigma1(e) + + srl $7,$24,2 + addu $8,$11 + lw $11,48($6) # K[12] + sll $10,$24,10 + addu $8,$9 + srl $9,$24,13 + xor $7,$10 + sll $10,$24,19 + xor $7,$9 + srl $9,$24,22 + xor $7,$10 + sll $10,$24,30 + xor $7,$9 + sw $20,48($29) # offload to ring buffer + xor $7,$10 # Sigma0(a) + + or $9,$24,$25 + and $10,$24,$25 + and $9,$30 + or $10,$9 # Maj(a,b,c) + addu $8,$11 # +=K[12] + addu $7,$10 + + addu $31,$8 + addu $7,$8 + lwl $22,59($5) + lwr $22,56($5) + srl $10,$21,24 # byte swap(13) + srl $11,$21,8 + andi $12,$21,0xFF00 + sll $21,$21,24 + andi $11,0xFF00 + sll $12,$12,8 + or $21,$10 + or $11,$12 + or $21,$11 + addu $9,$21,$3 # 13 + srl $3,$31,6 + xor $12,$1,$2 + sll $11,$31,7 + and $12,$31 + srl $10,$31,11 + xor $3,$11 + sll $11,$31,21 + xor $3,$10 + srl $10,$31,25 + xor $3,$11 + sll $11,$31,26 + xor $3,$10 + xor $12,$2 # Ch(e,f,g) + xor $10,$11,$3 # Sigma1(e) + + srl $3,$7,2 + addu $9,$12 + lw $12,52($6) # K[13] + sll $11,$7,10 + addu $9,$10 + srl $10,$7,13 + xor $3,$11 + sll $11,$7,19 + xor $3,$10 + srl $10,$7,22 + xor $3,$11 + sll $11,$7,30 + xor $3,$10 + sw $21,52($29) # offload to ring buffer + xor $3,$11 # Sigma0(a) + + or $10,$7,$24 + and $11,$7,$24 + and $10,$25 + or $11,$10 # Maj(a,b,c) + addu $9,$12 # +=K[13] + addu $3,$11 + + addu $30,$9 + addu $3,$9 + lw $8,0($29) # prefetch from ring buffer + lwl $23,63($5) + lwr $23,60($5) + srl $11,$22,24 # byte swap(14) + srl $12,$22,8 + andi $13,$22,0xFF00 + sll $22,$22,24 + andi $12,0xFF00 + sll $13,$13,8 + or $22,$11 + or $12,$13 + or $22,$12 + addu $10,$22,$2 # 14 + srl $2,$30,6 + xor $13,$31,$1 + sll $12,$30,7 + and $13,$30 + srl $11,$30,11 + xor $2,$12 + sll $12,$30,21 + xor $2,$11 + srl $11,$30,25 + xor $2,$12 + sll $12,$30,26 + xor $2,$11 + xor $13,$1 # Ch(e,f,g) + xor $11,$12,$2 # Sigma1(e) + + srl $2,$3,2 + addu $10,$13 + lw $13,56($6) # K[14] + sll $12,$3,10 + addu $10,$11 + srl $11,$3,13 + xor $2,$12 + sll $12,$3,19 + xor $2,$11 + srl $11,$3,22 + xor $2,$12 + sll $12,$3,30 + xor $2,$11 + sw $22,56($29) # offload to ring buffer + xor $2,$12 # Sigma0(a) + + or $11,$3,$7 + and $12,$3,$7 + and $11,$24 + or $12,$11 # Maj(a,b,c) + addu $10,$13 # +=K[14] + addu $2,$12 + + addu $25,$10 + addu $2,$10 + lw $9,4($29) # prefetch from ring buffer + srl $12,$23,24 # byte swap(15) + srl $13,$23,8 + andi $14,$23,0xFF00 + sll $23,$23,24 + andi $13,0xFF00 + sll $14,$14,8 + or $23,$12 + or $13,$14 + or $23,$13 + addu $11,$23,$1 # 15 + srl $1,$25,6 + xor $14,$30,$31 + sll $13,$25,7 + and $14,$25 + srl $12,$25,11 + xor $1,$13 + sll $13,$25,21 + xor $1,$12 + srl $12,$25,25 + xor $1,$13 + sll $13,$25,26 + xor $1,$12 + xor $14,$31 # Ch(e,f,g) + xor $12,$13,$1 # Sigma1(e) + + srl $1,$2,2 + addu $11,$14 + lw $14,60($6) # K[15] + sll $13,$2,10 + addu $11,$12 + srl $12,$2,13 + xor $1,$13 + sll $13,$2,19 + xor $1,$12 + srl $12,$2,22 + xor $1,$13 + sll $13,$2,30 + xor $1,$12 + sw $23,60($29) # offload to ring buffer + xor $1,$13 # Sigma0(a) + + or $12,$2,$3 + and $13,$2,$3 + and $12,$7 + or $13,$12 # Maj(a,b,c) + addu $11,$14 # +=K[15] + addu $1,$13 + + addu $24,$11 + addu $1,$11 + lw $10,8($29) # prefetch from ring buffer + b .L16_xx +.align 4 +.L16_xx: + srl $14,$9,3 # Xupdate(16) + addu $8,$17 # +=X[i+9] + sll $13,$9,14 + srl $12,$9,7 + xor $14,$13 + sll $13,11 + xor $14,$12 + srl $12,$9,18 + xor $14,$13 + + srl $15,$22,10 + xor $14,$12 # sigma0(X[i+1]) + sll $13,$22,13 + addu $8,$14 + srl $12,$22,17 + xor $15,$13 + sll $13,2 + xor $15,$12 + srl $12,$22,19 + xor $15,$13 + + xor $15,$12 # sigma1(X[i+14]) + addu $8,$15 + addu $12,$8,$31 # 16 + srl $31,$24,6 + xor $15,$25,$30 + sll $14,$24,7 + and $15,$24 + srl $13,$24,11 + xor $31,$14 + sll $14,$24,21 + xor $31,$13 + srl $13,$24,25 + xor $31,$14 + sll $14,$24,26 + xor $31,$13 + xor $15,$30 # Ch(e,f,g) + xor $13,$14,$31 # Sigma1(e) + + srl $31,$1,2 + addu $12,$15 + lw $15,64($6) # K[16] + sll $14,$1,10 + addu $12,$13 + srl $13,$1,13 + xor $31,$14 + sll $14,$1,19 + xor $31,$13 + srl $13,$1,22 + xor $31,$14 + sll $14,$1,30 + xor $31,$13 + sw $8,0($29) # offload to ring buffer + xor $31,$14 # Sigma0(a) + + or $13,$1,$2 + and $14,$1,$2 + and $13,$3 + or $14,$13 # Maj(a,b,c) + addu $12,$15 # +=K[16] + addu $31,$14 + + addu $7,$12 + addu $31,$12 + lw $11,12($29) # prefetch from ring buffer + srl $15,$10,3 # Xupdate(17) + addu $9,$18 # +=X[i+9] + sll $14,$10,14 + srl $13,$10,7 + xor $15,$14 + sll $14,11 + xor $15,$13 + srl $13,$10,18 + xor $15,$14 + + srl $16,$23,10 + xor $15,$13 # sigma0(X[i+1]) + sll $14,$23,13 + addu $9,$15 + srl $13,$23,17 + xor $16,$14 + sll $14,2 + xor $16,$13 + srl $13,$23,19 + xor $16,$14 + + xor $16,$13 # sigma1(X[i+14]) + addu $9,$16 + addu $13,$9,$30 # 17 + srl $30,$7,6 + xor $16,$24,$25 + sll $15,$7,7 + and $16,$7 + srl $14,$7,11 + xor $30,$15 + sll $15,$7,21 + xor $30,$14 + srl $14,$7,25 + xor $30,$15 + sll $15,$7,26 + xor $30,$14 + xor $16,$25 # Ch(e,f,g) + xor $14,$15,$30 # Sigma1(e) + + srl $30,$31,2 + addu $13,$16 + lw $16,68($6) # K[17] + sll $15,$31,10 + addu $13,$14 + srl $14,$31,13 + xor $30,$15 + sll $15,$31,19 + xor $30,$14 + srl $14,$31,22 + xor $30,$15 + sll $15,$31,30 + xor $30,$14 + sw $9,4($29) # offload to ring buffer + xor $30,$15 # Sigma0(a) + + or $14,$31,$1 + and $15,$31,$1 + and $14,$2 + or $15,$14 # Maj(a,b,c) + addu $13,$16 # +=K[17] + addu $30,$15 + + addu $3,$13 + addu $30,$13 + lw $12,16($29) # prefetch from ring buffer + srl $16,$11,3 # Xupdate(18) + addu $10,$19 # +=X[i+9] + sll $15,$11,14 + srl $14,$11,7 + xor $16,$15 + sll $15,11 + xor $16,$14 + srl $14,$11,18 + xor $16,$15 + + srl $17,$8,10 + xor $16,$14 # sigma0(X[i+1]) + sll $15,$8,13 + addu $10,$16 + srl $14,$8,17 + xor $17,$15 + sll $15,2 + xor $17,$14 + srl $14,$8,19 + xor $17,$15 + + xor $17,$14 # sigma1(X[i+14]) + addu $10,$17 + addu $14,$10,$25 # 18 + srl $25,$3,6 + xor $17,$7,$24 + sll $16,$3,7 + and $17,$3 + srl $15,$3,11 + xor $25,$16 + sll $16,$3,21 + xor $25,$15 + srl $15,$3,25 + xor $25,$16 + sll $16,$3,26 + xor $25,$15 + xor $17,$24 # Ch(e,f,g) + xor $15,$16,$25 # Sigma1(e) + + srl $25,$30,2 + addu $14,$17 + lw $17,72($6) # K[18] + sll $16,$30,10 + addu $14,$15 + srl $15,$30,13 + xor $25,$16 + sll $16,$30,19 + xor $25,$15 + srl $15,$30,22 + xor $25,$16 + sll $16,$30,30 + xor $25,$15 + sw $10,8($29) # offload to ring buffer + xor $25,$16 # Sigma0(a) + + or $15,$30,$31 + and $16,$30,$31 + and $15,$1 + or $16,$15 # Maj(a,b,c) + addu $14,$17 # +=K[18] + addu $25,$16 + + addu $2,$14 + addu $25,$14 + lw $13,20($29) # prefetch from ring buffer + srl $17,$12,3 # Xupdate(19) + addu $11,$20 # +=X[i+9] + sll $16,$12,14 + srl $15,$12,7 + xor $17,$16 + sll $16,11 + xor $17,$15 + srl $15,$12,18 + xor $17,$16 + + srl $18,$9,10 + xor $17,$15 # sigma0(X[i+1]) + sll $16,$9,13 + addu $11,$17 + srl $15,$9,17 + xor $18,$16 + sll $16,2 + xor $18,$15 + srl $15,$9,19 + xor $18,$16 + + xor $18,$15 # sigma1(X[i+14]) + addu $11,$18 + addu $15,$11,$24 # 19 + srl $24,$2,6 + xor $18,$3,$7 + sll $17,$2,7 + and $18,$2 + srl $16,$2,11 + xor $24,$17 + sll $17,$2,21 + xor $24,$16 + srl $16,$2,25 + xor $24,$17 + sll $17,$2,26 + xor $24,$16 + xor $18,$7 # Ch(e,f,g) + xor $16,$17,$24 # Sigma1(e) + + srl $24,$25,2 + addu $15,$18 + lw $18,76($6) # K[19] + sll $17,$25,10 + addu $15,$16 + srl $16,$25,13 + xor $24,$17 + sll $17,$25,19 + xor $24,$16 + srl $16,$25,22 + xor $24,$17 + sll $17,$25,30 + xor $24,$16 + sw $11,12($29) # offload to ring buffer + xor $24,$17 # Sigma0(a) + + or $16,$25,$30 + and $17,$25,$30 + and $16,$31 + or $17,$16 # Maj(a,b,c) + addu $15,$18 # +=K[19] + addu $24,$17 + + addu $1,$15 + addu $24,$15 + lw $14,24($29) # prefetch from ring buffer + srl $18,$13,3 # Xupdate(20) + addu $12,$21 # +=X[i+9] + sll $17,$13,14 + srl $16,$13,7 + xor $18,$17 + sll $17,11 + xor $18,$16 + srl $16,$13,18 + xor $18,$17 + + srl $19,$10,10 + xor $18,$16 # sigma0(X[i+1]) + sll $17,$10,13 + addu $12,$18 + srl $16,$10,17 + xor $19,$17 + sll $17,2 + xor $19,$16 + srl $16,$10,19 + xor $19,$17 + + xor $19,$16 # sigma1(X[i+14]) + addu $12,$19 + addu $16,$12,$7 # 20 + srl $7,$1,6 + xor $19,$2,$3 + sll $18,$1,7 + and $19,$1 + srl $17,$1,11 + xor $7,$18 + sll $18,$1,21 + xor $7,$17 + srl $17,$1,25 + xor $7,$18 + sll $18,$1,26 + xor $7,$17 + xor $19,$3 # Ch(e,f,g) + xor $17,$18,$7 # Sigma1(e) + + srl $7,$24,2 + addu $16,$19 + lw $19,80($6) # K[20] + sll $18,$24,10 + addu $16,$17 + srl $17,$24,13 + xor $7,$18 + sll $18,$24,19 + xor $7,$17 + srl $17,$24,22 + xor $7,$18 + sll $18,$24,30 + xor $7,$17 + sw $12,16($29) # offload to ring buffer + xor $7,$18 # Sigma0(a) + + or $17,$24,$25 + and $18,$24,$25 + and $17,$30 + or $18,$17 # Maj(a,b,c) + addu $16,$19 # +=K[20] + addu $7,$18 + + addu $31,$16 + addu $7,$16 + lw $15,28($29) # prefetch from ring buffer + srl $19,$14,3 # Xupdate(21) + addu $13,$22 # +=X[i+9] + sll $18,$14,14 + srl $17,$14,7 + xor $19,$18 + sll $18,11 + xor $19,$17 + srl $17,$14,18 + xor $19,$18 + + srl $20,$11,10 + xor $19,$17 # sigma0(X[i+1]) + sll $18,$11,13 + addu $13,$19 + srl $17,$11,17 + xor $20,$18 + sll $18,2 + xor $20,$17 + srl $17,$11,19 + xor $20,$18 + + xor $20,$17 # sigma1(X[i+14]) + addu $13,$20 + addu $17,$13,$3 # 21 + srl $3,$31,6 + xor $20,$1,$2 + sll $19,$31,7 + and $20,$31 + srl $18,$31,11 + xor $3,$19 + sll $19,$31,21 + xor $3,$18 + srl $18,$31,25 + xor $3,$19 + sll $19,$31,26 + xor $3,$18 + xor $20,$2 # Ch(e,f,g) + xor $18,$19,$3 # Sigma1(e) + + srl $3,$7,2 + addu $17,$20 + lw $20,84($6) # K[21] + sll $19,$7,10 + addu $17,$18 + srl $18,$7,13 + xor $3,$19 + sll $19,$7,19 + xor $3,$18 + srl $18,$7,22 + xor $3,$19 + sll $19,$7,30 + xor $3,$18 + sw $13,20($29) # offload to ring buffer + xor $3,$19 # Sigma0(a) + + or $18,$7,$24 + and $19,$7,$24 + and $18,$25 + or $19,$18 # Maj(a,b,c) + addu $17,$20 # +=K[21] + addu $3,$19 + + addu $30,$17 + addu $3,$17 + lw $16,32($29) # prefetch from ring buffer + srl $20,$15,3 # Xupdate(22) + addu $14,$23 # +=X[i+9] + sll $19,$15,14 + srl $18,$15,7 + xor $20,$19 + sll $19,11 + xor $20,$18 + srl $18,$15,18 + xor $20,$19 + + srl $21,$12,10 + xor $20,$18 # sigma0(X[i+1]) + sll $19,$12,13 + addu $14,$20 + srl $18,$12,17 + xor $21,$19 + sll $19,2 + xor $21,$18 + srl $18,$12,19 + xor $21,$19 + + xor $21,$18 # sigma1(X[i+14]) + addu $14,$21 + addu $18,$14,$2 # 22 + srl $2,$30,6 + xor $21,$31,$1 + sll $20,$30,7 + and $21,$30 + srl $19,$30,11 + xor $2,$20 + sll $20,$30,21 + xor $2,$19 + srl $19,$30,25 + xor $2,$20 + sll $20,$30,26 + xor $2,$19 + xor $21,$1 # Ch(e,f,g) + xor $19,$20,$2 # Sigma1(e) + + srl $2,$3,2 + addu $18,$21 + lw $21,88($6) # K[22] + sll $20,$3,10 + addu $18,$19 + srl $19,$3,13 + xor $2,$20 + sll $20,$3,19 + xor $2,$19 + srl $19,$3,22 + xor $2,$20 + sll $20,$3,30 + xor $2,$19 + sw $14,24($29) # offload to ring buffer + xor $2,$20 # Sigma0(a) + + or $19,$3,$7 + and $20,$3,$7 + and $19,$24 + or $20,$19 # Maj(a,b,c) + addu $18,$21 # +=K[22] + addu $2,$20 + + addu $25,$18 + addu $2,$18 + lw $17,36($29) # prefetch from ring buffer + srl $21,$16,3 # Xupdate(23) + addu $15,$8 # +=X[i+9] + sll $20,$16,14 + srl $19,$16,7 + xor $21,$20 + sll $20,11 + xor $21,$19 + srl $19,$16,18 + xor $21,$20 + + srl $22,$13,10 + xor $21,$19 # sigma0(X[i+1]) + sll $20,$13,13 + addu $15,$21 + srl $19,$13,17 + xor $22,$20 + sll $20,2 + xor $22,$19 + srl $19,$13,19 + xor $22,$20 + + xor $22,$19 # sigma1(X[i+14]) + addu $15,$22 + addu $19,$15,$1 # 23 + srl $1,$25,6 + xor $22,$30,$31 + sll $21,$25,7 + and $22,$25 + srl $20,$25,11 + xor $1,$21 + sll $21,$25,21 + xor $1,$20 + srl $20,$25,25 + xor $1,$21 + sll $21,$25,26 + xor $1,$20 + xor $22,$31 # Ch(e,f,g) + xor $20,$21,$1 # Sigma1(e) + + srl $1,$2,2 + addu $19,$22 + lw $22,92($6) # K[23] + sll $21,$2,10 + addu $19,$20 + srl $20,$2,13 + xor $1,$21 + sll $21,$2,19 + xor $1,$20 + srl $20,$2,22 + xor $1,$21 + sll $21,$2,30 + xor $1,$20 + sw $15,28($29) # offload to ring buffer + xor $1,$21 # Sigma0(a) + + or $20,$2,$3 + and $21,$2,$3 + and $20,$7 + or $21,$20 # Maj(a,b,c) + addu $19,$22 # +=K[23] + addu $1,$21 + + addu $24,$19 + addu $1,$19 + lw $18,40($29) # prefetch from ring buffer + srl $22,$17,3 # Xupdate(24) + addu $16,$9 # +=X[i+9] + sll $21,$17,14 + srl $20,$17,7 + xor $22,$21 + sll $21,11 + xor $22,$20 + srl $20,$17,18 + xor $22,$21 + + srl $23,$14,10 + xor $22,$20 # sigma0(X[i+1]) + sll $21,$14,13 + addu $16,$22 + srl $20,$14,17 + xor $23,$21 + sll $21,2 + xor $23,$20 + srl $20,$14,19 + xor $23,$21 + + xor $23,$20 # sigma1(X[i+14]) + addu $16,$23 + addu $20,$16,$31 # 24 + srl $31,$24,6 + xor $23,$25,$30 + sll $22,$24,7 + and $23,$24 + srl $21,$24,11 + xor $31,$22 + sll $22,$24,21 + xor $31,$21 + srl $21,$24,25 + xor $31,$22 + sll $22,$24,26 + xor $31,$21 + xor $23,$30 # Ch(e,f,g) + xor $21,$22,$31 # Sigma1(e) + + srl $31,$1,2 + addu $20,$23 + lw $23,96($6) # K[24] + sll $22,$1,10 + addu $20,$21 + srl $21,$1,13 + xor $31,$22 + sll $22,$1,19 + xor $31,$21 + srl $21,$1,22 + xor $31,$22 + sll $22,$1,30 + xor $31,$21 + sw $16,32($29) # offload to ring buffer + xor $31,$22 # Sigma0(a) + + or $21,$1,$2 + and $22,$1,$2 + and $21,$3 + or $22,$21 # Maj(a,b,c) + addu $20,$23 # +=K[24] + addu $31,$22 + + addu $7,$20 + addu $31,$20 + lw $19,44($29) # prefetch from ring buffer + srl $23,$18,3 # Xupdate(25) + addu $17,$10 # +=X[i+9] + sll $22,$18,14 + srl $21,$18,7 + xor $23,$22 + sll $22,11 + xor $23,$21 + srl $21,$18,18 + xor $23,$22 + + srl $8,$15,10 + xor $23,$21 # sigma0(X[i+1]) + sll $22,$15,13 + addu $17,$23 + srl $21,$15,17 + xor $8,$22 + sll $22,2 + xor $8,$21 + srl $21,$15,19 + xor $8,$22 + + xor $8,$21 # sigma1(X[i+14]) + addu $17,$8 + addu $21,$17,$30 # 25 + srl $30,$7,6 + xor $8,$24,$25 + sll $23,$7,7 + and $8,$7 + srl $22,$7,11 + xor $30,$23 + sll $23,$7,21 + xor $30,$22 + srl $22,$7,25 + xor $30,$23 + sll $23,$7,26 + xor $30,$22 + xor $8,$25 # Ch(e,f,g) + xor $22,$23,$30 # Sigma1(e) + + srl $30,$31,2 + addu $21,$8 + lw $8,100($6) # K[25] + sll $23,$31,10 + addu $21,$22 + srl $22,$31,13 + xor $30,$23 + sll $23,$31,19 + xor $30,$22 + srl $22,$31,22 + xor $30,$23 + sll $23,$31,30 + xor $30,$22 + sw $17,36($29) # offload to ring buffer + xor $30,$23 # Sigma0(a) + + or $22,$31,$1 + and $23,$31,$1 + and $22,$2 + or $23,$22 # Maj(a,b,c) + addu $21,$8 # +=K[25] + addu $30,$23 + + addu $3,$21 + addu $30,$21 + lw $20,48($29) # prefetch from ring buffer + srl $8,$19,3 # Xupdate(26) + addu $18,$11 # +=X[i+9] + sll $23,$19,14 + srl $22,$19,7 + xor $8,$23 + sll $23,11 + xor $8,$22 + srl $22,$19,18 + xor $8,$23 + + srl $9,$16,10 + xor $8,$22 # sigma0(X[i+1]) + sll $23,$16,13 + addu $18,$8 + srl $22,$16,17 + xor $9,$23 + sll $23,2 + xor $9,$22 + srl $22,$16,19 + xor $9,$23 + + xor $9,$22 # sigma1(X[i+14]) + addu $18,$9 + addu $22,$18,$25 # 26 + srl $25,$3,6 + xor $9,$7,$24 + sll $8,$3,7 + and $9,$3 + srl $23,$3,11 + xor $25,$8 + sll $8,$3,21 + xor $25,$23 + srl $23,$3,25 + xor $25,$8 + sll $8,$3,26 + xor $25,$23 + xor $9,$24 # Ch(e,f,g) + xor $23,$8,$25 # Sigma1(e) + + srl $25,$30,2 + addu $22,$9 + lw $9,104($6) # K[26] + sll $8,$30,10 + addu $22,$23 + srl $23,$30,13 + xor $25,$8 + sll $8,$30,19 + xor $25,$23 + srl $23,$30,22 + xor $25,$8 + sll $8,$30,30 + xor $25,$23 + sw $18,40($29) # offload to ring buffer + xor $25,$8 # Sigma0(a) + + or $23,$30,$31 + and $8,$30,$31 + and $23,$1 + or $8,$23 # Maj(a,b,c) + addu $22,$9 # +=K[26] + addu $25,$8 + + addu $2,$22 + addu $25,$22 + lw $21,52($29) # prefetch from ring buffer + srl $9,$20,3 # Xupdate(27) + addu $19,$12 # +=X[i+9] + sll $8,$20,14 + srl $23,$20,7 + xor $9,$8 + sll $8,11 + xor $9,$23 + srl $23,$20,18 + xor $9,$8 + + srl $10,$17,10 + xor $9,$23 # sigma0(X[i+1]) + sll $8,$17,13 + addu $19,$9 + srl $23,$17,17 + xor $10,$8 + sll $8,2 + xor $10,$23 + srl $23,$17,19 + xor $10,$8 + + xor $10,$23 # sigma1(X[i+14]) + addu $19,$10 + addu $23,$19,$24 # 27 + srl $24,$2,6 + xor $10,$3,$7 + sll $9,$2,7 + and $10,$2 + srl $8,$2,11 + xor $24,$9 + sll $9,$2,21 + xor $24,$8 + srl $8,$2,25 + xor $24,$9 + sll $9,$2,26 + xor $24,$8 + xor $10,$7 # Ch(e,f,g) + xor $8,$9,$24 # Sigma1(e) + + srl $24,$25,2 + addu $23,$10 + lw $10,108($6) # K[27] + sll $9,$25,10 + addu $23,$8 + srl $8,$25,13 + xor $24,$9 + sll $9,$25,19 + xor $24,$8 + srl $8,$25,22 + xor $24,$9 + sll $9,$25,30 + xor $24,$8 + sw $19,44($29) # offload to ring buffer + xor $24,$9 # Sigma0(a) + + or $8,$25,$30 + and $9,$25,$30 + and $8,$31 + or $9,$8 # Maj(a,b,c) + addu $23,$10 # +=K[27] + addu $24,$9 + + addu $1,$23 + addu $24,$23 + lw $22,56($29) # prefetch from ring buffer + srl $10,$21,3 # Xupdate(28) + addu $20,$13 # +=X[i+9] + sll $9,$21,14 + srl $8,$21,7 + xor $10,$9 + sll $9,11 + xor $10,$8 + srl $8,$21,18 + xor $10,$9 + + srl $11,$18,10 + xor $10,$8 # sigma0(X[i+1]) + sll $9,$18,13 + addu $20,$10 + srl $8,$18,17 + xor $11,$9 + sll $9,2 + xor $11,$8 + srl $8,$18,19 + xor $11,$9 + + xor $11,$8 # sigma1(X[i+14]) + addu $20,$11 + addu $8,$20,$7 # 28 + srl $7,$1,6 + xor $11,$2,$3 + sll $10,$1,7 + and $11,$1 + srl $9,$1,11 + xor $7,$10 + sll $10,$1,21 + xor $7,$9 + srl $9,$1,25 + xor $7,$10 + sll $10,$1,26 + xor $7,$9 + xor $11,$3 # Ch(e,f,g) + xor $9,$10,$7 # Sigma1(e) + + srl $7,$24,2 + addu $8,$11 + lw $11,112($6) # K[28] + sll $10,$24,10 + addu $8,$9 + srl $9,$24,13 + xor $7,$10 + sll $10,$24,19 + xor $7,$9 + srl $9,$24,22 + xor $7,$10 + sll $10,$24,30 + xor $7,$9 + sw $20,48($29) # offload to ring buffer + xor $7,$10 # Sigma0(a) + + or $9,$24,$25 + and $10,$24,$25 + and $9,$30 + or $10,$9 # Maj(a,b,c) + addu $8,$11 # +=K[28] + addu $7,$10 + + addu $31,$8 + addu $7,$8 + lw $23,60($29) # prefetch from ring buffer + srl $11,$22,3 # Xupdate(29) + addu $21,$14 # +=X[i+9] + sll $10,$22,14 + srl $9,$22,7 + xor $11,$10 + sll $10,11 + xor $11,$9 + srl $9,$22,18 + xor $11,$10 + + srl $12,$19,10 + xor $11,$9 # sigma0(X[i+1]) + sll $10,$19,13 + addu $21,$11 + srl $9,$19,17 + xor $12,$10 + sll $10,2 + xor $12,$9 + srl $9,$19,19 + xor $12,$10 + + xor $12,$9 # sigma1(X[i+14]) + addu $21,$12 + addu $9,$21,$3 # 29 + srl $3,$31,6 + xor $12,$1,$2 + sll $11,$31,7 + and $12,$31 + srl $10,$31,11 + xor $3,$11 + sll $11,$31,21 + xor $3,$10 + srl $10,$31,25 + xor $3,$11 + sll $11,$31,26 + xor $3,$10 + xor $12,$2 # Ch(e,f,g) + xor $10,$11,$3 # Sigma1(e) + + srl $3,$7,2 + addu $9,$12 + lw $12,116($6) # K[29] + sll $11,$7,10 + addu $9,$10 + srl $10,$7,13 + xor $3,$11 + sll $11,$7,19 + xor $3,$10 + srl $10,$7,22 + xor $3,$11 + sll $11,$7,30 + xor $3,$10 + sw $21,52($29) # offload to ring buffer + xor $3,$11 # Sigma0(a) + + or $10,$7,$24 + and $11,$7,$24 + and $10,$25 + or $11,$10 # Maj(a,b,c) + addu $9,$12 # +=K[29] + addu $3,$11 + + addu $30,$9 + addu $3,$9 + lw $8,0($29) # prefetch from ring buffer + srl $12,$23,3 # Xupdate(30) + addu $22,$15 # +=X[i+9] + sll $11,$23,14 + srl $10,$23,7 + xor $12,$11 + sll $11,11 + xor $12,$10 + srl $10,$23,18 + xor $12,$11 + + srl $13,$20,10 + xor $12,$10 # sigma0(X[i+1]) + sll $11,$20,13 + addu $22,$12 + srl $10,$20,17 + xor $13,$11 + sll $11,2 + xor $13,$10 + srl $10,$20,19 + xor $13,$11 + + xor $13,$10 # sigma1(X[i+14]) + addu $22,$13 + addu $10,$22,$2 # 30 + srl $2,$30,6 + xor $13,$31,$1 + sll $12,$30,7 + and $13,$30 + srl $11,$30,11 + xor $2,$12 + sll $12,$30,21 + xor $2,$11 + srl $11,$30,25 + xor $2,$12 + sll $12,$30,26 + xor $2,$11 + xor $13,$1 # Ch(e,f,g) + xor $11,$12,$2 # Sigma1(e) + + srl $2,$3,2 + addu $10,$13 + lw $13,120($6) # K[30] + sll $12,$3,10 + addu $10,$11 + srl $11,$3,13 + xor $2,$12 + sll $12,$3,19 + xor $2,$11 + srl $11,$3,22 + xor $2,$12 + sll $12,$3,30 + xor $2,$11 + sw $22,56($29) # offload to ring buffer + xor $2,$12 # Sigma0(a) + + or $11,$3,$7 + and $12,$3,$7 + and $11,$24 + or $12,$11 # Maj(a,b,c) + addu $10,$13 # +=K[30] + addu $2,$12 + + addu $25,$10 + addu $2,$10 + lw $9,4($29) # prefetch from ring buffer + srl $13,$8,3 # Xupdate(31) + addu $23,$16 # +=X[i+9] + sll $12,$8,14 + srl $11,$8,7 + xor $13,$12 + sll $12,11 + xor $13,$11 + srl $11,$8,18 + xor $13,$12 + + srl $14,$21,10 + xor $13,$11 # sigma0(X[i+1]) + sll $12,$21,13 + addu $23,$13 + srl $11,$21,17 + xor $14,$12 + sll $12,2 + xor $14,$11 + srl $11,$21,19 + xor $14,$12 + + xor $14,$11 # sigma1(X[i+14]) + addu $23,$14 + addu $11,$23,$1 # 31 + srl $1,$25,6 + xor $14,$30,$31 + sll $13,$25,7 + and $14,$25 + srl $12,$25,11 + xor $1,$13 + sll $13,$25,21 + xor $1,$12 + srl $12,$25,25 + xor $1,$13 + sll $13,$25,26 + xor $1,$12 + xor $14,$31 # Ch(e,f,g) + xor $12,$13,$1 # Sigma1(e) + + srl $1,$2,2 + addu $11,$14 + lw $14,124($6) # K[31] + sll $13,$2,10 + addu $11,$12 + srl $12,$2,13 + xor $1,$13 + sll $13,$2,19 + xor $1,$12 + srl $12,$2,22 + xor $1,$13 + sll $13,$2,30 + xor $1,$12 + sw $23,60($29) # offload to ring buffer + xor $1,$13 # Sigma0(a) + + or $12,$2,$3 + and $13,$2,$3 + and $12,$7 + or $13,$12 # Maj(a,b,c) + addu $11,$14 # +=K[31] + addu $1,$13 + + addu $24,$11 + addu $1,$11 + lw $10,8($29) # prefetch from ring buffer + and $14,0xfff + li $15,2290 + .set noreorder + bne $14,$15,.L16_xx + add $6,16*4 # Ktbl+=16 + + lw $23,16*4($29) # restore pointer to the end of input + lw $8,0*4($4) + lw $9,1*4($4) + lw $10,2*4($4) + add $5,16*4 + lw $11,3*4($4) + addu $1,$8 + lw $12,4*4($4) + addu $2,$9 + lw $13,5*4($4) + addu $3,$10 + lw $14,6*4($4) + addu $7,$11 + lw $15,7*4($4) + addu $24,$12 + sw $1,0*4($4) + addu $25,$13 + sw $2,1*4($4) + addu $30,$14 + sw $3,2*4($4) + addu $31,$15 + sw $7,3*4($4) + sw $24,4*4($4) + sw $25,5*4($4) + sw $30,6*4($4) + sw $31,7*4($4) + + bne $5,$23,.Loop + sub $6,192 # rewind $6 + + lw $31,128-1*4($29) + lw $30,128-2*4($29) + lw $23,128-3*4($29) + lw $22,128-4*4($29) + lw $21,128-5*4($29) + lw $20,128-6*4($29) + lw $19,128-7*4($29) + lw $18,128-8*4($29) + lw $17,128-9*4($29) + lw $16,128-10*4($29) + jr $31 + add $29,128 +.end sha256_block_data_order + +.rdata +.align 5 +K256: + .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5 + .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 + .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3 + .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 + .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc + .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da + .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7 + .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 + .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13 + .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 + .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3 + .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 + .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5 + .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 + .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208 + .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +.asciiz "SHA256 for MIPS, CRYPTOGAMS by " +.align 5 + +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha256.c b/Libraries/libressl/crypto/sha/sha256.c new file mode 100644 index 000000000..00c936811 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha256.c @@ -0,0 +1,499 @@ +/* $OpenBSD: sha256.c,v 1.30 2023/08/11 15:27:28 jsing Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +#include +#include +#include + +#include + +#include +#include + +#include "crypto_internal.h" + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + +/* Ensure that SHA_LONG and uint32_t are equivalent. */ +CTASSERT(sizeof(SHA_LONG) == sizeof(uint32_t)); + +#ifdef SHA256_ASM +void sha256_block_data_order(SHA256_CTX *ctx, const void *_in, size_t num); +#endif + +#ifndef SHA256_ASM +static const SHA_LONG K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, +}; + +static inline SHA_LONG +Sigma0(SHA_LONG x) +{ + return crypto_ror_u32(x, 2) ^ crypto_ror_u32(x, 13) ^ + crypto_ror_u32(x, 22); +} + +static inline SHA_LONG +Sigma1(SHA_LONG x) +{ + return crypto_ror_u32(x, 6) ^ crypto_ror_u32(x, 11) ^ + crypto_ror_u32(x, 25); +} + +static inline SHA_LONG +sigma0(SHA_LONG x) +{ + return crypto_ror_u32(x, 7) ^ crypto_ror_u32(x, 18) ^ (x >> 3); +} + +static inline SHA_LONG +sigma1(SHA_LONG x) +{ + return crypto_ror_u32(x, 17) ^ crypto_ror_u32(x, 19) ^ (x >> 10); +} + +static inline SHA_LONG +Ch(SHA_LONG x, SHA_LONG y, SHA_LONG z) +{ + return (x & y) ^ (~x & z); +} + +static inline SHA_LONG +Maj(SHA_LONG x, SHA_LONG y, SHA_LONG z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} + +static inline void +sha256_msg_schedule_update(SHA_LONG *W0, SHA_LONG W1, + SHA_LONG W9, SHA_LONG W14) +{ + *W0 = sigma1(W14) + W9 + sigma0(W1) + *W0; +} + +static inline void +sha256_round(SHA_LONG *a, SHA_LONG *b, SHA_LONG *c, SHA_LONG *d, + SHA_LONG *e, SHA_LONG *f, SHA_LONG *g, SHA_LONG *h, + SHA_LONG Kt, SHA_LONG Wt) +{ + SHA_LONG T1, T2; + + T1 = *h + Sigma1(*e) + Ch(*e, *f, *g) + Kt + Wt; + T2 = Sigma0(*a) + Maj(*a, *b, *c); + + *h = *g; + *g = *f; + *f = *e; + *e = *d + T1; + *d = *c; + *c = *b; + *b = *a; + *a = T1 + T2; +} + +static void +sha256_block_data_order(SHA256_CTX *ctx, const void *_in, size_t num) +{ + const uint8_t *in = _in; + const SHA_LONG *in32; + SHA_LONG a, b, c, d, e, f, g, h; + SHA_LONG X[16]; + int i; + + while (num--) { + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + if ((size_t)in % 4 == 0) { + /* Input is 32 bit aligned. */ + in32 = (const SHA_LONG *)in; + X[0] = be32toh(in32[0]); + X[1] = be32toh(in32[1]); + X[2] = be32toh(in32[2]); + X[3] = be32toh(in32[3]); + X[4] = be32toh(in32[4]); + X[5] = be32toh(in32[5]); + X[6] = be32toh(in32[6]); + X[7] = be32toh(in32[7]); + X[8] = be32toh(in32[8]); + X[9] = be32toh(in32[9]); + X[10] = be32toh(in32[10]); + X[11] = be32toh(in32[11]); + X[12] = be32toh(in32[12]); + X[13] = be32toh(in32[13]); + X[14] = be32toh(in32[14]); + X[15] = be32toh(in32[15]); + } else { + /* Input is not 32 bit aligned. */ + X[0] = crypto_load_be32toh(&in[0 * 4]); + X[1] = crypto_load_be32toh(&in[1 * 4]); + X[2] = crypto_load_be32toh(&in[2 * 4]); + X[3] = crypto_load_be32toh(&in[3 * 4]); + X[4] = crypto_load_be32toh(&in[4 * 4]); + X[5] = crypto_load_be32toh(&in[5 * 4]); + X[6] = crypto_load_be32toh(&in[6 * 4]); + X[7] = crypto_load_be32toh(&in[7 * 4]); + X[8] = crypto_load_be32toh(&in[8 * 4]); + X[9] = crypto_load_be32toh(&in[9 * 4]); + X[10] = crypto_load_be32toh(&in[10 * 4]); + X[11] = crypto_load_be32toh(&in[11 * 4]); + X[12] = crypto_load_be32toh(&in[12 * 4]); + X[13] = crypto_load_be32toh(&in[13 * 4]); + X[14] = crypto_load_be32toh(&in[14 * 4]); + X[15] = crypto_load_be32toh(&in[15 * 4]); + } + in += SHA256_CBLOCK; + + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[0], X[0]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[1], X[1]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[2], X[2]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[3], X[3]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[4], X[4]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[5], X[5]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[6], X[6]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[7], X[7]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[8], X[8]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[9], X[9]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[10], X[10]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[11], X[11]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[12], X[12]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[13], X[13]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[14], X[14]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[15], X[15]); + + for (i = 16; i < 64; i += 16) { + sha256_msg_schedule_update(&X[0], X[1], X[9], X[14]); + sha256_msg_schedule_update(&X[1], X[2], X[10], X[15]); + sha256_msg_schedule_update(&X[2], X[3], X[11], X[0]); + sha256_msg_schedule_update(&X[3], X[4], X[12], X[1]); + sha256_msg_schedule_update(&X[4], X[5], X[13], X[2]); + sha256_msg_schedule_update(&X[5], X[6], X[14], X[3]); + sha256_msg_schedule_update(&X[6], X[7], X[15], X[4]); + sha256_msg_schedule_update(&X[7], X[8], X[0], X[5]); + sha256_msg_schedule_update(&X[8], X[9], X[1], X[6]); + sha256_msg_schedule_update(&X[9], X[10], X[2], X[7]); + sha256_msg_schedule_update(&X[10], X[11], X[3], X[8]); + sha256_msg_schedule_update(&X[11], X[12], X[4], X[9]); + sha256_msg_schedule_update(&X[12], X[13], X[5], X[10]); + sha256_msg_schedule_update(&X[13], X[14], X[6], X[11]); + sha256_msg_schedule_update(&X[14], X[15], X[7], X[12]); + sha256_msg_schedule_update(&X[15], X[0], X[8], X[13]); + + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 0], X[0]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 1], X[1]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 2], X[2]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 3], X[3]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 4], X[4]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 5], X[5]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 6], X[6]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 7], X[7]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 8], X[8]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 9], X[9]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 10], X[10]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 11], X[11]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 12], X[12]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 13], X[13]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 14], X[14]); + sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 15], X[15]); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + } +} +#endif /* SHA256_ASM */ + +int +SHA224_Init(SHA256_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + c->h[0] = 0xc1059ed8UL; + c->h[1] = 0x367cd507UL; + c->h[2] = 0x3070dd17UL; + c->h[3] = 0xf70e5939UL; + c->h[4] = 0xffc00b31UL; + c->h[5] = 0x68581511UL; + c->h[6] = 0x64f98fa7UL; + c->h[7] = 0xbefa4fa4UL; + + c->md_len = SHA224_DIGEST_LENGTH; + + return 1; +} +LCRYPTO_ALIAS(SHA224_Init); + +int +SHA224_Update(SHA256_CTX *c, const void *data, size_t len) +{ + return SHA256_Update(c, data, len); +} +LCRYPTO_ALIAS(SHA224_Update); + +int +SHA224_Final(unsigned char *md, SHA256_CTX *c) +{ + return SHA256_Final(md, c); +} +LCRYPTO_ALIAS(SHA224_Final); + +unsigned char * +SHA224(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA224_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + + SHA224_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + + explicit_bzero(&c, sizeof(c)); + + return (md); +} +LCRYPTO_ALIAS(SHA224); + +int +SHA256_Init(SHA256_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + c->h[0] = 0x6a09e667UL; + c->h[1] = 0xbb67ae85UL; + c->h[2] = 0x3c6ef372UL; + c->h[3] = 0xa54ff53aUL; + c->h[4] = 0x510e527fUL; + c->h[5] = 0x9b05688cUL; + c->h[6] = 0x1f83d9abUL; + c->h[7] = 0x5be0cd19UL; + + c->md_len = SHA256_DIGEST_LENGTH; + + return 1; +} +LCRYPTO_ALIAS(SHA256_Init); + +int +SHA256_Update(SHA256_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + SHA_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((SHA_LONG)len) << 3)) & 0xffffffffUL; + /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to + * Wei Dai for pointing it out. */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh += (SHA_LONG)(len >> 29); /* might cause compiler warning on 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= SHA_CBLOCK || len + n >= SHA_CBLOCK) { + memcpy(p + n, data, SHA_CBLOCK - n); + sha256_block_data_order(c, p, 1); + n = SHA_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset(p, 0, SHA_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len/SHA_CBLOCK; + if (n > 0) { + sha256_block_data_order(c, data, n); + n *= SHA_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} +LCRYPTO_ALIAS(SHA256_Update); + +void +SHA256_Transform(SHA256_CTX *c, const unsigned char *data) +{ + sha256_block_data_order(c, data, 1); +} +LCRYPTO_ALIAS(SHA256_Transform); + +int +SHA256_Final(unsigned char *md, SHA256_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + unsigned int nn; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (SHA_CBLOCK - 8)) { + memset(p + n, 0, SHA_CBLOCK - n); + n = 0; + sha256_block_data_order(c, p, 1); + } + + memset(p + n, 0, SHA_CBLOCK - 8 - n); + c->data[SHA_LBLOCK - 2] = htobe32(c->Nh); + c->data[SHA_LBLOCK - 1] = htobe32(c->Nl); + + sha256_block_data_order(c, p, 1); + c->num = 0; + memset(p, 0, SHA_CBLOCK); + + /* + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." + * default: case below covers for it. It's not clear however if it's + * permitted to truncate to amount of bytes not divisible by 4. I bet not, + * but if it is, then default: case shall be extended. For reference. + * Idea behind separate cases for pre-defined lengths is to let the + * compiler decide if it's appropriate to unroll small loops. + */ + switch (c->md_len) { + case SHA224_DIGEST_LENGTH: + for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { + crypto_store_htobe32(md, c->h[nn]); + md += 4; + } + break; + + case SHA256_DIGEST_LENGTH: + for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { + crypto_store_htobe32(md, c->h[nn]); + md += 4; + } + break; + + default: + if (c->md_len > SHA256_DIGEST_LENGTH) + return 0; + for (nn = 0; nn < c->md_len / 4; nn++) { + crypto_store_htobe32(md, c->h[nn]); + md += 4; + } + break; + } + + return 1; +} +LCRYPTO_ALIAS(SHA256_Final); + +unsigned char * +SHA256(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA256_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + + SHA256_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + + explicit_bzero(&c, sizeof(c)); + + return (md); +} +LCRYPTO_ALIAS(SHA256); + +#endif /* OPENSSL_NO_SHA256 */ diff --git a/Libraries/libressl/crypto/sha/sha3.c b/Libraries/libressl/crypto/sha/sha3.c new file mode 100644 index 000000000..b070d715c --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha3.c @@ -0,0 +1,193 @@ +/* $OpenBSD: sha3.c,v 1.15 2023/04/16 15:32:16 jsing Exp $ */ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Markku-Juhani O. Saarinen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "sha3_internal.h" + +#define KECCAKF_ROUNDS 24 + +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) + +static const uint64_t sha3_keccakf_rndc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 +}; +static const int sha3_keccakf_rotc[24] = { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 +}; +static const int sha3_keccakf_piln[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 +}; + +static void +sha3_keccakf(uint64_t st[25]) +{ + uint64_t t, bc[5]; + int i, j, r; + +#if BYTE_ORDER != LITTLE_ENDIAN + uint8_t *v; + + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | + (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | + (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | + (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); + } +#endif + + for (r = 0; r < KECCAKF_ROUNDS; r++) { + + /* Theta */ + for (i = 0; i < 5; i++) + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + + for (i = 0; i < 5; i++) { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + st[j + i] ^= t; + } + + /* Rho Pi */ + t = st[1]; + for (i = 0; i < 24; i++) { + j = sha3_keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, sha3_keccakf_rotc[i]); + t = bc[0]; + } + + /* Chi */ + for (j = 0; j < 25; j += 5) { + for (i = 0; i < 5; i++) + bc[i] = st[j + i]; + for (i = 0; i < 5; i++) + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + + /* Iota */ + st[0] ^= sha3_keccakf_rndc[r]; + } + +#if BYTE_ORDER != LITTLE_ENDIAN + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + t = st[i]; + v[0] = t & 0xFF; + v[1] = (t >> 8) & 0xFF; + v[2] = (t >> 16) & 0xFF; + v[3] = (t >> 24) & 0xFF; + v[4] = (t >> 32) & 0xFF; + v[5] = (t >> 40) & 0xFF; + v[6] = (t >> 48) & 0xFF; + v[7] = (t >> 56) & 0xFF; + } +#endif +} + +int +sha3_init(sha3_ctx *c, int mdlen) +{ + if (mdlen < 0 || mdlen >= KECCAK_BYTE_WIDTH / 2) + return 0; + + memset(c, 0, sizeof(*c)); + + c->mdlen = mdlen; + c->rsize = KECCAK_BYTE_WIDTH - 2 * mdlen; + + return 1; +} + +int +sha3_update(sha3_ctx *c, const void *data, size_t len) +{ + size_t i, j; + + j = c->pt; + for (i = 0; i < len; i++) { + c->state.b[j++] ^= ((const uint8_t *) data)[i]; + if (j >= c->rsize) { + sha3_keccakf(c->state.q); + j = 0; + } + } + c->pt = j; + + return 1; +} + +int +sha3_final(void *md, sha3_ctx *c) +{ + int i; + + c->state.b[c->pt] ^= 0x06; + c->state.b[c->rsize - 1] ^= 0x80; + sha3_keccakf(c->state.q); + + for (i = 0; i < c->mdlen; i++) { + ((uint8_t *) md)[i] = c->state.b[i]; + } + + return 1; +} + +/* SHAKE128 and SHAKE256 extensible-output functionality. */ +void +shake_xof(sha3_ctx *c) +{ + c->state.b[c->pt] ^= 0x1F; + c->state.b[c->rsize - 1] ^= 0x80; + sha3_keccakf(c->state.q); + c->pt = 0; +} + +void +shake_out(sha3_ctx *c, void *out, size_t len) +{ + size_t i, j; + + j = c->pt; + for (i = 0; i < len; i++) { + if (j >= c->rsize) { + sha3_keccakf(c->state.q); + j = 0; + } + ((uint8_t *) out)[i] = c->state.b[j++]; + } + c->pt = j; +} diff --git a/Libraries/libressl/crypto/sha/sha3_internal.h b/Libraries/libressl/crypto/sha/sha3_internal.h new file mode 100644 index 000000000..53a4980c1 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha3_internal.h @@ -0,0 +1,81 @@ +/* $OpenBSD: sha3_internal.h,v 1.15 2023/04/25 19:32:19 tb Exp $ */ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Markku-Juhani O. Saarinen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#ifndef HEADER_SHA3_INTERNAL_H +#define HEADER_SHA3_INTERNAL_H + +#define KECCAK_BIT_WIDTH 1600 +#define KECCAK_BYTE_WIDTH (KECCAK_BIT_WIDTH / 8) + +#define SHA3_224_BIT_LENGTH 224 +#define SHA3_224_BITRATE (2 * SHA3_224_BIT_LENGTH) +#define SHA3_224_CAPACITY (KECCAK_BIT_WIDTH - SHA3_224_BITRATE) +#define SHA3_224_BLOCK_SIZE (SHA3_224_CAPACITY / 8) +#define SHA3_224_DIGEST_LENGTH (SHA3_224_BIT_LENGTH / 8) + +#define SHA3_256_BIT_LENGTH 256 +#define SHA3_256_BITRATE (2 * SHA3_256_BIT_LENGTH) +#define SHA3_256_CAPACITY (KECCAK_BIT_WIDTH - SHA3_256_BITRATE) +#define SHA3_256_BLOCK_SIZE (SHA3_256_CAPACITY / 8) +#define SHA3_256_DIGEST_LENGTH (SHA3_256_BIT_LENGTH / 8) + +#define SHA3_384_BIT_LENGTH 384 +#define SHA3_384_BITRATE (2 * SHA3_384_BIT_LENGTH) +#define SHA3_384_CAPACITY (KECCAK_BIT_WIDTH - SHA3_384_BITRATE) +#define SHA3_384_BLOCK_SIZE (SHA3_384_CAPACITY / 8) +#define SHA3_384_DIGEST_LENGTH (SHA3_384_BIT_LENGTH / 8) + +#define SHA3_512_BIT_LENGTH 512 +#define SHA3_512_BITRATE (2 * SHA3_512_BIT_LENGTH) +#define SHA3_512_CAPACITY (KECCAK_BIT_WIDTH - SHA3_512_BITRATE) +#define SHA3_512_BLOCK_SIZE (SHA3_512_CAPACITY / 8) +#define SHA3_512_DIGEST_LENGTH (SHA3_512_BIT_LENGTH / 8) + +typedef struct sha3_ctx_st { + union { + uint8_t b[200]; /* State as 8 bit bytes. */ + uint64_t q[25]; /* State as 64 bit words. */ + } state; + size_t pt; + size_t rsize; + size_t mdlen; +} sha3_ctx; + +int sha3_init(sha3_ctx *c, int mdlen); +int sha3_update(sha3_ctx *c, const void *data, size_t len); +int sha3_final(void *md, sha3_ctx *c); + +/* SHAKE128 and SHAKE256 extensible-output functions. */ +#define shake128_init(c) sha3_init(c, 16) +#define shake256_init(c) sha3_init(c, 32) +#define shake_update sha3_update + +void shake_xof(sha3_ctx *c); +void shake_out(sha3_ctx *c, void *out, size_t len); + +#endif diff --git a/Libraries/libressl/crypto/sha/sha512-elf-armv4.S b/Libraries/libressl/crypto/sha/sha512-elf-armv4.S new file mode 100644 index 000000000..8abf8d563 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512-elf-armv4.S @@ -0,0 +1,1786 @@ +#include "arm_arch.h" +#ifdef __ARMEL__ +# define LO 0 +# define HI 4 +# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1 +#else +# define HI 0 +# define LO 4 +# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1 +#endif + +.text +.code 32 +.type K512,%object +.align 5 +K512: +WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd) +WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc) +WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019) +WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118) +WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe) +WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2) +WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1) +WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694) +WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3) +WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65) +WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483) +WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5) +WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210) +WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4) +WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725) +WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70) +WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926) +WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df) +WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8) +WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b) +WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001) +WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30) +WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910) +WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8) +WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53) +WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8) +WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb) +WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3) +WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60) +WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec) +WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9) +WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b) +WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207) +WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178) +WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6) +WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b) +WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493) +WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c) +WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) +WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) +.size K512,.-K512 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-sha512_block_data_order +.skip 32-4 + +.global sha512_block_data_order +.type sha512_block_data_order,%function +sha512_block_data_order: + sub r3,pc,#8 @ sha512_block_data_order + add r2,r1,r2,lsl#7 @ len to point at the end of inp +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) + ldr r12,.LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P + tst r12,#1 + bne .LNEON +#endif + stmdb sp!,{r4-r12,lr} + sub r14,r3,#672 @ K512 + sub sp,sp,#9*8 + + ldr r7,[r0,#32+LO] + ldr r8,[r0,#32+HI] + ldr r9, [r0,#48+LO] + ldr r10, [r0,#48+HI] + ldr r11, [r0,#56+LO] + ldr r12, [r0,#56+HI] +.Loop: + str r9, [sp,#48+0] + str r10, [sp,#48+4] + str r11, [sp,#56+0] + str r12, [sp,#56+4] + ldr r5,[r0,#0+LO] + ldr r6,[r0,#0+HI] + ldr r3,[r0,#8+LO] + ldr r4,[r0,#8+HI] + ldr r9, [r0,#16+LO] + ldr r10, [r0,#16+HI] + ldr r11, [r0,#24+LO] + ldr r12, [r0,#24+HI] + str r3,[sp,#8+0] + str r4,[sp,#8+4] + str r9, [sp,#16+0] + str r10, [sp,#16+4] + str r11, [sp,#24+0] + str r12, [sp,#24+4] + ldr r3,[r0,#40+LO] + ldr r4,[r0,#40+HI] + str r3,[sp,#40+0] + str r4,[sp,#40+4] + +.L00_15: +#if __ARM_ARCH__<7 || defined(__STRICT_ALIGNMENT) + ldrb r3,[r1,#7] + ldrb r9, [r1,#6] + ldrb r10, [r1,#5] + ldrb r11, [r1,#4] + ldrb r4,[r1,#3] + ldrb r12, [r1,#2] + orr r3,r3,r9,lsl#8 + ldrb r9, [r1,#1] + orr r3,r3,r10,lsl#16 + ldrb r10, [r1],#8 + orr r3,r3,r11,lsl#24 + orr r4,r4,r12,lsl#8 + orr r4,r4,r9,lsl#16 + orr r4,r4,r10,lsl#24 +#else + ldr r3,[r1,#4] + ldr r4,[r1],#8 +#ifdef __ARMEL__ + rev r3,r3 + rev r4,r4 +#endif +#endif + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov r9,r7,lsr#14 + str r3,[sp,#64+0] + mov r10,r8,lsr#14 + str r4,[sp,#64+4] + eor r9,r9,r8,lsl#18 + ldr r11,[sp,#56+0] @ h.lo + eor r10,r10,r7,lsl#18 + ldr r12,[sp,#56+4] @ h.hi + eor r9,r9,r7,lsr#18 + eor r10,r10,r8,lsr#18 + eor r9,r9,r8,lsl#14 + eor r10,r10,r7,lsl#14 + eor r9,r9,r8,lsr#9 + eor r10,r10,r7,lsr#9 + eor r9,r9,r7,lsl#23 + eor r10,r10,r8,lsl#23 @ Sigma1(e) + adds r3,r3,r9 + ldr r9,[sp,#40+0] @ f.lo + adc r4,r4,r10 @ T += Sigma1(e) + ldr r10,[sp,#40+4] @ f.hi + adds r3,r3,r11 + ldr r11,[sp,#48+0] @ g.lo + adc r4,r4,r12 @ T += h + ldr r12,[sp,#48+4] @ g.hi + + eor r9,r9,r11 + str r7,[sp,#32+0] + eor r10,r10,r12 + str r8,[sp,#32+4] + and r9,r9,r7 + str r5,[sp,#0+0] + and r10,r10,r8 + str r6,[sp,#0+4] + eor r9,r9,r11 + ldr r11,[r14,#LO] @ K[i].lo + eor r10,r10,r12 @ Ch(e,f,g) + ldr r12,[r14,#HI] @ K[i].hi + + adds r3,r3,r9 + ldr r7,[sp,#24+0] @ d.lo + adc r4,r4,r10 @ T += Ch(e,f,g) + ldr r8,[sp,#24+4] @ d.hi + adds r3,r3,r11 + and r9,r11,#0xff + adc r4,r4,r12 @ T += K[i] + adds r7,r7,r3 + ldr r11,[sp,#8+0] @ b.lo + adc r8,r8,r4 @ d += T + teq r9,#148 + + ldr r12,[sp,#16+0] @ c.lo + orreq r14,r14,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov r9,r5,lsr#28 + mov r10,r6,lsr#28 + eor r9,r9,r6,lsl#4 + eor r10,r10,r5,lsl#4 + eor r9,r9,r6,lsr#2 + eor r10,r10,r5,lsr#2 + eor r9,r9,r5,lsl#30 + eor r10,r10,r6,lsl#30 + eor r9,r9,r6,lsr#7 + eor r10,r10,r5,lsr#7 + eor r9,r9,r5,lsl#25 + eor r10,r10,r6,lsl#25 @ Sigma0(a) + adds r3,r3,r9 + and r9,r5,r11 + adc r4,r4,r10 @ T += Sigma0(a) + + ldr r10,[sp,#8+4] @ b.hi + orr r5,r5,r11 + ldr r11,[sp,#16+4] @ c.hi + and r5,r5,r12 + and r12,r6,r10 + orr r6,r6,r10 + orr r5,r5,r9 @ Maj(a,b,c).lo + and r6,r6,r11 + adds r5,r5,r3 + orr r6,r6,r12 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc r6,r6,r4 @ h += T + tst r14,#1 + add r14,r14,#8 + tst r14,#1 + beq .L00_15 + ldr r9,[sp,#184+0] + ldr r10,[sp,#184+4] + bic r14,r14,#1 +.L16_79: + @ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) + @ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 + @ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 + mov r3,r9,lsr#1 + ldr r11,[sp,#80+0] + mov r4,r10,lsr#1 + ldr r12,[sp,#80+4] + eor r3,r3,r10,lsl#31 + eor r4,r4,r9,lsl#31 + eor r3,r3,r9,lsr#8 + eor r4,r4,r10,lsr#8 + eor r3,r3,r10,lsl#24 + eor r4,r4,r9,lsl#24 + eor r3,r3,r9,lsr#7 + eor r4,r4,r10,lsr#7 + eor r3,r3,r10,lsl#25 + + @ sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + @ LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 + @ HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 + mov r9,r11,lsr#19 + mov r10,r12,lsr#19 + eor r9,r9,r12,lsl#13 + eor r10,r10,r11,lsl#13 + eor r9,r9,r12,lsr#29 + eor r10,r10,r11,lsr#29 + eor r9,r9,r11,lsl#3 + eor r10,r10,r12,lsl#3 + eor r9,r9,r11,lsr#6 + eor r10,r10,r12,lsr#6 + ldr r11,[sp,#120+0] + eor r9,r9,r12,lsl#26 + + ldr r12,[sp,#120+4] + adds r3,r3,r9 + ldr r9,[sp,#192+0] + adc r4,r4,r10 + + ldr r10,[sp,#192+4] + adds r3,r3,r11 + adc r4,r4,r12 + adds r3,r3,r9 + adc r4,r4,r10 + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov r9,r7,lsr#14 + str r3,[sp,#64+0] + mov r10,r8,lsr#14 + str r4,[sp,#64+4] + eor r9,r9,r8,lsl#18 + ldr r11,[sp,#56+0] @ h.lo + eor r10,r10,r7,lsl#18 + ldr r12,[sp,#56+4] @ h.hi + eor r9,r9,r7,lsr#18 + eor r10,r10,r8,lsr#18 + eor r9,r9,r8,lsl#14 + eor r10,r10,r7,lsl#14 + eor r9,r9,r8,lsr#9 + eor r10,r10,r7,lsr#9 + eor r9,r9,r7,lsl#23 + eor r10,r10,r8,lsl#23 @ Sigma1(e) + adds r3,r3,r9 + ldr r9,[sp,#40+0] @ f.lo + adc r4,r4,r10 @ T += Sigma1(e) + ldr r10,[sp,#40+4] @ f.hi + adds r3,r3,r11 + ldr r11,[sp,#48+0] @ g.lo + adc r4,r4,r12 @ T += h + ldr r12,[sp,#48+4] @ g.hi + + eor r9,r9,r11 + str r7,[sp,#32+0] + eor r10,r10,r12 + str r8,[sp,#32+4] + and r9,r9,r7 + str r5,[sp,#0+0] + and r10,r10,r8 + str r6,[sp,#0+4] + eor r9,r9,r11 + ldr r11,[r14,#LO] @ K[i].lo + eor r10,r10,r12 @ Ch(e,f,g) + ldr r12,[r14,#HI] @ K[i].hi + + adds r3,r3,r9 + ldr r7,[sp,#24+0] @ d.lo + adc r4,r4,r10 @ T += Ch(e,f,g) + ldr r8,[sp,#24+4] @ d.hi + adds r3,r3,r11 + and r9,r11,#0xff + adc r4,r4,r12 @ T += K[i] + adds r7,r7,r3 + ldr r11,[sp,#8+0] @ b.lo + adc r8,r8,r4 @ d += T + teq r9,#23 + + ldr r12,[sp,#16+0] @ c.lo + orreq r14,r14,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov r9,r5,lsr#28 + mov r10,r6,lsr#28 + eor r9,r9,r6,lsl#4 + eor r10,r10,r5,lsl#4 + eor r9,r9,r6,lsr#2 + eor r10,r10,r5,lsr#2 + eor r9,r9,r5,lsl#30 + eor r10,r10,r6,lsl#30 + eor r9,r9,r6,lsr#7 + eor r10,r10,r5,lsr#7 + eor r9,r9,r5,lsl#25 + eor r10,r10,r6,lsl#25 @ Sigma0(a) + adds r3,r3,r9 + and r9,r5,r11 + adc r4,r4,r10 @ T += Sigma0(a) + + ldr r10,[sp,#8+4] @ b.hi + orr r5,r5,r11 + ldr r11,[sp,#16+4] @ c.hi + and r5,r5,r12 + and r12,r6,r10 + orr r6,r6,r10 + orr r5,r5,r9 @ Maj(a,b,c).lo + and r6,r6,r11 + adds r5,r5,r3 + orr r6,r6,r12 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc r6,r6,r4 @ h += T + tst r14,#1 + add r14,r14,#8 + ldreq r9,[sp,#184+0] + ldreq r10,[sp,#184+4] + beq .L16_79 + bic r14,r14,#1 + + ldr r3,[sp,#8+0] + ldr r4,[sp,#8+4] + ldr r9, [r0,#0+LO] + ldr r10, [r0,#0+HI] + ldr r11, [r0,#8+LO] + ldr r12, [r0,#8+HI] + adds r9,r5,r9 + str r9, [r0,#0+LO] + adc r10,r6,r10 + str r10, [r0,#0+HI] + adds r11,r3,r11 + str r11, [r0,#8+LO] + adc r12,r4,r12 + str r12, [r0,#8+HI] + + ldr r5,[sp,#16+0] + ldr r6,[sp,#16+4] + ldr r3,[sp,#24+0] + ldr r4,[sp,#24+4] + ldr r9, [r0,#16+LO] + ldr r10, [r0,#16+HI] + ldr r11, [r0,#24+LO] + ldr r12, [r0,#24+HI] + adds r9,r5,r9 + str r9, [r0,#16+LO] + adc r10,r6,r10 + str r10, [r0,#16+HI] + adds r11,r3,r11 + str r11, [r0,#24+LO] + adc r12,r4,r12 + str r12, [r0,#24+HI] + + ldr r3,[sp,#40+0] + ldr r4,[sp,#40+4] + ldr r9, [r0,#32+LO] + ldr r10, [r0,#32+HI] + ldr r11, [r0,#40+LO] + ldr r12, [r0,#40+HI] + adds r7,r7,r9 + str r7,[r0,#32+LO] + adc r8,r8,r10 + str r8,[r0,#32+HI] + adds r11,r3,r11 + str r11, [r0,#40+LO] + adc r12,r4,r12 + str r12, [r0,#40+HI] + + ldr r5,[sp,#48+0] + ldr r6,[sp,#48+4] + ldr r3,[sp,#56+0] + ldr r4,[sp,#56+4] + ldr r9, [r0,#48+LO] + ldr r10, [r0,#48+HI] + ldr r11, [r0,#56+LO] + ldr r12, [r0,#56+HI] + adds r9,r5,r9 + str r9, [r0,#48+LO] + adc r10,r6,r10 + str r10, [r0,#48+HI] + adds r11,r3,r11 + str r11, [r0,#56+LO] + adc r12,r4,r12 + str r12, [r0,#56+HI] + + add sp,sp,#640 + sub r14,r14,#640 + + teq r1,r2 + bne .Loop + + add sp,sp,#8*9 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + .word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +#if __ARM_ARCH__>=7 && !defined(__STRICT_ALIGNMENT) +.fpu neon + +.align 4 +.LNEON: + dmb @ errata #451034 on early Cortex A8 + vstmdb sp!,{d8-d15} @ ABI specification says so + sub r3,r3,#672 @ K512 + vldmia r0,{d16-d23} @ load context +.Loop_neon: + vshr.u64 d24,d20,#14 @ 0 +#if 0<16 + vld1.64 {d0},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d20,#18 + vshr.u64 d26,d20,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vsli.64 d26,d20,#23 +#if 0<16 && defined(__ARMEL__) + vrev64.8 d0,d0 +#endif + vadd.i64 d27,d28,d23 + veor d29,d21,d22 + veor d24,d25 + vand d29,d20 + veor d24,d26 @ Sigma1(e) + veor d29,d22 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d16,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d16,#34 + vshr.u64 d26,d16,#39 + vsli.64 d24,d16,#36 + vsli.64 d25,d16,#30 + vsli.64 d26,d16,#25 + vadd.i64 d27,d0 + vorr d30,d16,d18 + vand d29,d16,d18 + veor d23,d24,d25 + vand d30,d17 + veor d23,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d23,d27 + vadd.i64 d19,d27 + vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 1 +#if 1<16 + vld1.64 {d1},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vsli.64 d26,d19,#23 +#if 1<16 && defined(__ARMEL__) + vrev64.8 d1,d1 +#endif + vadd.i64 d27,d28,d22 + veor d29,d20,d21 + veor d24,d25 + vand d29,d19 + veor d24,d26 @ Sigma1(e) + veor d29,d21 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d23,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d23,#34 + vshr.u64 d26,d23,#39 + vsli.64 d24,d23,#36 + vsli.64 d25,d23,#30 + vsli.64 d26,d23,#25 + vadd.i64 d27,d1 + vorr d30,d23,d17 + vand d29,d23,d17 + veor d22,d24,d25 + vand d30,d16 + veor d22,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d22,d27 + vadd.i64 d18,d27 + vadd.i64 d22,d30 + vshr.u64 d24,d18,#14 @ 2 +#if 2<16 + vld1.64 {d2},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d18,#18 + vshr.u64 d26,d18,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vsli.64 d26,d18,#23 +#if 2<16 && defined(__ARMEL__) + vrev64.8 d2,d2 +#endif + vadd.i64 d27,d28,d21 + veor d29,d19,d20 + veor d24,d25 + vand d29,d18 + veor d24,d26 @ Sigma1(e) + veor d29,d20 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d22,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d22,#34 + vshr.u64 d26,d22,#39 + vsli.64 d24,d22,#36 + vsli.64 d25,d22,#30 + vsli.64 d26,d22,#25 + vadd.i64 d27,d2 + vorr d30,d22,d16 + vand d29,d22,d16 + veor d21,d24,d25 + vand d30,d23 + veor d21,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d21,d27 + vadd.i64 d17,d27 + vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 3 +#if 3<16 + vld1.64 {d3},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vsli.64 d26,d17,#23 +#if 3<16 && defined(__ARMEL__) + vrev64.8 d3,d3 +#endif + vadd.i64 d27,d28,d20 + veor d29,d18,d19 + veor d24,d25 + vand d29,d17 + veor d24,d26 @ Sigma1(e) + veor d29,d19 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d21,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d21,#34 + vshr.u64 d26,d21,#39 + vsli.64 d24,d21,#36 + vsli.64 d25,d21,#30 + vsli.64 d26,d21,#25 + vadd.i64 d27,d3 + vorr d30,d21,d23 + vand d29,d21,d23 + veor d20,d24,d25 + vand d30,d22 + veor d20,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d20,d27 + vadd.i64 d16,d27 + vadd.i64 d20,d30 + vshr.u64 d24,d16,#14 @ 4 +#if 4<16 + vld1.64 {d4},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d16,#18 + vshr.u64 d26,d16,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vsli.64 d26,d16,#23 +#if 4<16 && defined(__ARMEL__) + vrev64.8 d4,d4 +#endif + vadd.i64 d27,d28,d19 + veor d29,d17,d18 + veor d24,d25 + vand d29,d16 + veor d24,d26 @ Sigma1(e) + veor d29,d18 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d20,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d20,#34 + vshr.u64 d26,d20,#39 + vsli.64 d24,d20,#36 + vsli.64 d25,d20,#30 + vsli.64 d26,d20,#25 + vadd.i64 d27,d4 + vorr d30,d20,d22 + vand d29,d20,d22 + veor d19,d24,d25 + vand d30,d21 + veor d19,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d19,d27 + vadd.i64 d23,d27 + vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 5 +#if 5<16 + vld1.64 {d5},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vsli.64 d26,d23,#23 +#if 5<16 && defined(__ARMEL__) + vrev64.8 d5,d5 +#endif + vadd.i64 d27,d28,d18 + veor d29,d16,d17 + veor d24,d25 + vand d29,d23 + veor d24,d26 @ Sigma1(e) + veor d29,d17 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d19,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d19,#34 + vshr.u64 d26,d19,#39 + vsli.64 d24,d19,#36 + vsli.64 d25,d19,#30 + vsli.64 d26,d19,#25 + vadd.i64 d27,d5 + vorr d30,d19,d21 + vand d29,d19,d21 + veor d18,d24,d25 + vand d30,d20 + veor d18,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d18,d27 + vadd.i64 d22,d27 + vadd.i64 d18,d30 + vshr.u64 d24,d22,#14 @ 6 +#if 6<16 + vld1.64 {d6},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d22,#18 + vshr.u64 d26,d22,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vsli.64 d26,d22,#23 +#if 6<16 && defined(__ARMEL__) + vrev64.8 d6,d6 +#endif + vadd.i64 d27,d28,d17 + veor d29,d23,d16 + veor d24,d25 + vand d29,d22 + veor d24,d26 @ Sigma1(e) + veor d29,d16 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d18,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d18,#34 + vshr.u64 d26,d18,#39 + vsli.64 d24,d18,#36 + vsli.64 d25,d18,#30 + vsli.64 d26,d18,#25 + vadd.i64 d27,d6 + vorr d30,d18,d20 + vand d29,d18,d20 + veor d17,d24,d25 + vand d30,d19 + veor d17,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d17,d27 + vadd.i64 d21,d27 + vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 7 +#if 7<16 + vld1.64 {d7},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vsli.64 d26,d21,#23 +#if 7<16 && defined(__ARMEL__) + vrev64.8 d7,d7 +#endif + vadd.i64 d27,d28,d16 + veor d29,d22,d23 + veor d24,d25 + vand d29,d21 + veor d24,d26 @ Sigma1(e) + veor d29,d23 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d17,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d17,#34 + vshr.u64 d26,d17,#39 + vsli.64 d24,d17,#36 + vsli.64 d25,d17,#30 + vsli.64 d26,d17,#25 + vadd.i64 d27,d7 + vorr d30,d17,d19 + vand d29,d17,d19 + veor d16,d24,d25 + vand d30,d18 + veor d16,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d16,d27 + vadd.i64 d20,d27 + vadd.i64 d16,d30 + vshr.u64 d24,d20,#14 @ 8 +#if 8<16 + vld1.64 {d8},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d20,#18 + vshr.u64 d26,d20,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vsli.64 d26,d20,#23 +#if 8<16 && defined(__ARMEL__) + vrev64.8 d8,d8 +#endif + vadd.i64 d27,d28,d23 + veor d29,d21,d22 + veor d24,d25 + vand d29,d20 + veor d24,d26 @ Sigma1(e) + veor d29,d22 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d16,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d16,#34 + vshr.u64 d26,d16,#39 + vsli.64 d24,d16,#36 + vsli.64 d25,d16,#30 + vsli.64 d26,d16,#25 + vadd.i64 d27,d8 + vorr d30,d16,d18 + vand d29,d16,d18 + veor d23,d24,d25 + vand d30,d17 + veor d23,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d23,d27 + vadd.i64 d19,d27 + vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 9 +#if 9<16 + vld1.64 {d9},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vsli.64 d26,d19,#23 +#if 9<16 && defined(__ARMEL__) + vrev64.8 d9,d9 +#endif + vadd.i64 d27,d28,d22 + veor d29,d20,d21 + veor d24,d25 + vand d29,d19 + veor d24,d26 @ Sigma1(e) + veor d29,d21 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d23,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d23,#34 + vshr.u64 d26,d23,#39 + vsli.64 d24,d23,#36 + vsli.64 d25,d23,#30 + vsli.64 d26,d23,#25 + vadd.i64 d27,d9 + vorr d30,d23,d17 + vand d29,d23,d17 + veor d22,d24,d25 + vand d30,d16 + veor d22,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d22,d27 + vadd.i64 d18,d27 + vadd.i64 d22,d30 + vshr.u64 d24,d18,#14 @ 10 +#if 10<16 + vld1.64 {d10},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d18,#18 + vshr.u64 d26,d18,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vsli.64 d26,d18,#23 +#if 10<16 && defined(__ARMEL__) + vrev64.8 d10,d10 +#endif + vadd.i64 d27,d28,d21 + veor d29,d19,d20 + veor d24,d25 + vand d29,d18 + veor d24,d26 @ Sigma1(e) + veor d29,d20 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d22,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d22,#34 + vshr.u64 d26,d22,#39 + vsli.64 d24,d22,#36 + vsli.64 d25,d22,#30 + vsli.64 d26,d22,#25 + vadd.i64 d27,d10 + vorr d30,d22,d16 + vand d29,d22,d16 + veor d21,d24,d25 + vand d30,d23 + veor d21,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d21,d27 + vadd.i64 d17,d27 + vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 11 +#if 11<16 + vld1.64 {d11},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vsli.64 d26,d17,#23 +#if 11<16 && defined(__ARMEL__) + vrev64.8 d11,d11 +#endif + vadd.i64 d27,d28,d20 + veor d29,d18,d19 + veor d24,d25 + vand d29,d17 + veor d24,d26 @ Sigma1(e) + veor d29,d19 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d21,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d21,#34 + vshr.u64 d26,d21,#39 + vsli.64 d24,d21,#36 + vsli.64 d25,d21,#30 + vsli.64 d26,d21,#25 + vadd.i64 d27,d11 + vorr d30,d21,d23 + vand d29,d21,d23 + veor d20,d24,d25 + vand d30,d22 + veor d20,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d20,d27 + vadd.i64 d16,d27 + vadd.i64 d20,d30 + vshr.u64 d24,d16,#14 @ 12 +#if 12<16 + vld1.64 {d12},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d16,#18 + vshr.u64 d26,d16,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vsli.64 d26,d16,#23 +#if 12<16 && defined(__ARMEL__) + vrev64.8 d12,d12 +#endif + vadd.i64 d27,d28,d19 + veor d29,d17,d18 + veor d24,d25 + vand d29,d16 + veor d24,d26 @ Sigma1(e) + veor d29,d18 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d20,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d20,#34 + vshr.u64 d26,d20,#39 + vsli.64 d24,d20,#36 + vsli.64 d25,d20,#30 + vsli.64 d26,d20,#25 + vadd.i64 d27,d12 + vorr d30,d20,d22 + vand d29,d20,d22 + veor d19,d24,d25 + vand d30,d21 + veor d19,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d19,d27 + vadd.i64 d23,d27 + vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 13 +#if 13<16 + vld1.64 {d13},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vsli.64 d26,d23,#23 +#if 13<16 && defined(__ARMEL__) + vrev64.8 d13,d13 +#endif + vadd.i64 d27,d28,d18 + veor d29,d16,d17 + veor d24,d25 + vand d29,d23 + veor d24,d26 @ Sigma1(e) + veor d29,d17 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d19,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d19,#34 + vshr.u64 d26,d19,#39 + vsli.64 d24,d19,#36 + vsli.64 d25,d19,#30 + vsli.64 d26,d19,#25 + vadd.i64 d27,d13 + vorr d30,d19,d21 + vand d29,d19,d21 + veor d18,d24,d25 + vand d30,d20 + veor d18,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d18,d27 + vadd.i64 d22,d27 + vadd.i64 d18,d30 + vshr.u64 d24,d22,#14 @ 14 +#if 14<16 + vld1.64 {d14},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d22,#18 + vshr.u64 d26,d22,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vsli.64 d26,d22,#23 +#if 14<16 && defined(__ARMEL__) + vrev64.8 d14,d14 +#endif + vadd.i64 d27,d28,d17 + veor d29,d23,d16 + veor d24,d25 + vand d29,d22 + veor d24,d26 @ Sigma1(e) + veor d29,d16 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d18,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d18,#34 + vshr.u64 d26,d18,#39 + vsli.64 d24,d18,#36 + vsli.64 d25,d18,#30 + vsli.64 d26,d18,#25 + vadd.i64 d27,d14 + vorr d30,d18,d20 + vand d29,d18,d20 + veor d17,d24,d25 + vand d30,d19 + veor d17,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d17,d27 + vadd.i64 d21,d27 + vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 15 +#if 15<16 + vld1.64 {d15},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vsli.64 d26,d21,#23 +#if 15<16 && defined(__ARMEL__) + vrev64.8 d15,d15 +#endif + vadd.i64 d27,d28,d16 + veor d29,d22,d23 + veor d24,d25 + vand d29,d21 + veor d24,d26 @ Sigma1(e) + veor d29,d23 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d17,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d17,#34 + vshr.u64 d26,d17,#39 + vsli.64 d24,d17,#36 + vsli.64 d25,d17,#30 + vsli.64 d26,d17,#25 + vadd.i64 d27,d15 + vorr d30,d17,d19 + vand d29,d17,d19 + veor d16,d24,d25 + vand d30,d18 + veor d16,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d16,d27 + vadd.i64 d20,d27 + vadd.i64 d16,d30 + mov r12,#4 +.L16_79_neon: + subs r12,#1 + vshr.u64 q12,q7,#19 + vshr.u64 q13,q7,#61 + vshr.u64 q15,q7,#6 + vsli.64 q12,q7,#45 + vext.8 q14,q0,q1,#8 @ X[i+1] + vsli.64 q13,q7,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q0,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q4,q5,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d20,#14 @ from NEON_00_15 + vadd.i64 q0,q14 + vshr.u64 d25,d20,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d20,#41 @ from NEON_00_15 + vadd.i64 q0,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vsli.64 d26,d20,#23 +#if 16<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d23 + veor d29,d21,d22 + veor d24,d25 + vand d29,d20 + veor d24,d26 @ Sigma1(e) + veor d29,d22 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d16,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d16,#34 + vshr.u64 d26,d16,#39 + vsli.64 d24,d16,#36 + vsli.64 d25,d16,#30 + vsli.64 d26,d16,#25 + vadd.i64 d27,d0 + vorr d30,d16,d18 + vand d29,d16,d18 + veor d23,d24,d25 + vand d30,d17 + veor d23,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d23,d27 + vadd.i64 d19,d27 + vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 17 +#if 17<16 + vld1.64 {d1},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vsli.64 d26,d19,#23 +#if 17<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d22 + veor d29,d20,d21 + veor d24,d25 + vand d29,d19 + veor d24,d26 @ Sigma1(e) + veor d29,d21 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d23,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d23,#34 + vshr.u64 d26,d23,#39 + vsli.64 d24,d23,#36 + vsli.64 d25,d23,#30 + vsli.64 d26,d23,#25 + vadd.i64 d27,d1 + vorr d30,d23,d17 + vand d29,d23,d17 + veor d22,d24,d25 + vand d30,d16 + veor d22,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d22,d27 + vadd.i64 d18,d27 + vadd.i64 d22,d30 + vshr.u64 q12,q0,#19 + vshr.u64 q13,q0,#61 + vshr.u64 q15,q0,#6 + vsli.64 q12,q0,#45 + vext.8 q14,q1,q2,#8 @ X[i+1] + vsli.64 q13,q0,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q1,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q5,q6,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d18,#14 @ from NEON_00_15 + vadd.i64 q1,q14 + vshr.u64 d25,d18,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d18,#41 @ from NEON_00_15 + vadd.i64 q1,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vsli.64 d26,d18,#23 +#if 18<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d21 + veor d29,d19,d20 + veor d24,d25 + vand d29,d18 + veor d24,d26 @ Sigma1(e) + veor d29,d20 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d22,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d22,#34 + vshr.u64 d26,d22,#39 + vsli.64 d24,d22,#36 + vsli.64 d25,d22,#30 + vsli.64 d26,d22,#25 + vadd.i64 d27,d2 + vorr d30,d22,d16 + vand d29,d22,d16 + veor d21,d24,d25 + vand d30,d23 + veor d21,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d21,d27 + vadd.i64 d17,d27 + vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 19 +#if 19<16 + vld1.64 {d3},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vsli.64 d26,d17,#23 +#if 19<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d20 + veor d29,d18,d19 + veor d24,d25 + vand d29,d17 + veor d24,d26 @ Sigma1(e) + veor d29,d19 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d21,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d21,#34 + vshr.u64 d26,d21,#39 + vsli.64 d24,d21,#36 + vsli.64 d25,d21,#30 + vsli.64 d26,d21,#25 + vadd.i64 d27,d3 + vorr d30,d21,d23 + vand d29,d21,d23 + veor d20,d24,d25 + vand d30,d22 + veor d20,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d20,d27 + vadd.i64 d16,d27 + vadd.i64 d20,d30 + vshr.u64 q12,q1,#19 + vshr.u64 q13,q1,#61 + vshr.u64 q15,q1,#6 + vsli.64 q12,q1,#45 + vext.8 q14,q2,q3,#8 @ X[i+1] + vsli.64 q13,q1,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q2,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q6,q7,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d16,#14 @ from NEON_00_15 + vadd.i64 q2,q14 + vshr.u64 d25,d16,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d16,#41 @ from NEON_00_15 + vadd.i64 q2,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vsli.64 d26,d16,#23 +#if 20<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d19 + veor d29,d17,d18 + veor d24,d25 + vand d29,d16 + veor d24,d26 @ Sigma1(e) + veor d29,d18 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d20,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d20,#34 + vshr.u64 d26,d20,#39 + vsli.64 d24,d20,#36 + vsli.64 d25,d20,#30 + vsli.64 d26,d20,#25 + vadd.i64 d27,d4 + vorr d30,d20,d22 + vand d29,d20,d22 + veor d19,d24,d25 + vand d30,d21 + veor d19,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d19,d27 + vadd.i64 d23,d27 + vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 21 +#if 21<16 + vld1.64 {d5},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vsli.64 d26,d23,#23 +#if 21<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d18 + veor d29,d16,d17 + veor d24,d25 + vand d29,d23 + veor d24,d26 @ Sigma1(e) + veor d29,d17 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d19,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d19,#34 + vshr.u64 d26,d19,#39 + vsli.64 d24,d19,#36 + vsli.64 d25,d19,#30 + vsli.64 d26,d19,#25 + vadd.i64 d27,d5 + vorr d30,d19,d21 + vand d29,d19,d21 + veor d18,d24,d25 + vand d30,d20 + veor d18,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d18,d27 + vadd.i64 d22,d27 + vadd.i64 d18,d30 + vshr.u64 q12,q2,#19 + vshr.u64 q13,q2,#61 + vshr.u64 q15,q2,#6 + vsli.64 q12,q2,#45 + vext.8 q14,q3,q4,#8 @ X[i+1] + vsli.64 q13,q2,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q3,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q7,q0,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d22,#14 @ from NEON_00_15 + vadd.i64 q3,q14 + vshr.u64 d25,d22,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d22,#41 @ from NEON_00_15 + vadd.i64 q3,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vsli.64 d26,d22,#23 +#if 22<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d17 + veor d29,d23,d16 + veor d24,d25 + vand d29,d22 + veor d24,d26 @ Sigma1(e) + veor d29,d16 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d18,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d18,#34 + vshr.u64 d26,d18,#39 + vsli.64 d24,d18,#36 + vsli.64 d25,d18,#30 + vsli.64 d26,d18,#25 + vadd.i64 d27,d6 + vorr d30,d18,d20 + vand d29,d18,d20 + veor d17,d24,d25 + vand d30,d19 + veor d17,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d17,d27 + vadd.i64 d21,d27 + vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 23 +#if 23<16 + vld1.64 {d7},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vsli.64 d26,d21,#23 +#if 23<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d16 + veor d29,d22,d23 + veor d24,d25 + vand d29,d21 + veor d24,d26 @ Sigma1(e) + veor d29,d23 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d17,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d17,#34 + vshr.u64 d26,d17,#39 + vsli.64 d24,d17,#36 + vsli.64 d25,d17,#30 + vsli.64 d26,d17,#25 + vadd.i64 d27,d7 + vorr d30,d17,d19 + vand d29,d17,d19 + veor d16,d24,d25 + vand d30,d18 + veor d16,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d16,d27 + vadd.i64 d20,d27 + vadd.i64 d16,d30 + vshr.u64 q12,q3,#19 + vshr.u64 q13,q3,#61 + vshr.u64 q15,q3,#6 + vsli.64 q12,q3,#45 + vext.8 q14,q4,q5,#8 @ X[i+1] + vsli.64 q13,q3,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q4,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q0,q1,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d20,#14 @ from NEON_00_15 + vadd.i64 q4,q14 + vshr.u64 d25,d20,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d20,#41 @ from NEON_00_15 + vadd.i64 q4,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vsli.64 d26,d20,#23 +#if 24<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d23 + veor d29,d21,d22 + veor d24,d25 + vand d29,d20 + veor d24,d26 @ Sigma1(e) + veor d29,d22 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d16,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d16,#34 + vshr.u64 d26,d16,#39 + vsli.64 d24,d16,#36 + vsli.64 d25,d16,#30 + vsli.64 d26,d16,#25 + vadd.i64 d27,d8 + vorr d30,d16,d18 + vand d29,d16,d18 + veor d23,d24,d25 + vand d30,d17 + veor d23,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d23,d27 + vadd.i64 d19,d27 + vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 25 +#if 25<16 + vld1.64 {d9},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vsli.64 d26,d19,#23 +#if 25<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d22 + veor d29,d20,d21 + veor d24,d25 + vand d29,d19 + veor d24,d26 @ Sigma1(e) + veor d29,d21 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d23,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d23,#34 + vshr.u64 d26,d23,#39 + vsli.64 d24,d23,#36 + vsli.64 d25,d23,#30 + vsli.64 d26,d23,#25 + vadd.i64 d27,d9 + vorr d30,d23,d17 + vand d29,d23,d17 + veor d22,d24,d25 + vand d30,d16 + veor d22,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d22,d27 + vadd.i64 d18,d27 + vadd.i64 d22,d30 + vshr.u64 q12,q4,#19 + vshr.u64 q13,q4,#61 + vshr.u64 q15,q4,#6 + vsli.64 q12,q4,#45 + vext.8 q14,q5,q6,#8 @ X[i+1] + vsli.64 q13,q4,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q5,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q1,q2,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d18,#14 @ from NEON_00_15 + vadd.i64 q5,q14 + vshr.u64 d25,d18,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d18,#41 @ from NEON_00_15 + vadd.i64 q5,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vsli.64 d26,d18,#23 +#if 26<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d21 + veor d29,d19,d20 + veor d24,d25 + vand d29,d18 + veor d24,d26 @ Sigma1(e) + veor d29,d20 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d22,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d22,#34 + vshr.u64 d26,d22,#39 + vsli.64 d24,d22,#36 + vsli.64 d25,d22,#30 + vsli.64 d26,d22,#25 + vadd.i64 d27,d10 + vorr d30,d22,d16 + vand d29,d22,d16 + veor d21,d24,d25 + vand d30,d23 + veor d21,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d21,d27 + vadd.i64 d17,d27 + vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 27 +#if 27<16 + vld1.64 {d11},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vsli.64 d26,d17,#23 +#if 27<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d20 + veor d29,d18,d19 + veor d24,d25 + vand d29,d17 + veor d24,d26 @ Sigma1(e) + veor d29,d19 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d21,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d21,#34 + vshr.u64 d26,d21,#39 + vsli.64 d24,d21,#36 + vsli.64 d25,d21,#30 + vsli.64 d26,d21,#25 + vadd.i64 d27,d11 + vorr d30,d21,d23 + vand d29,d21,d23 + veor d20,d24,d25 + vand d30,d22 + veor d20,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d20,d27 + vadd.i64 d16,d27 + vadd.i64 d20,d30 + vshr.u64 q12,q5,#19 + vshr.u64 q13,q5,#61 + vshr.u64 q15,q5,#6 + vsli.64 q12,q5,#45 + vext.8 q14,q6,q7,#8 @ X[i+1] + vsli.64 q13,q5,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q6,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q2,q3,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d16,#14 @ from NEON_00_15 + vadd.i64 q6,q14 + vshr.u64 d25,d16,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d16,#41 @ from NEON_00_15 + vadd.i64 q6,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vsli.64 d26,d16,#23 +#if 28<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d19 + veor d29,d17,d18 + veor d24,d25 + vand d29,d16 + veor d24,d26 @ Sigma1(e) + veor d29,d18 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d20,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d20,#34 + vshr.u64 d26,d20,#39 + vsli.64 d24,d20,#36 + vsli.64 d25,d20,#30 + vsli.64 d26,d20,#25 + vadd.i64 d27,d12 + vorr d30,d20,d22 + vand d29,d20,d22 + veor d19,d24,d25 + vand d30,d21 + veor d19,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d19,d27 + vadd.i64 d23,d27 + vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 29 +#if 29<16 + vld1.64 {d13},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vsli.64 d26,d23,#23 +#if 29<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d18 + veor d29,d16,d17 + veor d24,d25 + vand d29,d23 + veor d24,d26 @ Sigma1(e) + veor d29,d17 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d19,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d19,#34 + vshr.u64 d26,d19,#39 + vsli.64 d24,d19,#36 + vsli.64 d25,d19,#30 + vsli.64 d26,d19,#25 + vadd.i64 d27,d13 + vorr d30,d19,d21 + vand d29,d19,d21 + veor d18,d24,d25 + vand d30,d20 + veor d18,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d18,d27 + vadd.i64 d22,d27 + vadd.i64 d18,d30 + vshr.u64 q12,q6,#19 + vshr.u64 q13,q6,#61 + vshr.u64 q15,q6,#6 + vsli.64 q12,q6,#45 + vext.8 q14,q7,q0,#8 @ X[i+1] + vsli.64 q13,q6,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q7,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q3,q4,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d22,#14 @ from NEON_00_15 + vadd.i64 q7,q14 + vshr.u64 d25,d22,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d22,#41 @ from NEON_00_15 + vadd.i64 q7,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vsli.64 d26,d22,#23 +#if 30<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d17 + veor d29,d23,d16 + veor d24,d25 + vand d29,d22 + veor d24,d26 @ Sigma1(e) + veor d29,d16 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d18,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d18,#34 + vshr.u64 d26,d18,#39 + vsli.64 d24,d18,#36 + vsli.64 d25,d18,#30 + vsli.64 d26,d18,#25 + vadd.i64 d27,d14 + vorr d30,d18,d20 + vand d29,d18,d20 + veor d17,d24,d25 + vand d30,d19 + veor d17,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d17,d27 + vadd.i64 d21,d27 + vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 31 +#if 31<16 + vld1.64 {d15},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vsli.64 d26,d21,#23 +#if 31<16 && defined(__ARMEL__) + vrev64.8 , +#endif + vadd.i64 d27,d28,d16 + veor d29,d22,d23 + veor d24,d25 + vand d29,d21 + veor d24,d26 @ Sigma1(e) + veor d29,d23 @ Ch(e,f,g) + vadd.i64 d27,d24 + vshr.u64 d24,d17,#28 + vadd.i64 d27,d29 + vshr.u64 d25,d17,#34 + vshr.u64 d26,d17,#39 + vsli.64 d24,d17,#36 + vsli.64 d25,d17,#30 + vsli.64 d26,d17,#25 + vadd.i64 d27,d15 + vorr d30,d17,d19 + vand d29,d17,d19 + veor d16,d24,d25 + vand d30,d18 + veor d16,d26 @ Sigma0(a) + vorr d30,d29 @ Maj(a,b,c) + vadd.i64 d16,d27 + vadd.i64 d20,d27 + vadd.i64 d16,d30 + bne .L16_79_neon + + vldmia r0,{d24-d31} @ load context to temp + vadd.i64 q8,q12 @ vectorized accumulate + vadd.i64 q9,q13 + vadd.i64 q10,q14 + vadd.i64 q11,q15 + vstmia r0,{d16-d23} @ save context + teq r1,r2 + sub r3,#640 @ rewind K512 + bne .Loop_neon + + vldmia sp!,{d8-d15} @ epilogue + .word 0xe12fff1e +#endif +.size sha512_block_data_order,.-sha512_block_data_order +.asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by " +.align 2 +.comm OPENSSL_armcap_P,4,4 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha512-elf-x86_64.S b/Libraries/libressl/crypto/sha/sha512-elf-x86_64.S new file mode 100644 index 000000000..0581c7c98 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512-elf-x86_64.S @@ -0,0 +1,1809 @@ +#include "x86_arch.h" +.text + +.globl sha512_block_data_order +.type sha512_block_data_order,@function +.align 16 +sha512_block_data_order: + endbr64 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $128+32,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +.Lprologue: + + leaq K512(%rip),%rbp + + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop + +.align 16 +.Lloop: + xorq %rdi,%rdi + movq 0(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,0(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 8(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,8(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 16(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,16(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 24(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,24(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 32(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,32(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 40(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,40(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 48(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,48(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 56(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,56(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + movq 64(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,64(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 72(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,72(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 80(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,80(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 88(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,88(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 96(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,96(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 104(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,104(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 112(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,112(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 120(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,120(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: + movq 8(%rsp),%r13 + movq 112(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 72(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 0(%rsp),%r12 + movq %r8,%r13 + addq %r14,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,0(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 16(%rsp),%r13 + movq 120(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 80(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 8(%rsp),%r12 + movq %rdx,%r13 + addq %r14,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,8(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 24(%rsp),%r13 + movq 0(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 88(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 16(%rsp),%r12 + movq %rcx,%r13 + addq %r14,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,16(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 32(%rsp),%r13 + movq 8(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 96(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 24(%rsp),%r12 + movq %rbx,%r13 + addq %r14,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,24(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 40(%rsp),%r13 + movq 16(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 104(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 32(%rsp),%r12 + movq %rax,%r13 + addq %r14,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,32(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 48(%rsp),%r13 + movq 24(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 112(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 40(%rsp),%r12 + movq %r11,%r13 + addq %r14,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,40(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 56(%rsp),%r13 + movq 32(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 120(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 48(%rsp),%r12 + movq %r10,%r13 + addq %r14,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,48(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 64(%rsp),%r13 + movq 40(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 0(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 56(%rsp),%r12 + movq %r9,%r13 + addq %r14,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,56(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + movq 72(%rsp),%r13 + movq 48(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 8(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 64(%rsp),%r12 + movq %r8,%r13 + addq %r14,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,64(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 80(%rsp),%r13 + movq 56(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 16(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 72(%rsp),%r12 + movq %rdx,%r13 + addq %r14,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,72(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 88(%rsp),%r13 + movq 64(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 24(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 80(%rsp),%r12 + movq %rcx,%r13 + addq %r14,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,80(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 96(%rsp),%r13 + movq 72(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 32(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 88(%rsp),%r12 + movq %rbx,%r13 + addq %r14,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,88(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 104(%rsp),%r13 + movq 80(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 40(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 96(%rsp),%r12 + movq %rax,%r13 + addq %r14,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,96(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 112(%rsp),%r13 + movq 88(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 48(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 104(%rsp),%r12 + movq %r11,%r13 + addq %r14,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,104(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 120(%rsp),%r13 + movq 96(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 56(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 112(%rsp),%r12 + movq %r10,%r13 + addq %r14,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,112(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 0(%rsp),%r13 + movq 104(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 64(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 120(%rsp),%r12 + movq %r9,%r13 + addq %r14,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,120(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + cmpq $80,%rdi + jb .Lrounds_16_xx + + movq 128+0(%rsp),%rdi + leaq 128(%rsi),%rsi + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop + + movq 128+24(%rsp),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue: + retq +.size sha512_block_data_order,.-sha512_block_data_order +.section .rodata +.align 64 +.type K512,@object +K512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.text +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha512-macosx-x86_64.S b/Libraries/libressl/crypto/sha/sha512-macosx-x86_64.S new file mode 100644 index 000000000..7581da47c --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512-macosx-x86_64.S @@ -0,0 +1,1803 @@ +#include "x86_arch.h" +.text + +.globl _sha512_block_data_order + +.p2align 4 +_sha512_block_data_order: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $128+32,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +L$prologue: + + leaq K512(%rip),%rbp + + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp L$loop + +.p2align 4 +L$loop: + xorq %rdi,%rdi + movq 0(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,0(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 8(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,8(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 16(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,16(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 24(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,24(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 32(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,32(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 40(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,40(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 48(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,48(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 56(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,56(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + movq 64(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,64(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 72(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,72(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 80(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,80(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 88(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,88(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 96(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,96(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 104(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,104(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 112(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,112(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 120(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,120(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + jmp L$rounds_16_xx +.p2align 4 +L$rounds_16_xx: + movq 8(%rsp),%r13 + movq 112(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 72(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 0(%rsp),%r12 + movq %r8,%r13 + addq %r14,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,0(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 16(%rsp),%r13 + movq 120(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 80(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 8(%rsp),%r12 + movq %rdx,%r13 + addq %r14,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,8(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 24(%rsp),%r13 + movq 0(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 88(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 16(%rsp),%r12 + movq %rcx,%r13 + addq %r14,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,16(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 32(%rsp),%r13 + movq 8(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 96(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 24(%rsp),%r12 + movq %rbx,%r13 + addq %r14,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,24(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 40(%rsp),%r13 + movq 16(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 104(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 32(%rsp),%r12 + movq %rax,%r13 + addq %r14,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,32(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 48(%rsp),%r13 + movq 24(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 112(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 40(%rsp),%r12 + movq %r11,%r13 + addq %r14,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,40(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 56(%rsp),%r13 + movq 32(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 120(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 48(%rsp),%r12 + movq %r10,%r13 + addq %r14,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,48(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 64(%rsp),%r13 + movq 40(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 0(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 56(%rsp),%r12 + movq %r9,%r13 + addq %r14,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,56(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + movq 72(%rsp),%r13 + movq 48(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 8(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 64(%rsp),%r12 + movq %r8,%r13 + addq %r14,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,64(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 80(%rsp),%r13 + movq 56(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 16(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 72(%rsp),%r12 + movq %rdx,%r13 + addq %r14,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,72(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 88(%rsp),%r13 + movq 64(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 24(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 80(%rsp),%r12 + movq %rcx,%r13 + addq %r14,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,80(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 96(%rsp),%r13 + movq 72(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 32(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 88(%rsp),%r12 + movq %rbx,%r13 + addq %r14,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,88(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 104(%rsp),%r13 + movq 80(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 40(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 96(%rsp),%r12 + movq %rax,%r13 + addq %r14,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,96(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 112(%rsp),%r13 + movq 88(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 48(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 104(%rsp),%r12 + movq %r11,%r13 + addq %r14,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,104(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 120(%rsp),%r13 + movq 96(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 56(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 112(%rsp),%r12 + movq %r10,%r13 + addq %r14,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,112(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 0(%rsp),%r13 + movq 104(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 64(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 120(%rsp),%r12 + movq %r9,%r13 + addq %r14,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,120(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + cmpq $80,%rdi + jb L$rounds_16_xx + + movq 128+0(%rsp),%rdi + leaq 128(%rsi),%rsi + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb L$loop + + movq 128+24(%rsp),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$epilogue: + retq + +.p2align 6 + +K512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 diff --git a/Libraries/libressl/crypto/sha/sha512-masm-x86_64.S b/Libraries/libressl/crypto/sha/sha512-masm-x86_64.S new file mode 100644 index 000000000..e964d9c83 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512-masm-x86_64.S @@ -0,0 +1,1888 @@ +; 1 "crypto/sha/sha512-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/sha/sha512-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/sha/sha512-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC sha512_block_data_order + +ALIGN 16 +sha512_block_data_order PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha512_block_data_order:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + mov rcx,r9 + + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov r11,rsp + shl rdx,4 + sub rsp,16*8+4*8 + lea rdx,QWORD PTR[rdx*8+rsi] + and rsp,-64 + mov QWORD PTR[((128+0))+rsp],rdi + mov QWORD PTR[((128+8))+rsp],rsi + mov QWORD PTR[((128+16))+rsp],rdx + mov QWORD PTR[((128+24))+rsp],r11 +$L$prologue:: + + lea rbp,QWORD PTR[K512] + + mov rax,QWORD PTR[rdi] + mov rbx,QWORD PTR[8+rdi] + mov rcx,QWORD PTR[16+rdi] + mov rdx,QWORD PTR[24+rdi] + mov r8,QWORD PTR[32+rdi] + mov r9,QWORD PTR[40+rdi] + mov r10,QWORD PTR[48+rdi] + mov r11,QWORD PTR[56+rdi] + jmp $L$loop + +ALIGN 16 +$L$loop:: + xor rdi,rdi + mov r12,QWORD PTR[rsi] + mov r13,r8 + mov r14,rax + bswap r12 + ror r13,23 + mov r15,r9 + mov QWORD PTR[rsp],r12 + + ror r14,5 + xor r13,r8 + xor r15,r10 + + ror r13,4 + add r12,r11 + xor r14,rax + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r8 + mov r11,rbx + + ror r14,6 + xor r13,r8 + xor r15,r10 + + xor r11,rcx + xor r14,rax + add r12,r15 + mov r15,rbx + + ror r13,14 + and r11,rax + and r15,rcx + + ror r14,28 + add r12,r13 + add r11,r15 + + add rdx,r12 + add r11,r12 + lea rdi,QWORD PTR[1+rdi] + add r11,r14 + + mov r12,QWORD PTR[8+rsi] + mov r13,rdx + mov r14,r11 + bswap r12 + ror r13,23 + mov r15,r8 + mov QWORD PTR[8+rsp],r12 + + ror r14,5 + xor r13,rdx + xor r15,r9 + + ror r13,4 + add r12,r10 + xor r14,r11 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rdx + mov r10,rax + + ror r14,6 + xor r13,rdx + xor r15,r9 + + xor r10,rbx + xor r14,r11 + add r12,r15 + mov r15,rax + + ror r13,14 + and r10,r11 + and r15,rbx + + ror r14,28 + add r12,r13 + add r10,r15 + + add rcx,r12 + add r10,r12 + lea rdi,QWORD PTR[1+rdi] + add r10,r14 + + mov r12,QWORD PTR[16+rsi] + mov r13,rcx + mov r14,r10 + bswap r12 + ror r13,23 + mov r15,rdx + mov QWORD PTR[16+rsp],r12 + + ror r14,5 + xor r13,rcx + xor r15,r8 + + ror r13,4 + add r12,r9 + xor r14,r10 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rcx + mov r9,r11 + + ror r14,6 + xor r13,rcx + xor r15,r8 + + xor r9,rax + xor r14,r10 + add r12,r15 + mov r15,r11 + + ror r13,14 + and r9,r10 + and r15,rax + + ror r14,28 + add r12,r13 + add r9,r15 + + add rbx,r12 + add r9,r12 + lea rdi,QWORD PTR[1+rdi] + add r9,r14 + + mov r12,QWORD PTR[24+rsi] + mov r13,rbx + mov r14,r9 + bswap r12 + ror r13,23 + mov r15,rcx + mov QWORD PTR[24+rsp],r12 + + ror r14,5 + xor r13,rbx + xor r15,rdx + + ror r13,4 + add r12,r8 + xor r14,r9 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rbx + mov r8,r10 + + ror r14,6 + xor r13,rbx + xor r15,rdx + + xor r8,r11 + xor r14,r9 + add r12,r15 + mov r15,r10 + + ror r13,14 + and r8,r9 + and r15,r11 + + ror r14,28 + add r12,r13 + add r8,r15 + + add rax,r12 + add r8,r12 + lea rdi,QWORD PTR[1+rdi] + add r8,r14 + + mov r12,QWORD PTR[32+rsi] + mov r13,rax + mov r14,r8 + bswap r12 + ror r13,23 + mov r15,rbx + mov QWORD PTR[32+rsp],r12 + + ror r14,5 + xor r13,rax + xor r15,rcx + + ror r13,4 + add r12,rdx + xor r14,r8 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rax + mov rdx,r9 + + ror r14,6 + xor r13,rax + xor r15,rcx + + xor rdx,r10 + xor r14,r8 + add r12,r15 + mov r15,r9 + + ror r13,14 + and rdx,r8 + and r15,r10 + + ror r14,28 + add r12,r13 + add rdx,r15 + + add r11,r12 + add rdx,r12 + lea rdi,QWORD PTR[1+rdi] + add rdx,r14 + + mov r12,QWORD PTR[40+rsi] + mov r13,r11 + mov r14,rdx + bswap r12 + ror r13,23 + mov r15,rax + mov QWORD PTR[40+rsp],r12 + + ror r14,5 + xor r13,r11 + xor r15,rbx + + ror r13,4 + add r12,rcx + xor r14,rdx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r11 + mov rcx,r8 + + ror r14,6 + xor r13,r11 + xor r15,rbx + + xor rcx,r9 + xor r14,rdx + add r12,r15 + mov r15,r8 + + ror r13,14 + and rcx,rdx + and r15,r9 + + ror r14,28 + add r12,r13 + add rcx,r15 + + add r10,r12 + add rcx,r12 + lea rdi,QWORD PTR[1+rdi] + add rcx,r14 + + mov r12,QWORD PTR[48+rsi] + mov r13,r10 + mov r14,rcx + bswap r12 + ror r13,23 + mov r15,r11 + mov QWORD PTR[48+rsp],r12 + + ror r14,5 + xor r13,r10 + xor r15,rax + + ror r13,4 + add r12,rbx + xor r14,rcx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r10 + mov rbx,rdx + + ror r14,6 + xor r13,r10 + xor r15,rax + + xor rbx,r8 + xor r14,rcx + add r12,r15 + mov r15,rdx + + ror r13,14 + and rbx,rcx + and r15,r8 + + ror r14,28 + add r12,r13 + add rbx,r15 + + add r9,r12 + add rbx,r12 + lea rdi,QWORD PTR[1+rdi] + add rbx,r14 + + mov r12,QWORD PTR[56+rsi] + mov r13,r9 + mov r14,rbx + bswap r12 + ror r13,23 + mov r15,r10 + mov QWORD PTR[56+rsp],r12 + + ror r14,5 + xor r13,r9 + xor r15,r11 + + ror r13,4 + add r12,rax + xor r14,rbx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r9 + mov rax,rcx + + ror r14,6 + xor r13,r9 + xor r15,r11 + + xor rax,rdx + xor r14,rbx + add r12,r15 + mov r15,rcx + + ror r13,14 + and rax,rbx + and r15,rdx + + ror r14,28 + add r12,r13 + add rax,r15 + + add r8,r12 + add rax,r12 + lea rdi,QWORD PTR[1+rdi] + add rax,r14 + + mov r12,QWORD PTR[64+rsi] + mov r13,r8 + mov r14,rax + bswap r12 + ror r13,23 + mov r15,r9 + mov QWORD PTR[64+rsp],r12 + + ror r14,5 + xor r13,r8 + xor r15,r10 + + ror r13,4 + add r12,r11 + xor r14,rax + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r8 + mov r11,rbx + + ror r14,6 + xor r13,r8 + xor r15,r10 + + xor r11,rcx + xor r14,rax + add r12,r15 + mov r15,rbx + + ror r13,14 + and r11,rax + and r15,rcx + + ror r14,28 + add r12,r13 + add r11,r15 + + add rdx,r12 + add r11,r12 + lea rdi,QWORD PTR[1+rdi] + add r11,r14 + + mov r12,QWORD PTR[72+rsi] + mov r13,rdx + mov r14,r11 + bswap r12 + ror r13,23 + mov r15,r8 + mov QWORD PTR[72+rsp],r12 + + ror r14,5 + xor r13,rdx + xor r15,r9 + + ror r13,4 + add r12,r10 + xor r14,r11 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rdx + mov r10,rax + + ror r14,6 + xor r13,rdx + xor r15,r9 + + xor r10,rbx + xor r14,r11 + add r12,r15 + mov r15,rax + + ror r13,14 + and r10,r11 + and r15,rbx + + ror r14,28 + add r12,r13 + add r10,r15 + + add rcx,r12 + add r10,r12 + lea rdi,QWORD PTR[1+rdi] + add r10,r14 + + mov r12,QWORD PTR[80+rsi] + mov r13,rcx + mov r14,r10 + bswap r12 + ror r13,23 + mov r15,rdx + mov QWORD PTR[80+rsp],r12 + + ror r14,5 + xor r13,rcx + xor r15,r8 + + ror r13,4 + add r12,r9 + xor r14,r10 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rcx + mov r9,r11 + + ror r14,6 + xor r13,rcx + xor r15,r8 + + xor r9,rax + xor r14,r10 + add r12,r15 + mov r15,r11 + + ror r13,14 + and r9,r10 + and r15,rax + + ror r14,28 + add r12,r13 + add r9,r15 + + add rbx,r12 + add r9,r12 + lea rdi,QWORD PTR[1+rdi] + add r9,r14 + + mov r12,QWORD PTR[88+rsi] + mov r13,rbx + mov r14,r9 + bswap r12 + ror r13,23 + mov r15,rcx + mov QWORD PTR[88+rsp],r12 + + ror r14,5 + xor r13,rbx + xor r15,rdx + + ror r13,4 + add r12,r8 + xor r14,r9 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rbx + mov r8,r10 + + ror r14,6 + xor r13,rbx + xor r15,rdx + + xor r8,r11 + xor r14,r9 + add r12,r15 + mov r15,r10 + + ror r13,14 + and r8,r9 + and r15,r11 + + ror r14,28 + add r12,r13 + add r8,r15 + + add rax,r12 + add r8,r12 + lea rdi,QWORD PTR[1+rdi] + add r8,r14 + + mov r12,QWORD PTR[96+rsi] + mov r13,rax + mov r14,r8 + bswap r12 + ror r13,23 + mov r15,rbx + mov QWORD PTR[96+rsp],r12 + + ror r14,5 + xor r13,rax + xor r15,rcx + + ror r13,4 + add r12,rdx + xor r14,r8 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rax + mov rdx,r9 + + ror r14,6 + xor r13,rax + xor r15,rcx + + xor rdx,r10 + xor r14,r8 + add r12,r15 + mov r15,r9 + + ror r13,14 + and rdx,r8 + and r15,r10 + + ror r14,28 + add r12,r13 + add rdx,r15 + + add r11,r12 + add rdx,r12 + lea rdi,QWORD PTR[1+rdi] + add rdx,r14 + + mov r12,QWORD PTR[104+rsi] + mov r13,r11 + mov r14,rdx + bswap r12 + ror r13,23 + mov r15,rax + mov QWORD PTR[104+rsp],r12 + + ror r14,5 + xor r13,r11 + xor r15,rbx + + ror r13,4 + add r12,rcx + xor r14,rdx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r11 + mov rcx,r8 + + ror r14,6 + xor r13,r11 + xor r15,rbx + + xor rcx,r9 + xor r14,rdx + add r12,r15 + mov r15,r8 + + ror r13,14 + and rcx,rdx + and r15,r9 + + ror r14,28 + add r12,r13 + add rcx,r15 + + add r10,r12 + add rcx,r12 + lea rdi,QWORD PTR[1+rdi] + add rcx,r14 + + mov r12,QWORD PTR[112+rsi] + mov r13,r10 + mov r14,rcx + bswap r12 + ror r13,23 + mov r15,r11 + mov QWORD PTR[112+rsp],r12 + + ror r14,5 + xor r13,r10 + xor r15,rax + + ror r13,4 + add r12,rbx + xor r14,rcx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r10 + mov rbx,rdx + + ror r14,6 + xor r13,r10 + xor r15,rax + + xor rbx,r8 + xor r14,rcx + add r12,r15 + mov r15,rdx + + ror r13,14 + and rbx,rcx + and r15,r8 + + ror r14,28 + add r12,r13 + add rbx,r15 + + add r9,r12 + add rbx,r12 + lea rdi,QWORD PTR[1+rdi] + add rbx,r14 + + mov r12,QWORD PTR[120+rsi] + mov r13,r9 + mov r14,rbx + bswap r12 + ror r13,23 + mov r15,r10 + mov QWORD PTR[120+rsp],r12 + + ror r14,5 + xor r13,r9 + xor r15,r11 + + ror r13,4 + add r12,rax + xor r14,rbx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r9 + mov rax,rcx + + ror r14,6 + xor r13,r9 + xor r15,r11 + + xor rax,rdx + xor r14,rbx + add r12,r15 + mov r15,rcx + + ror r13,14 + and rax,rbx + and r15,rdx + + ror r14,28 + add r12,r13 + add rax,r15 + + add r8,r12 + add rax,r12 + lea rdi,QWORD PTR[1+rdi] + add rax,r14 + + jmp $L$rounds_16_xx +ALIGN 16 +$L$rounds_16_xx:: + mov r13,QWORD PTR[8+rsp] + mov r14,QWORD PTR[112+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[72+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[rsp] + mov r13,r8 + add r12,r14 + mov r14,rax + ror r13,23 + mov r15,r9 + mov QWORD PTR[rsp],r12 + + ror r14,5 + xor r13,r8 + xor r15,r10 + + ror r13,4 + add r12,r11 + xor r14,rax + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r8 + mov r11,rbx + + ror r14,6 + xor r13,r8 + xor r15,r10 + + xor r11,rcx + xor r14,rax + add r12,r15 + mov r15,rbx + + ror r13,14 + and r11,rax + and r15,rcx + + ror r14,28 + add r12,r13 + add r11,r15 + + add rdx,r12 + add r11,r12 + lea rdi,QWORD PTR[1+rdi] + add r11,r14 + + mov r13,QWORD PTR[16+rsp] + mov r14,QWORD PTR[120+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[80+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[8+rsp] + mov r13,rdx + add r12,r14 + mov r14,r11 + ror r13,23 + mov r15,r8 + mov QWORD PTR[8+rsp],r12 + + ror r14,5 + xor r13,rdx + xor r15,r9 + + ror r13,4 + add r12,r10 + xor r14,r11 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rdx + mov r10,rax + + ror r14,6 + xor r13,rdx + xor r15,r9 + + xor r10,rbx + xor r14,r11 + add r12,r15 + mov r15,rax + + ror r13,14 + and r10,r11 + and r15,rbx + + ror r14,28 + add r12,r13 + add r10,r15 + + add rcx,r12 + add r10,r12 + lea rdi,QWORD PTR[1+rdi] + add r10,r14 + + mov r13,QWORD PTR[24+rsp] + mov r14,QWORD PTR[rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[88+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[16+rsp] + mov r13,rcx + add r12,r14 + mov r14,r10 + ror r13,23 + mov r15,rdx + mov QWORD PTR[16+rsp],r12 + + ror r14,5 + xor r13,rcx + xor r15,r8 + + ror r13,4 + add r12,r9 + xor r14,r10 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rcx + mov r9,r11 + + ror r14,6 + xor r13,rcx + xor r15,r8 + + xor r9,rax + xor r14,r10 + add r12,r15 + mov r15,r11 + + ror r13,14 + and r9,r10 + and r15,rax + + ror r14,28 + add r12,r13 + add r9,r15 + + add rbx,r12 + add r9,r12 + lea rdi,QWORD PTR[1+rdi] + add r9,r14 + + mov r13,QWORD PTR[32+rsp] + mov r14,QWORD PTR[8+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[96+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[24+rsp] + mov r13,rbx + add r12,r14 + mov r14,r9 + ror r13,23 + mov r15,rcx + mov QWORD PTR[24+rsp],r12 + + ror r14,5 + xor r13,rbx + xor r15,rdx + + ror r13,4 + add r12,r8 + xor r14,r9 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rbx + mov r8,r10 + + ror r14,6 + xor r13,rbx + xor r15,rdx + + xor r8,r11 + xor r14,r9 + add r12,r15 + mov r15,r10 + + ror r13,14 + and r8,r9 + and r15,r11 + + ror r14,28 + add r12,r13 + add r8,r15 + + add rax,r12 + add r8,r12 + lea rdi,QWORD PTR[1+rdi] + add r8,r14 + + mov r13,QWORD PTR[40+rsp] + mov r14,QWORD PTR[16+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[104+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[32+rsp] + mov r13,rax + add r12,r14 + mov r14,r8 + ror r13,23 + mov r15,rbx + mov QWORD PTR[32+rsp],r12 + + ror r14,5 + xor r13,rax + xor r15,rcx + + ror r13,4 + add r12,rdx + xor r14,r8 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rax + mov rdx,r9 + + ror r14,6 + xor r13,rax + xor r15,rcx + + xor rdx,r10 + xor r14,r8 + add r12,r15 + mov r15,r9 + + ror r13,14 + and rdx,r8 + and r15,r10 + + ror r14,28 + add r12,r13 + add rdx,r15 + + add r11,r12 + add rdx,r12 + lea rdi,QWORD PTR[1+rdi] + add rdx,r14 + + mov r13,QWORD PTR[48+rsp] + mov r14,QWORD PTR[24+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[112+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[40+rsp] + mov r13,r11 + add r12,r14 + mov r14,rdx + ror r13,23 + mov r15,rax + mov QWORD PTR[40+rsp],r12 + + ror r14,5 + xor r13,r11 + xor r15,rbx + + ror r13,4 + add r12,rcx + xor r14,rdx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r11 + mov rcx,r8 + + ror r14,6 + xor r13,r11 + xor r15,rbx + + xor rcx,r9 + xor r14,rdx + add r12,r15 + mov r15,r8 + + ror r13,14 + and rcx,rdx + and r15,r9 + + ror r14,28 + add r12,r13 + add rcx,r15 + + add r10,r12 + add rcx,r12 + lea rdi,QWORD PTR[1+rdi] + add rcx,r14 + + mov r13,QWORD PTR[56+rsp] + mov r14,QWORD PTR[32+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[120+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[48+rsp] + mov r13,r10 + add r12,r14 + mov r14,rcx + ror r13,23 + mov r15,r11 + mov QWORD PTR[48+rsp],r12 + + ror r14,5 + xor r13,r10 + xor r15,rax + + ror r13,4 + add r12,rbx + xor r14,rcx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r10 + mov rbx,rdx + + ror r14,6 + xor r13,r10 + xor r15,rax + + xor rbx,r8 + xor r14,rcx + add r12,r15 + mov r15,rdx + + ror r13,14 + and rbx,rcx + and r15,r8 + + ror r14,28 + add r12,r13 + add rbx,r15 + + add r9,r12 + add rbx,r12 + lea rdi,QWORD PTR[1+rdi] + add rbx,r14 + + mov r13,QWORD PTR[64+rsp] + mov r14,QWORD PTR[40+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[56+rsp] + mov r13,r9 + add r12,r14 + mov r14,rbx + ror r13,23 + mov r15,r10 + mov QWORD PTR[56+rsp],r12 + + ror r14,5 + xor r13,r9 + xor r15,r11 + + ror r13,4 + add r12,rax + xor r14,rbx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r9 + mov rax,rcx + + ror r14,6 + xor r13,r9 + xor r15,r11 + + xor rax,rdx + xor r14,rbx + add r12,r15 + mov r15,rcx + + ror r13,14 + and rax,rbx + and r15,rdx + + ror r14,28 + add r12,r13 + add rax,r15 + + add r8,r12 + add rax,r12 + lea rdi,QWORD PTR[1+rdi] + add rax,r14 + + mov r13,QWORD PTR[72+rsp] + mov r14,QWORD PTR[48+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[8+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[64+rsp] + mov r13,r8 + add r12,r14 + mov r14,rax + ror r13,23 + mov r15,r9 + mov QWORD PTR[64+rsp],r12 + + ror r14,5 + xor r13,r8 + xor r15,r10 + + ror r13,4 + add r12,r11 + xor r14,rax + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r8 + mov r11,rbx + + ror r14,6 + xor r13,r8 + xor r15,r10 + + xor r11,rcx + xor r14,rax + add r12,r15 + mov r15,rbx + + ror r13,14 + and r11,rax + and r15,rcx + + ror r14,28 + add r12,r13 + add r11,r15 + + add rdx,r12 + add r11,r12 + lea rdi,QWORD PTR[1+rdi] + add r11,r14 + + mov r13,QWORD PTR[80+rsp] + mov r14,QWORD PTR[56+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[16+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[72+rsp] + mov r13,rdx + add r12,r14 + mov r14,r11 + ror r13,23 + mov r15,r8 + mov QWORD PTR[72+rsp],r12 + + ror r14,5 + xor r13,rdx + xor r15,r9 + + ror r13,4 + add r12,r10 + xor r14,r11 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rdx + mov r10,rax + + ror r14,6 + xor r13,rdx + xor r15,r9 + + xor r10,rbx + xor r14,r11 + add r12,r15 + mov r15,rax + + ror r13,14 + and r10,r11 + and r15,rbx + + ror r14,28 + add r12,r13 + add r10,r15 + + add rcx,r12 + add r10,r12 + lea rdi,QWORD PTR[1+rdi] + add r10,r14 + + mov r13,QWORD PTR[88+rsp] + mov r14,QWORD PTR[64+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[24+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[80+rsp] + mov r13,rcx + add r12,r14 + mov r14,r10 + ror r13,23 + mov r15,rdx + mov QWORD PTR[80+rsp],r12 + + ror r14,5 + xor r13,rcx + xor r15,r8 + + ror r13,4 + add r12,r9 + xor r14,r10 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rcx + mov r9,r11 + + ror r14,6 + xor r13,rcx + xor r15,r8 + + xor r9,rax + xor r14,r10 + add r12,r15 + mov r15,r11 + + ror r13,14 + and r9,r10 + and r15,rax + + ror r14,28 + add r12,r13 + add r9,r15 + + add rbx,r12 + add r9,r12 + lea rdi,QWORD PTR[1+rdi] + add r9,r14 + + mov r13,QWORD PTR[96+rsp] + mov r14,QWORD PTR[72+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[32+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[88+rsp] + mov r13,rbx + add r12,r14 + mov r14,r9 + ror r13,23 + mov r15,rcx + mov QWORD PTR[88+rsp],r12 + + ror r14,5 + xor r13,rbx + xor r15,rdx + + ror r13,4 + add r12,r8 + xor r14,r9 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rbx + mov r8,r10 + + ror r14,6 + xor r13,rbx + xor r15,rdx + + xor r8,r11 + xor r14,r9 + add r12,r15 + mov r15,r10 + + ror r13,14 + and r8,r9 + and r15,r11 + + ror r14,28 + add r12,r13 + add r8,r15 + + add rax,r12 + add r8,r12 + lea rdi,QWORD PTR[1+rdi] + add r8,r14 + + mov r13,QWORD PTR[104+rsp] + mov r14,QWORD PTR[80+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[40+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[96+rsp] + mov r13,rax + add r12,r14 + mov r14,r8 + ror r13,23 + mov r15,rbx + mov QWORD PTR[96+rsp],r12 + + ror r14,5 + xor r13,rax + xor r15,rcx + + ror r13,4 + add r12,rdx + xor r14,r8 + + add r12,QWORD PTR[rdi*8+rbp] + and r15,rax + mov rdx,r9 + + ror r14,6 + xor r13,rax + xor r15,rcx + + xor rdx,r10 + xor r14,r8 + add r12,r15 + mov r15,r9 + + ror r13,14 + and rdx,r8 + and r15,r10 + + ror r14,28 + add r12,r13 + add rdx,r15 + + add r11,r12 + add rdx,r12 + lea rdi,QWORD PTR[1+rdi] + add rdx,r14 + + mov r13,QWORD PTR[112+rsp] + mov r14,QWORD PTR[88+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[48+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[104+rsp] + mov r13,r11 + add r12,r14 + mov r14,rdx + ror r13,23 + mov r15,rax + mov QWORD PTR[104+rsp],r12 + + ror r14,5 + xor r13,r11 + xor r15,rbx + + ror r13,4 + add r12,rcx + xor r14,rdx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r11 + mov rcx,r8 + + ror r14,6 + xor r13,r11 + xor r15,rbx + + xor rcx,r9 + xor r14,rdx + add r12,r15 + mov r15,r8 + + ror r13,14 + and rcx,rdx + and r15,r9 + + ror r14,28 + add r12,r13 + add rcx,r15 + + add r10,r12 + add rcx,r12 + lea rdi,QWORD PTR[1+rdi] + add rcx,r14 + + mov r13,QWORD PTR[120+rsp] + mov r14,QWORD PTR[96+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[56+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[112+rsp] + mov r13,r10 + add r12,r14 + mov r14,rcx + ror r13,23 + mov r15,r11 + mov QWORD PTR[112+rsp],r12 + + ror r14,5 + xor r13,r10 + xor r15,rax + + ror r13,4 + add r12,rbx + xor r14,rcx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r10 + mov rbx,rdx + + ror r14,6 + xor r13,r10 + xor r15,rax + + xor rbx,r8 + xor r14,rcx + add r12,r15 + mov r15,rdx + + ror r13,14 + and rbx,rcx + and r15,r8 + + ror r14,28 + add r12,r13 + add rbx,r15 + + add r9,r12 + add rbx,r12 + lea rdi,QWORD PTR[1+rdi] + add rbx,r14 + + mov r13,QWORD PTR[rsp] + mov r14,QWORD PTR[104+rsp] + mov r12,r13 + mov r15,r14 + + ror r12,7 + xor r12,r13 + shr r13,7 + + ror r12,1 + xor r13,r12 + mov r12,QWORD PTR[64+rsp] + + ror r15,42 + xor r15,r14 + shr r14,6 + + ror r15,19 + add r12,r13 + xor r14,r15 + + add r12,QWORD PTR[120+rsp] + mov r13,r9 + add r12,r14 + mov r14,rbx + ror r13,23 + mov r15,r10 + mov QWORD PTR[120+rsp],r12 + + ror r14,5 + xor r13,r9 + xor r15,r11 + + ror r13,4 + add r12,rax + xor r14,rbx + + add r12,QWORD PTR[rdi*8+rbp] + and r15,r9 + mov rax,rcx + + ror r14,6 + xor r13,r9 + xor r15,r11 + + xor rax,rdx + xor r14,rbx + add r12,r15 + mov r15,rcx + + ror r13,14 + and rax,rbx + and r15,rdx + + ror r14,28 + add r12,r13 + add rax,r15 + + add r8,r12 + add rax,r12 + lea rdi,QWORD PTR[1+rdi] + add rax,r14 + + cmp rdi,80 + jb $L$rounds_16_xx + + mov rdi,QWORD PTR[((128+0))+rsp] + lea rsi,QWORD PTR[128+rsi] + + add rax,QWORD PTR[rdi] + add rbx,QWORD PTR[8+rdi] + add rcx,QWORD PTR[16+rdi] + add rdx,QWORD PTR[24+rdi] + add r8,QWORD PTR[32+rdi] + add r9,QWORD PTR[40+rdi] + add r10,QWORD PTR[48+rdi] + add r11,QWORD PTR[56+rdi] + + cmp rsi,QWORD PTR[((128+16))+rsp] + + mov QWORD PTR[rdi],rax + mov QWORD PTR[8+rdi],rbx + mov QWORD PTR[16+rdi],rcx + mov QWORD PTR[24+rdi],rdx + mov QWORD PTR[32+rdi],r8 + mov QWORD PTR[40+rdi],r9 + mov QWORD PTR[48+rdi],r10 + mov QWORD PTR[56+rdi],r11 + jb $L$loop + + mov rsi,QWORD PTR[((128+24))+rsp] + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha512_block_data_order:: +sha512_block_data_order ENDP +ALIGN 64 + +K512:: + DQ 0428a2f98d728ae22h,07137449123ef65cdh + DQ 0b5c0fbcfec4d3b2fh,0e9b5dba58189dbbch + DQ 03956c25bf348b538h,059f111f1b605d019h + DQ 0923f82a4af194f9bh,0ab1c5ed5da6d8118h + DQ 0d807aa98a3030242h,012835b0145706fbeh + DQ 0243185be4ee4b28ch,0550c7dc3d5ffb4e2h + DQ 072be5d74f27b896fh,080deb1fe3b1696b1h + DQ 09bdc06a725c71235h,0c19bf174cf692694h + DQ 0e49b69c19ef14ad2h,0efbe4786384f25e3h + DQ 00fc19dc68b8cd5b5h,0240ca1cc77ac9c65h + DQ 02de92c6f592b0275h,04a7484aa6ea6e483h + DQ 05cb0a9dcbd41fbd4h,076f988da831153b5h + DQ 0983e5152ee66dfabh,0a831c66d2db43210h + DQ 0b00327c898fb213fh,0bf597fc7beef0ee4h + DQ 0c6e00bf33da88fc2h,0d5a79147930aa725h + DQ 006ca6351e003826fh,0142929670a0e6e70h + DQ 027b70a8546d22ffch,02e1b21385c26c926h + DQ 04d2c6dfc5ac42aedh,053380d139d95b3dfh + DQ 0650a73548baf63deh,0766a0abb3c77b2a8h + DQ 081c2c92e47edaee6h,092722c851482353bh + DQ 0a2bfe8a14cf10364h,0a81a664bbc423001h + DQ 0c24b8b70d0f89791h,0c76c51a30654be30h + DQ 0d192e819d6ef5218h,0d69906245565a910h + DQ 0f40e35855771202ah,0106aa07032bbd1b8h + DQ 019a4c116b8d2d0c8h,01e376c085141ab53h + DQ 02748774cdf8eeb99h,034b0bcb5e19b48a8h + DQ 0391c0cb3c5c95a63h,04ed8aa4ae3418acbh + DQ 05b9cca4f7763e373h,0682e6ff3d6b2b8a3h + DQ 0748f82ee5defb2fch,078a5636f43172f60h + DQ 084c87814a1f0ab72h,08cc702081a6439ech + DQ 090befffa23631e28h,0a4506cebde82bde9h + DQ 0bef9a3f7b2c67915h,0c67178f2e372532bh + DQ 0ca273eceea26619ch,0d186b8c721c0c207h + DQ 0eada7dd6cde0eb1eh,0f57d4f7fee6ed178h + DQ 006f067aa72176fbah,00a637dc5a2c898a6h + DQ 0113f9804bef90daeh,01b710b35131c471bh + DQ 028db77f523047d84h,032caab7b40c72493h + DQ 03c9ebe0a15c9bebch,0431d67c49c100d4ch + DQ 04cc5d4becb3e42b6h,0597f299cfc657e2ah + DQ 05fcb6fab3ad6faech,06c44198c4a475817h + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/sha/sha512-mingw64-x86_64.S b/Libraries/libressl/crypto/sha/sha512-mingw64-x86_64.S new file mode 100644 index 000000000..515395245 --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512-mingw64-x86_64.S @@ -0,0 +1,1814 @@ +#include "x86_arch.h" +.text + +.globl sha512_block_data_order +.def sha512_block_data_order; .scl 2; .type 32; .endef +.p2align 4 +sha512_block_data_order: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_sha512_block_data_order: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + movq %r9,%rcx + + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $128+32,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +.Lprologue: + + leaq K512(%rip),%rbp + + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop + +.p2align 4 +.Lloop: + xorq %rdi,%rdi + movq 0(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,0(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 8(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,8(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 16(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,16(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 24(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,24(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 32(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,32(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 40(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,40(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 48(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,48(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 56(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,56(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + movq 64(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,64(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 72(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,72(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 80(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,80(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 88(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,88(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 96(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,96(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 104(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,104(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 112(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,112(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 120(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,120(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + jmp .Lrounds_16_xx +.p2align 4 +.Lrounds_16_xx: + movq 8(%rsp),%r13 + movq 112(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 72(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 0(%rsp),%r12 + movq %r8,%r13 + addq %r14,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,0(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 16(%rsp),%r13 + movq 120(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 80(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 8(%rsp),%r12 + movq %rdx,%r13 + addq %r14,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,8(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 24(%rsp),%r13 + movq 0(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 88(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 16(%rsp),%r12 + movq %rcx,%r13 + addq %r14,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,16(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 32(%rsp),%r13 + movq 8(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 96(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 24(%rsp),%r12 + movq %rbx,%r13 + addq %r14,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,24(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 40(%rsp),%r13 + movq 16(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 104(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 32(%rsp),%r12 + movq %rax,%r13 + addq %r14,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,32(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 48(%rsp),%r13 + movq 24(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 112(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 40(%rsp),%r12 + movq %r11,%r13 + addq %r14,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,40(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 56(%rsp),%r13 + movq 32(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 120(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 48(%rsp),%r12 + movq %r10,%r13 + addq %r14,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,48(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 64(%rsp),%r13 + movq 40(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 0(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 56(%rsp),%r12 + movq %r9,%r13 + addq %r14,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,56(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + movq 72(%rsp),%r13 + movq 48(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 8(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 64(%rsp),%r12 + movq %r8,%r13 + addq %r14,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + movq %r12,64(%rsp) + + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %rax,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r8,%r15 + movq %rbx,%r11 + + rorq $6,%r14 + xorq %r8,%r13 + xorq %r10,%r15 + + xorq %rcx,%r11 + xorq %rax,%r14 + addq %r15,%r12 + movq %rbx,%r15 + + rorq $14,%r13 + andq %rax,%r11 + andq %rcx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r11 + + addq %r12,%rdx + addq %r12,%r11 + leaq 1(%rdi),%rdi + addq %r14,%r11 + + movq 80(%rsp),%r13 + movq 56(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 16(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 72(%rsp),%r12 + movq %rdx,%r13 + addq %r14,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%r15 + movq %r12,72(%rsp) + + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + rorq $4,%r13 + addq %r10,%r12 + xorq %r11,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rdx,%r15 + movq %rax,%r10 + + rorq $6,%r14 + xorq %rdx,%r13 + xorq %r9,%r15 + + xorq %rbx,%r10 + xorq %r11,%r14 + addq %r15,%r12 + movq %rax,%r15 + + rorq $14,%r13 + andq %r11,%r10 + andq %rbx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r10 + + addq %r12,%rcx + addq %r12,%r10 + leaq 1(%rdi),%rdi + addq %r14,%r10 + + movq 88(%rsp),%r13 + movq 64(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 24(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 80(%rsp),%r12 + movq %rcx,%r13 + addq %r14,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + movq %r12,80(%rsp) + + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r10,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rcx,%r15 + movq %r11,%r9 + + rorq $6,%r14 + xorq %rcx,%r13 + xorq %r8,%r15 + + xorq %rax,%r9 + xorq %r10,%r14 + addq %r15,%r12 + movq %r11,%r15 + + rorq $14,%r13 + andq %r10,%r9 + andq %rax,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r9 + + addq %r12,%rbx + addq %r12,%r9 + leaq 1(%rdi),%rdi + addq %r14,%r9 + + movq 96(%rsp),%r13 + movq 72(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 32(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 88(%rsp),%r12 + movq %rbx,%r13 + addq %r14,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%r15 + movq %r12,88(%rsp) + + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + rorq $4,%r13 + addq %r8,%r12 + xorq %r9,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rbx,%r15 + movq %r10,%r8 + + rorq $6,%r14 + xorq %rbx,%r13 + xorq %rdx,%r15 + + xorq %r11,%r8 + xorq %r9,%r14 + addq %r15,%r12 + movq %r10,%r15 + + rorq $14,%r13 + andq %r9,%r8 + andq %r11,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%r8 + + addq %r12,%rax + addq %r12,%r8 + leaq 1(%rdi),%rdi + addq %r14,%r8 + + movq 104(%rsp),%r13 + movq 80(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 40(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 96(%rsp),%r12 + movq %rax,%r13 + addq %r14,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + movq %r12,96(%rsp) + + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %r8,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %rax,%r15 + movq %r9,%rdx + + rorq $6,%r14 + xorq %rax,%r13 + xorq %rcx,%r15 + + xorq %r10,%rdx + xorq %r8,%r14 + addq %r15,%r12 + movq %r9,%r15 + + rorq $14,%r13 + andq %r8,%rdx + andq %r10,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rdx + + addq %r12,%r11 + addq %r12,%rdx + leaq 1(%rdi),%rdi + addq %r14,%rdx + + movq 112(%rsp),%r13 + movq 88(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 48(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 104(%rsp),%r12 + movq %r11,%r13 + addq %r14,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%r15 + movq %r12,104(%rsp) + + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rdx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r11,%r15 + movq %r8,%rcx + + rorq $6,%r14 + xorq %r11,%r13 + xorq %rbx,%r15 + + xorq %r9,%rcx + xorq %rdx,%r14 + addq %r15,%r12 + movq %r8,%r15 + + rorq $14,%r13 + andq %rdx,%rcx + andq %r9,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rcx + + addq %r12,%r10 + addq %r12,%rcx + leaq 1(%rdi),%rdi + addq %r14,%rcx + + movq 120(%rsp),%r13 + movq 96(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 56(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 112(%rsp),%r12 + movq %r10,%r13 + addq %r14,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + movq %r12,112(%rsp) + + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rcx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r10,%r15 + movq %rdx,%rbx + + rorq $6,%r14 + xorq %r10,%r13 + xorq %rax,%r15 + + xorq %r8,%rbx + xorq %rcx,%r14 + addq %r15,%r12 + movq %rdx,%r15 + + rorq $14,%r13 + andq %rcx,%rbx + andq %r8,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rbx + + addq %r12,%r9 + addq %r12,%rbx + leaq 1(%rdi),%rdi + addq %r14,%rbx + + movq 0(%rsp),%r13 + movq 104(%rsp),%r14 + movq %r13,%r12 + movq %r14,%r15 + + rorq $7,%r12 + xorq %r13,%r12 + shrq $7,%r13 + + rorq $1,%r12 + xorq %r12,%r13 + movq 64(%rsp),%r12 + + rorq $42,%r15 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + addq %r13,%r12 + xorq %r15,%r14 + + addq 120(%rsp),%r12 + movq %r9,%r13 + addq %r14,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%r15 + movq %r12,120(%rsp) + + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + rorq $4,%r13 + addq %rax,%r12 + xorq %rbx,%r14 + + addq (%rbp,%rdi,8),%r12 + andq %r9,%r15 + movq %rcx,%rax + + rorq $6,%r14 + xorq %r9,%r13 + xorq %r11,%r15 + + xorq %rdx,%rax + xorq %rbx,%r14 + addq %r15,%r12 + movq %rcx,%r15 + + rorq $14,%r13 + andq %rbx,%rax + andq %rdx,%r15 + + rorq $28,%r14 + addq %r13,%r12 + addq %r15,%rax + + addq %r12,%r8 + addq %r12,%rax + leaq 1(%rdi),%rdi + addq %r14,%rax + + cmpq $80,%rdi + jb .Lrounds_16_xx + + movq 128+0(%rsp),%rdi + leaq 128(%rsi),%rsi + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop + + movq 128+24(%rsp),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_sha512_block_data_order: +.p2align 6 + +K512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 diff --git a/Libraries/libressl/crypto/sha/sha512-mips.S b/Libraries/libressl/crypto/sha/sha512-mips.S new file mode 100644 index 000000000..da903b65d --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512-mips.S @@ -0,0 +1,2165 @@ +.text +.set noat +#if !defined(__vxworks) || defined(__pic__) +.option pic2 +#endif + +.align 5 +.globl sha512_block_data_order +.ent sha512_block_data_order +sha512_block_data_order: + .frame $29,192,$31 + .mask 3237937152,-4 + .set noreorder + .cpload $25 + sub $29,192 + sw $31,192-1*4($29) + sw $30,192-2*4($29) + sw $23,192-3*4($29) + sw $22,192-4*4($29) + sw $21,192-5*4($29) + sw $20,192-6*4($29) + sw $19,192-7*4($29) + sw $18,192-8*4($29) + sw $17,192-9*4($29) + sw $16,192-10*4($29) + sll $23,$6,7 + .set reorder + la $6,K512 # PIC-ified 'load address' + + ld $1,0*8($4) # load context + ld $2,1*8($4) + ld $3,2*8($4) + ld $7,3*8($4) + ld $24,4*8($4) + ld $25,5*8($4) + ld $30,6*8($4) + ld $31,7*8($4) + + add $23,$5 # pointer to the end of input + sw $23,16*8($29) + b .Loop + +.align 5 +.Loop: + ldl $8,7($5) + ldr $8,0($5) + ldl $9,15($5) + ldr $9,8($5) + ori $13,$0,0xFF + dsll $15,$13,32 + or $13,$15 # 0x000000FF000000FF + and $14,$8,$13 # byte swap(0) + dsrl $15,$8,24 + dsll $14,24 + and $15,$13 + dsll $13,8 # 0x0000FF000000FF00 + or $14,$15 + and $15,$8,$13 + dsrl $8,8 + dsll $15,8 + and $8,$13 + or $14,$15 + or $8,$14 + dsrl $14,$8,32 + dsll $8,32 + or $8,$14 + daddu $12,$8,$31 # 0 + dsrl $31,$24,14 + xor $15,$25,$30 + dsll $14,$24,23 + and $15,$24 + dsrl $13,$24,18 + xor $31,$14 + dsll $14,$24,46 + xor $31,$13 + dsrl $13,$24,41 + xor $31,$14 + dsll $14,$24,50 + xor $31,$13 + xor $15,$30 # Ch(e,f,g) + xor $13,$14,$31 # Sigma1(e) + + dsrl $31,$1,28 + daddu $12,$15 + ld $15,0($6) # K[0] + dsll $14,$1,25 + daddu $12,$13 + dsrl $13,$1,34 + xor $31,$14 + dsll $14,$1,30 + xor $31,$13 + dsrl $13,$1,39 + xor $31,$14 + dsll $14,$1,36 + xor $31,$13 + sd $8,0($29) # offload to ring buffer + xor $31,$14 # Sigma0(a) + + or $13,$1,$2 + and $14,$1,$2 + and $13,$3 + or $14,$13 # Maj(a,b,c) + daddu $12,$15 # +=K[0] + daddu $31,$14 + + daddu $7,$12 + daddu $31,$12 + ldl $10,23($5) + ldr $10,16($5) + ori $14,$0,0xFF + dsll $16,$14,32 + or $14,$16 # 0x000000FF000000FF + and $15,$9,$14 # byte swap(1) + dsrl $16,$9,24 + dsll $15,24 + and $16,$14 + dsll $14,8 # 0x0000FF000000FF00 + or $15,$16 + and $16,$9,$14 + dsrl $9,8 + dsll $16,8 + and $9,$14 + or $15,$16 + or $9,$15 + dsrl $15,$9,32 + dsll $9,32 + or $9,$15 + daddu $13,$9,$30 # 1 + dsrl $30,$7,14 + xor $16,$24,$25 + dsll $15,$7,23 + and $16,$7 + dsrl $14,$7,18 + xor $30,$15 + dsll $15,$7,46 + xor $30,$14 + dsrl $14,$7,41 + xor $30,$15 + dsll $15,$7,50 + xor $30,$14 + xor $16,$25 # Ch(e,f,g) + xor $14,$15,$30 # Sigma1(e) + + dsrl $30,$31,28 + daddu $13,$16 + ld $16,8($6) # K[1] + dsll $15,$31,25 + daddu $13,$14 + dsrl $14,$31,34 + xor $30,$15 + dsll $15,$31,30 + xor $30,$14 + dsrl $14,$31,39 + xor $30,$15 + dsll $15,$31,36 + xor $30,$14 + sd $9,8($29) # offload to ring buffer + xor $30,$15 # Sigma0(a) + + or $14,$31,$1 + and $15,$31,$1 + and $14,$2 + or $15,$14 # Maj(a,b,c) + daddu $13,$16 # +=K[1] + daddu $30,$15 + + daddu $3,$13 + daddu $30,$13 + ldl $11,31($5) + ldr $11,24($5) + ori $15,$0,0xFF + dsll $17,$15,32 + or $15,$17 # 0x000000FF000000FF + and $16,$10,$15 # byte swap(2) + dsrl $17,$10,24 + dsll $16,24 + and $17,$15 + dsll $15,8 # 0x0000FF000000FF00 + or $16,$17 + and $17,$10,$15 + dsrl $10,8 + dsll $17,8 + and $10,$15 + or $16,$17 + or $10,$16 + dsrl $16,$10,32 + dsll $10,32 + or $10,$16 + daddu $14,$10,$25 # 2 + dsrl $25,$3,14 + xor $17,$7,$24 + dsll $16,$3,23 + and $17,$3 + dsrl $15,$3,18 + xor $25,$16 + dsll $16,$3,46 + xor $25,$15 + dsrl $15,$3,41 + xor $25,$16 + dsll $16,$3,50 + xor $25,$15 + xor $17,$24 # Ch(e,f,g) + xor $15,$16,$25 # Sigma1(e) + + dsrl $25,$30,28 + daddu $14,$17 + ld $17,16($6) # K[2] + dsll $16,$30,25 + daddu $14,$15 + dsrl $15,$30,34 + xor $25,$16 + dsll $16,$30,30 + xor $25,$15 + dsrl $15,$30,39 + xor $25,$16 + dsll $16,$30,36 + xor $25,$15 + sd $10,16($29) # offload to ring buffer + xor $25,$16 # Sigma0(a) + + or $15,$30,$31 + and $16,$30,$31 + and $15,$1 + or $16,$15 # Maj(a,b,c) + daddu $14,$17 # +=K[2] + daddu $25,$16 + + daddu $2,$14 + daddu $25,$14 + ldl $12,39($5) + ldr $12,32($5) + ori $16,$0,0xFF + dsll $18,$16,32 + or $16,$18 # 0x000000FF000000FF + and $17,$11,$16 # byte swap(3) + dsrl $18,$11,24 + dsll $17,24 + and $18,$16 + dsll $16,8 # 0x0000FF000000FF00 + or $17,$18 + and $18,$11,$16 + dsrl $11,8 + dsll $18,8 + and $11,$16 + or $17,$18 + or $11,$17 + dsrl $17,$11,32 + dsll $11,32 + or $11,$17 + daddu $15,$11,$24 # 3 + dsrl $24,$2,14 + xor $18,$3,$7 + dsll $17,$2,23 + and $18,$2 + dsrl $16,$2,18 + xor $24,$17 + dsll $17,$2,46 + xor $24,$16 + dsrl $16,$2,41 + xor $24,$17 + dsll $17,$2,50 + xor $24,$16 + xor $18,$7 # Ch(e,f,g) + xor $16,$17,$24 # Sigma1(e) + + dsrl $24,$25,28 + daddu $15,$18 + ld $18,24($6) # K[3] + dsll $17,$25,25 + daddu $15,$16 + dsrl $16,$25,34 + xor $24,$17 + dsll $17,$25,30 + xor $24,$16 + dsrl $16,$25,39 + xor $24,$17 + dsll $17,$25,36 + xor $24,$16 + sd $11,24($29) # offload to ring buffer + xor $24,$17 # Sigma0(a) + + or $16,$25,$30 + and $17,$25,$30 + and $16,$31 + or $17,$16 # Maj(a,b,c) + daddu $15,$18 # +=K[3] + daddu $24,$17 + + daddu $1,$15 + daddu $24,$15 + ldl $13,47($5) + ldr $13,40($5) + ori $17,$0,0xFF + dsll $19,$17,32 + or $17,$19 # 0x000000FF000000FF + and $18,$12,$17 # byte swap(4) + dsrl $19,$12,24 + dsll $18,24 + and $19,$17 + dsll $17,8 # 0x0000FF000000FF00 + or $18,$19 + and $19,$12,$17 + dsrl $12,8 + dsll $19,8 + and $12,$17 + or $18,$19 + or $12,$18 + dsrl $18,$12,32 + dsll $12,32 + or $12,$18 + daddu $16,$12,$7 # 4 + dsrl $7,$1,14 + xor $19,$2,$3 + dsll $18,$1,23 + and $19,$1 + dsrl $17,$1,18 + xor $7,$18 + dsll $18,$1,46 + xor $7,$17 + dsrl $17,$1,41 + xor $7,$18 + dsll $18,$1,50 + xor $7,$17 + xor $19,$3 # Ch(e,f,g) + xor $17,$18,$7 # Sigma1(e) + + dsrl $7,$24,28 + daddu $16,$19 + ld $19,32($6) # K[4] + dsll $18,$24,25 + daddu $16,$17 + dsrl $17,$24,34 + xor $7,$18 + dsll $18,$24,30 + xor $7,$17 + dsrl $17,$24,39 + xor $7,$18 + dsll $18,$24,36 + xor $7,$17 + sd $12,32($29) # offload to ring buffer + xor $7,$18 # Sigma0(a) + + or $17,$24,$25 + and $18,$24,$25 + and $17,$30 + or $18,$17 # Maj(a,b,c) + daddu $16,$19 # +=K[4] + daddu $7,$18 + + daddu $31,$16 + daddu $7,$16 + ldl $14,55($5) + ldr $14,48($5) + ori $18,$0,0xFF + dsll $20,$18,32 + or $18,$20 # 0x000000FF000000FF + and $19,$13,$18 # byte swap(5) + dsrl $20,$13,24 + dsll $19,24 + and $20,$18 + dsll $18,8 # 0x0000FF000000FF00 + or $19,$20 + and $20,$13,$18 + dsrl $13,8 + dsll $20,8 + and $13,$18 + or $19,$20 + or $13,$19 + dsrl $19,$13,32 + dsll $13,32 + or $13,$19 + daddu $17,$13,$3 # 5 + dsrl $3,$31,14 + xor $20,$1,$2 + dsll $19,$31,23 + and $20,$31 + dsrl $18,$31,18 + xor $3,$19 + dsll $19,$31,46 + xor $3,$18 + dsrl $18,$31,41 + xor $3,$19 + dsll $19,$31,50 + xor $3,$18 + xor $20,$2 # Ch(e,f,g) + xor $18,$19,$3 # Sigma1(e) + + dsrl $3,$7,28 + daddu $17,$20 + ld $20,40($6) # K[5] + dsll $19,$7,25 + daddu $17,$18 + dsrl $18,$7,34 + xor $3,$19 + dsll $19,$7,30 + xor $3,$18 + dsrl $18,$7,39 + xor $3,$19 + dsll $19,$7,36 + xor $3,$18 + sd $13,40($29) # offload to ring buffer + xor $3,$19 # Sigma0(a) + + or $18,$7,$24 + and $19,$7,$24 + and $18,$25 + or $19,$18 # Maj(a,b,c) + daddu $17,$20 # +=K[5] + daddu $3,$19 + + daddu $30,$17 + daddu $3,$17 + ldl $15,63($5) + ldr $15,56($5) + ori $19,$0,0xFF + dsll $21,$19,32 + or $19,$21 # 0x000000FF000000FF + and $20,$14,$19 # byte swap(6) + dsrl $21,$14,24 + dsll $20,24 + and $21,$19 + dsll $19,8 # 0x0000FF000000FF00 + or $20,$21 + and $21,$14,$19 + dsrl $14,8 + dsll $21,8 + and $14,$19 + or $20,$21 + or $14,$20 + dsrl $20,$14,32 + dsll $14,32 + or $14,$20 + daddu $18,$14,$2 # 6 + dsrl $2,$30,14 + xor $21,$31,$1 + dsll $20,$30,23 + and $21,$30 + dsrl $19,$30,18 + xor $2,$20 + dsll $20,$30,46 + xor $2,$19 + dsrl $19,$30,41 + xor $2,$20 + dsll $20,$30,50 + xor $2,$19 + xor $21,$1 # Ch(e,f,g) + xor $19,$20,$2 # Sigma1(e) + + dsrl $2,$3,28 + daddu $18,$21 + ld $21,48($6) # K[6] + dsll $20,$3,25 + daddu $18,$19 + dsrl $19,$3,34 + xor $2,$20 + dsll $20,$3,30 + xor $2,$19 + dsrl $19,$3,39 + xor $2,$20 + dsll $20,$3,36 + xor $2,$19 + sd $14,48($29) # offload to ring buffer + xor $2,$20 # Sigma0(a) + + or $19,$3,$7 + and $20,$3,$7 + and $19,$24 + or $20,$19 # Maj(a,b,c) + daddu $18,$21 # +=K[6] + daddu $2,$20 + + daddu $25,$18 + daddu $2,$18 + ldl $16,71($5) + ldr $16,64($5) + ori $20,$0,0xFF + dsll $22,$20,32 + or $20,$22 # 0x000000FF000000FF + and $21,$15,$20 # byte swap(7) + dsrl $22,$15,24 + dsll $21,24 + and $22,$20 + dsll $20,8 # 0x0000FF000000FF00 + or $21,$22 + and $22,$15,$20 + dsrl $15,8 + dsll $22,8 + and $15,$20 + or $21,$22 + or $15,$21 + dsrl $21,$15,32 + dsll $15,32 + or $15,$21 + daddu $19,$15,$1 # 7 + dsrl $1,$25,14 + xor $22,$30,$31 + dsll $21,$25,23 + and $22,$25 + dsrl $20,$25,18 + xor $1,$21 + dsll $21,$25,46 + xor $1,$20 + dsrl $20,$25,41 + xor $1,$21 + dsll $21,$25,50 + xor $1,$20 + xor $22,$31 # Ch(e,f,g) + xor $20,$21,$1 # Sigma1(e) + + dsrl $1,$2,28 + daddu $19,$22 + ld $22,56($6) # K[7] + dsll $21,$2,25 + daddu $19,$20 + dsrl $20,$2,34 + xor $1,$21 + dsll $21,$2,30 + xor $1,$20 + dsrl $20,$2,39 + xor $1,$21 + dsll $21,$2,36 + xor $1,$20 + sd $15,56($29) # offload to ring buffer + xor $1,$21 # Sigma0(a) + + or $20,$2,$3 + and $21,$2,$3 + and $20,$7 + or $21,$20 # Maj(a,b,c) + daddu $19,$22 # +=K[7] + daddu $1,$21 + + daddu $24,$19 + daddu $1,$19 + ldl $17,79($5) + ldr $17,72($5) + ori $21,$0,0xFF + dsll $23,$21,32 + or $21,$23 # 0x000000FF000000FF + and $22,$16,$21 # byte swap(8) + dsrl $23,$16,24 + dsll $22,24 + and $23,$21 + dsll $21,8 # 0x0000FF000000FF00 + or $22,$23 + and $23,$16,$21 + dsrl $16,8 + dsll $23,8 + and $16,$21 + or $22,$23 + or $16,$22 + dsrl $22,$16,32 + dsll $16,32 + or $16,$22 + daddu $20,$16,$31 # 8 + dsrl $31,$24,14 + xor $23,$25,$30 + dsll $22,$24,23 + and $23,$24 + dsrl $21,$24,18 + xor $31,$22 + dsll $22,$24,46 + xor $31,$21 + dsrl $21,$24,41 + xor $31,$22 + dsll $22,$24,50 + xor $31,$21 + xor $23,$30 # Ch(e,f,g) + xor $21,$22,$31 # Sigma1(e) + + dsrl $31,$1,28 + daddu $20,$23 + ld $23,64($6) # K[8] + dsll $22,$1,25 + daddu $20,$21 + dsrl $21,$1,34 + xor $31,$22 + dsll $22,$1,30 + xor $31,$21 + dsrl $21,$1,39 + xor $31,$22 + dsll $22,$1,36 + xor $31,$21 + sd $16,64($29) # offload to ring buffer + xor $31,$22 # Sigma0(a) + + or $21,$1,$2 + and $22,$1,$2 + and $21,$3 + or $22,$21 # Maj(a,b,c) + daddu $20,$23 # +=K[8] + daddu $31,$22 + + daddu $7,$20 + daddu $31,$20 + ldl $18,87($5) + ldr $18,80($5) + ori $22,$0,0xFF + dsll $8,$22,32 + or $22,$8 # 0x000000FF000000FF + and $23,$17,$22 # byte swap(9) + dsrl $8,$17,24 + dsll $23,24 + and $8,$22 + dsll $22,8 # 0x0000FF000000FF00 + or $23,$8 + and $8,$17,$22 + dsrl $17,8 + dsll $8,8 + and $17,$22 + or $23,$8 + or $17,$23 + dsrl $23,$17,32 + dsll $17,32 + or $17,$23 + daddu $21,$17,$30 # 9 + dsrl $30,$7,14 + xor $8,$24,$25 + dsll $23,$7,23 + and $8,$7 + dsrl $22,$7,18 + xor $30,$23 + dsll $23,$7,46 + xor $30,$22 + dsrl $22,$7,41 + xor $30,$23 + dsll $23,$7,50 + xor $30,$22 + xor $8,$25 # Ch(e,f,g) + xor $22,$23,$30 # Sigma1(e) + + dsrl $30,$31,28 + daddu $21,$8 + ld $8,72($6) # K[9] + dsll $23,$31,25 + daddu $21,$22 + dsrl $22,$31,34 + xor $30,$23 + dsll $23,$31,30 + xor $30,$22 + dsrl $22,$31,39 + xor $30,$23 + dsll $23,$31,36 + xor $30,$22 + sd $17,72($29) # offload to ring buffer + xor $30,$23 # Sigma0(a) + + or $22,$31,$1 + and $23,$31,$1 + and $22,$2 + or $23,$22 # Maj(a,b,c) + daddu $21,$8 # +=K[9] + daddu $30,$23 + + daddu $3,$21 + daddu $30,$21 + ldl $19,95($5) + ldr $19,88($5) + ori $23,$0,0xFF + dsll $9,$23,32 + or $23,$9 # 0x000000FF000000FF + and $8,$18,$23 # byte swap(10) + dsrl $9,$18,24 + dsll $8,24 + and $9,$23 + dsll $23,8 # 0x0000FF000000FF00 + or $8,$9 + and $9,$18,$23 + dsrl $18,8 + dsll $9,8 + and $18,$23 + or $8,$9 + or $18,$8 + dsrl $8,$18,32 + dsll $18,32 + or $18,$8 + daddu $22,$18,$25 # 10 + dsrl $25,$3,14 + xor $9,$7,$24 + dsll $8,$3,23 + and $9,$3 + dsrl $23,$3,18 + xor $25,$8 + dsll $8,$3,46 + xor $25,$23 + dsrl $23,$3,41 + xor $25,$8 + dsll $8,$3,50 + xor $25,$23 + xor $9,$24 # Ch(e,f,g) + xor $23,$8,$25 # Sigma1(e) + + dsrl $25,$30,28 + daddu $22,$9 + ld $9,80($6) # K[10] + dsll $8,$30,25 + daddu $22,$23 + dsrl $23,$30,34 + xor $25,$8 + dsll $8,$30,30 + xor $25,$23 + dsrl $23,$30,39 + xor $25,$8 + dsll $8,$30,36 + xor $25,$23 + sd $18,80($29) # offload to ring buffer + xor $25,$8 # Sigma0(a) + + or $23,$30,$31 + and $8,$30,$31 + and $23,$1 + or $8,$23 # Maj(a,b,c) + daddu $22,$9 # +=K[10] + daddu $25,$8 + + daddu $2,$22 + daddu $25,$22 + ldl $20,103($5) + ldr $20,96($5) + ori $8,$0,0xFF + dsll $10,$8,32 + or $8,$10 # 0x000000FF000000FF + and $9,$19,$8 # byte swap(11) + dsrl $10,$19,24 + dsll $9,24 + and $10,$8 + dsll $8,8 # 0x0000FF000000FF00 + or $9,$10 + and $10,$19,$8 + dsrl $19,8 + dsll $10,8 + and $19,$8 + or $9,$10 + or $19,$9 + dsrl $9,$19,32 + dsll $19,32 + or $19,$9 + daddu $23,$19,$24 # 11 + dsrl $24,$2,14 + xor $10,$3,$7 + dsll $9,$2,23 + and $10,$2 + dsrl $8,$2,18 + xor $24,$9 + dsll $9,$2,46 + xor $24,$8 + dsrl $8,$2,41 + xor $24,$9 + dsll $9,$2,50 + xor $24,$8 + xor $10,$7 # Ch(e,f,g) + xor $8,$9,$24 # Sigma1(e) + + dsrl $24,$25,28 + daddu $23,$10 + ld $10,88($6) # K[11] + dsll $9,$25,25 + daddu $23,$8 + dsrl $8,$25,34 + xor $24,$9 + dsll $9,$25,30 + xor $24,$8 + dsrl $8,$25,39 + xor $24,$9 + dsll $9,$25,36 + xor $24,$8 + sd $19,88($29) # offload to ring buffer + xor $24,$9 # Sigma0(a) + + or $8,$25,$30 + and $9,$25,$30 + and $8,$31 + or $9,$8 # Maj(a,b,c) + daddu $23,$10 # +=K[11] + daddu $24,$9 + + daddu $1,$23 + daddu $24,$23 + ldl $21,111($5) + ldr $21,104($5) + ori $9,$0,0xFF + dsll $11,$9,32 + or $9,$11 # 0x000000FF000000FF + and $10,$20,$9 # byte swap(12) + dsrl $11,$20,24 + dsll $10,24 + and $11,$9 + dsll $9,8 # 0x0000FF000000FF00 + or $10,$11 + and $11,$20,$9 + dsrl $20,8 + dsll $11,8 + and $20,$9 + or $10,$11 + or $20,$10 + dsrl $10,$20,32 + dsll $20,32 + or $20,$10 + daddu $8,$20,$7 # 12 + dsrl $7,$1,14 + xor $11,$2,$3 + dsll $10,$1,23 + and $11,$1 + dsrl $9,$1,18 + xor $7,$10 + dsll $10,$1,46 + xor $7,$9 + dsrl $9,$1,41 + xor $7,$10 + dsll $10,$1,50 + xor $7,$9 + xor $11,$3 # Ch(e,f,g) + xor $9,$10,$7 # Sigma1(e) + + dsrl $7,$24,28 + daddu $8,$11 + ld $11,96($6) # K[12] + dsll $10,$24,25 + daddu $8,$9 + dsrl $9,$24,34 + xor $7,$10 + dsll $10,$24,30 + xor $7,$9 + dsrl $9,$24,39 + xor $7,$10 + dsll $10,$24,36 + xor $7,$9 + sd $20,96($29) # offload to ring buffer + xor $7,$10 # Sigma0(a) + + or $9,$24,$25 + and $10,$24,$25 + and $9,$30 + or $10,$9 # Maj(a,b,c) + daddu $8,$11 # +=K[12] + daddu $7,$10 + + daddu $31,$8 + daddu $7,$8 + ldl $22,119($5) + ldr $22,112($5) + ori $10,$0,0xFF + dsll $12,$10,32 + or $10,$12 # 0x000000FF000000FF + and $11,$21,$10 # byte swap(13) + dsrl $12,$21,24 + dsll $11,24 + and $12,$10 + dsll $10,8 # 0x0000FF000000FF00 + or $11,$12 + and $12,$21,$10 + dsrl $21,8 + dsll $12,8 + and $21,$10 + or $11,$12 + or $21,$11 + dsrl $11,$21,32 + dsll $21,32 + or $21,$11 + daddu $9,$21,$3 # 13 + dsrl $3,$31,14 + xor $12,$1,$2 + dsll $11,$31,23 + and $12,$31 + dsrl $10,$31,18 + xor $3,$11 + dsll $11,$31,46 + xor $3,$10 + dsrl $10,$31,41 + xor $3,$11 + dsll $11,$31,50 + xor $3,$10 + xor $12,$2 # Ch(e,f,g) + xor $10,$11,$3 # Sigma1(e) + + dsrl $3,$7,28 + daddu $9,$12 + ld $12,104($6) # K[13] + dsll $11,$7,25 + daddu $9,$10 + dsrl $10,$7,34 + xor $3,$11 + dsll $11,$7,30 + xor $3,$10 + dsrl $10,$7,39 + xor $3,$11 + dsll $11,$7,36 + xor $3,$10 + sd $21,104($29) # offload to ring buffer + xor $3,$11 # Sigma0(a) + + or $10,$7,$24 + and $11,$7,$24 + and $10,$25 + or $11,$10 # Maj(a,b,c) + daddu $9,$12 # +=K[13] + daddu $3,$11 + + daddu $30,$9 + daddu $3,$9 + ld $8,0($29) # prefetch from ring buffer + ldl $23,127($5) + ldr $23,120($5) + ori $11,$0,0xFF + dsll $13,$11,32 + or $11,$13 # 0x000000FF000000FF + and $12,$22,$11 # byte swap(14) + dsrl $13,$22,24 + dsll $12,24 + and $13,$11 + dsll $11,8 # 0x0000FF000000FF00 + or $12,$13 + and $13,$22,$11 + dsrl $22,8 + dsll $13,8 + and $22,$11 + or $12,$13 + or $22,$12 + dsrl $12,$22,32 + dsll $22,32 + or $22,$12 + daddu $10,$22,$2 # 14 + dsrl $2,$30,14 + xor $13,$31,$1 + dsll $12,$30,23 + and $13,$30 + dsrl $11,$30,18 + xor $2,$12 + dsll $12,$30,46 + xor $2,$11 + dsrl $11,$30,41 + xor $2,$12 + dsll $12,$30,50 + xor $2,$11 + xor $13,$1 # Ch(e,f,g) + xor $11,$12,$2 # Sigma1(e) + + dsrl $2,$3,28 + daddu $10,$13 + ld $13,112($6) # K[14] + dsll $12,$3,25 + daddu $10,$11 + dsrl $11,$3,34 + xor $2,$12 + dsll $12,$3,30 + xor $2,$11 + dsrl $11,$3,39 + xor $2,$12 + dsll $12,$3,36 + xor $2,$11 + sd $22,112($29) # offload to ring buffer + xor $2,$12 # Sigma0(a) + + or $11,$3,$7 + and $12,$3,$7 + and $11,$24 + or $12,$11 # Maj(a,b,c) + daddu $10,$13 # +=K[14] + daddu $2,$12 + + daddu $25,$10 + daddu $2,$10 + ld $9,8($29) # prefetch from ring buffer + ori $12,$0,0xFF + dsll $14,$12,32 + or $12,$14 # 0x000000FF000000FF + and $13,$23,$12 # byte swap(15) + dsrl $14,$23,24 + dsll $13,24 + and $14,$12 + dsll $12,8 # 0x0000FF000000FF00 + or $13,$14 + and $14,$23,$12 + dsrl $23,8 + dsll $14,8 + and $23,$12 + or $13,$14 + or $23,$13 + dsrl $13,$23,32 + dsll $23,32 + or $23,$13 + daddu $11,$23,$1 # 15 + dsrl $1,$25,14 + xor $14,$30,$31 + dsll $13,$25,23 + and $14,$25 + dsrl $12,$25,18 + xor $1,$13 + dsll $13,$25,46 + xor $1,$12 + dsrl $12,$25,41 + xor $1,$13 + dsll $13,$25,50 + xor $1,$12 + xor $14,$31 # Ch(e,f,g) + xor $12,$13,$1 # Sigma1(e) + + dsrl $1,$2,28 + daddu $11,$14 + ld $14,120($6) # K[15] + dsll $13,$2,25 + daddu $11,$12 + dsrl $12,$2,34 + xor $1,$13 + dsll $13,$2,30 + xor $1,$12 + dsrl $12,$2,39 + xor $1,$13 + dsll $13,$2,36 + xor $1,$12 + sd $23,120($29) # offload to ring buffer + xor $1,$13 # Sigma0(a) + + or $12,$2,$3 + and $13,$2,$3 + and $12,$7 + or $13,$12 # Maj(a,b,c) + daddu $11,$14 # +=K[15] + daddu $1,$13 + + daddu $24,$11 + daddu $1,$11 + ld $10,16($29) # prefetch from ring buffer + b .L16_xx +.align 4 +.L16_xx: + dsrl $14,$9,7 # Xupdate(16) + daddu $8,$17 # +=X[i+9] + dsll $13,$9,56 + dsrl $12,$9,1 + xor $14,$13 + dsll $13,7 + xor $14,$12 + dsrl $12,$9,8 + xor $14,$13 + + dsrl $15,$22,6 + xor $14,$12 # sigma0(X[i+1]) + dsll $13,$22,3 + daddu $8,$14 + dsrl $12,$22,19 + xor $15,$13 + dsll $13,42 + xor $15,$12 + dsrl $12,$22,61 + xor $15,$13 + + xor $15,$12 # sigma1(X[i+14]) + daddu $8,$15 + daddu $12,$8,$31 # 16 + dsrl $31,$24,14 + xor $15,$25,$30 + dsll $14,$24,23 + and $15,$24 + dsrl $13,$24,18 + xor $31,$14 + dsll $14,$24,46 + xor $31,$13 + dsrl $13,$24,41 + xor $31,$14 + dsll $14,$24,50 + xor $31,$13 + xor $15,$30 # Ch(e,f,g) + xor $13,$14,$31 # Sigma1(e) + + dsrl $31,$1,28 + daddu $12,$15 + ld $15,128($6) # K[16] + dsll $14,$1,25 + daddu $12,$13 + dsrl $13,$1,34 + xor $31,$14 + dsll $14,$1,30 + xor $31,$13 + dsrl $13,$1,39 + xor $31,$14 + dsll $14,$1,36 + xor $31,$13 + sd $8,0($29) # offload to ring buffer + xor $31,$14 # Sigma0(a) + + or $13,$1,$2 + and $14,$1,$2 + and $13,$3 + or $14,$13 # Maj(a,b,c) + daddu $12,$15 # +=K[16] + daddu $31,$14 + + daddu $7,$12 + daddu $31,$12 + ld $11,24($29) # prefetch from ring buffer + dsrl $15,$10,7 # Xupdate(17) + daddu $9,$18 # +=X[i+9] + dsll $14,$10,56 + dsrl $13,$10,1 + xor $15,$14 + dsll $14,7 + xor $15,$13 + dsrl $13,$10,8 + xor $15,$14 + + dsrl $16,$23,6 + xor $15,$13 # sigma0(X[i+1]) + dsll $14,$23,3 + daddu $9,$15 + dsrl $13,$23,19 + xor $16,$14 + dsll $14,42 + xor $16,$13 + dsrl $13,$23,61 + xor $16,$14 + + xor $16,$13 # sigma1(X[i+14]) + daddu $9,$16 + daddu $13,$9,$30 # 17 + dsrl $30,$7,14 + xor $16,$24,$25 + dsll $15,$7,23 + and $16,$7 + dsrl $14,$7,18 + xor $30,$15 + dsll $15,$7,46 + xor $30,$14 + dsrl $14,$7,41 + xor $30,$15 + dsll $15,$7,50 + xor $30,$14 + xor $16,$25 # Ch(e,f,g) + xor $14,$15,$30 # Sigma1(e) + + dsrl $30,$31,28 + daddu $13,$16 + ld $16,136($6) # K[17] + dsll $15,$31,25 + daddu $13,$14 + dsrl $14,$31,34 + xor $30,$15 + dsll $15,$31,30 + xor $30,$14 + dsrl $14,$31,39 + xor $30,$15 + dsll $15,$31,36 + xor $30,$14 + sd $9,8($29) # offload to ring buffer + xor $30,$15 # Sigma0(a) + + or $14,$31,$1 + and $15,$31,$1 + and $14,$2 + or $15,$14 # Maj(a,b,c) + daddu $13,$16 # +=K[17] + daddu $30,$15 + + daddu $3,$13 + daddu $30,$13 + ld $12,32($29) # prefetch from ring buffer + dsrl $16,$11,7 # Xupdate(18) + daddu $10,$19 # +=X[i+9] + dsll $15,$11,56 + dsrl $14,$11,1 + xor $16,$15 + dsll $15,7 + xor $16,$14 + dsrl $14,$11,8 + xor $16,$15 + + dsrl $17,$8,6 + xor $16,$14 # sigma0(X[i+1]) + dsll $15,$8,3 + daddu $10,$16 + dsrl $14,$8,19 + xor $17,$15 + dsll $15,42 + xor $17,$14 + dsrl $14,$8,61 + xor $17,$15 + + xor $17,$14 # sigma1(X[i+14]) + daddu $10,$17 + daddu $14,$10,$25 # 18 + dsrl $25,$3,14 + xor $17,$7,$24 + dsll $16,$3,23 + and $17,$3 + dsrl $15,$3,18 + xor $25,$16 + dsll $16,$3,46 + xor $25,$15 + dsrl $15,$3,41 + xor $25,$16 + dsll $16,$3,50 + xor $25,$15 + xor $17,$24 # Ch(e,f,g) + xor $15,$16,$25 # Sigma1(e) + + dsrl $25,$30,28 + daddu $14,$17 + ld $17,144($6) # K[18] + dsll $16,$30,25 + daddu $14,$15 + dsrl $15,$30,34 + xor $25,$16 + dsll $16,$30,30 + xor $25,$15 + dsrl $15,$30,39 + xor $25,$16 + dsll $16,$30,36 + xor $25,$15 + sd $10,16($29) # offload to ring buffer + xor $25,$16 # Sigma0(a) + + or $15,$30,$31 + and $16,$30,$31 + and $15,$1 + or $16,$15 # Maj(a,b,c) + daddu $14,$17 # +=K[18] + daddu $25,$16 + + daddu $2,$14 + daddu $25,$14 + ld $13,40($29) # prefetch from ring buffer + dsrl $17,$12,7 # Xupdate(19) + daddu $11,$20 # +=X[i+9] + dsll $16,$12,56 + dsrl $15,$12,1 + xor $17,$16 + dsll $16,7 + xor $17,$15 + dsrl $15,$12,8 + xor $17,$16 + + dsrl $18,$9,6 + xor $17,$15 # sigma0(X[i+1]) + dsll $16,$9,3 + daddu $11,$17 + dsrl $15,$9,19 + xor $18,$16 + dsll $16,42 + xor $18,$15 + dsrl $15,$9,61 + xor $18,$16 + + xor $18,$15 # sigma1(X[i+14]) + daddu $11,$18 + daddu $15,$11,$24 # 19 + dsrl $24,$2,14 + xor $18,$3,$7 + dsll $17,$2,23 + and $18,$2 + dsrl $16,$2,18 + xor $24,$17 + dsll $17,$2,46 + xor $24,$16 + dsrl $16,$2,41 + xor $24,$17 + dsll $17,$2,50 + xor $24,$16 + xor $18,$7 # Ch(e,f,g) + xor $16,$17,$24 # Sigma1(e) + + dsrl $24,$25,28 + daddu $15,$18 + ld $18,152($6) # K[19] + dsll $17,$25,25 + daddu $15,$16 + dsrl $16,$25,34 + xor $24,$17 + dsll $17,$25,30 + xor $24,$16 + dsrl $16,$25,39 + xor $24,$17 + dsll $17,$25,36 + xor $24,$16 + sd $11,24($29) # offload to ring buffer + xor $24,$17 # Sigma0(a) + + or $16,$25,$30 + and $17,$25,$30 + and $16,$31 + or $17,$16 # Maj(a,b,c) + daddu $15,$18 # +=K[19] + daddu $24,$17 + + daddu $1,$15 + daddu $24,$15 + ld $14,48($29) # prefetch from ring buffer + dsrl $18,$13,7 # Xupdate(20) + daddu $12,$21 # +=X[i+9] + dsll $17,$13,56 + dsrl $16,$13,1 + xor $18,$17 + dsll $17,7 + xor $18,$16 + dsrl $16,$13,8 + xor $18,$17 + + dsrl $19,$10,6 + xor $18,$16 # sigma0(X[i+1]) + dsll $17,$10,3 + daddu $12,$18 + dsrl $16,$10,19 + xor $19,$17 + dsll $17,42 + xor $19,$16 + dsrl $16,$10,61 + xor $19,$17 + + xor $19,$16 # sigma1(X[i+14]) + daddu $12,$19 + daddu $16,$12,$7 # 20 + dsrl $7,$1,14 + xor $19,$2,$3 + dsll $18,$1,23 + and $19,$1 + dsrl $17,$1,18 + xor $7,$18 + dsll $18,$1,46 + xor $7,$17 + dsrl $17,$1,41 + xor $7,$18 + dsll $18,$1,50 + xor $7,$17 + xor $19,$3 # Ch(e,f,g) + xor $17,$18,$7 # Sigma1(e) + + dsrl $7,$24,28 + daddu $16,$19 + ld $19,160($6) # K[20] + dsll $18,$24,25 + daddu $16,$17 + dsrl $17,$24,34 + xor $7,$18 + dsll $18,$24,30 + xor $7,$17 + dsrl $17,$24,39 + xor $7,$18 + dsll $18,$24,36 + xor $7,$17 + sd $12,32($29) # offload to ring buffer + xor $7,$18 # Sigma0(a) + + or $17,$24,$25 + and $18,$24,$25 + and $17,$30 + or $18,$17 # Maj(a,b,c) + daddu $16,$19 # +=K[20] + daddu $7,$18 + + daddu $31,$16 + daddu $7,$16 + ld $15,56($29) # prefetch from ring buffer + dsrl $19,$14,7 # Xupdate(21) + daddu $13,$22 # +=X[i+9] + dsll $18,$14,56 + dsrl $17,$14,1 + xor $19,$18 + dsll $18,7 + xor $19,$17 + dsrl $17,$14,8 + xor $19,$18 + + dsrl $20,$11,6 + xor $19,$17 # sigma0(X[i+1]) + dsll $18,$11,3 + daddu $13,$19 + dsrl $17,$11,19 + xor $20,$18 + dsll $18,42 + xor $20,$17 + dsrl $17,$11,61 + xor $20,$18 + + xor $20,$17 # sigma1(X[i+14]) + daddu $13,$20 + daddu $17,$13,$3 # 21 + dsrl $3,$31,14 + xor $20,$1,$2 + dsll $19,$31,23 + and $20,$31 + dsrl $18,$31,18 + xor $3,$19 + dsll $19,$31,46 + xor $3,$18 + dsrl $18,$31,41 + xor $3,$19 + dsll $19,$31,50 + xor $3,$18 + xor $20,$2 # Ch(e,f,g) + xor $18,$19,$3 # Sigma1(e) + + dsrl $3,$7,28 + daddu $17,$20 + ld $20,168($6) # K[21] + dsll $19,$7,25 + daddu $17,$18 + dsrl $18,$7,34 + xor $3,$19 + dsll $19,$7,30 + xor $3,$18 + dsrl $18,$7,39 + xor $3,$19 + dsll $19,$7,36 + xor $3,$18 + sd $13,40($29) # offload to ring buffer + xor $3,$19 # Sigma0(a) + + or $18,$7,$24 + and $19,$7,$24 + and $18,$25 + or $19,$18 # Maj(a,b,c) + daddu $17,$20 # +=K[21] + daddu $3,$19 + + daddu $30,$17 + daddu $3,$17 + ld $16,64($29) # prefetch from ring buffer + dsrl $20,$15,7 # Xupdate(22) + daddu $14,$23 # +=X[i+9] + dsll $19,$15,56 + dsrl $18,$15,1 + xor $20,$19 + dsll $19,7 + xor $20,$18 + dsrl $18,$15,8 + xor $20,$19 + + dsrl $21,$12,6 + xor $20,$18 # sigma0(X[i+1]) + dsll $19,$12,3 + daddu $14,$20 + dsrl $18,$12,19 + xor $21,$19 + dsll $19,42 + xor $21,$18 + dsrl $18,$12,61 + xor $21,$19 + + xor $21,$18 # sigma1(X[i+14]) + daddu $14,$21 + daddu $18,$14,$2 # 22 + dsrl $2,$30,14 + xor $21,$31,$1 + dsll $20,$30,23 + and $21,$30 + dsrl $19,$30,18 + xor $2,$20 + dsll $20,$30,46 + xor $2,$19 + dsrl $19,$30,41 + xor $2,$20 + dsll $20,$30,50 + xor $2,$19 + xor $21,$1 # Ch(e,f,g) + xor $19,$20,$2 # Sigma1(e) + + dsrl $2,$3,28 + daddu $18,$21 + ld $21,176($6) # K[22] + dsll $20,$3,25 + daddu $18,$19 + dsrl $19,$3,34 + xor $2,$20 + dsll $20,$3,30 + xor $2,$19 + dsrl $19,$3,39 + xor $2,$20 + dsll $20,$3,36 + xor $2,$19 + sd $14,48($29) # offload to ring buffer + xor $2,$20 # Sigma0(a) + + or $19,$3,$7 + and $20,$3,$7 + and $19,$24 + or $20,$19 # Maj(a,b,c) + daddu $18,$21 # +=K[22] + daddu $2,$20 + + daddu $25,$18 + daddu $2,$18 + ld $17,72($29) # prefetch from ring buffer + dsrl $21,$16,7 # Xupdate(23) + daddu $15,$8 # +=X[i+9] + dsll $20,$16,56 + dsrl $19,$16,1 + xor $21,$20 + dsll $20,7 + xor $21,$19 + dsrl $19,$16,8 + xor $21,$20 + + dsrl $22,$13,6 + xor $21,$19 # sigma0(X[i+1]) + dsll $20,$13,3 + daddu $15,$21 + dsrl $19,$13,19 + xor $22,$20 + dsll $20,42 + xor $22,$19 + dsrl $19,$13,61 + xor $22,$20 + + xor $22,$19 # sigma1(X[i+14]) + daddu $15,$22 + daddu $19,$15,$1 # 23 + dsrl $1,$25,14 + xor $22,$30,$31 + dsll $21,$25,23 + and $22,$25 + dsrl $20,$25,18 + xor $1,$21 + dsll $21,$25,46 + xor $1,$20 + dsrl $20,$25,41 + xor $1,$21 + dsll $21,$25,50 + xor $1,$20 + xor $22,$31 # Ch(e,f,g) + xor $20,$21,$1 # Sigma1(e) + + dsrl $1,$2,28 + daddu $19,$22 + ld $22,184($6) # K[23] + dsll $21,$2,25 + daddu $19,$20 + dsrl $20,$2,34 + xor $1,$21 + dsll $21,$2,30 + xor $1,$20 + dsrl $20,$2,39 + xor $1,$21 + dsll $21,$2,36 + xor $1,$20 + sd $15,56($29) # offload to ring buffer + xor $1,$21 # Sigma0(a) + + or $20,$2,$3 + and $21,$2,$3 + and $20,$7 + or $21,$20 # Maj(a,b,c) + daddu $19,$22 # +=K[23] + daddu $1,$21 + + daddu $24,$19 + daddu $1,$19 + ld $18,80($29) # prefetch from ring buffer + dsrl $22,$17,7 # Xupdate(24) + daddu $16,$9 # +=X[i+9] + dsll $21,$17,56 + dsrl $20,$17,1 + xor $22,$21 + dsll $21,7 + xor $22,$20 + dsrl $20,$17,8 + xor $22,$21 + + dsrl $23,$14,6 + xor $22,$20 # sigma0(X[i+1]) + dsll $21,$14,3 + daddu $16,$22 + dsrl $20,$14,19 + xor $23,$21 + dsll $21,42 + xor $23,$20 + dsrl $20,$14,61 + xor $23,$21 + + xor $23,$20 # sigma1(X[i+14]) + daddu $16,$23 + daddu $20,$16,$31 # 24 + dsrl $31,$24,14 + xor $23,$25,$30 + dsll $22,$24,23 + and $23,$24 + dsrl $21,$24,18 + xor $31,$22 + dsll $22,$24,46 + xor $31,$21 + dsrl $21,$24,41 + xor $31,$22 + dsll $22,$24,50 + xor $31,$21 + xor $23,$30 # Ch(e,f,g) + xor $21,$22,$31 # Sigma1(e) + + dsrl $31,$1,28 + daddu $20,$23 + ld $23,192($6) # K[24] + dsll $22,$1,25 + daddu $20,$21 + dsrl $21,$1,34 + xor $31,$22 + dsll $22,$1,30 + xor $31,$21 + dsrl $21,$1,39 + xor $31,$22 + dsll $22,$1,36 + xor $31,$21 + sd $16,64($29) # offload to ring buffer + xor $31,$22 # Sigma0(a) + + or $21,$1,$2 + and $22,$1,$2 + and $21,$3 + or $22,$21 # Maj(a,b,c) + daddu $20,$23 # +=K[24] + daddu $31,$22 + + daddu $7,$20 + daddu $31,$20 + ld $19,88($29) # prefetch from ring buffer + dsrl $23,$18,7 # Xupdate(25) + daddu $17,$10 # +=X[i+9] + dsll $22,$18,56 + dsrl $21,$18,1 + xor $23,$22 + dsll $22,7 + xor $23,$21 + dsrl $21,$18,8 + xor $23,$22 + + dsrl $8,$15,6 + xor $23,$21 # sigma0(X[i+1]) + dsll $22,$15,3 + daddu $17,$23 + dsrl $21,$15,19 + xor $8,$22 + dsll $22,42 + xor $8,$21 + dsrl $21,$15,61 + xor $8,$22 + + xor $8,$21 # sigma1(X[i+14]) + daddu $17,$8 + daddu $21,$17,$30 # 25 + dsrl $30,$7,14 + xor $8,$24,$25 + dsll $23,$7,23 + and $8,$7 + dsrl $22,$7,18 + xor $30,$23 + dsll $23,$7,46 + xor $30,$22 + dsrl $22,$7,41 + xor $30,$23 + dsll $23,$7,50 + xor $30,$22 + xor $8,$25 # Ch(e,f,g) + xor $22,$23,$30 # Sigma1(e) + + dsrl $30,$31,28 + daddu $21,$8 + ld $8,200($6) # K[25] + dsll $23,$31,25 + daddu $21,$22 + dsrl $22,$31,34 + xor $30,$23 + dsll $23,$31,30 + xor $30,$22 + dsrl $22,$31,39 + xor $30,$23 + dsll $23,$31,36 + xor $30,$22 + sd $17,72($29) # offload to ring buffer + xor $30,$23 # Sigma0(a) + + or $22,$31,$1 + and $23,$31,$1 + and $22,$2 + or $23,$22 # Maj(a,b,c) + daddu $21,$8 # +=K[25] + daddu $30,$23 + + daddu $3,$21 + daddu $30,$21 + ld $20,96($29) # prefetch from ring buffer + dsrl $8,$19,7 # Xupdate(26) + daddu $18,$11 # +=X[i+9] + dsll $23,$19,56 + dsrl $22,$19,1 + xor $8,$23 + dsll $23,7 + xor $8,$22 + dsrl $22,$19,8 + xor $8,$23 + + dsrl $9,$16,6 + xor $8,$22 # sigma0(X[i+1]) + dsll $23,$16,3 + daddu $18,$8 + dsrl $22,$16,19 + xor $9,$23 + dsll $23,42 + xor $9,$22 + dsrl $22,$16,61 + xor $9,$23 + + xor $9,$22 # sigma1(X[i+14]) + daddu $18,$9 + daddu $22,$18,$25 # 26 + dsrl $25,$3,14 + xor $9,$7,$24 + dsll $8,$3,23 + and $9,$3 + dsrl $23,$3,18 + xor $25,$8 + dsll $8,$3,46 + xor $25,$23 + dsrl $23,$3,41 + xor $25,$8 + dsll $8,$3,50 + xor $25,$23 + xor $9,$24 # Ch(e,f,g) + xor $23,$8,$25 # Sigma1(e) + + dsrl $25,$30,28 + daddu $22,$9 + ld $9,208($6) # K[26] + dsll $8,$30,25 + daddu $22,$23 + dsrl $23,$30,34 + xor $25,$8 + dsll $8,$30,30 + xor $25,$23 + dsrl $23,$30,39 + xor $25,$8 + dsll $8,$30,36 + xor $25,$23 + sd $18,80($29) # offload to ring buffer + xor $25,$8 # Sigma0(a) + + or $23,$30,$31 + and $8,$30,$31 + and $23,$1 + or $8,$23 # Maj(a,b,c) + daddu $22,$9 # +=K[26] + daddu $25,$8 + + daddu $2,$22 + daddu $25,$22 + ld $21,104($29) # prefetch from ring buffer + dsrl $9,$20,7 # Xupdate(27) + daddu $19,$12 # +=X[i+9] + dsll $8,$20,56 + dsrl $23,$20,1 + xor $9,$8 + dsll $8,7 + xor $9,$23 + dsrl $23,$20,8 + xor $9,$8 + + dsrl $10,$17,6 + xor $9,$23 # sigma0(X[i+1]) + dsll $8,$17,3 + daddu $19,$9 + dsrl $23,$17,19 + xor $10,$8 + dsll $8,42 + xor $10,$23 + dsrl $23,$17,61 + xor $10,$8 + + xor $10,$23 # sigma1(X[i+14]) + daddu $19,$10 + daddu $23,$19,$24 # 27 + dsrl $24,$2,14 + xor $10,$3,$7 + dsll $9,$2,23 + and $10,$2 + dsrl $8,$2,18 + xor $24,$9 + dsll $9,$2,46 + xor $24,$8 + dsrl $8,$2,41 + xor $24,$9 + dsll $9,$2,50 + xor $24,$8 + xor $10,$7 # Ch(e,f,g) + xor $8,$9,$24 # Sigma1(e) + + dsrl $24,$25,28 + daddu $23,$10 + ld $10,216($6) # K[27] + dsll $9,$25,25 + daddu $23,$8 + dsrl $8,$25,34 + xor $24,$9 + dsll $9,$25,30 + xor $24,$8 + dsrl $8,$25,39 + xor $24,$9 + dsll $9,$25,36 + xor $24,$8 + sd $19,88($29) # offload to ring buffer + xor $24,$9 # Sigma0(a) + + or $8,$25,$30 + and $9,$25,$30 + and $8,$31 + or $9,$8 # Maj(a,b,c) + daddu $23,$10 # +=K[27] + daddu $24,$9 + + daddu $1,$23 + daddu $24,$23 + ld $22,112($29) # prefetch from ring buffer + dsrl $10,$21,7 # Xupdate(28) + daddu $20,$13 # +=X[i+9] + dsll $9,$21,56 + dsrl $8,$21,1 + xor $10,$9 + dsll $9,7 + xor $10,$8 + dsrl $8,$21,8 + xor $10,$9 + + dsrl $11,$18,6 + xor $10,$8 # sigma0(X[i+1]) + dsll $9,$18,3 + daddu $20,$10 + dsrl $8,$18,19 + xor $11,$9 + dsll $9,42 + xor $11,$8 + dsrl $8,$18,61 + xor $11,$9 + + xor $11,$8 # sigma1(X[i+14]) + daddu $20,$11 + daddu $8,$20,$7 # 28 + dsrl $7,$1,14 + xor $11,$2,$3 + dsll $10,$1,23 + and $11,$1 + dsrl $9,$1,18 + xor $7,$10 + dsll $10,$1,46 + xor $7,$9 + dsrl $9,$1,41 + xor $7,$10 + dsll $10,$1,50 + xor $7,$9 + xor $11,$3 # Ch(e,f,g) + xor $9,$10,$7 # Sigma1(e) + + dsrl $7,$24,28 + daddu $8,$11 + ld $11,224($6) # K[28] + dsll $10,$24,25 + daddu $8,$9 + dsrl $9,$24,34 + xor $7,$10 + dsll $10,$24,30 + xor $7,$9 + dsrl $9,$24,39 + xor $7,$10 + dsll $10,$24,36 + xor $7,$9 + sd $20,96($29) # offload to ring buffer + xor $7,$10 # Sigma0(a) + + or $9,$24,$25 + and $10,$24,$25 + and $9,$30 + or $10,$9 # Maj(a,b,c) + daddu $8,$11 # +=K[28] + daddu $7,$10 + + daddu $31,$8 + daddu $7,$8 + ld $23,120($29) # prefetch from ring buffer + dsrl $11,$22,7 # Xupdate(29) + daddu $21,$14 # +=X[i+9] + dsll $10,$22,56 + dsrl $9,$22,1 + xor $11,$10 + dsll $10,7 + xor $11,$9 + dsrl $9,$22,8 + xor $11,$10 + + dsrl $12,$19,6 + xor $11,$9 # sigma0(X[i+1]) + dsll $10,$19,3 + daddu $21,$11 + dsrl $9,$19,19 + xor $12,$10 + dsll $10,42 + xor $12,$9 + dsrl $9,$19,61 + xor $12,$10 + + xor $12,$9 # sigma1(X[i+14]) + daddu $21,$12 + daddu $9,$21,$3 # 29 + dsrl $3,$31,14 + xor $12,$1,$2 + dsll $11,$31,23 + and $12,$31 + dsrl $10,$31,18 + xor $3,$11 + dsll $11,$31,46 + xor $3,$10 + dsrl $10,$31,41 + xor $3,$11 + dsll $11,$31,50 + xor $3,$10 + xor $12,$2 # Ch(e,f,g) + xor $10,$11,$3 # Sigma1(e) + + dsrl $3,$7,28 + daddu $9,$12 + ld $12,232($6) # K[29] + dsll $11,$7,25 + daddu $9,$10 + dsrl $10,$7,34 + xor $3,$11 + dsll $11,$7,30 + xor $3,$10 + dsrl $10,$7,39 + xor $3,$11 + dsll $11,$7,36 + xor $3,$10 + sd $21,104($29) # offload to ring buffer + xor $3,$11 # Sigma0(a) + + or $10,$7,$24 + and $11,$7,$24 + and $10,$25 + or $11,$10 # Maj(a,b,c) + daddu $9,$12 # +=K[29] + daddu $3,$11 + + daddu $30,$9 + daddu $3,$9 + ld $8,0($29) # prefetch from ring buffer + dsrl $12,$23,7 # Xupdate(30) + daddu $22,$15 # +=X[i+9] + dsll $11,$23,56 + dsrl $10,$23,1 + xor $12,$11 + dsll $11,7 + xor $12,$10 + dsrl $10,$23,8 + xor $12,$11 + + dsrl $13,$20,6 + xor $12,$10 # sigma0(X[i+1]) + dsll $11,$20,3 + daddu $22,$12 + dsrl $10,$20,19 + xor $13,$11 + dsll $11,42 + xor $13,$10 + dsrl $10,$20,61 + xor $13,$11 + + xor $13,$10 # sigma1(X[i+14]) + daddu $22,$13 + daddu $10,$22,$2 # 30 + dsrl $2,$30,14 + xor $13,$31,$1 + dsll $12,$30,23 + and $13,$30 + dsrl $11,$30,18 + xor $2,$12 + dsll $12,$30,46 + xor $2,$11 + dsrl $11,$30,41 + xor $2,$12 + dsll $12,$30,50 + xor $2,$11 + xor $13,$1 # Ch(e,f,g) + xor $11,$12,$2 # Sigma1(e) + + dsrl $2,$3,28 + daddu $10,$13 + ld $13,240($6) # K[30] + dsll $12,$3,25 + daddu $10,$11 + dsrl $11,$3,34 + xor $2,$12 + dsll $12,$3,30 + xor $2,$11 + dsrl $11,$3,39 + xor $2,$12 + dsll $12,$3,36 + xor $2,$11 + sd $22,112($29) # offload to ring buffer + xor $2,$12 # Sigma0(a) + + or $11,$3,$7 + and $12,$3,$7 + and $11,$24 + or $12,$11 # Maj(a,b,c) + daddu $10,$13 # +=K[30] + daddu $2,$12 + + daddu $25,$10 + daddu $2,$10 + ld $9,8($29) # prefetch from ring buffer + dsrl $13,$8,7 # Xupdate(31) + daddu $23,$16 # +=X[i+9] + dsll $12,$8,56 + dsrl $11,$8,1 + xor $13,$12 + dsll $12,7 + xor $13,$11 + dsrl $11,$8,8 + xor $13,$12 + + dsrl $14,$21,6 + xor $13,$11 # sigma0(X[i+1]) + dsll $12,$21,3 + daddu $23,$13 + dsrl $11,$21,19 + xor $14,$12 + dsll $12,42 + xor $14,$11 + dsrl $11,$21,61 + xor $14,$12 + + xor $14,$11 # sigma1(X[i+14]) + daddu $23,$14 + daddu $11,$23,$1 # 31 + dsrl $1,$25,14 + xor $14,$30,$31 + dsll $13,$25,23 + and $14,$25 + dsrl $12,$25,18 + xor $1,$13 + dsll $13,$25,46 + xor $1,$12 + dsrl $12,$25,41 + xor $1,$13 + dsll $13,$25,50 + xor $1,$12 + xor $14,$31 # Ch(e,f,g) + xor $12,$13,$1 # Sigma1(e) + + dsrl $1,$2,28 + daddu $11,$14 + ld $14,248($6) # K[31] + dsll $13,$2,25 + daddu $11,$12 + dsrl $12,$2,34 + xor $1,$13 + dsll $13,$2,30 + xor $1,$12 + dsrl $12,$2,39 + xor $1,$13 + dsll $13,$2,36 + xor $1,$12 + sd $23,120($29) # offload to ring buffer + xor $1,$13 # Sigma0(a) + + or $12,$2,$3 + and $13,$2,$3 + and $12,$7 + or $13,$12 # Maj(a,b,c) + daddu $11,$14 # +=K[31] + daddu $1,$13 + + daddu $24,$11 + daddu $1,$11 + ld $10,16($29) # prefetch from ring buffer + and $14,0xfff + li $15,2071 + .set noreorder + bne $14,$15,.L16_xx + add $6,16*8 # Ktbl+=16 + + lw $23,16*8($29) # restore pointer to the end of input + ld $8,0*8($4) + ld $9,1*8($4) + ld $10,2*8($4) + add $5,16*8 + ld $11,3*8($4) + daddu $1,$8 + ld $12,4*8($4) + daddu $2,$9 + ld $13,5*8($4) + daddu $3,$10 + ld $14,6*8($4) + daddu $7,$11 + ld $15,7*8($4) + daddu $24,$12 + sd $1,0*8($4) + daddu $25,$13 + sd $2,1*8($4) + daddu $30,$14 + sd $3,2*8($4) + daddu $31,$15 + sd $7,3*8($4) + sd $24,4*8($4) + sd $25,5*8($4) + sd $30,6*8($4) + sd $31,7*8($4) + + bne $5,$23,.Loop + sub $6,512 # rewind $6 + + lw $31,192-1*4($29) + lw $30,192-2*4($29) + lw $23,192-3*4($29) + lw $22,192-4*4($29) + lw $21,192-5*4($29) + lw $20,192-6*4($29) + lw $19,192-7*4($29) + lw $18,192-8*4($29) + lw $17,192-9*4($29) + lw $16,192-10*4($29) + jr $31 + add $29,192 +.end sha512_block_data_order + +.rdata +.align 5 +K512: + .dword 0x428a2f98d728ae22, 0x7137449123ef65cd + .dword 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc + .dword 0x3956c25bf348b538, 0x59f111f1b605d019 + .dword 0x923f82a4af194f9b, 0xab1c5ed5da6d8118 + .dword 0xd807aa98a3030242, 0x12835b0145706fbe + .dword 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2 + .dword 0x72be5d74f27b896f, 0x80deb1fe3b1696b1 + .dword 0x9bdc06a725c71235, 0xc19bf174cf692694 + .dword 0xe49b69c19ef14ad2, 0xefbe4786384f25e3 + .dword 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65 + .dword 0x2de92c6f592b0275, 0x4a7484aa6ea6e483 + .dword 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5 + .dword 0x983e5152ee66dfab, 0xa831c66d2db43210 + .dword 0xb00327c898fb213f, 0xbf597fc7beef0ee4 + .dword 0xc6e00bf33da88fc2, 0xd5a79147930aa725 + .dword 0x06ca6351e003826f, 0x142929670a0e6e70 + .dword 0x27b70a8546d22ffc, 0x2e1b21385c26c926 + .dword 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df + .dword 0x650a73548baf63de, 0x766a0abb3c77b2a8 + .dword 0x81c2c92e47edaee6, 0x92722c851482353b + .dword 0xa2bfe8a14cf10364, 0xa81a664bbc423001 + .dword 0xc24b8b70d0f89791, 0xc76c51a30654be30 + .dword 0xd192e819d6ef5218, 0xd69906245565a910 + .dword 0xf40e35855771202a, 0x106aa07032bbd1b8 + .dword 0x19a4c116b8d2d0c8, 0x1e376c085141ab53 + .dword 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8 + .dword 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb + .dword 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3 + .dword 0x748f82ee5defb2fc, 0x78a5636f43172f60 + .dword 0x84c87814a1f0ab72, 0x8cc702081a6439ec + .dword 0x90befffa23631e28, 0xa4506cebde82bde9 + .dword 0xbef9a3f7b2c67915, 0xc67178f2e372532b + .dword 0xca273eceea26619c, 0xd186b8c721c0c207 + .dword 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178 + .dword 0x06f067aa72176fba, 0x0a637dc5a2c898a6 + .dword 0x113f9804bef90dae, 0x1b710b35131c471b + .dword 0x28db77f523047d84, 0x32caab7b40c72493 + .dword 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c + .dword 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a + .dword 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +.asciiz "SHA512 for MIPS, CRYPTOGAMS by " +.align 5 + +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/sha/sha512.c b/Libraries/libressl/crypto/sha/sha512.c new file mode 100644 index 000000000..360a5c29f --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha512.c @@ -0,0 +1,580 @@ +/* $OpenBSD: sha512.c,v 1.41 2023/07/08 12:24:10 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +#include +#include +#include + +#include + +#include +#include + +#include "crypto_internal.h" +#include "sha_internal.h" + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) + +/* Ensure that SHA_LONG64 and uint64_t are equivalent. */ +CTASSERT(sizeof(SHA_LONG64) == sizeof(uint64_t)); + +#ifdef SHA512_ASM +void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); +#endif + +#ifndef SHA512_ASM +static const SHA_LONG64 K512[80] = { + U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd), + U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc), + U64(0x3956c25bf348b538), U64(0x59f111f1b605d019), + U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118), + U64(0xd807aa98a3030242), U64(0x12835b0145706fbe), + U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2), + U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1), + U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694), + U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3), + U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65), + U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483), + U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5), + U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210), + U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4), + U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725), + U64(0x06ca6351e003826f), U64(0x142929670a0e6e70), + U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926), + U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df), + U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8), + U64(0x81c2c92e47edaee6), U64(0x92722c851482353b), + U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001), + U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30), + U64(0xd192e819d6ef5218), U64(0xd69906245565a910), + U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8), + U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53), + U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8), + U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb), + U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3), + U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60), + U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec), + U64(0x90befffa23631e28), U64(0xa4506cebde82bde9), + U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b), + U64(0xca273eceea26619c), U64(0xd186b8c721c0c207), + U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178), + U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6), + U64(0x113f9804bef90dae), U64(0x1b710b35131c471b), + U64(0x28db77f523047d84), U64(0x32caab7b40c72493), + U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c), + U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a), + U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817), +}; + +static inline SHA_LONG64 +Sigma0(SHA_LONG64 x) +{ + return crypto_ror_u64(x, 28) ^ crypto_ror_u64(x, 34) ^ + crypto_ror_u64(x, 39); +} + +static inline SHA_LONG64 +Sigma1(SHA_LONG64 x) +{ + return crypto_ror_u64(x, 14) ^ crypto_ror_u64(x, 18) ^ + crypto_ror_u64(x, 41); +} + +static inline SHA_LONG64 +sigma0(SHA_LONG64 x) +{ + return crypto_ror_u64(x, 1) ^ crypto_ror_u64(x, 8) ^ (x >> 7); +} + +static inline SHA_LONG64 +sigma1(SHA_LONG64 x) +{ + return crypto_ror_u64(x, 19) ^ crypto_ror_u64(x, 61) ^ (x >> 6); +} + +static inline SHA_LONG64 +Ch(SHA_LONG64 x, SHA_LONG64 y, SHA_LONG64 z) +{ + return (x & y) ^ (~x & z); +} + +static inline SHA_LONG64 +Maj(SHA_LONG64 x, SHA_LONG64 y, SHA_LONG64 z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} + +static inline void +sha512_msg_schedule_update(SHA_LONG64 *W0, SHA_LONG64 W1, + SHA_LONG64 W9, SHA_LONG64 W14) +{ + *W0 = sigma1(W14) + W9 + sigma0(W1) + *W0; +} + +static inline void +sha512_round(SHA_LONG64 *a, SHA_LONG64 *b, SHA_LONG64 *c, SHA_LONG64 *d, + SHA_LONG64 *e, SHA_LONG64 *f, SHA_LONG64 *g, SHA_LONG64 *h, + SHA_LONG64 Kt, SHA_LONG64 Wt) +{ + SHA_LONG64 T1, T2; + + T1 = *h + Sigma1(*e) + Ch(*e, *f, *g) + Kt + Wt; + T2 = Sigma0(*a) + Maj(*a, *b, *c); + + *h = *g; + *g = *f; + *f = *e; + *e = *d + T1; + *d = *c; + *c = *b; + *b = *a; + *a = T1 + T2; +} + +static void +sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num) +{ + const uint8_t *in = _in; + const SHA_LONG64 *in64; + SHA_LONG64 a, b, c, d, e, f, g, h; + SHA_LONG64 X[16]; + int i; + + while (num--) { + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + if ((size_t)in % sizeof(SHA_LONG64) == 0) { + /* Input is 64 bit aligned. */ + in64 = (const SHA_LONG64 *)in; + X[0] = be64toh(in64[0]); + X[1] = be64toh(in64[1]); + X[2] = be64toh(in64[2]); + X[3] = be64toh(in64[3]); + X[4] = be64toh(in64[4]); + X[5] = be64toh(in64[5]); + X[6] = be64toh(in64[6]); + X[7] = be64toh(in64[7]); + X[8] = be64toh(in64[8]); + X[9] = be64toh(in64[9]); + X[10] = be64toh(in64[10]); + X[11] = be64toh(in64[11]); + X[12] = be64toh(in64[12]); + X[13] = be64toh(in64[13]); + X[14] = be64toh(in64[14]); + X[15] = be64toh(in64[15]); + } else { + /* Input is not 64 bit aligned. */ + X[0] = crypto_load_be64toh(&in[0 * 8]); + X[1] = crypto_load_be64toh(&in[1 * 8]); + X[2] = crypto_load_be64toh(&in[2 * 8]); + X[3] = crypto_load_be64toh(&in[3 * 8]); + X[4] = crypto_load_be64toh(&in[4 * 8]); + X[5] = crypto_load_be64toh(&in[5 * 8]); + X[6] = crypto_load_be64toh(&in[6 * 8]); + X[7] = crypto_load_be64toh(&in[7 * 8]); + X[8] = crypto_load_be64toh(&in[8 * 8]); + X[9] = crypto_load_be64toh(&in[9 * 8]); + X[10] = crypto_load_be64toh(&in[10 * 8]); + X[11] = crypto_load_be64toh(&in[11 * 8]); + X[12] = crypto_load_be64toh(&in[12 * 8]); + X[13] = crypto_load_be64toh(&in[13 * 8]); + X[14] = crypto_load_be64toh(&in[14 * 8]); + X[15] = crypto_load_be64toh(&in[15 * 8]); + } + in += SHA512_CBLOCK; + + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[0], X[0]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[1], X[1]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[2], X[2]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[3], X[3]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[4], X[4]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[5], X[5]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[6], X[6]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[7], X[7]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[8], X[8]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[9], X[9]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[10], X[10]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[11], X[11]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[12], X[12]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[13], X[13]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[14], X[14]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[15], X[15]); + + for (i = 16; i < 80; i += 16) { + sha512_msg_schedule_update(&X[0], X[1], X[9], X[14]); + sha512_msg_schedule_update(&X[1], X[2], X[10], X[15]); + sha512_msg_schedule_update(&X[2], X[3], X[11], X[0]); + sha512_msg_schedule_update(&X[3], X[4], X[12], X[1]); + sha512_msg_schedule_update(&X[4], X[5], X[13], X[2]); + sha512_msg_schedule_update(&X[5], X[6], X[14], X[3]); + sha512_msg_schedule_update(&X[6], X[7], X[15], X[4]); + sha512_msg_schedule_update(&X[7], X[8], X[0], X[5]); + sha512_msg_schedule_update(&X[8], X[9], X[1], X[6]); + sha512_msg_schedule_update(&X[9], X[10], X[2], X[7]); + sha512_msg_schedule_update(&X[10], X[11], X[3], X[8]); + sha512_msg_schedule_update(&X[11], X[12], X[4], X[9]); + sha512_msg_schedule_update(&X[12], X[13], X[5], X[10]); + sha512_msg_schedule_update(&X[13], X[14], X[6], X[11]); + sha512_msg_schedule_update(&X[14], X[15], X[7], X[12]); + sha512_msg_schedule_update(&X[15], X[0], X[8], X[13]); + + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 0], X[0]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 1], X[1]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 2], X[2]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 3], X[3]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 4], X[4]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 5], X[5]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 6], X[6]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 7], X[7]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 8], X[8]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 9], X[9]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 10], X[10]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 11], X[11]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 12], X[12]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 13], X[13]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 14], X[14]); + sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 15], X[15]); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + } +} + +#endif /* SHA512_ASM */ + +int +SHA384_Init(SHA512_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + c->h[0] = U64(0xcbbb9d5dc1059ed8); + c->h[1] = U64(0x629a292a367cd507); + c->h[2] = U64(0x9159015a3070dd17); + c->h[3] = U64(0x152fecd8f70e5939); + c->h[4] = U64(0x67332667ffc00b31); + c->h[5] = U64(0x8eb44a8768581511); + c->h[6] = U64(0xdb0c2e0d64f98fa7); + c->h[7] = U64(0x47b5481dbefa4fa4); + + c->md_len = SHA384_DIGEST_LENGTH; + + return 1; +} +LCRYPTO_ALIAS(SHA384_Init); + +int +SHA384_Update(SHA512_CTX *c, const void *data, size_t len) +{ + return SHA512_Update(c, data, len); +} +LCRYPTO_ALIAS(SHA384_Update); + +int +SHA384_Final(unsigned char *md, SHA512_CTX *c) +{ + return SHA512_Final(md, c); +} +LCRYPTO_ALIAS(SHA384_Final); + +unsigned char * +SHA384(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA512_CTX c; + static unsigned char m[SHA384_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + + SHA384_Init(&c); + SHA512_Update(&c, d, n); + SHA512_Final(md, &c); + + explicit_bzero(&c, sizeof(c)); + + return (md); +} +LCRYPTO_ALIAS(SHA384); + +int +SHA512_Init(SHA512_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + c->h[0] = U64(0x6a09e667f3bcc908); + c->h[1] = U64(0xbb67ae8584caa73b); + c->h[2] = U64(0x3c6ef372fe94f82b); + c->h[3] = U64(0xa54ff53a5f1d36f1); + c->h[4] = U64(0x510e527fade682d1); + c->h[5] = U64(0x9b05688c2b3e6c1f); + c->h[6] = U64(0x1f83d9abfb41bd6b); + c->h[7] = U64(0x5be0cd19137e2179); + + c->md_len = SHA512_DIGEST_LENGTH; + + return 1; +} +LCRYPTO_ALIAS(SHA512_Init); + +void +SHA512_Transform(SHA512_CTX *c, const unsigned char *data) +{ + sha512_block_data_order(c, data, 1); +} +LCRYPTO_ALIAS(SHA512_Transform); + +int +SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) +{ + const unsigned char *data = _data; + unsigned char *p = c->u.p; + SHA_LONG64 l; + + if (len == 0) + return 1; + + l = (c->Nl + (((SHA_LONG64)len) << 3))&U64(0xffffffffffffffff); + if (l < c->Nl) + c->Nh++; + if (sizeof(len) >= 8) + c->Nh += (((SHA_LONG64)len) >> 61); + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->u) - c->num; + + if (len < n) { + memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return 1; + } else{ + memcpy(p + c->num, data, n); + c->num = 0; + len -= n; + data += n; + sha512_block_data_order(c, p, 1); + } + } + + if (len >= sizeof(c->u)) { + sha512_block_data_order(c, data, len/sizeof(c->u)); + data += len; + len %= sizeof(c->u); + data -= len; + } + + if (len != 0) { + memcpy(p, data, len); + c->num = (int)len; + } + + return 1; +} +LCRYPTO_ALIAS(SHA512_Update); + +int +SHA512_Final(unsigned char *md, SHA512_CTX *c) +{ + unsigned char *p = (unsigned char *)c->u.p; + size_t n = c->num; + + p[n]=0x80; /* There always is a room for one */ + n++; + if (n > (sizeof(c->u) - 16)) { + memset(p + n, 0, sizeof(c->u) - n); + n = 0; + sha512_block_data_order(c, p, 1); + } + + memset(p + n, 0, sizeof(c->u) - 16 - n); + c->u.d[SHA_LBLOCK - 2] = htobe64(c->Nh); + c->u.d[SHA_LBLOCK - 1] = htobe64(c->Nl); + + sha512_block_data_order(c, p, 1); + + if (md == NULL) + return 0; + + /* Let compiler decide if it's appropriate to unroll... */ + switch (c->md_len) { + case SHA512_224_DIGEST_LENGTH: + for (n = 0; n < SHA512_224_DIGEST_LENGTH/8; n++) { + crypto_store_htobe64(md, c->h[n]); + md += 8; + } + crypto_store_htobe32(md, c->h[n] >> 32); + break; + case SHA512_256_DIGEST_LENGTH: + for (n = 0; n < SHA512_256_DIGEST_LENGTH/8; n++) { + crypto_store_htobe64(md, c->h[n]); + md += 8; + } + break; + case SHA384_DIGEST_LENGTH: + for (n = 0; n < SHA384_DIGEST_LENGTH/8; n++) { + crypto_store_htobe64(md, c->h[n]); + md += 8; + } + break; + case SHA512_DIGEST_LENGTH: + for (n = 0; n < SHA512_DIGEST_LENGTH/8; n++) { + crypto_store_htobe64(md, c->h[n]); + md += 8; + } + break; + default: + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(SHA512_Final); + +unsigned char * +SHA512(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA512_CTX c; + static unsigned char m[SHA512_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + + SHA512_Init(&c); + SHA512_Update(&c, d, n); + SHA512_Final(md, &c); + + explicit_bzero(&c, sizeof(c)); + + return (md); +} +LCRYPTO_ALIAS(SHA512); + +int +SHA512_224_Init(SHA512_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + /* FIPS 180-4 section 5.3.6.1. */ + c->h[0] = U64(0x8c3d37c819544da2); + c->h[1] = U64(0x73e1996689dcd4d6); + c->h[2] = U64(0x1dfab7ae32ff9c82); + c->h[3] = U64(0x679dd514582f9fcf); + c->h[4] = U64(0x0f6d2b697bd44da8); + c->h[5] = U64(0x77e36f7304c48942); + c->h[6] = U64(0x3f9d85a86a1d36c8); + c->h[7] = U64(0x1112e6ad91d692a1); + + c->md_len = SHA512_224_DIGEST_LENGTH; + + return 1; +} + +int +SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len) +{ + return SHA512_Update(c, data, len); +} + +int +SHA512_224_Final(unsigned char *md, SHA512_CTX *c) +{ + return SHA512_Final(md, c); +} + +int +SHA512_256_Init(SHA512_CTX *c) +{ + memset(c, 0, sizeof(*c)); + + /* FIPS 180-4 section 5.3.6.2. */ + c->h[0] = U64(0x22312194fc2bf72c); + c->h[1] = U64(0x9f555fa3c84c64c2); + c->h[2] = U64(0x2393b86b6f53b151); + c->h[3] = U64(0x963877195940eabd); + c->h[4] = U64(0x96283ee2a88effe3); + c->h[5] = U64(0xbe5e1e2553863992); + c->h[6] = U64(0x2b0199fc2c85b8aa); + c->h[7] = U64(0x0eb72ddc81c52ca2); + + c->md_len = SHA512_256_DIGEST_LENGTH; + + return 1; +} + +int +SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len) +{ + return SHA512_Update(c, data, len); +} + +int +SHA512_256_Final(unsigned char *md, SHA512_CTX *c) +{ + return SHA512_Final(md, c); +} + +#endif /* !OPENSSL_NO_SHA512 */ diff --git a/Libraries/libressl/crypto/sha/sha_internal.h b/Libraries/libressl/crypto/sha/sha_internal.h new file mode 100644 index 000000000..63cae3d3b --- /dev/null +++ b/Libraries/libressl/crypto/sha/sha_internal.h @@ -0,0 +1,36 @@ +/* $OpenBSD: sha_internal.h,v 1.3 2023/04/25 15:47:29 tb Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HEADER_SHA_INTERNAL_H +#define HEADER_SHA_INTERNAL_H + +#define SHA512_224_DIGEST_LENGTH 28 +#define SHA512_256_DIGEST_LENGTH 32 + +int SHA512_224_Init(SHA512_CTX *c); +int SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA512_224_Final(unsigned char *md, SHA512_CTX *c); + +int SHA512_256_Init(SHA512_CTX *c); +int SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA512_256_Final(unsigned char *md, SHA512_CTX *c); + +#endif diff --git a/Libraries/libressl/crypto/sm3/sm3.c b/Libraries/libressl/crypto/sm3/sm3.c new file mode 100644 index 000000000..80be935f7 --- /dev/null +++ b/Libraries/libressl/crypto/sm3/sm3.c @@ -0,0 +1,277 @@ +/* $OpenBSD: sm3.c,v 1.6 2023/07/08 06:36:55 jsing Exp $ */ +/* + * Copyright (c) 2018, Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENSSL_NO_SM3 + +#include + +#include + +#include + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SM3_WORD +#define HASH_CTX SM3_CTX +#define HASH_CBLOCK SM3_CBLOCK +#define HASH_UPDATE SM3_Update +#define HASH_TRANSFORM SM3_Transform +#define HASH_FINAL SM3_Final +#define HASH_MAKE_STRING(c, s) do { \ + unsigned long ll; \ + ll = (c)->A; HOST_l2c(ll, (s)); \ + ll = (c)->B; HOST_l2c(ll, (s)); \ + ll = (c)->C; HOST_l2c(ll, (s)); \ + ll = (c)->D; HOST_l2c(ll, (s)); \ + ll = (c)->E; HOST_l2c(ll, (s)); \ + ll = (c)->F; HOST_l2c(ll, (s)); \ + ll = (c)->G; HOST_l2c(ll, (s)); \ + ll = (c)->H; HOST_l2c(ll, (s)); \ +} while (0) +#define HASH_BLOCK_DATA_ORDER SM3_block_data_order + +void SM3_block_data_order(SM3_CTX *c, const void *p, size_t num); +void SM3_transform(SM3_CTX *c, const unsigned char *data); + +#include "md32_common.h" + +#define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17)) +#define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23)) + +#define FF0(X, Y, Z) (X ^ Y ^ Z) +#define GG0(X, Y, Z) (X ^ Y ^ Z) + +#define FF1(X, Y, Z) ((X & Y) | ((X | Y) & Z)) +#define GG1(X, Y, Z) ((Z ^ (X & (Y ^ Z)))) + +#define EXPAND(W0, W7, W13, W3, W10) \ + (P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10) + +#define ROUND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF, GG) do { \ + const SM3_WORD A12 = ROTATE(A, 12); \ + const SM3_WORD A12_SM = A12 + E + TJ; \ + const SM3_WORD SS1 = ROTATE(A12_SM, 7); \ + const SM3_WORD TT1 = FF(A, B, C) + D + (SS1 ^ A12) + (Wj); \ + const SM3_WORD TT2 = GG(E, F, G) + H + SS1 + Wi; \ + B = ROTATE(B, 9); \ + D = TT1; \ + F = ROTATE(F, 19); \ + H = P0(TT2); \ +} while(0) + +#define R1(A, B, C, D, E, F, G, H, TJ, Wi, Wj) \ + ROUND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF0, GG0) + +#define R2(A, B, C, D, E, F, G, H, TJ, Wi, Wj) \ + ROUND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF1, GG1) + +#define SM3_A 0x7380166fUL +#define SM3_B 0x4914b2b9UL +#define SM3_C 0x172442d7UL +#define SM3_D 0xda8a0600UL +#define SM3_E 0xa96f30bcUL +#define SM3_F 0x163138aaUL +#define SM3_G 0xe38dee4dUL +#define SM3_H 0xb0fb0e4eUL + +LCRYPTO_ALIAS(SM3_Update); +LCRYPTO_ALIAS(SM3_Final); + +int +SM3_Init(SM3_CTX *c) +{ + memset(c, 0, sizeof(*c)); + c->A = SM3_A; + c->B = SM3_B; + c->C = SM3_C; + c->D = SM3_D; + c->E = SM3_E; + c->F = SM3_F; + c->G = SM3_G; + c->H = SM3_H; + return 1; +} +LCRYPTO_ALIAS(SM3_Init); + +void +SM3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) +{ + const unsigned char *data = p; + SM3_WORD A, B, C, D, E, F, G, H; + SM3_WORD W00, W01, W02, W03, W04, W05, W06, W07; + SM3_WORD W08, W09, W10, W11, W12, W13, W14, W15; + + while (num-- != 0) { + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + F = ctx->F; + G = ctx->G; + H = ctx->H; + + /* + * We have to load all message bytes immediately since SM3 reads + * them slightly out of order. + */ + HOST_c2l(data, W00); + HOST_c2l(data, W01); + HOST_c2l(data, W02); + HOST_c2l(data, W03); + HOST_c2l(data, W04); + HOST_c2l(data, W05); + HOST_c2l(data, W06); + HOST_c2l(data, W07); + HOST_c2l(data, W08); + HOST_c2l(data, W09); + HOST_c2l(data, W10); + HOST_c2l(data, W11); + HOST_c2l(data, W12); + HOST_c2l(data, W13); + HOST_c2l(data, W14); + HOST_c2l(data, W15); + + R1(A, B, C, D, E, F, G, H, 0x79cc4519, W00, W00 ^ W04); + W00 = EXPAND(W00, W07, W13, W03, W10); + R1(D, A, B, C, H, E, F, G, 0xf3988a32, W01, W01 ^ W05); + W01 = EXPAND(W01, W08, W14, W04, W11); + R1(C, D, A, B, G, H, E, F, 0xe7311465, W02, W02 ^ W06); + W02 = EXPAND(W02, W09, W15, W05, W12); + R1(B, C, D, A, F, G, H, E, 0xce6228cb, W03, W03 ^ W07); + W03 = EXPAND(W03, W10, W00, W06, W13); + R1(A, B, C, D, E, F, G, H, 0x9cc45197, W04, W04 ^ W08); + W04 = EXPAND(W04, W11, W01, W07, W14); + R1(D, A, B, C, H, E, F, G, 0x3988a32f, W05, W05 ^ W09); + W05 = EXPAND(W05, W12, W02, W08, W15); + R1(C, D, A, B, G, H, E, F, 0x7311465e, W06, W06 ^ W10); + W06 = EXPAND(W06, W13, W03, W09, W00); + R1(B, C, D, A, F, G, H, E, 0xe6228cbc, W07, W07 ^ W11); + W07 = EXPAND(W07, W14, W04, W10, W01); + R1(A, B, C, D, E, F, G, H, 0xcc451979, W08, W08 ^ W12); + W08 = EXPAND(W08, W15, W05, W11, W02); + R1(D, A, B, C, H, E, F, G, 0x988a32f3, W09, W09 ^ W13); + W09 = EXPAND(W09, W00, W06, W12, W03); + R1(C, D, A, B, G, H, E, F, 0x311465e7, W10, W10 ^ W14); + W10 = EXPAND(W10, W01, W07, W13, W04); + R1(B, C, D, A, F, G, H, E, 0x6228cbce, W11, W11 ^ W15); + W11 = EXPAND(W11, W02, W08, W14, W05); + R1(A, B, C, D, E, F, G, H, 0xc451979c, W12, W12 ^ W00); + W12 = EXPAND(W12, W03, W09, W15, W06); + R1(D, A, B, C, H, E, F, G, 0x88a32f39, W13, W13 ^ W01); + W13 = EXPAND(W13, W04, W10, W00, W07); + R1(C, D, A, B, G, H, E, F, 0x11465e73, W14, W14 ^ W02); + W14 = EXPAND(W14, W05, W11, W01, W08); + R1(B, C, D, A, F, G, H, E, 0x228cbce6, W15, W15 ^ W03); + W15 = EXPAND(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x9d8a7a87, W00, W00 ^ W04); + W00 = EXPAND(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0x3b14f50f, W01, W01 ^ W05); + W01 = EXPAND(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0x7629ea1e, W02, W02 ^ W06); + W02 = EXPAND(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xec53d43c, W03, W03 ^ W07); + W03 = EXPAND(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xd8a7a879, W04, W04 ^ W08); + W04 = EXPAND(W04, W11, W01, W07, W14); + R2(D, A, B, C, H, E, F, G, 0xb14f50f3, W05, W05 ^ W09); + W05 = EXPAND(W05, W12, W02, W08, W15); + R2(C, D, A, B, G, H, E, F, 0x629ea1e7, W06, W06 ^ W10); + W06 = EXPAND(W06, W13, W03, W09, W00); + R2(B, C, D, A, F, G, H, E, 0xc53d43ce, W07, W07 ^ W11); + W07 = EXPAND(W07, W14, W04, W10, W01); + R2(A, B, C, D, E, F, G, H, 0x8a7a879d, W08, W08 ^ W12); + W08 = EXPAND(W08, W15, W05, W11, W02); + R2(D, A, B, C, H, E, F, G, 0x14f50f3b, W09, W09 ^ W13); + W09 = EXPAND(W09, W00, W06, W12, W03); + R2(C, D, A, B, G, H, E, F, 0x29ea1e76, W10, W10 ^ W14); + W10 = EXPAND(W10, W01, W07, W13, W04); + R2(B, C, D, A, F, G, H, E, 0x53d43cec, W11, W11 ^ W15); + W11 = EXPAND(W11, W02, W08, W14, W05); + R2(A, B, C, D, E, F, G, H, 0xa7a879d8, W12, W12 ^ W00); + W12 = EXPAND(W12, W03, W09, W15, W06); + R2(D, A, B, C, H, E, F, G, 0x4f50f3b1, W13, W13 ^ W01); + W13 = EXPAND(W13, W04, W10, W00, W07); + R2(C, D, A, B, G, H, E, F, 0x9ea1e762, W14, W14 ^ W02); + W14 = EXPAND(W14, W05, W11, W01, W08); + R2(B, C, D, A, F, G, H, E, 0x3d43cec5, W15, W15 ^ W03); + W15 = EXPAND(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x7a879d8a, W00, W00 ^ W04); + W00 = EXPAND(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0xf50f3b14, W01, W01 ^ W05); + W01 = EXPAND(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0xea1e7629, W02, W02 ^ W06); + W02 = EXPAND(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xd43cec53, W03, W03 ^ W07); + W03 = EXPAND(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xa879d8a7, W04, W04 ^ W08); + W04 = EXPAND(W04, W11, W01, W07, W14); + R2(D, A, B, C, H, E, F, G, 0x50f3b14f, W05, W05 ^ W09); + W05 = EXPAND(W05, W12, W02, W08, W15); + R2(C, D, A, B, G, H, E, F, 0xa1e7629e, W06, W06 ^ W10); + W06 = EXPAND(W06, W13, W03, W09, W00); + R2(B, C, D, A, F, G, H, E, 0x43cec53d, W07, W07 ^ W11); + W07 = EXPAND(W07, W14, W04, W10, W01); + R2(A, B, C, D, E, F, G, H, 0x879d8a7a, W08, W08 ^ W12); + W08 = EXPAND(W08, W15, W05, W11, W02); + R2(D, A, B, C, H, E, F, G, 0x0f3b14f5, W09, W09 ^ W13); + W09 = EXPAND(W09, W00, W06, W12, W03); + R2(C, D, A, B, G, H, E, F, 0x1e7629ea, W10, W10 ^ W14); + W10 = EXPAND(W10, W01, W07, W13, W04); + R2(B, C, D, A, F, G, H, E, 0x3cec53d4, W11, W11 ^ W15); + W11 = EXPAND(W11, W02, W08, W14, W05); + R2(A, B, C, D, E, F, G, H, 0x79d8a7a8, W12, W12 ^ W00); + W12 = EXPAND(W12, W03, W09, W15, W06); + R2(D, A, B, C, H, E, F, G, 0xf3b14f50, W13, W13 ^ W01); + W13 = EXPAND(W13, W04, W10, W00, W07); + R2(C, D, A, B, G, H, E, F, 0xe7629ea1, W14, W14 ^ W02); + W14 = EXPAND(W14, W05, W11, W01, W08); + R2(B, C, D, A, F, G, H, E, 0xcec53d43, W15, W15 ^ W03); + W15 = EXPAND(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x9d8a7a87, W00, W00 ^ W04); + W00 = EXPAND(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0x3b14f50f, W01, W01 ^ W05); + W01 = EXPAND(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0x7629ea1e, W02, W02 ^ W06); + W02 = EXPAND(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xec53d43c, W03, W03 ^ W07); + W03 = EXPAND(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xd8a7a879, W04, W04 ^ W08); + R2(D, A, B, C, H, E, F, G, 0xb14f50f3, W05, W05 ^ W09); + R2(C, D, A, B, G, H, E, F, 0x629ea1e7, W06, W06 ^ W10); + R2(B, C, D, A, F, G, H, E, 0xc53d43ce, W07, W07 ^ W11); + R2(A, B, C, D, E, F, G, H, 0x8a7a879d, W08, W08 ^ W12); + R2(D, A, B, C, H, E, F, G, 0x14f50f3b, W09, W09 ^ W13); + R2(C, D, A, B, G, H, E, F, 0x29ea1e76, W10, W10 ^ W14); + R2(B, C, D, A, F, G, H, E, 0x53d43cec, W11, W11 ^ W15); + R2(A, B, C, D, E, F, G, H, 0xa7a879d8, W12, W12 ^ W00); + R2(D, A, B, C, H, E, F, G, 0x4f50f3b1, W13, W13 ^ W01); + R2(C, D, A, B, G, H, E, F, 0x9ea1e762, W14, W14 ^ W02); + R2(B, C, D, A, F, G, H, E, 0x3d43cec5, W15, W15 ^ W03); + + ctx->A ^= A; + ctx->B ^= B; + ctx->C ^= C; + ctx->D ^= D; + ctx->E ^= E; + ctx->F ^= F; + ctx->G ^= G; + ctx->H ^= H; + } +} + +#endif /* !OPENSSL_NO_SM3 */ diff --git a/Libraries/libressl/crypto/sm4/sm4.c b/Libraries/libressl/crypto/sm4/sm4.c new file mode 100644 index 000000000..bd1689987 --- /dev/null +++ b/Libraries/libressl/crypto/sm4/sm4.c @@ -0,0 +1,266 @@ +/* $OpenBSD: sm4.c,v 1.2 2023/07/07 12:01:32 beck Exp $ */ +/* + * Copyright (c) 2017, 2019 Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef OPENSSL_NO_SM4 +#include + +struct sm4_key { + uint32_t rk[SM4_KEY_SCHEDULE]; +}; + +static const uint8_t SM4_S[256] = { + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, + 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, + 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, + 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, + 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, + 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, + 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, + 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, + 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, + 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, + 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, + 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, + 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, + 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, + 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, + 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, + 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, + 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, + 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, + 0xD7, 0xCB, 0x39, 0x48, +}; + +/* + * SM4_SBOX_T[j] == L(SM4_SBOX[j]). + */ +static const uint32_t SM4_SBOX_T[256] = { + 0x8ED55B5B, 0xD0924242, 0x4DEAA7A7, 0x06FDFBFB, 0xFCCF3333, 0x65E28787, + 0xC93DF4F4, 0x6BB5DEDE, 0x4E165858, 0x6EB4DADA, 0x44145050, 0xCAC10B0B, + 0x8828A0A0, 0x17F8EFEF, 0x9C2CB0B0, 0x11051414, 0x872BACAC, 0xFB669D9D, + 0xF2986A6A, 0xAE77D9D9, 0x822AA8A8, 0x46BCFAFA, 0x14041010, 0xCFC00F0F, + 0x02A8AAAA, 0x54451111, 0x5F134C4C, 0xBE269898, 0x6D482525, 0x9E841A1A, + 0x1E061818, 0xFD9B6666, 0xEC9E7272, 0x4A430909, 0x10514141, 0x24F7D3D3, + 0xD5934646, 0x53ECBFBF, 0xF89A6262, 0x927BE9E9, 0xFF33CCCC, 0x04555151, + 0x270B2C2C, 0x4F420D0D, 0x59EEB7B7, 0xF3CC3F3F, 0x1CAEB2B2, 0xEA638989, + 0x74E79393, 0x7FB1CECE, 0x6C1C7070, 0x0DABA6A6, 0xEDCA2727, 0x28082020, + 0x48EBA3A3, 0xC1975656, 0x80820202, 0xA3DC7F7F, 0xC4965252, 0x12F9EBEB, + 0xA174D5D5, 0xB38D3E3E, 0xC33FFCFC, 0x3EA49A9A, 0x5B461D1D, 0x1B071C1C, + 0x3BA59E9E, 0x0CFFF3F3, 0x3FF0CFCF, 0xBF72CDCD, 0x4B175C5C, 0x52B8EAEA, + 0x8F810E0E, 0x3D586565, 0xCC3CF0F0, 0x7D196464, 0x7EE59B9B, 0x91871616, + 0x734E3D3D, 0x08AAA2A2, 0xC869A1A1, 0xC76AADAD, 0x85830606, 0x7AB0CACA, + 0xB570C5C5, 0xF4659191, 0xB2D96B6B, 0xA7892E2E, 0x18FBE3E3, 0x47E8AFAF, + 0x330F3C3C, 0x674A2D2D, 0xB071C1C1, 0x0E575959, 0xE99F7676, 0xE135D4D4, + 0x661E7878, 0xB4249090, 0x360E3838, 0x265F7979, 0xEF628D8D, 0x38596161, + 0x95D24747, 0x2AA08A8A, 0xB1259494, 0xAA228888, 0x8C7DF1F1, 0xD73BECEC, + 0x05010404, 0xA5218484, 0x9879E1E1, 0x9B851E1E, 0x84D75353, 0x00000000, + 0x5E471919, 0x0B565D5D, 0xE39D7E7E, 0x9FD04F4F, 0xBB279C9C, 0x1A534949, + 0x7C4D3131, 0xEE36D8D8, 0x0A020808, 0x7BE49F9F, 0x20A28282, 0xD4C71313, + 0xE8CB2323, 0xE69C7A7A, 0x42E9ABAB, 0x43BDFEFE, 0xA2882A2A, 0x9AD14B4B, + 0x40410101, 0xDBC41F1F, 0xD838E0E0, 0x61B7D6D6, 0x2FA18E8E, 0x2BF4DFDF, + 0x3AF1CBCB, 0xF6CD3B3B, 0x1DFAE7E7, 0xE5608585, 0x41155454, 0x25A38686, + 0x60E38383, 0x16ACBABA, 0x295C7575, 0x34A69292, 0xF7996E6E, 0xE434D0D0, + 0x721A6868, 0x01545555, 0x19AFB6B6, 0xDF914E4E, 0xFA32C8C8, 0xF030C0C0, + 0x21F6D7D7, 0xBC8E3232, 0x75B3C6C6, 0x6FE08F8F, 0x691D7474, 0x2EF5DBDB, + 0x6AE18B8B, 0x962EB8B8, 0x8A800A0A, 0xFE679999, 0xE2C92B2B, 0xE0618181, + 0xC0C30303, 0x8D29A4A4, 0xAF238C8C, 0x07A9AEAE, 0x390D3434, 0x1F524D4D, + 0x764F3939, 0xD36EBDBD, 0x81D65757, 0xB7D86F6F, 0xEB37DCDC, 0x51441515, + 0xA6DD7B7B, 0x09FEF7F7, 0xB68C3A3A, 0x932FBCBC, 0x0F030C0C, 0x03FCFFFF, + 0xC26BA9A9, 0xBA73C9C9, 0xD96CB5B5, 0xDC6DB1B1, 0x375A6D6D, 0x15504545, + 0xB98F3636, 0x771B6C6C, 0x13ADBEBE, 0xDA904A4A, 0x57B9EEEE, 0xA9DE7777, + 0x4CBEF2F2, 0x837EFDFD, 0x55114444, 0xBDDA6767, 0x2C5D7171, 0x45400505, + 0x631F7C7C, 0x50104040, 0x325B6969, 0xB8DB6363, 0x220A2828, 0xC5C20707, + 0xF531C4C4, 0xA88A2222, 0x31A79696, 0xF9CE3737, 0x977AEDED, 0x49BFF6F6, + 0x992DB4B4, 0xA475D1D1, 0x90D34343, 0x5A124848, 0x58BAE2E2, 0x71E69797, + 0x64B6D2D2, 0x70B2C2C2, 0xAD8B2626, 0xCD68A5A5, 0xCB955E5E, 0x624B2929, + 0x3C0C3030, 0xCE945A5A, 0xAB76DDDD, 0x867FF9F9, 0xF1649595, 0x5DBBE6E6, + 0x35F2C7C7, 0x2D092424, 0xD1C61717, 0xD66FB9B9, 0xDEC51B1B, 0x94861212, + 0x78186060, 0x30F3C3C3, 0x897CF5F5, 0x5CEFB3B3, 0xD23AE8E8, 0xACDF7373, + 0x794C3535, 0xA0208080, 0x9D78E5E5, 0x56EDBBBB, 0x235E7D7D, 0xC63EF8F8, + 0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121, +}; + +static inline uint32_t +rotl(uint32_t a, uint8_t n) +{ + return (a << n) | (a >> (32 - n)); +} + +static inline uint32_t +load_u32_be(const uint8_t *b, uint32_t n) +{ + return ((uint32_t)b[4 * n] << 24) | + ((uint32_t)b[4 * n + 1] << 16) | + ((uint32_t)b[4 * n + 2] << 8) | + ((uint32_t)b[4 * n + 3]); +} + +static inline void +store_u32_be(uint32_t v, uint8_t *b) +{ + b[0] = (uint8_t)(v >> 24); + b[1] = (uint8_t)(v >> 16); + b[2] = (uint8_t)(v >> 8); + b[3] = (uint8_t)(v); +} + +static inline uint32_t +SM4_T_slow(uint32_t X) +{ + uint32_t t = 0; + + t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24; + t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16; + t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8; + t |= SM4_S[(uint8_t)X]; + + /* + * L linear transform + */ + return t ^ rotl(t, 2) ^ rotl(t, 10) ^ rotl(t, 18) ^ rotl(t, 24); +} + +static inline uint32_t +SM4_T(uint32_t X) +{ + return SM4_SBOX_T[(uint8_t)(X >> 24)] ^ + rotl(SM4_SBOX_T[(uint8_t)(X >> 16)], 24) ^ + rotl(SM4_SBOX_T[(uint8_t)(X >> 8)], 16) ^ + rotl(SM4_SBOX_T[(uint8_t)X], 8); +} + +int +SM4_set_key(const uint8_t *key, SM4_KEY *k) +{ + struct sm4_key *ks = (struct sm4_key *)k; + + /* + * Family Key + */ + static const uint32_t FK[4] = { + 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc, + }; + + /* + * Constant Key + */ + static const uint32_t CK[32] = { + 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, + 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9, + 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, + 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9, + 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229, + 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299, + 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209, + 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279, + }; + + uint32_t K[4]; + int i; + + K[0] = load_u32_be(key, 0) ^ FK[0]; + K[1] = load_u32_be(key, 1) ^ FK[1]; + K[2] = load_u32_be(key, 2) ^ FK[2]; + K[3] = load_u32_be(key, 3) ^ FK[3]; + + for (i = 0; i < SM4_KEY_SCHEDULE; i++) { + uint32_t X; + uint32_t t = 0; + + X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ CK[i]; + + t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24; + t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16; + t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8; + t |= SM4_S[(uint8_t)X]; + + t = t ^ rotl(t, 13) ^ rotl(t, 23); + K[i % 4] ^= t; + ks->rk[i] = K[i % 4]; + } + + return 1; +} +LCRYPTO_ALIAS(SM4_set_key); + +#define SM4_ROUNDS(k0, k1, k2, k3, F) \ + do { \ + B0 ^= F(B1 ^ B2 ^ B3 ^ ks->rk[k0]); \ + B1 ^= F(B0 ^ B2 ^ B3 ^ ks->rk[k1]); \ + B2 ^= F(B0 ^ B1 ^ B3 ^ ks->rk[k2]); \ + B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \ + } while(0) + +void +SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) +{ + struct sm4_key *ks = (struct sm4_key *)k; + uint32_t B0 = load_u32_be(in, 0); + uint32_t B1 = load_u32_be(in, 1); + uint32_t B2 = load_u32_be(in, 2); + uint32_t B3 = load_u32_be(in, 3); + + /* + * Uses byte-wise sbox in the first and last rounds to provide some + * protection from cache based side channels. + */ + SM4_ROUNDS( 0, 1, 2, 3, SM4_T_slow); + SM4_ROUNDS( 4, 5, 6, 7, SM4_T); + SM4_ROUNDS( 8, 9, 10, 11, SM4_T); + SM4_ROUNDS(12, 13, 14, 15, SM4_T); + SM4_ROUNDS(16, 17, 18, 19, SM4_T); + SM4_ROUNDS(20, 21, 22, 23, SM4_T); + SM4_ROUNDS(24, 25, 26, 27, SM4_T); + SM4_ROUNDS(28, 29, 30, 31, SM4_T_slow); + + store_u32_be(B3, out); + store_u32_be(B2, out + 4); + store_u32_be(B1, out + 8); + store_u32_be(B0, out + 12); +} +LCRYPTO_ALIAS(SM4_encrypt); + +void +SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) +{ + struct sm4_key *ks = (struct sm4_key *)k; + uint32_t B0 = load_u32_be(in, 0); + uint32_t B1 = load_u32_be(in, 1); + uint32_t B2 = load_u32_be(in, 2); + uint32_t B3 = load_u32_be(in, 3); + + SM4_ROUNDS(31, 30, 29, 28, SM4_T_slow); + SM4_ROUNDS(27, 26, 25, 24, SM4_T); + SM4_ROUNDS(23, 22, 21, 20, SM4_T); + SM4_ROUNDS(19, 18, 17, 16, SM4_T); + SM4_ROUNDS(15, 14, 13, 12, SM4_T); + SM4_ROUNDS(11, 10, 9, 8, SM4_T); + SM4_ROUNDS( 7, 6, 5, 4, SM4_T); + SM4_ROUNDS( 3, 2, 1, 0, SM4_T_slow); + + store_u32_be(B3, out); + store_u32_be(B2, out + 4); + store_u32_be(B1, out + 8); + store_u32_be(B0, out + 12); +} +LCRYPTO_ALIAS(SM4_decrypt); + +#endif /* OPENSSL_NO_SM4 */ diff --git a/Libraries/libressl/crypto/stack/stack.c b/Libraries/libressl/crypto/stack/stack.c new file mode 100644 index 000000000..65bd3217d --- /dev/null +++ b/Libraries/libressl/crypto/stack/stack.c @@ -0,0 +1,372 @@ +/* $OpenBSD: stack.c,v 1.23 2023/04/24 15:35:22 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include + +#undef MIN_NODES +#define MIN_NODES 4 + +#include + +int +(*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))( + const void *, const void *) +{ + int (*old)(const void *, const void *) = sk->comp; + + if (sk->comp != c) + sk->sorted = 0; + sk->comp = c; + + return old; +} +LCRYPTO_ALIAS(sk_set_cmp_func); + +_STACK * +sk_dup(_STACK *sk) +{ + _STACK *ret; + char **s; + + if ((ret = sk_new(sk->comp)) == NULL) + goto err; + s = reallocarray(ret->data, sk->num_alloc, sizeof(char *)); + if (s == NULL) + goto err; + ret->data = s; + + ret->num = sk->num; + memcpy(ret->data, sk->data, sizeof(char *) * sk->num); + ret->sorted = sk->sorted; + ret->num_alloc = sk->num_alloc; + ret->comp = sk->comp; + return (ret); + +err: + if (ret) + sk_free(ret); + return (NULL); +} +LCRYPTO_ALIAS(sk_dup); + +_STACK * +sk_new_null(void) +{ + return sk_new((int (*)(const void *, const void *))0); +} +LCRYPTO_ALIAS(sk_new_null); + +_STACK * +sk_new(int (*c)(const void *, const void *)) +{ + _STACK *ret; + int i; + + if ((ret = malloc(sizeof(_STACK))) == NULL) + goto err; + if ((ret->data = reallocarray(NULL, MIN_NODES, sizeof(char *))) == NULL) + goto err; + for (i = 0; i < MIN_NODES; i++) + ret->data[i] = NULL; + ret->comp = c; + ret->num_alloc = MIN_NODES; + ret->num = 0; + ret->sorted = 0; + return (ret); + +err: + free(ret); + return (NULL); +} +LCRYPTO_ALIAS(sk_new); + +int +sk_insert(_STACK *st, void *data, int loc) +{ + char **s; + + if (st == NULL) + return 0; + if (st->num_alloc <= st->num + 1) { + s = reallocarray(st->data, st->num_alloc, 2 * sizeof(char *)); + if (s == NULL) + return (0); + st->data = s; + st->num_alloc *= 2; + } + if ((loc >= (int)st->num) || (loc < 0)) + st->data[st->num] = data; + else { + memmove(&(st->data[loc + 1]), &(st->data[loc]), + sizeof(char *)*(st->num - loc)); + st->data[loc] = data; + } + st->num++; + st->sorted = 0; + return (st->num); +} +LCRYPTO_ALIAS(sk_insert); + +void * +sk_delete_ptr(_STACK *st, void *p) +{ + int i; + + for (i = 0; i < st->num; i++) + if (st->data[i] == p) + return (sk_delete(st, i)); + return (NULL); +} +LCRYPTO_ALIAS(sk_delete_ptr); + +void * +sk_delete(_STACK *st, int loc) +{ + char *ret; + + if (!st || (loc < 0) || (loc >= st->num)) + return NULL; + + ret = st->data[loc]; + if (loc != st->num - 1) { + memmove(&(st->data[loc]), &(st->data[loc + 1]), + sizeof(char *)*(st->num - 1 - loc)); + } + st->num--; + return (ret); +} +LCRYPTO_ALIAS(sk_delete); + +static int +internal_find(_STACK *st, void *data, int ret_val_options) +{ + const void * const *r; + int i; + + if (st == NULL) + return -1; + + if (st->comp == NULL) { + for (i = 0; i < st->num; i++) + if (st->data[i] == data) + return (i); + return (-1); + } + sk_sort(st); + if (data == NULL) + return (-1); + r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, + ret_val_options); + if (r == NULL) + return (-1); + return (int)((char **)r - st->data); +} + +int +sk_find(_STACK *st, void *data) +{ + return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); +} +LCRYPTO_ALIAS(sk_find); + +int +sk_find_ex(_STACK *st, void *data) +{ + return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); +} +LCRYPTO_ALIAS(sk_find_ex); + +int +sk_push(_STACK *st, void *data) +{ + return (sk_insert(st, data, st->num)); +} +LCRYPTO_ALIAS(sk_push); + +int +sk_unshift(_STACK *st, void *data) +{ + return (sk_insert(st, data, 0)); +} +LCRYPTO_ALIAS(sk_unshift); + +void * +sk_shift(_STACK *st) +{ + if (st == NULL) + return (NULL); + if (st->num <= 0) + return (NULL); + return (sk_delete(st, 0)); +} +LCRYPTO_ALIAS(sk_shift); + +void * +sk_pop(_STACK *st) +{ + if (st == NULL) + return (NULL); + if (st->num <= 0) + return (NULL); + return (sk_delete(st, st->num - 1)); +} +LCRYPTO_ALIAS(sk_pop); + +void +sk_zero(_STACK *st) +{ + if (st == NULL) + return; + if (st->num <= 0) + return; + memset(st->data, 0, sizeof(st->data)*st->num); + st->num = 0; +} +LCRYPTO_ALIAS(sk_zero); + +void +sk_pop_free(_STACK *st, void (*func)(void *)) +{ + int i; + + if (st == NULL) + return; + for (i = 0; i < st->num; i++) + if (st->data[i] != NULL) + func(st->data[i]); + sk_free(st); +} +LCRYPTO_ALIAS(sk_pop_free); + +void +sk_free(_STACK *st) +{ + if (st == NULL) + return; + free(st->data); + free(st); +} +LCRYPTO_ALIAS(sk_free); + +int +sk_num(const _STACK *st) +{ + if (st == NULL) + return -1; + return st->num; +} +LCRYPTO_ALIAS(sk_num); + +void * +sk_value(const _STACK *st, int i) +{ + if (!st || (i < 0) || (i >= st->num)) + return NULL; + return st->data[i]; +} +LCRYPTO_ALIAS(sk_value); + +void * +sk_set(_STACK *st, int i, void *value) +{ + if (!st || (i < 0) || (i >= st->num)) + return NULL; + st->sorted = 0; + return (st->data[i] = value); +} +LCRYPTO_ALIAS(sk_set); + +void +sk_sort(_STACK *st) +{ + if (st && !st->sorted) { + int (*comp_func)(const void *, const void *); + + /* same comment as in sk_find ... previously st->comp was declared + * as a (void*,void*) callback type, but this made the population + * of the callback pointer illogical - our callbacks compare + * type** with type**, so we leave the casting until absolutely + * necessary (ie. "now"). */ + comp_func = (int (*)(const void *, const void *))(st->comp); + qsort(st->data, st->num, sizeof(char *), comp_func); + st->sorted = 1; + } +} +LCRYPTO_ALIAS(sk_sort); + +int +sk_is_sorted(const _STACK *st) +{ + if (st == NULL) + return 1; + + if (st->sorted) + return 1; + + /* If there is no comparison function we cannot sort. */ + if (st->comp == NULL) + return 0; + + /* Lists with zero or one elements are always sorted. */ + return st->num <= 1; +} +LCRYPTO_ALIAS(sk_is_sorted); diff --git a/Libraries/libressl/crypto/ts/ts_asn1.c b/Libraries/libressl/crypto/ts/ts_asn1.c new file mode 100644 index 000000000..60ee0b81c --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_asn1.c @@ -0,0 +1,1077 @@ +/* $OpenBSD: ts_asn1.c,v 1.14 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Nils Larsch for the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +#include "ts_local.h" + +static const ASN1_TEMPLATE TS_MSG_IMPRINT_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_MSG_IMPRINT, hash_algo), + .field_name = "hash_algo", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_MSG_IMPRINT, hashed_msg), + .field_name = "hashed_msg", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM TS_MSG_IMPRINT_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = TS_MSG_IMPRINT_seq_tt, + .tcount = sizeof(TS_MSG_IMPRINT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(TS_MSG_IMPRINT), + .sname = "TS_MSG_IMPRINT", +}; + + +TS_MSG_IMPRINT * +d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, const unsigned char **in, long len) +{ + return (TS_MSG_IMPRINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &TS_MSG_IMPRINT_it); +} +LCRYPTO_ALIAS(d2i_TS_MSG_IMPRINT); + +int +i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_MSG_IMPRINT_it); +} +LCRYPTO_ALIAS(i2d_TS_MSG_IMPRINT); + +TS_MSG_IMPRINT * +TS_MSG_IMPRINT_new(void) +{ + return (TS_MSG_IMPRINT *)ASN1_item_new(&TS_MSG_IMPRINT_it); +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_new); + +void +TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &TS_MSG_IMPRINT_it); +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_free); + +TS_MSG_IMPRINT * +TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *x) +{ + return ASN1_item_dup(&TS_MSG_IMPRINT_it, x); +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_dup); + +#ifndef OPENSSL_NO_BIO +TS_MSG_IMPRINT * +d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) +{ + return ASN1_item_d2i_bio(&TS_MSG_IMPRINT_it, bp, a); +} +LCRYPTO_ALIAS(d2i_TS_MSG_IMPRINT_bio); + +int +i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) +{ + return ASN1_item_i2d_bio(&TS_MSG_IMPRINT_it, bp, a); +} +LCRYPTO_ALIAS(i2d_TS_MSG_IMPRINT_bio); +#endif + +TS_MSG_IMPRINT * +d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) +{ + return ASN1_item_d2i_fp(&TS_MSG_IMPRINT_it, fp, a); +} +LCRYPTO_ALIAS(d2i_TS_MSG_IMPRINT_fp); + +int +i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) +{ + return ASN1_item_i2d_fp(&TS_MSG_IMPRINT_it, fp, a); +} +LCRYPTO_ALIAS(i2d_TS_MSG_IMPRINT_fp); + +static const ASN1_TEMPLATE TS_REQ_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_REQ, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_REQ, msg_imprint), + .field_name = "msg_imprint", + .item = &TS_MSG_IMPRINT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_REQ, policy_id), + .field_name = "policy_id", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_REQ, nonce), + .field_name = "nonce", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_REQ, cert_req), + .field_name = "cert_req", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_REQ, extensions), + .field_name = "extensions", + .item = &X509_EXTENSION_it, + }, +}; + +const ASN1_ITEM TS_REQ_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = TS_REQ_seq_tt, + .tcount = sizeof(TS_REQ_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(TS_REQ), + .sname = "TS_REQ", +}; + + +TS_REQ * +d2i_TS_REQ(TS_REQ **a, const unsigned char **in, long len) +{ + return (TS_REQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &TS_REQ_it); +} +LCRYPTO_ALIAS(d2i_TS_REQ); + +int +i2d_TS_REQ(const TS_REQ *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_REQ_it); +} +LCRYPTO_ALIAS(i2d_TS_REQ); + +TS_REQ * +TS_REQ_new(void) +{ + return (TS_REQ *)ASN1_item_new(&TS_REQ_it); +} +LCRYPTO_ALIAS(TS_REQ_new); + +void +TS_REQ_free(TS_REQ *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &TS_REQ_it); +} +LCRYPTO_ALIAS(TS_REQ_free); + +TS_REQ * +TS_REQ_dup(TS_REQ *x) +{ + return ASN1_item_dup(&TS_REQ_it, x); +} +LCRYPTO_ALIAS(TS_REQ_dup); + +#ifndef OPENSSL_NO_BIO +TS_REQ * +d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) +{ + return ASN1_item_d2i_bio(&TS_REQ_it, bp, a); +} +LCRYPTO_ALIAS(d2i_TS_REQ_bio); + +int +i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) +{ + return ASN1_item_i2d_bio(&TS_REQ_it, bp, a); +} +LCRYPTO_ALIAS(i2d_TS_REQ_bio); +#endif + +TS_REQ * +d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) +{ + return ASN1_item_d2i_fp(&TS_REQ_it, fp, a); +} +LCRYPTO_ALIAS(d2i_TS_REQ_fp); + +int +i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) +{ + return ASN1_item_i2d_fp(&TS_REQ_it, fp, a); +} +LCRYPTO_ALIAS(i2d_TS_REQ_fp); + +static const ASN1_TEMPLATE TS_ACCURACY_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_ACCURACY, seconds), + .field_name = "seconds", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_ACCURACY, millis), + .field_name = "millis", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(TS_ACCURACY, micros), + .field_name = "micros", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM TS_ACCURACY_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = TS_ACCURACY_seq_tt, + .tcount = sizeof(TS_ACCURACY_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(TS_ACCURACY), + .sname = "TS_ACCURACY", +}; + + +TS_ACCURACY * +d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **in, long len) +{ + return (TS_ACCURACY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &TS_ACCURACY_it); +} +LCRYPTO_ALIAS(d2i_TS_ACCURACY); + +int +i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_ACCURACY_it); +} +LCRYPTO_ALIAS(i2d_TS_ACCURACY); + +TS_ACCURACY * +TS_ACCURACY_new(void) +{ + return (TS_ACCURACY *)ASN1_item_new(&TS_ACCURACY_it); +} +LCRYPTO_ALIAS(TS_ACCURACY_new); + +void +TS_ACCURACY_free(TS_ACCURACY *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &TS_ACCURACY_it); +} +LCRYPTO_ALIAS(TS_ACCURACY_free); + +TS_ACCURACY * +TS_ACCURACY_dup(TS_ACCURACY *x) +{ + return ASN1_item_dup(&TS_ACCURACY_it, x); +} +LCRYPTO_ALIAS(TS_ACCURACY_dup); + +static const ASN1_TEMPLATE TS_TST_INFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_TST_INFO, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_TST_INFO, policy_id), + .field_name = "policy_id", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_TST_INFO, msg_imprint), + .field_name = "msg_imprint", + .item = &TS_MSG_IMPRINT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_TST_INFO, serial), + .field_name = "serial", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_TST_INFO, time), + .field_name = "time", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_TST_INFO, accuracy), + .field_name = "accuracy", + .item = &TS_ACCURACY_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_TST_INFO, ordering), + .field_name = "ordering", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_TST_INFO, nonce), + .field_name = "nonce", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_TST_INFO, tsa), + .field_name = "tsa", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(TS_TST_INFO, extensions), + .field_name = "extensions", + .item = &X509_EXTENSION_it, + }, +}; + +const ASN1_ITEM TS_TST_INFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = TS_TST_INFO_seq_tt, + .tcount = sizeof(TS_TST_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(TS_TST_INFO), + .sname = "TS_TST_INFO", +}; + + +TS_TST_INFO * +d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **in, long len) +{ + return (TS_TST_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &TS_TST_INFO_it); +} +LCRYPTO_ALIAS(d2i_TS_TST_INFO); + +int +i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_TST_INFO_it); +} +LCRYPTO_ALIAS(i2d_TS_TST_INFO); + +TS_TST_INFO * +TS_TST_INFO_new(void) +{ + return (TS_TST_INFO *)ASN1_item_new(&TS_TST_INFO_it); +} +LCRYPTO_ALIAS(TS_TST_INFO_new); + +void +TS_TST_INFO_free(TS_TST_INFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &TS_TST_INFO_it); +} +LCRYPTO_ALIAS(TS_TST_INFO_free); + +TS_TST_INFO * +TS_TST_INFO_dup(TS_TST_INFO *x) +{ + return ASN1_item_dup(&TS_TST_INFO_it, x); +} +LCRYPTO_ALIAS(TS_TST_INFO_dup); + +#ifndef OPENSSL_NO_BIO +TS_TST_INFO * +d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) +{ + return ASN1_item_d2i_bio(&TS_TST_INFO_it, bp, a); +} +LCRYPTO_ALIAS(d2i_TS_TST_INFO_bio); + +int +i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) +{ + return ASN1_item_i2d_bio(&TS_TST_INFO_it, bp, a); +} +LCRYPTO_ALIAS(i2d_TS_TST_INFO_bio); +#endif + +TS_TST_INFO * +d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) +{ + return ASN1_item_d2i_fp(&TS_TST_INFO_it, fp, a); +} +LCRYPTO_ALIAS(d2i_TS_TST_INFO_fp); + +int +i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) +{ + return ASN1_item_i2d_fp(&TS_TST_INFO_it, fp, a); +} +LCRYPTO_ALIAS(i2d_TS_TST_INFO_fp); + +static const ASN1_TEMPLATE TS_STATUS_INFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_STATUS_INFO, status), + .field_name = "status", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_STATUS_INFO, text), + .field_name = "text", + .item = &ASN1_UTF8STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_STATUS_INFO, failure_info), + .field_name = "failure_info", + .item = &ASN1_BIT_STRING_it, + }, +}; + +const ASN1_ITEM TS_STATUS_INFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = TS_STATUS_INFO_seq_tt, + .tcount = sizeof(TS_STATUS_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(TS_STATUS_INFO), + .sname = "TS_STATUS_INFO", +}; + + +TS_STATUS_INFO * +d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, const unsigned char **in, long len) +{ + return (TS_STATUS_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &TS_STATUS_INFO_it); +} +LCRYPTO_ALIAS(d2i_TS_STATUS_INFO); + +int +i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_STATUS_INFO_it); +} +LCRYPTO_ALIAS(i2d_TS_STATUS_INFO); + +TS_STATUS_INFO * +TS_STATUS_INFO_new(void) +{ + return (TS_STATUS_INFO *)ASN1_item_new(&TS_STATUS_INFO_it); +} +LCRYPTO_ALIAS(TS_STATUS_INFO_new); + +void +TS_STATUS_INFO_free(TS_STATUS_INFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &TS_STATUS_INFO_it); +} +LCRYPTO_ALIAS(TS_STATUS_INFO_free); + +TS_STATUS_INFO * +TS_STATUS_INFO_dup(TS_STATUS_INFO *x) +{ + return ASN1_item_dup(&TS_STATUS_INFO_it, x); +} +LCRYPTO_ALIAS(TS_STATUS_INFO_dup); + +static int +ts_resp_set_tst_info(TS_RESP *a) +{ + long status; + + status = ASN1_INTEGER_get(a->status_info->status); + + if (a->token) { + if (status != 0 && status != 1) { + TSerror(TS_R_TOKEN_PRESENT); + return 0; + } + if (a->tst_info != NULL) + TS_TST_INFO_free(a->tst_info); + a->tst_info = PKCS7_to_TS_TST_INFO(a->token); + if (!a->tst_info) { + TSerror(TS_R_PKCS7_TO_TS_TST_INFO_FAILED); + return 0; + } + } else if (status == 0 || status == 1) { + TSerror(TS_R_TOKEN_NOT_PRESENT); + return 0; + } + + return 1; +} + +static int +ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + TS_RESP *ts_resp = (TS_RESP *)*pval; + + if (op == ASN1_OP_NEW_POST) { + ts_resp->tst_info = NULL; + } else if (op == ASN1_OP_FREE_POST) { + if (ts_resp->tst_info != NULL) + TS_TST_INFO_free(ts_resp->tst_info); + } else if (op == ASN1_OP_D2I_POST) { + if (ts_resp_set_tst_info(ts_resp) == 0) + return 0; + } + return 1; +} + +static const ASN1_AUX TS_RESP_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = ts_resp_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE TS_RESP_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(TS_RESP, status_info), + .field_name = "status_info", + .item = &TS_STATUS_INFO_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(TS_RESP, token), + .field_name = "token", + .item = &PKCS7_it, + }, +}; + +const ASN1_ITEM TS_RESP_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = TS_RESP_seq_tt, + .tcount = sizeof(TS_RESP_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &TS_RESP_aux, + .size = sizeof(TS_RESP), + .sname = "TS_RESP", +}; + + +TS_RESP * +d2i_TS_RESP(TS_RESP **a, const unsigned char **in, long len) +{ + return (TS_RESP *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &TS_RESP_it); +} +LCRYPTO_ALIAS(d2i_TS_RESP); + +int +i2d_TS_RESP(const TS_RESP *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_RESP_it); +} +LCRYPTO_ALIAS(i2d_TS_RESP); + +TS_RESP * +TS_RESP_new(void) +{ + return (TS_RESP *)ASN1_item_new(&TS_RESP_it); +} +LCRYPTO_ALIAS(TS_RESP_new); + +void +TS_RESP_free(TS_RESP *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &TS_RESP_it); +} +LCRYPTO_ALIAS(TS_RESP_free); + +TS_RESP * +TS_RESP_dup(TS_RESP *x) +{ + return ASN1_item_dup(&TS_RESP_it, x); +} +LCRYPTO_ALIAS(TS_RESP_dup); + +#ifndef OPENSSL_NO_BIO +TS_RESP * +d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) +{ + return ASN1_item_d2i_bio(&TS_RESP_it, bp, a); +} +LCRYPTO_ALIAS(d2i_TS_RESP_bio); + +int +i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) +{ + return ASN1_item_i2d_bio(&TS_RESP_it, bp, a); +} +LCRYPTO_ALIAS(i2d_TS_RESP_bio); +#endif + +TS_RESP * +d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) +{ + return ASN1_item_d2i_fp(&TS_RESP_it, fp, a); +} +LCRYPTO_ALIAS(d2i_TS_RESP_fp); + +int +i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) +{ + return ASN1_item_i2d_fp(&TS_RESP_it, fp, a); +} +LCRYPTO_ALIAS(i2d_TS_RESP_fp); + +static const ASN1_TEMPLATE ESS_ISSUER_SERIAL_seq_tt[] = { + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(ESS_ISSUER_SERIAL, issuer), + .field_name = "issuer", + .item = &GENERAL_NAME_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ESS_ISSUER_SERIAL, serial), + .field_name = "serial", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM ESS_ISSUER_SERIAL_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ESS_ISSUER_SERIAL_seq_tt, + .tcount = sizeof(ESS_ISSUER_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ESS_ISSUER_SERIAL), + .sname = "ESS_ISSUER_SERIAL", +}; + + +ESS_ISSUER_SERIAL * +d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, const unsigned char **in, long len) +{ + return (ESS_ISSUER_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ESS_ISSUER_SERIAL_it); +} +LCRYPTO_ALIAS(d2i_ESS_ISSUER_SERIAL); + +int +i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_ISSUER_SERIAL_it); +} +LCRYPTO_ALIAS(i2d_ESS_ISSUER_SERIAL); + +ESS_ISSUER_SERIAL * +ESS_ISSUER_SERIAL_new(void) +{ + return (ESS_ISSUER_SERIAL *)ASN1_item_new(&ESS_ISSUER_SERIAL_it); +} +LCRYPTO_ALIAS(ESS_ISSUER_SERIAL_new); + +void +ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ESS_ISSUER_SERIAL_it); +} +LCRYPTO_ALIAS(ESS_ISSUER_SERIAL_free); + +ESS_ISSUER_SERIAL * +ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *x) +{ + return ASN1_item_dup(&ESS_ISSUER_SERIAL_it, x); +} +LCRYPTO_ALIAS(ESS_ISSUER_SERIAL_dup); + +static const ASN1_TEMPLATE ESS_CERT_ID_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ESS_CERT_ID, hash), + .field_name = "hash", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ESS_CERT_ID, issuer_serial), + .field_name = "issuer_serial", + .item = &ESS_ISSUER_SERIAL_it, + }, +}; + +const ASN1_ITEM ESS_CERT_ID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ESS_CERT_ID_seq_tt, + .tcount = sizeof(ESS_CERT_ID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ESS_CERT_ID), + .sname = "ESS_CERT_ID", +}; + + +ESS_CERT_ID * +d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **in, long len) +{ + return (ESS_CERT_ID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ESS_CERT_ID_it); +} +LCRYPTO_ALIAS(d2i_ESS_CERT_ID); + +int +i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_CERT_ID_it); +} +LCRYPTO_ALIAS(i2d_ESS_CERT_ID); + +ESS_CERT_ID * +ESS_CERT_ID_new(void) +{ + return (ESS_CERT_ID *)ASN1_item_new(&ESS_CERT_ID_it); +} +LCRYPTO_ALIAS(ESS_CERT_ID_new); + +void +ESS_CERT_ID_free(ESS_CERT_ID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ESS_CERT_ID_it); +} +LCRYPTO_ALIAS(ESS_CERT_ID_free); + +ESS_CERT_ID * +ESS_CERT_ID_dup(ESS_CERT_ID *x) +{ + return ASN1_item_dup(&ESS_CERT_ID_it, x); +} +LCRYPTO_ALIAS(ESS_CERT_ID_dup); + +static const ASN1_TEMPLATE ESS_SIGNING_CERT_seq_tt[] = { + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(ESS_SIGNING_CERT, cert_ids), + .field_name = "cert_ids", + .item = &ESS_CERT_ID_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ESS_SIGNING_CERT, policy_info), + .field_name = "policy_info", + .item = &POLICYINFO_it, + }, +}; + +const ASN1_ITEM ESS_SIGNING_CERT_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ESS_SIGNING_CERT_seq_tt, + .tcount = sizeof(ESS_SIGNING_CERT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ESS_SIGNING_CERT), + .sname = "ESS_SIGNING_CERT", +}; + + +ESS_SIGNING_CERT * +d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, const unsigned char **in, long len) +{ + return (ESS_SIGNING_CERT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ESS_SIGNING_CERT_it); +} +LCRYPTO_ALIAS(d2i_ESS_SIGNING_CERT); + +int +i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_SIGNING_CERT_it); +} +LCRYPTO_ALIAS(i2d_ESS_SIGNING_CERT); + +ESS_SIGNING_CERT * +ESS_SIGNING_CERT_new(void) +{ + return (ESS_SIGNING_CERT *)ASN1_item_new(&ESS_SIGNING_CERT_it); +} +LCRYPTO_ALIAS(ESS_SIGNING_CERT_new); + +void +ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ESS_SIGNING_CERT_it); +} +LCRYPTO_ALIAS(ESS_SIGNING_CERT_free); + +ESS_SIGNING_CERT * +ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *x) +{ + return ASN1_item_dup(&ESS_SIGNING_CERT_it, x); +} +LCRYPTO_ALIAS(ESS_SIGNING_CERT_dup); + +static const ASN1_TEMPLATE ESS_CERT_ID_V2_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ESS_CERT_ID_V2, hash_alg), + .field_name = "hash_alg", + .item = &X509_ALGOR_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ESS_CERT_ID_V2, hash), + .field_name = "hash", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ESS_CERT_ID_V2, issuer_serial), + .field_name = "issuer_serial", + .item = &ESS_ISSUER_SERIAL_it, + }, +}; + +static const ASN1_ITEM ESS_CERT_ID_V2_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ESS_CERT_ID_V2_seq_tt, + .tcount = sizeof(ESS_CERT_ID_V2_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ESS_CERT_ID_V2), + .sname = "ESS_CERT_ID_V2", +}; + +ESS_CERT_ID_V2 * +d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a, const unsigned char **in, long len) +{ + return (ESS_CERT_ID_V2 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ESS_CERT_ID_V2_it); +} + +int +i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_CERT_ID_V2_it); +} + +ESS_CERT_ID_V2 * +ESS_CERT_ID_V2_new(void) +{ + return (ESS_CERT_ID_V2 *)ASN1_item_new(&ESS_CERT_ID_V2_it); +} + +void +ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ESS_CERT_ID_V2_it); +} + +ESS_CERT_ID_V2 * +ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *x) +{ + return ASN1_item_dup(&ESS_CERT_ID_V2_it, x); +} + +static const ASN1_TEMPLATE ESS_SIGNING_CERT_V2_seq_tt[] = { + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(ESS_SIGNING_CERT_V2, cert_ids), + .field_name = "cert_ids", + .item = &ESS_CERT_ID_V2_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ESS_SIGNING_CERT_V2, policy_info), + .field_name = "policy_info", + .item = &POLICYINFO_it, + }, +}; + +static const ASN1_ITEM ESS_SIGNING_CERT_V2_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ESS_SIGNING_CERT_V2_seq_tt, + .tcount = sizeof(ESS_SIGNING_CERT_V2_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ESS_SIGNING_CERT_V2), + .sname = "ESS_SIGNING_CERT_V2", +}; + +ESS_SIGNING_CERT_V2 * +d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a, const unsigned char **in, long len) +{ + return (ESS_SIGNING_CERT_V2 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ESS_SIGNING_CERT_V2_it); +} + +int +i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_SIGNING_CERT_V2_it); +} + +ESS_SIGNING_CERT_V2 * +ESS_SIGNING_CERT_V2_new(void) +{ + return (ESS_SIGNING_CERT_V2 *)ASN1_item_new(&ESS_SIGNING_CERT_V2_it); +} + +void +ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ESS_SIGNING_CERT_V2_it); +} + +ESS_SIGNING_CERT_V2 * +ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *x) +{ + return ASN1_item_dup(&ESS_SIGNING_CERT_V2_it, x); +} + +/* Getting encapsulated TS_TST_INFO object from PKCS7. */ +TS_TST_INFO * +PKCS7_to_TS_TST_INFO(PKCS7 *token) +{ + PKCS7_SIGNED *pkcs7_signed; + PKCS7 *enveloped; + ASN1_TYPE *tst_info_wrapper; + ASN1_OCTET_STRING *tst_info_der; + const unsigned char *p; + + if (!PKCS7_type_is_signed(token)) { + TSerror(TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* Content must be present. */ + if (PKCS7_get_detached(token)) { + TSerror(TS_R_DETACHED_CONTENT); + return NULL; + } + + /* We have a signed data with content. */ + pkcs7_signed = token->d.sign; + enveloped = pkcs7_signed->contents; + if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) { + TSerror(TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* We have a DER encoded TST_INFO as the signed data. */ + tst_info_wrapper = enveloped->d.other; + if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) { + TSerror(TS_R_BAD_TYPE); + return NULL; + } + + /* We have the correct ASN1_OCTET_STRING type. */ + tst_info_der = tst_info_wrapper->value.octet_string; + /* At last, decode the TST_INFO. */ + p = tst_info_der->data; + return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length); +} +LCRYPTO_ALIAS(PKCS7_to_TS_TST_INFO); diff --git a/Libraries/libressl/crypto/ts/ts_conf.c b/Libraries/libressl/crypto/ts/ts_conf.c new file mode 100644 index 000000000..103d43027 --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_conf.c @@ -0,0 +1,548 @@ +/* $OpenBSD: ts_conf.c,v 1.12 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +/* Macro definitions for the configuration file. */ + +#define BASE_SECTION "tsa" +#define ENV_DEFAULT_TSA "default_tsa" +#define ENV_SERIAL "serial" +#define ENV_CRYPTO_DEVICE "crypto_device" +#define ENV_SIGNER_CERT "signer_cert" +#define ENV_CERTS "certs" +#define ENV_SIGNER_KEY "signer_key" +#define ENV_DEFAULT_POLICY "default_policy" +#define ENV_OTHER_POLICIES "other_policies" +#define ENV_DIGESTS "digests" +#define ENV_ACCURACY "accuracy" +#define ENV_ORDERING "ordering" +#define ENV_TSA_NAME "tsa_name" +#define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain" +#define ENV_VALUE_SECS "secs" +#define ENV_VALUE_MILLISECS "millisecs" +#define ENV_VALUE_MICROSECS "microsecs" +#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits" +#define ENV_VALUE_YES "yes" +#define ENV_VALUE_NO "no" + +/* Function definitions for certificate and key loading. */ + +X509 * +TS_CONF_load_cert(const char *file) +{ + BIO *cert = NULL; + X509 *x = NULL; + + if ((cert = BIO_new_file(file, "r")) == NULL) + goto end; + x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); + +end: + if (x == NULL) + fprintf(stderr, "unable to load certificate: %s\n", file); + BIO_free(cert); + return x; +} +LCRYPTO_ALIAS(TS_CONF_load_cert); + +STACK_OF(X509) * +TS_CONF_load_certs(const char *file) +{ + BIO *certs = NULL; + STACK_OF(X509) *othercerts = NULL; + STACK_OF(X509_INFO) *allcerts = NULL; + int i; + + if (!(certs = BIO_new_file(file, "r"))) + goto end; + + if (!(othercerts = sk_X509_new_null())) + goto end; + allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); + for (i = 0; i < sk_X509_INFO_num(allcerts); i++) { + X509_INFO *xi = sk_X509_INFO_value(allcerts, i); + if (xi->x509) { + if (sk_X509_push(othercerts, xi->x509) == 0) { + sk_X509_pop_free(othercerts, X509_free); + othercerts = NULL; + goto end; + } + xi->x509 = NULL; + } + } + +end: + if (othercerts == NULL) + fprintf(stderr, "unable to load certificates: %s\n", file); + sk_X509_INFO_pop_free(allcerts, X509_INFO_free); + BIO_free(certs); + return othercerts; +} +LCRYPTO_ALIAS(TS_CONF_load_certs); + +EVP_PKEY * +TS_CONF_load_key(const char *file, const char *pass) +{ + BIO *key = NULL; + EVP_PKEY *pkey = NULL; + + if (!(key = BIO_new_file(file, "r"))) + goto end; + pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass); + +end: + if (pkey == NULL) + fprintf(stderr, "unable to load private key: %s\n", file); + BIO_free(key); + return pkey; +} +LCRYPTO_ALIAS(TS_CONF_load_key); + +/* Function definitions for handling configuration options. */ + +static void +TS_CONF_lookup_fail(const char *name, const char *tag) +{ + fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); +} + +static void +TS_CONF_invalid(const char *name, const char *tag) +{ + fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); +} + +const char * +TS_CONF_get_tsa_section(CONF *conf, const char *section) +{ + if (!section) { + section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA); + if (!section) + TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA); + } + return section; +} +LCRYPTO_ALIAS(TS_CONF_get_tsa_section); + +int +TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx) +{ + int ret = 0; + char *serial = NCONF_get_string(conf, section, ENV_SERIAL); + + if (!serial) { + TS_CONF_lookup_fail(section, ENV_SERIAL); + goto err; + } + TS_RESP_CTX_set_serial_cb(ctx, cb, serial); + + ret = 1; + +err: + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_serial); + +#ifndef OPENSSL_NO_ENGINE + +int +TS_CONF_set_crypto_device(CONF *conf, const char *section, const char *device) +{ + int ret = 0; + + if (!device) + device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE); + + if (device && !TS_CONF_set_default_engine(device)) { + TS_CONF_invalid(section, ENV_CRYPTO_DEVICE); + goto err; + } + ret = 1; + +err: + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_crypto_device); + +int +TS_CONF_set_default_engine(const char *name) +{ + ENGINE *e = NULL; + int ret = 0; + + /* Leave the default if builtin specified. */ + if (strcmp(name, "builtin") == 0) + return 1; + + if (!(e = ENGINE_by_id(name))) + goto err; + /* All the operations are going to be carried out by the engine. */ + if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) + goto err; + ret = 1; + +err: + if (!ret) { + TSerror(TS_R_COULD_NOT_SET_ENGINE); + ERR_asprintf_error_data("engine:%s", name); + } + ENGINE_free(e); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_default_engine); + +#endif + +int +TS_CONF_set_signer_cert(CONF *conf, const char *section, const char *cert, + TS_RESP_CTX *ctx) +{ + int ret = 0; + X509 *cert_obj = NULL; + + if (!cert) + cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT); + if (!cert) { + TS_CONF_lookup_fail(section, ENV_SIGNER_CERT); + goto err; + } + if (!(cert_obj = TS_CONF_load_cert(cert))) + goto err; + if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj)) + goto err; + + ret = 1; + +err: + X509_free(cert_obj); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_signer_cert); + +int +TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx) +{ + int ret = 0; + STACK_OF(X509) *certs_obj = NULL; + + if (!certs) + certs = NCONF_get_string(conf, section, ENV_CERTS); + /* Certificate chain is optional. */ + if (!certs) + goto end; + if (!(certs_obj = TS_CONF_load_certs(certs))) + goto err; + if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) + goto err; + +end: + ret = 1; +err: + sk_X509_pop_free(certs_obj, X509_free); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_certs); + +int +TS_CONF_set_signer_key(CONF *conf, const char *section, const char *key, + const char *pass, TS_RESP_CTX *ctx) +{ + int ret = 0; + EVP_PKEY *key_obj = NULL; + + if (!key) + key = NCONF_get_string(conf, section, ENV_SIGNER_KEY); + if (!key) { + TS_CONF_lookup_fail(section, ENV_SIGNER_KEY); + goto err; + } + if (!(key_obj = TS_CONF_load_key(key, pass))) + goto err; + if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) + goto err; + + ret = 1; + +err: + EVP_PKEY_free(key_obj); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_signer_key); + +int +TS_CONF_set_def_policy(CONF *conf, const char *section, const char *policy, + TS_RESP_CTX *ctx) +{ + int ret = 0; + ASN1_OBJECT *policy_obj = NULL; + + if (!policy) + policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY); + if (!policy) { + TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!(policy_obj = OBJ_txt2obj(policy, 0))) { + TS_CONF_invalid(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) + goto err; + + ret = 1; + +err: + ASN1_OBJECT_free(policy_obj); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_def_policy); + +int +TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *policies = NCONF_get_string(conf, section, ENV_OTHER_POLICIES); + + /* If no other policy is specified, that's fine. */ + if (policies && !(list = X509V3_parse_list(policies))) { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + if (!TS_RESP_CTX_add_policy(ctx, objtmp)) + goto err; + ASN1_OBJECT_free(objtmp); + } + + ret = 1; + +err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_policies); + +int +TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); + + if (!digests) { + TS_CONF_lookup_fail(section, ENV_DIGESTS); + goto err; + } + if (!(list = X509V3_parse_list(digests))) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (sk_CONF_VALUE_num(list) == 0) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(extval))) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (!TS_RESP_CTX_add_md(ctx, md)) + goto err; + } + + ret = 1; + +err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_digests); + +int +TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + int secs = 0, millis = 0, micros = 0; + STACK_OF(CONF_VALUE) *list = NULL; + char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); + + if (accuracy && !(list = X509V3_parse_list(accuracy))) { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + if (strcmp(val->name, ENV_VALUE_SECS) == 0) { + if (val->value) + secs = atoi(val->value); + } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) { + if (val->value) + millis = atoi(val->value); + } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) { + if (val->value) + micros = atoi(val->value); + } else { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + } + if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) + goto err; + + ret = 1; + +err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_accuracy); + +int +TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx) +{ + int ret = 0; + long digits = 0; + + /* If not specified, set the default value to 0, i.e. sec precision */ + if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, + &digits)) + digits = 0; + if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) { + TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); + goto err; + } + + if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits)) + goto err; + + return 1; + +err: + return ret; +} +LCRYPTO_ALIAS(TS_CONF_set_clock_precision_digits); + +static int +TS_CONF_add_flag(CONF *conf, const char *section, const char *field, int flag, + TS_RESP_CTX *ctx) +{ + /* Default is false. */ + const char *value = NCONF_get_string(conf, section, field); + + if (value) { + if (strcmp(value, ENV_VALUE_YES) == 0) + TS_RESP_CTX_add_flags(ctx, flag); + else if (strcmp(value, ENV_VALUE_NO) != 0) { + TS_CONF_invalid(section, field); + return 0; + } + } + + return 1; +} + +int +TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx); +} +LCRYPTO_ALIAS(TS_CONF_set_ordering); + +int +TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx); +} +LCRYPTO_ALIAS(TS_CONF_set_tsa_name); + +int +TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, + TS_ESS_CERT_ID_CHAIN, ctx); +} +LCRYPTO_ALIAS(TS_CONF_set_ess_cert_id_chain); diff --git a/Libraries/libressl/crypto/ts/ts_err.c b/Libraries/libressl/crypto/ts/ts_err.c new file mode 100644 index 000000000..bb8209a85 --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_err.c @@ -0,0 +1,124 @@ +/* $OpenBSD: ts_err.c,v 1.7 2023/07/07 07:25:21 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason) + +static ERR_STRING_DATA TS_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA TS_str_reasons[]= { + {ERR_REASON(TS_R_BAD_PKCS7_TYPE) , "bad pkcs7 type"}, + {ERR_REASON(TS_R_BAD_TYPE) , "bad type"}, + {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE) , "could not set engine"}, + {ERR_REASON(TS_R_COULD_NOT_SET_TIME) , "could not set time"}, + {ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) , "d2i ts resp int failed"}, + {ERR_REASON(TS_R_DETACHED_CONTENT) , "detached content"}, + {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR), "ess add signing cert error"}, + {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR), "ess signing certificate error"}, + {ERR_REASON(TS_R_INVALID_NULL_POINTER) , "invalid null pointer"}, + {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE), "invalid signer certificate purpose"}, + {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"}, + {ERR_REASON(TS_R_NONCE_MISMATCH) , "nonce mismatch"}, + {ERR_REASON(TS_R_NONCE_NOT_RETURNED) , "nonce not returned"}, + {ERR_REASON(TS_R_NO_CONTENT) , "no content"}, + {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN) , "no time stamp token"}, + {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"}, + {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR), "pkcs7 add signed attr error"}, + {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED), "pkcs7 to ts tst info failed"}, + {ERR_REASON(TS_R_POLICY_MISMATCH) , "policy mismatch"}, + {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"}, + {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR) , "response setup error"}, + {ERR_REASON(TS_R_SIGNATURE_FAILURE) , "signature failure"}, + {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"}, + {ERR_REASON(TS_R_TIME_SYSCALL_ERROR) , "time syscall error"}, + {ERR_REASON(TS_R_TOKEN_NOT_PRESENT) , "token not present"}, + {ERR_REASON(TS_R_TOKEN_PRESENT) , "token present"}, + {ERR_REASON(TS_R_TSA_NAME_MISMATCH) , "tsa name mismatch"}, + {ERR_REASON(TS_R_TSA_UNTRUSTED) , "tsa untrusted"}, + {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR) , "tst info setup error"}, + {ERR_REASON(TS_R_TS_DATASIGN) , "ts datasign"}, + {ERR_REASON(TS_R_UNACCEPTABLE_POLICY) , "unacceptable policy"}, + {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"}, + {ERR_REASON(TS_R_UNSUPPORTED_VERSION) , "unsupported version"}, + {ERR_REASON(TS_R_WRONG_CONTENT_TYPE) , "wrong content type"}, + {0, NULL} +}; + +#endif + +void +ERR_load_TS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(TS_str_functs[0].error) == NULL) { + ERR_load_strings(0, TS_str_functs); + ERR_load_strings(0, TS_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_TS_strings); diff --git a/Libraries/libressl/crypto/ts/ts_lib.c b/Libraries/libressl/crypto/ts/ts_lib.c new file mode 100644 index 000000000..1e94922aa --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_lib.c @@ -0,0 +1,158 @@ +/* $OpenBSD: ts_lib.c,v 1.14 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "bn_local.h" +#include "x509_local.h" + +/* Local function declarations. */ + +/* Function definitions. */ + +int +TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) +{ + BIGNUM num_bn; + int result = 0; + char *hex; + + BN_init(&num_bn); + ASN1_INTEGER_to_BN(num, &num_bn); + if ((hex = BN_bn2hex(&num_bn))) { + result = BIO_write(bio, "0x", 2) > 0; + result = result && BIO_write(bio, hex, strlen(hex)) > 0; + free(hex); + } + BN_free(&num_bn); + + return result; +} +LCRYPTO_ALIAS(TS_ASN1_INTEGER_print_bio); + +int +TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) +{ + char obj_txt[128]; + + int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); + if (len >= sizeof(obj_txt)) + len = sizeof(obj_txt) - 1; + BIO_write(bio, obj_txt, len); + BIO_write(bio, "\n", 1); + return 1; +} +LCRYPTO_ALIAS(TS_OBJ_print_bio); + +int +TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions) +{ + int i, critical, n; + X509_EXTENSION *ex; + ASN1_OBJECT *obj; + + BIO_printf(bio, "Extensions:\n"); + n = X509v3_get_ext_count(extensions); + for (i = 0; i < n; i++) { + ex = X509v3_get_ext(extensions, i); + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + critical = X509_EXTENSION_get_critical(ex); + BIO_printf(bio, ": %s\n", critical ? "critical" : ""); + if (!X509V3_EXT_print(bio, ex, 0, 4)) { + BIO_printf(bio, "%4s", ""); + ASN1_STRING_print(bio, ex->value); + } + BIO_write(bio, "\n", 1); + } + + return 1; +} +LCRYPTO_ALIAS(TS_ext_print_bio); + +int +TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg) +{ + int i = OBJ_obj2nid(alg->algorithm); + + return BIO_printf(bio, "Hash Algorithm: %s\n", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); +} +LCRYPTO_ALIAS(TS_X509_ALGOR_print_bio); + +int +TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) +{ + ASN1_OCTET_STRING *msg; + + TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a)); + + BIO_printf(bio, "Message data:\n"); + msg = TS_MSG_IMPRINT_get_msg(a); + BIO_dump_indent(bio, (const char *)ASN1_STRING_data(msg), + ASN1_STRING_length(msg), 4); + + return 1; +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_print_bio); diff --git a/Libraries/libressl/crypto/ts/ts_local.h b/Libraries/libressl/crypto/ts/ts_local.h new file mode 100644 index 000000000..07c9861e0 --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_local.h @@ -0,0 +1,316 @@ +/* $OpenBSD: ts_local.h,v 1.3 2022/11/26 17:23:18 tb Exp $ */ +/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL + * project 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_TS_LOCAL_H +#define HEADER_TS_LOCAL_H + +__BEGIN_HIDDEN_DECLS + +/* + * MessageImprint ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * hashedMessage OCTET STRING } + */ + +struct TS_msg_imprint_st { + X509_ALGOR *hash_algo; + ASN1_OCTET_STRING *hashed_msg; +}; + +/* + * TimeStampReq ::= SEQUENCE { + * version INTEGER { v1(1) }, + * messageImprint MessageImprint, + * --a hash algorithm OID and the hash value of the data to be + * --time-stamped + * reqPolicy TSAPolicyId OPTIONAL, + * nonce INTEGER OPTIONAL, + * certReq BOOLEAN DEFAULT FALSE, + * extensions [0] IMPLICIT Extensions OPTIONAL } + */ + +struct TS_req_st { + ASN1_INTEGER *version; + TS_MSG_IMPRINT *msg_imprint; + ASN1_OBJECT *policy_id; /* OPTIONAL */ + ASN1_INTEGER *nonce; /* OPTIONAL */ + ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ +}; + +/* + * Accuracy ::= SEQUENCE { + * seconds INTEGER OPTIONAL, + * millis [0] INTEGER (1..999) OPTIONAL, + * micros [1] INTEGER (1..999) OPTIONAL } + */ + +struct TS_accuracy_st { + ASN1_INTEGER *seconds; + ASN1_INTEGER *millis; + ASN1_INTEGER *micros; +}; + +/* + * TSTInfo ::= SEQUENCE { + * version INTEGER { v1(1) }, + * policy TSAPolicyId, + * messageImprint MessageImprint, + * -- MUST have the same value as the similar field in + * -- TimeStampReq + * serialNumber INTEGER, + * -- Time-Stamping users MUST be ready to accommodate integers + * -- up to 160 bits. + * genTime GeneralizedTime, + * accuracy Accuracy OPTIONAL, + * ordering BOOLEAN DEFAULT FALSE, + * nonce INTEGER OPTIONAL, + * -- MUST be present if the similar field was present + * -- in TimeStampReq. In that case it MUST have the same value. + * tsa [0] GeneralName OPTIONAL, + * extensions [1] IMPLICIT Extensions OPTIONAL } + */ + +struct TS_tst_info_st { + ASN1_INTEGER *version; + ASN1_OBJECT *policy_id; + TS_MSG_IMPRINT *msg_imprint; + ASN1_INTEGER *serial; + ASN1_GENERALIZEDTIME *time; + TS_ACCURACY *accuracy; + ASN1_BOOLEAN ordering; + ASN1_INTEGER *nonce; + GENERAL_NAME *tsa; + STACK_OF(X509_EXTENSION) *extensions; +}; + +/* + * PKIStatusInfo ::= SEQUENCE { + * status PKIStatus, + * statusString PKIFreeText OPTIONAL, + * failInfo PKIFailureInfo OPTIONAL } + * + * From RFC 1510 - section 3.1.1: + * PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + * -- text encoded as UTF-8 String (note: each UTF8String SHOULD + * -- include an RFC 1766 language tag to indicate the language + * -- of the contained text) + */ + +struct TS_status_info_st { + ASN1_INTEGER *status; + STACK_OF(ASN1_UTF8STRING) *text; + ASN1_BIT_STRING *failure_info; +}; + +/* + * TimeStampResp ::= SEQUENCE { + * status PKIStatusInfo, + * timeStampToken TimeStampToken OPTIONAL } + */ + +struct TS_resp_st { + TS_STATUS_INFO *status_info; + PKCS7 *token; + TS_TST_INFO *tst_info; +}; + +/* The structure below would belong to the ESS component. */ + +/* + * IssuerSerial ::= SEQUENCE { + * issuer GeneralNames, + * serialNumber CertificateSerialNumber + * } + */ + +struct ESS_issuer_serial { + STACK_OF(GENERAL_NAME) *issuer; + ASN1_INTEGER *serial; +}; + +/* + * ESSCertID ::= SEQUENCE { + * certHash Hash, + * issuerSerial IssuerSerial OPTIONAL + * } + */ + +struct ESS_cert_id { + ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ + ESS_ISSUER_SERIAL *issuer_serial; +}; + +/* + * SigningCertificate ::= SEQUENCE { + * certs SEQUENCE OF ESSCertID, + * policies SEQUENCE OF PolicyInformation OPTIONAL + * } + */ + +struct ESS_signing_cert { + STACK_OF(ESS_CERT_ID) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; +}; + +/* + * ESSCertIDv2 ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier + * DEFAULT {algorithm id-sha256}, + * certHash Hash, + * issuerSerial IssuerSerial OPTIONAL } + */ + +struct ESS_cert_id_v2 { + X509_ALGOR *hash_alg; /* Default SHA-256. */ + ASN1_OCTET_STRING *hash; + ESS_ISSUER_SERIAL *issuer_serial; +}; + +/* + * SigningCertificateV2 ::= SEQUENCE { + * certs SEQUENCE OF ESSCertIDv2, + * policies SEQUENCE OF PolicyInformation OPTIONAL } + */ + +struct ESS_signing_cert_v2 { + STACK_OF(ESS_CERT_ID_V2) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; +}; + +struct TS_resp_ctx { + X509 *signer_cert; + EVP_PKEY *signer_key; + STACK_OF(X509) *certs; /* Certs to include in signed data. */ + STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ + ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ + STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ + ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ + unsigned clock_precision_digits; /* fraction of seconds in + time stamp token. */ + unsigned flags; /* Optional info, see values above. */ + + /* Callback functions. */ + TS_serial_cb serial_cb; + void *serial_cb_data; /* User data for serial_cb. */ + + TS_time_cb time_cb; + void *time_cb_data; /* User data for time_cb. */ + + TS_extension_cb extension_cb; + void *extension_cb_data; /* User data for extension_cb. */ + + /* These members are used only while creating the response. */ + TS_REQ *request; + TS_RESP *response; + TS_TST_INFO *tst_info; +}; + +/* Context structure for the generic verify method. */ + +struct TS_verify_ctx { + /* Set this to the union of TS_VFY_... flags you want to carry out. */ + unsigned flags; + + /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ + X509_STORE *store; + STACK_OF(X509) *certs; + + /* Must be set only with TS_VFY_POLICY. */ + ASN1_OBJECT *policy; + + /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, + the algorithm from the response is used. */ + X509_ALGOR *md_alg; + unsigned char *imprint; + unsigned imprint_len; + + /* Must be set only with TS_VFY_DATA. */ + BIO *data; + + /* Must be set only with TS_VFY_TSA_NAME. */ + ASN1_INTEGER *nonce; + + /* Must be set only with TS_VFY_TSA_NAME. */ + GENERAL_NAME *tsa_name; +}; + +/* + * Public OpenSSL API that we do not currently want to expose. + */ + +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new(void); +void ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a); +int i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **pp); +ESS_CERT_ID_V2 *d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a, const unsigned char **pp, + long length); +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *a); + +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new(void); +void ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a); +int i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, + unsigned char **pp); +ESS_SIGNING_CERT_V2 *d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *a); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_TS_LOCAL_H */ diff --git a/Libraries/libressl/crypto/ts/ts_req_print.c b/Libraries/libressl/crypto/ts/ts_req_print.c new file mode 100644 index 000000000..ddcdda97a --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_req_print.c @@ -0,0 +1,105 @@ +/* $OpenBSD: ts_req_print.c,v 1.5 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +/* Function definitions. */ + +int +TS_REQ_print_bio(BIO *bio, TS_REQ *a) +{ + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *nonce; + + if (a == NULL) + return 0; + + v = TS_REQ_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a)); + + BIO_printf(bio, "Policy OID: "); + policy_id = TS_REQ_get_policy_id(a); + if (policy_id == NULL) + BIO_printf(bio, "unspecified\n"); + else + TS_OBJ_print_bio(bio, policy_id); + + BIO_printf(bio, "Nonce: "); + nonce = TS_REQ_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + BIO_printf(bio, "Certificate required: %s\n", + TS_REQ_get_cert_req(a) ? "yes" : "no"); + + TS_ext_print_bio(bio, TS_REQ_get_exts(a)); + + return 1; +} +LCRYPTO_ALIAS(TS_REQ_print_bio); diff --git a/Libraries/libressl/crypto/ts/ts_req_utils.c b/Libraries/libressl/crypto/ts/ts_req_utils.c new file mode 100644 index 000000000..d67941806 --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_req_utils.c @@ -0,0 +1,281 @@ +/* $OpenBSD: ts_req_utils.c,v 1.9 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "ts_local.h" + +int +TS_REQ_set_version(TS_REQ *a, long version) +{ + return ASN1_INTEGER_set(a->version, version); +} +LCRYPTO_ALIAS(TS_REQ_set_version); + +long +TS_REQ_get_version(const TS_REQ *a) +{ + return ASN1_INTEGER_get(a->version); +} +LCRYPTO_ALIAS(TS_REQ_get_version); + +int +TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) +{ + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; +} +LCRYPTO_ALIAS(TS_REQ_set_msg_imprint); + +TS_MSG_IMPRINT * +TS_REQ_get_msg_imprint(TS_REQ *a) +{ + return a->msg_imprint; +} +LCRYPTO_ALIAS(TS_REQ_get_msg_imprint); + +int +TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) +{ + X509_ALGOR *new_alg; + + if (a->hash_algo == alg) + return 1; + new_alg = X509_ALGOR_dup(alg); + if (new_alg == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + X509_ALGOR_free(a->hash_algo); + a->hash_algo = new_alg; + return 1; +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_set_algo); + +X509_ALGOR * +TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a) +{ + return a->hash_algo; +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_get_algo); + +int +TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len) +{ + return ASN1_OCTET_STRING_set(a->hashed_msg, d, len); +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_set_msg); + +ASN1_OCTET_STRING * +TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a) +{ + return a->hashed_msg; +} +LCRYPTO_ALIAS(TS_MSG_IMPRINT_get_msg); + +int +TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy) +{ + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; +} +LCRYPTO_ALIAS(TS_REQ_set_policy_id); + +ASN1_OBJECT * +TS_REQ_get_policy_id(TS_REQ *a) +{ + return a->policy_id; +} +LCRYPTO_ALIAS(TS_REQ_get_policy_id); + +int +TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) +{ + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; +} +LCRYPTO_ALIAS(TS_REQ_set_nonce); + +const ASN1_INTEGER * +TS_REQ_get_nonce(const TS_REQ *a) +{ + return a->nonce; +} +LCRYPTO_ALIAS(TS_REQ_get_nonce); + +int +TS_REQ_set_cert_req(TS_REQ *a, int cert_req) +{ + a->cert_req = cert_req ? 0xFF : 0x00; + return 1; +} +LCRYPTO_ALIAS(TS_REQ_set_cert_req); + +int +TS_REQ_get_cert_req(const TS_REQ *a) +{ + return a->cert_req ? 1 : 0; +} +LCRYPTO_ALIAS(TS_REQ_get_cert_req); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a) +{ + return a->extensions; +} +LCRYPTO_ALIAS(TS_REQ_get_exts); + +void +TS_REQ_ext_free(TS_REQ *a) +{ + if (!a) + return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; +} +LCRYPTO_ALIAS(TS_REQ_ext_free); + +int +TS_REQ_get_ext_count(TS_REQ *a) +{ + return X509v3_get_ext_count(a->extensions); +} +LCRYPTO_ALIAS(TS_REQ_get_ext_count); + +int +TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); +} +LCRYPTO_ALIAS(TS_REQ_get_ext_by_NID); + +int +TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); +} +LCRYPTO_ALIAS(TS_REQ_get_ext_by_OBJ); + +int +TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); +} +LCRYPTO_ALIAS(TS_REQ_get_ext_by_critical); + +X509_EXTENSION * +TS_REQ_get_ext(TS_REQ *a, int loc) +{ + return X509v3_get_ext(a->extensions, loc); +} +LCRYPTO_ALIAS(TS_REQ_get_ext); + +X509_EXTENSION * +TS_REQ_delete_ext(TS_REQ *a, int loc) +{ + return X509v3_delete_ext(a->extensions, loc); +} +LCRYPTO_ALIAS(TS_REQ_delete_ext); + +int +TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&a->extensions, ex, loc) != NULL; +} +LCRYPTO_ALIAS(TS_REQ_add_ext); + +void * +TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(a->extensions, nid, crit, idx); +} +LCRYPTO_ALIAS(TS_REQ_get_ext_d2i); diff --git a/Libraries/libressl/crypto/ts/ts_rsp_print.c b/Libraries/libressl/crypto/ts/ts_rsp_print.c new file mode 100644 index 000000000..c65d22668 --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_rsp_print.c @@ -0,0 +1,306 @@ +/* $OpenBSD: ts_rsp_print.c,v 1.7 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "ts_local.h" + +struct status_map_st { + int bit; + const char *text; +}; + +/* Local function declarations. */ + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v); +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy); + +/* Function definitions. */ + +int +TS_RESP_print_bio(BIO *bio, TS_RESP *a) +{ + TS_TST_INFO *tst_info; + + BIO_printf(bio, "Status info:\n"); + TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a)); + + BIO_printf(bio, "\nTST info:\n"); + tst_info = TS_RESP_get_tst_info(a); + if (tst_info != NULL) + TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a)); + else + BIO_printf(bio, "Not included.\n"); + + return 1; +} +LCRYPTO_ALIAS(TS_RESP_print_bio); + +int +TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a) +{ + static const char *status_map[] = { + "Granted.", + "Granted with modifications.", + "Rejected.", + "Waiting.", + "Revocation warning.", + "Revoked." + }; + static struct status_map_st failure_map[] = { + { + TS_INFO_BAD_ALG, + "unrecognized or unsupported algorithm identifier" + }, + { + TS_INFO_BAD_REQUEST, + "transaction not permitted or supported" + }, + { + TS_INFO_BAD_DATA_FORMAT, + "the data submitted has the wrong format" + }, + { + TS_INFO_TIME_NOT_AVAILABLE, + "the TSA's time source is not available" + }, + { + TS_INFO_UNACCEPTED_POLICY, + "the requested TSA policy is not supported by the TSA" + }, + { + TS_INFO_UNACCEPTED_EXTENSION, + "the requested extension is not supported by the TSA" + }, + { + TS_INFO_ADD_INFO_NOT_AVAILABLE, + "the additional information requested could not be understood " + "or is not available" + }, + { + TS_INFO_SYSTEM_FAILURE, + "the request cannot be handled due to system failure" + }, + { -1, NULL } + }; + long status; + int i, lines = 0; + + /* Printing status code. */ + BIO_printf(bio, "Status: "); + status = ASN1_INTEGER_get(a->status); + if (0 <= status && + status < (long)(sizeof(status_map) / sizeof(status_map[0]))) + BIO_printf(bio, "%s\n", status_map[status]); + else + BIO_printf(bio, "out of bounds\n"); + + /* Printing status description. */ + BIO_printf(bio, "Status description: "); + for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) { + if (i > 0) + BIO_puts(bio, "\t"); + ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), + 0); + BIO_puts(bio, "\n"); + } + if (i == 0) + BIO_printf(bio, "unspecified\n"); + + /* Printing failure information. */ + BIO_printf(bio, "Failure info: "); + if (a->failure_info != NULL) + lines = TS_status_map_print(bio, failure_map, a->failure_info); + if (lines == 0) + BIO_printf(bio, "unspecified"); + BIO_printf(bio, "\n"); + + return 1; +} +LCRYPTO_ALIAS(TS_STATUS_INFO_print_bio); + +static int +TS_status_map_print(BIO *bio, struct status_map_st *a, ASN1_BIT_STRING *v) +{ + int lines = 0; + + for (; a->bit >= 0; ++a) { + if (ASN1_BIT_STRING_get_bit(v, a->bit)) { + if (++lines > 1) + BIO_printf(bio, ", "); + BIO_printf(bio, "%s", a->text); + } + } + + return lines; +} + +int +TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a) +{ + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *serial; + const ASN1_GENERALIZEDTIME *gtime; + TS_ACCURACY *accuracy; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name; + + if (a == NULL) + return 0; + + /* Print version. */ + v = TS_TST_INFO_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + /* Print policy id. */ + BIO_printf(bio, "Policy OID: "); + policy_id = TS_TST_INFO_get_policy_id(a); + TS_OBJ_print_bio(bio, policy_id); + + /* Print message imprint. */ + TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a)); + + /* Print serial number. */ + BIO_printf(bio, "Serial number: "); + serial = TS_TST_INFO_get_serial(a); + if (serial == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, serial); + BIO_write(bio, "\n", 1); + + /* Print time stamp. */ + BIO_printf(bio, "Time stamp: "); + gtime = TS_TST_INFO_get_time(a); + ASN1_GENERALIZEDTIME_print(bio, gtime); + BIO_write(bio, "\n", 1); + + /* Print accuracy. */ + BIO_printf(bio, "Accuracy: "); + accuracy = TS_TST_INFO_get_accuracy(a); + if (accuracy == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ACCURACY_print_bio(bio, accuracy); + BIO_write(bio, "\n", 1); + + /* Print ordering. */ + BIO_printf(bio, "Ordering: %s\n", + TS_TST_INFO_get_ordering(a) ? "yes" : "no"); + + /* Print nonce. */ + BIO_printf(bio, "Nonce: "); + nonce = TS_TST_INFO_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + /* Print TSA name. */ + BIO_printf(bio, "TSA: "); + tsa_name = TS_TST_INFO_get_tsa(a); + if (tsa_name == NULL) + BIO_printf(bio, "unspecified"); + else { + STACK_OF(CONF_VALUE) *nval; + if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL))) + X509V3_EXT_val_prn(bio, nval, 0, 0); + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + } + BIO_write(bio, "\n", 1); + + /* Print extensions. */ + TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a)); + + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_print_bio); + +static int +TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy) +{ + const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy); + const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy); + const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy); + + if (seconds != NULL) + TS_ASN1_INTEGER_print_bio(bio, seconds); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " seconds, "); + if (millis != NULL) + TS_ASN1_INTEGER_print_bio(bio, millis); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " millis, "); + if (micros != NULL) + TS_ASN1_INTEGER_print_bio(bio, micros); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " micros"); + + return 1; +} diff --git a/Libraries/libressl/crypto/ts/ts_rsp_sign.c b/Libraries/libressl/crypto/ts/ts_rsp_sign.c new file mode 100644 index 000000000..3013cffbc --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_rsp_sign.c @@ -0,0 +1,1058 @@ +/* $OpenBSD: ts_rsp_sign.c,v 1.32 2023/08/22 08:09:36 tb Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include + +#include "evp_local.h" +#include "ts_local.h" +#include "x509_local.h" + +/* Private function declarations. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); +static int def_time_cb(struct TS_resp_ctx *, void *, time_t *sec, long *usec); +static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx); +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx); +static int TS_RESP_check_request(TS_RESP_CTX *ctx); +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx); +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy); +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); +static int TS_RESP_sign(TS_RESP_CTX *ctx); + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs); +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); +static int TS_TST_INFO_content_new(PKCS7 *p7); +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); + +static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( + ASN1_GENERALIZEDTIME *, time_t, long, unsigned); + +/* Default callbacks for response generation. */ + +static ASN1_INTEGER * +def_serial_cb(struct TS_resp_ctx *ctx, void *data) +{ + ASN1_INTEGER *serial; + + if ((serial = ASN1_INTEGER_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(serial, 1)) + goto err; + + return serial; + + err: + ASN1_INTEGER_free(serial); + TSerror(ERR_R_MALLOC_FAILURE); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Error during serial number generation."); + + return NULL; +} + +/* Use the gettimeofday function call. */ +static int +def_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) != 0) { + TSerror(TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller. */ + *sec = tv.tv_sec; + *usec = tv.tv_usec; + + return 1; +} + +static int +def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, void *data) +{ + /* No extensions are processed here. */ + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Unsupported extension."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); + return 0; +} + +void +TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) +{ + ctx->time_cb = cb; + ctx->time_cb_data = data; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_time_cb); + +/* TS_RESP_CTX management functions. */ + +TS_RESP_CTX * +TS_RESP_CTX_new(void) +{ + TS_RESP_CTX *ctx; + + if (!(ctx = calloc(1, sizeof(TS_RESP_CTX)))) { + TSerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* Setting default callbacks. */ + ctx->serial_cb = def_serial_cb; + ctx->time_cb = def_time_cb; + ctx->extension_cb = def_extension_cb; + + return ctx; +} +LCRYPTO_ALIAS(TS_RESP_CTX_new); + +void +TS_RESP_CTX_free(TS_RESP_CTX *ctx) +{ + if (!ctx) + return; + + X509_free(ctx->signer_cert); + EVP_PKEY_free(ctx->signer_key); + sk_X509_pop_free(ctx->certs, X509_free); + sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); + ASN1_OBJECT_free(ctx->default_policy); + sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ + ASN1_INTEGER_free(ctx->seconds); + ASN1_INTEGER_free(ctx->millis); + ASN1_INTEGER_free(ctx->micros); + free(ctx); +} +LCRYPTO_ALIAS(TS_RESP_CTX_free); + +int +TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) +{ + if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { + TSerror(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); + return 0; + } + X509_free(ctx->signer_cert); + ctx->signer_cert = signer; + CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); + return 1; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_signer_cert); + +int +TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) +{ + EVP_PKEY_free(ctx->signer_key); + ctx->signer_key = key; + CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); + + return 1; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_signer_key); + +int +TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy) +{ + if (ctx->default_policy) + ASN1_OBJECT_free(ctx->default_policy); + if (!(ctx->default_policy = OBJ_dup(def_policy))) + goto err; + return 1; + +err: + TSerror(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_def_policy); + +int +TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) +{ + int i; + + if (ctx->certs) { + sk_X509_pop_free(ctx->certs, X509_free); + ctx->certs = NULL; + } + if (!certs) + return 1; + if (!(ctx->certs = sk_X509_dup(certs))) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < sk_X509_num(ctx->certs); ++i) { + X509 *cert = sk_X509_value(ctx->certs, i); + CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509); + } + + return 1; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_certs); + +int +TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy) +{ + ASN1_OBJECT *copy = NULL; + + /* Create new policy stack if necessary. */ + if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) + goto err; + if (!(copy = OBJ_dup(policy))) + goto err; + if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) + goto err; + + return 1; + +err: + TSerror(ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(copy); + return 0; +} +LCRYPTO_ALIAS(TS_RESP_CTX_add_policy); + +int +TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) +{ + /* Create new md stack if necessary. */ + if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) + goto err; + /* Add the shared md, no copy needed. */ + if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) + goto err; + + return 1; + +err: + TSerror(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(TS_RESP_CTX_add_md); + +#define TS_RESP_CTX_accuracy_free(ctx) \ + ASN1_INTEGER_free(ctx->seconds); \ + ctx->seconds = NULL; \ + ASN1_INTEGER_free(ctx->millis); \ + ctx->millis = NULL; \ + ASN1_INTEGER_free(ctx->micros); \ + ctx->micros = NULL; + +int +TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, int secs, int millis, int micros) +{ + TS_RESP_CTX_accuracy_free(ctx); + if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) || + !ASN1_INTEGER_set(ctx->seconds, secs))) + goto err; + if (millis && (!(ctx->millis = ASN1_INTEGER_new()) || + !ASN1_INTEGER_set(ctx->millis, millis))) + goto err; + if (micros && (!(ctx->micros = ASN1_INTEGER_new()) || + !ASN1_INTEGER_set(ctx->micros, micros))) + goto err; + + return 1; + +err: + TS_RESP_CTX_accuracy_free(ctx); + TSerror(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_accuracy); + +void +TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} +LCRYPTO_ALIAS(TS_RESP_CTX_add_flags); + +void +TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) +{ + ctx->serial_cb = cb; + ctx->serial_cb_data = data; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_serial_cb); + +void +TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, TS_extension_cb cb, void *data) +{ + ctx->extension_cb = cb; + ctx->extension_cb_data = data; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_extension_cb); + +int +TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, int status, const char *text) +{ + TS_STATUS_INFO *si = NULL; + ASN1_UTF8STRING *utf8_text = NULL; + int ret = 0; + + if (!(si = TS_STATUS_INFO_new())) + goto err; + if (!ASN1_INTEGER_set(si->status, status)) + goto err; + if (text) { + if (!(utf8_text = ASN1_UTF8STRING_new()) || + !ASN1_STRING_set(utf8_text, text, strlen(text))) + goto err; + if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) + goto err; + if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) + goto err; + utf8_text = NULL; /* Ownership is lost. */ + } + if (!TS_RESP_set_status_info(ctx->response, si)) + goto err; + ret = 1; + +err: + if (!ret) + TSerror(ERR_R_MALLOC_FAILURE); + TS_STATUS_INFO_free(si); + ASN1_UTF8STRING_free(utf8_text); + return ret; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_status_info); + +int +TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, int status, const char *text) +{ + int ret = 1; + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + + if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) { + /* Status has not been set, set it now. */ + ret = TS_RESP_CTX_set_status_info(ctx, status, text); + } + return ret; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_status_info_cond); + +int +TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) +{ + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + + if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) + goto err; + if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) + goto err; + return 1; + +err: + TSerror(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(TS_RESP_CTX_add_failure_info); + +TS_REQ * +TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) +{ + return ctx->request; +} +LCRYPTO_ALIAS(TS_RESP_CTX_get_request); + +TS_TST_INFO * +TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) +{ + return ctx->tst_info; +} +LCRYPTO_ALIAS(TS_RESP_CTX_get_tst_info); + +int +TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision) +{ + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + return 0; + ctx->clock_precision_digits = precision; + return 1; +} +LCRYPTO_ALIAS(TS_RESP_CTX_set_clock_precision_digits); + +/* Main entry method of the response generation. */ +TS_RESP * +TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) +{ + ASN1_OBJECT *policy; + TS_RESP *response; + int result = 0; + + TS_RESP_CTX_init(ctx); + + /* Creating the response object. */ + if (!(ctx->response = TS_RESP_new())) { + TSerror(ERR_R_MALLOC_FAILURE); + goto end; + } + + /* Parsing DER request. */ + if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request format or " + "system error."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + goto end; + } + + /* Setting default status info. */ + if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) + goto end; + + /* Checking the request format. */ + if (!TS_RESP_check_request(ctx)) + goto end; + + /* Checking acceptable policies. */ + if (!(policy = TS_RESP_get_policy(ctx))) + goto end; + + /* Creating the TS_TST_INFO object. */ + if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) + goto end; + + /* Processing extensions. */ + if (!TS_RESP_process_extensions(ctx)) + goto end; + + /* Generating the signature. */ + if (!TS_RESP_sign(ctx)) + goto end; + + /* Everything was successful. */ + result = 1; + +end: + if (!result) { + TSerror(TS_R_RESPONSE_SETUP_ERROR); + if (ctx->response != NULL) { + if (TS_RESP_CTX_set_status_info_cond(ctx, + TS_STATUS_REJECTION, "Error during response " + "generation.") == 0) { + TS_RESP_free(ctx->response); + ctx->response = NULL; + } + } + } + response = ctx->response; + ctx->response = NULL; /* Ownership will be returned to caller. */ + TS_RESP_CTX_cleanup(ctx); + return response; +} +LCRYPTO_ALIAS(TS_RESP_create_response); + +/* Initializes the variable part of the context. */ +static void +TS_RESP_CTX_init(TS_RESP_CTX *ctx) +{ + ctx->request = NULL; + ctx->response = NULL; + ctx->tst_info = NULL; +} + +/* Cleans up the variable part of the context. */ +static void +TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) +{ + TS_REQ_free(ctx->request); + ctx->request = NULL; + TS_RESP_free(ctx->response); + ctx->response = NULL; + TS_TST_INFO_free(ctx->tst_info); + ctx->tst_info = NULL; +} + +/* Checks the format and content of the request. */ +static int +TS_RESP_check_request(TS_RESP_CTX *ctx) +{ + TS_REQ *request = ctx->request; + TS_MSG_IMPRINT *msg_imprint; + X509_ALGOR *md_alg; + int md_alg_id; + const ASN1_OCTET_STRING *digest; + EVP_MD *md = NULL; + int i; + + /* Checking request version. */ + if (TS_REQ_get_version(request) != 1) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request version."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); + return 0; + } + + /* Checking message digest algorithm. */ + msg_imprint = TS_REQ_get_msg_imprint(request); + md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); + md_alg_id = OBJ_obj2nid(md_alg->algorithm); + for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { + EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); + if (md_alg_id == EVP_MD_type(current_md)) + md = current_md; + } + if (!md) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Message digest algorithm is " + "not supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + + /* No message digest takes parameter. */ + if (md_alg->parameter && + ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Superfluous message digest " + "parameter."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + /* Checking message digest size. */ + digest = TS_MSG_IMPRINT_get_msg(msg_imprint); + if (digest->length != EVP_MD_size(md)) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad message digest."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + return 0; + } + + return 1; +} + +/* Returns the TSA policy based on the requested and acceptable policies. */ +static ASN1_OBJECT * +TS_RESP_get_policy(TS_RESP_CTX *ctx) +{ + ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); + ASN1_OBJECT *policy = NULL; + int i; + + if (ctx->default_policy == NULL) { + TSerror(TS_R_INVALID_NULL_POINTER); + return NULL; + } + /* Return the default policy if none is requested or the default is + requested. */ + if (!requested || !OBJ_cmp(requested, ctx->default_policy)) + policy = ctx->default_policy; + + /* Check if the policy is acceptable. */ + for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) { + ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); + if (!OBJ_cmp(requested, current)) + policy = current; + } + if (!policy) { + TSerror(TS_R_UNACCEPTABLE_POLICY); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Requested policy is not " + "supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); + } + return policy; +} + +/* Creates the TS_TST_INFO object based on the settings of the context. */ +static TS_TST_INFO * +TS_RESP_create_tst_info(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) +{ + int result = 0; + TS_TST_INFO *tst_info = NULL; + ASN1_INTEGER *serial = NULL; + ASN1_GENERALIZEDTIME *asn1_time = NULL; + time_t sec; + long usec; + TS_ACCURACY *accuracy = NULL; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name = NULL; + + if (!(tst_info = TS_TST_INFO_new())) + goto end; + if (!TS_TST_INFO_set_version(tst_info, 1)) + goto end; + if (!TS_TST_INFO_set_policy_id(tst_info, policy)) + goto end; + if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) + goto end; + if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data)) || + !TS_TST_INFO_set_serial(tst_info, serial)) + goto end; + if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec) || + !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, sec, usec, + ctx->clock_precision_digits)) || + !TS_TST_INFO_set_time(tst_info, asn1_time)) + goto end; + + /* Setting accuracy if needed. */ + if ((ctx->seconds || ctx->millis || ctx->micros) && + !(accuracy = TS_ACCURACY_new())) + goto end; + + if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) + goto end; + if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) + goto end; + if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros)) + goto end; + if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) + goto end; + + /* Setting ordering. */ + if ((ctx->flags & TS_ORDERING) && + !TS_TST_INFO_set_ordering(tst_info, 1)) + goto end; + + /* Setting nonce if needed. */ + if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL && + !TS_TST_INFO_set_nonce(tst_info, nonce)) + goto end; + + /* Setting TSA name to subject of signer certificate. */ + if (ctx->flags & TS_TSA_NAME) { + if (!(tsa_name = GENERAL_NAME_new())) + goto end; + tsa_name->type = GEN_DIRNAME; + tsa_name->d.dirn = + X509_NAME_dup(X509_get_subject_name(ctx->signer_cert)); + if (!tsa_name->d.dirn) + goto end; + if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) + goto end; + } + + result = 1; + +end: + if (!result) { + TS_TST_INFO_free(tst_info); + tst_info = NULL; + TSerror(TS_R_TST_INFO_SETUP_ERROR); + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during TSTInfo " + "generation."); + } + GENERAL_NAME_free(tsa_name); + TS_ACCURACY_free(accuracy); + ASN1_GENERALIZEDTIME_free(asn1_time); + ASN1_INTEGER_free(serial); + + return tst_info; +} + +/* Processing the extensions of the request. */ +static int +TS_RESP_process_extensions(TS_RESP_CTX *ctx) +{ + STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); + int i; + int ok = 1; + + for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + /* XXXXX The last argument was previously + (void *)ctx->extension_cb, but ISO C doesn't permit + converting a function pointer to void *. For lack of + better information, I'm placing a NULL there instead. + The callback can pick its own address out from the ctx + anyway... + */ + ok = (*ctx->extension_cb)(ctx, ext, NULL); + } + + return ok; +} + +/* Functions for signing the TS_TST_INFO structure of the context. */ +static int +TS_RESP_sign(TS_RESP_CTX *ctx) +{ + int ret = 0; + PKCS7 *p7 = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *certs; /* Certificates to include in sc. */ + ESS_SIGNING_CERT *sc = NULL; + ASN1_OBJECT *oid; + BIO *p7bio = NULL; + int i; + + /* Check if signcert and pkey match. */ + if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { + TSerror(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + /* Create a new PKCS7 signed object. */ + if (!(p7 = PKCS7_new())) { + TSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) + goto err; + + /* Force SignedData version to be 3 instead of the default 1. */ + if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) + goto err; + + /* Add signer certificate and optional certificate chain. */ + if (TS_REQ_get_cert_req(ctx->request)) { + PKCS7_add_certificate(p7, ctx->signer_cert); + if (ctx->certs) { + for (i = 0; i < sk_X509_num(ctx->certs); ++i) { + X509 *cert = sk_X509_value(ctx->certs, i); + PKCS7_add_certificate(p7, cert); + } + } + } + + /* Add a new signer info. */ + if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, + ctx->signer_key, EVP_sha1()))) { + TSerror(TS_R_PKCS7_ADD_SIGNATURE_ERROR); + goto err; + } + + /* Add content type signed attribute to the signer info. */ + oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, oid)) { + TSerror(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); + goto err; + } + + /* Create the ESS SigningCertificate attribute which contains + the signer certificate id and optionally the certificate chain. */ + certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; + if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) + goto err; + + /* Add SigningCertificate signed attribute to the signer info. */ + if (!ESS_add_signing_cert(si, sc)) { + TSerror(TS_R_ESS_ADD_SIGNING_CERT_ERROR); + goto err; + } + + /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ + if (!TS_TST_INFO_content_new(p7)) + goto err; + + /* Add the DER encoded tst_info to the PKCS7 structure. */ + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + TSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Convert tst_info to DER. */ + if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { + TSerror(TS_R_TS_DATASIGN); + goto err; + } + + /* Create the signature and add it to the signer info. */ + if (!PKCS7_dataFinal(p7, p7bio)) { + TSerror(TS_R_TS_DATASIGN); + goto err; + } + + /* Set new PKCS7 and TST_INFO objects. */ + TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); + p7 = NULL; /* Ownership is lost. */ + ctx->tst_info = NULL; /* Ownership is lost. */ + + ret = 1; + +err: + if (!ret) + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during signature " + "generation."); + BIO_free_all(p7bio); + ESS_SIGNING_CERT_free(sc); + PKCS7_free(p7); + return ret; +} + +static ESS_SIGNING_CERT * +ESS_SIGNING_CERT_new_init(X509 *signcert, STACK_OF(X509) *certs) +{ + ESS_CERT_ID *cid; + ESS_SIGNING_CERT *sc = NULL; + int i; + + /* Creating the ESS_CERT_ID stack. */ + if (!(sc = ESS_SIGNING_CERT_new())) + goto err; + if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) + goto err; + + /* Adding the signing certificate id. */ + if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) || + !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + /* Adding the certificate chain ids. */ + for (i = 0; i < sk_X509_num(certs); ++i) { + X509 *cert = sk_X509_value(certs, i); + if (!(cid = ESS_CERT_ID_new_init(cert, 1)) || + !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + } + + return sc; + +err: + ESS_SIGNING_CERT_free(sc); + TSerror(ERR_R_MALLOC_FAILURE); + return NULL; +} + +static ESS_CERT_ID * +ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) +{ + ESS_CERT_ID *cid = NULL; + GENERAL_NAME *name = NULL; + unsigned char cert_hash[TS_HASH_LEN]; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + if (!(cid = ESS_CERT_ID_new())) + goto err; + + if (!X509_digest(cert, TS_HASH_EVP, cert_hash, NULL)) + goto err; + + if (!ASN1_OCTET_STRING_set(cid->hash, cert_hash, sizeof(cert_hash))) + goto err; + + /* Setting the issuer/serial if requested. */ + if (issuer_needed) { + /* Creating issuer/serial structure. */ + if (!cid->issuer_serial && + !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) + goto err; + /* Creating general name from the certificate issuer. */ + if (!(name = GENERAL_NAME_new())) + goto err; + name->type = GEN_DIRNAME; + if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) + goto err; + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + goto err; + name = NULL; /* Ownership is lost. */ + /* Setting the serial number. */ + ASN1_INTEGER_free(cid->issuer_serial->serial); + if (!(cid->issuer_serial->serial = + ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) + goto err; + } + + return cid; + +err: + GENERAL_NAME_free(name); + ESS_CERT_ID_free(cid); + TSerror(ERR_R_MALLOC_FAILURE); + return NULL; +} + +static int +TS_TST_INFO_content_new(PKCS7 *p7) +{ + PKCS7 *ret = NULL; + ASN1_OCTET_STRING *octet_string = NULL; + + /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ + if (!(ret = PKCS7_new())) + goto err; + if (!(ret->d.other = ASN1_TYPE_new())) + goto err; + ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!(octet_string = ASN1_OCTET_STRING_new())) + goto err; + ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); + octet_string = NULL; + + /* Add encapsulated content to signed PKCS7 structure. */ + if (!PKCS7_set_content(p7, ret)) + goto err; + + return 1; + +err: + ASN1_OCTET_STRING_free(octet_string); + PKCS7_free(ret); + return 0; +} + +static int +ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp = NULL; + int len; + + len = i2d_ESS_SIGNING_CERT(sc, NULL); + if (!(pp = malloc(len))) { + TSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + TSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + free(pp); + pp = NULL; + return PKCS7_add_signed_attribute(si, + NID_id_smime_aa_signingCertificate, V_ASN1_SEQUENCE, seq); + +err: + ASN1_STRING_free(seq); + free(pp); + + return 0; +} + + +static ASN1_GENERALIZEDTIME * +TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, + time_t sec, long usec, unsigned precision) +{ + struct tm *tm = NULL; + char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; + char usecstr[TS_MAX_CLOCK_PRECISION_DIGITS + 2]; + char *p; + int rv; + + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + goto err; + + if (!(tm = gmtime(&sec))) + goto err; + + /* + * Put "genTime_str" in GeneralizedTime format. We work around the + * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST + * NOT include fractional seconds") and OpenSSL related functions to + * meet the rfc3161 requirement: "GeneralizedTime syntax can include + * fraction-of-second details". + */ + if (precision > 0) { + /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides + the following restrictions for a DER-encoding, which OpenSSL + (specifically ASN1_GENERALIZEDTIME_check() function) doesn't + support: + "The encoding MUST terminate with a "Z" (which means "Zulu" + time). The decimal point element, if present, MUST be the + point option ".". The fractional-seconds elements, + if present, MUST omit all trailing 0's; + if the elements correspond to 0, they MUST be wholly + omitted, and the decimal point element also MUST be + omitted." */ + (void) snprintf(usecstr, sizeof(usecstr), ".%06ld", usec); + /* truncate and trim trailing 0 */ + usecstr[precision + 1] = '\0'; + p = usecstr + strlen(usecstr) - 1; + while (p > usecstr && *p == '0') + *p-- = '\0'; + /* if we've reached the beginning, delete the . too */ + if (p == usecstr) + *p = '\0'; + + } else { + /* empty */ + usecstr[0] = '\0'; + } + rv = snprintf(genTime_str, sizeof(genTime_str), + "%04d%02d%02d%02d%02d%02d%sZ", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, usecstr); + if (rv < 0 || rv >= sizeof(genTime_str)) + goto err; + + /* Now call OpenSSL to check and set our genTime value */ + if (!asn1_time && !(asn1_time = ASN1_GENERALIZEDTIME_new())) + goto err; + if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) { + ASN1_GENERALIZEDTIME_free(asn1_time); + goto err; + } + + return asn1_time; + +err: + TSerror(TS_R_COULD_NOT_SET_TIME); + return NULL; +} diff --git a/Libraries/libressl/crypto/ts/ts_rsp_utils.c b/Libraries/libressl/crypto/ts/ts_rsp_utils.c new file mode 100644 index 000000000..34994adce --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_rsp_utils.c @@ -0,0 +1,503 @@ +/* $OpenBSD: ts_rsp_utils.c,v 1.11 2023/07/07 19:37:54 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "ts_local.h" + +/* Function definitions. */ + +int +TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) +{ + TS_STATUS_INFO *new_status_info; + + if (a->status_info == status_info) + return 1; + new_status_info = TS_STATUS_INFO_dup(status_info); + if (new_status_info == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + TS_STATUS_INFO_free(a->status_info); + a->status_info = new_status_info; + + return 1; +} +LCRYPTO_ALIAS(TS_RESP_set_status_info); + +TS_STATUS_INFO * +TS_RESP_get_status_info(TS_RESP *a) +{ + return a->status_info; +} +LCRYPTO_ALIAS(TS_RESP_get_status_info); + +const ASN1_UTF8STRING * +TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *si) +{ + return si->failure_info; +} +LCRYPTO_ALIAS(TS_STATUS_INFO_get0_failure_info); + +const STACK_OF(ASN1_UTF8STRING) * +TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *si) +{ + return si->text; +} +LCRYPTO_ALIAS(TS_STATUS_INFO_get0_text); + +const ASN1_INTEGER * +TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *si) +{ + return si->status; +} +LCRYPTO_ALIAS(TS_STATUS_INFO_get0_status); + +int +TS_STATUS_INFO_set_status(TS_STATUS_INFO *si, int i) +{ + return ASN1_INTEGER_set(si->status, i); +} +LCRYPTO_ALIAS(TS_STATUS_INFO_set_status); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void +TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info) +{ + /* Set new PKCS7 and TST_INFO objects. */ + PKCS7_free(a->token); + a->token = p7; + TS_TST_INFO_free(a->tst_info); + a->tst_info = tst_info; +} +LCRYPTO_ALIAS(TS_RESP_set_tst_info); + +PKCS7 * +TS_RESP_get_token(TS_RESP *a) +{ + return a->token; +} +LCRYPTO_ALIAS(TS_RESP_get_token); + +TS_TST_INFO * +TS_RESP_get_tst_info(TS_RESP *a) +{ + return a->tst_info; +} +LCRYPTO_ALIAS(TS_RESP_get_tst_info); + +int +TS_TST_INFO_set_version(TS_TST_INFO *a, long version) +{ + return ASN1_INTEGER_set(a->version, version); +} +LCRYPTO_ALIAS(TS_TST_INFO_set_version); + +long +TS_TST_INFO_get_version(const TS_TST_INFO *a) +{ + return ASN1_INTEGER_get(a->version); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_version); + +int +TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_policy_id); + +ASN1_OBJECT * +TS_TST_INFO_get_policy_id(TS_TST_INFO *a) +{ + return a->policy_id; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_policy_id); + +int +TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) +{ + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_msg_imprint); + +TS_MSG_IMPRINT * +TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a) +{ + return a->msg_imprint; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_msg_imprint); + +int +TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) +{ + ASN1_INTEGER *new_serial; + + if (a->serial == serial) + return 1; + new_serial = ASN1_INTEGER_dup(serial); + if (new_serial == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->serial); + a->serial = new_serial; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_serial); + +const ASN1_INTEGER * +TS_TST_INFO_get_serial(const TS_TST_INFO *a) +{ + return a->serial; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_serial); + +int +TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) +{ + ASN1_GENERALIZEDTIME *new_time; + + if (a->time == gtime) + return 1; + new_time = ASN1_STRING_dup(gtime); + if (new_time == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_GENERALIZEDTIME_free(a->time); + a->time = new_time; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_time); + +const ASN1_GENERALIZEDTIME * +TS_TST_INFO_get_time(const TS_TST_INFO *a) +{ + return a->time; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_time); + +int +TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) +{ + TS_ACCURACY *new_accuracy; + + if (a->accuracy == accuracy) + return 1; + new_accuracy = TS_ACCURACY_dup(accuracy); + if (new_accuracy == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + TS_ACCURACY_free(a->accuracy); + a->accuracy = new_accuracy; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_accuracy); + +TS_ACCURACY * +TS_TST_INFO_get_accuracy(TS_TST_INFO *a) +{ + return a->accuracy; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_accuracy); + +int +TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) +{ + ASN1_INTEGER *new_seconds; + + if (a->seconds == seconds) + return 1; + new_seconds = ASN1_INTEGER_dup(seconds); + if (new_seconds == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->seconds); + a->seconds = new_seconds; + return 1; +} +LCRYPTO_ALIAS(TS_ACCURACY_set_seconds); + +const ASN1_INTEGER * +TS_ACCURACY_get_seconds(const TS_ACCURACY *a) +{ + return a->seconds; +} +LCRYPTO_ALIAS(TS_ACCURACY_get_seconds); + +int +TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) +{ + ASN1_INTEGER *new_millis = NULL; + + if (a->millis == millis) + return 1; + if (millis != NULL) { + new_millis = ASN1_INTEGER_dup(millis); + if (new_millis == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->millis); + a->millis = new_millis; + return 1; +} +LCRYPTO_ALIAS(TS_ACCURACY_set_millis); + +const ASN1_INTEGER * +TS_ACCURACY_get_millis(const TS_ACCURACY *a) +{ + return a->millis; +} +LCRYPTO_ALIAS(TS_ACCURACY_get_millis); + +int +TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) +{ + ASN1_INTEGER *new_micros = NULL; + + if (a->micros == micros) + return 1; + if (micros != NULL) { + new_micros = ASN1_INTEGER_dup(micros); + if (new_micros == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->micros); + a->micros = new_micros; + return 1; +} +LCRYPTO_ALIAS(TS_ACCURACY_set_micros); + +const ASN1_INTEGER * +TS_ACCURACY_get_micros(const TS_ACCURACY *a) +{ + return a->micros; +} +LCRYPTO_ALIAS(TS_ACCURACY_get_micros); + +int +TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering) +{ + a->ordering = ordering ? 0xFF : 0x00; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_ordering); + +int +TS_TST_INFO_get_ordering(const TS_TST_INFO *a) +{ + return a->ordering ? 1 : 0; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ordering); + +int +TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) +{ + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_nonce); + +const ASN1_INTEGER * +TS_TST_INFO_get_nonce(const TS_TST_INFO *a) +{ + return a->nonce; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_nonce); + +int +TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) +{ + GENERAL_NAME *new_tsa; + + if (a->tsa == tsa) + return 1; + new_tsa = GENERAL_NAME_dup(tsa); + if (new_tsa == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + return 0; + } + GENERAL_NAME_free(a->tsa); + a->tsa = new_tsa; + return 1; +} +LCRYPTO_ALIAS(TS_TST_INFO_set_tsa); + +GENERAL_NAME * +TS_TST_INFO_get_tsa(TS_TST_INFO *a) +{ + return a->tsa; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_tsa); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a) +{ + return a->extensions; +} +LCRYPTO_ALIAS(TS_TST_INFO_get_exts); + +void +TS_TST_INFO_ext_free(TS_TST_INFO *a) +{ + if (!a) + return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; +} +LCRYPTO_ALIAS(TS_TST_INFO_ext_free); + +int +TS_TST_INFO_get_ext_count(TS_TST_INFO *a) +{ + return X509v3_get_ext_count(a->extensions); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ext_count); + +int +TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ext_by_NID); + +int +TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ext_by_OBJ); + +int +TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ext_by_critical); + +X509_EXTENSION * +TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc) +{ + return X509v3_get_ext(a->extensions, loc); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ext); + +X509_EXTENSION * +TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc) +{ + return X509v3_delete_ext(a->extensions, loc); +} +LCRYPTO_ALIAS(TS_TST_INFO_delete_ext); + +int +TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&a->extensions, ex, loc) != NULL; +} +LCRYPTO_ALIAS(TS_TST_INFO_add_ext); + +void * +TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(a->extensions, nid, crit, idx); +} +LCRYPTO_ALIAS(TS_TST_INFO_get_ext_d2i); diff --git a/Libraries/libressl/crypto/ts/ts_rsp_verify.c b/Libraries/libressl/crypto/ts/ts_rsp_verify.c new file mode 100644 index 000000000..69236f68a --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_rsp_verify.c @@ -0,0 +1,847 @@ +/* $OpenBSD: ts_rsp_verify.c,v 1.30 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "evp_local.h" +#include "ts_local.h" +#include "x509_local.h" + +/* Private function declarations. */ + +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain); +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); +static ESS_SIGNING_CERT_V2 *ESS_get_signing_cert_v2(PKCS7_SIGNER_INFO *si); +static int TS_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert); +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert); +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info); +static int TS_check_status_info(TS_RESP *response); +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len); +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info); +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); + +/* + * Local mapping between response codes and descriptions. + * Don't forget to change TS_STATUS_BUF_SIZE when modifying + * the elements of this array. + */ +static const char *TS_status_text[] = { + "granted", + "grantedWithMods", + "rejection", + "waiting", + "revocationWarning", + "revocationNotification" +}; + +#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) + +/* + * This must be greater or equal to the sum of the strings in TS_status_text + * plus the number of its elements. + */ +#define TS_STATUS_BUF_SIZE 256 + +static struct { + int code; + const char *text; +} TS_failure_info[] = { + { TS_INFO_BAD_ALG, "badAlg" }, + { TS_INFO_BAD_REQUEST, "badRequest" }, + { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" }, + { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" }, + { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" }, + { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" }, + { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" }, + { TS_INFO_SYSTEM_FAILURE, "systemFailure" } +}; + +#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ + sizeof(*TS_failure_info)) + +/* Functions for verifying a signed TS_TST_INFO structure. */ + +/* + * This function carries out the following tasks: + * - Checks if there is one and only one signer. + * - Search for the signing certificate in 'certs' and in the response. + * - Check the extended key usage and key usage fields of the signer + * certificate (done by the path validation). + * - Build and validate the certificate path. + * - Check if the certificate path meets the requirements of the + * SigningCertificate ESS signed attribute. + * - Verify the signature value. + * - Returns the signer certificate in 'signer', if 'signer' is not NULL. + */ +int +TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out) +{ + STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *signers = NULL; + X509 *signer; + STACK_OF(X509) *chain = NULL; + char buf[4096]; + int i, j = 0, ret = 0; + BIO *p7bio = NULL; + + /* Some sanity checks first. */ + if (!token) { + TSerror(TS_R_INVALID_NULL_POINTER); + goto err; + } + + /* Check for the correct content type */ + if (!PKCS7_type_is_signed(token)) { + TSerror(TS_R_WRONG_CONTENT_TYPE); + goto err; + } + + /* Check if there is one and only one signer. */ + sinfos = PKCS7_get_signer_info(token); + if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) { + TSerror(TS_R_THERE_MUST_BE_ONE_SIGNER); + goto err; + } + si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); + + /* Check for no content: no data to verify signature. */ + if (PKCS7_get_detached(token)) { + TSerror(TS_R_NO_CONTENT); + goto err; + } + + /* Get hold of the signer certificate, search only internal + certificates if it was requested. */ + signers = PKCS7_get0_signers(token, certs, 0); + if (!signers || sk_X509_num(signers) != 1) + goto err; + signer = sk_X509_value(signers, 0); + + /* Now verify the certificate. */ + if (!TS_verify_cert(store, certs, signer, &chain)) + goto err; + + /* Check if the signer certificate is consistent with the + ESS extension. */ + if (!TS_check_signing_certs(si, chain)) + goto err; + + /* Creating the message digest. */ + p7bio = PKCS7_dataInit(token, NULL); + + /* We now have to 'read' from p7bio to calculate digests etc. */ + while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0) + ; + + /* Verifying the signature. */ + j = PKCS7_signatureVerify(p7bio, token, si, signer); + if (j <= 0) { + TSerror(TS_R_SIGNATURE_FAILURE); + goto err; + } + + /* Return the signer certificate if needed. */ + if (signer_out) { + *signer_out = signer; + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + } + + ret = 1; + +err: + BIO_free_all(p7bio); + sk_X509_pop_free(chain, X509_free); + sk_X509_free(signers); + + return ret; +} +LCRYPTO_ALIAS(TS_RESP_verify_signature); + +/* + * The certificate chain is returned in chain. Caller is responsible for + * freeing the vector. + */ +static int +TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer, + STACK_OF(X509) **chain) +{ + X509_STORE_CTX cert_ctx; + int i; + int ret = 0; + + /* chain is an out argument. */ + *chain = NULL; + if (X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted) == 0) { + TSerror(ERR_R_X509_LIB); + goto err; + } + if (X509_STORE_CTX_set_purpose(&cert_ctx, + X509_PURPOSE_TIMESTAMP_SIGN) == 0) + goto err; + i = X509_verify_cert(&cert_ctx); + if (i <= 0) { + int j = X509_STORE_CTX_get_error(&cert_ctx); + + TSerror(TS_R_CERTIFICATE_VERIFY_ERROR); + ERR_asprintf_error_data("Verify error:%s", + X509_verify_cert_error_string(j)); + goto err; + } else { + /* Get a copy of the certificate chain. */ + *chain = X509_STORE_CTX_get1_chain(&cert_ctx); + ret = 1; + } + +err: + X509_STORE_CTX_cleanup(&cert_ctx); + + return ret; +} + +static int +TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) +{ + ESS_SIGNING_CERT *ss = NULL; + STACK_OF(ESS_CERT_ID) *cert_ids; + ESS_SIGNING_CERT_V2 *ssv2 = NULL; + STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2; + X509 *cert; + int i = 0; + int ret = 0; + + if ((ss = ESS_get_signing_cert(si)) != NULL) { + cert_ids = ss->cert_ids; + /* The signer certificate must be the first in cert_ids. */ + cert = sk_X509_value(chain, 0); + + if (TS_find_cert(cert_ids, cert) != 0) + goto err; + + /* + * Check the other certificates of the chain if there are more + * than one certificate ids in cert_ids. + */ + if (sk_ESS_CERT_ID_num(cert_ids) > 1) { + /* All the certificates of the chain must be in cert_ids. */ + for (i = 1; i < sk_X509_num(chain); i++) { + cert = sk_X509_value(chain, i); + + if (TS_find_cert(cert_ids, cert) < 0) + goto err; + } + } + } + + if ((ssv2 = ESS_get_signing_cert_v2(si)) != NULL) { + cert_ids_v2 = ssv2->cert_ids; + /* The signer certificate must be the first in cert_ids_v2. */ + cert = sk_X509_value(chain, 0); + + if (TS_find_cert_v2(cert_ids_v2, cert) != 0) + goto err; + + /* + * Check the other certificates of the chain if there are more + * than one certificate ids in cert_ids_v2. + */ + if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) { + /* All the certificates of the chain must be in cert_ids_v2. */ + for (i = 1; i < sk_X509_num(chain); i++) { + cert = sk_X509_value(chain, i); + + if (TS_find_cert_v2(cert_ids_v2, cert) < 0) + goto err; + } + } + } + + ret = 1; + +err: + if (!ret) + TSerror(TS_R_ESS_SIGNING_CERTIFICATE_ERROR); + ESS_SIGNING_CERT_free(ss); + ESS_SIGNING_CERT_V2_free(ssv2); + return ret; +} + +static ESS_SIGNING_CERT * +ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *attr; + const unsigned char *p; + + attr = PKCS7_get_signed_attribute(si, + NID_id_smime_aa_signingCertificate); + if (!attr) + return NULL; + if (attr->type != V_ASN1_SEQUENCE) + return NULL; + p = attr->value.sequence->data; + return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); +} + +static ESS_SIGNING_CERT_V2 * +ESS_get_signing_cert_v2(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *attr; + const unsigned char *p; + + attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2); + if (attr == NULL) + return NULL; + p = attr->value.sequence->data; + return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length); +} + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +static int +TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) +{ + int i; + unsigned char cert_hash[TS_HASH_LEN]; + + if (!cert_ids || !cert) + return -1; + + if (!X509_digest(cert, TS_HASH_EVP, cert_hash, NULL)) + return -1; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + if (X509_check_purpose(cert, -1, 0) == -1) + return -1; + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { + ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); + + /* Check the SHA-1 hash first. */ + if (cid->hash->length == TS_HASH_LEN && !memcmp(cid->hash->data, + cert_hash, TS_HASH_LEN)) { + /* Check the issuer/serial as well if specified. */ + ESS_ISSUER_SERIAL *is = cid->issuer_serial; + + if (is == NULL || TS_issuer_serial_cmp(is, cert) == 0) + return i; + } + } + + return -1; +} + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +static int +TS_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert) +{ + int i; + unsigned char cert_digest[EVP_MAX_MD_SIZE]; + unsigned int len; + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) { + ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i); + const EVP_MD *md = EVP_sha256(); + + if (cid->hash_alg != NULL) + md = EVP_get_digestbyobj(cid->hash_alg->algorithm); + if (md == NULL) + return -1; + + if (!X509_digest(cert, md, cert_digest, &len)) + return -1; + + if ((unsigned int)cid->hash->length != len) + return -1; + + if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) { + ESS_ISSUER_SERIAL *is = cid->issuer_serial; + + if (is == NULL || TS_issuer_serial_cmp(is, cert) == 0) + return i; + } + } + + return -1; +} + +static int +TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert) +{ + GENERAL_NAME *issuer; + + if (is == NULL || cert == NULL || sk_GENERAL_NAME_num(is->issuer) != 1) + return -1; + + /* Check the issuer first. It must be a directory name. */ + issuer = sk_GENERAL_NAME_value(is->issuer, 0); + if (issuer->type != GEN_DIRNAME || + X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert))) + return -1; + + /* Check the serial number, too. */ + if (ASN1_INTEGER_cmp(is->serial, X509_get_serialNumber(cert))) + return -1; + + return 0; +} + +/* + * Verifies whether 'response' contains a valid response with regards + * to the settings of the context: + * - Gives an error message if the TS_TST_INFO is not present. + * - Calls _TS_RESP_verify_token to verify the token content. + */ +int +TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) +{ + PKCS7 *token = TS_RESP_get_token(response); + TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); + int ret = 0; + + /* Check if we have a successful TS_TST_INFO object in place. */ + if (!TS_check_status_info(response)) + goto err; + + /* Check the contents of the time stamp token. */ + if (!int_TS_RESP_verify_token(ctx, token, tst_info)) + goto err; + + ret = 1; + +err: + return ret; +} +LCRYPTO_ALIAS(TS_RESP_verify_response); + +/* + * Tries to extract a TS_TST_INFO structure from the PKCS7 token and + * calls the internal int_TS_RESP_verify_token function for verifying it. + */ +int +TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) +{ + TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); + int ret = 0; + + if (tst_info) { + ret = int_TS_RESP_verify_token(ctx, token, tst_info); + TS_TST_INFO_free(tst_info); + } + return ret; +} +LCRYPTO_ALIAS(TS_RESP_verify_token); + +/* + * Verifies whether the 'token' contains a valid time stamp token + * with regards to the settings of the context. Only those checks are + * carried out that are specified in the context: + * - Verifies the signature of the TS_TST_INFO. + * - Checks the version number of the response. + * - Check if the requested and returned policies math. + * - Check if the message imprints are the same. + * - Check if the nonces are the same. + * - Check if the TSA name matches the signer. + * - Check if the TSA name is the expected TSA. + */ +static int +int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token, + TS_TST_INFO *tst_info) +{ + X509 *signer = NULL; + GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); + X509_ALGOR *md_alg = NULL; + unsigned char *imprint = NULL; + unsigned imprint_len = 0; + int ret = 0; + + /* Verify the signature. */ + if ((ctx->flags & TS_VFY_SIGNATURE) && + !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer)) + goto err; + + /* Check version number of response. */ + if ((ctx->flags & TS_VFY_VERSION) && + TS_TST_INFO_get_version(tst_info) != 1) { + TSerror(TS_R_UNSUPPORTED_VERSION); + goto err; + } + + /* Check policies. */ + if ((ctx->flags & TS_VFY_POLICY) && + !TS_check_policy(ctx->policy, tst_info)) + goto err; + + /* Check message imprints. */ + if ((ctx->flags & TS_VFY_IMPRINT) && + !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, + tst_info)) + goto err; + + /* Compute and check message imprints. */ + if ((ctx->flags & TS_VFY_DATA) && + (!TS_compute_imprint(ctx->data, tst_info, + &md_alg, &imprint, &imprint_len) || + !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) + goto err; + + /* Check nonces. */ + if ((ctx->flags & TS_VFY_NONCE) && + !TS_check_nonces(ctx->nonce, tst_info)) + goto err; + + /* Check whether TSA name and signer certificate match. */ + if ((ctx->flags & TS_VFY_SIGNER) && + tsa_name && !TS_check_signer_name(tsa_name, signer)) { + TSerror(TS_R_TSA_NAME_MISMATCH); + goto err; + } + + /* Check whether the TSA is the expected one. */ + if ((ctx->flags & TS_VFY_TSA_NAME) && + !TS_check_signer_name(ctx->tsa_name, signer)) { + TSerror(TS_R_TSA_UNTRUSTED); + goto err; + } + + ret = 1; + +err: + X509_free(signer); + X509_ALGOR_free(md_alg); + free(imprint); + return ret; +} + +static int +TS_check_status_info(TS_RESP *response) +{ + TS_STATUS_INFO *info = TS_RESP_get_status_info(response); + long status = ASN1_INTEGER_get(info->status); + const char *status_text = NULL; + char *embedded_status_text = NULL; + char failure_text[TS_STATUS_BUF_SIZE] = ""; + + /* Check if everything went fine. */ + if (status == 0 || status == 1) + return 1; + + /* There was an error, get the description in status_text. */ + if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) + status_text = TS_status_text[status]; + else + status_text = "unknown code"; + + /* Set the embedded_status_text to the returned description. */ + if (sk_ASN1_UTF8STRING_num(info->text) > 0 && + !(embedded_status_text = TS_get_status_text(info->text))) + return 0; + + /* Filling in failure_text with the failure information. */ + if (info->failure_info) { + int i; + int first = 1; + for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) { + if (ASN1_BIT_STRING_get_bit(info->failure_info, + TS_failure_info[i].code)) { + if (!first) + strlcat(failure_text, ",", + TS_STATUS_BUF_SIZE); + else + first = 0; + strlcat(failure_text, TS_failure_info[i].text, + TS_STATUS_BUF_SIZE); + } + } + } + if (failure_text[0] == '\0') + strlcpy(failure_text, "unspecified", TS_STATUS_BUF_SIZE); + + /* Making up the error string. */ + TSerror(TS_R_NO_TIME_STAMP_TOKEN); + ERR_asprintf_error_data + ("status code: %s, status text: %s, failure codes: %s", + status_text, + embedded_status_text ? embedded_status_text : "unspecified", + failure_text); + free(embedded_status_text); + + return 0; +} + +static char * +TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) +{ + int i; + unsigned int length = 0; + char *result = NULL; + + /* Determine length first. */ + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + length += ASN1_STRING_length(current); + length += 1; /* separator character */ + } + /* Allocate memory (closing '\0' included). */ + if (!(result = malloc(length))) { + TSerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Concatenate the descriptions. */ + result[0] = '\0'; + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + if (i > 0) + strlcat(result, "/", length); + strlcat(result, (const char *)ASN1_STRING_data(current), length); + } + return result; +} + +static int +TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) +{ + ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); + + if (OBJ_cmp(req_oid, resp_oid) != 0) { + TSerror(TS_R_POLICY_MISMATCH); + return 0; + } + + return 1; +} + +static int +TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, X509_ALGOR **out_md_alg, + unsigned char **out_imprint, unsigned int *out_imprint_len) +{ + TS_MSG_IMPRINT *msg_imprint; + X509_ALGOR *md_alg_resp; + X509_ALGOR *md_alg = NULL; + unsigned char *imprint = NULL; + unsigned int imprint_len = 0; + const EVP_MD *md; + EVP_MD_CTX md_ctx; + unsigned char buffer[4096]; + int length; + + *out_md_alg = NULL; + *out_imprint = NULL; + *out_imprint_len = 0; + + /* Retrieve the MD algorithm of the response. */ + msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); + md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); + if ((md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL) + goto err; + + /* Getting the MD object. */ + if ((md = EVP_get_digestbyobj((md_alg)->algorithm)) == NULL) { + TSerror(TS_R_UNSUPPORTED_MD_ALGORITHM); + goto err; + } + + /* Compute message digest. */ + if ((length = EVP_MD_size(md)) < 0) + goto err; + imprint_len = length; + if ((imprint = malloc(imprint_len)) == NULL) { + TSerror(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestInit(&md_ctx, md)) + goto err; + while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { + if (!EVP_DigestUpdate(&md_ctx, buffer, length)) + goto err; + } + if (!EVP_DigestFinal(&md_ctx, imprint, NULL)) + goto err; + + *out_md_alg = md_alg; + md_alg = NULL; + *out_imprint = imprint; + imprint = NULL; + *out_imprint_len = imprint_len; + + return 1; + +err: + X509_ALGOR_free(md_alg); + free(imprint); + return 0; +} + +static int +TS_check_imprints(X509_ALGOR *algor_a, unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info) +{ + TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); + int ret = 0; + + /* algor_a is optional. */ + if (algor_a) { + /* Compare algorithm OIDs. */ + if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) + goto err; + + /* The parameter must be NULL in both. */ + if ((algor_a->parameter && + ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) || + (algor_b->parameter && + ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) + goto err; + } + + /* Compare octet strings. */ + ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) && + memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; + +err: + if (!ret) + TSerror(TS_R_MESSAGE_IMPRINT_MISMATCH); + return ret; +} + +static int +TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) +{ + const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); + + /* Error if nonce is missing. */ + if (!b) { + TSerror(TS_R_NONCE_NOT_RETURNED); + return 0; + } + + /* No error if a nonce is returned without being requested. */ + if (ASN1_INTEGER_cmp(a, b) != 0) { + TSerror(TS_R_NONCE_MISMATCH); + return 0; + } + + return 1; +} + +/* Check if the specified TSA name matches either the subject + or one of the subject alternative names of the TSA certificate. */ +static int +TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) +{ + STACK_OF(GENERAL_NAME) *gen_names = NULL; + int idx = -1; + int found = 0; + + if (signer == NULL) + return 0; + + /* Check the subject name first. */ + if (tsa_name->type == GEN_DIRNAME && + X509_name_cmp(tsa_name->d.dirn, X509_get_subject_name(signer)) == 0) + return 1; + + /* Check all the alternative names. */ + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, + NULL, &idx); + while (gen_names != NULL && + !(found = (TS_find_name(gen_names, tsa_name) >= 0))) { + /* Get the next subject alternative name, + although there should be no more than one. */ + GENERAL_NAMES_free(gen_names); + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, + NULL, &idx); + } + if (gen_names) + GENERAL_NAMES_free(gen_names); + + return found; +} + +/* Returns 1 if name is in gen_names, 0 otherwise. */ +static int +TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) +{ + int i, found; + for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); + ++i) { + GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); + found = GENERAL_NAME_cmp(current, name) == 0; + } + return found ? i - 1 : -1; +} diff --git a/Libraries/libressl/crypto/ts/ts_verify_ctx.c b/Libraries/libressl/crypto/ts/ts_verify_ctx.c new file mode 100644 index 000000000..5a2d95c68 --- /dev/null +++ b/Libraries/libressl/crypto/ts/ts_verify_ctx.c @@ -0,0 +1,236 @@ +/* $OpenBSD: ts_verify_ctx.c,v 1.14 2023/07/07 07:25:21 beck Exp $ */ +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL + * project 2003. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +#include "ts_local.h" + +TS_VERIFY_CTX * +TS_VERIFY_CTX_new(void) +{ + TS_VERIFY_CTX *ctx = calloc(1, sizeof(TS_VERIFY_CTX)); + + if (!ctx) + TSerror(ERR_R_MALLOC_FAILURE); + + return ctx; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_new); + +void +TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx) +{ + if (!ctx) + return; + + TS_VERIFY_CTX_cleanup(ctx); + free(ctx); +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_free); + +void +TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) +{ + if (!ctx) + return; + + X509_STORE_free(ctx->store); + sk_X509_pop_free(ctx->certs, X509_free); + + ASN1_OBJECT_free(ctx->policy); + + X509_ALGOR_free(ctx->md_alg); + free(ctx->imprint); + + BIO_free_all(ctx->data); + + ASN1_INTEGER_free(ctx->nonce); + + GENERAL_NAME_free(ctx->tsa_name); + + memset(ctx, 0, sizeof(*ctx)); +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_cleanup); + +/* + * XXX: The following accessors demonstrate the amount of care and thought that + * went into OpenSSL 1.1 API design and the review thereof: for whatever reason + * these functions return what was passed in. Correct memory management is left + * as an exercise for the reader... Unfortunately, careful consumers like + * openssl-ruby assume this behavior, so we're stuck with this insanity. The + * cherry on top is the TS_VERIFY_CTS_set_certs() [sic!] function that made it + * into the public API. + * + * Outstanding job, R$ and tjh, A+. + */ + +int +TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int flags) +{ + ctx->flags |= flags; + + return ctx->flags; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_add_flags); + +int +TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int flags) +{ + ctx->flags = flags; + + return ctx->flags; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_set_flags); + +BIO * +TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *bio) +{ + ctx->data = bio; + + return ctx->data; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_set_data); + +X509_STORE * +TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *store) +{ + ctx->store = store; + + return ctx->store; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_set_store); + +STACK_OF(X509) * +TS_VERIFY_CTX_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs) +{ + ctx->certs = certs; + + return ctx->certs; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_set_certs); + +unsigned char * +TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, unsigned char *imprint, + long imprint_len) +{ + free(ctx->imprint); + + ctx->imprint = imprint; + ctx->imprint_len = imprint_len; + + return ctx->imprint; +} +LCRYPTO_ALIAS(TS_VERIFY_CTX_set_imprint); + +TS_VERIFY_CTX * +TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) +{ + TS_VERIFY_CTX *ret = ctx; + ASN1_OBJECT *policy; + TS_MSG_IMPRINT *imprint; + X509_ALGOR *md_alg; + ASN1_OCTET_STRING *msg; + const ASN1_INTEGER *nonce; + + if (ret) + TS_VERIFY_CTX_cleanup(ret); + else if (!(ret = TS_VERIFY_CTX_new())) + return NULL; + + /* Setting flags. */ + ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE); + + /* Setting policy. */ + if ((policy = TS_REQ_get_policy_id(req)) != NULL) { + if (!(ret->policy = OBJ_dup(policy))) + goto err; + } else + ret->flags &= ~TS_VFY_POLICY; + + /* Setting md_alg, imprint and imprint_len. */ + imprint = TS_REQ_get_msg_imprint(req); + md_alg = TS_MSG_IMPRINT_get_algo(imprint); + if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) + goto err; + msg = TS_MSG_IMPRINT_get_msg(imprint); + ret->imprint_len = ASN1_STRING_length(msg); + if (!(ret->imprint = malloc(ret->imprint_len))) + goto err; + memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len); + + /* Setting nonce. */ + if ((nonce = TS_REQ_get_nonce(req)) != NULL) { + if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) + goto err; + } else + ret->flags &= ~TS_VFY_NONCE; + + return ret; + +err: + if (ctx) + TS_VERIFY_CTX_cleanup(ctx); + else + TS_VERIFY_CTX_free(ret); + return NULL; +} +LCRYPTO_ALIAS(TS_REQ_to_TS_VERIFY_CTX); diff --git a/Libraries/libressl/crypto/txt_db/txt_db.c b/Libraries/libressl/crypto/txt_db/txt_db.c new file mode 100644 index 000000000..7d1f82c49 --- /dev/null +++ b/Libraries/libressl/crypto/txt_db/txt_db.c @@ -0,0 +1,378 @@ +/* $OpenBSD: txt_db.c,v 1.19 2023/07/08 11:28:03 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include + +#undef BUFSIZE +#define BUFSIZE 512 + +TXT_DB * +TXT_DB_read(BIO *in, int num) +{ + TXT_DB *ret = NULL; + int er = 1; + int esc = 0; + long ln = 0; + int i, add, n; + int size = BUFSIZE; + int offset = 0; + char *p, *f; + OPENSSL_STRING *pp; + BUF_MEM *buf = NULL; + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(buf, size)) + goto err; + + if ((ret = malloc(sizeof(TXT_DB))) == NULL) + goto err; + ret->num_fields = num; + ret->index = NULL; + ret->qual = NULL; + if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL) + goto err; + if ((ret->index = reallocarray(NULL, num, sizeof(*ret->index))) == NULL) + goto err; + if ((ret->qual = reallocarray(NULL, num, sizeof(*(ret->qual)))) == NULL) + goto err; + for (i = 0; i < num; i++) { + ret->index[i] = NULL; + ret->qual[i] = NULL; + } + + add = (num + 1)*sizeof(char *); + buf->data[size-1] = '\0'; + offset = 0; + for (;;) { + if (offset != 0) { + size += BUFSIZE; + if (!BUF_MEM_grow_clean(buf, size)) + goto err; + } + buf->data[offset] = '\0'; + BIO_gets(in, &(buf->data[offset]), size - offset); + ln++; + if (buf->data[offset] == '\0') + break; + if ((offset == 0) && (buf->data[0] == '#')) + continue; + i = strlen(&(buf->data[offset])); + offset += i; + if (buf->data[offset-1] != '\n') + continue; + else { + buf->data[offset-1] = '\0'; /* blat the '\n' */ + if (!(p = malloc(add + offset))) + goto err; + offset = 0; + } + pp = (char **)p; + p += add; + n = 0; + pp[n++] = p; + i = 0; + f = buf->data; + + esc = 0; + for (;;) { + if (*f == '\0') + break; + if (*f == '\t') { + if (esc) + p--; + else { + *(p++)='\0'; + f++; + if (n >= num) + break; + pp[n++] = p; + continue; + } + } + esc=(*f == '\\'); + *(p++)= *(f++); + } + *(p++)='\0'; + if ((n != num) || (*f != '\0')) { + fprintf(stderr, "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f); + er = 2; + goto err; + } + pp[n] = p; + if (!sk_OPENSSL_PSTRING_push(ret->data, pp)) { + fprintf(stderr, "failure in sk_push\n"); + er = 2; + goto err; + } + } + er = 0; + +err: + BUF_MEM_free(buf); + if (er) { + if (er == 1) + fprintf(stderr, "malloc failure\n"); + if (ret != NULL) { + if (ret->data != NULL) + sk_OPENSSL_PSTRING_free(ret->data); + free(ret->index); + free(ret->qual); + free(ret); + } + return (NULL); + } else + return (ret); +} +LCRYPTO_ALIAS(TXT_DB_read); + +OPENSSL_STRING * +TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value) +{ + OPENSSL_STRING *ret; + LHASH_OF(OPENSSL_STRING) *lh; + + if (idx >= db->num_fields) { + db->error = DB_ERROR_INDEX_OUT_OF_RANGE; + return (NULL); + } + lh = db->index[idx]; + if (lh == NULL) { + db->error = DB_ERROR_NO_INDEX; + return (NULL); + } + ret = lh_OPENSSL_STRING_retrieve(lh, value); + db->error = DB_ERROR_OK; + return (ret); +} +LCRYPTO_ALIAS(TXT_DB_get_by_index); + +int +TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) +{ + LHASH_OF(OPENSSL_STRING) *idx; + OPENSSL_STRING *r; + int i, n; + + if (field >= db->num_fields) { + db->error = DB_ERROR_INDEX_OUT_OF_RANGE; + return (0); + } + /* FIXME: we lose type checking at this point */ + if ((idx = (LHASH_OF(OPENSSL_STRING) *)lh_new(hash, cmp)) == NULL) { + db->error = DB_ERROR_MALLOC; + return (0); + } + n = sk_OPENSSL_PSTRING_num(db->data); + for (i = 0; i < n; i++) { + r = sk_OPENSSL_PSTRING_value(db->data, i); + if ((qual != NULL) && (qual(r) == 0)) + continue; + if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) { + db->error = DB_ERROR_INDEX_CLASH; + db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r); + db->arg2 = i; + lh_OPENSSL_STRING_free(idx); + return (0); + } + } + if (db->index[field] != NULL) + lh_OPENSSL_STRING_free(db->index[field]); + db->index[field] = idx; + db->qual[field] = qual; + return (1); +} +LCRYPTO_ALIAS(TXT_DB_create_index); + +long +TXT_DB_write(BIO *out, TXT_DB *db) +{ + long i, j,n, nn, l, tot = 0; + char *p, **pp, *f; + BUF_MEM *buf = NULL; + long ret = -1; + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + n = sk_OPENSSL_PSTRING_num(db->data); + nn = db->num_fields; + for (i = 0; i < n; i++) { + pp = sk_OPENSSL_PSTRING_value(db->data, i); + + l = 0; + for (j = 0; j < nn; j++) { + if (pp[j] != NULL) + l += strlen(pp[j]); + } + if (!BUF_MEM_grow_clean(buf, (int)(l*2 + nn))) + goto err; + + p = buf->data; + for (j = 0; j < nn; j++) { + f = pp[j]; + if (f != NULL) + for (;;) { + if (*f == '\0') + break; + if (*f == '\t') + *(p++) = '\\'; + *(p++) = *(f++); + } + *(p++) = '\t'; + } + p[-1] = '\n'; + j = p - buf->data; + if (BIO_write(out, buf->data, (int)j) != j) + goto err; + tot += j; + } + ret = tot; + +err: + if (buf != NULL) + BUF_MEM_free(buf); + return (ret); +} +LCRYPTO_ALIAS(TXT_DB_write); + +int +TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row) +{ + int i; + OPENSSL_STRING *r; + + for (i = 0; i < db->num_fields; i++) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i](row) == 0)) + continue; + r = lh_OPENSSL_STRING_retrieve(db->index[i], row); + if (r != NULL) { + db->error = DB_ERROR_INDEX_CLASH; + db->arg1 = i; + db->arg_row = r; + goto err; + } + } + } + /* We have passed the index checks, now just append and insert */ + if (!sk_OPENSSL_PSTRING_push(db->data, row)) { + db->error = DB_ERROR_MALLOC; + goto err; + } + + for (i = 0; i < db->num_fields; i++) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i](row) == 0)) + continue; + (void)lh_OPENSSL_STRING_insert(db->index[i], row); + } + } + return (1); + +err: + return (0); +} +LCRYPTO_ALIAS(TXT_DB_insert); + +void +TXT_DB_free(TXT_DB *db) +{ + int i, n; + char **p, *max; + + if (db == NULL) + return; + + if (db->index != NULL) { + for (i = db->num_fields - 1; i >= 0; i--) + if (db->index[i] != NULL) + lh_OPENSSL_STRING_free(db->index[i]); + free(db->index); + } + free(db->qual); + if (db->data != NULL) { + for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) { + /* check if any 'fields' have been allocated + * from outside of the initial block */ + p = sk_OPENSSL_PSTRING_value(db->data, i); + max = p[db->num_fields]; /* last address */ + if (max == NULL) /* new row */ + { + for (n = 0; n < db->num_fields; n++) + free(p[n]); + } else { + for (n = 0; n < db->num_fields; n++) { + if (((p[n] < (char *)p) || + (p[n] > max)) && + (p[n] != NULL)) + free(p[n]); + } + } + free(sk_OPENSSL_PSTRING_value(db->data, i)); + } + sk_OPENSSL_PSTRING_free(db->data); + } + free(db); +} +LCRYPTO_ALIAS(TXT_DB_free); diff --git a/Libraries/libressl/crypto/ui/ui_err.c b/Libraries/libressl/crypto/ui/ui_err.c new file mode 100644 index 000000000..3f875da77 --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_err.c @@ -0,0 +1,96 @@ +/* $OpenBSD: ui_err.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason) + +static ERR_STRING_DATA UI_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA UI_str_reasons[] = { + {ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), "common ok and cancel characters"}, + {ERR_REASON(UI_R_INDEX_TOO_LARGE), "index too large"}, + {ERR_REASON(UI_R_INDEX_TOO_SMALL), "index too small"}, + {ERR_REASON(UI_R_NO_RESULT_BUFFER), "no result buffer"}, + {ERR_REASON(UI_R_RESULT_TOO_LARGE), "result too large"}, + {ERR_REASON(UI_R_RESULT_TOO_SMALL), "result too small"}, + {ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"}, + {0, NULL} +}; + +#endif + +void +ERR_load_UI_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(UI_str_functs[0].error) == NULL) { + ERR_load_strings(0, UI_str_functs); + ERR_load_strings(0, UI_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_UI_strings); diff --git a/Libraries/libressl/crypto/ui/ui_lib.c b/Libraries/libressl/crypto/ui/ui_lib.c new file mode 100644 index 000000000..73d899afc --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_lib.c @@ -0,0 +1,907 @@ +/* $OpenBSD: ui_lib.c,v 1.51 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include + +#include "ui_local.h" + +static const UI_METHOD *default_UI_meth = NULL; + +UI * +UI_new(void) +{ + return (UI_new_method(NULL)); +} +LCRYPTO_ALIAS(UI_new); + +UI * +UI_new_method(const UI_METHOD *method) +{ + UI *ret; + + if ((ret = calloc(1, sizeof(UI))) == NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + return NULL; + } + if ((ret->meth = method) == NULL) + ret->meth = UI_get_default_method(); + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data); + + return ret; +} +LCRYPTO_ALIAS(UI_new_method); + +static void +free_string(UI_STRING *uis) +{ + if (uis == NULL) + return; + if (uis->flags & OUT_STRING_FREEABLE) { + free((char *) uis->out_string); + switch (uis->type) { + case UIT_BOOLEAN: + free((char *)uis->_.boolean_data.action_desc); + free((char *)uis->_.boolean_data.ok_chars); + free((char *)uis->_.boolean_data.cancel_chars); + break; + default: + break; + } + } + free(uis); +} + +void +UI_free(UI *ui) +{ + if (ui == NULL) + return; + + sk_UI_STRING_pop_free(ui->strings, free_string); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data); + free(ui); +} +LCRYPTO_ALIAS(UI_free); + +static int +allocate_string_stack(UI *ui) +{ + if (ui->strings == NULL) { + if ((ui->strings = sk_UI_STRING_new_null()) == NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + return -1; + } + } + return 0; +} + +static UI_STRING * +general_allocate_prompt(const char *prompt, int dup_prompt, + enum UI_string_types type, int input_flags, char *result_buf) +{ + UI_STRING *uis = NULL; + + if (prompt == NULL) { + UIerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if ((type == UIT_PROMPT || type == UIT_VERIFY || type == UIT_BOOLEAN) && + result_buf == NULL) { + UIerror(UI_R_NO_RESULT_BUFFER); + goto err; + } + + if ((uis = calloc(1, sizeof(UI_STRING))) == NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + goto err; + } + uis->out_string = prompt; + if (dup_prompt) { + if ((uis->out_string = strdup(prompt)) == NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + goto err; + } + uis->flags = OUT_STRING_FREEABLE; + } + uis->input_flags = input_flags; + uis->type = type; + uis->result_buf = result_buf; + + return uis; + + err: + free_string(uis); + return NULL; +} + +static int +general_allocate_string(UI *ui, const char *prompt, int dup_prompt, + enum UI_string_types type, int input_flags, char *result_buf, int minsize, + int maxsize, const char *test_buf) +{ + UI_STRING *s; + int ret; + + if ((s = general_allocate_prompt(prompt, dup_prompt, type, input_flags, + result_buf)) == NULL) + goto err; + s->_.string_data.result_minsize = minsize; + s->_.string_data.result_maxsize = maxsize; + s->_.string_data.test_buf = test_buf; + + if (allocate_string_stack(ui) < 0) + goto err; + if ((ret = sk_UI_STRING_push(ui->strings, s)) <= 0) + goto err; + + return ret; + + err: + free_string(s); + return -1; +} + +static int +general_allocate_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, int dup_strings, + enum UI_string_types type, int input_flags, char *result_buf) +{ + UI_STRING *s = NULL; + int ret; + + if (ok_chars == NULL || cancel_chars == NULL) { + UIerror(ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if (ok_chars[strcspn(ok_chars, cancel_chars)] != '\0') { + UIerror(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); + goto err; + } + + if ((s = general_allocate_prompt(prompt, dup_strings, type, input_flags, + result_buf)) == NULL) + goto err; + + if (dup_strings) { + if (action_desc != NULL) { + if ((s->_.boolean_data.action_desc = + strdup(action_desc)) == NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + goto err; + } + } + if ((s->_.boolean_data.ok_chars = strdup(ok_chars)) == NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + goto err; + } + if ((s->_.boolean_data.cancel_chars = strdup(cancel_chars)) == + NULL) { + UIerror(ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + s->_.boolean_data.action_desc = action_desc; + s->_.boolean_data.ok_chars = ok_chars; + s->_.boolean_data.cancel_chars = cancel_chars; + } + + if (allocate_string_stack(ui) < 0) + goto err; + if ((ret = sk_UI_STRING_push(ui->strings, s)) <= 0) + goto err; + + return ret; + + err: + free_string(s); + return -1; +} + +/* + * Returns the index to the place in the stack or -1 for error. Uses a + * direct reference to the prompt. + */ +int +UI_add_input_string(UI *ui, const char *prompt, int flags, char *result_buf, + int minsize, int maxsize) +{ + return general_allocate_string(ui, prompt, 0, UIT_PROMPT, flags, + result_buf, minsize, maxsize, NULL); +} +LCRYPTO_ALIAS(UI_add_input_string); + +/* Same as UI_add_input_string(), excepts it takes a copy of the prompt. */ +int +UI_dup_input_string(UI *ui, const char *prompt, int flags, char *result_buf, + int minsize, int maxsize) +{ + return general_allocate_string(ui, prompt, 1, UIT_PROMPT, flags, + result_buf, minsize, maxsize, NULL); +} +LCRYPTO_ALIAS(UI_dup_input_string); + +int +UI_add_verify_string(UI *ui, const char *prompt, int flags, char *result_buf, + int minsize, int maxsize, const char *test_buf) +{ + return general_allocate_string(ui, prompt, 0, UIT_VERIFY, flags, + result_buf, minsize, maxsize, test_buf); +} +LCRYPTO_ALIAS(UI_add_verify_string); + +int +UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, const char *test_buf) +{ + return general_allocate_string(ui, prompt, 1, UIT_VERIFY, flags, + result_buf, minsize, maxsize, test_buf); +} +LCRYPTO_ALIAS(UI_dup_verify_string); + +int +UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, int flags, char *result_buf) +{ + return general_allocate_boolean(ui, prompt, action_desc, ok_chars, + cancel_chars, 0, UIT_BOOLEAN, flags, result_buf); +} +LCRYPTO_ALIAS(UI_add_input_boolean); + +int +UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, int flags, char *result_buf) +{ + return general_allocate_boolean(ui, prompt, action_desc, ok_chars, + cancel_chars, 1, UIT_BOOLEAN, flags, result_buf); +} +LCRYPTO_ALIAS(UI_dup_input_boolean); + +int +UI_add_info_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0, + NULL); +} +LCRYPTO_ALIAS(UI_add_info_string); + +int +UI_dup_info_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 1, UIT_INFO, 0, NULL, 0, 0, + NULL); +} +LCRYPTO_ALIAS(UI_dup_info_string); + +int +UI_add_error_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0, + NULL); +} +LCRYPTO_ALIAS(UI_add_error_string); + +int +UI_dup_error_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 1, UIT_ERROR, 0, NULL, 0, 0, + NULL); +} +LCRYPTO_ALIAS(UI_dup_error_string); + +char * +UI_construct_prompt(UI *ui, const char *object_desc, const char *object_name) +{ + char *prompt; + + if (ui->meth->ui_construct_prompt) + return ui->meth->ui_construct_prompt(ui, object_desc, + object_name); + + if (object_desc == NULL) + return NULL; + + if (object_name == NULL) { + if (asprintf(&prompt, "Enter %s:", object_desc) == -1) + return (NULL); + } else { + if (asprintf(&prompt, "Enter %s for %s:", object_desc, + object_name) == -1) + return (NULL); + } + + return prompt; +} +LCRYPTO_ALIAS(UI_construct_prompt); + +void * +UI_add_user_data(UI *ui, void *user_data) +{ + void *old_data = ui->user_data; + + ui->user_data = user_data; + + return old_data; +} +LCRYPTO_ALIAS(UI_add_user_data); + +void * +UI_get0_user_data(UI *ui) +{ + return ui->user_data; +} +LCRYPTO_ALIAS(UI_get0_user_data); + +const char * +UI_get0_result(UI *ui, int i) +{ + if (i < 0) { + UIerror(UI_R_INDEX_TOO_SMALL); + return NULL; + } + if (i >= sk_UI_STRING_num(ui->strings)) { + UIerror(UI_R_INDEX_TOO_LARGE); + return NULL; + } + return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i)); +} +LCRYPTO_ALIAS(UI_get0_result); + +static int +print_error(const char *str, size_t len, void *arg) +{ + UI *ui = arg; + UI_STRING uis; + + memset(&uis, 0, sizeof(uis)); + uis.type = UIT_ERROR; + uis.out_string = str; + + if (ui->meth->ui_write_string && + !ui->meth->ui_write_string(ui, &uis)) + return -1; + return 0; +} + +int +UI_process(UI *ui) +{ + int i, ok = 0; + + if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui)) + return -1; + + if (ui->flags & UI_FLAG_PRINT_ERRORS) + ERR_print_errors_cb(print_error, ui); + + for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { + if (ui->meth->ui_write_string && + !ui->meth->ui_write_string(ui, + sk_UI_STRING_value(ui->strings, i))) { + ok = -1; + goto err; + } + } + + if (ui->meth->ui_flush) + switch (ui->meth->ui_flush(ui)) { + case -1: /* Interrupt/Cancel/something... */ + ok = -2; + goto err; + case 0: /* Errors */ + ok = -1; + goto err; + default: /* Success */ + ok = 0; + break; + } + + for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { + if (ui->meth->ui_read_string) { + switch (ui->meth->ui_read_string(ui, + sk_UI_STRING_value(ui->strings, i))) { + case -1: /* Interrupt/Cancel/something... */ + ui->flags &= ~UI_FLAG_REDOABLE; + ok = -2; + goto err; + case 0: /* Errors */ + ok = -1; + goto err; + default: /* Success */ + ok = 0; + break; + } + } + } + + err: + if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui)) + return -1; + return ok; +} +LCRYPTO_ALIAS(UI_process); + +int +UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)) +{ + if (ui == NULL) { + UIerror(ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + switch (cmd) { + case UI_CTRL_PRINT_ERRORS: + { + int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS); + if (i) + ui->flags |= UI_FLAG_PRINT_ERRORS; + else + ui->flags &= ~UI_FLAG_PRINT_ERRORS; + return save_flag; + } + case UI_CTRL_IS_REDOABLE: + return !!(ui->flags & UI_FLAG_REDOABLE); + default: + break; + } + UIerror(UI_R_UNKNOWN_CONTROL_COMMAND); + return -1; +} +LCRYPTO_ALIAS(UI_ctrl); + +int +UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp, + new_func, dup_func, free_func); +} +LCRYPTO_ALIAS(UI_get_ex_new_index); + +int +UI_set_ex_data(UI *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} +LCRYPTO_ALIAS(UI_set_ex_data); + +void * +UI_get_ex_data(UI *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} +LCRYPTO_ALIAS(UI_get_ex_data); + +void +UI_set_default_method(const UI_METHOD *method) +{ + default_UI_meth = method; +} +LCRYPTO_ALIAS(UI_set_default_method); + +const UI_METHOD * +UI_get_default_method(void) +{ + if (default_UI_meth == NULL) + default_UI_meth = UI_OpenSSL(); + + return default_UI_meth; +} +LCRYPTO_ALIAS(UI_get_default_method); + +const UI_METHOD * +UI_get_method(UI *ui) +{ + return ui->meth; +} +LCRYPTO_ALIAS(UI_get_method); + +const UI_METHOD * +UI_set_method(UI *ui, const UI_METHOD *method) +{ + ui->meth = method; + + return ui->meth; +} +LCRYPTO_ALIAS(UI_set_method); + +UI_METHOD * +UI_create_method(const char *name) +{ + UI_METHOD *method = NULL; + + if ((method = calloc(1, sizeof(UI_METHOD))) == NULL) + goto err; + + if (name != NULL) { + if ((method->name = strdup(name)) == NULL) + goto err; + } + + return method; + + err: + UI_destroy_method(method); + + return NULL; +} +LCRYPTO_ALIAS(UI_create_method); + +void +UI_destroy_method(UI_METHOD *method) +{ + if (method == NULL) + return; + + free(method->name); + free(method); +} +LCRYPTO_ALIAS(UI_destroy_method); + +int +UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui)) +{ + if (method == NULL) + return -1; + + method->ui_open_session = opener; + + return 0; +} +LCRYPTO_ALIAS(UI_method_set_opener); + +int +UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis)) +{ + if (method == NULL) + return -1; + + method->ui_write_string = writer; + + return 0; +} +LCRYPTO_ALIAS(UI_method_set_writer); + +int +UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)) +{ + if (method == NULL) + return -1; + + method->ui_flush = flusher; + + return 0; +} +LCRYPTO_ALIAS(UI_method_set_flusher); + +int +UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)) +{ + if (method == NULL) + return -1; + + method->ui_read_string = reader; + + return 0; +} +LCRYPTO_ALIAS(UI_method_set_reader); + +int +UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)) +{ + if (method == NULL) + return -1; + + method->ui_close_session = closer; + + return 0; +} +LCRYPTO_ALIAS(UI_method_set_closer); + +int +UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor)(UI *ui, const char *object_desc, + const char *object_name)) +{ + if (method == NULL) + return -1; + + method->ui_construct_prompt = prompt_constructor; + + return 0; +} +LCRYPTO_ALIAS(UI_method_set_prompt_constructor); + +int +(*UI_method_get_opener(const UI_METHOD * method))(UI *) +{ + if (method == NULL) + return NULL; + + return method->ui_open_session; +} +LCRYPTO_ALIAS(UI_method_get_opener); + +int +(*UI_method_get_writer(const UI_METHOD *method))(UI *, UI_STRING *) +{ + if (method == NULL) + return NULL; + + return method->ui_write_string; +} +LCRYPTO_ALIAS(UI_method_get_writer); + +int +(*UI_method_get_flusher(const UI_METHOD *method)) (UI *) +{ + if (method == NULL) + return NULL; + + return method->ui_flush; +} +LCRYPTO_ALIAS(UI_method_get_flusher); + +int +(*UI_method_get_reader(const UI_METHOD *method))(UI *, UI_STRING *) +{ + if (method == NULL) + return NULL; + + return method->ui_read_string; +} +LCRYPTO_ALIAS(UI_method_get_reader); + +int +(*UI_method_get_closer(const UI_METHOD *method))(UI *) +{ + if (method == NULL) + return NULL; + + return method->ui_close_session; +} +LCRYPTO_ALIAS(UI_method_get_closer); + +char * +(*UI_method_get_prompt_constructor(const UI_METHOD *method))(UI *, const char *, + const char *) +{ + if (method == NULL) + return NULL; + + return method->ui_construct_prompt; +} +LCRYPTO_ALIAS(UI_method_get_prompt_constructor); + +enum UI_string_types +UI_get_string_type(UI_STRING *uis) +{ + if (uis == NULL) + return UIT_NONE; + + return uis->type; +} +LCRYPTO_ALIAS(UI_get_string_type); + +int +UI_get_input_flags(UI_STRING *uis) +{ + if (uis == NULL) + return 0; + + return uis->input_flags; +} +LCRYPTO_ALIAS(UI_get_input_flags); + +const char * +UI_get0_output_string(UI_STRING *uis) +{ + if (uis == NULL) + return NULL; + + return uis->out_string; +} +LCRYPTO_ALIAS(UI_get0_output_string); + +const char * +UI_get0_action_string(UI_STRING *uis) +{ + if (uis == NULL) + return NULL; + + switch (uis->type) { + case UIT_PROMPT: + case UIT_BOOLEAN: + return uis->_.boolean_data.action_desc; + default: + return NULL; + } +} +LCRYPTO_ALIAS(UI_get0_action_string); + +const char * +UI_get0_result_string(UI_STRING *uis) +{ + if (uis == NULL) + return NULL; + + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->result_buf; + default: + return NULL; + } +} +LCRYPTO_ALIAS(UI_get0_result_string); + +const char * +UI_get0_test_string(UI_STRING *uis) +{ + if (uis == NULL) + return NULL; + + switch (uis->type) { + case UIT_VERIFY: + return uis->_.string_data.test_buf; + default: + return NULL; + } +} +LCRYPTO_ALIAS(UI_get0_test_string); + +int +UI_get_result_minsize(UI_STRING *uis) +{ + if (uis == NULL) + return -1; + + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->_.string_data.result_minsize; + default: + return -1; + } +} +LCRYPTO_ALIAS(UI_get_result_minsize); + +int +UI_get_result_maxsize(UI_STRING *uis) +{ + if (uis == NULL) + return -1; + + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->_.string_data.result_maxsize; + default: + return -1; + } +} +LCRYPTO_ALIAS(UI_get_result_maxsize); + +int +UI_set_result(UI *ui, UI_STRING *uis, const char *result) +{ + const char *p; + int l = strlen(result); + + ui->flags &= ~UI_FLAG_REDOABLE; + + if (uis == NULL) + return -1; + + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + if (l < uis->_.string_data.result_minsize) { + ui->flags |= UI_FLAG_REDOABLE; + UIerror(UI_R_RESULT_TOO_SMALL); + ERR_asprintf_error_data + ("You must type in %d to %d characters", + uis->_.string_data.result_minsize, + uis->_.string_data.result_maxsize); + return -1; + } + if (l > uis->_.string_data.result_maxsize) { + ui->flags |= UI_FLAG_REDOABLE; + UIerror(UI_R_RESULT_TOO_LARGE); + ERR_asprintf_error_data + ("You must type in %d to %d characters", + uis->_.string_data.result_minsize, + uis->_.string_data.result_maxsize); + return -1; + } + if (!uis->result_buf) { + UIerror(UI_R_NO_RESULT_BUFFER); + return -1; + } + strlcpy(uis->result_buf, result, + uis->_.string_data.result_maxsize + 1); + break; + case UIT_BOOLEAN: + if (!uis->result_buf) { + UIerror(UI_R_NO_RESULT_BUFFER); + return -1; + } + uis->result_buf[0] = '\0'; + for (p = result; *p; p++) { + if (strchr(uis->_.boolean_data.ok_chars, *p)) { + uis->result_buf[0] = + uis->_.boolean_data.ok_chars[0]; + break; + } + if (strchr(uis->_.boolean_data.cancel_chars, *p)) { + uis->result_buf[0] = + uis->_.boolean_data.cancel_chars[0]; + break; + } + } + default: + break; + } + return 0; +} +LCRYPTO_ALIAS(UI_set_result); diff --git a/Libraries/libressl/crypto/ui/ui_local.h b/Libraries/libressl/crypto/ui/ui_local.h new file mode 100644 index 000000000..460b5600b --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_local.h @@ -0,0 +1,152 @@ +/* $OpenBSD: ui_local.h,v 1.2 2022/11/26 17:23:18 tb Exp $ */ + +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_LOCAL_H +#define HEADER_UI_LOCAL_H + +#include +#include + +__BEGIN_HIDDEN_DECLS + +#ifdef _ +#undef _ +#endif + +struct ui_method_st { + char *name; + + /* All the functions return 1 or non-NULL for success and 0 or NULL + for failure */ + + /* Open whatever channel for this, be it the console, an X window + or whatever. + This function should use the ex_data structure to save + intermediate data. */ + int (*ui_open_session)(UI *ui); + + int (*ui_write_string)(UI *ui, UI_STRING *uis); + + /* Flush the output. If a GUI dialog box is used, this function can + be used to actually display it. */ + int (*ui_flush)(UI *ui); + + int (*ui_read_string)(UI *ui, UI_STRING *uis); + + int (*ui_close_session)(UI *ui); + + /* Construct a prompt in a user-defined manner. object_desc is a + textual short description of the object, for example "pass phrase", + and object_name is the name of the object (might be a card name or + a file name. + The returned string shall always be allocated on the heap with + malloc(), and need to be free'd with free(). */ + char *(*ui_construct_prompt)(UI *ui, const char *object_desc, + const char *object_name); +}; + +struct ui_string_st { + enum UI_string_types type; /* Input */ + const char *out_string; /* Input */ + int input_flags; /* Flags from the user */ + + /* The following parameters are completely irrelevant for UIT_INFO, + and can therefore be set to 0 or NULL */ + char *result_buf; /* Input and Output: If not NULL, user-defined + with size in result_maxsize. Otherwise, it + may be allocated by the UI routine, meaning + result_minsize is going to be overwritten.*/ + union { + struct { + int result_minsize; /* Input: minimum required + size of the result. + */ + int result_maxsize; /* Input: maximum permitted + size of the result */ + + const char *test_buf; /* Input: test string to verify + against */ + } string_data; + struct { + const char *action_desc; /* Input */ + const char *ok_chars; /* Input */ + const char *cancel_chars; /* Input */ + } boolean_data; + } _; + +#define OUT_STRING_FREEABLE 0x01 + int flags; /* flags for internal use */ +}; + +struct ui_st { + const UI_METHOD *meth; + STACK_OF(UI_STRING) *strings; /* We might want to prompt for more + than one thing at a time, and + with different echoing status. */ + void *user_data; + CRYPTO_EX_DATA ex_data; + +#define UI_FLAG_REDOABLE 0x0001 +#define UI_FLAG_PRINT_ERRORS 0x0100 + int flags; +}; + +__END_HIDDEN_DECLS + +#endif /* !HEADER_UI_LOCAL_H */ diff --git a/Libraries/libressl/crypto/ui/ui_null.c b/Libraries/libressl/crypto/ui/ui_null.c new file mode 100644 index 000000000..cbc9a5025 --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_null.c @@ -0,0 +1,18 @@ +/* $OpenBSD: ui_null.c,v 1.2 2023/02/16 08:38:17 tb Exp $ */ + +/* + * Written by Theo Buehler. Public domain. + */ + +#include "ui_local.h" + +static const UI_METHOD ui_null = { + .name = "OpenSSL NULL UI", +}; + +const UI_METHOD * +UI_null(void) +{ + return &ui_null; +} +LCRYPTO_ALIAS(UI_null); diff --git a/Libraries/libressl/crypto/ui/ui_openssl.c b/Libraries/libressl/crypto/ui/ui_openssl.c new file mode 100644 index 000000000..0b9170057 --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_openssl.c @@ -0,0 +1,398 @@ +/* $OpenBSD: ui_openssl.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) and others + * for the OpenSSL project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* The lowest level part of this file was previously in crypto/des/read_pwd.c, + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "ui_local.h" + +#ifndef NX509_SIG +#define NX509_SIG 32 +#endif + +/* Define globals. They are protected by a lock */ +static struct sigaction savsig[NX509_SIG]; + +static struct termios tty_orig; +static FILE *tty_in, *tty_out; +static int is_a_tty; + +/* Declare static functions */ +static int read_till_nl(FILE *); +static void recsig(int); +static void pushsig(void); +static void popsig(void); +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); + +static int read_string(UI *ui, UI_STRING *uis); +static int write_string(UI *ui, UI_STRING *uis); + +static int open_console(UI *ui); +static int echo_console(UI *ui); +static int noecho_console(UI *ui); +static int close_console(UI *ui); + +static UI_METHOD ui_openssl = { + .name = "OpenSSL default user interface", + .ui_open_session = open_console, + .ui_write_string = write_string, + .ui_read_string = read_string, + .ui_close_session = close_console, +}; + +/* The method with all the built-in thingies */ +UI_METHOD * +UI_OpenSSL(void) +{ + return &ui_openssl; +} +LCRYPTO_ALIAS(UI_OpenSSL); + +/* The following function makes sure that info and error strings are printed + before any prompt. */ +static int +write_string(UI *ui, UI_STRING *uis) +{ + switch (UI_get_string_type(uis)) { + case UIT_ERROR: + case UIT_INFO: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + break; + default: + break; + } + return 1; +} + +static int +read_string(UI *ui, UI_STRING *uis) +{ + int ok = 0; + + switch (UI_get_string_type(uis)) { + case UIT_BOOLEAN: + fputs(UI_get0_output_string(uis), tty_out); + fputs(UI_get0_action_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0); + case UIT_PROMPT: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1); + case UIT_VERIFY: + fprintf(tty_out, "Verifying - %s", + UI_get0_output_string(uis)); + fflush(tty_out); + if ((ok = read_string_inner(ui, uis, UI_get_input_flags(uis) & + UI_INPUT_FLAG_ECHO, 1)) <= 0) + return ok; + if (strcmp(UI_get0_result_string(uis), + UI_get0_test_string(uis)) != 0) { + fprintf(tty_out, "Verify failure\n"); + fflush(tty_out); + return 0; + } + break; + default: + break; + } + return 1; +} + + +/* Internal functions to read a string without echoing */ +static int +read_till_nl(FILE *in) +{ +#define SIZE 4 + char buf[SIZE + 1]; + + do { + if (!fgets(buf, SIZE, in)) + return 0; + } while (strchr(buf, '\n') == NULL); + return 1; +} + +static volatile sig_atomic_t intr_signal; + +static int +read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) +{ + static int ps; + int ok; + char result[BUFSIZ]; + int maxsize = BUFSIZ - 1; + char *p; + + intr_signal = 0; + ok = 0; + ps = 0; + + pushsig(); + ps = 1; + + if (!echo && !noecho_console(ui)) + goto error; + ps = 2; + + result[0] = '\0'; + p = fgets(result, maxsize, tty_in); + if (!p) + goto error; + if (feof(tty_in)) + goto error; + if (ferror(tty_in)) + goto error; + if ((p = strchr(result, '\n')) != NULL) { + if (strip_nl) + *p = '\0'; + } else if (!read_till_nl(tty_in)) + goto error; + if (UI_set_result(ui, uis, result) >= 0) + ok = 1; + +error: + if (intr_signal == SIGINT) + ok = -1; + if (!echo) + fprintf(tty_out, "\n"); + if (ps >= 2 && !echo && !echo_console(ui)) + ok = 0; + + if (ps >= 1) + popsig(); + + explicit_bzero(result, BUFSIZ); + return ok; +} + + +/* Internal functions to open, handle and close a channel to the console. */ +static int +open_console(UI *ui) +{ + CRYPTO_w_lock(CRYPTO_LOCK_UI); + is_a_tty = 1; + +#define DEV_TTY "/dev/tty" + if ((tty_in = fopen(DEV_TTY, "r")) == NULL) + tty_in = stdin; + if ((tty_out = fopen(DEV_TTY, "w")) == NULL) + tty_out = stderr; + + if (tcgetattr(fileno(tty_in), &tty_orig) == -1) { + if (errno == ENOTTY) + is_a_tty = 0; + else + /* + * Ariel Glenn ariel@columbia.edu reports that + * solaris can return EINVAL instead. This should be + * ok + */ + if (errno == EINVAL) + is_a_tty = 0; + else + return 0; + } + + return 1; +} + +static int +noecho_console(UI *ui) +{ + struct termios tty_new = tty_orig; + + tty_new.c_lflag &= ~ECHO; + if (is_a_tty && (tcsetattr(fileno(tty_in), TCSANOW, &tty_new) == -1)) + return 0; + return 1; +} + +static int +echo_console(UI *ui) +{ + if (is_a_tty && (tcsetattr(fileno(tty_in), TCSANOW, &tty_orig) == -1)) + return 0; + return 1; +} + +static int +close_console(UI *ui) +{ + if (tty_in != stdin) + fclose(tty_in); + if (tty_out != stderr) + fclose(tty_out); + CRYPTO_w_unlock(CRYPTO_LOCK_UI); + + return 1; +} + + +/* Internal functions to handle signals and act on them */ +static void +pushsig(void) +{ + int i; + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = recsig; + + for (i = 1; i < NX509_SIG; i++) { + if (i == SIGUSR1) + continue; + if (i == SIGUSR2) + continue; + if (i == SIGKILL) /* We can't make any action on that. */ + continue; + sigaction(i, &sa, &savsig[i]); + } + + signal(SIGWINCH, SIG_DFL); +} + +static void +popsig(void) +{ + int i; + for (i = 1; i < NX509_SIG; i++) { + if (i == SIGUSR1) + continue; + if (i == SIGUSR2) + continue; + sigaction(i, &savsig[i], NULL); + } +} + +static void +recsig(int i) +{ + intr_signal = i; +} diff --git a/Libraries/libressl/crypto/ui/ui_openssl_win.c b/Libraries/libressl/crypto/ui/ui_openssl_win.c new file mode 100644 index 000000000..b6a621f56 --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_openssl_win.c @@ -0,0 +1,337 @@ +/* $OpenBSD: ui_openssl.c,v 1.22 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) and others + * for the OpenSSL project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* The lowest level part of this file was previously in crypto/des/read_pwd.c, + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "ui_local.h" + +#ifndef NX509_SIG +#define NX509_SIG 32 +#endif + +/* Define globals. They are protected by a lock */ +static void (*savsig[NX509_SIG])(int ); + +DWORD console_mode; +static FILE *tty_in, *tty_out; +static int is_a_tty; + +/* Declare static functions */ +static int read_till_nl(FILE *); +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); + +static int read_string(UI *ui, UI_STRING *uis); +static int write_string(UI *ui, UI_STRING *uis); + +static int open_console(UI *ui); +static int echo_console(UI *ui); +static int noecho_console(UI *ui); +static int close_console(UI *ui); + +static UI_METHOD ui_openssl = { + .name = "OpenSSL default user interface", + .ui_open_session = open_console, + .ui_write_string = write_string, + .ui_read_string = read_string, + .ui_close_session = close_console, +}; + +/* The method with all the built-in thingies */ +UI_METHOD * +UI_OpenSSL(void) +{ + return &ui_openssl; +} + +/* The following function makes sure that info and error strings are printed + before any prompt. */ +static int +write_string(UI *ui, UI_STRING *uis) +{ + switch (UI_get_string_type(uis)) { + case UIT_ERROR: + case UIT_INFO: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + break; + default: + break; + } + return 1; +} + +static int +read_string(UI *ui, UI_STRING *uis) +{ + int ok = 0; + + switch (UI_get_string_type(uis)) { + case UIT_BOOLEAN: + fputs(UI_get0_output_string(uis), tty_out); + fputs(UI_get0_action_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0); + case UIT_PROMPT: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1); + case UIT_VERIFY: + fprintf(tty_out, "Verifying - %s", + UI_get0_output_string(uis)); + fflush(tty_out); + if ((ok = read_string_inner(ui, uis, UI_get_input_flags(uis) & + UI_INPUT_FLAG_ECHO, 1)) <= 0) + return ok; + if (strcmp(UI_get0_result_string(uis), + UI_get0_test_string(uis)) != 0) { + fprintf(tty_out, "Verify failure\n"); + fflush(tty_out); + return 0; + } + break; + default: + break; + } + return 1; +} + + +/* Internal functions to read a string without echoing */ +static int +read_till_nl(FILE *in) +{ +#define SIZE 4 + char buf[SIZE + 1]; + + do { + if (!fgets(buf, SIZE, in)) + return 0; + } while (strchr(buf, '\n') == NULL); + return 1; +} + +static int +read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) +{ + static int ps; + int ok; + char result[BUFSIZ]; + int maxsize = BUFSIZ - 1; + char *p; + + ok = 0; + ps = 0; + + ps = 1; + + if (!echo && !noecho_console(ui)) + goto error; + ps = 2; + + result[0] = '\0'; + p = fgets(result, maxsize, tty_in); + if (!p) + goto error; + if (feof(tty_in)) + goto error; + if (ferror(tty_in)) + goto error; + if ((p = strchr(result, '\n')) != NULL) { + if (strip_nl) + *p = '\0'; + } else if (!read_till_nl(tty_in)) + goto error; + if (UI_set_result(ui, uis, result) >= 0) + ok = 1; + +error: + if (!echo) + fprintf(tty_out, "\n"); + if (ps >= 2 && !echo && !echo_console(ui)) + ok = 0; + + explicit_bzero(result, BUFSIZ); + return ok; +} + + +/* Internal functions to open, handle and close a channel to the console. */ +static int +open_console(UI *ui) +{ + CRYPTO_w_lock(CRYPTO_LOCK_UI); + is_a_tty = 1; + + tty_in = stdin; + tty_out = stderr; + + HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); + if (handle != NULL && handle != INVALID_HANDLE_VALUE) { + if (GetFileType(handle) == FILE_TYPE_CHAR) + return GetConsoleMode(handle, &console_mode); + else + return 1; + } + return 0; +} + +static int +noecho_console(UI *ui) +{ + HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); + if (handle != NULL && handle != INVALID_HANDLE_VALUE) { + if (GetFileType(handle) == FILE_TYPE_CHAR) + return SetConsoleMode(handle, console_mode & ~ENABLE_ECHO_INPUT); + else + return 1; + } + return 0; +} + +static int +echo_console(UI *ui) +{ + HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); + if (handle != NULL && handle != INVALID_HANDLE_VALUE) { + if (GetFileType(handle) == FILE_TYPE_CHAR) + return SetConsoleMode(handle, console_mode); + else + return 1; + } + return 0; +} + +static int +close_console(UI *ui) +{ + if (tty_in != stdin) + fclose(tty_in); + if (tty_out != stderr) + fclose(tty_out); + CRYPTO_w_unlock(CRYPTO_LOCK_UI); + + return 1; +} diff --git a/Libraries/libressl/crypto/ui/ui_util.c b/Libraries/libressl/crypto/ui/ui_util.c new file mode 100644 index 000000000..4fa4058cd --- /dev/null +++ b/Libraries/libressl/crypto/ui/ui_util.c @@ -0,0 +1,98 @@ +/* $OpenBSD: ui_util.c,v 1.14 2023/02/16 08:38:17 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include "ui_local.h" + +int +UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, int verify) +{ + char buff[BUFSIZ]; + int ret; + + ret = UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length, + prompt, verify); + explicit_bzero(buff, BUFSIZ); + return (ret); +} +LCRYPTO_ALIAS(UI_UTIL_read_pw_string); + +int +UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, int verify) +{ + int ok = 0; + UI *ui; + + if (size < 1) + return -1; + + ui = UI_new(); + if (ui) { + ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1); + if (ok >= 0 && verify) + ok = UI_add_verify_string(ui, prompt, 0, buff, 0, + size - 1, buf); + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + } + if (ok > 0) + ok = 0; + return (ok); +} +LCRYPTO_ALIAS(UI_UTIL_read_pw); diff --git a/Libraries/libressl/crypto/whrlpool/wp-elf-x86_64.S b/Libraries/libressl/crypto/whrlpool/wp-elf-x86_64.S new file mode 100644 index 000000000..aba96efee --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp-elf-x86_64.S @@ -0,0 +1,864 @@ +#include "x86_arch.h" +.text + +.globl whirlpool_block +.type whirlpool_block,@function +.align 16 +whirlpool_block: + endbr64 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq %rsp,%r11 + subq $128+40,%rsp + andq $-64,%rsp + + leaq 128(%rsp),%r10 + movq %rdi,0(%r10) + movq %rsi,8(%r10) + movq %rdx,16(%r10) + movq %r11,32(%r10) +.Lprologue: + + movq %r10,%rbx + leaq .Ltable(%rip),%rbp + + xorq %rcx,%rcx + xorq %rdx,%rdx + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 +.Louterloop: + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + xorq %rsi,%rsi + movq %rsi,24(%rbx) +.align 16 +.Lround: + movq 4096(%rbp,%rsi,8),%r8 + movl 0(%rsp),%eax + movl 4(%rsp),%ebx + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r8 + movq 7(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + movl 0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + movq 6(%rbp,%rsi,8),%r10 + movq 5(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + movq 4(%rbp,%rsi,8),%r12 + movq 3(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + movl 0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + movq 2(%rbp,%rsi,8),%r14 + movq 1(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + movl 8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + movl 8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + movl 16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + movl 16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + movl 24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + movl 24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + movl 32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + movl 32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movb %al,%cl + movb %ah,%dl + movl 40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + movl 40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + movl 48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + movl 48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + movl 56+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + movl 56+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r8 + xorq 7(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + movl 64+0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r10 + xorq 5(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r12 + xorq 3(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + movl 64+0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r14 + xorq 1(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + movl 64+8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + movl 64+8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + movl 64+16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + movl 64+16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + movl 64+24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + movl 64+24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + movl 64+32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + movl 64+32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movb %al,%cl + movb %ah,%dl + movl 64+40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + movl 64+40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + movl 64+48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + movl 64+48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + leaq 128(%rsp),%rbx + movq 24(%rbx),%rsi + addq $1,%rsi + cmpq $10,%rsi + je .Lroundsdone + + movq %rsi,24(%rbx) + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + jmp .Lround +.align 16 +.Lroundsdone: + movq 0(%rbx),%rdi + movq 8(%rbx),%rsi + movq 16(%rbx),%rax + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + xorq 0(%rdi),%r8 + xorq 8(%rdi),%r9 + xorq 16(%rdi),%r10 + xorq 24(%rdi),%r11 + xorq 32(%rdi),%r12 + xorq 40(%rdi),%r13 + xorq 48(%rdi),%r14 + xorq 56(%rdi),%r15 + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rsi),%rsi + subq $1,%rax + jz .Lalldone + movq %rsi,8(%rbx) + movq %rax,16(%rbx) + jmp .Louterloop +.Lalldone: + movq 32(%rbx),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue: + retq +.size whirlpool_block,.-whirlpool_block + +.section .rodata +.align 64 +.type .Ltable,@object +.Ltable: +.byte 24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216 +.byte 35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38 +.byte 198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184 +.byte 232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251 +.byte 135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203 +.byte 184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17 +.byte 1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9 +.byte 79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13 +.byte 54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155 +.byte 166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255 +.byte 210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12 +.byte 245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14 +.byte 121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150 +.byte 111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48 +.byte 145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109 +.byte 82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248 +.byte 96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71 +.byte 188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53 +.byte 155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55 +.byte 142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138 +.byte 163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210 +.byte 12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108 +.byte 123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132 +.byte 53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128 +.byte 29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245 +.byte 224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179 +.byte 215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33 +.byte 194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156 +.byte 46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67 +.byte 75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41 +.byte 254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93 +.byte 87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213 +.byte 21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189 +.byte 119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232 +.byte 55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146 +.byte 229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158 +.byte 159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19 +.byte 240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35 +.byte 74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32 +.byte 218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68 +.byte 88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162 +.byte 201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207 +.byte 41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124 +.byte 10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90 +.byte 177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80 +.byte 160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201 +.byte 107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20 +.byte 133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217 +.byte 189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60 +.byte 93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143 +.byte 16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144 +.byte 244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7 +.byte 203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221 +.byte 62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211 +.byte 5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45 +.byte 103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120 +.byte 228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151 +.byte 39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2 +.byte 65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115 +.byte 139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167 +.byte 167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246 +.byte 125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178 +.byte 149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73 +.byte 216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86 +.byte 251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112 +.byte 238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205 +.byte 124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187 +.byte 102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113 +.byte 221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123 +.byte 23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175 +.byte 71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69 +.byte 158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26 +.byte 202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212 +.byte 45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88 +.byte 191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46 +.byte 7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63 +.byte 173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172 +.byte 90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176 +.byte 131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239 +.byte 51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182 +.byte 99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92 +.byte 2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18 +.byte 170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147 +.byte 113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222 +.byte 200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198 +.byte 25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209 +.byte 73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59 +.byte 217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95 +.byte 242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49 +.byte 227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168 +.byte 91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185 +.byte 136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188 +.byte 154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62 +.byte 38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11 +.byte 50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191 +.byte 176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89 +.byte 233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242 +.byte 15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119 +.byte 213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51 +.byte 128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244 +.byte 190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39 +.byte 205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235 +.byte 52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137 +.byte 72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50 +.byte 255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84 +.byte 122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141 +.byte 144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100 +.byte 95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157 +.byte 32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61 +.byte 104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15 +.byte 26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202 +.byte 174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183 +.byte 180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125 +.byte 84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206 +.byte 147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127 +.byte 34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47 +.byte 100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99 +.byte 241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42 +.byte 115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204 +.byte 18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130 +.byte 64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122 +.byte 8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72 +.byte 195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149 +.byte 236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223 +.byte 219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77 +.byte 161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192 +.byte 141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145 +.byte 61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200 +.byte 151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91 +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249 +.byte 43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110 +.byte 118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225 +.byte 130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230 +.byte 214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40 +.byte 27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195 +.byte 181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116 +.byte 175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190 +.byte 106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29 +.byte 80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234 +.byte 69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87 +.byte 243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56 +.byte 48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173 +.byte 239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196 +.byte 63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218 +.byte 85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199 +.byte 162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219 +.byte 234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233 +.byte 101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106 +.byte 186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3 +.byte 47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74 +.byte 192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142 +.byte 222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96 +.byte 28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252 +.byte 253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70 +.byte 77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31 +.byte 146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118 +.byte 117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250 +.byte 6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54 +.byte 138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174 +.byte 178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75 +.byte 230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133 +.byte 14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126 +.byte 31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231 +.byte 98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85 +.byte 212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58 +.byte 168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129 +.byte 150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82 +.byte 249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98 +.byte 197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163 +.byte 37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16 +.byte 89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171 +.byte 132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208 +.byte 114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197 +.byte 57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236 +.byte 76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22 +.byte 94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148 +.byte 120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159 +.byte 56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229 +.byte 140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152 +.byte 209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23 +.byte 165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228 +.byte 226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161 +.byte 97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78 +.byte 179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66 +.byte 33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52 +.byte 156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8 +.byte 30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238 +.byte 67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97 +.byte 199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177 +.byte 252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79 +.byte 4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36 +.byte 81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227 +.byte 153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37 +.byte 109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34 +.byte 13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101 +.byte 250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121 +.byte 223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105 +.byte 126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169 +.byte 36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25 +.byte 59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254 +.byte 171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154 +.byte 206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240 +.byte 17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153 +.byte 143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131 +.byte 78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4 +.byte 183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102 +.byte 235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224 +.byte 60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193 +.byte 129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253 +.byte 148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64 +.byte 247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28 +.byte 185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24 +.byte 19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139 +.byte 44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81 +.byte 211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5 +.byte 231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140 +.byte 110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57 +.byte 196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170 +.byte 3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27 +.byte 86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220 +.byte 68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94 +.byte 127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160 +.byte 169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136 +.byte 42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103 +.byte 187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10 +.byte 193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135 +.byte 83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241 +.byte 220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114 +.byte 11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83 +.byte 157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1 +.byte 108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43 +.byte 49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164 +.byte 116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243 +.byte 246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21 +.byte 70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76 +.byte 172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165 +.byte 137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181 +.byte 20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180 +.byte 225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186 +.byte 22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166 +.byte 58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247 +.byte 105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6 +.byte 9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65 +.byte 112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215 +.byte 182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111 +.byte 208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30 +.byte 237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214 +.byte 204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226 +.byte 66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104 +.byte 152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44 +.byte 164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237 +.byte 40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117 +.byte 92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134 +.byte 248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107 +.byte 134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194 +.byte 24,35,198,232,135,184,1,79 +.byte 54,166,210,245,121,111,145,82 +.byte 96,188,155,142,163,12,123,53 +.byte 29,224,215,194,46,75,254,87 +.byte 21,119,55,229,159,240,74,218 +.byte 88,201,41,10,177,160,107,133 +.byte 189,93,16,244,203,62,5,103 +.byte 228,39,65,139,167,125,149,216 +.byte 251,238,124,102,221,23,71,158 +.byte 202,45,191,7,173,90,131,51 +#if defined(HAVE_GNU_STACK) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Libraries/libressl/crypto/whrlpool/wp-macosx-x86_64.S b/Libraries/libressl/crypto/whrlpool/wp-macosx-x86_64.S new file mode 100644 index 000000000..6df325ad3 --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp-macosx-x86_64.S @@ -0,0 +1,859 @@ +#include "x86_arch.h" +.text + +.globl _whirlpool_block + +.p2align 4 +_whirlpool_block: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq %rsp,%r11 + subq $128+40,%rsp + andq $-64,%rsp + + leaq 128(%rsp),%r10 + movq %rdi,0(%r10) + movq %rsi,8(%r10) + movq %rdx,16(%r10) + movq %r11,32(%r10) +L$prologue: + + movq %r10,%rbx + leaq L$table(%rip),%rbp + + xorq %rcx,%rcx + xorq %rdx,%rdx + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 +L$outerloop: + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + xorq %rsi,%rsi + movq %rsi,24(%rbx) +.p2align 4 +L$round: + movq 4096(%rbp,%rsi,8),%r8 + movl 0(%rsp),%eax + movl 4(%rsp),%ebx + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r8 + movq 7(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + movl 0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + movq 6(%rbp,%rsi,8),%r10 + movq 5(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + movq 4(%rbp,%rsi,8),%r12 + movq 3(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + movl 0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + movq 2(%rbp,%rsi,8),%r14 + movq 1(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + movl 8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + movl 8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + movl 16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + movl 16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + movl 24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + movl 24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + movl 32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + movl 32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movb %al,%cl + movb %ah,%dl + movl 40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + movl 40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + movl 48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + movl 48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + movl 56+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + movl 56+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r8 + xorq 7(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + movl 64+0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r10 + xorq 5(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r12 + xorq 3(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + movl 64+0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r14 + xorq 1(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + movl 64+8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + movl 64+8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + movl 64+16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + movl 64+16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + movl 64+24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + movl 64+24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + movl 64+32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + movl 64+32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movb %al,%cl + movb %ah,%dl + movl 64+40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + movl 64+40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + movl 64+48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + movl 64+48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + leaq 128(%rsp),%rbx + movq 24(%rbx),%rsi + addq $1,%rsi + cmpq $10,%rsi + je L$roundsdone + + movq %rsi,24(%rbx) + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + jmp L$round +.p2align 4 +L$roundsdone: + movq 0(%rbx),%rdi + movq 8(%rbx),%rsi + movq 16(%rbx),%rax + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + xorq 0(%rdi),%r8 + xorq 8(%rdi),%r9 + xorq 16(%rdi),%r10 + xorq 24(%rdi),%r11 + xorq 32(%rdi),%r12 + xorq 40(%rdi),%r13 + xorq 48(%rdi),%r14 + xorq 56(%rdi),%r15 + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rsi),%rsi + subq $1,%rax + jz L$alldone + movq %rsi,8(%rbx) + movq %rax,16(%rbx) + jmp L$outerloop +L$alldone: + movq 32(%rbx),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$epilogue: + retq + + +.p2align 6 + +L$table: +.byte 24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216 +.byte 35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38 +.byte 198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184 +.byte 232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251 +.byte 135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203 +.byte 184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17 +.byte 1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9 +.byte 79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13 +.byte 54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155 +.byte 166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255 +.byte 210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12 +.byte 245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14 +.byte 121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150 +.byte 111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48 +.byte 145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109 +.byte 82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248 +.byte 96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71 +.byte 188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53 +.byte 155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55 +.byte 142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138 +.byte 163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210 +.byte 12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108 +.byte 123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132 +.byte 53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128 +.byte 29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245 +.byte 224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179 +.byte 215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33 +.byte 194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156 +.byte 46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67 +.byte 75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41 +.byte 254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93 +.byte 87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213 +.byte 21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189 +.byte 119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232 +.byte 55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146 +.byte 229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158 +.byte 159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19 +.byte 240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35 +.byte 74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32 +.byte 218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68 +.byte 88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162 +.byte 201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207 +.byte 41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124 +.byte 10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90 +.byte 177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80 +.byte 160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201 +.byte 107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20 +.byte 133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217 +.byte 189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60 +.byte 93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143 +.byte 16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144 +.byte 244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7 +.byte 203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221 +.byte 62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211 +.byte 5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45 +.byte 103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120 +.byte 228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151 +.byte 39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2 +.byte 65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115 +.byte 139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167 +.byte 167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246 +.byte 125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178 +.byte 149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73 +.byte 216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86 +.byte 251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112 +.byte 238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205 +.byte 124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187 +.byte 102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113 +.byte 221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123 +.byte 23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175 +.byte 71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69 +.byte 158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26 +.byte 202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212 +.byte 45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88 +.byte 191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46 +.byte 7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63 +.byte 173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172 +.byte 90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176 +.byte 131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239 +.byte 51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182 +.byte 99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92 +.byte 2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18 +.byte 170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147 +.byte 113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222 +.byte 200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198 +.byte 25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209 +.byte 73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59 +.byte 217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95 +.byte 242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49 +.byte 227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168 +.byte 91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185 +.byte 136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188 +.byte 154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62 +.byte 38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11 +.byte 50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191 +.byte 176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89 +.byte 233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242 +.byte 15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119 +.byte 213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51 +.byte 128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244 +.byte 190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39 +.byte 205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235 +.byte 52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137 +.byte 72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50 +.byte 255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84 +.byte 122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141 +.byte 144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100 +.byte 95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157 +.byte 32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61 +.byte 104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15 +.byte 26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202 +.byte 174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183 +.byte 180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125 +.byte 84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206 +.byte 147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127 +.byte 34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47 +.byte 100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99 +.byte 241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42 +.byte 115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204 +.byte 18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130 +.byte 64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122 +.byte 8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72 +.byte 195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149 +.byte 236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223 +.byte 219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77 +.byte 161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192 +.byte 141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145 +.byte 61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200 +.byte 151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91 +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249 +.byte 43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110 +.byte 118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225 +.byte 130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230 +.byte 214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40 +.byte 27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195 +.byte 181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116 +.byte 175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190 +.byte 106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29 +.byte 80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234 +.byte 69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87 +.byte 243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56 +.byte 48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173 +.byte 239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196 +.byte 63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218 +.byte 85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199 +.byte 162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219 +.byte 234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233 +.byte 101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106 +.byte 186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3 +.byte 47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74 +.byte 192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142 +.byte 222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96 +.byte 28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252 +.byte 253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70 +.byte 77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31 +.byte 146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118 +.byte 117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250 +.byte 6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54 +.byte 138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174 +.byte 178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75 +.byte 230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133 +.byte 14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126 +.byte 31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231 +.byte 98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85 +.byte 212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58 +.byte 168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129 +.byte 150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82 +.byte 249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98 +.byte 197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163 +.byte 37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16 +.byte 89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171 +.byte 132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208 +.byte 114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197 +.byte 57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236 +.byte 76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22 +.byte 94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148 +.byte 120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159 +.byte 56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229 +.byte 140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152 +.byte 209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23 +.byte 165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228 +.byte 226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161 +.byte 97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78 +.byte 179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66 +.byte 33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52 +.byte 156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8 +.byte 30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238 +.byte 67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97 +.byte 199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177 +.byte 252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79 +.byte 4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36 +.byte 81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227 +.byte 153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37 +.byte 109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34 +.byte 13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101 +.byte 250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121 +.byte 223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105 +.byte 126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169 +.byte 36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25 +.byte 59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254 +.byte 171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154 +.byte 206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240 +.byte 17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153 +.byte 143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131 +.byte 78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4 +.byte 183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102 +.byte 235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224 +.byte 60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193 +.byte 129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253 +.byte 148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64 +.byte 247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28 +.byte 185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24 +.byte 19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139 +.byte 44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81 +.byte 211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5 +.byte 231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140 +.byte 110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57 +.byte 196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170 +.byte 3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27 +.byte 86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220 +.byte 68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94 +.byte 127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160 +.byte 169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136 +.byte 42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103 +.byte 187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10 +.byte 193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135 +.byte 83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241 +.byte 220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114 +.byte 11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83 +.byte 157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1 +.byte 108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43 +.byte 49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164 +.byte 116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243 +.byte 246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21 +.byte 70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76 +.byte 172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165 +.byte 137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181 +.byte 20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180 +.byte 225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186 +.byte 22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166 +.byte 58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247 +.byte 105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6 +.byte 9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65 +.byte 112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215 +.byte 182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111 +.byte 208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30 +.byte 237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214 +.byte 204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226 +.byte 66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104 +.byte 152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44 +.byte 164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237 +.byte 40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117 +.byte 92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134 +.byte 248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107 +.byte 134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194 +.byte 24,35,198,232,135,184,1,79 +.byte 54,166,210,245,121,111,145,82 +.byte 96,188,155,142,163,12,123,53 +.byte 29,224,215,194,46,75,254,87 +.byte 21,119,55,229,159,240,74,218 +.byte 88,201,41,10,177,160,107,133 +.byte 189,93,16,244,203,62,5,103 +.byte 228,39,65,139,167,125,149,216 +.byte 251,238,124,102,221,23,71,158 +.byte 202,45,191,7,173,90,131,51 diff --git a/Libraries/libressl/crypto/whrlpool/wp-masm-x86_64.S b/Libraries/libressl/crypto/whrlpool/wp-masm-x86_64.S new file mode 100644 index 000000000..71f0c012a --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp-masm-x86_64.S @@ -0,0 +1,943 @@ +; 1 "crypto/whrlpool/wp-masm-x86_64.S.tmp" +; 1 "" 1 +; 1 "" 3 +; 343 "" 3 +; 1 "" 1 +; 1 "" 2 +; 1 "crypto/whrlpool/wp-masm-x86_64.S.tmp" 2 +OPTION DOTNAME + +; 1 "./crypto/x86_arch.h" 1 + + +; 16 "./crypto/x86_arch.h" + + + + + + + + + +; 40 "./crypto/x86_arch.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; 3 "crypto/whrlpool/wp-masm-x86_64.S.tmp" 2 +.text$ SEGMENT ALIGN(64) 'CODE' + +PUBLIC whirlpool_block + +ALIGN 16 +whirlpool_block PROC PUBLIC + mov QWORD PTR[8+rsp],rdi ;WIN64 prologue + mov QWORD PTR[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_whirlpool_block:: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + mov r11,rsp + sub rsp,128+40 + and rsp,-64 + + lea r10,QWORD PTR[128+rsp] + mov QWORD PTR[r10],rdi + mov QWORD PTR[8+r10],rsi + mov QWORD PTR[16+r10],rdx + mov QWORD PTR[32+r10],r11 +$L$prologue:: + + mov rbx,r10 + lea rbp,QWORD PTR[$L$table] + + xor rcx,rcx + xor rdx,rdx + mov r8,QWORD PTR[rdi] + mov r9,QWORD PTR[8+rdi] + mov r10,QWORD PTR[16+rdi] + mov r11,QWORD PTR[24+rdi] + mov r12,QWORD PTR[32+rdi] + mov r13,QWORD PTR[40+rdi] + mov r14,QWORD PTR[48+rdi] + mov r15,QWORD PTR[56+rdi] +$L$outerloop:: + mov QWORD PTR[rsp],r8 + mov QWORD PTR[8+rsp],r9 + mov QWORD PTR[16+rsp],r10 + mov QWORD PTR[24+rsp],r11 + mov QWORD PTR[32+rsp],r12 + mov QWORD PTR[40+rsp],r13 + mov QWORD PTR[48+rsp],r14 + mov QWORD PTR[56+rsp],r15 + xor r8,QWORD PTR[rsi] + xor r9,QWORD PTR[8+rsi] + xor r10,QWORD PTR[16+rsi] + xor r11,QWORD PTR[24+rsi] + xor r12,QWORD PTR[32+rsi] + xor r13,QWORD PTR[40+rsi] + xor r14,QWORD PTR[48+rsi] + xor r15,QWORD PTR[56+rsi] + mov QWORD PTR[((64+0))+rsp],r8 + mov QWORD PTR[((64+8))+rsp],r9 + mov QWORD PTR[((64+16))+rsp],r10 + mov QWORD PTR[((64+24))+rsp],r11 + mov QWORD PTR[((64+32))+rsp],r12 + mov QWORD PTR[((64+40))+rsp],r13 + mov QWORD PTR[((64+48))+rsp],r14 + mov QWORD PTR[((64+56))+rsp],r15 + xor rsi,rsi + mov QWORD PTR[24+rbx],rsi +ALIGN 16 +$L$round:: + mov r8,QWORD PTR[4096+rsi*8+rbp] + mov eax,DWORD PTR[rsp] + mov ebx,DWORD PTR[4+rsp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r8,QWORD PTR[rsi*8+rbp] + mov r9,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((0+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + mov r10,QWORD PTR[6+rsi*8+rbp] + mov r11,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + mov r12,QWORD PTR[4+rsi*8+rbp] + mov r13,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((0+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + mov r14,QWORD PTR[2+rsi*8+rbp] + mov r15,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r9,QWORD PTR[rsi*8+rbp] + xor r10,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((8+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r11,QWORD PTR[6+rsi*8+rbp] + xor r12,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r13,QWORD PTR[4+rsi*8+rbp] + xor r14,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((8+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r15,QWORD PTR[2+rsi*8+rbp] + xor r8,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r10,QWORD PTR[rsi*8+rbp] + xor r11,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((16+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r12,QWORD PTR[6+rsi*8+rbp] + xor r13,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r14,QWORD PTR[4+rsi*8+rbp] + xor r15,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((16+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r8,QWORD PTR[2+rsi*8+rbp] + xor r9,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r11,QWORD PTR[rsi*8+rbp] + xor r12,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((24+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r13,QWORD PTR[6+rsi*8+rbp] + xor r14,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r15,QWORD PTR[4+rsi*8+rbp] + xor r8,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((24+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r9,QWORD PTR[2+rsi*8+rbp] + xor r10,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r12,QWORD PTR[rsi*8+rbp] + xor r13,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((32+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r14,QWORD PTR[6+rsi*8+rbp] + xor r15,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r8,QWORD PTR[4+rsi*8+rbp] + xor r9,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((32+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r10,QWORD PTR[2+rsi*8+rbp] + xor r11,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r13,QWORD PTR[rsi*8+rbp] + xor r14,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((40+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r15,QWORD PTR[6+rsi*8+rbp] + xor r8,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r9,QWORD PTR[4+rsi*8+rbp] + xor r10,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((40+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r11,QWORD PTR[2+rsi*8+rbp] + xor r12,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r14,QWORD PTR[rsi*8+rbp] + xor r15,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((48+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r8,QWORD PTR[6+rsi*8+rbp] + xor r9,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r10,QWORD PTR[4+rsi*8+rbp] + xor r11,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((48+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r12,QWORD PTR[2+rsi*8+rbp] + xor r13,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r15,QWORD PTR[rsi*8+rbp] + xor r8,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((56+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r9,QWORD PTR[6+rsi*8+rbp] + xor r10,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r11,QWORD PTR[4+rsi*8+rbp] + xor r12,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((56+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r13,QWORD PTR[2+rsi*8+rbp] + xor r14,QWORD PTR[1+rdi*8+rbp] + mov QWORD PTR[rsp],r8 + mov QWORD PTR[8+rsp],r9 + mov QWORD PTR[16+rsp],r10 + mov QWORD PTR[24+rsp],r11 + mov QWORD PTR[32+rsp],r12 + mov QWORD PTR[40+rsp],r13 + mov QWORD PTR[48+rsp],r14 + mov QWORD PTR[56+rsp],r15 + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r8,QWORD PTR[rsi*8+rbp] + xor r9,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+0+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r10,QWORD PTR[6+rsi*8+rbp] + xor r11,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r12,QWORD PTR[4+rsi*8+rbp] + xor r13,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+0+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r14,QWORD PTR[2+rsi*8+rbp] + xor r15,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r9,QWORD PTR[rsi*8+rbp] + xor r10,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+8+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r11,QWORD PTR[6+rsi*8+rbp] + xor r12,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r13,QWORD PTR[4+rsi*8+rbp] + xor r14,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+8+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r15,QWORD PTR[2+rsi*8+rbp] + xor r8,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r10,QWORD PTR[rsi*8+rbp] + xor r11,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+16+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r12,QWORD PTR[6+rsi*8+rbp] + xor r13,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r14,QWORD PTR[4+rsi*8+rbp] + xor r15,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+16+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r8,QWORD PTR[2+rsi*8+rbp] + xor r9,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r11,QWORD PTR[rsi*8+rbp] + xor r12,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+24+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r13,QWORD PTR[6+rsi*8+rbp] + xor r14,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r15,QWORD PTR[4+rsi*8+rbp] + xor r8,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+24+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r9,QWORD PTR[2+rsi*8+rbp] + xor r10,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r12,QWORD PTR[rsi*8+rbp] + xor r13,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+32+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r14,QWORD PTR[6+rsi*8+rbp] + xor r15,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r8,QWORD PTR[4+rsi*8+rbp] + xor r9,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+32+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r10,QWORD PTR[2+rsi*8+rbp] + xor r11,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r13,QWORD PTR[rsi*8+rbp] + xor r14,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+40+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r15,QWORD PTR[6+rsi*8+rbp] + xor r8,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r9,QWORD PTR[4+rsi*8+rbp] + xor r10,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+40+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r11,QWORD PTR[2+rsi*8+rbp] + xor r12,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r14,QWORD PTR[rsi*8+rbp] + xor r15,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + mov eax,DWORD PTR[((64+48+8))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r8,QWORD PTR[6+rsi*8+rbp] + xor r9,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r10,QWORD PTR[4+rsi*8+rbp] + xor r11,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + mov ebx,DWORD PTR[((64+48+8+4))+rsp] + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r12,QWORD PTR[2+rsi*8+rbp] + xor r13,QWORD PTR[1+rdi*8+rbp] + mov cl,al + mov dl,ah + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr eax,16 + xor r15,QWORD PTR[rsi*8+rbp] + xor r8,QWORD PTR[7+rdi*8+rbp] + mov cl,al + mov dl,ah + + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r9,QWORD PTR[6+rsi*8+rbp] + xor r10,QWORD PTR[5+rdi*8+rbp] + mov cl,bl + mov dl,bh + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + shr ebx,16 + xor r11,QWORD PTR[4+rsi*8+rbp] + xor r12,QWORD PTR[3+rdi*8+rbp] + mov cl,bl + mov dl,bh + + lea rsi,QWORD PTR[rcx*1+rcx] + lea rdi,QWORD PTR[rdx*1+rdx] + xor r13,QWORD PTR[2+rsi*8+rbp] + xor r14,QWORD PTR[1+rdi*8+rbp] + lea rbx,QWORD PTR[128+rsp] + mov rsi,QWORD PTR[24+rbx] + add rsi,1 + cmp rsi,10 + je $L$roundsdone + + mov QWORD PTR[24+rbx],rsi + mov QWORD PTR[((64+0))+rsp],r8 + mov QWORD PTR[((64+8))+rsp],r9 + mov QWORD PTR[((64+16))+rsp],r10 + mov QWORD PTR[((64+24))+rsp],r11 + mov QWORD PTR[((64+32))+rsp],r12 + mov QWORD PTR[((64+40))+rsp],r13 + mov QWORD PTR[((64+48))+rsp],r14 + mov QWORD PTR[((64+56))+rsp],r15 + jmp $L$round +ALIGN 16 +$L$roundsdone:: + mov rdi,QWORD PTR[rbx] + mov rsi,QWORD PTR[8+rbx] + mov rax,QWORD PTR[16+rbx] + xor r8,QWORD PTR[rsi] + xor r9,QWORD PTR[8+rsi] + xor r10,QWORD PTR[16+rsi] + xor r11,QWORD PTR[24+rsi] + xor r12,QWORD PTR[32+rsi] + xor r13,QWORD PTR[40+rsi] + xor r14,QWORD PTR[48+rsi] + xor r15,QWORD PTR[56+rsi] + xor r8,QWORD PTR[rdi] + xor r9,QWORD PTR[8+rdi] + xor r10,QWORD PTR[16+rdi] + xor r11,QWORD PTR[24+rdi] + xor r12,QWORD PTR[32+rdi] + xor r13,QWORD PTR[40+rdi] + xor r14,QWORD PTR[48+rdi] + xor r15,QWORD PTR[56+rdi] + mov QWORD PTR[rdi],r8 + mov QWORD PTR[8+rdi],r9 + mov QWORD PTR[16+rdi],r10 + mov QWORD PTR[24+rdi],r11 + mov QWORD PTR[32+rdi],r12 + mov QWORD PTR[40+rdi],r13 + mov QWORD PTR[48+rdi],r14 + mov QWORD PTR[56+rdi],r15 + lea rsi,QWORD PTR[64+rsi] + sub rax,1 + jz $L$alldone + mov QWORD PTR[8+rbx],rsi + mov QWORD PTR[16+rbx],rax + jmp $L$outerloop +$L$alldone:: + mov rsi,QWORD PTR[32+rbx] + mov r15,QWORD PTR[rsi] + mov r14,QWORD PTR[8+rsi] + mov r13,QWORD PTR[16+rsi] + mov r12,QWORD PTR[24+rsi] + mov rbp,QWORD PTR[32+rsi] + mov rbx,QWORD PTR[40+rsi] + lea rsp,QWORD PTR[48+rsi] +$L$epilogue:: + mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue + mov rsi,QWORD PTR[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_whirlpool_block:: +whirlpool_block ENDP + +ALIGN 64 + +$L$table:: +DB 24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216 +DB 35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38 +DB 198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184 +DB 232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251 +DB 135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203 +DB 184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17 +DB 1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9 +DB 79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13 +DB 54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155 +DB 166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255 +DB 210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12 +DB 245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14 +DB 121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150 +DB 111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48 +DB 145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109 +DB 82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248 +DB 96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71 +DB 188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53 +DB 155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55 +DB 142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138 +DB 163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210 +DB 12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108 +DB 123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132 +DB 53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128 +DB 29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245 +DB 224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179 +DB 215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33 +DB 194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156 +DB 46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67 +DB 75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41 +DB 254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93 +DB 87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213 +DB 21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189 +DB 119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232 +DB 55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146 +DB 229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158 +DB 159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19 +DB 240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35 +DB 74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32 +DB 218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68 +DB 88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162 +DB 201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207 +DB 41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124 +DB 10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90 +DB 177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80 +DB 160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201 +DB 107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20 +DB 133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217 +DB 189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60 +DB 93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143 +DB 16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144 +DB 244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7 +DB 203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221 +DB 62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211 +DB 5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45 +DB 103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120 +DB 228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151 +DB 39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2 +DB 65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115 +DB 139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167 +DB 167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246 +DB 125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178 +DB 149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73 +DB 216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86 +DB 251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112 +DB 238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205 +DB 124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187 +DB 102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113 +DB 221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123 +DB 23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175 +DB 71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69 +DB 158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26 +DB 202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212 +DB 45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88 +DB 191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46 +DB 7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63 +DB 173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172 +DB 90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176 +DB 131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239 +DB 51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182 +DB 99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92 +DB 2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18 +DB 170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147 +DB 113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222 +DB 200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198 +DB 25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209 +DB 73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59 +DB 217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95 +DB 242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49 +DB 227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168 +DB 91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185 +DB 136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188 +DB 154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62 +DB 38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11 +DB 50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191 +DB 176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89 +DB 233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242 +DB 15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119 +DB 213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51 +DB 128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244 +DB 190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39 +DB 205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235 +DB 52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137 +DB 72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50 +DB 255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84 +DB 122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141 +DB 144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100 +DB 95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157 +DB 32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61 +DB 104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15 +DB 26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202 +DB 174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183 +DB 180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125 +DB 84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206 +DB 147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127 +DB 34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47 +DB 100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99 +DB 241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42 +DB 115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204 +DB 18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130 +DB 64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122 +DB 8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72 +DB 195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149 +DB 236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223 +DB 219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77 +DB 161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192 +DB 141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145 +DB 61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200 +DB 151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91 +DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +DB 207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249 +DB 43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110 +DB 118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225 +DB 130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230 +DB 214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40 +DB 27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195 +DB 181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116 +DB 175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190 +DB 106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29 +DB 80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234 +DB 69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87 +DB 243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56 +DB 48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173 +DB 239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196 +DB 63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218 +DB 85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199 +DB 162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219 +DB 234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233 +DB 101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106 +DB 186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3 +DB 47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74 +DB 192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142 +DB 222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96 +DB 28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252 +DB 253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70 +DB 77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31 +DB 146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118 +DB 117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250 +DB 6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54 +DB 138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174 +DB 178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75 +DB 230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133 +DB 14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126 +DB 31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231 +DB 98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85 +DB 212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58 +DB 168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129 +DB 150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82 +DB 249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98 +DB 197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163 +DB 37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16 +DB 89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171 +DB 132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208 +DB 114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197 +DB 57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236 +DB 76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22 +DB 94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148 +DB 120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159 +DB 56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229 +DB 140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152 +DB 209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23 +DB 165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228 +DB 226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161 +DB 97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78 +DB 179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66 +DB 33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52 +DB 156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8 +DB 30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238 +DB 67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97 +DB 199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177 +DB 252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79 +DB 4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36 +DB 81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227 +DB 153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37 +DB 109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34 +DB 13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101 +DB 250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121 +DB 223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105 +DB 126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169 +DB 36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25 +DB 59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254 +DB 171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154 +DB 206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240 +DB 17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153 +DB 143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131 +DB 78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4 +DB 183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102 +DB 235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224 +DB 60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193 +DB 129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253 +DB 148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64 +DB 247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28 +DB 185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24 +DB 19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139 +DB 44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81 +DB 211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5 +DB 231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140 +DB 110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57 +DB 196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170 +DB 3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27 +DB 86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220 +DB 68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94 +DB 127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160 +DB 169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136 +DB 42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103 +DB 187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10 +DB 193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135 +DB 83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241 +DB 220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114 +DB 11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83 +DB 157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1 +DB 108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43 +DB 49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164 +DB 116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243 +DB 246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21 +DB 70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76 +DB 172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165 +DB 137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181 +DB 20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180 +DB 225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186 +DB 22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166 +DB 58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247 +DB 105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6 +DB 9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65 +DB 112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215 +DB 182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111 +DB 208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30 +DB 237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214 +DB 204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226 +DB 66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104 +DB 152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44 +DB 164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237 +DB 40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117 +DB 92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134 +DB 248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107 +DB 134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194 +DB 24,35,198,232,135,184,1,79 +DB 54,166,210,245,121,111,145,82 +DB 96,188,155,142,163,12,123,53 +DB 29,224,215,194,46,75,254,87 +DB 21,119,55,229,159,240,74,218 +DB 88,201,41,10,177,160,107,133 +DB 189,93,16,244,203,62,5,103 +DB 228,39,65,139,167,125,149,216 +DB 251,238,124,102,221,23,71,158 +DB 202,45,191,7,173,90,131,51 + +.text$ ENDS +END + diff --git a/Libraries/libressl/crypto/whrlpool/wp-mingw64-x86_64.S b/Libraries/libressl/crypto/whrlpool/wp-mingw64-x86_64.S new file mode 100644 index 000000000..ea9f6cf9b --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp-mingw64-x86_64.S @@ -0,0 +1,869 @@ +#include "x86_arch.h" +.text + +.globl whirlpool_block +.def whirlpool_block; .scl 2; .type 32; .endef +.p2align 4 +whirlpool_block: + movq %rdi,8(%rsp) + movq %rsi,16(%rsp) + movq %rsp,%rax +.LSEH_begin_whirlpool_block: + movq %rcx,%rdi + movq %rdx,%rsi + movq %r8,%rdx + + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq %rsp,%r11 + subq $128+40,%rsp + andq $-64,%rsp + + leaq 128(%rsp),%r10 + movq %rdi,0(%r10) + movq %rsi,8(%r10) + movq %rdx,16(%r10) + movq %r11,32(%r10) +.Lprologue: + + movq %r10,%rbx + leaq .Ltable(%rip),%rbp + + xorq %rcx,%rcx + xorq %rdx,%rdx + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 +.Louterloop: + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + xorq %rsi,%rsi + movq %rsi,24(%rbx) +.p2align 4 +.Lround: + movq 4096(%rbp,%rsi,8),%r8 + movl 0(%rsp),%eax + movl 4(%rsp),%ebx + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r8 + movq 7(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + movl 0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + movq 6(%rbp,%rsi,8),%r10 + movq 5(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + movq 4(%rbp,%rsi,8),%r12 + movq 3(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + movl 0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + movq 2(%rbp,%rsi,8),%r14 + movq 1(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + movl 8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + movl 8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + movl 16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + movl 16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + movl 24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + movl 24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + movl 32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + movl 32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movb %al,%cl + movb %ah,%dl + movl 40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + movl 40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + movl 48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + movl 48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + movl 56+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + movl 56+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r8 + xorq 7(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + movl 64+0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r10 + xorq 5(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r12 + xorq 3(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + movl 64+0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r14 + xorq 1(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + movl 64+8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + movl 64+8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + movl 64+16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + movl 64+16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + movl 64+24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + movl 64+24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + movl 64+32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + movl 64+32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movb %al,%cl + movb %ah,%dl + movl 64+40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + movl 64+40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movb %al,%cl + movb %ah,%dl + movl 64+48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movb %bl,%cl + movb %bh,%dl + movl 64+48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + movb %al,%cl + movb %ah,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%eax + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movb %al,%cl + movb %ah,%dl + + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + movb %bl,%cl + movb %bh,%dl + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + shrl $16,%ebx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movb %bl,%cl + movb %bh,%dl + + leaq (%rcx,%rcx,1),%rsi + leaq (%rdx,%rdx,1),%rdi + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + leaq 128(%rsp),%rbx + movq 24(%rbx),%rsi + addq $1,%rsi + cmpq $10,%rsi + je .Lroundsdone + + movq %rsi,24(%rbx) + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + jmp .Lround +.p2align 4 +.Lroundsdone: + movq 0(%rbx),%rdi + movq 8(%rbx),%rsi + movq 16(%rbx),%rax + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + xorq 0(%rdi),%r8 + xorq 8(%rdi),%r9 + xorq 16(%rdi),%r10 + xorq 24(%rdi),%r11 + xorq 32(%rdi),%r12 + xorq 40(%rdi),%r13 + xorq 48(%rdi),%r14 + xorq 56(%rdi),%r15 + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rsi),%rsi + subq $1,%rax + jz .Lalldone + movq %rsi,8(%rbx) + movq %rax,16(%rbx) + jmp .Louterloop +.Lalldone: + movq 32(%rbx),%rsi + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue: + movq 8(%rsp),%rdi + movq 16(%rsp),%rsi + retq +.LSEH_end_whirlpool_block: + +.p2align 6 + +.Ltable: +.byte 24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216 +.byte 35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38 +.byte 198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184 +.byte 232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251 +.byte 135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203 +.byte 184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17 +.byte 1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9 +.byte 79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13 +.byte 54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155 +.byte 166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255 +.byte 210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12 +.byte 245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14 +.byte 121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150 +.byte 111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48 +.byte 145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109 +.byte 82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248 +.byte 96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71 +.byte 188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53 +.byte 155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55 +.byte 142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138 +.byte 163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210 +.byte 12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108 +.byte 123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132 +.byte 53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128 +.byte 29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245 +.byte 224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179 +.byte 215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33 +.byte 194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156 +.byte 46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67 +.byte 75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41 +.byte 254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93 +.byte 87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213 +.byte 21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189 +.byte 119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232 +.byte 55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146 +.byte 229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158 +.byte 159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19 +.byte 240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35 +.byte 74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32 +.byte 218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68 +.byte 88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162 +.byte 201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207 +.byte 41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124 +.byte 10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90 +.byte 177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80 +.byte 160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201 +.byte 107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20 +.byte 133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217 +.byte 189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60 +.byte 93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143 +.byte 16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144 +.byte 244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7 +.byte 203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221 +.byte 62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211 +.byte 5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45 +.byte 103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120 +.byte 228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151 +.byte 39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2 +.byte 65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115 +.byte 139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167 +.byte 167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246 +.byte 125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178 +.byte 149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73 +.byte 216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86 +.byte 251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112 +.byte 238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205 +.byte 124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187 +.byte 102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113 +.byte 221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123 +.byte 23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175 +.byte 71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69 +.byte 158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26 +.byte 202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212 +.byte 45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88 +.byte 191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46 +.byte 7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63 +.byte 173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172 +.byte 90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176 +.byte 131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239 +.byte 51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182 +.byte 99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92 +.byte 2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18 +.byte 170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147 +.byte 113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222 +.byte 200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198 +.byte 25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209 +.byte 73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59 +.byte 217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95 +.byte 242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49 +.byte 227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168 +.byte 91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185 +.byte 136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188 +.byte 154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62 +.byte 38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11 +.byte 50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191 +.byte 176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89 +.byte 233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242 +.byte 15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119 +.byte 213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51 +.byte 128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244 +.byte 190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39 +.byte 205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235 +.byte 52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137 +.byte 72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50 +.byte 255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84 +.byte 122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141 +.byte 144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100 +.byte 95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157 +.byte 32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61 +.byte 104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15 +.byte 26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202 +.byte 174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183 +.byte 180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125 +.byte 84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206 +.byte 147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127 +.byte 34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47 +.byte 100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99 +.byte 241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42 +.byte 115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204 +.byte 18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130 +.byte 64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122 +.byte 8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72 +.byte 195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149 +.byte 236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223 +.byte 219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77 +.byte 161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192 +.byte 141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145 +.byte 61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200 +.byte 151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91 +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249 +.byte 43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110 +.byte 118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225 +.byte 130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230 +.byte 214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40 +.byte 27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195 +.byte 181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116 +.byte 175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190 +.byte 106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29 +.byte 80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234 +.byte 69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87 +.byte 243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56 +.byte 48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173 +.byte 239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196 +.byte 63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218 +.byte 85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199 +.byte 162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219 +.byte 234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233 +.byte 101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106 +.byte 186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3 +.byte 47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74 +.byte 192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142 +.byte 222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96 +.byte 28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252 +.byte 253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70 +.byte 77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31 +.byte 146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118 +.byte 117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250 +.byte 6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54 +.byte 138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174 +.byte 178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75 +.byte 230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133 +.byte 14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126 +.byte 31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231 +.byte 98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85 +.byte 212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58 +.byte 168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129 +.byte 150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82 +.byte 249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98 +.byte 197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163 +.byte 37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16 +.byte 89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171 +.byte 132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208 +.byte 114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197 +.byte 57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236 +.byte 76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22 +.byte 94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148 +.byte 120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159 +.byte 56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229 +.byte 140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152 +.byte 209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23 +.byte 165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228 +.byte 226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161 +.byte 97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78 +.byte 179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66 +.byte 33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52 +.byte 156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8 +.byte 30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238 +.byte 67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97 +.byte 199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177 +.byte 252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79 +.byte 4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36 +.byte 81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227 +.byte 153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37 +.byte 109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34 +.byte 13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101 +.byte 250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121 +.byte 223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105 +.byte 126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169 +.byte 36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25 +.byte 59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254 +.byte 171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154 +.byte 206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240 +.byte 17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153 +.byte 143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131 +.byte 78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4 +.byte 183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102 +.byte 235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224 +.byte 60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193 +.byte 129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253 +.byte 148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64 +.byte 247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28 +.byte 185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24 +.byte 19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139 +.byte 44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81 +.byte 211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5 +.byte 231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140 +.byte 110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57 +.byte 196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170 +.byte 3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27 +.byte 86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220 +.byte 68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94 +.byte 127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160 +.byte 169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136 +.byte 42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103 +.byte 187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10 +.byte 193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135 +.byte 83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241 +.byte 220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114 +.byte 11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83 +.byte 157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1 +.byte 108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43 +.byte 49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164 +.byte 116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243 +.byte 246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21 +.byte 70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76 +.byte 172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165 +.byte 137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181 +.byte 20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180 +.byte 225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186 +.byte 22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166 +.byte 58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247 +.byte 105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6 +.byte 9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65 +.byte 112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215 +.byte 182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111 +.byte 208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30 +.byte 237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214 +.byte 204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226 +.byte 66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104 +.byte 152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44 +.byte 164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237 +.byte 40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117 +.byte 92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134 +.byte 248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107 +.byte 134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194 +.byte 24,35,198,232,135,184,1,79 +.byte 54,166,210,245,121,111,145,82 +.byte 96,188,155,142,163,12,123,53 +.byte 29,224,215,194,46,75,254,87 +.byte 21,119,55,229,159,240,74,218 +.byte 88,201,41,10,177,160,107,133 +.byte 189,93,16,244,203,62,5,103 +.byte 228,39,65,139,167,125,149,216 +.byte 251,238,124,102,221,23,71,158 +.byte 202,45,191,7,173,90,131,51 diff --git a/Libraries/libressl/crypto/whrlpool/wp_block.c b/Libraries/libressl/crypto/whrlpool/wp_block.c new file mode 100644 index 000000000..ad814a346 --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp_block.c @@ -0,0 +1,629 @@ +/* $OpenBSD: wp_block.c,v 1.15 2022/11/26 16:08:54 tb Exp $ */ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include "wp_local.h" + +typedef unsigned char u8; +#if defined(_LP64) +typedef unsigned long u64; +#else +typedef unsigned long long u64; +#endif + +#define ROUNDS 10 + +#undef SMALL_REGISTER_BANK +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define SMALL_REGISTER_BANK +# if defined(WHIRLPOOL_ASM) +# ifndef OPENSSL_SMALL_FOOTPRINT +# define OPENSSL_SMALL_FOOTPRINT /* it appears that for elder non-MMX + CPUs this is actually faster! */ +# endif +#include "x86_arch.h" +# define GO_FOR_MMX(ctx,inp,num) \ +do { \ + void whirlpool_block_mmx(void *,const void *,size_t); \ + if ((OPENSSL_cpu_caps() & CPUCAP_MASK_MMX) == 0) \ + break; \ + whirlpool_block_mmx(ctx->H.c,inp,num); \ + return; \ +} while (0) +# endif +#elif defined(__arm__) +# define SMALL_REGISTER_BANK +#endif + +#undef ROTATE +#if defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# endif +#endif + +#if defined(OPENSSL_SMALL_FOOTPRINT) +# if !defined(ROTATE) +# if BYTE_ORDER == LITTLE_ENDIAN /* little-endians have to rotate left */ +# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) +# else /* big-endians have to rotate right */ +# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) +# endif +# endif +# if defined(ROTATE) && !defined(__STRICT_ALIGNMENT) +# define __STRICT_ALIGNMENT /* ensure smallest table size */ +# endif +#endif + +/* + * Table size depends on __STRICT_ALIGNMENT and whether or not endian- + * specific ROTATE macro is defined. If __STRICT_ALIGNMENT is not + * defined, which is normally the case on x86[_64] CPUs, the table is + * 4KB large unconditionally. Otherwise if ROTATE is defined, the + * table is 2KB large, and otherwise - 16KB. 2KB table requires a + * whole bunch of additional rotations, but I'm willing to "trade," + * because 16KB table certainly trashes L1 cache. I wish all CPUs + * could handle unaligned load as 4KB table doesn't trash the cache, + * nor does it require additional rotations. + */ +/* + * Note that every Cn macro expands as two loads: one byte load and + * one quadword load. One can argue that that many single-byte loads + * is too excessive, as one could load a quadword and "milk" it for + * eight 8-bit values instead. Well, yes, but in order to do so *and* + * avoid excessive loads you have to accommodate a handful of 64-bit + * values in the register bank and issue a bunch of shifts and mask. + * It's a tradeoff: loads vs. shift and mask in big register bank[!]. + * On most CPUs eight single-byte loads are faster and I let other + * ones to depend on smart compiler to fold byte loads if beneficial. + * Hand-coded assembler would be another alternative:-) + */ +#ifdef __STRICT_ALIGNMENT +# if defined(ROTATE) +# define N 1 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) +# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) +# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) +# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) +# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) +# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) +# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) +# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) +# else +# define N 8 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c7,c0,c1,c2,c3,c4,c5,c6, \ + c6,c7,c0,c1,c2,c3,c4,c5, \ + c5,c6,c7,c0,c1,c2,c3,c4, \ + c4,c5,c6,c7,c0,c1,c2,c3, \ + c3,c4,c5,c6,c7,c0,c1,c2, \ + c2,c3,c4,c5,c6,c7,c0,c1, \ + c1,c2,c3,c4,c5,c6,c7,c0 +# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) +# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) +# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) +# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) +# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) +# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) +# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) +# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) +# endif +#else +# define N 2 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) +# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) +# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) +# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) +# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) +# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) +# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) +# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) +#endif + +static const +union { + u8 c[(256*N+ROUNDS)*sizeof(u64)]; + u64 q[(256*N+ROUNDS)]; + } Cx = { { + /* Note endian-neutral representation:-) */ + LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8), + LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26), + LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8), + LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb), + LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb), + LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11), + LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09), + LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d), + LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b), + LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff), + LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c), + LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e), + LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96), + LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30), + LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d), + LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8), + LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47), + LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35), + LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37), + LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a), + LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2), + LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c), + LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84), + LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80), + LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5), + LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3), + LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21), + LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c), + LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43), + LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29), + LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d), + LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5), + LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd), + LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8), + LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92), + LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e), + LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13), + LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23), + LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20), + LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44), + LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2), + LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf), + LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c), + LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a), + LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50), + LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9), + LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14), + LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9), + LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c), + LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f), + LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90), + LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07), + LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd), + LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3), + LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d), + LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78), + LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97), + LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02), + LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73), + LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7), + LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6), + LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2), + LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49), + LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56), + LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70), + LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd), + LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb), + LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71), + LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b), + LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf), + LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45), + LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a), + LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4), + LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58), + LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e), + LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f), + LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac), + LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0), + LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef), + LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6), + LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c), + LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12), + LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93), + LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde), + LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6), + LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1), + LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b), + LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f), + LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31), + LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8), + LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9), + LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc), + LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e), + LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b), + LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf), + LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59), + LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2), + LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77), + LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33), + LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4), + LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27), + LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb), + LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89), + LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32), + LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54), + LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d), + LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64), + LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d), + LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d), + LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f), + LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca), + LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7), + LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d), + LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce), + LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f), + LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f), + LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63), + LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a), + LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc), + LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82), + LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a), + LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48), + LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95), + LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf), + LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d), + LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0), + LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91), + LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8), + LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b), + LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00), + LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9), + LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e), + LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1), + LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6), + LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28), + LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3), + LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74), + LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe), + LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d), + LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea), + LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57), + LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38), + LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad), + LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4), + LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda), + LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7), + LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb), + LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9), + LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a), + LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03), + LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a), + LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e), + LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60), + LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc), + LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46), + LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f), + LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76), + LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa), + LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36), + LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae), + LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b), + LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85), + LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e), + LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7), + LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55), + LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a), + LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81), + LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52), + LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62), + LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3), + LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10), + LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab), + LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0), + LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5), + LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec), + LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16), + LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94), + LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f), + LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5), + LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98), + LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17), + LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4), + LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1), + LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e), + LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42), + LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34), + LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08), + LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee), + LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61), + LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1), + LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f), + LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24), + LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3), + LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25), + LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22), + LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65), + LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79), + LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69), + LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9), + LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19), + LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe), + LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a), + LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0), + LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99), + LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83), + LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04), + LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66), + LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0), + LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1), + LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd), + LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40), + LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c), + LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18), + LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b), + LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51), + LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05), + LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c), + LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39), + LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa), + LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b), + LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc), + LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e), + LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0), + LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88), + LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67), + LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a), + LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87), + LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1), + LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72), + LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53), + LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01), + LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b), + LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4), + LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3), + LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15), + LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c), + LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5), + LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5), + LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4), + LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba), + LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6), + LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7), + LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06), + LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41), + LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7), + LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f), + LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e), + LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6), + LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2), + LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68), + LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c), + LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed), + LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75), + LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86), + LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b), + LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2), +#define RC (&(Cx.q[256*N])) + 0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f, /* rc[ROUNDS] */ + 0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52, + 0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35, + 0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57, + 0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda, + 0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85, + 0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67, + 0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8, + 0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e, + 0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33 + } +}; + +void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n) + { + int r; + const u8 *p=inp; + union { u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q; + +#ifdef GO_FOR_MMX + GO_FOR_MMX(ctx,inp,n); +#endif + do { +#ifdef OPENSSL_SMALL_FOOTPRINT + u64 L[8]; + int i; + + for (i=0;i<64;i++) S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; + for (r=0;rc[i] ^= S.c[i] ^ p[i]; +#else + u64 L0,L1,L2,L3,L4,L5,L6,L7; + +#ifdef __STRICT_ALIGNMENT + if ((size_t)p & 7) + { + memcpy (S.c,p,64); + S.q[0] ^= (K.q[0] = H->q[0]); + S.q[1] ^= (K.q[1] = H->q[1]); + S.q[2] ^= (K.q[2] = H->q[2]); + S.q[3] ^= (K.q[3] = H->q[3]); + S.q[4] ^= (K.q[4] = H->q[4]); + S.q[5] ^= (K.q[5] = H->q[5]); + S.q[6] ^= (K.q[6] = H->q[6]); + S.q[7] ^= (K.q[7] = H->q[7]); + } + else +#endif + { + const u64 *pa = (const u64*)p; + S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; + S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; + S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; + S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; + S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; + S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; + S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; + S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; + } + + for(r=0;rc[i] ^= S.c[i] ^ p[i]; + } + else +#endif + { + const u64 *pa=(const u64 *)p; + H->q[0] ^= S.q[0] ^ pa[0]; + H->q[1] ^= S.q[1] ^ pa[1]; + H->q[2] ^= S.q[2] ^ pa[2]; + H->q[3] ^= S.q[3] ^ pa[3]; + H->q[4] ^= S.q[4] ^ pa[4]; + H->q[5] ^= S.q[5] ^ pa[5]; + H->q[6] ^= S.q[6] ^ pa[6]; + H->q[7] ^= S.q[7] ^ pa[7]; + } +#endif + p += 64; + } while(--n); + } diff --git a/Libraries/libressl/crypto/whrlpool/wp_dgst.c b/Libraries/libressl/crypto/whrlpool/wp_dgst.c new file mode 100644 index 000000000..71fd79c84 --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp_dgst.c @@ -0,0 +1,268 @@ +/* $OpenBSD: wp_dgst.c,v 1.7 2023/09/04 08:43:41 tb Exp $ */ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * OpenSSL-specific implementation notes. + * + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect + * number of *bytes* as input length argument. Bit-oriented routine + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and + * does not have one-stroke counterpart. + * + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially + * to serve WHIRLPOOL_Update. This is done for performance. + * + * Unlike authors' reference implementation, block processing + * routine whirlpool_block is designed to operate on multi-block + * input. This is done for performance. + */ + +#include + +#include + +#include "wp_local.h" + +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c) + { + memset (c,0,sizeof(*c)); + return(1); + } + +int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *_inp,size_t bytes) + { + /* Well, largest suitable chunk size actually is + * (1<<(sizeof(size_t)*8-3))-64, but below number + * is large enough for not to care about excessive + * calls to WHIRLPOOL_BitUpdate... */ + size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4); + const unsigned char *inp = _inp; + + while (bytes>=chunk) + { + WHIRLPOOL_BitUpdate(c,inp,chunk*8); + bytes -= chunk; + inp += chunk; + } + if (bytes) + WHIRLPOOL_BitUpdate(c,inp,bytes*8); + + return(1); + } + +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits) + { + size_t n; + unsigned int bitoff = c->bitoff, + bitrem = bitoff%8, + inpgap = (8-(unsigned int)bits%8)&7; + const unsigned char *inp=_inp; + + /* This 256-bit increment procedure relies on the size_t + * being natural size of CPU register, so that we don't + * have to mask the value in order to detect overflows. */ + c->bitlen[0] += bits; + if (c->bitlen[0] < bits) /* overflow */ + { + n = 1; + do { c->bitlen[n]++; + } while(c->bitlen[n]==0 + && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t))); + } + +#ifndef OPENSSL_SMALL_FOOTPRINT + reconsider: + if (inpgap==0 && bitrem==0) /* byte-oriented loop */ + { + while (bits) + { + if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK)) + { + whirlpool_block(c,inp,n); + inp += n*WHIRLPOOL_BBLOCK/8; + bits %= WHIRLPOOL_BBLOCK; + } + else + { + unsigned int byteoff = bitoff/8; + + bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */ + if (bits >= bitrem) + { + bits -= bitrem; + bitrem /= 8; + memcpy(c->data+byteoff,inp,bitrem); + inp += bitrem; + whirlpool_block(c,c->data,1); + bitoff = 0; + } + else + { + memcpy(c->data+byteoff,inp,bits/8); + bitoff += (unsigned int)bits; + bits = 0; + } + c->bitoff = bitoff; + } + } + } + else /* bit-oriented loop */ +#endif + { + /* + inp + | + +-------+-------+------- + ||||||||||||||||||||| + +-------+-------+------- + +-------+-------+-------+-------+------- + |||||||||||||| c->data + +-------+-------+-------+-------+------- + | + c->bitoff/8 + */ + while (bits) + { + unsigned int byteoff = bitoff/8; + unsigned char b; + +#ifndef OPENSSL_SMALL_FOOTPRINT + if (bitrem==inpgap) + { + c->data[byteoff++] |= inp[0] & (0xff>>inpgap); + inpgap = 8-inpgap; + bitoff += inpgap; bitrem = 0; /* bitoff%8 */ + bits -= inpgap; inpgap = 0; /* bits%8 */ + inp++; + if (bitoff==WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + bitoff = 0; + } + c->bitoff = bitoff; + goto reconsider; + } + else +#endif + if (bits>=8) + { + b = ((inp[0]<>(8-inpgap))); + b &= 0xff; + if (bitrem) c->data[byteoff++] |= b>>bitrem; + else c->data[byteoff++] = b; + bitoff += 8; + bits -= 8; + inp++; + if (bitoff>=WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) c->data[byteoff] = b<<(8-bitrem); + } + else /* remaining less than 8 bits */ + { + b = (inp[0]<data[byteoff++] |= b>>bitrem; + else c->data[byteoff++] = b; + bitoff += (unsigned int)bits; + if (bitoff==WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) c->data[byteoff] = b<<(8-bitrem); + bits = 0; + } + c->bitoff = bitoff; + } + } + } + +int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c) + { + unsigned int bitoff = c->bitoff, + byteoff = bitoff/8; + size_t i,j,v; + unsigned char *p; + + bitoff %= 8; + if (bitoff) c->data[byteoff] |= 0x80>>bitoff; + else c->data[byteoff] = 0x80; + byteoff++; + + /* pad with zeros */ + if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) + { + if (byteoffdata[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff); + whirlpool_block(c,c->data,1); + byteoff = 0; + } + if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) + memset(&c->data[byteoff],0, + (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff); + /* smash 256-bit c->bitlen in big-endian order */ + p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */ + for(i=0;ibitlen[i],j=0;j>=8) + *p-- = (unsigned char)(v&0xff); + + whirlpool_block(c,c->data,1); + + if (md) { + memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH); + memset(c,0,sizeof(*c)); + return(1); + } + return(0); + } + +unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md) + { + WHIRLPOOL_CTX ctx; + static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; + + if (md == NULL) md=m; + WHIRLPOOL_Init(&ctx); + WHIRLPOOL_Update(&ctx,inp,bytes); + WHIRLPOOL_Final(md,&ctx); + return(md); + } diff --git a/Libraries/libressl/crypto/whrlpool/wp_local.h b/Libraries/libressl/crypto/whrlpool/wp_local.h new file mode 100644 index 000000000..892dce23b --- /dev/null +++ b/Libraries/libressl/crypto/whrlpool/wp_local.h @@ -0,0 +1,11 @@ +/* $OpenBSD: wp_local.h,v 1.2 2023/09/04 08:43:41 tb Exp $ */ + +#include + +#include + +__BEGIN_HIDDEN_DECLS + +void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t); + +__END_HIDDEN_DECLS diff --git a/Libraries/libressl/crypto/x509/by_dir.c b/Libraries/libressl/crypto/x509/by_dir.c new file mode 100644 index 000000000..9fa6a1004 --- /dev/null +++ b/Libraries/libressl/crypto/x509/by_dir.c @@ -0,0 +1,413 @@ +/* $OpenBSD: by_dir.c,v 1.44 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "x509_local.h" + +typedef struct lookup_dir_hashes_st { + unsigned long hash; + int suffix; +} BY_DIR_HASH; + +typedef struct lookup_dir_entry_st { + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; +} BY_DIR_ENTRY; + +typedef struct lookup_dir_st { + BUF_MEM *buffer; + STACK_OF(BY_DIR_ENTRY) *dirs; +} BY_DIR; + +DECLARE_STACK_OF(BY_DIR_HASH) +DECLARE_STACK_OF(BY_DIR_ENTRY) + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret); +static int new_dir(X509_LOOKUP *lu); +static void free_dir(X509_LOOKUP *lu); +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret); + +static X509_LOOKUP_METHOD x509_dir_lookup = { + .name = "Load certs from files in a directory", + .new_item = new_dir, + .free = free_dir, + .init = NULL, + .shutdown = NULL, + .ctrl = dir_ctrl, + .get_by_subject = get_cert_by_subject, + .get_by_issuer_serial = NULL, + .get_by_fingerprint = NULL, + .get_by_alias = NULL, +}; + +X509_LOOKUP_METHOD * +X509_LOOKUP_hash_dir(void) +{ + return &x509_dir_lookup; +} +LCRYPTO_ALIAS(X509_LOOKUP_hash_dir); + +static int +dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **retp) +{ + int ret = 0; + BY_DIR *ld; + + ld = (BY_DIR *)ctx->method_data; + + switch (cmd) { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) { + ret = add_cert_dir(ld, X509_get_default_cert_dir(), + X509_FILETYPE_PEM); + if (!ret) { + X509error(X509_R_LOADING_CERT_DIR); + } + } else + ret = add_cert_dir(ld, argp, (int)argl); + break; + } + return ret; +} + +static int +new_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + if ((a = malloc(sizeof(*a))) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + if ((a->buffer = BUF_MEM_new()) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + free(a); + return 0; + } + a->dirs = NULL; + lu->method_data = (char *)a; + return 1; +} + +static void +by_dir_hash_free(BY_DIR_HASH *hash) +{ + free(hash); +} + +static int +by_dir_hash_cmp(const BY_DIR_HASH * const *a, + const BY_DIR_HASH * const *b) +{ + if ((*a)->hash > (*b)->hash) + return 1; + if ((*a)->hash < (*b)->hash) + return -1; + return 0; +} + +static void +by_dir_entry_free(BY_DIR_ENTRY *ent) +{ + free(ent->dir); + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + free(ent); +} + +static void +free_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + a = (BY_DIR *)lu->method_data; + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + BUF_MEM_free(a->buffer); + free(a); +} + +static int +add_cert_dir(BY_DIR *ctx, const char *dir, int type) +{ + int j; + const char *s, *ss, *p; + ptrdiff_t len; + + if (dir == NULL || !*dir) { + X509error(X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == ':') || (*p == '\0')) { + BY_DIR_ENTRY *ent; + + ss = s; + s = p + 1; + len = p - ss; + if (len == 0) + continue; + for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == (size_t)len && + strncmp(ent->dir, ss, (size_t)len) == 0) + break; + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) + continue; + if (ctx->dirs == NULL) { + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (ctx->dirs == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + } + ent = malloc(sizeof(*ent)); + if (ent == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = strndup(ss, (size_t)len); + if (ent->dir == NULL || ent->hashes == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + by_dir_entry_free(ent); + return 0; + } + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + X509error(ERR_R_MALLOC_FAILURE); + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +static int +get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + BY_DIR *ctx; + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok = 0; + int i, j, k; + unsigned long h; + BUF_MEM *b = NULL; + X509_OBJECT stmp, *tmp; + const char *postfix=""; + + if (name == NULL) + return 0; + + stmp.type = type; + if (type == X509_LU_X509) { + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject = name; + stmp.data.x509 = &data.x509.st_x509; + postfix=""; + } else if (type == X509_LU_CRL) { + data.crl.st_crl.crl = &data.crl.st_crl_info; + data.crl.st_crl_info.issuer = name; + stmp.data.crl = &data.crl.st_crl; + postfix="r"; + } else { + X509error(X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + X509error(ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + h = X509_NAME_hash(name); + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + int idx; + BY_DIR_HASH htmp, *hent; + + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; + if (!BUF_MEM_grow(b, j)) { + X509error(ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL) { + htmp.hash = h; + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + } else { + k = 0; + hent = NULL; + } + for (;;) { + (void) snprintf(b->data, b->max, "%s/%08lx.%s%d", + ent->dir, h, postfix, k); + + { + struct stat st; + if (stat(b->data, &st) < 0) + break; + } + /* found one. */ + if (type == X509_LU_X509) { + if ((X509_load_cert_file(xl, b->data, + ent->dir_type)) == 0) + break; + } else if (type == X509_LU_CRL) { + if ((X509_load_crl_file(xl, b->data, + ent->dir_type)) == 0) + break; + } + /* else case will caught higher up */ + k++; + } + + /* we have added it to the cache so now pull it out again */ + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + /* If a CRL, update the last file suffix added for this */ + if (type == X509_LU_CRL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* + * Look for entry again in case another thread added + * an entry first. + */ + if (hent == NULL) { + htmp.hash = h; + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (hent == NULL) { + hent = malloc(sizeof(*hent)); + if (hent == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + ok = 0; + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + X509error(ERR_R_MALLOC_FAILURE); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + free(hent); + ok = 0; + goto finish; + } + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + goto finish; + } + } +finish: + BUF_MEM_free(b); + return ok; +} diff --git a/Libraries/libressl/crypto/x509/by_file.c b/Libraries/libressl/crypto/x509/by_file.c new file mode 100644 index 000000000..606f4c8d0 --- /dev/null +++ b/Libraries/libressl/crypto/x509/by_file.c @@ -0,0 +1,273 @@ +/* $OpenBSD: by_file.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "x509_local.h" + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +static X509_LOOKUP_METHOD x509_file_lookup = { + .name = "Load file into cache", + .new_item = NULL, + .free = NULL, + .init = NULL, + .shutdown = NULL, + .ctrl = by_file_ctrl, + .get_by_subject = NULL, + .get_by_issuer_serial = NULL, + .get_by_fingerprint = NULL, + .get_by_alias = NULL, +}; + +X509_LOOKUP_METHOD * +X509_LOOKUP_file(void) +{ + return &x509_file_lookup; +} +LCRYPTO_ALIAS(X509_LOOKUP_file); + +static int +by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret) +{ + int ok = 0; + + switch (cmd) { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) { + ok = (X509_load_cert_crl_file(ctx, + X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + if (!ok) { + X509error(X509_R_LOADING_DEFAULTS); + } + } else { + if (argl == X509_FILETYPE_PEM) + ok = (X509_load_cert_crl_file(ctx, argp, + X509_FILETYPE_PEM) != 0); + else + ok = (X509_load_cert_file(ctx, + argp, (int)argl) != 0); + } + break; + } + return ok; +} + +int +X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509error(ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509error(ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_bio(in, NULL); + if (x == NULL) { + X509error(ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509error(X509_R_BAD_X509_FILETYPE); + goto err; + } +err: + X509_free(x); + BIO_free(in); + return ret; +} +LCRYPTO_ALIAS(X509_load_cert_file); + +int +X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509_CRL *x = NULL; + + in = BIO_new(BIO_s_file()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509error(ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509error(ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_CRL_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + if (x == NULL) { + X509error(ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509error(X509_R_BAD_X509_FILETYPE); + goto err; + } +err: + X509_CRL_free(x); + BIO_free(in); + return ret; +} +LCRYPTO_ALIAS(X509_load_crl_file); + +int +X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + int i, count = 0; + + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + X509error(ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); + BIO_free(in); + if (!inf) { + X509error(ERR_R_PEM_LIB); + return 0; + } + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + X509_STORE_add_cert(ctx->store_ctx, itmp->x509); + count++; + } + if (itmp->crl) { + X509_STORE_add_crl(ctx->store_ctx, itmp->crl); + count++; + } + } + if (count == 0) + X509error(X509_R_NO_CERTIFICATE_OR_CRL_FOUND); + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} +LCRYPTO_ALIAS(X509_load_cert_crl_file); diff --git a/Libraries/libressl/crypto/x509/by_mem.c b/Libraries/libressl/crypto/x509/by_mem.c new file mode 100644 index 000000000..579eecd36 --- /dev/null +++ b/Libraries/libressl/crypto/x509/by_mem.c @@ -0,0 +1,141 @@ +/* $OpenBSD: by_mem.c,v 1.8 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "x509_local.h" + +static int by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **); + +static X509_LOOKUP_METHOD x509_mem_lookup = { + .name = "Load cert from memory", + .new_item = NULL, + .free = NULL, + .init = NULL, + .shutdown = NULL, + .ctrl = by_mem_ctrl, + .get_by_subject = NULL, + .get_by_issuer_serial = NULL, + .get_by_fingerprint = NULL, + .get_by_alias = NULL, +}; + +X509_LOOKUP_METHOD * +X509_LOOKUP_mem(void) +{ + return (&x509_mem_lookup); +} +LCRYPTO_ALIAS(X509_LOOKUP_mem); + +static int +by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf, + long type, char **ret) +{ + STACK_OF(X509_INFO) *inf = NULL; + const struct iovec *iov; + X509_INFO *itmp; + BIO *in = NULL; + int i, count = 0, ok = 0; + + iov = (const struct iovec *)buf; + + if (!(cmd == X509_L_MEM && type == X509_FILETYPE_PEM)) + goto done; + + if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL) + goto done; + + if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) + goto done; + + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + ok = X509_STORE_add_cert(lu->store_ctx, itmp->x509); + if (!ok) + goto done; + count++; + } + if (itmp->crl) { + ok = X509_STORE_add_crl(lu->store_ctx, itmp->crl); + if (!ok) + goto done; + count++; + } + } + + ok = count != 0; + done: + if (count == 0) + X509error(ERR_R_PEM_LIB); + if (inf != NULL) + sk_X509_INFO_pop_free(inf, X509_INFO_free); + if (in != NULL) + BIO_free(in); + return (ok); +} diff --git a/Libraries/libressl/crypto/x509/x509_addr.c b/Libraries/libressl/crypto/x509/x509_addr.c new file mode 100644 index 000000000..5e4223ce2 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_addr.c @@ -0,0 +1,2061 @@ +/* $OpenBSD: x509_addr.c,v 1.90 2023/09/27 11:29:22 tb Exp $ */ +/* + * Contributed to the OpenSSL Project by the American Registry for + * Internet Numbers ("ARIN"). + */ +/* ==================================================================== + * Copyright (c) 2006-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +/* + * Implementation of RFC 3779 section 2.2. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "bytestring.h" +#include "x509_local.h" + +#ifndef OPENSSL_NO_RFC3779 + +/* + * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. + */ + +static const ASN1_TEMPLATE IPAddressRange_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressRange, min), + .field_name = "min", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressRange, max), + .field_name = "max", + .item = &ASN1_BIT_STRING_it, + }, +}; + +const ASN1_ITEM IPAddressRange_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = IPAddressRange_seq_tt, + .tcount = sizeof(IPAddressRange_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(IPAddressRange), + .sname = "IPAddressRange", +}; + +static const ASN1_TEMPLATE IPAddressOrRange_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressOrRange, u.addressPrefix), + .field_name = "u.addressPrefix", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressOrRange, u.addressRange), + .field_name = "u.addressRange", + .item = &IPAddressRange_it, + }, +}; + +const ASN1_ITEM IPAddressOrRange_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(IPAddressOrRange, type), + .templates = IPAddressOrRange_ch_tt, + .tcount = sizeof(IPAddressOrRange_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(IPAddressOrRange), + .sname = "IPAddressOrRange", +}; + +static const ASN1_TEMPLATE IPAddressChoice_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressChoice, u.inherit), + .field_name = "u.inherit", + .item = &ASN1_NULL_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(IPAddressChoice, u.addressesOrRanges), + .field_name = "u.addressesOrRanges", + .item = &IPAddressOrRange_it, + }, +}; + +const ASN1_ITEM IPAddressChoice_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(IPAddressChoice, type), + .templates = IPAddressChoice_ch_tt, + .tcount = sizeof(IPAddressChoice_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(IPAddressChoice), + .sname = "IPAddressChoice", +}; + +static const ASN1_TEMPLATE IPAddressFamily_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressFamily, addressFamily), + .field_name = "addressFamily", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(IPAddressFamily, ipAddressChoice), + .field_name = "ipAddressChoice", + .item = &IPAddressChoice_it, + }, +}; + +const ASN1_ITEM IPAddressFamily_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = IPAddressFamily_seq_tt, + .tcount = sizeof(IPAddressFamily_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(IPAddressFamily), + .sname = "IPAddressFamily", +}; + +static const ASN1_TEMPLATE IPAddrBlocks_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "IPAddrBlocks", + .item = &IPAddressFamily_it, +}; + +static const ASN1_ITEM IPAddrBlocks_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &IPAddrBlocks_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "IPAddrBlocks", +}; + +IPAddressRange * +d2i_IPAddressRange(IPAddressRange **a, const unsigned char **in, long len) +{ + return (IPAddressRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &IPAddressRange_it); +} +LCRYPTO_ALIAS(d2i_IPAddressRange); + +int +i2d_IPAddressRange(IPAddressRange *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressRange_it); +} +LCRYPTO_ALIAS(i2d_IPAddressRange); + +IPAddressRange * +IPAddressRange_new(void) +{ + return (IPAddressRange *)ASN1_item_new(&IPAddressRange_it); +} +LCRYPTO_ALIAS(IPAddressRange_new); + +void +IPAddressRange_free(IPAddressRange *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &IPAddressRange_it); +} +LCRYPTO_ALIAS(IPAddressRange_free); + +IPAddressOrRange * +d2i_IPAddressOrRange(IPAddressOrRange **a, const unsigned char **in, long len) +{ + return (IPAddressOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &IPAddressOrRange_it); +} +LCRYPTO_ALIAS(d2i_IPAddressOrRange); + +int +i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressOrRange_it); +} +LCRYPTO_ALIAS(i2d_IPAddressOrRange); + +IPAddressOrRange * +IPAddressOrRange_new(void) +{ + return (IPAddressOrRange *)ASN1_item_new(&IPAddressOrRange_it); +} +LCRYPTO_ALIAS(IPAddressOrRange_new); + +void +IPAddressOrRange_free(IPAddressOrRange *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &IPAddressOrRange_it); +} +LCRYPTO_ALIAS(IPAddressOrRange_free); + +IPAddressChoice * +d2i_IPAddressChoice(IPAddressChoice **a, const unsigned char **in, long len) +{ + return (IPAddressChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &IPAddressChoice_it); +} +LCRYPTO_ALIAS(d2i_IPAddressChoice); + +int +i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressChoice_it); +} +LCRYPTO_ALIAS(i2d_IPAddressChoice); + +IPAddressChoice * +IPAddressChoice_new(void) +{ + return (IPAddressChoice *)ASN1_item_new(&IPAddressChoice_it); +} +LCRYPTO_ALIAS(IPAddressChoice_new); + +void +IPAddressChoice_free(IPAddressChoice *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &IPAddressChoice_it); +} +LCRYPTO_ALIAS(IPAddressChoice_free); + +IPAddressFamily * +d2i_IPAddressFamily(IPAddressFamily **a, const unsigned char **in, long len) +{ + return (IPAddressFamily *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &IPAddressFamily_it); +} +LCRYPTO_ALIAS(d2i_IPAddressFamily); + +int +i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressFamily_it); +} +LCRYPTO_ALIAS(i2d_IPAddressFamily); + +IPAddressFamily * +IPAddressFamily_new(void) +{ + return (IPAddressFamily *)ASN1_item_new(&IPAddressFamily_it); +} +LCRYPTO_ALIAS(IPAddressFamily_new); + +void +IPAddressFamily_free(IPAddressFamily *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &IPAddressFamily_it); +} +LCRYPTO_ALIAS(IPAddressFamily_free); + +/* + * Convenience accessors for IPAddressFamily. + */ + +static int +IPAddressFamily_type(IPAddressFamily *af) +{ + /* XXX - can af->ipAddressChoice == NULL actually happen? */ + if (af == NULL || af->ipAddressChoice == NULL) + return -1; + + switch (af->ipAddressChoice->type) { + case IPAddressChoice_inherit: + case IPAddressChoice_addressesOrRanges: + return af->ipAddressChoice->type; + default: + return -1; + } +} + +static IPAddressOrRanges * +IPAddressFamily_addressesOrRanges(IPAddressFamily *af) +{ + if (IPAddressFamily_type(af) == IPAddressChoice_addressesOrRanges) + return af->ipAddressChoice->u.addressesOrRanges; + + return NULL; +} + +static ASN1_NULL * +IPAddressFamily_inheritance(IPAddressFamily *af) +{ + if (IPAddressFamily_type(af) == IPAddressChoice_inherit) + return af->ipAddressChoice->u.inherit; + + return NULL; +} + +static int +IPAddressFamily_set_inheritance(IPAddressFamily *af) +{ + if (IPAddressFamily_addressesOrRanges(af) != NULL) + return 0; + + if (IPAddressFamily_inheritance(af) != NULL) + return 1; + + if ((af->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + af->ipAddressChoice->type = IPAddressChoice_inherit; + + return 1; +} + +/* + * How much buffer space do we need for a raw address? + */ +#define ADDR_RAW_BUF_LEN 16 + +/* + * What's the address length associated with this AFI? + */ +static int +length_from_afi(const unsigned afi, int *length) +{ + switch (afi) { + case IANA_AFI_IPV4: + *length = 4; + return 1; + case IANA_AFI_IPV6: + *length = 16; + return 1; + default: + *length = 0; + return 0; + } +} + +/* + * Get AFI and optional SAFI from an IPAddressFamily. All three out arguments + * are optional; if |out_safi| is non-NULL, |safi_is_set| must be non-NULL. + */ +static int +IPAddressFamily_afi_safi(const IPAddressFamily *af, uint16_t *out_afi, + uint8_t *out_safi, int *safi_is_set) +{ + CBS cbs; + uint16_t afi; + uint8_t safi = 0; + int got_safi = 0; + + if (out_afi != NULL) + *out_afi = 0; + if (out_safi != NULL) { + *out_safi = 0; + *safi_is_set = 0; + } + + CBS_init(&cbs, af->addressFamily->data, af->addressFamily->length); + + if (!CBS_get_u16(&cbs, &afi)) + return 0; + + if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6) + return 0; + + /* Fetch the optional SAFI. */ + if (CBS_len(&cbs) != 0) { + if (!CBS_get_u8(&cbs, &safi)) + return 0; + got_safi = 1; + } + + /* If there's anything left, it's garbage. */ + if (CBS_len(&cbs) != 0) + return 0; + + /* XXX - error on reserved AFI/SAFI? */ + + if (out_afi != NULL) + *out_afi = afi; + + if (out_safi != NULL) { + *out_safi = safi; + *safi_is_set = got_safi; + } + + return 1; +} + +static int +IPAddressFamily_afi(const IPAddressFamily *af, uint16_t *out_afi) +{ + return IPAddressFamily_afi_safi(af, out_afi, NULL, NULL); +} + +static int +IPAddressFamily_afi_is_valid(const IPAddressFamily *af) +{ + return IPAddressFamily_afi_safi(af, NULL, NULL, NULL); +} + +static int +IPAddressFamily_afi_length(const IPAddressFamily *af, int *out_length) +{ + uint16_t afi; + + *out_length = 0; + + if (!IPAddressFamily_afi(af, &afi)) + return 0; + + return length_from_afi(afi, out_length); +} + +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +/* + * Sort comparison function for a sequence of IPAddressFamily. + * + * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about + * the ordering: I can read it as meaning that IPv6 without a SAFI + * comes before IPv4 with a SAFI, which seems pretty weird. The + * examples in appendix B suggest that the author intended the + * null-SAFI rule to apply only within a single AFI, which is what I + * would have expected and is what the following code implements. + */ +static int +IPAddressFamily_cmp(const IPAddressFamily *const *a_, + const IPAddressFamily *const *b_) +{ + const ASN1_OCTET_STRING *a = (*a_)->addressFamily; + const ASN1_OCTET_STRING *b = (*b_)->addressFamily; + int len, cmp; + + len = MINIMUM(a->length, b->length); + + if ((cmp = memcmp(a->data, b->data, len)) != 0) + return cmp; + + return a->length - b->length; +} + +static IPAddressFamily * +IPAddressFamily_find_in_parent(IPAddrBlocks *parent, IPAddressFamily *child_af) +{ + int index; + + (void)sk_IPAddressFamily_set_cmp_func(parent, IPAddressFamily_cmp); + + if ((index = sk_IPAddressFamily_find(parent, child_af)) < 0) + return NULL; + + return sk_IPAddressFamily_value(parent, index); +} + +/* + * Extract the AFI from an IPAddressFamily. + * + * This is public API. It uses the reserved AFI 0 as an in-band error + * while it doesn't care about the reserved AFI 65535... + */ +unsigned int +X509v3_addr_get_afi(const IPAddressFamily *af) +{ + uint16_t afi; + + /* + * XXX are these NULL checks really sensible? If af is non-NULL, it + * should have both addressFamily and ipAddressChoice... + */ + if (af == NULL || af->addressFamily == NULL || + af->addressFamily->data == NULL) + return 0; + + if (!IPAddressFamily_afi(af, &afi)) + return 0; + + return afi; +} +LCRYPTO_ALIAS(X509v3_addr_get_afi); + +/* + * Expand the bitstring form (RFC 3779, section 2.1.2) of an address into + * a raw byte array. At the moment this is coded for simplicity, not speed. + * + * Unused bits in the last octet of |bs| and all bits in subsequent bytes + * of |addr| are set to 0 or 1 depending on whether |fill| is 0 or not. + */ +static int +addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length, + uint8_t fill) +{ + if (bs->length < 0 || bs->length > length) + return 0; + + if (fill != 0) + fill = 0xff; + + if (bs->length > 0) { + /* XXX - shouldn't this check ASN1_STRING_FLAG_BITS_LEFT? */ + uint8_t unused_bits = bs->flags & 7; + uint8_t mask = (1 << unused_bits) - 1; + + memcpy(addr, bs->data, bs->length); + + if (fill == 0) + addr[bs->length - 1] &= ~mask; + else + addr[bs->length - 1] |= mask; + } + + memset(addr + bs->length, fill, length - bs->length); + + return 1; +} + +/* + * Extract the prefix length from a bitstring: 8 * length - unused bits. + */ +#define addr_prefix_len(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) + +/* + * i2r handler for one address bitstring. + */ +static int +i2r_address(BIO *out, const unsigned afi, const unsigned char fill, + const ASN1_BIT_STRING *bs) +{ + unsigned char addr[ADDR_RAW_BUF_LEN]; + int i, n; + + if (bs->length < 0) + return 0; + switch (afi) { + case IANA_AFI_IPV4: + if (!addr_expand(addr, bs, 4, fill)) + return 0; + BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], + addr[3]); + break; + case IANA_AFI_IPV6: + if (!addr_expand(addr, bs, 16, fill)) + return 0; + for (n = 16; + n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; n -= 2) + continue; + for (i = 0; i < n; i += 2) + BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], + (i < 14 ? ":" : "")); + if (i < 16) + BIO_puts(out, ":"); + if (i == 0) + BIO_puts(out, ":"); + break; + default: + for (i = 0; i < bs->length; i++) + BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), + bs->data[i]); + BIO_printf(out, "[%d]", (int)(bs->flags & 7)); + break; + } + return 1; +} + +/* + * i2r handler for a sequence of addresses and ranges. + */ +static int +i2r_IPAddressOrRanges(BIO *out, const int indent, + const IPAddressOrRanges *aors, const unsigned afi) +{ + const IPAddressOrRange *aor; + const ASN1_BIT_STRING *prefix; + const IPAddressRange *range; + int i; + + for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { + aor = sk_IPAddressOrRange_value(aors, i); + + BIO_printf(out, "%*s", indent, ""); + + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + prefix = aor->u.addressPrefix; + + if (!i2r_address(out, afi, 0x00, prefix)) + return 0; + BIO_printf(out, "/%d\n", addr_prefix_len(prefix)); + continue; + case IPAddressOrRange_addressRange: + range = aor->u.addressRange; + + if (!i2r_address(out, afi, 0x00, range->min)) + return 0; + BIO_puts(out, "-"); + if (!i2r_address(out, afi, 0xff, range->max)) + return 0; + BIO_puts(out, "\n"); + continue; + } + } + + return 1; +} + +/* + * i2r handler for an IPAddrBlocks extension. + */ +static int +i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, + int indent) +{ + const IPAddrBlocks *addr = ext; + IPAddressFamily *af; + uint16_t afi; + uint8_t safi; + int i, safi_is_set; + + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + af = sk_IPAddressFamily_value(addr, i); + + if (!IPAddressFamily_afi_safi(af, &afi, &safi, &safi_is_set)) + goto print_addresses; + + switch (afi) { + case IANA_AFI_IPV4: + BIO_printf(out, "%*sIPv4", indent, ""); + break; + case IANA_AFI_IPV6: + BIO_printf(out, "%*sIPv6", indent, ""); + break; + default: + BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); + break; + } + if (safi_is_set) { + switch (safi) { + case 1: + BIO_puts(out, " (Unicast)"); + break; + case 2: + BIO_puts(out, " (Multicast)"); + break; + case 3: + BIO_puts(out, " (Unicast/Multicast)"); + break; + case 4: + BIO_puts(out, " (MPLS)"); + break; + case 64: + BIO_puts(out, " (Tunnel)"); + break; + case 65: + BIO_puts(out, " (VPLS)"); + break; + case 66: + BIO_puts(out, " (BGP MDT)"); + break; + case 128: + BIO_puts(out, " (MPLS-labeled VPN)"); + break; + default: + BIO_printf(out, " (Unknown SAFI %u)", safi); + break; + } + } + + print_addresses: + switch (IPAddressFamily_type(af)) { + case IPAddressChoice_inherit: + BIO_puts(out, ": inherit\n"); + break; + case IPAddressChoice_addressesOrRanges: + BIO_puts(out, ":\n"); + if (!i2r_IPAddressOrRanges(out, indent + 2, + IPAddressFamily_addressesOrRanges(af), afi)) + return 0; + break; + /* XXX - how should we handle -1 here? */ + } + } + return 1; +} + +/* + * Sort comparison function for a sequence of IPAddressOrRange + * elements. + * + * There's no sane answer we can give if addr_expand() fails, and an + * assertion failure on externally supplied data is seriously uncool, + * so we just arbitrarily declare that if given invalid inputs this + * function returns -1. If this messes up your preferred sort order + * for garbage input, tough noogies. + */ +static int +IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b, + const int length) +{ + unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; + int prefix_len_a = 0, prefix_len_b = 0; + int r; + + switch (a->type) { + case IPAddressOrRange_addressPrefix: + if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) + return -1; + prefix_len_a = addr_prefix_len(a->u.addressPrefix); + break; + case IPAddressOrRange_addressRange: + if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) + return -1; + prefix_len_a = length * 8; + break; + } + + switch (b->type) { + case IPAddressOrRange_addressPrefix: + if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) + return -1; + prefix_len_b = addr_prefix_len(b->u.addressPrefix); + break; + case IPAddressOrRange_addressRange: + if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) + return -1; + prefix_len_b = length * 8; + break; + } + + if ((r = memcmp(addr_a, addr_b, length)) != 0) + return r; + else + return prefix_len_a - prefix_len_b; +} + +/* + * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() + * comparison routines are only allowed two arguments. + */ +static int +v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, + const IPAddressOrRange *const *b) +{ + return IPAddressOrRange_cmp(*a, *b, 4); +} + +/* + * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() + * comparison routines are only allowed two arguments. + */ +static int +v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, + const IPAddressOrRange *const *b) +{ + return IPAddressOrRange_cmp(*a, *b, 16); +} + +/* + * Calculate whether a range collapses to a prefix. + * See last paragraph of RFC 3779 2.2.3.7. + * + * It's the caller's responsibility to ensure that min <= max. + */ +static int +range_should_be_prefix(const unsigned char *min, const unsigned char *max, + const int length) +{ + unsigned char mask; + int i, j; + + for (i = 0; i < length && min[i] == max[i]; i++) + continue; + for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xff; j--) + continue; + if (i < j) + return -1; + if (i > j) + return i * 8; + mask = min[i] ^ max[i]; + switch (mask) { + case 0x01: + j = 7; + break; + case 0x03: + j = 6; + break; + case 0x07: + j = 5; + break; + case 0x0f: + j = 4; + break; + case 0x1f: + j = 3; + break; + case 0x3f: + j = 2; + break; + case 0x7f: + j = 1; + break; + default: + return -1; + } + if ((min[i] & mask) != 0 || (max[i] & mask) != mask) + return -1; + else + return i * 8 + j; +} + +/* + * Fill IPAddressOrRange with bit string encoding of a prefix - RFC 3779, 2.1.1. + */ +static int +make_addressPrefix(IPAddressOrRange **out_aor, uint8_t *addr, uint32_t afi, + int prefix_len) +{ + IPAddressOrRange *aor = NULL; + int afi_len, num_bits, num_octets; + uint8_t unused_bits; + + if (prefix_len < 0) + goto err; + + if (!length_from_afi(afi, &afi_len)) + goto err; + if (prefix_len > 8 * afi_len) + goto err; + + num_octets = (prefix_len + 7) / 8; + num_bits = prefix_len % 8; + + unused_bits = 0; + if (num_bits > 0) + unused_bits = 8 - num_bits; + + if ((aor = IPAddressOrRange_new()) == NULL) + goto err; + + aor->type = IPAddressOrRange_addressPrefix; + + if ((aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, num_octets)) + goto err; + if (!asn1_abs_set_unused_bits(aor->u.addressPrefix, unused_bits)) + goto err; + + *out_aor = aor; + return 1; + + err: + IPAddressOrRange_free(aor); + return 0; +} + +static uint8_t +count_trailing_zeroes(uint8_t octet) +{ + uint8_t count = 0; + + if (octet == 0) + return 8; + + while ((octet & (1 << count)) == 0) + count++; + + return count; +} + +static int +trim_end_u8(CBS *cbs, uint8_t trim) +{ + uint8_t octet; + + while (CBS_len(cbs) > 0) { + if (!CBS_peek_last_u8(cbs, &octet)) + return 0; + if (octet != trim) + return 1; + if (!CBS_get_last_u8(cbs, &octet)) + return 0; + } + + return 1; +} + +/* + * Populate IPAddressOrRange with bit string encoding of a range, see + * RFC 3779, 2.1.2. + */ +static int +make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, + uint32_t afi, int length) +{ + IPAddressOrRange *aor = NULL; + IPAddressRange *range; + int prefix_len; + CBS cbs; + size_t max_len, min_len; + uint8_t unused_bits_min, unused_bits_max; + uint8_t octet; + + if (memcmp(min, max, length) > 0) + goto err; + + /* + * RFC 3779, 2.2.3.6 - a range that can be expressed as a prefix + * must be encoded as a prefix. + */ + + if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0) + return make_addressPrefix(out_aor, min, afi, prefix_len); + + /* + * The bit string representing min is formed by removing all its + * trailing zero bits, so remove all trailing zero octets and count + * the trailing zero bits of the last octet. + */ + + CBS_init(&cbs, min, length); + + if (!trim_end_u8(&cbs, 0x00)) + goto err; + + unused_bits_min = 0; + if ((min_len = CBS_len(&cbs)) > 0) { + if (!CBS_peek_last_u8(&cbs, &octet)) + goto err; + + unused_bits_min = count_trailing_zeroes(octet); + } + + /* + * The bit string representing max is formed by removing all its + * trailing one bits, so remove all trailing 0xff octets and count + * the trailing ones of the last octet. + */ + + CBS_init(&cbs, max, length); + + if (!trim_end_u8(&cbs, 0xff)) + goto err; + + unused_bits_max = 0; + if ((max_len = CBS_len(&cbs)) > 0) { + if (!CBS_peek_last_u8(&cbs, &octet)) + goto err; + + unused_bits_max = count_trailing_zeroes(octet + 1); + } + + /* + * Populate IPAddressOrRange. + */ + + if ((aor = IPAddressOrRange_new()) == NULL) + goto err; + + aor->type = IPAddressOrRange_addressRange; + + if ((range = aor->u.addressRange = IPAddressRange_new()) == NULL) + goto err; + + if (!ASN1_BIT_STRING_set(range->min, min, min_len)) + goto err; + if (!asn1_abs_set_unused_bits(range->min, unused_bits_min)) + goto err; + + if (!ASN1_BIT_STRING_set(range->max, max, max_len)) + goto err; + if (!asn1_abs_set_unused_bits(range->max, unused_bits_max)) + goto err; + + *out_aor = aor; + + return 1; + + err: + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Construct a new address family or find an existing one. + */ +static IPAddressFamily * +make_IPAddressFamily(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *af = NULL; + CBB cbb; + CBS cbs; + uint8_t *key = NULL; + size_t keylen; + int i; + + if (!CBB_init(&cbb, 0)) + goto err; + + if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6) + goto err; + if (!CBB_add_u16(&cbb, afi)) + goto err; + + if (safi != NULL) { + if (*safi > 255) + goto err; + if (!CBB_add_u8(&cbb, *safi)) + goto err; + } + + if (!CBB_finish(&cbb, &key, &keylen)) + goto err; + + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + af = sk_IPAddressFamily_value(addr, i); + + CBS_init(&cbs, af->addressFamily->data, + af->addressFamily->length); + if (CBS_mem_equal(&cbs, key, keylen)) + goto done; + } + + if ((af = IPAddressFamily_new()) == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(af->addressFamily, key, keylen)) + goto err; + if (!sk_IPAddressFamily_push(addr, af)) + goto err; + + done: + free(key); + + return af; + + err: + CBB_cleanup(&cbb); + free(key); + IPAddressFamily_free(af); + + return NULL; +} + +/* + * Add an inheritance element. + */ +int +X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *af; + + if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL) + return 0; + + return IPAddressFamily_set_inheritance(af); +} +LCRYPTO_ALIAS(X509v3_addr_add_inherit); + +/* + * Construct an IPAddressOrRange sequence, or return an existing one. + */ +static IPAddressOrRanges * +make_prefix_or_range(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *af; + IPAddressOrRanges *aors = NULL; + + if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL) + return NULL; + + if (IPAddressFamily_inheritance(af) != NULL) + return NULL; + + if ((aors = IPAddressFamily_addressesOrRanges(af)) != NULL) + return aors; + + if ((aors = sk_IPAddressOrRange_new_null()) == NULL) + return NULL; + + switch (afi) { + case IANA_AFI_IPV4: + (void)sk_IPAddressOrRange_set_cmp_func(aors, + v4IPAddressOrRange_cmp); + break; + case IANA_AFI_IPV6: + (void)sk_IPAddressOrRange_set_cmp_func(aors, + v6IPAddressOrRange_cmp); + break; + } + + af->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; + af->ipAddressChoice->u.addressesOrRanges = aors; + + return aors; +} + +/* + * Add a prefix. + */ +int +X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi, unsigned char *a, const int prefix_len) +{ + IPAddressOrRanges *aors; + IPAddressOrRange *aor; + + if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) + return 0; + + if (!make_addressPrefix(&aor, a, afi, prefix_len)) + return 0; + + if (sk_IPAddressOrRange_push(aors, aor) <= 0) { + IPAddressOrRange_free(aor); + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(X509v3_addr_add_prefix); + +/* + * Add a range. + */ +int +X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi, unsigned char *min, unsigned char *max) +{ + IPAddressOrRanges *aors; + IPAddressOrRange *aor; + int length; + + if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) + return 0; + + if (!length_from_afi(afi, &length)) + return 0; + + if (!make_addressRange(&aor, min, max, afi, length)) + return 0; + + if (sk_IPAddressOrRange_push(aors, aor) <= 0) { + IPAddressOrRange_free(aor); + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(X509v3_addr_add_range); + +static int +extract_min_max_bitstr(IPAddressOrRange *aor, ASN1_BIT_STRING **out_min, + ASN1_BIT_STRING **out_max) +{ + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + *out_min = *out_max = aor->u.addressPrefix; + return 1; + case IPAddressOrRange_addressRange: + *out_min = aor->u.addressRange->min; + *out_max = aor->u.addressRange->max; + return 1; + default: + return 0; + } +} + +/* + * Extract min and max values from an IPAddressOrRange. + */ +static int +extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max, + int length) +{ + ASN1_BIT_STRING *min_bitstr, *max_bitstr; + + if (aor == NULL || min == NULL || max == NULL) + return 0; + + if (!extract_min_max_bitstr(aor, &min_bitstr, &max_bitstr)) + return 0; + + if (!addr_expand(min, min_bitstr, length, 0)) + return 0; + + return addr_expand(max, max_bitstr, length, 1); +} + +/* + * Public wrapper for extract_min_max(). + */ +int +X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, const int length) +{ + int afi_len; + + if (!length_from_afi(afi, &afi_len)) + return 0; + + if (length < afi_len) + return 0; + + if (!extract_min_max(aor, min, max, afi_len)) + return 0; + + return afi_len; +} +LCRYPTO_ALIAS(X509v3_addr_get_range); + +/* + * Check whether an IPAddrBLocks is in canonical form. + */ +int +X509v3_addr_is_canonical(IPAddrBlocks *addr) +{ + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; + IPAddressFamily *af; + IPAddressOrRanges *aors; + IPAddressOrRange *aor, *aor_a, *aor_b; + int i, j, k, length; + + /* + * Empty extension is canonical. + */ + if (addr == NULL) + return 1; + + /* + * Check whether the top-level list is in order. + */ + for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { + const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); + const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); + + /* Check that both have valid AFIs before comparing them. */ + if (!IPAddressFamily_afi_is_valid(a)) + return 0; + if (!IPAddressFamily_afi_is_valid(b)) + return 0; + + if (IPAddressFamily_cmp(&a, &b) >= 0) + return 0; + } + + /* + * Top level's ok, now check each address family. + */ + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + af = sk_IPAddressFamily_value(addr, i); + + if (!IPAddressFamily_afi_length(af, &length)) + return 0; + + /* + * If this family has an inheritance element, it is canonical. + */ + if (IPAddressFamily_inheritance(af) != NULL) + continue; + + /* + * If this family has neither an inheritance element nor an + * addressesOrRanges, we don't know what this is. + */ + if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL) + return 0; + + if (sk_IPAddressOrRange_num(aors) == 0) + return 0; + + for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { + aor_a = sk_IPAddressOrRange_value(aors, j); + aor_b = sk_IPAddressOrRange_value(aors, j + 1); + + if (!extract_min_max(aor_a, a_min, a_max, length) || + !extract_min_max(aor_b, b_min, b_max, length)) + return 0; + + /* + * Punt misordered list, overlapping start, or inverted + * range. + */ + if (memcmp(a_min, b_min, length) >= 0 || + memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* + * Punt if adjacent or overlapping. Check for adjacency + * by subtracting one from b_min first. + */ + for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) + continue; + if (memcmp(a_max, b_min, length) >= 0) + return 0; + + /* + * Check for range that should be expressed as a prefix. + */ + if (aor_a->type == IPAddressOrRange_addressPrefix) + continue; + + if (range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; + } + + /* + * Check final range to see if it's inverted or should be a + * prefix. + */ + aor = sk_IPAddressOrRange_value(aors, j); + if (aor->type == IPAddressOrRange_addressRange) { + if (!extract_min_max(aor, a_min, a_max, length)) + return 0; + if (memcmp(a_min, a_max, length) > 0) + return 0; + if (range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; + } + } + + /* + * If we made it through all that, we're happy. + */ + return 1; +} +LCRYPTO_ALIAS(X509v3_addr_is_canonical); + +/* + * Whack an IPAddressOrRanges into canonical form. + */ +static int +IPAddressOrRanges_canonize(IPAddressOrRanges *aors, const unsigned afi) +{ + IPAddressOrRange *a, *b, *merged; + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; + int i, j, length; + + if (!length_from_afi(afi, &length)) + return 0; + + /* + * Sort the IPAddressOrRanges sequence. + */ + sk_IPAddressOrRange_sort(aors); + + /* + * Clean up representation issues, punt on duplicates or overlaps. + */ + for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { + a = sk_IPAddressOrRange_value(aors, i); + b = sk_IPAddressOrRange_value(aors, i + 1); + + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; + + /* + * Punt inverted ranges. + */ + if (memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* + * Punt overlaps. + */ + if (memcmp(a_max, b_min, length) >= 0) + return 0; + + /* + * Merge if a and b are adjacent. We check for + * adjacency by subtracting one from b_min first. + */ + for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) + continue; + + if (memcmp(a_max, b_min, length) != 0) + continue; + + if (!make_addressRange(&merged, a_min, b_max, afi, length)) + return 0; + sk_IPAddressOrRange_set(aors, i, merged); + (void)sk_IPAddressOrRange_delete(aors, i + 1); + IPAddressOrRange_free(a); + IPAddressOrRange_free(b); + i--; + } + + /* + * Check for inverted final range. + */ + a = sk_IPAddressOrRange_value(aors, i); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + if (!extract_min_max(a, a_min, a_max, length)) + return 0; + if (memcmp(a_min, a_max, length) > 0) + return 0; + } + + return 1; +} + +/* + * Whack an IPAddrBlocks extension into canonical form. + */ +int +X509v3_addr_canonize(IPAddrBlocks *addr) +{ + IPAddressFamily *af; + IPAddressOrRanges *aors; + uint16_t afi; + int i; + + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + af = sk_IPAddressFamily_value(addr, i); + + /* Check AFI/SAFI here - IPAddressFamily_cmp() can't error. */ + if (!IPAddressFamily_afi(af, &afi)) + return 0; + + if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL) + continue; + + if (!IPAddressOrRanges_canonize(aors, afi)) + return 0; + } + + (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); + sk_IPAddressFamily_sort(addr); + + return X509v3_addr_is_canonical(addr); +} +LCRYPTO_ALIAS(X509v3_addr_canonize); + +/* + * v2i handler for the IPAddrBlocks extension. + */ +static void * +v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE)*values) +{ + static const char v4addr_chars[] = "0123456789."; + static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; + IPAddrBlocks *addr = NULL; + char *s = NULL, *t; + int i; + + if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; + unsigned afi, *safi = NULL, safi_; + const char *addr_chars = NULL; + const char *errstr; + int prefix_len, i1, i2, delim, length; + + if (!name_cmp(val->name, "IPv4")) { + afi = IANA_AFI_IPV4; + } else if (!name_cmp(val->name, "IPv6")) { + afi = IANA_AFI_IPV6; + } else if (!name_cmp(val->name, "IPv4-SAFI")) { + afi = IANA_AFI_IPV4; + safi = &safi_; + } else if (!name_cmp(val->name, "IPv6-SAFI")) { + afi = IANA_AFI_IPV6; + safi = &safi_; + } else { + X509V3error(X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + switch (afi) { + case IANA_AFI_IPV4: + addr_chars = v4addr_chars; + break; + case IANA_AFI_IPV6: + addr_chars = v6addr_chars; + break; + } + + if (!length_from_afi(afi, &length)) + goto err; + + /* + * Handle SAFI, if any, and strdup() so we can null-terminate + * the other input values. + */ + if (safi != NULL) { + unsigned long parsed_safi; + int saved_errno = errno; + + errno = 0; + parsed_safi = strtoul(val->value, &t, 0); + + /* Value must be present, then a tab, space or colon. */ + if (val->value[0] == '\0' || + (*t != '\t' && *t != ' ' && *t != ':')) { + X509V3error(X509V3_R_INVALID_SAFI); + X509V3_conf_err(val); + goto err; + } + /* Range and overflow check. */ + if ((errno == ERANGE && parsed_safi == ULONG_MAX) || + parsed_safi > 0xff) { + X509V3error(X509V3_R_INVALID_SAFI); + X509V3_conf_err(val); + goto err; + } + errno = saved_errno; + + *safi = parsed_safi; + + /* Check possible whitespace is followed by a colon. */ + t += strspn(t, " \t"); + if (*t != ':') { + X509V3error(X509V3_R_INVALID_SAFI); + X509V3_conf_err(val); + goto err; + } + + /* Skip over colon. */ + t++; + + /* Then over any trailing whitespace. */ + t += strspn(t, " \t"); + + s = strdup(t); + } else { + s = strdup(val->value); + } + if (s == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Check for inheritance. Not worth additional complexity to + * optimize this (seldom-used) case. + */ + if (strcmp(s, "inherit") == 0) { + if (!X509v3_addr_add_inherit(addr, afi, safi)) { + X509V3error(X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + free(s); + s = NULL; + continue; + } + + i1 = strspn(s, addr_chars); + i2 = i1 + strspn(s + i1, " \t"); + delim = s[i2++]; + s[i1] = '\0'; + + if (a2i_ipadd(min, s) != length) { + X509V3error(X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + + switch (delim) { + case '/': + /* length contains the size of the address in bytes. */ + if (length != 4 && length != 16) + goto err; + prefix_len = strtonum(s + i2, 0, 8 * length, &errstr); + if (errstr != NULL) { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!X509v3_addr_add_prefix(addr, afi, safi, min, + prefix_len)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '-': + i1 = i2 + strspn(s + i2, " \t"); + i2 = i1 + strspn(s + i1, addr_chars); + if (i1 == i2 || s[i2] != '\0') { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (a2i_ipadd(max, s + i1) != length) { + X509V3error(X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + if (memcmp(min, max, length) > 0) { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!X509v3_addr_add_range(addr, afi, safi, min, max)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '\0': + if (!X509v3_addr_add_prefix(addr, afi, safi, min, + length * 8)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + + free(s); + s = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!X509v3_addr_canonize(addr)) + goto err; + return addr; + + err: + free(s); + sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); + return NULL; +} + +/* + * OpenSSL dispatch + */ +const X509V3_EXT_METHOD v3_addr = { + .ext_nid = NID_sbgp_ipAddrBlock, + .ext_flags = 0, + .it = &IPAddrBlocks_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_IPAddrBlocks, + .i2r = i2r_IPAddrBlocks, + .r2i = NULL, + .usr_data = NULL, +}; + +/* + * Figure out whether extension uses inheritance. + */ +int +X509v3_addr_inherits(IPAddrBlocks *addr) +{ + IPAddressFamily *af; + int i; + + if (addr == NULL) + return 0; + + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + af = sk_IPAddressFamily_value(addr, i); + + if (IPAddressFamily_inheritance(af) != NULL) + return 1; + } + + return 0; +} +LCRYPTO_ALIAS(X509v3_addr_inherits); + +/* + * Figure out whether parent contains child. + * + * This only works correctly if both parent and child are in canonical form. + */ +static int +addr_contains(IPAddressOrRanges *parent, IPAddressOrRanges *child, int length) +{ + IPAddressOrRange *child_aor, *parent_aor; + uint8_t parent_min[ADDR_RAW_BUF_LEN], parent_max[ADDR_RAW_BUF_LEN]; + uint8_t child_min[ADDR_RAW_BUF_LEN], child_max[ADDR_RAW_BUF_LEN]; + int p, c; + + if (child == NULL || parent == child) + return 1; + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { + child_aor = sk_IPAddressOrRange_value(child, c); + + if (!extract_min_max(child_aor, child_min, child_max, length)) + return 0; + + for (;; p++) { + if (p >= sk_IPAddressOrRange_num(parent)) + return 0; + + parent_aor = sk_IPAddressOrRange_value(parent, p); + + if (!extract_min_max(parent_aor, parent_min, parent_max, + length)) + return 0; + + if (memcmp(parent_max, child_max, length) < 0) + continue; + if (memcmp(parent_min, child_min, length) > 0) + return 0; + break; + } + } + + return 1; +} + +/* + * Test whether |child| is a subset of |parent|. + */ +int +X509v3_addr_subset(IPAddrBlocks *child, IPAddrBlocks *parent) +{ + IPAddressFamily *child_af, *parent_af; + IPAddressOrRanges *child_aor, *parent_aor; + int i, length; + + if (child == NULL || child == parent) + return 1; + if (parent == NULL) + return 0; + + if (X509v3_addr_inherits(child) || X509v3_addr_inherits(parent)) + return 0; + + for (i = 0; i < sk_IPAddressFamily_num(child); i++) { + child_af = sk_IPAddressFamily_value(child, i); + + parent_af = IPAddressFamily_find_in_parent(parent, child_af); + if (parent_af == NULL) + return 0; + + if (!IPAddressFamily_afi_length(parent_af, &length)) + return 0; + + child_aor = IPAddressFamily_addressesOrRanges(child_af); + parent_aor = IPAddressFamily_addressesOrRanges(parent_af); + + if (!addr_contains(parent_aor, child_aor, length)) + return 0; + } + return 1; +} +LCRYPTO_ALIAS(X509v3_addr_subset); + +static int +verify_error(X509_STORE_CTX *ctx, X509 *cert, int error, int depth) +{ + if (ctx == NULL) + return 0; + + ctx->current_cert = cert; + ctx->error = error; + ctx->error_depth = depth; + + return ctx->verify_cb(0, ctx); +} + +/* + * Core code for RFC 3779 2.3 path validation. + * + * Returns 1 for success, 0 on error. + * + * When returning 0, ctx->error MUST be set to an appropriate value other than + * X509_V_OK. + */ +static int +addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, + IPAddrBlocks *ext) +{ + IPAddrBlocks *child = NULL, *parent = NULL; + IPAddressFamily *child_af, *parent_af; + IPAddressOrRanges *child_aor, *parent_aor; + X509 *cert = NULL; + int depth = -1; + int i; + unsigned int length; + int ret = 1; + + /* We need a non-empty chain to test against. */ + if (sk_X509_num(chain) <= 0) + goto err; + /* We need either a store ctx or an extension to work with. */ + if (ctx == NULL && ext == NULL) + goto err; + /* If there is a store ctx, it needs a verify_cb. */ + if (ctx != NULL && ctx->verify_cb == NULL) + goto err; + + /* + * Figure out where to start. If we don't have an extension to check, + * (either extracted from the leaf or passed by the caller), we're done. + * Otherwise, check canonical form and set up for walking up the chain. + */ + if (ext == NULL) { + depth = 0; + cert = sk_X509_value(chain, depth); + if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) + goto done; + if ((ext = cert->rfc3779_addr) == NULL) + goto done; + } else if (!X509v3_addr_is_canonical(ext)) { + if ((ret = verify_error(ctx, cert, + X509_V_ERR_INVALID_EXTENSION, depth)) == 0) + goto done; + } + + (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); + if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + ctx->error = X509_V_ERR_OUT_OF_MEM; + ret = 0; + goto done; + } + + /* + * Now walk up the chain. No cert may list resources that its parent + * doesn't list. + */ + for (depth++; depth < sk_X509_num(chain); depth++) { + cert = sk_X509_value(chain, depth); + + if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) { + if ((ret = verify_error(ctx, cert, + X509_V_ERR_INVALID_EXTENSION, depth)) == 0) + goto done; + } + + if ((parent = cert->rfc3779_addr) == NULL) { + for (i = 0; i < sk_IPAddressFamily_num(child); i++) { + child_af = sk_IPAddressFamily_value(child, i); + + if (IPAddressFamily_inheritance(child_af) != + NULL) + continue; + + if ((ret = verify_error(ctx, cert, + X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) + goto done; + break; + } + continue; + } + + /* + * Check that the child's resources are covered by the parent. + * Each covered resource is replaced with the parent's resource + * covering it, so the next iteration will check that the + * parent's resources are covered by the grandparent. + */ + for (i = 0; i < sk_IPAddressFamily_num(child); i++) { + child_af = sk_IPAddressFamily_value(child, i); + + if ((parent_af = IPAddressFamily_find_in_parent(parent, + child_af)) == NULL) { + /* + * If we have no match in the parent and the + * child inherits, that's fine. + */ + if (IPAddressFamily_inheritance(child_af) != + NULL) + continue; + + /* Otherwise the child isn't covered. */ + if ((ret = verify_error(ctx, cert, + X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) + goto done; + break; + } + + /* Parent inherits, nothing to do. */ + if (IPAddressFamily_inheritance(parent_af) != NULL) + continue; + + /* Child inherits. Use parent's address family. */ + if (IPAddressFamily_inheritance(child_af) != NULL) { + sk_IPAddressFamily_set(child, i, parent_af); + continue; + } + + child_aor = IPAddressFamily_addressesOrRanges(child_af); + parent_aor = + IPAddressFamily_addressesOrRanges(parent_af); + + /* + * Child and parent are canonical and neither inherits. + * If either addressesOrRanges is NULL, something's + * very wrong. + */ + if (child_aor == NULL || parent_aor == NULL) + goto err; + + if (!IPAddressFamily_afi_length(child_af, &length)) + goto err; + + /* Now check containment and replace or error. */ + if (addr_contains(parent_aor, child_aor, length)) { + sk_IPAddressFamily_set(child, i, parent_af); + continue; + } + + if ((ret = verify_error(ctx, cert, + X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) + goto done; + } + } + + /* + * Trust anchor can't inherit. + */ + if ((parent = cert->rfc3779_addr) != NULL) { + for (i = 0; i < sk_IPAddressFamily_num(parent); i++) { + parent_af = sk_IPAddressFamily_value(parent, i); + + if (IPAddressFamily_inheritance(parent_af) == NULL) + continue; + + if ((ret = verify_error(ctx, cert, + X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) + goto done; + } + } + + done: + sk_IPAddressFamily_free(child); + return ret; + + err: + sk_IPAddressFamily_free(child); + + if (ctx != NULL) + ctx->error = X509_V_ERR_UNSPECIFIED; + + return 0; +} + +/* + * RFC 3779 2.3 path validation -- called from X509_verify_cert(). + */ +int +X509v3_addr_validate_path(X509_STORE_CTX *ctx) +{ + if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { + ctx->error = X509_V_ERR_UNSPECIFIED; + return 0; + } + return addr_validate_path_internal(ctx, ctx->chain, NULL); +} +LCRYPTO_ALIAS(X509v3_addr_validate_path); + +/* + * RFC 3779 2.3 path validation of an extension. + * Test whether chain covers extension. + */ +int +X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext, + int allow_inheritance) +{ + if (ext == NULL) + return 1; + if (sk_X509_num(chain) <= 0) + return 0; + if (!allow_inheritance && X509v3_addr_inherits(ext)) + return 0; + return addr_validate_path_internal(NULL, chain, ext); +} +LCRYPTO_ALIAS(X509v3_addr_validate_resource_set); + +#endif /* OPENSSL_NO_RFC3779 */ diff --git a/Libraries/libressl/crypto/x509/x509_akey.c b/Libraries/libressl/crypto/x509/x509_akey.c new file mode 100644 index 000000000..f8c711335 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_akey.c @@ -0,0 +1,237 @@ +/* $OpenBSD: x509_akey.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist); +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_akey_id = { + .ext_nid = NID_authority_key_identifier, + .ext_flags = X509V3_EXT_MULTILINE, + .it = &AUTHORITY_KEYID_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID, + .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static STACK_OF(CONF_VALUE) * +i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) *extlist) +{ + STACK_OF(CONF_VALUE) *free_extlist = NULL; + char *tmpstr = NULL; + + if (extlist == NULL) { + if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + if (akeyid->keyid != NULL) { + if ((tmpstr = hex_to_string(akeyid->keyid->data, + akeyid->keyid->length)) == NULL) + goto err; + if (!X509V3_add_value("keyid", tmpstr, &extlist)) + goto err; + free(tmpstr); + tmpstr = NULL; + } + + if (akeyid->issuer != NULL) { + if ((extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, + extlist)) == NULL) + goto err; + } + + if (akeyid->serial != NULL) { + if ((tmpstr = hex_to_string(akeyid->serial->data, + akeyid->serial->length)) == NULL) + goto err; + if (!X509V3_add_value("serial", tmpstr, &extlist)) + goto err; + free(tmpstr); + tmpstr = NULL; + } + + if (sk_CONF_VALUE_num(extlist) <= 0) + goto err; + + return extlist; + + err: + free(tmpstr); + sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); + + return NULL; +} + +/* + * Currently two options: + * keyid: use the issuers subject keyid, the value 'always' means its is + * an error if the issuer certificate doesn't have a key id. + * issuer: use the issuers cert issuer and serial number. The default is + * to only use this if keyid is not present. With the option 'always' + * this is always included. + */ +static AUTHORITY_KEYID * +v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + char keyid = 0, issuer = 0; + int i; + CONF_VALUE *cnf; + ASN1_OCTET_STRING *ikeyid = NULL; + X509_NAME *isname = NULL; + STACK_OF(GENERAL_NAME) *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_INTEGER *serial = NULL; + X509_EXTENSION *ext; + X509 *cert; + AUTHORITY_KEYID *akeyid = NULL; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + cnf = sk_CONF_VALUE_value(values, i); + if (!strcmp(cnf->name, "keyid")) { + keyid = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + keyid = 2; + } else if (!strcmp(cnf->name, "issuer")) { + issuer = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + issuer = 2; + } else { + X509V3error(X509V3_R_UNKNOWN_OPTION); + ERR_asprintf_error_data("name=%s", cnf->name); + return NULL; + } + } + + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == CTX_TEST)) + return AUTHORITY_KEYID_new(); + X509V3error(X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((i >= 0) && (ext = X509_get_ext(cert, i))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + X509V3error(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + return NULL; + } + } + + if ((issuer && !ikeyid) || (issuer == 2)) { + isname = X509_NAME_dup(X509_get_issuer_name(cert)); + serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + if (!isname || !serial) { + X509V3error(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + goto err; + } + } + + if (!(akeyid = AUTHORITY_KEYID_new())) + goto err; + + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) || + !(gen = GENERAL_NAME_new()) || + !sk_GENERAL_NAME_push(gens, gen)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = isname; + } + + akeyid->issuer = gens; + akeyid->serial = serial; + akeyid->keyid = ikeyid; + + return akeyid; + + err: + AUTHORITY_KEYID_free(akeyid); + GENERAL_NAME_free(gen); + sk_GENERAL_NAME_free(gens); + X509_NAME_free(isname); + ASN1_INTEGER_free(serial); + ASN1_OCTET_STRING_free(ikeyid); + return NULL; +} diff --git a/Libraries/libressl/crypto/x509/x509_akeya.c b/Libraries/libressl/crypto/x509/x509_akeya.c new file mode 100644 index 000000000..52eca42cf --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_akeya.c @@ -0,0 +1,128 @@ +/* $OpenBSD: x509_akeya.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +static const ASN1_TEMPLATE AUTHORITY_KEYID_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(AUTHORITY_KEYID, keyid), + .field_name = "keyid", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(AUTHORITY_KEYID, issuer), + .field_name = "issuer", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(AUTHORITY_KEYID, serial), + .field_name = "serial", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM AUTHORITY_KEYID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = AUTHORITY_KEYID_seq_tt, + .tcount = sizeof(AUTHORITY_KEYID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(AUTHORITY_KEYID), + .sname = "AUTHORITY_KEYID", +}; + + +AUTHORITY_KEYID * +d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len) +{ + return (AUTHORITY_KEYID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &AUTHORITY_KEYID_it); +} +LCRYPTO_ALIAS(d2i_AUTHORITY_KEYID); + +int +i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_KEYID_it); +} +LCRYPTO_ALIAS(i2d_AUTHORITY_KEYID); + +AUTHORITY_KEYID * +AUTHORITY_KEYID_new(void) +{ + return (AUTHORITY_KEYID *)ASN1_item_new(&AUTHORITY_KEYID_it); +} +LCRYPTO_ALIAS(AUTHORITY_KEYID_new); + +void +AUTHORITY_KEYID_free(AUTHORITY_KEYID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_KEYID_it); +} +LCRYPTO_ALIAS(AUTHORITY_KEYID_free); diff --git a/Libraries/libressl/crypto/x509/x509_alt.c b/Libraries/libressl/crypto/x509/x509_alt.c new file mode 100644 index 000000000..59fa39fa6 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_alt.c @@ -0,0 +1,782 @@ +/* $OpenBSD: x509_alt.c,v 1.16 2023/08/30 00:49:32 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +#include "x509_internal.h" + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); + +const X509V3_EXT_METHOD v3_alt[] = { + { + .ext_nid = NID_subject_alt_name, + .ext_flags = 0, + .it = &GENERAL_NAMES_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + .v2i = (X509V3_EXT_V2I)v2i_subject_alt, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_issuer_alt_name, + .ext_flags = 0, + .it = &GENERAL_NAMES_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + .v2i = (X509V3_EXT_V2I)v2i_issuer_alt, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_certificate_issuer, + .ext_flags = 0, + .it = &GENERAL_NAMES_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, +}; + +STACK_OF(CONF_VALUE) * +i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) +{ + STACK_OF(CONF_VALUE) *free_ret = NULL; + GENERAL_NAME *gen; + int i; + + if (ret == NULL) { + if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + if ((gen = sk_GENERAL_NAME_value(gens, i)) == NULL) + goto err; + if ((ret = i2v_GENERAL_NAME(method, gen, ret)) == NULL) + goto err; + } + + return ret; + + err: + sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); + + return NULL; +} +LCRYPTO_ALIAS(i2v_GENERAL_NAMES); + +STACK_OF(CONF_VALUE) * +i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) +{ + STACK_OF(CONF_VALUE) *free_ret = NULL; + unsigned char *p; + char oline[256], htmp[5]; + int i; + + if (ret == NULL) { + if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + switch (gen->type) { + case GEN_OTHERNAME: + if (!X509V3_add_value("othername", "", &ret)) + goto err; + break; + + case GEN_X400: + if (!X509V3_add_value("X400Name", "", &ret)) + goto err; + break; + + case GEN_EDIPARTY: + if (!X509V3_add_value("EdiPartyName", "", &ret)) + goto err; + break; + + case GEN_EMAIL: + if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) + goto err; + break; + + case GEN_DNS: + if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) + goto err; + break; + + case GEN_URI: + if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) + goto err; + break; + + case GEN_DIRNAME: + if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL) + goto err; + if (!X509V3_add_value("DirName", oline, &ret)) + goto err; + break; + + case GEN_IPADD: /* XXX */ + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + (void) snprintf(oline, sizeof oline, + "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + oline[0] = 0; + for (i = 0; i < 8; i++) { + (void) snprintf(htmp, sizeof htmp, + "%X", p[0] << 8 | p[1]); + p += 2; + strlcat(oline, htmp, sizeof(oline)); + if (i != 7) + strlcat(oline, ":", sizeof(oline)); + } + } else { + if (!X509V3_add_value("IP Address", "", &ret)) + goto err; + break; + } + if (!X509V3_add_value("IP Address", oline, &ret)) + goto err; + break; + + case GEN_RID: + if (!i2t_ASN1_OBJECT(oline, 256, gen->d.rid)) + goto err; + if (!X509V3_add_value("Registered ID", oline, &ret)) + goto err; + break; + } + + return ret; + + err: + sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); + + return NULL; +} +LCRYPTO_ALIAS(i2v_GENERAL_NAME); + +int +GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) +{ + unsigned char *p; + int i; + + switch (gen->type) { + case GEN_OTHERNAME: + BIO_printf(out, "othername:"); + break; + + case GEN_X400: + BIO_printf(out, "X400Name:"); + break; + + case GEN_EDIPARTY: + /* Maybe fix this: it is supported now */ + BIO_printf(out, "EdiPartyName:"); + break; + + case GEN_EMAIL: + BIO_printf(out, "email:%.*s", gen->d.ia5->length, + gen->d.ia5->data); + break; + + case GEN_DNS: + BIO_printf(out, "DNS:%.*s", gen->d.ia5->length, + gen->d.ia5->data); + break; + + case GEN_URI: + BIO_printf(out, "URI:%.*s", gen->d.ia5->length, + gen->d.ia5->data); + break; + + case GEN_DIRNAME: + BIO_printf(out, "DirName: "); + X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_printf(out, "IP Address:%d.%d.%d.%d", + p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + BIO_printf(out, "IP Address"); + for (i = 0; i < 8; i++) { + BIO_printf(out, ":%X", p[0] << 8 | p[1]); + p += 2; + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:"); + break; + } + break; + + case GEN_RID: + BIO_printf(out, "Registered ID"); + i2a_ASN1_OBJECT(out, gen->d.rid); + break; + } + return 1; +} +LCRYPTO_ALIAS(GENERAL_NAME_print); + +static GENERAL_NAMES * +v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + + if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL && + strcmp(cnf->value, "copy") == 0) { + if (!copy_issuer(ctx, gens)) + goto err; + } else { + GENERAL_NAME *gen; + if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) + goto err; + if (sk_GENERAL_NAME_push(gens, gen) == 0) { + GENERAL_NAME_free(gen); + goto err; + } + } + } + return gens; + +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Append subject altname of issuer to issuer alt name of subject */ + +static int +copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) +{ + GENERAL_NAMES *ialt = NULL; + GENERAL_NAME *gen = NULL; + X509_EXTENSION *ext; + int i; + int ret = 0; + + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + X509V3error(X509V3_R_NO_ISSUER_DETAILS); + goto err; + } + i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) + return 1; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + X509V3error(X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { + GENERAL_NAME *val = sk_GENERAL_NAME_value(ialt, i); + + if ((gen = GENERAL_NAME_dup(val)) == NULL) + goto err; + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + ret = 1; + + err: + sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + GENERAL_NAME_free(gen); + + return ret; +} + +static GENERAL_NAMES * +v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) + goto err; + } else if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (sk_GENERAL_NAME_push(gens, gen) == 0) { + GENERAL_NAME_free(gen); + goto err; + } + } + } + return gens; + +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Copy any email addresses in a certificate or request to + * GENERAL_NAMES + */ + +static int +copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +{ + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + + if (ctx != NULL && ctx->flags == CTX_TEST) + return 1; + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + X509V3error(X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + /* Find the subject name */ + if (ctx->subject_cert) + nm = X509_get_subject_name(ctx->subject_cert); + else + nm = X509_REQ_get_subject_name(ctx->subject_req); + + /* Now add any email address(es) to STACK */ + i = -1; + while ((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if (move_p) { + X509_NAME_delete_entry(nm, i); + X509_NAME_ENTRY_free(ne); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + return 1; + +err: + GENERAL_NAME_free(gen); + ASN1_IA5STRING_free(email); + return 0; +} + +GENERAL_NAMES * +v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAME *gen; + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (sk_GENERAL_NAME_push(gens, gen) == 0) { + GENERAL_NAME_free(gen); + goto err; + } + } + return gens; + +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} +LCRYPTO_ALIAS(v2i_GENERAL_NAMES); + +GENERAL_NAME * +v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf) +{ + return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); +} +LCRYPTO_ALIAS(v2i_GENERAL_NAME); + +GENERAL_NAME * +a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, const char *value, int is_nc) +{ + char is_string = 0; + GENERAL_NAME *gen = NULL; + + if (!value) { + X509V3error(X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + } + + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: + is_string = 1; + break; + + case GEN_RID: + { + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + X509V3error(X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("value=%s", value); + goto err; + } + gen->d.rid = obj; + } + break; + + case GEN_IPADD: + if (is_nc) + gen->d.ip = a2i_IPADDRESS_NC(value); + else + gen->d.ip = a2i_IPADDRESS(value); + if (gen->d.ip == NULL) { + X509V3error(X509V3_R_BAD_IP_ADDRESS); + ERR_asprintf_error_data("value=%s", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + X509V3error(X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + X509V3error(X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + + default: + X509V3error(X509V3_R_UNSUPPORTED_TYPE); + goto err; + } + + if (is_string) { + if (!(gen->d.ia5 = ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, value, strlen(value))) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + } + + gen->type = gen_type; + + return gen; + +err: + if (out == NULL) + GENERAL_NAME_free(gen); + return NULL; +} +LCRYPTO_ALIAS(a2i_GENERAL_NAME); + +GENERAL_NAME * +v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) +{ + uint8_t *bytes = NULL; + char *name, *value; + GENERAL_NAME *ret; + size_t len = 0; + int type; + CBS cbs; + + name = cnf->name; + value = cnf->value; + + if (!value) { + X509V3error(X509V3_R_MISSING_VALUE); + return NULL; + } + + if (!name_cmp(name, "email")) + type = GEN_EMAIL; + else if (!name_cmp(name, "URI")) + type = GEN_URI; + else if (!name_cmp(name, "DNS")) + type = GEN_DNS; + else if (!name_cmp(name, "RID")) + type = GEN_RID; + else if (!name_cmp(name, "IP")) + type = GEN_IPADD; + else if (!name_cmp(name, "dirName")) + type = GEN_DIRNAME; + else if (!name_cmp(name, "otherName")) + type = GEN_OTHERNAME; + else { + X509V3error(X509V3_R_UNSUPPORTED_OPTION); + ERR_asprintf_error_data("name=%s", name); + return NULL; + } + + ret = a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); + if (ret == NULL) + return NULL; + + /* + * Validate what we have for sanity. + */ + + if (is_nc) { + struct x509_constraints_name *constraints_name = NULL; + + if (!x509_constraints_validate(ret, &constraints_name, NULL)) { + X509V3error(X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("name=%s", name); + goto err; + } + x509_constraints_name_free(constraints_name); + return ret; + } + + type = x509_constraints_general_to_bytes(ret, &bytes, &len); + CBS_init(&cbs, bytes, len); + switch (type) { + case GEN_DNS: + if (!x509_constraints_valid_sandns(&cbs)) { + X509V3error(X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("name=%s value='%.*s'", name, + (int)len, bytes); + goto err; + } + break; + case GEN_URI: + if (!x509_constraints_uri_host(bytes, len, NULL)) { + X509V3error(X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("name=%s value='%.*s'", name, + (int)len, bytes); + goto err; + } + break; + case GEN_EMAIL: + if (!x509_constraints_parse_mailbox(&cbs, NULL)) { + X509V3error(X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("name=%s value='%.*s'", name, + (int)len, bytes); + goto err; + } + break; + case GEN_IPADD: + if (len != 4 && len != 16) { + X509V3error(X509V3_R_BAD_IP_ADDRESS); + ERR_asprintf_error_data("name=%s len=%zu", name, len); + goto err; + } + break; + default: + break; + } + return ret; + err: + if (out == NULL) + GENERAL_NAME_free(ret); + return NULL; +} +LCRYPTO_ALIAS(v2i_GENERAL_NAME_ex); + +static int +do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) +{ + char *objtmp = NULL, *p; + int objlen; + + if (!(p = strchr(value, ';'))) + return 0; + if (!(gen->d.otherName = OTHERNAME_new())) + return 0; + /* Free this up because we will overwrite it. + * no need to free type_id because it is static + */ + ASN1_TYPE_free(gen->d.otherName->value); + if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) + return 0; + objlen = p - value; + objtmp = malloc(objlen + 1); + if (objtmp) { + strlcpy(objtmp, value, objlen + 1); + gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); + free(objtmp); + } else + gen->d.otherName->type_id = NULL; + if (!gen->d.otherName->type_id) + return 0; + return 1; +} + +static int +do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) +{ + int ret; + STACK_OF(CONF_VALUE) *sk; + X509_NAME *nm; + + if (!(nm = X509_NAME_new())) + return 0; + sk = X509V3_get_section(ctx, value); + if (!sk) { + X509V3error(X509V3_R_SECTION_NOT_FOUND); + ERR_asprintf_error_data("section=%s", value); + X509_NAME_free(nm); + return 0; + } + /* FIXME: should allow other character types... */ + ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); + if (!ret) + X509_NAME_free(nm); + gen->d.dirn = nm; + X509V3_section_free(ctx, sk); + + return ret; +} diff --git a/Libraries/libressl/crypto/x509/x509_asid.c b/Libraries/libressl/crypto/x509/x509_asid.c new file mode 100644 index 000000000..95b1acb1e --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_asid.c @@ -0,0 +1,1203 @@ +/* $OpenBSD: x509_asid.c,v 1.40 2023/04/19 12:30:09 jsg Exp $ */ +/* + * Contributed to the OpenSSL Project by the American Registry for + * Internet Numbers ("ARIN"). + */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +/* + * Implementation of RFC 3779 section 3.2. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "x509_local.h" + +#ifndef OPENSSL_NO_RFC3779 + +static const ASN1_TEMPLATE ASRange_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ASRange, min), + .field_name = "min", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ASRange, max), + .field_name = "max", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM ASRange_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ASRange_seq_tt, + .tcount = sizeof(ASRange_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ASRange), + .sname = "ASRange", +}; + +static const ASN1_TEMPLATE ASIdOrRange_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ASIdOrRange, u.id), + .field_name = "u.id", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ASIdOrRange, u.range), + .field_name = "u.range", + .item = &ASRange_it, + }, +}; + +const ASN1_ITEM ASIdOrRange_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(ASIdOrRange, type), + .templates = ASIdOrRange_ch_tt, + .tcount = sizeof(ASIdOrRange_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ASIdOrRange), + .sname = "ASIdOrRange", +}; + +static const ASN1_TEMPLATE ASIdentifierChoice_ch_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ASIdentifierChoice, u.inherit), + .field_name = "u.inherit", + .item = &ASN1_NULL_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(ASIdentifierChoice, u.asIdsOrRanges), + .field_name = "u.asIdsOrRanges", + .item = &ASIdOrRange_it, + }, +}; + +const ASN1_ITEM ASIdentifierChoice_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(ASIdentifierChoice, type), + .templates = ASIdentifierChoice_ch_tt, + .tcount = sizeof(ASIdentifierChoice_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ASIdentifierChoice), + .sname = "ASIdentifierChoice", +}; + +static const ASN1_TEMPLATE ASIdentifiers_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ASIdentifiers, asnum), + .field_name = "asnum", + .item = &ASIdentifierChoice_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(ASIdentifiers, rdi), + .field_name = "rdi", + .item = &ASIdentifierChoice_it, + }, +}; + +const ASN1_ITEM ASIdentifiers_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ASIdentifiers_seq_tt, + .tcount = sizeof(ASIdentifiers_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ASIdentifiers), + .sname = "ASIdentifiers", +}; + +ASRange * +d2i_ASRange(ASRange **a, const unsigned char **in, long len) +{ + return (ASRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ASRange_it); +} +LCRYPTO_ALIAS(d2i_ASRange); + +int +i2d_ASRange(ASRange *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASRange_it); +} +LCRYPTO_ALIAS(i2d_ASRange); + +ASRange * +ASRange_new(void) +{ + return (ASRange *)ASN1_item_new(&ASRange_it); +} +LCRYPTO_ALIAS(ASRange_new); + +void +ASRange_free(ASRange *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ASRange_it); +} +LCRYPTO_ALIAS(ASRange_free); + +ASIdOrRange * +d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, long len) +{ + return (ASIdOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ASIdOrRange_it); +} +LCRYPTO_ALIAS(d2i_ASIdOrRange); + +int +i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdOrRange_it); +} +LCRYPTO_ALIAS(i2d_ASIdOrRange); + +ASIdOrRange * +ASIdOrRange_new(void) +{ + return (ASIdOrRange *)ASN1_item_new(&ASIdOrRange_it); +} +LCRYPTO_ALIAS(ASIdOrRange_new); + +void +ASIdOrRange_free(ASIdOrRange *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ASIdOrRange_it); +} +LCRYPTO_ALIAS(ASIdOrRange_free); + +ASIdentifierChoice * +d2i_ASIdentifierChoice(ASIdentifierChoice **a, const unsigned char **in, + long len) +{ + return (ASIdentifierChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ASIdentifierChoice_it); +} +LCRYPTO_ALIAS(d2i_ASIdentifierChoice); + +int +i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifierChoice_it); +} +LCRYPTO_ALIAS(i2d_ASIdentifierChoice); + +ASIdentifierChoice * +ASIdentifierChoice_new(void) +{ + return (ASIdentifierChoice *)ASN1_item_new(&ASIdentifierChoice_it); +} +LCRYPTO_ALIAS(ASIdentifierChoice_new); + +void +ASIdentifierChoice_free(ASIdentifierChoice *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ASIdentifierChoice_it); +} +LCRYPTO_ALIAS(ASIdentifierChoice_free); + +ASIdentifiers * +d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, long len) +{ + return (ASIdentifiers *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ASIdentifiers_it); +} +LCRYPTO_ALIAS(d2i_ASIdentifiers); + +int +i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifiers_it); +} +LCRYPTO_ALIAS(i2d_ASIdentifiers); + +ASIdentifiers * +ASIdentifiers_new(void) +{ + return (ASIdentifiers *)ASN1_item_new(&ASIdentifiers_it); +} +LCRYPTO_ALIAS(ASIdentifiers_new); + +void +ASIdentifiers_free(ASIdentifiers *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ASIdentifiers_it); +} +LCRYPTO_ALIAS(ASIdentifiers_free); + +/* + * i2r method for an ASIdentifierChoice. + */ +static int +i2r_ASIdentifierChoice(BIO *out, ASIdentifierChoice *choice, int indent, + const char *msg) +{ + int i; + char *s; + if (choice == NULL) + return 1; + BIO_printf(out, "%*s%s:\n", indent, "", msg); + switch (choice->type) { + case ASIdentifierChoice_inherit: + BIO_printf(out, "%*sinherit\n", indent + 2, ""); + break; + case ASIdentifierChoice_asIdsOrRanges: + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); + i++) { + ASIdOrRange *aor = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + switch (aor->type) { + case ASIdOrRange_id: + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == + NULL) + return 0; + BIO_printf(out, "%*s%s\n", indent + 2, "", s); + free(s); + break; + case ASIdOrRange_range: + if ((s = i2s_ASN1_INTEGER(NULL, + aor->u.range->min)) == NULL) + return 0; + BIO_printf(out, "%*s%s-", indent + 2, "", s); + free(s); + if ((s = i2s_ASN1_INTEGER(NULL, + aor->u.range->max)) == NULL) + return 0; + BIO_printf(out, "%s\n", s); + free(s); + break; + default: + return 0; + } + } + break; + default: + return 0; + } + return 1; +} + +/* + * i2r method for an ASIdentifier extension. + */ +static int +i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out, + int indent) +{ + ASIdentifiers *asid = ext; + return (i2r_ASIdentifierChoice(out, asid->asnum, indent, + "Autonomous System Numbers") && + i2r_ASIdentifierChoice(out, asid->rdi, indent, + "Routing Domain Identifiers")); +} + +/* + * Sort comparison function for a sequence of ASIdOrRange elements. + */ +static int +ASIdOrRange_cmp(const ASIdOrRange *const *a_, const ASIdOrRange *const *b_) +{ + const ASIdOrRange *a = *a_, *b = *b_; + + /* XXX: these asserts need to be replaced */ + OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || + (a->type == ASIdOrRange_range && a->u.range != NULL && + a->u.range->min != NULL && a->u.range->max != NULL)); + + OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || + (b->type == ASIdOrRange_range && b->u.range != NULL && + b->u.range->min != NULL && b->u.range->max != NULL)); + + if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.id); + + if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { + int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); + return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, + b->u.range->max); + } + + if (a->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); + else + return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); +} + +/* + * Add an inherit element. + */ +int +X509v3_asid_add_inherit(ASIdentifiers *asid, int which) +{ + ASIdentifierChoice **choice; + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_inherit; + } + return (*choice)->type == ASIdentifierChoice_inherit; +} +LCRYPTO_ALIAS(X509v3_asid_add_inherit); + +/* + * Add an ID or range to an ASIdentifierChoice. + */ +int +X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min, + ASN1_INTEGER *max) +{ + ASIdentifierChoice **choice; + ASIdOrRange *aor; + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) + return 0; + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); + if ((*choice)->u.asIdsOrRanges == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_asIdsOrRanges; + } + if ((aor = ASIdOrRange_new()) == NULL) + return 0; + if (max == NULL) { + aor->type = ASIdOrRange_id; + aor->u.id = min; + } else { + aor->type = ASIdOrRange_range; + if ((aor->u.range = ASRange_new()) == NULL) + goto err; + ASN1_INTEGER_free(aor->u.range->min); + aor->u.range->min = min; + ASN1_INTEGER_free(aor->u.range->max); + aor->u.range->max = max; + } + if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) + goto err; + return 1; + + err: + ASIdOrRange_free(aor); + return 0; +} +LCRYPTO_ALIAS(X509v3_asid_add_id_or_range); + +/* + * Extract min and max values from an ASIdOrRange. + */ +static int +extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) +{ + switch (aor->type) { + case ASIdOrRange_id: + *min = aor->u.id; + *max = aor->u.id; + return 1; + case ASIdOrRange_range: + *min = aor->u.range->min; + *max = aor->u.range->max; + return 1; + } + + return 0; +} + +/* + * Check whether an ASIdentifierChoice is in canonical form. + */ +static int +ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + ASN1_INTEGER *orig; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Empty element or inheritance is canonical. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) + return 0; + + /* + * It's a list, check it. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, + i); + ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, + i + 1); + ASN1_INTEGER *a_min = NULL, + *a_max = NULL, + *b_min = NULL, + *b_max = + NULL; + + if (!extract_min_max(a, &a_min, &a_max) || + !extract_min_max(b, &b_min, &b_max)) + goto done; + + /* + * Punt misordered list, overlapping start, or inverted range. + */ + if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || + ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto done; + } + + if ((a_max_plus_one = + BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { + a_max_plus_one = orig; + X509V3error(ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * Punt if adjacent or overlapping. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) + goto done; + } + + /* + * Check for inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, + i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + if (!extract_min_max(a, &a_min, &a_max) || + ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + ret = 1; + + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Check whether an ASIdentifier extension is in canonical form. + */ +int +X509v3_asid_is_canonical(ASIdentifiers *asid) +{ + return (asid == NULL || + (ASIdentifierChoice_is_canonical(asid->asnum) && + ASIdentifierChoice_is_canonical(asid->rdi))); +} +LCRYPTO_ALIAS(X509v3_asid_is_canonical); + +/* + * Whack an ASIdentifierChoice into canonical form. + */ +static int +ASIdentifierChoice_canonize(ASIdentifierChoice *choice) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + ASN1_INTEGER *orig; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Nothing to do for empty element or inheritance. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + return 0; + } + + /* + * We have a non-empty list. Sort it. + */ + sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); + + /* + * Now check for errors and suboptimal encoding, rejecting the + * former and fixing the latter. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, + i); + ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, + i + 1); + ASN1_INTEGER *a_min = NULL, + *a_max = NULL, + *b_min = NULL, + *b_max = + NULL; + + if (!extract_min_max(a, &a_min, &a_max) || + !extract_min_max(b, &b_min, &b_max)) + goto done; + + /* + * Make sure we're properly sorted (paranoia). + */ + if (ASN1_INTEGER_cmp(a_min, b_min) > 0) + goto done; + + /* + * Punt inverted ranges. + */ + if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Check for overlaps. + */ + if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + goto done; + } + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto done; + } + + if ((a_max_plus_one = + BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { + a_max_plus_one = orig; + X509V3error(ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * If a and b are adjacent, merge them. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { + ASRange *r; + switch (a->type) { + case ASIdOrRange_id: + if ((r = calloc(1, sizeof(*r))) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto done; + } + r->min = a_min; + r->max = b_max; + a->type = ASIdOrRange_range; + a->u.range = r; + break; + case ASIdOrRange_range: + ASN1_INTEGER_free(a->u.range->max); + a->u.range->max = b_max; + break; + } + switch (b->type) { + case ASIdOrRange_id: + b->u.id = NULL; + break; + case ASIdOrRange_range: + b->u.range->max = NULL; + break; + } + ASIdOrRange_free(b); + (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, + i + 1); + i--; + continue; + } + } + + /* + * Check for final inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, + i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + if (!extract_min_max(a, &a_min, &a_max) || + ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + /* Paranoia */ + if (!ASIdentifierChoice_is_canonical(choice)) + goto done; + + ret = 1; + + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Whack an ASIdentifier extension into canonical form. + */ +int +X509v3_asid_canonize(ASIdentifiers *asid) +{ + if (asid == NULL) + return 1; + + if (!ASIdentifierChoice_canonize(asid->asnum)) + return 0; + + return ASIdentifierChoice_canonize(asid->rdi); +} +LCRYPTO_ALIAS(X509v3_asid_canonize); + +/* + * v2i method for an ASIdentifier extension. + */ +static void * +v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE)*values) +{ + ASN1_INTEGER *min = NULL, *max = NULL; + ASIdentifiers *asid = NULL; + int i; + + if ((asid = ASIdentifiers_new()) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0; + + /* + * Figure out whether this is an AS or an RDI. + */ + if (!name_cmp(val->name, "AS")) { + which = V3_ASID_ASNUM; + } else if (!name_cmp(val->name, "RDI")) { + which = V3_ASID_RDI; + } else { + X509V3error(X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + /* + * Handle inheritance. + */ + if (strcmp(val->value, "inherit") == 0) { + if (X509v3_asid_add_inherit(asid, which)) + continue; + X509V3error(X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + + /* + * Number, range, or mistake, pick it apart and figure out which + */ + i1 = strspn(val->value, "0123456789"); + if (val->value[i1] == '\0') { + is_range = 0; + } else { + is_range = 1; + i2 = i1 + strspn(val->value + i1, " \t"); + if (val->value[i2] != '-') { + X509V3error(X509V3_R_INVALID_ASNUMBER); + X509V3_conf_err(val); + goto err; + } + i2++; + i2 = i2 + strspn(val->value + i2, " \t"); + i3 = i2 + strspn(val->value + i2, "0123456789"); + if (val->value[i3] != '\0') { + X509V3error(X509V3_R_INVALID_ASRANGE); + X509V3_conf_err(val); + goto err; + } + } + + /* + * Syntax is ok, read and add it. + */ + if (!is_range) { + if (!X509V3_get_value_int(val, &min)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + char *s = strdup(val->value); + if (s == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + s[i1] = '\0'; + min = s2i_ASN1_INTEGER(NULL, s); + max = s2i_ASN1_INTEGER(NULL, s + i2); + free(s); + if (min == NULL || max == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + if (ASN1_INTEGER_cmp(min, max) > 0) { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + goto err; + } + } + if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + min = max = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!X509v3_asid_canonize(asid)) + goto err; + return asid; + + err: + ASIdentifiers_free(asid); + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); + return NULL; +} + +/* + * OpenSSL dispatch. + */ +const X509V3_EXT_METHOD v3_asid = { + .ext_nid = NID_sbgp_autonomousSysNum, + .ext_flags = 0, + .it = &ASIdentifiers_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_ASIdentifiers, + .i2r = i2r_ASIdentifiers, + .r2i = NULL, + .usr_data = NULL, +}; + +/* + * Figure out whether extension uses inheritance. + */ +int +X509v3_asid_inherits(ASIdentifiers *asid) +{ + if (asid == NULL) + return 0; + + if (asid->asnum != NULL) { + if (asid->asnum->type == ASIdentifierChoice_inherit) + return 1; + } + + if (asid->rdi != NULL) { + if (asid->rdi->type == ASIdentifierChoice_inherit) + return 1; + } + + return 0; +} +LCRYPTO_ALIAS(X509v3_asid_inherits); + +/* + * Figure out whether parent contains child. + */ +static int +asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) +{ + ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL; + int p, c; + + if (child == NULL || parent == child) + return 1; + + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_ASIdOrRange_num(child); c++) { + if (!extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, + &c_max)) + return 0; + for (;; p++) { + if (p >= sk_ASIdOrRange_num(parent)) + return 0; + if (!extract_min_max(sk_ASIdOrRange_value(parent, p), + &p_min, &p_max)) + return 0; + if (ASN1_INTEGER_cmp(p_max, c_max) < 0) + continue; + if (ASN1_INTEGER_cmp(p_min, c_min) > 0) + return 0; + break; + } + } + + return 1; +} + +/* + * Test whether child is a subset of parent. + */ +int +X509v3_asid_subset(ASIdentifiers *child, ASIdentifiers *parent) +{ + if (child == NULL || child == parent) + return 1; + + if (parent == NULL) + return 0; + + if (X509v3_asid_inherits(child) || X509v3_asid_inherits(parent)) + return 0; + + if (child->asnum != NULL) { + if (parent->asnum == NULL) + return 0; + + if (!asid_contains(parent->asnum->u.asIdsOrRanges, + child->asnum->u.asIdsOrRanges)) + return 0; + } + + if (child->rdi != NULL) { + if (parent->rdi == NULL) + return 0; + + if (!asid_contains(parent->rdi->u.asIdsOrRanges, + child->rdi->u.asIdsOrRanges)) + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(X509v3_asid_subset); + +/* + * Validation error handling via callback. + */ +#define validation_err(_err_) \ + do { \ + if (ctx != NULL) { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + ret = ctx->verify_cb(0, ctx); \ + } else { \ + ret = 0; \ + } \ + if (!ret) \ + goto done; \ + } while (0) + +/* + * Core code for RFC 3779 3.3 path validation. + */ +static int +asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, + ASIdentifiers *ext) +{ + ASIdOrRanges *child_as = NULL, *child_rdi = NULL; + int i, ret = 1, inherit_as = 0, inherit_rdi = 0; + X509 *x; + + /* We need a non-empty chain to test against. */ + if (sk_X509_num(chain) <= 0) + goto err; + /* We need either a store ctx or an extension to work with. */ + if (ctx == NULL && ext == NULL) + goto err; + /* If there is a store ctx, it needs a verify_cb. */ + if (ctx != NULL && ctx->verify_cb == NULL) + goto err; + + /* + * Figure out where to start. If we don't have an extension to check, + * (either extracted from the leaf or passed by the caller), we're done. + * Otherwise, check canonical form and set up for walking up the chain. + */ + if (ext != NULL) { + i = -1; + x = NULL; + if (!X509v3_asid_is_canonical(ext)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + } else { + i = 0; + x = sk_X509_value(chain, i); + if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) + goto done; + if ((ext = x->rfc3779_asid) == NULL) + goto done; + } + if (ext->asnum != NULL) { + switch (ext->asnum->type) { + case ASIdentifierChoice_inherit: + inherit_as = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_as = ext->asnum->u.asIdsOrRanges; + break; + } + } + if (ext->rdi != NULL) { + switch (ext->rdi->type) { + case ASIdentifierChoice_inherit: + inherit_rdi = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_rdi = ext->rdi->u.asIdsOrRanges; + break; + } + } + + /* + * Now walk up the chain. Extensions must be in canonical form, no + * cert may list resources that its parent doesn't list. + */ + for (i++; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + + if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (x->rfc3779_asid == NULL) { + if (child_as != NULL || child_rdi != NULL) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + continue; + } + if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_as = NULL; + inherit_as = 0; + } + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == + ASIdentifierChoice_asIdsOrRanges) { + if (inherit_as || + asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, + child_as)) { + child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; + inherit_as = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_rdi = NULL; + inherit_rdi = 0; + } + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { + if (inherit_rdi || + asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, + child_rdi)) { + child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; + inherit_rdi = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + + if (x == NULL) + goto err; + + if (x->rfc3779_asid != NULL) { + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + + done: + return ret; + + err: + if (ctx != NULL) + ctx->error = X509_V_ERR_UNSPECIFIED; + + return 0; +} + +#undef validation_err + +/* + * RFC 3779 3.3 path validation -- called from X509_verify_cert(). + */ +int +X509v3_asid_validate_path(X509_STORE_CTX *ctx) +{ + if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { + ctx->error = X509_V_ERR_UNSPECIFIED; + return 0; + } + return asid_validate_path_internal(ctx, ctx->chain, NULL); +} +LCRYPTO_ALIAS(X509v3_asid_validate_path); + +/* + * RFC 3779 3.3 path validation of an extension. + * Test whether chain covers extension. + */ +int +X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, + int allow_inheritance) +{ + if (ext == NULL) + return 1; + if (sk_X509_num(chain) <= 0) + return 0; + if (!allow_inheritance && X509v3_asid_inherits(ext)) + return 0; + return asid_validate_path_internal(NULL, chain, ext); +} +LCRYPTO_ALIAS(X509v3_asid_validate_resource_set); + +#endif /* OPENSSL_NO_RFC3779 */ diff --git a/Libraries/libressl/crypto/x509/x509_att.c b/Libraries/libressl/crypto/x509/x509_att.c new file mode 100644 index 000000000..0c9d55f74 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_att.c @@ -0,0 +1,413 @@ +/* $OpenBSD: x509_att.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "x509_local.h" + +int +X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) +{ + return sk_X509_ATTRIBUTE_num(x); +} +LCRYPTO_ALIAS(X509at_get_attr_count); + +int +X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509at_get_attr_by_OBJ(x, obj, lastpos)); +} +LCRYPTO_ALIAS(X509at_get_attr_by_NID); + +int +X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_ATTRIBUTE *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_ATTRIBUTE_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_ATTRIBUTE_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} +LCRYPTO_ALIAS(X509at_get_attr_by_OBJ); + +X509_ATTRIBUTE * +X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_ATTRIBUTE_value(x, loc); +} +LCRYPTO_ALIAS(X509at_get_attr); + +X509_ATTRIBUTE * +X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + X509_ATTRIBUTE *ret; + + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_ATTRIBUTE_delete(x, loc); + return (ret); +} +LCRYPTO_ALIAS(X509at_delete_attr); + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr) +{ + X509_ATTRIBUTE *new_attr = NULL; + STACK_OF(X509_ATTRIBUTE) *sk = NULL; + + if (x == NULL) { + X509error(ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + + if (*x == NULL) { + if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) + goto err; + } else + sk = *x; + + if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) + goto err2; + if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + +err: + X509error(ERR_R_MALLOC_FAILURE); +err2: + if (new_attr != NULL) + X509_ATTRIBUTE_free(new_attr); + if (sk != NULL && sk != *x) + sk_X509_ATTRIBUTE_free(sk); + return (NULL); +} +LCRYPTO_ALIAS(X509at_add1_attr); + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj, + int type, const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} +LCRYPTO_ALIAS(X509at_add1_attr_by_OBJ); + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, int nid, int type, + const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} +LCRYPTO_ALIAS(X509at_add1_attr_by_NID); + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, const char *attrname, + int type, const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} +LCRYPTO_ALIAS(X509at_add1_attr_by_txt); + +void * +X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, const ASN1_OBJECT *obj, + int lastpos, int type) +{ + int i; + X509_ATTRIBUTE *at; + + i = X509at_get_attr_by_OBJ(x, obj, lastpos); + if (i == -1) + return NULL; + if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) + return NULL; + at = X509at_get_attr(x, i); + if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) + return NULL; + return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); +} +LCRYPTO_ALIAS(X509at_get0_data_by_OBJ); + +X509_ATTRIBUTE * +X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype, + const void *data, int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509error(X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_NID); + +X509_ATTRIBUTE * +X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj, + int atrtype, const void *data, int len) +{ + X509_ATTRIBUTE *ret; + + if ((attr == NULL) || (*attr == NULL)) { + if ((ret = X509_ATTRIBUTE_new()) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret= *attr; + + if (!X509_ATTRIBUTE_set1_object(ret, obj)) + goto err; + if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) + goto err; + + if ((attr != NULL) && (*attr == NULL)) + *attr = ret; + return (ret); + +err: + if ((attr == NULL) || (ret != *attr)) + X509_ATTRIBUTE_free(ret); + return (NULL); +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_OBJ); + +X509_ATTRIBUTE * +X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const char *atrname, + int type, const unsigned char *bytes, int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; + + obj = OBJ_txt2obj(atrname, 0); + if (obj == NULL) { + X509error(X509_R_INVALID_FIELD_NAME); + ERR_asprintf_error_data("name=%s", atrname); + return (NULL); + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nattr; +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_txt); + +int +X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) +{ + if ((attr == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(attr->object); + attr->object = OBJ_dup(obj); + return attr->object != NULL; +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_object); + +int +X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, + int len) +{ + ASN1_TYPE *ttmp = NULL; + ASN1_STRING *stmp = NULL; + int atype = 0; + + if (!attr) + return 0; + if (attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if (!stmp) { + X509error(ERR_R_ASN1_LIB); + return 0; + } + atype = stmp->type; + } else if (len != -1){ + if (!(stmp = ASN1_STRING_type_new(attrtype))) + goto err; + if (!ASN1_STRING_set(stmp, data, len)) + goto err; + atype = attrtype; + } + /* + * This is a bit naughty because the attribute should really have + * at least one value but some types use and zero length SET and + * require this. + */ + if (attrtype == 0) { + ASN1_STRING_free(stmp); + return 1; + } + + if (!(ttmp = ASN1_TYPE_new())) + goto err; + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + goto err; + } else + ASN1_TYPE_set(ttmp, atype, stmp); + if (!sk_ASN1_TYPE_push(attr->set, ttmp)) + goto err; + return 1; + +err: + ASN1_TYPE_free(ttmp); + ASN1_STRING_free(stmp); + X509error(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_data); + +int +X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) +{ + if (attr == NULL) + return 0; + + return sk_ASN1_TYPE_num(attr->set); +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_count); + +ASN1_OBJECT * +X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) +{ + if (attr == NULL) + return (NULL); + return (attr->object); +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_object); + +void * +X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data) +{ + ASN1_TYPE *ttmp; + + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if (!ttmp) + return NULL; + if (atrtype != ASN1_TYPE_get(ttmp)){ + X509error(X509_R_WRONG_TYPE); + return NULL; + } + return ttmp->value.ptr; +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_data); + +ASN1_TYPE * +X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) +{ + if (attr == NULL) + return (NULL); + + return sk_ASN1_TYPE_value(attr->set, idx); +} +LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_type); diff --git a/Libraries/libressl/crypto/x509/x509_bcons.c b/Libraries/libressl/crypto/x509/x509_bcons.c new file mode 100644 index 000000000..a39ae0aae --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_bcons.c @@ -0,0 +1,203 @@ +/* $OpenBSD: x509_bcons.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist); +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_bcons = { + .ext_nid = NID_basic_constraints, + .ext_flags = 0, + .it = &BASIC_CONSTRAINTS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS, + .v2i = (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE BASIC_CONSTRAINTS_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(BASIC_CONSTRAINTS, ca), + .field_name = "ca", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(BASIC_CONSTRAINTS, pathlen), + .field_name = "pathlen", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM BASIC_CONSTRAINTS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = BASIC_CONSTRAINTS_seq_tt, + .tcount = sizeof(BASIC_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(BASIC_CONSTRAINTS), + .sname = "BASIC_CONSTRAINTS", +}; + + +BASIC_CONSTRAINTS * +d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len) +{ + return (BASIC_CONSTRAINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &BASIC_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(d2i_BASIC_CONSTRAINTS); + +int +i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &BASIC_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(i2d_BASIC_CONSTRAINTS); + +BASIC_CONSTRAINTS * +BASIC_CONSTRAINTS_new(void) +{ + return (BASIC_CONSTRAINTS *)ASN1_item_new(&BASIC_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(BASIC_CONSTRAINTS_new); + +void +BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &BASIC_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(BASIC_CONSTRAINTS_free); + + +static STACK_OF(CONF_VALUE) * +i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) *extlist) +{ + STACK_OF(CONF_VALUE) *free_extlist = NULL; + + if (extlist == NULL) { + if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + if (!X509V3_add_value_bool("CA", bcons->ca, &extlist)) + goto err; + if (!X509V3_add_value_int("pathlen", bcons->pathlen, &extlist)) + goto err; + + return extlist; + + err: + sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); + + return NULL; +} + +static BASIC_CONSTRAINTS * +v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + BASIC_CONSTRAINTS *bcons = NULL; + CONF_VALUE *val; + int i; + + if (!(bcons = BASIC_CONSTRAINTS_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "CA")) { + if (!X509V3_get_value_bool(val, &bcons->ca)) + goto err; + } else if (!strcmp(val->name, "pathlen")) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) + goto err; + } else { + X509V3error(X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + +err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/Libraries/libressl/crypto/x509/x509_bitst.c b/Libraries/libressl/crypto/x509/x509_bitst.c new file mode 100644 index 000000000..97c630d8b --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_bitst.c @@ -0,0 +1,220 @@ +/* $OpenBSD: x509_bitst.c,v 1.4 2023/04/21 06:11:56 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +static BIT_STRING_BITNAME ns_cert_type_table[] = { + {0, "SSL Client", "client"}, + {1, "SSL Server", "server"}, + {2, "S/MIME", "email"}, + {3, "Object Signing", "objsign"}, + {4, "Unused", "reserved"}, + {5, "SSL CA", "sslCA"}, + {6, "S/MIME CA", "emailCA"}, + {7, "Object Signing CA", "objCA"}, + {-1, NULL, NULL} +}; + +static BIT_STRING_BITNAME key_usage_type_table[] = { + {0, "Digital Signature", "digitalSignature"}, + {1, "Non Repudiation", "nonRepudiation"}, + {2, "Key Encipherment", "keyEncipherment"}, + {3, "Data Encipherment", "dataEncipherment"}, + {4, "Key Agreement", "keyAgreement"}, + {5, "Certificate Sign", "keyCertSign"}, + {6, "CRL Sign", "cRLSign"}, + {7, "Encipher Only", "encipherOnly"}, + {8, "Decipher Only", "decipherOnly"}, + {-1, NULL, NULL} +}; + +static BIT_STRING_BITNAME crl_reasons[] = { + {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, + {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, + {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, + {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"}, + {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, + {CRL_REASON_CESSATION_OF_OPERATION, "Cessation Of Operation", "cessationOfOperation"}, + {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, + {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, + {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"}, + {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_nscert = { + .ext_nid = NID_netscape_cert_type, + .ext_flags = 0, + .it = &ASN1_BIT_STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, + .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, + .i2r = NULL, + .r2i = NULL, + .usr_data = ns_cert_type_table, +}; + +const X509V3_EXT_METHOD v3_key_usage = { + .ext_nid = NID_key_usage, + .ext_flags = 0, + .it = &ASN1_BIT_STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, + .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, + .i2r = NULL, + .r2i = NULL, + .usr_data = key_usage_type_table, +}; + +const X509V3_EXT_METHOD v3_crl_reason = { + .ext_nid = NID_crl_reason, + .ext_flags = 0, + .it = &ASN1_ENUMERATED_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = crl_reasons, +}; + +STACK_OF(CONF_VALUE) * +i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *ret) +{ + BIT_STRING_BITNAME *bnam; + STACK_OF(CONF_VALUE) *free_ret = NULL; + + if (ret == NULL) { + if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + for (bnam = method->usr_data; bnam->lname != NULL; bnam++) { + if (!ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) + continue; + if (!X509V3_add_value(bnam->lname, NULL, &ret)) + goto err; + } + + return ret; + + err: + sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); + + return NULL; +} +LCRYPTO_ALIAS(i2v_ASN1_BIT_STRING); + +ASN1_BIT_STRING * +v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *val; + ASN1_BIT_STRING *bs; + int i; + BIT_STRING_BITNAME *bnam; + + if (!(bs = ASN1_BIT_STRING_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, val->name) || + !strcmp(bnam->lname, val->name) ) { + if (!ASN1_BIT_STRING_set_bit(bs, + bnam->bitnum, 1)) { + X509V3error(ERR_R_MALLOC_FAILURE); + ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + X509V3error(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} +LCRYPTO_ALIAS(v2i_ASN1_BIT_STRING); diff --git a/Libraries/libressl/crypto/x509/x509_cmp.c b/Libraries/libressl/crypto/x509/x509_cmp.c new file mode 100644 index 000000000..3ee4fd4a5 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_cmp.c @@ -0,0 +1,425 @@ +/* $OpenBSD: x509_cmp.c,v 1.42 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "evp_local.h" +#include "x509_local.h" + +int +X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) +{ + int i; + X509_CINF *ai, *bi; + + ai = a->cert_info; + bi = b->cert_info; + i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); + if (i) + return (i); + return (X509_NAME_cmp(ai->issuer, bi->issuer)); +} +LCRYPTO_ALIAS(X509_issuer_and_serial_cmp); + +#ifndef OPENSSL_NO_MD5 +unsigned long +X509_issuer_and_serial_hash(X509 *a) +{ + unsigned long ret = 0; + EVP_MD_CTX ctx; + unsigned char md[16]; + char *f; + + EVP_MD_CTX_init(&ctx); + f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); + if (f == NULL) + goto err; + if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f))) + goto err; + free(f); + f = NULL; + if (!EVP_DigestUpdate(&ctx, + (unsigned char *)a->cert_info->serialNumber->data, + (unsigned long)a->cert_info->serialNumber->length)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL)) + goto err; + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + +err: + EVP_MD_CTX_cleanup(&ctx); + free(f); + return (ret); +} +LCRYPTO_ALIAS(X509_issuer_and_serial_hash); +#endif + +int +X509_issuer_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); +} +LCRYPTO_ALIAS(X509_issuer_name_cmp); + +int +X509_subject_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); +} +LCRYPTO_ALIAS(X509_subject_name_cmp); + +int +X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) +{ + return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); +} +LCRYPTO_ALIAS(X509_CRL_cmp); + +#ifndef OPENSSL_NO_SHA +int +X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return memcmp(a->hash, b->hash, X509_CRL_HASH_LEN); +} +LCRYPTO_ALIAS(X509_CRL_match); +#endif + +X509_NAME * +X509_get_issuer_name(const X509 *a) +{ + return (a->cert_info->issuer); +} +LCRYPTO_ALIAS(X509_get_issuer_name); + +unsigned long +X509_issuer_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->issuer)); +} +LCRYPTO_ALIAS(X509_issuer_name_hash); + +#ifndef OPENSSL_NO_MD5 +unsigned long +X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} +LCRYPTO_ALIAS(X509_issuer_name_hash_old); +#endif + +X509_NAME * +X509_get_subject_name(const X509 *a) +{ + return (a->cert_info->subject); +} +LCRYPTO_ALIAS(X509_get_subject_name); + +ASN1_INTEGER * +X509_get_serialNumber(X509 *a) +{ + return (a->cert_info->serialNumber); +} +LCRYPTO_ALIAS(X509_get_serialNumber); + +const ASN1_INTEGER * +X509_get0_serialNumber(const X509 *a) +{ + return (a->cert_info->serialNumber); +} +LCRYPTO_ALIAS(X509_get0_serialNumber); + +unsigned long +X509_subject_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->subject)); +} +LCRYPTO_ALIAS(X509_subject_name_hash); + +#ifndef OPENSSL_NO_MD5 +unsigned long +X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} +LCRYPTO_ALIAS(X509_subject_name_hash_old); +#endif + +#ifndef OPENSSL_NO_SHA +/* Compare two certificates: they must be identical for + * this to work. NB: Although "cmp" operations are generally + * prototyped to take "const" arguments (eg. for use in + * STACKs), the way X509 handling is - these operations may + * involve ensuring the hashes are up-to-date and ensuring + * certain cert information is cached. So this is the point + * where the "depth-first" constification tree has to halt + * with an evil cast. + */ +int +X509_cmp(const X509 *a, const X509 *b) +{ + /* ensure hash is valid */ + X509_check_purpose((X509 *)a, -1, 0); + X509_check_purpose((X509 *)b, -1, 0); + + return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN); +} +LCRYPTO_ALIAS(X509_cmp); +#endif + +int +X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) +{ + int ret; + + /* Ensure canonical encoding is present and up to date */ + if (!a->canon_enc || a->modified) { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) + return -2; + } + if (!b->canon_enc || b->modified) { + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) + return -2; + } + ret = a->canon_enclen - b->canon_enclen; + if (ret) + return ret; + return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); +} +LCRYPTO_ALIAS(X509_NAME_cmp); + +unsigned long +X509_NAME_hash(X509_NAME *x) +{ + unsigned long ret = 0; + unsigned char md[SHA_DIGEST_LENGTH]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), + NULL)) + return 0; + + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + return (ret); +} +LCRYPTO_ALIAS(X509_NAME_hash); + + +#ifndef OPENSSL_NO_MD5 +/* I now DER encode the name and hash it. Since I cache the DER encoding, + * this is reasonably efficient. */ + +unsigned long +X509_NAME_hash_old(X509_NAME *x) +{ + EVP_MD_CTX md_ctx; + unsigned long ret = 0; + unsigned char md[16]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + EVP_MD_CTX_init(&md_ctx); + if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) && + EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) && + EVP_DigestFinal_ex(&md_ctx, md, NULL)) + ret = (((unsigned long)md[0]) | + ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | + ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + EVP_MD_CTX_cleanup(&md_ctx); + + return (ret); +} +LCRYPTO_ALIAS(X509_NAME_hash_old); +#endif + +/* Search a stack of X509 for a match */ +X509 * +X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial) +{ + int i; + X509_CINF cinf; + X509 x, *x509 = NULL; + + if (!sk) + return NULL; + + x.cert_info = &cinf; + cinf.serialNumber = serial; + cinf.issuer = name; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_issuer_and_serial_cmp(x509, &x) == 0) + return (x509); + } + return (NULL); +} +LCRYPTO_ALIAS(X509_find_by_issuer_and_serial); + +X509 * +X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) +{ + X509 *x509; + int i; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) + return (x509); + } + return (NULL); +} +LCRYPTO_ALIAS(X509_find_by_subject); + +EVP_PKEY * +X509_get_pubkey(X509 *x) +{ + if (x == NULL || x->cert_info == NULL) + return (NULL); + return (X509_PUBKEY_get(x->cert_info->key)); +} +LCRYPTO_ALIAS(X509_get_pubkey); + +EVP_PKEY * +X509_get0_pubkey(const X509 *x) +{ + if (x == NULL || x->cert_info == NULL) + return (NULL); + return (X509_PUBKEY_get0(x->cert_info->key)); +} +LCRYPTO_ALIAS(X509_get0_pubkey); + +ASN1_BIT_STRING * +X509_get0_pubkey_bitstr(const X509 *x) +{ + if (!x) + return NULL; + return x->cert_info->key->public_key; +} +LCRYPTO_ALIAS(X509_get0_pubkey_bitstr); + +int +X509_check_private_key(const X509 *x, const EVP_PKEY *k) +{ + const EVP_PKEY *xk; + int ret; + + xk = X509_get0_pubkey(x); + + if (xk) + ret = EVP_PKEY_cmp(xk, k); + else + ret = -2; + + switch (ret) { + case 1: + break; + case 0: + X509error(X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509error(X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + X509error(X509_R_UNKNOWN_KEY_TYPE); + } + if (ret > 0) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_check_private_key); + +/* + * Not strictly speaking an "up_ref" as a STACK doesn't have a reference + * count but it has the same effect by duping the STACK and upping the ref of + * each X509 structure. + */ +STACK_OF(X509) * +X509_chain_up_ref(STACK_OF(X509) *chain) +{ + STACK_OF(X509) *ret; + size_t i; + + ret = sk_X509_dup(chain); + for (i = 0; i < sk_X509_num(ret); i++) + X509_up_ref(sk_X509_value(ret, i)); + + return ret; +} +LCRYPTO_ALIAS(X509_chain_up_ref); diff --git a/Libraries/libressl/crypto/x509/x509_conf.c b/Libraries/libressl/crypto/x509/x509_conf.c new file mode 100644 index 000000000..189bf6440 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_conf.c @@ -0,0 +1,591 @@ +/* $OpenBSD: x509_conf.c,v 1.5 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* extension creation utilities */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "x509_local.h" + +static int v3_check_critical(const char **value); +static int v3_check_generic(const char **value); +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, const char *value); +static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, + int crit, int type, X509V3_CTX *ctx); +static char *conf_lhash_get_string(void *db, const char *section, + const char *value); +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, + const char *section); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, + int crit, void *ext_struc); +static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, + long *ext_len); + +/* CONF *conf: Config file */ +/* char *name: Name */ +/* char *value: Value */ +X509_EXTENSION * +X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value) +{ + int crit; + int ext_type; + X509_EXTENSION *ret; + + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(name, value, crit, ext_type, ctx); + ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + if (!ret) { + X509V3error(X509V3_R_ERROR_IN_EXTENSION); + ERR_asprintf_error_data("name=%s, value=%s", name, value); + } + return ret; +} +LCRYPTO_ALIAS(X509V3_EXT_nconf); + +/* CONF *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION * +X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value) +{ + int crit; + int ext_type; + + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(OBJ_nid2sn(ext_nid), + value, crit, ext_type, ctx); + return do_ext_nconf(conf, ctx, ext_nid, crit, value); +} +LCRYPTO_ALIAS(X509V3_EXT_nconf_nid); + +/* CONF *conf: Config file */ +/* char *value: Value */ +static X509_EXTENSION * +do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, + const char *value) +{ + const X509V3_EXT_METHOD *method; + X509_EXTENSION *ext; + void *ext_struc; + + if (ext_nid == NID_undef) { + X509V3error(X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3error(X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + /* Now get internal extension representation based on type */ + if (method->v2i) { + STACK_OF(CONF_VALUE) *nval; + + if (*value == '@') + nval = NCONF_get_section(conf, value + 1); + else + nval = X509V3_parse_list(value); + if (sk_CONF_VALUE_num(nval) <= 0) { + X509V3error(X509V3_R_INVALID_EXTENSION_STRING); + ERR_asprintf_error_data("name=%s,section=%s", + OBJ_nid2sn(ext_nid), value); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + return NULL; + } + ext_struc = method->v2i(method, ctx, nval); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + } else if (method->s2i) { + ext_struc = method->s2i(method, ctx, value); + } else if (method->r2i) { + if (!ctx->db || !ctx->db_meth) { + X509V3error(X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + ext_struc = method->r2i(method, ctx, value); + } else { + X509V3error(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); + ERR_asprintf_error_data("name=%s", OBJ_nid2sn(ext_nid)); + return NULL; + } + if (ext_struc == NULL) + return NULL; + + ext = do_ext_i2d(method, ext_nid, crit, ext_struc); + if (method->it) + ASN1_item_free(ext_struc, method->it); + else + method->ext_free(ext_struc); + return ext; +} + +static X509_EXTENSION * +do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, + void *ext_struc) +{ + unsigned char *ext_der; + int ext_len; + ASN1_OCTET_STRING *ext_oct = NULL; + X509_EXTENSION *ext; + + /* Convert internal representation to DER */ + if (method->it) { + ext_der = NULL; + ext_len = ASN1_item_i2d(ext_struc, &ext_der, + method->it); + if (ext_len < 0) + goto merr; + } else { + unsigned char *p; + ext_len = method->i2d(ext_struc, NULL); + if (!(ext_der = malloc(ext_len))) + goto merr; + p = ext_der; + method->i2d(ext_struc, &p); + } + if (!(ext_oct = ASN1_OCTET_STRING_new())) + goto merr; + ext_oct->data = ext_der; + ext_oct->length = ext_len; + + ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + if (!ext) + goto merr; + ASN1_OCTET_STRING_free(ext_oct); + + return ext; + +merr: + ASN1_OCTET_STRING_free(ext_oct); + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + +} + +/* Given an internal structure, nid and critical flag create an extension */ + +X509_EXTENSION * +X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) +{ + const X509V3_EXT_METHOD *method; + + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3error(X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + return do_ext_i2d(method, ext_nid, crit, ext_struc); +} +LCRYPTO_ALIAS(X509V3_EXT_i2d); + +/* Check the extension string for critical flag */ +static int +v3_check_critical(const char **value) +{ + const char *p = *value; + + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) + return 0; + p += 9; + while (isspace((unsigned char)*p)) p++; + *value = p; + return 1; +} + +/* Check extension string for generic extension and return the type */ +static int +v3_check_generic(const char **value) +{ + int gen_type = 0; + const char *p = *value; + + if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { + p += 4; + gen_type = 1; + } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { + p += 5; + gen_type = 2; + } else + return 0; + + while (isspace((unsigned char)*p)) + p++; + *value = p; + return gen_type; +} + +/* Create a generic extension: for now just handle DER type */ +static X509_EXTENSION * +v3_generic_extension(const char *ext, const char *value, int crit, int gen_type, + X509V3_CTX *ctx) +{ + unsigned char *ext_der = NULL; + long ext_len = 0; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + + if (!(obj = OBJ_txt2obj(ext, 0))) { + X509V3error(X509V3_R_EXTENSION_NAME_ERROR); + ERR_asprintf_error_data("name=%s", ext); + goto err; + } + + if (gen_type == 1) + ext_der = string_to_hex(value, &ext_len); + else if (gen_type == 2) + ext_der = generic_asn1(value, ctx, &ext_len); + else { + ERR_asprintf_error_data("Unexpected generic extension type %d", gen_type); + goto err; + } + + if (ext_der == NULL) { + X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); + ERR_asprintf_error_data("value=%s", value); + goto err; + } + + if (!(oct = ASN1_OCTET_STRING_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + + oct->data = ext_der; + oct->length = ext_len; + ext_der = NULL; + + extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); + +err: + ASN1_OBJECT_free(obj); + ASN1_OCTET_STRING_free(oct); + free(ext_der); + return extension; +} + +static unsigned char * +generic_asn1(const char *value, X509V3_CTX *ctx, long *ext_len) +{ + ASN1_TYPE *typ; + unsigned char *ext_der = NULL; + + typ = ASN1_generate_v3(value, ctx); + if (typ == NULL) + return NULL; + *ext_len = i2d_ASN1_TYPE(typ, &ext_der); + ASN1_TYPE_free(typ); + return ext_der; +} + +/* This is the main function: add a bunch of extensions based on a config file + * section to an extension STACK. + */ + +int +X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk) +{ + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + CONF_VALUE *val; + int i; + + if (!(nval = NCONF_get_section(conf, section))) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) + return 0; + if (sk) + X509v3_add_ext(sk, ext, -1); + X509_EXTENSION_free(ext); + } + return 1; +} +LCRYPTO_ALIAS(X509V3_EXT_add_nconf_sk); + +/* Convenience functions to add extensions to a certificate, CRL and request */ + +int +X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + + if (cert) + sk = &cert->cert_info->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} +LCRYPTO_ALIAS(X509V3_EXT_add_nconf); + +/* Same as above but for a CRL */ + +int +X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + + if (crl) + sk = &crl->crl->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} +LCRYPTO_ALIAS(X509V3_EXT_CRL_add_nconf); + +/* Add extensions to certificate request */ + +int +X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req) +{ + STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; + int i; + + if (req) + sk = &extlist; + i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); + if (!i || !sk) + return i; + i = X509_REQ_add_extensions(req, extlist); + sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); + return i; +} +LCRYPTO_ALIAS(X509V3_EXT_REQ_add_nconf); + +/* Config database functions */ + +char * +X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { + X509V3error(X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + return ctx->db_meth->get_string(ctx->db, name, section); +} +LCRYPTO_ALIAS(X509V3_get_string); + +STACK_OF(CONF_VALUE) * +X509V3_get_section(X509V3_CTX *ctx, const char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { + X509V3error(X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + return ctx->db_meth->get_section(ctx->db, section); +} +LCRYPTO_ALIAS(X509V3_get_section); + +void +X509V3_string_free(X509V3_CTX *ctx, char *str) +{ + if (!str) + return; + if (ctx->db_meth->free_string) + ctx->db_meth->free_string(ctx->db, str); +} +LCRYPTO_ALIAS(X509V3_string_free); + +void +X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) +{ + if (!section) + return; + if (ctx->db_meth->free_section) + ctx->db_meth->free_section(ctx->db, section); +} +LCRYPTO_ALIAS(X509V3_section_free); + +static char * +nconf_get_string(void *db, const char *section, const char *value) +{ + return NCONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) * +nconf_get_section(void *db, const char *section) +{ + return NCONF_get_section(db, section); +} + +static X509V3_CONF_METHOD nconf_method = { + nconf_get_string, + nconf_get_section, + NULL, + NULL +}; + +void +X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) +{ + ctx->db_meth = &nconf_method; + ctx->db = conf; +} +LCRYPTO_ALIAS(X509V3_set_nconf); + +void +X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, + X509_CRL *crl, int flags) +{ + ctx->issuer_cert = issuer; + ctx->subject_cert = subj; + ctx->crl = crl; + ctx->subject_req = req; + ctx->flags = flags; +} +LCRYPTO_ALIAS(X509V3_set_ctx); + +/* Old conf compatibility functions */ + +X509_EXTENSION * +X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *name, + const char *value) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf(&ctmp, ctx, name, value); +} +LCRYPTO_ALIAS(X509V3_EXT_conf); + +/* LHASH *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION * +X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, + const char *value) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); +} +LCRYPTO_ALIAS(X509V3_EXT_conf_nid); + +static char * +conf_lhash_get_string(void *db, const char *section, const char *value) +{ + return CONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) * +conf_lhash_get_section(void *db, const char *section) +{ + return CONF_get_section(db, section); +} + +static X509V3_CONF_METHOD conf_lhash_method = { + conf_lhash_get_string, + conf_lhash_get_section, + NULL, + NULL +}; + +void +X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) +{ + ctx->db_meth = &conf_lhash_method; + ctx->db = lhash; +} +LCRYPTO_ALIAS(X509V3_set_conf_lhash); + +int +X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509 *cert) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); +} +LCRYPTO_ALIAS(X509V3_EXT_add_conf); + +/* Same as above but for a CRL */ + +int +X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); +} +LCRYPTO_ALIAS(X509V3_EXT_CRL_add_conf); + +/* Add extensions to certificate request */ + +int +X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); +} +LCRYPTO_ALIAS(X509V3_EXT_REQ_add_conf); diff --git a/Libraries/libressl/crypto/x509/x509_constraints.c b/Libraries/libressl/crypto/x509/x509_constraints.c new file mode 100644 index 000000000..0773d2ba7 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_constraints.c @@ -0,0 +1,1294 @@ +/* $OpenBSD: x509_constraints.c,v 1.32 2023/09/29 15:53:59 beck Exp $ */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "bytestring.h" +#include "x509_internal.h" + +/* RFC 2821 section 4.5.3.1 */ +#define LOCAL_PART_MAX_LEN (size_t)64 +#define DOMAIN_PART_MAX_LEN (size_t)255 +#define MAX_IP_ADDRESS_LENGTH (size_t)46 + +static int +cbs_is_ip_address(CBS *cbs, int *is_ip) +{ + struct sockaddr_in6 sin6; + struct sockaddr_in sin4; + char *name = NULL; + + *is_ip = 0; + if (CBS_len(cbs) > MAX_IP_ADDRESS_LENGTH) + return 1; + if (!CBS_strdup(cbs, &name)) + return 0; + if (inet_pton(AF_INET, name, &sin4) == 1 || + inet_pton(AF_INET6, name, &sin6) == 1) + *is_ip = 1; + + free(name); + return 1; +} + +struct x509_constraints_name * +x509_constraints_name_new(void) +{ + return (calloc(1, sizeof(struct x509_constraints_name))); +} + +void +x509_constraints_name_clear(struct x509_constraints_name *name) +{ + free(name->name); + free(name->local); + free(name->der); + memset(name, 0, sizeof(*name)); +} + +void +x509_constraints_name_free(struct x509_constraints_name *name) +{ + if (name == NULL) + return; + x509_constraints_name_clear(name); + free(name); +} + +struct x509_constraints_name * +x509_constraints_name_dup(struct x509_constraints_name *name) +{ + struct x509_constraints_name *new; + + if ((new = x509_constraints_name_new()) == NULL) + goto err; + new->type = name->type; + new->af = name->af; + new->der_len = name->der_len; + if (name->der_len > 0) { + if ((new->der = malloc(name->der_len)) == NULL) + goto err; + memcpy(new->der, name->der, name->der_len); + } + if (name->name != NULL && (new->name = strdup(name->name)) == NULL) + goto err; + if (name->local != NULL && (new->local = strdup(name->local)) == NULL) + goto err; + memcpy(new->address, name->address, sizeof(name->address)); + return new; + err: + x509_constraints_name_free(new); + return NULL; +} + +struct x509_constraints_names * +x509_constraints_names_new(size_t names_max) +{ + struct x509_constraints_names *new; + + if ((new = calloc(1, sizeof(struct x509_constraints_names))) == NULL) + return NULL; + + new->names_max = names_max; + + return new; +} + +void +x509_constraints_names_clear(struct x509_constraints_names *names) +{ + size_t i; + + for (i = 0; i < names->names_count; i++) + x509_constraints_name_free(names->names[i]); + free(names->names); + memset(names, 0, sizeof(*names)); +} + +void +x509_constraints_names_free(struct x509_constraints_names *names) +{ + if (names == NULL) + return; + + x509_constraints_names_clear(names); + free(names); +} + +int +x509_constraints_names_add(struct x509_constraints_names *names, + struct x509_constraints_name *name) +{ + if (names->names_count >= names->names_max) + return 0; + if (names->names_count == names->names_len) { + struct x509_constraints_name **tmp; + if ((tmp = recallocarray(names->names, names->names_len, + names->names_len + 32, sizeof(*tmp))) == NULL) + return 0; + names->names_len += 32; + names->names = tmp; + } + names->names[names->names_count] = name; + names->names_count++; + return 1; +} + +struct x509_constraints_names * +x509_constraints_names_dup(struct x509_constraints_names *names) +{ + struct x509_constraints_names *new = NULL; + struct x509_constraints_name *name = NULL; + size_t i; + + if (names == NULL) + return NULL; + + if ((new = x509_constraints_names_new(names->names_max)) == NULL) + goto err; + + for (i = 0; i < names->names_count; i++) { + if ((name = x509_constraints_name_dup(names->names[i])) == NULL) + goto err; + if (!x509_constraints_names_add(new, name)) + goto err; + } + + return new; + err: + x509_constraints_names_free(new); + x509_constraints_name_free(name); + return NULL; +} + +/* + * Validate that the name contains only a hostname consisting of RFC + * 5890 compliant A-labels (see RFC 6066 section 3). This is more + * permissive to allow for a leading '.' for a subdomain based + * constraint, as well as allowing for '_' which is commonly accepted + * by nonconformant DNS implementations. + * + * if "wildcards" is set it allows '*' to occur in the string at the end of a + * component. + */ +static int +x509_constraints_valid_domain_internal(CBS *cbs, int wildcards) +{ + int first, component = 0; + uint8_t prev, c = 0; + size_t i, len; + CBS copy; + + CBS_dup(cbs, ©); + + len = CBS_len(cbs); + + if (len > DOMAIN_PART_MAX_LEN) + return 0; + for (i = 0; i < len; i++) { + prev = c; + if (!CBS_get_u8(©, &c)) + return 0; + + first = (i == 0); + + /* Everything has to be ASCII, with no NUL byte */ + if (!isascii(c) || c == '\0') + return 0; + /* It must be alphanumeric, a '-', '.', '_' or '*' */ + if (!isalnum(c) && c != '-' && c != '.' && c != '_' && c != '*') + return 0; + + /* if it is a '*', fail if not wildcards */ + if (!wildcards && c == '*') + return 0; + + /* '-' must not start a component or be at the end. */ + if (c == '-' && (component == 0 || i == len - 1)) + return 0; + + /* + * '.' must not be at the end. It may be first overall + * but must not otherwise start a component. + */ + if (c == '.' && ((component == 0 && !first) || i == len - 1)) + return 0; + + if (c == '.') { + /* Components can not end with a dash. */ + if (prev == '-') + return 0; + /* Start new component */ + component = 0; + continue; + } + /* + * Wildcards can only occur at the end of a component. + * c*.com is valid, c*c.com is not. + */ + if (prev == '*') + return 0; + + /* Components must be 63 chars or less. */ + if (++component > 63) + return 0; + } + + return 1; +} + +int +x509_constraints_valid_host(CBS *cbs, int permit_ip) +{ + uint8_t first; + int is_ip; + + if (!CBS_peek_u8(cbs, &first)) + return 0; + if (first == '.') + return 0; /* leading . not allowed in a host name or IP */ + if (!permit_ip) { + if (!cbs_is_ip_address(cbs, &is_ip)) + return 0; + if (is_ip) + return 0; + } + + return x509_constraints_valid_domain_internal(cbs, 0); +} + +int +x509_constraints_valid_sandns(CBS *cbs) +{ + uint8_t first; + + if (!CBS_peek_u8(cbs, &first)) + return 0; + if (first == '.') + return 0; /* leading . not allowed in a SAN DNS name */ + /* + * A domain may not be less than two characters, so you + * can't wildcard a single domain of less than that + */ + if (CBS_len(cbs) < 4 && first == '*') + return 0; + + return x509_constraints_valid_domain_internal(cbs, 1); +} + +static inline int +local_part_ok(char c) +{ + return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || c == '!' || c == '#' || c == '$' || + c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' || + c == '-' || c == '/' || c == '=' || c == '?' || c == '^' || + c == '_' || c == '`' || c == '{' || c == '|' || c == '}' || + c == '~' || c == '.'); +} + +/* + * Parse "candidate" as an RFC 2821 mailbox. + * Returns 0 if candidate is not a valid mailbox or if an error occurs. + * Returns 1 if candidate is a mailbox and adds newly allocated + * local and domain parts of the mailbox to "name->local" and name->name" + */ +int +x509_constraints_parse_mailbox(CBS *candidate, + struct x509_constraints_name *name) +{ + char working[DOMAIN_PART_MAX_LEN + 1] = { 0 }; + char *candidate_local = NULL; + char *candidate_domain = NULL; + CBS domain_cbs; + size_t i, len, wi = 0; + int accept = 0; + int quoted = 0; + CBS copy; + + /* XXX This should not be necessary - revisit and remove */ + if (candidate == NULL) + return 0; + + CBS_dup(candidate, ©); + + if ((len = CBS_len(©)) == 0) + return 0; + + /* It can't be bigger than the local part, domain part and the '@' */ + if (len > LOCAL_PART_MAX_LEN + DOMAIN_PART_MAX_LEN + 1) + return 0; + + for (i = 0; i < len; i++) { + char c; + if (!CBS_get_u8(©, &c)) + goto bad; + /* non ascii, cr, lf, or nul is never allowed */ + if (!isascii(c) || c == '\r' || c == '\n' || c == '\0') + goto bad; + if (i == 0) { + /* local part is quoted part */ + if (c == '"') + quoted = 1; + /* can not start with a . */ + if (c == '.') + goto bad; + } + if (accept) { + if (wi >= DOMAIN_PART_MAX_LEN) + goto bad; + working[wi++] = c; + accept = 0; + continue; + } + if (candidate_local != NULL) { + /* We are looking for the domain part */ + if (wi >= DOMAIN_PART_MAX_LEN) + goto bad; + working[wi++] = c; + if (i == len - 1) { + if (wi == 0) + goto bad; + if (candidate_domain != NULL) + goto bad; + candidate_domain = strdup(working); + if (candidate_domain == NULL) + goto bad; + } + continue; + } + /* We are looking for the local part */ + if (wi >= LOCAL_PART_MAX_LEN) + break; + + if (quoted) { + if (c == '\\') { + accept = 1; + continue; + } + if (c == '"' && i != 0) { + uint8_t next; + /* end the quoted part. @ must be next */ + if (!CBS_peek_u8(©, &next)) + goto bad; + if (next != '@') + goto bad; + quoted = 0; + } + /* + * XXX Go strangely permits sp but forbids ht + * mimic that for now + */ + if (c == 9) + goto bad; + if (wi >= LOCAL_PART_MAX_LEN) + goto bad; + working[wi++] = c; + continue; /* all's good inside our quoted string */ + } + if (c == '@') { + if (wi == 0) + goto bad; + if (candidate_local != NULL) + goto bad; + candidate_local = strdup(working); + if (candidate_local == NULL) + goto bad; + memset(working, 0, sizeof(working)); + wi = 0; + continue; + } + if (c == '\\') { + uint8_t next; + /* + * RFC 2821 hints these can happen outside of + * quoted string. Don't include the \ but + * next character must be ok. + */ + if (!CBS_peek_u8(©, &next)) + goto bad; + if (!local_part_ok(next)) + goto bad; + accept = 1; + } + if (!local_part_ok(c)) + goto bad; + if (wi >= LOCAL_PART_MAX_LEN) + goto bad; + working[wi++] = c; + } + if (candidate_local == NULL || candidate_domain == NULL) + goto bad; + CBS_init(&domain_cbs, candidate_domain, strlen(candidate_domain)); + if (!x509_constraints_valid_host(&domain_cbs, 0)) + goto bad; + + if (name != NULL) { + name->local = candidate_local; + name->name = candidate_domain; + name->type = GEN_EMAIL; + } else { + free(candidate_local); + free(candidate_domain); + } + return 1; + bad: + free(candidate_local); + free(candidate_domain); + return 0; +} + +int +x509_constraints_valid_domain_constraint(CBS *cbs) +{ + uint8_t first; + + if (CBS_len(cbs) == 0) + return 1; /* empty constraints match */ + + /* + * A domain may not be less than two characters, so you + * can't match a single domain of less than that + */ + if (CBS_len(cbs) < 3) { + if (!CBS_peek_u8(cbs, &first)) + return 0; + if (first == '.') + return 0; + } + return x509_constraints_valid_domain_internal(cbs, 0); +} + +/* + * Extract the host part of a URI. On failure to parse a valid host part of the + * URI, 0 is returned indicating an invalid URI. If the host part parses as + * valid, or is not present, 1 is returned indicating a possibly valid URI. + * + * In the case of a valid URI, *hostpart will be set to a copy of the host part + * of the URI, or the empty string if no URI is present. If memory allocation + * fails *hostpart will be set to NULL, even though we returned 1. It is the + * caller's responsibility to indicate an error for memory allocation failure, + * and the callers responsibility to free *hostpart. + * + * RFC 3986: + * the authority part of a uri starts with // and is terminated with + * the next '/', '?', '#' or end of the URI. + * + * The authority itself contains [userinfo '@'] host [: port] + * + * so the host starts at the start or after the '@', and ends + * with end of URI, '/', '?', "#', or ':'. + */ +int +x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostpart) +{ + size_t i, hostlen = 0; + uint8_t *authority = NULL; + char *host = NULL; + CBS host_cbs; + + /* + * Find first '//'. there must be at least a '//' and + * something else. + */ + if (len < 3) + return 0; + for (i = 0; i < len - 1; i++) { + if (!isascii(uri[i])) + return 0; + if (uri[i] == '/' && uri[i + 1] == '/') { + authority = uri + i + 2; + break; + } + } + if (authority == NULL) { + /* + * There is no authority, so no host part in this + * URI. This might be ok or might not, but it must + * fail if we run into a name constraint later, so + * we indicate that we have a URI with an empty + * host part, and succeed. + */ + if (hostpart != NULL) + *hostpart = strdup(""); + return 1; + } + for (i = authority - uri; i < len; i++) { + if (!isascii(uri[i])) + return 0; + /* it has a userinfo part */ + if (uri[i] == '@') { + hostlen = 0; + /* it can only have one */ + if (host != NULL) + break; + /* start after the userinfo part */ + host = uri + i + 1; + continue; + } + /* did we find the end? */ + if (uri[i] == ':' || uri[i] == '/' || uri[i] == '?' || + uri[i] == '#') + break; + hostlen++; + } + if (hostlen == 0) + return 0; + if (host == NULL) + host = authority; + CBS_init(&host_cbs, host, hostlen); + if (!x509_constraints_valid_host(&host_cbs, 1)) + return 0; + if (hostpart != NULL && !CBS_strdup(&host_cbs, hostpart)) + return 0; + return 1; +} + +int +x509_constraints_sandns(char *sandns, size_t dlen, char *constraint, size_t len) +{ + char *suffix; + + if (len == 0) + return 1; /* an empty constraint matches everything */ + + /* match the end of the domain */ + if (dlen < len) + return 0; + suffix = sandns + (dlen - len); + return (strncasecmp(suffix, constraint, len) == 0); +} + +/* + * Validate a pre-validated domain of length dlen against a pre-validated + * constraint of length len. + * + * returns 1 if the domain and constraint match. + * returns 0 otherwise. + * + * an empty constraint matches everything. + * constraint will be matched against the domain as a suffix if it + * starts with a '.'. + * domain will be matched against the constraint as a suffix if it + * starts with a '.'. + */ +int +x509_constraints_domain(char *domain, size_t dlen, char *constraint, size_t len) +{ + if (len == 0) + return 1; /* an empty constraint matches everything */ + + if (constraint[0] == '.') { + /* match the end of the domain */ + char *suffix; + if (dlen < len) + return 0; + suffix = domain + (dlen - len); + return (strncasecmp(suffix, constraint, len) == 0); + } + if (domain[0] == '.') { + /* match the end of the constraint */ + char *suffix; + if (len < dlen) + return 0; + suffix = constraint + (len - dlen); + return (strncasecmp(suffix, domain, dlen) == 0); + } + /* otherwise we must exactly match the constraint */ + if (dlen != len) + return 0; + return (strncasecmp(domain, constraint, len) == 0); +} + +int +x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, + size_t len, + int *error) +{ + int ret = 0; + char *hostpart = NULL; + CBS cbs; + + CBS_init(&cbs, constraint, len); + if (!x509_constraints_uri_host(uri, ulen, &hostpart)) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + if (hostpart == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!x509_constraints_valid_domain_constraint(&cbs)) { + *error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; + goto err; + } + ret = x509_constraints_domain(hostpart, strlen(hostpart), constraint, + len); + err: + free(hostpart); + return ret; +} + +/* + * Verify a validated address of size alen with a validated constraint + * of size constraint_len. returns 1 if matching, 0 if not. + * Addresses are assumed to be pre-validated for a length of 4 and 8 + * respectively for ipv4 addresses and constraints, and a length of + * 16 and 32 respectively for ipv6 address constraints by the caller. + */ +int +x509_constraints_ipaddr(uint8_t *address, size_t alen, uint8_t *constraint, + size_t len) +{ + uint8_t *mask; + size_t i; + + if (alen * 2 != len) + return 0; + + mask = constraint + alen; + for (i = 0; i < alen; i++) { + if ((address[i] & mask[i]) != (constraint[i] & mask[i])) + return 0; + } + return 1; +} + +/* + * Verify a canonicalized der encoded constraint dirname + * a canonicalized der encoded constraint. + */ +int +x509_constraints_dirname(uint8_t *dirname, size_t dlen, + uint8_t *constraint, size_t len) +{ + /* + * The constraint must be a prefix in DER format, so it can't be + * longer than the name it is checked against. + */ + if (len > dlen) + return 0; + return (memcmp(constraint, dirname, len) == 0); +} + +/* + * De-obfuscate a GENERAL_NAME into useful bytes for a name or constraint. + */ +int +x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes, + size_t *len) +{ + *bytes = NULL; + *len = 0; + + if (name->type == GEN_DNS) { + ASN1_IA5STRING *aname = name->d.dNSName; + + *bytes = aname->data; + *len = aname->length; + + return name->type; + } + if (name->type == GEN_EMAIL) { + ASN1_IA5STRING *aname = name->d.rfc822Name; + + *bytes = aname->data; + *len = aname->length; + + return name->type; + } + if (name->type == GEN_URI) { + ASN1_IA5STRING *aname = name->d.uniformResourceIdentifier; + + *bytes = aname->data; + *len = aname->length; + + return name->type; + } + if (name->type == GEN_DIRNAME) { + X509_NAME *dname = name->d.directoryName; + + if (!dname->modified || i2d_X509_NAME(dname, NULL) >= 0) { + *bytes = dname->canon_enc; + *len = dname->canon_enclen; + + return name->type; + } + } + if (name->type == GEN_IPADD) { + *bytes = name->d.ip->data; + *len = name->d.ip->length; + + return name->type; + } + + return 0; +} + +/* + * Extract the relevant names for constraint checking from "cert", + * validate them, and add them to the list of cert names for "chain". + * returns 1 on success sets error and returns 0 on failure. + */ +int +x509_constraints_extract_names(struct x509_constraints_names *names, + X509 *cert, int is_leaf, int *error) +{ + struct x509_constraints_name *vname = NULL; + X509_NAME *subject_name; + GENERAL_NAME *name; + ssize_t i = 0; + int name_type, include_cn = is_leaf, include_email = is_leaf; + + /* first grab the altnames */ + while ((name = sk_GENERAL_NAME_value(cert->altname, i++)) != NULL) { + uint8_t *bytes = NULL; + size_t len = 0; + CBS cbs; + + if ((vname = x509_constraints_name_new()) == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + + name_type = x509_constraints_general_to_bytes(name, &bytes, + &len); + CBS_init(&cbs, bytes, len); + switch (name_type) { + case GEN_DNS: + if (!x509_constraints_valid_sandns(&cbs)) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + if (!CBS_strdup(&cbs, &vname->name)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname->type = GEN_DNS; + include_cn = 0; /* Don't use cn from subject */ + break; + case GEN_EMAIL: + if (!x509_constraints_parse_mailbox(&cbs, vname)) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + vname->type = GEN_EMAIL; + include_email = 0; /* Don't use email from subject */ + break; + case GEN_URI: + if (!x509_constraints_uri_host(bytes, len, + &vname->name)) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + if (vname->name == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname->type = GEN_URI; + break; + case GEN_DIRNAME: + if (len == 0) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + if (bytes == NULL || ((vname->der = malloc(len)) == + NULL)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + memcpy(vname->der, bytes, len); + vname->der_len = len; + vname->type = GEN_DIRNAME; + break; + case GEN_IPADD: + if (len == 4) + vname->af = AF_INET; + if (len == 16) + vname->af = AF_INET6; + if (vname->af != AF_INET && vname->af != AF_INET6) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + memcpy(vname->address, bytes, len); + vname->type = GEN_IPADD; + break; + default: + /* Ignore this name */ + x509_constraints_name_free(vname); + vname = NULL; + continue; + } + if (!x509_constraints_names_add(names, vname)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname = NULL; + } + + x509_constraints_name_free(vname); + vname = NULL; + + subject_name = X509_get_subject_name(cert); + if (X509_NAME_entry_count(subject_name) > 0) { + X509_NAME_ENTRY *email; + X509_NAME_ENTRY *cn; + /* + * This cert has a non-empty subject, so we must add + * the subject as a dirname to be compared against + * any dirname constraints + */ + if ((subject_name->modified && + i2d_X509_NAME(subject_name, NULL) < 0) || + (vname = x509_constraints_name_new()) == NULL || + (vname->der = malloc(subject_name->canon_enclen)) == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + + memcpy(vname->der, subject_name->canon_enc, + subject_name->canon_enclen); + vname->der_len = subject_name->canon_enclen; + vname->type = GEN_DIRNAME; + if (!x509_constraints_names_add(names, vname)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname = NULL; + /* + * Get any email addresses from the subject line, and + * add them as mbox names to be compared against any + * email constraints + */ + while (include_email && + (i = X509_NAME_get_index_by_NID(subject_name, + NID_pkcs9_emailAddress, i)) >= 0) { + ASN1_STRING *aname; + CBS cbs; + if ((email = X509_NAME_get_entry(subject_name, i)) == + NULL || + (aname = X509_NAME_ENTRY_get_data(email)) == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + CBS_init(&cbs, aname->data, aname->length); + if ((vname = x509_constraints_name_new()) == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!x509_constraints_parse_mailbox(&cbs, vname)) { + *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto err; + } + vname->type = GEN_EMAIL; + if (!x509_constraints_names_add(names, vname)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname = NULL; + } + /* + * Include the CN as a hostname to be checked against + * name constraints if it looks like a hostname. + */ + while (include_cn && + (i = X509_NAME_get_index_by_NID(subject_name, + NID_commonName, i)) >= 0) { + CBS cbs; + ASN1_STRING *aname; + if ((cn = X509_NAME_get_entry(subject_name, i)) == + NULL || + (aname = X509_NAME_ENTRY_get_data(cn)) == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + CBS_init(&cbs, aname->data, aname->length); + if (!x509_constraints_valid_host(&cbs, 0)) + continue; /* ignore it if not a hostname */ + if ((vname = x509_constraints_name_new()) == NULL) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!CBS_strdup(&cbs, &vname->name)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname->type = GEN_DNS; + if (!x509_constraints_names_add(names, vname)) { + *error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + vname = NULL; + } + } + return 1; + err: + x509_constraints_name_free(vname); + return 0; +} + +/* + * Validate a constraint in a general name, putting the relevant data + * into "name" if valid. returns 0, and sets error if the constraint is + * not valid. returns 1 if the constraint validated. name->type will be + * set to a valid type if there is constraint data in name, or unmodified + * if the GENERAL_NAME had a valid type but was ignored. + */ +int +x509_constraints_validate(GENERAL_NAME *constraint, + struct x509_constraints_name **out_name, int *out_error) +{ + uint8_t next, *bytes = NULL; + size_t len = 0; + struct x509_constraints_name *name; + int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; + int name_type; + CBS cbs; + + if (out_name == NULL || *out_name != NULL) + return 0; + + if (out_error != NULL) + *out_error = 0; + + if ((name = x509_constraints_name_new()) == NULL) { + error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + + name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len); + CBS_init(&cbs, bytes, len); + switch (name_type) { + case GEN_DIRNAME: + if (len == 0) + goto err; /* XXX The RFCs are delightfully vague */ + if (bytes == NULL || (name->der = malloc(len)) == NULL) { + error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + memcpy(name->der, bytes, len); + name->der_len = len; + name->type = GEN_DIRNAME; + break; + case GEN_DNS: + if (!x509_constraints_valid_domain_constraint(&cbs)) + goto err; + if ((name->name = strndup(bytes, len)) == NULL) { + error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + name->type = GEN_DNS; + break; + case GEN_EMAIL: + if (len > 0 && memchr(bytes + 1, '@', len - 1) != NULL) { + if (!x509_constraints_parse_mailbox(&cbs, name)) + goto err; + break; + } + /* + * Mail constraints of the form @domain.com are accepted by + * OpenSSL and Microsoft. + */ + if (CBS_len(&cbs) > 0) { + if (!CBS_peek_u8(&cbs, &next)) + goto err; + if (next == '@') { + if (!CBS_skip(&cbs, 1)) + goto err; + } + } + if (!x509_constraints_valid_domain_constraint(&cbs)) + goto err; + if (!CBS_strdup(&cbs, &name->name)) { + error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + name->type = GEN_EMAIL; + break; + case GEN_IPADD: + /* Constraints are ip then mask */ + if (len == 8) + name->af = AF_INET; + else if (len == 32) + name->af = AF_INET6; + else + goto err; + memcpy(&name->address[0], bytes, len); + name->type = GEN_IPADD; + break; + case GEN_URI: + if (!x509_constraints_valid_domain_constraint(&cbs)) + goto err; + if ((name->name = strndup(bytes, len)) == NULL) { + error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + name->type = GEN_URI; + break; + default: + break; + } + + *out_name = name; + + return 1; + + err: + x509_constraints_name_free(name); + if (out_error != NULL) + *out_error = error; + + return 0; +} + +int +x509_constraints_extract_constraints(X509 *cert, + struct x509_constraints_names *permitted, + struct x509_constraints_names *excluded, + int *error) +{ + struct x509_constraints_name *vname = NULL; + NAME_CONSTRAINTS *nc = cert->nc; + GENERAL_SUBTREE *subtree; + int i; + + if (nc == NULL) + return 1; + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + subtree = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (subtree->minimum || subtree->maximum) { + *error = X509_V_ERR_SUBTREE_MINMAX; + return 0; + } + if (!x509_constraints_validate(subtree->base, &vname, error)) + return 0; + if (vname->type == 0) { + x509_constraints_name_free(vname); + vname = NULL; + continue; + } + if (!x509_constraints_names_add(permitted, vname)) { + x509_constraints_name_free(vname); + vname = NULL; + *error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + vname = NULL; + } + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + subtree = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (subtree->minimum || subtree->maximum) { + *error = X509_V_ERR_SUBTREE_MINMAX; + return 0; + } + if (!x509_constraints_validate(subtree->base, &vname, error)) + return 0; + if (vname->type == 0) { + x509_constraints_name_free(vname); + vname = NULL; + continue; + } + if (!x509_constraints_names_add(excluded, vname)) { + x509_constraints_name_free(vname); + vname = NULL; + *error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + vname = NULL; + } + + return 1; +} + +/* + * Match a validated name in "name" against a validated constraint in + * "constraint" return 1 if then name matches, 0 otherwise. + */ +int +x509_constraints_match(struct x509_constraints_name *name, + struct x509_constraints_name *constraint) +{ + if (name->type != constraint->type) + return 0; + if (name->type == GEN_DNS) + return x509_constraints_sandns(name->name, strlen(name->name), + constraint->name, strlen(constraint->name)); + if (name->type == GEN_URI) + return x509_constraints_domain(name->name, strlen(name->name), + constraint->name, strlen(constraint->name)); + if (name->type == GEN_IPADD) { + size_t nlen = name->af == AF_INET ? 4 : 16; + size_t clen = name->af == AF_INET ? 8 : 32; + if (name->af != AF_INET && name->af != AF_INET6) + return 0; + if (constraint->af != AF_INET && constraint->af != AF_INET6) + return 0; + if (name->af != constraint->af) + return 0; + return x509_constraints_ipaddr(name->address, nlen, + constraint->address, clen); + } + if (name->type == GEN_EMAIL) { + if (constraint->local) { + /* mailbox local and domain parts must exactly match */ + return (strcmp(name->local, constraint->local) == 0 && + strcmp(name->name, constraint->name) == 0); + } + /* otherwise match the constraint to the domain part */ + return x509_constraints_domain(name->name, strlen(name->name), + constraint->name, strlen(constraint->name)); + } + if (name->type == GEN_DIRNAME) + return x509_constraints_dirname(name->der, name->der_len, + constraint->der, constraint->der_len); + return 0; +} + +/* + * Make sure every name in names does not match any excluded + * constraints, and does match at least one permitted constraint if + * any are present. Returns 1 if ok, 0, and sets error if not. + */ +int +x509_constraints_check(struct x509_constraints_names *names, + struct x509_constraints_names *permitted, + struct x509_constraints_names *excluded, int *error) +{ + size_t i, j; + + for (i = 0; i < names->names_count; i++) { + int permitted_seen = 0; + int permitted_matched = 0; + + for (j = 0; j < excluded->names_count; j++) { + if (x509_constraints_match(names->names[i], + excluded->names[j])) { + *error = X509_V_ERR_EXCLUDED_VIOLATION; + return 0; + } + } + for (j = 0; j < permitted->names_count; j++) { + if (permitted->names[j]->type == names->names[i]->type) + permitted_seen++; + if (x509_constraints_match(names->names[i], + permitted->names[j])) { + permitted_matched++; + break; + } + } + if (permitted_seen && !permitted_matched) { + *error = X509_V_ERR_PERMITTED_VIOLATION; + return 0; + } + } + return 1; +} + +/* + * Walk a validated chain of X509 certs, starting at the leaf, and + * validate the name constraints in the chain. Intended for use with + * the legacy X509 validation code in x509_vfy.c + * + * returns 1 if the constraints are ok, 0 otherwise, setting error and + * depth + */ +int +x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth) +{ + int chain_length, verify_err = X509_V_ERR_UNSPECIFIED, i = 0; + struct x509_constraints_names *names = NULL; + struct x509_constraints_names *excluded = NULL; + struct x509_constraints_names *permitted = NULL; + size_t constraints_count = 0; + X509 *cert; + + if (chain == NULL || (chain_length = sk_X509_num(chain)) == 0) + goto err; + if (chain_length == 1) + return 1; + if ((names = x509_constraints_names_new( + X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) { + verify_err = X509_V_ERR_OUT_OF_MEM; + goto err; + } + + if ((cert = sk_X509_value(chain, 0)) == NULL) + goto err; + if (!x509_constraints_extract_names(names, cert, 1, &verify_err)) + goto err; + for (i = 1; i < chain_length; i++) { + if ((cert = sk_X509_value(chain, i)) == NULL) + goto err; + if (cert->nc != NULL) { + if ((permitted = x509_constraints_names_new( + X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { + verify_err = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if ((excluded = x509_constraints_names_new( + X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { + verify_err = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!x509_constraints_extract_constraints(cert, + permitted, excluded, &verify_err)) + goto err; + constraints_count += permitted->names_count; + constraints_count += excluded->names_count; + if (constraints_count > + X509_VERIFY_MAX_CHAIN_CONSTRAINTS) { + verify_err = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!x509_constraints_check(names, permitted, excluded, + &verify_err)) + goto err; + x509_constraints_names_free(excluded); + excluded = NULL; + x509_constraints_names_free(permitted); + permitted = NULL; + } + if (!x509_constraints_extract_names(names, cert, 0, + &verify_err)) + goto err; + } + + x509_constraints_names_free(names); + return 1; + + err: + *error = verify_err; + *depth = i; + x509_constraints_names_free(excluded); + x509_constraints_names_free(permitted); + x509_constraints_names_free(names); + return 0; +} diff --git a/Libraries/libressl/crypto/x509/x509_cpols.c b/Libraries/libressl/crypto/x509/x509_cpols.c new file mode 100644 index 000000000..bab2e99a9 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_cpols.c @@ -0,0 +1,764 @@ +/* $OpenBSD: x509_cpols.c,v 1.11 2023/04/26 20:54:21 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "x509_local.h" + +/* Certificate policies extension support: this one is a bit complex... */ + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent); +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value); +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent); +static void print_notice(BIO *out, USERNOTICE *notice, int indent); +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org); +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); + +const X509V3_EXT_METHOD v3_cpols = { + .ext_nid = NID_certificate_policies, + .ext_flags = 0, + .it = &CERTIFICATEPOLICIES_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_certpol, + .r2i = (X509V3_EXT_R2I)r2i_certpol, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "CERTIFICATEPOLICIES", + .item = &POLICYINFO_it, +}; + +const ASN1_ITEM CERTIFICATEPOLICIES_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &CERTIFICATEPOLICIES_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "CERTIFICATEPOLICIES", +}; + + +CERTIFICATEPOLICIES * +d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len) +{ + return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &CERTIFICATEPOLICIES_it); +} +LCRYPTO_ALIAS(d2i_CERTIFICATEPOLICIES); + +int +i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it); +} +LCRYPTO_ALIAS(i2d_CERTIFICATEPOLICIES); + +CERTIFICATEPOLICIES * +CERTIFICATEPOLICIES_new(void) +{ + return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it); +} +LCRYPTO_ALIAS(CERTIFICATEPOLICIES_new); + +void +CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it); +} +LCRYPTO_ALIAS(CERTIFICATEPOLICIES_free); + +static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYINFO, policyid), + .field_name = "policyid", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(POLICYINFO, qualifiers), + .field_name = "qualifiers", + .item = &POLICYQUALINFO_it, + }, +}; + +const ASN1_ITEM POLICYINFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICYINFO_seq_tt, + .tcount = sizeof(POLICYINFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICYINFO), + .sname = "POLICYINFO", +}; + + +POLICYINFO * +d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len) +{ + return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &POLICYINFO_it); +} +LCRYPTO_ALIAS(d2i_POLICYINFO); + +int +i2d_POLICYINFO(POLICYINFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it); +} +LCRYPTO_ALIAS(i2d_POLICYINFO); + +POLICYINFO * +POLICYINFO_new(void) +{ + return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it); +} +LCRYPTO_ALIAS(POLICYINFO_new); + +void +POLICYINFO_free(POLICYINFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it); +} +LCRYPTO_ALIAS(POLICYINFO_free); + +static const ASN1_TEMPLATE policydefault_tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, d.other), + .field_name = "d.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = { + { + .value = NID_id_qt_cps, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, d.cpsuri), + .field_name = "d.cpsuri", + .item = &ASN1_IA5STRING_it, + }, + }, + { + .value = NID_id_qt_unotice, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, d.usernotice), + .field_name = "d.usernotice", + .item = &USERNOTICE_it, + }, + }, +}; + +static const ASN1_ADB POLICYQUALINFO_adb = { + .flags = 0, + .offset = offsetof(POLICYQUALINFO, pqualid), + .tbl = POLICYQUALINFO_adbtbl, + .tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &policydefault_tt, + .null_tt = NULL, +}; + +static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, pqualid), + .field_name = "pqualid", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "POLICYQUALINFO", + .item = (const ASN1_ITEM *)&POLICYQUALINFO_adb, + }, +}; + +const ASN1_ITEM POLICYQUALINFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICYQUALINFO_seq_tt, + .tcount = sizeof(POLICYQUALINFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICYQUALINFO), + .sname = "POLICYQUALINFO", +}; + + +POLICYQUALINFO * +d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len) +{ + return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &POLICYQUALINFO_it); +} +LCRYPTO_ALIAS(d2i_POLICYQUALINFO); + +int +i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it); +} +LCRYPTO_ALIAS(i2d_POLICYQUALINFO); + +POLICYQUALINFO * +POLICYQUALINFO_new(void) +{ + return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it); +} +LCRYPTO_ALIAS(POLICYQUALINFO_new); + +void +POLICYQUALINFO_free(POLICYQUALINFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it); +} +LCRYPTO_ALIAS(POLICYQUALINFO_free); + +static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(USERNOTICE, noticeref), + .field_name = "noticeref", + .item = &NOTICEREF_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(USERNOTICE, exptext), + .field_name = "exptext", + .item = &DISPLAYTEXT_it, + }, +}; + +const ASN1_ITEM USERNOTICE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = USERNOTICE_seq_tt, + .tcount = sizeof(USERNOTICE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(USERNOTICE), + .sname = "USERNOTICE", +}; + + +USERNOTICE * +d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len) +{ + return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &USERNOTICE_it); +} +LCRYPTO_ALIAS(d2i_USERNOTICE); + +int +i2d_USERNOTICE(USERNOTICE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it); +} +LCRYPTO_ALIAS(i2d_USERNOTICE); + +USERNOTICE * +USERNOTICE_new(void) +{ + return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it); +} +LCRYPTO_ALIAS(USERNOTICE_new); + +void +USERNOTICE_free(USERNOTICE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it); +} +LCRYPTO_ALIAS(USERNOTICE_free); + +static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(NOTICEREF, organization), + .field_name = "organization", + .item = &DISPLAYTEXT_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(NOTICEREF, noticenos), + .field_name = "noticenos", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM NOTICEREF_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = NOTICEREF_seq_tt, + .tcount = sizeof(NOTICEREF_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(NOTICEREF), + .sname = "NOTICEREF", +}; + + +NOTICEREF * +d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len) +{ + return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &NOTICEREF_it); +} +LCRYPTO_ALIAS(d2i_NOTICEREF); + +int +i2d_NOTICEREF(NOTICEREF *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it); +} +LCRYPTO_ALIAS(i2d_NOTICEREF); + +NOTICEREF * +NOTICEREF_new(void) +{ + return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it); +} +LCRYPTO_ALIAS(NOTICEREF_new); + +void +NOTICEREF_free(NOTICEREF *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it); +} +LCRYPTO_ALIAS(NOTICEREF_free); + +static STACK_OF(POLICYINFO) * +r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value) +{ + STACK_OF(POLICYINFO) *pols = NULL; + char *pstr; + POLICYINFO *pol; + ASN1_OBJECT *pobj; + STACK_OF(CONF_VALUE) *vals; + CONF_VALUE *cnf; + int i, ia5org; + + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + X509V3error(ERR_R_X509V3_LIB); + goto err; + } + ia5org = 0; + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + cnf = sk_CONF_VALUE_value(vals, i); + if (cnf->value || !cnf->name) { + X509V3error(X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pstr = cnf->name; + if (!strcmp(pstr, "ia5org")) { + ia5org = 1; + continue; + } else if (*pstr == '@') { + STACK_OF(CONF_VALUE) *polsect; + polsect = X509V3_get_section(ctx, pstr + 1); + if (!polsect) { + X509V3error(X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + pol = policy_section(ctx, polsect, ia5org); + X509V3_section_free(ctx, polsect); + if (!pol) + goto err; + } else { + if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { + X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)){ + POLICYINFO_free(pol); + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pols; + +err: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + sk_POLICYINFO_pop_free(pols, POLICYINFO_free); + return NULL; +} + +static POLICYINFO * +policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org) +{ + int i; + CONF_VALUE *cnf; + POLICYINFO *pol; + POLICYQUALINFO *nqual = NULL; + + if ((pol = POLICYINFO_new()) == NULL) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + cnf = sk_CONF_VALUE_value(polstrs, i); + if (strcmp(cnf->name, "policyIdentifier") == 0) { + ASN1_OBJECT *pobj; + + if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) { + X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol->policyid = pobj; + } else if (name_cmp(cnf->name, "CPS") == 0) { + if ((nqual = POLICYQUALINFO_new()) == NULL) + goto merr; + nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps); + nqual->d.cpsuri = ASN1_IA5STRING_new(); + if (nqual->d.cpsuri == NULL) + goto merr; + if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value, + strlen(cnf->value)) == 0) + goto merr; + + if (pol->qualifiers == NULL) { + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (pol->qualifiers == NULL) + goto merr; + } + if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0) + goto merr; + nqual = NULL; + } else if (name_cmp(cnf->name, "userNotice") == 0) { + STACK_OF(CONF_VALUE) *unot; + POLICYQUALINFO *qual; + + if (*cnf->value != '@') { + X509V3error(X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (unot == NULL) { + X509V3error(X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + qual = notice_section(ctx, unot, ia5org); + X509V3_section_free(ctx, unot); + if (qual == NULL) + goto err; + + if (pol->qualifiers == NULL) { + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (pol->qualifiers == NULL) + goto merr; + } + if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0) + goto merr; + } else { + X509V3error(X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + if (pol->policyid == NULL) { + X509V3error(X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + +merr: + X509V3error(ERR_R_MALLOC_FAILURE); + +err: + POLICYQUALINFO_free(nqual); + POLICYINFO_free(pol); + return NULL; +} + +static POLICYQUALINFO * +notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + int i, ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + + if (!(qual = POLICYQUALINFO_new())) + goto merr; + qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); + if (!(not = USERNOTICE_new())) + goto merr; + qual->d.usernotice = not; + for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { + cnf = sk_CONF_VALUE_value(unot, i); + if (!strcmp(cnf->name, "explicitText")) { + if (not->exptext == NULL) { + not->exptext = ASN1_UTF8STRING_new(); + if (not->exptext == NULL) + goto merr; + } + if (!ASN1_STRING_set(not->exptext, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "organization")) { + NOTICEREF *nref; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + if (ia5org) + nref->organization->type = V_ASN1_IA5STRING; + else + nref->organization->type = V_ASN1_VISIBLESTRING; + if (!ASN1_STRING_set(nref->organization, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "noticeNumbers")) { + NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + nos = X509V3_parse_list(cnf->value); + if (!nos || !sk_CONF_VALUE_num(nos)) { + X509V3error(X509V3_R_INVALID_NUMBERS); + X509V3_conf_err(cnf); + if (nos != NULL) + sk_CONF_VALUE_pop_free(nos, + X509V3_conf_free); + goto err; + } + ret = nref_nos(nref->noticenos, nos); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + if (!ret) + goto err; + } else { + X509V3error(X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + X509V3error(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + +merr: + X509V3error(ERR_R_MALLOC_FAILURE); + +err: + POLICYQUALINFO_free(qual); + return NULL; +} + +static int +nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) +{ + CONF_VALUE *cnf; + ASN1_INTEGER *aint; + int i; + + for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { + cnf = sk_CONF_VALUE_value(nos, i); + if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { + X509V3error(X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + +merr: + X509V3error(ERR_R_MALLOC_FAILURE); + +err: + sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free); + return 0; +} + +static int +i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, + int indent) +{ + int i; + POLICYINFO *pinfo; + + /* First print out the policy OIDs */ + for (i = 0; i < sk_POLICYINFO_num(pol); i++) { + pinfo = sk_POLICYINFO_value(pol, i); + BIO_printf(out, "%*sPolicy: ", indent, ""); + i2a_ASN1_OBJECT(out, pinfo->policyid); + BIO_puts(out, "\n"); + if (pinfo->qualifiers) + print_qualifiers(out, pinfo->qualifiers, indent + 2); + } + return 1; +} + +static void +print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent) +{ + POLICYQUALINFO *qualinfo; + int i; + + for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: + BIO_printf(out, "%*sCPS: %.*s\n", indent, "", + qualinfo->d.cpsuri->length, + qualinfo->d.cpsuri->data); + break; + + case NID_id_qt_unotice: + BIO_printf(out, "%*sUser Notice:\n", indent, ""); + print_notice(out, qualinfo->d.usernotice, indent + 2); + break; + + default: + BIO_printf(out, "%*sUnknown Qualifier: ", + indent + 2, ""); + + i2a_ASN1_OBJECT(out, qualinfo->pqualid); + BIO_puts(out, "\n"); + break; + } + } +} + +static void +print_notice(BIO *out, USERNOTICE *notice, int indent) +{ + int i; + + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", + ref->organization->length, ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); + for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i) + BIO_puts(out, ", "); + tmp = i2s_ASN1_INTEGER(NULL, num); + BIO_puts(out, tmp); + free(tmp); + } + BIO_puts(out, "\n"); + } + if (notice->exptext) + BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", + notice->exptext->length, notice->exptext->data); +} diff --git a/Libraries/libressl/crypto/x509/x509_crld.c b/Libraries/libressl/crypto/x509/x509_crld.c new file mode 100644 index 000000000..7887ccd64 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_crld.c @@ -0,0 +1,828 @@ +/* $OpenBSD: x509_crld.c,v 1.5 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "x509_local.h" + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent); + +const X509V3_EXT_METHOD v3_crld = { + .ext_nid = NID_crl_distribution_points, + .ext_flags = 0, + .it = &CRL_DIST_POINTS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_crld, + .i2r = i2r_crldp, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_freshest_crl = { + .ext_nid = NID_freshest_crl, + .ext_flags = 0, + .it = &CRL_DIST_POINTS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_crld, + .i2r = i2r_crldp, + .r2i = NULL, + .usr_data = NULL, +}; + +static STACK_OF(GENERAL_NAME) * +gnames_from_sectname(X509V3_CTX *ctx, char *sect) +{ + STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(GENERAL_NAME) *gens; + + if (*sect == '@') + gnsect = X509V3_get_section(ctx, sect + 1); + else + gnsect = X509V3_parse_list(sect); + if (!gnsect) { + X509V3error(X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + if (*sect == '@') + X509V3_section_free(ctx, gnsect); + else + sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); + return gens; +} + +static int +set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, CONF_VALUE *cnf) +{ + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + + if (!strncmp(cnf->name, "fullname", 9)) { + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) + goto err; + } else if (!strcmp(cnf->name, "relativename")) { + int ret; + STACK_OF(CONF_VALUE) *dnsect; + X509_NAME *nm; + nm = X509_NAME_new(); + if (!nm) + return -1; + dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) { + X509V3error(X509V3_R_SECTION_NOT_FOUND); + X509_NAME_free(nm); + return -1; + } + ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + X509V3_section_free(ctx, dnsect); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) + goto err; + /* Since its a name fragment can't have more than one + * RDNSequence + */ + if (sk_X509_NAME_ENTRY_value(rnm, + sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { + X509V3error(X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + X509V3error(X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } + + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) + goto err; + if (fnm) { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } else { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + +err: + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; +} + +static const BIT_STRING_BITNAME reason_flags[] = { + {0, "Unused", "unused"}, + {1, "Key Compromise", "keyCompromise"}, + {2, "CA Compromise", "CACompromise"}, + {3, "Affiliation Changed", "affiliationChanged"}, + {4, "Superseded", "superseded"}, + {5, "Cessation Of Operation", "cessationOfOperation"}, + {6, "Certificate Hold", "certificateHold"}, + {7, "Privilege Withdrawn", "privilegeWithdrawn"}, + {8, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +static int +set_reasons(ASN1_BIT_STRING **preas, char *value) +{ + STACK_OF(CONF_VALUE) *rsk = NULL; + const BIT_STRING_BITNAME *pbn; + const char *bnam; + int i, ret = 0; + + if (*preas != NULL) + return 0; + rsk = X509V3_parse_list(value); + if (rsk == NULL) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) + goto err; + } + for (pbn = reason_flags; pbn->lname; pbn++) { + if (!strcmp(pbn->sname, bnam)) { + if (!ASN1_BIT_STRING_set_bit(*preas, + pbn->bitnum, 1)) + goto err; + break; + } + } + if (!pbn->lname) + goto err; + } + ret = 1; + +err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; +} + +static int +print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, int indent) +{ + int first = 1; + const BIT_STRING_BITNAME *pbn; + + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { + if (first) + first = 0; + else + BIO_puts(out, ", "); + BIO_puts(out, pbn->lname); + } + } + if (first) + BIO_puts(out, "\n"); + else + BIO_puts(out, "\n"); + return 1; +} + +static DIST_POINT * +crldp_from_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE *cnf; + DIST_POINT *point = NULL; + + point = DIST_POINT_new(); + if (!point) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(cnf->name, "reasons")) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } + else if (!strcmp(cnf->name, "CRLissuer")) { + point->CRLissuer = + gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) + goto err; + } + } + + return point; + +err: + DIST_POINT_free(point); + return NULL; +} + +static void * +v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + STACK_OF(DIST_POINT) *crld = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + int i; + + if (!(crld = sk_DIST_POINT_new_null())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + DIST_POINT *point; + cnf = sk_CONF_VALUE_value(nval, i); + if (!cnf->value) { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = crldp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (!point) + goto err; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + } else { + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (!(gens = GENERAL_NAMES_new())) + goto merr; + if (!sk_GENERAL_NAME_push(gens, gen)) + goto merr; + gen = NULL; + if (!(point = DIST_POINT_new())) + goto merr; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + if (!(point->distpoint = DIST_POINT_NAME_new())) + goto merr; + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + } + return crld; + +merr: + X509V3error(ERR_R_MALLOC_FAILURE); +err: + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + sk_DIST_POINT_pop_free(crld, DIST_POINT_free); + return NULL; +} + +static int +dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + + switch (operation) { + case ASN1_OP_NEW_POST: + dpn->dpname = NULL; + break; + + case ASN1_OP_FREE_POST: + if (dpn->dpname) + X509_NAME_free(dpn->dpname); + break; + } + return 1; +} + + +static const ASN1_AUX DIST_POINT_NAME_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = dpn_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DIST_POINT_NAME_ch_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(DIST_POINT_NAME, name.fullname), + .field_name = "name.fullname", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF, + .tag = 1, + .offset = offsetof(DIST_POINT_NAME, name.relativename), + .field_name = "name.relativename", + .item = &X509_NAME_ENTRY_it, + }, +}; + +const ASN1_ITEM DIST_POINT_NAME_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(DIST_POINT_NAME, type), + .templates = DIST_POINT_NAME_ch_tt, + .tcount = sizeof(DIST_POINT_NAME_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DIST_POINT_NAME_aux, + .size = sizeof(DIST_POINT_NAME), + .sname = "DIST_POINT_NAME", +}; + + + +DIST_POINT_NAME * +d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len) +{ + return (DIST_POINT_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DIST_POINT_NAME_it); +} +LCRYPTO_ALIAS(d2i_DIST_POINT_NAME); + +int +i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it); +} +LCRYPTO_ALIAS(i2d_DIST_POINT_NAME); + +DIST_POINT_NAME * +DIST_POINT_NAME_new(void) +{ + return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it); +} +LCRYPTO_ALIAS(DIST_POINT_NAME_new); + +void +DIST_POINT_NAME_free(DIST_POINT_NAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it); +} +LCRYPTO_ALIAS(DIST_POINT_NAME_free); + +static const ASN1_TEMPLATE DIST_POINT_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(DIST_POINT, distpoint), + .field_name = "distpoint", + .item = &DIST_POINT_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(DIST_POINT, reasons), + .field_name = "reasons", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(DIST_POINT, CRLissuer), + .field_name = "CRLissuer", + .item = &GENERAL_NAME_it, + }, +}; + +const ASN1_ITEM DIST_POINT_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DIST_POINT_seq_tt, + .tcount = sizeof(DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(DIST_POINT), + .sname = "DIST_POINT", +}; + + +DIST_POINT * +d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len) +{ + return (DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DIST_POINT_it); +} +LCRYPTO_ALIAS(d2i_DIST_POINT); + +int +i2d_DIST_POINT(DIST_POINT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it); +} +LCRYPTO_ALIAS(i2d_DIST_POINT); + +DIST_POINT * +DIST_POINT_new(void) +{ + return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it); +} +LCRYPTO_ALIAS(DIST_POINT_new); + +void +DIST_POINT_free(DIST_POINT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it); +} +LCRYPTO_ALIAS(DIST_POINT_free); + +static const ASN1_TEMPLATE CRL_DIST_POINTS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "CRLDistributionPoints", + .item = &DIST_POINT_it, +}; + +const ASN1_ITEM CRL_DIST_POINTS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &CRL_DIST_POINTS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "CRL_DIST_POINTS", +}; + + +CRL_DIST_POINTS * +d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len) +{ + return (CRL_DIST_POINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &CRL_DIST_POINTS_it); +} +LCRYPTO_ALIAS(d2i_CRL_DIST_POINTS); + +int +i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it); +} +LCRYPTO_ALIAS(i2d_CRL_DIST_POINTS); + +CRL_DIST_POINTS * +CRL_DIST_POINTS_new(void) +{ + return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it); +} +LCRYPTO_ALIAS(CRL_DIST_POINTS_new); + +void +CRL_DIST_POINTS_free(CRL_DIST_POINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it); +} +LCRYPTO_ALIAS(CRL_DIST_POINTS_free); + +static const ASN1_TEMPLATE ISSUING_DIST_POINT_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ISSUING_DIST_POINT, distpoint), + .field_name = "distpoint", + .item = &DIST_POINT_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(ISSUING_DIST_POINT, onlyuser), + .field_name = "onlyuser", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(ISSUING_DIST_POINT, onlyCA), + .field_name = "onlyCA", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 3, + .offset = offsetof(ISSUING_DIST_POINT, onlysomereasons), + .field_name = "onlysomereasons", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 4, + .offset = offsetof(ISSUING_DIST_POINT, indirectCRL), + .field_name = "indirectCRL", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 5, + .offset = offsetof(ISSUING_DIST_POINT, onlyattr), + .field_name = "onlyattr", + .item = &ASN1_FBOOLEAN_it, + }, +}; + +const ASN1_ITEM ISSUING_DIST_POINT_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ISSUING_DIST_POINT_seq_tt, + .tcount = sizeof(ISSUING_DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ISSUING_DIST_POINT), + .sname = "ISSUING_DIST_POINT", +}; + + +ISSUING_DIST_POINT * +d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len) +{ + return (ISSUING_DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ISSUING_DIST_POINT_it); +} +LCRYPTO_ALIAS(d2i_ISSUING_DIST_POINT); + +int +i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it); +} +LCRYPTO_ALIAS(i2d_ISSUING_DIST_POINT); + +ISSUING_DIST_POINT * +ISSUING_DIST_POINT_new(void) +{ + return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it); +} +LCRYPTO_ALIAS(ISSUING_DIST_POINT_new); + +void +ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it); +} +LCRYPTO_ALIAS(ISSUING_DIST_POINT_free); + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent); +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_idp = { + NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + &ISSUING_DIST_POINT_it, + 0, 0, 0, 0, + 0, 0, + 0, + v2i_idp, + i2r_idp, 0, + NULL +}; + +static void * +v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + ISSUING_DIST_POINT *idp = NULL; + CONF_VALUE *cnf; + char *name, *val; + int i, ret; + + idp = ISSUING_DIST_POINT_new(); + if (!idp) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + name = cnf->name; + val = cnf->value; + ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(name, "onlyuser")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) + goto err; + } + else if (!strcmp(name, "onlyCA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) + goto err; + } + else if (!strcmp(name, "onlyAA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) + goto err; + } + else if (!strcmp(name, "indirectCRL")) { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) + goto err; + } + else if (!strcmp(name, "onlysomereasons")) { + if (!set_reasons(&idp->onlysomereasons, val)) + goto err; + } else { + X509V3error(X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + +merr: + X509V3error(ERR_R_MALLOC_FAILURE); +err: + ISSUING_DIST_POINT_free(idp); + return NULL; +} + +static int +print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) +{ + int i; + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; +} + +static int +print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) +{ + if (dpn->type == 0) { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } else { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", + indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; +} + +static int +i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent) +{ + ISSUING_DIST_POINT *idp = pidp; + + if (idp->distpoint) + print_distpoint(out, idp->distpoint, indent); + if (idp->onlyuser > 0) + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + if (idp->onlyCA > 0) + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + if (idp->indirectCRL > 0) + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + if (idp->onlysomereasons) + print_reasons(out, "Only Some Reasons", + idp->onlysomereasons, indent); + if (idp->onlyattr > 0) + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) && + (idp->indirectCRL <= 0) && !idp->onlysomereasons && + (idp->onlyattr <= 0)) + BIO_printf(out, "%*s\n", indent, ""); + + return 1; +} + +static int +i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent) +{ + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + int i; + + for (i = 0; i < sk_DIST_POINT_num(crld); i++) { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if (point->distpoint) + print_distpoint(out, point->distpoint, indent); + if (point->reasons) + print_reasons(out, "Reasons", point->reasons, + indent); + if (point->CRLissuer) { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; +} + +int +DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) +{ + int i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + + if (!dpn || (dpn->type != 1)) + return 1; + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) + return 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + /* generate cached encoding of name */ + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; +} +LCRYPTO_ALIAS(DIST_POINT_set_dpname); diff --git a/Libraries/libressl/crypto/x509/x509_d2.c b/Libraries/libressl/crypto/x509/x509_d2.c new file mode 100644 index 000000000..bf358ec29 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_d2.c @@ -0,0 +1,131 @@ +/* $OpenBSD: x509_d2.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include + +int +X509_STORE_set_default_paths(X509_STORE *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* clear any errors */ + ERR_clear_error(); + + return (1); +} +LCRYPTO_ALIAS(X509_STORE_set_default_paths); + +int +X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path) +{ + X509_LOOKUP *lookup; + + if (file != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) + return (0); + } + if (path != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) + return (0); + } + if ((path == NULL) && (file == NULL)) + return (0); + return (1); +} +LCRYPTO_ALIAS(X509_STORE_load_locations); + +int +X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len) +{ + X509_LOOKUP *lookup; + struct iovec iov; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_mem()); + if (lookup == NULL) + return (0); + + iov.iov_base = buf; + iov.iov_len = len; + + if (X509_LOOKUP_add_mem(lookup, &iov, X509_FILETYPE_PEM) != 1) + return (0); + + return (1); +} +LCRYPTO_ALIAS(X509_STORE_load_mem); diff --git a/Libraries/libressl/crypto/x509/x509_def.c b/Libraries/libressl/crypto/x509/x509_def.c new file mode 100644 index 000000000..f85781afd --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_def.c @@ -0,0 +1,104 @@ +/* $OpenBSD: x509_def.c,v 1.7 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +const char * +X509_get_default_private_dir(void) +{ + return (X509_PRIVATE_DIR); +} +LCRYPTO_ALIAS(X509_get_default_private_dir); + +const char * +X509_get_default_cert_area(void) +{ + return (X509_CERT_AREA); +} +LCRYPTO_ALIAS(X509_get_default_cert_area); + +const char * +X509_get_default_cert_dir(void) +{ + return (X509_CERT_DIR); +} +LCRYPTO_ALIAS(X509_get_default_cert_dir); + +const char * +X509_get_default_cert_file(void) +{ + return (X509_CERT_FILE); +} +LCRYPTO_ALIAS(X509_get_default_cert_file); + +const char * +X509_get_default_cert_dir_env(void) +{ + return (X509_CERT_DIR_EVP); +} +LCRYPTO_ALIAS(X509_get_default_cert_dir_env); + +const char * +X509_get_default_cert_file_env(void) +{ + return (X509_CERT_FILE_EVP); +} +LCRYPTO_ALIAS(X509_get_default_cert_file_env); diff --git a/Libraries/libressl/crypto/x509/x509_err.c b/Libraries/libressl/crypto/x509/x509_err.c new file mode 100644 index 000000000..2cbd34935 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_err.c @@ -0,0 +1,213 @@ +/* $OpenBSD: x509_err.c,v 1.22 2023/05/14 17:20:26 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) + +static ERR_STRING_DATA X509_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509_str_reasons[] = { + {ERR_REASON(X509_R_BAD_X509_FILETYPE) , "bad x509 filetype"}, + {ERR_REASON(X509_R_BASE64_DECODE_ERROR) , "base64 decode error"}, + {ERR_REASON(X509_R_CANT_CHECK_DH_KEY) , "cant check dh key"}, + {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), "cert already in hash table"}, + {ERR_REASON(X509_R_ERR_ASN1_LIB) , "err asn1 lib"}, + {ERR_REASON(X509_R_INVALID_DIRECTORY) , "invalid directory"}, + {ERR_REASON(X509_R_INVALID_FIELD_NAME) , "invalid field name"}, + {ERR_REASON(X509_R_INVALID_TRUST) , "invalid trust"}, + {ERR_REASON(X509_R_INVALID_VERSION) , "invalid x509 version"}, + {ERR_REASON(X509_R_KEY_TYPE_MISMATCH) , "key type mismatch"}, + {ERR_REASON(X509_R_KEY_VALUES_MISMATCH) , "key values mismatch"}, + {ERR_REASON(X509_R_LOADING_CERT_DIR) , "loading cert dir"}, + {ERR_REASON(X509_R_LOADING_DEFAULTS) , "loading defaults"}, + {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) , "method not supported"}, + {ERR_REASON(X509_R_NO_CERTIFICATE_OR_CRL_FOUND), "no certificate or crl found"}, + {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), "no cert set for us to verify"}, + {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"}, + {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"}, + {ERR_REASON(X509_R_SHOULD_RETRY) , "should retry"}, + {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), "unable to find parameters in chain"}, + {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), "unable to get certs public key"}, + {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE) , "unknown key type"}, + {ERR_REASON(X509_R_UNKNOWN_NID) , "unknown nid"}, + {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID) , "unknown purpose id"}, + {ERR_REASON(X509_R_UNKNOWN_TRUST_ID) , "unknown trust id"}, + {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, + {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) , "wrong lookup type"}, + {ERR_REASON(X509_R_WRONG_TYPE) , "wrong type"}, + {0, NULL} +}; + +#undef ERR_FUNC +#undef ERR_REASON +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) + +static ERR_STRING_DATA X509V3_str_functs[] = { + {ERR_FUNC(0xfff), "CRYPTO_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509V3_str_reasons[] = { + {ERR_REASON(X509V3_R_BAD_IP_ADDRESS) , "bad ip address"}, + {ERR_REASON(X509V3_R_BAD_OBJECT) , "bad object"}, + {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) , "bn dec2bn error"}, + {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), "bn to asn1 integer error"}, + {ERR_REASON(X509V3_R_DIRNAME_ERROR) , "dirname error"}, + {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, + {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) , "duplicate zone id"}, + {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, + {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), "error creating extension"}, + {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) , "error in extension"}, + {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, + {ERR_REASON(X509V3_R_EXTENSION_EXISTS) , "extension exists"}, + {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, + {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, + {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), "extension setting not supported"}, + {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, + {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, + {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) , "illegal hex digit"}, + {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), "incorrect policy syntax tag"}, + {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, + {ERR_REASON(X509V3_R_INVALID_ASNUMBER) , "invalid asnumber"}, + {ERR_REASON(X509V3_R_INVALID_ASRANGE) , "invalid asrange"}, + {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, + {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), "invalid extension string"}, + {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, + {ERR_REASON(X509V3_R_INVALID_IPADDRESS) , "invalid ipaddress"}, + {ERR_REASON(X509V3_R_INVALID_NAME) , "invalid name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(X509V3_R_INVALID_NULL_NAME) , "invalid null name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_VALUE) , "invalid null value"}, + {ERR_REASON(X509V3_R_INVALID_NUMBER) , "invalid number"}, + {ERR_REASON(X509V3_R_INVALID_NUMBERS) , "invalid numbers"}, + {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), "invalid object identifier"}, + {ERR_REASON(X509V3_R_INVALID_OPTION) , "invalid option"}, + {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), "invalid policy identifier"}, + {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), "invalid proxy policy setting"}, + {ERR_REASON(X509V3_R_INVALID_PURPOSE) , "invalid purpose"}, + {ERR_REASON(X509V3_R_INVALID_SAFI) , "invalid safi"}, + {ERR_REASON(X509V3_R_INVALID_SECTION) , "invalid section"}, + {ERR_REASON(X509V3_R_INVALID_SYNTAX) , "invalid syntax"}, + {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, + {ERR_REASON(X509V3_R_MISSING_VALUE) , "missing value"}, + {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), "need organization and numbers"}, + {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) , "no config database"}, + {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, + {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS) , "no issuer details"}, + {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, + {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), "no proxy cert policy language defined"}, + {ERR_REASON(X509V3_R_NO_PUBLIC_KEY) , "no public key"}, + {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) , "no subject details"}, + {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, + {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, + {ERR_REASON(X509V3_R_OTHERNAME_ERROR) , "othername error"}, + {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), "policy language already defined"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) , "policy path length"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), "policy path length already defined"}, + {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), "policy syntax not currently supported"}, + {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), "policy when proxy language requires no policy"}, + {ERR_REASON(X509V3_R_SECTION_NOT_FOUND) , "section not found"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), "unable to get issuer details"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), "unable to get issuer keyid"}, + {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), "unknown bit string argument"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION) , "unknown extension"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, + {ERR_REASON(X509V3_R_UNKNOWN_OPTION) , "unknown option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) , "unsupported option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) , "unsupported type"}, + {ERR_REASON(X509V3_R_USER_TOO_LONG) , "user too long"}, + {0, NULL} +}; + +#endif + +void +ERR_load_X509_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509_str_functs); + ERR_load_strings(0, X509_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_X509_strings); + + +void +ERR_load_X509V3_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509V3_str_functs); + ERR_load_strings(0, X509V3_str_reasons); + } +#endif +} +LCRYPTO_ALIAS(ERR_load_X509V3_strings); diff --git a/Libraries/libressl/crypto/x509/x509_ext.c b/Libraries/libressl/crypto/x509/x509_ext.c new file mode 100644 index 000000000..ce316d25b --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_ext.c @@ -0,0 +1,262 @@ +/* $OpenBSD: x509_ext.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "x509_local.h" + +int +X509_CRL_get_ext_count(const X509_CRL *x) +{ + return (X509v3_get_ext_count(x->crl->extensions)); +} +LCRYPTO_ALIAS(X509_CRL_get_ext_count); + +int +X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); +} +LCRYPTO_ALIAS(X509_CRL_get_ext_by_NID); + +int +X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); +} +LCRYPTO_ALIAS(X509_CRL_get_ext_by_OBJ); + +int +X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); +} +LCRYPTO_ALIAS(X509_CRL_get_ext_by_critical); + +X509_EXTENSION * +X509_CRL_get_ext(const X509_CRL *x, int loc) +{ + return (X509v3_get_ext(x->crl->extensions, loc)); +} +LCRYPTO_ALIAS(X509_CRL_get_ext); + +X509_EXTENSION * +X509_CRL_delete_ext(X509_CRL *x, int loc) +{ + return (X509v3_delete_ext(x->crl->extensions, loc)); +} +LCRYPTO_ALIAS(X509_CRL_delete_ext); + +void * +X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); +} +LCRYPTO_ALIAS(X509_CRL_get_ext_d2i); + +int +X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); +} +LCRYPTO_ALIAS(X509_CRL_add1_ext_i2d); + +int +X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); +} +LCRYPTO_ALIAS(X509_CRL_add_ext); + +int +X509_get_ext_count(const X509 *x) +{ + return (X509v3_get_ext_count(x->cert_info->extensions)); +} +LCRYPTO_ALIAS(X509_get_ext_count); + +int +X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); +} +LCRYPTO_ALIAS(X509_get_ext_by_NID); + +int +X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); +} +LCRYPTO_ALIAS(X509_get_ext_by_OBJ); + +int +X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->cert_info->extensions, crit, + lastpos)); +} +LCRYPTO_ALIAS(X509_get_ext_by_critical); + +X509_EXTENSION * +X509_get_ext(const X509 *x, int loc) +{ + return (X509v3_get_ext(x->cert_info->extensions, loc)); +} +LCRYPTO_ALIAS(X509_get_ext); + +X509_EXTENSION * +X509_delete_ext(X509 *x, int loc) +{ + return (X509v3_delete_ext(x->cert_info->extensions, loc)); +} +LCRYPTO_ALIAS(X509_delete_ext); + +int +X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); +} +LCRYPTO_ALIAS(X509_add_ext); + +void * +X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); +} +LCRYPTO_ALIAS(X509_get_ext_d2i); + +int +X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags) +{ + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, + flags); +} +LCRYPTO_ALIAS(X509_add1_ext_i2d); + +int +X509_REVOKED_get_ext_count(const X509_REVOKED *x) +{ + return (X509v3_get_ext_count(x->extensions)); +} +LCRYPTO_ALIAS(X509_REVOKED_get_ext_count); + +int +X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); +} +LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_NID); + +int +X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); +} +LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_OBJ); + +int +X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); +} +LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_critical); + +X509_EXTENSION * +X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) +{ + return (X509v3_get_ext(x->extensions, loc)); +} +LCRYPTO_ALIAS(X509_REVOKED_get_ext); + +X509_EXTENSION * +X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_delete_ext(x->extensions, loc)); +} +LCRYPTO_ALIAS(X509_REVOKED_delete_ext); + +int +X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); +} +LCRYPTO_ALIAS(X509_REVOKED_add_ext); + +void * +X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->extensions, nid, crit, idx); +} +LCRYPTO_ALIAS(X509_REVOKED_get_ext_d2i); + +int +X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); +} +LCRYPTO_ALIAS(X509_REVOKED_add1_ext_i2d); diff --git a/Libraries/libressl/crypto/x509/x509_extku.c b/Libraries/libressl/crypto/x509/x509_extku.c new file mode 100644 index 000000000..94032f624 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_extku.c @@ -0,0 +1,221 @@ +/* $OpenBSD: x509_extku.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE( + const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist); + +const X509V3_EXT_METHOD v3_ext_ku = { + .ext_nid = NID_ext_key_usage, + .ext_flags = 0, + .it = &EXTENDED_KEY_USAGE_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_EXTENDED_KEY_USAGE, + .v2i = v2i_EXTENDED_KEY_USAGE, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD v3_ocsp_accresp = { + .ext_nid = NID_id_pkix_OCSP_acceptableResponses, + .ext_flags = 0, + .it = &EXTENDED_KEY_USAGE_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_EXTENDED_KEY_USAGE, + .v2i = v2i_EXTENDED_KEY_USAGE, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE EXTENDED_KEY_USAGE_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "EXTENDED_KEY_USAGE", + .item = &ASN1_OBJECT_it, +}; + +const ASN1_ITEM EXTENDED_KEY_USAGE_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &EXTENDED_KEY_USAGE_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "EXTENDED_KEY_USAGE", +}; + + +EXTENDED_KEY_USAGE * +d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len) +{ + return (EXTENDED_KEY_USAGE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &EXTENDED_KEY_USAGE_it); +} +LCRYPTO_ALIAS(d2i_EXTENDED_KEY_USAGE); + +int +i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &EXTENDED_KEY_USAGE_it); +} +LCRYPTO_ALIAS(i2d_EXTENDED_KEY_USAGE); + +EXTENDED_KEY_USAGE * +EXTENDED_KEY_USAGE_new(void) +{ + return (EXTENDED_KEY_USAGE *)ASN1_item_new(&EXTENDED_KEY_USAGE_it); +} +LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_new); + +void +EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &EXTENDED_KEY_USAGE_it); +} +LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_free); + +static STACK_OF(CONF_VALUE) * +i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *extlist) +{ + ASN1_OBJECT *obj; + EXTENDED_KEY_USAGE *eku = a; + STACK_OF(CONF_VALUE) *free_extlist = NULL; + char obj_tmp[80]; + int i; + + if (extlist == NULL) { + if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + if ((obj = sk_ASN1_OBJECT_value(eku, i)) == NULL) + goto err; + if (!i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, obj)) + goto err; + if (!X509V3_add_value(NULL, obj_tmp, &extlist)) + goto err; + } + + return extlist; + + err: + sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); + + return NULL; +} + +static void * +v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + EXTENDED_KEY_USAGE *extku; + char *extval; + ASN1_OBJECT *objtmp; + CONF_VALUE *val; + int i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (val->value) + extval = val->value; + else + extval = val->name; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + if (sk_ASN1_OBJECT_push(extku, objtmp) == 0) { + ASN1_OBJECT_free(objtmp); + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + } + return extku; +} diff --git a/Libraries/libressl/crypto/x509/x509_genn.c b/Libraries/libressl/crypto/x509/x509_genn.c new file mode 100644 index 000000000..556ba81c8 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_genn.c @@ -0,0 +1,537 @@ +/* $OpenBSD: x509_genn.c,v 1.6 2023/04/25 15:51:04 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include + +#include +#include +#include + +static const ASN1_TEMPLATE OTHERNAME_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OTHERNAME, type_id), + .field_name = "type_id", + .item = &ASN1_OBJECT_it, + }, + /* Maybe have a true ANY DEFINED BY later */ + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(OTHERNAME, value), + .field_name = "value", + .item = &ASN1_ANY_it, + }, +}; + +const ASN1_ITEM OTHERNAME_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OTHERNAME_seq_tt, + .tcount = sizeof(OTHERNAME_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OTHERNAME), + .sname = "OTHERNAME", +}; + + +OTHERNAME * +d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len) +{ + return (OTHERNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OTHERNAME_it); +} +LCRYPTO_ALIAS(d2i_OTHERNAME); + +int +i2d_OTHERNAME(OTHERNAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it); +} +LCRYPTO_ALIAS(i2d_OTHERNAME); + +OTHERNAME * +OTHERNAME_new(void) +{ + return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it); +} +LCRYPTO_ALIAS(OTHERNAME_new); + +void +OTHERNAME_free(OTHERNAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it); +} +LCRYPTO_ALIAS(OTHERNAME_free); + +/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */ +static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(EDIPARTYNAME, nameAssigner), + .field_name = "nameAssigner", + .item = &DIRECTORYSTRING_it, + }, + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 1, + .offset = offsetof(EDIPARTYNAME, partyName), + .field_name = "partyName", + .item = &DIRECTORYSTRING_it, + }, +}; + +const ASN1_ITEM EDIPARTYNAME_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = EDIPARTYNAME_seq_tt, + .tcount = sizeof(EDIPARTYNAME_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(EDIPARTYNAME), + .sname = "EDIPARTYNAME", +}; + + +EDIPARTYNAME * +d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len) +{ + return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &EDIPARTYNAME_it); +} +LCRYPTO_ALIAS(d2i_EDIPARTYNAME); + +int +i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it); +} +LCRYPTO_ALIAS(i2d_EDIPARTYNAME); + +EDIPARTYNAME * +EDIPARTYNAME_new(void) +{ + return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it); +} +LCRYPTO_ALIAS(EDIPARTYNAME_new); + +void +EDIPARTYNAME_free(EDIPARTYNAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it); +} +LCRYPTO_ALIAS(EDIPARTYNAME_free); + +static const ASN1_TEMPLATE GENERAL_NAME_ch_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_OTHERNAME, + .offset = offsetof(GENERAL_NAME, d.otherName), + .field_name = "d.otherName", + .item = &OTHERNAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_EMAIL, + .offset = offsetof(GENERAL_NAME, d.rfc822Name), + .field_name = "d.rfc822Name", + .item = &ASN1_IA5STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_DNS, + .offset = offsetof(GENERAL_NAME, d.dNSName), + .field_name = "d.dNSName", + .item = &ASN1_IA5STRING_it, + }, + /* Don't decode this */ + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_X400, + .offset = offsetof(GENERAL_NAME, d.x400Address), + .field_name = "d.x400Address", + .item = &ASN1_SEQUENCE_it, + }, + /* X509_NAME is a CHOICE type so use EXPLICIT */ + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = GEN_DIRNAME, + .offset = offsetof(GENERAL_NAME, d.directoryName), + .field_name = "d.directoryName", + .item = &X509_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_EDIPARTY, + .offset = offsetof(GENERAL_NAME, d.ediPartyName), + .field_name = "d.ediPartyName", + .item = &EDIPARTYNAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_URI, + .offset = offsetof(GENERAL_NAME, d.uniformResourceIdentifier), + .field_name = "d.uniformResourceIdentifier", + .item = &ASN1_IA5STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_IPADD, + .offset = offsetof(GENERAL_NAME, d.iPAddress), + .field_name = "d.iPAddress", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_RID, + .offset = offsetof(GENERAL_NAME, d.registeredID), + .field_name = "d.registeredID", + .item = &ASN1_OBJECT_it, + }, +}; + +const ASN1_ITEM GENERAL_NAME_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(GENERAL_NAME, type), + .templates = GENERAL_NAME_ch_tt, + .tcount = sizeof(GENERAL_NAME_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GENERAL_NAME), + .sname = "GENERAL_NAME", +}; + + +GENERAL_NAME * +d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len) +{ + return (GENERAL_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GENERAL_NAME_it); +} +LCRYPTO_ALIAS(d2i_GENERAL_NAME); + +int +i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it); +} +LCRYPTO_ALIAS(i2d_GENERAL_NAME); + +GENERAL_NAME * +GENERAL_NAME_new(void) +{ + return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it); +} +LCRYPTO_ALIAS(GENERAL_NAME_new); + +void +GENERAL_NAME_free(GENERAL_NAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it); +} +LCRYPTO_ALIAS(GENERAL_NAME_free); + +static const ASN1_TEMPLATE GENERAL_NAMES_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "GeneralNames", + .item = &GENERAL_NAME_it, +}; + +const ASN1_ITEM GENERAL_NAMES_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &GENERAL_NAMES_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "GENERAL_NAMES", +}; + + +GENERAL_NAMES * +d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len) +{ + return (GENERAL_NAMES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GENERAL_NAMES_it); +} +LCRYPTO_ALIAS(d2i_GENERAL_NAMES); + +int +i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it); +} +LCRYPTO_ALIAS(i2d_GENERAL_NAMES); + +GENERAL_NAMES * +GENERAL_NAMES_new(void) +{ + return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it); +} +LCRYPTO_ALIAS(GENERAL_NAMES_new); + +void +GENERAL_NAMES_free(GENERAL_NAMES *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it); +} +LCRYPTO_ALIAS(GENERAL_NAMES_free); + +GENERAL_NAME * +GENERAL_NAME_dup(GENERAL_NAME *a) +{ + return ASN1_item_dup(&GENERAL_NAME_it, a); +} +LCRYPTO_ALIAS(GENERAL_NAME_dup); + +static int +EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) +{ + int res; + + /* + * Shouldn't be possible in a valid GENERAL_NAME, but we handle it + * anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here. + */ + if (a == NULL || b == NULL) + return -1; + if (a->nameAssigner == NULL && b->nameAssigner != NULL) + return -1; + if (a->nameAssigner != NULL && b->nameAssigner == NULL) + return 1; + /* If we get here, both have nameAssigner set or both unset. */ + if (a->nameAssigner != NULL) { + res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner); + if (res != 0) + return res; + } + /* + * partyName is required, so these should never be NULL. We treat it in + * the same way as the a == NULL || b == NULL case above. + */ + if (a->partyName == NULL || b->partyName == NULL) + return -1; + + return ASN1_STRING_cmp(a->partyName, b->partyName); +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int +GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + switch (a->type) { + case GEN_X400: + result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); + break; + + case GEN_EDIPARTY: + result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName); + break; + + case GEN_OTHERNAME: + result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); + break; + + case GEN_DIRNAME: + result = X509_NAME_cmp(a->d.dirn, b->d.dirn); + break; + + case GEN_IPADD: + result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); + break; + + case GEN_RID: + result = OBJ_cmp(a->d.rid, b->d.rid); + break; + } + return result; +} +LCRYPTO_ALIAS(GENERAL_NAME_cmp); + +/* Returns 0 if they are equal, != 0 otherwise. */ +int +OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) +{ + int result = -1; + + if (!a || !b) + return -1; + /* Check their type first. */ + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) + return result; + /* Check the value. */ + result = ASN1_TYPE_cmp(a->value, b->value); + return result; +} +LCRYPTO_ALIAS(OTHERNAME_cmp); + +void +GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) +{ + switch (type) { + case GEN_X400: + a->d.x400Address = value; + break; + + case GEN_EDIPARTY: + a->d.ediPartyName = value; + break; + + case GEN_OTHERNAME: + a->d.otherName = value; + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + a->d.ia5 = value; + break; + + case GEN_DIRNAME: + a->d.dirn = value; + break; + + case GEN_IPADD: + a->d.ip = value; + break; + + case GEN_RID: + a->d.rid = value; + break; + } + a->type = type; +} +LCRYPTO_ALIAS(GENERAL_NAME_set0_value); + +void * +GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) +{ + if (ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: + return a->d.x400Address; + + case GEN_EDIPARTY: + return a->d.ediPartyName; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; + + default: + return NULL; + } +} +LCRYPTO_ALIAS(GENERAL_NAME_get0_value); + +int +GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid, + ASN1_TYPE *value) +{ + OTHERNAME *oth; + + oth = OTHERNAME_new(); + if (!oth) + return 0; + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; +} +LCRYPTO_ALIAS(GENERAL_NAME_set0_othername); + +int +GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, ASN1_OBJECT **poid, + ASN1_TYPE **pvalue) +{ + if (gen->type != GEN_OTHERNAME) + return 0; + if (poid) + *poid = gen->d.otherName->type_id; + if (pvalue) + *pvalue = gen->d.otherName->value; + return 1; +} +LCRYPTO_ALIAS(GENERAL_NAME_get0_otherName); diff --git a/Libraries/libressl/crypto/x509/x509_ia5.c b/Libraries/libressl/crypto/x509/x509_ia5.c new file mode 100644 index 000000000..4113c3d3b --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_ia5.c @@ -0,0 +1,238 @@ +/* $OpenBSD: x509_ia5.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_ns_ia5_list[] = { + { + .ext_nid = NID_netscape_base_url, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_revocation_url, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_ca_revocation_url, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_renewal_url, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_ca_policy_url, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_ssl_server_name, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_comment, + .ext_flags = 0, + .it = &ASN1_IA5STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = -1, + .ext_flags = 0, + .it = NULL, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, +}; + +static char * +i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5) +{ + char *tmp; + + if (!ia5 || !ia5->length) + return NULL; + if (!(tmp = malloc(ia5->length + 1))) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + memcpy(tmp, ia5->data, ia5->length); + tmp[ia5->length] = 0; + return tmp; +} + +static ASN1_IA5STRING * +s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) +{ + ASN1_IA5STRING *ia5; + if (!str) { + X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(ia5 = ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str, + strlen(str))) { + ASN1_IA5STRING_free(ia5); + goto err; + } + return ia5; + +err: + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; +} diff --git a/Libraries/libressl/crypto/x509/x509_info.c b/Libraries/libressl/crypto/x509/x509_info.c new file mode 100644 index 000000000..a3d4d1bcc --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_info.c @@ -0,0 +1,317 @@ +/* $OpenBSD: x509_info.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, + STACK_OF(CONF_VALUE) *ret); +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_info = { + .ext_nid = NID_info_access, + .ext_flags = X509V3_EXT_MULTILINE, + .it = &AUTHORITY_INFO_ACCESS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, + .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_sinfo = { + .ext_nid = NID_sinfo_access, + .ext_flags = X509V3_EXT_MULTILINE, + .it = &AUTHORITY_INFO_ACCESS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, + .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE ACCESS_DESCRIPTION_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ACCESS_DESCRIPTION, method), + .field_name = "method", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ACCESS_DESCRIPTION, location), + .field_name = "location", + .item = &GENERAL_NAME_it, + }, +}; + +const ASN1_ITEM ACCESS_DESCRIPTION_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ACCESS_DESCRIPTION_seq_tt, + .tcount = sizeof(ACCESS_DESCRIPTION_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ACCESS_DESCRIPTION), + .sname = "ACCESS_DESCRIPTION", +}; + + +ACCESS_DESCRIPTION * +d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len) +{ + return (ACCESS_DESCRIPTION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ACCESS_DESCRIPTION_it); +} +LCRYPTO_ALIAS(d2i_ACCESS_DESCRIPTION); + +int +i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ACCESS_DESCRIPTION_it); +} +LCRYPTO_ALIAS(i2d_ACCESS_DESCRIPTION); + +ACCESS_DESCRIPTION * +ACCESS_DESCRIPTION_new(void) +{ + return (ACCESS_DESCRIPTION *)ASN1_item_new(&ACCESS_DESCRIPTION_it); +} +LCRYPTO_ALIAS(ACCESS_DESCRIPTION_new); + +void +ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ACCESS_DESCRIPTION_it); +} +LCRYPTO_ALIAS(ACCESS_DESCRIPTION_free); + +static const ASN1_TEMPLATE AUTHORITY_INFO_ACCESS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "GeneralNames", + .item = &ACCESS_DESCRIPTION_it, +}; + +const ASN1_ITEM AUTHORITY_INFO_ACCESS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &AUTHORITY_INFO_ACCESS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "AUTHORITY_INFO_ACCESS", +}; + + +AUTHORITY_INFO_ACCESS * +d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len) +{ + return (AUTHORITY_INFO_ACCESS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &AUTHORITY_INFO_ACCESS_it); +} +LCRYPTO_ALIAS(d2i_AUTHORITY_INFO_ACCESS); + +int +i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_INFO_ACCESS_it); +} +LCRYPTO_ALIAS(i2d_AUTHORITY_INFO_ACCESS); + +AUTHORITY_INFO_ACCESS * +AUTHORITY_INFO_ACCESS_new(void) +{ + return (AUTHORITY_INFO_ACCESS *)ASN1_item_new(&AUTHORITY_INFO_ACCESS_it); +} +LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_new); + +void +AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_INFO_ACCESS_it); +} +LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_free); + +static STACK_OF(CONF_VALUE) * +i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, + AUTHORITY_INFO_ACCESS *ainfo, STACK_OF(CONF_VALUE) *ret) +{ + ACCESS_DESCRIPTION *desc; + CONF_VALUE *vtmp; + STACK_OF(CONF_VALUE) *free_ret = NULL; + char objtmp[80], *ntmp; + int i; + + if (ret == NULL) { + if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + if ((desc = sk_ACCESS_DESCRIPTION_value(ainfo, i)) == NULL) + goto err; + if ((ret = i2v_GENERAL_NAME(method, desc->location, + ret)) == NULL) + goto err; + if ((vtmp = sk_CONF_VALUE_value(ret, i)) == NULL) + goto err; + if (!i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method)) + goto err; + if (asprintf(&ntmp, "%s - %s", objtmp, vtmp->name) == -1) { + ntmp = NULL; + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + free(vtmp->name); + vtmp->name = ntmp; + } + + return ret; + + err: + sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); + + return NULL; +} + +static AUTHORITY_INFO_ACCESS * +v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + AUTHORITY_INFO_ACCESS *ainfo = NULL; + CONF_VALUE *cnf, ctmp; + ACCESS_DESCRIPTION *acc; + int i, objlen; + char *objtmp, *ptmp; + + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if ((acc = ACCESS_DESCRIPTION_new()) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + if (sk_ACCESS_DESCRIPTION_push(ainfo, acc) == 0) { + ACCESS_DESCRIPTION_free(acc); + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + X509V3error(X509V3_R_INVALID_SYNTAX); + goto err; + } + objlen = ptmp - cnf->name; + ctmp.name = ptmp + 1; + ctmp.value = cnf->value; + if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) + goto err; + if (!(objtmp = malloc(objlen + 1))) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + strlcpy(objtmp, cnf->name, objlen + 1); + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + X509V3error(X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("value=%s", objtmp); + free(objtmp); + goto err; + } + free(objtmp); + } + return ainfo; + +err: + sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); + return NULL; +} + +int +i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a) +{ + i2a_ASN1_OBJECT(bp, a->method); + return 2; +} +LCRYPTO_ALIAS(i2a_ACCESS_DESCRIPTION); diff --git a/Libraries/libressl/crypto/x509/x509_int.c b/Libraries/libressl/crypto/x509/x509_int.c new file mode 100644 index 000000000..35c8853c1 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_int.c @@ -0,0 +1,110 @@ +/* $OpenBSD: x509_int.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +const X509V3_EXT_METHOD v3_crl_num = { + .ext_nid = NID_crl_number, + .ext_flags = 0, + .it = &ASN1_INTEGER_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_delta_crl = { + .ext_nid = NID_delta_crl, + .ext_flags = 0, + .it = &ASN1_INTEGER_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static void * +s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value) +{ + return s2i_ASN1_INTEGER(meth, value); +} + +const X509V3_EXT_METHOD v3_inhibit_anyp = { + NID_inhibit_any_policy, 0, &ASN1_INTEGER_it, + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + (X509V3_EXT_S2I)s2i_asn1_int, + 0, 0, 0, 0, + NULL +}; diff --git a/Libraries/libressl/crypto/x509/x509_internal.h b/Libraries/libressl/crypto/x509/x509_internal.h new file mode 100644 index 000000000..15efff609 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_internal.h @@ -0,0 +1,141 @@ +/* $OpenBSD: x509_internal.h,v 1.26 2023/09/29 15:53:59 beck Exp $ */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef HEADER_X509_INTERNAL_H +#define HEADER_X509_INTERNAL_H + +/* Internal use only, not public API */ +#include + +#include "bytestring.h" +#include "x509_local.h" +#include "x509_verify.h" + +/* Hard limits on structure size and number of signature checks. */ +#define X509_VERIFY_MAX_CHAINS 8 /* Max validated chains */ +#define X509_VERIFY_MAX_CHAIN_CERTS 32 /* Max depth of a chain */ +#define X509_VERIFY_MAX_SIGCHECKS 256 /* Max signature checks */ + +/* + * Limit the number of names and constraints we will check in a chain + * to avoid a hostile input DOS + */ +#define X509_VERIFY_MAX_CHAIN_NAMES 512 +#define X509_VERIFY_MAX_CHAIN_CONSTRAINTS 512 + +/* + * Hold the parsed and validated result of names from a certificate. + * these typically come from a GENERALNAME, but we store the parsed + * and validated results, not the ASN1 bytes. + */ +struct x509_constraints_name { + int type; /* GEN_* types from GENERAL_NAME */ + char *name; /* Name to check */ + char *local; /* holds the local part of GEN_EMAIL */ + uint8_t *der; /* DER encoded value or NULL*/ + size_t der_len; + int af; /* INET and INET6 are supported */ + uint8_t address[32]; /* Must hold ipv6 + mask */ +}; + +struct x509_constraints_names { + struct x509_constraints_name **names; + size_t names_count; + size_t names_len; + size_t names_max; +}; + +struct x509_verify_chain { + STACK_OF(X509) *certs; /* Kept in chain order, includes leaf */ + int *cert_errors; /* Verify error for each cert in chain. */ + struct x509_constraints_names *names; /* All names from all certs */ +}; + +struct x509_verify_ctx { + X509_STORE_CTX *xsc; + struct x509_verify_chain **chains; /* Validated chains */ + STACK_OF(X509) *saved_error_chain; + int saved_error; + int saved_error_depth; + size_t chains_count; + STACK_OF(X509) *roots; /* Trusted roots for this validation */ + STACK_OF(X509) *intermediates; /* Intermediates provided by peer */ + time_t *check_time; /* Time for validity checks */ + int purpose; /* Cert purpose we are validating */ + size_t max_chains; /* Max chains to return */ + size_t max_depth; /* Max chain depth for validation */ + size_t max_sigs; /* Max number of signature checks */ + size_t sig_checks; /* Number of signature checks done */ + size_t error_depth; /* Depth of last error seen */ + int error; /* Last error seen */ +}; + +int ASN1_time_tm_clamp_notafter(struct tm *tm); + +__BEGIN_HIDDEN_DECLS + +int x509_vfy_check_id(X509_STORE_CTX *ctx); +int x509_vfy_check_revocation(X509_STORE_CTX *ctx); +int x509_vfy_check_policy(X509_STORE_CTX *ctx); +int x509_vfy_check_trust(X509_STORE_CTX *ctx); +int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx); +int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx); +int x509v3_cache_extensions(X509 *x); +X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); + +time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter); + +struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); + +void x509_constraints_name_clear(struct x509_constraints_name *name); +void x509_constraints_name_free(struct x509_constraints_name *name); +int x509_constraints_names_add(struct x509_constraints_names *names, + struct x509_constraints_name *name); +struct x509_constraints_names *x509_constraints_names_dup( + struct x509_constraints_names *names); +void x509_constraints_names_clear(struct x509_constraints_names *names); +struct x509_constraints_names *x509_constraints_names_new(size_t names_max); +int x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes, + size_t *len); +void x509_constraints_names_free(struct x509_constraints_names *names); +int x509_constraints_valid_host(CBS *cbs, int permit_ip); +int x509_constraints_valid_sandns(CBS *cbs); +int x509_constraints_domain(char *domain, size_t dlen, char *constraint, + size_t len); +int x509_constraints_parse_mailbox(CBS *candidate, + struct x509_constraints_name *name); +int x509_constraints_valid_domain_constraint(CBS *cbs); +int x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostp); +int x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, + size_t len, int *error); +int x509_constraints_extract_names(struct x509_constraints_names *names, + X509 *cert, int include_cn, int *error); +int x509_constraints_extract_constraints(X509 *cert, + struct x509_constraints_names *permitted, + struct x509_constraints_names *excluded, int *error); +int x509_constraints_validate(GENERAL_NAME *constraint, + struct x509_constraints_name **out_name, int *error); +int x509_constraints_check(struct x509_constraints_names *names, + struct x509_constraints_names *permitted, + struct x509_constraints_names *excluded, int *error); +int x509_constraints_chain(STACK_OF(X509) *chain, int *error, + int *depth); +void x509_verify_cert_info_populate(X509 *cert); +int x509_vfy_check_security_level(X509_STORE_CTX *ctx); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/crypto/x509/x509_issuer_cache.c b/Libraries/libressl/crypto/x509/x509_issuer_cache.c new file mode 100644 index 000000000..f7fbd54ca --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_issuer_cache.c @@ -0,0 +1,193 @@ +/* $OpenBSD: x509_issuer_cache.c,v 1.4 2022/12/26 07:18:53 jmc Exp $ */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* x509_issuer_cache */ + +/* + * The issuer cache is a cache of parent and child x509 certificate + * hashes with a signature validation result. + * + * Entries should only be added to the cache with a validation result + * from checking the public key math that "parent" signed "child". + * + * Finding an entry in the cache gets us the result of a previously + * performed validation of the signature of "parent" signing for the + * validity of "child". It allows us to skip doing the public key math + * when validating a certificate chain. It does not allow us to skip + * any other steps of validation (times, names, key usage, etc.) + */ + +#include +#include + +#include "x509_issuer_cache.h" + +static int +x509_issuer_cmp(struct x509_issuer *x1, struct x509_issuer *x2) +{ + int pcmp; + if ((pcmp = memcmp(x1->parent_md, x2->parent_md, EVP_MAX_MD_SIZE)) != 0) + return pcmp; + return memcmp(x1->child_md, x2->child_md, EVP_MAX_MD_SIZE); +} + +static size_t x509_issuer_cache_count; +static size_t x509_issuer_cache_max = X509_ISSUER_CACHE_MAX; +static RB_HEAD(x509_issuer_tree, x509_issuer) x509_issuer_cache = + RB_INITIALIZER(&x509_issuer_cache); +static TAILQ_HEAD(lruqueue, x509_issuer) x509_issuer_lru = + TAILQ_HEAD_INITIALIZER(x509_issuer_lru); +static pthread_mutex_t x509_issuer_tree_mutex = PTHREAD_MUTEX_INITIALIZER; + +RB_PROTOTYPE(x509_issuer_tree, x509_issuer, entry, x509_issuer_cmp); +RB_GENERATE(x509_issuer_tree, x509_issuer, entry, x509_issuer_cmp); + +/* + * Set the maximum number of cached entries. On additions to the cache + * the least recently used entries will be discarded so that the cache + * stays under the maximum number of entries. Setting a maximum of 0 + * disables the cache. + */ +int +x509_issuer_cache_set_max(size_t max) +{ + if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) + return 0; + x509_issuer_cache_max = max; + (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); + + return 1; +} + +/* + * Free the oldest entry in the issuer cache. Returns 1 + * if an entry was successfully freed, 0 otherwise. Must + * be called with x509_issuer_tree_mutex held. + */ +void +x509_issuer_cache_free_oldest() +{ + struct x509_issuer *old; + + if (x509_issuer_cache_count == 0) + return; + old = TAILQ_LAST(&x509_issuer_lru, lruqueue); + TAILQ_REMOVE(&x509_issuer_lru, old, queue); + RB_REMOVE(x509_issuer_tree, &x509_issuer_cache, old); + free(old->parent_md); + free(old->child_md); + free(old); + x509_issuer_cache_count--; +} + +/* + * Free the entire issuer cache, discarding all entries. + */ +void +x509_issuer_cache_free() +{ + if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) + return; + while (x509_issuer_cache_count > 0) + x509_issuer_cache_free_oldest(); + (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); +} + +/* + * Find a previous result of checking if parent signed child + * + * Returns: + * -1 : No entry exists in the cache. signature must be checked. + * 0 : The signature of parent signing child is invalid. + * 1 : The signature of parent signing child is valid. + */ +int +x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md) +{ + struct x509_issuer candidate, *found; + int ret = -1; + + memset(&candidate, 0, sizeof(candidate)); + candidate.parent_md = parent_md; + candidate.child_md = child_md; + + if (x509_issuer_cache_max == 0) + return -1; + + if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) + return -1; + if ((found = RB_FIND(x509_issuer_tree, &x509_issuer_cache, + &candidate)) != NULL) { + TAILQ_REMOVE(&x509_issuer_lru, found, queue); + TAILQ_INSERT_HEAD(&x509_issuer_lru, found, queue); + ret = found->valid; + } + (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); + + return ret; +} + +/* + * Attempt to add a validation result to the cache. + * + * valid must be: + * 0: The signature of parent signing child is invalid. + * 1: The signature of parent signing child is valid. + * + * Previously added entries for the same parent and child are *not* replaced. + */ +void +x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md, + int valid) +{ + struct x509_issuer *new; + + if (x509_issuer_cache_max == 0) + return; + if (valid != 0 && valid != 1) + return; + + if ((new = calloc(1, sizeof(struct x509_issuer))) == NULL) + return; + if ((new->parent_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL) + goto err; + memcpy(new->parent_md, parent_md, EVP_MAX_MD_SIZE); + if ((new->child_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL) + goto err; + memcpy(new->child_md, child_md, EVP_MAX_MD_SIZE); + + new->valid = valid; + + if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) + goto err; + while (x509_issuer_cache_count >= x509_issuer_cache_max) + x509_issuer_cache_free_oldest(); + if (RB_INSERT(x509_issuer_tree, &x509_issuer_cache, new) == NULL) { + TAILQ_INSERT_HEAD(&x509_issuer_lru, new, queue); + x509_issuer_cache_count++; + new = NULL; + } + (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); + + err: + if (new != NULL) { + free(new->parent_md); + free(new->child_md); + } + free(new); + return; +} diff --git a/Libraries/libressl/crypto/x509/x509_issuer_cache.h b/Libraries/libressl/crypto/x509/x509_issuer_cache.h new file mode 100644 index 000000000..3afe65bd4 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_issuer_cache.h @@ -0,0 +1,48 @@ +/* $OpenBSD: x509_issuer_cache.h,v 1.2 2022/09/03 17:47:47 jsing Exp $ */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* x509_issuer_cache */ +#ifndef HEADER_X509_ISSUER_CACHE_H +#define HEADER_X509_ISSUER_CACHE_H + +#include +#include + +#include + +__BEGIN_HIDDEN_DECLS + +struct x509_issuer { + RB_ENTRY(x509_issuer) entry; + TAILQ_ENTRY(x509_issuer) queue; /* LRU of entries */ + /* parent_md and child_md must point to EVP_MAX_MD_SIZE of memory */ + unsigned char *parent_md; + unsigned char *child_md; + int valid; /* Result of signature validation. */ +}; + +#define X509_ISSUER_CACHE_MAX 40000 /* Approx 7.5 MB, entries 200 bytes */ + +int x509_issuer_cache_set_max(size_t max); +int x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md); +void x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md, + int valid); +void x509_issuer_cache_free(); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/crypto/x509/x509_lib.c b/Libraries/libressl/crypto/x509/x509_lib.c new file mode 100644 index 000000000..93f8dc207 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_lib.c @@ -0,0 +1,436 @@ +/* $OpenBSD: x509_lib.c,v 1.14 2023/04/25 10:56:58 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include + +#include +#include +#include + +#include "x509_local.h" + +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_info, v3_sinfo; +extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; +extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; +extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; +extern const X509V3_EXT_METHOD v3_crl_hold; +extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern const X509V3_EXT_METHOD v3_addr, v3_asid; +extern const X509V3_EXT_METHOD v3_ct_scts[3]; + +/* + * This table needs to be sorted by increasing ext_nid values for OBJ_bsearch_. + */ + +static const X509V3_EXT_METHOD *standard_exts[] = { + &v3_nscert, + &v3_ns_ia5_list[0], + &v3_ns_ia5_list[1], + &v3_ns_ia5_list[2], + &v3_ns_ia5_list[3], + &v3_ns_ia5_list[4], + &v3_ns_ia5_list[5], + &v3_ns_ia5_list[6], + &v3_skey_id, + &v3_key_usage, + &v3_pkey_usage_period, + &v3_alt[0], + &v3_alt[1], + &v3_bcons, + &v3_crl_num, + &v3_cpols, + &v3_akey_id, + &v3_crld, + &v3_ext_ku, + &v3_delta_crl, + &v3_crl_reason, +#ifndef OPENSSL_NO_OCSP + &v3_crl_invdate, +#endif + &v3_info, +#ifndef OPENSSL_NO_RFC3779 + &v3_addr, + &v3_asid, +#endif +#ifndef OPENSSL_NO_OCSP + &v3_ocsp_nonce, + &v3_ocsp_crlid, + &v3_ocsp_accresp, + &v3_ocsp_nocheck, + &v3_ocsp_acutoff, + &v3_ocsp_serviceloc, +#endif + &v3_sinfo, + &v3_policy_constraints, +#ifndef OPENSSL_NO_OCSP + &v3_crl_hold, +#endif + &v3_name_constraints, + &v3_policy_mappings, + &v3_inhibit_anyp, + &v3_idp, + &v3_alt[2], + &v3_freshest_crl, +#ifndef OPENSSL_NO_CT + &v3_ct_scts[0], + &v3_ct_scts[1], + &v3_ct_scts[2], +#endif +}; + +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts) / sizeof(standard_exts[0])) + +static int +ext_cmp(const X509V3_EXT_METHOD * const *a, const X509V3_EXT_METHOD * const *b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +int +X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) { + X509V3error(ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + X509V3error(ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} +LCRYPTO_ALIAS(X509V3_EXT_add); + +static int +ext_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + const X509V3_EXT_METHOD * const *a = a_; + const X509V3_EXT_METHOD * const *b = b_; + return ext_cmp(a, b); +} + +static const X509V3_EXT_METHOD ** +OBJ_bsearch_ext(const X509V3_EXT_METHOD **key, + const X509V3_EXT_METHOD *const *base, int num) +{ + return (const X509V3_EXT_METHOD **)OBJ_bsearch_(key, base, num, + sizeof(const X509V3_EXT_METHOD *), ext_cmp_BSEARCH_CMP_FN); +} + +const X509V3_EXT_METHOD * +X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, * const *ret; + int idx; + + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); + if (ret) + return *ret; + if (!ext_list) + return NULL; + idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); + if (idx == -1) + return NULL; + return sk_X509V3_EXT_METHOD_value(ext_list, idx); +} +LCRYPTO_ALIAS(X509V3_EXT_get_nid); + +const X509V3_EXT_METHOD * +X509V3_EXT_get(X509_EXTENSION *ext) +{ + int nid; + + if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) + return NULL; + return X509V3_EXT_get_nid(nid); +} +LCRYPTO_ALIAS(X509V3_EXT_get); + +int +X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) +{ + for (; extlist->ext_nid!=-1; extlist++) + if (!X509V3_EXT_add(extlist)) + return 0; + return 1; +} +LCRYPTO_ALIAS(X509V3_EXT_add_list); + +int +X509V3_EXT_add_alias(int nid_to, int nid_from) +{ + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + + if (!(ext = X509V3_EXT_get_nid(nid_from))) { + X509V3error(X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (!(tmpext = malloc(sizeof(X509V3_EXT_METHOD)))) { + X509V3error(ERR_R_MALLOC_FAILURE); + return 0; + } + *tmpext = *ext; + tmpext->ext_nid = nid_to; + tmpext->ext_flags |= X509V3_EXT_DYNAMIC; + if (!X509V3_EXT_add(tmpext)) { + free(tmpext); + return 0; + } + return 1; +} +LCRYPTO_ALIAS(X509V3_EXT_add_alias); + +static void +ext_list_free(X509V3_EXT_METHOD *ext) +{ + if (ext->ext_flags & X509V3_EXT_DYNAMIC) + free(ext); +} + +void +X509V3_EXT_cleanup(void) +{ + sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); + ext_list = NULL; +} +LCRYPTO_ALIAS(X509V3_EXT_cleanup); + +int +X509V3_add_standard_extensions(void) +{ + return 1; +} +LCRYPTO_ALIAS(X509V3_add_standard_extensions); + +/* Return an extension internal structure */ + +void * +X509V3_EXT_d2i(X509_EXTENSION *ext) +{ + const X509V3_EXT_METHOD *method; + const unsigned char *p; + + if (!(method = X509V3_EXT_get(ext))) + return NULL; + p = ext->value->data; + if (method->it) + return ASN1_item_d2i(NULL, &p, ext->value->length, + method->it); + return method->d2i(NULL, &p, ext->value->length); +} +LCRYPTO_ALIAS(X509V3_EXT_d2i); + +/* Get critical flag and decoded version of extension from a NID. + * The "idx" variable returns the last found extension and can + * be used to retrieve multiple extensions of the same NID. + * However multiple extensions with the same NID is usually + * due to a badly encoded certificate so if idx is NULL we + * choke if multiple extensions exist. + * The "crit" variable is set to the critical value. + * The return value is the decoded extension or NULL on + * error. The actual error can have several different causes, + * the value of *crit reflects the cause: + * >= 0, extension found but not decoded (reflects critical value). + * -1 extension not found. + * -2 extension occurs more than once. + */ + +void * +X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx) +{ + int lastpos, i; + X509_EXTENSION *ex, *found_ex = NULL; + + if (!x) { + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; + } + if (idx) + lastpos = *idx + 1; + else + lastpos = 0; + if (lastpos < 0) + lastpos = 0; + for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { + ex = sk_X509_EXTENSION_value(x, i); + if (OBJ_obj2nid(ex->object) == nid) { + if (idx) { + *idx = i; + found_ex = ex; + break; + } else if (found_ex) { + /* Found more than one */ + if (crit) + *crit = -2; + return NULL; + } + found_ex = ex; + } + } + if (found_ex) { + /* Found it */ + if (crit) + *crit = X509_EXTENSION_get_critical(found_ex); + return X509V3_EXT_d2i(found_ex); + } + + /* Extension not found */ + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; +} +LCRYPTO_ALIAS(X509V3_get_d2i); + +/* This function is a general extension append, replace and delete utility. + * The precise operation is governed by the 'flags' value. The 'crit' and + * 'value' arguments (if relevant) are the extensions internal structure. + */ + +int +X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags) +{ + int extidx = -1; + int errcode; + X509_EXTENSION *ext, *extmp; + unsigned long ext_op = flags & X509V3_ADD_OP_MASK; + + /* If appending we don't care if it exists, otherwise + * look for existing extension. + */ + if (ext_op != X509V3_ADD_APPEND) + extidx = X509v3_get_ext_by_NID(*x, nid, -1); + + /* See if extension exists */ + if (extidx >= 0) { + /* If keep existing, nothing to do */ + if (ext_op == X509V3_ADD_KEEP_EXISTING) + return 1; + /* If default then its an error */ + if (ext_op == X509V3_ADD_DEFAULT) { + errcode = X509V3_R_EXTENSION_EXISTS; + goto err; + } + /* If delete, just delete it */ + if (ext_op == X509V3_ADD_DELETE) { + if ((extmp = sk_X509_EXTENSION_delete(*x, extidx)) == NULL) + return -1; + X509_EXTENSION_free(extmp); + return 1; + } + } else { + /* If replace existing or delete, error since + * extension must exist + */ + if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || + (ext_op == X509V3_ADD_DELETE)) { + errcode = X509V3_R_EXTENSION_NOT_FOUND; + goto err; + } + } + + /* If we get this far then we have to create an extension: + * could have some flags for alternative encoding schemes... + */ + + ext = X509V3_EXT_i2d(nid, crit, value); + + if (!ext) { + X509V3error(X509V3_R_ERROR_CREATING_EXTENSION); + return 0; + } + + /* If extension exists replace it.. */ + if (extidx >= 0) { + extmp = sk_X509_EXTENSION_value(*x, extidx); + X509_EXTENSION_free(extmp); + if (!sk_X509_EXTENSION_set(*x, extidx, ext)) + return -1; + return 1; + } + + if (!*x && !(*x = sk_X509_EXTENSION_new_null())) + return -1; + if (!sk_X509_EXTENSION_push(*x, ext)) + return -1; + + return 1; + +err: + if (!(flags & X509V3_ADD_SILENT)) + X509V3error(errcode); + return 0; +} +LCRYPTO_ALIAS(X509V3_add1_i2d); diff --git a/Libraries/libressl/crypto/x509/x509_local.h b/Libraries/libressl/crypto/x509/x509_local.h new file mode 100644 index 000000000..f00a55bac --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_local.h @@ -0,0 +1,388 @@ +/* $OpenBSD: x509_local.h,v 1.9 2023/05/28 05:25:24 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2013. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_X509_LOCAL_H +#define HEADER_X509_LOCAL_H + +__BEGIN_HIDDEN_DECLS + +#define TS_HASH_EVP EVP_sha1() +#define TS_HASH_LEN SHA_DIGEST_LENGTH + +#define X509_CERT_HASH_EVP EVP_sha512() +#define X509_CERT_HASH_LEN SHA512_DIGEST_LENGTH +#define X509_CRL_HASH_EVP EVP_sha512() +#define X509_CRL_HASH_LEN SHA512_DIGEST_LENGTH + +struct X509_pubkey_st { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; +}; + +struct X509_sig_st { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; +} /* X509_SIG */; + +struct X509_name_entry_st { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ +} /* X509_NAME_ENTRY */; + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +#ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +#else + char *bytes; +#endif +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; +} /* X509_NAME */; + +struct X509_extension_st { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; +} /* X509_EXTENSION */; + +struct x509_attributes_st { + ASN1_OBJECT *object; + STACK_OF(ASN1_TYPE) *set; +} /* X509_ATTRIBUTE */; + +struct X509_req_info_st { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} /* X509_REQ_INFO */; + +struct X509_req_st { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; +} /* X509_REQ */; + +/* + * This stuff is certificate "auxiliary info" it contains details which are + * useful in certificate stores and databases. When used this is tagged onto + * the end of the certificate itself. + */ +struct x509_cert_aux_st { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ +} /* X509_CERT_AUX */; + +struct x509_cinf_st { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + ASN1_ENCODING enc; +} /* X509_CINF */; + +struct x509_st { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +#ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; +#endif + unsigned char hash[X509_CERT_HASH_LEN]; + time_t not_before; + time_t not_after; + X509_CERT_AUX *aux; +} /* X509 */; + +struct x509_revoked_st { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; + int sequence; /* load sequence */ +}; + +struct X509_crl_info_st { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; +} /* X509_CRL_INFO */; + +struct X509_crl_st { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; + unsigned char hash[X509_CRL_HASH_LEN]; + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; +} /* X509_CRL */; + +struct pkcs8_priv_key_info_st { + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + ASN1_OCTET_STRING *pkey; + STACK_OF(X509_ATTRIBUTE) *attributes; +}; + +struct x509_object_st { + /* one of the above types */ + int type; + union { + X509 *x509; + X509_CRL *crl; + } data; +} /* X509_OBJECT */; + +struct x509_lookup_method_st { + const char *name; + int (*new_item)(X509_LOOKUP *ctx); + void (*free)(X509_LOOKUP *ctx); + int (*init)(X509_LOOKUP *ctx); + int (*shutdown)(X509_LOOKUP *ctx); + int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); + int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial)(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial,X509_OBJECT *ret); + int (*get_by_fingerprint)(X509_LOOKUP *ctx, int type, + const unsigned char *bytes, int len, X509_OBJECT *ret); + int (*get_by_alias)(X509_LOOKUP *ctx, int type, const char *str, + int len, X509_OBJECT *ret); +} /* X509_LOOKUP_METHOD */; + +struct X509_VERIFY_PARAM_st { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + int security_level; /* 'Security level', see SP800-57. */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ + STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ + unsigned int hostflags; /* Flags to control matching features */ + char *peername; /* Matching hostname in peer certificate */ + char *email; /* If not NULL email address to match */ + size_t emaillen; + unsigned char *ip; /* If not NULL IP address to match */ + size_t iplen; /* Length of IP address */ + int poisoned; +} /* X509_VERIFY_PARAM */; + +/* + * This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' + * function is then called to actually check the cert chain. + */ +struct x509_store_st { + /* The following is a cache of trusted certs */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup)(X509_STORE_CTX *ctx); + + CRYPTO_EX_DATA ex_data; + int references; +} /* X509_STORE */; + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st { + int init; /* have we been started */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + + X509_STORE *store_ctx; /* who owns us */ +} /* X509_LOOKUP */; + +/* + * This is used when verifying cert chains. Since the gathering of the cert + * chain can take some time (and has to be 'retried'), this needs to be kept + * and passed around. + */ +struct x509_store_ctx_st { + X509_STORE *store; + int current_method; /* used when looking up certs */ + + /* The following are set by the caller */ + X509 *cert; /* The cert to check */ + STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */ + STACK_OF(X509) *trusted; /* trusted stack for use with get_issuer() */ + STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + int (*check_policy)(X509_STORE_CTX *ctx); + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup)(X509_STORE_CTX *ctx); + + /* The following is built up */ + int valid; /* if 0, rebuild chain */ + int num_untrusted; /* number of untrusted certs in chain */ + STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */ + + int explicit_policy; /* Require explicit policy value */ + + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; /* cert currently being tested as valid issuer */ + X509_CRL *current_crl; /* current CRL */ + + int current_crl_score; /* score of current CRL */ + unsigned int current_reasons; /* Reason mask */ + + X509_STORE_CTX *parent; /* For CRL path validation: parent context */ + + CRYPTO_EX_DATA ex_data; +} /* X509_STORE_CTX */; + +int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet); + +int name_cmp(const char *name, const char *cmp); + +int X509_policy_check(const STACK_OF(X509) *certs, + const STACK_OF(ASN1_OBJECT) *user_policies, unsigned long flags, + X509 **out_current_cert); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_X509_LOCAL_H */ diff --git a/Libraries/libressl/crypto/x509/x509_lu.c b/Libraries/libressl/crypto/x509/x509_lu.c new file mode 100644 index 000000000..05730f56c --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_lu.c @@ -0,0 +1,880 @@ +/* $OpenBSD: x509_lu.c,v 1.60 2023/04/25 18:32:42 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include "x509_local.h" + +X509_LOOKUP * +X509_LOOKUP_new(X509_LOOKUP_METHOD *method) +{ + X509_LOOKUP *lu; + + if ((lu = calloc(1, sizeof(*lu))) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + lu->method = method; + + if (method->new_item != NULL && !method->new_item(lu)) { + free(lu); + return NULL; + } + + return lu; +} +LCRYPTO_ALIAS(X509_LOOKUP_new); + +void +X509_LOOKUP_free(X509_LOOKUP *ctx) +{ + if (ctx == NULL) + return; + if (ctx->method != NULL && ctx->method->free != NULL) + ctx->method->free(ctx); + free(ctx); +} +LCRYPTO_ALIAS(X509_LOOKUP_free); + +int +X509_LOOKUP_init(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->init == NULL) + return 1; + return ctx->method->init(ctx); +} +LCRYPTO_ALIAS(X509_LOOKUP_init); + +int +X509_LOOKUP_shutdown(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->shutdown == NULL) + return 1; + return ctx->method->shutdown(ctx); +} +LCRYPTO_ALIAS(X509_LOOKUP_shutdown); + +int +X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + if (ctx->method == NULL) + return -1; + if (ctx->method->ctrl == NULL) + return 1; + return ctx->method->ctrl(ctx, cmd, argc, argl, ret); +} +LCRYPTO_ALIAS(X509_LOOKUP_ctrl); + +int +X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, X509_NAME *name, + X509_OBJECT *ret) +{ + if (ctx->method == NULL || ctx->method->get_by_subject == NULL) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret); +} +LCRYPTO_ALIAS(X509_LOOKUP_by_subject); + +int +X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, ASN1_INTEGER *serial, X509_OBJECT *ret) +{ + if (ctx->method == NULL || ctx->method->get_by_issuer_serial == NULL) + return 0; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); +} +LCRYPTO_ALIAS(X509_LOOKUP_by_issuer_serial); + +int +X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const unsigned char *bytes, int len, X509_OBJECT *ret) +{ + if (ctx->method == NULL || ctx->method->get_by_fingerprint == NULL) + return 0; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); +} +LCRYPTO_ALIAS(X509_LOOKUP_by_fingerprint); + +int +X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str, + int len, X509_OBJECT *ret) +{ + if (ctx->method == NULL || ctx->method->get_by_alias == NULL) + return 0; + return ctx->method->get_by_alias(ctx, type, str, len, ret); +} +LCRYPTO_ALIAS(X509_LOOKUP_by_alias); + +static int +x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) +{ + int ret; + + if ((ret = (*a)->type - (*b)->type) != 0) + return ret; + + switch ((*a)->type) { + case X509_LU_X509: + return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); + case X509_LU_CRL: + return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); + } + return 0; +} + +X509_STORE * +X509_STORE_new(void) +{ + X509_STORE *store; + + if ((store = calloc(1, sizeof(*store))) == NULL) + goto err; + + if ((store->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) + goto err; + if ((store->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) + goto err; + if ((store->param = X509_VERIFY_PARAM_new()) == NULL) + goto err; + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, + &store->ex_data)) + goto err; + + store->references = 1; + + return store; + + err: + X509error(ERR_R_MALLOC_FAILURE); + X509_STORE_free(store); + + return NULL; +} +LCRYPTO_ALIAS(X509_STORE_new); + +X509_OBJECT * +X509_OBJECT_new(void) +{ + X509_OBJECT *obj; + + if ((obj = calloc(1, sizeof(*obj))) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + obj->type = X509_LU_NONE; + + return obj; +} +LCRYPTO_ALIAS(X509_OBJECT_new); + +void +X509_OBJECT_free(X509_OBJECT *a) +{ + if (a == NULL) + return; + + switch (a->type) { + case X509_LU_X509: + X509_free(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_free(a->data.crl); + break; + } + + free(a); +} +LCRYPTO_ALIAS(X509_OBJECT_free); + +void +X509_STORE_free(X509_STORE *store) +{ + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + int i; + + if (store == NULL) + return; + + if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0) + return; + + sk = store->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data); + X509_VERIFY_PARAM_free(store->param); + free(store); +} +LCRYPTO_ALIAS(X509_STORE_free); + +int +X509_STORE_up_ref(X509_STORE *store) +{ + return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1; +} +LCRYPTO_ALIAS(X509_STORE_up_ref); + +X509_LOOKUP * +X509_STORE_add_lookup(X509_STORE *store, X509_LOOKUP_METHOD *method) +{ + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + int i; + + sk = store->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + if (method == lu->method) { + return lu; + } + } + + if ((lu = X509_LOOKUP_new(method)) == NULL) + return NULL; + + lu->store_ctx = store; + if (sk_X509_LOOKUP_push(store->get_cert_methods, lu) <= 0) { + X509error(ERR_R_MALLOC_FAILURE); + X509_LOOKUP_free(lu); + return NULL; + } + + return lu; +} +LCRYPTO_ALIAS(X509_STORE_add_lookup); + +X509_OBJECT * +X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, + X509_NAME *name) +{ + X509_OBJECT *obj; + + if ((obj = X509_OBJECT_new()) == NULL) + return NULL; + if (!X509_STORE_CTX_get_by_subject(vs, type, name, obj)) { + X509_OBJECT_free(obj); + return NULL; + } + + return obj; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_obj_by_subject); + +int +X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret) +{ + X509_STORE *ctx = vs->store; + X509_LOOKUP *lu; + X509_OBJECT stmp, *tmp; + int i; + + if (ctx == NULL) + return 0; + + memset(&stmp, 0, sizeof(stmp)); + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) { + tmp = &stmp; + break; + } + } + if (tmp == NULL) + return 0; + } + + if (!X509_OBJECT_up_ref_count(tmp)) + return 0; + + *ret = *tmp; + + return 1; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_by_subject); + +/* Add obj to the store. Takes ownership of obj. */ +static int +X509_STORE_add_object(X509_STORE *store, X509_OBJECT *obj) +{ + int ret = 0; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + if (X509_OBJECT_retrieve_match(store->objs, obj) != NULL) { + /* Object is already present in the store. That's fine. */ + ret = 1; + goto out; + } + + if (sk_X509_OBJECT_push(store->objs, obj) <= 0) { + X509error(ERR_R_MALLOC_FAILURE); + goto out; + } + + obj = NULL; + ret = 1; + + out: + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_OBJECT_free(obj); + + return ret; +} + +int +X509_STORE_add_cert(X509_STORE *store, X509 *x) +{ + X509_OBJECT *obj; + + if (x == NULL) + return 0; + + if ((obj = X509_OBJECT_new()) == NULL) + return 0; + + if (!X509_up_ref(x)) { + X509_OBJECT_free(obj); + return 0; + } + + obj->type = X509_LU_X509; + obj->data.x509 = x; + + return X509_STORE_add_object(store, obj); +} +LCRYPTO_ALIAS(X509_STORE_add_cert); + +int +X509_STORE_add_crl(X509_STORE *store, X509_CRL *x) +{ + X509_OBJECT *obj; + + if (x == NULL) + return 0; + + if ((obj = X509_OBJECT_new()) == NULL) + return 0; + + if (!X509_CRL_up_ref(x)) { + X509_OBJECT_free(obj); + return 0; + } + + obj->type = X509_LU_CRL; + obj->data.crl = x; + + return X509_STORE_add_object(store, obj); +} +LCRYPTO_ALIAS(X509_STORE_add_crl); + +int +X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + return X509_up_ref(a->data.x509); + case X509_LU_CRL: + return X509_CRL_up_ref(a->data.crl); + } + return 1; +} +LCRYPTO_ALIAS(X509_OBJECT_up_ref_count); + +X509_LOOKUP_TYPE +X509_OBJECT_get_type(const X509_OBJECT *a) +{ + return a->type; +} +LCRYPTO_ALIAS(X509_OBJECT_get_type); + +static int +x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name, int *pnmatch) +{ + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; + int idx; + + stmp.type = type; + switch (type) { + case X509_LU_X509: + stmp.data.x509 = &x509_s; + x509_s.cert_info = &cinf_s; + cinf_s.subject = name; + break; + case X509_LU_CRL: + stmp.data.crl = &crl_s; + crl_s.crl = &crl_info_s; + crl_info_s.issuer = name; + break; + default: + return -1; + } + + idx = sk_X509_OBJECT_find(h, &stmp); + if (idx >= 0 && pnmatch) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { + tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(&tobj, &pstmp)) + break; + (*pnmatch)++; + } + } + return idx; +} + +int +X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name) +{ + return x509_object_idx_cnt(h, type, name, NULL); +} +LCRYPTO_ALIAS(X509_OBJECT_idx_by_subject); + +X509_OBJECT * +X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name) +{ + int idx; + + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) + return NULL; + return sk_X509_OBJECT_value(h, idx); +} +LCRYPTO_ALIAS(X509_OBJECT_retrieve_by_subject); + +X509 * +X509_OBJECT_get0_X509(const X509_OBJECT *xo) +{ + if (xo != NULL && xo->type == X509_LU_X509) + return xo->data.x509; + return NULL; +} +LCRYPTO_ALIAS(X509_OBJECT_get0_X509); + +X509_CRL * +X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo) +{ + if (xo != NULL && xo->type == X509_LU_CRL) + return xo->data.crl; + return NULL; +} +LCRYPTO_ALIAS(X509_OBJECT_get0_X509_CRL); + +static STACK_OF(X509) * +X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name) +{ + STACK_OF(X509) *sk = NULL; + X509 *x = NULL; + X509_OBJECT *obj; + int i, idx, cnt; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + idx = x509_object_idx_cnt(store->objs, X509_LU_X509, name, &cnt); + if (idx < 0) + goto err; + + if ((sk = sk_X509_new_null()) == NULL) + goto err; + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(store->objs, idx); + + x = obj->data.x509; + if (!X509_up_ref(x)) { + x = NULL; + goto err; + } + if (!sk_X509_push(sk, x)) + goto err; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return sk; + + err: + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_pop_free(sk, X509_free); + X509_free(x); + + return NULL; +} + +STACK_OF(X509) * +X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name) +{ + X509_STORE *store = ctx->store; + STACK_OF(X509) *sk; + X509_OBJECT *obj; + + if (store == NULL) + return NULL; + + if ((sk = X509_get1_certs_from_cache(store, name)) != NULL) + return sk; + + /* Nothing found: do lookup to possibly add new objects to cache. */ + obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name); + if (obj == NULL) + return NULL; + X509_OBJECT_free(obj); + + return X509_get1_certs_from_cache(store, name); +} +LCRYPTO_ALIAS(X509_STORE_CTX_get1_certs); + +STACK_OF(X509_CRL) * +X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name) +{ + X509_STORE *store = ctx->store; + STACK_OF(X509_CRL) *sk = NULL; + X509_CRL *x = NULL; + X509_OBJECT *obj = NULL; + int i, idx, cnt; + + if (store == NULL) + return NULL; + + /* Always do lookup to possibly add new CRLs to cache */ + obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_CRL, name); + if (obj == NULL) + return NULL; + + X509_OBJECT_free(obj); + obj = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, name, &cnt); + if (idx < 0) + goto err; + + if ((sk = sk_X509_CRL_new_null()) == NULL) + goto err; + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(store->objs, idx); + + x = obj->data.crl; + if (!X509_CRL_up_ref(x)) { + x = NULL; + goto err; + } + if (!sk_X509_CRL_push(sk, x)) + goto err; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + + err: + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get1_crls); + +X509_OBJECT * +X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) +{ + int idx, i; + X509_OBJECT *obj; + + idx = sk_X509_OBJECT_find(h, x); + if (idx == -1) + return NULL; + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp((const X509_OBJECT **)&obj, + (const X509_OBJECT **)&x)) + return NULL; + if (x->type == X509_LU_X509) { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } else if (x->type == X509_LU_CRL) { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } else + return obj; + } + return NULL; +} +LCRYPTO_ALIAS(X509_OBJECT_retrieve_match); + +/* Try to get issuer certificate from store. Due to limitations + * of the API this can only retrieve a single certificate matching + * a given subject name. However it will fill the cache with all + * matching certificates, so we can examine the cache for all + * matches. + * + * Return values are: + * 1 lookup successful. + * 0 certificate not found. + * -1 some other error. + */ +int +X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x) +{ + X509_NAME *xn; + X509_OBJECT *obj, *pobj; + X509 *issuer = NULL; + int i, idx, ret; + + *out_issuer = NULL; + + xn = X509_get_issuer_name(x); + obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn); + if (obj == NULL) + return 0; + + if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) { + X509_OBJECT_free(obj); + return 0; + } + if (!X509_up_ref(issuer)) { + X509_OBJECT_free(obj); + return -1; + } + + /* If certificate matches all OK */ + if (ctx->check_issued(ctx, x, issuer)) { + if (x509_check_cert_time(ctx, issuer, -1)) { + *out_issuer = issuer; + X509_OBJECT_free(obj); + return 1; + } + } + X509_free(issuer); + issuer = NULL; + X509_OBJECT_free(obj); + obj = NULL; + + if (ctx->store == NULL) + return 0; + + /* Else find index of first cert accepted by 'check_issued' */ + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = X509_OBJECT_idx_by_subject(ctx->store->objs, X509_LU_X509, xn); + if (idx != -1) /* should be true as we've had at least one match */ { + /* Look through all matching certs for suitable issuer */ + for (i = idx; i < sk_X509_OBJECT_num(ctx->store->objs); i++) { + pobj = sk_X509_OBJECT_value(ctx->store->objs, i); + /* See if we've run past the matches */ + if (pobj->type != X509_LU_X509) + break; + if (X509_NAME_cmp(xn, + X509_get_subject_name(pobj->data.x509))) + break; + if (ctx->check_issued(ctx, x, pobj->data.x509)) { + issuer = pobj->data.x509; + /* + * If times check, exit with match, + * otherwise keep looking. Leave last + * match in issuer so we return nearest + * match if no certificate time is OK. + */ + if (x509_check_cert_time(ctx, issuer, -1)) + break; + } + } + } + ret = 0; + if (issuer != NULL) { + if (!X509_up_ref(issuer)) { + ret = -1; + } else { + *out_issuer = issuer; + ret = 1; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return ret; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get1_issuer); + +STACK_OF(X509_OBJECT) * +X509_STORE_get0_objects(X509_STORE *xs) +{ + return xs->objs; +} +LCRYPTO_ALIAS(X509_STORE_get0_objects); + +void * +X509_STORE_get_ex_data(X509_STORE *xs, int idx) +{ + return CRYPTO_get_ex_data(&xs->ex_data, idx); +} +LCRYPTO_ALIAS(X509_STORE_get_ex_data); + +int +X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data) +{ + return CRYPTO_set_ex_data(&xs->ex_data, idx, data); +} +LCRYPTO_ALIAS(X509_STORE_set_ex_data); + +int +X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) +{ + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} +LCRYPTO_ALIAS(X509_STORE_set_flags); + +int +X509_STORE_set_depth(X509_STORE *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; +} +LCRYPTO_ALIAS(X509_STORE_set_depth); + +int +X509_STORE_set_purpose(X509_STORE *ctx, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} +LCRYPTO_ALIAS(X509_STORE_set_purpose); + +int +X509_STORE_set_trust(X509_STORE *ctx, int trust) +{ + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} +LCRYPTO_ALIAS(X509_STORE_set_trust); + +int +X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) +{ + return X509_VERIFY_PARAM_set1(ctx->param, param); +} +LCRYPTO_ALIAS(X509_STORE_set1_param); + +X509_VERIFY_PARAM * +X509_STORE_get0_param(X509_STORE *ctx) +{ + return ctx->param; +} +LCRYPTO_ALIAS(X509_STORE_get0_param); + +void +X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify) +{ + store->verify = verify; +} +LCRYPTO_ALIAS(X509_STORE_set_verify); + +X509_STORE_CTX_verify_fn +X509_STORE_get_verify(X509_STORE *store) +{ + return store->verify; +} +LCRYPTO_ALIAS(X509_STORE_get_verify); + +void +X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb) +{ + store->verify_cb = verify_cb; +} +LCRYPTO_ALIAS(X509_STORE_set_verify_cb); + +X509_STORE_CTX_verify_cb +X509_STORE_get_verify_cb(X509_STORE *store) +{ + return store->verify_cb; +} +LCRYPTO_ALIAS(X509_STORE_get_verify_cb); diff --git a/Libraries/libressl/crypto/x509/x509_ncons.c b/Libraries/libressl/crypto/x509/x509_ncons.c new file mode 100644 index 000000000..159e3c256 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_ncons.c @@ -0,0 +1,561 @@ +/* $OpenBSD: x509_ncons.c,v 1.9 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "x509_local.h" + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + void *a, BIO *bp, int ind); +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name); +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); +static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); + +const X509V3_EXT_METHOD v3_name_constraints = { + .ext_nid = NID_name_constraints, + .ext_flags = 0, + .it = &NAME_CONSTRAINTS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_NAME_CONSTRAINTS, + .i2r = i2r_NAME_CONSTRAINTS, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE GENERAL_SUBTREE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GENERAL_SUBTREE, base), + .field_name = "base", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(GENERAL_SUBTREE, minimum), + .field_name = "minimum", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(GENERAL_SUBTREE, maximum), + .field_name = "maximum", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM GENERAL_SUBTREE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GENERAL_SUBTREE_seq_tt, + .tcount = sizeof(GENERAL_SUBTREE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GENERAL_SUBTREE), + .sname = "GENERAL_SUBTREE", +}; + +static const ASN1_TEMPLATE NAME_CONSTRAINTS_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(NAME_CONSTRAINTS, permittedSubtrees), + .field_name = "permittedSubtrees", + .item = &GENERAL_SUBTREE_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(NAME_CONSTRAINTS, excludedSubtrees), + .field_name = "excludedSubtrees", + .item = &GENERAL_SUBTREE_it, + }, +}; + +const ASN1_ITEM NAME_CONSTRAINTS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = NAME_CONSTRAINTS_seq_tt, + .tcount = sizeof(NAME_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(NAME_CONSTRAINTS), + .sname = "NAME_CONSTRAINTS", +}; + + +GENERAL_SUBTREE * +GENERAL_SUBTREE_new(void) +{ + return (GENERAL_SUBTREE*)ASN1_item_new(&GENERAL_SUBTREE_it); +} +LCRYPTO_ALIAS(GENERAL_SUBTREE_new); + +void +GENERAL_SUBTREE_free(GENERAL_SUBTREE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GENERAL_SUBTREE_it); +} +LCRYPTO_ALIAS(GENERAL_SUBTREE_free); + +NAME_CONSTRAINTS * +NAME_CONSTRAINTS_new(void) +{ + return (NAME_CONSTRAINTS*)ASN1_item_new(&NAME_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(NAME_CONSTRAINTS_new); + +void +NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &NAME_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(NAME_CONSTRAINTS_free); + +static void * +v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE tval, *val; + STACK_OF(GENERAL_SUBTREE) **ptree = NULL; + NAME_CONSTRAINTS *ncons = NULL; + GENERAL_SUBTREE *sub = NULL; + + ncons = NAME_CONSTRAINTS_new(); + if (!ncons) + goto memerr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!strncmp(val->name, "permitted", 9) && val->name[9]) { + ptree = &ncons->permittedSubtrees; + tval.name = val->name + 10; + } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { + ptree = &ncons->excludedSubtrees; + tval.name = val->name + 9; + } else { + X509V3error(X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) + goto err; + if (!*ptree) + *ptree = sk_GENERAL_SUBTREE_new_null(); + if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) + goto memerr; + sub = NULL; + } + + return ncons; + +memerr: + X509V3error(ERR_R_MALLOC_FAILURE); +err: + NAME_CONSTRAINTS_free(ncons); + GENERAL_SUBTREE_free(sub); + return NULL; +} + +static int +i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind) +{ + NAME_CONSTRAINTS *ncons = a; + + do_i2r_name_constraints(method, ncons->permittedSubtrees, + bp, ind, "Permitted"); + do_i2r_name_constraints(method, ncons->excludedSubtrees, + bp, ind, "Excluded"); + return 1; +} + +static int +do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name) +{ + GENERAL_SUBTREE *tree; + int i; + + if (sk_GENERAL_SUBTREE_num(trees) > 0) + BIO_printf(bp, "%*s%s:\n", ind, "", name); + for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + tree = sk_GENERAL_SUBTREE_value(trees, i); + BIO_printf(bp, "%*s", ind + 2, ""); + if (tree->base->type == GEN_IPADD) + print_nc_ipadd(bp, tree->base->d.ip); + else + GENERAL_NAME_print(bp, tree->base); + BIO_puts(bp, "\n"); + } + return 1; +} + +static int +print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) +{ + int i, len; + unsigned char *p; + + p = ip->data; + len = ip->length; + BIO_puts(bp, "IP:"); + if (len == 8) { + BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + } else if (len == 32) { + for (i = 0; i < 16; i++) { + BIO_printf(bp, "%X", p[0] << 8 | p[1]); + p += 2; + if (i == 7) + BIO_puts(bp, "/"); + else if (i != 15) + BIO_puts(bp, ":"); + } + } else + BIO_printf(bp, "IP Address:"); + return 1; +} + +/* Check a certificate conforms to a specified set of constraints. + * Return values: + * X509_V_OK: All constraints obeyed. + * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. + * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. + * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. + * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name + */ + +int +NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) +{ + int r, i; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + if (X509_NAME_entry_count(nm) > 0) { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + + gntmp.type = GEN_EMAIL; + + /* Process any email address attributes in subject name */ + + for (i = -1;;) { + X509_NAME_ENTRY *ne; + i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i); + if (i == -1) + break; + ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + } + + } + + for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); + r = nc_match(gen, nc); + if (r != X509_V_OK) + return r; + } + return X509_V_OK; +} +LCRYPTO_ALIAS(NAME_CONSTRAINTS_check); +static int +nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) +{ + GENERAL_SUBTREE *sub; + int i, r, match = 0; + + /* Permitted subtrees: if any subtrees exist of matching the type + * at least one subtree must match. + */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + /* If we already have a match don't bother trying any more */ + if (match == 2) + continue; + if (match == 0) + match = 1; + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + match = 2; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + } + + if (match == 1) + return X509_V_ERR_PERMITTED_VIOLATION; + + /* Excluded subtrees: must not match any of these */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + return X509_V_ERR_EXCLUDED_VIOLATION; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + + } + + return X509_V_OK; +} + +static int +nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) +{ + switch (base->type) { + case GEN_DIRNAME: + return nc_dn(gen->d.directoryName, base->d.directoryName); + + case GEN_DNS: + return nc_dns(gen->d.dNSName, base->d.dNSName); + + case GEN_EMAIL: + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + + case GEN_URI: + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } +} + +/* directoryName name constraint matching. + * The canonical encoding of X509_NAME makes this comparison easy. It is + * matched if the subtree is a subset of the name. + */ + +static int +nc_dn(X509_NAME *nm, X509_NAME *base) +{ + /* Ensure canonical encodings are up to date. */ + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->modified && i2d_X509_NAME(base, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->canon_enclen > nm->canon_enclen) + return X509_V_ERR_PERMITTED_VIOLATION; + if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) + return X509_V_ERR_PERMITTED_VIOLATION; + return X509_V_OK; +} + +static int +nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) +{ + char *baseptr = (char *)base->data; + char *dnsptr = (char *)dns->data; + + /* Empty matches everything */ + if (!*baseptr) + return X509_V_OK; + /* Otherwise can add zero or more components on the left so + * compare RHS and if dns is longer and expect '.' as preceding + * character. + */ + if (dns->length > base->length) { + dnsptr += dns->length - base->length; + if (baseptr[0] != '.' && dnsptr[-1] != '.') + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if (strcasecmp(baseptr, dnsptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +} + +static int +nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; + const char *baseat = strchr(baseptr, '@'); + const char *emlat = strchr(emlptr, '@'); + + if (!emlat) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + /* Special case: initial '.' is RHS match */ + if (!baseat && (*baseptr == '.')) { + if (eml->length > base->length) { + emlptr += eml->length - base->length; + if (!strcasecmp(baseptr, emlptr)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* If we have anything before '@' match local part */ + + if (baseat) { + if (baseat != baseptr) { + if ((baseat - baseptr) != (emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + /* Case sensitive match of local part */ + if (strncmp(baseptr, emlptr, emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + } + /* Position base after '@' */ + baseptr = baseat + 1; + } + emlptr = emlat + 1; + /* Just have hostname left to match: case insensitive */ + if (strcasecmp(baseptr, emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +} + +static int +nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *hostptr = (char *)uri->data; + const char *p = strchr(hostptr, ':'); + int hostlen; + + /* Check for foo:// and skip past it */ + if (!p || (p[1] != '/') || (p[2] != '/')) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + hostptr = p + 3; + + /* Determine length of hostname part of URI */ + + /* Look for a port indicator as end of hostname first */ + + p = strchr(hostptr, ':'); + /* Otherwise look for trailing slash */ + if (!p) + p = strchr(hostptr, '/'); + + if (!p) + hostlen = strlen(hostptr); + else + hostlen = p - hostptr; + + if (hostlen == 0) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* Special case: initial '.' is RHS match */ + if (*baseptr == '.') { + if (hostlen > base->length) { + p = hostptr + hostlen - base->length; + if (!strncasecmp(p, baseptr, base->length)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) || + strncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +} diff --git a/Libraries/libressl/crypto/x509/x509_obj.c b/Libraries/libressl/crypto/x509/x509_obj.c new file mode 100644 index 000000000..ea4ae6b98 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_obj.c @@ -0,0 +1,182 @@ +/* $OpenBSD: x509_obj.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "x509_local.h" + +char * +X509_NAME_oneline(const X509_NAME *a, char *buf, int len) +{ + X509_NAME_ENTRY *ne; + int i; + int n, lold, l, l1, l2, num, j, type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b = NULL; + static const char hex[17] = "0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; + + if (buf == NULL) { + if ((b = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(b, 200)) + goto err; + b->data[0] = '\0'; + len = 200; + } + if (a == NULL) { + if (b) { + buf = b->data; + free(b); + } + strlcpy(buf, "NO X509_NAME", len); + return buf; + } + + len--; /* space for '\0' */ + l = 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + ne = sk_X509_NAME_ENTRY_value(a->entries, i); + n = OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { + i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); + s = tmp_buf; + } + l1 = strlen(s); + + type = ne->value->type; + num = ne->value->length; + q = ne->value->data; + if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; + for (j = 0; j < num; j++) + if (q[j] != 0) + gs_doit[j & 3] = 1; + + if (gs_doit[0]|gs_doit[1]|gs_doit[2]) + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; + gs_doit[3] = 1; + } + } else + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + + for (l2 = j=0; j < num; j++) { + if (!gs_doit[j&3]) + continue; + l2++; + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (b != NULL) { + if (!BUF_MEM_grow(b, l + 1)) + goto err; + p = &(b->data[lold]); + } else if (l > len) { + break; + } else + p = &(buf[lold]); + *(p++) = '/'; + memcpy(p, s, l1); + p += l1; + *(p++) = '='; + q = ne->value->data; + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + +err: + X509error(ERR_R_MALLOC_FAILURE); + if (b != NULL) + BUF_MEM_free(b); + return (NULL); +} +LCRYPTO_ALIAS(X509_NAME_oneline); diff --git a/Libraries/libressl/crypto/x509/x509_ocsp.c b/Libraries/libressl/crypto/x509/x509_ocsp.c new file mode 100644 index 000000000..cc55d9390 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_ocsp.c @@ -0,0 +1,382 @@ +/* $OpenBSD: x509_ocsp.c,v 1.2 2022/01/07 09:45:52 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_OCSP + +#include +#include +#include +#include +#include + +#include "ocsp_local.h" + +/* OCSP extensions and a couple of CRL entry extensions + */ + +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, + int indent); + +static void *ocsp_nonce_new(void); +static int i2d_ocsp_nonce(void *a, unsigned char **pp); +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); +static void ocsp_nonce_free(void *a); +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, + void *nocheck, BIO *out, int indent); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str); +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind); + +const X509V3_EXT_METHOD v3_ocsp_crlid = { + .ext_nid = NID_id_pkix_OCSP_CrlID, + .ext_flags = 0, + .it = &OCSP_CRLID_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_crlid, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_acutoff = { + .ext_nid = NID_id_pkix_OCSP_archiveCutoff, + .ext_flags = 0, + .it = &ASN1_GENERALIZEDTIME_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_acutoff, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_crl_invdate = { + .ext_nid = NID_invalidity_date, + .ext_flags = 0, + .it = &ASN1_GENERALIZEDTIME_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_acutoff, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_crl_hold = { + .ext_nid = NID_hold_instruction_code, + .ext_flags = 0, + .it = &ASN1_OBJECT_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_object, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_nonce = { + .ext_nid = NID_id_pkix_OCSP_Nonce, + .ext_flags = 0, + .it = NULL, + .ext_new = ocsp_nonce_new, + .ext_free = ocsp_nonce_free, + .d2i = d2i_ocsp_nonce, + .i2d = i2d_ocsp_nonce, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_nonce, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_nocheck = { + .ext_nid = NID_id_pkix_OCSP_noCheck, + .ext_flags = 0, + .it = &ASN1_NULL_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = s2i_ocsp_nocheck, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_nocheck, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_serviceloc = { + .ext_nid = NID_id_pkix_OCSP_serviceLocator, + .ext_flags = 0, + .it = &OCSP_SERVICELOC_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_serviceloc, + .r2i = NULL, + .usr_data = NULL, +}; + +static int +i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) +{ + OCSP_CRLID *a = in; + if (a->crlUrl) { + if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) + goto err; + if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlNum) { + if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) + goto err; + if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlTime) { + if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + return 1; + +err: + return 0; +} + +static int +i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, + int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) + return 0; + return 1; +} + +static int +i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, oid) <= 0) + return 0; + return 1; +} + +/* OCSP nonce. This is needs special treatment because it doesn't have + * an ASN1 encoding at all: it just contains arbitrary data. + */ + +static void * +ocsp_nonce_new(void) +{ + return ASN1_OCTET_STRING_new(); +} + +static int +i2d_ocsp_nonce(void *a, unsigned char **pp) +{ + ASN1_OCTET_STRING *os = a; + + if (pp) { + memcpy(*pp, os->data, os->length); + *pp += os->length; + } + return os->length; +} + +static void * +d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) +{ + ASN1_OCTET_STRING *os, **pos; + + pos = a; + if (pos == NULL || *pos == NULL) { + os = ASN1_OCTET_STRING_new(); + if (os == NULL) + goto err; + } else + os = *pos; + if (ASN1_OCTET_STRING_set(os, *pp, length) == 0) + goto err; + + *pp += length; + + if (pos != NULL) + *pos = os; + return os; + +err: + if (pos == NULL || *pos != os) + ASN1_OCTET_STRING_free(os); + OCSPerror(ERR_R_MALLOC_FAILURE); + return NULL; +} + +static void +ocsp_nonce_free(void *a) +{ + ASN1_OCTET_STRING_free(a); +} + +static int +i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, BIO *out, + int indent) +{ + if (BIO_printf(out, "%*s", indent, "") <= 0) + return 0; + if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) + return 0; + return 1; +} + +/* Nocheck is just a single NULL. Don't print anything and always set it */ + +static int +i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, BIO *out, + int indent) +{ + return 1; +} + +static void * +s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str) +{ + return ASN1_NULL_new(); +} + +static int +i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) +{ + int i; + OCSP_SERVICELOC *a = in; + ACCESS_DESCRIPTION *ad; + + if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) + goto err; + if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) + goto err; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) { + ad = sk_ACCESS_DESCRIPTION_value(a->locator, i); + if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ad->method) <= 0) + goto err; + if (BIO_puts(bp, " - ") <= 0) + goto err; + if (GENERAL_NAME_print(bp, ad->location) <= 0) + goto err; + } + return 1; + +err: + return 0; +} +#endif diff --git a/Libraries/libressl/crypto/x509/x509_pcons.c b/Libraries/libressl/crypto/x509/x509_pcons.c new file mode 100644 index 000000000..0ee935540 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_pcons.c @@ -0,0 +1,196 @@ +/* $OpenBSD: x509_pcons.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) * +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons, + STACK_OF(CONF_VALUE) *extlist); +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_policy_constraints = { + .ext_nid = NID_policy_constraints, + .ext_flags = 0, + .it = &POLICY_CONSTRAINTS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_POLICY_CONSTRAINTS, + .v2i = v2i_POLICY_CONSTRAINTS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE POLICY_CONSTRAINTS_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(POLICY_CONSTRAINTS, requireExplicitPolicy), + .field_name = "requireExplicitPolicy", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(POLICY_CONSTRAINTS, inhibitPolicyMapping), + .field_name = "inhibitPolicyMapping", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM POLICY_CONSTRAINTS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICY_CONSTRAINTS_seq_tt, + .tcount = sizeof(POLICY_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICY_CONSTRAINTS), + .sname = "POLICY_CONSTRAINTS", +}; + + +POLICY_CONSTRAINTS * +POLICY_CONSTRAINTS_new(void) +{ + return (POLICY_CONSTRAINTS*)ASN1_item_new(&POLICY_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(POLICY_CONSTRAINTS_new); + +void +POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICY_CONSTRAINTS_it); +} +LCRYPTO_ALIAS(POLICY_CONSTRAINTS_free); + +static STACK_OF(CONF_VALUE) * +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *extlist) +{ + POLICY_CONSTRAINTS *pcons = a; + STACK_OF(CONF_VALUE) *free_extlist = NULL; + + if (extlist == NULL) { + if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + if (!X509V3_add_value_int("Require Explicit Policy", + pcons->requireExplicitPolicy, &extlist)) + goto err; + if (!X509V3_add_value_int("Inhibit Policy Mapping", + pcons->inhibitPolicyMapping, &extlist)) + goto err; + + return extlist; + + err: + sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); + + return NULL; +} + +static void * +v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + POLICY_CONSTRAINTS *pcons = NULL; + CONF_VALUE *val; + int i; + + if (!(pcons = POLICY_CONSTRAINTS_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "requireExplicitPolicy")) { + if (!X509V3_get_value_int(val, + &pcons->requireExplicitPolicy)) goto err; + } else if (!strcmp(val->name, "inhibitPolicyMapping")) { + if (!X509V3_get_value_int(val, + &pcons->inhibitPolicyMapping)) goto err; + } else { + X509V3error(X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + X509V3error(X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + +err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} diff --git a/Libraries/libressl/crypto/x509/x509_pku.c b/Libraries/libressl/crypto/x509/x509_pku.c new file mode 100644 index 000000000..dd28077de --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_pku.c @@ -0,0 +1,158 @@ +/* $OpenBSD: x509_pku.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + PKEY_USAGE_PERIOD *usage, BIO *out, int indent); + +const X509V3_EXT_METHOD v3_pkey_usage_period = { + .ext_nid = NID_private_key_usage_period, + .ext_flags = 0, + .it = &PKEY_USAGE_PERIOD_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE PKEY_USAGE_PERIOD_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKEY_USAGE_PERIOD, notBefore), + .field_name = "notBefore", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(PKEY_USAGE_PERIOD, notAfter), + .field_name = "notAfter", + .item = &ASN1_GENERALIZEDTIME_it, + }, +}; + +const ASN1_ITEM PKEY_USAGE_PERIOD_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKEY_USAGE_PERIOD_seq_tt, + .tcount = sizeof(PKEY_USAGE_PERIOD_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKEY_USAGE_PERIOD), + .sname = "PKEY_USAGE_PERIOD", +}; + + +PKEY_USAGE_PERIOD * +d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len) +{ + return (PKEY_USAGE_PERIOD *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKEY_USAGE_PERIOD_it); +} +LCRYPTO_ALIAS(d2i_PKEY_USAGE_PERIOD); + +int +i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKEY_USAGE_PERIOD_it); +} +LCRYPTO_ALIAS(i2d_PKEY_USAGE_PERIOD); + +PKEY_USAGE_PERIOD * +PKEY_USAGE_PERIOD_new(void) +{ + return (PKEY_USAGE_PERIOD *)ASN1_item_new(&PKEY_USAGE_PERIOD_it); +} +LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_new); + +void +PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKEY_USAGE_PERIOD_it); +} +LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_free); + +static int +i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, + BIO *out, int indent) +{ + BIO_printf(out, "%*s", indent, ""); + if (usage->notBefore) { + BIO_write(out, "Not Before: ", 12); + ASN1_GENERALIZEDTIME_print(out, usage->notBefore); + if (usage->notAfter) + BIO_write(out, ", ", 2); + } + if (usage->notAfter) { + BIO_write(out, "Not After: ", 11); + ASN1_GENERALIZEDTIME_print(out, usage->notAfter); + } + return 1; +} diff --git a/Libraries/libressl/crypto/x509/x509_pmaps.c b/Libraries/libressl/crypto/x509/x509_pmaps.c new file mode 100644 index 000000000..39aebfee8 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_pmaps.c @@ -0,0 +1,237 @@ +/* $OpenBSD: x509_pmaps.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include + +#include +#include +#include +#include + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS( + const X509V3_EXT_METHOD *method, void *pmps, STACK_OF(CONF_VALUE) *extlist); + +const X509V3_EXT_METHOD v3_policy_mappings = { + .ext_nid = NID_policy_mappings, + .ext_flags = 0, + .it = &POLICY_MAPPINGS_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_POLICY_MAPPINGS, + .v2i = v2i_POLICY_MAPPINGS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE POLICY_MAPPING_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICY_MAPPING, issuerDomainPolicy), + .field_name = "issuerDomainPolicy", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICY_MAPPING, subjectDomainPolicy), + .field_name = "subjectDomainPolicy", + .item = &ASN1_OBJECT_it, + }, +}; + +const ASN1_ITEM POLICY_MAPPING_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICY_MAPPING_seq_tt, + .tcount = sizeof(POLICY_MAPPING_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICY_MAPPING), + .sname = "POLICY_MAPPING", +}; + +static const ASN1_TEMPLATE POLICY_MAPPINGS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "POLICY_MAPPINGS", + .item = &POLICY_MAPPING_it, +}; + +const ASN1_ITEM POLICY_MAPPINGS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &POLICY_MAPPINGS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "POLICY_MAPPINGS", +}; + + +POLICY_MAPPING * +POLICY_MAPPING_new(void) +{ + return (POLICY_MAPPING*)ASN1_item_new(&POLICY_MAPPING_it); +} +LCRYPTO_ALIAS(POLICY_MAPPING_new); + +void +POLICY_MAPPING_free(POLICY_MAPPING *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICY_MAPPING_it); +} +LCRYPTO_ALIAS(POLICY_MAPPING_free); + +static STACK_OF(CONF_VALUE) * +i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *extlist) +{ + STACK_OF(CONF_VALUE) *free_extlist = NULL; + POLICY_MAPPINGS *pmaps = a; + POLICY_MAPPING *pmap; + char issuer[80], subject[80]; + int i; + + if (extlist == NULL) { + if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) + return NULL; + } + + for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + if ((pmap = sk_POLICY_MAPPING_value(pmaps, i)) == NULL) + goto err; + if (!i2t_ASN1_OBJECT(issuer, sizeof issuer, + pmap->issuerDomainPolicy)) + goto err; + if (!i2t_ASN1_OBJECT(subject, sizeof subject, + pmap->subjectDomainPolicy)) + goto err; + if (!X509V3_add_value(issuer, subject, &extlist)) + goto err; + } + + return extlist; + + err: + sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); + + return NULL; +} + +static void * +v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + POLICY_MAPPINGS *pmaps = NULL; + POLICY_MAPPING *pmap = NULL; + ASN1_OBJECT *obj1 = NULL, *obj2 = NULL; + CONF_VALUE *val; + int i, rc; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!val->value || !val->name) { + rc = X509V3_R_INVALID_OBJECT_IDENTIFIER; + goto err; + } + obj1 = OBJ_txt2obj(val->name, 0); + obj2 = OBJ_txt2obj(val->value, 0); + if (!obj1 || !obj2) { + rc = X509V3_R_INVALID_OBJECT_IDENTIFIER; + goto err; + } + pmap = POLICY_MAPPING_new(); + if (!pmap) { + rc = ERR_R_MALLOC_FAILURE; + goto err; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + obj1 = obj2 = NULL; + if (sk_POLICY_MAPPING_push(pmaps, pmap) == 0) { + rc = ERR_R_MALLOC_FAILURE; + goto err; + } + pmap = NULL; + } + return pmaps; + +err: + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3error(rc); + if (rc == X509V3_R_INVALID_OBJECT_IDENTIFIER) + X509V3_conf_err(val); + ASN1_OBJECT_free(obj1); + ASN1_OBJECT_free(obj2); + POLICY_MAPPING_free(pmap); + return NULL; +} diff --git a/Libraries/libressl/crypto/x509/x509_policy.c b/Libraries/libressl/crypto/x509/x509_policy.c new file mode 100644 index 000000000..73f7154f5 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_policy.c @@ -0,0 +1,1019 @@ +/* $OpenBSD: x509_policy.c,v 1.25 2023/04/28 16:30:14 tb Exp $ */ +/* + * Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "x509_internal.h" +#include "x509_local.h" + +/* XXX move to proper place */ +#define X509_R_INVALID_POLICY_EXTENSION 201 + +/* + * This file computes the X.509 policy tree, as described in RFC 5280, section + * 6.1. It differs in that: + * + * (1) It does not track "qualifier_set". This is not needed as it is not + * output by this implementation. + * + * (2) It builds a directed acyclic graph, rather than a tree. When a given + * policy matches multiple parents, RFC 5280 makes a separate node for + * each parent. This representation condenses them into one node with + * multiple parents. Thus we refer to this structure as a "policy graph", + * rather than a "policy tree". + * + * (3) "expected_policy_set" is not tracked explicitly and built temporarily + * as part of building the graph. + * + * (4) anyPolicy nodes are not tracked explicitly. + * + * (5) Some pruning steps are deferred to when policies are evaluated, as a + * reachability pass. + */ + +/* + * An X509_POLICY_NODE is a node in the policy graph. It corresponds to a node + * from RFC 5280, section 6.1.2, step (a), but we store some fields differently. + */ +typedef struct x509_policy_node_st { + /* policy is the "valid_policy" field from RFC 5280. */ + ASN1_OBJECT *policy; + + /* + * parent_policies, if non-empty, is the list of "valid_policy" values + * for all nodes which are a parent of this node. In this case, no entry + * in this list will be anyPolicy. This list is in no particular order + * and may contain duplicates if the corresponding certificate had + * duplicate mappings. + * + * If empty, this node has a single parent, anyPolicy. The node is then + * a root policies, and is in authorities-constrained-policy-set if it + * has a path to a leaf node. + * + * Note it is not possible for a policy to have both anyPolicy and a + * concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs + * if there was no match in step (d.1.i). We do not need to represent a + * parent list of, say, {anyPolicy, OID1, OID2}. + */ + STACK_OF(ASN1_OBJECT) *parent_policies; + + /* + * mapped is one if this node matches a policy mapping in the + * certificate and zero otherwise. + */ + int mapped; + + /* + * reachable is one if this node is reachable from some valid policy in + * the end-entity certificate. It is computed during |has_explicit_policy|. + */ + int reachable; +} X509_POLICY_NODE; + +DECLARE_STACK_OF(X509_POLICY_NODE) + +#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) +#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) +#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) +#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) +#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) +#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) +#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) +#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) +#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) +#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) +#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) + +/* + * An X509_POLICY_LEVEL is the collection of nodes at the same depth in the + * policy graph. This structure can also be used to represent a level's + * "expected_policy_set" values. See |process_policy_mappings|. + */ +typedef struct x509_policy_level_st { + /* + * nodes is the list of nodes at this depth, except for the anyPolicy + * node, if any. This list is sorted by policy OID for efficient lookup. + */ + STACK_OF(X509_POLICY_NODE) *nodes; + + /* + * has_any_policy is one if there is an anyPolicy node at this depth, + * and zero otherwise. + */ + int has_any_policy; +} X509_POLICY_LEVEL; + +DECLARE_STACK_OF(X509_POLICY_LEVEL) + +#define sk_X509_POLICY_LEVEL_new(cmp) SKM_sk_new(X509_POLICY_LEVEL, (cmp)) +#define sk_X509_POLICY_LEVEL_new_null() SKM_sk_new_null(X509_POLICY_LEVEL) +#define sk_X509_POLICY_LEVEL_free(st) SKM_sk_free(X509_POLICY_LEVEL, (st)) +#define sk_X509_POLICY_LEVEL_num(st) SKM_sk_num(X509_POLICY_LEVEL, (st)) +#define sk_X509_POLICY_LEVEL_value(st, i) SKM_sk_value(X509_POLICY_LEVEL, (st), (i)) +#define sk_X509_POLICY_LEVEL_set(st, i, val) SKM_sk_set(X509_POLICY_LEVEL, (st), (i), (val)) +#define sk_X509_POLICY_LEVEL_zero(st) SKM_sk_zero(X509_POLICY_LEVEL, (st)) +#define sk_X509_POLICY_LEVEL_push(st, val) SKM_sk_push(X509_POLICY_LEVEL, (st), (val)) +#define sk_X509_POLICY_LEVEL_unshift(st, val) SKM_sk_unshift(X509_POLICY_LEVEL, (st), (val)) +#define sk_X509_POLICY_LEVEL_find(st, val) SKM_sk_find(X509_POLICY_LEVEL, (st), (val)) +#define sk_X509_POLICY_LEVEL_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_LEVEL, (st), (val)) +#define sk_X509_POLICY_LEVEL_delete(st, i) SKM_sk_delete(X509_POLICY_LEVEL, (st), (i)) +#define sk_X509_POLICY_LEVEL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_LEVEL, (st), (ptr)) +#define sk_X509_POLICY_LEVEL_insert(st, val, i) SKM_sk_insert(X509_POLICY_LEVEL, (st), (val), (i)) +#define sk_X509_POLICY_LEVEL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_LEVEL, (st), (cmp)) +#define sk_X509_POLICY_LEVEL_dup(st) SKM_sk_dup(X509_POLICY_LEVEL, st) +#define sk_X509_POLICY_LEVEL_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_LEVEL, (st), (free_func)) +#define sk_X509_POLICY_LEVEL_shift(st) SKM_sk_shift(X509_POLICY_LEVEL, (st)) +#define sk_X509_POLICY_LEVEL_pop(st) SKM_sk_pop(X509_POLICY_LEVEL, (st)) +#define sk_X509_POLICY_LEVEL_sort(st) SKM_sk_sort(X509_POLICY_LEVEL, (st)) +#define sk_X509_POLICY_LEVEL_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_LEVEL, (st)) + +/* + * Don't look Ethel, but you would really not want to look if we did + * this the OpenSSL way either, and we are not using this boringsslism + * anywhere else. Callers should ensure that the stack in data is sorted. + */ +void +sk_X509_POLICY_NODE_delete_if(STACK_OF(X509_POLICY_NODE) *nodes, + int (*delete_if)(X509_POLICY_NODE *, void *), void *data) +{ + _STACK *sk = (_STACK *)nodes; + X509_POLICY_NODE *node; + int new_num = 0; + int i; + + for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { + node = sk_X509_POLICY_NODE_value(nodes, i); + if (!delete_if(node, data)) + sk->data[new_num++] = (char *)node; + } + sk->num = new_num; +} + +static int +is_any_policy(const ASN1_OBJECT *obj) +{ + return OBJ_obj2nid(obj) == NID_any_policy; +} + +static void +x509_policy_node_free(X509_POLICY_NODE *node) +{ + if (node == NULL) + return; + + ASN1_OBJECT_free(node->policy); + sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free); + free(node); +} + +static X509_POLICY_NODE * +x509_policy_node_new(const ASN1_OBJECT *policy) +{ + X509_POLICY_NODE *node = NULL; + + if (is_any_policy(policy)) + goto err; + if ((node = calloc(1, sizeof(*node))) == NULL) + goto err; + if ((node->policy = OBJ_dup(policy)) == NULL) + goto err; + if ((node->parent_policies = sk_ASN1_OBJECT_new_null()) == NULL) + goto err; + + return node; + + err: + x509_policy_node_free(node); + return NULL; +} + +static int +x509_policy_node_cmp(const X509_POLICY_NODE *const *a, + const X509_POLICY_NODE *const *b) +{ + return OBJ_cmp((*a)->policy, (*b)->policy); +} + +static void +x509_policy_level_free(X509_POLICY_LEVEL *level) +{ + if (level == NULL) + return; + + sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free); + free(level); +} + +static X509_POLICY_LEVEL * +x509_policy_level_new(void) +{ + X509_POLICY_LEVEL *level; + + if ((level = calloc(1, sizeof(*level))) == NULL) + goto err; + level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); + if (level->nodes == NULL) + goto err; + + return level; + + err: + x509_policy_level_free(level); + return NULL; +} + +static int +x509_policy_level_is_empty(const X509_POLICY_LEVEL *level) +{ + if (level->has_any_policy) + return 0; + + return sk_X509_POLICY_NODE_num(level->nodes) == 0; +} + +static void +x509_policy_level_clear(X509_POLICY_LEVEL *level) +{ + X509_POLICY_NODE *node; + int i; + + level->has_any_policy = 0; + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + x509_policy_node_free(node); + } + sk_X509_POLICY_NODE_zero(level->nodes); +} + +/* + * x509_policy_level_find returns the node in |level| corresponding to |policy|, + * or NULL if none exists. Callers should ensure that level->nodes is sorted + * to avoid the cost of sorting it in sk_find(). + */ +static X509_POLICY_NODE * +x509_policy_level_find(X509_POLICY_LEVEL *level, const ASN1_OBJECT *policy) +{ + X509_POLICY_NODE node; + node.policy = (ASN1_OBJECT *)policy; + int idx; + + if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) + return NULL; + return sk_X509_POLICY_NODE_value(level->nodes, idx); +} + +/* + * x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns + * one on success and zero on error. No policy in |nodes| may already be present + * in |level|. This function modifies |nodes| to avoid making a copy, but the + * caller is still responsible for releasing |nodes| itself. + * + * This function is used to add nodes to |level| in bulk, and avoid resorting + * |level| after each addition. + */ +static int +x509_policy_level_add_nodes(X509_POLICY_LEVEL *level, + STACK_OF(X509_POLICY_NODE) *nodes) +{ + int i; + + for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) + return 0; + sk_X509_POLICY_NODE_set(nodes, i, NULL); + } + sk_X509_POLICY_NODE_sort(level->nodes); + + return 1; +} + +static int +policyinfo_cmp(const POLICYINFO *const *a, + const POLICYINFO *const *b) +{ + return OBJ_cmp((*a)->policyid, (*b)->policyid); +} + +static int +delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) +{ + const CERTIFICATEPOLICIES *policies = data; + POLICYINFO info; + info.policyid = node->policy; + + if (sk_POLICYINFO_find(policies, &info) >= 0) + return 0; + x509_policy_node_free(node); + return 1; +} + +/* + * process_certificate_policies updates |level| to incorporate |x509|'s + * certificate policies extension. This implements steps (d) and (e) of RFC + * 5280, section 6.1.3. |level| must contain the previous level's + * "expected_policy_set" information. For all but the top-most level, this is + * the output of |process_policy_mappings|. |any_policy_allowed| specifies + * whether anyPolicy is allowed or inhibited, taking into account the exception + * for self-issued certificates. + */ +static int +process_certificate_policies(const X509 *x509, X509_POLICY_LEVEL *level, + int any_policy_allowed) +{ + STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; + CERTIFICATEPOLICIES *policies; + const POLICYINFO *policy; + X509_POLICY_NODE *node; + int cert_has_any_policy, critical, i, previous_level_has_any_policy; + int ret = 0; + + policies = X509_get_ext_d2i(x509, NID_certificate_policies, &critical, + NULL); + if (policies == NULL) { + if (critical != -1) + return 0; /* Syntax error in the extension. */ + + /* RFC 5280, section 6.1.3, step (e). */ + x509_policy_level_clear(level); + return 1; + } + + /* + * certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4. + * TODO(https://crbug.com/boringssl/443): Move this check into the parser. + */ + if (sk_POLICYINFO_num(policies) == 0) { + X509error(X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + + (void)sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp); + sk_POLICYINFO_sort(policies); + cert_has_any_policy = 0; + for (i = 0; i < sk_POLICYINFO_num(policies); i++) { + policy = sk_POLICYINFO_value(policies, i); + if (is_any_policy(policy->policyid)) + cert_has_any_policy = 1; + if (i > 0 && + OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, + policy->policyid) == 0) { + /* + * Per RFC 5280, section 4.2.1.4, |policies| may not + * have duplicates. + */ + X509error(X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + } + + /* + * This does the same thing as RFC 5280, section 6.1.3, step (d), + * though in a slighty different order. |level| currently contains + * "expected_policy_set" values of the previous level. + * See |process_policy_mappings| for details. + */ + previous_level_has_any_policy = level->has_any_policy; + + /* + * First, we handle steps (d.1.i) and (d.2). The net effect of these + * two steps is to intersect |level| with |policies|, ignoring + * anyPolicy if it is inhibited. + */ + if (!cert_has_any_policy || !any_policy_allowed) { + if (!sk_POLICYINFO_is_sorted(policies)) + goto err; + sk_X509_POLICY_NODE_delete_if(level->nodes, + delete_if_not_in_policies, policies); + level->has_any_policy = 0; + } + + /* + * Step (d.1.ii) may attach new nodes to the previous level's anyPolicy + * node. + */ + if (previous_level_has_any_policy) { + new_nodes = sk_X509_POLICY_NODE_new_null(); + if (new_nodes == NULL) + goto err; + for (i = 0; i < sk_POLICYINFO_num(policies); i++) { + policy = sk_POLICYINFO_value(policies, i); + /* + * Though we've reordered the steps slightly, |policy| + * is in |level| if and only if it would have been a + * match in step (d.1.ii). + */ + if (is_any_policy(policy->policyid)) + continue; + if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) + goto err; + if (x509_policy_level_find(level, policy->policyid) != NULL) + continue; + node = x509_policy_node_new(policy->policyid); + if (node == NULL || + !sk_X509_POLICY_NODE_push(new_nodes, node)) { + x509_policy_node_free(node); + goto err; + } + } + if (!x509_policy_level_add_nodes(level, new_nodes)) + goto err; + } + + ret = 1; + +err: + sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); + CERTIFICATEPOLICIES_free(policies); + return ret; +} + +static int +compare_issuer_policy(const POLICY_MAPPING *const *a, + const POLICY_MAPPING *const *b) +{ + return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy); +} + +static int +compare_subject_policy(const POLICY_MAPPING *const *a, + const POLICY_MAPPING *const *b) +{ + return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); +} + +static int +delete_if_mapped(X509_POLICY_NODE *node, void *data) +{ + const POLICY_MAPPINGS *mappings = data; + POLICY_MAPPING mapping; + mapping.issuerDomainPolicy = node->policy; + if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0) + return 0; + x509_policy_node_free(node); + return 1; +} + +/* + * process_policy_mappings processes the policy mappings extension of |cert|, + * whose corresponding graph level is |level|. |mapping_allowed| specifies + * whether policy mapping is inhibited at this point. On success, it returns an + * |X509_POLICY_LEVEL| containing the "expected_policy_set" for |level|. On + * error, it returns NULL. This implements steps (a) and (b) of RFC 5280, + * section 6.1.4. + * + * We represent the "expected_policy_set" as an |X509_POLICY_LEVEL|. + * |has_any_policy| indicates whether there is an anyPolicy node with + * "expected_policy_set" of {anyPolicy}. If a node with policy oid P1 contains + * P2 in its "expected_policy_set", the level will contain a node of policy P2 + * with P1 in |parent_policies|. + * + * This is equivalent to the |X509_POLICY_LEVEL| that would result if the next + * certificats contained anyPolicy. |process_certificate_policies| will filter + * this result down to compute the actual level. + */ +static X509_POLICY_LEVEL * +process_policy_mappings(const X509 *cert, + X509_POLICY_LEVEL *level, + int mapping_allowed) +{ + STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; + POLICY_MAPPINGS *mappings; + const ASN1_OBJECT *last_policy; + POLICY_MAPPING *mapping; + X509_POLICY_LEVEL *next = NULL; + X509_POLICY_NODE *node; + int critical, i; + int ok = 0; + + mappings = X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); + if (mappings == NULL && critical != -1) { + /* Syntax error in the policy mappings extension. */ + goto err; + } + + if (mappings != NULL) { + /* + * PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5. + * TODO(https://crbug.com/boringssl/443): Move this check into + * the parser. + */ + if (sk_POLICY_MAPPING_num(mappings) == 0) { + X509error(X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + + /* RFC 5280, section 6.1.4, step (a). */ + for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + mapping = sk_POLICY_MAPPING_value(mappings, i); + if (is_any_policy(mapping->issuerDomainPolicy) || + is_any_policy(mapping->subjectDomainPolicy)) + goto err; + } + + /* Sort to group by issuerDomainPolicy. */ + (void)sk_POLICY_MAPPING_set_cmp_func(mappings, + compare_issuer_policy); + sk_POLICY_MAPPING_sort(mappings); + + if (mapping_allowed) { + /* + * Mark nodes as mapped, and add any nodes to |level| + * which may be needed as part of RFC 5280, + * section 6.1.4, step (b.1). + */ + new_nodes = sk_X509_POLICY_NODE_new_null(); + if (new_nodes == NULL) + goto err; + last_policy = NULL; + for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + mapping = sk_POLICY_MAPPING_value(mappings, i); + /* + * There may be multiple mappings with the same + * |issuerDomainPolicy|. + */ + if (last_policy != NULL && + OBJ_cmp(mapping->issuerDomainPolicy, + last_policy) == 0) + continue; + last_policy = mapping->issuerDomainPolicy; + + if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) + goto err; + node = x509_policy_level_find(level, + mapping->issuerDomainPolicy); + if (node == NULL) { + if (!level->has_any_policy) + continue; + node = x509_policy_node_new( + mapping->issuerDomainPolicy); + if (node == NULL || + !sk_X509_POLICY_NODE_push(new_nodes, + node)) { + x509_policy_node_free(node); + goto err; + } + } + node->mapped = 1; + } + if (!x509_policy_level_add_nodes(level, new_nodes)) + goto err; + } else { + /* + * RFC 5280, section 6.1.4, step (b.2). If mapping is + * inhibited, delete all mapped nodes. + */ + if (!sk_POLICY_MAPPING_is_sorted(mappings)) + goto err; + sk_X509_POLICY_NODE_delete_if(level->nodes, + delete_if_mapped, mappings); + sk_POLICY_MAPPING_pop_free(mappings, + POLICY_MAPPING_free); + mappings = NULL; + } + } + + /* + * If a node was not mapped, it retains the original "explicit_policy_set" + * value, itself. Add those to |mappings|. + */ + if (mappings == NULL) { + mappings = sk_POLICY_MAPPING_new_null(); + if (mappings == NULL) + goto err; + } + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (!node->mapped) { + mapping = POLICY_MAPPING_new(); + if (mapping == NULL) + goto err; + mapping->issuerDomainPolicy = OBJ_dup(node->policy); + mapping->subjectDomainPolicy = OBJ_dup(node->policy); + if (mapping->issuerDomainPolicy == NULL || + mapping->subjectDomainPolicy == NULL || + !sk_POLICY_MAPPING_push(mappings, mapping)) { + POLICY_MAPPING_free(mapping); + goto err; + } + } + } + + /* Sort to group by subjectDomainPolicy. */ + (void)sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy); + sk_POLICY_MAPPING_sort(mappings); + + /* Convert |mappings| to our "expected_policy_set" representation. */ + next = x509_policy_level_new(); + if (next == NULL) + goto err; + next->has_any_policy = level->has_any_policy; + + X509_POLICY_NODE *last_node = NULL; + for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + mapping = sk_POLICY_MAPPING_value(mappings, i); + /* + * Skip mappings where |issuerDomainPolicy| does not appear in + * the graph. + */ + if (!level->has_any_policy) { + if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) + goto err; + if (x509_policy_level_find(level, + mapping->issuerDomainPolicy) == NULL) + continue; + } + + if (last_node == NULL || + OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != + 0) { + last_node = x509_policy_node_new( + mapping->subjectDomainPolicy); + if (last_node == NULL || + !sk_X509_POLICY_NODE_push(next->nodes, last_node)) { + x509_policy_node_free(last_node); + goto err; + } + } + + if (!sk_ASN1_OBJECT_push(last_node->parent_policies, + mapping->issuerDomainPolicy)) + goto err; + mapping->issuerDomainPolicy = NULL; + } + + sk_X509_POLICY_NODE_sort(next->nodes); + ok = 1; + +err: + if (!ok) { + x509_policy_level_free(next); + next = NULL; + } + + sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); + sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); + return next; +} + +/* + * apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum + * of its current value and |skip_certs|. It returns one on success and zero if + * |skip_certs| is negative. + */ +static int +apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) +{ + if (skip_certs == NULL) + return 1; + + /* TODO(https://crbug.com/boringssl/443): Move this check into the parser. */ + if (skip_certs->type & V_ASN1_NEG) { + X509error(X509_R_INVALID_POLICY_EXTENSION); + return 0; + } + + /* If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. */ + uint64_t u64; + if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) + *value = (size_t)u64; + ERR_clear_error(); + return 1; +} + +/* + * process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and + * |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit + * anyPolicy extensions. It returns one on success and zero on error. This + * implements steps (i) and (j) of RFC 5280, section 6.1.4. + */ +static int +process_policy_constraints(const X509 *x509, size_t *explicit_policy, + size_t *policy_mapping, + size_t *inhibit_any_policy) +{ + ASN1_INTEGER *inhibit_any_policy_ext; + POLICY_CONSTRAINTS *constraints; + int critical; + int ok = 0; + + constraints = X509_get_ext_d2i(x509, NID_policy_constraints, &critical, + NULL); + if (constraints == NULL && critical != -1) + return 0; + if (constraints != NULL) { + if (constraints->requireExplicitPolicy == NULL && + constraints->inhibitPolicyMapping == NULL) { + /* + * Per RFC 5280, section 4.2.1.11, at least one of the + * fields must be + */ + X509error(X509_R_INVALID_POLICY_EXTENSION); + POLICY_CONSTRAINTS_free(constraints); + return 0; + } + ok = apply_skip_certs(constraints->requireExplicitPolicy, + explicit_policy) && + apply_skip_certs(constraints->inhibitPolicyMapping, + policy_mapping); + POLICY_CONSTRAINTS_free(constraints); + if (!ok) + return 0; + } + + inhibit_any_policy_ext = X509_get_ext_d2i(x509, NID_inhibit_any_policy, + &critical, NULL); + if (inhibit_any_policy_ext == NULL && critical != -1) + return 0; + ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); + ASN1_INTEGER_free(inhibit_any_policy_ext); + return ok; +} + +/* + * has_explicit_policy returns one if the set of authority-space policy OIDs + * |levels| has some non-empty intersection with |user_policies|, and zero + * otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This + * function modifies |levels| and should only be called at the end of policy + * evaluation. + */ +static int +has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, + const STACK_OF(ASN1_OBJECT) *user_policies) +{ + X509_POLICY_LEVEL *level, *prev; + X509_POLICY_NODE *node, *parent; + int num_levels, user_has_any_policy; + int i, j, k; + + if (!sk_ASN1_OBJECT_is_sorted(user_policies)) + return 0; + + /* Step (g.i). If the policy graph is empty, the intersection is empty. */ + num_levels = sk_X509_POLICY_LEVEL_num(levels); + level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1); + if (x509_policy_level_is_empty(level)) + return 0; + + /* + * If |user_policies| is empty, we interpret it as having a single + * anyPolicy value. The caller may also have supplied anyPolicy + * explicitly. + */ + user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) <= 0; + for (i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) { + if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) { + user_has_any_policy = 1; + break; + } + } + + /* + * Step (g.ii). If the policy graph is not empty and the user set + * contains anyPolicy, the intersection is the entire (non-empty) graph. + */ + if (user_has_any_policy) + return 1; + + /* + * Step (g.iii) does not delete anyPolicy nodes, so if the graph has + * anyPolicy, some explicit policy will survive. The actual intersection + * may synthesize some nodes in step (g.iii.3), but we do not return the + * policy list itself, so we skip actually computing this. + */ + if (level->has_any_policy) + return 1; + + /* + * We defer pruning the tree, so as we look for nodes with parent + * anyPolicy, step (g.iii.1), we must limit to nodes reachable from the + * bottommost level. Start by marking each of those nodes as reachable. + */ + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) + sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; + + for (i = num_levels - 1; i >= 0; i--) { + level = sk_X509_POLICY_LEVEL_value(levels, i); + for (j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) { + node = sk_X509_POLICY_NODE_value(level->nodes, j); + if (!node->reachable) + continue; + if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { + /* + * |node|'s parent is anyPolicy and is part of + * "valid_policy_node_set". If it exists in + * |user_policies|, the intersection is + * non-empty and we * can return immediately. + */ + if (sk_ASN1_OBJECT_find(user_policies, + node->policy) >= 0) + return 1; + } else if (i > 0) { + int num_parent_policies = + sk_ASN1_OBJECT_num(node->parent_policies); + /* + * |node|'s parents are concrete policies. Mark + * the parents reachable, to be inspected by the + * next loop iteration. + */ + prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); + for (k = 0; k < num_parent_policies; k++) { + if (!sk_X509_POLICY_NODE_is_sorted(prev->nodes)) + return 0; + parent = x509_policy_level_find(prev, + sk_ASN1_OBJECT_value(node->parent_policies, + k)); + if (parent != NULL) + parent->reachable = 1; + } + } + } + } + + return 0; +} + +static int +asn1_object_cmp(const ASN1_OBJECT *const *a, const ASN1_OBJECT *const *b) +{ + return OBJ_cmp(*a, *b); +} + +int +X509_policy_check(const STACK_OF(X509) *certs, + const STACK_OF(ASN1_OBJECT) *user_policies, + unsigned long flags, X509 **out_current_cert) +{ + *out_current_cert = NULL; + int ret = X509_V_ERR_OUT_OF_MEM; + X509 *cert; + X509_POLICY_LEVEL *level = NULL; + X509_POLICY_LEVEL *current_level; + STACK_OF(X509_POLICY_LEVEL) *levels = NULL; + STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL; + int num_certs = sk_X509_num(certs); + int is_self_issued, any_policy_allowed; + int i; + + /* Skip policy checking if the chain is just the trust anchor. */ + if (num_certs <= 1) + return X509_V_OK; + + /* See RFC 5280, section 6.1.2, steps (d) through (f). */ + size_t explicit_policy = + (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1; + size_t inhibit_any_policy = + (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1; + size_t policy_mapping = + (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; + + levels = sk_X509_POLICY_LEVEL_new_null(); + if (levels == NULL) + goto err; + + for (i = num_certs - 2; i >= 0; i--) { + cert = sk_X509_value(certs, i); + if (!x509v3_cache_extensions(cert)) + goto err; + is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; + + if (level == NULL) { + if (i != num_certs - 2) + goto err; + level = x509_policy_level_new(); + if (level == NULL) + goto err; + level->has_any_policy = 1; + } + + /* + * RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| + * is computed as in step (d.2). + */ + any_policy_allowed = + inhibit_any_policy > 0 || (i > 0 && is_self_issued); + if (!process_certificate_policies(cert, level, + any_policy_allowed)) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + + /* RFC 5280, section 6.1.3, step (f). */ + if (explicit_policy == 0 && x509_policy_level_is_empty(level)) { + ret = X509_V_ERR_NO_EXPLICIT_POLICY; + goto err; + } + + /* Insert into the list. */ + if (!sk_X509_POLICY_LEVEL_push(levels, level)) + goto err; + current_level = level; + level = NULL; + + /* + * If this is not the leaf certificate, we go to section 6.1.4. + * If it is the leaf certificate, we go to section 6.1.5 instead. + */ + if (i != 0) { + /* RFC 5280, section 6.1.4, steps (a) and (b). */ + level = process_policy_mappings(cert, current_level, + policy_mapping > 0); + if (level == NULL) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + } + + /* + * RFC 5280, section 6.1.4, step (h-j) for non-leaves, and + * section 6.1.5, step (a-b) for leaves. In the leaf case, + * RFC 5280 says only to update |explicit_policy|, but + * |policy_mapping| and |inhibit_any_policy| are no + * longer read at this point, so we use the same process. + */ + if (i == 0 || !is_self_issued) { + if (explicit_policy > 0) + explicit_policy--; + if (policy_mapping > 0) + policy_mapping--; + if (inhibit_any_policy > 0) + inhibit_any_policy--; + } + if (!process_policy_constraints(cert, &explicit_policy, + &policy_mapping, &inhibit_any_policy)) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + } + + /* + * RFC 5280, section 6.1.5, step (g). We do not output the policy set, + * so it is only necessary to check if the user-constrained-policy-set + * is not empty. + */ + if (explicit_policy == 0) { + /* + * Build a sorted copy of |user_policies| for more efficient + * lookup. + */ + if (user_policies != NULL) { + user_policies_sorted = sk_ASN1_OBJECT_dup( + user_policies); + if (user_policies_sorted == NULL) + goto err; + (void)sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, + asn1_object_cmp); + sk_ASN1_OBJECT_sort(user_policies_sorted); + } + + if (!has_explicit_policy(levels, user_policies_sorted)) { + ret = X509_V_ERR_NO_EXPLICIT_POLICY; + goto err; + } + } + + ret = X509_V_OK; + +err: + x509_policy_level_free(level); + /* + * |user_policies_sorted|'s contents are owned by |user_policies|, so + * we do not use |sk_ASN1_OBJECT_pop_free|. + */ + sk_ASN1_OBJECT_free(user_policies_sorted); + sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free); + return ret; +} diff --git a/Libraries/libressl/crypto/x509/x509_prn.c b/Libraries/libressl/crypto/x509/x509_prn.c new file mode 100644 index 000000000..3bf7c803e --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_prn.c @@ -0,0 +1,231 @@ +/* $OpenBSD: x509_prn.c,v 1.6 2023/05/08 05:30:38 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include + +#include +#include + +#include "x509_local.h" + +/* Extension printing routines */ + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent, int supported); + +/* Print out a name+value stack */ + +void +X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml) +{ + int i; + CONF_VALUE *nval; + + if (!val) + return; + if (!ml || !sk_CONF_VALUE_num(val)) { + BIO_printf(out, "%*s", indent, ""); + if (!sk_CONF_VALUE_num(val)) + BIO_puts(out, "\n"); + } + for (i = 0; i < sk_CONF_VALUE_num(val); i++) { + if (ml) + BIO_printf(out, "%*s", indent, ""); + else if (i > 0) BIO_printf(out, ", "); + nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) + BIO_puts(out, nval->value); + else if (!nval->value) + BIO_puts(out, nval->name); + else + BIO_printf(out, "%s:%s", nval->name, nval->value); + if (ml) + BIO_puts(out, "\n"); + } +} +LCRYPTO_ALIAS(X509V3_EXT_val_prn); + +/* Main routine: print out a general extension */ + +int +X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent) +{ + void *ext_str = NULL; + char *value = NULL; + const unsigned char *p; + const X509V3_EXT_METHOD *method; + STACK_OF(CONF_VALUE) *nval = NULL; + int ok = 1; + + if (!(method = X509V3_EXT_get(ext))) + return unknown_ext_print(out, ext, flag, indent, 0); + p = ext->value->data; + if (method->it) + ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, + method->it); + else + ext_str = method->d2i(NULL, &p, ext->value->length); + + if (!ext_str) + return unknown_ext_print(out, ext, flag, indent, 1); + + if (method->i2s) { + if (!(value = method->i2s(method, ext_str))) { + ok = 0; + goto err; + } + BIO_printf(out, "%*s%s", indent, "", value); + } else if (method->i2v) { + if (!(nval = method->i2v(method, ext_str, NULL))) { + ok = 0; + goto err; + } + X509V3_EXT_val_prn(out, nval, indent, + method->ext_flags & X509V3_EXT_MULTILINE); + } else if (method->i2r) { + if (!method->i2r(method, ext_str, out, indent)) + ok = 0; + } else + ok = 0; + +err: + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + free(value); + if (method->it) + ASN1_item_free(ext_str, method->it); + else + method->ext_free(ext_str); + return ok; +} +LCRYPTO_ALIAS(X509V3_EXT_print); + +int +X509V3_extensions_print(BIO *bp, const char *title, + const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent) +{ + int i, j; + + if (sk_X509_EXTENSION_num(exts) <= 0) + return 1; + + if (title) { + BIO_printf(bp, "%*s%s:\n",indent, "", title); + indent += 4; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + if (indent && BIO_printf(bp, "%*s",indent, "") <= 0) + return 0; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ":%s\n", j ? " critical" : "") <= 0) + return 0; + if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { + BIO_printf(bp, "%*s", indent + 4, ""); + ASN1_STRING_print(bp, ex->value); + } + if (BIO_write(bp, "\n",1) <= 0) + return 0; + } + return 1; +} +LCRYPTO_ALIAS(X509V3_extensions_print); + +static int +unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent, int supported) +{ + switch (flag & X509V3_EXT_UNKNOWN_MASK) { + case X509V3_EXT_DEFAULT: + return 0; + case X509V3_EXT_ERROR_UNKNOWN: + if (supported) + BIO_printf(out, "%*s", indent, ""); + else + BIO_printf(out, "%*s", indent, ""); + return 1; + case X509V3_EXT_PARSE_UNKNOWN: + return ASN1_parse_dump(out, + ext->value->data, ext->value->length, indent, -1); + case X509V3_EXT_DUMP_UNKNOWN: + return BIO_dump_indent(out, (char *)ext->value->data, + ext->value->length, indent); + default: + return 1; + } +} + + +int +X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) +{ + BIO *bio_tmp; + int ret; + + if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) + return 0; + ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); + BIO_free(bio_tmp); + return ret; +} +LCRYPTO_ALIAS(X509V3_EXT_print_fp); diff --git a/Libraries/libressl/crypto/x509/x509_purp.c b/Libraries/libressl/crypto/x509/x509_purp.c new file mode 100644 index 000000000..0c92dfb19 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_purp.c @@ -0,0 +1,1077 @@ +/* $OpenBSD: x509_purp.c,v 1.29 2023/08/18 08:42:41 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include + +#include "x509_internal.h" +#include "x509_local.h" + +#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) +#define xku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) +#define ns_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + +static int check_ssl_ca(const X509 *x); +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int purpose_smime(const X509 *x, int ca); +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); + +static int xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b); +static void xptable_free(X509_PURPOSE *p); + +static X509_PURPOSE xstandard[] = { + { + .purpose = X509_PURPOSE_SSL_CLIENT, + .trust = X509_TRUST_SSL_CLIENT, + .check_purpose = check_purpose_ssl_client, + .name = "SSL client", + .sname = "sslclient", + }, + { + .purpose = X509_PURPOSE_SSL_SERVER, + .trust = X509_TRUST_SSL_SERVER, + .check_purpose = check_purpose_ssl_server, + .name = "SSL server", + .sname = "sslserver", + }, + { + .purpose = X509_PURPOSE_NS_SSL_SERVER, + .trust = X509_TRUST_SSL_SERVER, + .check_purpose = check_purpose_ns_ssl_server, + .name = "Netscape SSL server", + .sname = "nssslserver", + }, + { + .purpose = X509_PURPOSE_SMIME_SIGN, + .trust = X509_TRUST_EMAIL, + .check_purpose = check_purpose_smime_sign, + .name = "S/MIME signing", + .sname = "smimesign", + }, + { + .purpose = X509_PURPOSE_SMIME_ENCRYPT, + .trust = X509_TRUST_EMAIL, + .check_purpose = check_purpose_smime_encrypt, + .name = "S/MIME encryption", + .sname = "smimeencrypt", + }, + { + .purpose = X509_PURPOSE_CRL_SIGN, + .trust = X509_TRUST_COMPAT, + .check_purpose = check_purpose_crl_sign, + .name = "CRL signing", + .sname = "crlsign", + }, + { + .purpose = X509_PURPOSE_ANY, + .trust = X509_TRUST_DEFAULT, + .check_purpose = no_check, + .name = "Any Purpose", + .sname = "any", + }, + { + .purpose = X509_PURPOSE_OCSP_HELPER, + .trust = X509_TRUST_COMPAT, + .check_purpose = ocsp_helper, + .name = "OCSP helper", + .sname = "ocsphelper", + }, + { + .purpose = X509_PURPOSE_TIMESTAMP_SIGN, + .trust = X509_TRUST_TSA, + .check_purpose = check_purpose_timestamp_sign, + .name = "Time Stamp signing", + .sname = "timestampsign", + }, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard) / sizeof(xstandard[0])) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int +xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b) +{ + return (*a)->purpose - (*b)->purpose; +} + +/* As much as I'd like to make X509_check_purpose use a "const" X509* + * I really can't because it does recalculate hashes and do other non-const + * things. */ +int +X509_check_purpose(X509 *x, int id, int ca) +{ + int idx; + const X509_PURPOSE *pt; + + if (!x509v3_cache_extensions(x)) + return -1; + + if (id == -1) + return 1; + idx = X509_PURPOSE_get_by_id(id); + if (idx == -1) + return -1; + pt = X509_PURPOSE_get0(idx); + return pt->check_purpose(pt, x, ca); +} +LCRYPTO_ALIAS(X509_check_purpose); + +int +X509_PURPOSE_set(int *p, int purpose) +{ + if (X509_PURPOSE_get_by_id(purpose) == -1) { + X509V3error(X509V3_R_INVALID_PURPOSE); + return 0; + } + *p = purpose; + return 1; +} +LCRYPTO_ALIAS(X509_PURPOSE_set); + +int +X509_PURPOSE_get_count(void) +{ + if (!xptable) + return X509_PURPOSE_COUNT; + return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; +} +LCRYPTO_ALIAS(X509_PURPOSE_get_count); + +X509_PURPOSE * +X509_PURPOSE_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_PURPOSE_COUNT) + return xstandard + idx; + return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); +} +LCRYPTO_ALIAS(X509_PURPOSE_get0); + +int +X509_PURPOSE_get_by_sname(const char *sname) +{ + int i; + X509_PURPOSE *xptmp; + + for (i = 0; i < X509_PURPOSE_get_count(); i++) { + xptmp = X509_PURPOSE_get0(i); + if (!strcmp(xptmp->sname, sname)) + return i; + } + return -1; +} +LCRYPTO_ALIAS(X509_PURPOSE_get_by_sname); + +int +X509_PURPOSE_get_by_id(int purpose) +{ + X509_PURPOSE tmp; + int idx; + + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + idx = sk_X509_PURPOSE_find(xptable, &tmp); + if (idx == -1) + return -1; + return idx + X509_PURPOSE_COUNT; +} +LCRYPTO_ALIAS(X509_PURPOSE_get_by_id); + +int +X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, const X509 *, int), const char *name, + const char *sname, void *arg) +{ + int idx; + X509_PURPOSE *ptmp; + char *name_dup, *sname_dup; + + name_dup = sname_dup = NULL; + + if (name == NULL || sname == NULL) { + X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + + /* This is set according to what we change: application can't set it */ + flags &= ~X509_PURPOSE_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_PURPOSE_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_PURPOSE_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if ((ptmp = malloc(sizeof(X509_PURPOSE))) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + if ((name_dup = strdup(name)) == NULL) + goto err; + if ((sname_dup = strdup(sname)) == NULL) + goto err; + + /* free existing name if dynamic */ + if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + free(ptmp->name); + free(ptmp->sname); + } + /* dup supplied name */ + ptmp->name = name_dup; + ptmp->sname = sname_dup; + /* Keep the dynamic flag of existing entry */ + ptmp->flags &= X509_PURPOSE_DYNAMIC; + /* Set all other flags */ + ptmp->flags |= flags; + + ptmp->purpose = id; + ptmp->trust = trust; + ptmp->check_purpose = ck; + ptmp->usr_data = arg; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (xptable == NULL && + (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) + goto err; + if (sk_X509_PURPOSE_push(xptable, ptmp) == 0) + goto err; + } + return 1; + +err: + free(name_dup); + free(sname_dup); + if (idx == -1) + free(ptmp); + X509V3error(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(X509_PURPOSE_add); + +static void +xptable_free(X509_PURPOSE *p) +{ + if (!p) + return; + if (p->flags & X509_PURPOSE_DYNAMIC) { + if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + free(p->name); + free(p->sname); + } + free(p); + } +} + +void +X509_PURPOSE_cleanup(void) +{ + sk_X509_PURPOSE_pop_free(xptable, xptable_free); + xptable = NULL; +} +LCRYPTO_ALIAS(X509_PURPOSE_cleanup); + +int +X509_PURPOSE_get_id(const X509_PURPOSE *xp) +{ + return xp->purpose; +} +LCRYPTO_ALIAS(X509_PURPOSE_get_id); + +char * +X509_PURPOSE_get0_name(const X509_PURPOSE *xp) +{ + return xp->name; +} +LCRYPTO_ALIAS(X509_PURPOSE_get0_name); + +char * +X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) +{ + return xp->sname; +} +LCRYPTO_ALIAS(X509_PURPOSE_get0_sname); + +int +X509_PURPOSE_get_trust(const X509_PURPOSE *xp) +{ + return xp->trust; +} +LCRYPTO_ALIAS(X509_PURPOSE_get_trust); + +static int +nid_cmp(const int *a, const int *b) +{ + return *a - *b; +} + +static int nid_cmp_BSEARCH_CMP_FN(const void *, const void *); +static int nid_cmp(int const *, int const *); +static int *OBJ_bsearch_nid(int *key, int const *base, int num); + +static int +nid_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + int const *a = a_; + int const *b = b_; + return nid_cmp(a, b); +} + +static int * +OBJ_bsearch_nid(int *key, int const *base, int num) +{ + return (int *)OBJ_bsearch_(key, base, num, sizeof(int), + nid_cmp_BSEARCH_CMP_FN); +} + +int +X509_supported_extension(X509_EXTENSION *ex) +{ + /* This table is a list of the NIDs of supported extensions: + * that is those which are used by the verify process. If + * an extension is critical and doesn't appear in this list + * then the verify process will normally reject the certificate. + * The list must be kept in numerical order because it will be + * searched using bsearch. + */ + + static const int supported_nids[] = { + NID_netscape_cert_type, /* 71 */ + NID_key_usage, /* 83 */ + NID_subject_alt_name, /* 85 */ + NID_basic_constraints, /* 87 */ + NID_certificate_policies, /* 89 */ + NID_ext_key_usage, /* 126 */ +#ifndef OPENSSL_NO_RFC3779 + NID_sbgp_ipAddrBlock, /* 290 */ + NID_sbgp_autonomousSysNum, /* 291 */ +#endif + NID_policy_constraints, /* 401 */ + NID_name_constraints, /* 666 */ + NID_policy_mappings, /* 747 */ + NID_inhibit_any_policy /* 748 */ + }; + + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) + return 0; + + if (OBJ_bsearch_nid(&ex_nid, supported_nids, + sizeof(supported_nids) / sizeof(int))) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_supported_extension); + +static void +setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + int i; + + if (dp->reasons) { + if (dp->reasons->length > 0) + dp->dp_reasons = dp->reasons->data[0]; + if (dp->reasons->length > 1) + dp->dp_reasons |= (dp->reasons->data[1] << 8); + dp->dp_reasons &= CRLDP_ALL_REASONS; + } else + dp->dp_reasons = CRLDP_ALL_REASONS; + if (!dp->distpoint || (dp->distpoint->type != 1)) + return; + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { + iname = gen->d.directoryName; + break; + } + } + if (!iname) + iname = X509_get_issuer_name(x); + + DIST_POINT_set_dpname(dp->distpoint, iname); +} + +static void +setup_crldp(X509 *x) +{ + int i; + + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL); + if (x->crldp == NULL && i != -1) { + x->ex_flags |= EXFLAG_INVALID; + return; + } + + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) + setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); +} + +static int +x509_extension_oid_cmp(const X509_EXTENSION *const *a, + const X509_EXTENSION *const *b) +{ + return OBJ_cmp((*a)->object, (*b)->object); +} + +static int +x509_extension_oids_are_unique(X509 *x509) +{ + STACK_OF(X509_EXTENSION) *exts = NULL; + const X509_EXTENSION *prev_ext, *curr_ext; + int i; + int ret = 0; + + if (X509_get_ext_count(x509) <= 1) + goto done; + + if ((exts = sk_X509_EXTENSION_dup(x509->cert_info->extensions)) == NULL) + goto err; + + (void)sk_X509_EXTENSION_set_cmp_func(exts, x509_extension_oid_cmp); + sk_X509_EXTENSION_sort(exts); + + prev_ext = sk_X509_EXTENSION_value(exts, 0); + for (i = 1; i < sk_X509_EXTENSION_num(exts); i++) { + curr_ext = sk_X509_EXTENSION_value(exts, i); + if (x509_extension_oid_cmp(&prev_ext, &curr_ext) == 0) + goto err; + prev_ext = curr_ext; + } + + done: + ret = 1; + + err: + sk_X509_EXTENSION_free(exts); + + return ret; +} + +static void +x509v3_cache_extensions_internal(X509 *x) +{ + BASIC_CONSTRAINTS *bs; + ASN1_BIT_STRING *usage; + ASN1_BIT_STRING *ns; + EXTENDED_KEY_USAGE *extusage; + X509_EXTENSION *ex; + long version; + int i; + + if (x->ex_flags & EXFLAG_SET) + return; + + if (!X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL)) + x->ex_flags |= EXFLAG_INVALID; + + version = X509_get_version(x); + if (version < 0 || version > 2) + x->ex_flags |= EXFLAG_INVALID; + if (version == 0) { + x->ex_flags |= EXFLAG_V1; + /* UIDs may only appear in v2 or v3 certs */ + if (x->cert_info->issuerUID != NULL || + x->cert_info->subjectUID != NULL) + x->ex_flags |= EXFLAG_INVALID; + } + if (version != 2 && X509_get_ext_count(x) != 0) + x->ex_flags |= EXFLAG_INVALID; + + /* Handle basic constraints */ + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) { + if (bs->ca) + x->ex_flags |= EXFLAG_CA; + if (bs->pathlen) { + if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) || + !bs->ca) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } else + x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + } else + x->ex_pathlen = -1; + BASIC_CONSTRAINTS_free(bs); + x->ex_flags |= EXFLAG_BCONS; + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + + /* Handle key usage */ + if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL))) { + if (usage->length > 0) { + x->ex_kusage = usage->data[0]; + if (usage->length > 1) + x->ex_kusage |= usage->data[1] << 8; + } else + x->ex_kusage = 0; + x->ex_flags |= EXFLAG_KUSAGE; + ASN1_BIT_STRING_free(usage); + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + + x->ex_xkusage = 0; + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL))) { + x->ex_flags |= EXFLAG_XKUSAGE; + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { + case NID_server_auth: + x->ex_xkusage |= XKU_SSL_SERVER; + break; + + case NID_client_auth: + x->ex_xkusage |= XKU_SSL_CLIENT; + break; + + case NID_email_protect: + x->ex_xkusage |= XKU_SMIME; + break; + + case NID_code_sign: + x->ex_xkusage |= XKU_CODE_SIGN; + break; + + case NID_ms_sgc: + case NID_ns_sgc: + x->ex_xkusage |= XKU_SGC; + break; + + case NID_OCSP_sign: + x->ex_xkusage |= XKU_OCSP_SIGN; + break; + + case NID_time_stamp: + x->ex_xkusage |= XKU_TIMESTAMP; + break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; + + case NID_anyExtendedKeyUsage: + x->ex_xkusage |= XKU_ANYEKU; + break; + } + } + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL))) { + if (ns->length > 0) + x->ex_nscert = ns->data[0]; + else + x->ex_nscert = 0; + x->ex_flags |= EXFLAG_NSCERT; + ASN1_BIT_STRING_free(ns); + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + + x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL); + if (x->skid == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL); + if (x->akid == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; + + /* Does subject name match issuer? */ + if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { + x->ex_flags |= EXFLAG_SI; + /* If SKID matches AKID also indicate self signed. */ + if (X509_check_akid(x, x->akid) == X509_V_OK && + !ku_reject(x, KU_KEY_CERT_SIGN)) + x->ex_flags |= EXFLAG_SS; + } + + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &i, NULL); + if (x->altname == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); + if (!x->nc && (i != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + +#ifndef OPENSSL_NO_RFC3779 + x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL); + if (x->rfc3779_addr == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; + if (!X509v3_addr_is_canonical(x->rfc3779_addr)) + x->ex_flags |= EXFLAG_INVALID; + x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL); + if (x->rfc3779_asid == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; + if (!X509v3_asid_is_canonical(x->rfc3779_asid)) + x->ex_flags |= EXFLAG_INVALID; +#endif + + for (i = 0; i < X509_get_ext_count(x); i++) { + ex = X509_get_ext(x, i); + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == + NID_freshest_crl) + x->ex_flags |= EXFLAG_FRESHEST; + if (!X509_EXTENSION_get_critical(ex)) + continue; + if (!X509_supported_extension(ex)) { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } + + if (!x509_extension_oids_are_unique(x)) + x->ex_flags |= EXFLAG_INVALID; + + x509_verify_cert_info_populate(x); + + x->ex_flags |= EXFLAG_SET; +} + +int +x509v3_cache_extensions(X509 *x) +{ + if ((x->ex_flags & EXFLAG_SET) == 0) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + x509v3_cache_extensions_internal(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return (x->ex_flags & EXFLAG_INVALID) == 0; +} + +/* CA checks common to all purposes + * return codes: + * 0 not a CA + * 1 is a CA + * 2 basicConstraints absent so "maybe" a CA + * 3 basicConstraints absent but self signed V1. + * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. + */ + +static int +check_ca(const X509 *x) +{ + /* keyUsage if present should allow cert signing */ + if (ku_reject(x, KU_KEY_CERT_SIGN)) + return 0; + if (x->ex_flags & EXFLAG_BCONS) { + if (x->ex_flags & EXFLAG_CA) + return 1; + /* If basicConstraints says not a CA then say so */ + else + return 0; + } else { + /* we support V1 roots for... uh, I don't really know why. */ + if ((x->ex_flags & V1_ROOT) == V1_ROOT) + return 3; + /* If key usage present it must have certSign so tolerate it */ + else if (x->ex_flags & EXFLAG_KUSAGE) + return 4; + /* Older certificates could have Netscape-specific CA types */ + else if (x->ex_flags & EXFLAG_NSCERT && + x->ex_nscert & NS_ANY_CA) + return 5; + /* can this still be regarded a CA certificate? I doubt it */ + return 0; + } +} + +int +X509_check_ca(X509 *x) +{ + x509v3_cache_extensions(x); + + return check_ca(x); +} +LCRYPTO_ALIAS(X509_check_ca); + +/* Check SSL CA: common checks for SSL client and server */ +static int +check_ssl_ca(const X509 *x) +{ + int ca_ret; + + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) + return ca_ret; + else + return 0; +} + +static int +check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SSL_CLIENT)) + return 0; + if (ca) + return check_ssl_ca(x); + /* We need to do digital signatures with it */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE)) + return 0; + /* nsCertType if present should allow SSL client use */ + if (ns_reject(x, NS_SSL_CLIENT)) + return 0; + return 1; +} + +static int +check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SSL_SERVER|XKU_SGC)) + return 0; + if (ca) + return check_ssl_ca(x); + + if (ns_reject(x, NS_SSL_SERVER)) + return 0; + /* Now as for keyUsage: we'll at least need to sign OR encipher */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) + return 0; + + return 1; +} + +static int +check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int ret; + + ret = check_purpose_ssl_server(xp, x, ca); + if (!ret || ca) + return ret; + /* We need to encipher or Netscape complains */ + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +/* common S/MIME checks */ +static int +purpose_smime(const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SMIME)) + return 0; + if (ca) { + int ca_ret; + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) + return ca_ret; + else + return 0; + } + if (x->ex_flags & EXFLAG_NSCERT) { + if (x->ex_nscert & NS_SMIME) + return 1; + /* Workaround for some buggy certificates */ + if (x->ex_nscert & NS_SSL_CLIENT) + return 2; + return 0; + } + return 1; +} + +static int +check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int ret; + + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) + return 0; + return ret; +} + +static int +check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int ret; + + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +static int +check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (ca) { + int ca_ret; + if ((ca_ret = check_ca(x)) != 2) + return ca_ret; + else + return 0; + } + if (ku_reject(x, KU_CRL_SIGN)) + return 0; + return 1; +} + +/* OCSP helper: this is *not* a full OCSP check. It just checks that + * each CA is valid. Additional checks must be made on the chain. + */ +static int +ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + /* Must be a valid CA. Should we really support the "I don't know" + value (2)? */ + if (ca) + return check_ca(x); + /* leaf certificate is checked in OCSP_verify() */ + return 1; +} + +static int +check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int i_ext; + + /* If ca is true we must return if this is a valid CA certificate. */ + if (ca) + return check_ca(x); + + /* + * Check the optional key usage field: + * if Key Usage is present, it must be one of digitalSignature + * and/or nonRepudiation (other values are not consistent and shall + * be rejected). + */ + if ((x->ex_flags & EXFLAG_KUSAGE) && + ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) + return 0; + + /* Only time stamp key usage is permitted and it's required. */ + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + return 0; + + /* Extended Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1); + if (i_ext >= 0) { + X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) + return 0; + } + + return 1; +} + +static int +no_check(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + return 1; +} + +/* Various checks to see if one certificate issued the second. + * This can be used to prune a set of possible issuer certificates + * which have been looked up using some simple method such as by + * subject name. + * These are: + * 1. Check issuer_name(subject) == subject_name(issuer) + * 2. If akid(subject) exists check it matches issuer + * 3. If key_usage(issuer) exists check it supports certificate signing + * returns 0 for OK, positive for reason for mismatch, reasons match + * codes for X509_verify_cert() + */ + +int +X509_check_issued(X509 *issuer, X509 *subject) +{ + if (X509_NAME_cmp(X509_get_subject_name(issuer), + X509_get_issuer_name(subject))) + return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; + + if (!x509v3_cache_extensions(issuer)) + return X509_V_ERR_UNSPECIFIED; + if (!x509v3_cache_extensions(subject)) + return X509_V_ERR_UNSPECIFIED; + + if (subject->akid) { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; + } + + if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + return X509_V_OK; +} +LCRYPTO_ALIAS(X509_check_issued); + +int +X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) +{ + if (!akid) + return X509_V_OK; + + /* Check key ids (if present) */ + if (akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) ) + return X509_V_ERR_AKID_SKID_MISMATCH; + /* Check serial number */ + if (akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + /* Check issuer name */ + if (akid->issuer) { + /* Ugh, for some peculiar reason AKID includes + * SEQUENCE OF GeneralName. So look for a DirName. + * There may be more than one but we only take any + * notice of the first. + */ + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + int i; + gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type == GEN_DIRNAME) { + nm = gen->d.dirn; + break; + } + } + if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + return X509_V_OK; +} +LCRYPTO_ALIAS(X509_check_akid); + +uint32_t +X509_get_extension_flags(X509 *x) +{ + /* Call for side-effect of computing hash and caching extensions */ + if (X509_check_purpose(x, -1, -1) != 1) + return EXFLAG_INVALID; + + return x->ex_flags; +} +LCRYPTO_ALIAS(X509_get_extension_flags); + +uint32_t +X509_get_key_usage(X509 *x) +{ + /* Call for side-effect of computing hash and caching extensions */ + if (X509_check_purpose(x, -1, -1) != 1) + return 0; + + if (x->ex_flags & EXFLAG_KUSAGE) + return x->ex_kusage; + + return UINT32_MAX; +} +LCRYPTO_ALIAS(X509_get_key_usage); + +uint32_t +X509_get_extended_key_usage(X509 *x) +{ + /* Call for side-effect of computing hash and caching extensions */ + if (X509_check_purpose(x, -1, -1) != 1) + return 0; + + if (x->ex_flags & EXFLAG_XKUSAGE) + return x->ex_xkusage; + + return UINT32_MAX; +} +LCRYPTO_ALIAS(X509_get_extended_key_usage); diff --git a/Libraries/libressl/crypto/x509/x509_r2x.c b/Libraries/libressl/crypto/x509/x509_r2x.c new file mode 100644 index 000000000..39b392259 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_r2x.c @@ -0,0 +1,117 @@ +/* $OpenBSD: x509_r2x.c,v 1.17 2023/04/25 09:46:36 job Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "x509_local.h" + +X509 * +X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) +{ + X509 *ret = NULL; + X509_CINF *xi = NULL; + X509_NAME *xn; + EVP_PKEY *pubkey; + + if ((ret = X509_new()) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* duplicate the request */ + xi = ret->cert_info; + + if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { + if (!X509_set_version(ret, 2)) + goto err; + } + + xn = X509_REQ_get_subject_name(r); + if (X509_set_subject_name(ret, xn) == 0) + goto err; + if (X509_set_issuer_name(ret, xn) == 0) + goto err; + + if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) + goto err; + if (X509_gmtime_adj(xi->validity->notAfter, + (long)60 * 60 * 24 * days) == NULL) + goto err; + + if ((pubkey = X509_REQ_get0_pubkey(r)) == NULL) + goto err; + if (!X509_set_pubkey(ret, pubkey)) + goto err; + + if (!X509_sign(ret, pkey, EVP_md5())) + goto err; + return ret; + +err: + X509_free(ret); + return NULL; +} +LCRYPTO_ALIAS(X509_REQ_to_X509); diff --git a/Libraries/libressl/crypto/x509/x509_req.c b/Libraries/libressl/crypto/x509/x509_req.c new file mode 100644 index 000000000..7ed106241 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_req.c @@ -0,0 +1,356 @@ +/* $OpenBSD: x509_req.c,v 1.33 2023/04/25 09:46:36 job Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "evp_local.h" +#include "x509_local.h" + +X509_REQ * +X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + X509_REQ *ret; + int i; + EVP_PKEY *pktmp; + + ret = X509_REQ_new(); + if (ret == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!X509_REQ_set_version(ret, 0)) + goto err; + + if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) + goto err; + + if ((pktmp = X509_get_pubkey(x)) == NULL) + goto err; + + i = X509_REQ_set_pubkey(ret, pktmp); + EVP_PKEY_free(pktmp); + if (!i) + goto err; + + if (pkey != NULL) { + if (!X509_REQ_sign(ret, pkey, md)) + goto err; + } + return (ret); + +err: + X509_REQ_free(ret); + return (NULL); +} +LCRYPTO_ALIAS(X509_to_X509_REQ); + +EVP_PKEY * +X509_REQ_get_pubkey(X509_REQ *req) +{ + if ((req == NULL) || (req->req_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(req->req_info->pubkey)); +} +LCRYPTO_ALIAS(X509_REQ_get_pubkey); + +EVP_PKEY * +X509_REQ_get0_pubkey(X509_REQ *req) +{ + if (req == NULL || req->req_info == NULL) + return NULL; + return X509_PUBKEY_get0(req->req_info->pubkey); +} +LCRYPTO_ALIAS(X509_REQ_get0_pubkey); + +int +X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +{ + EVP_PKEY *xk = NULL; + int ok = 0; + + if ((xk = X509_REQ_get0_pubkey(x)) == NULL) + return 0; + + switch (EVP_PKEY_cmp(xk, k)) { + case 1: + ok = 1; + break; + case 0: + X509error(X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509error(X509_R_KEY_TYPE_MISMATCH); + break; + case -2: +#ifndef OPENSSL_NO_EC + if (k->type == EVP_PKEY_EC) { + X509error(ERR_R_EC_LIB); + break; + } +#endif +#ifndef OPENSSL_NO_DH + if (k->type == EVP_PKEY_DH) { + /* No idea */ + X509error(X509_R_CANT_CHECK_DH_KEY); + break; + } +#endif + X509error(X509_R_UNKNOWN_KEY_TYPE); + } + + return (ok); +} +LCRYPTO_ALIAS(X509_REQ_check_private_key); + +/* It seems several organisations had the same idea of including a list of + * extensions in a certificate request. There are at least two OIDs that are + * used and there may be more: so the list is configurable. + */ + +static int ext_nid_list[] = {NID_ext_req, NID_ms_ext_req, NID_undef}; + +static int *ext_nids = ext_nid_list; + +int +X509_REQ_extension_nid(int req_nid) +{ + int i, nid; + + for (i = 0; ; i++) { + nid = ext_nids[i]; + if (nid == NID_undef) + return 0; + else if (req_nid == nid) + return 1; + } +} +LCRYPTO_ALIAS(X509_REQ_extension_nid); + +int * +X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} +LCRYPTO_ALIAS(X509_REQ_get_extension_nids); + +void +X509_REQ_set_extension_nids(int *nids) +{ + ext_nids = nids; +} +LCRYPTO_ALIAS(X509_REQ_set_extension_nids); + +STACK_OF(X509_EXTENSION) * +X509_REQ_get_extensions(X509_REQ *req) +{ + X509_ATTRIBUTE *attr; + ASN1_TYPE *ext = NULL; + int idx, *pnid; + const unsigned char *p; + + if (req == NULL || req->req_info == NULL || ext_nids == NULL) + return NULL; + for (pnid = ext_nids; *pnid != NID_undef; pnid++) { + idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); + if (idx == -1) + continue; + attr = X509_REQ_get_attr(req, idx); + ext = X509_ATTRIBUTE_get0_type(attr, 0); + break; + } + if (ext == NULL) + return sk_X509_EXTENSION_new_null(); + if (ext->type != V_ASN1_SEQUENCE) + return NULL; + p = ext->value.sequence->data; + return d2i_X509_EXTENSIONS(NULL, &p, ext->value.sequence->length); +} +LCRYPTO_ALIAS(X509_REQ_get_extensions); + +/* + * Add a STACK_OF extensions to a certificate request: allow alternative OIDs + * in case we want to create a non-standard one. + */ + +int +X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid) +{ + unsigned char *ext = NULL; + int extlen; + int rv; + + extlen = i2d_X509_EXTENSIONS(exts, &ext); + if (extlen <= 0) + return 0; + + rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); + free(ext); + + return rv; +} +LCRYPTO_ALIAS(X509_REQ_add_extensions_nid); + +/* This is the normal usage: use the "official" OID */ +int +X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) +{ + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); +} +LCRYPTO_ALIAS(X509_REQ_add_extensions); + +/* Request attribute functions */ + +int +X509_REQ_get_attr_count(const X509_REQ *req) +{ + return X509at_get_attr_count(req->req_info->attributes); +} +LCRYPTO_ALIAS(X509_REQ_get_attr_count); + +int +X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +} +LCRYPTO_ALIAS(X509_REQ_get_attr_by_NID); + +int +X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); +} +LCRYPTO_ALIAS(X509_REQ_get_attr_by_OBJ); + +X509_ATTRIBUTE * +X509_REQ_get_attr(const X509_REQ *req, int loc) +{ + return X509at_get_attr(req->req_info->attributes, loc); +} +LCRYPTO_ALIAS(X509_REQ_get_attr); + +X509_ATTRIBUTE * +X509_REQ_delete_attr(X509_REQ *req, int loc) +{ + return X509at_delete_attr(req->req_info->attributes, loc); +} +LCRYPTO_ALIAS(X509_REQ_delete_attr); + +int +X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&req->req_info->attributes, attr)) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_REQ_add1_attr); + +int +X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, + type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_REQ_add1_attr_by_OBJ); + +int +X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, + type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_REQ_add1_attr_by_NID); + +int +X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, + type, bytes, len)) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_REQ_add1_attr_by_txt); + +int +i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) +{ + req->req_info->enc.modified = 1; + return i2d_X509_REQ_INFO(req->req_info, pp); +} +LCRYPTO_ALIAS(i2d_re_X509_REQ_tbs); diff --git a/Libraries/libressl/crypto/x509/x509_set.c b/Libraries/libressl/crypto/x509/x509_set.c new file mode 100644 index 000000000..b56d30aec --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_set.c @@ -0,0 +1,262 @@ +/* $OpenBSD: x509_set.c,v 1.26 2023/06/23 08:00:28 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include "x509_local.h" + +const STACK_OF(X509_EXTENSION) * +X509_get0_extensions(const X509 *x) +{ + return x->cert_info->extensions; +} +LCRYPTO_ALIAS(X509_get0_extensions); + +const X509_ALGOR * +X509_get0_tbs_sigalg(const X509 *x) +{ + return x->cert_info->signature; +} +LCRYPTO_ALIAS(X509_get0_tbs_sigalg); + +int +X509_set_version(X509 *x, long version) +{ + if (x == NULL) + return (0); + if (x->cert_info->version == NULL) { + if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL) + return (0); + } + x->cert_info->enc.modified = 1; + return (ASN1_INTEGER_set(x->cert_info->version, version)); +} +LCRYPTO_ALIAS(X509_set_version); + +long +X509_get_version(const X509 *x) +{ + return ASN1_INTEGER_get(x->cert_info->version); +} +LCRYPTO_ALIAS(X509_get_version); + +int +X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return 0; + in = x->cert_info->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + x->cert_info->enc.modified = 1; + ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber = in; + } + } + return in != NULL; +} +LCRYPTO_ALIAS(X509_set_serialNumber); + +int +X509_set_issuer_name(X509 *x, X509_NAME *name) +{ + if (x == NULL || x->cert_info == NULL) + return 0; + x->cert_info->enc.modified = 1; + return X509_NAME_set(&x->cert_info->issuer, name); +} +LCRYPTO_ALIAS(X509_set_issuer_name); + +int +X509_set_subject_name(X509 *x, X509_NAME *name) +{ + if (x == NULL || x->cert_info == NULL) + return 0; + x->cert_info->enc.modified = 1; + return X509_NAME_set(&x->cert_info->subject, name); +} +LCRYPTO_ALIAS(X509_set_subject_name); + +const ASN1_TIME * +X509_get0_notBefore(const X509 *x) +{ + return X509_getm_notBefore(x); +} +LCRYPTO_ALIAS(X509_get0_notBefore); + +ASN1_TIME * +X509_getm_notBefore(const X509 *x) +{ + if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL) + return NULL; + return x->cert_info->validity->notBefore; +} +LCRYPTO_ALIAS(X509_getm_notBefore); + +int +X509_set_notBefore(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL || x->cert_info->validity == NULL) + return 0; + in = x->cert_info->validity->notBefore; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + x->cert_info->enc.modified = 1; + ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore = in; + } + } + return in != NULL; +} +LCRYPTO_ALIAS(X509_set_notBefore); + +int +X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) +{ + return X509_set_notBefore(x, tm); +} +LCRYPTO_ALIAS(X509_set1_notBefore); + +const ASN1_TIME * +X509_get0_notAfter(const X509 *x) +{ + return X509_getm_notAfter(x); +} +LCRYPTO_ALIAS(X509_get0_notAfter); + +ASN1_TIME * +X509_getm_notAfter(const X509 *x) +{ + if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL) + return NULL; + return x->cert_info->validity->notAfter; +} +LCRYPTO_ALIAS(X509_getm_notAfter); + +int +X509_set_notAfter(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL || x->cert_info->validity == NULL) + return 0; + in = x->cert_info->validity->notAfter; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + x->cert_info->enc.modified = 1; + ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter = in; + } + } + return in != NULL; +} +LCRYPTO_ALIAS(X509_set_notAfter); + +int +X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) +{ + return X509_set_notAfter(x, tm); +} +LCRYPTO_ALIAS(X509_set1_notAfter); + +int +X509_set_pubkey(X509 *x, EVP_PKEY *pkey) +{ + if (x == NULL || x->cert_info == NULL) + return 0; + x->cert_info->enc.modified = 1; + return X509_PUBKEY_set(&x->cert_info->key, pkey); +} +LCRYPTO_ALIAS(X509_set_pubkey); + +int +X509_get_signature_type(const X509 *x) +{ + return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm)); +} +LCRYPTO_ALIAS(X509_get_signature_type); + +X509_PUBKEY * +X509_get_X509_PUBKEY(const X509 *x) +{ + return x->cert_info->key; +} +LCRYPTO_ALIAS(X509_get_X509_PUBKEY); + +void +X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, + const ASN1_BIT_STRING **psuid) +{ + if (piuid != NULL) + *piuid = x->cert_info->issuerUID; + if (psuid != NULL) + *psuid = x->cert_info->subjectUID; +} +LCRYPTO_ALIAS(X509_get0_uids); diff --git a/Libraries/libressl/crypto/x509/x509_skey.c b/Libraries/libressl/crypto/x509/x509_skey.c new file mode 100644 index 000000000..245ba5158 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_skey.c @@ -0,0 +1,165 @@ +/* $OpenBSD: x509_skey.c,v 1.5 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +#include "x509_local.h" + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_skey_id = { + .ext_nid = NID_subject_key_identifier, + .ext_flags = 0, + .it = &ASN1_OCTET_STRING_it, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, + .s2i = (X509V3_EXT_S2I)s2i_skey_id, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +char * +i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, const ASN1_OCTET_STRING *oct) +{ + return hex_to_string(oct->data, oct->length); +} +LCRYPTO_ALIAS(i2s_ASN1_OCTET_STRING); + +ASN1_OCTET_STRING * +s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str) +{ + ASN1_OCTET_STRING *oct; + long length; + + if (!(oct = ASN1_OCTET_STRING_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!(oct->data = string_to_hex(str, &length))) { + ASN1_OCTET_STRING_free(oct); + return NULL; + } + + oct->length = length; + + return oct; +} +LCRYPTO_ALIAS(s2i_ASN1_OCTET_STRING); + +static ASN1_OCTET_STRING * +s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + ASN1_BIT_STRING *pk; + unsigned char pkey_dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (strcmp(str, "hash")) + return s2i_ASN1_OCTET_STRING(method, ctx, str); + + if (!(oct = ASN1_OCTET_STRING_new())) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + X509V3error(X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (ctx->subject_req) + pk = ctx->subject_req->req_info->pubkey->public_key; + else + pk = ctx->subject_cert->cert_info->key->public_key; + + if (!pk) { + X509V3error(X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, + EVP_sha1(), NULL)) + goto err; + + if (!ASN1_STRING_set(oct, pkey_dig, diglen)) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + +err: + ASN1_OCTET_STRING_free(oct); + return NULL; +} diff --git a/Libraries/libressl/crypto/x509/x509_trs.c b/Libraries/libressl/crypto/x509/x509_trs.c new file mode 100644 index 000000000..6b935f8be --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_trs.c @@ -0,0 +1,398 @@ +/* $OpenBSD: x509_trs.c,v 1.32 2023/07/02 17:12:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +#include "x509_local.h" + +static int tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b); +static void trtable_free(X509_TRUST *p); + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); + +static int obj_trust(int id, X509 *x, int flags); +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; + +/* WARNING: the following table should be kept in order of trust + * and without any gaps so we can just subtract the minimum trust + * value to get an index into the table + */ + +static X509_TRUST trstandard[] = { + { + .trust = X509_TRUST_COMPAT, + .check_trust = trust_compat, + .name = "compatible", + }, + { + .trust = X509_TRUST_SSL_CLIENT, + .check_trust = trust_1oidany, + .name = "SSL Client", + .arg1 = NID_client_auth, + }, + { + .trust = X509_TRUST_SSL_SERVER, + .check_trust = trust_1oidany, + .name = "SSL Server", + .arg1 = NID_server_auth, + }, + { + .trust = X509_TRUST_EMAIL, + .check_trust = trust_1oidany, + .name = "S/MIME email", + .arg1 = NID_email_protect, + }, + { + .trust = X509_TRUST_OBJECT_SIGN, + .check_trust = trust_1oidany, + .name = "Object Signer", + .arg1 = NID_code_sign, + }, + { + .trust = X509_TRUST_OCSP_SIGN, + .check_trust = trust_1oid, + .name = "OCSP responder", + .arg1 = NID_OCSP_sign, + }, + { + .trust = X509_TRUST_OCSP_REQUEST, + .check_trust = trust_1oid, + .name = "OCSP request", + .arg1 = NID_ad_OCSP, + }, + { + .trust = X509_TRUST_TSA, + .check_trust = trust_1oidany, + .name = "TSA server", + .arg1 = NID_time_stamp, + }, +}; + +#define X509_TRUST_COUNT (sizeof(trstandard) / sizeof(trstandard[0])) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int +tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b) +{ + return (*a)->trust - (*b)->trust; +} + +int +(*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int) +{ + int (*oldtrust)(int , X509 *, int); + + oldtrust = default_trust; + default_trust = trust; + return oldtrust; +} +LCRYPTO_ALIAS(X509_TRUST_set_default); + +int +X509_check_trust(X509 *x, int id, int flags) +{ + X509_TRUST *pt; + int idx; + + if (id == -1) + return 1; + /* + * XXX beck/jsing This enables self signed certs to be trusted for + * an unspecified id/trust flag value (this is NOT the + * X509_TRUST_DEFAULT), which was the longstanding + * openssl behaviour. boringssl does not have this behaviour. + * + * This should be revisited, but changing the default "not default" + * may break things. + */ + if (id == 0) { + int rv; + rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); + if (rv != X509_TRUST_UNTRUSTED) + return rv; + return trust_compat(NULL, x, 0); + } + idx = X509_TRUST_get_by_id(id); + if (idx == -1) + return default_trust(id, x, flags); + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); +} +LCRYPTO_ALIAS(X509_check_trust); + +int +X509_TRUST_get_count(void) +{ + if (!trtable) + return X509_TRUST_COUNT; + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +} +LCRYPTO_ALIAS(X509_TRUST_get_count); + +X509_TRUST * +X509_TRUST_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_TRUST_COUNT) + return trstandard + idx; + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +} +LCRYPTO_ALIAS(X509_TRUST_get0); + +int +X509_TRUST_get_by_id(int id) +{ + X509_TRUST tmp; + int idx; + + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + idx = sk_X509_TRUST_find(trtable, &tmp); + if (idx == -1) + return -1; + return idx + X509_TRUST_COUNT; +} +LCRYPTO_ALIAS(X509_TRUST_get_by_id); + +int +X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + X509error(X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} +LCRYPTO_ALIAS(X509_TRUST_set); + +int +X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2) +{ + int idx; + X509_TRUST *trtmp; + char *name_dup; + + /* This is set according to what we change: application can't set it */ + flags &= ~X509_TRUST_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_TRUST_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_TRUST_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(trtmp = malloc(sizeof(X509_TRUST)))) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else { + trtmp = X509_TRUST_get0(idx); + if (trtmp == NULL) { + X509error(X509_R_INVALID_TRUST); + return 0; + } + } + + if ((name_dup = strdup(name)) == NULL) + goto err; + + /* free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + free(trtmp->name); + /* dup supplied name */ + trtmp->name = name_dup; + /* Keep the dynamic flag of existing entry */ + trtmp->flags &= X509_TRUST_DYNAMIC; + /* Set all other flags */ + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + /* If it's a new entry, manage the dynamic table */ + if (idx == -1) { + if (trtable == NULL && + (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) + goto err; + if (sk_X509_TRUST_push(trtable, trtmp) == 0) + goto err; + } + return 1; + +err: + free(name_dup); + if (idx == -1) + free(trtmp); + X509error(ERR_R_MALLOC_FAILURE); + return 0; +} +LCRYPTO_ALIAS(X509_TRUST_add); + +static void +trtable_free(X509_TRUST *p) +{ + if (!p) + return; + if (p->flags & X509_TRUST_DYNAMIC) { + if (p->flags & X509_TRUST_DYNAMIC_NAME) + free(p->name); + free(p); + } +} + +void +X509_TRUST_cleanup(void) +{ + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; +} +LCRYPTO_ALIAS(X509_TRUST_cleanup); + +int +X509_TRUST_get_flags(const X509_TRUST *xp) +{ + return xp->flags; +} +LCRYPTO_ALIAS(X509_TRUST_get_flags); + +char * +X509_TRUST_get0_name(const X509_TRUST *xp) +{ + return xp->name; +} +LCRYPTO_ALIAS(X509_TRUST_get0_name); + +int +X509_TRUST_get_trust(const X509_TRUST *xp) +{ + return xp->trust; +} +LCRYPTO_ALIAS(X509_TRUST_get_trust); + +static int +trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* we don't have any trust settings: for compatibility + * we return trusted if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int +trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux) + return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} + +static int +trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return X509_TRUST_TRUSTED; + else + return X509_TRUST_UNTRUSTED; +} + +static int +obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + int i, nid; + X509_CERT_AUX *ax; + + ax = x->aux; + if (!ax) + return X509_TRUST_UNTRUSTED; + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + nid = OBJ_obj2nid(obj); + if (nid == id || nid == NID_anyExtendedKeyUsage) + return X509_TRUST_REJECTED; + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + nid = OBJ_obj2nid(obj); + if (nid == id || nid == NID_anyExtendedKeyUsage) + return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} diff --git a/Libraries/libressl/crypto/x509/x509_txt.c b/Libraries/libressl/crypto/x509/x509_txt.c new file mode 100644 index 000000000..5f5bc5ae8 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_txt.c @@ -0,0 +1,196 @@ +/* $OpenBSD: x509_txt.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +const char * +X509_verify_cert_error_string(long n) +{ + switch ((int)n) { + case X509_V_OK: + return "ok"; + case X509_V_ERR_UNSPECIFIED: + return "Unspecified certificate verification error"; + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + return "unable to get issuer certificate"; + case X509_V_ERR_UNABLE_TO_GET_CRL: + return "unable to get certificate CRL"; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + return "unable to decrypt certificate's signature"; + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + return "unable to decrypt CRL's signature"; + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + return "unable to decode issuer public key"; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + return "certificate signature failure"; + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return "CRL signature failure"; + case X509_V_ERR_CERT_NOT_YET_VALID: + return "certificate is not yet valid"; + case X509_V_ERR_CERT_HAS_EXPIRED: + return "certificate has expired"; + case X509_V_ERR_CRL_NOT_YET_VALID: + return "CRL is not yet valid"; + case X509_V_ERR_CRL_HAS_EXPIRED: + return "CRL has expired"; + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + return "format error in certificate's notBefore field"; + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + return "format error in certificate's notAfter field"; + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + return "format error in CRL's lastUpdate field"; + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return "format error in CRL's nextUpdate field"; + case X509_V_ERR_OUT_OF_MEM: + return "out of memory"; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return "self signed certificate"; + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + return "self signed certificate in certificate chain"; + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return "unable to get local issuer certificate"; + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return "unable to verify the first certificate"; + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + return "certificate chain too long"; + case X509_V_ERR_CERT_REVOKED: + return "certificate revoked"; + case X509_V_ERR_INVALID_CA: + return "invalid CA certificate"; + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + return "path length constraint exceeded"; + case X509_V_ERR_INVALID_PURPOSE: + return "unsupported certificate purpose"; + case X509_V_ERR_CERT_UNTRUSTED: + return "certificate not trusted"; + case X509_V_ERR_CERT_REJECTED: + return "certificate rejected"; + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + return "subject issuer mismatch"; + case X509_V_ERR_AKID_SKID_MISMATCH: + return "authority and subject key identifier mismatch"; + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + return "authority and issuer serial number mismatch"; + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: + return "key usage does not include certificate signing"; + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + return "unable to get CRL issuer certificate"; + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return "unhandled critical extension"; + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + return "key usage does not include CRL signing"; + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + return "unhandled critical CRL extension"; + case X509_V_ERR_INVALID_NON_CA: + return "invalid non-CA certificate (has CA markings)"; + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + return "proxy path length constraint exceeded"; + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: + return "key usage does not include digital signature"; + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + return "proxy certificates not allowed, " + "please set the appropriate flag"; + case X509_V_ERR_INVALID_EXTENSION: + return "invalid or inconsistent certificate extension"; + case X509_V_ERR_INVALID_POLICY_EXTENSION: + return "invalid or inconsistent certificate policy extension"; + case X509_V_ERR_NO_EXPLICIT_POLICY: + return "no explicit policy"; + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + return "Different CRL scope"; + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: + return "Unsupported extension feature"; + case X509_V_ERR_UNNESTED_RESOURCE: + return "RFC 3779 resource not subset of parent's resources"; + case X509_V_ERR_PERMITTED_VIOLATION: + return "permitted subtree violation"; + case X509_V_ERR_EXCLUDED_VIOLATION: + return "excluded subtree violation"; + case X509_V_ERR_SUBTREE_MINMAX: + return "name constraints minimum and maximum not supported"; + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: + return "unsupported name constraint type"; + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: + return "unsupported or invalid name constraint syntax"; + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + return "unsupported or invalid name syntax"; + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + return "CRL path validation error"; + case X509_V_ERR_APPLICATION_VERIFICATION: + return "application verification failure"; + case X509_V_ERR_HOSTNAME_MISMATCH: + return "Hostname mismatch"; + case X509_V_ERR_EMAIL_MISMATCH: + return "Email address mismatch"; + case X509_V_ERR_IP_ADDRESS_MISMATCH: + return "IP address mismatch"; + case X509_V_ERR_INVALID_CALL: + return "Invalid certificate verification context"; + case X509_V_ERR_STORE_LOOKUP: + return "Issuer certificate lookup error"; + case X509_V_ERR_EE_KEY_TOO_SMALL: + return "EE certificate key too weak"; + case X509_V_ERR_CA_KEY_TOO_SMALL: + return "CA certificate key too weak"; + case X509_V_ERR_CA_MD_TOO_WEAK: + return "CA signature digest algorithm too weak"; + default: + return "Unknown certificate verification error"; + } +} +LCRYPTO_ALIAS(X509_verify_cert_error_string); diff --git a/Libraries/libressl/crypto/x509/x509_utl.c b/Libraries/libressl/crypto/x509/x509_utl.c new file mode 100644 index 000000000..14b43e8b6 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_utl.c @@ -0,0 +1,1486 @@ +/* $OpenBSD: x509_utl.c,v 1.17 2023/05/12 19:02:10 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bytestring.h" + +static char *bn_to_string(const BIGNUM *bn); +static char *strip_spaces(char *name); +static int sk_strcmp(const char * const *a, const char * const *b); +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens); +static void str_free(OPENSSL_STRING str); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); + +static int ipv4_from_asc(unsigned char *v4, const char *in); +static int ipv6_from_asc(unsigned char *v6, const char *in); +static int ipv6_cb(const char *elem, int len, void *usr); +static int ipv6_hex(unsigned char *out, const char *in, int inlen); + +/* Add a CONF_VALUE name-value pair to stack. */ +int +X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + CONF_VALUE *vtmp = NULL; + STACK_OF(CONF_VALUE) *free_exts = NULL; + + if ((vtmp = calloc(1, sizeof(CONF_VALUE))) == NULL) + goto err; + if (name != NULL) { + if ((vtmp->name = strdup(name)) == NULL) + goto err; + } + if (value != NULL) { + if ((vtmp->value = strdup(value)) == NULL) + goto err; + } + + if (*extlist == NULL) { + if ((free_exts = *extlist = sk_CONF_VALUE_new_null()) == NULL) + goto err; + } + + if (!sk_CONF_VALUE_push(*extlist, vtmp)) + goto err; + + return 1; + + err: + X509V3error(ERR_R_MALLOC_FAILURE); + X509V3_conf_free(vtmp); + if (free_exts != NULL) { + sk_CONF_VALUE_free(*extlist); + *extlist = NULL; + } + return 0; +} +LCRYPTO_ALIAS(X509V3_add_value); + +int +X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return X509V3_add_value(name, (const char *)value, extlist); +} +LCRYPTO_ALIAS(X509V3_add_value_uchar); + +/* Free function for STACK_OF(CONF_VALUE) */ + +void +X509V3_conf_free(CONF_VALUE *conf) +{ + if (!conf) + return; + free(conf->name); + free(conf->value); + free(conf->section); + free(conf); +} +LCRYPTO_ALIAS(X509V3_conf_free); + +int +X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return X509V3_add_value(name, "FALSE", extlist); +} +LCRYPTO_ALIAS(X509V3_add_value_bool); + +int +X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return 1; +} +LCRYPTO_ALIAS(X509V3_add_value_bool_nf); + +static char * +bn_to_string(const BIGNUM *bn) +{ + const char *sign = ""; + char *bnstr, *hex; + char *ret = NULL; + + /* Only display small numbers in decimal, as conversion is quadratic. */ + if (BN_num_bits(bn) < 128) + return BN_bn2dec(bn); + + if ((hex = bnstr = BN_bn2hex(bn)) == NULL) + goto err; + + if (BN_is_negative(bn)) { + sign = "-"; + hex++; + } + + if (asprintf(&ret, "%s0x%s", sign, hex) == -1) + ret = NULL; + + err: + free(bnstr); + return ret; +} + +char * +i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) +{ + BIGNUM *bntmp; + char *strtmp = NULL; + + if (a == NULL) + return NULL; + if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL || + (strtmp = bn_to_string(bntmp)) == NULL) + X509V3error(ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} +LCRYPTO_ALIAS(i2s_ASN1_ENUMERATED); + +char * +i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *e) +{ + BIT_STRING_BITNAME *enam; + long strval; + + strval = ASN1_ENUMERATED_get(e); + for (enam = method->usr_data; enam->lname; enam++) { + if (strval == enam->bitnum) + return strdup(enam->lname); + } + return i2s_ASN1_ENUMERATED(method, e); +} +LCRYPTO_ALIAS(i2s_ASN1_ENUMERATED_TABLE); + +char * +i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) +{ + BIGNUM *bntmp; + char *strtmp = NULL; + + if (a == NULL) + return NULL; + if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL || + (strtmp = bn_to_string(bntmp)) == NULL) + X509V3error(ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} +LCRYPTO_ALIAS(i2s_ASN1_INTEGER); + +ASN1_INTEGER * +s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) +{ + BIGNUM *bn = NULL; + ASN1_INTEGER *aint; + int isneg = 0, ishex = 0; + int ret; + + if (!value) { + X509V3error(X509V3_R_INVALID_NULL_VALUE); + return NULL; + } + if ((bn = BN_new()) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + return NULL; + } + if (value[0] == '-') { + value++; + isneg = 1; + } + + if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { + value += 2; + ishex = 1; + } + + if (ishex) + ret = BN_hex2bn(&bn, value); + else + ret = BN_dec2bn(&bn, value); + + if (!ret || value[ret]) { + BN_free(bn); + X509V3error(X509V3_R_BN_DEC2BN_ERROR); + return NULL; + } + + if (BN_is_zero(bn)) + isneg = 0; + + aint = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + if (!aint) { + X509V3error(X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + return NULL; + } + if (isneg) + aint->type |= V_ASN1_NEG; + return aint; +} +LCRYPTO_ALIAS(s2i_ASN1_INTEGER); + +int +X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist) +{ + char *strtmp; + int ret; + + if (!aint) + return 1; + if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) + return 0; + ret = X509V3_add_value(name, strtmp, extlist); + free(strtmp); + return ret; +} +LCRYPTO_ALIAS(X509V3_add_value_int); + +int +X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool) +{ + char *btmp; + + if (!(btmp = value->value)) + goto err; + if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") || + !strcmp(btmp, "Y") || !strcmp(btmp, "y") || + !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { + *asn1_bool = 0xff; + return 1; + } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") || + !strcmp(btmp, "N") || !strcmp(btmp, "n") || + !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { + *asn1_bool = 0; + return 1; + } + + err: + X509V3error(X509V3_R_INVALID_BOOLEAN_STRING); + X509V3_conf_err(value); + return 0; +} +LCRYPTO_ALIAS(X509V3_get_value_bool); + +int +X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) +{ + ASN1_INTEGER *itmp; + + if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { + X509V3_conf_err(value); + return 0; + } + *aint = itmp; + return 1; +} +LCRYPTO_ALIAS(X509V3_get_value_int); + +#define HDR_NAME 1 +#define HDR_VALUE 2 + +/*#define DEBUG*/ + +STACK_OF(CONF_VALUE) * +X509V3_parse_list(const char *line) +{ + char *p, *q, c; + char *ntmp, *vtmp; + STACK_OF(CONF_VALUE) *values = NULL; + char *linebuf; + int state; + + /* We are going to modify the line so copy it first */ + if ((linebuf = strdup(line)) == NULL) { + X509V3error(ERR_R_MALLOC_FAILURE); + goto err; + } + state = HDR_NAME; + ntmp = NULL; + + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && + (c != '\n'); p++) { + + switch (state) { + case HDR_NAME: + if (c == ':') { + state = HDR_VALUE; + *p = 0; + ntmp = strip_spaces(q); + if (!ntmp) { + X509V3error(X509V3_R_INVALID_NULL_NAME); + goto err; + } + q = p + 1; + } else if (c == ',') { + *p = 0; + ntmp = strip_spaces(q); + q = p + 1; + if (!ntmp) { + X509V3error(X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + break; + + case HDR_VALUE: + if (c == ',') { + state = HDR_NAME; + *p = 0; + vtmp = strip_spaces(q); + if (!vtmp) { + X509V3error(X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + ntmp = NULL; + q = p + 1; + } + + } + } + + if (state == HDR_VALUE) { + vtmp = strip_spaces(q); + if (!vtmp) { + X509V3error(X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + } else { + ntmp = strip_spaces(q); + if (!ntmp) { + X509V3error(X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + free(linebuf); + return values; + + err: + free(linebuf); + sk_CONF_VALUE_pop_free(values, X509V3_conf_free); + return NULL; + +} +LCRYPTO_ALIAS(X509V3_parse_list); + +/* Delete leading and trailing spaces from a string */ +static char * +strip_spaces(char *name) +{ + char *p, *q; + + /* Skip over leading spaces */ + p = name; + while (*p && isspace((unsigned char)*p)) + p++; + if (!*p) + return NULL; + q = p + strlen(p) - 1; + while ((q != p) && isspace((unsigned char)*q)) + q--; + if (p != q) + q[1] = 0; + if (!*p) + return NULL; + return p; +} + +static const char hex_digits[] = "0123456789ABCDEF"; + +char * +hex_to_string(const unsigned char *buffer, long len) +{ + CBB cbb; + CBS cbs; + uint8_t *out = NULL; + uint8_t c; + size_t out_len; + + if (!CBB_init(&cbb, 0)) + goto err; + + if (len < 0) + goto err; + + CBS_init(&cbs, buffer, len); + while (CBS_len(&cbs) > 0) { + if (!CBS_get_u8(&cbs, &c)) + goto err; + if (!CBB_add_u8(&cbb, hex_digits[c >> 4])) + goto err; + if (!CBB_add_u8(&cbb, hex_digits[c & 0xf])) + goto err; + if (CBS_len(&cbs) > 0) { + if (!CBB_add_u8(&cbb, ':')) + goto err; + } + } + + if (!CBB_add_u8(&cbb, '\0')) + goto err; + + if (!CBB_finish(&cbb, &out, &out_len)) + goto err; + + err: + CBB_cleanup(&cbb); + + return out; +} +LCRYPTO_ALIAS(hex_to_string); + +static int +x509_skip_colons_cbs(CBS *cbs) +{ + uint8_t c; + + while (CBS_len(cbs) > 0) { + if (!CBS_peek_u8(cbs, &c)) + return 0; + if (c != ':') + return 1; + if (!CBS_get_u8(cbs, &c)) + return 0; + } + + return 1; +} + +static int +x509_get_xdigit_nibble_cbs(CBS *cbs, uint8_t *out_nibble) +{ + uint8_t c; + + if (!CBS_get_u8(cbs, &c)) + return 0; + + if (c >= '0' && c <= '9') { + *out_nibble = c - '0'; + return 1; + } + if (c >= 'a' && c <= 'f') { + *out_nibble = c - 'a' + 10; + return 1; + } + if (c >= 'A' && c <= 'F') { + *out_nibble = c - 'A' + 10; + return 1; + } + + X509V3error(X509V3_R_ILLEGAL_HEX_DIGIT); + return 0; +} + +unsigned char * +string_to_hex(const char *str, long *len) +{ + CBB cbb; + CBS cbs; + uint8_t *out = NULL; + size_t out_len; + uint8_t hi, lo; + + *len = 0; + + if (!CBB_init(&cbb, 0)) + goto err; + + if (str == NULL) { + X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); + goto err; + } + + CBS_init(&cbs, str, strlen(str)); + while (CBS_len(&cbs) > 0) { + /* + * Skipping only a single colon between two pairs of digits + * would make more sense - history... + */ + if (!x509_skip_colons_cbs(&cbs)) + goto err; + /* Another historic idiocy. */ + if (CBS_len(&cbs) == 0) + break; + if (!x509_get_xdigit_nibble_cbs(&cbs, &hi)) + goto err; + if (CBS_len(&cbs) == 0) { + X509V3error(X509V3_R_ODD_NUMBER_OF_DIGITS); + goto err; + } + if (!x509_get_xdigit_nibble_cbs(&cbs, &lo)) + goto err; + if (!CBB_add_u8(&cbb, hi << 4 | lo)) + goto err; + } + + if (!CBB_finish(&cbb, &out, &out_len)) + goto err; + if (out_len > LONG_MAX) { + freezero(out, out_len); + out = NULL; + goto err; + } + + *len = out_len; + + err: + CBB_cleanup(&cbb); + + return out; +} +LCRYPTO_ALIAS(string_to_hex); + +/* V2I name comparison function: returns zero if 'name' matches + * cmp or cmp.* + */ + +int +name_cmp(const char *name, const char *cmp) +{ + int len, ret; + char c; + + len = strlen(cmp); + if ((ret = strncmp(name, cmp, len))) + return ret; + c = name[len]; + if (!c || (c=='.')) + return 0; + return 1; +} + +static int +sk_strcmp(const char * const *a, const char * const *b) +{ + return strcmp(*a, *b); +} + +STACK_OF(OPENSSL_STRING) * +X509_get1_email(X509 *x) +{ + GENERAL_NAMES *gens; + STACK_OF(OPENSSL_STRING) *ret; + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return ret; +} +LCRYPTO_ALIAS(X509_get1_email); + +STACK_OF(OPENSSL_STRING) * +X509_get1_ocsp(X509 *x) +{ + AUTHORITY_INFO_ACCESS *info; + STACK_OF(OPENSSL_STRING) *ret = NULL; + int i; + + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); + if (!info) + return NULL; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { + if (ad->location->type == GEN_URI) { + if (!append_ia5(&ret, + ad->location->d.uniformResourceIdentifier)) + break; + } + } + } + AUTHORITY_INFO_ACCESS_free(info); + return ret; +} +LCRYPTO_ALIAS(X509_get1_ocsp); + +STACK_OF(OPENSSL_STRING) * +X509_REQ_get1_email(X509_REQ *x) +{ + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts; + STACK_OF(OPENSSL_STRING) *ret; + + exts = X509_REQ_get_extensions(x); + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_REQ_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; +} +LCRYPTO_ALIAS(X509_REQ_get1_email); + + +static STACK_OF(OPENSSL_STRING) * +get_email(X509_NAME *name, GENERAL_NAMES *gens) +{ + STACK_OF(OPENSSL_STRING) *ret = NULL; + X509_NAME_ENTRY *ne; + ASN1_IA5STRING *email; + GENERAL_NAME *gen; + int i; + + /* Now add any email address(es) to STACK */ + i = -1; + + /* First supplied X509_NAME */ + while ((i = X509_NAME_get_index_by_NID(name, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(name, i); + email = X509_NAME_ENTRY_get_data(ne); + if (!append_ia5(&ret, email)) + return NULL; + } + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != GEN_EMAIL) + continue; + if (!append_ia5(&ret, gen->d.ia5)) + return NULL; + } + return ret; +} + +static void +str_free(OPENSSL_STRING str) +{ + free(str); +} + +static int +append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) +{ + char *emtmp; + + /* First some sanity checks */ + if (email->type != V_ASN1_IA5STRING) + return 1; + if (!email->data || !email->length) + return 1; + if (!*sk) + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + if (!*sk) + return 0; + /* Don't add duplicates */ + if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) + return 1; + emtmp = strdup((char *)email->data); + if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { + X509_email_free(*sk); + *sk = NULL; + return 0; + } + return 1; +} + +void +X509_email_free(STACK_OF(OPENSSL_STRING) *sk) +{ + sk_OPENSSL_STRING_pop_free(sk, str_free); +} +LCRYPTO_ALIAS(X509_email_free); + +typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, unsigned int flags); + +/* Skip pattern prefix to match "wildcard" subject */ +static void +skip_prefix(const unsigned char **p, size_t *plen, const unsigned char *subject, + size_t subject_len, unsigned int flags) +{ + const unsigned char *pattern = *p; + size_t pattern_len = *plen; + + /* + * If subject starts with a leading '.' followed by more octets, and + * pattern is longer, compare just an equal-length suffix with the + * full subject (starting at the '.'), provided the prefix contains + * no NULs. + */ + if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0) + return; + + while (pattern_len > subject_len && *pattern) { + if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) && + *pattern == '.') + break; + ++pattern; + --pattern_len; + } + + /* Skip if entire prefix acceptable */ + if (pattern_len == subject_len) { + *p = pattern; + *plen = pattern_len; + } +} + +/* + * Open/BoringSSL uses memcmp for "equal_case" while their + * "equal_nocase" function is a hand-rolled strncasecmp that does not + * allow \0 in the pattern. Since an embedded \0 is likely a sign of + * problems, we simply don't allow it in either case, and then we use + * standard libc functions. + */ + +/* Compare using strncasecmp */ +static int +equal_nocase(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, unsigned int flags) +{ + if (memchr(pattern, '\0', pattern_len) != NULL) + return 0; + if (memchr(subject, '\0', subject_len) != NULL) + return 0; + skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); + if (pattern_len != subject_len) + return 0; + return (strncasecmp(pattern, subject, pattern_len) == 0); +} + +/* Compare using strncmp. */ +static int +equal_case(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, unsigned int flags) +{ + if (memchr(pattern, 0, pattern_len) != NULL) + return 0; + if (memchr(subject, 0, subject_len) != NULL) + return 0; + skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); + if (pattern_len != subject_len) + return 0; + return (strncmp(pattern, subject, pattern_len) == 0); +} + +/* + * RFC 5280, section 7.5, requires that only the domain is compared in a + * case-insensitive manner. + */ +static int +equal_email(const unsigned char *a, size_t a_len, const unsigned char *b, + size_t b_len, unsigned int unused_flags) +{ + size_t pos = a_len; + if (a_len != b_len) + return 0; + /* + * We search backwards for the '@' character, so that we do not have to + * deal with quoted local-parts. The domain part is compared in a + * case-insensitive manner. + */ + while (pos > 0) { + pos--; + if (a[pos] == '@' || b[pos] == '@') { + if (!equal_nocase(a + pos, a_len - pos, b + pos, + a_len - pos, 0)) + return 0; + break; + } + } + if (pos == 0) + pos = a_len; + return equal_case(a, pos, b, pos, 0); +} + +/* + * Compare the prefix and suffix with the subject, and check that the + * characters in-between are valid. + */ +static int +wildcard_match(const unsigned char *prefix, size_t prefix_len, + const unsigned char *suffix, size_t suffix_len, + const unsigned char *subject, size_t subject_len, unsigned int flags) +{ + const unsigned char *wildcard_start; + const unsigned char *wildcard_end; + const unsigned char *p; + int allow_multi = 0; + int allow_idna = 0; + + if (subject_len < prefix_len + suffix_len) + return 0; + if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) + return 0; + wildcard_start = subject + prefix_len; + wildcard_end = subject + (subject_len - suffix_len); + if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) + return 0; + /* + * If the wildcard makes up the entire first label, it must match at + * least one character. + */ + if (prefix_len == 0 && *suffix == '.') { + if (wildcard_start == wildcard_end) + return 0; + allow_idna = 1; + if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS) + allow_multi = 1; + } + /* IDNA labels cannot match partial wildcards */ + if (!allow_idna && + subject_len >= 4 + && strncasecmp((char *)subject, "xn--", 4) == 0) + return 0; + /* The wildcard may match a literal '*' */ + if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') + return 1; + /* + * Check that the part matched by the wildcard contains only + * permitted characters and only matches a single label unless + * allow_multi is set. + */ + for (p = wildcard_start; p != wildcard_end; ++p) + if (!(('0' <= *p && *p <= '9') || ('A' <= *p && *p <= 'Z') || + ('a' <= *p && *p <= 'z') || *p == '-' || + (allow_multi && *p == '.'))) + return 0; + return 1; +} + +#define LABEL_START (1 << 0) +#define LABEL_END (1 << 1) +#define LABEL_HYPHEN (1 << 2) +#define LABEL_IDNA (1 << 3) + +static const unsigned char * +valid_star(const unsigned char *p, size_t len, unsigned int flags) +{ + const unsigned char *star = 0; + size_t i; + int state = LABEL_START; + int dots = 0; + for (i = 0; i < len; ++i) { + /* + * Locate first and only legal wildcard, either at the start + * or end of a non-IDNA first and not final label. + */ + if (p[i] == '*') { + int atstart = (state & LABEL_START); + int atend = (i == len - 1 || p[i + 1] == '.'); + /* + * At most one wildcard per pattern. + * No wildcards in IDNA labels. + * No wildcards after the first label. + */ + if (star != NULL || (state & LABEL_IDNA) != 0 || dots) + return NULL; + /* Only full-label '*.example.com' wildcards? */ + if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS) + && (!atstart || !atend)) + return NULL; + /* No 'foo*bar' wildcards */ + if (!atstart && !atend) + return NULL; + star = &p[i]; + state &= ~LABEL_START; + } else if ((state & LABEL_START) != 0) { + /* + * At the start of a label, skip any "xn--" and + * remain in the LABEL_START state, but set the + * IDNA label state + */ + if ((state & LABEL_IDNA) == 0 && len - i >= 4 + && strncasecmp((char *)&p[i], "xn--", 4) == 0) { + i += 3; + state |= LABEL_IDNA; + continue; + } + /* Labels must start with a letter or digit */ + state &= ~LABEL_START; + if (('a' <= p[i] && p[i] <= 'z') + || ('A' <= p[i] && p[i] <= 'Z') + || ('0' <= p[i] && p[i] <= '9')) + continue; + return NULL; + } else if (('a' <= p[i] && p[i] <= 'z') + || ('A' <= p[i] && p[i] <= 'Z') + || ('0' <= p[i] && p[i] <= '9')) { + state &= LABEL_IDNA; + continue; + } else if (p[i] == '.') { + if (state & (LABEL_HYPHEN | LABEL_START)) + return NULL; + state = LABEL_START; + ++dots; + } else if (p[i] == '-') { + /* no domain/subdomain starts with '-' */ + if ((state & LABEL_START) != 0) + return NULL; + state |= LABEL_HYPHEN; + } else + return NULL; + } + + /* + * The final label must not end in a hyphen or ".", and + * there must be at least two dots after the star. + */ + if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) + return NULL; + return star; +} + +/* Compare using wildcards. */ +static int +equal_wildcard(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, unsigned int flags) +{ + const unsigned char *star = NULL; + + /* + * Subject names starting with '.' can only match a wildcard pattern + * via a subject sub-domain pattern suffix match. + */ + if (!(subject_len > 1 && subject[0] == '.')) + star = valid_star(pattern, pattern_len, flags); + if (star == NULL) + return equal_nocase(pattern, pattern_len, + subject, subject_len, flags); + return wildcard_match(pattern, star - pattern, + star + 1, (pattern + pattern_len) - star - 1, + subject, subject_len, flags); +} + +/* + * Compare an ASN1_STRING to a supplied string. If they match return 1. If + * cmp_type > 0 only compare if string matches the type, otherwise convert it + * to UTF8. + */ + +static int +do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, + unsigned int flags, const char *b, size_t blen, char **peername) +{ + int rv = 0; + + if (!a->data || !a->length) + return 0; + if (cmp_type > 0) { + if (cmp_type != a->type) + return 0; + if (cmp_type == V_ASN1_IA5STRING) + rv = equal(a->data, a->length, (unsigned char *)b, + blen, flags); + else if (a->length == (int)blen && !memcmp(a->data, b, blen)) + rv = 1; + if (rv > 0 && peername && + (*peername = strndup((char *)a->data, a->length)) == NULL) + rv = -1; + } else { + int astrlen; + unsigned char *astr = NULL; + astrlen = ASN1_STRING_to_UTF8(&astr, a); + if (astrlen < 0) + return -1; + rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); + if (rv > 0 && peername && + (*peername = strndup((char *)astr, astrlen)) == NULL) + rv = -1; + free(astr); + } + return rv; +} + +static int +do_x509_check(X509 *x, const char *chk, size_t chklen, unsigned int flags, + int check_type, char **peername) +{ + GENERAL_NAMES *gens = NULL; + X509_NAME *name = NULL; + size_t i; + int j; + int cnid = NID_undef; + int alt_type; + int san_present = 0; + int rv = 0; + equal_fn equal; + + /* See below, this flag is internal-only */ + flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS; + if (check_type == GEN_EMAIL) { + cnid = NID_pkcs9_emailAddress; + alt_type = V_ASN1_IA5STRING; + equal = equal_email; + } else if (check_type == GEN_DNS) { + if (!(flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) + cnid = NID_commonName; + /* Implicit client-side DNS sub-domain pattern */ + if (chklen > 1 && chk[0] == '.') + flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS; + alt_type = V_ASN1_IA5STRING; + if (flags & X509_CHECK_FLAG_NO_WILDCARDS) + equal = equal_nocase; + else + equal = equal_wildcard; + } else { + alt_type = V_ASN1_OCTET_STRING; + equal = equal_case; + } + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + if (gens != NULL) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + GENERAL_NAME *gen; + ASN1_STRING *cstr; + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != check_type) + continue; + san_present = 1; + if (check_type == GEN_EMAIL) + cstr = gen->d.rfc822Name; + else if (check_type == GEN_DNS) + cstr = gen->d.dNSName; + else + cstr = gen->d.iPAddress; + /* Positive on success, negative on error! */ + if ((rv = do_check_string(cstr, alt_type, equal, flags, + chk, chklen, peername)) != 0) + break; + } + GENERAL_NAMES_free(gens); + if (rv != 0) + return rv; + if (cnid == NID_undef || + (san_present && + !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))) + return 0; + } + + /* We're done if CN-ID is not pertinent */ + if (cnid == NID_undef) + return 0; + + j = -1; + name = X509_get_subject_name(x); + while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { + X509_NAME_ENTRY *ne; + ASN1_STRING *str; + if ((ne = X509_NAME_get_entry(name, j)) == NULL) + return -1; + if ((str = X509_NAME_ENTRY_get_data(ne)) == NULL) + return -1; + /* Positive on success, negative on error! */ + if ((rv = do_check_string(str, -1, equal, flags, + chk, chklen, peername)) != 0) + return rv; + } + return 0; +} + +int +X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags, + char **peername) +{ + if (chk == NULL) + return -2; + if (chklen == 0) + chklen = strlen(chk); + else if (memchr(chk, '\0', chklen)) + return -2; + return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); +} +LCRYPTO_ALIAS(X509_check_host); + +int +X509_check_email(X509 *x, const char *chk, size_t chklen, unsigned int flags) +{ + if (chk == NULL) + return -2; + if (chklen == 0) + chklen = strlen(chk); + else if (memchr(chk, '\0', chklen)) + return -2; + return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); +} +LCRYPTO_ALIAS(X509_check_email); + +int +X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags) +{ + if (chk == NULL) + return -2; + return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); +} +LCRYPTO_ALIAS(X509_check_ip); + +int +X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) +{ + unsigned char ipout[16]; + size_t iplen; + + if (ipasc == NULL) + return -2; + iplen = (size_t)a2i_ipadd(ipout, ipasc); + if (iplen == 0) + return -2; + return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); +} +LCRYPTO_ALIAS(X509_check_ip_asc); + +/* Convert IP addresses both IPv4 and IPv6 into an + * OCTET STRING compatible with RFC3280. + */ + +ASN1_OCTET_STRING * +a2i_IPADDRESS(const char *ipasc) +{ + unsigned char ipout[16]; + ASN1_OCTET_STRING *ret; + int iplen; + + /* If string contains a ':' assume IPv6 */ + + iplen = a2i_ipadd(ipout, ipasc); + + if (!iplen) + return NULL; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { + ASN1_OCTET_STRING_free(ret); + return NULL; + } + return ret; +} +LCRYPTO_ALIAS(a2i_IPADDRESS); + +ASN1_OCTET_STRING * +a2i_IPADDRESS_NC(const char *ipasc) +{ + ASN1_OCTET_STRING *ret = NULL; + unsigned char ipout[32]; + char *iptmp = NULL, *p; + int iplen1, iplen2; + + p = strchr(ipasc, '/'); + if (!p) + return NULL; + iptmp = strdup(ipasc); + if (!iptmp) + return NULL; + p = iptmp + (p - ipasc); + *p++ = 0; + + iplen1 = a2i_ipadd(ipout, iptmp); + + if (!iplen1) + goto err; + + iplen2 = a2i_ipadd(ipout + iplen1, p); + + free(iptmp); + iptmp = NULL; + + if (!iplen2 || (iplen1 != iplen2)) + goto err; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + goto err; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) + goto err; + + return ret; + + err: + free(iptmp); + if (ret) + ASN1_OCTET_STRING_free(ret); + return NULL; +} +LCRYPTO_ALIAS(a2i_IPADDRESS_NC); + + +int +a2i_ipadd(unsigned char *ipout, const char *ipasc) +{ + /* If string contains a ':' assume IPv6 */ + + if (strchr(ipasc, ':')) { + if (!ipv6_from_asc(ipout, ipasc)) + return 0; + return 16; + } else { + if (!ipv4_from_asc(ipout, ipasc)) + return 0; + return 4; + } +} +LCRYPTO_ALIAS(a2i_ipadd); + +static int +ipv4_from_asc(unsigned char *v4, const char *in) +{ + int a0, a1, a2, a3; + if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) || + (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; + v4[3] = a3; + return 1; +} + +typedef struct { + /* Temporary store for IPV6 output */ + unsigned char tmp[16]; + /* Total number of bytes in tmp */ + int total; + /* The position of a zero (corresponding to '::') */ + int zero_pos; + /* Number of zeroes */ + int zero_cnt; +} IPV6_STAT; + + +static int +ipv6_from_asc(unsigned char *v6, const char *in) +{ + IPV6_STAT v6stat; + + v6stat.total = 0; + v6stat.zero_pos = -1; + v6stat.zero_cnt = 0; + + /* Treat the IPv6 representation as a list of values + * separated by ':'. The presence of a '::' will parse + * as one, two or three zero length elements. + */ + if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) + return 0; + + /* Now for some sanity checks */ + + if (v6stat.zero_pos == -1) { + /* If no '::' must have exactly 16 bytes */ + if (v6stat.total != 16) + return 0; + } else { + /* If '::' must have less than 16 bytes */ + if (v6stat.total == 16) + return 0; + /* More than three zeroes is an error */ + if (v6stat.zero_cnt > 3) + return 0; + /* Can only have three zeroes if nothing else present */ + else if (v6stat.zero_cnt == 3) { + if (v6stat.total > 0) + return 0; + } + /* Can only have two zeroes if at start or end */ + else if (v6stat.zero_cnt == 2) { + if ((v6stat.zero_pos != 0) && + (v6stat.zero_pos != v6stat.total)) + return 0; + } else + /* Can only have one zero if *not* start or end */ + { + if ((v6stat.zero_pos == 0) || + (v6stat.zero_pos == v6stat.total)) + return 0; + } + } + + /* Format result */ + + if (v6stat.zero_pos >= 0) { + /* Copy initial part */ + memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + memcpy(v6, v6stat.tmp, 16); + + return 1; +} + +static int +ipv6_cb(const char *elem, int len, void *usr) +{ + IPV6_STAT *s = usr; + + /* Error if 16 bytes written */ + if (s->total == 16) + return 0; + if (len == 0) { + /* Zero length element, corresponds to '::' */ + if (s->zero_pos == -1) + s->zero_pos = s->total; + /* If we've already got a :: its an error */ + else if (s->zero_pos != s->total) + return 0; + s->zero_cnt++; + } else { + /* If more than 4 characters could be final a.b.c.d form */ + if (len > 4) { + /* Need at least 4 bytes left */ + if (s->total > 12) + return 0; + /* Must be end of string */ + if (elem[len]) + return 0; + if (!ipv4_from_asc(s->tmp + s->total, elem)) + return 0; + s->total += 4; + } else { + if (!ipv6_hex(s->tmp + s->total, elem, len)) + return 0; + s->total += 2; + } + } + return 1; +} + +/* Convert a string of up to 4 hex digits into the corresponding + * IPv6 form. + */ + +static int +ipv6_hex(unsigned char *out, const char *in, int inlen) +{ + unsigned char c; + unsigned int num = 0; + + if (inlen > 4) + return 0; + while (inlen--) { + c = *in++; + num <<= 4; + if ((c >= '0') && (c <= '9')) + num |= c - '0'; + else if ((c >= 'A') && (c <= 'F')) + num |= c - 'A' + 10; + else if ((c >= 'a') && (c <= 'f')) + num |= c - 'a' + 10; + else + return 0; + } + out[0] = num >> 8; + out[1] = num & 0xff; + return 1; +} + +int +X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, + unsigned long chtype) +{ + CONF_VALUE *v; + int i, mval; + char *p, *type; + + if (!nm) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + v = sk_CONF_VALUE_value(dn_sk, i); + type = v->name; + /* Skip past any leading X. X: X, etc to allow for + * multiple instances + */ + for (p = type; *p; p++) + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*type == '+') { + mval = -1; + type++; + } else + mval = 0; + if (!X509_NAME_add_entry_by_txt(nm, type, chtype, + (unsigned char *) v->value, -1, -1, mval)) + return 0; + } + return 1; +} +LCRYPTO_ALIAS(X509V3_NAME_from_section); diff --git a/Libraries/libressl/crypto/x509/x509_v3.c b/Libraries/libressl/crypto/x509/x509_v3.c new file mode 100644 index 000000000..8dddb463c --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_v3.c @@ -0,0 +1,315 @@ +/* $OpenBSD: x509_v3.c,v 1.21 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "x509_local.h" + +int +X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) +{ + if (x == NULL) + return (0); + return (sk_X509_EXTENSION_num(x)); +} +LCRYPTO_ALIAS(X509v3_get_ext_count); + +int +X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); +} +LCRYPTO_ALIAS(X509v3_get_ext_by_NID); + +int +X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, + const ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} +LCRYPTO_ALIAS(X509v3_get_ext_by_OBJ); + +int +X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, + int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (((ex->critical > 0) && crit) || + ((ex->critical <= 0) && !crit)) + return (lastpos); + } + return (-1); +} +LCRYPTO_ALIAS(X509v3_get_ext_by_critical); + +X509_EXTENSION * +X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) +{ + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_EXTENSION_value(x, loc); +} +LCRYPTO_ALIAS(X509v3_get_ext); + +X509_EXTENSION * +X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) +{ + X509_EXTENSION *ret; + + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_EXTENSION_delete(x, loc); + return (ret); +} +LCRYPTO_ALIAS(X509v3_delete_ext); + +STACK_OF(X509_EXTENSION) * +X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc) +{ + X509_EXTENSION *new_ex = NULL; + int n; + STACK_OF(X509_EXTENSION) *sk = NULL; + + if (x == NULL) { + X509error(ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) + goto err; + } else + sk= *x; + + n = sk_X509_EXTENSION_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) + goto err2; + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + +err: + X509error(ERR_R_MALLOC_FAILURE); +err2: + if (new_ex != NULL) + X509_EXTENSION_free(new_ex); + if (sk != NULL && (x != NULL && sk != *x)) + sk_X509_EXTENSION_free(sk); + return (NULL); +} +LCRYPTO_ALIAS(X509v3_add_ext); + +X509_EXTENSION * +X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit, + ASN1_OCTET_STRING *data) +{ + ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509error(X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} +LCRYPTO_ALIAS(X509_EXTENSION_create_by_NID); + +X509_EXTENSION * +X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, const ASN1_OBJECT *obj, + int crit, ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret= *ex; + + if (!X509_EXTENSION_set_object(ret, obj)) + goto err; + if (!X509_EXTENSION_set_critical(ret, crit)) + goto err; + if (!X509_EXTENSION_set_data(ret, data)) + goto err; + + if ((ex != NULL) && (*ex == NULL)) + *ex = ret; + return (ret); + +err: + if ((ex == NULL) || (ret != *ex)) + X509_EXTENSION_free(ret); + return (NULL); +} +LCRYPTO_ALIAS(X509_EXTENSION_create_by_OBJ); + +int +X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return ex->object != NULL; +} +LCRYPTO_ALIAS(X509_EXTENSION_set_object); + +int +X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) +{ + if (ex == NULL) + return (0); + ex->critical = (crit) ? 0xFF : -1; + return (1); +} +LCRYPTO_ALIAS(X509_EXTENSION_set_critical); + +int +X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) +{ + int i; + + if (ex == NULL) + return (0); + i = ASN1_STRING_set(ex->value, data->data, data->length); + if (!i) + return (0); + return (1); +} +LCRYPTO_ALIAS(X509_EXTENSION_set_data); + +ASN1_OBJECT * +X509_EXTENSION_get_object(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->object); +} +LCRYPTO_ALIAS(X509_EXTENSION_get_object); + +ASN1_OCTET_STRING * +X509_EXTENSION_get_data(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->value); +} +LCRYPTO_ALIAS(X509_EXTENSION_get_data); + +int +X509_EXTENSION_get_critical(const X509_EXTENSION *ex) +{ + if (ex == NULL) + return (0); + if (ex->critical > 0) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_EXTENSION_get_critical); diff --git a/Libraries/libressl/crypto/x509/x509_verify.c b/Libraries/libressl/crypto/x509/x509_verify.c new file mode 100644 index 000000000..ca4814d93 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_verify.c @@ -0,0 +1,1282 @@ +/* $OpenBSD: x509_verify.c,v 1.66 2023/05/07 07:11:50 tb Exp $ */ +/* + * Copyright (c) 2020-2021 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* x509_verify - inspired by golang's crypto/x509.Verify */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "x509_internal.h" +#include "x509_issuer_cache.h" + +static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, + struct x509_verify_chain *current_chain); +static int x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, + char *name); +static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, + struct x509_verify_chain *current_chain, int full_chain, char *name); +static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, + size_t depth, int error, int ok); +static void x509_verify_chain_free(struct x509_verify_chain *chain); + +/* + * Parse an asn1 to a representable time_t as per RFC 5280 rules. + * Returns -1 if that can't be done for any reason. + */ +time_t +x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter) +{ + struct tm tm = { 0 }; + int type; + + type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type); + if (type == -1) + return -1; + + /* RFC 5280 section 4.1.2.5 */ + if (tm.tm_year < 150 && type != V_ASN1_UTCTIME) + return -1; + if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) + return -1; + + if (notAfter) { + /* + * If we are a completely broken operating system with a + * 32 bit time_t, and we have been told this is a notAfter + * date, limit the date to a 32 bit representable value. + */ + if (!ASN1_time_tm_clamp_notafter(&tm)) + return -1; + } + + /* + * Defensively fail if the time string is not representable as + * a time_t. A time_t must be sane if you care about times after + * Jan 19 2038. + */ + return timegm(&tm); +} + +/* + * Cache certificate hash, and values parsed out of an X509. + * called from cache_extensions() + */ +void +x509_verify_cert_info_populate(X509 *cert) +{ + /* + * Parse and save the cert times, or remember that they + * are unacceptable/unparsable. + */ + cert->not_before = x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0); + cert->not_after = x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1); +} + +struct x509_verify_chain * +x509_verify_chain_new(void) +{ + struct x509_verify_chain *chain; + + if ((chain = calloc(1, sizeof(*chain))) == NULL) + goto err; + if ((chain->certs = sk_X509_new_null()) == NULL) + goto err; + if ((chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS, + sizeof(int))) == NULL) + goto err; + if ((chain->names = + x509_constraints_names_new(X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) + goto err; + + return chain; + err: + x509_verify_chain_free(chain); + return NULL; +} + +static void +x509_verify_chain_clear(struct x509_verify_chain *chain) +{ + sk_X509_pop_free(chain->certs, X509_free); + chain->certs = NULL; + free(chain->cert_errors); + chain->cert_errors = NULL; + x509_constraints_names_free(chain->names); + chain->names = NULL; +} + +static void +x509_verify_chain_free(struct x509_verify_chain *chain) +{ + if (chain == NULL) + return; + x509_verify_chain_clear(chain); + free(chain); +} + +static struct x509_verify_chain * +x509_verify_chain_dup(struct x509_verify_chain *chain) +{ + struct x509_verify_chain *new_chain; + + if ((new_chain = calloc(1, sizeof(*chain))) == NULL) + goto err; + if ((new_chain->certs = X509_chain_up_ref(chain->certs)) == NULL) + goto err; + if ((new_chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS, + sizeof(int))) == NULL) + goto err; + memcpy(new_chain->cert_errors, chain->cert_errors, + X509_VERIFY_MAX_CHAIN_CERTS * sizeof(int)); + if ((new_chain->names = + x509_constraints_names_dup(chain->names)) == NULL) + goto err; + return(new_chain); + err: + x509_verify_chain_free(new_chain); + return NULL; +} + +static int +x509_verify_chain_append(struct x509_verify_chain *chain, X509 *cert, + int *error) +{ + int verify_err = X509_V_ERR_UNSPECIFIED; + size_t idx; + + if (!x509_constraints_extract_names(chain->names, cert, + sk_X509_num(chain->certs) == 0, &verify_err)) { + *error = verify_err; + return 0; + } + + X509_up_ref(cert); + if (!sk_X509_push(chain->certs, cert)) { + X509_free(cert); + *error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + + idx = sk_X509_num(chain->certs) - 1; + chain->cert_errors[idx] = *error; + + /* + * We've just added the issuer for the previous certificate, + * clear its error if appropriate. + */ + if (idx > 1 && chain->cert_errors[idx - 1] == + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) + chain->cert_errors[idx - 1] = X509_V_OK; + + return 1; +} + +static X509 * +x509_verify_chain_last(struct x509_verify_chain *chain) +{ + int last; + + if (chain->certs == NULL) + return NULL; + if ((last = sk_X509_num(chain->certs) - 1) < 0) + return NULL; + return sk_X509_value(chain->certs, last); +} + +X509 * +x509_verify_chain_leaf(struct x509_verify_chain *chain) +{ + if (chain->certs == NULL) + return NULL; + return sk_X509_value(chain->certs, 0); +} + +static void +x509_verify_ctx_reset(struct x509_verify_ctx *ctx) +{ + size_t i; + + for (i = 0; i < ctx->chains_count; i++) + x509_verify_chain_free(ctx->chains[i]); + sk_X509_pop_free(ctx->saved_error_chain, X509_free); + ctx->saved_error = 0; + ctx->saved_error_depth = 0; + ctx->error = 0; + ctx->error_depth = 0; + ctx->chains_count = 0; + ctx->sig_checks = 0; + ctx->check_time = NULL; +} + +static void +x509_verify_ctx_clear(struct x509_verify_ctx *ctx) +{ + x509_verify_ctx_reset(ctx); + sk_X509_pop_free(ctx->intermediates, X509_free); + free(ctx->chains); + +} + +static int +x509_verify_cert_cache_extensions(X509 *cert) +{ + return x509v3_cache_extensions(cert); +} + +static int +x509_verify_cert_self_signed(X509 *cert) +{ + return (cert->ex_flags & EXFLAG_SS) ? 1 : 0; +} + +/* XXX beck - clean up this mess of is_root */ +static int +x509_verify_check_chain_end(X509 *cert, int full_chain) +{ + if (full_chain) + return x509_verify_cert_self_signed(cert); + return 1; +} + +static int +x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert, + int full_chain) +{ + X509 *match = NULL; + int i; + + if (!x509_verify_cert_cache_extensions(cert)) + return 0; + + /* Check by lookup if we have a legacy xsc */ + if (ctx->xsc != NULL) { + if ((match = x509_vfy_lookup_cert_match(ctx->xsc, + cert)) != NULL) { + X509_free(match); + return x509_verify_check_chain_end(cert, full_chain); + } + } else { + /* Check the provided roots */ + for (i = 0; i < sk_X509_num(ctx->roots); i++) { + if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0) + return x509_verify_check_chain_end(cert, + full_chain); + } + } + + return 0; +} + +static int +x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx, + struct x509_verify_chain *chain, int set_error, int is_trusted) +{ + size_t num_untrusted; + int i; + + if (ctx->xsc == NULL) + return 1; + + /* + * XXX num_untrusted is the number of untrusted certs at the + * bottom of the chain. This works now since we stop at the first + * trusted cert. This will need fixing once we allow more than one + * trusted certificate. + */ + num_untrusted = sk_X509_num(chain->certs); + if (is_trusted && num_untrusted > 0) + num_untrusted--; + ctx->xsc->num_untrusted = num_untrusted; + + sk_X509_pop_free(ctx->xsc->chain, X509_free); + ctx->xsc->chain = X509_chain_up_ref(chain->certs); + if (ctx->xsc->chain == NULL) + return x509_verify_cert_error(ctx, NULL, 0, + X509_V_ERR_OUT_OF_MEM, 0); + + if (set_error) { + ctx->xsc->error = X509_V_OK; + ctx->xsc->error_depth = 0; + for (i = 0; i < sk_X509_num(chain->certs); i++) { + if (chain->cert_errors[i] != X509_V_OK) { + ctx->xsc->error = chain->cert_errors[i]; + ctx->xsc->error_depth = i; + break; + } + } + } + + return 1; +} + + +/* + * Save the error state and unvalidated chain off of the xsc for + * later. + */ +static int +x509_verify_ctx_save_xsc_error(struct x509_verify_ctx *ctx) +{ + if (ctx->xsc != NULL && ctx->xsc->chain != NULL) { + sk_X509_pop_free(ctx->saved_error_chain, X509_free); + ctx->saved_error_chain = X509_chain_up_ref(ctx->xsc->chain); + if (ctx->saved_error_chain == NULL) + return x509_verify_cert_error(ctx, NULL, 0, + X509_V_ERR_OUT_OF_MEM, 0); + ctx->saved_error = ctx->xsc->error; + ctx->saved_error_depth = ctx->xsc->error_depth; + } + return 1; +} + +/* + * Restore the saved error state and unvalidated chain to the xsc + * if we do not have a validated chain. + */ +static int +x509_verify_ctx_restore_xsc_error(struct x509_verify_ctx *ctx) +{ + if (ctx->xsc != NULL && ctx->chains_count == 0 && + ctx->saved_error_chain != NULL) { + sk_X509_pop_free(ctx->xsc->chain, X509_free); + ctx->xsc->chain = X509_chain_up_ref(ctx->saved_error_chain); + if (ctx->xsc->chain == NULL) + return x509_verify_cert_error(ctx, NULL, 0, + X509_V_ERR_OUT_OF_MEM, 0); + ctx->xsc->error = ctx->saved_error; + ctx->xsc->error_depth = ctx->saved_error_depth; + } + return 1; +} + +/* Perform legacy style validation of a chain */ +static int +x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx, + struct x509_verify_chain *chain, size_t depth) +{ + int ret = 0, trust; + + if (ctx->xsc == NULL) + return 1; + + /* + * If we have a legacy xsc, choose a validated chain, and + * apply the extensions, revocation, and policy checks just + * like the legacy code did. We do this here instead of as + * building the chains to more easily support the callback and + * the bewildering array of VERIFY_PARAM knobs that are there + * for the fiddling. + */ + + /* These may be set in one of the following calls. */ + ctx->xsc->error = X509_V_OK; + ctx->xsc->error_depth = 0; + + if (!x509_verify_ctx_set_xsc_chain(ctx, chain, 0, 1)) + goto err; + + /* + * Call the legacy code to walk the chain and check trust + * in the legacy way to handle partial chains and get the + * callback fired correctly. + */ + trust = x509_vfy_check_trust(ctx->xsc); + if (trust == X509_TRUST_REJECTED) + goto err; /* callback was called in x509_vfy_check_trust */ + if (trust != X509_TRUST_TRUSTED) { + /* NOTREACHED */ + goto err; /* should not happen if we get in here - abort? */ + } + + /* + * XXX currently this duplicates some work done in chain + * build, but we keep it here until we have feature parity + */ + if (!x509_vfy_check_chain_extensions(ctx->xsc)) + goto err; + +#ifndef OPENSSL_NO_RFC3779 + if (!X509v3_asid_validate_path(ctx->xsc)) + goto err; + + if (!X509v3_addr_validate_path(ctx->xsc)) + goto err; +#endif + + if (!x509_vfy_check_security_level(ctx->xsc)) + goto err; + + if (!x509_constraints_chain(ctx->xsc->chain, + &ctx->xsc->error, &ctx->xsc->error_depth)) { + X509 *cert = sk_X509_value(ctx->xsc->chain, depth); + if (!x509_verify_cert_error(ctx, cert, + ctx->xsc->error_depth, ctx->xsc->error, 0)) + goto err; + } + + if (!x509_vfy_check_revocation(ctx->xsc)) + goto err; + + if (!x509_vfy_check_policy(ctx->xsc)) + goto err; + + ret = 1; + + err: + /* + * The above checks may have set ctx->xsc->error and + * ctx->xsc->error_depth - save these for later on. + */ + if (ctx->xsc->error != X509_V_OK) { + if (ctx->xsc->error_depth < 0 || + ctx->xsc->error_depth >= X509_VERIFY_MAX_CHAIN_CERTS) + return 0; + chain->cert_errors[ctx->xsc->error_depth] = + ctx->xsc->error; + ctx->error_depth = ctx->xsc->error_depth; + } + + return ret; +} + +/* Add a validated chain to our list of valid chains */ +static int +x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, + struct x509_verify_chain *chain, char *name) +{ + size_t depth; + X509 *last = x509_verify_chain_last(chain); + X509 *leaf = x509_verify_chain_leaf(chain); + + depth = sk_X509_num(chain->certs); + if (depth > 0) + depth--; + + if (ctx->chains_count >= ctx->max_chains) + return x509_verify_cert_error(ctx, last, depth, + X509_V_ERR_CERT_CHAIN_TOO_LONG, 0); + + /* Clear a get issuer failure for a root certificate. */ + if (chain->cert_errors[depth] == + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) + chain->cert_errors[depth] = X509_V_OK; + + if (!x509_verify_ctx_validate_legacy_chain(ctx, chain, depth)) + return 0; + + /* Verify the leaf certificate and store any resulting error. */ + if (!x509_verify_cert_valid(ctx, leaf, NULL)) + return 0; + if (!x509_verify_cert_hostname(ctx, leaf, name)) + return 0; + if (ctx->error_depth == 0 && + ctx->error != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) + chain->cert_errors[0] = ctx->error; + + /* + * In the non-legacy code, extensions and purpose are dealt + * with as the chain is built. + * + * The non-legacy api returns multiple chains but does not do + * any revocation checking (it must be done by the caller on + * any chain they wish to use) + */ + + if ((ctx->chains[ctx->chains_count] = x509_verify_chain_dup(chain)) == + NULL) { + return x509_verify_cert_error(ctx, last, depth, + X509_V_ERR_OUT_OF_MEM, 0); + } + ctx->chains_count++; + + ctx->error = X509_V_OK; + ctx->error_depth = depth; + + return 1; +} + +static int +x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent, + X509 *child) +{ + if (!x509_verify_cert_cache_extensions(parent)) + return 0; + if (ctx->xsc != NULL) + return (ctx->xsc->check_issued(ctx->xsc, child, parent)); + + /* XXX key usage */ + return X509_check_issued(child, parent) != X509_V_OK; +} + +static int +x509_verify_parent_signature(X509 *parent, X509 *child, int *error) +{ + EVP_PKEY *pkey; + int cached; + int ret = 0; + + /* Use cached value if we have it */ + if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0) + return cached; + + /* Check signature. Did parent sign child? */ + if ((pkey = X509_get_pubkey(parent)) == NULL) { + *error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + return 0; + } + if (X509_verify(child, pkey) <= 0) + *error = X509_V_ERR_CERT_SIGNATURE_FAILURE; + else + ret = 1; + + /* Add result to cache */ + x509_issuer_cache_add(parent->hash, child->hash, ret); + + EVP_PKEY_free(pkey); + + return ret; +} + +static int +x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, + int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain, + int full_chain, char *name) +{ + int depth = sk_X509_num(current_chain->certs); + struct x509_verify_chain *new_chain; + int i; + + /* Fail if the certificate is already in the chain */ + for (i = 0; i < sk_X509_num(current_chain->certs); i++) { + if (X509_cmp(sk_X509_value(current_chain->certs, i), + candidate) == 0) + return 0; + } + + if (ctx->sig_checks++ > X509_VERIFY_MAX_SIGCHECKS) { + /* don't allow callback to override safety check */ + (void) x509_verify_cert_error(ctx, candidate, depth, + X509_V_ERR_CERT_CHAIN_TOO_LONG, 0); + return 0; + } + + if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) { + if (!x509_verify_cert_error(ctx, candidate, depth, + ctx->error, 0)) + return 0; + } + + if (!x509_verify_cert_valid(ctx, candidate, current_chain)) + return 0; + + /* candidate is good, add it to a copy of the current chain */ + if ((new_chain = x509_verify_chain_dup(current_chain)) == NULL) { + x509_verify_cert_error(ctx, candidate, depth, + X509_V_ERR_OUT_OF_MEM, 0); + return 0; + } + if (!x509_verify_chain_append(new_chain, candidate, &ctx->error)) { + x509_verify_cert_error(ctx, candidate, depth, ctx->error, 0); + x509_verify_chain_free(new_chain); + return 0; + } + + /* + * If candidate is a trusted root, we have a validated chain, + * so we save it. Otherwise, recurse until we find a root or + * give up. + */ + if (is_root_cert) { + if (!x509_verify_ctx_set_xsc_chain(ctx, new_chain, 0, 1)) { + x509_verify_chain_free(new_chain); + return 0; + } + if (!x509_verify_ctx_add_chain(ctx, new_chain, name)) { + x509_verify_chain_free(new_chain); + return 0; + } + goto done; + } + + x509_verify_build_chains(ctx, candidate, new_chain, full_chain, name); + + done: + x509_verify_chain_free(new_chain); + return 1; +} + +static int +x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth, + int error, int ok) +{ + ctx->error = error; + ctx->error_depth = depth; + if (ctx->xsc != NULL) { + ctx->xsc->error = error; + ctx->xsc->error_depth = depth; + ctx->xsc->current_cert = cert; + return ctx->xsc->verify_cb(ok, ctx->xsc); + } + return ok; +} + +static void +x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, + struct x509_verify_chain *current_chain, int full_chain, char *name) +{ + X509 *candidate; + int i, depth, count, ret, is_root; + + /* + * If we are finding chains with an xsc, just stop after we have + * one chain, there's no point in finding more, it just exercises + * the potentially buggy callback processing in the calling software. + */ + if (ctx->xsc != NULL && ctx->chains_count > 0) + return; + + depth = sk_X509_num(current_chain->certs); + if (depth > 0) + depth--; + + if (depth >= ctx->max_depth && + !x509_verify_cert_error(ctx, cert, depth, + X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) + return; + + count = ctx->chains_count; + + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + ctx->error_depth = depth; + + if (ctx->saved_error != 0) + ctx->error = ctx->saved_error; + if (ctx->saved_error_depth != 0) + ctx->error_depth = ctx->saved_error_depth; + + if (ctx->xsc != NULL) { + /* + * Long ago experiments at Muppet labs resulted in a + * situation where software not only sees these errors + * but forced developers to expect them in certain cases. + * so we must mimic this awfulness for the legacy case. + */ + if (cert->ex_flags & EXFLAG_SS) + ctx->error = (depth == 0) ? + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + } + + /* Check for legacy mode roots */ + if (ctx->xsc != NULL) { + if ((ret = ctx->xsc->get_issuer(&candidate, ctx->xsc, cert)) < 0) { + x509_verify_cert_error(ctx, cert, depth, + X509_V_ERR_STORE_LOOKUP, 0); + return; + } + if (ret > 0) { + if (x509_verify_potential_parent(ctx, candidate, cert)) { + is_root = x509_verify_check_chain_end(candidate, + full_chain); + x509_verify_consider_candidate(ctx, cert, + is_root, candidate, current_chain, + full_chain, name); + } + X509_free(candidate); + } + } else { + /* Check to see if we have a trusted root issuer. */ + for (i = 0; i < sk_X509_num(ctx->roots); i++) { + candidate = sk_X509_value(ctx->roots, i); + if (x509_verify_potential_parent(ctx, candidate, cert)) { + is_root = x509_verify_check_chain_end(candidate, + full_chain); + x509_verify_consider_candidate(ctx, cert, + is_root, candidate, current_chain, + full_chain, name); + } + } + } + + /* Check intermediates after checking roots */ + if (ctx->intermediates != NULL) { + for (i = 0; i < sk_X509_num(ctx->intermediates); i++) { + candidate = sk_X509_value(ctx->intermediates, i); + if (x509_verify_potential_parent(ctx, candidate, cert)) { + x509_verify_consider_candidate(ctx, cert, + 0, candidate, current_chain, + full_chain, name); + } + } + } + + if (ctx->chains_count > count) { + if (ctx->xsc != NULL) { + ctx->xsc->error = X509_V_OK; + ctx->xsc->error_depth = depth; + ctx->xsc->current_cert = cert; + } + } else if (ctx->error_depth == depth) { + if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0)) + return; + } +} + +static int +x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, char *name) +{ + char *candidate; + size_t len; + + if (name == NULL) { + if (ctx->xsc != NULL) { + int ret; + + if ((ret = x509_vfy_check_id(ctx->xsc)) == 0) + ctx->error = ctx->xsc->error; + return ret; + } + return 1; + } + if ((candidate = strdup(name)) == NULL) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if ((len = strlen(candidate)) < 1) { + ctx->error = X509_V_ERR_UNSPECIFIED; /* XXX */ + goto err; + } + + /* IP addresses may be written in [ ]. */ + if (candidate[0] == '[' && candidate[len - 1] == ']') { + candidate[len - 1] = '\0'; + if (X509_check_ip_asc(cert, candidate + 1, 0) <= 0) { + ctx->error = X509_V_ERR_IP_ADDRESS_MISMATCH; + goto err; + } + } else { + int flags = 0; + + if (ctx->xsc == NULL) + flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; + + if (X509_check_host(cert, candidate, len, flags, NULL) <= 0) { + ctx->error = X509_V_ERR_HOSTNAME_MISMATCH; + goto err; + } + } + free(candidate); + return 1; + err: + free(candidate); + return x509_verify_cert_error(ctx, cert, 0, ctx->error, 0); +} + +static int +x509_verify_set_check_time(struct x509_verify_ctx *ctx) +{ + if (ctx->xsc != NULL) { + if (ctx->xsc->param->flags & X509_V_FLAG_USE_CHECK_TIME) { + ctx->check_time = &ctx->xsc->param->check_time; + return 1; + } + if (ctx->xsc->param->flags & X509_V_FLAG_NO_CHECK_TIME) + return 0; + } + + ctx->check_time = NULL; + return 1; +} + +static int +x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error) +{ + time_t when; + + if (cmp_time == NULL) + when = time(NULL); + else + when = *cmp_time; + + if (cert->not_before == -1) { + *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + return 0; + } + if (when < cert->not_before) { + *error = X509_V_ERR_CERT_NOT_YET_VALID; + return 0; + } + if (cert->not_after == -1) { + *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + return 0; + } + if (when > cert->not_after) { + *error = X509_V_ERR_CERT_HAS_EXPIRED; + return 0; + } + + return 1; +} + +static int +x509_verify_validate_constraints(X509 *cert, + struct x509_verify_chain *current_chain, int *error) +{ + struct x509_constraints_names *excluded = NULL; + struct x509_constraints_names *permitted = NULL; + int err = X509_V_ERR_UNSPECIFIED; + + if (current_chain == NULL) + return 1; + + if (cert->nc != NULL) { + if ((permitted = x509_constraints_names_new( + X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { + err = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if ((excluded = x509_constraints_names_new( + X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { + err = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!x509_constraints_extract_constraints(cert, + permitted, excluded, &err)) + goto err; + if (!x509_constraints_check(current_chain->names, + permitted, excluded, &err)) + goto err; + x509_constraints_names_free(excluded); + x509_constraints_names_free(permitted); + } + + return 1; + err: + *error = err; + x509_constraints_names_free(excluded); + x509_constraints_names_free(permitted); + return 0; +} + +static int +x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca) +{ + if (!x509_verify_cert_cache_extensions(cert)) { + ctx->error = X509_V_ERR_UNSPECIFIED; + return 0; + } + + if (ctx->xsc != NULL) + return 1; /* legacy is checked after chain is built */ + + if (cert->ex_flags & EXFLAG_CRITICAL) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + return 0; + } + /* No we don't care about v1, netscape, and other ancient silliness */ + if (need_ca && (!(cert->ex_flags & EXFLAG_BCONS) && + (cert->ex_flags & EXFLAG_CA))) { + ctx->error = X509_V_ERR_INVALID_CA; + return 0; + } + if (ctx->purpose > 0 && X509_check_purpose(cert, ctx->purpose, need_ca)) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + return 0; + } + + return 1; +} + +/* Validate that cert is a possible candidate to append to current_chain */ +static int +x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, + struct x509_verify_chain *current_chain) +{ + X509 *issuer_candidate; + int should_be_ca = current_chain != NULL; + size_t depth = 0; + + if (current_chain != NULL) + depth = sk_X509_num(current_chain->certs); + + if (!x509_verify_cert_extensions(ctx, cert, should_be_ca)) + return 0; + + if (should_be_ca) { + issuer_candidate = x509_verify_chain_last(current_chain); + if (issuer_candidate != NULL && + !X509_check_issued(issuer_candidate, cert)) + if (!x509_verify_cert_error(ctx, cert, depth, + X509_V_ERR_SUBJECT_ISSUER_MISMATCH, 0)) + return 0; + } + + if (x509_verify_set_check_time(ctx)) { + if (!x509_verify_cert_times(cert, ctx->check_time, + &ctx->error)) { + if (!x509_verify_cert_error(ctx, cert, depth, + ctx->error, 0)) + return 0; + } + } + + if (!x509_verify_validate_constraints(cert, current_chain, + &ctx->error) && !x509_verify_cert_error(ctx, cert, depth, + ctx->error, 0)) + return 0; + + return 1; +} + +struct x509_verify_ctx * +x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc) +{ + struct x509_verify_ctx *ctx; + size_t max_depth; + + if (xsc == NULL) + return NULL; + + if ((ctx = x509_verify_ctx_new(NULL)) == NULL) + return NULL; + + ctx->xsc = xsc; + + if (xsc->untrusted && + (ctx->intermediates = X509_chain_up_ref(xsc->untrusted)) == NULL) + goto err; + + max_depth = X509_VERIFY_MAX_CHAIN_CERTS; + if (xsc->param->depth > 0 && xsc->param->depth < X509_VERIFY_MAX_CHAIN_CERTS) + max_depth = xsc->param->depth; + if (!x509_verify_ctx_set_max_depth(ctx, max_depth)) + goto err; + + return ctx; + err: + x509_verify_ctx_free(ctx); + return NULL; +} + +/* Public API */ + +struct x509_verify_ctx * +x509_verify_ctx_new(STACK_OF(X509) *roots) +{ + struct x509_verify_ctx *ctx; + + if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL) + return NULL; + + if (roots != NULL) { + if ((ctx->roots = X509_chain_up_ref(roots)) == NULL) + goto err; + } else { + if ((ctx->roots = sk_X509_new_null()) == NULL) + goto err; + } + + ctx->max_depth = X509_VERIFY_MAX_CHAIN_CERTS; + ctx->max_chains = X509_VERIFY_MAX_CHAINS; + ctx->max_sigs = X509_VERIFY_MAX_SIGCHECKS; + + if ((ctx->chains = calloc(X509_VERIFY_MAX_CHAINS, + sizeof(*ctx->chains))) == NULL) + goto err; + + return ctx; + err: + x509_verify_ctx_free(ctx); + return NULL; +} + +void +x509_verify_ctx_free(struct x509_verify_ctx *ctx) +{ + if (ctx == NULL) + return; + sk_X509_pop_free(ctx->roots, X509_free); + x509_verify_ctx_clear(ctx); + free(ctx); +} + +int +x509_verify_ctx_set_max_depth(struct x509_verify_ctx *ctx, size_t max) +{ + if (max < 1 || max > X509_VERIFY_MAX_CHAIN_CERTS) + return 0; + ctx->max_depth = max; + return 1; +} + +int +x509_verify_ctx_set_max_chains(struct x509_verify_ctx *ctx, size_t max) +{ + if (max < 1 || max > X509_VERIFY_MAX_CHAINS) + return 0; + ctx->max_chains = max; + return 1; +} + +int +x509_verify_ctx_set_max_signatures(struct x509_verify_ctx *ctx, size_t max) +{ + if (max < 1 || max > 100000) + return 0; + ctx->max_sigs = max; + return 1; +} + +int +x509_verify_ctx_set_purpose(struct x509_verify_ctx *ctx, int purpose) +{ + if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) + return 0; + ctx->purpose = purpose; + return 1; +} + +int +x509_verify_ctx_set_intermediates(struct x509_verify_ctx *ctx, + STACK_OF(X509) *intermediates) +{ + if ((ctx->intermediates = X509_chain_up_ref(intermediates)) == NULL) + return 0; + return 1; +} + +const char * +x509_verify_ctx_error_string(struct x509_verify_ctx *ctx) +{ + return X509_verify_cert_error_string(ctx->error); +} + +size_t +x509_verify_ctx_error_depth(struct x509_verify_ctx *ctx) +{ + return ctx->error_depth; +} + +STACK_OF(X509) * +x509_verify_ctx_chain(struct x509_verify_ctx *ctx, size_t i) +{ + if (i >= ctx->chains_count) + return NULL; + return ctx->chains[i]->certs; +} + +size_t +x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name) +{ + struct x509_verify_chain *current_chain; + int retry_chain_build, full_chain = 0; + + if (ctx->roots == NULL || ctx->max_depth == 0) { + ctx->error = X509_V_ERR_INVALID_CALL; + goto err; + } + + if (ctx->xsc != NULL) { + if (leaf != NULL || name != NULL) { + ctx->error = X509_V_ERR_INVALID_CALL; + goto err; + } + leaf = ctx->xsc->cert; + + /* XXX */ + full_chain = 1; + if (ctx->xsc->param->flags & X509_V_FLAG_PARTIAL_CHAIN) + full_chain = 0; + /* + * XXX + * The legacy code expects the top level cert to be + * there, even if we didn't find a chain. So put it + * there, we will clobber it later if we find a valid + * chain. + */ + if ((ctx->xsc->chain = sk_X509_new_null()) == NULL) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!X509_up_ref(leaf)) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + if (!sk_X509_push(ctx->xsc->chain, leaf)) { + X509_free(leaf); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + ctx->xsc->error_depth = 0; + ctx->xsc->current_cert = leaf; + } + + if ((current_chain = x509_verify_chain_new()) == NULL) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto err; + } + + /* + * Add the leaf to the chain and try to build chains from it. + * Note that unlike Go's verifier, we have not yet checked + * anything about the leaf, This is intentional, so that we + * report failures in chain building before we report problems + * with the leaf. + */ + if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) { + x509_verify_chain_free(current_chain); + goto err; + } + do { + retry_chain_build = 0; + if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) { + if (!x509_verify_ctx_add_chain(ctx, current_chain, + name)) { + x509_verify_chain_free(current_chain); + goto err; + } + } else { + x509_verify_build_chains(ctx, leaf, current_chain, + full_chain, name); + if (full_chain && ctx->chains_count == 0) { + /* + * Save the error state from the xsc + * at this point to put back on the + * xsc in case we do not find a chain + * that is trusted but not a full + * chain to a self signed root. This + * is because the unvalidated chain is + * used by the autochain batshittery + * on failure and will be needed for + * that. + */ + ctx->xsc->error_depth = ctx->error_depth; + if (!x509_verify_ctx_save_xsc_error(ctx)) { + x509_verify_chain_free(current_chain); + goto err; + } + full_chain = 0; + retry_chain_build = 1; + } + } + } while (retry_chain_build); + + x509_verify_chain_free(current_chain); + + /* + * Do the new verifier style return, where we don't have an xsc + * that allows a crazy callback to turn invalid things into valid. + */ + if (ctx->xsc == NULL) { + /* + * Safety net: + * We could not find a validated chain, and for some reason do not + * have an error set. + */ + if (ctx->chains_count == 0 && ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + + /* + * If we are not using an xsc, and have no possibility for the + * crazy OpenSSL callback API changing the results of + * validation steps (because the callback can make validation + * proceed in the presence of invalid certs), any chains we + * have here are correctly built and verified. + */ + if (ctx->chains_count > 0) + ctx->error = X509_V_OK; + + return ctx->chains_count; + } + + /* + * Otherwise we are doing compatibility with an xsc, which means that we + * will have one chain, which might actually be a bogus chain because + * the callback told us to ignore errors and proceed to build an invalid + * chain. Possible return values from this include returning 1 with an + * invalid chain and a value of xsc->error != X509_V_OK (It's tradition + * that makes it ok). + */ + + if (ctx->chains_count > 0) { + /* + * The chain we have using an xsc might not be a verified chain + * if the callback perverted things while we built it to ignore + * failures and proceed with chain building. We put this chain + * and the error associated with it on the xsc. + */ + if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1, 1)) + goto err; + + /* + * Call the callback for completion up our built + * chain. The callback could still tell us to + * fail. Since this chain might exist as the result of + * callback doing perversions, we could still return + * "success" with something other than X509_V_OK set + * as the error. + */ + if (!x509_vfy_callback_indicate_completion(ctx->xsc)) + goto err; + } else { + /* + * We did not find a chain. Bring back the failure + * case we wanted to the xsc if we saved one. If we + * did not we should have just the leaf on the xsc. + */ + if (!x509_verify_ctx_restore_xsc_error(ctx)) + goto err; + + /* + * Safety net, ensure we have an error set in the + * failing case. + */ + if (ctx->xsc->error == X509_V_OK) { + if (ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + ctx->xsc->error = ctx->error; + } + + /* + * Let the callback override the return value + * at depth 0 if it chooses to + */ + return ctx->xsc->verify_cb(0, ctx->xsc); + } + + /* We only ever find one chain in compat mode with an xsc. */ + return 1; + + err: + if (ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + + if (ctx->xsc != NULL) { + if (ctx->xsc->error == X509_V_OK) + ctx->xsc->error = X509_V_ERR_UNSPECIFIED; + ctx->error = ctx->xsc->error; + } + + return 0; +} diff --git a/Libraries/libressl/crypto/x509/x509_verify.h b/Libraries/libressl/crypto/x509/x509_verify.h new file mode 100644 index 000000000..d8d2cb0b5 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_verify.h @@ -0,0 +1,43 @@ +/* $OpenBSD: x509_verify.h,v 1.2 2021/11/04 23:52:34 beck Exp $ */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef HEADER_X509_VERIFY_H +#define HEADER_X509_VERIFY_H + +#ifdef LIBRESSL_INTERNAL +struct x509_verify_ctx; +struct x509_verify_cert_info; +typedef struct x509_verify_ctx X509_VERIFY_CTX; + +X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); +void x509_verify_ctx_free(struct x509_verify_ctx *ctx); + +int x509_verify_ctx_set_max_depth(X509_VERIFY_CTX *ctx, size_t max); +int x509_verify_ctx_set_max_chains(X509_VERIFY_CTX *ctx, size_t max); +int x509_verify_ctx_set_max_signatures(X509_VERIFY_CTX *ctx, size_t max); +int x509_verify_ctx_set_purpose(X509_VERIFY_CTX *ctx, int purpose_id); +int x509_verify_ctx_set_intermediates(X509_VERIFY_CTX *ctx, + STACK_OF(X509) *intermediates); + +const char *x509_verify_ctx_error_string(X509_VERIFY_CTX *ctx); +size_t x509_verify_ctx_error_depth(X509_VERIFY_CTX *ctx); + +STACK_OF(X509) *x509_verify_ctx_chain(X509_VERIFY_CTX *ctx, size_t chain); + +size_t x509_verify(X509_VERIFY_CTX *ctx, X509 *leaf, char *name); +#endif + +#endif diff --git a/Libraries/libressl/crypto/x509/x509_vfy.c b/Libraries/libressl/crypto/x509/x509_vfy.c new file mode 100644 index 000000000..c4ba3d5b1 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_vfy.c @@ -0,0 +1,2719 @@ +/* $OpenBSD: x509_vfy.c,v 1.125 2023/06/08 22:02:40 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asn1_local.h" +#include "x509_internal.h" +#include "x509_local.h" + +/* CRL score values */ + +/* No unhandled critical extensions */ + +#define CRL_SCORE_NOCRITICAL 0x100 + +/* certificate is within CRL scope */ + +#define CRL_SCORE_SCOPE 0x080 + +/* CRL times valid */ + +#define CRL_SCORE_TIME 0x040 + +/* Issuer name matches certificate */ + +#define CRL_SCORE_ISSUER_NAME 0x020 + +/* If this score or above CRL is probably valid */ + +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) + +/* CRL issuer is certificate issuer */ + +#define CRL_SCORE_ISSUER_CERT 0x018 + +/* CRL issuer is on certificate path */ + +#define CRL_SCORE_SAME_PATH 0x008 + +/* CRL issuer matches CRL AKID */ + +#define CRL_SCORE_AKID 0x004 + +/* Have a delta CRL with valid times */ + +#define CRL_SCORE_TIME_DELTA 0x002 + +static int null_callback(int ok, X509_STORE_CTX *e); +static int check_issued(X509_STORE_CTX *ctx, X509 *subject, X509 *issuer); +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x, + int allow_expired); +static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_name_constraints(X509_STORE_CTX *ctx); +static int check_trust(X509_STORE_CTX *ctx); +static int check_revocation(X509_STORE_CTX *ctx); +static int check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth); +static int check_policy(X509_STORE_CTX *ctx); + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x); +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, + X509_CRL *base, STACK_OF(X509_CRL) *crls); +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score); +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons); +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); +static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path); +static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, + int clamp_notafter); + +static int internal_verify(X509_STORE_CTX *ctx); +static int get_trusted_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); +static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); +static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err); + +int ASN1_time_tm_clamp_notafter(struct tm *tm); + +static int +null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +/* Return 1 if a certificate is self signed */ +static int +cert_self_signed(X509 *x) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return 1; + else + return 0; +} + +static int +check_id_error(X509_STORE_CTX *ctx, int errcode) +{ + ctx->error = errcode; + ctx->current_cert = ctx->cert; + ctx->error_depth = 0; + return ctx->verify_cb(0, ctx); +} + +static int +check_hosts(X509 *x, X509_VERIFY_PARAM *vpm) +{ + int i, n; + char *name; + + n = sk_OPENSSL_STRING_num(vpm->hosts); + free(vpm->peername); + vpm->peername = NULL; + + for (i = 0; i < n; ++i) { + name = sk_OPENSSL_STRING_value(vpm->hosts, i); + if (X509_check_host(x, name, strlen(name), vpm->hostflags, + &vpm->peername) > 0) + return 1; + } + return n == 0; +} + +static int +check_id(X509_STORE_CTX *ctx) +{ + X509_VERIFY_PARAM *vpm = ctx->param; + X509 *x = ctx->cert; + + if (vpm->hosts && check_hosts(x, vpm) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) + return 0; + } + if (vpm->email != NULL && X509_check_email(x, vpm->email, vpm->emaillen, 0) + <= 0) { + if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) + return 0; + } + if (vpm->ip != NULL && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) + return 0; + } + return 1; +} + +int +x509_vfy_check_id(X509_STORE_CTX *ctx) { + return check_id(ctx); +} + +/* + * This is the effectively broken legacy OpenSSL chain builder. It + * might find an unvalidated chain and leave it sitting in + * ctx->chain. It does not correctly handle many cases where multiple + * chains could exist. + * + * Oh no.. I know a dirty word... + * Oooooooh.. + */ +static int +X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad, int *out_ok) +{ + X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int ok = 0, ret = 0; + int depth, i; + int num, j, retry, trust; + int (*cb) (int xok, X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp = NULL; + + cb = ctx->verify_cb; + + /* + * First we make sure the chain we are going to build is + * present and that the first entry is in place. + */ + ctx->chain = sk_X509_new_null(); + if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { + X509error(ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + X509_up_ref(ctx->cert); + ctx->num_untrusted = 1; + + /* We use a temporary STACK so we can chop and hack at it */ + if (ctx->untrusted != NULL && + (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + X509error(ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + + num = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, num - 1); + depth = param->depth; + + for (;;) { + /* If we have enough, we break */ + /* FIXME: If this happens, we should take + * note of it and, if appropriate, use the + * X509_V_ERR_CERT_CHAIN_TOO_LONG error code + * later. + */ + if (depth < num) + break; + /* If we are self signed, we break */ + if (cert_self_signed(x)) + break; + /* + * If asked see if we can find issuer in trusted store first + */ + if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + /* + * If successful for now free up cert so it + * will be picked up again later. + */ + if (ok > 0) { + X509_free(xtmp); + break; + } + } + /* If we were passed a cert chain, use it first */ + if (ctx->untrusted != NULL) { + /* + * If we do not find a non-expired untrusted cert, peek + * ahead and see if we can satisfy this from the trusted + * store. If not, see if we have an expired untrusted cert. + */ + xtmp = find_issuer(ctx, sktmp, x, 0); + if (xtmp == NULL && + !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)) { + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + if (ok > 0) { + X509_free(xtmp); + break; + } + xtmp = find_issuer(ctx, sktmp, x, 1); + } + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + X509error(ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + X509_up_ref(xtmp); + (void)sk_X509_delete_ptr(sktmp, xtmp); + ctx->num_untrusted++; + x = xtmp; + num++; + /* + * reparse the full chain for the next one + */ + continue; + } + } + break; + } + /* Remember how many untrusted certs we have */ + j = num; + + /* + * At this point, chain should contain a list of untrusted + * certificates. We now need to add at least one trusted one, + * if possible, otherwise we complain. + */ + + do { + /* + * Examine last certificate in chain and see if it is + * self signed. + */ + i = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, i - 1); + if (cert_self_signed(x)) { + /* we have a self signed certificate */ + if (i == 1) { + /* + * We have a single self signed + * certificate: see if we can find it + * in the store. We must have an exact + * match to avoid possible + * impersonation. + */ + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) { + ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert = x; + ctx->error_depth = i - 1; + if (ok == 1) + X509_free(xtmp); + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto end; + } else { + /* + * We have a match: replace + * certificate with store + * version so we get any trust + * settings. + */ + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->num_untrusted = 0; + } + } else { + /* + * extract and save self signed + * certificate for later use + */ + chain_ss = sk_X509_pop(ctx->chain); + ctx->num_untrusted--; + num--; + j--; + x = sk_X509_value(ctx->chain, num - 1); + } + } + /* We now lookup certs from the certificate store */ + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; + /* If we are self signed, we break */ + if (cert_self_signed(x)) + break; + ok = ctx->get_issuer(&xtmp, ctx, x); + + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + if (ok == 0) + break; + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + X509error(ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + num++; + } + + /* we now have our chain, lets check it... */ + trust = check_trust(ctx); + + /* If explicitly rejected error */ + if (trust == X509_TRUST_REJECTED) { + ok = 0; + goto end; + } + /* + * If it's not explicitly trusted then check if there + * is an alternative chain that could be used. We only + * do this if we haven't already checked via + * TRUSTED_FIRST and the user hasn't switched off + * alternate chain checking + */ + retry = 0; + if (trust != X509_TRUST_TRUSTED && + !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) && + !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { + while (j-- > 1) { + xtmp2 = sk_X509_value(ctx->chain, j - 1); + ok = ctx->get_issuer(&xtmp, ctx, xtmp2); + if (ok < 0) + goto end; + /* Check if we found an alternate chain */ + if (ok > 0) { + /* + * Free up the found cert + * we'll add it again later + */ + X509_free(xtmp); + /* + * Dump all the certs above + * this point - we've found an + * alternate chain + */ + while (num > j) { + xtmp = sk_X509_pop(ctx->chain); + X509_free(xtmp); + num--; + } + ctx->num_untrusted = sk_X509_num(ctx->chain); + retry = 1; + break; + } + } + } + } while (retry); + + /* + * If not explicitly trusted then indicate error unless it's a single + * self signed certificate in which case we've indicated an error already + * and set bad_chain == 1 + */ + if (trust != X509_TRUST_TRUSTED && !bad_chain) { + if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { + if (ctx->num_untrusted >= num) + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + else + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + ctx->current_cert = x; + } else { + if (!sk_X509_push(ctx->chain, chain_ss)) { + X509error(ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + num++; + ctx->num_untrusted = num; + ctx->current_cert = chain_ss; + ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss = NULL; + } + + ctx->error_depth = num - 1; + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto end; + } + + ret = 1; + end: + sk_X509_free(sktmp); + X509_free(chain_ss); + *bad = bad_chain; + *out_ok = ok; + + return ret; +} + +static int +X509_verify_cert_legacy(X509_STORE_CTX *ctx) +{ + int ok = 0, bad_chain; + + ctx->error = X509_V_OK; /* Initialize to OK */ + + if (!X509_verify_cert_legacy_build_chain(ctx, &bad_chain, &ok)) + goto end; + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + if (!ok) + goto end; + + /* Check that the chain satisfies the security level. */ + ok = x509_vfy_check_security_level(ctx); + if (!ok) + goto end; + + /* Check name constraints */ + ok = check_name_constraints(ctx); + if (!ok) + goto end; + +#ifndef OPENSSL_NO_RFC3779 + ok = X509v3_asid_validate_path(ctx); + if (!ok) + goto end; + + ok = X509v3_addr_validate_path(ctx); + if (!ok) + goto end; +#endif + + ok = check_id(ctx); + if (!ok) + goto end; + + /* + * Check revocation status: we do this after copying parameters because + * they may be needed for CRL signature verification. + */ + ok = ctx->check_revocation(ctx); + if (!ok) + goto end; + + /* At this point, we have a chain and need to verify it */ + if (ctx->verify != NULL) + ok = ctx->verify(ctx); + else + ok = internal_verify(ctx); + if (!ok) + goto end; + + /* If we get this far evaluate policies */ + if (!bad_chain) + ok = ctx->check_policy(ctx); + + end: + /* Safety net, error returns must set ctx->error */ + if (ok <= 0 && ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + + return ok; +} + +int +X509_verify_cert(X509_STORE_CTX *ctx) +{ + struct x509_verify_ctx *vctx = NULL; + int chain_count = 0; + + if (ctx->cert == NULL) { + X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + if (ctx->chain != NULL) { + /* + * This X509_STORE_CTX has already been used to verify + * a cert. We cannot do another one. + */ + X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + if (ctx->param->poisoned) { + /* + * This X509_STORE_CTX had failures setting + * up verify parameters. We can not use it. + */ + X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + if (ctx->error != X509_V_ERR_INVALID_CALL) { + /* + * This X509_STORE_CTX has not been properly initialized. + */ + X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + + /* + * If the certificate's public key is too weak, don't bother + * continuing. + */ + if (!check_key_level(ctx, ctx->cert) && + !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL)) + return 0; + + /* + * If flags request legacy, use the legacy verifier. If we + * requested "no alt chains" from the age of hammer pants, use + * the legacy verifier because the multi chain verifier really + * does find all the "alt chains". + * + * XXX deprecate the NO_ALT_CHAINS flag? + */ + if ((ctx->param->flags & X509_V_FLAG_LEGACY_VERIFY) || + (ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) + return X509_verify_cert_legacy(ctx); + + /* Use the modern multi-chain verifier from x509_verify_cert */ + + if ((vctx = x509_verify_ctx_new_from_xsc(ctx)) != NULL) { + ctx->error = X509_V_OK; /* Initialize to OK */ + chain_count = x509_verify(vctx, NULL, NULL); + } + x509_verify_ctx_free(vctx); + + /* if we succeed we have a chain in ctx->chain */ + return (chain_count > 0 && ctx->chain != NULL); +} +LCRYPTO_ALIAS(X509_verify_cert); + +/* Given a STACK_OF(X509) find the issuer of cert (if any) + */ + +static X509 * +find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x, + int allow_expired) +{ + int i; + X509 *issuer, *rv = NULL; + + for (i = 0; i < sk_X509_num(sk); i++) { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) { + if (x509_check_cert_time(ctx, issuer, -1)) + return issuer; + if (allow_expired) + rv = issuer; + } + } + return rv; +} + +/* Given a possible certificate and issuer check them */ + +static int +check_issued(X509_STORE_CTX *ctx, X509 *subject, X509 *issuer) +{ + /* + * Yes, the arguments of X509_STORE_CTX_check_issued_fn were exposed in + * reverse order compared to the already public X509_check_issued()... + */ + return X509_check_issued(issuer, subject) == X509_V_OK; +} + +/* Alternative lookup method: look from a STACK stored in ctx->trusted */ + +static int +get_trusted_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + *issuer = find_issuer(ctx, ctx->trusted, x, 1); + if (*issuer) { + CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); + return 1; + } else + return 0; +} + +/* Check a certificate chains extensions for consistency + * with the supplied purpose + */ + +int +x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok = 0, must_be_ca, plen = 0; + X509 *x; + int (*cb)(int xok, X509_STORE_CTX *xctx); + int proxy_path_length = 0; + int purpose; + + cb = ctx->verify_cb; + + /* must_be_ca can have 1 of 3 values: + -1: we accept both CA and non-CA certificates, to allow direct + use of self-signed certificates (which are marked as CA). + 0: we only accept non-CA certificates. This is currently not + used, but the possibility is present for future extensions. + 1: we only accept CA certificates. This is currently used for + all certificates in the chain except the leaf certificate. + */ + must_be_ca = -1; + + /* CRL path validation */ + if (ctx->parent) + purpose = X509_PURPOSE_CRL_SIGN; + else + purpose = ctx->param->purpose; + + /* Check all untrusted certificates */ + for (i = 0; i < ctx->num_untrusted; i++) { + int ret; + x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && + (x->ex_flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + ret = X509_check_ca(x); + if (must_be_ca == -1) { + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && + (ret != 1) && (ret != 0)) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + } else { + if ((ret == 0) || + ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && + (ret != 1))) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + } + if (ret == 0) { + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (ctx->param->purpose > 0) { + ret = X509_check_purpose(x, purpose, must_be_ca > 0); + if ((ret == 0) || + ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && + (ret != 1))) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + } + /* Check pathlen if not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) && + (x->ex_pathlen != -1) && + (plen > (x->ex_pathlen + proxy_path_length + 1))) { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + /* Increment path length if not self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + plen++; + must_be_ca = 1; + } + ok = 1; + +end: + return ok; +#endif +} + +static int +check_chain_extensions(X509_STORE_CTX *ctx) { + return x509_vfy_check_chain_extensions(ctx); +} + +static int +check_name_constraints(X509_STORE_CTX *ctx) +{ + if (!x509_constraints_chain(ctx->chain, &ctx->error, + &ctx->error_depth)) { + ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); + if (!ctx->verify_cb(0, ctx)) + return 0; + } + return 1; +} + +/* Given a certificate try and find an exact match in the store */ + +static X509 * +lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) +{ + STACK_OF(X509) *certs; + X509 *xtmp = NULL; + size_t i; + + /* Lookup all certs with matching subject name */ + certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); + if (certs == NULL) + return NULL; + + /* Look for exact match */ + for (i = 0; i < sk_X509_num(certs); i++) { + xtmp = sk_X509_value(certs, i); + if (!X509_cmp(xtmp, x)) + break; + } + + if (i < sk_X509_num(certs)) + X509_up_ref(xtmp); + else + xtmp = NULL; + + sk_X509_pop_free(certs, X509_free); + return xtmp; +} + +X509 * +x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) +{ + if (ctx->lookup_certs == NULL || ctx->store == NULL || + ctx->store->objs == NULL) + return NULL; + return lookup_cert_match(ctx, x); +} + +static int +check_trust(X509_STORE_CTX *ctx) +{ + size_t i; + int ok; + X509 *x = NULL; + int (*cb) (int xok, X509_STORE_CTX *xctx); + + cb = ctx->verify_cb; + /* Check all trusted certificates in chain */ + for (i = ctx->num_untrusted; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + + /* If explicitly trusted return trusted */ + if (ok == X509_TRUST_TRUSTED) + return X509_TRUST_TRUSTED; + /* + * If explicitly rejected notify callback and reject if not + * overridden. + */ + if (ok == X509_TRUST_REJECTED) { + ctx->error_depth = i; + ctx->current_cert = x; + ctx->error = X509_V_ERR_CERT_REJECTED; + ok = cb(0, ctx); + if (!ok) + return X509_TRUST_REJECTED; + } + } + /* + * If we accept partial chains and have at least one trusted certificate + * return success. + */ + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + X509 *mx; + if (ctx->num_untrusted < (int)sk_X509_num(ctx->chain)) + return X509_TRUST_TRUSTED; + x = sk_X509_value(ctx->chain, 0); + mx = lookup_cert_match(ctx, x); + if (mx) { + (void)sk_X509_set(ctx->chain, 0, mx); + X509_free(x); + ctx->num_untrusted = 0; + return X509_TRUST_TRUSTED; + } + } + + /* + * If no trusted certs in chain at all return untrusted and allow + * standard (no issuer cert) etc errors to be indicated. + */ + return X509_TRUST_UNTRUSTED; +} + +int +x509_vfy_check_trust(X509_STORE_CTX *ctx) +{ + return check_trust(ctx); +} + +static int +check_revocation(X509_STORE_CTX *ctx) +{ + int i, last, ok; + + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + return 1; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + last = sk_X509_num(ctx->chain) - 1; + else { + /* If checking CRL paths this isn't the EE certificate */ + if (ctx->parent) + return 1; + last = 0; + } + for (i = 0; i <= last; i++) { + ok = check_cert(ctx, ctx->chain, i); + if (!ok) + return ok; + } + return 1; +} + +int +x509_vfy_check_revocation(X509_STORE_CTX *ctx) +{ + return check_revocation(ctx); +} + +static int +check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth) +{ + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok = 0, cnum; + unsigned int last_reasons; + + cnum = ctx->error_depth = depth; + x = sk_X509_value(chain, cnum); + ctx->current_cert = x; + ctx->current_issuer = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { + last_reasons = ctx->current_reasons; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); + else + ok = get_crl_delta(ctx, &crl, &dcrl, x); + /* If error looking up CRL, nothing we can do except + * notify callback + */ + if (!ok) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) + goto err; + + if (dcrl) { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) + goto err; + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) + goto err; + } else + ok = 1; + + /* Don't look in full CRL if delta reason is removefromCRL */ + if (ok != 2) { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) + goto err; + } + + ctx->current_crl = NULL; + X509_CRL_free(crl); + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; + /* If reasons not updated we wont get anywhere by + * another iteration, so exit loop. + */ + if (last_reasons == ctx->current_reasons) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + } + +err: + ctx->current_crl = NULL; + X509_CRL_free(crl); + X509_CRL_free(dcrl); + return ok; +} + +/* Check CRL times against values in X509_STORE_CTX */ + +static int +check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) +{ + time_t *ptime; + int i; + + if (notify) + ctx->current_crl = crl; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + return (1); + else + ptime = NULL; + + i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (X509_CRL_get_nextUpdate(crl)) { + i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); + + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + /* Ignore expiry of base CRL is delta is valid */ + if ((i < 0) && + !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + + if (notify) + ctx->current_crl = NULL; + + return 1; +} + +static int +get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 **pissuer, int *pscore, unsigned int *preasons, + STACK_OF(X509_CRL) *crls) +{ + int i, crl_score, best_score = *pscore; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; + X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + + if (crl_score > best_score) { + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; + } + } + + if (best_crl) { + if (*pcrl) + X509_CRL_free(*pcrl); + *pcrl = best_crl; + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (*pdcrl) { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + } + + if (best_score >= CRL_SCORE_VALID) + return 1; + + return 0; +} + +/* Compare two CRL extensions for delta checking purposes. They should be + * both present or both absent. If both present all fields must be identical. + */ + +static int +crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) +{ + ASN1_OCTET_STRING *exta, *extb; + int i; + + i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { + /* Can't have multiple occurrences */ + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) + return 0; + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } else + exta = NULL; + + i = X509_CRL_get_ext_by_NID(b, nid, -1); + + if (i >= 0) { + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) + return 0; + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } else + extb = NULL; + + if (!exta && !extb) + return 1; + + if (!exta || !extb) + return 0; + + if (ASN1_OCTET_STRING_cmp(exta, extb)) + return 0; + + return 1; +} + +/* See if a base and delta are compatible */ + +static int +check_delta_base(X509_CRL *delta, X509_CRL *base) +{ + /* Delta CRL must be a delta */ + if (!delta->base_crl_number) + return 0; + /* Base must have a CRL number */ + if (!base->crl_number) + return 0; + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), + X509_CRL_get_issuer(delta))) + return 0; + /* AKID and IDP must match */ + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) + return 0; + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) + return 0; + /* Delta CRL base number must not exceed Full CRL number. */ + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) + return 0; + /* Delta CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) + return 1; + return 0; +} + +/* For a given base CRL find a delta... maybe extend to delta scoring + * or retrieve a chain of deltas... + */ + +static void +get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base, + STACK_OF(X509_CRL) *crls) +{ + X509_CRL *delta; + int i; + + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + return; + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + return; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) { + if (check_crl_time(ctx, delta, 0)) + *pscore |= CRL_SCORE_TIME_DELTA; + CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); + *dcrl = delta; + return; + } + } + *dcrl = NULL; +} + +/* For a given CRL return how suitable it is for the supplied certificate 'x'. + * The return value is a mask of several criteria. + * If the issuer is not the certificate issuer this is returned in *pissuer. + * The reasons mask is also used to determine if the CRL is suitable: if + * no new reasons the CRL is rejected, otherwise reasons is updated. + */ + +static int +get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, + X509_CRL *crl, X509 *x) +{ + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; + + /* First see if we can reject CRL straight away */ + + /* Invalid IDP cannot be processed */ + if (crl->idp_flags & IDP_INVALID) + return 0; + /* Reason codes or indirect CRLs need extended CRL support */ + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) + return 0; + } else if (crl->idp_flags & IDP_REASONS) { + /* If no new reasons reject */ + if (!(crl->idp_reasons & ~tmp_reasons)) + return 0; + } + /* Don't process deltas at this stage */ + else if (crl->base_crl_number) + return 0; + /* If issuer name doesn't match certificate need indirect CRL */ + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { + if (!(crl->idp_flags & IDP_INDIRECT)) + return 0; + } else + crl_score |= CRL_SCORE_ISSUER_NAME; + + if (!(crl->flags & EXFLAG_CRITICAL)) + crl_score |= CRL_SCORE_NOCRITICAL; + + /* Check expiry */ + if (check_crl_time(ctx, crl, 0)) + crl_score |= CRL_SCORE_TIME; + + /* Check authority key ID and locate certificate issuer */ + crl_akid_check(ctx, crl, pissuer, &crl_score); + + /* If we can't locate certificate issuer at this point forget it */ + + if (!(crl_score & CRL_SCORE_AKID)) + return 0; + + /* Check cert for matching CRL distribution points */ + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { + /* If no new reasons reject */ + if (!(crl_reasons & ~tmp_reasons)) + return 0; + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; + } + + *preasons = tmp_reasons; + + return crl_score; +} + +static void +crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score) +{ + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + int i; + + if (cidx != sk_X509_num(ctx->chain) - 1) + cidx++; + + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { + *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { + crl_issuer = sk_X509_value(ctx->chain, cidx); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; + } + } + + /* Anything else needs extended CRL support */ + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + return; + + /* Otherwise the CRL issuer is not on the path. Look for it in the + * set of untrusted certificates. + */ + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; + } + } +} + +/* Check the path of a CRL issuer certificate. This creates a new + * X509_STORE_CTX and populates it with most of the parameters from the + * parent. This could be optimised somewhat since a lot of path checking + * will be duplicated by the parent, but this will rarely be used in + * practice. + */ + +static int +check_crl_path(X509_STORE_CTX *ctx, X509 *x) +{ + X509_STORE_CTX crl_ctx; + int ret; + + /* Don't allow recursive CRL path validation */ + if (ctx->parent) + return 0; + if (!X509_STORE_CTX_init(&crl_ctx, ctx->store, x, ctx->untrusted)) { + ret = -1; + goto err; + } + + crl_ctx.crls = ctx->crls; + /* Copy verify params across */ + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + /* Verify CRL issuer */ + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) + goto err; + + /* Check chain is acceptable */ + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); + +err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; +} + +/* RFC3280 says nothing about the relationship between CRL path + * and certificate path, which could lead to situations where a + * certificate could be revoked or validated by a CA not authorised + * to do so. RFC5280 is more strict and states that the two paths must + * end in the same trust anchor, though some discussions remain... + * until this is resolved we use the RFC5280 version + */ + +static int +check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) +{ + X509 *cert_ta, *crl_ta; + + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) + return 1; + return 0; +} + +/* Check for match between two dist point names: three separate cases. + * 1. Both are relative names and compare X509_NAME types. + * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. + * 3. Both are full names and compare two GENERAL_NAMES. + * 4. One is NULL: automatic match. + */ + +static int +idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) +{ + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + int i, j; + + if (!a || !b) + return 1; + if (a->type == 1) { + if (!a->dpname) + return 0; + /* Case 1: two X509_NAME */ + if (b->type == 1) { + if (!b->dpname) + return 0; + if (!X509_NAME_cmp(a->dpname, b->dpname)) + return 1; + else + return 0; + } + /* Case 2: set name and GENERAL_NAMES appropriately */ + nm = a->dpname; + gens = b->name.fullname; + } else if (b->type == 1) { + if (!b->dpname) + return 0; + /* Case 2: set name and GENERAL_NAMES appropriately */ + gens = a->name.fullname; + nm = b->dpname; + } + + /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ + if (nm) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gena->d.directoryName)) + return 1; + } + return 0; + } + + /* Else case 3: two GENERAL_NAMES */ + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) + return 1; + } + } + + return 0; +} + +static int +crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) +{ + int i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + + /* If no CRLissuer return is successful iff don't need a match */ + if (!dp->CRLissuer) + return !!(crl_score & CRL_SCORE_ISSUER_NAME); + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(gen->d.directoryName, nm)) + return 1; + } + return 0; +} + +/* Check CRLDP and IDP */ + +static int +crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons) +{ + int i; + + if (crl->idp_flags & IDP_ONLYATTR) + return 0; + if (x->ex_flags & EXFLAG_CA) { + if (crl->idp_flags & IDP_ONLYUSER) + return 0; + } else { + if (crl->idp_flags & IDP_ONLYCA) + return 0; + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { + if (!crl->idp || + idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + *preasons &= dp->dp_reasons; + return 1; + } + } + } + if ((!crl->idp || !crl->idp->distpoint) && + (crl_score & CRL_SCORE_ISSUER_NAME)) + return 1; + return 0; +} + +/* Retrieve CRL corresponding to current certificate. + * If deltas enabled try to find a delta CRL too + */ + +static int +get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) +{ + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, + ctx->crls); + if (ok) + goto done; + + /* Lookup CRLs from store */ + skcrl = ctx->lookup_crls(ctx, nm); + + /* If no CRLs found and a near match from get_crl_sk use that */ + if (!skcrl && crl) + goto done; + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + +done: + + /* If we got any kind of CRL use it and return success */ + if (crl) { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; +} + +/* Check CRL validity */ +static int +check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) +{ + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0, chnum, cnum; + + cnum = ctx->error_depth; + chnum = sk_X509_num(ctx->chain) - 1; + /* if we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer) { + issuer = ctx->current_issuer; + } else if (cnum < chnum) { + /* + * Else find CRL issuer: if not last certificate then issuer + * is next certificate in chain. + */ + issuer = sk_X509_value(ctx->chain, cnum + 1); + } else { + issuer = sk_X509_value(ctx->chain, chnum); + /* If not self signed, can't check signature */ + if (!ctx->check_issued(ctx, issuer, issuer)) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (issuer) { + /* Skip most tests for deltas because they have already + * been done + */ + if (!crl->base_crl_number) { + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { + if (check_crl_path(ctx, + ctx->current_issuer) <= 0) { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (crl->idp_flags & IDP_INVALID) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; + } + + /* Attempt to get issuer certificate public key */ + ikey = X509_get_pubkey(issuer); + + if (!ikey) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } else { + /* Verify CRL signature */ + if (X509_CRL_verify(crl, ikey) <= 0) { + ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + } + + ok = 1; + +err: + EVP_PKEY_free(ikey); + return ok; +} + +/* Check certificate against CRL */ +static int +cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) +{ + int ok; + X509_REVOKED *rev; + + /* The rules changed for this... previously if a CRL contained + * unhandled critical extensions it could still be used to indicate + * a certificate was revoked. This has since been changed since + * critical extension can change the meaning of CRL entries. + */ + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && + (crl->flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + /* Look for serial number of certificate in CRL + * If found make sure reason is not removeFromCRL. + */ + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + + return 1; +} + +int +x509_vfy_check_policy(X509_STORE_CTX *ctx) +{ + X509 *current_cert = NULL; + int ret; + + if (ctx->parent != NULL) + return 1; + + ret = X509_policy_check(ctx->chain, ctx->param->policies, + ctx->param->flags, ¤t_cert); + if (ret != X509_V_OK) { + ctx->current_cert = current_cert; + ctx->error = ret; + if (ret == X509_V_ERR_OUT_OF_MEM) + return 0; + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + ctx->current_cert = NULL; + /* + * Verification errors need to be "sticky", a callback may have + * allowed an SSL handshake to continue despite an error, and + * we must then remain in an error state. Therefore, we MUST + * NOT clear earlier verification errors by setting the error + * to X509_V_OK. + */ + if (!ctx->verify_cb(2, ctx)) + return 0; + } + + return 1; +} + +static int +check_policy(X509_STORE_CTX *ctx) +{ + return x509_vfy_check_policy(ctx); +} + +/* + * Inform the verify callback of an error. + * + * If x is not NULL it is the error cert, otherwise use the chain cert + * at depth. + * + * If err is not X509_V_OK, that's the error value, otherwise leave + * unchanged (presumably set by the caller). + * + * Returns 0 to abort verification with an error, non-zero to continue. + */ +static int +verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) +{ + ctx->error_depth = depth; + ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth); + if (err != X509_V_OK) + ctx->error = err; + return ctx->verify_cb(0, ctx); +} + + +/* Mimic OpenSSL '0 for failure' ick */ +static int +time_t_bogocmp(time_t a, time_t b) +{ + if (a == -1 || b == -1) + return 0; + if (a <= b) + return -1; + return 1; +} + +/* + * Check certificate validity times. + * + * If depth >= 0, invoke verification callbacks on error, otherwise just return + * the validation status. + * + * Return 1 on success, 0 otherwise. + */ +int +x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) +{ + time_t ptime; + int i; + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = ctx->param->check_time; + else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + return 1; + else + ptime = time(NULL); + + if (x->ex_flags & EXFLAG_SET) + i = time_t_bogocmp(x->not_before, ptime); + else + i = X509_cmp_time(X509_get_notBefore(x), &ptime); + + if (i >= 0 && depth < 0) + return 0; + if (i == 0 && !verify_cb_cert(ctx, x, depth, + X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD)) + return 0; + if (i > 0 && !verify_cb_cert(ctx, x, depth, + X509_V_ERR_CERT_NOT_YET_VALID)) + return 0; + + if (x->ex_flags & EXFLAG_SET) + i = time_t_bogocmp(x->not_after, ptime); + else + i = X509_cmp_time_internal(X509_get_notAfter(x), &ptime, 1); + + if (i <= 0 && depth < 0) + return 0; + if (i == 0 && !verify_cb_cert(ctx, x, depth, + X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)) + return 0; + if (i < 0 && !verify_cb_cert(ctx, x, depth, + X509_V_ERR_CERT_HAS_EXPIRED)) + return 0; + + return 1; +} + +static int +x509_vfy_internal_verify(X509_STORE_CTX *ctx, int chain_verified) +{ + int n = sk_X509_num(ctx->chain) - 1; + X509 *xi = sk_X509_value(ctx->chain, n); + X509 *xs; + + if (ctx->check_issued(ctx, xi, xi)) + xs = xi; + else { + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + xs = xi; + goto check_cert; + } + if (n <= 0) + return verify_cb_cert(ctx, xi, 0, + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } + + /* + * Do not clear ctx->error=0, it must be "sticky", only the + * user's callback is allowed to reset errors (at its own + * peril). + */ + while (n >= 0) { + + /* + * Skip signature check for self signed certificates + * unless explicitly asked for. It doesn't add any + * security and just wastes time. If the issuer's + * public key is unusable, report the issuer + * certificate and its depth (rather than the depth of + * the subject). + */ + if (!chain_verified && ( xs != xi || + (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) { + EVP_PKEY *pkey; + if ((pkey = X509_get_pubkey(xi)) == NULL) { + if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n, + X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)) + return 0; + } else if (X509_verify(xs, pkey) <= 0) { + if (!verify_cb_cert(ctx, xs, n, + X509_V_ERR_CERT_SIGNATURE_FAILURE)) { + EVP_PKEY_free(pkey); + return 0; + } + } + EVP_PKEY_free(pkey); + } +check_cert: + /* Calls verify callback as needed */ + if (!chain_verified && !x509_check_cert_time(ctx, xs, n)) + return 0; + + /* + * Signal success at this depth. However, the + * previous error (if any) is retained. + */ + ctx->current_issuer = xi; + ctx->current_cert = xs; + ctx->error_depth = n; + if (!ctx->verify_cb(1, ctx)) + return 0; + + if (--n >= 0) { + xi = xs; + xs = sk_X509_value(ctx->chain, n); + } + } + return 1; +} + +static int +internal_verify(X509_STORE_CTX *ctx) +{ + return x509_vfy_internal_verify(ctx, 0); +} + +/* + * Internal verify, but with a chain where the verification + * math has already been performed. + */ +int +x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx) +{ + return x509_vfy_internal_verify(ctx, 1); +} + +int +X509_cmp_current_time(const ASN1_TIME *ctm) +{ + return X509_cmp_time(ctm, NULL); +} +LCRYPTO_ALIAS(X509_cmp_current_time); + +/* + * Compare a possibly unvalidated ASN1_TIME string against a time_t + * using RFC 5280 rules for the time string. If *cmp_time is NULL + * the current system time is used. + * + * XXX NOTE that unlike what you expect a "cmp" function to do in C, + * XXX this one is "special", and returns 0 for error. + * + * Returns: + * -1 if the ASN1_time is earlier than OR the same as *cmp_time. + * 1 if the ASN1_time is later than *cmp_time. + * 0 on error. + */ +static int +X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int is_notafter) +{ + time_t compare, cert_time; + + if (cmp_time == NULL) + compare = time(NULL); + else + compare = *cmp_time; + + if ((cert_time = x509_verify_asn1_time_to_time_t(ctm, is_notafter)) == + -1) + return 0; /* invalid time */ + + if (cert_time <= compare) + return -1; /* 0 is used for error, so map same to less than */ + + return 1; +} + +int +X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +{ + return X509_cmp_time_internal(ctm, cmp_time, 0); +} +LCRYPTO_ALIAS(X509_cmp_time); + + +ASN1_TIME * +X509_gmtime_adj(ASN1_TIME *s, long adj) +{ + return X509_time_adj(s, adj, NULL); +} +LCRYPTO_ALIAS(X509_gmtime_adj); + +ASN1_TIME * +X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_time) +{ + return X509_time_adj_ex(s, 0, offset_sec, in_time); +} +LCRYPTO_ALIAS(X509_time_adj); + +ASN1_TIME * +X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *in_time) +{ + time_t t; + if (in_time == NULL) + t = time(NULL); + else + t = *in_time; + + return ASN1_TIME_adj(s, t, offset_day, offset_sec); +} +LCRYPTO_ALIAS(X509_time_adj_ex); + +int +X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) +{ + EVP_PKEY *ktmp = NULL, *ktmp2; + int i, j; + + if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) + return 1; + + for (i = 0; i < sk_X509_num(chain); i++) { + ktmp = X509_get0_pubkey(sk_X509_value(chain, i)); + if (ktmp == NULL) { + X509error(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return 0; + } + if (!EVP_PKEY_missing_parameters(ktmp)) + break; + else + ktmp = NULL; + } + if (ktmp == NULL) { + X509error(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); + return 0; + } + + /* first, populate the other certs */ + for (j = i - 1; j >= 0; j--) { + if ((ktmp2 = X509_get0_pubkey(sk_X509_value(chain, j))) == NULL) + return 0; + if (!EVP_PKEY_copy_parameters(ktmp2, ktmp)) + return 0; + } + + if (pkey != NULL) + if (!EVP_PKEY_copy_parameters(pkey, ktmp)) + return 0; + return 1; +} +LCRYPTO_ALIAS(X509_get_pubkey_parameters); + +int +X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + /* This function is (usually) called only once, by + * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, + argl, argp, new_func, dup_func, free_func); +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_ex_new_index); + +int +X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) +{ + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_ex_data); + +void * +X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) +{ + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_ex_data); + +int +X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +{ + return ctx->error; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_error); + +void +X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) +{ + ctx->error = err; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_error); + +int +X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +{ + return ctx->error_depth; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_error_depth); + +void +X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth) +{ + ctx->error_depth = depth; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_error_depth); + +X509 * +X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) +{ + return ctx->current_cert; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_current_cert); + +void +X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x) +{ + ctx->current_cert = x; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_current_cert); + +STACK_OF(X509) * +X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) +{ + return ctx->chain; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_chain); + +STACK_OF(X509) * +X509_STORE_CTX_get0_chain(X509_STORE_CTX *xs) +{ + return xs->chain; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_chain); + +STACK_OF(X509) * +X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) +{ + int i; + X509 *x; + STACK_OF(X509) *chain; + + if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) + return NULL; + for (i = 0; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + } + return chain; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get1_chain); + +X509 * +X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) +{ + return ctx->current_issuer; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_current_issuer); + +X509_CRL * +X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) +{ + return ctx->current_crl; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_current_crl); + +X509_STORE_CTX * +X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) +{ + return ctx->parent; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_parent_ctx); + +X509_STORE * +X509_STORE_CTX_get0_store(X509_STORE_CTX *xs) +{ + return xs->store; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_store); + +void +X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) +{ + ctx->cert = x; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_cert); + +void +X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->untrusted = sk; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_chain); + +void +X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) +{ + ctx->crls = sk; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set0_crls); + +int +X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_purpose); + +int +X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_trust); + +/* This function is used to set the X509_STORE_CTX purpose and trust + * values. This is intended to be used when another structure has its + * own trust and purpose values which (if set) will be inherited by + * the ctx. If they aren't set then we will usually have a default + * purpose in mind which should then be used to set the trust value. + * An example of this is SSL use: an SSL structure will have its own + * purpose and trust settings which the application can set: if they + * aren't set then we use the default of SSL client/server. + */ + +int +X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust) +{ + int idx; + + /* If purpose not set use default */ + if (!purpose) + purpose = def_purpose; + /* If we have a purpose then check it is valid */ + if (purpose) { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + X509error(X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) { + X509error(X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + } + /* If trust not set then get from purpose default */ + if (!trust) + trust = ptmp->trust; + } + if (trust) { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) { + X509error(X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } + + if (purpose && !ctx->param->purpose) + ctx->param->purpose = purpose; + if (trust && !ctx->param->trust) + ctx->param->trust = trust; + return 1; +} +LCRYPTO_ALIAS(X509_STORE_CTX_purpose_inherit); + +X509_STORE_CTX * +X509_STORE_CTX_new(void) +{ + X509_STORE_CTX *ctx; + + ctx = calloc(1, sizeof(X509_STORE_CTX)); + if (!ctx) { + X509error(ERR_R_MALLOC_FAILURE); + return NULL; + } + return ctx; +} +LCRYPTO_ALIAS(X509_STORE_CTX_new); + +void +X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (ctx == NULL) + return; + + X509_STORE_CTX_cleanup(ctx); + free(ctx); +} +LCRYPTO_ALIAS(X509_STORE_CTX_free); + +int +X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *leaf, + STACK_OF(X509) *untrusted) +{ + int param_ret = 1; + + /* + * Make sure everything is initialized properly even in case of an + * early return due to an error. + * + * While this 'ctx' can be reused, X509_STORE_CTX_cleanup() will have + * freed everything and memset ex_data anyway. This also allows us + * to safely use X509_STORE_CTX variables from the stack which will + * have uninitialized data. + */ + memset(ctx, 0, sizeof(*ctx)); + + /* + * Start with this set to not valid - it will be set to valid + * in X509_verify_cert. + */ + ctx->error = X509_V_ERR_INVALID_CALL; + + /* + * Set values other than 0. Keep this in the same order as + * X509_STORE_CTX except for values that may fail. All fields that + * may fail should go last to make sure 'ctx' is as consistent as + * possible even on early exits. + */ + ctx->store = store; + ctx->cert = leaf; + ctx->untrusted = untrusted; + + if (store && store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store && store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store && store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store && store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store && store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store && store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = NULL; + + if (store && store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store && store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + ctx->check_policy = check_policy; + + if (store && store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = X509_STORE_CTX_get1_certs; + + if (store && store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = X509_STORE_CTX_get1_crls; + + if (store && store->cleanup) + ctx->cleanup = store->cleanup; + else + ctx->cleanup = NULL; + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Inherit callbacks and flags from X509_STORE if not set + * use defaults. + */ + if (store) + param_ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); + else + ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE; + + if (param_ret) + param_ret = X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default")); + + if (param_ret == 0) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + + if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, + &(ctx->ex_data)) == 0) { + X509error(ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} +LCRYPTO_ALIAS(X509_STORE_CTX_init); + +/* Set alternative lookup method: just a STACK of trusted certificates. + * This avoids X509_STORE nastiness where it isn't needed. + */ + +void +X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *trusted) +{ + X509_STORE_CTX_set0_trusted_stack(ctx, trusted); +} +LCRYPTO_ALIAS(X509_STORE_CTX_trusted_stack); + +void +X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *trusted) +{ + ctx->trusted = trusted; + ctx->get_issuer = get_trusted_issuer; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set0_trusted_stack); + +void +X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) +{ + if (ctx->cleanup) + ctx->cleanup(ctx); + if (ctx->param != NULL) { + if (ctx->parent == NULL) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = NULL; + } + if (ctx->chain != NULL) { + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = NULL; + } + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, + ctx, &(ctx->ex_data)); + memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); +} +LCRYPTO_ALIAS(X509_STORE_CTX_cleanup); + +void +X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_depth); + +void +X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) +{ + X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_flags); + +void +X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t) +{ + X509_VERIFY_PARAM_set_time(ctx->param, t); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_time); + +int +(*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *) +{ + return ctx->verify_cb; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_verify_cb); + +void +X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_verify_cb); + +int +(*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *) +{ + return ctx->verify; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_verify); + +void +X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, int (*verify)(X509_STORE_CTX *)) +{ + ctx->verify = verify; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_verify); + +X509_STORE_CTX_check_issued_fn +X509_STORE_get_check_issued(X509_STORE *store) +{ + return store->check_issued; +} +LCRYPTO_ALIAS(X509_STORE_get_check_issued); + +void +X509_STORE_set_check_issued(X509_STORE *store, + X509_STORE_CTX_check_issued_fn check_issued) +{ + store->check_issued = check_issued; +} +LCRYPTO_ALIAS(X509_STORE_set_check_issued); + +X509_STORE_CTX_check_issued_fn +X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx) +{ + return ctx->check_issued; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_check_issued); + +X509 * +X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) +{ + return ctx->cert; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_cert); + +STACK_OF(X509) * +X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->untrusted; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_untrusted); + +void +X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->untrusted = sk; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set0_untrusted); + +void +X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = sk; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set0_verified_chain); + +int +X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->num_untrusted; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get_num_untrusted); + +int +X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) +{ + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) + return 0; + return X509_VERIFY_PARAM_inherit(ctx->param, param); +} +LCRYPTO_ALIAS(X509_STORE_CTX_set_default); + +X509_VERIFY_PARAM * +X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) +{ + return ctx->param; +} +LCRYPTO_ALIAS(X509_STORE_CTX_get0_param); + +void +X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) +{ + if (ctx->param) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = param; +} +LCRYPTO_ALIAS(X509_STORE_CTX_set0_param); + +/* + * Check if |bits| are adequate for |security level|. + * Returns 1 if ok, 0 otherwise. + */ +static int +enough_bits_for_security_level(int bits, int level) +{ + /* + * Sigh. OpenSSL does this silly squashing, so we will + * too. Derp for Derp compatibility being important. + */ + if (level < 0) + level = 0; + if (level > 5) + level = 5; + + switch (level) { + case 0: + return 1; + case 1: + return bits >= 80; + case 2: + return bits >= 112; + case 3: + return bits >= 128; + case 4: + return bits >= 192; + case 5: + return bits >= 256; + default: + return 0; + } +} + +/* + * Check whether the public key of |cert| meets the security level of |ctx|. + * + * Returns 1 on success, 0 otherwise. + */ +static int +check_key_level(X509_STORE_CTX *ctx, X509 *cert) +{ + EVP_PKEY *pkey; + int bits; + + /* Unsupported or malformed keys are not secure */ + if ((pkey = X509_get0_pubkey(cert)) == NULL) + return 0; + + if ((bits = EVP_PKEY_security_bits(pkey)) <= 0) + return 0; + + return enough_bits_for_security_level(bits, ctx->param->security_level); +} + +/* + * Check whether the signature digest algorithm of |cert| meets the security + * level of |ctx|. Do not check trust anchors (self-signed or not). + * + * Returns 1 on success, 0 otherwise. + */ +static int +check_sig_level(X509_STORE_CTX *ctx, X509 *cert) +{ + const EVP_MD *md; + int bits, nid, md_nid; + + if ((nid = X509_get_signature_nid(cert)) == NID_undef) + return 0; + + /* + * Look up signature algorithm digest. + */ + + if (!OBJ_find_sigid_algs(nid, &md_nid, NULL)) + return 0; + + if (md_nid == NID_undef) + return 0; + + if ((md = EVP_get_digestbynid(md_nid)) == NULL) + return 0; + + /* Assume 4 bits of collision resistance for each hash octet. */ + bits = EVP_MD_size(md) * 4; + + return enough_bits_for_security_level(bits, ctx->param->security_level); +} + +int +x509_vfy_check_security_level(X509_STORE_CTX *ctx) +{ + int num = sk_X509_num(ctx->chain); + int i; + + if (ctx->param->security_level <= 0) + return 1; + + for (i = 0; i < num; i++) { + X509 *cert = sk_X509_value(ctx->chain, i); + + /* + * We've already checked the security of the leaf key, so here + * we only check the security of issuer keys. + */ + if (i > 0) { + if (!check_key_level(ctx, cert) && + !verify_cb_cert(ctx, cert, i, + X509_V_ERR_CA_KEY_TOO_SMALL)) + return 0; + } + + /* + * We also check the signature algorithm security of all certs + * except those of the trust anchor at index num - 1. + */ + if (i == num - 1) + break; + + if (!check_sig_level(ctx, cert) && + !verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK)) + return 0; + } + return 1; +} diff --git a/Libraries/libressl/crypto/x509/x509_vpm.c b/Libraries/libressl/crypto/x509/x509_vpm.c new file mode 100644 index 000000000..4ba697ead --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509_vpm.c @@ -0,0 +1,729 @@ +/* $OpenBSD: x509_vpm.c,v 1.40 2023/05/28 05:25:24 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "x509_local.h" + +/* X509_VERIFY_PARAM functions */ + +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, + size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, + size_t iplen); + +#define SET_HOST 0 +#define ADD_HOST 1 + +static void +str_free(char *s) +{ + free(s); +} + +/* + * Post 1.0.1 sk function "deep_copy". For the moment we simply make + * these take void * and use them directly without a glorious blob of + * obfuscating macros of dubious value in front of them. All this in + * preparation for a rototilling of safestack.h (likely inspired by + * this). + */ +static void * +sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void) +{ + _STACK *sk = sk_void; + void *(*copy_func)(void *) = copy_func_void; + void (*free_func)(void *) = free_func_void; + _STACK *ret = sk_dup(sk); + size_t i; + + if (ret == NULL) + return NULL; + + for (i = 0; i < ret->num; i++) { + if (ret->data[i] == NULL) + continue; + ret->data[i] = copy_func(ret->data[i]); + if (ret->data[i] == NULL) { + size_t j; + for (j = 0; j < i; j++) { + if (ret->data[j] != NULL) + free_func(ret->data[j]); + } + sk_free(ret); + return NULL; + } + } + + return ret; +} + +static int +x509_param_set_hosts_internal(X509_VERIFY_PARAM *vpm, int mode, + const char *name, size_t namelen) +{ + char *copy; + + if (name != NULL && namelen == 0) + namelen = strlen(name); + /* + * Refuse names with embedded NUL bytes. + */ + if (name && memchr(name, '\0', namelen)) + return 0; + + if (mode == SET_HOST && vpm->hosts) { + sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free); + vpm->hosts = NULL; + } + if (name == NULL || namelen == 0) + return 1; + copy = strndup(name, namelen); + if (copy == NULL) + return 0; + + if (vpm->hosts == NULL && + (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { + free(copy); + return 0; + } + + if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) { + free(copy); + if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) { + sk_OPENSSL_STRING_free(vpm->hosts); + vpm->hosts = NULL; + } + return 0; + } + + return 1; +} + +static void +x509_verify_param_zero(X509_VERIFY_PARAM *param) +{ + if (!param) + return; + + free(param->name); + param->name = NULL; + param->purpose = 0; + param->trust = 0; + /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + sk_OPENSSL_STRING_pop_free(param->hosts, str_free); + param->hosts = NULL; + free(param->peername); + param->peername = NULL; + free(param->email); + param->email = NULL; + param->emaillen = 0; + free(param->ip); + param->ip = NULL; + param->iplen = 0; + param->poisoned = 0; +} + +X509_VERIFY_PARAM * +X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + + param = calloc(1, sizeof(X509_VERIFY_PARAM)); + if (param == NULL) + return NULL; + x509_verify_param_zero(param); + return param; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_new); + +void +X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) +{ + if (param == NULL) + return; + x509_verify_param_zero(param); + free(param); +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_free); + +/* + * This function determines how parameters are "inherited" from one structure + * to another. There are several different ways this can happen. + * + * 1. If a child structure needs to have its values initialized from a parent + * they are simply copied across. For example SSL_CTX copied to SSL. + * 2. If the structure should take on values only if they are currently unset. + * For example the values in an SSL structure will take appropriate value + * for SSL servers or clients but only if the application has not set new + * ones. + * + * The "inh_flags" field determines how this function behaves. + * + * Normally any values which are set in the default are not copied from the + * destination and verify flags are ORed together. + * + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied + * to the destination. Effectively the values in "to" become default values + * which will be used only if nothing new is set in "from". + * + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether + * they are set or not. Flags is still Ored though. + * + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead + * of ORed. + * + * If X509_VP_FLAG_LOCKED is set then no values are copied. + * + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed + * after the next call. + */ + +/* Macro to test if a field should be copied from src to dest */ +#define test_x509_verify_param_copy(field, def) \ + (to_overwrite || \ + ((src->field != def) && (to_default || (dest->field == def)))) + +/* Macro to test and copy a field if necessary */ +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field + +int +X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) +{ + unsigned long inh_flags; + int to_default, to_overwrite; + + if (!src) + return 1; + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) + dest->inh_flags = 0; + + if (inh_flags & X509_VP_FLAG_LOCKED) + return 1; + + if (inh_flags & X509_VP_FLAG_DEFAULT) + to_default = 1; + else + to_default = 0; + + if (inh_flags & X509_VP_FLAG_OVERWRITE) + to_overwrite = 1; + else + to_overwrite = 0; + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + /* If overwrite or check time not set, copy across */ + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + /* Don't need to copy flag: that is done below */ + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + dest->flags = 0; + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) + return 0; + } + + x509_verify_param_copy(hostflags, 0); + + if (test_x509_verify_param_copy(hosts, NULL)) { + if (dest->hosts) { + sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); + dest->hosts = NULL; + } + if (src->hosts) { + dest->hosts = sk_deep_copy(src->hosts, strdup, str_free); + if (dest->hosts == NULL) + return 0; + } + } + + if (test_x509_verify_param_copy(email, NULL)) { + if (!X509_VERIFY_PARAM_set1_email(dest, src->email, + src->emaillen)) + return 0; + } + + if (test_x509_verify_param_copy(ip, NULL)) { + if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) + return 0; + } + + return 1; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit); + +int +X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) +{ + unsigned long save_flags = to->inh_flags; + int ret; + + to->inh_flags |= X509_VP_FLAG_DEFAULT; + ret = X509_VERIFY_PARAM_inherit(to, from); + to->inh_flags = save_flags; + return ret; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1); + +static int +x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src, + size_t srclen, int nonul) +{ + char *tmp; + + if (src == NULL) + return 0; + + if (srclen == 0) { + srclen = strlen(src); + if (srclen == 0) + return 0; + if ((tmp = strdup(src)) == NULL) + return 0; + } else { + if (nonul && memchr(src, '\0', srclen)) + return 0; + if ((tmp = malloc(srclen)) == NULL) + return 0; + memcpy(tmp, src, srclen); + } + + if (*pdest) + free(*pdest); + *pdest = tmp; + if (pdestlen) + *pdestlen = srclen; + return 1; +} + +int +X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) +{ + free(param->name); + param->name = NULL; + if (name == NULL) + return 1; + param->name = strdup(name); + if (param->name) + return 1; + return 0; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name); + +int +X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags |= flags; + return 1; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags); + +int +X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags &= ~flags; + return 1; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags); + +unsigned long +X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +{ + return param->flags; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags); + +int +X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) +{ + return X509_PURPOSE_set(¶m->purpose, purpose); +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose); + +int +X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) +{ + return X509_TRUST_set(¶m->trust, trust); +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust); + +void +X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) +{ + param->depth = depth; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth); + +void +X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level) +{ + param->security_level = auth_level; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level); + +time_t +X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param) +{ + return param->check_time; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time); + +void +X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) +{ + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time); + +int +X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) +{ + if (!param->policies) { + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) + return 0; + return 1; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy); + +int +X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies) +{ + int i; + ASN1_OBJECT *oid, *doid; + + if (!param) + return 0; + if (param->policies) + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + + if (!policies) { + param->policies = NULL; + return 1; + } + + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + + for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { + oid = sk_ASN1_OBJECT_value(policies, i); + doid = OBJ_dup(oid); + if (!doid) + return 0; + if (!sk_ASN1_OBJECT_push(param->policies, doid)) { + ASN1_OBJECT_free(doid); + return 0; + } + } + return 1; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies); + +int +X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + if (x509_param_set_hosts_internal(param, SET_HOST, name, namelen)) + return 1; + param->poisoned = 1; + return 0; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host); + +int +X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + if (x509_param_set_hosts_internal(param, ADD_HOST, name, namelen)) + return 1; + param->poisoned = 1; + return 0; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host); + +/* Public API in OpenSSL - nothing seems to use this. */ +unsigned int +X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param) +{ + return param->hostflags; +} + +void +X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags) +{ + param->hostflags = flags; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags); + +char * +X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) +{ + return param->peername; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername); + +int +X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, + size_t emaillen) +{ + if (x509_param_set1_internal(¶m->email, ¶m->emaillen, + email, emaillen, 1)) + return 1; + param->poisoned = 1; + return 0; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email); + +int +X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, + size_t iplen) +{ + if (iplen != 4 && iplen != 16) + goto err; + if (x509_param_set1_internal((char **)¶m->ip, ¶m->iplen, + (char *)ip, iplen, 0)) + return 1; + err: + param->poisoned = 1; + return 0; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip); + +int +X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) +{ + unsigned char ipout[16]; + size_t iplen; + + iplen = (size_t)a2i_ipadd(ipout, ipasc); + return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc); + +int +X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) +{ + return param->depth; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth); + +const char * +X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) +{ + return param->name; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_name); + +/* + * Default verify parameters: these are used for various applications and can + * be overridden by the user specified table. + */ + +static const X509_VERIFY_PARAM default_table[] = { + { + .name = "default", + .flags = X509_V_FLAG_TRUSTED_FIRST, + .depth = 100, + .trust = 0, /* XXX This is not the default trust value */ + }, + { + .name = "pkcs7", + .purpose = X509_PURPOSE_SMIME_SIGN, + .trust = X509_TRUST_EMAIL, + .depth = -1, + }, + { + .name = "smime_sign", + .purpose = X509_PURPOSE_SMIME_SIGN, + .trust = X509_TRUST_EMAIL, + .depth = -1, + }, + { + .name = "ssl_client", + .purpose = X509_PURPOSE_SSL_CLIENT, + .trust = X509_TRUST_SSL_CLIENT, + .depth = -1, + }, + { + .name = "ssl_server", + .purpose = X509_PURPOSE_SSL_SERVER, + .trust = X509_TRUST_SSL_SERVER, + .depth = -1, + } +}; + +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; + +static int +param_cmp(const X509_VERIFY_PARAM * const *a, + const X509_VERIFY_PARAM * const *b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int +X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + X509_VERIFY_PARAM *ptmp; + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + size_t idx; + + if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param)) + != -1) { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, + idx); + X509_VERIFY_PARAM_free(ptmp); + (void)sk_X509_VERIFY_PARAM_delete(param_table, + idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) + return 0; + return 1; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table); + +int +X509_VERIFY_PARAM_get_count(void) +{ + int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + if (param_table) + num += sk_X509_VERIFY_PARAM_num(param_table); + return num; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count); + +const X509_VERIFY_PARAM * +X509_VERIFY_PARAM_get0(int id) +{ + int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + if (id < num) + return default_table + id; + return sk_X509_VERIFY_PARAM_value(param_table, id - num); +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0); + +const X509_VERIFY_PARAM * +X509_VERIFY_PARAM_lookup(const char *name) +{ + X509_VERIFY_PARAM pm; + unsigned int i, limit; + + pm.name = (char *)name; + if (param_table) { + size_t idx; + if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + + limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + for (i = 0; i < limit; i++) { + if (strcmp(default_table[i].name, name) == 0) { + return &default_table[i]; + } + } + return NULL; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup); + +void +X509_VERIFY_PARAM_table_cleanup(void) +{ + if (param_table) + sk_X509_VERIFY_PARAM_pop_free(param_table, + X509_VERIFY_PARAM_free); + param_table = NULL; +} +LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup); diff --git a/Libraries/libressl/crypto/x509/x509cset.c b/Libraries/libressl/crypto/x509/x509cset.c new file mode 100644 index 000000000..7904a7d67 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509cset.c @@ -0,0 +1,233 @@ +/* $OpenBSD: x509cset.c,v 1.19 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "x509_local.h" + +int +X509_CRL_up_ref(X509_CRL *x) +{ + int refs = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); + return (refs > 1) ? 1 : 0; +} +LCRYPTO_ALIAS(X509_CRL_up_ref); + +int +X509_CRL_set_version(X509_CRL *x, long version) +{ + if (x == NULL) + return (0); + if (x->crl->version == NULL) { + if ((x->crl->version = ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->crl->version, version)); +} +LCRYPTO_ALIAS(X509_CRL_set_version); + +int +X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +{ + if ((x == NULL) || (x->crl == NULL)) + return (0); + return (X509_NAME_set(&x->crl->issuer, name)); +} +LCRYPTO_ALIAS(X509_CRL_set_issuer_name); + +int +X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->lastUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate = in; + } + } + return (in != NULL); +} +LCRYPTO_ALIAS(X509_CRL_set_lastUpdate); + +int +X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + return X509_CRL_set_lastUpdate(x, tm); +} +LCRYPTO_ALIAS(X509_CRL_set1_lastUpdate); + +int +X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->nextUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate = in; + } + } + return (in != NULL); +} +LCRYPTO_ALIAS(X509_CRL_set_nextUpdate); + +int +X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + return X509_CRL_set_nextUpdate(x, tm); +} +LCRYPTO_ALIAS(X509_CRL_set1_nextUpdate); + +int +X509_CRL_sort(X509_CRL *c) +{ + int i; + X509_REVOKED *r; + + /* sort the data so it will be written in serial + * number order */ + sk_X509_REVOKED_sort(c->crl->revoked); + for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) { + r = sk_X509_REVOKED_value(c->crl->revoked, i); + r->sequence = i; + } + c->crl->enc.modified = 1; + return 1; +} +LCRYPTO_ALIAS(X509_CRL_sort); + +const STACK_OF(X509_EXTENSION) * +X509_REVOKED_get0_extensions(const X509_REVOKED *x) +{ + return x->extensions; +} +LCRYPTO_ALIAS(X509_REVOKED_get0_extensions); + +const ASN1_TIME * +X509_REVOKED_get0_revocationDate(const X509_REVOKED *x) +{ + return x->revocationDate; +} +LCRYPTO_ALIAS(X509_REVOKED_get0_revocationDate); + +const ASN1_INTEGER * +X509_REVOKED_get0_serialNumber(const X509_REVOKED *x) +{ + return x->serialNumber; +} +LCRYPTO_ALIAS(X509_REVOKED_get0_serialNumber); + +int +X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->revocationDate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->revocationDate); + x->revocationDate = in; + } + } + return (in != NULL); +} +LCRYPTO_ALIAS(X509_REVOKED_set_revocationDate); + +int +X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(x->serialNumber); + x->serialNumber = in; + } + } + return (in != NULL); +} +LCRYPTO_ALIAS(X509_REVOKED_set_serialNumber); + +int +i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp) +{ + crl->crl->enc.modified = 1; + return i2d_X509_CRL_INFO(crl->crl, pp); +} +LCRYPTO_ALIAS(i2d_re_X509_CRL_tbs); diff --git a/Libraries/libressl/crypto/x509/x509name.c b/Libraries/libressl/crypto/x509/x509name.c new file mode 100644 index 000000000..d2df06ccc --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509name.c @@ -0,0 +1,452 @@ +/* $OpenBSD: x509name.c,v 1.35 2023/05/29 11:54:50 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bytestring.h" +#include "x509_local.h" + +int +X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-1); + return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); +} +LCRYPTO_ALIAS(X509_NAME_get_text_by_NID); + +int +X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf, + int len) +{ + unsigned char *text = NULL; + ASN1_STRING *data; + int i, text_len; + int ret = -1; + CBS cbs; + + i = X509_NAME_get_index_by_OBJ(name, obj, -1); + if (i < 0) + goto err; + data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + /* + * Fail if we cannot encode as UTF-8, or if the UTF-8 encoding of the + * string contains a 0 byte, because mortal callers seldom handle the + * length difference correctly. + */ + if ((text_len = ASN1_STRING_to_UTF8(&text, data)) < 0) + goto err; + CBS_init(&cbs, text, text_len); + if (CBS_contains_zero_byte(&cbs)) + goto err; + /* We still support the "pass NULL to find out how much" API */ + if (buf != NULL) { + if (len <= 0 || !CBS_write_bytes(&cbs, buf, len - 1, NULL)) + goto err; + /* It must be a C string */ + buf[text_len] = '\0'; + } + ret = text_len; + + err: + free(text); + return (ret); +} +LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); + +int +X509_NAME_entry_count(const X509_NAME *name) +{ + if (name == NULL) + return (0); + return (sk_X509_NAME_ENTRY_num(name->entries)); +} +LCRYPTO_ALIAS(X509_NAME_entry_count); + +int +X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); +} +LCRYPTO_ALIAS(X509_NAME_get_index_by_NID); + +/* NOTE: you should be passing -1, not 0 as lastpos */ +int +X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos) +{ + int n; + X509_NAME_ENTRY *ne; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (-1); + if (lastpos < 0) + lastpos = -1; + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) { + ne = sk_X509_NAME_ENTRY_value(sk, lastpos); + if (OBJ_cmp(ne->object, obj) == 0) + return (lastpos); + } + return (-1); +} +LCRYPTO_ALIAS(X509_NAME_get_index_by_OBJ); + +X509_NAME_ENTRY * +X509_NAME_get_entry(const X509_NAME *name, int loc) +{ + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc || + loc < 0) + return (NULL); + else + return (sk_X509_NAME_ENTRY_value(name->entries, loc)); +} +LCRYPTO_ALIAS(X509_NAME_get_entry); + +X509_NAME_ENTRY * +X509_NAME_delete_entry(X509_NAME *name, int loc) +{ + X509_NAME_ENTRY *ret; + int i, n, set_prev, set_next; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc || + loc < 0) + return (NULL); + sk = name->entries; + ret = sk_X509_NAME_ENTRY_delete(sk, loc); + n = sk_X509_NAME_ENTRY_num(sk); + name->modified = 1; + if (loc == n) + return (ret); + + /* else we need to fixup the set field */ + if (loc != 0) + set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; + else + set_prev = ret->set - 1; + set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; + + /* set_prev is the previous set + * set is the current set + * set_next is the following + * prev 1 1 1 1 1 1 1 1 + * set 1 1 2 2 + * next 1 1 2 2 2 2 3 2 + * so basically only if prev and next differ by 2, then + * re-number down by 1 */ + if (set_prev + 1 < set_next) + for (i = loc; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set--; + return (ret); +} +LCRYPTO_ALIAS(X509_NAME_delete_entry); + +int +X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + + ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} +LCRYPTO_ALIAS(X509_NAME_add_entry_by_OBJ); + +int +X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + + ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} +LCRYPTO_ALIAS(X509_NAME_add_entry_by_NID); + +int +X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + + ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} +LCRYPTO_ALIAS(X509_NAME_add_entry_by_txt); + +/* if set is -1, append to previous set, 0 'a new one', and 1, + * prepend to the guy we are about to stomp on. */ +int +X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, + int set) +{ + X509_NAME_ENTRY *new_name = NULL; + int n, i, inc; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (0); + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + inc = (set == 0); + name->modified = 1; + + if (set == -1) { + if (loc == 0) { + set = 0; + inc = 1; + } else + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; + } else /* if (set >= 0) */ { + if (loc >= n) { + if (loc != 0) + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; + else + set = 0; + } else + set = sk_X509_NAME_ENTRY_value(sk, loc)->set; + } + + /* OpenSSL has ASN1-generated X509_NAME_ENTRY_dup() without const. */ + if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL) + goto err; + new_name->set = set; + if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { + X509error(ERR_R_MALLOC_FAILURE); + goto err; + } + if (inc) { + n = sk_X509_NAME_ENTRY_num(sk); + for (i = loc + 1; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set += 1; + } + return (1); + +err: + if (new_name != NULL) + X509_NAME_ENTRY_free(new_name); + return (0); +} +LCRYPTO_ALIAS(X509_NAME_add_entry); + +X509_NAME_ENTRY * +X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_txt2obj(field, 0); + if (obj == NULL) { + X509error(X509_R_INVALID_FIELD_NAME); + ERR_asprintf_error_data("name=%s", field); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_txt); + +X509_NAME_ENTRY * +X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type, + const unsigned char *bytes, int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509error(X509_R_UNKNOWN_NID); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_NID); + +X509_NAME_ENTRY * +X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, const ASN1_OBJECT *obj, + int type, const unsigned char *bytes, int len) +{ + X509_NAME_ENTRY *ret; + + if ((ne == NULL) || (*ne == NULL)) { + if ((ret = X509_NAME_ENTRY_new()) == NULL) + return (NULL); + } else + ret= *ne; + + if (!X509_NAME_ENTRY_set_object(ret, obj)) + goto err; + if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) + goto err; + + if ((ne != NULL) && (*ne == NULL)) + *ne = ret; + return (ret); + +err: + if ((ne == NULL) || (ret != *ne)) + X509_NAME_ENTRY_free(ret); + return (NULL); +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_OBJ); + +int +X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + X509error(ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + ASN1_OBJECT_free(ne->object); + ne->object = OBJ_dup(obj); + return ((ne->object == NULL) ? 0 : 1); +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_set_object); + +int +X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len) +{ + int i; + + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) + return (0); + if ((type > 0) && (type & MBSTRING_FLAG)) + return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type, + OBJ_obj2nid(ne->object)) ? 1 : 0; + if (len < 0) + len = strlen((const char *)bytes); + i = ASN1_STRING_set(ne->value, bytes, len); + if (!i) + return (0); + if (type != V_ASN1_UNDEF) { + if (type == V_ASN1_APP_CHOOSE) + ne->value->type = ASN1_PRINTABLE_type(bytes, len); + else + ne->value->type = type; + } + return (1); +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_set_data); + +ASN1_OBJECT * +X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->object); +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_get_object); + +ASN1_STRING * +X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->value); +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_get_data); + +int +X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +{ + return (ne->set); +} +LCRYPTO_ALIAS(X509_NAME_ENTRY_set); diff --git a/Libraries/libressl/crypto/x509/x509rset.c b/Libraries/libressl/crypto/x509/x509rset.c new file mode 100644 index 000000000..f097a379f --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509rset.c @@ -0,0 +1,110 @@ +/* $OpenBSD: x509rset.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include "x509_local.h" + +int +X509_REQ_set_version(X509_REQ *x, long version) +{ + if (x == NULL) + return (0); + x->req_info->enc.modified = 1; + return (ASN1_INTEGER_set(x->req_info->version, version)); +} +LCRYPTO_ALIAS(X509_REQ_set_version); + +long +X509_REQ_get_version(const X509_REQ *x) +{ + return ASN1_INTEGER_get(x->req_info->version); +} +LCRYPTO_ALIAS(X509_REQ_get_version); + +int +X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + x->req_info->enc.modified = 1; + return (X509_NAME_set(&x->req_info->subject, name)); +} +LCRYPTO_ALIAS(X509_REQ_set_subject_name); + +X509_NAME * +X509_REQ_get_subject_name(const X509_REQ *x) +{ + return x->req_info->subject; +} +LCRYPTO_ALIAS(X509_REQ_get_subject_name); + +int +X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + x->req_info->enc.modified = 1; + return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +} +LCRYPTO_ALIAS(X509_REQ_set_pubkey); diff --git a/Libraries/libressl/crypto/x509/x509spki.c b/Libraries/libressl/crypto/x509/x509spki.c new file mode 100644 index 000000000..04c9a6f01 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509spki.c @@ -0,0 +1,136 @@ +/* $OpenBSD: x509spki.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include + +int +NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); +} +LCRYPTO_ALIAS(NETSCAPE_SPKI_set_pubkey); + +EVP_PKEY * +NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->spkac->pubkey)); +} +LCRYPTO_ALIAS(NETSCAPE_SPKI_get_pubkey); + +/* Load a Netscape SPKI from a base64 encoded string */ + +NETSCAPE_SPKI * +NETSCAPE_SPKI_b64_decode(const char *str, int len) +{ + unsigned char *spki_der; + const unsigned char *p; + int spki_len; + NETSCAPE_SPKI *spki; + + if (len <= 0) + len = strlen(str); + if (!(spki_der = malloc(len + 1))) { + X509error(ERR_R_MALLOC_FAILURE); + return NULL; + } + spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); + if (spki_len < 0) { + X509error(X509_R_BASE64_DECODE_ERROR); + free(spki_der); + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + free(spki_der); + return spki; +} +LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_decode); + +/* Generate a base64 encoded string from an SPKI */ + +char * +NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) +{ + unsigned char *der_spki, *p; + char *b64_str; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + der_spki = malloc(der_len); + b64_str = reallocarray(NULL, der_len, 2); + if (!der_spki || !b64_str) { + X509error(ERR_R_MALLOC_FAILURE); + free(der_spki); + free(b64_str); + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + free(der_spki); + return b64_str; +} +LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_encode); diff --git a/Libraries/libressl/crypto/x509/x509type.c b/Libraries/libressl/crypto/x509/x509type.c new file mode 100644 index 000000000..5da808cd0 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x509type.c @@ -0,0 +1,130 @@ +/* $OpenBSD: x509type.c,v 1.19 2023/06/15 18:30:09 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "evp_local.h" +#include "x509_local.h" + +int +X509_certificate_type(const X509 *x, const EVP_PKEY *pkey) +{ + const EVP_PKEY *pk = pkey; + int ret = 0, i; + + if (x == NULL) + return (0); + + if (pk == NULL) { + if ((pk = X509_get0_pubkey(x)) == NULL) + return (0); + } + + switch (pk->type) { + case EVP_PKEY_RSA: + ret = EVP_PK_RSA|EVP_PKT_SIGN|EVP_PKT_ENC; + break; + case EVP_PKEY_DSA: + ret = EVP_PK_DSA|EVP_PKT_SIGN; + break; + case EVP_PKEY_EC: + ret = EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH; + break; + case EVP_PKEY_ED25519: + ret = EVP_PKT_SIGN; + break; + case EVP_PKEY_DH: + ret = EVP_PK_DH|EVP_PKT_EXCH; + break; + case NID_id_GostR3410_94: + case NID_id_GostR3410_2001: + ret = EVP_PKT_EXCH|EVP_PKT_SIGN; + break; + default: + break; + } + + i = OBJ_obj2nid(x->sig_alg->algorithm); + if (i && OBJ_find_sigid_algs(i, NULL, &i)) { + switch (i) { + case NID_rsaEncryption: + case NID_rsa: + ret |= EVP_PKS_RSA; + break; + case NID_dsa: + case NID_dsa_2: + ret |= EVP_PKS_DSA; + break; + case NID_X9_62_id_ecPublicKey: + ret |= EVP_PKS_EC; + break; + default: + break; + } + } + + /* /8 because it's 1024 bits we look for, not bytes */ + if (EVP_PKEY_size(pk) <= 1024 / 8) + ret |= EVP_PKT_EXP; + return (ret); +} +LCRYPTO_ALIAS(X509_certificate_type); diff --git a/Libraries/libressl/crypto/x509/x_all.c b/Libraries/libressl/crypto/x509/x_all.c new file mode 100644 index 000000000..cd6da9f40 --- /dev/null +++ b/Libraries/libressl/crypto/x509/x_all.c @@ -0,0 +1,541 @@ +/* $OpenBSD: x_all.c,v 1.30 2023/02/16 08:38:17 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif + +#include "x509_local.h" + +X509 * +d2i_X509_bio(BIO *bp, X509 **x509) +{ + return ASN1_item_d2i_bio(&X509_it, bp, x509); +} +LCRYPTO_ALIAS(d2i_X509_bio); + +int +i2d_X509_bio(BIO *bp, X509 *x509) +{ + return ASN1_item_i2d_bio(&X509_it, bp, x509); +} +LCRYPTO_ALIAS(i2d_X509_bio); + +X509 * +d2i_X509_fp(FILE *fp, X509 **x509) +{ + return ASN1_item_d2i_fp(&X509_it, fp, x509); +} +LCRYPTO_ALIAS(d2i_X509_fp); + +int +i2d_X509_fp(FILE *fp, X509 *x509) +{ + return ASN1_item_i2d_fp(&X509_it, fp, x509); +} +LCRYPTO_ALIAS(i2d_X509_fp); + +X509_CRL * +d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) +{ + return ASN1_item_d2i_bio(&X509_CRL_it, bp, crl); +} +LCRYPTO_ALIAS(d2i_X509_CRL_bio); + +int +i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) +{ + return ASN1_item_i2d_bio(&X509_CRL_it, bp, crl); +} +LCRYPTO_ALIAS(i2d_X509_CRL_bio); + +X509_CRL * +d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) +{ + return ASN1_item_d2i_fp(&X509_CRL_it, fp, crl); +} +LCRYPTO_ALIAS(d2i_X509_CRL_fp); + +int +i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) +{ + return ASN1_item_i2d_fp(&X509_CRL_it, fp, crl); +} +LCRYPTO_ALIAS(i2d_X509_CRL_fp); + +X509_REQ * +d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) +{ + return ASN1_item_d2i_bio(&X509_REQ_it, bp, req); +} +LCRYPTO_ALIAS(d2i_X509_REQ_bio); + +int +i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) +{ + return ASN1_item_i2d_bio(&X509_REQ_it, bp, req); +} +LCRYPTO_ALIAS(i2d_X509_REQ_bio); + +X509_REQ * +d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) +{ + return ASN1_item_d2i_fp(&X509_REQ_it, fp, req); +} +LCRYPTO_ALIAS(d2i_X509_REQ_fp); + +int +i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) +{ + return ASN1_item_i2d_fp(&X509_REQ_it, fp, req); +} +LCRYPTO_ALIAS(i2d_X509_REQ_fp); + +#ifndef OPENSSL_NO_RSA +RSA * +d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(&RSAPrivateKey_it, bp, rsa); +} +LCRYPTO_ALIAS(d2i_RSAPrivateKey_bio); + +int +i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(&RSAPrivateKey_it, bp, rsa); +} +LCRYPTO_ALIAS(i2d_RSAPrivateKey_bio); + +RSA * +d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(&RSAPrivateKey_it, fp, rsa); +} +LCRYPTO_ALIAS(d2i_RSAPrivateKey_fp); + +int +i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(&RSAPrivateKey_it, fp, rsa); +} +LCRYPTO_ALIAS(i2d_RSAPrivateKey_fp); + +RSA * +d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(&RSAPublicKey_it, bp, rsa); +} +LCRYPTO_ALIAS(d2i_RSAPublicKey_bio); + +int +i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(&RSAPublicKey_it, bp, rsa); +} +LCRYPTO_ALIAS(i2d_RSAPublicKey_bio); + +RSA * +d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(&RSAPublicKey_it, fp, rsa); +} +LCRYPTO_ALIAS(d2i_RSAPublicKey_fp); + +int +i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(&RSAPublicKey_it, fp, rsa); +} +LCRYPTO_ALIAS(i2d_RSAPublicKey_fp); +#endif + +#ifndef OPENSSL_NO_DSA +DSA * +d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) +{ + return ASN1_item_d2i_bio(&DSAPrivateKey_it, bp, dsa); +} +LCRYPTO_ALIAS(d2i_DSAPrivateKey_bio); + +int +i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) +{ + return ASN1_item_i2d_bio(&DSAPrivateKey_it, bp, dsa); +} +LCRYPTO_ALIAS(i2d_DSAPrivateKey_bio); + +DSA * +d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) +{ + return ASN1_item_d2i_fp(&DSAPrivateKey_it, fp, dsa); +} +LCRYPTO_ALIAS(d2i_DSAPrivateKey_fp); + +int +i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) +{ + return ASN1_item_i2d_fp(&DSAPrivateKey_it, fp, dsa); +} +LCRYPTO_ALIAS(i2d_DSAPrivateKey_fp); +#endif + +#ifndef OPENSSL_NO_EC +EC_KEY * +d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); +} +LCRYPTO_ALIAS(d2i_ECPrivateKey_bio); + +int +i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); +} +LCRYPTO_ALIAS(i2d_ECPrivateKey_bio); + +EC_KEY * +d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); +} +LCRYPTO_ALIAS(d2i_ECPrivateKey_fp); + +int +i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); +} +LCRYPTO_ALIAS(i2d_ECPrivateKey_fp); +#endif + +X509_SIG * +d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) +{ + return ASN1_item_d2i_bio(&X509_SIG_it, bp, p8); +} +LCRYPTO_ALIAS(d2i_PKCS8_bio); + +int +i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) +{ + return ASN1_item_i2d_bio(&X509_SIG_it, bp, p8); +} +LCRYPTO_ALIAS(i2d_PKCS8_bio); + +X509_SIG * +d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) +{ + return ASN1_item_d2i_fp(&X509_SIG_it, fp, p8); +} +LCRYPTO_ALIAS(d2i_PKCS8_fp); + +int +i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) +{ + return ASN1_item_i2d_fp(&X509_SIG_it, fp, p8); +} +LCRYPTO_ALIAS(i2d_PKCS8_fp); + +PKCS8_PRIV_KEY_INFO * +d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_item_d2i_bio(&PKCS8_PRIV_KEY_INFO_it, bp, + p8inf); +} +LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_bio); + +int +i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_item_i2d_bio(&PKCS8_PRIV_KEY_INFO_it, bp, + p8inf); +} +LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_bio); + +PKCS8_PRIV_KEY_INFO * +d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_item_d2i_fp(&PKCS8_PRIV_KEY_INFO_it, fp, + p8inf); +} +LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_fp); + +int +i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_item_i2d_fp(&PKCS8_PRIV_KEY_INFO_it, fp, + p8inf); +} +LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_fp); + +EVP_PKEY * +d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, + bp, a); +} +LCRYPTO_ALIAS(d2i_PrivateKey_bio); + +int +i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); +} +LCRYPTO_ALIAS(i2d_PrivateKey_bio); + +EVP_PKEY * +d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, + fp, a); +} +LCRYPTO_ALIAS(d2i_PrivateKey_fp); + +int +i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); +} +LCRYPTO_ALIAS(i2d_PrivateKey_fp); + +int +i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} +LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_bio); + +int +i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} +LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_fp); + +int +X509_verify(X509 *a, EVP_PKEY *r) +{ + if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) + return 0; + return (ASN1_item_verify(&X509_CINF_it, a->sig_alg, + a->signature, a->cert_info, r)); +} +LCRYPTO_ALIAS(X509_verify); + +int +X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(&X509_REQ_INFO_it, + a->sig_alg, a->signature, a->req_info, r)); +} +LCRYPTO_ALIAS(X509_REQ_verify); + +int +NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(&NETSCAPE_SPKAC_it, + a->sig_algor, a->signature, a->spkac, r)); +} +LCRYPTO_ALIAS(NETSCAPE_SPKI_verify); + +int +X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->cert_info->enc.modified = 1; + return (ASN1_item_sign(&X509_CINF_it, + x->cert_info->signature, x->sig_alg, x->signature, + x->cert_info, pkey, md)); +} +LCRYPTO_ALIAS(X509_sign); + +int +X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) +{ + x->cert_info->enc.modified = 1; + return ASN1_item_sign_ctx(&X509_CINF_it, + x->cert_info->signature, x->sig_alg, x->signature, + x->cert_info, ctx); +} +LCRYPTO_ALIAS(X509_sign_ctx); + +int +X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(&X509_REQ_INFO_it, + x->sig_alg, NULL, x->signature, x->req_info, pkey, md)); +} +LCRYPTO_ALIAS(X509_REQ_sign); + +int +X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) +{ + return ASN1_item_sign_ctx(&X509_REQ_INFO_it, + x->sig_alg, NULL, x->signature, x->req_info, ctx); +} +LCRYPTO_ALIAS(X509_REQ_sign_ctx); + +int +X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->crl->enc.modified = 1; + return(ASN1_item_sign(&X509_CRL_INFO_it, x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md)); +} +LCRYPTO_ALIAS(X509_CRL_sign); + +int +X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) +{ + x->crl->enc.modified = 1; + return ASN1_item_sign_ctx(&X509_CRL_INFO_it, + x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx); +} +LCRYPTO_ALIAS(X509_CRL_sign_ctx); + +int +NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(&NETSCAPE_SPKAC_it, + x->sig_algor, NULL, x->signature, x->spkac, pkey, md)); +} +LCRYPTO_ALIAS(NETSCAPE_SPKI_sign); + +int +X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if (!key) + return 0; + return EVP_Digest(key->data, key->length, md, len, type, NULL); +} +LCRYPTO_ALIAS(X509_pubkey_digest); + +int +X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(&X509_it, type, (char *)data, + md, len)); +} +LCRYPTO_ALIAS(X509_digest); + +int +X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(&X509_CRL_it, type, (char *)data, + md, len)); +} +LCRYPTO_ALIAS(X509_CRL_digest); + +int +X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(&X509_REQ_it, type, (char *)data, + md, len)); +} +LCRYPTO_ALIAS(X509_REQ_digest); + +int +X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(&X509_NAME_it, type, (char *)data, + md, len)); +} +LCRYPTO_ALIAS(X509_NAME_digest); + +int +X509_up_ref(X509 *x) +{ + int i = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + return i > 1 ? 1 : 0; +} +LCRYPTO_ALIAS(X509_up_ref); diff --git a/Libraries/libressl/crypto/x86_arch.h b/Libraries/libressl/crypto/x86_arch.h new file mode 100644 index 000000000..5b2cf9754 --- /dev/null +++ b/Libraries/libressl/crypto/x86_arch.h @@ -0,0 +1,90 @@ +/* $OpenBSD: x86_arch.h,v 1.1 2016/11/04 17:30:30 miod Exp $ */ +/* + * Copyright (c) 2016 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * The knowledge of the layout of OPENSSL_ia32cap_P is internal to libcrypto + * (and, to some extent, to libssl), and may change in the future without + * notice. + */ + +/* + * OPENSSL_ia32cap_P is computed at runtime by OPENSSL_ia32_cpuid(). + * + * On processors which lack the cpuid instruction, the value is always + * zero (this only matters on 32-bit processors, of course). + * + * On processors which support the cpuid instruction, after running + * "cpuid 1", the value of %edx is written to the low word of OPENSSL_ia32cap_P, + * and the value of %ecx is written to its high word. + * + * Further processing is done to set or clear specific bits, depending + * upon the exact processor type. + * + * Assembly routines usually address OPENSSL_ia32cap_P as two 32-bit words, + * hence two sets of bit numbers and masks. OPENSSL_cpu_caps() returns the + * complete 64-bit word. + */ + +/* bit numbers for the low word */ +#define IA32CAP_BIT0_FPU 0 +#define IA32CAP_BIT0_MMX 23 +#define IA32CAP_BIT0_FXSR 24 +#define IA32CAP_BIT0_SSE 25 +#define IA32CAP_BIT0_SSE2 26 +#define IA32CAP_BIT0_HT 28 + +/* the following bits are not obtained from cpuid */ +#define IA32CAP_BIT0_INTELP4 20 +#define IA32CAP_BIT0_INTEL 30 + +/* bit numbers for the high word */ +#define IA32CAP_BIT1_PCLMUL 1 +#define IA32CAP_BIT1_SSSE3 9 +#define IA32CAP_BIT1_FMA3 12 +#define IA32CAP_BIT1_AESNI 25 +#define IA32CAP_BIT1_OSXSAVE 27 +#define IA32CAP_BIT1_AVX 28 + +#define IA32CAP_BIT1_AMD_XOP 11 + +/* bit masks for the low word */ +#define IA32CAP_MASK0_MMX (1 << IA32CAP_BIT0_MMX) +#define IA32CAP_MASK0_FXSR (1 << IA32CAP_BIT0_FXSR) +#define IA32CAP_MASK0_SSE (1 << IA32CAP_BIT0_SSE) +#define IA32CAP_MASK0_SSE2 (1 << IA32CAP_BIT0_SSE2) +#define IA32CAP_MASK0_HT (1 << IA32CAP_BIT0_HT) + +#define IA32CAP_MASK0_INTELP4 (1 << IA32CAP_BIT0_INTELP4) +#define IA32CAP_MASK0_INTEL (1 << IA32CAP_BIT0_INTEL) + +/* bit masks for the high word */ +#define IA32CAP_MASK1_PCLMUL (1 << IA32CAP_BIT1_PCLMUL) +#define IA32CAP_MASK1_SSSE3 (1 << IA32CAP_BIT1_SSSE3) +#define IA32CAP_MASK1_FMA3 (1 << IA32CAP_BIT1_FMA3) +#define IA32CAP_MASK1_AESNI (1 << IA32CAP_BIT1_AESNI) +#define IA32CAP_MASK1_AVX (1 << IA32CAP_BIT1_AVX) + +#define IA32CAP_MASK1_AMD_XOP (1 << IA32CAP_BIT1_AMD_XOP) + +/* bit masks for OPENSSL_cpu_caps() */ +#define CPUCAP_MASK_MMX IA32CAP_MASK0_MMX +#define CPUCAP_MASK_FXSR IA32CAP_MASK0_FXSR +#define CPUCAP_MASK_SSE IA32CAP_MASK0_SSE +#define CPUCAP_MASK_INTELP4 IA32CAP_MASK0_INTELP4 +#define CPUCAP_MASK_PCLMUL (1ULL << (32 + IA32CAP_BIT1_PCLMUL)) +#define CPUCAP_MASK_SSSE3 (1ULL << (32 + IA32CAP_BIT1_SSSE3)) +#define CPUCAP_MASK_AESNI (1ULL << (32 + IA32CAP_BIT1_AESNI)) diff --git a/Libraries/libressl/depcomp b/Libraries/libressl/depcomp new file mode 100644 index 000000000..715e34311 --- /dev/null +++ b/Libraries/libressl/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/Libraries/libressl/include/CMakeLists.txt b/Libraries/libressl/include/CMakeLists.txt new file mode 100644 index 000000000..9d015cd5e --- /dev/null +++ b/Libraries/libressl/include/CMakeLists.txt @@ -0,0 +1,42 @@ +if(ENABLE_LIBRESSL_INSTALL) + install(DIRECTORY . + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PATTERN "CMakeLists.txt" EXCLUDE + PATTERN "compat" EXCLUDE + PATTERN "pqueue.h" EXCLUDE + PATTERN "Makefile*" EXCLUDE + PATTERN "arch" EXCLUDE) + install(FILES ${CMAKE_BINARY_DIR}/include/openssl/opensslconf.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/openssl") +endif(ENABLE_LIBRESSL_INSTALL) + +file(COPY . + DESTINATION "${CMAKE_BINARY_DIR}/include" + PATTERN "CMakeLists.txt" EXCLUDE + PATTERN "compat" EXCLUDE + PATTERN "pqueue.h" EXCLUDE + PATTERN "Makefile*" EXCLUDE + PATTERN "arch" EXCLUDE) + +if(HOST_AARCH64) + file(READ arch/aarch64/opensslconf.h OPENSSLCONF) +elseif(HOST_ARM) + file(READ arch/arm/opensslconf.h OPENSSLCONF) +elseif(HOST_I386) + file(READ arch/i386/opensslconf.h OPENSSLCONF) +elseif(HOST_MIPS) + file(READ arch/mips/opensslconf.h OPENSSLCONF) +elseif(HOST_MIPS64) + file(READ arch/mips64/opensslconf.h OPENSSLCONF) +elseif(HOST_POWERPC) + file(READ arch/powerpc/opensslconf.h OPENSSLCONF) +elseif(HOST_POWERPC64) + file(READ arch/powerpc64/opensslconf.h OPENSSLCONF) +elseif(HOST_RISCV64) + file(READ arch/riscv64/opensslconf.h OPENSSLCONF) +elseif(HOST_SPARC64) + file(READ arch/sparc64/opensslconf.h OPENSSLCONF) +elseif(HOST_X86_64) + file(READ arch/amd64/opensslconf.h OPENSSLCONF) +endif() +file(WRITE ${CMAKE_BINARY_DIR}/include/openssl/opensslconf.h "${OPENSSLCONF}") diff --git a/Libraries/libressl/include/Makefile.am b/Libraries/libressl/include/Makefile.am new file mode 100644 index 000000000..22819c8a3 --- /dev/null +++ b/Libraries/libressl/include/Makefile.am @@ -0,0 +1,63 @@ +include $(top_srcdir)/Makefile.am.common + +EXTRA_DIST = CMakeLists.txt + +SUBDIRS = openssl + +noinst_HEADERS = pqueue.h +noinst_HEADERS += compat/dirent.h +noinst_HEADERS += compat/dirent_msvc.h +noinst_HEADERS += compat/endian.h +noinst_HEADERS += compat/err.h +noinst_HEADERS += compat/fcntl.h +noinst_HEADERS += compat/getopt.h +noinst_HEADERS += compat/limits.h +noinst_HEADERS += compat/netdb.h +noinst_HEADERS += compat/poll.h +noinst_HEADERS += compat/pthread.h +noinst_HEADERS += compat/readpassphrase.h +noinst_HEADERS += compat/resolv.h +noinst_HEADERS += compat/stdio.h +noinst_HEADERS += compat/stdlib.h +noinst_HEADERS += compat/string.h +noinst_HEADERS += compat/syslog.h +noinst_HEADERS += compat/time.h +noinst_HEADERS += compat/unistd.h +noinst_HEADERS += compat/win32netcompat.h + +noinst_HEADERS += compat/arpa/inet.h +noinst_HEADERS += compat/arpa/nameser.h + +noinst_HEADERS += compat/netinet/in.h +noinst_HEADERS += compat/netinet/ip.h +noinst_HEADERS += compat/netinet/tcp.h + +noinst_HEADERS += compat/sys/_null.h +noinst_HEADERS += compat/sys/ioctl.h +noinst_HEADERS += compat/sys/mman.h +noinst_HEADERS += compat/sys/param.h +noinst_HEADERS += compat/sys/queue.h +noinst_HEADERS += compat/sys/select.h +noinst_HEADERS += compat/sys/socket.h +noinst_HEADERS += compat/sys/stat.h +noinst_HEADERS += compat/sys/tree.h +noinst_HEADERS += compat/sys/time.h +noinst_HEADERS += compat/sys/types.h +noinst_HEADERS += compat/sys/uio.h + +noinst_HEADERS += arch/aarch64/opensslconf.h +noinst_HEADERS += arch/alpha/opensslconf.h +noinst_HEADERS += arch/amd64/opensslconf.h +noinst_HEADERS += arch/arm/opensslconf.h +noinst_HEADERS += arch/hppa/opensslconf.h +noinst_HEADERS += arch/i386/opensslconf.h +noinst_HEADERS += arch/m88k/opensslconf.h +noinst_HEADERS += arch/mips/opensslconf.h +noinst_HEADERS += arch/mips64/opensslconf.h +noinst_HEADERS += arch/powerpc/opensslconf.h +noinst_HEADERS += arch/powerpc64/opensslconf.h +noinst_HEADERS += arch/riscv64/opensslconf.h +noinst_HEADERS += arch/sh/opensslconf.h +noinst_HEADERS += arch/sparc64/opensslconf.h + +include_HEADERS = tls.h diff --git a/Libraries/libressl/include/Makefile.in b/Libraries/libressl/include/Makefile.in new file mode 100644 index 000000000..d3df0603d --- /dev/null +++ b/Libraries/libressl/include/Makefile.in @@ -0,0 +1,713 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_add_fortify_source.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/check-hardening-options.m4 \ + $(top_srcdir)/m4/check-libc.m4 \ + $(top_srcdir)/m4/check-os-options.m4 \ + $(top_srcdir)/m4/disable-compiler-warnings.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(noinst_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.common +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTO_VERSION = @LIBCRYPTO_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSL_VERSION = @LIBSSL_VERSION@ +LIBTLS_VERSION = @LIBTLS_VERSION@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSLDIR = @OPENSSLDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_LDADD = @PLATFORM_LDADD@ +PROG_LDADD = @PROG_LDADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(abs_top_builddir)/include \ + -I$(top_srcdir)/include/compat -DLIBRESSL_INTERNAL \ + -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= +EXTRA_DIST = CMakeLists.txt +SUBDIRS = openssl +noinst_HEADERS = pqueue.h compat/dirent.h compat/dirent_msvc.h \ + compat/endian.h compat/err.h compat/fcntl.h compat/getopt.h \ + compat/limits.h compat/netdb.h compat/poll.h compat/pthread.h \ + compat/readpassphrase.h compat/resolv.h compat/stdio.h \ + compat/stdlib.h compat/string.h compat/syslog.h compat/time.h \ + compat/unistd.h compat/win32netcompat.h compat/arpa/inet.h \ + compat/arpa/nameser.h compat/netinet/in.h compat/netinet/ip.h \ + compat/netinet/tcp.h compat/sys/_null.h compat/sys/ioctl.h \ + compat/sys/mman.h compat/sys/param.h compat/sys/queue.h \ + compat/sys/select.h compat/sys/socket.h compat/sys/stat.h \ + compat/sys/tree.h compat/sys/time.h compat/sys/types.h \ + compat/sys/uio.h arch/aarch64/opensslconf.h \ + arch/alpha/opensslconf.h arch/amd64/opensslconf.h \ + arch/arm/opensslconf.h arch/hppa/opensslconf.h \ + arch/i386/opensslconf.h arch/m88k/opensslconf.h \ + arch/mips/opensslconf.h arch/mips64/opensslconf.h \ + arch/powerpc/opensslconf.h arch/powerpc64/opensslconf.h \ + arch/riscv64/opensslconf.h arch/sh/opensslconf.h \ + arch/sparc64/opensslconf.h +include_HEADERS = tls.h +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.am.common $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-includeHEADERS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-includeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Libraries/libressl/include/arch/aarch64/opensslconf.h b/Libraries/libressl/include/arch/aarch64/opensslconf.h new file mode 100644 index 000000000..748ed8f8b --- /dev/null +++ b/Libraries/libressl/include/arch/aarch64/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/alpha/opensslconf.h b/Libraries/libressl/include/arch/alpha/opensslconf.h new file mode 100644 index 000000000..47f2aa8f2 --- /dev/null +++ b/Libraries/libressl/include/arch/alpha/opensslconf.h @@ -0,0 +1,152 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#define BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#define DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#define DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/amd64/opensslconf.h b/Libraries/libressl/include/arch/amd64/opensslconf.h new file mode 100644 index 000000000..5cad089a8 --- /dev/null +++ b/Libraries/libressl/include/arch/amd64/opensslconf.h @@ -0,0 +1,149 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/arm/opensslconf.h b/Libraries/libressl/include/arch/arm/opensslconf.h new file mode 100644 index 000000000..f17d3d280 --- /dev/null +++ b/Libraries/libressl/include/arch/arm/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/hppa/opensslconf.h b/Libraries/libressl/include/arch/hppa/opensslconf.h new file mode 100644 index 000000000..f17d3d280 --- /dev/null +++ b/Libraries/libressl/include/arch/hppa/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/i386/opensslconf.h b/Libraries/libressl/include/arch/i386/opensslconf.h new file mode 100644 index 000000000..3b3827cdb --- /dev/null +++ b/Libraries/libressl/include/arch/i386/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#define DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#define DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/m88k/opensslconf.h b/Libraries/libressl/include/arch/m88k/opensslconf.h new file mode 100644 index 000000000..f17d3d280 --- /dev/null +++ b/Libraries/libressl/include/arch/m88k/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/mips/opensslconf.h b/Libraries/libressl/include/arch/mips/opensslconf.h new file mode 100644 index 000000000..f17d3d280 --- /dev/null +++ b/Libraries/libressl/include/arch/mips/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/mips64/opensslconf.h b/Libraries/libressl/include/arch/mips64/opensslconf.h new file mode 100644 index 000000000..ed1204c8c --- /dev/null +++ b/Libraries/libressl/include/arch/mips64/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#define BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#define DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#define DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/powerpc/opensslconf.h b/Libraries/libressl/include/arch/powerpc/opensslconf.h new file mode 100644 index 000000000..f17d3d280 --- /dev/null +++ b/Libraries/libressl/include/arch/powerpc/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/powerpc64/opensslconf.h b/Libraries/libressl/include/arch/powerpc64/opensslconf.h new file mode 100644 index 000000000..5cad089a8 --- /dev/null +++ b/Libraries/libressl/include/arch/powerpc64/opensslconf.h @@ -0,0 +1,149 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/riscv64/opensslconf.h b/Libraries/libressl/include/arch/riscv64/opensslconf.h new file mode 100644 index 000000000..748ed8f8b --- /dev/null +++ b/Libraries/libressl/include/arch/riscv64/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/sh/opensslconf.h b/Libraries/libressl/include/arch/sh/opensslconf.h new file mode 100644 index 000000000..f17d3d280 --- /dev/null +++ b/Libraries/libressl/include/arch/sh/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/arch/sparc64/opensslconf.h b/Libraries/libressl/include/arch/sparc64/opensslconf.h new file mode 100644 index 000000000..ed1204c8c --- /dev/null +++ b/Libraries/libressl/include/arch/sparc64/opensslconf.h @@ -0,0 +1,154 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debugging the bignum libraries */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#define BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#define DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#define DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/compat/arpa/inet.h b/Libraries/libressl/include/compat/arpa/inet.h new file mode 100644 index 000000000..4422f4182 --- /dev/null +++ b/Libraries/libressl/include/compat/arpa/inet.h @@ -0,0 +1,15 @@ +/* + * Public domain + * arpa/inet.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include + +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0x00000400 +#endif + +#endif diff --git a/Libraries/libressl/include/compat/arpa/nameser.h b/Libraries/libressl/include/compat/arpa/nameser.h new file mode 100644 index 000000000..eff3b0d90 --- /dev/null +++ b/Libraries/libressl/include/compat/arpa/nameser.h @@ -0,0 +1,25 @@ +/* + * Public domain + * arpa/inet.h compatibility shim + */ + +#ifndef _WIN32 +#ifdef HAVE_ARPA_NAMESER_H +#include_next +#endif +#else +#include + +#ifndef INADDRSZ +#define INADDRSZ 4 +#endif + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 +#endif + +#ifndef INT16SZ +#define INT16SZ 2 +#endif + +#endif diff --git a/Libraries/libressl/include/compat/dirent.h b/Libraries/libressl/include/compat/dirent.h new file mode 100644 index 000000000..753e4a08e --- /dev/null +++ b/Libraries/libressl/include/compat/dirent.h @@ -0,0 +1,17 @@ +/* + * Public domain + * dirent.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_DIRENT_H +#define LIBCRYPTOCOMPAT_DIRENT_H + +#ifdef _MSC_VER +#include +#include +#else +#include_next +#endif + +#endif + diff --git a/Libraries/libressl/include/compat/dirent_msvc.h b/Libraries/libressl/include/compat/dirent_msvc.h new file mode 100644 index 000000000..67f295f19 --- /dev/null +++ b/Libraries/libressl/include/compat/dirent_msvc.h @@ -0,0 +1,611 @@ +/* + * dirent.h - dirent API for Microsoft Visual Studio + * + * Copyright (C) 2006-2012 Toni Ronkko + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $ + */ +#ifndef DIRENT_MSVC_H +#define DIRENT_MSVC_H + +#include + +#if _MSC_VER >= 1900 +#include <../ucrt/stdio.h> +#include <../ucrt/wchar.h> +#include <../ucrt/string.h> +#include <../ucrt/stdlib.h> +#include <../ucrt/sys/types.h> +#include <../ucrt/errno.h> +#else +#include <../include/stdio.h> +#include <../include/wchar.h> +#include <../include/string.h> +#include <../include/stdlib.h> +#include <../include/sys/types.h> +#include <../include/errno.h> +#endif + +#include +#include + +/* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* Indicates that d_namlen field is available in dirent structure */ +#define _DIRENT_HAVE_D_NAMLEN + +/* Maximum length of file name */ +#if !defined(PATH_MAX) +# define PATH_MAX MAX_PATH +#endif +#if !defined(FILENAME_MAX) +# define FILENAME_MAX MAX_PATH +#endif +#if !defined(NAME_MAX) +# define NAME_MAX FILENAME_MAX +#endif + +/* Return the exact length of d_namlen without zero terminator */ +#define _D_EXACT_NAMLEN(p)((p)->d_namlen) + +/* Return number of bytes needed to store d_namlen */ +#define _D_ALLOC_NAMLEN(p)(PATH_MAX) + +/* Wide-character version */ +struct _wdirent { + long d_ino; /* Always zero */ + unsigned short d_reclen; /* Structure size */ + size_t d_namlen; /* Length of name without \0 */ + int d_type; /* File type */ + wchar_t d_name[PATH_MAX]; /* File name */ +}; +typedef struct _wdirent _wdirent; + +struct _WDIR { + struct _wdirent ent; /* Current directory entry */ + WIN32_FIND_DATAW data; /* Private file data */ + int cached; /* True if data is valid */ + HANDLE handle; /* Win32 search handle */ + wchar_t *patt; /* Initial directory name */ +}; +typedef struct _WDIR _WDIR; + +static _WDIR *_wopendir(const wchar_t *dirname); +static struct _wdirent *_wreaddir(_WDIR *dirp); +static int _wclosedir(_WDIR *dirp); +static void _wrewinddir(_WDIR* dirp); + +/* Multi-byte character versions */ +struct dirent { + long d_ino; /* Always zero */ + unsigned short d_reclen; /* Structure size */ + size_t d_namlen; /* Length of name without \0 */ + int d_type; /* File type */ + char d_name[PATH_MAX]; /* File name */ +}; +typedef struct dirent dirent; + +struct DIR { + struct dirent ent; + struct _WDIR *wdirp; +}; +typedef struct DIR DIR; + +static DIR *opendir(const char *dirname); +static struct dirent *readdir(DIR *dirp); +static int closedir(DIR *dirp); +static void rewinddir(DIR* dirp); + +/* Internal utility functions */ +static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp); +static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp); + +static int dirent_mbstowcs_s( + size_t *pReturnValue, + wchar_t *wcstr, + size_t sizeInWords, + const char *mbstr, + size_t count); + +static int dirent_wcstombs_s( + size_t *pReturnValue, + char *mbstr, + size_t sizeInBytes, + const wchar_t *wcstr, + size_t count); + +/* + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ +static _WDIR* +_wopendir(const wchar_t *dirname) +{ + _WDIR *dirp = NULL; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + _set_errno(ENOENT); + return NULL; + } + + /* Allocate new _WDIR structure */ + dirp =(_WDIR*) malloc(sizeof(struct _WDIR)); + if (dirp != NULL) { + DWORD n; + + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* Compute the length of full path plus zero terminator */ + n = GetFullPathNameW(dirname, 0, NULL, NULL); + + /* Allocate room for absolute directory name and search pattern */ + dirp->patt =(wchar_t*) malloc(sizeof(wchar_t) * n + 16); + if (dirp->patt) { + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + */ + n = GetFullPathNameW(dirname, n, dirp->patt, NULL); + if (n > 0) { + wchar_t *p; + + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + if (dirp->patt < p) { + switch(p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; + } + } + *p++ = '*'; + *p = '\0'; + + /* Open directory stream and retrieve the first entry */ + if (dirent_first(dirp)) { + /* Directory stream opened successfully */ + error = 0; + } else { + /* Cannot retrieve first entry */ + error = 1; + _set_errno(ENOENT); + } + + } else { + /* Cannot retrieve full path name */ + _set_errno(ENOENT); + error = 1; + } + + } else { + /* Cannot allocate memory for search pattern */ + error = 1; + } + + } else { + /* Cannot allocate _WDIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + _wclosedir(dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. The directory entry is returned in dirent + * structure in the d_name field. Individual directory entries returned by + * this function include regular files, sub-directories, pseudo-directories + * "." and ".." as well as volume labels, hidden files and system files. + */ +static struct _wdirent* +_wreaddir(_WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + struct _wdirent *entp; + + /* Read next directory entry */ + datap = dirent_next(dirp); + if (datap) { + size_t n; + DWORD attr; + + /* Pointer to directory entry to return */ + entp = &dirp->ent; + + /* + * Copy file name as wide-character string. If the file name is too + * long to fit in to the destination buffer, then truncate file name + * to PATH_MAX characters and zero-terminate the buffer. + */ + n = 0; + while(n + 1 < PATH_MAX && datap->cFileName[n] != 0) { + entp->d_name[n] = datap->cFileName[n]; + n++; + } + dirp->ent.d_name[n] = 0; + + /* Length of file name excluding zero terminator */ + entp->d_namlen = n; + + /* File type */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entp->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entp->d_type = DT_DIR; + } else { + entp->d_type = DT_REG; + } + + /* Reset dummy fields */ + entp->d_ino = 0; + entp->d_reclen = sizeof(struct _wdirent); + + } else { + + /* Last directory entry read */ + entp = NULL; + + } + + return entp; +} + +/* + * Close directory stream opened by opendir() function. This invalidates the + * DIR structure as well as any directory entry read previously by + * _wreaddir(). + */ +static int +_wclosedir(_WDIR *dirp) +{ + int ok; + if (dirp) { + + /* Release search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + } + + /* Release search pattern */ + if (dirp->patt) { + free(dirp->patt); + dirp->patt = NULL; + } + + /* Release directory structure */ + free(dirp); + ok = /*success*/0; + + } else { + /* Invalid directory stream */ + _set_errno(EBADF); + ok = /*failure*/-1; + } + return ok; +} + +/* + * Rewind directory stream such that _wreaddir() returns the very first + * file name again. + */ +static void +_wrewinddir(_WDIR* dirp) +{ + if (dirp) { + /* Release existing search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + } + + /* Open new search handle */ + dirent_first(dirp); + } +} + +/* Get first directory entry(internal) */ +static WIN32_FIND_DATAW* +dirent_first(_WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + + /* Open directory and retrieve the first entry */ + dirp->handle = FindFirstFileW(dirp->patt, &dirp->data); + if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* a directory entry is now waiting in memory */ + datap = &dirp->data; + dirp->cached = 1; + + } else { + + /* Failed to re-open directory: no directory entry in memory */ + dirp->cached = 0; + datap = NULL; + + } + return datap; +} + +/* Get next directory entry(internal) */ +static WIN32_FIND_DATAW* +dirent_next(_WDIR *dirp) +{ + WIN32_FIND_DATAW *p; + + /* Get next directory entry */ + if (dirp->cached != 0) { + + /* A valid directory entry already in memory */ + p = &dirp->data; + dirp->cached = 0; + + } else if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* Get the next directory entry from stream */ + if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) { + /* Got a file */ + p = &dirp->data; + } else { + /* The very last entry has been processed or an error occured */ + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + p = NULL; + } + + } else { + + /* End of directory stream reached */ + p = NULL; + + } + + return p; +} + +/* + * Open directory stream using plain old C-string. + */ +static DIR* +opendir(const char *dirname) +{ + struct DIR *dirp; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + _set_errno(ENOENT); + return NULL; + } + + /* Allocate memory for DIR structure */ + dirp =(DIR*) malloc(sizeof(struct DIR)); + if (dirp) { + wchar_t wname[PATH_MAX]; + size_t n; + + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX); + if (!error) { + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir(wname); + if (dirp->wdirp) { + /* Directory stream opened */ + error = 0; + } else { + /* Failed to open directory stream */ + error = 1; + } + + } else { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + error = 1; + } + + } else { + /* Cannot allocate DIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + free(dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. + * + * When working with text consoles, please note that file names returned by + * readdir() are represented in the default ANSI code page while any output to + * console is typically formatted on another code page. Thus, non-ASCII + * characters in file names will not usually display correctly on console. The + * problem can be fixed in two ways:(1) change the character set of console + * to 1252 using chcp utility and use Lucida Console font, or(2) use + * _cprintf function when writing to console. The _cprinf() will re-encode + * ANSI strings to the console code page so many non-ASCII characters will + * display correcly. + */ +static struct dirent* +readdir(DIR *dirp) +{ + WIN32_FIND_DATAW *datap; + struct dirent *entp; + + /* Read next directory entry */ + datap = dirent_next(dirp->wdirp); + if (datap) { + size_t n; + int error; + + /* Attempt to convert file name to multi-byte string */ + error = dirent_wcstombs_s( + &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); + + /* + * If the file name cannot be represented by a multi-byte string, + * then attempt to use old 8+3 file name. This allows traditional + * Unix-code to access some file names despite of unicode + * characters, although file names may seem unfamiliar to the user. + * + * Be ware that the code below cannot come up with a short file + * name unless the file system provides one. At least + * VirtualBox shared folders fail to do this. + */ + if (error && datap->cAlternateFileName[0] != '\0') { + error = dirent_wcstombs_s( + &n, dirp->ent.d_name, PATH_MAX, + datap->cAlternateFileName, PATH_MAX); + } + + if (!error) { + DWORD attr; + + /* Initialize directory entry for return */ + entp = &dirp->ent; + + /* Length of file name excluding zero terminator */ + entp->d_namlen = n - 1; + + /* File attributes */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entp->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entp->d_type = DT_DIR; + } else { + entp->d_type = DT_REG; + } + + /* Reset dummy fields */ + entp->d_ino = 0; + entp->d_reclen = sizeof(struct dirent); + + } else { + /* + * Cannot convert file name to multi-byte string so construct + * an errornous directory entry and return that. Note that + * we cannot return NULL as that would stop the processing + * of directory entries completely. + */ + entp = &dirp->ent; + entp->d_name[0] = '?'; + entp->d_name[1] = '\0'; + entp->d_namlen = 1; + entp->d_type = DT_UNKNOWN; + entp->d_ino = 0; + entp->d_reclen = 0; + } + + } else { + /* No more directory entries */ + entp = NULL; + } + + return entp; +} + +/* + * Close directory stream. + */ +static int +closedir(DIR *dirp) +{ + int ok; + if (dirp) { + + /* Close wide-character directory stream */ + ok = _wclosedir(dirp->wdirp); + dirp->wdirp = NULL; + + /* Release multi-byte character version */ + free(dirp); + + } else { + + /* Invalid directory stream */ + _set_errno(EBADF); + ok = /*failure*/-1; + + } + return ok; +} + +/* + * Rewind directory stream to beginning. + */ +static void +rewinddir(DIR* dirp) +{ + /* Rewind wide-character string directory stream */ + _wrewinddir(dirp->wdirp); +} + +/* Convert multi-byte string to wide character string */ +static int +dirent_mbstowcs_s(size_t *pReturnValue, wchar_t *wcstr, + size_t sizeInWords, const char *mbstr, size_t count) +{ + return mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count); +} + +/* Convert wide-character string to multi-byte string */ +static int +dirent_wcstombs_s(size_t *pReturnValue, char *mbstr, + size_t sizeInBytes, /* max size of mbstr */ + const wchar_t *wcstr, size_t count) +{ + return wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count); +} + +#endif /*DIRENT_H*/ diff --git a/Libraries/libressl/include/compat/endian.h b/Libraries/libressl/include/compat/endian.h new file mode 100644 index 000000000..d0dcfe325 --- /dev/null +++ b/Libraries/libressl/include/compat/endian.h @@ -0,0 +1,142 @@ +/* + * Public domain + * endian.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_BYTE_ORDER_H_ +#define LIBCRYPTOCOMPAT_BYTE_ORDER_H_ + +#if defined(_WIN32) + +#define LITTLE_ENDIAN 1234 +#define BIG_ENDIAN 4321 +#define PDP_ENDIAN 3412 + +/* + * Use GCC and Visual Studio compiler defines to determine endian. + */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define BYTE_ORDER LITTLE_ENDIAN +#else +#define BYTE_ORDER BIG_ENDIAN +#endif + +#elif defined(HAVE_ENDIAN_H) +#include_next + +#elif defined(HAVE_MACHINE_ENDIAN_H) +#include_next + +#elif defined(__sun) || defined(_AIX) || defined(__hpux) +#include +#include + +#elif defined(__sgi) +#include +#include + +#endif + +#ifndef __STRICT_ALIGNMENT +#define __STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || \ + defined(__x86_64__) || defined(__s390__) || defined(__s390x__) || \ + defined(__aarch64__) || \ + ((defined(__arm__) || defined(__arm)) && __ARM_ARCH >= 6) +#undef __STRICT_ALIGNMENT +#endif +#endif + +#if defined(__APPLE__) && !defined(HAVE_ENDIAN_H) +#include +#define be16toh(x) OSSwapBigToHostInt16((x)) +#define htobe16(x) OSSwapHostToBigInt16((x)) +#define le32toh(x) OSSwapLittleToHostInt32((x)) +#define be32toh(x) OSSwapBigToHostInt32((x)) +#define htole32(x) OSSwapHostToLittleInt32(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define htole64(x) OSSwapHostToLittleInt64(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) +#endif /* __APPLE__ && !HAVE_ENDIAN_H */ + +#if defined(_WIN32) && !defined(HAVE_ENDIAN_H) +#include + +#define be16toh(x) ntohs((x)) +#define htobe16(x) htons((x)) +#define le32toh(x) (x) +#define be32toh(x) ntohl((x)) +#define htole32(x) (x) +#define htobe32(x) ntohl((x)) +#define be64toh(x) ntohll((x)) + +#if !defined(ntohll) +#define ntohll(x) \ + ((1 == htonl(1)) \ + ? (x) \ + : ((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#endif +#if !defined(htonll) +#define htonll(x) \ + ((1 == ntohl(1)) \ + ? (x) \ + : ((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#endif + +#define htobe64(x) ntohll((x)) +#endif /* _WIN32 && !HAVE_ENDIAN_H */ + +#ifdef __linux__ +#if !defined(betoh16) +#define betoh16(x) be16toh(x) +#endif +#if !defined(betoh32) +#define betoh32(x) be32toh(x) +#endif +#if !defined(betoh64) +#define betoh64(x) be64toh(x) +#endif +#endif /* __linux__ */ + +#if defined(__FreeBSD__) +#if !defined(HAVE_ENDIAN_H) +#include +#endif +#if !defined(betoh16) +#define betoh16(x) be16toh(x) +#endif +#if !defined(betoh32) +#define betoh32(x) be32toh(x) +#endif +#if !defined(betoh64) +#define betoh64(x) be64toh(x) +#endif +#endif + +#if defined(__NetBSD__) +#if !defined(betoh16) +#define betoh16(x) be16toh(x) +#endif +#if !defined(betoh32) +#define betoh32(x) be32toh(x) +#endif +#if !defined(betoh64) +#define betoh64(x) be64toh(x) +#endif +#endif + +#if defined(__sun) +#include +#define be16toh(x) BE_16(x) +#define htobe16(x) BE_16(x) +#define le32toh(x) LE_32(x) +#define be32toh(x) BE_32(x) +#define htole32(x) LE_32(x) +#define htobe32(x) BE_32(x) +#define be64toh(x) BE_64(x) +#define htobe64(x) BE_64(x) +#endif + +#endif diff --git a/Libraries/libressl/include/compat/err.h b/Libraries/libressl/include/compat/err.h new file mode 100644 index 000000000..945a75d61 --- /dev/null +++ b/Libraries/libressl/include/compat/err.h @@ -0,0 +1,95 @@ +/* + * Public domain + * err.h compatibility shim + */ + +#ifdef HAVE_ERR_H + +#include_next + +#else + +#ifndef LIBCRYPTOCOMPAT_ERR_H +#define LIBCRYPTOCOMPAT_ERR_H + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +__declspec(noreturn) +#else +__attribute__((noreturn)) +#endif +static inline void +err(int eval, const char *fmt, ...) +{ + int sverrno = errno; + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + va_end(ap); + fprintf(stderr, "%s\n", strerror(sverrno)); + exit(eval); +} + +#if defined(_MSC_VER) +__declspec(noreturn) +#else +__attribute__((noreturn)) +#endif +static inline void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(eval); +} + +static inline void +warn(const char *fmt, ...) +{ + int sverrno = errno; + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + va_end(ap); + fprintf(stderr, "%s\n", strerror(sverrno)); +} + +static inline void +vwarnx(const char *fmt, va_list args) +{ + if (fmt != NULL) + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); +} + +static inline void +warnx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} + +#endif + +#endif diff --git a/Libraries/libressl/include/compat/fcntl.h b/Libraries/libressl/include/compat/fcntl.h new file mode 100644 index 000000000..7dfedc612 --- /dev/null +++ b/Libraries/libressl/include/compat/fcntl.h @@ -0,0 +1,32 @@ +/* + * Public domain + * fcntl.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/fcntl.h> +#else +#include <../include/fcntl.h> +#endif +#else +#include_next +#endif + +#endif + +#ifndef O_NONBLOCK +#define O_NONBLOCK 0x100000 +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0x200000 +#endif + +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 1 +#endif diff --git a/Libraries/libressl/include/compat/getopt.h b/Libraries/libressl/include/compat/getopt.h new file mode 100644 index 000000000..8cc3207f3 --- /dev/null +++ b/Libraries/libressl/include/compat/getopt.h @@ -0,0 +1,50 @@ +/* $OpenBSD: getopt.h,v 1.3 2013/11/22 21:32:49 millert Exp $ */ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_GETOPT + +#include_next + +#else + +#ifndef _GETOPT_DEFINED_ +#define _GETOPT_DEFINED_ +int getopt(int, char * const *, const char *); + +extern char *optarg; /* getopt(3) external variables */ +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; +#endif + +#endif /* HAVE_GETOPT */ diff --git a/Libraries/libressl/include/compat/limits.h b/Libraries/libressl/include/compat/limits.h new file mode 100644 index 000000000..73cccfc16 --- /dev/null +++ b/Libraries/libressl/include/compat/limits.h @@ -0,0 +1,25 @@ +/* + * Public domain + * limits.h compatibility shim + */ + +#ifdef _MSC_VER +#include <../include/limits.h> +#if _MSC_VER >= 1900 +#include <../ucrt/stdlib.h> +#else +#include <../include/stdlib.h> +#endif +#ifndef PATH_MAX +#define PATH_MAX _MAX_PATH +#endif +#else +#include_next +#endif + +#ifdef __hpux +#include +#ifndef PATH_MAX +#define PATH_MAX MAXPATHLEN +#endif +#endif diff --git a/Libraries/libressl/include/compat/netdb.h b/Libraries/libressl/include/compat/netdb.h new file mode 100644 index 000000000..d36b91dba --- /dev/null +++ b/Libraries/libressl/include/compat/netdb.h @@ -0,0 +1,10 @@ +/* + * Public domain + * netdb.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/Libraries/libressl/include/compat/netinet/in.h b/Libraries/libressl/include/compat/netinet/in.h new file mode 100644 index 000000000..d1afb27df --- /dev/null +++ b/Libraries/libressl/include/compat/netinet/in.h @@ -0,0 +1,19 @@ +/* + * Public domain + * netinet/in.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif + +#ifndef LIBCRYPTOCOMPAT_NETINET_IN_H +#define LIBCRYPTOCOMPAT_NETINET_IN_H + +#ifdef __ANDROID__ +typedef uint16_t in_port_t; +#endif + +#endif diff --git a/Libraries/libressl/include/compat/netinet/ip.h b/Libraries/libressl/include/compat/netinet/ip.h new file mode 100644 index 000000000..29f17f3f7 --- /dev/null +++ b/Libraries/libressl/include/compat/netinet/ip.h @@ -0,0 +1,49 @@ +/* + * Public domain + * netinet/ip.h compatibility shim + */ + +#if defined(__hpux) +#include +#endif + +#ifndef _WIN32 +#ifdef HAVE_NETINET_IP_H +#include_next +#endif +#else +#include +#endif + +/* + * Definitions for DiffServ Codepoints as per RFC2474 + */ +#ifndef IPTOS_DSCP_CS0 +#define IPTOS_DSCP_CS0 0x00 +#define IPTOS_DSCP_CS1 0x20 +#define IPTOS_DSCP_CS2 0x40 +#define IPTOS_DSCP_CS3 0x60 +#define IPTOS_DSCP_CS4 0x80 +#define IPTOS_DSCP_CS5 0xa0 +#define IPTOS_DSCP_CS6 0xc0 +#define IPTOS_DSCP_CS7 0xe0 +#endif + +#ifndef IPTOS_DSCP_AF11 +#define IPTOS_DSCP_AF11 0x28 +#define IPTOS_DSCP_AF12 0x30 +#define IPTOS_DSCP_AF13 0x38 +#define IPTOS_DSCP_AF21 0x48 +#define IPTOS_DSCP_AF22 0x50 +#define IPTOS_DSCP_AF23 0x58 +#define IPTOS_DSCP_AF31 0x68 +#define IPTOS_DSCP_AF32 0x70 +#define IPTOS_DSCP_AF33 0x78 +#define IPTOS_DSCP_AF41 0x88 +#define IPTOS_DSCP_AF42 0x90 +#define IPTOS_DSCP_AF43 0x98 +#endif + +#ifndef IPTOS_DSCP_EF +#define IPTOS_DSCP_EF 0xb8 +#endif diff --git a/Libraries/libressl/include/compat/netinet/tcp.h b/Libraries/libressl/include/compat/netinet/tcp.h new file mode 100644 index 000000000..c98cf7412 --- /dev/null +++ b/Libraries/libressl/include/compat/netinet/tcp.h @@ -0,0 +1,10 @@ +/* + * Public domain + * netinet/tcp.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/Libraries/libressl/include/compat/poll.h b/Libraries/libressl/include/compat/poll.h new file mode 100644 index 000000000..e9204cf2c --- /dev/null +++ b/Libraries/libressl/include/compat/poll.h @@ -0,0 +1,63 @@ +/* + * Public domain + * + * poll(2) emulation for Windows + * + * This emulates just-enough poll functionality on Windows to work in the + * context of the openssl(1) program. This is not a replacement for + * POSIX.1-2001 poll(2). + * + * Dongsheng Song + * Brent Cook + */ + +#ifndef LIBCRYPTOCOMPAT_POLL_H +#define LIBCRYPTOCOMPAT_POLL_H + +#ifndef _WIN32 +#include_next +#else + +#include + +/* Type used for the number of file descriptors. */ +typedef unsigned long int nfds_t; + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600) +/* Data structure describing a polling request. */ +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + +/* Event types that can be polled */ +#define POLLIN 0x001 /* There is data to read. */ +#define POLLPRI 0x002 /* There is urgent data to read. */ +#define POLLOUT 0x004 /* Writing now will not block. */ + +# define POLLRDNORM 0x040 /* Normal data may be read. */ +# define POLLRDBAND 0x080 /* Priority data may be read. */ +# define POLLWRNORM 0x100 /* Writing now will not block. */ +# define POLLWRBAND 0x200 /* Priority data may be written. */ + +/* Event types always implicitly polled. */ +#define POLLERR 0x008 /* Error condition. */ +#define POLLHUP 0x010 /* Hung up. */ +#define POLLNVAL 0x020 /* Invalid polling request. */ + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int poll(struct pollfd *pfds, nfds_t nfds, int timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_POLL */ + +#endif /* LIBCRYPTOCOMPAT_POLL_H */ diff --git a/Libraries/libressl/include/compat/pthread.h b/Libraries/libressl/include/compat/pthread.h new file mode 100644 index 000000000..1ab011c39 --- /dev/null +++ b/Libraries/libressl/include/compat/pthread.h @@ -0,0 +1,117 @@ +/* + * Public domain + * pthread.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_PTHREAD_H +#define LIBCRYPTOCOMPAT_PTHREAD_H + +#ifdef _WIN32 + +#include +#include +#include + +/* + * Static once initialization values. + */ +#define PTHREAD_ONCE_INIT { INIT_ONCE_STATIC_INIT } + +/* + * Static mutex initialization values. + */ +#define PTHREAD_MUTEX_INITIALIZER { .lock = NULL } + +/* + * Once definitions. + */ +struct pthread_once { + INIT_ONCE once; +}; +typedef struct pthread_once pthread_once_t; + +static inline BOOL CALLBACK +_pthread_once_win32_cb(PINIT_ONCE once, PVOID param, PVOID *context) +{ + void (*cb) (void) = param; + cb(); + return TRUE; +} + +static inline int +pthread_once(pthread_once_t *once, void (*cb) (void)) +{ + BOOL rc = InitOnceExecuteOnce(&once->once, _pthread_once_win32_cb, cb, NULL); + if (rc == 0) + return -1; + else + return 0; +} + +typedef DWORD pthread_t; + +static inline pthread_t +pthread_self(void) +{ + return GetCurrentThreadId(); +} + +static inline int +pthread_equal(pthread_t t1, pthread_t t2) +{ + return t1 == t2; +} + +struct pthread_mutex { + volatile LPCRITICAL_SECTION lock; +}; +typedef struct pthread_mutex pthread_mutex_t; +typedef void pthread_mutexattr_t; + +static inline int +pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + if ((mutex->lock = malloc(sizeof(CRITICAL_SECTION))) == NULL) + exit(ENOMEM); + InitializeCriticalSection(mutex->lock); + return 0; +} + +static inline int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + if (mutex->lock == NULL) { + LPCRITICAL_SECTION lcs; + + if ((lcs = malloc(sizeof(CRITICAL_SECTION))) == NULL) + exit(ENOMEM); + InitializeCriticalSection(lcs); + if (InterlockedCompareExchangePointer((PVOID*)&mutex->lock, (PVOID)lcs, NULL) != NULL) { + DeleteCriticalSection(lcs); + free(lcs); + } + } + EnterCriticalSection(mutex->lock); + return 0; +} + +static inline int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + LeaveCriticalSection(mutex->lock); + return 0; +} + +static inline int +pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + DeleteCriticalSection(mutex->lock); + free(mutex->lock); + return 0; +} + +#else +#include_next +#endif + +#endif diff --git a/Libraries/libressl/include/compat/readpassphrase.h b/Libraries/libressl/include/compat/readpassphrase.h new file mode 100644 index 000000000..341691941 --- /dev/null +++ b/Libraries/libressl/include/compat/readpassphrase.h @@ -0,0 +1,44 @@ +/* $OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $ */ + +/* + * Copyright (c) 2000, 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +#ifdef HAVE_READPASSPHRASE_H + +#include_next + +#else + +#ifndef _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ + +char * readpassphrase(const char *, char *, size_t, int); + +#endif /* !_READPASSPHRASE_H_ */ + +#endif diff --git a/Libraries/libressl/include/compat/resolv.h b/Libraries/libressl/include/compat/resolv.h new file mode 100644 index 000000000..b8044605c --- /dev/null +++ b/Libraries/libressl/include/compat/resolv.h @@ -0,0 +1,24 @@ +/* + * Public domain + * resolv.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_RESOLV_H +#define LIBCRYPTOCOMPAT_RESOLV_H + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/resolv.h> +#else +#include <../include/resolv.h> +#endif +#elif defined(HAVE_RESOLV_H) +#include_next +#endif + +#ifndef HAVE_B64_NTOP +int b64_ntop(unsigned char const *, size_t, char *, size_t); +int b64_pton(char const *, unsigned char *, size_t); +#endif + +#endif diff --git a/Libraries/libressl/include/compat/stdio.h b/Libraries/libressl/include/compat/stdio.h new file mode 100644 index 000000000..d5725c9ac --- /dev/null +++ b/Libraries/libressl/include/compat/stdio.h @@ -0,0 +1,51 @@ +/* + * Public domain + * stdio.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_STDIO_H +#define LIBCRYPTOCOMPAT_STDIO_H + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/stdlib.h> +#include <../ucrt/corecrt_io.h> +#include <../ucrt/stdio.h> +#else +#include <../include/stdio.h> +#endif +#else +#include_next +#endif + +#ifndef HAVE_ASPRINTF +#include +int vasprintf(char **str, const char *fmt, va_list ap); +int asprintf(char **str, const char *fmt, ...); +#endif + +#ifdef _WIN32 + +#if defined(_MSC_VER) +#define __func__ __FUNCTION__ +#endif + +void posix_perror(const char *s); +FILE * posix_fopen(const char *path, const char *mode); +char * posix_fgets(char *s, int size, FILE *stream); +int posix_rename(const char *oldpath, const char *newpath); + +#ifndef NO_REDEF_POSIX_FUNCTIONS +#define perror(errnum) posix_perror(errnum) +#define fopen(path, mode) posix_fopen(path, mode) +#define fgets(s, size, stream) posix_fgets(s, size, stream) +#define rename(oldpath, newpath) posix_rename(oldpath, newpath) +#endif + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#endif + +#endif diff --git a/Libraries/libressl/include/compat/stdlib.h b/Libraries/libressl/include/compat/stdlib.h new file mode 100644 index 000000000..2eaea244c --- /dev/null +++ b/Libraries/libressl/include/compat/stdlib.h @@ -0,0 +1,47 @@ +/* + * stdlib.h compatibility shim + * Public domain + */ + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/stdlib.h> +#else +#include <../include/stdlib.h> +#endif +#else +#include_next +#endif + +#ifndef LIBCRYPTOCOMPAT_STDLIB_H +#define LIBCRYPTOCOMPAT_STDLIB_H + +#include +#include + +#ifndef HAVE_ARC4RANDOM_BUF +uint32_t arc4random(void); +void arc4random_buf(void *_buf, size_t n); +uint32_t arc4random_uniform(uint32_t upper_bound); +#endif + +#ifndef HAVE_FREEZERO +void freezero(void *ptr, size_t sz); +#endif + +#ifndef HAVE_GETPROGNAME +const char * getprogname(void); +#endif + +void *reallocarray(void *, size_t, size_t); + +#ifndef HAVE_RECALLOCARRAY +void *recallocarray(void *, size_t, size_t, size_t); +#endif + +#ifndef HAVE_STRTONUM +long long strtonum(const char *nptr, long long minval, + long long maxval, const char **errstr); +#endif + +#endif diff --git a/Libraries/libressl/include/compat/string.h b/Libraries/libressl/include/compat/string.h new file mode 100644 index 000000000..4bf7519b5 --- /dev/null +++ b/Libraries/libressl/include/compat/string.h @@ -0,0 +1,87 @@ +/* + * Public domain + * string.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_STRING_H +#define LIBCRYPTOCOMPAT_STRING_H + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/string.h> +#else +#include <../include/string.h> +#endif +#else +#include_next +#endif + +#include + +#if defined(__sun) || defined(_AIX) || defined(__hpux) +/* Some functions historically defined in string.h were placed in strings.h by + * SUS. Use the same hack as OS X and FreeBSD use to work around on AIX, + * Solaris, and HPUX. + */ +#include +#endif + +#ifndef HAVE_STRCASECMP +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t len); +#endif + +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRNDUP +char * strndup(const char *str, size_t maxlen); +/* the only user of strnlen is strndup, so only build it if needed */ +#ifndef HAVE_STRNLEN +size_t strnlen(const char *str, size_t maxlen); +#endif +#endif + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif + +#ifndef HAVE_EXPLICIT_BZERO +void explicit_bzero(void *, size_t); +#endif + +#ifndef HAVE_TIMINGSAFE_BCMP +int timingsafe_bcmp(const void *b1, const void *b2, size_t n); +#endif + +#ifndef HAVE_TIMINGSAFE_MEMCMP +int timingsafe_memcmp(const void *b1, const void *b2, size_t len); +#endif + +#ifndef HAVE_MEMMEM +void * memmem(const void *big, size_t big_len, const void *little, + size_t little_len); +#endif + +#ifdef _WIN32 +#include + +static inline char * +posix_strerror(int errnum) +{ + if (errnum == ECONNREFUSED) { + return "Connection refused"; + } + return strerror(errnum); +} + +#define strerror(errnum) posix_strerror(errnum) + +#endif + +#endif diff --git a/Libraries/libressl/include/compat/sys/_null.h b/Libraries/libressl/include/compat/sys/_null.h new file mode 100644 index 000000000..5d154019b --- /dev/null +++ b/Libraries/libressl/include/compat/sys/_null.h @@ -0,0 +1,18 @@ +/* $OpenBSD: _null.h,v 1.2 2016/09/09 22:07:58 millert Exp $ */ + +/* + * Written by Todd C. Miller, September 9, 2016 + * Public domain. + */ + +#ifndef NULL +#if !defined(__cplusplus) +#define NULL ((void *)0) +#elif __cplusplus >= 201103L +#define NULL nullptr +#elif defined(__GNUG__) +#define NULL __null +#else +#define NULL 0L +#endif +#endif diff --git a/Libraries/libressl/include/compat/sys/ioctl.h b/Libraries/libressl/include/compat/sys/ioctl.h new file mode 100644 index 000000000..a255506c5 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/ioctl.h @@ -0,0 +1,11 @@ +/* + * Public domain + * sys/ioctl.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#define ioctl(fd, type, arg) ioctlsocket(fd, type, arg) +#endif diff --git a/Libraries/libressl/include/compat/sys/mman.h b/Libraries/libressl/include/compat/sys/mman.h new file mode 100644 index 000000000..d9eb6a957 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/mman.h @@ -0,0 +1,19 @@ +/* + * Public domain + * sys/mman.h compatibility shim + */ + +#include_next + +#ifndef LIBCRYPTOCOMPAT_MMAN_H +#define LIBCRYPTOCOMPAT_MMAN_H + +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#else +#error "System does not support mapping anonymous pages?" +#endif +#endif + +#endif diff --git a/Libraries/libressl/include/compat/sys/param.h b/Libraries/libressl/include/compat/sys/param.h new file mode 100644 index 000000000..70488f828 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/param.h @@ -0,0 +1,15 @@ +/* + * Public domain + * sys/param.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_PARAM_H +#define LIBCRYPTOCOMPAT_SYS_PARAM_H + +#ifdef _MSC_VER +#include +#else +#include_next +#endif + +#endif diff --git a/Libraries/libressl/include/compat/sys/queue.h b/Libraries/libressl/include/compat/sys/queue.h new file mode 100644 index 000000000..f28ba8946 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/queue.h @@ -0,0 +1,536 @@ +/* $OpenBSD: queue.h,v 1.45 2018/07/12 14:22:54 sashan Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#include + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues and XOR simple queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * An XOR simple queue is used in the same way as a regular simple queue. + * The difference is that the head structure also includes a "cookie" that + * is XOR'd with the queue pointer (first, last or next) to generate the + * real pointer value. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) +#define _Q_INVALID ((void *)-1) +#define _Q_INVALIDATE(a) (a) = _Q_INVALID +#else +#define _Q_INVALIDATE(a) +#endif + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST(head); \ + (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ + (var) = (tvar)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \ + (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->slh_first; \ + \ + while (curelm->field.sle_next != (elm)) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ + _Q_INVALIDATE((elm)->field.sle_next); \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List access methods. + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \ + for((var) = LIST_FIRST(head); \ + (var)!= LIST_END(head); \ + (var) = LIST_NEXT(var, field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST(head); \ + (var) && ((tvar) = LIST_NEXT(var, field), 1); \ + (var) = (tvar)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \ + LIST_FIRST(head) = LIST_END(head); \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ + _Q_INVALIDATE((elm)->field.le_prev); \ + _Q_INVALIDATE((elm)->field.le_next); \ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ + (elm2)->field.le_next->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ + _Q_INVALIDATE((elm)->field.le_prev); \ + _Q_INVALIDATE((elm)->field.le_next); \ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SIMPLEQ_FIRST(head); \ + (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ + (var) = (tvar)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ + if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ + == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_CONCAT(head1, head2) do { \ + if (!SIMPLEQ_EMPTY((head2))) { \ + *(head1)->sqh_last = (head2)->sqh_first; \ + (head1)->sqh_last = (head2)->sqh_last; \ + SIMPLEQ_INIT((head2)); \ + } \ +} while (0) + +/* + * XOR Simple queue definitions. + */ +#define XSIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqx_first; /* first element */ \ + struct type **sqx_last; /* addr of last next element */ \ + unsigned long sqx_cookie; \ +} + +#define XSIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqx_next; /* next element */ \ +} + +/* + * XOR Simple queue access methods. + */ +#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \ + (unsigned long)(ptr))) +#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first)) +#define XSIMPLEQ_END(head) NULL +#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head)) +#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next)) + + +#define XSIMPLEQ_FOREACH(var, head, field) \ + for ((var) = XSIMPLEQ_FIRST(head); \ + (var) != XSIMPLEQ_END(head); \ + (var) = XSIMPLEQ_NEXT(head, var, field)) + +#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = XSIMPLEQ_FIRST(head); \ + (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \ + (var) = (tvar)) + +/* + * XOR Simple queue functions. + */ +#define XSIMPLEQ_INIT(head) do { \ + arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \ + (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ +} while (0) + +#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqx_next = (head)->sqx_first) == \ + XSIMPLEQ_XOR(head, NULL)) \ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ + (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \ +} while (0) + +#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \ + *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ +} while (0) + +#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \ + XSIMPLEQ_XOR(head, NULL)) \ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ + (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \ +} while (0) + +#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqx_first = XSIMPLEQ_XOR(head, \ + (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ +} while (0) + +#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ + if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \ + (elm)->field.sqx_next)->field.sqx_next) \ + == XSIMPLEQ_XOR(head, NULL)) \ + (head)->sqx_last = \ + XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ +} while (0) + + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue access methods. + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head) && \ + ((tvar) = TAILQ_NEXT(var, field), 1); \ + (var) = (tvar)) + + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head) && \ + ((tvar) = TAILQ_PREV(var, headname, field), 1); \ + (var) = (tvar)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ + _Q_INVALIDATE((elm)->field.tqe_prev); \ + _Q_INVALIDATE((elm)->field.tqe_next); \ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ + _Q_INVALIDATE((elm)->field.tqe_prev); \ + _Q_INVALIDATE((elm)->field.tqe_next); \ +} while (0) + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + } \ +} while (0) + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/Libraries/libressl/include/compat/sys/select.h b/Libraries/libressl/include/compat/sys/select.h new file mode 100644 index 000000000..5ca0ea156 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/select.h @@ -0,0 +1,10 @@ +/* + * Public domain + * sys/select.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/Libraries/libressl/include/compat/sys/socket.h b/Libraries/libressl/include/compat/sys/socket.h new file mode 100644 index 000000000..2f0b197b3 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/socket.h @@ -0,0 +1,18 @@ +/* + * Public domain + * sys/socket.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif + +#if !defined(SOCK_NONBLOCK) || !defined(SOCK_CLOEXEC) +#define NEED_SOCKET_FLAGS +#define SOCK_CLOEXEC 0x8000 /* set FD_CLOEXEC */ +#define SOCK_NONBLOCK 0x4000 /* set O_NONBLOCK */ +int bsd_socketpair(int domain, int type, int protocol, int socket_vector[2]); +#define socketpair(d,t,p,sv) bsd_socketpair(d,t,p,sv) +#endif diff --git a/Libraries/libressl/include/compat/sys/stat.h b/Libraries/libressl/include/compat/sys/stat.h new file mode 100644 index 000000000..b88da1d56 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/stat.h @@ -0,0 +1,121 @@ +/* + * Public domain + * sys/stat.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_STAT_H +#define LIBCRYPTOCOMPAT_SYS_STAT_H + +#ifndef _MSC_VER +#include_next + +/* for old MinGW */ +#ifndef S_IRWXU +#define S_IRWXU 0 +#endif +#ifndef S_IRWXG +#define S_IRWXG 0 +#endif +#ifndef S_IRGRP +#define S_IRGRP 0 +#endif +#ifndef S_IRWXO +#define S_IRWXO 0 +#endif +#ifndef S_IROTH +#define S_IROTH 0 +#endif + +#else + +#include +#if _MSC_VER >= 1900 +#include <../ucrt/sys/stat.h> +#else +#include <../include/sys/stat.h> +#endif + +/* File type and permission flags for stat() */ +#if !defined(S_IFMT) +# define S_IFMT _S_IFMT /* File type mask */ +#endif +#if !defined(S_IFDIR) +# define S_IFDIR _S_IFDIR /* Directory */ +#endif +#if !defined(S_IFCHR) +# define S_IFCHR _S_IFCHR /* Character device */ +#endif +#if !defined(S_IFFIFO) +# define S_IFFIFO _S_IFFIFO /* Pipe */ +#endif +#if !defined(S_IFREG) +# define S_IFREG _S_IFREG /* Regular file */ +#endif +#if !defined(S_IREAD) +# define S_IREAD _S_IREAD /* Read permission */ +#endif +#if !defined(S_IWRITE) +# define S_IWRITE _S_IWRITE /* Write permission */ +#endif +#if !defined(S_IEXEC) +# define S_IEXEC _S_IEXEC /* Execute permission */ +#endif +#if !defined(S_IFIFO) +# define S_IFIFO _S_IFIFO /* Pipe */ +#endif +#if !defined(S_IFBLK) +# define S_IFBLK 0 /* Block device */ +#endif +#if !defined(S_IFLNK) +# define S_IFLNK 0 /* Link */ +#endif +#if !defined(S_IFSOCK) +# define S_IFSOCK 0 /* Socket */ +#endif + +#if defined(_MSC_VER) +# define S_IRWXU 0 /* RWX user */ +# define S_IRUSR S_IREAD /* Read user */ +# define S_IWUSR S_IWRITE /* Write user */ +# define S_IXUSR 0 /* Execute user */ +# define S_IRWXG 0 /* RWX group */ +# define S_IRGRP 0 /* Read group */ +# define S_IWGRP 0 /* Write group */ +# define S_IXGRP 0 /* Execute group */ +# define S_IRWXO 0 /* RWX others */ +# define S_IROTH 0 /* Read others */ +# define S_IWOTH 0 /* Write others */ +# define S_IXOTH 0 /* Execute others */ +#endif + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK +#define DT_LNK S_IFLNK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) + +#endif + +#endif diff --git a/Libraries/libressl/include/compat/sys/time.h b/Libraries/libressl/include/compat/sys/time.h new file mode 100644 index 000000000..76428c190 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/time.h @@ -0,0 +1,28 @@ +/* + * Public domain + * sys/time.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_TIME_H +#define LIBCRYPTOCOMPAT_SYS_TIME_H + +#ifdef _MSC_VER +#include +int gettimeofday(struct timeval *tp, void *tzp); +#else +#include_next +#endif + +#ifndef timersub +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +#endif diff --git a/Libraries/libressl/include/compat/sys/tree.h b/Libraries/libressl/include/compat/sys/tree.h new file mode 100644 index 000000000..ffcac9023 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/tree.h @@ -0,0 +1,1006 @@ +/* $OpenBSD: tree.h,v 1.29 2017/07/30 19:27:20 deraadt Exp $ */ +/* + * Copyright 2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_TREE_H_ +#define _SYS_TREE_H_ + +#include + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __unused __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __unused __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __unused __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while ((__comp = (cmp)(elm, (head)->sph_root))) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while (1) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-black tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) do {} while (0) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_PREV(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +attr void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)))\ + RB_COLOR(oleft, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)))\ + RB_COLOR(oright, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +attr struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field))) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old)\ + RB_LEFT(RB_PARENT(old, field), field) = elm;\ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm;\ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field))); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +attr struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +attr struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ + (x) = (y)) + + +/* + * Copyright (c) 2016 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct rb_type { + int (*t_compare)(const void *, const void *); + void (*t_augment)(void *); + unsigned int t_offset; /* offset of rb_entry in type */ +}; + +struct rb_tree { + struct rb_entry *rbt_root; +}; + +struct rb_entry { + struct rb_entry *rbt_parent; + struct rb_entry *rbt_left; + struct rb_entry *rbt_right; + unsigned int rbt_color; +}; + +#define RBT_HEAD(_name, _type) \ +struct _name { \ + struct rb_tree rbh_root; \ +} + +#define RBT_ENTRY(_type) struct rb_entry + +static inline void +_rb_init(struct rb_tree *rbt) +{ + rbt->rbt_root = NULL; +} + +static inline int +_rb_empty(struct rb_tree *rbt) +{ + return (rbt->rbt_root == NULL); +} + +void *_rb_insert(const struct rb_type *, struct rb_tree *, void *); +void *_rb_remove(const struct rb_type *, struct rb_tree *, void *); +void *_rb_find(const struct rb_type *, struct rb_tree *, const void *); +void *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *); +void *_rb_root(const struct rb_type *, struct rb_tree *); +void *_rb_min(const struct rb_type *, struct rb_tree *); +void *_rb_max(const struct rb_type *, struct rb_tree *); +void *_rb_next(const struct rb_type *, void *); +void *_rb_prev(const struct rb_type *, void *); +void *_rb_left(const struct rb_type *, void *); +void *_rb_right(const struct rb_type *, void *); +void *_rb_parent(const struct rb_type *, void *); +void _rb_set_left(const struct rb_type *, void *, void *); +void _rb_set_right(const struct rb_type *, void *, void *); +void _rb_set_parent(const struct rb_type *, void *, void *); +void _rb_poison(const struct rb_type *, void *, unsigned long); +int _rb_check(const struct rb_type *, void *, unsigned long); + +#define RBT_INITIALIZER(_head) { { NULL } } + +#define RBT_PROTOTYPE(_name, _type, _field, _cmp) \ +extern const struct rb_type *const _name##_RBT_TYPE; \ + \ +__unused static inline void \ +_name##_RBT_INIT(struct _name *head) \ +{ \ + _rb_init(&head->rbh_root); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_INSERT(struct _name *head, struct _type *elm) \ +{ \ + return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_REMOVE(struct _name *head, struct _type *elm) \ +{ \ + return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_FIND(struct _name *head, const struct _type *key) \ +{ \ + return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_NFIND(struct _name *head, const struct _type *key) \ +{ \ + return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_ROOT(struct _name *head) \ +{ \ + return _rb_root(_name##_RBT_TYPE, &head->rbh_root); \ +} \ + \ +__unused static inline int \ +_name##_RBT_EMPTY(struct _name *head) \ +{ \ + return _rb_empty(&head->rbh_root); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_MIN(struct _name *head) \ +{ \ + return _rb_min(_name##_RBT_TYPE, &head->rbh_root); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_MAX(struct _name *head) \ +{ \ + return _rb_max(_name##_RBT_TYPE, &head->rbh_root); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_NEXT(struct _type *elm) \ +{ \ + return _rb_next(_name##_RBT_TYPE, elm); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_PREV(struct _type *elm) \ +{ \ + return _rb_prev(_name##_RBT_TYPE, elm); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_LEFT(struct _type *elm) \ +{ \ + return _rb_left(_name##_RBT_TYPE, elm); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_RIGHT(struct _type *elm) \ +{ \ + return _rb_right(_name##_RBT_TYPE, elm); \ +} \ + \ +__unused static inline struct _type * \ +_name##_RBT_PARENT(struct _type *elm) \ +{ \ + return _rb_parent(_name##_RBT_TYPE, elm); \ +} \ + \ +__unused static inline void \ +_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left) \ +{ \ + return _rb_set_left(_name##_RBT_TYPE, elm, left); \ +} \ + \ +__unused static inline void \ +_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right) \ +{ \ + return _rb_set_right(_name##_RBT_TYPE, elm, right); \ +} \ + \ +__unused static inline void \ +_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent) \ +{ \ + return _rb_set_parent(_name##_RBT_TYPE, elm, parent); \ +} \ + \ +__unused static inline void \ +_name##_RBT_POISON(struct _type *elm, unsigned long poison) \ +{ \ + return _rb_poison(_name##_RBT_TYPE, elm, poison); \ +} \ + \ +__unused static inline int \ +_name##_RBT_CHECK(struct _type *elm, unsigned long poison) \ +{ \ + return _rb_check(_name##_RBT_TYPE, elm, poison); \ +} + +#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \ +static int \ +_name##_RBT_COMPARE(const void *lptr, const void *rptr) \ +{ \ + const struct _type *l = lptr, *r = rptr; \ + return _cmp(l, r); \ +} \ +static const struct rb_type _name##_RBT_INFO = { \ + _name##_RBT_COMPARE, \ + _aug, \ + offsetof(struct _type, _field), \ +}; \ +const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO + +#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \ +static void \ +_name##_RBT_AUGMENT(void *ptr) \ +{ \ + struct _type *p = ptr; \ + return _aug(p); \ +} \ +RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT) + +#define RBT_GENERATE(_name, _type, _field, _cmp) \ + RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL) + +#define RBT_INIT(_name, _head) _name##_RBT_INIT(_head) +#define RBT_INSERT(_name, _head, _elm) _name##_RBT_INSERT(_head, _elm) +#define RBT_REMOVE(_name, _head, _elm) _name##_RBT_REMOVE(_head, _elm) +#define RBT_FIND(_name, _head, _key) _name##_RBT_FIND(_head, _key) +#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key) +#define RBT_ROOT(_name, _head) _name##_RBT_ROOT(_head) +#define RBT_EMPTY(_name, _head) _name##_RBT_EMPTY(_head) +#define RBT_MIN(_name, _head) _name##_RBT_MIN(_head) +#define RBT_MAX(_name, _head) _name##_RBT_MAX(_head) +#define RBT_NEXT(_name, _elm) _name##_RBT_NEXT(_elm) +#define RBT_PREV(_name, _elm) _name##_RBT_PREV(_elm) +#define RBT_LEFT(_name, _elm) _name##_RBT_LEFT(_elm) +#define RBT_RIGHT(_name, _elm) _name##_RBT_RIGHT(_elm) +#define RBT_PARENT(_name, _elm) _name##_RBT_PARENT(_elm) +#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l) +#define RBT_SET_RIGHT(_name, _elm, _r) _name##_RBT_SET_RIGHT(_elm, _r) +#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p) +#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p) +#define RBT_CHECK(_name, _elm, _p) _name##_RBT_CHECK(_elm, _p) + +#define RBT_FOREACH(_e, _name, _head) \ + for ((_e) = RBT_MIN(_name, (_head)); \ + (_e) != NULL; \ + (_e) = RBT_NEXT(_name, (_e))) + +#define RBT_FOREACH_SAFE(_e, _name, _head, _n) \ + for ((_e) = RBT_MIN(_name, (_head)); \ + (_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \ + (_e) = (_n)) + +#define RBT_FOREACH_REVERSE(_e, _name, _head) \ + for ((_e) = RBT_MAX(_name, (_head)); \ + (_e) != NULL; \ + (_e) = RBT_PREV(_name, (_e))) + +#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \ + for ((_e) = RBT_MAX(_name, (_head)); \ + (_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \ + (_e) = (_n)) + +#endif /* _SYS_TREE_H_ */ diff --git a/Libraries/libressl/include/compat/sys/types.h b/Libraries/libressl/include/compat/sys/types.h new file mode 100644 index 000000000..59664bcf9 --- /dev/null +++ b/Libraries/libressl/include/compat/sys/types.h @@ -0,0 +1,69 @@ +/* + * Public domain + * sys/types.h compatibility shim + */ + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/sys/types.h> +#else +#include <../include/sys/types.h> +#endif +#else +#include_next +#endif + +#ifndef LIBCRYPTOCOMPAT_SYS_TYPES_H +#define LIBCRYPTOCOMPAT_SYS_TYPES_H + +#include + +#ifdef __MINGW32__ +#include <_bsd_types.h> +typedef uint32_t in_addr_t; +typedef uint32_t uid_t; +#endif + +#ifdef _MSC_VER +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef uint32_t in_addr_t; +typedef uint32_t mode_t; +typedef uint32_t uid_t; + +#include +typedef SSIZE_T ssize_t; + +#ifndef SSIZE_MAX +#ifdef _WIN64 +#define SSIZE_MAX _I64_MAX +#else +#define SSIZE_MAX INT_MAX +#endif +#endif + +#endif + +#ifdef _WIN32 +#define __warn_references(sym,msg) +#else + +#ifndef __warn_references + +#ifndef __STRING +#define __STRING(x) #x +#endif + +#if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG) +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning." __STRING(sym) \ + "\n\t.ascii \"" msg "\"\n\t.text"); +#else +#define __warn_references(sym,msg) +#endif + +#endif /* __warn_references */ +#endif /* _WIN32 */ + +#endif diff --git a/Libraries/libressl/include/compat/sys/uio.h b/Libraries/libressl/include/compat/sys/uio.h new file mode 100644 index 000000000..b4aee9e3b --- /dev/null +++ b/Libraries/libressl/include/compat/sys/uio.h @@ -0,0 +1,17 @@ +/* + * Public domain + * sys/select.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else + +#include + +struct iovec { + void *iov_base; + size_t iov_len; +}; + +#endif diff --git a/Libraries/libressl/include/compat/syslog.h b/Libraries/libressl/include/compat/syslog.h new file mode 100644 index 000000000..f400ff66d --- /dev/null +++ b/Libraries/libressl/include/compat/syslog.h @@ -0,0 +1,37 @@ +/* + * Public domain + * syslog.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#endif + +#ifndef LIBCRYPTOCOMPAT_SYSLOG_H +#define LIBCRYPTOCOMPAT_SYSLOG_H + +#ifndef HAVE_SYSLOG_R + +#include + +#ifdef _WIN32 +#define LOG_INFO 6 /* informational */ +#define LOG_USER (1<<3) /* random user-level messages */ +#define LOG_LOCAL2 (18<<3) /* reserved for local use */ +#endif + +struct syslog_data { + int log_stat; + const char *log_tag; + int log_fac; + int log_mask; +}; + +#define SYSLOG_DATA_INIT {0, (const char *)0, LOG_USER, 0xff} + +void syslog_r(int, struct syslog_data *, const char *, ...); +void vsyslog_r(int, struct syslog_data *, const char *, va_list); + +#endif + +#endif diff --git a/Libraries/libressl/include/compat/time.h b/Libraries/libressl/include/compat/time.h new file mode 100644 index 000000000..27485218f --- /dev/null +++ b/Libraries/libressl/include/compat/time.h @@ -0,0 +1,68 @@ +/* + * Public domain + * sys/time.h compatibility shim + */ + +#ifndef SIZEOF_TIME_T +#ifdef SMALL_TIME_T +#define SIZEOF_TIME_T 4 +#else +#define SIZEOF_TIME_T 8 +#endif +#endif + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/time.h> +#else +#include <../include/time.h> +#endif +#else +#include_next +#endif + +#ifndef LIBCRYPTOCOMPAT_TIME_H +#define LIBCRYPTOCOMPAT_TIME_H + +#ifdef _WIN32 +struct tm *__gmtime_r(const time_t * t, struct tm * tm); +#define gmtime_r(tp, tm) __gmtime_r(tp, tm) +#endif + +#ifndef HAVE_TIMEGM +time_t timegm(struct tm *tm); +#endif + +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC CLOCK_REALTIME +#endif + +#ifndef CLOCK_REALTIME +#define CLOCK_REALTIME 0 +#endif + +#ifndef _WIN32 +#ifndef HAVE_CLOCK_GETTIME +typedef int clockid_t; +int clock_gettime(clockid_t clock_id, struct timespec *tp); +#endif + +#ifdef timespecsub +#define HAVE_TIMESPECSUB +#endif + +#ifndef HAVE_TIMESPECSUB +#define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while (0) +#endif + +#endif + +#endif diff --git a/Libraries/libressl/include/compat/unistd.h b/Libraries/libressl/include/compat/unistd.h new file mode 100644 index 000000000..63c07fc3d --- /dev/null +++ b/Libraries/libressl/include/compat/unistd.h @@ -0,0 +1,83 @@ +/* + * Public domain + * unistd.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_UNISTD_H +#define LIBCRYPTOCOMPAT_UNISTD_H + +#ifndef _MSC_VER + +#include_next + +#ifdef __MINGW32__ +int ftruncate(int fd, off_t length); +uid_t getuid(void); +ssize_t pread(int d, void *buf, size_t nbytes, off_t offset); +ssize_t pwrite(int d, const void *buf, size_t nbytes, off_t offset); +#endif + +#else + +#include +#include +#include + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#define R_OK 4 +#define W_OK 2 +#define X_OK 0 +#define F_OK 0 + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define access _access + +#ifdef _MSC_VER +#include +static inline unsigned int sleep(unsigned int seconds) +{ + Sleep(seconds * 1000); + return seconds; +} +#endif + +int ftruncate(int fd, off_t length); +uid_t getuid(void); +ssize_t pread(int d, void *buf, size_t nbytes, off_t offset); +ssize_t pwrite(int d, const void *buf, size_t nbytes, off_t offset); + +#endif + +#ifndef HAVE_GETENTROPY +int getentropy(void *buf, size_t buflen); +#else +/* + * Solaris 11.3 adds getentropy(2), but defines the function in sys/random.h + */ +#if defined(__sun) +#include +#endif +#endif + +#ifndef HAVE_GETOPT +#include "getopt.h" +#endif + +#ifndef HAVE_GETPAGESIZE +int getpagesize(void); +#endif + +#define pledge(request, paths) 0 +#define unveil(path, permissions) 0 + +#ifndef HAVE_PIPE2 +int pipe2(int fildes[2], int flags); +#endif + +#endif diff --git a/Libraries/libressl/include/compat/win32netcompat.h b/Libraries/libressl/include/compat/win32netcompat.h new file mode 100644 index 000000000..eabebe973 --- /dev/null +++ b/Libraries/libressl/include/compat/win32netcompat.h @@ -0,0 +1,57 @@ +/* + * Public domain + * + * BSD socket emulation code for Winsock2 + * Brent Cook + */ + +#ifndef LIBCRYPTOCOMPAT_WIN32NETCOMPAT_H +#define LIBCRYPTOCOMPAT_WIN32NETCOMPAT_H + +#ifdef _WIN32 + +#include +#include +#include + +#ifndef SHUT_RDWR +#define SHUT_RDWR SD_BOTH +#endif +#ifndef SHUT_RD +#define SHUT_RD SD_RECEIVE +#endif +#ifndef SHUT_WR +#define SHUT_WR SD_SEND +#endif + +int posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +int posix_open(const char *path, ...); + +int posix_close(int fd); + +ssize_t posix_read(int fd, void *buf, size_t count); + +ssize_t posix_write(int fd, const void *buf, size_t count); + +int posix_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen); + +int posix_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen); + +#ifndef NO_REDEF_POSIX_FUNCTIONS +#define connect(sockfd, addr, addrlen) posix_connect(sockfd, addr, addrlen) +#define open(path, ...) posix_open(path, __VA_ARGS__) +#define close(fd) posix_close(fd) +#define read(fd, buf, count) posix_read(fd, buf, count) +#define write(fd, buf, count) posix_write(fd, buf, count) +#define getsockopt(sockfd, level, optname, optval, optlen) \ + posix_getsockopt(sockfd, level, optname, optval, optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) \ + posix_setsockopt(sockfd, level, optname, optval, optlen) +#endif + +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/Makefile.am b/Libraries/libressl/include/openssl/Makefile.am new file mode 100644 index 000000000..fbb21e5de --- /dev/null +++ b/Libraries/libressl/include/openssl/Makefile.am @@ -0,0 +1,115 @@ +include $(top_srcdir)/Makefile.am.common + +if !ENABLE_LIBTLS_ONLY +opensslincludedir=$(includedir)/openssl + +BUILT_SOURCES = opensslconf.h +CLEANFILES = opensslconf.h + +opensslconf.h: Makefile + -echo "generating opensslconf.h ..." +if HOST_AARCH64 + -cp $(top_srcdir)/include/arch/aarch64/opensslconf.h opensslconf.h +endif +if HOST_ARM + -cp $(top_srcdir)/include/arch/arm/opensslconf.h opensslconf.h +endif +if HOST_I386 + -cp $(top_srcdir)/include/arch/i386/opensslconf.h opensslconf.h +endif +if HOST_MIPS + -cp $(top_srcdir)/include/arch/mips/opensslconf.h opensslconf.h +endif +if HOST_MIPS64 + -cp $(top_srcdir)/include/arch/mips64/opensslconf.h opensslconf.h +endif +if HOST_POWERPC + -cp $(top_srcdir)/include/arch/powerpc/opensslconf.h opensslconf.h +endif +if HOST_POWERPC64 + -cp $(top_srcdir)/include/arch/powerpc64/opensslconf.h opensslconf.h +endif +if HOST_RISCV64 + -cp $(top_srcdir)/include/arch/riscv64/opensslconf.h opensslconf.h +endif +if HOST_SPARC64 + -cp $(top_srcdir)/include/arch/sparc64/opensslconf.h opensslconf.h +endif +if HOST_X86_64 + -cp $(top_srcdir)/include/arch/amd64/opensslconf.h opensslconf.h +endif + +opensslinclude_HEADERS = opensslconf.h +opensslinclude_HEADERS += aes.h +opensslinclude_HEADERS += asn1.h +opensslinclude_HEADERS += asn1t.h +opensslinclude_HEADERS += bio.h +opensslinclude_HEADERS += blowfish.h +opensslinclude_HEADERS += bn.h +opensslinclude_HEADERS += buffer.h +opensslinclude_HEADERS += camellia.h +opensslinclude_HEADERS += cast.h +opensslinclude_HEADERS += chacha.h +opensslinclude_HEADERS += cmac.h +opensslinclude_HEADERS += cms.h +opensslinclude_HEADERS += comp.h +opensslinclude_HEADERS += conf.h +opensslinclude_HEADERS += conf_api.h +opensslinclude_HEADERS += crypto.h +opensslinclude_HEADERS += ct.h +opensslinclude_HEADERS += curve25519.h +opensslinclude_HEADERS += des.h +opensslinclude_HEADERS += dh.h +opensslinclude_HEADERS += dsa.h +opensslinclude_HEADERS += dtls1.h +opensslinclude_HEADERS += ec.h +opensslinclude_HEADERS += ecdh.h +opensslinclude_HEADERS += ecdsa.h +opensslinclude_HEADERS += engine.h +opensslinclude_HEADERS += err.h +opensslinclude_HEADERS += evp.h +opensslinclude_HEADERS += gost.h +opensslinclude_HEADERS += hkdf.h +opensslinclude_HEADERS += hmac.h +opensslinclude_HEADERS += idea.h +opensslinclude_HEADERS += kdf.h +opensslinclude_HEADERS += lhash.h +opensslinclude_HEADERS += md4.h +opensslinclude_HEADERS += md5.h +opensslinclude_HEADERS += modes.h +opensslinclude_HEADERS += obj_mac.h +opensslinclude_HEADERS += objects.h +opensslinclude_HEADERS += ocsp.h +opensslinclude_HEADERS += opensslfeatures.h +opensslinclude_HEADERS += opensslv.h +opensslinclude_HEADERS += ossl_typ.h +opensslinclude_HEADERS += pem.h +opensslinclude_HEADERS += pem2.h +opensslinclude_HEADERS += pkcs12.h +opensslinclude_HEADERS += pkcs7.h +opensslinclude_HEADERS += poly1305.h +opensslinclude_HEADERS += rand.h +opensslinclude_HEADERS += rc2.h +opensslinclude_HEADERS += rc4.h +opensslinclude_HEADERS += ripemd.h +opensslinclude_HEADERS += rsa.h +opensslinclude_HEADERS += safestack.h +opensslinclude_HEADERS += sha.h +opensslinclude_HEADERS += sm3.h +opensslinclude_HEADERS += sm4.h +opensslinclude_HEADERS += srtp.h +opensslinclude_HEADERS += ssl.h +opensslinclude_HEADERS += ssl2.h +opensslinclude_HEADERS += ssl23.h +opensslinclude_HEADERS += ssl3.h +opensslinclude_HEADERS += stack.h +opensslinclude_HEADERS += tls1.h +opensslinclude_HEADERS += ts.h +opensslinclude_HEADERS += txt_db.h +opensslinclude_HEADERS += ui.h +opensslinclude_HEADERS += ui_compat.h +opensslinclude_HEADERS += whrlpool.h +opensslinclude_HEADERS += x509.h +opensslinclude_HEADERS += x509_vfy.h +opensslinclude_HEADERS += x509v3.h +endif diff --git a/Libraries/libressl/include/openssl/Makefile.in b/Libraries/libressl/include/openssl/Makefile.in new file mode 100644 index 000000000..ac556f983 --- /dev/null +++ b/Libraries/libressl/include/openssl/Makefile.in @@ -0,0 +1,628 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/openssl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_add_fortify_source.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/check-hardening-options.m4 \ + $(top_srcdir)/m4/check-libc.m4 \ + $(top_srcdir)/m4/check-os-options.m4 \ + $(top_srcdir)/m4/disable-compiler-warnings.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__opensslinclude_HEADERS_DIST) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__opensslinclude_HEADERS_DIST = opensslconf.h aes.h asn1.h asn1t.h \ + bio.h blowfish.h bn.h buffer.h camellia.h cast.h chacha.h \ + cmac.h cms.h comp.h conf.h conf_api.h crypto.h ct.h \ + curve25519.h des.h dh.h dsa.h dtls1.h ec.h ecdh.h ecdsa.h \ + engine.h err.h evp.h gost.h hkdf.h hmac.h idea.h kdf.h lhash.h \ + md4.h md5.h modes.h obj_mac.h objects.h ocsp.h \ + opensslfeatures.h opensslv.h ossl_typ.h pem.h pem2.h pkcs12.h \ + pkcs7.h poly1305.h rand.h rc2.h rc4.h ripemd.h rsa.h \ + safestack.h sha.h sm3.h sm4.h srtp.h ssl.h ssl2.h ssl23.h \ + ssl3.h stack.h tls1.h ts.h txt_db.h ui.h ui_compat.h \ + whrlpool.h x509.h x509_vfy.h x509v3.h +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(opensslincludedir)" +HEADERS = $(opensslinclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.common +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTO_VERSION = @LIBCRYPTO_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSL_VERSION = @LIBSSL_VERSION@ +LIBTLS_VERSION = @LIBTLS_VERSION@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSLDIR = @OPENSSLDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_LDADD = @PLATFORM_LDADD@ +PROG_LDADD = @PROG_LDADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(abs_top_builddir)/include \ + -I$(top_srcdir)/include/compat -DLIBRESSL_INTERNAL \ + -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= +@ENABLE_LIBTLS_ONLY_FALSE@opensslincludedir = $(includedir)/openssl +@ENABLE_LIBTLS_ONLY_FALSE@BUILT_SOURCES = opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@CLEANFILES = opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@opensslinclude_HEADERS = opensslconf.h aes.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ asn1.h asn1t.h bio.h blowfish.h bn.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ buffer.h camellia.h cast.h chacha.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ cmac.h cms.h comp.h conf.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ conf_api.h crypto.h ct.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ curve25519.h des.h dh.h dsa.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ dtls1.h ec.h ecdh.h ecdsa.h engine.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ err.h evp.h gost.h hkdf.h hmac.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ idea.h kdf.h lhash.h md4.h md5.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ modes.h obj_mac.h objects.h ocsp.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ opensslfeatures.h opensslv.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ ossl_typ.h pem.h pem2.h pkcs12.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ pkcs7.h poly1305.h rand.h rc2.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ rc4.h ripemd.h rsa.h safestack.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ sha.h sm3.h sm4.h srtp.h ssl.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ ssl2.h ssl23.h ssl3.h stack.h tls1.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ ts.h txt_db.h ui.h ui_compat.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ whrlpool.h x509.h x509_vfy.h \ +@ENABLE_LIBTLS_ONLY_FALSE@ x509v3.h +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/openssl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/openssl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.am.common $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-opensslincludeHEADERS: $(opensslinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(opensslinclude_HEADERS)'; test -n "$(opensslincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(opensslincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(opensslincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(opensslincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(opensslincludedir)" || exit $$?; \ + done + +uninstall-opensslincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(opensslinclude_HEADERS)'; test -n "$(opensslincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(opensslincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(opensslincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-opensslincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-opensslincludeHEADERS + +.MAKE: all check install install-am install-exec install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man \ + install-opensslincludeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-opensslincludeHEADERS + +.PRECIOUS: Makefile + + +@ENABLE_LIBTLS_ONLY_FALSE@opensslconf.h: Makefile +@ENABLE_LIBTLS_ONLY_FALSE@ -echo "generating opensslconf.h ..." +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_AARCH64_TRUE@ -cp $(top_srcdir)/include/arch/aarch64/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_ARM_TRUE@ -cp $(top_srcdir)/include/arch/arm/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_I386_TRUE@ -cp $(top_srcdir)/include/arch/i386/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_MIPS_TRUE@ -cp $(top_srcdir)/include/arch/mips/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_MIPS64_TRUE@ -cp $(top_srcdir)/include/arch/mips64/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_POWERPC_TRUE@ -cp $(top_srcdir)/include/arch/powerpc/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_POWERPC64_TRUE@ -cp $(top_srcdir)/include/arch/powerpc64/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_RISCV64_TRUE@ -cp $(top_srcdir)/include/arch/riscv64/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_SPARC64_TRUE@ -cp $(top_srcdir)/include/arch/sparc64/opensslconf.h opensslconf.h +@ENABLE_LIBTLS_ONLY_FALSE@@HOST_X86_64_TRUE@ -cp $(top_srcdir)/include/arch/amd64/opensslconf.h opensslconf.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Libraries/libressl/include/openssl/aes.h b/Libraries/libressl/include/openssl/aes.h new file mode 100644 index 000000000..702873e11 --- /dev/null +++ b/Libraries/libressl/include/openssl/aes.h @@ -0,0 +1,124 @@ +/* $OpenBSD: aes.h,v 1.15 2023/07/31 05:04:06 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_H +#define HEADER_AES_H + +#include + +#ifdef OPENSSL_NO_AES +#error AES is disabled. +#endif + +#include + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +/* Because array size can't be a const in C, the following two are macros. + Both sizes are in bytes. */ +#define AES_MAXNR 14 +#define AES_BLOCK_SIZE 16 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { + unsigned int rd_key[4 *(AES_MAXNR + 1)]; + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, + const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, + const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, + const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num); +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_AES_H */ diff --git a/Libraries/libressl/include/openssl/asn1.h b/Libraries/libressl/include/openssl/asn1.h new file mode 100644 index 000000000..5eeee3317 --- /dev/null +++ b/Libraries/libressl/include/openssl/asn1.h @@ -0,0 +1,1175 @@ +/* $OpenBSD: asn1.h,v 1.80 2023/07/28 10:33:13 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +#define HEADER_ASN1_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define V_ASN1_UNIVERSAL 0x00 +#define V_ASN1_APPLICATION 0x40 +#define V_ASN1_CONTEXT_SPECIFIC 0x80 +#define V_ASN1_PRIVATE 0xc0 + +#define V_ASN1_CONSTRUCTED 0x20 +#define V_ASN1_PRIMITIVE_TAG 0x1f +#define V_ASN1_PRIMATIVE_TAG 0x1f + +#define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ +#define V_ASN1_OTHER -3 /* used in ASN1_TYPE */ +#define V_ASN1_ANY -4 /* used in ASN1 template code */ + +#define V_ASN1_NEG 0x100 /* negative flag */ + +#define V_ASN1_UNDEF -1 +#define V_ASN1_EOC 0 +#define V_ASN1_BOOLEAN 1 /**/ +#define V_ASN1_INTEGER 2 +#define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +#define V_ASN1_BIT_STRING 3 +#define V_ASN1_OCTET_STRING 4 +#define V_ASN1_NULL 5 +#define V_ASN1_OBJECT 6 +#define V_ASN1_OBJECT_DESCRIPTOR 7 +#define V_ASN1_EXTERNAL 8 +#define V_ASN1_REAL 9 +#define V_ASN1_ENUMERATED 10 +#define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) +#define V_ASN1_UTF8STRING 12 +#define V_ASN1_SEQUENCE 16 +#define V_ASN1_SET 17 +#define V_ASN1_NUMERICSTRING 18 /**/ +#define V_ASN1_PRINTABLESTRING 19 +#define V_ASN1_T61STRING 20 +#define V_ASN1_TELETEXSTRING 20 /* alias */ +#define V_ASN1_VIDEOTEXSTRING 21 /**/ +#define V_ASN1_IA5STRING 22 +#define V_ASN1_UTCTIME 23 +#define V_ASN1_GENERALIZEDTIME 24 /**/ +#define V_ASN1_GRAPHICSTRING 25 /**/ +#define V_ASN1_ISO64STRING 26 /**/ +#define V_ASN1_VISIBLESTRING 26 /* alias */ +#define V_ASN1_GENERALSTRING 27 /**/ +#define V_ASN1_UNIVERSALSTRING 28 /**/ +#define V_ASN1_BMPSTRING 30 + +#define B_ASN1_NUMERICSTRING 0x0001 +#define B_ASN1_PRINTABLESTRING 0x0002 +#define B_ASN1_T61STRING 0x0004 +#define B_ASN1_TELETEXSTRING 0x0004 +#define B_ASN1_VIDEOTEXSTRING 0x0008 +#define B_ASN1_IA5STRING 0x0010 +#define B_ASN1_GRAPHICSTRING 0x0020 +#define B_ASN1_ISO64STRING 0x0040 +#define B_ASN1_VISIBLESTRING 0x0040 +#define B_ASN1_GENERALSTRING 0x0080 +#define B_ASN1_UNIVERSALSTRING 0x0100 +#define B_ASN1_OCTET_STRING 0x0200 +#define B_ASN1_BIT_STRING 0x0400 +#define B_ASN1_BMPSTRING 0x0800 +#define B_ASN1_UNKNOWN 0x1000 +#define B_ASN1_UTF8STRING 0x2000 +#define B_ASN1_UTCTIME 0x4000 +#define B_ASN1_GENERALIZEDTIME 0x8000 +#define B_ASN1_SEQUENCE 0x10000 + +/* For use with ASN1_mbstring_copy() */ +#define MBSTRING_FLAG 0x1000 +#define MBSTRING_UTF8 (MBSTRING_FLAG) +#define MBSTRING_ASC (MBSTRING_FLAG|1) +#define MBSTRING_BMP (MBSTRING_FLAG|2) +#define MBSTRING_UNIV (MBSTRING_FLAG|4) + +#define SMIME_OLDMIME 0x400 +#define SMIME_CRLFEOL 0x800 +#define SMIME_STREAM 0x1000 + +struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) + +#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */ +#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */ + +#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */ +/* This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should + * be inserted in the memory buffer + */ +#define ASN1_STRING_FLAG_NDEF 0x010 + +/* This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been + * accessed. The flag will be reset when content has been written to it. + */ + +#define ASN1_STRING_FLAG_CONT 0x020 +/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +#define ASN1_STRING_FLAG_MSTRING 0x040 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* The value of the following field depends on the type being + * held. It is mostly being used for BIT_STRING so if the + * input data has a non-zero 'unused bits' value, it will be + * handled correctly */ + long flags; +}; + +/* ASN1_ENCODING structure: this is used to save the received + * encoding of an ASN1 type. This is useful to get round + * problems with invalid encodings which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +#define ASN1_LONG_UNDEF 0x7fffffffL + +#define STABLE_FLAGS_MALLOC 0x01 +#define STABLE_NO_MASK 0x02 +#define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DECLARE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_title 64 +#define ub_email_address 128 + +/* Declarations for template structures: for full definitions + * see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +#ifndef LIBRESSL_INTERNAL + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +#define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +#define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +#define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +#endif /* !LIBRESSL_INTERNAL */ + +#define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +#define I2D_OF(type) int (*)(type *,unsigned char **) +#define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +#define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +#define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +#define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/* The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +#ifndef LIBRESSL_INTERNAL + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +#define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +#define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +#define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +#define DECLARE_ASN1_ITEM(name) \ + extern const ASN1_ITEM name##_it; + +#endif /* !LIBRESSL_INTERNAL */ + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* These determine which characters to escape: + * RFC2253 special characters, control characters and + * MSB set characters + */ + +#define ASN1_STRFLGS_ESC_2253 1 +#define ASN1_STRFLGS_ESC_CTRL 2 +#define ASN1_STRFLGS_ESC_MSB 4 + + +/* This flag determines how we do escaping: normally + * RC2253 backslash only, set this to use backslash and + * quote. + */ + +#define ASN1_STRFLGS_ESC_QUOTE 8 + + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +#define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +#define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +#define CHARTYPE_LAST_ESC_2253 0x40 + +/* NB the internal flags are safely reused below by flags + * handled at the top level. + */ + +/* If this is set we convert all character strings + * to UTF8 first + */ + +#define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* If this is set we don't attempt to interpret content: + * just assume all strings are 1 byte per character. This + * will produce some pretty odd looking output! + */ + +#define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +#define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* This determines which strings to display and which to + * 'dump' (hex dump of content octets or DER encoding). We can + * only dump non character strings or everything. If we + * don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to + * the usual escaping options. + */ + +#define ASN1_STRFLGS_DUMP_ALL 0x80 +#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* These determine what 'dumping' does, we can dump the + * content octets or the DER encoding: both use the + * RFC2253 #NNNNN notation. + */ + +#define ASN1_STRFLGS_DUMP_DER 0x200 + +/* All the string flags consistent with RFC2253, + * escaping control characters isn't essential in + * RFC2253 but it is advisable anyway. + */ + +#define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DECLARE_STACK_OF(ASN1_INTEGER) + +DECLARE_STACK_OF(ASN1_GENERALSTRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING * asn1_string; + ASN1_OBJECT * object; + ASN1_INTEGER * integer; + ASN1_ENUMERATED * enumerated; + ASN1_BIT_STRING * bit_string; + ASN1_OCTET_STRING * octet_string; + ASN1_PRINTABLESTRING * printablestring; + ASN1_T61STRING * t61string; + ASN1_IA5STRING * ia5string; + ASN1_GENERALSTRING * generalstring; + ASN1_BMPSTRING * bmpstring; + ASN1_UNIVERSALSTRING * universalstring; + ASN1_UTCTIME * utctime; + ASN1_GENERALIZEDTIME * generalizedtime; + ASN1_VISIBLESTRING * visiblestring; + ASN1_UTF8STRING * utf8string; + /* set and sequence are left complete and still + * contain the set or sequence bytes */ + ASN1_STRING * set; + ASN1_STRING * sequence; + ASN1_VALUE * asn1_value; + } value; +} ASN1_TYPE; + +DECLARE_STACK_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +ASN1_SEQUENCE_ANY *d2i_ASN1_SEQUENCE_ANY(ASN1_SEQUENCE_ANY **a, const unsigned char **in, long len); +int i2d_ASN1_SEQUENCE_ANY(const ASN1_SEQUENCE_ANY *a, unsigned char **out); +extern const ASN1_ITEM ASN1_SEQUENCE_ANY_it; +ASN1_SEQUENCE_ANY *d2i_ASN1_SET_ANY(ASN1_SEQUENCE_ANY **a, const unsigned char **in, long len); +int i2d_ASN1_SET_ANY(const ASN1_SEQUENCE_ANY *a, unsigned char **out); +extern const ASN1_ITEM ASN1_SET_ANY_it; + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +#define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +#define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +#define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +#define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +#ifndef LIBRESSL_INTERNAL +#define M_ASN1_IA5STRING_new ASN1_IA5STRING_new + +#define M_ASN1_INTEGER_free ASN1_INTEGER_free +#define M_ASN1_ENUMERATED_free ASN1_ENUMERATED_free +#define M_ASN1_OCTET_STRING_free ASN1_OCTET_STRING_free + +#define M_ASN1_OCTET_STRING_print ASN1_STRING_print + +#define M_ASN1_STRING_data ASN1_STRING_data +#define M_ASN1_STRING_length ASN1_STRING_length +#endif + +ASN1_TYPE *ASN1_TYPE_new(void); +void ASN1_TYPE_free(ASN1_TYPE *a); +ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **a, const unsigned char **in, long len); +int i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **out); +extern const ASN1_ITEM ASN1_ANY_it; + +int ASN1_TYPE_get(const ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +extern const ASN1_ITEM ASN1_OBJECT_it; + +DECLARE_STACK_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* Since this is used to store all sorts of things, via macros, for now, make + its data void * */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(const ASN1_STRING *x); +unsigned char *ASN1_STRING_data(ASN1_STRING *x); +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +ASN1_BIT_STRING *ASN1_BIT_STRING_new(void); +void ASN1_BIT_STRING_free(ASN1_BIT_STRING *a); +ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len); +int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_BIT_STRING_it; +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n); + +ASN1_INTEGER *ASN1_INTEGER_new(void); +void ASN1_INTEGER_free(ASN1_INTEGER *a); +ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len); +int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out); +extern const ASN1_ITEM ASN1_INTEGER_it; +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +ASN1_ENUMERATED *ASN1_ENUMERATED_new(void); +void ASN1_ENUMERATED_free(ASN1_ENUMERATED *a); +ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, const unsigned char **in, long len); +int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out); +extern const ASN1_ITEM ASN1_ENUMERATED_it; + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); + +#ifndef LIBRESSL_INTERNAL +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); +#endif /* !LIBRESSL_INTERNAL */ + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void); +void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *a); +ASN1_OCTET_STRING *d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **a, const unsigned char **in, long len); +int i2d_ASN1_OCTET_STRING(ASN1_OCTET_STRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_OCTET_STRING_it; +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +ASN1_VISIBLESTRING *ASN1_VISIBLESTRING_new(void); +void ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *a); +ASN1_VISIBLESTRING *d2i_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING **a, const unsigned char **in, long len); +int i2d_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_VISIBLESTRING_it; +ASN1_UNIVERSALSTRING *ASN1_UNIVERSALSTRING_new(void); +void ASN1_UNIVERSALSTRING_free(ASN1_UNIVERSALSTRING *a); +ASN1_UNIVERSALSTRING *d2i_ASN1_UNIVERSALSTRING(ASN1_UNIVERSALSTRING **a, const unsigned char **in, long len); +int i2d_ASN1_UNIVERSALSTRING(ASN1_UNIVERSALSTRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_UNIVERSALSTRING_it; +ASN1_UTF8STRING *ASN1_UTF8STRING_new(void); +void ASN1_UTF8STRING_free(ASN1_UTF8STRING *a); +ASN1_UTF8STRING *d2i_ASN1_UTF8STRING(ASN1_UTF8STRING **a, const unsigned char **in, long len); +int i2d_ASN1_UTF8STRING(ASN1_UTF8STRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_UTF8STRING_it; +ASN1_NULL *ASN1_NULL_new(void); +void ASN1_NULL_free(ASN1_NULL *a); +ASN1_NULL *d2i_ASN1_NULL(ASN1_NULL **a, const unsigned char **in, long len); +int i2d_ASN1_NULL(ASN1_NULL *a, unsigned char **out); +extern const ASN1_ITEM ASN1_NULL_it; +ASN1_BMPSTRING *ASN1_BMPSTRING_new(void); +void ASN1_BMPSTRING_free(ASN1_BMPSTRING *a); +ASN1_BMPSTRING *d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **a, const unsigned char **in, long len); +int i2d_ASN1_BMPSTRING(ASN1_BMPSTRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_BMPSTRING_it; + +ASN1_STRING *ASN1_PRINTABLE_new(void); +void ASN1_PRINTABLE_free(ASN1_STRING *a); +ASN1_STRING *d2i_ASN1_PRINTABLE(ASN1_STRING **a, const unsigned char **in, long len); +int i2d_ASN1_PRINTABLE(ASN1_STRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_PRINTABLE_it; + +ASN1_STRING *DIRECTORYSTRING_new(void); +void DIRECTORYSTRING_free(ASN1_STRING *a); +ASN1_STRING *d2i_DIRECTORYSTRING(ASN1_STRING **a, const unsigned char **in, long len); +int i2d_DIRECTORYSTRING(ASN1_STRING *a, unsigned char **out); +extern const ASN1_ITEM DIRECTORYSTRING_it; +ASN1_STRING *DISPLAYTEXT_new(void); +void DISPLAYTEXT_free(ASN1_STRING *a); +ASN1_STRING *d2i_DISPLAYTEXT(ASN1_STRING **a, const unsigned char **in, long len); +int i2d_DISPLAYTEXT(ASN1_STRING *a, unsigned char **out); +extern const ASN1_ITEM DISPLAYTEXT_it; +ASN1_PRINTABLESTRING *ASN1_PRINTABLESTRING_new(void); +void ASN1_PRINTABLESTRING_free(ASN1_PRINTABLESTRING *a); +ASN1_PRINTABLESTRING *d2i_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING **a, const unsigned char **in, long len); +int i2d_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_PRINTABLESTRING_it; +ASN1_T61STRING *ASN1_T61STRING_new(void); +void ASN1_T61STRING_free(ASN1_T61STRING *a); +ASN1_T61STRING *d2i_ASN1_T61STRING(ASN1_T61STRING **a, const unsigned char **in, long len); +int i2d_ASN1_T61STRING(ASN1_T61STRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_T61STRING_it; +ASN1_IA5STRING *ASN1_IA5STRING_new(void); +void ASN1_IA5STRING_free(ASN1_IA5STRING *a); +ASN1_IA5STRING *d2i_ASN1_IA5STRING(ASN1_IA5STRING **a, const unsigned char **in, long len); +int i2d_ASN1_IA5STRING(ASN1_IA5STRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_IA5STRING_it; +ASN1_GENERALSTRING *ASN1_GENERALSTRING_new(void); +void ASN1_GENERALSTRING_free(ASN1_GENERALSTRING *a); +ASN1_GENERALSTRING *d2i_ASN1_GENERALSTRING(ASN1_GENERALSTRING **a, const unsigned char **in, long len); +int i2d_ASN1_GENERALSTRING(ASN1_GENERALSTRING *a, unsigned char **out); +extern const ASN1_ITEM ASN1_GENERALSTRING_it; +ASN1_UTCTIME *ASN1_UTCTIME_new(void); +void ASN1_UTCTIME_free(ASN1_UTCTIME *a); +ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, const unsigned char **in, long len); +int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **out); +extern const ASN1_ITEM ASN1_UTCTIME_it; +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_new(void); +void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a, const unsigned char **in, long len); +int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **out); +extern const ASN1_ITEM ASN1_GENERALIZEDTIME_it; +ASN1_TIME *ASN1_TIME_new(void); +void ASN1_TIME_free(ASN1_TIME *a); +ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len); +int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out); +extern const ASN1_ITEM ASN1_TIME_it; + +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm); +int ASN1_TIME_compare(const ASN1_TIME *t1, const ASN1_TIME *t2); +int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t2); +int ASN1_TIME_normalize(ASN1_TIME *t); +int ASN1_TIME_set_string_X509(ASN1_TIME *time, const char *str); +int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, + const ASN1_TIME *to); + +extern const ASN1_ITEM ASN1_OCTET_STRING_NDEF_it; + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_set_tm(ASN1_TIME *s, struct tm *tm); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, + long offset_sec); +int ASN1_TIME_check(const ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +#ifndef OPENSSL_NO_BIO +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type); +#endif +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_get_uint64(uint64_t *out_val, const ASN1_INTEGER *aint); +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *aint, uint64_t val); +int ASN1_INTEGER_get_int64(int64_t *out_val, const ASN1_INTEGER *aint); +int ASN1_INTEGER_set_int64(ASN1_INTEGER *aint, int64_t val); +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_get_int64(int64_t *out_val, const ASN1_ENUMERATED *aenum); +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *aenum, int64_t val); +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, + int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +#ifndef LIBRESSL_INTERNAL + +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +#endif /* !LIBRESSL_INTERNAL */ + +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x); + +#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +#define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, + unsigned long flags); + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in); + +#ifndef OPENSSL_NO_BIO +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x); + +#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +#define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump); +#endif + +unsigned long ASN1_tag2bit(int tag); +const char *ASN1_tag2str(int tag); + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, const unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, + int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, const unsigned char *data, + int len); +int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); + +ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +void ERR_load_ASN1_strings(void); + +/* Error codes for the ASN1 functions. */ + +/* Function codes. */ +#define ASN1_F_A2D_ASN1_OBJECT 100 +#define ASN1_F_A2I_ASN1_ENUMERATED 101 +#define ASN1_F_A2I_ASN1_INTEGER 102 +#define ASN1_F_A2I_ASN1_STRING 103 +#define ASN1_F_APPEND_EXP 176 +#define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +#define ASN1_F_ASN1_CB 177 +#define ASN1_F_ASN1_CHECK_TLEN 104 +#define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 +#define ASN1_F_ASN1_COLLECT 106 +#define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +#define ASN1_F_ASN1_D2I_FP 109 +#define ASN1_F_ASN1_D2I_READ_BIO 107 +#define ASN1_F_ASN1_DIGEST 184 +#define ASN1_F_ASN1_DO_ADB 110 +#define ASN1_F_ASN1_DUP 111 +#define ASN1_F_ASN1_ENUMERATED_SET 112 +#define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +#define ASN1_F_ASN1_EX_C2I 204 +#define ASN1_F_ASN1_FIND_END 190 +#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +#define ASN1_F_ASN1_GENERATE_V3 178 +#define ASN1_F_ASN1_GET_OBJECT 114 +#define ASN1_F_ASN1_HEADER_NEW 115 +#define ASN1_F_ASN1_I2D_BIO 116 +#define ASN1_F_ASN1_I2D_FP 117 +#define ASN1_F_ASN1_INTEGER_SET 118 +#define ASN1_F_ASN1_INTEGER_TO_BN 119 +#define ASN1_F_ASN1_ITEM_D2I_FP 206 +#define ASN1_F_ASN1_ITEM_DUP 191 +#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 +#define ASN1_F_ASN1_ITEM_EX_D2I 120 +#define ASN1_F_ASN1_ITEM_I2D_BIO 192 +#define ASN1_F_ASN1_ITEM_I2D_FP 193 +#define ASN1_F_ASN1_ITEM_PACK 198 +#define ASN1_F_ASN1_ITEM_SIGN 195 +#define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +#define ASN1_F_ASN1_ITEM_UNPACK 199 +#define ASN1_F_ASN1_ITEM_VERIFY 197 +#define ASN1_F_ASN1_MBSTRING_NCOPY 122 +#define ASN1_F_ASN1_OBJECT_NEW 123 +#define ASN1_F_ASN1_OUTPUT_DATA 214 +#define ASN1_F_ASN1_PACK_STRING 124 +#define ASN1_F_ASN1_PCTX_NEW 205 +#define ASN1_F_ASN1_PKCS5_PBE_SET 125 +#define ASN1_F_ASN1_SEQ_PACK 126 +#define ASN1_F_ASN1_SEQ_UNPACK 127 +#define ASN1_F_ASN1_SIGN 128 +#define ASN1_F_ASN1_STR2TYPE 179 +#define ASN1_F_ASN1_STRING_SET 186 +#define ASN1_F_ASN1_STRING_TABLE_ADD 129 +#define ASN1_F_ASN1_STRING_TYPE_NEW 130 +#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +#define ASN1_F_ASN1_TEMPLATE_NEW 133 +#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +#define ASN1_F_ASN1_TIME_ADJ 217 +#define ASN1_F_ASN1_TIME_SET 175 +#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +#define ASN1_F_ASN1_UNPACK_STRING 136 +#define ASN1_F_ASN1_UTCTIME_ADJ 218 +#define ASN1_F_ASN1_UTCTIME_SET 187 +#define ASN1_F_ASN1_VERIFY 137 +#define ASN1_F_B64_READ_ASN1 209 +#define ASN1_F_B64_WRITE_ASN1 210 +#define ASN1_F_BIO_NEW_NDEF 208 +#define ASN1_F_BITSTR_CB 180 +#define ASN1_F_BN_TO_ASN1_ENUMERATED 138 +#define ASN1_F_BN_TO_ASN1_INTEGER 139 +#define ASN1_F_C2I_ASN1_BIT_STRING 189 +#define ASN1_F_C2I_ASN1_INTEGER 194 +#define ASN1_F_C2I_ASN1_OBJECT 196 +#define ASN1_F_COLLECT_DATA 140 +#define ASN1_F_D2I_ASN1_BIT_STRING 141 +#define ASN1_F_D2I_ASN1_BOOLEAN 142 +#define ASN1_F_D2I_ASN1_BYTES 143 +#define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 +#define ASN1_F_D2I_ASN1_HEADER 145 +#define ASN1_F_D2I_ASN1_INTEGER 146 +#define ASN1_F_D2I_ASN1_OBJECT 147 +#define ASN1_F_D2I_ASN1_SET 148 +#define ASN1_F_D2I_ASN1_TYPE_BYTES 149 +#define ASN1_F_D2I_ASN1_UINTEGER 150 +#define ASN1_F_D2I_ASN1_UTCTIME 151 +#define ASN1_F_D2I_AUTOPRIVATEKEY 207 +#define ASN1_F_D2I_NETSCAPE_RSA 152 +#define ASN1_F_D2I_NETSCAPE_RSA_2 153 +#define ASN1_F_D2I_PRIVATEKEY 154 +#define ASN1_F_D2I_PUBLICKEY 155 +#define ASN1_F_D2I_RSA_NET 200 +#define ASN1_F_D2I_RSA_NET_2 201 +#define ASN1_F_D2I_X509 156 +#define ASN1_F_D2I_X509_CINF 157 +#define ASN1_F_D2I_X509_PKEY 159 +#define ASN1_F_I2D_ASN1_BIO_STREAM 211 +#define ASN1_F_I2D_ASN1_SET 188 +#define ASN1_F_I2D_ASN1_TIME 160 +#define ASN1_F_I2D_DSA_PUBKEY 161 +#define ASN1_F_I2D_EC_PUBKEY 181 +#define ASN1_F_I2D_PRIVATEKEY 163 +#define ASN1_F_I2D_PUBLICKEY 164 +#define ASN1_F_I2D_RSA_NET 162 +#define ASN1_F_I2D_RSA_PUBKEY 165 +#define ASN1_F_LONG_C2I 166 +#define ASN1_F_OID_MODULE_INIT 174 +#define ASN1_F_PARSE_TAGGING 182 +#define ASN1_F_PKCS5_PBE2_SET_IV 167 +#define ASN1_F_PKCS5_PBE_SET 202 +#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +#define ASN1_F_PKCS5_PBKDF2_SET 219 +#define ASN1_F_SMIME_READ_ASN1 212 +#define ASN1_F_SMIME_TEXT 213 +#define ASN1_F_X509_CINF_NEW 168 +#define ASN1_F_X509_CRL_ADD0_REVOKED 169 +#define ASN1_F_X509_INFO_NEW 170 +#define ASN1_F_X509_NAME_ENCODE 203 +#define ASN1_F_X509_NAME_EX_D2I 158 +#define ASN1_F_X509_NAME_EX_NEW 171 +#define ASN1_F_X509_NEW 172 +#define ASN1_F_X509_PKEY_NEW 173 + +/* Reason codes. */ +#define ASN1_R_ADDING_OBJECT 171 +#define ASN1_R_ASN1_PARSE_ERROR 203 +#define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +#define ASN1_R_AUX_ERROR 100 +#define ASN1_R_BAD_CLASS 101 +#define ASN1_R_BAD_OBJECT_HEADER 102 +#define ASN1_R_BAD_PASSWORD_READ 103 +#define ASN1_R_BAD_TAG 104 +#define ASN1_R_BAD_TEMPLATE 230 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +#define ASN1_R_BN_LIB 105 +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +#define ASN1_R_BUFFER_TOO_SMALL 107 +#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +#define ASN1_R_CONTEXT_NOT_INITIALISED 217 +#define ASN1_R_DATA_IS_WRONG 109 +#define ASN1_R_DECODE_ERROR 110 +#define ASN1_R_DECODING_ERROR 111 +#define ASN1_R_DEPTH_EXCEEDED 174 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +#define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 173 +#define ASN1_R_ERROR_LOADING_SECTION 172 +#define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 +#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +#define ASN1_R_EXPECTING_AN_INTEGER 115 +#define ASN1_R_EXPECTING_AN_OBJECT 116 +#define ASN1_R_EXPECTING_A_BOOLEAN 117 +#define ASN1_R_EXPECTING_A_TIME 118 +#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +#define ASN1_R_FIELD_MISSING 121 +#define ASN1_R_FIRST_NUM_TOO_LARGE 122 +#define ASN1_R_HEADER_TOO_LONG 123 +#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +#define ASN1_R_ILLEGAL_BOOLEAN 176 +#define ASN1_R_ILLEGAL_CHARACTERS 124 +#define ASN1_R_ILLEGAL_FORMAT 177 +#define ASN1_R_ILLEGAL_HEX 178 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +#define ASN1_R_ILLEGAL_INTEGER 180 +#define ASN1_R_ILLEGAL_NEGATIVE_VALUE 226 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +#define ASN1_R_ILLEGAL_NULL 125 +#define ASN1_R_ILLEGAL_NULL_VALUE 182 +#define ASN1_R_ILLEGAL_OBJECT 183 +#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +#define ASN1_R_ILLEGAL_TAGGED_ANY 127 +#define ASN1_R_ILLEGAL_TIME_VALUE 184 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +#define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +#define ASN1_R_INVALID_DIGIT 130 +#define ASN1_R_INVALID_MIME_TYPE 205 +#define ASN1_R_INVALID_MODIFIER 186 +#define ASN1_R_INVALID_NUMBER 187 +#define ASN1_R_INVALID_OBJECT_ENCODING 216 +#define ASN1_R_INVALID_SEPARATOR 131 +#define ASN1_R_INVALID_TIME_FORMAT 132 +#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +#define ASN1_R_INVALID_UTF8STRING 134 +#define ASN1_R_IV_TOO_LARGE 135 +#define ASN1_R_LENGTH_ERROR 136 +#define ASN1_R_LIST_ERROR 188 +#define ASN1_R_MIME_NO_CONTENT_TYPE 206 +#define ASN1_R_MIME_PARSE_ERROR 207 +#define ASN1_R_MIME_SIG_PARSE_ERROR 208 +#define ASN1_R_MISSING_EOC 137 +#define ASN1_R_MISSING_SECOND_NUMBER 138 +#define ASN1_R_MISSING_VALUE 189 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +#define ASN1_R_MSTRING_WRONG_TAG 140 +#define ASN1_R_NESTED_ASN1_STRING 197 +#define ASN1_R_NESTED_TOO_DEEP 219 +#define ASN1_R_NON_HEX_CHARACTERS 141 +#define ASN1_R_NOT_ASCII_FORMAT 190 +#define ASN1_R_NOT_ENOUGH_DATA 142 +#define ASN1_R_NO_CONTENT_TYPE 209 +#define ASN1_R_NO_DEFAULT_DIGEST 201 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +#define ASN1_R_NO_MULTIPART_BOUNDARY 211 +#define ASN1_R_NO_SIG_CONTENT_TYPE 212 +#define ASN1_R_NULL_IS_WRONG_LENGTH 144 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +#define ASN1_R_ODD_NUMBER_OF_CHARS 145 +#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +#define ASN1_R_SHORT_LINE 150 +#define ASN1_R_SIG_INVALID_MIME_TYPE 213 +#define ASN1_R_STREAMING_NOT_SUPPORTED 202 +#define ASN1_R_STRING_TOO_LONG 151 +#define ASN1_R_STRING_TOO_SHORT 152 +#define ASN1_R_TAG_VALUE_TOO_HIGH 153 +#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +#define ASN1_R_TOO_LARGE 223 +#define ASN1_R_TOO_LONG 155 +#define ASN1_R_TOO_SMALL 224 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +#define ASN1_R_TYPE_NOT_PRIMITIVE 231 +#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 +#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 +#define ASN1_R_UNEXPECTED_EOC 159 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +#define ASN1_R_UNKNOWN_FORMAT 160 +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +#define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +#define ASN1_R_UNKNOWN_TAG 194 +#define ASN1_R_UNKOWN_FORMAT 195 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +#define ASN1_R_UNSUPPORTED_CIPHER 165 +#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +#define ASN1_R_UNSUPPORTED_TYPE 196 +#define ASN1_R_WRONG_INTEGER_TYPE 225 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +#define ASN1_R_WRONG_TAG 168 +#define ASN1_R_WRONG_TYPE 169 + +int ASN1_time_parse(const char *_bytes, size_t _len, struct tm *_tm, int _mode); +int ASN1_time_tm_cmp(struct tm *_tm1, struct tm *_tm2); +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/asn1t.h b/Libraries/libressl/include/openssl/asn1t.h new file mode 100644 index 000000000..4d79f82ec --- /dev/null +++ b/Libraries/libressl/include/openssl/asn1t.h @@ -0,0 +1,907 @@ +/* $OpenBSD: asn1t.h,v 1.23 2023/07/28 10:00:10 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ASN1T_H +#define HEADER_ASN1T_H + +#include + +#include + +#include + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LIBRESSL_INTERNAL + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + + +/* Macros for start and end of ASN1_ITEM definition */ + +#define ASN1_ITEM_start(itname) \ + const ASN1_ITEM itname##_it = { + +#define static_ASN1_ITEM_start(itname) \ + static const ASN1_ITEM itname##_it = { + +#define ASN1_ITEM_end(itname) \ + }; + + + +/* Macros to aid ASN1 template writing */ + +#define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +#define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +#define static_ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + + +/* This is a ASN1 type which just embeds a template */ + +/* + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +#define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +#define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname) + +#define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define static_ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +#define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_ref(tname, cb, lck) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +#define static_ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +#define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname) + +#define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define static_ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + + +/* + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +#define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +#define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +#define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname) + +#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +#define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type) + +#define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define static_ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +#define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) + +#define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +/* Plain simple type */ +#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) + +/* OPTIONAL simple type */ +#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) + +/* IMPLICIT tagged OPTIONAL simple type */ +#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* Same as above but EXPLICIT */ + +#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* SEQUENCE OF type */ +#define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +#define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +#define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +#define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +#define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +#define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +#define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + + +#define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + + +#define ADB_ENTRY(val, template) {val, template} + +#define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +#endif /* !LIBRESSL_INTERNAL */ + +/* This is the ASN1 template structure that defines + * a wrapper round the actual type. It determines the + * actual position of the field in the value structure, + * various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ + const char *field_name; /* Field name */ + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +#define ASN1_TEMPLATE_item(t) (t->item_ptr) +#define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +#define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +#define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* Special case: this refers to a SET OF that + * will be sorted into DER order when encoded *and* + * the corresponding STACK will be modified to match + * the new order. + */ +#define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +#define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* These flags mean the tag should be taken from the + * tag field. If EXPLICIT then the underlying type + * is used for the inner tag. + */ + +/* IMPLICIT tagging */ +#define ASN1_TFLG_IMPTAG (0x1 << 3) + + +/* EXPLICIT tagging, inner tag from underlying type */ +#define ASN1_TFLG_EXPTAG (0x2 << 3) + +#define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT + +/* context specific EXPLICIT */ +#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT + +/* + * If tagging is in force these determine the type of tag to use. Otherwiser + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +#define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +#define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +#define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +#define ASN1_TFLG_PRIVATE (0x3<<6) + +#define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case + * the 'item' field points to an ASN1_ADB structure + * which contains a table of values to decode the + * relevant type + */ + +#define ASN1_TFLG_ADB_MASK (0x3<<8) + +#define ASN1_TFLG_ADB_OID (0x1<<8) + +#define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag when present in a SEQUENCE OF, SET OF + * or EXPLICIT causes indefinite length constructed + * encoding to be used if required. + */ + +#define ASN1_TFLG_NDEF (0x1<<11) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually)*/ + const char *sname; /* Structure name */ +}; + +/* These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +#define ASN1_ITYPE_PRIMITIVE 0x0 + +#define ASN1_ITYPE_SEQUENCE 0x1 + +#define ASN1_ITYPE_CHOICE 0x2 + +#define ASN1_ITYPE_EXTERN 0x4 + +#define ASN1_ITYPE_MSTRING 0x5 + +#define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* Cache for ASN1 tag and length, so we + * don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ + +typedef ASN1_VALUE * ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length); +typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* This is the ASN1_AUX structure: it handles various + * miscellaneous requirements. For example the use of + * reference counts and an informational callback. + * + * The "informational callback" is called at various + * points during the ASN1 encoding and decoding. It can + * be used to provide minor customisation of the structures + * used. This is most useful where the supplied routines + * *almost* do the right thing but need some extra help + * at a few points. If the callback returns zero then + * it is assumed a fatal error has occurred and the + * main operation should be abandoned. + * + * If major changes in the default behaviour are required + * then an external type is more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +#define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +#define ASN1_AFLG_ENCODING 2 + +/* operation values for asn1_cb */ + +#define ASN1_OP_NEW_PRE 0 +#define ASN1_OP_NEW_POST 1 +#define ASN1_OP_FREE_PRE 2 +#define ASN1_OP_FREE_POST 3 +#define ASN1_OP_D2I_PRE 4 +#define ASN1_OP_D2I_POST 5 +#define ASN1_OP_I2D_PRE 6 +#define ASN1_OP_I2D_POST 7 +#define ASN1_OP_PRINT_PRE 8 +#define ASN1_OP_PRINT_POST 9 +#define ASN1_OP_STREAM_PRE 10 +#define ASN1_OP_STREAM_POST 11 +#define ASN1_OP_DETACHED_PRE 12 +#define ASN1_OP_DETACHED_POST 13 + +#ifndef LIBRESSL_INTERNAL + +/* Macro to implement a primitive type */ +#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +#define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) +#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +/* This includes evil casts to remove const: they will go away when full + * ASN1 constification is done. + */ +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +#endif /* !LIBRESSL_INTERNAL */ + +/* external definitions for primitive types */ + +extern const ASN1_ITEM ASN1_BOOLEAN_it; +extern const ASN1_ITEM ASN1_TBOOLEAN_it; +extern const ASN1_ITEM ASN1_FBOOLEAN_it; +extern const ASN1_ITEM ASN1_SEQUENCE_it; +extern const ASN1_ITEM BIGNUM_it; +extern const ASN1_ITEM LONG_it; +extern const ASN1_ITEM ZLONG_it; + +#ifndef LIBRESSL_INTERNAL +extern const ASN1_ITEM CBIGNUM_it; +#endif + +DECLARE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/bio.h b/Libraries/libressl/include/openssl/bio.h new file mode 100644 index 000000000..b955524c4 --- /dev/null +++ b/Libraries/libressl/include/openssl/bio.h @@ -0,0 +1,747 @@ +/* $OpenBSD: bio.h,v 1.60 2023/08/25 12:37:33 schwarze Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BIO_H +#define HEADER_BIO_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif +#include + +# include +#include + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are the 'types' of BIOs */ +#define BIO_TYPE_NONE 0 +#define BIO_TYPE_MEM (1|0x0400) +#define BIO_TYPE_FILE (2|0x0400) + +#define BIO_TYPE_FD (4|0x0400|0x0100) +#define BIO_TYPE_SOCKET (5|0x0400|0x0100) +#define BIO_TYPE_NULL (6|0x0400) +#define BIO_TYPE_SSL (7|0x0200) +#define BIO_TYPE_MD (8|0x0200) /* passive filter */ +#define BIO_TYPE_BUFFER (9|0x0200) /* filter */ +#define BIO_TYPE_CIPHER (10|0x0200) /* filter */ +#define BIO_TYPE_BASE64 (11|0x0200) /* filter */ +#define BIO_TYPE_CONNECT (12|0x0400|0x0100) /* socket - connect */ +#define BIO_TYPE_ACCEPT (13|0x0400|0x0100) /* socket for accept */ +#define BIO_TYPE_PROXY_CLIENT (14|0x0200) /* client proxy BIO */ +#define BIO_TYPE_PROXY_SERVER (15|0x0200) /* server proxy BIO */ +#define BIO_TYPE_NBIO_TEST (16|0x0200) /* server proxy BIO */ +#define BIO_TYPE_NULL_FILTER (17|0x0200) +#define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */ +#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ +#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */ +#define BIO_TYPE_DGRAM (21|0x0400|0x0100) +#define BIO_TYPE_ASN1 (22|0x0200) /* filter */ +#define BIO_TYPE_COMP (23|0x0200) /* filter */ + +#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +/* + * BIO_TYPE_START is the first user-allocated BIO type. No pre-defined type, + * flag bits aside, may exceed this value. + */ +#define BIO_TYPE_START 128 + +/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); */ +#define BIO_NOCLOSE 0x00 +#define BIO_CLOSE 0x01 + +/* These are used in the following macros and are passed to + * BIO_ctrl() */ +#define BIO_CTRL_RESET 1 /* opt - rewind/zero etc */ +#define BIO_CTRL_EOF 2 /* opt - are we at the eof */ +#define BIO_CTRL_INFO 3 /* opt - extra tit-bits */ +#define BIO_CTRL_SET 4 /* man - set the 'IO' type */ +#define BIO_CTRL_GET 5 /* man - get the 'IO' type */ +#define BIO_CTRL_PUSH 6 /* opt - internal, used to signify change */ +#define BIO_CTRL_POP 7 /* opt - internal, used to signify change */ +#define BIO_CTRL_GET_CLOSE 8 /* man - set the 'close' on free */ +#define BIO_CTRL_SET_CLOSE 9 /* man - set the 'close' on free */ +#define BIO_CTRL_PENDING 10 /* opt - is their more data buffered */ +#define BIO_CTRL_FLUSH 11 /* opt - 'flush' buffered output */ +#define BIO_CTRL_DUP 12 /* man - extra stuff for 'duped' BIO */ +#define BIO_CTRL_WPENDING 13 /* opt - number of bytes still to write */ +/* callback is int cb(BIO *bio,state,ret); */ +#define BIO_CTRL_SET_CALLBACK 14 /* opt - set callback function */ +#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */ + +#define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */ + +/* dgram BIO stuff */ +#define BIO_CTRL_DGRAM_CONNECT 31 /* BIO dgram special */ +#define BIO_CTRL_DGRAM_SET_CONNECTED 32 /* allow for an externally + * connected socket to be + * passed in */ +#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */ +#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */ + +#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +#define BIO_CTRL_DGRAM_MTU_DISCOVER 39 /* set DF bit on egress packets */ +/* #endif */ + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +#define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */ +#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for + * MTU. want to use this + * if asking the kernel + * fails */ + +#define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU + * was exceed in the + * previous write + * operation */ + +#define BIO_CTRL_DGRAM_GET_PEER 46 +#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ + +#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to + * adjust socket timeouts */ + + +/* modifiers */ +#define BIO_FP_READ 0x02 +#define BIO_FP_WRITE 0x04 +#define BIO_FP_APPEND 0x08 +#define BIO_FP_TEXT 0x10 + +#define BIO_FLAGS_READ 0x01 +#define BIO_FLAGS_WRITE 0x02 +#define BIO_FLAGS_IO_SPECIAL 0x04 +#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +#define BIO_FLAGS_SHOULD_RETRY 0x08 + +/* Used in BIO_gethostbyname() */ +#define BIO_GHBN_CTRL_HITS 1 +#define BIO_GHBN_CTRL_MISSES 2 +#define BIO_GHBN_CTRL_CACHE_SIZE 3 +#define BIO_GHBN_CTRL_GET_ENTRY 4 +#define BIO_GHBN_CTRL_FLUSH 5 + +/* Mostly used in the SSL BIO */ +/* Not used anymore + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 + * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 + */ + +#define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* This is used with memory BIOs: it means we shouldn't free up or change the + * data in any way. + */ +#define BIO_FLAGS_MEM_RDONLY 0x200 + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +#define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +#define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +#define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +#define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +#define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +#define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +#define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* The next three are used in conjunction with the + * BIO_should_io_special() condition. After this returns true, + * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO + * stack and return the 'reason' for the special and the offending BIO. + * Given a BIO, BIO_get_retry_reason(bio) will return the code. */ +/* Returned from the SSL bio when the certificate retrieval code had an error */ +#define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +#define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +#define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +#define BIO_CB_FREE 0x01 +#define BIO_CB_READ 0x02 +#define BIO_CB_WRITE 0x03 +#define BIO_CB_PUTS 0x04 +#define BIO_CB_GETS 0x05 +#define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, + * the BIO_CB_RETURN flag indicates if it is after the call. + */ +#define BIO_CB_RETURN 0x80 +#define BIO_CB_return(a) ((a)|BIO_CB_RETURN)) +#define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +#define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi, + long argl, long ret); +typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp, + size_t len, int argi, long argl, int ret, size_t *processed); + +BIO_callback_fn BIO_get_callback(const BIO *b); +void BIO_set_callback(BIO *b, BIO_callback_fn callback); + +BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b); +void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback); + +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef int BIO_info_cb(BIO *, int, int); +/* Compatibility with OpenSSL's backward compatibility. */ +typedef BIO_info_cb bio_info_cb; + +typedef struct bio_method_st BIO_METHOD; + +DECLARE_STACK_OF(BIO) + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg); + +/* BIO_METHOD accessors */ +BIO_METHOD *BIO_meth_new(int type, const char *name); +void BIO_meth_free(BIO_METHOD *biom); +int (*BIO_meth_get_write(const BIO_METHOD *biom))(BIO *, const char *, int); +int BIO_meth_set_write(BIO_METHOD *biom, + int (*write)(BIO *, const char *, int)); +int (*BIO_meth_get_read(const BIO_METHOD *biom))(BIO *, char *, int); +int BIO_meth_set_read(BIO_METHOD *biom, int (*read)(BIO *, char *, int)); +int (*BIO_meth_get_puts(const BIO_METHOD *biom))(BIO *, const char *); +int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts)(BIO *, const char *)); +int (*BIO_meth_get_gets(const BIO_METHOD *biom))(BIO *, char *, int); +int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets)(BIO *, char *, int)); +long (*BIO_meth_get_ctrl(const BIO_METHOD *biom))(BIO *, int, long, void *); +int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl)(BIO *, int, long, void *)); +int (*BIO_meth_get_create(const BIO_METHOD *biom))(BIO *); +int BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *)); +int (*BIO_meth_get_destroy(const BIO_METHOD *biom))(BIO *); +int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *)); +long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))(BIO *, int, BIO_info_cb *); +int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, + long (*callback_ctrl)(BIO *, int, BIO_info_cb *)); + +/* connect BIO stuff */ +#define BIO_CONN_S_BEFORE 1 +#define BIO_CONN_S_GET_IP 2 +#define BIO_CONN_S_GET_PORT 3 +#define BIO_CONN_S_CREATE_SOCKET 4 +#define BIO_CONN_S_CONNECT 5 +#define BIO_CONN_S_OK 6 +#define BIO_CONN_S_BLOCKED_CONNECT 7 +#define BIO_CONN_S_NBIO 8 +/*#define BIO_CONN_get_param_hostname BIO_ctrl */ + +#define BIO_C_SET_CONNECT 100 +#define BIO_C_DO_STATE_MACHINE 101 +#define BIO_C_SET_NBIO 102 +#define BIO_C_SET_PROXY_PARAM 103 +#define BIO_C_SET_FD 104 +#define BIO_C_GET_FD 105 +#define BIO_C_SET_FILE_PTR 106 +#define BIO_C_GET_FILE_PTR 107 +#define BIO_C_SET_FILENAME 108 +#define BIO_C_SET_SSL 109 +#define BIO_C_GET_SSL 110 +#define BIO_C_SET_MD 111 +#define BIO_C_GET_MD 112 +#define BIO_C_GET_CIPHER_STATUS 113 +#define BIO_C_SET_BUF_MEM 114 +#define BIO_C_GET_BUF_MEM_PTR 115 +#define BIO_C_GET_BUFF_NUM_LINES 116 +#define BIO_C_SET_BUFF_SIZE 117 +#define BIO_C_SET_ACCEPT 118 +#define BIO_C_SSL_MODE 119 +#define BIO_C_GET_MD_CTX 120 +#define BIO_C_GET_PROXY_PARAM 121 +#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */ +#define BIO_C_GET_CONNECT 123 +#define BIO_C_GET_ACCEPT 124 +#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +#define BIO_C_FILE_SEEK 128 +#define BIO_C_GET_CIPHER_CTX 129 +#define BIO_C_SET_BUF_MEM_EOF_RETURN 130/*return end of input value*/ +#define BIO_C_SET_BIND_MODE 131 +#define BIO_C_GET_BIND_MODE 132 +#define BIO_C_FILE_TELL 133 +#define BIO_C_GET_SOCKS 134 +#define BIO_C_SET_SOCKS 135 + +#define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +#define BIO_C_GET_WRITE_BUF_SIZE 137 +#define BIO_C_MAKE_BIO_PAIR 138 +#define BIO_C_DESTROY_BIO_PAIR 139 +#define BIO_C_GET_WRITE_GUARANTEE 140 +#define BIO_C_GET_READ_REQUEST 141 +#define BIO_C_SHUTDOWN_WR 142 +#define BIO_C_NREAD0 143 +#define BIO_C_NREAD 144 +#define BIO_C_NWRITE0 145 +#define BIO_C_NWRITE 146 +#define BIO_C_RESET_READ_REQUEST 147 +#define BIO_C_SET_MD_CTX 148 + +#define BIO_C_SET_EX_ARG 153 +#define BIO_C_GET_EX_ARG 154 + +#define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +#define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +/* BIO_s_connect() and BIO_s_socks4a_connect() */ +#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) +#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) +#define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) +#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) +#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) +#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) +#define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) +#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0) + + +#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +/* BIO_s_accept_socket() */ +#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) +#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) +#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + +#define BIO_BIND_NORMAL 0 +#define BIO_BIND_REUSEADDR_IF_UNUSED 1 +#define BIO_BIND_REUSEADDR 2 +#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +#define BIO_do_connect(b) BIO_do_handshake(b) +#define BIO_do_accept(b) BIO_do_handshake(b) +#define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_proxy_client() */ +#define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) +#define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) +/* BIO_set_nbio(b,n) */ +#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) +/* BIO *BIO_get_filter_bio(BIO *bio); */ +#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) +#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) +#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) + +#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) +#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) +#define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) +#define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) + +#define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +#define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + +#define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) +#define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) + +#define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* name is cast to lose const, but might be better to route through a function + so we can do it safely */ +#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)name) +#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* WARNING WARNING, this ups the reference count on the read bio of the + * SSL structure. This is because the ssl read BIO is now pointed to by + * the next_bio field in the bio. So when you free the BIO, make sure + * you are doing a BIO_free_all() to catch the underlying BIO. */ +#define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) +#define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) +#define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +#define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) +#define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) +#define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ + +#define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) +#define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) +#define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) +#define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +#define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +#define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +#define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +#define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +#define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +#define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +#define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +#define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +#define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +#define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +/* For BIO_s_bio() */ +#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +#define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +#define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +#define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +#define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +#define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +#define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +#define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +#define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) +#define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) + +/* These two aren't currently implemented */ +/* int BIO_get_ex_num(BIO *bio); */ +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +unsigned long BIO_number_read(BIO *bio); +unsigned long BIO_number_written(BIO *bio); + +int BIO_get_new_index(void); +const BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +BIO *BIO_new(const BIO_METHOD *type); +int BIO_set(BIO *a, const BIO_METHOD *type); +int BIO_free(BIO *a); +int BIO_up_ref(BIO *bio); +void *BIO_get_data(BIO *a); +void BIO_set_data(BIO *a, void *ptr); +int BIO_get_init(BIO *a); +void BIO_set_init(BIO *a, int init); +int BIO_get_shutdown(BIO *a); +void BIO_set_shutdown(BIO *a, int shut); +void BIO_vfree(BIO *a); +int BIO_read(BIO *b, void *data, int len) + __attribute__((__bounded__(__buffer__,2,3))); +int BIO_gets(BIO *bp, char *buf, int size) + __attribute__((__bounded__ (__string__,2,3))); +int BIO_write(BIO *b, const void *data, int len) + __attribute__((__bounded__(__buffer__,2,3))); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); +char * BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO * BIO_push(BIO *b, BIO *append); +BIO * BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO * BIO_find_type(BIO *b, int bio_type); +BIO * BIO_next(BIO *b); +void BIO_set_next(BIO *b, BIO *next); +BIO * BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +void BIO_set_retry_reason(BIO *bio, int reason); +BIO * BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +const BIO_METHOD *BIO_s_mem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +const BIO_METHOD *BIO_s_socket(void); +const BIO_METHOD *BIO_s_connect(void); +const BIO_METHOD *BIO_s_accept(void); +const BIO_METHOD *BIO_s_fd(void); +const BIO_METHOD *BIO_s_log(void); +const BIO_METHOD *BIO_s_bio(void); +const BIO_METHOD *BIO_s_null(void); +const BIO_METHOD *BIO_f_null(void); +const BIO_METHOD *BIO_f_buffer(void); +const BIO_METHOD *BIO_f_nbio_test(void); +#ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_datagram(void); +#endif + +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int _error); +int BIO_dgram_non_fatal_error(int _error); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int _error); +int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +struct hostent *BIO_gethostbyname(const char *name); +/* We might want a thread-safe interface too: + * struct hostent *BIO_gethostbyname_r(const char *name, + * struct hostent *result, void *buffer, size_t buflen); + * or something similar (caller allocates a struct hostent, + * pointed to by "result", and additional buffer space for the various + * substructures; if the buffer does not suffice, NULL is returned + * and an appropriate error code is set). + */ +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_get_port(const char *str, unsigned short *port_ptr); +int BIO_get_host_ip(const char *str, unsigned char *ip); +int BIO_get_accept_socket(char *host_port, int mode); +int BIO_accept(int sock, char **ip_port); +int BIO_sock_init(void ); +void BIO_sock_cleanup(void); +int BIO_set_tcp_ndelay(int sock, int turn_on); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. + * Size 0 uses default value. + */ + +void BIO_copy_next_retry(BIO *b); + +/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/ + +/* Needed for libressl-portable. */ +#ifndef __MINGW_PRINTF_FORMAT +int BIO_printf(BIO *bio, const char *format, ...) + __attribute__((__format__(__printf__, 2, 3), __nonnull__(2))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) + __attribute__((__format__(__printf__, 2, 0), __nonnull__(2))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) + __attribute__((__deprecated__, __format__(__printf__, 3, 4), + __nonnull__(3))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) + __attribute__((__deprecated__, __format__(__printf__, 3, 0), + __nonnull__(3))); +#else +int BIO_printf(BIO *bio, const char *format, ...) + __attribute__((__format__(__MINGW_PRINTF_FORMAT, 2, 3), __nonnull__(2))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) + __attribute__((__format__(__MINGW_PRINTF_FORMAT, 2, 0), __nonnull__(2))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) + __attribute__((__deprecated__, __format__(__MINGW_PRINTF_FORMAT, 3, 4), + __nonnull__(3))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) + __attribute__((__deprecated__, __format__(__MINGW_PRINTF_FORMAT, 3, 0), + __nonnull__(3))); +#endif + +void ERR_load_BIO_strings(void); + +/* Error codes for the BIO functions. */ + +/* Function codes. */ +#define BIO_F_ACPT_STATE 100 +#define BIO_F_BIO_ACCEPT 101 +#define BIO_F_BIO_BER_GET_HEADER 102 +#define BIO_F_BIO_CALLBACK_CTRL 131 +#define BIO_F_BIO_CTRL 103 +#define BIO_F_BIO_GETHOSTBYNAME 120 +#define BIO_F_BIO_GETS 104 +#define BIO_F_BIO_GET_ACCEPT_SOCKET 105 +#define BIO_F_BIO_GET_HOST_IP 106 +#define BIO_F_BIO_GET_PORT 107 +#define BIO_F_BIO_MAKE_PAIR 121 +#define BIO_F_BIO_NEW 108 +#define BIO_F_BIO_NEW_FILE 109 +#define BIO_F_BIO_NEW_MEM_BUF 126 +#define BIO_F_BIO_NREAD 123 +#define BIO_F_BIO_NREAD0 124 +#define BIO_F_BIO_NWRITE 125 +#define BIO_F_BIO_NWRITE0 122 +#define BIO_F_BIO_PUTS 110 +#define BIO_F_BIO_READ 111 +#define BIO_F_BIO_SOCK_INIT 112 +#define BIO_F_BIO_WRITE 113 +#define BIO_F_BUFFER_CTRL 114 +#define BIO_F_CONN_CTRL 127 +#define BIO_F_CONN_STATE 115 +#define BIO_F_DGRAM_SCTP_READ 132 +#define BIO_F_FILE_CTRL 116 +#define BIO_F_FILE_READ 130 +#define BIO_F_LINEBUFFER_CTRL 129 +#define BIO_F_MEM_READ 128 +#define BIO_F_MEM_WRITE 117 +#define BIO_F_SSL_NEW 118 +#define BIO_F_WSASTARTUP 119 + +/* Reason codes. */ +#define BIO_R_ACCEPT_ERROR 100 +#define BIO_R_BAD_FOPEN_MODE 101 +#define BIO_R_BAD_HOSTNAME_LOOKUP 102 +#define BIO_R_BROKEN_PIPE 124 +#define BIO_R_CONNECT_ERROR 103 +#define BIO_R_EOF_ON_MEMORY_BIO 127 +#define BIO_R_ERROR_SETTING_NBIO 104 +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 +#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +#define BIO_R_INVALID_ARGUMENT 125 +#define BIO_R_INVALID_IP_ADDRESS 108 +#define BIO_R_INVALID_PORT_NUMBER 129 +#define BIO_R_IN_USE 123 +#define BIO_R_KEEPALIVE 109 +#define BIO_R_LENGTH_TOO_LONG 130 +#define BIO_R_NBIO_CONNECT_ERROR 110 +#define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 +#define BIO_R_NO_HOSTNAME_SPECIFIED 112 +#define BIO_R_NO_PORT_DEFINED 113 +#define BIO_R_NO_PORT_SPECIFIED 114 +#define BIO_R_NO_SUCH_FILE 128 +#define BIO_R_NULL_PARAMETER 115 +#define BIO_R_TAG_MISMATCH 116 +#define BIO_R_UNABLE_TO_BIND_SOCKET 117 +#define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +#define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +#define BIO_R_UNINITIALIZED 120 +#define BIO_R_UNSUPPORTED_METHOD 121 +#define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +#define BIO_R_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/blowfish.h b/Libraries/libressl/include/openssl/blowfish.h new file mode 100644 index 000000000..b434e70cb --- /dev/null +++ b/Libraries/libressl/include/openssl/blowfish.h @@ -0,0 +1,110 @@ +/* $OpenBSD: blowfish.h,v 1.17 2023/07/31 05:04:06 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +#define HEADER_BLOWFISH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_BF +#error BF is disabled. +#endif + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define BF_LONG unsigned int + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4*256]; +} BF_KEY; + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/bn.h b/Libraries/libressl/include/openssl/bn.h new file mode 100644 index 000000000..e00953ea2 --- /dev/null +++ b/Libraries/libressl/include/openssl/bn.h @@ -0,0 +1,534 @@ +/* $OpenBSD: bn.h,v 1.75 2023/07/31 05:04:06 tb Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_BN_H +#define HEADER_BN_H + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* This next option uses the C libraries (2 word)/(1 word) function. + * If it is not defined, I use my C version (which is slower). + * The reason for this flag is that when the particular C compiler + * library routine is used, and the library is linked with a different + * compiler, the library is missing. This mostly happens when the + * library is built with gcc and then linked using normal cc. This would + * be a common occurrence because gcc normally produces code that is + * 2 times faster than system compilers for the big number stuff. + * For machines with only one compiler (or shared libraries), this should + * be on. Again this in only really a problem on machines + * using "long long's", are 32bit, and are not using my assembler code. */ +/* #define BN_DIV2W */ + +#ifdef _LP64 +#undef BN_LLONG +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000L) +#define BN_MASK2h1 (0xffffffff80000000L) +#define BN_TBIT (0x8000000000000000L) +#define BN_DEC_CONV (10000000000000000000UL) +#define BN_DEC_FMT1 "%lu" +#define BN_DEC_FMT2 "%019lu" +#define BN_DEC_NUM 19 +#define BN_HEX_FMT1 "%lX" +#define BN_HEX_FMT2 "%016lX" +#else +#define BN_ULLONG unsigned long long +#define BN_LLONG +#define BN_ULONG unsigned int +#define BN_LONG int +#define BN_BITS 64 +#define BN_BYTES 4 +#define BN_BITS2 32 +#define BN_BITS4 16 +#define BN_MASK (0xffffffffffffffffLL) +#define BN_MASK2 (0xffffffffL) +#define BN_MASK2l (0xffff) +#define BN_MASK2h1 (0xffff8000L) +#define BN_MASK2h (0xffff0000L) +#define BN_TBIT (0x80000000L) +#define BN_DEC_CONV (1000000000L) +#define BN_DEC_FMT1 "%u" +#define BN_DEC_FMT2 "%09u" +#define BN_DEC_NUM 9 +#define BN_HEX_FMT1 "%X" +#define BN_HEX_FMT2 "%08X" +#endif + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ + +void BN_set_flags(BIGNUM *b, int n); +int BN_get_flags(const BIGNUM *b, int n); +void BN_with_flags(BIGNUM *dest, const BIGNUM *src, int flags); + +/* Values for |top| in BN_rand() */ +#define BN_RAND_TOP_ANY -1 +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +/* Values for |bottom| in BN_rand() */ +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +BN_GENCB *BN_GENCB_new(void); +void BN_GENCB_free(BN_GENCB *cb); + +/* Wrapper function to make using BN_GENCB easier, */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); + +/* Populate a BN_GENCB structure with an "old"-style callback */ +void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback)(int, int, void *), + void *cb_arg); + +/* Populate a BN_GENCB structure with a "new"-style callback */ +void BN_GENCB_set(BN_GENCB *gencb, int (*callback)(int, int, BN_GENCB *), + void *cb_arg); + +void *BN_GENCB_get_arg(BN_GENCB *cb); + +#define BN_prime_checks 0 /* default: select number of iterations + based on the size of the number */ + +/* + * BN_prime_checks_for_size() returns the number of Miller-Rabin + * iterations that will be done for checking that a random number + * is probably prime. The error rate for accepting a composite + * number as prime depends on the size of the prime |b|. The error + * rates used are for calculating an RSA key with 2 primes, and so + * the level is what you would expect for a key of double the size + * of the prime. + * + * This table is generated using the algorithm of FIPS PUB 186-4 + * Digital Signature Standard (DSS), section F.1, page 117. + * (https://dx.doi.org/10.6028/NIST.FIPS.186-4) + * + * The following magma script was used to generate the output: + * securitybits:=125; + * k:=1024; + * for t:=1 to 65 do + * for M:=3 to Floor(2*Sqrt(k-1)-1) do + * S:=0; + * // Sum over m + * for m:=3 to M do + * s:=0; + * // Sum over j + * for j:=2 to m do + * s+:=(RealField(32)!2)^-(j+(k-1)/j); + * end for; + * S+:=2^(m-(m-1)*t)*s; + * end for; + * A:=2^(k-2-M*t); + * B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; + * pkt:=2.00743*Log(2)*k*2^-k*(A+B); + * seclevel:=Floor(-Log(2,pkt)); + * if seclevel ge securitybits then + * printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; + * break; + * end if; + * end for; + * if seclevel ge securitybits then break; end if; + * end for; + * + * It can be run online at: + * http://magma.maths.usyd.edu.au/calc + * + * And will output: + * k: 1024, security: 129 bits (t: 6, M: 23) + * + * k is the number of bits of the prime, securitybits is the level + * we want to reach. + * + * prime length | RSA key size | # MR tests | security level + * -------------+--------------|------------+--------------- + * (b) >= 6394 | >= 12788 | 3 | 256 bit + * (b) >= 3747 | >= 7494 | 3 | 192 bit + * (b) >= 1345 | >= 2690 | 4 | 128 bit + * (b) >= 1080 | >= 2160 | 5 | 128 bit + * (b) >= 852 | >= 1704 | 5 | 112 bit + * (b) >= 476 | >= 952 | 5 | 80 bit + * (b) >= 400 | >= 800 | 6 | 80 bit + * (b) >= 347 | >= 694 | 7 | 80 bit + * (b) >= 308 | >= 616 | 8 | 80 bit + * (b) >= 55 | >= 110 | 27 | 64 bit + * (b) >= 6 | >= 12 | 34 | 64 bit + */ + +#define BN_prime_checks_for_size(b) ((b) >= 3747 ? 3 : \ + (b) >= 1345 ? 4 : \ + (b) >= 476 ? 5 : \ + (b) >= 400 ? 6 : \ + (b) >= 347 ? 7 : \ + (b) >= 308 ? 8 : \ + (b) >= 55 ? 27 : \ + /* b >= 6 */ 34) + +#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_zero(const BIGNUM *a); +int BN_is_one(const BIGNUM *a); +int BN_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_odd(const BIGNUM *a); + +void BN_zero(BIGNUM *a); +int BN_one(BIGNUM *a); + +const BIGNUM *BN_value_one(void); +BN_CTX *BN_CTX_new(void); +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +void BN_set_negative(BIGNUM *b, int n); + +int BN_is_negative(const BIGNUM *b); + +#ifndef LIBRESSL_INTERNAL +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +#endif +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +#ifndef LIBRESSL_INTERNAL +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +#endif +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +int BN_print_fp(FILE *fp, const BIGNUM *a); +int BN_print(BIO *fp, const BIGNUM *a); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char * BN_bn2hex(const BIGNUM *a); +char * BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +#ifndef LIBRESSL_INTERNAL +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +#endif +int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */ +#ifndef LIBRESSL_INTERNAL +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +#endif +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +int BN_security_bits(int L, int N); + +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void ); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, + BN_MONT_CTX *mont, BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* Primes from RFC 2409 */ +BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn); + +void ERR_load_BN_strings(void); + +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BNRAND 127 +#define BN_F_BN_BLINDING_CONVERT_EX 100 +#define BN_F_BN_BLINDING_CREATE_PARAM 128 +#define BN_F_BN_BLINDING_INVERT_EX 101 +#define BN_F_BN_BLINDING_NEW 102 +#define BN_F_BN_BLINDING_UPDATE 103 +#define BN_F_BN_BN2DEC 104 +#define BN_F_BN_BN2HEX 105 +#define BN_F_BN_CTX_GET 116 +#define BN_F_BN_CTX_NEW 106 +#define BN_F_BN_CTX_START 129 +#define BN_F_BN_DIV 107 +#define BN_F_BN_DIV_NO_BRANCH 138 +#define BN_F_BN_DIV_RECP 130 +#define BN_F_BN_EXP 123 +#define BN_F_BN_EXPAND2 108 +#define BN_F_BN_GENERATE_PRIME_EX 140 +#define BN_F_BN_EXPAND_INTERNAL 120 +#define BN_F_BN_GF2M_MOD 131 +#define BN_F_BN_GF2M_MOD_EXP 132 +#define BN_F_BN_GF2M_MOD_MUL 133 +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +#define BN_F_BN_GF2M_MOD_SQR 136 +#define BN_F_BN_GF2M_MOD_SQRT 137 +#define BN_F_BN_MOD_EXP2_MONT 118 +#define BN_F_BN_MOD_EXP_MONT 109 +#define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +#define BN_F_BN_MOD_EXP_MONT_WORD 117 +#define BN_F_BN_MOD_EXP_RECP 125 +#define BN_F_BN_MOD_EXP_SIMPLE 126 +#define BN_F_BN_MOD_INVERSE 110 +#define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +#define BN_F_BN_MOD_LSHIFT_QUICK 119 +#define BN_F_BN_MOD_MUL_RECIPROCAL 111 +#define BN_F_BN_MOD_SQRT 121 +#define BN_F_BN_MPI2BN 112 +#define BN_F_BN_NEW 113 +#define BN_F_BN_RAND 114 +#define BN_F_BN_RAND_RANGE 122 +#define BN_F_BN_USUB 115 + +/* Reason codes. */ +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#define BN_R_BIGNUM_TOO_LONG 114 +#define BN_R_BITS_TOO_SMALL 117 +#define BN_R_CALLED_WITH_EVEN_MODULUS 102 +#define BN_R_DIV_BY_ZERO 103 +#define BN_R_ENCODING_ERROR 104 +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +#define BN_R_INPUT_NOT_REDUCED 110 +#define BN_R_INVALID_ARGUMENT 118 +#define BN_R_INVALID_LENGTH 106 +#define BN_R_INVALID_RANGE 115 +#define BN_R_NOT_A_SQUARE 111 +#define BN_R_NOT_INITIALIZED 107 +#define BN_R_NO_INVERSE 108 +#define BN_R_NO_SOLUTION 116 +#define BN_R_P_IS_NOT_PRIME 112 +#define BN_R_TOO_MANY_ITERATIONS 113 +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/buffer.h b/Libraries/libressl/include/openssl/buffer.h new file mode 100644 index 000000000..d461d6493 --- /dev/null +++ b/Libraries/libressl/include/openssl/buffer.h @@ -0,0 +1,102 @@ +/* $OpenBSD: buffer.h,v 1.17 2023/07/28 10:17:21 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BUFFER_H +#define HEADER_BUFFER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Already declared in ossl_typ.h */ +/* typedef struct buf_mem_st BUF_MEM; */ + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ +}; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); + +void ERR_load_BUF_strings(void); + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +#define BUF_F_BUF_MEMDUP 103 +#define BUF_F_BUF_MEM_GROW 100 +#define BUF_F_BUF_MEM_GROW_CLEAN 105 +#define BUF_F_BUF_MEM_NEW 101 +#define BUF_F_BUF_STRDUP 102 +#define BUF_F_BUF_STRNDUP 104 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/camellia.h b/Libraries/libressl/include/openssl/camellia.h new file mode 100644 index 000000000..b9b5f792b --- /dev/null +++ b/Libraries/libressl/include/openssl/camellia.h @@ -0,0 +1,125 @@ +/* $OpenBSD: camellia.h,v 1.5 2014/11/13 20:01:58 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_CAMELLIA_H +#define HEADER_CAMELLIA_H + +#include + +#ifdef OPENSSL_NO_CAMELLIA +#error CAMELLIA is disabled. +#endif + +#include + +#define CAMELLIA_ENCRYPT 1 +#define CAMELLIA_DECRYPT 0 + +/* Because array size can't be a const in C, the following two are macros. + Both sizes are in bytes. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ + +#define CAMELLIA_BLOCK_SIZE 16 +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_Camellia_H */ diff --git a/Libraries/libressl/include/openssl/cast.h b/Libraries/libressl/include/openssl/cast.h new file mode 100644 index 000000000..093669606 --- /dev/null +++ b/Libraries/libressl/include/openssl/cast.h @@ -0,0 +1,103 @@ +/* $OpenBSD: cast.h,v 1.13 2023/07/08 07:25:43 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CAST_H +#define HEADER_CAST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_CAST +#error CAST is disabled. +#endif + +#define CAST_ENCRYPT 1 +#define CAST_DECRYPT 0 + +#define CAST_LONG unsigned int + +#define CAST_BLOCK 8 +#define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key, + int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const CAST_KEY *ks, unsigned char *iv, int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/chacha.h b/Libraries/libressl/include/openssl/chacha.h new file mode 100644 index 000000000..e2345b219 --- /dev/null +++ b/Libraries/libressl/include/openssl/chacha.h @@ -0,0 +1,58 @@ +/* $OpenBSD: chacha.h,v 1.8 2019/01/22 00:59:21 dlg Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_CHACHA_H +#define HEADER_CHACHA_H + +#include + +#if defined(OPENSSL_NO_CHACHA) +#error ChaCha is disabled. +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + unsigned int input[16]; + unsigned char ks[64]; + unsigned char unused; +} ChaCha_ctx; + +void ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, + unsigned int keybits); +void ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv, + const unsigned char *counter); +void ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, + size_t len); + +void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len, + const unsigned char key[32], const unsigned char iv[8], uint64_t counter); +void CRYPTO_xchacha_20(unsigned char *out, const unsigned char *in, size_t len, + const unsigned char key[32], const unsigned char iv[24]); +void CRYPTO_hchacha_20(unsigned char out[32], + const unsigned char key[32], const unsigned char iv[16]); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_CHACHA_H */ diff --git a/Libraries/libressl/include/openssl/cmac.h b/Libraries/libressl/include/openssl/cmac.h new file mode 100644 index 000000000..cb6d64b02 --- /dev/null +++ b/Libraries/libressl/include/openssl/cmac.h @@ -0,0 +1,82 @@ +/* $OpenBSD: cmac.h,v 1.3 2014/06/21 13:42:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#ifndef HEADER_CMAC_H +#define HEADER_CMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/cms.h b/Libraries/libressl/include/openssl/cms.h new file mode 100644 index 000000000..76672af09 --- /dev/null +++ b/Libraries/libressl/include/openssl/cms.h @@ -0,0 +1,535 @@ +/* $OpenBSD: cms.h,v 1.16 2023/07/28 10:28:02 tb Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_H +#define HEADER_CMS_H + +#include + +#ifndef OPENSSL_NO_CMS +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +DECLARE_STACK_OF(CMS_SignerInfo) +DECLARE_STACK_OF(CMS_RecipientEncryptedKey) +DECLARE_STACK_OF(CMS_RecipientInfo) +DECLARE_STACK_OF(CMS_RevocationInfoChoice) +CMS_ContentInfo *CMS_ContentInfo_new(void); +void CMS_ContentInfo_free(CMS_ContentInfo *a); +CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, const unsigned char **in, long len); +int i2d_CMS_ContentInfo(CMS_ContentInfo *a, unsigned char **out); +extern const ASN1_ITEM CMS_ContentInfo_it; +CMS_ReceiptRequest *CMS_ReceiptRequest_new(void); +void CMS_ReceiptRequest_free(CMS_ReceiptRequest *a); +CMS_ReceiptRequest *d2i_CMS_ReceiptRequest(CMS_ReceiptRequest **a, const unsigned char **in, long len); +int i2d_CMS_ReceiptRequest(CMS_ReceiptRequest *a, unsigned char **out); +extern const ASN1_ITEM CMS_ReceiptRequest_it; +int CMS_ContentInfo_print_ctx(BIO *out, CMS_ContentInfo *x, int indent, const ASN1_PCTX *pctx); + +#define CMS_SIGNERINFO_ISSUER_SERIAL 0 +#define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +#define CMS_RECIPINFO_NONE -1 +#define CMS_RECIPINFO_TRANS 0 +#define CMS_RECIPINFO_AGREE 1 +#define CMS_RECIPINFO_KEK 2 +#define CMS_RECIPINFO_PASS 3 +#define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +#define CMS_TEXT 0x1 +#define CMS_NOCERTS 0x2 +#define CMS_NO_CONTENT_VERIFY 0x4 +#define CMS_NO_ATTR_VERIFY 0x8 +#define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +#define CMS_NOINTERN 0x10 +#define CMS_NO_SIGNER_CERT_VERIFY 0x20 +#define CMS_NOVERIFY 0x20 +#define CMS_DETACHED 0x40 +#define CMS_BINARY 0x80 +#define CMS_NOATTR 0x100 +#define CMS_NOSMIMECAP 0x200 +#define CMS_NOOLDMIMETYPE 0x400 +#define CMS_CRLFEOL 0x800 +#define CMS_STREAM 0x1000 +#define CMS_NOCRL 0x2000 +#define CMS_PARTIAL 0x4000 +#define CMS_REUSE_DIGEST 0x8000 +#define CMS_USE_KEYID 0x10000 +#define CMS_DEBUG_DECRYPT 0x20000 +#define CMS_KEY_PARAM 0x40000 +#define CMS_ASCIICRLF 0x80000 + +const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); + +int CMS_get_version(const CMS_ContentInfo *cms, long *version); +int CMS_SignerInfo_get_version(const CMS_SignerInfo *si, long *version); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +#ifdef HEADER_PEM_H +CMS_ContentInfo *PEM_read_bio_CMS(BIO *bp, CMS_ContentInfo **x, + pem_password_cb *cb, void *u); +CMS_ContentInfo *PEM_read_CMS(FILE *fp, CMS_ContentInfo **x, + pem_password_cb *cb, void *u); +int PEM_write_bio_CMS(BIO *bp, const CMS_ContentInfo *x); +int PEM_write_CMS(FILE *fp, const CMS_ContentInfo *x); +#endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, + EVP_PKEY *pkey, STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, + size_t keylen, BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, + size_t keylen, const unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, unsigned char *pass, + ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, + unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, EVP_PKEY **pk, + X509 **recip, X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, ASN1_OBJECT *otherTypeId, ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, + size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass, + ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, + int wrap_nid, int pbe_nid, unsigned char *pass, ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, + EVP_PKEY *pk, const EVP_MD *md, unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, + X509_ALGOR **pdig, X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, + int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int type, const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, const char *attrname, + int type, const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +#ifdef HEADER_X509V3_H + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, + STACK_OF(GENERAL_NAMES) *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid, + int *pallorfirst, STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +#endif +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) * + CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, ASN1_BIT_STRING **pubkey, ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* Backward compatibility for spelling errors. */ +#define CMS_R_UNKNOWN_DIGEST_ALGORITM CMS_R_UNKNOWN_DIGEST_ALGORITHM +#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE \ + CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + +int ERR_load_CMS_strings(void); + +/* + * CMS function codes. + */ +#define CMS_F_CHECK_CONTENT 99 +#define CMS_F_CMS_ADD0_CERT 164 +#define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +#define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +#define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +#define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +#define CMS_F_CMS_ADD1_SIGNER 102 +#define CMS_F_CMS_ADD1_SIGNINGTIME 103 +#define CMS_F_CMS_COMPRESS 104 +#define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +#define CMS_F_CMS_COPY_CONTENT 107 +#define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +#define CMS_F_CMS_DATA 109 +#define CMS_F_CMS_DATAFINAL 110 +#define CMS_F_CMS_DATAINIT 111 +#define CMS_F_CMS_DECRYPT 112 +#define CMS_F_CMS_DECRYPT_SET1_KEY 113 +#define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +#define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +#define CMS_F_CMS_DIGEST_VERIFY 118 +#define CMS_F_CMS_ENCODE_RECEIPT 161 +#define CMS_F_CMS_ENCRYPT 119 +#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT 179 +#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +#define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +#define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +#define CMS_F_CMS_ENV_ASN1_CTRL 171 +#define CMS_F_CMS_FINAL 127 +#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +#define CMS_F_CMS_GET0_CONTENT 129 +#define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +#define CMS_F_CMS_GET0_ENVELOPED 131 +#define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +#define CMS_F_CMS_GET0_SIGNED 133 +#define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +#define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +#define CMS_F_CMS_RECEIPT_VERIFY 160 +#define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +#define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 +#define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 +#define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 +#define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 +#define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 +#define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +#define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +#define CMS_F_CMS_SD_ASN1_CTRL 170 +#define CMS_F_CMS_SET1_IAS 176 +#define CMS_F_CMS_SET1_KEYID 177 +#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +#define CMS_F_CMS_SET_DETACHED 147 +#define CMS_F_CMS_SIGN 148 +#define CMS_F_CMS_SIGNED_DATA_INIT 149 +#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +#define CMS_F_CMS_SIGNERINFO_SIGN 151 +#define CMS_F_CMS_SIGNERINFO_VERIFY 152 +#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +#define CMS_F_CMS_SIGN_RECEIPT 163 +#define CMS_F_CMS_STREAM 155 +#define CMS_F_CMS_UNCOMPRESS 156 +#define CMS_F_CMS_VERIFY 157 +#define CMS_F_KEK_UNWRAP_KEY 180 + +/* + * CMS reason codes. + */ +#define CMS_R_ADD_SIGNER_ERROR 99 +#define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +#define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +#define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +#define CMS_R_CIPHER_INITIALISATION_ERROR 101 +#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +#define CMS_R_CMS_DATAFINAL_ERROR 103 +#define CMS_R_CMS_LIB 104 +#define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +#define CMS_R_CONTENT_NOT_FOUND 105 +#define CMS_R_CONTENT_TYPE_MISMATCH 171 +#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +#define CMS_R_CONTENT_VERIFY_ERROR 109 +#define CMS_R_CTRL_ERROR 110 +#define CMS_R_CTRL_FAILURE 111 +#define CMS_R_DECRYPT_ERROR 112 +#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +#define CMS_R_ERROR_SETTING_KEY 115 +#define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +#define CMS_R_INVALID_KEY_LENGTH 118 +#define CMS_R_MD_BIO_INIT_ERROR 119 +#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +#define CMS_R_MSGSIGDIGEST_ERROR 172 +#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +#define CMS_R_NEED_ONE_SIGNER 164 +#define CMS_R_NOT_A_SIGNED_RECEIPT 165 +#define CMS_R_NOT_ENCRYPTED_DATA 122 +#define CMS_R_NOT_KEK 123 +#define CMS_R_NOT_KEY_AGREEMENT 181 +#define CMS_R_NOT_KEY_TRANSPORT 124 +#define CMS_R_NOT_PWRI 177 +#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +#define CMS_R_NO_CIPHER 126 +#define CMS_R_NO_CONTENT 127 +#define CMS_R_NO_CONTENT_TYPE 173 +#define CMS_R_NO_DEFAULT_DIGEST 128 +#define CMS_R_NO_DIGEST_SET 129 +#define CMS_R_NO_KEY 130 +#define CMS_R_NO_KEY_OR_CERT 174 +#define CMS_R_NO_MATCHING_DIGEST 131 +#define CMS_R_NO_MATCHING_RECIPIENT 132 +#define CMS_R_NO_MATCHING_SIGNATURE 166 +#define CMS_R_NO_MSGSIGDIGEST 167 +#define CMS_R_NO_PASSWORD 178 +#define CMS_R_NO_PRIVATE_KEY 133 +#define CMS_R_NO_PUBLIC_KEY 134 +#define CMS_R_NO_RECEIPT_REQUEST 168 +#define CMS_R_NO_SIGNERS 135 +#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +#define CMS_R_RECEIPT_DECODE_ERROR 169 +#define CMS_R_RECIPIENT_ERROR 137 +#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +#define CMS_R_SIGNFINAL_ERROR 139 +#define CMS_R_SMIME_TEXT_ERROR 140 +#define CMS_R_STORE_INIT_ERROR 141 +#define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +#define CMS_R_TYPE_NOT_DATA 143 +#define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +#define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +#define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +#define CMS_R_UNKNOWN_CIPHER 148 +#define CMS_R_UNKNOWN_DIGEST_ALGORITHM 149 +#define CMS_R_UNKNOWN_ID 150 +#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +#define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +#define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +#define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155 +#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +#define CMS_R_UNSUPPORTED_TYPE 156 +#define CMS_R_UNWRAP_ERROR 157 +#define CMS_R_UNWRAP_FAILURE 180 +#define CMS_R_VERIFICATION_FAILURE 158 +#define CMS_R_WRAP_ERROR 159 + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/Libraries/libressl/include/openssl/comp.h b/Libraries/libressl/include/openssl/comp.h new file mode 100644 index 000000000..f0330276f --- /dev/null +++ b/Libraries/libressl/include/openssl/comp.h @@ -0,0 +1,7 @@ +/* $OpenBSD: comp.h,v 1.13 2023/07/28 09:42:44 tb Exp $ */ + +/* + * Public domain. + * + * This header is intentionally left empty. Some software uses it unnecessarily. + */ diff --git a/Libraries/libressl/include/openssl/conf.h b/Libraries/libressl/include/openssl/conf.h new file mode 100644 index 000000000..5d10163bf --- /dev/null +++ b/Libraries/libressl/include/openssl/conf.h @@ -0,0 +1,246 @@ +/* $OpenBSD: conf.h,v 1.16 2022/07/12 14:42:48 kn Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_H +#define HEADER_CONF_H + +#include + +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DECLARE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create)(CONF_METHOD *meth); + int (*init)(CONF *conf); + int (*destroy)(CONF *conf); + int (*destroy_data)(CONF *conf); + int (*load_bio)(CONF *conf, BIO *bp, long *eline); + int (*dump)(const CONF *conf, BIO *bp); + int (*is_number)(const CONF *conf, char c); + int (*to_int)(const CONF *conf, char c); + int (*load)(CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func(CONF_IMODULE *md); + +#define CONF_MFLAGS_IGNORE_ERRORS 0x1 +#define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +#define CONF_MFLAGS_SILENT 0x4 +#define CONF_MFLAGS_NO_DSO 0x8 +#define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +#define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +void OPENSSL_config(const char *config_name); +void OPENSSL_no_config(void); + +/* New conf code. The semantics are different from the functions above. + If that wasn't the case, the above functions would have been replaced */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +int NCONF_dump_fp(const CONF *conf, FILE *out); +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +void CONF_modules_free(void); +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb)(const char *elem, int len, void *usr), void *arg); + +void OPENSSL_load_builtin_modules(void); + +void ERR_load_CONF_strings(void); + +/* Error codes for the CONF functions. */ + +/* Function codes. */ +#define CONF_F_CONF_DUMP_FP 104 +#define CONF_F_CONF_LOAD 100 +#define CONF_F_CONF_LOAD_BIO 102 +#define CONF_F_CONF_LOAD_FP 103 +#define CONF_F_CONF_MODULES_LOAD 116 +#define CONF_F_CONF_PARSE_LIST 119 +#define CONF_F_DEF_LOAD 120 +#define CONF_F_DEF_LOAD_BIO 121 +#define CONF_F_MODULE_INIT 115 +#define CONF_F_MODULE_LOAD_DSO 117 +#define CONF_F_MODULE_RUN 118 +#define CONF_F_NCONF_DUMP_BIO 105 +#define CONF_F_NCONF_DUMP_FP 106 +#define CONF_F_NCONF_GET_NUMBER 107 +#define CONF_F_NCONF_GET_NUMBER_E 112 +#define CONF_F_NCONF_GET_SECTION 108 +#define CONF_F_NCONF_GET_STRING 109 +#define CONF_F_NCONF_LOAD 113 +#define CONF_F_NCONF_LOAD_BIO 110 +#define CONF_F_NCONF_LOAD_FP 114 +#define CONF_F_NCONF_NEW 111 +#define CONF_F_STR_COPY 101 + +/* Reason codes. */ +#define CONF_R_ERROR_LOADING_DSO 110 +#define CONF_R_LIST_CANNOT_BE_NULL 115 +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +#define CONF_R_MISSING_EQUAL_SIGN 101 +#define CONF_R_MISSING_FINISH_FUNCTION 111 +#define CONF_R_MISSING_INIT_FUNCTION 112 +#define CONF_R_MODULE_INITIALIZATION_ERROR 109 +#define CONF_R_NO_CLOSE_BRACE 102 +#define CONF_R_NO_CONF 105 +#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +#define CONF_R_NO_SECTION 107 +#define CONF_R_NO_SUCH_FILE 114 +#define CONF_R_NO_VALUE 108 +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +#define CONF_R_UNKNOWN_MODULE_NAME 113 +#define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 +#define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/conf_api.h b/Libraries/libressl/include/openssl/conf_api.h new file mode 100644 index 000000000..95f938622 --- /dev/null +++ b/Libraries/libressl/include/openssl/conf_api.h @@ -0,0 +1,88 @@ +/* $OpenBSD: conf_api.h,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_API_H +#define HEADER_CONF_API_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/crypto.h b/Libraries/libressl/include/openssl/crypto.h new file mode 100644 index 000000000..07a55ec1f --- /dev/null +++ b/Libraries/libressl/include/openssl/crypto.h @@ -0,0 +1,548 @@ +/* $OpenBSD: crypto.h,v 1.63 2023/07/28 10:19:20 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include + +#ifndef HEADER_CRYPTO_H +#define HEADER_CRYPTO_H + +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Backward compatibility to SSLeay */ +/* This is more to be used to check the correct DLL is being used + * in the MS world. */ +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +#define SSLEAY_VERSION 0 +/* #define SSLEAY_OPTIONS 1 no longer supported */ +#define SSLEAY_CFLAGS 2 +#define SSLEAY_BUILT_ON 3 +#define SSLEAY_PLATFORM 4 +#define SSLEAY_DIR 5 + +/* When changing the CRYPTO_LOCK_* list, be sure to maintain the text lock + * names in cryptlib.c + */ + +#define CRYPTO_LOCK_ERR 1 +#define CRYPTO_LOCK_EX_DATA 2 +#define CRYPTO_LOCK_X509 3 +#define CRYPTO_LOCK_X509_INFO 4 +#define CRYPTO_LOCK_X509_PKEY 5 +#define CRYPTO_LOCK_X509_CRL 6 +#define CRYPTO_LOCK_X509_REQ 7 +#define CRYPTO_LOCK_DSA 8 +#define CRYPTO_LOCK_RSA 9 +#define CRYPTO_LOCK_EVP_PKEY 10 +#define CRYPTO_LOCK_X509_STORE 11 +#define CRYPTO_LOCK_SSL_CTX 12 +#define CRYPTO_LOCK_SSL_CERT 13 +#define CRYPTO_LOCK_SSL_SESSION 14 +#define CRYPTO_LOCK_SSL_SESS_CERT 15 +#define CRYPTO_LOCK_SSL 16 +#define CRYPTO_LOCK_SSL_METHOD 17 +#define CRYPTO_LOCK_RAND 18 +#define CRYPTO_LOCK_RAND2 19 +#define CRYPTO_LOCK_MALLOC 20 +#define CRYPTO_LOCK_BIO 21 +#define CRYPTO_LOCK_GETHOSTBYNAME 22 +#define CRYPTO_LOCK_GETSERVBYNAME 23 +#define CRYPTO_LOCK_READDIR 24 +#define CRYPTO_LOCK_RSA_BLINDING 25 +#define CRYPTO_LOCK_DH 26 +#define CRYPTO_LOCK_MALLOC2 27 +#define CRYPTO_LOCK_DSO 28 +#define CRYPTO_LOCK_DYNLOCK 29 +#define CRYPTO_LOCK_ENGINE 30 +#define CRYPTO_LOCK_UI 31 +#define CRYPTO_LOCK_ECDSA 32 +#define CRYPTO_LOCK_EC 33 +#define CRYPTO_LOCK_ECDH 34 +#define CRYPTO_LOCK_BN 35 +#define CRYPTO_LOCK_EC_PRE_COMP 36 +#define CRYPTO_LOCK_STORE 37 +#define CRYPTO_LOCK_COMP 38 +#define CRYPTO_LOCK_FIPS 39 +#define CRYPTO_LOCK_FIPS2 40 +#define CRYPTO_NUM_LOCKS 41 + +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +#ifndef CRYPTO_w_lock +#define CRYPTO_w_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,NULL,0) +#define CRYPTO_w_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,NULL,0) +#define CRYPTO_r_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,NULL,0) +#define CRYPTO_r_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,NULL,0) +#define CRYPTO_add(addr,amount,type) \ + CRYPTO_add_lock(addr,amount,type,NULL,0) +#endif + +/* Some applications as well as some parts of OpenSSL need to allocate + and deallocate locks in a dynamic fashion. The following typedef + makes this possible in a type-safe manner. */ +/* struct CRYPTO_dynlock_value has to be defined by the application. */ +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + + +/* The following can be used to detect memory leaks in the SSLeay library. + * It used, it turns on malloc checking */ + +#define CRYPTO_MEM_CHECK_OFF 0x0 /* an enume */ +#define CRYPTO_MEM_CHECK_ON 0x1 /* a bit */ +#define CRYPTO_MEM_CHECK_ENABLE 0x2 /* a bit */ +#define CRYPTO_MEM_CHECK_DISABLE 0x3 /* an enume */ + +/* The following are bit values to turn on or off options connected to the + * malloc checking functionality */ + +/* Adds time to the memory checking information */ +#define V_CRYPTO_MDEBUG_TIME 0x1 /* a bit */ +/* Adds thread number to the memory checking information */ +#define V_CRYPTO_MDEBUG_THREAD 0x2 /* a bit */ + +#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) + + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; +DECLARE_STACK_OF(void) + +#define CRYPTO_EX_INDEX_SSL 0 +#define CRYPTO_EX_INDEX_SSL_CTX 1 +#define CRYPTO_EX_INDEX_SSL_SESSION 2 +#define CRYPTO_EX_INDEX_APP 3 +#define CRYPTO_EX_INDEX_BIO 4 +#define CRYPTO_EX_INDEX_DH 5 +#define CRYPTO_EX_INDEX_DSA 6 +#define CRYPTO_EX_INDEX_EC_KEY 7 +#define CRYPTO_EX_INDEX_ENGINE 8 +#define CRYPTO_EX_INDEX_RSA 9 +#define CRYPTO_EX_INDEX_UI 10 +#define CRYPTO_EX_INDEX_UI_METHOD 11 +#define CRYPTO_EX_INDEX_X509 12 +#define CRYPTO_EX_INDEX_X509_STORE 13 +#define CRYPTO_EX_INDEX_X509_STORE_CTX 14 +#define CRYPTO_EX_INDEX__COUNT 15 + +#ifndef LIBRESSL_INTERNAL +#define CRYPTO_malloc_init() (0) +#define CRYPTO_malloc_debug_init() (0) + +#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ +# define CRYPTO_MDEBUG +# endif +#endif + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_is_mem_check_on(void); + +/* for applications */ +#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +#define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) + +#define OPENSSL_malloc(num) CRYPTO_malloc((int)num,NULL,0) +#define OPENSSL_strdup(str) CRYPTO_strdup((str),NULL,0) +#define OPENSSL_realloc(addr,num) \ + CRYPTO_realloc((char *)addr,(int)num,NULL,0) +#define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,NULL,0) +#define OPENSSL_remalloc(addr,num) \ + CRYPTO_remalloc((char **)addr,(int)num,NULL,0) +#define OPENSSL_freeFunc CRYPTO_free +#define OPENSSL_free(addr) CRYPTO_free(addr) + +#define OPENSSL_malloc_locked(num) \ + CRYPTO_malloc_locked((int)num,NULL,0) +#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) +#endif + +const char *OpenSSL_version(int type); +#define OPENSSL_VERSION 0 +#define OPENSSL_CFLAGS 1 +#define OPENSSL_BUILT_ON 2 +#define OPENSSL_PLATFORM 3 +#define OPENSSL_DIR 4 +#define OPENSSL_ENGINES_DIR 5 +unsigned long OpenSSL_version_num(void); + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +/* Within a given class, get/register a new index */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given + * class (invokes whatever per-class callbacks are applicable) */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index + * (relative to the class type involved) */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); +/* This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. */ +void CRYPTO_cleanup_all_ex_data(void); + +void CRYPTO_lock(int mode, int type, const char *file, int line); +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st { + void *ptr; + unsigned long val; +} CRYPTO_THREADID; +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); + +#ifndef LIBRESSL_INTERNAL +/* These functions are deprecated no-op stubs */ +void CRYPTO_set_id_callback(unsigned long (*func)(void)); +unsigned long (*CRYPTO_get_id_callback(void))(void); +unsigned long CRYPTO_thread_id(void); + +int CRYPTO_get_new_lockid(char *name); +const char *CRYPTO_get_lock_name(int type); + +int CRYPTO_num_locks(void); +void CRYPTO_set_locking_callback(void (*func)(int mode, int type, + const char *file, int line)); +void (*CRYPTO_get_locking_callback(void))(int mode, int type, + const char *file, int line); +void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, + const char *file, int line); + +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); + +int CRYPTO_get_new_dynlockid(void); +void CRYPTO_destroy_dynlockid(int i); +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line)); +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line)); +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); +void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file, int line); +#endif + +/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- + * call the latter last if you need different functions */ +int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t), void (*f)(void *)); +int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *)); +int CRYPTO_set_mem_ex_functions(void *(*m)(size_t, const char *, int), + void *(*r)(void *, size_t, const char *, int), void (*f)(void *)); +int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t, const char *, int), + void (*free_func)(void *)); +int CRYPTO_set_mem_debug_functions( + void (*m)(void *, int, const char *, int, int), + void (*r)(void *, void *, int, const char *, int, int), + void (*f)(void *, int), void (*so)(long), long (*go)(void)); +void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t), + void (**f)(void *)); +void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)); +void CRYPTO_get_mem_ex_functions(void *(**m)(size_t, const char *, int), + void *(**r)(void *, size_t, const char *, int), void (**f)(void *)); +void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t, const char *, int), + void (**f)(void *)); +void CRYPTO_get_mem_debug_functions( + void (**m)(void *, int, const char *, int, int), + void (**r)(void *, void *, int, const char *, int, int), + void (**f)(void *, int), void (**so)(long), long (**go)(void)); + +#ifndef LIBRESSL_INTERNAL +void *CRYPTO_malloc_locked(int num, const char *file, int line); +void CRYPTO_free_locked(void *ptr); +void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +void CRYPTO_free(void *ptr); +void *CRYPTO_realloc(void *addr, int num, const char *file, int line); +#endif + +void *CRYPTO_realloc_clean(void *addr, int old_num, int num, + const char *file, int line); +void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); + +#ifndef LIBRESSL_INTERNAL +void OPENSSL_cleanse(void *ptr, size_t len); +#endif + +void CRYPTO_set_mem_debug_options(long bits); +long CRYPTO_get_mem_debug_options(void); + +#define CRYPTO_push_info(info) \ + CRYPTO_push_info_(info, NULL, 0); +int CRYPTO_push_info_(const char *info, const char *file, int line); +int CRYPTO_pop_info(void); +int CRYPTO_remove_all_info(void); + + +/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; + * used as default in CRYPTO_MDEBUG compilations): */ +/* The last argument has the following significance: + * + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, int before_p) + __attribute__ ((deprecated)); +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file, int line, int before_p) + __attribute__ ((deprecated)); +void CRYPTO_dbg_free(void *addr, int before_p) + __attribute__ ((deprecated)); +/* Tell the debugging code about options. By default, the following values + * apply: + * + * 0: Clear all options. + * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. + * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. + * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 + */ +void CRYPTO_dbg_set_options(long bits) + __attribute__ ((deprecated)); +long CRYPTO_dbg_get_options(void) + __attribute__ ((deprecated)); + + +int CRYPTO_mem_leaks_fp(FILE *); +int CRYPTO_mem_leaks(struct bio_st *bio); +/* unsigned long order, char *file, int line, int num_bytes, char *addr */ +typedef int *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *); +int CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); + +/* + * Because this is a public header, use a portable method of indicating the + * function does not return, rather than __dead. + */ +#ifdef _MSC_VER +__declspec(noreturn) +#else +__attribute__((__noreturn__)) +#endif +void OpenSSLDie(const char *file, int line, const char *assertion); +#define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) + +uint64_t OPENSSL_cpu_caps(void); + +int OPENSSL_isservice(void); + +#ifndef LIBRESSL_INTERNAL +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); + +/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It + * takes an amount of time dependent on |len|, but independent of the contents + * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a + * defined order as the return value when a != b is undefined, other than to be + * non-zero. */ +int CRYPTO_memcmp(const void *a, const void *b, size_t len); +#endif + +/* + * OpenSSL compatible OPENSSL_INIT options. + */ + +#define OPENSSL_INIT_NO_LOAD_CONFIG 0x00000001L +#define OPENSSL_INIT_LOAD_CONFIG 0x00000002L + +/* LibreSSL specific */ +#define _OPENSSL_INIT_FLAG_NOOP 0x80000000L + +/* + * These are provided for compatibility, but have no effect + * on how LibreSSL is initialized. + */ +#define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ADD_ALL_CIPHERS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ADD_ALL_DIGESTS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_NO_ADD_ALL_CIPHERS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_NO_ADD_ALL_DIGESTS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ASYNC _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_RDRAND _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_DYNAMIC _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_OPENSSL _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_CRYPTODEV _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_CAPI _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_PADLOCK _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_AFALG _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_reserved_internal _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ATFORK _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_ALL_BUILTIN _OPENSSL_INIT_FLAG_NOOP + +int OPENSSL_init_crypto(uint64_t opts, const void *settings); +void OPENSSL_cleanup(void); + +void ERR_load_CRYPTO_strings(void); + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 +#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +#define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +#define CRYPTO_F_DEF_ADD_INDEX 104 +#define CRYPTO_F_DEF_GET_CLASS 105 +#define CRYPTO_F_FIPS_MODE_SET 109 +#define CRYPTO_F_INT_DUP_EX_DATA 106 +#define CRYPTO_F_INT_FREE_EX_DATA 107 +#define CRYPTO_F_INT_NEW_EX_DATA 108 + +/* Reason codes. */ +#define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ct.h b/Libraries/libressl/include/openssl/ct.h new file mode 100644 index 000000000..895046e00 --- /dev/null +++ b/Libraries/libressl/include/openssl/ct.h @@ -0,0 +1,567 @@ +/* $OpenBSD: ct.h,v 1.7 2022/05/08 20:59:32 tb Exp $ */ +/* + * Public API for Certificate Transparency (CT). + * Written by Rob Percival (robpercival@google.com) for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CT_H +#define HEADER_CT_H + +#include + +#ifndef OPENSSL_NO_CT +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/* Minimum RSA key size, from RFC6962 */ +#define SCT_MIN_RSA_BITS 2048 + +/* All hashes are SHA256 in v1 of Certificate Transparency */ +#define CT_V1_HASHLEN SHA256_DIGEST_LENGTH + +typedef enum { + CT_LOG_ENTRY_TYPE_NOT_SET = -1, + CT_LOG_ENTRY_TYPE_X509 = 0, + CT_LOG_ENTRY_TYPE_PRECERT = 1 +} ct_log_entry_type_t; + +typedef enum { + SCT_VERSION_NOT_SET = -1, + SCT_VERSION_V1 = 0 +} sct_version_t; + +typedef enum { + SCT_SOURCE_UNKNOWN, + SCT_SOURCE_TLS_EXTENSION, + SCT_SOURCE_X509V3_EXTENSION, + SCT_SOURCE_OCSP_STAPLED_RESPONSE +} sct_source_t; + +typedef enum { + SCT_VALIDATION_STATUS_NOT_SET, + SCT_VALIDATION_STATUS_UNKNOWN_LOG, + SCT_VALIDATION_STATUS_VALID, + SCT_VALIDATION_STATUS_INVALID, + SCT_VALIDATION_STATUS_UNVERIFIED, + SCT_VALIDATION_STATUS_UNKNOWN_VERSION +} sct_validation_status_t; + +DECLARE_STACK_OF(SCT) +DECLARE_STACK_OF(CTLOG) + +/****************************************** + * CT policy evaluation context functions * + ******************************************/ + +/* + * Creates a new, empty policy evaluation context. + * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished + * with the CT_POLICY_EVAL_CTX. + */ +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); + +/* Deletes a policy evaluation context and anything it owns. */ +void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx); + +/* Gets the peer certificate that the SCTs are for */ +X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the certificate associated with the received SCTs. + * Increments the reference count of cert. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert); + +/* Gets the issuer of the aforementioned certificate */ +X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the issuer of the certificate associated with the received SCTs. + * Increments the reference count of issuer. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer); + +/* Gets the CT logs that are trusted sources of SCTs */ +const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx); + +/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */ +void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_STORE *log_store); + +/* + * Gets the time, in milliseconds since the Unix epoch, that will be used as the + * current time when checking whether an SCT was issued in the future. + * Such SCTs will fail validation, as required by RFC6962. + */ +uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch. + * If an SCT's timestamp is after this time, it will be interpreted as having + * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs + * whose timestamp is in the future", so an SCT will not validate in this case. + */ +void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms); + +/***************** + * SCT functions * + *****************/ + +/* + * Creates a new, blank SCT. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new(void); + +/* + * Creates a new SCT from some base64-encoded strings. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, + ct_log_entry_type_t entry_type, uint64_t timestamp, + const char *extensions_base64, const char *signature_base64); + +/* + * Frees the SCT and the underlying data structures. + */ +void SCT_free(SCT *sct); + +/* + * Free a stack of SCTs, and the underlying SCTs themselves. + * Intended to be compatible with X509V3_EXT_FREE. + */ +void SCT_LIST_free(STACK_OF(SCT) *a); + +/* + * Returns the version of the SCT. + */ +sct_version_t SCT_get_version(const SCT *sct); + +/* + * Set the version of an SCT. + * Returns 1 on success, 0 if the version is unrecognized. + */ +int SCT_set_version(SCT *sct, sct_version_t version); + +/* + * Returns the log entry type of the SCT. + */ +ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct); + +/* + * Set the log entry type of an SCT. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type); + +/* + * Gets the ID of the log that an SCT came from. + * Ownership of the log ID remains with the SCT. + * Returns the length of the log ID. + */ +size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id); + +/* + * Set the log ID of an SCT to point directly to the *log_id specified. + * The SCT takes ownership of the specified pointer. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len); + +/* + * Set the log ID of an SCT. + * This makes a copy of the log_id. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, + size_t log_id_len); + +/* + * Returns the timestamp for the SCT (epoch time in milliseconds). + */ +uint64_t SCT_get_timestamp(const SCT *sct); + +/* + * Set the timestamp of an SCT (epoch time in milliseconds). + */ +void SCT_set_timestamp(SCT *sct, uint64_t timestamp); + +/* + * Return the NID for the signature used by the SCT. + * For CT v1, this will be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset). + */ +int SCT_get_signature_nid(const SCT *sct); + +/* + * Set the signature type of an SCT + * For CT v1, this should be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set_signature_nid(SCT *sct, int nid); + +/* + * Set *ext to point to the extension data for the SCT. ext must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext); + +/* + * Set the extensions of an SCT to point directly to the *ext specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len); + +/* + * Set the extensions of an SCT. + * This takes a copy of the ext. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set1_extensions(SCT *sct, const unsigned char *ext, + size_t ext_len); + +/* + * Set *sig to point to the signature for the SCT. sig must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_signature(const SCT *sct, unsigned char **sig); + +/* + * Set the signature of an SCT to point directly to the *sig specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len); + +/* + * Set the signature of an SCT to be a copy of the *sig specified. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set1_signature(SCT *sct, const unsigned char *sig, + size_t sig_len); + +/* + * The origin of this SCT, e.g. TLS extension, OCSP response, etc. + */ +sct_source_t SCT_get_source(const SCT *sct); + +/* + * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc. + * Returns 1 on success, 0 otherwise. + */ +int SCT_set_source(SCT *sct, sct_source_t source); + +/* + * Returns a text string describing the validation status of |sct|. + */ +const char *SCT_validation_status_string(const SCT *sct); + +/* + * Pretty-prints an |sct| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came + * from, so that the log name can be printed. + */ +void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs); + +/* + * Pretty-prints an |sct_list| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * SCTs will be delimited by |separator|. + * If |logs| is not NULL, it will be used to lookup the CT log that each SCT + * came from, so that the log names can be printed. + */ +void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, + const char *separator, const CTLOG_STORE *logs); + +/* + * Gets the last result of validating this SCT. + * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET. + */ +sct_validation_status_t SCT_get_validation_status(const SCT *sct); + +/* + * Validates the given SCT with the provided context. + * Sets the "validation_status" field of the SCT. + * Returns 1 if the SCT is valid and the signature verifies. + * Returns 0 if the SCT is invalid or could not be verified. + * Returns -1 if an error occurs. + */ +int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx); + +/* + * Validates the given list of SCTs with the provided context. + * Sets the "validation_status" field of each SCT. + * Returns 1 if there are no invalid SCTs and all signatures verify. + * Returns 0 if at least one SCT is invalid or could not be verified. + * Returns a negative integer if an error occurs. + */ +int SCT_LIST_validate(const STACK_OF(SCT) *scts, + CT_POLICY_EVAL_CTX *ctx); + + +/********************************* + * SCT parsing and serialisation * + *********************************/ + +/* + * Serialize (to TLS format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just return the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Convert TLS format SCT list to a stack of SCTs. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + size_t len); + +/* + * Serialize (to DER format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just returns the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Parses an SCT list in DER format and returns it. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + long len); + +/* + * Serialize (to TLS format) an |sct| and write it to |out|. + * If |out| is null, no SCT will be output but the length will still be returned. + * If |out| points to a null pointer, a string will be allocated to hold the + * TLS-format SCT. It is the responsibility of the caller to free it. + * If |out| points to an allocated string, the TLS-format SCT will be written + * to it. + * The length of the SCT in TLS format will be returned. + */ +int i2o_SCT(const SCT *sct, unsigned char **out); + +/* + * Parses an SCT in TLS format and returns it. + * If |psct| is not null, it will end up pointing to the parsed SCT. If it + * already points to a non-null pointer, the pointer will be free'd. + * |in| should be a pointer to a string containing the TLS-format SCT. + * |in| will be advanced to the end of the SCT if parsing succeeds. + * |len| should be the length of the SCT in |in|. + * Returns NULL if an error occurs. + * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len' + * fields will be populated (with |in| and |len| respectively). + */ +SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len); + +/******************** + * CT log functions * + ********************/ + +/* + * Creates a new CT log instance with the given |public_key| and |name|. + * Takes ownership of |public_key| but copies |name|. + * Returns NULL if malloc fails or if |public_key| cannot be converted to DER. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); + +/* + * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER + * in |pkey_base64|. The |name| is a string to help users identify this log. + * Returns 1 on success, 0 on failure. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, + const char *name); + +/* + * Deletes a CT log instance and its fields. + */ +void CTLOG_free(CTLOG *log); + +/* Gets the name of the CT log */ +const char *CTLOG_get0_name(const CTLOG *log); +/* Gets the ID of the CT log */ +void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, + size_t *log_id_len); +/* Gets the public key of the CT log */ +EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log); + +/************************** + * CT log store functions * + **************************/ + +/* + * Creates a new CT log store. + * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. + */ +CTLOG_STORE *CTLOG_STORE_new(void); + +/* + * Deletes a CT log store and all of the CT log instances held within. + */ +void CTLOG_STORE_free(CTLOG_STORE *store); + +/* + * Finds a CT log in the store based on its log ID. + * Returns the CT log, or NULL if no match is found. + */ +const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, + const uint8_t *log_id, size_t log_id_len); + +/* + * Loads a CT log list into a |store| from a |file|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file); + +/* + * Loads the default CT log list into a |store|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +int CTLOG_STORE_load_default_file(CTLOG_STORE *store); + +int ERR_load_CT_strings(void); + +/* + * CT function codes. + */ +# define CT_F_CTLOG_NEW 117 +# define CT_F_CTLOG_NEW_FROM_BASE64 118 +# define CT_F_CTLOG_NEW_FROM_CONF 119 +# define CT_F_CTLOG_STORE_LOAD_CTX_NEW 122 +# define CT_F_CTLOG_STORE_LOAD_FILE 123 +# define CT_F_CTLOG_STORE_LOAD_LOG 130 +# define CT_F_CTLOG_STORE_NEW 131 +# define CT_F_CT_BASE64_DECODE 124 +# define CT_F_CT_POLICY_EVAL_CTX_NEW 133 +# define CT_F_CT_V1_LOG_ID_FROM_PKEY 125 +# define CT_F_I2O_SCT 107 +# define CT_F_I2O_SCT_LIST 108 +# define CT_F_I2O_SCT_SIGNATURE 109 +# define CT_F_O2I_SCT 110 +# define CT_F_O2I_SCT_LIST 111 +# define CT_F_O2I_SCT_SIGNATURE 112 +# define CT_F_SCT_CTX_NEW 126 +# define CT_F_SCT_CTX_VERIFY 128 +# define CT_F_SCT_NEW 100 +# define CT_F_SCT_NEW_FROM_BASE64 127 +# define CT_F_SCT_SET0_LOG_ID 101 +# define CT_F_SCT_SET1_EXTENSIONS 114 +# define CT_F_SCT_SET1_LOG_ID 115 +# define CT_F_SCT_SET1_SIGNATURE 116 +# define CT_F_SCT_SET_LOG_ENTRY_TYPE 102 +# define CT_F_SCT_SET_SIGNATURE_NID 103 +# define CT_F_SCT_SET_VERSION 104 + +/* + * CT reason codes. + */ +# define CT_R_BASE64_DECODE_ERROR 108 +# define CT_R_INVALID_LOG_ID_LENGTH 100 +# define CT_R_LOG_CONF_INVALID 109 +# define CT_R_LOG_CONF_INVALID_KEY 110 +# define CT_R_LOG_CONF_MISSING_DESCRIPTION 111 +# define CT_R_LOG_CONF_MISSING_KEY 112 +# define CT_R_LOG_KEY_INVALID 113 +# define CT_R_SCT_FUTURE_TIMESTAMP 116 +# define CT_R_SCT_INVALID 104 +# define CT_R_SCT_INVALID_SIGNATURE 107 +# define CT_R_SCT_LIST_INVALID 105 +# define CT_R_SCT_LOG_ID_MISMATCH 114 +# define CT_R_SCT_NOT_SET 106 +# define CT_R_SCT_UNSUPPORTED_VERSION 115 +# define CT_R_UNRECOGNIZED_SIGNATURE_NID 101 +# define CT_R_UNSUPPORTED_ENTRY_TYPE 102 +# define CT_R_UNSUPPORTED_VERSION 103 + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/Libraries/libressl/include/openssl/curve25519.h b/Libraries/libressl/include/openssl/curve25519.h new file mode 100644 index 000000000..e42bc22c1 --- /dev/null +++ b/Libraries/libressl/include/openssl/curve25519.h @@ -0,0 +1,104 @@ +/* $OpenBSD: curve25519.h,v 1.7 2022/11/13 14:05:04 tb Exp $ */ +/* + * Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_CURVE25519_H +#define HEADER_CURVE25519_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Curve25519. + * + * Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. + */ + +/* + * X25519. + * + * X25519 is the Diffie-Hellman primitive built from curve25519. It is + * sometimes referred to as curve25519, but X25519 is a more precise name. + * See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. + */ + +#define X25519_KEY_LENGTH 32 + +/* + * X25519_keypair sets |out_public_value| and |out_private_key| to a freshly + * generated, public/private key pair. + */ +void X25519_keypair(uint8_t out_public_value[X25519_KEY_LENGTH], + uint8_t out_private_key[X25519_KEY_LENGTH]); + +/* + * X25519 writes a shared key to |out_shared_key| that is calculated from the + * given private key and the peer's public value. It returns one on success and + * zero on error. + * + * Don't use the shared key directly, rather use a KDF and also include the two + * public values as inputs. + */ +int X25519(uint8_t out_shared_key[X25519_KEY_LENGTH], + const uint8_t private_key[X25519_KEY_LENGTH], + const uint8_t peers_public_value[X25519_KEY_LENGTH]); + +/* + * ED25519 + * + * Ed25519 is a signature scheme using a twisted Edwards curve that is + * birationally equivalent to curve25519. + */ + +#define ED25519_PRIVATE_KEY_LENGTH 32 +#define ED25519_PUBLIC_KEY_LENGTH 32 +#define ED25519_SIGNATURE_LENGTH 64 + +/* + * ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly + * generated, public/private key pair. + */ +void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH], + uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]); + +/* + * ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from + * |message| using |public_key| and |private_key|. It returns one on success + * or zero on allocation failure. + */ +int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, + const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH], + const uint8_t private_key_seed[ED25519_PRIVATE_KEY_LENGTH]); + +/* + * ED25519_verify returns one iff |signature| is a valid signature by + * |public_key| of |message_len| bytes from |message|. It returns zero + * otherwise. + */ +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[ED25519_SIGNATURE_LENGTH], + const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]); + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* HEADER_CURVE25519_H */ diff --git a/Libraries/libressl/include/openssl/des.h b/Libraries/libressl/include/openssl/des.h new file mode 100644 index 000000000..bc5d35f37 --- /dev/null +++ b/Libraries/libressl/include/openssl/des.h @@ -0,0 +1,215 @@ +/* $OpenBSD: des.h,v 1.21 2023/07/31 05:04:06 tb Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_NEW_DES_H +#define HEADER_NEW_DES_H + +#include + +#ifdef OPENSSL_NO_DES +#error DES is disabled. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * + * and const_DES_cblock * are incompatible pointer types. */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* make sure things are correct size on machines with + * 8 byte longs */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +#define DES_KEY_SZ (sizeof(DES_cblock)) +#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define DES_CBC_MODE 0 +#define DES_PCBC_MODE 1 + +#define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +extern int DES_check_key; /* defaults to false */ +extern int DES_rw_mode; /* defaults to DES_PCBC_MODE */ + +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, DES_cblock *ivec, + int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, DES_cblock *ivec, + int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, DES_cblock *ivec, + const_DES_cblock *inw, const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, DES_cblock *ivec, + int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* This is the DES encryption function that gets called by just about + every other DES routine in the library. You should not use this + function except to implement 'modes' of DES. I say this because the + functions that call this routine do the conversion from 'char *' to + long, and this needs to be done to make sure 'non-aligned' memory + access do not occur. The characters are loaded 'little endian'. + Data is a pointer to 2 unsigned long's and ks is the + DES_key_schedule to use. enc, is non zero specifies encryption, + zero if decryption. */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* This functions is the same as DES_encrypt1() except that the DES + initial permutation (IP) and final permutation (FP) have been left + out. As for DES_encrypt1(), you should not use this function. + It is used by the routines in the library that implement triple DES. + IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same + as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec1, DES_cblock *ivec2, + int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, DES_cblock *ivec, + int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, + DES_key_schedule *schedule, DES_cblock *ivec, int *num, + int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, + DES_key_schedule *schedule, DES_cblock *ivec, int *num); + +#define DES_fixup_key_parity DES_set_odd_parity + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/dh.h b/Libraries/libressl/include/openssl/dh.h new file mode 100644 index 000000000..65b4348ac --- /dev/null +++ b/Libraries/libressl/include/openssl/dh.h @@ -0,0 +1,249 @@ +/* $OpenBSD: dh.h,v 1.37 2023/04/18 08:33:43 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_H +#define HEADER_DH_H + +#include + +#ifdef OPENSSL_NO_DH +#error DH is disabled. +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +#endif + +#define DH_FLAG_CACHE_MONT_P 0x01 + +/* If this flag is set the DH method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define DH_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +#define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +#define DH_GENERATOR_5 5 + +/* DH_check error codes */ +#define DH_CHECK_P_NOT_PRIME 0x01 +#define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +#define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_NOT_SUITABLE_GENERATOR 0x08 +#define DH_CHECK_Q_NOT_PRIME 0x10 +#define DH_CHECK_INVALID_Q_VALUE 0x20 +#define DH_CHECK_INVALID_J_VALUE 0x40 + +/* DH_check_pub_key error codes */ +#define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +#define DH_CHECK_PUBKEY_INVALID 0x04 + +/* primes p where (p-1)/2 is prime too are called "safe"; we define + this for backward compatibility: */ +#define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +DH *d2i_DHparams_bio(BIO *bp, DH **a); +int i2d_DHparams_bio(BIO *bp, DH *a); +DH *d2i_DHparams_fp(FILE *fp, DH **a); +int i2d_DHparams_fp(FILE *fp, DH *a); + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH * DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_size(const DH *dh); +int DH_bits(const DH *dh); +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); +int DH_security_bits(const DH *dh); + +ENGINE *DH_get0_engine(DH *d); +void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DH_get0_p(const DH *dh); +const BIGNUM *DH_get0_q(const DH *dh); +const BIGNUM *DH_get0_g(const DH *dh); +const BIGNUM *DH_get0_priv_key(const DH *dh); +const BIGNUM *DH_get0_pub_key(const DH *dh); +void DH_clear_flags(DH *dh, int flags); +int DH_test_flags(const DH *dh, int flags); +void DH_set_flags(DH *dh, int flags); +long DH_get_length(const DH *dh); +int DH_set_length(DH *dh, long length); + +/* + * Wrapped in OPENSSL_NO_DEPRECATED in 0.9.8, added to rust-openssl in 2020, + * for "advanced DH support". + */ +DH * DH_generate_parameters(int prime_len,int generator, + void (*callback)(int,int,void *),void *cb_arg); + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb); + +int DH_check(const DH *dh,int *codes); +int DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); +DH * d2i_DHparams(DH **a,const unsigned char **pp, long length); +int i2d_DHparams(const DH *a,unsigned char **pp); +int DHparams_print_fp(FILE *fp, const DH *x); +#ifndef OPENSSL_NO_BIO +int DHparams_print(BIO *bp, const DH *x); +#else +int DHparams_print(char *bp, const DH *x); +#endif + +#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +#define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) + + +void ERR_load_DH_strings(void); + +/* Error codes for the DH functions. */ + +/* Function codes. */ +#define DH_F_COMPUTE_KEY 102 +#define DH_F_DHPARAMS_PRINT_FP 101 +#define DH_F_DH_BUILTIN_GENPARAMS 106 +#define DH_F_DH_COMPUTE_KEY 114 +#define DH_F_DH_GENERATE_KEY 115 +#define DH_F_DH_GENERATE_PARAMETERS_EX 116 +#define DH_F_DH_NEW_METHOD 105 +#define DH_F_DH_PARAM_DECODE 107 +#define DH_F_DH_PRIV_DECODE 110 +#define DH_F_DH_PRIV_ENCODE 111 +#define DH_F_DH_PUB_DECODE 108 +#define DH_F_DH_PUB_ENCODE 109 +#define DH_F_DO_DH_PRINT 100 +#define DH_F_GENERATE_KEY 103 +#define DH_F_GENERATE_PARAMETERS 104 +#define DH_F_PKEY_DH_DERIVE 112 +#define DH_F_PKEY_DH_KEYGEN 113 + +/* Reason codes. */ +#define DH_R_BAD_GENERATOR 101 +#define DH_R_BN_DECODE_ERROR 109 +#define DH_R_BN_ERROR 106 +#define DH_R_DECODE_ERROR 104 +#define DH_R_INVALID_PUBKEY 102 +#define DH_R_KEYS_NOT_SET 108 +#define DH_R_KEY_SIZE_TOO_SMALL 110 +#define DH_R_MODULUS_TOO_LARGE 103 +#define DH_R_NON_FIPS_METHOD 111 +#define DH_R_NO_PARAMETERS_SET 107 +#define DH_R_NO_PRIVATE_VALUE 100 +#define DH_R_PARAMETER_ENCODING_ERROR 105 +#define DH_R_CHECK_INVALID_J_VALUE 115 +#define DH_R_CHECK_INVALID_Q_VALUE 116 +#define DH_R_CHECK_PUBKEY_INVALID 122 +#define DH_R_CHECK_PUBKEY_TOO_LARGE 123 +#define DH_R_CHECK_PUBKEY_TOO_SMALL 124 +#define DH_R_CHECK_P_NOT_PRIME 117 +#define DH_R_CHECK_P_NOT_SAFE_PRIME 118 +#define DH_R_CHECK_Q_NOT_PRIME 119 +#define DH_R_MISSING_PUBKEY 125 +#define DH_R_NOT_SUITABLE_GENERATOR 120 +#define DH_R_UNABLE_TO_CHECK_GENERATOR 121 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/dsa.h b/Libraries/libressl/include/openssl/dsa.h new file mode 100644 index 000000000..8029e7f94 --- /dev/null +++ b/Libraries/libressl/include/openssl/dsa.h @@ -0,0 +1,282 @@ +/* $OpenBSD: dsa.h,v 1.43 2023/04/18 08:47:28 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch . He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +#define HEADER_DSA_H + +#include + +#ifdef OPENSSL_NO_DSA +#error DSA is disabled. +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#ifndef OPENSSL_NO_DH +# include +#endif + +#include + +#ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +#endif + +#define DSA_FLAG_CACHE_MONT_P 0x01 + +/* If this flag is set the DSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define DSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DSA_SIG_st DSA_SIG; + +DSA *d2i_DSAparams_bio(BIO *bp, DSA **a); +int i2d_DSAparams_bio(BIO *bp, DSA *a); +DSA *d2i_DSAparams_fp(FILE *fp, DSA **a); +int i2d_DSAparams_fp(FILE *fp, DSA *a); + +DSA *DSAparams_dup(DSA *x); +DSA_SIG * DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa); +int DSA_do_verify(const unsigned char *dgst,int dgst_len, + DSA_SIG *sig,DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); + +DSA * DSA_new(void); +DSA * DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); +int DSA_bits(const DSA *d); + /* next 4 return -1 on error */ +int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp); +int DSA_sign(int type,const unsigned char *dgst,int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type,const unsigned char *dgst,int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); +int DSA_security_bits(const DSA *d); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +extern const ASN1_ITEM DSAPublicKey_it; + +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +extern const ASN1_ITEM DSAPrivateKey_it; + +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); +int i2d_DSAparams(const DSA *a,unsigned char **pp); +extern const ASN1_ITEM DSAparams_it; + +/* Wrapped in OPENSSL_NO_DEPRECATED in 0.9.8. Still used in 2023. */ +DSA * DSA_generate_parameters(int bits, + unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret,void + (*callback)(int, int, void *),void *cb_arg); + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + +int DSA_generate_key(DSA *a); + +#ifndef OPENSSL_NO_BIO +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +#endif +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); + +/* + * Primality test according to FIPS PUB 186-4, Appendix C.3. Set the number + * to 64 rounds of Miller-Rabin, which corresponds to 128 bits of security. + * This is necessary for keys of size >= 3072. + */ +#define DSS_prime_checks 64 +#define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +#ifndef OPENSSL_NO_DH +/* Convert DSA structure (key or just parameters) into DH structure + * (be careful to avoid small subgroup attacks when using this!) */ +DH *DSA_dup_DH(const DSA *r); +#endif + +void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g); +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key); +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DSA_get0_p(const DSA *d); +const BIGNUM *DSA_get0_q(const DSA *d); +const BIGNUM *DSA_get0_g(const DSA *d); +const BIGNUM *DSA_get0_pub_key(const DSA *d); +const BIGNUM *DSA_get0_priv_key(const DSA *d); +void DSA_clear_flags(DSA *d, int flags); +int DSA_test_flags(const DSA *d, int flags); +void DSA_set_flags(DSA *d, int flags); +ENGINE *DSA_get0_engine(DSA *d); + +DSA_METHOD *DSA_meth_new(const char *name, int flags); +void DSA_meth_free(DSA_METHOD *meth); +DSA_METHOD *DSA_meth_dup(const DSA_METHOD *meth); +const char *DSA_meth_get0_name(const DSA_METHOD *meth); +int DSA_meth_set1_name(DSA_METHOD *meth, const char *name); +int DSA_meth_set_sign(DSA_METHOD *meth, + DSA_SIG *(*sign)(const unsigned char *, int, DSA *)); +int DSA_meth_set_finish(DSA_METHOD *meth, int (*finish)(DSA *)); + +#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +#define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +void ERR_load_DSA_strings(void); + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +#define DSA_F_D2I_DSA_SIG 110 +#define DSA_F_DO_DSA_PRINT 104 +#define DSA_F_DSAPARAMS_PRINT 100 +#define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_DO_SIGN 112 +#define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_GENERATE_KEY 124 +#define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +#define DSA_F_DSA_NEW_METHOD 103 +#define DSA_F_DSA_PARAM_DECODE 119 +#define DSA_F_DSA_PRINT_FP 105 +#define DSA_F_DSA_PRIV_DECODE 115 +#define DSA_F_DSA_PRIV_ENCODE 116 +#define DSA_F_DSA_PUB_DECODE 117 +#define DSA_F_DSA_PUB_ENCODE 118 +#define DSA_F_DSA_SIGN 106 +#define DSA_F_DSA_SIGN_SETUP 107 +#define DSA_F_DSA_SIG_NEW 109 +#define DSA_F_DSA_SIG_PRINT 125 +#define DSA_F_DSA_VERIFY 108 +#define DSA_F_I2D_DSA_SIG 111 +#define DSA_F_OLD_DSA_PRIV_DECODE 122 +#define DSA_F_PKEY_DSA_CTRL 120 +#define DSA_F_PKEY_DSA_KEYGEN 121 +#define DSA_F_SIG_CB 114 + +/* Reason codes. */ +#define DSA_R_BAD_Q_VALUE 102 +#define DSA_R_BN_DECODE_ERROR 108 +#define DSA_R_BN_ERROR 109 +#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +#define DSA_R_DECODE_ERROR 104 +#define DSA_R_INVALID_DIGEST_TYPE 106 +#define DSA_R_INVALID_PARAMETERS 112 +#define DSA_R_MISSING_PARAMETERS 101 +#define DSA_R_MODULUS_TOO_LARGE 103 +#define DSA_R_NEED_NEW_SETUP_VALUES 110 +#define DSA_R_NON_FIPS_DSA_METHOD 111 +#define DSA_R_NO_PARAMETERS_SET 107 +#define DSA_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/dtls1.h b/Libraries/libressl/include/openssl/dtls1.h new file mode 100644 index 000000000..79542c807 --- /dev/null +++ b/Libraries/libressl/include/openssl/dtls1.h @@ -0,0 +1,107 @@ +/* $OpenBSD: dtls1.h,v 1.27 2021/05/16 13:56:30 jsing Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS1_H +#define HEADER_DTLS1_H + +#if defined(_WIN32) +#include +#else +#include +#endif + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DTLS1_VERSION 0xFEFF +#define DTLS1_2_VERSION 0xFEFD +#define DTLS1_VERSION_MAJOR 0xFE + +/* lengths of messages */ +#define DTLS1_COOKIE_LENGTH 256 + +#define DTLS1_RT_HEADER_LENGTH 13 + +#define DTLS1_HM_HEADER_LENGTH 12 + +#define DTLS1_HM_BAD_FRAGMENT -2 +#define DTLS1_HM_FRAGMENT_RETRY -3 + +#define DTLS1_CCS_HEADER_LENGTH 1 + +#define DTLS1_AL_HEADER_LENGTH 2 + +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ +#define DTLS1_TMO_READ_COUNT 2 +#define DTLS1_TMO_WRITE_COUNT 2 + +#define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ec.h b/Libraries/libressl/include/openssl/ec.h new file mode 100644 index 000000000..9e3354df4 --- /dev/null +++ b/Libraries/libressl/include/openssl/ec.h @@ -0,0 +1,722 @@ +/* $OpenBSD: ec.h,v 1.46 2023/08/11 04:45:27 tb Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + */ + +#ifndef HEADER_EC_H +#define HEADER_EC_H + +#include + +#ifdef OPENSSL_NO_EC +#error EC is disabled. +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#elif defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +#endif + +#ifndef OPENSSL_ECC_MAX_FIELD_BITS +#define OPENSSL_ECC_MAX_FIELD_BITS 661 +#endif + +/* Elliptic point conversion form as per X9.62, page 4 and section 4.4.2. */ +typedef enum { + POINT_CONVERSION_COMPRESSED = 2, + POINT_CONVERSION_UNCOMPRESSED = 4, + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_point_st EC_POINT; + +const EC_METHOD *EC_GFp_simple_method(void); +const EC_METHOD *EC_GFp_mont_method(void); + +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); +void EC_GROUP_free(EC_GROUP *group); +#ifndef LIBRESSL_INTERNAL +void EC_GROUP_clear_free(EC_GROUP *group); +#endif + +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); +int EC_GROUP_order_bits(const EC_GROUP *group); +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); + +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *ctx); + +#if !defined(LIBRESSL_INTERNAL) +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); +#endif + +int EC_GROUP_get_degree(const EC_GROUP *group); + +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/* Compare two EC_GROUPs. Returns 0 if both groups are equal, 1 otherwise. */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +EC_POINT *EC_POINT_new(const EC_GROUP *group); +void EC_POINT_free(EC_POINT *point); +#ifndef LIBRESSL_INTERNAL +void EC_POINT_clear_free(EC_POINT *point); +#endif +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); +int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); +int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); + +#ifndef LIBRESSL_INTERNAL +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx); +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); +#endif /* !LIBRESSL_INTERNAL */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx); +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, EC_POINT *, + BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, EC_POINT *, + BN_CTX *); + +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], + BN_CTX *ctx); +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx); +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +int EC_GROUP_get_basis_type(const EC_GROUP *); + +#define OPENSSL_EC_EXPLICIT_CURVE 0x000 +#define OPENSSL_EC_NAMED_CURVE 0x001 + +typedef struct ecpk_parameters_st ECPKPARAMETERS; + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +#ifndef OPENSSL_NO_BIO +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +#endif +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); + +#define EC_PKEY_NO_PARAMETERS 0x001 +#define EC_PKEY_NO_PUBKEY 0x002 + +#define EC_FLAG_NON_FIPS_ALLOW 0x1 +#define EC_FLAG_FIPS_CHECKED 0x2 +#define EC_FLAG_COFACTOR_ECDH 0x1000 + +EC_KEY *EC_KEY_new(void); +int EC_KEY_get_flags(const EC_KEY *key); +void EC_KEY_set_flags(EC_KEY *key, int flags); +void EC_KEY_clear_flags(EC_KEY *key, int flags); +EC_KEY *EC_KEY_new_by_curve_name(int nid); +void EC_KEY_free(EC_KEY *key); +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); +EC_KEY *EC_KEY_dup(const EC_KEY *src); +int EC_KEY_up_ref(EC_KEY *key); + +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); + +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); +int EC_KEY_generate_key(EC_KEY *key); +int EC_KEY_check_key(const EC_KEY *key); +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y); + +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); +int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out); + +#ifndef OPENSSL_NO_BIO +int ECParameters_print(BIO *bp, const EC_KEY *key); +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); +#endif +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef) +int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg); +void *EC_KEY_get_ex_data(const EC_KEY *key, int idx); + +const EC_KEY_METHOD *EC_KEY_OpenSSL(void); +const EC_KEY_METHOD *EC_KEY_get_default_method(void); +void EC_KEY_set_default_method(const EC_KEY_METHOD *meth); +const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key); +int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth); +EC_KEY *EC_KEY_new_method(ENGINE *engine); + +int ECDH_size(const EC_KEY *ecdh); +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); + +typedef struct ECDSA_SIG_st ECDSA_SIG; + +ECDSA_SIG *ECDSA_SIG_new(void); +void ECDSA_SIG_free(ECDSA_SIG *sig); +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); +const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +int ECDSA_size(const EC_KEY *eckey); + +ECDSA_SIG *ECDSA_do_sign(const unsigned char *digest, int digest_len, + EC_KEY *eckey); +int ECDSA_do_verify(const unsigned char *digest, int digest_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +int ECDSA_sign(int type, const unsigned char *digest, int digest_len, + unsigned char *signature, unsigned int *signature_len, EC_KEY *eckey); +int ECDSA_verify(int type, const unsigned char *digest, int digest_len, + const unsigned char *signature, int signature_len, EC_KEY *eckey); + +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth); +void EC_KEY_METHOD_free(EC_KEY_METHOD *meth); +void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, const EC_POINT *pub_key)); +void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, + int (*keygen)(EC_KEY *key)); +void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, + const EC_KEY *ecdh)); +void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const unsigned char *digest, int digest_len, + unsigned char *signature, unsigned int *signature_len, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const unsigned char *digest, int digest_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)); +void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned char *digest, int digest_len, + const unsigned char *signature, int signature_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *digest, int digest_len, + const ECDSA_SIG *sig, EC_KEY *eckey)); +void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, + int (**pinit)(EC_KEY *key), + void (**pfinish)(EC_KEY *key), + int (**pcopy)(EC_KEY *dest, const EC_KEY *src), + int (**pset_group)(EC_KEY *key, const EC_GROUP *grp), + int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key), + int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key)); +void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *key)); +void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, + int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, + const EC_KEY *ecdh)); +void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, + int (**psign)(int type, const unsigned char *digest, int digest_len, + unsigned char *signature, unsigned int *signature_len, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), + int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(**psign_sig)(const unsigned char *digest, int digest_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)); +void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned char *digest, int digest_len, + const unsigned char *signature, int signature_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *digest, int digest_len, + const ECDSA_SIG *sig, EC_KEY *eckey)); + +EC_KEY *ECParameters_dup(EC_KEY *key); + +#ifndef __cplusplus +#if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +#endif + +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +#define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) + +#define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) + +#define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) + +#define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) + +#define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) + +#define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md)) + +#define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd)) + +#define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) + +#define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \ + (void *)(plen)) + +#define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p)) + +#define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p)) + +/* SM2 will skip the operation check so no need to pass operation here */ +#define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) + +#define EVP_PKEY_CTX_get1_id(ctx, id) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) + +#define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len)) + +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) +#define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) +#define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) +#define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) +#define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) +#define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) +#define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) +#define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11) +#define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12) +#define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) + +/* KDF types */ +#define EVP_PKEY_ECDH_KDF_NONE 1 +#define EVP_PKEY_ECDH_KDF_X9_63 2 + +void ERR_load_EC_strings(void); + +/* Error codes for the EC functions. */ + +/* Function codes. */ +#define EC_F_BN_TO_FELEM 224 +#define EC_F_COMPUTE_WNAF 143 +#define EC_F_D2I_ECPARAMETERS 144 +#define EC_F_D2I_ECPKPARAMETERS 145 +#define EC_F_D2I_ECPRIVATEKEY 146 +#define EC_F_DO_EC_KEY_PRINT 221 +#define EC_F_ECKEY_PARAM2TYPE 223 +#define EC_F_ECKEY_PARAM_DECODE 212 +#define EC_F_ECKEY_PRIV_DECODE 213 +#define EC_F_ECKEY_PRIV_ENCODE 214 +#define EC_F_ECKEY_PUB_DECODE 215 +#define EC_F_ECKEY_PUB_ENCODE 216 +#define EC_F_ECKEY_TYPE2PARAM 220 +#define EC_F_ECPARAMETERS_PRINT 147 +#define EC_F_ECPARAMETERS_PRINT_FP 148 +#define EC_F_ECPKPARAMETERS_PRINT 149 +#define EC_F_ECPKPARAMETERS_PRINT_FP 150 +#define EC_F_ECP_NIST_MOD_192 203 +#define EC_F_ECP_NIST_MOD_224 204 +#define EC_F_ECP_NIST_MOD_256 205 +#define EC_F_ECP_NIST_MOD_521 206 +#define EC_F_ECP_NISTZ256_GET_AFFINE 240 +#define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 +#define EC_F_ECP_NISTZ256_POINTS_MUL 241 +#define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 +#define EC_F_ECP_NISTZ256_SET_WORDS 245 +#define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 +#define EC_F_EC_ASN1_GROUP2CURVE 153 +#define EC_F_EC_ASN1_GROUP2FIELDID 154 +#define EC_F_EC_ASN1_GROUP2PARAMETERS 155 +#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 +#define EC_F_EC_ASN1_PARAMETERS2GROUP 157 +#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 +#define EC_F_EC_EX_DATA_SET_DATA 211 +#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +#define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +#define EC_F_EC_GFP_MONT_FIELD_MUL 131 +#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +#define EC_F_EC_GFP_MONT_FIELD_SQR 132 +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 +#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +#define EC_F_EC_GFP_NIST_FIELD_MUL 200 +#define EC_F_EC_GFP_NIST_FIELD_SQR 201 +#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 +#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 +#define EC_F_EC_GROUP_CHECK 170 +#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +#define EC_F_EC_GROUP_COPY 106 +#define EC_F_EC_GROUP_GET0_GENERATOR 139 +#define EC_F_EC_GROUP_GET_COFACTOR 140 +#define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +#define EC_F_EC_GROUP_GET_CURVE_GFP 130 +#define EC_F_EC_GROUP_GET_DEGREE 173 +#define EC_F_EC_GROUP_GET_ORDER 141 +#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +#define EC_F_EC_GROUP_NEW 108 +#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +#define EC_F_EC_GROUP_NEW_FROM_DATA 175 +#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 +#define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +#define EC_F_EC_GROUP_SET_CURVE_GFP 109 +#define EC_F_EC_GROUP_SET_EXTRA_DATA 110 +#define EC_F_EC_GROUP_SET_GENERATOR 111 +#define EC_F_EC_KEY_CHECK_KEY 177 +#define EC_F_EC_KEY_COPY 178 +#define EC_F_EC_KEY_GENERATE_KEY 179 +#define EC_F_EC_KEY_NEW 182 +#define EC_F_EC_KEY_PRINT 180 +#define EC_F_EC_KEY_PRINT_FP 181 +#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +#define EC_F_EC_POINTS_MAKE_AFFINE 136 +#define EC_F_EC_POINT_ADD 112 +#define EC_F_EC_POINT_CMP 113 +#define EC_F_EC_POINT_COPY 114 +#define EC_F_EC_POINT_DBL 115 +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +#define EC_F_EC_POINT_INVERT 210 +#define EC_F_EC_POINT_IS_AT_INFINITY 118 +#define EC_F_EC_POINT_IS_ON_CURVE 119 +#define EC_F_EC_POINT_MAKE_AFFINE 120 +#define EC_F_EC_POINT_MUL 184 +#define EC_F_EC_POINT_NEW 121 +#define EC_F_EC_POINT_OCT2POINT 122 +#define EC_F_EC_POINT_POINT2OCT 123 +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +#define EC_F_EC_POINT_SET_TO_INFINITY 127 +#define EC_F_EC_PRE_COMP_DUP 207 +#define EC_F_EC_PRE_COMP_NEW 196 +#define EC_F_EC_WNAF_MUL 187 +#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +#define EC_F_I2D_ECPARAMETERS 190 +#define EC_F_I2D_ECPKPARAMETERS 191 +#define EC_F_I2D_ECPRIVATEKEY 192 +#define EC_F_I2O_ECPUBLICKEY 151 +#define EC_F_NISTP224_PRE_COMP_NEW 227 +#define EC_F_NISTP256_PRE_COMP_NEW 236 +#define EC_F_NISTP521_PRE_COMP_NEW 237 +#define EC_F_O2I_ECPUBLICKEY 152 +#define EC_F_OLD_EC_PRIV_DECODE 222 +#define EC_F_PKEY_EC_CTRL 197 +#define EC_F_PKEY_EC_CTRL_STR 198 +#define EC_F_PKEY_EC_DERIVE 217 +#define EC_F_PKEY_EC_KEYGEN 199 +#define EC_F_PKEY_EC_PARAMGEN 219 +#define EC_F_PKEY_EC_SIGN 218 + +/* Reason codes. */ +#define EC_R_ASN1_ERROR 115 +#define EC_R_ASN1_UNKNOWN_FIELD 116 +#define EC_R_BAD_SIGNATURE 166 +#define EC_R_BIGNUM_OUT_OF_RANGE 144 +#define EC_R_BUFFER_TOO_SMALL 100 +#define EC_R_COORDINATES_OUT_OF_RANGE 146 +#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +#define EC_R_DECODE_ERROR 142 +#define EC_R_DISCRIMINANT_IS_ZERO 118 +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +#define EC_R_FIELD_TOO_LARGE 143 +#define EC_R_GF2M_NOT_SUPPORTED 147 +#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +#define EC_R_INCOMPATIBLE_OBJECTS 101 +#define EC_R_INVALID_ARGUMENT 112 +#define EC_R_INVALID_COMPRESSED_POINT 110 +#define EC_R_INVALID_COMPRESSION_BIT 109 +#define EC_R_INVALID_CURVE 141 +#define EC_R_INVALID_DIGEST 151 +#define EC_R_INVALID_DIGEST_TYPE 138 +#define EC_R_INVALID_ENCODING 102 +#define EC_R_INVALID_FIELD 103 +#define EC_R_INVALID_FORM 104 +#define EC_R_INVALID_GROUP_ORDER 122 +#define EC_R_INVALID_KEY 165 +#define EC_R_INVALID_OUTPUT_LENGTH 171 +#define EC_R_INVALID_PEER_KEY 152 +#define EC_R_INVALID_PENTANOMIAL_BASIS 132 +#define EC_R_INVALID_PRIVATE_KEY 123 +#define EC_R_INVALID_TRINOMIAL_BASIS 137 +#define EC_R_KDF_FAILED 167 +#define EC_R_KDF_PARAMETER_ERROR 148 +#define EC_R_KEY_TRUNCATION 168 +#define EC_R_KEYS_NOT_SET 140 +#define EC_R_MISSING_PARAMETERS 124 +#define EC_R_MISSING_PRIVATE_KEY 125 +#define EC_R_NEED_NEW_SETUP_VALUES 170 +#define EC_R_NOT_A_NIST_PRIME 135 +#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 +#define EC_R_NOT_IMPLEMENTED 126 +#define EC_R_NOT_INITIALIZED 111 +#define EC_R_NO_FIELD_MOD 133 +#define EC_R_NO_PARAMETERS_SET 139 +#define EC_R_PASSED_NULL_PARAMETER 134 +#define EC_R_PEER_KEY_ERROR 149 +#define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +#define EC_R_POINT_AT_INFINITY 106 +#define EC_R_POINT_ARITHMETIC_FAILURE 169 +#define EC_R_POINT_IS_NOT_ON_CURVE 107 +#define EC_R_SHARED_INFO_ERROR 150 +#define EC_R_SLOT_FULL 108 +#define EC_R_UNDEFINED_GENERATOR 113 +#define EC_R_UNDEFINED_ORDER 128 +#define EC_R_UNKNOWN_COFACTOR 164 +#define EC_R_UNKNOWN_GROUP 129 +#define EC_R_UNKNOWN_ORDER 114 +#define EC_R_UNSUPPORTED_FIELD 131 +#define EC_R_WRONG_CURVE_PARAMETERS 145 +#define EC_R_WRONG_ORDER 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ecdh.h b/Libraries/libressl/include/openssl/ecdh.h new file mode 100644 index 000000000..0149d5cdf --- /dev/null +++ b/Libraries/libressl/include/openssl/ecdh.h @@ -0,0 +1,6 @@ +/* $OpenBSD: ecdh.h,v 1.10 2023/07/28 09:25:12 tb Exp $ */ +/* + * Public domain. + */ + +#include diff --git a/Libraries/libressl/include/openssl/ecdsa.h b/Libraries/libressl/include/openssl/ecdsa.h new file mode 100644 index 000000000..9f498eb4a --- /dev/null +++ b/Libraries/libressl/include/openssl/ecdsa.h @@ -0,0 +1,6 @@ +/* $OpenBSD: ecdsa.h,v 1.20 2023/07/28 09:16:17 tb Exp $ */ +/* + * Public domain. + */ + +#include diff --git a/Libraries/libressl/include/openssl/engine.h b/Libraries/libressl/include/openssl/engine.h new file mode 100644 index 000000000..1e04b61e5 --- /dev/null +++ b/Libraries/libressl/include/openssl/engine.h @@ -0,0 +1,817 @@ +/* $OpenBSD: engine.h,v 1.42 2023/08/04 05:44:51 tb Exp $ */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_H +#define HEADER_ENGINE_H + +#include + +#include +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_EC +#include +#endif +#include +#ifndef OPENSSL_NO_RSA +#include +#endif +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These flags are used to control combinations of algorithm (methods) + * by bitwise "OR"ing. */ +#define ENGINE_METHOD_RSA (unsigned int)0x0001 +#define ENGINE_METHOD_DSA (unsigned int)0x0002 +#define ENGINE_METHOD_DH (unsigned int)0x0004 +#define ENGINE_METHOD_RAND (unsigned int)0x0008 +#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +#define ENGINE_METHOD_STORE (unsigned int)0x0100 +#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +#define ENGINE_METHOD_EC (unsigned int)0x0800 +/* Obvious all-or-nothing cases. */ +#define ENGINE_METHOD_ALL (unsigned int)0xFFFF +#define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be set + * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. */ +#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */ + +/* This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles these + * control commands on behalf of the ENGINE using their "cmd_defns" data. */ +#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* This flag is for ENGINEs who return new duplicate structures when found via + * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl() + * commands are called in sequence as part of some stateful process like + * key-generation setup and execution), it can set this flag - then each attempt + * to obtain the ENGINE will result in it being copied into a new structure. + * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments + * the existing ENGINE's structural reference count. */ +#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are + * not usable as default methods. + */ + +#define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each + * command expects. Currently only numeric and string input is supported. If a + * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options, + * then it is regarded as an "internal" control command - and not for use in + * config setting situations. As such, they're not available to the + * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to + * this list of 'command types' should be reflected carefully in + * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to + * ENGINE_ctrl) */ +#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* Indicates that the control command takes *no* input. Ie. the control command + * is unparameterised. */ +#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. */ +#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* NB: These 3 control commands are deprecated and should not be used. ENGINEs + * relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate the + * same functionality to their own ENGINE-specific control functions that can be + * "discovered" by calling applications. The fact these control commands + * wouldn't be "executable" (ie. usable by text-based config) doesn't change the + * fact that application code can find and use them without requiring per-ENGINE + * hacking. */ + +/* These flags are used to tell the ctrl function what should be done. + * All command numbers are shared between all engines, even if some don't + * make sense to some engines. In such a case, they do nothing but return + * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ +#define ENGINE_CTRL_SET_LOGSTREAM 1 +#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any + handles/connections etc. */ +#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */ +#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used + when calling the password + callback and the user + interface */ +#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given + a string that represents a + file name or so */ +#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given + section in the already loaded + configuration */ + +/* These control commands allow an application to deal with an arbitrary engine + * in a dynamic way. Warn: Negative return values indicate errors FOR THESE + * COMMANDS because zero is used to indicate 'end-of-list'. Other commands, + * including ENGINE-specific command types, return zero for an error. + * + * An ENGINE can choose to implement these ctrl functions, and can internally + * manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the + * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns + * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl() + * handler need only implement its own commands - the above "meta" commands will + * be taken care of. */ + +/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then + * all the remaining control commands will return failure, so it is worth + * checking this first if the caller is trying to "discover" the engine's + * capabilities and doesn't want errors generated unnecessarily. */ +#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. */ +#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. */ +#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. */ +#define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the NAME_LEN + * case, the return value is the length of the command name (not counting a + * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer + * large enough, and it will be populated with the name of the command (WITH a + * trailing EOL). */ +#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +#define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +#define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. */ +#define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */ +#define ENGINE_CMD_BASE 200 + +/* + * Prototypes for the stub functions in engine_stubs.c. They are provided to + * build M2Crypto, Dovecot, apr-utils without patching. All the other garbage + * can hopefully go away soon. + */ +#ifdef OPENSSL_NO_ENGINE +void ENGINE_load_builtin_engines(void); +void ENGINE_load_dynamic(void); +void ENGINE_load_openssl(void); +int ENGINE_register_all_complete(void); + +void ENGINE_cleanup(void); + +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *engine); +int ENGINE_init(ENGINE *engine); +int ENGINE_finish(ENGINE *engine); + +ENGINE *ENGINE_by_id(const char *id); +const char *ENGINE_get_id(const ENGINE *engine); +const char *ENGINE_get_name(const ENGINE *engine); + +int ENGINE_set_default(ENGINE *engine, unsigned int flags); + +ENGINE *ENGINE_get_default_RSA(void); +int ENGINE_set_default_RSA(ENGINE *engine); + +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, long i, void *p, + void (*f)(void), int cmd_optional); +int ENGINE_ctrl_cmd_string(ENGINE *engine, const char *cmd, const char *arg, + int cmd_optional); + +EVP_PKEY *ENGINE_load_private_key(ENGINE *engine, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *engine, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +#else +/* If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its + * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries + * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that + * supports the stated commands (ie. the "cmd_num" entries as described by the + * array). NB: The array must be ordered in increasing order of cmd_num. + * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set + * to zero and/or cmd_name set to NULL. */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR)(void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, + void (*f)(void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); + +/* These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* Returns to a pointer to the array of supported cipher 'nid's. If the second + * parameter is non-NULL it is set to the size of the returned array. */ +typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); +typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); + +/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE + * structures where the pointers have a "structural reference". This means that + * their reference is to allowed access to the structure but it does not imply + * that the structure is functional. To simply increment or decrement the + * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not + * required when iterating using ENGINE_get_next as it will automatically + * decrement the structural reference count of the "current" ENGINE and + * increment the structural reference count of the ENGINE it returns (unless it + * is NULL). */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); +/* Add all the built-in engines. */ +void ENGINE_load_openssl(void); +void ENGINE_load_dynamic(void); +#ifndef OPENSSL_NO_STATIC_ENGINE +void ENGINE_load_padlock(void); +#endif +void ENGINE_load_builtin_engines(void); + +/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/* Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required, so + * ENGINE_cleanup() will reverse any "register" operations. */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_EC(ENGINE *e); +void ENGINE_unregister_EC(ENGINE *e); +void ENGINE_register_all_EC(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_STORE(ENGINE *e); +void ENGINE_unregister_STORE(ENGINE *e); +void ENGINE_register_all_STORE(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* These functions register all support from the above categories. Note, use of + * these functions can result in static linkage of code your application may not + * need. If you only need a subset of functionality, consider using more + * selective initialisation. */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* Send parametrised control commands to the engine. The possibilities to send + * down an integer, a pointer to data or a function pointer are provided. Any of + * the parameters may or may not be NULL, depending on the command number. In + * actuality, this function only requires a structural (rather than functional) + * reference to an engine, but many control commands may require the engine be + * functional. The caller should be aware of trying commands that require an + * operational ENGINE, and only use functional references in such situations. */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); + +/* This function tests if an ENGINE-specific command is usable as a "setting". + * Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional commands. + * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to + * use the cmd_name and cmd_optional. */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(void), int cmd_optional); + +/* This function passes a command-name and argument to an ENGINE. The cmd_name + * is converted to a command number and the control command is called using + * 'arg' as an argument (unless the ENGINE doesn't support such a command, in + * which case no control command is called). The command is checked for input + * flags, and if necessary the argument will be converted to a numeric value. If + * cmd_optional is non-zero, then if the ENGINE doesn't support the given + * cmd_name the return value will be success anyway. This function is intended + * for applications to use so that users (or config files) can supply + * engine-specific config data to the ENGINE at run-time to control behaviour of + * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl() + * functions that return data, deal with binary data, or that are otherwise + * supposed to be used directly through ENGINE_ctrl() in application code. Any + * "return" data from an ENGINE_ctrl() operation in this function will be lost - + * the return value is interpreted as failure if the return value is zero, + * success otherwise, and this function returns a boolean value as a result. In + * other words, vendors of 'ENGINE'-enabled devices should write ENGINE + * implementations with parameterisations that work in this scheme, so that + * compliant ENGINE-based applications can work consistently with the same + * configuration for the same ENGINE-enabled devices, across applications. */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an ENGINE + * structure with personalised implementations of things prior to using it + * directly or adding it to the builtin ENGINE list in OpenSSL. These are also + * here so that the ENGINE structure doesn't have to be exposed and break binary + * compatibility! */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ec_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +/* This function cleans up anything that needs it. Eg. the ENGINE_add() function + * automatically ensures the list cleanup function is registered to be called + * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure + * ENGINE_cleanup() will clean up after them. */ +void ENGINE_cleanup(void); + +/* These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* FUNCTIONAL functions. These functions deal with ENGINE structures + * that have (or will) be initialised for use. Broadly speaking, the + * structural functions are useful for iterating the list of available + * engine types, creating new engine types, and other "list" operations. + * These functions actually deal with ENGINEs that are to be used. As + * such these functions can fail (if applicable) when particular + * engines are unavailable - eg. if a hardware accelerator is not + * attached or not functioning correctly. Each ENGINE has 2 reference + * counts; structural and functional. Every time a functional reference + * is obtained or released, a corresponding structural reference is + * automatically obtained or released too. */ + +/* Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently + * operational and cannot initialise. */ +int ENGINE_init(ENGINE *e); +/* Free a functional reference to a engine type. This does not require + * a corresponding call to ENGINE_free as it also releases a structural + * reference. */ +int ENGINE_finish(ENGINE *e); + +/* The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* This returns a pointer for the current ENGINE structure that + * is (by default) performing any RSA operations. The value returned + * is an incremented reference, so it should be free'd (ENGINE_finish) + * before it is discarded. */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_EC(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* This sets a new default ENGINE structure for performing RSA + * operations. If the result is non-zero (success) then the ENGINE + * structure will have had its reference count up'd so the caller + * should still free their own reference 'e'. */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_EC(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000 +/* Binary versions older than this are too old for us (whether we're a loader or + * a loadee) */ +#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000 + +/* When compiling an ENGINE entirely as an external shared library, loadable by + * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure + * type provides the calling application's (or library's) error functionality + * and memory management function pointers to the loaded library. These should + * be used/set in the loaded library code so that the loading application's + * 'state' will be used/changed in all operations. The 'static_state' pointer + * allows the loaded library to know if it shares the same static data as the + * calling application (or library), and thus whether these callbacks need to be + * set or not. */ +typedef void *(*dyn_MEM_malloc_cb)(size_t); +typedef void *(*dyn_MEM_realloc_cb)(void *, size_t); +typedef void (*dyn_MEM_free_cb)(void *); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_cb malloc_cb; + dyn_MEM_realloc_cb realloc_cb; + dyn_MEM_free_cb free_cb; +} dynamic_MEM_fns; +/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use + * these types so we (and any other dependent code) can simplify a bit?? */ +typedef void (*dyn_lock_locking_cb)(int, int, const char *, int); +typedef int (*dyn_lock_add_lock_cb)(int*, int, int, const char *, int); +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)( + const char *, int); +typedef void (*dyn_dynlock_lock_cb)(int, struct CRYPTO_dynlock_value *, + const char *, int); +typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *, + const char *, int); +typedef struct st_dynamic_LOCK_fns { + dyn_lock_locking_cb lock_locking_cb; + dyn_lock_add_lock_cb lock_add_lock_cb; + dyn_dynlock_create_cb dynlock_create_cb; + dyn_dynlock_lock_cb dynlock_lock_cb; + dyn_dynlock_destroy_cb dynlock_destroy_cb; +} dynamic_LOCK_fns; +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + const ERR_FNS *err_fns; + const CRYPTO_EX_DATA_IMPL *ex_data_fns; + dynamic_MEM_fns mem_fns; + dynamic_LOCK_fns lock_fns; +} dynamic_fns; + +/* The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code. + * If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's version + * is unsatisfactory and could veto the load. The function is expected to + * be implemented with the symbol name "v_check", and a default implementation + * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */ +typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version); +#define IMPLEMENT_DYNAMIC_CHECK_FN() \ + extern unsigned long v_check(unsigned long v); \ + extern unsigned long v_check(unsigned long v) { \ + if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load will + * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the + * structure, and (c) the shared library will be unloaded. So implementations + * should do their own internal cleanup in failure circumstances otherwise they + * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that + * the loader is looking for. If this is NULL, the shared library can choose to + * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared + * library must initialise only an ENGINE matching the passed 'id'. The function + * is expected to be implemented with the symbol name "bind_engine". A standard + * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where + * the parameter 'fn' is a callback function that populates the ENGINE structure + * and returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); */ +typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id, + const dynamic_fns *fns); +#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + extern \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + extern \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ + fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ + return 0; \ + if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ + return 0; \ + if(!ERR_set_implementation(fns->err_fns)) return 0; \ + skip_cbs: \ + if(!fn(e,id)) return 0; \ + return 1; } + +/* If the loading application (or library) and the loaded ENGINE library share + * the same static data (eg. they're both dynamically linked to the same + * libcrypto.so) we need a way to avoid trying to set system callbacks - this + * would fail, and for the same reason that it's unnecessary to try. If the + * loaded ENGINE has (or gets from through the loader) its own copy of the + * libcrypto static data, we will need to set the callbacks. The easiest way to + * detect this is to have a function that returns a pointer to some static data + * and let the loading application and loaded ENGINE compare their respective + * values. */ + void *ENGINE_get_static_state(void); + +void ERR_load_ENGINE_strings(void); +#endif + +/* Error codes for the ENGINE functions. */ + +/* Function codes. */ +#define ENGINE_F_DYNAMIC_CTRL 180 +#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +#define ENGINE_F_DYNAMIC_LOAD 182 +#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +#define ENGINE_F_ENGINE_ADD 105 +#define ENGINE_F_ENGINE_BY_ID 106 +#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +#define ENGINE_F_ENGINE_CTRL 142 +#define ENGINE_F_ENGINE_CTRL_CMD 178 +#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +#define ENGINE_F_ENGINE_FINISH 107 +#define ENGINE_F_ENGINE_FREE_UTIL 108 +#define ENGINE_F_ENGINE_GET_CIPHER 185 +#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 +#define ENGINE_F_ENGINE_GET_DIGEST 186 +#define ENGINE_F_ENGINE_GET_NEXT 115 +#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +#define ENGINE_F_ENGINE_GET_PKEY_METH 192 +#define ENGINE_F_ENGINE_GET_PREV 116 +#define ENGINE_F_ENGINE_INIT 119 +#define ENGINE_F_ENGINE_LIST_ADD 120 +#define ENGINE_F_ENGINE_LIST_REMOVE 121 +#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +#define ENGINE_F_ENGINE_NEW 122 +#define ENGINE_F_ENGINE_REMOVE 123 +#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 +#define ENGINE_F_ENGINE_SET_ID 129 +#define ENGINE_F_ENGINE_SET_NAME 130 +#define ENGINE_F_ENGINE_TABLE_REGISTER 184 +#define ENGINE_F_ENGINE_UNLOAD_KEY 152 +#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +#define ENGINE_F_ENGINE_UP_REF 190 +#define ENGINE_F_INT_CTRL_HELPER 172 +#define ENGINE_F_INT_ENGINE_CONFIGURE 188 +#define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +#define ENGINE_F_LOG_MESSAGE 141 + +/* Reason codes. */ +#define ENGINE_R_ALREADY_LOADED 100 +#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +#define ENGINE_R_CMD_NOT_EXECUTABLE 134 +#define ENGINE_R_COMMAND_TAKES_INPUT 135 +#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +#define ENGINE_R_CONFLICTING_ENGINE_ID 103 +#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +#define ENGINE_R_DH_NOT_IMPLEMENTED 139 +#define ENGINE_R_DSA_NOT_IMPLEMENTED 140 +#define ENGINE_R_DSO_FAILURE 104 +#define ENGINE_R_DSO_NOT_FOUND 132 +#define ENGINE_R_ENGINES_SECTION_ERROR 148 +#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +#define ENGINE_R_ENGINE_SECTION_ERROR 149 +#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +#define ENGINE_R_FINISH_FAILED 106 +#define ENGINE_R_GET_HANDLE_FAILED 107 +#define ENGINE_R_ID_OR_NAME_MISSING 108 +#define ENGINE_R_INIT_FAILED 109 +#define ENGINE_R_INTERNAL_LIST_ERROR 110 +#define ENGINE_R_INVALID_ARGUMENT 143 +#define ENGINE_R_INVALID_CMD_NAME 137 +#define ENGINE_R_INVALID_CMD_NUMBER 138 +#define ENGINE_R_INVALID_INIT_VALUE 151 +#define ENGINE_R_INVALID_STRING 150 +#define ENGINE_R_NOT_INITIALISED 117 +#define ENGINE_R_NOT_LOADED 112 +#define ENGINE_R_NO_CONTROL_FUNCTION 120 +#define ENGINE_R_NO_INDEX 144 +#define ENGINE_R_NO_LOAD_FUNCTION 125 +#define ENGINE_R_NO_REFERENCE 130 +#define ENGINE_R_NO_SUCH_ENGINE 116 +#define ENGINE_R_NO_UNLOAD_FUNCTION 126 +#define ENGINE_R_PROVIDE_PARAMETERS 113 +#define ENGINE_R_RSA_NOT_IMPLEMENTED 141 +#define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +#define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +#define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/err.h b/Libraries/libressl/include/openssl/err.h new file mode 100644 index 000000000..d85de24cb --- /dev/null +++ b/Libraries/libressl/include/openssl/err.h @@ -0,0 +1,411 @@ +/* $OpenBSD: err.h,v 1.31 2023/07/28 10:23:19 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ERR_H +#define HEADER_ERR_H + +#include + +#include +#include + +#include +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_LHASH +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef OPENSSL_NO_ERR +#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +#else +#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +#endif + +#include + +#define ERR_TXT_MALLOCED 0x01 +#define ERR_TXT_STRING 0x02 + +#define ERR_FLAG_MARK 0x01 + +#define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + CRYPTO_THREADID tid; + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +#define ERR_LIB_NONE 1 +#define ERR_LIB_SYS 2 +#define ERR_LIB_BN 3 +#define ERR_LIB_RSA 4 +#define ERR_LIB_DH 5 +#define ERR_LIB_EVP 6 +#define ERR_LIB_BUF 7 +#define ERR_LIB_OBJ 8 +#define ERR_LIB_PEM 9 +#define ERR_LIB_DSA 10 +#define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +#define ERR_LIB_ASN1 13 +#define ERR_LIB_CONF 14 +#define ERR_LIB_CRYPTO 15 +#define ERR_LIB_EC 16 +#define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +#define ERR_LIB_BIO 32 +#define ERR_LIB_PKCS7 33 +#define ERR_LIB_X509V3 34 +#define ERR_LIB_PKCS12 35 +#define ERR_LIB_RAND 36 +#define ERR_LIB_DSO 37 +#define ERR_LIB_ENGINE 38 +#define ERR_LIB_OCSP 39 +#define ERR_LIB_UI 40 +#define ERR_LIB_COMP 41 +#define ERR_LIB_ECDSA 42 +#define ERR_LIB_ECDH 43 +#define ERR_LIB_STORE 44 +#define ERR_LIB_FIPS 45 +#define ERR_LIB_CMS 46 +#define ERR_LIB_TS 47 +#define ERR_LIB_HMAC 48 +#define ERR_LIB_JPAKE 49 +#define ERR_LIB_GOST 50 +#define ERR_LIB_CT 51 +#define ERR_LIB_KDF 52 + +#define ERR_LIB_USER 128 + +#ifndef LIBRESSL_INTERNAL +#define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) +#define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) +#define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) +#define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) +#define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) +#define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) +#define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) +#define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) +#define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) +#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) +#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) +#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) +#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) +#define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) +#define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) +#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) +#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) +#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) +#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) +#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) +#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) +#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) +#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) +#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) +#define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) +#define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) +#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) +#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) +#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) +#define GOSTerr(f,r) ERR_PUT_error(ERR_LIB_GOST,(f),(r),__FILE__,__LINE__) +#define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) +#define CTerr(f, r) ERR_PUT_error(ERR_LIB_CT,(f),(r),__FILE__,__LINE__) +#define KDFerr(f, r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),__FILE__,__LINE__) +#endif + +#ifdef LIBRESSL_INTERNAL +#define SYSerror(r) ERR_PUT_error(ERR_LIB_SYS,(0xfff),(r),__FILE__,__LINE__) +#define BNerror(r) ERR_PUT_error(ERR_LIB_BN,(0xfff),(r),__FILE__,__LINE__) +#define RSAerror(r) ERR_PUT_error(ERR_LIB_RSA,(0xfff),(r),__FILE__,__LINE__) +#define DHerror(r) ERR_PUT_error(ERR_LIB_DH,(0xfff),(r),__FILE__,__LINE__) +#define EVPerror(r) ERR_PUT_error(ERR_LIB_EVP,(0xfff),(r),__FILE__,__LINE__) +#define BUFerror(r) ERR_PUT_error(ERR_LIB_BUF,(0xfff),(r),__FILE__,__LINE__) +#define OBJerror(r) ERR_PUT_error(ERR_LIB_OBJ,(0xfff),(r),__FILE__,__LINE__) +#define PEMerror(r) ERR_PUT_error(ERR_LIB_PEM,(0xfff),(r),__FILE__,__LINE__) +#define DSAerror(r) ERR_PUT_error(ERR_LIB_DSA,(0xfff),(r),__FILE__,__LINE__) +#define X509error(r) ERR_PUT_error(ERR_LIB_X509,(0xfff),(r),__FILE__,__LINE__) +#define ASN1error(r) ERR_PUT_error(ERR_LIB_ASN1,(0xfff),(r),__FILE__,__LINE__) +#define CONFerror(r) ERR_PUT_error(ERR_LIB_CONF,(0xfff),(r),__FILE__,__LINE__) +#define CRYPTOerror(r) ERR_PUT_error(ERR_LIB_CRYPTO,(0xfff),(r),__FILE__,__LINE__) +#define ECerror(r) ERR_PUT_error(ERR_LIB_EC,(0xfff),(r),__FILE__,__LINE__) +#define BIOerror(r) ERR_PUT_error(ERR_LIB_BIO,(0xfff),(r),__FILE__,__LINE__) +#define PKCS7error(r) ERR_PUT_error(ERR_LIB_PKCS7,(0xfff),(r),__FILE__,__LINE__) +#define X509V3error(r) ERR_PUT_error(ERR_LIB_X509V3,(0xfff),(r),__FILE__,__LINE__) +#define PKCS12error(r) ERR_PUT_error(ERR_LIB_PKCS12,(0xfff),(r),__FILE__,__LINE__) +#define RANDerror(r) ERR_PUT_error(ERR_LIB_RAND,(0xfff),(r),__FILE__,__LINE__) +#define DSOerror(r) ERR_PUT_error(ERR_LIB_DSO,(0xfff),(r),__FILE__,__LINE__) +#define ENGINEerror(r) ERR_PUT_error(ERR_LIB_ENGINE,(0xfff),(r),__FILE__,__LINE__) +#define OCSPerror(r) ERR_PUT_error(ERR_LIB_OCSP,(0xfff),(r),__FILE__,__LINE__) +#define UIerror(r) ERR_PUT_error(ERR_LIB_UI,(0xfff),(r),__FILE__,__LINE__) +#define COMPerror(r) ERR_PUT_error(ERR_LIB_COMP,(0xfff),(r),__FILE__,__LINE__) +#define ECDSAerror(r) ERR_PUT_error(ERR_LIB_ECDSA,(0xfff),(r),__FILE__,__LINE__) +#define ECDHerror(r) ERR_PUT_error(ERR_LIB_ECDH,(0xfff),(r),__FILE__,__LINE__) +#define STOREerror(r) ERR_PUT_error(ERR_LIB_STORE,(0xfff),(r),__FILE__,__LINE__) +#define FIPSerror(r) ERR_PUT_error(ERR_LIB_FIPS,(0xfff),(r),__FILE__,__LINE__) +#define CMSerror(r) ERR_PUT_error(ERR_LIB_CMS,(0xfff),(r),__FILE__,__LINE__) +#define TSerror(r) ERR_PUT_error(ERR_LIB_TS,(0xfff),(r),__FILE__,__LINE__) +#define HMACerror(r) ERR_PUT_error(ERR_LIB_HMAC,(0xfff),(r),__FILE__,__LINE__) +#define JPAKEerror(r) ERR_PUT_error(ERR_LIB_JPAKE,(0xfff),(r),__FILE__,__LINE__) +#define GOSTerror(r) ERR_PUT_error(ERR_LIB_GOST,(0xfff),(r),__FILE__,__LINE__) +#define CTerror(r) ERR_PUT_error(ERR_LIB_CT,(0xfff),(r),__FILE__,__LINE__) +#define KDFerror(r) ERR_PUT_error(ERR_LIB_KDF,(0xfff),(r),__FILE__,__LINE__) +#endif + +#define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)<<24L)| \ + ((((unsigned long)f)&0xfffL)<<12L)| \ + ((((unsigned long)r)&0xfffL))) +#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) +#define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) +#define ERR_GET_REASON(l) (int)((l)&0xfffL) +#define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) + + +/* OS functions */ +#define SYS_F_FOPEN 1 +#define SYS_F_CONNECT 2 +#define SYS_F_GETSERVBYNAME 3 +#define SYS_F_SOCKET 4 +#define SYS_F_IOCTLSOCKET 5 +#define SYS_F_BIND 6 +#define SYS_F_LISTEN 7 +#define SYS_F_ACCEPT 8 +#define SYS_F_WSASTARTUP 9 /* Winsock stuff */ +#define SYS_F_OPENDIR 10 +#define SYS_F_FREAD 11 + + +/* reasons */ +#define ERR_R_SYS_LIB ERR_LIB_SYS /* 2 */ +#define ERR_R_BN_LIB ERR_LIB_BN /* 3 */ +#define ERR_R_RSA_LIB ERR_LIB_RSA /* 4 */ +#define ERR_R_DH_LIB ERR_LIB_DH /* 5 */ +#define ERR_R_EVP_LIB ERR_LIB_EVP /* 6 */ +#define ERR_R_BUF_LIB ERR_LIB_BUF /* 7 */ +#define ERR_R_OBJ_LIB ERR_LIB_OBJ /* 8 */ +#define ERR_R_PEM_LIB ERR_LIB_PEM /* 9 */ +#define ERR_R_DSA_LIB ERR_LIB_DSA /* 10 */ +#define ERR_R_X509_LIB ERR_LIB_X509 /* 11 */ +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 /* 13 */ +#define ERR_R_CONF_LIB ERR_LIB_CONF /* 14 */ +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO /* 15 */ +#define ERR_R_EC_LIB ERR_LIB_EC /* 16 */ +#define ERR_R_SSL_LIB ERR_LIB_SSL /* 20 */ +#define ERR_R_BIO_LIB ERR_LIB_BIO /* 32 */ +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 /* 33 */ +#define ERR_R_X509V3_LIB ERR_LIB_X509V3 /* 34 */ +#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12 /* 35 */ +#define ERR_R_RAND_LIB ERR_LIB_RAND /* 36 */ +#define ERR_R_DSO_LIB ERR_LIB_DSO /* 37 */ +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE /* 38 */ +#define ERR_R_OCSP_LIB ERR_LIB_OCSP /* 39 */ +#define ERR_R_UI_LIB ERR_LIB_UI /* 40 */ +#define ERR_R_COMP_LIB ERR_LIB_COMP /* 41 */ +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA /* 42 */ +#define ERR_R_ECDH_LIB ERR_LIB_ECDH /* 43 */ +#define ERR_R_STORE_LIB ERR_LIB_STORE /* 44 */ +#define ERR_R_TS_LIB ERR_LIB_TS /* 45 */ + +#define ERR_R_NESTED_ASN1_ERROR 58 +#define ERR_R_BAD_ASN1_OBJECT_HEADER 59 +#define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 +#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 +#define ERR_R_ASN1_LENGTH_MISMATCH 62 +#define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +#define ERR_R_FATAL 64 +#define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +#define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +#define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +#define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +#define ERR_R_DISABLED (5|ERR_R_FATAL) +#define ERR_R_INIT_FAIL (6|ERR_R_FATAL) + +/* 99 is the maximum possible ERR_R_... code, higher values + * are reserved for the individual libraries */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void ); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), + void *u); +void ERR_print_errors_fp(FILE *fp); +#ifndef OPENSSL_NO_BIO +void ERR_print_errors(BIO *bp); +#endif +void ERR_asprintf_error_data(char * format, ...); +#ifndef LIBRESSL_INTERNAL +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +#endif +void ERR_load_strings(int lib, ERR_STRING_DATA str[]); +void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); +void ERR_load_ERR_strings(void); +void ERR_load_crypto_strings(void); +void ERR_free_strings(void); + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +/* Wrapped in OPENSSL_NO_DEPRECATED in 0.9.8. Still used in 2023. */ +void ERR_remove_state(unsigned long pid); +ERR_STATE *ERR_get_state(void); + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/evp.h b/Libraries/libressl/include/openssl/evp.h new file mode 100644 index 000000000..381098b96 --- /dev/null +++ b/Libraries/libressl/include/openssl/evp.h @@ -0,0 +1,1515 @@ +/* $OpenBSD: evp.h,v 1.119 2023/08/25 12:37:33 schwarze Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ENVELOPE_H +#define HEADER_ENVELOPE_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif + +/* +#define EVP_RC2_KEY_SIZE 16 +#define EVP_RC4_KEY_SIZE 16 +#define EVP_BLOWFISH_KEY_SIZE 16 +#define EVP_CAST5_KEY_SIZE 16 +#define EVP_RC5_32_12_16_KEY_SIZE 16 +*/ +#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */ +#define EVP_MAX_KEY_LENGTH 64 +#define EVP_MAX_IV_LENGTH 16 +#define EVP_MAX_BLOCK_LENGTH 32 + +#define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +#define PKCS5_DEFAULT_ITER 2048 + +#include + +#define EVP_PK_RSA 0x0001 +#define EVP_PK_DSA 0x0002 +#define EVP_PK_DH 0x0004 +#define EVP_PK_EC 0x0008 +#define EVP_PKT_SIGN 0x0010 +#define EVP_PKT_ENC 0x0020 +#define EVP_PKT_EXCH 0x0040 +#define EVP_PKS_RSA 0x0100 +#define EVP_PKS_DSA 0x0200 +#define EVP_PKS_EC 0x0400 +#define EVP_PKT_EXP 0x1000 /* <= 512 bit key */ + +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_RSA_PSS NID_rsassaPss +#define EVP_PKEY_RSA2 NID_rsa +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_DSA1 NID_dsa_2 +#define EVP_PKEY_DSA2 NID_dsaWithSHA +#define EVP_PKEY_DSA3 NID_dsaWithSHA1 +#define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +#define EVP_PKEY_DH NID_dhKeyAgreement +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_GOSTR01 NID_id_GostR3410_2001 +#define EVP_PKEY_GOSTIMIT NID_id_Gost28147_89_MAC +#define EVP_PKEY_HMAC NID_hmac +#define EVP_PKEY_CMAC NID_cmac +#define EVP_PKEY_HKDF NID_hkdf +#define EVP_PKEY_GOSTR12_256 NID_id_tc26_gost3410_2012_256 +#define EVP_PKEY_GOSTR12_512 NID_id_tc26_gost3410_2012_512 +#define EVP_PKEY_ED25519 NID_ED25519 +#define EVP_PKEY_X25519 NID_X25519 + +#ifdef __cplusplus +extern "C" { +#endif + +#define EVP_PKEY_MO_SIGN 0x0001 +#define EVP_PKEY_MO_VERIFY 0x0002 +#define EVP_PKEY_MO_ENCRYPT 0x0004 +#define EVP_PKEY_MO_DECRYPT 0x0008 + +#ifndef EVP_MD +#define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single + * block */ + +/* DigestAlgorithmIdentifier flags... */ + +#define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +#define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +#define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ + +/* Digest ctrls */ + +#define EVP_MD_CTRL_DIGALGID 0x1 +#define EVP_MD_CTRL_MICALG 0x2 +#define EVP_MD_CTRL_SET_KEY 0x3 +#define EVP_MD_CTRL_GOST_SET_SBOX 0x4 + +/* Minimum Algorithm specific ctrl value */ + +#define EVP_MD_CTRL_ALG_CTRL 0x1000 + +#endif /* !EVP_MD */ + +/* values for EVP_MD_CTX flags */ + +#define EVP_MD_CTX_FLAG_ONESHOT 0x0001 /* digest update will be called + * once only */ +#define EVP_MD_CTX_FLAG_CLEANED 0x0002 /* context has already been + * cleaned */ +#define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data + * in EVP_MD_CTX_cleanup */ +/* FIPS and pad options are ignored in 1.0.0, definitions are here + * so we don't accidentally reuse the values for other purposes. + */ + +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest + * in FIPS mode */ + +/* The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +#define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */ +#define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ +#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ + +#define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */ + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +#define EVP_CIPH_STREAM_CIPHER 0x0 +#define EVP_CIPH_ECB_MODE 0x1 +#define EVP_CIPH_CBC_MODE 0x2 +#define EVP_CIPH_CFB_MODE 0x3 +#define EVP_CIPH_OFB_MODE 0x4 +#define EVP_CIPH_CTR_MODE 0x5 +#define EVP_CIPH_GCM_MODE 0x6 +#define EVP_CIPH_CCM_MODE 0x7 +#define EVP_CIPH_XTS_MODE 0x10001 +#define EVP_CIPH_WRAP_MODE 0x10002 +#define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +#define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +#define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +#define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +#define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +#define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +#define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +#define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +#define EVP_CIPH_CUSTOM_COPY 0x400 +/* Allow use default ASN1 get/set iv */ +#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +#define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* Cipher handles any and all padding logic as well + * as finalisation. + */ +#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 + +/* + * Cipher context flag to indicate that we can handle wrap mode: if allowed in + * older applications, it could overflow buffers. + */ +#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 + +/* ctrl() values */ + +#define EVP_CTRL_INIT 0x0 +#define EVP_CTRL_SET_KEY_LENGTH 0x1 +#define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +#define EVP_CTRL_GET_RC5_ROUNDS 0x4 +#define EVP_CTRL_SET_RC5_ROUNDS 0x5 +#define EVP_CTRL_RAND_KEY 0x6 +#define EVP_CTRL_PBE_PRF_NID 0x7 +#define EVP_CTRL_COPY 0x8 +#define EVP_CTRL_AEAD_SET_IVLEN 0x9 +#define EVP_CTRL_AEAD_GET_TAG 0x10 +#define EVP_CTRL_AEAD_SET_TAG 0x11 +#define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +#define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +#define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +#define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +#define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +#define EVP_CTRL_GCM_IV_GEN 0x13 +#define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +#define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +#define EVP_CTRL_CCM_SET_L 0x14 +#define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* AEAD cipher deduces payload length and returns number of bytes + * required to store MAC and eventual padding. Subsequent call to + * EVP_Cipher even appends/verifies MAC. + */ +#define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +#define EVP_CTRL_GCM_SET_IV_INV 0x18 +/* Set the S-BOX NID for GOST ciphers */ +#define EVP_CTRL_GOST_SET_SBOX 0x19 + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +#define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +#define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +#define EVP_GCM_TLS_TAG_LEN 16 + +/* CCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +#define EVP_CCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +#define EVP_CCM_TLS_EXPLICIT_IV_LEN 8 +/* Total length of CCM IV length for TLS */ +#define EVP_CCM_TLS_IV_LEN 12 +/* Length of tag for TLS */ +#define EVP_CCM_TLS_TAG_LEN 16 +/* Length of CCM8 tag for TLS */ +#define EVP_CCM8_TLS_TAG_LEN 8 + +/* Length of tag for TLS */ +#define EVP_CHACHAPOLY_TLS_TAG_LEN 16 + +/* XXX - do we want to expose these? */ +#if defined(LIBRESSL_INTERNAL) +#define ED25519_KEYLEN 32 +#define X25519_KEYLEN 32 +#endif + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +/* Password based encryption function */ +typedef int EVP_PBE_KEYGEN(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de); + +#ifndef OPENSSL_NO_RSA +#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +#endif + +#ifndef OPENSSL_NO_DSA +#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +#endif + +#ifndef OPENSSL_NO_DH +#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +#endif + +#ifndef OPENSSL_NO_EC +#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +#endif + +#ifndef OPENSSL_NO_GOST +#define EVP_PKEY_assign_GOST(pkey,gostkey) EVP_PKEY_assign((pkey),EVP_PKEY_GOSTR01,\ + (char *)(gostkey)) +#endif + +/* Add some extra combinations */ +#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +#define EVP_MD_nid(e) EVP_MD_type(e) +#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type); +void EVP_MD_meth_free(EVP_MD *md); +EVP_MD *EVP_MD_meth_dup(const EVP_MD *md); +int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize); +int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize); +int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize); +int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags); +int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_update(EVP_MD *md, + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)); +int EVP_MD_meth_set_final(EVP_MD *md, + int (*final)(EVP_MD_CTX *ctx, unsigned char *md)); +int EVP_MD_meth_set_copy(EVP_MD *md, + int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)); +int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_ctrl(EVP_MD *md, + int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); +EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); +void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); +#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +#define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, + unsigned char *iv, size_t len); +int EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, + const unsigned char *iv, size_t len); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx); +void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data); +unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx); +#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); +#define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); +EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher); +void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); + +int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); +int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); +int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size); +int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc)); +int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl)); +int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup)(EVP_CIPHER_CTX *)); +int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)); +int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)); +int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr)); + +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *engine, + const unsigned char *private_key, size_t len); +EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *engine, + const unsigned char *public_key, size_t len); +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, + unsigned char *out_private_key, size_t *out_len); +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, + unsigned char *out_public_key, size_t *out_len); + +#define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +#define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) + +#define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +#define EVP_SignInit(a,b) EVP_DigestInit(a,b) +#define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +#define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +#define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +#define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +#define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +#define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) +#define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) +#define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) +#define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) +#define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +#define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + +int EVP_Cipher(EVP_CIPHER_CTX *c, unsigned char *out, const unsigned char *in, + unsigned int inl); + +#define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +#define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +#define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +#define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +EVP_MD_CTX *EVP_MD_CTX_new(void); +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +int EVP_Digest(const void *data, size_t count, unsigned char *md, + unsigned int *size, const EVP_MD *type, ENGINE *impl); + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, int datal, int count, + unsigned char *key, unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, const unsigned char *iv); +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +#ifndef LIBRESSL_INTERNAL +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +#endif + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, const unsigned char *iv); +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#ifndef LIBRESSL_INTERNAL +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#endif + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc); +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc); +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#ifndef LIBRESSL_INTERNAL +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#endif + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); + +int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen); + +int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, size_t tbslen); + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv); +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, + int npubk); +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void); +void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx); +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +#ifndef OPENSSL_NO_BIO +const BIO_METHOD *BIO_f_md(void); +const BIO_METHOD *BIO_f_base64(void); +const BIO_METHOD *BIO_f_cipher(void); +int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); +#endif + +const EVP_MD *EVP_md_null(void); +#ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +#endif +#ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +const EVP_MD *EVP_md5_sha1(void); +#endif +#ifndef OPENSSL_NO_SHA +const EVP_MD *EVP_sha1(void); +#endif +#ifndef OPENSSL_NO_SHA256 +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +#endif +#ifndef OPENSSL_NO_SHA512 +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +const EVP_MD *EVP_sha512_224(void); +const EVP_MD *EVP_sha512_256(void); +#endif +#ifndef OPENSSL_NO_SHA3 +const EVP_MD *EVP_sha3_224(void); +const EVP_MD *EVP_sha3_256(void); +const EVP_MD *EVP_sha3_384(void); +const EVP_MD *EVP_sha3_512(void); +#endif +#ifndef OPENSSL_NO_SM3 +const EVP_MD *EVP_sm3(void); +#endif +#ifndef OPENSSL_NO_RIPEMD +const EVP_MD *EVP_ripemd160(void); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +#endif +#ifndef OPENSSL_NO_GOST +const EVP_MD *EVP_gostr341194(void); +const EVP_MD *EVP_gost2814789imit(void); +const EVP_MD *EVP_streebog256(void); +const EVP_MD *EVP_streebog512(void); +#endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +#ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +#endif +#ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +#ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +#endif +#endif +#ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +#endif +#ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +#endif +#ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +#endif +#ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +#endif +#ifndef OPENSSL_NO_AES +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_wrap(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_192_wrap(void); +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_wrap(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +const EVP_CIPHER *EVP_chacha20_poly1305(void); +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +#endif +#endif +#ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +#endif + +#ifndef OPENSSL_NO_CHACHA +const EVP_CIPHER *EVP_chacha20(void); +#endif + +#ifndef OPENSSL_NO_GOST +const EVP_CIPHER *EVP_gost2814789_ecb(void); +const EVP_CIPHER *EVP_gost2814789_cfb64(void); +const EVP_CIPHER *EVP_gost2814789_cnt(void); +#endif + +#ifndef OPENSSL_NO_SM4 +const EVP_CIPHER *EVP_sm4_ecb(void); +const EVP_CIPHER *EVP_sm4_cbc(void); +const EVP_CIPHER *EVP_sm4_cfb128(void); +#define EVP_sm4_cfb EVP_sm4_cfb128 +const EVP_CIPHER *EVP_sm4_ofb(void); +const EVP_CIPHER *EVP_sm4_ctr(void); +#endif + +void OPENSSL_add_all_algorithms_noconf(void); +void OPENSSL_add_all_algorithms_conf(void); + +#ifdef OPENSSL_LOAD_CONF +#define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_conf() +#else +#define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_noconf() +#endif + +void OpenSSL_add_all_ciphers(void); +void OpenSSL_add_all_digests(void); + +#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() +#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() +#define SSLeay_add_all_digests() OpenSSL_add_all_digests() + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); +void EVP_cleanup(void); + +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key, + int enc_key_len, EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, const unsigned char *key, + int key_len, EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(const EVP_PKEY *pkey); +int EVP_PKEY_security_bits(const EVP_PKEY *pkey); +int EVP_PKEY_size(const EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(const EVP_PKEY *pkey); +const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); + +#ifndef OPENSSL_NO_RSA +struct rsa_st; +struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +#endif +#ifndef OPENSSL_NO_DSA +struct dsa_st; +struct dsa_st *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +#endif +#ifndef OPENSSL_NO_DH +struct dh_st; +struct dh_st *EVP_PKEY_get0_DH(EVP_PKEY *pkey); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +#endif +#ifndef OPENSSL_NO_EC +struct ec_key_st; +struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +#endif +#ifndef OPENSSL_NO_GOST +struct gost_key_st; +#endif + +EVP_PKEY *EVP_PKEY_new(void); +void EVP_PKEY_free(EVP_PKEY *pkey); +int EVP_PKEY_up_ref(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, int keylen, + unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, + int saltlen, int iter, const EVP_MD *digest, int keylen, + unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +#define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +#define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); + +#define ASN1_PKEY_ALIAS 0x1 +#define ASN1_PKEY_DYNAMIC 0x2 +#define ASN1_PKEY_SIGPARAM_NULL 0x4 + +#define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +#define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +#define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 +#define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub), + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk), + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx), + int (*pkey_size)(const EVP_PKEY *pk), + int (*pkey_bits)(const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf), + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk), + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen), + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder), + int (*param_missing)(const EVP_PKEY *pk), + int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from), + int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free)(EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2)); +void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_security_bits)(const EVP_PKEY *pkey)); + +void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check)(const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_public_check)(const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check)(const EVP_PKEY *pk)); + +#define EVP_PKEY_OP_UNDEFINED 0 +#define EVP_PKEY_OP_PARAMGEN (1<<1) +#define EVP_PKEY_OP_KEYGEN (1<<2) +#define EVP_PKEY_OP_SIGN (1<<3) +#define EVP_PKEY_OP_VERIFY (1<<4) +#define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +#define EVP_PKEY_OP_SIGNCTX (1<<6) +#define EVP_PKEY_OP_VERIFYCTX (1<<7) +#define EVP_PKEY_OP_ENCRYPT (1<<8) +#define EVP_PKEY_OP_DECRYPT (1<<9) +#define EVP_PKEY_OP_DERIVE (1<<10) + +#define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +#define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +#define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +#define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +#define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +#define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd)) + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_PEER_KEY 2 + +#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +#define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +#define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +#define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +#define EVP_PKEY_CTRL_SET_IV 8 + +#define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +#define EVP_PKEY_CTRL_CMS_DECRYPT 10 +#define EVP_PKEY_CTRL_CMS_SIGN 11 + +#define EVP_PKEY_CTRL_CIPHER 12 + +#define EVP_PKEY_CTRL_GET_MD 13 + +#define EVP_PKEY_ALG_CTRL 0x1000 + + +#define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* Method handles all operations: don't assume any digest related + * defaults. + */ +#define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, + int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, + int keylen); +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, + size_t *routlen, const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init)(EVP_PKEY_CTX *ctx), + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init)(EVP_PKEY_CTX *ctx), + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init)(EVP_PKEY_CTX *ctx), + int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init)(EVP_PKEY_CTX *ctx), + int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init)(EVP_PKEY_CTX *ctx), + int (*verify_recover)(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init)(EVP_PKEY_CTX *ctx), + int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init)(EVP_PKEY_CTX *ctx), + int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init)(EVP_PKEY_CTX *ctx), + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), + int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)); + +void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, + int (*check)(EVP_PKEY *pkey)); +void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth, + int (*public_check)(EVP_PKEY *pkey)); +void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth, + int (*param_check)(EVP_PKEY *pkey)); + +/* Authenticated Encryption with Additional Data. + * + * AEAD couples confidentiality and integrity in a single primtive. AEAD + * algorithms take a key and then can seal and open individual messages. Each + * message has a unique, per-message nonce and, optionally, additional data + * which is authenticated but not included in the output. */ + +typedef struct evp_aead_st EVP_AEAD; + +#ifndef OPENSSL_NO_AES +/* EVP_aes_128_gcm is AES-128 in Galois Counter Mode. */ +const EVP_AEAD *EVP_aead_aes_128_gcm(void); +/* EVP_aes_256_gcm is AES-256 in Galois Counter Mode. */ +const EVP_AEAD *EVP_aead_aes_256_gcm(void); +#endif + +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ +const EVP_AEAD *EVP_aead_chacha20_poly1305(void); +/* EVP_aead_xchacha20_poly1305 is XChaCha20 with a Poly1305 authenticator. */ +const EVP_AEAD *EVP_aead_xchacha20_poly1305(void); +#endif + +/* EVP_AEAD_key_length returns the length of the keys used. */ +size_t EVP_AEAD_key_length(const EVP_AEAD *aead); + +/* EVP_AEAD_nonce_length returns the length of the per-message nonce. */ +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead); + +/* EVP_AEAD_max_overhead returns the maximum number of additional bytes added + * by the act of sealing data with the AEAD. */ +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead); + +/* EVP_AEAD_max_tag_len returns the maximum tag length when using this AEAD. + * This * is the largest value that can be passed as a tag length to + * EVP_AEAD_CTX_init. */ +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead); + +/* An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key + * and message-independent IV. */ +typedef struct evp_aead_ctx_st EVP_AEAD_CTX; + +/* EVP_AEAD_MAX_TAG_LENGTH is the maximum tag length used by any AEAD + * defined in this header. */ +#define EVP_AEAD_MAX_TAG_LENGTH 16 + +/* EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to + * EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD + * should be used. */ +#define EVP_AEAD_DEFAULT_TAG_LENGTH 0 + +/* EVP_AEAD_CTX_new allocates a new context for use with EVP_AEAD_CTX_init. + * It can be cleaned up for reuse with EVP_AEAD_CTX_cleanup and must be freed + * with EVP_AEAD_CTX_free. */ +EVP_AEAD_CTX *EVP_AEAD_CTX_new(void); + +/* EVP_AEAD_CTX_free releases all memory owned by the context. */ +void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx); + +/* EVP_AEAD_CTX_init initializes the context for the given AEAD algorithm. + * The implementation argument may be NULL to choose the default implementation. + * Authentication tags may be truncated by passing a tag length. A tag length + * of zero indicates the default tag length should be used. */ +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const unsigned char *key, size_t key_len, size_t tag_len, ENGINE *impl); + +/* EVP_AEAD_CTX_cleanup frees any data allocated for this context. */ +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); + +/* EVP_AEAD_CTX_seal encrypts and authenticates the input and authenticates + * any additional data (AD), the result being written as output. One is + * returned on success, otherwise zero. + * + * This function may be called (with the same EVP_AEAD_CTX) concurrently with + * itself or EVP_AEAD_CTX_open. + * + * At most max_out_len bytes are written as output and, in order to ensure + * success, this value should be the length of the input plus the result of + * EVP_AEAD_overhead. On successful return, out_len is set to the actual + * number of bytes written. + * + * The length of the nonce is must be equal to the result of + * EVP_AEAD_nonce_length for this AEAD. + * + * EVP_AEAD_CTX_seal never results in a partial output. If max_out_len is + * insufficient, zero will be returned and out_len will be set to zero. + * + * If the input and output are aliased then out must be <= in. */ +int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len); + +/* EVP_AEAD_CTX_open authenticates the input and additional data, decrypting + * the input and writing it as output. One is returned on success, otherwise + * zero. + * + * This function may be called (with the same EVP_AEAD_CTX) concurrently with + * itself or EVP_AEAD_CTX_seal. + * + * At most the number of input bytes are written as output. In order to ensure + * success, max_out_len should be at least the same as the input length. On + * successful return out_len is set to the actual number of bytes written. + * + * The length of nonce must be equal to the result of EVP_AEAD_nonce_length + * for this AEAD. + * + * EVP_AEAD_CTX_open never results in a partial output. If max_out_len is + * insufficient, zero will be returned and out_len will be set to zero. + * + * If the input and output are aliased then out must be <= in. */ +int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len); + +void EVP_add_alg_module(void); + +void ERR_load_EVP_strings(void); + +/* Error codes for the EVP functions. */ + +/* Function codes. */ +#define EVP_F_AEAD_AES_GCM_INIT 187 +#define EVP_F_AEAD_AES_GCM_OPEN 188 +#define EVP_F_AEAD_AES_GCM_SEAL 189 +#define EVP_F_AEAD_CHACHA20_POLY1305_INIT 192 +#define EVP_F_AEAD_CHACHA20_POLY1305_OPEN 193 +#define EVP_F_AEAD_CHACHA20_POLY1305_SEAL 194 +#define EVP_F_AEAD_CTX_OPEN 185 +#define EVP_F_AEAD_CTX_SEAL 186 +#define EVP_F_AESNI_INIT_KEY 165 +#define EVP_F_AESNI_XTS_CIPHER 176 +#define EVP_F_AES_INIT_KEY 133 +#define EVP_F_AES_XTS 172 +#define EVP_F_AES_XTS_CIPHER 175 +#define EVP_F_ALG_MODULE_INIT 177 +#define EVP_F_CAMELLIA_INIT_KEY 159 +#define EVP_F_CMAC_INIT 173 +#define EVP_F_D2I_PKEY 100 +#define EVP_F_DO_SIGVER_INIT 161 +#define EVP_F_DSAPKEY2PKCS8 134 +#define EVP_F_DSA_PKEY2PKCS8 135 +#define EVP_F_ECDSA_PKEY2PKCS8 129 +#define EVP_F_ECKEY_PKEY2PKCS8 132 +#define EVP_F_EVP_AEAD_CTX_INIT 180 +#define EVP_F_EVP_AEAD_CTX_OPEN 190 +#define EVP_F_EVP_AEAD_CTX_SEAL 191 +#define EVP_F_EVP_BYTESTOKEY 200 +#define EVP_F_EVP_CIPHERINIT_EX 123 +#define EVP_F_EVP_CIPHER_CTX_COPY 163 +#define EVP_F_EVP_CIPHER_CTX_CTRL 124 +#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +#define EVP_F_EVP_CIPHER_GET_ASN1_IV 201 +#define EVP_F_EVP_CIPHER_SET_ASN1_IV 202 +#define EVP_F_EVP_DECRYPTFINAL_EX 101 +#define EVP_F_EVP_DECRYPTUPDATE 199 +#define EVP_F_EVP_DIGESTFINAL_EX 196 +#define EVP_F_EVP_DIGESTINIT_EX 128 +#define EVP_F_EVP_ENCRYPTFINAL_EX 127 +#define EVP_F_EVP_ENCRYPTUPDATE 198 +#define EVP_F_EVP_MD_CTX_COPY_EX 110 +#define EVP_F_EVP_MD_CTX_CTRL 195 +#define EVP_F_EVP_MD_SIZE 162 +#define EVP_F_EVP_OPENINIT 102 +#define EVP_F_EVP_PBE_ALG_ADD 115 +#define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +#define EVP_F_EVP_PBE_CIPHERINIT 116 +#define EVP_F_EVP_PKCS82PKEY 111 +#define EVP_F_EVP_PKCS82PKEY_BROKEN 136 +#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +#define EVP_F_EVP_PKEY_CTX_CTRL 137 +#define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +#define EVP_F_EVP_PKEY_CTX_DUP 156 +#define EVP_F_EVP_PKEY_DECRYPT 104 +#define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +#define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +#define EVP_F_EVP_PKEY_DERIVE 153 +#define EVP_F_EVP_PKEY_DERIVE_INIT 154 +#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +#define EVP_F_EVP_PKEY_ENCRYPT 105 +#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +#define EVP_F_EVP_PKEY_GET1_DH 119 +#define EVP_F_EVP_PKEY_GET1_DSA 120 +#define EVP_F_EVP_PKEY_GET1_ECDSA 130 +#define EVP_F_EVP_PKEY_GET1_EC_KEY 131 +#define EVP_F_EVP_PKEY_GET1_RSA 121 +#define EVP_F_EVP_PKEY_KEYGEN 146 +#define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +#define EVP_F_EVP_PKEY_NEW 106 +#define EVP_F_EVP_PKEY_PARAMGEN 148 +#define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +#define EVP_F_EVP_PKEY_SIGN 140 +#define EVP_F_EVP_PKEY_SIGN_INIT 141 +#define EVP_F_EVP_PKEY_VERIFY 142 +#define EVP_F_EVP_PKEY_VERIFY_INIT 143 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +#define EVP_F_EVP_RIJNDAEL 126 +#define EVP_F_EVP_SIGNFINAL 107 +#define EVP_F_EVP_VERIFYFINAL 108 +#define EVP_F_FIPS_CIPHERINIT 166 +#define EVP_F_FIPS_CIPHER_CTX_COPY 170 +#define EVP_F_FIPS_CIPHER_CTX_CTRL 167 +#define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171 +#define EVP_F_FIPS_DIGESTINIT 168 +#define EVP_F_FIPS_MD_CTX_COPY 169 +#define EVP_F_HMAC_INIT_EX 174 +#define EVP_F_INT_CTX_NEW 157 +#define EVP_F_PKCS5_PBE_KEYIVGEN 117 +#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +#define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +#define EVP_F_PKCS8_SET_BROKEN 112 +#define EVP_F_PKEY_SET_TYPE 158 +#define EVP_F_RC2_GET_ASN1_TYPE_AND_IV 197 +#define EVP_F_RC2_MAGIC_TO_METH 109 +#define EVP_F_RC5_CTRL 125 + +/* Reason codes. */ +#define EVP_R_AES_IV_SETUP_FAILED 162 +#define EVP_R_AES_KEY_SETUP_FAILED 143 +#define EVP_R_ASN1_LIB 140 +#define EVP_R_BAD_BLOCK_LENGTH 136 +#define EVP_R_BAD_DECRYPT 100 +#define EVP_R_BAD_KEY_LENGTH 137 +#define EVP_R_BN_DECODE_ERROR 112 +#define EVP_R_BN_PUBKEY_ERROR 113 +#define EVP_R_BUFFER_TOO_SMALL 155 +#define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +#define EVP_R_CIPHER_PARAMETER_ERROR 122 +#define EVP_R_COMMAND_NOT_SUPPORTED 147 +#define EVP_R_CTRL_NOT_IMPLEMENTED 132 +#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +#define EVP_R_DECODE_ERROR 114 +#define EVP_R_DIFFERENT_KEY_TYPES 101 +#define EVP_R_DIFFERENT_PARAMETERS 153 +#define EVP_R_DISABLED_FOR_FIPS 163 +#define EVP_R_ENCODE_ERROR 115 +#define EVP_R_ERROR_LOADING_SECTION 165 +#define EVP_R_ERROR_SETTING_FIPS_MODE 166 +#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 +#define EVP_R_EXPECTING_AN_HMAC_KEY 174 +#define EVP_R_EXPECTING_AN_RSA_KEY 127 +#define EVP_R_EXPECTING_A_DH_KEY 128 +#define EVP_R_EXPECTING_A_DSA_KEY 129 +#define EVP_R_EXPECTING_A_ECDSA_KEY 141 +#define EVP_R_EXPECTING_A_EC_KEY 142 +#define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +#define EVP_R_GET_RAW_KEY_FAILED 182 +#define EVP_R_INITIALIZATION_ERROR 134 +#define EVP_R_INPUT_NOT_INITIALIZED 111 +#define EVP_R_INVALID_DIGEST 152 +#define EVP_R_INVALID_FIPS_MODE 168 +#define EVP_R_INVALID_IV_LENGTH 194 +#define EVP_R_INVALID_KEY_LENGTH 130 +#define EVP_R_INVALID_OPERATION 148 +#define EVP_R_IV_TOO_LARGE 102 +#define EVP_R_KEYGEN_FAILURE 120 +#define EVP_R_KEY_SETUP_FAILED 180 +#define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +#define EVP_R_METHOD_NOT_SUPPORTED 144 +#define EVP_R_MISSING_PARAMETERS 103 +#define EVP_R_NO_CIPHER_SET 131 +#define EVP_R_NO_DEFAULT_DIGEST 158 +#define EVP_R_NO_DIGEST_SET 139 +#define EVP_R_NO_DSA_PARAMETERS 116 +#define EVP_R_NO_KEY_SET 154 +#define EVP_R_NO_OPERATION_SET 149 +#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 +#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +#define EVP_R_ONLY_ONESHOT_SUPPORTED 177 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +#define EVP_R_OPERATON_NOT_INITIALIZED 151 +#define EVP_R_OUTPUT_ALIASES_INPUT 172 +#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +#define EVP_R_PUBLIC_KEY_NOT_RSA 106 +#define EVP_R_TAG_TOO_LARGE 171 +#define EVP_R_TOO_LARGE 164 +#define EVP_R_UNKNOWN_CIPHER 160 +#define EVP_R_UNKNOWN_DIGEST 161 +#define EVP_R_UNKNOWN_OPTION 169 +#define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +#define EVP_R_UNSUPPORTED_ALGORITHM 156 +#define EVP_R_UNSUPPORTED_CIPHER 107 +#define EVP_R_UNSUPPORTED_KEYLENGTH 123 +#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +#define EVP_R_UNSUPPORTED_KEY_SIZE 108 +#define EVP_R_UNSUPPORTED_PRF 125 +#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +#define EVP_R_WRAP_MODE_NOT_ALLOWED 170 +#define EVP_R_UNSUPPORTED_SALT_TYPE 126 +#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +#define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/gost.h b/Libraries/libressl/include/openssl/gost.h new file mode 100644 index 000000000..c7d9d25b2 --- /dev/null +++ b/Libraries/libressl/include/openssl/gost.h @@ -0,0 +1,262 @@ +/* $OpenBSD: gost.h,v 1.4 2022/07/12 14:42:49 kn Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_GOST_H +#define HEADER_GOST_H + +#include + +#ifdef OPENSSL_NO_GOST +#error GOST is disabled. +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct gost2814789_key_st { + unsigned int key[8]; + unsigned int k87[256],k65[256],k43[256],k21[256]; + unsigned int count; + unsigned key_meshing : 1; +} GOST2814789_KEY; + +int Gost2814789_set_sbox(GOST2814789_KEY *key, int nid); +int Gost2814789_set_key(GOST2814789_KEY *key, + const unsigned char *userKey, const int bits); +void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out, + GOST2814789_KEY *key, const int enc); +void Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out, + size_t length, GOST2814789_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, + size_t length, GOST2814789_KEY *key, + unsigned char *ivec, unsigned char *cnt_buf, int *num); + +typedef struct { + ASN1_OCTET_STRING *iv; + ASN1_OBJECT *enc_param_set; +} GOST_CIPHER_PARAMS; + +GOST_CIPHER_PARAMS *GOST_CIPHER_PARAMS_new(void); +void GOST_CIPHER_PARAMS_free(GOST_CIPHER_PARAMS *a); +GOST_CIPHER_PARAMS *d2i_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS **a, const unsigned char **in, long len); +int i2d_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS *a, unsigned char **out); +extern const ASN1_ITEM GOST_CIPHER_PARAMS_it; + +#define GOST2814789IMIT_LENGTH 4 +#define GOST2814789IMIT_CBLOCK 8 +#define GOST2814789IMIT_LONG unsigned int + +typedef struct GOST2814789IMITstate_st { + GOST2814789IMIT_LONG Nl, Nh; + unsigned char data[GOST2814789IMIT_CBLOCK]; + unsigned int num; + + GOST2814789_KEY cipher; + unsigned char mac[GOST2814789IMIT_CBLOCK]; +} GOST2814789IMIT_CTX; + +/* Note, also removed second parameter and removed dctx->cipher setting */ +int GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid); +int GOST2814789IMIT_Update(GOST2814789IMIT_CTX *c, const void *data, size_t len); +int GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c); +void GOST2814789IMIT_Transform(GOST2814789IMIT_CTX *c, const unsigned char *data); +unsigned char *GOST2814789IMIT(const unsigned char *d, size_t n, + unsigned char *md, int nid, + const unsigned char *key, const unsigned char *iv); + +#define GOSTR341194_LONG unsigned int + +#define GOSTR341194_LENGTH 32 +#define GOSTR341194_CBLOCK 32 +#define GOSTR341194_LBLOCK (GOSTR341194_CBLOCK/4) + +typedef struct GOSTR341194state_st { + GOSTR341194_LONG Nl, Nh; + GOSTR341194_LONG data[GOSTR341194_LBLOCK]; + unsigned int num; + + GOST2814789_KEY cipher; + unsigned char H[GOSTR341194_CBLOCK]; + unsigned char S[GOSTR341194_CBLOCK]; +} GOSTR341194_CTX; + +/* Note, also removed second parameter and removed dctx->cipher setting */ +int GOSTR341194_Init(GOSTR341194_CTX *c, int nid); +int GOSTR341194_Update(GOSTR341194_CTX *c, const void *data, size_t len); +int GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX *c); +void GOSTR341194_Transform(GOSTR341194_CTX *c, const unsigned char *data); +unsigned char *GOSTR341194(const unsigned char *d, size_t n,unsigned char *md, int nid); + +#if defined(_LP64) +#define STREEBOG_LONG64 unsigned long +#define U64(C) C##UL +#else +#define STREEBOG_LONG64 unsigned long long +#define U64(C) C##ULL +#endif + +#define STREEBOG_LBLOCK 8 +#define STREEBOG_CBLOCK 64 +#define STREEBOG256_LENGTH 32 +#define STREEBOG512_LENGTH 64 + +typedef struct STREEBOGstate_st { + STREEBOG_LONG64 data[STREEBOG_LBLOCK]; + unsigned int num; + unsigned int md_len; + STREEBOG_LONG64 h[STREEBOG_LBLOCK]; + STREEBOG_LONG64 N[STREEBOG_LBLOCK]; + STREEBOG_LONG64 Sigma[STREEBOG_LBLOCK]; +} STREEBOG_CTX; + +int STREEBOG256_Init(STREEBOG_CTX *c); +int STREEBOG256_Update(STREEBOG_CTX *c, const void *data, size_t len); +int STREEBOG256_Final(unsigned char *md, STREEBOG_CTX *c); +void STREEBOG256_Transform(STREEBOG_CTX *c, const unsigned char *data); +unsigned char *STREEBOG256(const unsigned char *d, size_t n,unsigned char *md); + +int STREEBOG512_Init(STREEBOG_CTX *c); +int STREEBOG512_Update(STREEBOG_CTX *c, const void *data, size_t len); +int STREEBOG512_Final(unsigned char *md, STREEBOG_CTX *c); +void STREEBOG512_Transform(STREEBOG_CTX *c, const unsigned char *data); +unsigned char *STREEBOG512(const unsigned char *d, size_t n,unsigned char *md); + +typedef struct gost_key_st GOST_KEY; +GOST_KEY *GOST_KEY_new(void); +void GOST_KEY_free(GOST_KEY * r); +int GOST_KEY_check_key(const GOST_KEY * eckey); +int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y); +const EC_GROUP * GOST_KEY_get0_group(const GOST_KEY * key); +int GOST_KEY_set_group(GOST_KEY * key, const EC_GROUP * group); +int GOST_KEY_get_digest(const GOST_KEY * key); +int GOST_KEY_set_digest(GOST_KEY * key, int digest_nid); +const BIGNUM * GOST_KEY_get0_private_key(const GOST_KEY * key); +int GOST_KEY_set_private_key(GOST_KEY * key, const BIGNUM * priv_key); +const EC_POINT * GOST_KEY_get0_public_key(const GOST_KEY * key); +int GOST_KEY_set_public_key(GOST_KEY * key, const EC_POINT * pub_key); +size_t GOST_KEY_get_size(const GOST_KEY * r); + +/* Gost-specific pmeth control-function parameters */ +/* For GOST R34.10 parameters */ +#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) +#define EVP_PKEY_CTRL_GOST_SIG_FORMAT (EVP_PKEY_ALG_CTRL+2) +#define EVP_PKEY_CTRL_GOST_SET_DIGEST (EVP_PKEY_ALG_CTRL+3) +#define EVP_PKEY_CTRL_GOST_GET_DIGEST (EVP_PKEY_ALG_CTRL+4) + +#define GOST_SIG_FORMAT_SR_BE 0 +#define GOST_SIG_FORMAT_RS_LE 1 + +void ERR_load_GOST_strings(void); + +/* Error codes for the GOST functions. */ + +/* Function codes. */ +#define GOST_F_DECODE_GOST01_ALGOR_PARAMS 104 +#define GOST_F_ENCODE_GOST01_ALGOR_PARAMS 105 +#define GOST_F_GOST2001_COMPUTE_PUBLIC 106 +#define GOST_F_GOST2001_DO_SIGN 107 +#define GOST_F_GOST2001_DO_VERIFY 108 +#define GOST_F_GOST2001_KEYGEN 109 +#define GOST_F_GOST89_GET_ASN1_PARAMETERS 102 +#define GOST_F_GOST89_SET_ASN1_PARAMETERS 103 +#define GOST_F_GOST_KEY_CHECK_KEY 124 +#define GOST_F_GOST_KEY_NEW 125 +#define GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 126 +#define GOST_F_PARAM_COPY_GOST01 110 +#define GOST_F_PARAM_DECODE_GOST01 111 +#define GOST_F_PKEY_GOST01_CTRL 116 +#define GOST_F_PKEY_GOST01_DECRYPT 112 +#define GOST_F_PKEY_GOST01_DERIVE 113 +#define GOST_F_PKEY_GOST01_ENCRYPT 114 +#define GOST_F_PKEY_GOST01_PARAMGEN 115 +#define GOST_F_PKEY_GOST01_SIGN 123 +#define GOST_F_PKEY_GOST_MAC_CTRL 100 +#define GOST_F_PKEY_GOST_MAC_KEYGEN 101 +#define GOST_F_PRIV_DECODE_GOST01 117 +#define GOST_F_PUB_DECODE_GOST01 118 +#define GOST_F_PUB_ENCODE_GOST01 119 +#define GOST_F_PUB_PRINT_GOST01 120 +#define GOST_F_UNPACK_SIGNATURE_CP 121 +#define GOST_F_UNPACK_SIGNATURE_LE 122 + +/* Reason codes. */ +#define GOST_R_BAD_KEY_PARAMETERS_FORMAT 104 +#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 105 +#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 106 +#define GOST_R_CTRL_CALL_FAILED 107 +#define GOST_R_ERROR_COMPUTING_SHARED_KEY 108 +#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 109 +#define GOST_R_INCOMPATIBLE_ALGORITHMS 110 +#define GOST_R_INCOMPATIBLE_PEER_KEY 111 +#define GOST_R_INVALID_DIGEST_TYPE 100 +#define GOST_R_INVALID_IV_LENGTH 103 +#define GOST_R_INVALID_MAC_KEY_LENGTH 101 +#define GOST_R_KEY_IS_NOT_INITIALIZED 112 +#define GOST_R_KEY_PARAMETERS_MISSING 113 +#define GOST_R_MAC_KEY_NOT_SET 102 +#define GOST_R_NO_PARAMETERS_SET 115 +#define GOST_R_NO_PEER_KEY 116 +#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 117 +#define GOST_R_PUBLIC_KEY_UNDEFINED 118 +#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 120 +#define GOST_R_SIGNATURE_MISMATCH 121 +#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 122 +#define GOST_R_UKM_NOT_SET 123 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/hkdf.h b/Libraries/libressl/include/openssl/hkdf.h new file mode 100644 index 000000000..6cec526e3 --- /dev/null +++ b/Libraries/libressl/include/openssl/hkdf.h @@ -0,0 +1,65 @@ +/* $OpenBSD: hkdf.h,v 1.3 2023/08/11 04:52:08 tb Exp $ */ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_HKDF_H +#define OPENSSL_HEADER_HKDF_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * HKDF computes HKDF (as specified by RFC 5869) of initial keying + * material |secret| with |salt| and |info| using |digest|, and + * outputs |out_len| bytes to |out_key|. It returns one on success and + * zero on error. + * + * HKDF is an Extract-and-Expand algorithm. It does not do any key + * stretching, and as such, is not suited to be used alone to generate + * a key from a password. + */ + +int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len, const uint8_t *info, size_t info_len); + +/* + * HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from + * initial keying material |secret| and salt |salt| using |digest|, + * and outputs |out_len| bytes to |out_key|. The maximum output size + * is |EVP_MAX_MD_SIZE|. It returns one on success and zero on error. + */ +int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const uint8_t *salt, size_t salt_len); + +/* + * HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of + * length |out_len| from the PRK |prk| and info |info| using |digest|, + * and outputs the result to |out_key|. It returns one on success and + * zero on error. + */ +int HKDF_expand(uint8_t *out_key, size_t out_len, + const EVP_MD *digest, const uint8_t *prk, size_t prk_len, + const uint8_t *info, size_t info_len); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_HKDF_H */ diff --git a/Libraries/libressl/include/openssl/hmac.h b/Libraries/libressl/include/openssl/hmac.h new file mode 100644 index 000000000..1ce365294 --- /dev/null +++ b/Libraries/libressl/include/openssl/hmac.h @@ -0,0 +1,98 @@ +/* $OpenBSD: hmac.h,v 1.17 2023/04/25 15:48:48 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_H +#define HEADER_HMAC_H + +#include + +#ifdef OPENSSL_NO_HMAC +#error HMAC is disabled. +#endif + +#include + +#define HMAC_MAX_MD_CBLOCK 144 /* largest known is SHA3-224 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define HMAC_size(e) (EVP_MD_size(HMAC_CTX_get_md((e)))) + +HMAC_CTX *HMAC_CTX_new(void); +void HMAC_CTX_free(HMAC_CTX *ctx); +int HMAC_CTX_reset(HMAC_CTX *ctx); + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md); /* deprecated */ +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, + ENGINE *impl); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); +const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/idea.h b/Libraries/libressl/include/openssl/idea.h new file mode 100644 index 000000000..e5ddd3a6f --- /dev/null +++ b/Libraries/libressl/include/openssl/idea.h @@ -0,0 +1,99 @@ +/* $OpenBSD: idea.h,v 1.11 2023/07/07 12:51:58 beck Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_IDEA_H +#define HEADER_IDEA_H + +#include /* IDEA_INT, OPENSSL_NO_IDEA */ + +#ifdef OPENSSL_NO_IDEA +#error IDEA is disabled. +#endif + +#define IDEA_ENCRYPT 1 +#define IDEA_DECRYPT 0 + +#define IDEA_BLOCK 8 +#define IDEA_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *idea_options(void); +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int enc); +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num); +void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/kdf.h b/Libraries/libressl/include/openssl/kdf.h new file mode 100644 index 000000000..f823bf99e --- /dev/null +++ b/Libraries/libressl/include/openssl/kdf.h @@ -0,0 +1,111 @@ +/* $OpenBSD: kdf.h,v 1.8 2022/07/12 14:42:49 kn Exp $ */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2016-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_KDF_H +# define HEADER_KDF_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 7) + +# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 +# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 +# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 + +# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)) + +# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)) + +# define EVP_PKEY_CTX_hkdf_mode(pctx, mode) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL) + +int ERR_load_KDF_strings(void); + +/* + * KDF function codes. + */ +# define KDF_F_PKEY_HKDF_CTRL_STR 103 +# define KDF_F_PKEY_HKDF_DERIVE 102 +# define KDF_F_PKEY_HKDF_INIT 108 + +/* + * KDF reason codes. + */ +# define KDF_R_MISSING_KEY 104 +# define KDF_R_MISSING_MESSAGE_DIGEST 105 +# define KDF_R_UNKNOWN_PARAMETER_TYPE 103 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Libraries/libressl/include/openssl/lhash.h b/Libraries/libressl/include/openssl/lhash.h new file mode 100644 index 000000000..9c6365739 --- /dev/null +++ b/Libraries/libressl/include/openssl/lhash.h @@ -0,0 +1,235 @@ +/* $OpenBSD: lhash.h,v 1.12 2014/06/12 15:49:29 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Header for dynamic hash table routines + * Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +#define HEADER_LHASH_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st { + void *data; + struct lhash_node_st *next; +#ifndef OPENSSL_NO_HASH_COMP + unsigned long hash; +#endif +} LHASH_NODE; + +typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); +typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); +typedef void (*LHASH_DOALL_FN_TYPE)(void *); +typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *); + +/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks. + * This way, callbacks can be provided to LHASH structures without function + * pointer casting and the macro-defined callbacks provide per-variable casting + * before deferring to the underlying type-specific callbacks. NB: It is + * possible to place a "static" in front of both the DECLARE and IMPLEMENT + * macros if the functions are strictly internal. */ + +/* First: "hash" functions */ +#define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +#define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +#define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +#define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Third: "doall" functions */ +#define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +#define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + +typedef struct lhash_st { + LHASH_NODE **b; + LHASH_COMP_FN_TYPE comp; + LHASH_HASH_FN_TYPE hash; + unsigned int num_nodes; + unsigned int num_alloc_nodes; + unsigned int p; + unsigned int pmax; + unsigned long up_load; /* load times 256 */ + unsigned long down_load; /* load times 256 */ + unsigned long num_items; + + unsigned long num_expands; + unsigned long num_expand_reallocs; + unsigned long num_contracts; + unsigned long num_contract_reallocs; + unsigned long num_hash_calls; + unsigned long num_comp_calls; + unsigned long num_insert; + unsigned long num_replace; + unsigned long num_delete; + unsigned long num_no_delete; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; + + int error; +} _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ + +#define LH_LOAD_MULT 256 + +/* Indicates a malloc() error in the last call, this is only bad + * in lh_insert(). */ +#define lh_error(lh) ((lh)->error) + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(const _LHASH *lh); + +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); + +#ifndef OPENSSL_NO_BIO +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); +#endif + +/* Type checking... */ + +#define LHASH_OF(type) struct lhash_st_##type + +#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +#define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +#define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +#define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +#define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +#define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/md4.h b/Libraries/libressl/include/openssl/md4.h new file mode 100644 index 000000000..cb4f3cb6e --- /dev/null +++ b/Libraries/libressl/include/openssl/md4.h @@ -0,0 +1,102 @@ +/* $OpenBSD: md4.h,v 1.17 2023/07/08 06:47:26 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_MD4_H +#define HEADER_MD4_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_MD4 +#error MD4 is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define MD4_LONG unsigned int + +#define MD4_CBLOCK 64 +#define MD4_LBLOCK (MD4_CBLOCK/4) +#define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B,C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/md5.h b/Libraries/libressl/include/openssl/md5.h new file mode 100644 index 000000000..d248c93a8 --- /dev/null +++ b/Libraries/libressl/include/openssl/md5.h @@ -0,0 +1,107 @@ +/* $OpenBSD: md5.h,v 1.21 2023/07/08 06:50:38 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_MD5_H +#define HEADER_MD5_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_MD5 +#error MD5 is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define MD5_LONG unsigned int + +#define MD5_CBLOCK 64 +#define MD5_LBLOCK (MD5_CBLOCK/4) +#define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B,C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__, 2, 3))); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__, 1, 2))); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/modes.h b/Libraries/libressl/include/openssl/modes.h new file mode 100644 index 000000000..53fa9afb0 --- /dev/null +++ b/Libraries/libressl/include/openssl/modes.h @@ -0,0 +1,118 @@ +/* $OpenBSD: modes.h,v 1.6 2023/07/08 14:55:36 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*block128_f)(const unsigned char in[16], + unsigned char out[16], + const void *key); + +typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f)(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f)(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, + const unsigned char *nonce, size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, + const unsigned char *aad, size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, size_t len, int enc); + +#ifdef __cplusplus +} +#endif diff --git a/Libraries/libressl/include/openssl/obj_mac.h b/Libraries/libressl/include/openssl/obj_mac.h new file mode 100644 index 000000000..51cd083a6 --- /dev/null +++ b/Libraries/libressl/include/openssl/obj_mac.h @@ -0,0 +1,4630 @@ +/* crypto/objects/obj_mac.h */ + +/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the + * following command: + * perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 992 +#define OBJ_pSpecified OBJ_pkcs1,9L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_sha512_224WithRSAEncryption "RSA-SHA512/224" +#define LN_sha512_224WithRSAEncryption "sha512-224WithRSAEncryption" +#define NID_sha512_224WithRSAEncryption 1025 +#define OBJ_sha512_224WithRSAEncryption OBJ_pkcs1,15L + +#define SN_sha512_256WithRSAEncryption "RSA-SHA512/256" +#define LN_sha512_256WithRSAEncryption "sha512-256WithRSAEncryption" +#define NID_sha512_256WithRSAEncryption 1026 +#define OBJ_sha512_256WithRSAEncryption OBJ_pkcs1,16L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_ct_routeOriginAuthz "id-ct-routeOriginAuthz" +#define NID_id_ct_routeOriginAuthz 1001 +#define OBJ_id_ct_routeOriginAuthz OBJ_id_smime_ct,24L + +#define SN_id_ct_rpkiManifest "id-ct-rpkiManifest" +#define NID_id_ct_rpkiManifest 1002 +#define OBJ_id_ct_rpkiManifest OBJ_id_smime_ct,26L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_ct_rpkiGhostbusters "id-ct-rpkiGhostbusters" +#define NID_id_ct_rpkiGhostbusters 1003 +#define OBJ_id_ct_rpkiGhostbusters OBJ_id_smime_ct,35L + +#define SN_id_ct_resourceTaggedAttest "id-ct-resourceTaggedAttest" +#define NID_id_ct_resourceTaggedAttest 1004 +#define OBJ_id_ct_resourceTaggedAttest OBJ_id_smime_ct,36L + +#define SN_id_ct_geofeedCSVwithCRLF "id-ct-geofeedCSVwithCRLF" +#define NID_id_ct_geofeedCSVwithCRLF 1013 +#define OBJ_id_ct_geofeedCSVwithCRLF OBJ_id_smime_ct,47L + +#define SN_id_ct_signedChecklist "id-ct-signedChecklist" +#define NID_id_ct_signedChecklist 1014 +#define OBJ_id_ct_signedChecklist OBJ_id_smime_ct,48L + +#define SN_id_ct_ASPA "id-ct-ASPA" +#define NID_id_ct_ASPA 1017 +#define OBJ_id_ct_ASPA OBJ_id_smime_ct,49L + +#define SN_id_ct_signedTAL "id-ct-signedTAL" +#define NID_id_ct_signedTAL 1024 +#define OBJ_id_ct_signedTAL OBJ_id_smime_ct,50L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_aa_signingCertificateV2 "id-smime-aa-signingCertificateV2" +#define NID_id_smime_aa_signingCertificateV2 1023 +#define OBJ_id_smime_aa_signingCertificateV2 OBJ_id_smime_aa,47L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define LN_hmacWithSHA512_224 "hmacWithSHA512-224" +#define NID_hmacWithSHA512_224 1027 +#define OBJ_hmacWithSHA512_224 OBJ_rsadsi,2L,12L + +#define LN_hmacWithSHA512_256 "hmacWithSHA512-256" +#define NID_hmacWithSHA512_256 1028 +#define OBJ_hmacWithSHA512_256 OBJ_rsadsi,2L,13L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_cp "id-cp" +#define NID_id_cp 1005 +#define OBJ_id_cp OBJ_id_pkix,14L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_tlsfeature "tlsfeature" +#define LN_tlsfeature "TLS Feature" +#define NID_tlsfeature 1016 +#define OBJ_tlsfeature OBJ_id_pe,24L + +#define SN_sbgp_ipAddrBlockv2 "sbgp-ipAddrBlockv2" +#define NID_sbgp_ipAddrBlockv2 1006 +#define OBJ_sbgp_ipAddrBlockv2 OBJ_id_pe,28L + +#define SN_sbgp_autonomousSysNumv2 "sbgp-autonomousSysNumv2" +#define NID_sbgp_autonomousSysNumv2 1007 +#define OBJ_sbgp_autonomousSysNumv2 OBJ_id_pe,29L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_id_kp_bgpsec_router "id-kp-bgpsec-router" +#define LN_id_kp_bgpsec_router "BGPsec Router" +#define NID_id_kp_bgpsec_router 1015 +#define OBJ_id_kp_bgpsec_router OBJ_id_kp,30L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_ipAddr_asNumber "ipAddr-asNumber" +#define NID_ipAddr_asNumber 1008 +#define OBJ_ipAddr_asNumber OBJ_id_cp,2L + +#define SN_ipAddr_asNumberv2 "ipAddr-asNumberv2" +#define NID_ipAddr_asNumberv2 1009 +#define OBJ_ipAddr_asNumberv2 OBJ_id_cp,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define SN_rpkiManifest "rpkiManifest" +#define LN_rpkiManifest "RPKI Manifest" +#define NID_rpkiManifest 1010 +#define OBJ_rpkiManifest OBJ_id_ad,10L + +#define SN_signedObject "signedObject" +#define LN_signedObject "Signed Object" +#define NID_signedObject 1011 +#define OBJ_signedObject OBJ_id_ad,11L + +#define SN_rpkiNotify "rpkiNotify" +#define LN_rpkiNotify "RPKI Notify" +#define NID_rpkiNotify 1012 +#define OBJ_rpkiNotify OBJ_id_ad,13L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define OBJ_extendedValidation OBJ_Enterprises,311L,60L + +#define LN_jurisdictionLocalityName "jurisdictionLocalityName" +#define NID_jurisdictionLocalityName 956 +#define OBJ_jurisdictionLocalityName OBJ_extendedValidation,2L,1L,1L + +#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" +#define NID_jurisdictionStateOrProvinceName 957 +#define OBJ_jurisdictionStateOrProvinceName OBJ_extendedValidation,2L,1L,2L + +#define LN_jurisdictionCountryName "jurisdictionCountryName" +#define NID_jurisdictionCountryName 958 +#define OBJ_jurisdictionCountryName OBJ_extendedValidation,2L,1L,3L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define SN_sha512_224 "SHA512-224" +#define LN_sha512_224 "sha512-224" +#define NID_sha512_224 1029 +#define OBJ_sha512_224 OBJ_nist_hashalgs,5L + +#define SN_sha512_256 "SHA512-256" +#define LN_sha512_256 "sha512-256" +#define NID_sha512_256 1030 +#define OBJ_sha512_256 OBJ_nist_hashalgs,6L + +#define SN_sha3_224 "SHA3-224" +#define LN_sha3_224 "sha3-224" +#define NID_sha3_224 1031 +#define OBJ_sha3_224 OBJ_nist_hashalgs,7L + +#define SN_sha3_256 "SHA3-256" +#define LN_sha3_256 "sha3-256" +#define NID_sha3_256 1032 +#define OBJ_sha3_256 OBJ_nist_hashalgs,8L + +#define SN_sha3_384 "SHA3-384" +#define LN_sha3_384 "sha3-384" +#define NID_sha3_384 1033 +#define OBJ_sha3_384 OBJ_nist_hashalgs,9L + +#define SN_sha3_512 "SHA3-512" +#define LN_sha3_512 "sha3-512" +#define NID_sha3_512 1034 +#define OBJ_sha3_512 OBJ_nist_hashalgs,10L + +#define SN_hmac_sha3_224 "id-hmacWithSHA3-224" +#define LN_hmac_sha3_224 "hmac-sha3-224" +#define NID_hmac_sha3_224 1035 +#define OBJ_hmac_sha3_224 OBJ_nist_hashalgs,13L + +#define SN_hmac_sha3_256 "id-hmacWithSHA3-256" +#define LN_hmac_sha3_256 "hmac-sha3-256" +#define NID_hmac_sha3_256 1036 +#define OBJ_hmac_sha3_256 OBJ_nist_hashalgs,14L + +#define SN_hmac_sha3_384 "id-hmacWithSHA3-384" +#define LN_hmac_sha3_384 "hmac-sha3-384" +#define NID_hmac_sha3_384 1037 +#define OBJ_hmac_sha3_384 OBJ_nist_hashalgs,15L + +#define SN_hmac_sha3_512 "id-hmacWithSHA3-512" +#define LN_hmac_sha3_512 "hmac-sha3-512" +#define NID_hmac_sha3_512 1038 +#define OBJ_hmac_sha3_512 OBJ_nist_hashalgs,16L + +#define OBJ_nist_sigalgs OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "id-dsa-with-sha224" +#define LN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_nist_sigalgs,1L + +#define SN_dsa_with_SHA256 "id-dsa-with-sha256" +#define LN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_nist_sigalgs,2L + +#define SN_dsa_with_SHA384 "id-dsa-with-sha384" +#define LN_dsa_with_SHA384 "dsa_with_SHA384" +#define NID_dsa_with_SHA384 1039 +#define OBJ_dsa_with_SHA384 OBJ_nist_sigalgs,3L + +#define SN_dsa_with_SHA512 "id-dsa-with-sha512" +#define LN_dsa_with_SHA512 "dsa_with_SHA512" +#define NID_dsa_with_SHA512 1040 +#define OBJ_dsa_with_SHA512 OBJ_nist_sigalgs,4L + +#define SN_dsa_with_SHA3_224 "id-dsa-with-sha3-224" +#define LN_dsa_with_SHA3_224 "dsa_with_SHA3-224" +#define NID_dsa_with_SHA3_224 1041 +#define OBJ_dsa_with_SHA3_224 OBJ_nist_sigalgs,5L + +#define SN_dsa_with_SHA3_256 "id-dsa-with-sha3-256" +#define LN_dsa_with_SHA3_256 "dsa_with_SHA3-256" +#define NID_dsa_with_SHA3_256 1042 +#define OBJ_dsa_with_SHA3_256 OBJ_nist_sigalgs,6L + +#define SN_dsa_with_SHA3_384 "id-dsa-with-sha3-384" +#define LN_dsa_with_SHA3_384 "dsa_with_SHA3-384" +#define NID_dsa_with_SHA3_384 1043 +#define OBJ_dsa_with_SHA3_384 OBJ_nist_sigalgs,7L + +#define SN_dsa_with_SHA3_512 "id-dsa-with-sha3-512" +#define LN_dsa_with_SHA3_512 "dsa_with_SHA3-512" +#define NID_dsa_with_SHA3_512 1044 +#define OBJ_dsa_with_SHA3_512 OBJ_nist_sigalgs,8L + +#define SN_ecdsa_with_SHA3_224 "id-ecdsa-with-sha3-224" +#define LN_ecdsa_with_SHA3_224 "ecdsa_with_SHA3-224" +#define NID_ecdsa_with_SHA3_224 1045 +#define OBJ_ecdsa_with_SHA3_224 OBJ_nist_sigalgs,9L + +#define SN_ecdsa_with_SHA3_256 "id-ecdsa-with-sha3-256" +#define LN_ecdsa_with_SHA3_256 "ecdsa_with_SHA3-256" +#define NID_ecdsa_with_SHA3_256 1046 +#define OBJ_ecdsa_with_SHA3_256 OBJ_nist_sigalgs,10L + +#define SN_ecdsa_with_SHA3_384 "id-ecdsa-with-sha3-384" +#define LN_ecdsa_with_SHA3_384 "ecdsa_with_SHA3-384" +#define NID_ecdsa_with_SHA3_384 1047 +#define OBJ_ecdsa_with_SHA3_384 OBJ_nist_sigalgs,11L + +#define SN_ecdsa_with_SHA3_512 "id-ecdsa-with-sha3-512" +#define LN_ecdsa_with_SHA3_512 "ecdsa_with_SHA3-512" +#define NID_ecdsa_with_SHA3_512 1048 +#define OBJ_ecdsa_with_SHA3_512 OBJ_nist_sigalgs,12L + +#define SN_RSA_SHA3_224 "id-rsassa-pkcs1-v1_5-with-sha3-224" +#define LN_RSA_SHA3_224 "RSA-SHA3-224" +#define NID_RSA_SHA3_224 1049 +#define OBJ_RSA_SHA3_224 OBJ_nist_sigalgs,13L + +#define SN_RSA_SHA3_256 "id-rsassa-pkcs1-v1_5-with-sha3-256" +#define LN_RSA_SHA3_256 "RSA-SHA3-256" +#define NID_RSA_SHA3_256 1050 +#define OBJ_RSA_SHA3_256 OBJ_nist_sigalgs,14L + +#define SN_RSA_SHA3_384 "id-rsassa-pkcs1-v1_5-with-sha3-384" +#define LN_RSA_SHA3_384 "RSA-SHA3-384" +#define NID_RSA_SHA3_384 1051 +#define OBJ_RSA_SHA3_384 OBJ_nist_sigalgs,15L + +#define SN_RSA_SHA3_512 "id-rsassa-pkcs1-v1_5-with-sha3-512" +#define LN_RSA_SHA3_512 "RSA-SHA3-512" +#define NID_RSA_SHA3_512 1052 +#define OBJ_RSA_SHA3_512 OBJ_nist_sigalgs,16L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_sm3 "SM3" +#define LN_sm3 "sm3" +#define NID_sm3 968 +#define OBJ_sm3 1L,2L,156L,10197L,1L,401L + +#define SN_sm3WithRSAEncryption "RSA-SM3" +#define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" +#define NID_sm3WithRSAEncryption 969 +#define OBJ_sm3WithRSAEncryption 1L,2L,156L,10197L,1L,504L + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_ISO_CN "ISO-CN" +#define LN_ISO_CN "ISO CN Member Body" +#define NID_ISO_CN 970 +#define OBJ_ISO_CN OBJ_member_body,156L + +#define SN_oscca "oscca" +#define NID_oscca 971 +#define OBJ_oscca OBJ_ISO_CN,10197L + +#define SN_sm_scheme "sm-scheme" +#define NID_sm_scheme 972 +#define OBJ_sm_scheme OBJ_oscca,1L + +#define SN_sm4_ecb "SM4-ECB" +#define LN_sm4_ecb "sm4-ecb" +#define NID_sm4_ecb 973 +#define OBJ_sm4_ecb OBJ_sm_scheme,104L,1L + +#define SN_sm4_cbc "SM4-CBC" +#define LN_sm4_cbc "sm4-cbc" +#define NID_sm4_cbc 974 +#define OBJ_sm4_cbc OBJ_sm_scheme,104L,2L + +#define SN_sm4_ofb128 "SM4-OFB" +#define LN_sm4_ofb128 "sm4-ofb" +#define NID_sm4_ofb128 975 +#define OBJ_sm4_ofb128 OBJ_sm_scheme,104L,3L + +#define SN_sm4_cfb128 "SM4-CFB" +#define LN_sm4_cfb128 "sm4-cfb" +#define NID_sm4_cfb128 976 +#define OBJ_sm4_cfb128 OBJ_sm_scheme,104L,4L + +#define SN_sm4_cfb1 "SM4-CFB1" +#define LN_sm4_cfb1 "sm4-cfb1" +#define NID_sm4_cfb1 977 +#define OBJ_sm4_cfb1 OBJ_sm_scheme,104L,5L + +#define SN_sm4_cfb8 "SM4-CFB8" +#define LN_sm4_cfb8 "sm4-cfb8" +#define NID_sm4_cfb8 978 +#define OBJ_sm4_cfb8 OBJ_sm_scheme,104L,6L + +#define SN_sm4_ctr "SM4-CTR" +#define LN_sm4_ctr "sm4-ctr" +#define NID_sm4_ctr 979 +#define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L + +#define OBJ_secg_scheme OBJ_certicom_arc,1L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 980 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 981 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 982 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 983 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 984 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 985 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 986 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 987 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 988 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 989 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 990 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 991 + +#define SN_ct_precert_scts "ct_precert_scts" +#define LN_ct_precert_scts "CT Precertificate SCTs" +#define NID_ct_precert_scts 1018 +#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L + +#define SN_ct_precert_poison "ct_precert_poison" +#define LN_ct_precert_poison "CT Precertificate Poison" +#define NID_ct_precert_poison 1019 +#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L + +#define SN_ct_precert_signer "ct_precert_signer" +#define LN_ct_precert_signer "CT Precertificate Signer" +#define NID_ct_precert_signer 1020 +#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L + +#define SN_ct_cert_scts "ct_cert_scts" +#define LN_ct_cert_scts "CT Certificate SCTs" +#define NID_ct_cert_scts 1021 +#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L + +#define SN_hkdf "HKDF" +#define LN_hkdf "hkdf" +#define NID_hkdf 1022 + +#define SN_teletrust "teletrust" +#define NID_teletrust 920 +#define OBJ_teletrust OBJ_identified_organization,36L + +#define SN_brainpool "brainpool" +#define NID_brainpool 921 +#define OBJ_brainpool OBJ_teletrust,3L,3L,2L,8L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 922 +#define OBJ_brainpoolP160r1 OBJ_brainpool,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 923 +#define OBJ_brainpoolP160t1 OBJ_brainpool,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 924 +#define OBJ_brainpoolP192r1 OBJ_brainpool,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 925 +#define OBJ_brainpoolP192t1 OBJ_brainpool,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 926 +#define OBJ_brainpoolP224r1 OBJ_brainpool,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 927 +#define OBJ_brainpoolP224t1 OBJ_brainpool,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 928 +#define OBJ_brainpoolP256r1 OBJ_brainpool,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 929 +#define OBJ_brainpoolP256t1 OBJ_brainpool,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 930 +#define OBJ_brainpoolP320r1 OBJ_brainpool,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 931 +#define OBJ_brainpoolP320t1 OBJ_brainpool,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 932 +#define OBJ_brainpoolP384r1 OBJ_brainpool,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 933 +#define OBJ_brainpoolP384t1 OBJ_brainpool,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 934 +#define OBJ_brainpoolP512r1 OBJ_brainpool,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 935 +#define OBJ_brainpoolP512t1 OBJ_brainpool,1L,14L + +#define SN_FRP256v1 "FRP256v1" +#define NID_FRP256v1 936 +#define OBJ_FRP256v1 1L,2L,250L,1L,223L,101L,256L,1L + +#define SN_chacha20 "ChaCha" +#define LN_chacha20 "chacha" +#define NID_chacha20 937 + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 967 + +#define SN_gost89_ecb "gost89-ecb" +#define NID_gost89_ecb 938 + +#define SN_gost89_cbc "gost89-cbc" +#define NID_gost89_cbc 939 + +#define SN_tc26 "tc26" +#define NID_tc26 940 +#define OBJ_tc26 OBJ_member_body,643L,7L,1L + +#define SN_id_tc26_gost3411_2012_256 "streebog256" +#define LN_id_tc26_gost3411_2012_256 "GOST R 34.11-2012 (256 bit)" +#define NID_id_tc26_gost3411_2012_256 941 +#define OBJ_id_tc26_gost3411_2012_256 OBJ_tc26,1L,2L,2L + +#define SN_id_tc26_gost3411_2012_512 "streebog512" +#define LN_id_tc26_gost3411_2012_512 "GOST R 34-11-2012 (512 bit)" +#define NID_id_tc26_gost3411_2012_512 942 +#define OBJ_id_tc26_gost3411_2012_512 OBJ_tc26,1L,2L,3L + +#define SN_id_tc26_hmac_gost_3411_12_256 "id-tc26-hmac-gost-3411-12-256" +#define LN_id_tc26_hmac_gost_3411_12_256 "HMAC STREEBOG 256" +#define NID_id_tc26_hmac_gost_3411_12_256 999 +#define OBJ_id_tc26_hmac_gost_3411_12_256 OBJ_tc26,1L,4L,1L + +#define SN_id_tc26_hmac_gost_3411_12_512 "id-tc26-hmac-gost-3411-12-512" +#define LN_id_tc26_hmac_gost_3411_12_512 "HMAC STREEBOG 512" +#define NID_id_tc26_hmac_gost_3411_12_512 1000 +#define OBJ_id_tc26_hmac_gost_3411_12_512 OBJ_tc26,1L,4L,2L + +#define SN_id_tc26_gost_3410_12_256_paramSetA "id-tc26-gost-3410-12-256-paramSetA" +#define LN_id_tc26_gost_3410_12_256_paramSetA "GOST R 34.10-2012 (256 bit) ParamSet A" +#define NID_id_tc26_gost_3410_12_256_paramSetA 993 +#define OBJ_id_tc26_gost_3410_12_256_paramSetA OBJ_tc26,2L,1L,1L,1L + +#define SN_id_tc26_gost_3410_12_256_paramSetB "id-tc26-gost-3410-12-256-paramSetB" +#define LN_id_tc26_gost_3410_12_256_paramSetB "GOST R 34.10-2012 (256 bit) ParamSet B" +#define NID_id_tc26_gost_3410_12_256_paramSetB 994 +#define OBJ_id_tc26_gost_3410_12_256_paramSetB OBJ_tc26,2L,1L,1L,2L + +#define SN_id_tc26_gost_3410_12_256_paramSetC "id-tc26-gost-3410-12-256-paramSetC" +#define LN_id_tc26_gost_3410_12_256_paramSetC "GOST R 34.10-2012 (256 bit) ParamSet C" +#define NID_id_tc26_gost_3410_12_256_paramSetC 995 +#define OBJ_id_tc26_gost_3410_12_256_paramSetC OBJ_tc26,2L,1L,1L,3L + +#define SN_id_tc26_gost_3410_12_256_paramSetD "id-tc26-gost-3410-12-256-paramSetD" +#define LN_id_tc26_gost_3410_12_256_paramSetD "GOST R 34.10-2012 (256 bit) ParamSet D" +#define NID_id_tc26_gost_3410_12_256_paramSetD 996 +#define OBJ_id_tc26_gost_3410_12_256_paramSetD OBJ_tc26,2L,1L,1L,4L + +#define SN_id_tc26_gost_3410_12_512_paramSetTest "id-tc26-gost-3410-12-512-paramSetTest" +#define LN_id_tc26_gost_3410_12_512_paramSetTest "GOST R 34.10-2012 (512 bit) testing parameter set" +#define NID_id_tc26_gost_3410_12_512_paramSetTest 997 +#define OBJ_id_tc26_gost_3410_12_512_paramSetTest OBJ_tc26,2L,1L,2L,0L + +#define SN_id_tc26_gost_3410_12_512_paramSetA "id-tc26-gost-3410-12-512-paramSetA" +#define LN_id_tc26_gost_3410_12_512_paramSetA "GOST R 34.10-2012 (512 bit) ParamSet A" +#define NID_id_tc26_gost_3410_12_512_paramSetA 943 +#define OBJ_id_tc26_gost_3410_12_512_paramSetA OBJ_tc26,2L,1L,2L,1L + +#define SN_id_tc26_gost_3410_12_512_paramSetB "id-tc26-gost-3410-12-512-paramSetB" +#define LN_id_tc26_gost_3410_12_512_paramSetB "GOST R 34.10-2012 (512 bit) ParamSet B" +#define NID_id_tc26_gost_3410_12_512_paramSetB 944 +#define OBJ_id_tc26_gost_3410_12_512_paramSetB OBJ_tc26,2L,1L,2L,2L + +#define SN_id_tc26_gost_3410_12_512_paramSetC "id-tc26-gost-3410-12-512-paramSetC" +#define LN_id_tc26_gost_3410_12_512_paramSetC "GOST R 34.10-2012 (512 bit) ParamSet C" +#define NID_id_tc26_gost_3410_12_512_paramSetC 998 +#define OBJ_id_tc26_gost_3410_12_512_paramSetC OBJ_tc26,2L,1L,2L,3L + +#define SN_id_tc26_gost_28147_param_Z "id-tc26-gost-28147-param-Z" +#define NID_id_tc26_gost_28147_param_Z 945 +#define OBJ_id_tc26_gost_28147_param_Z OBJ_tc26,2L,5L,1L,1L + +#define SN_id_tc26_gost3410_2012_256 "id-tc26-gost3410-2012-256" +#define LN_id_tc26_gost3410_2012_256 "GOST R 34.10-2012 (256 bit)" +#define NID_id_tc26_gost3410_2012_256 946 +#define OBJ_id_tc26_gost3410_2012_256 OBJ_tc26,1L,1L,1L + +#define SN_id_tc26_gost3410_2012_512 "id-tc26-gost3410-2012-512" +#define LN_id_tc26_gost3410_2012_512 "GOST R 34.10-2012 (512 bit)" +#define NID_id_tc26_gost3410_2012_512 947 +#define OBJ_id_tc26_gost3410_2012_512 OBJ_tc26,1L,1L,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_256 "id-tc26-signwithdigest-gost3410-2012-256" +#define LN_id_tc26_signwithdigest_gost3410_2012_256 "GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_256 948 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_256 OBJ_tc26,1L,3L,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_512 "id-tc26-signwithdigest-gost3410-2012-512" +#define LN_id_tc26_signwithdigest_gost3410_2012_512 "GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_512 949 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_512 OBJ_tc26,1L,3L,3L + +#define SN_X25519 "X25519" +#define NID_X25519 950 +#define OBJ_X25519 1L,3L,101L,110L + +#define SN_X448 "X448" +#define NID_X448 951 +#define OBJ_X448 1L,3L,101L,111L + +#define SN_Ed25519 "Ed25519" +#define NID_Ed25519 952 +#define OBJ_Ed25519 1L,3L,101L,112L + +#define SN_Ed448 "Ed448" +#define NID_Ed448 953 +#define OBJ_Ed448 1L,3L,101L,113L + +#define SN_Ed25519ph "Ed25519ph" +#define NID_Ed25519ph 954 +#define OBJ_Ed25519ph 1L,3L,101L,114L + +#define SN_Ed448ph "Ed448ph" +#define NID_Ed448ph 955 +#define OBJ_Ed448ph 1L,3L,101L,115L + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 959 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 960 + +#define SN_kx_dhe "KxDHE" +#define LN_kx_dhe "kx-dhe" +#define NID_kx_dhe 961 + +#define SN_kx_gost "KxGOST" +#define LN_kx_gost "kx-gost" +#define NID_kx_gost 962 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 963 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 964 + +#define SN_auth_gost01 "AuthGOST01" +#define LN_auth_gost01 "auth-gost01" +#define NID_auth_gost01 965 + +#define SN_auth_null "AuthNULL" +#define LN_auth_null "auth-null" +#define NID_auth_null 966 + diff --git a/Libraries/libressl/include/openssl/objects.h b/Libraries/libressl/include/openssl/objects.h new file mode 100644 index 000000000..451545e05 --- /dev/null +++ b/Libraries/libressl/include/openssl/objects.h @@ -0,0 +1,163 @@ +/* $OpenBSD: objects.h,v 1.23 2023/07/28 10:25:05 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_OBJECTS_H +#define HEADER_OBJECTS_H + +#include + +#define SN_ED25519 SN_Ed25519 +#define NID_ED25519 NID_Ed25519 +#define OBJ_ED25519 OBJ_Ed25519 + +#include +#include + +#define OBJ_NAME_TYPE_UNDEF 0x00 +#define OBJ_NAME_TYPE_MD_METH 0x01 +#define OBJ_NAME_TYPE_CIPHER_METH 0x02 +#define OBJ_NAME_TYPE_PKEY_METH 0x03 +#define OBJ_NAME_TYPE_COMP_METH 0x04 +#define OBJ_NAME_TYPE_NUM 0x05 + +#define OBJ_NAME_ALIAS 0x8000 + +#define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +#define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), + int (*cmp_func)(const char *, const char *), + void (*free_func)(const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn)(const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, void (*fn)(const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT * OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT * OBJ_nid2obj(int n); +const char * OBJ_nid2ln(int n); +const char * OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT * OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); + +#if defined(LIBRESSL_INTERNAL) +const void * OBJ_bsearch_(const void *key, const void *base, int num, + int size, int (*cmp)(const void *, const void *)); +const void * OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, int (*cmp)(const void *, const void *), + int flags); +#endif + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +void OBJ_cleanup(void); +int OBJ_create_objects(BIO *in); + +size_t OBJ_length(const ASN1_OBJECT *obj); +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); + +void ERR_load_OBJ_strings(void); + +/* Error codes for the OBJ functions. */ + +/* Function codes. */ +#define OBJ_F_OBJ_ADD_OBJECT 105 +#define OBJ_F_OBJ_CREATE 100 +#define OBJ_F_OBJ_DUP 101 +#define OBJ_F_OBJ_NAME_NEW_INDEX 106 +#define OBJ_F_OBJ_NID2LN 102 +#define OBJ_F_OBJ_NID2OBJ 103 +#define OBJ_F_OBJ_NID2SN 104 + +/* Reason codes. */ +#define OBJ_R_MALLOC_FAILURE 100 +#define OBJ_R_UNKNOWN_NID 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ocsp.h b/Libraries/libressl/include/openssl/ocsp.h new file mode 100644 index 000000000..691ee4a3d --- /dev/null +++ b/Libraries/libressl/include/openssl/ocsp.h @@ -0,0 +1,484 @@ +/* $OpenBSD: ocsp.h,v 1.20 2022/07/12 14:42:49 kn Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was transfered to Richard Levitte from CertCo by Kathy + Weinhold in mid-spring 2000 to be included in OpenSSL or released + as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OCSP_H +#define HEADER_OCSP_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +#define OCSP_REVOKED_STATUS_NOSTATUS -1 +#define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +#define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +#define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +#define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +#define OCSP_REVOKED_STATUS_SUPERSEDED 4 +#define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +#define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +#define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + + +/* Various flags and values */ + +#define OCSP_DEFAULT_NONCE_LENGTH 16 + +#define OCSP_NOCERTS 0x1 +#define OCSP_NOINTERN 0x2 +#define OCSP_NOSIGS 0x4 +#define OCSP_NOCHAIN 0x8 +#define OCSP_NOVERIFY 0x10 +#define OCSP_NOEXPLICIT 0x20 +#define OCSP_NOCASIGN 0x40 +#define OCSP_NODELEGATED 0x80 +#define OCSP_NOCHECKS 0x100 +#define OCSP_TRUSTOTHER 0x200 +#define OCSP_RESPID_KEY 0x400 +#define OCSP_NOTIME 0x800 + +typedef struct ocsp_cert_id_st OCSP_CERTID; + +DECLARE_STACK_OF(OCSP_CERTID) + +typedef struct ocsp_one_request_st OCSP_ONEREQ; + +DECLARE_STACK_OF(OCSP_ONEREQ) + +typedef struct ocsp_req_info_st OCSP_REQINFO; +typedef struct ocsp_signature_st OCSP_SIGNATURE; +typedef struct ocsp_request_st OCSP_REQUEST; + +#define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +#define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +#define OCSP_RESPONSE_STATUS_TRYLATER 3 +#define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +#define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES; + +#define V_OCSP_RESPID_NAME 0 +#define V_OCSP_RESPID_KEY 1 + +DECLARE_STACK_OF(OCSP_RESPID) + +OCSP_RESPID *OCSP_RESPID_new(void); +void OCSP_RESPID_free(OCSP_RESPID *a); +OCSP_RESPID *d2i_OCSP_RESPID(OCSP_RESPID **a, const unsigned char **in, long len); +int i2d_OCSP_RESPID(OCSP_RESPID *a, unsigned char **out); +extern const ASN1_ITEM OCSP_RESPID_it; + +typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; + +#define V_OCSP_CERTSTATUS_GOOD 0 +#define V_OCSP_CERTSTATUS_REVOKED 1 +#define V_OCSP_CERTSTATUS_UNKNOWN 2 + +typedef struct ocsp_cert_status_st OCSP_CERTSTATUS; +typedef struct ocsp_single_response_st OCSP_SINGLERESP; + +DECLARE_STACK_OF(OCSP_SINGLERESP) + +typedef struct ocsp_response_data_st OCSP_RESPDATA; + +typedef struct ocsp_basic_response_st OCSP_BASICRESP; + +typedef struct ocsp_crl_id_st OCSP_CRLID; +typedef struct ocsp_service_locator_st OCSP_SERVICELOC; + +#define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +#define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +#define PEM_read_bio_OCSP_REQUEST(bp,x,cb) \ + (OCSP_REQUEST *)PEM_ASN1_read_bio((char *(*)())d2i_OCSP_REQUEST, \ + PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) + +#define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) \ + (OCSP_RESPONSE *)PEM_ASN1_read_bio((char *(*)())d2i_OCSP_RESPONSE, \ + PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) + +#define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +#define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +#define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(&ASN1_BIT_STRING_it,type,data,md,len) + +#define OCSP_CERTSTATUS_dup(cs) \ + ASN1_item_dup(&OCSP_CERTSTATUS_it, cs) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, const char *name, + const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, + const X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, const X509_NAME *issuerName, + const ASN1_BIT_STRING *issuerKey, const ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, X509 *signer, EVP_PKEY *key, + const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs); +const X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs); +const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, + STACK_OF(X509) *extra_certs); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP *bs); +const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, + const ASN1_OCTET_STRING **pid, const X509_NAME **pname); + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(const char *url, char **phost, char **pport, + char **ppath, int *pssl); + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, ASN1_INTEGER **pserial, + OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid, + int status, int reason, ASN1_TIME *revtime, ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, + const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags); + +X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char* tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, const char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, + const ASN1_OBJECT *obj, int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, + int loc); +const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x); + +OCSP_SINGLERESP *OCSP_SINGLERESP_new(void); +void OCSP_SINGLERESP_free(OCSP_SINGLERESP *a); +OCSP_SINGLERESP *d2i_OCSP_SINGLERESP(OCSP_SINGLERESP **a, const unsigned char **in, long len); +int i2d_OCSP_SINGLERESP(OCSP_SINGLERESP *a, unsigned char **out); +extern const ASN1_ITEM OCSP_SINGLERESP_it; +OCSP_CERTSTATUS *OCSP_CERTSTATUS_new(void); +void OCSP_CERTSTATUS_free(OCSP_CERTSTATUS *a); +OCSP_CERTSTATUS *d2i_OCSP_CERTSTATUS(OCSP_CERTSTATUS **a, const unsigned char **in, long len); +int i2d_OCSP_CERTSTATUS(OCSP_CERTSTATUS *a, unsigned char **out); +extern const ASN1_ITEM OCSP_CERTSTATUS_it; +OCSP_REVOKEDINFO *OCSP_REVOKEDINFO_new(void); +void OCSP_REVOKEDINFO_free(OCSP_REVOKEDINFO *a); +OCSP_REVOKEDINFO *d2i_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO **a, const unsigned char **in, long len); +int i2d_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO *a, unsigned char **out); +extern const ASN1_ITEM OCSP_REVOKEDINFO_it; +OCSP_BASICRESP *OCSP_BASICRESP_new(void); +void OCSP_BASICRESP_free(OCSP_BASICRESP *a); +OCSP_BASICRESP *d2i_OCSP_BASICRESP(OCSP_BASICRESP **a, const unsigned char **in, long len); +int i2d_OCSP_BASICRESP(OCSP_BASICRESP *a, unsigned char **out); +extern const ASN1_ITEM OCSP_BASICRESP_it; +OCSP_RESPDATA *OCSP_RESPDATA_new(void); +void OCSP_RESPDATA_free(OCSP_RESPDATA *a); +OCSP_RESPDATA *d2i_OCSP_RESPDATA(OCSP_RESPDATA **a, const unsigned char **in, long len); +int i2d_OCSP_RESPDATA(OCSP_RESPDATA *a, unsigned char **out); +extern const ASN1_ITEM OCSP_RESPDATA_it; +OCSP_RESPID *OCSP_RESPID_new(void); +void OCSP_RESPID_free(OCSP_RESPID *a); +OCSP_RESPID *d2i_OCSP_RESPID(OCSP_RESPID **a, const unsigned char **in, long len); +int i2d_OCSP_RESPID(OCSP_RESPID *a, unsigned char **out); +extern const ASN1_ITEM OCSP_RESPID_it; +OCSP_RESPONSE *OCSP_RESPONSE_new(void); +void OCSP_RESPONSE_free(OCSP_RESPONSE *a); +OCSP_RESPONSE *d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len); +int i2d_OCSP_RESPONSE(OCSP_RESPONSE *a, unsigned char **out); +OCSP_RESPONSE *d2i_OCSP_RESPONSE_bio(BIO *bp, OCSP_RESPONSE **a); +int i2d_OCSP_RESPONSE_bio(BIO *bp, OCSP_RESPONSE *a); +extern const ASN1_ITEM OCSP_RESPONSE_it; +OCSP_RESPBYTES *OCSP_RESPBYTES_new(void); +void OCSP_RESPBYTES_free(OCSP_RESPBYTES *a); +OCSP_RESPBYTES *d2i_OCSP_RESPBYTES(OCSP_RESPBYTES **a, const unsigned char **in, long len); +int i2d_OCSP_RESPBYTES(OCSP_RESPBYTES *a, unsigned char **out); +extern const ASN1_ITEM OCSP_RESPBYTES_it; +OCSP_ONEREQ *OCSP_ONEREQ_new(void); +void OCSP_ONEREQ_free(OCSP_ONEREQ *a); +OCSP_ONEREQ *d2i_OCSP_ONEREQ(OCSP_ONEREQ **a, const unsigned char **in, long len); +int i2d_OCSP_ONEREQ(OCSP_ONEREQ *a, unsigned char **out); +extern const ASN1_ITEM OCSP_ONEREQ_it; +OCSP_CERTID *OCSP_CERTID_new(void); +void OCSP_CERTID_free(OCSP_CERTID *a); +OCSP_CERTID *d2i_OCSP_CERTID(OCSP_CERTID **a, const unsigned char **in, long len); +int i2d_OCSP_CERTID(OCSP_CERTID *a, unsigned char **out); +extern const ASN1_ITEM OCSP_CERTID_it; +OCSP_REQUEST *OCSP_REQUEST_new(void); +void OCSP_REQUEST_free(OCSP_REQUEST *a); +OCSP_REQUEST *d2i_OCSP_REQUEST(OCSP_REQUEST **a, const unsigned char **in, long len); +int i2d_OCSP_REQUEST(OCSP_REQUEST *a, unsigned char **out); +OCSP_REQUEST *d2i_OCSP_REQUEST_bio(BIO *bp, OCSP_REQUEST **a); +int i2d_OCSP_REQUEST_bio(BIO *bp, OCSP_REQUEST *a); +extern const ASN1_ITEM OCSP_REQUEST_it; +OCSP_SIGNATURE *OCSP_SIGNATURE_new(void); +void OCSP_SIGNATURE_free(OCSP_SIGNATURE *a); +OCSP_SIGNATURE *d2i_OCSP_SIGNATURE(OCSP_SIGNATURE **a, const unsigned char **in, long len); +int i2d_OCSP_SIGNATURE(OCSP_SIGNATURE *a, unsigned char **out); +extern const ASN1_ITEM OCSP_SIGNATURE_it; +OCSP_REQINFO *OCSP_REQINFO_new(void); +void OCSP_REQINFO_free(OCSP_REQINFO *a); +OCSP_REQINFO *d2i_OCSP_REQINFO(OCSP_REQINFO **a, const unsigned char **in, long len); +int i2d_OCSP_REQINFO(OCSP_REQINFO *a, unsigned char **out); +extern const ASN1_ITEM OCSP_REQINFO_it; +OCSP_CRLID *OCSP_CRLID_new(void); +void OCSP_CRLID_free(OCSP_CRLID *a); +OCSP_CRLID *d2i_OCSP_CRLID(OCSP_CRLID **a, const unsigned char **in, long len); +int i2d_OCSP_CRLID(OCSP_CRLID *a, unsigned char **out); +extern const ASN1_ITEM OCSP_CRLID_it; +OCSP_SERVICELOC *OCSP_SERVICELOC_new(void); +void OCSP_SERVICELOC_free(OCSP_SERVICELOC *a); +OCSP_SERVICELOC *d2i_OCSP_SERVICELOC(OCSP_SERVICELOC **a, const unsigned char **in, long len); +int i2d_OCSP_SERVICELOC(OCSP_SERVICELOC *a, unsigned char **out); +extern const ASN1_ITEM OCSP_SERVICELOC_it; + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +void ERR_load_OCSP_strings(void); + +/* Error codes for the OCSP functions. */ + +/* Function codes. */ +#define OCSP_F_ASN1_STRING_ENCODE 100 +#define OCSP_F_D2I_OCSP_NONCE 102 +#define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +#define OCSP_F_OCSP_BASIC_SIGN 104 +#define OCSP_F_OCSP_BASIC_VERIFY 105 +#define OCSP_F_OCSP_CERT_ID_NEW 101 +#define OCSP_F_OCSP_CHECK_DELEGATED 106 +#define OCSP_F_OCSP_CHECK_IDS 107 +#define OCSP_F_OCSP_CHECK_ISSUER 108 +#define OCSP_F_OCSP_CHECK_VALIDITY 115 +#define OCSP_F_OCSP_MATCH_ISSUERID 109 +#define OCSP_F_OCSP_PARSE_URL 114 +#define OCSP_F_OCSP_REQUEST_SIGN 110 +#define OCSP_F_OCSP_REQUEST_VERIFY 116 +#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +#define OCSP_F_OCSP_SENDREQ_BIO 112 +#define OCSP_F_OCSP_SENDREQ_NBIO 117 +#define OCSP_F_PARSE_HTTP_LINE1 118 +#define OCSP_F_REQUEST_VERIFY 113 + +/* Reason codes. */ +#define OCSP_R_BAD_DATA 100 +#define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +#define OCSP_R_DIGEST_ERR 102 +#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +#define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +#define OCSP_R_ERROR_PARSING_URL 121 +#define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +#define OCSP_R_NOT_BASIC_RESPONSE 104 +#define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +#define OCSP_R_NO_CONTENT 106 +#define OCSP_R_NO_PUBLIC_KEY 107 +#define OCSP_R_NO_RESPONSE_DATA 108 +#define OCSP_R_NO_REVOKED_TIME 109 +#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +#define OCSP_R_REQUEST_NOT_SIGNED 128 +#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +#define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +#define OCSP_R_SERVER_READ_ERROR 113 +#define OCSP_R_SERVER_RESPONSE_ERROR 114 +#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +#define OCSP_R_SERVER_WRITE_ERROR 116 +#define OCSP_R_SIGNATURE_FAILURE 117 +#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +#define OCSP_R_STATUS_EXPIRED 125 +#define OCSP_R_STATUS_NOT_YET_VALID 126 +#define OCSP_R_STATUS_TOO_OLD 127 +#define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +#define OCSP_R_UNKNOWN_NID 120 +#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/opensslconf.h b/Libraries/libressl/include/openssl/opensslconf.h new file mode 100644 index 000000000..5cad089a8 --- /dev/null +++ b/Libraries/libressl/include/openssl/opensslconf.h @@ -0,0 +1,149 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependencies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very much CPU dependent */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/Libraries/libressl/include/openssl/opensslfeatures.h b/Libraries/libressl/include/openssl/opensslfeatures.h new file mode 100644 index 000000000..b00d7cf01 --- /dev/null +++ b/Libraries/libressl/include/openssl/opensslfeatures.h @@ -0,0 +1,133 @@ +/* $OpenBSD: opensslfeatures.h,v 1.41 2023/07/28 09:53:55 tb Exp $ */ +/* + * Feature flags for LibreSSL... so you can actually tell when things + * are enabled, rather than not being able to tell when things are + * enabled (or possibly not yet not implemented, or removed!). + */ +#define LIBRESSL_HAS_QUIC +#define LIBRESSL_HAS_TLS1_3 +#define LIBRESSL_HAS_DTLS1_2 + +/* + * Used for compatibility with compilers lacking __attribute__ + */ +#if defined(_MSC_VER) && !defined(__clang__) && !defined(__attribute__) +#define __attribute__(a) +#endif + +#define OPENSSL_THREADS + +#define OPENSSL_NO_BUF_FREELISTS +#define OPENSSL_NO_DEPRECATED +#define OPENSSL_NO_EC2M +#define OPENSSL_NO_GMP +#define OPENSSL_NO_JPAKE +#define OPENSSL_NO_KRB5 +#define OPENSSL_NO_RSAX +#define OPENSSL_NO_SHA0 +#define OPENSSL_NO_SSL2 +#define OPENSSL_NO_STORE + +/* + * OPENSSL_NO_* flags that currently appear in OpenSSL. + */ + +/* #define OPENSSL_NO_AFALGENG */ +/* #define OPENSSL_NO_ALGORITHMS */ +/* #define OPENSSL_NO_ARIA */ +/* #define OPENSSL_NO_ASM */ +#define OPENSSL_NO_ASYNC +/* #define OPENSSL_NO_AUTOALGINIT */ +/* #define OPENSSL_NO_AUTOERRINIT */ +/* #define OPENSSL_NO_AUTOLOAD_CONFIG */ +/* #define OPENSSL_NO_BF */ +/* #define OPENSSL_NO_BLAKE2 */ +/* #define OPENSSL_NO_CAMELLIA */ +/* #define OPENSSL_NO_CAPIENG */ +/* #define OPENSSL_NO_CAST */ +/* #define OPENSSL_NO_CHACHA */ +/* #define OPENSSL_NO_CMAC */ +/* #define OPENSSL_NO_CMS */ +#define OPENSSL_NO_COMP /* XXX */ +/* #define OPENSSL_NO_CRYPTO_MDEBUG */ +/* #define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE */ +/* #define OPENSSL_NO_CT */ +/* #define OPENSSL_NO_DECC_INIT */ +/* #define OPENSSL_NO_DES */ +/* #define OPENSSL_NO_DEVCRYPTOENG */ +/* #define OPENSSL_NO_DGRAM */ +/* #define OPENSSL_NO_DH */ +/* #define OPENSSL_NO_DSA */ +#define OPENSSL_NO_DSO +/* #define OPENSSL_NO_DTLS */ +#define OPENSSL_NO_DTLS1 +#ifndef LIBRESSL_HAS_DTLS1_2 +#define OPENSSL_NO_DTLS1_2 +#endif +/* #define OPENSSL_NO_DTLS1_2_METHOD */ +/* #define OPENSSL_NO_DTLS1_METHOD */ +#define OPENSSL_NO_DYNAMIC_ENGINE +/* #define OPENSSL_NO_EC */ +#define OPENSSL_NO_EC_NISTP_64_GCC_128 +#define OPENSSL_NO_EGD +#define OPENSSL_NO_ENGINE +/* #define OPENSSL_NO_ERR */ +/* #define OPENSSL_NO_FUZZ_AFL */ +/* #define OPENSSL_NO_FUZZ_LIBFUZZER */ +/* #define OPENSSL_NO_GOST */ +#define OPENSSL_NO_HEARTBEATS +/* #define OPENSSL_NO_HW */ +/* #define OPENSSL_NO_HW_PADLOCK */ +/* #define OPENSSL_NO_IDEA */ +/* #define OPENSSL_NO_INLINE_ASM */ +#define OPENSSL_NO_MD2 +/* #define OPENSSL_NO_MD4 */ +/* #define OPENSSL_NO_MD5 */ +#define OPENSSL_NO_MDC2 +/* #define OPENSSL_NO_MULTIBLOCK */ +/* #define OPENSSL_NO_NEXTPROTONEG */ +/* #define OPENSSL_NO_OCB */ +/* #define OPENSSL_NO_OCSP */ +/* #define OPENSSL_NO_PINSHARED */ +/* #define OPENSSL_NO_POLY1305 */ +/* #define OPENSSL_NO_POSIX_IO */ +#define OPENSSL_NO_PSK +/* #define OPENSSL_NO_RC2 */ +/* #define OPENSSL_NO_RC4 */ +#define OPENSSL_NO_RC5 +/* #define OPENSSL_NO_RDRAND */ +/* #define OPENSSL_NO_RFC3779 */ +/* #define OPENSSL_NO_RMD160 */ +/* #define OPENSSL_NO_RSA */ +/* #define OPENSSL_NO_SCRYPT */ +#define OPENSSL_NO_SCTP +/* #define OPENSSL_NO_SECURE_MEMORY */ +#define OPENSSL_NO_SEED +/* #define OPENSSL_NO_SIPHASH */ +/* #define OPENSSL_NO_SM2 */ +/* #define OPENSSL_NO_SM3 */ +/* #define OPENSSL_NO_SM4 */ +/* #define OPENSSL_NO_SOCK */ +#define OPENSSL_NO_SRP +/* #define OPENSSL_NO_SRTP */ +#define OPENSSL_NO_SSL3 +#define OPENSSL_NO_SSL3_METHOD +#define OPENSSL_NO_SSL_TRACE +/* #define OPENSSL_NO_STATIC_ENGINE */ +/* #define OPENSSL_NO_STDIO */ +/* #define OPENSSL_NO_TLS */ +#define OPENSSL_NO_TLS1 +#define OPENSSL_NO_TLS1_1 +#define OPENSSL_NO_TLS1_METHOD +#define OPENSSL_NO_TLS1_1_METHOD +/* #define OPENSSL_NO_TLS1_2 */ +/* #define OPENSSL_NO_TLS1_2_METHOD */ +#ifndef LIBRESSL_HAS_TLS1_3 +#define OPENSSL_NO_TLS1_3 +#endif +/* #define OPENSSL_NO_TLS1_METHOD */ +/* #define OPENSSL_NO_TS */ +/* #define OPENSSL_NO_UI_CONSOLE */ +/* #define OPENSSL_NO_UNIT_TEST */ +/* #define OPENSSL_NO_WEAK_SSL_CIPHERS */ +/* #define OPENSSL_NO_WHIRLPOOL */ diff --git a/Libraries/libressl/include/openssl/opensslv.h b/Libraries/libressl/include/openssl/opensslv.h new file mode 100644 index 000000000..d7ce60fd3 --- /dev/null +++ b/Libraries/libressl/include/openssl/opensslv.h @@ -0,0 +1,18 @@ +/* $OpenBSD: opensslv.h,v 1.77 2023/09/20 11:42:25 tb Exp $ */ +#ifndef HEADER_OPENSSLV_H +#define HEADER_OPENSSLV_H + +/* These will change with each release of LibreSSL-portable */ +#define LIBRESSL_VERSION_NUMBER 0x3080200fL +/* ^ Patch starts here */ +#define LIBRESSL_VERSION_TEXT "LibreSSL 3.8.2" + +/* These will never change */ +#define OPENSSL_VERSION_NUMBER 0x20000000L +#define OPENSSL_VERSION_TEXT LIBRESSL_VERSION_TEXT +#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +#define SHLIB_VERSION_HISTORY "" +#define SHLIB_VERSION_NUMBER "1.0.0" + +#endif /* HEADER_OPENSSLV_H */ diff --git a/Libraries/libressl/include/openssl/ossl_typ.h b/Libraries/libressl/include/openssl/ossl_typ.h new file mode 100644 index 000000000..4e0c51802 --- /dev/null +++ b/Libraries/libressl/include/openssl/ossl_typ.h @@ -0,0 +1,204 @@ +/* $OpenBSD: ossl_typ.h,v 1.30 2023/08/11 05:10:35 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OPENSSL_TYPES_H +#define HEADER_OPENSSL_TYPES_H + +#include + +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; + +typedef struct asn1_object_st ASN1_OBJECT; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; + +#if defined(_WIN32) && defined(__WINCRYPT_H__) +#if !defined(LIBRESSL_INTERNAL) && !defined(LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING) +#ifdef _MSC_VER +#pragma message("Warning, overriding WinCrypt defines") +#else +#warning overriding WinCrypt defines +#endif +#endif +#undef X509_NAME +#undef X509_CERT_PAIR +#undef X509_EXTENSIONS +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#undef PKCS7_ISSUER_AND_SERIAL +#endif + +#ifdef BIGNUM +#undef BIGNUM +#endif +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct bio_st BIO; +typedef struct buf_mem_st BUF_MEM; + +typedef struct comp_ctx_st COMP_CTX; +typedef struct comp_method_st COMP_METHOD; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_md_st EVP_MD; +typedef struct evp_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; + +typedef struct hmac_ctx_st HMAC_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct ec_key_st EC_KEY; +typedef struct ec_key_method_st EC_KEY_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_pss_params_st RSA_PSS_PARAMS; + +typedef struct rand_meth_st RAND_METHOD; + +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct x509_object_st X509_OBJECT; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; + +typedef struct store_st STORE; +typedef struct store_method_st STORE_METHOD; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + +/* If placed in pkcs12.h, we end up with a circular dependency with pkcs7.h */ +#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ +#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Callback types for crypto.h */ +typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +typedef struct sct_st SCT; +typedef struct sct_ctx_st SCT_CTX; +typedef struct ctlog_st CTLOG; +typedef struct ctlog_store_st CTLOG_STORE; +typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX; + +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/Libraries/libressl/include/openssl/pem.h b/Libraries/libressl/include/openssl/pem.h new file mode 100644 index 000000000..130acbccf --- /dev/null +++ b/Libraries/libressl/include/openssl/pem.h @@ -0,0 +1,596 @@ +/* $OpenBSD: pem.h,v 1.26 2023/04/25 17:51:36 tb Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PEM_H +#define HEADER_PEM_H + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_STACK +#include +#endif +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PEM_BUFSIZE 1024 + +#define PEM_OBJ_UNDEF 0 +#define PEM_OBJ_X509 1 +#define PEM_OBJ_X509_REQ 2 +#define PEM_OBJ_CRL 3 +#define PEM_OBJ_SSL_SESSION 4 +#define PEM_OBJ_PRIV_KEY 10 +#define PEM_OBJ_PRIV_RSA 11 +#define PEM_OBJ_PRIV_DSA 12 +#define PEM_OBJ_PRIV_DH 13 +#define PEM_OBJ_PUB_RSA 14 +#define PEM_OBJ_PUB_DSA 15 +#define PEM_OBJ_PUB_DH 16 +#define PEM_OBJ_DHPARAMS 17 +#define PEM_OBJ_DSAPARAMS 18 +#define PEM_OBJ_PRIV_RSA_PUBLIC 19 +#define PEM_OBJ_PRIV_ECDSA 20 +#define PEM_OBJ_PUB_ECDSA 21 +#define PEM_OBJ_ECPARAMETERS 22 + +#define PEM_ERROR 30 +#define PEM_DEK_DES_CBC 40 +#define PEM_DEK_IDEA_CBC 45 +#define PEM_DEK_DES_EDE 50 +#define PEM_DEK_DES_ECB 60 +#define PEM_DEK_RSA 70 +#define PEM_DEK_RSA_MD2 80 +#define PEM_DEK_RSA_MD5 90 + +#define PEM_MD_MD2 NID_md2 +#define PEM_MD_MD5 NID_md5 +#define PEM_MD_SHA NID_sha +#define PEM_MD_MD2_RSA NID_md2WithRSAEncryption +#define PEM_MD_MD5_RSA NID_md5WithRSAEncryption +#define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption + +#define PEM_STRING_X509_OLD "X509 CERTIFICATE" +#define PEM_STRING_X509 "CERTIFICATE" +#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +#define PEM_STRING_X509_CRL "X509 CRL" +#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +#define PEM_STRING_PUBLIC "PUBLIC KEY" +#define PEM_STRING_RSA "RSA PRIVATE KEY" +#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +#define PEM_STRING_DSA "DSA PRIVATE KEY" +#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +#define PEM_STRING_PKCS7 "PKCS7" +#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +#define PEM_STRING_PKCS8INF "PRIVATE KEY" +#define PEM_STRING_DHPARAMS "DH PARAMETERS" +#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +#define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +#define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_PARAMETERS "PARAMETERS" +#define PEM_STRING_CMS "CMS" + +/* enc_type is one off */ +#define PEM_TYPE_ENCRYPTED 10 +#define PEM_TYPE_MIC_ONLY 20 +#define PEM_TYPE_MIC_CLEAR 30 +#define PEM_TYPE_CLEAR 40 + +typedef struct pem_recip_st { + char *name; + X509_NAME *dn; + + int cipher; + int key_enc; + /* char iv[8]; unused and wrong size */ +} PEM_USER; + +typedef struct pem_ctx_st { + int type; /* what type of object */ + + struct { + int version; + int mode; + } proc_type; + + char *domain; + + struct { + int cipher; + /* unused, and wrong size + unsigned char iv[8]; */ + } DEK_info; + + PEM_USER *originator; + + int num_recipient; + PEM_USER **recipient; + + /* XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ + EVP_MD *md; /* signature type */ + + int md_enc; /* is the md encrypted or not? */ + int md_len; /* length of md_data */ + char *md_data; /* message digest, could be pkey encrypted */ + + EVP_CIPHER *dec; /* date encryption cipher */ + int key_len; /* key length */ + unsigned char *key; /* key */ + /* unused, and wrong size + unsigned char iv[8]; */ + + int data_enc; /* is the data encrypted */ + int data_len; + unsigned char *data; +} PEM_CTX; + +#ifndef LIBRESSL_INTERNAL +/* These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: + * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...) + */ + +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + + +#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +#endif + +/* These are the same except they are for the declarations */ + + +#define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +#define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +#define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + + +#ifndef OPENSSL_NO_BIO +#define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +#define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +#define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +#else + +#define DECLARE_PEM_read_bio(name, type) /**/ +#define DECLARE_PEM_write_bio(name, type) /**/ +#define DECLARE_PEM_write_bio_const(name, type) /**/ +#define DECLARE_PEM_write_cb_bio(name, type) /**/ + +#endif + +#define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) + +#define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) + +#define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) + +#define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) + +#define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) + +#define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) + +#define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) + +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +#ifndef OPENSSL_NO_BIO +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, void *u); +void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, + void **x, pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, + STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cd, void *u); +#endif + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); + +int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +int PEM_def_callback(char *buf, int num, int w, void *key); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + + +DECLARE_PEM_rw(X509, X509) + +DECLARE_PEM_rw(X509_AUX, X509) + +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) + +DECLARE_PEM_rw(X509_CRL, X509_CRL) + +DECLARE_PEM_rw(PKCS7, PKCS7) + +DECLARE_PEM_rw(PKCS8, X509_SIG) + +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +#ifndef OPENSSL_NO_RSA + +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) + +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) + +#endif + +#ifndef OPENSSL_NO_DSA + +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) + +DECLARE_PEM_rw(DSA_PUBKEY, DSA) + +DECLARE_PEM_rw_const(DSAparams, DSA) + +#endif + +#ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +#endif + +#ifndef OPENSSL_NO_DH + +DECLARE_PEM_rw_const(DHparams, DH) + +#endif + +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) + +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, + void *u); +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, void *u); + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +#ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, + void *u); +#endif + + +void ERR_load_PEM_strings(void); + +/* Error codes for the PEM functions. */ + +/* Function codes. */ +#define PEM_F_B2I_DSS 127 +#define PEM_F_B2I_PVK_BIO 128 +#define PEM_F_B2I_RSA 129 +#define PEM_F_CHECK_BITLEN_DSA 130 +#define PEM_F_CHECK_BITLEN_RSA 131 +#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +#define PEM_F_DO_B2I 132 +#define PEM_F_DO_B2I_BIO 133 +#define PEM_F_DO_BLOB_HEADER 134 +#define PEM_F_DO_PK8PKEY 126 +#define PEM_F_DO_PK8PKEY_FP 125 +#define PEM_F_DO_PVK_BODY 135 +#define PEM_F_DO_PVK_HEADER 136 +#define PEM_F_I2B_PVK 137 +#define PEM_F_I2B_PVK_BIO 138 +#define PEM_F_LOAD_IV 101 +#define PEM_F_PEM_ASN1_READ 102 +#define PEM_F_PEM_ASN1_READ_BIO 103 +#define PEM_F_PEM_ASN1_WRITE 104 +#define PEM_F_PEM_ASN1_WRITE_BIO 105 +#define PEM_F_PEM_DEF_CALLBACK 100 +#define PEM_F_PEM_DO_HEADER 106 +#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 +#define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +#define PEM_F_PEM_PK8PKEY 119 +#define PEM_F_PEM_READ 108 +#define PEM_F_PEM_READ_BIO 109 +#define PEM_F_PEM_READ_BIO_PARAMETERS 140 +#define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +#define PEM_F_PEM_READ_PRIVATEKEY 124 +#define PEM_F_PEM_SEALFINAL 110 +#define PEM_F_PEM_SEALINIT 111 +#define PEM_F_PEM_SIGNFINAL 112 +#define PEM_F_PEM_WRITE 113 +#define PEM_F_PEM_WRITE_BIO 114 +#define PEM_F_PEM_WRITE_PRIVATEKEY 139 +#define PEM_F_PEM_X509_INFO_READ 115 +#define PEM_F_PEM_X509_INFO_READ_BIO 116 +#define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* Reason codes. */ +#define PEM_R_BAD_BASE64_DECODE 100 +#define PEM_R_BAD_DECRYPT 101 +#define PEM_R_BAD_END_LINE 102 +#define PEM_R_BAD_IV_CHARS 103 +#define PEM_R_BAD_MAGIC_NUMBER 116 +#define PEM_R_BAD_PASSWORD_READ 104 +#define PEM_R_BAD_VERSION_NUMBER 117 +#define PEM_R_BIO_WRITE_FAILURE 118 +#define PEM_R_CIPHER_IS_NULL 127 +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +#define PEM_R_INCONSISTENT_HEADER 121 +#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +#define PEM_R_KEYBLOB_TOO_SHORT 123 +#define PEM_R_NOT_DEK_INFO 105 +#define PEM_R_NOT_ENCRYPTED 106 +#define PEM_R_NOT_PROC_TYPE 107 +#define PEM_R_NO_START_LINE 108 +#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +#define PEM_R_PUBLIC_KEY_NO_RSA 110 +#define PEM_R_PVK_DATA_TOO_SHORT 124 +#define PEM_R_PVK_TOO_SHORT 125 +#define PEM_R_READ_KEY 111 +#define PEM_R_SHORT_HEADER 112 +#define PEM_R_UNSUPPORTED_CIPHER 113 +#define PEM_R_UNSUPPORTED_ENCRYPTION 114 +#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/pem2.h b/Libraries/libressl/include/openssl/pem2.h new file mode 100644 index 000000000..19525b4a4 --- /dev/null +++ b/Libraries/libressl/include/openssl/pem2.h @@ -0,0 +1,71 @@ +/* $OpenBSD: pem2.h,v 1.5 2014/06/12 15:49:30 deraadt Exp $ */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This header only exists to break a circular dependency between pem and err + * Ben 30 Jan 1999. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HEADER_PEM_H +void ERR_load_PEM_strings(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/Libraries/libressl/include/openssl/pkcs12.h b/Libraries/libressl/include/openssl/pkcs12.h new file mode 100644 index 000000000..44dbb3815 --- /dev/null +++ b/Libraries/libressl/include/openssl/pkcs12.h @@ -0,0 +1,344 @@ +/* $OpenBSD: pkcs12.h,v 1.27 2022/09/11 17:30:13 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PKCS12_H +#define HEADER_PKCS12_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +/* Default iteration count */ +#ifndef PKCS12_DEFAULT_ITER +#define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +#endif + +#define PKCS12_MAC_KEY_LENGTH 20 + +#define PKCS12_SALT_LEN 8 + +/* Uncomment out next line for unicode password and names, otherwise ASCII */ + +/*#define PBE_UNICODE*/ + +#ifdef PBE_UNICODE +#define PKCS12_key_gen PKCS12_key_gen_uni +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni +#else +#define PKCS12_key_gen PKCS12_key_gen_asc +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc +#endif + +/* MS key usage constants */ + +#define KEY_EX 0x10 +#define KEY_SIG 0x80 + +typedef struct PKCS12_MAC_DATA_st PKCS12_MAC_DATA; + +typedef struct PKCS12_st PKCS12; + +typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG; + +DECLARE_STACK_OF(PKCS12_SAFEBAG) +DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st PKCS12_BAGS; + +#define PKCS12_ERROR 0 +#define PKCS12_OK 1 + +#ifndef LIBRESSL_INTERNAL + +/* Compatibility macros */ + +#define M_PKCS12_x5092certbag PKCS12_x5092certbag +#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag + +#define M_PKCS12_certbag2x509 PKCS12_certbag2x509 +#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl + +#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data +#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes +#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes +#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata + +#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey +#define M_PKCS8_decrypt PKCS8_decrypt + +#endif /* !LIBRESSL_INTERNAL */ + +#define M_PKCS12_bag_type PKCS12_bag_type +#define M_PKCS12_cert_bag_type PKCS12_cert_bag_type +#define M_PKCS12_crl_bag_type PKCS12_cert_bag_type + +#define PKCS12_bag_type PKCS12_SAFEBAG_get_nid +#define PKCS12_cert_bag_type PKCS12_SAFEBAG_get_bag_nid + +#define PKCS12_certbag2x509 PKCS12_SAFEBAG_get1_cert +#define PKCS12_certbag2x509crl PKCS12_SAFEBAG_get1_crl + +#define PKCS12_x5092certbag PKCS12_SAFEBAG_create_cert +#define PKCS12_x509crl2certbag PKCS12_SAFEBAG_create_crl +#define PKCS12_MAKE_KEYBAG PKCS12_SAFEBAG_create0_p8inf +#define PKCS12_MAKE_SHKEYBAG PKCS12_SAFEBAG_create_pkcs8_encrypt + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, + int attr_nid); +const STACK_OF(X509_ATTRIBUTE) * + PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); + +X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); + +ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid); +int PKCS12_mac_present(const PKCS12 *p12); +void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, const X509_ALGOR **pmacalg, + const ASN1_OCTET_STRING **psalt, const ASN1_INTEGER **piter, + const PKCS12 *p12); + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, + const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); + +const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); +const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); +const STACK_OF(PKCS12_SAFEBAG) * + PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, + int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, + int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, const char *pass, + int passlen, const unsigned char *in, int inlen, unsigned char **data, + int *datalen, int en_de); +void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, const ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, const char *pass, int passlen, void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, unsigned char *out, + const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, unsigned char *out, + const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md_type, + int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(const unsigned char *uni, int unilen); + +PKCS12 *PKCS12_new(void); +void PKCS12_free(PKCS12 *a); +PKCS12 *d2i_PKCS12(PKCS12 **a, const unsigned char **in, long len); +int i2d_PKCS12(PKCS12 *a, unsigned char **out); +extern const ASN1_ITEM PKCS12_it; +PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(void); +void PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a); +PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, const unsigned char **in, long len); +int i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **out); +extern const ASN1_ITEM PKCS12_MAC_DATA_it; +PKCS12_SAFEBAG *PKCS12_SAFEBAG_new(void); +void PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a); +PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, const unsigned char **in, long len); +int i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **out); +extern const ASN1_ITEM PKCS12_SAFEBAG_it; +PKCS12_BAGS *PKCS12_BAGS_new(void); +void PKCS12_BAGS_free(PKCS12_BAGS *a); +PKCS12_BAGS *d2i_PKCS12_BAGS(PKCS12_BAGS **a, const unsigned char **in, long len); +int i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **out); +extern const ASN1_ITEM PKCS12_BAGS_it; + +extern const ASN1_ITEM PKCS12_SAFEBAGS_it; +extern const ASN1_ITEM PKCS12_AUTHSAFES_it; + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key, + int key_usage, int iter, int key_nid, const char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, const char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); + +void ERR_load_PKCS12_strings(void); + +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +#define PKCS12_F_PARSE_BAG 129 +#define PKCS12_F_PARSE_BAGS 103 +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 +#define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +#define PKCS12_F_PKCS12_CREATE 105 +#define PKCS12_F_PKCS12_GEN_MAC 107 +#define PKCS12_F_PKCS12_INIT 109 +#define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +#define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +#define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +#define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +#define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +#define PKCS12_F_PKCS12_MAKE_KEYBAG 112 +#define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +#define PKCS12_F_PKCS12_NEWPASS 128 +#define PKCS12_F_PKCS12_PACK_P7DATA 114 +#define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +#define PKCS12_F_PKCS12_PARSE 118 +#define PKCS12_F_PKCS12_PBE_CRYPT 119 +#define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +#define PKCS12_F_PKCS12_SETUP_MAC 122 +#define PKCS12_F_PKCS12_SET_MAC 123 +#define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +#define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +#define PKCS12_F_PKCS12_VERIFY_MAC 126 +#define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +#define PKCS12_F_PKCS8_ENCRYPT 125 + +/* Reason codes. */ +#define PKCS12_R_CANT_PACK_STRUCTURE 100 +#define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +#define PKCS12_R_DECODE_ERROR 101 +#define PKCS12_R_ENCODE_ERROR 102 +#define PKCS12_R_ENCRYPT_ERROR 103 +#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +#define PKCS12_R_INVALID_NULL_ARGUMENT 104 +#define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +#define PKCS12_R_IV_GEN_ERROR 106 +#define PKCS12_R_KEY_GEN_ERROR 107 +#define PKCS12_R_MAC_ABSENT 108 +#define PKCS12_R_MAC_GENERATION_ERROR 109 +#define PKCS12_R_MAC_SETUP_ERROR 110 +#define PKCS12_R_MAC_STRING_SET_ERROR 111 +#define PKCS12_R_MAC_VERIFY_ERROR 112 +#define PKCS12_R_MAC_VERIFY_FAILURE 113 +#define PKCS12_R_PARSE_ERROR 114 +#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +#define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/pkcs7.h b/Libraries/libressl/include/openssl/pkcs7.h new file mode 100644 index 000000000..bea1a2096 --- /dev/null +++ b/Libraries/libressl/include/openssl/pkcs7.h @@ -0,0 +1,524 @@ +/* $OpenBSD: pkcs7.h,v 1.21 2023/04/25 18:04:03 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PKCS7_H +#define HEADER_PKCS7_H + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) && defined(__WINCRYPT_H__) +#if !defined(LIBRESSL_INTERNAL) && !defined(LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING) +#ifdef _MSC_VER +#pragma message("Warning, overriding WinCrypt defines") +#else +#warning overriding WinCrypt defines +#endif +#endif +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#endif + +/* +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DECLARE_STACK_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DECLARE_STACK_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE. + * How about merging the two */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* The following is non NULL if it contains ASN1 encoding of + * this structure */ + unsigned char *asn1; + long length; + +#define PKCS7_S_HEADER 0 +#define PKCS7_S_BODY 1 +#define PKCS7_S_TAIL 2 + int state; /* used during processing */ + + int detached; + + ASN1_OBJECT *type; + /* content as defined by the type */ + /* all encryption/message digests are applied to the 'contents', + * leaving out the 'type' field. */ + union { + char *ptr; + + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DECLARE_STACK_OF(PKCS7) +DECLARE_PKCS12_STACK_OF(PKCS7) + +#define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +#define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +#define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +#define PKCS7_get_attributes(si) ((si)->unauth_attr) + +#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +#define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) +#define PKCS7_type_is_encrypted(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) + +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +#define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +#define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +#define PKCS7_TEXT 0x1 +#define PKCS7_NOCERTS 0x2 +#define PKCS7_NOSIGS 0x4 +#define PKCS7_NOCHAIN 0x8 +#define PKCS7_NOINTERN 0x10 +#define PKCS7_NOVERIFY 0x20 +#define PKCS7_DETACHED 0x40 +#define PKCS7_BINARY 0x80 +#define PKCS7_NOATTR 0x100 +#define PKCS7_NOSMIMECAP 0x200 +#define PKCS7_NOOLDMIMETYPE 0x400 +#define PKCS7_CRLFEOL 0x800 +#define PKCS7_STREAM 0x1000 +#define PKCS7_NOCRL 0x2000 +#define PKCS7_PARTIAL 0x4000 +#define PKCS7_REUSE_DIGEST 0x8000 + +/* Flags: for compatibility with older code */ + +#define SMIME_TEXT PKCS7_TEXT +#define SMIME_NOCERTS PKCS7_NOCERTS +#define SMIME_NOSIGS PKCS7_NOSIGS +#define SMIME_NOCHAIN PKCS7_NOCHAIN +#define SMIME_NOINTERN PKCS7_NOINTERN +#define SMIME_NOVERIFY PKCS7_NOVERIFY +#define SMIME_DETACHED PKCS7_DETACHED +#define SMIME_BINARY PKCS7_BINARY +#define SMIME_NOATTR PKCS7_NOATTR + +PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void); +void PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a); +PKCS7_ISSUER_AND_SERIAL *d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len); +int i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it; + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, unsigned int *len); +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +PKCS7_SIGNER_INFO *PKCS7_SIGNER_INFO_new(void); +void PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a); +PKCS7_SIGNER_INFO *d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len); +int i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_SIGNER_INFO_it; +PKCS7_RECIP_INFO *PKCS7_RECIP_INFO_new(void); +void PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a); +PKCS7_RECIP_INFO *d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len); +int i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_RECIP_INFO_it; +PKCS7_SIGNED *PKCS7_SIGNED_new(void); +void PKCS7_SIGNED_free(PKCS7_SIGNED *a); +PKCS7_SIGNED *d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len); +int i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_SIGNED_it; +PKCS7_ENC_CONTENT *PKCS7_ENC_CONTENT_new(void); +void PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a); +PKCS7_ENC_CONTENT *d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len); +int i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_ENC_CONTENT_it; +PKCS7_ENVELOPE *PKCS7_ENVELOPE_new(void); +void PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a); +PKCS7_ENVELOPE *d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len); +int i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_ENVELOPE_it; +PKCS7_SIGN_ENVELOPE *PKCS7_SIGN_ENVELOPE_new(void); +void PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a); +PKCS7_SIGN_ENVELOPE *d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len); +int i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it; +PKCS7_DIGEST *PKCS7_DIGEST_new(void); +void PKCS7_DIGEST_free(PKCS7_DIGEST *a); +PKCS7_DIGEST *d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len); +int i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_DIGEST_it; +PKCS7_ENCRYPT *PKCS7_ENCRYPT_new(void); +void PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a); +PKCS7_ENCRYPT *d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len); +int i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_ENCRYPT_it; +PKCS7 *PKCS7_new(void); +void PKCS7_free(PKCS7 *a); +PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len); +int i2d_PKCS7(PKCS7 *a, unsigned char **out); +extern const ASN1_ITEM PKCS7_it; + +extern const ASN1_ITEM PKCS7_ATTR_SIGN_it; +extern const ASN1_ITEM PKCS7_ATTR_VERIFY_it; + +int PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx); + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk); + + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, + int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + + +void ERR_load_PKCS7_strings(void); + +/* Error codes for the PKCS7 functions. */ + +/* Function codes. */ +#define PKCS7_F_B64_READ_PKCS7 120 +#define PKCS7_F_B64_WRITE_PKCS7 121 +#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +#define PKCS7_F_PKCS7_ADD_CRL 101 +#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +#define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +#define PKCS7_F_PKCS7_ADD_SIGNER 103 +#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +#define PKCS7_F_PKCS7_CTRL 104 +#define PKCS7_F_PKCS7_DATADECODE 112 +#define PKCS7_F_PKCS7_DATAFINAL 128 +#define PKCS7_F_PKCS7_DATAINIT 105 +#define PKCS7_F_PKCS7_DATASIGN 106 +#define PKCS7_F_PKCS7_DATAVERIFY 107 +#define PKCS7_F_PKCS7_DECRYPT 114 +#define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +#define PKCS7_F_PKCS7_ENCODE_RINFO 132 +#define PKCS7_F_PKCS7_ENCRYPT 115 +#define PKCS7_F_PKCS7_FINAL 134 +#define PKCS7_F_PKCS7_FIND_DIGEST 127 +#define PKCS7_F_PKCS7_GET0_SIGNERS 124 +#define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +#define PKCS7_F_PKCS7_SET_CIPHER 108 +#define PKCS7_F_PKCS7_SET_CONTENT 109 +#define PKCS7_F_PKCS7_SET_DIGEST 126 +#define PKCS7_F_PKCS7_SET_TYPE 110 +#define PKCS7_F_PKCS7_SIGN 116 +#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +#define PKCS7_F_PKCS7_VERIFY 117 +#define PKCS7_F_SMIME_READ_PKCS7 122 +#define PKCS7_F_SMIME_TEXT 123 + +/* Reason codes. */ +#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +#define PKCS7_R_CTRL_ERROR 152 +#define PKCS7_R_DECODE_ERROR 130 +#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 +#define PKCS7_R_DECRYPT_ERROR 119 +#define PKCS7_R_DIGEST_FAILURE 101 +#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +#define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +#define PKCS7_R_ERROR_SETTING_CIPHER 121 +#define PKCS7_R_INVALID_MIME_TYPE 131 +#define PKCS7_R_INVALID_NULL_POINTER 143 +#define PKCS7_R_MIME_NO_CONTENT_TYPE 132 +#define PKCS7_R_MIME_PARSE_ERROR 133 +#define PKCS7_R_MIME_SIG_PARSE_ERROR 134 +#define PKCS7_R_MISSING_CERIPEND_INFO 103 +#define PKCS7_R_NO_CONTENT 122 +#define PKCS7_R_NO_CONTENT_TYPE 135 +#define PKCS7_R_NO_DEFAULT_DIGEST 151 +#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 +#define PKCS7_R_NO_MULTIPART_BOUNDARY 137 +#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 +#define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +#define PKCS7_R_NO_SIGNERS 142 +#define PKCS7_R_NO_SIG_CONTENT_TYPE 138 +#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +#define PKCS7_R_PKCS7_DATAFINAL 126 +#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 +#define PKCS7_R_PKCS7_DATASIGN 145 +#define PKCS7_R_PKCS7_PARSE_ERROR 139 +#define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 +#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +#define PKCS7_R_SIGNATURE_FAILURE 105 +#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +#define PKCS7_R_SIGNING_CTRL_FAILURE 147 +#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +#define PKCS7_R_SIG_INVALID_MIME_TYPE 141 +#define PKCS7_R_SMIME_TEXT_ERROR 129 +#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +#define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +#define PKCS7_R_UNKNOWN_OPERATION 110 +#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +#define PKCS7_R_WRONG_CONTENT_TYPE 113 +#define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/poly1305.h b/Libraries/libressl/include/openssl/poly1305.h new file mode 100644 index 000000000..00ab0bfd2 --- /dev/null +++ b/Libraries/libressl/include/openssl/poly1305.h @@ -0,0 +1,49 @@ +/* $OpenBSD: poly1305.h,v 1.3 2014/07/25 14:04:51 jsing Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_POLY1305_H +#define HEADER_POLY1305_H + +#include + +#if defined(OPENSSL_NO_POLY1305) +#error Poly1305 is disabled. +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct poly1305_context { + size_t aligner; + unsigned char opaque[136]; +} poly1305_context; + +typedef struct poly1305_context poly1305_state; + +void CRYPTO_poly1305_init(poly1305_context *ctx, const unsigned char key[32]); +void CRYPTO_poly1305_update(poly1305_context *ctx, const unsigned char *in, + size_t len); +void CRYPTO_poly1305_finish(poly1305_context *ctx, unsigned char mac[16]); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_POLY1305_H */ diff --git a/Libraries/libressl/include/openssl/rand.h b/Libraries/libressl/include/openssl/rand.h new file mode 100644 index 000000000..a0e9b4796 --- /dev/null +++ b/Libraries/libressl/include/openssl/rand.h @@ -0,0 +1,123 @@ +/* $OpenBSD: rand.h,v 1.23 2022/07/12 14:42:50 kn Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_RAND_H +#define HEADER_RAND_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct rand_meth_st RAND_METHOD; */ + +struct rand_meth_st { + void (*seed)(const void *buf, int num); + int (*bytes)(unsigned char *buf, int num); + void (*cleanup)(void); + void (*add)(const void *buf, int num, double entropy); + int (*pseudorand)(unsigned char *buf, int num); + int (*status)(void); +}; + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +#ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +#endif +RAND_METHOD *RAND_SSLeay(void); + +#ifndef LIBRESSL_INTERNAL +void RAND_cleanup(void ); +int RAND_bytes(unsigned char *buf, int num); +int RAND_pseudo_bytes(unsigned char *buf, int num); +void RAND_seed(const void *buf, int num); +void RAND_add(const void *buf, int num, double entropy); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); +int RAND_poll(void); +#endif + +void ERR_load_RAND_strings(void); + +/* Error codes for the RAND functions. (no longer used) */ + +/* Function codes. */ +#define RAND_F_RAND_GET_RAND_METHOD 101 +#define RAND_F_RAND_INIT_FIPS 102 +#define RAND_F_SSLEAY_RAND_BYTES 100 + +/* Reason codes. */ +#define RAND_R_DUAL_EC_DRBG_DISABLED 104 +#define RAND_R_ERROR_INITIALISING_DRBG 102 +#define RAND_R_ERROR_INSTANTIATING_DRBG 103 +#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +#define RAND_R_PRNG_NOT_SEEDED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/rc2.h b/Libraries/libressl/include/openssl/rc2.h new file mode 100644 index 000000000..09c6c08a5 --- /dev/null +++ b/Libraries/libressl/include/openssl/rc2.h @@ -0,0 +1,100 @@ +/* $OpenBSD: rc2.h,v 1.12 2023/07/07 08:29:37 beck Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC2_H +#define HEADER_RC2_H + +#include /* OPENSSL_NO_RC2, RC2_INT */ + +#ifdef OPENSSL_NO_RC2 +#error RC2 is disabled. +#endif + +#define RC2_ENCRYPT 1 +#define RC2_DECRYPT 0 + +#define RC2_BLOCK 8 +#define RC2_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *key, + int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/rc4.h b/Libraries/libressl/include/openssl/rc4.h new file mode 100644 index 000000000..7ebe23210 --- /dev/null +++ b/Libraries/libressl/include/openssl/rc4.h @@ -0,0 +1,88 @@ +/* $OpenBSD: rc4.h,v 1.14 2023/07/28 10:35:14 tb Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +#define HEADER_RC4_H + +#include /* OPENSSL_NO_RC4, RC4_INT */ + +#ifdef OPENSSL_NO_RC4 +#error RC4 is disabled. +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/ripemd.h b/Libraries/libressl/include/openssl/ripemd.h new file mode 100644 index 000000000..03ba781c4 --- /dev/null +++ b/Libraries/libressl/include/openssl/ripemd.h @@ -0,0 +1,104 @@ +/* $OpenBSD: ripemd.h,v 1.15 2023/07/08 06:52:56 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_RIPEMD_H +#define HEADER_RIPEMD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_RIPEMD +#error RIPEMD is disabled. +#endif + +#if defined(__LP32__) +#define RIPEMD160_LONG unsigned long +#elif defined(__ILP64__) +#define RIPEMD160_LONG unsigned long +#define RIPEMD160_LONG_LOG2 3 +#else +#define RIPEMD160_LONG unsigned int +#endif + +#define RIPEMD160_CBLOCK 64 +#define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +#define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B,C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, + unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/rsa.h b/Libraries/libressl/include/openssl/rsa.h new file mode 100644 index 000000000..4fcef3a97 --- /dev/null +++ b/Libraries/libressl/include/openssl/rsa.h @@ -0,0 +1,609 @@ +/* $OpenBSD: rsa.h,v 1.65 2023/07/28 10:05:16 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RSA_H +#define HEADER_RSA_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#include + +#ifdef OPENSSL_NO_RSA +#error RSA is disabled. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; + + /* Hash algorithm decoded from maskGenAlgorithm. */ + X509_ALGOR *maskHash; +} /* RSA_PSS_PARAMS */; + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; + + /* Hash algorithm decoded from maskGenFunc. */ + X509_ALGOR *maskHash; +} RSA_OAEP_PARAMS; + +#ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +#endif + +#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +#endif +#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */ +#endif + +#define RSA_3 0x3L +#define RSA_F4 0x10001L + +/* Don't check pub/private match. */ +#define RSA_METHOD_FLAG_NO_CHECK 0x0001 + +#define RSA_FLAG_CACHE_PUBLIC 0x0002 +#define RSA_FLAG_CACHE_PRIVATE 0x0004 +#define RSA_FLAG_BLINDING 0x0008 +#define RSA_FLAG_THREAD_SAFE 0x0010 + +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag bn_mod_exp + * gets called when private key components are absent. + */ +#define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions. + */ +#define RSA_FLAG_SIGN_VER 0x0040 + +/* + * The built-in RSA implementation uses blinding by default, but other engines + * might not need it. + */ +#define RSA_FLAG_NO_BLINDING 0x0080 + +/* Salt length matches digest */ +#define RSA_PSS_SALTLEN_DIGEST -1 +/* Verify only: auto detect salt length */ +#define RSA_PSS_SALTLEN_AUTO -2 +/* Set salt length to maximum possible */ +#define RSA_PSS_SALTLEN_MAX -3 + +#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL) + +#define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) + +#define EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) + +#define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, plen) + +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +#define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +#define EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +#define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)) + +#define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(pmd)) + +#define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)(pmd)) + +#define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)(l)) + +#define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)(l)) + +#define EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, \ + EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, 0, (void *)(md)) + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +#define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +#define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +#define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +#define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +#define RSA_PKCS1_PADDING 1 +#define RSA_SSLV23_PADDING 2 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_OAEP_PADDING 4 +/* rust-openssl and erlang expose this and salt even uses it. */ +#define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +#define RSA_PKCS1_PSS_PADDING 6 + +#define RSA_PKCS1_PADDING_SIZE 11 + +#define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +#define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_bits(const RSA *rsa); +int RSA_size(const RSA *rsa); + +/* + * Wrapped in OPENSSL_NO_DEPRECATED in 0.9.8. Still used for libressl bindings + * in rust-openssl. + */ +RSA *RSA_generate_key(int bits, unsigned long e, + void (*callback)(int, int, void *), void *cb_arg); + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + +int RSA_check_key(const RSA *); +/* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +const RSA_METHOD *RSA_PKCS1_OpenSSL(void); +const RSA_METHOD *RSA_PKCS1_SSLeay(void); + +const RSA_METHOD *RSA_null_method(void); + +int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2); + +RSA *d2i_RSAPublicKey(RSA **a, const unsigned char **in, long len); +int i2d_RSAPublicKey(const RSA *a, unsigned char **out); +extern const ASN1_ITEM RSAPublicKey_it; +RSA *d2i_RSAPrivateKey(RSA **a, const unsigned char **in, long len); +int i2d_RSAPrivateKey(const RSA *a, unsigned char **out); +extern const ASN1_ITEM RSAPrivateKey_it; + +RSA_PSS_PARAMS *RSA_PSS_PARAMS_new(void); +void RSA_PSS_PARAMS_free(RSA_PSS_PARAMS *a); +RSA_PSS_PARAMS *d2i_RSA_PSS_PARAMS(RSA_PSS_PARAMS **a, const unsigned char **in, long len); +int i2d_RSA_PSS_PARAMS(RSA_PSS_PARAMS *a, unsigned char **out); +extern const ASN1_ITEM RSA_PSS_PARAMS_it; + +RSA_OAEP_PARAMS *RSA_OAEP_PARAMS_new(void); +void RSA_OAEP_PARAMS_free(RSA_OAEP_PARAMS *a); +RSA_OAEP_PARAMS *d2i_RSA_OAEP_PARAMS(RSA_OAEP_PARAMS **a, const unsigned char **in, long len); +int i2d_RSA_OAEP_PARAMS(RSA_OAEP_PARAMS *a, unsigned char **out); +extern const ASN1_ITEM RSA_OAEP_PARAMS_it; + +int RSA_print_fp(FILE *fp, const RSA *r, int offset); + +#ifndef OPENSSL_NO_BIO +int RSA_print(BIO *bp, const RSA *r, int offset); +#endif + +/* The following 2 functions sign and verify a X509_SIG ASN1 object + * inside PKCS#1 padded RSA encryption */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* The following 2 function sign and verify a ASN1_OCTET_STRING + * object inside PKCS#1 padded RSA encryption */ +int RSA_sign_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, unsigned int siglen, + RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num, const unsigned char *param, + int plen, const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_add_none(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, const unsigned char *EM, + int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +int RSA_security_bits(const RSA *rsa); + +void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, + const BIGNUM **d); +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp); +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +const BIGNUM *RSA_get0_n(const RSA *r); +const BIGNUM *RSA_get0_e(const RSA *r); +const BIGNUM *RSA_get0_d(const RSA *r); +const BIGNUM *RSA_get0_p(const RSA *r); +const BIGNUM *RSA_get0_q(const RSA *r); +const BIGNUM *RSA_get0_dmp1(const RSA *r); +const BIGNUM *RSA_get0_dmq1(const RSA *r); +const BIGNUM *RSA_get0_iqmp(const RSA *r); +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r); +void RSA_clear_flags(RSA *r, int flags); +int RSA_test_flags(const RSA *r, int flags); +void RSA_set_flags(RSA *r, int flags); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* If this flag is set the RSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its responsibility + * to ensure the result is compliant. + */ + +#define RSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* Application has decided PRNG is good enough to generate a key: don't + * check. + */ +#define RSA_FLAG_CHECKED 0x0800 + +RSA_METHOD *RSA_meth_new(const char *name, int flags); +void RSA_meth_free(RSA_METHOD *meth); +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); +int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); +int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); +int (*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa); +int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa)); +int RSA_meth_set_pub_enc(RSA_METHOD *meth, int (*pub_enc)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); +int RSA_meth_set_pub_dec(RSA_METHOD *meth, int (*pub_dec)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); +int RSA_meth_set_mod_exp(RSA_METHOD *meth, int (*mod_exp)(BIGNUM *r0, + const BIGNUM *i, RSA *rsa, BN_CTX *ctx)); +int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, int (*bn_mod_exp)(BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx)); +int RSA_meth_set_init(RSA_METHOD *meth, int (*init)(RSA *rsa)); +int RSA_meth_set_keygen(RSA_METHOD *meth, int (*keygen)(RSA *rsa, int bits, + BIGNUM *e, BN_GENCB *cb)); +int RSA_meth_set_flags(RSA_METHOD *meth, int flags); +int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data); +const char *RSA_meth_get0_name(const RSA_METHOD *); +int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth))(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth))(BIGNUM *r0, const BIGNUM *i, + RSA *rsa, BN_CTX *ctx); +int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))(BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +int (*RSA_meth_get_init(const RSA_METHOD *meth))(RSA *rsa); +int (*RSA_meth_get_keygen(const RSA_METHOD *meth))(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb); +int RSA_meth_get_flags(const RSA_METHOD *meth); +void *RSA_meth_get0_app_data(const RSA_METHOD *meth); +int (*RSA_meth_get_sign(const RSA_METHOD *meth))(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); +int RSA_meth_set_sign(RSA_METHOD *rsa, int (*sign)(int type, + const unsigned char *m, unsigned int m_length, unsigned char *sigret, + unsigned int *siglen, const RSA *rsa)); +int (*RSA_meth_get_verify(const RSA_METHOD *meth))(int dtype, + const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); +int RSA_meth_set_verify(RSA_METHOD *rsa, int (*verify)(int dtype, + const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)); + + +void ERR_load_RSA_strings(void); + +/* Error codes for the RSA functions. */ + +/* Function codes. */ +#define RSA_F_CHECK_PADDING_MD 140 +#define RSA_F_DO_RSA_PRINT 146 +#define RSA_F_INT_RSA_VERIFY 145 +#define RSA_F_MEMORY_LOCK 100 +#define RSA_F_OLD_RSA_PRIV_DECODE 147 +#define RSA_F_PKEY_RSA_CTRL 143 +#define RSA_F_PKEY_RSA_CTRL_STR 144 +#define RSA_F_PKEY_RSA_SIGN 142 +#define RSA_F_PKEY_RSA_VERIFY 154 +#define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +#define RSA_F_RSA_BUILTIN_KEYGEN 129 +#define RSA_F_RSA_CHECK_KEY 123 +#define RSA_F_RSA_EAY_MOD_EXP 157 +#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 +#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 +#define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 +#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 +#define RSA_F_RSA_GENERATE_KEY 105 +#define RSA_F_RSA_GENERATE_KEY_EX 155 +#define RSA_F_RSA_ITEM_VERIFY 156 +#define RSA_F_RSA_MEMORY_LOCK 130 +#define RSA_F_RSA_NEW_METHOD 106 +#define RSA_F_RSA_NULL 124 +#define RSA_F_RSA_NULL_MOD_EXP 131 +#define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +#define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +#define RSA_F_RSA_PADDING_ADD_NONE 107 +#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +#define RSA_F_RSA_PADDING_ADD_X931 127 +#define RSA_F_RSA_PADDING_CHECK_NONE 111 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +#define RSA_F_RSA_PADDING_CHECK_X931 128 +#define RSA_F_RSA_PRINT 115 +#define RSA_F_RSA_PRINT_FP 116 +#define RSA_F_RSA_PRIVATE_DECRYPT 150 +#define RSA_F_RSA_PRIVATE_ENCRYPT 151 +#define RSA_F_RSA_PRIV_DECODE 137 +#define RSA_F_RSA_PRIV_ENCODE 138 +#define RSA_F_RSA_PUBLIC_DECRYPT 152 +#define RSA_F_RSA_PUBLIC_ENCRYPT 153 +#define RSA_F_RSA_PUB_DECODE 139 +#define RSA_F_RSA_SETUP_BLINDING 136 +#define RSA_F_RSA_SIGN 117 +#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +#define RSA_F_RSA_VERIFY 119 +#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +#define RSA_F_RSA_VERIFY_PKCS1_PSS 126 +#define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 + +/* Reason codes. */ +#define RSA_R_ALGORITHM_MISMATCH 100 +#define RSA_R_BAD_E_VALUE 101 +#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +#define RSA_R_BAD_PAD_BYTE_COUNT 103 +#define RSA_R_BAD_SIGNATURE 104 +#define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +#define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +#define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +#define RSA_R_DATA_TOO_LARGE 109 +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +#define RSA_R_DATA_TOO_SMALL 111 +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +#define RSA_R_DIGEST_DOES_NOT_MATCH 158 +#define RSA_R_DIGEST_NOT_ALLOWED 145 +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +#define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +#define RSA_R_FIRST_OCTET_INVALID 133 +#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +#define RSA_R_INVALID_DIGEST 157 +#define RSA_R_INVALID_DIGEST_LENGTH 143 +#define RSA_R_INVALID_HEADER 137 +#define RSA_R_INVALID_KEYBITS 145 +#define RSA_R_INVALID_LABEL 160 +#define RSA_R_INVALID_MESSAGE_LENGTH 131 +#define RSA_R_INVALID_MGF1_MD 156 +#define RSA_R_INVALID_OAEP_PARAMETERS 161 +#define RSA_R_INVALID_PADDING 138 +#define RSA_R_INVALID_PADDING_MODE 141 +#define RSA_R_INVALID_PSS_PARAMETERS 149 +#define RSA_R_INVALID_PSS_SALTLEN 146 +#define RSA_R_INVALID_SALT_LENGTH 150 +#define RSA_R_INVALID_TRAILER 139 +#define RSA_R_INVALID_X931_DIGEST 142 +#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +#define RSA_R_KEY_SIZE_TOO_SMALL 120 +#define RSA_R_LAST_OCTET_INVALID 134 +#define RSA_R_MODULUS_TOO_LARGE 105 +#define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 +#define RSA_R_NON_FIPS_RSA_METHOD 157 +#define RSA_R_NO_PUBLIC_EXPONENT 140 +#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +#define RSA_R_OAEP_DECODING_ERROR 121 +#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +#define RSA_R_PADDING_CHECK_FAILED 114 +#define RSA_R_PSS_SALTLEN_TOO_SMALL 164 +#define RSA_R_P_NOT_PRIME 128 +#define RSA_R_Q_NOT_PRIME 129 +#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +#define RSA_R_SLEN_CHECK_FAILED 136 +#define RSA_R_SLEN_RECOVERY_FAILED 135 +#define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +#define RSA_R_UNKNOWN_DIGEST 166 +#define RSA_R_UNKNOWN_MASK_DIGEST 151 +#define RSA_R_UNKNOWN_PADDING_TYPE 118 +#define RSA_R_UNKNOWN_PSS_DIGEST 152 +#define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 162 +#define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 +#define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +#define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +#define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +#define RSA_R_VALUE_MISSING 147 +#define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/safestack.h b/Libraries/libressl/include/openssl/safestack.h new file mode 100644 index 000000000..4f575ba94 --- /dev/null +++ b/Libraries/libressl/include/openssl/safestack.h @@ -0,0 +1,1971 @@ +/* $OpenBSD: safestack.h,v 1.29 2023/08/03 16:32:15 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SAFESTACK_H +#define HEADER_SAFESTACK_H + +#include + +#ifndef CHECKED_PTR_OF +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#endif + +/* In C++ we get problems because an explicit cast is needed from (void *) + * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +#define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + +#define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +#define CHECKED_SK_FREE_FUNC2(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type))0))) + +#define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const void *, const void *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + +#define STACK_OF(type) struct stack_st_##type +#define PREDECLARE_STACK_OF(type) STACK_OF(type); + +#define DECLARE_STACK_OF(type) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; +#define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; + +#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/ + + +/* Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * +o * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as + * mentioned above, instead of a single char each entry is a + * NUL-terminated array of chars. So, we have to implement STRING + * specially for STACK_OF. This is dealt with in the autogenerated + * macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* SKM_sk_... stack macros are internal to safestack.h: + * never use them directly, use sk__... instead */ +#define SKM_sk_new(type, cmp) \ + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) +#define SKM_sk_new_null(type) \ + ((STACK_OF(type) *)sk_new_null()) +#define SKM_sk_free(type, st) \ + sk_free(CHECKED_STACK_OF(type, st)) +#define SKM_sk_num(type, st) \ + sk_num(CHECKED_STACK_OF(type, st)) +#define SKM_sk_value(type, st,i) \ + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) +#define SKM_sk_set(type, st,i,val) \ + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) +#define SKM_sk_zero(type, st) \ + sk_zero(CHECKED_STACK_OF(type, st)) +#define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +#define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +#define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +#define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +#define SKM_sk_set_cmp_func(type, st, cmp) \ + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) +#define SKM_sk_dup(type, st) \ + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +#define SKM_sk_shift(type, st) \ + (type *)sk_shift(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop(type, st) \ + (type *)sk_pop(CHECKED_STACK_OF(type, st)) +#define SKM_sk_sort(type, st) \ + sk_sort(CHECKED_STACK_OF(type, st)) +#define SKM_sk_is_sorted(type, st) \ + sk_is_sorted(CHECKED_STACK_OF(type, st)) + +#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) +#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) +#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) +#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) +#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) +#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) +#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) +#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) +#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) +#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) +#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) + +#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) +#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) +#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) +#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) +#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) +#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) +#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) +#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) +#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) +#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) +#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) +#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) +#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) +#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) +#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) +#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) +#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) + +#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) +#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) +#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) +#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) +#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) +#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) +#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) +#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) +#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) +#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) +#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) + +#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) +#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) +#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) +#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) +#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) +#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) +#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) +#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) +#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) +#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) +#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) + +#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) +#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) +#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) +#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) +#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) +#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) +#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) +#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) +#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) +#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) +#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) + +#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) +#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) +#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) +#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) +#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) +#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) +#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) +#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) +#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) +#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) +#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) + +#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) +#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) +#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) +#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) +#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) +#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) +#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) +#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) +#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) +#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) +#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) + +#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) + +#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) +#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) +#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) +#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) +#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) +#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) +#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) +#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) +#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) +#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) +#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) + +#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) +#define sk_BIO_new_null() SKM_sk_new_null(BIO) +#define sk_BIO_free(st) SKM_sk_free(BIO, (st)) +#define sk_BIO_num(st) SKM_sk_num(BIO, (st)) +#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) +#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) +#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) +#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) +#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) +#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) +#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) +#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) +#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) +#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) +#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) +#define sk_BIO_dup(st) SKM_sk_dup(BIO, st) +#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) +#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) +#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) +#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) +#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) + +#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) + +#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) + +#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) +#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) +#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) +#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) +#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) +#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) +#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) +#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) +#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) +#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) +#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) + +#define sk_CMS_RecipientEncryptedKey_new(cmp) SKM_sk_new(CMS_RecipientEncryptedKey, (cmp)) +#define sk_CMS_RecipientEncryptedKey_new_null() SKM_sk_new_null(CMS_RecipientEncryptedKey) +#define sk_CMS_RecipientEncryptedKey_free(st) SKM_sk_free(CMS_RecipientEncryptedKey, (st)) +#define sk_CMS_RecipientEncryptedKey_num(st) SKM_sk_num(CMS_RecipientEncryptedKey, (st)) +#define sk_CMS_RecipientEncryptedKey_value(st, i) SKM_sk_value(CMS_RecipientEncryptedKey, (st), (i)) +#define sk_CMS_RecipientEncryptedKey_set(st, i, val) SKM_sk_set(CMS_RecipientEncryptedKey, (st), (i), (val)) +#define sk_CMS_RecipientEncryptedKey_zero(st) SKM_sk_zero(CMS_RecipientEncryptedKey, (st)) +#define sk_CMS_RecipientEncryptedKey_push(st, val) SKM_sk_push(CMS_RecipientEncryptedKey, (st), (val)) +#define sk_CMS_RecipientEncryptedKey_unshift(st, val) SKM_sk_unshift(CMS_RecipientEncryptedKey, (st), (val)) +#define sk_CMS_RecipientEncryptedKey_find(st, val) SKM_sk_find(CMS_RecipientEncryptedKey, (st), (val)) +#define sk_CMS_RecipientEncryptedKey_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientEncryptedKey, (st), (val)) +#define sk_CMS_RecipientEncryptedKey_delete(st, i) SKM_sk_delete(CMS_RecipientEncryptedKey, (st), (i)) +#define sk_CMS_RecipientEncryptedKey_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientEncryptedKey, (st), (ptr)) +#define sk_CMS_RecipientEncryptedKey_insert(st, val, i) SKM_sk_insert(CMS_RecipientEncryptedKey, (st), (val), (i)) +#define sk_CMS_RecipientEncryptedKey_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientEncryptedKey, (st), (cmp)) +#define sk_CMS_RecipientEncryptedKey_dup(st) SKM_sk_dup(CMS_RecipientEncryptedKey, st) +#define sk_CMS_RecipientEncryptedKey_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientEncryptedKey, (st), (free_func)) +#define sk_CMS_RecipientEncryptedKey_shift(st) SKM_sk_shift(CMS_RecipientEncryptedKey, (st)) +#define sk_CMS_RecipientEncryptedKey_pop(st) SKM_sk_pop(CMS_RecipientEncryptedKey, (st)) +#define sk_CMS_RecipientEncryptedKey_sort(st) SKM_sk_sort(CMS_RecipientEncryptedKey, (st)) +#define sk_CMS_RecipientEncryptedKey_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientEncryptedKey, (st)) + +#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) +#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) +#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) +#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) +#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) +#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) +#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) +#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) +#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) +#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) +#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) + +#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) +#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) +#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) +#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) +#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) +#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) +#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) +#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) +#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) +#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) +#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) + +#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) +#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) +#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) +#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) +#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) +#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) +#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) +#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) +#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) +#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) +#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) + +#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) +#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) +#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) +#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) +#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) +#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) +#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) +#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) +#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) +#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) +#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) + +#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) +#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) +#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) +#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) +#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) +#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) +#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) +#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) +#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) +#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) +#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) +#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) +#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) +#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) +#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) +#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) +#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) + +#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) +#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) +#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) +#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) +#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) +#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) +#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) +#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) +#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) +#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) +#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) +#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) +#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) +#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) +#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) +#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) +#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) + +#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) +#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) +#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) +#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) +#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) +#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) +#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) +#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) +#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) +#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) +#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) + +#define sk_CTLOG_new(cmp) SKM_sk_new(CTLOG, (cmp)) +#define sk_CTLOG_new_null() SKM_sk_new_null(CTLOG) +#define sk_CTLOG_free(st) SKM_sk_free(CTLOG, (st)) +#define sk_CTLOG_num(st) SKM_sk_num(CTLOG, (st)) +#define sk_CTLOG_value(st, i) SKM_sk_value(CTLOG, (st), (i)) +#define sk_CTLOG_set(st, i, val) SKM_sk_set(CTLOG, (st), (i), (val)) +#define sk_CTLOG_zero(st) SKM_sk_zero(CTLOG, (st)) +#define sk_CTLOG_push(st, val) SKM_sk_push(CTLOG, (st), (val)) +#define sk_CTLOG_unshift(st, val) SKM_sk_unshift(CTLOG, (st), (val)) +#define sk_CTLOG_find(st, val) SKM_sk_find(CTLOG, (st), (val)) +#define sk_CTLOG_find_ex(st, val) SKM_sk_find_ex(CTLOG, (st), (val)) +#define sk_CTLOG_delete(st, i) SKM_sk_delete(CTLOG, (st), (i)) +#define sk_CTLOG_delete_ptr(st, ptr) SKM_sk_delete_ptr(CTLOG, (st), (ptr)) +#define sk_CTLOG_insert(st, val, i) SKM_sk_insert(CTLOG, (st), (val), (i)) +#define sk_CTLOG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CTLOG, (st), (cmp)) +#define sk_CTLOG_dup(st) SKM_sk_dup(CTLOG, st) +#define sk_CTLOG_pop_free(st, free_func) SKM_sk_pop_free(CTLOG, (st), (free_func)) +#define sk_CTLOG_shift(st) SKM_sk_shift(CTLOG, (st)) +#define sk_CTLOG_pop(st) SKM_sk_pop(CTLOG, (st)) +#define sk_CTLOG_sort(st) SKM_sk_sort(CTLOG, (st)) +#define sk_CTLOG_is_sorted(st) SKM_sk_is_sorted(CTLOG, (st)) + +#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) +#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) +#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) +#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) +#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) +#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) +#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) +#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) +#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) +#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) +#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) +#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) +#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) +#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) +#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) +#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) +#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) + +#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) + +#ifdef LIBRESSL_INTERNAL +#define sk_ESS_CERT_ID_V2_new(cmp) SKM_sk_new(ESS_CERT_ID_V2, (cmp)) +#define sk_ESS_CERT_ID_V2_new_null() SKM_sk_new_null(ESS_CERT_ID_V2) +#define sk_ESS_CERT_ID_V2_free(st) SKM_sk_free(ESS_CERT_ID_V2, (st)) +#define sk_ESS_CERT_ID_V2_num(st) SKM_sk_num(ESS_CERT_ID_V2, (st)) +#define sk_ESS_CERT_ID_V2_value(st, i) SKM_sk_value(ESS_CERT_ID_V2, (st), (i)) +#define sk_ESS_CERT_ID_V2_set(st, i, val) SKM_sk_set(ESS_CERT_ID_V2, (st), (i), (val)) +#define sk_ESS_CERT_ID_V2_zero(st) SKM_sk_zero(ESS_CERT_ID_V2, (st)) +#define sk_ESS_CERT_ID_V2_push(st, val) SKM_sk_push(ESS_CERT_ID_V2, (st), (val)) +#define sk_ESS_CERT_ID_V2_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID_V2, (st), (val)) +#define sk_ESS_CERT_ID_V2_find(st, val) SKM_sk_find(ESS_CERT_ID_V2, (st), (val)) +#define sk_ESS_CERT_ID_V2_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID_V2, (st), (val)) +#define sk_ESS_CERT_ID_V2_delete(st, i) SKM_sk_delete(ESS_CERT_ID_V2, (st), (i)) +#define sk_ESS_CERT_ID_V2_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID_V2, (st), (ptr)) +#define sk_ESS_CERT_ID_V2_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID_V2, (st), (val), (i)) +#define sk_ESS_CERT_ID_V2_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID_V2, (st), (cmp)) +#define sk_ESS_CERT_ID_V2_dup(st) SKM_sk_dup(ESS_CERT_ID_V2, st) +#define sk_ESS_CERT_ID_V2_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID_V2, (st), (free_func)) +#define sk_ESS_CERT_ID_V2_shift(st) SKM_sk_shift(ESS_CERT_ID_V2, (st)) +#define sk_ESS_CERT_ID_V2_pop(st) SKM_sk_pop(ESS_CERT_ID_V2, (st)) +#define sk_ESS_CERT_ID_V2_sort(st) SKM_sk_sort(ESS_CERT_ID_V2, (st)) +#define sk_ESS_CERT_ID_V2_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID_V2, (st)) +#endif /* LIBRESSL_INTERNAL */ + +#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) + +#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) + +#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) + +#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) + +#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) +#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) +#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) +#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) +#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) +#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) +#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) +#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) +#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) +#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) + +#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) +#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) +#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) +#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) +#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) +#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) +#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) +#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) +#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) +#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) +#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) + +#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) +#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) +#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) +#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) +#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) +#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) +#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) +#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) +#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) +#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) +#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) + +#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) +#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) +#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) +#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) +#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) +#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) +#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) +#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) +#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) +#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) +#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) +#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) +#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) +#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) +#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) +#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) +#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) + +#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) +#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) +#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) +#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) +#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) +#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) +#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) +#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) +#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) +#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) +#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) + +#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) +#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) + +#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) +#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) + +#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) +#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) +#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) +#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) +#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) +#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) +#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) +#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) +#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) +#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) +#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) + +#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) +#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) +#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) +#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) +#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) +#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) +#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) +#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) +#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) +#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) +#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) + +#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) +#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) +#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) +#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) +#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) +#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) +#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) +#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) +#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) +#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) +#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) + +#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) +#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) +#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) +#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) +#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) +#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) +#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) +#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) +#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) +#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) +#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) + +#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) +#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) +#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) +#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) +#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) +#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) +#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) +#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) +#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) +#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) +#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) + +#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) +#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) +#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) +#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) +#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) +#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) +#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) +#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) +#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) +#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) +#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) + +#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) +#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) +#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) +#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) +#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) +#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) +#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) +#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) +#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) +#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) +#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) +#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) +#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) +#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) +#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) +#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) +#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) +#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) +#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) +#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) +#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) + +#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) +#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) +#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) +#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) +#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) +#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) +#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) +#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) +#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) +#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) +#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) + +#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) +#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) +#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) +#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) +#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) +#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) +#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) +#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) +#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) +#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) +#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) + +#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) +#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) +#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) +#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) +#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) +#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) +#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) +#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) +#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) +#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) +#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) +#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) +#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) +#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) +#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) +#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) +#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) + +#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) +#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) +#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) +#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) +#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) +#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) +#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) +#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) +#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) +#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) +#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) + +#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) +#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) +#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) +#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) +#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) +#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) +#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) +#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) +#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) +#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) +#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) + +#define sk_SCT_new(cmp) SKM_sk_new(SCT, (cmp)) +#define sk_SCT_new_null() SKM_sk_new_null(SCT) +#define sk_SCT_free(st) SKM_sk_free(SCT, (st)) +#define sk_SCT_num(st) SKM_sk_num(SCT, (st)) +#define sk_SCT_value(st, i) SKM_sk_value(SCT, (st), (i)) +#define sk_SCT_set(st, i, val) SKM_sk_set(SCT, (st), (i), (val)) +#define sk_SCT_zero(st) SKM_sk_zero(SCT, (st)) +#define sk_SCT_push(st, val) SKM_sk_push(SCT, (st), (val)) +#define sk_SCT_unshift(st, val) SKM_sk_unshift(SCT, (st), (val)) +#define sk_SCT_find(st, val) SKM_sk_find(SCT, (st), (val)) +#define sk_SCT_find_ex(st, val) SKM_sk_find_ex(SCT, (st), (val)) +#define sk_SCT_delete(st, i) SKM_sk_delete(SCT, (st), (i)) +#define sk_SCT_delete_ptr(st, ptr) SKM_sk_delete_ptr(SCT, (st), (ptr)) +#define sk_SCT_insert(st, val, i) SKM_sk_insert(SCT, (st), (val), (i)) +#define sk_SCT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SCT, (st), (cmp)) +#define sk_SCT_dup(st) SKM_sk_dup(SCT, st) +#define sk_SCT_pop_free(st, free_func) SKM_sk_pop_free(SCT, (st), (free_func)) +#define sk_SCT_shift(st) SKM_sk_shift(SCT, (st)) +#define sk_SCT_pop(st) SKM_sk_pop(SCT, (st)) +#define sk_SCT_sort(st) SKM_sk_sort(SCT, (st)) +#define sk_SCT_is_sorted(st) SKM_sk_is_sorted(SCT, (st)) + +#define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp)) +#define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE) +#define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i)) +#define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val)) +#define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i)) +#define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr)) +#define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i)) +#define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp)) +#define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st) +#define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func)) +#define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st)) + +#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) +#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) +#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) +#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) +#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) +#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) +#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) +#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) +#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) +#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) +#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) + +#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) +#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) +#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) +#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) +#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) +#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) +#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) +#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) +#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) +#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) +#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) +#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) +#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) +#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) +#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) +#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) +#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) + +#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) + +#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) + +#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) +#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) +#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) +#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) +#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) +#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) +#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) +#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) +#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) +#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) +#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) + +#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) +#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) +#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) +#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) +#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) +#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) +#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) +#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) +#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) +#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) +#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) +#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) +#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) +#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) +#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) +#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) +#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) +#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) +#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) +#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) +#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) + +#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) +#define sk_X509_new_null() SKM_sk_new_null(X509) +#define sk_X509_free(st) SKM_sk_free(X509, (st)) +#define sk_X509_num(st) SKM_sk_num(X509, (st)) +#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) +#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) +#define sk_X509_zero(st) SKM_sk_zero(X509, (st)) +#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) +#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) +#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) +#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) +#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) +#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) +#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) +#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) +#define sk_X509_dup(st) SKM_sk_dup(X509, st) +#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) +#define sk_X509_shift(st) SKM_sk_shift(X509, (st)) +#define sk_X509_pop(st) SKM_sk_pop(X509, (st)) +#define sk_X509_sort(st) SKM_sk_sort(X509, (st)) +#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) + +#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) +#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) +#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) +#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) +#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) +#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) +#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) +#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) +#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) +#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) +#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) + +#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) +#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) +#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) +#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) +#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) +#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) +#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) +#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) +#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) +#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) +#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) +#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) +#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) +#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) +#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) +#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) +#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) + +#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) +#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) +#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) +#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) +#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) +#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) +#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) +#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) +#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) +#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) +#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) + +#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) +#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) +#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) +#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) +#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) +#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) +#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) +#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) +#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) +#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) +#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) +#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) +#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) +#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) +#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) +#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) +#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) +#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) +#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) +#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) +#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) + +#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) +#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) +#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) +#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) +#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) +#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) +#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) +#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) +#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) +#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) +#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) + +#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) +#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) +#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) +#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) +#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) +#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) +#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) +#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) +#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) +#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) +#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) +#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) +#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) +#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) +#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) +#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) +#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) +#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) +#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) +#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) +#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) + +#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) +#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) +#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) +#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) +#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) +#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) +#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) +#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) +#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) +#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) +#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) + +#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) +#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) +#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) +#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) +#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) +#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) +#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) +#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) +#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) +#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) +#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) +#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) +#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) +#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) +#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) +#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) +#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) +#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) +#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) +#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) +#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) + +#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) +#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) +#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) +#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) +#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) +#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) +#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) +#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) +#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) +#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) +#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) + +#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) +#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) +#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) +#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) +#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) +#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) +#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) +#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) +#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) +#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) +#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) +#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) +#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) +#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) +#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) +#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) +#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) + +#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) +#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) +#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) +#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) +#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) +#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) +#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) +#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) +#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) +#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) +#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) + +#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) +#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) +#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) +#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) +#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) +#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) +#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) +#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) +#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) +#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) +#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) +#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) +#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) +#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) +#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) +#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) +#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) + +#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) +#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) +#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) +#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) +#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) +#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) +#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) +#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) +#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) +#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) +#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) +#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) +#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) +#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) +#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) +#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) +#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) + +#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) +#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) +#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) +#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) +#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) +#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) +#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) +#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) +#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) +#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) +#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) + +#define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +#define sk_void_new_null() SKM_sk_new_null(void) +#define sk_void_free(st) SKM_sk_free(void, (st)) +#define sk_void_num(st) SKM_sk_num(void, (st)) +#define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +#define sk_void_zero(st) SKM_sk_zero(void, (st)) +#define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +#define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +#define sk_void_dup(st) SKM_sk_dup(void, st) +#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +#define sk_void_shift(st) SKM_sk_shift(void, (st)) +#define sk_void_pop(st) SKM_sk_pop(void, (st)) +#define sk_void_sort(st) SKM_sk_sort(void, (st)) +#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) + +#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) +#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func)) +#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) +#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) +#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) +#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) + +#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) +#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func)) +#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) +#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) + +#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) + +#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +#define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) + +#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +#define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) + +#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) + +#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) + +#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +#define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) + +#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +#define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) + +#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) + +#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +#define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) + +#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/Libraries/libressl/include/openssl/sha.h b/Libraries/libressl/include/openssl/sha.h new file mode 100644 index 000000000..e1de79f4f --- /dev/null +++ b/Libraries/libressl/include/openssl/sha.h @@ -0,0 +1,189 @@ +/* $OpenBSD: sha.h,v 1.22 2023/07/08 07:08:11 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_SHA_H +#define HEADER_SHA_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA1) +#error SHA is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define SHA_LONG unsigned int + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK-8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +#ifndef OPENSSL_NO_SHA1 +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__, 2, 3))); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__, 1, 2))); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +#endif + +#define SHA256_CBLOCK (SHA_LBLOCK*4) /* SHA-256 treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA224_DIGEST_LENGTH 28 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +#ifndef OPENSSL_NO_SHA256 +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__, 2, 3))); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__, 1, 2))); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__, 2, 3))); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__, 1, 2))); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +#endif + +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. */ +#if defined(_LP64) +#define SHA_LONG64 unsigned long +#define U64(C) C##UL +#else +#define SHA_LONG64 unsigned long long +#define U64(C) C##ULL +#endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; +#endif + +#ifndef OPENSSL_NO_SHA512 +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__, 2, 3))); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__, 1, 2))); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__, 2, 3))); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__, 1, 2))); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/sm3.h b/Libraries/libressl/include/openssl/sm3.h new file mode 100644 index 000000000..553c64dcd --- /dev/null +++ b/Libraries/libressl/include/openssl/sm3.h @@ -0,0 +1,53 @@ +/* $OpenBSD: sm3.h,v 1.1 2018/11/11 06:53:31 tb Exp $ */ +/* + * Copyright (c) 2018, Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_SM3_H +#define HEADER_SM3_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_SM3 +#error SM3 is disabled. +#endif + +#define SM3_DIGEST_LENGTH 32 +#define SM3_WORD unsigned int + +#define SM3_CBLOCK 64 +#define SM3_LBLOCK (SM3_CBLOCK / 4) + +typedef struct SM3state_st { + SM3_WORD A, B, C, D, E, F, G, H; + SM3_WORD Nl, Nh; + SM3_WORD data[SM3_LBLOCK]; + unsigned int num; +} SM3_CTX; + +int SM3_Init(SM3_CTX *c); +int SM3_Update(SM3_CTX *c, const void *data, size_t len); +int SM3_Final(unsigned char *md, SM3_CTX *c); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SM3_H */ diff --git a/Libraries/libressl/include/openssl/sm4.h b/Libraries/libressl/include/openssl/sm4.h new file mode 100644 index 000000000..5931ac714 --- /dev/null +++ b/Libraries/libressl/include/openssl/sm4.h @@ -0,0 +1,51 @@ +/* $OpenBSD: sm4.h,v 1.1 2019/03/17 17:42:37 tb Exp $ */ +/* + * Copyright (c) 2017, 2019 Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_SM4_H +#define HEADER_SM4_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_SM4 +#error SM4 is disabled. +#endif + +#define SM4_DECRYPT 0 +#define SM4_ENCRYPT 1 + +#define SM4_BLOCK_SIZE 16 +#define SM4_KEY_SCHEDULE 32 + +typedef struct sm4_key_st { + unsigned char opaque[128]; +} SM4_KEY; + +int SM4_set_key(const uint8_t *key, SM4_KEY *ks); +void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks); +void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SM4_H */ diff --git a/Libraries/libressl/include/openssl/srtp.h b/Libraries/libressl/include/openssl/srtp.h new file mode 100644 index 000000000..89ce86202 --- /dev/null +++ b/Libraries/libressl/include/openssl/srtp.h @@ -0,0 +1,146 @@ +/* $OpenBSD: srtp.h,v 1.7 2021/06/11 15:28:13 landry Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. + * Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +#define HEADER_D1_SRTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRTP_AES128_CM_SHA1_80 0x0001 +#define SRTP_AES128_CM_SHA1_32 0x0002 +#define SRTP_AES128_F8_SHA1_80 0x0003 +#define SRTP_AES128_F8_SHA1_32 0x0004 +#define SRTP_NULL_SHA1_80 0x0005 +#define SRTP_NULL_SHA1_32 0x0006 + +/* AEAD SRTP protection profiles from RFC 7714 */ +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/ssl.h b/Libraries/libressl/include/openssl/ssl.h new file mode 100644 index 000000000..acde94c74 --- /dev/null +++ b/Libraries/libressl/include/openssl/ssl.h @@ -0,0 +1,2362 @@ +/* $OpenBSD: ssl.h,v 1.230 2022/12/26 07:31:44 jmc Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_H +#define HEADER_SSL_H + +#include + +#include + +#include +#include +#include + +#include + +#ifndef OPENSSL_NO_DEPRECATED +#include +#include +#include + +#ifndef OPENSSL_NO_X509 +#include +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSLeay version number for ASN.1 encoding of the session information */ +/* Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +#define SSL_SESSION_ASN1_VERSION 0x0001 + +/* text strings for the ciphers */ +#define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 +#define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 +#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 +#define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 +#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 +#define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 +#define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 +#define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA +#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 +#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA + +/* VRS Additional Kerberos5 entries + */ +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +#define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +#define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 + +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +#define SSL_MAX_SID_CTX_LENGTH 32 + +#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +#define SSL_MAX_KEY_ARG_LENGTH 8 +#define SSL_MAX_MASTER_KEY_LENGTH 48 + + +/* These are used to specify which ciphers to use and not to use */ + +#define SSL_TXT_LOW "LOW" +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" + +#define SSL_TXT_kFZA "kFZA" /* unused! */ +#define SSL_TXT_aFZA "aFZA" /* unused! */ +#define SSL_TXT_eFZA "eFZA" /* unused! */ +#define SSL_TXT_FZA "FZA" /* unused! */ + +#define SSL_TXT_aNULL "aNULL" +#define SSL_TXT_eNULL "eNULL" +#define SSL_TXT_NULL "NULL" + +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHr "kDHr" /* no such ciphersuites supported! */ +#define SSL_TXT_kDHd "kDHd" /* no such ciphersuites supported! */ +#define SSL_TXT_kDH "kDH" /* no such ciphersuites supported! */ +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kKRB5 "kKRB5" +#define SSL_TXT_kECDHr "kECDHr" +#define SSL_TXT_kECDHe "kECDHe" +#define SSL_TXT_kECDH "kECDH" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_kGOST "kGOST" +#define SSL_TXT_kSRP "kSRP" + +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aDSS "aDSS" +#define SSL_TXT_aDH "aDH" /* no such ciphersuites supported! */ +#define SSL_TXT_aECDH "aECDH" +#define SSL_TXT_aKRB5 "aKRB5" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_aGOST94 "aGOST94" +#define SSL_TXT_aGOST01 "aGOST01" +#define SSL_TXT_aGOST "aGOST" + +#define SSL_TXT_DSS "DSS" +#define SSL_TXT_DH "DH" +#define SSL_TXT_DHE "DHE" /* same as "kDHE:-ADH" */ +#define SSL_TXT_EDH "EDH" /* previous name for DHE */ +#define SSL_TXT_ADH "ADH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_ECDHE "ECDHE" /* same as "kECDHE:-AECDH" */ +#define SSL_TXT_EECDH "EECDH" /* previous name for ECDHE */ +#define SSL_TXT_AECDH "AECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_KRB5 "KRB5" +#define SSL_TXT_PSK "PSK" +#define SSL_TXT_SRP "SRP" + +#define SSL_TXT_DES "DES" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_RC2 "RC2" +#define SSL_TXT_IDEA "IDEA" +#define SSL_TXT_SEED "SEED" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_AES_GCM "AESGCM" +#define SSL_TXT_CAMELLIA128 "CAMELLIA128" +#define SSL_TXT_CAMELLIA256 "CAMELLIA256" +#define SSL_TXT_CAMELLIA "CAMELLIA" +#define SSL_TXT_CHACHA20 "CHACHA20" + +#define SSL_TXT_AEAD "AEAD" +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" /* same as "SHA1" */ +#define SSL_TXT_GOST94 "GOST94" +#define SSL_TXT_GOST89MAC "GOST89MAC" +#define SSL_TXT_SHA256 "SHA256" +#define SSL_TXT_SHA384 "SHA384" +#define SSL_TXT_STREEBOG256 "STREEBOG256" +#define SSL_TXT_STREEBOG512 "STREEBOG512" + +#define SSL_TXT_DTLS1 "DTLSv1" +#define SSL_TXT_DTLS1_2 "DTLSv1.2" +#define SSL_TXT_SSLV2 "SSLv2" +#define SSL_TXT_SSLV3 "SSLv3" +#define SSL_TXT_TLSV1 "TLSv1" +#define SSL_TXT_TLSV1_1 "TLSv1.1" +#define SSL_TXT_TLSV1_2 "TLSv1.2" +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define SSL_TXT_TLSV1_3 "TLSv1.3" +#endif + +#define SSL_TXT_EXP "EXP" +#define SSL_TXT_EXPORT "EXPORT" + +#define SSL_TXT_ALL "ALL" + +/* + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +#define SSL_TXT_CMPALL "COMPLEMENTOFALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* The following cipher list is used by default. + * It also is substituted when an application-defined cipher list string + * starts with 'DEFAULT'. */ +#define SSL_DEFAULT_CIPHER_LIST "ALL:!aNULL:!eNULL:!SSLv2" +/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! + * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable + * some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + + +#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +#define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* This is needed to stop compilers complaining about the + * 'struct ssl_st *' function parameters used to prototype callbacks + * in SSL_CTX. */ +typedef struct ssl_st *ssl_crock_st; + +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; + +#if defined(LIBRESSL_HAS_QUIC) || defined(LIBRESSL_INTERNAL) +typedef struct ssl_quic_method_st SSL_QUIC_METHOD; +#endif + +DECLARE_STACK_OF(SSL_CIPHER) + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); + +/* Allow initial connection to servers that don't support RI */ +#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L + +/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added + * in OpenSSL 0.9.6d. Usually (depending on the application protocol) + * the workaround is not needed. + * Unfortunately some broken SSL/TLS implementations cannot handle it + * at all, which is why it was previously included in SSL_OP_ALL. + * Now it's not. + */ +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L + +/* DTLS options */ +#define SSL_OP_NO_QUERY_MTU 0x00001000L +/* Turn on Cookie Exchange (on relevant for servers) */ +#define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +#define SSL_OP_NO_TICKET 0x00004000L + +/* As server, disallow session resumption on renegotiation */ +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* Disallow client initiated renegotiation. */ +#define SSL_OP_NO_CLIENT_RENEGOTIATION 0x00020000L +/* If set, always create a new key when using tmp_dh parameters */ +#define SSL_OP_SINGLE_DH_USE 0x00100000L +/* Set on servers to choose the cipher according to the server's + * preferences */ +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L + +#define SSL_OP_NO_TLSv1 0x04000000L +#define SSL_OP_NO_TLSv1_2 0x08000000L +#define SSL_OP_NO_TLSv1_1 0x10000000L + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define SSL_OP_NO_TLSv1_3 0x20000000L +#endif + +#define SSL_OP_NO_DTLSv1 0x40000000L +#define SSL_OP_NO_DTLSv1_2 0x80000000L + +/* SSL_OP_ALL: various bug workarounds that should be rather harmless. */ +#define SSL_OP_ALL \ + (SSL_OP_LEGACY_SERVER_CONNECT) + +/* Obsolete flags kept for compatibility. No sane code should use them. */ +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0 +#define SSL_OP_CISCO_ANYCONNECT 0x0 +#define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x0 +#define SSL_OP_EPHEMERAL_RSA 0x0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0x0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x0 +#define SSL_OP_NO_COMPRESSION 0x0 +#define SSL_OP_NO_SSLv2 0x0 +#define SSL_OP_NO_SSLv3 0x0 +#define SSL_OP_PKCS1_CHECK_1 0x0 +#define SSL_OP_PKCS1_CHECK_2 0x0 +#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x0 +#define SSL_OP_SINGLE_ECDH_USE 0x0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 +#define SSL_OP_TLSEXT_PADDING 0x0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x0 +#define SSL_OP_TLS_D5_BUG 0x0 +#define SSL_OP_TLS_ROLLBACK_BUG 0x0 + +/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): */ +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L +/* Make it possible to retry SSL_write() with changed buffer location + * (buffer contents must stay the same!); this is not the default to avoid + * the misconception that non-blocking SSL_write() behaves like + * non-blocking write(): */ +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* Never bother the application with retries if the transport + * is blocking: */ +#define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L +/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context + * or just freed (depending on the context's setting for freelist_max_len). */ +#define SSL_MODE_RELEASE_BUFFERS 0x00000010L + +/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, + * they cannot be used to clear bits. */ + +#define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +#define SSL_CTX_clear_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +#define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) +#define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) +#define SSL_clear_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +#define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + +#define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +#define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +#define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +#define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +#define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +#define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +#define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) + +#define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, + int version, int content_type, const void *buf, size_t len, SSL *ssl, + void *arg)); +void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); +#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line); +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb); +SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx); +int SSL_set_num_tickets(SSL *s, size_t num_tickets); +size_t SSL_get_num_tickets(const SSL *s); +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); +size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); +STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s); + +#ifndef LIBRESSL_INTERNAL +struct ssl_aead_ctx_st; +typedef struct ssl_aead_ctx_st SSL_AEAD_CTX; +#endif + +#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */ + +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* This callback type is used inside SSL_CTX, SSL, and in the functions that set + * them. It is used to override the generation of SSL/TLS session IDs in a + * server. Return value should be zero on an error, non-zero to proceed. Also, + * callbacks should themselves check if the id they generate is unique otherwise + * the SSL handshake will fail with an error - callbacks can do this using the + * 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) + * The length value passed in is set at the maximum size the session ID can be. + * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback + * can alter this length to be less if desired, but under SSLv2 session IDs are + * supposed to be fixed at 16 bytes so the id will be padded after the callback + * returns in this case. It is also an error for the callback to set the size to + * zero. */ +typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id, + unsigned int *id_len); + +typedef struct ssl_comp_st SSL_COMP; + +#ifdef LIBRESSL_INTERNAL +DECLARE_STACK_OF(SSL_COMP) +struct lhash_st_SSL_SESSION { + int dummy; +}; +#endif + +#define SSL_SESS_CACHE_OFF 0x0000 +#define SSL_SESS_CACHE_CLIENT 0x0001 +#define SSL_SESS_CACHE_SERVER 0x0002 +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +struct lhash_st_SSL_SESSION *SSL_CTX_sessions(SSL_CTX *ctx); +#define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +#define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +#define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +#define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +#define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +#define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +#define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +#define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +#define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +#define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +#define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +#define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, + const unsigned char *data, int len, int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, + const unsigned char *data, int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl, + int type, int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +#endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb)(SSL *ssl, const unsigned char *cookie, + unsigned int cookie_len)); +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, int (*cb)(SSL *ssl, + const unsigned char **out, unsigned int *outlen, void *arg), void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, int (*cb)(SSL *ssl, + unsigned char **out, unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg), void *arg); + +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, const unsigned char *client, + unsigned int client_len); +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned int *len); + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); +int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg), void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +typedef int (*SSL_psk_use_session_cb_func)(SSL *ssl, const EVP_MD *md, + const unsigned char **id, size_t *idlen, SSL_SESSION **sess); +void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb); +#endif + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 +#define SSL_X509_LOOKUP 4 + +/* These will only be used when doing non-blocking IO */ +#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +#define SSL_want_read(s) (SSL_want(s) == SSL_READING) +#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + +#define SSL_MAC_FLAG_READ_MAC_STREAM 1 +#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +#ifdef __cplusplus +} +#endif + +#include +#include +#include /* This is mostly sslv3 with a few tweaks */ +#include /* Datagram TLS */ +#include +#include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* compatibility */ +#define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +#define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +#define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +#define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) + +/* The following are the possible values for ssl->state are are + * used to indicate where we are up to in the SSL connection establishment. + * The macros that follow are about the only things you should need to use + * and even then, only when using non-blocking IO. + * It can also be useful to work out where you were when the connection + * failed */ + +#define SSL_ST_CONNECT 0x1000 +#define SSL_ST_ACCEPT 0x2000 +#define SSL_ST_MASK 0x0FFF +#define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) +#define SSL_ST_BEFORE 0x4000 +#define SSL_ST_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) + +#define SSL_CB_LOOP 0x01 +#define SSL_CB_EXIT 0x02 +#define SSL_CB_READ 0x04 +#define SSL_CB_WRITE 0x08 +#define SSL_CB_ALERT 0x4000 /* used in callback */ +#define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +#define SSL_CB_HANDSHAKE_START 0x10 +#define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +#define SSL_get_state(a) (SSL_state((a))) +#define SSL_is_init_finished(a) (SSL_state((a)) == SSL_ST_OK) +#define SSL_in_init(a) (SSL_state((a))&SSL_ST_INIT) +#define SSL_in_before(a) (SSL_state((a))&SSL_ST_BEFORE) +#define SSL_in_connect_init(a) (SSL_state((a))&SSL_ST_CONNECT) +#define SSL_in_accept_init(a) (SSL_state((a))&SSL_ST_ACCEPT) + +/* The following 2 states are kept in ssl->rstate when reads fail, + * you should not need these */ +#define SSL_ST_READ_HEADER 0xF0 +#define SSL_ST_READ_BODY 0xF1 +#define SSL_ST_READ_DONE 0xF2 + +/* Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options + * are 'ored' with SSL_VERIFY_PEER if they are desired */ +#define SSL_VERIFY_NONE 0x00 +#define SSL_VERIFY_PEER 0x01 +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +#define SSL_VERIFY_CLIENT_ONCE 0x04 +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define SSL_VERIFY_POST_HANDSHAKE 0x08 + +int SSL_verify_client_post_handshake(SSL *s); +void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val); +void SSL_set_post_handshake_auth(SSL *s, int val); +#endif + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +/* More backward compatibility */ +#define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +#define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +#define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_time(a) SSL_SESSION_get_time(a) +#define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +#define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +#define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +SSL_SESSION *PEM_read_bio_SSL_SESSION(BIO *bp, SSL_SESSION **x, + pem_password_cb *cb, void *u); +SSL_SESSION *PEM_read_SSL_SESSION(FILE *fp, SSL_SESSION **x, + pem_password_cb *cb, void *u); +int PEM_write_bio_SSL_SESSION(BIO *bp, SSL_SESSION *x); +int PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x); + +/* + * TLS Alerts. + * + * https://www.iana.org/assignments/tls-parameters/#tls-parameters-6 + */ + +/* Obsolete alerts. */ +#ifndef LIBRESSL_INTERNAL +#define SSL_AD_DECRYPTION_FAILED 21 /* Removed in TLSv1.1 */ +#define SSL_AD_NO_CERTIFICATE 41 /* Removed in TLSv1.0 */ +#define SSL_AD_EXPORT_RESTRICTION 60 /* Removed in TLSv1.1 */ +#endif + +#define SSL_AD_CLOSE_NOTIFY 0 +#define SSL_AD_UNEXPECTED_MESSAGE 10 +#define SSL_AD_BAD_RECORD_MAC 20 +#define SSL_AD_RECORD_OVERFLOW 22 +#define SSL_AD_DECOMPRESSION_FAILURE 30 /* Removed in TLSv1.3 */ +#define SSL_AD_HANDSHAKE_FAILURE 40 +#define SSL_AD_BAD_CERTIFICATE 42 +#define SSL_AD_UNSUPPORTED_CERTIFICATE 43 +#define SSL_AD_CERTIFICATE_REVOKED 44 +#define SSL_AD_CERTIFICATE_EXPIRED 45 +#define SSL_AD_CERTIFICATE_UNKNOWN 46 +#define SSL_AD_ILLEGAL_PARAMETER 47 +#define SSL_AD_UNKNOWN_CA 48 +#define SSL_AD_ACCESS_DENIED 49 +#define SSL_AD_DECODE_ERROR 50 +#define SSL_AD_DECRYPT_ERROR 51 +#define SSL_AD_PROTOCOL_VERSION 70 +#define SSL_AD_INSUFFICIENT_SECURITY 71 +#define SSL_AD_INTERNAL_ERROR 80 +#define SSL_AD_INAPPROPRIATE_FALLBACK 86 +#define SSL_AD_USER_CANCELLED 90 +#define SSL_AD_NO_RENEGOTIATION 100 /* Removed in TLSv1.3 */ +#define SSL_AD_MISSING_EXTENSION 109 /* Added in TLSv1.3. */ +#define SSL_AD_UNSUPPORTED_EXTENSION 110 +#define SSL_AD_CERTIFICATE_UNOBTAINABLE 111 /* Removed in TLSv1.3 */ +#define SSL_AD_UNRECOGNIZED_NAME 112 +#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE 114 /* Removed in TLSv1.3 */ +#define SSL_AD_UNKNOWN_PSK_IDENTITY 115 +#define SSL_AD_CERTIFICATE_REQUIRED 116 +#define SSL_AD_NO_APPLICATION_PROTOCOL 120 + +/* Offset to get an SSL_R_... value from an SSL_AD_... value. */ +#define SSL_AD_REASON_OFFSET 1000 + +#define SSL_ERROR_NONE 0 +#define SSL_ERROR_SSL 1 +#define SSL_ERROR_WANT_READ 2 +#define SSL_ERROR_WANT_WRITE 3 +#define SSL_ERROR_WANT_X509_LOOKUP 4 +#define SSL_ERROR_SYSCALL 5 +#define SSL_ERROR_ZERO_RETURN 6 +#define SSL_ERROR_WANT_CONNECT 7 +#define SSL_ERROR_WANT_ACCEPT 8 +#define SSL_ERROR_WANT_ASYNC 9 +#define SSL_ERROR_WANT_ASYNC_JOB 10 +#define SSL_ERROR_WANT_CLIENT_HELLO_CB 11 + +#define SSL_CTRL_NEED_TMP_RSA 1 +#define SSL_CTRL_SET_TMP_RSA 2 +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_SET_TMP_ECDH 4 +#define SSL_CTRL_SET_TMP_RSA_CB 5 +#define SSL_CTRL_SET_TMP_DH_CB 6 +#define SSL_CTRL_SET_TMP_ECDH_CB 7 + +#define SSL_CTRL_GET_SESSION_REUSED 8 +#define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +#define SSL_CTRL_GET_FLAGS 13 +#define SSL_CTRL_EXTRA_CHAIN_CERT 14 + +#define SSL_CTRL_SET_MSG_CALLBACK 15 +#define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 + +/* only applies to datagram connections */ +#define SSL_CTRL_SET_MTU 17 +/* Stats */ +#define SSL_CTRL_SESS_NUMBER 20 +#define SSL_CTRL_SESS_CONNECT 21 +#define SSL_CTRL_SESS_CONNECT_GOOD 22 +#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +#define SSL_CTRL_SESS_ACCEPT 24 +#define SSL_CTRL_SESS_ACCEPT_GOOD 25 +#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +#define SSL_CTRL_SESS_HIT 27 +#define SSL_CTRL_SESS_CB_HIT 28 +#define SSL_CTRL_SESS_MISSES 29 +#define SSL_CTRL_SESS_TIMEOUTS 30 +#define SSL_CTRL_SESS_CACHE_FULL 31 +#define SSL_CTRL_OPTIONS 32 +#define SSL_CTRL_MODE 33 + +#define SSL_CTRL_GET_READ_AHEAD 40 +#define SSL_CTRL_SET_READ_AHEAD 41 +#define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +#define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +#define SSL_CTRL_SET_SESS_CACHE_MODE 44 +#define SSL_CTRL_GET_SESS_CACHE_MODE 45 + +#define SSL_CTRL_GET_MAX_CERT_LIST 50 +#define SSL_CTRL_SET_MAX_CERT_LIST 51 + +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 + +/* see tls1.h for macros based on these */ +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +#define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB 128 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG 129 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE 127 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 + +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 + +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 + +#define SSL_CTRL_SET_SRP_ARG 78 +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 + +#define DTLS_CTRL_GET_TIMEOUT 73 +#define DTLS_CTRL_HANDLE_TIMEOUT 74 +#define DTLS_CTRL_LISTEN 75 + +#define SSL_CTRL_GET_RI_SUPPORT 76 +#define SSL_CTRL_CLEAR_OPTIONS 77 +#define SSL_CTRL_CLEAR_MODE 78 + +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 + +#define SSL_CTRL_CHAIN 88 +#define SSL_CTRL_CHAIN_CERT 89 + +#define SSL_CTRL_SET_GROUPS 91 +#define SSL_CTRL_SET_GROUPS_LIST 92 +#define SSL_CTRL_GET_SHARED_GROUP 93 +#define SSL_CTRL_SET_ECDH_AUTO 94 + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +#define SSL_CTRL_GET_PEER_TMP_KEY 109 +#define SSL_CTRL_GET_SERVER_TMP_KEY SSL_CTRL_GET_PEER_TMP_KEY +#else +#define SSL_CTRL_GET_SERVER_TMP_KEY 109 +#endif + +#define SSL_CTRL_GET_CHAIN_CERTS 115 + +#define SSL_CTRL_SET_DH_AUTO 118 + +#define SSL_CTRL_SET_MIN_PROTO_VERSION 123 +#define SSL_CTRL_SET_MAX_PROTO_VERSION 124 +#define SSL_CTRL_GET_MIN_PROTO_VERSION 130 +#define SSL_CTRL_GET_MAX_PROTO_VERSION 131 + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define SSL_CTRL_GET_SIGNATURE_NID 132 +#endif + +#define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +#define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +#define DTLSv1_listen(ssl, peer) \ + SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) + +#define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +#define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) + +#define SSL_CTX_need_tmp_RSA(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) +#define SSL_CTX_set_tmp_rsa(ctx,rsa) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +#define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +#define SSL_CTX_set_dh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +#define SSL_CTX_set_ecdh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) + +#define SSL_need_tmp_RSA(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) +#define SSL_set_tmp_rsa(ssl,rsa) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +#define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +#define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +#define SSL_set_dh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +#define SSL_set_ecdh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) + +int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); +int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); +int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509); +int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509); +int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain); +int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); + +int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain); +int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain); +int SSL_add0_chain_cert(SSL *ssl, X509 *x509); +int SSL_add1_chain_cert(SSL *ssl, X509 *x509); +int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain); +int SSL_clear_chain_certs(SSL *ssl); + +int SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, size_t groups_len); +int SSL_CTX_set1_groups_list(SSL_CTX *ctx, const char *groups); + +int SSL_set1_groups(SSL *ssl, const int *groups, size_t groups_len); +int SSL_set1_groups_list(SSL *ssl, const char *groups); + +int SSL_CTX_get_min_proto_version(SSL_CTX *ctx); +int SSL_CTX_get_max_proto_version(SSL_CTX *ctx); +int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version); +int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version); + +int SSL_get_min_proto_version(SSL *ssl); +int SSL_get_max_proto_version(SSL *ssl); +int SSL_set_min_proto_version(SSL *ssl, uint16_t version); +int SSL_set_max_proto_version(SSL *ssl, uint16_t version); + +const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx); + +#ifndef LIBRESSL_INTERNAL +#define SSL_CTRL_SET_CURVES SSL_CTRL_SET_GROUPS +#define SSL_CTRL_SET_CURVES_LIST SSL_CTRL_SET_GROUPS_LIST + +#define SSL_CTX_set1_curves SSL_CTX_set1_groups +#define SSL_CTX_set1_curves_list SSL_CTX_set1_groups_list +#define SSL_set1_curves SSL_set1_groups +#define SSL_set1_curves_list SSL_set1_groups_list +#endif + +#define SSL_CTX_add_extra_chain_cert(ctx, x509) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, (char *)x509) +#define SSL_CTX_get_extra_chain_certs(ctx, px509) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 0, px509) +#define SSL_CTX_get_extra_chain_certs_only(ctx, px509) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 1, px509) +#define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0, NULL) + +#define SSL_get_shared_group(s, n) \ + SSL_ctrl((s), SSL_CTRL_GET_SHARED_GROUP, (n), NULL) +#define SSL_get_shared_curve SSL_get_shared_group + +#define SSL_get_server_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define SSL_get_signature_nid(s, pn) \ + SSL_ctrl(s, SSL_CTRL_GET_SIGNATURE_NID, 0, pn) + +#define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s, SSL_CTRL_GET_PEER_SIGNATURE_NID, 0, pn) +#define SSL_get_peer_tmp_key(s, pk) \ + SSL_ctrl(s, SSL_CTRL_GET_PEER_TMP_KEY, 0, pk) + +int SSL_get_signature_type_nid(const SSL *ssl, int *nid); +int SSL_get_peer_signature_type_nid(const SSL *ssl, int *nid); + +#endif /* LIBRESSL_HAS_TLS1_3 || LIBRESSL_INTERNAL */ + +#ifndef LIBRESSL_INTERNAL +/* + * Also provide those functions as macros for compatibility with + * existing users. + */ +#define SSL_CTX_set0_chain SSL_CTX_set0_chain +#define SSL_CTX_set1_chain SSL_CTX_set1_chain +#define SSL_CTX_add0_chain_cert SSL_CTX_add0_chain_cert +#define SSL_CTX_add1_chain_cert SSL_CTX_add1_chain_cert +#define SSL_CTX_get0_chain_certs SSL_CTX_get0_chain_certs +#define SSL_CTX_clear_chain_certs SSL_CTX_clear_chain_certs + +#define SSL_add0_chain_cert SSL_add0_chain_cert +#define SSL_add1_chain_cert SSL_add1_chain_cert +#define SSL_set0_chain SSL_set0_chain +#define SSL_set1_chain SSL_set1_chain +#define SSL_get0_chain_certs SSL_get0_chain_certs +#define SSL_clear_chain_certs SSL_clear_chain_certs + +#define SSL_CTX_set1_groups SSL_CTX_set1_groups +#define SSL_CTX_set1_groups_list SSL_CTX_set1_groups_list +#define SSL_set1_groups SSL_set1_groups +#define SSL_set1_groups_list SSL_set1_groups_list + +#define SSL_CTX_get_min_proto_version SSL_CTX_get_min_proto_version +#define SSL_CTX_get_max_proto_version SSL_CTX_get_max_proto_version +#define SSL_CTX_set_min_proto_version SSL_CTX_set_min_proto_version +#define SSL_CTX_set_max_proto_version SSL_CTX_set_max_proto_version + +#define SSL_get_min_proto_version SSL_get_min_proto_version +#define SSL_get_max_proto_version SSL_get_max_proto_version +#define SSL_set_min_proto_version SSL_set_min_proto_version +#define SSL_set_max_proto_version SSL_set_max_proto_version +#endif + +const BIO_METHOD *BIO_f_ssl(void); +BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); +int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +#endif +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +void SSL_CTX_free(SSL_CTX *); +int SSL_CTX_up_ref(SSL_CTX *ctx); +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +long SSL_CTX_get_timeout(const SSL_CTX *ctx); +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); +int SSL_want(const SSL *s); +int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +const SSL_CIPHER *SSL_CIPHER_get_by_id(unsigned int id); +const SSL_CIPHER *SSL_CIPHER_get_by_value(uint16_t value); +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +const char * SSL_CIPHER_get_version(const SSL_CIPHER *c); +const char * SSL_CIPHER_get_name(const SSL_CIPHER *c); +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); +uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *c); +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); +int SSL_CIPHER_is_aead(const SSL_CIPHER *c); + +int SSL_get_fd(const SSL *s); +int SSL_get_rfd(const SSL *s); +int SSL_get_wfd(const SSL *s); +const char * SSL_get_cipher_list(const SSL *s, int n); +char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +int SSL_get_read_ahead(const SSL * s); +int SSL_pending(const SSL *s); +int SSL_set_fd(SSL *s, int fd); +int SSL_set_rfd(SSL *s, int fd); +int SSL_set_wfd(SSL *s, int fd); +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +BIO * SSL_get_rbio(const SSL *s); +void SSL_set0_rbio(SSL *s, BIO *rbio); +BIO * SSL_get_wbio(const SSL *s); +int SSL_set_cipher_list(SSL *s, const char *str); +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +int SSL_set_ciphersuites(SSL *s, const char *str); +#endif +void SSL_set_read_ahead(SSL *s, int yes); +int SSL_get_verify_mode(const SSL *s); +int SSL_get_verify_depth(const SSL *s); +int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *); +void SSL_set_verify(SSL *s, int mode, + int (*callback)(int ok, X509_STORE_CTX *ctx)); +void SSL_set_verify_depth(SSL *s, int depth); +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len); +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, long len); +int SSL_use_certificate(SSL *ssl, X509 *x); +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_chain_file(SSL *ssl, const char *file); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */ +int SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len); +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); + +void SSL_load_error_strings(void ); +const char *SSL_state_string(const SSL *s); +const char *SSL_rstate_string(const SSL *s); +const char *SSL_state_string_long(const SSL *s); +const char *SSL_rstate_string_long(const SSL *s); +const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *ss); +size_t SSL_SESSION_get_master_key(const SSL_SESSION *ss, + unsigned char *out, size_t max_out); +int SSL_SESSION_get_protocol_version(const SSL_SESSION *s); +long SSL_SESSION_get_time(const SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(const SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +int SSL_copy_session_id(SSL *to, const SSL *from); +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, + unsigned int sid_len); +int SSL_SESSION_set1_id_context(SSL_SESSION *s, + const unsigned char *sid_ctx, unsigned int sid_ctx_len); +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +int SSL_SESSION_is_resumable(const SSL_SESSION *s); +#endif + +SSL_SESSION *SSL_SESSION_new(void); +void SSL_SESSION_free(SSL_SESSION *ses); +int SSL_SESSION_up_ref(SSL_SESSION *ss); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *ss, + unsigned int *len); +const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *ss, + unsigned int *len); +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *sess); +int SSL_SESSION_set_max_early_data(SSL_SESSION *sess, uint32_t max_early_data); +#endif +unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s); +int SSL_SESSION_has_ticket(const SSL_SESSION *s); +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *ss); +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c); +int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); +int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +#ifdef HEADER_X509_H +X509 * SSL_get_peer_certificate(const SSL *s); +#endif + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*callback)(int, X509_STORE_CTX *)); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *, void *), void *arg); +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + +pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx); +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_check_private_key(const SSL_CTX *ctx); +int SSL_check_private_key(const SSL *ctx); + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, unsigned int sid_ctx_len); + +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); +int SSL_set1_host(SSL *s, const char *hostname); +void SSL_set_hostflags(SSL *s, unsigned int flags); +const char *SSL_get0_peername(SSL *s); + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +SSL *SSL_new(SSL_CTX *ctx); +void SSL_free(SSL *ssl); +int SSL_up_ref(SSL *ssl); +int SSL_accept(SSL *ssl); +int SSL_connect(SSL *ssl); +int SSL_is_dtls(const SSL *s); +int SSL_is_server(const SSL *s); +int SSL_read(SSL *ssl, void *buf, int num); +int SSL_peek(SSL *ssl, void *buf, int num); +int SSL_write(SSL *ssl, const void *buf, int num); +int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *bytes_read); +int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *bytes_peeked); +int SSL_write_ex(SSL *ssl, const void *buf, size_t num, size_t *bytes_written); + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx); +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data); + +uint32_t SSL_get_max_early_data(const SSL *s); +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data); + +#define SSL_EARLY_DATA_NOT_SENT 0 +#define SSL_EARLY_DATA_REJECTED 1 +#define SSL_EARLY_DATA_ACCEPTED 2 +int SSL_get_early_data_status(const SSL *s); + +#define SSL_READ_EARLY_DATA_ERROR 0 +#define SSL_READ_EARLY_DATA_SUCCESS 1 +#define SSL_READ_EARLY_DATA_FINISH 2 +int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes); +int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written); +#endif + +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +int SSL_get_error(const SSL *s, int ret_code); +const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +const SSL_METHOD *SSLv23_method(void); /* SSLv3 or TLSv1.* */ +const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 or TLSv1.* */ +const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 or TLSv1.* */ + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ + +const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ + +const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ + +const SSL_METHOD *TLS_method(void); /* TLS v1.0 or later */ +const SSL_METHOD *TLS_server_method(void); /* TLS v1.0 or later */ +const SSL_METHOD *TLS_client_method(void); /* TLS v1.0 or later */ + +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ + +const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */ +const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */ +const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */ + +const SSL_METHOD *DTLS_method(void); /* DTLS v1.0 or later */ +const SSL_METHOD *DTLS_server_method(void); /* DTLS v1.0 or later */ +const SSL_METHOD *DTLS_client_method(void); /* DTLS v1.0 or later */ + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); +STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s); +STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s); + +int SSL_do_handshake(SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +int SSL_renegotiate_pending(SSL *s); +int SSL_shutdown(SSL *s); + +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +const char *SSL_alert_type_string_long(int value); +const char *SSL_alert_type_string(int value); +const char *SSL_alert_desc_string_long(int value); +const char *SSL_alert_desc_string(int value); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +int SSL_add_client_CA(SSL *ssl, X509 *x); +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +long SSL_get_default_timeout(const SSL *s); + +int SSL_library_init(void ); + +char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk); + +SSL *SSL_dup(SSL *ssl); + +X509 *SSL_get_certificate(const SSL *ssl); +/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode); +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl,int mode); +int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl,int mode); +int SSL_get_shutdown(const SSL *ssl); +int SSL_version(const SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +int SSL_CTX_load_verify_mem(SSL_CTX *ctx, void *buf, int len); +#define SSL_get0_session SSL_get_session /* just peek at pointer */ +SSL_SESSION *SSL_get_session(const SSL *ssl); +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb)(const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, int val); +int SSL_state(const SSL *ssl); +void SSL_set_state(SSL *ssl, int state); + +void SSL_set_verify_result(SSL *ssl, long v); +long SSL_get_verify_result(const SSL *ssl); + +int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_get_ex_data_X509_STORE_CTX_idx(void ); + +#define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +#define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +#define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +#define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +#define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +#define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +#define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +#define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +#define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +#define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +#define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +#define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + +/* NB: the keylength is only applicable when is_export is true */ +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl, int is_export, int keylength)); +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh)(SSL *ssl, int is_export, int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh)(SSL *ssl, int is_export, int keylength)); +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh)(SSL *ssl, int is_export, int keylength)); +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh)(SSL *ssl, int is_export, int keylength)); + +size_t SSL_get_client_random(const SSL *s, unsigned char *out, size_t max_out); +size_t SSL_get_server_random(const SSL *s, unsigned char *out, size_t max_out); + +const void *SSL_get_current_compression(SSL *s); +const void *SSL_get_current_expansion(SSL *s); + +const char *SSL_COMP_get_name(const void *comp); +void *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id, void *cm); + +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, + tls_session_ticket_ext_cb_fn cb, void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn tls_session_secret_cb, void *arg); + +void SSL_set_debug(SSL *s, int debug); +int SSL_cache_hit(SSL *s); + +/* What the "other" parameter contains in security callback */ +/* Mask for type */ +#define SSL_SECOP_OTHER_TYPE 0xffff0000 +#define SSL_SECOP_OTHER_NONE 0 +#define SSL_SECOP_OTHER_CIPHER (1 << 16) +#define SSL_SECOP_OTHER_CURVE (2 << 16) +#define SSL_SECOP_OTHER_DH (3 << 16) +#define SSL_SECOP_OTHER_PKEY (4 << 16) +#define SSL_SECOP_OTHER_SIGALG (5 << 16) +#define SSL_SECOP_OTHER_CERT (6 << 16) + +/* Indicated operation refers to peer key or certificate */ +#define SSL_SECOP_PEER 0x1000 + +/* Values for "op" parameter in security callback */ + +/* Called to filter ciphers */ +/* Ciphers client supports */ +#define SSL_SECOP_CIPHER_SUPPORTED (1 | SSL_SECOP_OTHER_CIPHER) +/* Cipher shared by client/server */ +#define SSL_SECOP_CIPHER_SHARED (2 | SSL_SECOP_OTHER_CIPHER) +/* Sanity check of cipher server selects */ +#define SSL_SECOP_CIPHER_CHECK (3 | SSL_SECOP_OTHER_CIPHER) +/* Curves supported by client */ +#define SSL_SECOP_CURVE_SUPPORTED (4 | SSL_SECOP_OTHER_CURVE) +/* Curves shared by client/server */ +#define SSL_SECOP_CURVE_SHARED (5 | SSL_SECOP_OTHER_CURVE) +/* Sanity check of curve server selects */ +#define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE) +/* Temporary DH key */ +/* + * XXX: changed in OpenSSL e2b420fdd70 to (7 | SSL_SECOP_OTHER_PKEY) + * Needs switching internal use of DH to EVP_PKEY. The code is not reachable + * from outside the library as long as we do not expose the callback in the API. + */ +#define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_DH) +/* SSL/TLS version */ +#define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE) +/* Session tickets */ +#define SSL_SECOP_TICKET (10 | SSL_SECOP_OTHER_NONE) +/* Supported signature algorithms sent to peer */ +#define SSL_SECOP_SIGALG_SUPPORTED (11 | SSL_SECOP_OTHER_SIGALG) +/* Shared signature algorithm */ +#define SSL_SECOP_SIGALG_SHARED (12 | SSL_SECOP_OTHER_SIGALG) +/* Sanity check signature algorithm allowed */ +#define SSL_SECOP_SIGALG_CHECK (13 | SSL_SECOP_OTHER_SIGALG) +/* Used to get mask of supported public key signature algorithms */ +#define SSL_SECOP_SIGALG_MASK (14 | SSL_SECOP_OTHER_SIGALG) +/* Use to see if compression is allowed */ +#define SSL_SECOP_COMPRESSION (15 | SSL_SECOP_OTHER_NONE) +/* EE key in certificate */ +#define SSL_SECOP_EE_KEY (16 | SSL_SECOP_OTHER_CERT) +/* CA key in certificate */ +#define SSL_SECOP_CA_KEY (17 | SSL_SECOP_OTHER_CERT) +/* CA digest algorithm in certificate */ +#define SSL_SECOP_CA_MD (18 | SSL_SECOP_OTHER_CERT) +/* Peer EE key in certificate */ +#define SSL_SECOP_PEER_EE_KEY (SSL_SECOP_EE_KEY | SSL_SECOP_PEER) +/* Peer CA key in certificate */ +#define SSL_SECOP_PEER_CA_KEY (SSL_SECOP_CA_KEY | SSL_SECOP_PEER) +/* Peer CA digest algorithm in certificate */ +#define SSL_SECOP_PEER_CA_MD (SSL_SECOP_CA_MD | SSL_SECOP_PEER) + +void SSL_set_security_level(SSL *ssl, int level); +int SSL_get_security_level(const SSL *ssl); + +void SSL_CTX_set_security_level(SSL_CTX *ctx, int level); +int SSL_CTX_get_security_level(const SSL_CTX *ctx); + +#if defined(LIBRESSL_HAS_QUIC) || defined(LIBRESSL_INTERNAL) +/* + * QUIC integration. + * + * QUIC acts as an underlying transport for the TLS 1.3 handshake. The following + * functions allow a QUIC implementation to serve as the underlying transport as + * described in RFC 9001. + * + * When configured for QUIC, |SSL_do_handshake| will drive the handshake as + * before, but it will not use the configured |BIO|. It will call functions on + * |SSL_QUIC_METHOD| to configure secrets and send data. If data is needed from + * the peer, it will return |SSL_ERROR_WANT_READ|. As the caller receives data + * it can decrypt, it calls |SSL_provide_quic_data|. Subsequent + * |SSL_do_handshake| calls will then consume that data and progress the + * handshake. After the handshake is complete, the caller should continue to + * call |SSL_provide_quic_data| for any post-handshake data, followed by + * |SSL_process_quic_post_handshake| to process it. It is an error to call + * |SSL_peek|, |SSL_read| and |SSL_write| in QUIC. + * + * To avoid DoS attacks, the QUIC implementation must limit the amount of data + * being queued up. The implementation can call + * |SSL_quic_max_handshake_flight_len| to get the maximum buffer length at each + * encryption level. + * + * QUIC implementations must additionally configure transport parameters with + * |SSL_set_quic_transport_params|. |SSL_get_peer_quic_transport_params| may be + * used to query the value received from the peer. This extension is handled + * as an opaque byte string, which the caller is responsible for serializing + * and parsing. See RFC 9000 section 7.4 for further details. + */ + +/* + * ssl_encryption_level_t specifies the QUIC encryption level used to transmit + * handshake messages. + */ +typedef enum ssl_encryption_level_t { + ssl_encryption_initial = 0, + ssl_encryption_early_data, + ssl_encryption_handshake, + ssl_encryption_application, +} OSSL_ENCRYPTION_LEVEL; + +/* + * ssl_quic_method_st (aka |SSL_QUIC_METHOD|) describes custom QUIC hooks. + * + * Note that we provide both the new (BoringSSL) secrets interface + * (set_read_secret/set_write_secret) along with the old interface + * (set_encryption_secrets), which quictls is still using. + * + * Since some consumers fail to use named initialisers, the order of these + * functions is important. Hopefully all of these consumers use the old version. + */ +struct ssl_quic_method_st { + /* + * set_encryption_secrets configures the read and write secrets for the + * given encryption level. This function will always be called before an + * encryption level other than |ssl_encryption_initial| is used. + * + * When reading packets at a given level, the QUIC implementation must + * send ACKs at the same level, so this function provides read and write + * secrets together. The exception is |ssl_encryption_early_data|, where + * secrets are only available in the client to server direction. The + * other secret will be NULL. The server acknowledges such data at + * |ssl_encryption_application|, which will be configured in the same + * |SSL_do_handshake| call. + * + * This function should use |SSL_get_current_cipher| to determine the TLS + * cipher suite. + */ + int (*set_encryption_secrets)(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *read_secret, const uint8_t *write_secret, + size_t secret_len); + + /* + * add_handshake_data adds handshake data to the current flight at the + * given encryption level. It returns one on success and zero on error. + * Callers should defer writing data to the network until |flush_flight| + * to better pack QUIC packets into transport datagrams. + * + * If |level| is not |ssl_encryption_initial|, this function will not be + * called before |level| is initialized with |set_write_secret|. + */ + int (*add_handshake_data)(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *data, size_t len); + + /* + * flush_flight is called when the current flight is complete and should + * be written to the transport. Note a flight may contain data at + * several encryption levels. It returns one on success and zero on + * error. + */ + int (*flush_flight)(SSL *ssl); + + /* + * send_alert sends a fatal alert at the specified encryption level. It + * returns one on success and zero on error. + * + * If |level| is not |ssl_encryption_initial|, this function will not be + * called before |level| is initialized with |set_write_secret|. + */ + int (*send_alert)(SSL *ssl, enum ssl_encryption_level_t level, + uint8_t alert); + + /* + * set_read_secret configures the read secret and cipher suite for the + * given encryption level. It returns one on success and zero to + * terminate the handshake with an error. It will be called at most once + * per encryption level. + * + * Read keys will not be released before QUIC may use them. Once a level + * has been initialized, QUIC may begin processing data from it. + * Handshake data should be passed to |SSL_provide_quic_data| and + * application data (if |level| is |ssl_encryption_early_data| or + * |ssl_encryption_application|) may be processed according to the rules + * of the QUIC protocol. + */ + int (*set_read_secret)(SSL *ssl, enum ssl_encryption_level_t level, + const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); + + /* + * set_write_secret behaves like |set_read_secret| but configures the + * write secret and cipher suite for the given encryption level. It will + * be called at most once per encryption level. + * + * Write keys will not be released before QUIC may use them. If |level| + * is |ssl_encryption_early_data| or |ssl_encryption_application|, QUIC + * may begin sending application data at |level|. + */ + int (*set_write_secret)(SSL *ssl, enum ssl_encryption_level_t level, + const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); +}; + +/* + * SSL_CTX_set_quic_method configures the QUIC hooks. This should only be + * configured with a minimum version of TLS 1.3. |quic_method| must remain valid + * for the lifetime of |ctx|. It returns one on success and zero on error. + */ +int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method); + +/* + * SSL_set_quic_method configures the QUIC hooks. This should only be + * configured with a minimum version of TLS 1.3. |quic_method| must remain valid + * for the lifetime of |ssl|. It returns one on success and zero on error. + */ +int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method); + +/* SSL_is_quic returns true if an SSL has been configured for use with QUIC. */ +int SSL_is_quic(const SSL *ssl); + +/* + * SSL_quic_max_handshake_flight_len returns returns the maximum number of bytes + * that may be received at the given encryption level. This function should be + * used to limit buffering in the QUIC implementation. See RFC 9000 section 7.5. + */ +size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, + enum ssl_encryption_level_t level); + +/* + * SSL_quic_read_level returns the current read encryption level. + */ +enum ssl_encryption_level_t SSL_quic_read_level(const SSL *ssl); + +/* + * SSL_quic_write_level returns the current write encryption level. + */ +enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl); + +/* + * SSL_provide_quic_data provides data from QUIC at a particular encryption + * level |level|. It returns one on success and zero on error. Note this + * function will return zero if the handshake is not expecting data from |level| + * at this time. The QUIC implementation should then close the connection with + * an error. + */ +int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *data, size_t len); + +/* + * SSL_process_quic_post_handshake processes any data that QUIC has provided + * after the handshake has completed. This includes NewSessionTicket messages + * sent by the server. It returns one on success and zero on error. + */ +int SSL_process_quic_post_handshake(SSL *ssl); + +/* + * SSL_set_quic_transport_params configures |ssl| to send |params| (of length + * |params_len|) in the quic_transport_parameters extension in either the + * ClientHello or EncryptedExtensions handshake message. It is an error to set + * transport parameters if |ssl| is not configured for QUIC. The buffer pointed + * to by |params| only need be valid for the duration of the call to this + * function. This function returns 1 on success and 0 on failure. + */ +int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, + size_t params_len); + +/* + * SSL_get_peer_quic_transport_params provides the caller with the value of the + * quic_transport_parameters extension sent by the peer. A pointer to the buffer + * containing the TransportParameters will be put in |*out_params|, and its + * length in |*params_len|. This buffer will be valid for the lifetime of the + * |SSL|. If no params were received from the peer, |*out_params_len| will be 0. + */ +void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, size_t *out_params_len); + +/* + * SSL_set_quic_use_legacy_codepoint configures whether to use the legacy QUIC + * extension codepoint 0xffa5 as opposed to the official value 57. This is + * unsupported in LibreSSL. + */ +void SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy); + +#endif + +void ERR_load_SSL_strings(void); + +/* Error codes for the SSL functions. */ + +/* Function codes. */ +#define SSL_F_CLIENT_CERTIFICATE 100 +#define SSL_F_CLIENT_FINISHED 167 +#define SSL_F_CLIENT_HELLO 101 +#define SSL_F_CLIENT_MASTER_KEY 102 +#define SSL_F_D2I_SSL_SESSION 103 +#define SSL_F_DO_DTLS1_WRITE 245 +#define SSL_F_DO_SSL3_WRITE 104 +#define SSL_F_DTLS1_ACCEPT 246 +#define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 +#define SSL_F_DTLS1_BUFFER_RECORD 247 +#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316 +#define SSL_F_DTLS1_CLIENT_HELLO 248 +#define SSL_F_DTLS1_CONNECT 249 +#define SSL_F_DTLS1_ENC 250 +#define SSL_F_DTLS1_GET_HELLO_VERIFY 251 +#define SSL_F_DTLS1_GET_MESSAGE 252 +#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 +#define SSL_F_DTLS1_GET_RECORD 254 +#define SSL_F_DTLS1_HANDLE_TIMEOUT 297 +#define SSL_F_DTLS1_HEARTBEAT 305 +#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 +#define SSL_F_DTLS1_PROCESS_RECORD 257 +#define SSL_F_DTLS1_READ_BYTES 258 +#define SSL_F_DTLS1_READ_FAILED 259 +#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 +#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 +#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 +#define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 +#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 +#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 +#define SSL_F_DTLS1_SEND_SERVER_HELLO 266 +#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 +#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +#define SSL_F_GET_CLIENT_FINISHED 105 +#define SSL_F_GET_CLIENT_HELLO 106 +#define SSL_F_GET_CLIENT_MASTER_KEY 107 +#define SSL_F_GET_SERVER_FINISHED 108 +#define SSL_F_GET_SERVER_HELLO 109 +#define SSL_F_GET_SERVER_VERIFY 110 +#define SSL_F_I2D_SSL_SESSION 111 +#define SSL_F_READ_N 112 +#define SSL_F_REQUEST_CERTIFICATE 113 +#define SSL_F_SERVER_FINISH 239 +#define SSL_F_SERVER_HELLO 114 +#define SSL_F_SERVER_VERIFY 240 +#define SSL_F_SSL23_ACCEPT 115 +#define SSL_F_SSL23_CLIENT_HELLO 116 +#define SSL_F_SSL23_CONNECT 117 +#define SSL_F_SSL23_GET_CLIENT_HELLO 118 +#define SSL_F_SSL23_GET_SERVER_HELLO 119 +#define SSL_F_SSL23_PEEK 237 +#define SSL_F_SSL23_READ 120 +#define SSL_F_SSL23_WRITE 121 +#define SSL_F_SSL2_ACCEPT 122 +#define SSL_F_SSL2_CONNECT 123 +#define SSL_F_SSL2_ENC_INIT 124 +#define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 +#define SSL_F_SSL2_PEEK 234 +#define SSL_F_SSL2_READ 125 +#define SSL_F_SSL2_READ_INTERNAL 236 +#define SSL_F_SSL2_SET_CERTIFICATE 126 +#define SSL_F_SSL2_WRITE 127 +#define SSL_F_SSL3_ACCEPT 128 +#define SSL_F_SSL3_ADD_CERT_TO_BUF 296 +#define SSL_F_SSL3_CALLBACK_CTRL 233 +#define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +#define SSL_F_SSL3_CHECK_CLIENT_HELLO 304 +#define SSL_F_SSL3_CLIENT_HELLO 131 +#define SSL_F_SSL3_CONNECT 132 +#define SSL_F_SSL3_CTRL 213 +#define SSL_F_SSL3_CTX_CTRL 133 +#define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +#define SSL_F_SSL3_ENC 134 +#define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 +#define SSL_F_SSL3_GET_CERT_STATUS 289 +#define SSL_F_SSL3_GET_CERT_VERIFY 136 +#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 +#define SSL_F_SSL3_GET_CLIENT_HELLO 138 +#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 +#define SSL_F_SSL3_GET_FINISHED 140 +#define SSL_F_SSL3_GET_KEY_EXCHANGE 141 +#define SSL_F_SSL3_GET_MESSAGE 142 +#define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 +#define SSL_F_SSL3_GET_NEXT_PROTO 306 +#define SSL_F_SSL3_GET_RECORD 143 +#define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 +#define SSL_F_SSL3_GET_SERVER_DONE 145 +#define SSL_F_SSL3_GET_SERVER_HELLO 146 +#define SSL_F_SSL3_HANDSHAKE_MAC 285 +#define SSL_F_SSL3_NEW_SESSION_TICKET 287 +#define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +#define SSL_F_SSL3_PEEK 235 +#define SSL_F_SSL3_READ_BYTES 148 +#define SSL_F_SSL3_READ_N 149 +#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 +#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 +#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 +#define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 +#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +#define SSL_F_SSL3_SEND_SERVER_HELLO 242 +#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 +#define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +#define SSL_F_SSL3_SETUP_READ_BUFFER 156 +#define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +#define SSL_F_SSL3_WRITE_BYTES 158 +#define SSL_F_SSL3_WRITE_PENDING 159 +#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +#define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +#define SSL_F_SSL_BAD_METHOD 160 +#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +#define SSL_F_SSL_CERT_DUP 221 +#define SSL_F_SSL_CERT_INST 222 +#define SSL_F_SSL_CERT_INSTANTIATE 214 +#define SSL_F_SSL_CERT_NEW 162 +#define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +#define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +#define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +#define SSL_F_SSL_CLEAR 164 +#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +#define SSL_F_SSL_CREATE_CIPHER_LIST 166 +#define SSL_F_SSL_CTRL 232 +#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +#define SSL_F_SSL_CTX_MAKE_PROFILES 309 +#define SSL_F_SSL_CTX_NEW 169 +#define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +#define SSL_F_SSL_CTX_SET_PURPOSE 226 +#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +#define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +#define SSL_F_SSL_CTX_SET_TRUST 229 +#define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +#define SSL_F_SSL_DO_HANDSHAKE 180 +#define SSL_F_SSL_GET_NEW_SESSION 181 +#define SSL_F_SSL_GET_PREV_SESSION 217 +#define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +#define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 +#define SSL_F_SSL_GET_SIGN_PKEY 183 +#define SSL_F_SSL_INIT_WBIO_BUFFER 184 +#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +#define SSL_F_SSL_NEW 186 +#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +#define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +#define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +#define SSL_F_SSL_PEEK 270 +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 +#define SSL_F_SSL_READ 223 +#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +#define SSL_F_SSL_SESSION_NEW 189 +#define SSL_F_SSL_SESSION_PRINT_FP 190 +#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +#define SSL_F_SSL_SESS_CERT_NEW 225 +#define SSL_F_SSL_SET_CERT 191 +#define SSL_F_SSL_SET_CIPHER_LIST 271 +#define SSL_F_SSL_SET_FD 192 +#define SSL_F_SSL_SET_PKEY 193 +#define SSL_F_SSL_SET_PURPOSE 227 +#define SSL_F_SSL_SET_RFD 194 +#define SSL_F_SSL_SET_SESSION 195 +#define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +#define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +#define SSL_F_SSL_SET_TRUST 228 +#define SSL_F_SSL_SET_WFD 196 +#define SSL_F_SSL_SHUTDOWN 224 +#define SSL_F_SSL_SRP_CTX_INIT 313 +#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 +#define SSL_F_SSL_UNDEFINED_FUNCTION 197 +#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +#define SSL_F_SSL_USE_CERTIFICATE 198 +#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +#define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +#define SSL_F_SSL_USE_PRIVATEKEY 201 +#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +#define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +#define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +#define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +#define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +#define SSL_F_SSL_WRITE 208 +#define SSL_F_TLS1_AEAD_CTX_INIT 339 +#define SSL_F_TLS1_CERT_VERIFY_MAC 286 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD 340 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER 338 +#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 +#define SSL_F_TLS1_ENC 210 +#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +#define SSL_F_TLS1_HEARTBEAT 315 +#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +#define SSL_F_TLS1_PRF 284 +#define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +#define SSL_F_WRITE_PENDING 212 + +/* Reason codes. */ +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +#define SSL_R_BAD_ALERT_RECORD 101 +#define SSL_R_BAD_AUTHENTICATION_TYPE 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_CHECKSUM 104 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +#define SSL_R_BAD_DECOMPRESSION 107 +#define SSL_R_BAD_DH_G_LENGTH 108 +#define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 +#define SSL_R_BAD_DH_P_LENGTH 110 +#define SSL_R_BAD_DIGEST_LENGTH 111 +#define SSL_R_BAD_DSA_SIGNATURE 112 +#define SSL_R_BAD_ECC_CERT 304 +#define SSL_R_BAD_ECDSA_SIGNATURE 305 +#define SSL_R_BAD_ECPOINT 306 +#define SSL_R_BAD_HANDSHAKE_LENGTH 332 +#define SSL_R_BAD_HELLO_REQUEST 105 +#define SSL_R_BAD_LENGTH 271 +#define SSL_R_BAD_MAC_DECODE 113 +#define SSL_R_BAD_MAC_LENGTH 333 +#define SSL_R_BAD_MESSAGE_TYPE 114 +#define SSL_R_BAD_PACKET_LENGTH 115 +#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 +#define SSL_R_BAD_RESPONSE_ARGUMENT 117 +#define SSL_R_BAD_RSA_DECRYPT 118 +#define SSL_R_BAD_RSA_ENCRYPT 119 +#define SSL_R_BAD_RSA_E_LENGTH 120 +#define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +#define SSL_R_BAD_RSA_SIGNATURE 122 +#define SSL_R_BAD_SIGNATURE 123 +#define SSL_R_BAD_SRP_A_LENGTH 347 +#define SSL_R_BAD_SRP_B_LENGTH 348 +#define SSL_R_BAD_SRP_G_LENGTH 349 +#define SSL_R_BAD_SRP_N_LENGTH 350 +#define SSL_R_BAD_SRP_S_LENGTH 351 +#define SSL_R_BAD_SRTP_MKI_VALUE 352 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +#define SSL_R_BAD_SSL_FILETYPE 124 +#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +#define SSL_R_BAD_STATE 126 +#define SSL_R_BAD_WRITE_RETRY 127 +#define SSL_R_BIO_NOT_SET 128 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +#define SSL_R_BN_LIB 130 +#define SSL_R_CA_DN_LENGTH_MISMATCH 131 +#define SSL_R_CA_DN_TOO_LONG 132 +#define SSL_R_CA_KEY_TOO_SMALL 397 +#define SSL_R_CA_MD_TOO_WEAK 398 +#define SSL_R_CCS_RECEIVED_EARLY 133 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +#define SSL_R_CERT_LENGTH_MISMATCH 135 +#define SSL_R_CHALLENGE_IS_DIFFERENT 136 +#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +#define SSL_R_CIPHER_COMPRESSION_UNAVAILABLE 371 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +#define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_CLIENTHELLO_TLSEXT 226 +#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +#define SSL_R_COMPRESSION_DISABLED 343 +#define SSL_R_COMPRESSION_FAILURE 141 +#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +#define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +#define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 +#define SSL_R_CONNECTION_TYPE_NOT_SET 144 +#define SSL_R_COOKIE_MISMATCH 308 +#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +#define SSL_R_DATA_LENGTH_TOO_LONG 146 +#define SSL_R_DECRYPTION_FAILED 147 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +#define SSL_R_DH_KEY_TOO_SMALL 394 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +#define SSL_R_DIGEST_CHECK_FAILED 149 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +#define SSL_R_DUPLICATE_COMPRESSION_ID 309 +#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 +#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 +#define SSL_R_EE_KEY_TOO_SMALL 399 +#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_ILLEGAL_PADDING 283 +#define SSL_R_INAPPROPRIATE_FALLBACK 373 +#define SSL_R_INCONSISTENT_COMPRESSION 340 +#define SSL_R_INVALID_CHALLENGE_LENGTH 158 +#define SSL_R_INVALID_COMMAND 280 +#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +#define SSL_R_INVALID_PURPOSE 278 +#define SSL_R_INVALID_SRP_USERNAME 357 +#define SSL_R_INVALID_STATUS_RESPONSE 328 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +#define SSL_R_INVALID_TRUST 279 +#define SSL_R_KEY_ARG_TOO_LONG 284 +#define SSL_R_KRB5 285 +#define SSL_R_KRB5_C_CC_PRINC 286 +#define SSL_R_KRB5_C_GET_CRED 287 +#define SSL_R_KRB5_C_INIT 288 +#define SSL_R_KRB5_C_MK_REQ 289 +#define SSL_R_KRB5_S_BAD_TICKET 290 +#define SSL_R_KRB5_S_INIT 291 +#define SSL_R_KRB5_S_RD_REQ 292 +#define SSL_R_KRB5_S_TKT_EXPIRED 293 +#define SSL_R_KRB5_S_TKT_NYV 294 +#define SSL_R_KRB5_S_TKT_SKEW 295 +#define SSL_R_LENGTH_MISMATCH 159 +#define SSL_R_LENGTH_TOO_SHORT 160 +#define SSL_R_LIBRARY_BUG 274 +#define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +#define SSL_R_MESSAGE_TOO_LONG 296 +#define SSL_R_MISSING_DH_DSA_CERT 162 +#define SSL_R_MISSING_DH_KEY 163 +#define SSL_R_MISSING_DH_RSA_CERT 164 +#define SSL_R_MISSING_DSA_SIGNING_CERT 165 +#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 +#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 +#define SSL_R_MISSING_RSA_CERTIFICATE 168 +#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +#define SSL_R_MISSING_RSA_SIGNING_CERT 170 +#define SSL_R_MISSING_SRP_PARAM 358 +#define SSL_R_MISSING_TMP_DH_KEY 171 +#define SSL_R_MISSING_TMP_ECDH_KEY 311 +#define SSL_R_MISSING_TMP_RSA_KEY 172 +#define SSL_R_MISSING_TMP_RSA_PKEY 173 +#define SSL_R_MISSING_VERIFY_MESSAGE 174 +#define SSL_R_MULTIPLE_SGC_RESTARTS 346 +#define SSL_R_NON_SSLV2_INITIAL_PACKET 175 +#define SSL_R_NO_APPLICATION_PROTOCOL 235 +#define SSL_R_NO_CERTIFICATES_RETURNED 176 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +#define SSL_R_NO_CERTIFICATE_RETURNED 178 +#define SSL_R_NO_CERTIFICATE_SET 179 +#define SSL_R_NO_CERTIFICATE_SPECIFIED 180 +#define SSL_R_NO_CIPHERS_AVAILABLE 181 +#define SSL_R_NO_CIPHERS_PASSED 182 +#define SSL_R_NO_CIPHERS_SPECIFIED 183 +#define SSL_R_NO_CIPHER_LIST 184 +#define SSL_R_NO_CIPHER_MATCH 185 +#define SSL_R_NO_CLIENT_CERT_METHOD 331 +#define SSL_R_NO_CLIENT_CERT_RECEIVED 186 +#define SSL_R_NO_COMPRESSION_SPECIFIED 187 +#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +#define SSL_R_NO_METHOD_SPECIFIED 188 +#define SSL_R_NO_PRIVATEKEY 189 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +#define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +#define SSL_R_NO_PUBLICKEY 192 +#define SSL_R_NO_RENEGOTIATION 339 +#define SSL_R_NO_REQUIRED_DIGEST 324 +#define SSL_R_NO_SHARED_CIPHER 193 +#define SSL_R_NO_SRTP_PROFILES 359 +#define SSL_R_NO_VERIFY_CALLBACK 194 +#define SSL_R_NULL_SSL_CTX 195 +#define SSL_R_NULL_SSL_METHOD_PASSED 196 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +#define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +#define SSL_R_PACKET_LENGTH_TOO_LONG 198 +#define SSL_R_PARSE_TLSEXT 227 +#define SSL_R_PATH_TOO_LONG 270 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +#define SSL_R_PEER_ERROR 200 +#define SSL_R_PEER_ERROR_CERTIFICATE 201 +#define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 +#define SSL_R_PEER_ERROR_NO_CIPHER 203 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 +#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 +#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +#define SSL_R_PSK_NO_CLIENT_CB 224 +#define SSL_R_PSK_NO_SERVER_CB 225 +#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 +#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 +#define SSL_R_PUBLIC_KEY_NOT_RSA 210 +#define SSL_R_READ_BIO_NOT_SET 211 +#define SSL_R_READ_TIMEOUT_EXPIRED 312 +#define SSL_R_READ_WRONG_PACKET_TYPE 212 +#define SSL_R_RECORD_LENGTH_MISMATCH 213 +#define SSL_R_RECORD_TOO_LARGE 214 +#define SSL_R_RECORD_TOO_SMALL 298 +#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +#define SSL_R_RENEGOTIATION_MISMATCH 337 +#define SSL_R_REQUIRED_CIPHER_MISSING 215 +#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 +#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 +#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 +#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +#define SSL_R_SERVERHELLO_TLSEXT 275 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +#define SSL_R_SHORT_READ 219 +#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +#define SSL_R_SRP_A_CALC 361 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +#define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +#define SSL_R_SSL_HANDSHAKE_FAILURE 229 +#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +#define SSL_R_SSL_SESSION_ID_CONFLICT 302 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 +#define SSL_R_SSL_SESSION_ID_TOO_LONG 408 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +#define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +#define SSL_R_TLS_HEARTBEAT_PENDING 366 +#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 +#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 +#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 +#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 +#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 +#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 +#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +#define SSL_R_UNEXPECTED_MESSAGE 244 +#define SSL_R_UNEXPECTED_RECORD 245 +#define SSL_R_UNINITIALIZED 276 +#define SSL_R_UNKNOWN_ALERT_TYPE 246 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +#define SSL_R_UNKNOWN_CIPHER_TYPE 249 +#define SSL_R_UNKNOWN_DIGEST 368 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +#define SSL_R_UNKNOWN_PKEY_TYPE 251 +#define SSL_R_UNKNOWN_PROTOCOL 252 +#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 +#define SSL_R_UNKNOWN_SSL_VERSION 254 +#define SSL_R_UNKNOWN_STATE 255 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +#define SSL_R_UNSUPPORTED_CIPHER 256 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +#define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +#define SSL_R_UNSUPPORTED_PROTOCOL 258 +#define SSL_R_UNSUPPORTED_SSL_VERSION 259 +#define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +#define SSL_R_VERSION_TOO_LOW 396 +#define SSL_R_WRITE_BIO_NOT_SET 260 +#define SSL_R_WRONG_CIPHER_RETURNED 261 +#define SSL_R_WRONG_CURVE 378 +#define SSL_R_WRONG_MESSAGE_TYPE 262 +#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 +#define SSL_R_WRONG_SIGNATURE_LENGTH 264 +#define SSL_R_WRONG_SIGNATURE_SIZE 265 +#define SSL_R_WRONG_SIGNATURE_TYPE 370 +#define SSL_R_WRONG_SSL_VERSION 266 +#define SSL_R_WRONG_VERSION_NUMBER 267 +#define SSL_R_X509_LIB 268 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 +#define SSL_R_PEER_BEHAVING_BADLY 666 +#define SSL_R_QUIC_INTERNAL_ERROR 667 +#define SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED 668 +#define SSL_R_UNKNOWN 999 + +/* + * OpenSSL compatible OPENSSL_INIT options + */ + +/* + * These are provided for compatibility, but have no effect + * on how LibreSSL is initialized. + */ +#define OPENSSL_INIT_LOAD_SSL_STRINGS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_SSL_DEFAULT _OPENSSL_INIT_FLAG_NOOP + +int OPENSSL_init_ssl(uint64_t opts, const void *settings); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ssl2.h b/Libraries/libressl/include/openssl/ssl2.h new file mode 100644 index 000000000..3a8d30072 --- /dev/null +++ b/Libraries/libressl/include/openssl/ssl2.h @@ -0,0 +1,153 @@ +/* $OpenBSD: ssl2.h,v 1.12 2014/12/14 15:30:50 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL2_H +#define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Protocol Version Codes */ +#define SSL2_VERSION 0x0002 +#define SSL2_VERSION_MAJOR 0x00 +#define SSL2_VERSION_MINOR 0x02 +/* #define SSL2_CLIENT_VERSION 0x0002 */ +/* #define SSL2_SERVER_VERSION 0x0002 */ + +/* Protocol Message Codes */ +#define SSL2_MT_ERROR 0 +#define SSL2_MT_CLIENT_HELLO 1 +#define SSL2_MT_CLIENT_MASTER_KEY 2 +#define SSL2_MT_CLIENT_FINISHED 3 +#define SSL2_MT_SERVER_HELLO 4 +#define SSL2_MT_SERVER_VERIFY 5 +#define SSL2_MT_SERVER_FINISHED 6 +#define SSL2_MT_REQUEST_CERTIFICATE 7 +#define SSL2_MT_CLIENT_CERTIFICATE 8 + +/* Error Message Codes */ +#define SSL2_PE_UNDEFINED_ERROR 0x0000 +#define SSL2_PE_NO_CIPHER 0x0001 +#define SSL2_PE_NO_CERTIFICATE 0x0002 +#define SSL2_PE_BAD_CERTIFICATE 0x0004 +#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 + +/* Cipher Kind Values */ +#define SSL2_CK_NULL_WITH_MD5 0x02000000 /* v3 */ +#define SSL2_CK_RC4_128_WITH_MD5 0x02010080 +#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 +#define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 +#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 +#define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 +#define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 +#define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140 /* v3 */ +#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 +#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0 /* v3 */ +#define SSL2_CK_RC4_64_WITH_MD5 0x02080080 /* MS hack */ + +#define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800 /* SSLeay */ +#define SSL2_CK_NULL 0x02ff0810 /* SSLeay */ + +#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" +#define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" +#define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" +#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" +#define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" +#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" +#define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" +#define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" +#define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" +#define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" + +#define SSL2_TXT_NULL "NULL" + +/* Flags for the SSL_CIPHER.algorithm2 field */ +#define SSL2_CF_5_BYTE_ENC 0x01 +#define SSL2_CF_8_BYTE_ENC 0x02 + +/* Certificate Type Codes */ +#define SSL2_CT_X509_CERTIFICATE 0x01 + +/* Authentication Type Code */ +#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 + +#define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 + +/* Upper/Lower Bounds */ +#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 +#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u /* 2^15-1 */ +#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383 /* 2^14-1 */ + +#define SSL2_CHALLENGE_LENGTH 16 +/*#define SSL2_CHALLENGE_LENGTH 32 */ +#define SSL2_MIN_CHALLENGE_LENGTH 16 +#define SSL2_MAX_CHALLENGE_LENGTH 32 +#define SSL2_CONNECTION_ID_LENGTH 16 +#define SSL2_MAX_CONNECTION_ID_LENGTH 16 +#define SSL2_SSL_SESSION_ID_LENGTH 16 +#define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 +#define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 +#define SSL2_MAX_KEY_MATERIAL_LENGTH 24 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ssl23.h b/Libraries/libressl/include/openssl/ssl23.h new file mode 100644 index 000000000..570e4b017 --- /dev/null +++ b/Libraries/libressl/include/openssl/ssl23.h @@ -0,0 +1,82 @@ +/* $OpenBSD: ssl23.h,v 1.4 2014/12/14 15:30:50 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL23_H +#define HEADER_SSL23_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*client */ +/* write to server */ +#define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) +#define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) +/* read from server */ +#define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) +#define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) + +/* server */ +/* read from client */ +#define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) +#define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ssl3.h b/Libraries/libressl/include/openssl/ssl3.h new file mode 100644 index 000000000..6c6cc2ad2 --- /dev/null +++ b/Libraries/libressl/include/openssl/ssl3.h @@ -0,0 +1,455 @@ +/* $OpenBSD: ssl3.h,v 1.57 2021/09/10 14:49:13 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_SSL3_H +#define HEADER_SSL3_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* TLS_EMPTY_RENEGOTIATION_INFO_SCSV from RFC 5746. */ +#define SSL3_CK_SCSV 0x030000FF + +/* TLS_FALLBACK_SCSV from draft-ietf-tls-downgrade-scsv-03. */ +#define SSL3_CK_FALLBACK_SCSV 0x03005600 + +#define SSL3_CK_RSA_NULL_MD5 0x03000001 +#define SSL3_CK_RSA_NULL_SHA 0x03000002 +#define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +#define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +#define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +#define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +#define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +#define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +#define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +#define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +#define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +#define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +#define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +#define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +#define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +#define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +#define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +#define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +#define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +/* VRS Additional Kerberos5 entries + */ +#define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +#define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +#define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +#define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +#define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +#define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +#define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +#define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +#define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +#define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +#define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +#define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +#define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B + +#define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +#define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +#define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +#define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +#define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +#define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +#define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +#define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +#define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +#define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +#define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +#define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +#define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +#define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +#define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + +#define SSL3_SSL_SESSION_ID_LENGTH 32 +#define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +#define SSL3_MASTER_SECRET_SIZE 48 +#define SSL3_RANDOM_SIZE 32 +#define SSL3_SEQUENCE_SIZE 8 +#define SSL3_SESSION_ID_SIZE 32 +#define SSL3_CIPHER_VALUE_SIZE 2 + +#define SSL3_RT_HEADER_LENGTH 5 +#define SSL3_HM_HEADER_LENGTH 4 + +#define SSL3_ALIGN_PAYLOAD 8 + +/* This is the maximum MAC (digest) size used by the SSL library. + * Currently maximum of 20 is used by SHA1, but we reserve for + * future extension for 512-bit hashes. + */ + +#define SSL3_RT_MAX_MD_SIZE 64 + +/* Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +#define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +#define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* The standards give a maximum encryption overhead of 1024 bytes. + * In practice the value is lower than this. The overhead is the maximum + * number of padding bytes (256) plus the mac size. + */ +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* OpenSSL currently only uses a padding length of at most one block so + * the send overhead is smaller. + */ + +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +#define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +#define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +#define SSL3_VERSION 0x0300 +#define SSL3_VERSION_MAJOR 0x03 +#define SSL3_VERSION_MINOR 0x00 + +#define SSL3_RT_CHANGE_CIPHER_SPEC 20 +#define SSL3_RT_ALERT 21 +#define SSL3_RT_HANDSHAKE 22 +#define SSL3_RT_APPLICATION_DATA 23 + +#define SSL3_AL_WARNING 1 +#define SSL3_AL_FATAL 2 + +#ifndef LIBRESSL_INTERNAL +#define SSL3_AD_CLOSE_NOTIFY 0 +#define SSL3_AD_UNEXPECTED_MESSAGE 10 /* fatal */ +#define SSL3_AD_BAD_RECORD_MAC 20 /* fatal */ +#define SSL3_AD_DECOMPRESSION_FAILURE 30 /* fatal */ +#define SSL3_AD_HANDSHAKE_FAILURE 40 /* fatal */ +#define SSL3_AD_NO_CERTIFICATE 41 +#define SSL3_AD_BAD_CERTIFICATE 42 +#define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +#define SSL3_AD_CERTIFICATE_REVOKED 44 +#define SSL3_AD_CERTIFICATE_EXPIRED 45 +#define SSL3_AD_CERTIFICATE_UNKNOWN 46 +#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */ +#endif + +#define TLS1_HB_REQUEST 1 +#define TLS1_HB_RESPONSE 2 + +#define SSL3_CT_RSA_SIGN 1 +#define SSL3_CT_DSS_SIGN 2 +#define SSL3_CT_RSA_FIXED_DH 3 +#define SSL3_CT_DSS_FIXED_DH 4 +#define SSL3_CT_RSA_EPHEMERAL_DH 5 +#define SSL3_CT_DSS_EPHEMERAL_DH 6 +#define SSL3_CT_FORTEZZA_DMS 20 +/* SSL3_CT_NUMBER is used to size arrays and it must be large + * enough to contain all of the cert types defined either for + * SSLv3 and TLSv1. + */ +#define SSL3_CT_NUMBER 13 + +#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 +#define TLS1_FLAGS_FREEZE_TRANSCRIPT 0x0020 +#define SSL3_FLAGS_CCS_OK 0x0080 + +/* SSLv3 */ +/*client */ +/* extra state */ +#define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) +/* write to server */ +#define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) +#define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) +/* read from server */ +#define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) +#define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) +#define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) +/* write to server */ +#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) +#define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) +#define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) +#define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) +#define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) +#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) +/* read from server */ +#define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) +#define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) +#define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) +#define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) + +/* server */ +/* extra state */ +#define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) +/* read from client */ +/* Do not change the number values, they do matter */ +#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +/* write to client */ +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) +#define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) +#define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) +/* read from client */ +#define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) +#define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) +#define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +#define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) +/* write to client */ +#define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) + +#define SSL3_MT_HELLO_REQUEST 0 +#define SSL3_MT_CLIENT_HELLO 1 +#define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEWSESSION_TICKET 4 +#define SSL3_MT_CERTIFICATE 11 +#define SSL3_MT_SERVER_KEY_EXCHANGE 12 +#define SSL3_MT_CERTIFICATE_REQUEST 13 +#define SSL3_MT_SERVER_DONE 14 +#define SSL3_MT_CERTIFICATE_VERIFY 15 +#define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +#define SSL3_MT_FINISHED 20 +#define SSL3_MT_CERTIFICATE_STATUS 22 + +#define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +#define SSL3_MT_CCS 1 + +#ifndef LIBRESSL_INTERNAL +/* These are used when changing over to a new cipher */ +#define SSL3_CC_READ 0x01 +#define SSL3_CC_WRITE 0x02 +#define SSL3_CC_CLIENT 0x10 +#define SSL3_CC_SERVER 0x20 +#define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +#define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +#define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +#define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/stack.h b/Libraries/libressl/include/openssl/stack.h new file mode 100644 index 000000000..6bea6348f --- /dev/null +++ b/Libraries/libressl/include/openssl/stack.h @@ -0,0 +1,107 @@ +/* $OpenBSD: stack.h,v 1.9 2014/06/12 15:49:30 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_STACK_H +#define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st { + int num; + char **data; + int sorted; + + int num_alloc; + int (*comp)(const void *, const void *); +} _STACK; /* Use STACK_OF(...) instead */ + +#define M_sk_num(sk) ((sk) ? (sk)->num:-1) +#define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) + +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); + +void *sk_set(_STACK *, int, void *); + +_STACK *sk_new(int (*cmp)(const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func)(void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))( + const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/tls1.h b/Libraries/libressl/include/openssl/tls1.h new file mode 100644 index 000000000..2bdbd3c18 --- /dev/null +++ b/Libraries/libressl/include/openssl/tls1.h @@ -0,0 +1,780 @@ +/* $OpenBSD: tls1.h,v 1.56 2022/07/17 14:39:09 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_TLS1_H +#define HEADER_TLS1_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define OPENSSL_TLS_SECURITY_LEVEL 1 + +#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define TLS1_3_VERSION 0x0304 +#endif + +#define TLS1_2_VERSION 0x0303 +#define TLS1_2_VERSION_MAJOR 0x03 +#define TLS1_2_VERSION_MINOR 0x03 + +#define TLS1_1_VERSION 0x0302 +#define TLS1_1_VERSION_MAJOR 0x03 +#define TLS1_1_VERSION_MINOR 0x02 + +#define TLS1_VERSION 0x0301 +#define TLS1_VERSION_MAJOR 0x03 +#define TLS1_VERSION_MINOR 0x01 + +#ifndef LIBRESSL_INTERNAL +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 /* fatal */ +#define TLS1_AD_ACCESS_DENIED 49 /* fatal */ +#define TLS1_AD_DECODE_ERROR 50 /* fatal */ +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICTION 60 /* fatal */ +#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ +#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ +#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ +/* Code 86 from RFC 7507. */ +#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */ +#define TLS1_AD_USER_CANCELLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 +/* Codes 110-114 from RFC 3546. */ +#define TLS1_AD_UNSUPPORTED_EXTENSION 110 +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +#define TLS1_AD_UNRECOGNIZED_NAME 112 +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +/* Code 115 from RFC 4279. */ +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ +#endif + +/* + * TLS ExtensionType values. + * + * https://www.iana.org/assignments/tls-extensiontype-values/ + */ + +/* ExtensionType values from RFC 3546, RFC 4366 and RFC 6066. */ +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_max_fragment_length 1 +#define TLSEXT_TYPE_client_certificate_url 2 +#define TLSEXT_TYPE_trusted_ca_keys 3 +#define TLSEXT_TYPE_truncated_hmac 4 +#define TLSEXT_TYPE_status_request 5 + +/* ExtensionType values from RFC 4681. */ +#define TLSEXT_TYPE_user_mapping 6 + +/* ExtensionType values from RFC 5878. */ +#define TLSEXT_TYPE_client_authz 7 +#define TLSEXT_TYPE_server_authz 8 + +/* ExtensionType values from RFC 6091. */ +#define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC 7919. */ +#define TLSEXT_TYPE_supported_groups 10 + +/* ExtensionType values from RFC 4492. */ +#ifndef LIBRESSL_INTERNAL +#define TLSEXT_TYPE_elliptic_curves TLSEXT_TYPE_supported_groups +#endif +#define TLSEXT_TYPE_ec_point_formats 11 + +/* ExtensionType value from RFC 5054. */ +#define TLSEXT_TYPE_srp 12 + +/* ExtensionType value from RFC 5246/RFC 8446. */ +#define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC 5764. */ +#define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC 5620. */ +#define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC 7301. */ +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* ExtensionType value from RFC 7685. */ +#define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC 4507. */ +#define TLSEXT_TYPE_session_ticket 35 + +/* ExtensionType values from RFC 8446 section 4.2 */ +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define TLSEXT_TYPE_pre_shared_key 41 +#define TLSEXT_TYPE_early_data 42 +#define TLSEXT_TYPE_supported_versions 43 +#define TLSEXT_TYPE_cookie 44 +#define TLSEXT_TYPE_psk_key_exchange_modes 45 +#define TLSEXT_TYPE_certificate_authorities 47 +#define TLSEXT_TYPE_oid_filters 48 +#define TLSEXT_TYPE_post_handshake_auth 49 +#define TLSEXT_TYPE_signature_algorithms_cert 50 +#define TLSEXT_TYPE_key_share 51 +#endif + +/* ExtensionType value from RFC 9001 section 8.2 */ +#if defined(LIBRESSL_HAS_QUIC) || defined(LIBRESSL_INTERNAL) +#define TLSEXT_TYPE_quic_transport_parameters 57 +#endif + +/* + * TLS 1.3 extension names from OpenSSL, where they decided to use a different + * name from that given in RFC 8446. + */ +#if defined(LIBRESSL_HAS_TLS1_3) +#define TLSEXT_TYPE_psk TLSEXT_TYPE_pre_shared_key +#define TLSEXT_TYPE_psk_kex_modes TLSEXT_TYPE_psk_key_exchange_modes +#endif + +/* Temporary extension type */ +#define TLSEXT_TYPE_renegotiate 0xff01 + +/* NameType value from RFC 3546. */ +#define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC 3546 */ +#define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC 4492. */ +#define TLSEXT_ECPOINTFORMAT_first 0 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +#define TLSEXT_ECPOINTFORMAT_last 2 + +#define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type); +int SSL_get_servername_type(const SSL *s); +/* SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) + * + * It returns 1 on success and zero otherwise. + */ +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *p, size_t plen, + int use_context); + +#define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +#define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +#define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +#define SSL_get_tlsext_status_type(ssl) \ +SSL_ctrl(ssl, SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE, 0, NULL) + +#define SSL_set_tlsext_status_type(ssl, type) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) + +#define SSL_get_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +#define SSL_set_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +#define SSL_get_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +#define SSL_set_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +#define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) + +#define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) + +#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 + +#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) +#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) + +#define SSL_CTX_get_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) +#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) + +#define SSL_CTX_get_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG,0,(void *)arg) +#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0,(void *)arg) + +#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) + +/* PSK ciphersuites from RFC 4279. */ +#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt + * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see + * s3_lib.c). We actually treat them like SSL 3.0 ciphers, which we probably + * shouldn't. Note that the first two are actually not in the IDs. */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +/* AES ciphersuites from RFC 3268. */ + +#define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +#define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +#define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +#define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +#define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +#define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +#define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC 4132. */ +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +#define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +#define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC 4132. */ +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC 4162. */ +#define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +#define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +#define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +#define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +#define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +#define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC 5288. */ +#define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +#define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +#define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +#define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +#define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +#define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +#define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +#define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +#define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +#define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +#define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +#define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BA +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BB +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BC +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BD +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BE +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256 0x030000BF + +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C0 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C1 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C2 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C3 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C4 +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256 0x030000C5 + +/* TLS 1.3 cipher suites from RFC 8446 appendix B.4. */ +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define TLS1_3_CK_AES_128_GCM_SHA256 0x03001301 +#define TLS1_3_CK_AES_256_GCM_SHA384 0x03001302 +#define TLS1_3_CK_CHACHA20_POLY1305_SHA256 0x03001303 +#define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 +#define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 +#endif + +/* ECC ciphersuites from RFC 4492. */ +#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +#define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054. */ +#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC 5289. */ +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +#define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +#define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC 5289. */ +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* ChaCha20-Poly1305 based ciphersuites. */ +#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CCA8 +#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CCA9 +#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CCAA + +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +/* AES ciphersuites from RFC 3268. */ +#define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +#define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +#define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +#define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */ +#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279. */ +#define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +/* SRP ciphersuite from RFC 5054. */ +#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC 4132. */ +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256 "CAMELLIA128-SHA256" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DH-DSS-CAMELLIA128-SHA256" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DH-RSA-CAMELLIA128-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DHE-DSS-CAMELLIA128-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DHE-RSA-CAMELLIA128-SHA256" +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256 "ADH-CAMELLIA128-SHA256" + +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256 "CAMELLIA256-SHA256" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DH-DSS-CAMELLIA256-SHA256" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DH-RSA-CAMELLIA256-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DHE-DSS-CAMELLIA256-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DHE-RSA-CAMELLIA256-SHA256" +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256 "ADH-CAMELLIA256-SHA256" + +/* SEED ciphersuites from RFC 4162. */ +#define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +#define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +#define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites. */ +#define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +#define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC 5288. */ +#define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +#define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +#define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* ECDH HMAC based ciphersuites from RFC 5289. */ +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC 5289. */ +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +/* ChaCha20-Poly1305 based ciphersuites. */ +#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" +#define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" + +/* TLS 1.3 cipher suites from RFC 8446 appendix B.4. */ +#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) +#define TLS1_3_TXT_AES_128_GCM_SHA256 "AEAD-AES128-GCM-SHA256" +#define TLS1_3_TXT_AES_256_GCM_SHA384 "AEAD-AES256-GCM-SHA384" +#define TLS1_3_TXT_CHACHA20_POLY1305_SHA256 "AEAD-CHACHA20-POLY1305-SHA256" +#define TLS1_3_TXT_AES_128_CCM_SHA256 "AEAD-AES128-CCM-SHA256" +#define TLS1_3_TXT_AES_128_CCM_8_SHA256 "AEAD-AES128-CCM-8-SHA256" + +#define TLS1_3_RFC_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" +#define TLS1_3_RFC_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" +#define TLS1_3_RFC_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +#define TLS1_3_RFC_AES_128_CCM_SHA256 "TLS_AES_128_CCM_SHA256" +#define TLS1_3_RFC_AES_128_CCM_8_SHA256 "TLS_AES_128_CCM_8_SHA256" +#endif + +#define TLS_CT_RSA_SIGN 1 +#define TLS_CT_DSS_SIGN 2 +#define TLS_CT_RSA_FIXED_DH 3 +#define TLS_CT_DSS_FIXED_DH 4 +#define TLS_CT_GOST94_SIGN 21 +#define TLS_CT_GOST01_SIGN 22 +#define TLS_CT_ECDSA_SIGN 64 +#define TLS_CT_RSA_FIXED_ECDH 65 +#define TLS_CT_ECDSA_FIXED_ECDH 66 +#define TLS_CT_GOST12_256_SIGN 67 +#define TLS_CT_GOST12_512_SIGN 68 +#define TLS_CT_GOST12_256_SIGN_COMPAT 238 /* pre-IANA, for compat */ +#define TLS_CT_GOST12_512_SIGN_COMPAT 239 /* pre-IANA, for compat */ +/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) */ +#define TLS_CT_NUMBER 13 + +#define TLS1_FINISH_MAC_LENGTH 12 + +#define TLS_MD_MAX_CONST_SIZE 20 +#define TLS_MD_CLIENT_FINISH_CONST "client finished" +#define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_FINISH_CONST "server finished" +#define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_KEY_EXPANSION_CONST "key expansion" +#define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +#define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_IV_BLOCK_CONST "IV block" +#define TLS_MD_IV_BLOCK_CONST_SIZE 8 +#define TLS_MD_MASTER_SECRET_CONST "master secret" +#define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ts.h b/Libraries/libressl/include/openssl/ts.h new file mode 100644 index 000000000..0d5de6223 --- /dev/null +++ b/Libraries/libressl/include/openssl/ts.h @@ -0,0 +1,665 @@ +/* $OpenBSD: ts.h,v 1.22 2023/07/28 09:53:55 tb Exp $ */ +/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL + * project 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_TS_H +#define HEADER_TS_H + +#include + +#ifndef OPENSSL_NO_BUFFER +#include +#endif +#ifndef OPENSSL_NO_EVP +#include +#endif +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#ifndef OPENSSL_NO_DSA +#include +#endif + +#ifndef OPENSSL_NO_DH +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct TS_msg_imprint_st TS_MSG_IMPRINT; +typedef struct TS_req_st TS_REQ; +typedef struct TS_accuracy_st TS_ACCURACY; +typedef struct TS_tst_info_st TS_TST_INFO; + +/* Possible values for status. */ +#define TS_STATUS_GRANTED 0 +#define TS_STATUS_GRANTED_WITH_MODS 1 +#define TS_STATUS_REJECTION 2 +#define TS_STATUS_WAITING 3 +#define TS_STATUS_REVOCATION_WARNING 4 +#define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* Possible values for failure_info. */ +#define TS_INFO_BAD_ALG 0 +#define TS_INFO_BAD_REQUEST 2 +#define TS_INFO_BAD_DATA_FORMAT 5 +#define TS_INFO_TIME_NOT_AVAILABLE 14 +#define TS_INFO_UNACCEPTED_POLICY 15 +#define TS_INFO_UNACCEPTED_EXTENSION 16 +#define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +#define TS_INFO_SYSTEM_FAILURE 25 + +typedef struct TS_status_info_st TS_STATUS_INFO; + +DECLARE_STACK_OF(ASN1_UTF8STRING) + +typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL; +typedef struct ESS_cert_id ESS_CERT_ID; +DECLARE_STACK_OF(ESS_CERT_ID) +typedef struct ESS_signing_cert ESS_SIGNING_CERT; + +typedef struct ESS_cert_id_v2 ESS_CERT_ID_V2; +DECLARE_STACK_OF(ESS_CERT_ID_V2) + +typedef struct ESS_signing_cert_v2 ESS_SIGNING_CERT_V2; + +typedef struct TS_resp_st TS_RESP; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, + unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, + unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_rsp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +const ASN1_UTF8STRING *TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *si); +const STACK_OF(ASN1_UTF8STRING) * + TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *si); +const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *si); +int TS_STATUS_INFO_set_status(TS_STATUS_INFO *si, int i); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, + int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* Declarations related to response generation, defined in ts/ts_rsp_sign.c. */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +#define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +#define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +#define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *); + +/* This must return the seconds and microseconds since Jan 1, 1970 in + the sec and usec variables allocated by the caller. + Return non-zero for success and zero for failure. */ +typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, time_t *sec, long *usec); + +/* This must process the given extension. + * It can modify the TS_TST_INFO object of the context. + * Return values: !0 (processed), 0 (error, it must set the + * status info/failure info of the response). + */ +typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +typedef struct TS_resp_ctx TS_RESP_CTX; + +DECLARE_STACK_OF(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* Adds a new acceptable policy, only the default policy + is accepted by default. */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy); + +/* Adds a new acceptable message digest. Note that no message digests + are accepted by default. The md argument is shared with the caller. */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* Clock precision digits, i.e. the number of decimal digits: + '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +#define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses gettimeofday() and gmtime(). */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_rsp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +#define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +#define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +#define TS_VFY_POLICY (1u << 2) +/* Verify the message imprint provided by the user. This flag should not be + specified with TS_VFY_DATA. */ +#define TS_VFY_IMPRINT (1u << 3) +/* Verify the message imprint computed by the verify method from the user + provided data and the MD algorithm of the response. This flag should not be + specified with TS_VFY_IMPRINT. */ +#define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +#define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +#define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +#define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +#define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +#define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + * they are defined in ts/ts_verify_ctx.c. + */ + +/* Set all fields to zero. */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); + +int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int flags); +int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int flags); +BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *bio); +X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *store); +/* R$ special */ +#define TS_VERIFY_CTS_set_certs TS_VERIFY_CTX_set_certs +STACK_OF(X509) *TS_VERIFY_CTX_set_certs(TS_VERIFY_CTX *ctx, + STACK_OF(X509) *certs); +unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, + unsigned char *imprint, long imprint_len); + +/* + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_rsp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* Function declarations for handling configuration options, + defined in ts/ts_conf.c */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +#ifndef OPENSSL_NO_ENGINE +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +#endif +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +void ERR_load_TS_strings(void); + +/* Error codes for the TS functions. */ + +/* Function codes. */ +#define TS_F_D2I_TS_RESP 147 +#define TS_F_DEF_SERIAL_CB 110 +#define TS_F_DEF_TIME_CB 111 +#define TS_F_ESS_ADD_SIGNING_CERT 112 +#define TS_F_ESS_CERT_ID_NEW_INIT 113 +#define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +#define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +#define TS_F_PKCS7_TO_TS_TST_INFO 148 +#define TS_F_TS_ACCURACY_SET_MICROS 115 +#define TS_F_TS_ACCURACY_SET_MILLIS 116 +#define TS_F_TS_ACCURACY_SET_SECONDS 117 +#define TS_F_TS_CHECK_IMPRINTS 100 +#define TS_F_TS_CHECK_NONCES 101 +#define TS_F_TS_CHECK_POLICY 102 +#define TS_F_TS_CHECK_SIGNING_CERTS 103 +#define TS_F_TS_CHECK_STATUS_INFO 104 +#define TS_F_TS_COMPUTE_IMPRINT 145 +#define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +#define TS_F_TS_GET_STATUS_TEXT 105 +#define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +#define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +#define TS_F_TS_REQ_SET_NONCE 120 +#define TS_F_TS_REQ_SET_POLICY_ID 121 +#define TS_F_TS_RESP_CREATE_RESPONSE 122 +#define TS_F_TS_RESP_CREATE_TST_INFO 123 +#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +#define TS_F_TS_RESP_CTX_ADD_MD 125 +#define TS_F_TS_RESP_CTX_ADD_POLICY 126 +#define TS_F_TS_RESP_CTX_NEW 127 +#define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +#define TS_F_TS_RESP_CTX_SET_CERTS 129 +#define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +#define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +#define TS_F_TS_RESP_GET_POLICY 133 +#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +#define TS_F_TS_RESP_SET_STATUS_INFO 135 +#define TS_F_TS_RESP_SET_TST_INFO 150 +#define TS_F_TS_RESP_SIGN 136 +#define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +#define TS_F_TS_RESP_VERIFY_TOKEN 107 +#define TS_F_TS_TST_INFO_SET_ACCURACY 137 +#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +#define TS_F_TS_TST_INFO_SET_NONCE 139 +#define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +#define TS_F_TS_TST_INFO_SET_SERIAL 141 +#define TS_F_TS_TST_INFO_SET_TIME 142 +#define TS_F_TS_TST_INFO_SET_TSA 143 +#define TS_F_TS_VERIFY 108 +#define TS_F_TS_VERIFY_CERT 109 +#define TS_F_TS_VERIFY_CTX_NEW 144 + +/* Reason codes. */ +#define TS_R_BAD_PKCS7_TYPE 132 +#define TS_R_BAD_TYPE 133 +#define TS_R_CERTIFICATE_VERIFY_ERROR 100 +#define TS_R_COULD_NOT_SET_ENGINE 127 +#define TS_R_COULD_NOT_SET_TIME 115 +#define TS_R_D2I_TS_RESP_INT_FAILED 128 +#define TS_R_DETACHED_CONTENT 134 +#define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +#define TS_R_INVALID_NULL_POINTER 102 +#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +#define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +#define TS_R_NONCE_MISMATCH 104 +#define TS_R_NONCE_NOT_RETURNED 105 +#define TS_R_NO_CONTENT 106 +#define TS_R_NO_TIME_STAMP_TOKEN 107 +#define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +#define TS_R_POLICY_MISMATCH 108 +#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +#define TS_R_RESPONSE_SETUP_ERROR 121 +#define TS_R_SIGNATURE_FAILURE 109 +#define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +#define TS_R_TIME_SYSCALL_ERROR 122 +#define TS_R_TOKEN_NOT_PRESENT 130 +#define TS_R_TOKEN_PRESENT 131 +#define TS_R_TSA_NAME_MISMATCH 111 +#define TS_R_TSA_UNTRUSTED 112 +#define TS_R_TST_INFO_SETUP_ERROR 123 +#define TS_R_TS_DATASIGN 124 +#define TS_R_UNACCEPTABLE_POLICY 125 +#define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +#define TS_R_UNSUPPORTED_VERSION 113 +#define TS_R_WRONG_CONTENT_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/txt_db.h b/Libraries/libressl/include/openssl/txt_db.h new file mode 100644 index 000000000..56b6b4248 --- /dev/null +++ b/Libraries/libressl/include/openssl/txt_db.h @@ -0,0 +1,112 @@ +/* $OpenBSD: txt_db.h,v 1.9 2014/07/10 22:45:58 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_TXT_DB_H +#define HEADER_TXT_DB_H + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#define DB_ERROR_OK 0 +#define DB_ERROR_MALLOC 1 +#define DB_ERROR_INDEX_CLASH 2 +#define DB_ERROR_INDEX_OUT_OF_RANGE 3 +#define DB_ERROR_NO_INDEX 4 +#define DB_ERROR_INSERT_INDEX_CLASH 5 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual)(OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +#ifndef OPENSSL_NO_BIO +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +#else +TXT_DB *TXT_DB_read(char *in, int num); +long TXT_DB_write(char *out, TXT_DB *db); +#endif +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/ui.h b/Libraries/libressl/include/openssl/ui.h new file mode 100644 index 000000000..c68843139 --- /dev/null +++ b/Libraries/libressl/include/openssl/ui.h @@ -0,0 +1,403 @@ +/* $OpenBSD: ui.h,v 1.18 2023/04/18 08:33:43 tb Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_H +#define HEADER_UI_H + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct ui_st UI; */ +/* typedef struct ui_method_st UI_METHOD; */ + + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. + * When everything is fine, they return 0, a positive value or a non-NULL + * pointer, all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/* + * The following functions are used to add strings to be printed and prompt + * strings to prompt for data. The names are UI_{add,dup}__string + * and UI_{add,dup}_input_boolean. + * + * UI_{add,dup}__string have the following meanings: + * add add a text or prompt string. The pointers given to these + * functions are used verbatim, no copying is done. + * dup make a copy of the text or prompt string, then add the copy + * to the collection of strings in the user interface. + * + * The function is a name for the functionality that the given + * string shall be used for. It can be one of: + * input use the string as data prompt. + * verify use the string as verification prompt. This + * is used to verify a previous input. + * info use the string for informational output. + * error use the string for error output. + * Honestly, there's currently no difference between info and error for the + * moment. + * + * UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + * and are typically used when one wants to prompt for a yes/no response. + * + * All of the functions in this group take a UI and a prompt string. + * The string input and verify addition functions also take a flag argument, + * a buffer for the result to end up in, a minimum input size and a maximum + * input size (the result buffer MUST be large enough to be able to contain + * the maximum number of characters). Additionally, the verify addition + * functions takes another buffer to compare the result against. + * The boolean input functions take an action description string (which should + * be safe to ignore if the expected user action is obvious, for example with + * a dialog box with an OK button and a Cancel button), a string of acceptable + * characters to mean OK and to mean Cancel. The two last strings are checked + * to make sure they don't have common characters. Additionally, the same + * flag argument as for the string input is taken, as well as a result buffer. + * The result buffer is required to be at least one byte long. Depending on + * the answer, the first character from the OK or the Cancel character strings + * will be stored in the first byte of the result buffer. No NUL will be + * added, so the result is *not* a string. + * + * On success, the functions all return an index of the added information. + * That index is useful when retrieving results with UI_get0_result(). + */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +#define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely + * up to the application, it might for example be in the user data set + * with UI_add_user_data(). It is not recommended to have more than + * one input in each UI being marked with this flag, or the application + * might get confused. + */ +#define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/* + * Users of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + */ +#define UI_INPUT_FLAG_USER_BASE 16 + + +/* + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * malloc(), and need to be free'd with free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" + */ +char *UI_construct_prompt(UI *ui_method, const char *object_desc, + const char *object_name); + + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. + * Other methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parametrised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as + * be used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +#define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +#define UI_CTRL_IS_REDOABLE 2 + + +/* Some methods may use extra data */ +#define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +#define UI_get_app_data(s) UI_get_ex_data(s,0) +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +const UI_METHOD *UI_null(void); + +/* + * ---------- For method writers ---------- + * A method contains a number of functions that implement the low level + * of the User Interface. The functions are: + * + * an opener This function starts a session, maybe by opening + * a channel to a tty, or by opening a window. + * a writer This function is called to write a given string, + * maybe to the tty, maybe as a field label in a + * window. + * a flusher This function is called to flush everything that + * has been output so far. It can be used to actually + * display a dialog box after it has been built. + * a reader This function is called to read a given prompt, + * maybe from the tty, maybe from a field in a + * window. Note that it's called with all string + * structures, not only the prompt ones, so it must + * check such things itself. + * a closer This function closes the session, maybe by closing + * the channel to the tty, or closing the window. + * + * All these functions are expected to return: + * + * 0 on error. + * 1 on success. + * -1 on out-of-band events, for example if some prompting has + * been canceled (by pressing Ctrl-C, for example). This is + * only checked when returned by the flusher or the reader. + * + * The way this is used, the opener is first called, then the writer for all + * strings, then the flusher, then the reader for all strings and finally the + * closer. Note that if you want to prompt from a terminal or other command + * line interface, the best is to have the reader also write the prompts + * instead of having the writer do it. If you want to prompt from a dialog + * box, the writer can be used to build up the contents of the box, and the + * flusher to actually display the box and run the event loop until all data + * has been given, after which the reader only grabs the given data and puts + * them back into the UI strings. + * + * All method functions take a UI as argument. Additionally, the writer and + * the reader take a UI_STRING. + */ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DECLARE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. + * This is only needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(const char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer)(UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader)(UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor)(UI *ui, const char *object_desc, + const char *object_name)); +int (*UI_method_get_opener(const UI_METHOD *method))(UI *); +int (*UI_method_get_writer(const UI_METHOD *method))(UI *, UI_STRING *); +int (*UI_method_get_flusher(const UI_METHOD *method))(UI *); +int (*UI_method_get_reader(const UI_METHOD *method))(UI *, UI_STRING *); +int (*UI_method_get_closer(const UI_METHOD *method))(UI *); +char *(*UI_method_get_prompt_constructor(const UI_METHOD *method))(UI *, + const char *, const char *); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* Return the optional action string to output (boolean prompt instruction) */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +/* Return the string to test the result against. Only useful with verifies. */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +void ERR_load_UI_strings(void); + +/* Error codes for the UI functions. */ + +/* Function codes. */ +#define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +#define UI_F_GENERAL_ALLOCATE_PROMPT 109 +#define UI_F_GENERAL_ALLOCATE_STRING 100 +#define UI_F_UI_CTRL 111 +#define UI_F_UI_DUP_ERROR_STRING 101 +#define UI_F_UI_DUP_INFO_STRING 102 +#define UI_F_UI_DUP_INPUT_BOOLEAN 110 +#define UI_F_UI_DUP_INPUT_STRING 103 +#define UI_F_UI_DUP_VERIFY_STRING 106 +#define UI_F_UI_GET0_RESULT 107 +#define UI_F_UI_NEW_METHOD 104 +#define UI_F_UI_SET_RESULT 105 + +/* Reason codes. */ +#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +#define UI_R_INDEX_TOO_LARGE 102 +#define UI_R_INDEX_TOO_SMALL 103 +#define UI_R_NO_RESULT_BUFFER 105 +#define UI_R_RESULT_TOO_LARGE 100 +#define UI_R_RESULT_TOO_SMALL 101 +#define UI_R_UNKNOWN_CONTROL_COMMAND 106 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/ui_compat.h b/Libraries/libressl/include/openssl/ui_compat.h new file mode 100644 index 000000000..6484bf6b5 --- /dev/null +++ b/Libraries/libressl/include/openssl/ui_compat.h @@ -0,0 +1,65 @@ +/* $OpenBSD: ui_compat.h,v 1.5 2022/12/23 02:20:28 jsing Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_COMPAT_H +#define HEADER_UI_COMPAT_H + +#include +#include + +#endif diff --git a/Libraries/libressl/include/openssl/whrlpool.h b/Libraries/libressl/include/openssl/whrlpool.h new file mode 100644 index 000000000..875d34f7d --- /dev/null +++ b/Libraries/libressl/include/openssl/whrlpool.h @@ -0,0 +1,41 @@ +/* $OpenBSD: whrlpool.h,v 1.5 2014/07/10 22:45:58 jsing Exp $ */ + +#include + +#ifndef HEADER_WHRLPOOL_H +#define HEADER_WHRLPOOL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WHIRLPOOL_DIGEST_LENGTH (512/8) +#define WHIRLPOOL_BBLOCK 512 +#define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK/8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)]; + } WHIRLPOOL_CTX; + +#ifndef OPENSSL_NO_WHIRLPOOL +int WHIRLPOOL_Init (WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits); +int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/include/openssl/x509.h b/Libraries/libressl/include/openssl/x509.h new file mode 100644 index 000000000..7980761d6 --- /dev/null +++ b/Libraries/libressl/include/openssl/x509.h @@ -0,0 +1,1203 @@ +/* $OpenBSD: x509.h,v 1.101 2023/07/28 15:50:33 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +#define HEADER_X509_H + +#include + +#include +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_BUFFER +#include +#endif +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_EC +#include +#endif +#ifndef OPENSSL_NO_EVP +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_SHA +#include +#endif +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) && defined(__WINCRYPT_H__) +#if !defined(LIBRESSL_INTERNAL) && !defined(LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING) +#ifdef _MSC_VER +#pragma message("Warning, overriding WinCrypt defines") +#else +#warning overriding WinCrypt defines +#endif +#endif +#undef X509_NAME +#undef X509_CERT_PAIR +#undef X509_EXTENSIONS +#endif + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 + +#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +#define X509v3_KU_NON_REPUDIATION 0x0040 +#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +#define X509v3_KU_KEY_AGREEMENT 0x0008 +#define X509v3_KU_KEY_CERT_SIGN 0x0004 +#define X509v3_KU_CRL_SIGN 0x0002 +#define X509v3_KU_ENCIPHER_ONLY 0x0001 +#define X509v3_KU_DECIPHER_ONLY 0x8000 +#define X509v3_KU_UNDEF 0xffff + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */; + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +typedef struct X509_sig_st X509_SIG; + +typedef struct X509_name_entry_st X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) + +DECLARE_STACK_OF(X509_NAME) + +typedef struct X509_extension_st X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) + +typedef struct x509_attributes_st X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st X509_REQ_INFO; + +typedef struct X509_req_st X509_REQ; + +typedef struct x509_cert_aux_st X509_CERT_AUX; + +typedef struct x509_cinf_st X509_CINF; + +DECLARE_STACK_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust)(struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +/* standard trust ids */ + +/* OpenSSL changed this to 0 */ +#define X509_TRUST_DEFAULT -1 /* Only valid in purpose settings */ + +#define X509_TRUST_COMPAT 1 +#define X509_TRUST_SSL_CLIENT 2 +#define X509_TRUST_SSL_SERVER 3 +#define X509_TRUST_EMAIL 4 +#define X509_TRUST_OBJECT_SIGN 5 +#define X509_TRUST_OCSP_SIGN 6 +#define X509_TRUST_OCSP_REQUEST 7 +#define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +#define X509_TRUST_MIN 1 +#define X509_TRUST_MAX 8 + + +/* trust_flags values */ +#define X509_TRUST_DYNAMIC 1 +#define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +#define X509_FLAG_COMPAT 0 +#define X509_FLAG_NO_HEADER 1L +#define X509_FLAG_NO_VERSION (1L << 1) +#define X509_FLAG_NO_SERIAL (1L << 2) +#define X509_FLAG_NO_SIGNAME (1L << 3) +#define X509_FLAG_NO_ISSUER (1L << 4) +#define X509_FLAG_NO_VALIDITY (1L << 5) +#define X509_FLAG_NO_SUBJECT (1L << 6) +#define X509_FLAG_NO_PUBKEY (1L << 7) +#define X509_FLAG_NO_EXTENSIONS (1L << 8) +#define X509_FLAG_NO_SIGDUMP (1L << 9) +#define X509_FLAG_NO_AUX (1L << 10) +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +#define XN_FLAG_SEP_MASK (0xf << 16) + +#define XN_FLAG_COMPAT 0 /* Traditional SSLeay: use old X509_NAME_print */ +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) /* RFC2253 ,+ */ +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) /* ,+ spaced: more readable */ +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) /* ;+ spaced */ +#define XN_FLAG_SEP_MULTILINE (4 << 16) /* One line per field */ + +#define XN_FLAG_DN_REV (1 << 20) /* Reverse DN order */ + +/* How the field name is shown */ + +#define XN_FLAG_FN_MASK (0x3 << 21) + +#define XN_FLAG_FN_SN 0 /* Object short name */ +#define XN_FLAG_FN_LN (1 << 21) /* Object long name */ +#define XN_FLAG_FN_OID (2 << 21) /* Always use OIDs */ +#define XN_FLAG_FN_NONE (3 << 21) /* No field names */ + +#define XN_FLAG_SPC_EQ (1 << 23) /* Put spaces round '=' */ + +/* This determines if we dump fields we don't recognise: + * RFC2253 requires this. + */ + +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +#define XN_FLAG_FN_ALIGN (1 << 25) /* Align field names to 20 characters */ + +/* Complete set of RFC2253 flags */ + +#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +DECLARE_STACK_OF(X509_REVOKED) + +typedef struct X509_crl_info_st X509_CRL_INFO; + +DECLARE_STACK_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + + int references; +} X509_PKEY; + +#ifndef OPENSSL_NO_EVP +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + + int references; +} X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +#endif + +/* The next 2 structures and their 8 routines were sent to me by + * Pat Richard and are used to manipulate + * Netscapes spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { + /* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +#ifdef __cplusplus +} +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define X509_extract_key(x) X509_get_pubkey(x) /*****/ +#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +#define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) + +int X509_CRL_up_ref(X509_CRL *x); +int X509_CRL_get_signature_nid(const X509_CRL *crl); + +int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp); + +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); +long X509_CRL_get_version(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); +ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl); +ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl); +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); +void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); + +const X509_ALGOR *X509_CRL_get0_tbs_sigalg(const X509_CRL *crl); + +int X509_REQ_get_signature_nid(const X509_REQ *req); + +void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new( + int (*crl_init)(X509_CRL *crl), + int (*crl_free)(X509_CRL *crl), + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer), + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x); + +const char *X509_verify_cert_error_string(long n); + +#ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +#endif + +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp,X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); + +#ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp,X509 **x509); +int i2d_X509_bio(BIO *bp,X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +#endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval); +void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval, + const X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, size_t *pderlen); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char * X509_get_default_cert_area(void ); +const char * X509_get_default_cert_dir(void ); +const char * X509_get_default_cert_file(void ); +const char * X509_get_default_cert_dir_env(void ); +const char * X509_get_default_cert_file_env(void ); +const char * X509_get_default_private_dir(void ); + +X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); + +X509_ALGOR *X509_ALGOR_new(void); +void X509_ALGOR_free(X509_ALGOR *a); +X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **a, const unsigned char **in, long len); +int i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **out); +extern const ASN1_ITEM X509_ALGOR_it; +X509_ALGORS *d2i_X509_ALGORS(X509_ALGORS **a, const unsigned char **in, long len); +int i2d_X509_ALGORS(X509_ALGORS *a, unsigned char **out); +extern const ASN1_ITEM X509_ALGORS_it; +X509_VAL *X509_VAL_new(void); +void X509_VAL_free(X509_VAL *a); +X509_VAL *d2i_X509_VAL(X509_VAL **a, const unsigned char **in, long len); +int i2d_X509_VAL(X509_VAL *a, unsigned char **out); +extern const ASN1_ITEM X509_VAL_it; + +X509_PUBKEY *X509_PUBKEY_new(void); +void X509_PUBKEY_free(X509_PUBKEY *a); +X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **a, const unsigned char **in, long len); +int i2d_X509_PUBKEY(X509_PUBKEY *a, unsigned char **out); +extern const ASN1_ITEM X509_PUBKEY_it; + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); +EVP_PKEY * X509_PUBKEY_get0(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, + STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp); +EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, + long length); +#ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp); +RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a,unsigned char **pp); +DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, + long length); +#endif + +X509_SIG *X509_SIG_new(void); +void X509_SIG_free(X509_SIG *a); +X509_SIG *d2i_X509_SIG(X509_SIG **a, const unsigned char **in, long len); +int i2d_X509_SIG(X509_SIG *a, unsigned char **out); +extern const ASN1_ITEM X509_SIG_it; +void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg, + const ASN1_OCTET_STRING **pdigest); +void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, + ASN1_OCTET_STRING **pdigest); + +X509_REQ_INFO *X509_REQ_INFO_new(void); +void X509_REQ_INFO_free(X509_REQ_INFO *a); +X509_REQ_INFO *d2i_X509_REQ_INFO(X509_REQ_INFO **a, const unsigned char **in, long len); +int i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out); +extern const ASN1_ITEM X509_REQ_INFO_it; +X509_REQ *X509_REQ_new(void); +void X509_REQ_free(X509_REQ *a); +X509_REQ *d2i_X509_REQ(X509_REQ **a, const unsigned char **in, long len); +int i2d_X509_REQ(X509_REQ *a, unsigned char **out); +extern const ASN1_ITEM X509_REQ_it; + +X509_ATTRIBUTE *X509_ATTRIBUTE_new(void); +void X509_ATTRIBUTE_free(X509_ATTRIBUTE *a); +X509_ATTRIBUTE *d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **a, const unsigned char **in, long len); +int i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a, unsigned char **out); +extern const ASN1_ITEM X509_ATTRIBUTE_it; +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +X509_EXTENSION *X509_EXTENSION_new(void); +void X509_EXTENSION_free(X509_EXTENSION *a); +X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **a, const unsigned char **in, long len); +int i2d_X509_EXTENSION(X509_EXTENSION *a, unsigned char **out); +extern const ASN1_ITEM X509_EXTENSION_it; +X509_EXTENSIONS *d2i_X509_EXTENSIONS(X509_EXTENSIONS **a, const unsigned char **in, long len); +int i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out); +extern const ASN1_ITEM X509_EXTENSIONS_it; + +X509_NAME_ENTRY *X509_NAME_ENTRY_new(void); +void X509_NAME_ENTRY_free(X509_NAME_ENTRY *a); +X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len); +int i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out); +extern const ASN1_ITEM X509_NAME_ENTRY_it; + +X509_NAME *X509_NAME_new(void); +void X509_NAME_free(X509_NAME *a); +X509_NAME *d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len); +int i2d_X509_NAME(X509_NAME *a, unsigned char **out); +extern const ASN1_ITEM X509_NAME_it; + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +X509_CINF *X509_CINF_new(void); +void X509_CINF_free(X509_CINF *a); +X509_CINF *d2i_X509_CINF(X509_CINF **a, const unsigned char **in, long len); +int i2d_X509_CINF(X509_CINF *a, unsigned char **out); +extern const ASN1_ITEM X509_CINF_it; + +X509 *X509_new(void); +void X509_free(X509 *a); +X509 *d2i_X509(X509 **a, const unsigned char **in, long len); +int i2d_X509(X509 *a, unsigned char **out); +extern const ASN1_ITEM X509_it; +X509_CERT_AUX *X509_CERT_AUX_new(void); +void X509_CERT_AUX_free(X509_CERT_AUX *a); +X509_CERT_AUX *d2i_X509_CERT_AUX(X509_CERT_AUX **a, const unsigned char **in, long len); +int i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **out); +extern const ASN1_ITEM X509_CERT_AUX_it; + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a,unsigned char **pp); +X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +int X509_get_signature_nid(const X509 *x); + +int X509_alias_set1(X509 *x, const unsigned char *name, int len); +int X509_keyid_set1(X509 *x, const unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +X509_REVOKED *X509_REVOKED_new(void); +void X509_REVOKED_free(X509_REVOKED *a); +X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *a); +X509_REVOKED *d2i_X509_REVOKED(X509_REVOKED **a, const unsigned char **in, long len); +int i2d_X509_REVOKED(X509_REVOKED *a, unsigned char **out); +extern const ASN1_ITEM X509_REVOKED_it; + +X509_CRL_INFO *X509_CRL_INFO_new(void); +void X509_CRL_INFO_free(X509_CRL_INFO *a); +X509_CRL_INFO *d2i_X509_CRL_INFO(X509_CRL_INFO **a, const unsigned char **in, long len); +int i2d_X509_CRL_INFO(X509_CRL_INFO *a, unsigned char **out); +extern const ASN1_ITEM X509_CRL_INFO_it; + +X509_CRL *X509_CRL_new(void); +void X509_CRL_free(X509_CRL *a); +X509_CRL *d2i_X509_CRL(X509_CRL **a, const unsigned char **in, long len); +int i2d_X509_CRL(X509_CRL *a, unsigned char **out); +extern const ASN1_ITEM X509_CRL_it; + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY * X509_PKEY_new(void ); +void X509_PKEY_free(X509_PKEY *a); + +NETSCAPE_SPKI *NETSCAPE_SPKI_new(void); +void NETSCAPE_SPKI_free(NETSCAPE_SPKI *a); +NETSCAPE_SPKI *d2i_NETSCAPE_SPKI(NETSCAPE_SPKI **a, const unsigned char **in, long len); +int i2d_NETSCAPE_SPKI(NETSCAPE_SPKI *a, unsigned char **out); +extern const ASN1_ITEM NETSCAPE_SPKI_it; +NETSCAPE_SPKAC *NETSCAPE_SPKAC_new(void); +void NETSCAPE_SPKAC_free(NETSCAPE_SPKAC *a); +NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **a, const unsigned char **in, long len); +int i2d_NETSCAPE_SPKAC(NETSCAPE_SPKAC *a, unsigned char **out); +extern const ASN1_ITEM NETSCAPE_SPKAC_it; + +#ifndef OPENSSL_NO_EVP +X509_INFO * X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char * X509_NAME_oneline(const X509_NAME *a, char *buf, int size); + +int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, + unsigned char *md,unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, + X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx); +#endif + +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); +void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, + const ASN1_BIT_STRING **psuid); +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); +int X509_set_version(X509 *x, long version); +long X509_get_version(const X509 *x); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER * X509_get_serialNumber(X509 *x); +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_issuer_name(const X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_subject_name(const X509 *a); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); +const ASN1_TIME *X509_get0_notBefore(const X509 *x); +ASN1_TIME *X509_getm_notBefore(const X509 *x); +const ASN1_TIME *X509_get0_notAfter(const X509 *x); +ASN1_TIME *X509_getm_notAfter(const X509 *x); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY * X509_get_pubkey(X509 *x); +EVP_PKEY * X509_get0_pubkey(const X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey); +int X509_get_signature_type(const X509 *x); + +#define X509_get_notBefore X509_getm_notBefore +#define X509_get_notAfter X509_getm_notAfter + +int X509_REQ_set_version(X509_REQ *x,long version); +long X509_REQ_get_version(const X509_REQ *x); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *x); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); +EVP_PKEY * X509_REQ_get0_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int * X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *x); +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); + +int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); + +int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +#endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print_fp(FILE *bp,X509 *x); +int X509_CRL_print_fp(FILE *bp,X509_CRL *x); +int X509_REQ_print_fp(FILE *bp,X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, + unsigned long flags); + +#ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print(BIO *bp,X509 *x); +int X509_ocspid_print(BIO *bp,X509 *x); +int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp,X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); +int X509_REQ_print(BIO *bp,X509_REQ *req); +#endif + +int X509_NAME_entry_count(const X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, + char *buf,int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, + const ASN1_OBJECT *obj, char *buf,int len); + +/* NOTE: you should be passing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. */ +int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, + int lastpos); +int X509_NAME_get_index_by_OBJ(const X509_NAME *name, + const ASN1_OBJECT *obj, int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int type, const unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, const unsigned char *bytes, int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + const ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT * X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(const X509 *x); +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(const X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void * X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(const X509_CRL *x); +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, + int lastpos); +int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, + const ASN1_OBJECT *obj, int lastpos); +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, + int lastpos); +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void * X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, + int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, + int crit, unsigned long flags); + +int X509_REVOKED_get_ext_count(const X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, + int lastpos); +int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, + const ASN1_OBJECT *obj, int lastpos); +int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, + int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, + int loc); +void * X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, + int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, + int crit, unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, + const ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, + ASN1_OCTET_STRING *data); +ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, + const char *attrname, int type, + const unsigned char *bytes, int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + const ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data); +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, + int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); + +PBEPARAM *PBEPARAM_new(void); +void PBEPARAM_free(PBEPARAM *a); +PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, const unsigned char **in, long len); +int i2d_PBEPARAM(PBEPARAM *a, unsigned char **out); +extern const ASN1_ITEM PBEPARAM_it; +PBE2PARAM *PBE2PARAM_new(void); +void PBE2PARAM_free(PBE2PARAM *a); +PBE2PARAM *d2i_PBE2PARAM(PBE2PARAM **a, const unsigned char **in, long len); +int i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **out); +extern const ASN1_ITEM PBE2PARAM_it; +PBKDF2PARAM *PBKDF2PARAM_new(void); +void PBKDF2PARAM_free(PBKDF2PARAM *a); +PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, const unsigned char **in, long len); +int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **out); +extern const ASN1_ITEM PBKDF2PARAM_it; + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void); +void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, const unsigned char **in, long len); +int i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **out); +extern const ASN1_ITEM PKCS8_PRIV_KEY_INFO_it; + +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, + int ptype, void *pval, unsigned char *penc, int penclen); +int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, const unsigned char **pk, + int *ppklen, const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8); + +const STACK_OF(X509_ATTRIBUTE) *PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST * X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(const X509_TRUST *xp); +char *X509_TRUST_get0_name(const X509_TRUST *xp); +int X509_TRUST_get_trust(const X509_TRUST *xp); + +int X509_up_ref(X509 *x); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +#define X509_F_ADD_CERT_DIR 100 +#define X509_F_BY_FILE_CTRL 101 +#define X509_F_CHECK_POLICY 145 +#define X509_F_DIR_CTRL 102 +#define X509_F_GET_CERT_BY_SUBJECT 103 +#define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +#define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +#define X509_F_X509AT_ADD1_ATTR 135 +#define X509_F_X509V3_ADD_EXT 104 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +#define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +#define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +#define X509_F_X509_CHECK_PRIVATE_KEY 128 +#define X509_F_X509_CRL_PRINT_FP 147 +#define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +#define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +#define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +#define X509_F_X509_LOAD_CERT_CRL_FILE 132 +#define X509_F_X509_LOAD_CERT_FILE 111 +#define X509_F_X509_LOAD_CRL_FILE 112 +#define X509_F_X509_NAME_ADD_ENTRY 113 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +#define X509_F_X509_NAME_ONELINE 116 +#define X509_F_X509_NAME_PRINT 117 +#define X509_F_X509_PRINT_EX_FP 118 +#define X509_F_X509_PUBKEY_GET 119 +#define X509_F_X509_PUBKEY_SET 120 +#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +#define X509_F_X509_REQ_PRINT_EX 121 +#define X509_F_X509_REQ_PRINT_FP 122 +#define X509_F_X509_REQ_TO_X509 123 +#define X509_F_X509_STORE_ADD_CERT 124 +#define X509_F_X509_STORE_ADD_CRL 125 +#define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +#define X509_F_X509_STORE_CTX_INIT 143 +#define X509_F_X509_STORE_CTX_NEW 142 +#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +#define X509_F_X509_TO_X509_REQ 126 +#define X509_F_X509_TRUST_ADD 133 +#define X509_F_X509_TRUST_SET 141 +#define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +#define X509_R_BAD_X509_FILETYPE 100 +#define X509_R_BASE64_DECODE_ERROR 118 +#define X509_R_CANT_CHECK_DH_KEY 114 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +#define X509_R_ERR_ASN1_LIB 102 +#define X509_R_INVALID_DIRECTORY 113 +#define X509_R_INVALID_FIELD_NAME 119 +#define X509_R_INVALID_TRUST 123 +#define X509_R_INVALID_VERSION 137 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 103 +#define X509_R_LOADING_DEFAULTS 104 +#define X509_R_METHOD_NOT_SUPPORTED 124 +#define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +#define X509_R_SHOULD_RETRY 106 +#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +#define X509_R_UNKNOWN_KEY_TYPE 117 +#define X509_R_UNKNOWN_NID 109 +#define X509_R_UNKNOWN_PURPOSE_ID 121 +#define X509_R_UNKNOWN_TRUST_ID 120 +#define X509_R_UNSUPPORTED_ALGORITHM 111 +#define X509_R_WRONG_LOOKUP_TYPE 112 +#define X509_R_WRONG_TYPE 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/x509_vfy.h b/Libraries/libressl/include/openssl/x509_vfy.h new file mode 100644 index 000000000..1aa29abd3 --- /dev/null +++ b/Libraries/libressl/include/openssl/x509_vfy.h @@ -0,0 +1,477 @@ +/* $OpenBSD: x509_vfy.h,v 1.64 2023/05/28 05:25:24 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +#include +/* openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. */ +#endif + +#ifndef HEADER_X509_VFY_H +#define HEADER_X509_VFY_H + +#include + +#ifndef OPENSSL_NO_LHASH +#include +#endif +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * SSL_CTX -> X509_STORE + * -> X509_LOOKUP + * ->X509_LOOKUP_METHOD + * -> X509_LOOKUP + * ->X509_LOOKUP_METHOD + * + * SSL -> X509_STORE_CTX + * ->X509_STORE + * + * The X509_STORE holds the tables etc for verification stuff. + * A X509_STORE_CTX is used while validating a single certificate. + * The X509_STORE has X509_LOOKUPs for looking up certs. + * The X509_STORE then calls a function to actually verify the + * certificate chain. + */ + +typedef enum { + X509_LU_NONE, + X509_LU_X509, + X509_LU_CRL, +} X509_LOOKUP_TYPE; + + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* XXX - unused in OpenSSL. Can we remove this? */ +typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID; + + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +#define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +#define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +#define X509_L_FILE_LOAD 1 +#define X509_L_ADD_DIR 2 +#define X509_L_MEM 3 + +#define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +#define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +#define X509_LOOKUP_add_mem(x,iov,type) \ + X509_LOOKUP_ctrl((x),X509_L_MEM,(const char *)(iov),\ + (long)(type),NULL) + +#define X509_V_OK 0 +#define X509_V_ERR_UNSPECIFIED 1 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +#define X509_V_ERR_UNNESTED_RESOURCE 46 + +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +/* The application is not happy */ +#define X509_V_ERR_APPLICATION_VERIFICATION 50 + +/* Host, email and IP check errors */ +#define X509_V_ERR_HOSTNAME_MISMATCH 62 +#define X509_V_ERR_EMAIL_MISMATCH 63 +#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 + +/* Caller error */ +#define X509_V_ERR_INVALID_CALL 65 +/* Issuer lookup error */ +#define X509_V_ERR_STORE_LOOKUP 66 + +/* Security level errors */ +#define X509_V_ERR_EE_KEY_TOO_SMALL 67 +#define X509_V_ERR_CA_KEY_TOO_SMALL 68 +#define X509_V_ERR_CA_MD_TOO_WEAK 69 + +/* Certificate verify flags */ + +/* Deprecated in 1.1.0, has no effect. Various FFI bindings still expose it. */ +#define X509_V_FLAG_CB_ISSUER_CHECK 0x0 +/* Use check time instead of current time */ +#define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +#define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +#define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +#define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Does nothing as its functionality has been enabled by default */ +#define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +#define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +#define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +#define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +#define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +#define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check selfsigned CA signature */ +#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +#define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Allow partial chains if at least one certificate is in trusted store */ +#define X509_V_FLAG_PARTIAL_CHAIN 0x80000 + +/* If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag + * will force the behaviour to match that of previous versions. */ +#define X509_V_FLAG_NO_ALT_CHAINS 0x100000 + +/* Do not check certificate or CRL validity against current time. */ +#define X509_V_FLAG_NO_CHECK_TIME 0x200000 + +/* Force the use of the legacy certificate verification */ +#define X509_V_FLAG_LEGACY_VERIFY 0x400000 + +#define X509_VP_FLAG_DEFAULT 0x1 +#define X509_VP_FLAG_OVERWRITE 0x2 +#define X509_VP_FLAG_RESET_FLAGS 0x4 +#define X509_VP_FLAG_LOCKED 0x8 +#define X509_VP_FLAG_ONCE 0x10 + +/* + * Obsolete internal use: mask of policy related options. + * This should really go away. + */ +#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +X509_OBJECT *X509_OBJECT_new(void); +void X509_OBJECT_free(X509_OBJECT *a); +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + X509_LOOKUP_TYPE type, X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); +int X509_OBJECT_up_ref_count(X509_OBJECT *a); +X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a); +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *xo); +X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo); + +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); +int X509_STORE_up_ref(X509_STORE *x); +#define X509_STORE_get1_certs X509_STORE_CTX_get1_certs +#define X509_STORE_get1_crls X509_STORE_CTX_get1_crls +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *xs); +void *X509_STORE_get_ex_data(X509_STORE *xs, int idx); +int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data); + +#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \ + (newf), (dupf), (freef)) + +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); + +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); + +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *); + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); +#define X509_STORE_set_verify_cb_func(ctx, func) \ + X509_STORE_set_verify_cb((ctx), (func)) + +typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, + X509 *subject, X509 *issuer); + +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *store); +void X509_STORE_set_check_issued(X509_STORE *store, + X509_STORE_CTX_check_issued_fn check_issued); +X509_STORE_CTX_check_issued_fn + X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *xs); +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *xs); +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); +X509_LOOKUP_METHOD *X509_LOOKUP_mem(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +#define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject +X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, X509_NAME *name); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); + + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const unsigned char *bytes, int len, X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const char *str, int len, X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len); +int X509_STORE_set_default_paths(X509_STORE *ctx); + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); +void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth); +X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +int (*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *); +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + int (*verify)(X509_STORE_CTX *)); +int (*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); +#define X509_STORE_set_verify_func(ctx, func) \ + X509_STORE_set_verify((ctx), (func)) + +int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level); +time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, + size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, const char *name, + size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, + size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, + size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +int X509_VERIFY_PARAM_get_count(void); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/openssl/x509v3.h b/Libraries/libressl/include/openssl/x509v3.h new file mode 100644 index 000000000..f867cc38c --- /dev/null +++ b/Libraries/libressl/include/openssl/x509v3.h @@ -0,0 +1,1119 @@ +/* $OpenBSD: x509v3.h,v 1.25 2023/06/25 18:15:21 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_X509V3_H +#define HEADER_X509V3_H + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void * (*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE)(void *); +typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long); +typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext); +typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; + /* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; + /* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; + + /* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; + + /* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; + + /* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string)(void *db, const char *section, const char *value); + STACK_OF(CONF_VALUE) *(*get_section)(void *db, const char *section); + void (*free_string)(void *db, char *string); + void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { + #define CTX_TEST 0x1 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; + /* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DECLARE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +#define X509V3_EXT_DYNAMIC 0x1 +#define X509V3_EXT_CTX_DEP 0x2 +#define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { + + #define GEN_OTHERNAME 0 + #define GEN_EMAIL 1 + #define GEN_DNS 2 + #define GEN_X400 3 + #define GEN_DIRNAME 4 + #define GEN_EDIPARTY 5 + #define GEN_URI 6 + #define GEN_IPADD 7 + #define GEN_RID 8 + + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_STRING *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + } d; +} GENERAL_NAME; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +DECLARE_STACK_OF(GENERAL_NAME) + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; +DECLARE_STACK_OF(GENERAL_NAMES) + +DECLARE_STACK_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; + /* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +#define CRLDP_ALL_REASONS 0x807f + +#define CRL_REASON_NONE -1 +#define CRL_REASON_UNSPECIFIED 0 +#define CRL_REASON_KEY_COMPROMISE 1 +#define CRL_REASON_CA_COMPROMISE 2 +#define CRL_REASON_AFFILIATION_CHANGED 3 +#define CRL_REASON_SUPERSEDED 4 +#define CRL_REASON_CESSATION_OF_OPERATION 5 +#define CRL_REASON_CERTIFICATE_HOLD 6 +#define CRL_REASON_REMOVE_FROM_CRL 8 +#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +#define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DECLARE_STACK_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DECLARE_STACK_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DECLARE_STACK_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DECLARE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DECLARE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +#define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +#define IDP_INVALID 0x2 +/* onlyuser true */ +#define IDP_ONLYUSER 0x4 +/* onlyCA true */ +#define IDP_ONLYCA 0x8 +/* onlyattr true */ +#define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +#define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +#define IDP_REASONS 0x40 + +#define X509V3_conf_err(val) ERR_asprintf_error_data( \ + "section:%s,name:%s,value:%s", val->section, \ + val->name, val->value); + +#define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +#define EXT_BITSTRING(nid, table) { nid, 0, &ASN1_BIT_STRING_it, \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +#define EXT_IA5STRING(nid) { nid, 0, &ASN1_IA5STRING_it, \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +#define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + + +/* X509_PURPOSE stuff */ + +#define EXFLAG_BCONS 0x0001 +#define EXFLAG_KUSAGE 0x0002 +#define EXFLAG_XKUSAGE 0x0004 +#define EXFLAG_NSCERT 0x0008 + +#define EXFLAG_CA 0x0010 +#define EXFLAG_SI 0x0020 /* Self issued. */ +#define EXFLAG_V1 0x0040 +#define EXFLAG_INVALID 0x0080 +#define EXFLAG_SET 0x0100 +#define EXFLAG_CRITICAL 0x0200 +#if !defined(LIBRESSL_INTERNAL) +#define EXFLAG_PROXY 0x0400 +#endif +#define EXFLAG_INVALID_POLICY 0x0800 +#define EXFLAG_FRESHEST 0x1000 +#define EXFLAG_SS 0x2000 /* Self signed. */ + +#define KU_DIGITAL_SIGNATURE 0x0080 +#define KU_NON_REPUDIATION 0x0040 +#define KU_KEY_ENCIPHERMENT 0x0020 +#define KU_DATA_ENCIPHERMENT 0x0010 +#define KU_KEY_AGREEMENT 0x0008 +#define KU_KEY_CERT_SIGN 0x0004 +#define KU_CRL_SIGN 0x0002 +#define KU_ENCIPHER_ONLY 0x0001 +#define KU_DECIPHER_ONLY 0x8000 + +#define NS_SSL_CLIENT 0x80 +#define NS_SSL_SERVER 0x40 +#define NS_SMIME 0x20 +#define NS_OBJSIGN 0x10 +#define NS_SSL_CA 0x04 +#define NS_SMIME_CA 0x02 +#define NS_OBJSIGN_CA 0x01 +#define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +#define XKU_SSL_SERVER 0x1 +#define XKU_SSL_CLIENT 0x2 +#define XKU_SMIME 0x4 +#define XKU_CODE_SIGN 0x8 +#define XKU_SGC 0x10 +#define XKU_OCSP_SIGN 0x20 +#define XKU_TIMESTAMP 0x40 +#define XKU_DVCS 0x80 +#define XKU_ANYEKU 0x100 + +#define X509_PURPOSE_DYNAMIC 0x1 +#define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +#define X509_PURPOSE_SSL_CLIENT 1 +#define X509_PURPOSE_SSL_SERVER 2 +#define X509_PURPOSE_NS_SSL_SERVER 3 +#define X509_PURPOSE_SMIME_SIGN 4 +#define X509_PURPOSE_SMIME_ENCRYPT 5 +#define X509_PURPOSE_CRL_SIGN 6 +#define X509_PURPOSE_ANY 7 +#define X509_PURPOSE_OCSP_HELPER 8 +#define X509_PURPOSE_TIMESTAMP_SIGN 9 + +#define X509_PURPOSE_MIN 1 +#define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +#define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +#define X509V3_ADD_OP_MASK 0xfL +#define X509V3_ADD_DEFAULT 0L +#define X509V3_ADD_APPEND 1L +#define X509V3_ADD_REPLACE 2L +#define X509V3_ADD_REPLACE_EXISTING 3L +#define X509V3_ADD_KEEP_EXISTING 4L +#define X509V3_ADD_DELETE 5L +#define X509V3_ADD_SILENT 0x10 + +DECLARE_STACK_OF(X509_PURPOSE) + +BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void); +void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a); +BASIC_CONSTRAINTS *d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len); +int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out); +extern const ASN1_ITEM BASIC_CONSTRAINTS_it; + +AUTHORITY_KEYID *AUTHORITY_KEYID_new(void); +void AUTHORITY_KEYID_free(AUTHORITY_KEYID *a); +AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len); +int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out); +extern const ASN1_ITEM AUTHORITY_KEYID_it; + +PKEY_USAGE_PERIOD *PKEY_USAGE_PERIOD_new(void); +void PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a); +PKEY_USAGE_PERIOD *d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len); +int i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out); +extern const ASN1_ITEM PKEY_USAGE_PERIOD_it; + +GENERAL_NAME *GENERAL_NAME_new(void); +void GENERAL_NAME_free(GENERAL_NAME *a); +GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len); +int i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out); +extern const ASN1_ITEM GENERAL_NAME_it; +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + + + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +GENERAL_NAMES *GENERAL_NAMES_new(void); +void GENERAL_NAMES_free(GENERAL_NAMES *a); +GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len); +int i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out); +extern const ASN1_ITEM GENERAL_NAMES_it; + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +OTHERNAME *OTHERNAME_new(void); +void OTHERNAME_free(OTHERNAME *a); +OTHERNAME *d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len); +int i2d_OTHERNAME(OTHERNAME *a, unsigned char **out); +extern const ASN1_ITEM OTHERNAME_it; +EDIPARTYNAME *EDIPARTYNAME_new(void); +void EDIPARTYNAME_free(EDIPARTYNAME *a); +EDIPARTYNAME *d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len); +int i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out); +extern const ASN1_ITEM EDIPARTYNAME_it; +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +EXTENDED_KEY_USAGE *EXTENDED_KEY_USAGE_new(void); +void EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a); +EXTENDED_KEY_USAGE *d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len); +int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out); +extern const ASN1_ITEM EXTENDED_KEY_USAGE_it; +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a); + +CERTIFICATEPOLICIES *CERTIFICATEPOLICIES_new(void); +void CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a); +CERTIFICATEPOLICIES *d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len); +int i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out); +extern const ASN1_ITEM CERTIFICATEPOLICIES_it; +POLICYINFO *POLICYINFO_new(void); +void POLICYINFO_free(POLICYINFO *a); +POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len); +int i2d_POLICYINFO(POLICYINFO *a, unsigned char **out); +extern const ASN1_ITEM POLICYINFO_it; +POLICYQUALINFO *POLICYQUALINFO_new(void); +void POLICYQUALINFO_free(POLICYQUALINFO *a); +POLICYQUALINFO *d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len); +int i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out); +extern const ASN1_ITEM POLICYQUALINFO_it; +USERNOTICE *USERNOTICE_new(void); +void USERNOTICE_free(USERNOTICE *a); +USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len); +int i2d_USERNOTICE(USERNOTICE *a, unsigned char **out); +extern const ASN1_ITEM USERNOTICE_it; +NOTICEREF *NOTICEREF_new(void); +void NOTICEREF_free(NOTICEREF *a); +NOTICEREF *d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len); +int i2d_NOTICEREF(NOTICEREF *a, unsigned char **out); +extern const ASN1_ITEM NOTICEREF_it; + +CRL_DIST_POINTS *CRL_DIST_POINTS_new(void); +void CRL_DIST_POINTS_free(CRL_DIST_POINTS *a); +CRL_DIST_POINTS *d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len); +int i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out); +extern const ASN1_ITEM CRL_DIST_POINTS_it; +DIST_POINT *DIST_POINT_new(void); +void DIST_POINT_free(DIST_POINT *a); +DIST_POINT *d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len); +int i2d_DIST_POINT(DIST_POINT *a, unsigned char **out); +extern const ASN1_ITEM DIST_POINT_it; +DIST_POINT_NAME *DIST_POINT_NAME_new(void); +void DIST_POINT_NAME_free(DIST_POINT_NAME *a); +DIST_POINT_NAME *d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len); +int i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out); +extern const ASN1_ITEM DIST_POINT_NAME_it; +ISSUING_DIST_POINT *ISSUING_DIST_POINT_new(void); +void ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a); +ISSUING_DIST_POINT *d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len); +int i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out); +extern const ASN1_ITEM ISSUING_DIST_POINT_it; + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +ACCESS_DESCRIPTION *ACCESS_DESCRIPTION_new(void); +void ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a); +ACCESS_DESCRIPTION *d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len); +int i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out); +extern const ASN1_ITEM ACCESS_DESCRIPTION_it; +AUTHORITY_INFO_ACCESS *AUTHORITY_INFO_ACCESS_new(void); +void AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a); +AUTHORITY_INFO_ACCESS *d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len); +int i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out); +extern const ASN1_ITEM AUTHORITY_INFO_ACCESS_it; + +extern const ASN1_ITEM POLICY_MAPPING_it; +POLICY_MAPPING *POLICY_MAPPING_new(void); +void POLICY_MAPPING_free(POLICY_MAPPING *a); +extern const ASN1_ITEM POLICY_MAPPINGS_it; + +extern const ASN1_ITEM GENERAL_SUBTREE_it; +GENERAL_SUBTREE *GENERAL_SUBTREE_new(void); +void GENERAL_SUBTREE_free(GENERAL_SUBTREE *a); + +extern const ASN1_ITEM NAME_CONSTRAINTS_it; +NAME_CONSTRAINTS *NAME_CONSTRAINTS_new(void); +void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a); + +POLICY_CONSTRAINTS *POLICY_CONSTRAINTS_new(void); +void POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a); +extern const ASN1_ITEM POLICY_CONSTRAINTS_it; + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + int gen_type, const char *value, int is_nc); + +#ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + int ext_nid, const char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *name, const char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +#endif + +char *X509V3_get_string(X509V3_CTX *ctx, const char *name, + const char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); + + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); + +char *hex_to_string(const unsigned char *buffer, long len); +unsigned char *string_to_hex(const char *str, long *len); + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent); +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +int X509_PURPOSE_get_count(void); +X509_PURPOSE * X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(const char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, const X509 *, int), + const char *name, const char *sname, void *arg); +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(const X509_PURPOSE *); +uint32_t X509_get_extension_flags(X509 *x); +uint32_t X509_get_key_usage(X509 *x); +uint32_t X509_get_extended_key_usage(X509 *x); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); + +/* Flags for X509_check_* functions */ +/* Always check subject name for host match even if subject alt names present */ +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* Disable checking the CN for a hostname, to support modern validation */ +#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 + +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +#define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int a2i_ipadd(unsigned char *ipout, const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, + unsigned long chtype); + +#ifndef OPENSSL_NO_RFC3779 +typedef struct ASRange_st { + ASN1_INTEGER *min; + ASN1_INTEGER *max; +} ASRange; + +#define ASIdOrRange_id 0 +#define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DECLARE_STACK_OF(ASIdOrRange) + +#define ASIdentifierChoice_inherit 0 +#define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum; + ASIdentifierChoice *rdi; +} ASIdentifiers; + +ASRange *ASRange_new(void); +void ASRange_free(ASRange *a); +ASRange *d2i_ASRange(ASRange **a, const unsigned char **in, long len); +int i2d_ASRange(ASRange *a, unsigned char **out); +extern const ASN1_ITEM ASRange_it; + +ASIdOrRange *ASIdOrRange_new(void); +void ASIdOrRange_free(ASIdOrRange *a); +ASIdOrRange *d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, + long len); +int i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out); +extern const ASN1_ITEM ASIdOrRange_it; + +ASIdentifierChoice *ASIdentifierChoice_new(void); +void ASIdentifierChoice_free(ASIdentifierChoice *a); +ASIdentifierChoice *d2i_ASIdentifierChoice(ASIdentifierChoice **a, + const unsigned char **in, long len); +int i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out); +extern const ASN1_ITEM ASIdentifierChoice_it; + +ASIdentifiers *ASIdentifiers_new(void); +void ASIdentifiers_free(ASIdentifiers *a); +ASIdentifiers *d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, + long len); +int i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out); +extern const ASN1_ITEM ASIdentifiers_it; + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min; + ASN1_BIT_STRING *max; +} IPAddressRange; + +#define IPAddressOrRange_addressPrefix 0 +#define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DECLARE_STACK_OF(IPAddressOrRange) + +#define IPAddressChoice_inherit 0 +#define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DECLARE_STACK_OF(IPAddressFamily) + +IPAddressRange *IPAddressRange_new(void); +void IPAddressRange_free(IPAddressRange *a); +IPAddressRange *d2i_IPAddressRange(IPAddressRange **a, + const unsigned char **in, long len); +int i2d_IPAddressRange(IPAddressRange *a, unsigned char **out); +extern const ASN1_ITEM IPAddressRange_it; + +IPAddressOrRange *IPAddressOrRange_new(void); +void IPAddressOrRange_free(IPAddressOrRange *a); +IPAddressOrRange *d2i_IPAddressOrRange(IPAddressOrRange **a, + const unsigned char **in, long len); +int i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out); +extern const ASN1_ITEM IPAddressOrRange_it; + +IPAddressChoice *IPAddressChoice_new(void); +void IPAddressChoice_free(IPAddressChoice *a); +IPAddressChoice *d2i_IPAddressChoice(IPAddressChoice **a, + const unsigned char **in, long len); +int i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out); +extern const ASN1_ITEM IPAddressChoice_it; + +IPAddressFamily *IPAddressFamily_new(void); +void IPAddressFamily_free(IPAddressFamily *a); +IPAddressFamily *d2i_IPAddressFamily(IPAddressFamily **a, + const unsigned char **in, long len); +int i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out); +extern const ASN1_ITEM IPAddressFamily_it; + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +#define V3_ASID_ASNUM 0 +#define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +#define IANA_AFI_IPV4 1 +#define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int X509v3_asid_add_inherit(ASIdentifiers *asid, int which); +int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi); +int X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi, unsigned char *a, const int prefixlen); +int X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi, unsigned char *min, unsigned char *max); +unsigned X509v3_addr_get_afi(const IPAddressFamily *f); +int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, const int length); + +/* + * Canonical forms. + */ +int X509v3_asid_is_canonical(ASIdentifiers *asid); +int X509v3_addr_is_canonical(IPAddrBlocks *addr); +int X509v3_asid_canonize(ASIdentifiers *asid); +int X509v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int X509v3_asid_inherits(ASIdentifiers *asid); +int X509v3_addr_inherits(IPAddrBlocks *addr); +int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int X509v3_asid_validate_path(X509_STORE_CTX *); +int X509v3_addr_validate_path(X509_STORE_CTX *); +int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, + int allow_inheritance); +int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext, + int allow_inheritance); + +#endif /* !OPENSSL_NO_RFC3779 */ + +void ERR_load_X509V3_strings(void); + +/* Error codes for the X509V3 functions. */ + +/* Function codes. */ +#define X509V3_F_A2I_GENERAL_NAME 164 +#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +#define X509V3_F_COPY_EMAIL 122 +#define X509V3_F_COPY_ISSUER 123 +#define X509V3_F_DO_DIRNAME 144 +#define X509V3_F_DO_EXT_CONF 124 +#define X509V3_F_DO_EXT_I2D 135 +#define X509V3_F_DO_EXT_NCONF 151 +#define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 +#define X509V3_F_GNAMES_FROM_SECTNAME 156 +#define X509V3_F_HEX_TO_STRING 111 +#define X509V3_F_I2S_ASN1_ENUMERATED 121 +#define X509V3_F_I2S_ASN1_IA5STRING 149 +#define X509V3_F_I2S_ASN1_INTEGER 120 +#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +#define X509V3_F_NOTICE_SECTION 132 +#define X509V3_F_NREF_NOS 133 +#define X509V3_F_POLICY_SECTION 131 +#define X509V3_F_PROCESS_PCI_VALUE 150 +#define X509V3_F_R2I_CERTPOL 130 +#define X509V3_F_R2I_PCI 155 +#define X509V3_F_S2I_ASN1_IA5STRING 100 +#define X509V3_F_S2I_ASN1_INTEGER 108 +#define X509V3_F_S2I_ASN1_OCTET_STRING 112 +#define X509V3_F_S2I_ASN1_SKEY_ID 114 +#define X509V3_F_S2I_SKEY_ID 115 +#define X509V3_F_SET_DIST_POINT_NAME 158 +#define X509V3_F_STRING_TO_HEX 113 +#define X509V3_F_SXNET_ADD_ID_ASC 125 +#define X509V3_F_SXNET_ADD_ID_INTEGER 126 +#define X509V3_F_SXNET_ADD_ID_ULONG 127 +#define X509V3_F_SXNET_GET_ID_ASC 128 +#define X509V3_F_SXNET_GET_ID_ULONG 129 +#define X509V3_F_V2I_ASIDENTIFIERS 163 +#define X509V3_F_V2I_ASN1_BIT_STRING 101 +#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +#define X509V3_F_V2I_AUTHORITY_KEYID 119 +#define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +#define X509V3_F_V2I_CRLD 134 +#define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +#define X509V3_F_V2I_GENERAL_NAMES 118 +#define X509V3_F_V2I_GENERAL_NAME_EX 117 +#define X509V3_F_V2I_IDP 157 +#define X509V3_F_V2I_IPADDRBLOCKS 159 +#define X509V3_F_V2I_ISSUER_ALT 153 +#define X509V3_F_V2I_NAME_CONSTRAINTS 147 +#define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +#define X509V3_F_V2I_POLICY_MAPPINGS 145 +#define X509V3_F_V2I_SUBJECT_ALT 154 +#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 +#define X509V3_F_V3_GENERIC_EXTENSION 116 +#define X509V3_F_X509V3_ADD1_I2D 140 +#define X509V3_F_X509V3_ADD_VALUE 105 +#define X509V3_F_X509V3_EXT_ADD 104 +#define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +#define X509V3_F_X509V3_EXT_CONF 107 +#define X509V3_F_X509V3_EXT_I2D 136 +#define X509V3_F_X509V3_EXT_NCONF 152 +#define X509V3_F_X509V3_GET_SECTION 142 +#define X509V3_F_X509V3_GET_STRING 143 +#define X509V3_F_X509V3_GET_VALUE_BOOL 110 +#define X509V3_F_X509V3_PARSE_LIST 109 +#define X509V3_F_X509_PURPOSE_ADD 137 +#define X509V3_F_X509_PURPOSE_SET 141 + +/* Reason codes. */ +#define X509V3_R_BAD_IP_ADDRESS 118 +#define X509V3_R_BAD_OBJECT 119 +#define X509V3_R_BN_DEC2BN_ERROR 100 +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +#define X509V3_R_DIRNAME_ERROR 149 +#define X509V3_R_DISTPOINT_ALREADY_SET 160 +#define X509V3_R_DUPLICATE_ZONE_ID 133 +#define X509V3_R_ERROR_CONVERTING_ZONE 131 +#define X509V3_R_ERROR_CREATING_EXTENSION 144 +#define X509V3_R_ERROR_IN_EXTENSION 128 +#define X509V3_R_EXPECTED_A_SECTION_NAME 137 +#define X509V3_R_EXTENSION_EXISTS 145 +#define X509V3_R_EXTENSION_NAME_ERROR 115 +#define X509V3_R_EXTENSION_NOT_FOUND 102 +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +#define X509V3_R_EXTENSION_VALUE_ERROR 116 +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +#define X509V3_R_ILLEGAL_HEX_DIGIT 113 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +#define X509V3_R_INVALID_MULTIPLE_RDNS 161 +#define X509V3_R_INVALID_ASNUMBER 162 +#define X509V3_R_INVALID_ASRANGE 163 +#define X509V3_R_INVALID_BOOLEAN_STRING 104 +#define X509V3_R_INVALID_EXTENSION_STRING 105 +#define X509V3_R_INVALID_INHERITANCE 165 +#define X509V3_R_INVALID_IPADDRESS 166 +#define X509V3_R_INVALID_NAME 106 +#define X509V3_R_INVALID_NULL_ARGUMENT 107 +#define X509V3_R_INVALID_NULL_NAME 108 +#define X509V3_R_INVALID_NULL_VALUE 109 +#define X509V3_R_INVALID_NUMBER 140 +#define X509V3_R_INVALID_NUMBERS 141 +#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +#define X509V3_R_INVALID_OPTION 138 +#define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +#define X509V3_R_INVALID_PURPOSE 146 +#define X509V3_R_INVALID_SAFI 164 +#define X509V3_R_INVALID_SECTION 135 +#define X509V3_R_INVALID_SYNTAX 143 +#define X509V3_R_ISSUER_DECODE_ERROR 126 +#define X509V3_R_MISSING_VALUE 124 +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +#define X509V3_R_NO_CONFIG_DATABASE 136 +#define X509V3_R_NO_ISSUER_CERTIFICATE 121 +#define X509V3_R_NO_ISSUER_DETAILS 127 +#define X509V3_R_NO_POLICY_IDENTIFIER 139 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +#define X509V3_R_NO_PUBLIC_KEY 114 +#define X509V3_R_NO_SUBJECT_DETAILS 125 +#define X509V3_R_ODD_NUMBER_OF_DIGITS 112 +#define X509V3_R_OPERATION_NOT_DEFINED 148 +#define X509V3_R_OTHERNAME_ERROR 147 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +#define X509V3_R_POLICY_PATH_LENGTH 156 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +#define X509V3_R_SECTION_NOT_FOUND 150 +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +#define X509V3_R_UNKNOWN_EXTENSION 129 +#define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +#define X509V3_R_UNKNOWN_OPTION 120 +#define X509V3_R_UNSUPPORTED_OPTION 117 +#define X509V3_R_UNSUPPORTED_TYPE 167 +#define X509V3_R_USER_TOO_LONG 132 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Libraries/libressl/include/pqueue.h b/Libraries/libressl/include/pqueue.h new file mode 100644 index 000000000..cdda4a396 --- /dev/null +++ b/Libraries/libressl/include/pqueue.h @@ -0,0 +1,93 @@ +/* $OpenBSD: pqueue.h,v 1.4 2016/11/04 18:28:58 guenther Exp $ */ + +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PQUEUE_H +#define HEADER_PQUEUE_H + +__BEGIN_HIDDEN_DECLS + +typedef struct _pqueue *pqueue; + +typedef struct _pitem { + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ + void *data; + struct _pitem *next; +} pitem; + +typedef struct _pitem *piterator; + +pitem *pitem_new(unsigned char *prio64be, void *data); +void pitem_free(pitem *item); + +pqueue pqueue_new(void); +void pqueue_free(pqueue pq); + +pitem *pqueue_insert(pqueue pq, pitem *item); +pitem *pqueue_peek(pqueue pq); +pitem *pqueue_pop(pqueue pq); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +pitem *pqueue_iterator(pqueue pq); +pitem *pqueue_next(piterator *iter); + +int pqueue_size(pqueue pq); + +__END_HIDDEN_DECLS + +#endif /* ! HEADER_PQUEUE_H */ diff --git a/Libraries/libressl/include/tls.h b/Libraries/libressl/include/tls.h new file mode 100644 index 000000000..59b2c4cc5 --- /dev/null +++ b/Libraries/libressl/include/tls.h @@ -0,0 +1,230 @@ +/* $OpenBSD: tls.h,v 1.63 2023/07/02 06:37:27 beck Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS_H +#define HEADER_TLS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#ifndef LIBRESSL_INTERNAL +#include +typedef SSIZE_T ssize_t; +#endif +#endif + +#include + +#include +#include + +#define TLS_API 20200120 + +/* + * Deprecated versions of TLS. Using these effectively selects + * the minimum supported version. + */ +#define TLS_PROTOCOL_TLSv1_0 (1 << 3) +#define TLS_PROTOCOL_TLSv1_1 (1 << 3) +/* Supported versions of TLS */ +#define TLS_PROTOCOL_TLSv1_2 (1 << 3) +#define TLS_PROTOCOL_TLSv1_3 (1 << 4) + +#define TLS_PROTOCOL_TLSv1 \ + (TLS_PROTOCOL_TLSv1_2|TLS_PROTOCOL_TLSv1_3) + +#define TLS_PROTOCOLS_ALL TLS_PROTOCOL_TLSv1 +#define TLS_PROTOCOLS_DEFAULT (TLS_PROTOCOL_TLSv1_2|TLS_PROTOCOL_TLSv1_3) + +#define TLS_WANT_POLLIN -2 +#define TLS_WANT_POLLOUT -3 + +/* RFC 6960 Section 2.3 */ +#define TLS_OCSP_RESPONSE_SUCCESSFUL 0 +#define TLS_OCSP_RESPONSE_MALFORMED 1 +#define TLS_OCSP_RESPONSE_INTERNALERROR 2 +#define TLS_OCSP_RESPONSE_TRYLATER 3 +#define TLS_OCSP_RESPONSE_SIGREQUIRED 4 +#define TLS_OCSP_RESPONSE_UNAUTHORIZED 5 + +/* RFC 6960 Section 2.2 */ +#define TLS_OCSP_CERT_GOOD 0 +#define TLS_OCSP_CERT_REVOKED 1 +#define TLS_OCSP_CERT_UNKNOWN 2 + +/* RFC 5280 Section 5.3.1 */ +#define TLS_CRL_REASON_UNSPECIFIED 0 +#define TLS_CRL_REASON_KEY_COMPROMISE 1 +#define TLS_CRL_REASON_CA_COMPROMISE 2 +#define TLS_CRL_REASON_AFFILIATION_CHANGED 3 +#define TLS_CRL_REASON_SUPERSEDED 4 +#define TLS_CRL_REASON_CESSATION_OF_OPERATION 5 +#define TLS_CRL_REASON_CERTIFICATE_HOLD 6 +#define TLS_CRL_REASON_REMOVE_FROM_CRL 8 +#define TLS_CRL_REASON_PRIVILEGE_WITHDRAWN 9 +#define TLS_CRL_REASON_AA_COMPROMISE 10 + +#define TLS_MAX_SESSION_ID_LENGTH 32 +#define TLS_TICKET_KEY_SIZE 48 + +struct tls; +struct tls_config; + +typedef ssize_t (*tls_read_cb)(struct tls *_ctx, void *_buf, size_t _buflen, + void *_cb_arg); +typedef ssize_t (*tls_write_cb)(struct tls *_ctx, const void *_buf, + size_t _buflen, void *_cb_arg); + +int tls_init(void); + +const char *tls_config_error(struct tls_config *_config); +const char *tls_error(struct tls *_ctx); + +struct tls_config *tls_config_new(void); +void tls_config_free(struct tls_config *_config); + +const char *tls_default_ca_cert_file(void); + +int tls_config_add_keypair_file(struct tls_config *_config, + const char *_cert_file, const char *_key_file); +int tls_config_add_keypair_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _cert_len, const uint8_t *_key, size_t _key_len); +int tls_config_add_keypair_ocsp_file(struct tls_config *_config, + const char *_cert_file, const char *_key_file, + const char *_ocsp_staple_file); +int tls_config_add_keypair_ocsp_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _cert_len, const uint8_t *_key, size_t _key_len, + const uint8_t *_staple, size_t _staple_len); +int tls_config_set_alpn(struct tls_config *_config, const char *_alpn); +int tls_config_set_ca_file(struct tls_config *_config, const char *_ca_file); +int tls_config_set_ca_path(struct tls_config *_config, const char *_ca_path); +int tls_config_set_ca_mem(struct tls_config *_config, const uint8_t *_ca, + size_t _len); +int tls_config_set_cert_file(struct tls_config *_config, + const char *_cert_file); +int tls_config_set_cert_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _len); +int tls_config_set_ciphers(struct tls_config *_config, const char *_ciphers); +int tls_config_set_crl_file(struct tls_config *_config, const char *_crl_file); +int tls_config_set_crl_mem(struct tls_config *_config, const uint8_t *_crl, + size_t _len); +int tls_config_set_dheparams(struct tls_config *_config, const char *_params); +int tls_config_set_ecdhecurve(struct tls_config *_config, const char *_curve); +int tls_config_set_ecdhecurves(struct tls_config *_config, const char *_curves); +int tls_config_set_key_file(struct tls_config *_config, const char *_key_file); +int tls_config_set_key_mem(struct tls_config *_config, const uint8_t *_key, + size_t _len); +int tls_config_set_keypair_file(struct tls_config *_config, + const char *_cert_file, const char *_key_file); +int tls_config_set_keypair_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _cert_len, const uint8_t *_key, size_t _key_len); +int tls_config_set_keypair_ocsp_file(struct tls_config *_config, + const char *_cert_file, const char *_key_file, const char *_staple_file); +int tls_config_set_keypair_ocsp_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _cert_len, const uint8_t *_key, size_t _key_len, + const uint8_t *_staple, size_t staple_len); +int tls_config_set_ocsp_staple_mem(struct tls_config *_config, + const uint8_t *_staple, size_t _len); +int tls_config_set_ocsp_staple_file(struct tls_config *_config, + const char *_staple_file); +int tls_config_set_protocols(struct tls_config *_config, uint32_t _protocols); +int tls_config_set_session_fd(struct tls_config *_config, int _session_fd); +int tls_config_set_verify_depth(struct tls_config *_config, int _verify_depth); + +void tls_config_prefer_ciphers_client(struct tls_config *_config); +void tls_config_prefer_ciphers_server(struct tls_config *_config); + +void tls_config_insecure_noverifycert(struct tls_config *_config); +void tls_config_insecure_noverifyname(struct tls_config *_config); +void tls_config_insecure_noverifytime(struct tls_config *_config); +void tls_config_verify(struct tls_config *_config); + +void tls_config_ocsp_require_stapling(struct tls_config *_config); +void tls_config_verify_client(struct tls_config *_config); +void tls_config_verify_client_optional(struct tls_config *_config); + +void tls_config_clear_keys(struct tls_config *_config); +int tls_config_parse_protocols(uint32_t *_protocols, const char *_protostr); + +int tls_config_set_session_id(struct tls_config *_config, + const unsigned char *_session_id, size_t _len); +int tls_config_set_session_lifetime(struct tls_config *_config, int _lifetime); +int tls_config_add_ticket_key(struct tls_config *_config, uint32_t _keyrev, + unsigned char *_key, size_t _keylen); + +struct tls *tls_client(void); +struct tls *tls_server(void); +int tls_configure(struct tls *_ctx, struct tls_config *_config); +void tls_reset(struct tls *_ctx); +void tls_free(struct tls *_ctx); + +int tls_accept_fds(struct tls *_ctx, struct tls **_cctx, int _fd_read, + int _fd_write); +int tls_accept_socket(struct tls *_ctx, struct tls **_cctx, int _socket); +int tls_accept_cbs(struct tls *_ctx, struct tls **_cctx, + tls_read_cb _read_cb, tls_write_cb _write_cb, void *_cb_arg); +int tls_connect(struct tls *_ctx, const char *_host, const char *_port); +int tls_connect_fds(struct tls *_ctx, int _fd_read, int _fd_write, + const char *_servername); +int tls_connect_servername(struct tls *_ctx, const char *_host, + const char *_port, const char *_servername); +int tls_connect_socket(struct tls *_ctx, int _s, const char *_servername); +int tls_connect_cbs(struct tls *_ctx, tls_read_cb _read_cb, + tls_write_cb _write_cb, void *_cb_arg, const char *_servername); +int tls_handshake(struct tls *_ctx); +ssize_t tls_read(struct tls *_ctx, void *_buf, size_t _buflen); +ssize_t tls_write(struct tls *_ctx, const void *_buf, size_t _buflen); +int tls_close(struct tls *_ctx); + +int tls_peer_cert_provided(struct tls *_ctx); +int tls_peer_cert_contains_name(struct tls *_ctx, const char *_name); + +const char *tls_peer_cert_hash(struct tls *_ctx); +const char *tls_peer_cert_issuer(struct tls *_ctx); +const char *tls_peer_cert_subject(struct tls *_ctx); +time_t tls_peer_cert_notbefore(struct tls *_ctx); +time_t tls_peer_cert_notafter(struct tls *_ctx); +const uint8_t *tls_peer_cert_chain_pem(struct tls *_ctx, size_t *_len); + +const char *tls_conn_alpn_selected(struct tls *_ctx); +const char *tls_conn_cipher(struct tls *_ctx); +int tls_conn_cipher_strength(struct tls *_ctx); +const char *tls_conn_servername(struct tls *_ctx); +int tls_conn_session_resumed(struct tls *_ctx); +const char *tls_conn_version(struct tls *_ctx); + +uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password); +void tls_unload_file(uint8_t *_buf, size_t len); + +int tls_ocsp_process_response(struct tls *_ctx, const unsigned char *_response, + size_t _size); +int tls_peer_ocsp_cert_status(struct tls *_ctx); +int tls_peer_ocsp_crl_reason(struct tls *_ctx); +time_t tls_peer_ocsp_next_update(struct tls *_ctx); +int tls_peer_ocsp_response_status(struct tls *_ctx); +const char *tls_peer_ocsp_result(struct tls *_ctx); +time_t tls_peer_ocsp_revocation_time(struct tls *_ctx); +time_t tls_peer_ocsp_this_update(struct tls *_ctx); +const char *tls_peer_ocsp_url(struct tls *_ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_TLS_H */ diff --git a/Libraries/libressl/install-sh b/Libraries/libressl/install-sh new file mode 100644 index 000000000..ec298b537 --- /dev/null +++ b/Libraries/libressl/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2020-11-14.01; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/Libraries/libressl/libcrypto.pc.in b/Libraries/libressl/libcrypto.pc.in new file mode 100644 index 000000000..11d7ef033 --- /dev/null +++ b/Libraries/libressl/libcrypto.pc.in @@ -0,0 +1,13 @@ +#libcrypto pkg-config source file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: LibreSSL-libcrypto +Description: LibreSSL cryptography library +Version: @VERSION@ +Libs: -L${libdir} -lcrypto +Libs.private: @LIBS@ @PLATFORM_LDADD@ +Cflags: -I${includedir} diff --git a/Libraries/libressl/libssl.pc.in b/Libraries/libressl/libssl.pc.in new file mode 100644 index 000000000..512ec1cbe --- /dev/null +++ b/Libraries/libressl/libssl.pc.in @@ -0,0 +1,13 @@ +#libssl pkg-config source file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: LibreSSL-libssl +Description: Secure Sockets Layer and cryptography libraries +Version: @VERSION@ +Requires.private: libcrypto +Libs: -L${libdir} -lssl +Cflags: -I${includedir} diff --git a/Libraries/libressl/libtls.pc.in b/Libraries/libressl/libtls.pc.in new file mode 100644 index 000000000..d1769299a --- /dev/null +++ b/Libraries/libressl/libtls.pc.in @@ -0,0 +1,13 @@ +#libtls pkg-config source file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: LibreSSL-libtls +Description: Secure communications using the TLS socket protocol. +Version: @VERSION@ +Libs: -L${libdir} -ltls +Libs.private: @LIBS@ @PLATFORM_LDADD@ +Cflags: -I${includedir} diff --git a/Libraries/libressl/ltmain.sh b/Libraries/libressl/ltmain.sh new file mode 100644 index 000000000..5d29bd672 --- /dev/null +++ b/Libraries/libressl/ltmain.sh @@ -0,0 +1,9630 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.2 +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + case " $install_prog " in + *[\\\ /]cp\ *) extra_mode=;; + *) extra_mode='-m 644';; + esac + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $extra_mode $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $extra_mode $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $extra_mode $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog $extra_mode \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append deplibs " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + test -z "$DESTDIR" && need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + else + # XXX + tmp=`echo $libname|sed -e 's,+,_,g' -e 's,-,_,g' -e 's,\.,_,g'` + eval tmp2=\$${tmp}_ltversion + if ! test -z "${SHARED_LIBS_LOG}"; then + if ! test -f ${SHARED_LIBS_LOG}; then + echo "# SHARED_LIBS+= # " >${SHARED_LIBS_LOG} + fi + tmp4=`echo $libname|sed -e 's/^lib//'` + printf "SHARED_LIBS +=\t%-20s %-8s # %s\n" "$tmp4" "$tmp2" "$versuffix" >>${SHARED_LIBS_LOG} + fi + if test -n "$versuffix" && test -n "$tmp2"; then + versuffix=".$tmp2" + fi + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/Libraries/libressl/m4/ax_add_fortify_source.m4 b/Libraries/libressl/m4/ax_add_fortify_source.m4 new file mode 100644 index 000000000..7e1531279 --- /dev/null +++ b/Libraries/libressl/m4/ax_add_fortify_source.m4 @@ -0,0 +1,80 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_ADD_FORTIFY_SOURCE +# +# DESCRIPTION +# +# Check whether -D_FORTIFY_SOURCE=2 can be added to CPPFLAGS without macro +# redefinition warnings, other cpp warnings or linker. Some distributions +# (such as Gentoo Linux) enable _FORTIFY_SOURCE globally in their +# compilers, leading to unnecessary warnings in the form of +# +# :0:0: error: "_FORTIFY_SOURCE" redefined [-Werror] +# : note: this is the location of the previous definition +# +# which is a problem if -Werror is enabled. This macro checks whether +# _FORTIFY_SOURCE is already defined, and if not, adds -D_FORTIFY_SOURCE=2 +# to CPPFLAGS. +# +# Newer mingw-w64 msys2 package comes with a bug in +# headers-git-7.0.0.5546.d200317d-1. It broke -D_FORTIFY_SOURCE support, +# and would need -lssp or -fstack-protector. See +# https://github.com/msys2/MINGW-packages/issues/5803. Try to actually +# link it. +# +# LICENSE +# +# Copyright (c) 2017 David Seifert +# Copyright (c) 2019 Reini Urban +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 4 + +AC_DEFUN([AX_ADD_FORTIFY_SOURCE],[ + ac_save_cflags=$CFLAGS + ac_cwerror_flag=yes + AX_CHECK_COMPILE_FLAG([-Werror],[CFLAGS="$CFLAGS -Werror"]) + AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CPPFLAGS]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([], + [[ + #ifndef _FORTIFY_SOURCE + return 0; + #else + this_is_an_error; + #endif + ]] + )], + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ + #define _FORTIFY_SOURCE 2 + #include + int main() { + char *s = " "; + strcpy(s, "x"); + return strlen(s)-1; + } + ]] + )], + [ + AC_MSG_RESULT([yes]) + CFLAGS=$ac_save_cflags + CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2" + ], [ + AC_MSG_RESULT([no]) + CFLAGS=$ac_save_cflags + ], + ), + [ + AC_MSG_RESULT([no]) + CFLAGS=$ac_save_cflags + ]) +]) diff --git a/Libraries/libressl/m4/ax_check_compile_flag.m4 b/Libraries/libressl/m4/ax_check_compile_flag.m4 new file mode 100644 index 000000000..bd753b34d --- /dev/null +++ b/Libraries/libressl/m4/ax_check_compile_flag.m4 @@ -0,0 +1,53 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/Libraries/libressl/m4/check-hardening-options.m4 b/Libraries/libressl/m4/check-hardening-options.m4 new file mode 100644 index 000000000..4b5784b62 --- /dev/null +++ b/Libraries/libressl/m4/check-hardening-options.m4 @@ -0,0 +1,105 @@ + +AC_DEFUN([CHECK_CFLAG], [ + AC_LANG_ASSERT(C) + AC_MSG_CHECKING([if $saved_CC supports "$1"]) + old_cflags="$CFLAGS" + CFLAGS="$1 -Wall -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[printf("Hello")]])], + [AC_MSG_RESULT([yes]) + CFLAGS=$old_cflags + HARDEN_CFLAGS="$HARDEN_CFLAGS $1"], + [AC_MSG_RESULT([no]) + CFLAGS=$old_cflags + [$2]]) +]) + +AC_DEFUN([CHECK_LDFLAG], [ + AC_LANG_ASSERT(C) + AC_MSG_CHECKING([if $saved_LD supports "$1"]) + old_ldflags="$LDFLAGS" + LDFLAGS="$1 -Wall -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[printf("Hello")]])], + [AC_MSG_RESULT([yes]) + LDFLAGS=$old_ldflags + HARDEN_LDFLAGS="$HARDEN_LDFLAGS $1"], + [AC_MSG_RESULT([no]) + LDFLAGS=$old_ldflags + [$2]]) +]) + +AC_DEFUN([DISABLE_AS_EXECUTABLE_STACK], [ + save_cflags="$CFLAGS" + CFLAGS= + AC_MSG_CHECKING([whether AS supports .note.GNU-stack]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + __asm__(".section .note.GNU-stack,\"\",@progbits");]])], + [AC_MSG_RESULT([yes])] + [AM_CFLAGS=-DHAVE_GNU_STACK], + [AC_MSG_RESULT([no])] + ) + CFLAGS="$save_cflags $AM_CFLAGS" +]) + + +AC_DEFUN([CHECK_C_HARDENING_OPTIONS], [ + + AC_ARG_ENABLE([hardening], + [AS_HELP_STRING([--disable-hardening], + [Disable options to frustrate memory corruption exploits])], + [], [enable_hardening=yes]) + + AC_ARG_ENABLE([windows-ssp], + [AS_HELP_STRING([--enable-windows-ssp], + [Enable building the stack smashing protection on + Windows. This currently distributing libssp-0.dll.])]) + + # We want to check for compiler flag support. Prior to clang v5.1, there was no + # way to make clang's "argument unused" warning fatal. So we invoke the + # compiler through a wrapper script that greps for this message. + saved_CC="$CC" + saved_LD="$LD" + flag_wrap="$srcdir/scripts/wrap-compiler-for-flag-check" + CC="$flag_wrap $CC" + LD="$flag_wrap $LD" + + AS_IF([test "x$enable_hardening" = "xyes"], [ + # Tell GCC to NOT optimize based on signed arithmetic overflow + CHECK_CFLAG([[-fno-strict-overflow]]) + + # _FORTIFY_SOURCE replaces builtin functions with safer versions. + AS_IF([test "x$HOST_OS" != "xwin"], [ + AX_ADD_FORTIFY_SOURCE + ]) + + # Enable read only relocations + CHECK_LDFLAG([[-Wl,-z,relro]]) + CHECK_LDFLAG([[-Wl,-z,now]]) + + # Windows security flags + AS_IF([test "x$HOST_OS" = "xwin"], [ + CHECK_LDFLAG([[-Wl,--nxcompat]]) + CHECK_LDFLAG([[-Wl,--dynamicbase]]) + CHECK_LDFLAG([[-Wl,--high-entropy-va]]) + ]) + + # Use stack-protector-strong if available; if not, fallback to + # stack-protector-all which is considered to be overkill + AS_IF([test "x$enable_windows_ssp" = "xyes" -o "x$HOST_OS" != "xwin"], [ + CHECK_CFLAG([[-fstack-protector-strong]], + CHECK_CFLAG([[-fstack-protector-all]], + AC_MSG_WARN([compiler does not appear to support stack protection]) + ) + ) + AS_IF([test "x$HOST_OS" = "xwin"], [ + AC_SEARCH_LIBS([__stack_chk_guard],[ssp]) + ]) + ]) + ]) + + # Restore CC, LD + CC="$saved_CC" + LD="$saved_LD" + + CFLAGS="$CFLAGS $HARDEN_CFLAGS" + LDFLAGS="$LDFLAGS $HARDEN_LDFLAGS" +]) diff --git a/Libraries/libressl/m4/check-libc.m4 b/Libraries/libressl/m4/check-libc.m4 new file mode 100644 index 000000000..dc8d6bd7c --- /dev/null +++ b/Libraries/libressl/m4/check-libc.m4 @@ -0,0 +1,172 @@ +AC_DEFUN([CHECK_LIBC_COMPAT], [ +# Check for libc headers +AC_CHECK_HEADERS([endian.h machine/endian.h err.h readpassphrase.h]) +AC_CHECK_HEADERS([netinet/ip.h], [], [], +[#include +#include +]) +AC_HEADER_RESOLV +# Check for general libc functions +AC_CHECK_FUNCS([asprintf freezero memmem]) +AC_CHECK_FUNCS([readpassphrase reallocarray recallocarray]) +AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum]) +AC_CHECK_FUNCS([timegm _mkgmtime timespecsub]) +AC_CHECK_FUNCS([getopt getprogname syslog syslog_r]) +AC_CACHE_CHECK([for getpagesize], ac_cv_func_getpagesize, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + getpagesize(); +]])], + [ ac_cv_func_getpagesize="yes" ], + [ ac_cv_func_getpagesize="no" + ]) +]) +AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) +AM_CONDITIONAL([HAVE_FREEZERO], [test "x$ac_cv_func_freezero" = xyes]) +AM_CONDITIONAL([HAVE_GETPAGESIZE], [test "x$ac_cv_func_getpagesize" = xyes]) +AM_CONDITIONAL([HAVE_GETOPT], [test "x$ac_cv_func_getopt" = xyes]) +AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) +AM_CONDITIONAL([HAVE_READPASSPHRASE], [test "x$ac_cv_func_readpassphrase" = xyes]) +AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes]) +AM_CONDITIONAL([HAVE_RECALLOCARRAY], [test "x$ac_cv_func_recallocarray" = xyes]) +AM_CONDITIONAL([HAVE_STRLCAT], [test "x$ac_cv_func_strlcat" = xyes]) +AM_CONDITIONAL([HAVE_STRLCPY], [test "x$ac_cv_func_strlcpy" = xyes]) +AM_CONDITIONAL([HAVE_STRNDUP], [test "x$ac_cv_func_strndup" = xyes]) +AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes]) +AM_CONDITIONAL([HAVE_STRSEP], [test "x$ac_cv_func_strsep" = xyes]) +AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes]) +AM_CONDITIONAL([HAVE_TIMEGM], [test "x$ac_cv_func_timegm" = xyes]) +AM_CONDITIONAL([HAVE_GETPROGNAME], [test "x$ac_cv_func_getprogname" = xyes]) +AM_CONDITIONAL([HAVE_SYSLOG], [test "x$ac_cv_func_syslog" = xyes]) +AM_CONDITIONAL([HAVE_SYSLOG_R], [test "x$ac_cv_func_syslog_r" = xyes]) +]) + +AC_DEFUN([CHECK_SYSCALL_COMPAT], [ +AC_CHECK_FUNCS([accept4 pipe2 pledge poll socketpair]) +AM_CONDITIONAL([HAVE_ACCEPT4], [test "x$ac_cv_func_accept4" = xyes]) +AM_CONDITIONAL([HAVE_PIPE2], [test "x$ac_cv_func_pipe2" = xyes]) +AM_CONDITIONAL([HAVE_PLEDGE], [test "x$ac_cv_func_pledge" = xyes]) +AM_CONDITIONAL([HAVE_POLL], [test "x$ac_cv_func_poll" = xyes]) +AM_CONDITIONAL([HAVE_SOCKETPAIR], [test "x$ac_cv_func_socketpair" = xyes]) +]) + +AC_DEFUN([CHECK_B64_NTOP], [ +AC_SEARCH_LIBS([b64_ntop],[resolv]) +AC_SEARCH_LIBS([__b64_ntop],[resolv]) +AC_CACHE_CHECK([for b64_ntop], ac_cv_have_b64_ntop_arg, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include + ]], [[ b64_ntop(NULL, 0, NULL, 0); ]])], + [ ac_cv_have_b64_ntop_arg="yes" ], + [ ac_cv_have_b64_ntop_arg="no" + ]) +]) +AM_CONDITIONAL([HAVE_B64_NTOP], [test "x$ac_cv_func_b64_ntop_arg" = xyes]) +]) + +AC_DEFUN([CHECK_CRYPTO_COMPAT], [ +# Check crypto-related libc functions and syscalls +AC_CHECK_FUNCS([arc4random arc4random_buf arc4random_uniform]) +AC_CHECK_FUNCS([explicit_bzero getauxval]) + +AC_CACHE_CHECK([for getentropy], ac_cv_func_getentropy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + +/* + * Explanation: + * + * - iOS <= 10.1 fails because of missing sys/random.h + * + * - in macOS 10.12 getentropy is not tagged as introduced in + * 10.12 so we cannot use it for target < 10.12 + */ +#ifdef __APPLE__ +# include +# include + +# if (TARGET_OS_IPHONE || TARGET_OS_SIMULATOR) +# include /* Not available as of iOS <= 10.1 */ +# else + +# include /* Pre 10.12 systems should die here */ + +/* Based on: https://gitweb.torproject.org/tor.git/commit/?id=16fcbd21 */ +# ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 /* Robustness */ +# endif +# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) +# if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +# error "Targeting on Mac OSX 10.11 or earlier" +# endif +# endif + +# endif +#endif /* __APPLE__ */ + ]], [[ + char buffer; + (void)getentropy(&buffer, sizeof (buffer)); +]])], + [ ac_cv_func_getentropy="yes" ], + [ ac_cv_func_getentropy="no" + ]) +]) + +AC_CHECK_FUNCS([timingsafe_bcmp timingsafe_memcmp]) +AM_CONDITIONAL([HAVE_ARC4RANDOM], [test "x$ac_cv_func_arc4random" = xyes]) +AM_CONDITIONAL([HAVE_ARC4RANDOM_BUF], [test "x$ac_cv_func_arc4random_buf" = xyes]) +AM_CONDITIONAL([HAVE_ARC4RANDOM_UNIFORM], [test "x$ac_cv_func_arc4random_uniform" = xyes]) +AM_CONDITIONAL([HAVE_EXPLICIT_BZERO], [test "x$ac_cv_func_explicit_bzero" = xyes]) +AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = xyes]) +AM_CONDITIONAL([HAVE_TIMINGSAFE_BCMP], [test "x$ac_cv_func_timingsafe_bcmp" = xyes]) +AM_CONDITIONAL([HAVE_TIMINGSAFE_MEMCMP], [test "x$ac_cv_func_timingsafe_memcmp" = xyes]) + +# Override arc4random_buf implementations with known issues +AM_CONDITIONAL([HAVE_ARC4RANDOM_BUF], + [test "x$USE_BUILTIN_ARC4RANDOM" != xyes \ + -a "x$ac_cv_func_arc4random_buf" = xyes]) + +# Check for getentropy fallback dependencies +AC_CHECK_FUNCS([getauxval]) +AC_SEARCH_LIBS([dl_iterate_phdr],[dl]) +AC_CHECK_FUNCS([dl_iterate_phdr]) + +AC_SEARCH_LIBS([pthread_once],[pthread]) +AC_SEARCH_LIBS([pthread_mutex_lock],[pthread]) +AC_SEARCH_LIBS([clock_gettime],[rt posix4]) +AC_CHECK_FUNCS([clock_gettime]) +AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "x$ac_cv_func_clock_gettime" = xyes]) +]) + +AC_DEFUN([CHECK_VA_COPY], [ +AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +va_list x,y; + ]], [[ va_copy(x,y); ]])], + [ ac_cv_have_va_copy="yes" ], + [ ac_cv_have_va_copy="no" + ]) +]) +if test "x$ac_cv_have_va_copy" = "xyes" ; then + AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists]) +fi + +AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +va_list x,y; + ]], [[ __va_copy(x,y); ]])], + [ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no" + ]) +]) +if test "x$ac_cv_have___va_copy" = "xyes" ; then + AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists]) +fi +]) diff --git a/Libraries/libressl/m4/check-os-options.m4 b/Libraries/libressl/m4/check-os-options.m4 new file mode 100644 index 000000000..c73709dbb --- /dev/null +++ b/Libraries/libressl/m4/check-os-options.m4 @@ -0,0 +1,163 @@ +AC_DEFUN([CHECK_OS_OPTIONS], [ + +CFLAGS="$CFLAGS -Wall -std=gnu99 -fno-strict-aliasing" +BUILD_NC=yes + +case $host_os in + *aix*) + HOST_OS=aix + if test "`echo $CC | cut -d ' ' -f 1`" != "gcc" ; then + CFLAGS="-qnoansialias $USER_CFLAGS" + fi + AC_SUBST([PLATFORM_LDADD], ['-lperfstat']) + ;; + *cygwin*) + HOST_OS=cygwin + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" + ;; + *darwin*) + HOST_OS=darwin + HOST_ABI=macosx + # + # Don't use arc4random on systems before 10.12 because of + # weak seed on failure to open /dev/random, based on latest + # public source: + # http://www.opensource.apple.com/source/Libc/Libc-997.90.3/gen/FreeBSD/arc4random.c + # + # We use the presence of getentropy() to detect 10.12. The + # following check take into account that: + # + # - iOS <= 10.1 fails because of missing getentropy and + # hence they miss sys/random.h + # + # - in macOS 10.12 getentropy is not tagged as introduced in + # 10.12 so we cannot use it for target < 10.12 + # + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include /* Systems without getentropy() should die here */ + +/* Based on: https://gitweb.torproject.org/tor.git/commit/?id=16fcbd21 */ +#ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 +#endif +#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) +# if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +# error "Running on Mac OSX 10.11 or earlier" +# endif +#endif + ]], [[ +char buf[1]; getentropy(buf, 1); + ]])], + [ USE_BUILTIN_ARC4RANDOM=no ], + [ USE_BUILTIN_ARC4RANDOM=yes ] + ) + AC_MSG_CHECKING([whether to use builtin arc4random]) + AC_MSG_RESULT([$USE_BUILTIN_ARC4RANDOM]) + # Not available on iOS + AC_CHECK_HEADER([arpa/telnet.h], [], [BUILD_NC=no]) + ;; + *freebsd*) + HOST_OS=freebsd + HOST_ABI=elf + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#if __FreeBSD_version < 1200000 + undefined +#endif + ]], [[]])], + [ USE_BUILTIN_ARC4RANDOM=no ], + [ USE_BUILTIN_ARC4RANDOM=yes ] + ) + AC_SUBST([PROG_LDADD], ['-lthr']) + ;; + *hpux*) + HOST_OS=hpux; + if test "`echo $host_os | cut -c 1-4`" = "ia64" ; then + if test "`echo $CC | cut -d ' ' -f 1`" = "gcc" ; then + CFLAGS="$CFLAGS -mlp64" + else + CFLAGS="+DD64" + fi + fi + if ! test "`echo $CC | cut -d ' ' -f 1`" = "gcc" ; then + CFLAGS="-g -O2 +Otype_safety=off $CFLAGS $USER_CFLAGS" + fi + CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D__STRICT_ALIGNMENT" + ;; + *linux*) + HOST_OS=linux + HOST_ABI=elf + CPPFLAGS="$CPPFLAGS -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -D_GNU_SOURCE" + ;; + *midipix*) + HOST_OS=midipix + CPPFLAGS="$CPPFLAGS -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -D_GNU_SOURCE" + ;; + *netbsd*) + HOST_OS=netbsd + HOST_ABI=elf + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#if __NetBSD_Version__ < 700000001 + undefined +#endif + ]], [[]])], + [ USE_BUILTIN_ARC4RANDOM=no ], + [ USE_BUILTIN_ARC4RANDOM=yes ] + ) + CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE" + ;; + *openbsd* | *bitrig*) + HOST_OS=openbsd + HOST_ABI=elf + AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD gcc has bounded]) + AC_DEFINE([HAVE_ATTRIBUTE__DEAD], [1], [OpenBSD gcc has __dead]) + ;; + *mingw*) + HOST_OS=win + HOST_ABI=mingw64 + BUILD_NC=no + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_POSIX -D_POSIX_SOURCE -D__USE_MINGW_ANSI_STDIO" + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_THREAD_SAFE_FUNCTIONS" + CPPFLAGS="$CPPFLAGS -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600" + CPPFLAGS="$CPPFLAGS" + AC_SUBST([PLATFORM_LDADD], ['-lws2_32 -lbcrypt']) + ;; + *solaris*) + HOST_OS=solaris + HOST_ABI=elf + CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 -DBSD_COMP" + AC_SUBST([PLATFORM_LDADD], ['-ldl -lmd -lnsl -lsocket']) + ;; + *) ;; +esac + +# Check if time_t is sized correctly +AC_CHECK_SIZEOF([time_t], [time.h]) +AM_CONDITIONAL([SMALL_TIME_T], [test "$ac_cv_sizeof_time_t" = "4"]) +if test "$ac_cv_sizeof_time_t" = "4"; then + AC_DEFINE([SMALL_TIME_T]) + echo " ** Warning, this system is unable to represent times past 2038" + echo " ** It will behave incorrectly when handling valid RFC5280 dates" + + if test "$host_os" = "mingw32" ; then + echo " **" + echo " ** You can solve this by adjusting the build flags in your" + echo " ** mingw-w64 toolchain. Refer to README.windows for details." + fi +fi + +AM_CONDITIONAL([HOST_AIX], [test x$HOST_OS = xaix]) +AM_CONDITIONAL([HOST_CYGWIN], [test x$HOST_OS = xcygwin]) +AM_CONDITIONAL([HOST_DARWIN], [test x$HOST_OS = xdarwin]) +AM_CONDITIONAL([HOST_FREEBSD], [test x$HOST_OS = xfreebsd]) +AM_CONDITIONAL([HOST_HPUX], [test x$HOST_OS = xhpux]) +AM_CONDITIONAL([HOST_LINUX], [test x$HOST_OS = xlinux]) +AM_CONDITIONAL([HOST_MIDIPIX], [test x$HOST_OS = xmidipix]) +AM_CONDITIONAL([HOST_NETBSD], [test x$HOST_OS = xnetbsd]) +AM_CONDITIONAL([HOST_OPENBSD], [test x$HOST_OS = xopenbsd]) +AM_CONDITIONAL([HOST_SOLARIS], [test x$HOST_OS = xsolaris]) +AM_CONDITIONAL([HOST_WIN], [test x$HOST_OS = xwin]) +]) diff --git a/Libraries/libressl/m4/disable-compiler-warnings.m4 b/Libraries/libressl/m4/disable-compiler-warnings.m4 new file mode 100644 index 000000000..279272211 --- /dev/null +++ b/Libraries/libressl/m4/disable-compiler-warnings.m4 @@ -0,0 +1,29 @@ +AC_DEFUN([DISABLE_COMPILER_WARNINGS], [ +# Clang throws a lot of warnings when it does not understand a flag. Disable +# this warning for now so other warnings are visible. +AC_MSG_CHECKING([if compiling with clang]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#ifndef __clang__ + not clang +#endif + ]])], + [CLANG=yes], + [CLANG=no] +) +AC_MSG_RESULT([$CLANG]) +AS_IF([test "x$CLANG" = "xyes"], [CLANG_FLAGS=-Qunused-arguments]) +CFLAGS="$CFLAGS $CLANG_FLAGS" +LDFLAGS="$LDFLAGS $CLANG_FLAGS" + +# Removing the dependency on -Wno-pointer-sign should be a goal. These are +# largely unsigned char */char* mismatches in asn1 functions. +save_cflags="$CFLAGS" +CFLAGS=-Wno-pointer-sign +AC_MSG_CHECKING([whether CC supports -Wno-pointer-sign]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], + [AC_MSG_RESULT([yes])] + [AM_CFLAGS=-Wno-pointer-sign], + [AC_MSG_RESULT([no])] +) +CFLAGS="$save_cflags $AM_CFLAGS" +]) diff --git a/Libraries/libressl/m4/libtool.m4 b/Libraries/libressl/m4/libtool.m4 new file mode 100644 index 000000000..44e0ecff1 --- /dev/null +++ b/Libraries/libressl/m4/libtool.m4 @@ -0,0 +1,7982 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/Libraries/libressl/m4/ltoptions.m4 b/Libraries/libressl/m4/ltoptions.m4 new file mode 100644 index 000000000..5d9acd8e2 --- /dev/null +++ b/Libraries/libressl/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/Libraries/libressl/m4/ltsugar.m4 b/Libraries/libressl/m4/ltsugar.m4 new file mode 100644 index 000000000..9000a057d --- /dev/null +++ b/Libraries/libressl/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/Libraries/libressl/m4/ltversion.m4 b/Libraries/libressl/m4/ltversion.m4 new file mode 100644 index 000000000..07a8602d4 --- /dev/null +++ b/Libraries/libressl/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/Libraries/libressl/m4/lt~obsolete.m4 b/Libraries/libressl/m4/lt~obsolete.m4 new file mode 100644 index 000000000..c573da90c --- /dev/null +++ b/Libraries/libressl/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/Libraries/libressl/man/ACCESS_DESCRIPTION_new.3 b/Libraries/libressl/man/ACCESS_DESCRIPTION_new.3 new file mode 100644 index 000000000..15156ffca --- /dev/null +++ b/Libraries/libressl/man/ACCESS_DESCRIPTION_new.3 @@ -0,0 +1,151 @@ +.\" $OpenBSD: ACCESS_DESCRIPTION_new.3,v 1.6 2022/03/31 17:27:16 naddy Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt ACCESS_DESCRIPTION_NEW 3 +.Os +.Sh NAME +.Nm ACCESS_DESCRIPTION_new , +.Nm ACCESS_DESCRIPTION_free , +.Nm AUTHORITY_INFO_ACCESS_new , +.Nm AUTHORITY_INFO_ACCESS_free +.Nd X.509 information access extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft ACCESS_DESCRIPTION * +.Fn ACCESS_DESCRIPTION_new void +.Ft void +.Fn ACCESS_DESCRIPTION_free "ACCESS_DESCRIPTION *ad" +.Ft AUTHORITY_INFO_ACCESS +.Fn AUTHORITY_INFO_ACCESS_new void +.Ft void +.Fn AUTHORITY_INFO_ACCESS_free "AUTHORITY_INFO_ACCESS *aia" +.Sh DESCRIPTION +Using the information access extensions, certificates and certificate +revocation lists can point to auxiliary information and services +available online, for example online validation services or CA +policy data. +.Pp +.Fn ACCESS_DESCRIPTION_new +allocates and initializes an empty +.Vt ACCESS_DESCRIPTION +object, representing an ASN.1 +.Vt AccessDescription +structure defined in RFC 5280 section 4.2.2.1. +It can hold a pointer to a +.Vt GENERAL_NAME +object documented in +.Xr GENERAL_NAME_new 3 +and an access method identifier. +.Fn ACCESS_DESCRIPTION_free +frees +.Fa ad . +.Pp +The access method identifier is somewhat misnamed; it identifies +the type and format of the information provided. +How to access that information is often obvious from the +.Vt GENERAL_NAME +which may for example include a uniform resource identifier. +.Pp +Four standard access method identifiers are defined in RFC 5280: +.Bl -bullet +.It +.Qq id-ad-caIssuers +can occur in the authority information access extension of certificates +and certificate revocation lists and provides access to certificates +issued to the CA that issued the certificate, or provides access +to certificates used for signing the CRL, in order to help constructing +a certification path. +.It +.Qq id-ad-ocsp +can occur in the authority information access extension of certificates +and provides access to revocation information via the Online +Certificate Status Protocol (OCSP) defined in RFC 6960. +.It +.Qq id-ad-caRepository +can occur in the subject information access extension of CA +certificates and provides access to an online repository of +certificates issued by the CA. +.It +.Qq id-ad-timeStamping +can occur in the subject information access extension of end entity +certificates and indicates that the subject offers timestamping +services using the Time Stamp Protocol defined in RFC 3161. +.El +.Pp +.Fn AUTHORITY_INFO_ACCESS_new +allocates and initializes an empty +.Vt AUTHORITY_INFO_ACCESS +object, which is a +.Vt STACK_OF(ACCESS_DESCRIPTION) +and represents an ASN.1 +.Vt AuthorityInfoAccessSyntax +structure defined in RFC 5280 section 4.2.2.1. +It can be used for the authority information access extension of +certificates and certificate revocation lists and for the subject +information access extension of certificates. +.Fn AUTHORITY_INFO_ACCESS_free +frees +.Fa aia . +.Sh RETURN VALUES +.Fn ACCESS_DESCRIPTION_new +and +.Fn AUTHORITY_INFO_ACCESS_new +return the new +.Vt ACCESS_DESCRIPTION +or +.Vt AUTHORITY_INFO_ACCESS +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_ACCESS_DESCRIPTION 3 , +.Xr DIST_POINT_new 3 , +.Xr GENERAL_NAME_new 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr TS_REQ_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +These extensions are only defined in the following RFC and not +specified in the underlying X.509 standard. +.Pp +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.2.1: Certificate Extensions: Authority Information Access +.It +section 4.2.2.2: Certificate Extensions: Subject Information Access +.It +section 5.2.7: CRL Extensions: Authority Information Access +.El +.Pp +Regarding OCSP and TSP, see: +.Pp +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol +.Pp +RFC 3161: Internet X.509 Public Key Infrastructure Time-Stamp Protocol +.Sh HISTORY +.Fn ACCESS_DESCRIPTION_new , +.Fn ACCESS_DESCRIPTION_free , +.Fn AUTHORITY_INFO_ACCESS_new , +and +.Fn AUTHORITY_INFO_ACCESS_free +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/AES_encrypt.3 b/Libraries/libressl/man/AES_encrypt.3 new file mode 100644 index 000000000..f022848a6 --- /dev/null +++ b/Libraries/libressl/man/AES_encrypt.3 @@ -0,0 +1,173 @@ +.\" $OpenBSD: AES_encrypt.3,v 1.1 2019/08/28 10:37:42 schwarze Exp $ +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 28 2019 $ +.Dt AES_ENCRYPT 3 +.Os +.Sh NAME +.Nm AES_set_encrypt_key , +.Nm AES_set_decrypt_key , +.Nm AES_encrypt , +.Nm AES_decrypt , +.Nm AES_cbc_encrypt +.Nd low-level interface to the AES symmetric cipher +.Sh SYNOPSIS +.In openssl/aes.h +.Ft int +.Fo AES_set_encrypt_key +.Fa "const unsigned char *userKey" +.Fa "const int bits" +.Fa "AES_KEY *key" +.Fc +.Ft int +.Fo AES_set_decrypt_key +.Fa "const unsigned char *userKey" +.Fa "const int bits" +.Fa "AES_KEY *key" +.Fc +.Ft void +.Fo AES_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "const AES_KEY *key" +.Fc +.Ft void +.Fo AES_decrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "const AES_KEY *key" +.Fc +.Ft void +.Fo AES_cbc_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "size_t length" +.Fa "const AES_KEY *key" +.Fa "unsigned char *ivec" +.Fa "const int enc" +.Fc +.Sh DESCRIPTION +These function provide a low-level interface to the AES symmetric +cipher algorithm, also called Rijndael. +For reasons of flexibility, it is recommended that application +programs use the high-level interface described in +.Xr EVP_EncryptInit 3 +and +.Xr EVP_aes_128_cbc 3 +instead whenever possible. +.Pp +.Vt AES_KEY +is a structure that can hold up to 60 +.Vt int +values and a number of rounds. +.Pp +.Fn AES_set_encrypt_key +expands the +.Fa userKey , +which is +.Fa bits +long, into the +.Fa key +structure to prepare for encryption. +The number of bits and bytes read from +.Fa userKey , +the number of +.Vt int +values stored into +.Fa key , +and the number of rounds are as follows: +.Pp +.Bl -column bits bytes ints rounds -offset indent -compact +.It bits Ta bytes Ta ints Ta rounds +.It 128 Ta 16 Ta 44 Ta 10 +.It 192 Ta 24 Ta 52 Ta 12 +.It 256 Ta 32 Ta 60 Ta 14 +.El +.Pp +.Fn AES_set_decrypt_key +does the same, but in preparation for decryption. +.Pp +.Fn AES_encrypt +reads a single 16 byte block from +.Pf * Fa in , +encrypts it with the +.Fa key , +and writes the 16 resulting bytes to +.Pf * Fa out . +The 16 byte buffers starting at +.Fa in +and +.Fa out +can overlap, and +.Fa in +and +.Fa out +can even point to the same memory location. +.Pp +.Fn AES_decrypt +decrypts a single block and is otherwise identical to +.Fn AES_encrypt . +.Pp +If +.Fa enc +is non-zero, +.Fn AES_cbc_encrypt +encrypts +.Fa len +bytes at +.Fa in +to +.Fa out +using the 128 bit +.Fa key +and the 128 bit +initialization vector +.Fa ivec +in CBC mode. +If +.Fa enc +is 0, +.Fn AES_cbc_encrypt +performs the corresponding decryption. +.Sh RETURN VALUES +.Fn AES_set_encrypt_key +and +.Fn AES_set_decrypt_key +return 0 for success, -1 if +.Fa userKey +or +.Fa key +is +.Dv NULL , +or -2 if the number of +.Fa bits +is unsupported. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr EVP_aes_128_cbc 3 , +.Xr EVP_EncryptInit 3 +.Sh STANDARDS +ISO/IEC 18033-3:2010 +Information technology \(em Security techniques \(em +Encryption algorithms \(em Part 3: Block ciphers +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . +.Sh AUTHORS +.An Vincent Rijmen +.An Antoon Bosselaers +.An Paulo Barreto diff --git a/Libraries/libressl/man/ASIdentifiers_new.3 b/Libraries/libressl/man/ASIdentifiers_new.3 new file mode 100644 index 000000000..d8473b81a --- /dev/null +++ b/Libraries/libressl/man/ASIdentifiers_new.3 @@ -0,0 +1,138 @@ +.\" $OpenBSD: ASIdentifiers_new.3,v 1.11 2023/09/30 18:16:44 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 30 2023 $ +.Dt ASIDENTIFIERS_NEW 3 +.Os +.Sh NAME +.Nm ASIdentifiers_new , +.Nm ASIdentifiers_free , +.Nm d2i_ASIdentifiers , +.Nm i2d_ASIdentifiers +.Nd RFC 3779 autonomous system identifier delegation extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft ASIdentifiers * +.Fo ASIdentifiers_new +.Fa "void" +.Fc +.Ft void +.Fo ASIdentifiers_free +.Fa "ASIdentifiers *asid" +.Fc +.Ft ASIdentifiers * +.Fo d2i_ASIdentifiers +.Fa "ASIdentifiers **asid" +.Fa "const unsigned char **in" +.Fa "long len" +.Fc +.Ft int +.Fo i2d_ASIdentifiers +.Fa "ASIdentifiers *asid" +.Fa "unsigned char **out" +.Fc +.Sh DESCRIPTION +RFC 3779 defines two X.509v3 certificate extensions that allow the +delegation of +IP addresses and autonomous system (AS) identifiers +from the issuer to the subject of the certificate. +An +.Vt ASIdentifiers +object contains collections of individual AS numbers and +ranges of AS numbers to be delegated. +.Pp +.Fn ASIdentifiers_new +allocates and initializes a new, empty +.Vt ASIdentifiers +object that can be populated with +.Xr X509v3_asid_add_id_or_range 3 . +See +.Xr ASRange_new 3 +for implementation details. +.Pp +.Fn ASIdentifiers_free +frees +.Fa asid +including any data contained in it. +If +.Fa asid +is +.Dv NULL , +no action occurs. +.Pp +.Fn d2i_ASIdentifiers +and +.Fn i2d_ASIdentifiers +decode and encode ASN.1 +.Vt ASIdentifiers +objects as defined in RFC 3779, section 3.2.3.1. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +In order for the encoding produced by +.Fn i2d_ASIdentifiers +to conform to RFC 3779, +.Fa asid +must be in +.Dq canonical form , +see +.Xr X509v3_asid_canonize 3 . +.Sh RETURN VALUES +.Fn ASIdentifiers_new +returns a new +.Vt ASIdentifiers +object or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_ASIdentifiers +returns an +.Vt ASIdentifiers +object or +.Dv NULL +if a decoding or memory allocation error occurs. +.Pp +.Fn i2d_ASIdentifiers +returns the number of bytes successfully encoded +or a value <= 0 if an error occurs. +.Sh SEE ALSO +.Xr ASRange_new 3 , +.Xr crypto 3 , +.Xr IPAddressRange_new 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_addr_get_range 3 , +.Xr X509v3_addr_inherits 3 , +.Xr X509v3_addr_subset 3 , +.Xr X509v3_addr_validate_path 3 , +.Xr X509v3_asid_add_id_or_range 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 3: Autonomous System Identifier Delegation Extension +.El +.Pp +RFC 7020: The Internet Numbers Registry System +.Pp +RFC 7249: Internet Numbers Registries +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +There are no corresponding functions for the RFC 3779 +IP address delegation extension represented by +.Vt IPAddrBlocks . diff --git a/Libraries/libressl/man/ASN1_BIT_STRING_set.3 b/Libraries/libressl/man/ASN1_BIT_STRING_set.3 new file mode 100644 index 000000000..5d863d19d --- /dev/null +++ b/Libraries/libressl/man/ASN1_BIT_STRING_set.3 @@ -0,0 +1,138 @@ +.\" $OpenBSD: ASN1_BIT_STRING_set.3,v 1.4 2023/07/28 05:53:10 tb Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 28 2023 $ +.Dt ASN1_BIT_STRING_SET 3 +.Os +.Sh NAME +.Nm ASN1_BIT_STRING_set , +.Nm ASN1_BIT_STRING_set_bit , +.Nm ASN1_BIT_STRING_get_bit +.Nd ASN.1 BIT STRING accessors +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_BIT_STRING_set +.Fa "ASN1_BIT_STRING *bitstr" +.Fa "unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo ASN1_BIT_STRING_set_bit +.Fa "ASN1_BIT_STRING *bitstr" +.Fa "int bitnumber" +.Fa "int set" +.Fc +.Ft int +.Fo ASN1_BIT_STRING_get_bit +.Fa "ASN1_BIT_STRING *bitstr" +.Fa "int bitnumber" +.Fc +.Sh DESCRIPTION +.Fn ASN1_BIT_STRING_set +sets the length attribute of +.Fa bitstr +to +.Fa len +and copies that number of bytes from +.Fa data +into +.Fa bitstr , +overwriting any previous data, by merely calling +.Xr ASN1_STRING_set 3 . +This function does no validation whatsoever. +In particular, it neither checks that +.Fa bitstr +is actually of the type +.Dv V_ASN1_BIT_STRING +nor, even if it is, that the +.Fa data +and +.Fa len +arguments make sense for this particular bit string. +.Pp +If the +.Fa set +argument is non-zero, +.Fn ASN1_BIT_STRING_set_bit +sets the bit with the given +.Fa bitnumber +in the +.Fa bitstr ; +otherwise, it clears that bit. +A +.Fa bitnumber +of 0 addresses the most significant bit in the first data byte of +.Fa bitstr , +7 the least significant bit in the same byte, +8 the most significant bit in the second data byte, and so on. +.Pp +If setting a bit is requested beyond the last existing data byte, +additional bytes are added to the +.Fa bitstr +as needed. +After clearing a bit, any trailing NUL bytes are removed from the +.Fa bitstr . +.Pp +.Fn ASN1_BIT_STRING_get_bit +checks that the bit with the given +.Fa bitnumber +is set in +.Fa bitstr . +.Sh RETURN VALUES +.Fn ASN1_BIT_STRING_set +returns 1 on success or 0 if memory allocation fails or if +.Fa data +is +.Dv NULL +and +.Fa len +is \-1 in the same call. +.Pp +.Fn ASN1_BIT_STRING_set_bit +returns 1 on success or 0 if +.Fa bitstr +is +.Dv NULL +or if memory allocation fails. +.Pp +.Fn ASN1_BIT_STRING_get_bit +returns 1 if the bit with the given +.Fa bitnumber +is set in the +.Fa bitstr +or 0 if +.Fa bitstr +is +.Dv NULL , +if +.Fa bitnumber +points beyond the last data byte in +.Fa bitstr , +or if the requested bit is not set. +.Sh SEE ALSO +.Xr ASN1_BIT_STRING_new 3 , +.Xr ASN1_STRING_set 3 , +.Xr d2i_ASN1_BIT_STRING 3 +.Sh HISTORY +.Fn ASN1_BIT_STRING_set +first appeared in SSLeay 0.6.5. +.Fn ASN1_BIT_STRING_set_bit +and +.Fn ASN1_BIT_STRING_get_bit +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/ASN1_INTEGER_get.3 b/Libraries/libressl/man/ASN1_INTEGER_get.3 new file mode 100644 index 000000000..84f566eda --- /dev/null +++ b/Libraries/libressl/man/ASN1_INTEGER_get.3 @@ -0,0 +1,428 @@ +.\" $OpenBSD: ASN1_INTEGER_get.3,v 1.7 2023/05/22 19:38:04 tb Exp $ +.\" selective merge up to: +.\" OpenSSL man3/ASN1_INTEGER_get_int64 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2021, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 22 2023 $ +.Dt ASN1_INTEGER_GET 3 +.Os +.Sh NAME +.Nm ASN1_INTEGER_get_uint64 , +.Nm ASN1_INTEGER_get_int64 , +.Nm ASN1_INTEGER_get , +.Nm ASN1_INTEGER_set_uint64 , +.Nm ASN1_INTEGER_set_int64 , +.Nm ASN1_INTEGER_set , +.Nm ASN1_INTEGER_cmp , +.Nm ASN1_INTEGER_dup , +.Nm BN_to_ASN1_INTEGER , +.Nm ASN1_INTEGER_to_BN , +.Nm ASN1_ENUMERATED_get_int64 , +.Nm ASN1_ENUMERATED_get , +.Nm ASN1_ENUMERATED_set_int64 , +.Nm ASN1_ENUMERATED_set , +.Nm BN_to_ASN1_ENUMERATED , +.Nm ASN1_ENUMERATED_to_BN +.Nd ASN.1 INTEGER and ENUMERATED utilities +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_INTEGER_get_uint64 +.Fa "uint64_t *out_val" +.Fa "const ASN1_INTEGER *a" +.Fc +.Ft int +.Fo ASN1_INTEGER_get_int64 +.Fa "int64_t *out_val" +.Fa "const ASN1_INTEGER *a" +.Fc +.Ft long +.Fo ASN1_INTEGER_get +.Fa "const ASN1_INTEGER *a" +.Fc +.Ft int +.Fo ASN1_INTEGER_set_uint64 +.Fa "ASN1_INTEGER *a" +.Fa "uint64_t v" +.Fc +.Ft int +.Fo ASN1_INTEGER_set_int64 +.Fa "ASN1_INTEGER *a" +.Fa "int64_t v" +.Fc +.Ft int +.Fo ASN1_INTEGER_set +.Fa "ASN1_INTEGER *a" +.Fa "long v" +.Fc +.Ft int +.Fo ASN1_INTEGER_cmp +.Fa "const ASN1_INTEGER *a1" +.Fa "const ASN1_INTEGER *a2" +.Fc +.Ft ASN1_INTEGER * +.Fo ASN1_INTEGER_dup +.Fa "const ASN1_INTEGER *a" +.Fc +.Ft ASN1_INTEGER * +.Fo BN_to_ASN1_INTEGER +.Fa "const BIGNUM *bn" +.Fa "ASN1_INTEGER *ai" +.Fc +.Ft BIGNUM * +.Fo ASN1_INTEGER_to_BN +.Fa "const ASN1_INTEGER *ai" +.Fa "BIGNUM *bn" +.Fc +.Ft int +.Fo ASN1_ENUMERATED_get_int64 +.Fa "int64_t *out_val" +.Fa "const ASN1_ENUMERATED *a" +.Fc +.Ft long +.Fo ASN1_ENUMERATED_get +.Fa "const ASN1_ENUMERATED *a" +.Fc +.Ft int +.Fo ASN1_ENUMERATED_set_int64 +.Fa "ASN1_ENUMERATED *a" +.Fa "int64_t v" +.Fc +.Ft int +.Fo ASN1_ENUMERATED_set +.Fa "ASN1_ENUMERATED *a" +.Fa "long v" +.Fc +.Ft ASN1_ENUMERATED * +.Fo BN_to_ASN1_ENUMERATED +.Fa "const BIGNUM *bn" +.Fa "ASN1_ENUMERATED *ai" +.Fc +.Ft BIGNUM * +.Fo ASN1_ENUMERATED_to_BN +.Fa "const ASN1_ENUMERATED *ai" +.Fa "BIGNUM *bn" +.Fc +.Sh DESCRIPTION +These functions convert to and from +.Vt ASN1_INTEGER +and +.Vt ASN1_ENUMERATED +objects. +.Pp +.Fn ASN1_INTEGER_get_uint64 +and +.Fn ASN1_INTEGER_get_int64 +store the value of +.Fa a +in +.Pf * Fa out_val +if successful. +.Pp +The deprecated function +.Fn ASN1_INTEGER_get +converts +.Fa a +to the +.Vt long +type. +.Pp +.Fn ASN1_INTEGER_set_uint64 , +.Fn ASN1_INTEGER_set_int64 , +and +.Fn ASN1_INTEGER_set +set the type of +.Fa a +to +.Dv V_ASN1_INTEGER +or +.Dv V_ASN1_NEG_INTEGER +depending on the sign of +.Fa v +and set the value of +.Fa a +to +.Fa v . +.Pp +.Fn ASN1_INTEGER_cmp +compares the signed integer numbers represented by +.Fa a1 +and +.Fa a2 . +.Pp +.Fn ASN1_INTEGER_dup +does exactly the same as +.Xr ASN1_STRING_dup 3 +without providing any type safety, +except that it fails if the +.Xr ASN1_STRING_length 3 +of +.Fa a +is 0. +.Pp +.Fn BN_to_ASN1_INTEGER +converts +.Fa bn +to an +.Vt ASN1_INTEGER . +If +.Fa ai +is +.Dv NULL , +a new +.Vt ASN1_INTEGER +object is returned. +Otherwise, the existing object +.Fa ai +is used instead. +.Pp +.Fn ASN1_INTEGER_to_BN +converts +.Fa ai +into a +.Vt BIGNUM . +If +.Fa bn +is +.Dv NULL , +a new +.Vt BIGNUM +object is returned. +Otherwise, the existing object +.Fa bn +is used instead. +.Pp +.Fn ASN1_ENUMERATED_get_int64 , +.Fn ASN1_ENUMERATED_get , +.Fn ASN1_ENUMERATED_set_int64 , +.Fn ASN1_ENUMERATED_set , +.Fn BN_to_ASN1_ENUMERATED , +and +.Fn ASN1_ENUMERATED_to_BN +behave like their +.Vt ASN1_INTEGER +counterparts except that they operate on an +.Vt ASN1_ENUMERATED +object. +.Sh RETURN VALUES +.Fn ASN1_INTEGER_get_uint64 +returns 1 in case of success or 0 if +.Fa a +is not of the type +.Dv V_ASN1_INTEGER +or greater than +.Dv UINT64_MAX . +.Pp +.Fn ASN1_INTEGER_get_int64 +returns 1 in case of success or 0 if +.Fa a +is not of the type +.Dv V_ASN1_INTEGER +or +.Dv V_ASN1_NEG_INTEGER , +less than +.Dv INT64_MIN , +or greater than +.Dv INT64_MAX . +.Pp +.Fn ASN1_INTEGER_get +and +.Fn ASN1_ENUMERATED_get +return the converted value, 0 if +.Fa a +is +.Dv NULL , +or \-1 on error, which is ambiguous because \-1 is a legitimate +value for an +.Vt ASN1_INTEGER . +.Pp +.Fn ASN1_INTEGER_set_uint64 , +.Fn ASN1_INTEGER_set_int64 , +.Fn ASN1_INTEGER_set , +.Fn ASN1_ENUMERATED_set_int64 , +and +.Fn ASN1_ENUMERATED_set +return 1 for success or 0 for failure. +They only fail if a memory allocation error occurs. +.Pp +.Fn ASN1_INTEGER_cmp +returns a value greater than, equal to, or less than 0 +if the signed integer number represented by +.Fa a1 +is greater than, equal to, or less than +the signed integer number represented by +.Fa a2 , +respectively. +.Pp +.Fn ASN1_INTEGER_dup +returns a pointer to a newly allocated +.Vt ASN1_STRING +structure or +.Dv NULL +if +.Fa a +is a +.Dv NULL +pointer, if the length of +.Fa a +is 0, or if memory allocation fails. +.Pp +.Fn BN_to_ASN1_INTEGER +and +.Fn BN_to_ASN1_ENUMERATED +return an +.Vt ASN1_INTEGER +or +.Vt ASN1_ENUMERATED +object, respectively, or +.Dv NULL +if an error occurs. +They only fail due to memory allocation errors. +.Pp +.Fn ASN1_INTEGER_to_BN +and +.Fn ASN1_ENUMERATED_to_BN +return a +.Vt BIGNUM +object of +.Dv NULL +if an error occurs. +They can fail if the passed type is incorrect (due to a programming error) +or due to memory allocation failures. +.Sh SEE ALSO +.Xr ASN1_INTEGER_new 3 , +.Xr ASN1_STRING_length 3 +.Sh HISTORY +.Fn ASN1_INTEGER_set +first appeared in SSLeay 0.5.1. +.Fn ASN1_INTEGER_get , +.Fn BN_to_ASN1_INTEGER , +and +.Fn ASN1_INTEGER_to_BN +first appeared in SSLeay 0.6.0. +.Fn ASN1_INTEGER_cmp +and +.Fn ASN1_INTEGER_dup +first appeared in SSLeay 0.6.5. +These functions have been available since +.Ox 2.3 . +.Pp +.Fn ASN1_ENUMERATED_get , +.Fn ASN1_ENUMERATED_set , +.Fn BN_to_ASN1_ENUMERATED , +and +.Fn ASN1_ENUMERATED_to_BN +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Pp +.Fn ASN1_INTEGER_get_uint64 , +.Fn ASN1_INTEGER_get_int64 , +.Fn ASN1_INTEGER_set_uint64 , +.Fn ASN1_INTEGER_set_int64 , +.Fn ASN1_ENUMERATED_get_int64 , +and +.Fn ASN1_ENUMERATED_set_int64 +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.2 . +.Sh CAVEATS +In general an +.Vt ASN1_INTEGER +or +.Vt ASN1_ENUMERATED +type can contain an integer of almost arbitrary size +and so cannot always be represented by a C +.Vt long +type. +The ambiguous return values of +.Fn ASN1_INTEGER_get +and +.Fn ASN1_ENUMERATED_get +imply that these functions should be avoided if possible. +.Sh BUGS +.Fn ASN1_INTEGER_cmp , +.Fn ASN1_INTEGER_dup , +and +.Fn ASN1_INTEGER_to_BN +do not check whether their arguments are really of the type +.Dv V_ASN1_INTEGER +or +.Dv V_ASN1_NEG_INTEGER . +They may report success even if their arguments are of a wrong type. +Consequently, even in case of success, the return value of +.Fn ASN1_INTEGER_dup +is not guaranteed to be of the type +.Dv V_ASN1_INTEGER +or +.Dv V_ASN1_NEG_INTEGER +either. +.Pp +Similarly, +.Fn ASN1_ENUMERATED_to_BN +does not check whether its argument is really of the type +.Dv V_ASN1_ENUMERATED +or +.Dv V_ASN1_NEG_ENUMERATED +and may report success even if the argument is of a wrong type. diff --git a/Libraries/libressl/man/ASN1_NULL_new.3 b/Libraries/libressl/man/ASN1_NULL_new.3 new file mode 100644 index 000000000..b4d2428ed --- /dev/null +++ b/Libraries/libressl/man/ASN1_NULL_new.3 @@ -0,0 +1,66 @@ +.\" $OpenBSD: ASN1_NULL_new.3,v 1.3 2021/12/09 18:42:35 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 9 2021 $ +.Dt ASN1_NULL_NEW 3 +.Os +.Sh NAME +.Nm ASN1_NULL_new , +.Nm ASN1_NULL_free +.Nd ASN.1 NULL value +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_NULL * +.Fn ASN1_NULL_new void +.Ft void +.Fn ASN1_NULL_free "ASN1_NULL *val_in" +.Sh DESCRIPTION +.Fn ASN1_NULL_new +returns a specific invalid pointer that represents the ASN.1 NULL value, +which is the only possible value of the ASN.1 NULL type. +That pointer is different from a +.Dv NULL +pointer. +Dereferencing it almost certainly results in a segmentation fault. +This function does not allocate memory and cannot fail. +.Pp +.Fn ASN1_NULL_free +has no effect whatsoever. +In particular, it ignores the +.Fa val_in +argument and does not free any memory. +In normal use, application programs only pass the invalid pointer +obtained from +.Fn ASN1_NULL_new +to this function. +But even if a valid pointer is passed, that pointer does not become invalid. +.Pp +The ASN.1 NULL type is also represented by the +.Dv V_ASN1_NULL +type identifier constant. +.Sh SEE ALSO +.Xr ASN1_item_new 3 , +.Xr d2i_ASN1_NULL 3 +.Sh STANDARDS +ITU-T Recommendation X.208, also known as ISO/IEC 8824-1: +Specification of Abstract Syntax Notation One (ASN.1), +section 19: Notation for the null type +.Sh HISTORY +.Fn ASN1_NULL_new +and +.Fn ASN1_NULL_free +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/ASN1_OBJECT_new.3 b/Libraries/libressl/man/ASN1_OBJECT_new.3 new file mode 100644 index 000000000..3e2eac02e --- /dev/null +++ b/Libraries/libressl/man/ASN1_OBJECT_new.3 @@ -0,0 +1,228 @@ +.\" $OpenBSD: ASN1_OBJECT_new.3,v 1.16 2023/09/05 15:01:39 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d4 Mar 19 12:28:58 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017, 2021, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson. +.\" Copyright (c) 2002, 2006 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 5 2023 $ +.Dt ASN1_OBJECT_NEW 3 +.Os +.Sh NAME +.Nm ASN1_OBJECT_new , +.Nm ASN1_OBJECT_create , +.Nm ASN1_OBJECT_free +.Nd ASN.1 object identifiers +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_OBJECT * +.Fo ASN1_OBJECT_new +.Fa void +.Fc +.Ft ASN1_OBJECT * +.Fo ASN1_OBJECT_create +.Fa "int nid" +.Fa "unsigned char *content" +.Fa "int len" +.Fa "const char *short_name" +.Fa "const char *long_name" +.Fc +.Ft void +.Fo ASN1_OBJECT_free +.Fa "ASN1_OBJECT *a" +.Fc +.Sh DESCRIPTION +.Fn ASN1_OBJECT_new +allocates and initializes an empty +.Vt ASN1_OBJECT +object, representing an ASN.1 OBJECT IDENTIFIER. +It can hold a short name, a long name, a numeric identifier (NID), +and a sequence of integers identifying a node in the International +Object Identifier tree as specified in ITU-T recommendation X.660. +The new object is marked as dynamically allocated. +.Pp +The ASN.1 object identifier type is also represented by the +.Dv V_ASN1_OBJECT +type identifier constant. +.Pp +.Fn ASN1_OBJECT_create +allocates a new +.Vt ASN1_OBJECT +with the given +.Fa nid , +copies the +.Fa len +DER +.Fa content +octets, the +.Fa short_name , +and the +.Fa long_name +into it, and marks the new object and all data contained in it +as dynamically allocated. +.Pp +Application programs normally use utility functions like +.Xr OBJ_nid2obj 3 +rather than using +.Fn ASN1_OBJECT_new +or +.Fn ASN1_OBJECT_create +directly. +.Pp +.Fn ASN1_OBJECT_free +has the following effects: +.Pp +All data contained in +.Fa a +that is marked as dynamically allocated is freed, +and the respective fields of +.Fa a +become empty. +Contained data not marked as dynamically allocated remains intact. +.Pp +If the object +.Fa a +itself is marked as dynamically allocated, it is freed. +Otherwise, the pointer +.Fa a +remains valid. +.Pp +If +.Fa a +is a +.Dv NULL +pointer or if neither the object itself nor any of its content +is marked as dynamically allocated, no action occurs. +.Sh RETURN VALUES +.Fn ASN1_OBJECT_new +and +.Fn ASN1_OBJECT_create +return a pointer to the new object or +.Dv NULL +if memory allocation fails, +.Sh ERRORS +After failure of +.Fn ASN1_OBJECT_new +or +.Fn ASN1_OBJECT_create , +the following diagnostic can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +Memory allocation failed. +.El +.Pp +After some cases of failure of +.Fn ASN1_OBJECT_create , +the following diagnostic can be retrieved in addition to the above: +.Bl -tag -width Ds +.It Dv ERR_R_ASN1_LIB Qq "ASN1 lib" +Memory allocation failed. +.El +.Sh SEE ALSO +.Xr a2d_ASN1_OBJECT 3 , +.Xr ASN1_TYPE_get 3 , +.Xr d2i_ASN1_OBJECT 3 , +.Xr OBJ_create 3 , +.Xr OBJ_nid2obj 3 +.Sh STANDARDS +ITU-T Recommendation X.208, also known as ISO/IEC 8824-1: +Specification of Abstract Syntax Notation One (ASN.1), +section 28: Notation for the object identifier type +.Pp +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.19: Encoding of an object identifier value +.Sh HISTORY +.Fn ASN1_OBJECT_new +and +.Fn ASN1_OBJECT_free +first appeared in SSLeay 0.5.1 and +.Fn ASN1_OBJECT_create +in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Sh BUGS +The function +.Fn ASN1_OBJECT_new +is not useful for any practical purpose because the library does not +provide any function capable of adding data to an existing object. +Consequently, if the application program creates an object with +.Fn ASN1_OBJECT_new , +that object will always remain empty. +.Pp +Similarly, if an +.Fa nid +of +.Dv NID_undef +is passed to +.Fn ASN1_OBJECT_create , +or if +.Dv NULL +is passed for any of its pointer arguments, the returned object +will permanently remain incomplete. diff --git a/Libraries/libressl/man/ASN1_PRINTABLE_type.3 b/Libraries/libressl/man/ASN1_PRINTABLE_type.3 new file mode 100644 index 000000000..391dd32e6 --- /dev/null +++ b/Libraries/libressl/man/ASN1_PRINTABLE_type.3 @@ -0,0 +1,92 @@ +.\" $OpenBSD: ASN1_PRINTABLE_type.3,v 1.1 2021/11/15 13:39:40 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 15 2021 $ +.Dt ASN1_PRINTABLE_TYPE 3 +.Os +.Sh NAME +.Nm ASN1_PRINTABLE_type +.Nd classify a single-byte character string +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_PRINTABLE_type +.Fa "const unsigned char *string" +.Fa "int len" +.Fc +.Sh DESCRIPTION +.Fn ASN1_PRINTABLE_type +assumes that the given +.Fa string +consists of single-byte characters and classifies it +according to which kinds characters occur. +If +.Fa len +is greater than 0, at most +.Fa len +characters are inspected. +Otherwise, the +.Fa string +needs to be NUL-terminated. +.Sh RETURN VALUES +If the given +.Fa string +contains a character outside the +.Xr ascii 7 +range, +.Fn ASN1_PRINTABLE_type +returns +.Dv V_ASN1_T61STRING . +.Pp +Otherwise, if it contains a character that is neither a letter +nor a digit nor the space character +.Po +.Ql "\ " , +ASCII 0x20 +.Pc +nor the apostrophe quote +.Po +.Ql \(aq , +ASCII 0x27 +.Pc +nor contained in the set +.Qq ()+,\-./:=?\& , +it returns +.Dv V_ASN1_IA5STRING . +.Pp +Otherwise, including if +.Fa string +is a +.Dv NULL +pointer or points to an empty string, it returns +.Dv V_ASN1_PRINTABLESTRING . +.Sh SEE ALSO +.Xr ASN1_mbstring_copy 3 , +.Xr ASN1_STRING_new 3 , +.Xr ASN1_STRING_to_UTF8 3 , +.Xr isascii 3 , +.Xr ascii 7 +.Sh HISTORY +.Fn ASN1_PRINTABLE_type +first appeared in SSLeay 0.4.5d, has been part of the public API +since SSLeay 0.5.1, and has been available since +.Ox 2.4 . +.Sh CAVEATS +The ASN.1 notion of what constitutes a +.Vt PrintableString +is more restrictive than what the C library function +.Xr isprint 3 +considers printable. diff --git a/Libraries/libressl/man/ASN1_STRING_TABLE_add.3 b/Libraries/libressl/man/ASN1_STRING_TABLE_add.3 new file mode 100644 index 000000000..482faa0f5 --- /dev/null +++ b/Libraries/libressl/man/ASN1_STRING_TABLE_add.3 @@ -0,0 +1,142 @@ +.\" $OpenBSD: ASN1_STRING_TABLE_add.3,v 1.9 2021/12/15 20:07:51 schwarze Exp $ +.\" checked up to: +.\" OpenSSL ASN1_STRING_TABLE_add.pod 7b608d08 Jul 27 01:18:50 2017 +0800 +.\" +.\" Copyright (c) 2017, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 15 2021 $ +.Dt ASN1_STRING_TABLE_ADD 3 +.Os +.Sh NAME +.Nm ASN1_STRING_TABLE_add , +.Nm ASN1_STRING_TABLE_get , +.Nm ASN1_STRING_TABLE_cleanup +.Nd maintain the global ASN.1 string table +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_STRING_TABLE_add +.Fa "int nid" +.Fa "long minsize" +.Fa "long maxsize" +.Fa "unsigned long mask" +.Fa "unsigned long flags" +.Fc +.Ft ASN1_STRING_TABLE * +.Fo ASN1_STRING_TABLE_get +.Fa "int nid" +.Fc +.Ft void +.Fn ASN1_STRING_TABLE_cleanup void +.Sh DESCRIPTION +The ASN.1 string table is a unique global object. +Each entry is of the type +.Vt ASN1_STRING_TABLE +and contains information about one NID object. +Some entries are predefined according to RFC 3280 appendix A.1. +.Pp +By default, the upper bounds for the number of characters in various kinds of +.Vt ASN1_STRING +objects are: +.Pp +.Bl -column -compact NID_organizationalUnitNa maxsi ub_organization_unit_na +.It object type Ta maxsize Ta symbolic constant +.It Dv NID_commonName Ta 64 Ta Dv ub_common_name +.It Dv NID_countryName Ta 2 Ta \(em +.It Dv NID_givenName Ta 32768 Ta Dv ub_name +.It Dv NID_initials Ta 32768 Ta Dv ub_name +.It Dv NID_localityName Ta 128 Ta Dv ub_locality_name +.It Dv NID_name Ta 32768 Ta Dv ub_name +.It Dv NID_organizationName Ta 64 Ta Dv ub_organization_name +.It Dv NID_organizationalUnitName Ta 64 Ta Dv ub_organization_unit_name +.It Dv NID_pkcs9_emailAddress Ta 128 Ta Dv ub_email_address +.It Dv NID_serialNumber Ta 64 Ta Dv ub_serial_number +.It Dv NID_stateOrProvinceName Ta 128 Ta Dv ub_state_name +.It Dv NID_surname Ta 32768 Ta Dv ub_name +.El +.Pp +The function +.Fn ASN1_STRING_TABLE_add +changes the existing entry for +.Fa nid +or, if there is none, allocates a new entry. +The fields of the entry are overwritten with the function arguments +of the same name. +If +.Fa minsize +or +.Fa maxsize +is negative or +.Fa mask +is 0, that argument is ignored and the respective field remains unchanged, +or for a new entry, it is set to \-1, \-1, 0, or +.Dv STABLE_FLAGS_MALLOC , +respectively. +.Pp +The bits set in the +.Fa flags +argument are OR'ed into the existing field rather than overwriting it. +The only useful flag is +.Dv STABLE_NO_MASK . +If it is set, +.Xr ASN1_STRING_set_by_NID 3 +skips applying the global mask that can be set with +.Xr ASN1_STRING_set_default_mask 3 . +Otherwise, the table entry only accepts types +permitted by both the global mask and the +.Fa mask +argument. +Setting +.Dv STABLE_FLAGS_MALLOC +or any other bit in the +.Fa mask +argument has no effect. +.Pp +The function +.Fn ASN1_STRING_TABLE_get +retrieves the entry for +.Fa nid . +.Pp +The function +.Fn ASN1_STRING_TABLE_cleanup +removes and frees all entries except the predefined ones +and restores the predefined ones to their default state. +.Sh RETURN VALUES +The +.Fn ASN1_STRING_TABLE_add +function returns 1 if successful; otherwise 0 is returned +and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn ASN1_STRING_TABLE_get +returns a valid +.Vt ASN1_STRING_TABLE +structure or +.Dv NULL +if nothing is found. +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr ASN1_STRING_set_by_NID 3 , +.Xr OBJ_create 3 , +.Xr OBJ_nid2obj 3 +.Sh HISTORY +.Fn ASN1_STRING_TABLE_add , +.Fn ASN1_STRING_TABLE_get , +and +.Fn ASN1_STRING_TABLE_cleanup +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Sh BUGS +Most aspects of the semantics considerably differ from OpenSSL. diff --git a/Libraries/libressl/man/ASN1_STRING_length.3 b/Libraries/libressl/man/ASN1_STRING_length.3 new file mode 100644 index 000000000..20834e081 --- /dev/null +++ b/Libraries/libressl/man/ASN1_STRING_length.3 @@ -0,0 +1,458 @@ +.\" $OpenBSD: ASN1_STRING_length.3,v 1.29 2021/12/14 19:36:18 schwarze Exp $ +.\" full merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2019, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson. +.\" Copyright (c) 2002, 2006, 2013, 2015, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt ASN1_STRING_LENGTH 3 +.Os +.Sh NAME +.Nm ASN1_STRING_cmp , +.Nm ASN1_OCTET_STRING_cmp , +.Nm ASN1_STRING_data , +.Nm ASN1_STRING_dup , +.Nm ASN1_OCTET_STRING_dup , +.Nm ASN1_STRING_get0_data , +.Nm ASN1_STRING_length , +.Nm ASN1_STRING_length_set , +.Nm ASN1_STRING_set0 , +.Nm ASN1_STRING_set , +.Nm ASN1_OCTET_STRING_set , +.Nm ASN1_STRING_copy , +.Nm ASN1_STRING_to_UTF8 , +.Nm ASN1_STRING_type +.\" deprecated aliases, intentionally undocumented: +.\" M_ASN1_STRING_data, M_ASN1_STRING_length +.Nd ASN1_STRING utility functions +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_STRING_cmp +.Fa "const ASN1_STRING *a" +.Fa "const ASN1_STRING *b" +.Fc +.Ft int +.Fo ASN1_OCTET_STRING_cmp +.Fa "const ASN1_OCTET_STRING *a" +.Fa "const ASN1_OCTET_STRING *b" +.Fc +.Ft unsigned char * +.Fo ASN1_STRING_data +.Fa "ASN1_STRING *x" +.Fc +.Ft ASN1_STRING * +.Fo ASN1_STRING_dup +.Fa "const ASN1_STRING *a" +.Fc +.Ft ASN1_OCTET_STRING * +.Fo ASN1_OCTET_STRING_dup +.Fa "const ASN1_OCTET_STRING *a" +.Fc +.Ft const unsigned char * +.Fo ASN1_STRING_get0_data +.Fa "const ASN1_STRING *x" +.Fc +.Ft int +.Fo ASN1_STRING_length +.Fa "const ASN1_STRING *x" +.Fc +.Ft void +.Fo ASN1_STRING_length_set +.Fa "ASN1_STRING *x" +.Fa "int len" +.Fc +.Ft void +.Fo ASN1_STRING_set0 +.Fa "ASN1_STRING *str" +.Fa "void *data" +.Fa "int len" +.Fc +.Ft int +.Fo ASN1_STRING_set +.Fa "ASN1_STRING *str" +.Fa "const void *data" +.Fa "int len" +.Fc +.Ft int +.Fo ASN1_OCTET_STRING_set +.Fa "ASN1_OCTET_STRING *str" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo ASN1_STRING_copy +.Fa "ASN1_STRING *dst" +.Fa "const ASN1_STRING *src" +.Fc +.Ft int +.Fo ASN1_STRING_to_UTF8 +.Fa "unsigned char **out" +.Fa "const ASN1_STRING *in" +.Fc +.Ft int +.Fo ASN1_STRING_type +.Fa "const ASN1_STRING *x" +.Fc +.Sh DESCRIPTION +These functions manipulate +.Vt ASN1_STRING +structures. +.Pp +.Fn ASN1_STRING_cmp +compares the type, the length, and the content of +.Fa a +and +.Fa b . +.Pp +.Fn ASN1_OCTET_STRING_cmp +does exactly the same as +.Fn ASN1_STRING_cmp +without providing any type safety. +.Pp +.Fn ASN1_STRING_data +is similar to +.Fn ASN1_STRING_get0_data +except that the returned value is not constant. +This function is deprecated. +Applications should use +.Fn ASN1_STRING_get0_data +instead. +.Pp +.Fn ASN1_STRING_dup +allocates a new +.Vt ASN1_STRING +object and copies the type, length, data, and flags from +.Fa a +into it. +.Pp +.Fn ASN1_OCTET_STRING_dup +does exactly the same as +.Fn ASN1_STRING_dup +without providing any type safety. +.Pp +.Fn ASN1_STRING_get0_data +returns an internal pointer to the data of +.Fa x . +It should not be freed or modified in any way. +.Pp +.Fn ASN1_STRING_length +returns the length attribute of +.Fa x , +measured in bytes. +.Pp +.Fn ASN1_STRING_length_set +sets the length attribute of +.Fa x +to +.Fa len . +It may put +.Fa x +into an inconsistent internal state. +.Pp +.Fn ASN1_STRING_set0 +frees any data stored in +.Fa str , +sets the length attribute to +.Fa len +bytes, and sets the data attribute to +.Fa data , +transferring ownership, without doing any validation. +.Pp +.Fn ASN1_STRING_set +sets the length attribute of +.Fa str +to +.Fa len +and copies that number of bytes from +.Fa data +into +.Fa str , +overwriting any previous data. +If +.Fa len +is \-1, then +.Fn strlen data +is used instead of +.Fa len . +If +.Fa data +is +.Dv NULL , +the content of +.Fa str +remains uninitialized; that is not considered an error unless +.Fa len +is negative. +.Pp +.Fn ASN1_OCTET_STRING_set +does exactly the same as +.Fn ASN1_STRING_set +without providing any type safety. +.Pp +.Fn ASN1_STRING_copy +copies the length and data of +.Fa src +into +.Fa dst +using +.Fn ASN1_STRING_set +and changes the type and flags of +.Fa dst +to match the type and flags of +.Fa src . +.Pp +.Fn ASN1_STRING_to_UTF8 +converts the string +.Fa in +to UTF-8 format. +The converted data is copied into a newly allocated buffer +.Pf * Fa out . +The buffer +.Pf * Fa out +should be freed using +.Xr free 3 . +.Pp +.Fn ASN1_STRING_type +returns the type of +.Fa x . +If the bit +.Dv V_ASN1_NEG +is set in the return value, +.Fa x +is an ASN.1 INTEGER or ENUMERATED object with a negative value. +.Pp +Almost all ASN.1 types are represented as +.Vt ASN1_STRING +structures. +Other types such as +.Vt ASN1_OCTET_STRING +are simply typedefed to +.Vt ASN1_STRING +and the functions call the +.Vt ASN1_STRING +equivalents. +.Vt ASN1_STRING +is also used for some CHOICE types which consist entirely of primitive +string types such as +.Vt DirectoryString +and +.Vt Time . +.Pp +These functions should +.Em not +be used to examine or modify +.Vt ASN1_INTEGER +or +.Vt ASN1_ENUMERATED +types: the relevant INTEGER or ENUMERATED utility functions should +be used instead. +.Pp +In general it cannot be assumed that the data returned by +.Fn ASN1_STRING_get0_data +and +.Fn ASN1_STRING_data +is NUL terminated, and it may contain embedded NUL characters. +The format of the data depends on the string type: +for example for an +.Vt IA5String +the data contains ASCII characters, for a +.Vt BMPString +two bytes per character in big endian format, and for a +.Vt UTF8String +UTF-8 characters. +.Pp +Similar care should be taken to ensure the data is in the correct format +when calling +.Fn ASN1_STRING_set +or +.Fn ASN1_STRING_set0 . +.Sh RETURN VALUES +.Fn ASN1_STRING_cmp +and +.Fn ASN1_OCTET_STRING_cmp +return 0 if the type, the length, and the content of +.Fa a +and +.Fa b +agree, or a non-zero value otherwise. +In contrast to +.Xr strcmp 3 , +the sign of the return value does not indicate lexicographical ordering. +.Pp +.Fn ASN1_STRING_data +and +.Fn ASN1_STRING_get0_data +return an internal pointer to the data of +.Fa x . +.Pp +.Fn ASN1_STRING_dup +and +.Fn ASN1_OCTET_STRING_dup +return a pointer to a newly allocated +.Vt ASN1_STRING +structure or +.Dv NULL +if an error occurred. +.Pp +.Fn ASN1_STRING_length +returns a number of bytes. +.Pp +.Fn ASN1_STRING_set , +.Fn ASN1_OCTET_STRING_set , +and +.Fn ASN1_STRING_copy +return 1 on success or 0 on failure. +They fail if memory allocation fails. +.Fn ASN1_STRING_set +and +.Fn ASN1_OCTET_STRING_set +also fail if +.Fa data +is +.Dv NULL +and +.Fa len +is \-1 in the same call. +.Fn ASN1_STRING_copy +also fails if +.Fa src +is +.Dv NULL . +.Pp +.Fn ASN1_STRING_to_UTF8 +returns the number of bytes in the output buffer +.Pf * Fa out , +or a negative number if an error occurred. +.Pp +.Fn ASN1_STRING_type +returns an integer constant, for example +.Dv V_ASN1_OCTET_STRING +or +.Dv V_ASN1_NEG_INTEGER . +.Pp +In some cases of failure of +.Fn ASN1_STRING_dup , +.Fn ASN1_STRING_set , +and +.Fn ASN1_STRING_to_UTF8 , +the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_BIT_STRING_set 3 , +.Xr ASN1_mbstring_copy 3 , +.Xr ASN1_PRINTABLE_type 3 , +.Xr ASN1_STRING_new 3 , +.Xr ASN1_UNIVERSALSTRING_to_string 3 +.Sh HISTORY +.Fn ASN1_STRING_cmp , +.Fn ASN1_STRING_dup , +.Fn ASN1_STRING_set , +and +.Fn ASN1_OCTET_STRING_set +first appeared in SSLeay 0.6.5. +.Fn ASN1_OCTET_STRING_cmp , +.Fn ASN1_STRING_data , +.Fn ASN1_OCTET_STRING_dup , +and +.Fn ASN1_STRING_type +first appeared in SSLeay 0.8.0. +.Fn ASN1_STRING_length +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn ASN1_STRING_length_set +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn ASN1_STRING_to_UTF8 +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn ASN1_STRING_set0 +first appeared in OpenSSL 0.9.8h and has been available since +.Ox 4.5 . +.Pp +.Fn ASN1_STRING_copy +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Pp +.Fn ASN1_STRING_get0_data +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Sh BUGS +.Fn ASN1_OCTET_STRING_cmp , +.Fn ASN1_OCTET_STRING_dup , +and +.Fn ASN1_OCTET_STRING_set +do not check whether their arguments are really of the type +.Dv V_ASN1_OCTET_STRING . +They may report success even if their arguments are of a wrong type. +Consequently, even in case of success, the return value of +.Fn ASN1_OCTET_STRING_dup +is not guaranteed to be of the type +.Dv V_ASN1_OCTET_STRING +either. diff --git a/Libraries/libressl/man/ASN1_STRING_new.3 b/Libraries/libressl/man/ASN1_STRING_new.3 new file mode 100644 index 000000000..9500b82df --- /dev/null +++ b/Libraries/libressl/man/ASN1_STRING_new.3 @@ -0,0 +1,302 @@ +.\" $OpenBSD: ASN1_STRING_new.3,v 1.25 2023/07/28 05:48:33 tb Exp $ +.\" OpenSSL 99d63d46 Tue Mar 24 07:52:24 2015 -0400 +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 28 2023 $ +.Dt ASN1_STRING_NEW 3 +.Os +.Sh NAME +.Nm ASN1_STRING_new , +.Nm ASN1_STRING_type_new , +.Nm ASN1_STRING_free , +.Nm ASN1_OCTET_STRING_new , +.Nm ASN1_OCTET_STRING_free , +.Nm ASN1_BIT_STRING_new , +.Nm ASN1_BIT_STRING_free , +.Nm ASN1_INTEGER_new , +.Nm ASN1_INTEGER_free , +.Nm ASN1_ENUMERATED_new , +.Nm ASN1_ENUMERATED_free , +.Nm ASN1_UTF8STRING_new , +.Nm ASN1_UTF8STRING_free , +.Nm ASN1_IA5STRING_new , +.Nm ASN1_IA5STRING_free , +.Nm ASN1_UNIVERSALSTRING_new , +.Nm ASN1_UNIVERSALSTRING_free , +.Nm ASN1_BMPSTRING_new , +.Nm ASN1_BMPSTRING_free , +.Nm ASN1_GENERALSTRING_new , +.Nm ASN1_GENERALSTRING_free , +.Nm ASN1_T61STRING_new , +.Nm ASN1_T61STRING_free , +.Nm ASN1_VISIBLESTRING_new , +.Nm ASN1_VISIBLESTRING_free , +.Nm ASN1_PRINTABLESTRING_new , +.Nm ASN1_PRINTABLESTRING_free , +.Nm ASN1_PRINTABLE_new , +.Nm ASN1_PRINTABLE_free , +.Nm DIRECTORYSTRING_new , +.Nm DIRECTORYSTRING_free , +.Nm DISPLAYTEXT_new , +.Nm DISPLAYTEXT_free , +.Nm ASN1_GENERALIZEDTIME_new , +.Nm ASN1_GENERALIZEDTIME_free , +.Nm ASN1_UTCTIME_new , +.Nm ASN1_UTCTIME_free , +.Nm ASN1_TIME_new , +.Nm ASN1_TIME_free +.\" deprecated aliases, intentionally undocumented: M_ASN1_IA5STRING_new, +.\" M_ASN1_ENUMERATED_free, M_ASN1_INTEGER_free, M_ASN1_OCTET_STRING_free +.Nd allocate and free ASN1_STRING objects +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_STRING * +.Fn ASN1_STRING_new void +.Ft ASN1_STRING * +.Fn ASN1_STRING_type_new "int type" +.Ft void +.Fn ASN1_STRING_free "ASN1_STRING *a" +.Ft ASN1_OCTET_STRING * +.Fn ASN1_OCTET_STRING_new void +.Ft void +.Fn ASN1_OCTET_STRING_free "ASN1_OCTET_STRING *a" +.Ft ASN1_BIT_STRING * +.Fn ASN1_BIT_STRING_new void +.Ft void +.Fn ASN1_BIT_STRING_free "ASN1_BIT_STRING *a" +.Ft ASN1_INTEGER * +.Fn ASN1_INTEGER_new void +.Ft void +.Fn ASN1_INTEGER_free "ASN1_INTEGER *a" +.Ft ASN1_ENUMERATED * +.Fn ASN1_ENUMERATED_new void +.Ft void +.Fn ASN1_ENUMERATED_free "ASN1_ENUMERATED *a" +.Ft ASN1_UTF8STRING * +.Fn ASN1_UTF8STRING_new void +.Ft void +.Fn ASN1_UTF8STRING_free "ASN1_UTF8STRING *a" +.Ft ASN1_IA5STRING * +.Fn ASN1_IA5STRING_new void +.Ft void +.Fn ASN1_IA5STRING_free "ASN1_IA5STRING *a" +.Ft ASN1_UNIVERSALSTRING * +.Fn ASN1_UNIVERSALSTRING_new void +.Ft void +.Fn ASN1_UNIVERSALSTRING_free "ASN1_UNIVERSALSTRING *a" +.Ft ASN1_BMPSTRING * +.Fn ASN1_BMPSTRING_new void +.Ft void +.Fn ASN1_BMPSTRING_free "ASN1_BMPSTRING *a" +.Ft ASN1_GENERALSTRING * +.Fn ASN1_GENERALSTRING_new void +.Ft void +.Fn ASN1_GENERALSTRING_free "ASN1_GENERALSTRING *a" +.Ft ASN1_T61STRING * +.Fn ASN1_T61STRING_new void +.Ft void +.Fn ASN1_T61STRING_free "ASN1_T61STRING *a" +.Ft ASN1_VISIBLESTRING * +.Fn ASN1_VISIBLESTRING_new void +.Ft void +.Fn ASN1_VISIBLESTRING_free "ASN1_VISIBLESTRING *a" +.Ft ASN1_PRINTABLESTRING * +.Fn ASN1_PRINTABLESTRING_new void +.Ft void +.Fn ASN1_PRINTABLESTRING_free "ASN1_PRINTABLESTRING *a" +.Ft ASN1_STRING * +.Fn ASN1_PRINTABLE_new void +.Ft void +.Fn ASN1_PRINTABLE_free "ASN1_STRING *a" +.Ft ASN1_STRING * +.Fn DIRECTORYSTRING_new void +.Ft void +.Fn DIRECTORYSTRING_free "ASN1_STRING *a" +.Ft ASN1_STRING * +.Fn DISPLAYTEXT_new void +.Ft void +.Fn DISPLAYTEXT_free "ASN1_STRING *a" +.Ft ASN1_GENERALIZEDTIME * +.Fn ASN1_GENERALIZEDTIME_new void +.Ft void +.Fn ASN1_GENERALIZEDTIME_free "ASN1_GENERALIZEDTIME *a" +.Ft ASN1_UTCTIME * +.Fn ASN1_UTCTIME_new void +.Ft void +.Fn ASN1_UTCTIME_free "ASN1_UTCTIME *a" +.Ft ASN1_TIME * +.Fn ASN1_TIME_new void +.Ft void +.Fn ASN1_TIME_free "ASN1_TIME *a" +.Sh DESCRIPTION +The +.Vt ASN1_STRING +object can represent a variety of ASN.1 built-in types. +It can store a type and a value. +.Pp +All the +.Fn *_new +functions +allocate and initialize an empty +.Vt ASN1_STRING +object. +The following table shows the type assigned to the new object, +and which ASN.1 type it represents. +.Bl -column "ASN1_GENERALIZEDTIME_new()" "V_ASN1_GENERALIZEDTIME" +.It Em constructor function Ta Em OpenSSL type Ta Em ASN.1 type +.It Ta +.It Fn ASN1_STRING_new Ta Dv V_ASN1_OCTET_STRING +.It Fn ASN1_STRING_type_new Ta Fa type No argument +.It Ta +.It Fn ASN1_OCTET_STRING_new Ta Dv V_ASN1_OCTET_STRING Ta OCTET STRING +.It Fn ASN1_BIT_STRING_new Ta Dv V_ASN1_BIT_STRING Ta BIT STRING +.It Fn ASN1_INTEGER_new Ta Dv V_ASN1_INTEGER Ta INTEGER +.It Fn ASN1_ENUMERATED_new Ta Dv V_ASN1_ENUMERATED Ta ENUMERATED +.It Ta +.It Fn ASN1_UTF8STRING_new Ta Dv V_ASN1_UTF8STRING Ta UTF8String +.It Fn ASN1_IA5STRING_new Ta Dv V_ASN1_IA5STRING Ta IA5String +.It Ta +.It Fn ASN1_UNIVERSALSTRING_new Ta Dv V_ASN1_UNIVERSALSTRING Ta UniversalString +.It Fn ASN1_BMPSTRING_new Ta Dv V_ASN1_BMPSTRING Ta BMPString +.It Fn ASN1_GENERALSTRING_new Ta Dv V_ASN1_GENERALSTRING Ta GeneralString +.It Fn ASN1_T61STRING_new Ta Dv V_ASN1_T61STRING Ta T61String +.It Fn ASN1_VISIBLESTRING_new Ta Dv V_ASN1_VISIBLESTRING Ta VisibleString +.It Fn ASN1_PRINTABLESTRING_new Ta Dv V_ASN1_PRINTABLESTRING Ta PrintableString +.It Ta +.It Fn ASN1_PRINTABLE_new Ta Dv V_ASN1_UNDEF +.It Fn DIRECTORYSTRING_new Ta Dv V_ASN1_UNDEF +.It Fn DISPLAYTEXT_new Ta Dv V_ASN1_UNDEF +.It Ta +.It Fn ASN1_GENERALIZEDTIME_new Ta Dv V_ASN1_GENERALIZEDTIME Ta GeneralizedTime +.It Fn ASN1_UTCTIME_new Ta Dv V_ASN1_UTCTIME Ta UTCTime +.It Fn ASN1_TIME_new Ta Dv V_ASN1_UNDEF Ta TIME +.El +.Pp +All the +.Fn *_free +functions free +.Fa a +including any data contained in it. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +All the +.Fn *_new +functions return the new +.Vt ASN1_STRING +object if successful; otherwise +.Dv NULL +is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_BIT_STRING_set 3 , +.Xr ASN1_INTEGER_get 3 , +.Xr ASN1_item_pack 3 , +.Xr ASN1_mbstring_copy 3 , +.Xr ASN1_PRINTABLE_type 3 , +.Xr ASN1_STRING_length 3 , +.Xr ASN1_STRING_print_ex 3 , +.Xr ASN1_time_parse 3 , +.Xr ASN1_TIME_set 3 , +.Xr ASN1_TYPE_get 3 , +.Xr ASN1_UNIVERSALSTRING_to_string 3 , +.Xr d2i_ASN1_OBJECT 3 , +.Xr d2i_ASN1_OCTET_STRING 3 , +.Xr i2a_ASN1_STRING 3 , +.Xr X509_cmp_time 3 , +.Xr X509_EXTENSION_get_object 3 , +.Xr X509_get_ext_by_OBJ 3 , +.Xr X509_NAME_ENTRY_get_object 3 +.Sh HISTORY +.Fn ASN1_OCTET_STRING_new , +.Fn ASN1_OCTET_STRING_free , +.Fn ASN1_BIT_STRING_new , +.Fn ASN1_BIT_STRING_free , +.Fn ASN1_INTEGER_new , +.Fn ASN1_INTEGER_free , +.Fn ASN1_IA5STRING_new , +.Fn ASN1_IA5STRING_free , +.Fn ASN1_T61STRING_new , +.Fn ASN1_T61STRING_free , +.Fn ASN1_PRINTABLESTRING_new , +.Fn ASN1_PRINTABLESTRING_free , +.Fn ASN1_PRINTABLE_new , +.Fn ASN1_PRINTABLE_free , +.Fn ASN1_UTCTIME_new , +and +.Fn ASN1_UTCTIME_free +first appeared in SSLeay 0.5.1. +.Fn ASN1_STRING_new , +.Fn ASN1_STRING_type_new , +and +.Fn ASN1_STRING_free +first appeared in SSLeay 0.6.5. +.Fn ASN1_UNIVERSALSTRING_new , +.Fn ASN1_UNIVERSALSTRING_free , +.Fn ASN1_GENERALSTRING_new , +and +.Fn ASN1_GENERALSTRING_free +first appeared in SSLeay 0.8.0. +.Fn ASN1_BMPSTRING_new , +.Fn ASN1_BMPSTRING_free , +.Fn ASN1_GENERALIZEDTIME_new , +and +.Fn ASN1_GENERALIZEDTIME_free +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn ASN1_ENUMERATED_new , +.Fn ASN1_ENUMERATED_free , +.Fn ASN1_TIME_new , +and +.Fn ASN1_TIME_free +first appeared in OpenSSL 0.9.2b. +.Fn ASN1_UTF8STRING_new , +.Fn ASN1_UTF8STRING_free , +.Fn ASN1_VISIBLESTRING_new , +.Fn ASN1_VISIBLESTRING_free , +.Fn DIRECTORYSTRING_new , +.Fn DIRECTORYSTRING_free , +.Fn DISPLAYTEXT_new , +and +.Fn DISPLAYTEXT_free +first appeared in OpenSSL 0.9.3. +These functions have been available since +.Ox 2.6 . +.Sh BUGS +.Vt ASN1_OCTET_STRING , +.Vt ASN1_BIT_STRING , +.Vt ASN1_INTEGER , +.Vt ASN1_ENUMERATED , +.Vt ASN1_UTF8STRING , +.Vt ASN1_IA5STRING , +.Vt ASN1_UNIVERSALSTRING , +.Vt ASN1_BMPSTRING , +.Vt ASN1_GENERALSTRING , +.Vt ASN1_T61STRING , +.Vt ASN1_VISIBLESTRING , +.Vt ASN1_PRINTABLESTRING , +.Vt ASN1_GENERALIZEDTIME , +.Vt ASN1_UTCTIME , +and +.Vt ASN1_TIME +are merely typedef aliases of +.Vt ASN1_STRING +and provide no type safety whatsoever. diff --git a/Libraries/libressl/man/ASN1_STRING_print_ex.3 b/Libraries/libressl/man/ASN1_STRING_print_ex.3 new file mode 100644 index 000000000..eb43b2fe5 --- /dev/null +++ b/Libraries/libressl/man/ASN1_STRING_print_ex.3 @@ -0,0 +1,241 @@ +.\" $OpenBSD: ASN1_STRING_print_ex.3,v 1.18 2021/12/14 19:36:18 schwarze Exp $ +.\" full merge up to: OpenSSL bb9ad09e Jun 6 00:43:05 2016 -0400 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Dr. Stephen Henson. +.\" Copyright (c) 2002, 2004, 2007, 2013, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt ASN1_STRING_PRINT_EX 3 +.Os +.Sh NAME +.Nm ASN1_STRING_print_ex , +.Nm ASN1_STRING_print_ex_fp , +.Nm ASN1_STRING_print , +.Nm ASN1_tag2str +.\" M_ASN1_OCTET_STRING_print is a deprecated alias, intentionally undocumented +.Nd ASN1_STRING output routines +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_STRING_print_ex +.Fa "BIO *out" +.Fa "const ASN1_STRING *str" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo ASN1_STRING_print_ex_fp +.Fa "FILE *fp" +.Fa "const ASN1_STRING *str" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo ASN1_STRING_print +.Fa "BIO *out" +.Fa "const ASN1_STRING *str" +.Fc +.Ft const char * +.Fo ASN1_tag2str +.Fa "int tag" +.Fc +.Sh DESCRIPTION +These functions output an +.Vt ASN1_STRING +structure. +.Vt ASN1_STRING +is used to +represent all the ASN.1 string types. +.Pp +.Fn ASN1_STRING_print_ex +outputs +.Fa str +to +.Fa out , +the format being determined by the options +.Fa flags . +.Fn ASN1_STRING_print_ex_fp +is identical except it outputs to +.Fa fp +instead. +.Pp +.Fn ASN1_STRING_print +prints +.Fa str +to +.Fa out +but using a different format to +.Fn ASN1_STRING_print_ex . +It replaces unprintable characters (other than CR, LF) with +.Sq \&. . +.Pp +.Fn ASN1_tag2str +returns a human-readable name of the specified ASN.1 +.Fa tag . +.Pp +.Fn ASN1_STRING_print +is a deprecated function which should be avoided; use +.Fn ASN1_STRING_print_ex +instead. +.Pp +Although there are a large number of options, +.Dv ASN1_STRFLGS_RFC2253 +is often suitable, or on UTF-8 terminals +.Dv ASN1_STRFLGS_RFC2253 +and +.Pf ~ Dv ASN1_STRFLGS_ESC_MSB . +.Pp +The complete set of supported options for +.Fa flags +is listed below. +.Pp +Various characters can be escaped. +If +.Dv ASN1_STRFLGS_ESC_2253 +is set, the characters determined by RFC 2253 are escaped. +If +.Dv ASN1_STRFLGS_ESC_CTRL +is set, control characters are escaped. +If +.Dv ASN1_STRFLGS_ESC_MSB +is set, characters with the MSB set are escaped: this option should +.Em not +be used if the terminal correctly interprets UTF-8 sequences. +.Pp +Escaping takes several forms. +If the character being escaped is a 16-bit character then the form "\eUXXXX" +is used using exactly four characters for the hex representation. +If it is 32 bits then "\eWXXXXXXXX" is used using eight characters +of its hex representation. +These forms will only be used if UTF-8 conversion is not set (see below). +.Pp +Printable characters are normally escaped using the backslash +.Pq Sq \e +character. +If +.Dv ASN1_STRFLGS_ESC_QUOTE +is set, then the whole string is instead surrounded by double quote +characters: this is arguably more readable than the backslash notation. +Other characters use the "\eXX" using exactly two characters of the hex +representation. +.Pp +If +.Dv ASN1_STRFLGS_UTF8_CONVERT +is set, then characters are converted to UTF-8 format first. +If the terminal supports the display of UTF-8 sequences then this +option will correctly display multi-byte characters. +.Pp +If +.Dv ASN1_STRFLGS_IGNORE_TYPE +is set, then the string type is not interpreted at all: +everything is assumed to be one byte per character. +This is primarily for debugging purposes and can result +in confusing output in multi-character strings. +.Pp +If +.Dv ASN1_STRFLGS_SHOW_TYPE +is set, then the string type itself is printed before its value +(for example "BMPSTRING"), using +.Fn ASN1_tag2str . +.Pp +Instead of being interpreted the contents of a string can be "dumped": +this just outputs the value of the string using the form #XXXX +using hex format for each octet. +.Pp +If +.Dv ASN1_STRFLGS_DUMP_ALL +is set, then any type is dumped. +.Pp +Normally non-character string types (such as OCTET STRING) +are assumed to be one byte per character; if +.Dv ASN1_STRFLGS_DUMP_UNKNOWN +is set, then they will be dumped instead. +.Pp +When a type is dumped normally just the content octets are printed; if +.Dv ASN1_STRFLGS_DUMP_DER +is set, then the complete encoding is dumped +instead (including tag and length octets). +.Pp +.Dv ASN1_STRFLGS_RFC2253 +includes all the flags required by RFC 2253. +It is equivalent to +.Dv ASN1_STRFLGS_ESC_2253 | +.Dv ASN1_STRFLGS_ESC_CTRL | +.Dv ASN1_STRFLGS_ESC_MSB | +.Dv ASN1_STRFLGS_UTF8_CONVERT | +.Dv ASN1_STRFLGS_DUMP_UNKNOWN | +.Dv ASN1_STRFLGS_DUMP_DER . +.Sh RETURN VALUES +.Fn ASN1_STRING_print_ex +and +.Fn ASN1_STRING_print_ex_fp +return the number of characters written or \-1 if an error occurred. +.Pp +.Fn ASN1_STRING_print +returns 1 on success or 0 on error. +.Pp +.Fn ASN1_tag2str +returns a static string. +.Sh SEE ALSO +.Xr ASN1_parse_dump 3 , +.Xr ASN1_STRING_new 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_signature_dump 3 +.Sh HISTORY +.Fn ASN1_STRING_print +first appeared in SSLeay 0.6.5 and has been available since +.Ox 2.4 . +.Pp +.Fn ASN1_tag2str +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn ASN1_STRING_print_ex +and +.Fn ASN1_STRING_print_ex_fp +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/ASN1_TIME_set.3 b/Libraries/libressl/man/ASN1_TIME_set.3 new file mode 100644 index 000000000..4f6a99673 --- /dev/null +++ b/Libraries/libressl/man/ASN1_TIME_set.3 @@ -0,0 +1,671 @@ +.\" $OpenBSD: ASN1_TIME_set.3,v 1.19 2022/11/13 22:11:44 schwarze Exp $ +.\" full merge up to: OpenSSL 3d0f1cb9 Jul 11 03:01:24 2017 +0800 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" Copyright (c) 2022 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Todd Short . +.\" Copyright (c) 2015, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 13 2022 $ +.Dt ASN1_TIME_SET 3 +.Os +.Sh NAME +.Nm ASN1_TIME_set , +.Nm ASN1_UTCTIME_set , +.Nm ASN1_GENERALIZEDTIME_set , +.Nm ASN1_TIME_adj , +.Nm ASN1_UTCTIME_adj , +.Nm ASN1_GENERALIZEDTIME_adj , +.Nm ASN1_TIME_set_string , +.Nm ASN1_TIME_set_string_X509 , +.Nm ASN1_UTCTIME_set_string , +.Nm ASN1_GENERALIZEDTIME_set_string , +.Nm ASN1_TIME_normalize , +.Nm ASN1_TIME_check , +.Nm ASN1_UTCTIME_check , +.Nm ASN1_GENERALIZEDTIME_check , +.Nm ASN1_TIME_print , +.Nm ASN1_UTCTIME_print , +.Nm ASN1_GENERALIZEDTIME_print , +.Nm ASN1_TIME_to_tm , +.Nm ASN1_TIME_diff , +.Nm ASN1_TIME_cmp_time_t , +.Nm ASN1_UTCTIME_cmp_time_t , +.Nm ASN1_TIME_compare , +.Nm ASN1_TIME_to_generalizedtime +.Nd ASN.1 Time functions +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_TIME * +.Fo ASN1_TIME_set +.Fa "ASN1_TIME *s" +.Fa "time_t t" +.Fc +.Ft ASN1_UTCTIME * +.Fo ASN1_UTCTIME_set +.Fa "ASN1_UTCTIME *s" +.Fa "time_t t" +.Fc +.Ft ASN1_GENERALIZEDTIME * +.Fo ASN1_GENERALIZEDTIME_set +.Fa "ASN1_GENERALIZEDTIME *s" +.Fa "time_t t" +.Fc +.Ft ASN1_TIME * +.Fo ASN1_TIME_adj +.Fa "ASN1_TIME *s" +.Fa "time_t t" +.Fa "int offset_day" +.Fa "long offset_sec" +.Fc +.Ft ASN1_UTCTIME * +.Fo ASN1_UTCTIME_adj +.Fa "ASN1_UTCTIME *s" +.Fa "time_t t" +.Fa "int offset_day" +.Fa "long offset_sec" +.Fc +.Ft ASN1_GENERALIZEDTIME * +.Fo ASN1_GENERALIZEDTIME_adj +.Fa "ASN1_GENERALIZEDTIME *s" +.Fa "time_t t" +.Fa "int offset_day" +.Fa "long offset_sec" +.Fc +.Ft int +.Fo ASN1_TIME_set_string +.Fa "ASN1_TIME *s" +.Fa "const char *str" +.Fc +.Ft int +.Fo ASN1_TIME_set_string_X509 +.Fa "ASN1_TIME *s" +.Fa "const char *str" +.Fc +.Ft int +.Fo ASN1_UTCTIME_set_string +.Fa "ASN1_UTCTIME *s" +.Fa "const char *str" +.Fc +.Ft int +.Fo ASN1_GENERALIZEDTIME_set_string +.Fa "ASN1_GENERALIZEDTIME *s" +.Fa "const char *str" +.Fc +.Ft int +.Fo ASN1_TIME_normalize +.Fa "ASN1_TIME *s" +.Fc +.Ft int +.Fo ASN1_TIME_check +.Fa "const ASN1_TIME *t" +.Fc +.Ft int +.Fo ASN1_UTCTIME_check +.Fa "const ASN1_UTCTIME *t" +.Fc +.Ft int +.Fo ASN1_GENERALIZEDTIME_check +.Fa "const ASN1_GENERALIZEDTIME *t" +.Fc +.Ft int +.Fo ASN1_TIME_print +.Fa "BIO *b" +.Fa "const ASN1_TIME *s" +.Fc +.Ft int +.Fo ASN1_UTCTIME_print +.Fa "BIO *b" +.Fa "const ASN1_UTCTIME *s" +.Fc +.Ft int +.Fo ASN1_GENERALIZEDTIME_print +.Fa "BIO *b" +.Fa "const ASN1_GENERALIZEDTIME *s" +.Fc +.Ft int +.Fo ASN1_TIME_to_tm +.Fa "const ASN1_TIME *s" +.Fa "struct tm *tm" +.Fc +.Ft int +.Fo ASN1_TIME_diff +.Fa "int *pday" +.Fa "int *psec" +.Fa "const ASN1_TIME *from" +.Fa "const ASN1_TIME *to" +.Fc +.Ft int +.Fo ASN1_TIME_cmp_time_t +.Fa "const ASN1_TIME *s" +.Fa "time_t t" +.Fc +.Ft int +.Fo ASN1_UTCTIME_cmp_time_t +.Fa "const ASN1_UTCTIME *s" +.Fa "time_t t" +.Fc +.Ft int +.Fo ASN1_TIME_compare +.Fa "const ASN1_TIME *s" +.Fa "const ASN1_TIME *t" +.Fc +.Ft ASN1_GENERALIZEDTIME * +.Fo ASN1_TIME_to_generalizedtime +.Fa "const ASN1_TIME *t" +.Fa "ASN1_GENERALIZEDTIME **out" +.Fc +.Sh DESCRIPTION +An +.Vt ASN1_TIME +object is a shallow wrapper around a string containing an ASN.1 +.Vt Time +value in the restricted format valid in X.509 certificates. +An +.Vt ASN1_TIME +object is either an +.Vt ASN1_UTCTIME +object containing a string of the format +.Ar YYMMDDHHMMSS Ns Cm Z +which is valid for the years 1950 to 2049, or an +.Vt ASN1_GENERALIZEDTIME +object containing a string of the format +.Ar YYYYMMDDHHMMSS Ns Cm Z +which is valid for the years 0000 to 1949 and 2050 to 9999. +In both cases, the mandatory suffix +.Sq Cm Z +represents the GMT time zone. +LibreSSL by design does not support the full syntax of ASN.1 times. +In particular, it neither supports fractional seconds +nor any other time zone. +.Pp +The functions +.Fn ASN1_TIME_set , +.Fn ASN1_UTCTIME_set , +and +.Fn ASN1_GENERALIZEDTIME_set +set the time object +.Fa s +to the time represented by the +.Vt time_t +value +.Fa t . +If +.Fa s +is +.Dv NULL , +a new time object is allocated and returned. +.Pp +The functions +.Fn ASN1_TIME_adj , +.Fn ASN1_UTCTIME_adj , +and +.Fn ASN1_GENERALIZEDTIME_adj +set the time object +.Fa s +to the time represented by the time +.Fa offset_day +and +.Fa offset_sec +after the +.Vt time_t +value +.Fa t . +The values of +.Fa offset_day +or +.Fa offset_sec +can be negative to set a time before +.Fa t . +The +.Fa offset_sec +value can also exceed the number of seconds in a day. +If +.Fa s +is +.Dv NULL , +a new time object is allocated and returned. +.Pp +.Fn ASN1_TIME_adj +may change the type from +.Vt ASN1_GENERALIZEDTIME +to +.Vt ASN1_UTCTIME +or vice versa depending on the resulting year. +The functions +.Fn ASN1_UTCTIME_adj +and +.Fn ASN1_GENERALIZEDTIME_adj +do not modify the type of the return object. +.Pp +The functions +.Fn ASN1_TIME_set_string , +.Fn ASN1_TIME_set_string_X509 , +.Fn ASN1_UTCTIME_set_string , +and +.Fn ASN1_GENERALIZEDTIME_set_string +set the time object +.Fa s +to the time string +.Fa str , +which must be in appropriate ASN.1 time format: +YYMMDDHHMMSSZ for +.Vt ASN1_UTCTIME , +YYYYMMDDHHMMSSZ for +.Vt ASN1_GENERALIZEDTIME , +or either of the two for +.Vt ASN1_TIME . +The string +.Fa str +is copied into +.Fa s . +If +.Fa s +is +.Dv NULL , +these functions only perform a format check on +.Fa str . +.Pp +In LibreSSL, +.Fn ASN1_TIME_set_string +and +.Fn ASN1_TIME_set_string_X509 +behave identically and always set the time object +to a valid value to use in an X.509 certificate. +.Fn ASN1_GENERALIZEDTIME_set_string +may encode a time string that is not valid in an X.509 certificate. +.Pp +The function +.Fn ASN1_TIME_normalize +converts an +.Vt ASN1_GENERALIZEDTIME +into a time value that can be used in a certificate +by changing it to an +.Vt ASN1_UTCTIME +if possible. +It has no effect on an +.Vt ASN1_UTCTIME . +.Pp +The functions +.Fn ASN1_TIME_check , +.Fn ASN1_UTCTIME_check , +and +.Fn ASN1_GENERALIZEDTIME_check +check the syntax of the time string contained in the object +.Fa s . +.Pp +The functions +.Fn ASN1_TIME_print , +.Fn ASN1_UTCTIME_print , +and +.Fn ASN1_GENERALIZEDTIME_print +print out the time +.Fa s +to +.Vt BIO +.Fa b +in human readable format. +It will be of the format MMM DD HH:MM:SS YYYY [GMT], for example "Feb 3 +00:55:52 2015 GMT". +It does not include a newline. +If the time string has an invalid format, +it prints out "Bad time value" and returns an error. +.Pp +The function +.Fn ASN1_TIME_to_tm +converts the time +.Fa s +to the standard +.Vt tm +structure. +If +.Fa s +is +.Dv NULL , +then the current time is converted. +The output time is always in the GMT time zone. +The +.Fa tm_sec , tm_min , tm_hour , tm_mday , tm_mon , +and +.Fa tm_year +fields of the +.Vt tm +structure are set to the proper values, +whereas all other fields are set to 0. +If +.Fa tm +is +.Dv NULL , +this function performs a format check on +.Fa s +only. +.Pp +The function +.Fn ASN1_TIME_diff +sets +.Pf * Fa pday +and +.Pf * Fa psec +to the time difference between +.Fa from +and +.Fa to . +If +.Fa to +represents a time later than +.Fa from , +then one or both (depending on the time difference) of +.Pf * Fa pday +and +.Pf * Fa psec +will be positive. +If +.Fa to +represents a time earlier than +.Fa from , +then one or both of +.Pf * Fa pday +and +.Pf * Fa psec +will be negative. +If +.Fa to +and +.Fa from +represent the same time, then +.Pf * Fa pday +and +.Pf * Fa psec +will both be zero. +If both +.Pf * Fa pday +and +.Pf * Fa psec +are nonzero, they will always have the same sign. +The value of +.Pf * Fa psec +will always be less than the number of seconds in a day. +If +.Fa from +or +.Fa to +is +.Dv NULL , +the current time is used. +.Pp +The functions +.Fn ASN1_TIME_cmp_time_t , +.Fn ASN1_UTCTIME_cmp_time_t , +and +.Fn ASN1_TIME_compare +compare the two times represented by +.Fa s +and +.Fa t . +.Pp +The function +.Fn ASN1_TIME_to_generalizedtime +converts the +.Vt ASN1_TIME +.Fa t +to an +.Vt ASN1_GENERALIZEDTIME , +regardless of year. +If either +.Fa out +or +.Pf * Fa out +is +.Dv NULL , +then a new object is allocated and must be freed after use. +.Pp +The +.Vt ASN1_TIME , +.Vt ASN1_UTCTIME , +and +.Vt ASN1_GENERALIZEDTIME +objects are represented as +.Vt ASN1_STRING +objects internally and can be freed using +.Xr ASN1_STRING_free 3 . +.Pp +It is recommended that +.Vt ASN1_TIME +functions be used instead of +.Vt ASN1_UTCTIME +or +.Vt ASN1_GENERALIZEDTIME +functions because the +.Vt ASN1_UTCTIME +and +.Vt ASN1_GENERALIZEDTIME +functions act only on that specific time format, while the +.Vt ASN1_TIME +functions operate on either format. +.Sh RETURN VALUES +.Fn ASN1_TIME_set , +.Fn ASN1_UTCTIME_set , +.Fn ASN1_GENERALIZEDTIME_set , +.Fn ASN1_TIME_adj , +.Fn ASN1_UTCTIME_adj , +.Fn ASN1_GENERALIZEDTIME_adj , +and +.Fn ASN1_TIME_to_generalizedtime +return a pointer to a time object or +.Dv NULL +if an error occurred. +.Pp +.Fn ASN1_TIME_set_string , +.Fn ASN1_TIME_set_string_X509 , +.Fn ASN1_UTCTIME_set_string , +and +.Fn ASN1_GENERALIZEDTIME_set_string +return 1 if the time value is successfully set or 0 otherwise. +.Pp +.Fn ASN1_TIME_normalize +returns 1 on success or 0 on error. +.Pp +.Fn ASN1_TIME_check , +.Fn ASN1_UTCTIME_check , +and +.Fn ASN1_GENERALIZEDTIME_check +return 1 if the time string contained in the object is syntactically +correct or 0 otherwise. +.Pp +.Fn ASN1_TIME_print , +.Fn ASN1_UTCTIME_print , +and +.Fn ASN1_GENERALIZEDTIME_print +return 1 if the time is successfully printed or 0 if an error +occurred (I/O error or invalid time format). +.Pp +.Fn ASN1_TIME_to_tm +returns 1 if the time is successfully parsed +or 0 if an error occurred, usually due to an invalid time format. +.Pp +.Fn ASN1_TIME_diff +returns 1 for success or 0 for failure. +It can for example fail if a time string passed in has invalid syntax. +.Pp +.Fn ASN1_TIME_cmp_time_t , +.Fn ASN1_UTCTIME_cmp_time_t , +and +.Fn ASN1_TIME_compare +return \-1 if +.Fa s +is earlier than +.Fa t , +0 if both are equal, 1 if +.Fa s +is later than +.Fa t , +or \-2 on error. +.Sh EXAMPLES +Set a time object to one hour after the current time and print it +out: +.Bd -literal -offset indent +#include +#include + +ASN1_TIME *asn1_time; +time_t t; +BIO *b; + +t = time(NULL); +asn1_time = ASN1_TIME_adj(NULL, t, 0, 60 * 60); +b = BIO_new_fp(stdout, BIO_NOCLOSE); +if (asn1_time != NULL) { + ASN1_TIME_print(b, asn1_time); + BIO_printf(b, "\en"); +} else { + BIO_printf(b, "Time out of range or un-representable\en"); +} +ASN1_STRING_free(asn1_time); +BIO_free(b); +.Ed +.Sh SEE ALSO +.Xr ASN1_TIME_new 3 , +.Xr ASN1_time_parse 3 , +.Xr X509_cmp_time 3 +.Sh STANDARDS +The usage of the ASN.1 +.Vt Time , +.Vt UTCTime , +and +.Vt GeneralizedTime +data types in X.509 certificates is specified in +RFC 5280, Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.1.2.5 (TBS Certificate Validity). +.Sh HISTORY +.Fn ASN1_UTCTIME_check +and +.Fn ASN1_UTCTIME_print +first appeared in SSLeay 0.5.1. +.Fn ASN1_UTCTIME_set +first appeared in SSLeay 0.6.0. +.Fn ASN1_UTCTIME_set_string +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn ASN1_TIME_set , +.Fn ASN1_GENERALIZEDTIME_set , +.Fn ASN1_GENERALIZEDTIME_set_string , +.Fn ASN1_GENERALIZEDTIME_check , +.Fn ASN1_TIME_print , +and +.Fn ASN1_GENERALIZEDTIME_print +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Pp +.Fn ASN1_UTCTIME_cmp_time_t +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn ASN1_TIME_check +and +.Fn ASN1_TIME_to_generalizedtime +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ASN1_TIME_adj , +.Fn ASN1_UTCTIME_adj , +.Fn ASN1_GENERALIZEDTIME_adj , +and +.Fn ASN1_TIME_set_string +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn ASN1_TIME_diff +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 7.1 . +.Pp +.Fn ASN1_TIME_set_string_X509 , +.Fn ASN1_TIME_normalize , +.Fn ASN1_TIME_to_tm , +.Fn ASN1_TIME_cmp_time_t , +and +.Fn ASN1_TIME_compare +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.2 . +.Sh CAVEATS +Some applications add offset times directly to a +.Vt time_t +value and pass the results to +.Fn ASN1_TIME_set +(or equivalent). +This can cause problems as the +.Vt time_t +value can overflow on some systems resulting in unexpected results. +New applications should use +.Fn ASN1_TIME_adj +instead and pass the offset value in the +.Fa offset_sec +and +.Fa offset_day +parameters instead of directly manipulating a +.Vt time_t +value. diff --git a/Libraries/libressl/man/ASN1_TYPE_get.3 b/Libraries/libressl/man/ASN1_TYPE_get.3 new file mode 100644 index 000000000..03b41f8fa --- /dev/null +++ b/Libraries/libressl/man/ASN1_TYPE_get.3 @@ -0,0 +1,442 @@ +.\" $OpenBSD: ASN1_TYPE_get.3,v 1.18 2022/01/12 17:54:51 tb Exp $ +.\" selective merge up to: OpenSSL 6328d367 Jul 4 21:58:30 2020 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 12 2022 $ +.Dt ASN1_TYPE_GET 3 +.Os +.Sh NAME +.Nm ASN1_TYPE_new , +.Nm ASN1_TYPE_free , +.Nm ASN1_TYPE_get , +.Nm ASN1_TYPE_set , +.Nm ASN1_TYPE_set1 , +.Nm ASN1_TYPE_set_octetstring , +.Nm ASN1_TYPE_get_octetstring , +.Nm ASN1_TYPE_set_int_octetstring , +.Nm ASN1_TYPE_get_int_octetstring , +.Nm ASN1_TYPE_cmp +.Nd ASN.1 objects of arbitrary type +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_TYPE * +.Fn ASN1_TYPE_new void +.Ft void +.Fn ASN1_TYPE_free "ASN1_TYPE *a" +.Ft int +.Fo ASN1_TYPE_get +.Fa "const ASN1_TYPE *a" +.Fc +.Ft void +.Fo ASN1_TYPE_set +.Fa "ASN1_TYPE *a" +.Fa "int type" +.Fa "void *value" +.Fc +.Ft int +.Fo ASN1_TYPE_set1 +.Fa "ASN1_TYPE *a" +.Fa "int type" +.Fa "const void *value" +.Fc +.Ft int +.Fo ASN1_TYPE_set_octetstring +.Fa "ASN1_TYPE *a" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo ASN1_TYPE_get_octetstring +.Fa "const ASN1_TYPE *a" +.Fa "unsigned char *buffer" +.Fa "int buflen" +.Fc +.Ft int +.Fo ASN1_TYPE_set_int_octetstring +.Fa "ASN1_TYPE *a" +.Fa "long num" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo ASN1_TYPE_get_int_octetstring +.Fa "const ASN1_TYPE *a", +.Fa "long *num" +.Fa "unsigned char *buffer", +.Fa "int buflen" +.Fc +.Ft int +.Fo ASN1_TYPE_cmp +.Fa "const ASN1_TYPE *a" +.Fa "const ASN1_TYPE *b" +.Fc +.Sh DESCRIPTION +The +.Vt ASN1_TYPE +data type and the +.Dv V_ASN1_ANY +type identifier constant represent the ASN.1 ANY type. +An +.Vt ASN1_TYPE +object can store an ASN.1 value of arbitrary type, +including constructed types such as a SEQUENCE. +It also remembers internally which type it currently holds. +.Pp +.Fn ASN1_TYPE_new +allocates and initializes an empty +.Vt ASN1_TYPE +object of undefined type. +.Pp +.Fn ASN1_TYPE_free +frees +.Fa a +including the value stored in it, if any. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn ASN1_TYPE_get +returns the type currently held by +.Fa a , +represented by one of the +.Dv V_ASN1_* +constants defined in +.In openssl/asn1.h . +.Pp +.Fn ASN1_TYPE_set +frees the value contained in +.Fa a , +if any, and sets the +.Fa value +and +.Fa type +now held in +.Fa a . +This function uses the pointer +.Fa value +internally so it must +.Sy not +be freed up after the call. +.Pp +.Fn ASN1_TYPE_set1 +sets the type held by +.Fa a +to +.Fa type +and its value to a copy of +.Fa value . +If copying succeeds, the previous value that was contained in +.Fa a +is freed. +If copying fails, +.Fa a +remains unchanged. +.Pp +The type and meaning of the +.Fa value +argument of +.Fn ASN1_TYPE_set +and +.Fn ASN1_TYPE_set1 +is determined by the +.Fa type +argument. +If +.Fa type +is +.Dv V_ASN1_NULL , +.Fa value +is ignored. +If +.Fa type +is +.Dv V_ASN1_BOOLEAN , +then the boolean is set to TRUE if +.Fa value +is not +.Dv NULL . +If +.Fa type +is +.Dv V_ASN1_OBJECT , +then +.Fa value +is an +.Vt ASN1_OBJECT +structure. +Otherwise +.Fa type +is an +.Vt ASN1_STRING +structure. +If +.Fa type +corresponds to a primitive type or a string type, then the contents +of the +.Vt ASN1_STRING +contains the content octets of the type. +If +.Fa type +corresponds to a constructed type or a tagged type +.Pq Dv V_ASN1_SEQUENCE , V_ASN1_SET , No or Dv V_ASN1_OTHER , +then the +.Vt ASN1_STRING +contains the entire ASN.1 encoding verbatim, including tag and +length octets. +.Pp +.Fn ASN1_TYPE_set_octetstring +allocates a new +.Vt ASN1_OCTET_STRING +object, copies +.Fa len +bytes of +.Fa data +into it using +.Xr ASN1_STRING_set 3 , +and replaces the value of +.Fa a +with it by calling +.Fn ASN1_TYPE_set +with a type of +.Dv V_ASN1_OCTET_STRING . +.Pp +.Fn ASN1_TYPE_get_octetstring +copies the contents of the +.Vt ASN1_OCTET_STRING +object contained in +.Fa a , +but not more than +.Fa buflen +bytes, into the +.Fa buffer +provided by the caller. +.Pp +.Fn ASN1_TYPE_set_int_octetstring +frees the value contained in +.Fa a , +if any, sets its type to +.Dv V_ASN1_SEQUENCE , +and sets its value to a two-element ASN.1 sequence consisting of +an ASN.1 INTEGER object with the value +.Fa num +and an ASN.1 OCTET STRING object +containing a copy of the +.Fa len +bytes pointed to by +.Fa data . +.Pp +.Fn ASN1_TYPE_get_int_octetstring +copies the integer value from the first element of the ASN.1 sequence +.Fa a +to +.Pf * Fa num +unless +.Fa num +is a +.Dv NULL +pointer and copies the octet string value from the second element, +but not more than +.Fa buflen +bytes, into the +.Fa buffer +provided by the caller unless +.Fa buffer +is a +.Dv NULL +pointer. +.Pp +.Fn ASN1_TYPE_cmp +checks that +.Fa a +and +.Fa b +hold the same type, the same value, and are encoded in the same way. +.Pp +If the types agree and the values have the same meaning but are +encoded differently, they are considered different. +For example, a boolean value is represented +using a single content octet. +Under BER, any non-zero octet represents the TRUE value, but +.Fn ASN1_TYPE_cmp +will only report a match if the content octet is the same. +.Pp +If either or both of the arguments passed to +.Fn ASN1_TYPE_cmp +is +.Dv NULL , +the result is a mismatch. +Technically, if both arguments are +.Dv NULL , +the two types could be absent OPTIONAL fields and so should match, +however passing +.Dv NULL +values could also indicate a programming error (for example an +unparsable type which returns +.Dv NULL ) +for types which do +.Sy not +match. +So applications should handle the case of two absent values separately. +.Sh RETURN VALUES +.Fn ASN1_TYPE_new +returns the new +.Vt ASN1_TYPE +object or +.Dv NULL +if an error occurs. +.Pp +.Fn ASN1_TYPE_get +returns the type currently held by +.Fa a +or 0 if an error occurs. +The latter can happen if +.Fa a +does not contain a value even though its type is not +.Dv V_ASN1_NULL . +For example, it will always happen for empty objects +newly constructed with +.Fn ASN1_TYPE_new . +.Pp +.Fn ASN1_TYPE_set1 , +.Fn ASN1_TYPE_set_octetstring , +and +.Fn ASN1_TYPE_set_int_octetstring +return 1 on success or 0 on failure. +.Pp +.Fn ASN1_TYPE_get_octetstring +returns the number of data bytes contained in the +.Vt ASN1_OCTET_STRING +object contained in +.Fa a +or \-1 if +.Fa a +is not of the type +.Dv V_ASN1_OCTET_STRING +or does not contain any object. +If the return value is greater than the +.Fa buflen +argument, the content was truncated when copied to the +.Fa buffer . +.Pp +.Fn ASN1_TYPE_get_int_octetstring +returns the number of data bytes contained in the +.Vt ASN1_OCTET_STRING +object that is the second element of the ASN.1 sequence +.Fa a +or \-1 if +.Fa a +is not of the type +.Dv V_ASN1_SEQUENCE +or if decoding fails. +If the return value is greater than the +.Fa buflen +argument, the content was truncated when copied to the +.Fa buffer . +.Pp +.Fn ASN1_TYPE_cmp +returns 0 for a match or non-zero for a mismatch. +.Sh SEE ALSO +.Xr ASN1_generate_nconf 3 , +.Xr ASN1_get_object 3 , +.Xr ASN1_item_free 3 , +.Xr ASN1_OBJECT_new 3 , +.Xr ASN1_parse_dump 3 , +.Xr ASN1_put_object 3 , +.Xr ASN1_STRING_dup 3 , +.Xr ASN1_STRING_new 3 , +.Xr crypto 3 , +.Xr d2i_ASN1_NULL 3 , +.Xr d2i_ASN1_SEQUENCE_ANY 3 , +.Xr d2i_ASN1_TYPE 3 , +.Xr OBJ_dup 3 +.Sh HISTORY +.Fn ASN1_TYPE_new +and +.Fn ASN1_TYPE_free +first appeared in SSLeay 0.5.1, +.Fn ASN1_TYPE_get +and +.Fn ASN1_TYPE_set +in SSLeay 0.8.0, and +.Fn ASN1_TYPE_set_octetstring , +.Fn ASN1_TYPE_get_octetstring , +.Fn ASN1_TYPE_set_int_octetstring , +and +.Fn ASN1_TYPE_get_int_octetstring +in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn ASN1_TYPE_set1 +first appeared in OpenSSL 0.9.8h and has been available since +.Ox 4.5 . +.Pp +.Fn ASN1_TYPE_cmp +first appeared in OpenSSL 0.9.8zd, 1.0.0p, and 1.0.1k +and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/ASN1_UNIVERSALSTRING_to_string.3 b/Libraries/libressl/man/ASN1_UNIVERSALSTRING_to_string.3 new file mode 100644 index 000000000..2af675295 --- /dev/null +++ b/Libraries/libressl/man/ASN1_UNIVERSALSTRING_to_string.3 @@ -0,0 +1,64 @@ +.\" $OpenBSD: ASN1_UNIVERSALSTRING_to_string.3,v 1.1 2021/11/15 13:39:40 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 15 2021 $ +.Dt ASN1_UNIVERSALSTRING_TO_STRING 3 +.Os +.Sh NAME +.Nm ASN1_UNIVERSALSTRING_to_string +.Nd recode UTF-32 to ISO Latin-1 +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_UNIVERSALSTRING_to_string +.Fa "ASN1_UNIVERSALSTRING *string" +.Fc +.Sh DESCRIPTION +.Fn ASN1_UNIVERSALSTRING_to_string +assumes that the given +.Fa string +is encoded in UTF-32, recodes it in place to ISO Latin-1, +and changes the type according to +.Xr ASN1_PRINTABLE_type 3 . +.Pp +.Fn ASN1_UNIVERSALSTRING_to_string +fails and leaves the +.Fa string +unchanged if its +.Xr ASN1_STRING_type 3 +is not +.Dv V_ASN1_UNIVERSALSTRING , +if its +.Xr ASN1_STRING_length 3 +is not a multiple of four bytes, +or if any of its characters cannot be represented in ISO Latin-1. +.Pp +In case of success, the +.Xr ASN1_STRING_length 3 +of the +.Fa string +is reduced by a factor of four. +.Sh RETURN VALUES +.Fn ASN1_UNIVERSALSTRING_to_string +returns 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr ASN1_mbstring_copy 3 , +.Xr ASN1_STRING_new 3 , +.Xr ASN1_STRING_to_UTF8 3 +.Sh HISTORY +.Fn ASN1_UNIVERSALSTRING_to_string +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/ASN1_generate_nconf.3 b/Libraries/libressl/man/ASN1_generate_nconf.3 new file mode 100644 index 000000000..b15d4295a --- /dev/null +++ b/Libraries/libressl/man/ASN1_generate_nconf.3 @@ -0,0 +1,394 @@ +.\" $OpenBSD: ASN1_generate_nconf.3,v 1.13 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL 05ea606a Fri May 20 20:52:46 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson. +.\" Copyright (c) 2002, 2003, 2006-2009, 2013-2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt ASN1_GENERATE_NCONF 3 +.Os +.Sh NAME +.Nm ASN1_generate_nconf , +.Nm ASN1_generate_v3 +.Nd ASN.1 generation functions +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_TYPE * +.Fo ASN1_generate_nconf +.Fa "const char *str" +.Fa "CONF *nconf" +.Fc +.Ft ASN1_TYPE * +.Fo ASN1_generate_v3 +.Fa "const char *str" +.Fa "X509V3_CTX *cnf" +.Fc +.Sh DESCRIPTION +These functions generate the ASN.1 encoding of a string in an +.Vt ASN1_TYPE +structure. +.Pp +.Fa str +contains the string to encode +.Fa nconf +or +.Fa cnf +contains the optional configuration information +where additional strings will be read from. +.Fa nconf +will typically come from a config file whereas +.Fa cnf +is obtained from an +.Vt X509V3_CTX +structure which will typically be used +by X509 v3 certificate extension functions. +.Fa cnf +or +.Fa nconf +can be set to +.Dv NULL +if no additional configuration will be used. +.Sh GENERATION STRING FORMAT +The actual data encoded is determined by the string +.Fa str +and the configuration information. +The general format of the string is: +.Pp +.D1 Oo Ar modifier , Oc Ns Ar type Ns Op : Ns Ar value +.Pp +That is zero or more comma separated modifiers followed by a type +followed by an optional colon and a value. +The formats of +.Ar type , +.Ar value +and +.Ar modifier +are explained below. +.Ss Supported types +The supported types are listed below. +Unless otherwise specified, only the +.Cm ASCII +format is permissible. +.Bl -tag -width Ds +.It Cm BOOLEAN , BOOL +This encodes a boolean type. +The +.Ar value +string is mandatory and should be +.Cm TRUE +or +.Cm FALSE . +Additionally +.Cm true , +.Cm Y , +.Cm y , +.Cm YES , +.Cm yes , +.Cm false , +.Cm N , +.Cm n , +.Cm NO +and +.Cm no +are acceptable. +.It Cm NULL +Encode the NULL type. +The +.Ar value +string must not be present. +.It Cm INTEGER , INT +Encodes an ASN.1 INTEGER type. +The +.Ar value +string represents the value of the integer. +It can be prefaced by a minus sign +and is normally interpreted as a decimal value unless the prefix +.Cm 0x +is included. +.It Cm ENUMERATED , ENUM +Encodes the ASN.1 ENUMERATED type. +It is otherwise identical to +.Cm INTEGER . +.It Cm OBJECT , OID +Encodes an ASN.1 OBJECT IDENTIFIER. +The +.Ar value +string can be a short name, a long name, or numerical format. +.It Cm UTCTIME , UTC +Encodes an ASN.1 UTCTime structure. +The value should be in the format +.Ar YYMMDDHHMMSSZ . +.It Cm GENERALIZEDTIME , GENTIME +Encodes an ASN.1 GeneralizedTime structure. +The value should be in the format +.Ar YYYYMMDDHHMMSSZ . +.It Cm OCTETSTRING , OCT +Encodes an ASN.1 OCTET STRING. +.Ar value +represents the contents of this structure. +The format strings +.Cm ASCII +and +.Cm HEX +can be used to specify the format of +.Ar value . +.It Cm BITSTRING , BITSTR +Encodes an ASN.1 BIT STRING. +.Ar value +represents the contents of this structure. +The format strings +.Cm ASCII , +.Cm HEX , +and +.Cm BITLIST +can be used to specify the format of +.Ar value . +.Pp +If the format is anything other than +.Cm BITLIST , +the number of unused bits is set to zero. +.It Xo +.Cm BMPSTRING , BMP , +.Cm GeneralString , +.Cm IA5STRING , IA5 , +.Cm NUMERICSTRING , NUMERIC , +.Cm PRINTABLESTRING , PRINTABLE , +.Cm T61STRING , T61 , +.Cm TELETEXSTRING , +.Cm UNIVERSALSTRING , UNIV , +.Cm UTF8String , UTF8 , +.Cm VISIBLESTRING , VISIBLE +.Xc +These encode the corresponding string types. +.Ar value +represents the contents of this structure. +The format can be +.Cm ASCII +or +.Cm UTF8 . +.It Cm SEQUENCE , SEQ , SET +Formats the result as an ASN.1 SEQUENCE or SET type. +.Ar value +should be a section name which will contain the contents. +The field names in the section are ignored +and the values are in the generated string format. +If +.Ar value +is absent, then an empty SEQUENCE will be encoded. +.El +.Ss Modifiers +Modifiers affect the following structure. +They can be used to add EXPLICIT or IMPLICIT tagging, add wrappers, +or to change the string format of the final type and value. +The supported formats are: +.Bl -tag -width Ds +.It Cm EXPLICIT , EXP +Add an explicit tag to the following structure. +This string should be followed by a colon +and the tag value to use as a decimal value. +.Pp +By following the number with +.Cm U , +.Cm A , +.Cm P +or +.Cm C , +UNIVERSAL, APPLICATION, PRIVATE or CONTEXT SPECIFIC tagging can be used. +The default is CONTEXT SPECIFIC. +.It Cm IMPLICIT , IMP +This is the same as +.Cm EXPLICIT +except IMPLICIT tagging is used instead. +.It Cm OCTWRAP , SEQWRAP , SETWRAP , BITWRAP +The following structure is surrounded by +an OCTET STRING, a SEQUENCE, a SET, or a BIT STRING, respectively. +For a BIT STRING the number of unused bits is set to zero. +.It Cm FORMAT +This specifies the format of the ultimate value. +It should be followed by a colon and one of the strings +.Cm ASCII , +.Cm UTF8 , +.Cm HEX , +or +.Cm BITLIST . +.Pp +If no format specifier is included, then +.Cm ASCII +is used. +If +.Cm UTF8 +is specified, then the +.Ar value +string must be a valid UTF-8 string. +For +.Cm HEX , +the output must be a set of hex digits. +.Cm BITLIST +(which is only valid for a BIT STRING) is a comma separated list +of the indices of the set bits, all other bits are zero. +.El +.Sh RETURN VALUES +.Fn ASN1_generate_nconf +and +.Fn ASN1_generate_v3 +return the encoded data as an +.Vt ASN1_TYPE +structure or +.Dv NULL +if an error occurred. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh EXAMPLES +A simple +.Vt IA5String : +.Pp +.Dl IA5STRING:Hello World +.Pp +An +.Vt IA5String +explicitly tagged: +.Pp +.Dl EXPLICIT:0,IA5STRING:Hello World +.Pp +An +.Vt IA5String +explicitly tagged using APPLICATION tagging: +.Pp +.Dl EXPLICIT:0A,IA5STRING:Hello World +.Pp +A BITSTRING with bits 1 and 5 set and all others zero: +.Pp +.Dl FORMAT:BITLIST,BITSTRING:1,5 +.Pp +A more complex example using a config file to produce a +SEQUENCE consisting of a BOOL an OID and a +.Vt UTF8String : +.Bd -literal -offset indent +asn1 = SEQUENCE:seq_section + +[seq_section] + +field1 = BOOLEAN:TRUE +field2 = OID:commonName +field3 = UTF8:Third field +.Ed +.Pp +This example produces an +.Vt RSAPrivateKey +structure. +This is the key contained in the file +.Pa client.pem +in all OpenSSL distributions. +Note that the field names such as +.Qq coeff +are ignored and are present just for clarity. +.Bd -literal -offset 2n +asn1=SEQUENCE:private_key +[private_key] +version=INTEGER:0 + +n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\e +D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9 + +e=INTEGER:0x010001 + +d=INTEGER:0x6F05EAD2F27FFAEC84BEC360C4B928FD5F3A9865D0FCAAD291E2A52F4A\e +F810DC6373278C006A0ABBA27DC8C63BF97F7E666E27C5284D7D3B1FFFE16B7A87B51D + +p=INTEGER:0xF3929B9435608F8A22C208D86795271D54EBDFB09DDEF539AB083DA912\e +D4BD57 + +q=INTEGER:0xC50016F89DFF2561347ED1186A46E150E28BF2D0F539A1594BBD7FE467\e +46EC4F + +exp1=INTEGER:0x9E7D4326C924AFC1DEA40B45650134966D6F9DFA3A7F9D698CD4ABEA\e +9C0A39B9 + +exp2=INTEGER:0xBA84003BB95355AFB7C50DF140C60513D0BA51D637272E355E397779\e +E7B2458F + +coeff=INTEGER:0x30B9E4F2AFA5AC679F920FC83F1F2DF1BAF1779CF989447FABC2F5\e +628657053A +.Ed +.Pp +This example is the corresponding public key in an ASN.1 +.Vt SubjectPublicKeyInfo +structure: +.Bd -literal -offset 2n +# Start with a SEQUENCE +asn1=SEQUENCE:pubkeyinfo + +# pubkeyinfo contains an algorithm identifier and the public key +# wrapped in a BIT STRING +[pubkeyinfo] +algorithm=SEQUENCE:rsa_alg +pubkey=BITWRAP,SEQUENCE:rsapubkey + +# algorithm ID for RSA is just an OID and a NULL +[rsa_alg] +algorithm=OID:rsaEncryption +parameter=NULL + +# Actual public key: modulus and exponent +[rsapubkey] +n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\e +D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9 + +e=INTEGER:0x010001 +.Ed +.Sh SEE ALSO +.Xr ASN1_TYPE_get 3 , +.Xr d2i_ASN1_TYPE 3 , +.Xr x509v3.cnf 5 +.Sh HISTORY +.Fn ASN1_generate_nconf +and +.Fn ASN1_generate_v3 +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/ASN1_get_object.3 b/Libraries/libressl/man/ASN1_get_object.3 new file mode 100644 index 000000000..781b12ad5 --- /dev/null +++ b/Libraries/libressl/man/ASN1_get_object.3 @@ -0,0 +1,200 @@ +.\" $OpenBSD: ASN1_get_object.3,v 1.2 2021/07/11 19:03:45 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 11 2021 $ +.Dt ASN1_GET_OBJECT 3 +.Os +.Sh NAME +.Nm ASN1_get_object +.Nd parse identifier and length octets +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_get_object +.Fa "const unsigned char **ber_in" +.Fa "long *plength" +.Fa "int *ptag" +.Fa "int *pclass" +.Fa "long omax" +.Fc +.Sh DESCRIPTION +.Fn ASN1_get_object +parses the identifier and length octets of a BER-encoded value. +On function entry, +.Pf * Fa ber_in +is expected to point to the first identifier octet. +If the identifier and length octets turn out to be valid, +the function advances +.Pf * Fa ber_in +to the first content octet before returning. +.Pp +If the identifier octets are valid, +.Fn ASN1_get_object +stores the tag number in +.Pf * Fa ptag +and the class of the tag in +.Pf * Fa pclass . +The class is either +.Dv V_ASN1_UNIVERSAL +or +.Dv V_ASN1_APPLICATION +or +.Dv V_ASN1_CONTEXT_SPECIFIC +or +.Dv V_ASN1_PRIVATE . +.Pp +If the length octets are valid, too, +.Fn ASN1_get_object +stores the number encoded in the length octets in +.Pf * Fa plength . +If the length octet indicates the indefinite form, +.Pf * Fa plength +is set to 0. +.Pp +.Fn ASN1_get_object +inspects at most +.Fa omax +bytes. +If parsing of the length octets remains incomplete after inspecting +that number of bytes, parsing fails with +.Dv ASN1_R_HEADER_TOO_LONG . +.Sh RETURN VALUES +Bits set in the return value of +.Fn ASN1_get_object +have the following meanings: +.Bl -tag -width Ds +.It 0x80 +An error occurred. +One of the +.Sx ERRORS +described below has been set. +.It 0x20 = Dv V_ASN1_CONSTRUCTED +The encoding is constructed rather than primitive, +and the identifier and length octets are valid. +.It 0x01 +The length octet indicates the indefinite form. +This bit can only occur if +.Dv V_ASN1_CONSTRUCTED +is also set. +.El +.Pp +Consequently, the following combinations can occur: +.Bl -tag -width Ds +.It 0x00 +A valid primitive encoding. +.It 0x20 +A valid constructed encoding, definite form. +.It 0x21 +A valid constructed encoding, indefinite form. +.It 0x80 +Either a primitive encoding with a valid tag and definite length, +but the content octets won't fit into +.Fa omax , +or parsing failed. +Use +.Xr ERR_GET_REASON 3 +to distinguish the two cases. +.It 0xa0 +A constructed encoding with a valid tag and definite length, +but the content octets won't fit into +.Fa omax . +.El +.Pp +The bit combinations 0x01, 0x81, and 0xa1 cannot occur as return values. +.Sh ERRORS +If the bit 0x80 is set in the return value, +diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv ASN1_R_HEADER_TOO_LONG Qq "header too long" +Inspecting +.Fa omax +bytes was insufficient to finish parsing, +the tag number encoded in the identifier octets exceeds +.Dv INT_MAX , +the number encoded in the length octets exceeds +.Dv LONG_MAX , +or using the indefinite form for the length octets is attempted +even though the encoding is primitive. +.Pp +In this case, the return value is exactly 0x80; no other bits are set. +.Pp +If the problem occurred while parsing the identifier octets, +.Pf * Fa ptag +and +.Pf * Fa pclass +remain unchanged. +If the problem occurred while parsing the length octets, +.Pf * Fa ptag +and +.Pf * Fa pclass +are set according to the identifier octets. +In both cases, +.Pf * Fa ber_in +and +.Pf * Fa plength +remain unchanged. +.Pp +The wording of the error message is confusing. +On the one hand, the header might be just fine, +and the root cause of the problem could be that the chosen +.Fa omax +argument was too small. +On the other hand, outright BER syntax errors are also reported as +.Dv ASN1_R_HEADER_TOO_LONG . +.It Dv ASN1_R_TOO_LONG Qq "too long" +The identifier and length octets are valid, +but the content octets won't fit into +.Fa omax . +The following have been set as appropriate and can safely be inspected: +.Pf * pclass , +.Pf * ptag , +.Pf * plength , +and the bits +.Dv V_ASN1_CONSTRUCTED +and 0x01 in the return value. +The parse pointer +.Pf * ber_in +has been advanced to the first content octet. +.Pp +Again, the error message may occasionally sound confusing. +The length of the content may be reasonable, and the root cause of +the problem could be that the chosen +.Fa omax +argument was too small. +.El +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr ASN1_item_new 3 , +.Xr ASN1_parse_dump 3 +.Sh STANDARDS +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER): +.Bl -dash -offset 2n -width 1n -compact +.It +Section 8.1.2: Identifier octets +.It +Section 8.1.3: Length octets +.El +.Sh HISTORY +.Fn ASN1_get_object +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/ASN1_item_d2i.3 b/Libraries/libressl/man/ASN1_item_d2i.3 new file mode 100644 index 000000000..bc99f4a6d --- /dev/null +++ b/Libraries/libressl/man/ASN1_item_d2i.3 @@ -0,0 +1,492 @@ +.\" $OpenBSD: ASN1_item_d2i.3,v 1.18 2023/05/01 07:37:45 tb Exp $ +.\" selective merge up to: +.\" OpenSSL doc/man3/d2i_X509.pod 256989ce Jun 19 15:00:32 2020 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2003, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt ASN1_ITEM_D2I 3 +.Os +.Sh NAME +.Nm ASN1_item_d2i , +.Nm ASN1_item_d2i_bio , +.Nm ASN1_item_d2i_fp , +.Nm d2i_ASN1_TYPE , +.Nm ASN1_item_i2d , +.Nm ASN1_item_i2d_bio , +.Nm ASN1_item_i2d_fp , +.Nm i2d_ASN1_TYPE , +.Nm ASN1_item_dup , +.Nm ASN1_item_print +.Nd decode and encode ASN.1 objects +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_VALUE * +.Fo ASN1_item_d2i +.Fa "ASN1_VALUE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fa "const ASN1_ITEM *it" +.Fc +.Ft void * +.Fo ASN1_item_d2i_bio +.Fa "const ASN1_ITEM *it" +.Fa "BIO *in_bio" +.Fa "void *val_out" +.Fc +.Ft void * +.Fo ASN1_item_d2i_fp +.Fa "const ASN1_ITEM *it" +.Fa "FILE *in_fp" +.Fa "void *val_out" +.Fc +.Ft ASN1_TYPE * +.Fo d2i_ASN1_TYPE +.Fa "ASN1_TYPE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo ASN1_item_i2d +.Fa "ASN1_VALUE *val_in" +.Fa "unsigned char **der_out" +.Fa "const ASN1_ITEM *it" +.Fc +.Ft int +.Fo ASN1_item_i2d_bio +.Fa "const ASN1_ITEM *it" +.Fa "BIO *out_bio" +.Fa "void *val_in" +.Fc +.Ft int +.Fo ASN1_item_i2d_fp +.Fa "const ASN1_ITEM *it" +.Fa "FILE *out_fp" +.Fa "void *val_in" +.Fc +.Ft int +.Fo i2d_ASN1_TYPE +.Fa "ASN1_TYPE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft void * +.Fo ASN1_item_dup +.Fa "const ASN1_ITEM *it" +.Fa "void *val_in" +.Fc +.Ft int +.Fo ASN1_item_print +.Fa "BIO *out_bio" +.Fa "ASN1_VALUE *val_in" +.Fa "int indent" +.Fa "const ASN1_ITEM *it" +.Fa "const ASN1_PCTX *pctx" +.Fc +.Sh DESCRIPTION +These functions convert ASN.1 values from their BER encoding to +internal C structures +.Pq Dq d2i +and vice versa +.Pq Dq i2d . +Unlike the C structures which contain pointers to sub-objects, BER +is a serialized encoding, suitable for transfer over the network +and for storage in a file. +.Pp +.Fn ASN1_item_d2i +interprets +.Pf * Fa der_in +as a DER- or BER-encoded byte array and decodes one value of type +.Fa it +represented by up to +.Fa length +bytes. +If successful, +.Pf * Fa der_in +is advanced to the byte following the parsed data. +.Pp +If decoding succeeds and +.Fa val_out +or +.Pf * Fa val_out +is +.Dv NULL , +a new object is allocated. +.Pp +If decoding succeeds and +.Pf * Fa val_out +is not +.Dv NULL , +it is assumed to point to a valid populated object and an attempt +is made to reuse it. +It must not be an empty structure such as one returned by +.Xr ASN1_item_new 3 +or by one of the various type-specific +.Fn *_new +functions. +This +.Dq reuse +capability is present for backward compatibility, but its use is +strongly discouraged; see the +.Sx BUGS +section below. +.Pp +.Fn ASN1_item_d2i_bio +and +.Fn ASN1_item_d2i_fp +are similar to +.Fn ASN1_item_d2i +except that they read from a +.Vt BIO +or +.Vt FILE , +respectively. +.Pp +.Fn d2i_ASN1_TYPE +is similar to +.Fn ASN1_item_d2i +except that it does not require a desired type to be specified by +the user, but instead returns an +.Vt ASN1_TYPE +wrapper object containing both the type and the value found in the input. +.Pp +.Fn ASN1_item_i2d +encodes the object pointed to by +.Fa val_in +into DER format. +.Pp +If +.Pf * Fa der_out +is not +.Dv NULL , +it writes the DER-encoded data to the buffer at +.Pf * Fa der_out +and increments it to point after the data just written. +In this case, it is the responsibility of the user to make sure +that the buffer pointed to by +.Pf * Fa der_out +is long enough, such that no buffer overflow can occur. +.Pp +If +.Pf * Fa der_out +is +.Dv NULL , +memory is allocated for a buffer, and +.Pf * Fa der_out +is not incremented, but points to the start of the data just written. +.Pp +If +.Fa der_out +is +.Dv NULL , +the encoded bytes are not written anywhere but discarded. +For +.Fa val_in +objects of variable encoding size, this is sometimes used to first +find the number of bytes that will be written. +Then, a sufficient amount of memory is allocated before calling +.Fn ASN1_item_i2d +again. +This explicit double-call technique is often not needed because the +auto-allocation technique described in the previous paragraph can +be used. +.Pp +.Fn ASN1_item_i2d_bio +and +.Fn ASN1_item_i2d_fp +are similar to +.Fn ASN1_item_i2d +except that they write to a +.Vt BIO +or +.Vt FILE , +respectively. +.Pp +.Fn i2d_ASN1_TYPE +is similar to +.Fn ASN1_item_i2d +except that the type and the value are not provided separately, +but in the form of a single +.Vt ASN1_TYPE +object. +.Pp +.Fn ASN1_item_dup +creates a deep copy of +.Fa val_in +by calling +.Fn ASN1_item_i2d +and +.Fn ASN1_item_d2i . +.Sh RETURN VALUES +If successful, +.Fn ASN1_item_d2i , +.Fn ASN1_item_d2i_bio , +.Fn ASN1_item_d2i_fp , +and +.Fn d2i_ASN1_TYPE +return a pointer to the decoded ASN.1 value. +In addition, if +.Fa val_out +is not +.Dv NULL , +the pointer is also written to +.Pf * Fa val_out . +If an error occurs, +.Dv NULL +is returned. +.Pp +.Fn ASN1_item_i2d +and +.Fn i2d_ASN1_TYPE +return the number of bytes written +or a negative value if an error occurs. +.Pp +.Fn ASN1_item_i2d_bio +and +.Fn ASN1_item_i2d_fp +return 1 for success or 0 for failure. +.Pp +.Fn ASN1_item_dup +returns the new +.Vt ASN1_VALUE +object or +.Dv NULL +if an error occurs. +.Sh EXAMPLES +Many type-specific wrapper functions exist. +Using those wrappers is recommended in application code +because it restores part of the type safety that the low-level +interfaces using +.Vt ASN1_VALUE +lack. +.Pp +For example, to allocate a buffer and write the DER encoding of an +.Vt X509 +object into it: +.Bd -literal -offset indent +X509 *x; +unsigned char *buf; +int len; + +buf = NULL; +len = i2d_X509(x, &buf); +if (len < 0) + /* error */ +.Ed +.Pp +Attempt to decode a buffer: +.Bd -literal -offset indent +X509 *x; +unsigned char *buf; +const unsigned char *p; +int len; + +/* Set up buf and len to point to the input buffer. */ +p = buf; +x = d2i_X509(NULL, &p, len); +if (x == NULL) + /* error */ +.Ed +.Pp +Equivalent technique: +.Bd -literal -offset indent +X509 *x; +unsigned char *buf; +const unsigned char *p; +int len; + +/* Set up buf and len to point to the input buffer. */ +p = buf; +x = NULL; + +if (d2i_X509(&x, &p, len) == NULL) + /* error */ +.Ed +.Sh SEE ALSO +.Xr ASN1_get_object 3 , +.Xr ASN1_item_digest 3 , +.Xr ASN1_item_new 3 , +.Xr ASN1_item_pack 3 , +.Xr ASN1_item_sign 3 , +.Xr ASN1_item_verify 3 , +.Xr ASN1_TYPE_new 3 +.Sh HISTORY +.Fn d2i_ASN1_TYPE +and +.Fn i2d_ASN1_TYPE +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn ASN1_item_d2i , +.Fn ASN1_item_d2i_bio , +.Fn ASN1_item_d2i_fp , +.Fn ASN1_item_i2d , +.Fn ASN1_item_i2d_bio , +.Fn ASN1_item_i2d_fp , +and +.Fn ASN1_item_dup +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ASN1_item_print +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh CAVEATS +If the type described by +.Fa it +fails to match the true type of +.Fa val_in +or +.Pf * Fa val_out , +buffer overflows and segmentation faults are likely to occur. +For more details about why the type +.Vt ASN1_VALUE +constitutes dangerous user interface design, see +.Xr ASN1_item_new 3 . +.Pp +The encoded data is in binary form and may contain embedded NUL bytes. +Functions such as +.Xr strlen 3 +will not return the correct length of the encoded data. +.Pp +While the way that +.Pf * Fa der_in +and +.Pf * Fa der_out +are incremented after the operation supports the typical usage +patterns of reading or writing one object after another, this +behaviour can trap the unwary. +.Pp +Using a temporary pointer into the buffer is mandatory. +A common mistake is to attempt to use a buffer directly as follows: +.Bd -literal -offset indent +X509 *x; +unsigned char *buf; +int len; + +len = i2d_X509(x, NULL); +buf = malloc(len); +i2d_X509(x, &buf); +/* do something with buf[] */ +free(buf); +.Ed +.Pp +This code will result in +.Va buf +apparently containing garbage because it was incremented during +.Fn i2d_X509 +to point after the data just written. +Also +.Va buf +will no longer contain the pointer allocated by +.Xr malloc 3 +and the subsequent call to +.Xr free 3 +is likely to crash. +.Pp +Another trap to avoid is misuse of the +.Fa val_out +argument: +.Bd -literal -offset indent +X509 *x; + +if (d2i_X509(&x, &p, len) == NULL) + /* error */ +.Ed +.Pp +This will probably crash somewhere in +.Fn d2i_X509 +because +.Va x +is uninitialized and an attempt will be made to interpret its invalid +content as an +.Vt X509 +object, typically causing a segmentation violation. +If +.Va x +is set to +.Dv NULL +first, then this will not happen. +.Sh BUGS +If the +.Dq reuse +capability is used, a valid object is passed in via +.Pf * Fa val_out , +and an error occurs, then the object is not freed and may be left +in an invalid or inconsistent state. +.Pp +In some versions of OpenSSL, the +.Dq reuse +behaviour is broken such that some parts of the reused object may +persist if they are not present in the new one. +.Pp +In many versions of OpenSSL, +.Fn ASN1_item_i2d +will not return an error if mandatory fields are not initialized +due to a programming error. +In that case, the encoded structure may contain invalid data and +some fields may be missing entirely, such that trying to parse it +with +.Fn ASN1_item_d2i +may fail. diff --git a/Libraries/libressl/man/ASN1_item_digest.3 b/Libraries/libressl/man/ASN1_item_digest.3 new file mode 100644 index 000000000..56a97555e --- /dev/null +++ b/Libraries/libressl/man/ASN1_item_digest.3 @@ -0,0 +1,71 @@ +.\" $OpenBSD: ASN1_item_digest.3,v 1.2 2022/09/11 04:39:46 jsg Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 11 2022 $ +.Dt ASN1_ITEM_DIGEST 3 +.Os +.Sh NAME +.Nm ASN1_item_digest +.Nd DER-encode and hash an ASN.1 value +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo ASN1_item_digest +.Fa "const ASN1_ITEM *it" +.Fa "const EVP_MD *type" +.Fa "void *val_in" +.Fa "unsigned char *md" +.Fa "unsigned int *s" +.Fc +.Sh DESCRIPTION +.Fn ASN1_item_digest +assumes that +.Fa val_in +is an +.Vt ASN1_VALUE +of the type specified by +.Fa it , +encodes it into DER format by calling +.Xr ASN1_item_i2d 3 , +hashes the resulting byte array using the digest +.Fa type +by calling +.Xr EVP_Digest 3 , +places the digest value into +.Pf * Fa md , +and, unless +.Fa s +is +.Dv NULL , +places the length in bytes of the digest into +.Pf * Fa s . +Providing a buffer +.Pf * Fa md +large enough to contain the digest is the responsibility of the caller; +providing a buffer of +.Dv EVP_MAX_MD_SIZE +bytes is recommended. +.Sh RETURN VALUES +.Fn ASN1_item_digest +returns 1 for success or 0 if encoding or hashing fails. +.Sh SEE ALSO +.Xr ASN1_item_i2d 3 , +.Xr ASN1_item_sign 3 , +.Xr EVP_Digest 3 +.Sh HISTORY +.Fn ASN1_item_digest +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.1 . diff --git a/Libraries/libressl/man/ASN1_item_new.3 b/Libraries/libressl/man/ASN1_item_new.3 new file mode 100644 index 000000000..7015ed631 --- /dev/null +++ b/Libraries/libressl/man/ASN1_item_new.3 @@ -0,0 +1,126 @@ +.\" $OpenBSD: ASN1_item_new.3,v 1.11 2022/01/12 17:54:51 tb Exp $ +.\" +.\" Copyright (c) 2016, 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 12 2022 $ +.Dt ASN1_ITEM_NEW 3 +.Os +.Sh NAME +.Nm ASN1_item_new , +.Nm ASN1_item_free +.Nd generic ASN.1 value constructor and destructor +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_VALUE * +.Fo ASN1_item_new +.Fa "const ASN1_ITEM *it" +.Fc +.Ft void +.Fo ASN1_item_free +.Fa "ASN1_VALUE *val_in" +.Fa "const ASN1_ITEM *it" +.Fc +.Sh DESCRIPTION +.Fn ASN1_item_new +allocates and initializes an empty ASN.1 value +of the type described by the global static object +.Fa it . +.Pp +If the item type described by +.Fa it +is reference counted, +.Fn ASN1_item_free +decrements the reference count of +.Fa val_in . +Otherwise, or if the reference count reaches 0, +.Fn ASN1_item_free +frees +.Fa val_in , +assuming that it is of the type described by +.Fa it . +If the true type of +.Fa val_in +fails to match the specified +.Fa it , +buffer overflows and segmentation faults are likely to occur. +It is not possible to recover the type of an +.Vt ASN1_VALUE +object by inspecting it; the type always needs to be remembered +separately. +.Pp +.Vt ASN1_VALUE +is an incomplete type, and pointers to it always require casting +to the correct complete type before they can be dereferenced. +For all practical purposes, a pointer to +.Vt ASN1_VALUE +is equivalent to a +.Vt void +pointer. +.Pp +Depending on +.Fa it , +there are more than 150 different types that +.Fn ASN1_item_new +may return. +Most of them are pointers to structures or pointers to arrays of +structures, but there are a few exceptions, for example: +If +.Fa it +is +.Dv ASN1_NULL_it , +.Fn ASN1_item_new +returns a specific invalid pointer representing the unique +.Vt ASN1_NULL +object. +If +.Fa it +is +.Dv LONG_it , +.Fn ASN1_item_new +does not return a pointer at all, but a +.Vt long +value cast to +.Vt ASN1_VALUE * . +.Sh RETURN VALUES +The +.Fn ASN1_item_new +function returns the new +.Vt ASN1_VALUE +object if successful; otherwise +.Dv NULL +is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_get_object 3 , +.Xr ASN1_item_d2i 3 , +.Xr ASN1_item_digest 3 , +.Xr ASN1_item_pack 3 , +.Xr ASN1_item_sign 3 , +.Xr ASN1_item_verify 3 , +.Xr ASN1_NULL_new 3 , +.Xr ASN1_TYPE_new 3 , +.Xr d2i_ASN1_NULL 3 , +.Xr OBJ_nid2obj 3 +.Sh HISTORY +.Fn ASN1_item_new +and +.Fn ASN1_item_free +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Sh BUGS +The +.Vt ASN1_VALUE +type compromises type safety and invites programming mistakes that +will typically have severe consequences. diff --git a/Libraries/libressl/man/ASN1_item_pack.3 b/Libraries/libressl/man/ASN1_item_pack.3 new file mode 100644 index 000000000..4c8753062 --- /dev/null +++ b/Libraries/libressl/man/ASN1_item_pack.3 @@ -0,0 +1,84 @@ +.\" $OpenBSD: ASN1_item_pack.3,v 1.1 2021/11/15 11:51:09 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 15 2021 $ +.Dt ASN1_ITEM_PACK 3 +.Os +.Sh NAME +.Nm ASN1_item_pack , +.Nm ASN1_item_unpack +.Nd pack an ASN.1 object into an ASN1_STRING +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_STRING * +.Fo ASN1_item_pack +.Fa "void *val_in" +.Fa "const ASN1_ITEM *it" +.Fa "ASN1_STRING **string_out" +.Fc +.Ft void * +.Fo ASN1_item_unpack +.Fa "const ASN1_STRING *string_in" +.Fa "const ASN1_ITEM *it" +.Fc +.Sh DESCRIPTION +.Fn ASN1_item_pack +encodes the object pointed to by +.Fa val_in +into DER format using +.Xr ASN1_item_i2d 3 +and stores the encoded form in +.Pf ** Fa string_out . +If +.Fa string_out +or +.Pf * Fa string_out +is a +.Dv NULL +pointer, a new +.Vt ASN1_STRING +object is allocated and returned. +.Pp +.Fn ASN1_item_unpack +interprets the data in +.Fa string_in +as a DER- or BER-encoded byte array and decodes one value of the type +.Fa it +into a newly allocated object using +.Xr ASN1_item_d2i 3 . +.Sh RETURN VALUES +.Fn ASN1_item_pack +returns the modified or new object or +.Dv NULL +if memory allocation or encoding fails. +.Pp +.Fn ASN1_item_unpack +returns the new object or +.Dv NULL +if memory allocation or decoding fails. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr ASN1_item_new 3 , +.Xr ASN1_STRING_new 3 +.Sh HISTORY +.Fn ASN1_item_pack +and +.Fn ASN1_item_unpack +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Sh BUGS +See the BUGS section in +.Xr ASN1_item_i2d 3 . diff --git a/Libraries/libressl/man/ASN1_item_sign.3 b/Libraries/libressl/man/ASN1_item_sign.3 new file mode 100644 index 000000000..b47fd1d04 --- /dev/null +++ b/Libraries/libressl/man/ASN1_item_sign.3 @@ -0,0 +1,128 @@ +.\" $OpenBSD: ASN1_item_sign.3,v 1.2 2021/12/18 17:47:44 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 18 2021 $ +.Dt ASN1_ITEM_SIGN 3 +.Os +.Sh NAME +.Nm ASN1_item_sign , +.Nm ASN1_item_sign_ctx +.Nd DER-encode and sign an ASN.1 value +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo ASN1_item_sign +.Fa "const ASN1_ITEM *it" +.Fa "X509_ALGOR *algor1" +.Fa "X509_ALGOR *algor2" +.Fa "ASN1_BIT_STRING *sig_out" +.Fa "void *val_in" +.Fa "EVP_PKEY *pkey" +.Fa "const EVP_MD *type" +.Fc +.Ft int +.Fo ASN1_item_sign_ctx +.Fa "const ASN1_ITEM *it" +.Fa "X509_ALGOR *algor1" +.Fa "X509_ALGOR *algor2" +.Fa "ASN1_BIT_STRING *sig_out" +.Fa "void *val_in" +.Fa "EVP_MD_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn ASN1_item_sign +assumes that +.Fa val_in +is an +.Vt ASN1_VALUE +of the type specified by +.Fa it , +encodes it into DER format by calling +.Xr ASN1_item_i2d 3 , +and signs the resulting byte array in a way similar to +.Xr EVP_DigestSign 3 , +using a signing context created with +.Xr EVP_DigestSignInit 3 +for the given digest +.Fa type +and private key +.Fa pkey . +The created signature is placed into the +.Fa sig_out +object provided by the caller, +freeing and replacing any data already contained in that object. +.Pp +.Fn ASN1_item_sign_ctx +is similar except that the provided +.Ft ctx +is used rather than creating a new one. +No matter whether +.Fn ASN1_item_sign_ctx +succeeds or fails, +.Xr EVP_MD_CTX_cleanup 3 +is called on +.Fa ctx +before returning. +.Pp +For both functions, unless +.Fa algor1 +is +.Dv NULL , +its algorithm OID and parameter type are set according to the digest +.Fa type +used, and its parameter value is cleared. +In RSA-PSS mode, the parameter value is also copied into +.Fa algor1 . +Unless +.Fa algor2 +is +.Dv NULL , +the same data is copied into it. +.\" The following is not yet supported by LibreSSL +.\" because we do not provide EVP_PKEY_asn1_set_item(3). +.\" except that user-defined key types set up with +.\" .Xr EVP_PKEY_asn1_new 3 +.\" may optionally provide information about a second algorithm in +.\" .Fa algor2 . +.Sh RETURN VALUES +These functions return the length of the signature in bytes +or 0 if memory allocation, encoding, or signing fails. +.Pp +.Fn ASN1_item_sign_ctx +also fails and returns 0 if +.Fa ctx +is not fully initialized. +.Sh SEE ALSO +.Xr ASN1_BIT_STRING_new 3 , +.Xr ASN1_item_digest 3 , +.Xr ASN1_item_i2d 3 , +.Xr ASN1_item_verify 3 , +.Xr EVP_Digest 3 , +.Xr EVP_DigestSign 3 , +.Xr EVP_MD_CTX_new 3 , +.\" We do not provide EVP_PKEY_asn1_set_item(3). +.\" .Xr EVP_PKEY_asn1_new 3 , +.Xr EVP_PKEY_new 3 , +.Xr OBJ_find_sigid_by_algs 3 , +.Xr X509_ALGOR_new 3 +.Sh HISTORY +.Fn ASN1_item_sign +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.1 . +.Pp +.Fn ASN1_item_sign_ctx +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/ASN1_item_verify.3 b/Libraries/libressl/man/ASN1_item_verify.3 new file mode 100644 index 000000000..d2810879e --- /dev/null +++ b/Libraries/libressl/man/ASN1_item_verify.3 @@ -0,0 +1,77 @@ +.\" $OpenBSD: ASN1_item_verify.3,v 1.3 2021/12/18 17:47:44 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 18 2021 $ +.Dt ASN1_ITEM_VERIFY 3 +.Os +.Sh NAME +.Nm ASN1_item_verify +.Nd signature verification for ASN.1 values +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo ASN1_item_verify +.Fa "const ASN1_ITEM *it" +.Fa "X509_ALGOR *algor1" +.Fa "ASN1_BIT_STRING *sig_in" +.Fa "void *val_in" +.Fa "EVP_PKEY *pkey" +.Fc +.Sh DESCRIPTION +.Fn ASN1_item_verify +assumes that +.Fa val_in +is an +.Ft ASN1_VALUE +of the type specified by +.Fa it , +encodes it into DER format by calling +.Xr ASN1_item_i2d 3 , +and verifies in a way similar to +.Xr EVP_DigestVerify 3 +that +.Fa sig_in +contains a valid signature of the resulting byte array, +a signature that was created with the signature algorithm +.Fa algor1 +and the private key corresponding to the public key +.Fa pkey . +.Sh RETURN VALUES +.Fn ASN1_item_verify +returns 1 if signature verification succeeds, 0 if signature verification +fails, or \-1 if +.Fa pkey +is +.Dv NULL , +if +.Fa sig_in +contains invalid flags, or if +.Fa algor1 +requests an invalid or unsupported digest algorithm +or does not work with the given +.Fa pkey . +.Sh SEE ALSO +.Xr ASN1_BIT_STRING_new 3 , +.Xr ASN1_item_i2d 3 , +.Xr ASN1_item_sign 3 , +.Xr EVP_DigestVerify 3 , +.Xr EVP_PKEY_new 3 , +.Xr OBJ_find_sigid_algs 3 , +.Xr X509_ALGOR_new 3 +.Sh HISTORY +.Fn ASN1_item_verify +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.1 . diff --git a/Libraries/libressl/man/ASN1_mbstring_copy.3 b/Libraries/libressl/man/ASN1_mbstring_copy.3 new file mode 100644 index 000000000..e0b48aaa6 --- /dev/null +++ b/Libraries/libressl/man/ASN1_mbstring_copy.3 @@ -0,0 +1,369 @@ +.\" $OpenBSD: ASN1_mbstring_copy.3,v 1.6 2022/02/21 00:22:03 jsg Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 21 2022 $ +.Dt ASN1_MBSTRING_COPY 3 +.Os +.Sh NAME +.Nm ASN1_mbstring_copy , +.Nm ASN1_mbstring_ncopy , +.Nm ASN1_STRING_set_by_NID , +.Nm ASN1_STRING_set_default_mask , +.Nm ASN1_STRING_set_default_mask_asc , +.Nm ASN1_STRING_get_default_mask , +.Nm ASN1_tag2bit +.Nd copy a multibyte string into an ASN.1 string object +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_mbstring_copy +.Fa "ASN1_STRING **out" +.Fa "const unsigned char *in" +.Fa "int inbytes" +.Fa "int inform" +.Fa "unsigned long mask" +.Fc +.Ft int +.Fo ASN1_mbstring_ncopy +.Fa "ASN1_STRING **out" +.Fa "const unsigned char *in" +.Fa "int inbytes" +.Fa "int inform" +.Fa "unsigned long mask" +.Fa "long minchars" +.Fa "long maxchars" +.Fc +.Ft ASN1_STRING * +.Fo ASN1_STRING_set_by_NID +.Fa "ASN1_STRING **out" +.Fa "const unsigned char *in" +.Fa "int inbytes" +.Fa "int inform" +.Fa "int nid" +.Fc +.Ft void +.Fo ASN1_STRING_set_default_mask +.Fa "unsigned long mask" +.Fc +.Ft int +.Fo ASN1_STRING_set_default_mask_asc +.Fa "const char *maskname" +.Fc +.Ft unsigned long +.Fn ASN1_STRING_get_default_mask void +.Ft unsigned long +.Fn ASN1_tag2bit "int tag" +.Sh DESCRIPTION +.Fn ASN1_mbstring_copy +interprets +.Fa inbytes +bytes starting at +.Fa in +as a multibyte string and copies it to +.Pf * Fa out , +optionally changing the encoding. +If the +.Fa inbytes +argument is negative, the +.Xr strlen 3 +of +.Fa in +is used instead. +.Pp +The +.Fa inform +argument specifies the character encoding of +.Fa in : +.Bl -column MBSTRING_UNIV encoding +.It Ar inform Ta encoding +.It Dv MBSTRING_ASC Ta ISO-Latin-1 +.It Dv MBSTRING_BMP Ta UTF-16 +.It Dv MBSTRING_UNIV Ta UTF-32 +.It Dv MBSTRING_UTF8 Ta UTF-8 +.El +.Pp +The bit +.Fa mask +specifies a set of ASN.1 string types +that the user is willing to accept: +.Bl -column B_ASN1_UNIVERSALSTRING ASN1_UNIVERSALSTRING default +.It bit in Fa mask Ta acceptable output type Ta default +.It Dv B_ASN1_PRINTABLESTRING Ta Vt ASN1_PRINTABLESTRING Ta yes +.It Dv B_ASN1_IA5STRING Ta Vt ASN1_IA5STRING Ta no +.It Dv B_ASN1_T61STRING Ta Vt ASN1_T61STRING Ta yes +.It Dv B_ASN1_BMPSTRING Ta Vt ASN1_BMPSTRING Ta yes +.It Dv B_ASN1_UNIVERSALSTRING Ta Vt ASN1_UNIVERSALSTRING Ta no +.It any other bit Ta Vt ASN1_UTF8STRING Ta yes +.El +.Pp +The first type from the above table that is included in the +.Fa mask +argument and that can represent +.Fa in +is used as the output type. +The +.Dq default +column indicates whether the type is considered acceptable if the +.Fa mask +argument has the special value 0. +.Pp +The following bit mask constants +each include several of the bits listed above: +.Bl -column B_ASN1_DIRECTORYSTRING_ MMM MMM MMM MMM MMM MMMM +.It mask constant Ta PRI Ta IA5 Ta T61 Ta BMP Ta UNI Ta UTF8 +.It Dv B_ASN1_DIRECTORYSTRING Ta yes Ta no Ta yes Ta yes Ta yes Ta yes +.It Dv DIRSTRING_TYPE Ta yes Ta no Ta yes Ta yes Ta no Ta yes +.It Dv PKCS9STRING_TYPE Ta yes Ta yes Ta yes Ta yes Ta no Ta yes +.El +.Pp +If +.Fa out +is +.Dv NULL , +.Fa inform , +.Fa inbytes , +and +.Fa in +are validated and the output type is determined and returned, +but nothing is copied. +.Pp +Otherwise, if +.Pf * Fa out +is +.Dv NULL , +a new output object of the output type is allocated +and a pointer to it is stored in +.Pf * Fa out . +.Pp +Otherwise, +.Pf ** Fa out +is used as the output object. +Any data already stored in it is freed +and its type is changed to the output type. +.Pp +Finally, +.Fa in +is copied to the output object, changing the character encoding if +.Fa inform +does not match the encoding used by the output type. +.Pp +.Fn ASN1_mbstring_ncopy +is similar except that the number of characters in +.Fa in +is restricted to the range from +.Fa minchars +to +.Fa maxchars , +inclusive. +If +.Fa maxchars +is 0, no upper limit is enforced on the number of characters. +.Pp +.Fn ASN1_STRING_set_by_NID +is similar with the following differences: +.Bl -bullet -width 1n +.It +If +.Fa out +is +.Dv NULL , +a new output object is allocated and returned +instead of skipping the copying. +.It +If +.Fa nid +has a global string table entry that can be retrieved with +.Xr ASN1_STRING_TABLE_get 3 , +.Fa mask , +.Fa minchars , +and +.Fa maxchars +are taken from that string table entry. +For some values of +.Fa nid , +an additional global mask is AND'ed into the mask before using it. +The default value of the global mask is +.Dv B_ASN1_UTF8STRING . +.It +If +.Fa nid +has no global string table entry, +.Dv B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | +.Dv B_ASN1_BMPSTRING | B_ASN1_UTF8STRING +is used instead of the mask taken from the table, +and the global mask is also AND'ed into it. +.It +Even though success and failure happen in the same situations, +the return value is different. +.Xr ASN1_STRING_type 3 +can be used to determine the type of the return value. +.El +.Pp +.Fn ASN1_STRING_set_default_mask +sets the global mask used by +.Fn ASN1_STRING_set_by_NID +to the +.Fa mask +argument. +.Pp +.Fn ASN1_STRING_set_default_mask_asc +sets the global mask as follows: +.Bl -column utf8only +.It Ar maskname Ta Ar mask +.It Qo default Qc Ta anything +.It Qo nombstr Qc Ta anything except Dv B_ASN1_BMPSTRING | B_ASN1_UTF8STRING +.It Qo pkix Qc Ta anything except Dv B_ASN1_T61STRING +.It Qo utf8only Qc Ta Dv B_ASN1_UTF8STRING +.El +.Pp +If the +.Fa maskname +argument starts with the substring +.Qq MASK:\& , +the rest of it is interpreted as an +.Vt unsigned long +value using +.Xr strtoul 3 . +.Pp +.Fn ASN1_tag2bit +translates ASN.1 data types to type bits as follows: +.Bl -column V_ASN1_OBJECT_DESCRIPTOR B_ASN1_UNIVERSALSTRING +.It Fa tag Ta return value +.It Dv V_ASN1_BIT_STRING Ta Dv B_ASN1_BIT_STRING +.It Dv V_ASN1_BMPSTRING Ta Dv B_ASN1_BMPSTRING +.It Dv V_ASN1_BOOLEAN Ta 0 +.It Dv V_ASN1_ENUMERATED Ta Dv B_ASN1_UNKNOWN +.It Dv V_ASN1_EOC Ta 0 +.It Dv V_ASN1_EXTERNAL Ta Dv B_ASN1_UNKNOWN +.It Dv V_ASN1_GENERALIZEDTIME Ta Dv B_ASN1_GENERALIZEDTIME +.It Dv V_ASN1_GENERALSTRING Ta Dv B_ASN1_GENERALSTRING +.It Dv V_ASN1_GRAPHICSTRING Ta Dv B_ASN1_GRAPHICSTRING +.It Dv V_ASN1_IA5STRING Ta Dv B_ASN1_IA5STRING +.It Dv V_ASN1_INTEGER Ta 0 +.It Dv V_ASN1_ISO64STRING Ta Dv B_ASN1_ISO64STRING +.It Dv V_ASN1_NULL Ta 0 +.It Dv V_ASN1_NUMERICSTRING Ta Dv B_ASN1_NUMERICSTRING +.It Dv V_ASN1_OBJECT Ta 0 +.It Dv V_ASN1_OBJECT_DESCRIPTOR Ta Dv B_ASN1_UNKNOWN +.It Dv V_ASN1_OCTET_STRING Ta Dv B_ASN1_OCTET_STRING +.It Dv V_ASN1_PRINTABLESTRING Ta Dv B_ASN1_PRINTABLESTRING +.It Dv V_ASN1_REAL Ta Dv B_ASN1_UNKNOWN +.It Dv V_ASN1_SEQUENCE Ta Dv B_ASN1_SEQUENCE +.It Dv V_ASN1_SET Ta 0 +.It Dv V_ASN1_T61STRING Ta Dv B_ASN1_T61STRING +.It Dv V_ASN1_TELETEXSTRING Ta Dv B_ASN1_TELETEXSTRING +.It Dv V_ASN1_UNDEF Ta 0 +.It Dv V_ASN1_UNIVERSALSTRING Ta Dv B_ASN1_UNIVERSALSTRING +.It Dv V_ASN1_UTCTIME Ta Dv B_ASN1_UTCTIME +.It Dv V_ASN1_UTF8STRING Ta Dv B_ASN1_UTF8STRING +.It Dv V_ASN1_VIDEOTEXSTRING Ta Dv B_ASN1_VIDEOTEXSTRING +.It Dv V_ASN1_VISIBLESTRING Ta Dv B_ASN1_VISIBLESTRING +.It 11, 13, 14, 15, 29 Ta Dv B_ASN1_UNKNOWN +.It Dv other Po < 0, > 30 Pc Ta Dv 0 +.El +.Pp +In typical usage, the calling code calculates the bitwise AND +of the return value and a mask describing data types +that the calling code is willing to use. +If the result of the AND operation is non-zero, the data type is +adequate; otherwise, the calling code may need to raise an error. +.Sh RETURN VALUES +.Fn ASN1_mbstring_copy +and +.Fn ASN1_mbstring_ncopy +return the +.Dv V_ASN1_* +constant representing the output type or \-1 if +.Fa inform +is invalid, if +.Fa inbytes +or +.Fa in +is invalid for the +.Fa inform +encoding, if +.Fa in +contains an UTF-16 surrogate, +which is unsupported even for input using the UTF-16 encoding, +or if memory allocation fails. +.Pp +.Fn ASN1_mbstring_ncopy +also returns \-1 if +.Fa in +contains fewer than +.Fa minchars +or more than +.Fa maxchars +characters. +.Pp +.Fn ASN1_STRING_set_by_NID +returns the new or changed ASN.1 string object or +.Dv NULL +on failure. +.Pp +.Fn ASN1_STRING_set_default_mask_asc +returns 1 if successful or 0 if +.Qq MASK:\& +is not followed by a number, if the number is followed by a non-numeric +character, or if the +.Fa maskname +is invalid. +.Pp +.Fn ASN1_STRING_get_default_mask +returns the global mask. +.Pp +.Fn ASN1_tag2bit +returns a +.Dv B_ASN1_* +constant or 0. +.Sh SEE ALSO +.Xr ASN1_PRINTABLE_type 3 , +.Xr ASN1_STRING_new 3 , +.Xr ASN1_STRING_set 3 , +.Xr ASN1_STRING_TABLE_get 3 , +.Xr ASN1_UNIVERSALSTRING_to_string 3 +.Sh HISTORY +.Fn ASN1_mbstring_copy , +.Fn ASN1_mbstring_ncopy , +.Fn ASN1_STRING_set_by_NID , +.Fn ASN1_STRING_set_default_mask , +.Fn ASN1_STRING_set_default_mask_asc , +and +.Fn ASN1_STRING_get_default_mask +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn ASN1_tag2bit +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh BUGS +If integer overflow occurs in +.Fn ASN1_STRING_set_default_mask_asc +while parsing a number following +.Qq MASK:\& , +the function succeeds, essentially behaving in the same way as for +.Qq default . +.Pp +Passing +.Qq default +to +.Fn ASN1_STRING_set_default_mask_asc +does +.Em not +restore the default mask. +Instead, passing +.Qq utf8only +does that. diff --git a/Libraries/libressl/man/ASN1_parse_dump.3 b/Libraries/libressl/man/ASN1_parse_dump.3 new file mode 100644 index 000000000..50761f38a --- /dev/null +++ b/Libraries/libressl/man/ASN1_parse_dump.3 @@ -0,0 +1,216 @@ +.\" $OpenBSD: ASN1_parse_dump.3,v 1.3 2021/12/09 18:52:09 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 9 2021 $ +.Dt ASN1_PARSE_DUMP 3 +.Os +.Sh NAME +.Nm ASN1_parse_dump , +.Nm ASN1_parse +.Nd parse BER and print information about it +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo ASN1_parse_dump +.Fa "BIO *bio" +.Fa "const unsigned char *ber_in" +.Fa "long length" +.Fa "int indent" +.Fa "int dump" +.Fc +.Ft int +.Fo ASN1_parse +.Fa "BIO *bio" +.Fa "const unsigned char *ber_in" +.Fa "long length" +.Fa "int indent" +.Fc +.Sh DESCRIPTION +.Fn ASN1_parse_dump +parses BER-encoded values and prints information about them to +.Fa bio . +On function entry, +.Pf * Fa ber_in +is expected to point to the first identifier octet of an encoded value. +At most +.Fa length +bytes are inspected. +.Pp +For each value successfully parsed, the following information is printed: +.Bl -enum +.It +The index of its first identifier octet relative to +.Fa ber_in +as a decimal number followed by a colon. +For the first value parsed and printed, this is +.Qq 0:\& . +.It +The nesting depth as a decimal integer. +For the first value parsed and printed, this is +.Qq d=0 . +.It +The header length in bytes, including the identifier octets and the +length octets, as a decimal integer. +For example, for a boolean value, this is +.Qq hl=2 +because the encoding of a boolean value contains +one identifier octet (0x01) and one length octet (also 0x01, +because one content octet follows after the header). +.It +If the value is encoded using the definite form for the length octets, +the number encoded in the length octets as a decimal integer. +This is the number of content octets that follow. +For example, for a boolean value, this is +.Qq l=1 . +If the value is encoded using a length octet indicating the indefinite form, +.Qq l=inf +is printed instead. +.It +If the value is primitive, +.Qq prim:\& +is printed; +if it is constructed, +.Qq cons:\& . +.It +The next field depends on the class of the tag: +.Bl -tag -width Ds +.It Dv V_ASN1_PRIVATE +.Qq priv +followed by the decimal tag number in square brackets +.It Dv V_ASN1_CONTEXT_SPECIFIC +.Qq cont +followed by the decimal tag number in square brackets +.It Dv V_ASN1_APPLICATION +.Qq appl +followed by the decimal tag number in square brackets +.It V_ASN1_UNIVERSAL +If the tag number is 30 or less, the return value from +.Xr ASN1_tag2str 3 +is printed; otherwise, +.Qq +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 12 2022 $ +.Dt ASN1_PUT_OBJECT 3 +.Os +.Sh NAME +.Nm ASN1_put_object , +.Nm ASN1_put_eoc , +.Nm ASN1_object_size +.Nd start and end the BER encoding of an arbitrary ASN.1 data element +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft void +.Fo ASN1_put_object +.Fa "unsigned char **ber_out" +.Fa "int constructed" +.Fa "int content_length" +.Fa "int tag" +.Fa "int class" +.Fc +.Ft int +.Fo ASN1_put_eoc +.Fa "unsigned char **ber_out" +.Fc +.Ft int +.Fo ASN1_object_size +.Fa "int constructed" +.Fa "int content_length" +.Fa "int tag" +.Fc +.Sh DESCRIPTION +.Fn ASN1_put_object +begins writing the BER encoding of an arbitrary ASN.1 data element +to the buffer +.Pf * ber_out +by writing the identifier and the length bytes. +Making sure that there is sufficient space in the buffer +is the responsibility of the caller. +This function does not write any content bytes +nor any end-of-content bytes. +.Pp +The tag +.Fa class +can be +.Dv V_ASN1_UNIVERSAL , +.Dv V_ASN1_APPLICATION , +.Dv V_ASN1_CONTEXT_SPECIFIC , +or +.Dv V_ASN1_PRIVATE +and is written to the two most significant bits of the first byte written. +.Pp +The +.Fa constructed +argument can have the following values: +.Bl -tag -width 1n -offset 2n -compact +.It 0 +Start a primitive value by setting the third most significant bit +of the first byte written to 0. +Always use the definite form. +.It 1 +Start a constructed value by setting the third most significant bit +of the first byte written to 1, and use the definite form. +.It 2 +Start a constructed value and use the indefinite form, +.El +.Pp +If the +.Fa tag +is less than +.Dv V_ASN1_PRIMITIVE_TAG Pq = 0x1f , +it is written to the five least significant bits +of the only identifier byte written. +Otherwise, these five bits are all set to 1, and the +.Fa tag +is encoded in one or more following identifier bytes as needed. +.Pp +After completing the identifier byte(s), +when using the definite form, the given +.Fa content_length +is encoded in one or more bytes as needed, +using the long form if and only if the +.Fa content_length +is greater than 127. +When using the indefinite form, +the special byte 0x80 is written instead and the +.Fa content_length +argument is ignored. +.Pp +At the end, +.Pf * Fa ber_out +is set to the byte following the last byte written. +The calling code can then start writing content bytes. +.Pp +If the indefinite form was selected, +the calling code is also responsible for calling +.Fn ASN1_put_eoc +which writes an end-of-content marker to +.Pf * Fa ber_out , +consisting of two NUL bytes, and advances +.Pf * Fa ber_out +by two bytes. +.Pp +.Fn ASN1_object_size +calculates the total length in bytes of the BER encoding +of an ASN.1 data element with the given +.Fa tag +and the number of content bytes given by +.Fa content_length . +The +.Fa constructed +argument has the same meaning as for +.Fn ASN1_put_object . +The return value includes the identifier, length, and content bytes. +If +.Fa constructed +is 2, it also includes the end-of-content bytes. +For the definite form, only the short form is supported if the +.Fa content_length +is less than 128. +.Sh RETURN VALUES +.Fn ASN1_put_eoc +returns the number of bytes written, which is always 2. +.Pp +.Fn ASN1_object_size +returns the total number of bytes in the encoding of the data element. +.Sh SEE ALSO +.Xr ASN1_item_i2d 3 , +.Xr ASN1_TYPE_get 3 , +.Xr i2d_ASN1_NULL 3 , +.Xr i2d_ASN1_OBJECT 3 , +.Xr i2d_ASN1_OCTET_STRING 3 , +.Xr i2d_ASN1_SEQUENCE_ANY 3 +.Sh STANDARDS +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.1: General rules for encoding +.Sh HISTORY +.Fn ASN1_put_object +and +.Fn ASN1_object_size +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn ASN1_put_eoc +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Sh CAVEATS +None of these functions do any sanity checking. +When called in inconsistent ways, invalid content may result in +.Pf * Fa ber_out , +for example +.Bl -dash -compact +.It +a +.Fa tag +number less than +.Dv V_ASN1_PRIMITIVE_TAG +with a +.Fa class +other than +.Dv V_ASN1_UNIVERSAL +.It +a +.Fa tag +number equal to +.Dv V_ASN1_EOC Pq 0x00 +or +.Dv V_ASN1_PRIMITIVE_TAG Pq 0x1f +.It +a +.Vt BOOLEAN , +.Vt INTEGER , +.Vt NULL +etc. with the +.Fa constructed +bit set +.It +a +.Vt SEQUENCE +or +.Vt SET +etc. without the +.Fa constructed +bit set +.It +a +.Fa content_length +that makes no sense for the given +.Fa tag +.It +a +.Fa content_length +that disagrees with the following data +.It +a +.Vt BOOLEAN , +.Vt INTEGER , +.Vt NULL +etc. in indefinite form +.It +an end-of-content marker even though no indefinite form was started +.It +\&... +.El +.Pp +If the calling code wants to find out how many bytes were written, +it needs to save a copy of the pointer +.Pf * Fa ber_out +before calling +.Fn ASN1_put_object . diff --git a/Libraries/libressl/man/ASN1_time_parse.3 b/Libraries/libressl/man/ASN1_time_parse.3 new file mode 100644 index 000000000..6ec45e5dc --- /dev/null +++ b/Libraries/libressl/man/ASN1_time_parse.3 @@ -0,0 +1,141 @@ +.\" $OpenBSD: ASN1_time_parse.3,v 1.9 2020/11/02 17:45:35 tb Exp $ +.\" +.\" Copyright (c) 2016 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 2 2020 $ +.Dt ASN1_TIME_PARSE 3 +.Os +.Sh NAME +.Nm ASN1_time_parse , +.Nm ASN1_time_tm_cmp , +.Nm ASN1_TIME_set_tm +.Nd LibreSSL utilities for ASN.1 time types +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fn ASN1_time_parse "const char *bytes" "size_t len" "struct tm *tm" "int mode" +.Ft int +.Fn ASN1_time_tm_cmp "struct tm *tm1" "struct tm *tm2" +.Ft ASN1_TIME * +.Fn ASN1_TIME_set_tm "ASN1_TIME *s" "struct tm *tm" +.Sh DESCRIPTION +The +.Fn ASN1_time_parse +function parses an ASN.1 time string of +.Ar len +bytes starting at +.Ar bytes . +The resulting time is stored in +.Ar tm +if +.Ar tm +is not +.Dv NULL . +.Pp +The +.Ar mode +parameter must be one of +.Bl -bullet -offset four +.It +0 to parse a time as specified in RFC 5280 for an X509 object, +which may be either a UTC time or a Generalized time. +.It +.Dv V_ASN1_UTCTIME +to parse an RFC 5280 format UTC time. +.It +.Dv V_ASN1_GENERALIZEDTIME +to parse an RFC 5280 format Generalized time. +.El +.Pp +The +.Fn ASN1_time_tm_cmp +function compares two times in +.Ar tm1 +and +.Ar tm2 . +.Pp +The function +.Fn ASN1_TIME_set_tm +sets the +.Vt ASN1_TIME +structure +.Fa s +to the time represented by the +.Vt struct tm +value pointed to by +.Fa tm . +If +.Fa s +is +.Dv NULL , +a new +.Vt ASN1_TIME +structure is allocated and returned. +.Sh RETURN VALUES +.Fn ASN1_time_parse +returns +.Bl -bullet -offset four +.It +-1 if the string was invalid for the +.Ar mode +specified. +.It +.Dv V_ASN1_UTCTIME +if the string parsed as a valid UTC time. +.It +.Dv V_ASN1_GENERALIZEDTIME +if the string parsed as a valid Generalized time. +.El +.Pp +.Fn ASN1_time_tm_cmp +returns +.Bl -bullet -offset four +.It +-1 if +.Ar tm1 +is less than +.Ar tm2 . +.It +1 if +.Ar tm1 +is greater than +.Ar tm2 . +.It +0 if +.Ar tm1 +is the same as +.Ar tm2 . +.El +.Pp +.Fn ASN1_TIME_set_tm +returns a pointer to an +.Vt ASN1_TIME +structure or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr ASN1_TIME_new 3 , +.Xr ASN1_TIME_set 3 , +.Xr X509_cmp_time 3 +.Sh HISTORY +.Fn ASN1_time_parse +and +.Fn ASN1_time_tm_cmp +first appeared in +.Ox 6.1 +and +.Fn ASN1_TIME_set_tm +in +.Ox 6.2 . diff --git a/Libraries/libressl/man/ASRange_new.3 b/Libraries/libressl/man/ASRange_new.3 new file mode 100644 index 000000000..5d92a375f --- /dev/null +++ b/Libraries/libressl/man/ASRange_new.3 @@ -0,0 +1,417 @@ +.\" $OpenBSD: ASRange_new.3,v 1.7 2023/10/01 05:20:41 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 1 2023 $ +.Dt ASRANGE_NEW 3 +.Os +.Sh NAME +.Nm ASRange_new , +.Nm ASRange_free , +.Nm d2i_ASRange , +.Nm i2d_ASRange , +.Nm ASIdOrRange_new , +.Nm ASIdOrRange_free , +.Nm d2i_ASIdOrRange , +.Nm i2d_ASIdOrRange , +.Nm ASIdentifierChoice_new , +.Nm ASIdentifierChoice_free , +.Nm d2i_ASIdentifierChoice , +.Nm i2d_ASIdentifierChoice +.Nd RFC 3779 autonomous system identifiers and ranges +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft "ASRange *" +.Fn ASRange_new void +.Ft void +.Fn ASRange_free "ASRange *asrange" +.Ft ASRange * +.Fo d2i_ASRange +.Fa "ASRange **asrange" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASRange +.Fa "ASRange *asrange" +.Fa "unsigned char **der_out" +.Fc +.Ft "ASIdOrRange *" +.Fn ASIdOrRange_new void +.Ft void +.Fn ASIdOrRange_free "ASIdOrRange *aor" +.Ft ASIdOrRange * +.Fo d2i_ASIdOrRange +.Fa "ASIdOrRange **aor" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASIdOrRange +.Fa "ASIdOrRange *aor" +.Fa "unsigned char **der_out" +.Fc +.Ft "ASIdentifierChoice *" +.Fn ASIdentifierChoice_new void +.Ft void +.Fn ASIdentifierChoice_free "ASIdentifierChoice *aic" +.Ft ASIdentifierChoice * +.Fo d2i_ASIdentifierChoice +.Fa "ASIdentifierChoice **aic" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASIdentifierChoice +.Fa "ASIdentifierChoice *aic" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Vt ASRange , +.Vt ASIdOrRange , +and +.Vt ASIdentifierChoice +are building blocks of the +.Vt ASIdentifiers +type representing the RFC 3779 +autonomous system identifier delegation extension. +.Pp +All +.Vt ASN1_INTEGER Ns s +in this manual must be representable as unsigned 32-bit integers. +The API performs no corresponding checks. +The library provides no convenient way of setting the value of an +.Vt ASN1_INTEGER +directly. +A detour via a +.Vt BIGNUM +or a string is unavoidable. +To retrieve the value of an +.Vt ASN1_INTEGER , +use +.Xr ASN1_INTEGER_get_uint64 3 . +.Pp +The +.Vt ASRange +type defined in RFC 3779 section 3.2.3.8 is implemented as +.Bd -literal -offset indent +typedef struct ASRange_st { + ASN1_INTEGER *min; + ASN1_INTEGER *max; +} ASRange; +.Ed +.Pp +It represents the closed range [min,max] of AS identifiers between +.Fa min +and +.Fa max , +where +.Fa min +should be strictly smaller than +.Fa max . +.Pp +.Fn ASRange_new +allocates a new +.Vt ASRange +object with allocated, empty +.Fa min +and +.Fa max , +thus representing the invalid range [0,0]. +.Pp +.Fn ASRange_free +frees +.Fa asrange +including any data contained in it. +If +.Fa asrange +is +.Dv NULL , +no action occurs. +.Pp +The +.Vt ASIdOrRange +type defined in RFC 3779 section 3.2.3.5 is implemented as +.Bd -literal -offset indent +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; +.Ed +.Pp +representing an individual AS identifier or a range. +When populating an +.Vt ASIdOrRange +object by hand, its +.Fa type +should be set to +.Dv ASIdOrRange_id +or +.Dv ASIdOrRange_range +to indicate which member of the union +.Fa u +is valid. +.Pp +.Fn ASIdOrRange_new +returns a new +.Vt ASIdOrRange +object with invalid type and +.Dv NULL +members of the union +.Fa u . +.Pp +.Fn ASIdOrRange_free +frees +.Fa aor +including any data contained in it, +provided +.Fa type +is set correctly. +If +.Fa asrange +is +.Dv NULL , +no action occurs. +.Pp +In order to express a list of AS identifiers and ranges, +RFC 3779 section 3.2.3.4 +uses an ASN.1 SEQUENCE, +which is implemented via a +.Xr STACK_OF 3 +construction over +.Vt ASIdOrRange : +.Bd -literal -offset indent +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +.Ed +.Pp +Since an +.Vt ASIdOrRanges +object should be sorted in a specific way (see +.Xr X509v3_asid_canonize 3 Ns ), +a comparison function is needed for a correct instantiation +with +.Xr sk_new 3 . +The +.Fn ASIdOrRange_cmp +function is not directly exposed and not easily accessible +from outside the library, +and it is non-trivial to implement. +It is therefore discouraged to use +.Vt ASIdOrRanges +objects that are not part of an +.Vt ASIdentifiers +object. +.Pp +The +.Dq inherit +marker from RFC 3779 section 3.2.3.3 is implemented as +.Vt ASN1_NULL . +It has no dedicated type or API and can be instantiated with +.Xr ASN1_NULL_new 3 . +.Pp +The +.Vt ASIdentifierChoice +type defined in RFC 3779 section 3.2.3.2 is implemented as +.Bd -literal -offset indent +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; +.Ed +.Pp +where the +.Fa type +member should be set to +.Dv ASIdentifierChoice_inherit +or +.Dv ASIdentifierChoice_asIdsOrRanges +to indicate whether a given +.Vt ASIdentifierChoice +object represents an inherited list or an explicit list. +.Pp +.Fn ASIdentifierChoice_new +returns a new +.Vt ASIdentifierChoice +object with invalid type and +.Dv NULL +members of the union +.Fa u . +.Pp +.Fn ASIdentifierChoice_free +frees +.Fa aic +including any data contained in it, +provided +.Fa type +is set correctly. +.Pp +The +.Vt ASIdentifiers +type defined in RFC 3779 section 3.2.3.1 is implemented as +.Bd -literal -offset indent +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum; + ASIdentifierChoice *rdi; +} ASIdentifiers; +.Ed +.Pp +It should be instantiated with +.Xr ASIdentifiers_new 3 +and populated with +.Xr X509v3_asid_add_id_or_range 3 . +.Pp +.Fn d2i_ASRange , +.Fn i2d_ASRange , +.Fn d2i_ASIdOrRange , +.Fn i2d_ASIdOrRange , +.Fn d2i_ASIdentifierChoice , +and +.Fn i2d_ASIdentifierChoice +decode and encode ASN.1 +.Vt ASRange , +.Vt ASIdOrRange , +and +.Vt ASIdentifierChoice +objects. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +In order for the encoding produced by +.Fn i2d_ASRange +to be correct, +.Fa min +must be strictly less than +.Fa max . +Similarly for +.Fn i2d_ASIdOrRange +and an +.Fa ASIdOrRange +object of +.Fa type +.Dv ASIdOrRange_range . +.Sh RETURN VALUES +.Fn ASRange_new +returns a new +.Vt ASRange +object with allocated, empty members, or +.Dv NULL +if an error occurs. +.Pp +.Fn ASIdOrRange_new +returns a new, empty +.Vt ASIdOrRange +object or +.Dv NULL +if an error occurs. +.Pp +.Fn ASIdentifierChoice_new +returns a new, empty +.Vt ASIdentifierChoice +object or +.Dv NULL +if an error occurs. +.Pp +The decoding functions +.Fn d2i_ASRange , +.Fn d2i_ASIdOrRange , +and +.Fn d2i_ASIdentifierChoice +return an +.Vt ASRange , +an +.Vt ASIdOrRange , +or an +.Vt ASIdentifierChoice , +object, respectively, +or +.Dv NULL +if an error occurs. +.Pp +The encoding functions +.Fn i2d_ASRange , +.Fn i2d_ASIdOrRange , +and +.Fn i2d_ASIdentifierChoice +return the number of bytes successfully encoded +or a value <= 0 if an error occurs. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr BN_set_word 3 , +.Xr BN_to_ASN1_INTEGER 3 , +.Xr crypto 3 , +.Xr IPAddressRange_new 3 , +.Xr s2i_ASN1_INTEGER 3 , +.Xr STACK_OF 3 , +.Xr X509_new 3 , +.Xr X509v3_asid_add_id_or_range 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 3.2.3: Syntax +.It +section 3.2.3.1: Type ASIdentifiers +.It +section 3.2.3.2: Elements asnum, rdi, and Type ASIdentifierChoice +.It +section 3.2.3.3: Element inherit +.It +section 3.2.3.4: Element asIdsOrRanges +.It +section 3.2.3.5: Type ASIdOrRange +.It +section 3.2.3.6: Element id +.It +section 3.2.3.7: Element range +.It +section 3.2.3.8: Type ASRange +.It +section 3.2.3.9: Elements min and max +.El +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +An +.Fn ASIdOrRanges_new +function that installs the correct comparison function +on the stack of +.Vt ASIdOrRange +should have been part of the API to make it usable. +.Pp +.Fn ASIdentifierChoice_new +is of very limited use because +.Fn ASIdOrRanges_new +is missing. +.Pp +There is no way of ensuring that an +.Vt ASIdOrRanges +object is in canonical form unless it is part of an +.Vt ASIdentifiers +object. +It is therefore difficult to guarantee that the output of +.Fn i2d_ASIdentifierChoice +is conformant. +.Pp +RFC 3779 3.2.3.4 has +.Dq Fa asIdsOrRanges +while its type in this implementation is +.Vt ASIdOrRanges . diff --git a/Libraries/libressl/man/AUTHORITY_KEYID_new.3 b/Libraries/libressl/man/AUTHORITY_KEYID_new.3 new file mode 100644 index 000000000..bff451ff3 --- /dev/null +++ b/Libraries/libressl/man/AUTHORITY_KEYID_new.3 @@ -0,0 +1,73 @@ +.\" $OpenBSD: AUTHORITY_KEYID_new.3,v 1.4 2019/06/06 01:06:58 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt AUTHORITY_KEYID_NEW 3 +.Os +.Sh NAME +.Nm AUTHORITY_KEYID_new , +.Nm AUTHORITY_KEYID_free +.Nd X.509 authority key identifier extension +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft AUTHORITY_KEYID * +.Fn AUTHORITY_KEYID_new void +.Ft void +.Fn AUTHORITY_KEYID_free "AUTHORITY_KEYID *id" +.Sh DESCRIPTION +Using the authority key identifier extension, an X.509 certificate +or certificate revocation list can specify which key pair was used +for signing it. +.Pp +.Fn AUTHORITY_KEYID_new +allocates and initializes an empty +.Vt AUTHORITY_KEYID +object, representing an ASN.1 +.Vt AuthorityKeyIdentifier +structure defined in RFC 5280 section 4.2.1.1. +It can hold an issuer name, a serial number, and a key identifier. +.Pp +.Fn AUTHORITY_KEYID_free +frees +.Fa id . +.Sh RETURN VALUES +.Fn AUTHORITY_KEYID_new +returns the new +.Vt AUTHORITY_KEYID +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_AUTHORITY_KEYID 3 , +.Xr GENERAL_NAMES_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.1.1: Certificate Extensions: Authority Key Identifier +.It +section 5.2.1: CRL Extensions: Authority Key Identifier +.El +.Sh HISTORY +.Fn AUTHORITY_KEYID_new +and +.Fn AUTHORITY_KEYID_free +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/BASIC_CONSTRAINTS_new.3 b/Libraries/libressl/man/BASIC_CONSTRAINTS_new.3 new file mode 100644 index 000000000..e60b0d223 --- /dev/null +++ b/Libraries/libressl/man/BASIC_CONSTRAINTS_new.3 @@ -0,0 +1,89 @@ +.\" $OpenBSD: BASIC_CONSTRAINTS_new.3,v 1.6 2021/10/27 11:24:47 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 27 2021 $ +.Dt BASIC_CONSTRAINTS_NEW 3 +.Os +.Sh NAME +.Nm BASIC_CONSTRAINTS_new , +.Nm BASIC_CONSTRAINTS_free +.Nd X.509 extension to mark CA certificates +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft BASIC_CONSTRAINTS * +.Fn BASIC_CONSTRAINTS_new void +.Ft void +.Fn BASIC_CONSTRAINTS_free "BASIC_CONSTRAINTS *bc" +.Sh DESCRIPTION +.Fn BASIC_CONSTRAINTS_new +allocates and initializes an empty +.Vt BASIC_CONSTRAINTS +object, representing an ASN.1 +.Vt BasicConstraints +structure defined in RFC 5280 section 4.2.1.9. +.Pp +This object contains two fields. +The field +.Fa "int ca" +is non-zero if the certificate is a CA certificate. +The field +.Fa "ASN1_INTEGER *pathlen" +specifies the maximum number of non-self-issued intermediate +certificates that may follow this certificate in a valid +certification path. +.Pp +If an X.509 version 3 certificate does not contain this extension +or if the +.Fa ca +field of the +.Vt BASIC_CONSTRAINTS +object is 0, or if the certificate contains a key usage extension +having the +.Dv KU_KEY_CERT_SIGN +bit unset, then it is not a CA certificate but an end entity +certificate. +.Pp +.Fn BASIC_CONSTRAINTS_free +frees +.Fa bc . +.Sh RETURN VALUES +.Fn BASIC_CONSTRAINTS_new +returns the new +.Vt BASIC_CONSTRAINTS +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_BASIC_CONSTRAINTS 3 , +.Xr X509_check_purpose 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get_extension_flags 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.1.9: Basic Constraints +.It +section 6.1: Basic Path Validation +.El +.Sh HISTORY +.Fn BASIC_CONSTRAINTS_new +and +.Fn BASIC_CONSTRAINTS_free +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/BF_set_key.3 b/Libraries/libressl/man/BF_set_key.3 new file mode 100644 index 000000000..5f4c7a689 --- /dev/null +++ b/Libraries/libressl/man/BF_set_key.3 @@ -0,0 +1,269 @@ +.\" $OpenBSD: BF_set_key.3,v 1.12 2023/08/05 18:27:55 jmc Exp $ +.\" OpenSSL 99d63d46 Jul 19 09:27:53 2016 -0400 +.\" +.\" This file was written by Richard Levitte . +.\" Copyright (c) 2000, 2002, 2005, 2014, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 5 2023 $ +.Dt BF_SET_KEY 3 +.Os +.Sh NAME +.Nm BF_set_key , +.Nm BF_encrypt , +.Nm BF_decrypt , +.Nm BF_ecb_encrypt , +.Nm BF_cbc_encrypt , +.Nm BF_cfb64_encrypt , +.Nm BF_ofb64_encrypt +.Nd Blowfish encryption +.Sh SYNOPSIS +.In openssl/blowfish.h +.Ft void +.Fo BF_set_key +.Fa "BF_KEY *key" +.Fa "int len" +.Fa "const unsigned char *data" +.Fc +.Ft void +.Fo BF_encrypt +.Fa "BF_LONG *data" +.Fa "const BF_KEY *key" +.Fc +.Ft void +.Fo BF_decrypt +.Fa "BF_LONG *data" +.Fa "const BF_KEY *key" +.Fc +.Ft void +.Fo BF_ecb_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "BF_KEY *key" +.Fa "int enc" +.Fc +.Ft void +.Fo BF_cbc_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "BF_KEY *schedule" +.Fa "unsigned char *ivec" +.Fa "int enc" +.Fc +.Ft void +.Fo BF_cfb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "BF_KEY *schedule" +.Fa "unsigned char *ivec" +.Fa "int *num" +.Fa "int enc" +.Fc +.Ft void +.Fo BF_ofb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "BF_KEY *schedule" +.Fa "unsigned char *ivec" +.Fa "int *num" +.Fc +.Sh DESCRIPTION +This library implements the Blowfish cipher, +which was invented and defined by +.An Counterpane . +Note that applications should use higher level functions such as +.Xr EVP_EncryptInit 3 +instead of calling the Blowfish functions directly. +.Pp +Blowfish is a block cipher that operates on 64-bit (8 byte) blocks of data. +It uses a variable size key, but typically, 128-bit (16 byte) keys +are considered good for strong encryption. +Blowfish can be used in the same modes as DES +and is currently one of the faster block ciphers. +It is quite a bit faster than DES, and much faster than IDEA or RC2. +.Pp +Blowfish consists of a key setup phase +and the actual encryption or decryption phase. +.Pp +.Fn BF_set_key +sets up the +.Vt BF_KEY +.Fa key +using the +.Fa len +bytes long key at +.Fa data . +.Pp +.Fn BF_ecb_encrypt +is the basic Blowfish encryption and decryption function. +It encrypts or decrypts the first 64 bits of +.Fa in +using the key +.Fa key , +putting the result in +.Fa out . +.Fa enc +decides if encryption +.Pq Dv BF_ENCRYPT +or decryption +.Pq Dv BF_DECRYPT +shall be performed. +The vector pointed at by +.Fa in +and +.Fa out +must be 64 bits in length, no less. +If they are larger, everything after the first 64 bits is ignored. +.Pp +The mode functions +.Fn BF_cbc_encrypt , +.Fn BF_cfb64_encrypt , +and +.Fn BF_ofb64_encrypt +all operate on variable length data. +They all take an initialization vector +.Fa ivec +which needs to be passed along into the next call of the same function +for the same message. +.Fa ivec +may be initialized with anything, but the recipient needs to know what +it was initialized with, or it won't be able to decrypt. +Some programs and protocols simplify this, like SSH, where +.Fa ivec +is simply initialized to zero. +.Fn BF_cbc_encrypt +operates on data that is a multiple of 8 bytes long, while +.Fn BF_cfb64_encrypt +and +.Fn BF_ofb64_encrypt +are used to encrypt a variable number of bytes (the amount +does not have to be an exact multiple of 8). +The purpose of the latter two is to simulate stream ciphers and, +therefore, they need the parameter +.Fa num , +which is a pointer to an integer where the current offset in +.Fa ivec +is stored between calls. +This integer must be initialized to zero when +.Fa ivec +is initialized. +.Pp +.Fn BF_cbc_encrypt +is the Cipher Block Chaining function for Blowfish. +It encrypts or decrypts the 64-bit chunks of +.Fa in +using the key +.Fa schedule , +putting the result in +.Fa out . +.Fa enc +decides if encryption +.Pq Dv BF_ENCRYPT +or decryption +.Pq Dv BF_DECRYPT +shall be performed. +.Fa ivec +must point at an 8-byte long initialization vector. +.Pp +.Fn BF_cfb64_encrypt +is the CFB mode for Blowfish with 64-bit feedback. +It encrypts or decrypts the bytes in +.Fa in +using the key +.Fa schedule , +putting the result in +.Fa out . +.Fa enc +decides if encryption +.Pq Dv BF_ENCRYPT +or decryption +.Pq Dv BF_DECRYPT +shall be performed. +.Fa ivec +must point at an +8-byte long initialization vector. +.Fa num +must point at an integer which must be initially zero. +.Pp +.Fn BF_ofb64_encrypt +is the OFB mode for Blowfish with 64-bit feedback. +It uses the same parameters as +.Fn BF_cfb64_encrypt , +which must be initialized the same way. +.Pp +.Fn BF_encrypt +and +.Fn BF_decrypt +are the lowest level functions for Blowfish encryption. +They encrypt/decrypt the first 64 bits of the vector pointed by +.Fa data , +using the key +.Fa key . +These functions should not be used unless implementing `modes' of Blowfish. +The alternative is to use +.Fn BF_ecb_encrypt . +Be aware that these functions take each 32-bit chunk in host-byte order, +which is little-endian on little-endian platforms +and big-endian on big-endian ones. +.Sh SEE ALSO +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn BF_set_key , +.Fn BF_encrypt , +.Fn BF_ecb_encrypt , +.Fn BF_cbc_encrypt , +.Fn BF_cfb64_encrypt , +and +.Fn BF_ofb64_encrypt +first appeared in SSLeay 0.6.6. +.Fn BF_decrypt +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_accept.3 b/Libraries/libressl/man/BIO_accept.3 new file mode 100644 index 000000000..e2547ac0d --- /dev/null +++ b/Libraries/libressl/man/BIO_accept.3 @@ -0,0 +1,387 @@ +.\" $OpenBSD: BIO_accept.3,v 1.2 2023/04/30 13:38:48 schwarze Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt BIO_ACCEPT 3 +.Os +.Sh NAME +.\" mentioned in OpenSSL documentation and still used internally in LibreSSL +.Nm BIO_get_host_ip , +.Nm BIO_get_port , +.Nm BIO_get_accept_socket , +.Nm BIO_accept , +.Nm BIO_sock_error , +.Nm BIO_sock_non_fatal_error , +.Nm BIO_sock_should_retry , +.\" used internally in LibreSSL and OpenSSL and not deprecated in OpenSSL +.Nm BIO_socket_nbio , +.\" mentioned in OpenSSL documentation and not deprecated in OpenSSL +.Nm BIO_set_tcp_ndelay +.\" deprecated in OpenSSL and unused anywhere, hence intentionally undocumented +.\" .Nm BIO_gethostbyname +.\" .Nm BIO_GHBN_CTRL_CACHE_SIZE +.\" .Nm BIO_GHBN_CTRL_FLUSH +.\" .Nm BIO_GHBN_CTRL_GET_ENTRY +.\" .Nm BIO_GHBN_CTRL_HITS +.\" .Nm BIO_GHBN_CTRL_MISSES +.\" .Nm BIO_socket_ioctl +.\" does almost nothing and used very rarely, hence intentionally undocumented +.\" .Nm BIO_sock_init +.\" .Nm BIO_sock_cleanup +.Nd wrappers for socket operations +.Sh SYNOPSIS +.In openssl/bio.h +.Ft int +.Fo BIO_get_host_ip +.Fa "const char *hostname" +.Fa "unsigned char *in_addr_buffer" +.Fc +.Ft int +.Fo BIO_get_port +.Fa "const char *servname" +.Fa "unsigned short *port" +.Fc +.Ft int +.Fo BIO_get_accept_socket +.Fa "char *host_port" +.Fa "int bind_mode" +.Fc +.Ft int +.Fo BIO_accept +.Fa "int socket" +.Fa "char **addr" +.Fc +.Ft int +.Fn BIO_sock_error "int socket" +.Ft int +.Fn BIO_sock_non_fatal_error "int errnum" +.Ft int +.Fn BIO_sock_should_retry "int retval" +.Ft int +.Fn BIO_socket_nbio "int socket" "int mode" +.Ft int +.Fn BIO_set_tcp_ndelay "int socket" "int on" +.Sh DESCRIPTION +.Fn BIO_get_host_ip +looks up one IPv4 address for the given +.Fa hostname +using +.Xr getaddrinfo 3 +and writes the first returned IPv4 address into +.Pf * Fa in_addr_buffer . +The caller is responsible for providing a buffer that is at least +.Fn sizeof in_addr_t +bytes long. +After a successful call, the caller needs to cast +.Fa in_addr_buffer +to +.Pq Vt in_addr_t * . +.Pp +.Fn BIO_get_port +looks up +.Fa servname +in the +.Xr services 5 +database using +.Xr getaddrinfo 3 +and stores the associated port number at the location specified by the +.Fa port +argument. +.Pp +.Fn BIO_get_accept_socket +creates an IPv4 TCP socket and +.Xr listen 2 Ns s +for incoming connections. +The string +.Fa host_port +is parsed. +If it contains a colon, the substring before the colon is interpreted +as a local hostname of the interface to +.Xr bind 2 +to. +If the hostname is empty, consists of a single asterisk +.Pq Qq *:... , +or if there is no colon, +.Dv INADDR_ANY +is used instead of a local hostname. +The rest of the string +.Fa host_port , +or the whole string if it contains no colon, +is treated as a service name. +The hostname and the service name are converted to a local IP address +and port number using +.Xr getaddrinfo 3 . +If +.Fa bind_mode +is the constant +.Dv BIO_BIND_REUSEADDR , +allowing local address reuse is attempted using +.Xr setsockopt 2 +with an argument of +.Dv SO_REUSEADDR +before calling +.Xr bind 2 . +.Pp +.Fn BIO_accept +calls +.Xr accept 2 +to receive one connection on the +.Fa socket . +When it receives a connection, it +.Xr free 3 Ns s +.Pf * Fa addr , +and if it is an IPv4 connection, it allocates a new string, +writes the peer IP address in dotted decimal form, a colon, +and the decimal port number into the string, and stores a pointer +to the string in +.Pf * Fa addr . +For other address families or if +.Xr getnameinfo 3 +or memory allocation fails, +.Pf * Fa addr +is set to +.Dv NULL +but +.Fn BIO_accept +succeeds anyway. +.Pp +.Fn BIO_sock_error +retrieves, clears, and returns the error status code of the +.Fa socket +by calling +.Xr getsockopt 2 +with arguments +.Dv SOL_SOCKET +and +.Dv SO_ERROR . +.Pp +.Fn BIO_sock_non_fatal_error +determines whether the error status code +.Fa errnum +represents a recoverable error. +.Pp +.Fn BIO_sock_should_retry +determines whether a recoverable error occurred by inspecting both +.Xr errno 2 +and +.Fa retval , +which is supposed to usually be +the return value of a previously called function like +.Fn BIO_accept , +.Xr BIO_read 3 , +or +.Xr BIO_write 3 . +.Pp +If +.Fa mode +is non-zero, +.Fn BIO_socket_nbio +switches the +.Fa socket +to non-blocking mode using +.Xr fcntl 2 . +If +.Fa mode +is 0, it switches to blocking mode. +.Pp +.Fn BIO_set_tcp_ndelay +sets the +.Dv TCP_NODELAY +option on the +.Fa socket +if +.Fa on +is 1 or clears it if +.Fa on +is 0; see +.Xr tcp 4 +for details. +.Sh RETURN VALUES +.Fn BIO_get_host_ip , +.Fn BIO_get_port , +and +.Fn BIO_socket_nbio +return 1 on success or 0 on failure. +.Pp +.Fn BIO_get_accept_socket +returns the file descriptor of the newly created listening socket or \-1 if +.Fa host_port +is +.Dv NULL , +no service is specified, or +.Xr getaddrinfo 3 , +.Xr socket 2 , +.Xr bind 2 , +.Xr listen 2 , +or memory allocation fails. +.Pp +.Fn BIO_accept +returns the file descriptor of the received connection, +\-1 on fatal errors, that is, when +.Fa addr +is +.Dv NULL +or +.Xr accept 2 +fails fatally, or \-2 when +.Xr accept 2 +fails in a non-fatal way and might succeed when retried later. +.Pp +.Fn BIO_sock_error +returns an error status code like +.Dv EAGAIN , +.Dv ECONNABORTED , +.Dv ECONNREFUSED , +.Dv ECONNRESET , +.Dv ELOOP , +.Dv EMSGSIZE , +.Dv ENOBUFS , +.Dv ENOTCONN , +.Dv EPIPE , +.Dv ETIMEDOUT , +or others, 0 if the +.Fa socket +is not in an error state, or 1 if +.Xr getsockopt 2 +fails. +.Pp +.Fn BIO_sock_non_fatal_error +returns 1 if +.Fa errnum +is +.Dv EAGAIN , +.Dv EALREADY , +.Dv EINPROGRESS , +.Dv EINTR , +or +.Dv ENOTCONN +and 0 otherwise, even if +.Fa errnum +is 0. +.Pp +.Fn BIO_sock_should_retry +returns 1 if +.Fn BIO_sock_non_fatal_error errno +is 1 and +.Fa retval +is either 0 or \-1, or 0 otherwise. +.Pp +.Fn BIO_set_tcp_ndelay +returns 0 on success or \-1 on failure. +.Sh ERRORS +If +.Fn BIO_get_host_ip , +.Fn BIO_get_port , +or +.Fn BIO_get_accept_socket +fail or +.Fn BIO_accept +fails fatally, the following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv BIO_R_ACCEPT_ERROR Qq "accept error" +.Xr accept 2 +failed fatally in +.Fn BIO_accept . +.It Dv BIO_R_BAD_HOSTNAME_LOOKUP Qq "bad hostname lookup" +.Xr getaddrinfo 3 +failed or +.Fa hostname +was +.Dv NULL +in +.Fn BIO_get_host_ip , +or +.Xr getaddrinfo 3 +failed in +.Fn BIO_get_accept_socket . +.It Dv BIO_R_INVALID_ARGUMENT Qq "invalid argument" +.Xr getaddrinfo 3 +failed in +.Fn BIO_get_port . +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +Memory allocation failed in +.Fn BIO_get_accept_socket , +or +.Fn BIO_accept +.Em succeeded +but was unable to allocate memory for +.Pf * Fa addr . +For +.Fn BIO_accept , +the returned file descriptor is valid, +and communication with the peer can be attempted using it. +.It Dv BIO_R_NO_PORT_SPECIFIED Qq "no port specified" +The +.Fa servname +argument was +.Dv NULL +in +.Fn BIO_get_port , +or +.Fa host_port +was +.Dv NULL +or ended after the first colon in +.Fn BIO_get_accept_socket . +.It Dv BIO_R_NULL_PARAMETER Qq "null parameter" +The +.Fa addr +argument was +.Dv NULL +in +.Fn BIO_accept . +.It Dv BIO_R_UNABLE_TO_BIND_SOCKET Qq "unable to bind socket" +.Xr bind 2 +failed in +.Fn BIO_get_accept_socket . +.It Dv BIO_R_UNABLE_TO_CREATE_SOCKET Qq "unable to create socket" +.Xr socket 2 +failed in +.Fn BIO_get_accept_socket . +.It Dv BIO_R_UNABLE_TO_LISTEN_SOCKET Qq "unable to listen socket" +.Xr listen 2 +failed in +.Fn BIO_get_accept_socket . +.El +.Sh SEE ALSO +.Xr bind 2 , +.Xr connect 2 , +.Xr errno 2 , +.Xr fcntl 2 , +.Xr getsockopt 2 , +.Xr listen 2 , +.Xr sigaction 2 , +.Xr socket 2 , +.Xr BIO_new 3 , +.Xr BIO_read 3 , +.Xr getaddrinfo 3 , +.Xr ip 4 , +.Xr tcp 4 +.Sh HISTORY +.Fn BIO_sock_should_retry +first appeared in SSLeay 0.6.5 and the other functions except +.Fn BIO_socket_nbio +in SSLeay 0.8.0. +They have all been available since +.Ox 2.4 . +.Pp +.Fn BIO_socket_nbio +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/BIO_ctrl.3 b/Libraries/libressl/man/BIO_ctrl.3 new file mode 100644 index 000000000..d4515ea9a --- /dev/null +++ b/Libraries/libressl/man/BIO_ctrl.3 @@ -0,0 +1,642 @@ +.\" $OpenBSD: BIO_ctrl.3,v 1.24 2023/07/26 20:01:04 tb Exp $ +.\" full merge up to: OpenSSL 24a535eaf Tue Sep 22 13:14:20 2020 +0100 +.\" selective merge up to: OpenSSL 0c5bc96f Tue Mar 15 13:57:22 2022 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt BIO_CTRL 3 +.Os +.Sh NAME +.Nm BIO_ctrl , +.Nm BIO_callback_ctrl , +.Nm BIO_ptr_ctrl , +.Nm BIO_int_ctrl , +.Nm BIO_reset , +.Nm BIO_seek , +.Nm BIO_tell , +.Nm BIO_flush , +.Nm BIO_eof , +.Nm BIO_set_close , +.Nm BIO_get_close , +.Nm BIO_pending , +.Nm BIO_wpending , +.Nm BIO_ctrl_pending , +.Nm BIO_ctrl_wpending , +.Nm BIO_get_info_callback , +.Nm BIO_set_info_callback , +.Nm BIO_info_cb , +.Nm bio_info_cb +.Nd BIO control operations +.Sh SYNOPSIS +.In openssl/bio.h +.Ft long +.Fo BIO_ctrl +.Fa "BIO *b" +.Fa "int cmd" +.Fa "long larg" +.Fa "void *parg" +.Fc +.Ft long +.Fo BIO_callback_ctrl +.Fa "BIO *b" +.Fa "int cmd" +.Fa "BIO_info_cb *cb" +.Fc +.Ft char * +.Fo BIO_ptr_ctrl +.Fa "BIO *b" +.Fa "int cmd" +.Fa "long larg" +.Fc +.Ft long +.Fo BIO_int_ctrl +.Fa "BIO *b" +.Fa "int cmd" +.Fa "long larg" +.Fa "int iarg" +.Fc +.Ft int +.Fo BIO_reset +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_seek +.Fa "BIO *b" +.Fa "int ofs" +.Fc +.Ft int +.Fo BIO_tell +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_flush +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_eof +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_set_close +.Fa "BIO *b" +.Fa "long flag" +.Fc +.Ft int +.Fo BIO_get_close +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_pending +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_wpending +.Fa "BIO *b" +.Fc +.Ft size_t +.Fo BIO_ctrl_pending +.Fa "BIO *b" +.Fc +.Ft size_t +.Fo BIO_ctrl_wpending +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_get_info_callback +.Fa "BIO *b" +.Fa "BIO_info_cb **cbp" +.Fc +.Ft int +.Fo BIO_set_info_callback +.Fa "BIO *b" +.Fa "BIO_info_cb *cb" +.Fc +.Ft typedef int +.Fo BIO_info_cb +.Fa "BIO *b" +.Fa "int state" +.Fa "int res" +.Fc +.Ft typedef int +.Fo bio_info_cb +.Fa "BIO *b" +.Fa "int state" +.Fa "int res" +.Fc +.Sh DESCRIPTION +.Fn BIO_ctrl , +.Fn BIO_callback_ctrl , +.Fn BIO_ptr_ctrl , +and +.Fn BIO_int_ctrl +are BIO "control" operations taking arguments of various types. +These functions are not normally called directly - +various macros are used instead. +The standard macros are described below. +Macros specific to a particular type of BIO +are described in the specific BIO's manual page +as well as any special features of the standard calls. +.Pp +Depending on the +.Fa cmd +and on the type of +.Fa b , +.Fn BIO_ctrl +may have a read-only effect on +.Fa b +or change data in +.Fa b +or in its sub-structures. +It may also have a side effect of changing the memory pointed to by +.Fa parg . +.Pp +.Fn BIO_callback_ctrl +does not call +.Fn BIO_ctrl +but instead requires that the BIO type of +.Fa b +provides a dedicated +.Fa callback_ctrl +function pointer, which is built into the library for some standard BIO +types and can be provided with +.Xr BIO_meth_set_callback_ctrl 3 +for application-defined BIO types. +The only +.Fa cmd +supported by +.Fn BIO_callback_ctrl +is +.Dv BIO_CTRL_SET_CALLBACK . +.Pp +.Fn BIO_ptr_ctrl +calls +.Fn BIO_ctrl +with +.Fa parg +pointing to the location of a temporary pointer variable initialized to +.Dv NULL . +.Pp +.Fn BIO_int_ctrl +calls +.Fn BIO_ctrl +with +.Fa parg +pointing to the location of a temporary +.Vt int +variable initialized to +.Fa iarg . +If +.Fn BIO_ctrl +changes the value stored at +.Pf * Fa parg , +the new value is ignored. +.Pp +.Fn BIO_reset +typically resets a BIO to some initial state. +In the case of file related BIOs, for example, +it rewinds the file pointer to the start of the file. +.Pp +.Fn BIO_seek +resets a file related BIO's (that is file descriptor and +FILE BIOs) file position pointer to +.Fa ofs +bytes from start of file. +.Pp +.Fn BIO_tell +returns the current file position of a file related BIO. +.Pp +.Fn BIO_flush +normally writes out any internally buffered data. +In some cases it is used to signal EOF and that no more data will be written. +.Pp +.Fn BIO_eof +returns 1 if the BIO has read EOF. +The precise meaning of "EOF" varies according to the BIO type. +.Pp +.Fn BIO_set_close +sets the BIO +.Fa b +close flag to +.Fa flag . +.Fa flag +can take the value +.Dv BIO_CLOSE +or +.Dv BIO_NOCLOSE . +Typically +.Dv BIO_CLOSE +is used in a source/sink BIO to indicate that the underlying I/O stream +should be closed when the BIO is freed. +.Pp +.Fn BIO_get_close +returns the BIO's close flag. +.Pp +.Fn BIO_pending , +.Fn BIO_ctrl_pending , +.Fn BIO_wpending , +and +.Fn BIO_ctrl_wpending +return the number of pending characters in the BIO's read and write buffers. +Not all BIOs support these calls. +.Fn BIO_ctrl_pending +and +.Fn BIO_ctrl_wpending +return a +.Vt size_t +type and are functions. +.Fn BIO_pending +and +.Fn BIO_wpending +are macros which call +.Fn BIO_ctrl . +.Pp +.Fn BIO_set_info_callback +installs the function pointer +.Fa cb +as an info callback in +.Fa b +by calling +.Fn BIO_callback_ctrl +with a command of +.Dv BIO_CTRL_SET_CALLBACK . +Among the BIO types built into the library, only +.Xr BIO_s_connect 3 +and +.Xr BIO_f_ssl 3 +support this functionality. +Some filter BIO types forward this control call +to the next BIO in the chain instead of processing it themselves. +.Pp +.Fn BIO_get_info_callback +places the function pointer to the info callback into +.Pf * Fa cbp +if any was installed using +.Fn BIO_set_info_callback +or +.Fn BIO_callback_ctrl . +If the type of +.Fa b +supports setting an info callback but none was installed, it stores a +.Dv NULL +pointer in +.Pf * Fa cbp . +.Pp +The function type name +.Vt bio_info_cb +is a deprecated synonym for +.Vt BIO_info_cb +provided for backward compatibility with some existing application software. +.Pp +The following +.Fa cmd +constants correspond to macros: +.Bl -column BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT BIO_set_ssl_renegotiate_timeout(3) +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_DESTROY_BIO_PAIR Ta Xr BIO_destroy_bio_pair 3 +.It Dv BIO_C_DO_STATE_MACHINE Ta Xr BIO_do_handshake 3 +.It Dv BIO_C_FILE_SEEK Ta Fn BIO_seek +.It Dv BIO_C_FILE_TELL Ta Fn BIO_tell +.It Dv BIO_C_GET_ACCEPT Ta Xr BIO_get_accept_port 3 +.It Dv BIO_C_GET_BIND_MODE Ta Xr BIO_get_bind_mode 3 +.It Dv BIO_C_GET_BUF_MEM_PTR Ta Xr BIO_get_mem_ptr 3 +.It Dv BIO_C_GET_BUFF_NUM_LINES Ta Xr BIO_get_buffer_num_lines 3 +.It Dv BIO_C_GET_CIPHER_CTX Ta Xr BIO_get_cipher_ctx 3 +.It Dv BIO_C_GET_CIPHER_STATUS Ta Xr BIO_get_cipher_status 3 +.It Dv BIO_C_GET_FD Ta Xr BIO_get_fd 3 +.It Dv BIO_C_GET_FILE_PTR Ta Xr BIO_get_fp 3 +.It Dv BIO_C_GET_MD Ta Xr BIO_get_md 3 +.It Dv BIO_C_GET_MD_CTX Ta Xr BIO_get_md_ctx 3 +.It Dv BIO_C_GET_READ_REQUEST Ta Xr BIO_get_read_request 3 +.It Dv BIO_C_GET_SSL Ta Xr BIO_get_ssl 3 +.It Dv BIO_C_GET_SSL_NUM_RENEGOTIATES Ta Xr BIO_get_num_renegotiates 3 +.It Dv BIO_C_GET_WRITE_BUF_SIZE Ta Xr BIO_get_write_buf_size 3 +.It Dv BIO_C_GET_WRITE_GUARANTEE Ta Xr BIO_get_write_guarantee 3 +.It Dv BIO_C_MAKE_BIO_PAIR Ta Xr BIO_make_bio_pair 3 +.It Dv BIO_C_RESET_READ_REQUEST Ta Xr BIO_ctrl_reset_read_request 3 +.It Dv BIO_C_SET_BIND_MODE Ta Xr BIO_set_bind_mode 3 +.It Dv BIO_C_SET_BUF_MEM Ta Xr BIO_set_mem_buf 3 +.It Dv BIO_C_SET_BUF_MEM_EOF_RETURN Ta Xr BIO_set_mem_eof_return 3 +.It Dv BIO_C_SET_BUFF_READ_DATA Ta Xr BIO_set_buffer_read_data 3 +.It Dv BIO_C_SET_FD Ta Xr BIO_set_fd 3 +.It Dv BIO_C_SET_FILE_PTR Ta Xr BIO_set_fp 3 +.It Dv BIO_C_SET_MD Ta Xr BIO_set_md 3 +.It Dv BIO_C_SET_MD_CTX Ta Xr BIO_set_md_ctx 3 +.It Dv BIO_C_SET_NBIO Ta Xr BIO_set_nbio 3 +.It Dv BIO_C_SET_SSL Ta Xr BIO_set_ssl 3 +.It Dv BIO_C_SET_SSL_RENEGOTIATE_BYTES Ta Xr BIO_set_ssl_renegotiate_bytes 3 +.It Dv BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT Ta Xr BIO_set_ssl_renegotiate_timeout 3 +.It Dv BIO_C_SET_WRITE_BUF_SIZE Ta Xr BIO_set_write_buf_size 3 +.It Dv BIO_C_SHUTDOWN_WR Ta Xr BIO_shutdown_wr 3 +.It Dv BIO_C_SSL_MODE Ta Xr BIO_set_ssl_mode 3 +.It Dv BIO_CTRL_DGRAM_CONNECT Ta Xr BIO_ctrl_dgram_connect 3 +.It Dv BIO_CTRL_DGRAM_GET_PEER Ta Xr BIO_dgram_get_peer 3 +.It Dv BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP Ta Xr BIO_dgram_recv_timedout 3 +.It Dv BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP Ta Xr BIO_dgram_send_timedout 3 +.It Dv BIO_CTRL_DGRAM_SET_CONNECTED Ta Xr BIO_ctrl_set_connected 3 +.It Dv BIO_CTRL_DGRAM_SET_PEER Ta Xr BIO_dgram_set_peer 3 +.It Dv BIO_CTRL_DUP Ta Xr BIO_dup_state 3 +.It Dv BIO_CTRL_EOF Ta Fn BIO_eof +.It Dv BIO_CTRL_FLUSH Ta Fn BIO_flush +.It Dv BIO_CTRL_GET_CALLBACK Ta Fn BIO_get_info_callback +.It Dv BIO_CTRL_GET_CLOSE Ta Fn BIO_get_close +.It Dv BIO_CTRL_INFO Ta Xr BIO_get_mem_data 3 +.It Dv BIO_CTRL_PENDING Ta Fn BIO_pending +.It Dv BIO_CTRL_RESET Ta Fn BIO_reset +.It Dv BIO_CTRL_SET_CALLBACK Ta Fn BIO_set_info_callback +.It Dv BIO_CTRL_SET_CLOSE Ta Fn BIO_set_close +.It Dv BIO_CTRL_WPENDING Ta Fn BIO_wpending +.El +.Pp +A few +.Fa cmd +constants serve more than one macro each +and are documented in the following manual pages: +.Bl -column BIO_C_SET_BUFF_SIZE BIO_s_connect(3) -offset 3n +.It Fa cmd No constant Ta manual page +.It Dv BIO_C_GET_CONNECT Ta Xr BIO_s_connect 3 +.It Dv BIO_C_SET_ACCEPT Ta Xr BIO_s_accept 3 +.It Dv BIO_C_SET_BUFF_SIZE Ta Xr BIO_f_buffer 3 +.It Dv BIO_C_SET_CONNECT Ta Xr BIO_s_connect 3 +.It Dv BIO_C_SET_FILENAME Ta Xr BIO_s_file 3 +.El +.Pp +Some +.Fa cmd +constants are not associated with any macros. +They are documented in the following manual pages: +.Bl -column BIO_CTRL_DGRAM_SET_RECV_TIMEOUT BIO_dgram_recv_timedout(3)\ + -offset 3n +.It Fa cmd No constant Ta manual page +.\" The following constants are intentionally undocumented because +.\" BIO_f_asn1 has been removed from the public API. +.\" .It Dv BIO_C_GET_EX_ARG Ta Xr BIO_f_asn1 3 +.\" .It Dv BIO_C_SET_EX_ARG Ta Xr BIO_f_asn1 3 +.It Dv BIO_CTRL_DGRAM_GET_FALLBACK_MTU Ta Xr BIO_dgram_set_peer 3 +.It Dv BIO_CTRL_DGRAM_GET_MTU Ta Xr BIO_dgram_set_peer 3 +.It Dv BIO_CTRL_DGRAM_GET_RECV_TIMEOUT Ta Xr BIO_dgram_recv_timedout 3 +.It Dv BIO_CTRL_DGRAM_GET_SEND_TIMEOUT Ta Xr BIO_dgram_send_timedout 3 +.It Dv BIO_CTRL_DGRAM_SET_MTU Ta Xr BIO_dgram_set_peer 3 +.It Dv BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT Ta Xr BIO_dgram_recv_timedout 3 +.It Dv BIO_CTRL_DGRAM_SET_RECV_TIMEOUT Ta Xr BIO_dgram_recv_timedout 3 +.It Dv BIO_CTRL_DGRAM_SET_SEND_TIMEOUT Ta Xr BIO_dgram_send_timedout 3 +.It Dv BIO_CTRL_DGRAM_MTU_EXCEEDED Ta Xr BIO_s_datagram 3 +.It Dv BIO_CTRL_POP Ta Xr BIO_pop 3 +.It Dv BIO_CTRL_PUSH Ta Xr BIO_push 3 +.El +.Sh RETURN VALUES +The meaning of the return values of +.Fn BIO_ctrl , +.Fn BIO_callback_ctrl , +and +.Fn BIO_int_ctrl +depends on both the type of +.Fa b +and on the +.Fa cmd . +If +.Fa b +is a +.Dv NULL +pointer, no action occurs and 0 is returned. +The return value \-2 usually indicates a fatal error. +In particular, it is returned if the +.Fa cmd +is unsupported by the type of +.Fa b . +.Pp +.Fn BIO_callback_ctrl +and +.Fn BIO_set_info_callback +return 1 on success, 0 if +.Fa b +is +.Dv NULL +or to indicate failure of a valid +.Fa cmd , +or \-2 if the +.Fa cmd +is not supported by +.Fa b . +.Pp +.Fn BIO_ptr_ctrl +returns +.Dv NULL +if the +.Fn BIO_ctrl +call returns a negative value or does not change +.Pf * Fa parg , +or the pointer it puts into +.Pf * Fa parg +otherwise. +.Pp +.Fn BIO_int_ctrl +returns the return value of +.Fn BIO_ctrl . +.Pp +.Fn BIO_reset +normally returns 1 for success and 0 or -1 for failure. +File BIOs are an exception, returning 0 for success and -1 for failure. +.Pp +.Fn BIO_seek +and +.Fn BIO_tell +both return the current file position on success +and -1 for failure, except file BIOs which for +.Fn BIO_seek +always return 0 for success and -1 for failure. +.Pp +.Fn BIO_flush +returns 1 for success and 0 or -1 for failure. +.Pp +.Fn BIO_eof +returns 1 if EOF has been reached or 0 otherwise. +.Pp +.Fn BIO_set_close +always returns 1. +.Pp +.Fn BIO_get_close +returns the close flag value +.Dv BIO_CLOSE +or +.Dv BIO_NOCLOSE . +.Pp +.Fn BIO_pending , +.Fn BIO_ctrl_pending , +.Fn BIO_wpending , +and +.Fn BIO_ctrl_wpending +return the amount of pending data. +.Pp +.Fn BIO_get_info_callback +returns 1 on success, including when the type of +.Fa b +supports an info callback but none is installed, +0 if +.Fa b +is +.Dv NULL +or \-2 if the type of +.Fa b +does not support an info callback. +.Pp +If a callback was installed in +.Fa b +using +.Xr BIO_set_callback_ex 3 +or +.Xr BIO_set_callback 3 , +it can modify the return values of all these functions. +.Sh NOTES +Because it can write data, +.Fn BIO_flush +may return 0 or -1 indicating that the call should be retried later +in a similar manner to +.Xr BIO_write 3 . +The +.Xr BIO_should_retry 3 +call should be used and appropriate action taken if the call fails. +.Pp +The return values of +.Fn BIO_pending +and +.Fn BIO_wpending +may not reliably determine the amount of pending data in all cases. +For example in the case of a file BIO some data may be available in the +.Vt FILE +structure's internal buffers but it is not possible +to determine this in a portable way. +For other types of BIO they may not be supported. +.Pp +If they do not internally handle a particular +.Fn BIO_ctrl +operation, filter BIOs usually pass the operation +to the next BIO in the chain. +This often means there is no need to locate the required BIO for +a particular operation: it can be called on a chain and it will +be automatically passed to the relevant BIO. +However, this can cause unexpected results. +For example no current filter BIOs implement +.Fn BIO_seek , +but this may still succeed if the chain ends +in a FILE or file descriptor BIO. +.Pp +Source/sink BIOs return a 0 if they do not recognize the +.Fn BIO_ctrl +operation. +.Sh SEE ALSO +.Xr BIO_meth_new 3 , +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_ctrl , +.Fn BIO_reset , +.Fn BIO_flush , +.Fn BIO_eof , +.Fn BIO_set_close , +.Fn BIO_get_close , +and +.Fn BIO_pending +first appeared in SSLeay 0.6.0. +.Fn BIO_wpending +first appeared in SSLeay 0.8.1. +.Fn BIO_ptr_ctrl , +.Fn BIO_int_ctrl , +.Fn BIO_get_info_callback +and +.Fn BIO_set_info_callback +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_seek +and +.Fn BIO_tell +first appeared in SSLeay 0.9.1. +.Fn BIO_ctrl_pending +and +.Fn BIO_ctrl_wpending +first appeared in OpenSSL 0.9.4. +These functions have been available since +.Ox 2.6 . +.Pp +.Fn BIO_callback_ctrl +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn bio_info_cb +first appeared with a more complicated prototype in OpenSSL 0.9.6 +and has been available since +.Ox 2.9 . +.Pp +.Fn BIO_info_cb +first appeared in OpenSSL 1.1.0h and has been available since +.Ox 6.3 . +.Sh BUGS +Some of the return values are ambiguous and care should be taken. +In particular a return value of 0 can be returned if an operation +is not supported, if an error occurred, if EOF has not been reached +and in the case of +.Fn BIO_seek +on a file BIO for a successful operation. diff --git a/Libraries/libressl/man/BIO_dump.3 b/Libraries/libressl/man/BIO_dump.3 new file mode 100644 index 000000000..8817f0c4c --- /dev/null +++ b/Libraries/libressl/man/BIO_dump.3 @@ -0,0 +1,128 @@ +.\" $OpenBSD: BIO_dump.3,v 1.4 2022/12/20 15:34:03 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 20 2022 $ +.Dt BIO_DUMP 3 +.Os +.Sh NAME +.Nm BIO_dump , +.Nm BIO_dump_indent , +.Nm BIO_dump_fp , +.Nm BIO_dump_indent_fp +.\" intentionally undocumented because nothing uses these two functions: +.\" .Nm BIO_dump_cb +.\" .Nm BIO_dump_indent_cb +.Nd hexadecimal printout of arbitrary byte arrays +.Sh SYNOPSIS +.In openssl/bio.h +.Ft int +.Fo BIO_dump +.Fa "BIO *b" +.Fa "const char *s" +.Fa "int len" +.Fc +.Ft int +.Fo BIO_dump_indent +.Fa "BIO *b" +.Fa "const char *s" +.Fa "int len" +.Fa "int indent" +.Fc +.Ft int +.Fo BIO_dump_fp +.Fa "FILE *fp" +.Fa "const char *s" +.Fa "int len" +.Fc +.Ft int +.Fo BIO_dump_indent_fp +.Fa "FILE *fp" +.Fa "const char *s" +.Fa "int len" +.Fa "int indent" +.Fc +.Sh DESCRIPTION +.Fn BIO_dump +prints +.Fa len +bytes starting at +.Fa s +to +.Fa bio +in hexadecimal format. +.Pp +The first column of output contains the index, in the byte array starting at +.Fa s , +of the first byte shown on the respective output line, expressed as a +four-digit hexadecimal number starting at 0000, followed by a dash. +After the dash, sixteen bytes of data are printed as two-digit +hexadecimal numbers, respecting the order in which they appear in +the array +.Fa s . +Another dash is printed after the eighth column. +.Pp +To the right of the hexadecimal representation of the bytes, +the same bytes are printed again, this time as ASCII characters. +Non-printable ASCII characters are replaced with dots. +.Pp +Trailing space characters and NUL bytes are omitted from the main table. +If there are any, an additional line is printed, consisting of the +.Fa len +argument as a four-digit hexadecimal number, a dash, and the fixed string +.Qq . +.Pp +.Fn BIO_dump_indent +is similar except that +.Fa indent +space characters are prepended to each output line. +If +.Fa indent +is 7 or more, the number of data columns is reduced such that the +total width of the output does not exceed 79 characters per line. +.Pp +.Fn BIO_dump_fp +and +.Fn BIO_dump_indent_fp +are similar except that +.Xr fwrite 3 +is used instead of +.Xr BIO_write 3 . +.Sh RETURN VALUES +On success these functions return the total number of bytes written by +.Xr BIO_write 3 +or +.Xr fwrite 3 . +If a failure occurs at any point when writing, these +functions will stop after having potentially written out partial results, +and return -1. +.Sh SEE ALSO +.Xr hexdump 1 , +.Xr BIO_new 3 , +.Xr BIO_write 3 +.Sh HISTORY +.Fn BIO_dump +first appeared in SSLeay 0.6.5 and has been available since +.Ox 2.4 . +.Pp +.Fn BIO_dump_indent +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn BIO_dump_fp +and +.Fn BIO_dump_indent_fp +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/BIO_dup_chain.3 b/Libraries/libressl/man/BIO_dup_chain.3 new file mode 100644 index 000000000..5c5e8c653 --- /dev/null +++ b/Libraries/libressl/man/BIO_dup_chain.3 @@ -0,0 +1,141 @@ +.\" $OpenBSD: BIO_dup_chain.3,v 1.2 2023/04/09 06:27:52 jsg Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 9 2023 $ +.Dt BIO_DUP_CHAIN 3 +.Os +.Sh NAME +.Nm BIO_dup_chain , +.Nm BIO_dup_state +.Nd copy a BIO chain +.Sh SYNOPSIS +.In openssl/bio.h +.Ft BIO * +.Fn BIO_dup_chain "BIO *b" +.Ft long +.Fn BIO_dup_state "BIO *b" "BIO *new_bio" +.Sh DESCRIPTION +.Fn BIO_dup_chain +copies the chain starting at +.Fa b +by iteratively copying +.Fa b +and all the BIOs following it +and joining the copies in the same order as in the original chain. +The copying operation is neither a deep copy nor a shallow copy. +.Pp +Some parts of the state of each BIO are copied, +in particular with respect to the values returned by +.Xr BIO_get_init 3 , +.Xr BIO_test_flags 3 , +and +.Xr BIO_get_shutdown 3 . +.\" XXX new_bio->num = bio->num; +Other parts of the state of the BIOs are not copied +but instead initialized to 0, +in particular with respect to the values returned by +.Xr BIO_number_read 3 , +.Xr BIO_number_written 3 , +and +.Xr BIO_get_retry_reason 3 . +The custom data pointer that can be used by custom BIO types +and that can be retrieved with +.Xr BIO_get_data 3 +is set to +.Dv NULL +in the copied BIO objects rather than copied. +The reference count of each BIO in the copied chain is set to 1. +.Pp +For each BIO in the chain, copying the data that was set with +.Xr BIO_set_ex_data 3 +is attempted, which may involve calling application-defined +callback functions. +.Pp +The following pointers are copied +rather than creating deep copies of the objects pointed to: +.Bl -bullet +.It +The +.Fa type +pointer used for creating each BIO with +.Xr BIO_new 3 , +implying that functions like +.Xr BIO_method_name 3 +return pointers to the same strings for the BIOs in the copied chain, +and that these strings are not copied. +.It +All function pointers, in particular those installed with +.Xr BIO_set_callback_ex 3 +and +.Xr BIO_get_callback_ex 3 . +.It +The pointer installed with +.Xr BIO_set_callback_arg 3 , +which implies that for BIOs using +.Xr BIO_debug_callback 3 , +those in the copied chain use the same BIOs for debugging output +as the corresponding ones in the original chain, +and none of the debugging output BIOs are copied. +.El +.Pp +.Fn BIO_dup_state +is a macro that calls +.Xr BIO_ctrl 3 +with a +.Fa cmd +argument of +.Dv BIO_CTRL_DUP . +It is automatically called for each BIO during +.Fn BIO_dup_chain +after the copied BIO is initialized and data copied into it, +but before the data set with +.Xr BIO_set_ex_data 3 +is copied into the new BIO and before it is linked into the new chain. +.Pp +This control operation may modify the operation of +.Fn BIO_dup_chain +for particular types of BIOs contained in the chain, +for example initializing or copying additional data. +For BIO types provided by the library, such additional effects +are documented in the respective manual pages, in particular in +.Xr BIO_f_buffer 3 , +.Xr BIO_f_cipher 3 , +.Xr BIO_f_md 3 , +.Xr BIO_f_ssl 3 , +.Xr BIO_s_bio 3 , +and +.Xr BIO_s_connect 3 . +.Sh RETURN VALUES +.Fn BIO_dup_chain +returns a pointer to the newly allocated copy of the BIO +.Fa b +on success or +.Dv NULL +on failure . +.Pp +.Fn BIO_dup_state +returns 1 on success or a value less than or equal to zero on failure. +.Sh SEE ALSO +.Xr BIO_get_data 3 , +.Xr BIO_new 3 , +.Xr BIO_next 3 , +.Xr BIO_push 3 +.Sh HISTORY +.Fn BIO_dup_chain +and +.Fn BIO_dup_state +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_f_base64.3 b/Libraries/libressl/man/BIO_f_base64.3 new file mode 100644 index 000000000..e4589de03 --- /dev/null +++ b/Libraries/libressl/man/BIO_f_base64.3 @@ -0,0 +1,148 @@ +.\" $OpenBSD: BIO_f_base64.3,v 1.15 2023/09/11 04:00:40 jsg Exp $ +.\" OpenSSL fc1d88f0 Wed Jul 2 22:42:40 2014 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2003, 2005, 2014 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 11 2023 $ +.Dt BIO_F_BASE64 3 +.Os +.Sh NAME +.Nm BIO_f_base64 +.\" .Nm EVP_ENCODE_LENGTH and +.\" .Nm EVP_DECODE_LENGTH are intentionally undocumented +.\" because they are internal implementation details of BIO_f_base64(3) +.\" and practically unused outside evp/bio_b64.c. +.Nd base64 BIO filter +.Sh SYNOPSIS +.In openssl/bio.h +.In openssl/evp.h +.Ft const BIO_METHOD * +.Fo BIO_f_base64 +.Fa void +.Fc +.Sh DESCRIPTION +.Fn BIO_f_base64 +returns the base64 BIO method. +This is a filter BIO that base64 encodes any data written through it +and decodes any data read through it. +.Pp +Base64 BIOs do not support +.Xr BIO_gets 3 +or +.Xr BIO_puts 3 . +.Pp +.Xr BIO_flush 3 +on a base64 BIO that is being written through +is used to signal that no more data is to be encoded: +this is used to flush the final block through the BIO. +.Pp +To encode the data all on one line and to expect the data to be all +on one line, initialize the base64 BIO as follows: +.Bd -literal -offset indent +BIO *b64 = BIO_new(BIO_f_base64()); +BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); +.Ed +.Sh RETURN VALUES +.Fn BIO_f_base64 +returns the base64 BIO method. +.Pp +When called on a base64 BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_BASE64 +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq base64 encoding . +.Sh EXAMPLES +Base64 encode the string "hello, world\en" +and write the result to standard output: +.Bd -literal -offset indent +BIO *bio, *b64; +char message[] = "hello, world\en"; + +b64 = BIO_new(BIO_f_base64()); +bio = BIO_new_fp(stdout, BIO_NOCLOSE); +BIO_push(b64, bio); +BIO_write(b64, message, strlen(message)); +BIO_flush(b64); + +BIO_free_all(b64); +.Ed +.Pp +Read Base64-encoded data from standard input +and write the decoded data to standard output: +.Bd -literal -offset indent +BIO *bio, *b64, *bio_out; +char inbuf[512]; +int inlen; + +b64 = BIO_new(BIO_f_base64()); +bio = BIO_new_fp(stdin, BIO_NOCLOSE); +bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); +BIO_push(b64, bio); +while((inlen = BIO_read(b64, inbuf, 512)) > 0) + BIO_write(bio_out, inbuf, inlen); + +BIO_flush(bio_out); +BIO_free_all(b64); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr EVP_EncodeInit 3 +.Sh HISTORY +.Fn BIO_f_base64 +first appeared in SSLeay 0.6.5 and has been available since +.Ox 2.4 . +.Sh BUGS +The ambiguity of EOF in base64-encoded data can cause additional +data following the base64-encoded block to be misinterpreted. +.Pp +There should be some way of specifying a test that the BIO can perform +to reliably determine EOF (for example a MIME boundary). diff --git a/Libraries/libressl/man/BIO_f_buffer.3 b/Libraries/libressl/man/BIO_f_buffer.3 new file mode 100644 index 000000000..a3012c5c5 --- /dev/null +++ b/Libraries/libressl/man/BIO_f_buffer.3 @@ -0,0 +1,262 @@ +.\" $OpenBSD: BIO_f_buffer.3,v 1.17 2023/04/29 12:22:08 schwarze Exp $ +.\" full merge up to OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2010, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2023 $ +.Dt BIO_F_BUFFER 3 +.Os +.Sh NAME +.Nm BIO_f_buffer , +.Nm BIO_get_buffer_num_lines , +.Nm BIO_set_read_buffer_size , +.Nm BIO_set_write_buffer_size , +.Nm BIO_set_buffer_size , +.Nm BIO_set_buffer_read_data +.\" .Nm BIO_buffer_get_num_lines and +.\" .Nm BIO_CTRL_GET are intentionally undocumented. +.\" Contrary to what bio.h says, they do not *not* get some "IO type", +.\" whatever that is supposed to be, but are NOOPs, and nothing uses them. +.Nd buffering BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_f_buffer +.Fa void +.Fc +.Ft long +.Fo BIO_get_buffer_num_lines +.Fa "BIO *b" +.Fc +.Ft long +.Fo BIO_set_read_buffer_size +.Fa "BIO *b" +.Fa "long size" +.Fc +.Ft long +.Fo BIO_set_write_buffer_size +.Fa "BIO *b" +.Fa "long size" +.Fc +.Ft long +.Fo BIO_set_buffer_size +.Fa "BIO *b" +.Fa "long size" +.Fc +.Ft long +.Fo BIO_set_buffer_read_data +.Fa "BIO *b" +.Fa "void *buf" +.Fa "long num" +.Fc +.Sh DESCRIPTION +.Fn BIO_f_buffer +returns the buffering BIO method. +.Pp +Data written to a buffering BIO is buffered and periodically written +to the next BIO in the chain. +Data read from a buffering BIO comes from an internal buffer +which is filled from the next BIO in the chain. +Both +.Xr BIO_gets 3 +and +.Xr BIO_puts 3 +are supported. +.Pp +Calling +.Xr BIO_reset 3 +on a buffering BIO clears any buffered data. +.Pp +.Fn BIO_get_buffer_num_lines +returns the number of lines currently buffered. +.Pp +.Fn BIO_set_read_buffer_size , +.Fn BIO_set_write_buffer_size , +and +.Fn BIO_set_buffer_size +set the read, write or both read and write buffer sizes to +.Fa size . +The initial buffer size is +.Dv DEFAULT_BUFFER_SIZE , +currently 4096. +Any attempt to reduce the buffer size below +.Dv DEFAULT_BUFFER_SIZE +is ignored. +Any buffered data is cleared when the buffer is resized. +.Pp +.Fn BIO_set_buffer_read_data +clears the read buffer and fills it with +.Fa num +bytes of +.Fa buf . +If +.Fa num +is larger than the current buffer size, the buffer is expanded. +.Pp +Buffering BIOs implement +.Xr BIO_gets 3 +by using +.Xr BIO_read 3 +operations on the next BIO in the chain. +By prepending a buffering BIO to a chain +it is therefore possible to provide the functionality of +.Xr BIO_gets 3 +if the following BIOs do not support it (for example SSL BIOs). +.Pp +Data is only written to the next BIO in the chain +when the write buffer fills or when +.Xr BIO_flush 3 +is called. +It is therefore important to call +.Xr BIO_flush 3 +whenever any pending data should be written +such as when removing a buffering BIO using +.Xr BIO_pop 3 . +.Xr BIO_flush 3 +may need to be retried if the ultimate source/sink BIO is non-blocking. +.Pp +When a chain containing a buffering BIO is copied with +.Xr BIO_dup_chain 3 , +.Fn BIO_set_read_buffer_size +and +.Fn BIO_set_write_buffer_size +are called internally to automatically copy both buffer sizes from the +original BIO object to the new one. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +arguments correspond to macros as follows: +.Bl -column BIO_C_GET_BUFF_NUM_LINES BIO_get_buffer_num_lines() -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_GET_BUFF_NUM_LINES Ta Fn BIO_get_buffer_num_lines +.It Dv BIO_C_SET_BUFF_READ_DATA Ta Fn BIO_set_buffer_read_data +.It Dv BIO_C_SET_BUFF_SIZE Ta Fn BIO_set_buffer_size +.It Dv BIO_CTRL_FLUSH Ta Xr BIO_flush 3 +.It Dv BIO_CTRL_PENDING Ta Xr BIO_pending 3 +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_WPENDING Ta Xr BIO_wpending 3 +.El +.Pp +The +.Fa cmd +constant +.Dv BIO_C_SET_BUFF_SIZE +is special. +It is also used for +.Xr BIO_int_ctrl 3 +with the following +.Fa iarg +arguments: +.Bl -column BIO_C_SET_BUFF_SIZE iarg BIO_set_write_buffer_size() -offset 3n +.It Fa cmd No constant Ta Fa iarg Ta corresponding macro +.It Dv BIO_C_SET_BUFF_SIZE Ta 0 Ta Fn BIO_set_read_buffer_size +.It Ta 1 Ta Fn BIO_set_write_buffer_size +.El +.Sh RETURN VALUES +.Fn BIO_f_buffer +returns the buffering BIO method. +.Pp +When called on a buffering BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_BUFFER +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq buffer . +.Pp +.Fn BIO_get_buffer_num_lines +returns the number of lines buffered (may be 0). +.Pp +.Fn BIO_set_read_buffer_size , +.Fn BIO_set_write_buffer_size , +and +.Fn BIO_set_buffer_size +return 1 if the buffer was successfully resized or 0 for failure. +.Pp +.Fn BIO_set_buffer_read_data +returns 1 if the data was set correctly or 0 if there was an error. +.Sh SEE ALSO +.Xr BIO_ctrl 3 , +.Xr BIO_flush 3 , +.Xr BIO_new 3 , +.Xr BIO_pop 3 , +.Xr BIO_reset 3 +.Sh HISTORY +.Fn BIO_f_buffer +first appeared in SSLeay 0.6.0. +.Fn BIO_get_buffer_num_lines +and +.Fn BIO_set_buffer_size +first appeared in SSLeay 0.6.5. +.Fn BIO_set_read_buffer_size +and +.Fn BIO_set_write_buffer_size +first appeared in SSLeay 0.8.0. +.Fn BIO_set_buffer_read_data +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_f_cipher.3 b/Libraries/libressl/man/BIO_f_cipher.3 new file mode 100644 index 000000000..c5d00c698 --- /dev/null +++ b/Libraries/libressl/man/BIO_f_cipher.3 @@ -0,0 +1,209 @@ +.\" $OpenBSD: BIO_f_cipher.3,v 1.16 2023/04/29 12:01:53 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2003, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2023 $ +.Dt BIO_F_CIPHER 3 +.Os +.Sh NAME +.Nm BIO_f_cipher , +.Nm BIO_set_cipher , +.Nm BIO_get_cipher_status , +.Nm BIO_get_cipher_ctx +.\" .Nm BIO_CTRL_SET is intentionally undocumented because it has no effect. +.Nd cipher BIO filter +.Sh SYNOPSIS +.In openssl/bio.h +.In openssl/evp.h +.Ft const BIO_METHOD * +.Fo BIO_f_cipher +.Fa void +.Fc +.Ft int +.Fo BIO_set_cipher +.Fa "BIO *b" +.Fa "const EVP_CIPHER *cipher" +.Fa "unsigned char *key" +.Fa "unsigned char *iv" +.Fa "int enc" +.Fc +.Ft long +.Fo BIO_get_cipher_status +.Fa "BIO *b" +.Fc +.Ft long +.Fo BIO_get_cipher_ctx +.Fa "BIO *b" +.Fa "EVP_CIPHER_CTX **pctx" +.Fc +.Sh DESCRIPTION +.Fn BIO_f_cipher +returns the cipher BIO method. +This is a filter BIO that encrypts any data written through it, +and decrypts any data read from it. +It is a BIO wrapper for the cipher routines +.Xr EVP_CipherInit 3 , +.Xr EVP_CipherUpdate 3 , +and +.Xr EVP_CipherFinal 3 . +.Pp +Cipher BIOs do not support +.Xr BIO_gets 3 +or +.Xr BIO_puts 3 . +.Pp +.Xr BIO_flush 3 +on an encryption BIO that is being written through +is used to signal that no more data is to be encrypted: +this is used to flush and possibly pad the final block through the BIO. +.Pp +.Fn BIO_set_cipher +sets the cipher of BIO +.Fa b +to +.Fa cipher +using key +.Fa key +and IV +.Fa iv . +.Fa enc +should be set to 1 for encryption and zero for decryption. +.Pp +When reading from an encryption BIO, the final block is automatically +decrypted and checked when EOF is detected. +.Fn BIO_get_cipher_status +is a +.Xr BIO_ctrl 3 +macro which can be called to determine +whether the decryption operation was successful. +.Pp +.Fn BIO_get_cipher_ctx +is a +.Xr BIO_ctrl 3 +macro which retrieves the internal BIO cipher context. +The retrieved context can be used in conjunction +with the standard cipher routines to set it up. +This is useful when +.Fn BIO_set_cipher +is not flexible enough for the applications needs. +.Pp +When a chain containing a cipher BIO is copied with +.Xr BIO_dup_chain 3 , +the cipher context is automatically copied from the existing BIO object +to the new one and the init flag that can be retrieved with +.Xr BIO_get_init 3 +is set to 1. +.Pp +When encrypting, +.Xr BIO_flush 3 +must be called to flush the final block through the BIO. +If it is not, then the final block will fail a subsequent decrypt. +.Pp +When decrypting, an error on the final block is signalled +by a zero return value from the read operation. +A successful decrypt followed by EOF +will also return zero for the final read. +.Fn BIO_get_cipher_status +should be called to determine if the decrypt was successful. +.Pp +As always, if +.Xr BIO_gets 3 +or +.Xr BIO_puts 3 +support is needed, then it can be achieved +by preceding the cipher BIO with a buffering BIO. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +arguments correspond to macros as follows: +.Bl -column BIO_C_GET_CIPHER_STATUS BIO_get_cipher_status() -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_GET_CIPHER_CTX Ta Fn BIO_get_cipher_ctx +.It Dv BIO_C_GET_CIPHER_STATUS Ta Fn BIO_get_cipher_status +.It Dv BIO_CTRL_FLUSH Ta Xr BIO_flush 3 +.It Dv BIO_CTRL_PENDING Ta Xr BIO_pending 3 +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_WPENDING Ta Xr BIO_wpending 3 +.El +.Sh RETURN VALUES +.Fn BIO_f_cipher +returns the cipher BIO method. +.Pp +When called on a cipher BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_CIPHER +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq cipher . +.Pp +.Fn BIO_set_cipher +returns 1 on success and 0 on error. +.Pp +.Fn BIO_get_cipher_status +returns 1 for a successful decrypt and 0 for failure. +.Pp +.Fn BIO_get_cipher_ctx +currently always returns 1. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn BIO_f_cipher , +.Fn BIO_set_cipher , +and +.Fn BIO_get_cipher_status +first appeared in SSLeay 0.6.5 and have been available since +.Ox 2.4 . +.Pp +.Fn BIO_get_cipher_ctx +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/BIO_f_md.3 b/Libraries/libressl/man/BIO_f_md.3 new file mode 100644 index 000000000..279aabc98 --- /dev/null +++ b/Libraries/libressl/man/BIO_f_md.3 @@ -0,0 +1,366 @@ +.\" $OpenBSD: BIO_f_md.3,v 1.15 2023/04/28 16:20:01 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2006, 2009, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 28 2023 $ +.Dt BIO_F_MD 3 +.Os +.Sh NAME +.Nm BIO_f_md , +.Nm BIO_set_md , +.Nm BIO_get_md , +.Nm BIO_get_md_ctx , +.Nm BIO_set_md_ctx +.Nd message digest BIO filter +.Sh SYNOPSIS +.In openssl/bio.h +.In openssl/evp.h +.Ft const BIO_METHOD * +.Fo BIO_f_md +.Fa void +.Fc +.Ft long +.Fo BIO_set_md +.Fa "BIO *b" +.Fa "EVP_MD *md" +.Fc +.Ft long +.Fo BIO_get_md +.Fa "BIO *b" +.Fa "EVP_MD **mdp" +.Fc +.Ft long +.Fo BIO_get_md_ctx +.Fa "BIO *b" +.Fa "EVP_MD_CTX **mdcp" +.Fc +.Ft long +.Fo BIO_set_md_ctx +.Fa "BIO *b" +.Fa "EVP_MD_CTX *mdc" +.Fc +.Sh DESCRIPTION +.Fn BIO_f_md +returns the message digest BIO method. +This is a filter BIO that digests any data passed through it. +It is a BIO wrapper for the digest routines +.Xr EVP_DigestInit 3 , +.Xr EVP_DigestUpdate 3 , +and +.Xr EVP_DigestFinal 3 . +.Pp +.Fn BIO_set_md +sets the message digest of +.Fa b +to +.Fa md +and initializes it using +.Xr EVP_DigestInit_ex 3 . +Calling this function is required before any data is passed through +.Fa b . +.Pp +.Fn BIO_get_md +places a pointer to the digest method of +.Fa b +into +.Pf * Fa mdp . +.Pp +Any data written or read through a digest BIO using +.Xr BIO_read 3 +and +.Xr BIO_write 3 +is digested. +.Pp +.Xr BIO_gets 3 , +if its +.Sy size +parameter is large enough, +finishes the digest calculation and returns the digest value. +.Xr BIO_puts 3 +is +not supported. +If an application needs to call +.Xr BIO_gets 3 +or +.Xr BIO_puts 3 +through a chain containing digest BIOs, +this can be done by prepending a buffering BIO. +.Pp +After the digest has been retrieved from a digest BIO, call +.Xr BIO_reset 3 +to reinitialize it and any BIOs following it in its chain +before passing any more data through it. +If no subsequent BIOs require reinitialization, +.Fn BIO_set_md +can be used instead of +.Xr BIO_reset 3 . +.Pp +.Fn BIO_get_md_ctx +places a pointer to the digest context of +.Fa b +into +.Pf * Fa mdcp +and marks the BIO as initialized without actually initializing it. +Unless +.Fn BIO_set_md +was already called on +.Fa b , +the caller becomes responsible for initializing the digest context with +.Xr EVP_DigestInit_ex 3 . +.Pp +The context returned by +.Fn BIO_get_md_ctx +can be used in calls to +.Xr EVP_DigestFinal 3 +and also in the signature routines +.Xr EVP_SignFinal 3 +and +.Xr EVP_VerifyFinal 3 . +.Pp +The context returned by +.Fn BIO_get_md_ctx +is an internal context structure. +Changes made to this context will affect the digest BIO itself, and +the context pointer will become invalid when the digest BIO is freed. +.Pp +.Fn BIO_set_md_ctx +replaces the digest context of +.Fa b +with +.Fa mdc . +Calling this function is usually not necessary +because creating a digest BIO with +.Xr BIO_new 3 +automatically creates a digest context and stores it internally. +Before calling +.Fn BIO_set_md_ctx , +the caller has to retrieve the old context using +.Fn BIO_get_md_ctx , +and the caller also becomes responsible for calling +.Xr EVP_MD_CTX_free 3 +on the old context. +Unless +.Fa mdc +is already initialized, the caller needs to initialize it after calling +.Fn BIO_set_md_ctx +using either +.Fn BIO_set_md +or +.Xr EVP_DigestInit 3 . +.Pp +When a chain containing a message digest BIO is copied with +.Xr BIO_dup_chain 3 , +.Xr EVP_MD_CTX_copy_ex 3 +is called internally to automatically copy the message digest context +from the existing BIO object to the new one, +and the init flag that can be retrieved with +.Xr BIO_get_init 3 +is set to 1. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +arguments correspond to macros as follows: +.Bl -column BIO_C_GET_MD_CTX "corresponding macro" -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_GET_MD Ta Fn BIO_get_md +.It Dv BIO_C_GET_MD_CTX Ta Fn BIO_get_md_ctx +.It Dv BIO_C_SET_MD Ta Fn BIO_set_md +.It Dv BIO_C_SET_MD_CTX Ta Fn BIO_set_md_ctx +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.El +.Sh RETURN VALUES +.Fn BIO_f_md +returns the digest BIO method. +.Pp +When called on a message digest BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_MD +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq message digest . +.Pp +.Fn BIO_set_md +returns 1 on success or 0 if +.Xr EVP_DigestInit_ex 3 +fails. +.Pp +.Fn BIO_get_md +and +.Fn BIO_set_md_ctx +return 1 on success or 0 if +.Fa b +is not initialized. +.Pp +.Fn BIO_get_md_ctx +returns 1 on success or 0 on failure, +but the current implementation cannot actually fail. +.Sh EXAMPLES +The following example creates a BIO chain containing a SHA-1 and MD5 +digest BIO and passes the string "Hello World" through it. +Error checking has been omitted for clarity. +.Bd -literal -offset 2n +BIO *bio, *mdtmp; +const char message[] = "Hello World"; +bio = BIO_new(BIO_s_null()); +mdtmp = BIO_new(BIO_f_md()); +BIO_set_md(mdtmp, EVP_sha1()); +/* + * For BIO_push() we want to append the sink BIO + * and keep a note of the start of the chain. + */ +bio = BIO_push(mdtmp, bio); +mdtmp = BIO_new(BIO_f_md()); +BIO_set_md(mdtmp, EVP_md5()); +bio = BIO_push(mdtmp, bio); +/* Note: mdtmp can now be discarded */ +BIO_write(bio, message, strlen(message)); +.Ed +.Pp +The next example digests data by reading through a chain instead: +.Bd -literal -offset 2n +BIO *bio, *mdtmp; +char buf[1024]; +int rdlen; + +bio = BIO_new_file(file, "rb"); +mdtmp = BIO_new(BIO_f_md()); +BIO_set_md(mdtmp, EVP_sha1()); +bio = BIO_push(mdtmp, bio); +mdtmp = BIO_new(BIO_f_md()); +BIO_set_md(mdtmp, EVP_md5()); +bio = BIO_push(mdtmp, bio); +do { + rdlen = BIO_read(bio, buf, sizeof(buf)); + /* Might want to do something with the data here */ +} while (rdlen > 0); +.Ed +.Pp +This next example retrieves the message digests from a BIO chain +and outputs them. +This could be used with the examples above. +.Bd -literal -offset 2n +BIO *mdtmp; +unsigned char mdbuf[EVP_MAX_MD_SIZE]; +int mdlen; +int i; + +mdtmp = bio; /* Assume bio has previously been set up */ +do { + EVP_MD *md; + mdtmp = BIO_find_type(mdtmp, BIO_TYPE_MD); + if (!mdtmp) + break; + BIO_get_md(mdtmp, &md); + printf("%s digest", OBJ_nid2sn(EVP_MD_type(md))); + mdlen = BIO_gets(mdtmp, mdbuf, EVP_MAX_MD_SIZE); + for(i = 0; i < mdlen; i++) + printf(":%02X", mdbuf[i]); + printf("\en"); + mdtmp = BIO_next(mdtmp); +} while(mdtmp); +BIO_free_all(bio); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr EVP_DigestInit 3 +.Sh HISTORY +.Fn BIO_f_md , +.Fn BIO_set_md , +and +.Fn BIO_get_md +first appeared in SSLeay 0.6.0. +.Fn BIO_get_md_ctx +first appeared in SSLeay 0.8.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_set_md_ctx +first appeared in OpenSSL 0.9.7e and has been available since +.Ox 3.8 . +.Pp +Before OpenSSL 1.0.0, the call to +.Fn BIO_get_md_ctx +would only work if the +.Vt BIO +had been initialized, for example by calling +.Fn BIO_set_md . +.Sh BUGS +The lack of support for +.Xr BIO_puts 3 +and the non-standard behaviour of +.Xr BIO_gets 3 +could be regarded as anomalous. +It could be argued that +.Xr BIO_gets 3 +and +.Xr BIO_puts 3 +should be passed to the next BIO in the chain and digest the data +passed through and that digests should be retrieved using a separate +.Xr BIO_ctrl 3 +call. diff --git a/Libraries/libressl/man/BIO_f_null.3 b/Libraries/libressl/man/BIO_f_null.3 new file mode 100644 index 000000000..687d991b5 --- /dev/null +++ b/Libraries/libressl/man/BIO_f_null.3 @@ -0,0 +1,99 @@ +.\" $OpenBSD: BIO_f_null.3,v 1.12 2023/04/11 16:58:43 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 11 2023 $ +.Dt BIO_F_NULL 3 +.Os +.Sh NAME +.Nm BIO_f_null +.\" .Nm BIO_f_nbio_test is intentionally undocumented +.\" because it exposes absurd functionality that is unused +.\" except in openssl(1) s_client/s_server -nbio_test. +.Nd null filter +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_f_null +.Fa void +.Fc +.Sh DESCRIPTION +.Fn BIO_f_null +returns the null filter BIO method. +This is a filter BIO that does nothing. +As may be apparent, a null filter BIO is not particularly useful. +.Pp +All requests to a null filter BIO are passed through to the next BIO +in the chain: this means that a BIO chain containing a null filter BIO +behaves just as though the BIO was not there. +.Pp +A chain containing a null filter BIO cannot be copied with +.Xr BIO_dup_chain 3 , +and any attempt to do so fails and returns +.Dv NULL . +.Sh RETURN VALUES +.Fn BIO_f_null +returns the null filter BIO method. +.Pp +When called on a null filter BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_NULL_FILTER +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq NULL filter , +not to be confused with a NUL string nor with a +.Dv NULL pointer . +.Sh SEE ALSO +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_f_null +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_f_ssl.3 b/Libraries/libressl/man/BIO_f_ssl.3 new file mode 100644 index 000000000..ed2681677 --- /dev/null +++ b/Libraries/libressl/man/BIO_f_ssl.3 @@ -0,0 +1,632 @@ +.\" $OpenBSD: BIO_f_ssl.3,v 1.14 2023/04/11 16:58:43 schwarze Exp $ +.\" full merge up to: OpenSSL f672aee4 Feb 9 11:52:40 2016 -0500 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2003, 2009, 2014-2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 11 2023 $ +.Dt BIO_F_SSL 3 +.Os +.Sh NAME +.Nm BIO_f_ssl , +.Nm BIO_set_ssl , +.Nm BIO_get_ssl , +.Nm BIO_set_ssl_mode , +.Nm BIO_set_ssl_renegotiate_bytes , +.Nm BIO_get_num_renegotiates , +.Nm BIO_set_ssl_renegotiate_timeout , +.Nm BIO_new_ssl , +.Nm BIO_new_ssl_connect , +.Nm BIO_new_buffer_ssl_connect , +.Nm BIO_ssl_copy_session_id , +.Nm BIO_ssl_shutdown , +.Nm BIO_do_handshake +.Nd SSL BIO +.Sh SYNOPSIS +.In openssl/bio.h +.In openssl/ssl.h +.Ft const BIO_METHOD * +.Fn BIO_f_ssl void +.Ft long +.Fo BIO_set_ssl +.Fa "BIO *b" +.Fa "SSL *ssl" +.Fa "long c" +.Fc +.Ft long +.Fo BIO_get_ssl +.Fa "BIO *b" +.Fa "SSL *sslp" +.Fc +.Ft long +.Fo BIO_set_ssl_mode +.Fa "BIO *b" +.Fa "long client" +.Fc +.Ft long +.Fo BIO_set_ssl_renegotiate_bytes +.Fa "BIO *b" +.Fa "long num" +.Fc +.Ft long +.Fo BIO_set_ssl_renegotiate_timeout +.Fa "BIO *b" +.Fa "long seconds" +.Fc +.Ft long +.Fo BIO_get_num_renegotiates +.Fa "BIO *b" +.Fc +.Ft BIO * +.Fn BIO_new_ssl "SSL_CTX *ctx" "int client" +.Ft BIO * +.Fn BIO_new_ssl_connect "SSL_CTX *ctx" +.Ft BIO * +.Fn BIO_new_buffer_ssl_connect "SSL_CTX *ctx" +.Ft int +.Fn BIO_ssl_copy_session_id "BIO *to" "BIO *from" +.Ft void +.Fn BIO_ssl_shutdown "BIO *bio" +.Ft long +.Fn BIO_do_handshake "BIO *b" +.Sh DESCRIPTION +.Fn BIO_f_ssl +returns the +.Vt SSL +.Vt BIO +method. +This is a filter +.Vt BIO +which is a wrapper around the OpenSSL +.Vt SSL +routines adding a +.Vt BIO +.Dq flavor +to SSL I/O. +.Pp +I/O performed on an +.Vt SSL +.Vt BIO +communicates using the SSL protocol with +the +.Vt SSL Ns 's +read and write +.Vt BIO Ns s . +If an SSL connection is not established then an attempt is made to establish +one on the first I/O call. +.Pp +If a +.Vt BIO +is appended to an +.Vt SSL +.Vt BIO +using +.Xr BIO_push 3 , +it is automatically used as the +.Vt SSL +.Vt BIO Ns 's read and write +.Vt BIO Ns s . +.Pp +Calling +.Xr BIO_reset 3 +on an +.Vt SSL +.Vt BIO +closes down any current SSL connection by calling +.Xr SSL_shutdown 3 . +.Xr BIO_reset 3 +is then sent to the next +.Vt BIO +in the chain; this will typically disconnect the underlying transport. +The +.Vt SSL +.Vt BIO +is then reset to the initial accept or connect state. +.Pp +If the close flag is set when an +.Vt SSL +.Vt BIO +is freed then the internal +.Vt SSL +structure is also freed using +.Xr SSL_free 3 . +.Pp +.Fn BIO_set_ssl +sets the internal +.Vt SSL +pointer of +.Vt BIO +.Fa b +to +.Fa ssl +using +the close flag +.Fa c . +.Pp +.Fn BIO_get_ssl +retrieves the +.Vt SSL +pointer of +.Vt BIO +.Fa b ; +it can then be manipulated using the standard SSL library functions. +.Pp +.Fn BIO_set_ssl_mode +sets the +.Vt SSL +.Vt BIO +mode to +.Fa client . +If +.Fa client +is 1, client mode is set. +If +.Fa client +is 0, server mode is set. +.Pp +.Fn BIO_set_ssl_renegotiate_bytes +sets the renegotiate byte count to +.Fa num . +When set, after every +.Fa num +bytes of I/O (read and write) the SSL session is automatically renegotiated. +.Fa num +must be at least 512 bytes. +.Pp +.Fn BIO_set_ssl_renegotiate_timeout +sets the renegotiate timeout to +.Fa seconds . +When the renegotiate timeout elapses, the session is automatically renegotiated. +.Pp +.Fn BIO_get_num_renegotiates +returns the total number of session renegotiations due to I/O or timeout. +.Pp +.Fn BIO_new_ssl +allocates an +.Vt SSL +.Vt BIO +using +.Vt SSL_CTX +.Va ctx +and using client mode if +.Fa client +is nonzero. +.Pp +.Fn BIO_new_ssl_connect +creates a new +.Vt BIO +chain consisting of an +.Vt SSL +.Vt BIO +(using +.Fa ctx ) +followed by a connect BIO. +.Pp +.Fn BIO_new_buffer_ssl_connect +creates a new +.Vt BIO +chain consisting of a buffering +.Vt BIO , +an +.Vt SSL +.Vt BIO +(using +.Fa ctx ) +and a connect +.Vt BIO . +.Pp +.Fn BIO_ssl_copy_session_id +copies an SSL session id between +.Vt BIO +chains +.Fa from +and +.Fa to . +It does this by locating the +.Vt SSL +.Vt BIO Ns s +in each chain and calling +.Xr SSL_copy_session_id 3 +on the internal +.Vt SSL +pointer. +.Pp +.Fn BIO_ssl_shutdown +closes down an SSL connection on +.Vt BIO +chain +.Fa bio . +It does this by locating the +.Vt SSL +.Vt BIO +in the +chain and calling +.Xr SSL_shutdown 3 +on its internal +.Vt SSL +pointer. +.Pp +.Fn BIO_do_handshake +attempts to complete an SSL handshake on the supplied +.Vt BIO +and establish the SSL connection. +It returns 1 if the connection was established successfully. +A zero or negative value is returned if the connection could not be +established; the call +.Xr BIO_should_retry 3 +should be used for non blocking connect +.Vt BIO Ns s +to determine if the call should be retried. +If an SSL connection has already been established, this call has no effect. +.Pp +When a chain containing an SSL BIO is copied with +.Xr BIO_dup_chain 3 , +.Xr SSL_dup 3 +is called internally to copy the +.Vt SSL +object from the existing BIO object to the new BIO object, +and the internal data related to +.Fn BIO_set_ssl_renegotiate_bytes +and +.Fn BIO_set_ssl_renegotiate_timeout +is also copied. +.Pp +.Vt SSL +.Vt BIO Ns s +are exceptional in that if the underlying transport is non-blocking they can +still request a retry in exceptional circumstances. +Specifically this will happen if a session renegotiation takes place during a +.Xr BIO_read 3 +operation. +One case where this happens is when step up occurs. +.Pp +In OpenSSL 0.9.6 and later the SSL flag +.Dv SSL_AUTO_RETRY +can be set to disable this behaviour. +In other words, when this flag is set an +.Vt SSL +.Vt BIO +using a blocking transport will never request a retry. +.Pp +Since unknown +.Xr BIO_ctrl 3 +operations are sent through filter +.Vt BIO Ns s , +the server name and port can be set using +.Xr BIO_set_conn_hostname 3 +and +.Xr BIO_set_conn_port 3 +on the +.Vt BIO +returned by +.Fn BIO_new_ssl_connect +without having to locate the connect +.Vt BIO +first. +.Pp +Applications do not have to call +.Fn BIO_do_handshake +but may wish to do so to separate the handshake process from other I/O +processing. +.Pp +.Fn BIO_set_ssl , +.Fn BIO_get_ssl , +.Fn BIO_set_ssl_mode , +.Fn BIO_set_ssl_renegotiate_bytes , +.Fn BIO_set_ssl_renegotiate_timeout , +.Fn BIO_get_num_renegotiates , +and +.Fn BIO_do_handshake +are implemented as macros. +.Sh RETURN VALUES +.Fn BIO_f_ssl +returns a pointer to a static +.Vt BIO_METHOD +structure. +.Pp +When called on an SSL BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_SSL +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq ssl . +.Pp +.Fn BIO_set_ssl , +.Fn BIO_get_ssl , +.Fn BIO_set_ssl_mode , +.Fn BIO_set_ssl_renegotiate_bytes , +.Fn BIO_set_ssl_renegotiate_timeout , +and +.Fn BIO_get_num_renegotiates +return 1 on success or a value less than or equal to 0 +if an error occurred. +.Pp +.Fn BIO_new_ssl , +.Fn BIO_new_ssl_connect , +and +.Fn BIO_new_buffer_ssl_connect +returns a pointer to a newly allocated +.Vt BIO +chain or +.Dv NULL +if an error occurred. +.Pp +.Fn BIO_ssl_copy_session_id +returns 1 on success or 0 on error. +.Pp +.Fn BIO_do_handshake +returns 1 if the connection was established successfully +or a value less than or equal to 0 otherwise. +.Sh EXAMPLES +This SSL/TLS client example attempts to retrieve a page from an SSL/TLS web +server. +The I/O routines are identical to those of the unencrypted example in +.Xr BIO_s_connect 3 . +.Bd -literal +BIO *sbio, *out; +int len; +char tmpbuf[1024]; +SSL_CTX *ctx; +SSL *ssl; + +ERR_load_crypto_strings(); +ERR_load_SSL_strings(); +OpenSSL_add_all_algorithms(); + +/* + * We would seed the PRNG here if the platform didn't do it automatically + */ + +ctx = SSL_CTX_new(SSLv23_client_method()); + +/* + * We'd normally set some stuff like the verify paths and mode here because + * as things stand this will connect to any server whose certificate is + * signed by any CA. + */ + +sbio = BIO_new_ssl_connect(ctx); + +BIO_get_ssl(sbio, &ssl); + +if (!ssl) { + fprintf(stderr, "Can't locate SSL pointer\en"); + /* whatever ... */ +} + +/* Don't want any retries */ +SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + +/* We might want to do other things with ssl here */ + +BIO_set_conn_hostname(sbio, "localhost:https"); + +out = BIO_new_fp(stdout, BIO_NOCLOSE); +if (BIO_do_connect(sbio) <= 0) { + fprintf(stderr, "Error connecting to server\en"); + ERR_print_errors_fp(stderr); + /* whatever ... */ +} + +if (BIO_do_handshake(sbio) <= 0) { + fprintf(stderr, "Error establishing SSL connection\en"); + ERR_print_errors_fp(stderr); + /* whatever ... */ +} + +/* Could examine ssl here to get connection info */ + +BIO_puts(sbio, "GET / HTTP/1.0\en\en"); +for (;;) { + len = BIO_read(sbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); +} +BIO_free_all(sbio); +BIO_free(out); +.Ed +.Pp +Here is a simple server example. +It makes use of a buffering +.Vt BIO +to allow lines to be read from the +.Vt SSL +.Vt BIO +using +.Xr BIO_gets 3 . +It creates a pseudo web page containing the actual request from a client and +also echoes the request to standard output. +.Bd -literal +BIO *sbio, *bbio, *acpt, *out; +int len; +char tmpbuf[1024]; +SSL_CTX *ctx; +SSL *ssl; + +ERR_load_crypto_strings(); +ERR_load_SSL_strings(); +OpenSSL_add_all_algorithms(); + +/* Might seed PRNG here */ + +ctx = SSL_CTX_new(SSLv23_server_method()); + +if (!SSL_CTX_use_certificate_file(ctx,"server.pem",SSL_FILETYPE_PEM) + || !SSL_CTX_use_PrivateKey_file(ctx,"server.pem",SSL_FILETYPE_PEM) + || !SSL_CTX_check_private_key(ctx)) { + fprintf(stderr, "Error setting up SSL_CTX\en"); + ERR_print_errors_fp(stderr); + return 0; +} + +/* + * Might do other things here like setting verify locations and DH and/or + * RSA temporary key callbacks + */ + +/* New SSL BIO setup as server */ +sbio = BIO_new_ssl(ctx,0); + +BIO_get_ssl(sbio, &ssl); + +if (!ssl) { + fprintf(stderr, "Can't locate SSL pointer\en"); + /* whatever ... */ +} + +/* Don't want any retries */ +SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + +/* Create the buffering BIO */ + +bbio = BIO_new(BIO_f_buffer()); + +/* Add to chain */ +sbio = BIO_push(bbio, sbio); + +acpt = BIO_new_accept("4433"); + +/* + * By doing this when a new connection is established we automatically + * have sbio inserted into it. The BIO chain is now 'swallowed' by the + * accept BIO and will be freed when the accept BIO is freed. + */ + +BIO_set_accept_bios(acpt,sbio); + +out = BIO_new_fp(stdout, BIO_NOCLOSE); + +/* Wait for incoming connection */ +if (BIO_do_accept(acpt) <= 0) { + fprintf(stderr, "Error setting up accept BIO\en"); + ERR_print_errors_fp(stderr); + return 0; +} + +/* We only want one connection so remove and free accept BIO */ + +sbio = BIO_pop(acpt); + +BIO_free_all(acpt); + +if (BIO_do_handshake(sbio) <= 0) { + fprintf(stderr, "Error in SSL handshake\en"); + ERR_print_errors_fp(stderr); + return 0; +} + +BIO_puts(sbio, "HTTP/1.0 200 OK\er\enContent-type: text/plain\er\en\er\en"); +BIO_puts(sbio, "\er\enConnection Established\er\enRequest headers:\er\en"); +BIO_puts(sbio, "--------------------------------------------------\er\en"); + +for (;;) { + len = BIO_gets(sbio, tmpbuf, 1024); + if (len <= 0) + break; + BIO_write(sbio, tmpbuf, len); + BIO_write(out, tmpbuf, len); + /* Look for blank line signifying end of headers */ + if ((tmpbuf[0] == '\er') || (tmpbuf[0] == '\en')) + break; +} + +BIO_puts(sbio, "--------------------------------------------------\er\en"); +BIO_puts(sbio, "\er\en"); + +/* Since there is a buffering BIO present we had better flush it */ +BIO_flush(sbio); + +BIO_free_all(sbio); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 +.Sh HISTORY +.Fn BIO_f_ssl , +.Fn BIO_set_ssl , +and +.Fn BIO_get_ssl +first appeared in SSLeay 0.6.0. +.Fn BIO_set_ssl_mode , +.Fn BIO_new_ssl , +and +.Fn BIO_ssl_copy_session_id +first appeared in SSLeay 0.8.0. +.Fn BIO_ssl_shutdown +and +.Fn BIO_do_handshake +first appeared in SSLeay 0.8.1. +.Fn BIO_set_ssl_renegotiate_bytes , +.Fn BIO_get_num_renegotiates , +.Fn BIO_set_ssl_renegotiate_timeout , +.Fn BIO_new_ssl_connect , +and +.Fn BIO_new_buffer_ssl_connect +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +In OpenSSL versions before 1.0.0 the +.Xr BIO_pop 3 +call was handled incorrectly: +the I/O BIO reference count was incorrectly incremented (instead of +decremented) and dissociated with the +.Vt SSL +.Vt BIO +even if the +.Vt SSL +.Vt BIO +was not +explicitly being popped (e.g., a pop higher up the chain). +Applications which included workarounds for this bug (e.g., freeing BIOs more +than once) should be modified to handle this fix or they may free up an already +freed +.Vt BIO . diff --git a/Libraries/libressl/man/BIO_find_type.3 b/Libraries/libressl/man/BIO_find_type.3 new file mode 100644 index 000000000..4a9eee783 --- /dev/null +++ b/Libraries/libressl/man/BIO_find_type.3 @@ -0,0 +1,271 @@ +.\" $OpenBSD: BIO_find_type.3,v 1.12 2023/07/26 20:01:04 tb Exp $ +.\" full merge up to: OpenSSL 1cb7eff4 Sep 10 13:56:40 2019 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2013, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt BIO_FIND_TYPE 3 +.Os +.Sh NAME +.Nm BIO_find_type , +.Nm BIO_next , +.Nm BIO_method_type , +.Nm BIO_method_name +.Nd BIO chain traversal +.Sh SYNOPSIS +.In openssl/bio.h +.Ft BIO * +.Fo BIO_find_type +.Fa "BIO *bio" +.Fa "int type" +.Fc +.Ft BIO * +.Fo BIO_next +.Fa "BIO *bio" +.Fc +.Ft int +.Fo BIO_method_type +.Fa "const BIO *bio" +.Fc +.Ft const char * +.Fo BIO_method_name +.Fa "const BIO *bio" +.Fc +.Fd #define BIO_TYPE_NONE 0 +.Fd #define BIO_TYPE_START 128 +.Sh DESCRIPTION +.Fn BIO_find_type +searches for a BIO matching the given +.Fa type +in the chain starting at +.Fa bio . +If the least significant byte of the +.Fa type +argument is non-zero, only exact matches of the +.Fa type +are accepted. +Otherwise, a match only requires that any of the bits set in the +.Fa type +argument is also set in the candidate BIO. +.Pp +Types with a least significant byte in the range from 0 to +.Dv BIO_TYPE_START , +inclusive, are reserved for BIO types built into the library. +Types with a least significant byte greater than +.Dv BIO_TYPE_START +are available for user-defined BIO types; see +.Xr BIO_get_new_index 3 +for details. +.Pp +.Fn BIO_next +returns the next BIO in the chain after +.Fa bio . +This function can be used to traverse all BIOs in a chain +or in conjunction with +.Fn BIO_find_type +to find all BIOs of a certain type. +.Pp +.Fn BIO_method_type +returns the type of the given +.Fa bio . +.Pp +.Fn BIO_method_name +returns an ASCII string representing the type of the +.Fa bio . +.Pp +The following are the built-in source/sink BIO types +that operate on file descriptors. +They all have both of the bits +.Dv BIO_TYPE_SOURCE_SINK +and +.Dv BIO_TYPE_DESCRIPTOR +but not the bit +.Dv BIO_TYPE_FILTER +set in their type constant. +.Bl -column BIO_TYPE_NULL_FILTER "datagram socket" BIO_s_datagram(3) +.It Fa type No constant Ta Em name No string Ta Vt BIO_METHOD +.It Dv BIO_TYPE_ACCEPT Ta socket accept Ta Xr BIO_s_accept 3 +.It Dv BIO_TYPE_CONNECT Ta socket connect Ta Xr BIO_s_connect 3 +.It Dv BIO_TYPE_DGRAM Ta datagram socket Ta Xr BIO_s_datagram 3 +.It Dv BIO_TYPE_FD Ta file descriptor Ta Xr BIO_s_fd 3 +.It Dv BIO_TYPE_SOCKET Ta socket Ta Xr BIO_s_socket 3 +.El +.Pp +The following are the built-in source/sink BIO types +that do not directly operate on file descriptors. +They all have the bit +.Dv BIO_TYPE_SOURCE_SINK +but not the bits +.Dv BIO_TYPE_DESCRIPTOR +and +.Dv BIO_TYPE_FILTER +set in their type constant. +.Bl -column BIO_TYPE_NULL_FILTER "datagram socket" BIO_s_datagram(3) +.It Fa type No constant Ta Em name No string Ta Vt BIO_METHOD +.It Dv BIO_TYPE_BIO Ta BIO pair Ta Xr BIO_s_bio 3 +.It Dv BIO_TYPE_FILE Ta FILE pointer Ta Xr BIO_s_file 3 +.It Dv BIO_TYPE_MEM Ta memory buffer Ta Xr BIO_s_mem 3 +.It Dv BIO_TYPE_NULL Ta NULL Ta Xr BIO_s_null 3 +.El +.Pp +The following are the built-in filter BIO types. +They all have the bit +.Dv BIO_TYPE_FILTER +but not the bits +.Dv BIO_TYPE_SOURCE_SINK +and +.Dv BIO_TYPE_DESCRIPTOR +set in their type constant. +.Bl -column BIO_TYPE_NULL_FILTER "datagram socket" BIO_s_datagram(3) +.It Fa type No constant Ta Em name No string Ta Vt BIO_METHOD +.\" BIO_TYPE_ASN1 is intentionally undocumented because BIO_f_asn1 was +.\" removed from the public API. +.\" .It Dv BIO_TYPE_ASN1 Ta asn1 Ta Xr BIO_f_asn1 3 +.It Dv BIO_TYPE_BASE64 Ta base64 encoding Ta Xr BIO_f_base64 3 +.It Dv BIO_TYPE_BUFFER Ta buffer Ta Xr BIO_f_buffer 3 +.It Dv BIO_TYPE_CIPHER Ta cipher Ta Xr BIO_f_cipher 3 +.It Dv BIO_TYPE_MD Ta message digest Ta Xr BIO_f_md 3 +.It Dv BIO_TYPE_NULL_FILTER Ta NULL filter Ta Xr BIO_f_null 3 +.It Dv BIO_TYPE_SSL Ta ssl Ta Xr BIO_f_ssl 3 +.El +.Pp +The constants +.Dv BIO_TYPE_BER , +.Dv BIO_TYPE_PROXY_CLIENT , +and +.Dv BIO_TYPE_PROXY_SERVER +do not correspond to any BIO types implemented by the library and are +not intended to be used for application-defined types, either. +The constants +.Dv BIO_TYPE_COMP , +.Dv BIO_TYPE_LINEBUFFER , +and +.Dv BIO_TYPE_NBIO_TEST +corresponds to a deprecated BIO types that are intentionally undocumented. +.Pp +If a variable in an application program is intended +to store a BIO type but temporarily does not refer to any BIO +or refers to a BIO of an unknown type, setting the variable to +.Dv BIO_TYPE_NONE +is recommended. +.Sh RETURN VALUES +.Fn BIO_find_type +returns the next matching BIO or +.Dv NULL +if +.Fa bio +is a +.Dv NULL +pointer or if no matching BIO is found. +.Pp +.Fn BIO_next +returns the next BIO or +.Dv NULL +if +.Fa bio +is a +.Dv NULL +pointer or points to the last BIO in a chain. +.Pp +.Fn BIO_method_type +returns one of the +.Dv BIO_TYPE_* +constants. +.Pp +.Fn BIO_method_name +returns an internal pointer to a string. +.Sh EXAMPLES +Traverse a chain looking for digest BIOs: +.Bd -literal -offset 2n +BIO *btmp; + +btmp = in_bio; /* in_bio is the chain to search through */ +while (btmp != NULL) { + btmp = BIO_find_type(btmp, BIO_TYPE_MD); + if (btmp == NULL) + break; /* Not found */ + + /* btmp is a digest BIO, do something with it ... */ + ... + + btmp = BIO_next(btmp); +} +.Ed +.Sh SEE ALSO +.Xr BIO_meth_new 3 , +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_method_type +and +.Fn BIO_method_name +first appeared in SSLeay 0.6.0. +.Fn BIO_find_type +first appeared in SSLeay 0.6.6. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_next +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/BIO_get_data.3 b/Libraries/libressl/man/BIO_get_data.3 new file mode 100644 index 000000000..b4b0014d1 --- /dev/null +++ b/Libraries/libressl/man/BIO_get_data.3 @@ -0,0 +1,397 @@ +.\" $OpenBSD: BIO_get_data.3,v 1.7 2022/12/19 14:40:14 schwarze Exp $ +.\" full merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Matt Caswell . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 19 2022 $ +.Dt BIO_GET_DATA 3 +.Os +.Sh NAME +.Nm BIO_set_data , +.Nm BIO_get_data , +.Nm BIO_set_flags , +.Nm BIO_clear_flags , +.Nm BIO_test_flags , +.Nm BIO_get_flags , +.Nm BIO_set_retry_read , +.Nm BIO_set_retry_write , +.Nm BIO_set_retry_special , +.Nm BIO_clear_retry_flags , +.Nm BIO_get_retry_flags , +.Nm BIO_copy_next_retry , +.Nm BIO_set_init , +.Nm BIO_get_init , +.Nm BIO_set_shutdown , +.Nm BIO_get_shutdown +.Nd manage BIO state information +.Sh SYNOPSIS +.In openssl/bio.h +.Ft void +.Fo BIO_set_data +.Fa "BIO *a" +.Fa "void *ptr" +.Fc +.Ft void * +.Fo BIO_get_data +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_set_flags +.Fa "BIO *a" +.Fa "int flags" +.Fc +.Ft void +.Fo BIO_clear_flags +.Fa "BIO *a" +.Fa "int flags" +.Fc +.Ft int +.Fo BIO_test_flags +.Fa "const BIO *a" +.Fa "int flags" +.Fc +.Ft int +.Fo BIO_get_flags +.Fa "const BIO *a" +.Fc +.Ft void +.Fo BIO_set_retry_read +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_set_retry_write +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_set_retry_special +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_clear_retry_flags +.Fa "BIO *a" +.Fc +.Ft int +.Fo BIO_get_retry_flags +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_copy_next_retry +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_set_init +.Fa "BIO *a" +.Fa "int init" +.Fc +.Ft int +.Fo BIO_get_init +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_set_shutdown +.Fa "BIO *a" +.Fa "int shutdown" +.Fc +.Ft int +.Fo BIO_get_shutdown +.Fa "BIO *a" +.Fc +.Sh DESCRIPTION +These functions are mainly useful when implementing a custom BIO. +.Pp +The +.Fn BIO_set_data +function associates the custom data pointed to by +.Fa ptr +with the +.Fa "BIO a" . +This data can subsequently be retrieved via a call to +.Fn BIO_get_data . +This can be used by custom BIOs for storing implementation specific +information. +.Pp +.Fn BIO_set_flags +sets all the bits contained in the +.Fa flags +argument in the flags stored in +.Fa a . +The value of a flag neither changes when it is already set in +.Fa a +nor when it is unset in the +.Fa flags +argument. +.Pp +.Fn BIO_clear_flags +clears all the bits contained in the +.Fa flags +argument from the flags stored in +.Fa a . +The value of a flag neither changes when it is already unset in +.Fa a +nor when it is unset in the +.Fa flags +argument. +.Pp +.Fn BIO_test_flags +checks whether any of the bits contained in the +.Fa flags +argument are set in the flags stored in +.Fa a . +Application programs usually call macros like those documented in +.Xr BIO_should_retry 3 +rather than calling +.Fn BIO_test_flags +directly. +Flag bits correspond to accessor functions as follows: +.Pp +.Bl -tag -width BIO_FLAGS_SHOULD_RETRY -compact +.It Dv BIO_FLAGS_READ +.Xr BIO_should_read 3 +.It Dv BIO_FLAGS_WRITE +.Xr BIO_should_write 3 +.It Dv BIO_FLAGS_IO_SPECIAL +.Xr BIO_should_io_special 3 +.It Dv BIO_FLAGS_RWS +.Xr BIO_retry_type 3 +.It Dv BIO_FLAGS_SHOULD_RETRY +.Xr BIO_should_retry 3 +.It Dv BIO_FLAGS_BASE64_NO_NL +see +.Xr BIO_f_base64 3 +.It Dv BIO_FLAGS_MEM_RDONLY +see +.Xr BIO_s_mem 3 +.El +.Pp +In particular, +.Dv BIO_FLAGS_RWS +is the bitwise OR of +.Dv BIO_FLAGS_READ , +.Dv BIO_FLAGS_WRITE , +and +.Dv BIO_FLAGS_IO_SPECIAL . +.Pp +.Fn BIO_set_retry_read , +.Fn BIO_set_retry_write , +and +.Fn BIO_set_retry_special +set the +.Dv BIO_FLAGS_READ , +.Dv BIO_FLAGS_WRITE , +and +.Dv BIO_FLAGS_IO_SPECIAL +flag bit in +.Fa a , +respectively. +They all set the +.Dv BIO_FLAGS_SHOULD_RETRY +flag bit, too. +.Pp +.Fn BIO_clear_retry_flags +clears the flag bits +.Dv BIO_FLAGS_READ , +.Dv BIO_FLAGS_WRITE , +.Dv BIO_FLAGS_IO_SPECIAL , +and +.Dv BIO_FLAGS_SHOULD_RETRY +in +.Fa a . +.Pp +.Fn BIO_copy_next_retry +copies retry-related state data from the BIO that follows +.Fa a +in its chain to +.Fa a , +that is, the data accessible with +.Fn BIO_get_retry_flags +and +.Xr BIO_get_retry_reason 3 . +Flags which are already set in +.Fa a +are not cleared. +Before calling +.Fn BIO_copy_next_retry , +making sure that +.Fa a +is not the last BIO in its chain is the responsibility of the caller, +for example by checking that +.Xr BIO_next 3 +does not return +.Dv NULL . +.Pp +The +.Fn BIO_set_init +function sets the +.Fa init +flag in +.Fa a +to the specified value. +A non-zero value indicates that initialisation is complete, +whilst zero indicates that it is not. +Often initialisation will complete +during initial construction of the BIO. +For some BIOs however, initialisation may not be complete until +additional steps have been taken, for example through calling custom +ctrls. +.Pp +The +.Fn BIO_set_shutdown +and +.Fn BIO_get_shutdown +functions are low-level interfaces to forcefully set and get the +.Fa shutdown +flag of +.Fa a , +circumventing type-dependent sanity checks, +exclusively intended for implementing a new BIO type. +The +.Fa shutdown +argument must be either +.Dv BIO_CLOSE +or +.Dv BIO_NOCLOSE . +When merely using a +.Vt BIO +object, call +.Xr BIO_set_close 3 +and +.Xr BIO_get_close 3 +instead. +.Sh RETURN VALUES +.Fn BIO_get_data +returns a pointer to the implementation specific custom data associated +with +.Fa a , +or +.Dv NULL +if none is set. +.Pp +.Fn BIO_test_flags +returns the bitwise AND of the +.Fa flags +argument and the flags stored in +.Fa a . +Consequently, it returns a non-zero value +if and only if at least one of the requested +.Fa flags +is set. +.Pp +.Fn BIO_get_flags +returns all the flags currently stored in +.Fa a . +.Pp +.Fn BIO_get_retry_flags +returns the bitwise AND of +.Pq Dv BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY +and the flags stored in +.Fa a . +.Pp +.Fn BIO_get_init +returns the value of the init flag of +.Fa a . +.Pp +.Fn BIO_get_shutdown +returns the value previously set with +.Fn BIO_set_shutdown +or with +.Xr BIO_set_close 3 . +.Sh SEE ALSO +.Xr BIO_meth_new 3 , +.Xr BIO_new 3 , +.Xr BIO_set_close 3 , +.Xr BIO_should_retry 3 +.Sh HISTORY +.Fn BIO_set_flags , +.Fn BIO_clear_flags , +.Fn BIO_set_retry_read , +.Fn BIO_set_retry_write , +.Fn BIO_set_retry_special , +.Fn BIO_clear_retry_flags , +and +.Fn BIO_get_retry_flags +first appeared in SSLeay 0.8.0, +.Fn BIO_copy_next_retry +in SSLeay 0.8.1, and +.Fn BIO_get_flags +in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_test_flags +first appeared in OpenSSL 0.9.8e and has been available since +.Ox 4.5 . +.Pp +.Fn BIO_set_data , +.Fn BIO_get_data , +.Fn BIO_set_init , +.Fn BIO_set_shutdown , +and +.Fn BIO_get_shutdown +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Pp +.Fn BIO_get_init +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/BIO_get_ex_new_index.3 b/Libraries/libressl/man/BIO_get_ex_new_index.3 new file mode 100644 index 000000000..69f0ffc43 --- /dev/null +++ b/Libraries/libressl/man/BIO_get_ex_new_index.3 @@ -0,0 +1,205 @@ +.\" $OpenBSD: BIO_get_ex_new_index.3,v 1.14 2023/07/21 04:39:49 tb Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Rich Salz . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 21 2023 $ +.Dt BIO_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm BIO_get_ex_new_index , +.Nm BIO_set_ex_data , +.Nm BIO_get_ex_data , +.Nm BIO_set_app_data , +.Nm BIO_get_app_data , +.Nm ENGINE_get_ex_new_index , +.Nm ENGINE_set_ex_data , +.Nm ENGINE_get_ex_data , +.Nm UI_get_ex_new_index , +.Nm UI_set_ex_data , +.Nm UI_get_ex_data , +.Nm X509_get_ex_new_index , +.Nm X509_set_ex_data , +.Nm X509_get_ex_data , +.Nm EC_KEY_get_ex_new_index , +.Nm EC_KEY_get_ex_data , +.Nm EC_KEY_set_ex_data +.Nd application-specific data +.Sh SYNOPSIS +.In openssl/bio.h +.In openssl/engine.h +.In openssl/ui.h +.In openssl/x509.h +.In openssl/ec.h +.Ft int +.Fo TYPE_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fo TYPE_set_ex_data +.Fa "TYPE *d" +.Fa "int idx" +.Fa "void *arg" +.Fc +.Ft void * +.Fo TYPE_get_ex_data +.Fa "TYPE *d" +.Fa "int idx" +.Fc +.Ft int +.Fo TYPE_set_app_data +.Fa "TYPE *d" +.Fa "void *arg" +.Fc +.Ft void * +.Fo TYPE_get_app_data +.Fa "TYPE *d" +.Fc +.Sh DESCRIPTION +In the description here, +.Vt TYPE +is used a placeholder for any of the OpenSSL datatypes listed in +.Xr CRYPTO_get_ex_new_index 3 . +.Pp +These functions handle application-specific data in OpenSSL data +structures. +Their usage is identical to that of +.Xr RSA_get_ex_new_index 3 , +.Xr RSA_set_ex_data 3 , +and +.Xr RSA_get_ex_data 3 . +.Pp +.Fn TYPE_get_ex_new_index +is a macro that calls +.Xr CRYPTO_get_ex_new_index 3 +with the correct index value. +.Pp +.Fn TYPE_set_ex_data +is a function that calls +.Xr CRYPTO_set_ex_data 3 +with an offset into the opaque exdata part of the +.Vt TYPE +object. +.Pp +.Fn TYPE_get_ex_data +is a function that calls +.Xr CRYPTO_get_ex_data 3 +with an offset into the opaque exdata part of the +.Vt TYPE +object. +.Pp +.Fn TYPE_set_app_data +and +.Fn TYPE_get_app_data +are deprecated wrappers that call +.Fn TYPE_set_ex_data +and +.Fn TYPE_get_ex_data +with +.Fa idx +set to 0. +.Sh RETURN VALUES +.Fn TYPE_get_new_ex_index +returns a new index on success or \-1 on error. +.Pp +.Fn TYPE_set_ex_data +and +.Fn TYPE_set_app_data +return 1 on success or 0 on error. +.Pp +.Fn TYPE_get_ex_data +and +.Fn TYPE_get_app_data +return the application data or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr CRYPTO_get_ex_new_index 3 , +.Xr RSA_get_ex_new_index 3 , +.Xr X509_new 3 +.Sh HISTORY +.Fn BIO_set_app_data +and +.Fn BIO_get_app_data +first appeared in SSLeay 0.8.1. +.Fn BIO_get_ex_new_index , +.Fn BIO_set_ex_data , +and +.Fn BIO_get_ex_data +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_get_ex_new_index , +.Fn X509_set_ex_data , +and +.Fn X509_get_ex_data +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn ENGINE_get_ex_new_index , +.Fn ENGINE_set_ex_data , +.Fn ENGINE_get_ex_data , +.Fn UI_get_ex_new_index , +.Fn UI_set_ex_data , +and +.Fn UI_get_ex_data +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EC_KEY_get_ex_new_index , +.Fn EC_KEY_set_ex_data , +and +.Fn EC_KEY_get_ex_data +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/BIO_meth_new.3 b/Libraries/libressl/man/BIO_meth_new.3 new file mode 100644 index 000000000..215956059 --- /dev/null +++ b/Libraries/libressl/man/BIO_meth_new.3 @@ -0,0 +1,367 @@ +.\" $OpenBSD: BIO_meth_new.3,v 1.5 2018/07/09 09:52:18 tb Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Matt Caswell +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 9 2018 $ +.Dt BIO_METH_NEW 3 +.Os +.Sh NAME +.Nm BIO_get_new_index , +.Nm BIO_meth_new , +.Nm BIO_meth_free , +.Nm BIO_meth_get_write , +.Nm BIO_meth_set_write , +.Nm BIO_meth_get_read , +.Nm BIO_meth_set_read , +.Nm BIO_meth_get_puts , +.Nm BIO_meth_set_puts , +.Nm BIO_meth_get_gets , +.Nm BIO_meth_set_gets , +.Nm BIO_meth_get_ctrl , +.Nm BIO_meth_set_ctrl , +.Nm BIO_meth_get_create , +.Nm BIO_meth_set_create , +.Nm BIO_meth_get_destroy , +.Nm BIO_meth_set_destroy , +.Nm BIO_meth_get_callback_ctrl , +.Nm BIO_meth_set_callback_ctrl +.Nd manipulate BIO_METHOD structures +.Sh SYNOPSIS +.In openssl/bio.h +.Ft int +.Fn BIO_get_new_index void +.Ft BIO_METHOD * +.Fo BIO_meth_new +.Fa "int type" +.Fa "const char *name" +.Fc +.Ft void +.Fo BIO_meth_free +.Fa "BIO_METHOD *biom" +.Fc +.Ft int +.Fn "(*BIO_meth_get_write(const BIO_METHOD *biom))" "BIO *" "const char *" int +.Ft int +.Fo BIO_meth_set_write +.Fa "BIO_METHOD *biom" +.Fa "int (*write)(BIO *, const char *, int)" +.Fc +.Ft int +.Fn "(*BIO_meth_get_read(const BIO_METHOD *biom))" "BIO *" "char *" int +.Ft int +.Fo BIO_meth_set_read +.Fa "BIO_METHOD *biom" +.Fa "int (*read)(BIO *, char *, int)" +.Fc +.Ft int +.Fn "(*BIO_meth_get_puts(const BIO_METHOD *biom))" "BIO *" "const char *" +.Ft int +.Fo BIO_meth_set_puts +.Fa "BIO_METHOD *biom" +.Fa "int (*puts)(BIO *, const char *)" +.Fc +.Ft int +.Fn "(*BIO_meth_get_gets(const BIO_METHOD *biom))" "BIO *" "char *" int +.Ft int +.Fo BIO_meth_set_gets +.Fa "BIO_METHOD *biom" +.Fa "int (*gets)(BIO *, char *, int)" +.Fc +.Ft long +.Fn "(*BIO_meth_get_ctrl(const BIO_METHOD *biom))" "BIO *" int long "void *" +.Ft int +.Fo BIO_meth_set_ctrl +.Fa "BIO_METHOD *biom" +.Fa "long (*ctrl)(BIO *, int, long, void *)" +.Fc +.Ft int +.Fn "(*BIO_meth_get_create(const BIO_METHOD *biom))" "BIO *" +.Ft int +.Fo BIO_meth_set_create +.Fa "BIO_METHOD *biom" +.Fa "int (*create)(BIO *)" +.Fc +.Ft int +.Fn "(*BIO_meth_get_destroy(const BIO_METHOD *biom))" "BIO *" +.Ft int +.Fo BIO_meth_set_destroy +.Fa "BIO_METHOD *biom" +.Fa "int (*destroy)(BIO *)" +.Fc +.Ft long +.Fo "(*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))" +.Fa "BIO *" +.Fa int +.Fa "BIO_info_cb *" +.Fc +.Ft int +.Fo BIO_meth_set_callback_ctrl +.Fa "BIO_METHOD *biom" +.Fa "long (*callback_ctrl)(BIO *, int, BIO_info_cb *)" +.Fc +.Sh DESCRIPTION +The +.Vt BIO_METHOD +structure stores function pointers implementing a +.Vt BIO +type. +See +.Xr BIO_new 3 +for more information about +.Vt BIO +objects. +.Pp +.Fn BIO_meth_new +creates a new +.Vt BIO_METHOD +structure. +It requires a unique integer +.Fa type ; +use +.Fn BIO_get_new_index +to get the value for +.Fa type . +Currently, the user can only create up to 127 different BIO types, and +.Fa type +is limited to the range 129\(en255. +The +.Fa name +pointer is stored in the structure and will not be freed by +.Fn BIO_meth_free . +.Pp +The standard BIO types are listed in +.In openssl/bio.h . +Some examples include +.Dv BIO_TYPE_BUFFER +and +.Dv BIO_TYPE_CIPHER . +The +.Fa type +of filter BIOs should have the +.Dv BIO_TYPE_FILTER +bit set. +Source/sink BIOs should have the +.Dv BIO_TYPE_SOURCE_SINK +bit set. +File descriptor based BIOs (e.g. socket, fd, connect, accept etc.\&) +should additionally have the +.Dv BIO_TYPE_DESCRIPTOR +bit set. +See +.Xr BIO_find_type 3 +for more information. +.Pp +.Fn BIO_meth_free +is an alias for +.Xr free 3 . +.Pp +.Fn BIO_meth_get_write , +.Fn BIO_meth_set_write , +.Fn BIO_meth_get_read , +and +.Fn BIO_meth_set_read +get and set the functions +.Fa write +and +.Fa read +used for writing and reading arbitrary length data to and from the +.Vt BIO . +These functions are called from +.Xr BIO_write 3 +and +.Xr BIO_read 3 , +respectively. +The parameters and return values of +.Fa write +and +.Fa read +have the same meaning as for +.Xr BIO_write 3 +and +.Xr BIO_read 3 . +.Pp +.Fn BIO_meth_get_puts +and +.Fn BIO_meth_set_puts +get and set the function +.Fa puts +used for writing a NUL-terminated string to the +.Vt BIO . +This function is called from +.Xr BIO_puts 3 . +The parameters and the return value of +.Fa puts +have the same meaning as for +.Xr BIO_puts 3 . +.Pp +.Fn BIO_meth_get_gets +and +.Fn BIO_meth_set_gets +get and set the function +.Fa gets +used for reading a line of data from the +.Vt BIO . +This function is called from +.Xr BIO_gets 3 . +The parameters and the return value of +.Fa gets +have the same meaning as for +.Xr BIO_gets 3 . +.Pp +.Fn BIO_meth_get_ctrl +and +.Fn BIO_meth_set_ctrl +get and set the function +.Fa ctrl +used for processing control messages in the +.Vt BIO . +This function is called from +.Xr BIO_ctrl 3 . +The parameters and return value of +.Fa ctrl +have the same meaning as for +.Xr BIO_ctrl 3 . +.Pp +.Fn BIO_meth_get_create +and +.Fn BIO_meth_set_create +get and set a function +.Fa create +used while initializing a new instance of the +.Vt BIO . +This function is called from +.Xr BIO_new 3 . +The +.Xr BIO_new 3 +function allocates the memory for the new +.Vt BIO , +and a pointer to this newly allocated structure is passed +as the parameter to +.Fa create . +.Pp +.Fn BIO_meth_get_destroy +and +.Fn BIO_meth_set_destroy +get and set a function +.Fa destroy +used while destroying an instance of a +.Vt BIO . +This function is called from +.Xr BIO_free 3 . +A pointer to the +.Vt BIO +to be destroyed is passed as the parameter. +The +.Fa destroy +function is intended to perform clean-up specific to the +.Vt BIO +.Fa type . +The memory for the +.Vt BIO +itself must not be freed by this function. +.Pp +.Fn BIO_meth_get_callback_ctrl +and +.Fn BIO_meth_set_callback_ctrl +get and set the function +.Fa callback_ctrl +used for processing callback control messages in the +.Vt BIO . +This function is called from +.Xr BIO_callback_ctrl 3 . +The parameters and return value of +.Fa callback_ctrl +have the same meaning as for +.Xr BIO_callback_ctrl 3 . +.Sh RETURN VALUES +.Fn BIO_get_new_index +returns the new BIO type value or \-1 if an error occurs. +.Pp +.Fn BIO_meth_new +returns the new +.Vt BIO_METHOD +structure or +.Dv NULL +if an error occurs. +.Pp +The +.Fn BIO_meth_set_* +functions return 1 on success or 0 on error. +Currently, they cannot fail. +.Pp +The +.Fn BIO_meth_get_* +functions return function pointers. +.Sh SEE ALSO +.Xr BIO_ctrl 3 , +.Xr BIO_find_type 3 , +.Xr BIO_new 3 , +.Xr BIO_read 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/BIO_new.3 b/Libraries/libressl/man/BIO_new.3 new file mode 100644 index 000000000..f97a31482 --- /dev/null +++ b/Libraries/libressl/man/BIO_new.3 @@ -0,0 +1,279 @@ +.\" $OpenBSD: BIO_new.3,v 1.28 2023/07/26 20:01:04 tb Exp $ +.\" full merge up to: +.\" OpenSSL man3/BIO_new.pod fb46be03 Feb 26 11:51:31 2016 +0000 +.\" OpenSSL man7/bio.pod 631c37be Dec 12 16:56:50 2017 +0100 +.\" partial merge up to: +.\" OpenSSL man3/BIO_new.pod e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt BIO_NEW 3 +.Os +.Sh NAME +.Nm BIO_new , +.Nm BIO_up_ref , +.Nm BIO_set , +.Nm BIO_free , +.Nm BIO_vfree , +.Nm BIO_free_all +.Nd construct and destruct I/O abstraction objects +.Sh SYNOPSIS +.In openssl/bio.h +.Ft BIO * +.Fo BIO_new +.Fa "const BIO_METHOD *type" +.Fc +.Ft int +.Fo BIO_up_ref +.Fa "BIO *a" +.Fc +.Ft int +.Fo BIO_set +.Fa "BIO *a" +.Fa "const BIO_METHOD *type" +.Fc +.Ft int +.Fo BIO_free +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_vfree +.Fa "BIO *a" +.Fc +.Ft void +.Fo BIO_free_all +.Fa "BIO *a" +.Fc +.Sh DESCRIPTION +A +.Vt BIO +is an I/O abstraction object, hiding many of the underlying I/O +details from an application. +If an application uses BIOs for its I/O, it can transparently handle +SSL connections, unencrypted network connections, and file I/O. +.Pp +The +.Fn BIO_new +function constructs a new +.Vt BIO +using the method +.Fa type +and sets its reference count to 1. +There are two groups of BIO types, source/sink BIOs and filter BIOs. +.Pp +Source/sink BIOs provide input or consume output. +Examples include socket BIOs and file BIOs. +.Pp +Filter BIOs take data from one BIO and pass it through to another, +or to the application, forming a chain of BIOs. +The data may be left unmodified (for example by a message digest BIO) +or translated (for example by an encryption BIO). +The effect of a filter BIO may change according to the I/O operation +it is performing: for example an encryption BIO encrypts data +if it is written to and decrypts data if it is read from. +.Pp +Some BIOs (such as memory BIOs) can be used immediately after calling +.Fn BIO_new . +Others (such as file BIOs) need some additional initialization, and +utility functions exists to construct and initialize such BIOs. +.Pp +Normally the +.Fa type +argument is supplied by a function which returns a pointer to a +.Vt BIO_METHOD . +There is a naming convention for such functions: +the methods for source/sink BIOs are called +.Fn BIO_s_* +and those for filter BIOs +.Fn BIO_f_* . +.Pp +.Fn BIO_up_ref +increments the reference count of +.Fa a +by 1. +.Pp +.Fn BIO_set +is a deprecated function to initialize an unused +.Vt BIO +structure located in static memory or on the stack, +to set its method to +.Fa type , +and to set its reference count to 1. +It must not be called on +.Vt BIO +objects created with +.Fn BIO_new , +nor on objects that were already used. +.Pp +.Fn BIO_free +and +.Fn BIO_vfree +decrement the reference count of +.Fa a +by 1, and if the reference count reaches 0, they destruct the single +.Vt BIO +.Fa a , +which may also have some effect on the +underlying I/O structure, for example it may close the file being +referred to under certain circumstances. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +If +.Fn BIO_free +is called on a BIO chain, it destructs at most one BIO, +resulting in a memory leak. +.Pp +.Fn BIO_free_all +calls +.Fn BIO_free +on +.Fa a +and on all following +.Vt BIO +objects in the chain. +As soon as the reference count of a +.Vt BIO +is still non-zero after calling +.Fn BIO_free +on it, the function +.Fn BIO_free_all +returns right away and refrains from freeing the remaining +.Vt BIO +objects in the chain. +It does not halt if an error occurs +destructing an individual BIO in the chain. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +Calling +.Fn BIO_free_all +on a single BIO has the same effect as +.Fn BIO_vfree . +.Pp +Common I/O functions are documented in +.Xr BIO_read 3 . +Forming chains is explained in +.Xr BIO_push 3 ; +inspecting them is explained in +.Xr BIO_find_type 3 . +For more details about the different kinds of BIOs, see the individual +.Vt BIO_METHOD +manual pages. +.Sh RETURN VALUES +.Fn BIO_new +returns a newly constructed +.Vt BIO +object or +.Dv NULL +on failure. +.Pp +.Fn BIO_up_ref , +.Fn BIO_set , +and +.Fn BIO_free +return 1 for success or 0 for failure. +.Sh EXAMPLES +Create a memory BIO: +.Pp +.Dl BIO *mem = BIO_new(BIO_s_mem()); +.Sh SEE ALSO +.Xr BIO_accept 3 , +.Xr BIO_ctrl 3 , +.Xr BIO_dump 3 , +.Xr BIO_dup_chain 3 , +.Xr BIO_f_base64 3 , +.Xr BIO_f_buffer 3 , +.Xr BIO_f_cipher 3 , +.Xr BIO_f_md 3 , +.Xr BIO_f_null 3 , +.Xr BIO_f_ssl 3 , +.Xr BIO_find_type 3 , +.Xr BIO_get_ex_new_index 3 , +.Xr BIO_meth_new 3 , +.Xr BIO_new_CMS 3 , +.Xr BIO_printf 3 , +.Xr BIO_push 3 , +.Xr BIO_read 3 , +.Xr BIO_s_accept 3 , +.Xr BIO_s_bio 3 , +.Xr BIO_s_connect 3 , +.Xr BIO_s_datagram 3 , +.Xr BIO_s_fd 3 , +.Xr BIO_s_file 3 , +.Xr BIO_s_mem 3 , +.Xr BIO_s_null 3 , +.Xr BIO_s_socket 3 , +.Xr BIO_set_callback 3 , +.Xr BIO_set_data 3 , +.Xr BIO_should_retry 3 , +.Xr BUF_MEM_new 3 , +.Xr crypto 3 +.Sh HISTORY +.Fn BIO_new , +.Fn BIO_set , +and +.Fn BIO_free +first appeared in SSLeay 0.6.0. +.Fn BIO_free_all +first appeared in SSLeay 0.6.6. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_vfree +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn BIO_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/BIO_new_CMS.3 b/Libraries/libressl/man/BIO_new_CMS.3 new file mode 100644 index 000000000..ab93e1c00 --- /dev/null +++ b/Libraries/libressl/man/BIO_new_CMS.3 @@ -0,0 +1,141 @@ +.\" $OpenBSD: BIO_new_CMS.3,v 1.9 2023/05/01 07:28:11 tb Exp $ +.\" full merge up to: OpenSSL df75c2bfc Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt BIO_NEW_CMS 3 +.Os +.Sh NAME +.Nm BIO_new_CMS +.Nd CMS streaming filter BIO +.Sh SYNOPSIS +.In openssl/cms.h +.Ft BIO * +.Fo BIO_new_CMS +.Fa "BIO *out" +.Fa "CMS_ContentInfo *cms" +.Fc +.Sh DESCRIPTION +.Fn BIO_new_CMS +returns a streaming filter +.Vt BIO +chain based on +.Fa cms . +The output of the filter is written to +.Fa out . +Any data written to the chain is automatically translated +to a BER format CMS structure of the appropriate type. +.Pp +The chain returned by this function behaves like a standard filter +.Vt BIO . +It supports non blocking I/O. +Content is processed and streamed on the fly and not all held in memory +at once: so it is possible to encode very large structures. +After all content has been written through the chain, +.Xr BIO_flush 3 +must be called to finalise the structure. +.Pp +The +.Dv CMS_STREAM +flag must be included in the corresponding +.Fa flags +parameter of the +.Fa cms +creation function. +.Pp +If an application wishes to write additional data to +.Fa out , +BIOs should be removed from the chain using +.Xr BIO_pop 3 +and freed with +.Xr BIO_free 3 +until +.Fa out +is reached. +If no additional data needs to be written, +.Xr BIO_free_all 3 +can be called to free up the whole chain. +.Pp +Any content written through the filter is used verbatim: +no canonical translation is performed. +.Pp +It is possible to chain multiple BIOs to, for example, +create a triple wrapped signed, enveloped, signed structure. +In this case it is the application's responsibility +to set the inner content type of any outer +.Vt CMS_ContentInfo +structures. +.Pp +Large numbers of small writes through the chain should be avoided as this +will produce an output consisting of lots of OCTET STRING structures. +Prepending a +.Xr BIO_f_buffer 3 +buffering BIO will prevent this. +.Sh RETURN VALUES +.Fn BIO_new_CMS +returns a +.Vt BIO +chain when successful or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_sign 3 +.Sh HISTORY +.Fn BIO_new_CMS +first appeared in OpenSSL 1.0.0 +and has been available since +.Ox 6.7 . +.Sh BUGS +There is currently no corresponding inverse BIO +which can decode a CMS structure on the fly. diff --git a/Libraries/libressl/man/BIO_printf.3 b/Libraries/libressl/man/BIO_printf.3 new file mode 100644 index 000000000..838b771be --- /dev/null +++ b/Libraries/libressl/man/BIO_printf.3 @@ -0,0 +1,97 @@ +.\" $OpenBSD: BIO_printf.3,v 1.3 2018/03/22 17:11:04 schwarze Exp $ +.\" OpenSSL 2ca2e917 Mon Mar 20 16:25:22 2017 -0400 +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt BIO_PRINTF 3 +.Os +.Sh NAME +.Nm BIO_printf , +.Nm BIO_vprintf , +.Nm BIO_snprintf , +.Nm BIO_vsnprintf +.Nd formatted output to a BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft int +.Fo BIO_printf +.Fa "BIO *bio" +.Fa "const char *format" +.Fa ... +.Fc +.Ft int +.Fo BIO_vprintf +.Fa "BIO *bio" +.Fa "const char *format" +.Fa "va_list args" +.Fc +.Ft int +.Fo BIO_snprintf +.Fa "char *buf" +.Fa "size_t n" +.Fa "const char *format" +.Fa ... +.Fc +.Ft int +.Fo BIO_vsnprintf +.Fa "char *buf" +.Fa "size_t n" +.Fa "const char *format" +.Fa "va_list args" +.Fc +.Sh DESCRIPTION +.Fn BIO_vprintf +is a wrapper around +.Xr vfprintf 3 , +sending the output to the specified +.Fa bio . +.Pp +.Fn BIO_printf +is a wrapper around +.Fn BIO_vprintf . +.Pp +.Fn BIO_snprintf +and +.Fn BIO_vsnprintf +are wrappers around +.Xr vsnprintf 3 . +.Sh RETURN VALUES +These functions return the number of bytes written, +or -1 if an error occurs. +.Pp +In contrast to +.Xr snprintf 3 +and +.Xr vsnprintf 3 , +.Fn BIO_snprintf +and +.Fn BIO_vsnprintf +also return -1 if +.Fa n +is too small to hold the complete output. +.Sh SEE ALSO +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_printf +first appeared in SSLeay 0.6.5 and has been available since +.Ox 2.4 . +.Pp +.Fn BIO_vprintf , +.Fn BIO_snprintf , +and +.Fn BIO_vsnprintf +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/BIO_push.3 b/Libraries/libressl/man/BIO_push.3 new file mode 100644 index 000000000..46c736e2c --- /dev/null +++ b/Libraries/libressl/man/BIO_push.3 @@ -0,0 +1,335 @@ +.\" $OpenBSD: BIO_push.3,v 1.14 2022/12/16 16:02:17 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL doc/man3/BIO_push.pod 791bfd91 Nov 19 20:38:27 2021 +0100 +.\" OpenSSL doc/man7/bio.pod 1cb7eff4 Sep 10 13:56:40 2019 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 16 2022 $ +.Dt BIO_PUSH 3 +.Os +.Sh NAME +.Nm BIO_push , +.Nm BIO_pop , +.Nm BIO_set_next +.Nd manipulate BIO chains +.Sh SYNOPSIS +.In openssl/bio.h +.Ft BIO * +.Fo BIO_push +.Fa "BIO *b" +.Fa "BIO *new_tail" +.Fc +.Ft BIO * +.Fo BIO_pop +.Fa "BIO *b" +.Fc +.Ft void +.Fo BIO_set_next +.Fa "BIO *b" +.Fa "BIO *new_tail" +.Fc +.Sh DESCRIPTION +BIOs can be joined together to form chains. +A chain normally consists of one or more filter BIOs +and one source/sink BIO at the end. +Data read from or written to the first BIO traverses the chain +to the end. +.Pp +Every BIO is a member of exactly one chain. +It is either at the beginning of its chain +or there is exactly one preceding BIO. +It is either at the end of its chain +or there is exactly one following BIO. +If there is neither a preceding nor a following BIO, +it can be regarded as a chain with one member. +Every chain has exactly one beginning and exactly one end. +.Pp +.Fn BIO_push +appends the chain starting at +.Fa new_tail +to the end of the chain that contains +.Fa b . +Unless +.Fa b +is +.Dv NULL , +it then calls +.Xr BIO_ctrl 3 +on +.Fa b +with an argument of +.Dv BIO_CTRL_PUSH . +If +.Fa b +or +.Fa new_tail +is +.Dv NULL , +nothing is appended. +.Pp +In LibreSSL, if +.Fa new_tail +is not at the beginning of its chain, +the head of that chain up to but not including +.Fa new_tail +is cut off and becomes a separate chain. +For portability, it is best to make sure that +.Fa new_tail +is at the beginning of its chain before calling +.Fn BIO_push . +.Pp +.Fn BIO_pop +removes the BIO +.Fa b +from its chain. +Despite the word +.Dq pop +in the function name, +.Fa b +can be at the beginning, in the middle, or at the end of its chain. +Before removal, +.Xr BIO_ctrl 3 +is called on +.Fa b +with an argument of +.Dv BIO_CTRL_POP . +The removed BIO +.Fa b +becomes the only member of its own chain and can thus be freed +or attached to a different chain. +If +.Fa b +is +.Dv NULL , +no action occurs. +.Pp +.Fn BIO_set_next +appends the chain starting with +.Fa new_tail +to the chain ending with +.Fa b . +.Pp +In LibreSSL, if +.Fa new_tail +is not at the beginning of its chain, +the head of that chain up to but not including +.Fa new_tail +is cut off and becomes a separate chain, +and if +.Fa b +is not at the end of its chain, +the tail of that chain starting after +.Fa b +is cut off and becomes a separate chain. +.Pp +For portability, it is best to make sure that +.Fa b +is at the end of its chain and that +.Fa new_tail +is at the beginning of its chain before calling +.Fn BIO_set_next +and to avoid calling +.Fn BIO_pop +on +.Fa new_tail +afterwards. +.Pp +In LibreSSL, the only built-in BIO type for which +.Xr BIO_ctrl 3 +calls with an argument of +.Dv BIO_CTRL_PUSH +or +.Dv BIO_CTRL_POP +have any effect is +.Xr BIO_f_ssl 3 . +.Sh RETURN VALUES +.Fn BIO_push +returns +.Fa b +if it is not +.Dv NULL +or +.Fa new_tail +if it is. +.Pp +.Fn BIO_pop +returns the BIO that followed +.Fa b +in its chain, or +.Dv NULL +if +.Fa b +is +.Dv NULL +or was at the end of its chain. +.Sh EXAMPLES +For these examples suppose +.Sy md1 +and +.Sy md2 +are digest BIOs, +.Sy b64 +is a Base64 BIO and +.Sy f +is a file BIO (see +.Xr BIO_f_md 3 , +.Xr BIO_f_base64 3 , +and +.Xr BIO_s_file 3 , +respectively). +.Pp +If the call +.Pp +.Dl BIO_push(b64, f); +.Pp +is made then the new chain will be +.Sy b64-f . +After making the calls +.Bd -literal -offset indent +BIO_push(md2, b64); +BIO_push(md1, md2); +.Ed +.Pp +the new chain is +.Sy md1-md2-b64-f . +Data written to +.Sy md1 +will be digested +by +.Sy md1 +and +.Sy md2 , +Base64-encoded and written to +.Sy f . +.Pp +It should be noted that reading causes data to pass +in the reverse direction. +That is, data is read from +.Sy f , +Base64-decoded and digested by +.Sy md1 +and +.Sy md2 . +If this call is made: +.Pp +.Dl BIO_pop(md2); +.Pp +The call will return +.Sy b64 +and the new chain will be +.Sy md1-b64-f ; +data can be written to +.Sy md1 +as before. +.Sh SEE ALSO +.Xr BIO_find_type 3 , +.Xr BIO_new 3 , +.Xr BIO_read 3 +.Sh HISTORY +.Fn BIO_push +first appeared in SSLeay 0.6.0. +.Fn BIO_pop +first appeared in SSLeay 0.6.4. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_set_next +first appeared in OpenSSL 1.1.0 +and has been available since +.Ox 7.1 . +.Sh CAVEATS +Creating a cyclic chain results in undefined behavior. +For example, infinite recursion or infinite loops may ensue. +.Pp +If it is unknown whether +.Fa b +and +.Fa new_tail +are already members of the same chain and whether joining them would +create a cycle, the calling code can use the following safe idiom: +.Bd -literal -offset indent +BIO *btest; + +for (btest = new_tail; btest != NULL; btest = BIO_next(btest)) + if (btest == b) + /* Bail out because this would create a cycle. */ +BIO_push(b, new_tail); /* This is now safe. */ +.Ed +.Pp +The same idiom can be used with +.Fn BIO_set_next +instead of +.Fn BIO_push . +.Pp +Often, the safe idiom is not needed because it is already known that +.Fa b +and +.Fa new_tail +are not members of the same chain, for example when +.Fa b +or +.Fa new_tail +was created right before. diff --git a/Libraries/libressl/man/BIO_read.3 b/Libraries/libressl/man/BIO_read.3 new file mode 100644 index 000000000..5fea9f728 --- /dev/null +++ b/Libraries/libressl/man/BIO_read.3 @@ -0,0 +1,281 @@ +.\" $OpenBSD: BIO_read.3,v 1.11 2022/12/18 17:40:55 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 18 2022 $ +.Dt BIO_READ 3 +.Os +.Sh NAME +.Nm BIO_read , +.Nm BIO_number_read , +.Nm BIO_gets , +.Nm BIO_write , +.Nm BIO_puts , +.Nm BIO_indent , +.Nm BIO_number_written +.Nd BIO I/O functions +.Sh SYNOPSIS +.In openssl/bio.h +.Ft int +.Fo BIO_read +.Fa "BIO *b" +.Fa "void *buf" +.Fa "int len" +.Fc +.Ft unsigned long +.Fo BIO_number_read +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_gets +.Fa "BIO *b" +.Fa "char *buf" +.Fa "int size" +.Fc +.Ft int +.Fo BIO_write +.Fa "BIO *b" +.Fa "const void *buf" +.Fa "int len" +.Fc +.Ft int +.Fo BIO_puts +.Fa "BIO *b" +.Fa "const char *string" +.Fc +.Ft int +.Fo BIO_indent +.Fa "BIO *b" +.Fa "int indent" +.Fa "int max" +.Fc +.Ft unsigned long +.Fo BIO_number_written +.Fa "BIO *b" +.Fc +.Sh DESCRIPTION +.Fn BIO_read +attempts to read +.Fa len +bytes from +.Fa b +and places the data in +.Fa buf . +.Pp +.Fn BIO_number_read +returns the grand total of bytes read from +.Fa b +using +.Fn BIO_read +so far. +Bytes read with +.Fn BIO_gets +do +.Sy not +count. +.Xr BIO_new 3 +and +.Xr BIO_set 3 +initialize the counter to 0. +When reading very large amounts of data, +the counter will eventually wrap around from +.Dv ULONG_MAX +to 0. +.Pp +.Fn BIO_gets +performs the BIOs "gets" operation and places the data in +.Fa buf . +Usually this operation will attempt to read a line of data +from the BIO of maximum length +.Fa size No \- 1 . +There are exceptions to this however, for example +.Fn BIO_gets +on a digest BIO will calculate and return the digest +and other BIOs may not support +.Fn BIO_gets +at all. +The returned string is always NUL-terminated. +.Pp +.Fn BIO_write +attempts to write +.Fa len +bytes from +.Fa buf +to +.Fa b . +.Pp +.Fn BIO_puts +attempts to write the NUL-terminated +.Fa string +to +.Fa b . +.Pp +.Fn BIO_indent +attempts to write +.Fa indent +space characters to +.Fa b , +but not more than +.Fa max +characters. +.Pp +.Fn BIO_number_written +returns the grand total of bytes written to +.Fa b +using +.Fn BIO_write , +.Fn BIO_puts , +and +.Fn BIO_indent +so far. +.Xr BIO_new 3 +and +.Xr BIO_set 3 +initialize the counter to 0. +When writing very large amounts of data, +the counter will eventually wrap around from +.Dv ULONG_MAX +to 0. +.Pp +One technique sometimes used with blocking sockets +is to use a system call (such as +.Xr select 2 , +.Xr poll 2 +or equivalent) to determine when data is available and then call +.Xr read 2 +to read the data. +The equivalent with BIOs (that is call +.Xr select 2 +on the underlying I/O structure and then call +.Fn BIO_read +to read the data) should +.Em not +be used because a single call to +.Fn BIO_read +can cause several reads (and writes in the case of SSL BIOs) +on the underlying I/O structure and may block as a result. +Instead +.Xr select 2 +(or equivalent) should be combined with non-blocking I/O +so successive reads will request a retry instead of blocking. +.Pp +See +.Xr BIO_should_retry 3 +for details of how to determine the cause of a retry and other I/O issues. +.Pp +If the +.Fn BIO_gets +function is not supported by a BIO then it is possible to +work around this by adding a buffering BIO +.Xr BIO_f_buffer 3 +to the chain. +.Sh RETURN VALUES +.Fn BIO_indent +returns 1 if successful, even if nothing was written, +or 0 if writing fails. +.Pp +.Fn BIO_number_read +and +.Fn BIO_number_written +return a number of bytes or 0 if +.Fa b +is a +.Dv NULL +pointer. +.Pp +The other functions return either the amount of data successfully +read or written (if the return value is positive) or that no data +was successfully read or written if the result is 0 or \-1. +If the return value is \-2, then the operation is not implemented +in the specific BIO type. +The trailing NUL is not included in the length returned by +.Fn BIO_gets . +.Pp +A 0 or \-1 return is not necessarily an indication of an error. +In particular when the source/sink is non-blocking or of a certain type +it may merely be an indication that no data is currently available and that +the application should retry the operation later. +.Sh SEE ALSO +.Xr BIO_meth_new 3 , +.Xr BIO_new 3 , +.Xr BIO_should_retry 3 +.Sh HISTORY +.Fn BIO_read , +.Fn BIO_gets , +.Fn BIO_write , +and +.Fn BIO_puts +first appeared in SSLeay 0.6.0. +.Fn BIO_number_read +and +.Fn BIO_number_written +first appeared in SSLeay 0.6.5. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_indent +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.4 . diff --git a/Libraries/libressl/man/BIO_s_accept.3 b/Libraries/libressl/man/BIO_s_accept.3 new file mode 100644 index 000000000..8e88fe1c5 --- /dev/null +++ b/Libraries/libressl/man/BIO_s_accept.3 @@ -0,0 +1,414 @@ +.\" $OpenBSD: BIO_s_accept.3,v 1.16 2023/04/29 13:06:10 schwarze Exp $ +.\" full merge up to: OpenSSL c03726ca Thu Aug 27 12:28:08 2015 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2014, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2023 $ +.Dt BIO_S_ACCEPT 3 +.Os +.Sh NAME +.Nm BIO_s_accept , +.Nm BIO_set_accept_port , +.Nm BIO_get_accept_port , +.Nm BIO_new_accept , +.Nm BIO_set_nbio_accept , +.Nm BIO_set_accept_bios , +.Nm BIO_set_bind_mode , +.Nm BIO_get_bind_mode , +.Nm BIO_do_accept +.Nd accept BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_accept +.Fa void +.Fc +.Ft long +.Fo BIO_set_accept_port +.Fa "BIO *b" +.Fa "char *name" +.Fc +.Ft char * +.Fo BIO_get_accept_port +.Fa "BIO *b" +.Fc +.Ft BIO * +.Fo BIO_new_accept +.Fa "const char *host_port" +.Fc +.Ft long +.Fo BIO_set_nbio_accept +.Fa "BIO *b" +.Fa "int n" +.Fc +.Ft long +.Fo BIO_set_accept_bios +.Fa "BIO *b" +.Fa "char *bio" +.Fc +.Ft long +.Fo BIO_set_bind_mode +.Fa "BIO *b" +.Fa "long mode" +.Fc +.Ft long +.Fo BIO_get_bind_mode +.Fa "BIO *b" +.Fa "long dummy" +.Fc +.Fd #define BIO_BIND_NORMAL 0 +.Fd #define BIO_BIND_REUSEADDR_IF_UNUSED 1 +.Fd #define BIO_BIND_REUSEADDR 2 +.Ft long +.Fo BIO_do_accept +.Fa "BIO *b" +.Fc +.Sh DESCRIPTION +.Fn BIO_s_accept +returns the accept BIO method. +This is a wrapper round the platform's TCP/IP socket +.Xr accept 2 +routines. +.Pp +Using accept BIOs, TCP/IP connections can be accepted +and data transferred using only BIO routines. +In this way any platform specific operations +are hidden by the BIO abstraction. +.Pp +Read and write operations on an accept BIO +will perform I/O on the underlying connection. +If no connection is established and the port (see below) is set up +properly then the BIO waits for an incoming connection. +.Pp +Accept BIOs support +.Xr BIO_puts 3 +but not +.Xr BIO_gets 3 . +.Pp +If the close flag is set on an accept BIO, then any active +connection on that chain is shut down and the socket closed when +the BIO is freed. +.Pp +Calling +.Xr BIO_reset 3 +on an accept BIO will close any active connection and reset the BIO +into a state where it awaits another incoming connection. +.Pp +.Xr BIO_get_fd 3 +and +.Xr BIO_set_fd 3 +can be called to retrieve or set the accept socket. +See +.Xr BIO_s_fd 3 . +.Pp +.Fn BIO_set_accept_port +uses the string +.Fa name +to set the accept port. +The port is represented as a string of the form +.Ar host : Ns Ar port , +where +.Ar host +is the interface to use and +.Ar port +is the port. +The host can be +.Qq * , +which is interpreted as meaning any interface; +.Ar port +has the same syntax as the port specified in +.Xr BIO_set_conn_port 3 +for connect BIOs. +It can be a numerical port string or a string to look up using +.Xr getservbyname 3 +and a string table. +.Pp +.Fn BIO_new_accept +combines +.Xr BIO_new 3 +and +.Fn BIO_set_accept_port +into a single call. +It creates a new accept BIO with port +.Fa host_port . +.Pp +.Fn BIO_set_nbio_accept +sets the accept socket to blocking mode (the default) if +.Fa n +is 0 or non-blocking mode if +.Fa n +is 1. +.Pp +.Fn BIO_set_accept_bios +can be used to set a chain of BIOs which will be duplicated +and prepended to the chain when an incoming connection is received. +This is useful if, for example, a buffering or SSL BIO +is required for each connection. +The chain of BIOs must not be freed after this call - +they will be automatically freed when the accept BIO is freed. +.Pp +.Fn BIO_set_bind_mode +and +.Fn BIO_get_bind_mode +set and retrieve the current bind mode. +If +.Dv BIO_BIND_NORMAL Pq the default +is set, then another socket cannot be bound to the same port. +If +.Dv BIO_BIND_REUSEADDR +is set, then other sockets can bind to the same port. +If +.Dv BIO_BIND_REUSEADDR_IF_UNUSED +is set, then an attempt is first made to use +.Dv BIO_BIN_NORMAL ; +if this fails and the port is not in use, +then a second attempt is made using +.Dv BIO_BIND_REUSEADDR . +.Pp +.Fn BIO_do_accept +serves two purposes. +When it is first called, after the accept BIO has been set up, +it will attempt to create the accept socket and bind an address to it. +Second and subsequent calls to +.Fn BIO_do_accept +will await an incoming connection, or request a retry in non-blocking mode. +.Sh NOTES +When an accept BIO is at the end of a chain, it will await an +incoming connection before processing I/O calls. +When an accept BIO is not at the end of a chain, +it passes I/O calls to the next BIO in the chain. +.Pp +When a connection is established, a new socket BIO is created +for the connection and appended to the chain. +That is the chain is now accept->socket. +This effectively means that attempting I/O on an initial accept +socket will await an incoming connection then perform I/O on it. +.Pp +If any additional BIOs have been set using +.Fn BIO_set_accept_bios , +then they are placed between the socket and the accept BIO; +that is, the chain will be accept->otherbios->socket. +.Pp +If a server wishes to process multiple connections (as is normally +the case), then the accept BIO must be made available for further +incoming connections. +This can be done by waiting for a connection and then calling: +.Pp +.Dl connection = BIO_pop(accept); +.Pp +After this call, +.Sy connection +will contain a BIO for the recently established connection and +.Sy accept +will now be a single BIO again which can be used +to await further incoming connections. +If no further connections will be accepted, the +.Sy accept +can be freed using +.Xr BIO_free 3 . +.Pp +If only a single connection will be processed, +it is possible to perform I/O using the accept BIO itself. +This is often undesirable however because the accept BIO +will still accept additional incoming connections. +This can be resolved by using +.Xr BIO_pop 3 +(see above) and freeing up the accept BIO after the initial connection. +.Pp +If the underlying accept socket is non-blocking and +.Fn BIO_do_accept +is called to await an incoming connection, it is possible for +.Xr BIO_should_io_special 3 +with the reason +.Dv BIO_RR_ACCEPT . +If this happens, then it is an indication that an accept attempt +would block: the application should take appropriate action +to wait until the underlying socket has accepted a connection +and retry the call. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +and +.Fa larg +arguments correspond to macros as follows: +.Bl -column BIO_C_DO_STATE_MACHINE larg BIO_get_accept_port(3) -offset 3n +.It Fa cmd No constant Ta Fa larg Ta corresponding macro +.It Dv BIO_C_DO_STATE_MACHINE Ta 0 Ta Fn BIO_do_accept +.It Dv BIO_C_GET_ACCEPT Ta 0 Ta Fn BIO_get_accept_port +.It Dv BIO_C_GET_BIND_MODE Ta 0 Ta Fn BIO_get_bind_mode +.It Dv BIO_C_GET_FD Ta 0 Ta Xr BIO_get_fd 3 +.It Dv BIO_C_SET_ACCEPT Ta 0 Ta Fn BIO_set_accept_port +.It Ta 1 Ta Fn BIO_set_nbio_accept +.It Ta 2 Ta Fn BIO_set_accept_bios +.It Dv BIO_C_SET_FD Ta Fa fd Ta Xr BIO_set_fd 3 +.It Dv BIO_C_SET_NBIO Ta Fa n Ta Xr BIO_set_nbio 3 +.It Dv BIO_C_SET_BIND_MODE Ta Fa mode Ta Fn BIO_set_bind_mode +.It Dv BIO_CTRL_GET_CLOSE Ta 0 Ta Xr BIO_get_close 3 +.It Dv BIO_CTRL_RESET Ta 0 Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_SET_CLOSE Ta Fa flag Ta Xr BIO_set_close 3 +.El +.Sh RETURN VALUES +When called on an accept BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_ACCEPT +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq socket accept . +.Pp +.Fn BIO_do_accept , +.Fn BIO_set_accept_port , +.Fn BIO_set_nbio_accept , +.Fn BIO_set_accept_bios , +and +.Fn BIO_set_bind_mode +return 1 for success or 0 or -1 for failure. +.Pp +.Fn BIO_get_accept_port +returns the port as a string or +.Dv NULL +on error. +.Pp +.Fn BIO_get_bind_mode +returns the set of BIO_BIND flags or -1 on failure. +.Pp +.Fn BIO_new_accept +returns a +.Vt BIO +or +.Dv NULL +on error. +.Sh EXAMPLES +This example accepts two connections on port 4444, +sends messages down each and finally closes both down. +.Bd -literal -offset 2n +BIO *abio, *cbio, *cbio2; +ERR_load_crypto_strings(); +abio = BIO_new_accept("4444"); + +/* First call to BIO_accept() sets up accept BIO */ +if (BIO_do_accept(abio) <= 0) { + fprintf(stderr, "Error setting up accept\en"); + ERR_print_errors_fp(stderr); + exit(0); +} + +/* Wait for incoming connection */ +if (BIO_do_accept(abio) <= 0) { + fprintf(stderr, "Error accepting connection\en"); + ERR_print_errors_fp(stderr); + exit(0); +} +fprintf(stderr, "Connection 1 established\en"); + +/* Retrieve BIO for connection */ +cbio = BIO_pop(abio); + +BIO_puts(cbio, "Connection 1: Sending out Data on initial connection\en"); +fprintf(stderr, "Sent out data on connection 1\en"); + +/* Wait for another connection */ +if (BIO_do_accept(abio) <= 0) { + fprintf(stderr, "Error accepting connection\en"); + ERR_print_errors_fp(stderr); + exit(0); +} +fprintf(stderr, "Connection 2 established\en"); + +/* Close accept BIO to refuse further connections */ +cbio2 = BIO_pop(abio); +BIO_free(abio); + +BIO_puts(cbio2, "Connection 2: Sending out Data on second\en"); +fprintf(stderr, "Sent out data on connection 2\en"); +BIO_puts(cbio, "Connection 1: Second connection established\en"); + +/* Close the two established connections */ +BIO_free(cbio); +BIO_free(cbio2); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_s_accept , +.Fn BIO_set_accept_port , +.Fn BIO_new_accept , +.Fn BIO_set_accept_bios , +and +.Fn BIO_do_accept +first appeared in SSLeay 0.8.0. +.Fn BIO_set_nbio_accept +and +.Fn BIO_get_accept_port +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_set_bind_mode +and +.Fn BIO_get_bind_mode +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/BIO_s_bio.3 b/Libraries/libressl/man/BIO_s_bio.3 new file mode 100644 index 000000000..b3e6c3d32 --- /dev/null +++ b/Libraries/libressl/man/BIO_s_bio.3 @@ -0,0 +1,426 @@ +.\" $OpenBSD: BIO_s_bio.3,v 1.19 2023/04/29 12:01:53 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by +.\" Lutz Jaenicke , +.\" Dr. Stephen Henson , +.\" Bodo Moeller , +.\" and Richard Levitte . +.\" Copyright (c) 2000, 2002, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2023 $ +.Dt BIO_S_BIO 3 +.Os +.Sh NAME +.Nm BIO_s_bio , +.Nm BIO_make_bio_pair , +.Nm BIO_destroy_bio_pair , +.Nm BIO_shutdown_wr , +.Nm BIO_set_write_buf_size , +.Nm BIO_get_write_buf_size , +.Nm BIO_new_bio_pair , +.Nm BIO_get_write_guarantee , +.Nm BIO_ctrl_get_write_guarantee , +.Nm BIO_get_read_request , +.Nm BIO_ctrl_get_read_request , +.Nm BIO_ctrl_reset_read_request +.\" The following non-copying I/O functions are intentionally undocumented +.\" because they seem fragile and unused by anything: +.\" .Nm BIO_nread0 +.\" .Nm BIO_nread +.\" .Nm BIO_nwrite0 +.\" .Nm BIO_nwrite +.\" .Nm BIO_C_NREAD0 +.\" .Nm BIO_C_NREAD +.\" .Nm BIO_C_NWRITE0 +.\" .Nm BIO_C_NWRITE +.Nd BIO pair BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_bio +.Fa void +.Fc +.Ft int +.Fo BIO_make_bio_pair +.Fa "BIO *b1" +.Fa "BIO *b2" +.Fc +.Ft int +.Fo BIO_destroy_bio_pair +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_shutdown_wr +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_set_write_buf_size +.Fa "BIO *b" +.Fa "long size" +.Fc +.Ft size_t +.Fo BIO_get_write_buf_size +.Fa "BIO *b" +.Fa "long size" +.Fc +.Ft int +.Fo BIO_new_bio_pair +.Fa "BIO **bio1" +.Fa "size_t writebuf1" +.Fa "BIO **bio2" +.Fa "size_t writebuf2" +.Fc +.Ft int +.Fo BIO_get_write_guarantee +.Fa "BIO *b" +.Fc +.Ft size_t +.Fo BIO_ctrl_get_write_guarantee +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_get_read_request +.Fa "BIO *b" +.Fc +.Ft size_t +.Fo BIO_ctrl_get_read_request +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_ctrl_reset_read_request +.Fa "BIO *b" +.Fc +.Sh DESCRIPTION +.Fn BIO_s_bio +returns the method for a BIO pair. +A BIO pair is a pair of source/sink BIOs where data written to either +half of the pair is buffered and can be read from the other half. +Both halves must usually be handled by the same application thread +since no locking is done on the internal data structures. +.Pp +Since BIO chains typically end in a source/sink BIO, +it is possible to make this one half of a BIO pair and +have all the data processed by the chain under application control. +.Pp +One typical use of BIO pairs is +to place TLS/SSL I/O under application control. +This can be used when the application wishes to use a non-standard +transport for TLS/SSL or the normal socket routines are inappropriate. +.Pp +Calls to +.Xr BIO_read 3 +will read data from the buffer or request a retry if no data is available. +.Pp +Calls to +.Xr BIO_write 3 +will place data in the buffer or request a retry if the buffer is full. +.Pp +The standard calls +.Xr BIO_ctrl_pending 3 +and +.Xr BIO_ctrl_wpending 3 +can be used to determine the amount of pending data +in the read or write buffer. +.Pp +.Xr BIO_reset 3 +clears any data in the write buffer. +.Pp +.Fn BIO_make_bio_pair +joins two separate BIOs into a connected pair. +.Pp +.Fn BIO_destroy_pair +destroys the association between two connected BIOs. +Freeing up any half of the pair will automatically destroy the association. +.Pp +.Fn BIO_shutdown_wr +is used to close down a BIO +.Fa b . +After this call no further writes on BIO +.Fa b +are allowed; they will return an error. +Reads on the other half of the pair will return any pending data +or EOF when all pending data has been read. +.Pp +.Fn BIO_set_write_buf_size +sets the write buffer size of BIO +.Fa b +to +.Fa size . +If the size is not initialized, a default value is used. +This is currently 17K, sufficient for a maximum size TLS record. +When a chain containing a BIO pair is copied with +.Xr BIO_dup_chain 3 , +the write buffer size is automatically copied +from the original BIO object to the new one. +.Pp +.Fn BIO_get_write_buf_size +returns the size of the write buffer. +.Pp +.Fn BIO_new_bio_pair +combines the calls to +.Xr BIO_new 3 , +.Fn BIO_make_bio_pair +and +.Fn BIO_set_write_buf_size +to create a connected pair of BIOs +.Fa bio1 +and +.Fa bio2 +with write buffer sizes +.Fa writebuf1 +and +.Fa writebuf2 . +If either size is zero, then the default size is used. +.Fn BIO_new_bio_pair +does not check whether +.Fa bio1 +or +.Fa bio2 +point to some other BIO; the values are overwritten and +.Xr BIO_free 3 +is not called. +.Pp +.Fn BIO_get_write_guarantee +and +.Fn BIO_ctrl_get_write_guarantee +return the maximum length of data +that can be currently written to the BIO. +Writes larger than this value will return a value from +.Xr BIO_write 3 +less than the amount requested or if the buffer is full request a retry. +.Fn BIO_ctrl_get_write_guarantee +is a function whereas +.Fn BIO_get_write_guarantee +is a macro. +.Pp +.Fn BIO_get_read_request +and +.Fn BIO_ctrl_get_read_request +return the amount of data requested, or the buffer size if it is less, +if the last read attempt at the other half of the BIO pair failed +due to an empty buffer. +This can be used to determine how much data should be +written to the BIO so the next read will succeed: +this is most useful in TLS/SSL applications where the amount of +data read is usually meaningful rather than just a buffer size. +After a successful read this call will return zero. +It also will return zero once new data has been written +satisfying the read request or part of it. +Note that +.Fn BIO_get_read_request +never returns an amount larger than that returned by +.Fn BIO_get_write_guarantee . +.Pp +.Fn BIO_ctrl_reset_read_request +can also be used to reset the value returned by +.Fn BIO_get_read_request +to zero. +.Pp +Both halves of a BIO pair should be freed. +Even if one half is implicitly freed due to a +.Xr BIO_free_all 3 +or +.Xr SSL_free 3 +call, the other half still needs to be freed. +.Pp +When used in bidirectional applications (such as TLS/SSL), +care should be taken to flush any data in the write buffer. +This can be done by calling +.Xr BIO_pending 3 +on the other half of the pair and, if any data is pending, +reading it and sending it to the underlying transport. +This must be done before any normal processing (such as calling +.Xr select 2 ) +due to a request and +.Xr BIO_should_read 3 +being true. +.Pp +To see why this is important, +consider a case where a request is sent using +.Xr BIO_write 3 +and a response read with +.Xr BIO_read 3 , +this can occur during a TLS/SSL handshake for example. +.Xr BIO_write 3 +will succeed and place data in the write buffer. +.Xr BIO_read 3 +will initially fail and +.Xr BIO_should_read 3 +will be true. +If the application then waits for data to become available +on the underlying transport before flushing the write buffer, +it will never succeed because the request was never sent. +.Pp +.Xr BIO_eof 3 +is true if no data is in the peer BIO and the peer BIO has been shutdown. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +arguments correspond to macros as follows: +.Bl -column BIO_C_GET_WRITE_GUARANTEE BIO_ctrl_reset_read_request() -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_DESTROY_BIO_PAIR Ta Fn BIO_destroy_bio_pair +.It Dv BIO_C_GET_READ_REQUEST Ta Fn BIO_get_read_request +.It Dv BIO_C_GET_WRITE_BUF_SIZE Ta Fn BIO_get_write_buf_size +.It Dv BIO_C_GET_WRITE_GUARANTEE Ta Fn BIO_get_write_guarantee +.It Dv BIO_C_MAKE_BIO_PAIR Ta Fn BIO_make_bio_pair +.It Dv BIO_C_RESET_READ_REQUEST Ta Fn BIO_ctrl_reset_read_request +.It Dv BIO_C_SET_WRITE_BUF_SIZE Ta Fn BIO_set_write_buf_size +.It Dv BIO_C_SHUTDOWN_WR Ta Fn BIO_shutdown_wr +.It Dv BIO_CTRL_EOF Ta Xr BIO_eof 3 +.It Dv BIO_CTRL_GET_CLOSE Ta Xr BIO_get_close 3 +.It Dv BIO_CTRL_PENDING Ta Xr BIO_pending 3 +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_SET_CLOSE Ta Xr BIO_set_close 3 +.It Dv BIO_CTRL_WPENDING Ta Xr BIO_wpending 3 +.El +.Sh RETURN VALUES +.Fn BIO_new_bio_pair +returns 1 on success, with the new BIOs available in +.Fa bio1 +and +.Fa bio2 , +or 0 on failure, with NULL pointers stored into the locations for +.Fa bio1 +and +.Fa bio2 . +Check the error stack for more information. +.Pp +When called on a BIO pair BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_BIO +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq BIO pair . +.\" XXX More return values need to be added here. +.Sh EXAMPLES +The BIO pair can be used to have full control +over the network access of an application. +The application can call +.Xr select 2 +on the socket as required without having to go through the SSL interface. +.Bd -literal -offset 2n +BIO *internal_bio, *network_bio; +\&... +BIO_new_bio_pair(&internal_bio, 0, &network_bio, 0); +SSL_set_bio(ssl, internal_bio, internal_bio); +SSL_operations(); /* e.g. SSL_read() and SSL_write() */ +\&... + +application | TLS-engine + | | + +----------> SSL_operations() + | /\e || + | || \e/ + | BIO-pair (internal_bio) + | BIO-pair (network_bio) + | || /\e + | \e/ || + +-----------< BIO_operations() + | | + socket | + +\&... +SSL_free(ssl); /* implicitly frees internal_bio */ +BIO_free(network_bio); +\&... +.Ed +.Pp +As the BIO pair will only buffer the data and never directly access +the connection, it behaves non-blocking and will return as soon as +the write buffer is full or the read buffer is drained. +Then the application has to flush the write buffer +and/or fill the read buffer. +.Pp +Use +.Xr BIO_ctrl_pending 3 +to find out whether data is buffered in the BIO +and must be transferred to the network. +Use +.Fn BIO_ctrl_get_read_request +to find out how many bytes must be written into the buffer before the +SSL operations can successfully be continued. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BIO_read 3 , +.Xr BIO_should_retry 3 , +.Xr ssl 3 , +.Xr SSL_set_bio 3 +.Sh HISTORY +.Fn BIO_s_bio , +.Fn BIO_make_bio_pair , +.Fn BIO_destroy_bio_pair , +.Fn BIO_set_write_buf_size , +.Fn BIO_get_write_buf_size , +.Fn BIO_new_bio_pair , +.Fn BIO_get_write_guarantee , +.Fn BIO_ctrl_get_write_guarantee , +.Fn BIO_get_read_request , +and +.Fn BIO_ctrl_reset_read_request +first appeared in OpenSSL 0.9.4 and have been available since +.Ox 2.6 . +.Pp +.Fn BIO_ctrl_reset_read_request +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn BIO_shutdown_wr +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Sh CAVEATS +As the data is buffered, SSL operations may return with an +.Dv ERROR_SSL_WANT_READ +condition, but there is still data in the write buffer. +An application must not rely on the error value of the SSL operation +but must assure that the write buffer is always flushed first. +Otherwise a deadlock may occur as the peer might be waiting +for the data before being able to continue. diff --git a/Libraries/libressl/man/BIO_s_connect.3 b/Libraries/libressl/man/BIO_s_connect.3 new file mode 100644 index 000000000..bce68a26b --- /dev/null +++ b/Libraries/libressl/man/BIO_s_connect.3 @@ -0,0 +1,503 @@ +.\" $OpenBSD: BIO_s_connect.3,v 1.19 2023/04/30 13:53:54 schwarze Exp $ +.\" full merge up to: OpenSSL 0e474b8b Nov 1 15:45:49 2015 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt BIO_S_CONNECT 3 +.Os +.Sh NAME +.Nm BIO_s_connect , +.Nm BIO_new_connect , +.Nm BIO_set_conn_hostname , +.Nm BIO_set_conn_port , +.Nm BIO_set_conn_ip , +.Nm BIO_set_conn_int_port , +.Nm BIO_get_conn_hostname , +.Nm BIO_get_conn_port , +.Nm BIO_get_conn_ip , +.Nm BIO_get_conn_int_port , +.Nm BIO_set_nbio , +.Nm BIO_do_connect +.Nd connect BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_connect +.Fa void +.Fc +.Ft BIO * +.Fo BIO_new_connect +.Fa "const char *name" +.Fc +.Ft long +.Fo BIO_set_conn_hostname +.Fa "BIO *b" +.Fa "char *name" +.Fc +.Ft long +.Fo BIO_set_conn_port +.Fa "BIO *b" +.Fa "char *port" +.Fc +.Ft long +.Fo BIO_set_conn_ip +.Fa "BIO *b" +.Fa "char *ip" +.Fc +.Ft long +.Fo BIO_set_conn_int_port +.Fa "BIO *b" +.Fa "char *port" +.Fc +.Ft char * +.Fo BIO_get_conn_hostname +.Fa "BIO *b" +.Fc +.Ft char * +.Fo BIO_get_conn_port +.Fa "BIO *b" +.Fc +.Ft char * +.Fo BIO_get_conn_ip +.Fa "BIO *b" +.Fc +.Ft long +.Fo BIO_get_conn_int_port +.Fa "BIO *b" +.Fc +.Ft long +.Fo BIO_set_nbio +.Fa "BIO *b" +.Fa "long n" +.Fc +.Ft long +.Fo BIO_do_connect +.Fa "BIO *b" +.Fc +.Sh DESCRIPTION +.Fn BIO_s_connect +returns the connect BIO method. +This is a wrapper around the platform's TCP/IP socket connection routines. +.Pp +Using connect BIOs, TCP/IP connections can be made and data +transferred using only BIO routines. +In this way any platform specific operations +are hidden by the BIO abstraction. +.Pp +Read and write operations on a connect BIO will perform I/O +on the underlying connection. +If no connection is established and the port and hostname (see below) +is set up properly, then a connection is established first. +.Pp +Connect BIOs support +.Xr BIO_puts 3 +but not +.Xr BIO_gets 3 . +.Pp +If the close flag is set on a connect BIO, then any active connection +is shutdown and the socket closed when the BIO is freed. +.Pp +Calling +.Xr BIO_reset 3 +on a connect BIO will close any active connection and reset the BIO +into a state where it can connect to the same host again. +.Pp +.Xr BIO_get_fd 3 +places the underlying socket in +.Fa c +if it is not +.Dv NULL +and also returns the socket. +If +.Fa c +is not +.Dv NULL , +it should be of type +.Vt "int *" . +.Pp +.Xr BIO_set_info_callback 3 +and +.Xr BIO_callback_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_SET_CALLBACK +save the pointer to the +.Fa cb +function internally in +.Fa b +and +.Xr BIO_get_info_callback 3 +retrieves this function pointer. +If such an info callback is installed, it is invoked whenever +a state change or error occurs in the connect BIO state machine. +The arguments of the callback include the new +.Fa state +in case of a state change or the old +.Fa state +in case of an error and the value +.Fa res +that the state machine would return to whatever operation invoked it +if no info callback had been installed. +If an info callback is installed, the state machine +returns the return value of the info callback instead. +Consequently, the info callback is supposed to usually return +.Fa res . +The precise effect of the return value depends on which operation +the state machine was invoked from. +Usually, \-1 is used to indicate failure and return values less than +or equal to zero abort the operation in question, whereas positive +values indicate success and allow the operation to proceed. +.Pp +The +.Fa state +constants passed to the callback are named according to +which operation needs to be performed next. +They are listed here in the order the states are passed through: +.Pp +.Bl -tag -width BIO_CONN_S_BLOCKED_CONNECT -offset 3n -compact +.It Dv BIO_CONN_S_BEFORE +The BIO is idle and no connection has been initiated yet. +.It Dv BIO_CONN_S_GET_IP +The hostname to connect to needs to be converted to an IP address. +.It Dv BIO_CONN_S_GET_PORT +The service name to connect to needs to be converted to a TCP port number. +.It Dv BIO_CONN_S_CREATE_SOCKET +The TCP socket needs to be created with the +.Xr socket 2 +system call. +.It Dv BIO_CONN_S_NBIO +Socket options may need to be set using +.Xr fcntl 2 +and +.Xr setsockopt 2 . +.It Dv BIO_CONN_S_CONNECT +The connection needs to be initiated with the +.Xr connect 2 +system call. +.It Dv BIO_CONN_S_BLOCKED_CONNECT +The +.Xr connect 2 +system call would have blocked and needs to be tried again. +.It Dv BIO_CONN_S_OK +The connection has been established and can now be used to transfer data. +.El +.Pp +.Fn BIO_set_conn_hostname +uses the string +.Fa name +to set the hostname. +The hostname can be an IP address. +The hostname can also include the port in the form +.Ar hostname : Ns Ar port . +It is also acceptable to use the forms +.Ar hostname Ns / Ns Pa any/other/path +or +.Ar hostname : Ns Ar port Ns / Ns Pa any/other/path . +.Pp +.Fn BIO_set_conn_port +sets the port to +.Fa port . +.Fa port +is looked up as a service using +.Xr getaddrinfo 3 . +.Pp +.Fn BIO_set_conn_ip +sets the IP address to +.Fa ip +using binary form i.e. four bytes specifying the IP address +in big-endian form. +.Pp +.Fn BIO_set_conn_int_port +sets the port using +.Fa port . +.Fa port +should +be of type +.Vt "int *" . +.Pp +.Fn BIO_get_conn_hostname +returns the hostname of the connect BIO or +.Dv NULL +if the BIO is initialized but no hostname is set. +This return value is an internal pointer which should not be modified. +.Pp +.Fn BIO_get_conn_port +returns the port as a string. +This return value is an internal pointer which should not be modified. +.Pp +.Fn BIO_get_conn_ip +returns the IP address in binary form. +.Pp +.Fn BIO_get_conn_int_port +returns the port as an +.Vt int . +.Pp +.Fn BIO_set_nbio +sets the non-blocking I/O flag to +.Fa n . +If +.Fa n +is zero then blocking I/O is set. +If +.Fa n +is 1 then non-blocking I/O is set. +Blocking I/O is the default. +The call to +.Fn BIO_set_nbio +should be made before the connection is established +because non-blocking I/O is set during the connect process. +.Pp +.Fn BIO_new_connect +combines +.Xr BIO_new 3 +and +.Fn BIO_set_conn_hostname +into a single call. +It creates a new connect BIO with +.Fa name . +.Pp +.Fn BIO_do_connect +attempts to connect the supplied BIO. +It returns 1 if the connection was established successfully. +A zero or negative value is returned if the connection +could not be established. +The call +.Xr BIO_should_retry 3 +should be used for non-blocking connect BIOs +to determine if the call should be retried. +.Pp +If blocking I/O is set then a non-positive return value from any +I/O call is caused by an error condition, although a zero return +will normally mean that the connection was closed. +.Pp +If the port name is supplied as part of the host name then this will +override any value set with +.Fn BIO_set_conn_port . +This may be undesirable if the application does not wish to allow +connection to arbitrary ports. +This can be avoided by checking for the presence of the +.Sq \&: +character in the passed hostname and either indicating an error +or truncating the string at that point. +.Pp +The values returned by +.Fn BIO_get_conn_hostname , +.Fn BIO_get_conn_port , +.Fn BIO_get_conn_ip , +and +.Fn BIO_get_conn_int_port +are updated when a connection attempt is made. +Before any connection attempt the values returned +are those set by the application itself. +.Pp +Applications do not have to call +.Fn BIO_do_connect +but may wish to do so to separate the connection process +from other I/O processing. +.Pp +If non-blocking I/O is set, +then retries will be requested as appropriate. +.Pp +In addition to +.Xr BIO_should_read 3 +and +.Xr BIO_should_write 3 +it is also possible for +.Xr BIO_should_io_special 3 +to be true during the initial connection process with the reason +.Dv BIO_RR_CONNECT . +If this is returned, it is an indication +that a connection attempt would block. +The application should then take appropriate action to wait +until the underlying socket has connected and retry the call. +.Pp +When a chain containing a connect BIO is copied with +.Xr BIO_dup_chain 3 , +.Fn BIO_set_conn_hostname , +.Fn BIO_set_conn_port , +.Fn BIO_set_nbio , +and +.Xr BIO_set_info_callback 3 +are called internally to automatically copy the hostname, port, +non-blocking I/O flag, and info callback from the original BIO object +to the new one. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +and +.Fa larg +arguments correspond to macros as follows: +.Bl -column BIO_C_DO_STATE_MACHINE larg BIO_get_conn_hostname(3) -offset 3n +.It Fa cmd No constant Ta Fa larg Ta corresponding macro +.It Dv BIO_C_DO_STATE_MACHINE Ta 0 Ta Fn BIO_do_connect +.It Dv BIO_C_GET_CONNECT Ta 0 Ta Fn BIO_get_conn_hostname +.It Ta 1 Ta Fn BIO_get_conn_port +.It Ta 2 Ta Fn BIO_get_conn_ip +.It Ta 3 Ta Fn BIO_get_conn_int_port +.It Dv BIO_C_GET_FD Ta 0 Ta Xr BIO_get_fd 3 +.It Dv BIO_C_SET_CONNECT Ta 0 Ta Fn BIO_set_conn_hostname +.It Ta 1 Ta Fn BIO_set_conn_port +.It Ta 2 Ta Fn BIO_set_conn_ip +.It Ta 3 Ta Fn BIO_set_conn_int_port +.It Dv BIO_C_SET_NBIO Ta Fa n Ta Fn BIO_set_nbio +.It Dv BIO_CTRL_GET_CLOSE Ta 0 Ta Xr BIO_get_close 3 +.It Dv BIO_CTRL_RESET Ta 0 Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_SET_CLOSE Ta Fa flag Ta Xr BIO_set_close 3 +.El +.Sh RETURN VALUES +.Fn BIO_s_connect +returns the connect BIO method. +.Pp +When called on a connect BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_CONNECT +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq socket connect . +.Pp +.Xr BIO_get_fd 3 +returns the socket or -1 if the BIO has not been initialized. +.Pp +.Fn BIO_set_conn_hostname , +.Fn BIO_set_conn_port , +.Fn BIO_set_conn_ip , +and +.Fn BIO_set_conn_int_port +always return 1. +.Pp +.Fn BIO_get_conn_hostname +returns the connected hostname or +.Dv NULL +if none is set. +.Pp +.Fn BIO_get_conn_port +returns a string representing the connected port or +.Dv NULL +if not set. +.Pp +.Fn BIO_get_conn_ip +returns a pointer to the connected IP address in binary form +or all zeros if not set. +.Pp +.Fn BIO_get_conn_int_port +returns the connected port or 0 if none was set. +.Pp +.Fn BIO_set_nbio +always returns 1. +.Pp +.Fn BIO_do_connect +returns 1 if the connection was successfully +established and 0 or -1 if the connection failed. +.Sh EXAMPLES +This example connects to a webserver on the local host and attempts +to retrieve a page and copy the result to standard output. +.Bd -literal -offset 2n +BIO *cbio, *out; +int len; +char tmpbuf[1024]; + +ERR_load_crypto_strings(); +cbio = BIO_new_connect("localhost:http"); +out = BIO_new_fp(stdout, BIO_NOCLOSE); +if (BIO_do_connect(cbio) <= 0) { + fprintf(stderr, "Error connecting to server\en"); + ERR_print_errors_fp(stderr); + /* whatever ... */ +} +BIO_puts(cbio, "GET / HTTP/1.0\en\en"); +for(;;) { + len = BIO_read(cbio, tmpbuf, 1024); + if (len <= 0) + break; + BIO_write(out, tmpbuf, len); +} +BIO_free(cbio); +BIO_free(out); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_s_connect , +.Fn BIO_new_connect , +.Fn BIO_set_nbio , +and +.Fn BIO_do_connect +first appeared in SSLeay 0.8.0. +.Fn BIO_set_conn_hostname , +.Fn BIO_set_conn_port , +.Fn BIO_set_conn_ip , +.Fn BIO_set_conn_int_port , +.Fn BIO_get_conn_hostname , +.Fn BIO_get_conn_port , +.Fn BIO_get_conn_ip , +and +.Fn BIO_get_conn_int_port +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_s_datagram.3 b/Libraries/libressl/man/BIO_s_datagram.3 new file mode 100644 index 000000000..104823e7a --- /dev/null +++ b/Libraries/libressl/man/BIO_s_datagram.3 @@ -0,0 +1,573 @@ +.\" $OpenBSD: BIO_s_datagram.3,v 1.3 2023/04/28 16:49:00 schwarze Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 28 2023 $ +.Dt BIO_S_DATAGRAM 3 +.Os +.Sh NAME +.Nm BIO_s_datagram , +.Nm BIO_new_dgram , +.Nm BIO_dgram_set_peer , +.Nm BIO_ctrl_dgram_connect , +.Nm BIO_dgram_get_peer , +.Nm BIO_ctrl_set_connected , +.Nm BIO_dgram_recv_timedout , +.Nm BIO_dgram_send_timedout , +.Nm BIO_dgram_non_fatal_error +.\" .Nm BIO_CTRL_DGRAM_QUERY_MTU and +.\" .Nm BIO_CTRL_DGRAM_MTU_DISCOVER are intentionally undocumented. +.\" They are almost unused, and OpenBSD does not appear to support them. +.Nd datagram socket BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fn BIO_s_datagram void +.Ft BIO * +.Fo BIO_new_dgram +.Fa "int fd" +.Fa "int close_flag" +.Fc +.Ft int +.Fo BIO_dgram_set_peer +.Fa "BIO *b" +.Fa "struct sockaddr *sa" +.Fc +.Ft int +.Fo BIO_ctrl_dgram_connect +.Fa "BIO *b" +.Fa "struct sockaddr *sa" +.Fc +.Ft int +.Fo BIO_dgram_get_peer +.Fa "BIO *b" +.Fa "struct sockaddr *sa" +.Fc +.Ft int +.Fo BIO_ctrl_set_connected +.Fa "BIO *b" +.Fa "long argl" +.Fa "struct sockaddr *sa" +.Fc +.Ft int +.Fn BIO_dgram_recv_timedout "BIO *b" +.Ft int +.Fn BIO_dgram_send_timedout "BIO *b" +.Ft int +.Fn BIO_dgram_non_fatal_error "int errnum" +.Sh DESCRIPTION +.Fn BIO_s_datagram +returns the datagram socket BIO method. +The usual application is to transmit data using the IPv4 or IPv6 +.Xr udp 4 +protocol. +.Pp +When called on a datagram socket BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_DGRAM +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq datagram socket . +.Ss Constructors and destructors +.Xr BIO_new 3 +allocates a new datagram socket BIO object and initializes all its data +to zero, including the datagram socket file descriptor, the peer address, +the init flag that can be retrieved with +.Xr BIO_get_init 3 , +the connected flag, the MTU, and all timeout and error information. +The reference count and the close flag are set to 1. +.Pp +.Fn BIO_new_dgram +allocates and initializes a new datagram socket BIO object with +.Xr BIO_new 3 , +sets the datagram socket file descriptor and the close flag +according to its arguments, and sets the init flag to 1. +.Pp +If the reference count reaches 0 in +.Xr BIO_free 3 +and the close and init flags are set, +.Xr shutdown 2 +and +.Xr close 2 +are called on the datagram socket file descriptor before freeing the +storage used by the BIO object. +.Pp +When a chain containing a datagram socket BIO is copied with +.Xr BIO_dup_chain 3 , +the datagram socket file descriptor, the init flag, the close flag, +the flags accessible with +.Xr BIO_test_flags 3 , +and any data that was set with +.Xr BIO_set_ex_data 3 +are automatically copied from the original BIO object to the new one, +but the peer address, the connected flag, the MTU and all timeout and +error information are not copied but instead initialized to zero. +.Ss Initialization and configuration +If the close flag is set in +.Fa b , +.Xr BIO_set_fd 3 +clears all flags that are set in +.Fa b +and if the init flag was set, it calls +.Xr shutdown 2 +and +.Xr close 2 +on the previously assigned file descriptor. +In any case, +.Xr BIO_set_fd 3 +then sets the new file descriptor and the new close flag according to +its arguments and sets the init flag to 1. +.Pp +If the init flag is set in +.Fa b , +.Xr BIO_get_fd 3 +returns its datagram socket file descriptor, and unless the +.Fa c +argument is a +.Dv NULL +pointer, it also stores the file descriptor in +.Pf * Fa c . +If the init flag is not set, +.Xr BIO_get_fd 3 +fails and returns \-1. +.Pp +.Xr BIO_set_close 3 +sets the close flag in +.Fa b +to the +.Fa flag +argument. +.Xr BIO_get_close 3 +returns the value of the close flag from +.Fa b . +.Pp +For datagram socket BIO objects, +the shutdown flag is the same flag as the close flag. +Consequently, +.Xr BIO_set_shutdown 3 +has the same effect as +.Xr BIO_set_close 3 +and +.Xr BIO_get_shutdown 3 +has the same effect as +.Xr BIO_get_close 3 . +.Pp +.Fn BIO_dgram_set_peer +copies +.Fa sa +as the peer address into +.Fa b . +.Pp +.Fn BIO_ctrl_dgram_connect +does exactly the same as +.Fn BIO_dgram_set_peer . +Its name is even more misleading than the name of +.Fn BIO_ctrl_set_connected . +In addition to what is said there, +.Fn BIO_ctrl_dgram_connect +does not even set the connected flag in +.Fa b . +.Pp +.Fn BIO_dgram_get_peer +copies the peer address from +.Fa b +to +.Pf * Fa sa . +Before calling this function, the caller has to make sure +that the peer address is indeed set in +.Fa b +and that sufficient memory is available starting at +.Fa sa +to copy a complete +.Vt struct sockaddr , +.Vt struct sockaddr_in , +or +.Vt struct sockaddr_in6 +to that place, depending on which address family +.Fa b +is currently used for. +.Pp +Unless +.Fa sa +is +.Dv NULL , +.Fn BIO_ctrl_set_connected +sets the connected flag in +.Fa b +and copies +.Fa sa +as the peer address into +.Fa b . +If +.Fa sa +is +.Dv NULL , +.Fn BIO_ctrl_set_connected +clears the connected flag and the peer address in +.Fa b . +Considering that communication using a datagram protocol is connectionless, +the name of this function is misleading. +It is neither establishing or terminating a connection nor changing +anything with respect to the state of the datagram socket, but merely +modifying some purely informational data in the wrapping BIO object. +The additional +.Fa argl +argument is passed through to the callbacks documented in +.Xr BIO_set_callback 3 +if any such callbacks are installed, but it is otherwise ignored. +.Pp +.Xr BIO_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT +interprets the +.Fa parg +argument as a pointer to a +.Vt struct timeval +and sets the read timeout to the specified absolute UTC time. +.Pp +.Xr BIO_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_DGRAM_SET_RECV_TIMEOUT , +.Dv BIO_CTRL_DGRAM_GET_RECV_TIMEOUT , +.Dv BIO_CTRL_DGRAM_SET_SEND_TIMEOUT , +or +.Dv BIO_CTRL_DGRAM_GET_SEND_TIMEOUT +interprets the +.Fa parg +argument as a pointer to a +.Vt struct timeval +and calls +.Xr setsockopt 2 +or +.Xr getsockopt 2 +on the datagram socket file descriptor of +.Fa b +with an argument of +.Dv SO_RCVTIMEO +or +.Dv SO_SNDTIMEO , +respectively. +.Dv BIO_CTRL_DGRAM_SET_RECV_TIMEOUT +and +.Dv BIO_CTRL_DGRAM_SET_SEND_TIMEOUT +return 1 on success, +.Dv BIO_CTRL_DGRAM_GET_RECV_TIMEOUT +and +.Dv BIO_CTRL_DGRAM_GET_SEND_TIMEOUT +the number of bytes written to +.Pf * Fa parg . +All four return \-1 on failure. +Remember that +.Xr BIO_read 3 +may actually use a shorter timeout when +.Dv BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT +is in effect. +.Pp +.Xr BIO_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_DGRAM_GET_FALLBACK_MTU +returns 1232 if the peer address is an IPv6 address that is not IPv4 mapped +or 548 otherwise. +Making sure that a peer address is set before issuing this command +is the responsibility of the caller. +.Pp +.Xr BIO_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_DGRAM_SET_MTU +sets the MTU attribute of +.Fa b +to the value of the +.Fa larg +argument and also returns that argument. +.Xr BIO_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_DGRAM_GET_MTU +returns the MTU attribute of +.Fa b +or 0 if it was not set. +.Pp +.Xr BIO_ctrl 3 +with a +.Fa cmd +of +.Dv BIO_CTRL_DGRAM_MTU_EXCEEDED +returns 1 if the most recent non-fatal failure of +.Xr BIO_read 3 +or +.Xr BIO_write 3 +was caused by +.Er EMSGSIZE +or 0 otherwise. +This command also clears the +.Xr errno 2 +value that was saved internally for this particular purpose, so that +issuing the same command again will return 0 until the next +.Er EMSGSIZE +failure occurs. +.Pp +.Fn BIO_dgram_recv_timedout +and +.Fn BIO_dgram_send_timedout +check whether the most recent non-fatal failure of +.Xr BIO_read 3 +or +.Xr BIO_write 3 +was caused by +.Er EAGAIN . +Despite having different names, both functions do exactly the same, +and both inspect the most recent non-fatal I/O failure, no matter +whether it occurred during a receive or send operation. +Both functions also clear the +.Xr errno 2 +value that was saved internally for this particular purpose, +so that calling these functions again will return 0 until the next +.Er EAGAIN +failure occurs. +.Pp +Datagram socket BIOs do not support +.Xr BIO_eof 3 , +.Xr BIO_get_mem_data 3 , +.Xr BIO_pending 3 , +.Xr BIO_reset 3 , +.Xr BIO_seek 3 , +.Xr BIO_tell 3 , +and +.Xr BIO_wpending 3 , +and attempting any such operation results in failure +and returns a value of 0. +.Pp +Control commands correspond to accessor functions as follows: +.Pp +.Bl -tag -width BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP -compact +.It Dv BIO_C_GET_FD +.Xr BIO_get_fd 3 +.It Dv BIO_C_SET_FD +.Xr BIO_set_fd 3 +.It Dv BIO_CTRL_DGRAM_CONNECT +.Fn BIO_ctrl_dgram_connect Pq deprecated +.It Dv BIO_CTRL_DGRAM_GET_PEER +.Fn BIO_dgram_get_peer +.It BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP +.Fn BIO_dgram_recv_timedout +.It BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP +.Fn BIO_dgram_send_timedout +.It Dv BIO_CTRL_DGRAM_SET_CONNECTED +.Fn BIO_ctrl_set_connected +.It Dv BIO_CTRL_DGRAM_SET_PEER +.Fn BIO_dgram_set_peer +.It Dv BIO_CTRL_GET_CLOSE +.Xr BIO_get_close 3 +.It Dv BIO_CTRL_SET_CLOSE +.Xr BIO_set_close 3 +.El +.Ss Input and output operations +.Xr BIO_read 3 +attempts to read up to +.Fa len +bytes into +.Fa buf +from the datagram socket file descriptor using +.Xr recvfrom 2 . +If a read timeout is set, +.Xr setsockopt 2 +is used with an argument of +.Dv SO_RCVTIMEO +to temporarily shorten the timeout on the datagram socket during the +.Xr recvfrom 2 +call such that it returns before the read timeout expires. +.Pp +If +.Xr recvfrom 2 +succeeds and the connected flag is not yet set, +.Xr BIO_read 3 +also copies the peer address received from +.Xr recvfrom 2 +into +.Fa b . +.Pp +If +.Xr recvfrom 2 +is attempted, +.Xr BIO_read 3 +clears the flags +.Dv BIO_FLAGS_WRITE +and +.Dv BIO_FLAGS_IO_SPECIAL +in +.Fa b +and clears or sets the flags +.Dv BIO_FLAGS_READ +and +.Dv BIO_FLAGS_SHOULD_RETRY +as appropriate. +.Pp +If the connected flag is set in +.Fa b , +.Xr BIO_write 3 +attempts to +.Xr write 2 +.Fa len +bytes from +.Fa buf +to the datagram socket file descriptor. +If the connected flag is not set, it attempts to transmit +.Fa len +bytes from +.Fa buf +to the peer using +.Xr sendto 2 . +.Pp +If +.Xr write 2 +or +.Xr sendto 2 +is attempted, +.Xr BIO_write 3 +clears the flags +.Dv BIO_FLAGS_READ +and +.Dv BIO_FLAGS_IO_SPECIAL +in +.Fa b +and clears or sets the flags +.Dv BIO_FLAGS_WRITE +and +.Dv BIO_FLAGS_SHOULD_RETRY +as appropriate. +.Pp +The effect of +.Xr BIO_puts 3 +is similar to the effect of +.Xr BIO_write 3 +with a +.Fa len +argument of +.Fn strlen string . +.Pp +Datagram socket BIOs do not support +.Xr BIO_gets 3 . +Calling this function fails and returns \-2. +.Pp +.Xr BIO_flush 3 +has no effect on a datagram socket BIO. +It always succeeds and returns 1. +.Sh RETURN VALUES +.Fn BIO_s_datagram +returns the datagram socket BIO method. +.Pp +.Fn BIO_new_dgram +returns a newly allocated datagram socket BIO object or +.Dv NULL +on failure. +.Pp +.Fn BIO_dgram_set_peer , +.Fn BIO_ctrl_dgram_connect , +and +.Fn BIO_ctrl_set_connected +return 1 on success or a value less than or equal to zero on failure. +They can only fail if +.Fa b +is not a datagram socket BIO object. +.Pp +.Fn BIO_dgram_get_peer +returns the number of bytes copied to +.Fa sa +or a value less than or equal to zero on failure. +It can only fail if +.Fa b +is not a datagram socket BIO object. +.Pp +.Fn BIO_dgram_recv_timedout +and +.Fn BIO_dgram_send_timedout +return 1 if the most recent non-fatal I/O error was caused by +.Er EAGAIN +or 0 otherwise. +.Pp +.Fn BIO_dgram_non_fatal_error +returns 1 if +.Fa errnum +is +.Er EAGAIN , +.Er EALREADY , +.Er EINPROGRESS , +or +.Er EINTR +or 0 otherwise, even if +.Fa errnum +is 0. +.Sh SEE ALSO +.Xr close 2 , +.Xr getsockopt 2 , +.Xr recvfrom 2 , +.Xr sendto 2 , +.Xr shutdown 2 , +.Xr BIO_ctrl 3 , +.Xr BIO_get_init 3 , +.Xr BIO_new 3 , +.Xr BIO_read 3 , +.Xr BIO_s_connect 3 , +.Xr BIO_set_fd 3 , +.Xr BIO_should_retry 3 , +.Xr udp 4 +.Sh HISTORY +.Fn BIO_s_datagram , +.Fn BIO_new_dgram , +.Fn BIO_dgram_set_peer , +.Fn BIO_ctrl_dgram_connect , +.Fn BIO_ctrl_set_connected , +.Fn BIO_dgram_recv_timedout , +.Fn BIO_dgram_send_timedout , +and +.Fn BIO_dgram_non_fatal_error +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn BIO_dgram_get_peer +first appeared in OpenSSL 0.9.8m and has been available since +.Ox 4.9 . +.Sh BUGS +If +.Xr getsockopt 2 +or +.Xr setsockopt 2 +fails during +.Xr BIO_read 3 , +the library prints an error message to standard error output +but otherwise ignores the problem, thus possibly using unintended +timeout values. +.Pp +.Xr BIO_read 3 +and +.Xr BIO_write 3 +may clear the global variable +.Xr errno 2 +before attempting the +.Xr recvfrom 2 +or +.Xr sendto 2 +system call but may not clear it if they fail before reaching this point. diff --git a/Libraries/libressl/man/BIO_s_fd.3 b/Libraries/libressl/man/BIO_s_fd.3 new file mode 100644 index 000000000..de5d5d700 --- /dev/null +++ b/Libraries/libressl/man/BIO_s_fd.3 @@ -0,0 +1,292 @@ +.\" $OpenBSD: BIO_s_fd.3,v 1.12 2023/04/29 12:04:54 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2023 $ +.Dt BIO_S_FD 3 +.Os +.Sh NAME +.Nm BIO_s_fd , +.Nm BIO_set_fd , +.Nm BIO_get_fd , +.Nm BIO_new_fd , +.Nm BIO_fd_non_fatal_error , +.Nm BIO_fd_should_retry +.Nd file descriptor BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_fd +.Fa "void" +.Fc +.Ft long +.Fo BIO_set_fd +.Fa "BIO *b" +.Fa "int fd" +.Fa "long close_flag" +.Fc +.Ft long +.Fo BIO_get_fd +.Fa "BIO *b" +.Fa "int *c" +.Fc +.Ft BIO * +.Fo BIO_new_fd +.Fa "int fd" +.Fa "int close_flag" +.Fc +.Ft int +.Fn BIO_fd_non_fatal_error "int errnum" +.Ft int +.Fn BIO_fd_should_retry "int retval" +.Sh DESCRIPTION +.Fn BIO_s_fd +returns the file descriptor BIO method. +This is a wrapper around the platform's file descriptor routines such as +.Xr read 2 +and +.Xr write 2 . +.Pp +.Xr BIO_read 3 +and +.Xr BIO_write 3 +read or write the underlying descriptor. +.Xr BIO_puts 3 +is supported but +.Xr BIO_gets 3 +is not. +.Pp +If the close flag is set, +.Xr close 2 +is called on the underlying file descriptor when the +.Vt BIO +is freed. +.Pp +.Xr BIO_reset 3 +attempts to set the file pointer to the start of the file using +.Fn lseek fd 0 0 . +.Pp +.Xr BIO_seek 3 +sets the file pointer to position +.Fa ofs +from start of file using +.Fn lseek fd ofs 0 . +.Pp +.Xr BIO_tell 3 +returns the current file position by calling +.Fn lseek fd 0 1 . +.Pp +.Fn BIO_set_fd +sets the file descriptor of +.Vt BIO +.Fa b +to +.Fa fd +and the close flag to +.Fa close_flag . +It is currently implemented as a macro. +.Pp +.Fn BIO_get_fd +places the file descriptor in +.Fa c +if it is not +.Dv NULL +and also returns the file descriptor. +It is currently implemented as a macro. +.Pp +.Fn BIO_new_fd +returns a file descriptor BIO using +.Fa fd +and +.Fa close_flag . +.Pp +.Fn BIO_fd_non_fatal_error +determines whether the error status code +.Fa errnum +represents a recoverable error. +.Fn BIO_fd_should_retry +determines whether a recoverable error occurred by inspecting both +.Xr errno 2 +and +.Fa retval , +which is supposed to usually be +the return value of a previously called function like +.Xr BIO_read 3 +or +.Xr BIO_write 3 . +These two functions are mostly used internally; in application code, +it is usually easier and more robust to use +.Xr BIO_should_retry 3 , +which works for any BIO type. +.Pp +The behaviour of +.Xr BIO_read 3 +and +.Xr BIO_write 3 +depends on the behavior of the platform's +.Xr read 2 +and +.Xr write 2 +calls on the descriptor. +If the underlying file descriptor is in a non-blocking mode, +then the BIO will behave in the manner described in the +.Xr BIO_read 3 +and +.Xr BIO_should_retry 3 +manual pages. +.Pp +File descriptor BIOs should not be used for socket I/O. +Use socket BIOs instead. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +arguments correspond to macros as follows: +.Bl -column BIO_CTRL_GET_CLOSE BIO_get_close(3) -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_FILE_SEEK Ta Xr BIO_seek 3 +.It Dv BIO_C_FILE_TELL Ta Xr BIO_tell 3 +.It Dv BIO_C_GET_FD Ta Fn BIO_get_fd +.It Dv BIO_C_SET_FD Ta Fn BIO_set_fd +.It Dv BIO_CTRL_GET_CLOSE Ta Xr BIO_get_close 3 +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_SET_CLOSE Ta Xr BIO_set_close 3 +.El +.Sh RETURN VALUES +.Fn BIO_s_fd +returns the file descriptor BIO method. +.Pp +When called on a file descriptor BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_FD +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq file descriptor . +.Pp +.Fn BIO_set_fd +always returns 1. +.Pp +.Fn BIO_get_fd +returns the file descriptor or -1 if the +.Vt BIO +has not been initialized. +.Pp +.Fn BIO_new_fd +returns the newly allocated +.Vt BIO +or +.Dv NULL +if an error occurred. +.Pp +.Fn BIO_fd_non_fatal_error +returns 1 if +.Fa errnum +is +.Dv EAGAIN , +.Dv EALREADY , +.Dv EINPROGRESS , +.Dv EINTR , +or +.Dv ENOTCONN +and 0 otherwise, even if +.Fa errnum +is 0. +.Pp +.Fn BIO_fd_should_retry +returns 1 if +.Fn BIO_fd_non_fatal_error errno +is 1 and +.Fa retval +is either 0 or \-1, or 0 otherwise. +.Sh EXAMPLES +This is a file descriptor BIO version of "Hello World": +.Bd -literal -offset indent +BIO *out; +out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE); +BIO_printf(out, "Hello World\en"); +BIO_free(out); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BIO_read 3 , +.Xr BIO_s_socket 3 , +.Xr BIO_seek 3 , +.Xr BIO_should_retry 3 +.Sh HISTORY +.Fn BIO_s_fd , +.Fn BIO_set_fd , +and +.Fn BIO_get_fd +first appeared in SSLeay 0.6.0, +.Fn BIO_fd_should_retry +in SSLeay 0.6.5, and +.Fn BIO_new_fd +and +.Fn BIO_fd_non_fatal_error +in SSLeay 0.8.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_s_file.3 b/Libraries/libressl/man/BIO_s_file.3 new file mode 100644 index 000000000..7b5890312 --- /dev/null +++ b/Libraries/libressl/man/BIO_s_file.3 @@ -0,0 +1,379 @@ +.\" $OpenBSD: BIO_s_file.3,v 1.16 2023/05/01 07:04:38 jsg Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" selective merge up to: OpenSSL 1212818e Sep 11 13:22:14 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2010 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt BIO_S_FILE 3 +.Os +.Sh NAME +.Nm BIO_s_file , +.Nm BIO_new_file , +.Nm BIO_new_fp , +.Nm BIO_set_fp , +.Nm BIO_get_fp , +.Nm BIO_read_filename , +.Nm BIO_write_filename , +.Nm BIO_append_filename , +.Nm BIO_rw_filename +.\" Nm BIO_CTRL_SET_FILENAME is unused and intentionally undocumented. +.Nd FILE BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_file +.Fa void +.Fc +.Ft BIO * +.Fo BIO_new_file +.Fa "const char *filename" +.Fa "const char *mode" +.Fc +.Ft BIO * +.Fo BIO_new_fp +.Fa "FILE *stream" +.Fa "int flags" +.Fc +.Ft long +.Fo BIO_set_fp +.Fa "BIO *b" +.Fa "FILE *fp" +.Fa "int flags" +.Fc +.Ft long +.Fo BIO_get_fp +.Fa "BIO *b" +.Fa "FILE **fpp" +.Fc +.Ft long +.Fo BIO_read_filename +.Fa "BIO *b" +.Fa "char *name" +.Fc +.Ft long +.Fo BIO_write_filename +.Fa "BIO *b" +.Fa "char *name" +.Fc +.Ft long +.Fo BIO_append_filename +.Fa "BIO *b" +.Fa "char *name" +.Fc +.Ft long +.Fo BIO_rw_filename +.Fa "BIO *b" +.Fa "char *name" +.Fc +.Sh DESCRIPTION +.Fn BIO_s_file +returns the BIO file method. +As its name implies, it is a wrapper around the stdio +.Vt FILE +structure and it is a source/sink BIO. +.Pp +Calls to +.Xr BIO_read 3 +and +.Xr BIO_write 3 +read and write data to the underlying stream. +.Xr BIO_gets 3 +and +.Xr BIO_puts 3 +are supported on file BIOs. +.Pp +.Xr BIO_flush 3 +on a file BIO calls the +.Xr fflush 3 +function on the wrapped stream. +.Pp +.Xr BIO_reset 3 +attempts to change the file pointer to the start of file using +.Fn fseek stream 0 0 . +.Pp +.Xr BIO_seek 3 +sets the file pointer to position +.Fa ofs +from the start of the file using +.Fn fseek stream ofs 0 . +.Pp +.Xr BIO_eof 3 +calls +.Xr feof 3 . +.Pp +Setting the +.Dv BIO_CLOSE +flag calls +.Xr fclose 3 +on the stream when the BIO is freed. +.Pp +.Fn BIO_new_file +creates a new file BIO with mode +.Fa mode . +The meaning of +.Fa mode +is the same as for the stdio function +.Xr fopen 3 . +The +.Dv BIO_CLOSE +flag is set on the returned BIO. +.Pp +.Fn BIO_new_fp +creates a file BIO wrapping +.Fa stream . +Flags can be: +.Dv BIO_CLOSE , BIO_NOCLOSE Pq the close flag , +.Dv BIO_FP_TEXT +(sets the underlying stream to text mode, default is binary: +this only has any effect under Win32). +.Pp +.Fn BIO_set_fp +sets the file pointer of a file BIO to +.Fa fp . +.Fa flags +has the same meaning as in +.Fn BIO_new_fp . +.Fn BIO_set_fp +is a macro. +.Pp +.Fn BIO_get_fp +retrieves the file pointer of a file BIO, it is a macro. +.Pp +.Xr BIO_seek 3 +is a macro that sets the position pointer to +.Fa offset +bytes from the start of file. +.Pp +.Xr BIO_tell 3 +returns the value of the position pointer. +.Pp +.Fn BIO_read_filename , +.Fn BIO_write_filename , +.Fn BIO_append_filename , +and +.Fn BIO_rw_filename +set the file BIO +.Fa b +to use file +.Fa name +for reading, writing, append or read write respectively. +.Pp +When wrapping stdout, stdin, or stderr, the underlying stream +should not normally be closed, so the +.Dv BIO_NOCLOSE +flag should be set. +.Pp +Because the file BIO calls the underlying stdio functions, any quirks +in stdio behaviour will be mirrored by the corresponding BIO. +.Pp +On Windows, +.Fn BIO_new_files +reserves for the filename argument to be UTF-8 encoded. +In other words, if you have to make it work in a multi-lingual +environment, encode file names in UTF-8. +.Pp +The following +.Xr BIO_ctrl 3 +.Fa cmd +constants correspond to macros: +.Bl -column BIO_C_GET_FILE_PTR "corresponding macro" -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_FILE_SEEK Ta Xr BIO_seek 3 +.It Dv BIO_C_FILE_TELL Ta Xr BIO_tell 3 +.It Dv BIO_C_GET_FILE_PTR Ta Fn BIO_get_fp +.It Dv BIO_C_SET_FILE_PTR Ta Fn BIO_set_fp +.It Dv BIO_C_SET_FILENAME Ta various, see below +.It Dv BIO_CTRL_EOF Ta Xr BIO_eof 3 +.It Dv BIO_CTRL_FLUSH Ta Xr BIO_flush 3 +.It Dv BIO_CTRL_GET_CLOSE Ta Xr BIO_get_close 3 +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_SET_CLOSE Ta Xr BIO_set_close 3 +.El +.Pp +The meaning of +.Dv BIO_C_SET_FILENAME +depends on the flags passed in the +.Xr BIO_ctrl 3 +.Fa larg +argument: +.Bl -column "BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE" "BIO_append_filename()"\ + -offset 3n +.It Fa larg No argument Ta corresponding macro +.It Dv BIO_CLOSE | BIO_FP_READ Ta Fn BIO_read_filename +.It Dv BIO_CLOSE | BIO_FP_WRITE Ta Fn BIO_write_filename +.It Dv BIO_CLOSE | BIO_FP_APPEND Ta Fn BIO_append_filename +.It Dv BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE Ta Fn BIO_rw_filename +.El +.Sh RETURN VALUES +.Fn BIO_s_file +returns the file BIO method. +.Pp +.Fn BIO_new_file +and +.Fn BIO_new_fp +return a file BIO or +.Dv NULL +if an error occurred. +.Pp +When called on a file BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_FILE +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq FILE pointer . +.Pp +.Fn BIO_set_fp +and +.Fn BIO_get_fp +return 1 for success or 0 for failure (although the current +implementation never returns 0). +.Pp +.Xr BIO_seek 3 +returns the same value as the underlying +.Xr fseek 3 +function: 0 for success or -1 for failure. +.Pp +.Xr BIO_tell 3 +returns the current file position. +.Pp +.Fn BIO_read_filename , +.Fn BIO_write_filename , +.Fn BIO_append_filename , +and +.Fn BIO_rw_filename +return 1 for success or 0 for failure. +.Sh EXAMPLES +File BIO "hello world": +.Bd -literal -offset indent +BIO *bio_out; +bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); +BIO_printf(bio_out, "Hello World\en"); +.Ed +.Pp +Alternative technique: +.Bd -literal -offset indent +BIO *bio_out; +bio_out = BIO_new(BIO_s_file()); +if(bio_out == NULL) /* Error ... */ +if(!BIO_set_fp(bio_out, stdout, BIO_NOCLOSE)) /* Error ... */ +BIO_printf(bio_out, "Hello World\en"); +.Ed +.Pp +Write to a file: +.Bd -literal -offset indent +BIO *out; +out = BIO_new_file("filename.txt", "w"); +if(!out) /* Error occurred */ +BIO_printf(out, "Hello World\en"); +BIO_free(out); +.Ed +.Pp +Alternative technique: +.Bd -literal -offset indent +BIO *out; +out = BIO_new(BIO_s_file()); +if(out == NULL) /* Error ... */ +if(!BIO_write_filename(out, "filename.txt")) /* Error ... */ +BIO_printf(out, "Hello World\en"); +BIO_free(out); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BIO_read 3 , +.Xr BIO_seek 3 +.Sh HISTORY +.Fn BIO_s_file , +.Fn BIO_set_fp , +.Fn BIO_get_fp , +.Fn BIO_read_filename , +.Fn BIO_write_filename , +and +.Fn BIO_append_filename +first appeared in SSLeay 0.6.0. +.Fn BIO_new_file +and +.Fn BIO_new_fp +first appeared in SSLeay 0.8.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_rw_filename +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . +.Sh BUGS +.Xr BIO_reset 3 +and +.Xr BIO_seek 3 +are implemented using +.Xr fseek 3 +on the underlying stream. +The return value for +.Xr fseek 3 +is 0 for success or -1 if an error occurred. +This differs from other types of BIO which will typically return +1 for success and a non-positive value if an error occurred. diff --git a/Libraries/libressl/man/BIO_s_mem.3 b/Libraries/libressl/man/BIO_s_mem.3 new file mode 100644 index 000000000..475cd8869 --- /dev/null +++ b/Libraries/libressl/man/BIO_s_mem.3 @@ -0,0 +1,310 @@ +.\" $OpenBSD: BIO_s_mem.3,v 1.18 2023/04/29 12:04:54 schwarze Exp $ +.\" full merge up to: OpenSSL 8711efb4 Mon Apr 20 11:33:12 2009 +0000 +.\" selective merge up to: OpenSSL 36359cec Mar 7 14:37:23 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2023 $ +.Dt BIO_S_MEM 3 +.Os +.Sh NAME +.Nm BIO_s_mem , +.Nm BIO_set_mem_eof_return , +.Nm BIO_get_mem_data , +.Nm BIO_set_mem_buf , +.Nm BIO_get_mem_ptr , +.Nm BIO_new_mem_buf +.Nd memory BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_mem +.Fa "void" +.Fc +.Ft long +.Fo BIO_set_mem_eof_return +.Fa "BIO *b" +.Fa "int v" +.Fc +.Ft long +.Fo BIO_get_mem_data +.Fa "BIO *b" +.Fa "char **pp" +.Fc +.Ft long +.Fo BIO_set_mem_buf +.Fa "BIO *b" +.Fa "BUF_MEM *bm" +.Fa "int c" +.Fc +.Ft long +.Fo BIO_get_mem_ptr +.Fa "BIO *b" +.Fa "BUF_MEM **pp" +.Fc +.Ft BIO * +.Fo BIO_new_mem_buf +.Fa "const void *buf" +.Fa "int len" +.Fc +.Sh DESCRIPTION +.Fn BIO_s_mem +returns the memory BIO method function. +.Pp +A memory BIO is a source/sink BIO which uses memory for its I/O. +Data written to a memory BIO is stored in a +.Vt BUF_MEM +structure which is extended as appropriate to accommodate the stored data. +.Pp +Any data written to a memory BIO can be recalled by reading from it. +Unless the memory BIO is read only, +any data read from it is deleted from the BIO. +To find out whether a memory BIO is read only, +.Xr BIO_test_flags 3 +can be called with an argument of +.Dv BIO_FLAGS_MEM_RDONLY . +.Pp +Memory BIOs support +.Xr BIO_gets 3 +and +.Xr BIO_puts 3 . +.Pp +If the +.Dv BIO_CLOSE +flag is set when a memory BIO is freed, the underlying +.Dv BUF_MEM +structure is also freed. +.Pp +Calling +.Xr BIO_reset 3 +on a read/write memory BIO clears any data in it. +On a read only BIO it restores the BIO to its original state +and the read only data can be read again. +.Pp +.Xr BIO_eof 3 +is true if no data is in the BIO. +.Pp +.Xr BIO_ctrl_pending 3 +returns the number of bytes currently stored. +.Pp +.Fn BIO_set_mem_eof_return +sets the behaviour of memory BIO +.Fa b +when it is empty. +If +.Fa v +is zero, then an empty memory BIO will return EOF: +it will return zero and +.Fn BIO_should_retry +will be false. +If +.Fa v +is non-zero then it will return +.Fa v +when it is empty and it will set the read retry flag: +.Fn BIO_read_retry +is true. +To avoid ambiguity with a normal positive return value +.Fa v +should be set to a negative value, typically -1. +.Pp +.Fn BIO_get_mem_data +sets +.Pf * Fa pp +to a pointer to the start of the memory BIO's data +and returns the total amount of data available. +It is implemented as a macro. +.Pp +.Fn BIO_set_mem_buf +sets the internal BUF_MEM structure to +.Fa bm +and sets the close flag to +.Fa c . +That is, +.Fa c +should be either +.Dv BIO_CLOSE +or +.Dv BIO_NOCLOSE . +.Fn BIO_set_mem_buf +is a macro. +.Pp +.Fn BIO_get_mem_ptr +places the underlying +.Vt BUF_MEM +structure in +.Pf * Fa pp . +It is a macro. +.Pp +.Fn BIO_new_mem_buf +creates a memory BIO using +.Fa len +bytes of data at +.Fa buf . +If +.Fa len +is -1, then +.Fa buf +is assumed to be NUL terminated and its length is determined by +.Xr strlen 3 . +The BIO is set to a read only state and as a result cannot be written to. +This is useful when some data needs to be made available +from a static area of memory in the form of a BIO. +The supplied data is read directly from the supplied buffer: +it is +.Em not +copied first, so the supplied area of memory must be unchanged +until the BIO is freed. +.Pp +Writes to memory BIOs will always succeed if memory is available: +their size can grow indefinitely. +.Pp +.Xr BIO_ctrl 3 +.Fa cmd +arguments correspond to macros as follows: +.Bl -column BIO_C_SET_BUF_MEM_EOF_RETURN BIO_set_mem_eof_return() -offset 3n +.It Fa cmd No constant Ta corresponding macro +.It Dv BIO_C_GET_BUF_MEM_PTR Ta Fn BIO_get_mem_ptr +.It Dv BIO_C_SET_BUF_MEM Ta Fn BIO_set_mem_buf +.It Dv BIO_C_SET_BUF_MEM_EOF_RETURN Ta Fn BIO_set_mem_eof_return +.It Dv BIO_CTRL_EOF Ta Xr BIO_eof 3 +.It Dv BIO_CTRL_GET_CLOSE Ta Xr BIO_get_close 3 +.It Dv BIO_CTRL_INFO Ta Fn BIO_get_mem_data +.It Dv BIO_CTRL_PENDING Ta Xr BIO_pending 3 +.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 +.It Dv BIO_CTRL_SET_CLOSE Ta Xr BIO_set_close 3 +.It Dv BIO_CTRL_WPENDING Ta Xr BIO_wpending 3 +.El +.Sh RETURN VALUES +.Fn BIO_s_mem +returns a pointer to a static object. +.Pp +When called on a memory BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_MEM +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq memory buffer . +.Pp +.Fn BIO_set_mem_eof_return , +.Fn BIO_get_mem_data , +.Fn BIO_set_mem_buf , +and +.Fn BIO_get_mem_ptr +return 1 on success or a value less than or equal to 0 if an error occurred. +.Pp +.Fn BIO_new_mem_buf +returns a newly allocated +.Vt BIO +object on success or +.Dv NULL +on error. +.Sh EXAMPLES +Create a memory BIO and write some data to it: +.Bd -literal -offset indent +BIO *mem = BIO_new(BIO_s_mem()); +BIO_puts(mem, "Hello World\en"); +.Ed +.Pp +Create a read only memory BIO: +.Bd -literal -offset indent +char data[] = "Hello World"; +BIO *mem; +mem = BIO_new_mem_buf(data, -1); +.Ed +.Pp +Extract the +.Vt BUF_MEM +structure from a memory BIO and then free up the BIO: +.Bd -literal -offset indent +BUF_MEM *bptr; +BIO_get_mem_ptr(mem, &bptr); +/* Make sure BIO_free() leaves BUF_MEM alone. */ +BIO_set_close(mem, BIO_NOCLOSE); +BIO_free(mem); +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BUF_MEM_new 3 +.Sh HISTORY +.Fn BIO_s_mem +first appeared in SSLeay 0.6.0. +.Fn BIO_set_mem_buf +and +.Fn BIO_get_mem_ptr +first appeared in SSLeay 0.6.5. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_set_mem_eof_return +and +.Fn BIO_get_mem_data +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . +.Pp +.Fn BIO_new_mem_buf +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Sh CAVEATS +Do not manually switch a writable memory BIO to read-only mode: calling +.Xr BIO_set_flags 3 +with an argument of +.Dv BIO_FLAGS_MEM_RDONLY +will ultimately result in a memory leak when the BIO object is +finally handed to +.Xr BIO_free 3 . +It might also cause security issues because it prevents +.Xr BIO_reset 3 +from clearing the data. +.Sh BUGS +There should be an option to set the maximum size of a memory BIO. +.Pp +There should be a way to "rewind" a read/write BIO without destroying +its contents. diff --git a/Libraries/libressl/man/BIO_s_null.3 b/Libraries/libressl/man/BIO_s_null.3 new file mode 100644 index 000000000..6e7cad6d3 --- /dev/null +++ b/Libraries/libressl/man/BIO_s_null.3 @@ -0,0 +1,101 @@ +.\" $OpenBSD: BIO_s_null.3,v 1.10 2023/04/11 16:58:43 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 11 2023 $ +.Dt BIO_S_NULL 3 +.Os +.Sh NAME +.Nm BIO_s_null +.\" .Nm BIO_s_log is intentionally undocumented because it is unused +.Nd null data sink +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_null +.Fa void +.Fc +.Sh DESCRIPTION +.Fn BIO_s_null +returns the null sink BIO method. +Data written to the null sink is discarded, reads return EOF. +.Pp +A null sink BIO behaves in a similar manner to the +.Xr null 4 +device. +.Pp +A null BIO can be placed on the end of a chain to discard any data +passed through it. +.Pp +A null sink is useful if, for example, an application wishes +to digest some data by writing through a digest bio +but not send the digested data anywhere. +Since a BIO chain must normally include a source/sink BIO, +this can be achieved by adding a null sink BIO to the end of the chain. +.Sh RETURN VALUES +.Fn BIO_s_null +returns the null sink BIO method. +.Pp +When called on a null sink BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_NULL +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq NULL , +not to be confused with a NUL string nor with a +.Dv NULL +pointer. +.Sh SEE ALSO +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_s_null +first appeared in SSLeay 0.6.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_s_socket.3 b/Libraries/libressl/man/BIO_s_socket.3 new file mode 100644 index 000000000..402622b3b --- /dev/null +++ b/Libraries/libressl/man/BIO_s_socket.3 @@ -0,0 +1,125 @@ +.\" $OpenBSD: BIO_s_socket.3,v 1.10 2023/04/11 16:58:43 schwarze Exp $ +.\" OpenSSL bbdc9c98 Oct 19 22:02:21 2000 +0000 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 11 2023 $ +.Dt BIO_S_SOCKET 3 +.Os +.Sh NAME +.Nm BIO_s_socket , +.Nm BIO_new_socket +.Nd socket BIO +.Sh SYNOPSIS +.In openssl/bio.h +.Ft const BIO_METHOD * +.Fo BIO_s_socket +.Fa void +.Fc +.Ft BIO * +.Fo BIO_new_socket +.Fa "int sock" +.Fa "int close_flag" +.Fc +.Sh DESCRIPTION +.Fn BIO_s_socket +returns the socket BIO method. +This is a wrapper around the platform's socket routines. +.Pp +.Xr BIO_read 3 +and +.Xr BIO_write 3 +read or write the underlying socket. +.Xr BIO_puts 3 +is supported but +.Xr BIO_gets 3 +is not. +.Pp +If the close flag is set, then the socket is shut down and closed +when the BIO is freed. +.Pp +.Fn BIO_new_socket +returns a socket BIO using +.Fa sock +and +.Fa close_flag . +.Pp +Socket BIOs also support any relevant functionality of file descriptor BIOs. +.Pp +The reason for having separate file descriptor and socket BIOs +is that on some platforms, sockets are not file descriptors +and use distinct I/O routines. +Windows is one such platform. +Any code mixing the two will not work on all platforms. +.Sh RETURN VALUES +.Fn BIO_s_socket +returns the socket BIO method. +.Pp +.Fn BIO_new_socket +returns the newly allocated BIO or +.Dv NULL +if an error occurred. +.Pp +When called on a socket BIO object, +.Xr BIO_method_type 3 +returns the constant +.Dv BIO_TYPE_SOCKET +and +.Xr BIO_method_name 3 +returns a pointer to the static string +.Qq socket . +.Sh SEE ALSO +.Xr BIO_get_fd 3 , +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_s_socket +first appeared in SSLeay 0.6.0. +.Fn BIO_new_socket +first appeared in SSLeay 0.8.0. +Both functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BIO_set_callback.3 b/Libraries/libressl/man/BIO_set_callback.3 new file mode 100644 index 000000000..56a0102be --- /dev/null +++ b/Libraries/libressl/man/BIO_set_callback.3 @@ -0,0 +1,396 @@ +.\" $OpenBSD: BIO_set_callback.3,v 1.12 2023/04/30 13:57:29 schwarze Exp $ +.\" full merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2016, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt BIO_SET_CALLBACK 3 +.Os +.Sh NAME +.Nm BIO_callback_fn_ex , +.Nm BIO_set_callback_ex , +.Nm BIO_get_callback_ex , +.Nm BIO_callback_fn , +.Nm BIO_set_callback , +.Nm BIO_get_callback , +.Nm BIO_set_callback_arg , +.Nm BIO_get_callback_arg , +.Nm BIO_debug_callback +.\" The following three macros are intentionally undocumented because +.\" they are unused and would only cause obfuscation if they were used. +.\" .Nm BIO_CB_return +.\" .Nm BIO_cb_pre +.\" .Nm BIO_cb_post +.Nd BIO callback functions +.Sh SYNOPSIS +.In openssl/bio.h +.Ft typedef long +.Fo (*BIO_callback_fn_ex) +.Fa "BIO *b" +.Fa "int oper" +.Fa "const char *argp" +.Fa "size_t len" +.Fa "int argi" +.Fa "long argl" +.Fa "int ret" +.Fa "size_t *processed" +.Fc +.Ft void +.Fo BIO_set_callback_ex +.Fa "BIO *b" +.Fa "BIO_callback_fn_ex cb_ex" +.Fc +.Ft BIO_callback_fn_ex +.Fo BIO_get_callback_ex +.Fa "const BIO *b" +.Fc +.Ft typedef long +.Fo (*BIO_callback_fn) +.Fa "BIO *b" +.Fa "int oper" +.Fa "const char *argp" +.Fa "int argi" +.Fa "long argl" +.Fa "long ret" +.Fc +.Ft void +.Fo BIO_set_callback +.Fa "BIO *b" +.Fa "BIO_callback_fn cb" +.Fc +.Ft BIO_callback_fn +.Fo BIO_get_callback +.Fa "BIO *b" +.Fc +.Ft void +.Fo BIO_set_callback_arg +.Fa "BIO *b" +.Fa "char *pointer" +.Fc +.Ft char * +.Fo BIO_get_callback_arg +.Fa "const BIO *b" +.Fc +.Ft long +.Fo BIO_debug_callback +.Fa "BIO *bio" +.Fa "int oper" +.Fa "const char *argp" +.Fa "int argi" +.Fa "long argl" +.Fa "long ret" +.Fc +.Sh DESCRIPTION +.Fn BIO_set_callback_ex +and +.Fn BIO_get_callback_ex +set and retrieve the BIO callback. +The callback is called during most high-level BIO operations. +It can be used for debugging purposes to trace operations on a BIO +or to modify its operation. +.Pp +.Fn BIO_set_callback +and +.Fn BIO_get_callback +are deprecated functions that set and retrieve the old-style BIO callback, +which is only used if no new-style callback is set with +.Fn BIO_set_callback_ex . +.Pp +.Fn BIO_set_callback_arg +stores the +.Fa pointer +internally in +.Fa b +and +.Fn BIO_get_callback_arg +retrieves it from +.Fa b . +The name of these two functions is badly misleading: the +.Fa pointer +is never passed as an argument to any callback function. +But of course, callback functions can call +.Fn BIO_get_callback_arg +and access the pointer, just like any other code can. +.Pp +.Fn BIO_debug_callback +is a standard debugging callback which prints +out information related to each BIO operation. +If +.Fn BIO_set_callback_arg +was called with a +.Pf non- Dv NULL +argument, information is sent to the BIO pointed to by the +.Fa pointer ; +otherwise, standard error output is used. +.Pp +The arguments of the callback functions are as follows: +.Bl -tag -width Ds +.It Fa b +The BIO the callback is attached to. +.It Fa oper +The operation being performed, which is one of +.Dv BIO_CB_CTRL , +.Dv BIO_CB_FREE , +.Dv BIO_CB_GETS , +.Dv BIO_CB_PUTS , +.Dv BIO_CB_READ , +or +.Dv BIO_CB_WRITE . +For some operations, the callback is called twice, +once before and once after the actual operation. +The latter case has +.Fa oper +OR'ed with +.Dv BIO_CB_RETURN . +.It Fa argp , argi , argl +The meaning of these three arguments depends on the value of +.Fa oper , +that is on the operation being performed. +.It Fa len +The length of the data requested to be read or written. +This is only useful if +.Fa oper +is +.Dv BIO_CB_READ , +.Dv BIO_CB_WRITE , +or +.Dv BIO_CB_GETS . +.It Fa ret +When +.Fa oper +does not include +.Dv BIO_CB_RETURN , +i.e. when the callback is invoked before an operation, +the value passed into the callback via +.Fa ret +is always 1. +In this case, if the callback returns a negative value, the library +aborts the requested operation and instead returns the negative +return value from the callback to the application. +If the callback returns a non-negative value, that return value is +ignored by the library, and the operation is performed normally. +.Pp +When +.Fa oper +includes +.Dv BIO_CB_RETURN , +i.e. when the callback is invoked after an operation, +the value passed into the callback via +.Fa ret +is the return value that the operation would return to the application +if no callback were present. +When a callback is present, the operation only passes this value +to the callback and instead of it returns the return value of the +callback to the application. +.It Fa processed +The location pointed to is updated with the number of bytes +actually read or written. +Only used for +.Dv BIO_CB_READ , +.Dv BIO_CB_WRITE , +.Dv BIO_CB_GETS , +and +.Dv BIO_CB_PUTS . +.El +.Pp +The callback should normally simply return +.Fa ret +when it has finished processing, unless it specifically wishes to +abort the operation or to modify the value returned to the application. +.Pp +The callbacks are called as follows: +.Bl -tag -width 1n +.It \&In Fn BIO_free "BIO *b" : +.Bd -literal +before the free operation: +cb_ex(b, BIO_CB_FREE, NULL, 0, 0, 0, 1, NULL) +or cb(b, BIO_CB_FREE, NULL, 0, 0, 1) +.Ed +.It \&In Fn BIO_read "BIO *b" "void *out" "int outl" : +.Bd -literal +before the read operation: +cb_ex(b, BIO_CB_READ, out, outl, 0, 0, 1, NULL) +or cb(b, BIO_CB_READ, out, outl, 0, 1) + +after the read operation: +cb_ex(b, BIO_CB_READ|BIO_CB_RETURN, out, outl, 0, 0, ret, &bytes) +or cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl, 0, ret) +.Ed +.It \&In Fn BIO_write "BIO *b" "const void *in" "int inl" : +.Bd -literal +before the write operation: +cb_ex(b, BIO_CB_WRITE, in, inl, 0, 0, 1, NULL) +or cb(b, BIO_CB_WRITE, in, inl, 0, 1) + +after the write operation: +cb_ex(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl, 0, 0, ret, &bytes) +or cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl, 0, ret) +.Ed +.It \&In Fn BIO_gets "BIO *b" "char *out" "int outl" : +.Bd -literal +before the read operation: +cb_ex(b, BIO_CB_GETS, out, outl, 0, 0, 1, NULL) +or cb(b, BIO_CB_GETS, out, outl, 0, 1) + +after the read operation: +cb_ex(b, BIO_CB_GETS|BIO_CB_RETURN, out, outl, 0, 0, ret, &bytes) +or cb(b, BIO_CB_GETS|BIO_CB_RETURN, out, outl, 0, ret) +.Ed +.It \&In Fn BIO_puts "BIO *b" "const char *in" : +.Bd -literal +before the write operation: +cb_ex(b, BIO_CB_PUTS, in, 0, 0, 0, 1, NULL) +or cb(b, BIO_CB_PUTS, in, 0, 0, 1) + +after the write operation: +cb_ex(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0, 0, ret, &bytes) +or cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0, ret) +.Ed +.It \&In Fn BIO_ctrl "BIO *b" "int cmd" "long larg" "void *parg" : +.Bd -literal +before the control operation: +cb_ex(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1, NULL) +or cb(b, BIO_CB_CTRL, parg, cmd, larg, 1) + +after the control operation: +cb_ex(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, 0, cmd, larg, ret, NULL) +or cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret) +.Ed +.It \&In Fn BIO_callback_ctrl "BIO *b" "int cmd" "BIO_info_cb *fp" : +.Bd -literal +before the control operation: +cb_ex(b, BIO_CB_CTRL, fp, 0, cmd, 0, 1, NULL) +or cb(b, BIO_CB_CTRL, fp, cmd, 0, 1) + +after the control operation: +cb_ex(b, BIO_CB_CTRL|BIO_CB_RETURN, fp, 0, cmd, 0, ret, NULL) +or cb(b, BIO_CB_CTRL|BIO_CB_RETURN, fp, cmd, 0, ret) +.Ed +.El +.Sh RETURN VALUES +.Fn BIO_get_callback_ex +returns a pointer to the function +.Fa cb_ex +previously installed with +.Fn BIO_set_callback_cb , +or +.Dv NULL +if no such callback was installed. +.Pp +.Fn BIO_get_callback +returns a pointer to the function +.Fa cb +previously installed with +.Fn BIO_set_callback , +or +.Dv NULL +if no such callback was installed. +.Pp +.Fn BIO_get_callback_arg +returns the +.Fa pointer +previously set with +.Fn BIO_set_callback_arg , +or +.Dv NULL +if no such pointer was set. +.Pp +.Fn BIO_debug_callback +returns +.Fa ret +if the bit +.Dv BIO_CB_RETURN +is set in +.Fa cmd , +or 1 otherwise. +.Sh EXAMPLES +The +.Fn BIO_debug_callback +function is a good example. +Its source is in the file +.Pa crypto/bio/bio_cb.c . +.Sh SEE ALSO +.Xr BIO_new 3 +.Sh HISTORY +.Fn BIO_set_callback , +.Fn BIO_get_callback , +.Fn BIO_set_callback_arg , +and +.Fn BIO_debug_callback +first appeared in SSLeay 0.6.0. +.Fn BIO_get_callback_arg +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_callback_fn +first appeared in OpenSSL 1.1.0. +.Fn BIO_callback_fn_ex , +.Fn BIO_set_callback_ex , +and +.Fn BIO_get_callback_ex +first appeared in OpenSSL 1.1.1. +These functions have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/BIO_should_retry.3 b/Libraries/libressl/man/BIO_should_retry.3 new file mode 100644 index 000000000..9b9374351 --- /dev/null +++ b/Libraries/libressl/man/BIO_should_retry.3 @@ -0,0 +1,301 @@ +.\" $OpenBSD: BIO_should_retry.3,v 1.11 2023/04/30 14:03:47 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" selective merge up to: OpenSSL 57fd5170 May 13 11:24:11 2018 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2010, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt BIO_SHOULD_RETRY 3 +.Os +.Sh NAME +.Nm BIO_should_read , +.Nm BIO_should_write , +.Nm BIO_should_io_special , +.Nm BIO_retry_type , +.Nm BIO_should_retry , +.Nm BIO_get_retry_BIO , +.Nm BIO_get_retry_reason , +.Nm BIO_set_retry_reason +.Nd BIO retry functions +.Sh SYNOPSIS +.In openssl/bio.h +.Ft int +.Fo BIO_should_read +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_should_write +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_should_io_special +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_retry_type +.Fa "BIO *b" +.Fc +.Ft int +.Fo BIO_should_retry +.Fa "BIO *b" +.Fc +.Fd #define BIO_FLAGS_READ 0x01 +.Fd #define BIO_FLAGS_WRITE 0x02 +.Fd #define BIO_FLAGS_IO_SPECIAL 0x04 +.Fd #define BIO_FLAGS_RWS \e +.Fd \& (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +.Fd #define BIO_FLAGS_SHOULD_RETRY 0x08 +.Ft BIO * +.Fo BIO_get_retry_BIO +.Fa "BIO *bio" +.Fa "int *reason" +.Fc +.Ft int +.Fo BIO_get_retry_reason +.Fa "BIO *bio" +.Fc +.Ft void +.Fo BIO_set_retry_reason +.Fa "BIO *bio" +.Fa "int reason" +.Fc +.Sh DESCRIPTION +These functions determine why a BIO is not able to read or write data. +They will typically be called after a failed +.Xr BIO_read 3 +or +.Xr BIO_write 3 +call. +.Pp +.Fn BIO_should_retry +returns 1 if the call that produced this condition should be retried +at a later time, or 0 if an error occurred. +.Pp +.Fn BIO_should_read +returns 1 if the cause of the retry condition is that a BIO needs +to read data, or 0 otherwise. +.Pp +.Fn BIO_should_write +returns 1 if the cause of the retry condition is that a BIO needs +to write data, or 0 otherwise. +.Pp +.Fn BIO_should_io_special +returns 1 if some special condition (i.e. a reason other than reading +or writing) is the cause of the retry condition, or 0 otherwise. +.Pp +.Fn BIO_retry_type +returns the bitwise OR of one or more of the flags +.Dv BIO_FLAGS_READ , +.Dv BIO_FLAGS_WRITE , +and +.Dv BIO_FLAGS_IO_SPECIAL +representing the cause of the current retry condition, +or 0 if there is no retry condition. +Current BIO types only set one of the flags at a time. +.Pp +.Fn BIO_get_retry_BIO +determines the precise reason for the special condition. +It walks the BIO chain starting at +.Fa bio +and returns the BIO that caused this condition. +If there is no special condition, +.Fa bio +itself is returned. +If +.Fa reason +is not a +.Dv NULL +pointer, +.Pf * Fa reason +is set to one of the following reason codes: +.Bl -tag -width 1n -offset 3n +.It 0 +There is no special condition. +.It Dv BIO_RR_ACCEPT +.Xr accept 2 +would have blocked. +This can occur for BIOs created from +.Xr BIO_s_accept 3 +or +.Xr BIO_f_ssl 3 . +.It Dv BIO_RR_CONNECT +.Xr connect 2 +would have blocked. +This can occur for BIOs created from +.Xr BIO_s_connect 3 +or +.Xr BIO_f_ssl 3 . +.It Dv BIO_RR_SSL_X509_LOOKUP +An application callback set by +.Xr SSL_CTX_set_client_cert_cb 3 +has asked to be called again. +This can occur for BIOs created from +.Xr BIO_f_ssl 3 . +.El +.Pp +.Fn BIO_get_retry_reason +returns one of the above reason codes for a special condition that occurred in +.Fa bio . +It does not walk the chain and returns 0 if no special condition occurred in +.Fa bio +itself. +.Pp +.Fn BIO_set_retry_reason +sets the retry reason for a special condition for the given +.Fa bio . +It is intended to be called by functions implementing a BIO type +rather than by functions merely using BIOs. +.Pp +.Fn BIO_should_retry , +.Fn BIO_should_read , +.Fn BIO_should_write , +.Fn BIO_should_io_special , +and +.Fn BIO_retry_type +are implemented as macros. +.Pp +If +.Fn BIO_should_retry +returns false, then the precise "error condition" depends on +the BIO type that caused it and the return code of the BIO operation. +For example if a call to +.Xr BIO_read 3 +on a socket BIO returns 0 and +.Fn BIO_should_retry +is false, then the cause will be that the connection closed. +A similar condition on a file BIO will mean that it has reached EOF. +Some BIO types may place additional information on the error queue. +For more details see the individual BIO type manual pages. +.Pp +If the underlying I/O structure is in a blocking mode, +almost all current BIO types will not request a retry, +because the underlying I/O calls will not. +If the application knows that the BIO type will never +signal a retry then it need not call +.Fn BIO_should_retry +after a failed BIO I/O call. +This is typically done with file BIOs. +.Pp +SSL BIOs are the only current exception to this rule: +they can request a retry even if the underlying I/O structure +is blocking, if a handshake occurs during a call to +.Xr BIO_read 3 . +An application can retry the failed call immediately +or avoid this situation by setting +.Dv SSL_MODE_AUTO_RETRY +on the underlying SSL structure. +.Pp +While an application may retry a failed non-blocking call immediately, +this is likely to be very inefficient because the call will fail +repeatedly until data can be processed or is available. +An application will normally wait until the necessary condition +is satisfied. +How this is done depends on the underlying I/O structure. +.Pp +For example if the cause is ultimately a socket and +.Fn BIO_should_read +is true then a call to +.Xr select 2 +may be made to wait until data is available +and then retry the BIO operation. +By combining the retry conditions of several non-blocking BIOs in a single +.Xr select 2 +call it is possible to service several BIOs in a single thread, +though the performance may be poor if SSL BIOs are present because +long delays can occur during the initial handshake process. +.Pp +It is possible for a BIO to block indefinitely if the underlying I/O +structure cannot process or return any data. +This depends on the behaviour of the platforms I/O functions. +This is often not desirable: one solution is to use non-blocking I/O +and use a timeout on the +.Xr select 2 +(or equivalent) call. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BIO_read 3 +.Sh HISTORY +.Fn BIO_should_read , +.Fn BIO_should_write , +.Fn BIO_retry_type , +and +.Fn BIO_should_retry +first appeared in SSLeay 0.6.0. +.Fn BIO_should_io_special , +.Fn BIO_get_retry_BIO , +and +.Fn BIO_get_retry_reason +first appeared in SSLeay 0.8.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BIO_set_retry_reason +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.1 . +.Sh BUGS +The OpenSSL ASN.1 functions cannot gracefully deal with non-blocking I/O: +they cannot retry after a partial read or write. +This is usually worked around by only passing the relevant data to ASN.1 +functions when the entire structure can be read or written. diff --git a/Libraries/libressl/man/BN_CTX_new.3 b/Libraries/libressl/man/BN_CTX_new.3 new file mode 100644 index 000000000..336b91889 --- /dev/null +++ b/Libraries/libressl/man/BN_CTX_new.3 @@ -0,0 +1,123 @@ +.\" $OpenBSD: BN_CTX_new.3,v 1.10 2023/04/25 17:21:51 tb Exp $ +.\" OpenSSL aafbe1cc Jun 12 23:42:08 2013 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 25 2023 $ +.Dt BN_CTX_NEW 3 +.Os +.Sh NAME +.Nm BN_CTX_new , +.Nm BN_CTX_free +.Nd allocate and free BN_CTX structures +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BN_CTX * +.Fo BN_CTX_new +.Fa void +.Fc +.Ft void +.Fo BN_CTX_free +.Fa "BN_CTX *c" +.Fc +.Sh DESCRIPTION +A +.Vt BN_CTX +is a structure that holds +.Vt BIGNUM +temporary variables used by library functions. +Since dynamic memory allocation to create +.Vt BIGNUM Ns s +is rather expensive when used in conjunction with repeated subroutine +calls, the +.Vt BN_CTX +structure is used. +.Pp +.Fn BN_CTX_new +allocates and initializes a +.Vt BN_CTX +structure. +.Pp +.Fn BN_CTX_free +frees the components of the +.Vt BN_CTX +and, if it was created by +.Fn BN_CTX_new , +also the structure itself. +If +.Xr BN_CTX_start 3 +has been used on the +.Vt BN_CTX , +.Xr BN_CTX_end 3 +must be called before the +.Vt BN_CTX +may be freed by +.Fn BN_CTX_free . +If +.Fa c +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn BN_CTX_new +returns a pointer to the +.Vt BN_CTX . +If the allocation fails, it returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_CTX_start 3 , +.Xr BN_new 3 +.Sh HISTORY +.Fn BN_CTX_new +and +.Fn BN_CTX_free +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BN_CTX_start.3 b/Libraries/libressl/man/BN_CTX_start.3 new file mode 100644 index 000000000..a2b62eff5 --- /dev/null +++ b/Libraries/libressl/man/BN_CTX_start.3 @@ -0,0 +1,137 @@ +.\" $OpenBSD: BN_CTX_start.3,v 1.8 2019/08/20 10:59:09 schwarze Exp $ +.\" full merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 20 2019 $ +.Dt BN_CTX_START 3 +.Os +.Sh NAME +.Nm BN_CTX_start , +.Nm BN_CTX_get , +.Nm BN_CTX_end +.Nd use temporary BIGNUM variables +.Sh SYNOPSIS +.In openssl/bn.h +.Ft void +.Fo BN_CTX_start +.Fa "BN_CTX *ctx" +.Fc +.Ft BIGNUM * +.Fo BN_CTX_get +.Fa "BN_CTX *ctx" +.Fc +.Ft void +.Fo BN_CTX_end +.Fa "BN_CTX *ctx" +.Fc +.Sh DESCRIPTION +These functions are used to obtain temporary +.Vt BIGNUM +variables from a +.Vt BN_CTX +(which can be created using +.Xr BN_CTX_new 3 ) +in order to save the overhead of repeatedly creating and freeing +.Vt BIGNUM Ns s +in functions that are called from inside a loop. +.Pp +A function must call +.Fn BN_CTX_start +first. +Then, +.Fn BN_CTX_get +may be called repeatedly to obtain temporary +.Vt BIGNUM Ns s . +All +.Fn BN_CTX_get +calls must be made before calling any other functions that use the +.Fa ctx +as an argument. +.Pp +Finally, +.Fn BN_CTX_end +must be called before returning from the function. +When +.Fn BN_CTX_end +is called, the +.Vt BIGNUM +pointers obtained from +.Fn BN_CTX_get +become invalid. +If +.Fa ctx +is +.Dv NULL , +no action occurs. +.Sh RETURN VALUES +.Fn BN_CTX_get +returns a pointer to the +.Vt BIGNUM , +or +.Dv NULL +on error. +Once +.Fn BN_CTX_get +has failed, the subsequent calls will return +.Dv NULL +as well, so it is sufficient to check the return value of the last +.Fn BN_CTX_get +call. +In case of an error, an error code is set which can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_CTX_new 3 , +.Xr BN_new 3 +.Sh HISTORY +.Fn BN_CTX_start , +.Fn BN_CTX_get , +and +.Fn BN_CTX_end +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/BN_add.3 b/Libraries/libressl/man/BN_add.3 new file mode 100644 index 000000000..e7de441b7 --- /dev/null +++ b/Libraries/libressl/man/BN_add.3 @@ -0,0 +1,646 @@ +.\" $OpenBSD: BN_add.3,v 1.20 2023/04/27 09:47:03 tb Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller +.\" and Bodo Moeller . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 27 2023 $ +.Dt BN_ADD 3 +.Os +.Sh NAME +.Nm BN_add , +.Nm BN_uadd , +.Nm BN_sub , +.Nm BN_usub , +.Nm BN_mul , +.Nm BN_sqr , +.Nm BN_div , +.Nm BN_mod , +.Nm BN_nnmod , +.Nm BN_mod_add , +.Nm BN_mod_add_quick , +.Nm BN_mod_sub , +.Nm BN_mod_sub_quick , +.Nm BN_mod_mul , +.Nm BN_mod_sqr , +.Nm BN_mod_lshift , +.Nm BN_mod_lshift_quick , +.Nm BN_mod_lshift1 , +.Nm BN_mod_lshift1_quick , +.Nm BN_exp , +.Nm BN_mod_exp , +.\" The following are public, but intentionally undocumented for now: +.\" .Nm BN_mod_exp_mont , r \(== a ^ p (mod m) +.\" .Nm BN_mod_exp_mont_consttime , +.\" .Nm BN_mod_exp_mont_word , +.\" .Nm BN_mod_exp_simple , +.\" .Nm BN_mod_exp2_mont r \(== (a1 ^ p1) * (a2 ^ p2) (mod m) +.\" Maybe they should be deleted from . +.Nm BN_gcd +.Nd arithmetic operations on BIGNUMs +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_add +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fc +.Ft int +.Fo BN_uadd +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fc +.Ft int +.Fo BN_sub +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fc +.Ft int +.Fo BN_usub +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fc +.Ft int +.Fo BN_mul +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_sqr +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_div +.Fa "BIGNUM *dv" +.Fa "BIGNUM *rem" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *d" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod +.Fa "BIGNUM *rem" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_nnmod +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_add +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_add_quick +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "const BIGNUM *m" +.Fc +.Ft int +.Fo BN_mod_sub +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_sub_quick +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "const BIGNUM *m" +.Fc +.Ft int +.Fo BN_mod_mul +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_sqr +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_lshift +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "int n" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_lshift_quick +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "int n" +.Fa "const BIGNUM *m" +.Fc +.Ft int +.Fo BN_mod_lshift1 +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_lshift1_quick +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *m" +.Fc +.Ft int +.Fo BN_exp +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *p" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_mod_exp +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *p" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_gcd +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn BN_add +adds +.Fa a +and +.Fa b +and places the result in +.Fa r +.Pq Li r=a+b . +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +.Pp +.Fn BN_uadd +adds the absolute values of +.Fa a +and +.Fa b +and places the result in +.Fa r +.Pq Li r=|a|+|b|\& . +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +.Pp +.Fn BN_sub +subtracts +.Fa b +from +.Fa a +and places the result in +.Fa r +.Pq Li r=a-b . +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +.Pp +.Fn BN_usub +subtracts the absolute value of +.Fa b +from the absolute value of +.Fa a +and places the result in +.Fa r +.Pq Li r=|a|-|b|\& . +It requires the absolute value of +.Fa a +to be greater than the absolute value of +.Fa b ; +otherwise it will fail. +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +.Pp +.Fn BN_mul +multiplies +.Fa a +and +.Fa b +and places the result in +.Fa r +.Pq Li r=a*b . +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +For multiplication by powers of 2, use +.Xr BN_lshift 3 . +.Pp +.Fn BN_sqr +takes the square of +.Fa a +and places the result in +.Fa r +.Pq Li r=a^2 . +.Fa r +and +.Fa a +may be the same +.Vt BIGNUM . +This function is faster than +.Fn BN_mul r a a . +.Pp +.Fn BN_div +divides +.Fa a +by +.Fa d +and places the result in +.Fa dv +and the remainder in +.Fa rem +.Pq Li dv=a/d , rem=a%d . +If the flag +.Dv BN_FLG_CONSTTIME +is set on +.Fa a +or +.Fa d , +it operates in constant time. +Either of +.Fa dv +and +.Fa rem +may be +.Dv NULL , +in which case the respective value is not returned. +The result is rounded towards zero; thus if +.Fa a +is negative, the remainder will be zero or negative. +For division by powers of 2, use +.Fn BN_rshift 3 . +.Pp +.Fn BN_mod +corresponds to +.Fn BN_div +with +.Fa dv +set to +.Dv NULL . +It is implemented as a macro. +.Pp +.Fn BN_nnmod +reduces +.Fa a +modulo +.Fa m +and places the non-negative remainder in +.Fa r . +.Pp +.Fn BN_mod_add +adds +.Fa a +to +.Fa b +modulo +.Fa m +and places the non-negative result in +.Fa r . +.Pp +.Fn BN_mod_add_quick +is a variant of +.Fn BN_mod_add +that requires +.Fa a +and +.Fa b +to both be non-negative and smaller than +.Fa m . +If any of these constraints are violated, +it silently produces wrong results. +.Pp +.Fn BN_mod_sub +subtracts +.Fa b +from +.Fa a +modulo +.Fa m +and places the non-negative result in +.Fa r . +.Pp +.Fn BN_mod_sub_quick +is a variant of +.Fn BN_mod_sub +that requires +.Fa a +and +.Fa b +to both be non-negative and smaller than +.Fa m . +If any of these constraints are violated, +it silently produces wrong results. +.Pp +.Fn BN_mod_mul +multiplies +.Fa a +by +.Fa b +and finds the non-negative remainder respective to modulus +.Fa m +.Pq Li r=(a*b)%m . +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +For a more efficient algorithm for repeated computations using the same +modulus, see +.Xr BN_mod_mul_montgomery 3 . +.Pp +.Fn BN_mod_sqr +takes the square of +.Fa a +modulo +.Fa m +and places the result in +.Fa r . +.Pp +.Fn BN_mod_lshift +shifts +.Fa a +left by +.Fa n +bits, reduces the result modulo +.Fa m , +and places the non-negative remainder in +.Fa r +.Pq Li r=a*2^n mod m . +.Pp +.Fn BN_mod_lshift1 +shifts +.Fa a +left by one bit, reduces the result modulo +.Fa m , +and places the non-negative remainder in +.Fa r +.Pq Li r=a*2 mod m . +.Pp +.Fn BN_mod_lshift_quick +and +.Fn BN_mod_lshift1_quick +are variants of +.Fn BN_mod_lshift +and +.Fn BN_mod_lshift1 , +respectively, that require +.Fa a +to be non-negative and less than +.Fa m . +If either of these constraints is violated, they sometimes fail +and sometimes silently produce wrong results. +.Pp +.Fn BN_exp +raises +.Fa a +to the +.Fa p Ns -th +power and places the result in +.Fa r +.Pq Li r=a^p . +This function is faster than repeated applications of +.Fn BN_mul . +.Pp +.Fn BN_mod_exp +computes +.Fa a +to the +.Fa p Ns -th +power modulo +.Fa m +.Pq Li r=(a^p)%m . +If the flag +.Dv BN_FLG_CONSTTIME +is set on +.Fa p , +it operates in constant time. +This function uses less time and space than +.Fn BN_exp . +.Pp +.Fn BN_gcd +computes the greatest common divisor of +.Fa a +and +.Fa b +and places the result in +.Fa r . +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa b . +.Pp +For all functions, +.Fa ctx +is a previously allocated +.Vt BN_CTX +used for temporary variables; see +.Xr BN_CTX_new 3 . +.Pp +Unless noted otherwise, the result +.Vt BIGNUM +must be different from the arguments. +.Sh RETURN VALUES +For all functions, 1 is returned for success, 0 on error. +The return value should always be checked, for example: +.Pp +.Dl if (!BN_add(r,a,b)) goto err; +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_add_word 3 , +.Xr BN_CTX_new 3 , +.Xr BN_new 3 , +.Xr BN_set_bit 3 , +.Xr BN_set_flags 3 , +.Xr BN_set_negative 3 +.Sh HISTORY +.Fn BN_add , +.Fn BN_sub , +.Fn BN_mul , +.Fn BN_sqr , +.Fn BN_div , +.Fn BN_mod , +.Fn BN_mod_mul , +.Fn BN_mod_exp , +and +.Fn BN_gcd +first appeared in SSLeay 0.5.1. +.Fn BN_exp +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BN_uadd , +.Fn BN_usub , +and the +.Fa ctx +argument to +.Fn BN_mul +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . +.Pp +.Fn BN_nnmod , +.Fn BN_mod_add , +.Fn BN_mod_add_quick , +.Fn BN_mod_sub , +.Fn BN_mod_sub_quick , +.Fn BN_mod_sqr , +.Fn BN_mod_lshift , +.Fn BN_mod_lshift_quick , +.Fn BN_mod_lshift1 , +and +.Fn BN_mod_lshift1_quick +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Sh BUGS +Even if the +.Dv BN_FLG_CONSTTIME +flag is set on +.Fa a +or +.Fa b , +.Fn BN_gcd +neither fails nor operates in constant time, potentially allowing +timing side-channel attacks. +.Pp +Even if the +.Dv BN_FLG_CONSTTIME +flag is set on +.Fa p , +if the modulus +.Fa m +is even, +.Fn BN_mod_exp +does not operate in constant time, potentially allowing +timing side-channel attacks. +.Pp +If +.Dv BN_FLG_CONSTTIME +is set on +.Fa p , +.Fn BN_exp +fails instead of operating in constant time. diff --git a/Libraries/libressl/man/BN_add_word.3 b/Libraries/libressl/man/BN_add_word.3 new file mode 100644 index 000000000..161029c30 --- /dev/null +++ b/Libraries/libressl/man/BN_add_word.3 @@ -0,0 +1,182 @@ +.\" $OpenBSD: BN_add_word.3,v 1.10 2022/11/22 19:02:07 schwarze Exp $ +.\" full merge up to: OpenSSL 9e183d22 Mar 11 08:56:44 2017 -0500 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 22 2022 $ +.Dt BN_ADD_WORD 3 +.Os +.Sh NAME +.Nm BN_add_word , +.Nm BN_sub_word , +.Nm BN_mul_word , +.Nm BN_div_word , +.Nm BN_mod_word +.Nd arithmetic functions on BIGNUMs with integers +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_add_word +.Fa "BIGNUM *a" +.Fa "BN_ULONG w" +.Fc +.Ft int +.Fo BN_sub_word +.Fa "BIGNUM *a" +.Fa "BN_ULONG w" +.Fc +.Ft int +.Fo BN_mul_word +.Fa "BIGNUM *a" +.Fa "BN_ULONG w" +.Fc +.Ft BN_ULONG +.Fo BN_div_word +.Fa "BIGNUM *a" +.Fa "BN_ULONG w" +.Fc +.Ft BN_ULONG +.Fo BN_mod_word +.Fa "const BIGNUM *a" +.Fa "BN_ULONG w" +.Fc +.Sh DESCRIPTION +These functions perform arithmetic operations on BIGNUMs with unsigned +integers. +They are much more efficient than the normal BIGNUM arithmetic +operations. +.Pp +.Vt BN_ULONG +is a macro that expands to +.Vt unsigned long Pq = Vt uint64_t +on +.Dv _LP64 +platforms and +.Vt unsigned int Pq = Vt uint32_t +elsewhere. +.Pp +.Fn BN_add_word +adds +.Fa w +to +.Fa a +.Pq Li a+=w . +.Pp +.Fn BN_sub_word +subtracts +.Fa w +from +.Fa a +.Pq Li a-=w . +.Pp +.Fn BN_mul_word +multiplies +.Fa a +and +.Fa w +.Pq Li a*=w . +.Pp +.Fn BN_div_word +divides +.Fa a +by +.Fa w +.Pq Li a/=w +and returns the remainder. +.Pp +.Fn BN_mod_word +returns the remainder of +.Fa a +divided by +.Fa w +.Pq Li a%w . +.Pp +For +.Fn BN_div_word +and +.Fn BN_mod_word , +.Fa w +must not be 0. +.Sh RETURN VALUES +.Fn BN_add_word , +.Fn BN_sub_word , +and +.Fn BN_mul_word +return 1 for success or 0 on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Pp +.Fn BN_mod_word +and +.Fn BN_div_word +return +.Fa a Ns % Ns Fa w +on success and +.Po Vt BN_ULONG Pc Ns -1 +if an error occurred. +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_new 3 +.Sh HISTORY +.Fn BN_add_word , +.Fn BN_div_word , +and +.Fn BN_mod_word +first appeared in SSLeay 0.5.1. +.Fn BN_sub_word +and +.Fn BN_mul_word +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +Before 0.9.8a, the return value for +.Fn BN_div_word +and +.Fn BN_mod_word +in case of an error was 0. diff --git a/Libraries/libressl/man/BN_bn2bin.3 b/Libraries/libressl/man/BN_bn2bin.3 new file mode 100644 index 000000000..0fe9a9073 --- /dev/null +++ b/Libraries/libressl/man/BN_bn2bin.3 @@ -0,0 +1,388 @@ +.\" $OpenBSD: BN_bn2bin.3,v 1.16 2023/07/09 06:45:03 tb Exp $ +.\" full merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file was written by Ulf Moeller +.\" and Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 9 2023 $ +.Dt BN_BN2BIN 3 +.Os +.Sh NAME +.Nm BN_bn2bin , +.Nm BN_bn2binpad , +.Nm BN_bin2bn , +.Nm BN_bn2lebinpad , +.Nm BN_lebin2bn , +.Nm BN_bn2hex , +.Nm BN_bn2dec , +.Nm BN_hex2bn , +.Nm BN_dec2bn , +.Nm BN_asc2bn , +.Nm BN_print , +.Nm BN_print_fp , +.Nm BN_bn2mpi , +.Nm BN_mpi2bn +.Nd format conversions +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_bn2bin +.Fa "const BIGNUM *a" +.Fa "unsigned char *to" +.Fc +.Ft int +.Fo BN_bn2binpad +.Fa "const BIGNUM *a" +.Fa "unsigned char *to" +.Fa "int tolen" +.Fc +.Ft BIGNUM * +.Fo BN_bin2bn +.Fa "const unsigned char *s" +.Fa "int len" +.Fa "BIGNUM *ret" +.Fc +.Ft int +.Fo BN_bn2lebinpad +.Fa "const BIGNUM *a" +.Fa "unsigned char *to" +.Fa "int tolen" +.Fc +.Ft BIGNUM * +.Fo BN_lebin2bn +.Fa "const unsigned char *s" +.Fa "int len" +.Fa "BIGNUM *ret" +.Fc +.Ft char * +.Fo BN_bn2hex +.Fa "const BIGNUM *a" +.Fc +.Ft char * +.Fo BN_bn2dec +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_hex2bn +.Fa "BIGNUM **ap" +.Fa "const char *str" +.Fc +.Ft int +.Fo BN_dec2bn +.Fa "BIGNUM **ap" +.Fa "const char *str" +.Fc +.Ft int +.Fo BN_asc2bn +.Fa "BIGNUM **ap" +.Fa "const char *str" +.Fc +.Ft int +.Fo BN_print +.Fa "BIO *fp" +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_print_fp +.Fa "FILE *fp" +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_bn2mpi +.Fa "const BIGNUM *a" +.Fa "unsigned char *to" +.Fc +.Ft BIGNUM * +.Fo BN_mpi2bn +.Fa "unsigned char *s" +.Fa "int len" +.Fa "BIGNUM *ret" +.Fc +.Sh DESCRIPTION +.Fn BN_bn2bin +converts the absolute value of +.Fa a +into big-endian form and stores it at +.Fa to . +.Fa to +must point to +.Fn BN_num_bytes a +bytes of memory. +.Pp +.Fn BN_bn2binpad +also converts the absolute value of +.Fa a +into big-endian form and stores it at +.Fa to . +.Fa tolen +indicates the length of the output buffer +.Pf * Fa to . +The result is padded with zeros if necessary. +If +.Fa tolen +is less than +.Fn BN_num_bytes a , +an error is returned. +.Pp +.Fn BN_bin2bn +converts the positive integer in big-endian form of length +.Fa len +at +.Fa s +into a +.Vt BIGNUM +and places it in +.Fa ret . +If +.Fa ret +is +.Dv NULL , +a new +.Vt BIGNUM +is created. +.Pp +.Fn BN_bn2lebinpad +and +.Fn BN_lebin2bn +are identical to +.Fn BN_bn2binpad +and +.Fn BN_bin2bn +except the buffer +.Pf * Fa to +is in little-endian format. +.Pp +.Fn BN_bn2hex +and +.Fn BN_bn2dec +return printable strings containing the hexadecimal and decimal encoding of +.Fa a +respectively. +For negative numbers, the string is prefaced with a leading minus sign. +The string must be freed later using +.Xr free 3 . +.Pp +.Fn BN_hex2bn +interprets +.Fa str +as a hexadecimal number. +The string may start with a minus sign +.Pq Sq - . +Conversion stops at the first byte that is not a hexadecimal digit. +The number is converted to a +.Vt BIGNUM +and stored in +.Pf ** Fa ap . +If +.Pf * Fa ap +is +.Dv NULL , +a new +.Vt BIGNUM +is created. +If +.Fa ap +is +.Dv NULL , +it only computes the number's length in hexadecimal digits, +also counting the leading minus sign if there is one. +A "negative zero" is converted to zero. +.Fn BN_dec2bn +is the same using the decimal system. +.Fn BN_asc2bn +infers the number base from an optional prefix. +If +.Fa str +starts with +.Qq 0x +or +.Qq 0X , +it calls +.Fn BN_hex2bn , +otherwise +.Fn BN_dec2bn . +If the number is negative, the minus sign can be given before or +after the prefix. +.Pp +.Fn BN_print +and +.Fn BN_print_fp +write the hexadecimal encoding of +.Fa a , +with a leading minus sign for negative numbers, to the +.Vt BIO +or +.Vt FILE +.Fa fp . +.Pp +.Fn BN_bn2mpi +and +.Fn BN_mpi2bn +convert +.Vt BIGNUM Ns s +from and to a format that consists of the number's length in bytes +represented as a 4-byte big-endian number, and the number itself in +big-endian format, where the most significant bit signals a negative +number (the representation of numbers with the MSB set is prefixed with +a NUL byte). +.Pp +.Fn BN_bn2mpi +stores the representation of +.Fa a +at +.Fa to , +where +.Pf * Fa to +must be large enough to hold the result. +The size can be determined by calling +.Fn BN_bn2mpi a NULL . +.Pp +.Fn BN_mpi2bn +converts the +.Fa len +bytes long representation at +.Fa s +to a +.Vt BIGNUM +and stores it at +.Fa ret , +or in a newly allocated +.Vt BIGNUM +if +.Fa ret +is +.Dv NULL . +.Sh RETURN VALUES +.Fn BN_bn2bin +returns the length of the big-endian number placed at +.Fa to . +.Pp +.Fn BN_bn2binpad +and +.Fn BN_bn2lebinpad +return the number of bytes written +or \-1 if the supplied buffer is too small. +.Pp +.Fn BN_bin2bn +and +.Fn BN_lebin2bn +return the +.Vt BIGNUM , +or +.Dv NULL +on error. +.Pp +.Fn BN_bn2hex +and +.Fn BN_bn2dec +return a NUL-terminated string, or +.Dv NULL +on error. +.Fn BN_hex2bn +and +.Fn BN_dec2bn +return the number's length in hexadecimal or decimal digits, +also counting the leading minus sign if there is one, +or 0 on error, in which case no new +.Vt BIGNUM +is created. +.Fn BN_asc2bn +returns 1 on success or 0 on error, in which case no new +.Vt BIGNUM +is created. +.Pp +.Fn BN_print_fp +and +.Fn BN_print +return 1 on success, 0 on write errors. +.Pp +.Fn BN_bn2mpi +returns the length of the representation. +.Fn BN_mpi2bn +returns the +.Vt BIGNUM , +or +.Dv NULL +on error. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_INTEGER_to_BN 3 , +.Xr BN_new 3 , +.Xr BN_num_bytes 3 , +.Xr BN_zero 3 +.Sh HISTORY +.Fn BN_bn2bin , +.Fn BN_bin2bn , +and +.Fn BN_print +first appeared in SSLeay 0.5.1. +.Fn BN_print_fp +first appeared in SSLeay 0.6.0. +.Fn BN_bn2hex , +.Fn BN_bn2dec , +.Fn BN_hex2bn , +.Fn BN_dec2bn , +.Fn BN_bn2mpi , +and +.Fn BN_mpi2bn +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BN_asc2bin +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Pp +.Fn BN_bn2binpad , +.Fn BN_bn2lebinpad , +and +.Fn BN_lebin2bn +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/BN_cmp.3 b/Libraries/libressl/man/BN_cmp.3 new file mode 100644 index 000000000..ba973313f --- /dev/null +++ b/Libraries/libressl/man/BN_cmp.3 @@ -0,0 +1,169 @@ +.\" $OpenBSD: BN_cmp.3,v 1.10 2022/11/22 19:02:07 schwarze Exp $ +.\" full merge up to: OpenSSL 5b31b9df Aug 4 10:45:52 2021 +0300 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 22 2022 $ +.Dt BN_CMP 3 +.Os +.Sh NAME +.Nm BN_cmp , +.Nm BN_ucmp , +.Nm BN_is_zero , +.Nm BN_is_one , +.Nm BN_is_word , +.Nm BN_abs_is_word , +.Nm BN_is_odd +.Nd BIGNUM comparison and test functions +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_cmp +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fc +.Ft int +.Fo BN_ucmp +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fc +.Ft int +.Fo BN_is_zero +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_is_one +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_is_word +.Fa "const BIGNUM *a" +.Fa "const BN_ULONG w" +.Fc +.Ft int +.Fo BN_abs_is_word +.Fa "const BIGNUM *a" +.Fa "const BN_ULONG w" +.Fc +.Ft int +.Fo BN_is_odd +.Fa "const BIGNUM *a" +.Fc +.Sh DESCRIPTION +.Fn BN_cmp +compares the numbers +.Fa a +and +.Fa b . +.Fn BN_ucmp +compares their absolute values. +.Pp +.Fn BN_is_zero , +.Fn BN_is_one +and +.Fn BN_is_word +test if +.Fa a +equals 0, 1, or +.Fa w +respectively. +.Fn BN_abs_is_word +tests if the absolute value of +.Fa a +equals +.Fa w . +.Fn BN_is_odd +tests if a is odd. +.Pp +.Vt BN_ULONG +is a macro that expands to +.Vt unsigned long Pq = Vt uint64_t +on +.Dv _LP64 +platforms and +.Vt unsigned int Pq = Vt uint32_t +elsewhere. +.Sh RETURN VALUES +.Fn BN_cmp +returns -1 if +.Fa a Ns < Ns Fa b , +0 if +.Fa a Ns == Ns Fa b , +and 1 if +.Fa a Ns > Ns Fa b . +.Fn BN_ucmp +is the same using the absolute values of +.Fa a +and +.Fa b . +.Pp +.Fn BN_is_zero , +.Fn BN_is_one , +.Fn BN_is_word , +.Fn BN_abs_is_word , +and +.Fn BN_is_odd +return 1 if the condition is true, 0 otherwise. +.Sh SEE ALSO +.Xr BN_new 3 +.Sh HISTORY +.Fn BN_cmp , +.Fn BN_ucmp , +.Fn BN_is_zero , +.Fn BN_is_one , +and +.Fn BN_is_word +first appeared in SSLeay 0.5.1. +.Fn BN_is_odd +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn BN_abs_is_word +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/BN_copy.3 b/Libraries/libressl/man/BN_copy.3 new file mode 100644 index 000000000..383255e38 --- /dev/null +++ b/Libraries/libressl/man/BN_copy.3 @@ -0,0 +1,165 @@ +.\" $OpenBSD: BN_copy.3,v 1.10 2021/12/06 19:45:27 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller +.\" and Matt Caswell . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 6 2021 $ +.Dt BN_COPY 3 +.Os +.Sh NAME +.Nm BN_copy , +.Nm BN_dup , +.Nm BN_with_flags +.Nd copy BIGNUMs +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BIGNUM * +.Fo BN_copy +.Fa "BIGNUM *to" +.Fa "const BIGNUM *from" +.Fc +.Ft BIGNUM * +.Fo BN_dup +.Fa "const BIGNUM *from" +.Fc +.Ft void +.Fo BN_with_flags +.Fa "BIGNUM *dest" +.Fa "const BIGNUM *b" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn BN_copy +copies +.Fa from +to +.Fa to . +.Pp +.Fn BN_dup +creates a new +.Vt BIGNUM +containing the value +.Fa from . +.Pp +.Fn BN_with_flags +creates a +.Em temporary +shallow copy of +.Fa b +in +.Fa dest . +It places significant restrictions on the copied data. +Applications that do not adhere to these restrictions +may encounter unexpected side effects or crashes. +For that reason, use of this function is discouraged. +.Pp +Any flags provided in +.Fa flags +will be set in +.Fa dest +in addition to any flags already set in +.Fa b . +For example, this can be used to create a temporary copy of a +.Vt BIGNUM +with the +.Dv BN_FLG_CONSTTIME +flag set for constant time operations. +.Pp +The temporary copy in +.Fa dest +will share some internal state with +.Fa b . +For this reason, the following restrictions apply to the use of +.Fa dest : +.Bl -bullet +.It +.Fa dest +should be a newly allocated +.Vt BIGNUM +obtained via a call to +.Xr BN_new 3 . +It should not have been used for other purposes or initialised in any way. +.It +.Fa dest +must only be used in "read-only" operations, i.e. typically those +functions where the relevant parameter is declared "const". +.It +.Fa dest +must be used and freed before any further subsequent use of +.Fa b . +.El +.Sh RETURN VALUES +.Fn BN_copy +returns +.Fa to +on success or +.Dv NULL +on error. +.Fn BN_dup +returns the new +.Vt BIGNUM +or +.Dv NULL +on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr BN_set_flags 3 +.Sh HISTORY +.Fn BN_copy +and +.Fn BN_dup +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn BN_with_flags +first appeared in OpenSSL 0.9.7h and 0.9.8a +and has been available since +.Ox 4.0 . diff --git a/Libraries/libressl/man/BN_generate_prime.3 b/Libraries/libressl/man/BN_generate_prime.3 new file mode 100644 index 000000000..a7551390e --- /dev/null +++ b/Libraries/libressl/man/BN_generate_prime.3 @@ -0,0 +1,375 @@ +.\" $OpenBSD: BN_generate_prime.3,v 1.24 2023/05/12 08:18:13 jsg Exp $ +.\" full merge up to: OpenSSL f987a4dd Jun 27 10:12:08 2019 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller +.\" Bodo Moeller , and Matt Caswell . +.\" Copyright (c) 2000, 2003, 2013, 2014, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 12 2023 $ +.Dt BN_GENERATE_PRIME 3 +.Os +.Sh NAME +.Nm BN_is_prime_ex , +.Nm BN_is_prime_fasttest_ex , +.Nm BN_generate_prime_ex , +.Nm BN_GENCB_call , +.Nm BN_GENCB_new , +.Nm BN_GENCB_free , +.Nm BN_GENCB_set , +.Nm BN_GENCB_get_arg , +.Nm BN_GENCB_set_old +.\" Nm BN_prime_checks_for_size is intentionally undocumented +.\" because it should not be used outside of libcrypto. +.Nd generate primes and test for primality +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_is_prime_ex +.Fa "const BIGNUM *a" +.Fa "int nchecks" +.Fa "BN_CTX *ctx" +.Fa "BN_GENCB *cb" +.Fc +.Ft int +.Fo BN_is_prime_fasttest_ex +.Fa "const BIGNUM *a" +.Fa "int nchecks" +.Fa "BN_CTX *ctx" +.Fa "int do_trial_division" +.Fa "BN_GENCB *cb" +.Fc +.Ft int +.Fo BN_generate_prime_ex +.Fa "BIGNUM *ret" +.Fa "int bits" +.Fa "int safe" +.Fa "const BIGNUM *modulus" +.Fa "const BIGNUM *remainder" +.Fa "BN_GENCB *cb" +.Fc +.Ft int +.Fo BN_GENCB_call +.Fa "BN_GENCB *cb" +.Fa "int state_code" +.Fa "int serial_number" +.Fc +.Ft BN_GENCB * +.Fn BN_GENCB_new void +.Ft void +.Fo BN_GENCB_free +.Fa "BN_GENCB *cb" +.Fc +.Ft void +.Fo BN_GENCB_set +.Fa "BN_GENCB *cb" +.Fa "int (*cb_fp)(int, int, BN_GENCB *)" +.Fa "void *cb_arg" +.Fc +.Ft void * +.Fo BN_GENCB_get_arg +.Fa "BN_GENCB *cb" +.Fc +.Pp +Deprecated: +.Pp +.Ft void +.Fo BN_GENCB_set_old +.Fa "BN_GENCB *cb" +.Fa "void (*cb_fp)(int, int, void *)" +.Fa "void *cb_arg" +.Fc +.Sh DESCRIPTION +.Fn BN_is_prime_ex +and +.Fn BN_is_prime_fasttest_ex +test whether the number +.Fa a +is prime. +In LibreSSL, both functions behave identically +and use the Baillie-Pomerance-Selfridge-Wagstaff algorithm +combined with +.Fa checks +Miller-Rabin rounds. +The +.Fa do_trial_division +argument is ignored. +.Pp +It is unknown whether any composite number exists that the +Baillie-PSW algorithm misclassifies as a prime. +Some suspect that there may be infinitely many such numbers, +but not a single one is currently known. +It is known that no such number exists below 2\(ha64. +.Pp +In order to reduce the likelihood of a composite number +passing the primality tests +.Fn BN_is_prime_fasttest_ex +and +.Fn BN_is_prime_ex , +a number of rounds of the probabilistic Miller-Rabin test is performed. +If +.Fa checks +is positive, it is used as the number of rounds; +if it is zero or the special value +.Dv BN_prime_checks , +a suitable number of rounds is calculated from the bit length of +.Fa a . +.Pp +If +.Dv NULL +is passed for the +.Fa ctx +argument, these function allocate a +.Vt BN_CTX +object internally when they need one and free it before returning. +Alternatively, to save the overhead of allocating and freeing +that object for each call, the caller can pre-allocate a +.Vt BN_CTX +object and pass it in the +.Fa ctx +argument. +.Pp +.Fn BN_generate_prime_ex +generates a pseudo-random prime number of at least bit length +.Fa bits +and places it in +.Fa ret . +Primality of +.Fa ret +is tested internally using +.Fn BN_is_prime_ex . +Consequently, for +.Fa bits +larger than 64, it is theoretically possible +that this function might place a composite number into +.Fa ret ; +the probability of such an event is unknown but very small. +.Pp +The prime may have to fulfill additional requirements for use in +Diffie-Hellman key exchange: +.Bl -bullet +.It +If +.Fa modulus +is not +.Dv NULL , +a prime is generated that fulfills the condition +.Fa ret No % Fa modulus No = Fa remainder . +If the +.Fa remainder +argument is +.Dv NULL , +1 is used as the desired remainder. +.It +If the +.Fa safe +argument is non-zero, a safe prime is generated, that is, +.Po Fa ret No \- 1 Pc Ns /2 +is also prime. +.El +.Pp +If +.Fa cb +is not +.Dv NULL , +it is used as follows: +.Bl -bullet +.It +.Fn BN_GENCB_call cb 0 serial_number +is called after generating a potential prime number. +.It +The +.Fa state_code +of 1 is reserved for callbacks during primality testing, +but LibreSSL performs no such callbacks. +.It +When +.Fa safe +is non-zero and a safe prime has been found, +.Fn BN_GENCB_call cb 2 serial_number +is called. +.It +The callers of +.Fn BN_generate_prime_ex +may call +.Fn BN_GENCB_call +with other values as described in their respective manual pages; see +.Sx SEE ALSO . +.El +.Pp +In all cases, the +.Fa serial_number +is the number of candidates that have already been discarded +for not being prime; that is, +.Fa serial_number +is 0 for the first candidate +and then incremented whenever a new candidate is generated. +.Pp +.Fn BN_GENCB_call +calls the callback function held in +.Fa cb +and passes the +.Fa state_code +and the +.Fa serial_number +as arguments. +If +.Fa cb +is +.Dv NULL +or does not contain a callback function, no action occurs. +.Pp +.Fn BN_GENCB_new +allocates a new +.Vt BN_GENCB +object. +.Pp +.Fn BN_GENCB_free +frees +.Fa cb . +If +.Fa cb +is +.Dv NULL , +no action occurs. +.Pp +.Fn BN_GENCB_set +initialises +.Fa cb +to use the callback function pointer +.Fa cb_fp +and the additional callback argument +.Fa cb_arg . +.Pp +The deprecated function +.Fn BN_GENCB_set_old +initialises +.Fa cb +to use the old-style callback function pointer +.Fa cb_fp +and the additional callback argument +.Fa cb_arg . +.Sh RETURN VALUES +.Fn BN_is_prime_ex +and +.Fn BN_is_prime_fasttest_ex +return 0 if the number is composite, 1 if it is prime with a very small +error probability, or \-1 on error. +.Pp +.Fn BN_generate_prime_ex +returns 1 on success or 0 on error. +.Pp +.Fn BN_GENCB_call +returns 1 on success, including when +.Fa cb +is +.Dv NULL +or does not contain a callback function, +or 0 on error. +.Pp +.Fn BN_GENCB_new +returns a pointer to the newly allocated +.Vt BN_GENCB +object or +.Dv NULL +if memory allocation fails. +.Pp +The callback functions pointed to by the +.Fa cb_fp +arguments are supposed to return 1 on success or 0 on error. +.Pp +.Fn BN_GENCB_get_arg +returns the +.Fa cb_arg +pointer that was previously stored in +.Fa cb +using +.Fn BN_GENCB_set +or +.Fn BN_GENCB_set_old . +.Pp +In some cases, error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr DH_generate_parameters 3 , +.Xr DSA_generate_parameters 3 , +.Xr RSA_generate_key 3 +.Sh HISTORY +.Fn BN_generate_prime_ex , +.Fn BN_is_prime_ex , +.Fn BN_is_prime_fasttest_ex , +.Fn BN_GENCB_call , +.Fn BN_GENCB_set_old , +and +.Fn BN_GENCB_set +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn BN_GENCB_new , +.Fn BN_GENCB_free , +and +.Fn BN_GENCB_get_arg +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/BN_get_rfc3526_prime_8192.3 b/Libraries/libressl/man/BN_get_rfc3526_prime_8192.3 new file mode 100644 index 000000000..abaf80ef2 --- /dev/null +++ b/Libraries/libressl/man/BN_get_rfc3526_prime_8192.3 @@ -0,0 +1,153 @@ +.\" $OpenBSD: BN_get_rfc3526_prime_8192.3,v 1.1 2023/07/20 16:26:40 tb Exp $ +.\" checked up to: OpenSSL DH_get_1024_160 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 20 2023 $ +.Dt BN_GET_RFC3526_PRIME_8192 3 +.Os +.Sh NAME +.Nm BN_get_rfc2409_prime_768 , +.Nm BN_get_rfc2409_prime_1024 , +.Nm BN_get_rfc3526_prime_1536 , +.Nm BN_get_rfc3526_prime_2048 , +.Nm BN_get_rfc3526_prime_3072 , +.Nm BN_get_rfc3526_prime_4096 , +.Nm BN_get_rfc3526_prime_6144 , +.Nm BN_get_rfc3526_prime_8192 +.Nd standard moduli for Diffie-Hellman key exchange +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BIGNUM * +.Fn BN_get_rfc2409_prime_768 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc2409_prime_1024 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc3526_prime_1536 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc3526_prime_2048 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc3526_prime_3072 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc3526_prime_4096 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc3526_prime_6144 "BIGNUM *bn" +.Ft BIGNUM * +.Fn BN_get_rfc3526_prime_8192 "BIGNUM *bn" +.Sh DESCRIPTION +Each of these functions returns one specific constant Sophie Germain +prime number +.Fa p . +.Pp +If +.Fa bn +is +.Dv NULL , +a new +.Vt BIGNUM +object is created and returned. +Otherwise, the number is stored in +.Pf * Fa bn +and +.Fa bn +is returned. +.Pp +All these numbers are of the form +.Pp +.EQ +p = 2 sup s - 2 sup left ( s - 64 right ) - 1 + 2 sup 64 * +left { left [ 2 sup left ( s - 130 right ) pi right ] + offset right } +delim $$ +.EN +.Pp +where +.Ar s +is the size of the binary representation of the number in bits +and appears at the end of the function names. +As long as the offset is sufficiently small, the above form assures +that the top and bottom 64 bits of each number are all 1. +.Pp +The offsets are defined in the standards as follows: +.Bl -column "8192 = 2 * 2^12" "4743158" -offset indent +.It size Ar s Ta Ar offset +.It Ta +.It \ 768 = 3 * 2^8 Ta 149686 +.It 1024 = 2 * 2^9 Ta 129093 +.It 1536 = 3 * 2^9 Ta 741804 +.It 2048 = 2 * 2^10 Ta 124476 +.It 3072 = 3 * 2^10 Ta 1690314 +.It 4096 = 2 * 2^11 Ta 240904 +.It 6144 = 3 * 2^11 Ta 929484 +.It 8192 = 2 * 2^12 Ta 4743158 +.El +.Pp +For each of these prime numbers, the finite group of natural numbers +smaller than +.Fa p , +where the group operation is defined as multiplication modulo +.Fa p , +is used for Diffie-Hellman key exchange. +The first two of these groups are called the First Oakley Group and +the Second Oakley Group. +Obviously, all these groups are cyclic groups of order +.Fa p , +respectively, and the numbers returned by these functions are not +secrets. +.Sh RETURN VALUES +If memory allocation fails, these functions return +.Dv NULL . +That can happen even if +.Fa bn +is not +.Dv NULL . +.Sh SEE ALSO +.Xr BN_mod_exp 3 , +.Xr BN_new 3 , +.Xr BN_set_flags 3 , +.Xr DH_new 3 +.Sh STANDARDS +RFC 2409, "The Internet Key Exchange (IKE)", defines the Oakley Groups. +.Pp +RFC 2412, "The OAKLEY Key Determination Protocol", contains additional +information about these numbers. +.Pp +RFC 3526, "More Modular Exponential (MODP) Diffie-Hellman groups +for Internet Key Exchange (IKE)", defines the other six numbers. +.Sh HISTORY +.Fn BN_get_rfc2409_prime_768 , +.Fn BN_get_rfc2409_prime_1024 , +.Fn BN_get_rfc3526_prime_1536 , +.Fn BN_get_rfc3526_prime_2048 , +.Fn BN_get_rfc3526_prime_3072 , +.Fn BN_get_rfc3526_prime_4096 , +.Fn BN_get_rfc3526_prime_6144 , +and +.Fn BN_get_rfc3526_prime_8192 +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +The same functions without +.Sy BN_ +prefix first appeared in OpenSSL 0.9.8a and +.Ox 4.5 ; +they were removed in +.Ox 7.4 . +.Sh CAVEATS +As all the memory needed for storing the numbers is dynamically +allocated, the +.Dv BN_FLG_STATIC_DATA +flag is not set on the returned +.Vt BIGNUM +objects. +So be careful to not change the returned numbers. diff --git a/Libraries/libressl/man/BN_kronecker.3 b/Libraries/libressl/man/BN_kronecker.3 new file mode 100644 index 000000000..90b7f4323 --- /dev/null +++ b/Libraries/libressl/man/BN_kronecker.3 @@ -0,0 +1,57 @@ +.\" $OpenBSD: BN_kronecker.3,v 1.2 2022/11/15 17:55:00 schwarze Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 15 2022 $ +.Dt BN_KRONECKER 3 +.Os +.Sh NAME +.Nm BN_kronecker +.Nd Kronecker symbol +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_kronecker +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn BN_kronecker +computes the Kronecker symbol +.Pq a | b , +which generalizes the Legendre and Jacobi symbols +for arbitrary integer numbers +.Fa b . +.Sh RETURN VALUES +.Fn BN_kronecker +returns \-1, 0, or 1 in case of success or \-2 on error. +.Sh SEE ALSO +.Xr BN_CTX_new 3 , +.Xr BN_gcd 3 , +.Xr BN_mod_sqrt 3 , +.Xr BN_new 3 +.Rs +.%A Henri Cohen +.%B A Course in Computational Algebraic Number Theory +.%I Springer +.%C Berlin +.%D 1993 +.%O Algorithm 1.4.10 +.Re +.Sh HISTORY +.Fn BN_kronecker +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/BN_mod_inverse.3 b/Libraries/libressl/man/BN_mod_inverse.3 new file mode 100644 index 000000000..788f66fb9 --- /dev/null +++ b/Libraries/libressl/man/BN_mod_inverse.3 @@ -0,0 +1,123 @@ +.\" $OpenBSD: BN_mod_inverse.3,v 1.11 2021/11/30 18:34:35 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 30 2021 $ +.Dt BN_MOD_INVERSE 3 +.Os +.Sh NAME +.Nm BN_mod_inverse +.Nd compute inverse modulo n +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BIGNUM * +.Fo BN_mod_inverse +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *n" +.Fa "BN_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn BN_mod_inverse +computes the inverse of +.Fa a +modulo +.Fa n +and places the result in +.Fa r +.Pq Li (a*r)%n==1 . +If +.Fa r +is +.Dv NULL , +a new +.Vt BIGNUM +is created. +.Pp +If the flag +.Dv BN_FLG_CONSTTIME +is set on +.Fa a +or +.Fa n , +it operates in constant time. +.Pp +.Fa ctx +is a previously allocated +.Vt BN_CTX +used for temporary variables. +.Fa r +may be the same +.Vt BIGNUM +as +.Fa a +or +.Fa n . +.Sh RETURN VALUES +.Fn BN_mod_inverse +returns the +.Vt BIGNUM +containing the inverse, or +.Dv NULL +on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_new 3 , +.Xr BN_set_flags 3 +.Sh HISTORY +.Fn BN_mod_inverse +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . +.Pp +The +.Fa r +argument was added in SSLeay 0.9.1 and +.Ox 2.6 . diff --git a/Libraries/libressl/man/BN_mod_mul_montgomery.3 b/Libraries/libressl/man/BN_mod_mul_montgomery.3 new file mode 100644 index 000000000..0815eced4 --- /dev/null +++ b/Libraries/libressl/man/BN_mod_mul_montgomery.3 @@ -0,0 +1,271 @@ +.\" $OpenBSD: BN_mod_mul_montgomery.3,v 1.15 2023/04/21 06:34:37 tb Exp $ +.\" full merge up to: OpenSSL 6859cf74 Sep 25 13:33:28 2002 +0000 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 21 2023 $ +.Dt BN_MOD_MUL_MONTGOMERY 3 +.Os +.Sh NAME +.Nm BN_MONT_CTX_new , +.Nm BN_MONT_CTX_free , +.Nm BN_MONT_CTX_set , +.Nm BN_MONT_CTX_set_locked , +.Nm BN_MONT_CTX_copy , +.Nm BN_mod_mul_montgomery , +.Nm BN_from_montgomery , +.Nm BN_to_montgomery +.Nd Montgomery multiplication +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BN_MONT_CTX * +.Fo BN_MONT_CTX_new +.Fa void +.Fc +.Ft void +.Fo BN_MONT_CTX_free +.Fa "BN_MONT_CTX *mont" +.Fc +.Ft int +.Fo BN_MONT_CTX_set +.Fa "BN_MONT_CTX *mont" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft BN_MONT_CTX * +.Fo BN_MONT_CTX_set_locked +.Fa "BN_MONT_CTX **pmont" +.Fa "int lock" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft BN_MONT_CTX * +.Fo BN_MONT_CTX_copy +.Fa "BN_MONT_CTX *to" +.Fa "BN_MONT_CTX *from" +.Fc +.Ft int +.Fo BN_mod_mul_montgomery +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_MONT_CTX *mont" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_from_montgomery +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "BN_MONT_CTX *mont" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo BN_to_montgomery +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "BN_MONT_CTX *mont" +.Fa "BN_CTX *ctx" +.Fc +.Sh DESCRIPTION +These functions implement Montgomery multiplication. +They are used automatically when +.Xr BN_mod_exp 3 +is called with suitable input, but they may be useful when several +operations are to be performed using the same modulus. +.Pp +.Fn BN_MONT_CTX_new +allocates and initializes a +.Vt BN_MONT_CTX +structure. +.Pp +.Fn BN_MONT_CTX_set +sets up the +.Fa mont +structure from the modulus +.Fa m +by precomputing its inverse and a value R. +.Pp +.Fn BN_MONT_CTX_set_locked +is a wrapper around +.Fn BN_MONT_CTX_new +and +.Fn BN_MONT_CTX_set +that is useful if more than one thread intends to use the same +.Vt BN_MONT_CTX +and none of these threads is exclusively responsible for creating +and initializing the context. +.Fn BN_MONT_CTX_set_locked +first acquires the specified +.Fa lock +using +.Xr CRYPTO_lock 3 . +If +.Pf * Fa pmont +already differs from +.Dv NULL , +no action occurs. +Otherwise, a new +.Vt BN_MONT_CTX +is allocated with +.Fn BN_MONT_CTX_new , +set up with +.Fn BN_MONT_CTX_set , +and a pointer to it is stored in +.Pf * Fa pmont . +Finally, the +.Fa lock +is released. +.Pp +.Fn BN_MONT_CTX_copy +copies the +.Vt BN_MONT_CTX +.Fa from +to +.Fa to . +.Pp +.Fn BN_MONT_CTX_free +frees the components of the +.Vt BN_MONT_CTX , +and, if it was created by +.Fn BN_MONT_CTX_new , +also the structure itself. +If +.Fa mont +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn BN_mod_mul_montgomery +computes +.Pp +.D1 Mont Ns Po Fa a , Fa b Pc := Fa a No * Fa b No * R^-1 +.Pp +and places the result in +.Fa r . +.Pp +.Fn BN_from_montgomery +performs the Montgomery reduction +.Pp +.D1 Fa r No = Fa a No * R^-1 +.Pp +.Fn BN_to_montgomery +computes +.Pp +.D1 Mont Ns Po Fa a , No R^2 Pc = Fa a No * R +.Pp +Note that +.Fa a +must be non-negative and smaller than the modulus. +.Pp +For all functions, +.Fa ctx +is a previously allocated +.Vt BN_CTX +used for temporary variables. +.Pp +.Sy Warning : +The inputs must be reduced modulo +.Fa m , +otherwise the result will be outside the expected range. +.Sh RETURN VALUES +.Fn BN_MONT_CTX_new +returns the newly allocated +.Vt BN_MONT_CTX +or +.Dv NULL +on error. +.Pp +.Fn BN_MONT_CTX_set_locked +returns a pointer to the existing or newly created context or +.Dv NULL +on error. +.Pp +For the other functions, 1 is returned for success or 0 on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_CTX_new 3 , +.Xr BN_new 3 , +.Xr CRYPTO_lock 3 +.Sh HISTORY +.Fn BN_MONT_CTX_new , +.Fn BN_MONT_CTX_free , +.Fn BN_MONT_CTX_set , +.Fn BN_mod_mul_montgomery , +.Fn BN_from_montgomery , +and +.Fn BN_to_montgomery +first appeared in SSLeay 0.6.1 and have been available since +.Ox 2.4 . +.Pp +.Fn BN_MONT_CTX_copy +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . +.Pp +.Fn BN_MONT_CTX_set_locked +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.0 . diff --git a/Libraries/libressl/man/BN_mod_sqrt.3 b/Libraries/libressl/man/BN_mod_sqrt.3 new file mode 100644 index 000000000..7247d907a --- /dev/null +++ b/Libraries/libressl/man/BN_mod_sqrt.3 @@ -0,0 +1,111 @@ +.\" $OpenBSD: BN_mod_sqrt.3,v 1.2 2022/12/06 22:22:42 tb Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 6 2022 $ +.Dt BN_MOD_SQRT 3 +.Os +.Sh NAME +.Nm BN_mod_sqrt +.Nd square root in a prime field +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BIGNUM * +.Fo BN_mod_sqrt +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *p" +.Fa "BN_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn BN_mod_sqrt +solves +.Bd -unfilled -offset indent +.EQ +r sup 2 == a ( roman mod p ) +.EN +.Ed +.Pp +for +.Fa r +in the prime field of characteristic +.Fa p +using the Tonelli-Shanks algorithm if needed +and places one of the two solutions into +.Fa r . +The other solution is +.Fa p +\- +.Fa r . +.Pp +The argument +.Fa p +is expected to be a prime number. +.Sh RETURN VALUES +In case of success, +.Fn BN_mod_sqrt +returns +.Fa r , +or a newly allocated +.Vt BIGNUM +object if the +.Fa r +argument is +.Dv NULL . +.Pp +In case of failure, +.Dv NULL +is returned. +This for example happens if +.Fa a +is not a quadratic residue or if memory allocation fails. +.Sh SEE ALSO +.Xr BN_CTX_new 3 , +.Xr BN_kronecker 3 , +.Xr BN_mod_sqr 3 , +.Xr BN_new 3 +.Rs +.%A Henri Cohen +.%B A Course in Computational Algebraic Number Theory +.%I Springer +.%C Berlin +.%D 1993 +.%O Algorithm 1.5.1 +.Re +.Sh HISTORY +.Fn BN_mod_sqrt +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh CAVEATS +If +.Fa p +is not prime, +.Fn BN_mod_sqrt +may succeed or fail. +If it succeeds, the square of the returned value is congruent to +.Fa a +modulo +.Fa p . +If it fails, the reason reported by +.Xr ERR_get_error 3 +is often misleading. +In particular, even if +.Fa a +is a perfect square, +.Fn BN_mod_sqrt +often reports +.Dq not a square +instead of +.Dq p is not prime . diff --git a/Libraries/libressl/man/BN_new.3 b/Libraries/libressl/man/BN_new.3 new file mode 100644 index 000000000..088048c62 --- /dev/null +++ b/Libraries/libressl/man/BN_new.3 @@ -0,0 +1,165 @@ +.\" $OpenBSD: BN_new.3,v 1.31 2023/07/26 20:08:59 tb Exp $ +.\" full merge up to: OpenSSL man3/BN_new 2457c19d Mar 6 08:43:36 2004 +0000 +.\" selective merge up to: man3/BN_new 681acb31 Sep 29 13:10:34 2017 +0200 +.\" full merge up to: OpenSSL man7/bn 05ea606a May 20 20:52:46 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2004 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt BN_NEW 3 +.Os +.Sh NAME +.Nm BN_new , +.Nm BN_clear , +.Nm BN_free , +.Nm BN_clear_free +.Nd allocate and free BIGNUMs +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BIGNUM * +.Fo BN_new +.Fa void +.Fc +.Ft void +.Fo BN_clear +.Fa "BIGNUM *a" +.Fc +.Ft void +.Fo BN_free +.Fa "BIGNUM *a" +.Fc +.Ft void +.Fo BN_clear_free +.Fa "BIGNUM *a" +.Fc +.Sh DESCRIPTION +The BN library performs arithmetic operations on integers of arbitrary +size. +It was written for use in public key cryptography, such as RSA and +Diffie-Hellman. +.Pp +It uses dynamic memory allocation for storing its data structures. +That means that there is no limit on the size of the numbers manipulated +by these functions, but return values must always be checked in case a +memory allocation error has occurred. +.Pp +The basic object in this library is a +.Vt BIGNUM . +It is used to hold a single large integer. +This type should be considered opaque and fields should not be modified +or accessed directly. +.Pp +.Fn BN_new +allocates and initializes a +.Vt BIGNUM +structure, in particular setting the value to zero and the flags to +.Dv BN_FLG_MALLOCED . +The security-relevant flag +.Dv BN_FLG_CONSTTIME +is not set by default. +.Pp +.Fn BN_clear +is used to destroy sensitive data such as keys when they are no longer +needed. +It erases the memory used by +.Fa a +and sets it to the value 0. +.Pp +.Fn BN_free +frees the components of the +.Vt BIGNUM +and, if it was created by +.Fn BN_new , +also the structure itself. +.Fn BN_clear_free +additionally overwrites the data before the memory is returned to the +system. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn BN_new +returns a pointer to the +.Vt BIGNUM . +If the allocation fails, it returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_add_word 3 , +.Xr BN_bn2bin 3 , +.Xr BN_cmp 3 , +.Xr BN_copy 3 , +.Xr BN_CTX_new 3 , +.Xr BN_CTX_start 3 , +.Xr BN_generate_prime 3 , +.Xr BN_get_rfc3526_prime_8192 3 , +.Xr BN_kronecker 3 , +.Xr BN_mod_inverse 3 , +.Xr BN_mod_mul_montgomery 3 , +.Xr BN_mod_sqrt 3 , +.Xr BN_num_bytes 3 , +.Xr BN_rand 3 , +.Xr BN_security_bits 3 , +.Xr BN_set_bit 3 , +.Xr BN_set_flags 3 , +.Xr BN_set_negative 3 , +.Xr BN_swap 3 , +.Xr BN_zero 3 , +.Xr crypto 3 +.Sh HISTORY +.Fn BN_new , +.Fn BN_clear , +.Fn BN_free , +and +.Fn BN_clear_free +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BN_num_bytes.3 b/Libraries/libressl/man/BN_num_bytes.3 new file mode 100644 index 000000000..785f43e2f --- /dev/null +++ b/Libraries/libressl/man/BN_num_bytes.3 @@ -0,0 +1,175 @@ +.\" $OpenBSD: BN_num_bytes.3,v 1.9 2022/11/22 18:55:04 schwarze Exp $ +.\" full merge up to: OpenSSL 9e183d22 Mar 11 08:56:44 2017 -0500 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller +.\" and Richard Levitte . +.\" Copyright (c) 2000, 2004 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 22 2022 $ +.Dt BN_NUM_BYTES 3 +.Os +.Sh NAME +.Nm BN_num_bits_word , +.Nm BN_num_bits , +.Nm BN_num_bytes +.Nd get BIGNUM size +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_num_bits_word +.Fa "BN_ULONG w" +.Fc +.Ft int +.Fo BN_num_bits +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_num_bytes +.Fa "const BIGNUM *a" +.Fc +.Sh DESCRIPTION +.Fn BN_num_bits_word +returns the number of significant bits in +.Fa w , +that is, the minimum number of digits needed to write +.Fa w +as a binary number. +Except for an argument of 0, this is +.Pp +.D1 floor(log2( Ns Fa w ) ) No + 1 . +.Pp +.Vt BN_ULONG +is a macro that expands to +.Vt unsigned long Pq = Vt uint64_t +on +.Dv _LP64 +platforms and +.Vt unsigned int Pq = Vt uint32_t +elsewhere. +.Pp +.Fn BN_num_bits +returns the number of significant bits in the value of the +.Fa "BIGNUM *a" , +following the same principle as +.Fn BN_num_bits_word . +.Pp +.Fn BN_num_bytes +is a macro that returns the number of significant bytes in +.Fa a , +i.e. the minimum number of bytes needed to store the value of +.Fa a , +that is, +.Fn BN_num_bits a +divided by eight and rounded up to the next integer number. +.Sh RETURN VALUES +.Fn BN_num_bits_word +returns the number of significant bits in +.Fa w +or 0 if +.Fa w +is 0. +The maximum return value that can occur is +.Dv BN_BITS2 , +which is 64 on +.Dv _LP64 +platforms and 32 elsewhere. +.Pp +.Fn BN_num_bits +returns the number of significant bits and +.Fn BN_num_bytes +the number of significant bytes in +.Fa a , +or 0 if the value of +.Fa a +is 0. +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr BN_security_bits 3 , +.Xr DH_size 3 , +.Xr DSA_size 3 , +.Xr RSA_size 3 +.Sh HISTORY +.Fn BN_num_bytes +and +.Fn BN_num_bits +first appeared in SSLeay 0.5.1. +.Fn BN_num_bits_word +first appeared in SSLeay 0.5.2. +These functions have been available since +.Ox 2.4 . +.Sh CAVEATS +Some have tried using +.Fn BN_num_bits +on individual numbers in RSA keys, DH keys and DSA keys, and found that +they don't always come up with the number of bits they expected +(something like 512, 1024, 2048, ...). +This is because generating a number with some specific number of bits +doesn't always set the highest bits, thereby making the number of +.Em significant +bits a little smaller. +If you want to know the "key size" of such a key, use functions like +.Xr RSA_size 3 , +.Xr DH_size 3 , +and +.Xr DSA_size 3 . diff --git a/Libraries/libressl/man/BN_rand.3 b/Libraries/libressl/man/BN_rand.3 new file mode 100644 index 000000000..3d4401a42 --- /dev/null +++ b/Libraries/libressl/man/BN_rand.3 @@ -0,0 +1,146 @@ +.\" $OpenBSD: BN_rand.3,v 1.18 2021/11/30 18:34:35 tb Exp $ +.\" full merge up to: OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" selective merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2001, 2002, 2013, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 30 2021 $ +.Dt BN_RAND 3 +.Os +.Sh NAME +.Nm BN_rand , +.Nm BN_rand_range , +.Nm BN_pseudo_rand , +.Nm BN_pseudo_rand_range +.Nd generate pseudo-random number +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_rand +.Fa "BIGNUM *rnd" +.Fa "int bits" +.Fa "int top" +.Fa "int bottom" +.Fc +.Ft int +.Fo BN_rand_range +.Fa "BIGNUM *rnd" +.Fa "const BIGNUM *range" +.Fc +.Sh DESCRIPTION +.Fn BN_rand +generates a cryptographically strong pseudo-random number of +.Fa bits +in length and stores it in +.Fa rnd . +If +.Fa top +is +.Dv BN_RAND_TOP_ANY , +the most significant bit of the random number can be zero. +If +.Fa top +is +.Dv BN_RAND_TOP_ONE , +the most significant bit is set to 1, and if +.Fa top +is +.Dv BN_RAND_TOP_TWO , +the two most significant bits of the number will be set to 1, so +that the product of two such random numbers will always have +.Pf 2* Fa bits +length. +If +.Fa bottom +is +.Dv BN_RAND_BOTTOM_ODD , +the number will be odd; +if it is +.Dv BN_RAND_BOTTOM_ANY , +it can be odd or even. +The value of +.Fa bits +must be zero or greater. +If +.Fa bits +is +1 then +.Fa top +cannot be +.Dv BN_RAND_TOP_TWO . +.Pp +.Fn BN_rand_range +generates a cryptographically strong pseudo-random number +.Fa rnd +in the range 0 <= +.Fa rnd No < Fa range . +.Pp +.Fn BN_pseudo_rand +is a deprecated alias for +.Fn BN_rand , +and +.Fn BN_pseudo_rand_range +for +.Fn BN_rand_range . +.Sh RETURN VALUES +The functions return 1 on success, 0 on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_new 3 +.Sh HISTORY +.Fn BN_rand +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . +.Pp +The +.Fa top +== -1 case and the function +.Fn BN_rand_range +first appeared in OpenSSL 0.9.6a and have been available since +.Ox 3.0 . diff --git a/Libraries/libressl/man/BN_set_bit.3 b/Libraries/libressl/man/BN_set_bit.3 new file mode 100644 index 000000000..2c5306677 --- /dev/null +++ b/Libraries/libressl/man/BN_set_bit.3 @@ -0,0 +1,216 @@ +.\" $OpenBSD: BN_set_bit.3,v 1.8 2021/11/30 18:34:35 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 30 2021 $ +.Dt BN_SET_BIT 3 +.Os +.Sh NAME +.Nm BN_set_bit , +.Nm BN_clear_bit , +.Nm BN_is_bit_set , +.Nm BN_mask_bits , +.Nm BN_lshift , +.Nm BN_lshift1 , +.Nm BN_rshift , +.Nm BN_rshift1 +.Nd bit operations on BIGNUMs +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_set_bit +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Ft int +.Fo BN_clear_bit +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Ft int +.Fo BN_is_bit_set +.Fa "const BIGNUM *a" +.Fa "int n" +.Fc +.Ft int +.Fo BN_mask_bits +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Ft int +.Fo BN_lshift +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "int n" +.Fc +.Ft int +.Fo BN_lshift1 +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fc +.Ft int +.Fo BN_rshift +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "int n" +.Fc +.Ft int +.Fo BN_rshift1 +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fc +.Sh DESCRIPTION +.Fn BN_set_bit +sets bit +.Fa n +in +.Fa a +to 1 +.Pq Li a|=(1<>n) . +An error occurs if +.Fa a +already is shorter than +.Fa n +bits. +.Pp +.Fn BN_lshift +shifts +.Fa a +left by +.Fa n +bits and places the result in +.Fa r +.Pq Li r=a*2^n . +Note that +.Fa n +must be non-negative. +.Fn BN_lshift1 +shifts +.Fa a +left by one and places the result in +.Fa r +.Pq Li r=2*a . +.Pp +.Fn BN_rshift +shifts +.Fa a +right by +.Fa n +bits and places the result in +.Fa r +.Pq Li r=a/2^n . +Note that +.Fa n +must be non-negative. +.Fn BN_rshift1 +shifts +.Fa a +right by one and places the result in +.Fa r +.Pq Li r=a/2 . +.Pp +For the shift functions, +.Fa r +and +.Fa a +may be the same variable. +.Sh RETURN VALUES +.Fn BN_is_bit_set +returns 1 if the bit is set, 0 otherwise. +.Pp +All other functions return 1 for success, 0 on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_new 3 , +.Xr BN_num_bytes 3 , +.Xr BN_set_negative 3 , +.Xr BN_zero 3 +.Sh HISTORY +.Fn BN_set_bit , +.Fn BN_clear_bit , +.Fn BN_is_bit_set , +.Fn BN_mask_bits , +.Fn BN_lshift , +.Fn BN_lshift1 , +.Fn BN_rshift , +and +.Fn BN_rshift1 +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/BN_set_flags.3 b/Libraries/libressl/man/BN_set_flags.3 new file mode 100644 index 000000000..1285ae2b2 --- /dev/null +++ b/Libraries/libressl/man/BN_set_flags.3 @@ -0,0 +1,160 @@ +.\" $OpenBSD: BN_set_flags.3,v 1.6 2023/04/27 07:22:22 tb Exp $ +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 27 2023 $ +.Dt BN_SET_FLAGS 3 +.Os +.Sh NAME +.Nm BN_set_flags , +.Nm BN_get_flags +.Nd enable and inspect flags on BIGNUM objects +.Sh SYNOPSIS +.In openssl/bn.h +.Ft void +.Fo BN_set_flags +.Fa "BIGNUM *b" +.Fa "int flags" +.Fc +.Ft int +.Fo BN_get_flags +.Fa "const BIGNUM *b" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn BN_set_flags +enables the given +.Fa flags +on +.Fa b . +The +.Fa flags +argument can contain zero or more of the following constants OR'ed +together: +.Bl -tag -width Ds +.It Dv BN_FLG_CONSTTIME +If this flag is set on the divident +.Fa a +or the divisor +.Fa d +in +.Xr BN_div 3 , +on the exponent +.Fa p +in +.Xr BN_mod_exp 3 , +or on the divisor +.Fa a +or the modulus +.Fa n +in +.Xr BN_mod_inverse 3 , +these functions select algorithms with an execution time independent +of the respective numbers, to avoid exposing sensitive information +to timing side-channel attacks. +.Pp +This flag is off by default for +.Vt BIGNUM +objects created with +.Xr BN_new 3 . +.It Dv BN_FLG_MALLOCED +If this flag is set, +.Xr BN_free 3 +and +.Xr BN_clear_free 3 +will not only clear and free the components of +.Fa b , +but also +.Fa b +itself. +This flag is set internally by +.Xr BN_new 3 . +Setting it manually on an existing +.Vt BIGNUM +object is usually a bad idea and can cause calls to +.Xr free 3 +with bogus arguments. +.It Dv BN_FLG_STATIC_DATA +If this flag is set, +.Xr BN_clear_free 3 +will neither clear nor free the memory used for storing the number. +Consequently, setting it manually on an existing +.Vt BIGNUM +object is usually a terrible idea that can cause both disclosure +of secret data and memory leaks. +This flag is automatically set on the constant +.Vt BIGNUM +object returned by +.Xr BN_value_one 3 . +.El +.Pp +.Fn BN_get_flags +interprets +.Fa flags +as a bitmask and returns those of the given flags that are set in +.Fa b , +OR'ed together, or 0 if none of the given +.Fa flags +is set. +The +.Fa flags +argument has the same syntax as for +.Fn BN_set_flags . +.Sh RETURN VALUES +.Fn BN_get_flags +returns zero or more of the above constants, OR'ed together. +.Sh SEE ALSO +.Xr BN_mod_exp 3 , +.Xr BN_mod_inverse 3 , +.Xr BN_new 3 , +.Xr BN_with_flags 3 +.Sh HISTORY +.Fn BN_set_flags +and +.Fn BN_get_flags +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . +.Sh CAVEATS +No public interface exists to clear a flag once it is set. +So think twice before using +.Fn BN_set_flags . +.Sh BUGS +Even if the +.Dv BN_FLG_CONSTTIME +flag is set on +.Fa a +or +.Fa b , +.Fn BN_gcd +neither fails nor operates in constant time, potentially allowing +timing side-channel attacks. +.Pp +Even if the +.Dv BN_FLG_CONSTTIME +flag is set on +.Fa p , +if the modulus +.Fa m +is even, +.Xr BN_mod_exp 3 +does not operate in constant time, potentially allowing +timing side-channel attacks. +.Pp +If +.Dv BN_FLG_CONSTTIME +is set on +.Fa p , +.Fn BN_exp +fails instead of operating in constant time. diff --git a/Libraries/libressl/man/BN_set_negative.3 b/Libraries/libressl/man/BN_set_negative.3 new file mode 100644 index 000000000..6cdff5c97 --- /dev/null +++ b/Libraries/libressl/man/BN_set_negative.3 @@ -0,0 +1,63 @@ +.\" $OpenBSD: BN_set_negative.3,v 1.6 2021/12/06 19:45:27 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 6 2021 $ +.Dt BN_SET_NEGATIVE 3 +.Os +.Sh NAME +.Nm BN_set_negative , +.Nm BN_is_negative +.Nd change and inspect the sign of a BIGNUM +.Sh SYNOPSIS +.In openssl/bn.h +.Ft void +.Fo BN_set_negative +.Fa "BIGNUM *b" +.Fa "int n" +.Fc +.Ft int +.Fo BN_is_negative +.Fa "const BIGNUM *b" +.Fc +.Sh DESCRIPTION +.Fn BN_set_negative +sets +.Fa b +to negative if both +.Fa b +and +.Fa n +are non-zero, otherwise it sets it to positive. +.Pp +.Fn BN_is_negative +tests the sign of +.Fa b . +.Sh RETURN VALUES +.Fn BN_is_negative +returns 1 if +.Fa b +is negative or 0 otherwise. +.Sh SEE ALSO +.Xr BN_add 3 , +.Xr BN_new 3 , +.Xr BN_set_bit 3 , +.Xr BN_zero 3 +.Sh HISTORY +.Fn BN_set_negative +and +.Fn BN_is_negative +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/BN_swap.3 b/Libraries/libressl/man/BN_swap.3 new file mode 100644 index 000000000..218ca1cf0 --- /dev/null +++ b/Libraries/libressl/man/BN_swap.3 @@ -0,0 +1,148 @@ +.\" $OpenBSD: BN_swap.3,v 1.6 2021/12/19 22:06:35 schwarze Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Bodo Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 19 2021 $ +.Dt BN_SWAP 3 +.Os +.Sh NAME +.Nm BN_swap , +.Nm BN_consttime_swap +.Nd exchange BIGNUMs +.Sh SYNOPSIS +.In openssl/bn.h +.Ft void +.Fo BN_swap +.Fa "BIGNUM *a" +.Fa "BIGNUM *b" +.Fc +.Ft void +.Fo BN_consttime_swap +.Fa "BN_ULONG condition" +.Fa "BIGNUM *a" +.Fa "BIGNUM *b" +.Fa "int nwords" +.Fc +.Sh DESCRIPTION +.Fn BN_swap +and +.Fn BN_consttime_swap +exchange the values of +.Fa a +and +.Fa b . +.Pp +.Fn BN_swap +implements this by exchanging the pointers to the data buffers of +.Fa a +and +.Fa b +and also exchanging the values of the +.Dv BN_FLG_STATIC_DATA +bits. +Consequently, the operation is fast and execution time does not depend +on any properties of the two numbers. +However, execution time obviously differs between swapping (by calling +this function) and not swapping (by not calling this function). +.Pp +.Fn BN_consttime_swap +only performs the exchange if the +.Fa condition +is non-zero; otherwise, it has no effect. +It implements the exchange by exchanging the contents of the data +buffers rather than the pointers to the data buffers. +This is slower, but implemented in such a way that the execution time +is not only independent of the properties of the two numbers, but also +independent of the +.Fa condition +argument, i.e. the same for swapping or not swapping. +Execution time does however grow in an approximately linear manner with the +.Fa nwords +argument. +.Pp +.Fn BN_consttime_swap +calls +.Xr abort 3 +if at least one of +.Fa a +or +.Fa b +has fewer than +.Fa nwords +data words allocated or more than +.Fa nwords +data words are currently in use in at least one of them. +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr BN_set_flags 3 +.Sh HISTORY +.Fn BN_swap +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Pp +.Fn BN_consttime_swap +first appeared in OpenSSL 1.0.1g and has been available since +.Ox 5.6 . diff --git a/Libraries/libressl/man/BN_zero.3 b/Libraries/libressl/man/BN_zero.3 new file mode 100644 index 000000000..0b677b246 --- /dev/null +++ b/Libraries/libressl/man/BN_zero.3 @@ -0,0 +1,174 @@ +.\" $OpenBSD: BN_zero.3,v 1.13 2023/04/30 19:23:54 tb Exp $ +.\" full merge up to: OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" selective merge up to: OpenSSL b713c4ff Jan 22 14:41:09 2018 -0500 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2001, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt BN_ZERO 3 +.Os +.Sh NAME +.Nm BN_zero , +.Nm BN_one , +.Nm BN_value_one , +.Nm BN_set_word , +.Nm BN_get_word +.Nd BIGNUM assignment operations +.Sh SYNOPSIS +.In openssl/bn.h +.Ft int +.Fo BN_zero +.Fa "BIGNUM *a" +.Fc +.Ft int +.Fo BN_one +.Fa "BIGNUM *a" +.Fc +.Ft const BIGNUM * +.Fo BN_value_one +.Fa void +.Fc +.Ft int +.Fo BN_set_word +.Fa "BIGNUM *a" +.Fa "BN_ULONG w" +.Fc +.Ft BN_ULONG +.Fo BN_get_word +.Fa "const BIGNUM *a" +.Fc +.Sh DESCRIPTION +.Vt BN_ULONG +is a macro that expands to an unsigned integral type optimized +for the most efficient implementation on the local platform. +It is +.Vt unsigned long Pq = Vt uint64_t +on +.Dv _LP64 +platforms and +.Vt unsigned int Pq = Vt uint32_t +elsewhere. +.Pp +.Fn BN_zero , +.Fn BN_one , +and +.Fn BN_set_word +set +.Fa a +to the values 0, 1 and +.Fa w +respectively. +.Pp +.Fn BN_value_one +returns a +.Vt BIGNUM +constant of value 1. +This constant is useful for comparisons and assignments. +.Sh RETURN VALUES +.Fn BN_get_word +returns the value +.Fa a , +or a number with all bits set if +.Fa a +cannot be represented as a +.Vt BN_ULONG . +.Pp +.Fn BN_zero , +.Fn BN_one , +and +.Fn BN_set_word +return 1 on success, 0 otherwise. +.Fn BN_value_one +returns the constant. +.Sh SEE ALSO +.Xr BN_bn2bin 3 , +.Xr BN_new 3 , +.Xr BN_set_bit 3 , +.Xr BN_set_negative 3 +.Sh HISTORY +.Fn BN_zero , +.Fn BN_one , +.Fn BN_value_one , +and +.Fn BN_set_word +first appeared in SSLeay 0.5.1. +.Fn BN_get_word +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . +.Sh BUGS +Someone might change the constant. +.Pp +If the value of a +.Vt BIGNUM +is equal to a +.Vt BN_ULONG +with all bits set, the return value of +.Fn BN_get_word +collides with return value used to indicate errors. +.Pp +.Vt BN_ULONG +should probably be a typedef rather than a macro. diff --git a/Libraries/libressl/man/BUF_MEM_new.3 b/Libraries/libressl/man/BUF_MEM_new.3 new file mode 100644 index 000000000..3b2f20d21 --- /dev/null +++ b/Libraries/libressl/man/BUF_MEM_new.3 @@ -0,0 +1,154 @@ +.\" $OpenBSD: BUF_MEM_new.3,v 1.18 2023/07/27 06:20:45 tb Exp $ +.\" OpenSSL doc/crypto/buffer.pod 18edda0f Sep 20 03:28:54 2000 +0000 +.\" not merged: 74924dcb, 58e3457a, 21b0fa91, 7644a9ae +.\" OpenSSL doc/crypto/BUF_MEM_new.pod 53934822 Jun 9 16:39:19 2016 -0400 +.\" not merged: c952780c, 91da5e77 +.\" OpenSSL doc/man3/BUF_MEM_new.pod 498180de Dec 12 15:35:09 2016 +0300 +.\" +.\" This file was written by Ralf S. Engelschall . +.\" Copyright (c) 1999, 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 27 2023 $ +.Dt BUF_MEM_NEW 3 +.Os +.Sh NAME +.Nm BUF_MEM_new , +.Nm BUF_MEM_free , +.Nm BUF_MEM_grow , +.Nm BUF_MEM_grow_clean +.Nd simple character arrays structure +.Sh SYNOPSIS +.In openssl/buffer.h +.Ft BUF_MEM * +.Fo BUF_MEM_new +.Fa void +.Fc +.Ft void +.Fo BUF_MEM_free +.Fa "BUF_MEM *a" +.Fc +.Ft int +.Fo BUF_MEM_grow +.Fa "BUF_MEM *str" +.Fa "size_t len" +.Fc +.Ft int +.Fo BUF_MEM_grow_clean +.Fa "BUF_MEM *str" +.Fa "size_t len" +.Fc +.Sh DESCRIPTION +The buffer library handles simple character arrays. +Buffers are used for various purposes in the library, most notably +memory BIOs. +.Pp +The library uses the +.Vt BUF_MEM +structure defined in buffer.h: +.Bd -literal +typedef struct buf_mem_st +{ + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ +} BUF_MEM; +.Ed +.Pp +.Fa length +is the current size of the buffer in bytes; +.Fa max +is the amount of memory allocated to the buffer. +There are three functions which handle these and one miscellaneous function. +.Pp +.Fn BUF_MEM_new +allocates a new buffer of zero size. +.Pp +.Fn BUF_MEM_free +frees up an already existing buffer. +The data is zeroed before freeing up in case the buffer contains +sensitive data. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn BUF_MEM_grow +changes the size of an already existing buffer to +.Fa len . +Any data already in the buffer is preserved if it increases in size. +.Pp +.Fn BUF_MEM_grow_clean +is similar to +.Fn BUF_MEM_grow , +but it sets any freed or additionally allocated memory to zero. +.Sh RETURN VALUES +.Fn BUF_MEM_new +returns the buffer or +.Dv NULL +on error. +.Pp +.Fn BUF_MEM_grow +and +.Fn BUF_MEM_grow_clean +return zero on error or the new size (i.e.\& +.Fa len ) . +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BIO_s_mem 3 +.Sh HISTORY +.Fn BUF_MEM_new , +.Fn BUF_MEM_free , +and +.Fn BUF_MEM_grow +first appeared in SSLeay 0.6.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn BUF_MEM_grow_clean +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/CMAC_Init.3 b/Libraries/libressl/man/CMAC_Init.3 new file mode 100644 index 000000000..a938c0db6 --- /dev/null +++ b/Libraries/libressl/man/CMAC_Init.3 @@ -0,0 +1,293 @@ +.\" $OpenBSD: CMAC_Init.3,v 1.4 2020/08/06 22:17:49 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 6 2020 $ +.Dt CMAC_INIT 3 +.Os +.Sh NAME +.Nm CMAC_CTX_new , +.Nm CMAC_Init , +.Nm CMAC_Update , +.Nm CMAC_Final , +.Nm CMAC_resume , +.Nm CMAC_CTX_copy , +.Nm CMAC_CTX_get0_cipher_ctx , +.Nm CMAC_CTX_cleanup , +.Nm CMAC_CTX_free +.Nd Cipher-based message authentication code +.Sh SYNOPSIS +.In openssl/cmac.h +.Ft CMAC_CTX * +.Fn CMAC_CTX_new void +.Ft int +.Fo CMAC_Init +.Fa "CMAC_CTX *ctx" +.Fa "const void *key" +.Fa "size_t key_len" +.Fa "const EVP_CIPHER *cipher" +.Fa "ENGINE *impl" +.Fc +.Ft int +.Fo CMAC_Update +.Fa "CMAC_CTX *ctx" +.Fa "const void *in_data" +.Fa "size_t in_len" +.Fc +.Ft int +.Fo CMAC_Final +.Fa "CMAC_CTX *ctx" +.Fa "unsigned char *out_mac" +.Fa "size_t *out_len" +.Fc +.Ft int +.Fn CMAC_resume "CMAC_CTX *ctx" +.Ft int +.Fo CMAC_CTX_copy +.Fa "CMAC_CTX *out_ctx" +.Fa "CMAC_CTX *in_ctx" +.Fc +.Ft EVP_CIPHER_CTX * +.Fn CMAC_CTX_get0_cipher_ctx "CMAC_CTX *ctx" +.Ft void +.Fn CMAC_CTX_cleanup "CMAC_CTX *ctx" +.Ft void +.Fn CMAC_CTX_free "CMAC_CTX *ctx" +.Sh DESCRIPTION +CMAC is a message authentication code algorithm that can employ an +arbitrary block cipher using a symmetric key. +.Pp +The present manual page describes low-level functions implementing CMAC. +Instead of using these functions directly, +application programs normally call +.Xr EVP_PKEY_CTX_new_id 3 +with an argument of +.Dv EVP_PKEY_CMAC +and then pass the resulting +.Vt EVP_MD_CTX +object to +.Xr EVP_DigestInit_ex 3 . +.Pp +The CMAC API is object-oriented. +Calculating a message authentication code requires a +.Vt CMAC_CTX +object. +Usually, the functions +.Fn CMAC_CTX_new , +.Fn CMAC_Init , +.Fn CMAC_Update , +.Fn CMAC_Final , +and +.Fn CMAC_CTX_free +need to be called in this order. +.Pp +.Fn CMAC_CTX_new +allocates a new +.Vt CMAC_CTX +object, initializes the embedded +.Vt EVP_CIPHER_CTX +object, and marks the object itself as uninitialized. +.Pp +.Fn CMAC_Init +selects the given block +.Fa cipher +for use by +.Fa ctx . +Functions to obtain suitable +.Vt EVP_CIPHER +objects are listed in the CIPHER LISTING section of the +.Xr EVP_Cipher 3 +manual page. +Unless +.Fa key +is +.Dv NULL , +.Fn CMAC_Init +also initializes +.Fa ctx +for use with the given symmetric +.Fa key +that is +.Fa key_len +bytes long. +In particular, it calculates and internally stores the two subkeys +and initializes +.Fa ctx +for subsequently feeding in data with +.Fn CMAC_Update . +To use the default cipher implementations provided by the library, pass +.Dv NULL +as the +.Fa impl +argument. +.Pp +If +.Fa ctx +is already initialized, +.Fn CMAC_Init +can be called again with +.Fa key , +.Fa cipher , +and +.Fa impl +all set to +.Dv NULL +and +.Fa key_len +set to 0. +In that case, any data already processed is discarded and +.Fa ctx +is re-initialized to start reading data anew. +.Pp +.Fn CMAC_Update +processes +.Fa in_len +bytes of input data pointed to by +.Fa in_data . +Depending on the number of input bytes already cached in +.Fa ctx , +on +.Fa in_len , +and on the block size, this may encrypt zero or more blocks. +Unless +.Fa in_len +is zero, this function leaves at least one byte and at most one +block of input cached but unprocessed inside the +.Fa ctx +object. +.Fn CMAC_Update +can be called multiple times +to concatenate several chunks of input data of varying sizes. +.Pp +.Fn CMAC_Final +stores the length of the message authentication code in bytes, +which equals the cipher block size, into +.Pf * Fa out_len . +Unless +.Fa out_mac +is +.Dv NULL , +it encrypts the last block, padding it if required, and copies the +resulting message authentication code to +.Fa out_mac . +The caller is responsible for providing a buffer of sufficient size. +.Pp +Calling +.Fn CMAC_resume +after +.Fn CMAC_Final +allows the user to subsequently append additional data with +.Fn CMAC_Update . +Otherwise, unless +.Fn CMAC_Init +is called to start from scratch, +.Fn CMAC_Update +can no longer be used after +.Fn CMAC_Final . +.Pp +.Fn CMAC_CTX_copy +performs a deep copy of the already initialized +.Fa in_ctx +into +.Fa out_ctx . +.Pp +.Fn CMAC_CTX_cleanup +zeros out both subkeys and all temporary data in +.Fa ctx +and in the embedded +.Vt EVP_CIPHER_CTX +object, frees all allocated memory associated with it, +except for +.Fa ctx +itself, and marks it as uninitialized, +such that it can be reused for subsequent +.Fn CMAC_Init . +.Pp +.Fn CMAC_CTX_free +calls +.Fn CMAC_CTX_cleanup , +then frees +.Fa ctx +itself. +If +.Fa ctx +is +.Dv NULL , +no action occurs. +.Sh RETURN VALUES +.Fn CMAC_CTX_new +returns the new context object or +.Dv NULL +in case of failure. +It succeeds unless memory is exhausted. +.Pp +.Fn CMAC_Init , +.Fn CMAC_Update , +.Fn CMAC_Final , +.Fn CMAC_resume , +and +.Fn CMAC_CTX_copy +return 1 on success or 0 on failure. +.Fn CMAC_Init +fails if initializing the embedded +.Vt EVP_CIPHER_CTX +object fails. +The others fail if +.Fa in_ctx +is uninitialized. +.Fn CMAC_Update +and +.Fn CMAC_Final +also fail if encrypting a block fails, and +.Fn CMAC_CTX_copy +if copying the embedded +.Vt EVP_CIPHER_CTX +object fails, which can for example happen when memory is exhausted. +.Pp +.Fn CMAC_CTX_get0_cipher_ctx +returns an internal pointer to the +.Vt EVP_CIPHER_CTX +object that is embedded in +.Fa ctx . +.Sh ERRORS +The CMAC code itself does not use the +.In openssl/err.h +framework, so in general, the reasons for failure cannot be found out with +.Xr ERR_get_error 3 . +However, since the +.Xr EVP_Cipher 3 +functions are used internally, entries may still get pushed onto +the error stack in some cases of failure. +.Sh SEE ALSO +.Xr EVP_aes_128_cbc 3 , +.Xr EVP_Cipher 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_PKEY_CTX_new_id 3 , +.Xr HMAC 3 +.Sh STANDARDS +.Rs +.%A Morris Dworkin +.%T "Recommendation for Block Cipher Modes of Operation:\ + The CMAC Mode for Authentication" +.%I National Institute of Standards and Technology +.%R NIST Special Publication 800-38B +.%U https://doi.org/10.6028/NIST.SP.800-38B +.%C Gaithersburg, Maryland +.%D May 2005, updated October 6, 2016 +.Re +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.1 +and have been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/CMS_ContentInfo_new.3 b/Libraries/libressl/man/CMS_ContentInfo_new.3 new file mode 100644 index 000000000..ff6417949 --- /dev/null +++ b/Libraries/libressl/man/CMS_ContentInfo_new.3 @@ -0,0 +1,134 @@ +.\" $OpenBSD: CMS_ContentInfo_new.3,v 1.3 2019/11/02 15:39:46 schwarze Exp $ +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_CONTENTINFO_NEW 3 +.Os +.Sh NAME +.Nm CMS_ContentInfo_new , +.Nm CMS_ContentInfo_free , +.Nm CMS_ContentInfo_print_ctx , +.Nm CMS_ReceiptRequest_new , +.Nm CMS_ReceiptRequest_free +.Nd Cryptographic Message Syntax data structures +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fn CMS_ContentInfo_new void +.Ft void +.Fn CMS_ContentInfo_free "CMS_ContentInfo *cms" +.Ft int +.Fo CMS_ContentInfo_print_ctx +.Fa "BIO *out" +.Fa "CMS_ContentInfo *cms" +.Fa "int indent" +.Fa "const ASN1_PCTX *pctx" +.Fc +.Ft CMS_ReceiptRequest * +.Fn CMS_ReceiptRequest_new void +.Ft void +.Fn CMS_ReceiptRequest_free "CMS_ReceiptRequest *rr" +.Sh DESCRIPTION +.Fn CMS_ContentInfo_new +allocates and initializes an empty +.Vt CMS_ContentInfo +object, representing an ASN.1 +.Vt ContentInfo +structure defined in RFC 5652 section 3. +It can hold a pointer to an ASN.1 OBJECT IDENTIFIER +and a pointer to either a +.Vt SignedData , +.Vt EnvelopedData , +.Vt DigestedData , +.Vt EncryptedData , +.Vt AuthenticatedData , +or +.Vt CompressedData +object or to an arbitrary ASN.1 object. +.Fn CMS_ContentInfo_free +frees +.Fa cms . +.Pp +.Fn CMS_ContentInfo_print_ctx +prints a human readable representation of +.Fa cms +to +.Fa out . +.Pp +.Fn CMS_ReceiptRequest_new +allocates and initializes an empty +.Vt CMS_ReceiptRequest +object, representing an ASN.1 +.Vt ReceiptRequest +structure defined in RFC 2634 section 2.7. +It can contain a content identifier, a list of recipients requested +to return a signed receipt, and a list of users to send the receipt to. +.Fn CMS_ReceiptRequest_free +frees +.Fa rr . +.Sh RETURN VALUES +.Fn CMS_ContentInfo_new +and +.Fn CMS_ReceiptRequest_new +return the new +.Vt CMS_ContentInfo +or +.Vt CMS_ReceiptRequest +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr BIO_new_CMS 3 , +.Xr CMS_add0_cert 3 , +.Xr CMS_add1_recipient_cert 3 , +.Xr CMS_add1_signer 3 , +.Xr CMS_compress 3 , +.Xr CMS_decrypt 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_final 3 , +.Xr CMS_get0_RecipientInfos 3 , +.Xr CMS_get0_SignerInfos 3 , +.Xr CMS_get0_type 3 , +.Xr CMS_get1_ReceiptRequest 3 , +.Xr CMS_sign 3 , +.Xr CMS_sign_receipt 3 , +.Xr CMS_uncompress 3 , +.Xr CMS_verify 3 , +.Xr CMS_verify_receipt 3 , +.Xr crypto 3 , +.Xr d2i_CMS_ContentInfo 3 , +.Xr i2d_CMS_bio_stream 3 , +.Xr PEM_read_bio_PrivateKey 3 , +.Xr PEM_write_bio_CMS_stream 3 , +.Xr SMIME_read_CMS 3 , +.Xr SMIME_write_CMS 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax, section 3: General Syntax +.Pp +RFC 3274: Compressed Data Content Type for Cryptographic Message Syntax (CMS) +.Pp +RFC 2634: Enhanced Security Services for S/MIME, +section 2.7: Receipt Request Syntax +.Sh HISTORY +.Fn CMS_ContentInfo_new , +.Fn CMS_ContentInfo_free , +.Fn CMS_ReceiptRequest_new , +and +.Fn CMS_ReceiptRequest_free +first appeared in OpenSSL 0.9.8h and +.Fn CMS_ContentInfo_print_ctx +in OpenSSL 1.0.0. +This functions have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_add0_cert.3 b/Libraries/libressl/man/CMS_add0_cert.3 new file mode 100644 index 000000000..c5a7367d2 --- /dev/null +++ b/Libraries/libressl/man/CMS_add0_cert.3 @@ -0,0 +1,214 @@ +.\" $OpenBSD: CMS_add0_cert.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_ADD0_CERT 3 +.Os +.Sh NAME +.Nm CMS_add0_cert , +.Nm CMS_add1_cert , +.Nm CMS_get1_certs , +.Nm CMS_add0_crl , +.Nm CMS_add1_crl , +.Nm CMS_get1_crls +.Nd CMS certificate and CRL utility functions +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo CMS_add0_cert +.Fa "CMS_ContentInfo *cms" +.Fa "X509 *certificate" +.Fc +.Ft int +.Fo CMS_add1_cert +.Fa "CMS_ContentInfo *cms" +.Fa "X509 *certificate" +.Fc +.Ft STACK_OF(X509) * +.Fo CMS_get1_certs +.Fa "CMS_ContentInfo *cms" +.Fc +.Ft int +.Fo CMS_add0_crl +.Fa "CMS_ContentInfo *cms" +.Fa "X509_CRL *crl" +.Fc +.Ft int +.Fo CMS_add1_crl +.Fa "CMS_ContentInfo *cms" +.Fa "X509_CRL *crl" +.Fc +.Ft STACK_OF(X509_CRL) * +.Fo CMS_get1_crls +.Fa "CMS_ContentInfo *cms" +.Fc +.Sh DESCRIPTION +.Fn CMS_add0_cert +adds the +.Fa certificate +to the +.Fa certificates +field of +.Fa cms +if it is of the type +.Vt SignedData +or to the +.Fa originatorInfo.certs +field if it is of the type +.Vt EnvelopedData . +.Fn CMS_add1_cert +does the same and also increments the reference count of the +.Fa certificate +with +.Xr X509_up_ref 3 +in case of success. +.Pp +.Fn CMS_get1_certs +returns all certificates in +.Fa cms . +.Pp +.Fn CMS_add0_crl +adds the +.Fa crl +to the +.Fa crls +field of +.Fa cms +if it is of the type +.Vt SignedData +or to the +.Fa originatorInfo.crls +field if it is of the type +.Vt EnvelopedData . +.Fn CMS_add1_crl +does the same and also increments the reference count of the +.Fa crl +with +.Xr X509_CRL_up_ref 3 +in case of success. +.Pp +.Fn CMS_get1_crls +returns any CRLs in +.Fa cms . +.Pp +An error occurs if +.Fa cms +is of any type other than +.Vt SignedData +or +.Vt EnvelopedData . +.Pp +The same +.Fa certificate +or +.Fa crl +must not be added to the same +.Fa cms +structure more than once. +.Sh RETURN VALUES +.Fn CMS_add0_cert , +.Fn CMS_add1_cert , +.Fn CMS_add0_crl , +and +.Fn CMS_add1_crl +return 1 for success or 0 for failure. +.Pp +.Fn CMS_get1_certs +and +.Fn CMS_get1_crls +return the STACK of certificates or CRLs or +.Dv NULL +if there are none or an error occurs. +The only error which will occur in practice is if the +.Fa cms +type is invalid. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_final 3 , +.Xr CMS_sign 3 , +.Xr ERR_get_error 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax +.Bl -dash -compact -offset indent +.It +section 5.1: SignedData Type +.It +section 6.1: EnvelopedData Type +.El +.Sh HISTORY +.Fn CMS_add0_cert , +.Fn CMS_add1_cert , +.Fn CMS_get1_certs , +.Fn CMS_add0_crl , +and +.Fn CMS_get1_crls +first appeared in OpenSSL 0.9.8h and +.Fn CMS_add1_crl +in OpenSSL 1.0.0. +These functions have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_add1_recipient_cert.3 b/Libraries/libressl/man/CMS_add1_recipient_cert.3 new file mode 100644 index 000000000..465119397 --- /dev/null +++ b/Libraries/libressl/man/CMS_add1_recipient_cert.3 @@ -0,0 +1,200 @@ +.\" $OpenBSD: CMS_add1_recipient_cert.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_ADD1_RECIPIENT_CERT 3 +.Os +.Sh NAME +.Nm CMS_add1_recipient_cert , +.Nm CMS_add0_recipient_key +.Nd add recipients to a CMS EnvelopedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_RecipientInfo * +.Fo CMS_add1_recipient_cert +.Fa "CMS_ContentInfo *cms" +.Fa "X509 *certificate" +.Fa "unsigned int flags" +.Fc +.Ft CMS_RecipientInfo * +.Fo CMS_add0_recipient_key +.Fa "CMS_ContentInfo *cms" +.Fa "int nid" +.Fa "unsigned char *key" +.Fa "size_t keylen" +.Fa "unsigned char *id" +.Fa "size_t idlen" +.Fa "ASN1_GENERALIZEDTIME *date" +.Fa "ASN1_OBJECT *otherTypeId" +.Fa "ASN1_TYPE *otherType" +.Fc +.Sh DESCRIPTION +These functions add a new +.Vt RecipientInfo +structure to the +.Fa recipientInfos +field of the +.Vt EnvelopedData +structure +.Fa cms , +which should have been obtained from an initial call to +.Xr CMS_encrypt 3 +with the flag +.Dv CMS_PARTIAL +set. +.Pp +.Fn CMS_add1_recipient_cert +adds the recipient +.Fa certificate +as a +.Vt KeyTransRecipientInfo +structure. +.Pp +.Fn CMS_add0_recipient_key +adds the symmetric +.Fa key +of length +.Fa keylen +using the wrapping algorithm +.Fa nid , +the identifier +.Fa id +of length +.Fa idlen , +and the optional values +.Fa date , +.Fa otherTypeId +and +.Fa otherType +as a +.Vt KEKRecipientInfo +structure. +.Pp +The main purpose of these functions is to provide finer control over a CMS +.Vt EnvelopedData +structure where the simpler +.Xr CMS_encrypt 3 +function defaults are not appropriate, +for example if one or more +.Vt KEKRecipientInfo +structures need to be added. +New attributes can also be added using the returned +.Vt CMS_RecipientInfo +structure and the CMS attribute utility functions. +.Pp +By default, recipient certificates are identified using issuer +name and serial number. +If the flag +.Dv CMS_USE_KEYID +is set, the subject key identifier value is used instead. +An error occurs if all recipient certificates do not have a subject key +identifier extension. +.Pp +Currently only AES based key wrapping algorithms are supported for +.Fa nid , +specifically +.Dv NID_id_aes128_wrap , +.Dv NID_id_aes192_wrap , +and +.Dv NID_id_aes256_wrap . +If +.Fa nid +is set to +.Dv NID_undef , +then an AES wrap algorithm will be used consistent with +.Fa keylen . +.Sh RETURN VALUES +.Fn CMS_add1_recipient_cert +and +.Fn CMS_add0_recipient_key +return an internal pointer to the +.Vt CMS_RecipientInfo +structure just added or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_final 3 , +.Xr ERR_get_error 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax +.Bl -dash -compact -offset indent +.It +section 6.1: EnvelopedData Type +.It +section 6.2.1: KeyTransRecipientInfo Type +.It +section 6.2.3: KEKRecipientInfo Type +.El +.Sh HISTORY +.Fn CMS_add1_recipient_cert +and +.Fn CMS_add0_recipient_key +first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_add1_signer.3 b/Libraries/libressl/man/CMS_add1_signer.3 new file mode 100644 index 000000000..9ee97dfaf --- /dev/null +++ b/Libraries/libressl/man/CMS_add1_signer.3 @@ -0,0 +1,246 @@ +.\" $OpenBSD: CMS_add1_signer.3,v 1.8 2020/06/24 18:15:00 jmc Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 24 2020 $ +.Dt CMS_ADD1_SIGNER 3 +.Os +.Sh NAME +.Nm CMS_add1_signer , +.Nm CMS_SignerInfo_sign +.Nd add a signer to a CMS SignedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_SignerInfo * +.Fo CMS_add1_signer +.Fa "CMS_ContentInfo *cms" +.Fa "X509 *signcert" +.Fa "EVP_PKEY *pkey" +.Fa "const EVP_MD *md" +.Fa "unsigned int flags" +.Fc +.Ft int +.Fo CMS_SignerInfo_sign +.Fa "CMS_SignerInfo *si" +.Fc +.Sh DESCRIPTION +.Fn CMS_add1_signer +adds a signer with certificate +.Fa signcert +and private key +.Fa pkey +using message digest +.Fa md +to the +.Fa signerInfos +field of the +.Vt SignedData +structure +.Fa cms , +which should have been obtained from an initial call to +.Xr CMS_sign 3 +with the flag +.Dv CMS_PARTIAL +set, or which can be a valid +.Vt SignedData +structure in the case of re-signing. +.Pp +If +.Fa md +is +.Dv NULL , +the default digest for the public key algorithm of +.Fa pkey +is used. +.Pp +Unless the +.Dv CMS_REUSE_DIGEST +flag is set, the +.Fa cms +structure remains incomplete and must be finalized either by streaming +(if applicable) or by a call to +.Xr CMS_final 3 . +.Pp +The main purpose of +.Fn CMS_add1_signer +is to provide finer control over a CMS +.Vt SignedData +structure where the simpler +.Xr CMS_sign 3 +function defaults are not appropriate, for example if multiple signers +or non default digest algorithms are needed. +New attributes can also be added using the returned +.Vt CMS_SignerInfo +structure and the CMS attribute utility functions or the CMS signed +receipt request functions. +.Pp +Any of the following flags (OR'ed together) can be passed in the +.Fa flags +parameter: +.Bl -tag -width Ds +.It Dv CMS_REUSE_DIGEST +Attempt to copy the content digest value from one of the existing +.Vt CMS_SignerInfo +structures in +.Fa cms +while adding another signer. +An error occurs if a matching digest value cannot be found to copy. +The +.Fa cms +structure will be valid and finalized when this flag is set. +.It Dv CMS_PARTIAL +If this flag is set in addition to +.Dv CMS_REUSE_DIGEST , +the returned +.Vt CMS_SignerInfo +structure will not be finalized so additional attributes can be added. +In this case an explicit call to +.Fn CMS_SignerInfo_sign +is needed to finalize it. +.It Dv CMS_NOCERTS +Do not add the signer's certificate to the +.Fa certificates +field of +.Fa cms . +The signer's certificate must still be supplied in the +.Fa signcert +parameter though. +This flag can reduce the size of the signature if the signer's certificate can +be obtained by other means, for example from a previously signed message. +.It Dv CMS_NOATTR +Leave the +.Fa signedAttrs +field of the returned +.Vt CMS_SignedData +structure empty. +By default, several CMS +.Vt SignedAttributes +are added, including the signing time, the CMS content type, +and the supported list of ciphers in an +.Vt SMIMECapabilities +attribute. +.It Dv CMS_NOSMIMECAP +Omit just the +.Vt SMIMECapabilities +attribute. +.It Dv CMS_USE_KEYID +Use the subject key identifier value to identify signing certificates. +An error occurs if the signing certificate does not have a subject key +identifier extension. +By default, issuer name and serial number are used instead. +.El +.Pp +If present, the +.Vt SMIMECapabilities +attribute indicates support for the +following algorithms in preference order: 256-bit AES, Gost R3411-94, +Gost 28147-89, 192-bit AES, 128-bit AES, triple DES, 128-bit RC2, 64-bit +RC2, DES and 40-bit RC2. +If any of these algorithms is not available then it will not be +included. +.Pp +The +.Fn CMS_SignerInfo_sign +function explicitly signs +.Fa si . +Its main use is when the +.Dv CMS_REUSE_DIGEST +and +.Dv CMS_PARTIAL +flags were both set in the call to +.Fn CMS_add1_signer +that created +.Fa si . +.Sh RETURN VALUES +.Fn CMS_add1_signer +returns an internal pointer to the new +.Vt CMS_SignerInfo +structure just added or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_final 3 , +.Xr CMS_sign 3 , +.Xr ERR_get_error 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax, section 5.1: SignedData Type +.Pp +RFC 8551: Secure/Multipurpose Internet Mail Extensions (S/MIME) +Version\ 4.0 Message Specification +.Bl -dash -compact -offset indent +.It +section 2.5: Attributes and the SignerInfo Type +.It +section 2.5.2: SMIMECapabilities Attribute +.El +.Sh HISTORY +.Fn CMS_add1_signer +and +.Fn CMS_SignerInfo_sign +first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_compress.3 b/Libraries/libressl/man/CMS_compress.3 new file mode 100644 index 000000000..242e4e96c --- /dev/null +++ b/Libraries/libressl/man/CMS_compress.3 @@ -0,0 +1,170 @@ +.\" $OpenBSD: CMS_compress.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_COMPRESS 3 +.Os +.Sh NAME +.Nm CMS_compress +.Nd create a CMS CompressedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo CMS_compress +.Fa "BIO *in" +.Fa "int comp_nid" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_compress +creates and returns a CMS +.Vt CompressedData +structure. +.Pp +.Fa comp_nid +is the compression algorithm to use or +.Dv NID_undef +to use the default algorithm. +Currently, the default algorithm +.Dv NID_zlib_compression +is the only supported algorithm. +If zlib support is not compiled in, +.Fn CMS_compress +always returns an error. +.Pp +.Fa in +provides the content to be compressed. +.Pp +Any of the following flags (OR'ed together) can be passed in the +.Fa flags +parameter: +.Bl -tag -width Ds +.It Dv CMS_TEXT +Prepend MIME headers for type text/plain to the data. +.It Dv CMS_BINARY +Do not translate the supplied content into MIME canonical format, +even though that is required by the S/MIME specifications. +This option should be used if the supplied data is in binary format. +Otherwise, the translation will corrupt it. +If +.Dv CMS_BINARY +is set, +.Dv CMS_TEXT +is ignored. +.It Dv CMS_STREAM +Return a partial +.Vt CMS_ContentInfo +structure suitable for streaming I/O: no data is read from +.Fa in . +Several functions including +.Xr SMIME_write_CMS 3 , +.Xr i2d_CMS_bio_stream 3 , +or +.Xr PEM_write_bio_CMS_stream 3 +can be used to finalize the structure. +Alternatively, finalization can be performed by obtaining the streaming +ASN1 +.Vt BIO +directly using +.Xr BIO_new_CMS 3 . +Outputting the contents of the +.Vt CMS_ContentInfo +structure via a function that does not +properly finalize it will give unpredictable results. +.It Dv CMS_DETACHED +Do not include the compressed data in the +.Vt CMS_ContentInfo +structure. +This is rarely used in practice and is not supported by +.Xr SMIME_write_CMS 3 . +.El +.Pp +Additional compression parameters such as the zlib compression level +cannot currently be set. +.Sh RETURN VALUES +.Fn CMS_compress +returns either a +.Vt CMS_ContentInfo +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_uncompress 3 +.Sh STANDARDS +RFC 3274: Compressed Data Content Type for Cryptographic Message Syntax (CMS) +.Sh HISTORY +.Fn CMS_compress +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . +.Pp +The +.Dv CMS_STREAM +flag first appeared in OpenSSL 1.0.0. diff --git a/Libraries/libressl/man/CMS_decrypt.3 b/Libraries/libressl/man/CMS_decrypt.3 new file mode 100644 index 000000000..243ab2f30 --- /dev/null +++ b/Libraries/libressl/man/CMS_decrypt.3 @@ -0,0 +1,226 @@ +.\" $OpenBSD: CMS_decrypt.3,v 1.8 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_DECRYPT 3 +.Os +.Sh NAME +.Nm CMS_decrypt , +.Nm CMS_decrypt_set1_pkey , +.Nm CMS_decrypt_set1_key +.Nd decrypt content from a CMS EnvelopedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo CMS_decrypt +.Fa "CMS_ContentInfo *cms" +.Fa "EVP_PKEY *private_key" +.Fa "X509 *certificate" +.Fa "BIO *dcont" +.Fa "BIO *out" +.Fa "unsigned int flags" +.Fc +.Ft int +.Fo CMS_decrypt_set1_pkey +.Fa "CMS_ContentInfo *cms" +.Fa "EVP_PKEY *private_key" +.Fa "X509 *certificate" +.Fc +.Ft int +.Fo CMS_decrypt_set1_key +.Fa "CMS_ContentInfo *cms" +.Fa "unsigned char *symmetric_key" +.Fa "size_t keylen" +.Fa "const unsigned char *id" +.Fa "size_t idlen" +.Fc +.Sh DESCRIPTION +.Fn CMS_decrypt +extracts and decrypts the content from the CMS +.Vt EnvelopedData +structure +.Fa cms +using the +.Fa private_key +and the +.Fa certificate +of the recipient. +It writes the decrypted content to +.Fa out . +.Pp +In the rare case where the compressed content is detached, pass it in via +.Fa dcont . +For normal use, set +.Fa dcont +to +.Dv NULL . +.Pp +Although the recipient's +.Fa certificate +is not needed to decrypt the data, it is needed to locate the +appropriate (of possibly several) recipients in the CMS structure. +.Pp +If the +.Fa certificate +is set to +.Dv NULL , +all possible recipients are tried. +This case however is problematic. +To thwart the MMA attack (Bleichenbacher's attack on PKCS #1 v1.5 RSA +padding), all recipients are tried whether they succeed or not. +If no recipient succeeds, a random symmetric key is used to decrypt +the content: this will typically output garbage and may (but is not +guaranteed to) ultimately return a padding error only. +If +.Fn CMS_decrypt +just returned an error when all recipient encrypted keys failed to +decrypt, an attacker could use this in a timing attack. +If the special flag +.Dv CMS_DEBUG_DECRYPT +is set, the above behaviour is modified and an error +.Em is +returned if no recipient encrypted key can be decrypted +.Em without +generating a random content encryption key. +Applications should use this flag with extreme caution +especially in automated gateways as it can leave them open to attack. +.Pp +It is possible to determine the correct recipient key by other means +(for example by looking them up in a database) and setting them in the +.Fa cms +structure in advance using the CMS utility functions such as +.Fn CMS_decrypt_set1_pkey . +In this case both +.Fa certificate +and +.Fa private_key +should be set to +.Dv NULL +when calling +.Fn CMS_decrypt +later on. +.Pp +To process +.Vt KEKRecipientInfo +types, +.Fn CMS_decrypt_set1_key +or +.Xr CMS_RecipientInfo_set0_key 3 +and +.Xr CMS_RecipientInfo_decrypt 3 +should be called before +.Fn CMS_decrypt +and +.Fa certificate +and +.Fa private_key +set to +.Dv NULL +when calling +.Fn CMS_decrypt +later on. +.Pp +If the +.Dv CMS_TEXT +bit is set in +.Fa flags , +MIME headers for type text/plain are deleted from the content. +If the content is not of type text/plain, an error occurs. +.Sh RETURN VALUES +.Fn CMS_decrypt , +.Fn CMS_decrypt_set1_pkey , +and +.Fn CMS_decrypt_set1_key +return 1 for success or 0 for failure. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_get0_RecipientInfos 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax (CMS) +.Bl -dash -compact -offset indent +.It +section 6.1: EnvelopedData Type +.It +section 6.2.3: KEKRecipientInfo Type +.El +.Sh HISTORY +.Fn CMS_decrypt , +.Fn CMS_decrypt_set1_pkey , +and +.Fn CMS_decrypt_set1_key +first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . +.Sh BUGS +The lack of single pass processing and the need to hold all data in +memory as mentioned in +.Xr CMS_verify 3 +also applies to +.Fn CMS_decrypt . diff --git a/Libraries/libressl/man/CMS_encrypt.3 b/Libraries/libressl/man/CMS_encrypt.3 new file mode 100644 index 000000000..03d8b4edb --- /dev/null +++ b/Libraries/libressl/man/CMS_encrypt.3 @@ -0,0 +1,191 @@ +.\" $OpenBSD: CMS_encrypt.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_ENCRYPT 3 +.Os +.Sh NAME +.Nm CMS_encrypt +.Nd create a CMS EnvelopedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo CMS_encrypt +.Fa "STACK_OF(X509) *certificates" +.Fa "BIO *in" +.Fa "const EVP_CIPHER *cipher" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_encrypt +creates a CMS +.Vt EnvelopedData +structure, encrypting the content provided by +.Fa in . +.Pp +The recipient +.Fa certificates +are added as +.Vt KeyTransRecipientInfo +structures by calling the function +.Xr CMS_add1_recipient_cert 3 +internally. +Only certificates carrying RSA, Diffie-Hellman or EC keys are supported +by this function. +The +.Fa certificates +argument can be set to +.Dv NULL +if the +.Dv CMS_PARTIAL +flag is set and recipients are added later using +.Xr CMS_add1_recipient_cert 3 +or +.Xr CMS_add0_recipient_key 3 . +.Pp +.Fa cipher +is the symmetric cipher to use. +It must support ASN.1 encoding of its parameters. +.Xr EVP_des_ede3_cbc 3 +(triple DES) is the algorithm of choice for S/MIME use because most +clients support it. +.Pp +Many browsers implement a "sign and encrypt" option which is simply an +S/MIME +.Vt EnvelopedData +containing an S/MIME signed message. +This can be readily produced by storing the S/MIME signed message in a +memory BIO and passing it to +.Fn CMS_encrypt . +.Pp +The following flags can be passed in the +.Fa flags +parameter: +.Bl -tag -width Ds +.It Dv CMS_TEXT +MIME headers for type text/plain are prepended to the data. +.It Dv CMS_BINARY +Do not translate the supplied content into MIME canonical format +even though that is required by the S/MIME specifications. +This option should be used if the supplied data is in binary format. +Otherwise, the translation will corrupt it. +If +.Dv CMS_BINARY +is set, then +.Dv CMS_TEXT +is ignored. +.It Dv CMS_USE_KEYID +Use the subject key identifier value to identify recipient certificates. +An error occurs if all recipient certificates do not have a subject key +identifier extension. +By default, issuer name and serial number are used instead. +.It Dv CMS_STREAM +Return a partial +.Vt CMS_ContentInfo +structure suitable for streaming I/O: no data is read from the BIO +.Fa in . +Several functions including +.Xr SMIME_write_CMS 3 , +.Xr i2d_CMS_bio_stream 3 , +or +.Xr PEM_write_bio_CMS_stream 3 +can be used to finalize the structure. +Alternatively, finalization can be performed by obtaining the streaming +ASN1 +.Vt BIO +directly using +.Xr BIO_new_CMS 3 . +Outputting the content of the returned +.Vt CMS_ContentInfo +structure via a function that does not properly finalize it +will give unpredictable results. +.It Dv CMS_PARTIAL +Return a partial +.Vt CMS_ContentInfo +structure to which additional recipients and attributes can +be added before finalization. +.It Dv CMS_DETACHED +Omit the data being encrypted from the +.Vt CMS_ContentInfo +structure. +This is rarely used in practice and is not supported by +.Xr SMIME_write_CMS 3 . +.El +.Sh RETURN VALUES +.Fn CMS_encrypt +returns either a +.Vt CMS_ContentInfo +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_add0_cert 3 , +.Xr CMS_add1_recipient_cert 3 , +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_decrypt 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax (CMS) +.Bl -dash -compact -offset indent +.It +section 6.1: EnvelopedData Type +.It +section 6.2.1: KeyTransRecipientInfo Type +.El +.Sh HISTORY +.Fn CMS_encrypt +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . +.Pp +The +.Dv CMS_STREAM +flag first appeared in OpenSSL 1.0.0. diff --git a/Libraries/libressl/man/CMS_final.3 b/Libraries/libressl/man/CMS_final.3 new file mode 100644 index 000000000..4ca894592 --- /dev/null +++ b/Libraries/libressl/man/CMS_final.3 @@ -0,0 +1,101 @@ +.\" $OpenBSD: CMS_final.3,v 1.6 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL 25ccb589 Jul 1 02:02:06 2019 +0800 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_FINAL 3 +.Os +.Sh NAME +.Nm CMS_final +.Nd finalise a CMS_ContentInfo structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo CMS_final +.Fa "CMS_ContentInfo *cms" +.Fa "BIO *data" +.Fa "BIO *dcont" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_final +finalises the structure +.Fa cms . +Its purpose is to perform any operations necessary on +.Fa cms +(digest computation for example) and set the appropriate fields. +The parameter +.Fa data +contains the content to be processed. +The +.Fa dcont +parameter contains a +.Vt BIO +to write content to after processing: this is +only used with detached data and will usually be set to +.Dv NULL . +.Pp +This function will normally be called when the +.Dv CMS_PARTIAL +flag is used. +It should only be used when streaming is not performed because the +streaming I/O functions perform finalisation operations internally. +.Sh RETURN VALUES +.Fn CMS_final +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_sign 3 , +.Xr ERR_get_error 3 +.Sh HISTORY +.Fn CMS_final +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_get0_RecipientInfos.3 b/Libraries/libressl/man/CMS_get0_RecipientInfos.3 new file mode 100644 index 000000000..094d6ec48 --- /dev/null +++ b/Libraries/libressl/man/CMS_get0_RecipientInfos.3 @@ -0,0 +1,328 @@ +.\" $OpenBSD: CMS_get0_RecipientInfos.3,v 1.8 2022/03/31 17:27:16 naddy Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt CMS_GET0_RECIPIENTINFOS 3 +.Os +.Sh NAME +.Nm CMS_get0_RecipientInfos , +.Nm CMS_RecipientInfo_type , +.Nm CMS_RecipientInfo_ktri_get0_signer_id , +.Nm CMS_RecipientInfo_ktri_cert_cmp , +.Nm CMS_RecipientInfo_set0_pkey , +.Nm CMS_RecipientInfo_kekri_get0_id , +.Nm CMS_RecipientInfo_kekri_id_cmp , +.Nm CMS_RecipientInfo_set0_key , +.Nm CMS_RecipientInfo_decrypt , +.Nm CMS_RecipientInfo_encrypt +.Nd CMS EnvelopedData RecipientInfo routines +.Sh SYNOPSIS +.In openssl/cms.h +.Ft STACK_OF(CMS_RecipientInfo) * +.Fo CMS_get0_RecipientInfos +.Fa "CMS_ContentInfo *cms" +.Fc +.Ft int +.Fo CMS_RecipientInfo_type +.Fa "CMS_RecipientInfo *ri" +.Fc +.Ft int +.Fo CMS_RecipientInfo_ktri_get0_signer_id +.Fa "CMS_RecipientInfo *ri" +.Fa "ASN1_OCTET_STRING **keyid" +.Fa "X509_NAME **issuer" +.Fa "ASN1_INTEGER **sno" +.Fc +.Ft int +.Fo CMS_RecipientInfo_ktri_cert_cmp +.Fa "CMS_RecipientInfo *ri" +.Fa "X509 *certificate" +.Fc +.Ft int +.Fo CMS_RecipientInfo_set0_pkey +.Fa "CMS_RecipientInfo *ri" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo CMS_RecipientInfo_kekri_get0_id +.Fa "CMS_RecipientInfo *ri" +.Fa "X509_ALGOR **palg" +.Fa "ASN1_OCTET_STRING **pid" +.Fa "ASN1_GENERALIZEDTIME **pdate" +.Fa "ASN1_OBJECT **potherid" +.Fa "ASN1_TYPE **pothertype" +.Fc +.Ft int +.Fo CMS_RecipientInfo_kekri_id_cmp +.Fa "CMS_RecipientInfo *ri" +.Fa "const unsigned char *id" +.Fa "size_t idlen" +.Fc +.Ft int +.Fo CMS_RecipientInfo_set0_key +.Fa "CMS_RecipientInfo *ri" +.Fa "unsigned char *key" +.Fa "size_t keylen" +.Fc +.Ft int +.Fo CMS_RecipientInfo_decrypt +.Fa "CMS_ContentInfo *cms" +.Fa "CMS_RecipientInfo *ri" +.Fc +.Ft int +.Fo CMS_RecipientInfo_encrypt +.Fa "CMS_ContentInfo *cms" +.Fa "CMS_RecipientInfo *ri" +.Fc +.Sh DESCRIPTION +.Fn CMS_get0_RecipientInfos +returns all the +.Vt RecipientInfo +structures associated with the +.Vt EnvelopedData +structure +.Fa cms . +.Pp +.Fn CMS_RecipientInfo_type +returns the type of +.Fa ri : +.Bl -column CMS_RECIPINFO_TRANS for -compact +.It Dv CMS_RECIPINFO_TRANS Ta for Ta Vt KeyTransRecipientInfo , +.It Dv CMS_RECIPINFO_AGREE Ta for Ta Vt KeyAgreeRecipientInfo , +.It Dv CMS_RECIPINFO_KEK Ta for Ta Vt KEKRecipientInfo , +.It Dv CMS_RECIPINFO_PASS Ta for Ta Vt PasswordRecipientinfo , No or +.It Dv CMS_RECIPINFO_OTHER Ta for Ta Vt OtherRecipientInfo . +.El +.Pp +.Fn CMS_RecipientInfo_ktri_get0_signer_id +retrieves the certificate +.Vt RecipientIdentifier +associated with the +.Vt KeyTransRecipientInfo +structure +.Fa ri . +Either the +.Vt SubjectKeyIdentifier +will be set in +.Fa keyid +or both issuer name and serial number in +.Fa issuer +and +.Fa sno . +.Pp +.Fn CMS_RecipientInfo_ktri_cert_cmp +compares the +.Fa certificate +against the +.Vt KeyTransRecipientInfo +structure +.Fa ri . +.Pp +.Fn CMS_RecipientInfo_set0_pkey +associates the private key +.Fa pkey +with the +.Vt KeyTransRecipientInfo +structure +.Fa ri . +.Pp +.Fn CMS_RecipientInfo_kekri_get0_id +retrieves the key information from the +.Vt KEKRecipientInfo +structure +.Fa ri . +Fields are copied out as follows: +.Bl -column keyEncryptionAlgorithm to -compact +.It Fa keyEncryptionAlgorithm Ta to Ta Pf * Fa palg , +.It Fa keyIdentifier Ta to Ta Pf * Fa pid , +.It Fa date Ta to Ta Pf * Fa pdate Pq optional , +.It Fa other.keyAttrId Ta to Ta Pf * Fa potherid Pq optional , +.It Fa other.keyAttr Ta to Ta Pf * Fa pothertype Pq optional . +.El +Where a field is optional and absent, +.Dv NULL +is written to the corresponding parameter. +Parameters the application is not interested in can be set to +.Dv NULL . +.Pp +.Fn CMS_RecipientInfo_kekri_id_cmp +compares the identifier in the +.Fa id +and +.Fa idlen +parameters against the +.Fa keyIdentifier +field of the +.Vt KEKRecipientInfo +structure +.Fa ri . +.Pp +.Fn CMS_RecipientInfo_set0_key +associates the symmetric +.Fa key +of length +.Fa keylen +with the +.Vt KEKRecipientInfo +structure +.Fa ri . +.Pp +.Fn CMS_RecipientInfo_decrypt +attempts to decrypt the +.Vt RecipientInfo +structure +.Fa ri +in +.Fa cms . +A key must have been associated with +.Fa ri +first. +.Pp +.Fn CMS_RecipientInfo_encrypt +attempts to encrypt the +.Vt RecipientInfo +structure +.Fa ri +in +.Fa cms . +A key must have been associated with +.Fa ri +first and the content encryption key must be available, +for example by a previous call to +.Fn CMS_RecipientInfo_decrypt . +.Pp +The main purpose of these functions is to enable an application to +lookup recipient keys using any appropriate technique when the simpler +method of +.Xr CMS_decrypt 3 +is not appropriate. +.Pp +In typical usage, an application retrieves all +.Vt CMS_RecipientInfo +structures using +.Fn CMS_get0_RecipientInfos +and checks the type of each using +.Fn CMS_RecipientInfo_type . +Depending on the type, the +.Vt CMS_RecipientInfo +structure can be ignored or its key identifier data retrieved using +an appropriate function. +If the corresponding secret or private key can be obtained by any +appropriate means, it can then be associated with the structure and +.Fn CMS_RecipientInfo_decrypt +called. +If successful, +.Xr CMS_decrypt 3 +can be called with a +.Dv NULL +key to decrypt the enveloped content. +.Pp +The function +.Fn CMS_RecipientInfo_encrypt +can be used to add a new recipient to an existing enveloped data +structure. +Typically an application will first decrypt an appropriate +.Vt CMS_RecipientInfo +structure to make the content encrypt key available. +It will then add a new recipient using a function such as +.Xr CMS_add1_recipient_cert 3 +and finally encrypt the content encryption key using +.Fn CMS_RecipientInfo_encrypt . +.Sh RETURN VALUES +.Fn CMS_get0_RecipientInfos +returns an internal pointer to all the +.Vt CMS_RecipientInfo +structures, or +.Dv NULL +if an error occurs. +.Pp +.Fn CMS_RecipientInfo_type +returns an integer constant. +.Pp +.Fn CMS_RecipientInfo_ktri_get0_signer_id , +.Fn CMS_RecipientInfo_set0_pkey , +.Fn CMS_RecipientInfo_kekri_get0_id , +.Fn CMS_RecipientInfo_set0_key , +.Fn CMS_RecipientInfo_decrypt , +and +.Fn CMS_RecipientInfo_encrypt +return 1 for success or 0 if an error occurs. +.Pp +.Fn CMS_RecipientInfo_ktri_cert_cmp +and +.Fn CMS_RecipientInfo_kekri_id_cmp +return 0 when +.Fa ri +matches or non-zero otherwise. +.Pp +Any error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_decrypt 3 +.Sh STANDARDS +RFC 5652 Cryptographic Message Syntax (CMS): +.Bl -dash -compact -offset indent +.It +section 6.1: EnvelopedData Type +.It +section 6.2: RecipientInfo Type +.It +section 6.2.1: KeyTransRecipientInfo Type +.It +section 6.2.3: KEKRecipientInfo Type +.El +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8h, +except that +.Fn CMS_RecipientInfo_encrypt +first appeared in OpenSSL 1.0.2. +They have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_get0_SignerInfos.3 b/Libraries/libressl/man/CMS_get0_SignerInfos.3 new file mode 100644 index 000000000..0be92d800 --- /dev/null +++ b/Libraries/libressl/man/CMS_get0_SignerInfos.3 @@ -0,0 +1,213 @@ +.\" $OpenBSD: CMS_get0_SignerInfos.3,v 1.8 2023/07/26 19:30:43 tb Exp $ +.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt CMS_GET0_SIGNERINFOS 3 +.Os +.Sh NAME +.Nm CMS_get0_SignerInfos , +.Nm CMS_SignerInfo_get_version , +.Nm CMS_SignerInfo_get0_signer_id , +.Nm CMS_SignerInfo_get0_signature , +.Nm CMS_SignerInfo_cert_cmp , +.Nm CMS_SignerInfo_set1_signer_cert +.Nd CMS SignedData signer functions +.Sh SYNOPSIS +.In openssl/cms.h +.Ft STACK_OF(CMS_SignerInfo) * +.Fo CMS_get0_SignerInfos +.Fa "CMS_ContentInfo *cms" +.Fc +.Ft int +.Fo CMS_SignerInfo_get_version +.Fa "CMS_SignerInfo *si" +.Fa "long *version" +.Fc +.Ft int +.Fo CMS_SignerInfo_get0_signer_id +.Fa "CMS_SignerInfo *si" +.Fa "ASN1_OCTET_STRING **keyid" +.Fa "X509_NAME **issuer" +.Fa "ASN1_INTEGER **sno" +.Fc +.Ft ASN1_OCTET_STRING * +.Fo CMS_SignerInfo_get0_signature +.Fa "CMS_SignerInfo *si" +.Fc +.Ft int +.Fo CMS_SignerInfo_cert_cmp +.Fa "CMS_SignerInfo *si" +.Fa "X509 *certificate" +.Fc +.Ft void +.Fo CMS_SignerInfo_set1_signer_cert +.Fa "CMS_SignerInfo *si" +.Fa "X509 *signer" +.Fc +.Sh DESCRIPTION +.Fn CMS_get0_SignerInfos +returns all the +.Vt SignerInfo +structures associated with the +.Vt SignedData +structure +.Fa cms . +.Pp +.Fn CMS_SignerInfo_get_version +sets +.Pf * Fa version +to the syntax version number of the +.Vt SignerInfo +structure +.Fa si . +.Pp +.Fn CMS_SignerInfo_get0_signer_id +retrieves the certificate +.Vt SignerIdentifier +associated with the +.Vt SignerInfo +structure +.Fa si . +Either the +.Vt SubjectKeyIdentifier +will be set in +.Fa keyid +or both issuer name and serial number in +.Fa issuer +and +.Fa sno . +.Pp +.Fn CMS_SignerInfo_get0_signature +retrieves the +.Fa signature +field of +.Fa si . +The application program is allowed to modify the data pointed to. +.Pp +.Fn CMS_SignerInfo_cert_cmp +compares the +.Fa certificate +against the signer identifier of +.Fa si . +.Pp +.Fn CMS_SignerInfo_set1_signer_cert +sets the signer certificate of +.Fa si +to +.Fa signer . +.Pp +The main purpose of these functions is to enable an application to +look up signer certificates using any appropriate technique when the +simpler method of +.Xr CMS_verify 3 +is not appropriate. +.Pp +In typical usage, an application retrieves all +.Vt CMS_SignerInfo +structures using +.Fn CMS_get0_SignerInfos +and retrieves the identifier information using CMS. +It will then obtain the signer certificate by some unspecified means +(or return and error if it cannot be found) and set it using +.Fn CMS_SignerInfo_set1_signer_cert . +Once all signer certificates have been set, +.Xr CMS_verify 3 +can be used. +.Sh RETURN VALUES +.Fn CMS_get0_SignerInfos +returns an internal pointer to all the +.Vt CMS_SignerInfo +structures, or +.Dv NULL +if there are no signers or if +.Fa cms +is not of the type +.Vt SignedData . +.Pp +.Fn CMS_SignerInfo_get_version +always succeeds and returns 1. +.Pp +.Fn CMS_SignerInfo_get0_signer_id +returns 1 for success or 0 for failure. +.Pp +.Fn CMS_SignerInfo_get0_signature +returns an internal pointer to the signature. +.Pp +.Fn CMS_SignerInfo_cert_cmp +returns 0 for a match or non-zero otherwise. +.Pp +Any error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_verify 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax (CMS) +.Bl -dash -compact -offset indent +.It +section 5.1: SignedData Type +.It +section 5.3: SignerInfo Type +.El +.Sh HISTORY +.Fn CMS_get0_SignerInfos , +.Fn CMS_SignerInfo_get0_signer_id , +.Fn CMS_SignerInfo_cert_cmp , +and +.Fn CMS_SignerInfo_set1_signer_cert +first appeared in OpenSSL 0.9.8h and +.Fn CMS_SignerInfo_get0_signature +in OpenSSL 1.0.2. +These functions have been available since +.Ox 6.7 . +.Pp +.Fn CMS_SignerInfo_get_version +first appeared in +.Ox 7.4 . diff --git a/Libraries/libressl/man/CMS_get0_type.3 b/Libraries/libressl/man/CMS_get0_type.3 new file mode 100644 index 000000000..55adacd86 --- /dev/null +++ b/Libraries/libressl/man/CMS_get0_type.3 @@ -0,0 +1,226 @@ +.\" $OpenBSD: CMS_get0_type.3,v 1.9 2023/07/27 05:31:28 tb Exp $ +.\" full merge up to: OpenSSL 72a7a702 Feb 26 14:05:09 2019 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 27 2023 $ +.Dt CMS_GET0_TYPE 3 +.Os +.Sh NAME +.Nm CMS_get0_type , +.Nm CMS_get_version , +.Nm CMS_set1_eContentType , +.Nm CMS_get0_eContentType , +.Nm CMS_get0_content +.Nd get and set CMS content types and content +.Sh SYNOPSIS +.In openssl/cms.h +.Ft const ASN1_OBJECT * +.Fo CMS_get0_type +.Fa "const CMS_ContentInfo *cms" +.Fc +.Ft int +.Fo CMS_get_version +.Fa "const CMS_ContentInfo *cms" +.Fa "long *version" +.Fc +.Ft int +.Fo CMS_set1_eContentType +.Fa "CMS_ContentInfo *cms" +.Fa "const ASN1_OBJECT *oid" +.Fc +.Ft const ASN1_OBJECT * +.Fo CMS_get0_eContentType +.Fa "CMS_ContentInfo *cms" +.Fc +.Ft ASN1_OCTET_STRING ** +.Fo CMS_get0_content +.Fa "CMS_ContentInfo *cms" +.Fc +.Sh DESCRIPTION +.Fn CMS_get0_type +returns the content type of the +.Vt ContentInfo +structure +.Fa cms . +The +.Vt ASN1_OBJECT +value returned can be converted to an integer NID value using +.Xr OBJ_obj2nid 3 . +The following content types are identified by the following NIDs: +.Pp +.Bl -column AuthenticatedData NID_id_smime_ct_compressedData -compact +.It Vt SignedData Ta Dv NID_pkcs7_signed +.It Vt EnvelopedData Ta Dv NID_pkcs7_enveloped +.It Vt DigestedData Ta Dv NID_pkcs7_digest +.It Vt EncryptedData Ta Dv NID_pkcs7_encrypted +.It Vt AuthenticatedData Ta Dv NID_id_smime_ct_authData +.It Vt CompressedData Ta Dv NID_id_smime_ct_compressedData +.It arbitrary data Ta Dv NID_pkcs7_data +.El +.Pp +The +.Vt SignedData , +.Vt DigestedData , +.Vt AuthenticatedData , +and +.Vt CompressedData +types contain a field +.Fa encapContentInfo +to allow embedding content, and +.Vt EnvelopedData +and +.Vt EncryptedData +contain a field +.Fa encryptedContentInfo +for that purpose. +The type of the embedded content to be stored in that field can be +set with the function +.Fn CMS_set1_eContentType , +to be called on +.Fa cms +structures returned from functions such as +.Xr CMS_sign 3 +or +.Xr CMS_encrypt 3 +with the +.Dv CMS_PARTIAL +flag set and +.Em before +the structure is finalised; otherwise the results are undefined. +.Fn CMS_set1_eContentType +copies the supplied +.Fa oid , +so it should be freed up after use. +.Pp +.Fn CMS_get_version +sets +.Pf * Fa version +to the syntax version number of the +.Vt ContentInfo +structure +.Fa cms . +The version is a number between 0 and 5 and is defined for all the +above content types except for arbitrary data. +For arbitrary data and unsupported content types +.Fn CMS_get_version +fails and the content of +.Pf * Fa version +is unspecified. +.Pp +.Fn CMS_get0_eContentType +returns the type of the embedded content. +.Pp +.Fn CMS_get0_content +returns a pointer to the storage location where the pointer to the +embedded content is stored. +That means that for example after +.Pp +.Dl ASN1_OCTET_STRING **pconf = CMS_get0_content(cms); +.Pp +.Pf * Va pconf +could be +.Dv NULL +if there is no embedded content. +Applications can access, modify or create the embedded content in a +.Vt CMS_ContentInfo +structure using this function. +Applications usually will not need to modify the embedded content as it +is normally set by higher level functions. +.Sh RETURN VALUES +.Fn CMS_get0_type +and +.Fn CMS_get0_eContentType +return internal pointers to +.Vt OBJECT IDENTIFIER +structures. +.Pp +.Fn CMS_get_version +returns 1 on success and 0 on failure. +.Pp +.Fn CMS_get0_content +returns an internal pointer to the storage location where the pointer +to the embedded content is stored. +.Pp +.Fn CMS_set1_eContentType +returns 1 for success or 0 if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr d2i_CMS_ContentInfo 3 , +.Xr SMIME_read_CMS 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax +.Pp +RFC 3274: Compressed Data Content Type for Cryptographic Message Syntax (CMS) +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . +.Pp +.Fn CMS_get_version +first appeared in +.Ox 7.4 . diff --git a/Libraries/libressl/man/CMS_get1_ReceiptRequest.3 b/Libraries/libressl/man/CMS_get1_ReceiptRequest.3 new file mode 100644 index 000000000..9feedd13a --- /dev/null +++ b/Libraries/libressl/man/CMS_get1_ReceiptRequest.3 @@ -0,0 +1,198 @@ +.\" $OpenBSD: CMS_get1_ReceiptRequest.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_GET1_RECEIPTREQUEST 3 +.Os +.Sh NAME +.Nm CMS_ReceiptRequest_create0 , +.Nm CMS_add1_ReceiptRequest , +.Nm CMS_get1_ReceiptRequest , +.Nm CMS_ReceiptRequest_get0_values +.Nd CMS signed receipt request functions +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ReceiptRequest * +.Fo CMS_ReceiptRequest_create0 +.Fa "unsigned char *id" +.Fa "int idlen" +.Fa "int allorfirst" +.Fa "STACK_OF(GENERAL_NAMES) *receiptList" +.Fa "STACK_OF(GENERAL_NAMES) *receiptsTo" +.Fc +.Ft int +.Fo CMS_add1_ReceiptRequest +.Fa "CMS_SignerInfo *si" +.Fa "CMS_ReceiptRequest *rr" +.Fc +.Ft int +.Fo CMS_get1_ReceiptRequest +.Fa "CMS_SignerInfo *si" +.Fa "CMS_ReceiptRequest **prr" +.Fc +.Ft void +.Fo CMS_ReceiptRequest_get0_values +.Fa "CMS_ReceiptRequest *rr" +.Fa "ASN1_STRING **pcid" +.Fa "int *pallorfirst" +.Fa "STACK_OF(GENERAL_NAMES) **plist" +.Fa "STACK_OF(GENERAL_NAMES) **prto" +.Fc +.Sh DESCRIPTION +.Fn CMS_ReceiptRequest_create0 +creates a new +.Vt ReceiptRequest +structure. +The +.Fa signedContentIdentifier +field is set using +.Fa id +and +.Fa idlen , +or it is set to 32 bytes of pseudo random data if +.Fa id +is +.Dv NULL . +If +.Fa receiptList +is +.Dv NULL , +the +.Fa allOrFirstTier +option in the +.Fa receiptsFrom +field is set to the value of the +.Fa allorfirst +argument. +If +.Fa receiptList +is not +.Dv NULL , +the +.Fa receiptList +option in the +.Fa receiptsFrom +field is used. +The +.Fa receiptsTo +argument specifies the value of the +.Fa receiptsTo +field. +.Pp +.Fn CMS_add1_ReceiptRequest +adds a BER-encoded copy of +.Fa rr +to +.Fa si . +.Pp +.Fn CMS_get1_ReceiptRequest +looks for a signed receipt request in +.Fa si . +If any is found, it is decoded and written to +.Fa prr . +.Pp +.Fn CMS_ReceiptRequest_get0_values +retrieves the values of a receipt request. +The +.Fa signedContentIdentifier +is copied to +.Fa pcid . +If the +.Fa allOrFirstTier +option is used in the +.Fa receiptsFrom +field, its value is copied to +.Fa pallorfirst ; +otherwise the +.Fa receiptList +field is copied to +.Fa plist . +The +.Fa receiptsTo +field is copied to +.Fa prto . +.Pp +The contents of a signed receipt should only be considered meaningful if +the corresponding +.Vt CMS_ContentInfo +structure can be successfully verified using +.Xr CMS_verify 3 . +.Sh RETURN VALUES +.Fn CMS_ReceiptRequest_create0 +returns the new signed receipt request structure or +.Dv NULL +if an error occurred. +.Pp +.Fn CMS_add1_ReceiptRequest +returns 1 for success or 0 if an error occurred. +.Pp +.Fn CMS_get1_ReceiptRequest +returns 1 is a signed receipt request is found and decoded. +It returns 0 if a signed receipt request is not present or -1 if it is +present but malformed. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_sign 3 , +.Xr CMS_sign_receipt 3 , +.Xr CMS_verify 3 , +.Xr CMS_verify_receipt 3 , +.Xr ERR_get_error 3 +.Sh STANDARDS +RFC 2634: Enhanced Security Services for S/MIME, +section 2.7: Receipt Request Syntax +.Sh HISTORY +.Fn CMS_ReceiptRequest_create0 , +.Fn CMS_add1_ReceiptRequest , +.Fn CMS_get1_ReceiptRequest , +and +.Fn CMS_ReceiptRequest_get0_values +first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_sign.3 b/Libraries/libressl/man/CMS_sign.3 new file mode 100644 index 000000000..64461959d --- /dev/null +++ b/Libraries/libressl/man/CMS_sign.3 @@ -0,0 +1,243 @@ +.\" $OpenBSD: CMS_sign.3,v 1.9 2020/06/24 18:15:00 jmc Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 24 2020 $ +.Dt CMS_SIGN 3 +.Os +.Sh NAME +.Nm CMS_sign +.Nd create a CMS SignedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo CMS_sign +.Fa "X509 *signcert" +.Fa "EVP_PKEY *pkey" +.Fa "STACK_OF(X509) *certs" +.Fa "BIO *data" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_sign +creates and returns a CMS +.Vt SignedData +structure. +.Fa signcert +is the certificate to sign with, +.Fa pkey +is the corresponding private key. +.Fa certs +is an optional additional set of certificates to include in the CMS +structure (for example any intermediate CAs in the chain). +Any or all of these parameters can be +.Dv NULL . +.Pp +The data to be signed is read from +.Fa data . +.Pp +Any of the following flags (OR'ed together) can be passed in the +.Fa flags +argument: +.Bl -tag -width Ds +.It Dv CMS_TEXT +Prepend MIME headers for the type text/plain to the data. +Many S/MIME clients expect the signed content to include valid MIME +headers. +.It Dv CMS_NOCERTS +Do not include the signer's certificate in the +.Vt CMS_ContentInfo +structure. +The signer's certificate must still be supplied in the +.Fa signcert +parameter though. +This can reduce the size of the signature if the signer's certificate can +be obtained by other means, for example from a previously signed message. +.It Dv CMS_DETACHED +Omit the data being signed from the +.Vt CMS_ContentInfo +structure. +This is used for +.Vt CMS_ContentInfo +detached signatures which are used in S/MIME plaintext signed messages +for example. +.It Dv CMS_BINARY +Do not translate the supplied content into MIME canonical format +even though that is required by the S/MIME specifications. +This option should be used if the supplied data is in binary format. +Otherwise the translation will corrupt it. +.It Dv CMS_NOATTR +Do not add any +.Vt SignedAttributes . +By default, the +.Fa signerInfos +field includes several CMS +.Vt SignedAttributes +including the signing time, the CMS content type, +and the supported list of ciphers in an +.Vt SMIMECapabilities +attribute. +.It Dv CMS_NOSMIMECAP +Omit just the +.Vt SMIMECapabilities . +If present, the SMIMECapabilities attribute indicates support for the +following algorithms in preference order: 256-bit AES, Gost R3411-94, +Gost 28147-89, 192-bit AES, 128-bit AES, triple DES, 128-bit RC2, 64-bit +RC2, DES and 40-bit RC2. +If any of these algorithms is not available, then it will not be +included. +.It Dv CMS_USE_KEYID +Use the subject key identifier value to identify signing certificates. +An error occurs if the signing certificate does not have a subject key +identifier extension. +By default, issuer name and serial number are used instead. +.It Dv CMS_STREAM +Only initialize the returned +.Vt CMS_ContentInfo +structure to prepare it for performing the signing operation. +The signing is however +.Em not +performed and the data to be signed is not read from the +.Fa data +parameter. +Signing is deferred until after the data has been written. +In this way, data can be signed in a single pass. +The returned +.Vt CMS_ContentInfo +structure is +.Em not +complete and outputting its contents via a function that does not +properly finalize the +.Vt CMS_ContentInfo +structure will give unpredictable results. +Several functions including +.Xr SMIME_write_CMS 3 , +.Xr i2d_CMS_bio_stream 3 , +or +.Xr PEM_write_bio_CMS_stream 3 +finalize the structure. +Alternatively, finalization can be performed by obtaining the streaming +ASN1 +.Vt BIO +directly using +.Xr BIO_new_CMS 3 . +.It Dv CMS_PARTIAL +Output a partial +.Vt CMS_ContentInfo +structure to which additional signers and capabilities can be +added before finalization. +.El +.Pp +If a signer is specified, it will use the default digest for the signing +algorithm. +This is SHA1 for both RSA and DSA keys. +.Pp +If +.Fa signcert +and +.Fa pkey +are +.Dv NULL , +then a certificates only CMS structure is output. +.Pp +The function +.Fn CMS_sign +is a basic CMS signing function whose output will be suitable for many +purposes. +For finer control of the output format the +.Fa certs , +.Fa signcert +and +.Fa pkey +parameters can all be +.Dv NULL +and the +.Dv CMS_PARTIAL +flag set. +Then one or more signers can be added using the function +.Xr CMS_add1_signer 3 , +non default digests can be used and custom attributes added. +.Xr CMS_final 3 +must then be called to finalize the structure if streaming is not +enabled. +.Sh RETURN VALUES +.Fn CMS_sign +returns either a valid +.Vt CMS_ContentInfo +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_add0_cert 3 , +.Xr CMS_add1_signer 3 , +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_final 3 , +.Xr CMS_sign_receipt 3 , +.Xr CMS_verify 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax (CMS) +.Bl -dash -compact -offset indent +.It +section 5.1: SignedData Type +.It +section 5.3: SignerInfo Type +.El +.Pp +RFC 8551: Secure/Multipurpose Internet Mail Extensions (S/MIME) +Version\ 4.0 Message Specification, +section 2.5.2: SMIMECapabilities Attribute +.Sh HISTORY +.Fn CMS_sign +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . +.Sh BUGS +Some attributes such as counter signatures are not supported. diff --git a/Libraries/libressl/man/CMS_sign_receipt.3 b/Libraries/libressl/man/CMS_sign_receipt.3 new file mode 100644 index 000000000..639495784 --- /dev/null +++ b/Libraries/libressl/man/CMS_sign_receipt.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: CMS_sign_receipt.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_SIGN_RECEIPT 3 +.Os +.Sh NAME +.Nm CMS_sign_receipt +.Nd create a CMS signed receipt +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo CMS_sign_receipt +.Fa "CMS_SignerInfo *si" +.Fa "X509 *signcert" +.Fa "EVP_PKEY *pkey" +.Fa "STACK_OF(X509) *certs" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_sign_receipt +creates a new CMS +.Vt SignedData +structure containing a signed +.Vt Receipt +as its embedded content. +.Fa si +is the +.Vt SignerInfo +structure containing the signed receipt request. +.Fa signcert +is the certificate to sign with, +.Fa pkey +is the corresponding private key. +.Fa certs +is an optional additional set of certificates to include in the CMS +structure (for example any intermediate CAs in the chain). +.Pp +This functions behaves in a similar way to +.Xr CMS_sign 3 +except that the +.Fa flags +values +.Dv CMS_DETACHED , +.Dv CMS_BINARY , +.Dv CMS_NOATTR , +.Dv CMS_TEXT , +and +.Dv CMS_STREAM +are not supported since they do not make sense in the context of +signed receipts. +.Sh RETURN VALUES +.Fn CMS_sign_receipt +returns either a valid +.Vt CMS_ContentInfo +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_get1_ReceiptRequest 3 , +.Xr CMS_sign 3 , +.Xr CMS_verify_receipt 3 +.Sh STANDARDS +RFC 2634: Enhanced Security Services for S/MIME, section 2.8: Receipt Syntax +.Sh HISTORY +.Fn CMS_sign_receipt +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMS_uncompress.3 b/Libraries/libressl/man/CMS_uncompress.3 new file mode 100644 index 000000000..ed2172521 --- /dev/null +++ b/Libraries/libressl/man/CMS_uncompress.3 @@ -0,0 +1,115 @@ +.\" $OpenBSD: CMS_uncompress.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_UNCOMPRESS 3 +.Os +.Sh NAME +.Nm CMS_uncompress +.Nd uncompress a CMS CompressedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo CMS_uncompress +.Fa "CMS_ContentInfo *cms" +.Fa "BIO *dcont" +.Fa "BIO *out" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_uncompress +extracts and uncompresses the content of a CMS +.Vt CompressedData +structure +.Fa cms +and writes it to +.Fa out . +.Pp +In the rare case where the compressed content is detached, +pass it in via +.Fa dcont . +For normal use, set +.Fa dcont +to +.Dv NULL . +.Pp +The only currently supported compression algorithm is zlib: if the +structure indicates the use of any other algorithm, an error is returned. +If zlib support is not compiled in, +.Fn CMS_uncompress +always returns an error. +.Pp +If the +.Dv CMS_TEXT +bit is set in +.Fa flags , +MIME headers for type text/plain are deleted from the content. +If the content is not of type text/plain, an error is returned. +.Sh RETURN VALUES +.Fn CMS_uncompress +returns 1 for success or 0 for failure. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_compress 3 , +.Xr CMS_ContentInfo_new 3 +.Sh STANDARDS +RFC 3274: Compressed Data Content Type for Cryptographic Message Syntax (CMS) +.Sh HISTORY +.Fn CMS_uncompress +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . +.Sh BUGS +The lack of single pass processing and the need to hold all data in +memory as mentioned in +.Xr CMS_verify 3 +also applies to +.Fn CMS_uncompress . diff --git a/Libraries/libressl/man/CMS_verify.3 b/Libraries/libressl/man/CMS_verify.3 new file mode 100644 index 000000000..ac2386669 --- /dev/null +++ b/Libraries/libressl/man/CMS_verify.3 @@ -0,0 +1,227 @@ +.\" $OpenBSD: CMS_verify.3,v 1.9 2023/06/05 17:17:23 job Exp $ +.\" full merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 5 2023 $ +.Dt CMS_VERIFY 3 +.Os +.Sh NAME +.Nm CMS_verify , +.Nm CMS_get0_signers +.Nd verify a CMS SignedData structure +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo CMS_verify +.Fa "CMS_ContentInfo *cms" +.Fa "STACK_OF(X509) *certs" +.Fa "X509_STORE *store" +.Fa "BIO *indata" +.Fa "BIO *out" +.Fa "unsigned int flags" +.Fc +.Ft STACK_OF(X509) * +.Fo CMS_get0_signers +.Fa "CMS_ContentInfo *cms" +.Fc +.Sh DESCRIPTION +.Fn CMS_verify +verifies the CMS +.Vt SignedData +structure +.Fa cms . +.Fa certs +is a set of certificates in which to search for the signing +certificate(s). +.Fa store +is a trusted certificate store used for chain verification. +.Fa indata +is the detached content if the content is not present in +.Fa cms . +The content is written to +.Fa out +if it is not +.Dv NULL . +.Pp +.Fn CMS_get0_signers +retrieves the signing certificate(s) from +.Fa cms . +It may only be called after a successful +.Fn CMS_verify +operation. +The signers must be freed with +.Fn sk_X509_free . +.Pp +Normally the verify process proceeds as follows. +.Pp +Initially some sanity checks are performed on +.Fa cms . +There must be at least one signature on the data. +If the content is detached, +.Fa indata +cannot be +.Dv NULL . +.Pp +An attempt is made to locate all the signing certificate(s), first +looking in the +.Fa certs +parameter (if it is not +.Dv NULL ) +and then looking in any certificates contained in the +.Fa cms +structure itself. +If any signing certificate cannot be located, the operation fails. +.Pp +Each signing certificate is chain verified using the +.Sy smimesign +purpose and the supplied trusted certificate +.Fa store . +Any internal certificates in the message are used as untrusted CAs. +If CRL checking is enabled in +.Fa store , +any internal CRLs are used in addition to attempting to look them up in +.Fa store . +If any chain verify fails, an error code is returned. +.Pp +Finally the signed content is read (and written to +.Fa out +if it is not +.Dv NULL ) +and the signature is checked. +.Pp +If all signatures verify correctly, then the function is successful. +.Pp +Any of the following +.Fa flags +(OR'ed together) can be passed to change the default verify behaviour: +.Bl -tag -width Ds +.It Dv CMS_NOINTERN +Do not use the certificates in the message itself when +locating the signing certificate(s). +This means that all the signing certificates must be in the +.Fa certs +parameter. +.It Dv CMS_NOCRL +If CRL checking is enabled in +.Fa store , +then any CRLs in the message itself are ignored. +.It Dv CMS_TEXT +MIME headers for type text/plain are deleted from the content. +If the content is not of type text/plain, an error is returned. +.It Dv CMS_NO_SIGNER_CERT_VERIFY +Do not verify signing certificates. +.It Dv CMS_NO_ATTR_VERIFY +Do not check the signed attributes signature. +.It Dv CMS_NO_CONTENT_VERIFY +Do not check the content digest. +.El +.Pp +One application of +.Dv CMS_NOINTERN +is to only accept messages signed by a small number of certificates. +The acceptable certificates would be passed in the +.Fa certs +parameter. +In this case, if the signer is not one of the certificates supplied in +.Fa certs , +then the verify will fail because the signer cannot be found. +.Pp +In some cases the standard techniques for looking up and validating +certificates are not appropriate: for example an application may wish to +lookup certificates in a database or perform customised verification. +This can be achieved by setting and verifying the signers certificates +manually using the signed data utility functions. +.Pp +Care should be taken when modifying the default verify behaviour, for +example setting +.Dv CMS_NO_CONTENT_VERIFY +will totally disable all content verification and any modified content +will be considered valid. +This combination is however useful if one merely wishes to write the +content to +.Fa out +and its validity is not considered important. +.Pp +Chain verification should arguably be performed using the signing time +rather than the current time. +However since the signing time is supplied by the signer it cannot be +trusted without additional evidence (such as a trusted timestamp). +.Sh RETURN VALUES +.Fn CMS_verify +returns 1 for a successful verification or 0 if an error occurred. +.Pp +.Fn CMS_get0_signers +returns all signers or +.Dv NULL +if an error occurred. +The signers must be freed with +.Fn sk_X509_free . +.Pp +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_get0_SignerInfos 3 , +.Xr CMS_sign 3 , +.Xr CMS_verify_receipt 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax (CMS), +section 5.1: SignedData Type +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . +.Sh BUGS +The trusted certificate store is not searched for the signing certificate. +This is primarily due to the inadequacies of the current +.Vt X509_STORE +functionality. +.Pp +The lack of single pass processing means that the signed content must +all be held in memory if it is not detached. diff --git a/Libraries/libressl/man/CMS_verify_receipt.3 b/Libraries/libressl/man/CMS_verify_receipt.3 new file mode 100644 index 000000000..ac50087a4 --- /dev/null +++ b/Libraries/libressl/man/CMS_verify_receipt.3 @@ -0,0 +1,110 @@ +.\" $OpenBSD: CMS_verify_receipt.3,v 1.7 2019/11/02 15:39:46 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt CMS_VERIFY_RECEIPT 3 +.Os +.Sh NAME +.Nm CMS_verify_receipt +.Nd verify a CMS signed receipt +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo CMS_verify_receipt +.Fa "CMS_ContentInfo *rcms" +.Fa "CMS_ContentInfo *ocms" +.Fa "STACK_OF(X509) *certs" +.Fa "X509_STORE *store" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +.Fn CMS_verify_receipt +verifies a CMS signed receipt. +.Fa rcms +is the signed receipt to verify. +.Fa ocms +is the original +.Vt SignedData +structure containing the receipt request. +.Fa certs +is a set of certificates in which to search for the signing certificate. +.Fa store +is a trusted certificate store (used for chain verification). +.Pp +This functions behaves in a similar way to +.Xr CMS_verify 3 +except that the +.Fa flags +values +.Dv CMS_DETACHED , +.Dv CMS_BINARY , +.Dv CMS_TEXT , +and +.Dv CMS_STREAM +are not supported since they do not make sense in the context of signed +receipts. +.Sh RETURN VALUES +.Fn CMS_verify_receipt +returns 1 for a successful verification or 0 if an error occurred. +.Pp +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_get1_ReceiptRequest 3 , +.Xr CMS_sign_receipt 3 , +.Xr CMS_verify 3 +.Sh STANDARDS +RFC 2634: Enhanced Security Services for S/MIME, section 2.8: Receipt Syntax +.Sh HISTORY +.Fn CMS_verify_receipt +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/CMakeLists.txt b/Libraries/libressl/man/CMakeLists.txt new file mode 100644 index 000000000..462a83161 --- /dev/null +++ b/Libraries/libressl/man/CMakeLists.txt @@ -0,0 +1,11 @@ +if(ENABLE_LIBRESSL_INSTALL) + install(DIRECTORY . + DESTINATION ${CMAKE_INSTALL_MANDIR}/man3 + FILES_MATCHING PATTERN "*.3" + ) + + install(DIRECTORY . + DESTINATION ${CMAKE_INSTALL_MANDIR}/man5 + FILES_MATCHING PATTERN "*.5" + ) +endif(ENABLE_LIBRESSL_INSTALL) diff --git a/Libraries/libressl/man/CONF_modules_free.3 b/Libraries/libressl/man/CONF_modules_free.3 new file mode 100644 index 000000000..c5fb84094 --- /dev/null +++ b/Libraries/libressl/man/CONF_modules_free.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: CONF_modules_free.3,v 1.6 2023/07/21 10:46:54 tb Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2004, 2006 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 21 2023 $ +.Dt CONF_MODULES_FREE 3 +.Os +.Sh NAME +.Nm CONF_modules_free , +.Nm CONF_modules_finish , +.Nm CONF_modules_unload +.Nd OpenSSL configuration cleanup functions +.Sh SYNOPSIS +.In openssl/conf.h +.Ft void +.Fo CONF_modules_free +.Fa void +.Fc +.Ft void +.Fo CONF_modules_finish +.Fa void +.Fc +.Ft void +.Fo CONF_modules_unload +.Fa "int all" +.Fc +.Sh DESCRIPTION +.Fn CONF_modules_free +closes down and frees up all memory allocated by all configuration +modules. +Normally applications will only call this function +at application exit to tidy up any configuration performed. +.Pp +.Fn CONF_modules_finish +calls the configuration +.Sy finish +handler of each configuration module to free up any configuration +that module may have performed. +.Pp +.Fn CONF_modules_unload +finishes and unloads configuration modules. +If +.Fa all +is set to 1, the builtin modules will be unloaded as well. +.Sh SEE ALSO +.Xr CONF_modules_load_file 3 , +.Xr OPENSSL_config 3 +.Sh HISTORY +.Fn CONF_modules_free , +.Fn CONF_modules_finish , +and +.Fn CONF_modules_unload +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/CONF_modules_load_file.3 b/Libraries/libressl/man/CONF_modules_load_file.3 new file mode 100644 index 000000000..964473d49 --- /dev/null +++ b/Libraries/libressl/man/CONF_modules_load_file.3 @@ -0,0 +1,286 @@ +.\" $OpenBSD: CONF_modules_load_file.3,v 1.11 2023/07/21 10:46:54 tb Exp $ +.\" full merge up to: e9b77246 Jan 20 19:58:49 2017 +0100 +.\" selective merge up to: d090fc00 Feb 26 13:11:10 2019 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 21 2023 $ +.Dt CONF_MODULES_LOAD_FILE 3 +.Os +.Sh NAME +.Nm CONF_modules_load_file , +.Nm CONF_modules_load , +.Nm X509_get_default_cert_area +.Nd OpenSSL configuration functions +.Sh SYNOPSIS +.In openssl/conf.h +.Ft int +.Fo CONF_modules_load_file +.Fa "const char *filename" +.Fa "const char *appname" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo CONF_modules_load +.Fa "const CONF *cnf" +.Fa "const char *appname" +.Fa "unsigned long flags" +.Fc +.In openssl/x509.h +.Ft const char * +.Fn X509_get_default_cert_area void +.Sh DESCRIPTION +The function +.Fn CONF_modules_load_file +configures OpenSSL using the file +.Fa filename +in +.Xr openssl.cnf 5 +format and the application name +.Fa appname . +If +.Fa filename +is +.Dv NULL , +the standard OpenSSL configuration file +.Pa /etc/ssl/openssl.cnf +is used. +If +.Fa appname +is +.Dv NULL , +the standard OpenSSL application name +.Qq openssl_conf +is used. +The behaviour can be customized using +.Fa flags . +.Pp +See the +.Sx EXAMPLES +section for additional functions that may need to be called. +Calling configuration functions in the right order for the intended +effect can be tricky because many configuration functions internally +call each other. +.Pp +.Fn CONF_modules_load +is identical to +.Fn CONF_modules_load_file +except it reads configuration information from +.Fa cnf . +.Pp +The following +.Fa flags +are currently recognized: +.Bl -tag -width Ds +.It Dv CONF_MFLAGS_IGNORE_ERRORS +Ignore errors returned by individual configuration modules. +By default, the first module error is considered fatal and no further +modules are loaded. +.It Dv CONF_MFLAGS_SILENT +Do not add any error information. +By default, all module errors add error information to the error queue. +.It Dv CONF_MFLAGS_NO_DSO +Disable loading of configuration modules from DSOs. +This flag is provided for compatibility and has no effect. +.It Dv CONF_MFLAGS_IGNORE_MISSING_FILE +Let +.Fn CONF_modules_load_file +ignore missing configuration files. +By default, a missing configuration file returns an error. +.It CONF_MFLAGS_DEFAULT_SECTION +If +.Fa appname +is not +.Dv NULL +but does not exist, fall back to the default section +.Qq openssl_conf . +.El +.Pp +By using +.Fn CONF_modules_load_file +with appropriate flags, an application can customise application +configuration to best suit its needs. +In some cases the use of a configuration file is optional and its +absence is not an error: in this case +.Dv CONF_MFLAGS_IGNORE_MISSING_FILE +would be set. +.Pp +Errors during configuration may also be handled differently by +different applications. +For example in some cases an error may simply print out a warning +message and the application may continue. +In other cases an application might consider a configuration file +error fatal and exit immediately. +.Pp +Applications can use the +.Fn CONF_modules_load +function if they wish to load a configuration file themselves and +have finer control over how errors are treated. +.Sh RETURN VALUES +.Fn CONF_modules_load_file +and +.Fn CONF_modules_load +return 1 for success and zero or a negative value for failure. +If module errors are not ignored, the return code will reflect the return +value of the failing module (this will always be zero or negative). +.Pp +.Fn X509_get_default_cert_area +returns a pointer to the constant string +.Qq "/etc/ssl" . +.Sh FILES +.Bl -tag -width /etc/ssl/openssl.cnf -compact +.It Pa /etc/ssl +standard configuration directory +.It Pa /etc/ssl/openssl.cnf +standard configuration file +.El +.Sh EXAMPLES +Load a configuration file and print out any errors and exit (missing +file considered fatal): +.Bd -literal +if (CONF_modules_load_file(NULL, NULL, 0) <= 0) { + fprintf(stderr, "FATAL: error loading configuration file\en"); + ERR_print_errors_fp(stderr); + exit(1); +} +.Ed +.Pp +Load default configuration file using the section indicated +by "myapp", tolerate missing files, but exit on other errors: +.Bd -literal +if (CONF_modules_load_file(NULL, "myapp", + CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) { + fprintf(stderr, "FATAL: error loading configuration file\en"); + ERR_print_errors_fp(stderr); + exit(1); +} +.Ed +.Pp +Load custom configuration file and section instead of the standard one, +only print warnings on error, missing configuration file ignored: +.Bd -literal +OPENSSL_no_config(); +ENGINE_load_builtin_engines(); +OPENSSL_load_builtin_modules(); +if (CONF_modules_load_file("/something/app.cnf", "myapp", + CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) { + fprintf(stderr, "WARNING: error loading configuration file\en"); + ERR_print_errors_fp(stderr); +} +.Ed +.Pp +In the previous example, the call to +.Xr OPENSSL_no_config 3 +is required first to suppress automatic loading +of the standard configuration file, and the calls to +.Xr ENGINE_load_builtin_engines 3 +and +.Xr OPENSSL_load_builtin_modules 3 +are needed so that the configuration of builtin modules and engines +is also loaded in addition to the configuration of +.Qq myapp . +.Pp +Load and parse configuration file manually, custom error handling: +.Bd -literal +FILE *fp; +CONF *cnf = NULL; +long eline; + +fp = fopen("/somepath/app.cnf", "r"); +if (fp == NULL) { + fprintf(stderr, "Error opening configuration file\en"); + /* Other missing configuration file behaviour */ +} else { + cnf = NCONF_new(NULL); + if (NCONF_load_fp(cnf, fp, &eline) == 0) { + fprintf(stderr, "Error on line %ld of configuration file\en", + eline); + ERR_print_errors_fp(stderr); + /* Other malformed configuration file behaviour */ + } else if (CONF_modules_load(cnf, "appname", 0) <= 0) { + fprintf(stderr, "Error configuring application\en"); + ERR_print_errors_fp(stderr); + /* Other configuration error behaviour */ + } + fclose(fp); + NCONF_free(cnf); +} +.Ed +.Sh SEE ALSO +.Xr CONF_modules_free 3 , +.Xr ENGINE_load_builtin_engines 3 , +.Xr ERR 3 , +.Xr OPENSSL_config 3 , +.Xr OPENSSL_load_builtin_modules 3 +.Sh HISTORY +.Fn X509_get_default_cert_area +first appeared in SSLeay 0.4.1 and has been available since +.Ox 2.4 . +.Pp +.Fn CONF_modules_load_file +and +.Fn CONF_modules_load +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/CRYPTO_get_mem_functions.3 b/Libraries/libressl/man/CRYPTO_get_mem_functions.3 new file mode 100644 index 000000000..5d4311628 --- /dev/null +++ b/Libraries/libressl/man/CRYPTO_get_mem_functions.3 @@ -0,0 +1,114 @@ +.\" $OpenBSD: CRYPTO_get_mem_functions.3,v 1.7 2019/06/10 09:49:48 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt CRYPTO_GET_MEM_FUNCTIONS 3 +.Os +.Sh NAME +.Nm CRYPTO_get_mem_functions , +.Nm CRYPTO_set_mem_functions , +.Nm CRYPTO_mem_ctrl , +.Nm CRYPTO_mem_leaks , +.Nm CRYPTO_mem_leaks_fp , +.Nm CRYPTO_mem_leaks_cb +.Nd legacy OpenSSL memory allocation control +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft void +.Fo CRYPTO_get_mem_functions +.Fa "void *(**m)(size_t)" +.Fa "void *(**r)(void *, size_t)" +.Fa "void (**f)(void *)" +.Fc +.Ft int +.Fo CRYPTO_set_mem_functions +.Fa "void *(*m)(size_t)" +.Fa "void *(*r)(void *, size_t)" +.Fa "void (*f)(void *)" +.Fc +.Ft int +.Fo CRYPTO_mem_ctrl +.Fa "int mode" +.Fc +.Ft int +.Fo CRYPTO_mem_leaks +.Fa "BIO *b" +.Fc +.Ft int +.Fo CRYPTO_mem_leaks_fp +.Fa "FILE *fp" +.Fc +.Ft typedef int * +.Fo CRYPTO_MEM_LEAK_CB +.Fa "unsigned long" +.Fa "const char *" +.Fa int +.Fa int +.Fa "void *" +.Fc +.Ft int +.Fo CRYPTO_mem_leaks_cb +.Fa "CRYPTO_MEM_LEAK_CB *cb" +.Fc +.Sh DESCRIPTION +Do not use any of the interfaces documented here. +They are provided purely for compatibility with legacy application code. +.Pp +.Fn CRYPTO_get_mem_functions +assigns pointers to the C library functions +.Xr malloc 3 , +.Xr realloc 3 , +and +.Xr free 3 +to those of its arguments that are not +.Dv NULL . +.Pp +.Fn CRYPTO_set_mem_functions , +.Fn CRYPTO_mem_ctrl , +.Fn CRYPTO_mem_leaks , +.Fn CRYPTO_mem_leaks_fp , +and +.Fn CRYPTO_mem_leaks_cb +have no effect. +.Sh RETURN VALUES +.Fn CRYPTO_set_mem_functions +always returns 0. +.Pp +.Fn CRYPTO_mem_ctrl +always returns +.Dv CRYPTO_MEM_CHECK_OFF . +.Pp +.Fn CRYPTO_mem_leaks , +.Fn CRYPTO_mem_leaks_fp , +and +.Fn CRYPTO_mem_leaks_cb +always return -1. +.Sh SEE ALSO +.Xr crypto 3 +.Sh HISTORY +.Fn CRYPTO_mem_ctrl , +.Fn CRYPTO_mem_leaks , +and +.Fn CRYPTO_mem_leaks_fp +first appeared in SSLeay 0.6.4. +.Fn CRYPTO_get_mem_functions +and +.Fn CRYPTO_set_mem_functions +first appeared in SSLeay 0.6.5. +.Fn CRYPTO_mem_leaks_cb +first appeared in SSLeay 0.6.6. +All these functions have all been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/CRYPTO_lock.3 b/Libraries/libressl/man/CRYPTO_lock.3 new file mode 100644 index 000000000..cb6224a70 --- /dev/null +++ b/Libraries/libressl/man/CRYPTO_lock.3 @@ -0,0 +1,176 @@ +.\" $OpenBSD: CRYPTO_lock.3,v 1.1 2019/03/10 15:00:34 schwarze Exp $ +.\" OpenSSL doc/crypto/threads.pod fb552ac6 Sep 30 23:43:01 2009 +0000 +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 10 2019 $ +.Dt CRYPTO_LOCK 3 +.Os +.Sh NAME +.Nm CRYPTO_THREADID_current , +.Nm CRYPTO_THREADID_cmp , +.Nm CRYPTO_THREADID_cpy , +.Nm CRYPTO_THREADID_hash , +.Nm CRYPTO_lock , +.Nm CRYPTO_w_lock , +.Nm CRYPTO_w_unlock , +.Nm CRYPTO_r_lock , +.Nm CRYPTO_r_unlock , +.Nm CRYPTO_add +.Nd thread support +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft void +.Fo CRYPTO_THREADID_current +.Fa "CRYPTO_THREADID *id" +.Fc +.Ft int +.Fo CRYPTO_THREADID_cmp +.Fa "const CRYPTO_THREADID *a" +.Fa "const CRYPTO_THREADID *b" +.Fc +.Ft void +.Fo CRYPTO_THREADID_cpy +.Fa "CRYPTO_THREADID *dest" +.Fa "const CRYPTO_THREADID *src" +.Fc +.Ft unsigned long +.Fo CRYPTO_THREADID_hash +.Fa "const CRYPTO_THREADID *id" +.Fc +.Ft void +.Fo CRYPTO_lock +.Fa "int mode" +.Fa "int type" +.Fa "const char *file" +.Fa "int line" +.Fc +.Ft int +.Fo CRYPTO_add +.Fa "int *p" +.Fa "int amount" +.Fa "int type" +.Fc +.Bd -literal +#define CRYPTO_w_lock(type) \e + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, __FILE__, __LINE__) +#define CRYPTO_w_unlock(type) \e + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, __FILE__, __LINE__) +#define CRYPTO_r_lock(type) \e + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ, type, __FILE__, __LINE__) +#define CRYPTO_r_unlock(type) \e + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ, type, __FILE__, __LINE__) +.Ed +.Sh DESCRIPTION +These functions are obsolete. +.Pp +.Fn CRYPTO_THREADID_current +stores a unique identifier of the currently executing thread +into the opaque object +.Fa id . +.Pp +.Fn CRYPTO_THREADID_cpy +copies the contents of +.Fa src +to +.Fa dest . +.Pp +.Fn CRYPTO_lock +locks or unlocks a mutex lock. +.Pp +.Fa mode +is a bitfield describing what should be done with the lock. +For each call, either +.Dv CRYPTO_LOCK +or +.Dv CRYPTO_UNLOCK +must be included. +In the LibreSSL implementation, +.Dv CRYPTO_READ +and +.Dv CRYPTO_WRITE +are ignored. +.Pp +.Fa type +is a number in the range 0 <= +.Fa type No < Dv CRYPTO_NUM_LOCKS +identifying a particular lock. +Currently, the value of +.Dv CRYPTO_NUM_LOCKS +is 41. +.Pp +The +.Ar file +and +.Ar line +arguments are ignored. +.Pp +In the LibreSSL implementation, +.Fn CRYPTO_lock +is a wrapper around +.Xr pthread_mutex_lock 3 +and +.Xr pthread_mutex_unlock 3 . +.Pp +.Fn CRYPTO_add +locks the lock number +.Fa type , +adds +.Fa amount +to +.Pf * Fa p , +and unlocks the lock number +.Fa type +again. +.Sh RETURN VALUES +.Fn CRYPTO_THREADID_cmp +returns 0 if +.Fa a +and +.Fa b +refer to the same thread or a non-zero value otherwise. +.Pp +.Fn CRYPTO_THREADID_hash +returns a numeric value usable as a hash-table key. +In the LibreSSL implementation, it is the value returned from +.Xr pthread_self 3 +for the thread +.Fa id . +.Pp +.Fn CRYPTO_add +returns the new value of +.Pf * Fa p . +.Sh SEE ALSO +.Xr crypto 3 +.Sh HISTORY +.Fn CRYPTO_lock , +.Fn CRYPTO_w_lock , +.Fn CRYPTO_w_unlock , +.Fn CRYPTO_r_lock , +and +.Fn CRYPTO_r_unlock +first appeared in SSLeay 0.6.0. +.Fn CRYPTO_add +first appeared in SSLeay 0.6.2. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn CRYPTO_THREADID_current , +.Fn CRYPTO_THREADID_cmp , +.Fn CRYPTO_THREADID_cpy , +and +.Fn CRYPTO_THREADID_hash +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/CRYPTO_memcmp.3 b/Libraries/libressl/man/CRYPTO_memcmp.3 new file mode 100644 index 000000000..cbc0030c5 --- /dev/null +++ b/Libraries/libressl/man/CRYPTO_memcmp.3 @@ -0,0 +1,95 @@ +.\" $OpenBSD: CRYPTO_memcmp.3,v 1.1 2019/08/25 06:20:22 schwarze Exp $ +.\" full merge up to: OpenSSL 1075139c Jun 24 09:18:48 2019 +1000 +.\" +.\" This file was written by Pauli . +.\" Copyright (c) 2019 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 25 2019 $ +.Dt CRYPTO_MEMCMP 3 +.Os +.Sh NAME +.Nm CRYPTO_memcmp +.Nd constant time memory comparison +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft int +.Fo CRYPTO_memcmp +.Fa "const void *a" +.Fa "const void *b" +.Fa "size_t len" +.Fc +.Sh DESCRIPTION +.Fn CRYPTO_memcmp +compares the +.Fa len +bytes pointed to by +.Fa a +and +.Fa b +for equality. +It takes an amount of time dependent on +.Fa len , +but independent of the contents of the memory regions pointed to by +.Fa a +and +.Fa b . +.Sh RETURN VALUES +.Fn CRYPTO_memcmp +returns 0 if the content of the memory regions is equal +or non-zero otherwise. +.Sh HISTORY +.Fn CRYPTO_memcmp +first appeared in OpenSSL 1.0.1d and has been available since +.Ox 5.6 . +.Sh BUGS +Unlike +.Xr memcmp 3 +and +.Xr timingsafe_memcmp 3 , +this function cannot be used to order the two memory regions. +In the current implementation, the return value is always greater +than or equal to 0. diff --git a/Libraries/libressl/man/CRYPTO_set_ex_data.3 b/Libraries/libressl/man/CRYPTO_set_ex_data.3 new file mode 100644 index 000000000..c22fb2235 --- /dev/null +++ b/Libraries/libressl/man/CRYPTO_set_ex_data.3 @@ -0,0 +1,564 @@ +.\" $OpenBSD: CRYPTO_set_ex_data.3,v 1.15 2023/09/18 14:49:43 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 18 2023 $ +.Dt CRYPTO_SET_EX_DATA 3 +.Os +.Sh NAME +.Nm CRYPTO_get_ex_new_index , +.Nm CRYPTO_EX_new , +.Nm CRYPTO_EX_free , +.Nm CRYPTO_EX_dup , +.Nm CRYPTO_new_ex_data , +.Nm CRYPTO_set_ex_data , +.Nm CRYPTO_get_ex_data , +.Nm CRYPTO_free_ex_data +.Nd low-level functions for application specific data +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft int +.Fo CRYPTO_get_ex_new_index +.Fa "int class_index" +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft typedef int +.Fo CRYPTO_EX_new +.Fa "void *parent" +.Fa "void *data" +.Fa "CRYPTO_EX_DATA *ad" +.Fa "int idx" +.Fa "long argl" +.Fa "void *argp" +.Fc +.Ft typedef void +.Fo CRYPTO_EX_free +.Fa "void *parent" +.Fa "void *data" +.Fa "CRYPTO_EX_DATA *ad" +.Fa "int idx" +.Fa "long argl" +.Fa "void *argp" +.Fc +.Ft typedef int +.Fo CRYPTO_EX_dup +.Fa "CRYPTO_EX_DATA *to" +.Fa "const CRYPTO_EX_DATA *from" +.Fa "void *datap" +.Fa "int idx" +.Fa "long argl" +.Fa "void *argp" +.Fc +.Ft int +.Fo CRYPTO_new_ex_data +.Fa "int class_index" +.Fa "void *parent" +.Fa "CRYPTO_EX_DATA *ad" +.Fc +.Ft int +.Fo CRYPTO_set_ex_data +.Fa "CRYPTO_EX_DATA *ad" +.Fa "int idx" +.Fa "void *data" +.Fc +.Ft void * +.Fo CRYPTO_get_ex_data +.Fa "CRYPTO_EX_DATA *ad" +.Fa "int idx" +.Fc +.Ft void +.Fo CRYPTO_free_ex_data +.Fa "int class_index" +.Fa "void *parent" +.Fa "CRYPTO_EX_DATA *ad" +.Fc +.Sh DESCRIPTION +The library implements the functions documented in the +.Xr RSA_get_ex_new_index 3 +manual page and similar functions for other parent object types +using the functions documented in the present manual page. +Application programs almost never need +to call the functions documented here directly. +.Pp +.Fn CRYPTO_get_ex_new_index +behaves in the same way as +.Xr RSA_get_ex_new_index 3 +except that the parent object type that the new +.Fa idx +is reserved for is not part of the function name +but instead specified by the additional +.Fa class_index +argument receiving one of the +.Dv CRYPTO_EX_INDEX_* +constants defined in +.In openssl/crypto.h . +The recommendation given in +.Xr RSA_get_ex_new_index 3 +to set the +.Fa argl +argument to 0 and the last four arguments all to +.Dv NULL +applies. +The library passes the +.Fa argl +and +.Fa argp +arguments through to the callback functions for the respective +.Fa idx , +but ignores them otherwise. +.Pp +If a function pointer is passed for the +.Fa new_func +argument, that function is called for the returned +.Fa idx +whenever a new parent object is allocated with +.Xr RSA_new 3 +or a similar function. +.Pp +If a function pointer is passed for the +.Fa free_func +argument, that function is called for the returned +.Fa idx +when a parent object is freed with +.Xr RSA_free 3 +or a similar function. +.Pp +The arguments of +.Fa new_func +and +.Fa free_func +are as follows: +.Pp +.Bl -tag -width Ds -compact +.It Fa parent +the parent object that contains the +.Fa data +.It Fa data +the +.Fa data +previously set by +.Fn CRYPTO_set_ex_data +at +.Fa idx +in +.Fa parent +.It Fa ad +the +.Vt CRYPTO_EX_DATA +subobject of the +.Fa parent +object +.It Fa idx +return value of +.Fn CRYPTO_get_ex_new_index +that set this callback +.It Fa argl +the +.Fa argl +passed to +.Fn CRYPTO_get_ex_new_index +for this +.Fa idx +.It Fa argp +the +.Fa argp +passed to +.Fn CRYPTO_get_ex_new_index +for this +.Fa idx +.El +.Pp +If a function pointer is passed for the +.Fa dup_func , +that function is supposed to be called for the returned +.Fa idx +whenever a parent object of the respective type is copied. +Actually, the only functions doing that are +.Xr BIO_dup_chain 3 , +.Xr EC_KEY_copy 3 , +and +.Xr SSL_dup 3 , +and the TLS 1.3 network stack does it internally when duplicating a +.Vt SSL_SESSION +object after receiving a new session ticket message. +Most other object types supporting ex_data do not support +copying in the first place, whereas +.Xr DSA_dup_DH 3 +and +.Xr X509_dup 3 +simply ignore +.Fa dup_func . +.Pp +The arguments of +.Fa dup_func +are as follows: +.Pp +.Bl -tag -width Ds -compact +.It Fa to +the +.Vt CRYPTO_EX_DATA +subobject of the new parent object +.It Fa from +the +.Vt CRYPTO_EX_DATA +subobject of the original parent object +.It Fa datap +a pointer to a copy of the pointer to the original ex_data +.It Fa idx +return value of +.Fn CRYPTO_get_ex_new_index +that set this callback +.It Fa argl +the +.Fa argl +passed to +.Fn CRYPTO_get_ex_new_index +for this +.Fa idx +.It Fa argp +the +.Fa argp +passed to +.Fn CRYPTO_get_ex_new_index +for this +.Fa idx +.El +.Pp +Inside +.Fa dup_func , +the +.Fa data +pointer contained in the original parent object being copied +can be accessed by casting and dereferencing +.Fa datap , +for example: +.Pp +.Dl char *orig_data = *(char **)datap; +.Pp +If the original data is copied, for example in a manner similar to +.Bd -literal -offset indent +char *new_data; +if ((new_data = strdup(orig_data)) == NULL) + return 0; +.Ed +.Pp +then the pointer to the newly allocated memory needs to be passed +back to the caller in the +.Fa datap +argument, for example: +.Bd -literal -offset indent +*(char **)datap = new_data; +return 1; +.Ed +.Pp +Calling +.Fn CRYPTO_set_ex_data to idx new_data +from inside +.Fa dup_func +has no effect because the code calling +.Fa dup_func +unconditionally calls +.Fn CRYPTO_set_ex_data to idx *datap +after +.Fa dup_func +returns successfully. +Consequently, if +.Fa dup_func +does not change +.Pf * Fa datap , +the new parent object ends up containing a pointer to the same memory +as the original parent object and any memory allocated in +.Fa dup_func +is leaked. +.Pp +When multiple callback functions are called, +they are called in increasing order of their +.Fa idx +value. +.Pp +.Fn CRYPTO_new_ex_data +is an internal function that initializes the +.Fa ad +subobject of the +.Fa parent +object, with the type of the parent object specified by the +.Fa class_index +argument. +Initialization includes calling the respective +.Fa new_func +callbacks for all reserved +.Fa idx +values that have such callbacks configured. +Despite its name, +.Fn CRYPTO_new_ex_data +does not create a new object but requires that +.Fa ad +points to an already allocated but still uninitialized object. +.Pp +.Fn CRYPTO_set_ex_data +and +.Fn CRYPTO_get_ex_data +behave in the same way as +.Xr RSA_set_ex_data 3 +and +.Xr RSA_get_ex_data 3 , +respectively, except that they do not accept a pointer +to the parent object but instead require a pointer to the +.Vt CRYPTO_EX_DATA +subobject of that parent object. +.Pp +.Fn CRYPTO_free_ex_data +is an internal function that frees any memory used inside the +.Fa ad +subobject of the +.Fa parent +object, with the type of the parent object specified by the +.Fa class_index +argument. +This includes calling the respective +.Fa free_func +callbacks for all reserved +.Fa idx +values that have such callbacks configured. +Despite its name, +.Fn CRYPTO_free_ex_data +does not free +.Fa ad +itself. +.Sh RETURN VALUES +.Fn CRYPTO_get_ex_new_index +returns a new index equal to or greater than 1 +or \-1 if memory allocation fails. +.Pp +.Fn CRYPTO_EX_new +and +.Fn CRYPTO_EX_dup +functions are supposed to return 1 on success or 0 on failure. +.Pp +.Fn CRYPTO_new_ex_data +and +.Fn CRYPTO_set_ex_data +return 1 on success or 0 if memory allocation fails. +.Pp +.Fn CRYPTO_get_ex_data +returns the application specific data or +.Dv NULL +if the parent object that contains +.Fa ad +does not contain application specific data at the given +.Fa idx . +.Sh ERRORS +After failure of +.Fn CRYPTO_get_ex_new_index , +.Fn CRYPTO_new_ex_data , +or +.Fn CRYPTO_set_ex_data , +the following diagnostic can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +Memory allocation failed. +.El +.Pp +In a few unusual failure cases, +.Xr ERR_get_error 3 +may report different errors caused by +.Xr OPENSSL_init_crypto 3 +or even none at all. +.Pp +Even though it cannot indicate failure, +.Fn CRYPTO_free_ex_data +may occasionally also set an error code that can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn CRYPTO_get_ex_data +does not distinguish success from failure. +Consequently, after +.Fn CRYPTO_get_ex_data +returns +.Dv NULL , +.Xr ERR_get_error 3 +returns 0 unless there is still an earlier error in the queue. +.Sh SEE ALSO +.Xr BIO_get_ex_new_index 3 , +.Xr DH_get_ex_new_index 3 , +.Xr DSA_get_ex_new_index 3 , +.Xr RSA_get_ex_new_index 3 , +.Xr SSL_CTX_get_ex_new_index 3 , +.Xr SSL_get_ex_new_index 3 , +.Xr SSL_SESSION_get_ex_new_index 3 , +.Xr X509_STORE_CTX_get_ex_new_index 3 , +.Xr X509_STORE_get_ex_new_index 3 +.Sh HISTORY +.Fn CRYPTO_get_ex_new_index , +.Fn CRYPTO_new_ex_data , +.Fn CRYPTO_set_ex_data , +.Fn CRYPTO_get_ex_data , +and +.Fn CRYPTO_free_ex_data +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . +.Pp +.Fn CRYPTO_EX_new , +.Fn CRYPTO_EX_free , +and +.Fn CRYPTO_EX_dup +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Sh CAVEATS +If an program installs callback functions, the last call to +.Fn CRYPTO_get_ex_new_index +installing a function of a certain type for a certain +.Fa class_index +needs to be complete before the first object of that +.Fa class_index +can be created, freed, or copied, respectively. +Otherwise, incomplete initialization or cleanup will result. +.Pp +At the time +.Fa new_func +is called, the +.Fa parent +object is only partially initialized, +so trying to access any data in it is strongly discouraged. +The +.Fa data +argument is typically +.Dv NULL +in +.Fa new_func . +.Pp +At the time +.Fa free_func +is called, the +.Fa parent +object is already mostly deconstructed +and part of its content may have been cleared and freed. +Consequently, trying to access any data in +.Fa parent +is strongly discouraged. +According to the OpenSSL API documentation, the library code calling +.Fa free_func +would even be permitted to pass a +.Dv NULL +pointer for the +.Fa parent +argument. +.Pp +.Fn CRYPTO_set_ex_data +and +.Fn CRYPTO_get_ex_data +cannot reasonably be used outside the callback functions +because no API function provides access to any pointers of the type +.Vt CRYPTO_EX_DATA * . +.Pp +Inside +.Fa new_func , +calling +.Fn CRYPTO_get_ex_data +makes no sense because it always returns +.Dv NULL , +and calling +.Fn CRYPTO_set_ex_data +makes no sense because +.Fa new_func +does not have access to any meaningful +.Fa data +it could store, and the absence of application specific data at any given +.Fa idx +is already sufficiently indicated by the default return value +.Dv NULL +of +.Fn CRYPTO_get_ex_data , +.Xr RSA_get_ex_data 3 , +and similar functions. +.Pp +Inside +.Fa free_func , +calling +.Fn CRYPTO_get_ex_data +makes no sense because the return value is already available in +.Fa data , +and calling +.Fn CRYPTO_set_ex_data +makes no sense because the parent object, including any ex_data +contained in it, is already being deconstructed and will no longer +exist by the time application code regains control. +.Pp +Inside +.Fa dup_func , +calling +.Fn CRYPTO_get_ex_data +makes no sense because the return value for +.Fa from +is already available as +.Pf * Fa datap , +and the return value for +.Fa to +is +.Dv NULL . +Calling +.Fn CRYPTO_set_ex_data +makes no sense because changing +.Fa from +would cause an undesirable side effect in this context +and trying to change +.Fa to +is ineffective as explained above. +.Pp +Consequently, application code can never use +.Fn CRYPTO_set_ex_data +or +.Fn CRYPTO_get_ex_data +in a meaningful way. +.Pp +The fact that the functions documented in the present manual page +are part of the public API might create the impression +that application programs could add ex_data support +to additional object types not offering it by default. +However, for built-in object types not offering ex_support, this +is not possible because such objects do not contain the required +.Vt CRYPTO_EX_DATA +subobject. +.Pp +It is theoretically possible to add ex_data support to an +application-defined object type by adding a +.Vt CRYPTO_EX_DATA +field to the struct declaration, a call to +.Fn CRYPTO_new_ex_data +to the object constructor, and a call to +.Fn CRYPTO_free_ex_data +to the object destructor. +The OpenSSL documentation mentions that the constant +.Dv CRYPTO_EX_INDEX_APP +is reserved for this very purpose. +However, doing this would hardly be useful. +It is much more straightforward to just add +all the required data fields to the struct declaration itself. +.Sh BUGS +If +.Fa new_func +or +.Fa dup_func +fails, the failure is silently ignored by the library, potentially +resulting in an incompletely initialized object. +The application program cannot detect this kind of failure. diff --git a/Libraries/libressl/man/ChaCha.3 b/Libraries/libressl/man/ChaCha.3 new file mode 100644 index 000000000..9aae6d70c --- /dev/null +++ b/Libraries/libressl/man/ChaCha.3 @@ -0,0 +1,253 @@ +.\" $OpenBSD: ChaCha.3,v 1.3 2022/02/18 10:24:32 jsg Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 18 2022 $ +.Dt CHACHA 3 +.Os +.Sh NAME +.Nm ChaCha_set_key , +.Nm ChaCha_set_iv , +.Nm ChaCha , +.Nm CRYPTO_chacha_20 , +.Nm CRYPTO_hchacha_20 , +.Nm CRYPTO_xchacha_20 +.Nd ChaCha20 stream cipher +.Sh SYNOPSIS +.In openssl/chacha.h +.Ft void +.Fo ChaCha_set_key +.Fa "ChaCha_ctx *ctx" +.Fa "const unsigned char *key" +.Fa "unsigned int keybits" +.Fc +.Ft void +.Fo ChaCha_set_iv +.Fa "ChaCha_ctx *ctx" +.Fa "const unsigned char *iv" +.Fa "const unsigned char *counter" +.Fc +.Ft void +.Fo ChaCha +.Fa "ChaCha_ctx *ctx" +.Fa "unsigned char *out" +.Fa "const unsigned char *in" +.Fa "size_t len" +.Fc +.Ft void +.Fo CRYPTO_chacha_20 +.Fa "unsigned char *out" +.Fa "const unsigned char *in" +.Fa "size_t len" +.Fa "const unsigned char key[32]" +.Fa "const unsigned char iv[8]" +.Fa "uint64_t counter" +.Fc +.Ft void +.Fo CRYPTO_hchacha_20 +.Fa "unsigned char out[32]" +.Fa "const unsigned char key[32]" +.Fa "const unsigned char iv[16]" +.Fc +.Ft void +.Fo CRYPTO_xchacha_20 +.Fa "unsigned char *out" +.Fa "const unsigned char *in" +.Fa "size_t len" +.Fa "const unsigned char key[32]" +.Fa "const unsigned char iv[24]" +.Fc +.Sh DESCRIPTION +These functions provide a low-level implementation +of the ChaCha stream cipher with 256 and 128-bit keys. +The number of rounds is hardcoded to 20; +variants with 8 or 12 rounds are not supported. +.Pp +Instead of using these functions directly, +application programs normally use the more portable +.Xr EVP_chacha20 3 +high-level interface. +.Pp +The ChaCha state is contained in the +.Vt ChaCha_ctx +structure and consists of sixteen 32-bit unsigned integers. +.Pp +For the recommended value of 256 +.Fa keybits , +.Fn ChaCha_set_key +copies 32 bytes (256 bits) from +.Fa key +to the middle eight integers of the ChaCha state, +using little endian order for each integer. +For the alternative value of 128 +.Fa keybits , +only 16 bytes (128 bits) are copied from +.Fa key +to the ChaCha state, but they are copied twice, +once to the second quarter and once to the third quarter. +The first quarter of the ChaCha state is set to four constant integers; +these constants differ depending on whether +.Fa keybits +is 128 or 256. +The last quarter of the ChaCha state remains unchanged. +.Pp +.Fn ChaCha_set_iv +copies eight bytes (64 bits) from +.Fa counter +and eight bytes (64 bits) from +.Fa iv +to the last quarter of the ChaCha state, the counter to the first +two integers and the initialization vector to the last two integers, +again in little endian order. +If +.Fa counter +is +.Dv NULL , +the two respective integers are set to 0 instead. +The first three quarters of the ChaCha state remain unchanged. +.Pp +.Fn ChaCha +encrypts +.Fa len +bytes of data from +.Fa in +to +.Fa out +using the +.Fa ctx +that was previously set up with +.Fn ChaCha_set_key +and +.Fn ChaCha_set_iv . +Providing an +.Fa out +buffer of at least +.Fa len +bytes is the responsibility of the caller. +This function can be called multiple times in a row with varying +.Fa len +arguments. +The +.Fa len +does not need to be a multiple of 64. +.Pp +.Fn CRYPTO_chacha_20 +encrypts +.Fa len +bytes of data from +.Fa in +to +.Fa out +in a one-shot operation, using the given +.Fa key +and +.Fa iv +as described for +.Fn ChaCha_set_key +and +.Fn ChaCha_set_iv +and copying the less significant half of +.Fa counter +to the first counter integer in the initial ChaCha state +and the more significant half to the second integer. +Providing an +.Fa out +buffer of at least +.Fa len +bytes is again the responsibility of the caller. +The maximum supported value for +.Fa len +is 2^32 \- 1. +.Pp +XChaCha is a variant of ChaCha designed to support longer nonces, +just like XSalsa20 is a variant of Salsa20 supporting longer nonces. +.Pp +.Fn CRYPTO_xchacha_20 +encrypts +.Fa len +bytes of data from +.Fa in +to +.Fa out +in a one-shot operation with the XChaCha algorithm, using the given +.Fa key +and +.Fa iv . +It is equivalent to +.Fn CRYPTO_chacha_20 +with the last third of +.Fa iv , +a +.Fa counter +of 0, and a key generated with +.Fn CRYPTO_hchacha_20 +from the first two thirds of +.Fa iv . +.Sh SEE ALSO +.Xr crypto 3 , +.Xr EVP_chacha20 3 +.Rs +.%A Daniel J. Bernstein +.%T ChaCha, a variant of Salsa20 +.%U https://cr.yp.to/chacha/chacha-20080128.pdf +.%C Chicago +.%D January 28, 2008 +.Re +.Rs +.%A Daniel J. Bernstein +.%T Extending the Salsa20 nonce +.%U https://cr.yp.to/snuffle/xsalsa-20110204.pdf +.%C Chicago +.%D August 22, 2017 +.Re +.Sh STANDARDS +RFC 8439: ChaCha20 and Poly1305 for IETF Protocols +.Pp +Note that the standard specifies +a 32-bit counter and a 96-bit initialization vector whereas +this implementation follows Bernstein's original specification +and uses a 64-bit counter and a 64-bit initialization vector. +.Pp +These functions are specific to LibreSSL and not provided by OpenSSL. +BoringSSL does provide +.Fn CRYPTO_chacha_20 , +but with an incompatible interface, taking a 96-bit +.Fa iv +and a 32-bit +.Fa counter . +.Sh HISTORY +.Fn ChaCha_set_key , +.Fn ChaCha_set_iv , +.Fn ChaCha , +and +.Fn CRYPTO_chacha_20 +first appeared in +.Ox 5.6 . +.\" Committed on May 1, 2014. +.\" BoringSSL added CRYPTO_chacha_20 on June 20, 2014. +.Pp +.Fn CRYPTO_hchacha_20 +and +.Fn CRYPTO_xchacha_20 +first appeared in +.Ox 6.5 . +.Sh AUTHORS +.An -nosplit +This implementation was written by +.An Daniel J. Bernstein Aq Mt djb@cr.yp.to . +The API layer was added by +.An Joel Sing Aq Mt jsing@openbsd.org +for ChaCha, and for XChaCha by +.An David Gwynne Aq Mt dlg@openbsd.org . diff --git a/Libraries/libressl/man/DES_set_key.3 b/Libraries/libressl/man/DES_set_key.3 new file mode 100644 index 000000000..e74c7c5e4 --- /dev/null +++ b/Libraries/libressl/man/DES_set_key.3 @@ -0,0 +1,870 @@ +.\" $OpenBSD: DES_set_key.3,v 1.15 2022/03/31 17:27:16 naddy Exp $ +.\" full merge up to: +.\" OpenSSL man3/DES_random_key 521738e9 Oct 5 14:58:30 2018 -0400 +.\" +.\" -------------------------------------------------------------------------- +.\" Major patches to this file were contributed by +.\" Ulf Moeller , Ben Laurie , +.\" and Richard Levitte . +.\" -------------------------------------------------------------------------- +.\" Copyright (c) 2000, 2001, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" -------------------------------------------------------------------------- +.\" Parts of this file are derived from SSLeay documentation, +.\" which is covered by the following Copyright and license: +.\" -------------------------------------------------------------------------- +.\" +.\" Copyright (C) 1995-1998 Tim Hudson (tjh@cryptsoft.com) +.\" All rights reserved. +.\" +.\" This package is an SSL implementation written +.\" by Eric Young (eay@cryptsoft.com). +.\" The implementation was written so as to conform with Netscapes SSL. +.\" +.\" This library is free for commercial and non-commercial use as long as +.\" the following conditions are aheared to. The following conditions +.\" apply to all code found in this distribution, be it the RC4, RSA, +.\" lhash, DES, etc., code; not just the SSL code. The SSL documentation +.\" included with this distribution is covered by the same copyright terms +.\" except that the holder is Tim Hudson (tjh@cryptsoft.com). +.\" +.\" Copyright remains Eric Young's, and as such any Copyright notices in +.\" the code are not to be removed. +.\" If this package is used in a product, Eric Young should be given +.\" attribution as the author of the parts of the library used. +.\" This can be in the form of a textual message at program startup or +.\" in documentation (online or textual) provided with the package. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" "This product includes cryptographic software written by +.\" Eric Young (eay@cryptsoft.com)" +.\" The word 'cryptographic' can be left out if the rouines from the +.\" library being used are not cryptographic related :-). +.\" 4. If you include any Windows specific code (or a derivative thereof) +.\" from the apps directory (application code) you must include an +.\" acknowledgement: "This product includes software written by +.\" Tim Hudson (tjh@cryptsoft.com)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" The licence and distribution terms for any publically available version or +.\" derivative of this code cannot be changed. i.e. this code cannot simply be +.\" copied and put under another distribution licence +.\" [including the GNU Public Licence.] +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt DES_SET_KEY 3 +.Os +.Sh NAME +.Nm DES_random_key , +.Nm DES_set_key , +.Nm DES_key_sched , +.Nm DES_set_key_checked , +.Nm DES_set_key_unchecked , +.Nm DES_set_odd_parity , +.Nm DES_is_weak_key , +.Nm DES_ecb_encrypt , +.Nm DES_ecb2_encrypt , +.Nm DES_ecb3_encrypt , +.Nm DES_ncbc_encrypt , +.Nm DES_cfb_encrypt , +.Nm DES_ofb_encrypt , +.Nm DES_pcbc_encrypt , +.Nm DES_cfb64_encrypt , +.Nm DES_ofb64_encrypt , +.Nm DES_xcbc_encrypt , +.Nm DES_ede2_cbc_encrypt , +.Nm DES_ede2_cfb64_encrypt , +.Nm DES_ede2_ofb64_encrypt , +.Nm DES_ede3_cbc_encrypt , +.Nm DES_ede3_cbcm_encrypt , +.Nm DES_ede3_cfb64_encrypt , +.Nm DES_ede3_ofb64_encrypt , +.Nm DES_cbc_cksum , +.Nm DES_quad_cksum , +.Nm DES_string_to_key , +.Nm DES_string_to_2keys , +.Nm DES_fcrypt , +.Nm DES_crypt , +.Nm DES_enc_read , +.Nm DES_enc_write +.Nd DES encryption +.Sh SYNOPSIS +.In openssl/des.h +.Ft void +.Fo DES_random_key +.Fa "DES_cblock *ret" +.Fc +.Ft int +.Fo DES_set_key +.Fa "const_DES_cblock *key" +.Fa "DES_key_schedule *schedule" +.Fc +.Ft int +.Fo DES_key_sched +.Fa "const_DES_cblock *key" +.Fa "DES_key_schedule *schedule" +.Fc +.Ft int +.Fo DES_set_key_checked +.Fa "const_DES_cblock *key" +.Fa "DES_key_schedule *schedule" +.Fc +.Ft void +.Fo DES_set_key_unchecked +.Fa "const_DES_cblock *key" +.Fa "DES_key_schedule *schedule" +.Fc +.Ft void +.Fo DES_set_odd_parity +.Fa "DES_cblock *key" +.Fc +.Ft int +.Fo DES_is_weak_key +.Fa "const_DES_cblock *key" +.Fc +.Ft void +.Fo DES_ecb_encrypt +.Fa "const_DES_cblock *input" +.Fa "DES_cblock *output" +.Fa "DES_key_schedule *ks" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ecb2_encrypt +.Fa "const_DES_cblock *input" +.Fa "DES_cblock *output" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ecb3_encrypt +.Fa "const_DES_cblock *input" +.Fa "DES_cblock *output" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_key_schedule *ks3" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ncbc_encrypt +.Fa "const unsigned char *input" +.Fa "unsigned char *output" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_cfb_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "int numbits" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ofb_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "int numbits" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fc +.Ft void +.Fo DES_pcbc_encrypt +.Fa "const unsigned char *input" +.Fa "unsigned char *output" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_cfb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fa "int *num" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ofb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fa "int *num" +.Fc +.Ft void +.Fo DES_xcbc_encrypt +.Fa "const unsigned char *input" +.Fa "unsigned char *output" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "DES_cblock *ivec" +.Fa "const_DES_cblock *inw" +.Fa "const_DES_cblock *outw" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ede2_cbc_encrypt +.Fa "const unsigned char *input" +.Fa "unsigned char *output" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_cblock *ivec" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ede2_cfb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_cblock *ivec" +.Fa "int *num" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ede2_ofb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_cblock *ivec" +.Fa "int *num" +.Fc +.Ft void +.Fo DES_ede3_cbc_encrypt +.Fa "const unsigned char *input" +.Fa "unsigned char *output" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_key_schedule *ks3" +.Fa "DES_cblock *ivec" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ede3_cbcm_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_key_schedule *ks3" +.Fa "DES_cblock *ivec1" +.Fa "DES_cblock *ivec2" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ede3_cfb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_key_schedule *ks3" +.Fa "DES_cblock *ivec" +.Fa "int *num" +.Fa "int enc" +.Fc +.Ft void +.Fo DES_ede3_ofb64_encrypt +.Fa "const unsigned char *in" +.Fa "unsigned char *out" +.Fa "long length" +.Fa "DES_key_schedule *ks1" +.Fa "DES_key_schedule *ks2" +.Fa "DES_key_schedule *ks3" +.Fa "DES_cblock *ivec" +.Fa "int *num" +.Fc +.Ft DES_LONG +.Fo DES_cbc_cksum +.Fa "const unsigned char *input" +.Fa "DES_cblock *output" +.Fa "long length" +.Fa "DES_key_schedule *schedule" +.Fa "const_DES_cblock *ivec" +.Fc +.Ft DES_LONG +.Fo DES_quad_cksum +.Fa "const unsigned char *input" +.Fa "DES_cblock output[]" +.Fa "long length" +.Fa "int out_count" +.Fa "DES_cblock *seed" +.Fc +.Ft void +.Fo DES_string_to_key +.Fa "const char *str" +.Fa "DES_cblock *key" +.Fc +.Ft void +.Fo DES_string_to_2keys +.Fa "const char *str" +.Fa "DES_cblock *key1" +.Fa "DES_cblock *key2" +.Fc +.Ft char * +.Fo DES_fcrypt +.Fa "const char *buf" +.Fa "const char *salt" +.Fa "char *ret" +.Fc +.Ft char * +.Fo DES_crypt +.Fa "const char *buf" +.Fa "const char *salt" +.Fc +.Ft int +.Fo DES_enc_read +.Fa "int fd" +.Fa "void *buf" +.Fa "int len" +.Fa "DES_key_schedule *sched" +.Fa "DES_cblock *iv" +.Fc +.Ft int +.Fo DES_enc_write +.Fa "int fd" +.Fa "const void *buf" +.Fa "int len" +.Fa "DES_key_schedule *sched" +.Fa "DES_cblock *iv" +.Fc +.Sh DESCRIPTION +This library contains a fast implementation of the DES encryption +algorithm. +.Pp +There are two phases to the use of DES encryption. +The first is the generation of a +.Vt DES_key_schedule +from a key, and the second is the actual encryption. +A DES key is of type +.Vt DES_cblock . +This type consists of 8 bytes with odd parity. +The least significant bit in each byte is the parity bit. +The key schedule is an expanded form of the key; it is used to speed the +encryption process. +.Pp +.Fn DES_random_key +generates a random key in odd parity. +.Pp +Before a DES key can be used, it must be converted into the architecture +dependent +.Vt DES_key_schedule +via the +.Fn DES_set_key_checked +or +.Fn DES_set_key_unchecked +function. +.Pp +.Fn DES_set_key_checked +will check that the key passed is of odd parity and is not a weak or +semi-weak key. +If the parity is wrong, then -1 is returned. +If the key is a weak key, then -2 is returned. +If an error is returned, the key schedule is not generated. +.Pp +.Fn DES_set_key +works like +.Fn DES_set_key_checked +if the +.Em DES_check_key +flag is non-zero, otherwise like +.Fn DES_set_key_unchecked . +These functions are available for compatibility; it is recommended to +use a function that does not depend on a global variable. +.Pp +.Fn DES_set_odd_parity +sets the parity of the passed +.Fa key +to odd. +.Pp +The following routines mostly operate on an input and output stream of +.Vt DES_cblock Ns s . +.Pp +.Fn DES_ecb_encrypt +is the basic DES encryption routine that encrypts or decrypts a single +8-byte +.Vt DES_cblock +in electronic code book (ECB) mode. +It always transforms the input data, pointed to by +.Fa input , +into the output data, pointed to by the +.Fa output +argument. +If the +.Fa enc +argument is non-zero +.Pq Dv DES_ENCRYPT , +the +.Fa input +(cleartext) is encrypted into the +.Fa output +(ciphertext) using the key_schedule specified by the +.Fa schedule +argument, previously set via +.Fn DES_set_key . +If +.Fa enc +is zero +.Pq Dv DES_DECRYPT , +the +.Fa input +(now ciphertext) is decrypted into the +.Fa output +(now cleartext). +Input and output may overlap. +.Fn DES_ecb_encrypt +does not return a value. +.Pp +.Fn DES_ecb3_encrypt +encrypts/decrypts the +.Fa input +block by using three-key Triple-DES encryption in ECB mode. +This involves encrypting the input with +.Fa ks1 , +decrypting with the key schedule +.Fa ks2 , +and then encrypting with +.Fa ks3 . +This routine greatly reduces the chances of brute force breaking of DES +and has the advantage of if +.Fa ks1 , +.Fa ks2 , +and +.Fa ks3 +are the same, it is equivalent to just encryption using ECB mode and +.Fa ks1 +as the key. +.Pp +The macro +.Fn DES_ecb2_encrypt +is provided to perform two-key Triple-DES encryption by using +.Fa ks1 +for the final encryption. +.Pp +.Fn DES_ncbc_encrypt +encrypts/decrypts using the cipher-block-chaining (CBC) mode of DES. +If the +.Fa enc +argument is non-zero, the routine cipher-block-chain encrypts the +cleartext data pointed to by the +.Fa input +argument into the ciphertext pointed to by the +.Fa output +argument, using the key schedule provided by the +.Fa schedule +argument, and initialization vector provided by the +.Fa ivec +argument. +If the +.Fa length +argument is not an integral multiple of eight bytes, the last block is +copied to a temporary area and zero filled. +The output is always an integral multiple of eight bytes. +.Pp +.Fn DES_xcbc_encrypt +is RSA's DESX mode of DES. +It uses +.Fa inw +and +.Fa outw +to "whiten" the encryption. +.Fa inw +and +.Fa outw +are secret (unlike the iv) and are as such, part of the key. +So the key is sort of 24 bytes. +This is much better than CBC DES. +.Pp +.Fn DES_ede3_cbc_encrypt +implements outer triple CBC DES encryption with three keys. +This means that each DES operation inside the CBC mode is +.Qq Li C=E(ks3,D(ks2,E(ks1,M))) . +This mode is used by SSL. +.Pp +The +.Fn DES_ede2_cbc_encrypt +macro implements two-key Triple-DES by reusing +.Fa ks1 +for the final encryption. +.Qq Li C=E(ks1,D(ks2,E(ks1,M))) . +This form of Triple-DES is used by the RSAREF library. +.Pp +.Fn DES_pcbc_encrypt +encrypts/decrypts using the propagating cipher block chaining mode used +by Kerberos v4. +Its parameters are the same as +.Fn DES_ncbc_encrypt . +.Pp +.Fn DES_cfb_encrypt +encrypts/decrypts using cipher feedback mode. +This method takes an array of characters as input and outputs an array +of characters. +It does not require any padding to 8 character groups. +Note: the +.Fa ivec +variable is changed and the new changed value needs to be passed to the +next call to this function. +Since this function runs a complete DES ECB encryption per +.Fa numbits , +this function is only suggested for use when sending a small number of +characters. +.Pp +.Fn DES_cfb64_encrypt +implements CFB mode of DES with 64-bit feedback. +Why is this useful you ask? +Because this routine will allow you to encrypt an arbitrary number of +bytes, without 8 byte padding. +Each call to this routine will encrypt the input bytes to output and +then update ivec and num. +num contains "how far" we are though ivec. +If this does not make much sense, read more about CFB mode of DES. +.Pp +.Fn DES_ede3_cfb64_encrypt +and +.Fn DES_ede2_cfb64_encrypt +is the same as +.Fn DES_cfb64_encrypt +except that Triple-DES is used. +.Pp +.Fn DES_ofb_encrypt +encrypts using output feedback mode. +This method takes an array of characters as input and outputs an array +of characters. +It does not require any padding to 8 character groups. +Note: the +.Fa ivec +variable is changed and the new changed value needs to be passed to the +next call to this function. +Since this function runs a complete DES ECB encryption per +.Fa numbits , +this function is only suggested for use when sending a small number +of characters. +.Pp +.Fn DES_ofb64_encrypt +is the same as +.Fn DES_cfb64_encrypt +using Output Feed Back mode. +.Pp +.Fn DES_ede3_ofb64_encrypt +and +.Fn DES_ede2_ofb64_encrypt +is the same as +.Fn DES_ofb64_encrypt , +using Triple-DES. +.Pp +The following functions are included in the DES library for +compatibility with the MIT Kerberos library. +.Pp +.Fn DES_cbc_cksum +produces an 8-byte checksum based on the input stream (via CBC +encryption). +The last 4 bytes of the checksum are returned and the complete 8 bytes +are placed in +.Fa output . +This function is used by Kerberos v4. +Other applications should use +.Xr EVP_DigestInit 3 +etc. instead. +.Pp +.Fn DES_quad_cksum +is a Kerberos v4 function. +It returns a 4-byte checksum from the input bytes. +The algorithm can be iterated over the input, depending on +.Fa out_count , +1, 2, 3 or 4 times. +If +.Fa output +is +.Pf non- Dv NULL , +the 8 bytes generated by each pass are written into +.Fa output . +.Pp +The following are DES-based transformations: +.Pp +.Fn DES_fcrypt +is a fast version of the Unix +.Xr crypt 3 +function. +The +.Fa salt +must be two ASCII characters. +This version is different from the normal crypt in that the third +parameter is the buffer that the return value is written into. +It needs to be at least 14 bytes long. +The fourteenth byte is set to NUL. +This version takes only a small amount of space relative to other +fast crypt implementations. +It is thread safe, unlike the normal crypt. +.Pp +.Fn DES_crypt +is a faster replacement for the normal system +.Xr crypt 3 . +This function calls +.Fn DES_fcrypt +with a static array passed as the third parameter. +This emulates the normal non-thread safe semantics of +.Xr crypt 3 . +.Pp +.Fn DES_enc_write +writes +.Fa len +bytes to file descriptor +.Fa fd +from buffer +.Fa buf . +The data is encrypted via +.Em pcbc_encrypt +(default) using +.Fa sched +for the key and +.Fa iv +as a starting vector. +The actual data send down +.Fa fd +consists of 4 bytes (in network byte order) containing the length of the +following encrypted data. +The encrypted data then follows, padded with random data out to a +multiple of 8 bytes. +.Pp +.Fn DES_enc_read +is used to read +.Fa len +bytes from file descriptor +.Fa fd +into buffer +.Fa buf . +The data being read from +.Fa fd +is assumed to have come from +.Fn DES_enc_write +and is decrypted using +.Fa sched +for the key schedule and +.Fa iv +for the initial vector. +.Pp +.Sy Warning : +The data format used by +.Fn DES_enc_write +and +.Fn DES_enc_read +has a cryptographic weakness: when asked to write more than +.Dv MAXWRITE +bytes, +.Fn DES_enc_write +will split the data into several chunks that are all encrypted using the +same IV. +So don't use these functions unless you are sure you know what +you do (in which case you might not want to use them anyway). +They cannot handle non-blocking sockets. +.Fn DES_enc_read +uses an internal state and thus cannot be used on multiple files. +.Pp +.Em DES_rw_mode +is used to specify the encryption mode to use with +.Fn DES_enc_read . +If set to +.Dv DES_PCBC_MODE +(the default), DES_pcbc_encrypt is used. +If set to +.Dv DES_CBC_MODE , +DES_cbc_encrypt is used. +.Sh RETURN VALUES +.Fn DES_set_key , +.Fn DES_key_sched , +and +.Fn DES_set_key_checked +return 0 on success or a negative value on error. +.Pp +.Fn DES_is_weak_key +returns 1 if the passed key is a weak key or 0 if it is ok. +.Pp +.Fn DES_cbc_cksum +and +.Fn DES_quad_cksum +return a 4-byte integer representing the last 4 bytes of the checksum +of the input. +.Pp +.Fn DES_fcrypt +returns a pointer to the caller-provided buffer +.Fa ret , +and +.Fn DES_crypt +returns a pointer to a static buffer. +Both are allowed to return +.Dv NULL +to indicate failure, but currently, they cannot fail. +.Sh SEE ALSO +.Xr crypt 3 , +.Xr EVP_des_cbc 3 , +.Xr EVP_EncryptInit 3 +.Sh STANDARDS +ANSI X3.106 +.Pp +The DES library was initially written to be source code compatible +with the MIT Kerberos library. +.Sh HISTORY +.Fn DES_random_key , +.Fn DES_set_key , +.Fn DES_key_sched , +.Fn DES_set_odd_parity , +.Fn DES_is_weak_key , +.Fn DES_ecb_encrypt , +.Fn DES_cfb_encrypt , +.Fn DES_ofb_encrypt , +.Fn DES_pcbc_encrypt , +.Fn DES_cfb64_encrypt , +.Fn DES_ofb64_encrypt , +.Fn DES_ede3_cbc_encrypt , +.Fn DES_cbc_cksum , +.Fn DES_quad_cksum , +.Fn DES_string_to_key , +.Fn DES_string_to_2keys , +.Fn DES_crypt , +.Fn DES_enc_read , +and +.Fn DES_enc_write +appeared in SSLeay 0.4 or earlier. +.Fn DES_ncbc_encrypt +first appeared in SSLeay 0.4.2. +.Fn DES_ede2_cbc_encrypt +first appeared in SSLeay 0.4.4. +.Fn DES_ecb2_encrypt , +.Fn DES_ecb3_encrypt , +.Fn DES_ede2_cfb64_encrypt , +.Fn DES_ede2_ofb64_encrypt , +.Fn DES_ede3_cfb64_encrypt , +and +.Fn DES_ede3_ofb64_encrypt +first appeared in SSLeay 0.5.1. +.Fn DES_xcbc_encrypt +first appeared in SSLeay 0.6.2. +.Fn DES_fcrypt +first appeared in SSLeay 0.6.5. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn DES_set_key_checked +and +.Fn DES_set_key_unchecked +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +In OpenSSL 0.9.7 and +.Ox 3.2 , +all +.Sy des_ +functions were renamed to +.Sy DES_ +to avoid clashes with older versions of libdes. +.Sh AUTHORS +.An Eric Young Aq Mt eay@cryptsoft.com +.Sh CAVEATS +Single-key DES is insecure due to its short key size. +ECB mode is not suitable for most applications. +.Sh BUGS +DES_cbc_encrypt does not modify +.Fa ivec ; +use +.Fn DES_ncbc_encrypt +instead. +.Pp +.Fn DES_cfb_encrypt +and +.Fn DES_ofb_encrypt +operates on input of 8 bits. +What this means is that if you set numbits to 12, and length to 2, the +first 12 bits will come from the 1st input byte and the low half of the +second input byte. +The second 12 bits will have the low 8 bits taken from the 3rd input +byte and the top 4 bits taken from the 4th input byte. +The same holds for output. +This function has been implemented this way because most people will be +using a multiple of 8 and because once you get into pulling input +bytes apart things get ugly! +.Pp +.Fn DES_string_to_key +is available for backward compatibility with the MIT library. +New applications should use a cryptographic hash function. +The same applies for +.Fn DES_string_to_2key . diff --git a/Libraries/libressl/man/DH_generate_key.3 b/Libraries/libressl/man/DH_generate_key.3 new file mode 100644 index 000000000..076b49f7a --- /dev/null +++ b/Libraries/libressl/man/DH_generate_key.3 @@ -0,0 +1,122 @@ +.\" $OpenBSD: DH_generate_key.3,v 1.12 2019/08/19 13:08:26 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 19 2019 $ +.Dt DH_GENERATE_KEY 3 +.Os +.Sh NAME +.Nm DH_generate_key , +.Nm DH_compute_key +.Nd perform Diffie-Hellman key exchange +.Sh SYNOPSIS +.In openssl/dh.h +.Ft int +.Fo DH_generate_key +.Fa "DH *dh" +.Fc +.Ft int +.Fo DH_compute_key +.Fa "unsigned char *key" +.Fa "BIGNUM *pub_key" +.Fa "DH *dh" +.Fc +.Sh DESCRIPTION +.Fn DH_generate_key +performs the first step of a Diffie-Hellman key exchange by generating +private and public DH values. +By calling +.Fn DH_compute_key , +these are combined with the other party's public value to compute the +shared key. +.Pp +.Fn DH_generate_key +expects +.Fa dh +to contain the shared parameters +.Sy dh->p +and +.Sy dh->g . +It generates a random private DH value unless +.Sy dh->priv_key +is already set, and computes the corresponding public value +.Sy dh->pub_key , +which can then be published. +.Pp +.Fn DH_compute_key +computes the shared secret from the private DH value in +.Fa dh +and the other party's public value in +.Fa pub_key +and stores it in +.Fa key . +.Fa key +must point to +.Fn DH_size dh +bytes of memory. +.Sh RETURN VALUES +.Fn DH_generate_key +returns 1 on success, or 0 otherwise. +.Pp +.Fn DH_compute_key +returns the size of the shared secret on success, or -1 on error. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr DH_get0_key 3 , +.Xr DH_new 3 , +.Xr DH_size 3 , +.Xr ECDH_compute_key 3 +.Sh HISTORY +.Fn DH_generate_key +and +.Fn DH_compute_key +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/DH_generate_parameters.3 b/Libraries/libressl/man/DH_generate_parameters.3 new file mode 100644 index 000000000..ac29521ec --- /dev/null +++ b/Libraries/libressl/man/DH_generate_parameters.3 @@ -0,0 +1,241 @@ +.\" $OpenBSD: DH_generate_parameters.3,v 1.14 2022/07/13 13:47:59 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" selective merge up to: OpenSSL b0edda11 Mar 20 13:00:17 2018 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller +.\" and Matt Caswell . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt DH_GENERATE_PARAMETERS 3 +.Os +.Sh NAME +.Nm DH_generate_parameters_ex , +.Nm DH_check , +.Nm DH_check_pub_key , +.Nm DH_generate_parameters +.Nd generate and check Diffie-Hellman parameters +.Sh SYNOPSIS +.In openssl/dh.h +.Ft int +.Fo DH_generate_parameters_ex +.Fa "DH *dh" +.Fa "int prime_len" +.Fa "int generator" +.Fa "BN_GENCB *cb" +.Fc +.Ft int +.Fo DH_check +.Fa "DH *dh" +.Fa "int *codes" +.Fc +.Ft int +.Fo DH_check_pub_key +.Fa "const DH *dh" +.Fa "const BIGNUM *pub_key" +.Fa "int *codes" +.Fc +.Pp +Deprecated: +.Pp +.Ft DH * +.Fo DH_generate_parameters +.Fa "int prime_len" +.Fa "int generator" +.Fa "void (*callback)(int, int, void *)" +.Fa "void *cb_arg" +.Fc +.Sh DESCRIPTION +.Fn DH_generate_parameters_ex +generates Diffie-Hellman parameters that can be shared among a group of +users, and stores them in the provided +.Vt DH +structure. +.Pp +.Fa prime_len +is the length in bits of the safe prime to be generated. +.Fa generator +is a small number > 1, typically 2 or 5. +.Pp +A callback function may be used to provide feedback about the progress +of the key generation. +If +.Fa cb +is not +.Dv NULL , +it will be called as described in +.Xr BN_generate_prime 3 +while a random prime number is generated, and when a prime has been +found, +.Fn BN_GENCB_call cb 3 0 +is called; see +.Xr BN_GENCB_call 3 . +.Pp +.Fn DH_check +validates Diffie-Hellman parameters. +If no problems are found, +.Pf * Ar codes +is set to zero. +Otherwise, one or more of the following bits are set: +.Bl -tag -width Ds +.It Dv DH_CHECK_P_NOT_PRIME +The parameter +.Fa dh->p +is not prime. +.It Dv DH_CHECK_P_NOT_SAFE_PRIME +The parameter +.Fa dh->p +is not a safe prime. +.It Dv DH_UNABLE_TO_CHECK_GENERATOR +The generator +.Fa dh->g +cannot be checked for suitability: it is neither 2 nor 5. +.It Dv DH_NOT_SUITABLE_GENERATOR +The generator +.Fa dh->g +is not suitable. +.El +.Pp +.Fn DH_check_pub_key +checks whether +.Fa pub_key +is a valid public key when using the domain parameters contained in +.Fa dh . +If no problems are found, +.Pf * Ar codes +is set to zero. +Otherwise, one or more of the following bits are set: +.Bl -tag -width Ds +.It Dv DH_CHECK_PUBKEY_TOO_SMALL +.Fa pub_key +is less than or equal to 1. +.It Dv DH_CHECK_PUBKEY_TOO_LARGE +.Fa pub_key +is greater than or equal to +.Fa dh->p No \- 1 . +.It DH_CHECK_PUBKEY_INVALID +.Fa dh->q +is set but +.Fa pub_key +to the power of +.Fa dh->q +is not 1 modulo +.Fa dh->p . +.El +.Sh RETURN VALUES +.Fn DH_generate_parameters_ex , +.Fn DH_check , +and +.Fn DH_check_pub_key +return 1 if the check could be performed or 0 otherwise. +.Pp +.Fn DH_generate_parameters +(deprecated) returns a pointer to the +.Vt DH +structure, or +.Dv NULL +if the parameter generation fails. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr DH_get0_pqg 3 , +.Xr DH_new 3 +.Sh HISTORY +.Fn DH_check +and +.Fn DH_generate_parameters +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +The +.Fa cb_arg +argument to +.Fn DH_generate_parameters +was added in SSLeay 0.9.0. +.Pp +.Fn DH_check_pub_key +first appeared in OpenSSL 0.9.8a and has been available since +.Ox 4.0 . +.Pp +.Fn DH_generate_parameters_ex +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Sh CAVEATS +.Fn DH_generate_parameters_ex +and +.Fn DH_generate_parameters +may run for several hours before finding a suitable prime. +.Pp +The parameters generated by +.Fn DH_generate_parameters_ex +and +.Fn DH_generate_parameters +are not to be used in signature schemes. +.Sh BUGS +If +.Fa generator +is not 2 or 5, +.Fa dh->g Ns = Ns Fa generator +is not a usable generator. diff --git a/Libraries/libressl/man/DH_get0_pqg.3 b/Libraries/libressl/man/DH_get0_pqg.3 new file mode 100644 index 000000000..340d50757 --- /dev/null +++ b/Libraries/libressl/man/DH_get0_pqg.3 @@ -0,0 +1,349 @@ +.\" $OpenBSD: DH_get0_pqg.3,v 1.7 2023/03/06 13:25:46 tb Exp $ +.\" selective merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2016, 2018 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 6 2023 $ +.Dt DH_GET0_PQG 3 +.Os +.Sh NAME +.Nm DH_get0_pqg , +.Nm DH_get0_p , +.Nm DH_get0_q , +.Nm DH_get0_g , +.Nm DH_set0_pqg , +.Nm DH_get0_key , +.Nm DH_get0_pub_key , +.Nm DH_get0_priv_key , +.Nm DH_set0_key , +.Nm DH_clear_flags , +.Nm DH_test_flags , +.Nm DH_set_flags , +.Nm DH_get0_engine , +.Nm DH_set_length +.Nd get data from and set data in a DH object +.Sh SYNOPSIS +.In openssl/dh.h +.Ft void +.Fo DH_get0_pqg +.Fa "const DH *dh" +.Fa "const BIGNUM **p" +.Fa "const BIGNUM **q" +.Fa "const BIGNUM **g" +.Fc +.Ft "const BIGNUM *" +.Fo DH_get0_p +.Fa "const DH *dh" +.Fc +.Ft "const BIGNUM *" +.Fo DH_get0_q +.Fa "const DH *dh" +.Fc +.Ft "const BIGNUM *" +.Fo DH_get0_g +.Fa "const DH *dh" +.Fc +.Ft int +.Fo DH_set0_pqg +.Fa "DH *dh" +.Fa "BIGNUM *p" +.Fa "BIGNUM *q" +.Fa "BIGNUM *g" +.Fc +.Ft void +.Fo DH_get0_key +.Fa "const DH *dh" +.Fa "const BIGNUM **pub_key" +.Fa "const BIGNUM **priv_key" +.Fc +.Ft "const BIGNUM *" +.Fo DH_get0_pub_key +.Fa "const DH *dh" +.Fc +.Ft "const BIGNUM *" +.Fo DH_get0_priv_key +.Fa "const DH *dh" +.Fc +.Ft int +.Fo DH_set0_key +.Fa "DH *dh" +.Fa "BIGNUM *pub_key" +.Fa "BIGNUM *priv_key" +.Fc +.Ft void +.Fo DH_clear_flags +.Fa "DH *dh" +.Fa "int flags" +.Fc +.Ft int +.Fo DH_test_flags +.Fa "const DH *dh" +.Fa "int flags" +.Fc +.Ft void +.Fo DH_set_flags +.Fa "DH *dh" +.Fa "int flags" +.Fc +.Ft ENGINE * +.Fo DH_get0_engine +.Fa "DH *d" +.Fc +.Ft int +.Fo DH_set_length +.Fa "DH *dh" +.Fa "long length" +.Fc +.Sh DESCRIPTION +A +.Vt DH +object contains the parameters +.Fa p , +.Fa g , +and optionally +.Fa q . +It also contains a public key +.Fa pub_key +and an optional private key +.Fa priv_key . +.Pp +The +.Fa p , +.Fa q , +and +.Fa g +parameters can be obtained by calling +.Fn DH_get0_pqg . +If the parameters have not yet been set, then +.Pf * Fa p , +.Pf * Fa q , +and +.Pf * Fa g +are set to +.Dv NULL . +Otherwise, they are set to pointers to the internal representations +of the values that should not be freed by the application. +Any of the out parameters +.Fa p , +.Fa q , +and +.Fa g +can be +.Dv NULL , +in which case no value is returned for that parameter. +.Pp +The +.Fa p , +.Fa q , +and +.Fa g +values can be set by calling +.Fn DH_set0_pqg . +Calling this function transfers the memory management of the values to +.Fa dh , +and therefore they should not be freed by the caller. +The +.Fa q +argument may be +.Dv NULL . +.Pp +The +.Fn DH_get0_key +function stores pointers to the internal representations +of the public key in +.Pf * Fa pub_key +and to the private key in +.Pf * Fa priv_key . +Either may be +.Dv NULL +if it has not yet been set. +If the private key has been set, then the public key must be. +Any of the out parameters +.Fa pub_key +and +.Fa priv_key +can be +.Dv NULL , +in which case no value is returned for that parameter. +.Pp +The public and private key values can be set using +.Fn DH_set0_key . +Either parameter may be +.Dv NULL , +which means the corresponding +.Vt DH +field is left untouched. +This function transfers the memory management of the key values to +.Fa dh , +and therefore they should not be freed by the caller. +.Pp +Values retrieved with +.Fn DH_get0_pqg +and +.Fn DH_get0_key +are owned by the +.Vt DH +object and may therefore not be passed to +.Fn DH_set0_pqg +or +.Fn DH_set0_key . +If needed, duplicate the received values using +.Xr BN_dup 3 +and pass the duplicates. +.Pp +Any of the values +.Fa p , +.Fa q , +.Fa g , +.Fa pub_key , +and +.Fa priv_key +can also be retrieved separately by the corresponding functions +.Fn DH_get0_p , +.Fn DH_get0_q , +.Fn DH_get0_g , +.Fn DH_get0_pub_key , +and +.Fn DH_get0_priv_key , +respectively. +The pointers are owned by the +.Vt DH +object. +.Pp +.Fn DH_clear_flags +clears the specified +.Fa flags +in +.Fa dh . +.Fn DH_test_flags +tests the +.Fa flags +in +.Fa dh . +.Fn DH_set_flags +sets the +.Fa flags +in +.Fa dh ; +any flags already set remain set. +For all three functions, multiple flags can be passed in one call, +OR'ed together bitwise. +.Pp +.Fn DH_set_length +sets the optional length attribute of +.Fa dh , +indicating the length of the secret exponent (private key) in bits. +If the length attribute is non-zero, it is used, otherwise it is ignored. +.Sh RETURN VALUES ++.Fn DH_get0_p , ++.Fn DH_get0_q , ++.Fn DH_get0_g , ++.Fn DH_get0_pub_key , ++and ++.Fn DH_get0_priv_key , ++return a pointer owned by the ++.Vt DH ++object if the corresponding value has been set, ++otherwise they return ++.Dv NULL . +.Fn DH_set0_pqg , +.Fn DH_set0_key , +and +.Fn DH_set_length +return 1 on success or 0 on failure. +.Pp +.Fn DH_test_flags +return those of the given +.Fa flags +currently set in +.Fa dh +or 0 if none of the given +.Fa flags +are set. +.Pp +.Fn DH_get0_engine +returns a pointer to the +.Vt ENGINE +used by the +.Vt DH +object +.Fa dh , +or +.Dv NULL +if no engine was set for this object. +.Sh SEE ALSO +.Xr DH_generate_key 3 , +.Xr DH_generate_parameters 3 , +.Xr DH_new 3 , +.Xr DH_security_bits 3 , +.Xr DH_size 3 , +.Xr DHparams_print 3 +.Sh HISTORY +.Fn DH_get0_pqg , +.Fn DH_set0_pqg , +.Fn DH_get0_key , +.Fn DH_set0_key , +.Fn DH_clear_flags , +.Fn DH_test_flags , +.Fn DH_set_flags , +.Fn DH_get0_engine , +and +.Fn DH_set_length +first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . +.Pp +.Fn DH_get0_p , +.Fn DH_get0_q , +.Fn DH_get0_g , +.Fn DH_get0_pub_key , +and +.Fn DH_get0_priv_key +first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/DH_get_ex_new_index.3 b/Libraries/libressl/man/DH_get_ex_new_index.3 new file mode 100644 index 000000000..81a0aff8e --- /dev/null +++ b/Libraries/libressl/man/DH_get_ex_new_index.3 @@ -0,0 +1,99 @@ +.\" $OpenBSD: DH_get_ex_new_index.3,v 1.5 2018/03/23 23:18:17 schwarze Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt DH_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm DH_get_ex_new_index , +.Nm DH_set_ex_data , +.Nm DH_get_ex_data +.Nd add application specific data to DH structures +.Sh SYNOPSIS +.In openssl/dh.h +.Ft int +.Fo DH_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fo DH_set_ex_data +.Fa "DH *d" +.Fa "int idx" +.Fa "void *arg" +.Fc +.Ft char * +.Fo DH_get_ex_data +.Fa "DH *d" +.Fa "int idx" +.Fc +.Sh DESCRIPTION +These functions handle application specific data in +.Vt DH +structures. +Their usage is identical to that of +.Xr RSA_get_ex_new_index 3 , +.Xr RSA_set_ex_data 3 , +and +.Xr RSA_get_ex_data 3 . +.Sh SEE ALSO +.Xr DH_new 3 , +.Xr RSA_get_ex_new_index 3 +.Sh HISTORY +.Fn DH_get_ex_new_index , +.Fn DH_set_ex_data , +and +.Fn DH_get_ex_data +first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/DH_new.3 b/Libraries/libressl/man/DH_new.3 new file mode 100644 index 000000000..499345689 --- /dev/null +++ b/Libraries/libressl/man/DH_new.3 @@ -0,0 +1,133 @@ +.\" $OpenBSD: DH_new.3,v 1.12 2022/07/13 21:51:35 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt DH_NEW 3 +.Os +.Sh NAME +.Nm DH_new , +.Nm DH_up_ref , +.Nm DH_free +.Nd allocate and free DH objects +.Sh SYNOPSIS +.In openssl/dh.h +.Ft DH* +.Fn DH_new void +.Ft int +.Fo DH_up_ref +.Fa "DH *dh" +.Fc +.Ft void +.Fo DH_free +.Fa "DH *dh" +.Fc +.Sh DESCRIPTION +The DH functions implement the Diffie-Hellman key agreement protocol. +.Pp +.Fn DH_new +allocates and initializes a +.Vt DH +structure, setting the reference count to 1. +It is equivalent to +.Xr DH_new_method 3 +with a +.Dv NULL +argument. +.Pp +.Fn DH_up_ref +increments the reference count by 1. +.Pp +.Fn DH_free +decrements the reference count by 1. +If it reaches 0, it frees the +.Vt DH +structure and its components. +The values are erased before the memory is returned to the system. +If +.Fa dh +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +If the allocation fails, +.Fn DH_new +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 . +Otherwise it returns a pointer to the newly allocated structure. +.Pp +.Fn DH_up_ref +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr crypto 3 , +.Xr d2i_DHparams 3 , +.Xr DH_generate_key 3 , +.Xr DH_generate_parameters 3 , +.Xr DH_get0_pqg 3 , +.Xr DH_get_ex_new_index 3 , +.Xr DH_security_bits 3 , +.Xr DH_set_method 3 , +.Xr DH_size 3 , +.Xr DHparams_print 3 , +.Xr DSA_dup_DH 3 , +.Xr EVP_PKEY_CTX_set_dh_paramgen_prime_len 3 , +.Xr EVP_PKEY_set1_DH 3 +.Sh HISTORY +.Fn DH_new +and +.Fn DH_free +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn DH_up_ref +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/DH_set_method.3 b/Libraries/libressl/man/DH_set_method.3 new file mode 100644 index 000000000..e89fdc64a --- /dev/null +++ b/Libraries/libressl/man/DH_set_method.3 @@ -0,0 +1,217 @@ +.\" $OpenBSD: DH_set_method.3,v 1.8 2022/01/15 23:38:50 jsg Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002, 2007 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt DH_SET_METHOD 3 +.Os +.Sh NAME +.Nm DH_set_default_method , +.Nm DH_get_default_method , +.Nm DH_set_method , +.Nm DH_new_method , +.Nm DH_OpenSSL +.Nd select DH method +.Sh SYNOPSIS +.In openssl/dh.h +.Ft void +.Fo DH_set_default_method +.Fa "const DH_METHOD *meth" +.Fc +.Ft const DH_METHOD * +.Fo DH_get_default_method +.Fa void +.Fc +.Ft int +.Fo DH_set_method +.Fa "DH *dh" +.Fa "const DH_METHOD *meth" +.Fc +.Ft DH * +.Fo DH_new_method +.Fa "ENGINE *engine" +.Fc +.Ft const DH_METHOD * +.Fo DH_OpenSSL +.Fa void +.Fc +.Sh DESCRIPTION +A +.Vt DH_METHOD +object contains pointers to the functions +used for Diffie-Hellman operations. +By default, the internal implementation returned by +.Fn DH_OpenSSL +is used. +By selecting another method, alternative implementations +such as hardware accelerators may be used. +.Pp +.Fn DH_set_default_method +selects +.Fa meth +as the default method for all +.Vt DH +structures created later. +If any +.Vt ENGINE +was registered with +.Xr ENGINE_register_DH 3 +that can be successfully initialized, it overrides the default. +.Pp +.Fn DH_get_default_method +returns a pointer to the current default method, +even if it is actually overridden by an +.Vt ENGINE . +.Pp +.Fn DH_set_method +selects +.Fa meth +to perform all operations using the key +.Fa dh . +This replaces the +.Vt DH_METHOD +used by the +.Fa dh +key and if the previous method was supplied by an +.Vt ENGINE , +.Xr ENGINE_finish 3 +is called on it. +It is possible to have +.Vt DH +keys that only work with certain +.Vt DH_METHOD +implementations (e.g. from an +.Vt ENGINE +module that supports embedded hardware-protected keys), +and in such cases attempting to change the +.Vt DH_METHOD +for the key can have unexpected results. +.Pp +.Fn DH_new_method +allocates and initializes a +.Vt DH +structure so that +.Fa engine +is used for the DH operations. +If +.Fa engine +is +.Dv NULL , +.Xr ENGINE_get_default_DH 3 +is used. +If that returns +.Dv NULL , +the default method controlled by +.Fn DH_set_default_method +is used. +.Pp +The +.Vt DH_METHOD +structure is defined as follows: +.Bd -literal +typedef struct dh_meth_st +{ + /* name of the implementation */ + const char *name; + + /* generate private and public DH values for key agreement */ + int (*generate_key)(DH *dh); + + /* compute shared secret */ + int (*compute_key)(unsigned char *key, BIGNUM *pub_key, DH *dh); + + /* compute r = a ^ p mod m (May be NULL for some implementations) */ + int (*bn_mod_exp)(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + + /* called at DH_new */ + int (*init)(DH *dh); + + /* called at DH_free */ + int (*finish)(DH *dh); + + int flags; + + char *app_data; /* ?? */ + +} DH_METHOD; +.Ed +.Sh RETURN VALUES +.Fn DH_OpenSSL +and +.Fn DH_get_default_method +return pointers to the respective +.Vt DH_METHOD . +.Pp +.Fn DH_set_method +returns 1 on success or 0 on failure. +Currently, it cannot fail. +.Pp +.Fn DH_new_method +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 +if the allocation fails. +Otherwise it returns a pointer to the newly allocated structure. +.Sh SEE ALSO +.Xr DH_new 3 , +.Xr ENGINE_get_default_DH 3 , +.Xr ENGINE_register_DH 3 , +.Xr ENGINE_set_default_DH 3 +.Sh HISTORY +.Fn DH_set_default_method , +.Fn DH_get_default_method , +.Fn DH_set_method , +.Fn DH_new_method +and +.Fn DH_OpenSSL +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/DH_size.3 b/Libraries/libressl/man/DH_size.3 new file mode 100644 index 000000000..4e6dbc0cb --- /dev/null +++ b/Libraries/libressl/man/DH_size.3 @@ -0,0 +1,97 @@ +.\" $OpenBSD: DH_size.3,v 1.10 2022/07/13 21:51:35 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller +.\" and Kurt Roeckx . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt DH_SIZE 3 +.Os +.Sh NAME +.Nm DH_size , +.Nm DH_bits +.Nd get Diffie-Hellman prime size +.Sh SYNOPSIS +.In openssl/dh.h +.Ft int +.Fo DH_size +.Fa "const DH *dh" +.Fc +.Ft int +.Fo DH_bits +.Fa "const DH *dh" +.Fc +.Sh DESCRIPTION +.Fn DH_size +returns the Diffie-Hellman prime size in bytes. +It can be used to determine how much memory must be allocated for the +shared secret computed by +.Xr DH_compute_key 3 . +.Pp +.Fn DH_bits +returns the number of significant bits in the key. +.Pp +.Fa dh +and +.Fa dh->p +must not be +.Dv NULL . +.Sh SEE ALSO +.Xr BN_num_bytes 3 , +.Xr DH_generate_key 3 , +.Xr DH_get0_key 3 , +.Xr DH_new 3 , +.Xr DH_security_bits 3 +.Sh HISTORY +.Fn DH_size +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . +.Pp +.Fn DH_bits +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/DIST_POINT_new.3 b/Libraries/libressl/man/DIST_POINT_new.3 new file mode 100644 index 000000000..6a5cc4046 --- /dev/null +++ b/Libraries/libressl/man/DIST_POINT_new.3 @@ -0,0 +1,154 @@ +.\" $OpenBSD: DIST_POINT_new.3,v 1.5 2019/06/06 01:06:58 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt DIST_POINT_NEW 3 +.Os +.Sh NAME +.Nm DIST_POINT_new , +.Nm DIST_POINT_free , +.Nm CRL_DIST_POINTS_new , +.Nm CRL_DIST_POINTS_free , +.Nm DIST_POINT_NAME_new , +.Nm DIST_POINT_NAME_free , +.Nm ISSUING_DIST_POINT_new , +.Nm ISSUING_DIST_POINT_free +.Nd X.509 CRL distribution point extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft DIST_POINT * +.Fn DIST_POINT_new void +.Ft void +.Fn DIST_POINT_free "DIST_POINT *dp" +.Ft CRL_DIST_POINTS * +.Fn CRL_DIST_POINTS_new void +.Ft void +.Fn CRL_DIST_POINTS_free "CRL_DIST_POINTS *dps" +.Ft DIST_POINT_NAME * +.Fn DIST_POINT_NAME_new void +.Ft void +.Fn DIST_POINT_NAME_free "DIST_POINT_NAME *name" +.Ft ISSUING_DIST_POINT * +.Fn ISSUING_DIST_POINT_new void +.Ft void +.Fn ISSUING_DIST_POINT_free "ISSUING_DIST_POINT *dp" +.Sh DESCRIPTION +Using the CRL distribution point extension, a certificate can specify +where to obtain certificate revocation lists that might later revoke it. +.Pp +.Fn DIST_POINT_new +allocates and initializes an empty +.Vt DIST_POINT +object, representing an ASN.1 +.Vt DistributionPoint +structure defined in RFC 5280 section 4.2.1.13. +It can hold issuer names, distribution point names, and reason flags. +.Fn DIST_POINT_free +frees +.Fa dp . +.Pp +.Fn CRL_DIST_POINTS_new +allocates and initializes an empty +.Vt CRL_DIST_POINTS +object, which is a +.Vt STACK_OF(DIST_POINT) +and represents the ASN.1 +.Vt CRLDistributionPoints +structure defined in RFC 5280 section 4.2.1.13. +It can be used as an extension in +.Vt X509 +and in +.Vt X509_CRL +objects. +.Fn CRL_DIST_POINTS_free +frees +.Fa dps . +.Pp +.Fn DIST_POINT_NAME_new +allocates and initializes an empty +.Vt DIST_POINT_NAME +object, representing an ASN.1 +.Vt DistributionPointName +structure defined in RFC 5280 section 4.2.1.13. +It is used by the +.Vt DIST_POINT +and +.Vt ISSUING_DIST_POINT +objects and can hold multiple names, each representing a different +way to obtain the same CRL. +.Fn DIST_POINT_NAME_free +frees +.Fa name . +.Pp +.Fn ISSUING_DIST_POINT_new +allocates and initializes an empty +.Vt ISSUING_DIST_POINT +object, representing an ASN.1 +.Vt IssuingDistributionPoint +structure defined in RFC 5280 section 5.2.5. +Using this extension, a CRL can specify which distribution point +it was issued from and which kinds of certificates and revocation +reasons it covers. +.Fn ISSUING_DIST_POINT_free +frees +.Fa dp . +.Sh RETURN VALUES +.Fn DIST_POINT_new , +.Fn CRL_DIST_POINTS_new , +.Fn DIST_POINT_NAME_new , +and +.Fn ISSUING_DIST_POINT_new +return the new +.Vt DIST_POINT , +.Vt CRL_DIST_POINTS , +.Vt DIST_POINT_NAME , +or +.Vt ISSUING_DIST_POINT +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_DIST_POINT 3 , +.Xr GENERAL_NAMES_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.1.13: CRL Distribution Points +.It +section 5.2.5: Issuing Distribution Point +.El +.Sh HISTORY +.Fn DIST_POINT_new , +.Fn DIST_POINT_free , +.Fn CRL_DIST_POINTS_new , +.Fn CRL_DIST_POINTS_free , +.Fn DIST_POINT_NAME_new , +and +.Fn DIST_POINT_NAME_free +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . +.Pp +.Fn ISSUING_DIST_POINT_new +and +.Fn ISSUING_DIST_POINT_free +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/DSA_SIG_new.3 b/Libraries/libressl/man/DSA_SIG_new.3 new file mode 100644 index 000000000..160b45393 --- /dev/null +++ b/Libraries/libressl/man/DSA_SIG_new.3 @@ -0,0 +1,141 @@ +.\" $OpenBSD: DSA_SIG_new.3,v 1.8 2019/06/10 14:58:48 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller , +.\" Dr. Stephen Henson , and +.\" TJ Saunders . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt DSA_SIG_NEW 3 +.Os +.Sh NAME +.Nm DSA_SIG_new , +.Nm DSA_SIG_free , +.Nm DSA_SIG_get0 , +.Nm DSA_SIG_set0 +.Nd manipulate DSA signature objects +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft DSA_SIG * +.Fn DSA_SIG_new void +.Ft void +.Fo DSA_SIG_free +.Fa "DSA_SIG *sig" +.Fc +.Ft void +.Fo DSA_SIG_get0 +.Fa "const DSA_SIG *sig" +.Fa "const BIGNUM **r" +.Fa "const BIGNUM **s" +.Fc +.Ft int +.Fo DSA_SIG_set0 +.Fa "DSA_SIG *sig" +.Fa "BIGNUM *r" +.Fa "BIGNUM *s" +.Fc +.Sh DESCRIPTION +.Fn DSA_SIG_new +allocates an empty +.Vt DSA_SIG +structure. +.Pp +.Fn DSA_SIG_free +frees the +.Vt DSA_SIG +structure and its components. +The values are erased before the memory is returned to the system. +If +.Fa sig +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn DSA_SIG_get0 +retrieves internal pointers to the +.Fa r +and +.Fa s +values contained in +.Fa sig . +.Pp +The +.Fa r +and +.Fa s +values can be set by calling +.Fn DSA_SIG_set0 . +Calling this function transfers the memory management of the values to +.Fa sig , +and therefore they should not be freed by the caller. +.Sh RETURN VALUES +If the allocation fails, +.Fn DSA_SIG_new +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 . +Otherwise it returns a pointer to the newly allocated structure. +.Pp +.Fn DSA_SIG_set0 +returns 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr DSA_do_sign 3 , +.Xr DSA_new 3 +.Sh HISTORY +.Fn DSA_SIG_new +and +.Fn DSA_SIG_free +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . +.Pp +.Fn DSA_SIG_get0 +and +.Fn DSA_SIG_set0 +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/DSA_do_sign.3 b/Libraries/libressl/man/DSA_do_sign.3 new file mode 100644 index 000000000..4602bed87 --- /dev/null +++ b/Libraries/libressl/man/DSA_do_sign.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: DSA_do_sign.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt DSA_DO_SIGN 3 +.Os +.Sh NAME +.Nm DSA_do_sign , +.Nm DSA_do_verify +.Nd raw DSA signature operations +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft DSA_SIG * +.Fo DSA_do_sign +.Fa "const unsigned char *dgst" +.Fa "int dlen" +.Fa "DSA *dsa" +.Fc +.Ft int +.Fo DSA_do_verify +.Fa "const unsigned char *dgst" +.Fa "int dgst_len" +.Fa "DSA_SIG *sig" +.Fa "DSA *dsa" +.Fc +.Sh DESCRIPTION +.Fn DSA_do_sign +computes a digital signature on the +.Fa dlen +byte message digest +.Fa dgst +using the private key +.Fa dsa +and returns it in a newly allocated +.Vt DSA_SIG +structure. +.Pp +.Xr DSA_sign_setup 3 +may be used to precompute part of the signing operation in case +signature generation is time-critical. +.Pp +.Fn DSA_do_verify +verifies that the signature +.Fa sig +matches a given message digest +.Fa dgst +of size +.Fa dgst_len . +.Fa dsa +is the signer's public key. +.Sh RETURN VALUES +.Fn DSA_do_sign +returns the signature or +.Dv NULL +on error. +.Fn DSA_do_verify +returns 1 for a valid signature, 0 for an incorrect signature, +and -1 on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr DSA_get0_key 3 , +.Xr DSA_meth_set_sign 3 , +.Xr DSA_new 3 , +.Xr DSA_SIG_new 3 , +.Xr DSA_sign 3 +.Sh HISTORY +.Fn DSA_do_sign +and +.Fn DSA_do_verify +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/DSA_dup_DH.3 b/Libraries/libressl/man/DSA_dup_DH.3 new file mode 100644 index 000000000..d6163fd3c --- /dev/null +++ b/Libraries/libressl/man/DSA_dup_DH.3 @@ -0,0 +1,88 @@ +.\" $OpenBSD: DSA_dup_DH.3,v 1.9 2023/08/12 08:26:38 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 12 2023 $ +.Dt DSA_DUP_DH 3 +.Os +.Sh NAME +.Nm DSA_dup_DH +.Nd create a DH structure out of DSA structure +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft DH * +.Fo DSA_dup_DH +.Fa "const DSA *r" +.Fc +.Sh DESCRIPTION +.Fn DSA_dup_DH +duplicates +.Vt DSA +parameters/keys as +.Vt DH +parameters/keys. +.Sh RETURN VALUES +.Fn DSA_dup_DH +returns the new +.Vt DH +structure or +.Dv NULL +on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr DH_new 3 , +.Xr DSA_get0_pqg 3 , +.Xr DSA_new 3 +.Sh HISTORY +.Fn DSA_dup_DH +first appeared in OpenSSL 0.9.4 and has been available since +.Ox 2.6 . +.Sh CAVEATS +Be careful to avoid small subgroup attacks when using this. diff --git a/Libraries/libressl/man/DSA_generate_key.3 b/Libraries/libressl/man/DSA_generate_key.3 new file mode 100644 index 000000000..97e185e0b --- /dev/null +++ b/Libraries/libressl/man/DSA_generate_key.3 @@ -0,0 +1,84 @@ +.\" $OpenBSD: DSA_generate_key.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt DSA_GENERATE_KEY 3 +.Os +.Sh NAME +.Nm DSA_generate_key +.Nd generate DSA key pair +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft int +.Fo DSA_generate_key +.Fa "DSA *a" +.Fc +.Sh DESCRIPTION +.Fn DSA_generate_key +expects +.Fa a +to contain DSA parameters. +It generates a new key pair and stores it in +.Fa a->pub_key +and +.Fa a->priv_key . +.Sh RETURN VALUES +.Fn DSA_generate_key +returns 1 on success or 0 otherwise. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr DSA_generate_parameters 3 , +.Xr DSA_get0_key 3 , +.Xr DSA_new 3 +.Sh HISTORY +.Fn DSA_generate_key +first appeared in SSLeay 0.6.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/DSA_generate_parameters.3 b/Libraries/libressl/man/DSA_generate_parameters.3 new file mode 100644 index 000000000..07fa5acf9 --- /dev/null +++ b/Libraries/libressl/man/DSA_generate_parameters.3 @@ -0,0 +1,226 @@ +.\" $OpenBSD: DSA_generate_parameters.3,v 1.13 2023/05/14 09:27:15 tb Exp $ +.\" OpenSSL 9b86974e Aug 7 22:14:47 2015 -0400 +.\" +.\" This file was written by Ulf Moeller , +.\" Bodo Moeller , and Matt Caswell . +.\" Copyright (c) 2000, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 14 2023 $ +.Dt DSA_GENERATE_PARAMETERS 3 +.Os +.Sh NAME +.Nm DSA_generate_parameters_ex , +.Nm DSA_generate_parameters +.Nd generate DSA parameters +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft int +.Fo DSA_generate_parameters_ex +.Fa "DSA *dsa" +.Fa "int bits" +.Fa "const unsigned char *seed" +.Fa "int seed_len" +.Fa "int *counter_ret" +.Fa "unsigned long *h_ret" +.Fa "BN_GENCB *cb" +.Fc +.Pp +Deprecated: +.Pp +.Ft DSA * +.Fo DSA_generate_parameters +.Fa "int bits" +.Fa "unsigned char *seed" +.Fa "int seed_len" +.Fa "int *counter_ret" +.Fa "unsigned long *h_ret" +.Fa "void (*callback)(int, int, void *)" +.Fa "void *cb_arg" +.Fc +.Sh DESCRIPTION +.Fn DSA_generate_parameters_ex +generates primes p and q and a generator g for use in the DSA and stores +the result in +.Fa dsa . +.Pp +.Fa bits +is the length of the prime to be generated; the DSS allows a maximum of +1024 bits. +.Pp +If +.Fa seed +is +.Dv NULL +or +.Fa seed_len +< 20, the primes will be generated at random. +Otherwise, the seed is used to generate them. +If the given seed does not yield a prime q, a new random seed is chosen +and placed at +.Fa seed . +.Pp +.Fn DSA_generate_parameters_ex +places the iteration count in +.Pf * Fa counter_ret +and a counter used for finding a generator in +.Pf * Fa h_ret , +unless these are +.Dv NULL . +.Pp +A callback function may be used to provide feedback about the progress +of the key generation. +If +.Fa cb +is not +.Dv NULL , +it will be called as shown below. +For information on the +.Vt BN_GENCB +structure, refer to +.Xr BN_GENCB_call 3 . +.Bl -bullet +.It +When a candidate for q is generated, +.Fn BN_GENCB_call cb 0 m++ +is called +.Pf ( Fa m +is 0 for the first candidate). +.It +When a candidate for q has passed a test by trial division, +.Fn BN_GENCB_call cb 1 -1 +is called. +While a candidate for q is tested by Miller-Rabin primality tests, +.Fn BN_GENCB_call cb 1 i +is called in the outer loop (once for each witness that confirms that +the candidate may be prime); +.Fa i +is the loop counter (starting at 0). +.It +When a prime q has been found, +.Fn BN_GENCB_call cb 2 0 +and +.Fn BN_GENCB_call cb 3 0 +are called. +.It +Before a candidate for p (other than the first) is generated and tested, +.Fn BN_GENCB_call cb 0 counter +is called. +.It +When a candidate for p has passed the test by trial division, +.Fn BN_GENCB_call cb 1 -1 +is called. +While it is tested by the Miller-Rabin primality test, +.Fn BN_GENCB_call cb 1 i +is called in the outer loop (once for each witness that confirms that +the candidate may be prime). +.Fa i +is the loop counter (starting at 0). +.It +When p has been found, +.Fn BN_GENCB_call cb 2 1 +is called. +.It +When the generator has been found, +.Fn BN_GENCB_call cb 3 1 +is called. +.El +.Pp +.Fn DSA_generate_parameters +(deprecated) works in much the same way as for +.Fn DSA_generate_parameters_ex , +except that no +.Fa dsa +parameter is passed and instead a newly allocated +.Vt DSA +structure is returned. +Additionally "old style" callbacks are used instead of the newer +.Vt BN_GENCB +based approach. +Refer to +.Xr BN_generate_prime 3 +for further information. +.Sh RETURN VALUES +.Fn DSA_generate_parameters_ex +returns a 1 on success, or 0 otherwise. +.Pp +.Fn DSA_generate_parameters +returns a pointer to the +.Vt DSA +structure, or +.Dv NULL +if the parameter generation fails. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_generate_prime 3 , +.Xr DSA_get0_pqg 3 , +.Xr DSA_new 3 +.Sh HISTORY +.Fn DSA_generate_parameters +first appeared in SSLeay 0.8.0 and had its +.Fa cb_arg +argument added in SSLeay 0.9.0. +It has been available since +.Ox 2.4 . +.Pp +In versions up to OpenSSL 0.9.4, +.Fn callback 1 ...\& +was called in the inner loop of the Miller-Rabin test whenever it +reached the squaring step (the parameters to +.Fn callback +did not reveal how many witnesses had been tested); since OpenSSL 0.9.5, +.Fn callback 1 ...\& +is called as in +.Xr BN_is_prime_ex 3 , +i.e. once for each witness. +.Pp +.Fn DSA_generate_parameters_ex +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Sh BUGS +Seed lengths > 20 are not supported. diff --git a/Libraries/libressl/man/DSA_get0_pqg.3 b/Libraries/libressl/man/DSA_get0_pqg.3 new file mode 100644 index 000000000..b5250d9f9 --- /dev/null +++ b/Libraries/libressl/man/DSA_get0_pqg.3 @@ -0,0 +1,327 @@ +.\" $OpenBSD: DSA_get0_pqg.3,v 1.7 2023/03/07 06:15:07 tb Exp $ +.\" full merge up to: OpenSSL e90fc053 Jul 15 09:39:45 2017 -0400 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 7 2023 $ +.Dt DSA_GET0_PQG 3 +.Os +.Sh NAME +.Nm DSA_get0_pqg , +.Nm DSA_get0_p , +.Nm DSA_get0_q , +.Nm DSA_get0_g , +.Nm DSA_set0_pqg , +.Nm DSA_get0_key , +.Nm DSA_get0_pub_key , +.Nm DSA_get0_priv_key , +.Nm DSA_set0_key , +.Nm DSA_clear_flags , +.Nm DSA_test_flags , +.Nm DSA_set_flags , +.Nm DSA_get0_engine +.Nd get data from and set data in a DSA object +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft void +.Fo DSA_get0_pqg +.Fa "const DSA *d" +.Fa "const BIGNUM **p" +.Fa "const BIGNUM **q" +.Fa "const BIGNUM **g" +.Fc +.Ft "const BIGNUM *" +.Fo DSA_get0_p +.Fa "const DSA *d" +.Fc +.Ft "const BIGNUM *" +.Fo DSA_get0_q +.Fa "const DSA *d" +.Fc +.Ft "const BIGNUM *" +.Fo DSA_get0_g +.Fa "const DSA *d" +.Fc +.Ft int +.Fo DSA_set0_pqg +.Fa "DSA *d" +.Fa "BIGNUM *p" +.Fa "BIGNUM *q" +.Fa "BIGNUM *g" +.Fc +.Ft void +.Fo DSA_get0_key +.Fa "const DSA *d" +.Fa "const BIGNUM **pub_key" +.Fa "const BIGNUM **priv_key" +.Fc +.Ft "const BIGNUM *" +.Fo DSA_get0_pub_key +.Fa "const DSA *d" +.Fc +.Ft "const BIGNUM *" +.Fo DSA_get0_priv_key +.Fa "const DSA *d" +.Fc +.Ft int +.Fo DSA_set0_key +.Fa "DSA *d" +.Fa "BIGNUM *pub_key" +.Fa "BIGNUM *priv_key" +.Fc +.Ft void +.Fo DSA_clear_flags +.Fa "DSA *d" +.Fa "int flags" +.Fc +.Ft int +.Fo DSA_test_flags +.Fa "const DSA *d" +.Fa "int flags" +.Fc +.Ft void +.Fo DSA_set_flags +.Fa "DSA *d" +.Fa "int flags" +.Fc +.Ft ENGINE * +.Fo DSA_get0_engine +.Fa "DSA *d" +.Fc +.Sh DESCRIPTION +A +.Vt DSA +object contains the parameters +.Fa p , +.Fa q , +and +.Fa g . +It also contains a public key +.Fa pub_key +and an optional private key +.Fa priv_key . +.Pp +The +.Fa p , +.Fa q , +and +.Fa g +parameters can be obtained by calling +.Fn DSA_get0_pqg . +If the parameters have not yet been set, then +.Pf * Fa p , +.Pf * Fa q , +and +.Pf * Fa g +are set to +.Dv NULL . +Otherwise, they are set to pointers to the internal representations +of the values that should not be freed by the application. +.Pp +The +.Fa p , +.Fa q , +and +.Fa g +values can be set by calling +.Fn DSA_set0_pqg . +Calling this function transfers the memory management of the values to +.Fa d , +and therefore they should not be freed by the caller. +.Pp +The +.Fn DSA_get0_key +function stores pointers to the internal representations +of the public key in +.Pf * Fa pub_key +and to the private key in +.Pf * Fa priv_key . +Either may be +.Dv NULL +if it has not yet been set. +If the private key has been set, then the public key must be. +.Pp +The public and private key values can be set using +.Fn DSA_set0_key . +The public key must be +.Pf non- Dv NULL +the first time this function is called on a given +.Vt DSA +object. +The private key may be +.Dv NULL . +On subsequent calls, either may be +.Dv NULL , +which means the corresponding +.Vt DSA +field is left untouched. +.Fn DSA_set0_key +transfers the memory management of the key values to +.Fa d , +and therefore they should not be freed by the caller. +.Pp +Values retrieved with +.Fn DSA_get0_pqg +and +.Fn DSA_get0_key +are owned by the +.Vt DSA +object and may therefore not be passed to +.Fn DSA_set0_pqg +or +.Fn DSA_set0_key . +If needed, duplicate the received values using +.Xr BN_dup 3 +and pass the duplicates. +.Pp +Any of the values +.Fa p , +.Fa q , +.Fa g , +.Fa pub_key , +and +.Fa priv_key +can also be retrieved separately by the corresponding functions +.Fn DSA_get0_p , +.Fn DSA_get0_q , +.Fn DSA_get0_g , +.Fn DSA_get0_pub_key , +and +.Fn DSA_get0_priv_key , +respectively. +The pointers are owned by the +.Vt DSA +object. +.Pp +.Fn DSA_clear_flags +clears the specified +.Fa flags +in +.Fa d . +.Fn DSA_test_flags +tests the +.Fa flags +in +.Fa d . +.Fn DSA_set_flags +sets the +.Fa flags +in +.Fa d ; +any flags already set remain set. +For all three functions, multiple flags can be passed in one call, +OR'ed together bitwise. +.Sh RETURN VALUES +.Fn DSA_get0_p , +.Fn DSA_get0_q , +.Fn DSA_get0_g , +.Fn DSA_get0_pub_key , +and +.Fn DSA_get0_priv_key +return a pointer owned by the +.Vt DSA +object if the corresponding value has been set, +otherwise they return +.Dv NULL . +.Fn DSA_set0_pqg +and +.Fn DSA_set0_key +return 1 on success or 0 on failure. +.Pp +.Fn DSA_test_flags +returns those of the given +.Fa flags +currently set in +.Fa d +or 0 if none of the given +.Fa flags +are set. +.Pp +.Fn DSA_get0_engine +returns a pointer to the +.Vt ENGINE +used by the +.Vt DSA +object +Fa d , +or +.Dv NULL +if no engine was set for this object. +.Sh SEE ALSO +.Xr DSA_do_sign 3 , +.Xr DSA_dup_DH 3 , +.Xr DSA_generate_key 3 , +.Xr DSA_generate_parameters 3 , +.Xr DSA_new 3 , +.Xr DSA_print 3 , +.Xr DSA_security_bits 3 , +.Xr DSA_sign 3 , +.Xr DSA_size 3 +.Sh HISTORY +.Fn DSA_get0_pqg , +.Fn DSA_set0_pqg , +.Fn DSA_get0_key , +.Fn DSA_set0_key , +.Fn DSA_clear_flags , +.Fn DSA_test_flags , +.Fn DSA_set_flags , +and +.Fn DSA_get0_engine +first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . +.Pp +.Fn DSA_get0_p , +.Fn DSA_get0_q , +.Fn DSA_get0_g , +.Fn DSA_get0_pub_key , +and +.Fn DSA_get0_priv_key +first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/DSA_get_ex_new_index.3 b/Libraries/libressl/man/DSA_get_ex_new_index.3 new file mode 100644 index 000000000..8fe055f33 --- /dev/null +++ b/Libraries/libressl/man/DSA_get_ex_new_index.3 @@ -0,0 +1,98 @@ +.\" $OpenBSD: DSA_get_ex_new_index.3,v 1.5 2018/03/22 16:06:33 schwarze Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2009 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt DSA_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm DSA_get_ex_new_index , +.Nm DSA_set_ex_data , +.Nm DSA_get_ex_data +.Nd add application specific data to DSA structures +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft int +.Fo DSA_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fo DSA_set_ex_data +.Fa "DSA *d" +.Fa "int idx" +.Fa "void *arg" +.Fc +.Ft char * +.Fo DSA_get_ex_data +.Fa "DSA *d" +.Fa "int idx" +.Fc +.Sh DESCRIPTION +These functions handle application specific data in +.Vt DSA +structures. +Their usage is identical to that of +.Xr RSA_get_ex_new_index 3 , +.Xr RSA_set_ex_data 3 , +and +.Xr RSA_get_ex_data 3 . +.Sh SEE ALSO +.Xr DSA_new 3 , +.Xr RSA_get_ex_new_index 3 +.Sh HISTORY +.Fn DSA_get_ex_new_index , +.Fn DSA_set_ex_data , +and +.Fn DSA_get_ex_data +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/DSA_meth_new.3 b/Libraries/libressl/man/DSA_meth_new.3 new file mode 100644 index 000000000..d89cd397b --- /dev/null +++ b/Libraries/libressl/man/DSA_meth_new.3 @@ -0,0 +1,230 @@ +.\" $OpenBSD: DSA_meth_new.3,v 1.3 2022/07/10 13:41:59 schwarze Exp $ +.\" selective merge up to: OpenSSL c4d3c19b Apr 3 13:57:12 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Matt Caswell . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 10 2022 $ +.Dt DSA_METH_NEW 3 +.Os +.Sh NAME +.Nm DSA_meth_new , +.Nm DSA_meth_free , +.Nm DSA_meth_dup , +.Nm DSA_meth_get0_name , +.Nm DSA_meth_set1_name , +.Nm DSA_meth_set_sign , +.Nm DSA_meth_set_finish +.Nd build up DSA methods +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft DSA_METHOD * +.Fo DSA_meth_new +.Fa "const char *name" +.Fa "int flags" +.Fc +.Ft void +.Fo DSA_meth_free +.Fa "DSA_METHOD *meth" +.Fc +.Ft DSA_METHOD * +.Fo DSA_meth_dup +.Fa "const DSA_METHOD *meth" +.Fc +.Ft const char * +.Fo DSA_meth_get0_name +.Fa "const DSA_METHOD *meth" +.Fc +.Ft int +.Fo DSA_meth_set1_name +.Fa "DSA_METHOD *meth" +.Fa "const char *name" +.Fc +.Ft int +.Fo DSA_meth_set_sign +.Fa "DSA_METHOD *meth" +.Fa "DSA_SIG *(*sign)(const unsigned char *, int, DSA *)" +.Fc +.Ft int +.Fo DSA_meth_set_finish +.Fa "DSA_METHOD *meth" +.Fa "int (*finish)(DSA *)" +.Fc +.Sh DESCRIPTION +The +.Vt DSA_METHOD +structure holds function pointers for custom DSA implementations. +.Pp +.Fn DSA_meth_new +creates a new +.Vt DSA_METHOD +structure. +A copy of the NUL-terminated +.Fa name +is stored in the new +.Vt DSA_METHOD +object. +Any new +.Vt DSA +object constructed from this +.Vt DSA_METHOD +will have the given +.Fa flags +set by default. +.Pp +.Fn DSA_meth_dup +creates a deep copy of +.Fa meth . +This might be useful for creating a new +.Vt DSA_METHOD +based on an existing one, but with some differences. +.Pp +.Fn DSA_meth_free +destroys +.Fa meth +and frees any memory associated with it. +.Pp +.Fn DSA_meth_get0_name +returns an internal pointer to the name of +.Fa meth . +.Fn DSA_meth_set1_name +stores a copy of the NUL-terminated +.Fa name +in +.Fa meth +after freeing the previously stored name. +Method names are ignored by the default DSA implementation but can be +used by alternative implementations and by the application program. +.Pp +.Fn DSA_meth_set_sign +sets the function used for creating a DSA signature. +This function will be called from +.Xr DSA_do_sign 3 +and indirectly from +.Xr DSA_sign 3 . +The parameters of +.Fa sign +have the same meaning as for +.Xr DSA_do_sign 3 . +.Pp +.Fn DSA_meth_set_finish +sets an optional function for destroying a +.Vt DSA +object. +Unless +.Fa finish +is +.Dv NULL , +it will be called from +.Xr DSA_free 3 . +It takes the same argument +and is intended to do DSA implementation specific cleanup. +The memory used by the +.Vt DSA +object itself should not be freed by the +.Fa finish +function. +.Sh RETURN VALUES +.Fn DSA_meth_new +and +.Fn DSA_meth_dup +return the newly allocated +.Vt DSA_METHOD +object or +.Dv NULL +on failure. +.Pp +.Fn DSA_meth_get0_name +returns an internal pointer which must not be freed by the caller. +.Pp +.Fn DSA_meth_set1_name +and all +.Fn DSA_meth_set_* +functions return 1 on success or 0 on failure. +In the current implementation, only +.Fn DSA_meth_set1_name +can actually fail. +.Sh SEE ALSO +.Xr DSA_do_sign 3 , +.Xr DSA_new 3 , +.Xr DSA_set_method 3 , +.Xr DSA_SIG_new 3 , +.Xr DSA_sign 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0. +.Pp +.Fn DSA_meth_new , +.Fn DSA_meth_free , +.Fn DSA_meth_dup , +.Fn DSA_meth_set_sign , +and +.Fn DSA_meth_set_finish +have been available since +.Ox 6.3 . +.Pp +.Fn DSA_meth_get0_name +and +.Fn DSA_meth_set1_name +have been available since +.Ox 7.2 . diff --git a/Libraries/libressl/man/DSA_new.3 b/Libraries/libressl/man/DSA_new.3 new file mode 100644 index 000000000..8e3160117 --- /dev/null +++ b/Libraries/libressl/man/DSA_new.3 @@ -0,0 +1,141 @@ +.\" $OpenBSD: DSA_new.3,v 1.13 2022/07/13 21:51:35 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt DSA_NEW 3 +.Os +.Sh NAME +.Nm DSA_new , +.Nm DSA_up_ref , +.Nm DSA_free +.Nd allocate and free DSA objects +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft DSA* +.Fn DSA_new void +.Ft int +.Fo DSA_up_ref +.Fa "DSA *dsa" +.Fc +.Ft void +.Fo DSA_free +.Fa "DSA *dsa" +.Fc +.Sh DESCRIPTION +The DSA functions implement the Digital Signature Algorithm. +.Pp +.Fn DSA_new +allocates and initializes a +.Vt DSA +structure, setting the reference count to 1. +It is equivalent to calling +.Xr DSA_new_method 3 +with a +.Dv NULL +argument. +.Pp +.Fn DSA_up_ref +increments the reference count by 1. +.Pp +.Fn DSA_free +decrements the reference count by 1. +If it reaches 0, it frees the +.Vt DSA +structure and its components. +The values are erased before the memory is returned to the system. +If +.Fa dsa +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +If the allocation fails, +.Fn DSA_new +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 . +Otherwise it returns a pointer to the newly allocated structure. +.Pp +.Fn DSA_up_ref +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr crypto 3 , +.Xr d2i_DSAPublicKey 3 , +.Xr DH_new 3 , +.Xr DSA_do_sign 3 , +.Xr DSA_dup_DH 3 , +.Xr DSA_generate_key 3 , +.Xr DSA_generate_parameters 3 , +.Xr DSA_get0_pqg 3 , +.Xr DSA_get_ex_new_index 3 , +.Xr DSA_meth_new 3 , +.Xr DSA_print 3 , +.Xr DSA_security_bits 3 , +.Xr DSA_set_method 3 , +.Xr DSA_SIG_new 3 , +.Xr DSA_sign 3 , +.Xr DSA_size 3 , +.Xr EVP_PKEY_set1_DSA 3 , +.Xr RSA_new 3 +.Sh STANDARDS +US Federal Information Processing Standard FIPS 186 (Digital Signature +Standard, DSS), ANSI X9.30 +.Sh HISTORY +.Fn DSA_new +and +.Fn DSA_free +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . +.Pp +.Fn DSA_up_ref +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/DSA_set_method.3 b/Libraries/libressl/man/DSA_set_method.3 new file mode 100644 index 000000000..31ded16d8 --- /dev/null +++ b/Libraries/libressl/man/DSA_set_method.3 @@ -0,0 +1,221 @@ +.\" $OpenBSD: DSA_set_method.3,v 1.10 2022/01/15 23:38:50 jsg Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002, 2007 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt DSA_SET_METHOD 3 +.Os +.Sh NAME +.Nm DSA_set_default_method , +.Nm DSA_get_default_method , +.Nm DSA_set_method , +.Nm DSA_new_method , +.Nm DSA_OpenSSL +.Nd select DSA method +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft void +.Fo DSA_set_default_method +.Fa "const DSA_METHOD *meth" +.Fc +.Ft const DSA_METHOD * +.Fn DSA_get_default_method void +.Ft int +.Fo DSA_set_method +.Fa "DSA *dsa" +.Fa "const DSA_METHOD *meth" +.Fc +.Ft DSA * +.Fo DSA_new_method +.Fa "ENGINE *engine" +.Fc +.Ft DSA_METHOD * +.Fn DSA_OpenSSL void +.Sh DESCRIPTION +A +.Vt DSA_METHOD +object contains pointers to the functions used for DSA operations. +By default, the internal implementation returned by +.Fn DSA_OpenSSL +is used. +By selecting another method, alternative implementations +such as hardware accelerators may be used. +.Pp +.Fn DSA_set_default_method +selects +.Fa meth +as the default method for all +.Vt DSA +structures created later. +If any +.Vt ENGINE +was registered with +.Xr ENGINE_register_DSA 3 +that can be successfully initialized, it overrides the default. +.Pp +.Fn DSA_get_default_method +returns a pointer to the current default method, +even if it is actually overridden by an +.Vt ENGINE . +.Pp +.Fn DSA_set_method +selects +.Fa meth +to perform all operations using the key +.Fa dsa . +This replaces the +.Vt DSA_METHOD +used by the DSA key and if the previous method was supplied by an +.Vt ENGINE , +.Xr ENGINE_finish 3 +is called on it. +It is possible to have DSA keys that only work with certain +.Vt DSA_METHOD +implementations (e.g. from an +.Vt ENGINE +module that supports embedded hardware-protected keys), +and in such cases attempting to change the +.Vt DSA_METHOD +for the key can have unexpected results. +.Pp +.Fn DSA_new_method +allocates and initializes a +.Vt DSA +structure so that +.Fa engine +is used for the DSA operations. +If +.Fa engine +is +.Dv NULL , +.Xr ENGINE_get_default_DSA 3 +is used. +If that returns +.Dv NULL , +the default method controlled by +.Fn DSA_set_default_method +is used. +.Pp +The +.Vt DSA_METHOD +structure is defined as follows: +.Bd -literal +struct +{ + /* name of the implementation */ + const char *name; + + /* sign */ + DSA_SIG *(*dsa_do_sign)(const unsigned char *dgst, int dlen, + DSA *dsa); + + /* pre-compute k^-1 and r */ + int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + + /* verify */ + int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + + /* compute rr = a1^p1 * a2^p2 mod m (May be NULL for some + implementations) */ + int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont); + + /* compute r = a ^ p mod m (May be NULL for some implementations) */ + int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); + + /* called at DSA_new */ + int (*init)(DSA *DSA); + + /* called at DSA_free */ + int (*finish)(DSA *DSA); + + int flags; + + char *app_data; /* ?? */ + +} DSA_METHOD; +.Ed +.Sh RETURN VALUES +.Fn DSA_OpenSSL +and +.Fn DSA_get_default_method +return pointers to the respective +.Vt DSA_METHOD . +.Pp +.Fn DSA_set_method +returns 1 on success or 0 on failure. +Currently, it cannot fail. +.Pp +.Fn DSA_new_method +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 +if the allocation fails. +Otherwise it returns a pointer to the newly allocated structure. +.Sh SEE ALSO +.Xr DSA_meth_new 3 , +.Xr DSA_new 3 , +.Xr ENGINE_get_default_DSA 3 , +.Xr ENGINE_register_DSA 3 , +.Xr ENGINE_set_default_DSA 3 +.Sh HISTORY +.Fn DSA_set_default_method , +.Fn DSA_get_default_method , +.Fn DSA_set_method , +.Fn DSA_new_method , +and +.Fn DSA_OpenSSL +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/DSA_sign.3 b/Libraries/libressl/man/DSA_sign.3 new file mode 100644 index 000000000..59f9042ba --- /dev/null +++ b/Libraries/libressl/man/DSA_sign.3 @@ -0,0 +1,173 @@ +.\" $OpenBSD: DSA_sign.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt DSA_SIGN 3 +.Os +.Sh NAME +.Nm DSA_sign , +.Nm DSA_sign_setup , +.Nm DSA_verify +.Nd DSA signatures +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft int +.Fo DSA_sign +.Fa "int type" +.Fa "const unsigned char *dgst" +.Fa "int len" +.Fa "unsigned char *sigret" +.Fa "unsigned int *siglen" +.Fa "DSA *dsa" +.Fc +.Ft int +.Fo DSA_sign_setup +.Fa "DSA *dsa" +.Fa "BN_CTX *ctx" +.Fa "BIGNUM **kinvp" +.Fa "BIGNUM **rp" +.Fc +.Ft int +.Fo DSA_verify +.Fa "int type" +.Fa "const unsigned char *dgst" +.Fa "int len" +.Fa "unsigned char *sigbuf" +.Fa "int siglen" +.Fa "DSA *dsa" +.Fc +.Sh DESCRIPTION +.Fn DSA_sign +computes a digital signature on the +.Fa len +byte message digest +.Fa dgst +using the private key +.Fa dsa +and places its ASN.1 DER encoding at +.Fa sigret . +The length of the signature is placed in +.Pf * Fa siglen . +.Fa sigret +must point to +.Fn DSA_size dsa +bytes of memory. +.Pp +.Fn DSA_sign_setup +may be used to precompute part of the signing operation in case +signature generation is time-critical. +It expects +.Fa dsa +to contain DSA parameters. +It places the precomputed values in newly allocated +.Vt BIGNUM Ns s +at +.Pf * Fa kinvp +and +.Pf * Fa rp , +after freeing the old ones unless +.Fa kinvp +and +.Fa rp +are +.Dv NULL . +These values may be passed to +.Fn DSA_sign +in +.Fa dsa->kinv +and +.Sy dsa->r . +.Fa ctx +is a pre-allocated +.Vt BN_CTX +or +.Dv NULL . +.Pp +.Fn DSA_verify +verifies that the signature +.Fa sigbuf +of size +.Fa siglen +matches a given message digest +.Fa dgst +of size +.Fa len . +.Fa dsa +is the signer's public key. +.Pp +The +.Fa type +parameter is ignored. +.Sh RETURN VALUES +.Fn DSA_sign +and +.Fn DSA_sign_setup +return 1 on success or 0 on error. +.Fn DSA_verify +returns 1 for a valid signature, 0 for an incorrect signature, +and -1 on error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr DSA_do_sign 3 , +.Xr DSA_get0_key 3 , +.Xr DSA_new 3 +.Sh STANDARDS +US Federal Information Processing Standard FIPS 186 (Digital Signature +Standard, DSS), ANSI X9.30 +.Sh HISTORY +.Fn DSA_sign +and +.Fn DSA_verify +first appeared in SSLeay 0.6.0. +.Fn DSA_sign_setup +first appeared in SSLeay 0.8.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/DSA_size.3 b/Libraries/libressl/man/DSA_size.3 new file mode 100644 index 000000000..4786acc7e --- /dev/null +++ b/Libraries/libressl/man/DSA_size.3 @@ -0,0 +1,122 @@ +.\" $OpenBSD: DSA_size.3,v 1.8 2022/07/13 21:44:23 schwarze Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller +.\" and Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt DSA_SIZE 3 +.Os +.Sh NAME +.Nm DSA_size , +.Nm DSA_bits +.Nd get DSA signature or key size +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft int +.Fo DSA_size +.Fa "const DSA *dsa" +.Fc +.Ft int +.Fo DSA_bits +.Fa "const DSA *dsa" +.Fc +.Sh DESCRIPTION +.Fn DSA_size +returns the maximum size of an ASN.1 encoded DSA signature for the key +.Fa dsa +in bytes. +It can be used to determine how much memory must be allocated for a DSA +signature. +.Pp +.Fa dsa->q +must not be +.Dv NULL . +.Pp +.Fn DSA_bits +returns the number of significant bits in the public domain parameter +.Fa p +contained in +.Fa dsa . +This is also the number of bits in the public key. +.Sh RETURN VALUES +.Fn DSA_size +returns the size of the signature in bytes. +.Pp +.Fn DSA_bits +returns the size of the public key in bits. +.Sh SEE ALSO +.Xr DSA_get0_pqg 3 , +.Xr DSA_new 3 , +.Xr DSA_security_bits 3 , +.Xr DSA_sign 3 +.Sh HISTORY +.Fn DSA_size +first appeared in SSLeay 0.6.0 and has been available since +.Ox 2.4 . +.Pp +.Fn DSA_bits +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/DTLSv1_listen.3 b/Libraries/libressl/man/DTLSv1_listen.3 new file mode 100644 index 000000000..047ec0a7f --- /dev/null +++ b/Libraries/libressl/man/DTLSv1_listen.3 @@ -0,0 +1,187 @@ +.\" $OpenBSD: DTLSv1_listen.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 7795475f Dec 18 13:18:31 2015 -0500 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt DTLSV1_LISTEN 3 +.Os +.Sh NAME +.Nm DTLSv1_listen +.Nd listen for incoming DTLS connections +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo DTLSv1_listen +.Fa "SSL *ssl" +.Fa "struct sockaddr *peer" +.Fc +.Sh DESCRIPTION +.Fn DTLSv1_listen +listens for new incoming DTLS connections. +If a ClientHello is received that does not contain a cookie, then +.Fn DTLSv1_listen +responds with a HelloVerifyRequest. +If a ClientHello is received with a cookie that is verified, then +control is returned to user code to enable the handshake to be +completed (for example by using +.Xr SSL_accept 3 ) . +.Pp +.Fn DTLSv1_listen +is currently implemented as a macro. +.Pp +Datagram based protocols can be susceptible to Denial of Service +attacks. +A DTLS attacker could, for example, submit a series of handshake +initiation requests that cause the server to allocate state (and +possibly perform cryptographic operations) thus consuming server +resources. +The attacker could also (with UDP) quite simply forge the source IP +address in such an attack. +.Pp +As a counter measure to that DTLS includes a stateless cookie mechanism. +The idea is that when a client attempts to connect to a server it sends +a ClientHello message. +The server responds with a HelloVerifyRequest which contains a unique +cookie. +The client then resends the ClientHello, but this time includes the +cookie in the message thus proving that the client is capable of +receiving messages sent to that address. +All of this can be done by the server without allocating any state, and +thus without consuming expensive resources. +.Pp +OpenSSL implements this capability via the +.Fn DTLSv1_listen +function. +The +.Fa ssl +parameter should be a newly allocated +.Vt SSL +object with its read and write BIOs set, in the same way as might +be done for a call to +.Xr SSL_accept 3 . +Typically the read BIO will be in an "unconnected" state and thus +capable of receiving messages from any peer. +.Pp +When a ClientHello is received that contains a cookie that has been +verified, then +.Fn DTLSv1_listen +will return with the +.Fa ssl +parameter updated into a state where the handshake can be continued by a +call to (for example) +.Xr SSL_accept 3 . +Additionally the +.Vt struct sockaddr +pointed to by +.Fa peer +will be filled in with details of the peer that sent the ClientHello. +It is the calling code's responsibility to ensure that the +.Fa peer +location is sufficiently large to accommodate the addressing scheme in use. +For example this might be done by allocating space for a +.Vt struct sockaddr_storage +and casting the pointer to it to a +.Vt struct sockaddr * +for the call to +.Fn DTLSv1_listen . +Typically user code is expected to "connect" the underlying socket +to the peer and continue the handshake in a connected state. +.Pp +Prior to calling +.Fn DTLSv1_listen +user code must ensure that cookie generation and verification callbacks +have been set up using +.Fn SSL_CTX_set_cookie_generate_cb +and +.Fn SSL_CTX_set_cookie_verify_cb +respectively. +.Pp +Since +.Fn DTLSv1_listen +operates entirely statelessly whilst processing incoming ClientHellos, +it is unable to process fragmented messages (since this would require +the allocation of state). +An implication of this is that +.Fn DTLSv1_listen +only supports ClientHellos that fit inside a single datagram. +.Sh RETURN VALUES +From OpenSSL 1.1.0 a return value of >= 1 indicates success. +In this instance the +.Fa peer +value will be filled in and the +.Fa ssl +object set up ready to continue the handshake. +.Pp +A return value of 0 indicates a non-fatal error. +This could (for example) be because of non-blocking IO, or some invalid +message having been received from a peer. +Errors may be placed on the OpenSSL error queue with further information +if appropriate. +Typically user code is expected to retry the call to +.Fn DTLSv1_listen +in the event of a non-fatal error. +Any old errors on the error queue will be cleared in the subsequent +call. +.Pp +A return value of <0 indicates a fatal error. +This could (for example) be because of a failure to allocate sufficient +memory for the operation. +.Pp +Prior to OpenSSL 1.1.0 fatal and non-fatal errors both produce return +codes <= 0 (in typical implementations user code treats all errors as +non-fatal), whilst return codes >0 indicate success. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_get_error 3 +.Sh HISTORY +.Fn DTLSv1_listen +first appeared in OpenSSL 0.9.8m and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/ECDH_compute_key.3 b/Libraries/libressl/man/ECDH_compute_key.3 new file mode 100644 index 000000000..c49988e14 --- /dev/null +++ b/Libraries/libressl/man/ECDH_compute_key.3 @@ -0,0 +1,88 @@ +.\" $OpenBSD: ECDH_compute_key.3,v 1.3 2023/08/29 10:07:42 tb Exp $ +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 29 2023 $ +.Dt ECDH_COMPUTE_KEY 3 +.Os +.Sh NAME +.Nm ECDH_compute_key , +.Nm ECDH_size +.Nd Elliptic Curve Diffie-Hellman key exchange +.Sh SYNOPSIS +.In openssl/ec.h +.Ft int +.Fo ECDH_compute_key +.Fa "void *out" +.Fa "size_t outlen" +.Fa "const EC_POINT *public_key" +.Fa "EC_KEY *ecdh" +.Fa "void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)" +.Fc +.Ft int +.Fo ECDH_size +.Fa "const EC_KEY *ecdh" +.Fc +.Sh DESCRIPTION +.Fn ECDH_compute_key +performs Elliptic Curve Diffie-Hellman key agreement. +It combines the private key contained in +.Fa ecdh +with the other party's +.Fa public_key , +takes the +.Fa x +component of the affine coordinates, +and optionally applies the key derivation function +.Fa KDF . +It stores the resulting symmetric key in the buffer +.Fa out , +which is +.Fa outlen +bytes long. +If +.Fa KDF +is +.Dv NULL , +.Fa outlen +must be at least +.Fn ECDH_size ecdh . +.Pp +.Fn ECDH_size +returns the number of bytes needed to store an affine coordinate of a +point on the elliptic curve used by +.Fa ecdh , +which is one eighth of the degree of the finite field underlying +that elliptic curve, rounded up to the next integer number. +.Sh RETURN VALUES +.Fn ECDH_compute_key +returns the length of the computed key in bytes or -1 if an error occurs. +.Pp +.Fn ECDH_size +returns the number of bytes needed to store an affine coordinate. +.Sh SEE ALSO +.Xr DH_generate_key 3 , +.Xr DH_size 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_new 3 , +.Xr EC_POINT_new 3 , +.Xr X25519 3 +.Sh HISTORY +.Fn ECDH_compute_key +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Pp +.Fn ECDH_size +first appeared in +.Ox 6.1 . diff --git a/Libraries/libressl/man/ECDSA_SIG_new.3 b/Libraries/libressl/man/ECDSA_SIG_new.3 new file mode 100644 index 000000000..c9ef8e814 --- /dev/null +++ b/Libraries/libressl/man/ECDSA_SIG_new.3 @@ -0,0 +1,452 @@ +.\" $OpenBSD: ECDSA_SIG_new.3,v 1.20 2023/08/29 10:07:42 tb Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" selective merge up to: OpenSSL da4ea0cf Aug 5 16:13:24 2019 +0100 +.\" +.\" This file was written by Nils Larsch . +.\" Copyright (c) 2004, 2005, 2013, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 29 2023 $ +.Dt ECDSA_SIG_NEW 3 +.Os +.Sh NAME +.Nm ECDSA_SIG_new , +.Nm ECDSA_SIG_free , +.Nm ECDSA_SIG_get0 , +.Nm ECDSA_SIG_get0_r , +.Nm ECDSA_SIG_get0_s , +.Nm ECDSA_SIG_set0 , +.Nm i2d_ECDSA_SIG , +.Nm d2i_ECDSA_SIG , +.Nm ECDSA_size , +.Nm ECDSA_sign , +.Nm ECDSA_verify , +.Nm ECDSA_do_sign , +.Nm ECDSA_do_verify +.Nd Elliptic Curve Digital Signature Algorithm +.Sh SYNOPSIS +.In openssl/ec.h +.Ft ECDSA_SIG* +.Fo ECDSA_SIG_new +.Fa void +.Fc +.Ft void +.Fo ECDSA_SIG_free +.Fa "ECDSA_SIG *sig" +.Fc +.Ft void +.Fo ECDSA_SIG_get0 +.Fa "const ECDSA_SIG *sig" +.Fa "const BIGNUM **r" +.Fa "const BIGNUM **s" +.Fc +.Ft "const BIGNUM *" +.Fo ECDSA_SIG_get0_r +.Fa "const ECDSA_SIG *sig" +.Fc +.Ft "const BIGNUM *" +.Fo ECDSA_SIG_get0_s +.Fa "const ECDSA_SIG *sig" +.Fc +.Ft int +.Fo ECDSA_SIG_set0 +.Fa "ECDSA_SIG *sig" +.Fa "BIGNUM *r" +.Fa "BIGNUM *s" +.Fc +.Ft int +.Fo i2d_ECDSA_SIG +.Fa "const ECDSA_SIG *sig_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ECDSA_SIG* +.Fo d2i_ECDSA_SIG +.Fa "ECDSA_SIG **sig_out" +.Fa "const unsigned char **der_in" +.Fa "long len" +.Fc +.Ft int +.Fo ECDSA_size +.Fa "const EC_KEY *eckey" +.Fc +.Ft int +.Fo ECDSA_sign +.Fa "int type" +.Fa "const unsigned char *dgst" +.Fa "int dgstlen" +.Fa "unsigned char *sig" +.Fa "unsigned int *siglen" +.Fa "EC_KEY *eckey" +.Fc +.Ft int +.Fo ECDSA_verify +.Fa "int type" +.Fa "const unsigned char *dgst" +.Fa "int dgstlen" +.Fa "const unsigned char *sig" +.Fa "int siglen" +.Fa "EC_KEY *eckey" +.Fc +.Ft ECDSA_SIG* +.Fo ECDSA_do_sign +.Fa "const unsigned char *dgst" +.Fa "int dgst_len" +.Fa "EC_KEY *eckey" +.Fc +.Ft int +.Fo ECDSA_do_verify +.Fa "const unsigned char *dgst" +.Fa "int dgst_len" +.Fa "const ECDSA_SIG *sig" +.Fa "EC_KEY* eckey" +.Fc +.Sh DESCRIPTION +These functions provide a low level interface to ECDSA. +Most applications should use the higher level EVP interface such as +.Xr EVP_DigestSignInit 3 +or +.Xr EVP_DigestVerifyInit 3 +instead. +Creation of the required +.Vt EC_KEY +objects is described in +.Xr EC_KEY_new 3 . +.Pp +The +.Vt ECDSA_SIG +structure consists of two +.Vt BIGNUM Ns s +for the +.Fa r +and +.Fa s +value of an ECDSA signature (see X9.62 or FIPS 186-2). +.Bd -literal -offset indent +struct { + BIGNUM *r; + BIGNUM *s; +} ECDSA_SIG; +.Ed +.Pp +.Fn ECDSA_SIG_new +allocates a new +.Vt ECDSA_SIG +structure (note: this function also allocates the +.Vt BIGNUM Ns s ) +and initializes it. +.Pp +.Fn ECDSA_SIG_free +frees the +.Vt ECDSA_SIG +structure +.Fa sig . +.Pp +.Fn ECDSA_SIG_get0 +retrieves internal pointers the +.Fa r +and +.Fa s +values contained in +.Fa sig . +The values +.Fa r +and +.Fa s +can also be retrieved separately by the corresponding function +.Fn ECDSA_SIG_get0_r +and +.Fn ECDSA_SIG_get0_s , +respectively. +.Pp +.Fn ECDSA_SIG_set0 +sets the +.Fa r +and +.Fa s +values in +.Fa sig . +Calling this function transfers the memory management of the values to +.Fa sig . +Therefore, the values that have been passed in +should not be freed by the caller. +.Pp +.Fn i2d_ECDSA_SIG +creates the DER encoding of the ECDSA signature +.Fa sig_in +and writes the encoded signature to +.Pf * Fa der_out . +.Fn d2i_ECDSA_SIG +decodes the DER-encoded signature stored in the buffer +.Pf * Fa der_in +which is +.Fa len +bytes long into +.Pf * Fa sig_out . +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn ECDSA_size +returns the maximum length of a DER-encoded ECDSA signature created with +the private EC key +.Fa eckey . +.Pp +.Fn ECDSA_sign +computes a digital signature of the +.Fa dgstlen +bytes hash value +.Fa dgst +using the private EC key +.Fa eckey . +The DER-encoded signature is stored in +.Fa sig +and its length is returned in +.Fa siglen . +Note: +.Fa sig +must point to +.Fn ECDSA_size +bytes of memory. +The parameter +.Fa type +is ignored. +.Pp +.Fn ECDSA_verify +verifies that the signature in +.Fa sig +of size +.Fa siglen +is a valid ECDSA signature of the hash value +.Fa dgst +of size +.Fa dgstlen +using the public key +.Fa eckey . +The parameter +.Fa type +is ignored. +.Pp +.Fn ECDSA_do_sign +computes a digital signature of the +.Fa dgst_len +bytes hash value +.Fa dgst +using the private key +.Fa eckey . +The signature is returned in a newly allocated +.Vt ECDSA_SIG +structure (or +.Dv NULL +on error). +.Pp +.Fn ECDSA_do_verify +verifies that the signature +.Fa sig +is a valid ECDSA signature of the hash value +.Fa dgst +of size +.Fa dgst_len +using the public key +.Fa eckey . +.Sh RETURN VALUES +.Fn ECDSA_SIG_new +returns the new +.Vt ECDSA_SIG +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_ECDSA_SIG +returns the number of bytes successfully encoded +or a negative value if an error occurs. +.Pp +.Fn d2i_ECDSA_SIG +returns a pointer to the decoded +.Vt ECDSA_SIG +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn ECDSA_size +returns the maximum length signature or 0 on error. +.Pp +.Fn ECDSA_SIG_get0_r +and +.Fn ECDSA_SIG_get0_s +return a pointer owned by the +.Vt ECDSA_SIG +object if it has been set or +.Dv NULL +otherwise. +.Pp +.Fn ECDSA_SIG_set0 +and +.Fn ECDSA_sign +return 1 if successful or 0 on error. +.Pp +.Fn ECDSA_do_sign +returns a pointer to an allocated +.Vt ECDSA_SIG +structure or +.Dv NULL +on error. +.Pp +.Fn ECDSA_verify +and +.Fn ECDSA_do_verify +return 1 for a valid signature, 0 for an invalid signature and -1 on +error. +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh EXAMPLES +Creating an ECDSA signature of given SHA-1 hash value using the named +curve secp192k1. +.Pp +First step: create an +.Vt EC_KEY +object. +This part is +.Em not +ECDSA specific. +.Bd -literal -offset indent +int ret; +ECDSA_SIG *sig; +EC_KEY *eckey; + +eckey = EC_KEY_new_by_curve_name(NID_secp192k1); +if (eckey == NULL) { + /* error */ +} +if (!EC_KEY_generate_key(eckey)) { + /* error */ +} +.Ed +.Pp +Second step: compute the ECDSA signature of a SHA-1 hash value using +.Fn ECDSA_do_sign +.Bd -literal -offset indent +sig = ECDSA_do_sign(digest, 20, eckey); +if (sig == NULL) { + /* error */ +} +.Ed +.Pp +or using +.Fn ECDSA_sign +.Bd -literal -offset indent +unsigned char *buffer, *pp; +int buf_len; + +buf_len = ECDSA_size(eckey); +buffer = malloc(buf_len); +pp = buffer; +if (!ECDSA_sign(0, dgst, dgstlen, pp, &buf_len, eckey) { + /* error */ +} +.Ed +.Pp +Third step: verify the created ECDSA signature using +.Fn ECDSA_do_verify +.Pp +.Dl ret = ECDSA_do_verify(digest, 20, sig, eckey); +.Pp +or using +.Fn ECDSA_verify +.Pp +.Dl ret = ECDSA_verify(0, digest, 20, buffer, buf_len, eckey); +.Pp +and finally evaluate the return value: +.Bd -literal -offset indent +if (ret == -1) { + /* error */ +} else if (ret == 0) { + /* incorrect signature */ +} else { + /* ret == 1 */ + /* signature ok */ +} +.Ed +.Sh SEE ALSO +.Xr crypto 3 , +.Xr d2i_ECPKParameters 3 , +.Xr DSA_new 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_METHOD_new 3 , +.Xr EC_KEY_new 3 , +.Xr EC_KEY_set_ex_data 3 , +.Xr EVP_DigestSignInit 3 , +.Xr EVP_DigestVerifyInit 3 , +.Xr RSA_new 3 +.Sh STANDARDS +ANSI X9.62, US Federal Information Processing Standard FIPS 186-5 +(Digital Signature Standard, DSS) +.Sh HISTORY +.Fn ECDSA_SIG_new , +.Fn ECDSA_SIG_free , +.Fn i2d_ECDSA_SIG , +.Fn d2i_ECDSA_SIG , +.Fn ECDSA_size , +.Fn ECDSA_sign , +.Fn ECDSA_verify , +.Fn ECDSA_do_sign , +and +.Fn ECDSA_do_verify +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn ECDSA_SIG_get0 +and +.Fn ECDSA_SIG_set0 +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Fn ECDSA_SIG_get0_r +and +.Fn ECDSA_SIG_get0_s +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.1 . +.Sh AUTHORS +.An Nils Larsch +for the OpenSSL project. diff --git a/Libraries/libressl/man/EC_GFp_simple_method.3 b/Libraries/libressl/man/EC_GFp_simple_method.3 new file mode 100644 index 000000000..fd9f71e7f --- /dev/null +++ b/Libraries/libressl/man/EC_GFp_simple_method.3 @@ -0,0 +1,136 @@ +.\" $OpenBSD: EC_GFp_simple_method.3,v 1.12 2023/04/27 08:47:04 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 27 2023 $ +.Dt EC_GFP_SIMPLE_METHOD 3 +.Os +.Sh NAME +.Nm EC_GFp_simple_method , +.Nm EC_GFp_mont_method , +.Nm EC_METHOD_get_field_type +.Nd obtain EC_METHOD objects +.Sh SYNOPSIS +.In openssl/ec.h +.Ft const EC_METHOD * +.Fn EC_GFp_simple_method void +.Ft const EC_METHOD * +.Fn EC_GFp_mont_method void +.Ft int +.Fo EC_METHOD_get_field_type +.Fa "const EC_METHOD *meth" +.Fc +.Sh DESCRIPTION +The elliptic curve library provides a number of different +implementations through a single common interface. +Each implementation is optimised for different scenarios. +An implementation is represented by an +.Vt EC_METHOD +structure. +.Pp +When constructing a curve using +.Xr EC_GROUP_new 3 , +an implementation method must be provided. +The functions described here all return a const pointer to an +.Sy EC_METHOD +structure that can be passed to +.Xr EC_GROUP_new 3 . +It is important that the correct implementation type for the form +of curve selected is used. +.Pp +For Fp curves the lowest common denominator implementation is the +.Fn EC_GFp_simple_method +implementation. +All other implementations are based on this one. +.Fn EC_GFp_mont_method +adds the use of Montgomery multiplication (see +.Xr BN_mod_mul_montgomery 3 ) . +.Pp +.Fn EC_METHOD_get_field_type +identifies what type of field the +.Vt EC_METHOD +structure supports. +If the field type is Fp, then the value +.Dv NID_X9_62_prime_field +is returned. +If the field type is F2^m, then the value +.Dv NID_X9_62_characteristic_two_field +is returned. +These values are defined in the +.In openssl/objects.h +header file. +.Sh RETURN VALUES +All +.Fn EC_GFp* +functions always return a const pointer to an +.Vt EC_METHOD +structure. +.Pp +.Fn EC_METHOD_get_field_type +returns an integer that identifies the type of field the +.Vt EC_METHOD +structure supports. +.Sh SEE ALSO +.Xr BN_mod_mul_montgomery 3 , +.Xr d2i_ECPKParameters 3 , +.Xr EC_GROUP_copy 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_new 3 , +.Xr EC_POINT_add 3 , +.Xr EC_POINT_new 3 +.Sh HISTORY +.Fn EC_GFp_simple_method +and +.Fn EC_GFp_mont_method +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EC_METHOD_get_field_type +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/EC_GROUP_copy.3 b/Libraries/libressl/man/EC_GROUP_copy.3 new file mode 100644 index 000000000..c83ee3d5b --- /dev/null +++ b/Libraries/libressl/man/EC_GROUP_copy.3 @@ -0,0 +1,512 @@ +.\" $OpenBSD: EC_GROUP_copy.3,v 1.14 2023/06/28 18:07:07 tb Exp $ +.\" full merge up to: OpenSSL d900a015 Oct 8 14:40:42 2015 +0200 +.\" selective merge up to: OpenSSL 24c23e1f Aug 22 10:51:25 2019 +0530 +.\" +.\" This file was written by Matt Caswell , +.\" Dr. Stephen Henson , +.\" and Jayaram X Matta . +.\" Copyright (c) 2013, 2015, 2019 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 28 2023 $ +.Dt EC_GROUP_COPY 3 +.Os +.Sh NAME +.Nm EC_GROUP_copy , +.Nm EC_GROUP_dup , +.Nm EC_GROUP_method_of , +.Nm EC_GROUP_set_generator , +.Nm EC_GROUP_get0_generator , +.Nm EC_GROUP_get_order , +.Nm EC_GROUP_order_bits , +.Nm EC_GROUP_get_cofactor , +.Nm EC_GROUP_set_curve_name , +.Nm EC_GROUP_get_curve_name , +.Nm EC_GROUP_set_asn1_flag , +.Nm EC_GROUP_get_asn1_flag , +.Nm EC_GROUP_set_point_conversion_form , +.Nm EC_GROUP_get_point_conversion_form , +.Nm EC_GROUP_get0_seed , +.Nm EC_GROUP_get_seed_len , +.Nm EC_GROUP_set_seed , +.Nm EC_GROUP_get_degree , +.Nm EC_GROUP_check , +.Nm EC_GROUP_check_discriminant , +.Nm EC_GROUP_cmp , +.Nm EC_GROUP_get_basis_type +.Nd manipulate EC_GROUP objects +.Sh SYNOPSIS +.In openssl/ec.h +.In openssl/bn.h +.Ft int +.Fo EC_GROUP_copy +.Fa "EC_GROUP *dst" +.Fa "const EC_GROUP *src" +.Fc +.Ft EC_GROUP * +.Fo EC_GROUP_dup +.Fa "const EC_GROUP *src" +.Fc +.Ft const EC_METHOD * +.Fo EC_GROUP_method_of +.Fa "const EC_GROUP *group" +.Fc +.Ft int +.Fo EC_GROUP_set_generator +.Fa "EC_GROUP *group" +.Fa "const EC_POINT *generator" +.Fa "const BIGNUM *order" +.Fa "const BIGNUM *cofactor" +.Fc +.Ft const EC_POINT * +.Fo EC_GROUP_get0_generator +.Fa "const EC_GROUP *group" +.Fc +.Ft int +.Fo EC_GROUP_get_order +.Fa "const EC_GROUP *group" +.Fa "BIGNUM *order" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_order_bits +.Fa "const EC_GROUP *group" +.Fc +.Ft int +.Fo EC_GROUP_get_cofactor +.Fa "const EC_GROUP *group" +.Fa "BIGNUM *cofactor" +.Fa "BN_CTX *ctx" +.Fc +.Ft void +.Fo EC_GROUP_set_curve_name +.Fa "EC_GROUP *group" +.Fa "int nid" +.Fc +.Ft int +.Fo EC_GROUP_get_curve_name +.Fa "const EC_GROUP *group" +.Fc +.Ft void +.Fo EC_GROUP_set_asn1_flag +.Fa "EC_GROUP *group" +.Fa "int flag" +.Fc +.Ft int +.Fo EC_GROUP_get_asn1_flag +.Fa "const EC_GROUP *group" +.Fc +.Ft void +.Fo EC_GROUP_set_point_conversion_form +.Fa "EC_GROUP *group" +.Fa "point_conversion_form_t form" +.Fc +.Ft point_conversion_form_t +.Fo EC_GROUP_get_point_conversion_form +.Fa "const EC_GROUP *" +.Fc +.Ft unsigned char * +.Fo EC_GROUP_get0_seed +.Fa "const EC_GROUP *x" +.Fc +.Ft size_t +.Fo EC_GROUP_get_seed_len +.Fa "const EC_GROUP *" +.Fc +.Ft size_t +.Fo EC_GROUP_set_seed +.Fa "EC_GROUP *" +.Fa "const unsigned char *" +.Fa "size_t len" +.Fc +.Ft int +.Fo EC_GROUP_get_degree +.Fa "const EC_GROUP *group" +.Fc +.Ft int +.Fo EC_GROUP_check +.Fa "const EC_GROUP *group" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_check_discriminant +.Fa "const EC_GROUP *group" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_cmp +.Fa "const EC_GROUP *a" +.Fa "const EC_GROUP *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_get_basis_type +.Fa "const EC_GROUP *" +.Fc +.Sh DESCRIPTION +These functions operate on +.Vt EC_GROUP +objects created by the functions described in +.Xr EC_GROUP_new 3 . +.Pp +.Fn EC_GROUP_copy +copies the curve +.Fa src +into +.Fa dst . +Both +.Fa src +and +.Fa dst +must use the same +.Vt EC_METHOD . +.Pp +.Fn EC_GROUP_dup +creates a new +.Vt EC_GROUP +object and copies the content from +.Fa src +to the newly created +.Vt EC_GROUP +object. +.Pp +.Fn EC_GROUP_method_of +obtains the +.Vt EC_METHOD +of +.Fa group . +.Pp +.Fn EC_GROUP_set_generator +sets curve parameters that must be agreed by all participants using +the curve. +These parameters include the +.Fa generator , +the +.Fa order +and the +.Fa cofactor . +The +.Fa generator +is a well defined point on the curve chosen for cryptographic +operations. +Integers used for point multiplications will be between 0 and +.Fa order No - 1 . +The +.Fa order +multiplied by the +.Fa cofactor +gives the number of points on the curve. +.Pp +.Fn EC_GROUP_get0_generator +returns the generator for the identified +.Fa group . +.Pp +.Fn EC_GROUP_get_order +retrieves the order of the +.Fa group +and copies its value into +.Fa order . +It fails if the order of the +.Fa group +is not set or set to zero. +.Pp +.Fn EC_GROUP_get_cofactor +retrieves the cofactor of the +.Fa group +and copies its value into +.Fa cofactor . +It fails if the cofactor of the +.Fa group +is not set or set to zero. +.Pp +The functions +.Fn EC_GROUP_set_curve_name +and +.Fn EC_GROUP_get_curve_name +set and get the NID for the curve, respectively (see +.Xr EC_GROUP_new 3 ) . +If a curve does not have a NID associated with it, then +.Fn EC_GROUP_get_curve_name +will return +.Dv NID_undef . +.Pp +The asn1_flag value is used to determine whether the curve encoding +uses explicit parameters or a named curve using an ASN.1 OID: +many applications only support the latter form. +If asn1_flag is the default value +.Dv OPENSSL_EC_NAMED_CURVE , +then the named curve form is used and the parameters must have a +corresponding named curve NID set. +If asn1_flags is +.Dv OPENSSL_EC_EXPLICIT_CURVE , +the parameters are explicitly encoded. +The functions +.Fn EC_GROUP_get_asn1_flag +and +.Fn EC_GROUP_set_asn1_flag +get and set the status of the asn1_flag for the curve. +.Pp +The point_conversion_form for a curve controls how +.Vt EC_POINT +data is encoded as ASN.1 as defined in X9.62 (ECDSA). +.Vt point_conversion_form_t +is an enum defined as follows: +.Bd -literal +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; +.Ed +.Pp +For +.Dv POINT_CONVERSION_UNCOMPRESSED +the point is encoded as an octet signifying the UNCOMPRESSED form +has been used followed by the octets for x, followed by the octets +for y. +.Pp +For any given x coordinate for a point on a curve it is possible to +derive two possible y values. +For +.Dv POINT_CONVERSION_COMPRESSED +the point is encoded as an octet signifying that the COMPRESSED +form has been used AND which of the two possible solutions for y +has been used, followed by the octets for x. +.Pp +For +.Dv POINT_CONVERSION_HYBRID +the point is encoded as an octet signifying the HYBRID form has +been used AND which of the two possible solutions for y has been +used, followed by the octets for x, followed by the octets for y. +.Pp +The functions +.Fn EC_GROUP_set_point_conversion_form +and +.Fn EC_GROUP_get_point_conversion_form +set and get the point_conversion_form for the curve, respectively. +.Pp +ANSI X9.62 (ECDSA standard) defines a method of generating the curve +parameter b from a random number. +This provides advantages in that a parameter obtained in this way is +highly unlikely to be susceptible to special purpose attacks, or have +any trapdoors in it. +If the seed is present for a curve then the b parameter was generated in +a verifiable fashion using that seed. +The OpenSSL EC library does not use this seed value but does enable you +to inspect it using +.Fn EC_GROUP_get0_seed . +This returns a pointer to a memory block containing the seed that was +used. +The length of the memory block can be obtained using +.Fn EC_GROUP_get_seed_len . +A number of the builtin curves within the library provide seed values +that can be obtained. +It is also possible to set a custom seed using +.Fn EC_GROUP_set_seed +and passing a pointer to a memory block, along with the length of +the seed. +Again, the EC library will not use this seed value, although it will be +preserved in any ASN.1 based communications. +.Pp +.Fn EC_GROUP_get_degree +gets the degree of the field. +For Fp fields this will be the number of bits in p. +For F2^m fields this will be the value m. +.Pp +The function +.Fn EC_GROUP_check_discriminant +calculates the discriminant for the curve and verifies that it is +valid. +For a curve defined over Fp the discriminant is given by the formula +4*a^3 + 27*b^2 whilst for F2^m curves the discriminant is simply b. +In either case for the curve to be valid the discriminant must be +non-zero. +.Pp +The function +.Fn EC_GROUP_check +performs a number of checks on a curve to verify that it is valid. +Checks performed include verifying that the discriminant is non-zero; +that a generator has been defined; that the generator is on the curve +and has the correct order. +.Pp +.Fn EC_GROUP_cmp +compares +.Fa a +and +.Fa b +to determine whether they represent the same curve or not. +.Pp +.Fn EC_GROUP_get_basis_type +always returns 0 and is only provided for compatibility. +.Sh RETURN VALUES +The following functions return 1 on success or 0 on error: +.Fn EC_GROUP_copy , +.Fn EC_GROUP_set_generator , +.Fn EC_GROUP_check , +and +.Fn EC_GROUP_check_discriminant . +.Pp +.Fn EC_GROUP_dup +returns a pointer to the duplicated curve or +.Dv NULL +on error. +.Pp +.Fn EC_GROUP_method_of +returns the +.Vt EC_METHOD +implementation in use for the given curve or +.Dv NULL +on error. +.Pp +.Fn EC_GROUP_get0_generator +returns the generator for the given curve or +.Dv NULL +on error. +.Pp +.Fn EC_GROUP_get_order +returns 0 if the order is not set or set to zero for the +.Fa group +or if copying into +.Fa order +fails, or 1 otherwise. +.Pp +.Fn EC_GROUP_order_bits +returns the number of bits in the group order. +.Pp +.Fn EC_GROUP_get_cofactor +returns 0 if the cofactor is not set or set to zero for the +.Fa group +or if copying into +.Fa cofactor +fails, or 1 otherwise. +.Pp +.Fn EC_GROUP_get_curve_name +returns the curve name (NID) for the +.Fa group +or +.Dv NID_undef +if no curve name is associated. +.Pp +.Fn EC_GROUP_get_asn1_flag +returns the ASN.1 flag for the specified +.Fa group . +.Pp +.Fn EC_GROUP_get_point_conversion_form +returns the point_conversion_form for the +.Fa group . +.Pp +.Fn EC_GROUP_get_degree +returns the degree for the +.Fa group +or 0 if the operation is not supported +by the underlying group implementation. +.Pp +.Fn EC_GROUP_get0_seed +returns a pointer to the seed that was used to generate the parameter +b, or +.Dv NULL +if the seed is not specified. +.Fn EC_GROUP_get_seed_len +returns the length of the seed or 0 if the seed is not specified. +.Pp +.Fn EC_GROUP_set_seed +returns the length of the seed that has been set. +If the supplied seed is +.Dv NULL +or the supplied seed length is 0, the return value will be 1. +On error 0 is returned. +.Pp +.Fn EC_GROUP_cmp +returns 0 if the curves are equal, 1 if they are not equal, +or -1 on error. +.Pp +.Fn EC_GROUP_get_basis_type +always returns 0. +.Sh SEE ALSO +.Xr d2i_ECPKParameters 3 , +.Xr EC_GFp_simple_method 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_new 3 , +.Xr EC_POINT_add 3 , +.Xr EC_POINT_new 3 +.Sh HISTORY +.Fn EC_GROUP_copy , +.Fn EC_GROUP_method_of , +.Fn EC_GROUP_set_generator , +.Fn EC_GROUP_get0_generator , +.Fn EC_GROUP_get_order , +and +.Fn EC_GROUP_get_cofactor +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EC_GROUP_dup , +.Fn EC_GROUP_set_curve_name , +.Fn EC_GROUP_get_curve_name , +.Fn EC_GROUP_set_asn1_flag , +.Fn EC_GROUP_get_asn1_flag , +.Fn EC_GROUP_set_point_conversion_form , +.Fn EC_GROUP_get_point_conversion_form , +.Fn EC_GROUP_get0_seed , +.Fn EC_GROUP_get_seed_len , +.Fn EC_GROUP_set_seed , +.Fn EC_GROUP_get_degree , +.Fn EC_GROUP_check , +.Fn EC_GROUP_check_discriminant , +.Fn EC_GROUP_cmp , +and +.Fn EC_GROUP_get_basis_type +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn EC_GROUP_order_bits +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/EC_GROUP_new.3 b/Libraries/libressl/man/EC_GROUP_new.3 new file mode 100644 index 000000000..7a539eb92 --- /dev/null +++ b/Libraries/libressl/man/EC_GROUP_new.3 @@ -0,0 +1,298 @@ +.\" $OpenBSD: EC_GROUP_new.3,v 1.15 2023/04/27 09:35:20 tb Exp $ +.\" OpenSSL 6328d367 Sat Jul 4 21:58:30 2020 +0200 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 27 2023 $ +.Dt EC_GROUP_NEW 3 +.Os +.Sh NAME +.Nm EC_GROUP_new , +.Nm EC_GROUP_free , +.Nm EC_GROUP_clear_free , +.Nm EC_GROUP_new_curve_GFp , +.Nm EC_GROUP_new_by_curve_name , +.Nm EC_GROUP_set_curve , +.Nm EC_GROUP_get_curve , +.Nm EC_GROUP_set_curve_GFp , +.Nm EC_GROUP_get_curve_GFp , +.Nm EC_get_builtin_curves +.Nd create and destroy EC_GROUP objects +.Sh SYNOPSIS +.In openssl/ec.h +.In openssl/bn.h +.Ft EC_GROUP * +.Fo EC_GROUP_new +.Fa "const EC_METHOD *meth" +.Fc +.Ft void +.Fo EC_GROUP_free +.Fa "EC_GROUP *group" +.Fc +.Ft void +.Fo EC_GROUP_clear_free +.Fa "EC_GROUP *group" +.Fc +.Ft EC_GROUP * +.Fo EC_GROUP_new_curve_GFp +.Fa "const BIGNUM *p" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft EC_GROUP * +.Fo EC_GROUP_new_by_curve_name +.Fa "int nid" +.Fc +.Ft int +.Fo EC_GROUP_set_curve +.Fa "EC_GROUP *group" +.Fa "const BIGNUM *p" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_get_curve +.Fa "const EC_GROUP *group" +.Fa "BIGNUM *p" +.Fa "BIGNUM *a" +.Fa "BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_set_curve_GFp +.Fa "EC_GROUP *group" +.Fa "const BIGNUM *p" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_get_curve_GFp +.Fa "const EC_GROUP *group" +.Fa "BIGNUM *p" +.Fa "BIGNUM *a" +.Fa "BIGNUM *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft size_t +.Fo EC_get_builtin_curves +.Fa "EC_builtin_curve *r" +.Fa "size_t nitems" +.Fc +.Sh DESCRIPTION +The EC library provides functions for performing operations on +elliptic curves over finite fields. +In general, an elliptic curve satisfies an equation of the form: +.Pp +.Dl y^2 = x^3 + ax + b +.Pp +An +.Vt EC_GROUP +structure is used to represent the definition of an elliptic curve. +A new curve can be constructed by calling +.Fn EC_GROUP_new , +using the implementation provided by +.Fa meth +(see +.Xr EC_GFp_simple_method 3 ) . +It is then necessary to call +.Fn EC_GROUP_set_curve +to set the curve parameters. +.Pp +.Fn EC_GROUP_set_curve +sets the curve parameters +.Fa p , +.Fa a , +and +.Fa b , +where +.Fa a +and +.Fa b +represent the coefficients of the curve equation. +.Pp +.Fn EC_GROUP_set_curve_GFp +is a deprecated synonym for +.Fn EC_GROUP_set_curve . +.Pp +.Fn EC_GROUP_get_curve +obtains the previously set curve parameters. +.Pp +.Fn EC_GROUP_get_curve_GFp +is a deprecated synonym for +.Fn EC_GROUP_get_curve . +.Pp +The function +.Fn EC_GROUP_new_curve_GFp +is a shortcut for calling +.Fn EC_GROUP_new +and +.Fn EC_GROUP_set_curve . +An appropriate default implementation method will be used. +.Pp +Whilst the library can be used to create any curve using the functions +described above, there are also a number of predefined curves that are +available. +In order to obtain a list of all of the predefined curves, call the +function +.Fn EC_get_builtin_curves . +The parameter +.Fa r +should be an array of +.Vt EC_builtin_cure +structures of size +.Fa nitems . +The function will populate the +.Fa r +array with information about the builtin curves. +If +.Fa nitems +is less than the total number of curves available, then the first +.Fa nitems +curves will be returned. +Otherwise the total number of curves will be provided. +The return value is the total number of curves available (whether that +number has been populated in +.Fa r +or not). +Passing a +.Dv NULL +.Fa r , +or setting +.Fa nitems +to 0, will do nothing other than return the total number of curves +available. +The +.Vt EC_builtin_curve +structure is defined as follows: +.Bd -literal +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; +.Ed +.Pp +Each +.Vt EC_builtin_curve +item has a unique integer ID +.Pq Fa nid +and a human readable comment string describing the curve. +.Pp +In order to construct a builtin curve, use the function +.Fn EC_GROUP_new_by_curve_name +and provide the +.Fa nid +of the curve to be constructed. +.Pp +.Fn EC_GROUP_free +frees the memory associated with the +.Vt EC_GROUP . +If +.Fa group +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn EC_GROUP_clear_free +destroys any sensitive data held within the +.Vt EC_GROUP +and then frees its memory. +If +.Fa group +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +All +.Fn EC_GROUP_new* +functions return a pointer to the newly constructed group or +.Dv NULL +on error. +.Pp +.Fn EC_get_builtin_curves +returns the number of builtin curves that are available. +.Pp +.Fn EC_GROUP_set_curve , +.Fn EC_GROUP_get_curve , +.Fn EC_GROUP_set_curve_GFp , +and +.Fn EC_GROUP_get_curve_GFp +return 1 on success or 0 on error. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr d2i_ECPKParameters 3 , +.Xr EC_GFp_simple_method 3 , +.Xr EC_GROUP_copy 3 , +.Xr EC_KEY_new 3 , +.Xr EC_POINT_add 3 , +.Xr EC_POINT_new 3 , +.Xr ECDH_compute_key 3 , +.Xr ECDSA_SIG_new 3 +.Sh HISTORY +.Fn EC_GROUP_new , +.Fn EC_GROUP_free , +.Fn EC_GROUP_clear_free , +.Fn EC_GROUP_new_curve_GFp , +.Fn EC_GROUP_set_curve_GFp , +and +.Fn EC_GROUP_get_curve_GFp +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EC_GROUP_new_by_curve_name , +and +.Fn EC_get_builtin_curves +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Fn EC_GROUP_set_curve +and +.Fn EC_GROUP_get_curve +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/EC_KEY_METHOD_new.3 b/Libraries/libressl/man/EC_KEY_METHOD_new.3 new file mode 100644 index 000000000..489bd3ac6 --- /dev/null +++ b/Libraries/libressl/man/EC_KEY_METHOD_new.3 @@ -0,0 +1,322 @@ +.\" $OpenBSD: EC_KEY_METHOD_new.3,v 1.3 2023/08/29 10:07:42 tb Exp $ +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 29 2023 $ +.Dt EC_KEY_METHOD_NEW 3 +.Os +.Sh NAME +.Nm EC_KEY_METHOD_new , +.Nm EC_KEY_METHOD_free , +.Nm EC_KEY_METHOD_set_init , +.Nm EC_KEY_METHOD_get_init , +.Nm EC_KEY_METHOD_set_sign , +.Nm EC_KEY_METHOD_get_sign , +.Nm EC_KEY_METHOD_set_verify , +.Nm EC_KEY_METHOD_get_verify , +.Nm EC_KEY_METHOD_set_keygen , +.Nm EC_KEY_METHOD_get_keygen , +.Nm EC_KEY_METHOD_set_compute_key , +.Nm EC_KEY_METHOD_get_compute_key , +.Nm EC_KEY_OpenSSL , +.Nm EC_KEY_set_default_method , +.Nm EC_KEY_get_default_method , +.Nm EC_KEY_new_method , +.Nm EC_KEY_set_method , +.Nm EC_KEY_get_method +.Nd custom EC_KEY implementations +.Sh SYNOPSIS +.In openssl/ec.h +.Ft EC_KEY_METHOD * +.Fo EC_KEY_METHOD_new +.Fa "const EC_KEY_METHOD *meth" +.Fc +.Ft void +.Fo EC_KEY_METHOD_free +.Fa "EC_KEY_METHOD *meth" +.Fc +.Ft void +.Fo EC_KEY_METHOD_set_init +.Fa "EC_KEY_METHOD *meth" +.Fa "int (*init)(EC_KEY *key)" +.Fa "void (*finish)(EC_KEY *key)" +.Fa "int (*copy)(EC_KEY *dest, const EC_KEY *src)" +.Fa "int (*set_group)(EC_KEY *key, const EC_GROUP *grp)" +.Fa "int (*set_private)(EC_KEY *key, const BIGNUM *priv_key)" +.Fa "int (*set_public)(EC_KEY *key, const EC_POINT *pub_key)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_get_init +.Fa "const EC_KEY_METHOD *meth" +.Fa "int (**pinit)(EC_KEY *key)" +.Fa "void (**pfinish)(EC_KEY *key)" +.Fa "int (**pcopy)(EC_KEY *dest, const EC_KEY *src)" +.Fa "int (**pset_group)(EC_KEY *key, const EC_GROUP *grp)" +.Fa "int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key)" +.Fa "int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_set_sign +.Fa "EC_KEY_METHOD *meth" +.Fa "int (*sign)(int type, const unsigned char *dgst, int dgstlen,\ + unsigned char *sig, unsigned int *siglen,\ + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)" +.Fa "int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx,\ + BIGNUM **kinv, BIGNUM **rp)" +.Fa "ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen,\ + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_get_sign +.Fa "const EC_KEY_METHOD *meth" +.Fa "int (**psign)(int type, const unsigned char *dgst, int dgstlen,\ + unsigned char *sig, unsigned int *siglen,\ + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)" +.Fa "int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx,\ + BIGNUM **kinv, BIGNUM **rp)" +.Fa "ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, int dgstlen,\ + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_set_verify +.Fa "EC_KEY_METHOD *meth" +.Fa "int (*verify)(int type, const unsigned char *dgst, int dgst_len,\ + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)" +.Fa "int (*verify_sig)(const unsigned char *dgst, int dgst_len,\ + const ECDSA_SIG *sig, EC_KEY *eckey)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_get_verify +.Fa "const EC_KEY_METHOD *meth" +.Fa "int (**pverify)(int type, const unsigned char *dgst, int dgst_len,\ + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)" +.Fa "int (**pverify_sig)(const unsigned char *dgst, int dgst_len,\ + const ECDSA_SIG *sig, EC_KEY *eckey)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_set_keygen +.Fa "EC_KEY_METHOD *meth" +.Fa "int (*keygen)(EC_KEY *key)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_get_keygen +.Fa "const EC_KEY_METHOD *meth" +.Fa "int (**pkeygen)(EC_KEY *key)" +.Fc +.Ft void +.Fo EC_KEY_METHOD_set_compute_key +.Fa "EC_KEY_METHOD *meth" +.Fa "int (*ckey)(void *out, size_t outlen,\ + const EC_POINT *pub_key, EC_KEY *ecdh,\ + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))" +.Fc +.Ft void +.Fo EC_KEY_METHOD_get_compute_key +.Fa "const EC_KEY_METHOD *meth" +.Fa "int (**pck)(void *out, size_t outlen,\ + const EC_POINT *pub_key, EC_KEY *ecdh,\ + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))" +.Fc +.Ft const EC_KEY_METHOD * +.Fn EC_KEY_OpenSSL void +.Ft void +.Fo EC_KEY_set_default_method +.Fa "const EC_KEY_METHOD *meth" +.Fc +.Ft const EC_KEY_METHOD * +.Fn EC_KEY_get_default_method void +.Ft EC_KEY * +.Fo EC_KEY_new_method +.Fa "ENGINE *engine" +.Fc +.Ft int +.Fo EC_KEY_set_method +.Fa "EC_KEY *key" +.Fa "const EC_KEY_METHOD *meth" +.Fc +.Ft const EC_KEY_METHOD * +.Fo EC_KEY_get_method +.Fa "const EC_KEY *key" +.Fc +.Sh DESCRIPTION +An +.Vt EC_KEY_METHOD +object holds function pointers used for +.Vt EC_KEY +operations. +.Pp +.Fn EC_KEY_METHOD_new +creates a shallow copy of +.Fa meth , +or an empty +.Vt EC_KEY_METHOD +object if +.Fa meth +is +.Dv NULL . +.Pp +.Fn EC_KEY_METHOD_free +frees +.Fa meth . +If +.Fa meth +is +.Dv NULL +or the return value of +.Fn EC_KEY_OpenSSL , +no action occurs. +.Pp +.Fn EC_KEY_METHOD_set_init +and +.Fn EC_KEY_METHOD_get_init +set and retrieve optional callback functions called at the following places: +.Pp +.Bl -tag -width set_private -compact +.It Fa init +at the end of +.Fn EC_KEY_new_method +and +.Fn EC_KEY_set_method +.It Fa finish +at the beginning of +.Xr EC_KEY_free 3 , +.Xr EC_KEY_copy 3 , +and +.Fn EC_KEY_set_method +.It Fa copy +at the end of +.Xr EC_KEY_copy 3 +.It Fa set_group +at the end of +.Xr EC_KEY_set_group 3 +and +.Xr EC_KEY_new_by_curve_name 3 +.It Fa set_private +at the beginning of +.Xr EC_KEY_set_private_key 3 +.It Fa set_public +at the beginning of +.Xr EC_KEY_set_public_key 3 +.El +.Pp +If any of these callbacks returns 0, the calling function fails. +By default, all these callbacks are +.Dv NULL . +Arguments of +.Fn EC_KEY_METHOD_get_init +can be set to +.Dv NULL +to selectively retrieve callback function pointers. +.Pp +.Fn EC_KEY_METHOD_set_sign +and +.Fn EC_KEY_METHOD_get_sign +set and retrieve the functions implementing +.Xr ECDSA_sign 3 +and +.Xr ECDSA_do_sign 3 . +.Pp +.Fn EC_KEY_METHOD_set_verify +and +.Fn EC_KEY_METHOD_get_verify +set and retrieve the functions implementing +.Xr ECDSA_verify 3 +and +.Xr ECDSA_do_verify 3 . +.Pp +.Fn EC_KEY_METHOD_set_keygen +and +.Fn EC_KEY_METHOD_get_keygen +set and retrieve the function implementing +.Xr EC_KEY_generate_key 3 . +.Pp +.Fn EC_KEY_METHOD_set_compute_key +and +.Fn EC_KEY_METHOD_get_compute_key +set and retrieve the function implementing +.Xr ECDH_compute_key 3 . +.Pp +.Fn EC_KEY_set_default_method +chooses the +.Fa meth +to be used for the creation of new +.Vt EC_KEY +objects by future invocations of +.Fn EC_KEY_new_method , +or reverts to the default implementation if +.Fa meth +is +.Dv NULL . +.Pp +.Fn EC_KEY_new_method +creates and initializes a new +.Vt EC_KEY +object using the given +.Fa engine , +or the using the +.Vt EC_KEY_METHOD +set with +.Fn EC_KEY_set_default_method +if +.Fa engine +is +.Dv NULL , +or using the default EC_KEY implementation by default. +.Pp +.Fn EC_KEY_set_method +dissociates the +.Fa key +from the +.Vt ENGINE +it is using, if any, and causes it to use +.Fa meth +in the future. +.Sh RETURN VALUES +.Fn EC_KEY_METHOD_new +returns the newly allocated +.Vt EC_KEY_METHOD +object or +.Dv NULL +if an error occurs. +.Pp +.Fn EC_KEY_OpenSSL +returns a static object representing the default EC_KEY implementation. +.Pp +.Fn EC_KEY_get_default_method +returns the +.Vt EC_KEY_METHOD +that +.Fn EC_KEY_new_method +will use for the creation of new +.Vt EC_KEY +objects in the future. +.Pp +.Fn EC_KEY_new_method +returns the newly allocated +.Vt EC_KEY +object or NULL if an error occurs. +.Pp +.Fn EC_KEY_set_method +returns 1 for success or 0 for failure. +.Pp +.Fn EC_KEY_get_method +returns the EC_KEY implementation used by the given +.Fa key . +.Sh SEE ALSO +.Xr EC_KEY_new 3 , +.Xr ECDSA_sign 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/EC_KEY_new.3 b/Libraries/libressl/man/EC_KEY_new.3 new file mode 100644 index 000000000..06afdd537 --- /dev/null +++ b/Libraries/libressl/man/EC_KEY_new.3 @@ -0,0 +1,529 @@ +.\" $OpenBSD: EC_KEY_new.3,v 1.18 2023/08/29 10:07:42 tb Exp $ +.\" full merge up to: OpenSSL 3aef36ff Jan 5 13:06:03 2016 -0500 +.\" partial merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2013, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 29 2023 $ +.Dt EC_KEY_NEW 3 +.Os +.Sh NAME +.Nm EC_KEY_new , +.Nm EC_KEY_get_flags , +.Nm EC_KEY_set_flags , +.Nm EC_KEY_clear_flags , +.Nm EC_KEY_new_by_curve_name , +.Nm EC_KEY_free , +.Nm EC_KEY_copy , +.Nm EC_KEY_dup , +.Nm EC_KEY_up_ref , +.Nm EC_KEY_get0_group , +.Nm EC_KEY_set_group , +.Nm EC_KEY_get0_private_key , +.Nm EC_KEY_set_private_key , +.Nm EC_KEY_get0_public_key , +.Nm EC_KEY_set_public_key , +.Nm EC_KEY_get_enc_flags , +.Nm EC_KEY_set_enc_flags , +.Nm EC_KEY_get_conv_form , +.Nm EC_KEY_set_conv_form , +.Nm EC_KEY_set_asn1_flag , +.Nm EC_KEY_precompute_mult , +.Nm EC_KEY_generate_key , +.Nm EC_KEY_check_key , +.Nm EC_KEY_set_public_key_affine_coordinates , +.Nm EC_KEY_print , +.Nm EC_KEY_print_fp +.Nd create, destroy and manipulate EC_KEY objects +.Sh SYNOPSIS +.In openssl/ec.h +.In openssl/bn.h +.Ft EC_KEY * +.Fn EC_KEY_new void +.Ft int +.Fo EC_KEY_get_flags +.Fa "const EC_KEY *key" +.Fc +.Ft void +.Fo EC_KEY_set_flags +.Fa "EC_KEY *key" +.Fa "int flags" +.Fc +.Ft void +.Fo EC_KEY_clear_flags +.Fa "EC_KEY *key" +.Fa "int flags" +.Fc +.Ft EC_KEY * +.Fo EC_KEY_new_by_curve_name +.Fa "int nid" +.Fc +.Ft void +.Fo EC_KEY_free +.Fa "EC_KEY *key" +.Fc +.Ft EC_KEY * +.Fo EC_KEY_copy +.Fa "EC_KEY *dst" +.Fa "const EC_KEY *src" +.Fc +.Ft EC_KEY * +.Fo EC_KEY_dup +.Fa "const EC_KEY *src" +.Fc +.Ft int +.Fo EC_KEY_up_ref +.Fa "EC_KEY *key" +.Fc +.Ft const EC_GROUP * +.Fo EC_KEY_get0_group +.Fa "const EC_KEY *key" +.Fc +.Ft int +.Fo EC_KEY_set_group +.Fa "EC_KEY *key" +.Fa "const EC_GROUP *group" +.Fc +.Ft const BIGNUM * +.Fo EC_KEY_get0_private_key +.Fa "const EC_KEY *key" +.Fc +.Ft int +.Fo EC_KEY_set_private_key +.Fa "EC_KEY *key" +.Fa "const BIGNUM *prv" +.Fc +.Ft const EC_POINT * +.Fo EC_KEY_get0_public_key +.Fa "const EC_KEY *key" +.Fc +.Ft int +.Fo EC_KEY_set_public_key +.Fa "EC_KEY *key" +.Fa "const EC_POINT *pub" +.Fc +.Ft unsigned int +.Fo EC_KEY_get_enc_flags +.Fa "const EC_KEY *key" +.Fc +.Ft void +.Fo EC_KEY_set_enc_flags +.Fa "EC_KEY *key" +.Fa "unsigned int flags" +.Fc +.Ft point_conversion_form_t +.Fo EC_KEY_get_conv_form +.Fa "const EC_KEY *key" +.Fc +.Ft void +.Fo EC_KEY_set_conv_form +.Fa "EC_KEY *key" +.Fa "point_conversion_form_t cform" +.Fc +.Ft void +.Fo EC_KEY_set_asn1_flag +.Fa "EC_KEY *key" +.Fa "int asn1_flag" +.Fc +.Ft int +.Fo EC_KEY_precompute_mult +.Fa "EC_KEY *key" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_KEY_generate_key +.Fa "EC_KEY *key" +.Fc +.Ft int +.Fo EC_KEY_check_key +.Fa "const EC_KEY *key" +.Fc +.Ft int +.Fo EC_KEY_set_public_key_affine_coordinates +.Fa "EC_KEY *key" +.Fa "BIGNUM *x" +.Fa "BIGNUM *y" +.Fc +.Ft int +.Fo EC_KEY_print +.Fa "BIO *bp" +.Fa "const EC_KEY *key" +.Fa "int off" +.Fc +.Ft int +.Fo EC_KEY_print_fp +.Fa "FILE *fp" +.Fa "const EC_KEY *key" +.Fa "int off" +.Fc +.Sh DESCRIPTION +An +.Vt EC_KEY +represents a public key and (optionally) an associated private key. +The public key is a point on a curve represented by an +.Vt EC_POINT , +see +.Xr EC_POINT_new 3 . +The private key is simply a +.Vt BIGNUM , +see +.Xr BN_new 3 . +.Pp +A new +.Vt EC_KEY +(with no associated curve) can be constructed by calling +.Fn EC_KEY_new . +The reference count for the newly created +.Vt EC_KEY +is initially set to 1. +A curve can be associated with the +.Vt EC_KEY +by calling +.Fn EC_KEY_set_group . +.Pp +Alternatively a new +.Vt EC_KEY +can be constructed by calling +.Fn EC_KEY_new_by_curve_name +and supplying the +.Fa nid +of the associated curve. +Refer to +.Xr EC_GROUP_new 3 +for a description of curve names. +This function simply wraps calls to +.Fn EC_KEY_new +and +.Fn EC_GROUP_new_by_curve_name . +.Pp +Calling +.Fn EC_KEY_free +decrements the reference count for the +.Vt EC_KEY +object and, if it has dropped to zero, then frees the memory associated +with it. +If +.Fa key +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn EC_KEY_copy +copies the contents of the +.Vt EC_KEY +in +.Fa src +into +.Fa dst . +.Pp +.Fn EC_KEY_dup +creates a new +.Vt EC_KEY +object and copies +.Fa src +into it. +.Pp +.Fn EC_KEY_up_ref +increments the reference count associated with the +.Vt EC_KEY +object. +.Pp +.Fn EC_KEY_generate_key +generates a new public and private key for the supplied +.Fa key +object. +.Fa key +must have an +.Vt EC_GROUP +object associated with it before calling this function. +The private key is a random integer (0 < priv_key < order, where order +is the order of the +.Vt EC_GROUP +object). +The public key is an +.Vt EC_POINT +on the curve calculated by multiplying the generator for the curve +by the private key. +.Pp +.Fn EC_KEY_check_key +performs various sanity checks on the +.Vt EC_KEY +object to confirm that it is valid. +.Pp +.Fn EC_KEY_set_public_key_affine_coordinates +sets the public key for +.Fa key +based on its affine coordinates, i.e. it constructs an +.Vt EC_POINT +object based on the supplied +.Fa x +and +.Fa y +values and sets the public key to be this +.Vt EC_POINT . +It also performs certain sanity checks on the key to confirm that +it is valid. +.Pp +The functions +.Fn EC_KEY_get0_group , +.Fn EC_KEY_set_group , +.Fn EC_KEY_get0_private_key , +.Fn EC_KEY_set_private_key , +.Fn EC_KEY_get0_public_key , +and +.Fn EC_KEY_set_public_key +get and set the +.Vt EC_GROUP +object, the private key and the +.Vt EC_POINT +public key for the +.Fa key , +respectively. +.Pp +The functions +.Fn EC_KEY_get_enc_flags +and +.Fn EC_KEY_set_enc_flags +get and set the value of the encoding flags for the +.Fa key . +There are two encoding flags currently defined: +.Dv EC_PKEY_NO_PARAMETERS +and +.Dv EC_PKEY_NO_PUBKEY . +These flags define the behaviour of how the +.Fa key +is converted into ASN.1 in a call to +.Fn i2d_ECPrivateKey . +If +.Dv EC_PKEY_NO_PARAMETERS +is set then the public parameters for the curve +are not encoded along with the private key. +If +.Dv EC_PKEY_NO_PUBKEY +is set then the public key is not encoded along with the private +key. +.Pp +The format of the external representation of the public key written by +.Xr i2d_ECPrivateKey 3 , +such as whether it is stored in a compressed form or not, +is described by the point_conversion_form. +See +.Xr EC_GROUP_copy 3 +for a description of point_conversion_form. +.Pp +When reading a private key encoded without an associated public key, +for example if +.Dv EC_PKEY_NO_PUBKEY +was used, +.Xr d2i_ECPrivateKey 3 +generates the missing public key automatically. +Private keys encoded without parameters, for example if +.Dv EC_PKEY_NO_PARAMETERS +was used, cannot be loaded using +.Xr d2i_ECPrivateKey 3 . +.Pp +The functions +.Fn EC_KEY_get_conv_form +and +.Fn EC_KEY_set_conv_form +get and set the point_conversion_form for the +.Fa key . +For a description of point_conversion_form please refer to +.Xr EC_GROUP_copy 3 . +.Pp +.Fn EC_KEY_set_flags +sets the flags in the +.Fa flags +parameter on the +.Vt EC_KEY +object. +Any flags that are already set are left set. +The currently defined standard flags are +.Dv EC_FLAG_NON_FIPS_ALLOW +and +.Dv EC_FLAG_FIPS_CHECKED . +In addition there is the ECDH-specific flag +.Dv EC_FLAG_COFACTOR_ECDH . +.Fn EC_KEY_get_flags +returns the current flags that are set for this +.Vt EC_KEY . +.Fn EC_KEY_clear_flags +clears the flags indicated by the +.Fa flags +parameter. +All other flags are left in their existing state. +.Pp +.Fn EC_KEY_set_asn1_flag +sets the asn1_flag on the underlying +.Vt EC_GROUP +object (if set). +Refer to +.Xr EC_GROUP_copy 3 +for further information on the asn1_flag. +.Pp +.Fn EC_KEY_precompute_mult +stores multiples of the underlying +.Vt EC_GROUP +generator for faster point multiplication. +See also +.Xr EC_POINT_add 3 . +.Pp +.Fn EC_KEY_print +and +.Fn EC_KEY_print_fp +print out the content of +.Fa key +to the +.Vt BIO +.Fa bp +or to the +.Vt FILE +pointer +.Fa fp , +respectively. +Each line is indented by +.Fa indent +spaces. +.Sh RETURN VALUES +.Fn EC_KEY_new , +.Fn EC_KEY_new_by_curve_name , +and +.Fn EC_KEY_dup +return a pointer to the newly created +.Vt EC_KEY object +or +.Dv NULL +on error. +.Pp +.Fn EC_KEY_get_flags +returns the flags associated with the +.Vt EC_KEY object . +.Pp +.Fn EC_KEY_copy +returns a pointer to the destination key or +.Dv NULL +on error. +In the latter case, part of the content may already have been copied. +.Pp +.Fn EC_KEY_up_ref , +.Fn EC_KEY_set_group , +.Fn EC_KEY_set_private_key , +.Fn EC_KEY_set_public_key , +.Fn EC_KEY_precompute_mult , +.Fn EC_KEY_generate_key , +.Fn EC_KEY_check_key , +.Fn EC_KEY_set_public_key_affine_coordinates , +.Fn EC_KEY_print , +and +.Fn EC_KEY_print_fp +return 1 on success or 0 on error. +.Pp +.Fn EC_KEY_get0_group +returns the +.Vt EC_GROUP +associated with the +.Vt EC_KEY . +.Pp +.Fn EC_KEY_get0_private_key +and +.Fn EC_KEY_get0_public_key +return the private or public keys, respectively, associated with the +.Vt EC_KEY . +.Pp +.Fn EC_KEY_get_enc_flags +returns the value of the current encoding flags for the +.Vt EC_KEY . +.Pp +.Fn EC_KEY_get_conv_form +returns the point_conversion_form for the +.Vt EC_KEY . +.Sh SEE ALSO +.Xr d2i_ECPKParameters 3 , +.Xr EC_GFp_simple_method 3 , +.Xr EC_GROUP_copy 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_METHOD_new 3 , +.Xr EC_POINT_add 3 , +.Xr EC_POINT_new 3 , +.Xr ECDH_compute_key 3 , +.Xr ECDSA_SIG_new 3 , +.Xr EVP_PKEY_set1_EC_KEY 3 +.Sh HISTORY +.Fn EC_KEY_new , +.Fn EC_KEY_new_by_curve_name , +.Fn EC_KEY_free , +.Fn EC_KEY_copy , +.Fn EC_KEY_dup , +.Fn EC_KEY_up_ref , +.Fn EC_KEY_get0_group , +.Fn EC_KEY_set_group , +.Fn EC_KEY_get0_private_key , +.Fn EC_KEY_set_private_key , +.Fn EC_KEY_get0_public_key , +.Fn EC_KEY_set_public_key , +.Fn EC_KEY_get_enc_flags , +.Fn EC_KEY_set_enc_flags , +.Fn EC_KEY_get_conv_form , +.Fn EC_KEY_set_conv_form , +.Fn EC_KEY_set_asn1_flag , +.Fn EC_KEY_precompute_mult , +.Fn EC_KEY_generate_key , +.Fn EC_KEY_check_key , +.Fn EC_KEY_print , +and +.Fn EC_KEY_print_fp +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn EC_KEY_get_flags , +.Fn EC_KEY_set_flags , +.Fn EC_KEY_clear_flags , +and +.Fn EC_KEY_set_public_key_affine_coordinates +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/EC_POINT_add.3 b/Libraries/libressl/man/EC_POINT_add.3 new file mode 100644 index 000000000..6c19f6d27 --- /dev/null +++ b/Libraries/libressl/man/EC_POINT_add.3 @@ -0,0 +1,309 @@ +.\" $OpenBSD: EC_POINT_add.3,v 1.12 2023/04/12 09:55:22 jsg Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 12 2023 $ +.Dt EC_POINT_ADD 3 +.Os +.Sh NAME +.Nm EC_POINT_add , +.Nm EC_POINT_dbl , +.Nm EC_POINT_invert , +.Nm EC_POINT_is_at_infinity , +.Nm EC_POINT_is_on_curve , +.Nm EC_POINT_cmp , +.Nm EC_POINT_make_affine , +.Nm EC_POINTs_make_affine , +.Nm EC_POINTs_mul , +.Nm EC_POINT_mul , +.Nm EC_GROUP_precompute_mult , +.Nm EC_GROUP_have_precompute_mult +.Nd perform mathematical operations and tests on EC_POINT objects +.Sh SYNOPSIS +.In openssl/ec.h +.In openssl/bn.h +.Ft int +.Fo EC_POINT_add +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *r" +.Fa "const EC_POINT *a" +.Fa "const EC_POINT *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_dbl +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *r" +.Fa "const EC_POINT *a" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_invert +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *a" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_is_at_infinity +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *p" +.Fc +.Ft int +.Fo EC_POINT_is_on_curve +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *point" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_cmp +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *a" +.Fa "const EC_POINT *b" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_make_affine +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *point" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINTs_make_affine +.Fa "const EC_GROUP *group" +.Fa "size_t num" +.Fa "EC_POINT *points[]" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINTs_mul +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *r" +.Fa "const BIGNUM *n" +.Fa "size_t num" +.Fa "const EC_POINT *p[]" +.Fa "const BIGNUM *m[]" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_mul +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *r" +.Fa "const BIGNUM *n" +.Fa "const EC_POINT *q" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_precompute_mult +.Fa "EC_GROUP *group" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_GROUP_have_precompute_mult +.Fa "const EC_GROUP *group" +.Fc +.Sh DESCRIPTION +These functions operate on +.Vt EC_POINT +objects created by +.Xr EC_POINT_new 3 . +.Pp +.Fn EC_POINT_add +adds the two points +.Fa a +and +.Fa b +and places the result in +.Fa r . +Similarly +.Fn EC_POINT_dbl +doubles the point +.Fa a +and places the result in +.Fa r . +In both cases it is valid for +.Fa r +to be one of +.Fa a +or +.Fa b . +.Pp +.Fn EC_POINT_invert +calculates the inverse of the supplied point +.Fa a . +The result is placed back in +.Fa a . +.Pp +The function +.Fn EC_POINT_is_at_infinity +tests whether the supplied point is at infinity or not. +.Pp +.Fn EC_POINT_is_on_curve +tests whether the supplied point is on the curve or not. +.Pp +.Fn EC_POINT_cmp +compares the two supplied points and tests whether or not they are +equal. +.Pp +The functions +.Fn EC_POINT_make_affine +and +.Fn EC_POINTs_make_affine +force the internal representation of the +.Vt EC_POINT Ns s +into the affine coordinate system. +In the case of +.Fn EC_POINTs_make_affine , +the value +.Fa num +provides the number of points in the array +.Fa points +to be forced. +.Pp +.Fn EC_POINT_mul +calculates the value +.Pp +.D1 generator * n + q * m +.Pp +and stores the result in +.Fa r . +The value +.Fa n +may be +.Dv NULL , +in which case the result is just +.Pp +.Dl q * m. +.Pp +.Fn EC_POINTs_mul +only supports the values 0 and 1 for +.Fa num . +If it is 1, then +.Fn EC_POINTs_mul +calculates the value +.Pp +.Dl generator * n + q[0] * m[0]. +.Pp +If +.Fa num +is 0 then +.Fa q +and +.Fa m +must be +.Dv NULL , +and the result is just +.Pp +.Dl generator * n . +.Pp +As for +.Fn EC_POINT_mul , +the value +.Fa n +may be +.Dv NULL . +.Pp +The function +.Fn EC_GROUP_precompute_mult +stores multiples of the generator for faster point multiplication, +whilst +.Fn EC_GROUP_have_precompute_mult +tests whether precomputation has already been done. +See +.Xr EC_GROUP_copy 3 +for information about the generator. +.Sh RETURN VALUES +The following functions return 1 on success or 0 on error: +.Fn EC_POINT_add , +.Fn EC_POINT_dbl , +.Fn EC_POINT_invert , +.Fn EC_POINT_make_affine , +.Fn EC_POINTs_make_affine , +.Fn EC_POINT_mul , +.Fn EC_POINTs_mul , +and +.Fn EC_GROUP_precompute_mult . +.Pp +.Fn EC_POINT_is_at_infinity +returns 1 if the point is at infinity or 0 otherwise. +.Pp +.Fn EC_POINT_is_on_curve +returns 1 if the point is on the curve, 0 if not, or -1 on error. +.Pp +.Fn EC_POINT_cmp +returns 1 if the points are not equal, 0 if they are, or -1 on error. +.Pp +.Fn EC_GROUP_have_precompute_mult +returns 1 if a precomputation has been done or 0 if not. +.Sh SEE ALSO +.Xr d2i_ECPKParameters 3 , +.Xr EC_GFp_simple_method 3 , +.Xr EC_GROUP_copy 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_new 3 , +.Xr EC_POINT_new 3 +.Sh HISTORY +.Fn EC_POINT_add , +.Fn EC_POINT_dbl , +.Fn EC_POINT_invert , +.Fn EC_POINT_is_at_infinity , +.Fn EC_POINT_is_on_curve , +.Fn EC_POINT_cmp , +.Fn EC_POINT_make_affine , +.Fn EC_POINTs_make_affine , +.Fn EC_POINTs_mul , +.Fn EC_POINT_mul , +and +.Fn EC_GROUP_precompute_mult +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EC_GROUP_have_precompute_mult +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/EC_POINT_new.3 b/Libraries/libressl/man/EC_POINT_new.3 new file mode 100644 index 000000000..decfd3383 --- /dev/null +++ b/Libraries/libressl/man/EC_POINT_new.3 @@ -0,0 +1,526 @@ +.\" $OpenBSD: EC_POINT_new.3,v 1.14 2023/04/27 09:39:52 tb Exp $ +.\" full merge up to: OpenSSL 50db8163 Jul 30 16:56:41 2018 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2013, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 27 2023 $ +.Dt EC_POINT_NEW 3 +.Os +.Sh NAME +.Nm EC_POINT_new , +.Nm EC_POINT_free , +.Nm EC_POINT_clear_free , +.Nm EC_POINT_copy , +.Nm EC_POINT_dup , +.Nm EC_POINT_method_of , +.Nm EC_POINT_set_to_infinity , +.Nm EC_POINT_set_affine_coordinates , +.Nm EC_POINT_set_affine_coordinates_GFp , +.Nm EC_POINT_get_affine_coordinates , +.Nm EC_POINT_get_affine_coordinates_GFp , +.Nm EC_POINT_set_Jprojective_coordinates_GFp , +.Nm EC_POINT_get_Jprojective_coordinates_GFp , +.Nm EC_POINT_set_compressed_coordinates , +.Nm EC_POINT_set_compressed_coordinates_GFp , +.Nm EC_POINT_point2oct , +.Nm EC_POINT_oct2point , +.Nm EC_POINT_point2bn , +.Nm EC_POINT_bn2point , +.Nm EC_POINT_point2hex , +.Nm EC_POINT_hex2point +.Nd create, destroy, and manipulate EC_POINT objects +.Sh SYNOPSIS +.In openssl/ec.h +.In openssl/bn.h +.Ft EC_POINT * +.Fo EC_POINT_new +.Fa "const EC_GROUP *group" +.Fc +.Ft void +.Fo EC_POINT_free +.Fa "EC_POINT *point" +.Fc +.Ft void +.Fo EC_POINT_clear_free +.Fa "EC_POINT *point" +.Fc +.Ft int +.Fo EC_POINT_copy +.Fa "EC_POINT *dst" +.Fa "const EC_POINT *src" +.Fc +.Ft EC_POINT * +.Fo EC_POINT_dup +.Fa "const EC_POINT *src" +.Fa "const EC_GROUP *group" +.Fc +.Ft const EC_METHOD * +.Fo EC_POINT_method_of +.Fa "const EC_POINT *point" +.Fc +.Ft int +.Fo EC_POINT_set_to_infinity +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *point" +.Fc +.Ft int +.Fo EC_POINT_set_affine_coordinates +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *p" +.Fa "const BIGNUM *x" +.Fa "const BIGNUM *y" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_set_affine_coordinates_GFp +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *p" +.Fa "const BIGNUM *x" +.Fa "const BIGNUM *y" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_get_affine_coordinates +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *p" +.Fa "BIGNUM *x" +.Fa "BIGNUM *y" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_get_affine_coordinates_GFp +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *p" +.Fa "BIGNUM *x" +.Fa "BIGNUM *y" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_set_Jprojective_coordinates_GFp +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *p" +.Fa "const BIGNUM *x" +.Fa "const BIGNUM *y" +.Fa "const BIGNUM *z" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_get_Jprojective_coordinates_GFp +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *p" +.Fa "BIGNUM *x" +.Fa "BIGNUM *y" +.Fa "BIGNUM *z" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_set_compressed_coordinates +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *p" +.Fa "const BIGNUM *x" +.Fa "int y_bit" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_set_compressed_coordinates_GFp +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *p" +.Fa "const BIGNUM *x" +.Fa "int y_bit" +.Fa "BN_CTX *ctx" +.Fc +.Ft size_t +.Fo EC_POINT_point2oct +.Fa "const EC_GROUP *group" +.Fa "const EC_POINT *p" +.Fa "point_conversion_form_t form" +.Fa "unsigned char *buf" +.Fa "size_t len" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo EC_POINT_oct2point +.Fa "const EC_GROUP *group" +.Fa "EC_POINT *p" +.Fa "const unsigned char *buf" +.Fa "size_t len" +.Fa "BN_CTX *ctx" +.Fc +.Ft BIGNUM * +.Fo EC_POINT_point2bn +.Fa "const EC_GROUP *" +.Fa "const EC_POINT *" +.Fa "point_conversion_form_t form" +.Fa "BIGNUM *" +.Fa "BN_CTX *" +.Fc +.Ft EC_POINT * +.Fo EC_POINT_bn2point +.Fa "const EC_GROUP *" +.Fa "const BIGNUM *" +.Fa "EC_POINT *" +.Fa "BN_CTX *" +.Fc +.Ft char * +.Fo EC_POINT_point2hex +.Fa "const EC_GROUP *" +.Fa "const EC_POINT *" +.Fa "point_conversion_form_t form" +.Fa "BN_CTX *" +.Fc +.Ft EC_POINT * +.Fo EC_POINT_hex2point +.Fa "const EC_GROUP *" +.Fa "const char *" +.Fa "EC_POINT *" +.Fa "BN_CTX *" +.Fc +.Sh DESCRIPTION +An +.Vt EC_POINT +represents a point on a curve. +A curve is represented by an +.Vt EC_GROUP +object created by the functions described in +.Xr EC_GROUP_new 3 . +.Pp +A new point is constructed by calling the function +.Fn EC_POINT_new +and providing the +.Fa group +object that the point relates to. +.Pp +.Fn EC_POINT_free +frees the memory associated with the +.Vt EC_POINT . +If +.Fa point +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn EC_POINT_clear_free +destroys any sensitive data held within the +.Vt EC_POINT +and then frees its memory. +If +.Fa point +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn EC_POINT_copy +copies the point +.Fa src +into +.Fa dst . +Both +.Fa src +and +.Fa dst +must use the same +.Vt EC_METHOD . +.Pp +.Fn EC_POINT_dup +creates a new +.Vt EC_POINT +object and copies the content from +.Fa src +to the newly created +.Vt EC_POINT +object. +.Pp +.Fn EC_POINT_method_of +obtains the +.Vt EC_METHOD +associated with +.Fa point . +.Pp +A valid point on a curve is the special point at infinity. +A point is set to be at infinity by calling +.Fn EC_POINT_set_to_infinity . +.Pp +The affine coordinates for a point describe a point in terms of its +.Fa x +and +.Fa y +position. +The function +.Fn EC_POINT_set_affine_coordinates +sets the +.Fa x +and +.Fa y +coordinates for the point +.Fa p +defined over the curve given in +.Fa group . +The function +.Fn EC_POINT_get_affine_coordinates +sets +.Fa x +and +.Fa y , +either of which may be +.Dv NULL , +to the corresponding coordinates of +.Fa p . +.Pp +The functions +.Fn EC_POINT_set_affine_coordinates_GFp +is a deprecated synonym for +.Fn EC_POINT_set_affine_coordinates +and the function +.Fn EC_POINT_get_affine_coordinates_GFp +is a deprecated synonym for +.Fn EC_POINT_get_affine_coordinates . +.Pp +As well as the affine coordinates, a point can alternatively be +described in terms of its Jacobian projective coordinates. +Jacobian projective coordinates are expressed as three values +.Fa x , +.Fa y , +and +.Fa z . +Working in this coordinate system provides more efficient point +multiplication operations. +A mapping exists between Jacobian projective coordinates and affine +coordinates. +A Jacobian projective coordinate +.Pq Fa x , y , z +can be written as an affine coordinate as +.Pp +.Dl (x/(z^2), y/(z^3)) . +.Pp +Conversion to Jacobian projective from affine coordinates is simple. +The coordinate +.Pq Fa x , y +is mapped to +.Pq Fa x , y , No 1 . +To set or get the projective coordinates use +.Fn EC_POINT_set_Jprojective_coordinates_GFp +and +.Fn EC_POINT_get_Jprojective_coordinates_GFp , +respectively. +.Pp +Points can also be described in terms of their compressed coordinates. +For a point +.Pq Fa x , y , +for any given value for +.Fa x +such that the point is on the curve, there will only ever be two +possible values for +.Fa y . +Therefore, a point can be set using the +.Fn EC_POINT_set_compressed_coordinates +function where +.Fa x +is the x coordinate and +.Fa y_bit +is a value 0 or 1 to identify which of the two possible values for y +should be used. +.Pp +The functions +.Fn EC_POINT_set_compressed_coordinates_GFp +is a deprecated synonym for +.Fn EC_POINT_set_compressed_coordinates . +.Pp +In addition +.Vt EC_POINT Ns s +can be converted to and from various external representations. +Supported representations are octet strings, +.Vt BIGNUM Ns s , +and hexadecimal. +The format of the external representation is described by the +point_conversion_form. +See +.Xr EC_GROUP_copy 3 +for a description of point_conversion_form. +Octet strings are stored in a buffer along with an associated buffer +length. +A point held in a +.Vt BIGNUM +is calculated by converting the point to an octet string and then +converting that octet string into a +.Vt BIGNUM +integer. +Points in hexadecimal format are stored in a NUL terminated character +string where each character is one of the printable values 0-9 or A-F +(or a-f). +.Pp +The functions +.Fn EC_POINT_point2oct , +.Fn EC_POINT_oct2point , +.Fn EC_POINT_point2bn , +.Fn EC_POINT_bn2point , +.Fn EC_POINT_point2hex , +and +.Fn EC_POINT_hex2point +convert from and to +.Vt EC_POINT Ns s +for the formats octet string, +.Vt BIGNUM , +and hexadecimal, respectively. +.Pp +The function +.Fn EC_POINT_point2oct +must be supplied with a +.Fa buf +long enough to store the octet string. +The return value provides the number of octets stored. +Calling the function with a +.Dv NULL +.Fa buf +will not perform the conversion but will still return the required +buffer length. +.Pp +The function +.Fn EC_POINT_point2hex +will allocate sufficient memory to store the hexadecimal string. +It is the caller's responsibility to free this memory with a subsequent +call to +.Xr free 3 . +.Sh RETURN VALUES +.Fn EC_POINT_new +and +.Fn EC_POINT_dup +return the newly allocated +.Vt EC_POINT +or +.Dv NULL +on error. +.Pp +The following functions return 1 on success or 0 on error: +.Fn EC_POINT_copy , +.Fn EC_POINT_set_to_infinity , +.Fn EC_POINT_set_Jprojective_coordinates_GFp , +.Fn EC_POINT_get_Jprojective_coordinates_GFp , +.Fn EC_POINT_set_affine_coordinates , +.Fn EC_POINT_set_affine_coordinates_GFp , +.Fn EC_POINT_get_affine_coordinates , +.Fn EC_POINT_get_affine_coordinates_GFp , +.Fn EC_POINT_set_compressed_coordinates , +.Fn EC_POINT_set_compressed_coordinates_GFp , +and +.Fn EC_POINT_oct2point . +.Pp +.Fn EC_POINT_method_of +returns the +.Vt EC_METHOD +associated with the supplied +.Vt EC_POINT . +.Pp +.Fn EC_POINT_point2oct +returns the length of the required buffer, or 0 on error. +.Pp +.Fn EC_POINT_point2bn +returns the pointer to the +.Vt BIGNUM +supplied or +.Dv NULL +on error. +.Pp +.Fn EC_POINT_bn2point +returns the pointer to the +.Vt EC_POINT +supplied or +.Dv NULL +on error. +.Pp +.Fn EC_POINT_point2hex +returns a pointer to the hex string or +.Dv NULL +on error. +.Pp +.Fn EC_POINT_hex2point +returns the pointer to the +.Vt EC_POINT +supplied or +.Dv NULL +on error. +.Sh SEE ALSO +.Xr d2i_ECPKParameters 3 , +.Xr EC_GFp_simple_method 3 , +.Xr EC_GROUP_copy 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_new 3 , +.Xr EC_POINT_add 3 , +.Xr ECDH_compute_key 3 +.Sh HISTORY +.Fn EC_POINT_new , +.Fn EC_POINT_free , +.Fn EC_POINT_clear_free , +.Fn EC_POINT_copy , +.Fn EC_POINT_method_of , +.Fn EC_POINT_set_to_infinity , +.Fn EC_POINT_set_affine_coordinates_GFp , +.Fn EC_POINT_get_affine_coordinates_GFp , +.Fn EC_POINT_set_Jprojective_coordinates_GFp , +.Fn EC_POINT_get_Jprojective_coordinates_GFp , +.Fn EC_POINT_set_compressed_coordinates_GFp , +.Fn EC_POINT_point2oct , +and +.Fn EC_POINT_oct2point +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EC_POINT_dup , +.Fn EC_POINT_point2bn , +.Fn EC_POINT_bn2point , +.Fn EC_POINT_point2hex , +and +.Fn EC_POINT_hex2point +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn EC_POINT_set_affine_coordinates , +.Fn EC_POINT_get_affine_coordinates , +and +.Fn EC_POINT_set_compressed_coordinates +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/ENGINE_add.3 b/Libraries/libressl/man/ENGINE_add.3 new file mode 100644 index 000000000..4ae878b4f --- /dev/null +++ b/Libraries/libressl/man/ENGINE_add.3 @@ -0,0 +1,243 @@ +.\" $OpenBSD: ENGINE_add.3,v 1.3 2018/04/18 03:39:22 schwarze Exp $ +.\" content checked up to: OpenSSL 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 18 2018 $ +.Dt ENGINE_ADD 3 +.Os +.Sh NAME +.Nm ENGINE_add , +.Nm ENGINE_set_id , +.Nm ENGINE_get_id , +.Nm ENGINE_set_name , +.Nm ENGINE_get_name , +.Nm ENGINE_remove , +.Nm ENGINE_cleanup , +.Nm ENGINE_get_first , +.Nm ENGINE_get_last , +.Nm ENGINE_get_next , +.Nm ENGINE_get_prev , +.Nm ENGINE_by_id +.Nd maintain a global list of ENGINE objects +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_add +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_id +.Fa "ENGINE *e" +.Fa "const char *id" +.Fc +.Ft const char * +.Fo ENGINE_get_id +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_name +.Fa "ENGINE *e" +.Fa "const char *name" +.Fc +.Ft const char * +.Fo ENGINE_get_name +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_remove +.Fa "ENGINE *e" +.Fc +.Ft void +.Fn ENGINE_cleanup void +.Ft ENGINE * +.Fn ENGINE_get_first void +.Ft ENGINE * +.Fn ENGINE_get_last void +.Ft ENGINE * +.Fo ENGINE_get_next +.Fa "ENGINE *e" +.Fc +.Ft ENGINE * +.Fo ENGINE_get_prev +.Fa "ENGINE *e" +.Fc +.Ft ENGINE * +.Fo ENGINE_by_id +.Fa "const char *id" +.Fc +.Sh DESCRIPTION +The crypto library maintains a global list of +.Vt ENGINE +objects. +.Pp +.Fn ENGINE_add +appends +.Fa e +to the end of the list +and increments its structural reference count by 1. +A unique identifier and a name of +.Fa e +have to be set with +.Fn ENGINE_set_id +and +.Fn ENGINE_set_name +before calling this function. +.Fn ENGINE_add +fails if the list already contains an +.Vt ENGINE +with the same identifier. +.Pp +.Fn ENGINE_remove +removes +.Fa e +from the list. +If successful, it calls +.Xr ENGINE_free 3 +on +.Fa e . +.Pp +.Fn ENGINE_cleanup +calls +.Xr ENGINE_finish 3 +on all +.Vt ENGINE +objects that were selected as default engines, for example using the +functions documented in the +.Xr ENGINE_set_default 3 +and +.Xr ENGINE_get_default_RSA 3 +manual pages, and it calls +.Fn ENGINE_remove +on all +.Vt ENGINE +objects that were added to the global list with +.Fn ENGINE_add . +Calling this function is required at the end of each program using +.Fn ENGINE_add , +even if no engines are explicitly registered or used. +.Pp +.Fn ENGINE_get_first +and +.Fn ENGINE_get_last +provide access to the first and last +.Vt ENGINE +object on the list, respectively. +Unless the list is empty, they increment the structural reference +count of the retrieved object by 1. +.Pp +.Fn ENGINE_get_next +and +.Fn ENGINE_get_prev +support iteration of the list. +They always call +.Xr ENGINE_free 3 +on +.Fa e . +Unless the end of the list is reached, they increment the structural +reference count of the retrieved object by 1. +.Pp +.Fn ENGINE_by_id +searches the list for an +.Vt ENGINE +object with a matching +.Fa id . +If found, it increments the structural reference count of the +retrieved object by 1. +If +.Dv ENGINE_FLAGS_BY_ID_COPY +was set on +.Fa e +with +.Xr ENGINE_set_flags 3 , +it returns a shallow copy of the object rather than incrementing +the reference count and returning a pointer to the original. +.Sh RETURN VALUES +.Fn ENGINE_add , +.Fn ENGINE_set_id , +.Fn ENGINE_set_name , +and +.Fn ENGINE_remove +return 1 on success or 0 on error. +.Fn ENGINE_set_id +and +.Fn ENGINE_set_name +can only fail if the supplied +.Fa id +or +.Fa name +is +.Dv NULL . +.Pp +.Fn ENGINE_get_id +and +.Fn ENGINE_get_name +return a pointer to an internal string +representing the identifier and the name of +.Fa e , +respectively. +.Pp +.Fn ENGINE_get_first +and +.Fn ENGINE_get_last +return an +.Vt ENGINE +object or +.Dv NULL +if the list is empty. +.Pp +.Fn ENGINE_get_next +and +.Fn ENGINE_get_prev +return an +.Vt ENGINE +object or +.Dv NULL +when the end of the list is reached. +.Pp +.Fn ENGINE_by_id +returns an +.Vt ENGINE +object or +.Dv NULL +if no matching object is found. +.Sh SEE ALSO +.Xr ENGINE_get_default_RSA 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_all_RSA 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default 3 , +.Xr ENGINE_set_flags 3 , +.Xr ENGINE_unregister_RSA 3 +.Sh HISTORY +.Fn ENGINE_add , +.Fn ENGINE_set_id , +.Fn ENGINE_get_id , +.Fn ENGINE_set_name , +.Fn ENGINE_get_name , +.Fn ENGINE_remove , +.Fn ENGINE_get_first , +.Fn ENGINE_get_last , +.Fn ENGINE_get_next , +.Fn ENGINE_get_prev , +and +.Fn ENGINE_by_id +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 2.9 . +.Pp +.Fn ENGINE_cleanup +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/ENGINE_ctrl.3 b/Libraries/libressl/man/ENGINE_ctrl.3 new file mode 100644 index 000000000..b4965a5a0 --- /dev/null +++ b/Libraries/libressl/man/ENGINE_ctrl.3 @@ -0,0 +1,470 @@ +.\" $OpenBSD: ENGINE_ctrl.3,v 1.5 2022/01/15 23:38:50 jsg Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt ENGINE_CTRL 3 +.Os +.Sh NAME +.Nm ENGINE_ctrl , +.Nm ENGINE_cmd_is_executable , +.Nm ENGINE_ctrl_cmd , +.Nm ENGINE_ctrl_cmd_string , +.Nm ENGINE_set_ctrl_function , +.Nm ENGINE_get_ctrl_function , +.Nm ENGINE_set_cmd_defns , +.Nm ENGINE_get_cmd_defns +.Nd control commands for ENGINE objects +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_ctrl +.Fa "ENGINE *e" +.Fa "int cmd" +.Fa "long i" +.Fa "void *p" +.Fa "void (*f)(void)" +.Fc +.Ft int +.Fo ENGINE_cmd_is_executable +.Fa "ENGINE *e" +.Fa "int cmd" +.Fc +.Ft int +.Fo ENGINE_ctrl_cmd +.Fa "ENGINE *e" +.Fa "const char *cmd_name" +.Fa "long i" +.Fa "void *p" +.Fa "void (*f)(void)" +.Fa "int cmd_optional" +.Fc +.Ft int +.Fo ENGINE_ctrl_cmd_string +.Fa "ENGINE *e" +.Fa "const char *cmd_name" +.Fa "const char *arg" +.Fa "int cmd_optional" +.Fc +.Ft typedef int +.Fo (*ENGINE_CTRL_FUNC_PTR) +.Fa "ENGINE *e" +.Fa "int cmd" +.Fa "long i" +.Fa "void *p" +.Fa "void (*f)(void)" +.Fc +.Ft int +.Fo ENGINE_set_ctrl_function +.Fa "ENGINE *e" +.Fa "ENGINE_CTRL_FUNC_PTR ctrl_f" +.Fc +.Ft ENGINE_CTRL_FUNC_PTR +.Fo ENGINE_get_ctrl_function +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_cmd_defns +.Fa "ENGINE *e" +.Fa "const ENGINE_CMD_DEFN *defns" +.Fc +.Ft const ENGINE_CMD_DEFN * +.Fo ENGINE_get_cmd_defns +.Fa "const ENGINE *e" +.Fc +.Sh DESCRIPTION +.Fn ENGINE_ctrl +calls the built-in or user-defined +.Fa cmd +for the engine +.Fa e , +passing the arguments +.Fa i +and +.Fa p . +.Pp +User-defined commands can be used before +.Xr ENGINE_init 3 +to provide data required for initialization +or at any time to modify the behaviour of an engine. +.Pp +Most built-in commands operate on user-defined commands installed with +.Fn ENGINE_set_cmd_defns , +either using the +.Fa p +argument to indicate the user-defined command with the command name +.Fa cmd_name +or using the +.Fa i +argument to indicate the user-defined command with the command number +.Fa cmd_num . +The +.Fa cmd +arguments to call the built-in commands are as follows: +.Bl -tag -width Ds +.It Dv ENGINE_CTRL_GET_CMD_FLAGS +Return the +.Fa cmd_flags +of the user-defined command with the number +.Fa i , +or a number less than or equal to 0 if an error occurs or +the command number does not exist. +A return value of 0 indicates failure if +.Fa e +is +.Dv NULL +or has a reference count of 0, or success if +.Fa e +is valid. +.It Dv ENGINE_CTRL_GET_CMD_FROM_NAME +Return the positive command number +of the user-defined command with the name +.Fa p , +or a number less than or equal to 0 if an error occurs or no +matching name is found. +.It Dv ENGINE_CTRL_GET_DESC_FROM_CMD +Copy the description of the user-defined command with the number +.Fa i +into the buffer +.Fa p +and NUL-terminate it. +It is the responsibility of the caller to make sure that the buffer +.Fa p +is large enough, either by calling +.Dv ENGINE_CTRL_GET_DESC_LEN_FROM_CMD +first or using knowledge about the array passed to +.Fn ENGINE_set_cmd_defns . +The return value is the number of bytes written +.Em including +the terminating NUL byte, or a number less than or equal to 0 +if an error occurs. +.It Dv ENGINE_CTRL_GET_DESC_LEN_FROM_CMD +Return the length in bytes +.Em excluding +the terminating NUL byte +of the description of the user-defined command with the number +.Fa i , +or a number less than or equal to 0 if an error occurs. +A return value of 0 indicates failure if +.Fa e +is +.Dv NULL +or has a reference count of 0, or success if +.Fa e +is valid. +.It Dv ENGINE_CTRL_GET_FIRST_CMD_TYPE +Return the positive command number +of the first user-defined command installed with +.Fn ENGINE_set_cmd_defns +or a number less than or equal to 0 if an error occurs or no +user-defined command has been installed. +.It Dv ENGINE_CTRL_GET_NAME_FROM_CMD +Copy the name of the user-defined command with the number +.Fa i +into the buffer +.Fa p +and NUL-terminate it. +It is the responsibility of the caller to make sure that the buffer +.Fa p +is large enough, either by calling +.Dv ENGINE_CTRL_GET_NAME_LEN_FROM_CMD +first or using knowledge about the array passed to +.Fn ENGINE_set_cmd_defns . +The return value is the number of bytes written +.Em including +the terminating NUL byte, or a number less than or equal to 0 +if an error occurs. +.It Dv ENGINE_CTRL_GET_NAME_LEN_FROM_CMD +Return the length in bytes +.Em excluding +the terminating NULL byte +of the name of the user-defined command with the number +.Fa i , +or a number less than or equal to 0 if an error occurs. +A return value of 0 indicates failure if +.Fa e +is +.Dv NULL +or has a reference count of 0, or success if +.Fa e +is valid. +.It Dv ENGINE_CTRL_GET_NEXT_CMD_TYPE +Return the positive command number of the next user-defined command +after the user-defined command with the number +.Fa i , +or a number less than or equal to 0 if an error occurs or if +.Fa i +is the last user-defined command. +Together with +.Dv ENGINE_CTRL_GET_FIRST_CMD_TYPE , +this can be used to iterate the user-defined commands installed with +.Fn ENGINE_set_cmd_defns . +.It Dv ENGINE_CTRL_HAS_CTRL_FUNCTION +Return 1 if +.Fa e +has its own +.Fa ctrl_f +installed with +.Fn ENGINE_set_ctrl_function +or 0 otherwise. +.El +.Pp +.Fn ENGINE_ctrl_cmd +translates the +.Fa cmd_name +of a user-defined command to a +.Fa cmd +number and calls +.Fn ENGINE_ctrl +on it. +If +.Fa cmd_optional +is non-zero, lack of a +.Fa ctrl_f +in +.Fa e +and translation failure with +.Dv ENGINE_CTRL_GET_CMD_FROM_NAME +are considered success, and the command has no effect. +Otherwise, these problems cause +.Fn ENGINE_ctrl_cmd +to fail. +.Pp +Neither +.Fn ENGINE_ctrl +nor +.Fn ENGINE_ctrl_cmd +ever call the +.Fa f +callback, but merely pass it on as an argument to the engine-specific +.Fa ctrl_f +control function. +It is up to +.Fa ctrl_f +how to use it, or alternatively to ignore it as well. +.Pp +.Fn ENGINE_ctrl_cmd_string +translates the +.Fa cmd_name +of a user-defined command to a +.Fa cmd +number. +If that command has the +.Dv ENGINE_CMD_FLAG_NO_INPUT +flag set, +.Fa arg +must be +.Dv NULL +and +.Fn ENGINE_ctrl +is called with +.Fa i +set to 0 and +.Fa p +set to +.Dv NULL . +Otherwise, +.Fa arg +must not be +.Dv NULL . +If the command accepts string input, +.Fa i +is set to 0 and +.Fa arg +is passed as the +.Fa p +argument to +.Fn ENGINE_ctrl . +Otherwise, +.Fa arg +is converted with +.Xr strtol 3 +and passed as the +.Fa i +argument to +.Fn ENGINE_ctrl , +setting +.Fa p +to +.Dv NULL . +.Pp +.Fn ENGINE_set_ctrl_function +installs +.Fa ctrl_f +as the engine-specific control function for +.Fa e . +Future calls to +.Fn ENGINE_ctrl +will call that function, passing on their arguments unchanged, if the +.Fa cmd +is not built-in to the library or if the +.Dv ENGINE_FLAGS_MANUAL_CMD_CTRL +flag is set in +.Fa e . +Let the +.Fa ctrl_f +return positive values on success or negative values on failure. +Avoid return values of 0 because they cause dangerous ambiguity. +In particular, +.Fn ENGINE_ctrl_cmd +and +.Fn ENGINE_ctrl_cmd_string +cannot be used with user-defined commands +that may return 0 on success. +.Pp +.Fn ENGINE_set_cmd_defns +install an array of command definitions in +.Fa e . +.Pp +The structure +.Vt ENGINE_CMD_DEFN +has the following fields: +.Bl -tag -width Ds +.It Fa "unsigned int cmd_num" +A positive, unique, monotonically increasing command number. +Avoid using numbers below +.Dv ENGINE_CMD_BASE . +.It Fa "const char *cmd_name" +The unique name of the command. +.It Fa "const char *cmd_desc" +A short description of the command. +.It Fa "unsigned int cmd_flags" +The bitwise OR of zero or more of the following flags: +.Bl -tag -width Ds +.It Dv ENGINE_CMD_FLAG_NUMERIC +The command uses +.Fa i . +.It Dv ENGINE_CMD_FLAG_STRING +The command uses +.Fa p . +.It Dv ENGINE_CMD_FLAG_NO_INPUT +The command neither uses +.Fa i +nor +.Fa p . +.It Dv ENGINE_CMD_FLAG_INTERNAL +This flag has no effect and is only provided for compatibility. +.El +.El +.Pp +The last element of +.Fa defns +does not specify a command, but must have a +.Fa cmd_num +of 0 and a +.Fa cmd_name +of +.Dv NULL +to indicate the end of the array. +.Sh RETURN VALUES +For +.Fn ENGINE_ctrl , +positive return values indicate success and negative return values +indicate failure. +The meaning of a zero return value depends on the particular +.Fa cmd +and may indicate both success and failure, which is pathetic. +.Pp +Regardless of the +.Fa cmd , +.Fn ENGINE_ctrl +returns 0 if +.Fa e +is +.Dv NULL +or has a reference count of 0. +This is quite unfortunate for commands like +.Dv ENGINE_CTRL_GET_CMD_FLAGS +where 0 may indicate success, so make sure +.Fa e +is valid before issuing a control command. +.Pp +For built-in commands except +.Dv ENGINE_CTRL_HAS_CTRL_FUNCTION , +.Fn ENGINE_ctrl +returns \-1 if +.Dv ENGINE_FLAGS_MANUAL_CMD_CTRL +is set but no +.Fa ctrl_f +has been installed with +.Fn ENGINE_set_ctrl_function . +.Pp +For commands that are not built in, +.Fn ENGINE_ctrl +returns 0 if no +.Fa ctrl_f +has been installed with +.Fn ENGINE_set_ctrl_function . +.Pp +.Fn ENGINE_cmd_is_executable +returns 1 if the user-defined +.Fa cmd +is executable and has at least one of the flags +.Dv ENGINE_CMD_FLAG_NUMERIC , +.Dv ENGINE_CMD_FLAG_STRING , +and +.Dv ENGINE_CMD_FLAG_NO_INPUT +set, or 0 otherwise. +.Pp +.Fn ENGINE_ctrl_cmd +and +.Fn ENGINE_ctrl_cmd_string +return 1 on success or 0 on error. +.Pp +.Fn ENGINE_set_ctrl_function +and +.Fn ENGINE_set_cmd_defns +always return 1. +.Pp +.Fn ENGINE_get_ctrl_function +returns a pointer to the function +.Fa ctrl_f +installed with +.Fn ENGINE_set_ctrl_function , +or +.Dv NULL +if none has been installed. +.Pp +.Fn ENGINE_get_cmd_defns +returns the array of command definitions installed in +.Fa e +or +.Dv NULL +if none is installed. +.Sh SEE ALSO +.Xr ENGINE_add 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_flags 3 , +.Xr ENGINE_set_RSA 3 +.Sh HISTORY +.Fn ENGINE_ctrl , +.Fn ENGINE_set_ctrl_function , +and +.Fn ENGINE_get_ctrl_function +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 2.9 . +.Pp +.Fn ENGINE_cmd_is_executable , +.Fn ENGINE_ctrl_cmd , +.Fn ENGINE_ctrl_cmd_string , +.Fn ENGINE_set_cmd_defns , +and +.Fn ENGINE_get_cmd_defns +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/ENGINE_get_default_RSA.3 b/Libraries/libressl/man/ENGINE_get_default_RSA.3 new file mode 100644 index 000000000..348f13670 --- /dev/null +++ b/Libraries/libressl/man/ENGINE_get_default_RSA.3 @@ -0,0 +1,151 @@ +.\" $OpenBSD: ENGINE_get_default_RSA.3,v 1.4 2023/07/21 04:35:36 tb Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 21 2023 $ +.Dt ENGINE_GET_DEFAULT_RSA 3 +.Os +.Sh NAME +.Nm ENGINE_get_default_RSA , +.Nm ENGINE_get_default_DSA , +.Nm ENGINE_get_default_EC , +.Nm ENGINE_get_default_DH , +.Nm ENGINE_get_default_RAND , +.Nm ENGINE_get_cipher_engine , +.Nm ENGINE_get_digest_engine , +.Nm ENGINE_set_table_flags , +.Nm ENGINE_get_table_flags +.Nd retrieve the default ENGINE for an algorithm +.Sh SYNOPSIS +.In openssl/engine.h +.Ft ENGINE * +.Fn ENGINE_get_default_RSA void +.Ft ENGINE * +.Fn ENGINE_get_default_DSA void +.Ft ENGINE * +.Fn ENGINE_get_default_EC void +.Ft ENGINE * +.Fn ENGINE_get_default_DH void +.Ft ENGINE * +.Fn ENGINE_get_default_RAND void +.Ft ENGINE * +.Fo ENGINE_get_cipher_engine +.Fa "int nid" +.Fc +.Ft ENGINE * +.Fo ENGINE_get_digest_engine +.Fa "int nid" +.Fc +.Ft void +.Fo ENGINE_set_table_flags +.Fa "unsigned int flags" +.Fc +.Ft unsigned int +.Fn ENGINE_get_table_flags void +.Sh DESCRIPTION +These functions retrieve the current default +.Vt ENGINE +implementing the respective algorithm. +.Pp +If a default engine was previously selected, +.Xr ENGINE_init 3 +is called on it again and it is used. +Otherwise, these functions inspect the engines registered +with the functions documented in +.Xr ENGINE_register_RSA 3 +in the order of the table for the respective algorithm. +If an inspected engine is already successfully initialized, +.Xr ENGINE_init 3 +is called on it again and it is used as the new default. +Otherwise, unless the global flag +.Dv ENGINE_TABLE_FLAG_NOINIT +is set, +.Xr ENGINE_init 3 +is tried on it. +If it succeeds, that engine is used as the new default. +If it fails or if +.Dv ENGINE_TABLE_FLAG_NOINIT +is set, inspection continues with the next engine. +.Pp +The global flag can be set by calling +.Fn ENGINE_set_table_flags +with an argument of +.Dv ENGINE_TABLE_FLAG_NOINIT +or cleared by calling it with an argument of 0. +By default, the flag is not set. +.Pp +While all the other functions operate on exactly one algorithm, +.Fn ENGINE_get_cipher_engine +and +.Fn ENGINE_get_digest_engine +are special in so far as they can handle multiple algorithms, +identified by the given +.Fa nid . +The default engine is remembered separately for each algorithm. +.Pp +Application programs rarely need to call these functions because +they are called automatically when needed, in particular from +.Xr RSA_new 3 , +.Xr DSA_new 3 , +.Xr EC_KEY_new 3 , +.Xr DH_new 3 , +.Xr EVP_CipherInit_ex 3 , +and +.Xr EVP_DigestInit_ex 3 . +.Sh RETURN VALUES +These functions return a functional reference to an +.Vt ENGINE +object or +.Dv NULL +on failure, in particular when no engine implementing the algorithm +is available, when +.Xr ENGINE_init 3 +fails for all implementations, +or when insufficient memory is available. +Even when these functions fail, the application may still be able +to use the algorithm in question because the built-in implementation +is used in that case, if one is available. +.Pp +.Fn ENGINE_get_table_flags +returns +.Dv ENGINE_TABLE_FLAG_NOINIT +if the global flag is set or 0 otherwise. +.Sh SEE ALSO +.Xr ENGINE_init 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default 3 +.Sh HISTORY +.Fn ENGINE_get_default_RSA , +.Fn ENGINE_get_default_DSA , +.Fn ENGINE_get_default_DH , +and +.Fn ENGINE_get_default_RAND +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 2.9 . +.Pp +.Fn ENGINE_get_cipher_engine , +.Fn ENGINE_get_digest_engine , +.Fn ENGINE_set_table_flags , +and +.Fn ENGINE_get_table_flags +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_get_default_EC +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/ENGINE_init.3 b/Libraries/libressl/man/ENGINE_init.3 new file mode 100644 index 000000000..d41d98a2f --- /dev/null +++ b/Libraries/libressl/man/ENGINE_init.3 @@ -0,0 +1,134 @@ +.\" $OpenBSD: ENGINE_init.3,v 1.2 2018/04/18 03:39:22 schwarze Exp $ +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 18 2018 $ +.Dt ENGINE_INIT 3 +.Os +.Sh NAME +.Nm ENGINE_init , +.Nm ENGINE_finish , +.Nm ENGINE_set_init_function , +.Nm ENGINE_set_finish_function , +.Nm ENGINE_get_init_function , +.Nm ENGINE_get_finish_function +.Nd initialize ENGINE objects +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_init +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_finish +.Fa "ENGINE *e" +.Fc +.Ft typedef int +.Fo (*ENGINE_GEN_INT_FUNC_PTR) +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_init_function +.Fa "ENGINE *e" +.Fa "ENGINE_GEN_INT_FUNC_PTR init_f" +.Fc +.Ft int +.Fo ENGINE_set_finish_function +.Fa "ENGINE *e" +.Fa "ENGINE_GEN_INT_FUNC_PTR finish_f" +.Fc +.Ft ENGINE_GEN_INT_FUNC_PTR +.Fo ENGINE_get_init_function +.Fa "const ENGINE *e" +.Fc +.Ft ENGINE_GEN_INT_FUNC_PTR +.Fo ENGINE_get_finish_function +.Fa "const ENGINE *e" +.Fc +.Sh DESCRIPTION +.Fn ENGINE_init +initializes +.Fa e +by calling the +.Fa init_f +previously installed with +.Fn ENGINE_set_init_function , +if any. +In case of success, it also increments both the structural +and the functional reference count by 1. +If no +.Fa init_f +was installed, +.Fn ENGINE_init +always succeeds. +Calling +.Fn ENGINE_init +again after it already succeeded always succeeds, but has no effect +except that it increments both the structural and the functional +reference count by 1. +.Pp +.Fn ENGINE_finish +decrements the functional reference count by 1. +When it reaches 0, it calls the +.Fa finish_f +previously installed with +.Fn ENGINE_set_finish_function , +if any. +If no +.Fa finish_f +was installed, +.Fn ENGINE_finish +always succeeds. +Unless +.Fa finish_f +fails, +.Fn ENGINE_finish +also calls +.Xr ENGINE_free 3 . +.Pp +.Fn ENGINE_init +is internally called by the functions documented in the +.Xr ENGINE_get_default_RSA 3 +manual page. +.Sh RETURN VALUES +.Fn ENGINE_init +and +.Fn ENGINE_finish +return 1 on success or 0 on error. +.Pp +.Fn ENGINE_set_init_function +and +.Fn ENGINE_set_finish_function +always return 1. +.Pp +.Fn ENGINE_get_init_function +and +.Fn ENGINE_get_finish_function +return a function pointer to the respective callback, or +.Dv NULL +if none is installed. +.Sh SEE ALSO +.Xr ENGINE_add 3 , +.Xr ENGINE_ctrl 3 , +.Xr ENGINE_get_default_RSA 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default 3 , +.Xr ENGINE_set_flags 3 , +.Xr ENGINE_set_RSA 3 , +.Xr ENGINE_unregister_RSA 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/ENGINE_new.3 b/Libraries/libressl/man/ENGINE_new.3 new file mode 100644 index 000000000..eaab08d1f --- /dev/null +++ b/Libraries/libressl/man/ENGINE_new.3 @@ -0,0 +1,190 @@ +.\" $OpenBSD: ENGINE_new.3,v 1.5 2021/03/12 05:18:00 jsg Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 12 2021 $ +.Dt ENGINE_NEW 3 +.Os +.Sh NAME +.Nm ENGINE_new , +.Nm ENGINE_up_ref , +.Nm ENGINE_free , +.Nm ENGINE_set_destroy_function , +.Nm ENGINE_get_destroy_function +.Nd create and destroy ENGINE objects +.Sh SYNOPSIS +.In openssl/engine.h +.Ft ENGINE * +.Fn ENGINE_new void +.Ft int +.Fo ENGINE_up_ref +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_free +.Fa "ENGINE *e" +.Fc +.Ft typedef int +.Fo (*ENGINE_GEN_INT_FUNC_PTR) +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_destroy_function +.Fa "ENGINE *e" +.Fa "ENGINE_GEN_INT_FUNC_PTR destroy_f" +.Fc +.Ft ENGINE_GEN_INT_FUNC_PTR +.Fo ENGINE_get_destroy_function +.Fa "const ENGINE *e" +.Fc +.Sh DESCRIPTION +.Vt ENGINE +objects can be used to provide alternative implementations of +cryptographic algorithms, to support additional algorithms, to +support cryptographic hardware, and to switch among alternative +implementations of algorithms at run time. +LibreSSL generally avoids engines and prefers providing +cryptographic functionality in the crypto library itself. +.Pp +.Fn ENGINE_new +allocates and initializes an empty +.Vt ENGINE +object and sets its structural reference count to 1 +and its functional reference count to 0. +For more information about the functional reference count, see the +.Xr ENGINE_init 3 +manual page. +.Pp +Many functions increment the structural reference count by 1 +when successful. +Some of them, including +.Xr ENGINE_get_first 3 , +.Xr ENGINE_get_last 3 , +.Xr ENGINE_get_next 3 , +.Xr ENGINE_get_prev 3 , +and +.Xr ENGINE_by_id 3 , +do so because they return a structural reference to the user. +Other functions, including +.Xr ENGINE_add 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_get_cipher_engine 3 , +.Xr ENGINE_get_digest_engine 3 , +and the +.Xr ENGINE_get_default_RSA 3 +and +.Xr ENGINE_set_default 3 +families of functions +do so when they store a structural reference internally. +.Pp +.Fn ENGINE_up_ref +explicitly increment the structural reference count by 1. +.Pp +.Fn ENGINE_free +decrements the structural reference count by 1, +and if it reaches 0, the optional +.Fa destroy_f +previously installed with +.Fn ENGINE_set_destroy_function +is called, if one is installed, and both the memory used internally by +.Fa e +and +.Fa e +itself are freed. +If +.Fa e +is a +.Dv NULL +pointer, no action occurs. +.Pp +Many functions internally call the equivalent of +.Fn ENGINE_free . +Some of them, including +.Xr ENGINE_get_next 3 +and +.Xr ENGINE_get_prev 3 , +thus invalidate the structural reference passed in by the user. +Other functions, including +.Xr ENGINE_finish 3 , +.Xr ENGINE_remove 3 , +and the +.Xr ENGINE_set_default 3 +family of functions +do so when an internally stored structural reference is no longer needed. +.Pp +.Fn ENGINE_set_destroy_function +installs a callback function that will be called by +.Fn ENGINE_free , +but only when +.Fa e +actually gets destroyed, +not when only its reference count gets decremented. +The value returned from the +.Fa destroy_f +will be ignored. +.Sh RETURN VALUES +.Fn ENGINE_new +returns a structural reference to the new +.Vt ENGINE +object or +.Dv NULL +if an error occurs. +.Pp +.Fn ENGINE_up_ref +returns 0 if +.Fa e +is +.Dv NULL +and 1 otherwise. +.Pp +.Fn ENGINE_free +and +.Fn ENGINE_set_destroy_function +always return 1. +.Pp +.Fn ENGINE_get_destroy_function +returns a function pointer to the callback, or +.Dv NULL +if none is installed. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr ENGINE_add 3 , +.Xr ENGINE_ctrl 3 , +.Xr ENGINE_get_default_RSA 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_register_all_RSA 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default 3 , +.Xr ENGINE_set_flags 3 , +.Xr ENGINE_set_RSA 3 , +.Xr ENGINE_unregister_RSA 3 +.Sh HISTORY +.Fn ENGINE_new +and +.Fn ENGINE_free +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 2.9 . +.Pp +.Fn ENGINE_set_destroy_function +and +.Fn ENGINE_get_destroy_function +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_up_ref +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.4 . diff --git a/Libraries/libressl/man/ENGINE_register_RSA.3 b/Libraries/libressl/man/ENGINE_register_RSA.3 new file mode 100644 index 000000000..5c63729cf --- /dev/null +++ b/Libraries/libressl/man/ENGINE_register_RSA.3 @@ -0,0 +1,142 @@ +.\" $OpenBSD: ENGINE_register_RSA.3,v 1.2 2018/04/18 03:39:22 schwarze Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 18 2018 $ +.Dt ENGINE_REGISTER_RSA 3 +.Os +.Sh NAME +.Nm ENGINE_register_RSA , +.Nm ENGINE_register_DSA , +.Nm ENGINE_register_ECDH , +.Nm ENGINE_register_ECDSA , +.Nm ENGINE_register_DH , +.Nm ENGINE_register_RAND , +.Nm ENGINE_register_STORE , +.Nm ENGINE_register_ciphers , +.Nm ENGINE_register_digests , +.Nm ENGINE_register_complete +.Nd register an ENGINE as implementing an algorithm +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_register_RSA +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_DSA +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_ECDH +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_ECDSA +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_DH +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_RAND +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_STORE +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_ciphers +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_digests +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_register_complete +.Fa "ENGINE *e" +.Fc +.Sh DESCRIPTION +In addition to the global table described in +.Xr ENGINE_add 3 , +the crypto library maintains several tables containing references to +.Vt ENGINE +objects implementing one specific cryptographic algorithm. +.Pp +The functions listed in the present manual page append +.Fa e +to the end of the table for the respective algorithm. +.Pp +If +.Fa e +does not contain a method for the requested algorithm, +these functions succeed without having any effect. +.Pp +If +.Fa e +is already registered for the given algorithm, +they move it to the end of the respective table. +.Pp +.Fn ENGINE_register_ciphers +and +.Fn ENGINE_register_digests +are special in so far as an engine may implement +more than one cipher or more than one digest. +In that case, +.Fa e +is registered for all the ciphers or digests it implements. +.Pp +.Fn ENGINE_register_complete +registers +.Fa e +for all algorithms it implements by calling all the other functions. +.Sh RETURN VALUES +These functions return 1 on success or 0 on error. +They only fail if insufficient memory is available. +.Sh SEE ALSO +.Xr ENGINE_add 3 , +.Xr ENGINE_get_default_RSA 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_all_RSA 3 , +.Xr ENGINE_set_default 3 , +.Xr ENGINE_set_RSA 3 , +.Xr ENGINE_unregister_RSA 3 +.Sh HISTORY +.Fn ENGINE_register_RSA , +.Fn ENGINE_register_DSA , +.Fn ENGINE_register_DH , +.Fn ENGINE_register_RAND , +.Fn ENGINE_register_ciphers , +.Fn ENGINE_register_digests , +and +.Fn ENGINE_register_complete +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_register_ECDH , +.Fn ENGINE_register_ECDSA , +and +.Fn ENGINE_register_STORE +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Sh BUGS +.Fn ENGINE_register_complete +ignores all errors, even memory allocation failure, and always returns 1. diff --git a/Libraries/libressl/man/ENGINE_register_all_RSA.3 b/Libraries/libressl/man/ENGINE_register_all_RSA.3 new file mode 100644 index 000000000..3016eec3d --- /dev/null +++ b/Libraries/libressl/man/ENGINE_register_all_RSA.3 @@ -0,0 +1,123 @@ +.\" $OpenBSD: ENGINE_register_all_RSA.3,v 1.3 2018/04/18 03:39:22 schwarze Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 18 2018 $ +.Dt ENGINE_REGISTER_ALL_RSA 3 +.Os +.Sh NAME +.Nm ENGINE_register_all_RSA , +.Nm ENGINE_register_all_DSA , +.Nm ENGINE_register_all_ECDH , +.Nm ENGINE_register_all_ECDSA , +.Nm ENGINE_register_all_DH , +.Nm ENGINE_register_all_RAND , +.Nm ENGINE_register_all_STORE , +.Nm ENGINE_register_all_ciphers , +.Nm ENGINE_register_all_digests , +.Nm ENGINE_register_all_complete , +.Nm ENGINE_load_builtin_engines , +.Nm ENGINE_load_dynamic +.Nd register all engines as implementing an algorithm +.Sh SYNOPSIS +.In openssl/engine.h +.Ft void +.Fn ENGINE_register_all_RSA void +.Ft void +.Fn ENGINE_register_all_DSA void +.Ft void +.Fn ENGINE_register_all_ECDH void +.Ft void +.Fn ENGINE_register_all_ECDSA void +.Ft void +.Fn ENGINE_register_all_DH void +.Ft void +.Fn ENGINE_register_all_RAND void +.Ft void +.Fn ENGINE_register_all_STORE void +.Ft void +.Fn ENGINE_register_all_ciphers void +.Ft void +.Fn ENGINE_register_all_digests void +.Ft int +.Fn ENGINE_register_all_complete void +.Ft void +.Fn ENGINE_load_builtin_engines void +.Ft void +.Fn ENGINE_load_dynamic void +.Sh DESCRIPTION +These functions loop over all the +.Vt ENGINE +objects contained in the global table described in the +.Xr ENGINE_add 3 +manual page. +They register each object for the respective algorithm +by calling the corresponding function described in +.Xr ENGINE_register_RSA 3 . +.Pp +.Fn ENGINE_register_all_complete +calls +.Fn ENGINE_register_complete +in this way, except that it skips those +.Vt ENGINE +objects that have the +.Dv ENGINE_FLAGS_NO_REGISTER_ALL +flag set with +.Xr ENGINE_set_flags 3 . +.Pp +.Fn ENGINE_load_builtin_engines +calls +.Xr OPENSSL_init_crypto 3 +with no options, loads any built-in engines +that are enabled by default, and calls +.Fn ENGINE_register_all_complete . +Currently, LibreSSL does not provide any engines. +.Sy GOST +and +.Sy aesni +support is provided by the crypto library itself +and does not require any engines, not even built-in ones. +.Pp +.Fn ENGINE_load_dynamic +has no effect and is only provided for compatibility. +.Sh SEE ALSO +.Xr ENGINE_add 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_flags 3 , +.Xr OPENSSL_config 3 , +.Xr OPENSSL_init_crypto 3 +.Sh HISTORY +.Fn ENGINE_register_all_RSA , +.Fn ENGINE_register_all_DSA , +.Fn ENGINE_register_all_DH , +.Fn ENGINE_register_all_RAND , +.Fn ENGINE_register_all_ciphers , +.Fn ENGINE_register_all_digests , +.Fn ENGINE_register_all_complete , +.Fn ENGINE_load_builtin_engines , +and +.Fn ENGINE_load_dynamic +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_register_all_ECDH , +.Fn ENGINE_register_all_ECDSA , +and +.Fn ENGINE_register_all_STORE +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/ENGINE_set_RSA.3 b/Libraries/libressl/man/ENGINE_set_RSA.3 new file mode 100644 index 000000000..b2cec473b --- /dev/null +++ b/Libraries/libressl/man/ENGINE_set_RSA.3 @@ -0,0 +1,317 @@ +.\" $OpenBSD: ENGINE_set_RSA.3,v 1.7 2023/07/21 04:29:27 tb Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 21 2023 $ +.Dt ENGINE_SET_RSA 3 +.Os +.Sh NAME +.Nm ENGINE_set_RSA , +.Nm ENGINE_get_RSA , +.Nm ENGINE_set_DSA , +.Nm ENGINE_get_DSA , +.Nm ENGINE_set_EC , +.Nm ENGINE_get_EC , +.Nm ENGINE_set_DH , +.Nm ENGINE_get_DH , +.Nm ENGINE_set_RAND , +.Nm ENGINE_get_RAND , +.Nm ENGINE_set_STORE , +.Nm ENGINE_get_STORE , +.Nm ENGINE_set_ciphers , +.Nm ENGINE_get_ciphers , +.Nm ENGINE_get_cipher , +.Nm ENGINE_set_digests , +.Nm ENGINE_get_digests , +.Nm ENGINE_get_digest +.Nd install and retrieve function tables of crypto engines +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_set_RSA +.Fa "ENGINE *e" +.Fa "const RSA_METHOD *rsa_meth" +.Fc +.Ft const RSA_METHOD * +.Fo ENGINE_get_RSA +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_DSA +.Fa "ENGINE *e" +.Fa "const DSA_METHOD *dsa_meth" +.Fc +.Ft const DSA_METHOD * +.Fo ENGINE_get_DSA +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_EC +.Fa "ENGINE *e" +.Fa "const EC_KEY_METHOD *ec_meth" +.Fc +.Ft const EC_KEY_METHOD * +.Fo ENGINE_get_EC +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_DH +.Fa "ENGINE *e" +.Fa "const DH_METHOD *dh_meth" +.Fc +.Ft const DH_METHOD * +.Fo ENGINE_get_DH +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_RAND +.Fa "ENGINE *e" +.Fa "const RAND_METHOD *rand_meth" +.Fc +.Ft const RAND_METHOD * +.Fo ENGINE_get_RAND +.Fa "const ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_STORE +.Fa "ENGINE *e" +.Fa "const STORE_METHOD *rand_meth" +.Fc +.Ft const STORE_METHOD * +.Fo ENGINE_get_STORE +.Fa "const ENGINE *e" +.Fc +.Ft typedef int +.Fo (*ENGINE_CIPHERS_PTR) +.Fa "ENGINE *e" +.Fa "const EVP_CIPHER **impl" +.Fa "const int **nids" +.Fa "int nid" +.Fc +.Ft int +.Fo ENGINE_set_ciphers +.Fa "ENGINE *e" +.Fa "ENGINE_CIPHERS_PTR f" +.Fc +.Ft ENGINE_CIPHERS_PTR +.Fo ENGINE_get_ciphers +.Fa "const ENGINE *e" +.Fc +.Ft const EVP_CIPHER * +.Fo ENGINE_get_cipher +.Fa "ENGINE *e" +.Fa "int nid" +.Fc +.Ft typedef int +.Fo (*ENGINE_DIGESTS_PTR) +.Fa "ENGINE *e" +.Fa "const EVP_MD **impl" +.Fa "const int **nids" +.Fa "int nid" +.Fc +.Ft int +.Fo ENGINE_set_digests +.Fa "ENGINE *e" +.Fa "ENGINE_DIGESTS_PTR f" +.Fc +.Ft ENGINE_DIGESTS_PTR +.Fo ENGINE_get_digests +.Fa "const ENGINE *e" +.Fc +.Ft const EVP_MD * +.Fo ENGINE_get_digest +.Fa "ENGINE *e" +.Fa "int nid" +.Fc +.Sh DESCRIPTION +The +.Fn ENGINE_set_* +functions install a table of function pointers +implementing the respective algorithm in +.Fa e . +Partial information about the various method objects is available from +.Xr RSA_meth_new 3 , +.Xr RSA_get_default_method 3 , +.Xr DSA_meth_new 3 , +.Xr DSA_get_default_method 3 , +.Xr EC_KEY_get_default_method 3 , +.Xr DH_get_default_method 3 , +.Xr RAND_get_rand_method 3 , +.Xr EVP_get_cipherbynid 3 , +and +.Xr EVP_get_digestbynid 3 . +.Vt STORE_METHOD +is an incomplete type, and the pointers to it are not used for anything. +For complete descriptions of these types, +refer to the respective header files. +.Pp +The functions described in the +.Xr ENGINE_register_RSA 3 +and +.Xr ENGINE_set_default 3 +manual pages only have an effect after function pointers +were installed using the functions described here. +.Pp +.Fn ENGINE_set_ciphers +and +.Fn ENGINE_set_digests +are special in so far as the +.Vt ENGINE +structure does not provide fields to store function pointers +implementing ciphers or digests. +Instead, these two functions only install a callback to +retrieve implementations. +Where the pointers to the implementations are stored internally, +how they get initialized, and how the +.Vt ENGINE_CIPHERS_PTR +and +.Vt ENGINE_DIGESTS_PTR +callbacks retrieve them +is up to the implementation of each individual engine. +.Pp +If the +.Vt ENGINE_CIPHERS_PTR +and +.Vt ENGINE_DIGESTS_PTR +callbacks are called with a non-zero +.Fa nid , +they retrieve the implementation of that cipher or digest, +respectively. +In this case, a +.Dv NULL +pointer can be passed as the +.Fa nids +argument. +.Fn ENGINE_get_cipher +and +.Fn ENGINE_get_digest +call the callbacks installed in +.Fa e +in this way. +.Pp +If 0 is passed as the +.Fa nid +argument, an internal pointer +to the array of implementations available in +.Fa e +is returned in +.Pf * Fa impl , +and an internal pointer +to the array of corresponding identifiers in +.Pf * Fa nids . +The return value of the callback indicates +the number of implementations returned. +.Pp +The +.Fn ENGINE_get_* +functions retrieve the previously installed function tables. +They are used when constructing basic cryptographic objects +as shown in the following table: +.Bl -column "ENGINE_get_digestMM" +.It Accessor: Ta Called by: +.It Fn ENGINE_get_RSA Ta Xr RSA_new_method 3 , Xr RSA_new 3 +.It Fn ENGINE_get_DSA Ta Xr DSA_new_method 3 , Xr DSA_new 3 +.It Fn ENGINE_get_EC Ta Xr EC_KEY_new_method 3 , Xr EC_KEY_new 3 , +.Xr EC_KEY_new_by_curve_name 3 +.It Fn ENGINE_get_DH Ta Xr DH_new_method 3 , Xr DH_new 3 +.It Fn ENGINE_get_RAND Ta unused +.It Fn ENGINE_get_STORE Ta unused +.It Fn ENGINE_get_cipher Ta Xr EVP_CipherInit_ex 3 +.It Fn ENGINE_get_digest Ta Xr EVP_DigestInit_ex 3 +.El +.Sh RETURN VALUES +The +.Fn ENGINE_set_* +functions return 1 on success or 0 on error. +Currently, they cannot fail. +.Pp +The +.Fn ENGINE_get_* +functions return a method object for the respective algorithm, or +.Dv NULL +if none is installed. +.Pp +.Fn ENGINE_get_ciphers +and +.Fn ENGINE_get_digests +return a function pointer to the respective callback, or +.Dv NULL +if none is installed. +.Pp +.Fn ENGINE_get_cipher +returns an +.Vt EVP_CIPHER +object implementing the cipher +.Fa nid +or +.Dv NULL +if +.Fa e +does not implement that cipher. +.Pp +.Fn ENGINE_get_digest +returns an +.Vt EVP_MD +object implementing the digest +.Fa nid +or +.Dv NULL +if +.Fa e +does not implement that digest. +.Sh SEE ALSO +.Xr DSA_new 3 , +.Xr ENGINE_ctrl 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default 3 , +.Xr ENGINE_set_flags 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_EncryptInit 3 , +.Xr RSA_new 3 +.Sh HISTORY +.Fn ENGINE_set_RSA , +.Fn ENGINE_get_RSA , +.Fn ENGINE_set_DSA , +.Fn ENGINE_get_DSA , +.Fn ENGINE_set_DH , +.Fn ENGINE_get_DH , +.Fn ENGINE_set_RAND , +.Fn ENGINE_get_RAND , +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 2.9 . +.Pp +.Fn ENGINE_set_ciphers , +.Fn ENGINE_get_ciphers , +.Fn ENGINE_get_cipher , +.Fn ENGINE_set_digests , +.Fn ENGINE_get_digests , +and +.Fn ENGINE_get_digest +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_set_STORE +and +.Fn ENGINE_get_STORE +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Fn ENGINE_set_EC +and +.Fn ENGINE_get_EC +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/ENGINE_set_default.3 b/Libraries/libressl/man/ENGINE_set_default.3 new file mode 100644 index 000000000..c2655f2b9 --- /dev/null +++ b/Libraries/libressl/man/ENGINE_set_default.3 @@ -0,0 +1,186 @@ +.\" $OpenBSD: ENGINE_set_default.3,v 1.4 2019/06/03 14:43:15 schwarze Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 3 2019 $ +.Dt ENGINE 3 +.Os +.Sh NAME +.Nm ENGINE_set_default , +.Nm ENGINE_set_default_string , +.Nm ENGINE_set_default_RSA , +.Nm ENGINE_set_default_DSA , +.Nm ENGINE_set_default_ECDH , +.Nm ENGINE_set_default_ECDSA , +.Nm ENGINE_set_default_DH , +.Nm ENGINE_set_default_RAND , +.Nm ENGINE_set_default_ciphers , +.Nm ENGINE_set_default_digests +.Nd register an ENGINE as the default for an algorithm +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_set_default_RSA +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_DSA +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_ECDH +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_ECDSA +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_DH +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_RAND +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_ciphers +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default_digests +.Fa "ENGINE *e" +.Fc +.Ft int +.Fo ENGINE_set_default +.Fa "ENGINE *e" +.Fa "unsigned int flags" +.Fc +.Ft int +.Fo ENGINE_set_default_string +.Fa "ENGINE *e" +.Fa "const char *list" +.Fc +.Sh DESCRIPTION +These functions register +.Fa e +as implementing the respective algorithm +like the functions described in the +.Xr ENGINE_register_RSA 3 +manual page do it. +In addition, they call +.Xr ENGINE_init 3 +on +.Fa e +and select +.Fa e +as the default implementation of the respective algorithm to be +returned by the functions described in +.Xr ENGINE_get_default_RSA 3 +in the future. +If another engine was previously selected +as the default implementation of the respective algorithm, +.Xr ENGINE_finish 3 +is called on that previous engine. +.Pp +If +.Fa e +implements more than one cipher or digest, +.Fn ENGINE_set_default_ciphers +and +.Fn ENGINE_set_default_digests +register and select it for all these ciphers and digests, respectively. +.Pp +.Fn ENGINE_set_default +registers +.Fa e +as the default implementation of all algorithms specified by the +.Fa flags +by calling the appropriate ones among the other functions. +Algorithms can be selected by combining any number of the +following constants with bitwise OR: +.Dv ENGINE_METHOD_ALL , +.Dv ENGINE_METHOD_RSA , +.Dv ENGINE_METHOD_DSA , +.Dv ENGINE_METHOD_ECDH , +.Dv ENGINE_METHOD_ECDSA , +.Dv ENGINE_METHOD_DH , +.Dv ENGINE_METHOD_RAND , +.Dv ENGINE_METHOD_CIPHERS , +.Dv ENGINE_METHOD_DIGESTS , +.Dv ENGINE_METHOD_PKEY_METHS , +and +.Dv ENGINE_METHOD_PKEY_ASN1_METHS . +.Pp +.Fn ENGINE_set_default_string +is similar except that it selects the algorithms according to the string +.Fa def_list , +which contains an arbitrary number of comma-separated keywords from +the following list: ALL, RSA, DSA, ECDH, ECDSA, DH, RAND, CIPHERS, +DIGESTS, PKEY_CRYPTO, PKEY_ASN1, and PKEY. +PKEY_CRYPTO corresponds to +.Dv ENGINE_METHOD_PKEY_METHS , +PKEY_ASN1 to +.Dv ENGINE_METHOD_PKEY_ASN1_METHS , +and PKEY selects both. +.Sh RETURN VALUES +These functions return 1 on success or 0 on error. +They fail if +.Xr ENGINE_init 3 +fails or if insufficient memory is available. +.Sh SEE ALSO +.Xr ENGINE_get_default_RSA 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_RSA 3 , +.Xr ENGINE_unregister_RSA 3 +.Sh HISTORY +.Fn ENGINE_set_default , +.Fn ENGINE_set_default_RSA , +.Fn ENGINE_set_default_DSA , +.Fn ENGINE_set_default_DH , +and +.Fn ENGINE_set_default_RAND +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 2.9 . +.Pp +.Fn ENGINE_set_default_string , +.Fn ENGINE_set_default_ciphers , +and +.Fn ENGINE_set_default_digests +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_set_default_ECDH +and +.Fn ENGINE_set_default_ECDSA +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Sh CAVEATS +Failure of +.Xr ENGINE_finish 3 +is ignored. +.Sh BUGS +Even when +.Fn ENGINE_set_default +or +.Fn ENGINE_set_default_string +fail, they typically still register +.Fa e +for some algorithms, but usually not for all it could be registered +for by calling the individual functions. diff --git a/Libraries/libressl/man/ENGINE_set_flags.3 b/Libraries/libressl/man/ENGINE_set_flags.3 new file mode 100644 index 000000000..33e8f333c --- /dev/null +++ b/Libraries/libressl/man/ENGINE_set_flags.3 @@ -0,0 +1,92 @@ +.\" $OpenBSD: ENGINE_set_flags.3,v 1.2 2018/04/18 03:39:22 schwarze Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 18 2018 $ +.Dt ENGINE_SET_FLAGS 3 +.Os +.Sh NAME +.Nm ENGINE_set_flags , +.Nm ENGINE_get_flags +.Nd modify the behaviour of an ENGINE object +.Sh SYNOPSIS +.In openssl/engine.h +.Ft int +.Fo ENGINE_set_flags +.Fa "ENGINE *e" +.Fa "int flags" +.Fc +.Ft int +.Fo ENGINE_get_flags +.Fa "const ENGINE *e" +.Fc +.Sh DESCRIPTION +.Fn ENGINE_set_flags +sets the flags attribute of +.Fa e +to the new +.Fa flags . +The previous state of the flags attribute is overwritten. +Flags that were previously set are cleared +unless they are also present in the new +.Fa flags . +.Pp +The +.Fa flags +argument can be the bitwise OR of zero or more +of the following constants: +.Bl -tag -width Ds +.It Dv ENGINE_FLAGS_BY_ID_COPY +.Xr ENGINE_by_id 3 +returns a shallow copy of the +.Vt ENGINE +object it found rather than incrementing the reference count +and returning a pointer to the original. +.It Dv ENGINE_FLAGS_MANUAL_CMD_CTRL +.Xr ENGINE_ctrl 3 +lets the function installed with +.Xr ENGINE_set_ctrl_function 3 +handle all commands except +.Dv ENGINE_CTRL_HAS_CTRL_FUNCTION , +even the builtin commands. +.It Dv ENGINE_FLAGS_NO_REGISTER_ALL +.Xr ENGINE_register_all_complete 3 +skips +.Fa e . +.El +.Sh RETURN VALUES +.Fn ENGINE_set_flags +always returns 1. +.Pp +.Fn ENGINE_get_flags +returns the +.Fa flags +attribute of +.Fa e . +.Sh SEE ALSO +.Xr ENGINE_by_id 3 , +.Xr ENGINE_ctrl 3 , +.Xr ENGINE_init 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_all_complete 3 , +.Xr ENGINE_set_RSA 3 +.Sh HISTORY +.Fn ENGINE_set_flags +and +.Fn ENGINE_get_flags +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/ENGINE_unregister_RSA.3 b/Libraries/libressl/man/ENGINE_unregister_RSA.3 new file mode 100644 index 000000000..d03730638 --- /dev/null +++ b/Libraries/libressl/man/ENGINE_unregister_RSA.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: ENGINE_unregister_RSA.3,v 1.3 2018/04/18 03:39:22 schwarze Exp $ +.\" content checked up to: +.\" OpenSSL ENGINE_add 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 18 2018 $ +.Dt ENGINE_UNREGISTER_RSA 3 +.Os +.Sh NAME +.Nm ENGINE_unregister_RSA , +.Nm ENGINE_unregister_DSA , +.Nm ENGINE_unregister_ECDH , +.Nm ENGINE_unregister_ECDSA , +.Nm ENGINE_unregister_DH , +.Nm ENGINE_unregister_RAND , +.Nm ENGINE_unregister_STORE , +.Nm ENGINE_unregister_ciphers , +.Nm ENGINE_unregister_digests +.Nd revoke the registration of an ENGINE object +.Sh SYNOPSIS +.In openssl/engine.h +.Ft void +.Fo ENGINE_unregister_RSA +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_DSA +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_ECDH +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_ECDSA +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_DH +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_RAND +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_STORE +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_ciphers +.Fa "ENGINE *e" +.Fc +.Ft void +.Fo ENGINE_unregister_digests +.Fa "ENGINE *e" +.Fc +.Sh DESCRIPTION +These functions remove +.Fa e +from the list of +.Vt ENGINE +objects that were previously registered for the respective algorithm +with the functions described in +.Xr ENGINE_register_RSA 3 . +.Pp +If +.Fa e +is currently used as the default engine for the algorithm +as described in the +.Fn ENGINE_set_default 3 +and +.Fn ENGINE_get_default_RSA 3 +manual pages, +.Xr ENGINE_finish 3 +is also called. +.Pp +.Fn ENGINE_unregister_ciphers +and +.Fn ENGINE_unregister_digests +unregister +.Fa e +for all ciphers or digests, respectively. +.Sh SEE ALSO +.Xr ENGINE_cleanup 3 , +.Xr ENGINE_finish 3 , +.Xr ENGINE_new 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default 3 +.Sh HISTORY +.Fn ENGINE_unregister_RSA , +.Fn ENGINE_unregister_DSA , +.Fn ENGINE_unregister_DH , +.Fn ENGINE_unregister_RAND , +.Fn ENGINE_unregister_ciphers , +and +.Fn ENGINE_unregister_digests +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn ENGINE_unregister_ECDH , +.Fn ENGINE_unregister_ECDSA , +and +.Fn ENGINE_unregister_STORE +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/ERR.3 b/Libraries/libressl/man/ERR.3 new file mode 100644 index 000000000..8f17e7a32 --- /dev/null +++ b/Libraries/libressl/man/ERR.3 @@ -0,0 +1,152 @@ +.\" $OpenBSD: ERR.3,v 1.11 2023/07/26 20:15:51 tb Exp $ +.\" OpenSSL 186bb907 Apr 13 11:05:13 2015 -0700 +.\" +.\" This file was written by Ulf Moeller and +.\" Dr. Stephen Henson . +.\" Copyright (c) 2000, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt ERR 3 +.Os +.Sh NAME +.Nm ERR +.Nd OpenSSL error codes +.Sh SYNOPSIS +.In openssl/err.h +.Sh DESCRIPTION +When a call to the OpenSSL library fails, this is usually signaled by +the return value, and an error code is stored in an error queue +associated with the current thread. +The +.Nm +library provides functions to obtain these error codes and textual error +messages. +The +.Xr ERR_get_error 3 +manpage describes how to access error codes. +.Pp +Error codes contain information about where the error occurred, and what +went wrong. +.Xr ERR_GET_LIB 3 +describes how to extract this information. +A method to obtain human-readable error messages is described in +.Xr ERR_error_string 3 . +.Pp +.Xr ERR_clear_error 3 +can be used to clear the error queue. +.Pp +Note that +.Xr ERR_remove_state 3 +should be used to avoid memory leaks when threads are terminated. +.Sh ADDING NEW ERROR CODES TO OPENSSL +See +.Xr ERR_put_error 3 +if you want to record error codes in the OpenSSL error system from +within your application. +.Pp +The remainder of this section is of interest only if you want to add new +error codes to OpenSSL or add error codes from external libraries. +.Pp +When you are using new function or reason codes, run +.Sy make errors . +The necessary +.Sy #define Ns s +will then automatically be added to the sub-library's header file. +.Ss Adding new libraries +When adding a new sub-library to OpenSSL, assign it a library number +.Dv ERR_LIB_XXX , +define a macro +.Fn XXXerr +(both in +.In openssl/err.h ) , +add its name to +.Va ERR_str_libraries[] +(in +.Pa /usr/src/lib/libcrypto/err/err.c ) , +and add +.Fn ERR_load_XXX_strings +to the +.Fn ERR_load_crypto_strings +function (in +.Sy /usr/src/lib/libcrypto/err/err_all.c ) . +Finally, add +.Pa xxx_err.c +to the +.Pa Makefile . +.Sh USING ERROR CODES IN EXTERNAL LIBRARIES +It is also possible to use OpenSSL's error code scheme in external +libraries. +.Sh INTERNALS +The error queues are stored in a hash table with one +.Vt ERR_STATE +entry for each PID. +.Fn ERR_get_state +returns the current thread's +.Vt ERR_STATE . +An +.Vt ERR_STATE +can hold up to +.Dv ERR_NUM_ERRORS +error codes. +When more error codes are added, the old ones are overwritten, on the +assumption that the most recent errors are most important. +.Pp +Error strings are also stored in a hash table. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr ERR_asprintf_error_data 3 , +.Xr ERR_clear_error 3 , +.Xr ERR_error_string 3 , +.Xr ERR_get_error 3 , +.Xr ERR_GET_LIB 3 , +.Xr ERR_load_crypto_strings 3 , +.Xr ERR_load_strings 3 , +.Xr ERR_print_errors 3 , +.Xr ERR_put_error 3 , +.Xr ERR_remove_state 3 , +.Xr ERR_set_mark 3 , +.Xr SSL_get_error 3 diff --git a/Libraries/libressl/man/ERR_GET_LIB.3 b/Libraries/libressl/man/ERR_GET_LIB.3 new file mode 100644 index 000000000..bc14f0e2a --- /dev/null +++ b/Libraries/libressl/man/ERR_GET_LIB.3 @@ -0,0 +1,126 @@ +.\" $OpenBSD: ERR_GET_LIB.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL doc/man3/ERR_GET_LIB.pod 3dfda1a6 Dec 12 11:14:40 2016 -0500 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt ERR_GET_LIB 3 +.Os +.Sh NAME +.Nm ERR_GET_LIB , +.Nm ERR_GET_FUNC , +.Nm ERR_GET_REASON , +.Nm ERR_FATAL_ERROR +.Nd get library, function and reason codes for OpenSSL errors +.Sh SYNOPSIS +.In openssl/err.h +.Ft int +.Fo ERR_GET_LIB +.Fa "unsigned long e" +.Fc +.Ft int +.Fo ERR_GET_FUNC +.Fa "unsigned long e" +.Fc +.Ft int +.Fo ERR_GET_REASON +.Fa "unsigned long e" +.Fc +.Ft int +.Fo ERR_FATAL_ERROR +.Fa "unsigned long e" +.Fc +.Sh DESCRIPTION +The error code returned by +.Xr ERR_get_error 3 +consists of a library number, function code, and reason code. +.Fn ERR_GET_LIB , +.Fn ERR_GET_FUNC , +and +.Fn ERR_GET_REASON +can be used to extract these. +.Pp +The library number and function code describe where the error occurred, +whereas the reason code is the information about what went wrong. +.Pp +Each sub-library of OpenSSL has a unique library number; function and +reason codes are unique within each sub-library. +Note that different libraries may use the same value to signal different +functions and reasons. +.Pp +.Dv ERR_R_* +reason codes such as +.Dv ERR_R_MALLOC_FAILURE +are globally unique. +However, when checking for sub-library specific reason codes, be sure to +also compare the library number. +.Pp +.Fn ERR_FATAL_ERROR +indicates whether a given error code is a fatal error. +.Pp +These functions are implemented as macros. +.Sh RETURN VALUES +.Fn ERR_GET_LIB , +.Fn ERR_GET_FUNC , +and +.Fn ERR_GET_REASON +return the library number, function code, and reason code, respectively. +.Pp +.Fn ERR_FATAL_ERROR +returns non-zero if the error is fatal or 0 otherwise. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_get_error 3 +.Sh HISTORY +.Fn ERR_GET_LIB , +.Fn ERR_GET_FUNC , +.Fn ERR_GET_REASON , +and +.Fn ERR_FATAL_ERROR +first appeared in SSLeay 0.4.4 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/ERR_asprintf_error_data.3 b/Libraries/libressl/man/ERR_asprintf_error_data.3 new file mode 100644 index 000000000..67999e9cb --- /dev/null +++ b/Libraries/libressl/man/ERR_asprintf_error_data.3 @@ -0,0 +1,55 @@ +.\" $OpenBSD: ERR_asprintf_error_data.3,v 1.2 2017/02/21 07:15:21 jmc Exp $ +.\" +.\" Copyright (c) 2017 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.Dd $Mdocdate: February 21 2017 $ +.Dt ERR_ASPRINTF_ERROR_DATA 3 +.Os +.Sh NAME +.Nm ERR_asprintf_error_data +.Nd record a LibreSSL error using a formatted string +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fo ERR_asprintf_error_data +.Fa "char * format" +.Fa ... +.Fc +.Sh DESCRIPTION +.Nm +builds a string using +.Xr asprintf 3 +called with the provided +.Ar format +and arguments. +The resulting string is then associated with the error code that was most +recently added. +If +.Xr asprintf 3 +fails, the string "malloc failed" is associated instead. +.Pp +.Nm +is intended to be used instead of the OpenSSL functions +.Xr ERR_add_error_data 3 +and +.Xr ERR_add_error_vdata 3 . +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_put_error 3 , +.Xr printf 3 +.Sh HISTORY +.Nm +appeared in +.Ox 5.6 +and is available in all versions of LibreSSL. diff --git a/Libraries/libressl/man/ERR_clear_error.3 b/Libraries/libressl/man/ERR_clear_error.3 new file mode 100644 index 000000000..54f563e16 --- /dev/null +++ b/Libraries/libressl/man/ERR_clear_error.3 @@ -0,0 +1,70 @@ +.\" $OpenBSD: ERR_clear_error.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt ERR_CLEAR_ERROR 3 +.Os +.Sh NAME +.Nm ERR_clear_error +.Nd clear the OpenSSL error queue +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fn ERR_clear_error void +.Sh DESCRIPTION +.Fn ERR_clear_error +empties the current thread's error queue. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_get_error 3 +.Sh HISTORY +.Fn ERR_clear_error +first appeared in SSLeay 0.4.4 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/ERR_error_string.3 b/Libraries/libressl/man/ERR_error_string.3 new file mode 100644 index 000000000..60f913285 --- /dev/null +++ b/Libraries/libressl/man/ERR_error_string.3 @@ -0,0 +1,176 @@ +.\" $OpenBSD: ERR_error_string.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2004 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt ERR_ERROR_STRING 3 +.Os +.Sh NAME +.Nm ERR_error_string , +.Nm ERR_error_string_n , +.Nm ERR_lib_error_string , +.Nm ERR_func_error_string , +.Nm ERR_reason_error_string +.Nd obtain human-readable OpenSSL error messages +.Sh SYNOPSIS +.In openssl/err.h +.Ft char * +.Fo ERR_error_string +.Fa "unsigned long e" +.Fa "char *buf" +.Fc +.Ft void +.Fo ERR_error_string_n +.Fa "unsigned long e" +.Fa "char *buf" +.Fa "size_t len" +.Fc +.Ft const char * +.Fo ERR_lib_error_string +.Fa "unsigned long e" +.Fc +.Ft const char * +.Fo ERR_func_error_string +.Fa "unsigned long e" +.Fc +.Ft const char * +.Fo ERR_reason_error_string +.Fa "unsigned long e" +.Fc +.Sh DESCRIPTION +.Fn ERR_error_string +generates a human-readable string representing the error code +.Fa e +and places it in +.Fa buf . +.Fa buf +must be at least 256 bytes long. +If +.Fa buf +is +.Dv NULL , +the error string is placed in a static buffer. +Note that this function is not thread-safe and does no checks on +the size of the buffer; use +.Fn ERR_error_string_n +instead. +.Pp +.Fn ERR_error_string_n +is a variant of +.Fn ERR_error_string +that writes at most +.Fa len +characters (including the terminating NUL) and truncates the string +if necessary. +For +.Fn ERR_error_string_n , +.Fa buf +may not be +.Dv NULL . +.Pp +The string will have the following format: +.Pp +.Dl error:[error code]:[library name]:[function name]:[reason string] +.Pp +The error code is an 8-digit hexadecimal number. +The library name, the function name, and the reason string are ASCII +text. +.Pp +.Fn ERR_lib_error_string , +.Fn ERR_func_error_string , +and +.Fn ERR_reason_error_string +return the library name, the function name, and the reason string, +respectively. +.Pp +The OpenSSL error strings should be loaded by calling +.Xr ERR_load_crypto_strings 3 +or, for SSL applications, +.Xr SSL_load_error_strings 3 +first. +If there is no text string registered for the given error code, the +error string will contain the numeric code. +.Pp +.Xr ERR_print_errors 3 +can be used to print all error codes currently in the queue. +.Sh RETURN VALUES +.Fn ERR_error_string +returns a pointer to a static buffer containing the string if +.Fa buf +is +.Dv NULL , +or +.Fa buf +otherwise. +.Pp +.Fn ERR_lib_error_string , +.Fn ERR_func_error_string , +and +.Fn ERR_reason_error_string +return the strings, or +.Dv NULL +if none is registered for the error code. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_get_error 3 , +.Xr ERR_load_crypto_strings 3 , +.Xr ERR_print_errors 3 , +.Xr SSL_load_error_strings 3 +.Sh HISTORY +.Fn ERR_error_string , +.Fn ERR_lib_error_string , +.Fn ERR_func_error_string , +and +.Fn ERR_reason_error_string +first appeared in SSLeay 0.4.4 and have been available since +.Ox 2.4 . +.Pp +.Fn ERR_error_string_n +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/ERR_get_error.3 b/Libraries/libressl/man/ERR_get_error.3 new file mode 100644 index 000000000..f3bcc09cb --- /dev/null +++ b/Libraries/libressl/man/ERR_get_error.3 @@ -0,0 +1,191 @@ +.\" $OpenBSD: ERR_get_error.3,v 1.8 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt ERR_GET_ERROR 3 +.Os +.Sh NAME +.Nm ERR_get_error , +.Nm ERR_peek_error , +.Nm ERR_peek_last_error , +.Nm ERR_get_error_line , +.Nm ERR_peek_error_line , +.Nm ERR_peek_last_error_line , +.Nm ERR_get_error_line_data , +.Nm ERR_peek_error_line_data , +.Nm ERR_peek_last_error_line_data +.Nd obtain OpenSSL error code and data +.Sh SYNOPSIS +.In openssl/err.h +.Ft unsigned long +.Fn ERR_get_error void +.Ft unsigned long +.Fn ERR_peek_error void +.Ft unsigned long +.Fn ERR_peek_last_error void +.Ft unsigned long +.Fo ERR_get_error_line +.Fa "const char **file" +.Fa "int *line" +.Fc +.Ft unsigned long +.Fo ERR_peek_error_line +.Fa "const char **file" +.Fa "int *line" +.Fc +.Ft unsigned long +.Fo ERR_peek_last_error_line +.Fa "const char **file" +.Fa "int *line" +.Fc +.Ft unsigned long +.Fo ERR_get_error_line_data +.Fa "const char **file" +.Fa "int *line" +.Fa "const char **data" +.Fa "int *flags" +.Fc +.Ft unsigned long +.Fo ERR_peek_error_line_data +.Fa "const char **file" +.Fa "int *line" +.Fa "const char **data" +.Fa "int *flags" +.Fc +.Ft unsigned long +.Fo ERR_peek_last_error_line_data +.Fa "const char **file" +.Fa "int *line" +.Fa "const char **data" +.Fa "int *flags" +.Fc +.Sh DESCRIPTION +.Fn ERR_get_error +returns the earliest error code from the thread's error queue and +removes the entry. +This function can be called repeatedly until there are no more error +codes to return. +.Pp +.Fn ERR_peek_error +returns the earliest error code from the thread's error queue without +modifying it. +.Pp +.Fn ERR_peek_last_error +returns the latest error code from the thread's error queue without +modifying it. +.Pp +See +.Xr ERR_GET_LIB 3 +for obtaining information about the location and reason for the error, and +.Xr ERR_error_string 3 +for human-readable error messages. +.Pp +.Fn ERR_get_error_line , +.Fn ERR_peek_error_line , +and +.Fn ERR_peek_last_error_line +are the same as the above, but they additionally store the file name and +line number where the error occurred in +.Pf * Fa file +and +.Pf * Fa line , +unless these are +.Dv NULL . +.Pp +.Fn ERR_get_error_line_data , +.Fn ERR_peek_error_line_data , +and +.Fn ERR_peek_last_error_line_data +store additional data and flags associated with the error code in +.Pf * Fa data +and +.Pf * Fa flags , +unless these are +.Dv NULL . +.Pf * Fa data +contains a string if +.Pf * Fa flags Ns & Ns Dv ERR_TXT_STRING +is true. +.Pp +An application +.Sy MUST NOT +free the +.Pf * Fa data +pointer (or any other pointers returned by these functions) with +.Xr free 3 +as freeing is handled automatically by the error library. +.Sh RETURN VALUES +The error code, or 0 if there is no error in the queue. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_error_string 3 , +.Xr ERR_GET_LIB 3 +.Sh HISTORY +.Fn ERR_get_error +and +.Fn ERR_peek_error +first appeared in SSLeay 0.4.4. +.Fn ERR_get_error_line +and +.Fn ERR_peek_error_line +first appeared in SSLeay 0.6.0. +.Fn ERR_get_error_line_data +and +.Fn ERR_peek_error_line_data +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn ERR_peek_last_error , +.Fn ERR_peek_last_error_line , +and +.Fn ERR_peek_last_error_line_data +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/ERR_load_crypto_strings.3 b/Libraries/libressl/man/ERR_load_crypto_strings.3 new file mode 100644 index 000000000..72d10b030 --- /dev/null +++ b/Libraries/libressl/man/ERR_load_crypto_strings.3 @@ -0,0 +1,151 @@ +.\" $OpenBSD: ERR_load_crypto_strings.3,v 1.11 2023/07/21 10:45:44 tb Exp $ +.\" full merge up to: OpenSSL f672aee4 Feb 9 11:52:40 2016 -0500 +.\" selective merge up to: OpenSSL b3696a55 Sep 2 09:35:50 2017 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 21 2023 $ +.Dt ERR_LOAD_CRYPTO_STRINGS 3 +.Os +.Sh NAME +.Nm ERR_load_crypto_strings , +.Nm ERR_free_strings , +.Nm SSL_load_error_strings +.Nd load and free OpenSSL error strings +.\" The following functions are intentionally undocumented +.\" because they are merely subroutines of ERR_load_crypto_strings(3) +.\" and should not have been made a part of the API: +.\" ERR_load_ASN1_strings() +.\" ERR_load_BIO_strings() +.\" ERR_load_BN_strings() +.\" ERR_load_BUF_strings() +.\" ERR_load_CMS_strings() +.\" ERR_load_CONF_strings() +.\" ERR_load_CRYPTO_strings() +.\" ERR_load_DH_strings() +.\" ERR_load_DSA_strings() +.\" ERR_load_EC_strings() +.\" ERR_load_ERR_strings() +.\" ERR_load_EVP_strings() +.\" ERR_load_GOST_strings() +.\" ERR_load_OBJ_strings() +.\" ERR_load_OCSP_strings() +.\" ERR_load_PEM_strings() +.\" ERR_load_PKCS12_strings() +.\" ERR_load_PKCS7_strings() +.\" ERR_load_RAND_strings() +.\" ERR_load_RSA_strings() +.\" ERR_load_TS_strings() +.\" ERR_load_UI_strings() +.\" ERR_load_X509_strings() +.\" ERR_load_X509V3_strings() +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fn ERR_load_crypto_strings void +.Ft void +.Fn ERR_free_strings void +.In openssl/ssl.h +.Ft void +.Fn SSL_load_error_strings void +.Sh DESCRIPTION +These functions are deprecated. +It is never useful for any application program to call any of them explicitly. +The library automatically calls them internally whenever needed. +.Pp +.Fn ERR_load_crypto_strings +registers the error strings for all +.Xr crypto 3 +functions. +.Fn SSL_load_error_strings +does the same, but also registers the +.Xr ssl 3 +error strings. +.Pp +If the error strings were already loaded before, no action occurs. +.Pp +.Fn ERR_free_strings +frees all previously loaded error strings. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_error_string 3 , +.Xr OPENSSL_config 3 +.Sh HISTORY +.Fn ERR_load_crypto_strings +and +.Fn SSL_load_error_strings +first appeared in SSLeay 0.4.4. +.Fn ERR_free_strings +first appeared in SSLeay 0.5.1. +These functions been available since +.Ox 2.4 . +.Sh BUGS +Even though the error strings are already compiled into the object +code of the library as static strings, these functions store them +again using dynamically allocated memory on the heap. +That may fail if insufficient memory is available, +but these functions do not report such errors. +Instead, they fail silently, possibly having registered none or only +a part of the strings requested. diff --git a/Libraries/libressl/man/ERR_load_strings.3 b/Libraries/libressl/man/ERR_load_strings.3 new file mode 100644 index 000000000..44fde08c9 --- /dev/null +++ b/Libraries/libressl/man/ERR_load_strings.3 @@ -0,0 +1,117 @@ +.\" $OpenBSD: ERR_load_strings.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt ERR_LOAD_STRINGS 3 +.Os +.Sh NAME +.Nm ERR_load_strings , +.Nm ERR_PACK , +.Nm ERR_get_next_error_library +.Nd load arbitrary OpenSSL error strings +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fo ERR_load_strings +.Fa "int lib" +.Fa "ERR_STRING_DATA str[]" +.Fc +.Ft unsigned long +.Fo ERR_PACK +.Fa "int lib" +.Fa "int func" +.Fa "int reason" +.Fc +.Ft int +.Fn ERR_get_next_error_library void +.Sh DESCRIPTION +.Fn ERR_load_strings +registers error strings for library number +.Fa lib . +.Pp +.Fa str +is an array of error string data: +.Bd -literal -offset indent +typedef struct ERR_string_data_st +{ + unsigned long error; + char *string; +} ERR_STRING_DATA; +.Ed +.Pp +The error code is generated from the library number and a function and +reason code: +.Pp +.Dl error = ERR_PACK(lib, func, reason) +.Pp +.Fn ERR_PACK +is a macro. +.Pp +The last entry in the array is +.Brq 0 , Dv NULL . +.Pp +.Fn ERR_get_next_error_library +can be used to assign library numbers to user libraries at runtime. +.Sh RETURN VALUES +.Fn ERR_PACK +returns the error code. +.Fn ERR_get_next_error_library +returns a new library number. +.Sh SEE ALSO +.Xr ERR 3 +.Sh HISTORY +.Fn ERR_load_strings +and +.Fn ERR_PACK +first appeared in SSLeay 0.4.4. +.Fn ERR_get_next_error_library +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/ERR_print_errors.3 b/Libraries/libressl/man/ERR_print_errors.3 new file mode 100644 index 000000000..a5c7c0328 --- /dev/null +++ b/Libraries/libressl/man/ERR_print_errors.3 @@ -0,0 +1,122 @@ +.\" $OpenBSD: ERR_print_errors.3,v 1.8 2020/03/28 22:40:58 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller , +.\" with additions by Rich Salz . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 28 2020 $ +.Dt ERR_PRINT_ERRORS 3 +.Os +.Sh NAME +.Nm ERR_print_errors , +.Nm ERR_print_errors_fp , +.Nm ERR_print_errors_cb +.Nd print OpenSSL error messages +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fo ERR_print_errors +.Fa "BIO *bp" +.Fc +.Ft void +.Fo ERR_print_errors_fp +.Fa "FILE *fp" +.Fc +.Ft void +.Fo ERR_print_errors_cb +.Fa "int (*cb)(const char *str, size_t len, void *u)" +.Fa "void *u" +.Fc +.Sh DESCRIPTION +.Fn ERR_print_errors +is a convenience function that prints the error strings for all errors +that OpenSSL has recorded to +.Fa bp , +thus emptying the error queue. +.Pp +.Fn ERR_print_errors_fp +is the same, except that the output goes to a +.Vt FILE . +.Pp +.Fn ERR_print_errors_cb +is the same, except that the callback function, +.Fa cb , +is called for each error line with the string, length, and userdata +.Fa u +as the callback parameters. +.Pp +The error strings have the following format: +.Bd -literal +[pid]:error:[error code]:[library name]:[function name]:[reason string]: +[file name]:[line]:[optional text message] +.Ed +.Pp +The error code is an 8-digit hexadecimal number. +The library name, the function name, and the reason string are ASCII +text, as is the optional text message if one was set for the +respective error code. +.Pp +If there is no text string registered for the given error code, the +error string will contain the numeric code. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_error_string 3 , +.Xr ERR_get_error 3 , +.Xr ERR_load_crypto_strings 3 , +.Xr SSL_load_error_strings 3 +.Sh HISTORY +.Fn ERR_print_errors +first appeared in SSLeay 0.4.5. +.Fn ERR_print_errors_fp +first appeared in SSLeay 0.6.0. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn ERR_print_errors_cb +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/ERR_put_error.3 b/Libraries/libressl/man/ERR_put_error.3 new file mode 100644 index 000000000..7eac5e415 --- /dev/null +++ b/Libraries/libressl/man/ERR_put_error.3 @@ -0,0 +1,158 @@ +.\" $OpenBSD: ERR_put_error.3,v 1.10 2022/03/31 17:27:16 naddy Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt ERR_PUT_ERROR 3 +.Os +.Sh NAME +.Nm ERR_put_error , +.Nm ERR_add_error_data , +.Nm ERR_add_error_vdata +.Nd record an OpenSSL error +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fo ERR_put_error +.Fa "int lib" +.Fa "int func" +.Fa "int reason" +.Fa "const char *file" +.Fa "int line" +.Fc +.Ft void +.Fo ERR_add_error_data +.Fa "int num" +.Fa ... +.Fc +.Ft void +.Fo ERR_add_error_vdata +.Fa "int num" +.Fa "va_list arg" +.Fc +.Sh DESCRIPTION +.Fn ERR_put_error +adds an error code to the thread's error queue. +It signals that the error of reason code +.Fa reason +occurred in function +.Fa func +of library +.Fa lib , +in line number +.Fa line +of +.Fa file . +This function is usually called by a macro. +.Pp +.Fn ERR_add_error_data +associates the concatenation of its +.Fa num +string arguments with the error code added last. +.Fn ERR_add_error_vdata +is similar except the argument is a +.Vt va_list . +Use of +.Fn ERR_add_error_data +and +.Fn ERR_add_error_vdata +is deprecated inside of LibreSSL in favour of +.Xr ERR_asprintf_error_data 3 . +.Pp +.Xr ERR_load_strings 3 +can be used to register error strings so that the application can +generate human-readable error messages for the error code. +.Pp +Each sub-library has a specific macro +.Fn XXXerr f r +that is used to report errors. +Its first argument is a function code +.Dv XXX_F_* ; +the second argument is a reason code +.Dv XXX_R_* . +Function codes are derived from the function names +whereas reason codes consist of textual error descriptions. +For example, the function +.Fn ssl23_read +reports a "handshake failure" as follows: +.Pp +.Dl SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); +.Pp +Function and reason codes should consist of upper case characters, +numbers and underscores only. +The error file generation script translates function codes into function +names by looking in the header files for an appropriate function name. +If none is found, it just uses the capitalized form such as "SSL23_READ" +in the above example. +.Pp +The trailing section of a reason code (after the "_R_") is translated +into lower case and underscores changed to spaces. +.Pp +Although a library will normally report errors using its own specific +.Fn XXXerr +macro, another library's macro can be used. +This is normally only done when a library wants to include ASN.1 code +which must use the +.Fn ASN1err +macro. +.Sh SEE ALSO +.Xr ERR 3 , +.Xr ERR_asprintf_error_data 3 , +.Xr ERR_load_strings 3 +.Sh HISTORY +.Fn ERR_put_error +first appeared in SSLeay 0.4.4. +.Fn ERR_add_error_data +first appeared in SSLeay 0.9.0. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn ERR_add_error_vdata +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/ERR_remove_state.3 b/Libraries/libressl/man/ERR_remove_state.3 new file mode 100644 index 000000000..bc28f15de --- /dev/null +++ b/Libraries/libressl/man/ERR_remove_state.3 @@ -0,0 +1,108 @@ +.\" $OpenBSD: ERR_remove_state.3,v 1.7 2020/03/28 22:40:58 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Ulf Moeller and +.\" Matt Caswell . +.\" Copyright (c) 2000, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 28 2020 $ +.Dt ERR_REMOVE_STATE 3 +.Os +.Sh NAME +.Nm ERR_remove_thread_state , +.Nm ERR_remove_state +.Nd free a thread's OpenSSL error queue +.Sh SYNOPSIS +.In openssl/err.h +.Ft void +.Fo ERR_remove_thread_state +.Fa "const CRYPTO_THREADID *tid" +.Fc +.Pp +Deprecated: +.Pp +.Ft void +.Fo ERR_remove_state +.Fa "unsigned long pid" +.Fc +.Sh DESCRIPTION +.Fn ERR_remove_thread_state +frees the error queue associated with thread +.Fa tid . +If +.Fa tid +is +.Dv NULL , +the current thread will have its error queue removed. +.Pp +Since error queue data structures are allocated automatically for new +threads, they must be freed when threads are terminated in order to +avoid memory leaks. +.Pp +.Fn ERR_remove_state +is deprecated and has been replaced by +.Fn ERR_remove_thread_state . +Since threads in OpenSSL are no longer identified by unsigned long +values, any argument to this function is ignored. +Calling +.Fn ERR_remove_state +is equivalent to +.Fn ERR_remove_thread_state NULL . +.Sh SEE ALSO +.Xr ERR 3 +.Sh HISTORY +.Fn ERR_remove_state +first appeared in SSLeay 0.6.1 and has been available since +.Ox 2.4 . +.Pp +It was deprecated in OpenSSL 1.0.0 and +.Ox 4.9 +when +.Fn ERR_remove_thread_state +was introduced and thread IDs were introduced to identify threads +instead of +.Vt unsigned long . diff --git a/Libraries/libressl/man/ERR_set_mark.3 b/Libraries/libressl/man/ERR_set_mark.3 new file mode 100644 index 000000000..2f3486d8c --- /dev/null +++ b/Libraries/libressl/man/ERR_set_mark.3 @@ -0,0 +1,86 @@ +.\" $OpenBSD: ERR_set_mark.3,v 1.4 2018/03/23 00:09:11 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Richard Levitte . +.\" Copyright (c) 2003 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt ERR_SET_MARK 3 +.Os +.Sh NAME +.Nm ERR_set_mark , +.Nm ERR_pop_to_mark +.Nd set marks and pop OpenSSL errors until mark +.Sh SYNOPSIS +.In openssl/err.h +.Ft int +.Fn ERR_set_mark void +.Ft int +.Fn ERR_pop_to_mark void +.Sh DESCRIPTION +.Fn ERR_set_mark +sets a mark on the current topmost error record if there is one. +.Pp +.Fn ERR_pop_to_mark +will pop the top of the error stack until a mark is found. +The mark is then removed. +If there is no mark, the whole stack is removed. +.Sh RETURN VALUES +.Fn ERR_set_mark +returns 0 if the error stack is empty, otherwise 1. +.Pp +.Fn ERR_pop_to_mark +returns 0 if there was no mark in the error stack, which implies that +the stack became empty, otherwise 1. +.Sh SEE ALSO +.Xr ERR 3 +.Sh HISTORY +.Fn ERR_set_mark +and +.Fn ERR_pop_to_mark +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/ESS_SIGNING_CERT_new.3 b/Libraries/libressl/man/ESS_SIGNING_CERT_new.3 new file mode 100644 index 000000000..4baabbcd9 --- /dev/null +++ b/Libraries/libressl/man/ESS_SIGNING_CERT_new.3 @@ -0,0 +1,117 @@ +.\" $OpenBSD: ESS_SIGNING_CERT_new.3,v 1.5 2019/06/06 01:06:58 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt ESS_SIGNING_CERT_NEW 3 +.Os +.Sh NAME +.Nm ESS_SIGNING_CERT_new , +.Nm ESS_SIGNING_CERT_free , +.Nm ESS_CERT_ID_new , +.Nm ESS_CERT_ID_free , +.Nm ESS_ISSUER_SERIAL_new , +.Nm ESS_ISSUER_SERIAL_free +.Nd signing certificates for S/MIME +.Sh SYNOPSIS +.In openssl/ts.h +.Ft ESS_SIGNING_CERT * +.Fn ESS_SIGNING_CERT_new void +.Ft void +.Fn ESS_SIGNING_CERT_free "ESS_SIGNING_CERT *signing_cert" +.Ft ESS_CERT_ID * +.Fn ESS_CERT_ID_new void +.Ft void +.Fn ESS_CERT_ID_free "ESS_CERT_ID *cert_id" +.Ft ESS_ISSUER_SERIAL * +.Fn ESS_ISSUER_SERIAL_new void +.Ft void +.Fn ESS_ISSUER_SERIAL_free "ESS_ISSUER_SERIAL *issuer_serial" +.Sh DESCRIPTION +The signing certificate may be included in the signedAttributes +field of a +.Vt SignerInfo +structure to mitigate simple substitution and re-issue attacks. +.Pp +.Fn ESS_SIGNING_CERT_new +allocates and initializes an empty +.Vt ESS_SIGNING_CERT +object, representing an ASN.1 +.Vt SigningCertificate +structure defined in RFC 2634 section 5.4. +It can hold the certificate used for signing the data, +additional authorization certificates that can be used during +validation, and policies applying to the certificate. +.Fn ESS_SIGNING_CERT_free +frees +.Fa signing_cert . +.Pp +.Fn ESS_CERT_ID_new +allocates and initializes an empty +.Vt ESS_CERT_ID +object, representing an ASN.1 +.Vt ESSCertID +structure defined in RFC 2634 section 5.4.1. +Such objects can be used inside +.Vt ESS_SIGNING_CERT +objects, and each one can hold a SHA1 hash of one certificate. +.Fn ESS_CERT_ID_free +frees +.Fa cert_id . +.Pp +.Fn ESS_ISSUER_SERIAL_new +allocates and initializes an empty +.Vt ESS_ISSUER_SERIAL +object, representing an ASN.1 +.Vt IssuerSerial +structure defined in RFC 2634 section 5.4.1. +It can hold an issuer name and a serial number and can be included in an +.Vt ESS_CERT_ID +object, which is useful for additional authorization certificates, +but redundant for the signing certificate itself. +.Fn ESS_ISSUER_SERIAL_free +frees +.Fa issuer_serial . +.Sh RETURN VALUES +.Fn ESS_SIGNING_CERT_new , +.Fn ESS_CERT_ID_new , +and +.Fn ESS_ISSUER_SERIAL_new +return the new +.Vt ESS_SIGNING_CERT , +.Vt ESS_CERT_ID , +or +.Vt ESS_ISSUER_SERIAL +object, respectively, or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr d2i_ESS_SIGNING_CERT 3 +.Sh STANDARDS +RFC 2634: Enhanced Security Services for S/MIME, +section 5: Signing Certificate Attribute +.Pp +Note that RFC 2634 has been updated by RFC 5035: +Enhanced Security Services (ESS) Update: +Adding CertID Algorithm Agility. +But the current implementation only supports the +Signing Certificate Attribute Definition Version 1 +according to RFC 2634, not the +Signing Certificate Attribute Definition Version 2 +according to RFC 5035. +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_AEAD_CTX_init.3 b/Libraries/libressl/man/EVP_AEAD_CTX_init.3 new file mode 100644 index 000000000..01692c93e --- /dev/null +++ b/Libraries/libressl/man/EVP_AEAD_CTX_init.3 @@ -0,0 +1,411 @@ +.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.15 2023/09/12 13:58:06 schwarze Exp $ +.\" +.\" Copyright (c) 2014, Google Inc. +.\" Parts of the text were written by Adam Langley and David Benjamin. +.\" Copyright (c) 2015 Reyk Floeter +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and/or distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 12 2023 $ +.Dt EVP_AEAD_CTX_INIT 3 +.Os +.Sh NAME +.Nm EVP_AEAD_CTX_new , +.Nm EVP_AEAD_CTX_free , +.Nm EVP_AEAD_CTX_init , +.Nm EVP_AEAD_CTX_cleanup , +.Nm EVP_AEAD_CTX_open , +.Nm EVP_AEAD_CTX_seal , +.Nm EVP_AEAD_key_length , +.Nm EVP_AEAD_max_overhead , +.Nm EVP_AEAD_max_tag_len , +.Nm EVP_AEAD_nonce_length , +.Nm EVP_aead_aes_128_gcm , +.Nm EVP_aead_aes_256_gcm , +.Nm EVP_aead_chacha20_poly1305 , +.Nm EVP_aead_xchacha20_poly1305 +.Nd authenticated encryption with additional data +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_AEAD_CTX * +.Fn EVP_AEAD_CTX_new void +.Ft void +.Fo EVP_AEAD_CTX_free +.Fa "EVP_AEAD_CTX *ctx" +.Fc +.Ft int +.Fo EVP_AEAD_CTX_init +.Fa "EVP_AEAD_CTX *ctx" +.Fa "const EVP_AEAD *aead" +.Fa "const unsigned char *key" +.Fa "size_t key_len" +.Fa "size_t tag_len" +.Fa "ENGINE *impl" +.Fc +.Ft void +.Fo EVP_AEAD_CTX_cleanup +.Fa "EVP_AEAD_CTX *ctx" +.Fc +.Ft int +.Fo EVP_AEAD_CTX_open +.Fa "const EVP_AEAD_CTX *ctx" +.Fa "unsigned char *out" +.Fa "size_t *out_len" +.Fa "size_t max_out_len" +.Fa "const unsigned char *nonce" +.Fa "size_t nonce_len" +.Fa "const unsigned char *in" +.Fa "size_t in_len" +.Fa "const unsigned char *ad" +.Fa "size_t ad_len" +.Fc +.Ft int +.Fo EVP_AEAD_CTX_seal +.Fa "const EVP_AEAD_CTX *ctx" +.Fa "unsigned char *out" +.Fa "size_t *out_len" +.Fa "size_t max_out_len" +.Fa "const unsigned char *nonce" +.Fa "size_t nonce_len" +.Fa "const unsigned char *in" +.Fa "size_t in_len" +.Fa "const unsigned char *ad" +.Fa "size_t ad_len" +.Fc +.Ft size_t +.Fo EVP_AEAD_key_length +.Fa "const EVP_AEAD *aead" +.Fc +.Ft size_t +.Fo EVP_AEAD_max_overhead +.Fa "const EVP_AEAD *aead" +.Fc +.Ft size_t +.Fo EVP_AEAD_max_tag_len +.Fa "const EVP_AEAD *aead" +.Fc +.Ft size_t +.Fo EVP_AEAD_nonce_length +.Fa "const EVP_AEAD *aead" +.Fc +.Ft const EVP_AEAD * +.Fo EVP_aead_aes_128_gcm +.Fa void +.Fc +.Ft const EVP_AEAD * +.Fo EVP_aead_aes_256_gcm +.Fa void +.Fc +.Ft const EVP_AEAD * +.Fo EVP_aead_chacha20_poly1305 +.Fa void +.Fc +.Ft const EVP_AEAD * +.Fo EVP_aead_xchacha20_poly1305 +.Fa void +.Fc +.Sh DESCRIPTION +AEAD (Authenticated Encryption with Additional Data) couples +confidentiality and integrity in a single primitive. +AEAD algorithms take a key and can then seal and open individual +messages. +Each message has a unique, per-message nonce and, optionally, additional +data which is authenticated but not included in the output. +.Pp +.Fn EVP_AEAD_CTX_new +allocates a new context for use with +.Fn EVP_AEAD_CTX_init . +It can be cleaned up for reuse with +.Fn EVP_AEAD_CTX_cleanup +and must be freed with +.Fn EVP_AEAD_CTX_free . +.Pp +.Fn EVP_AEAD_CTX_free +cleans up +.Fa ctx +and frees the space allocated to it. +.Pp +.Fn EVP_AEAD_CTX_init +initializes the context +.Fa ctx +for the given AEAD algorithm +.Fa aead . +The +.Fa impl +argument must be +.Dv NULL +for the default implementation; +other values are currently not supported. +Authentication tags may be truncated by passing a tag length. +A +.Fa tag_len +argument of +.Dv EVP_AEAD_DEFAULT_TAG_LENGTH , +which has the value 0, causes the default tag length to be used. +.Pp +.Fn EVP_AEAD_CTX_cleanup +frees any data allocated for the context +.Fa ctx . +After +.Fn EVP_AEAD_CTX_cleanup , +.Fa ctx +is in the same state as after +.Fn EVP_AEAD_CTX_new . +.Pp +.Fn EVP_AEAD_CTX_open +authenticates the input +.Fa in +and optional additional data +.Fa ad , +decrypting the input and writing it as output +.Fa out . +This function may be called (with the same +.Vt EVP_AEAD_CTX ) +concurrently with itself or with +.Fn EVP_AEAD_CTX_seal . +At most the number of input bytes are written as output. +In order to ensure success, +.Fa max_out_len +should be at least the same as the input length +.Fa in_len . +On successful return +.Fa out_len +is set to the actual number of bytes written. +The length of the +.Fa nonce +specified with +.Fa nonce_len +must be equal to the result of EVP_AEAD_nonce_length for this AEAD. +.Fn EVP_AEAD_CTX_open +never results in partial output. +If +.Fa max_out_len +is insufficient, zero will be returned and +.Fa out_len +will be set to zero. +If the input and output are aliased then +.Fa out +must be <= +.Fa in . +.Pp +.Fn EVP_AEAD_CTX_seal +encrypts and authenticates the input and authenticates any additional +data provided in +.Fa ad , +the encrypted input and authentication tag being written as output +.Fa out . +This function may be called (with the same +.Vt EVP_AEAD_CTX ) +concurrently with itself or with +.Fn EVP_AEAD_CTX_open . +At most +.Fa max_out_len +bytes are written as output and, in order to ensure success, this value +should be the +.Fa in_len +plus the result of +.Fn EVP_AEAD_max_overhead . +On successful return, +.Fa out_len +is set to the actual number of bytes written. +The length of the +.Fa nonce +specified with +.Fa nonce_len +must be equal to the result of +.Fn EVP_AEAD_nonce_length +for this AEAD. +.Fn EVP_AEAD_CTX_seal +never results in a partial output. +If +.Fa max_out_len +is insufficient, zero will be returned and +.Fa out_len +will be set to zero. +If the input and output are aliased then +.Fa out +must be <= +.Fa in . +.Pp +.Fn EVP_AEAD_key_length , +.Fn EVP_AEAD_max_overhead , +.Fn EVP_AEAD_max_tag_len , +and +.Fn EVP_AEAD_nonce_length +provide information about the AEAD algorithm +.Fa aead . +.Pp +.Fn EVP_AEAD_max_tag_len +returns the maximum tag length that can be used with the given +.Fa aead . +This is the largest value that can be passed as the +.Fa tag_len +argument to +.Fn EVP_AEAD_CTX_init . +No built-in +.Vt EVP_AEAD +object has a maximum tag length larger than the constant +.Dv EVP_AEAD_MAX_TAG_LENGTH . +.Pp +All cipher algorithms have a fixed key length unless otherwise stated. +The following ciphers are available: +.Bl -tag -width Ds -offset indent +.It Fn EVP_aead_aes_128_gcm +AES-128 in Galois Counter Mode, using a +.Fa key_len +of 16 bytes and a +.Fa nonce_len +of 12 bytes. +.It Fn EVP_aead_aes_256_gcm +AES-256 in Galois Counter Mode, using a +.Fa key_len +of 32 bytes and a +.Fa nonce_len +of 12 bytes. +.It Fn EVP_aead_chacha20_poly1305 +ChaCha20 with a Poly1305 authenticator, using a +.Fa key_len +of 32 bytes and a +.Fa nonce_len +of 12 bytes. +The constant +.Dv EVP_CHACHAPOLY_TLS_TAG_LEN +specifies the length of the authentication tag in bytes and has a value of 16. +.It Fn EVP_aead_xchacha20_poly1305 +XChaCha20 with a Poly1305 authenticator, using a +.Fa key_len +of 32 bytes and a +.Fa nonce_len +of 24 bytes. +.El +.Pp +Unless compatibility with other implementations +like OpenSSL or BoringSSL is required, using the +.Sy EVP_AEAD +interface to AEAD ciphers is recommended +in preference to the functions documented in the +.Xr EVP_EncryptInit 3 , +.Xr EVP_aes_256_gcm 3 , +and +.Xr EVP_chacha20_poly1305 3 +manual pages. +The code then becomes transparent to the AEAD cipher used +and much more flexible. +It is also safer to use as it prevents common mistakes with the EVP APIs. +.Sh RETURN VALUES +.Fn EVP_AEAD_CTX_new +returns the new +.Vt EVP_AEAD_CTX +object on success; +otherwise +.Dv NULL +is returned and +.Va errno +is set to +.Er ENOMEM . +.Pp +.Fn EVP_AEAD_CTX_init , +.Fn EVP_AEAD_CTX_open , +and +.Fn EVP_AEAD_CTX_seal +return 1 for success or zero for failure. +.Pp +.Fn EVP_AEAD_key_length +returns the length of the key used for this AEAD. +.Pp +.Fn EVP_AEAD_max_overhead +returns the maximum number of additional bytes added by the act of +sealing data with the AEAD. +.Pp +.Fn EVP_AEAD_max_tag_len +returns the maximum tag length when using this AEAD. +.Pp +.Fn EVP_AEAD_nonce_length +returns the length of the per-message nonce. +.Sh EXAMPLES +Encrypt a string using ChaCha20-Poly1305: +.Bd -literal -offset indent +const EVP_AEAD *aead = EVP_aead_chacha20_poly1305(); +static const unsigned char nonce[32] = {0}; +size_t buf_len, nonce_len; +EVP_AEAD_CTX *ctx; + +ctx = EVP_AEAD_CTX_new(); +EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead), + EVP_AEAD_DEFAULT_TAG_LENGTH, NULL); +nonce_len = EVP_AEAD_nonce_length(aead); + +EVP_AEAD_CTX_seal(ctx, out, &out_len, BUFSIZE, nonce, + nonce_len, in, in_len, NULL, 0); + +EVP_AEAD_CTX_free(ctx); +.Ed +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh STANDARDS +.Rs +.%A A. Langley +.%A W. Chang +.%A N. Mavrogiannopoulos +.%A J. Strombergson +.%A S. Josefsson +.%D June 2016 +.%R RFC 7905 +.%T ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) +.Re +.Pp +.Rs +.%A S. Arciszewski +.%D October 2018 +.%R draft-arciszewski-xchacha-02 +.%T XChaCha: eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 +.Re +.Sh HISTORY +AEAD is based on the implementation by +.An Adam Langley +.\" OpenSSL commit 9a8646510b Sep 9 12:13:24 2013 -0400 +for Chromium/BoringSSL and first appeared in +.Ox 5.6 . +.Pp +.Fn EVP_AEAD_CTX_new +and +.Fn EVP_AEAD_CTX_free +first appeared in +.Ox 7.1 . +.Sh CAVEATS +The original publications and code by +.An Adam Langley +used a modified AEAD construction that is incompatible with the common +style used by AEAD in TLS and incompatible with RFC 7905: +.Pp +.Rs +.%A A. Langley +.%A W. Chang +.%D November 2013 +.%R draft-agl-tls-chacha20poly1305-04 +.%T ChaCha20 and Poly1305 based Cipher Suites for TLS +.Re +.Pp +.Rs +.%A Y. Nir +.%A A. Langley +.%D June 2018 +.%R RFC 8439 +.%T ChaCha20 and Poly1305 for IETF Protocols +.Re +.Pp +In particular, the original version used a +.Fa nonce_len +of 8 bytes. diff --git a/Libraries/libressl/man/EVP_BytesToKey.3 b/Libraries/libressl/man/EVP_BytesToKey.3 new file mode 100644 index 000000000..821259a51 --- /dev/null +++ b/Libraries/libressl/man/EVP_BytesToKey.3 @@ -0,0 +1,143 @@ +.\" $OpenBSD: EVP_BytesToKey.3,v 1.8 2019/06/07 20:46:25 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2001, 2011, 2013, 2014, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 7 2019 $ +.Dt EVP_BYTESTOKEY 3 +.Os +.Sh NAME +.Nm EVP_BytesToKey +.Nd password based encryption routine +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_BytesToKey +.Fa "const EVP_CIPHER *type" +.Fa "const EVP_MD *md" +.Fa "const unsigned char *salt" +.Fa "const unsigned char *data" +.Fa "int datal" +.Fa "int count" +.Fa "unsigned char *key" +.Fa "unsigned char *iv" +.Fc +.Sh DESCRIPTION +.Fn EVP_BytesToKey +derives a key and IV from various parameters. +.Fa type +is the cipher to derive the key and IV for. +.Fa md +is the message digest to use. +The +.Fa salt +parameter is used as a salt in the derivation: +it should point to an 8-byte buffer or +.Dv NULL +if no salt is used. +.Fa data +is a buffer containing +.Fa datal +bytes which is used to derive the keying data. +.Fa count +is the iteration count to use. +The derived key and IV will be written to +.Fa key +and +.Fa iv , +respectively. +.Pp +A typical application of this function is to derive keying material for +an encryption algorithm from a password in the +.Fa data +parameter. +.Pp +Increasing the +.Fa count +parameter slows down the algorithm, which makes it harder for an attacker +to perform a brute force attack using a large number of candidate +passwords. +.Pp +If the total key and IV length is less than the digest length and MD5 +is used, then the derivation algorithm is compatible with PKCS#5 v1.5. +Otherwise, a non-standard extension is used to derive the extra data. +.Pp +Newer applications should use more standard algorithms such as PBKDF2 as +defined in PKCS#5v2.1 for key derivation. +.Sh KEY DERIVATION ALGORITHM +The key and IV is derived by concatenating D_1, D_2, etc. until enough +data is available for the key and IV. +D_i is defined recursively as: +.Pp +.Dl D_i = HASH^count(D_(i-1) || data || salt) +.Pp +where || denotes concatenation, D_0 is empty, HASH is the digest +algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is +HASH(HASH(data)) and so on. +.Pp +The initial bytes are used for the key and the subsequent bytes for the +IV. +.Sh RETURN VALUES +If +.Fa data +is +.Dv NULL , +.Fn EVP_BytesToKey +returns the number of bytes needed to store the derived key. +Otherwise, +.Fn EVP_BytesToKey +returns the size of the derived key in bytes or 0 on error. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 , +.Xr PKCS5_PBKDF2_HMAC 3 +.Sh HISTORY +.Fn EVP_BytesToKey +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/EVP_CIPHER_CTX_ctrl.3 b/Libraries/libressl/man/EVP_CIPHER_CTX_ctrl.3 new file mode 100644 index 000000000..ba0e4b074 --- /dev/null +++ b/Libraries/libressl/man/EVP_CIPHER_CTX_ctrl.3 @@ -0,0 +1,264 @@ +.\" $OpenBSD: EVP_CIPHER_CTX_ctrl.3,v 1.2 2023/10/01 18:23:50 tb Exp $ +.\" full merge up to: OpenSSL 5211e094 Nov 11 14:39:11 2014 -0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2023 Ingo Schwarze +.\" Copyright (c) 2018 Damien Miller +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2001, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 1 2023 $ +.Dt EVP_CIPHER_CTX_CTRL 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_CTX_ctrl , +.Nm EVP_CIPHER_CTX_set_padding , +.Nm EVP_CIPHER_CTX_set_key_length , +.Nm EVP_CIPHER_CTX_key_length , +.Nm EVP_CIPHER_key_length , +.Nm EVP_CIPHER_CTX_iv_length , +.Nm EVP_CIPHER_iv_length , +.Nm EVP_CIPHER_CTX_set_iv , +.Nm EVP_CIPHER_CTX_get_iv +.Nd configure EVP cipher contexts +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_CIPHER_CTX_ctrl +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "int type" +.Fa "int arg" +.Fa "void *ptr" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_set_padding +.Fa "EVP_CIPHER_CTX *x" +.Fa "int padding" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_set_key_length +.Fa "EVP_CIPHER_CTX *x" +.Fa "int keylen" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_key_length +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft int +.Fo EVP_CIPHER_key_length +.Fa "const EVP_CIPHER *e" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_iv_length +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft int +.Fo EVP_CIPHER_iv_length +.Fa "const EVP_CIPHER *e" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_set_iv +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const unsigned char *iv" +.Fa "size_t len" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_get_iv +.Fa "const EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *iv" +.Fa "size_t len" +.Fc +.Sh DESCRIPTION +.Fn EVP_CIPHER_CTX_ctrl +allows various cipher specific parameters to be determined and set. +Currently only the RC2 effective key length can be set. +.Pp +.Fn EVP_CIPHER_CTX_set_padding +enables or disables padding. +This function should be called after the context is set up for +encryption or decryption with +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit_ex 3 , +or +.Xr EVP_CipherInit_ex 3 . +By default encryption operations are padded using standard block padding +and the padding is checked and removed when decrypting. +If the +.Fa padding +parameter is zero, then no padding is performed, the total amount of data +encrypted or decrypted must then be a multiple of the block size or an +error will occur. +.Pp +.Fn EVP_CIPHER_CTX_set_key_length +sets the key length of the cipher ctx. +If the cipher is a fixed length cipher, then attempting to set the key +length to any value other than the fixed value is an error. +.Pp +.Fn EVP_CIPHER_CTX_key_length +and +.Fn EVP_CIPHER_key_length +return the key length of a cipher when passed an +.Vt EVP_CIPHER_CTX +or +.Vt EVP_CIPHER +structure. +The constant +.Dv EVP_MAX_KEY_LENGTH +is the maximum key length for all ciphers. +Note: although +.Fn EVP_CIPHER_key_length +is fixed for a given cipher, the value of +.Fn EVP_CIPHER_CTX_key_length +may be different for variable key length ciphers. +.Pp +.Fn EVP_CIPHER_CTX_iv_length +and +.Fn EVP_CIPHER_iv_length +return the IV length of a cipher when passed an +.Vt EVP_CIPHER_CTX +or +.Vt EVP_CIPHER . +They will return zero if the cipher does not use an IV. +.Fn EVP_CIPHER_CTX_iv_length +can fail and return \-1. +The constant +.Dv EVP_MAX_IV_LENGTH +is the maximum IV length for all ciphers. +.Pp +.Fn EVP_CIPHER_CTX_set_iv +and +.Fn EVP_CIPHER_CTX_get_iv +set and retrieve the IV for an +.Vt EVP_CIPHER_CTX , +respectively. +In both cases, the specified IV length must exactly equal the expected +IV length for the context as returned by +.Fn EVP_CIPHER_CTX_iv_length . +.Sh RETURN VALUES +.Fn EVP_CIPHER_CTX_ctrl +usually returns 1 for success, 0 for failure, or \-1 if the +.Fa type +is not supported by the +.Fa ctx , +but there may be exceptions for some +.Fa type +arguments. +.Pp +.Fn EVP_CIPHER_CTX_set_padding +always returns 1. +.Pp +.Fn EVP_CIPHER_CTX_set_key_length , +.Fn EVP_CIPHER_CTX_set_iv , +and +.Fn EVP_CIPHER_CTX_get_iv +return 1 for success or 0 for failure. +.Pp +.Fn EVP_CIPHER_CTX_key_length +and +.Fn EVP_CIPHER_key_length +return the key length. +.Pp +.Fn EVP_CIPHER_CTX_iv_length +and +.Fn EVP_CIPHER_iv_length +return the IV length or zero if the cipher does not use an IV. +.Fn EVP_CIPHER_CTX_iv_length +can fail and return \-1. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_CIPHER_nid 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn EVP_CIPHER_CTX_key_length , +.Fn EVP_CIPHER_key_length , +.Fn EVP_CIPHER_CTX_iv_length , +and +.Fn EVP_CIPHER_iv_length +first appeared in SSLeay 0.6.5 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_CIPHER_CTX_ctrl +and +.Fn EVP_CIPHER_CTX_set_key_length +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn EVP_CIPHER_CTX_set_padding +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Pp +.Fn EVP_CIPHER_CTX_set_iv +and +.Fn EVP_CIPHER_CTX_get_iv +first appeared in LibreSSL 2.8.1 and have been available since +.Ox 6.4 . +.Sh BUGS +.Dv EVP_MAX_KEY_LENGTH +and +.Dv EVP_MAX_IV_LENGTH +only refer to the internal ciphers with default key lengths. +If custom ciphers exceed these values, the results are unpredictable. +This is because it has become standard practice to define a generic key +as a fixed unsigned char array containing +.Dv EVP_MAX_KEY_LENGTH +bytes. diff --git a/Libraries/libressl/man/EVP_CIPHER_CTX_get_cipher_data.3 b/Libraries/libressl/man/EVP_CIPHER_CTX_get_cipher_data.3 new file mode 100644 index 000000000..4f75c8b00 --- /dev/null +++ b/Libraries/libressl/man/EVP_CIPHER_CTX_get_cipher_data.3 @@ -0,0 +1,146 @@ +.\" $OpenBSD: EVP_CIPHER_CTX_get_cipher_data.3,v 1.3 2023/08/26 15:12:04 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Matt Caswell . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 26 2023 $ +.Dt EVP_CIPHER_CTX_GET_CIPHER_DATA 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_CTX_get_cipher_data , +.Nm EVP_CIPHER_CTX_set_cipher_data , +.Nm EVP_CIPHER_CTX_buf_noconst +.Nd inspect and modify EVP_CIPHER_CTX objects +.Sh SYNOPSIS +.In openssl/evp.h +.Ft void * +.Fo EVP_CIPHER_CTX_get_cipher_data +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft void * +.Fo EVP_CIPHER_CTX_set_cipher_data +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "void *cipher_data" +.Fc +.Ft unsigned char * +.Fo EVP_CIPHER_CTX_buf_noconst +.Fa "EVP_CIPHER_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn EVP_CIPHER_CTX_get_cipher_data +returns a pointer to the cipher data of +.Fa ctx . +The format and content of this data is specific to the algorithm +and to the particular implementation of the cipher. +For example, this data can be used by engines +to store engine specific information. +The data is automatically allocated and freed by OpenSSL, so +applications and engines should not normally free this directly (but see +below). +.Pp +.Fn EVP_CIPHER_CTX_set_cipher_data +allows an application or engine to replace the existing cipher data +with new data, transferring ownership of +.Fa cipher_data +to the +.Fa ctx +object. +A pointer to any existing cipher data is returned from this function. +If the old data is no longer required, +it should be freed through a call to +.Xr free 3 . +.Pp +.Fn EVP_CIPHER_CTX_buf_noconst +provides engines and custom cipher implementations +with access to the internal buffer that +.Xr EVP_EncryptUpdate 3 +copies input data into before encrypting it. +This function can for example be used +inside callback functions installed with +.Xr EVP_CIPHER_meth_set_do_cipher 3 . +.Sh RETURN VALUES +.Fn EVP_CIPHER_CTX_get_cipher_data +returns an internal pointer owned by +.Fa ctx . +.Pp +.Fn EVP_CIPHER_CTX_set_cipher_data +returns a pointer to the old cipher data of +.Fa ctx +and transfers ownership to the caller. +.Pp +.Fn EVP_CIPHER_CTX_buf_noconst +returns a pointer to an internal buffer owned by +.Fa ctx . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_CIPHER_meth_new 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn EVP_CIPHER_CTX_get_cipher_data , +.Fn EVP_CIPHER_CTX_set_cipher_data , +and +.Fn EVP_CIPHER_CTX_buf_noconst +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/EVP_CIPHER_CTX_set_flags.3 b/Libraries/libressl/man/EVP_CIPHER_CTX_set_flags.3 new file mode 100644 index 000000000..67ef8679b --- /dev/null +++ b/Libraries/libressl/man/EVP_CIPHER_CTX_set_flags.3 @@ -0,0 +1,233 @@ +.\" $OpenBSD: EVP_CIPHER_CTX_set_flags.3,v 1.2 2023/09/06 16:26:49 schwarze Exp $ +.\" full merge up to: OpenSSL 5211e094 Nov 11 14:39:11 2014 -0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Patrick Steuer . +.\" Copyright (c) 2000, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 6 2023 $ +.Dt EVP_CIPHER_CTX_SET_FLAGS 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_CTX_set_flags , +.Nm EVP_CIPHER_CTX_clear_flags , +.Nm EVP_CIPHER_CTX_test_flags , +.Nm EVP_CIPHER_CTX_rand_key , +.Nm EVP_CIPHER_param_to_asn1 , +.Nm EVP_CIPHER_asn1_to_param , +.\" .Nm EVP_CIPHER_set_asn1_iv and +.\" .Nm EVP_CIPHER_get_asn1_iv are intentionally undocumented +.\" because they are unused according to codesearch.debian.net +.\" and should probably not be public: they seem hardly useful +.\" even for implementing custom EVP_CIPHER algorithms. +.Nm EVP_CIPHER_CTX_get_app_data , +.Nm EVP_CIPHER_CTX_set_app_data +.Nd unusual EVP cipher context configuration +.Sh SYNOPSIS +.In openssl/evp.h +.Ft void +.Fo EVP_CIPHER_CTX_set_flags +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "int flags" +.Fc +.Ft void +.Fo EVP_CIPHER_CTX_clear_flags +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "int flags" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_test_flags +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "int flags" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_rand_key +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *key" +.Fc +.Ft int +.Fo EVP_CIPHER_param_to_asn1 +.Fa "EVP_CIPHER_CTX *c" +.Fa "ASN1_TYPE *type" +.Fc +.Ft int +.Fo EVP_CIPHER_asn1_to_param +.Fa "EVP_CIPHER_CTX *c" +.Fa "ASN1_TYPE *type" +.Fc +.Ft void * +.Fo EVP_CIPHER_CTX_get_app_data +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft void +.Fo EVP_CIPHER_CTX_set_app_data +.Fa "const EVP_CIPHER_CTX *ctx" +.Fa "void *data" +.Fc +.Sh DESCRIPTION +.Fn EVP_CIPHER_CTX_set_flags +enables the given +.Fa flags +in +.Fa ctx . +.Fn EVP_CIPHER_CTX_clear_flags +disables the given +.Fa flags +in +.Fa ctx . +.Fn EVP_CIPHER_CTX_test_flags +checks whether any of the given +.Fa flags +are currently set in +.Fa ctx , +returning the subset of the +.Fa flags +that are set, or 0 if none of them are set. +Currently, the only supported cipher context flag is +.Dv EVP_CIPHER_CTX_FLAG_WRAP_ALLOW ; +see +.Xr EVP_aes_128_wrap 3 +for details. +.Pp +.Fn EVP_CIPHER_CTX_rand_key +generates a random key of the appropriate length based on the cipher +context. +The +.Vt EVP_CIPHER +can provide its own random key generation routine to support keys +of a specific form. +The +.Fa key +argument must point to a buffer at least as big as the value returned by +.Xr EVP_CIPHER_CTX_key_length 3 . +.Pp +.Fn EVP_CIPHER_param_to_asn1 +sets the ASN.1 +.Vt AlgorithmIdentifier +parameter based on the passed cipher. +This will typically include any parameters and an IV. +The cipher IV (if any) must be set when this call is made. +This call should be made before the cipher is actually "used" (before any +.Xr EVP_EncryptUpdate 3 +or +.Xr EVP_DecryptUpdate 3 +calls, for example). +This function may fail if the cipher does not have any ASN.1 support. +.Pp +.Fn EVP_CIPHER_asn1_to_param +sets the cipher parameters based on an ASN.1 +.Vt AlgorithmIdentifier +parameter. +The precise effect depends on the cipher. +In the case of RC2, for example, it will set the IV and effective +key length. +This function should be called after the base cipher type is set but +before the key is set. +For example +.Xr EVP_CipherInit 3 +will be called with the IV and key set to +.Dv NULL , +.Fn EVP_CIPHER_asn1_to_param +will be called and finally +.Xr EVP_CipherInit 3 +again with all parameters except the key set to +.Dv NULL . +It is possible for this function to fail if the cipher does not +have any ASN.1 support or the parameters cannot be set (for example +the RC2 effective key length is not supported). +.Sh RETURN VALUES +.Fn EVP_CIPHER_CTX_rand_key +return 1 for success or 0 for failure. +.Pp +.Fn EVP_CIPHER_param_to_asn1 +and +.Fn EVP_CIPHER_asn1_to_param +return greater than zero for success and zero or a negative number +for failure. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_CIPHER_CTX_ctrl 3 , +.Xr EVP_CIPHER_CTX_get_cipher_data 3 , +.Xr EVP_CIPHER_nid 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn EVP_CIPHER_CTX_set_app_data +and +.Fn EVP_CIPHER_CTX_get_app_data +first appeared in SSLeay 0.8.0. +.Fn EVP_CIPHER_param_to_asn1 +and +.Fn EVP_CIPHER_asn1_to_param +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_CIPHER_CTX_rand_key +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Sh BUGS +The ASN.1 code is incomplete (and sometimes inaccurate). +It has only been tested for certain common S/MIME ciphers +(RC2, DES, triple DES) in CBC mode. diff --git a/Libraries/libressl/man/EVP_CIPHER_do_all.3 b/Libraries/libressl/man/EVP_CIPHER_do_all.3 new file mode 100644 index 000000000..1d43d503d --- /dev/null +++ b/Libraries/libressl/man/EVP_CIPHER_do_all.3 @@ -0,0 +1,134 @@ +.\" $OpenBSD: EVP_CIPHER_do_all.3,v 1.1 2023/08/30 00:58:57 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 30 2023 $ +.Dt EVP_CIPHER_DO_ALL 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_do_all , +.Nm EVP_CIPHER_do_all_sorted , +.Nm EVP_MD_do_all , +.Nm EVP_MD_do_all_sorted +.Nd iterate over lookup tables for ciphers and digests +.Sh SYNOPSIS +.In openssl/evp.h +.Ft void +.Fo EVP_CIPHER_do_all +.Fa "void (*fn)(const EVP_CIPHER *cipher, const char *from,\ + const char *to, void *arg)" +.Fa "void *arg" +.Fc +.Ft void +.Fo EVP_CIPHER_do_all_sorted +.Fa "void (*fn)(const EVP_CIPHER *cipher, const char *from,\ + const char *to, void *arg)" +.Fa "void *arg" +.Fc +.Ft void +.Fo EVP_MD_do_all +.Fa "void (*fn)(const EVP_MD *md, const char *from,\ + const char *to, void *arg)" +.Fa "void *arg" +.Fc +.Ft void +.Fo EVP_MD_do_all_sorted +.Fa "void (*fn)(const EVP_MD *md, const char *from,\ + const char *to, void *arg)" +.Fa "void *arg" +.Fc +.Sh DESCRIPTION +.Fn EVP_CIPHER_do_all +calls +.Fa fn +on every entry of the global table of cipher names and aliases. +For a cipher name entry, +.Fa fn +is called with a non-NULL +.Fa cipher , +its non-NULL cipher name +.Fa from , +a NULL +.Fa to , +and the +.Fa arg +pointer. +For an alias entry, +.Fa fn +is called with a NULL +.Fa cipher , +its alias +.Fa from , +the cipher name that alias points +.Fa to , +and the +.Fa arg +pointer. +.Pp +.Fn EVP_CIPHER_do_all_sorted +is similar, except that it processes the cipher names and aliases +in lexicographic order of their +.Fa from +names as determined by +.Xr strcmp 3 . +.Pp +.Fn EVP_MD_do_all +calls +.Fa fn +on every entry of the global table of digest names and aliases. +For a digest name entry, +.Fa fn +is called with a non-NULL +.Fa md , +its non-NULL digest name +.Fa from , +a NULL +.Fa to , +and the +.Fa arg +pointer. +For an alias entry, +.Fa fn +is called with a NULL +.Fa md , +its alias +.Fa from , +the digest name that alias points +.Fa to , +and the +.Fa arg +pointer. +.Pp +.Fn EVP_MD_do_all_sorted +is similar, except that it processes the digest names and aliases +in lexicographic order of their +.Fa from +names as determined by +.Xr strcmp 3 . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_add_cipher 3 , +.Xr OBJ_NAME_do_all 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Sh BUGS +.Fn EVP_CIPHER_do_all_sorted +and +.Fn EVP_MD_do_all_sorted +are wrappers of +.Xr OBJ_NAME_do_all_sorted 3 . +In particular, if memory allocation fails, they do nothing at all +without telling the caller about the problem. diff --git a/Libraries/libressl/man/EVP_CIPHER_meth_new.3 b/Libraries/libressl/man/EVP_CIPHER_meth_new.3 new file mode 100644 index 000000000..4ea8f8dfe --- /dev/null +++ b/Libraries/libressl/man/EVP_CIPHER_meth_new.3 @@ -0,0 +1,400 @@ +.\" $OpenBSD: EVP_CIPHER_meth_new.3,v 1.5 2023/09/10 05:22:46 jsg Exp $ +.\" selective merge up to: OpenSSL b0edda11 Mar 20 13:00:17 2018 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte +.\" Copyright (c) 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2023 $ +.Dt EVP_CIPHER_METH_NEW 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_meth_new , +.Nm EVP_CIPHER_meth_dup , +.Nm EVP_CIPHER_meth_free , +.Nm EVP_CIPHER_meth_set_iv_length , +.Nm EVP_CIPHER_meth_set_flags , +.Nm EVP_CIPHER_meth_set_impl_ctx_size , +.Nm EVP_CIPHER_meth_set_init , +.Nm EVP_CIPHER_meth_set_do_cipher , +.Nm EVP_CIPHER_meth_set_cleanup , +.Nm EVP_CIPHER_meth_set_set_asn1_params , +.Nm EVP_CIPHER_meth_set_get_asn1_params , +.Nm EVP_CIPHER_meth_set_ctrl +.Nd Routines to build up EVP_CIPHER methods +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_CIPHER * +.Fo EVP_CIPHER_meth_new +.Fa "int cipher_type" +.Fa "int block_size" +.Fa "int key_len" +.Fc +.Ft EVP_CIPHER * +.Fo EVP_CIPHER_meth_dup +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft void +.Fo EVP_CIPHER_meth_free +.Fa "EVP_CIPHER *cipher" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_iv_length +.Fa "EVP_CIPHER *cipher" +.Fa "int iv_len" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_flags +.Fa "EVP_CIPHER *cipher" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_impl_ctx_size +.Fa "EVP_CIPHER *cipher" +.Fa "int ctx_size" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_init +.Fa "EVP_CIPHER *cipher" +.Fa "int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,\ + const unsigned char *iv, int enc)" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_do_cipher +.Fa "EVP_CIPHER *cipher" +.Fa "int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,\ + const unsigned char *in, size_t inl)" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_cleanup +.Fa "EVP_CIPHER *cipher" +.Fa "int (*cleanup)(EVP_CIPHER_CTX *)" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_set_asn1_params +.Fa "EVP_CIPHER *cipher" +.Fa "int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_get_asn1_params +.Fa "EVP_CIPHER *cipher" +.Fa "int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)" +.Fc +.Ft int +.Fo EVP_CIPHER_meth_set_ctrl +.Fa "EVP_CIPHER *cipher" +.Fa "int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr)" +.Fc +.Sh DESCRIPTION +The +.Vt EVP_CIPHER +type is a structure holding function pointers for +a symmetric cipher implementation. +.Pp +.Fn EVP_CIPHER_meth_new +allocates a new +.Vt EVP_CIPHER +structure. +The cipher's NID (see +.Xr EVP_CIPHER_nid 3 ) +is set to +.Fa cipher_type , +the block size and key length are set to +.Fa block_size +and +.Fa key_len , +respectively. +.Pp +.Fn EVP_CIPHER_meth_dup +creates a copy of +.Fa cipher . +.Pp +.Fn EVP_CIPHER_meth_free +frees an +.Vt EVP_CIPHER +structure. +.Pp +.Fn EVP_CIPHER_meth_set_iv_length +sets the length of the initialization vector. +This is only needed when the implemented cipher mode requires it. +.Pp +.Fn EVP_CIPHER_meth_set_flags +overwrites the flags to describe optional behaviours in +.Fa cipher +with +.Fa flags . +At most one of the following cipher modes can be set: +.Dv EVP_CIPH_STREAM_CIPHER , +.Dv EVP_CIPH_ECB_MODE , +.Dv EVP_CIPH_CBC_MODE , +.Dv EVP_CIPH_CFB_MODE , +.Dv EVP_CIPH_OFB_MODE , +.Dv EVP_CIPH_CTR_MODE , +.Dv EVP_CIPH_GCM_MODE , +.Dv EVP_CIPH_CCM_MODE , +.Dv EVP_CIPH_XTS_MODE , +and +.Dv EVP_CIPH_WRAP_MODE . +.Pp +Zero or more of the following flags can be OR'ed into the +.Fa flags +argument: +.Bl -tag -width Ds +.It Dv EVP_CIPH_VARIABLE_LENGTH +This cipher has a variable key length, and the function +.Xr EVP_CIPHER_CTX_set_key_length 3 +can be used with it. +.It Dv EVP_CIPH_CUSTOM_IV +Instruct +.Xr EVP_CipherInit_ex 3 +and similar initialization functions to leave storing and initialising +the IV entirely to the implementation. +If this flag is set, +the implementation is typically expected to do that in its +.Fa init +function. +.It Dv EVP_CIPH_ALWAYS_CALL_INIT +Instruct +.Xr EVP_CipherInit_ex 3 +and similar initialization functions to call the implementation's +.Fa init +function even if the +.Fa key +argument is +.Dv NULL . +.It Dv EVP_CIPH_CTRL_INIT +Instruct +.Xr EVP_CipherInit_ex 3 +and similar initialization functions to call the implementation's +.Fa ctrl +function with a command +.Fa type +of +.Dv EVP_CTRL_INIT +early during the setup. +.It Dv EVP_CIPH_CUSTOM_KEY_LENGTH +Instruct +.Xr EVP_CIPHER_CTX_set_key_length 3 +to not check and set the key length itself, +but to leave that to the implementation by instead calling its +.Fa ctrl +function with a command +.Fa type +of +.Dv EVP_CTRL_SET_KEY_LENGTH +and the key length in +.Fa arg . +.It Dv EVP_CIPH_NO_PADDING +Instruct +.Xr EVP_CipherFinal_ex 3 +and similar finalization functions to not use standard block padding +but instead report an error if the total amount of data +to be encrypted or decrypted is not a multiple of the block size. +.It Dv EVP_CIPH_RAND_KEY +Instruct +.Xr EVP_CIPHER_CTX_rand_key 3 +to not generate a random key using +.Xr arc4random_buf 3 +but instead leave that to the implementation by calling the +.Fa ctrl +function with a command +.Fa type +of +.Dv EVP_CTRL_RAND_KEY +and the pointer to the key memory storage in +.Fa ptr . +.It Dv EVP_CIPH_CUSTOM_COPY +Instruct +.Xr EVP_CIPHER_CTX_copy 3 +to call the implementation's +.Fa ctrl +function with a command +.Fa type +of +.Dv EVP_CTRL_COPY +and the destination +.Fa "EVP_CIPHER_CTX *out" +in the +.Fa ptr +argument immediately before returning successfully. +The intended use is for further things to deal with after the +implementation specific data block has been copied. +The implementation-specific data block is reached with +.Xr EVP_CIPHER_CTX_get_cipher_data 3 . +.It Dv EVP_CIPH_FLAG_DEFAULT_ASN1 +Instruct +.Xr EVP_CIPHER_param_to_asn1 3 +to use +.Xr ASN1_TYPE_set_octetstring 3 +if no +.Fa set_asn1_parameters +function is installed, and instruct +.Xr EVP_CIPHER_asn1_to_param 3 +to use +.Xr ASN1_TYPE_get_octetstring 3 +if no +.Fa get_asn1_parameters +function is installed. +.It Dv EVP_CIPH_FLAG_LENGTH_BITS +Signals that the length of the input buffer for encryption / decryption +is to be understood as the number of bits instead of bytes for this +implementation. +This is only useful for CFB1 ciphers. +.It Dv EVP_CIPH_FLAG_CUSTOM_CIPHER +Instruct +.Xr EVP_CipherUpdate 3 , +.Xr EVP_CipherFinal_ex 3 , +and similar encryption, decryption, and finalization functions +that the implementation's +.Fa do_cipher +function takes care of everything, +including padding, buffering and finalization. +.It Dv EVP_CIPH_FLAG_AEAD_CIPHER +This indicates that this is an AEAD cipher implementation. +.El +.Pp +.Fn EVP_CIPHER_meth_set_impl_ctx_size +sets the size of the EVP_CIPHER's implementation context so that it can +be automatically allocated. +.Pp +.Fn EVP_CIPHER_meth_set_init +sets the +.Fa init +function for +.Fa cipher . +The cipher init function is called by +.Xr EVP_CipherInit 3 , +.Xr EVP_CipherInit_ex 3 , +.Xr EVP_EncryptInit 3 , +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit 3 , +and +.Xr EVP_DecryptInit_ex 3 . +.Pp +.Fn EVP_CIPHER_meth_set_do_cipher +sets the cipher function for +.Fa cipher . +The cipher function is called by +.Xr EVP_CipherUpdate 3 , +.Xr EVP_EncryptUpdate 3 , +.Xr EVP_DecryptUpdate 3 , +.Xr EVP_CipherFinal 3 , +.Xr EVP_EncryptFinal 3 , +.Xr EVP_EncryptFinal_ex 3 , +.Xr EVP_DecryptFinal 3 +and +.Xr EVP_DecryptFinal_ex 3 . +.Pp +.Fn EVP_CIPHER_meth_set_cleanup +sets the function for +.Fa cipher +to do extra cleanup before the method's private data structure is +cleaned out and freed. +Note that the cleanup function is passed a +.Sy EVP_CIPHER_CTX * , +the private data structure is then available with +.Xr EVP_CIPHER_CTX_get_cipher_data 3 . +This cleanup function is called by +.Xr EVP_CIPHER_CTX_reset 3 +and +.Xr EVP_CIPHER_CTX_free 3 . +.Pp +.Fn EVP_CIPHER_meth_set_set_asn1_params +sets the function for +.Fa cipher +to set the AlgorithmIdentifier "parameter" based on the passed cipher. +This function is called by +.Xr EVP_CIPHER_param_to_asn1 3 . +.Fn EVP_CIPHER_meth_set_get_asn1_params +sets the function for +.Fa cipher +that sets the cipher parameters based on an ASN.1 AlgorithmIdentifier +"parameter". +Both these functions are needed when there is a need for custom data +(more or other than the cipher IV). They are called by +.Xr EVP_CIPHER_param_to_asn1 3 +and +.Xr EVP_CIPHER_asn1_to_param 3 +respectively if defined. +.Pp +.Fn EVP_CIPHER_meth_set_ctrl +sets the control function for +.Fa cipher . +.Sh RETURN VALUES +.Fn EVP_CIPHER_meth_new +and +.Fn EVP_CIPHER_meth_dup +return a pointer to a newly created +.Vt EVP_CIPHER , +or NULL on failure. +.Pp +All +.Fn EVP_CIPHER_meth_set_* +functions return 1. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.3 . diff --git a/Libraries/libressl/man/EVP_CIPHER_nid.3 b/Libraries/libressl/man/EVP_CIPHER_nid.3 new file mode 100644 index 000000000..1feff4f34 --- /dev/null +++ b/Libraries/libressl/man/EVP_CIPHER_nid.3 @@ -0,0 +1,306 @@ +.\" $OpenBSD: EVP_CIPHER_nid.3,v 1.3 2023/09/05 14:54:21 schwarze Exp $ +.\" full merge up to: OpenSSL man3/EVP_EncryptInit.pod +.\" 0874d7f2 Oct 11 13:13:47 2022 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 5 2023 $ +.Dt EVP_CIPHER_NID 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_nid , +.Nm EVP_CIPHER_CTX_nid , +.Nm EVP_CIPHER_name , +.Nm EVP_CIPHER_type , +.Nm EVP_CIPHER_CTX_type , +.Nm EVP_CIPHER_block_size , +.Nm EVP_CIPHER_CTX_block_size , +.Nm EVP_CIPHER_flags , +.Nm EVP_CIPHER_CTX_flags , +.Nm EVP_CIPHER_mode , +.Nm EVP_CIPHER_CTX_mode +.Nd inspect EVP_CIPHER objects +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_CIPHER_nid +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_nid +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft const char * +.Fo EVP_CIPHER_name +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft int +.Fo EVP_CIPHER_type +.Fa "const EVP_CIPHER *ctx" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_type +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft int +.Fo EVP_CIPHER_block_size +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_block_size +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft unsigned long +.Fo EVP_CIPHER_flags +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft unsigned long +.Fo EVP_CIPHER_CTX_flags +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft unsigned long +.Fo EVP_CIPHER_mode +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft unsigned long +.Fo EVP_CIPHER_CTX_mode +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn EVP_CIPHER_nid +returns the numerical identifier (NID) of the +.Fa cipher . +The NID is an internal value which may or may not have a corresponding +ASN.1 OBJECT IDENTIFIER; see +.Xr OBJ_nid2obj 3 +for details. +.Pp +.Fn EVP_CIPHER_CTX_nid +returns the NID of the cipher that +.Fa ctx +is configured to use. +.Pp +.Fn EVP_CIPHER_name +converts the NID of the +.Fa cipher +to its short name with +.Xr OBJ_nid2sn 3 . +.Pp +.Fn EVP_CIPHER_type +returns the NID associated with the ASN.1 OBJECT IDENTIFIER of the +.Fa cipher , +ignoring the cipher parameters. +For example, +.Xr EVP_aes_256_cfb1 3 , +.Xr EVP_aes_256_cfb8 3 , +and +.Xr EVP_aes_256_cfb128 3 +all return the same NID, +.Dv NID_aes_256_cfb128 . +.Pp +.Fn EVP_CIPHER_CTX_type +returns the NID associated with the ASN.1 OBJECT IDENTIFIER of the cipher that +.Fa ctx +is configured to use. +.Pp +.Fn EVP_CIPHER_block_size +returns the block size of the +.Fa cipher +in bytes. +.Fn EVP_CIPHER_CTX_block_size +returns the block size of the cipher that +.Fa ctx +is configured to use. +Block sizes are guaranteed to be less than or equal to the constant +.Dv EVP_MAX_BLOCK_LENGTH . +Currently, +.Xr EVP_CipherInit_ex 3 +and the other functions documented in the same manual page +only support block sizes of 1, 8, and 16 bytes. +.Pp +.Fn EVP_CIPHER_flags +returns the cipher flags used by the +.Fa cipher . +The meaning of the flags is described in the +.Xr EVP_CIPHER_meth_set_flags 3 +manual page. +.Pp +.Fn EVP_CIPHER_CTX_flags +returns the cipher flags of the cipher that +.Fa ctx +is configured to use. +Be careful to not confuse these with the unrelated cipher context flags +that can be inspected with +.Xr EVP_CIPHER_CTX_test_flags 3 . +.Pp +.Fn EVP_CIPHER_mode +returns the +.Fa cipher +mode, which is the logical AND of the constant +.Dv EVP_CIPH_MODE +and the return value of +.Fn EVP_CIPHER_flags . +.Pp +.Fn EVP_CIPHER_CTX_mode +returns the cipher mode of the cipher that +.Fa ctx +is configured to use. +.Pp +.Fn EVP_CIPHER_name , +.Fn EVP_CIPHER_CTX_type , +.Fn EVP_CIPHER_mode , +and +.Fn EVP_CIPHER_CTX_mode +are implemented as macros. +.Sh RETURN VALUES +.Fn EVP_CIPHER_nid +and +.Fn EVP_CIPHER_CTX_nid +return an NID. +.Pp +.Fn EVP_CIPHER_name +returns a pointer to a string that is owned by an internal library object or +.Dv NULL +if the NID is neither built into the library nor added to the global +object table by one of the functions documented in the manual page +.Xr OBJ_create 3 , +of if the object does not contain a short name. +.Pp +.Fn EVP_CIPHER_type +and +.Fn EVP_CIPHER_CTX_type +return the NID of the cipher's OBJECT IDENTIFIER or +.Dv NID_undef +if it is not associated with an OBJECT IDENTIFIER. +.Pp +.Fn EVP_CIPHER_block_size +and +.Fn EVP_CIPHER_CTX_block_size +return the block size in bytes. +.Pp +.Fn EVP_CIPHER_flags +and +.Fn EVP_CIPHER_CTX_flags +return one or more +.Dv EVP_CIPH_* +flag bits OR'ed together. +.Pp +.Fn EVP_CIPHER_mode +and +.Fn EVP_CIPHER_CTX_mode +return one of the constants +.Dv EVP_CIPH_ECB_MODE , +.Dv EVP_CIPH_CBC_MODE , +.Dv EVP_CIPH_CFB_MODE , +.Dv EVP_CIPH_OFB_MODE , +.Dv EVP_CIPH_CTR_MODE , +.Dv EVP_CIPH_GCM_MODE , +.Dv EVP_CIPH_CCM_MODE , +.Dv EVP_CIPH_XTS_MODE , +or +.Dv EVP_CIPH_WRAP_MODE +to indicate a block cipher or +.Dv EVP_CIPH_STREAM_CIPHER +to indicate a stream cipher. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_CIPHER_CTX_ctrl 3 , +.Xr EVP_EncryptInit 3 , +.Xr OBJ_nid2obj 3 +.Sh HISTORY +.Fn EVP_CIPHER_type , +.Fn EVP_CIPHER_CTX_type , +.Fn EVP_CIPHER_block_size , +and +.Fn EVP_CIPHER_CTX_block_size +first appeared in SSLeay 0.6.5. +.Fn EVP_CIPHER_nid +and +.Fn EVP_CIPHER_CTX_nid +first appeared in SSLeay 0.8.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_CIPHER_flags , +.Fn EVP_CIPHER_CTX_flags , +.Fn EVP_CIPHER_mode , +and +.Fn EVP_CIPHER_CTX_mode +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn EVP_CIPHER_name +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh CAVEATS +The behaviour of the functions taking an +.Vt EVP_CIPHER_CTX +argument is undefined if they are called on a +.Fa ctx +that has no cipher configured yet, for example one freshly returned from +.Xr EVP_CIPHER_CTX_new 3 . +In that case, the program may for example be terminated by a +.Dv NULL +pointer access. diff --git a/Libraries/libressl/man/EVP_DigestInit.3 b/Libraries/libressl/man/EVP_DigestInit.3 new file mode 100644 index 000000000..a5ce6f84f --- /dev/null +++ b/Libraries/libressl/man/EVP_DigestInit.3 @@ -0,0 +1,613 @@ +.\" $OpenBSD: EVP_DigestInit.3,v 1.31 2023/09/07 19:59:58 schwarze Exp $ +.\" full merge up to: OpenSSL 7f572e95 Dec 2 13:57:04 2015 +0000 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson , +.\" Richard Levitte , +.\" Paul Yang , and +.\" Antoine Salon . +.\" Copyright (c) 2000-2004, 2009, 2012-2016, 2018, 2019 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 7 2023 $ +.Dt EVP_DIGESTINIT 3 +.Os +.Sh NAME +.Nm EVP_MD_CTX_new , +.Nm EVP_MD_CTX_reset , +.Nm EVP_MD_CTX_free , +.Nm EVP_MD_CTX_init , +.Nm EVP_MD_CTX_create , +.Nm EVP_MD_CTX_cleanup , +.Nm EVP_MD_CTX_destroy , +.Nm EVP_DigestInit_ex , +.Nm EVP_DigestUpdate , +.Nm EVP_DigestFinal_ex , +.Nm EVP_Digest , +.Nm EVP_MD_CTX_copy_ex , +.Nm EVP_DigestInit , +.Nm EVP_DigestFinal , +.Nm EVP_MD_CTX_copy , +.Nm EVP_MD_CTX_md , +.Nm EVP_md_null , +.Nm EVP_sha224 , +.Nm EVP_sha256 , +.Nm EVP_sha384 , +.Nm EVP_sha512 , +.Nm EVP_sha512_224 , +.Nm EVP_sha512_256 , +.Nm EVP_ripemd160 , +.Nm EVP_get_digestbyname , +.Nm EVP_get_digestbynid , +.Nm EVP_get_digestbyobj +.Nd EVP digest routines +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_MD_CTX * +.Fn EVP_MD_CTX_new void +.Ft int +.Fo EVP_MD_CTX_reset +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft void +.Fo EVP_MD_CTX_free +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft void +.Fo EVP_MD_CTX_init +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft EVP_MD_CTX * +.Fn EVP_MD_CTX_create void +.Ft int +.Fo EVP_MD_CTX_cleanup +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft void +.Fo EVP_MD_CTX_destroy +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft int +.Fo EVP_DigestInit_ex +.Fa "EVP_MD_CTX *ctx" +.Fa "const EVP_MD *type" +.Fa "ENGINE *impl" +.Fc +.Ft int +.Fo EVP_DigestUpdate +.Fa "EVP_MD_CTX *ctx" +.Fa "const void *d" +.Fa "size_t cnt" +.Fc +.Ft int +.Fo EVP_DigestFinal_ex +.Fa "EVP_MD_CTX *ctx" +.Fa "unsigned char *md" +.Fa "unsigned int *s" +.Fc +.Ft int +.Fo EVP_Digest +.Fa "const void *d" +.Fa "size_t cnt" +.Fa "unsigned char *md" +.Fa "unsigned int *s" +.Fa "const EVP_MD *type" +.Fa "ENGINE *impl" +.Fc +.Ft int +.Fo EVP_MD_CTX_copy_ex +.Fa "EVP_MD_CTX *out" +.Fa "const EVP_MD_CTX *in" +.Fc +.Ft int +.Fo EVP_DigestInit +.Fa "EVP_MD_CTX *ctx" +.Fa "const EVP_MD *type" +.Fc +.Ft int +.Fo EVP_DigestFinal +.Fa "EVP_MD_CTX *ctx" +.Fa "unsigned char *md" +.Fa "unsigned int *s" +.Fc +.Ft int +.Fo EVP_MD_CTX_copy +.Fa "EVP_MD_CTX *out" +.Fa "EVP_MD_CTX *in" +.Fc +.Ft const EVP_MD * +.Fo EVP_MD_CTX_md +.Fa "const EVP_MD_CTX *ctx" +.Fc +.Ft const EVP_MD * +.Fn EVP_md_null void +.Ft const EVP_MD * +.Fn EVP_sha224 void +.Ft const EVP_MD * +.Fn EVP_sha256 void +.Ft const EVP_MD * +.Fn EVP_sha384 void +.Ft const EVP_MD * +.Fn EVP_sha512 void +.Ft const EVP_MD * +.Fn EVP_sha512_224 void +.Ft const EVP_MD * +.Fn EVP_sha512_256 void +.Ft const EVP_MD * +.Fn EVP_ripemd160 void +.Ft const EVP_MD * +.Fo EVP_get_digestbyname +.Fa "const char *name" +.Fc +.Ft const EVP_MD * +.Fo EVP_get_digestbynid +.Fa "int type" +.Fc +.Ft const EVP_MD * +.Fo EVP_get_digestbyobj +.Fa "const ASN1_OBJECT *o" +.Fc +.Sh DESCRIPTION +The EVP digest routines are a high-level interface to message digests +and should be used instead of the cipher-specific functions. +.Pp +.Fn EVP_MD_CTX_new +allocates a new, empty digest context. +.Pp +.Fn EVP_MD_CTX_reset +cleans up +.Fa ctx +and resets it to the state it had after +.Fn EVP_MD_CTX_new , +such that it can be reused. +.Pp +.Fn EVP_MD_CTX_free +cleans up +.Fa ctx +and frees the space allocated to it. +.Pp +.Fn EVP_MD_CTX_init +is a deprecated function to clear a digest context on the stack +before use. +Do not use it on a digest context returned from +.Fn EVP_MD_CTX_new +or one that was already used. +.Pp +.Fn EVP_MD_CTX_create , +.Fn EVP_MD_CTX_cleanup , +and +.Fn EVP_MD_CTX_destroy +are deprecated aliases for +.Fn EVP_MD_CTX_new , +.Fn EVP_MD_CTX_reset , +and +.Fn EVP_MD_CTX_free , +respectively. +.Pp +.Fn EVP_DigestInit_ex +sets up the digest context +.Fa ctx +to use a digest +.Fa type +from +.Vt ENGINE +.Fa impl . +The +.Fa type +will typically be supplied by a function such as +.Fn EVP_sha512 . +If +.Fa impl +is +.Dv NULL , +then the default implementation of digest +.Fa type +is used. +.Pp +.Fn EVP_DigestUpdate +hashes +.Fa cnt +bytes of data at +.Fa d +into the digest context +.Fa ctx . +This function can be called several times on the same +.Fa ctx +to hash additional data. +.Pp +.Fn EVP_DigestFinal_ex +retrieves the digest value from +.Fa ctx +and places it in +.Fa md . +If the +.Fa s +parameter is not +.Dv NULL , +then the number of bytes of data written (i.e. the length of the +digest) will be written to the integer at +.Fa s ; +at most +.Dv EVP_MAX_MD_SIZE +bytes will be written. +After calling +.Fn EVP_DigestFinal_ex , +no additional calls to +.Fn EVP_DigestUpdate +can be made, but +.Fn EVP_DigestInit_ex +can be called to initialize a new digest operation. +.Pp +.Fn EVP_Digest +is a simple wrapper function to hash +.Fa cnt +bytes of data at +.Fa d +using the digest +.Fa type +from +.Vt ENGINE +.Fa impl +in a one-shot operation and place the digest value into +.Fa md , +and, unless +.Fa s +is +.Dv NULL , +the length of the digest in bytes into +.Pf * Fa s . +This wrapper uses a temporary digest context and passes its arguments to +.Fn EVP_DigestInit_ex , +.Fn EVP_DigestUpdate , +and +.Fn EVP_DigestFinal_ex +internally. +.Pp +.Fn EVP_MD_CTX_copy_ex +can be used to copy the message digest state from +.Fa in +to +.Fa out . +This is useful if large amounts of data are to be hashed which only +differ in the last few bytes. +.Pp +.Fn EVP_DigestInit +is a deprecated function behaving like +.Fn EVP_DigestInit_ex +except that it always uses the default digest implementation +and that it requires +.Fn EVP_MD_CTX_reset +before it can be used on a context that was already used. +.Pp +.Fn EVP_DigestFinal +is a deprecated function behaving like +.Fn EVP_DigestFinal_ex +except that the digest context +.Fa ctx +is automatically cleaned up after use by calling +.Fn EVP_MD_CTX_reset +internally. +.Pp +.Fn EVP_MD_CTX_copy +is a deprecated function behaving like +.Fn EVP_MD_CTX_copy_ex +except that it requires +.Fn EVP_MD_CTX_reset +before a context that was already used can be passed as +.Fa out . +.Pp +.Fn EVP_sha224 , +.Fn EVP_sha256 , +.Fn EVP_sha384 , +.Fn EVP_sha512 , +and +.Fn EVP_ripemd160 +return +.Vt EVP_MD +structures for the SHA224, SHA256, SHA384, SHA512 and +RIPEMD160 digest algorithms respectively. +.Pp +.Fn EVP_sha512_224 +and +.Fn EVP_sha512_256 +return an +.Vt EVP_MD +structure that provides the truncated SHA512 variants SHA512/224 and SHA512/256, +respectively. +.Pp +.Fn EVP_md_null +is a "null" message digest that does nothing: +i.e. the hash it returns is of zero length. +.Pp +.Fn EVP_get_digestbyname , +.Fn EVP_get_digestbynid , +and +.Fn EVP_get_digestbyobj +return an +.Vt EVP_MD +structure when passed a digest name, a digest NID, or an ASN1_OBJECT +structure respectively. +.Pp +.Fn EVP_get_digestbynid +and +.Fn EVP_get_digestbyobj +are implemented as macros. +.Pp +The EVP interface to message digests should almost always be used +in preference to the low-level interfaces. +This is because the code then becomes transparent to the digest used and +much more flexible. +.Pp +For most applications the +.Fa impl +parameter to +.Fn EVP_DigestInit_ex +will be set to NULL to use the default digest implementation. +.Pp +The functions +.Fn EVP_DigestInit , +.Fn EVP_DigestFinal , +and +.Fn EVP_MD_CTX_copy +are obsolete but are retained to maintain compatibility with existing +code. +New applications should use +.Fn EVP_DigestInit_ex , +.Fn EVP_DigestFinal_ex , +and +.Fn EVP_MD_CTX_copy_ex +because they can efficiently reuse a digest context instead of +initializing and cleaning it up on each call and allow non-default +implementations of digests to be specified. +.Pp +If digest contexts are not cleaned up after use, memory leaks will occur. +.Sh RETURN VALUES +.Fn EVP_MD_CTX_new +and +.Fn EVP_MD_CTX_create +return the new +.Vt EVP_MD_CTX +object or +.Dv NULL +for failure. +.Pp +.Fn EVP_MD_CTX_reset +and +.Fn EVP_MD_CTX_cleanup +always return 1. +.Pp +.Fn EVP_DigestInit_ex , +.Fn EVP_DigestUpdate , +.Fn EVP_DigestFinal_ex , +.Fn EVP_Digest , +.Fn EVP_MD_CTX_copy_ex , +.Fn EVP_DigestInit , +.Fn EVP_DigestFinal , +and +.Fn EVP_MD_CTX_copy +return 1 for success or 0 for failure. +.Pp +.Fn EVP_MD_CTX_md +returns the +.Vt EVP_MD +object used by +.Fa ctx , +or +.Dv NULL +if +.Fa ctx +is +.Dv NULL +or does not have any message digest algorithm assigned yet. +.Pp +.Fn EVP_md_null , +.Fn EVP_sha224 , +.Fn EVP_sha256 , +.Fn EVP_sha384 , +.Fn EVP_sha512 , +.Fn EVP_sha512_224 , +.Fn EVP_sha512_256 , +and +.Fn EVP_ripemd160 +return pointers to constant static objects owned by the library. +.Pp +.Fn EVP_get_digestbyname , +.Fn EVP_get_digestbynid , +and +.Fn EVP_get_digestbyobj +return either an +.Vt EVP_MD +structure or +.Dv NULL +if an error occurs. +.Sh EXAMPLES +This example digests the data "Test Message\en" and "Hello World\en", +using the digest name passed on the command line. +.Bd -literal -offset indent +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + EVP_MD_CTX *mdctx; + const EVP_MD *md; + const char mess1[] = "Test Message\en"; + const char mess2[] = "Hello World\en"; + unsigned char md_value[EVP_MAX_MD_SIZE]; + unsigned int md_len, i; + + if (argc <= 1) { + printf("Usage: mdtest digestname\en"); + exit(1); + } + + md = EVP_get_digestbyname(argv[1]); + if (md == NULL) { + printf("Unknown message digest %s\en", argv[1]); + exit(1); + } + + mdctx = EVP_MD_CTX_new(); + EVP_DigestInit_ex(mdctx, md, NULL); + EVP_DigestUpdate(mdctx, mess1, strlen(mess1)); + EVP_DigestUpdate(mdctx, mess2, strlen(mess2)); + EVP_DigestFinal_ex(mdctx, md_value, &md_len); + EVP_MD_CTX_free(mdctx); + + printf("Digest is: "); + for(i = 0; i < md_len; i++) + printf("%02x", md_value[i]); + printf("\en"); + + return 0; +} +.Ed +.Sh SEE ALSO +.Xr BIO_f_md 3 , +.Xr CMAC_Init 3 , +.Xr evp 3 , +.Xr EVP_BytesToKey 3 , +.Xr EVP_DigestSignInit 3 , +.Xr EVP_DigestVerifyInit 3 , +.Xr EVP_MD_CTX_ctrl 3 , +.Xr EVP_MD_meth_new 3 , +.Xr EVP_MD_nid 3 , +.Xr EVP_PKEY_CTX_set_signature_md 3 , +.Xr EVP_PKEY_meth_set_signctx 3 , +.Xr EVP_sha1 3 , +.Xr EVP_sha3_224 3 , +.Xr EVP_SignInit 3 , +.Xr EVP_sm3 3 , +.Xr EVP_VerifyInit 3 , +.Xr EVP_whirlpool 3 , +.Xr HMAC 3 , +.Xr OCSP_basic_sign 3 , +.Xr OCSP_request_sign 3 , +.Xr PKCS5_PBKDF2_HMAC 3 , +.Xr PKCS7_sign_add_signer 3 , +.Xr X509_ALGOR_set_md 3 , +.Xr X509_digest 3 , +.Xr X509_sign 3 +.Sh HISTORY +.Fn EVP_DigestInit , +.Fn EVP_DigestUpdate , +and +.Fn EVP_DigestFinal +first appeared in SSLeay 0.5.1. +.Fn EVP_md_null +and +.Fn EVP_get_digestbyname +first appeared in SSLeay 0.8.0. +.Fn EVP_get_digestbynid +and +.Fn EVP_get_digestbyobj +first appeared in SSLeay 0.8.1. +.Fn EVP_ripemd160 +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_MD_CTX_copy +first appeared in OpenSSL 0.9.2b and has been available since +.Ox 2.6 . +.Pp +.Fn EVP_MD_CTX_md +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn EVP_MD_CTX_init , +.Fn EVP_MD_CTX_create , +.Fn EVP_MD_CTX_cleanup , +.Fn EVP_MD_CTX_destroy , +.Fn EVP_DigestInit_ex , +.Fn EVP_DigestFinal_ex , +.Fn EVP_Digest , +and +.Fn EVP_MD_CTX_copy_ex +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EVP_sha224 , +.Fn EVP_sha256 , +.Fn EVP_sha384 , +and +.Fn EVP_sha512 +first appeared in OpenSSL 0.9.7h and 0.9.8a +and have been available since +.Ox 4.0 . +.Pp +.Fn EVP_MD_CTX_new , +.Fn EVP_MD_CTX_reset , +and +.Fn EVP_MD_CTX_free +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Pp +.Fn EVP_sha512_224 +and +.Fn EVP_sha512_256 +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.4 . diff --git a/Libraries/libressl/man/EVP_DigestSignInit.3 b/Libraries/libressl/man/EVP_DigestSignInit.3 new file mode 100644 index 000000000..de6e57c2c --- /dev/null +++ b/Libraries/libressl/man/EVP_DigestSignInit.3 @@ -0,0 +1,239 @@ +.\" $OpenBSD: EVP_DigestSignInit.3,v 1.12 2022/01/15 09:08:51 tb Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt EVP_DIGESTSIGNINIT 3 +.Os +.Sh NAME +.Nm EVP_DigestSignInit , +.Nm EVP_DigestSignUpdate , +.Nm EVP_DigestSignFinal , +.Nm EVP_DigestSign +.Nd EVP signing functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_DigestSignInit +.Fa "EVP_MD_CTX *ctx" +.Fa "EVP_PKEY_CTX **pctx" +.Fa "const EVP_MD *type" +.Fa "ENGINE *e" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_DigestSignUpdate +.Fa "EVP_MD_CTX *ctx" +.Fa "const void *d" +.Fa "size_t cnt" +.Fc +.Ft int +.Fo EVP_DigestSignFinal +.Fa "EVP_MD_CTX *ctx" +.Fa "unsigned char *sig" +.Fa "size_t *siglen" +.Fc +.Ft int +.Fo EVP_DigestSign +.Fa "EVP_MD_CTX *ctx" +.Fa "unsigned char *sigret" +.Fa "size_t *siglen" +.Fa "const unsigned char *tbs" +.Fa "size_t tbslen" +.Fc +.Sh DESCRIPTION +The EVP signature routines are a high-level interface to digital +signatures. +.Pp +.Fn EVP_DigestSignInit +sets up the signing context +.Fa ctx +to use the digest +.Fa type +from +.Vt ENGINE +.Fa e +and private key +.Fa pkey . +.Fa ctx +must be initialized with +.Xr EVP_MD_CTX_init 3 +before calling this function. +If +.Fa pctx +is not +.Dv NULL , +the +.Vt EVP_PKEY_CTX +of the signing operation will be written to +.Pf * Fa pctx : +this can be used to set alternative signing options. +Any existing value in +.Pf * Fa pctx +will be overwritten. +The +.Vt EVP_PKEY_CTX +value returned must not be freed directly by the application. +It will be freed automatically when the +.Vt EVP_MD_CTX +is freed. +.Pp +.Fn EVP_DigestSignUpdate +hashes +.Fa cnt +bytes of data at +.Fa d +into the signature context +.Fa ctx . +This function can be called several times on the same +.Fa ctx +to include additional data. +This function is currently implemented using a macro. +.Pp +.Fn EVP_DigestSignFinal +signs the data in +.Fa ctx +and places the signature in +.Fa sig . +If +.Fa sig +is +.Dv NULL , +then the maximum size of the output buffer is written to +.Pf * Fa siglen . +If +.Fa sig +is not +.Dv NULL , +then before the call +.Fa siglen +should contain the length of the +.Fa sig +buffer. +If the call is successful, the signature is written to +.Fa sig +and the amount of data written to +.Fa siglen . +.Pp +.Fn EVP_DigestSign +signs +.Fa tbslen +bytes of data at +.Fa tbs +and places the signature in +.Fa sigret +and its length in +.Fa siglen +in a similar way to +.Fn EVP_DigestSignFinal . +.Fn EVP_DigestSign +is a one shot operation which signs a single block of data +with one function call. +For algorithms that support streaming it is equivalent to calling +.Fn EVP_DigestSignUpdate +and +.Fn EVP_DigestSignFinal . +.\" For algorithms which do not support streaming +.\" (e.g. PureEdDSA) +.\" it is the only way to sign data. +.Pp +The EVP interface to digital signatures should almost always be +used in preference to the low-level interfaces. +This is because the code then becomes transparent to the algorithm used +and much more flexible. +.Pp +The call to +.Fn EVP_DigestSignFinal +internally finalizes a copy of the digest context. +This means that +.Fn EVP_DigestSignUpdate +and +.Fn EVP_DigestSignFinal +can be called later to digest and sign additional data. +.Pp +Since only a copy of the digest context is ever finalized, the context +must be cleaned up after use by calling +.Xr EVP_MD_CTX_free 3 , +or a memory leak will occur. +.Pp +The use of +.Xr EVP_PKEY_size 3 +with these functions is discouraged because some signature operations +may have a signature length which depends on the parameters set. +As a result, +.Xr EVP_PKEY_size 3 +would have to return a value which indicates the maximum possible +signature for any set of parameters. +.Sh RETURN VALUES +.Fn EVP_DigestSignInit , +.Fn EVP_DigestSignUpdate , +.Fn EVP_DigestSignFinal , +and +.Fn EVP_DigestSign +return 1 for success and 0 for failure. +.Pp +The error codes can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_DigestVerifyInit 3 , +.Xr EVP_PKEY_meth_set_signctx 3 +.Sh HISTORY +.Fn EVP_DigestSignInit , +.Fn EVP_DigestSignUpdate , +and +.Fn EVP_DigestSignFinal +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn EVP_DigestSign +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/EVP_DigestVerifyInit.3 b/Libraries/libressl/man/EVP_DigestVerifyInit.3 new file mode 100644 index 000000000..0eb314346 --- /dev/null +++ b/Libraries/libressl/man/EVP_DigestVerifyInit.3 @@ -0,0 +1,219 @@ +.\" $OpenBSD: EVP_DigestVerifyInit.3,v 1.14 2022/01/15 09:08:51 tb Exp $ +.\" OpenSSL fb552ac6 Sep 30 23:43:01 2009 +0000 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2014, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt EVP_DIGESTVERIFYINIT 3 +.Os +.Sh NAME +.Nm EVP_DigestVerifyInit , +.Nm EVP_DigestVerifyUpdate , +.Nm EVP_DigestVerifyFinal , +.Nm EVP_DigestVerify +.Nd EVP signature verification functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_DigestVerifyInit +.Fa "EVP_MD_CTX *ctx" +.Fa "EVP_PKEY_CTX **pctx" +.Fa "const EVP_MD *type" +.Fa "ENGINE *e" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_DigestVerifyUpdate +.Fa "EVP_MD_CTX *ctx" +.Fa "const void *d" +.Fa "size_t cnt" +.Fc +.Ft int +.Fo EVP_DigestVerifyFinal +.Fa "EVP_MD_CTX *ctx" +.Fa "const unsigned char *sig" +.Fa "size_t siglen" +.Fc +.Ft int +.Fo EVP_DigestVerify +.Fa "EVP_MD_CTX *ctx" +.Fa "const unsigned char *sig" +.Fa "size_t siglen" +.Fa "const unsigned char *tbs" +.Fa "size_t *tbslen" +.Fc +.Sh DESCRIPTION +The EVP signature routines are a high-level interface to digital +signatures. +.Pp +.Fn EVP_DigestVerifyInit +sets up verification context +.Fa ctx +to use digest +.Fa type +from +.Vt ENGINE +.Fa e +and public key +.Fa pkey . +.Fa ctx +must be initialized with +.Xr EVP_MD_CTX_init 3 +before calling this function. +If +.Fa pctx +is not +.Dv NULL , +the +.Vt EVP_PKEY_CTX +of the verification operation will be written to +.Pf * Fa pctx : +this can be used to set alternative verification options. +Any existing value in +.Pf * .Fa pctx +is overwritten. +The +.Vt EVP_PKEY_CTX +value returned must not be freed directly by the application. +It will be freed automatically when the +.Vt EVP_MD_CTX +is freed. +.Pp +.Fn EVP_DigestVerifyUpdate +hashes +.Fa cnt +bytes of data at +.Fa d +into the verification context +.Fa ctx . +This function can be called several times on the same +.Fa ctx +to include additional data. +This function is currently implemented using a macro. +.Pp +.Fn EVP_DigestVerifyFinal +verifies the data in +.Fa ctx +against the signature in +.Fa sig +of length +.Fa siglen . +.Pp +.Fn EVP_DigestVerify +verifies +.Fa tbslen +bytes at +.Fa tbs +against the signature in +.Fa sig +of length +.Fa siglen . +.Fn EVP_DigestVerify +is a one shot operation which verifies a single block of data +in one function call. +For algorithms that support streaming it is equivalent to calling +.Fn EVP_DigestVerifyUpdate +and +.Fn EVP_DigestVerifyFinal . +.\" For algorithms which do not support streaming +.\" (e.g. PureEdDSA) +.\" it is the only way to verify data. +.Pp +The EVP interface to digital signatures should almost always be +used in preference to the low level interfaces. +This is because the code then becomes transparent to the algorithm used +and much more flexible. +.Pp +The call to +.Fn EVP_DigestVerifyFinal +internally finalizes a copy of the digest context. +This means that +.Xr EVP_VerifyUpdate 3 +and +.Xr EVP_VerifyFinal 3 +can be called later to digest and verify additional data. +.Pp +Since only a copy of the digest context is ever finalized, the context +must be cleaned up after use by calling +.Xr EVP_MD_CTX_free 3 +or a memory leak will occur. +.Sh RETURN VALUES +.Fn EVP_DigestVerifyInit +and +.Fn EVP_DigestVerifyUpdate +return 1 for success and 0 for failure. +.Pp +.Fn EVP_DigestVerifyFinal +and +.Fn EVP_DigestVerify +return 1 for success; any other value indicates failure. +A return value of 0 indicates that the signature did not verify +successfully (that is, the signature did not match the original +data or the signature had an invalid form), while other values +indicate a more serious error (and sometimes also indicate an invalid +signature form). +.Pp +The error codes can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_DigestSignInit 3 , +.Xr EVP_PKEY_meth_set_verifyctx 3 +.Sh HISTORY +.Fn EVP_DigestVerifyInit , +.Fn EVP_DigestVerifyUpdate , +and +.Fn EVP_DigestVerifyFinal +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn EVP_DigestVerify +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/EVP_EncodeInit.3 b/Libraries/libressl/man/EVP_EncodeInit.3 new file mode 100644 index 000000000..da79af84c --- /dev/null +++ b/Libraries/libressl/man/EVP_EncodeInit.3 @@ -0,0 +1,334 @@ +.\" $OpenBSD: EVP_EncodeInit.3,v 1.7 2019/06/06 01:06:58 schwarze Exp $ +.\" full merge up to: OpenSSL f430ba31 Jun 19 19:39:01 2016 +0200 +.\" selective merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt EVP_ENCODEINIT 3 +.Os +.Sh NAME +.Nm EVP_ENCODE_CTX_new , +.Nm EVP_ENCODE_CTX_free , +.Nm EVP_EncodeInit , +.Nm EVP_EncodeUpdate , +.Nm EVP_EncodeFinal , +.Nm EVP_EncodeBlock , +.Nm EVP_DecodeInit , +.Nm EVP_DecodeUpdate , +.Nm EVP_DecodeFinal , +.Nm EVP_DecodeBlock +.Nd EVP base64 encode/decode routines +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_ENCODE_CTX * +.Fn EVP_ENCODE_CTX_new void +.Ft void +.Fo EVP_ENCODE_CTX_free +.Fa "EVP_ENCODE_CTX *ctx" +.Fc +.Ft void +.Fo EVP_EncodeInit +.Fa "EVP_ENCODE_CTX *ctx" +.Fc +.Ft int +.Fo EVP_EncodeUpdate +.Fa "EVP_ENCODE_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "const unsigned char *in" +.Fa "int inl" +.Fc +.Ft void +.Fo EVP_EncodeFinal +.Fa "EVP_ENCODE_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_EncodeBlock +.Fa "unsigned char *t" +.Fa "const unsigned char *f" +.Fa "int n" +.Fc +.Ft void +.Fo EVP_DecodeInit +.Fa "EVP_ENCODE_CTX *ctx" +.Fc +.Ft int +.Fo EVP_DecodeUpdate +.Fa "EVP_ENCODE_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "const unsigned char *in" +.Fa "int inl" +.Fc +.Ft int +.Fo EVP_DecodeFinal +.Fa "EVP_ENCODE_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_DecodeBlock +.Fa "unsigned char *t" +.Fa "const unsigned char *f" +.Fa "int n" +.Fc +.Sh DESCRIPTION +The EVP encode routines provide a high level interface to base64 +encoding and decoding. +Base64 encoding converts binary data into a printable form that uses +the characters A-Z, a-z, 0-9, "+" and "/" to represent the data. +For every 3 bytes of binary data provided, 4 bytes of base64-encoded +data will be produced, plus some occasional newlines. +If the input data length is not a multiple of 3, then the output data +will be padded at the end using the "=" character. +.Pp +.Fn EVP_ENCODE_CTX_new +allocates, initializes and returns a context to be used for the encode +and decode functions. +.Pp +.Fn EVP_ENCODE_CTX_free +frees +.Fa ctx . +.Pp +Encoding of binary data is performed in blocks of 48 input bytes (or +less for the final block). +For each 48-byte input block encoded, 64 bytes of base64 data is output, +plus an additional newline character, i.e. 65 bytes in total. +The final block, which may be less than 48 bytes, will output 4 bytes +for every 3 bytes of input. +If the data length is not divisible by 3, then a full 4 bytes is still +output for the final 1 or 2 bytes of input. +Similarly a newline character will also be output. +.Pp +.Fn EVP_EncodeInit +initialises +.Fa ctx +for the start of a new encoding operation. +.Pp +.Fn EVP_EncodeUpdate +encodes +.Fa inl +bytes of data found in the buffer pointed to by +.Fa in . +The output is stored in the buffer +.Fa out +and the number of bytes output is stored in +.Pf * Fa outl . +It is the caller's responsibility to ensure that the buffer at +.Fa out +is sufficiently large to accommodate the output data. +Only full blocks of data (48 bytes) will be immediately processed and +output by this function. +Any remainder is held in the +.Fa ctx +object and will be processed by a subsequent call to +.Fn EVP_EncodeUpdate +or +.Fn EVP_EncodeFinal . +To calculate the required size of the output buffer, add together the +value of +.Fa inl +with the amount of unprocessed data held in +.Fa ctx +and divide the result by 48 (ignore any remainder). +This gives the number of blocks of data that will be processed. +Ensure the output buffer contains 65 bytes of storage for each block, +plus an additional byte for a NUL terminator. +.Fn EVP_EncodeUpdate +may be called repeatedly to process large amounts of input data. +In the event of an error , +.Fn EVP_EncodeUpdate +will set +.Pf * Fa outl +to 0 and return 0. +On success 1 will be returned. +.Pp +.Fn EVP_EncodeFinal +must be called at the end of an encoding operation. +It will process any partial block of data remaining in the +.Fa ctx +object. +The output data will be stored in +.Fa out +and the length of the data written will be stored in +.Pf * Fa outl . +It is the caller's responsibility to ensure that +.Fa out +is sufficiently large to accommodate the output data, which will +never be more than 65 bytes plus an additional NUL terminator, i.e. +66 bytes in total. +.Pp +.Fn EVP_EncodeBlock +encodes a full block of input data in +.Fa f +and of length +.Fa n +and stores it in +.Fa t . +For every 3 bytes of input provided, 4 bytes of output data will be +produced. +If +.Sy n +is not divisible by 3, then the block is encoded as a final block +of data and the output is padded such that it is always divisible +by 4. +Additionally a NUL terminator character will be added. +For example, if 16 bytes of input data are provided, then 24 bytes +of encoded data is created plus 1 byte for a NUL terminator, +i.e. 25 bytes in total. +The length of the data generated +.Em without +the NUL terminator is returned from the function. +.Pp +.Fn EVP_DecodeInit +initialises +.Fa ctx +for the start of a new decoding operation. +.Pp +.Fn EVP_DecodeUpdate +decodes +.Fa inl +characters of data found in the buffer pointed to by +.Fa in . +The output is stored in the buffer +.Fa out +and the number of bytes output is stored in +.Pf * Fa outl . +It is the caller's responsibility to ensure that the buffer at +.Fa out +is sufficiently large to accommodate the output data. +This function will attempt to decode as much data as possible in 4-byte +chunks. +Any whitespace, newline or carriage return characters are ignored. +Any partial chunk of unprocessed data (1, 2 or 3 bytes) that remains at +the end will be held in the +.Fa ctx +object and processed by a subsequent call to +.Fn EVP_DecodeUpdate . +If any illegal base64 characters are encountered or if the base64 +padding character "=" is encountered in the middle of the data, +then the function returns -1 to indicate an error. +A return value of 0 or 1 indicates successful processing of the data. +A return value of 0 additionally indicates that the last input data +characters processed included the base64 padding character "=" and +therefore no more non-padding character data is expected to be +processed. +For every 4 valid base64 bytes processed \(em ignoring whitespace, +carriage returns and line feeds \(em 3 bytes of binary output data +will be produced, or less at the end of the data where the padding +character "=" has been used. +.Pp +.Fn EVP_DecodeFinal +must be called at the end of a decoding operation. +If there is any unprocessed data still in +.Fa ctx , +then the input data must not have been a multiple of 4 and therefore an +error has occurred. +The function will return -1 in this case. +Otherwise the function returns 1 on success. +.Pp +.Fn EVP_DecodeBlock +will decode the block of +.Fa n +characters of base64 data contained in +.Fa f +and store the result in +.Fa t . +Any leading whitespace will be trimmed as will any trailing whitespace, +newlines, carriage returns or EOF characters. +After such trimming the length of the data in +.Fa f +must be divisible by 4. +For every 4 input bytes, exactly 3 output bytes will be produced. +The output will be padded with 0 bits if necessary to ensure that the +output is always 3 bytes for every 4 input bytes. +This function will return the length of the data decoded or -1 on error. +.Sh RETURN VALUES +.Fn EVP_ENCODE_CTX_new +returns a pointer to the newly allocated +.Vt EVP_ENCODE_CTX +object or +.Dv NULL +on error. +.Pp +.Fn EVP_EncodeUpdate +returns 0 on error or 1 on success. +.Pp +.Fn EVP_EncodeBlock +returns the number of bytes encoded excluding the NUL terminator. +.Pp +.Fn EVP_DecodeUpdate +returns -1 on error and 0 or 1 on success. +If 0 is returned, then no more non-padding base64 characters are +expected. +.Pp +.Fn EVP_DecodeFinal +returns -1 on error or 1 on success. +.Pp +.Fn EVP_DecodeBlock +returns the length of the data decoded or -1 on error. +.Sh SEE ALSO +.Xr BIO_f_base64 3 , +.Xr evp 3 +.Sh HISTORY +The +.Fn EVP_Encode* +and +.Fn EVP_Decode* +functions first appeared in SSLeay 0.5.1 +and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_ENCODE_CTX_new +and +.Fn EVP_ENCODE_CTX_free +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/EVP_EncryptInit.3 b/Libraries/libressl/man/EVP_EncryptInit.3 new file mode 100644 index 000000000..ddec4e7e7 --- /dev/null +++ b/Libraries/libressl/man/EVP_EncryptInit.3 @@ -0,0 +1,1029 @@ +.\" $OpenBSD: EVP_EncryptInit.3,v 1.48 2023/08/31 17:27:41 schwarze Exp $ +.\" full merge up to: OpenSSL 5211e094 Nov 11 14:39:11 2014 -0800 +.\" EVP_bf_cbc.pod EVP_cast5_cbc.pod EVP_idea_cbc.pod EVP_rc2_cbc.pod +.\" 7c6d372a Nov 20 13:20:01 2018 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Richard Levitte . +.\" Copyright (c) 2000-2002, 2005, 2012-2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 31 2023 $ +.Dt EVP_ENCRYPTINIT 3 +.Os +.Sh NAME +.Nm EVP_CIPHER_CTX_new , +.Nm EVP_CIPHER_CTX_reset , +.Nm EVP_CIPHER_CTX_cleanup , +.Nm EVP_CIPHER_CTX_init , +.Nm EVP_CIPHER_CTX_free , +.Nm EVP_CIPHER_CTX_copy , +.Nm EVP_EncryptInit_ex , +.Nm EVP_EncryptUpdate , +.Nm EVP_EncryptFinal_ex , +.Nm EVP_DecryptInit_ex , +.Nm EVP_DecryptUpdate , +.Nm EVP_DecryptFinal_ex , +.Nm EVP_CipherInit_ex , +.Nm EVP_CipherUpdate , +.Nm EVP_CipherFinal_ex , +.Nm EVP_EncryptInit , +.Nm EVP_EncryptFinal , +.Nm EVP_DecryptInit , +.Nm EVP_DecryptFinal , +.Nm EVP_CipherInit , +.Nm EVP_CipherFinal , +.Nm EVP_Cipher , +.Nm EVP_CIPHER_CTX_encrypting , +.Nm EVP_get_cipherbyname , +.Nm EVP_get_cipherbynid , +.Nm EVP_get_cipherbyobj , +.Nm EVP_CIPHER_CTX_cipher , +.Nm EVP_enc_null , +.Nm EVP_idea_cbc , +.Nm EVP_idea_ecb , +.Nm EVP_idea_cfb64 , +.Nm EVP_idea_cfb , +.Nm EVP_idea_ofb , +.Nm EVP_rc2_cbc , +.Nm EVP_rc2_ecb , +.Nm EVP_rc2_cfb64 , +.Nm EVP_rc2_cfb , +.Nm EVP_rc2_ofb , +.Nm EVP_rc2_40_cbc , +.Nm EVP_rc2_64_cbc , +.Nm EVP_bf_cbc , +.Nm EVP_bf_ecb , +.Nm EVP_bf_cfb64 , +.Nm EVP_bf_cfb , +.Nm EVP_bf_ofb , +.Nm EVP_cast5_cbc , +.Nm EVP_cast5_ecb , +.Nm EVP_cast5_cfb64 , +.Nm EVP_cast5_cfb , +.Nm EVP_cast5_ofb +.Nd EVP cipher routines +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_CIPHER_CTX * +.Fn EVP_CIPHER_CTX_new void +.Ft int +.Fo EVP_CIPHER_CTX_reset +.Fa "EVP_CIPHER_CTX *ctx" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_cleanup +.Fa "EVP_CIPHER_CTX *ctx" +.Fc +.Ft void +.Fo EVP_CIPHER_CTX_init +.Fa "EVP_CIPHER_CTX *ctx" +.Fc +.Ft void +.Fo EVP_CIPHER_CTX_free +.Fa "EVP_CIPHER_CTX *ctx" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_copy +.Fa "EVP_CIPHER_CTX *out" +.Fa "const EVP_CIPHER_CTX *in" +.Fc +.Ft int +.Fo EVP_EncryptInit_ex +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "ENGINE *impl" +.Fa "const unsigned char *key" +.Fa "const unsigned char *iv" +.Fc +.Ft int +.Fo EVP_EncryptUpdate +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "const unsigned char *in" +.Fa "int inl" +.Fc +.Ft int +.Fo EVP_EncryptFinal_ex +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_DecryptInit_ex +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "ENGINE *impl" +.Fa "const unsigned char *key" +.Fa "const unsigned char *iv" +.Fc +.Ft int +.Fo EVP_DecryptUpdate +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "const unsigned char *in" +.Fa "int inl" +.Fc +.Ft int +.Fo EVP_DecryptFinal_ex +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *outm" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_CipherInit_ex +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "ENGINE *impl" +.Fa "const unsigned char *key" +.Fa "const unsigned char *iv" +.Fa "int enc" +.Fc +.Ft int +.Fo EVP_CipherUpdate +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "const unsigned char *in" +.Fa "int inl" +.Fc +.Ft int +.Fo EVP_CipherFinal_ex +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *outm" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_EncryptInit +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "const unsigned char *key" +.Fa "const unsigned char *iv" +.Fc +.Ft int +.Fo EVP_EncryptFinal +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_DecryptInit +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "const unsigned char *key" +.Fa "const unsigned char *iv" +.Fc +.Ft int +.Fo EVP_DecryptFinal +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *outm" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_CipherInit +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "const unsigned char *key" +.Fa "const unsigned char *iv" +.Fa "int enc" +.Fc +.Ft int +.Fo EVP_CipherFinal +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *outm" +.Fa "int *outl" +.Fc +.Ft int +.Fo EVP_Cipher +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "const unsigned char *in" +.Fa "unsigned int inl" +.Fc +.Ft int +.Fo EVP_CIPHER_CTX_encrypting +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Ft const EVP_CIPHER * +.Fo EVP_get_cipherbyname +.Fa "const char *name" +.Fc +.Ft const EVP_CIPHER * +.Fo EVP_get_cipherbynid +.Fa "int nid" +.Fc +.Ft const EVP_CIPHER * +.Fo EVP_get_cipherbyobj +.Fa "const ASN1_OBJECT *a" +.Fc +.Ft const EVP_CIPHER * +.Fo EVP_CIPHER_CTX_cipher +.Fa "const EVP_CIPHER_CTX *ctx" +.Fc +.Sh DESCRIPTION +The EVP cipher routines are a high level interface to certain symmetric +ciphers. +.Pp +.Fn EVP_CIPHER_CTX_new +creates a new, empty cipher context. +.Pp +.Fn EVP_CIPHER_CTX_reset +clears all information from +.Fa ctx +and frees all allocated memory associated with it, except the +.Fa ctx +object itself, such that it can be reused for another series of calls to +.Fn EVP_CipherInit , +.Fn EVP_CipherUpdate , +and +.Fn EVP_CipherFinal . +.Fn EVP_CIPHER_CTX_cleanup +is a deprecated alias for +.Fn EVP_CIPHER_CTX_reset . +.Pp +.Fn EVP_CIPHER_CTX_init +is a deprecated function to clear a cipher context on the stack +before use. +Do not use it on a cipher context returned from +.Fn EVP_CIPHER_CTX_new +or one that was already used. +.Pp +.Fn EVP_CIPHER_CTX_free +clears all information from +.Fa ctx +and frees all allocated memory associated with it, including +.Fa ctx +itself. +This function should be called after all operations using a cipher +are complete, so sensitive information does not remain in memory. +If +.Fa ctx +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn EVP_CIPHER_CTX_copy +calls +.Fn EVP_CIPHER_CTX_reset +on +.Fa out +and copies all the data from +.Fa in +to +.Fa out , +except that the +.Vt EVP_CIPHER +and +.Vt ENGINE +objects used by +.Fa in +and any application specific data set with +.Xr EVP_CIPHER_CTX_set_app_data 3 +are not copied and +.Fa out +will point to the same three objects. +The algorithm- and implementation-specific cipher data described in +.Xr EVP_CIPHER_CTX_get_cipher_data 3 +is copied with +.Xr malloc 3 +and +.Xr memcpy 3 , +i.e. assuming that it does not contain pointers to any sub-objects. +If the bit +.Dv EVP_CIPH_CUSTOM_COPY +has been set with +.Xr EVP_CIPHER_meth_set_flags 3 , +.Xr EVP_CIPHER_CTX_ctrl 3 +is called at the end with arguments +.Fa in , +.Dv EVP_CTRL_COPY , +.No 0 , +and +.Fa out +such that the cipher implementation can perform further algorithm- +and implementation-specific initializations after the algorithm- +and implementation-specific cipher data has been copied. +Among the cipher algorithms built into the library, +.Dv EVP_CIPH_CUSTOM_COPY +and +.Dv EVP_CTRL_COPY +are used by some of the ciphers documented in the +.Xr EVP_aes_256_gcm 3 +manual page. +.Pp +.Fn EVP_EncryptInit_ex +sets up the cipher context +.Fa ctx +for encryption with cipher +.Fa type +from +.Vt ENGINE +.Fa impl . +.Fa type +is normally supplied by a function such as +.Xr EVP_aes_256_cbc 3 . +If +.Fa impl +is +.Dv NULL , +then the default implementation is used. +.Fa key +is the symmetric key to use and +.Fa iv +is the IV to use (if necessary). +The actual number of bytes used for the +key and IV depends on the cipher. +It is possible to set all parameters to +.Dv NULL +except +.Fa type +in an initial call and supply the remaining parameters in subsequent +calls, all of which have +.Fa type +set to +.Dv NULL . +This is done when the default cipher parameters are not appropriate. +.Pp +.Fn EVP_EncryptUpdate +encrypts +.Fa inl +bytes from the buffer +.Fa in +and writes the encrypted version to +.Fa out . +This function can be called multiple times to encrypt successive blocks +of data. +The amount of data written depends on the block alignment of the +encrypted data: as a result the amount of data written may be anything +from zero bytes to (inl + cipher_block_size - 1) so +.Fa out +should contain sufficient room. +The actual number of bytes written is placed in +.Fa outl . +.Pp +If padding is enabled (the default) then +.Fn EVP_EncryptFinal_ex +encrypts the "final" data, that is any data that remains in a partial +block. +It uses NOTES (aka PKCS padding). +The encrypted final data is written to +.Fa out +which should have sufficient space for one cipher block. +The number of bytes written is placed in +.Fa outl . +After this function is called, the encryption operation is finished and +no further calls to +.Fn EVP_EncryptUpdate +should be made. +.Pp +If padding is disabled then +.Fn EVP_EncryptFinal_ex +will not encrypt any more data and it will return an error if any data +remains in a partial block: that is if the total data length is not a +multiple of the block size. +.Pp +.Fn EVP_DecryptInit_ex , +.Fn EVP_DecryptUpdate , +and +.Fn EVP_DecryptFinal_ex +are the corresponding decryption operations. +.Fn EVP_DecryptFinal +will return an error code if padding is enabled and the final block is +not correctly formatted. +The parameters and restrictions are identical to the encryption +operations except that if padding is enabled the decrypted data buffer +.Fa out +passed to +.Fn EVP_DecryptUpdate +should have sufficient room for (inl + cipher_block_size) bytes +unless the cipher block size is 1 in which case +.Fa inl +bytes is sufficient. +.Pp +.Fn EVP_CipherInit_ex , +.Fn EVP_CipherUpdate , +and +.Fn EVP_CipherFinal_ex +are functions that can be used for decryption or encryption. +The operation performed depends on the value of the +.Fa enc +parameter. +It should be set to 1 for encryption, 0 for decryption and -1 to leave +the value unchanged (the actual value of +.Fa enc +being supplied in a previous call). +.Pp +.Fn EVP_EncryptInit , +.Fn EVP_DecryptInit , +and +.Fn EVP_CipherInit +are deprecated functions behaving like +.Fn EVP_EncryptInit_ex , +.Fn EVP_DecryptInit_ex , +and +.Fn EVP_CipherInit_ex +except that they always use the default cipher implementation +and that they require +.Fn EVP_CIPHER_CTX_reset +before they can be used on a context that was already used. +.Pp +.Fn EVP_EncryptFinal , +.Fn EVP_DecryptFinal , +and +.Fn EVP_CipherFinal +are identical to +.Fn EVP_EncryptFinal_ex , +.Fn EVP_DecryptFinal_ex , +and +.Fn EVP_CipherFinal_ex . +In previous releases of OpenSSL, they also used to clean up the +.Fa ctx , +but this is no longer done and +.Fn EVP_CIPHER_CTX_reset +or +.Fn EVP_CIPHER_CTX_free +must be called to free any context resources. +.Pp +.Fn EVP_Cipher +encrypts or decrypts aligned blocks of data +whose lengths match the cipher block size. +It requires that the previous encryption or decryption operation +using the same +.Fa ctx , +if there was any, ended exactly on a block boundary and that +.Fa inl +is an integer multiple of the cipher block size. +If either of these conditions is violated, +.Fn EVP_Cipher +silently produces incorrect results. +For that reason, using the function +.Fn EVP_CipherUpdate +instead is strongly recommended. +The latter can safely handle partial blocks, and even if +.Fa inl +actually is a multiple of the cipher block size for all calls, +the overhead incurred by using +.Fn EVP_CipherUpdate +is minimal. +.Pp +.Fn EVP_get_cipherbyname , +.Fn EVP_get_cipherbynid , +and +.Fn EVP_get_cipherbyobj +return an +.Vt EVP_CIPHER +structure when passed a cipher name, a NID or an +.Vt ASN1_OBJECT +structure. +.Pp +.Fn EVP_CIPHER_CTX_cipher +returns the +.Vt EVP_CIPHER +structure when passed an +.Vt EVP_CIPHER_CTX +structure. +.Pp +Where possible the EVP interface to symmetric ciphers should be +used in preference to the low level interfaces. +This is because the code then becomes transparent to the cipher used and +much more flexible. +.Pp +PKCS padding works by adding n padding bytes of value n to make the +total length of the encrypted data a multiple of the block size. +Padding is always added so if the data is already a multiple of the +block size n will equal the block size. +For example if the block size is 8 and 11 bytes are to be encrypted then +5 padding bytes of value 5 will be added. +.Pp +When decrypting, the final block is checked to see if it has the correct +form. +.Pp +Although the decryption operation can produce an error if padding is +enabled, it is not a strong test that the input data or key is correct. +A random block has better than 1 in 256 chance of being of the correct +format and problems with the input data earlier on will not produce a +final decrypt error. +.Pp +If padding is disabled then the decryption operation will always succeed +if the total amount of data decrypted is a multiple of the block size. +.Pp +The functions +.Fn EVP_EncryptInit , +.Fn EVP_EncryptFinal , +.Fn EVP_DecryptInit , +.Fn EVP_CipherInit , +and +.Fn EVP_CipherFinal +are obsolete but are retained for compatibility with existing code. +New code should use +.Fn EVP_EncryptInit_ex , +.Fn EVP_EncryptFinal_ex , +.Fn EVP_DecryptInit_ex , +.Fn EVP_DecryptFinal_ex , +.Fn EVP_CipherInit_ex , +and +.Fn EVP_CipherFinal_ex +because they can reuse an existing context without allocating and +freeing it up on each call. +.Pp +.Fn EVP_get_cipherbynid +and +.Fn EVP_get_cipherbyobj +are implemented as macros. +.Sh RETURN VALUES +.Fn EVP_CIPHER_CTX_new +returns a pointer to a newly created +.Vt EVP_CIPHER_CTX +for success or +.Dv NULL +for failure. +.Pp +.Fn EVP_CIPHER_CTX_reset , +.Fn EVP_CIPHER_CTX_cleanup , +.Fn EVP_CIPHER_CTX_copy , +.Fn EVP_EncryptInit_ex , +.Fn EVP_EncryptUpdate , +.Fn EVP_EncryptFinal_ex , +.Fn EVP_DecryptInit_ex , +.Fn EVP_DecryptUpdate , +.Fn EVP_DecryptFinal_ex , +.Fn EVP_CipherInit_ex , +.Fn EVP_CipherUpdate , +.Fn EVP_CipherFinal_ex , +.Fn EVP_EncryptInit , +.Fn EVP_EncryptFinal , +.Fn EVP_DecryptInit , +.Fn EVP_DecryptFinal , +.Fn EVP_CipherInit , +.Fn EVP_CipherFinal , +and +.Fn EVP_Cipher +return 1 for success or 0 for failure. +.Pp +.Fn EVP_CIPHER_CTX_encrypting +returns 1 if +.Fa ctx +is initialized for encryption or 0 otherwise, in which case +it may be uninitialized or initialized for decryption. +.Pp +.Fn EVP_get_cipherbyname , +.Fn EVP_get_cipherbynid , +and +.Fn EVP_get_cipherbyobj +return an +.Vt EVP_CIPHER +structure or +.Dv NULL +on error. +.Pp +.Fn EVP_CIPHER_CTX_cipher +returns an +.Vt EVP_CIPHER +structure. +.Sh CIPHER LISTING +All algorithms have a fixed key length unless otherwise stated. +.Bl -tag -width Ds +.It Fn EVP_enc_null +Null cipher: does nothing. +.It Xo +.Fn EVP_idea_cbc , +.Fn EVP_idea_ecb , +.Fn EVP_idea_cfb64 , +.Fn EVP_idea_ofb +.Xc +IDEA encryption algorithm in CBC, ECB, CFB and OFB modes respectively. +.Fn EVP_idea_cfb +is an alias for +.Fn EVP_idea_cfb64 , +implemented as a macro. +.It Xo +.Fn EVP_rc2_cbc , +.Fn EVP_rc2_ecb , +.Fn EVP_rc2_cfb64 , +.Fn EVP_rc2_ofb +.Xc +RC2 encryption algorithm in CBC, ECB, CFB and OFB modes respectively. +This is a variable key length cipher with an additional parameter called +"effective key bits" or "effective key length". +By default both are set to 128 bits. +.Fn EVP_rc2_cfb +is an alias for +.Fn EVP_rc2_cfb64 , +implemented as a macro. +.It Xo +.Fn EVP_rc2_40_cbc , +.Fn EVP_rc2_64_cbc +.Xc +RC2 algorithm in CBC mode with a default key length and effective key +length of 40 and 64 bits. +These are obsolete and new code should use +.Fn EVP_rc2_cbc , +.Xr EVP_CIPHER_CTX_set_key_length 3 , +and +.Xr EVP_CIPHER_CTX_ctrl 3 +to set the key length and effective key length. +.It Xo +.Fn EVP_bf_cbc , +.Fn EVP_bf_ecb , +.Fn EVP_bf_cfb64 , +.Fn EVP_bf_ofb +.Xc +Blowfish encryption algorithm in CBC, ECB, CFB and OFB modes +respectively. +This is a variable key length cipher. +.Fn EVP_bf_cfb +is an alias for +.Fn EVP_bf_cfb64 , +implemented as a macro. +.It Xo +.Fn EVP_cast5_cbc , +.Fn EVP_cast5_ecb , +.Fn EVP_cast5_cfb64 , +.Fn EVP_cast5_ofb +.Xc +CAST encryption algorithm in CBC, ECB, CFB and OFB modes respectively. +This is a variable key length cipher. +.Fn EVP_cast5_cfb +is an alias for +.Fn EVP_cast5_cfb64 , +implemented as a macro. +.El +.Pp +See also +.Xr EVP_aes_128_cbc 3 , +.Xr EVP_camellia_128_cbc 3 , +.Xr EVP_des_cbc 3 , +.Xr EVP_rc4 3 , +and +.Xr EVP_sm4_cbc 3 . +.Ss GCM mode +For GCM mode ciphers, the behaviour of the EVP interface +is subtly altered and several additional ctrl operations are +supported. +.Pp +To specify any additional authenticated data (AAD), a call to +.Fn EVP_CipherUpdate , +.Fn EVP_EncryptUpdate , +or +.Fn EVP_DecryptUpdate +should be made with the output parameter out set to +.Dv NULL . +.Pp +When decrypting, the return value of +.Fn EVP_DecryptFinal +or +.Fn EVP_CipherFinal +indicates if the operation was successful. +If it does not indicate success, the authentication operation has +failed and any output data MUST NOT be used as it is corrupted. +.Pp +The following ctrls are supported in GCM mode: +.Bl -tag -width Ds +.It Fn EVP_CIPHER_CTX_ctrl ctx EVP_CTRL_GCM_SET_IVLEN ivlen NULL +Sets the IV length: this call can only be made before specifying an IV. +If not called, a default IV length is used. +For GCM AES the default is 12, i.e. 96 bits. +.It Fn EVP_CIPHER_CTX_ctrl ctx EVP_CTRL_GCM_GET_TAG taglen tag +Writes +.Fa taglen +bytes of the tag value to the buffer indicated by +.Fa tag . +This call can only be made when encrypting data and after all data has +been processed, e.g. after an +.Fn EVP_EncryptFinal +call. +.It Fn EVP_CIPHER_CTX_ctrl ctx EVP_CTRL_GCM_SET_TAG taglen tag +Sets the expected tag to +.Fa taglen +bytes from +.Fa tag . +This call is only legal when decrypting data and must be made before +any data is processed, e.g. before any +.Fa EVP_DecryptUpdate +call. +.El +.Ss CCM mode +The behaviour of CCM mode ciphers is similar to GCM mode, but with +a few additional requirements and different ctrl values. +.Pp +Like GCM mode any additional authenticated data (AAD) is passed +by calling +.Fn EVP_CipherUpdate , +.Fn EVP_EncryptUpdate , +or +.Fn EVP_DecryptUpdate +with the output parameter out set to +.Dv NULL . +Additionally, the total +plaintext or ciphertext length MUST be passed to +.Fn EVP_CipherUpdate , +.Fn EVP_EncryptUpdate , +or +.Fn EVP_DecryptUpdate +with the output and input +parameters +.Pq Fa in No and Fa out +set to +.Dv NULL +and the length passed in the +.Fa inl +parameter. +.Pp +The following ctrls are supported in CCM mode: +.Bl -tag -width Ds +.It Fn EVP_CIPHER_CTX_ctrl ctx EVP_CTRL_CCM_SET_TAG taglen tag +This call is made to set the expected CCM tag value when decrypting or +the length of the tag (with the +.Fa tag +parameter set to +.Dv NULL ) +when encrypting. +The tag length is often referred to as M. +If not set, a default value is used (12 for AES). +.It Fn EVP_CIPHER_CTX_ctrl ctx EVP_CTRL_CCM_SET_L ivlen NULL +Sets the CCM L value. +If not set, a default is used (8 for AES). +.It Fn EVP_CIPHER_CTX_ctrl ctx EVP_CTRL_CCM_SET_IVLEN ivlen NULL +Sets the CCM nonce (IV) length: this call can only be made before +specifying a nonce value. +The nonce length is given by 15 - L so it is 7 by default for AES. +.El +.Sh EXAMPLES +Encrypt a string using blowfish: +.Bd -literal -offset 3n +int +do_crypt(char *outfile) +{ + unsigned char outbuf[1024]; + int outlen, tmplen; + /* + * Bogus key and IV: we'd normally set these from + * another source. + */ + unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + unsigned char iv[] = {1,2,3,4,5,6,7,8}; + const char intext[] = "Some Crypto Text"; + EVP_CIPHER_CTX *ctx; + FILE *out; + + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_bf_cbc(), NULL, key, iv); + + if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, intext, + strlen(intext))) { + /* Error */ + EVP_CIPHER_CTX_free(ctx); + return 0; + } + /* + * Buffer passed to EVP_EncryptFinal() must be after data just + * encrypted to avoid overwriting it. + */ + if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) { + /* Error */ + EVP_CIPHER_CTX_free(ctx); + return 0; + } + outlen += tmplen; + EVP_CIPHER_CTX_free(ctx); + /* + * Need binary mode for fopen because encrypted data is + * binary data. Also cannot use strlen() on it because + * it won't be NUL terminated and may contain embedded + * NULs. + */ + out = fopen(outfile, "wb"); + if (out == NULL) { + /* Error */ + return 0; + } + fwrite(outbuf, 1, outlen, out); + fclose(out); + return 1; +} +.Ed +.Pp +The ciphertext from the above example can be decrypted using the +.Xr openssl 1 +utility with the command line: +.Bd -literal -offset indent +openssl bf -in cipher.bin -K 000102030405060708090A0B0C0D0E0F \e + -iv 0102030405060708 -d +.Ed +.Pp +General encryption, decryption function example using FILE I/O and AES128 +with a 128-bit key: +.Bd -literal +int +do_crypt(FILE *in, FILE *out, int do_encrypt) +{ + /* Allow enough space in output buffer for additional block */ + unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH]; + int inlen, outlen; + EVP_CIPHER_CTX *ctx; + + /* + * Bogus key and IV: we'd normally set these from + * another source. + */ + unsigned char key[] = "0123456789abcdeF"; + unsigned char iv[] = "1234567887654321"; + + ctx = EVP_CIPHER_CTX_new(); + EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, + do_encrypt); + EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, do_encrypt); + + for (;;) { + inlen = fread(inbuf, 1, 1024, in); + if (inlen <= 0) + break; + if (!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, + inlen)) { + /* Error */ + EVP_CIPHER_CTX_free(ctx); + return 0; + } + fwrite(outbuf, 1, outlen, out); + } + if (!EVP_CipherFinal_ex(ctx, outbuf, &outlen)) { + /* Error */ + EVP_CIPHER_CTX_free(ctx); + return 0; + } + fwrite(outbuf, 1, outlen, out); + + EVP_CIPHER_CTX_free(ctx); + return 1; +} +.Ed +.Sh SEE ALSO +.Xr BIO_f_cipher 3 , +.Xr evp 3 , +.Xr EVP_AEAD_CTX_init 3 , +.Xr EVP_aes_128_cbc 3 , +.Xr EVP_camellia_128_cbc 3 , +.Xr EVP_chacha20 3 , +.Xr EVP_CIPHER_CTX_ctrl 3 , +.Xr EVP_CIPHER_CTX_get_cipher_data 3 , +.Xr EVP_CIPHER_CTX_set_flags 3 , +.Xr EVP_CIPHER_nid 3 , +.Xr EVP_des_cbc 3 , +.Xr EVP_OpenInit 3 , +.Xr EVP_rc4 3 , +.Xr EVP_SealInit 3 , +.Xr EVP_sm4_cbc 3 +.Sh HISTORY +.Fn EVP_EncryptInit , +.Fn EVP_EncryptUpdate , +.Fn EVP_EncryptFinal , +.Fn EVP_DecryptInit , +.Fn EVP_DecryptUpdate , +.Fn EVP_DecryptFinal , +.Fn EVP_CipherInit , +.Fn EVP_CipherUpdate , +.Fn EVP_CipherFinal , +.Fn EVP_get_cipherbyname , +.Fn EVP_idea_cbc , +.Fn EVP_idea_ecb , +.Fn EVP_idea_cfb , +and +.Fn EVP_idea_ofb +first appeared in SSLeay 0.5.1. +.Fn EVP_rc2_cbc , +.Fn EVP_rc2_ecb , +.Fn EVP_rc2_cfb , +and +.Fn EVP_rc2_ofb +first appeared in SSLeay 0.5.2. +.Fn EVP_Cipher +first appeared in SSLeay 0.6.5. +.Fn EVP_bf_cbc , +.Fn EVP_bf_ecb , +.Fn EVP_bf_cfb , +and +.Fn EVP_bf_ofb +first appeared in SSLeay 0.6.6. +.Fn EVP_CIPHER_CTX_cleanup , +.Fn EVP_get_cipherbyobj , +.Fn EVP_CIPHER_CTX_cipher , +and +.Fn EVP_enc_null +first appeared in SSLeay 0.8.0. +.Fn EVP_get_cipherbynid +first appeared in SSLeay 0.8.1. +.Fn EVP_CIPHER_CTX_init +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_rc2_40_cbc +and +.Fn EVP_rc2_64_cbc +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . +.Pp +.Fn EVP_EncryptInit_ex , +.Fn EVP_EncryptFinal_ex , +.Fn EVP_DecryptInit_ex , +.Fn EVP_DecryptFinal_ex , +.Fn EVP_CipherInit_ex , +and +.Fn EVP_CipherFinal_ex +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EVP_bf_cfb64 , +.Fn EVP_cast5_cfb64 , +.Fn EVP_idea_cfb64 , +and +.Fn EVP_rc2_cfb64 +first appeared in OpenSSL 0.9.7e and have been available since +.Ox 3.8 . +.Pp +.Fn EVP_CIPHER_CTX_new +and +.Fn EVP_CIPHER_CTX_free +first appeared in OpenSSL 0.9.8b and have been available since +.Ox 4.5 . +.Pp +.Fn EVP_CIPHER_CTX_copy +first appeared in OpenSSL 1.0.0 +and has been available since +.Ox 4.9 . +.Pp +.Fn EVP_CIPHER_CTX_reset +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Pp +.Fn EVP_CIPHER_CTX_encrypting +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.4 . +.Sh BUGS +.Fn EVP_CIPHER_CTX_copy +may already have cleared the data in +.Fa out +and copied some new data into it even if it fails and returns 0. diff --git a/Libraries/libressl/man/EVP_MD_CTX_ctrl.3 b/Libraries/libressl/man/EVP_MD_CTX_ctrl.3 new file mode 100644 index 000000000..0aaeddd6d --- /dev/null +++ b/Libraries/libressl/man/EVP_MD_CTX_ctrl.3 @@ -0,0 +1,280 @@ +.\" $OpenBSD: EVP_MD_CTX_ctrl.3,v 1.2 2023/09/07 19:28:37 schwarze Exp $ +.\" full merge up to: OpenSSL man3/EVP_DigestInit.pod +.\" 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte , +.\" Todd Short , Paul Yang , +.\" and Antoine Salon . +.\" Copyright (c) 2015, 2016, 2018, 2019 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 7 2023 $ +.Dt EVP_MD_CTX_CTRL 3 +.Os +.Sh NAME +.Nm EVP_MD_CTX_ctrl , +.Nm EVP_MD_CTX_set_flags , +.Nm EVP_MD_CTX_clear_flags , +.Nm EVP_MD_CTX_test_flags , +.Nm EVP_MD_CTX_pkey_ctx , +.Nm EVP_MD_CTX_set_pkey_ctx , +.Nm EVP_MD_CTX_md_data +.Nd configure EVP message digest contexts +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_MD_CTX_ctrl +.Fa "EVP_MD_CTX *ctx" +.Fa "int command" +.Fa "int p1" +.Fa "void* p2" +.Fc +.Ft void +.Fo EVP_MD_CTX_set_flags +.Fa "EVP_MD_CTX *ctx" +.Fa "int flags" +.Fc +.Ft void +.Fo EVP_MD_CTX_clear_flags +.Fa "EVP_MD_CTX *ctx" +.Fa "int flags" +.Fc +.Ft int +.Fo EVP_MD_CTX_test_flags +.Fa "const EVP_MD_CTX *ctx" +.Fa "int flags" +.Fc +.Ft EVP_PKEY_CTX * +.Fo EVP_MD_CTX_pkey_ctx +.Fa "const EVP_MD_CTX *ctx" +.Fc +.Ft void +.Fo EVP_MD_CTX_set_pkey_ctx +.Fa "EVP_MD_CTX *ctx" +.Fa "EVP_PKEY_CTX *pctx" +.Fc +.Ft void * +.Fo EVP_MD_CTX_md_data +.Fa "const EVP_MD_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn EVP_MD_CTX_ctrl +performs the digest-specific control +.Fa command +with the command-specific arguments +.Fa p1 +and +.Fa p2 +on +.Fa ctx , +which needs to already be set up with +.Xr EVP_DigestInit_ex 3 +before calling this function. +Other restrictions may apply depending on the control +.Fa command +and digest implementation. +.Pp +If the +.Fa command +is +.Dv EVP_MD_CTRL_MICALG , +.Fa p1 +is ignored and +.Fa p2 +is an output argument of the type +.Fa "char **p2" . +A string specifying the digest Message Integrity Check algorithm +is allocated and a pointer to this string is returned in +.Pf * Fa p2 . +It is the responsibility of the caller to +.Xr free 3 +.Pf * Fa p2 +when it is no longer needed. +This +.Fa command +is used by +.Xr SMIME_write_ASN1 3 +when creating S/MIME multipart/signed messages as specified in RFC 3851. +.Pp +.Fn EVP_MD_CTX_set_flags +sets and +.Fn EVP_MD_CTX_clear_flags +clears all the flag bits in +.Fa ctx +that are set in the +.Fa flags +argument. +.Fn EVP_MD_CTX_test_flags +tests which of the flag bits that are set in the +.Fa flags +argument are also set in +.Fa ctx . +Possible flag bits are: +.Bl -tag -width Ds -offset 2n +.It Dv EVP_MD_CTX_FLAG_NO_INIT +Instruct +.Xr EVP_DigestInit_ex 3 +and functions calling it not to initialise the internal data +that is specific to the digest method and its implementation. +.It Dv EVP_MD_CTX_FLAG_ONESHOT +Instruct the digest to optimize for one update only, if possible. +For digest algorithms built into the library, this flag usually +has no effect. +.El +.Pp +.Fn EVP_MD_CTX_pkey_ctx +returns the +.Vt EVP_PKEY_CTX +assigned to +.Fa ctx . +The returned pointer should not be freed by the caller. +.Pp +.Fn EVP_MD_CTX_set_pkey_ctx +assigns +.Fa pctx +to +.Fa ctx . +This is normally used to provide a customized +.Vt EVP_PKEY_CTX +to +.Xr EVP_DigestSignInit 3 +or +.Xr EVP_DigestVerifyInit 3 . +The caller retains ownership of the +.Fa pctx +passed to this function and is responsible for freeing it +when it is no longer needed. +.Pp +If the +.Fa ctx +already contains a +.Vt EVP_PKEY_CTX +when this function is called, that old +.Vt EVP_PKEY_CTX +is freed if it was created internally, but if it was also installed with +.Fn EVP_MD_CTX_set_pkey_ctx , +the pointer to the old +.Vt EVP_PKEY_CTX +is merely replaced by the new pointer and ownership of the old +.Vt EVP_PKEY_CTX +remains with the previous caller. +.Pp +Passing a +.Dv NULL +pointer for the +.Fa pctx +argument is also allowed. +In that case, any +.Vt EVP_PKEY_CTX +already assigned to +.Fa ctx +is dissociated from it as described above, but no new +.Vt EVP_PKEY_CTX +is assigned. +.Pp +.Fn EVP_MD_CTX_md_data +returns the digest method private data of +.Fa ctx . +The space was allocated and its size set with +.Xr EVP_MD_meth_set_app_datasize 3 . +.Sh RETURN VALUES +.Fn EVP_MD_CTX_ctrl +returns 1 for success or 0 for failure. +.Pp +.Fn EVP_MD_CTX_test_flags +returns the bitwise OR of the +.Fa flags +argument and the flags set in +.Fa ctx . +.Pp +.Fn EVP_MD_CTX_pkey_ctx +and +.Fn EVP_MD_CTX_md_data +return pointers to storage owned by +.Fa ctx . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_MD_meth_new 3 , +.Xr EVP_MD_nid 3 +.Sh HISTORY +.Fn EVP_MD_CTX_set_flags , +.Fn EVP_MD_CTX_clear_flags , +and +.Fn EVP_MD_CTX_test_flags , +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EVP_MD_CTX_ctrl +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 5.7 . +.Pp +.Fn EVP_MD_CTX_pkey_ctx +and +.Fn EVP_MD_CTX_md_data +first appeared in OpenSSL 1.1.0 and +.Fn EVP_MD_CTX_set_pkey_ctx +in OpenSSL 1.1.1. +These functions have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/EVP_MD_meth_new.3 b/Libraries/libressl/man/EVP_MD_meth_new.3 new file mode 100644 index 000000000..8a80cca06 --- /dev/null +++ b/Libraries/libressl/man/EVP_MD_meth_new.3 @@ -0,0 +1,352 @@ +.\" $OpenBSD: EVP_MD_meth_new.3,v 1.5 2023/09/12 16:26:30 schwarze Exp $ +.\" selective merge up to: +.\" OpenSSL man3/EVP_MD_meth_new 0388d212 Dec 14 12:47:07 2018 -0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 12 2023 $ +.Dt EVP_MD_METH_NEW 3 +.Os +.Sh NAME +.Nm EVP_MD_meth_dup , +.Nm EVP_MD_meth_new , +.Nm EVP_MD_meth_free , +.Nm EVP_MD_meth_set_input_blocksize , +.Nm EVP_MD_meth_set_result_size , +.Nm EVP_MD_meth_set_app_datasize , +.Nm EVP_MD_meth_set_flags , +.Nm EVP_MD_meth_set_init , +.Nm EVP_MD_meth_set_update , +.Nm EVP_MD_meth_set_final , +.Nm EVP_MD_meth_set_copy , +.Nm EVP_MD_meth_set_cleanup , +.Nm EVP_MD_meth_set_ctrl +.Nd Routines to build up EVP_MD methods +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_MD * +.Fo EVP_MD_meth_new +.Fa "int md_type" +.Fa "int pkey_type" +.Fc +.Ft void +.Fo EVP_MD_meth_free +.Fa "EVP_MD *md" +.Fc +.Ft EVP_MD * +.Fo EVP_MD_meth_dup +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_meth_set_input_blocksize +.Fa "EVP_MD *md" +.Fa "int blocksize" +.Fc +.Ft int +.Fo EVP_MD_meth_set_result_size +.Fa "EVP_MD *md" +.Fa "int resultsize" +.Fc +.Ft int +.Fo EVP_MD_meth_set_app_datasize +.Fa "EVP_MD *md" +.Fa "int datasize" +.Fc +.Ft int +.Fo EVP_MD_meth_set_flags +.Fa "EVP_MD *md" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo EVP_MD_meth_set_init +.Fa "EVP_MD *md" +.Fa "int (*init)(EVP_MD_CTX *ctx)" +.Fc +.Ft int +.Fo EVP_MD_meth_set_update +.Fa "EVP_MD *md" +.Fa "int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)" +.Fc +.Ft int +.Fo EVP_MD_meth_set_final +.Fa "EVP_MD *md" +.Fa "int (*final)(EVP_MD_CTX *ctx, unsigned char *md)" +.Fc +.Ft int +.Fo EVP_MD_meth_set_copy +.Fa "EVP_MD *md" +.Fa "int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)" +.Fc +.Ft int +.Fo EVP_MD_meth_set_cleanup +.Fa "EVP_MD *md" +.Fa "int (*cleanup)(EVP_MD_CTX *ctx)" +.Fc +.Ft int +.Fo EVP_MD_meth_set_ctrl +.Fa "EVP_MD *md" +.Fa "int (*control)(EVP_MD_CTX *ctx, int command, int p1, void *p2)" +.Fc +.Sh DESCRIPTION +The +.Vt EVP_MD +type is a structure for digest method implementation. +It can also have associated public/private key signing and verifying +routines. +.Pp +.Fn EVP_MD_meth_new +creates a new +.Vt EVP_MD +structure. +.Pp +.Fn EVP_MD_meth_dup +creates a copy of +.Fa md . +.Pp +.Fn EVP_MD_meth_free +destroys a +.Vt EVP_MD +structure. +.Pp +.Fn EVP_MD_meth_set_input_blocksize +sets the internal input block size for the method +.Fa md +to +.Fa blocksize +bytes. +.Pp +.Fn EVP_MD_meth_set_result_size +sets the size of the result that the digest method in +.Fa md +is expected to produce to +.Fa resultsize +bytes. +.Pp +The digest method may have its own private data, which OpenSSL will +allocate for it. +.Fn EVP_MD_meth_set_app_datasize +should be used to set the size for it to +.Fa datasize . +.Pp +.Fn EVP_MD_meth_set_flags +sets the flags to describe optional behaviours in the particular +.Fa md . +Several flags can be or'd together. +The available flags are: +.Bl -tag -width Ds +.It Dv EVP_MD_FLAG_DIGALGID_NULL +When setting up a +.Vt DigestAlgorithmIdentifier +with +.Xr X509_ALGOR_set_md 3 , +set the parameter type to +.Dv V_ASN1_NULL +and the parameter value to +.Dv NULL . +This is the default, which means that it takes effect for +.Vt EVP_MD +objects that do not have +.Dv EVP_MD_FLAG_DIGALGID_ABSENT +set. +Use this for PKCS#1. +.It Dv EVP_MD_FLAG_DIGALGID_ABSENT +When setting up a +.Vt DigestAlgorithmIdentifier +with +.Xr X509_ALGOR_set_md 3 , +set the parameter type to +.Dv V_ASN1_UNDEF +and the parameter value to +.Dv NULL . +This is used by the +.Vt EVP_MD +objects documented in the manual page +.Xr EVP_sha3_224 3 +and by the objects returned from +.Xr EVP_sha512 3 , +.Xr EVP_sha512_256 3 , +.Xr EVP_sha512_224 3 , +.Xr EVP_sha384 3 , +.Xr EVP_sha256 3 , +.Xr EVP_sha224 3 , +.Xr EVP_sha1 3 , +and +.Xr EVP_sm3 3 . +.It Dv EVP_MD_FLAG_DIGALGID_CUSTOM +This flag is reserved for user-defined +.Vt EVP_MD +objects supporting custom +.Vt DigestAlgorithmIdentifier +handling via +.Xr EVP_MD_CTX_ctrl 3 , +but actually, it is ignored by both LibreSSL and OpenSSL +and such user-defined behaviour is not supported by the libraries. +.It Dv EVP_MD_FLAG_FIPS +Mark the digest method as suitable for FIPS mode. +This flag is ignored by both LibreSSL and OpenSSL. +.It Dv EVP_MD_FLAG_ONESHOT +Intended to indicate that the digest method can only handle one block +of input, but actually, this flag is ignored by both LibreSSL and OpenSSL. +.El +.Pp +.Fn EVP_MD_meth_set_init +sets the digest init function for +.Fa md . +The digest init function is called by +.Xr EVP_Digest 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_DigestInit_ex 3 , +EVP_SignInit, +.Xr EVP_SignInit_ex 3 , +.Xr EVP_VerifyInit 3 +and +.Xr EVP_VerifyInit_ex 3 . +.Pp +.Fn EVP_MD_meth_set_update +sets the digest update function for +.Fa md . +The digest update function is called by +.Xr EVP_Digest 3 , +.Xr EVP_DigestUpdate 3 +and +.Xr EVP_SignUpdate 3 . +.Pp +.Fn EVP_MD_meth_set_final +sets the digest final function for +.Fa md . +The digest final function is called by +.Xr EVP_Digest 3 , +.Xr EVP_DigestFinal 3 , +.Xr EVP_DigestFinal_ex 3 , +.Xr EVP_SignFinal 3 +and +.Xr EVP_VerifyFinal 3 . +.Pp +.Fn EVP_MD_meth_set_copy +sets the function for +.Fa md +to do extra computations after the method's private data structure has +been copied from one +.Vt EVP_MD_CTX +object to another. +If all that's needed is to copy the data, there is no need for this copy +function. +The copy function is passed two +.Vt EVP_MD_CTX +objects, the private data structure is then available with +.Xr EVP_MD_CTX_md_data 3 . +This copy function is called by +.Xr EVP_MD_CTX_copy 3 +and +.Xr EVP_MD_CTX_copy_ex 3 . +.Pp +.Fn EVP_MD_meth_set_cleanup +sets the function for +.Fa md +to do extra cleanup before the method's private data structure is +cleaned out and freed. +The cleanup function is passed an +.Vt EVP_MD_CTX +object, the private data structure is then available with +.Xr EVP_MD_CTX_md_data 3 . +This cleanup function is called by +.Xr EVP_MD_CTX_reset 3 +and +.Xr EVP_MD_CTX_free 3 . +.Pp +.Fn EVP_MD_meth_set_ctrl +sets the +.Fa control +function for +.Fa md . +The +.Fa control +function supplied by the application program has to return 1 to indicate +success, 0 to indicate failure, or \-1 if the +.Fa command +is not supported for this digest method. +See +.Xr EVP_MD_CTX_ctrl 3 +for the available +.Fa command +arguments. +.Sh RETURN VALUES +.Fn EVP_MD_meth_new +and +.Fn EVP_MD_meth_dup +return a pointer to a newly created +.Vt EVP_MD , +or NULL on failure. +All +.Fn EVP_MD_meth_set_* +functions return 1. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr EVP_SignInit 3 , +.Xr EVP_VerifyInit 3 +.Sh HISTORY +All these functions +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/EVP_MD_nid.3 b/Libraries/libressl/man/EVP_MD_nid.3 new file mode 100644 index 000000000..acc0c704f --- /dev/null +++ b/Libraries/libressl/man/EVP_MD_nid.3 @@ -0,0 +1,265 @@ +.\" $OpenBSD: EVP_MD_nid.3,v 1.3 2023/09/07 16:32:41 schwarze Exp $ +.\" full merge up to: OpenSSL man3/EVP_DigestInit.pod +.\" 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Antoine Salon . +.\" Copyright (c) 2000, 2012, 2019 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 7 2023 $ +.Dt EVP_MD_NID 3 +.Os +.Sh NAME +.Nm EVP_MD_nid , +.Nm EVP_MD_type , +.Nm EVP_MD_CTX_type , +.Nm EVP_MD_name , +.Nm EVP_MD_size , +.Nm EVP_MD_CTX_size , +.Nm EVP_MD_block_size , +.Nm EVP_MD_CTX_block_size , +.Nm EVP_MD_flags , +.Nm EVP_MD_pkey_type +.Nd inspect EVP_MD objects +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_MD_nid +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_type +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_CTX_type +.Fa "const EVP_MD_CTX *ctx" +.Fc +.Ft const char * +.Fo EVP_MD_name +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_size +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_CTX_size +.Fa "const EVP_MD_CTX *ctx" +.Fc +.Ft int +.Fo EVP_MD_block_size +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_CTX_block_size +.Fa "const EVP_MD_CTX *ctx" +.Fc +.Ft unsigned long +.Fo EVP_MD_flags +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_MD_pkey_type +.Fa "const EVP_MD *md" +.Fc +.Sh DESCRIPTION +.Fn EVP_MD_nid +and +.Fn EVP_MD_type +are identical and return the numerical identifier (NID) of +.Fa md . +The NID is an internal value which may or may not have +a corresponding ASN.1 OBJECT IDENTIFIER; see +.Xr OBJ_nid2obj 3 +for details. +For example , +.Fn EVP_MD_type EVP_sha512() +returns +.Dv NID_sha512 . +.Fn EVP_MD_CTX_type +returns the NID of the message digest algorithm that +.Fa ctx +is configured to use. +These functions are normally used when setting ASN.1 OIDs. +.Pp +.Fn EVP_MD_name +converts the NID of +.Fa md +to its short name with +.Xr OBJ_nid2sn 3 . +.Pp +.Fn EVP_MD_size +returns the size in bytes of the message digests (hashes) produced by +.Fa md . +.Fn EVP_MD_CTX_size +return the size of the hashes produced by the message digest algorithm that +.Fa ctx +is configured to use. +.Pp +.Fn EVP_MD_block_size +returns the block size in bytes of +.Fa md . +.Fn EVP_MD_CTX_block_size +returns the block size of the message digest algorithm that +.Fa ctx +is configured to use. +.Pp +.Fn EVP_MD_flags +returns the message digest flags used by +.Fa md . +The meaning of the flags is described in the +.Xr EVP_MD_meth_set_flags 3 +manual page. +Be careful to not confuse these flags with the unrelated +message digest context flags that can be inspected with +.Xr EVP_MD_CTX_test_flags 3 . +.Pp +.Fn EVP_MD_pkey_type +returns the NID of the public key signing algorithm associated with this +digest. +For example, +.Xr EVP_sha512 3 +is associated with RSA, so this returns +.Dv NID_sha512WithRSAEncryption . +Since digests and signature algorithms are no longer linked, this +function is only retained for compatibility reasons. +.Pp +.Fn EVP_MD_nid , +.Fn EVP_MD_CTX_type , +.Fn EVP_MD_name , +.Fn EVP_MD_CTX_size , +and +.Fn EVP_MD_CTX_block_size +are implemented as macros. +.Sh RETURN VALUES +.Fn EVP_MD_nid , +.Fn EVP_MD_type , +.Fn EVP_MD_CTX_type , +and +.Fn EVP_MD_pkey_type +return the NID of the corresponding OBJECT IDENTIFIER or +.Dv NID_undef +if none exists. +.Pp +.Fn EVP_MD_name +returns a pointer to a string +that is owned by an internal library object or +.Dv NULL +if the NID is neither built into the library nor added to the global +object table by one of the functions documented in the manual page +.Xr OBJ_create 3 , +or if the object does not contain a short name. +.Pp +.Fn EVP_MD_size , +.Fn EVP_MD_CTX_size , +.Fn EVP_MD_block_size , +and +.Fn EVP_MD_CTX_block_size +return the digest or block size in bytes. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_MD_CTX_ctrl 3 , +.Xr OBJ_nid2obj 3 +.Sh HISTORY +.Fn EVP_MD_size +first appeared in SSLeay 0.6.6, +.Fn EVP_MD_CTX_size +and +.Fn EVP_MD_CTX_type +in SSLeay 0.8.0, +.Fn EVP_MD_type +and +.Fn EVP_MD_pkey_type +in SSLeay 0.8.1, and +.Fn EVP_MD_block_size +and +.Fn EVP_MD_CTX_block_size +in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_MD_nid +and +.Fn EVP_MD_name +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EVP_MD_flags +first appeared in OpenSSL 1.0.0 +and has been available since +.Ox 4.9 . +.Sh CAVEATS +The behaviour of the functions taking an +.Vt EVP_MD_CTX +argument is undefined if they are called on a +.Fa ctx +that has no message digest configured yet, +for example one freshly returned from +.Xr EVP_MD_CTX_new 3 . +In that case, the program may for example be terminated by a +.Dv NULL +pointer access. diff --git a/Libraries/libressl/man/EVP_OpenInit.3 b/Libraries/libressl/man/EVP_OpenInit.3 new file mode 100644 index 000000000..766d178cb --- /dev/null +++ b/Libraries/libressl/man/EVP_OpenInit.3 @@ -0,0 +1,154 @@ +.\" $OpenBSD: EVP_OpenInit.3,v 1.8 2019/06/07 20:46:25 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 7 2019 $ +.Dt EVP_OPENINIT 3 +.Os +.Sh NAME +.Nm EVP_OpenInit , +.Nm EVP_OpenUpdate , +.Nm EVP_OpenFinal +.Nd EVP envelope decryption +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_OpenInit +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "EVP_CIPHER *type" +.Fa "unsigned char *ek" +.Fa "int ekl" +.Fa "unsigned char *iv" +.Fa "EVP_PKEY *priv" +.Fc +.Ft int +.Fo EVP_OpenUpdate +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "unsigned char *in" +.Fa "int inl" +.Fc +.Ft int +.Fo EVP_OpenFinal +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fc +.Sh DESCRIPTION +The EVP envelope routines are a high level interface to envelope +decryption. +They decrypt a public key encrypted symmetric key and then decrypt data +using it. +.Pp +.Fn EVP_OpenInit +initializes a cipher context +.Fa ctx +for decryption with cipher +.Fa type . +It decrypts the encrypted symmetric key of length +.Fa ekl +bytes passed in the +.Fa ek +parameter using the private key +.Fa priv . +The IV is supplied in the +.Fa iv +parameter. +.Pp +.Fn EVP_OpenUpdate +and +.Fn EVP_OpenFinal +have exactly the same properties as the +.Xr EVP_DecryptUpdate 3 +and +.Xr EVP_DecryptFinal 3 +routines. +.Pp +It is possible to call +.Fn EVP_OpenInit +twice in the same way as +.Xr EVP_DecryptInit 3 . +The first call should have +.Fa priv +set to +.Dv NULL +and (after setting any cipher parameters) it should be +called again with +.Fa type +set to +.Dv NULL . +.Pp +If the cipher passed in the +.Fa type +parameter is a variable length cipher then the key length will be set to +the value of the recovered key length. +If the cipher is a fixed length cipher then the recovered key length +must match the fixed cipher length. +.Sh RETURN VALUES +.Fn EVP_OpenInit +returns 0 on error or a non-zero integer (actually the recovered secret +key size) if successful. +.Pp +.Fn EVP_OpenUpdate +returns 1 for success or 0 for failure. +.Pp +.Fn EVP_OpenFinal +returns 0 if the decrypt failed or 1 for success. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 , +.Xr EVP_SealInit 3 +.Sh HISTORY +.Fn EVP_OpenInit , +.Fn EVP_OpenUpdate , +and +.Fn EVP_OpenFinal +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/EVP_PKCS82PKEY.3 b/Libraries/libressl/man/EVP_PKCS82PKEY.3 new file mode 100644 index 000000000..5fed846fe --- /dev/null +++ b/Libraries/libressl/man/EVP_PKCS82PKEY.3 @@ -0,0 +1,63 @@ +.\" $OpenBSD: EVP_PKCS82PKEY.3,v 1.1 2021/10/25 13:48:12 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 25 2021 $ +.Dt EVP_PKCS82PKEY 3 +.Os +.Sh NAME +.Nm EVP_PKCS82PKEY , +.Nm EVP_PKEY2PKCS8 +.Nd convert between EVP_PKEY and PKCS#8 PrivateKeyInfo +.Sh SYNOPSIS +.In openssl/x509.h +.Ft EVP_PKEY * +.Fn EVP_PKCS82PKEY "const PKCS8_PRIV_KEY_INFO *keyinfo" +.Ft PKCS8_PRIV_KEY_INFO * +.Fn EVP_PKEY2PKCS8 "EVP_PKEY *pkey" +.Sh DESCRIPTION +.Fn EVP_PKCS82PKEY +extracts the private key from a PKCS#8 +.Vt PrivateKeyInfo +structure. +.Pp +.Fn EVP_PKEY2PKCS8 +creates a PKCS#8 +.Vt PrivateKeyInfo +structure representing the private key contained in +.Fa pkey . +.Pp +Supported algorithms include DH, DSA, EC, GOST2001, and RSA. +Application programs can add additional algorithms using +.Xr EVP_PKEY_asn1_add0 3 . +.Sh RETURN VALUES +These functions return a newly allocated object or +.Dv NULL +if the algorithm indicated in +.Fa keyinfo +or +.Fa pkey +is unsupported or if memory allocation, decoding, or encoding fails. +.Sh SEE ALSO +.Xr EVP_PKEY_asn1_add0 3 , +.Xr EVP_PKEY_base_id 3 , +.Xr EVP_PKEY_new 3 , +.Xr PKCS8_pkey_set0 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +.Xr X509_ALGOR_get0 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.3 +and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/EVP_PKEY_CTX_ctrl.3 b/Libraries/libressl/man/EVP_PKEY_CTX_ctrl.3 new file mode 100644 index 000000000..f07d02c82 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_CTX_ctrl.3 @@ -0,0 +1,497 @@ +.\" $OpenBSD: EVP_PKEY_CTX_ctrl.3,v 1.23 2023/09/13 13:32:01 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" Parts were split out into RSA_pkey_ctx_ctrl(3). +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Antoine Salon . +.\" Copyright (c) 2006, 2009, 2013, 2014, 2015, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 13 2023 $ +.Dt EVP_PKEY_CTX_CTRL 3 +.Os +.Sh NAME +.Nm EVP_PKEY_CTX_ctrl , +.Nm EVP_PKEY_CTX_ctrl_str , +.Nm EVP_PKEY_CTX_set_signature_md , +.Nm EVP_PKEY_CTX_get_signature_md , +.Nm EVP_PKEY_CTX_set_dsa_paramgen_bits , +.Nm EVP_PKEY_CTX_set_dh_paramgen_prime_len , +.Nm EVP_PKEY_CTX_set_dh_paramgen_generator , +.Nm EVP_PKEY_CTX_set_ec_paramgen_curve_nid , +.Nm EVP_PKEY_CTX_set_ec_param_enc , +.Nm EVP_PKEY_CTX_set_ecdh_cofactor_mode , +.Nm EVP_PKEY_CTX_get_ecdh_cofactor_mode , +.Nm EVP_PKEY_CTX_set_ecdh_kdf_type , +.Nm EVP_PKEY_CTX_get_ecdh_kdf_type , +.Nm EVP_PKEY_CTX_set_ecdh_kdf_md , +.Nm EVP_PKEY_CTX_get_ecdh_kdf_md , +.Nm EVP_PKEY_CTX_set_ecdh_kdf_outlen , +.Nm EVP_PKEY_CTX_get_ecdh_kdf_outlen , +.Nm EVP_PKEY_CTX_set0_ecdh_kdf_ukm , +.Nm EVP_PKEY_CTX_get0_ecdh_kdf_ukm , +.Nm EVP_PKEY_CTX_set1_id , +.Nm EVP_PKEY_CTX_get1_id , +.Nm EVP_PKEY_CTX_get1_id_len +.Nd algorithm specific control operations +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_CTX_ctrl +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int keytype" +.Fa "int optype" +.Fa "int cmd" +.Fa "int p1" +.Fa "void *p2" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_ctrl_str +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const char *type" +.Fa "const char *value" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_signature_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_signature_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD **pmd" +.Fc +.In openssl/dsa.h +.Ft int +.Fo EVP_PKEY_CTX_set_dsa_paramgen_bits +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int nbits" +.Fc +.In openssl/dh.h +.Ft int +.Fo EVP_PKEY_CTX_set_dh_paramgen_prime_len +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_dh_paramgen_generator +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int gen" +.Fc +.In openssl/ec.h +.Ft int +.Fo EVP_PKEY_CTX_set_ec_paramgen_curve_nid +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int nid" +.Fc +.Fa int +.Fo EVP_PKEY_CTX_set_ec_param_enc +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int param_enc" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_ecdh_cofactor_mode +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int cofactor_mode" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_ecdh_cofactor_mode +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_ecdh_kdf_type +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int kdf" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_ecdh_kdf_type +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_ecdh_kdf_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_ecdh_kdf_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD **pmd" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_ecdh_kdf_outlen +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_ecdh_kdf_outlen +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int *plen" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set0_ecdh_kdf_ukm +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *ukm" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get0_ecdh_kdf_ukm +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char **pukm" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set1_id +.Fa "EVP_PKEY_CTX *ctx" +.Fa "void *id" +.Fa "size_t id_len" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get1_id +.Fa "EVP_PKEY_CTX *ctx" +.Fa "void *id" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get1_id_len +.Fa "EVP_PKEY_CTX *ctx" +.Fa "size_t *pid_len" +.Fc +.Sh DESCRIPTION +The function +.Fn EVP_PKEY_CTX_ctrl +sends a control operation to the context +.Fa ctx . +The key type used must match +.Fa keytype +if it is not -1. +The parameter +.Fa optype +is a mask indicating which operations the control can be applied to. +The control command is indicated in +.Fa cmd +and any additional arguments in +.Fa p1 +and +.Fa p2 . +.Pp +Applications will not normally call +.Fn EVP_PKEY_CTX_ctrl +directly but will instead call one of the algorithm specific macros +described below and in +.Xr RSA_pkey_ctx_ctrl 3 . +.Pp +The function +.Fn EVP_PKEY_CTX_ctrl_str +allows an application to send an algorithm specific control operation to +a context +.Fa ctx +in string form. +This is intended to be used for options specified on the command line or +in text files. +The commands supported are documented in the +.Xr openssl 1 +utility command line pages for the option +.Fl pkeyopt +which is supported by the +.Cm pkeyutl , +.Cm genpkey , +and +.Cm req +commands. +.Pp +All the remaining "functions" are implemented as macros. +.Pp +The +.Fn EVP_PKEY_CTX_set_signature_md +and +.Fn EVP_PKEY_CTX_get_signature_md +macros set and get the message digest type used in a signature. +They can be used with the RSA, DSA, and ECDSA algorithms. +If the key is of the type +.Dv EVP_PKEY_RSA_PSS +and has usage restrictions, an error occurs if an attempt is made +to set the digest to anything other than the restricted value. +.Pp +These two macros expand to +.Fn EVP_PKEY_CTX_ctrl +with an +.Fa optype +of +.Dv EVP_PKEY_OP_TYPE_SIG +and the following command arguments: +.Pp +.Bl -column -compact EVP_PKEY_CTRL_GET_MD EVP_PKEY_CTX_get_signature_md() +.It Fa cmd No constant Ta corresponding macro +.It Dv EVP_PKEY_CTRL_MD Ta Fn EVP_PKEY_CTX_set_signature_md +.It Dv EVP_PKEY_CTRL_GET_MD Ta Fn EVP_PKEY_CTX_get_signature_md +.El +.Ss DSA parameters +The macro +.Fn EVP_PKEY_CTX_set_dsa_paramgen_bits +sets the number of bits used for DSA parameter generation to +.Fa nbits . +If not specified, 1024 is used. +.Ss DH parameters +The macro +.Fn EVP_PKEY_CTX_set_dh_paramgen_prime_len +sets the length of the DH prime parameter +.Fa len +for DH parameter generation. +It only accepts lengths greater than or equal to 256. +If this macro is not called, then 1024 is used. +.Pp +The +.Fn EVP_PKEY_CTX_set_dh_paramgen_generator +macro sets DH generator to +.Fa gen +for DH parameter generation. +If not specified, 2 is used. +.Ss EC parameters +The +.Fn EVP_PKEY_CTX_set_ec_paramgen_curve_nid +macro sets the EC curve for EC parameter generation to +.Fa nid . +For EC parameter generation, this macro must be called or an error occurs +because there is no default curve. +.Pp +The +.Fn EVP_PKEY_CTX_set_ec_param_enc +macro sets the EC parameter encoding to +.Fa param_enc +when generating EC parameters or an EC key. +The encoding can be set to 0 for explicit parameters or to +.Dv OPENSSL_EC_NAMED_CURVE +to use named curve form. +.Ss ECDH parameters +The +.Fn EVP_PKEY_CTX_set_ecdh_cofactor_mode +macro sets the cofactor mode to +.Fa cofactor_mode +for ECDH key derivation. +Possible values are 1 to enable cofactor key derivation, 0 to disable +it, or -1 to clear the stored cofactor mode and fall back to the +private key cofactor mode. +.Pp +The +.Fn EVP_PKEY_CTX_get_ecdh_cofactor_mode +macro returns the cofactor mode for +.Fa ctx +used for ECDH key derivation. +Possible return values are 1 when cofactor key derivation is enabled +or 0 otherwise. +.Ss ECDH key derivation function parameters +The +.Fn EVP_PKEY_CTX_set_ecdh_kdf_type +macro sets the key derivation function type to +.Fa kdf +for ECDH key derivation. +Possible values are +.Dv EVP_PKEY_ECDH_KDF_NONE +or +.Dv EVP_PKEY_ECDH_KDF_X9_63 +which uses the key derivation specified in X9.63. +When using key derivation, the +.Fa kdf_md +and +.Fa kdf_outlen +parameters must also be specified. +.Pp +The +.Fn EVP_PKEY_CTX_get_ecdh_kdf_type +macro returns the key derivation function type for +.Fa ctx +used for ECDH key derivation. +Possible return values are +.Dv EVP_PKEY_ECDH_KDF_NONE +or +.Dv EVP_PKEY_ECDH_KDF_X9_63 . +.Pp +The +.Fn EVP_PKEY_CTX_set_ecdh_kdf_md +macro sets the key derivation function message digest to +.Fa md +for ECDH key derivation. +Note that X9.63 specifies that this digest should be SHA1, +but OpenSSL tolerates other digests. +.Pp +The +.Fn EVP_PKEY_CTX_get_ecdh_kdf_md +macro gets the key derivation function message digest for +.Fa ctx +used for ECDH key derivation. +.Pp +The +.Fn EVP_PKEY_CTX_set_ecdh_kdf_outlen +macro sets the key derivation function output length to +.Fa len +for ECDH key derivation. +.Pp +The +.Fn EVP_PKEY_CTX_get_ecdh_kdf_outlen +macro gets the key derivation function output length for +.Fa ctx +used for ECDH key derivation. +.Pp +The +.Fn EVP_PKEY_CTX_set0_ecdh_kdf_ukm +macro sets the user key material to +.Fa ukm +for ECDH key derivation. +This parameter is optional and corresponds to the shared info +in X9.63 terms. +The library takes ownership of the user key material, so the caller +should not free the original memory pointed to by +.Fa ukm . +.Pp +The +.Fn EVP_PKEY_CTX_get0_ecdh_kdf_ukm +macro gets the user key material for +.Fa ctx . +The return value is the user key material length. +The resulting pointer is owned by the library and should not be +freed by the caller. +.Ss Other parameters +The +.Fn EVP_PKEY_CTX_set1_id , +.Fn EVP_PKEY_CTX_get1_id , +and +.Fn EVP_PKEY_CTX_get1_id_len +macros manipulate a special identifier field used for some specific +signature algorithms such as SM2. +The +.Fn EVP_PKEY_set1_id +macro sets the ID to a copy of +.Fa id +with the length +.Fa id_len . +The caller can safely free the original memory pointed to by +.Fa id . +The +.Fn EVP_PKEY_CTX_get1_id_len +macro returns the length of the ID set via a previous call to +.Fn EVP_PKEY_set1_id . +That length is typically used to allocate memory for a subsequent call to +.Fn EVP_PKEY_CTX_get1_id , +which copies the previously set ID into +.Pf * Fa id . +The caller is responsible for allocating sufficient memory for +.Fa id +before calling +.Fn EVP_PKEY_CTX_get1_id . +.Sh RETURN VALUES +.Fn EVP_PKEY_CTX_ctrl +and its macros return a positive value for success and 0 or a negative +value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh SEE ALSO +.Xr DH_new 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_get_default_digest_nid 3 , +.Xr EVP_PKEY_keygen 3 , +.Xr EVP_PKEY_meth_set_ctrl 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 , +.Xr RSA_pkey_ctx_ctrl 3 +.Sh HISTORY +The functions +.Fn EVP_PKEY_CTX_ctrl , +.Fn EVP_PKEY_CTX_ctrl_str , +.Fn EVP_PKEY_CTX_set_signature_md , +.Fn EVP_PKEY_CTX_set_dsa_paramgen_bits , +.Fn EVP_PKEY_CTX_set_dh_paramgen_prime_len , +.Fn EVP_PKEY_CTX_set_dh_paramgen_generator , +and +.Fn EVP_PKEY_CTX_set_ec_paramgen_curve_nid +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +The functions +.Fn EVP_PKEY_CTX_get_signature_md , +.Fn EVP_PKEY_CTX_set_ec_param_enc , +.Fn EVP_PKEY_CTX_set_ecdh_cofactor_mode , +.Fn EVP_PKEY_CTX_get_ecdh_cofactor_mode , +.Fn EVP_PKEY_CTX_set_ecdh_kdf_type , +.Fn EVP_PKEY_CTX_get_ecdh_kdf_type , +.Fn EVP_PKEY_CTX_set_ecdh_kdf_md , +.Fn EVP_PKEY_CTX_get_ecdh_kdf_md , +.Fn EVP_PKEY_CTX_set_ecdh_kdf_outlen , +.Fn EVP_PKEY_CTX_get_ecdh_kdf_outlen , +.Fn EVP_PKEY_CTX_set0_ecdh_kdf_ukm , +and +.Fn EVP_PKEY_CTX_get0_ecdh_kdf_ukm +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.6 . +.Pp +The functions +.Fn EVP_PKEY_CTX_set1_id , +.Fn EVP_PKEY_CTX_get1_id , +and +.Fn EVP_PKEY_CTX_get1_id_len +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 6.6 . diff --git a/Libraries/libressl/man/EVP_PKEY_CTX_get_operation.3 b/Libraries/libressl/man/EVP_PKEY_CTX_get_operation.3 new file mode 100644 index 000000000..2482c746d --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_CTX_get_operation.3 @@ -0,0 +1,137 @@ +.\" $OpenBSD: EVP_PKEY_CTX_get_operation.3,v 1.3 2023/09/12 16:15:23 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 12 2023 $ +.Dt EVP_PKEY_CTX_GET_OPERATION 3 +.Os +.Sh NAME +.Nm EVP_PKEY_CTX_get_operation , +.Nm EVP_PKEY_CTX_get0_pkey +.Nd inspect EVP_PKEY_CTX objects +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_CTX_get_operation +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft EVP_PKEY * +.Fo EVP_PKEY_CTX_get0_pkey +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn EVP_PKEY_CTX_get_operation +finds out which initialization function has been called on +.Fa ctx , +if any: +.Bl -column EVP_PKEY_OP_VERIFYRECO EVP_PKEY_verify_recover_init +.It return value Ta initialized with Ta e.g. for +.It Dv EVP_PKEY_OP_DECRYPT Ta Xr EVP_PKEY_decrypt_init 3 Ta RSA, SM2 +.It Dv EVP_PKEY_OP_DERIVE Ta Xr EVP_PKEY_derive_init 3 Ta HKDF +.It Dv EVP_PKEY_OP_ENCRYPT Ta Xr EVP_PKEY_encrypt_init 3 Ta RSA, SM2 +.It Dv EVP_PKEY_OP_KEYGEN Ta Xr EVP_PKEY_keygen_init 3 Ta almost all +.It Dv EVP_PKEY_OP_PARAMGEN Ta Xr EVP_PKEY_paramgen_init 3 Ta DH, DSA, EC +.It Dv EVP_PKEY_OP_SIGN Ta Xr EVP_PKEY_sign_init 3 Ta DSA,EC,RSA,SM2 +.It Dv EVP_PKEY_OP_SIGN Ta Xr EVP_DigestSignInit 3 Ta ED25519 +.It Dv EVP_PKEY_OP_SIGNCTX Ta Xr EVP_DigestSignInit 3 Ta CMAC, HMAC +.It Dv EVP_PKEY_OP_UNDEFINED Ta not initialized Ta NONE +.It Dv EVP_PKEY_OP_VERIFY Ta Xr EVP_PKEY_verify_init 3 Ta DSA,EC,RSA,SM2 +.It Dv EVP_PKEY_OP_VERIFY Ta Xr EVP_DigestVerifyInit 3 Ta ED25519 +.It Dv EVP_PKEY_OP_VERIFYCTX Ta Xr EVP_DigestVerifyInit 3 Ta no built-in +.It Dv EVP_PKEY_OP_VERIFYRECOVER Ta Xr EVP_PKEY_verify_recover_init 3 Ta RSA +.El +.Pp +The rightmost column of the above table shows examples of algorithms +the return values can occur for. +For example, if +.Xr EVP_PKEY_base_id 3 +returns +.Dv EVP_PKEY_HKDF , +then calling +.Fn EVP_PKEY_CTX_get_operation +on a +.Vt EVP_PKEY_CTX +using that key may return +.Dv EVP_PKEY_OP_DERIVE . +.Pp +If the return value is +.Dv EVP_PKEY_OP_SIGNCTX +or +.Dv EVP_PKEY_OP_VERIFYCTX , +the +.Fa ctx +supports +.Xr EVP_DigestSignUpdate 3 +or +.Xr EVP_DigestVerifyUpdate 3 , +respectively. +If the return value is +.Dv EVP_PKEY_OP_SIGN +or +.Dv EVP_PKEY_OP_VERIFY , +if does not, and only one-shot signing or verification is supported. +.Pp +The return value +.Dv EVP_PKEY_OP_UNDEFINED +can for example occur if the +.Fa ctx +was freshly returned from +.Xr EVP_PKEY_CTX_new 3 +or +.Xr EVP_PKEY_CTX_new_id 3 +and not yet initialized. +.Pp +The following masks are defined as the logical OR of two or more of the above +.Dv EVP_PKEY_OP_* +bits: +.Pp +.Bl -tag -width EVP_PKEY_OP_TYPE_NOGEN -compact +.It Dv EVP_PKEY_OP_TYPE_CRYPT +DECRYPT | ENCRYPT +.It Dv EVP_PKEY_OP_TYPE_GEN +KEYGEN | PARAMGEN +.It Dv EVP_PKEY_OP_TYPE_NOGEN +CRYPT | DERIVE | SIG +.It Dv EVP_PKEY_OP_TYPE_SIG +SIGN | SIGNCTX | VERIFY | VERIFYCTX | VERIFYRECOVER +.El +.Sh RETURN VALUES +.Fn EVP_PKEY_CTX_get_operation +returns one of the single-bit +.Dv EVP_PKEY_OP_* +constants or +.Dv EVP_PKEY_OP_UNDEFINED +if +.Fa ctx +is not initialized. +.Pp +.Fn EVP_PKEY_CTX_get0_pkey +returns an internal pointer to the +.Vt EVP_PKEY +object used by +.Fa ctx , +without incrementing its reference count. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_PKEY_base_id 3 , +.Xr EVP_PKEY_CTX_ctrl 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_new 3 +.Sh HISTORY +.Fn EVP_PKEY_CTX_get_operation +and +.Fn EVP_PKEY_CTX_get0_pkey +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_CTX_new.3 b/Libraries/libressl/man/EVP_PKEY_CTX_new.3 new file mode 100644 index 000000000..7a72ac18f --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_CTX_new.3 @@ -0,0 +1,188 @@ +.\" $OpenBSD: EVP_PKEY_CTX_new.3,v 1.13 2023/09/09 14:39:09 schwarze Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019, 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 9 2023 $ +.Dt EVP_PKEY_CTX_NEW 3 +.Os +.Sh NAME +.Nm EVP_PKEY_CTX_new , +.Nm EVP_PKEY_CTX_new_id , +.Nm EVP_PKEY_CTX_dup , +.Nm EVP_PKEY_CTX_free +.Nd public key algorithm context functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_PKEY_CTX * +.Fo EVP_PKEY_CTX_new +.Fa "EVP_PKEY *pkey" +.Fa "ENGINE *e" +.Fc +.Ft EVP_PKEY_CTX * +.Fo EVP_PKEY_CTX_new_id +.Fa "int id" +.Fa "ENGINE *e" +.Fc +.Ft EVP_PKEY_CTX * +.Fo EVP_PKEY_CTX_dup +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft void +.Fo EVP_PKEY_CTX_free +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_CTX_new +function allocates a public key algorithm context using the algorithm +specified in +.Fa pkey +and using +.Fa e +unless it is +.Dv NULL . +If +.Fa pkey +is associated with an engine, that engine is used and +.Fa e +is ignored. +.Pp +The +.Fn EVP_PKEY_CTX_new_id +function allocates a public key algorithm context using the algorithm +specified by +.Fa id +and using +.Fa e +unless it is +.Dv NULL . +It is normally used when no +.Vt EVP_PKEY +structure is associated with the operations, for example during +parameter generation of key generation for some algorithms. +The +.Fa id +argument can be any of the constants that +.Xr EVP_PKEY_base_id 3 +and +.Xr EVP_PKEY_id 3 +may return. +.Pp +.Fn EVP_PKEY_CTX_dup +duplicates the context +.Fa ctx . +.Pp +.Fn EVP_PKEY_CTX_free +frees up the context +.Fa ctx . +If +.Fa ctx +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn EVP_PKEY_CTX_new , +.Fn EVP_PKEY_CTX_new_id , +and +.Fn EVP_PKEY_CTX_dup +return either the newly allocated +.Vt EVP_PKEY_CTX +structure or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr EVP_DigestSignInit 3 , +.Xr EVP_DigestVerifyInit 3 , +.Xr EVP_PKEY_base_id 3 , +.Xr EVP_PKEY_check 3 , +.Xr EVP_PKEY_CTX_ctrl 3 , +.Xr EVP_PKEY_CTX_get_operation 3 , +.Xr EVP_PKEY_CTX_hkdf_mode 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_keygen 3 , +.Xr EVP_PKEY_meth_set_init 3 , +.Xr EVP_PKEY_new 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 , +.Xr RSA_pkey_ctx_ctrl 3 , +.Xr X25519 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . +.Sh CAVEATS +The +.Vt EVP_PKEY_CTX +structure is an opaque public key algorithm context used by the OpenSSL +high level public key API. +Contexts +.Sy MUST NOT +be shared between threads. +It is not permissible to use the same context simultaneously in two +threads. diff --git a/Libraries/libressl/man/EVP_PKEY_CTX_set_hkdf_md.3 b/Libraries/libressl/man/EVP_PKEY_CTX_set_hkdf_md.3 new file mode 100644 index 000000000..86286fab5 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_CTX_set_hkdf_md.3 @@ -0,0 +1,257 @@ +.\" $OpenBSD: EVP_PKEY_CTX_set_hkdf_md.3,v 1.3 2023/09/13 13:46:52 schwarze Exp $ +.\" full merge up to: OpenSSL 1cb7eff4 Sep 10 13:56:40 2019 +0100 +.\" +.\" This file was written by Alessandro Ghedini , +.\" Matt Caswell , and Viktor Dukhovni . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 13 2023 $ +.Dt EVP_PKEY_CTX_SET_HKDF_MD 3 +.Os +.Sh NAME +.Nm EVP_PKEY_CTX_set_hkdf_md , +.Nm EVP_PKEY_CTX_set1_hkdf_salt , +.Nm EVP_PKEY_CTX_set1_hkdf_key , +.Nm EVP_PKEY_CTX_add1_hkdf_info , +.Nm EVP_PKEY_CTX_hkdf_mode +.Nd HMAC-based Extract-and-Expand key derivation algorithm +.Sh SYNOPSIS +.In openssl/kdf.h +.Ft int +.Fo EVP_PKEY_CTX_hkdf_mode +.Fa "EVP_PKEY_CTX *pctx" +.Fa "int mode" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_hkdf_md +.Fa "EVP_PKEY_CTX *pctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set1_hkdf_salt +.Fa "EVP_PKEY_CTX *pctx" +.Fa "unsigned char *salt" +.Fa "int saltlen" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set1_hkdf_key +.Fa "EVP_PKEY_CTX *pctx" +.Fa "unsigned char *key" +.Fa "int keylen" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_add1_hkdf_info +.Fa "EVP_PKEY_CTX *pctx" +.Fa "unsigned char *info" +.Fa "int infolen" +.Fc +.Sh DESCRIPTION +The +.Dv EVP_PKEY_HKDF +algorithm implements the HKDF key derivation function. +HKDF follows the "extract-then-expand" paradigm, where the KDF logically +consists of two modules. +The first stage takes the input keying material and "extracts" from it a +fixed-length pseudorandom key K. +The second stage "expands" the key K +into several additional pseudorandom keys (the output of the KDF). +.Pp +.Fn EVP_PKEY_CTX_hkdf_mode +sets the mode for the HKDF operation. +There are three modes that are currently defined: +.Bl -tag -width Ds +.It Dv EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND +This is the default mode. +Calling +.Xr EVP_PKEY_derive 3 +on an +.Vt EVP_PKEY_CTX +set up for HKDF will perform an extract followed by +an expand operation in one go. +The derived key returned will be the result after the expand operation. +The intermediate fixed-length pseudorandom key K is not returned. +.Pp +In this mode the digest, key, salt and info values must be set before a +key is derived or an error occurs. +.It Dv EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY +In this mode calling +.Xr EVP_PKEY_derive 3 +will just perform the extract operation. +The value returned will be the intermediate fixed-length pseudorandom +key K. +.Pp +The digest, key and salt values must be set before a key is derived or +an error occurs. +.It Dv EVP_PKEY_HKDEF_MODE_EXPAND_ONLY +In this mode calling +.Xr EVP_PKEY_derive 3 +will just perform the expand operation. +The input key should be set to the intermediate fixed-length +pseudorandom key K returned from a previous extract operation. +.Pp +The digest, key and info values must be set before a key is derived or +an error occurs. +.El +.Pp +.Fn EVP_PKEY_CTX_set_hkdf_md +sets the message digest associated with the HKDF. +.Pp +.Fn EVP_PKEY_CTX_set1_hkdf_salt +sets the salt to +.Fa saltlen +bytes of the buffer +.Fa salt . +Any existing value is replaced. +.Pp +.Fn EVP_PKEY_CTX_set1_hkdf_key +sets the key to +.Fa keylen +bytes of the buffer +.Fa key . +Any existing value is replaced. +.Pp +.Fn EVP_PKEY_CTX_add1_hkdf_info +sets the info value to +.Fa infolen +bytes of the buffer +.Fa info . +If a value is already set, it is appended to the existing value. +.Sh STRING CTRLS +HKDF also supports string based control operations via +.Xr EVP_PKEY_CTX_ctrl_str 3 . +The +.Fa type +parameter "md" uses the supplied +.Fa value +as the name of the digest algorithm to use. +The +.Fa type +parameter "mode" accepts "EXTRACT_AND_EXPAND", "EXTRACT_ONLY" +and "EXPAND_ONLY" as +.Fa value +to determine the mode to use. +The +.Fa type +parameters "salt", "key" and "info" use the supplied +.Fa value +parameter as a +seed, key, or info. +The names "hexsalt", "hexkey" and "hexinfo" are similar except they take +a hex string which is converted to binary. +.Sh NOTES +All these functions are implemented as macros. +.Pp +A context for HKDF can be obtained by calling: +.Bd -literal + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); +.Ed +.Pp +The total length of the info buffer cannot exceed 1024 bytes in length: +this should be more than enough for any normal use of HKDF. +.Pp +The output length of an HKDF expand operation is specified via the +length parameter to the +.Xr EVP_PKEY_derive 3 +function. +Since the HKDF output length is variable, passing a +.Dv NULL +buffer as a means to obtain the requisite length is not meaningful with +HKDF in any mode that performs an expand operation. +Instead, the caller must allocate a buffer of the desired length, and +pass that buffer to +.Xr EVP_PKEY_derive 3 +along with (a pointer initialized to) the desired length. +Passing a +.Dv NULL +buffer to obtain the length is allowed when using +.Dv EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY . +.Sh RETURN VALUES +All these functions return 1 for success and 0 or a negative value for +failure. +In particular a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh EXAMPLES +This example derives 10 bytes using SHA-256 with the secret key +"secret", salt value "salt" and info value "label": +.Bd -literal +EVP_PKEY_CTX *pctx; +unsigned char out[10]; +size_t outlen = sizeof(out); + +if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL) + /* Error */ + +if (EVP_PKEY_derive_init(pctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0) + /* Error */ +if (EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0) + /* Error */ +if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) + /* Error */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_ctrl_str 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_derive 3 +.Sh STANDARDS +RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) +.Sh HISTORY +.Fn EVP_PKEY_CTX_set_hkdf_md , +.Fn EVP_PKEY_CTX_set1_hkdf_salt , +.Fn EVP_PKEY_CTX_set1_hkdf_key , +and +.Fn EVP_PKEY_CTX_add1_hkdf_info +first appeared in OpenSSL 1.1.0 and +.Fn EVP_PKEY_CTX_hkdf_mode +in OpenSSL 1.1.1. +These functions have been available since +.Ox 7.2 . diff --git a/Libraries/libressl/man/EVP_PKEY_add1_attr.3 b/Libraries/libressl/man/EVP_PKEY_add1_attr.3 new file mode 100644 index 000000000..ae910b167 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_add1_attr.3 @@ -0,0 +1,188 @@ +.\" $OpenBSD: EVP_PKEY_add1_attr.3,v 1.3 2021/10/26 18:50:38 jmc Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 26 2021 $ +.Dt EVP_PKEY_ADD1_ATTR 3 +.Os +.Sh NAME +.Nm EVP_PKEY_add1_attr , +.Nm EVP_PKEY_add1_attr_by_OBJ , +.Nm EVP_PKEY_add1_attr_by_NID , +.Nm EVP_PKEY_add1_attr_by_txt , +.Nm EVP_PKEY_delete_attr , +.Nm EVP_PKEY_get_attr , +.Nm EVP_PKEY_get_attr_count , +.Nm EVP_PKEY_get_attr_by_OBJ , +.Nm EVP_PKEY_get_attr_by_NID +.Nd X.501 Attributes of private keys +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo EVP_PKEY_add1_attr +.Fa "EVP_PKEY *key" +.Fa "X509_ATTRIBUTE *attr" +.Fc +.Ft int +.Fo EVP_PKEY_add1_attr_by_OBJ +.Fa "EVP_PKEY *key" +.Fa "const ASN1_OBJECT *obj" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_add1_attr_by_NID +.Fa "EVP_PKEY *key" +.Fa "int nid" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_add1_attr_by_txt +.Fa "EVP_PKEY *key" +.Fa "const char *name" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft X509_ATTRIBUTE * +.Fo EVP_PKEY_delete_attr +.Fa "EVP_PKEY *key" +.Fa "int index" +.Fc +.Ft X509_ATTRIBUTE * +.Fo EVP_PKEY_get_attr +.Fa "const EVP_PKEY *key" +.Fa "int index" +.Fc +.Ft int +.Fo EVP_PKEY_get_attr_count +.Fa "const EVP_PKEY *key" +.Fc +.Ft int +.Fo EVP_PKEY_get_attr_by_OBJ +.Fa "const EVP_PKEY *key" +.Fa "const ASN1_OBJECT *obj" +.Fa "int start_after" +.Fc +.Ft int +.Fo EVP_PKEY_get_attr_by_NID +.Fa "const EVP_PKEY *key" +.Fa "int nid" +.Fa "int start_after" +.Fc +.Sh DESCRIPTION +These functions support associating an array of X.501 Attributes +with a private key. +Such attributes can for example be included in PKCS#12 structures. +.Pp +.Fn EVP_PKEY_add1_attr +appends a deep copy of the +.Fa attr +using +.Xr X509at_add1_attr 3 . +.Pp +.Fn EVP_PKEY_add1_attr_by_OBJ , +.Fn EVP_PKEY_add1_attr_by_NID , +and +.Fn EVP_PKEY_add1_attr_by_txt +create a new X.501 Attribute object using +.Xr X509_ATTRIBUTE_create_by_OBJ 3 , +.Xr X509_ATTRIBUTE_create_by_NID 3 , +or +.Xr X509_ATTRIBUTE_create_by_txt 3 , +respectively, and append it using +.Xr X509at_add1_attr 3 . +.Pp +.Fn EVP_PKEY_delete_attr +deletes the attribute with the zero-based +.Fa index +using +.Xr X509at_delete_attr 3 . +.Pp +.Fn EVP_PKEY_get_attr +returns the attribute with the zero-based +.Fa index +using +.Xr X509at_get_attr 3 . +.Pp +.Fn EVP_PKEY_get_attr_count +returns the number of attributes currently associated with the +.Fa key +using +.Xr X509at_get_attr_count 3 . +.Pp +.Fn EVP_PKEY_get_attr_by_OBJ +and +.Fn EVP_PKEY_get_attr_by_NID +search for an attribute of the type +.Fa obj +or +.Fa nid +using +.Xr X509at_get_attr_by_OBJ 3 +or +.Xr X509at_get_attr_by_NID 3 , +respectively. +.Sh RETURN VALUES +.Fn EVP_PKEY_add1_attr , +.Fn EVP_PKEY_add1_attr_by_OBJ , +.Fn EVP_PKEY_add1_attr_by_NID , +and +.Fn EVP_PKEY_add1_attr_by_txt +return 1 for success or 0 for failure. +.Pp +.Fn EVP_PKEY_delete_attr +and +.Fn EVP_PKEY_get_attr +return the deleted or requested attribute or +.Dv NULL +if the requested index is negative or greater than or equal to +the current number of attributes associated with the +.Fa key . +.Pp +.Fn EVP_PKEY_get_attr_count +returns the current number of attributes. +.Pp +.Fn EVP_PKEY_get_attr_by_OBJ +and +.Fn EVP_PKEY_get_attr_by_NID +return the index of the first attribute that has an index greater than +.Fa start_after +and a type matching +.Fa obj +or +.Fa nid , +respectively, or \-1 on failure. +In addition, +.Fn EVP_PKEY_get_attr_by_NID +returns \-2 if +.Xr OBJ_nid2obj 3 +fails on the requested +.Fa nid . +.Sh SEE ALSO +.Xr EVP_PKEY_new 3 , +.Xr OBJ_nid2obj 3 , +.Xr PKCS12_create 3 , +.Xr X509_ATTRIBUTE_create_by_OBJ 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509at_add1_attr 3 , +.Xr X509at_get_attr 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8 +and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/EVP_PKEY_asn1_get_count.3 b/Libraries/libressl/man/EVP_PKEY_asn1_get_count.3 new file mode 100644 index 000000000..9f272a242 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_asn1_get_count.3 @@ -0,0 +1,264 @@ +.\" $OpenBSD: EVP_PKEY_asn1_get_count.3,v 1.7 2023/09/13 13:55:50 schwarze Exp $ +.\" full merge up to: OpenSSL 72a7a702 Feb 26 14:05:09 2019 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2020, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 13 2023 $ +.Dt EVP_PKEY_ASN1_GET_COUNT 3 +.Os +.Sh NAME +.Nm EVP_PKEY_asn1_get_count , +.Nm EVP_PKEY_asn1_get0 , +.Nm EVP_PKEY_get0_asn1 , +.Nm EVP_PKEY_asn1_find , +.Nm EVP_PKEY_asn1_find_str , +.Nm EVP_PKEY_asn1_get0_info +.Nd enumerate public key ASN.1 methods +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fn EVP_PKEY_asn1_get_count void +.Ft const EVP_PKEY_ASN1_METHOD * +.Fo EVP_PKEY_asn1_get0 +.Fa "int idx" +.Fc +.Ft const EVP_PKEY_ASN1_METHOD * +.Fo EVP_PKEY_get0_asn1 +.Fa "const EVP_PKEY *pkey" +.Fc +.Ft const EVP_PKEY_ASN1_METHOD * +.Fo EVP_PKEY_asn1_find +.Fa "ENGINE **pe" +.Fa "int type" +.Fc +.Ft const EVP_PKEY_ASN1_METHOD * +.Fo EVP_PKEY_asn1_find_str +.Fa "ENGINE **pe" +.Fa "const char *str" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_asn1_get0_info +.Fa "int *ppkey_id" +.Fa "int *pkey_base_id" +.Fa "int *ppkey_flags" +.Fa "const char **pinfo" +.Fa "const char **ppem_str" +.Fa "const EVP_PKEY_ASN1_METHOD *ameth" +.Fc +.Sh DESCRIPTION +.Fn EVP_PKEY_asn1_get_count +returns the number of public key ASN.1 methods available. +It includes standard methods and any methods added by the application. +.Pp +.Fn EVP_PKEY_asn1_get0 +returns the public key ASN.1 method +.Fa idx . +The value of +.Fa idx +must be in the range from zero to +.Fn EVP_PKEY_asn1_get_count +\- 1. +.Pp +.Fn EVP_PKEY_asn1_find +looks up the method with NID +.Fa type , +which can be any of the values that +.Xr EVP_PKEY_base_id 3 +and +.Xr EVP_PKEY_id 3 +may return. +If +.Fa pe +is not +.Dv NULL , +it first looks for an engine implementing a method for the NID +.Fa type . +If one is found, +.Pf * Fa pe +is set to that engine and the method from that engine is returned instead. +.Pp +.Fn EVP_PKEY_asn1_find_str +looks up the method with the PEM type string given by the first +.Fa len +bytes of +.Fa str . +If +.Fa len +is \-1, the +.Xr strlen 3 +of +.Fa str +is used instead. +The PEM type strings supported by default are listed in the +.Xr EVP_PKEY_base_id 3 +manual page. +Just like +.Fn EVP_PKEY_asn1_find , +if +.Fa pe +is not +.Dv NULL , +methods from engines are preferred. +.Pp +.Fn EVP_PKEY_asn1_get0_info +retrieves the public key ID as returned by +.Xr EVP_PKEY_id 3 , +the base public key ID as returned by +.Xr EVP_PKEY_base_id 3 +.Pq both NIDs , +any flags, and internal pointers owned by +.Fa ameth +pointing to its method description string and its PEM type string. +.Pp +The following flags bits can occur, OR'ed together in +.Pf * Fa ppkey_flags : +.Bl -tag -width Ds +.It Dv ASN1_PKEY_ALIAS +This +.Fa ameth +object serves as an alias for another +.Vt EVP_PKEY_ASN1_METHOD +object and will never be returned from +.Fn EVP_PKEY_asn1_find +or +.Fn EVP_PKEY_asn1_find_str . +It is either an alias built into the library, or it was created with +.Xr EVP_PKEY_asn1_add_alias 3 . +.It Dv ASN1_PKEY_DYNAMIC +This +.Fa ameth +object is marked as dynamically allocated. +If this flag is set, +.Xr EVP_PKEY_asn1_free 3 +can free +.Fa ameth ; +otherwise, +.Xr EVP_PKEY_asn1_free 3 +has no effect on it. +.It Dv ASN1_PKEY_SIGPARAM_NULL +If the signing +.Fa ctx +uses an +.Vt EVP_PKEY +private key associated with this +.Fa ameth , +instruct +.Xr ASN1_item_sign_ctx 3 +to use a parameter type of +.Dv V_ASN1_NULL +instead of the default +.Dv V_ASN1_UNDEF +when encoding the ASN.1 +.Vt AlgorithmIdentifier +objects with +.Xr X509_ALGOR_set0 3 . +In particular, this is used for +.Dv EVP_PKEY_RSA . +.El +.Pp +.Fn EVP_PKEY_asn1_get_count , +.Fn EVP_PKEY_asn1_get0 , +.Fn EVP_PKEY_asn1_find +and +.Fn EVP_PKEY_asn1_find_str +are not thread safe, but as long as all +.Vt EVP_PKEY_ASN1_METHOD +objects are added before the application gets threaded, using them is +safe. +See +.Xr EVP_PKEY_asn1_add0 3 . +.Sh RETURN VALUES +.Fn EVP_PKEY_asn1_get_count +returns the number of available public key methods. +.Pp +.Fn EVP_PKEY_asn1_get0 +returns a public key method or +.Dv NULL +if +.Fa idx +is out of range. +.Pp +.Fn EVP_PKEY_get0_asn1 +returns the public key method used by +.Fa pkey . +.Pp +.Fn EVP_PKEY_asn1_find +and +.Fn EVP_PKEY_asn1_find_str +return a matching public key method or +.Dv NULL +if no match is found. +.Pp +.Fn EVP_PKEY_asn1_get0_info +returns 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr EVP_PKEY_asn1_new 3 , +.Xr EVP_PKEY_base_id 3 , +.Xr EVP_PKEY_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_asn1_new.3 b/Libraries/libressl/man/EVP_PKEY_asn1_new.3 new file mode 100644 index 000000000..82a109c57 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_asn1_new.3 @@ -0,0 +1,545 @@ +.\" $OpenBSD: EVP_PKEY_asn1_new.3,v 1.10 2023/09/13 14:18:21 schwarze Exp $ +.\" selective merge up to: +.\" OpenSSL man3/EVP_PKEY_ASN1_METHOD b0004708 Nov 1 00:45:24 2017 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte +.\" and Paul Yang . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 13 2023 $ +.Dt EVP_PKEY_ASN1_NEW 3 +.Os +.Sh NAME +.Nm EVP_PKEY_asn1_new , +.Nm EVP_PKEY_asn1_copy , +.Nm EVP_PKEY_asn1_free , +.Nm EVP_PKEY_asn1_add0 , +.Nm EVP_PKEY_asn1_add_alias , +.Nm EVP_PKEY_asn1_set_public , +.Nm EVP_PKEY_asn1_set_private , +.Nm EVP_PKEY_asn1_set_param , +.Nm EVP_PKEY_asn1_set_free , +.Nm EVP_PKEY_asn1_set_ctrl , +.Nm EVP_PKEY_asn1_set_check , +.Nm EVP_PKEY_asn1_set_public_check , +.Nm EVP_PKEY_asn1_set_param_check , +.Nm EVP_PKEY_asn1_set_security_bits +.Nd manipulating and registering an EVP_PKEY_ASN1_METHOD structure +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_PKEY_ASN1_METHOD * +.Fo EVP_PKEY_asn1_new +.Fa "int id" +.Fa "int flags" +.Fa "const char *pem_str" +.Fa "const char *info" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_copy +.Fa "EVP_PKEY_ASN1_METHOD *dst" +.Fa "const EVP_PKEY_ASN1_METHOD *src" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_free +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fc +.Ft int +.Fo EVP_PKEY_asn1_add0 +.Fa "const EVP_PKEY_ASN1_METHOD *ameth" +.Fc +.Ft int +.Fo EVP_PKEY_asn1_add_alias +.Fa "int to" +.Fa "int from" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_public +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub)" +.Fa "int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk)" +.Fa "int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b)" +.Fa "int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,\ + ASN1_PCTX *pctx)" +.Fa "int (*pkey_size)(const EVP_PKEY *pk)" +.Fa "int (*pkey_bits)(const EVP_PKEY *pk)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_private +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)" +.Fa "int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)" +.Fa "int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,\ + ASN1_PCTX *pctx)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_param +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder,\ + int derlen)" +.Fa "int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder)" +.Fa "int (*param_missing)(const EVP_PKEY *pk)" +.Fa "int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from)" +.Fa "int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b)" +.Fa "int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,\ + ASN1_PCTX *pctx)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_free +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "void (*pkey_free)(EVP_PKEY *pkey)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_ctrl +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_check +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*pkey_check)(const EVP_PKEY *pk)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_public_check +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*pkey_public_check)(const EVP_PKEY *pk)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_param_check +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*pkey_param_check)(const EVP_PKEY *pk)" +.Fc +.Ft void +.Fo EVP_PKEY_asn1_set_security_bits +.Fa "EVP_PKEY_ASN1_METHOD *ameth" +.Fa "int (*pkey_security_bits)(const EVP_PKEY *pkey)" +.Fc +.Sh DESCRIPTION +.Vt EVP_PKEY_ASN1_METHOD +is a structure which holds a set of ASN.1 conversion, printing and +information methods for a specific public key algorithm. +.Pp +There are two places where the +.Vt EVP_PKEY_ASN1_METHOD +objects are stored: one is a built-in array representing the standard +methods for different algorithms, and the other one is a stack of +user-defined application-specific methods, which can be manipulated by +using +.Fn EVP_PKEY_asn1_add0 . +.Ss Methods +The methods are the underlying implementations of a particular public +key algorithm present by the +.Vt EVP_PKEY +object. +.Bd -unfilled +.Ft int Fn (*pub_decode) "EVP_PKEY *pk" "X509_PUBKEY *pub" +.Ft int Fn (*pub_encode) "X509_PUBKEY *pub" "const EVP_PKEY *pk" +.Ed +.Pp +Decode and encode +.Vt X509_PUBKEY +ASN.1 parameters to and from +.Fa pk . +These methods must return 0 on error and 1 on success. +They are called by +.Xr X509_PUBKEY_get 3 +and +.Xr X509_PUBKEY_set 3 . +.Bd -unfilled +.Ft int Fn (*pub_cmp) "const EVP_PKEY *a" "const EVP_PKEY *b" +.Ed +.Pp +Compare two public keys. +This method must return 1 when the keys are equal and 0 otherwise. +It is called by +.Xr EVP_PKEY_cmp 3 . +.Bd -filled +.Ft int Fo (*pub_print) +.Fa "BIO *out" +.Fa "const EVP_PKEY *pkey" +.Fa "int indent" +.Fa "ASN1_PCTX *pctx" +.Fc +.Ed +.Pp +Print a public key in humanly readable text to +.Fa out , +indented +.Fa indent +spaces. +This method must return 0 on error and 1 on success. +It is called by +.Xr EVP_PKEY_print_public 3 . +.Bd -unfilled +.Ft int Fn (*priv_decode) "EVP_PKEY *pk" "const PKCS8_PRIV_KEY_INFO *p8inf" +.Ft int Fn (*priv_encode) "PKCS8_PRIV_KEY_INFO *p8" "const EVP_PKEY *pk" +.Ed +.Pp +Decode and encode +.Vt PKCS8_PRIV_KEY_INFO +form private key to and from +.Fa pk . +These methods must return 0 on error, 1 on success. +They are called by +.Xr EVP_PKCS82PKEY 3 +and +.Xr EVP_PKEY2PKCS8 3 . +.Bd -filled +.Ft int Fo (*priv_print) +.Fa "BIO *out" +.Fa "const EVP_PKEY *pkey" +.Fa "int indent" +.Fa "ASN1_PCTX *pctx" +.Fc +.Ed +.Pp +Print a private key in humanly readable text to +.Fa out , +indented +.Fa indent +spaces. +This method must return 0 on error and 1 on success. +It is called by +.Xr EVP_PKEY_print_private 3 . +.Bd -unfilled +.Ft int Fn (*pkey_size) "const EVP_PKEY *pk" +.Ed +.Pp +Returns the key size in bytes. +This method is called by +.Xr EVP_PKEY_size 3 . +.Bd -unfilled +.Ft int Fn (*pkey_bits) "const EVP_PKEY *pk" +.Ed +.Pp +Returns the key size in bits. +This method is called by +.Xr EVP_PKEY_bits 3 . +.Bd -filled +.Ft int Fo (*param_decode) +.Fa "EVP_PKEY *pkey" +.Fa "const unsigned char **pder" +.Fa "int derlen" +.Fc +.br +.Ft int Fo (*param_encode) +.Fa "const EVP_PKEY *pkey" +.Fa "unsigned char **pder" +.Fc +.Ed +.Pp +Decode and encode DER formatted parameters to and from +.Fa pk . +These methods must return 0 on error and 1 on success. +They are called by +.Fn PEM_read_bio_Parameters . +.Bd -unfilled +.Ft int Fn (*param_missing) "const EVP_PKEY *pk" +.Ed +.Pp +Return 0 if a key parameter is missing or 1 otherwise. +This method is called by +.Xr EVP_PKEY_missing_parameters 3 . +.Bd -unfilled +.Ft int Fn (*param_copy) "EVP_PKEY *to" "const EVP_PKEY *from" +.Ed +.Pp +Copy key parameters from +.Fa from +to +.Fa to . +This method must return 0 on error and 1 on success. +It is called by +.Xr EVP_PKEY_copy_parameters 3 . +.Bd -unfilled +.Ft int Fn (*param_cmp) "const EVP_PKEY *a" "const EVP_PKEY *b" +.Ed +.Pp +Compare the parameters of the keys +.Fa a +and +.Fa b . +This method must return 1 when the keys are equal, 0 when not equal, and a +negative number on error. +It is called by +.Xr EVP_PKEY_cmp_parameters 3 . +.Bd -filled +.Ft int Fo (*param_print) +.Fa "BIO *out" +.Fa "const EVP_PKEY *pkey" +.Fa "int indent" +.Fa "ASN1_PCTX *pctx" +.Fc +.Ed +.Pp +Print the private key parameters in humanly readable text to +.Fa out , +indented +.Fa indent +spaces. +This method must return 0 on error and 1 on success. +It is called by +.Xr EVP_PKEY_print_params 3 . +.Bd -unfilled +.Ft void Fn (*pkey_free) "EVP_PKEY *pkey" +.Ed +.Pp +Free the internals of +.Fa pkey . +This method is called by +.Xr EVP_PKEY_free 3 , +.Xr EVP_PKEY_set_type 3 , +.Xr EVP_PKEY_set_type_str 3 , +and +.Xr EVP_PKEY_assign 3 . +.Bd -filled +.Ft int Fo (*pkey_ctrl) +.Fa "EVP_PKEY *pkey" +.Fa "int op" +.Fa "long arg1" +.Fa "void *arg2" +.Fc +.Ed +.Pp +Add extra algorithm specific control. +.Pp +If the +.Fa op +argument is +.Dv ASN1_PKEY_CTRL_DEFAULT_MD_NID , +the +.Fa pkey_ctrl +method is supposed to write the message digest NID +for public key signature operations with the given +.Fa pkey +to +.Pf * Fa arg2 +as documented in the +.Xr EVP_PKEY_get_default_digest_nid 3 +manual page. +.Pp +The +.Fa pkey_ctrl +method is also called by +.Fn PKCS7_SIGNER_INFO_set , +.Fn PKCS7_RECIP_INFO_set , +and other functions. +.\" TODO: +.\" ASN1_PKEY_CTRL_CMS_ENVELOPE in cms_env.c rsa_ameth.c +.\" ASN1_PKEY_CTRL_CMS_RI_TYPE in cms_env.c dsa_ameth.c ec_ameth.c rsa_ameth.c +.\" ASN1_PKEY_CTRL_CMS_SIGN in cms_sd.c dsa_ameth.c ec_ameth.c rsa_ameth.c +.\" ASN1_PKEY_CTRL_PKCS7_ENCRYPT in pk7_lib.c rsa_ameth.c +.\" ASN1_PKEY_CTRL_PKCS7_SIGN in pk7_lib.c dsa_ameth.c ec_ameth.c rsa_ameth.c +.Bd -unfilled +.Ft int Fn (*pkey_check) "const EVP_PKEY *pk" +.Ft int Fn (*pkey_public_check) "const EVP_PKEY *pk" +.Ft int Fn (*pkey_param_check) "const EVP_PKEY *pk" +.Ed +.Pp +Check the validity of +.Fa pk +for key-pair, public component, and parameters, respectively. +These methods must return 0 for an invalid key or 1 for a valid key. +They are called by +.Xr EVP_PKEY_check 3 , +.Xr EVP_PKEY_public_check 3 , +and +.Xr EVP_PKEY_param_check 3 , +respectively. +.Bd -unfilled +.Ft int Fn (*pkey_security_bits) "const EVP_PKEY *pkey" +.Ed +.Pp +Return the security strength measured in bits of +.Fa pkey . +It is called by +.Xr EVP_PKEY_security_bits 3 . +.Ss Functions +.Fn EVP_PKEY_asn1_new +creates and returns a new +.Vt EVP_PKEY_ASN1_METHOD +object, marks it as dynamically allocated, and associates the given +.Fa id , +.Fa flags , +.Fa pem_str +and +.Fa info . +.Fa id +is a NID, +.Fa pem_str +is the PEM type string, +.Fa info +is a descriptive string. +If +.Dv ASN1_PKEY_SIGPARAM_NULL +is set in +.Fa flags , +the signature algorithm parameters are given the type +.Dv V_ASN1_NULL +by default, otherwise they will be given the type +.Dv V_ASN1_UNDEF +(i.e. the parameter is omitted). +See +.Xr X509_ALGOR_set0 3 +for more information. +.Pp +.Fn EVP_PKEY_asn1_copy +copies all function pointers from +.Fa src +to +.Fa dst . +The data in +.Fa dst +that can be set with +.Fn EVP_PKEY_asn1_new +\(em NIDs, flags, and strings \(em +remains unchanged. +This function is not thread safe, it is recommended to only use this when +initializing the application. +.Pp +.Fn EVP_PKEY_asn1_free +frees the dynamically allocated +.Fa ameth +including all memory it refers to. +If +.Fa ameth +is +.Dv NULL +of not marked as dynamically allocated, no action occurs. +.Pp +.Fn EVP_PKEY_asn1_add0 +adds +.Fa ameth +to the user defined stack of methods unless another +.Vt EVP_PKEY_ASN1_METHOD +with the same NID is already there. +This function is not thread safe, it is recommended to only use this when +initializing the application. +.Pp +.Fn EVP_PKEY_asn1_add_alias +creates an alias with the NID +.Fa to +for the +.Vt EVP_PKEY_ASN1_METHOD +with NID +.Fa from +unless another +.Vt EVP_PKEY_ASN1_METHOD +with the same NID is already added. +This function is not thread safe, it's recommended to only use this when +initializing the application. +.Pp +.Fn EVP_PKEY_asn1_set_public , +.Fn EVP_PKEY_asn1_set_private , +.Fn EVP_PKEY_asn1_set_param , +.Fn EVP_PKEY_asn1_set_free , +.Fn EVP_PKEY_asn1_set_ctrl , +.Fn EVP_PKEY_asn1_set_check , +.Fn EVP_PKEY_asn1_set_public_check , +.Fn EVP_PKEY_asn1_set_param_check , +and +.Fn EVP_PKEY_asn1_set_security_bits +set the diverse methods of the given +.Vt EVP_PKEY_ASN1_METHOD +object. +.Sh RETURN VALUES +.Fn EVP_PKEY_asn1_new +returns a pointer to the new +.Vt EVP_PKEY_ASN1_METHOD +object or +.Dv NULL +if memory allocation fails. +.Pp +.Fn EVP_PKEY_asn1_add0 +and +.Fn EVP_PKEY_asn1_add_alias +return 0 on error or 1 on success. +.Sh SEE ALSO +.Xr EVP_PKEY_asn1_get_count 3 , +.Xr EVP_PKEY_new 3 , +.Xr X509_PUBKEY_new 3 +.Sh HISTORY +.Fn EVP_PKEY_asn1_new , +.Fn EVP_PKEY_asn1_copy , +.Fn EVP_PKEY_asn1_free , +.Fn EVP_PKEY_asn1_add0 , +.Fn EVP_PKEY_asn1_add_alias , +.Fn EVP_PKEY_asn1_set_public , +.Fn EVP_PKEY_asn1_set_private , +.Fn EVP_PKEY_asn1_set_param , +.Fn EVP_PKEY_asn1_set_free , +and +.Fn EVP_PKEY_asn1_set_ctrl +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn EVP_PKEY_asn1_set_check , +.Fn EVP_PKEY_asn1_set_public_check , +and +.Fn EVP_PKEY_asn1_set_param_check +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.1 . +.Pp +.Fn EVP_PKEY_asn1_set_security_bits +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.2 . diff --git a/Libraries/libressl/man/EVP_PKEY_check.3 b/Libraries/libressl/man/EVP_PKEY_check.3 new file mode 100644 index 000000000..5a78e3512 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_check.3 @@ -0,0 +1,149 @@ +.\" $OpenBSD: EVP_PKEY_check.3,v 1.2 2022/07/14 14:49:09 tb Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 14 2022 $ +.Dt EVP_PKEY_CHECK 3 +.Os +.Sh NAME +.Nm EVP_PKEY_check , +.Nm EVP_PKEY_public_check , +.Nm EVP_PKEY_param_check +.Nd key and parameter check functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fn EVP_PKEY_check "EVP_PKEY_CTX *ctx" +.Ft int +.Fn EVP_PKEY_public_check "EVP_PKEY_CTX *ctx" +.Ft int +.Fn EVP_PKEY_param_check "EVP_PKEY_CTX *ctx" +.Sh DESCRIPTION +.Fn EVP_PKEY_check +performs various sanity checks on the key contained in +.Fa ctx +but only supports a small number of key types by default. +It preferably uses the function +.Fa check +configured for +.Fa ctx +with +.Xr EVP_PKEY_meth_set_check 3 . +It falls back to the function +.Fa pkey_check +configured for the private key contained in +.Fa ctx +with +.Xr EVP_PKEY_asn1_set_check 3 . +If that wasn't configured either, it attempts to use the following +check functions: +.Pp +.Bl -tag -width 3n -compact -offset -indent +.It DH +not supported, return value \-2 +.It EC +.Xr EC_KEY_check_key 3 +.It RSA +.Xr RSA_check_key 3 +.El +.Pp +.Fn EVP_PKEY_public_check +performs various sanity checks on the public key contained in +.Fa ctx +but only supports a small number of key types by default. +It preferably uses the function +.Fa public_check +configured for +.Fa ctx +with +.Xr EVP_PKEY_meth_set_public_check 3 . +It falls back to the function +.Fa pkey_public_check +configured for the private key contained in +.Fa ctx +with +.Xr EVP_PKEY_asn1_set_public_check 3 . +If that wasn't configured either, it attempts to use the following +check functions: +.Pp +.Bl -tag -width 3n -compact -offset -indent +.It DH +.Xr DH_check_pub_key 3 +.It EC +.Xr EC_KEY_check_key 3 +.It RSA +not supported, return value \-2 +.El +.Pp +.Fn EVP_PKEY_param_check +performs various sanity checks on the key parameters contained in +.Fa ctx +but only supports a small number of key types by default. +It preferably uses the function +.Fa check +configured for +.Fa ctx +with +.Xr EVP_PKEY_meth_set_param_check 3 . +It falls back to the function +.Fa pkey_check +configured for the private key contained in +.Fa ctx +with +.Xr EVP_PKEY_asn1_set_param_check 3 . +If that wasn't configured either, it attempts to use the following +check functions: +.Pp +.Bl -tag -width 3n -compact -offset -indent +.It DH +.Xr DH_check 3 +.It EC +.Xr EC_GROUP_check 3 +.It RSA +not supported, return value \-2 +.El +.Sh RETURN VALUES +These functions return 1 if the check was performed and no problem +was found, 0 if a problem was found or if the check could not be +performed, for example because +.Fa ctx +does not contain an +.Vt EVP_PKEY +object, or \-2 if the required check function is neither configured for +.Fa ctx +nor for the +.Vt PKEY +contained therein, and the check in question is not supported by default +for the algorithm in question either. +.Sh SEE ALSO +.Xr DH_check 3 , +.Xr EC_GROUP_check 3 , +.Xr EC_KEY_new 3 , +.Xr EVP_PKEY_asn1_new 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_meth_new 3 , +.Xr EVP_PKEY_new 3 , +.Xr RSA_check_key 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.1 . +.Sh BUGS +For EC keys, +.Fn EVP_PKEY_public_check +also checks the +.Em private +key and fails if there is a problem with any of the private +components, even if no problem is found with the public key. diff --git a/Libraries/libressl/man/EVP_PKEY_cmp.3 b/Libraries/libressl/man/EVP_PKEY_cmp.3 new file mode 100644 index 000000000..42bfb6fec --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_cmp.3 @@ -0,0 +1,180 @@ +.\" $OpenBSD: EVP_PKEY_cmp.3,v 1.13 2023/09/08 11:37:58 schwarze Exp $ +.\" full merge up to: OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" selective merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2013, 2014, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 8 2023 $ +.Dt EVP_PKEY_CMP 3 +.Os +.Sh NAME +.Nm EVP_PKEY_missing_parameters , +.Nm EVP_PKEY_copy_parameters , +.Nm EVP_PKEY_cmp_parameters , +.Nm EVP_PKEY_cmp +.\" .Nm EVP_PKEY_save_parameters is intentionally undocumented +.\" because nothing uses it according to codesearch.debian.net +.\" and it only affects X509_PUBKEY_set(3) for DSA and GOST2001 keys, +.\" resulting in incomplete output without the public key parameters. +.Nd public key parameter and comparison functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_missing_parameters +.Fa "const EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_copy_parameters +.Fa "EVP_PKEY *destination" +.Fa "const EVP_PKEY *source" +.Fc +.Ft int +.Fo EVP_PKEY_cmp_parameters +.Fa "const EVP_PKEY *a" +.Fa "const EVP_PKEY *b" +.Fc +.Ft int +.Fo EVP_PKEY_cmp +.Fa "const EVP_PKEY *a" +.Fa "const EVP_PKEY *b" +.Fc +.Sh DESCRIPTION +.Fn EVP_PKEY_missing_parameters +checks whether any public key parameters are missing from +.Fa pkey . +.Pp +.Fn EVP_PKEY_copy_parameters +copies all public key parameters from the +.Fa source +to the +.Fa destination . +If the algorithm does not use parameters, no action occurs. +.Pp +.Fn EVP_PKEY_cmp_parameters +compares the public key parameters of +.Fa a +and +.Fa b . +This is only supported for algorithms that use parameters. +.Pp +.Fn EVP_PKEY_cmp +compares the public key components of +.Fa a +and +.Fa b . +If the algorithm uses public key parameters, +it also compares the parameters. +.Pp +The main purpose of the functions +.Fn EVP_PKEY_missing_parameters +and +.Fn EVP_PKEY_copy_parameters +is to handle public keys in certificates where the parameters are +sometimes omitted from a public key if they are inherited from the CA +that signed it. +.Pp +Since OpenSSL private keys contain public key components too, the +function +.Fn EVP_PKEY_cmp +can also be used to determine if a private key matches a public key. +.Sh RETURN VALUES +.Fn EVP_PKEY_missing_parameters +returns 1 if the public key parameters of +.Fa pkey +are missing or incomplete or 0 if they are present and complete +or if the algorithm doesn't use parameters. +.Pp +.Fn EVP_PKEY_copy_parameters +returns 1 for success or 0 for failure. +In particular, it fails if the key types mismatch or if the public +key parameters in the +.Fa source +are missing or incomplete. +.Pp +.Fn EVP_PKEY_cmp_parameters +and +.Fn EVP_PKEY_cmp +return 1 if the keys match, 0 if they don't match, -1 if the key types +are different and -2 if the operation is not supported. +.Sh SEE ALSO +.Xr EVP_PKEY_asn1_set_public 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_keygen 3 , +.Xr EVP_PKEY_new 3 , +.Xr X509_get_pubkey_parameters 3 +.Sh HISTORY +.Fn EVP_PKEY_missing_parameters +and +.Fn EVP_PKEY_copy_parameters +first appeared in SSLeay 0.8.0. +.Fn EVP_PKEY_cmp_parameters +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_PKEY_cmp +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/EVP_PKEY_decrypt.3 b/Libraries/libressl/man/EVP_PKEY_decrypt.3 new file mode 100644 index 000000000..af5ed93fb --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_decrypt.3 @@ -0,0 +1,177 @@ +.\" $OpenBSD: EVP_PKEY_decrypt.3,v 1.8 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: OpenSSL 48e5119a Jan 19 10:49:22 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2013, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt EVP_PKEY_DECRYPT 3 +.Os +.Sh NAME +.Nm EVP_PKEY_decrypt_init , +.Nm EVP_PKEY_decrypt +.Nd decrypt using a public key algorithm +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_decrypt_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_decrypt +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *out" +.Fa "size_t *outlen" +.Fa "const unsigned char *in" +.Fa "size_t inlen" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_decrypt_init +function initializes a public key algorithm context using key +.Fa ctx->pkey +for a decryption operation. +.Pp +The +.Fn EVP_PKEY_decrypt +function performs a public key decryption operation using +.Fa ctx . +The data to be decrypted is specified using the +.Fa in +and +.Fa inlen +parameters. +If +.Fa out +is +.Dv NULL +then the maximum size of the output buffer is written to the +.Fa outlen +parameter. +If +.Fa out +is not +.Dv NULL +then before the call the +.Fa outlen +parameter should contain the length of the +.Fa out +buffer. +If the call is successful, the decrypted data is written to +.Fa out +and the amount of data written to +.Fa outlen . +.Pp +After the call to +.Fn EVP_PKEY_decrypt_init , +algorithm specific control operations can be performed to set any +appropriate parameters for the operation. +.Pp +The function +.Fn EVP_PKEY_decrypt +can be called more than once on the same context if several operations +are performed using the same parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_decrypt_init +and +.Fn EVP_PKEY_decrypt +return 1 for success and 0 or a negative value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh EXAMPLES +Decrypt data using OAEP (for RSA keys): +.Bd -literal -offset indent +#include +#include + +EVP_PKEY_CTX *ctx; +ENGINE *eng; +unsigned char *out, *in; +size_t outlen, inlen; +EVP_PKEY *key; + +/* + * Assumes that key, eng, in, and inlen are already set up + * and that key is an RSA private key. + */ +ctx = EVP_PKEY_CTX_new(key, eng); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_decrypt_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) + /* Error */ + +/* Determine buffer length */ +if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0) + /* Error */ + +out = malloc(outlen); + +if (!out) + /* malloc failure */ + +if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0) + /* Error */ + +/* Decrypted data is outlen bytes written to buffer out */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_meth_set_decrypt 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 +.Sh HISTORY +.Fn EVP_PKEY_decrypt_init +and +.Fn EVP_PKEY_decrypt +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_derive.3 b/Libraries/libressl/man/EVP_PKEY_derive.3 new file mode 100644 index 000000000..c82018341 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_derive.3 @@ -0,0 +1,257 @@ +.\" $OpenBSD: EVP_PKEY_derive.3,v 1.9 2023/09/09 14:26:35 schwarze Exp $ +.\" full merge up to: OpenSSL 48e5119a Jan 19 10:49:22 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2013, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 9 2023 $ +.Dt EVP_PKEY_DERIVE 3 +.Os +.Sh NAME +.Nm EVP_PKEY_derive_init , +.Nm EVP_PKEY_derive_set_peer , +.Nm EVP_PKEY_CTX_get0_peerkey , +.Nm EVP_PKEY_derive +.Nd derive public key algorithm shared secret +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_derive_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_derive_set_peer +.Fa "EVP_PKEY_CTX *ctx" +.Fa "EVP_PKEY *peerkey" +.Fc +.Ft EVP_PKEY * +.Fo EVP_PKEY_CTX_get0_peerkey +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_derive +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *key" +.Fa "size_t *keylen" +.Fc +.Sh DESCRIPTION +.Fn EVP_PKEY_derive_init +initializes the public key algorithm context +.Fa ctx +for shared secret derivation using the +.Vt EVP_PKEY +object already stored in +.Fa ctx . +The library provides built-in support for keys with an +.Xr EVP_PKEY_base_id 3 +of +.Dv EVP_PKEY_DH , +.Dv EVP_PKEY_EC , +.Dv EVP_PKEY_GOSTR01 , +.Dv EVP_PKEY_HKDF , +and +.Dv EVP_PKEY_X25519 . +.Pp +After the call to +.Fn EVP_PKEY_derive_init , +algorithm specific control operations can optionally be performed +to set any appropriate parameters for the operation. +.Pp +.Fn EVP_PKEY_derive_set_peer +configures the +.Fa ctx , +which already needs to be initialized with +.Fn EVP_PKEY_derive_init , +.Xr EVP_PKEY_encrypt_init 3 , +or +.Xr EVP_PKEY_decrypt_init 3 , +to use the +.Fa peerkey , +which is normally a public key. +In case of success, the reference count of the +.Fa peerkey +is incremented by one. +Consequently, the caller needs to call +.Xr EVP_PKEY_free 3 +on the +.Fa peerkey +when the caller no longer needs it, even if it is still in use by +.Fa ctx . +.Pp +.Fn EVP_PKEY_derive +derives a shared secret using +.Fa ctx . +If +.Fa key +is +.Dv NULL , +then the maximum size of the output buffer is written to the +.Fa keylen +parameter. +If +.Fa key +is not +.Dv NULL +then before the call the +.Fa keylen +parameter should contain the length of the +.Fa key +buffer. +If the call is successful, the shared secret is written to +.Fa key +and the amount of data written to +.Fa keylen . +.Pp +The function +.Fn EVP_PKEY_derive +can be called more than once on the same context if several operations +are performed using the same parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_derive_init , +.Fn EVP_PKEY_derive_set_peer , +and +.Fn EVP_PKEY_derive +return 1 for success and 0 or a negative value for failure. +In particular, a return value of \-2 indicates the operation is not +supported by the public key algorithm. +.Pp +For +.Fn EVP_PKEY_derive_set_peer , +a return value of \-1 can for example occur if +.Fa ctx +is not properly initialized, does not contain an +.Vt EVP_PKEY +that can be retrieved with +.Xr EVP_PKEY_CTX_get0_pkey 3 , +the +.Xr EVP_PKEY_id 3 +of both keys mismatch, or +.Xr EVP_PKEY_cmp_parameters 3 +reports mismatching key parameters. +.Pp +.Fn EVP_PKEY_derive +fails with a return value of \-1 for example if +.Fa ctx +has not been successfully initialized with +.Fn EVP_PKEY_derive_init . +.Pp +.Fn EVP_PKEY_CTX_get0_peerkey +returns an internal pointer to the +.Fa peerkey +used by +.Fa ctx +without incrementing its reference count. +.Sh EXAMPLES +Derive shared secret (for example DH or EC keys): +.Bd -literal -offset indent +#include +#include + +EVP_PKEY_CTX *ctx; +ENGINE *eng; +unsigned char *skey; +size_t skeylen; +EVP_PKEY *pkey, *peerkey; + +/* Assumes that pkey, eng, and peerkey have already been set up. */ +ctx = EVP_PKEY_CTX_new(pkey, eng); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_derive_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0) + /* Error */ + +/* Determine buffer length */ +if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0) + /* Error */ + +skey = malloc(skeylen); + +if (!skey) + /* malloc failure */ + +if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0) + /* Error */ + +/* Shared secret is skey bytes written to buffer skey */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_meth_set_derive 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 , +.Xr X25519 3 +.Sh HISTORY +.Fn EVP_PKEY_derive_init , +.Fn EVP_PKEY_derive_set_peer , +.Fn EVP_PKEY_CTX_get0_peerkey , +and +.Fn EVP_PKEY_derive +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_encrypt.3 b/Libraries/libressl/man/EVP_PKEY_encrypt.3 new file mode 100644 index 000000000..a13594b5e --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_encrypt.3 @@ -0,0 +1,186 @@ +.\" $OpenBSD: EVP_PKEY_encrypt.3,v 1.8 2023/05/14 09:29:37 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2013, 2014, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 14 2023 $ +.Dt EVP_PKEY_ENCRYPT 3 +.Os +.Sh NAME +.Nm EVP_PKEY_encrypt_init , +.Nm EVP_PKEY_encrypt +.Nd encrypt using a public key algorithm +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_encrypt_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_encrypt +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *out" +.Fa "size_t *outlen" +.Fa "const unsigned char *in" +.Fa "size_t inlen" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_encrypt_init +function initializes a public key algorithm context using key +.Fa ctx->pkey +for an encryption operation. +.Pp +The +.Fn EVP_PKEY_encrypt +function performs a public key encryption operation using +.Fa ctx . +The data to be encrypted is specified using the +.Fa in +and +.Fa inlen +parameters. +If +.Fa out +is +.Dv NULL , +then the maximum size of the output buffer is written to the +.Fa outlen +parameter. +If +.Fa out +is not +.Dv NULL , +then before the call the +.Fa outlen +parameter should contain the length of the +.Fa out +buffer. +If the call is successful, the encrypted data is written to +.Fa out +and the amount of data written to +.Fa outlen . +.Pp +After the call to +.Fn EVP_PKEY_encrypt_init , +algorithm specific control operations can be performed to set any +appropriate parameters for the operation. +.Pp +The function +.Fn EVP_PKEY_encrypt +can be called more than once on the same context if several operations +are performed using the same parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_encrypt_init +and +.Fn EVP_PKEY_encrypt +return 1 for success and 0 or a negative value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh EXAMPLES +Encrypt data using OAEP (for RSA keys). +See also +.Xr PEM_read_PUBKEY 3 +and +.Xr d2i_X509 3 +for means to load a public key. +You may also simply set +.Dq eng +to +.Dv NULL +to start with the default OpenSSL RSA implementation: +.Bd -literal -offset indent +#include +#include +#include + +EVP_PKEY_CTX *ctx; +ENGINE *eng; +unsigned char *out, *in; +size_t outlen, inlen; +EVP_PKEY *key; +/* NB: assumes eng, key in, inlen are already set up + * and that key is an RSA public key + */ +ctx = EVP_PKEY_CTX_new(key, eng); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_encrypt_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) + /* Error */ + +/* Determine buffer length */ +if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0) + /* Error */ + +out = malloc(outlen); + +if (!out) + /* malloc failure */ + +if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0) + /* Error */ + +/* Encrypted data is outlen bytes written to buffer out */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_meth_set_encrypt 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 +.Sh HISTORY +.Fn EVP_PKEY_encrypt_init +and +.Fn EVP_PKEY_encrypt +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_get_default_digest_nid.3 b/Libraries/libressl/man/EVP_PKEY_get_default_digest_nid.3 new file mode 100644 index 000000000..bef39987a --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_get_default_digest_nid.3 @@ -0,0 +1,131 @@ +.\" $OpenBSD: EVP_PKEY_get_default_digest_nid.3,v 1.7 2023/09/13 14:57:21 schwarze Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2013, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 13 2023 $ +.Dt EVP_PKEY_GET_DEFAULT_DIGEST_NID 3 +.Os +.Sh NAME +.Nm EVP_PKEY_get_default_digest_nid +.Nd get default signature digest +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_get_default_digest_nid +.Fa "EVP_PKEY *pkey" +.Fa "int *pnid" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_get_default_digest_nid +function sets +.Pf * Fa pnid +to the default message digest NID for the public key signature +operations associated with +.Fa pkey . +.Pp +Some signature algorithms, for example +.Dv EVP_PKEY_ED25519 , +do not use a digest during signing. +In this case, +.Pf * Fa pnid +is set to +.Dv NID_undef . +.Pp +Support for the following public key algorithms is built into the library: +.Pp +.Bl -column -compact EVP_PKEY_base_id(3) NID_id_Gost28147_89_MAC mandatory +.It Xr EVP_PKEY_base_id 3 Ta Pf * Fa pnid Ta return value +.It Dv EVP_PKEY_DSA Ta Dv NID_sha1 Ta mandatory +.It Dv EVP_PKEY_EC Ta Dv NID_sha1 Ta mandatory +.It Dv EVP_PKEY_ED25519 Ta Dv NID_undef Ta mandatory +.It Dv EVP_PKEY_GOSTIMIT Ta Dv NID_id_Gost28147_89_MAC Ta mandatory +.It Dv EVP_PKEY_GOSTR01 Ta variable Ta mandatory +.It Dv EVP_PKEY_HMAC Ta Dv NID_sha1 Ta advisory +.It Dv EVP_PKEY_RSA Ta Dv NID_sha256 Ta advisory +.El +.Sh RETURN VALUES +The +.Fn EVP_PKEY_get_default_digest_nid +function returns 1 if the message digest is advisory (that is other +digests can be used) and 2 if it is mandatory (other digests cannot be +used). +It returns 0 or a negative value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh SEE ALSO +.Xr EVP_PKEY_asn1_set_ctrl 3 , +.Xr EVP_PKEY_CTX_ctrl 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_new 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 +.Sh HISTORY +.Fn EVP_PKEY_get_default_digest_nid +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_keygen.3 b/Libraries/libressl/man/EVP_PKEY_keygen.3 new file mode 100644 index 000000000..e86c04984 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_keygen.3 @@ -0,0 +1,344 @@ +.\" $OpenBSD: EVP_PKEY_keygen.3,v 1.13 2023/09/10 04:05:26 jsg Exp $ +.\" full merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2013, 2015, 2016, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2023 $ +.Dt EVP_PKEY_KEYGEN 3 +.Os +.Sh NAME +.Nm EVP_PKEY_keygen_init , +.Nm EVP_PKEY_keygen , +.Nm EVP_PKEY_paramgen_init , +.Nm EVP_PKEY_paramgen , +.Nm EVP_PKEY_gen_cb , +.Nm EVP_PKEY_CTX_set_cb , +.Nm EVP_PKEY_CTX_get_cb , +.Nm EVP_PKEY_CTX_set0_keygen_info , +.Nm EVP_PKEY_CTX_get_keygen_info , +.Nm EVP_PKEY_CTX_set_app_data , +.Nm EVP_PKEY_CTX_get_app_data +.Nd key and parameter generation functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_keygen_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_keygen +.Fa "EVP_PKEY_CTX *ctx" +.Fa "EVP_PKEY **ppkey" +.Fc +.Ft int +.Fo EVP_PKEY_paramgen_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_paramgen +.Fa "EVP_PKEY_CTX *ctx" +.Fa "EVP_PKEY **ppkey" +.Fc +.Ft typedef int +.Fo EVP_PKEY_gen_cb +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft void +.Fo EVP_PKEY_CTX_set_cb +.Fa "EVP_PKEY_CTX *ctx" +.Fa "EVP_PKEY_gen_cb *cb" +.Fc +.Ft EVP_PKEY_gen_cb * +.Fo EVP_PKEY_CTX_get_cb +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft void +.Fo EVP_PKEY_CTX_set0_keygen_info +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int *dat" +.Fa "int datlen" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_keygen_info +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int idx" +.Fc +.Ft void +.Fo EVP_PKEY_CTX_set_app_data +.Fa "EVP_PKEY_CTX *ctx" +.Fa "void *data" +.Fc +.Ft void * +.Fo EVP_PKEY_CTX_get_app_data +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_keygen_init +function initializes a public key algorithm context using key +.Fa ctx->pkey +for a key generation operation. +.Pp +The +.Fn EVP_PKEY_keygen +function performs a key generation operation. +The generated key is written to +.Fa ppkey . +.Pp +The functions +.Fn EVP_PKEY_paramgen_init +and +.Fn EVP_PKEY_paramgen +are similar except parameters are generated. +.Pp +The functions +.Fn EVP_PKEY_CTX_set_cb +and +.Fn EVP_PKEY_CTX_get_cb +set and retrieve the key or parameter generation callback, respectively. +.Pp +The function +.Fn EVP_PKEY_CTX_set0_keygen_info +sets the parameters associated with the generation operation to the array +.Fa dat +containing +.Ft datlen +integer parameters. +The caller retains ownership of the +.Fa dat +array; it will never be freed by the library. +.Pp +The function +.Fn EVP_PKEY_CTX_get_keygen_info +returns parameters associated with the generation operation. +If +.Fa idx +is -1, the total number of parameters available is returned. +Any non-negative value returns the value of that parameter. +.Fn EVP_PKEY_CTX_get_keygen_info +with a non-negative value for +.Fa idx +should only be called within the generation callback. +.Pp +If the callback returns 0, then the key generation operation is aborted +and an error occurs. +This might occur during a time consuming operation where a user clicks +on a "cancel" button. +.Pp +The functions +.Fn EVP_PKEY_CTX_set_app_data +and +.Fn EVP_PKEY_CTX_get_app_data +set and retrieve an opaque pointer. +This can be used to set some application defined value which can be +retrieved in the callback: for example a handle which is used to update +a "progress dialog". +.Pp +After the call to +.Fn EVP_PKEY_keygen_init +or +.Fn EVP_PKEY_paramgen_init , +algorithm specific control operations can be performed to set any +appropriate parameters for the operation. +.Pp +The functions +.Fn EVP_PKEY_keygen +and +.Fn EVP_PKEY_paramgen +can be called more than once on the same context if several operations +are performed using the same parameters. +.Pp +The meaning of the parameters passed to the callback will depend on the +algorithm and the specific implementation of the algorithm. +Some might not give any useful information at all during key or +parameter generation. +Others might not even call the callback. +.Pp +The operation performed by key or parameter generation depends on the +algorithm used. +In some cases (e.g. EC with a supplied named curve) the "generation" +option merely sets the appropriate fields in an +.Vt EVP_PKEY +structure. +.Pp +In OpenSSL, an +.Vt EVP_PKEY +structure containing a private key also contains the public key +components and parameters (if any). +An OpenSSL private key is equivalent to what some libraries call a "key +pair". +A private key can be used in functions which require the use of a public +key or parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_keygen_init , +.Fn EVP_PKEY_paramgen_init , +.Fn EVP_PKEY_keygen , +and +.Fn EVP_PKEY_paramgen +return 1 for success and 0 or a negative value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Pp +Callback functions of the type +.Fn EVP_PKEY_gen_cb +are supposed to return 1 on success or 0 on error. +.Pp +.Fn EVP_PKEY_CTX_get_cb +returns a function pointer to the currently installed callback function or +.Dv NULL +if no callback function is installed. +.Pp +.Fn EVP_PKEY_CTX_get_keygen_info +returns the number of available parameters if +.Fa idx +is \-1, one of these parameters if +.Fa idx +is greater than or equal to zero but less than the number +of available parameters, or 0 otherwise. +.Sh EXAMPLES +Generate a 2048-bit RSA key: +.Bd -literal -offset indent +#include +#include + +EVP_PKEY_CTX *ctx; +EVP_PKEY *pkey = NULL; + +ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_keygen_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) + /* Error */ + +/* Generate key */ +if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + /* Error */ +.Ed +.Pp +Generate a key from a set of parameters: +.Bd -literal -offset indent +#include +#include + +EVP_PKEY_CTX *ctx; +ENGINE *eng; +EVP_PKEY *pkey = NULL, *param; + +/* Assumes that param and eng are already set up. */ +ctx = EVP_PKEY_CTX_new(param, eng); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_keygen_init(ctx) <= 0) + /* Error */ + +/* Generate key */ +if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + /* Error */ +.Ed +.Pp +Example of generation callback for OpenSSL public key implementations: +.Bd -literal -offset indent +/* Application data is a BIO to output status to */ + +EVP_PKEY_CTX_set_app_data(ctx, status_bio); + +static int +genpkey_cb(EVP_PKEY_CTX *ctx) +{ + char c = '*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p; + + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\en'; + BIO_write(b, &c, 1); + (void)BIO_flush(b); + return 1; +} +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_meth_set_keygen 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 , +.Xr X25519 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_meth_get0_info.3 b/Libraries/libressl/man/EVP_PKEY_meth_get0_info.3 new file mode 100644 index 000000000..acfb035bb --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_meth_get0_info.3 @@ -0,0 +1,78 @@ +.\" $OpenBSD: EVP_PKEY_meth_get0_info.3,v 1.3 2019/06/06 01:06:58 schwarze Exp $ +.\" OpenSSL EVP_PKEY_meth_get_count.pod 6a2da303 Aug 9 11:25:19 2017 -0400 +.\" OpenSSL EVP_PKEY_meth_get_count.pod 48ed9c23 Jul 25 17:48:26 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt EVP_PKEY_METH_GET0_INFO 3 +.Os +.Sh NAME +.Nm EVP_PKEY_meth_get0_info +.Nd enumerate public key methods +.Sh SYNOPSIS +.In openssl/evp.h +.Ft void +.Fo EVP_PKEY_meth_get0_info +.Fa "int *ppkey_id" +.Fa "int *pflags" +.Fa "const EVP_PKEY_METHOD *meth" +.Fc +.Sh DESCRIPTION +The function +.Fn EVP_PKEY_meth_get0_info +retrieves the public key ID (a NID) and any flags associated with the +public key method +.Pf * Fa meth . +.Sh SEE ALSO +.Xr EVP_PKEY_meth_new 3 , +.Xr EVP_PKEY_new 3 +.Sh HISTORY +.Fn EVP_PKEY_meth_get0_info +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/EVP_PKEY_meth_new.3 b/Libraries/libressl/man/EVP_PKEY_meth_new.3 new file mode 100644 index 000000000..5ec0b1210 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_meth_new.3 @@ -0,0 +1,647 @@ +.\" $OpenBSD: EVP_PKEY_meth_new.3,v 1.6 2023/09/09 14:35:23 schwarze Exp $ +.\" selective merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Paul Yang . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 9 2023 $ +.Dt EVP_PKEY_METH_NEW 3 +.Os +.Sh NAME +.Nm EVP_PKEY_meth_new , +.Nm EVP_PKEY_meth_free , +.Nm EVP_PKEY_meth_copy , +.Nm EVP_PKEY_meth_find , +.Nm EVP_PKEY_meth_add0 , +.Nm EVP_PKEY_meth_set_init , +.Nm EVP_PKEY_meth_set_copy , +.Nm EVP_PKEY_meth_set_cleanup , +.Nm EVP_PKEY_meth_set_paramgen , +.Nm EVP_PKEY_meth_set_keygen , +.Nm EVP_PKEY_meth_set_sign , +.Nm EVP_PKEY_meth_set_verify , +.Nm EVP_PKEY_meth_set_verify_recover , +.Nm EVP_PKEY_meth_set_signctx , +.Nm EVP_PKEY_meth_set_verifyctx , +.Nm EVP_PKEY_meth_set_encrypt , +.Nm EVP_PKEY_meth_set_decrypt , +.Nm EVP_PKEY_meth_set_derive , +.Nm EVP_PKEY_meth_set_ctrl , +.Nm EVP_PKEY_meth_set_check , +.Nm EVP_PKEY_meth_set_public_check , +.Nm EVP_PKEY_meth_set_param_check , +.Nm EVP_PKEY_CTX_get_data , +.Nm EVP_PKEY_CTX_set_data +.Nd manipulate an EVP_PKEY_METHOD structure +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_PKEY_METHOD * +.Fo EVP_PKEY_meth_new +.Fa "int id" +.Fa "int flags" +.Fc +.Ft void +.Fo EVP_PKEY_meth_free +.Fa "EVP_PKEY_METHOD *pmeth" +.Fc +.Ft void +.Fo EVP_PKEY_meth_copy +.Fa "EVP_PKEY_METHOD *dst" +.Fa "const EVP_PKEY_METHOD *src" +.Fc +.Ft const EVP_PKEY_METHOD * +.Fo EVP_PKEY_meth_find +.Fa "int type" +.Fc +.Ft int +.Fo EVP_PKEY_meth_add0 +.Fa "const EVP_PKEY_METHOD *pmeth" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_init +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*init)(EVP_PKEY_CTX *ctx)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_copy +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_cleanup +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "void (*cleanup)(EVP_PKEY_CTX *ctx)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_paramgen +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*paramgen_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_keygen +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*keygen_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_sign +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*sign_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,\ + const unsigned char *tbs, size_t tbslen)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_verify +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*verify_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig,\ + size_t siglen, const unsigned char *tbs, size_t tbslen)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_verify_recover +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*verify_recover_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*verify_recover)(EVP_PKEY_CTX *ctx, unsigned char *sig,\ + size_t *siglen, const unsigned char *tbs, size_t tbslen)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_signctx +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)" +.Fa "int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig,\ + size_t *siglen, EVP_MD_CTX *mctx)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_verifyctx +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)" +.Fa "int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,\ + int siglen, EVP_MD_CTX *mctx)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_encrypt +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*encrypt_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out,\ + size_t *outlen, const unsigned char *in, size_t inlen)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_decrypt +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*decrypt_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out,\ + size_t *outlen, const unsigned char *in, size_t inlen)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_derive +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*derive_init)(EVP_PKEY_CTX *ctx)" +.Fa "int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_ctrl +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)" +.Fa "int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_check +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*check)(EVP_PKEY *pkey)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_public_check +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*public_check)(EVP_PKEY *pkey)" +.Fc +.Ft void +.Fo EVP_PKEY_meth_set_param_check +.Fa "EVP_PKEY_METHOD *pmeth" +.Fa "int (*param_check)(EVP_PKEY *pkey)" +.Fc +.Ft void * +.Fo EVP_PKEY_CTX_get_data +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft void +.Fo EVP_PKEY_CTX_set_data +.Fa "EVP_PKEY_CTX *ctx" +.Fa "void *data" +.Fc +.Sh DESCRIPTION +The +.Vt EVP_PKEY_METHOD +structure holds a set of methods +for a specific public key cryptographic algorithm. +Those methods perform tasks such as generating keys, signing, verifying, +encrypting, decrypting, and so on. +.Pp +There are two places where the +.Vt EVP_PKEY_METHOD +objects are stored: one is a built-in static array representing the +standard methods for different algorithms, and the other one is a stack +of user-defined application-specific methods, which can be manipulated +with +.Fn EVP_PKEY_meth_add0 . +.Pp +The +.Vt EVP_PKEY_METHOD +objects are usually referenced by +.Vt EVP_PKEY_CTX +objects. +.Ss Methods +The methods implement the particular public key algorithm represented by the +.Vt EVP_PKEY_CTX +object. +.Bd -unfilled +.Ft int Fn (*init) "EVP_PKEY_CTX *ctx" +.Ft int Fn (*copy) "EVP_PKEY_CTX *dst" "EVP_PKEY_CTX *src" +.Ft void Fn (*cleanup) "EVP_PKEY_CTX *ctx" +.Ed +.Pp +The +.Fn init +method is called by +.Xr EVP_PKEY_CTX_new 3 +and +.Xr EVP_PKEY_CTX_new_id 3 +to initialize the algorithm-specific data when a new +.Vt EVP_PKEY_CTX +is created. +The +.Fn cleanup +method is called by +.Xr EVP_PKEY_CTX_free 3 +when an +.Vt EVP_PKEY_CTX +is freed. +The +.Fn copy +method is called by +.Xr EVP_PKEY_CTX_dup 3 +when an +.Vt EVP_PKEY_CTX +is duplicated. +.Bd -unfilled +.Ft int Fn (*paramgen_init) "EVP_PKEY_CTX *ctx" +.Ft int Fn (*paramgen) "EVP_PKEY_CTX *ctx" "EVP_PKEY *pkey" +.Ed +.Pp +The +.Fn paramgen_init +and +.Fn paramgen +methods deal with key parameter generation. +They are called by +.Xr EVP_PKEY_paramgen_init 3 +and +.Xr EVP_PKEY_paramgen 3 +to handle the parameter generation process. +.Bd -unfilled +.Ft int Fn (*keygen_init) "EVP_PKEY_CTX *ctx" +.Ft int Fn (*keygen) "EVP_PKEY_CTX *ctx" "EVP_PKEY *pkey" +.Ed +.Pp +The +.Fn keygen_init +and +.Fn keygen +methods are used to generate a key for the specified algorithm. +They are called by +.Xr EVP_PKEY_keygen_init 3 +and +.Xr EVP_PKEY_keygen 3 . +.Bd -unfilled +.Ft int Fn (*sign_init) "EVP_PKEY_CTX *ctx" +.Ft int Fo (*sign) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *sig" +.Fa "size_t *siglen" +.Fa "const unsigned char *tbs" +.Fa "size_t tbslen" +.Fc +.Ed +.Pp +The +.Fn sign_init +and +.Fn sign +methods are used to generate the signature of a piece of data using a +private key. +They are called by +.Xr EVP_PKEY_sign_init 3 +and +.Xr EVP_PKEY_sign 3 . +.Bd -unfilled +.Ft int Fn (*verify_init) "EVP_PKEY_CTX *ctx" +.Ft int Fo (*verify) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const unsigned char *sig" +.Fa "size_t siglen" +.Fa "const unsigned char *tbs" +.Fa "size_t tbslen" +.Fc +.Ed +.Pp +The +.Fn verify_init +and +.Fn verify +methods are used to verify whether a signature is valid. +They are called by +.Xr EVP_PKEY_verify_init 3 +and +.Xr EVP_PKEY_verify 3 . +.Bd -unfilled +.Ft int Fn (*verify_recover_init) "EVP_PKEY_CTX *ctx" +.Ft int Fo (*verify_recover) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *rout" +.Fa "size_t *routlen" +.Fa "const unsigned char *sig" +.Fa "size_t siglen" +.Fc +.Ed +.Pp +The +.Fn verify_recover_init +and +.Fn verify_recover +methods are used to verify a signature and then recover the digest from +the signature (for instance, a signature that was generated by the RSA +signing algorithm). +They are called by +.Xr EVP_PKEY_verify_recover_init 3 +and +.Xr EVP_PKEY_verify_recover 3 . +.Bd -unfilled +.Ft int Fn (*signctx_init) "EVP_PKEY_CTX *ctx" "EVP_MD_CTX *mctx" +.Ft int Fo (*signctx) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *sig" +.Fa "size_t *siglen" +.Fa "EVP_MD_CTX *mctx" +.Fc +.Ed +.Pp +The +.Fn signctx_init +and +.Fn signctx +methods are used to sign a digest represented by an +.Vt EVP_MD_CTX +object. +They are called by the +.Xr EVP_DigestSignInit 3 +functions. +.Bd -unfilled +.Ft int Fn (*verifyctx_init) "EVP_PKEY_CTX *ctx" "EVP_MD_CTX *mctx" +.Ft int Fo (*verifyctx) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const unsigned char *sig" +.Fa "int siglen" +.Fa "EVP_MD_CTX *mctx" +.Fc +.Ed +.Pp +The +.Fn verifyctx_init +and +.Fn verifyctx +methods are used to verify a signature against the data in an +.Vt EVP_MD_CTX +object. +They are called by the +.Xr EVP_DigestVerifyInit 3 +functions. +.Bd -unfilled +.Ft int Fn (*encrypt_init) "EVP_PKEY_CTX *ctx" +.Ft int Fo (*encrypt) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *out" +.Fa "size_t *outlen" +.Fa "const unsigned char *in" +.Fa "size_t inlen" +.Fc +.Ed +.Pp +The +.Fn encrypt_init +and +.Fn encrypt +methods are used to encrypt a piece of data. +They are called by +.Xr EVP_PKEY_encrypt_init 3 +and +.Xr EVP_PKEY_encrypt 3 . +.Bd -unfilled +.Ft int Fn (*decrypt_init) "EVP_PKEY_CTX *ctx" +.Ft int Fo (*decrypt) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *out" +.Fa "size_t *outlen" +.Fa "const unsigned char *in" +.Fa "size_t inlen" +.Fc +.Ed +.Pp +The +.Fn decrypt_init +and +.Fn decrypt +methods are used to decrypt a piece of data. +They are called by +.Xr EVP_PKEY_decrypt_init 3 +and +.Xr EVP_PKEY_decrypt 3 . +.Bd -unfilled +.Ft int Fn (*derive_init) "EVP_PKEY_CTX *ctx" +.Ft int Fo (*derive) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *key" +.Fa "size_t *keylen" +.Fc +.Ed +.Pp +The +.Fn derive_init +and +.Fn derive +methods are used to derive the shared secret from a public key algorithm +(for instance, the DH algorithm). +They are called by +.Xr EVP_PKEY_derive_init 3 +and +.Xr EVP_PKEY_derive 3 . +.Bd -unfilled +.Ft int Fo (*ctrl) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int type" +.Fa "int p1" +.Fa "void *p2" +.Fc +.Ft int Fo (*ctrl_str) +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const char *type" +.Fa "const char *value" +.Fc +.Ed +.Pp +The +.Fn ctrl +and +.Fn ctrl_str +methods are used to adjust algorithm-specific settings. +See +.Xr EVP_PKEY_CTX_ctrl 3 +for details. +.Bd -unfilled +.Ft int Fn (*check) "EVP_PKEY *pkey" +.Ft int Fn (*public_check) "EVP_PKEY *pkey" +.Ft int Fn (*param_check) "EVP_PKEY *pkey" +.Ed +These methods are used to validate a key pair, the public component, +and the parameters for the given +.Fa pkey , +respectively. +They are called by +.Xr EVP_PKEY_check 3 , +.Xr EVP_PKEY_public_check 3 , +and +.Xr EVP_PKEY_param_check 3 , +respectively. +.Ss Functions +.Fn EVP_PKEY_meth_new +creates a new +.Vt EVP_PKEY_METHOD +object with the given +.Fa id +and +.Fa flags . +The following flags are supported: +.Bl -tag -width Ds +.It Dv EVP_PKEY_FLAG_AUTOARGLEN +Automatically calculate the maximum size of the output buffer +in corresponding EVP methods by the EVP framework. +Thus the implementations of these methods don't need to care about +handling the case of returning output buffer size by themselves. +For details on the output buffer size, refer to +.Xr EVP_PKEY_sign 3 . +.It Dv EVP_PKEY_FLAG_SIGCTX_CUSTOM +Indicate that the +.Fn signctx +method of an +.Vt EVP_PKEY_METHOD +is always called by the EVP framework while doing a digest signing +operation by calling +.Xr EVP_DigestSignFinal 3 . +.El +.Pp +.Fn EVP_PKEY_meth_free +frees +.Fa pmeth . +.Pp +.Fn EVP_PKEY_meth_copy +copies +.Fa src +to +.Fa dst . +.Pp +.Fn EVP_PKEY_meth_find +finds an +.Vt EVP_PKEY_METHOD +object with the given +.Fa id . +This function first searches through the user-defined method objects and +then through the built-in objects. +.Pp +.Fn EVP_PKEY_meth_add0 +adds +.Fa pmeth +to the stack of user defined methods. +.Pp +The +.Fn EVP_PKEY_meth_set_* +functions set the corresponding fields of +.Fa pmeth +to the arguments passed. +.Pp +.Fn EVP_PKEY_CTX_get_data +retrieves algorithm- and implementation-specific private key data from +.Fa ctx . +Public key algorithm implementations typically allocate and initialize +this data automatically in their +.Fn init +function. +.Pp +.Fn EVP_PKEY_CTX_set_data +transfers ownership of the given +.Fa data +to +.Fa ctx , +replacing the existing algorithm- and implementation-specific +private key data. +It is the responsibility of the caller to free the existing data +before calling this function. +.Sh RETURN VALUES +.Fn EVP_PKEY_meth_new +returns a pointer to a new +.Vt EVP_PKEY_METHOD +object or +.Dv NULL +on error. +.Pp +.Fn EVP_PKEY_meth_find +returns a pointer to the found +.Vt EVP_PKEY_METHOD +object or +.Dv NULL +if no matching object is found. +.Pp +.Fn EVP_PKEY_meth_add0 +returns 1 if the method is added successfully or 0 if an error occurred. +.Pp +.Fn EVP_PKEY_CTX_get_data +returns an internal pointer owned by +.Fa ctx . +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr EVP_PKEY_meth_get0_info 3 , +.Xr EVP_PKEY_new 3 +.Sh HISTORY +.Fn EVP_PKEY_meth_new , +.Fn EVP_PKEY_meth_free , +.Fn EVP_PKEY_meth_find , +.Fn EVP_PKEY_meth_add0 , +.Fn EVP_PKEY_meth_set_init , +.Fn EVP_PKEY_meth_set_copy , +.Fn EVP_PKEY_meth_set_cleanup , +.Fn EVP_PKEY_meth_set_paramgen , +.Fn EVP_PKEY_meth_set_keygen , +.Fn EVP_PKEY_meth_set_sign , +.Fn EVP_PKEY_meth_set_verify , +.Fn EVP_PKEY_meth_set_verify_recover , +.Fn EVP_PKEY_meth_set_signctx , +.Fn EVP_PKEY_meth_set_verifyctx , +.Fn EVP_PKEY_meth_set_encrypt , +.Fn EVP_PKEY_meth_set_decrypt , +.Fn EVP_PKEY_meth_set_derive , +.Fn EVP_PKEY_meth_set_ctrl , +.Fn EVP_PKEY_CTX_get_data , +and +.Fn EVP_PKEY_CTX_set_data +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn EVP_PKEY_meth_copy +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . +.Pp +.Fn EVP_PKEY_meth_set_check , +.Fn EVP_PKEY_meth_set_public_check , +and +.Fn EVP_PKEY_meth_set_param_check +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/EVP_PKEY_new.3 b/Libraries/libressl/man/EVP_PKEY_new.3 new file mode 100644 index 000000000..3b9611990 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_new.3 @@ -0,0 +1,309 @@ +.\" $OpenBSD: EVP_PKEY_new.3,v 1.18 2022/12/14 22:37:07 schwarze Exp $ +.\" full merge up to: OpenSSL 4dcfdfce May 27 11:50:05 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Matt Caswell . +.\" Copyright (c) 2002, 2018, 2020 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2022 $ +.Dt EVP_PKEY_NEW 3 +.Os +.Sh NAME +.Nm EVP_PKEY_new , +.Nm EVP_PKEY_up_ref , +.Nm EVP_PKEY_free , +.Nm EVP_PKEY_new_raw_private_key , +.Nm EVP_PKEY_new_raw_public_key , +.Nm EVP_PKEY_new_CMAC_key , +.Nm EVP_PKEY_new_mac_key , +.Nm EVP_PKEY_get_raw_private_key , +.Nm EVP_PKEY_get_raw_public_key +.Nd public and private key allocation and raw key handling functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_PKEY * +.Fn EVP_PKEY_new void +.Ft int +.Fo EVP_PKEY_up_ref +.Fa "EVP_PKEY *pkey" +.Fc +.Ft void +.Fo EVP_PKEY_free +.Fa "EVP_PKEY *pkey" +.Fc +.Ft EVP_PKEY * +.Fo EVP_PKEY_new_raw_private_key +.Fa "int type" +.Fa "ENGINE *e" +.Fa "const unsigned char *rawpriv" +.Fa "size_t rawlen" +.Fc +.Ft EVP_PKEY * +.Fo EVP_PKEY_new_raw_public_key +.Fa "int type" +.Fa "ENGINE *e" +.Fa "const unsigned char *rawpub" +.Fa "size_t rawlen" +.Fc +.Ft EVP_PKEY * +.Fo EVP_PKEY_new_CMAC_key +.Fa "ENGINE *e" +.Fa "const unsigned char *rawpriv" +.Fa "size_t rawlen" +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft EVP_PKEY * +.Fo EVP_PKEY_new_mac_key +.Fa "int type" +.Fa "ENGINE *e" +.Fa "const unsigned char *rawpriv" +.Fa "int rawlen" +.Fc +.Ft int +.Fo EVP_PKEY_get_raw_private_key +.Fa "const EVP_PKEY *pkey" +.Fa "unsigned char *rawpriv" +.Fa "size_t *rawlen" +.Fc +.Ft int +.Fo EVP_PKEY_get_raw_public_key +.Fa "const EVP_PKEY *pkey" +.Fa "unsigned char *rawpub" +.Fa "size_t *rawlen" +.Fc +.Sh DESCRIPTION +The +.Vt EVP_PKEY +structure is used by various OpenSSL functions which require a general +private or public key without reference to any particular algorithm. +.Pp +The +.Fn EVP_PKEY_new +function allocates an empty +.Vt EVP_PKEY +structure. +The reference count is set to 1. +To add a private or public key to it, use the functions described in +.Xr EVP_PKEY_set1_RSA 3 . +.Pp +.Fn EVP_PKEY_up_ref +increments the reference count of +.Fa pkey +by 1. +.Pp +.Fn EVP_PKEY_free +decrements the reference count of +.Fa pkey +by 1, and if the reference count reaches zero, frees it up. +If +.Fa pkey +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn EVP_PKEY_new_raw_private_key +allocates a new +.Vt EVP_PKEY . +If +.Fa e +is +.Pf non- Dv NULL , +the new structure is associated with the engine +.Fa e . +The NID of a public key algorithm that supports raw private keys, i.e.\& +.Dv EVP_PKEY_HMAC , +.Dv EVP_PKEY_X25519 , +or +.Dv EVP_PKEY_ED25519 , +is provided in the +.Fa type +argument and +.Fa rawlen +bytes of raw private key data of that type in +.Fa rawpriv . +The public key data is automatically derived from the given private +key data, if appropriate for the algorithm type. +.Pp +.Fn EVP_PKEY_new_raw_public_key +works in the same way as +.Fn EVP_PKEY_new_raw_private_key +except that +.Fa rawpub +points to the raw public key data. +The +.Vt EVP_PKEY +structure is initialised without any private key information. +Algorithm types that support raw public keys are +.Dv EVP_PKEY_X25519 +and +.Dv EVP_PKEY_ED25519 . +.Pp +.Fn EVP_PKEY_new_CMAC_key +works in the same way as +.Fn EVP_PKEY_new_raw_private_key +except that it only handles the +.Dv EVP_PKEY_CMAC +algorithm type. +The additional +.Fa cipher +argument specifies the cipher algorithm +to be used during the creation of the CMAC. +It should be a standard encryption only cipher. +For example, AEAD and XTS ciphers should not be used. +.Pp +.Fn EVP_PKEY_new_mac_key +is a deprecated function that works in the same way as +.Fn EVP_PKEY_new_raw_private_key . +.Pp +.Fn EVP_PKEY_get_raw_private_key +writes up to +.Pf * Fa rawlen +bytes of raw private key data to the buffer starting at +.Fa rawpriv +and stores the number of bytes written in +.Pf * Fa rawlen . +The calling application is responsible for ensuring that the buffer +is large enough to receive the private key data. +If the +.Fa rawpriv +argument is +.Dv NULL , +the number of bytes required to hold the key is stored in +.Pf * Fa rawlen . +This function only works for algorithms that support raw private keys. +Currently these are +.Dv EVP_PKEY_HMAC , +.Dv EVP_PKEY_X25519 , +and +.Dv EVP_PKEY_ED25519 . +.Pp +.Fn EVP_PKEY_get_raw_public_key +is similar to +.Fn EVP_PKEY_get_raw_private_key +except that it writes raw public key data. +This function only works for algorithms that support raw public keys. +Currently these are +.Dv EVP_PKEY_X25519 +and +.Dv EVP_PKEY_ED25519 . +.Sh RETURN VALUES +.Fn EVP_PKEY_new , +.Fn EVP_PKEY_new_raw_private_key , +.Fn EVP_PKEY_new_raw_public_key , +.Fn EVP_PKEY_new_CMAC_key , +and +.Fn EVP_PKEY_new_mac_key +return either the newly allocated +.Vt EVP_PKEY +structure or +.Dv NULL +if an error occurred. +.Pp +.Fn EVP_PKEY_up_ref , +.Fn EVP_PKEY_get_raw_private_key , +and +.Fn EVP_PKEY_get_raw_public_key +return 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr CMAC_Init 3 , +.Xr d2i_PrivateKey 3 , +.Xr evp 3 , +.Xr EVP_PKCS82PKEY 3 , +.Xr EVP_PKEY_add1_attr 3 , +.Xr EVP_PKEY_asn1_new 3 , +.Xr EVP_PKEY_check 3 , +.Xr EVP_PKEY_cmp 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_get_default_digest_nid 3 , +.Xr EVP_PKEY_meth_new 3 , +.Xr EVP_PKEY_print_private 3 , +.Xr EVP_PKEY_set1_RSA 3 , +.Xr EVP_PKEY_size 3 , +.Xr X509_get_pubkey_parameters 3 +.Sh HISTORY +.Fn EVP_PKEY_new +and +.Fn EVP_PKEY_free +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_PKEY_new_CMAC_key +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 6.9 . +.Pp +.Fn EVP_PKEY_new_mac_key +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Pp +.Fn EVP_PKEY_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Pp +.Fn EVP_PKEY_new_raw_private_key , +.Fn EVP_PKEY_new_raw_public_key , +.Fn EVP_PKEY_get_raw_private_key , +and +.Fn EVP_PKEY_get_raw_public_key +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.3 . diff --git a/Libraries/libressl/man/EVP_PKEY_print_private.3 b/Libraries/libressl/man/EVP_PKEY_print_private.3 new file mode 100644 index 000000000..c1e689981 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_print_private.3 @@ -0,0 +1,130 @@ +.\" $OpenBSD: EVP_PKEY_print_private.3,v 1.7 2019/06/06 01:06:58 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt EVP_PKEY_PRINT_PRIVATE 3 +.Os +.Sh NAME +.Nm EVP_PKEY_print_public , +.Nm EVP_PKEY_print_private , +.Nm EVP_PKEY_print_params +.Nd public key algorithm printing routines +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_print_public +.Fa "BIO *out" +.Fa "const EVP_PKEY *pkey" +.Fa "int indent" +.Fa "ASN1_PCTX *pctx" +.Fc +.Ft int +.Fo EVP_PKEY_print_private +.Fa "BIO *out" +.Fa "const EVP_PKEY *pkey" +.Fa "int indent" +.Fa "ASN1_PCTX *pctx" +.Fc +.Ft int +.Fo EVP_PKEY_print_params +.Fa "BIO *out" +.Fa "const EVP_PKEY *pkey" +.Fa "int indent" +.Fa "ASN1_PCTX *pctx" +.Fc +.Sh DESCRIPTION +The functions +.Fn EVP_PKEY_print_public , +.Fn EVP_PKEY_print_private , +and +.Fn EVP_PKEY_print_params +print out the public, private or parameter components of key +.Fa pkey , +respectively. +The key is sent to +.Vt BIO +.Fa out +in human readable form. +The parameter +.Fa indent +indicates how far the printout should be indented. +.Pp +The +.Fa pctx +parameter allows the print output to be finely tuned by using ASN.1 +printing options. +If +.Fa pctx +is set to +.Dv NULL , +then default values will be used. +Currently, no public key algorithms include any options in the +.Fa pctx +parameter. +.Pp +If the key does not include all the components indicated by the function, +then only those contained in the key will be printed. +For example, passing a public key to +.Fn EVP_PKEY_print_private +will only print the public components. +.Sh RETURN VALUES +These functions all return 1 for success and 0 or a negative value for +failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh SEE ALSO +.Xr EVP_PKEY_asn1_set_public 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_keygen 3 , +.Xr EVP_PKEY_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_set1_RSA.3 b/Libraries/libressl/man/EVP_PKEY_set1_RSA.3 new file mode 100644 index 000000000..4a382e115 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_set1_RSA.3 @@ -0,0 +1,517 @@ +.\" $OpenBSD: EVP_PKEY_set1_RSA.3,v 1.20 2023/08/27 13:08:15 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019, 2020, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 27 2023 $ +.Dt EVP_PKEY_SET1_RSA 3 +.Os +.Sh NAME +.Nm EVP_PKEY_set1_RSA , +.Nm EVP_PKEY_set1_DSA , +.Nm EVP_PKEY_set1_DH , +.Nm EVP_PKEY_set1_EC_KEY , +.Nm EVP_PKEY_get1_RSA , +.Nm EVP_PKEY_get1_DSA , +.Nm EVP_PKEY_get1_DH , +.Nm EVP_PKEY_get1_EC_KEY , +.Nm EVP_PKEY_get0_RSA , +.Nm EVP_PKEY_get0_DSA , +.Nm EVP_PKEY_get0_DH , +.Nm EVP_PKEY_get0_EC_KEY , +.Nm EVP_PKEY_get0_hmac , +.Nm EVP_PKEY_get0 , +.Nm EVP_PKEY_assign_RSA , +.Nm EVP_PKEY_assign_DSA , +.Nm EVP_PKEY_assign_DH , +.Nm EVP_PKEY_assign_EC_KEY , +.Nm EVP_PKEY_assign_GOST , +.Nm EVP_PKEY_assign , +.Nm EVP_PKEY_base_id , +.Nm EVP_PKEY_id , +.Nm EVP_PKEY_type , +.Nm EVP_PKEY_set_type , +.Nm EVP_PKEY_set_type_str +.\" The function X509_certificate_type(3) is intentionally undocumented +.\" and scheduled for deletion from the library. BoringSSL already +.\" deleted it and OpenSSL deprecates it in version 3.0. +.Nd EVP_PKEY assignment functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_set1_RSA +.Fa "EVP_PKEY *pkey" +.Fa "RSA *key" +.Fc +.Ft int +.Fo EVP_PKEY_set1_DSA +.Fa "EVP_PKEY *pkey" +.Fa "DSA *key" +.Fc +.Ft int +.Fo EVP_PKEY_set1_DH +.Fa "EVP_PKEY *pkey" +.Fa "DH *key" +.Fc +.Ft int +.Fo EVP_PKEY_set1_EC_KEY +.Fa "EVP_PKEY *pkey" +.Fa "EC_KEY *key" +.Fc +.Ft RSA * +.Fo EVP_PKEY_get1_RSA +.Fa "EVP_PKEY *pkey" +.Fc +.Ft DSA * +.Fo EVP_PKEY_get1_DSA +.Fa "EVP_PKEY *pkey" +.Fc +.Ft DH * +.Fo EVP_PKEY_get1_DH +.Fa "EVP_PKEY *pkey" +.Fc +.Ft EC_KEY * +.Fo EVP_PKEY_get1_EC_KEY +.Fa "EVP_PKEY *pkey" +.Fc +.Ft RSA * +.Fo EVP_PKEY_get0_RSA +.Fa "EVP_PKEY *pkey" +.Fc +.Ft DSA * +.Fo EVP_PKEY_get0_DSA +.Fa "EVP_PKEY *pkey" +.Fc +.Ft DH * +.Fo EVP_PKEY_get0_DH +.Fa "EVP_PKEY *pkey" +.Fc +.Ft EC_KEY * +.Fo EVP_PKEY_get0_EC_KEY +.Fa "EVP_PKEY *pkey" +.Fc +.Ft const unsigned char * +.Fo EVP_PKEY_get0_hmac +.Fa "const EVP_PKEY *pkey" +.Fa "size_t *len" +.Fc +.Ft void * +.Fo EVP_PKEY_get0 +.Fa "const EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_assign_RSA +.Fa "EVP_PKEY *pkey" +.Fa "RSA *key" +.Fc +.Ft int +.Fo EVP_PKEY_assign_DSA +.Fa "EVP_PKEY *pkey" +.Fa "DSA *key" +.Fc +.Ft int +.Fo EVP_PKEY_assign_DH +.Fa "EVP_PKEY *pkey" +.Fa "DH *key" +.Fc +.Ft int +.Fo EVP_PKEY_assign_EC_KEY +.Fa "EVP_PKEY *pkey" +.Fa "EC_KEY *key" +.Fc +.Ft int +.Fo EVP_PKEY_assign_GOST +.Fa "EVP_PKEY *pkey" +.Fa "GOST_KEY *key" +.Fc +.Ft int +.Fo EVP_PKEY_assign +.Fa "EVP_PKEY *pkey" +.Fa "int type" +.Fa "void *key" +.Fc +.Ft int +.Fo EVP_PKEY_base_id +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_id +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_type +.Fa "int type" +.Fc +.Ft int +.Fo EVP_PKEY_set_type +.Fa "EVP_PKEY *pkey" +.Fa "int type" +.Fc +.Ft int +.Fo EVP_PKEY_set_type_str +.Fa "EVP_PKEY *pkey" +.Fa "const char *str" +.Fa "int len" +.Fc +.Sh DESCRIPTION +.Fn EVP_PKEY_set1_RSA , +.Fn EVP_PKEY_set1_DSA , +.Fn EVP_PKEY_set1_DH , +and +.Fn EVP_PKEY_set1_EC_KEY +set the key referenced by +.Fa pkey +to +.Fa key +and increment the reference count of +.Fa key +by 1 in case of success. +.Pp +.Fn EVP_PKEY_get1_RSA , +.Fn EVP_PKEY_get1_DSA , +.Fn EVP_PKEY_get1_DH , +and +.Fn EVP_PKEY_get1_EC_KEY +return the key referenced in +.Fa pkey , +incrementing its reference count by 1, or +.Dv NULL +if the key is not of the correct type. +.Pp +.Fn EVP_PKEY_get0_RSA , +.Fn EVP_PKEY_get0_DSA , +.Fn EVP_PKEY_get0_DH , +.Fn EVP_PKEY_get0_EC_KEY , +and +.Fn EVP_PKEY_get0 +are identical except that they do not increment the reference count. +Consequently, the returned key must not be freed by the caller. +.Pp +.Fn EVP_PKEY_get0_hmac +returns an internal pointer to the key referenced in +.Fa pkey +and sets +.Pf * Fa len +to its length in bytes. +The returned pointer must not be freed by the caller. +If +.Fa pkey +is not of the correct type, +.Dv NULL +is returned and the content of +.Pf * Fa len +becomes unspecified. +.Pp +.Fn EVP_PKEY_assign_RSA , +.Fn EVP_PKEY_assign_DSA , +.Fn EVP_PKEY_assign_DH , +.Fn EVP_PKEY_assign_EC_KEY , +.Fn EVP_PKEY_assign_GOST , +and +.Fn EVP_PKEY_assign +also set the referenced key to +.Fa key ; +however these use the supplied +.Fa key +internally without incrementing its reference count, such that +.Fa key +will be freed when the parent +.Fa pkey +is freed. +If the +.Fa key +is of the wrong type, these functions report success even though +.Fa pkey +ends up in a corrupted state. +Even the functions explicitly containing the type in their name are +.Em not +type safe because they are implemented as macros. +The following types are supported: +.Dv EVP_PKEY_RSA , +.Dv EVP_PKEY_DSA , +.Dv EVP_PKEY_DH , +.Dv EVP_PKEY_EC , +and +.Dv EVP_PKEY_GOSTR01 . +.Pp +.Fn EVP_PKEY_base_id +returns the type of +.Fa pkey +according to the following table: +.Pp +.Bl -column -compact -offset 2n EVP_PKEY_GOSTR NID_X9_62_id_ecPublicKey +.It Sy return value Ta Ta Sy PEM type string +.It Dv EVP_PKEY_CMAC Ta = Dv NID_cmac Ta CMAC +.It Dv EVP_PKEY_DH Ta = Dv NID_dhKeyAgreement Ta DH +.It Dv EVP_PKEY_DSA Ta = Dv NID_dsa Ta DSA +.It Dv EVP_PKEY_EC Ta = Dv NID_X9_62_id_ecPublicKey Ta EC +.It Dv EVP_PKEY_GOSTIMIT Ta = Dv NID_id_Gost28147_89_MAC Ta GOST-MAC +.It Dv EVP_PKEY_GOSTR01 Ta = Dv NID_id_GostR3410_2001 Ta GOST2001 +.It Dv EVP_PKEY_HMAC Ta = Dv NID_hmac Ta HMAC +.It Dv EVP_PKEY_RSA Ta = Dv NID_rsaEncryption Ta RSA +.It Dv EVP_PKEY_RSA_PSS Ta = Dv NID_rsassaPss Ta RSA-PSS +.El +.Pp +Application programs can support additional key types by calling +.Xr EVP_PKEY_asn1_add0 3 . +.Pp +.Fn EVP_PKEY_id +returns the actual OID associated with +.Fa pkey . +Historically keys using the same algorithm could use different OIDs. +The following deprecated aliases are still supported: +.Pp +.Bl -column -compact -offset 2n EVP_PKEY_GOSTR12_ NID_id_tc26_gost3410_2012_512 +.It Sy return value Ta Ta Sy alias for +.It Dv EVP_PKEY_DSA1 Ta = Dv NID_dsa_2 Ta DSA +.It Dv EVP_PKEY_DSA2 Ta = Dv NID_dsaWithSHA Ta DSA +.It Dv EVP_PKEY_DSA3 Ta = Dv NID_dsaWithSHA1 Ta DSA +.It Dv EVP_PKEY_DSA4 Ta = Dv NID_dsaWithSHA1_2 Ta DSA +.It Dv EVP_PKEY_GOSTR12_256 Ta = Dv NID_id_tc26_gost3410_2012_256 Ta GOST2001 +.It Dv EVP_PKEY_GOSTR12_512 Ta = Dv NID_id_tc26_gost3410_2012_512 Ta GOST2001 +.It Dv EVP_PKEY_RSA2 Ta = Dv NID_rsa Ta RSA +.El +.Pp +Application programs can support additional alternative OIDs by calling +.Xr EVP_PKEY_asn1_add_alias 3 . +.Pp +Most applications wishing to know a key type will simply call +.Fn EVP_PKEY_base_id +and will not care about the actual type, +which will be identical in almost all cases. +.Pp +.Fn EVP_PKEY_type +returns the underlying type of the NID +.Fa type . +For example, +.Fn EVP_PKEY_type EVP_PKEY_RSA2 +will return +.Dv EVP_PKEY_RSA . +.Pp +.Fn EVP_PKEY_set_type +frees the key referenced in +.Fa pkey , +if any, and sets the key type of +.Fa pkey +to +.Fa type +without referencing a new key from +.Fa pkey +yet. +For +.Fa type , +any of the possible return values of +.Fn EVP_PKEY_base_id +and +.Fn EVP_PKEY_id +can be passed. +.Pp +.Fn EVP_PKEY_set_type_str +frees the key referenced in +.Fa pkey , +if any, and sets the key type of +.Fa pkey +according to the PEM type string given by the first +.Fa len +bytes of +.Fa str . +If +.Fa len +is \-1, the +.Xr strlen 3 +of +.Fa str +is used instead. +The PEM type strings supported by default are listed in the table above. +This function does not reference a new key from +.Fa pkey . +.Pp +If +.Fa pkey +is a +.Dv NULL +pointer, +.Fn EVP_PKEY_set_type +and +.Fn EVP_PKEY_set_type_str +check that a matching key type exists but do not change any object. +.Pp +In accordance with the OpenSSL naming convention, the key obtained from +or assigned to +.Fa pkey +using the +.Sy 1 +functions must be freed as well as +.Fa pkey . +.Sh RETURN VALUES +.Fn EVP_PKEY_set1_RSA , +.Fn EVP_PKEY_set1_DSA , +.Fn EVP_PKEY_set1_DH , +.Fn EVP_PKEY_set1_EC_KEY , +.Fn EVP_PKEY_assign_RSA , +.Fn EVP_PKEY_assign_DSA , +.Fn EVP_PKEY_assign_DH , +.Fn EVP_PKEY_assign_EC_KEY , +.Fn EVP_PKEY_assign_GOST , +.Fn EVP_PKEY_assign , +.Fn EVP_PKEY_set_type , +and +.Fn EVP_PKEY_set_type_str +return 1 for success or 0 for failure. +.Pp +.Fn EVP_PKEY_get1_RSA , +.Fn EVP_PKEY_get1_DSA , +.Fn EVP_PKEY_get1_DH , +.Fn EVP_PKEY_get1_EC_KEY , +.Fn EVP_PKEY_get0_RSA , +.Fn EVP_PKEY_get0_DSA , +.Fn EVP_PKEY_get0_DH , +.Fn EVP_PKEY_get0_EC_KEY , +.Fn EVP_PKEY_get0_hmac , +and +.Fn EVP_PKEY_get0 +return the referenced key or +.Dv NULL +if an error occurred. +For +.Fn EVP_PKEY_get0 , +the return value points to an +.Vt RSA , +.Vt DSA , +.Vt DH , +.Vt EC_KEY , +.Vt GOST_KEY , +or +.Vt ASN1_OCTET_STRING +object depending on the type of +.Fa pkey . +.Pp +.Fn EVP_PKEY_base_id , +.Fn EVP_PKEY_id , +and +.Fn EVP_PKEY_type +return a key type or +.Dv NID_undef +(equivalently +.Dv EVP_PKEY_NONE ) +on error. +.Sh SEE ALSO +.Xr DH_new 3 , +.Xr DSA_new 3 , +.Xr EC_KEY_new 3 , +.Xr EVP_PKEY_get0_asn1 3 , +.Xr EVP_PKEY_new 3 , +.Xr RSA_new 3 +.Sh HISTORY +.Fn EVP_PKEY_assign_RSA , +.Fn EVP_PKEY_assign_DSA , +.Fn EVP_PKEY_assign_DH , +.Fn EVP_PKEY_assign , +and +.Fn EVP_PKEY_type +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_PKEY_set1_RSA , +.Fn EVP_PKEY_set1_DSA , +.Fn EVP_PKEY_set1_DH , +.Fn EVP_PKEY_get1_RSA , +.Fn EVP_PKEY_get1_DSA , +and +.Fn EVP_PKEY_get1_DH +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn EVP_PKEY_set1_EC_KEY , +.Fn EVP_PKEY_get1_EC_KEY , +and +.Fn EVP_PKEY_assign_EC_KEY +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn EVP_PKEY_get0 , +.Fn EVP_PKEY_base_id , +.Fn EVP_PKEY_id , +.Fn EVP_PKEY_set_type , +and +.Fn EVP_PKEY_set_type_str +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn EVP_PKEY_assign_GOST +first appeared in +.Ox 5.7 . +.Pp +.Fn EVP_PKEY_get0_RSA , +.Fn EVP_PKEY_get0_DSA , +.Fn EVP_PKEY_get0_DH , +and +.Fn EVP_PKEY_get0_EC_KEY +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Pp +.Fn EVP_PKEY_get0_hmac +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/EVP_PKEY_sign.3 b/Libraries/libressl/man/EVP_PKEY_sign.3 new file mode 100644 index 000000000..fbd8e6637 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_sign.3 @@ -0,0 +1,191 @@ +.\" $OpenBSD: EVP_PKEY_sign.3,v 1.8 2022/03/31 17:27:17 naddy Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2013, 2014 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt EVP_PKEY_SIGN 3 +.Os +.Sh NAME +.Nm EVP_PKEY_sign_init , +.Nm EVP_PKEY_sign +.Nd sign using a public key algorithm +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_sign_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_sign +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *sig" +.Fa "size_t *siglen" +.Fa "const unsigned char *tbs" +.Fa "size_t tbslen" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_sign_init +function initializes a public key algorithm context using the key +.Fa ctx->pkey +for a signing operation. +.Pp +The +.Fn EVP_PKEY_sign +function performs a public key signing operation using +.Fa ctx . +The data to be signed is specified using the +.Fa tbs +and +.Fa tbslen +parameters. +If +.Fa sig +is +.Dv NULL , +then the maximum size of the output buffer is written to the +.Fa siglen +parameter. +If +.Fa sig +is not +.Dv NULL , +then before the call the +.Fa siglen +parameter should contain the length of the +.Fa sig +buffer. +If the call is successful, the signature is written to +.Fa sig +and the amount of data written to +.Fa siglen . +.Pp +.Fn EVP_PKEY_sign +does not hash the data to be signed, and therefore is normally used +to sign digests. +For signing arbitrary messages, see the +.Xr EVP_DigestSignInit 3 +and +.Xr EVP_SignInit 3 +signing interfaces instead. +.Pp +After the call to +.Fn EVP_PKEY_sign_init , +algorithm specific control operations can be performed to set any +appropriate parameters for the operation; see +.Xr EVP_PKEY_CTX_ctrl 3 . +.Pp +The function +.Fn EVP_PKEY_sign +can be called more than once on the same context if several operations +are performed using the same parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_sign_init +and +.Fn EVP_PKEY_sign +return 1 for success and 0 or a negative value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh EXAMPLES +Sign data using RSA with PKCS#1 padding and SHA256 digest: +.Bd -literal -offset indent +#include +#include + +EVP_PKEY_CTX *ctx; +/* md is a SHA-256 digest in this example. */ +unsigned char *md, *sig; +size_t mdlen = 32, siglen; +EVP_PKEY *signing_key; + +/* + * NB: assumes signing_key and md are set up before the next + * step. signing_key must be an RSA private key and md must + * point to the SHA-256 digest to be signed. + */ +ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_sign_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + /* Error */ + +/* Determine buffer length */ +if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0) + /* Error */ + +sig = malloc(siglen); + +if (!sig) + /* malloc failure */ + +if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0) + /* Error */ + +/* Signature is siglen bytes written to buffer sig */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_ctrl 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_meth_set_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 +.Sh HISTORY +.Fn EVP_PKEY_sign_init +and +.Fn EVP_PKEY_sign +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_size.3 b/Libraries/libressl/man/EVP_PKEY_size.3 new file mode 100644 index 000000000..b45cda7f9 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_size.3 @@ -0,0 +1,237 @@ +.\" $OpenBSD: EVP_PKEY_size.3,v 1.2 2023/09/12 15:29:03 schwarze Exp $ +.\" full merge up to: OpenSSL eed9d03b Jan 8 11:04:15 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2022, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte . +.\" Copyright (c) 2020 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 12 2023 $ +.Dt EVP_PKEY_SIZE 3 +.Os +.Sh NAME +.Nm EVP_PKEY_size , +.Nm EVP_PKEY_bits , +.Nm EVP_PKEY_security_bits +.Nd EVP_PKEY information functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_size +.Fa "const EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_bits +.Fa "const EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_security_bits +.Fa "const EVP_PKEY *pkey" +.Fc +.Sh DESCRIPTION +.Fn EVP_PKEY_size +returns the maximum size in bytes needed for the output buffer +for almost any operation that can be done with +.Fa pkey . +The primary use is with +.Xr EVP_SignFinal 3 +and +.Xr EVP_SealInit 3 . +The returned size is also large enough for the output buffer of +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_decrypt 3 , +and +.Xr EVP_PKEY_derive 3 . +.Pp +Unless the documentation for the operation says otherwise, +the size returned by +.Fn EVP_PKEY_size +is only an upper limit and the final content of the target +buffer may be smaller. +It is therefore crucial to take note of the size given back by the +function that performs the operation. +For example, +.Xr EVP_PKEY_sign 3 +returns that length in the +.Pf * Fa siglen +argument. +.Pp +Using +.Fn EVP_PKEY_size +is discouraged with +.Xr EVP_DigestSignFinal 3 . +.Pp +Most functions using an output buffer support passing +.Dv NULL +for the buffer and a pointer to an integer +to get the exact size that this function call delivers +in the context that it is called in. +This allows those functions to be called twice, once to find out the +exact buffer size, then allocate the buffer in between, and call that +function again to actually output the data. +For those functions, it isn't strictly necessary to call +.Fn EVP_PKEY_size +to find out the buffer size, but it may still be useful in cases +where it's desirable to know the upper limit in advance. +.Pp +By default, +.Fn EVP_PKEY_size +is supported for the following algorithms: +.Bl -column ED25519 "EVP_MAX_BLOCK_LENGTH = 32" +.It Ta same result as from: +.It CMAC Ta Dv EVP_MAX_BLOCK_LENGTH No = 32 +.It DH Ta Xr DH_size 3 +.It DSA Ta Xr DSA_size 3 +.It EC Ta Xr ECDSA_size 3 +.It ED25519 Ta 64, but see below +.It GOST01 Ta 64 or 128 +.It HMAC Ta Dv EVP_MAX_MD_SIZE No = 64 +.It RSA Ta Xr RSA_size 3 +.It X25519 Ta Dv X25519_KEYLEN No = 32 +.El +.Pp +For +.Dv EVP_PKEY_ED25519 , +the situation is special: while the key size is +.Dv ED25519_KEYLEN No = 32 bytes , +.Fn EVP_PKEY_size +returns 64 because the signature is longer than the keys. +.Pp +The application program can support additional algorithms by calling +.Xr EVP_PKEY_asn1_set_public 3 . +.Pp +.Fn EVP_PKEY_bits +returns the cryptographic length of the cryptosystem to which the key in +.Fa pkey +belongs, in bits. +The definition of cryptographic length is specific to the key cryptosystem. +By default, the following algorithms are supported: +.Bl -column ED25519 "the public domain parameter p" DSA_bits(3) +.It Ta cryptographic length = Ta same result as from: +.It Ta significant bits in ... Ta +.It DH Ta the public domain parameter Fa p Ta Xr DH_bits 3 +.It DSA Ta the public domain parameter Fa p Ta Xr DSA_bits 3 +.It EC Ta the order of the group Ta Xr EC_GROUP_order_bits 3 +.It ED25519 Ta 253 Ta \(em +.It GOST01 Ta 256 or 512 Ta \(em +.It RSA Ta the public modulus Ta Xr RSA_bits 3 +.It X25519 Ta 253 Ta \(em +.El +.Pp +The application program can support additional algorithms by calling +.Xr EVP_PKEY_asn1_set_public 3 . +.Pp +.Fn EVP_PKEY_security_bits +returns the security strength measured in bits of the given +.Fa pkey +as defined in NIST SP800-57. +By default, the following algorithms are supported: +.Bl -column ED25519 DSA_security_bits(3) +.It Ta same result as from: +.It DH Ta Xr DH_security_bits 3 +.It DSA Ta Xr DSA_security_bits 3 +.It EC Ta Xr EC_GROUP_order_bits 3 divided by 2 +.It ED25519 Ta 128 +.It GOST01 Ta not supported, return value is \-2 +.It RSA Ta Xr RSA_security_bits 3 +.It X25519 Ta 128 +.El +.Pp +For EC keys, if the result is greater than 80, it is rounded down +to 256, 192, 128, 112, or 80. +.Pp +The application program can support additional algorithms by calling +.Xr EVP_PKEY_asn1_set_security_bits 3 . +.Sh RETURN VALUES +.Fn EVP_PKEY_size +and +.Fn EVP_PKEY_bits +return a positive number or 0 if this size isn't available. +.Pp +.Fn EVP_PKEY_security_bits +returns a number in the range from 0 to 256 inclusive +or \-2 if this function is unsupported for the algorithm used by +.Fa pkey . +It returns 0 if +.Fa pkey +is +.Dv NULL . +.Sh SEE ALSO +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_new 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_SealInit 3 , +.Xr EVP_SignFinal 3 +.Sh HISTORY +.Fn EVP_PKEY_size +first appeared in SSLeay 0.6.0 and +.Fn EVP_PKEY_bits +in SSLeay 0.9.0. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_PKEY_security_bits +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.2 . diff --git a/Libraries/libressl/man/EVP_PKEY_verify.3 b/Libraries/libressl/man/EVP_PKEY_verify.3 new file mode 100644 index 000000000..c4d983320 --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_verify.3 @@ -0,0 +1,168 @@ +.\" $OpenBSD: EVP_PKEY_verify.3,v 1.7 2018/03/23 04:34:23 schwarze Exp $ +.\" full merge up to: OpenSSL 48e5119a Jan 19 10:49:22 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2010, 2013, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt EVP_PKEY_VERIFY 3 +.Os +.Sh NAME +.Nm EVP_PKEY_verify_init , +.Nm EVP_PKEY_verify +.Nd signature verification using a public key algorithm +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_verify_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_verify +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const unsigned char *sig" +.Fa "size_t siglen" +.Fa "const unsigned char *tbs" +.Fa "size_t tbslen" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_verify_init +function initializes a public key algorithm context using key +.Fa ctx->pkey +for a signature verification operation. +.Pp +The +.Fn EVP_PKEY_verify +function performs a public key verification operation using +.Fa ctx . +The signature is specified using the +.Fa sig +and +.Fa siglen +parameters. +The verified data (i.e. the data believed originally signed) is +specified using the +.Fa tbs +and +.Fa tbslen +parameters. +.Pp +After the call to +.Fn EVP_PKEY_verify_init , +algorithm specific control operations can be performed to set any +appropriate parameters for the operation. +.Pp +The function +.Fn EVP_PKEY_verify +can be called more than once on the same context if several operations +are performed using the same parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_verify_init +and +.Fn EVP_PKEY_verify +return 1 if the verification was successful and 0 if it failed. +Unlike other functions the return value 0 from +.Fn EVP_PKEY_verify +only indicates that the signature did not verify successfully. +That is, +.Fa tbs +did not match the original data or the signature was of invalid form. +It is not an indication of a more serious error. +.Pp +A negative value indicates an error other that signature verification +failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh EXAMPLES +Verify signature using PKCS#1 and SHA256 digest: +.Bd -literal -offset 3n +#include +#include + +EVP_PKEY_CTX *ctx; +unsigned char *md, *sig; +size_t mdlen, siglen; +EVP_PKEY *verify_key; + +/* + * Assumes that verify_key, sig, siglen, md, and mdlen are already set up + * and that verify_key is an RSA public key. + */ +ctx = EVP_PKEY_CTX_new(verify_key, NULL); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_verify_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + /* Error */ + +/* Perform operation */ +ret = EVP_PKEY_verify(ctx, sig, siglen, md, mdlen); + +/* + * ret == 1 indicates success, 0 verify failure, + * and < 0 some other error. + */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_meth_set_verify 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify_recover 3 +.Sh HISTORY +.Fn EVP_PKEY_verify_init +and +.Fn EVP_PKEY_verify +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_PKEY_verify_recover.3 b/Libraries/libressl/man/EVP_PKEY_verify_recover.3 new file mode 100644 index 000000000..3a55faccd --- /dev/null +++ b/Libraries/libressl/man/EVP_PKEY_verify_recover.3 @@ -0,0 +1,189 @@ +.\" $OpenBSD: EVP_PKEY_verify_recover.3,v 1.9 2018/03/23 04:34:23 schwarze Exp $ +.\" full merge up to: OpenSSL 48e5119a Jan 19 10:49:22 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2006, 2009, 2010, 2013, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt EVP_PKEY_VERIFY_RECOVER 3 +.Os +.Sh NAME +.Nm EVP_PKEY_verify_recover_init , +.Nm EVP_PKEY_verify_recover +.Nd recover signature using a public key algorithm +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_verify_recover_init +.Fa "EVP_PKEY_CTX *ctx" +.Fc +.Ft int +.Fo EVP_PKEY_verify_recover +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *rout" +.Fa "size_t *routlen" +.Fa "const unsigned char *sig" +.Fa "size_t siglen" +.Fc +.Sh DESCRIPTION +The +.Fn EVP_PKEY_verify_recover_init +function initializes a public key algorithm context using key +.Fa ctx->pkey +for a verify recover operation. +.Pp +The +.Fn EVP_PKEY_verify_recover +function recovers signed data using +.Fa ctx . +The signature is specified using the +.Fa sig +and +.Fa siglen +parameters. +If +.Fa rout +is +.Dv NULL , +then the maximum size of the output buffer is written to the +.Fa routlen +parameter. +If +.Fa rout +is not +.Dv NULL , +then before the call the +.Fa routlen +parameter should contain the length of the +.Fa rout +buffer. +If the call is successful, recovered data is written to +.Fa rout +and the amount of data written to +.Fa routlen . +.Pp +Normally an application is only interested in whether a signature +verification operation is successful. +In those cases, the +.Xr EVP_PKEY_verify 3 +function should be used. +.Pp +Sometimes however it is useful to obtain the data originally signed +using a signing operation. +Only certain public key algorithms can recover a signature in this way +(for example RSA in PKCS padding mode). +.Pp +After the call to +.Fn EVP_PKEY_verify_recover_init , +algorithm specific control operations can be performed to set any +appropriate parameters for the operation. +.Pp +The function +.Fn EVP_PKEY_verify_recover +can be called more than once on the same context if several operations +are performed using the same parameters. +.Sh RETURN VALUES +.Fn EVP_PKEY_verify_recover_init +and +.Fn EVP_PKEY_verify_recover +return 1 for success and 0 or a negative value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh EXAMPLES +Recover digest originally signed using PKCS#1 and SHA256 digest: +.Bd -literal -offset indent +#include +#include + +EVP_PKEY_CTX *ctx; +unsigned char *rout, *sig; +size_t routlen, siglen; +EVP_PKEY *verify_key; + +/* + * Assumes that verify_key, sig, and siglen are already set up + * and that verify_key is an RSA public key. + */ +ctx = EVP_PKEY_CTX_new(verify_key, NULL); +if (!ctx) + /* Error occurred */ +if (EVP_PKEY_verify_recover_init(ctx) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + /* Error */ +if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + /* Error */ + +/* Determine buffer length */ +if (EVP_PKEY_verify_recover(ctx, NULL, &routlen, sig, siglen) <= 0) + /* Error */ + +rout = malloc(routlen); + +if (!rout) + /* malloc failure */ + +if (EVP_PKEY_verify_recover(ctx, rout, &routlen, sig, siglen) <= 0) + /* Error */ + +/* Recovered data is routlen bytes written to buffer rout */ +.Ed +.Sh SEE ALSO +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_meth_set_verify_recover 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 +.Sh HISTORY +.Fn EVP_PKEY_verify_recover_init +and +.Fn EVP_PKEY_verify_recover +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/EVP_SealInit.3 b/Libraries/libressl/man/EVP_SealInit.3 new file mode 100644 index 000000000..15938fcb3 --- /dev/null +++ b/Libraries/libressl/man/EVP_SealInit.3 @@ -0,0 +1,188 @@ +.\" $OpenBSD: EVP_SealInit.3,v 1.8 2019/06/07 20:46:25 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2003, 2005, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 7 2019 $ +.Dt EVP_SEALINIT 3 +.Os +.Sh NAME +.Nm EVP_SealInit , +.Nm EVP_SealUpdate , +.Nm EVP_SealFinal +.Nd EVP envelope encryption +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_SealInit +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "const EVP_CIPHER *type" +.Fa "unsigned char **ek" +.Fa "int *ekl" +.Fa "unsigned char *iv" +.Fa "EVP_PKEY **pubk" +.Fa "int npubk" +.Fc +.Ft int +.Fo EVP_SealUpdate +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fa "unsigned char *in" +.Fa "int inl" +.Fc +.Ft int +.Fo EVP_SealFinal +.Fa "EVP_CIPHER_CTX *ctx" +.Fa "unsigned char *out" +.Fa "int *outl" +.Fc +.Sh DESCRIPTION +The EVP envelope routines are a high level interface to envelope +encryption. +They generate a random key and IV (if required) then "envelope" it by +using public key encryption. +Data can then be encrypted using this key. +.Pp +.Fn EVP_SealInit +initializes a cipher context +.Fa ctx +for encryption with cipher +.Fa type +using a random secret key and IV. +.Fa type +is normally supplied by a function such as +.Xr EVP_aes_256_cbc 3 ; +see +.Xr EVP_EncryptInit 3 +for details. +The secret key is encrypted using one or more public keys. +This allows the same encrypted data to be decrypted using any of +the corresponding private keys. +.Fa ek +is an array of buffers where the public key encrypted secret key will be +written. +Each buffer must contain enough room for the corresponding encrypted +key: that is +.Fa ek[i] +must have room for +.Fn EVP_PKEY_size pubk[i] +bytes. +The actual size of each encrypted secret key is written to the array +.Fa ekl . +.Fa pubk +is an array of +.Fa npubk +public keys. +.Pp +The +.Fa iv +parameter is a buffer where the generated IV is written to. +It must contain enough room for the corresponding cipher's IV, as +determined by (for example) +.Fn EVP_CIPHER_iv_length type . +.Pp +If the cipher does not require an IV then the +.Fa iv +parameter is ignored and can be +.Dv NULL . +.Pp +.Fn EVP_SealUpdate +and +.Fn EVP_SealFinal +have exactly the same properties as the +.Xr EVP_EncryptUpdate 3 +and +.Xr EVP_EncryptFinal 3 +routines. +.Pp +The public key must be RSA because it is the only OpenSSL public key +algorithm that supports key transport. +.Pp +Envelope encryption is the usual method of using public key encryption +on large amounts of data. +This is because public key encryption is slow but symmetric encryption +is fast. +So symmetric encryption is used for bulk encryption and the small random +symmetric key used is transferred using public key encryption. +.Pp +It is possible to call +.Fn EVP_SealInit +twice in the same way as +.Xr EVP_EncryptInit 3 . +The first call should have +.Fa npubk +set to 0 and (after setting any cipher parameters) it should be called +again with +.Fa type +set to NULL. +.Sh RETURN VALUES +.Fn EVP_SealInit +returns 0 on error or +.Fa npubk +if successful. +.Pp +.Fn EVP_SealUpdate +and +.Fn EVP_SealFinal +return 1 for success and 0 for failure. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 , +.Xr EVP_OpenInit 3 +.Sh HISTORY +.Fn EVP_SealInit , +.Fn EVP_SealUpdate , +and +.Fn EVP_SealFinal +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_SealFinal +did not return a value before OpenSSL 0.9.7. diff --git a/Libraries/libressl/man/EVP_SignInit.3 b/Libraries/libressl/man/EVP_SignInit.3 new file mode 100644 index 000000000..59dbca1e5 --- /dev/null +++ b/Libraries/libressl/man/EVP_SignInit.3 @@ -0,0 +1,202 @@ +.\" $OpenBSD: EVP_SignInit.3,v 1.16 2022/07/13 19:10:40 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" selective merge up to: OpenSSL 79b49fb0 Mar 20 10:03:10 2018 +1000 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000-2002, 2005, 2006, 2014-2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt EVP_SIGNINIT 3 +.Os +.Sh NAME +.Nm EVP_SignInit_ex , +.Nm EVP_SignUpdate , +.Nm EVP_SignFinal , +.Nm EVP_SignInit +.Nd EVP signing functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_SignInit_ex +.Fa "EVP_MD_CTX *ctx" +.Fa "const EVP_MD *type" +.Fa "ENGINE *impl" +.Fc +.Ft int +.Fo EVP_SignUpdate +.Fa "EVP_MD_CTX *ctx" +.Fa "const void *d" +.Fa "unsigned int cnt" +.Fc +.Ft int +.Fo EVP_SignFinal +.Fa "EVP_MD_CTX *ctx" +.Fa "unsigned char *sig" +.Fa "unsigned int *s" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft void +.Fo EVP_SignInit +.Fa "EVP_MD_CTX *ctx" +.Fa "const EVP_MD *type" +.Fc +.Sh DESCRIPTION +The EVP signature routines are a high level interface to digital +signatures. +.Pp +.Fn EVP_SignInit_ex +sets up a signing context +.Fa ctx +to use the digest +.Fa type +from +.Vt ENGINE +.Fa impl . +.Fa ctx +must be initialized with +.Xr EVP_MD_CTX_init 3 +before calling this function. +.Pp +.Fn EVP_SignUpdate +hashes +.Fa cnt +bytes of data at +.Fa d +into the signature context +.Fa ctx . +This function can be called several times on the same +.Fa ctx +to include additional data. +.Pp +.Fn EVP_SignFinal +signs the data in +.Fa ctx +using the private key +.Fa pkey +and places the signature in +.Fa sig . +.Fa sig +must be at least +.Xr EVP_PKEY_size 3 +bytes in size. +.Fa s +is an OUT parameter, and not used as an IN parameter. +The number of bytes of data written (i.e.\& +the length of the signature) will be written to the integer at +.Fa s . +At most +.Xr EVP_PKEY_size 3 +bytes will be written. +.Pp +.Fn EVP_SignInit +initializes a signing context +.Fa ctx +to use the default implementation of digest +.Fa type . +.Pp +The EVP interface to digital signatures should almost always be +used in preference to the low level interfaces. +This is because the code then becomes transparent to the algorithm used +and much more flexible. +.Pp +The call to +.Fn EVP_SignFinal +internally finalizes a copy of the digest context. +This means that calls to +.Fn EVP_SignUpdate +and +.Fn EVP_SignFinal +can be called later to digest and sign additional data. +.Pp +Since only a copy of the digest context is ever finalized, the context +must be cleaned up after use by calling +.Xr EVP_MD_CTX_free 3 +or a memory leak will occur. +.Sh RETURN VALUES +.Fn EVP_SignInit_ex , +.Fn EVP_SignUpdate , +and +.Fn EVP_SignFinal +return 1 for success and 0 for failure. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_PKEY_asn1_set_public 3 , +.Xr EVP_PKEY_size 3 , +.Xr EVP_VerifyInit 3 +.Sh HISTORY +.Fn EVP_SignInit , +.Fn EVP_SignUpdate , +and +.Fn EVP_SignFinal +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_SignInit_ex +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh BUGS +Older versions of this documentation wrongly stated that calls to +.Fn EVP_SignUpdate +could not be made after calling +.Fn EVP_SignFinal . +.Pp +Since the private key is passed in the call to +.Fn EVP_SignFinal , +any error relating to the private key (for example an unsuitable key and +digest combination) will not be indicated until after potentially large +amounts of data have been passed through +.Fn EVP_SignUpdate . +.Pp +It is not possible to change the signing parameters using these +function. +.Pp +The previous two bugs are fixed in the newer EVP_DigestSign* function. diff --git a/Libraries/libressl/man/EVP_VerifyInit.3 b/Libraries/libressl/man/EVP_VerifyInit.3 new file mode 100644 index 000000000..5556f6c83 --- /dev/null +++ b/Libraries/libressl/man/EVP_VerifyInit.3 @@ -0,0 +1,195 @@ +.\" $OpenBSD: EVP_VerifyInit.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" selective merge up to: OpenSSL 79b49fb0 Mar 20 10:03:10 2018 +1000 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2001, 2006, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt EVP_VERIFYINIT 3 +.Os +.Sh NAME +.Nm EVP_VerifyInit_ex , +.Nm EVP_VerifyUpdate , +.Nm EVP_VerifyFinal , +.Nm EVP_VerifyInit +.Nd EVP signature verification functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_VerifyInit_ex +.Fa "EVP_MD_CTX *ctx" +.Fa "const EVP_MD *type" +.Fa "ENGINE *impl" +.Fc +.Ft int +.Fo EVP_VerifyUpdate +.Fa "EVP_MD_CTX *ctx" +.Fa "const void *d" +.Fa "unsigned int cnt" +.Fc +.Ft int +.Fo EVP_VerifyFinal +.Fa "EVP_MD_CTX *ctx" +.Fa "unsigned char *sigbuf" +.Fa "unsigned int siglen" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_VerifyInit +.Fa "EVP_MD_CTX *ctx" +.Fa "const EVP_MD *type" +.Fc +.Sh DESCRIPTION +The EVP signature verification routines are a high level interface to +digital signatures. +.Pp +.Fn EVP_VerifyInit_ex +sets up a verification context +.Fa ctx +to use the digest +.Fa type +from +.Vt ENGINE +.Fa impl . +.Fa ctx +must be initialized by calling +.Xr EVP_MD_CTX_init 3 +before calling this function. +.Pp +.Fn EVP_VerifyUpdate +hashes +.Fa cnt +bytes of data at +.Fa d +into the verification context +.Fa ctx . +This function can be called several times on the same +.Fa ctx +to include additional data. +.Pp +.Fn EVP_VerifyFinal +verifies the data in +.Fa ctx +using the public key +.Fa pkey +and against the +.Fa siglen +bytes at +.Fa sigbuf . +.Pp +.Fn EVP_VerifyInit +initializes a verification context +.Fa ctx +to use the default implementation of digest +.Fa type . +.Pp +The EVP interface to digital signatures should almost always be +used in preference to the low level interfaces. +This is because the code then becomes transparent to the algorithm used +and much more flexible. +.Pp +The call to +.Fn EVP_VerifyFinal +internally finalizes a copy of the digest context. +This means that calls to +.Fn EVP_VerifyUpdate +and +.Fn EVP_VerifyFinal +can be called later to digest and verify additional data. +.Pp +Since only a copy of the digest context is ever finalized, the context +must be cleaned up after use by calling +.Xr EVP_MD_CTX_free 3 , +or a memory leak will occur. +.Sh RETURN VALUES +.Fn EVP_VerifyInit_ex +and +.Fn EVP_VerifyUpdate +return 1 for success and 0 for failure. +.Pp +.Fn EVP_VerifyFinal +returns 1 for a correct signature, 0 for failure, and -1 if some other +error occurred. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_SignInit 3 +.Sh HISTORY +.Fn EVP_VerifyInit , +.Fn EVP_VerifyUpdate , +and +.Fn EVP_VerifyFinal +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_VerifyInit_ex +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh BUGS +Older versions of this documentation wrongly stated that calls to +.Fn EVP_VerifyUpdate +could not be made after calling +.Fn EVP_VerifyFinal . +.Pp +Since the public key is passed in the call to +.Xr EVP_SignFinal 3 , +any error relating to the private key (for example an unsuitable key and +digest combination) will not be indicated until after potentially large +amounts of data have been passed through +.Xr EVP_SignUpdate 3 . +.Pp +It is not possible to change the signing parameters using these +functions. +.Pp +The previous two bugs are fixed in the newer functions of the +.Xr EVP_DigestVerifyInit 3 +family. diff --git a/Libraries/libressl/man/EVP_add_cipher.3 b/Libraries/libressl/man/EVP_add_cipher.3 new file mode 100644 index 000000000..6cbfd2e39 --- /dev/null +++ b/Libraries/libressl/man/EVP_add_cipher.3 @@ -0,0 +1,190 @@ +.\" $OpenBSD: EVP_add_cipher.3,v 1.6 2023/08/25 18:39:04 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 25 2023 $ +.Dt EVP_ADD_CIPHER 3 +.Os +.Sh NAME +.Nm EVP_add_cipher , +.Nm EVP_add_cipher_alias , +.Nm EVP_delete_cipher_alias , +.Nm EVP_add_digest , +.Nm EVP_add_digest_alias , +.Nm EVP_delete_digest_alias +.Nd maintain lookup tables for cipher and digest names +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_add_cipher +.Fa "const EVP_CIPHER *cipher" +.Fc +.Ft int +.Fo EVP_add_cipher_alias +.Fa "const char *name" +.Fa "const char *alias" +.Fc +.Ft int +.Fo EVP_delete_cipher_alias +.Fa "const char *alias" +.Fc +.Ft int +.Fo EVP_add_digest +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_add_digest_alias +.Fa "const char *name" +.Fa "const char *alias" +.Fc +.Ft int +.Fo EVP_delete_digest_alias +.Fa "const char *alias" +.Fc +.Sh DESCRIPTION +.Fn EVP_add_cipher +adds +.Fa cipher +to a global lookup table so that it can be retrieved with +.Xr EVP_get_cipherbyname 3 +using both its long and short names, +as determined by the +.Fa cipher Ns 's +NID via +.Xr OBJ_nid2ln 3 +and +.Xr OBJ_nid2sn 3 . +It is the caller's responsibility to ensure that the long +and short names are not +.Dv NULL . +Internally, the lookup table is the global associative array and +.Xr OBJ_NAME_add 3 +is used to add two key-value pairs with value pointer +.Fa cipher +and the keys consisting of the names and +the type +.Dv OBJ_NAME_TYPE_CIPHER_METH . +.Pp +.Fn EVP_add_cipher_alias +and +.Fn EVP_delete_cipher_alias +add and remove the +.Fa alias +for the cipher +.Fa name . +They are implemented as macros wrapping +.Xr OBJ_NAME_add 3 +and +.Xr OBJ_NAME_remove 3 +with +.Fa type +set to the bitwise or of +.Dv OBJ_NAME_TYPE_CIPHER_METH +and +.Dv OBJ_NAME_ALIAS . +.Pp +.Fn EVP_add_digest +adds +.Fa md +to a global lookup table so that it can be retrieved with +.Xr EVP_get_digestbyname 3 +using both its long and short names, +as determined by the +.Fa md Ns 's +NID via +.Xr OBJ_nid2ln 3 +and +.Xr OBJ_nid2sn 3 . +If the +.Fa md +has an associated public key signing algorithm (see +.Xr EVP_MD_pkey_type 3 ) +distinct from the +.Fa md , +the signing algorithm's short and long names are added as aliases for +the short name of +.Fa md . +It is the caller's responsibility to ensure that all long +and short names are not +.Dv NULL . +Internally, the lookup table is the global associative array and +.Xr OBJ_NAME_add 3 +is used to add two key-value pairs with value pointer +.Fa md +and the keys consisting of the names and +the type +.Dv OBJ_NAME_TYPE_MD_METH . +The aliases are added with +.Fn EVP_add_digest_alias . +.Pp +.Fn EVP_add_digest_alias +and +.Fn EVP_delete_digest_alias +add and remove the +.Fa alias +for the digest +.Fa name . +They are implemented as macros wrapping +.Xr OBJ_NAME_add 3 +and +.Xr OBJ_NAME_remove 3 +with +.Fa type +set to the bitwise or of +.Dv OBJ_NAME_TYPE_MD_METH +and +.Dv OBJ_NAME_ALIAS . +.Sh RETURN VALUES +.Fn EVP_add_cipher , +.Fn EVP_add_cipher_alias , +.Fn EVP_add_digest , +and +.Fn EVP_add_digest_alias +return 1 on success or 0 if memory allocation fails. +.Pp +.Fn EVP_delete_cipher_alias +and +.Fn EVP_delete_digest_alias +return 1 if one alias was removed or 0 otherwise. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_CIPHER_meth_new 3 , +.Xr EVP_get_cipherbyname 3 , +.Xr EVP_get_digestbyname 3 , +.Xr EVP_MD_meth_new 3 , +.Xr OBJ_create 3 , +.Xr OBJ_NAME_add 3 , +.Xr OpenSSL_add_all_algorithms 3 +.Sh HISTORY +.Fn EVP_add_cipher +and +.Fn EVP_add_digest +first appeared in OpenSSL 0.9.0 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_add_cipher_alias , +.Fn EVP_delete_cipher_alias , +.Fn EVP_add_digest_alias , +and +.Fn EVP_delete_digest_alias +first appeared in OpenSSL 0.9.4 and have been available since +.Ox 2.6 . +.Sh BUGS +Key-value pairs already added before an error occurred +remain in the global associative array, +leaving it in an unknown state. +.Pp +While aliases can be added and removed, there is no dedicated API +to remove added ciphers or digests. diff --git a/Libraries/libressl/man/EVP_aes_128_cbc.3 b/Libraries/libressl/man/EVP_aes_128_cbc.3 new file mode 100644 index 000000000..ac63f7f1f --- /dev/null +++ b/Libraries/libressl/man/EVP_aes_128_cbc.3 @@ -0,0 +1,337 @@ +.\" $OpenBSD: EVP_aes_128_cbc.3,v 1.4 2020/06/24 18:15:00 jmc Exp $ +.\" selective merge up to: OpenSSL 7c6d372a Nov 20 13:20:01 2018 +0000 +.\" +.\" This file was written by Ronald Tse +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 24 2020 $ +.Dt EVP_AES_128_CBC 3 +.Os +.Sh NAME +.Nm EVP_aes_128_cbc , +.Nm EVP_aes_192_cbc , +.Nm EVP_aes_256_cbc , +.Nm EVP_aes_128_cfb1 , +.Nm EVP_aes_192_cfb1 , +.Nm EVP_aes_256_cfb1 , +.Nm EVP_aes_128_cfb8 , +.Nm EVP_aes_192_cfb8 , +.Nm EVP_aes_256_cfb8 , +.Nm EVP_aes_128_cfb128 , +.Nm EVP_aes_192_cfb128 , +.Nm EVP_aes_256_cfb128 , +.Nm EVP_aes_128_cfb , +.Nm EVP_aes_192_cfb , +.Nm EVP_aes_256_cfb , +.Nm EVP_aes_128_ctr , +.Nm EVP_aes_192_ctr , +.Nm EVP_aes_256_ctr , +.Nm EVP_aes_128_ecb , +.Nm EVP_aes_192_ecb , +.Nm EVP_aes_256_ecb , +.Nm EVP_aes_128_ofb , +.Nm EVP_aes_192_ofb , +.Nm EVP_aes_256_ofb , +.Nm EVP_aes_128_cbc_hmac_sha1 , +.Nm EVP_aes_256_cbc_hmac_sha1 , +.Nm EVP_aes_128_ccm , +.Nm EVP_aes_192_ccm , +.Nm EVP_aes_256_ccm , +.Nm EVP_aes_128_gcm , +.Nm EVP_aes_192_gcm , +.Nm EVP_aes_256_gcm , +.Nm EVP_aes_128_wrap , +.Nm EVP_aes_192_wrap , +.Nm EVP_aes_256_wrap , +.Nm EVP_aes_128_xts , +.Nm EVP_aes_256_xts +.Nd EVP AES cipher +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_ctr void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_ctr void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_ctr void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_cbc_hmac_sha1 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_cbc_hmac_sha1 void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_ccm void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_ccm void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_ccm void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_gcm void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_gcm void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_gcm void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_wrap void +.Ft const EVP_CIPHER * +.Fn EVP_aes_192_wrap void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_wrap void +.Ft const EVP_CIPHER * +.Fn EVP_aes_128_xts void +.Ft const EVP_CIPHER * +.Fn EVP_aes_256_xts void +.Sh DESCRIPTION +These functions provide the AES encryption algorithm in the +.Xr evp 3 +framework. +.Pp +.Fn EVP_aes_128_cbc , +.Fn EVP_aes_192_cbc , +.Fn EVP_aes_256_cbc , +.Fn EVP_aes_128_cfb1 , +.Fn EVP_aes_192_cfb1 , +.Fn EVP_aes_256_cfb1 , +.Fn EVP_aes_128_cfb8 , +.Fn EVP_aes_192_cfb8 , +.Fn EVP_aes_256_cfb8 , +.Fn EVP_aes_128_cfb128 , +.Fn EVP_aes_192_cfb128 , +.Fn EVP_aes_256_cfb128 , +.Fn EVP_aes_128_ctr , +.Fn EVP_aes_192_ctr , +.Fn EVP_aes_256_ctr , +.Fn EVP_aes_128_ecb , +.Fn EVP_aes_192_ecb , +.Fn EVP_aes_256_ecb , +.Fn EVP_aes_128_ofb , +.Fn EVP_aes_192_ofb , +and +.Fn EVP_aes_256_ofb +provide AES for 128, 192, and 256-bit keys in the following modes: +CBC, CFB with 1-bit shift, CFB with 8-bit shift, CFB with 128-bit shift, +CTR, ECB, and OFB. +.Pp +.Fn EVP_aes_128_cfb , +.Fn EVP_aes_192_cfb , +and +.Fn EVP_aes_256_cfb +are aliases for +.Fn EVP_aes_128_cfb128 , +.Fn EVP_aes_192_cfb128 , +and +.Fn EVP_aes_256_cfb128 . +.Pp +.Fn EVP_aes_128_cbc_hmac_sha1 +and +.Fn EVP_aes_256_cbc_hmac_sha1 +provide authenticated encryption with AES in CBC mode using SHA-1 as HMAC, +with keys of 128 and 256-bit length respectively. +The authentication tag is 160 bits long. +This is not intended for usage outside of TLS and requires +calling of some undocumented control functions. +These ciphers do not conform to the EVP AEAD interface. +.Pp +.Fn EVP_aes_128_ccm , +.Fn EVP_aes_192_ccm , +.Fn EVP_aes_256_ccm , +.Fn EVP_aes_128_gcm , +.Fn EVP_aes_192_gcm , +and +.Fn EVP_aes_256_gcm +provide AES for 128, 192 and 256-bit keys in CBC-MAC Mode (CCM) +and Galois Counter Mode (GCM), respectively. +These ciphers require additional control operations to function +correctly; see +.Xr EVP_EncryptInit 3 +for details. +.Pp +.Fn EVP_aes_128_wrap , +.Fn EVP_aes_192_wrap , +and +.Fn EVP_aes_256_wrap +provide AES key wrap with 128, 192 and 256-bit keys +according to RFC 3394 section 2.2.1 ("wrap"). +When the returned +.Vt EVP_CIPHER +object is later passed to +.Xr EVP_CipherInit_ex 3 , +.Xr EVP_EncryptInit_ex 3 , +or +.Xr EVP_DecryptInit_ex 3 +together with an +.Vt EVP_CIPHER_CTX +object, the flag +.Dv EVP_CIPHER_CTX_FLAG_WRAP_ALLOW +must have been set in the +.Vt EVP_CIPHER_CTX +using +.Xr EVP_CIPHER_CTX_set_flags 3 . +Otherwise, or when passing the returned +.Vt EVP_CIPHER +object to +.Xr EVP_CipherInit 3 , +.Xr EVP_EncryptInit 3 , +or +.Xr EVP_DecryptInit 3 , +initialization fails with a +.Dq wrap not allowed +error. +.Pp +.Fn EVP_aes_128_xts +and +.Fn EVP_aes_256_xts +provide XEX-based tweaked-codebook mode with ciphertext stealing (XTS-AES) +as specified in IEEE Std. 1619-2007 and described in NIST SP 800-38E. +It was designed for encrypting data on a storage device, +provides confidentiality but not authentication of data, +and requires a key of double length for protection of a certain key size. +In particular, XTS-AES-128 takes input of a 256-bit key to achieve +AES 128-bit security, and XTS-AES-256 takes input of a 512-bit key +to achieve AES 256-bit security. +.Sh RETURN VALUES +These functions return an +.Vt EVP_CIPHER +structure that provides the implementation of the symmetric cipher. +.Sh SEE ALSO +.Xr AES_encrypt 3 , +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn EVP_aes_128_cbc , +.Fn EVP_aes_192_cbc , +.Fn EVP_aes_256_cbc , +.Fn EVP_aes_128_cfb , +.Fn EVP_aes_192_cfb , +.Fn EVP_aes_256_cfb , +.Fn EVP_aes_128_ebc , +.Fn EVP_aes_192_ebc , +.Fn EVP_aes_256_ebc , +.Fn EVP_aes_128_ofb , +.Fn EVP_aes_192_ofb , +and +.Fn EVP_aes_256_ofb +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EVP_aes_128_cfb1 , +.Fn EVP_aes_192_cfb1 , +.Fn EVP_aes_256_cfb1 , +.Fn EVP_aes_128_cfb8 , +.Fn EVP_aes_192_cfb8 , +.Fn EVP_aes_256_cfb8 , +.Fn EVP_aes_128_cfb128 , +.Fn EVP_aes_192_cfb128 , +and +.Fn EVP_aes_256_cfb128 +first appeared in OpenSSL 0.9.7e and have been available since +.Ox 3.8 . +.Pp +.Fn EVP_aes_128_ctr , +.Fn EVP_aes_192_ctr , +.Fn EVP_aes_256_ctr , +.Fn EVP_aes_128_cbc_hmac_sha1 , +.Fn EVP_aes_256_cbc_hmac_sha1 , +.Fn EVP_aes_128_ccm , +.Fn EVP_aes_192_ccm , +.Fn EVP_aes_256_ccm , +.Fn EVP_aes_128_gcm , +.Fn EVP_aes_192_gcm , +.Fn EVP_aes_256_gcm , +.Fn EVP_aes_128_xts , +and +.Fn EVP_aes_256_xts +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . +.Pp +.Fn EVP_aes_128_wrap , +.Fn EVP_aes_192_wrap , +and +.Fn EVP_aes_256_wrap +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/EVP_camellia_128_cbc.3 b/Libraries/libressl/man/EVP_camellia_128_cbc.3 new file mode 100644 index 000000000..190247a68 --- /dev/null +++ b/Libraries/libressl/man/EVP_camellia_128_cbc.3 @@ -0,0 +1,149 @@ +.\" $OpenBSD: EVP_camellia_128_cbc.3,v 1.2 2020/06/24 18:15:00 jmc Exp $ +.\" selective merge up to: OpenSSL 7c6d372a Nov 20 13:20:01 2018 +0000 +.\" +.\" This file was written by Ronald Tse +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 24 2020 $ +.Dt EVP_CAMELLIA_128_CBC 3 +.Os +.Sh NAME +.Nm EVP_camellia_128_cbc , +.Nm EVP_camellia_192_cbc , +.Nm EVP_camellia_256_cbc , +.Nm EVP_camellia_128_cfb , +.Nm EVP_camellia_192_cfb , +.Nm EVP_camellia_256_cfb , +.Nm EVP_camellia_128_cfb1 , +.Nm EVP_camellia_192_cfb1 , +.Nm EVP_camellia_256_cfb1 , +.Nm EVP_camellia_128_cfb8 , +.Nm EVP_camellia_192_cfb8 , +.Nm EVP_camellia_256_cfb8 , +.Nm EVP_camellia_128_cfb128 , +.Nm EVP_camellia_192_cfb128 , +.Nm EVP_camellia_256_cfb128 , +.Nm EVP_camellia_128_ecb , +.Nm EVP_camellia_192_ecb , +.Nm EVP_camellia_256_ecb , +.Nm EVP_camellia_128_ofb , +.Nm EVP_camellia_192_ofb , +.Nm EVP_camellia_256_ofb +.Nd EVP Camellia cipher +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_128_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_192_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_camellia_256_ofb void +.Sh DESCRIPTION +These functions provide the Camellia encryption algorithm in the +.Xr evp 3 +framework. +They use 128, 192, and 256-bit keys in the following modes, respectively: +CBC, CFB with 1-bit shift, CFB with 8-bit shift, CFB with 128-bit shift, +ECB, and OFB. +.Pp +.Fn EVP_camellia_128_cfb , +.Fn EVP_camellia_192_cfb , +and +.Fn EVP_camellia_256_cfb +are aliases for +.Fn EVP_camellia_128_cfb128 , +.Fn EVP_camellia_192_cfb128 , +and +.Fn EVP_camellia_256_cfb128 , +implemented as macros. +.Sh RETURN VALUES +These functions return an +.Vt EVP_CIPHER +structure that provides the implementation of the symmetric cipher. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8c +and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/EVP_chacha20.3 b/Libraries/libressl/man/EVP_chacha20.3 new file mode 100644 index 000000000..8d0be1ed6 --- /dev/null +++ b/Libraries/libressl/man/EVP_chacha20.3 @@ -0,0 +1,292 @@ +.\" $OpenBSD: EVP_chacha20.3,v 1.7 2023/09/12 13:58:06 schwarze Exp $ +.\" full merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ronald Tse . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 12 2023 $ +.Dt EVP_CHACHA20 3 +.Os +.Sh NAME +.Nm EVP_chacha20 , +.Nm EVP_chacha20_poly1305 +.Nd ChaCha20 stream cipher for EVP +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_CIPHER * +.Fn EVP_chacha20 void +.Ft const EVP_CIPHER * +.Fn EVP_chacha20_poly1305 void +.Sh DESCRIPTION +.Fn EVP_chacha20 +provides the ChaCha20 stream cipher in the EVP framework. +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit_ex 3 , +and +.Xr EVP_CipherInit_ex 3 +take a +.Fa key +argument of 32 bytes = 256 bits and an +.Fa iv +argument of 16 bytes = 128 bits, internally using +.Xr ChaCha_set_key 3 +and +.Xr ChaCha_set_iv 3 . +The lower 8 bytes = 64 bits of +.Fa iv +are used as counter and the remaining 8 bytes are used as +the initialization vector of +.Xr ChaCha_set_iv 3 . +.Xr EVP_EncryptUpdate 3 , +.Xr EVP_EncryptFinal_ex 3 , +.Xr EVP_DecryptUpdate 3 , +and +.Xr EVP_DecryptFinal_ex 3 +internally use +.Xr ChaCha 3 +to perform encryption and decryption. +.Xr EVP_CIPHER_CTX_ctrl 3 +always fails for +.Fa ctx +objects created from +.Fn EVP_chacha20 . +.Pp +.Fn EVP_chacha20_poly1305 +provides authenticated encryption with ChaCha20-Poly1305. +Unless compatibility with other implementations +like OpenSSL or BoringSSL is required, using +.Xr EVP_AEAD_CTX_init 3 +with +.Xr EVP_aead_chacha20_poly1305 3 +is recommended instead because the code then becomes transparent +to the AEAD cipher used, more flexible, and less error prone. +.Pp +With +.Fn EVP_chacha20_poly1305 , +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit_ex 3 , +and +.Xr EVP_CipherInit_ex 3 +take a +.Fa key +argument of 32 bytes = 256 bits and an +.Fa iv +argument of 12 bytes = 96 bits. +This supports additional authenticated data (AAD) and produces a 128-bit +authentication tag. +The constant +.Dv EVP_CHACHAPOLY_TLS_TAG_LEN +specifies the length of the authentication tag in bytes and has a value of 16. +.Pp +The following +.Fa type +arguments are supported for +.Xr EVP_CIPHER_CTX_ctrl 3 : +.Bl -tag -width Ds +.It Dv EVP_CTRL_AEAD_GET_TAG +Copy the number of bytes indicated by the +.Fa arg +argument from the tag to the location indicated by the +.Fa ptr +argument; +to be called after +.Xr EVP_EncryptFinal_ex 3 . +This control operation fails if the +.Fa ctx +is not configured for encryption or if +.Fa arg +is less than 1 or greater than 16. +.It Dv EVP_CTRL_AEAD_SET_TAG +Copy the number of bytes indicated by the +.Fa arg +argument from the location indicated by the +.Fa ptr +argument and designate them as the expected tag length and tag, +causing subsequent +.Xr EVP_DecryptFinal_ex 3 +to fail if the tag calculated during decryption does not match. +It is strongly recommended to specify +.Fa arg +as exactly 16. +Otherwise, only the initial part of the tag may be compared +and mismatches near the end of the tag may get silently ignored. +This control operation fails if the +.Fa ctx +is configured for encryption or if +.Fa arg +is less than 1 or greater than 16. +If the +.Fa ptr +argument is a +.Dv NULL +pointer, this control operation succeeds without having any effect. +.It EVP_CTRL_AEAD_SET_IV_FIXED +Set the initialization vector by reading the 12 bytes pointed to by the +.Fa ptr +argument, independently of +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit_ex 3 , +and +.Xr EVP_CipherInit_ex 3 . +This control operation fails if the +.Fa arg +argument is not exactly 12. +.It Dv EVP_CTRL_AEAD_SET_IVLEN +Instruct subsequent +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit_ex 3 , +or +.Xr EVP_CipherInit_ex 3 +to expect an +.Fa iv +argument shorter than the default of 12 bytes; the +.Fa arg +argument specifies the number of bytes to be used. +The initialization functions will only read +the specified smaller number of bytes from +.Fa iv +and internally zero-pad them on the left. +Using this is not recommended because it is likely more fragile +and less often tested than the equivalent method of simply providing +a full-sized +.Fa iv . +This control operation fails if +.Fa arg +is less than 1 or greater than 16. +.It Dv EVP_CTRL_INIT +Set the length of the initialization vector to the default value +of 12 bytes and clear the Poly1305 internal state. +The application program usually does not need to invoke this control +operation manually because it is automatically called internally by +.Xr EVP_EncryptInit_ex 3 , +.Xr EVP_DecryptInit_ex 3 , +and +.Xr EVP_CipherInit_ex 3 . +.El +.Sh RETURN VALUES +.Fn EVP_chacha20 +and +.Fn EVP_chacha20_poly1305 +return pointers to static +.Vt EVP_CIPHER +objects that contain the implementations of the symmetric cipher. +.Pp +If +.Fa ctx +was created from +.Fn EVP_chacha20 +or +.Fn EVP_chacha20_poly1305 , +.Xr EVP_CIPHER_CTX_ctrl 3 +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr ChaCha 3 , +.Xr evp 3 , +.Xr EVP_aead_chacha20_poly1305 3 , +.Xr EVP_CIPHER_meth_new 3 , +.Xr EVP_EncryptInit 3 +.Sh STANDARDS +.Rs +.%A A. Langley +.%A W. Chang +.%A N. Mavrogiannopoulos +.%A J. Strombergson +.%A S. Josefsson +.%D June 2016 +.%R RFC 7905 +.%T ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) +.Re +.Sh HISTORY +.Fn EVP_chacha20 +first appeared in +.Ox 5.6 . +.Pp +.Fn EVP_chacha20_poly1305 +first appeared in OpenSSL 1.1.0 +.\" OpenSSL commit bd989745 Dec 9 21:30:56 2015 +0100 Andy Polyakov +and has been available since +.Ox 7.2 . +.Sh CAVEATS +The original publications and code by +.An Adam Langley +used a modified AEAD construction that is incompatible with the common +style used by AEAD in TLS and incompatible with RFC 7905: +.Pp +.Rs +.%A A. Langley +.%A W. Chang +.%D November 2013 +.%R draft-agl-tls-chacha20poly1305-04 +.%T ChaCha20 and Poly1305 based Cipher Suites for TLS +.Re +.Pp +.Rs +.%A Y. Nir +.%A A. Langley +.%D May 2018 +.%R RFC 8439 +.%T ChaCha20 and Poly1305 for IETF Protocols +.Re +.Pp +In particular, the original version used a nonce of 8 instead of 12 bytes. diff --git a/Libraries/libressl/man/EVP_des_cbc.3 b/Libraries/libressl/man/EVP_des_cbc.3 new file mode 100644 index 000000000..759e03fac --- /dev/null +++ b/Libraries/libressl/man/EVP_des_cbc.3 @@ -0,0 +1,221 @@ +.\" $OpenBSD: EVP_des_cbc.3,v 1.1 2019/03/21 12:54:37 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL EVP_desx_cbc.pod 8fa4d95e Oct 21 11:59:09 2017 +0900 +.\" selective merge up to: +.\" OpenSSL EVP_des.pod 7c6d372a Nov 20 13:20:01 2018 +0000 +.\" +.\" This file was written by Ronald Tse +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 21 2019 $ +.Dt EVP_DES_CBC 3 +.Os +.Sh NAME +.Nm EVP_des_cbc , +.Nm EVP_des_cfb , +.Nm EVP_des_cfb1 , +.Nm EVP_des_cfb8 , +.Nm EVP_des_cfb64 , +.Nm EVP_des_ecb , +.Nm EVP_des_ofb , +.Nm EVP_des_ede , +.Nm EVP_des_ede_cbc , +.Nm EVP_des_ede_cfb , +.Nm EVP_des_ede_cfb64 , +.Nm EVP_des_ede_ecb , +.Nm EVP_des_ede_ofb , +.Nm EVP_des_ede3 , +.Nm EVP_des_ede3_cbc , +.Nm EVP_des_ede3_cfb , +.Nm EVP_des_ede3_cfb1 , +.Nm EVP_des_ede3_cfb8 , +.Nm EVP_des_ede3_cfb64 , +.Nm EVP_des_ede3_ecb , +.Nm EVP_des_ede3_ofb , +.Nm EVP_desx_cbc +.Nd EVP DES cipher +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_CIPHER * +.Fn EVP_des_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_des_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_des_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_des_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_des_cfb64 void +.Ft const EVP_CIPHER * +.Fn EVP_des_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede_cfb64 void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3 void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_cfb1 void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_cfb8 void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_cfb64 void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_des_ede3_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_desx_cbc void +.Sh DESCRIPTION +These functions provide the DES encryption algorithm in the +.Xr evp 3 +framework. +.Pp +.Fn EVP_des_cbc , +.Fn EVP_des_cfb1 , +.Fn EVP_des_cfb8 , +.Fn EVP_des_cfb64 , +.Fn EVP_des_ecb , +and +.Fn EVP_des_ofb +provide DES in CBC, CFB with 1-bit shift, CFB with 8-bit shift, +CFB with 64-bit shift, ECB, and OFB modes. +.Fn EVP_des_cfb +is an alias for +.Fn EVP_des_cfb64 , +implemented as a macro. +.Pp +.Fn EVP_des_ede_cbc , +.Fn EVP_des_ede_cfb64 , +.Fn EVP_des_ede_ecb , +and +.Fn EVP_des_ede_ofb +provide two key triple DES in CBC, CFB with 64-bit shift, ECB, and OFB modes. +.Fn EVP_des_ede_cfb +is an alias for +.Fn EVP_des_ede_cfb64 , +implemented as a macro. +.Fn EVP_des_ede +is an alias for +.Fn EVP_des_ede_ecb . +.Pp +.Fn EVP_des_ede3_cbc , +.Fn EVP_des_ede3_cfb1 , +.Fn EVP_des_ede3_cfb8 , +.Fn EVP_des_ede3_cfb64 , +.Fn EVP_des_ede3_ecb , +.Fn EVP_des_ede3_ofb +provide three key triple DES in CBC, CFB with 1-bit shift, CFB with 8-bit +shift, CFB with 64-bit shift, ECB, and OFB modes. +.Fn EVP_des_ede3_cfb +is an alias for +.Fn EVP_des_ede3_cfb64 , +implemented as a macro. +.Fn EVP_des_ede3 +is an alias for +.Fn EVP_des_ede3_ecb . +.Pp +.Fn EVP_desx_cbc +provides the DES-X encryption algorithm in CBC mode. +It uses a key length of 128 bits and acts on blocks of 128 bits. +.Sh RETURN VALUES +These functions return an +.Vt EVP_CIPHER +structure that provides the implementation of the symmetric cipher. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn EVP_des_cbc , +.Fn EVP_des_cfb , +.Fn EVP_des_ecb , +.Fn EVP_des_ofb , +.Fn EVP_des_ede , +.Fn EVP_des_ede_cbc , +.Fn EVP_des_ede_cfb , +.Fn EVP_des_ede_ofb , +.Fn EVP_des_ede3 , +.Fn EVP_des_ede3_cbc , +.Fn EVP_des_ede3_cfb , +and +.Fn EVP_des_ede3_ofb +first appeared in SSLeay 0.5.1. +.Fn EVP_desx_cbc +first appeared in SSLeay 0.6.2. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_des_ede_ecb +and +.Fn EVP_des_ede3_ecb +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn EVP_des_cfb1 , +.Fn EVP_des_cfb8 , +.Fn EVP_des_cfb64 , +.Fn EVP_des_ede_cfb64 , +.Fn EVP_des_ede3_cfb1 , +.Fn EVP_des_ede3_cfb8 , +and +.Fn EVP_des_ede3_cfb64 +first appeared in OpenSSL 0.9.7e and have been available since +.Ox 3.8 . diff --git a/Libraries/libressl/man/EVP_rc4.3 b/Libraries/libressl/man/EVP_rc4.3 new file mode 100644 index 000000000..fda041113 --- /dev/null +++ b/Libraries/libressl/man/EVP_rc4.3 @@ -0,0 +1,109 @@ +.\" $OpenBSD: EVP_rc4.3,v 1.1 2019/03/21 13:37:25 schwarze Exp $ +.\" full merge up to: OpenSSL 8fa4d95e Oct 21 11:59:09 2017 +0900 +.\" +.\" This file was written by Ronald Tse +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 21 2019 $ +.Dt EVP_RC4 3 +.Os +.Sh NAME +.Nm EVP_rc4 , +.Nm EVP_rc4_40 , +.Nm EVP_rc4_hmac_md5 +.Nd EVP RC4 stream cipher +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_CIPHER * +.Fn EVP_rc4 void +.Ft const EVP_CIPHER * +.Fn EVP_rc4_40 void +.Ft const EVP_CIPHER * +.Fn EVP_rc4_hmac_md5 void +.Sh DESCRIPTION +These functions provide the RC4 stream cipher in the +.Xr evp 3 +framework. +It is a variable key length cipher. +.Pp +.Fn EVP_rc4 +uses a default key length of 128 bits. +.Pp +.Fn EVP_rc4_40 +uses a key length of 40 bits instead. +This function is deprecated. +Use +.Fn EVP_rc4 +and +.Xr EVP_CIPHER_CTX_set_key_length 3 +instead. +.Pp +.Fn EVP_rc4_hmac_md5 +provides authenticated encryption with the RC4 stream cipher +with MD5 as HMAC. +This function is not intended for usage outside of TLS +and requires calling of some undocumented control functions. +It does not conform to the EVP AEAD interface. +.Sh RETURN VALUES +These functions return an +.Vt EVP_CIPHER +structure that provides the implementation of the symmetric cipher. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh HISTORY +.Fn EVP_rc4 +first appeared in SSLeay 0.5.1 +and +.Fn EVP_rc4_40 +in OpenSSL 0.9.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_rc4_hmac_md5 +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/EVP_sha1.3 b/Libraries/libressl/man/EVP_sha1.3 new file mode 100644 index 000000000..43898a5f6 --- /dev/null +++ b/Libraries/libressl/man/EVP_sha1.3 @@ -0,0 +1,121 @@ +.\" $OpenBSD: EVP_sha1.3,v 1.1 2023/08/27 15:33:08 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 27 2023 $ +.Dt EVP_SHA1 3 +.Os +.Sh NAME +.Nm EVP_sha1 , +.Nm EVP_md5 , +.Nm EVP_md5_sha1 , +.Nm EVP_md4 +.Nd legacy message digest algorithms +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_MD * +.Fn EVP_sha1 void +.Ft const EVP_MD * +.Fn EVP_md5 void +.Ft const EVP_MD * +.Fn EVP_md5_sha1 void +.Ft const EVP_MD * +.Fn EVP_md4 void +.Sh DESCRIPTION +The following message digest algorithms are cryptographically broken. +None of them should be used in new code unless there is no way around it. +.Pp +.Fn EVP_sha1 +implements the SHA-1 algorithm and produces 160 bits of output +from a given input. +Examples of protocols and software still requiring it +include OCSP, DNS, and the +.Sy git +version control system. +.Pp +.Fn EVP_md5 +implements the MD5 algorithm and produces 128 bits of output +from a given input. +It is still occasionally used when no security is required +but a fast hash algorithm is beneficial. +.Pp +.Fn EVP_md5_sha1 +produces concatenated MD5 and SHA-1 message digests. +Do not use this except where it is required for the historic SSLv3 protocol. +.Pp +.Fn EVP_md4 +implements the MD4 algorithm and produces 128 bits of output +from a given input. +It has been marked as +.Dq historic +by the Internet Engineering Task Force since 2011. +.Sh RETURN VALUES +These functions return pointers to static +.Vt EVP_MD +objects implementing the hash functions. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_MD_meth_new 3 +.Sh STANDARDS +.Rs +.%A T. Polk +.%A L. Chen +.%A S. Turner +.%A P. Hoffman +.%T Security Considerations for the SHA-0 and SHA-1 Message-Digest Algorithms +.%R RFC 6194 +.%D March 2011 +.Re +.Pp +.Rs +.%A S. Turner +.%A L. Chen +.%T Updated Security Considerations for the MD5 Message-Digest\ + and the HMAC-MD5 Algorithms +.%R RFC 6151 +.%D March 2011 +.Re +.Pp +.Rs +.%A S. Turner +.%A L. Chen +.%T MD4 to Historic Status +.%R RFC 6150 +.%D March 2011 +.Re +.Pp +.Rs +.%A P. Kocher +.%A P. Karlton +.%A A. Freier +.%T The Secure Sockets Layer (SSL) Protocol Version 3.0 +.%R RFC 6101 +.%D August 2011 +.Re +.Sh HISTORY +.Fn EVP_sha1 +and +.Fn EVP_md5 +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_md4 +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn EVP_md5_sha1 +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/EVP_sha3_224.3 b/Libraries/libressl/man/EVP_sha3_224.3 new file mode 100644 index 000000000..bd9138c3f --- /dev/null +++ b/Libraries/libressl/man/EVP_sha3_224.3 @@ -0,0 +1,92 @@ +.\" $OpenBSD: EVP_sha3_224.3,v 1.2 2023/08/15 11:54:38 schwarze Exp $ +.\" selective merge up to: OpenSSL bbda8ce9 Oct 31 15:43:01 2017 +0800 +.\" +.\" This file was written by Ronald Tse . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 15 2023 $ +.Dt EVP_SHA3_224 3 +.Os +.Sh NAME +.Nm EVP_sha3_224 , +.Nm EVP_sha3_256 , +.Nm EVP_sha3_384 , +.Nm EVP_sha3_512 +.Nd Secure Hash Algorithm 3 for EVP +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_MD * +.Fn EVP_sha3_224 void +.Ft const EVP_MD * +.Fn EVP_sha3_256 void +.Ft const EVP_MD * +.Fn EVP_sha3_384 void +.Ft const EVP_MD * +.Fn EVP_sha3_512 void +.Sh DESCRIPTION +SHA-3 (Secure Hash Algorithm 3) is a family of cryptographic hash +functions standardized in NIST FIPS 202, first published in 2015. +It is based on the Keccak algorithm. +.Pp +.Fn EVP_sha3_224 , +.Fn EVP_sha3_256 , +.Fn EVP_sha3_384 , +and +.Fn EVP_sha3_512 +implement the SHA3-224, SHA3-256, SHA3-384, and SHA3-512 algorithms +and produce 224, 256, 384 and 512 bits of output from a given input, +respectively. +.Sh RETURN VALUES +These functions return pointers to static +.Vt EVP_MD +objects implementing the hash functions. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_MD_meth_new 3 +.Sh STANDARDS +NIST FIPS 202 diff --git a/Libraries/libressl/man/EVP_sm3.3 b/Libraries/libressl/man/EVP_sm3.3 new file mode 100644 index 000000000..aa6789f24 --- /dev/null +++ b/Libraries/libressl/man/EVP_sm3.3 @@ -0,0 +1,82 @@ +.\" $OpenBSD: EVP_sm3.3,v 1.1 2019/08/25 17:08:20 schwarze Exp $ +.\" full merge up to: OpenSSL 21ebd2fc Aug 24 20:38:04 2018 +0800 +.\" +.\" This file was written by Jack Lloyd +.\" and Ronald Tse . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" Copyright (c) 2017 Ribose Inc. All Rights Reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 25 2019 $ +.Dt EVP_SM3 3 +.Os +.Sh NAME +.Nm EVP_sm3 +.Nd SM3 hash function for EVP +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_MD * +.Fn EVP_sm3 void +.Sh DESCRIPTION +SM3 is a cryptographic hash function with a 256-bit output. +It is part of the Chinese +.Dq Commercial Cryptography +suite of algorithms which is required +for certain commercial applications in China. +.Sh RETURN VALUES +.Fn EVP_sm3 +returns a pointer to a static +.Vt EVP_MD +object implementing the SM3 hash function. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 +.Sh STANDARDS +GB/T 32905-2016 and GM/T 0004-2012 +.Sh HISTORY +.Fn EVP_sm3 +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/EVP_sm4_cbc.3 b/Libraries/libressl/man/EVP_sm4_cbc.3 new file mode 100644 index 000000000..85ff88f54 --- /dev/null +++ b/Libraries/libressl/man/EVP_sm4_cbc.3 @@ -0,0 +1,81 @@ +.\" $OpenBSD: EVP_sm4_cbc.3,v 1.1 2019/03/18 05:56:24 schwarze Exp $ +.\" full merge up to: OpenSSL 87103969 Oct 1 14:11:57 2018 -0700 +.\" +.\" Copyright (c) 2017 Ribose Inc +.\" Copyright (c) 2019 Ingo Schwarze +.\" The original version of this file +.\" was written by Ronald Tse . +.\" +.\" Permission to use, copy, modify, and/or distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 18 2019 $ +.Dt EVP_SM4_CBC 3 +.Os +.Sh NAME +.Nm EVP_sm4_cbc , +.Nm EVP_sm4_ecb , +.Nm EVP_sm4_cfb , +.Nm EVP_sm4_cfb128 , +.Nm EVP_sm4_ofb , +.Nm EVP_sm4_ctr +.Nd EVP SM4 cipher +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_CIPHER * +.Fn EVP_sm4_cbc void +.Ft const EVP_CIPHER * +.Fn EVP_sm4_ecb void +.Ft const EVP_CIPHER * +.Fn EVP_sm4_cfb void +.Ft const EVP_CIPHER * +.Fn EVP_sm4_cfb128 void +.Ft const EVP_CIPHER * +.Fn EVP_sm4_ofb void +.Ft const EVP_CIPHER * +.Fn EVP_sm4_ctr void +.Sh DESCRIPTION +These functions provide the SM4 blockcipher in the +.Xr evp 3 +framework. +.Pp +All modes use a key length of 128 bits and act on blocks of 128 +bits. +.Pp +.Fn EVP_sm4_cfb +is an alias for +.Fn EVP_sm4_cfb128 . +.Pp +With an argument of +.Qq sm4 +or +.Qq SM4 , +.Xr EVP_get_cipherbyname 3 +returns +.Fn EVP_sm4_cbc . +.Sh RETURN VALUES +These functions return an +.Vt EVP_CIPHER +structure that provides the implementation of the symmetric cipher. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_EncryptInit 3 +.Sh STANDARDS +.Rs +.%T Information security technology - SM4 block cipher algorithm +.%I National Standards of People's Republic of China +.%N GB/T 32907-2016 +.%D August 29, 2016 +.Re +.Sh HISTORY +These functions appeared in OpenSSL 1.1.1 and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/EVP_whirlpool.3 b/Libraries/libressl/man/EVP_whirlpool.3 new file mode 100644 index 000000000..29f85bc1a --- /dev/null +++ b/Libraries/libressl/man/EVP_whirlpool.3 @@ -0,0 +1,83 @@ +.\" $OpenBSD: EVP_whirlpool.3,v 1.1 2019/08/25 17:08:20 schwarze Exp $ +.\" full merge up to: OpenSSL bbda8ce9 Oct 31 15:43:01 2017 +0800 +.\" +.\" This file was written by Ronald Tse . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 25 2019 $ +.Dt EVP_WHIRLPOOL 3 +.Os +.Sh NAME +.Nm EVP_whirlpool +.Nd WHIRLPOOL hash function for EVP +.Sh SYNOPSIS +.In openssl/evp.h +.Ft const EVP_MD * +.Fn EVP_whirlpool void +.Sh DESCRIPTION +WHIRLPOOL is a cryptographic hash function +producing a message digest of 512 bits. +.Sh RETURN VALUES +.Fn EVP_whirlpool +returns a pointer to a static +.Vt EVP_MD +object implementing the WHIRLPOOL hash function. +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_DigestInit 3 +.Sh STANDARDS +ISO/IEC 10118-3:2004 +.Sh HISTORY +.Fn EVP_whirlpool +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh AUTHORS +.An -nosplit +The WHIRLPOOL algorithm was designed by +.An Vincent Rijmen +and +.An Paulo S. L. M. Barreto . diff --git a/Libraries/libressl/man/EXTENDED_KEY_USAGE_new.3 b/Libraries/libressl/man/EXTENDED_KEY_USAGE_new.3 new file mode 100644 index 000000000..3d1ed17ff --- /dev/null +++ b/Libraries/libressl/man/EXTENDED_KEY_USAGE_new.3 @@ -0,0 +1,84 @@ +.\" $OpenBSD: EXTENDED_KEY_USAGE_new.3,v 1.6 2021/10/27 11:24:47 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 27 2021 $ +.Dt EXTENDED_KEY_USAGE_NEW 3 +.Os +.Sh NAME +.Nm EXTENDED_KEY_USAGE_new , +.Nm EXTENDED_KEY_USAGE_free +.Nd X.509 key usage restrictions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft EXTENDED_KEY_USAGE +.Fn EXTENDED_KEY_USAGE_new void +.Ft void +.Fn EXTENDED_KEY_USAGE_free "EXTENDED_KEY_USAGE *eku" +.Sh DESCRIPTION +By using the key usage extension, the extended key usage extension, +or both of them, +.Vt X509 +end entity certificates may indicate that the key contained in them +is only intended to be used for the specified purposes. +If both extensions are present, only uses compatible with both +extensions are intended. +.Pp +.Fn EXTENDED_KEY_USAGE_new +allocates and initializes an empty +.Vt EXTENDED_KEY_USAGE +object, which is a +.Vt STACK_OF(ASN1_OBJECT) +and represents an ASN.1 +.Vt ExtKeyUsageSyntax +structure defined in RFC 5280 section 4.2.1.12. +It can hold key purpose identifiers. +.Pp +.Fn EXTENDED_KEY_USAGE_free +frees +.Fa eku . +.Pp +The key usage extension uses the ASN.1 BIT STRING data type +and doesn't require any dedicated object. +.Sh RETURN VALUES +.Fn EXTENDED_KEY_USAGE_new +returns the new +.Vt EXTENDED_KEY_USAGE +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr d2i_EXTENDED_KEY_USAGE 3 , +.Xr POLICYINFO_new 3 , +.Xr X509_check_purpose 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get_extension_flags 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.1.3: Key Usage +.It +section 4.2.1.12: Extended Key Usage +.El +.Sh HISTORY +.Fn EXTENDED_KEY_USAGE_new +and +.Fn EXTENDED_KEY_USAGE_free +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/GENERAL_NAME_new.3 b/Libraries/libressl/man/GENERAL_NAME_new.3 new file mode 100644 index 000000000..a6b7ee56d --- /dev/null +++ b/Libraries/libressl/man/GENERAL_NAME_new.3 @@ -0,0 +1,165 @@ +.\" $OpenBSD: GENERAL_NAME_new.3,v 1.6 2019/06/06 01:06:58 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt GENERAL_NAME_NEW 3 +.Os +.Sh NAME +.Nm GENERAL_NAME_new , +.Nm GENERAL_NAME_free , +.Nm GENERAL_NAMES_new , +.Nm GENERAL_NAMES_free , +.Nm EDIPARTYNAME_new , +.Nm EDIPARTYNAME_free , +.Nm OTHERNAME_new , +.Nm OTHERNAME_free +.Nd names for use in X.509 extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft GENERAL_NAME * +.Fn GENERAL_NAME_new void +.Ft void +.Fn GENERAL_NAME_free "GENERAL_NAME *name" +.Ft GENERAL_NAMES * +.Fn GENERAL_NAMES_new void +.Ft void +.Fn GENERAL_NAMES_free "GENERAL_NAMES *names" +.Ft EDIPARTYNAME * +.Fn EDIPARTYNAME_new void +.Ft void +.Fn EDIPARTYNAME_free "EDIPARTYNAME *name" +.Ft OTHERNAME * +.Fn OTHERNAME_new void +.Ft void +.Fn OTHERNAME_free "OTHERNAME *name" +.Sh DESCRIPTION +Even though the X.501 +.Vt Name +documented in +.Xr X509_NAME_new 3 +is a complicated multi-layered structure, it is very rigid and not +flexible enough to represent various entities that many people want +to use as names in certificates. +For that reason, X.509 extensions use the X.509 +.Vt GeneralName +wrapper structure rather than using the X.501 +.Vt Name +structure directly, at the expense of adding one or two additional +layers of indirection. +.Pp +.Fn GENERAL_NAME_new +allocates and initializes an empty +.Vt GENERAL_NAME +object, representing the ASN.1 +.Vt GeneralName +structure defined in RFC 5280 section 4.2.1.6. +It can for example hold an +.Vt X509_name +object, an IP address, a DNS host name, a uniform resource identifier, +an email address, or an +.Vt EDIPARTYNAME +or +.Vt OTHERNAME +object described below. +.Fn GENERAL_NAME_free +frees +.Fa name . +.Pp +.Fn GENERAL_NAMES_new +allocates and initializes an empty +.Vt GENERAL_NAMES +object, which is a +.Vt STACK_OF(GENERAL_NAME) +and represents the ASN.1 +.Vt GeneralNames +structure defined in RFC 5280 section 4.2.1.6. +It is used by extension structures that can contain multiple names, +for example key identifier, alternative name, and distribution point +extensions. +.Fn GENERAL_NAMES_free +frees +.Fa names . +.Pp +.Fn EDIPARTYNAME_new +allocates and initializes an empty +.Vt EDIPARTYNAME +object, representing the ASN.1 +.Vt EDIPartyName +structure defined in RFC 5280 section 4.2.1.6, where +.Dq EDI +stands for +.Dq electronic data identifier . +It can hold two strings, the name itself and the name of the authority +that assigned that name. +.Fn EDIPARTYNAME_free +frees +.Fa name . +.Pp +.Fn OTHERNAME_new +allocates and initializes an empty +.Vt OTHERNAME +object, representing the ASN.1 +.Vt OtherName +structure defined in RFC 5280 section 4.2.1.6. +It can hold data of any +.Vt ASN1_TYPE +together with a type identifier. +.Fn OTHERNAME_free +frees +.Fa name . +.Sh RETURN VALUES +.Fn GENERAL_NAME_new , +.Fn GENERAL_NAMES_new , +.Fn EDIPARTYNAME_new , +and +.Fn OTHERNAME_new +return a new +.Vt GENERAL_NAME , +.Vt GENERAL_NAMES , +.Vt EDIPARTYNAME , +or +.Vt OTHERNAME +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_GENERAL_NAME 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_NAME_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.2: Certificate Extensions +.Sh HISTORY +.Fn GENERAL_NAME_new , +.Fn GENERAL_NAME_free , +.Fn GENERAL_NAMES_new , +and +.Fn GENERAL_NAMES_free +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Pp +.Fn OTHERNAME_new +and +.Fn OTHERNAME_free +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn EDIPARTYNAME_new +and +.Fn EDIPARTYNAME_free +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/HMAC.3 b/Libraries/libressl/man/HMAC.3 new file mode 100644 index 000000000..a0af270c4 --- /dev/null +++ b/Libraries/libressl/man/HMAC.3 @@ -0,0 +1,331 @@ +.\" $OpenBSD: HMAC.3,v 1.20 2022/01/25 17:55:39 tb Exp $ +.\" full merge up to: OpenSSL crypto/hmac a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" selective merge up to: OpenSSL man3/HMAC b3696a55 Sep 2 09:35:50 2017 -0400 +.\" +.\" This file was written by Ulf Moeller , +.\" Richard Levitte , and +.\" Matt Caswell . +.\" Copyright (c) 2000-2002, 2006, 2008, 2009, 2013, 2015, 2016 +.\" The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 25 2022 $ +.Dt HMAC 3 +.Os +.Sh NAME +.Nm HMAC , +.Nm HMAC_CTX_new , +.Nm HMAC_CTX_reset , +.Nm HMAC_CTX_free , +.Nm HMAC_Init_ex , +.Nm HMAC_Init , +.Nm HMAC_Update , +.Nm HMAC_Final , +.Nm HMAC_CTX_copy , +.Nm HMAC_CTX_set_flags , +.Nm HMAC_CTX_get_md , +.Nm HMAC_size +.Nd HMAC message authentication code +.Sh SYNOPSIS +.In openssl/hmac.h +.Ft unsigned char * +.Fo HMAC +.Fa "const EVP_MD *evp_md" +.Fa "const void *key" +.Fa "int key_len" +.Fa "const unsigned char *d" +.Fa "size_t n" +.Fa "unsigned char *md" +.Fa "unsigned int *md_len" +.Fc +.Ft HMAC_CTX * +.Fn HMAC_CTX_new void +.Ft int +.Fo HMAC_CTX_reset +.Fa "HMAC_CTX *ctx" +.Fc +.Ft void +.Fo HMAC_CTX_free +.Fa "HMAC_CTX *ctx" +.Fc +.Ft int +.Fo HMAC_Init_ex +.Fa "HMAC_CTX *ctx" +.Fa "const void *key" +.Fa "int key_len" +.Fa "const EVP_MD *md" +.Fa "ENGINE *impl" +.Fc +.Ft int +.Fo HMAC_Init +.Fa "HMAC_CTX *ctx" +.Fa "const void *key" +.Fa "int key_len" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo HMAC_Update +.Fa "HMAC_CTX *ctx" +.Fa "const unsigned char *data" +.Fa "size_t len" +.Fc +.Ft int +.Fo HMAC_Final +.Fa "HMAC_CTX *ctx" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo HMAC_CTX_copy +.Fa "HMAC_CTX *dctx" +.Fa "HMAC_CTX *sctx" +.Fc +.Ft void +.Fo HMAC_CTX_set_flags +.Fa "HMAC_CTX *ctx" +.Fa "unsigned long flags" +.Fc +.Ft const EVP_MD * +.Fo HMAC_CTX_get_md +.Fa "const HMAC_CTX *ctx" +.Fc +.Ft size_t +.Fo HMAC_size +.Fa "const HMAC_CTX *e" +.Fc +.Sh DESCRIPTION +HMAC is a MAC (message authentication code), i.e. a keyed hash +function used for message authentication, which is based on a hash +function. +.Pp +.Fn HMAC +computes the message authentication code of the +.Fa n +bytes at +.Fa d +using the hash function +.Fa evp_md +and the key +.Fa key +which is +.Fa key_len +bytes long. +.Pp +It places the result in +.Fa md , +which must have space for the output of the hash function, which is no +more than +.Dv EVP_MAX_MD_SIZE +bytes. +If +.Fa md +is +.Dv NULL , +the digest is placed in a static array, which is not thread safe. +The size of the output is placed in +.Fa md_len , +unless it is +.Dv NULL . +.Pp +.Fa evp_md +can be +.Xr EVP_sha1 3 , +.Xr EVP_ripemd160 3 , +etc. +.Pp +.Fn HMAC_CTX_new +allocates and initializes a new +.Vt HMAC_CTX +object. +.Pp +.Fn HMAC_CTX_reset +zeroes and re-initializes +.Fa ctx +and associated resources, making it suitable for new computations +as if it was deleted with +.Fn HMAC_CTX_free +and newly created with +.Fn HMAC_CTX_new . +.Pp +.Fn HMAC_CTX_free +erases the key and other data from +.Fa ctx , +releases any associated resources, and finally frees +.Fa ctx +itself. +.Pp +The following functions may be used if the message is not completely +stored in memory: +.Pp +.Fn HMAC_Init_ex +sets up or reuses +.Fa ctx +to use the hash function +.Fa evp_md +and the key +.Fa key . +Either can be +.Dv NULL , +in which case the existing one is reused. +The +.Fa ctx +must have been created with +.Fn HMAC_CTX_new +before the first use in this function. +If +.Fn HMAC_Init_ex +is called with a +.Dv NULL +.Fa key +but +.Fa evp_md +is neither +.Dv NULL +nor the same as the previous digest used by +.Fa ctx , +then an error is returned because reuse of an existing key with a +different digest is not supported. +.Pp +.Fn HMAC_Init +is a deprecated wrapper around +.Fn HMAC_Init_ex +which performs no longer useful extra initialization in +some circumstances. +.Pp +.Fn HMAC_Update +can be called repeatedly with chunks of the message to be authenticated +.Pq Fa len No bytes at Fa data . +.Pp +.Fn HMAC_Final +places the message authentication code in +.Fa md , +which must have space for the hash function output. +.Pp +.Fn HMAC_CTX_copy +copies all of the internal state from +.Fa sctx +into +.Fa dctx . +.Pp +.Fn HMAC_CTX_set_flags +applies the specified flags to the internal +.Vt EVP_MD_CTX +objects. +Possible flag values +.Dv EVP_MD_CTX_FLAG_* +are defined in +.In openssl/evp.h . +.Pp +.Fn HMAC_size +returns the length in bytes of the underlying hash function output. +It is implemented as a macro. +.Sh RETURN VALUES +.Fn HMAC +returns a pointer to the message authentication code or +.Dv NULL +if an error occurred. +.Pp +.Fn HMAC_CTX_new +returns a pointer to the new +.Vt HMAC_CTX +object or +.Dv NULL +if an error occurred. +.Pp +.Fn HMAC_CTX_reset , +.Fn HMAC_Init_ex , +.Fn HMAC_Update , +.Fn HMAC_Final , +and +.Fn HMAC_CTX_copy +return 1 for success or 0 if an error occurred. +.Pp +.Fn HMAC_CTX_get_md +returns the message digest that was previously set for +.Fa ctx +with +.Fn HMAC_Init_ex , +or +.Dv NULL +if none was set. +.Pp +.Fn HMAC_size +returns the length in bytes of the underlying hash function output +or 0 on error. +.Sh SEE ALSO +.Xr CMAC_Init 3 , +.Xr EVP_DigestInit 3 +.Sh STANDARDS +RFC 2104 +.Sh HISTORY +.Fn HMAC , +.Fn HMAC_Init , +.Fn HMAC_Update , +.Fn HMAC_Final , +and +.Fn HMAC_size +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . +.Pp +.Fn HMAC_Init_ex +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn HMAC_CTX_set_flags +first appeared in OpenSSL 0.9.7f and have been available since +.Ox 3.8 . +.Pp +.Fn HMAC_CTX_copy +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Pp +.Fn HMAC_CTX_new , +.Fn HMAC_CTX_reset , +.Fn HMAC_CTX_free , +and +.Fn HMAC_CTX_get_md +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/IPAddressRange_new.3 b/Libraries/libressl/man/IPAddressRange_new.3 new file mode 100644 index 000000000..a812107cd --- /dev/null +++ b/Libraries/libressl/man/IPAddressRange_new.3 @@ -0,0 +1,525 @@ +.\" $OpenBSD: IPAddressRange_new.3,v 1.9 2023/10/03 09:58:06 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 3 2023 $ +.Dt IPADDRESSRANGE_NEW 3 +.Os +.Sh NAME +.Nm IPAddressRange_new , +.Nm IPAddressRange_free , +.Nm d2i_IPAddressRange , +.Nm i2d_IPAddressRange , +.Nm IPAddressOrRange_new , +.Nm IPAddressOrRange_free , +.Nm d2i_IPAddressOrRange , +.Nm i2d_IPAddressOrRange , +.Nm IPAddressChoice_new , +.Nm IPAddressChoice_free , +.Nm d2i_IPAddressChoice , +.Nm i2d_IPAddressChoice , +.Nm IPAddressFamily_new , +.Nm IPAddressFamily_free , +.Nm d2i_IPAddressFamily , +.Nm i2d_IPAddressFamily +.Nd RFC 3779 IP address prefixes and ranges +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft "IPAddressRange *" +.Fn IPAddressRange_new void +.Ft void +.Fn IPAddressRange_free "IPAddressRange *range" +.Ft IPAddressRange * +.Fo d2i_IPAddressRange +.Fa "IPAddressRange **range" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressRange +.Fa "IPAddressRange *range" +.Fa "unsigned char **der_out" +.Fc +.Ft "IPAddressOrRange *" +.Fn IPAddressOrRange_new void +.Ft void +.Fn IPAddressOrRange_free "IPAddressOrRange *aor" +.Ft IPAddressOrRange * +.Fo d2i_IPAddressOrRange +.Fa "IPAddressOrRange **aor" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressOrRange +.Fa "IPAddressOrRange *aor" +.Fa "unsigned char **der_out" +.Fc +.Ft "IPAddressChoice *" +.Fn IPAddressChoice_new void +.Ft void +.Fn IPAddressChoice_free "IPAddressChoice *ac" +.Ft IPAddressChoice * +.Fo d2i_IPAddressChoice +.Fa "IPAddressChoice **ac" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressChoice +.Fa "IPAddressChoice *ac" +.Fa "unsigned char **der_out" +.Fc +.Ft "IPAddressFamily *" +.Fn IPAddressFamily_new void +.Ft void +.Fn IPAddressFamily_free "IPAddressFamily *af" +.Ft IPAddressFamily * +.Fo d2i_IPAddressFamily +.Fa "IPAddressFamily **af" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressFamily +.Fa "IPAddressFamily *af" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Vt IPAddressRange , +.Vt IPAddressOrRange , +.Vt IPAddressChoice , +and +.Vt IPAddressFamily +are building blocks of the +.Vt IPAddrBlocks +type representing the RFC 3779 IP address delegation extension. +.Pp +Per RFC 3779, section 2.1.1, +an IPv4 or an IPv6 address is encoded in network byte order in an +ASN.1 BIT STRING of bit size 32 or 128 bits, respectively. +The bit size of a prefix is its prefix length; +all insignificant zero bits are omitted +from the encoding. +Per section 2.1.2, +an address range is expressed as a pair of BIT STRINGs +where all the least significant zero bits of the lower bound +and all the least significant one bits of the upper bound are omitted. +.Pp +The library provides no API for directly converting an IP address or +prefix (in any form) to and from an +.Vt ASN1_BIT_STRING . +It also provides no API for directly handling ranges. +The +.Vt ASN1_BIT_STRING +internals are subtle and directly manipulating them in the +context of the RFC 3779 API is discouraged. +The bit size of an +.Vt ASN1_BIT_STRING +representing an IP address prefix or range is eight times its +.Fa length +member minus the lowest three bits of its +.Fa flags , +provided the +.Dv ASN1_STRING_FLAG_BITS_LEFT +flag is set. +.Pp +The +.Vt IPAddressRange +type defined in RFC 3779 section 2.2.3.9 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min; + ASN1_BIT_STRING *max; +} IPAddressRange; +.Ed +.Pp +It represents the closed range [min,max] of IP addresses between +.Fa min +and +.Fa max , +where +.Fa min +should be strictly smaller than +.Fa max +and the range should not be expressible as a prefix. +.Pp +.Fn IPAddressRange_new +allocates a new +.Vt IPAddressRange +object with allocated, empty +.Fa min +and +.Fa max , +thus representing the entire address space invalidly as a non-prefix. +.Pp +.Fn IPAddressRange_free +frees +.Fa range +including any data contained in it. +If +.Fa range +is +.Dv NULL , +no action occurs. +.Pp +There is no dedicated type representing the +.Vt IPAddress +type defined in RFC 3779 section 2.2.3.8. +The API uses +.Vt ASN1_BIT_STRING +for this. +.Pp +The +.Vt IPAddressOrRange +type defined in RFC 3779 section 2.2.3.7 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; +.Ed +.Pp +representing an individual address prefix or an address range. +The +.Fa type +member should be set to +.Dv IPAddressOrRange_addressPrefix +or +.Dv IPAddressOrRange_addressRange +to indicate which member of the union +.Fa u +is valid. +.Pp +.Fn IPAddressOrRange_new +returns a new +.Vt IPAddressOrRange +object with invalid type and +.Dv NULL +members of the union +.Fa u . +.Pp +.Fn IPAddressOrRange_free +frees +.Fa aor +including any data contained in it, +provided +.Fa type +is set correctly. +If +.Fa aor +is +.Dv NULL , +no action occurs. +.Pp +In order to express a list of address prefixes and address ranges, +RFC 3779 section 2.2.3.6 +uses an ASN.1 SEQUENCE, +which is implemented via a +.Xr STACK_OF 3 +construction over +.Vt IPAddressOrRange : +.Bd -literal -offset indent +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +.Ed +.Pp +Since an +.Vt IPAddressOrRanges +object should be sorted in a specific way (see +.Xr X509v3_addr_canonize 3 ) , +a comparison function is needed for a correct instantiation +with +.Xr sk_new 3 . +The +.Fn v4IPAddressOrRange_cmp +and +.Fn v6IPAddressOrRange_cmp +functions are not directly exposed and not easily accessible +from outside the library, +and they are non-trivial to implement. +It is therefore discouraged to use +.Vt IPAddressOrRanges +objects that are not part of an +.Vt IPAddrBlocks +object. +.Pp +The +.Dq inherit +marker from RFC 3779 section 2.2.3.5 is implemented as +.Vt ASN1_NULL . +It has no dedicated type or API and can be instantiated with +.Xr ASN1_NULL_new 3 . +.Pp +The +.Vt IPAddressChoice +type defined in RFC 3779 section 2.2.3.4 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; +.Ed +.Pp +where the +.Fa type +member should be set to +.Dv IPAddressChoice_inherit +or +.Dv IPAddressChoice_addressesOrRanges +to indicate whether a given +.Vt IPAddressChoice +object represents an inherited list or an explicit list. +.Pp +.Fn IPAddressChoice_new +returns a new +.Vt IPAddressChoice +object with invalid type and +.Dv NULL +members of the union +.Fa u . +.Pp +.Fn IPAddressChoice_free +frees +.Fa ac +including any data contained in it, +provided +.Fa type +is set correctly. +.Pp +The +.Fa addressFamily +element defined in RFC 3779 section 2.2.3.3 is implemented as an +.Vt ASN1_OCTET_STRING +and it contains two or three octets. +The first two octets are always present and represent the +address family identifier (AFI) +in network byte order. +The optional subsequent address family identifier (SAFI) +occupies the third octet. +For IPv4 and IPv6, +.Dv IANA_AFI_IPV4 +and +.Dv IANA_AFI_IPV6 +are predefined. +Other AFIs are not supported by this implementation. +.Pp +The +.Vt IPAddressFamily +type defined in RFC 3779 section 2.2.3.2 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; +.Ed +.Pp +The +.Fa addressFamily +member indicates the address family the +.Fa ipAddressChoice +represents. +.Pp +.Fn IPAddressFamily_new +returns a new +.Vt IPAddressFamily +object with empty +.Fa addressFamily +and invalid +.Fa ipAddressChoice +members. +.Pp +.Fn IPAddressFamily_free +frees +.Fa af +including any data contained in it. +If +.Fa af +is +.Dv NULL , +no action occurs. +.Pp +The +.Vt IPAddrBlocks +type defined in RFC 3779 section 2.2.3.1 +uses an ASN.1 SEQUENCE, +which is implemented via a +.Xr STACK_OF 3 +construction over +.Vt IPAddressFamily : +.Bd -literal -offset indent +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +.Ed +.Pp +It can be instantiated with +.Fn sk_IPAddressFamily_new_null +and the correct sorting function can be installed with +.Xr X509v3_addr_canonize 3 . +To populate it, use +.Xr X509v3_addr_add_prefix 3 +and related functions. +.Pp +.Fn d2i_IPAddressRange , +.Fn i2d_IPAddressRange , +.Fn d2i_IPAddressOrRange , +.Fn i2d_IPAddressOrRange , +.Fn d2i_IPAddressChoice , +.Fn i2d_IPAddressChoice , +.Fn d2i_IPAddressFamily , +and +.Fn i2d_IPAddressFamily +decode and encode ASN.1 +.Vt IPAddressRange , +.Vt IPAddressOrRange , +.Vt IPAddressChoice , +and +.Vt IPAddressFamily +objects. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +There is no easy way of ensuring that the encodings generated by +these functions are correct, unless they are applied to objects +that are part of a canonical +.Vt IPAddrBlocks +structure, see +.Xr X509v3_addr_is_canonical 3 . +.Sh RETURN VALUES +.Fn IPAddressRange_new +returns a new +.Vt IPAddressRange +object with allocated, empty members, or +.Dv NULL +if an error occurs. +.Pp +.Fn IPAddressOrRange_new +returns a new, empty +.Vt IPAddressOrRange +object or +.Dv NULL +if an error occurs. +.Pp +.Fn IPAddressChoice_new +returns a new, empty +.Vt IPAddressChoice +object or +.Dv NULL +if an error occurs. +.Pp +.Fn IPAddressFamily_new +returns a new +.Vt IPAddressFamily +object with allocated, empty members, or +.Dv NULL +if an error occurs. +.Pp +The decoding functions +.Fn d2i_IPAddressRange , +.Fn d2i_IPAddressOrRange , +.Fn d2i_IPAddressChoice , +and +.Fn d2i_IPAddressFamily +return an +.Vt IPAddressRange , +an +.Vt IPAddressOrRange , +an +.Vt IPAddressChoice , +or an +.Vt IPAddressFamily +object, respectively, +or +.Dv NULL +if an error occurs. +.Pp +The encoding functions +.Fn i2d_IPAddressRange , +.Fn i2d_IPAddressOrRange , +.Fn i2d_IPAddressChoice , +and +.Fn i2d_IPAddressFamily +return the number of bytes successfully encoded +or a value <= 0 if an error occurs. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr ASN1_BIT_STRING_new 3 , +.Xr ASN1_OCTET_STRING_new 3 , +.Xr ASN1_OCTET_STRING_set 3 , +.Xr crypto 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_addr_inherits 3 , +.Xr X509v3_addr_subset 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 2.1.1: Encoding of an IP Address or Prefix +.It +section 2.1.2: Encoding of a Range of IP Addresses +.It +section 2.2.3: Syntax +.It +section 2.2.3.1: Type IPAddrBlocks +.It +section 2.2.3.2: Type IPAddressFamily +.It +section 2.2.3.3: Element addressFamily +.It +section 2.2.3.4: Element ipAddressChoice and Type IPAddressChoice +.It +section 2.2.3.5: Element inherit +.It +section 2.2.3.6: Element addressesOrRanges +.It +section 2.2.3.7: Type IPAddressOrRange +.It +section 2.2.3.8: Element addressPrefix and Type IPAddress +.It +section 2.2.3.9: Element addressRange and Type IPAddressRange +.El +.Pp +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.6: Encoding of a bitstring value +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +.\" The internals do not seem to consistently apply and check +.\" .Dv ASN1_STRING_FLAG_BITS_LEFT +.\" which may lead to incorrect encoding and misinterpretation +As it stands, the API is barely usable +due to missing convenience accessors, constructors and destructors +and due to the complete absence of API that checks that the +individual building blocks are correct. +Extracting information from a given object can be done relatively +safely. +However, constructing objects is very error prone, be it +by hand or using the bug-ridden +.Xr X509v3_addr_add_inherit 3 +API. +.Pp +RFC 3779 has element +.Dq addressesOrRanges . +Its type in this API is +.Vt IPAddressOrRanges . diff --git a/Libraries/libressl/man/MD5.3 b/Libraries/libressl/man/MD5.3 new file mode 100644 index 000000000..1e4a62859 --- /dev/null +++ b/Libraries/libressl/man/MD5.3 @@ -0,0 +1,196 @@ +.\" $OpenBSD: MD5.3,v 1.8 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller and +.\" Richard Levitte . +.\" Copyright (c) 2000, 2006 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt MD5 3 +.Os +.Sh NAME +.Nm MD4 , +.Nm MD5 , +.Nm MD4_Init , +.Nm MD4_Update , +.Nm MD4_Final , +.Nm MD5_Init , +.Nm MD5_Update , +.Nm MD5_Final +.Nd MD4 and MD5 hash functions +.Sh SYNOPSIS +.In openssl/md4.h +.Ft unsigned char * +.Fo MD4 +.Fa "const unsigned char *d" +.Fa "unsigned long n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo MD4_Init +.Fa "MD4_CTX *c" +.Fc +.Ft int +.Fo MD4_Update +.Fa "MD4_CTX *c" +.Fa "const void *data" +.Fa "unsigned long len" +.Fc +.Ft int +.Fo MD4_Final +.Fa "unsigned char *md" +.Fa "MD4_CTX *c" +.Fc +.In openssl/md5.h +.Ft unsigned char * +.Fo MD5 +.Fa "const unsigned char *d" +.Fa "unsigned long n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo MD5_Init +.Fa "MD5_CTX *c" +.Fc +.Ft int +.Fo MD5_Update +.Fa "MD5_CTX *c" +.Fa "const void *data" +.Fa "unsigned long len" +.Fc +.Ft int +.Fo MD5_Final +.Fa "unsigned char *md" +.Fa "MD5_CTX *c" +.Fc +.Sh DESCRIPTION +MD4 and MD5 are cryptographic hash functions with a 128-bit +output. +.Pp +.Fn MD4 +and +.Fn MD5 +compute the MD4 and MD5 message digest of the +.Fa n +bytes at +.Fa d +and place it in +.Fa md , +which must have space for +.Dv MD4_DIGEST_LENGTH No == Dv MD5_DIGEST_LENGTH No == 16 +bytes of output. +If +.Fa md +is +.Dv NULL , +the digest is placed in a static array. +.Pp +The following functions may be used if the message is not completely +stored in memory: +.Pp +.Fn MD5_Init +initializes a +.Vt MD5_CTX +structure. +.Pp +.Fn MD5_Update +can be called repeatedly with chunks of the message to be hashed +.Pq Fa len No bytes at Fa data . +.Pp +.Fn MD5_Final +places the message digest in +.Fa md , +which must have space for +.Dv MD5_DIGEST_LENGTH No == 16 +bytes of output, and erases the +.Vt MD5_CTX . +.Pp +.Fn MD4_Init , +.Fn MD4_Update , +and +.Fn MD4_Final +are analogous using an +.Vt MD4_CTX +structure. +.Pp +Applications should use the higher level functions +.Xr EVP_DigestInit 3 +etc. instead of calling these hash functions directly. +.Sh RETURN VALUES +.Fn MD4 +and +.Fn MD5 +return pointers to the hash value. +.Pp +.Fn MD4_Init , +.Fn MD4_Update , +.Fn MD4_Final , +.Fn MD5_Init , +.Fn MD5_Update , +and +.Fn MD5_Final +return 1 for success or 0 otherwise. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 +.Sh STANDARDS +RFC 1320, RFC 1321 +.Sh HISTORY +.Fn MD5 , +.Fn MD5_Init , +.Fn MD5_Update , +and +.Fn MD5_Final +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Pp +.Fn MD4 , +.Fn MD4_Init , +.Fn MD4_Update , +and +.Fn MD4_Final +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/Makefile.am b/Libraries/libressl/man/Makefile.am new file mode 100644 index 000000000..7c7bb1a87 --- /dev/null +++ b/Libraries/libressl/man/Makefile.am @@ -0,0 +1,6543 @@ +EXTRA_DIST = CMakeLists.txt +if !ENABLE_LIBTLS_ONLY +dist_man3_MANS = +dist_man5_MANS = +dist_man3_MANS += BIO_f_ssl.3 +dist_man3_MANS += DTLSv1_listen.3 +dist_man3_MANS += OPENSSL_init_ssl.3 +dist_man3_MANS += PEM_read_SSL_SESSION.3 +dist_man3_MANS += SSL_CIPHER_get_name.3 +dist_man3_MANS += SSL_COMP_add_compression_method.3 +dist_man3_MANS += SSL_CTX_add1_chain_cert.3 +dist_man3_MANS += SSL_CTX_add_extra_chain_cert.3 +dist_man3_MANS += SSL_CTX_add_session.3 +dist_man3_MANS += SSL_CTX_ctrl.3 +dist_man3_MANS += SSL_CTX_flush_sessions.3 +dist_man3_MANS += SSL_CTX_free.3 +dist_man3_MANS += SSL_CTX_get0_certificate.3 +dist_man3_MANS += SSL_CTX_get_ex_new_index.3 +dist_man3_MANS += SSL_CTX_get_verify_mode.3 +dist_man3_MANS += SSL_CTX_load_verify_locations.3 +dist_man3_MANS += SSL_CTX_new.3 +dist_man3_MANS += SSL_CTX_sess_number.3 +dist_man3_MANS += SSL_CTX_sess_set_cache_size.3 +dist_man3_MANS += SSL_CTX_sess_set_get_cb.3 +dist_man3_MANS += SSL_CTX_sessions.3 +dist_man3_MANS += SSL_CTX_set1_groups.3 +dist_man3_MANS += SSL_CTX_set_alpn_select_cb.3 +dist_man3_MANS += SSL_CTX_set_cert_store.3 +dist_man3_MANS += SSL_CTX_set_cert_verify_callback.3 +dist_man3_MANS += SSL_CTX_set_cipher_list.3 +dist_man3_MANS += SSL_CTX_set_client_CA_list.3 +dist_man3_MANS += SSL_CTX_set_client_cert_cb.3 +dist_man3_MANS += SSL_CTX_set_default_passwd_cb.3 +dist_man3_MANS += SSL_CTX_set_generate_session_id.3 +dist_man3_MANS += SSL_CTX_set_info_callback.3 +dist_man3_MANS += SSL_CTX_set_keylog_callback.3 +dist_man3_MANS += SSL_CTX_set_max_cert_list.3 +dist_man3_MANS += SSL_CTX_set_min_proto_version.3 +dist_man3_MANS += SSL_CTX_set_mode.3 +dist_man3_MANS += SSL_CTX_set_msg_callback.3 +dist_man3_MANS += SSL_CTX_set_num_tickets.3 +dist_man3_MANS += SSL_CTX_set_options.3 +dist_man3_MANS += SSL_CTX_set_quiet_shutdown.3 +dist_man3_MANS += SSL_CTX_set_read_ahead.3 +dist_man3_MANS += SSL_CTX_set_security_level.3 +dist_man3_MANS += SSL_CTX_set_session_cache_mode.3 +dist_man3_MANS += SSL_CTX_set_session_id_context.3 +dist_man3_MANS += SSL_CTX_set_ssl_version.3 +dist_man3_MANS += SSL_CTX_set_timeout.3 +dist_man3_MANS += SSL_CTX_set_tlsext_servername_callback.3 +dist_man3_MANS += SSL_CTX_set_tlsext_status_cb.3 +dist_man3_MANS += SSL_CTX_set_tlsext_ticket_key_cb.3 +dist_man3_MANS += SSL_CTX_set_tlsext_use_srtp.3 +dist_man3_MANS += SSL_CTX_set_tmp_dh_callback.3 +dist_man3_MANS += SSL_CTX_set_tmp_rsa_callback.3 +dist_man3_MANS += SSL_CTX_set_verify.3 +dist_man3_MANS += SSL_CTX_use_certificate.3 +dist_man3_MANS += SSL_SESSION_free.3 +dist_man3_MANS += SSL_SESSION_get0_cipher.3 +dist_man3_MANS += SSL_SESSION_get0_peer.3 +dist_man3_MANS += SSL_SESSION_get_compress_id.3 +dist_man3_MANS += SSL_SESSION_get_ex_new_index.3 +dist_man3_MANS += SSL_SESSION_get_id.3 +dist_man3_MANS += SSL_SESSION_get_protocol_version.3 +dist_man3_MANS += SSL_SESSION_get_time.3 +dist_man3_MANS += SSL_SESSION_has_ticket.3 +dist_man3_MANS += SSL_SESSION_is_resumable.3 +dist_man3_MANS += SSL_SESSION_new.3 +dist_man3_MANS += SSL_SESSION_print.3 +dist_man3_MANS += SSL_SESSION_set1_id_context.3 +dist_man3_MANS += SSL_accept.3 +dist_man3_MANS += SSL_alert_type_string.3 +dist_man3_MANS += SSL_clear.3 +dist_man3_MANS += SSL_connect.3 +dist_man3_MANS += SSL_copy_session_id.3 +dist_man3_MANS += SSL_do_handshake.3 +dist_man3_MANS += SSL_dup.3 +dist_man3_MANS += SSL_dup_CA_list.3 +dist_man3_MANS += SSL_export_keying_material.3 +dist_man3_MANS += SSL_free.3 +dist_man3_MANS += SSL_get_SSL_CTX.3 +dist_man3_MANS += SSL_get_certificate.3 +dist_man3_MANS += SSL_get_ciphers.3 +dist_man3_MANS += SSL_get_client_CA_list.3 +dist_man3_MANS += SSL_get_client_random.3 +dist_man3_MANS += SSL_get_current_cipher.3 +dist_man3_MANS += SSL_get_default_timeout.3 +dist_man3_MANS += SSL_get_error.3 +dist_man3_MANS += SSL_get_ex_data_X509_STORE_CTX_idx.3 +dist_man3_MANS += SSL_get_ex_new_index.3 +dist_man3_MANS += SSL_get_fd.3 +dist_man3_MANS += SSL_get_finished.3 +dist_man3_MANS += SSL_get_peer_cert_chain.3 +dist_man3_MANS += SSL_get_peer_certificate.3 +dist_man3_MANS += SSL_get_rbio.3 +dist_man3_MANS += SSL_get_server_tmp_key.3 +dist_man3_MANS += SSL_get_session.3 +dist_man3_MANS += SSL_get_shared_ciphers.3 +dist_man3_MANS += SSL_get_state.3 +dist_man3_MANS += SSL_get_verify_result.3 +dist_man3_MANS += SSL_get_version.3 +dist_man3_MANS += SSL_library_init.3 +dist_man3_MANS += SSL_load_client_CA_file.3 +dist_man3_MANS += SSL_new.3 +dist_man3_MANS += SSL_num_renegotiations.3 +dist_man3_MANS += SSL_pending.3 +dist_man3_MANS += SSL_read.3 +dist_man3_MANS += SSL_read_early_data.3 +dist_man3_MANS += SSL_renegotiate.3 +dist_man3_MANS += SSL_rstate_string.3 +dist_man3_MANS += SSL_session_reused.3 +dist_man3_MANS += SSL_set1_host.3 +dist_man3_MANS += SSL_set1_param.3 +dist_man3_MANS += SSL_set_SSL_CTX.3 +dist_man3_MANS += SSL_set_bio.3 +dist_man3_MANS += SSL_set_connect_state.3 +dist_man3_MANS += SSL_set_fd.3 +dist_man3_MANS += SSL_set_max_send_fragment.3 +dist_man3_MANS += SSL_set_psk_use_session_callback.3 +dist_man3_MANS += SSL_set_session.3 +dist_man3_MANS += SSL_set_shutdown.3 +dist_man3_MANS += SSL_set_tmp_ecdh.3 +dist_man3_MANS += SSL_set_verify_result.3 +dist_man3_MANS += SSL_shutdown.3 +dist_man3_MANS += SSL_state_string.3 +dist_man3_MANS += SSL_want.3 +dist_man3_MANS += SSL_write.3 +dist_man3_MANS += d2i_SSL_SESSION.3 +dist_man3_MANS += ssl.3 +dist_man3_MANS += ACCESS_DESCRIPTION_new.3 +dist_man3_MANS += AES_encrypt.3 +dist_man3_MANS += ASIdentifiers_new.3 +dist_man3_MANS += ASN1_BIT_STRING_set.3 +dist_man3_MANS += ASN1_INTEGER_get.3 +dist_man3_MANS += ASN1_NULL_new.3 +dist_man3_MANS += ASN1_OBJECT_new.3 +dist_man3_MANS += ASN1_PRINTABLE_type.3 +dist_man3_MANS += ASN1_STRING_TABLE_add.3 +dist_man3_MANS += ASN1_STRING_length.3 +dist_man3_MANS += ASN1_STRING_new.3 +dist_man3_MANS += ASN1_STRING_print_ex.3 +dist_man3_MANS += ASN1_TIME_set.3 +dist_man3_MANS += ASN1_TYPE_get.3 +dist_man3_MANS += ASN1_UNIVERSALSTRING_to_string.3 +dist_man3_MANS += ASN1_generate_nconf.3 +dist_man3_MANS += ASN1_get_object.3 +dist_man3_MANS += ASN1_item_d2i.3 +dist_man3_MANS += ASN1_item_digest.3 +dist_man3_MANS += ASN1_item_new.3 +dist_man3_MANS += ASN1_item_pack.3 +dist_man3_MANS += ASN1_item_sign.3 +dist_man3_MANS += ASN1_item_verify.3 +dist_man3_MANS += ASN1_mbstring_copy.3 +dist_man3_MANS += ASN1_parse_dump.3 +dist_man3_MANS += ASN1_put_object.3 +dist_man3_MANS += ASN1_time_parse.3 +dist_man3_MANS += ASRange_new.3 +dist_man3_MANS += AUTHORITY_KEYID_new.3 +dist_man3_MANS += BASIC_CONSTRAINTS_new.3 +dist_man3_MANS += BF_set_key.3 +dist_man3_MANS += BIO_accept.3 +dist_man3_MANS += BIO_ctrl.3 +dist_man3_MANS += BIO_dump.3 +dist_man3_MANS += BIO_dup_chain.3 +dist_man3_MANS += BIO_f_base64.3 +dist_man3_MANS += BIO_f_buffer.3 +dist_man3_MANS += BIO_f_cipher.3 +dist_man3_MANS += BIO_f_md.3 +dist_man3_MANS += BIO_f_null.3 +dist_man3_MANS += BIO_find_type.3 +dist_man3_MANS += BIO_get_data.3 +dist_man3_MANS += BIO_get_ex_new_index.3 +dist_man3_MANS += BIO_meth_new.3 +dist_man3_MANS += BIO_new.3 +dist_man3_MANS += BIO_new_CMS.3 +dist_man3_MANS += BIO_printf.3 +dist_man3_MANS += BIO_push.3 +dist_man3_MANS += BIO_read.3 +dist_man3_MANS += BIO_s_accept.3 +dist_man3_MANS += BIO_s_bio.3 +dist_man3_MANS += BIO_s_connect.3 +dist_man3_MANS += BIO_s_datagram.3 +dist_man3_MANS += BIO_s_fd.3 +dist_man3_MANS += BIO_s_file.3 +dist_man3_MANS += BIO_s_mem.3 +dist_man3_MANS += BIO_s_null.3 +dist_man3_MANS += BIO_s_socket.3 +dist_man3_MANS += BIO_set_callback.3 +dist_man3_MANS += BIO_should_retry.3 +dist_man3_MANS += BN_CTX_new.3 +dist_man3_MANS += BN_CTX_start.3 +dist_man3_MANS += BN_add.3 +dist_man3_MANS += BN_add_word.3 +dist_man3_MANS += BN_bn2bin.3 +dist_man3_MANS += BN_cmp.3 +dist_man3_MANS += BN_copy.3 +dist_man3_MANS += BN_generate_prime.3 +dist_man3_MANS += BN_get_rfc3526_prime_8192.3 +dist_man3_MANS += BN_kronecker.3 +dist_man3_MANS += BN_mod_inverse.3 +dist_man3_MANS += BN_mod_mul_montgomery.3 +dist_man3_MANS += BN_mod_sqrt.3 +dist_man3_MANS += BN_new.3 +dist_man3_MANS += BN_num_bytes.3 +dist_man3_MANS += BN_rand.3 +dist_man3_MANS += BN_set_bit.3 +dist_man3_MANS += BN_set_flags.3 +dist_man3_MANS += BN_set_negative.3 +dist_man3_MANS += BN_swap.3 +dist_man3_MANS += BN_zero.3 +dist_man3_MANS += BUF_MEM_new.3 +dist_man3_MANS += CMAC_Init.3 +dist_man3_MANS += CMS_ContentInfo_new.3 +dist_man3_MANS += CMS_add0_cert.3 +dist_man3_MANS += CMS_add1_recipient_cert.3 +dist_man3_MANS += CMS_add1_signer.3 +dist_man3_MANS += CMS_compress.3 +dist_man3_MANS += CMS_decrypt.3 +dist_man3_MANS += CMS_encrypt.3 +dist_man3_MANS += CMS_final.3 +dist_man3_MANS += CMS_get0_RecipientInfos.3 +dist_man3_MANS += CMS_get0_SignerInfos.3 +dist_man3_MANS += CMS_get0_type.3 +dist_man3_MANS += CMS_get1_ReceiptRequest.3 +dist_man3_MANS += CMS_sign.3 +dist_man3_MANS += CMS_sign_receipt.3 +dist_man3_MANS += CMS_uncompress.3 +dist_man3_MANS += CMS_verify.3 +dist_man3_MANS += CMS_verify_receipt.3 +dist_man3_MANS += CONF_modules_free.3 +dist_man3_MANS += CONF_modules_load_file.3 +dist_man3_MANS += CRYPTO_get_mem_functions.3 +dist_man3_MANS += CRYPTO_lock.3 +dist_man3_MANS += CRYPTO_memcmp.3 +dist_man3_MANS += CRYPTO_set_ex_data.3 +dist_man3_MANS += ChaCha.3 +dist_man3_MANS += DES_set_key.3 +dist_man3_MANS += DH_generate_key.3 +dist_man3_MANS += DH_generate_parameters.3 +dist_man3_MANS += DH_get0_pqg.3 +dist_man3_MANS += DH_get_ex_new_index.3 +dist_man3_MANS += DH_new.3 +dist_man3_MANS += DH_set_method.3 +dist_man3_MANS += DH_size.3 +dist_man3_MANS += DIST_POINT_new.3 +dist_man3_MANS += DSA_SIG_new.3 +dist_man3_MANS += DSA_do_sign.3 +dist_man3_MANS += DSA_dup_DH.3 +dist_man3_MANS += DSA_generate_key.3 +dist_man3_MANS += DSA_generate_parameters.3 +dist_man3_MANS += DSA_get0_pqg.3 +dist_man3_MANS += DSA_get_ex_new_index.3 +dist_man3_MANS += DSA_meth_new.3 +dist_man3_MANS += DSA_new.3 +dist_man3_MANS += DSA_set_method.3 +dist_man3_MANS += DSA_sign.3 +dist_man3_MANS += DSA_size.3 +dist_man3_MANS += ECDH_compute_key.3 +dist_man3_MANS += ECDSA_SIG_new.3 +dist_man3_MANS += EC_GFp_simple_method.3 +dist_man3_MANS += EC_GROUP_copy.3 +dist_man3_MANS += EC_GROUP_new.3 +dist_man3_MANS += EC_KEY_METHOD_new.3 +dist_man3_MANS += EC_KEY_new.3 +dist_man3_MANS += EC_POINT_add.3 +dist_man3_MANS += EC_POINT_new.3 +dist_man3_MANS += ENGINE_add.3 +dist_man3_MANS += ENGINE_ctrl.3 +dist_man3_MANS += ENGINE_get_default_RSA.3 +dist_man3_MANS += ENGINE_init.3 +dist_man3_MANS += ENGINE_new.3 +dist_man3_MANS += ENGINE_register_RSA.3 +dist_man3_MANS += ENGINE_register_all_RSA.3 +dist_man3_MANS += ENGINE_set_RSA.3 +dist_man3_MANS += ENGINE_set_default.3 +dist_man3_MANS += ENGINE_set_flags.3 +dist_man3_MANS += ENGINE_unregister_RSA.3 +dist_man3_MANS += ERR.3 +dist_man3_MANS += ERR_GET_LIB.3 +dist_man3_MANS += ERR_asprintf_error_data.3 +dist_man3_MANS += ERR_clear_error.3 +dist_man3_MANS += ERR_error_string.3 +dist_man3_MANS += ERR_get_error.3 +dist_man3_MANS += ERR_load_crypto_strings.3 +dist_man3_MANS += ERR_load_strings.3 +dist_man3_MANS += ERR_print_errors.3 +dist_man3_MANS += ERR_put_error.3 +dist_man3_MANS += ERR_remove_state.3 +dist_man3_MANS += ERR_set_mark.3 +dist_man3_MANS += ESS_SIGNING_CERT_new.3 +dist_man3_MANS += EVP_AEAD_CTX_init.3 +dist_man3_MANS += EVP_BytesToKey.3 +dist_man3_MANS += EVP_CIPHER_CTX_ctrl.3 +dist_man3_MANS += EVP_CIPHER_CTX_get_cipher_data.3 +dist_man3_MANS += EVP_CIPHER_CTX_set_flags.3 +dist_man3_MANS += EVP_CIPHER_do_all.3 +dist_man3_MANS += EVP_CIPHER_meth_new.3 +dist_man3_MANS += EVP_CIPHER_nid.3 +dist_man3_MANS += EVP_DigestInit.3 +dist_man3_MANS += EVP_DigestSignInit.3 +dist_man3_MANS += EVP_DigestVerifyInit.3 +dist_man3_MANS += EVP_EncodeInit.3 +dist_man3_MANS += EVP_EncryptInit.3 +dist_man3_MANS += EVP_MD_CTX_ctrl.3 +dist_man3_MANS += EVP_MD_meth_new.3 +dist_man3_MANS += EVP_MD_nid.3 +dist_man3_MANS += EVP_OpenInit.3 +dist_man3_MANS += EVP_PKCS82PKEY.3 +dist_man3_MANS += EVP_PKEY_CTX_ctrl.3 +dist_man3_MANS += EVP_PKEY_CTX_get_operation.3 +dist_man3_MANS += EVP_PKEY_CTX_new.3 +dist_man3_MANS += EVP_PKEY_CTX_set_hkdf_md.3 +dist_man3_MANS += EVP_PKEY_add1_attr.3 +dist_man3_MANS += EVP_PKEY_asn1_get_count.3 +dist_man3_MANS += EVP_PKEY_asn1_new.3 +dist_man3_MANS += EVP_PKEY_check.3 +dist_man3_MANS += EVP_PKEY_cmp.3 +dist_man3_MANS += EVP_PKEY_decrypt.3 +dist_man3_MANS += EVP_PKEY_derive.3 +dist_man3_MANS += EVP_PKEY_encrypt.3 +dist_man3_MANS += EVP_PKEY_get_default_digest_nid.3 +dist_man3_MANS += EVP_PKEY_keygen.3 +dist_man3_MANS += EVP_PKEY_meth_get0_info.3 +dist_man3_MANS += EVP_PKEY_meth_new.3 +dist_man3_MANS += EVP_PKEY_new.3 +dist_man3_MANS += EVP_PKEY_print_private.3 +dist_man3_MANS += EVP_PKEY_set1_RSA.3 +dist_man3_MANS += EVP_PKEY_sign.3 +dist_man3_MANS += EVP_PKEY_size.3 +dist_man3_MANS += EVP_PKEY_verify.3 +dist_man3_MANS += EVP_PKEY_verify_recover.3 +dist_man3_MANS += EVP_SealInit.3 +dist_man3_MANS += EVP_SignInit.3 +dist_man3_MANS += EVP_VerifyInit.3 +dist_man3_MANS += EVP_add_cipher.3 +dist_man3_MANS += EVP_aes_128_cbc.3 +dist_man3_MANS += EVP_camellia_128_cbc.3 +dist_man3_MANS += EVP_chacha20.3 +dist_man3_MANS += EVP_des_cbc.3 +dist_man3_MANS += EVP_rc4.3 +dist_man3_MANS += EVP_sha1.3 +dist_man3_MANS += EVP_sha3_224.3 +dist_man3_MANS += EVP_sm3.3 +dist_man3_MANS += EVP_sm4_cbc.3 +dist_man3_MANS += EVP_whirlpool.3 +dist_man3_MANS += EXTENDED_KEY_USAGE_new.3 +dist_man3_MANS += GENERAL_NAME_new.3 +dist_man3_MANS += HMAC.3 +dist_man3_MANS += IPAddressRange_new.3 +dist_man3_MANS += MD5.3 +dist_man3_MANS += NAME_CONSTRAINTS_new.3 +dist_man3_MANS += OBJ_NAME_add.3 +dist_man3_MANS += OBJ_create.3 +dist_man3_MANS += OBJ_find_sigid_algs.3 +dist_man3_MANS += OBJ_nid2obj.3 +dist_man3_MANS += OCSP_CRLID_new.3 +dist_man3_MANS += OCSP_REQUEST_new.3 +dist_man3_MANS += OCSP_SERVICELOC_new.3 +dist_man3_MANS += OCSP_cert_to_id.3 +dist_man3_MANS += OCSP_request_add1_nonce.3 +dist_man3_MANS += OCSP_resp_find_status.3 +dist_man3_MANS += OCSP_response_status.3 +dist_man3_MANS += OCSP_sendreq_new.3 +dist_man3_MANS += OPENSSL_VERSION_NUMBER.3 +dist_man3_MANS += OPENSSL_cleanse.3 +dist_man3_MANS += OPENSSL_config.3 +dist_man3_MANS += OPENSSL_init_crypto.3 +dist_man3_MANS += OPENSSL_load_builtin_modules.3 +dist_man3_MANS += OPENSSL_malloc.3 +dist_man3_MANS += OPENSSL_sk_new.3 +dist_man3_MANS += OpenSSL_add_all_algorithms.3 +dist_man3_MANS += PEM_ASN1_read.3 +dist_man3_MANS += PEM_X509_INFO_read.3 +dist_man3_MANS += PEM_bytes_read_bio.3 +dist_man3_MANS += PEM_read.3 +dist_man3_MANS += PEM_read_bio_PrivateKey.3 +dist_man3_MANS += PEM_write_bio_CMS_stream.3 +dist_man3_MANS += PEM_write_bio_PKCS7_stream.3 +dist_man3_MANS += PKCS12_SAFEBAG_new.3 +dist_man3_MANS += PKCS12_create.3 +dist_man3_MANS += PKCS12_new.3 +dist_man3_MANS += PKCS12_newpass.3 +dist_man3_MANS += PKCS12_parse.3 +dist_man3_MANS += PKCS5_PBKDF2_HMAC.3 +dist_man3_MANS += PKCS7_add_attribute.3 +dist_man3_MANS += PKCS7_dataFinal.3 +dist_man3_MANS += PKCS7_dataInit.3 +dist_man3_MANS += PKCS7_decrypt.3 +dist_man3_MANS += PKCS7_encrypt.3 +dist_man3_MANS += PKCS7_final.3 +dist_man3_MANS += PKCS7_get_signer_info.3 +dist_man3_MANS += PKCS7_new.3 +dist_man3_MANS += PKCS7_set_content.3 +dist_man3_MANS += PKCS7_set_type.3 +dist_man3_MANS += PKCS7_sign.3 +dist_man3_MANS += PKCS7_sign_add_signer.3 +dist_man3_MANS += PKCS7_verify.3 +dist_man3_MANS += PKCS8_PRIV_KEY_INFO_new.3 +dist_man3_MANS += PKCS8_pkey_set0.3 +dist_man3_MANS += PKEY_USAGE_PERIOD_new.3 +dist_man3_MANS += POLICYINFO_new.3 +dist_man3_MANS += RAND_add.3 +dist_man3_MANS += RAND_bytes.3 +dist_man3_MANS += RAND_load_file.3 +dist_man3_MANS += RAND_set_rand_method.3 +dist_man3_MANS += RC4.3 +dist_man3_MANS += RIPEMD160.3 +dist_man3_MANS += RSA_PSS_PARAMS_new.3 +dist_man3_MANS += RSA_blinding_on.3 +dist_man3_MANS += RSA_check_key.3 +dist_man3_MANS += RSA_generate_key.3 +dist_man3_MANS += RSA_get0_key.3 +dist_man3_MANS += RSA_get_ex_new_index.3 +dist_man3_MANS += RSA_meth_new.3 +dist_man3_MANS += RSA_new.3 +dist_man3_MANS += RSA_padding_add_PKCS1_type_1.3 +dist_man3_MANS += RSA_pkey_ctx_ctrl.3 +dist_man3_MANS += RSA_print.3 +dist_man3_MANS += RSA_private_encrypt.3 +dist_man3_MANS += RSA_public_encrypt.3 +dist_man3_MANS += RSA_security_bits.3 +dist_man3_MANS += RSA_set_method.3 +dist_man3_MANS += RSA_sign.3 +dist_man3_MANS += RSA_sign_ASN1_OCTET_STRING.3 +dist_man3_MANS += RSA_size.3 +dist_man3_MANS += SHA1.3 +dist_man3_MANS += SMIME_crlf_copy.3 +dist_man3_MANS += SMIME_read_ASN1.3 +dist_man3_MANS += SMIME_read_CMS.3 +dist_man3_MANS += SMIME_read_PKCS7.3 +dist_man3_MANS += SMIME_text.3 +dist_man3_MANS += SMIME_write_ASN1.3 +dist_man3_MANS += SMIME_write_CMS.3 +dist_man3_MANS += SMIME_write_PKCS7.3 +dist_man3_MANS += STACK_OF.3 +dist_man3_MANS += TS_REQ_new.3 +dist_man3_MANS += UI_UTIL_read_pw.3 +dist_man3_MANS += UI_create_method.3 +dist_man3_MANS += UI_get_string_type.3 +dist_man3_MANS += UI_new.3 +dist_man3_MANS += X25519.3 +dist_man3_MANS += X509V3_EXT_print.3 +dist_man3_MANS += X509V3_extensions_print.3 +dist_man3_MANS += X509V3_get_d2i.3 +dist_man3_MANS += X509_ALGOR_dup.3 +dist_man3_MANS += X509_ATTRIBUTE_get0_object.3 +dist_man3_MANS += X509_ATTRIBUTE_new.3 +dist_man3_MANS += X509_ATTRIBUTE_set1_object.3 +dist_man3_MANS += X509_CINF_new.3 +dist_man3_MANS += X509_CRL_METHOD_new.3 +dist_man3_MANS += X509_CRL_get0_by_serial.3 +dist_man3_MANS += X509_CRL_new.3 +dist_man3_MANS += X509_CRL_print.3 +dist_man3_MANS += X509_EXTENSION_set_object.3 +dist_man3_MANS += X509_INFO_new.3 +dist_man3_MANS += X509_LOOKUP_hash_dir.3 +dist_man3_MANS += X509_LOOKUP_new.3 +dist_man3_MANS += X509_NAME_ENTRY_get_object.3 +dist_man3_MANS += X509_NAME_add_entry_by_txt.3 +dist_man3_MANS += X509_NAME_get_index_by_NID.3 +dist_man3_MANS += X509_NAME_hash.3 +dist_man3_MANS += X509_NAME_new.3 +dist_man3_MANS += X509_NAME_print_ex.3 +dist_man3_MANS += X509_OBJECT_get0_X509.3 +dist_man3_MANS += X509_PKEY_new.3 +dist_man3_MANS += X509_PUBKEY_new.3 +dist_man3_MANS += X509_PURPOSE_set.3 +dist_man3_MANS += X509_REQ_add1_attr.3 +dist_man3_MANS += X509_REQ_add_extensions.3 +dist_man3_MANS += X509_REQ_new.3 +dist_man3_MANS += X509_REQ_print_ex.3 +dist_man3_MANS += X509_REVOKED_new.3 +dist_man3_MANS += X509_SIG_get0.3 +dist_man3_MANS += X509_SIG_new.3 +dist_man3_MANS += X509_STORE_CTX_get_error.3 +dist_man3_MANS += X509_STORE_CTX_get_ex_new_index.3 +dist_man3_MANS += X509_STORE_CTX_new.3 +dist_man3_MANS += X509_STORE_CTX_set_flags.3 +dist_man3_MANS += X509_STORE_CTX_set_verify.3 +dist_man3_MANS += X509_STORE_CTX_set_verify_cb.3 +dist_man3_MANS += X509_STORE_get_by_subject.3 +dist_man3_MANS += X509_STORE_load_locations.3 +dist_man3_MANS += X509_STORE_new.3 +dist_man3_MANS += X509_STORE_set1_param.3 +dist_man3_MANS += X509_STORE_set_verify_cb_func.3 +dist_man3_MANS += X509_TRUST_set.3 +dist_man3_MANS += X509_VERIFY_PARAM_new.3 +dist_man3_MANS += X509_VERIFY_PARAM_set_flags.3 +dist_man3_MANS += X509_add1_trust_object.3 +dist_man3_MANS += X509_check_ca.3 +dist_man3_MANS += X509_check_host.3 +dist_man3_MANS += X509_check_issued.3 +dist_man3_MANS += X509_check_private_key.3 +dist_man3_MANS += X509_check_purpose.3 +dist_man3_MANS += X509_check_trust.3 +dist_man3_MANS += X509_cmp.3 +dist_man3_MANS += X509_cmp_time.3 +dist_man3_MANS += X509_digest.3 +dist_man3_MANS += X509_find_by_subject.3 +dist_man3_MANS += X509_get0_notBefore.3 +dist_man3_MANS += X509_get0_signature.3 +dist_man3_MANS += X509_get1_email.3 +dist_man3_MANS += X509_get_extension_flags.3 +dist_man3_MANS += X509_get_pubkey.3 +dist_man3_MANS += X509_get_pubkey_parameters.3 +dist_man3_MANS += X509_get_serialNumber.3 +dist_man3_MANS += X509_get_subject_name.3 +dist_man3_MANS += X509_get_version.3 +dist_man3_MANS += X509_keyid_set1.3 +dist_man3_MANS += X509_load_cert_file.3 +dist_man3_MANS += X509_new.3 +dist_man3_MANS += X509_ocspid_print.3 +dist_man3_MANS += X509_print_ex.3 +dist_man3_MANS += X509_sign.3 +dist_man3_MANS += X509_signature_dump.3 +dist_man3_MANS += X509_verify_cert.3 +dist_man3_MANS += X509at_add1_attr.3 +dist_man3_MANS += X509at_get_attr.3 +dist_man3_MANS += X509v3_addr_add_inherit.3 +dist_man3_MANS += X509v3_addr_get_range.3 +dist_man3_MANS += X509v3_addr_inherits.3 +dist_man3_MANS += X509v3_addr_subset.3 +dist_man3_MANS += X509v3_addr_validate_path.3 +dist_man3_MANS += X509v3_asid_add_id_or_range.3 +dist_man3_MANS += X509v3_get_ext_by_NID.3 +dist_man3_MANS += a2d_ASN1_OBJECT.3 +dist_man3_MANS += bn_dump.3 +dist_man3_MANS += crypto.3 +dist_man3_MANS += d2i_ASN1_NULL.3 +dist_man3_MANS += d2i_ASN1_OBJECT.3 +dist_man3_MANS += d2i_ASN1_OCTET_STRING.3 +dist_man3_MANS += d2i_ASN1_SEQUENCE_ANY.3 +dist_man3_MANS += d2i_AUTHORITY_KEYID.3 +dist_man3_MANS += d2i_BASIC_CONSTRAINTS.3 +dist_man3_MANS += d2i_CMS_ContentInfo.3 +dist_man3_MANS += d2i_DHparams.3 +dist_man3_MANS += d2i_DIST_POINT.3 +dist_man3_MANS += d2i_DSAPublicKey.3 +dist_man3_MANS += d2i_ECPKParameters.3 +dist_man3_MANS += d2i_ESS_SIGNING_CERT.3 +dist_man3_MANS += d2i_GENERAL_NAME.3 +dist_man3_MANS += d2i_OCSP_REQUEST.3 +dist_man3_MANS += d2i_OCSP_RESPONSE.3 +dist_man3_MANS += d2i_PKCS12.3 +dist_man3_MANS += d2i_PKCS7.3 +dist_man3_MANS += d2i_PKCS8PrivateKey_bio.3 +dist_man3_MANS += d2i_PKCS8_PRIV_KEY_INFO.3 +dist_man3_MANS += d2i_PKEY_USAGE_PERIOD.3 +dist_man3_MANS += d2i_POLICYINFO.3 +dist_man3_MANS += d2i_PrivateKey.3 +dist_man3_MANS += d2i_RSAPublicKey.3 +dist_man3_MANS += d2i_TS_REQ.3 +dist_man3_MANS += d2i_X509.3 +dist_man3_MANS += d2i_X509_ALGOR.3 +dist_man3_MANS += d2i_X509_ATTRIBUTE.3 +dist_man3_MANS += d2i_X509_CRL.3 +dist_man3_MANS += d2i_X509_EXTENSION.3 +dist_man3_MANS += d2i_X509_NAME.3 +dist_man3_MANS += d2i_X509_REQ.3 +dist_man3_MANS += d2i_X509_SIG.3 +dist_man3_MANS += des_read_pw.3 +dist_man3_MANS += evp.3 +dist_man3_MANS += i2a_ASN1_STRING.3 +dist_man3_MANS += i2d_CMS_bio_stream.3 +dist_man3_MANS += i2d_PKCS7_bio_stream.3 +dist_man3_MANS += lh_new.3 +dist_man3_MANS += lh_stats.3 +dist_man3_MANS += s2i_ASN1_INTEGER.3 +dist_man3_MANS += x509_verify.3 +dist_man3_MANS += tls_accept_socket.3 +dist_man3_MANS += tls_client.3 +dist_man3_MANS += tls_config_ocsp_require_stapling.3 +dist_man3_MANS += tls_config_set_protocols.3 +dist_man3_MANS += tls_config_set_session_id.3 +dist_man3_MANS += tls_config_verify.3 +dist_man3_MANS += tls_conn_version.3 +dist_man3_MANS += tls_connect.3 +dist_man3_MANS += tls_init.3 +dist_man3_MANS += tls_load_file.3 +dist_man3_MANS += tls_ocsp_process_response.3 +dist_man3_MANS += tls_read.3 +dist_man5_MANS += openssl.cnf.5 +dist_man5_MANS += x509v3.cnf.5 +install-data-hook: + ln -sf "ACCESS_DESCRIPTION_new.3" "$(DESTDIR)$(mandir)/man3/ACCESS_DESCRIPTION_free.3" + ln -sf "ACCESS_DESCRIPTION_new.3" "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_free.3" + ln -sf "ACCESS_DESCRIPTION_new.3" "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_new.3" + ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_cbc_encrypt.3" + ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_decrypt.3" + ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_set_decrypt_key.3" + ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_set_encrypt_key.3" + ln -sf "ASIdentifiers_new.3" "$(DESTDIR)$(mandir)/man3/ASIdentifiers_free.3" + ln -sf "ASIdentifiers_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifiers.3" + ln -sf "ASIdentifiers_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifiers.3" + ln -sf "ASN1_BIT_STRING_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_get_bit.3" + ln -sf "ASN1_BIT_STRING_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_set_bit.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get_int64.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set_int64.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_to_BN.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_cmp.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_dup.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_int64.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_uint64.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_int64.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_uint64.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_to_BN.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_ENUMERATED.3" + ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_INTEGER.3" + ln -sf "ASN1_NULL_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_NULL_free.3" + ln -sf "ASN1_OBJECT_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_create.3" + ln -sf "ASN1_OBJECT_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_free.3" + ln -sf "ASN1_STRING_TABLE_add.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_cleanup.3" + ln -sf "ASN1_STRING_TABLE_add.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_get.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_cmp.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_dup.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_set.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_cmp.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_copy.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_data.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_dup.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get0_data.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_length_set.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set0.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_to_UTF8.3" + ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_new.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_free.3" + ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_new.3" + ln -sf "ASN1_STRING_print_ex.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print.3" + ln -sf "ASN1_STRING_print_ex.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print_ex_fp.3" + ln -sf "ASN1_STRING_print_ex.3" "$(DESTDIR)$(mandir)/man3/ASN1_tag2str.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_adj.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_check.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_print.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set_string.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_adj.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_check.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_cmp_time_t.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_compare.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_diff.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_normalize.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_print.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string_X509.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_generalizedtime.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_tm.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_adj.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_check.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_cmp_time_t.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_print.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set.3" + ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set_string.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_cmp.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_free.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_int_octetstring.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_octetstring.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_new.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set1.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_int_octetstring.3" + ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_octetstring.3" + ln -sf "ASN1_generate_nconf.3" "$(DESTDIR)$(mandir)/man3/ASN1_generate_v3.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_bio.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_fp.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_dup.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_bio.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_fp.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_print.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TYPE.3" + ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TYPE.3" + ln -sf "ASN1_item_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_free.3" + ln -sf "ASN1_item_pack.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_unpack.3" + ln -sf "ASN1_item_sign.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_sign_ctx.3" + ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get_default_mask.3" + ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_by_NID.3" + ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask.3" + ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask_asc.3" + ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_mbstring_ncopy.3" + ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_tag2bit.3" + ln -sf "ASN1_parse_dump.3" "$(DESTDIR)$(mandir)/man3/ASN1_parse.3" + ln -sf "ASN1_put_object.3" "$(DESTDIR)$(mandir)/man3/ASN1_object_size.3" + ln -sf "ASN1_put_object.3" "$(DESTDIR)$(mandir)/man3/ASN1_put_eoc.3" + ln -sf "ASN1_time_parse.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_tm.3" + ln -sf "ASN1_time_parse.3" "$(DESTDIR)$(mandir)/man3/ASN1_time_tm_cmp.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdOrRange_free.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdOrRange_new.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_free.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_new.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASRange_free.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASIdOrRange.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifierChoice.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASRange.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASIdOrRange.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifierChoice.3" + ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASRange.3" + ln -sf "AUTHORITY_KEYID_new.3" "$(DESTDIR)$(mandir)/man3/AUTHORITY_KEYID_free.3" + ln -sf "BASIC_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/BASIC_CONSTRAINTS_free.3" + ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_cbc_encrypt.3" + ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_cfb64_encrypt.3" + ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_decrypt.3" + ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_ecb_encrypt.3" + ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_encrypt.3" + ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_ofb64_encrypt.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_accept_socket.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_host_ip.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_port.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_tcp_ndelay.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_sock_error.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_sock_non_fatal_error.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_sock_should_retry.3" + ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_socket_nbio.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_callback_ctrl.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_pending.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_wpending.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_eof.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_flush.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_close.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_info_callback.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_info_cb.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_int_ctrl.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_pending.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_ptr_ctrl.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_reset.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_seek.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_close.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_info_callback.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_tell.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_wpending.3" + ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/bio_info_cb.3" + ln -sf "BIO_dump.3" "$(DESTDIR)$(mandir)/man3/BIO_dump_fp.3" + ln -sf "BIO_dump.3" "$(DESTDIR)$(mandir)/man3/BIO_dump_indent.3" + ln -sf "BIO_dump.3" "$(DESTDIR)$(mandir)/man3/BIO_dump_indent_fp.3" + ln -sf "BIO_dup_chain.3" "$(DESTDIR)$(mandir)/man3/BIO_dup_state.3" + ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_get_buffer_num_lines.3" + ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_read_data.3" + ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_size.3" + ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_read_buffer_size.3" + ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_write_buffer_size.3" + ln -sf "BIO_f_cipher.3" "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_ctx.3" + ln -sf "BIO_f_cipher.3" "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_status.3" + ln -sf "BIO_f_cipher.3" "$(DESTDIR)$(mandir)/man3/BIO_set_cipher.3" + ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_get_md.3" + ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_get_md_ctx.3" + ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_set_md.3" + ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_set_md_ctx.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_do_handshake.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_num_renegotiates.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_ssl.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_new_buffer_ssl_connect.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_new_ssl.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_new_ssl_connect.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_mode.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_bytes.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_timeout.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_ssl_copy_session_id.3" + ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_ssl_shutdown.3" + ln -sf "BIO_find_type.3" "$(DESTDIR)$(mandir)/man3/BIO_method_name.3" + ln -sf "BIO_find_type.3" "$(DESTDIR)$(mandir)/man3/BIO_method_type.3" + ln -sf "BIO_find_type.3" "$(DESTDIR)$(mandir)/man3/BIO_next.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_clear_flags.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_clear_retry_flags.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_copy_next_retry.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_flags.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_init.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_retry_flags.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_shutdown.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_data.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_flags.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_init.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_read.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_special.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_write.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_shutdown.3" + ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_test_flags.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_get_app_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_get_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_set_app_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_new_index.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_new_index.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_get_app_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_new_index.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_set_app_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_set_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/UI_get_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/UI_get_ex_new_index.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/UI_set_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_get_ex_data.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_get_ex_new_index.3" + ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_set_ex_data.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_get_new_index.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_free.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_callback_ctrl.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_create.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_ctrl.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_destroy.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_gets.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_puts.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_read.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_write.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_callback_ctrl.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_create.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_ctrl.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_destroy.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_gets.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_puts.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_read.3" + ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_write.3" + ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_free.3" + ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_free_all.3" + ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_set.3" + ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_up_ref.3" + ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_vfree.3" + ln -sf "BIO_printf.3" "$(DESTDIR)$(mandir)/man3/BIO_snprintf.3" + ln -sf "BIO_printf.3" "$(DESTDIR)$(mandir)/man3/BIO_vprintf.3" + ln -sf "BIO_printf.3" "$(DESTDIR)$(mandir)/man3/BIO_vsnprintf.3" + ln -sf "BIO_push.3" "$(DESTDIR)$(mandir)/man3/BIO_pop.3" + ln -sf "BIO_push.3" "$(DESTDIR)$(mandir)/man3/BIO_set_next.3" + ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_gets.3" + ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_indent.3" + ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_number_read.3" + ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_number_written.3" + ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_puts.3" + ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_write.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_do_accept.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_accept_port.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_bind_mode.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_new_accept.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_accept_bios.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_accept_port.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_bind_mode.3" + ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_nbio_accept.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_read_request.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_write_guarantee.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_reset_read_request.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_destroy_bio_pair.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_get_read_request.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_get_write_buf_size.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_get_write_guarantee.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_make_bio_pair.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_new_bio_pair.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_set_write_buf_size.3" + ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_shutdown_wr.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_do_connect.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_hostname.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_int_port.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_ip.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_port.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_new_connect.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_hostname.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_int_port.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_ip.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_port.3" + ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_nbio.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_dgram_connect.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_set_connected.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_get_peer.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_non_fatal_error.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_recv_timedout.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_send_timedout.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_set_peer.3" + ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_new_dgram.3" + ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_fd_non_fatal_error.3" + ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_fd_should_retry.3" + ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_get_fd.3" + ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_new_fd.3" + ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_set_fd.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_append_filename.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_get_fp.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_new_file.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_new_fp.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_read_filename.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_rw_filename.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_set_fp.3" + ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_write_filename.3" + ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_get_mem_data.3" + ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_get_mem_ptr.3" + ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_new_mem_buf.3" + ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_set_mem_buf.3" + ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_set_mem_eof_return.3" + ln -sf "BIO_s_socket.3" "$(DESTDIR)$(mandir)/man3/BIO_new_socket.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_callback_fn.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_callback_fn_ex.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_debug_callback.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_get_callback.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_get_callback_arg.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_get_callback_ex.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_set_callback_arg.3" + ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_set_callback_ex.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_get_retry_BIO.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_get_retry_reason.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_retry_type.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_reason.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_should_io_special.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_should_read.3" + ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_should_write.3" + ln -sf "BN_CTX_new.3" "$(DESTDIR)$(mandir)/man3/BN_CTX_free.3" + ln -sf "BN_CTX_start.3" "$(DESTDIR)$(mandir)/man3/BN_CTX_end.3" + ln -sf "BN_CTX_start.3" "$(DESTDIR)$(mandir)/man3/BN_CTX_get.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_div.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_exp.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_gcd.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_add.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_add_quick.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_exp.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1_quick.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift_quick.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_mul.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_sqr.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_sub.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_sub_quick.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mul.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_nnmod.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_sqr.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_sub.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_uadd.3" + ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_usub.3" + ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_div_word.3" + ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_mod_word.3" + ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_mul_word.3" + ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_sub_word.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_asc2bn.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bin2bn.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2binpad.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2dec.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2hex.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2lebinpad.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2mpi.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_dec2bn.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_hex2bn.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_lebin2bn.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_mpi2bn.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_print.3" + ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_print_fp.3" + ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_abs_is_word.3" + ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_odd.3" + ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_one.3" + ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_word.3" + ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_zero.3" + ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_ucmp.3" + ln -sf "BN_copy.3" "$(DESTDIR)$(mandir)/man3/BN_dup.3" + ln -sf "BN_copy.3" "$(DESTDIR)$(mandir)/man3/BN_with_flags.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_call.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_free.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_get_arg.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_new.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_set.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_set_old.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_generate_prime_ex.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_is_prime_ex.3" + ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_is_prime_fasttest_ex.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_1024.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_768.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_1536.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_2048.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_3072.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_4096.3" + ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_6144.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_copy.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_free.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_new.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set_locked.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_from_montgomery.3" + ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_to_montgomery.3" + ln -sf "BN_new.3" "$(DESTDIR)$(mandir)/man3/BN_clear.3" + ln -sf "BN_new.3" "$(DESTDIR)$(mandir)/man3/BN_clear_free.3" + ln -sf "BN_new.3" "$(DESTDIR)$(mandir)/man3/BN_free.3" + ln -sf "BN_num_bytes.3" "$(DESTDIR)$(mandir)/man3/BN_num_bits.3" + ln -sf "BN_num_bytes.3" "$(DESTDIR)$(mandir)/man3/BN_num_bits_word.3" + ln -sf "BN_rand.3" "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand.3" + ln -sf "BN_rand.3" "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand_range.3" + ln -sf "BN_rand.3" "$(DESTDIR)$(mandir)/man3/BN_rand_range.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_clear_bit.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_is_bit_set.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_lshift.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_lshift1.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_mask_bits.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_rshift.3" + ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_rshift1.3" + ln -sf "BN_set_flags.3" "$(DESTDIR)$(mandir)/man3/BN_get_flags.3" + ln -sf "BN_set_negative.3" "$(DESTDIR)$(mandir)/man3/BN_is_negative.3" + ln -sf "BN_swap.3" "$(DESTDIR)$(mandir)/man3/BN_consttime_swap.3" + ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_get_word.3" + ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_one.3" + ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_set_word.3" + ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_value_one.3" + ln -sf "BUF_MEM_new.3" "$(DESTDIR)$(mandir)/man3/BUF_MEM_free.3" + ln -sf "BUF_MEM_new.3" "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow.3" + ln -sf "BUF_MEM_new.3" "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow_clean.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_cleanup.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_copy.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_free.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_get0_cipher_ctx.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_new.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_Final.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_Update.3" + ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_resume.3" + ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_free.3" + ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_print_ctx.3" + ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_free.3" + ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_new.3" + ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add0_crl.3" + ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add1_cert.3" + ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add1_crl.3" + ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_get1_certs.3" + ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_get1_crls.3" + ln -sf "CMS_add1_recipient_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add0_recipient_key.3" + ln -sf "CMS_add1_signer.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_sign.3" + ln -sf "CMS_decrypt.3" "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_key.3" + ln -sf "CMS_decrypt.3" "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_pkey.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_decrypt.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_encrypt.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_get0_id.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_id_cmp.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_cert_cmp.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_get0_signer_id.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_key.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_pkey.3" + ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_type.3" + ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_cert_cmp.3" + ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signature.3" + ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signer_id.3" + ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get_version.3" + ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_set1_signer_cert.3" + ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_get0_content.3" + ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_get0_eContentType.3" + ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_get_version.3" + ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_set1_eContentType.3" + ln -sf "CMS_get1_ReceiptRequest.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_create0.3" + ln -sf "CMS_get1_ReceiptRequest.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_get0_values.3" + ln -sf "CMS_get1_ReceiptRequest.3" "$(DESTDIR)$(mandir)/man3/CMS_add1_ReceiptRequest.3" + ln -sf "CMS_verify.3" "$(DESTDIR)$(mandir)/man3/CMS_get0_signers.3" + ln -sf "CONF_modules_free.3" "$(DESTDIR)$(mandir)/man3/CONF_modules_finish.3" + ln -sf "CONF_modules_free.3" "$(DESTDIR)$(mandir)/man3/CONF_modules_unload.3" + ln -sf "CONF_modules_load_file.3" "$(DESTDIR)$(mandir)/man3/CONF_modules_load.3" + ln -sf "CONF_modules_load_file.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_area.3" + ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_MEM_LEAK_CB.3" + ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_ctrl.3" + ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks.3" + ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_cb.3" + ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_fp.3" + ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_set_mem_functions.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cmp.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cpy.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_current.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_hash.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_add.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_r_lock.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_r_unlock.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_w_lock.3" + ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_w_unlock.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_dup.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_free.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_new.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_free_ex_data.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_data.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_new_index.3" + ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_new_ex_data.3" + ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_chacha_20.3" + ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_hchacha_20.3" + ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_xchacha_20.3" + ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/ChaCha_set_iv.3" + ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/ChaCha_set_key.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_cbc_cksum.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_cfb64_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_cfb_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_crypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ecb2_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ecb3_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ecb_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede2_cbc_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede2_cfb64_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede2_ofb64_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_cbc_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_cbcm_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_cfb64_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_ofb64_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_enc_read.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_enc_write.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_fcrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_is_weak_key.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_key_sched.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ncbc_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ofb64_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ofb_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_pcbc_encrypt.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_quad_cksum.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_random_key.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_set_key_checked.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_set_key_unchecked.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_set_odd_parity.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_string_to_2keys.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_string_to_key.3" + ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_xcbc_encrypt.3" + ln -sf "DH_generate_key.3" "$(DESTDIR)$(mandir)/man3/DH_compute_key.3" + ln -sf "DH_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DH_check.3" + ln -sf "DH_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DH_check_pub_key.3" + ln -sf "DH_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DH_generate_parameters_ex.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_clear_flags.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_engine.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_g.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_key.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_p.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_priv_key.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_pub_key.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_q.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set0_key.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set0_pqg.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set_flags.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set_length.3" + ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_test_flags.3" + ln -sf "DH_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DH_get_ex_data.3" + ln -sf "DH_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DH_set_ex_data.3" + ln -sf "DH_new.3" "$(DESTDIR)$(mandir)/man3/DH_free.3" + ln -sf "DH_new.3" "$(DESTDIR)$(mandir)/man3/DH_up_ref.3" + ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_OpenSSL.3" + ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_get_default_method.3" + ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_new_method.3" + ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_set_default_method.3" + ln -sf "DH_size.3" "$(DESTDIR)$(mandir)/man3/DH_bits.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_free.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_new.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_free.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_new.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/DIST_POINT_free.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_free.3" + ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_new.3" + ln -sf "DSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/DSA_SIG_free.3" + ln -sf "DSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/DSA_SIG_get0.3" + ln -sf "DSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/DSA_SIG_set0.3" + ln -sf "DSA_do_sign.3" "$(DESTDIR)$(mandir)/man3/DSA_do_verify.3" + ln -sf "DSA_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DSA_generate_parameters_ex.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_clear_flags.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_engine.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_g.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_key.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_p.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_priv_key.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_pub_key.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_q.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_set0_key.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_set0_pqg.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_set_flags.3" + ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_test_flags.3" + ln -sf "DSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DSA_get_ex_data.3" + ln -sf "DSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DSA_set_ex_data.3" + ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_dup.3" + ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_free.3" + ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_get0_name.3" + ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_set1_name.3" + ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_set_finish.3" + ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_set_sign.3" + ln -sf "DSA_new.3" "$(DESTDIR)$(mandir)/man3/DSA_free.3" + ln -sf "DSA_new.3" "$(DESTDIR)$(mandir)/man3/DSA_up_ref.3" + ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_OpenSSL.3" + ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_get_default_method.3" + ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_new_method.3" + ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_set_default_method.3" + ln -sf "DSA_sign.3" "$(DESTDIR)$(mandir)/man3/DSA_sign_setup.3" + ln -sf "DSA_sign.3" "$(DESTDIR)$(mandir)/man3/DSA_verify.3" + ln -sf "DSA_size.3" "$(DESTDIR)$(mandir)/man3/DSA_bits.3" + ln -sf "ECDH_compute_key.3" "$(DESTDIR)$(mandir)/man3/ECDH_size.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_free.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_r.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_s.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_set0.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_do_sign.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_do_verify.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_sign.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_size.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_verify.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ECDSA_SIG.3" + ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ECDSA_SIG.3" + ln -sf "EC_GFp_simple_method.3" "$(DESTDIR)$(mandir)/man3/EC_GFp_mont_method.3" + ln -sf "EC_GFp_simple_method.3" "$(DESTDIR)$(mandir)/man3/EC_METHOD_get_field_type.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_check.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_check_discriminant.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_cmp.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_dup.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_generator.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_seed.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_asn1_flag.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_basis_type.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_cofactor.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_name.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_degree.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_order.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_point_conversion_form.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_seed_len.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_method_of.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_order_bits.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_asn1_flag.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_name.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_generator.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_point_conversion_form.3" + ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_seed.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_clear_free.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_free.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_GFp.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_by_curve_name.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_curve_GFp.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_GFp.3" + ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_get_builtin_curves.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_free.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_compute_key.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_init.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_keygen.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_sign.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_verify.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_compute_key.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_init.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_keygen.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_sign.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_verify.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_OpenSSL.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_default_method.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_method.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_new_method.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_default_method.3" + ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_method.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_check_key.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_clear_flags.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_copy.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_dup.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_free.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_generate_key.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_group.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_private_key.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_public_key.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_conv_form.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_enc_flags.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_flags.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_new_by_curve_name.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_precompute_mult.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_print.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_print_fp.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_asn1_flag.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_conv_form.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_enc_flags.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_flags.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_group.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_private_key.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key_affine_coordinates.3" + ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_up_ref.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_have_precompute_mult.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_precompute_mult.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_cmp.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_dbl.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_invert.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_is_at_infinity.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_is_on_curve.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_make_affine.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_mul.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINTs_make_affine.3" + ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINTs_mul.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_bn2point.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_clear_free.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_copy.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_dup.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_free.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_get_Jprojective_coordinates_GFp.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates_GFp.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_hex2point.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_method_of.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_oct2point.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_point2bn.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_point2hex.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_point2oct.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_Jprojective_coordinates_GFp.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates_GFp.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates_GFp.3" + ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_to_infinity.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_by_id.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_cleanup.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_first.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_id.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_last.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_name.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_next.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_prev.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_remove.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_id.3" + ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_name.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_CTRL_FUNC_PTR.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_cmd_is_executable.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd_string.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_cmd_defns.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ctrl_function.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_cmd_defns.3" + ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_ctrl_function.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher_engine.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DH.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DSA.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_EC.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_RAND.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest_engine.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_table_flags.3" + ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_table_flags.3" + ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" + ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_finish.3" + ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_finish_function.3" + ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_init_function.3" + ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_finish_function.3" + ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_init_function.3" + ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" + ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_free.3" + ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_destroy_function.3" + ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_destroy_function.3" + ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_up_ref.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_DH.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_DSA.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDH.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDSA.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_RAND.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_STORE.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_ciphers.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_complete.3" + ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_digests.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_load_builtin_engines.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_load_dynamic.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DH.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DSA.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDH.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDSA.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_RAND.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_STORE.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ciphers.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_complete.3" + ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_digests.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_CIPHERS_PTR.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_DIGESTS_PTR.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_DH.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_DSA.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_EC.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_RAND.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_RSA.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_STORE.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ciphers.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_digests.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_DH.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_DSA.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_EC.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_RAND.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_STORE.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_ciphers.3" + ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_digests.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DH.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DSA.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDH.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDSA.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RAND.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RSA.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ciphers.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_digests.3" + ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_string.3" + ln -sf "ENGINE_set_flags.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_flags.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DH.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DSA.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDH.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDSA.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_RAND.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_STORE.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ciphers.3" + ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_digests.3" + ln -sf "ERR_GET_LIB.3" "$(DESTDIR)$(mandir)/man3/ERR_FATAL_ERROR.3" + ln -sf "ERR_GET_LIB.3" "$(DESTDIR)$(mandir)/man3/ERR_GET_FUNC.3" + ln -sf "ERR_GET_LIB.3" "$(DESTDIR)$(mandir)/man3/ERR_GET_REASON.3" + ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_error_string_n.3" + ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_func_error_string.3" + ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_lib_error_string.3" + ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_reason_error_string.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_get_error_line.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_get_error_line_data.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_error.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line_data.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line.3" + ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line_data.3" + ln -sf "ERR_load_crypto_strings.3" "$(DESTDIR)$(mandir)/man3/ERR_free_strings.3" + ln -sf "ERR_load_crypto_strings.3" "$(DESTDIR)$(mandir)/man3/SSL_load_error_strings.3" + ln -sf "ERR_load_strings.3" "$(DESTDIR)$(mandir)/man3/ERR_PACK.3" + ln -sf "ERR_load_strings.3" "$(DESTDIR)$(mandir)/man3/ERR_get_next_error_library.3" + ln -sf "ERR_print_errors.3" "$(DESTDIR)$(mandir)/man3/ERR_print_errors_cb.3" + ln -sf "ERR_print_errors.3" "$(DESTDIR)$(mandir)/man3/ERR_print_errors_fp.3" + ln -sf "ERR_put_error.3" "$(DESTDIR)$(mandir)/man3/ERR_add_error_data.3" + ln -sf "ERR_put_error.3" "$(DESTDIR)$(mandir)/man3/ERR_add_error_vdata.3" + ln -sf "ERR_remove_state.3" "$(DESTDIR)$(mandir)/man3/ERR_remove_thread_state.3" + ln -sf "ERR_set_mark.3" "$(DESTDIR)$(mandir)/man3/ERR_pop_to_mark.3" + ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_free.3" + ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_new.3" + ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_free.3" + ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_new.3" + ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_SIGNING_CERT_free.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_cleanup.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_free.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_new.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_open.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_seal.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_key_length.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_overhead.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_tag_len.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_nonce_length.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_128_gcm.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_256_gcm.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_chacha20_poly1305.3" + ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_xchacha20_poly1305.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_iv.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_iv_length.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_key_length.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_iv.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_key_length.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_padding.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_iv_length.3" + ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_key_length.3" + ln -sf "EVP_CIPHER_CTX_get_cipher_data.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_buf_noconst.3" + ln -sf "EVP_CIPHER_CTX_get_cipher_data.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_cipher_data.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_clear_flags.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_app_data.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_rand_key.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_app_data.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_test_flags.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_asn1_to_param.3" + ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_param_to_asn1.3" + ln -sf "EVP_CIPHER_do_all.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_do_all_sorted.3" + ln -sf "EVP_CIPHER_do_all.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all.3" + ln -sf "EVP_CIPHER_do_all.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all_sorted.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_dup.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_free.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_cleanup.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_ctrl.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_do_cipher.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_flags.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_get_asn1_params.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_impl_ctx_size.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_init.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_iv_length.3" + ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_set_asn1_params.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_block_size.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_flags.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_mode.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_nid.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_type.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_block_size.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_flags.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_mode.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_name.3" + ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_type.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_Digest.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal_ex.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestInit_ex.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestUpdate.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_cleanup.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy_ex.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_create.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_destroy.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_free.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_init.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_new.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_reset.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyname.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_digestbynid.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyobj.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_md_null.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_ripemd160.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha224.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha256.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha384.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha512.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha512_224.3" + ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha512_256.3" + ln -sf "EVP_DigestSignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestSign.3" + ln -sf "EVP_DigestSignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestSignFinal.3" + ln -sf "EVP_DigestSignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestSignUpdate.3" + ln -sf "EVP_DigestVerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestVerify.3" + ln -sf "EVP_DigestVerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyFinal.3" + ln -sf "EVP_DigestVerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyUpdate.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeBlock.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeFinal.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeInit.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeUpdate.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_free.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_new.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncodeBlock.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncodeFinal.3" + ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncodeUpdate.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cipher.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cleanup.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_copy.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_encrypting.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_free.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_init.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_new.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_reset.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_Cipher.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal_ex.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherInit.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherInit_ex.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherUpdate.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal_ex.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit_ex.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptUpdate.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal_ex.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptInit_ex.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptUpdate.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_cbc.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb64.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_ecb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_ofb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_cbc.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb64.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_ecb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_ofb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_enc_null.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyname.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbynid.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyobj.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_cbc.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb64.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_ecb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_ofb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_40_cbc.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_64_cbc.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_cbc.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb64.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_ecb.3" + ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_ofb.3" + ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_clear_flags.3" + ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md_data.3" + ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_pkey_ctx.3" + ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_flags.3" + ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_pkey_ctx.3" + ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_test_flags.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_dup.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_free.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_app_datasize.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_cleanup.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_copy.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_ctrl.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_final.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_flags.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_init.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_input_blocksize.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_result_size.3" + ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_update.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_block_size.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_size.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_type.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_block_size.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_flags.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_name.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_pkey_type.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_size.3" + ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_type.3" + ln -sf "EVP_OpenInit.3" "$(DESTDIR)$(mandir)/man3/EVP_OpenFinal.3" + ln -sf "EVP_OpenInit.3" "$(DESTDIR)$(mandir)/man3/EVP_OpenUpdate.3" + ln -sf "EVP_PKCS82PKEY.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY2PKCS8.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_ctrl_str.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_ecdh_kdf_ukm.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id_len.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_cofactor_mode.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_md.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_outlen.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_type.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_signature_md.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_ecdh_kdf_ukm.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_id.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_generator.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_prime_len.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dsa_paramgen_bits.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_param_enc.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_paramgen_curve_nid.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_cofactor_mode.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_md.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_outlen.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_type.3" + ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_signature_md.3" + ln -sf "EVP_PKEY_CTX_get_operation.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_pkey.3" + ln -sf "EVP_PKEY_CTX_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_dup.3" + ln -sf "EVP_PKEY_CTX_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_free.3" + ln -sf "EVP_PKEY_CTX_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_new_id.3" + ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_add1_hkdf_info.3" + ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_hkdf_mode.3" + ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_key.3" + ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_salt.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_NID.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_OBJ.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_txt.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_delete_attr.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_NID.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_OBJ.3" + ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_count.3" + ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find.3" + ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find_str.3" + ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0.3" + ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0_info.3" + ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_asn1.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add0.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add_alias.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_copy.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_free.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_check.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_ctrl.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_free.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param_check.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_private.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public_check.3" + ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_security_bits.3" + ln -sf "EVP_PKEY_check.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_param_check.3" + ln -sf "EVP_PKEY_check.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_public_check.3" + ln -sf "EVP_PKEY_cmp.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_cmp_parameters.3" + ln -sf "EVP_PKEY_cmp.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_copy_parameters.3" + ln -sf "EVP_PKEY_cmp.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_missing_parameters.3" + ln -sf "EVP_PKEY_decrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_init.3" + ln -sf "EVP_PKEY_derive.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_peerkey.3" + ln -sf "EVP_PKEY_derive.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_init.3" + ln -sf "EVP_PKEY_derive.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_set_peer.3" + ln -sf "EVP_PKEY_encrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_init.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_app_data.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_cb.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_keygen_info.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_keygen_info.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_app_data.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_cb.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_gen_cb.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_keygen_init.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen.3" + ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen_init.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_data.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_data.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_add0.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_copy.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_find.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_free.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_check.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_cleanup.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_copy.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_ctrl.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_decrypt.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_derive.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_encrypt.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_init.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_keygen.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_param_check.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_paramgen.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_public_check.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_sign.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_signctx.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify_recover.3" + ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verifyctx.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_free.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_private_key.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_public_key.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_CMAC_key.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_mac_key.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_private_key.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_public_key.3" + ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_up_ref.3" + ln -sf "EVP_PKEY_print_private.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_params.3" + ln -sf "EVP_PKEY_print_private.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_public.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DH.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_EC_KEY.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_GOST.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_RSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_base_id.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DH.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_EC_KEY.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_RSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_hmac.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DH.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_EC_KEY.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_RSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_id.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DH.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DSA.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_EC_KEY.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type_str.3" + ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_type.3" + ln -sf "EVP_PKEY_sign.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_sign_init.3" + ln -sf "EVP_PKEY_size.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_bits.3" + ln -sf "EVP_PKEY_size.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_security_bits.3" + ln -sf "EVP_PKEY_verify.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_init.3" + ln -sf "EVP_PKEY_verify_recover.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_recover_init.3" + ln -sf "EVP_SealInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SealFinal.3" + ln -sf "EVP_SealInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SealUpdate.3" + ln -sf "EVP_SignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SignFinal.3" + ln -sf "EVP_SignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SignInit_ex.3" + ln -sf "EVP_SignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SignUpdate.3" + ln -sf "EVP_VerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_VerifyFinal.3" + ln -sf "EVP_VerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_VerifyInit_ex.3" + ln -sf "EVP_VerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_VerifyUpdate.3" + ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_add_cipher_alias.3" + ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_add_digest.3" + ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_add_digest_alias.3" + ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_delete_cipher_alias.3" + ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_delete_digest_alias.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cbc_hmac_sha1.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ccm.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb1.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb128.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb8.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ctr.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ecb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_gcm.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ofb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_wrap.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_xts.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cbc.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ccm.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb1.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb128.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb8.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ctr.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ecb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_gcm.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ofb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_wrap.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc_hmac_sha1.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ccm.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb1.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb128.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb8.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ctr.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ecb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_gcm.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ofb.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_wrap.3" + ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_xts.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb1.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb128.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb8.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ecb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ofb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cbc.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb1.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb128.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb8.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ecb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ofb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cbc.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb1.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb128.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb8.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ecb.3" + ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ofb.3" + ln -sf "EVP_chacha20.3" "$(DESTDIR)$(mandir)/man3/EVP_chacha20_poly1305.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb1.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb64.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb8.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ecb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cbc.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb1.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb64.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb8.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ecb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ofb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cbc.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb64.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ecb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ofb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ofb.3" + ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_desx_cbc.3" + ln -sf "EVP_rc4.3" "$(DESTDIR)$(mandir)/man3/EVP_rc4_40.3" + ln -sf "EVP_rc4.3" "$(DESTDIR)$(mandir)/man3/EVP_rc4_hmac_md5.3" + ln -sf "EVP_sha1.3" "$(DESTDIR)$(mandir)/man3/EVP_md4.3" + ln -sf "EVP_sha1.3" "$(DESTDIR)$(mandir)/man3/EVP_md5.3" + ln -sf "EVP_sha1.3" "$(DESTDIR)$(mandir)/man3/EVP_md5_sha1.3" + ln -sf "EVP_sha3_224.3" "$(DESTDIR)$(mandir)/man3/EVP_sha3_256.3" + ln -sf "EVP_sha3_224.3" "$(DESTDIR)$(mandir)/man3/EVP_sha3_384.3" + ln -sf "EVP_sha3_224.3" "$(DESTDIR)$(mandir)/man3/EVP_sha3_512.3" + ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb.3" + ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb128.3" + ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_ctr.3" + ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_ecb.3" + ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_ofb.3" + ln -sf "EXTENDED_KEY_USAGE_new.3" "$(DESTDIR)$(mandir)/man3/EXTENDED_KEY_USAGE_free.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_free.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_new.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_free.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_new.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_NAME_free.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/OTHERNAME_free.3" + ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/OTHERNAME_new.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_copy.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_free.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_get_md.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_new.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_reset.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_set_flags.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Final.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Init.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Init_ex.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Update.3" + ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_size.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressChoice_free.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressChoice_new.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressFamily_free.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressFamily_new.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_free.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_new.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressRange_free.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressChoice.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressFamily.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressOrRange.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressRange.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressChoice.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressFamily.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressOrRange.3" + ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressRange.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4_Final.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4_Init.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4_Update.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD5_Final.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD5_Init.3" + ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD5_Update.3" + ln -sf "NAME_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_free.3" + ln -sf "NAME_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_new.3" + ln -sf "NAME_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/NAME_CONSTRAINTS_free.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_cleanup.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all_sorted.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_get.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_init.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_new_index.3" + ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_remove.3" + ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_add_object.3" + ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_cleanup.3" + ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_create_objects.3" + ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_new_nid.3" + ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/check_defer.3" + ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/obj_cleanup_defer.3" + ln -sf "OBJ_find_sigid_algs.3" "$(DESTDIR)$(mandir)/man3/OBJ_find_sigid_by_algs.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_cmp.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_dup.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_ln2nid.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_nid2ln.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_nid2sn.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_obj2nid.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_obj2txt.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_sn2nid.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_txt2nid.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_txt2obj.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/i2a_ASN1_OBJECT.3" + ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/i2t_ASN1_OBJECT.3" + ln -sf "OCSP_CRLID_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_CRLID_free.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_free.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_new.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_free.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_new.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQUEST_free.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_free.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_new.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_add0_id.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_add1_cert.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_count.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_get0.3" + ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_sign.3" + ln -sf "OCSP_SERVICELOC_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_SERVICELOC_free.3" + ln -sf "OCSP_SERVICELOC_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_url_svcloc_new.3" + ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_free.3" + ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_new.3" + ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_cert_id_new.3" + ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_id_cmp.3" + ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_id_get0_info.3" + ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_id_issuer_cmp.3" + ln -sf "OCSP_request_add1_nonce.3" "$(DESTDIR)$(mandir)/man3/OCSP_basic_add1_nonce.3" + ln -sf "OCSP_request_add1_nonce.3" "$(DESTDIR)$(mandir)/man3/OCSP_check_nonce.3" + ln -sf "OCSP_request_add1_nonce.3" "$(DESTDIR)$(mandir)/man3/OCSP_copy_nonce.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_free.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_new.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_free.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_new.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_free.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_get0_id.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_new.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_basic_verify.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_cert_status_str.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_check_validity.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_resp_count.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_resp_find.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_resp_get0.3" + ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_single_get0_status.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_free.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_new.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_free.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_new.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_free.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_new.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_free.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_new.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_free.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_new.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_basic_sign.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_response_create.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_response_get1_basic.3" + ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_response_status_str.3" + ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_add1_header.3" + ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_free.3" + ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_set1_req.3" + ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_parse_url.3" + ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_bio.3" + ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_nbio.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_NUMBER.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_TEXT.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_VERSION_TEXT.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_version.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_version_num.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/SSLeay.3" + ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/SSLeay_version.3" + ln -sf "OPENSSL_config.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_no_config.3" + ln -sf "OPENSSL_init_crypto.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_init.3" + ln -sf "OPENSSL_load_builtin_modules.3" "$(DESTDIR)$(mandir)/man3/ASN1_add_oid_module.3" + ln -sf "OPENSSL_load_builtin_modules.3" "$(DESTDIR)$(mandir)/man3/ENGINE_add_conf_module.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_free.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_malloc.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_realloc.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_strdup.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_free.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_realloc.3" + ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_strdup.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_delete.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_delete_ptr.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_dup.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_find.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_find_ex.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_free.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_insert.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_is_sorted.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_new.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_new_null.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_num.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_pop.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_pop_free.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_push.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_set.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_set_cmp_func.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_shift.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_sort.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_unshift.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_value.3" + ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_zero.3" + ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/EVP_cleanup.3" + ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_ciphers.3" + ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_digests.3" + ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/SSLeay_add_all_algorithms.3" + ln -sf "PEM_ASN1_read.3" "$(DESTDIR)$(mandir)/man3/PEM_ASN1_read_bio.3" + ln -sf "PEM_ASN1_read.3" "$(DESTDIR)$(mandir)/man3/d2i_of_void.3" + ln -sf "PEM_X509_INFO_read.3" "$(DESTDIR)$(mandir)/man3/PEM_X509_INFO_read_bio.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_def_callback.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_do_header.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_get_EVP_CIPHER_INFO.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_write.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio.3" + ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/pem_password_cb.3" + ln -sf "PEM_read_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_SSL_SESSION.3" + ln -sf "PEM_read_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/PEM_write_SSL_SESSION.3" + ln -sf "PEM_read_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_SSL_SESSION.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_CMS.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DHparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DSAparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_ECPKParameters.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_ECPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_EC_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS7.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8_PRIV_KEY_INFO.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPublicKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_RSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509_AUX.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509_CRL.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509_REQ.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_CMS.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DHparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPKParameters.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_EC_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS7.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8_PRIV_KEY_INFO.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPublicKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_AUX.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_CRL.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_REQ.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_CMS.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DHparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DSAparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_ECPKParameters.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_ECPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_EC_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS7.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey_nid.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8_PRIV_KEY_INFO.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPublicKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_RSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_AUX.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_CRL.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ_NEW.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_CMS.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DHparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAparams.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPKParameters.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_EC_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS7.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey_nid.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8_PRIV_KEY_INFO.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPrivateKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPublicKey.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSA_PUBKEY.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_AUX.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_CRL.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ.3" + ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ_NEW.3" + ln -sf "PKCS12_SAFEBAG_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_free.3" + ln -sf "PKCS12_SAFEBAG_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_new.3" + ln -sf "PKCS12_SAFEBAG_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_SAFEBAG_free.3" + ln -sf "PKCS12_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_free.3" + ln -sf "PKCS12_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_new.3" + ln -sf "PKCS12_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_free.3" + ln -sf "PKCS5_PBKDF2_HMAC.3" "$(DESTDIR)$(mandir)/man3/PKCS5_PBKDF2_HMAC_SHA1.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add0_attrib_signing_time.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add1_attrib_digest.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_content_type.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_smimecap.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add_signed_attribute.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_get_attribute.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_get_signed_attribute.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_set_attributes.3" + ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_set_signed_attributes.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_free.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_new.3" + ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_free.3" + ln -sf "PKCS7_set_content.3" "$(DESTDIR)$(mandir)/man3/PKCS7_content_new.3" + ln -sf "PKCS7_set_type.3" "$(DESTDIR)$(mandir)/man3/PKCS7_set0_type_other.3" + ln -sf "PKCS7_verify.3" "$(DESTDIR)$(mandir)/man3/PKCS7_get0_signers.3" + ln -sf "PKCS8_PRIV_KEY_INFO_new.3" "$(DESTDIR)$(mandir)/man3/PKCS8_PRIV_KEY_INFO_free.3" + ln -sf "PKCS8_pkey_set0.3" "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_add1_attr_by_NID.3" + ln -sf "PKCS8_pkey_set0.3" "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0.3" + ln -sf "PKCS8_pkey_set0.3" "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0_attrs.3" + ln -sf "PKEY_USAGE_PERIOD_new.3" "$(DESTDIR)$(mandir)/man3/PKEY_USAGE_PERIOD_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_new.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/NOTICEREF_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/NOTICEREF_new.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICYINFO_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_new.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_new.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_new.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/USERNOTICE_free.3" + ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/USERNOTICE_new.3" + ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_cleanup.3" + ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_poll.3" + ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_seed.3" + ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_status.3" + ln -sf "RAND_bytes.3" "$(DESTDIR)$(mandir)/man3/RAND_pseudo_bytes.3" + ln -sf "RAND_load_file.3" "$(DESTDIR)$(mandir)/man3/RAND_file_name.3" + ln -sf "RAND_load_file.3" "$(DESTDIR)$(mandir)/man3/RAND_write_file.3" + ln -sf "RAND_set_rand_method.3" "$(DESTDIR)$(mandir)/man3/RAND_SSLeay.3" + ln -sf "RAND_set_rand_method.3" "$(DESTDIR)$(mandir)/man3/RAND_get_rand_method.3" + ln -sf "RC4.3" "$(DESTDIR)$(mandir)/man3/RC4_set_key.3" + ln -sf "RIPEMD160.3" "$(DESTDIR)$(mandir)/man3/RIPEMD160_Final.3" + ln -sf "RIPEMD160.3" "$(DESTDIR)$(mandir)/man3/RIPEMD160_Init.3" + ln -sf "RIPEMD160.3" "$(DESTDIR)$(mandir)/man3/RIPEMD160_Update.3" + ln -sf "RSA_PSS_PARAMS_new.3" "$(DESTDIR)$(mandir)/man3/RSA_PSS_PARAMS_free.3" + ln -sf "RSA_blinding_on.3" "$(DESTDIR)$(mandir)/man3/RSA_blinding_off.3" + ln -sf "RSA_generate_key.3" "$(DESTDIR)$(mandir)/man3/RSA_generate_key_ex.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_clear_flags.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_crt_params.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_d.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_dmp1.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_dmq1.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_e.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_factors.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_iqmp.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_n.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_p.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_q.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set0_crt_params.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set0_factors.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set0_key.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set_flags.3" + ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_test_flags.3" + ln -sf "RSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/RSA_get_ex_data.3" + ln -sf "RSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/RSA_set_ex_data.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_dup.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_free.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_app_data.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_name.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_bn_mod_exp.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_finish.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_flags.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_init.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_keygen.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_mod_exp.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_dec.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_enc.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_dec.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_enc.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_sign.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_verify.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set0_app_data.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set1_name.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_bn_mod_exp.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_finish.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_flags.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_init.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_keygen.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_mod_exp.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_dec.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_enc.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_dec.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_enc.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_sign.3" + ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_verify.3" + ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSAPrivateKey_dup.3" + ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSAPublicKey_dup.3" + ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSA_free.3" + ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSA_up_ref.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_OAEP.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_type_2.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_add_none.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_OAEP.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_1.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_2.3" + ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_none.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_rsa_oaep_label.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_mgf1_md.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_oaep_md.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_padding.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_pss_saltlen.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_bits.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_pubexp.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_mgf1_md.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_oaep_md.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_padding.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen.3" + ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_saltlen.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DHparams_print.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DHparams_print_fp.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSA_print.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSA_print_fp.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSAparams_print.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSAparams_print_fp.3" + ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/RSA_print_fp.3" + ln -sf "RSA_private_encrypt.3" "$(DESTDIR)$(mandir)/man3/RSA_public_decrypt.3" + ln -sf "RSA_public_encrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_old.3" + ln -sf "RSA_public_encrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_old.3" + ln -sf "RSA_public_encrypt.3" "$(DESTDIR)$(mandir)/man3/RSA_private_decrypt.3" + ln -sf "RSA_security_bits.3" "$(DESTDIR)$(mandir)/man3/BN_security_bits.3" + ln -sf "RSA_security_bits.3" "$(DESTDIR)$(mandir)/man3/DH_security_bits.3" + ln -sf "RSA_security_bits.3" "$(DESTDIR)$(mandir)/man3/DSA_security_bits.3" + ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_PKCS1_SSLeay.3" + ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_flags.3" + ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_get_default_method.3" + ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_get_method.3" + ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_new_method.3" + ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_set_default_method.3" + ln -sf "RSA_sign.3" "$(DESTDIR)$(mandir)/man3/RSA_verify.3" + ln -sf "RSA_sign_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/RSA_verify_ASN1_OCTET_STRING.3" + ln -sf "RSA_size.3" "$(DESTDIR)$(mandir)/man3/RSA_bits.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA1_Final.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA1_Init.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA1_Update.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224_Final.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224_Init.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224_Update.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256_Final.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256_Init.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256_Update.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384_Final.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384_Init.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384_Update.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512_Final.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512_Init.3" + ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512_Update.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_description.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_find.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_auth_nid.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_bits.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_cipher_nid.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_digest_nid.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_id.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_kx_nid.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_version.3" + ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_is_aead.3" + ln -sf "SSL_COMP_add_compression_method.3" "$(DESTDIR)$(mandir)/man3/SSL_COMP_get_compression_methods.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_add0_chain_cert.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_chain_certs.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_chain_certs.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set0_chain.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_chain.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_add0_chain_cert.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_add1_chain_cert.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_chain_certs.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_chain_certs.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_set0_chain.3" + ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_chain.3" + ln -sf "SSL_CTX_add_extra_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_extra_chain_certs.3" + ln -sf "SSL_CTX_add_extra_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs.3" + ln -sf "SSL_CTX_add_extra_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs_only.3" + ln -sf "SSL_CTX_add_session.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_remove_session.3" + ln -sf "SSL_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_callback_ctrl.3" + ln -sf "SSL_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/SSL_callback_ctrl.3" + ln -sf "SSL_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/SSL_ctrl.3" + ln -sf "SSL_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ex_data.3" + ln -sf "SSL_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ex_data.3" + ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_callback.3" + ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_depth.3" + ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_verify_callback.3" + ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_verify_depth.3" + ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_verify_mode.3" + ln -sf "SSL_CTX_load_verify_locations.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_verify_paths.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLS_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLS_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLS_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_2_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_2_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_2_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_up_ref.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSLv23_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSLv23_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSLv23_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLS_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLS_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLS_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_1_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_1_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_1_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_2_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_2_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_2_server_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_client_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_method.3" + ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_server_method.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_good.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_renegotiate.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cache_full.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cb_hits.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_good.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_renegotiate.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_hits.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_misses.3" + ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_timeouts.3" + ln -sf "SSL_CTX_sess_set_cache_size.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_cache_size.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_get_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_new_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_remove_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_new_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_remove_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/get_session_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/new_session_cb.3" + ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/remove_session_cb.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves_list.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_groups_list.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_curves.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_curves_list.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_groups.3" + ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_groups_list.3" + ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_alpn_protos.3" + ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_alpn_selected.3" + ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_select_next_proto.3" + ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_set_alpn_protos.3" + ln -sf "SSL_CTX_set_cert_store.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_cert_store.3" + ln -sf "SSL_CTX_set_cipher_list.3" "$(DESTDIR)$(mandir)/man3/SSL_set_cipher_list.3" + ln -sf "SSL_CTX_set_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_add_client_CA.3" + ln -sf "SSL_CTX_set_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_add_client_CA.3" + ln -sf "SSL_CTX_set_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_set_client_CA_list.3" + ln -sf "SSL_CTX_set_client_cert_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_cert_cb.3" + ln -sf "SSL_CTX_set_client_cert_cb.3" "$(DESTDIR)$(mandir)/man3/client_cert_cb.3" + ln -sf "SSL_CTX_set_default_passwd_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb.3" + ln -sf "SSL_CTX_set_default_passwd_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb_userdata.3" + ln -sf "SSL_CTX_set_default_passwd_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_passwd_cb_userdata.3" + ln -sf "SSL_CTX_set_generate_session_id.3" "$(DESTDIR)$(mandir)/man3/GEN_SESSION_CB.3" + ln -sf "SSL_CTX_set_generate_session_id.3" "$(DESTDIR)$(mandir)/man3/SSL_has_matching_session_id.3" + ln -sf "SSL_CTX_set_generate_session_id.3" "$(DESTDIR)$(mandir)/man3/SSL_set_generate_session_id.3" + ln -sf "SSL_CTX_set_info_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_info_callback.3" + ln -sf "SSL_CTX_set_info_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_get_info_callback.3" + ln -sf "SSL_CTX_set_info_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_info_callback.3" + ln -sf "SSL_CTX_set_keylog_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_keylog_callback.3" + ln -sf "SSL_CTX_set_keylog_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_keylog_cb_func.3" + ln -sf "SSL_CTX_set_max_cert_list.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_cert_list.3" + ln -sf "SSL_CTX_set_max_cert_list.3" "$(DESTDIR)$(mandir)/man3/SSL_get_max_cert_list.3" + ln -sf "SSL_CTX_set_max_cert_list.3" "$(DESTDIR)$(mandir)/man3/SSL_set_max_cert_list.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_proto_version.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_min_proto_version.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_proto_version.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_get_max_proto_version.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_get_min_proto_version.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_set_max_proto_version.3" + ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_set_min_proto_version.3" + ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_mode.3" + ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_mode.3" + ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_mode.3" + ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_mode.3" + ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_set_mode.3" + ln -sf "SSL_CTX_set_msg_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_msg_callback_arg.3" + ln -sf "SSL_CTX_set_msg_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback.3" + ln -sf "SSL_CTX_set_msg_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback_arg.3" + ln -sf "SSL_CTX_set_num_tickets.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_num_tickets.3" + ln -sf "SSL_CTX_set_num_tickets.3" "$(DESTDIR)$(mandir)/man3/SSL_get_num_tickets.3" + ln -sf "SSL_CTX_set_num_tickets.3" "$(DESTDIR)$(mandir)/man3/SSL_set_num_tickets.3" + ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_options.3" + ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_options.3" + ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_options.3" + ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_get_options.3" + ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_get_secure_renegotiation_support.3" + ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_set_options.3" + ln -sf "SSL_CTX_set_quiet_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_quiet_shutdown.3" + ln -sf "SSL_CTX_set_quiet_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_get_quiet_shutdown.3" + ln -sf "SSL_CTX_set_quiet_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_set_quiet_shutdown.3" + ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_read_ahead.3" + ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_read_ahead.3" + ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_get_read_ahead.3" + ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_set_read_ahead.3" + ln -sf "SSL_CTX_set_security_level.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_security_level.3" + ln -sf "SSL_CTX_set_security_level.3" "$(DESTDIR)$(mandir)/man3/SSL_get_security_level.3" + ln -sf "SSL_CTX_set_security_level.3" "$(DESTDIR)$(mandir)/man3/SSL_set_security_level.3" + ln -sf "SSL_CTX_set_session_cache_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_session_cache_mode.3" + ln -sf "SSL_CTX_set_session_id_context.3" "$(DESTDIR)$(mandir)/man3/SSL_set_session_id_context.3" + ln -sf "SSL_CTX_set_ssl_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ssl_method.3" + ln -sf "SSL_CTX_set_ssl_version.3" "$(DESTDIR)$(mandir)/man3/SSL_get_ssl_method.3" + ln -sf "SSL_CTX_set_ssl_version.3" "$(DESTDIR)$(mandir)/man3/SSL_set_ssl_method.3" + ln -sf "SSL_CTX_set_timeout.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_timeout.3" + ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_servername_arg.3" + ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_get_servername.3" + ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_get_servername_type.3" + ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_host_name.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_arg.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_cb.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_status_arg.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_ocsp_resp.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_type.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_ocsp_resp.3" + ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_type.3" + ln -sf "SSL_CTX_set_tlsext_use_srtp.3" "$(DESTDIR)$(mandir)/man3/SSL_get_selected_srtp_profile.3" + ln -sf "SSL_CTX_set_tlsext_use_srtp.3" "$(DESTDIR)$(mandir)/man3/SSL_get_srtp_profiles.3" + ln -sf "SSL_CTX_set_tlsext_use_srtp.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_use_srtp.3" + ln -sf "SSL_CTX_set_tmp_dh_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_dh.3" + ln -sf "SSL_CTX_set_tmp_dh_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh.3" + ln -sf "SSL_CTX_set_tmp_dh_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh_callback.3" + ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_need_tmp_RSA.3" + ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_rsa.3" + ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_need_tmp_RSA.3" + ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa.3" + ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa_callback.3" + ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_verify_depth.3" + ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/SSL_set_verify.3" + ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/SSL_set_verify_depth.3" + ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/verify_callback.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_check_private_key.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_ASN1.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_ASN1.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_ASN1.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_mem.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_check_private_key.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_ASN1.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_ASN1.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_ASN1.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_chain_file.3" + ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_file.3" + ln -sf "SSL_SESSION_free.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_up_ref.3" + ln -sf "SSL_SESSION_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ex_data.3" + ln -sf "SSL_SESSION_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_ex_data.3" + ln -sf "SSL_SESSION_get_id.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set1_id.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_timeout.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_time.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_timeout.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_get_time.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_get_timeout.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_set_time.3" + ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_set_timeout.3" + ln -sf "SSL_SESSION_has_ticket.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ticket_lifetime_hint.3" + ln -sf "SSL_SESSION_print.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_print_fp.3" + ln -sf "SSL_SESSION_set1_id_context.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get0_id_context.3" + ln -sf "SSL_alert_type_string.3" "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string.3" + ln -sf "SSL_alert_type_string.3" "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string_long.3" + ln -sf "SSL_alert_type_string.3" "$(DESTDIR)$(mandir)/man3/SSL_alert_type_string_long.3" + ln -sf "SSL_get_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_get_privatekey.3" + ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ciphers.3" + ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_get1_supported_ciphers.3" + ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_list.3" + ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_get_client_ciphers.3" + ln -sf "SSL_get_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_CA_list.3" + ln -sf "SSL_get_client_random.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_master_key.3" + ln -sf "SSL_get_client_random.3" "$(DESTDIR)$(mandir)/man3/SSL_get_server_random.3" + ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher.3" + ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_bits.3" + ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_name.3" + ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_version.3" + ln -sf "SSL_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_get_ex_data.3" + ln -sf "SSL_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_set_ex_data.3" + ln -sf "SSL_get_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_get_rfd.3" + ln -sf "SSL_get_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_get_wfd.3" + ln -sf "SSL_get_finished.3" "$(DESTDIR)$(mandir)/man3/SSL_get_peer_finished.3" + ln -sf "SSL_get_rbio.3" "$(DESTDIR)$(mandir)/man3/SSL_get_wbio.3" + ln -sf "SSL_get_session.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_session.3" + ln -sf "SSL_get_session.3" "$(DESTDIR)$(mandir)/man3/SSL_get1_session.3" + ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_accept_init.3" + ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_before.3" + ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_connect_init.3" + ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_init.3" + ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_is_init_finished.3" + ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_state.3" + ln -sf "SSL_get_version.3" "$(DESTDIR)$(mandir)/man3/SSL_is_dtls.3" + ln -sf "SSL_get_version.3" "$(DESTDIR)$(mandir)/man3/SSL_version.3" + ln -sf "SSL_library_init.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_add_ssl_algorithms.3" + ln -sf "SSL_library_init.3" "$(DESTDIR)$(mandir)/man3/SSLeay_add_ssl_algorithms.3" + ln -sf "SSL_load_client_CA_file.3" "$(DESTDIR)$(mandir)/man3/SSL_add_dir_cert_subjects_to_stack.3" + ln -sf "SSL_load_client_CA_file.3" "$(DESTDIR)$(mandir)/man3/SSL_add_file_cert_subjects_to_stack.3" + ln -sf "SSL_new.3" "$(DESTDIR)$(mandir)/man3/SSL_up_ref.3" + ln -sf "SSL_num_renegotiations.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_num_renegotiations.3" + ln -sf "SSL_num_renegotiations.3" "$(DESTDIR)$(mandir)/man3/SSL_total_renegotiations.3" + ln -sf "SSL_read.3" "$(DESTDIR)$(mandir)/man3/SSL_peek.3" + ln -sf "SSL_read.3" "$(DESTDIR)$(mandir)/man3/SSL_peek_ex.3" + ln -sf "SSL_read.3" "$(DESTDIR)$(mandir)/man3/SSL_read_ex.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_early_data.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_early_data.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_max_early_data.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_max_early_data.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_get_early_data_status.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_get_max_early_data.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_set_max_early_data.3" + ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_write_early_data.3" + ln -sf "SSL_renegotiate.3" "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_abbreviated.3" + ln -sf "SSL_renegotiate.3" "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_pending.3" + ln -sf "SSL_rstate_string.3" "$(DESTDIR)$(mandir)/man3/SSL_rstate_string_long.3" + ln -sf "SSL_set1_host.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_peername.3" + ln -sf "SSL_set1_host.3" "$(DESTDIR)$(mandir)/man3/SSL_set_hostflags.3" + ln -sf "SSL_set1_param.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_param.3" + ln -sf "SSL_set1_param.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_param.3" + ln -sf "SSL_set1_param.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_param.3" + ln -sf "SSL_set_connect_state.3" "$(DESTDIR)$(mandir)/man3/SSL_is_server.3" + ln -sf "SSL_set_connect_state.3" "$(DESTDIR)$(mandir)/man3/SSL_set_accept_state.3" + ln -sf "SSL_set_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_set_rfd.3" + ln -sf "SSL_set_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_set_wfd.3" + ln -sf "SSL_set_max_send_fragment.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_send_fragment.3" + ln -sf "SSL_set_psk_use_session_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_psk_use_session_cb_func.3" + ln -sf "SSL_set_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_get_shutdown.3" + ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ecdh_auto.3" + ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh.3" + ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh_callback.3" + ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_set_ecdh_auto.3" + ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_ecdh_callback.3" + ln -sf "SSL_state_string.3" "$(DESTDIR)$(mandir)/man3/SSL_state_string_long.3" + ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_nothing.3" + ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_read.3" + ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_write.3" + ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_x509_lookup.3" + ln -sf "SSL_write.3" "$(DESTDIR)$(mandir)/man3/SSL_write_ex.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_free.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_new.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_free.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_new.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_REQ_free.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_RESP_free.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_RESP_new.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_free.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_new.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_free.3" + ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_new.3" + ln -sf "UI_UTIL_read_pw.3" "$(DESTDIR)$(mandir)/man3/UI_UTIL_read_pw_string.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_destroy_method.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_closer.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_flusher.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_opener.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_prompt_constructor.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_reader.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_writer.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_closer.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_flusher.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_opener.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_prompt_constructor.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_reader.3" + ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_writer.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_action_string.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_output_string.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_result_string.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_test_string.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get_input_flags.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get_result_maxsize.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get_result_minsize.3" + ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_set_result.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_OpenSSL.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_error_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_info_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_input_boolean.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_input_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_user_data.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_verify_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_construct_prompt.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_ctrl.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_error_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_info_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_input_boolean.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_input_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_verify_string.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_free.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get0_result.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get0_user_data.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get_default_method.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get_method.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_new_method.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_null.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_process.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_set_default_method.3" + ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_set_method.3" + ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/ED25519_keypair.3" + ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/ED25519_sign.3" + ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/ED25519_verify.3" + ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/X25519_keypair.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509V3_EXT_d2i.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509V3_EXT_i2d.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509V3_add1_i2d.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_add1_ext_i2d.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_extensions.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_d2i.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add1_ext_i2d.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_extensions.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_d2i.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_add1_ext_i2d.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_get0_extensions.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_get0_uids.3" + ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_d2i.3" + ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_cmp.3" + ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_free.3" + ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_get0.3" + ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_new.3" + ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set0.3" + ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set_md.3" + ln -sf "X509_ATTRIBUTE_get0_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_count.3" + ln -sf "X509_ATTRIBUTE_get0_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_data.3" + ln -sf "X509_ATTRIBUTE_get0_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_type.3" + ln -sf "X509_ATTRIBUTE_new.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create.3" + ln -sf "X509_ATTRIBUTE_new.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_dup.3" + ln -sf "X509_ATTRIBUTE_new.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_free.3" + ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_NID.3" + ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_OBJ.3" + ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_txt.3" + ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_set1_data.3" + ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_free.3" + ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_new.3" + ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_CINF_free.3" + ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_VAL_free.3" + ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_VAL_new.3" + ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_METHOD_free.3" + ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_meth_data.3" + ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_default_method.3" + ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_meth_data.3" + ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_add0_revoked.3" + ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_by_cert.3" + ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_REVOKED.3" + ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_sort.3" + ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_free.3" + ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_new.3" + ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_dup.3" + ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_free.3" + ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_up_ref.3" + ln -sf "X509_CRL_print.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_print_fp.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_NID.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_OBJ.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_dup.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_free.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_critical.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_data.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_object.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_new.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_critical.3" + ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_data.3" + ln -sf "X509_INFO_new.3" "$(DESTDIR)$(mandir)/man3/X509_INFO_free.3" + ln -sf "X509_LOOKUP_hash_dir.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_file.3" + ln -sf "X509_LOOKUP_hash_dir.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_mem.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_dir.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_mem.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_alias.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_fingerprint.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_issuer_serial.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_subject.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_ctrl.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_free.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_init.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_load_file.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_shutdown.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir_env.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file.3" + ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file_env.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_NID.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_OBJ.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_txt.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_free.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_get_data.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_new.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_data.3" + ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_object.3" + ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry.3" + ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_NID.3" + ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_OBJ.3" + ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_delete_entry.3" + ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_entry_count.3" + ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_entry.3" + ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_index_by_OBJ.3" + ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_NID.3" + ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_OBJ.3" + ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_hash_old.3" + ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash.3" + ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash_old.3" + ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash.3" + ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash_old.3" + ln -sf "X509_NAME_new.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_free.3" + ln -sf "X509_NAME_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_oneline.3" + ln -sf "X509_NAME_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_print.3" + ln -sf "X509_NAME_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_print_ex_fp.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free_contents.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get0_X509_CRL.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get_type.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_idx_by_subject.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_new.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_by_subject.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_match.3" + ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_up_ref_count.3" + ln -sf "X509_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PKEY_free.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_free.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0_param.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set0_param.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_bio.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_fp.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_PUBKEY.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_bio.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_fp.3" + ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_PUBKEY.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_add.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_cleanup.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_name.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_sname.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_id.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_sname.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_count.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_id.3" + ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_trust.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_NID.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_OBJ.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_txt.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_delete_attr.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_NID.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_OBJ.3" + ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_count.3" + ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add_extensions_nid.3" + ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_extension_nid.3" + ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extension_nids.3" + ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extensions.3" + ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_extension_nids.3" + ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_free.3" + ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_new.3" + ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_dup.3" + ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_free.3" + ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_to_X509_REQ.3" + ln -sf "X509_REQ_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_print.3" + ln -sf "X509_REQ_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_print_fp.3" + ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_dup.3" + ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_free.3" + ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_revocationDate.3" + ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_serialNumber.3" + ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_revocationDate.3" + ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_serialNumber.3" + ln -sf "X509_SIG_get0.3" "$(DESTDIR)$(mandir)/man3/X509_SIG_getm.3" + ln -sf "X509_SIG_new.3" "$(DESTDIR)$(mandir)/man3/X509_SIG_free.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_chain.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_crl.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_issuer.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_parent_ctx.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_chain.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_chain.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_current_cert.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_error_depth.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_num_untrusted.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_verified_chain.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_current_cert.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error_depth.3" + ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_verify_cert_error_string.3" + ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_app_data.3" + ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_ex_data.3" + ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_app_data.3" + ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_ex_data.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_cleanup.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_free.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_cert.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_store.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_untrusted.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_init.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_crls.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_trusted_stack.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_untrusted.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_cert.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_chain.3" + ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_trusted_stack.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_param.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_purpose_inherit.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_param.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_default.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_depth.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_purpose.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_time.3" + ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_trust.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_check_issued_fn.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_check_issued.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_fn.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_check_issued.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_check_issued.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify.3" + ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_func.3" + ln -sf "X509_STORE_CTX_set_verify_cb.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify_cb.3" + ln -sf "X509_STORE_CTX_set_verify_cb.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_cb.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_certs.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_crls.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_issuer.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_by_subject.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_obj_by_subject.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_certs.3" + ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_crls.3" + ln -sf "X509_STORE_load_locations.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_add_lookup.3" + ln -sf "X509_STORE_load_locations.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_load_mem.3" + ln -sf "X509_STORE_load_locations.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_default_paths.3" + ln -sf "X509_STORE_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_free.3" + ln -sf "X509_STORE_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_up_ref.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_add_cert.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_add_crl.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_objects.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_param.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_data.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_new_index.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_depth.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_ex_data.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_flags.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_purpose.3" + ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_trust.3" + ln -sf "X509_STORE_set_verify_cb_func.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify_cb.3" + ln -sf "X509_STORE_set_verify_cb_func.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_cb.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_add.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_cleanup.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0_name.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_by_id.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_count.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_flags.3" + ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_trust.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_table.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_free.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_count.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_inherit.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_lookup.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1.3" + ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_table_cleanup.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_policy.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add1_host.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_clear_flags.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_name.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_peername.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_depth.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_flags.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_time.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_email.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_host.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip_asc.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_name.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_policies.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_auth_level.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_depth.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_hostflags.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_purpose.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_time.3" + ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_trust.3" + ln -sf "X509_add1_trust_object.3" "$(DESTDIR)$(mandir)/man3/X509_add1_reject_object.3" + ln -sf "X509_add1_trust_object.3" "$(DESTDIR)$(mandir)/man3/X509_reject_clear.3" + ln -sf "X509_add1_trust_object.3" "$(DESTDIR)$(mandir)/man3/X509_trust_clear.3" + ln -sf "X509_check_host.3" "$(DESTDIR)$(mandir)/man3/X509_check_email.3" + ln -sf "X509_check_host.3" "$(DESTDIR)$(mandir)/man3/X509_check_ip.3" + ln -sf "X509_check_host.3" "$(DESTDIR)$(mandir)/man3/X509_check_ip_asc.3" + ln -sf "X509_check_private_key.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_check_private_key.3" + ln -sf "X509_check_trust.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_set_default.3" + ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_cmp.3" + ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_match.3" + ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_cmp.3" + ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_and_serial_cmp.3" + ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_name_cmp.3" + ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_subject_name_cmp.3" + ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_cmp_current_time.3" + ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_gmtime_adj.3" + ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_time_adj.3" + ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_time_adj_ex.3" + ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_digest.3" + ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_digest.3" + ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_digest.3" + ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_digest.3" + ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_pubkey_digest.3" + ln -sf "X509_find_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_find_by_issuer_and_serial.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_lastUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_nextUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_lastUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_nextUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_lastUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_nextUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_lastUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_nextUpdate.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_get0_notAfter.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_get_notAfter.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_get_notBefore.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_getm_notAfter.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_getm_notBefore.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set1_notAfter.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set1_notBefore.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set_notAfter.3" + ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set_notBefore.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_signature.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_tbs_sigalg.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_signature_nid.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_signature.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_signature_nid.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_get0_tbs_sigalg.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_get_signature_nid.3" + ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_get_signature_type.3" + ln -sf "X509_get1_email.3" "$(DESTDIR)$(mandir)/man3/X509_email_free.3" + ln -sf "X509_get1_email.3" "$(DESTDIR)$(mandir)/man3/X509_get1_ocsp.3" + ln -sf "X509_get_extension_flags.3" "$(DESTDIR)$(mandir)/man3/X509_get_extended_key_usage.3" + ln -sf "X509_get_extension_flags.3" "$(DESTDIR)$(mandir)/man3/X509_get_key_usage.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_extract_key.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_pubkey.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_pubkey.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_pubkey.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_extract_key.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey_bitstr.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_get_X509_PUBKEY.3" + ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_set_pubkey.3" + ln -sf "X509_get_serialNumber.3" "$(DESTDIR)$(mandir)/man3/X509_get0_serialNumber.3" + ln -sf "X509_get_serialNumber.3" "$(DESTDIR)$(mandir)/man3/X509_set_serialNumber.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_issuer.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_issuer_name.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_subject_name.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_subject_name.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_get_issuer_name.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_set_issuer_name.3" + ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_set_subject_name.3" + ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_version.3" + ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_version.3" + ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_version.3" + ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_version.3" + ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_set_version.3" + ln -sf "X509_keyid_set1.3" "$(DESTDIR)$(mandir)/man3/X509_alias_get0.3" + ln -sf "X509_keyid_set1.3" "$(DESTDIR)$(mandir)/man3/X509_alias_set1.3" + ln -sf "X509_keyid_set1.3" "$(DESTDIR)$(mandir)/man3/X509_keyid_get0.3" + ln -sf "X509_load_cert_file.3" "$(DESTDIR)$(mandir)/man3/X509_load_cert_crl_file.3" + ln -sf "X509_load_cert_file.3" "$(DESTDIR)$(mandir)/man3/X509_load_crl_file.3" + ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_to_X509.3" + ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_chain_up_ref.3" + ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_dup.3" + ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_free.3" + ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_up_ref.3" + ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_print.3" + ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_print.3" + ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_print_ex_fp.3" + ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_print_fp.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_sign.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_sign_ctx.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_verify.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_sign.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_sign_ctx.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_verify.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_sign_ctx.3" + ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_verify.3" + ln -sf "X509_signature_dump.3" "$(DESTDIR)$(mandir)/man3/X509_signature_print.3" + ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_NID.3" + ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_OBJ.3" + ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_txt.3" + ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_delete_attr.3" + ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get0_data_by_OBJ.3" + ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_NID.3" + ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_OBJ.3" + ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get_attr_count.3" + ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_prefix.3" + ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_range.3" + ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_canonize.3" + ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_is_canonical.3" + ln -sf "X509v3_addr_get_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_get_afi.3" + ln -sf "X509v3_addr_inherits.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_inherits.3" + ln -sf "X509v3_addr_subset.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_subset.3" + ln -sf "X509v3_addr_validate_path.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_validate_resource_set.3" + ln -sf "X509v3_addr_validate_path.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_path.3" + ln -sf "X509v3_addr_validate_path.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_resource_set.3" + ln -sf "X509v3_asid_add_id_or_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_add_inherit.3" + ln -sf "X509v3_asid_add_id_or_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_canonize.3" + ln -sf "X509v3_asid_add_id_or_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_is_canonical.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_add_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_delete_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_NID.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_OBJ.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_critical.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_count.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_delete_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_NID.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_OBJ.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_critical.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_count.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_add_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_delete_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_NID.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_OBJ.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_critical.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_count.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_add_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_delete_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_OBJ.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_critical.3" + ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_count.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_add_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_check_top.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_cmp_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_div_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_expand.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_expand2.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_fix_top.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_add_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_comba4.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_comba8.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_normal.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_part_recursive.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_recursive.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_set_high.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_set_low.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_set_max.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_comba4.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_comba8.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_normal.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_recursive.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sub_words.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_wexpand.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/mul.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/mul_add.3" + ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/sqr.3" + ln -sf "d2i_ASN1_NULL.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_NULL.3" + ln -sf "d2i_ASN1_OBJECT.3" "$(DESTDIR)$(mandir)/man3/OBJ_get0_data.3" + ln -sf "d2i_ASN1_OBJECT.3" "$(DESTDIR)$(mandir)/man3/OBJ_length.3" + ln -sf "d2i_ASN1_OBJECT.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OBJECT.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BIT_STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BMPSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_ENUMERATED.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALIZEDTIME.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_IA5STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_INTEGER.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLE.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLESTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_T61STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TIME.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UINTEGER.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UNIVERSALSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTCTIME.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTF8STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_VISIBLESTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_DIRECTORYSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_DISPLAYTEXT.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BIT_STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BMPSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_ENUMERATED.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALIZEDTIME.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_IA5STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_INTEGER.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OCTET_STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLE.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLESTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_T61STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TIME.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UNIVERSALSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTCTIME.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTF8STRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_VISIBLESTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_DIRECTORYSTRING.3" + ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_DISPLAYTEXT.3" + ln -sf "d2i_ASN1_SEQUENCE_ANY.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_SET_ANY.3" + ln -sf "d2i_ASN1_SEQUENCE_ANY.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SEQUENCE_ANY.3" + ln -sf "d2i_ASN1_SEQUENCE_ANY.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SET_ANY.3" + ln -sf "d2i_AUTHORITY_KEYID.3" "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_KEYID.3" + ln -sf "d2i_BASIC_CONSTRAINTS.3" "$(DESTDIR)$(mandir)/man3/d2i_EXTENDED_KEY_USAGE.3" + ln -sf "d2i_BASIC_CONSTRAINTS.3" "$(DESTDIR)$(mandir)/man3/i2d_BASIC_CONSTRAINTS.3" + ln -sf "d2i_BASIC_CONSTRAINTS.3" "$(DESTDIR)$(mandir)/man3/i2d_EXTENDED_KEY_USAGE.3" + ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/d2i_CMS_ReceiptRequest.3" + ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/d2i_CMS_bio.3" + ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/i2d_CMS_ContentInfo.3" + ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/i2d_CMS_ReceiptRequest.3" + ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/i2d_CMS_bio.3" + ln -sf "d2i_DHparams.3" "$(DESTDIR)$(mandir)/man3/i2d_DHparams.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_ACCESS_DESCRIPTION.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_AUTHORITY_INFO_ACCESS.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_CRL_DIST_POINTS.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_DIST_POINT_NAME.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_ISSUING_DIST_POINT.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_ACCESS_DESCRIPTION.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_INFO_ACCESS.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_CRL_DIST_POINTS.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT_NAME.3" + ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_ISSUING_DIST_POINT.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/DSAparams_dup.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_bio.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_fp.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_bio.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_fp.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_SIG.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAparams.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_bio.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_fp.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_bio.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_fp.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPublicKey.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_bio.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_fp.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_SIG.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAparams.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_bio.3" + ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECPKParameters_print.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECPKParameters_print_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECParameters_dup.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECParameters_print.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECParameters_print_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_bio.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECParameters.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_bio.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_bio.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_bio.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECParameters.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_bio.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_bio.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_fp.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2o_ECPublicKey.3" + ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/o2i_ECPublicKey.3" + ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/d2i_ESS_CERT_ID.3" + ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/d2i_ESS_ISSUER_SERIAL.3" + ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/i2d_ESS_CERT_ID.3" + ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/i2d_ESS_ISSUER_SERIAL.3" + ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/i2d_ESS_SIGNING_CERT.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_EDIPARTYNAME.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_GENERAL_NAMES.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_OTHERNAME.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_EDIPARTYNAME.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAME.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAMES.3" + ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_OTHERNAME.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTID.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_ONEREQ.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REQINFO.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SERVICELOC.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SIGNATURE.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTID.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_ONEREQ.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQINFO.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQUEST.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SERVICELOC.3" + ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SIGNATURE.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_BASICRESP.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTSTATUS.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CRLID.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPBYTES.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPDATA.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPID.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REVOKEDINFO.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SINGLERESP.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_BASICRESP.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTSTATUS.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CRLID.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPBYTES.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPDATA.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPID.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPONSE.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REVOKEDINFO.3" + ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SINGLERESP.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_BAGS.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_MAC_DATA.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_SAFEBAG.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_bio.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_fp.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_BAGS.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_MAC_DATA.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_SAFEBAG.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_bio.3" + ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_fp.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_DIGEST.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENCRYPT.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENC_CONTENT.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENVELOPE.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ISSUER_AND_SERIAL.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_RECIP_INFO.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNED.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNER_INFO.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGN_ENVELOPE.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_bio.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_fp.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_DIGEST.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENCRYPT.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENC_CONTENT.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENVELOPE.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ISSUER_AND_SERIAL.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_RECIP_INFO.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNED.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNER_INFO.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGN_ENVELOPE.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_bio.3" + ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_fp.3" + ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8PrivateKey_fp.3" + ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_bio.3" + ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_fp.3" + ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_bio.3" + ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_fp.3" + ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_bio.3" + ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_fp.3" + ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO.3" + ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_bio.3" + ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_fp.3" + ln -sf "d2i_PKEY_USAGE_PERIOD.3" "$(DESTDIR)$(mandir)/man3/i2d_PKEY_USAGE_PERIOD.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_CERTIFICATEPOLICIES.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_NOTICEREF.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_POLICYQUALINFO.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_USERNOTICE.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_CERTIFICATEPOLICIES.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_NOTICEREF.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_POLICYINFO.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_POLICYQUALINFO.3" + ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_USERNOTICE.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_AutoPrivateKey.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_bio.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_fp.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_PublicKey.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_bio.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_fp.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_bio.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_fp.3" + ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PublicKey.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_Netscape_RSA.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_bio.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_fp.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_bio.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_fp.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PSS_PARAMS.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_bio.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_fp.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_Netscape_RSA.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_bio.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_fp.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_bio.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_fp.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PSS_PARAMS.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_bio.3" + ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_fp.3" + ln -sf "d2i_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/i2d_SSL_SESSION.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_ACCURACY.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_STATUS_INFO.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_ACCURACY.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_fp.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_STATUS_INFO.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_bio.3" + ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_fp.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_AUX.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CERT_AUX.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CINF.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_VAL.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_bio.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_fp.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_AUX.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CERT_AUX.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CINF.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_VAL.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_bio.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_fp.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_re_X509_CRL_tbs.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_re_X509_REQ_tbs.3" + ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_re_X509_tbs.3" + ln -sf "d2i_X509_ALGOR.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_ALGORS.3" + ln -sf "d2i_X509_ALGOR.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGOR.3" + ln -sf "d2i_X509_ALGOR.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGORS.3" + ln -sf "d2i_X509_ATTRIBUTE.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_ATTRIBUTE.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_INFO.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_bio.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_fp.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REVOKED.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_INFO.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_bio.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_fp.3" + ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REVOKED.3" + ln -sf "d2i_X509_EXTENSION.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_EXTENSIONS.3" + ln -sf "d2i_X509_EXTENSION.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSION.3" + ln -sf "d2i_X509_EXTENSION.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSIONS.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_dup.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_dup.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get0_der.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_set.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_NAME_ENTRY.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME.3" + ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME_ENTRY.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_INFO.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_bio.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_fp.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_INFO.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_bio.3" + ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_fp.3" + ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_bio.3" + ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_fp.3" + ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_bio.3" + ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_fp.3" + ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_SIG.3" + ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_get_pw_prompt.3" + ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string.3" + ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string_min.3" + ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_set_pw_prompt.3" + ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/a2i_ASN1_ENUMERATED.3" + ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/a2i_ASN1_INTEGER.3" + ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/a2i_ASN1_STRING.3" + ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/i2a_ASN1_ENUMERATED.3" + ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/i2a_ASN1_INTEGER.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/DECLARE_LHASH_OF.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_COMP_FN_TYPE.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_ARG_FN_TYPE.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_FN_TYPE.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_HASH_FN_TYPE.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_delete.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_doall.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_doall_arg.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_error.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_free.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_insert.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_retrieve.3" + ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_strhash.3" + ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_stats.3" + ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_stats_bio.3" + ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats.3" + ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats_bio.3" + ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_stats_bio.3" + ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED.3" + ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED_TABLE.3" + ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_INTEGER.3" + ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_OCTET_STRING.3" + ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/s2i_ASN1_OCTET_STRING.3" + ln -sf "tls_accept_socket.3" "$(DESTDIR)$(mandir)/man3/tls_accept_cbs.3" + ln -sf "tls_accept_socket.3" "$(DESTDIR)$(mandir)/man3/tls_accept_fds.3" + ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_configure.3" + ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_free.3" + ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_reset.3" + ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_server.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_parse_protocols.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_client.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_server.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_alpn.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ciphers.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_dheparams.3" + ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ecdhecurves.3" + ln -sf "tls_config_set_session_id.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_ticket_key.3" + ln -sf "tls_config_set_session_id.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_session_fd.3" + ln -sf "tls_config_set_session_id.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_session_lifetime.3" + ln -sf "tls_config_verify.3" "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifycert.3" + ln -sf "tls_config_verify.3" "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifyname.3" + ln -sf "tls_config_verify.3" "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifytime.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_alpn_selected.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_cipher.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_cipher_strength.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_servername.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_session_resumed.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_chain_pem.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_contains_name.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_hash.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_issuer.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notafter.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notbefore.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_provided.3" + ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_subject.3" + ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_cbs.3" + ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_fds.3" + ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_servername.3" + ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_socket.3" + ln -sf "tls_init.3" "$(DESTDIR)$(mandir)/man3/tls_config_error.3" + ln -sf "tls_init.3" "$(DESTDIR)$(mandir)/man3/tls_config_free.3" + ln -sf "tls_init.3" "$(DESTDIR)$(mandir)/man3/tls_config_new.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_clear_keys.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_path.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_key_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_key_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_mem.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_verify_depth.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_verify_client.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_verify_client_optional.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_default_ca_cert_file.3" + ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_unload_file.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_cert_status.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_crl_reason.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_next_update.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_response_status.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_result.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_revocation_time.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_this_update.3" + ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_url.3" + ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_close.3" + ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_error.3" + ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_handshake.3" + ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_write.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_chain.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_depth.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_string.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_free.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_new.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_intermediates.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_chains.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_depth.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_signatures.3" + ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_purpose.3" + +uninstall-local: + -rm -f "$(DESTDIR)$(mandir)/man3/ACCESS_DESCRIPTION_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AES_cbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AES_decrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AES_set_decrypt_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AES_set_encrypt_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASIdentifiers_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifiers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifiers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_get_bit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_set_bit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get_int64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set_int64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_to_BN.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_int64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_uint64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_int64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_uint64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_to_BN.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_ENUMERATED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_INTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_NULL_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_create.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_get.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get0_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_length_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_to_UTF8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print_ex_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_tag2str.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_adj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_adj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_cmp_time_t.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_compare.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_diff.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_normalize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_generalizedtime.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_tm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_adj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_cmp_time_t.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_int_octetstring.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_octetstring.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_int_octetstring.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_octetstring.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_generate_v3.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TYPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TYPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_unpack.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_sign_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get_default_mask.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask_asc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_mbstring_ncopy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_tag2bit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_parse.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_object_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_put_eoc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_tm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_time_tm_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASIdOrRange_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASIdOrRange_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASRange_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASIdOrRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifierChoice.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASIdOrRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifierChoice.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/AUTHORITY_KEYID_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BASIC_CONSTRAINTS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BF_cbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BF_cfb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BF_decrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BF_ecb_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BF_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BF_ofb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_accept_socket.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_host_ip.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_tcp_ndelay.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_sock_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_sock_non_fatal_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_sock_should_retry.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_socket_nbio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_callback_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_pending.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_wpending.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_eof.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_flush.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_close.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_info_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_info_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_int_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_pending.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ptr_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_reset.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_seek.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_close.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_info_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_tell.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_wpending.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bio_info_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dump_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dump_indent.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dump_indent_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dup_state.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_buffer_num_lines.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_read_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_read_buffer_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_write_buffer_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_status.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_md_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_md_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_do_handshake.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_num_renegotiates.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_ssl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_buffer_ssl_connect.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_ssl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_ssl_connect.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_bytes.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_timeout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ssl_copy_session_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ssl_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_method_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_method_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_next.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_clear_retry_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_copy_next_retry.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_retry_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_special.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_test_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_get_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_set_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_callback_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_create.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_destroy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_gets.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_puts.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_callback_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_create.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_destroy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_gets.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_puts.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_free_all.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_vfree.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_snprintf.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_vprintf.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_vsnprintf.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_pop.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_next.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_gets.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_indent.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_number_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_number_written.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_puts.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_do_accept.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_accept_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_bind_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_accept.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_accept_bios.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_accept_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_bind_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_nbio_accept.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_read_request.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_write_guarantee.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_reset_read_request.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_destroy_bio_pair.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_read_request.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_write_buf_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_write_guarantee.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_make_bio_pair.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_bio_pair.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_write_buf_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_shutdown_wr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_do_connect.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_hostname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_int_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_ip.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_connect.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_hostname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_int_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_ip.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_port.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_nbio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_dgram_connect.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_set_connected.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_get_peer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_non_fatal_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_recv_timedout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_send_timedout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_set_peer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_dgram.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_fd_non_fatal_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_fd_should_retry.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_fd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_fd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_fd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_append_filename.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_read_filename.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_rw_filename.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_write_filename.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_mem_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_mem_ptr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_mem_buf.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_mem_buf.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_mem_eof_return.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_socket.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_callback_fn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_callback_fn_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_debug_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_callback_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_callback_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_callback_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_callback_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_retry_BIO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_retry_reason.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_retry_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_reason.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_should_io_special.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_should_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BIO_should_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_CTX_end.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_CTX_get.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_div.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_exp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_gcd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_add.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_add_quick.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_exp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1_quick.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift_quick.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_mul.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_sqr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_sub.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_sub_quick.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mul.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_nnmod.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_sqr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_sub.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_uadd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_usub.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_div_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mul_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_sub_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_asc2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_bin2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2binpad.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2dec.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2hex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2lebinpad.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2mpi.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_dec2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_hex2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_lebin2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mpi2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_abs_is_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_odd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_one.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_zero.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_ucmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_with_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_call.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_get_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_set_old.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_generate_prime_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_prime_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_prime_fasttest_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_1024.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_768.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_1536.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_2048.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_3072.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_4096.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_6144.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set_locked.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_from_montgomery.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_to_montgomery.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_clear.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_clear_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_num_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_num_bits_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand_range.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_rand_range.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_clear_bit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_bit_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_lshift.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_lshift1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_mask_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_rshift.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_rshift1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_negative.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_consttime_swap.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_one.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_set_word.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_value_one.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BUF_MEM_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow_clean.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_get0_cipher_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_resume.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_print_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add0_crl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add1_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add1_crl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get1_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get1_crls.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add0_recipient_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_pkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_decrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_get0_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_id_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_cert_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_get0_signer_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_pkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_cert_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signature.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signer_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_set1_signer_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get0_content.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get0_eContentType.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_set1_eContentType.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_create0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_get0_values.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add1_ReceiptRequest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get0_signers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CONF_modules_finish.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CONF_modules_unload.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CONF_modules_load.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_area.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_MEM_LEAK_CB.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_set_mem_functions.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cpy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_current.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_hash.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_add.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_r_lock.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_r_unlock.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_w_lock.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_w_unlock.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_free_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_new_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_chacha_20.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_hchacha_20.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_xchacha_20.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ChaCha_set_iv.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ChaCha_set_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_cbc_cksum.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_cfb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_cfb_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_crypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ecb2_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ecb3_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ecb_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede2_cbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede2_cfb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede2_ofb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_cbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_cbcm_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_cfb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_ofb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_enc_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_enc_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_fcrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_is_weak_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_key_sched.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ncbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ofb64_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_ofb_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_pcbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_quad_cksum.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_random_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_set_key_checked.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_set_key_unchecked.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_set_odd_parity.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_string_to_2keys.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_string_to_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DES_xcbc_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_compute_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_check_pub_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_generate_parameters_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_engine.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_g.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_p.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_priv_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_pub_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_q.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_set0_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_set0_pqg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_test_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_OpenSSL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_get_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_new_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DIST_POINT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_SIG_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_SIG_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_SIG_set0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_do_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_generate_parameters_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_engine.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_g.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_p.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_priv_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_pub_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_q.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set0_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set0_pqg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_test_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_get0_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_set1_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_set_finish.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_set_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_OpenSSL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_new_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_sign_setup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDH_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_r.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_s.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_set0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_do_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_do_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECDSA_SIG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECDSA_SIG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GFp_mont_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_METHOD_get_field_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_check_discriminant.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_generator.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_seed.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_asn1_flag.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_basis_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_cofactor.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_degree.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_order.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_point_conversion_form.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_seed_len.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_method_of.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_order_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_asn1_flag.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_generator.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_point_conversion_form.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_seed.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_clear_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_by_curve_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_curve_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_get_builtin_curves.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_compute_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_keygen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_compute_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_keygen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_OpenSSL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_new_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_check_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_generate_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_group.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_public_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_conv_form.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_enc_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_new_by_curve_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_precompute_mult.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_asn1_flag.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_conv_form.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_enc_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_group.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key_affine_coordinates.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_have_precompute_mult.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_precompute_mult.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_dbl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_invert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_is_at_infinity.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_is_on_curve.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_make_affine.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_mul.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINTs_make_affine.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINTs_mul.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_bn2point.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_clear_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_get_Jprojective_coordinates_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_hex2point.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_method_of.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_oct2point.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_point2bn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_point2hex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_point2oct.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_Jprojective_coordinates_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates_GFp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_to_infinity.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_by_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_first.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_last.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_next.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_prev.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_remove.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_CTRL_FUNC_PTR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_cmd_is_executable.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_cmd_defns.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ctrl_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_cmd_defns.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_ctrl_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher_engine.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_EC.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest_engine.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_table_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_table_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_finish.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_finish_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_init_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_finish_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_init_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_destroy_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_destroy_function.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_STORE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_complete.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_load_builtin_engines.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_load_dynamic.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_STORE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_complete.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_CIPHERS_PTR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_DIGESTS_PTR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_EC.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_STORE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_EC.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_STORE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_RAND.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_STORE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_FATAL_ERROR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_GET_FUNC.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_GET_REASON.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_error_string_n.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_func_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_lib_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_reason_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_get_error_line.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_get_error_line_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_free_strings.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_load_error_strings.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_PACK.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_get_next_error_library.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_print_errors_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_print_errors_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_add_error_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_add_error_vdata.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_remove_thread_state.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ERR_pop_to_mark.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ESS_SIGNING_CERT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_open.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_seal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_key_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_overhead.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_tag_len.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_nonce_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_128_gcm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_256_gcm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_chacha20_poly1305.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_xchacha20_poly1305.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_iv.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_iv_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_key_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_iv.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_key_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_padding.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_iv_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_key_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_buf_noconst.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_cipher_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_rand_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_test_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_asn1_to_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_param_to_asn1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_do_all_sorted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all_sorted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_do_cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_get_asn1_params.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_impl_ctx_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_iv_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_set_asn1_params.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_block_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_block_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_Digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestInit_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_create.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_destroy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_reset.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_digestbynid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyobj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md_null.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_ripemd160.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha224.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha256.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha384.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha512.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha512_224.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha512_256.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestSign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestSignFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestSignUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestVerify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeBlock.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeInit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncodeBlock.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncodeFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncodeUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_encrypting.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_reset.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_Cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherInit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherInit_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptInit_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_enc_null.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbynid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyobj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_40_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_64_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_pkey_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_pkey_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_test_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_app_datasize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_input_blocksize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_result_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_block_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_block_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_pkey_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_OpenFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_OpenUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY2PKCS8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_ctrl_str.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_ecdh_kdf_ukm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id_len.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_cofactor_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_outlen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_signature_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_ecdh_kdf_ukm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_generator.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_prime_len.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dsa_paramgen_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_param_enc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_paramgen_curve_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_cofactor_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_outlen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_signature_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_pkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_new_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_add1_hkdf_info.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_hkdf_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_salt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_txt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_delete_attr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find_str.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0_info.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_asn1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add_alias.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_private.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_security_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_param_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_public_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_cmp_parameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_copy_parameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_missing_parameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_peerkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_set_peer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_keygen_info.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_keygen_info.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_gen_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_keygen_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_add0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_find.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_decrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_derive.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_encrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_keygen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_param_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_paramgen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_public_check.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_signctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify_recover.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verifyctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_public_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_CMAC_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_mac_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_public_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_params.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_public.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_EC_KEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_GOST.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_base_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_EC_KEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_hmac.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_EC_KEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DH.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_EC_KEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type_str.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_sign_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_security_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_recover_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SealFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SealUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SignFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SignInit_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SignUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_VerifyFinal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_VerifyInit_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_VerifyUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_add_cipher_alias.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_add_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_add_digest_alias.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_delete_cipher_alias.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_delete_digest_alias.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cbc_hmac_sha1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ccm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ctr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_gcm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_wrap.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_xts.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ccm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ctr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_gcm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_wrap.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc_hmac_sha1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ccm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ctr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_gcm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_wrap.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_xts.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_chacha20_poly1305.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb64.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_desx_cbc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc4_40.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc4_hmac_md5.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md4.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md5.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md5_sha1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha3_256.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha3_384.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha3_512.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb128.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_ctr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_ecb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_ofb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EXTENDED_KEY_USAGE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_NAME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OTHERNAME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OTHERNAME_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_copy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_get_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_reset.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Init_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressChoice_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressChoice_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressFamily_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressFamily_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressRange_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressChoice.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressFamily.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressOrRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressChoice.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressFamily.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressOrRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressRange.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD4.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD4_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD4_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD4_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD5_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD5_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/MD5_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/NAME_CONSTRAINTS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all_sorted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_get.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_remove.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_add_object.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_create_objects.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_new_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/check_defer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/obj_cleanup_defer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_find_sigid_by_algs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_ln2nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_nid2ln.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_nid2sn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_obj2nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_obj2txt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_sn2nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_txt2nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_txt2obj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2a_ASN1_OBJECT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2t_ASN1_OBJECT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CRLID_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQUEST_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_add0_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_add1_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SERVICELOC_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_url_svcloc_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_cert_id_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_id_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_id_get0_info.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_id_issuer_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_basic_add1_nonce.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_check_nonce.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_copy_nonce.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_get0_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_basic_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_cert_status_str.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_check_validity.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_resp_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_resp_find.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_resp_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_single_get0_status.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_basic_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_response_create.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_response_get1_basic.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_response_status_str.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_add1_header.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_set1_req.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_parse_url.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_nbio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_NUMBER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_TEXT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_VERSION_TEXT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_version_num.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_no_config.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_add_oid_module.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_add_conf_module.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_malloc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_realloc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_strdup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_realloc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_strdup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_delete.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_delete_ptr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_find.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_find_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_insert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_is_sorted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_new_null.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_num.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_pop.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_pop_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_push.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_set_cmp_func.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_shift.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_sort.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_unshift.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_value.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sk_zero.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_digests.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay_add_all_algorithms.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_ASN1_read_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_of_void.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_X509_INFO_read_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_def_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_do_header.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_get_EVP_CIPHER_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/pem_password_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_SSL_SESSION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_SSL_SESSION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_SSL_SESSION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_CMS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DHparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DSAparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_ECPKParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_ECPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_EC_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS7.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8_PRIV_KEY_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_RSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509_CRL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_CMS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DHparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPKParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_EC_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS7.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8_PRIV_KEY_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_CRL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_CMS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DHparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DSAparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_ECPKParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_ECPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_EC_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS7.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8_PRIV_KEY_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_RSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_CRL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ_NEW.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_CMS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DHparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPKParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_EC_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS7.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8_PRIV_KEY_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_CRL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ_NEW.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_SAFEBAG_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS5_PBKDF2_HMAC_SHA1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add0_attrib_signing_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add1_attrib_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_content_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_smimecap.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add_signed_attribute.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_get_attribute.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_get_signed_attribute.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_set_attributes.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_set_signed_attributes.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_content_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_set0_type_other.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_get0_signers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_PRIV_KEY_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_add1_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0_attrs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKEY_USAGE_PERIOD_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/NOTICEREF_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/NOTICEREF_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICYINFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/USERNOTICE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/USERNOTICE_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_poll.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_seed.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_status.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_pseudo_bytes.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_file_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_write_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_SSLeay.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RAND_get_rand_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RC4_set_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RIPEMD160_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RIPEMD160_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RIPEMD160_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_PSS_PARAMS_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_blinding_off.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_generate_key_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_crt_params.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_dmp1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_dmq1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_e.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_factors.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_iqmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_n.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_p.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_q.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set0_crt_params.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set0_factors.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set0_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_test_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_bn_mod_exp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_finish.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_keygen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_mod_exp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_dec.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_enc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_dec.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_enc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set0_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set1_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_bn_mod_exp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_finish.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_keygen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_mod_exp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_dec.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_enc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_dec.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_enc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSAPrivateKey_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSAPublicKey_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_OAEP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_type_2.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_add_none.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_OAEP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_2.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_none.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_rsa_oaep_label.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_mgf1_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_oaep_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_padding.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_pss_saltlen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_pubexp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_mgf1_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_oaep_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_padding.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_saltlen.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DHparams_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DHparams_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSAparams_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSAparams_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_public_decrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_old.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_old.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_private_decrypt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/BN_security_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DH_security_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSA_security_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_PKCS1_SSLeay.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_new_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_verify_ASN1_OCTET_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/RSA_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA1_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA1_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA1_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA224.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA224_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA224_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA224_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA256.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA256_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA256_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA256_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA384.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA384_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA384_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA384_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA512.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA512_Final.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA512_Init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SHA512_Update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_description.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_find.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_auth_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_cipher_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_digest_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_kx_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_is_aead.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_COMP_get_compression_methods.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_add0_chain_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_chain_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_chain_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set0_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add0_chain_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add1_chain_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_chain_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_chain_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set0_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_extra_chain_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs_only.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_remove_session.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_callback_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_callback_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_verify_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_verify_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_verify_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_verify_paths.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLS_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLS_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLS_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_2_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_2_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_2_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLv23_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLv23_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLv23_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLS_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLS_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLS_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_1_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_1_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_1_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_2_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_2_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_2_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_client_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_server_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_good.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_renegotiate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cache_full.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cb_hits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_good.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_renegotiate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_hits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_misses.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_timeouts.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_cache_size.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_get_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_new_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_remove_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_new_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_remove_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/get_session_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/new_session_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/remove_session_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_groups_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_curves.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_curves_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_groups.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_groups_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_alpn_protos.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_alpn_selected.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_select_next_proto.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_alpn_protos.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_cert_store.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_cipher_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_add_client_CA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add_client_CA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_client_CA_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_cert_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/client_cert_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb_userdata.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_passwd_cb_userdata.3" + -rm -f "$(DESTDIR)$(mandir)/man3/GEN_SESSION_CB.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_has_matching_session_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_generate_session_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_info_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_info_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_info_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_keylog_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_keylog_cb_func.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_cert_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_max_cert_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_max_cert_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_min_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_max_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_min_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_max_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_min_proto_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_msg_callback_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_num_tickets.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_num_tickets.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_num_tickets.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_options.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_options.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_options.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_options.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_secure_renegotiation_support.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_options.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_quiet_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_quiet_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_quiet_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_read_ahead.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_read_ahead.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_read_ahead.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_read_ahead.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_security_level.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_security_level.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_security_level.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_session_cache_mode.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_session_id_context.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ssl_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_ssl_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_ssl_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_timeout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_servername_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_servername.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_servername_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_host_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_status_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_ocsp_resp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_ocsp_resp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_selected_srtp_profile.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_srtp_profiles.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_use_srtp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_dh.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_need_tmp_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_rsa.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_need_tmp_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_verify_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_verify_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/verify_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_check_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_ASN1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_ASN1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_ASN1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_check_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_ASN1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_ASN1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_ASN1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_chain_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set1_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_timeout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_timeout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_timeout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_timeout.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ticket_lifetime_hint.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get0_id_context.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string_long.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_alert_type_string_long.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_privatekey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get1_supported_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_client_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_CA_list.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_master_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_server_random.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_bits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_rfd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_wfd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_peer_finished.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_wbio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_session.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get1_session.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_accept_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_before.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_connect_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_is_init_finished.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_state.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_is_dtls.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_add_ssl_algorithms.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay_add_ssl_algorithms.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add_dir_cert_subjects_to_stack.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add_file_cert_subjects_to_stack.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_num_renegotiations.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_total_renegotiations.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_peek.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_peek_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_read_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_max_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_max_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_early_data_status.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_max_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_max_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_write_early_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_abbreviated.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_pending.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_rstate_string_long.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_peername.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_hostflags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_is_server.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_accept_state.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_rfd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_wfd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_send_fragment.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_psk_use_session_cb_func.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ecdh_auto.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_ecdh_auto.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_ecdh_callback.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_state_string_long.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_nothing.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_read.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_x509_lookup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/SSL_write_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_REQ_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_RESP_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_RESP_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_UTIL_read_pw_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_destroy_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_closer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_flusher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_opener.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_prompt_constructor.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_reader.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_writer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_closer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_flusher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_opener.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_prompt_constructor.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_reader.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_writer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_action_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_output_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_result_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_test_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_input_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_result_maxsize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_result_minsize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_result.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_OpenSSL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_info_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_input_boolean.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_input_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_user_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_verify_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_construct_prompt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_info_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_input_boolean.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_input_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_verify_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_result.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_user_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_new_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_null.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_process.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ED25519_keypair.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ED25519_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ED25519_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X25519_keypair.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509V3_EXT_d2i.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509V3_EXT_i2d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509V3_add1_i2d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_add1_ext_i2d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_extensions.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_d2i.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add1_ext_i2d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_extensions.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_d2i.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_add1_ext_i2d.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_extensions.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_uids.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_d2i.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set_md.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_txt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_set1_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CINF_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VAL_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VAL_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_METHOD_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_meth_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_default_method.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_meth_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_add0_revoked.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_by_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_REVOKED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_sort.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_critical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_object.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_critical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_dir.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_alias.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_fingerprint.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_issuer_serial.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_subject.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_ctrl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_load_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_shutdown.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir_env.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file_env.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_txt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_get_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_object.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_delete_entry.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_entry_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_entry.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_index_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_hash_old.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash_old.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash_old.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_oneline.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_print_ex_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free_contents.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get0_X509_CRL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_idx_by_subject.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_by_subject.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_match.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_up_ref_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PKEY_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_add.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_sname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_sname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_trust.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_txt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_delete_attr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add_extensions_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_extension_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extension_nids.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extensions.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_extension_nids.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_to_X509_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_revocationDate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_serialNumber.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_revocationDate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_serialNumber.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_SIG_getm.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_SIG_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_crl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_issuer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_parent_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_current_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_error_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_num_untrusted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_verified_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_current_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_verify_cert_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_app_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_store.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_untrusted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_init.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_crls.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_trusted_stack.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_untrusted.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_trusted_stack.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_purpose_inherit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_default.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_purpose.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_trust.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_check_issued_fn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_check_issued.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_fn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_check_issued.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_check_issued.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_func.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_crls.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_issuer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_by_subject.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_obj_by_subject.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_certs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_crls.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_add_lookup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_load_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_default_paths.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_add_cert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_add_crl.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_objects.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_param.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_new_index.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_ex_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_purpose.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_trust.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_cb.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_add.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_by_id.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_trust.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_table.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_inherit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_lookup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_table_cleanup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_policy.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add1_host.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_clear_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_peername.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_flags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_email.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_host.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip_asc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_policies.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_auth_level.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_hostflags.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_purpose.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_trust.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_add1_reject_object.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_reject_clear.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_trust_clear.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_check_email.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_check_ip.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_check_ip_asc.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_check_private_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_set_default.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_match.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_and_serial_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_name_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_subject_name_cmp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_cmp_current_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_gmtime_adj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_time_adj.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_time_adj_ex.3" + -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_pubkey_digest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_find_by_issuer_and_serial.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_lastUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_nextUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_lastUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_nextUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_lastUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_nextUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_lastUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_nextUpdate.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_notAfter.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_notAfter.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_notBefore.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_getm_notAfter.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_getm_notBefore.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set1_notAfter.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set1_notBefore.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_notAfter.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_notBefore.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_signature.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_tbs_sigalg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_signature_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_signature.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_signature_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_tbs_sigalg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_signature_nid.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_signature_type.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_email_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get1_ocsp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_extended_key_usage.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_key_usage.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_extract_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_pubkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_pubkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_pubkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_extract_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey_bitstr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_X509_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_pubkey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_serialNumber.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_serialNumber.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_issuer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_issuer_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_subject_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_subject_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_issuer_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_issuer_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_subject_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_version.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_alias_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_alias_set1.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_keyid_get0.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_load_cert_crl_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_load_crl_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_to_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_chain_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_up_ref.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_print_ex_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_sign_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_sign.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_sign_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_sign_ctx.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_verify.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_signature_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_txt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_delete_attr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get0_data_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get_attr_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_prefix.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_range.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_canonize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_is_canonical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_get_afi.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_inherits.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_subset.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_validate_resource_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_path.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_resource_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_add_inherit.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_canonize.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_is_canonical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_add_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_delete_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_critical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_delete_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_critical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_add_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_delete_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_NID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_critical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_add_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_delete_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_OBJ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_critical.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_count.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_add_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_check_top.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_cmp_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_div_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_expand.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_expand2.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_fix_top.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_add_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_comba4.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_comba8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_normal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_part_recursive.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_recursive.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_set_high.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_set_low.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_set_max.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_comba4.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_comba8.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_normal.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_recursive.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_sub_words.3" + -rm -f "$(DESTDIR)$(mandir)/man3/bn_wexpand.3" + -rm -f "$(DESTDIR)$(mandir)/man3/mul.3" + -rm -f "$(DESTDIR)$(mandir)/man3/mul_add.3" + -rm -f "$(DESTDIR)$(mandir)/man3/sqr.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_NULL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_get0_data.3" + -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_length.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OBJECT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BIT_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BMPSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_ENUMERATED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALIZEDTIME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_IA5STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_INTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLESTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_T61STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TIME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UINTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UNIVERSALSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTCTIME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTF8STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_VISIBLESTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DIRECTORYSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DISPLAYTEXT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BIT_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BMPSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_ENUMERATED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALIZEDTIME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_IA5STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_INTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OCTET_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLESTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_T61STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TIME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UNIVERSALSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTCTIME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTF8STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_VISIBLESTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DIRECTORYSTRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DISPLAYTEXT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_SET_ANY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SEQUENCE_ANY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SET_ANY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_KEYID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EXTENDED_KEY_USAGE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_BASIC_CONSTRAINTS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EXTENDED_KEY_USAGE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CMS_ReceiptRequest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CMS_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CMS_ContentInfo.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CMS_ReceiptRequest.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CMS_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DHparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ACCESS_DESCRIPTION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_AUTHORITY_INFO_ACCESS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CRL_DIST_POINTS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DIST_POINT_NAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ISSUING_DIST_POINT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ACCESS_DESCRIPTION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_INFO_ACCESS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CRL_DIST_POINTS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT_NAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ISSUING_DIST_POINT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DSAparams_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_SIG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_SIG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECPKParameters_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECPKParameters_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECParameters_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECParameters_print.3" + -rm -f "$(DESTDIR)$(mandir)/man3/ECParameters_print_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECParameters.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2o_ECPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/o2i_ECPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ESS_CERT_ID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ESS_ISSUER_SERIAL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ESS_CERT_ID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ESS_ISSUER_SERIAL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ESS_SIGNING_CERT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EDIPARTYNAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_GENERAL_NAMES.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OTHERNAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EDIPARTYNAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAMES.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OTHERNAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_ONEREQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REQINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SERVICELOC.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SIGNATURE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_ONEREQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQUEST.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SERVICELOC.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SIGNATURE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_BASICRESP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTSTATUS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CRLID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPBYTES.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPDATA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REVOKEDINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SINGLERESP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_BASICRESP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTSTATUS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CRLID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPBYTES.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPDATA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPID.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPONSE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REVOKEDINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SINGLERESP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_BAGS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_MAC_DATA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_SAFEBAG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_BAGS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_MAC_DATA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_SAFEBAG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_DIGEST.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENCRYPT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENC_CONTENT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENVELOPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ISSUER_AND_SERIAL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_RECIP_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNER_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGN_ENVELOPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_DIGEST.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENCRYPT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENC_CONTENT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENVELOPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ISSUER_AND_SERIAL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_RECIP_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNER_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGN_ENVELOPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8PrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKEY_USAGE_PERIOD.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CERTIFICATEPOLICIES.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_NOTICEREF.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_POLICYQUALINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_USERNOTICE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CERTIFICATEPOLICIES.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_NOTICEREF.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_POLICYINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_POLICYQUALINFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_USERNOTICE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_AutoPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_Netscape_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PSS_PARAMS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_Netscape_RSA.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PSS_PARAMS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_SSL_SESSION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_ACCURACY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_STATUS_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_ACCURACY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_STATUS_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CERT_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CINF.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_VAL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CERT_AUX.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CINF.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_VAL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_re_X509_CRL_tbs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_re_X509_REQ_tbs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_re_X509_tbs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_ALGORS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGOR.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGORS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_ATTRIBUTE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REVOKED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REVOKED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_EXTENSIONS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSION.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSIONS.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_dup.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get0_der.3" + -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_set.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_NAME_ENTRY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME_ENTRY.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_INFO.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_fp.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_SIG.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_pw_prompt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string_min.3" + -rm -f "$(DESTDIR)$(mandir)/man3/EVP_set_pw_prompt.3" + -rm -f "$(DESTDIR)$(mandir)/man3/a2i_ASN1_ENUMERATED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/a2i_ASN1_INTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/a2i_ASN1_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2a_ASN1_ENUMERATED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2a_ASN1_INTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/DECLARE_LHASH_OF.3" + -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_COMP_FN_TYPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_ARG_FN_TYPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_FN_TYPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_HASH_FN_TYPE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_delete.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_doall.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_doall_arg.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_insert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_retrieve.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_strhash.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_stats.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_stats_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/lh_stats_bio.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED_TABLE.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_INTEGER.3" + -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_OCTET_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/s2i_ASN1_OCTET_STRING.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_accept_cbs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_accept_fds.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_configure.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_reset.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_server.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_parse_protocols.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_client.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_server.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_alpn.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ciphers.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_dheparams.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ecdhecurves.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_ticket_key.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_session_fd.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_session_lifetime.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifycert.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifyname.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifytime.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_alpn_selected.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_cipher.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_cipher_strength.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_servername.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_session_resumed.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_chain_pem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_contains_name.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_hash.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_issuer.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notafter.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notbefore.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_provided.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_subject.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_cbs.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_fds.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_servername.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_socket.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_clear_keys.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_path.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_key_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_key_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_mem.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_verify_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_verify_client.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_verify_client_optional.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_default_ca_cert_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_unload_file.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_cert_status.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_crl_reason.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_next_update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_response_status.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_result.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_revocation_time.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_this_update.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_url.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_close.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_error.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_handshake.3" + -rm -f "$(DESTDIR)$(mandir)/man3/tls_write.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_chain.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_string.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_free.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_new.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_intermediates.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_chains.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_depth.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_signatures.3" + -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_purpose.3" +endif diff --git a/Libraries/libressl/man/Makefile.in b/Libraries/libressl/man/Makefile.in new file mode 100644 index 000000000..4aef7cb45 --- /dev/null +++ b/Libraries/libressl/man/Makefile.in @@ -0,0 +1,6951 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = man +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_add_fortify_source.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/check-hardening-options.m4 \ + $(top_srcdir)/m4/check-libc.m4 \ + $(top_srcdir)/m4/check-os-options.m4 \ + $(top_srcdir)/m4/disable-compiler-warnings.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man3dir = $(mandir)/man3 +am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" +man5dir = $(mandir)/man5 +NROFF = nroff +MANS = $(dist_man3_MANS) $(dist_man5_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(dist_man3_MANS) $(dist_man5_MANS) \ + $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTO_VERSION = @LIBCRYPTO_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSL_VERSION = @LIBSSL_VERSION@ +LIBTLS_VERSION = @LIBTLS_VERSION@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSLDIR = @OPENSSLDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_LDADD = @PLATFORM_LDADD@ +PROG_LDADD = @PROG_LDADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = CMakeLists.txt +@ENABLE_LIBTLS_ONLY_FALSE@dist_man3_MANS = BIO_f_ssl.3 DTLSv1_listen.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OPENSSL_init_ssl.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PEM_read_SSL_SESSION.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CIPHER_get_name.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_COMP_add_compression_method.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_add1_chain_cert.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_add_extra_chain_cert.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_add_session.3 SSL_CTX_ctrl.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_flush_sessions.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_free.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_get0_certificate.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_get_verify_mode.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_load_verify_locations.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_new.3 SSL_CTX_sess_number.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_sess_set_cache_size.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_sess_set_get_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_sessions.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set1_groups.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_alpn_select_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_cert_store.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_cert_verify_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_cipher_list.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_client_CA_list.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_client_cert_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_default_passwd_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_generate_session_id.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_info_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_keylog_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_max_cert_list.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_min_proto_version.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_mode.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_msg_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_num_tickets.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_options.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_quiet_shutdown.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_read_ahead.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_security_level.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_session_cache_mode.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_session_id_context.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_ssl_version.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_timeout.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_tlsext_servername_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_tlsext_status_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_tlsext_ticket_key_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_tlsext_use_srtp.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_tmp_dh_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_tmp_rsa_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_set_verify.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_CTX_use_certificate.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_free.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get0_cipher.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get0_peer.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get_compress_id.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get_id.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get_protocol_version.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_get_time.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_has_ticket.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_is_resumable.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_print.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_SESSION_set1_id_context.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_accept.3 SSL_alert_type_string.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_clear.3 SSL_connect.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_copy_session_id.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_do_handshake.3 SSL_dup.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_dup_CA_list.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_export_keying_material.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_free.3 SSL_get_SSL_CTX.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_certificate.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_ciphers.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_client_CA_list.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_client_random.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_current_cipher.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_default_timeout.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_error.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_ex_data_X509_STORE_CTX_idx.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_ex_new_index.3 SSL_get_fd.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_finished.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_peer_cert_chain.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_peer_certificate.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_rbio.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_server_tmp_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_session.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_shared_ciphers.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_state.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_verify_result.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_get_version.3 SSL_library_init.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_load_client_CA_file.3 SSL_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_num_renegotiations.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_pending.3 SSL_read.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_read_early_data.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_renegotiate.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_rstate_string.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_session_reused.3 SSL_set1_host.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set1_param.3 SSL_set_SSL_CTX.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_bio.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_connect_state.3 SSL_set_fd.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_max_send_fragment.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_psk_use_session_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_session.3 SSL_set_shutdown.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_tmp_ecdh.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_set_verify_result.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_shutdown.3 SSL_state_string.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SSL_want.3 SSL_write.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_SSL_SESSION.3 ssl.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ACCESS_DESCRIPTION_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ AES_encrypt.3 ASIdentifiers_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_BIT_STRING_set.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_INTEGER_get.3 ASN1_NULL_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_OBJECT_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_PRINTABLE_type.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_STRING_TABLE_add.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_STRING_length.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_STRING_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_STRING_print_ex.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_TIME_set.3 ASN1_TYPE_get.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_UNIVERSALSTRING_to_string.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_generate_nconf.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_get_object.3 ASN1_item_d2i.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_item_digest.3 ASN1_item_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_item_pack.3 ASN1_item_sign.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_item_verify.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_mbstring_copy.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_parse_dump.3 ASN1_put_object.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ASN1_time_parse.3 ASRange_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ AUTHORITY_KEYID_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BASIC_CONSTRAINTS_new.3 BF_set_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_accept.3 BIO_ctrl.3 BIO_dump.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_dup_chain.3 BIO_f_base64.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_f_buffer.3 BIO_f_cipher.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_f_md.3 BIO_f_null.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_find_type.3 BIO_get_data.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_meth_new.3 BIO_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_new_CMS.3 BIO_printf.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_push.3 BIO_read.3 BIO_s_accept.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_s_bio.3 BIO_s_connect.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_s_datagram.3 BIO_s_fd.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_s_file.3 BIO_s_mem.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_s_null.3 BIO_s_socket.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_set_callback.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BIO_should_retry.3 BN_CTX_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_CTX_start.3 BN_add.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_add_word.3 BN_bn2bin.3 BN_cmp.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_copy.3 BN_generate_prime.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_get_rfc3526_prime_8192.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_kronecker.3 BN_mod_inverse.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_mod_mul_montgomery.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_mod_sqrt.3 BN_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_num_bytes.3 BN_rand.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_set_bit.3 BN_set_flags.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_set_negative.3 BN_swap.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ BN_zero.3 BUF_MEM_new.3 CMAC_Init.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_ContentInfo_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_add0_cert.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_add1_recipient_cert.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_add1_signer.3 CMS_compress.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_decrypt.3 CMS_encrypt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_final.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_get0_RecipientInfos.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_get0_SignerInfos.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_get0_type.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_get1_ReceiptRequest.3 CMS_sign.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_sign_receipt.3 CMS_uncompress.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CMS_verify.3 CMS_verify_receipt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CONF_modules_free.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CONF_modules_load_file.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CRYPTO_get_mem_functions.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CRYPTO_lock.3 CRYPTO_memcmp.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ CRYPTO_set_ex_data.3 ChaCha.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DES_set_key.3 DH_generate_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DH_generate_parameters.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DH_get0_pqg.3 DH_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DH_new.3 DH_set_method.3 DH_size.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DIST_POINT_new.3 DSA_SIG_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_do_sign.3 DSA_dup_DH.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_generate_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_generate_parameters.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_get0_pqg.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_meth_new.3 DSA_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_set_method.3 DSA_sign.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ DSA_size.3 ECDH_compute_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ECDSA_SIG_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EC_GFp_simple_method.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EC_GROUP_copy.3 EC_GROUP_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EC_KEY_METHOD_new.3 EC_KEY_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EC_POINT_add.3 EC_POINT_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_add.3 ENGINE_ctrl.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_get_default_RSA.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_init.3 ENGINE_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_register_RSA.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_register_all_RSA.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_set_RSA.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_set_default.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_set_flags.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ENGINE_unregister_RSA.3 ERR.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_GET_LIB.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_asprintf_error_data.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_clear_error.3 ERR_error_string.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_get_error.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_load_crypto_strings.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_load_strings.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_print_errors.3 ERR_put_error.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ERR_remove_state.3 ERR_set_mark.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ ESS_SIGNING_CERT_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_AEAD_CTX_init.3 EVP_BytesToKey.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_CIPHER_CTX_ctrl.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_CIPHER_CTX_get_cipher_data.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_CIPHER_CTX_set_flags.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_CIPHER_do_all.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_CIPHER_meth_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_CIPHER_nid.3 EVP_DigestInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_DigestSignInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_DigestVerifyInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_EncodeInit.3 EVP_EncryptInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_MD_CTX_ctrl.3 EVP_MD_meth_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_MD_nid.3 EVP_OpenInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKCS82PKEY.3 EVP_PKEY_CTX_ctrl.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_CTX_get_operation.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_CTX_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_CTX_set_hkdf_md.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_add1_attr.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_asn1_get_count.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_asn1_new.3 EVP_PKEY_check.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_cmp.3 EVP_PKEY_decrypt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_derive.3 EVP_PKEY_encrypt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_get_default_digest_nid.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_keygen.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_meth_get0_info.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_meth_new.3 EVP_PKEY_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_print_private.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_set1_RSA.3 EVP_PKEY_sign.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_size.3 EVP_PKEY_verify.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_PKEY_verify_recover.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_SealInit.3 EVP_SignInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_VerifyInit.3 EVP_add_cipher.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_aes_128_cbc.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_camellia_128_cbc.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_chacha20.3 EVP_des_cbc.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_rc4.3 EVP_sha1.3 EVP_sha3_224.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_sm3.3 EVP_sm4_cbc.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EVP_whirlpool.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ EXTENDED_KEY_USAGE_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ GENERAL_NAME_new.3 HMAC.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ IPAddressRange_new.3 MD5.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ NAME_CONSTRAINTS_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OBJ_NAME_add.3 OBJ_create.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OBJ_find_sigid_algs.3 OBJ_nid2obj.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_CRLID_new.3 OCSP_REQUEST_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_SERVICELOC_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_cert_to_id.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_request_add1_nonce.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_resp_find_status.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_response_status.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OCSP_sendreq_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OPENSSL_VERSION_NUMBER.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OPENSSL_cleanse.3 OPENSSL_config.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OPENSSL_init_crypto.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OPENSSL_load_builtin_modules.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OPENSSL_malloc.3 OPENSSL_sk_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ OpenSSL_add_all_algorithms.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PEM_ASN1_read.3 PEM_X509_INFO_read.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PEM_bytes_read_bio.3 PEM_read.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PEM_read_bio_PrivateKey.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PEM_write_bio_CMS_stream.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PEM_write_bio_PKCS7_stream.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS12_SAFEBAG_new.3 PKCS12_create.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS12_new.3 PKCS12_newpass.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS12_parse.3 PKCS5_PBKDF2_HMAC.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_add_attribute.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_dataFinal.3 PKCS7_dataInit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_decrypt.3 PKCS7_encrypt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_final.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_get_signer_info.3 PKCS7_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_set_content.3 PKCS7_set_type.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_sign.3 PKCS7_sign_add_signer.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS7_verify.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS8_PRIV_KEY_INFO_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKCS8_pkey_set0.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ PKEY_USAGE_PERIOD_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ POLICYINFO_new.3 RAND_add.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RAND_bytes.3 RAND_load_file.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RAND_set_rand_method.3 RC4.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RIPEMD160.3 RSA_PSS_PARAMS_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_blinding_on.3 RSA_check_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_generate_key.3 RSA_get0_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_meth_new.3 RSA_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_padding_add_PKCS1_type_1.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_pkey_ctx_ctrl.3 RSA_print.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_private_encrypt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_public_encrypt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_security_bits.3 RSA_set_method.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_sign.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_sign_ASN1_OCTET_STRING.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ RSA_size.3 SHA1.3 SMIME_crlf_copy.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SMIME_read_ASN1.3 SMIME_read_CMS.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SMIME_read_PKCS7.3 SMIME_text.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SMIME_write_ASN1.3 SMIME_write_CMS.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ SMIME_write_PKCS7.3 STACK_OF.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ TS_REQ_new.3 UI_UTIL_read_pw.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ UI_create_method.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ UI_get_string_type.3 UI_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X25519.3 X509V3_EXT_print.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509V3_extensions_print.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509V3_get_d2i.3 X509_ALGOR_dup.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_ATTRIBUTE_get0_object.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_ATTRIBUTE_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_ATTRIBUTE_set1_object.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_CINF_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_CRL_METHOD_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_CRL_get0_by_serial.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_CRL_new.3 X509_CRL_print.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_EXTENSION_set_object.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_INFO_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_LOOKUP_hash_dir.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_LOOKUP_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_NAME_ENTRY_get_object.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_NAME_add_entry_by_txt.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_NAME_get_index_by_NID.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_NAME_hash.3 X509_NAME_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_NAME_print_ex.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_OBJECT_get0_X509.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_PKEY_new.3 X509_PUBKEY_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_PURPOSE_set.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_REQ_add1_attr.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_REQ_add_extensions.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_REQ_new.3 X509_REQ_print_ex.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_REVOKED_new.3 X509_SIG_get0.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_SIG_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_CTX_get_error.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_CTX_get_ex_new_index.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_CTX_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_CTX_set_flags.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_CTX_set_verify.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_CTX_set_verify_cb.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_get_by_subject.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_load_locations.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_set1_param.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_STORE_set_verify_cb_func.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_TRUST_set.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_VERIFY_PARAM_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_VERIFY_PARAM_set_flags.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_add1_trust_object.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_check_ca.3 X509_check_host.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_check_issued.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_check_private_key.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_check_purpose.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_check_trust.3 X509_cmp.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_cmp_time.3 X509_digest.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_find_by_subject.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get0_notBefore.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get0_signature.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get1_email.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get_extension_flags.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get_pubkey.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get_pubkey_parameters.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get_serialNumber.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get_subject_name.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_get_version.3 X509_keyid_set1.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_load_cert_file.3 X509_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_ocspid_print.3 X509_print_ex.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_sign.3 X509_signature_dump.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509_verify_cert.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509at_add1_attr.3 X509at_get_attr.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_addr_add_inherit.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_addr_get_range.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_addr_inherits.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_addr_subset.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_addr_validate_path.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_asid_add_id_or_range.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ X509v3_get_ext_by_NID.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ a2d_ASN1_OBJECT.3 bn_dump.3 crypto.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_ASN1_NULL.3 d2i_ASN1_OBJECT.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_ASN1_OCTET_STRING.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_ASN1_SEQUENCE_ANY.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_AUTHORITY_KEYID.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_BASIC_CONSTRAINTS.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_CMS_ContentInfo.3 d2i_DHparams.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_DIST_POINT.3 d2i_DSAPublicKey.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_ECPKParameters.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_ESS_SIGNING_CERT.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_GENERAL_NAME.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_OCSP_REQUEST.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_OCSP_RESPONSE.3 d2i_PKCS12.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_PKCS7.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_PKCS8PrivateKey_bio.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_PKCS8_PRIV_KEY_INFO.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_PKEY_USAGE_PERIOD.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_POLICYINFO.3 d2i_PrivateKey.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_RSAPublicKey.3 d2i_TS_REQ.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_X509.3 d2i_X509_ALGOR.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_X509_ATTRIBUTE.3 d2i_X509_CRL.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_X509_EXTENSION.3 d2i_X509_NAME.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ d2i_X509_REQ.3 d2i_X509_SIG.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ des_read_pw.3 evp.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ i2a_ASN1_STRING.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ i2d_CMS_bio_stream.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ i2d_PKCS7_bio_stream.3 lh_new.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ lh_stats.3 s2i_ASN1_INTEGER.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ x509_verify.3 tls_accept_socket.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_client.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_config_ocsp_require_stapling.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_config_set_protocols.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_config_set_session_id.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_config_verify.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_conn_version.3 tls_connect.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_init.3 tls_load_file.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_ocsp_process_response.3 \ +@ENABLE_LIBTLS_ONLY_FALSE@ tls_read.3 +@ENABLE_LIBTLS_ONLY_FALSE@dist_man5_MANS = openssl.cnf.5 x509v3.cnf.5 +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign man/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man3: $(dist_man3_MANS) + @$(NORMAL_INSTALL) + @list1='$(dist_man3_MANS)'; \ + list2=''; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(dist_man3_MANS)'; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-man5: $(dist_man5_MANS) + @$(NORMAL_INSTALL) + @list1='$(dist_man5_MANS)'; \ + list2=''; \ + test -n "$(man5dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.5[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list='$(dist_man5_MANS)'; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@ENABLE_LIBTLS_ONLY_TRUE@uninstall-local: +@ENABLE_LIBTLS_ONLY_TRUE@install-data-hook: +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man3 install-man5 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-local uninstall-man + +uninstall-man: uninstall-man3 uninstall-man5 + +.MAKE: install-am install-data-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man3 install-man5 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am uninstall-local uninstall-man \ + uninstall-man3 uninstall-man5 + +.PRECIOUS: Makefile + +@ENABLE_LIBTLS_ONLY_FALSE@install-data-hook: +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ACCESS_DESCRIPTION_new.3" "$(DESTDIR)$(mandir)/man3/ACCESS_DESCRIPTION_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ACCESS_DESCRIPTION_new.3" "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ACCESS_DESCRIPTION_new.3" "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_set_decrypt_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "AES_encrypt.3" "$(DESTDIR)$(mandir)/man3/AES_set_encrypt_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASIdentifiers_new.3" "$(DESTDIR)$(mandir)/man3/ASIdentifiers_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASIdentifiers_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifiers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASIdentifiers_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifiers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_BIT_STRING_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_get_bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_BIT_STRING_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_set_bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_to_BN.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_uint64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_uint64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_to_BN.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_INTEGER_get.3" "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_NULL_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_NULL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_OBJECT_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_OBJECT_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_TABLE_add.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_TABLE_add.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get0_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_length_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_to_UTF8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_length.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_new.3" "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_print_ex.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_print_ex.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print_ex_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_STRING_print_ex.3" "$(DESTDIR)$(mandir)/man3/ASN1_tag2str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_cmp_time_t.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_compare.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_diff.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_normalize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_generalizedtime.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_tm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_cmp_time_t.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TIME_set.3" "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_int_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_int_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_TYPE_get.3" "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_generate_nconf.3" "$(DESTDIR)$(mandir)/man3/ASN1_generate_v3.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_d2i.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_new.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_pack.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_unpack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_item_sign.3" "$(DESTDIR)$(mandir)/man3/ASN1_item_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get_default_mask.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask_asc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_mbstring_ncopy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_mbstring_copy.3" "$(DESTDIR)$(mandir)/man3/ASN1_tag2bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_parse_dump.3" "$(DESTDIR)$(mandir)/man3/ASN1_parse.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_put_object.3" "$(DESTDIR)$(mandir)/man3/ASN1_object_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_put_object.3" "$(DESTDIR)$(mandir)/man3/ASN1_put_eoc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_time_parse.3" "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_tm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASN1_time_parse.3" "$(DESTDIR)$(mandir)/man3/ASN1_time_tm_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdOrRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdOrRange_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/ASRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASIdOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifierChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ASRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASIdOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifierChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ASRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ASRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "AUTHORITY_KEYID_new.3" "$(DESTDIR)$(mandir)/man3/AUTHORITY_KEYID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BASIC_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/BASIC_CONSTRAINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_ecb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BF_set_key.3" "$(DESTDIR)$(mandir)/man3/BF_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_accept_socket.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_host_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_tcp_ndelay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_sock_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_sock_non_fatal_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_sock_should_retry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_socket_nbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_pending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_wpending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_eof.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_flush.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_close.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_info_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_int_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_pending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_ptr_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_seek.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_close.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_tell.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/BIO_wpending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_ctrl.3" "$(DESTDIR)$(mandir)/man3/bio_info_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_dump.3" "$(DESTDIR)$(mandir)/man3/BIO_dump_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_dump.3" "$(DESTDIR)$(mandir)/man3/BIO_dump_indent.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_dump.3" "$(DESTDIR)$(mandir)/man3/BIO_dump_indent_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_dup_chain.3" "$(DESTDIR)$(mandir)/man3/BIO_dup_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_get_buffer_num_lines.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_read_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_read_buffer_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_buffer.3" "$(DESTDIR)$(mandir)/man3/BIO_set_write_buffer_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_cipher.3" "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_cipher.3" "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_cipher.3" "$(DESTDIR)$(mandir)/man3/BIO_set_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_get_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_get_md_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_set_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_md.3" "$(DESTDIR)$(mandir)/man3/BIO_set_md_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_do_handshake.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_num_renegotiates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_get_ssl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_new_buffer_ssl_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_new_ssl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_new_ssl_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_bytes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_ssl_copy_session_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_f_ssl.3" "$(DESTDIR)$(mandir)/man3/BIO_ssl_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_find_type.3" "$(DESTDIR)$(mandir)/man3/BIO_method_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_find_type.3" "$(DESTDIR)$(mandir)/man3/BIO_method_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_find_type.3" "$(DESTDIR)$(mandir)/man3/BIO_next.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_clear_retry_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_copy_next_retry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_retry_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_get_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_special.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_set_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_data.3" "$(DESTDIR)$(mandir)/man3/BIO_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/BIO_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/TYPE_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/UI_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/UI_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/UI_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_get_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_destroy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_gets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_puts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_get_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_destroy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_gets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_puts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_meth_new.3" "$(DESTDIR)$(mandir)/man3/BIO_meth_set_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_free_all.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_new.3" "$(DESTDIR)$(mandir)/man3/BIO_vfree.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_printf.3" "$(DESTDIR)$(mandir)/man3/BIO_snprintf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_printf.3" "$(DESTDIR)$(mandir)/man3/BIO_vprintf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_printf.3" "$(DESTDIR)$(mandir)/man3/BIO_vsnprintf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_push.3" "$(DESTDIR)$(mandir)/man3/BIO_pop.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_push.3" "$(DESTDIR)$(mandir)/man3/BIO_set_next.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_gets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_indent.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_number_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_number_written.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_puts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_read.3" "$(DESTDIR)$(mandir)/man3/BIO_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_do_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_accept_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_get_bind_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_new_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_accept_bios.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_accept_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_bind_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_accept.3" "$(DESTDIR)$(mandir)/man3/BIO_set_nbio_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_read_request.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_write_guarantee.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_reset_read_request.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_destroy_bio_pair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_get_read_request.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_get_write_buf_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_get_write_guarantee.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_make_bio_pair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_new_bio_pair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_set_write_buf_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_bio.3" "$(DESTDIR)$(mandir)/man3/BIO_shutdown_wr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_do_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_hostname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_int_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_get_conn_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_new_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_hostname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_int_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_conn_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_connect.3" "$(DESTDIR)$(mandir)/man3/BIO_set_nbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_dgram_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_ctrl_set_connected.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_get_peer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_non_fatal_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_recv_timedout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_send_timedout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_dgram_set_peer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_datagram.3" "$(DESTDIR)$(mandir)/man3/BIO_new_dgram.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_fd_non_fatal_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_fd_should_retry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_get_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_new_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_fd.3" "$(DESTDIR)$(mandir)/man3/BIO_set_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_append_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_get_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_new_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_new_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_read_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_rw_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_set_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_file.3" "$(DESTDIR)$(mandir)/man3/BIO_write_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_get_mem_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_get_mem_ptr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_new_mem_buf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_set_mem_buf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_mem.3" "$(DESTDIR)$(mandir)/man3/BIO_set_mem_eof_return.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_s_socket.3" "$(DESTDIR)$(mandir)/man3/BIO_new_socket.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_callback_fn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_callback_fn_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_debug_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_get_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_get_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_get_callback_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_set_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_set_callback.3" "$(DESTDIR)$(mandir)/man3/BIO_set_callback_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_get_retry_BIO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_get_retry_reason.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_retry_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_set_retry_reason.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_should_io_special.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_should_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BIO_should_retry.3" "$(DESTDIR)$(mandir)/man3/BIO_should_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_CTX_new.3" "$(DESTDIR)$(mandir)/man3/BN_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_CTX_start.3" "$(DESTDIR)$(mandir)/man3/BN_CTX_end.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_CTX_start.3" "$(DESTDIR)$(mandir)/man3/BN_CTX_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_div.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_gcd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_add_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_lshift_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_sqr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_sub.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mod_sub_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_nnmod.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_sqr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_sub.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_uadd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add.3" "$(DESTDIR)$(mandir)/man3/BN_usub.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_div_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_mod_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_mul_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_add_word.3" "$(DESTDIR)$(mandir)/man3/BN_sub_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_asc2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bin2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2binpad.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2hex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2lebinpad.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_bn2mpi.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_dec2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_hex2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_lebin2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_mpi2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_bn2bin.3" "$(DESTDIR)$(mandir)/man3/BN_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_abs_is_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_odd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_one.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_is_zero.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_cmp.3" "$(DESTDIR)$(mandir)/man3/BN_ucmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_copy.3" "$(DESTDIR)$(mandir)/man3/BN_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_copy.3" "$(DESTDIR)$(mandir)/man3/BN_with_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_call.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_get_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_GENCB_set_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_generate_prime_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_is_prime_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_generate_prime.3" "$(DESTDIR)$(mandir)/man3/BN_is_prime_fasttest_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_1024.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_768.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_1536.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_2048.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_3072.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_4096.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_get_rfc3526_prime_8192.3" "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_6144.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set_locked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_from_montgomery.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_mod_mul_montgomery.3" "$(DESTDIR)$(mandir)/man3/BN_to_montgomery.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_new.3" "$(DESTDIR)$(mandir)/man3/BN_clear.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_new.3" "$(DESTDIR)$(mandir)/man3/BN_clear_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_new.3" "$(DESTDIR)$(mandir)/man3/BN_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_num_bytes.3" "$(DESTDIR)$(mandir)/man3/BN_num_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_num_bytes.3" "$(DESTDIR)$(mandir)/man3/BN_num_bits_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_rand.3" "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_rand.3" "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand_range.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_rand.3" "$(DESTDIR)$(mandir)/man3/BN_rand_range.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_clear_bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_is_bit_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_lshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_lshift1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_mask_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_rshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_bit.3" "$(DESTDIR)$(mandir)/man3/BN_rshift1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_flags.3" "$(DESTDIR)$(mandir)/man3/BN_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_set_negative.3" "$(DESTDIR)$(mandir)/man3/BN_is_negative.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_swap.3" "$(DESTDIR)$(mandir)/man3/BN_consttime_swap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_get_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_one.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_set_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BN_zero.3" "$(DESTDIR)$(mandir)/man3/BN_value_one.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BUF_MEM_new.3" "$(DESTDIR)$(mandir)/man3/BUF_MEM_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BUF_MEM_new.3" "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "BUF_MEM_new.3" "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow_clean.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_get0_cipher_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMAC_Init.3" "$(DESTDIR)$(mandir)/man3/CMAC_resume.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_print_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_ContentInfo_new.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add0_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add1_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add1_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_get1_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add0_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_get1_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add1_recipient_cert.3" "$(DESTDIR)$(mandir)/man3/CMS_add0_recipient_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_add1_signer.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_decrypt.3" "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_decrypt.3" "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_pkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_get0_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_id_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_cert_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_get0_signer_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_pkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_RecipientInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_cert_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signature.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signer_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_SignerInfos.3" "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_set1_signer_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_get0_content.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_get0_eContentType.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get0_type.3" "$(DESTDIR)$(mandir)/man3/CMS_set1_eContentType.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get1_ReceiptRequest.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_create0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get1_ReceiptRequest.3" "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_get0_values.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_get1_ReceiptRequest.3" "$(DESTDIR)$(mandir)/man3/CMS_add1_ReceiptRequest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CMS_verify.3" "$(DESTDIR)$(mandir)/man3/CMS_get0_signers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CONF_modules_free.3" "$(DESTDIR)$(mandir)/man3/CONF_modules_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CONF_modules_free.3" "$(DESTDIR)$(mandir)/man3/CONF_modules_unload.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CONF_modules_load_file.3" "$(DESTDIR)$(mandir)/man3/CONF_modules_load.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CONF_modules_load_file.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_area.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_MEM_LEAK_CB.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_get_mem_functions.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_set_mem_functions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cpy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_current.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_r_lock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_r_unlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_w_lock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_lock.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_w_unlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_free_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "CRYPTO_set_ex_data.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_new_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_chacha_20.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_hchacha_20.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_xchacha_20.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/ChaCha_set_iv.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ChaCha.3" "$(DESTDIR)$(mandir)/man3/ChaCha_set_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_cbc_cksum.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_cfb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_crypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ecb2_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ecb3_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ecb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede2_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede2_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede2_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_cbcm_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ede3_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_enc_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_enc_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_fcrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_is_weak_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_key_sched.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ncbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_ofb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_pcbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_quad_cksum.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_random_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_set_key_checked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_set_key_unchecked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_set_odd_parity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_string_to_2keys.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_string_to_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DES_set_key.3" "$(DESTDIR)$(mandir)/man3/DES_xcbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_generate_key.3" "$(DESTDIR)$(mandir)/man3/DH_compute_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DH_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DH_check_pub_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DH_generate_parameters_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_g.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_p.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_priv_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_pub_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_get0_q.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set0_pqg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_set_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DH_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DH_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DH_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_new.3" "$(DESTDIR)$(mandir)/man3/DH_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_new.3" "$(DESTDIR)$(mandir)/man3/DH_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_set_method.3" "$(DESTDIR)$(mandir)/man3/DH_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DH_size.3" "$(DESTDIR)$(mandir)/man3/DH_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/DIST_POINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DIST_POINT_new.3" "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/DSA_SIG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/DSA_SIG_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/DSA_SIG_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_do_sign.3" "$(DESTDIR)$(mandir)/man3/DSA_do_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_generate_parameters.3" "$(DESTDIR)$(mandir)/man3/DSA_generate_parameters_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_g.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_p.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_priv_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_pub_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_get0_q.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_set0_pqg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get0_pqg.3" "$(DESTDIR)$(mandir)/man3/DSA_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DSA_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/DSA_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_set1_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_set_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/DSA_meth_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_new.3" "$(DESTDIR)$(mandir)/man3/DSA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_new.3" "$(DESTDIR)$(mandir)/man3/DSA_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_set_method.3" "$(DESTDIR)$(mandir)/man3/DSA_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_sign.3" "$(DESTDIR)$(mandir)/man3/DSA_sign_setup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_sign.3" "$(DESTDIR)$(mandir)/man3/DSA_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "DSA_size.3" "$(DESTDIR)$(mandir)/man3/DSA_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDH_compute_key.3" "$(DESTDIR)$(mandir)/man3/ECDH_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_r.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_s.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_do_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_do_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/ECDSA_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/d2i_ECDSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ECDSA_SIG_new.3" "$(DESTDIR)$(mandir)/man3/i2d_ECDSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GFp_simple_method.3" "$(DESTDIR)$(mandir)/man3/EC_GFp_mont_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GFp_simple_method.3" "$(DESTDIR)$(mandir)/man3/EC_METHOD_get_field_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_check_discriminant.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_generator.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_seed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_asn1_flag.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_basis_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_cofactor.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_degree.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_order.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_point_conversion_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_seed_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_method_of.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_order_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_asn1_flag.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_generator.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_point_conversion_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_copy.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_seed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_clear_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_by_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_curve_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_GROUP_new.3" "$(DESTDIR)$(mandir)/man3/EC_get_builtin_curves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_compute_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_compute_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_check_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_generate_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_group.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_conv_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_enc_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_new_by_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_precompute_mult.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_asn1_flag.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_conv_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_enc_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_group.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key_affine_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_KEY_new.3" "$(DESTDIR)$(mandir)/man3/EC_KEY_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_have_precompute_mult.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_GROUP_precompute_mult.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_dbl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_invert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_is_at_infinity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_is_on_curve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_make_affine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINTs_make_affine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_add.3" "$(DESTDIR)$(mandir)/man3/EC_POINTs_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_bn2point.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_clear_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_get_Jprojective_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_hex2point.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_method_of.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_oct2point.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_point2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_point2hex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_point2oct.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_Jprojective_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EC_POINT_new.3" "$(DESTDIR)$(mandir)/man3/EC_POINT_set_to_infinity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_by_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_first.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_last.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_next.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_prev.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_remove.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_add.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_CTRL_FUNC_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_cmd_is_executable.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_cmd_defns.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ctrl_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_cmd_defns.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_ctrl.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_ctrl_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_EC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_table_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_get_default_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_table_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_finish_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_init_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_finish_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_init.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_init_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_destroy_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_destroy_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_new.3" "$(DESTDIR)$(mandir)/man3/ENGINE_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_complete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_load_builtin_engines.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_load_dynamic.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_complete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_register_all_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_CIPHERS_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_DIGESTS_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_EC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_EC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_default.3" "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_set_flags.3" "$(DESTDIR)$(mandir)/man3/ENGINE_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ENGINE_unregister_RSA.3" "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_GET_LIB.3" "$(DESTDIR)$(mandir)/man3/ERR_FATAL_ERROR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_GET_LIB.3" "$(DESTDIR)$(mandir)/man3/ERR_GET_FUNC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_GET_LIB.3" "$(DESTDIR)$(mandir)/man3/ERR_GET_REASON.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_error_string_n.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_func_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_lib_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_error_string.3" "$(DESTDIR)$(mandir)/man3/ERR_reason_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_get_error_line.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_get_error_line_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_get_error.3" "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_load_crypto_strings.3" "$(DESTDIR)$(mandir)/man3/ERR_free_strings.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_load_crypto_strings.3" "$(DESTDIR)$(mandir)/man3/SSL_load_error_strings.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_load_strings.3" "$(DESTDIR)$(mandir)/man3/ERR_PACK.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_load_strings.3" "$(DESTDIR)$(mandir)/man3/ERR_get_next_error_library.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_print_errors.3" "$(DESTDIR)$(mandir)/man3/ERR_print_errors_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_print_errors.3" "$(DESTDIR)$(mandir)/man3/ERR_print_errors_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_put_error.3" "$(DESTDIR)$(mandir)/man3/ERR_add_error_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_put_error.3" "$(DESTDIR)$(mandir)/man3/ERR_add_error_vdata.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_remove_state.3" "$(DESTDIR)$(mandir)/man3/ERR_remove_thread_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ERR_set_mark.3" "$(DESTDIR)$(mandir)/man3/ERR_pop_to_mark.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "ESS_SIGNING_CERT_new.3" "$(DESTDIR)$(mandir)/man3/ESS_SIGNING_CERT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_open.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_seal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_overhead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_tag_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_AEAD_nonce_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_128_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_256_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_chacha20_poly1305.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_AEAD_CTX_init.3" "$(DESTDIR)$(mandir)/man3/EVP_aead_xchacha20_poly1305.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_iv.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_iv_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_iv.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_padding.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_iv_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_get_cipher_data.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_buf_noconst.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_get_cipher_data.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_cipher_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_rand_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_asn1_to_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_param_to_asn1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_do_all.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_do_all_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_do_all.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_do_all.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_do_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_get_asn1_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_impl_ctx_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_iv_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_set_asn1_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_CIPHER_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_Digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_destroy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_digestbynid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyobj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_md_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_ripemd160.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha224.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha384.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha512.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha512_224.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestInit.3" "$(DESTDIR)$(mandir)/man3/EVP_sha512_256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestSignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestSign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestSignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestSignFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestSignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestSignUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestVerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestVerify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestVerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_DigestVerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeBlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeInit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecodeUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncodeBlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncodeFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncodeInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncodeUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_encrypting.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_Cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherInit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_CipherUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_DecryptUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_EncryptUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_bf_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_cast5_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_enc_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbynid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyobj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_idea_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_40_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_64_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_EncryptInit.3" "$(DESTDIR)$(mandir)/man3/EVP_rc2_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_pkey_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_pkey_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_app_datasize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_input_blocksize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_result_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_pkey_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_MD_nid.3" "$(DESTDIR)$(mandir)/man3/EVP_MD_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_OpenInit.3" "$(DESTDIR)$(mandir)/man3/EVP_OpenFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_OpenInit.3" "$(DESTDIR)$(mandir)/man3/EVP_OpenUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKCS82PKEY.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY2PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_ctrl_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_ecdh_kdf_ukm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_cofactor_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_outlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_signature_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_ecdh_kdf_ukm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_generator.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_prime_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dsa_paramgen_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_param_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_paramgen_curve_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_cofactor_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_outlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_signature_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_get_operation.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_pkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_new_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_add1_hkdf_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_hkdf_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_CTX_set_hkdf_md.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_salt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_delete_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_add1_attr.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_get_count.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_asn1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_private.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_asn1_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_check.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_param_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_check.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_public_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_cmp.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_cmp_parameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_cmp.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_copy_parameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_cmp.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_missing_parameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_decrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_derive.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_peerkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_derive.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_derive.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_set_peer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_encrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_keygen_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_keygen_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_gen_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_keygen_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_keygen.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_add0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_derive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_param_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_paramgen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_public_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_signctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify_recover.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_meth_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verifyctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_CMAC_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_mac_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_print_private.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_print_private.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_public.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_GOST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_base_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_hmac.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_set1_RSA.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_sign.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_sign_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_size.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_size.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_verify.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_PKEY_verify_recover.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_recover_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_SealInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SealFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_SealInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SealUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_SignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SignFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_SignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SignInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_SignInit.3" "$(DESTDIR)$(mandir)/man3/EVP_SignUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_VerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_VerifyFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_VerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_VerifyInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_VerifyInit.3" "$(DESTDIR)$(mandir)/man3/EVP_VerifyUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_add_cipher_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_add_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_add_digest_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_delete_cipher_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_add_cipher.3" "$(DESTDIR)$(mandir)/man3/EVP_delete_digest_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cbc_hmac_sha1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ccm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_wrap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_128_xts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ccm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_192_wrap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc_hmac_sha1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ccm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_wrap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_aes_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_aes_256_xts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_camellia_128_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_chacha20.3" "$(DESTDIR)$(mandir)/man3/EVP_chacha20_poly1305.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_des_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_des_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_desx_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_rc4.3" "$(DESTDIR)$(mandir)/man3/EVP_rc4_40.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_rc4.3" "$(DESTDIR)$(mandir)/man3/EVP_rc4_hmac_md5.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sha1.3" "$(DESTDIR)$(mandir)/man3/EVP_md4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sha1.3" "$(DESTDIR)$(mandir)/man3/EVP_md5.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sha1.3" "$(DESTDIR)$(mandir)/man3/EVP_md5_sha1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sha3_224.3" "$(DESTDIR)$(mandir)/man3/EVP_sha3_256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sha3_224.3" "$(DESTDIR)$(mandir)/man3/EVP_sha3_384.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sha3_224.3" "$(DESTDIR)$(mandir)/man3/EVP_sha3_512.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EVP_sm4_cbc.3" "$(DESTDIR)$(mandir)/man3/EVP_sm4_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "EXTENDED_KEY_USAGE_new.3" "$(DESTDIR)$(mandir)/man3/EXTENDED_KEY_USAGE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_NAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/OTHERNAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "GENERAL_NAME_new.3" "$(DESTDIR)$(mandir)/man3/OTHERNAME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_get_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_CTX_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Init_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "HMAC.3" "$(DESTDIR)$(mandir)/man3/HMAC_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressChoice_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressChoice_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressFamily_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressFamily_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/IPAddressRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressFamily.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/d2i_IPAddressRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressFamily.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "IPAddressRange_new.3" "$(DESTDIR)$(mandir)/man3/i2d_IPAddressRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD4_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD5_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD5_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "MD5.3" "$(DESTDIR)$(mandir)/man3/MD5_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "NAME_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "NAME_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "NAME_CONSTRAINTS_new.3" "$(DESTDIR)$(mandir)/man3/NAME_CONSTRAINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_NAME_add.3" "$(DESTDIR)$(mandir)/man3/OBJ_NAME_remove.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_add_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_create_objects.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/OBJ_new_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/check_defer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_create.3" "$(DESTDIR)$(mandir)/man3/obj_cleanup_defer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_find_sigid_algs.3" "$(DESTDIR)$(mandir)/man3/OBJ_find_sigid_by_algs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_ln2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_nid2ln.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_nid2sn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_obj2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_obj2txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_sn2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_txt2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/OBJ_txt2obj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/i2a_ASN1_OBJECT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OBJ_nid2obj.3" "$(DESTDIR)$(mandir)/man3/i2t_ASN1_OBJECT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_CRLID_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_CRLID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQUEST_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_add0_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_add1_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_REQUEST_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_request_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_SERVICELOC_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_SERVICELOC_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_SERVICELOC_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_url_svcloc_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_cert_id_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_id_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_id_get0_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_cert_to_id.3" "$(DESTDIR)$(mandir)/man3/OCSP_id_issuer_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_request_add1_nonce.3" "$(DESTDIR)$(mandir)/man3/OCSP_basic_add1_nonce.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_request_add1_nonce.3" "$(DESTDIR)$(mandir)/man3/OCSP_check_nonce.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_request_add1_nonce.3" "$(DESTDIR)$(mandir)/man3/OCSP_copy_nonce.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_get0_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_basic_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_cert_status_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_check_validity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_resp_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_resp_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_resp_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_resp_find_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_single_get0_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_basic_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_response_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_response_get1_basic.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_response_status.3" "$(DESTDIR)$(mandir)/man3/OCSP_response_status_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_add1_header.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_set1_req.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_parse_url.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OCSP_sendreq_new.3" "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_nbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_NUMBER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_TEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_VERSION_TEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_version_num.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/SSLeay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_VERSION_NUMBER.3" "$(DESTDIR)$(mandir)/man3/SSLeay_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_config.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_no_config.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_init_crypto.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_load_builtin_modules.3" "$(DESTDIR)$(mandir)/man3/ASN1_add_oid_module.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_load_builtin_modules.3" "$(DESTDIR)$(mandir)/man3/ENGINE_add_conf_module.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_malloc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_realloc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/CRYPTO_strdup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_realloc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_malloc.3" "$(DESTDIR)$(mandir)/man3/OPENSSL_strdup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_delete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_delete_ptr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_find_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_insert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_is_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_new_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_num.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_pop.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_pop_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_push.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_set_cmp_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_shift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_sort.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_unshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_value.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OPENSSL_sk_new.3" "$(DESTDIR)$(mandir)/man3/sk_zero.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/EVP_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "OpenSSL_add_all_algorithms.3" "$(DESTDIR)$(mandir)/man3/SSLeay_add_all_algorithms.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_ASN1_read.3" "$(DESTDIR)$(mandir)/man3/PEM_ASN1_read_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_ASN1_read.3" "$(DESTDIR)$(mandir)/man3/d2i_of_void.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_X509_INFO_read.3" "$(DESTDIR)$(mandir)/man3/PEM_X509_INFO_read_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_def_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_do_header.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_get_EVP_CIPHER_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read.3" "$(DESTDIR)$(mandir)/man3/pem_password_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/PEM_write_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ_NEW.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PEM_read_bio_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ_NEW.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS12_SAFEBAG_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS12_SAFEBAG_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS12_SAFEBAG_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_SAFEBAG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS12_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS12_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS12_new.3" "$(DESTDIR)$(mandir)/man3/PKCS12_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS5_PBKDF2_HMAC.3" "$(DESTDIR)$(mandir)/man3/PKCS5_PBKDF2_HMAC_SHA1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add0_attrib_signing_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add1_attrib_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_content_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_smimecap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_add_signed_attribute.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_get_attribute.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_get_signed_attribute.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_set_attributes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_add_attribute.3" "$(DESTDIR)$(mandir)/man3/PKCS7_set_signed_attributes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_new.3" "$(DESTDIR)$(mandir)/man3/PKCS7_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_set_content.3" "$(DESTDIR)$(mandir)/man3/PKCS7_content_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_set_type.3" "$(DESTDIR)$(mandir)/man3/PKCS7_set0_type_other.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS7_verify.3" "$(DESTDIR)$(mandir)/man3/PKCS7_get0_signers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS8_PRIV_KEY_INFO_new.3" "$(DESTDIR)$(mandir)/man3/PKCS8_PRIV_KEY_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS8_pkey_set0.3" "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS8_pkey_set0.3" "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKCS8_pkey_set0.3" "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0_attrs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "PKEY_USAGE_PERIOD_new.3" "$(DESTDIR)$(mandir)/man3/PKEY_USAGE_PERIOD_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/NOTICEREF_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/NOTICEREF_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICYINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/USERNOTICE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "POLICYINFO_new.3" "$(DESTDIR)$(mandir)/man3/USERNOTICE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_poll.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_seed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_add.3" "$(DESTDIR)$(mandir)/man3/RAND_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_bytes.3" "$(DESTDIR)$(mandir)/man3/RAND_pseudo_bytes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_load_file.3" "$(DESTDIR)$(mandir)/man3/RAND_file_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_load_file.3" "$(DESTDIR)$(mandir)/man3/RAND_write_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_set_rand_method.3" "$(DESTDIR)$(mandir)/man3/RAND_SSLeay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RAND_set_rand_method.3" "$(DESTDIR)$(mandir)/man3/RAND_get_rand_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RC4.3" "$(DESTDIR)$(mandir)/man3/RC4_set_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RIPEMD160.3" "$(DESTDIR)$(mandir)/man3/RIPEMD160_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RIPEMD160.3" "$(DESTDIR)$(mandir)/man3/RIPEMD160_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RIPEMD160.3" "$(DESTDIR)$(mandir)/man3/RIPEMD160_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_PSS_PARAMS_new.3" "$(DESTDIR)$(mandir)/man3/RSA_PSS_PARAMS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_blinding_on.3" "$(DESTDIR)$(mandir)/man3/RSA_blinding_off.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_generate_key.3" "$(DESTDIR)$(mandir)/man3/RSA_generate_key_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_crt_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_dmp1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_dmq1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_e.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_factors.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_iqmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_n.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_p.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_get0_q.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set0_crt_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set0_factors.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get0_key.3" "$(DESTDIR)$(mandir)/man3/RSA_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/RSA_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/RSA_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_bn_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set0_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set1_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_bn_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_meth_new.3" "$(DESTDIR)$(mandir)/man3/RSA_meth_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSAPrivateKey_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSAPublicKey_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_new.3" "$(DESTDIR)$(mandir)/man3/RSA_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_OAEP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_type_2.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_add_none.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_OAEP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_2.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_padding_add_PKCS1_type_1.3" "$(DESTDIR)$(mandir)/man3/RSA_padding_check_none.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_rsa_oaep_label.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_mgf1_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_oaep_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_padding.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_pss_saltlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_pubexp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_mgf1_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_oaep_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_padding.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_pkey_ctx_ctrl.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_saltlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DHparams_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DHparams_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSA_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSA_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSAparams_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/DSAparams_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_print.3" "$(DESTDIR)$(mandir)/man3/RSA_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_private_encrypt.3" "$(DESTDIR)$(mandir)/man3/RSA_public_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_public_encrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_public_encrypt.3" "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_public_encrypt.3" "$(DESTDIR)$(mandir)/man3/RSA_private_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_security_bits.3" "$(DESTDIR)$(mandir)/man3/BN_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_security_bits.3" "$(DESTDIR)$(mandir)/man3/DH_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_security_bits.3" "$(DESTDIR)$(mandir)/man3/DSA_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_PKCS1_SSLeay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_get_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_set_method.3" "$(DESTDIR)$(mandir)/man3/RSA_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_sign.3" "$(DESTDIR)$(mandir)/man3/RSA_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_sign_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/RSA_verify_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "RSA_size.3" "$(DESTDIR)$(mandir)/man3/RSA_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA1_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA1_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA1_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA224_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA256_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA384_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SHA1.3" "$(DESTDIR)$(mandir)/man3/SHA512_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_description.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_auth_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_cipher_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_digest_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_kx_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CIPHER_get_name.3" "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_is_aead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_COMP_add_compression_method.3" "$(DESTDIR)$(mandir)/man3/SSL_COMP_get_compression_methods.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_add0_chain_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set0_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_add0_chain_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_add1_chain_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_set0_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add1_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add_extra_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_extra_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add_extra_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add_extra_chain_cert.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs_only.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_add_session.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_remove_session.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/SSL_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_ctrl.3" "$(DESTDIR)$(mandir)/man3/SSL_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_verify_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_get_verify_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_verify_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_load_verify_locations.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_verify_paths.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLS_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLS_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLS_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_2_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_2_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_2_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/DTLSv1_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSLv23_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSLv23_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/SSLv23_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLS_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLS_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLS_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_1_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_1_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_1_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_2_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_2_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_2_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_new.3" "$(DESTDIR)$(mandir)/man3/TLSv1_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_good.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_renegotiate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cache_full.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cb_hits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_good.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_renegotiate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_hits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_misses.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_number.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_timeouts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_cache_size.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_cache_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_get_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_new_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_remove_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_new_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_remove_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/get_session_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/new_session_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_sess_set_get_cb.3" "$(DESTDIR)$(mandir)/man3/remove_session_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_groups_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_curves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_curves_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_groups.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set1_groups.3" "$(DESTDIR)$(mandir)/man3/SSL_set1_groups_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_alpn_protos.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_alpn_selected.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_select_next_proto.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_alpn_select_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_set_alpn_protos.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_cert_store.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_cert_store.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_cipher_list.3" "$(DESTDIR)$(mandir)/man3/SSL_set_cipher_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_add_client_CA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_add_client_CA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_set_client_CA_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_client_cert_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_cert_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_client_cert_cb.3" "$(DESTDIR)$(mandir)/man3/client_cert_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_default_passwd_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_default_passwd_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb_userdata.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_default_passwd_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_passwd_cb_userdata.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_generate_session_id.3" "$(DESTDIR)$(mandir)/man3/GEN_SESSION_CB.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_generate_session_id.3" "$(DESTDIR)$(mandir)/man3/SSL_has_matching_session_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_generate_session_id.3" "$(DESTDIR)$(mandir)/man3/SSL_set_generate_session_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_info_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_info_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_get_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_info_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_keylog_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_keylog_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_keylog_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_keylog_cb_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_max_cert_list.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_cert_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_max_cert_list.3" "$(DESTDIR)$(mandir)/man3/SSL_get_max_cert_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_max_cert_list.3" "$(DESTDIR)$(mandir)/man3/SSL_set_max_cert_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_min_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_get_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_get_min_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_set_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_min_proto_version.3" "$(DESTDIR)$(mandir)/man3/SSL_set_min_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_get_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_set_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_msg_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_msg_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_msg_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_msg_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_num_tickets.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_num_tickets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_num_tickets.3" "$(DESTDIR)$(mandir)/man3/SSL_get_num_tickets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_num_tickets.3" "$(DESTDIR)$(mandir)/man3/SSL_set_num_tickets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_get_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_get_secure_renegotiation_support.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_options.3" "$(DESTDIR)$(mandir)/man3/SSL_set_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_quiet_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_quiet_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_quiet_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_get_quiet_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_quiet_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_set_quiet_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_get_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_read_ahead.3" "$(DESTDIR)$(mandir)/man3/SSL_set_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_security_level.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_security_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_security_level.3" "$(DESTDIR)$(mandir)/man3/SSL_get_security_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_security_level.3" "$(DESTDIR)$(mandir)/man3/SSL_set_security_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_session_cache_mode.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_session_cache_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_session_id_context.3" "$(DESTDIR)$(mandir)/man3/SSL_set_session_id_context.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_ssl_version.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ssl_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_ssl_version.3" "$(DESTDIR)$(mandir)/man3/SSL_get_ssl_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_ssl_version.3" "$(DESTDIR)$(mandir)/man3/SSL_set_ssl_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_timeout.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_servername_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_get_servername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_get_servername_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_servername_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_host_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_status_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_ocsp_resp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_ocsp_resp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_status_cb.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_use_srtp.3" "$(DESTDIR)$(mandir)/man3/SSL_get_selected_srtp_profile.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_use_srtp.3" "$(DESTDIR)$(mandir)/man3/SSL_get_srtp_profiles.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tlsext_use_srtp.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_use_srtp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_dh_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_dh.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_dh_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_dh_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_need_tmp_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_rsa.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_need_tmp_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_tmp_rsa_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/SSL_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/SSL_set_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/verify_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_check_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_check_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_chain_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_CTX_use_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_free.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_id.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set1_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_get_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_get_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_get_time.3" "$(DESTDIR)$(mandir)/man3/SSL_set_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_has_ticket.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ticket_lifetime_hint.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_print.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_SESSION_set1_id_context.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get0_id_context.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_alert_type_string.3" "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_alert_type_string.3" "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_alert_type_string.3" "$(DESTDIR)$(mandir)/man3/SSL_alert_type_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_certificate.3" "$(DESTDIR)$(mandir)/man3/SSL_get_privatekey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_get1_supported_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_ciphers.3" "$(DESTDIR)$(mandir)/man3/SSL_get_client_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_client_CA_list.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_CA_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_client_random.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_master_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_client_random.3" "$(DESTDIR)$(mandir)/man3/SSL_get_server_random.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_current_cipher.3" "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/SSL_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_get_rfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_get_wfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_finished.3" "$(DESTDIR)$(mandir)/man3/SSL_get_peer_finished.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_rbio.3" "$(DESTDIR)$(mandir)/man3/SSL_get_wbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_session.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_session.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_session.3" "$(DESTDIR)$(mandir)/man3/SSL_get1_session.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_accept_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_before.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_connect_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_in_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_is_init_finished.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_state.3" "$(DESTDIR)$(mandir)/man3/SSL_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_version.3" "$(DESTDIR)$(mandir)/man3/SSL_is_dtls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_get_version.3" "$(DESTDIR)$(mandir)/man3/SSL_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_library_init.3" "$(DESTDIR)$(mandir)/man3/OpenSSL_add_ssl_algorithms.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_library_init.3" "$(DESTDIR)$(mandir)/man3/SSLeay_add_ssl_algorithms.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_load_client_CA_file.3" "$(DESTDIR)$(mandir)/man3/SSL_add_dir_cert_subjects_to_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_load_client_CA_file.3" "$(DESTDIR)$(mandir)/man3/SSL_add_file_cert_subjects_to_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_new.3" "$(DESTDIR)$(mandir)/man3/SSL_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_num_renegotiations.3" "$(DESTDIR)$(mandir)/man3/SSL_clear_num_renegotiations.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_num_renegotiations.3" "$(DESTDIR)$(mandir)/man3/SSL_total_renegotiations.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read.3" "$(DESTDIR)$(mandir)/man3/SSL_peek.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read.3" "$(DESTDIR)$(mandir)/man3/SSL_peek_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read.3" "$(DESTDIR)$(mandir)/man3/SSL_read_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_get_early_data_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_get_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_set_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_read_early_data.3" "$(DESTDIR)$(mandir)/man3/SSL_write_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_renegotiate.3" "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_abbreviated.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_renegotiate.3" "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_pending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_rstate_string.3" "$(DESTDIR)$(mandir)/man3/SSL_rstate_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set1_host.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_peername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set1_host.3" "$(DESTDIR)$(mandir)/man3/SSL_set_hostflags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set1_param.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set1_param.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set1_param.3" "$(DESTDIR)$(mandir)/man3/SSL_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_connect_state.3" "$(DESTDIR)$(mandir)/man3/SSL_is_server.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_connect_state.3" "$(DESTDIR)$(mandir)/man3/SSL_set_accept_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_set_rfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_fd.3" "$(DESTDIR)$(mandir)/man3/SSL_set_wfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_max_send_fragment.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_send_fragment.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_psk_use_session_callback.3" "$(DESTDIR)$(mandir)/man3/SSL_psk_use_session_cb_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_shutdown.3" "$(DESTDIR)$(mandir)/man3/SSL_get_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ecdh_auto.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_set_ecdh_auto.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_set_tmp_ecdh.3" "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_ecdh_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_state_string.3" "$(DESTDIR)$(mandir)/man3/SSL_state_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_nothing.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_want.3" "$(DESTDIR)$(mandir)/man3/SSL_want_x509_lookup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "SSL_write.3" "$(DESTDIR)$(mandir)/man3/SSL_write_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_REQ_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_RESP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_RESP_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "TS_REQ_new.3" "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_UTIL_read_pw.3" "$(DESTDIR)$(mandir)/man3/UI_UTIL_read_pw_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_destroy_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_closer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_flusher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_opener.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_prompt_constructor.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_reader.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_get_writer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_closer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_flusher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_opener.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_prompt_constructor.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_reader.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_create_method.3" "$(DESTDIR)$(mandir)/man3/UI_method_set_writer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_action_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_output_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_result_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get0_test_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get_input_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get_result_maxsize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_get_result_minsize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_get_string_type.3" "$(DESTDIR)$(mandir)/man3/UI_set_result.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_info_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_input_boolean.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_input_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_user_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_add_verify_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_construct_prompt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_info_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_input_boolean.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_input_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_dup_verify_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get0_result.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get0_user_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_get_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_process.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "UI_new.3" "$(DESTDIR)$(mandir)/man3/UI_set_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/ED25519_keypair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/ED25519_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/ED25519_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X25519.3" "$(DESTDIR)$(mandir)/man3/X25519_keypair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509V3_EXT_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509V3_EXT_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509V3_add1_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_add1_ext_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add1_ext_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_add1_ext_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_get0_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_get0_uids.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509V3_get_d2i.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ALGOR_dup.3" "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_get0_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_get0_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_get0_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_new.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_new.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_new.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_ATTRIBUTE_set1_object.3" "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_set1_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_CINF_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_VAL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CINF_new.3" "$(DESTDIR)$(mandir)/man3/X509_VAL_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_METHOD_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_meth_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_METHOD_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_meth_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_add0_revoked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_by_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_REVOKED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_get0_by_serial.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_sort.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_new.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_CRL_print.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_EXTENSION_set_object.3" "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_INFO_new.3" "$(DESTDIR)$(mandir)/man3/X509_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_hash_dir.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_hash_dir.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_dir.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_fingerprint.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_issuer_serial.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_load_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir_env.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_LOOKUP_new.3" "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file_env.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_get_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_ENTRY_get_object.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_add_entry_by_txt.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_delete_entry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_entry_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_entry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_index_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_get_index_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_hash_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_hash.3" "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_new.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_oneline.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_NAME_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_print_ex_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free_contents.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get0_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_idx_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_match.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_OBJECT_get0_X509.3" "$(DESTDIR)$(mandir)/man3/X509_OBJECT_up_ref_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PKEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PUBKEY_new.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_sname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_sname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_PURPOSE_set.3" "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_delete_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_add_extensions_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_extension_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extension_nids.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_add_extensions.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_extension_nids.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_new.3" "$(DESTDIR)$(mandir)/man3/X509_to_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REQ_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_revocationDate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_revocationDate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_REVOKED_new.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_SIG_get0.3" "$(DESTDIR)$(mandir)/man3/X509_SIG_getm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_SIG_new.3" "$(DESTDIR)$(mandir)/man3/X509_SIG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_parent_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_current_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_error_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_num_untrusted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_verified_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_current_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_error.3" "$(DESTDIR)$(mandir)/man3/X509_verify_cert_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_get_ex_new_index.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_store.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_untrusted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_trusted_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_untrusted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_trusted_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_purpose_inherit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_default.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_purpose.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_check_issued_fn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_check_issued.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_fn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_check_issued.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_check_issued.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify_cb.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_CTX_set_verify_cb.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_obj_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_get_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_load_locations.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_add_lookup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_load_locations.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_load_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_load_locations.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_default_paths.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_new.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_add_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_add_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_objects.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_purpose.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set1_param.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set_verify_cb_func.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_STORE_set_verify_cb_func.3" "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_by_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_TRUST_set.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_table.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_inherit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_lookup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_new.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_table_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_policy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add1_host.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_peername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_email.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_host.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip_asc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_policies.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_auth_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_hostflags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_purpose.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_VERIFY_PARAM_set_flags.3" "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_add1_trust_object.3" "$(DESTDIR)$(mandir)/man3/X509_add1_reject_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_add1_trust_object.3" "$(DESTDIR)$(mandir)/man3/X509_reject_clear.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_add1_trust_object.3" "$(DESTDIR)$(mandir)/man3/X509_trust_clear.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_check_host.3" "$(DESTDIR)$(mandir)/man3/X509_check_email.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_check_host.3" "$(DESTDIR)$(mandir)/man3/X509_check_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_check_host.3" "$(DESTDIR)$(mandir)/man3/X509_check_ip_asc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_check_private_key.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_check_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_check_trust.3" "$(DESTDIR)$(mandir)/man3/X509_TRUST_set_default.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_match.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_and_serial_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_issuer_name_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp.3" "$(DESTDIR)$(mandir)/man3/X509_subject_name_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_cmp_current_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_gmtime_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_time_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_cmp_time.3" "$(DESTDIR)$(mandir)/man3/X509_time_adj_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_digest.3" "$(DESTDIR)$(mandir)/man3/X509_pubkey_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_find_by_subject.3" "$(DESTDIR)$(mandir)/man3/X509_find_by_issuer_and_serial.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_get0_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_get_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_get_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_getm_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_getm_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set1_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set1_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_notBefore.3" "$(DESTDIR)$(mandir)/man3/X509_set_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_signature.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_tbs_sigalg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_signature_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_signature.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_signature_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_get0_tbs_sigalg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_get_signature_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get0_signature.3" "$(DESTDIR)$(mandir)/man3/X509_get_signature_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get1_email.3" "$(DESTDIR)$(mandir)/man3/X509_email_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get1_email.3" "$(DESTDIR)$(mandir)/man3/X509_get1_ocsp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_extension_flags.3" "$(DESTDIR)$(mandir)/man3/X509_get_extended_key_usage.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_extension_flags.3" "$(DESTDIR)$(mandir)/man3/X509_get_key_usage.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_extract_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_extract_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey_bitstr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_get_X509_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_pubkey.3" "$(DESTDIR)$(mandir)/man3/X509_set_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_serialNumber.3" "$(DESTDIR)$(mandir)/man3/X509_get0_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_serialNumber.3" "$(DESTDIR)$(mandir)/man3/X509_set_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_issuer_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_subject_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_subject_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_get_issuer_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_set_issuer_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_subject_name.3" "$(DESTDIR)$(mandir)/man3/X509_set_subject_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_set_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_set_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_get_version.3" "$(DESTDIR)$(mandir)/man3/X509_set_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_keyid_set1.3" "$(DESTDIR)$(mandir)/man3/X509_alias_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_keyid_set1.3" "$(DESTDIR)$(mandir)/man3/X509_alias_set1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_keyid_set1.3" "$(DESTDIR)$(mandir)/man3/X509_keyid_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_load_cert_file.3" "$(DESTDIR)$(mandir)/man3/X509_load_cert_crl_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_load_cert_file.3" "$(DESTDIR)$(mandir)/man3/X509_load_crl_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_to_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_chain_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_new.3" "$(DESTDIR)$(mandir)/man3/X509_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_print_ex_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_print_ex.3" "$(DESTDIR)$(mandir)/man3/X509_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_REQ_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_sign.3" "$(DESTDIR)$(mandir)/man3/X509_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509_signature_dump.3" "$(DESTDIR)$(mandir)/man3/X509_signature_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_add1_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_delete_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get0_data_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509at_get_attr.3" "$(DESTDIR)$(mandir)/man3/X509at_get_attr_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_prefix.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_range.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_canonize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_add_inherit.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_is_canonical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_get_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_get_afi.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_inherits.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_inherits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_subset.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_subset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_validate_path.3" "$(DESTDIR)$(mandir)/man3/X509v3_addr_validate_resource_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_validate_path.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_path.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_addr_validate_path.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_resource_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_asid_add_id_or_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_add_inherit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_asid_add_id_or_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_canonize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_asid_add_id_or_range.3" "$(DESTDIR)$(mandir)/man3/X509v3_asid_is_canonical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "X509v3_get_ext_by_NID.3" "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_add_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_check_top.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_cmp_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_div_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_expand.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_expand2.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_fix_top.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_add_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_comba4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_comba8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_normal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_part_recursive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_recursive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_mul_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_set_high.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_set_low.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_set_max.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_comba4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_comba8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_normal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_recursive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sqr_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_sub_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/bn_wexpand.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/mul_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "bn_dump.3" "$(DESTDIR)$(mandir)/man3/sqr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_NULL.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_NULL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OBJECT.3" "$(DESTDIR)$(mandir)/man3/OBJ_get0_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OBJECT.3" "$(DESTDIR)$(mandir)/man3/OBJ_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OBJECT.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OBJECT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BIT_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BMPSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALIZEDTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_IA5STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_T61STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UINTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UNIVERSALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTCTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTF8STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_VISIBLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_DIRECTORYSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/d2i_DISPLAYTEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BIT_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BMPSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALIZEDTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_IA5STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_T61STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UNIVERSALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTCTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTF8STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_VISIBLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_DIRECTORYSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_OCTET_STRING.3" "$(DESTDIR)$(mandir)/man3/i2d_DISPLAYTEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_SEQUENCE_ANY.3" "$(DESTDIR)$(mandir)/man3/d2i_ASN1_SET_ANY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_SEQUENCE_ANY.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SEQUENCE_ANY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ASN1_SEQUENCE_ANY.3" "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SET_ANY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_AUTHORITY_KEYID.3" "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_KEYID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_BASIC_CONSTRAINTS.3" "$(DESTDIR)$(mandir)/man3/d2i_EXTENDED_KEY_USAGE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_BASIC_CONSTRAINTS.3" "$(DESTDIR)$(mandir)/man3/i2d_BASIC_CONSTRAINTS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_BASIC_CONSTRAINTS.3" "$(DESTDIR)$(mandir)/man3/i2d_EXTENDED_KEY_USAGE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/d2i_CMS_ReceiptRequest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/d2i_CMS_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/i2d_CMS_ContentInfo.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/i2d_CMS_ReceiptRequest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_CMS_ContentInfo.3" "$(DESTDIR)$(mandir)/man3/i2d_CMS_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DHparams.3" "$(DESTDIR)$(mandir)/man3/i2d_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_ACCESS_DESCRIPTION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_AUTHORITY_INFO_ACCESS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_CRL_DIST_POINTS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_DIST_POINT_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/d2i_ISSUING_DIST_POINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_ACCESS_DESCRIPTION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_INFO_ACCESS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_CRL_DIST_POINTS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DIST_POINT.3" "$(DESTDIR)$(mandir)/man3/i2d_ISSUING_DIST_POINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/DSAparams_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_DSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECPKParameters_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECPKParameters_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECParameters_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECParameters_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/ECParameters_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/i2o_ECPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ECPKParameters.3" "$(DESTDIR)$(mandir)/man3/o2i_ECPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/d2i_ESS_CERT_ID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/d2i_ESS_ISSUER_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/i2d_ESS_CERT_ID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/i2d_ESS_ISSUER_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_ESS_SIGNING_CERT.3" "$(DESTDIR)$(mandir)/man3/i2d_ESS_SIGNING_CERT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_EDIPARTYNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_GENERAL_NAMES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_OTHERNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_EDIPARTYNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAMES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_GENERAL_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_OTHERNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_ONEREQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REQINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SERVICELOC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SIGNATURE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_ONEREQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQUEST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SERVICELOC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_REQUEST.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SIGNATURE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_BASICRESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTSTATUS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CRLID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPBYTES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPDATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REVOKEDINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SINGLERESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_BASICRESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTSTATUS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CRLID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPBYTES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPDATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPONSE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REVOKEDINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_OCSP_RESPONSE.3" "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SINGLERESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_BAGS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_MAC_DATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_SAFEBAG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_BAGS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_MAC_DATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_SAFEBAG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS12.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_DIGEST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENCRYPT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENC_CONTENT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ISSUER_AND_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_RECIP_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNER_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGN_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_DIGEST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENCRYPT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENC_CONTENT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ISSUER_AND_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_RECIP_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNER_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGN_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS7.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8PrivateKey_bio.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKCS8_PRIV_KEY_INFO.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PKEY_USAGE_PERIOD.3" "$(DESTDIR)$(mandir)/man3/i2d_PKEY_USAGE_PERIOD.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_CERTIFICATEPOLICIES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_NOTICEREF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_POLICYQUALINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/d2i_USERNOTICE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_CERTIFICATEPOLICIES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_NOTICEREF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_POLICYINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_POLICYQUALINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_POLICYINFO.3" "$(DESTDIR)$(mandir)/man3/i2d_USERNOTICE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_AutoPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/d2i_PublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_PrivateKey.3" "$(DESTDIR)$(mandir)/man3/i2d_PublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_Netscape_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PSS_PARAMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_Netscape_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PSS_PARAMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_RSAPublicKey.3" "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_SSL_SESSION.3" "$(DESTDIR)$(mandir)/man3/i2d_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_ACCURACY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_STATUS_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_ACCURACY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_STATUS_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_TS_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CERT_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CINF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_VAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CERT_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CINF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_VAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_re_X509_CRL_tbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_re_X509_REQ_tbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509.3" "$(DESTDIR)$(mandir)/man3/i2d_re_X509_tbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_ALGOR.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_ALGORS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_ALGOR.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGOR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_ALGOR.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGORS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_ATTRIBUTE.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_ATTRIBUTE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REVOKED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_CRL.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REVOKED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_EXTENSION.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_EXTENSIONS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_EXTENSION.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_EXTENSION.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSIONS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_get0_der.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/X509_NAME_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_NAME_ENTRY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_NAME.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME_ENTRY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_REQ.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "d2i_X509_SIG.3" "$(DESTDIR)$(mandir)/man3/i2d_X509_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_get_pw_prompt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string_min.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "des_read_pw.3" "$(DESTDIR)$(mandir)/man3/EVP_set_pw_prompt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/a2i_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/a2i_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/a2i_ASN1_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/i2a_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "i2a_ASN1_STRING.3" "$(DESTDIR)$(mandir)/man3/i2a_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/DECLARE_LHASH_OF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_COMP_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_ARG_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/LHASH_HASH_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_delete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_doall.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_doall_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_insert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_retrieve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_new.3" "$(DESTDIR)$(mandir)/man3/lh_strhash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_stats.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_stats_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "lh_stats.3" "$(DESTDIR)$(mandir)/man3/lh_stats_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED_TABLE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/i2s_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "s2i_ASN1_INTEGER.3" "$(DESTDIR)$(mandir)/man3/s2i_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_accept_socket.3" "$(DESTDIR)$(mandir)/man3/tls_accept_cbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_accept_socket.3" "$(DESTDIR)$(mandir)/man3/tls_accept_fds.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_configure.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_client.3" "$(DESTDIR)$(mandir)/man3/tls_server.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_parse_protocols.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_client.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_server.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_alpn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_dheparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_protocols.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ecdhecurves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_session_id.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_ticket_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_session_id.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_session_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_set_session_id.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_session_lifetime.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_verify.3" "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifycert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_verify.3" "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifyname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_config_verify.3" "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifytime.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_alpn_selected.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_cipher_strength.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_servername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_conn_session_resumed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_chain_pem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_contains_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notafter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notbefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_provided.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_conn_version.3" "$(DESTDIR)$(mandir)/man3/tls_peer_cert_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_cbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_fds.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_servername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_connect.3" "$(DESTDIR)$(mandir)/man3/tls_connect_socket.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_init.3" "$(DESTDIR)$(mandir)/man3/tls_config_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_init.3" "$(DESTDIR)$(mandir)/man3/tls_config_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_init.3" "$(DESTDIR)$(mandir)/man3/tls_config_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_clear_keys.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_path.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_key_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_key_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_set_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_verify_client.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_config_verify_client_optional.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_default_ca_cert_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_load_file.3" "$(DESTDIR)$(mandir)/man3/tls_unload_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_cert_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_crl_reason.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_next_update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_response_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_result.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_revocation_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_this_update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_ocsp_process_response.3" "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_url.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_close.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_handshake.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "tls_read.3" "$(DESTDIR)$(mandir)/man3/tls_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_intermediates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_chains.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_signatures.3" +@ENABLE_LIBTLS_ONLY_FALSE@ ln -sf "x509_verify.3" "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_purpose.3" + +@ENABLE_LIBTLS_ONLY_FALSE@uninstall-local: +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ACCESS_DESCRIPTION_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AUTHORITY_INFO_ACCESS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AES_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AES_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AES_set_decrypt_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AES_set_encrypt_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASIdentifiers_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifiers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifiers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_get_bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_set_bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_get_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_set_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_to_BN.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_get_uint64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_int64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_set_uint64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_to_BN.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_to_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_NULL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OBJECT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_TABLE_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get0_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_length_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_to_UTF8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BIT_STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_BMPSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_ENUMERATED_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_IA5STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_INTEGER_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_OCTET_STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLESTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_PRINTABLE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_type_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_T61STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UNIVERSALSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTF8STRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_VISIBLESTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DIRECTORYSTRING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DISPLAYTEXT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_print_ex_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_tag2str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_GENERALIZEDTIME_set_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_cmp_time_t.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_compare.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_diff.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_normalize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_string_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_generalizedtime.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_to_tm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_cmp_time_t.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_UTCTIME_set_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_int_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_get_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_int_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TYPE_set_octetstring.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_generate_v3.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_d2i_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_i2d_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_unpack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_item_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_get_default_mask.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_STRING_set_default_mask_asc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_mbstring_ncopy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_tag2bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_parse.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_object_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_put_eoc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_TIME_set_tm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_time_tm_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASIdOrRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASIdOrRange_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASIdentifierChoice_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASIdOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASIdentifierChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASIdOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASIdentifierChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/AUTHORITY_KEYID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BASIC_CONSTRAINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BF_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BF_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BF_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BF_ecb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BF_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BF_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_accept_socket.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_host_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_tcp_ndelay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_sock_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_sock_non_fatal_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_sock_should_retry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_socket_nbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_pending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_wpending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_eof.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_flush.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_close.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_info_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_int_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_pending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ptr_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_seek.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_close.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_tell.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_wpending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bio_info_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dump_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dump_indent.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dump_indent_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dup_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_buffer_num_lines.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_read_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_buffer_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_read_buffer_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_write_buffer_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_cipher_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_md_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_md_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_do_handshake.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_num_renegotiates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_ssl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_buffer_ssl_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_ssl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_ssl_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_bytes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ssl_renegotiate_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ssl_copy_session_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ssl_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_method_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_method_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_next.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_clear_retry_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_copy_next_retry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_retry_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_special.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TYPE_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_destroy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_gets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_puts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_get_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_destroy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_gets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_puts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_meth_set_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_free_all.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_vfree.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_snprintf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_vprintf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_vsnprintf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_pop.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_next.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_gets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_indent.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_number_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_number_written.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_puts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_do_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_accept_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_bind_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_accept_bios.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_accept_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_bind_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_nbio_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_read_request.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_get_write_guarantee.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_reset_read_request.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_destroy_bio_pair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_read_request.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_write_buf_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_write_guarantee.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_make_bio_pair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_bio_pair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_write_buf_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_shutdown_wr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_do_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_hostname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_int_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_conn_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_hostname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_int_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_conn_port.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_nbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_dgram_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_ctrl_set_connected.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_get_peer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_non_fatal_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_recv_timedout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_send_timedout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_dgram_set_peer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_dgram.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_fd_non_fatal_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_fd_should_retry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_append_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_read_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_rw_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_write_filename.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_mem_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_mem_ptr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_mem_buf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_mem_buf.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_mem_eof_return.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_new_socket.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_callback_fn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_callback_fn_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_debug_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_callback_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_callback_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_retry_BIO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_get_retry_reason.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_retry_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_set_retry_reason.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_should_io_special.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_should_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BIO_should_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_CTX_end.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_CTX_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_div.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_gcd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_add_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift1_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_lshift_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_sqr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_sub.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_sub_quick.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_nnmod.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_sqr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_sub.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_uadd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_usub.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_div_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mod_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mul_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_sub_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_asc2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_bin2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2binpad.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2hex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2lebinpad.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_bn2mpi.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_dec2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_hex2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_lebin2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mpi2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_abs_is_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_odd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_one.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_zero.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_ucmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_with_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_call.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_get_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_GENCB_set_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_generate_prime_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_prime_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_prime_fasttest_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_1024.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc2409_prime_768.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_1536.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_2048.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_3072.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_4096.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_rfc3526_prime_6144.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_MONT_CTX_set_locked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_from_montgomery.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_to_montgomery.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_clear.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_clear_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_num_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_num_bits_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_pseudo_rand_range.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_rand_range.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_clear_bit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_bit_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_lshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_lshift1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_mask_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_rshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_rshift1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_is_negative.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_consttime_swap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_get_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_one.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_set_word.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_value_one.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BUF_MEM_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BUF_MEM_grow_clean.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_get0_cipher_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMAC_resume.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ContentInfo_print_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add0_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add1_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add1_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get1_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get1_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add0_recipient_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_decrypt_set1_pkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_get0_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_kekri_id_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_cert_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_ktri_get0_signer_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_set0_pkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_RecipientInfo_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_cert_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signature.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get0_signer_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_SignerInfo_set1_signer_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get0_content.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get0_eContentType.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_set1_eContentType.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_create0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_ReceiptRequest_get0_values.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_add1_ReceiptRequest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CMS_get0_signers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CONF_modules_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CONF_modules_unload.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CONF_modules_load.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_area.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_MEM_LEAK_CB.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_mem_leaks_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_set_mem_functions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_cpy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_current.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_THREADID_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_r_lock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_r_unlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_w_lock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_w_unlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_EX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_free_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_new_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_chacha_20.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_hchacha_20.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_xchacha_20.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ChaCha_set_iv.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ChaCha_set_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_cbc_cksum.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_cfb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_crypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ecb2_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ecb3_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ecb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede2_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede2_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede2_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_cbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_cbcm_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_cfb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ede3_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_enc_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_enc_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_fcrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_is_weak_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_key_sched.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ncbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ofb64_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_ofb_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_pcbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_quad_cksum.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_random_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_set_key_checked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_set_key_unchecked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_set_odd_parity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_string_to_2keys.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_string_to_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DES_xcbc_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_compute_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_check_pub_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_generate_parameters_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_g.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_p.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_priv_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_pub_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get0_q.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_set0_pqg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRL_DIST_POINTS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DIST_POINT_NAME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DIST_POINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ISSUING_DIST_POINT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_SIG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_SIG_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_SIG_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_do_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_generate_parameters_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_g.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_p.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_priv_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_pub_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get0_q.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set0_pqg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_set1_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_set_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_meth_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_sign_setup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDH_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_r.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_get0_s.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_SIG_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_do_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_do_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECDSA_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECDSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECDSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GFp_mont_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_METHOD_get_field_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_check_discriminant.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_generator.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get0_seed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_asn1_flag.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_basis_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_cofactor.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_degree.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_order.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_point_conversion_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_seed_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_method_of.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_order_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_asn1_flag.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_generator.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_point_conversion_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_seed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_clear_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_get_curve_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_by_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_new_curve_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_set_curve_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_get_builtin_curves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_compute_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_compute_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_METHOD_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_check_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_generate_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_group.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get0_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_conv_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_enc_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_new_by_curve_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_precompute_mult.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_asn1_flag.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_conv_form.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_enc_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_group.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_set_public_key_affine_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_KEY_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_have_precompute_mult.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_GROUP_precompute_mult.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_dbl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_invert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_is_at_infinity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_is_on_curve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_make_affine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINTs_make_affine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINTs_mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_bn2point.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_clear_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_get_Jprojective_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_get_affine_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_hex2point.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_method_of.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_oct2point.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_point2bn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_point2hex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_point2oct.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_Jprojective_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_affine_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_compressed_coordinates_GFp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EC_POINT_set_to_infinity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_by_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_first.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_last.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_next.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_prev.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_remove.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_CTRL_FUNC_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_cmd_is_executable.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_ctrl_cmd_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_cmd_defns.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ctrl_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_cmd_defns.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_ctrl_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_EC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_default_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest_engine.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_table_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_table_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_finish_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_init_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_finish_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_init_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_GEN_INT_FUNC_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_destroy_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_destroy_function.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_complete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_load_builtin_engines.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_load_dynamic.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_complete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_register_all_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_CIPHERS_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_DIGESTS_PTR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_EC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_EC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_set_default_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ECDSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_RAND.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_STORE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_unregister_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_FATAL_ERROR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_GET_FUNC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_GET_REASON.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_error_string_n.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_func_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_lib_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_reason_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_get_error_line.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_get_error_line_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_error_line_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_peek_last_error_line_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_free_strings.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_load_error_strings.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_PACK.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_get_next_error_library.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_print_errors_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_print_errors_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_add_error_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_add_error_vdata.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_remove_thread_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ERR_pop_to_mark.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ESS_CERT_ID_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ESS_ISSUER_SERIAL_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ESS_SIGNING_CERT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_open.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_CTX_seal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_overhead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_max_tag_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_AEAD_nonce_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_128_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_aes_256_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_chacha20_poly1305.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aead_xchacha20_poly1305.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_iv.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_iv_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_iv.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_padding.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_iv_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_key_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_buf_noconst.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_cipher_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_rand_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_asn1_to_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_param_to_asn1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_do_all_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_do_all_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_do_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_get_asn1_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_impl_ctx_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_iv_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_meth_set_set_asn1_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_Digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_copy_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_destroy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_digestbynid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_digestbyobj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_ripemd160.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha224.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha384.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha512.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha512_224.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha512_256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestSign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestSignFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestSignUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestVerify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DigestVerifyUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeBlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeInit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecodeUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_ENCODE_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncodeBlock.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncodeFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncodeUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_encrypting.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CIPHER_CTX_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_Cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherInit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_CipherUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_DecryptUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptFinal_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_EncryptUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_bf_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cast5_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_enc_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbynid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_cipherbyobj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_idea_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_40_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_64_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc2_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_md_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_pkey_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_set_pkey_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_app_datasize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_input_blocksize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_result_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_meth_set_update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_CTX_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_block_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_pkey_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_MD_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_OpenFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_OpenUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY2PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_ctrl_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_ecdh_kdf_ukm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get1_id_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_cofactor_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_outlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_ecdh_kdf_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_signature_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_ecdh_kdf_ukm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_generator.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dh_paramgen_prime_len.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_dsa_paramgen_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_param_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ec_paramgen_curve_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_cofactor_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_outlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_ecdh_kdf_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_signature_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_pkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_new_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_add1_hkdf_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_hkdf_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set1_hkdf_salt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_add1_attr_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_delete_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_attr_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_find_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_get0_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_asn1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_add_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_param_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_private.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_public_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_asn1_set_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_param_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_public_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_cmp_parameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_copy_parameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_missing_parameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_peerkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_derive_set_peer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_keygen_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_keygen_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_gen_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_keygen_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_paramgen_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_add0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_derive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_encrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_param_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_paramgen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_public_check.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_signctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verify_recover.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_meth_set_verifyctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get_raw_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_CMAC_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_mac_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_new_raw_public_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_print_public.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_GOST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_assign_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_base_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get0_hmac.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_get1_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DH.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_DSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set1_EC_KEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_set_type_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_sign_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_verify_recover_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SealFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SealUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SignFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SignInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_SignUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_VerifyFinal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_VerifyInit_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_VerifyUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_add_cipher_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_add_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_add_digest_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_delete_cipher_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_delete_digest_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cbc_hmac_sha1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ccm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_wrap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_128_xts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ccm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_192_wrap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cbc_hmac_sha1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ccm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_gcm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_wrap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_aes_256_xts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_128_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_192_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_camellia_256_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_chacha20_poly1305.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_cfb8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede3_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_cfb64.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ede_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_des_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_desx_cbc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc4_40.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_rc4_hmac_md5.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md5.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_md5_sha1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha3_256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha3_384.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sha3_512.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_cfb128.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_ctr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_ecb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_sm4_ofb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EXTENDED_KEY_USAGE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EDIPARTYNAME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_NAMES_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_NAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OTHERNAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OTHERNAME_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_copy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_get_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_CTX_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Init_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/HMAC_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressChoice_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressChoice_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressFamily_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressFamily_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressOrRange_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/IPAddressRange_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressFamily.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_IPAddressRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressChoice.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressFamily.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressOrRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_IPAddressRange.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD4_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD4_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD4_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD5_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD5_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/MD5_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/GENERAL_SUBTREE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/NAME_CONSTRAINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_do_all_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_NAME_remove.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_add_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_create_objects.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_new_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/check_defer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/obj_cleanup_defer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_find_sigid_by_algs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_ln2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_nid2ln.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_nid2sn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_obj2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_obj2txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_sn2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_txt2nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_txt2obj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2a_ASN1_OBJECT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2t_ASN1_OBJECT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CRLID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_ONEREQ_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQINFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQUEST_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SIGNATURE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_add0_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_add1_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_onereq_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_request_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SERVICELOC_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_url_svcloc_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTID_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_cert_id_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_id_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_id_get0_info.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_id_issuer_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_basic_add1_nonce.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_check_nonce.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_copy_nonce.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_CERTSTATUS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REVOKEDINFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_get0_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_SINGLERESP_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_basic_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_cert_status_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_check_validity.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_resp_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_resp_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_resp_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_single_get0_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_BASICRESP_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPBYTES_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPDATA_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPID_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_RESPONSE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_basic_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_response_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_response_get1_basic.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_response_status_str.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_add1_header.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_REQ_CTX_set1_req.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_parse_url.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OCSP_sendreq_nbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_NUMBER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/LIBRESSL_VERSION_TEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_VERSION_TEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_version_num.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_no_config.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ASN1_add_oid_module.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ENGINE_add_conf_module.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_malloc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_realloc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CRYPTO_strdup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_realloc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OPENSSL_strdup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_delete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_delete_ptr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_find_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_insert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_is_sorted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_new_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_num.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_pop.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_pop_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_push.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_set_cmp_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_shift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_sort.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_unshift.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_value.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sk_zero.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_add_all_digests.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay_add_all_algorithms.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_ASN1_read_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_of_void.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_X509_INFO_read_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_def_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_do_header.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_get_EVP_CIPHER_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/pem_password_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_read_bio_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8PrivateKey_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_X509_REQ_NEW.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_CMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8PrivateKey_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PEM_write_bio_X509_REQ_NEW.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_BAGS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_SAFEBAG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_MAC_DATA_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS12_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS5_PBKDF2_HMAC_SHA1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add0_attrib_signing_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add1_attrib_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_content_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add_attrib_smimecap.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_add_signed_attribute.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_get_attribute.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_get_signed_attribute.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_set_attributes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_set_signed_attributes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_DIGEST_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENCRYPT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENC_CONTENT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ENVELOPE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_RECIP_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNED_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGNER_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_SIGN_ENVELOPE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_content_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_set0_type_other.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_get0_signers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_PRIV_KEY_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS8_pkey_get0_attrs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKEY_USAGE_PERIOD_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/CERTIFICATEPOLICIES_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/NOTICEREF_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/NOTICEREF_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICYINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICYQUALINFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_CONSTRAINTS_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/POLICY_MAPPING_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/USERNOTICE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/USERNOTICE_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_poll.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_seed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_pseudo_bytes.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_file_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_write_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_SSLeay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RAND_get_rand_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RC4_set_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RIPEMD160_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RIPEMD160_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RIPEMD160_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_PSS_PARAMS_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_blinding_off.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_generate_key_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_crt_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_dmp1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_dmq1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_e.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_factors.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_iqmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_n.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_p.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get0_q.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set0_crt_params.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set0_factors.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set0_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_test_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_bn_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_priv_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_pub_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set0_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set1_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_bn_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_finish.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_keygen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_mod_exp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_priv_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_dec.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_pub_enc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_meth_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSAPrivateKey_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSAPublicKey_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_OAEP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_add_PKCS1_type_2.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_add_none.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_OAEP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_PKCS1_type_2.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_padding_check_none.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get0_rsa_oaep_label.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_mgf1_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_oaep_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_padding.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_get_rsa_pss_saltlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_keygen_pubexp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_mgf1_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_oaep_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_padding.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_CTX_set_rsa_pss_saltlen.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DHparams_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DHparams_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSAparams_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSAparams_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_public_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_decrypt_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_PKEY_encrypt_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_private_decrypt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/BN_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DH_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSA_security_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_PKCS1_SSLeay.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_get_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_verify_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/RSA_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA1_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA1_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA1_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA224.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA224_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA224_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA224_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA256.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA256_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA256_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA256_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA384.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA384_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA384_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA384_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA512.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA512_Final.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA512_Init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SHA512_Update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_description.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_find.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_auth_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_cipher_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_digest_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_kx_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CIPHER_is_aead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_COMP_get_compression_methods.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_add0_chain_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set0_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add0_chain_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add1_chain_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set0_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_extra_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_extra_chain_certs_only.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_remove_session.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_callback_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_verify_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_verify_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_verify_paths.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLS_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLS_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLS_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_2_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_2_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_2_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DTLSv1_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLv23_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLv23_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLv23_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLS_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLS_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLS_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_1_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_1_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_1_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_2_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_2_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_2_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_client_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TLSv1_server_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_good.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_accept_renegotiate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cache_full.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_cb_hits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_good.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_connect_renegotiate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_hits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_misses.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_timeouts.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_cache_size.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_get_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_new_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_get_remove_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_new_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_sess_set_remove_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/get_session_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/new_session_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/remove_session_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_curves_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_groups_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_curves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_curves_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_groups.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set1_groups_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_alpn_protos.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_alpn_selected.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_select_next_proto.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_alpn_protos.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_cert_store.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_cipher_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_add_client_CA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add_client_CA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_client_CA_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_cert_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/client_cert_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_passwd_cb_userdata.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_default_passwd_cb_userdata.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/GEN_SESSION_CB.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_has_matching_session_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_generate_session_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_info_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_keylog_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_keylog_cb_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_cert_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_max_cert_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_max_cert_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_min_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_min_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_max_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_min_proto_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_msg_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_msg_callback_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_num_tickets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_num_tickets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_num_tickets.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_clear_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_secure_renegotiation_support.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_options.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_quiet_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_quiet_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_quiet_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_default_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_read_ahead.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_security_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_security_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_security_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_session_cache_mode.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_session_id_context.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ssl_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_ssl_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_ssl_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_servername_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_servername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_servername_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_host_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_tlsext_status_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tlsext_status_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_ocsp_resp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_tlsext_status_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_ocsp_resp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_status_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_selected_srtp_profile.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_srtp_profiles.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tlsext_use_srtp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_dh.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_dh_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_need_tmp_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_rsa.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_need_tmp_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_rsa_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/verify_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_check_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_PrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_RSAPrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_chain_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_use_certificate_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_check_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_PrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_RSAPrivateKey_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_ASN1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_chain_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_use_certificate_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set1_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_timeout.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_ticket_lifetime_hint.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get0_id_context.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_alert_desc_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_alert_type_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_privatekey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get1_supported_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_client_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_client_CA_list.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_master_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_server_random.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_bits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_cipher_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_rfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_wfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_peer_finished.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_wbio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_session.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get1_session.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_accept_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_before.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_connect_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_in_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_is_init_finished.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_is_dtls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OpenSSL_add_ssl_algorithms.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSLeay_add_ssl_algorithms.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add_dir_cert_subjects_to_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_add_file_cert_subjects_to_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_clear_num_renegotiations.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_total_renegotiations.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_peek.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_peek_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_read_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_get_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_SESSION_set_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_early_data_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_max_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_write_early_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_abbreviated.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_renegotiate_pending.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_rstate_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_peername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_hostflags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set1_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_is_server.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_accept_state.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_rfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_wfd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_max_send_fragment.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_psk_use_session_cb_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_get_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_ecdh_auto.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_CTX_set_tmp_ecdh_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_ecdh_auto.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_set_tmp_ecdh_callback.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_state_string_long.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_nothing.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_read.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_want_x509_lookup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/SSL_write_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_ACCURACY_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_MSG_IMPRINT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_REQ_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_RESP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_RESP_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_STATUS_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/TS_TST_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_UTIL_read_pw_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_destroy_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_closer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_flusher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_opener.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_prompt_constructor.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_reader.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_get_writer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_closer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_flusher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_opener.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_prompt_constructor.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_reader.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_method_set_writer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_action_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_output_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_result_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_test_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_input_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_result_maxsize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_result_minsize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_result.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_OpenSSL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_info_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_input_boolean.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_input_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_user_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_add_verify_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_construct_prompt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_info_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_input_boolean.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_input_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_dup_verify_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_result.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get0_user_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_get_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_new_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_null.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_process.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/UI_set_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ED25519_keypair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ED25519_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ED25519_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X25519_keypair.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509V3_EXT_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509V3_EXT_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509V3_add1_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_add1_ext_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add1_ext_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_add1_ext_i2d.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_uids.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_d2i.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ALGOR_set_md.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_get0_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_create_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_ATTRIBUTE_set1_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CINF_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VAL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VAL_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_METHOD_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_meth_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_default_method.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_meth_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_add0_revoked.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_by_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_REVOKED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_sort.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_create_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_get_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_EXTENSION_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_dir.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_add_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_alias.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_fingerprint.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_issuer_serial.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_ctrl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_load_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_LOOKUP_shutdown.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_dir_env.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_default_cert_file_env.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_create_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_get_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_set_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_add_entry_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_delete_entry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_entry_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_entry.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_index_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get_text_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_hash_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_name_hash_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_subject_name_hash_old.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_oneline.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_print_ex_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_free_contents.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get0_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_get_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_idx_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_retrieve_match.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_OBJECT_up_ref_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PKEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PUBKEY_set0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get0_sname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_by_sname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_PURPOSE_get_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add1_attr_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_delete_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_attr_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_add_extensions_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_extension_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extension_nids.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_extensions.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_extension_nids.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_INFO_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_to_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_revocationDate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get0_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_revocationDate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_set_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_SIG_getm.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_SIG_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_current_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_parent_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_current_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_error_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_num_untrusted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_verified_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_current_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_error_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_verify_cert_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_app_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_store.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_untrusted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_init.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_trusted_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_untrusted.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_trusted_stack.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_purpose_inherit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_default.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_purpose.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_set_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_check_issued_fn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_check_issued.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_fn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_check_issued.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_check_issued.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_func.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get1_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_CTX_get_obj_by_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_certs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get1_crls.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_add_lookup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_load_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_default_paths.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_add_cert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_add_crl.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_objects.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get0_param.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_ex_new_index.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_ex_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_purpose.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_get_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_STORE_set_verify_cb.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_by_id.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_get_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_table.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_inherit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_lookup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_table_cleanup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add0_policy.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_add1_host.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_clear_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get0_peername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_flags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_get_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_email.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_host.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_ip_asc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set1_policies.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_auth_level.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_hostflags.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_purpose.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_VERIFY_PARAM_set_trust.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_add1_reject_object.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_reject_clear.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_trust_clear.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_check_email.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_check_ip.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_check_ip_asc.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_check_private_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_TRUST_set_default.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_match.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_and_serial_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_issuer_name_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_subject_name_cmp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_cmp_current_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_gmtime_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_time_adj.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_time_adj_ex.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/PKCS7_ISSUER_AND_SERIAL_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_pubkey_digest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_find_by_issuer_and_serial.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set1_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_lastUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_nextUpdate.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_getm_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_getm_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set1_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set1_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_notAfter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_notBefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_signature.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get0_tbs_sigalg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_signature_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_signature.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_signature_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_tbs_sigalg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_signature_nid.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_signature_type.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_email_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get1_ocsp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_extended_key_usage.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_key_usage.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_extract_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get0_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_extract_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_pubkey_bitstr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_X509_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_pubkey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get0_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_serialNumber.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_issuer_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_subject_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_subject_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_issuer_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_issuer_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_subject_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_set_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_get_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_set_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_set_version.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_alias_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_alias_set1.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_keyid_get0.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_load_cert_crl_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_load_crl_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_to_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_chain_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_up_ref.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CERT_AUX_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_print_ex_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_sign.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REQ_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_sign_ctx.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_verify.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_signature_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_add1_attr_by_txt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_delete_attr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get0_data_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get_attr_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509at_get_attr_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_prefix.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_add_range.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_canonize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_is_canonical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_get_afi.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_inherits.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_subset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_addr_validate_resource_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_path.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_validate_resource_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_add_inherit.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_canonize.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_asid_is_canonical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_CRL_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_REVOKED_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_NID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_add_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_delete_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_OBJ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_by_critical.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509v3_get_ext_count.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_add_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_check_top.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_cmp_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_div_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_expand.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_expand2.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_fix_top.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_add_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_comba4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_comba8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_normal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_part_recursive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_recursive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_mul_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_set_high.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_set_low.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_set_max.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_comba4.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_comba8.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_normal.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_recursive.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_sqr_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_sub_words.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/bn_wexpand.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/mul.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/mul_add.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/sqr.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_NULL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_get0_data.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/OBJ_length.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OBJECT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BIT_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_BMPSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALIZEDTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_GENERALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_IA5STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_PRINTABLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_T61STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_TIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UINTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UNIVERSALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTCTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_UTF8STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_VISIBLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DIRECTORYSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DISPLAYTEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BIT_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_BMPSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALIZEDTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_GENERALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_IA5STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_PRINTABLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_T61STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_TIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UNIVERSALSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTCTIME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_UTF8STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_VISIBLESTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DIRECTORYSTRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DISPLAYTEXT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ASN1_SET_ANY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SEQUENCE_ANY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ASN1_SET_ANY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_KEYID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EXTENDED_KEY_USAGE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_BASIC_CONSTRAINTS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EXTENDED_KEY_USAGE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CMS_ReceiptRequest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CMS_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CMS_ContentInfo.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CMS_ReceiptRequest.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CMS_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DHparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ACCESS_DESCRIPTION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_AUTHORITY_INFO_ACCESS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CRL_DIST_POINTS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DIST_POINT_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ISSUING_DIST_POINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ACCESS_DESCRIPTION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_AUTHORITY_INFO_ACCESS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CRL_DIST_POINTS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DIST_POINT_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ISSUING_DIST_POINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DSAparams_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_DSAparams_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSA_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_DSAparams_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECPKParameters_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECPKParameters_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECParameters_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECParameters_print.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/ECParameters_print_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPKParameters_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ECPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EC_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPKParameters_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECParameters.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ECPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EC_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2o_ECPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/o2i_ECPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ESS_CERT_ID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_ESS_ISSUER_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ESS_CERT_ID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ESS_ISSUER_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_ESS_SIGNING_CERT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_EDIPARTYNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_GENERAL_NAMES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OTHERNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_EDIPARTYNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_GENERAL_NAMES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OTHERNAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_ONEREQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REQINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SERVICELOC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SIGNATURE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_ONEREQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REQUEST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SERVICELOC.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SIGNATURE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_BASICRESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CERTSTATUS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_CRLID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPBYTES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPDATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_RESPID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_REVOKEDINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_OCSP_SINGLERESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_BASICRESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CERTSTATUS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_CRLID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPBYTES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPDATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPID.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_RESPONSE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_REVOKEDINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_OCSP_SINGLERESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_BAGS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_MAC_DATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_SAFEBAG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS12_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_BAGS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_MAC_DATA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_SAFEBAG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS12_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_DIGEST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENCRYPT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENC_CONTENT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_ISSUER_AND_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_RECIP_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGNER_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_SIGN_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS7_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_DIGEST.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENCRYPT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENC_CONTENT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_ISSUER_AND_SERIAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_RECIP_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGNER_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_SIGN_ENVELOPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS7_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKey_nid_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_PRIV_KEY_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_PRIV_KEY_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKEY_USAGE_PERIOD.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_CERTIFICATEPOLICIES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_NOTICEREF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_POLICYQUALINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_USERNOTICE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_CERTIFICATEPOLICIES.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_NOTICEREF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_POLICYINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_POLICYQUALINFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_USERNOTICE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_AutoPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8PrivateKeyInfo_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_Netscape_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSAPublicKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PSS_PARAMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_RSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_Netscape_RSA.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPrivateKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSAPublicKey_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PSS_PARAMS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_RSA_PUBKEY_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_SSL_SESSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_ACCURACY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_MSG_IMPRINT_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_RESP_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_STATUS_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_TS_TST_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_ACCURACY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_MSG_IMPRINT_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_RESP_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_STATUS_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_TS_TST_INFO_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CERT_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CINF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_VAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CERT_AUX.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CINF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_VAL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_re_X509_CRL_tbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_re_X509_REQ_tbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_re_X509_tbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_ALGORS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGOR.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_ALGORS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_ATTRIBUTE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_CRL_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REVOKED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_CRL_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REVOKED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_EXTENSIONS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSION.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_EXTENSIONS.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_ENTRY_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_dup.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_get0_der.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/X509_NAME_set.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_NAME_ENTRY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_NAME_ENTRY.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_X509_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_INFO.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_REQ_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/d2i_PKCS8_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_PKCS8_fp.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2d_X509_SIG.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_get_pw_prompt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_read_pw_string_min.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/EVP_set_pw_prompt.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/a2i_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/a2i_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/a2i_ASN1_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2a_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2a_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/DECLARE_LHASH_OF.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_COMP_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_ARG_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_DOALL_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/LHASH_HASH_FN_TYPE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_delete.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_doall.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_doall_arg.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_insert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_retrieve.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_strhash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_stats.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_stats_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_node_usage_stats_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/lh_stats_bio.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_ENUMERATED_TABLE.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_INTEGER.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/i2s_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/s2i_ASN1_OCTET_STRING.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_accept_cbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_accept_fds.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_configure.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_reset.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_server.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_parse_protocols.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_client.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_prefer_ciphers_server.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_alpn.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ciphers.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_dheparams.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ecdhecurves.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_ticket_key.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_session_fd.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_session_lifetime.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifycert.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifyname.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_insecure_noverifytime.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_alpn_selected.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_cipher.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_cipher_strength.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_servername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_conn_session_resumed.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_chain_pem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_contains_name.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_hash.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_issuer.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notafter.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_notbefore.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_provided.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_cert_subject.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_cbs.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_fds.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_servername.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_connect_socket.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_add_keypair_ocsp_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_clear_keys.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ca_path.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_cert_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_crl_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_key_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_key_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_keypair_ocsp_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_ocsp_staple_mem.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_set_verify_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_verify_client.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_config_verify_client_optional.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_default_ca_cert_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_unload_file.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_cert_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_crl_reason.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_next_update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_response_status.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_result.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_revocation_time.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_this_update.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_peer_ocsp_url.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_close.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_error.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_handshake.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/tls_write.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_chain.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_error_string.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_free.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_new.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_intermediates.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_chains.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_depth.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_max_signatures.3" +@ENABLE_LIBTLS_ONLY_FALSE@ -rm -f "$(DESTDIR)$(mandir)/man3/x509_verify_ctx_set_purpose.3" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Libraries/libressl/man/NAME_CONSTRAINTS_new.3 b/Libraries/libressl/man/NAME_CONSTRAINTS_new.3 new file mode 100644 index 000000000..fec3aba7f --- /dev/null +++ b/Libraries/libressl/man/NAME_CONSTRAINTS_new.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: NAME_CONSTRAINTS_new.3,v 1.4 2020/09/17 08:50:05 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 17 2020 $ +.Dt NAME_CONSTRAINTS_NEW 3 +.Os +.Sh NAME +.Nm NAME_CONSTRAINTS_new , +.Nm NAME_CONSTRAINTS_free , +.Nm GENERAL_SUBTREE_new , +.Nm GENERAL_SUBTREE_free +.\" .Nm NAME_CONSTRAINTS_check is intentionally undocumented. +.\" beck@ said in the x509/x509_ncons.c rev. 1.4 commit message: +.\" We probably need to deprecate it thoughtfully. +.Nd X.509 CA name constraints extension +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft NAME_CONSTRAINTS * +.Fn NAME_CONSTRAINTS_new void +.Ft void +.Fn NAME_CONSTRAINTS_free "NAME_CONSTRAINTS *names" +.Ft GENERAL_SUBTREE * +.Fn GENERAL_SUBTREE_new void +.Ft void +.Fn GENERAL_SUBTREE_free "GENERAL_SUBTREE *name" +.Sh DESCRIPTION +X.509 CA certificates can use the name constraints extension +to restrict the subject names of subsequent certificates in a +certification path. +.Pp +.Fn NAME_CONSTRAINTS_new +allocates and initializes an empty +.Vt NAME_CONSTRAINTS +object, representing an ASN.1 +.Vt NameConstraints +structure defined in RFC 5280 section 4.2.1.10. +It consists of two +.Vt STACK_OF(GENERAL_SUBTREE) +objects, one specifying permitted names, the other excluded names. +.Fn NAME_CONSTRAINTS_free +frees +.Fa names . +.Pp +.Fn GENERAL_SUBTREE_new +allocates and initializes an empty +.Vt GENERAL_SUBTREE +object, representing an ASN.1 +.Vt GeneralSubtree +structure defined in RFC 5280 section 4.2.1.10. +It is a trivial wrapper around the +.Vt GENERAL_NAME +object documented in +.Xr GENERAL_NAME_new 3 . +The standard requires the other fields of +.Vt GENERAL_SUBTREE +to be ignored. +.Fn GENERAL_SUBTREE_free +frees +.Fa name . +.Sh RETURN VALUES +.Fn NAME_CONSTRAINTS_new +and +.Fn GENERAL_SUBTREE_new +return the new +.Vt NAME_CONSTRAINTS +or +.Vt GENERAL_SUBTREE +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr GENERAL_NAMES_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.2.1.10: Name Constraints +.Sh HISTORY +.Fn NAME_CONSTRAINTS_new , +.Fn NAME_CONSTRAINTS_free , +.Fn GENERAL_SUBTREE_new , +and +.Fn GENERAL_SUBTREE_free +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/OBJ_NAME_add.3 b/Libraries/libressl/man/OBJ_NAME_add.3 new file mode 100644 index 000000000..ad2ba8089 --- /dev/null +++ b/Libraries/libressl/man/OBJ_NAME_add.3 @@ -0,0 +1,346 @@ +.\" $OpenBSD: OBJ_NAME_add.3,v 1.5 2023/09/01 12:13:13 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 1 2023 $ +.Dt OBJ_NAME_ADD 3 +.Os +.Sh NAME +.Nm OBJ_NAME_add , +.Nm OBJ_NAME_remove , +.Nm OBJ_NAME_get , +.Nm OBJ_NAME_new_index , +.Nm OBJ_NAME_init , +.Nm OBJ_NAME_cleanup , +.Nm OBJ_NAME_do_all , +.Nm OBJ_NAME_do_all_sorted +.Nd global associative array +.Sh SYNOPSIS +.In openssl/objects.h +.Ft int +.Fo OBJ_NAME_add +.Fa "const char *name" +.Fa "int type" +.Fa "const char *value" +.Fc +.Ft int +.Fo OBJ_NAME_remove +.Fa "const char *name" +.Fa "int type" +.Fc +.Ft const char * +.Fo OBJ_NAME_get +.Fa "const char *name" +.Fa "int type" +.Fc +.Ft int +.Fo OBJ_NAME_new_index +.Fa "unsigned long (*hash_func)(const char *name)" +.Fa "int (*cmp_func)(const char *name1, const char *name2)" +.Fa "void (*free_func)(const char *name, int type, const char *value)" +.Fc +.Ft int +.Fn OBJ_NAME_init void +.Ft void +.Fn OBJ_NAME_cleanup "int type" +.Bd -literal +typedef struct { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; +.Ed +.Pp +.Ft void +.Fo OBJ_NAME_do_all +.Fa "int type" +.Fa "void (*fn)(const OBJ_NAME *pair, void *arg)" +.Fa "void *arg" +.Fc +.Ft void +.Fo OBJ_NAME_do_all_sorted +.Fa "int type" +.Fa "void (*fn)(const OBJ_NAME *pair, void *arg)" +.Fa "void *arg" +.Fc +.Sh DESCRIPTION +These functions implement a single, static associative array +with the following properties: +.Bl -bullet +.It +The keys are ordered pairs consisting of a NUL-terminated string +.Pq called the Fa name +and an +.Vt int +number +.Pq called the Fa type . +Two types are predefined and used internally by the library: +.Dv OBJ_NAME_TYPE_MD_METH +and +.Dv OBJ_NAME_TYPE_CIPHER_METH . +Two additional types are predefined but not used internally: +.Dv OBJ_NAME_TYPE_PKEY_METH +and +.Dv OBJ_NAME_TYPE_COMP_METH . +All predefined types are greater than +.Dv OBJ_NAME_TYPE_UNDEF +and smaller than +.Dv OBJ_NAME_TYPE_NUM . +.It +The values are pointers. +Formally, they are of the type +.Vt const char * , +but in practice, pointers of other types, for example +.Vt EVP_CIPHER * +or +.Vt EVP_MD * , +are often stored as values +and cast back to the correct type on retrieval. +.It +The array supports type-specific aliases for names. +.El +.Pp +.Fn OBJ_NAME_add +removes the key-value pair or alias with the key +.Pq Fa name , type +in the same way as +.Fn OBJ_NAME_remove +and inserts a key-value pair with the specified +.Fa name , +.Fa type , +and +.Fa value . +If the bit +.Dv OBJ_NAME_ALIAS +is set in the +.Fa type +argument, that bit is cleared before using the +.Fa type +and the key +.Pq Fa name , type +becomes an alias for the key +.Pq Fa value , type +instead of setting a value. +It is not checked whether the key +.Pq Fa value , type +already exists. +Consequently, it is possible to define an alias +before setting the associated value. +.Pp +.Fn OBJ_NAME_remove +removes the key-value pair or alias with the key +.Pq Fa name , type +from the array, if it exists. +Otherwise, it has no effect. +If the bit +.Dv OBJ_NAME_ALIAS +is set in the +.Fa type +argument, it is ignored and cleared before using the +.Fa type . +If the +.Fa type +is an application-defined type added with +.Fn OBJ_NAME_new_index +and the +.Fa free_func +associated with the +.Fa type +is not a +.Dv NULL +pointer, it is called with the +.Fa name , +.Fa type , +and +.Fa value +of the key-value pair being removed or with the +.Fa name , +.Fa type , +and alias target name of the alias being removed. +In typical usage, this function might free the +.Fa name , +and it might free the +.Fa value +in a type-specific way. +.Pp +.Fn OBJ_NAME_get +looks up the key +.Pq Fa name , type , +recursively resolving up to ten aliases if needed. +If the bit +.Dv OBJ_NAME_ALIAS +is set in the +.Fa type +argument, it is cleared before using the +.Fa type , +processing of aliases is disabled, and if +.Pq Fa name , type +is an alias, the target name of the alias is returned instead of a value. +.Pp +.Fn OBJ_NAME_new_index +assigns the smallest unassigned positive integer number +to represent a new, application-defined +.Fa type . +The three function pointers will be used, respectively, +to hash a name for this type, to compare two names for this type, +and to free the contents of a key-value pair holding the given +.Fa name , +.Fa type , +and +.Fa value . +If the +.Fa hash_func +argument is a +.Dv NULL +pointer, +.Xr lh_strhash 3 +is used instead. +If the +.Fa cmp_func +argument is a +.Dv NULL +pointer, +.Xr strcmp 3 +is used instead. +If the +.Fa free_func +argument is a +.Dv NULL +pointer, the +.Fa name +and +.Fa value +pointers contained in the key-value pair are not freed, +only the structure representing the pair itself is. +This default behaviour is also used for the built-in types. +.Pp +.Fn OBJ_NAME_init +initializes the array. +After initialization, the array is empty. +Calling +.Fn OBJ_NAME_init +when the array is already initialized has no effect. +Application programs do not need to call this function because +.Fn OBJ_NAME_add +and +.Fn OBJ_NAME_get +automatically call it whenever needed. +.Pp +.Fn OBJ_NAME_cleanup +removes all key-value pairs and aliases of the given +.Fa type +from the array by calling +.Fn OBJ_NAME_remove +on every such pair and alias. +If the +.Fa type +argument is negative, it removes all key-value pairs and aliases +of any type and also reverses all effects of +.Fn OBJ_NAME_new_index +and +.Fn OBJ_NAME_init , +in particular resetting the list of types to the predefined types +and releasing all memory reserved by these functions. +.Pp +The +.Vt OBJ_NAME +structure represents one key-value pair or one alias with the key +.Pq Fa name , type . +If the +.Fa alias +field is 0, the +.Fa data +field contains the value; otherwise, it contains the alias target name. +.Pp +.Fn OBJ_NAME_do_all +calls +.Fa fn +on every +.Fa pair +and alias in the array that has the given +.Fa type , +also passing the +.Fa arg +pointer. +.Fn OBJ_NAME_do_all_sorted +is similar except that it processes the pairs and aliases +in lexicographic order of their names as determined by +.Xr strcmp 3 , +ignoring any +.Fa cmp_func +that may be defined for the +.Fa type . +.Sh RETURN VALUES +.Fn OBJ_NAME_add +and +.Fn OBJ_NAME_init +return 1 on success or 0 if memory allocation fails. +.Pp +.Fn OBJ_NAME_remove +returns 1 if one key-value pair or alias was removed or 0 otherwise. +.Pp +.Fn OBJ_NAME_get +returns the +.Fa value +associated with the key +.Pq Fa name , type +or +.Dv NULL +if +.Fa name +is +.Dv NULL , +if the array does not contain a value for this key, +or if more than ten aliases are encountered before finding a value. +.Pp +.Fn OBJ_NAME_new_index +returns a positive integer greater than or equal to +.Dv OBJ_NAME_TYPE_NUM +representing the new type or 0 if memory allocation fails. +.Sh SEE ALSO +.Xr EVP_cleanup 3 , +.Xr EVP_get_cipherbyname 3 , +.Xr EVP_get_digestbyname 3 , +.Xr lh_new 3 , +.Xr OBJ_create 3 , +.Xr OBJ_nid2obj 3 +.Sh BUGS +Calling +.Fn OBJ_NAME_get +with the bit +.Dv OBJ_NAME_ALIAS +is not very useful because there is no way to tell +whether the returned pointer points to a value or to a name, +short of calling the function again without setting the bit +and comparing the two returned pointers. +.Pp +The +.Fa free_func +has no way to tell whether its +.Fa value +argument is indeed of the given +.Fa type +or whether it is merely the target name of an alias. +Consequently, to use values of a type +that requires more cleanup than merely calling +.Xr free 3 +on it, instances of the type need to begin with a magic number or string +that cannot occur at the beginning of a name. +.Pp +.Fn OBJ_NAME_do_all_sorted +is unable to report errors. +If memory allocations fails, it does nothing at all +without telling the caller about the problem. diff --git a/Libraries/libressl/man/OBJ_create.3 b/Libraries/libressl/man/OBJ_create.3 new file mode 100644 index 000000000..7a6135e05 --- /dev/null +++ b/Libraries/libressl/man/OBJ_create.3 @@ -0,0 +1,313 @@ +.\" $OpenBSD: OBJ_create.3,v 1.8 2023/09/06 12:26:59 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL OBJ_nid2obj.pod 9b86974e Aug 17 15:21:33 2015 -0400 +.\" selective merge up to: +.\" OpenSSL OBJ_nid2obj.pod 0c5bc96f Mar 15 13:57:22 2022 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017, 2021, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 6 2023 $ +.Dt OBJ_CREATE 3 +.Os +.Sh NAME +.Nm OBJ_new_nid , +.Nm OBJ_add_object , +.Nm OBJ_create , +.\" OBJ_create_and_add_object is a deprecated, unused alias for OBJ_create(3). +.Nm OBJ_create_objects , +.Nm obj_cleanup_defer , +.Nm OBJ_cleanup , +.Nm check_defer +.Nd modify the table of ASN.1 object identifiers +.Sh SYNOPSIS +.In openssl/objects.h +.Ft int +.Fn OBJ_new_nid "int increment" +.Ft int +.Fn OBJ_add_object "const ASN1_OBJECT *object" +.Ft int +.Fo OBJ_create +.Fa "const char *oid" +.Fa "const char *sn" +.Fa "const char *ln" +.Fc +.Ft int +.Fn OBJ_create_objects "BIO *in_bio" +.Vt extern int obj_cleanup_defer ; +.Ft void +.Fn OBJ_cleanup void +.Ft void +.Fn check_defer "int nid" +.Sh DESCRIPTION +.Fn OBJ_new_nid +returns the smallest currently unassigned ASN.1 numeric +object identifier (NID) and reserves +.Fa increment +consecutive NIDs starting with it. +Passing an argument of 1 is usually recommended. +The return value can be assigned to a new object by passing it as the +.Fa nid +argument to +.Xr ASN1_OBJECT_create 3 +and by passing the resulting object to +.Fn OBJ_add_object . +.Pp +.Fn OBJ_add_object +adds a copy of the +.Fa object +to the internal table of ASN.1 object identifiers for use by +.Xr OBJ_nid2obj 3 +and related functions. +.Pp +.Fn OBJ_create +provides a simpler way to add a new object to the internal table. +.Fa oid +is the numerical form of the object, +.Fa sn +the short name and +.Fa ln +the long name. +A new NID is automatically assigned using +.Fn OBJ_new_nid . +.Pp +.Fn OBJ_create_objects +reads text lines of the form +.Pp +.D1 Fa oid sn ln +.Pp +from +.Fa in_bio +and calls +.Fn OBJ_create oid sn ln +for every line read. +The three fields of the input lines +are separated by one or more whitespace characters. +.Pp +For all three functions, the objects added to the internal table and +all the data contained in them is marked as not dynamically allocated. +Consequently, retrieving them with +.Xr OBJ_nid2obj 3 +or a similar function and then calling +.Xr ASN1_OBJECT_free 3 +on the returned pointer will have no effect. +.Pp +The global variable +.Va obj_cleanup_defer +controls the behaviour of +.Fn OBJ_cleanup +and +.Xr EVP_cleanup 3 . +.Pp +If +.Va obj_cleanup_defer +has the default value of 0, +.Fn OBJ_cleanup +resets the internal object table to its default state, +removing and freeing all objects that were added with +.Fn OBJ_add_object , +.Fn OBJ_create , +or +.Fn OBJ_create_objects . +Otherwise, +.Fn OBJ_cleanup +only sets +.Va obj_cleanup_defer +to 2, which defers the cleanup of the internal object table +to the next call of +.Xr EVP_cleanup 3 . +.Pp +By default, +.Xr EVP_cleanup 3 +has no effect on the internal object table. +Only if +.Va obj_cleanup_defer +is 2, it resets +.Va obj_cleanup_defer +to 0 and calls +.Fn OBJ_cleanup , +which then resets the table to its default state. +.Pp +The function +.Fn check_defer +sets +.Va obj_cleanup_defer +to 1 unless +.Fa nid +is a built-in numeric identifier, but it has no effect if +.Va obj_cleanup_defer +already differs from 0. +This function is called internally by various functions +in the EVP library, in particular by subroutines of +.Xr OpenSSL_add_all_ciphers 3 +and +.Xr OpenSSL_add_all_digests 3 . +.Pp +To reliably reset the internal object table no matter what the +current state may be, an application program needs to call both +.Fn OBJ_cleanup +and +.Xr EVP_cleanup 3 , +in this order. +The opposite order will usually not work. +.Sh RETURN VALUES +.Fn OBJ_new_nid +returns the new NID. +.Pp +.Fn OBJ_add_object +returns the NID of the added +.Fa object +or +.Dv NID_undef +if no object was added because the +.Fa object +argument was +.Dv NULL , +did not contain an NID, or memory allocation failed. +.Pp +.Fn OBJ_create +returns the new NID or +.Dv NID_undef +if +.Fa oid +is not a valid representation of an object identifier +or if memory allocation fails. +.Pp +.Fn OBJ_create_objects +returns the number of objects added. +.Pp +In some cases of failure of +.Fn OBJ_add_object , +.Fn OBJ_create , +and +.Fn OBJ_create_objects , +the reason can be determined with +.Xr ERR_get_error 3 . +.Sh EXAMPLES +Create a new NID and initialize an object from it: +.Bd -literal -offset indent +int new_nid; +ASN1_OBJECT *obj; + +new_nid = OBJ_create("1.2.3.4", "NewOID", "New Object Identifier"); +obj = OBJ_nid2obj(new_nid); +.Ed +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr EVP_cleanup 3 , +.Xr OBJ_NAME_add 3 , +.Xr OBJ_nid2obj 3 +.Sh HISTORY +.Fn OBJ_new_nid , +.Fn OBJ_add_object , +and +.Fn OBJ_cleanup +first appeared in SSLeay 0.8.0 and +.Fn OBJ_create +in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Va obj_cleanup_defer +and +.Fn check_defer +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Sh CAVEATS +.Fn OBJ_add_object +indicates success even after adding an incomplete object that was created with +.Xr ASN1_OBJECT_create 3 +but lacks a short name, a long name, or an OID. +.Pp +Even +.Fn OBJ_create +tolerates +.Dv NULL +pointers being passed for the +.Fa sn +and/or +.Fa ln +arguments, in which case +.Xr OBJ_nid2sn 3 +and +.Xr OBJ_sn2nid 3 +or +.Xr OBJ_nid2ln 3 +and +.Xr OBJ_ln2nid 3 +will not work on the added object, respectively. +.Sh BUGS +.Fn OBJ_new_nid +does not reserve any return value to indicate an error. +Consequently, to avoid conflicting NID assignments and integer overflows, +care must be taken to not pass negative, zero, or large arguments to +.Fn OBJ_new_nid . +.Pp +.Fn OBJ_create_objects +does not distinguish between end of file, I/O errors, temporary +unavailability of data on a non-blocking BIO, invalid input syntax, +and memory allocation failure. +In all these cases, reading is aborted and the number of objects +that were already added is returned. diff --git a/Libraries/libressl/man/OBJ_find_sigid_algs.3 b/Libraries/libressl/man/OBJ_find_sigid_algs.3 new file mode 100644 index 000000000..9aeb54c90 --- /dev/null +++ b/Libraries/libressl/man/OBJ_find_sigid_algs.3 @@ -0,0 +1,90 @@ +.\" $OpenBSD: OBJ_find_sigid_algs.3,v 1.1 2023/07/22 06:35:26 tb Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 22 2023 $ +.Dt OBJ_FIND_SIGID_ALGS 3 +.Os +.Sh NAME +.Nm OBJ_find_sigid_algs , +.Nm OBJ_find_sigid_by_algs +.Nd signature algorithm mappings +.Sh SYNOPSIS +.In openssl/objects.h +.Ft int +.Fo OBJ_find_sigid_algs +.Fa "int signature" +.Fa "int *pdigest" +.Fa "int *pencryption" +.Fc +.Ft int +.Fo OBJ_find_sigid_by_algs +.Fa "int *psignature" +.Fa "int digest" +.Fa "int encryption" +.Fc +.Sh DESCRIPTION +.Fn OBJ_find_sigid_algs +looks up the +.Fa signature +algorithm. +If it is found, the associated digest algorithm is stored in +.Pf * Fa pdigest +unless +.Fa pdigest +is a +.Dv NULL +pointer, and the associated encryption algorithm is stored in +.Pf * Fa pencryption +unless +.Fa pencryption +is a +.Dv NULL +pointer. +.Pp +.Fn OBJ_find_sigid_by_algs +looks up the pair +.Pq Fa digest , encryption . +If it is found, the associated signature algorithm is stored in +.Pf * Fa psignature +unless +.Fa psignature +is a +.Dv NULL +pointer. +.Sh RETURN VALUES +.Fn OBJ_find_sigid_algs +returns 1 if a definition of the +.Fa signature +algorithm is found or 0 if a definition of the +.Fa signature +algorithm is not built into the library. +.Pp +.Fn OBJ_find_sigid_by_algs +returns 1 if a signature algorithm using the specified +.Fa digest +and +.Fa encryption +algorithms is defined or 0 if the definition of such an algorithm +is not built into the library. +.Sh SEE ALSO +.Xr EVP_cleanup 3 , +.Xr OBJ_create 3 , +.Xr OBJ_NAME_add 3 , +.Xr OBJ_nid2obj 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/OBJ_nid2obj.3 b/Libraries/libressl/man/OBJ_nid2obj.3 new file mode 100644 index 000000000..4e420b831 --- /dev/null +++ b/Libraries/libressl/man/OBJ_nid2obj.3 @@ -0,0 +1,522 @@ +.\" $OpenBSD: OBJ_nid2obj.3,v 1.21 2023/09/05 13:50:22 schwarze Exp $ +.\" full merge up to: OpenSSL c264592d May 14 11:28:00 2006 +0000 +.\" selective merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017, 2021, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 5 2023 $ +.Dt OBJ_NID2OBJ 3 +.Os +.Sh NAME +.Nm OBJ_nid2obj , +.Nm OBJ_nid2ln , +.Nm OBJ_nid2sn , +.Nm OBJ_obj2nid , +.Nm OBJ_ln2nid , +.Nm OBJ_sn2nid , +.Nm OBJ_txt2nid , +.Nm OBJ_txt2obj , +.Nm OBJ_obj2txt , +.Nm OBJ_cmp , +.Nm OBJ_dup , +.Nm i2t_ASN1_OBJECT , +.Nm i2a_ASN1_OBJECT +.Nd inspect and create ASN.1 object identifiers +.Sh SYNOPSIS +.In openssl/objects.h +.Ft ASN1_OBJECT * +.Fo OBJ_nid2obj +.Fa "int nid" +.Fc +.Ft const char * +.Fo OBJ_nid2ln +.Fa "int nid" +.Fc +.Ft const char * +.Fo OBJ_nid2sn +.Fa "int nid" +.Fc +.Ft int +.Fo OBJ_obj2nid +.Fa "const ASN1_OBJECT *object" +.Fc +.Ft int +.Fo OBJ_ln2nid +.Fa "const char *ln" +.Fc +.Ft int +.Fo OBJ_sn2nid +.Fa "const char *sn" +.Fc +.Ft int +.Fo OBJ_txt2nid +.Fa "const char *s" +.Fc +.Ft ASN1_OBJECT * +.Fo OBJ_txt2obj +.Fa "const char *s" +.Fa "int no_name" +.Fc +.Ft int +.Fo OBJ_obj2txt +.Fa "char *buf" +.Fa "int buf_len" +.Fa "const ASN1_OBJECT *object" +.Fa "int no_name" +.Fc +.Ft int +.Fo OBJ_cmp +.Fa "const ASN1_OBJECT *a" +.Fa "const ASN1_OBJECT *b" +.Fc +.Ft ASN1_OBJECT * +.Fo OBJ_dup +.Fa "const ASN1_OBJECT *object" +.Fc +.In openssl/asn1.h +.Ft int +.Fo i2t_ASN1_OBJECT +.Fa "char *buf" +.Fa "int buf_len" +.Fa "const ASN1_OBJECT *object" +.Fc +.Ft int +.Fo i2a_ASN1_OBJECT +.Fa "BIO *out_bio" +.Fa "const ASN1_OBJECT *object" +.Fc +.Sh DESCRIPTION +The ASN.1 object utility functions process +.Vt ASN1_OBJECT +structures, in the following called +.Dq objects . +An object represents an ASN.1 +.Vt OBJECT IDENTIFIER +.Pq OID . +The library maintains an internal global table of objects. +Many of these objects are built into the library +and contained in the global table by default. +The application program can add additional objects to the global table +by using functions documented in the +.Xr OBJ_create 3 +manual page. +Consequently, there are three classes of objects: +built-in table objects, user-defined table objects, and non-table objects. +.Pp +In addition to the OID, each object can hold +a long name, a short name, and a numerical identifier (NID). +Even though the concept of NIDs is specific to the library +and not standardized, using the NID is often the most convenient way +for source code to refer to a specific OID. +The NIDs of the built-in objects are available as defined constants. +.Pp +Built-in table objects have certain advantages +over objects that are not in the global table: +for example, their NIDs can be used in C language switch statements. +They are also shared: +there is only a single static constant structure for each built-on OID. +.Pp +Some functions operate on table objects only: +.Pp +.Fn OBJ_nid2obj +retrieves the table object associated with the +.Fa nid . +.Fn OBJ_nid2ln +and +.Fn OBJ_nid2sn +retrieve its long and short name, respectively. +.Pp +.Fn OBJ_obj2nid +retrieves the NID associated with the given +.Fa object , +which is either the NID stored in the +.Fa object +itself, if any, or otherwise the NID stored in a table object +containing the same OID. +.Pp +.Fn OBJ_ln2nid +and +.Fn OBJ_sn2nid +retrieve the NID from the table object with the long name +.Fa ln +or the short name +.Fa sn , +respectively. +.Pp +.Fn OBJ_txt2nid +retrieves the NID from the table object described by the text string +.Fa s , +which can be a long name, a short name, +or the numerical representation of an OID. +.Pp +The remaining functions can be used both on table objects +and on objects that are not in the global table: +.Pp +.Fn OBJ_txt2obj +retrieves or creates an object matching the text string +.Fa s . +If +.Fa no_name +is 1, only the numerical representation of an OID is accepted. +If +.Fa no_name +is 0, long names and short names are accepted as well. +.Pp +.Fn OBJ_obj2txt +writes a NUL terminated textual representation +of the OID contained in the given +.Fa object +into +.Fa buf . +At most +.Fa buf_len +bytes are written, truncating the result if necessary. +The total amount of space required is returned. +If +.Fa no_name +is 0 and the table object containing the same OID +contains a long name, the long name is written. +Otherwise, if +.Fa no_name +is 0 and the table object containing the same OID +contains a short name, the short name is written. +Otherwise, the numerical representation of the OID is written. +.Pp +.Fn i2t_ASN1_OBJECT +is the same as +.Fn OBJ_obj2txt +with +.Fa no_name +set to 0. +.Pp +.Fn i2a_ASN1_OBJECT +writes a textual representation of the OID contained in the given +.Fa object +to +.Fa out_bio +using +.Xr BIO_write 3 . +It does not write a terminating NUL byte. +If the +.Fa object +argument is +.Dv NULL +or contains no OID, it writes the 4-byte string +.Qq NULL . +If +.Fn i2t_ASN1_OBJECT +fails, +.Fn i2a_ASN1_OBJECT +writes the 9-byte string +.Qq . +Otherwise, it writes the string constructed with +.Fn i2t_ASN1_OBJECT . +.Pp +.Fn OBJ_cmp +tests whether +.Fa a +and +.Fa b +represent the same ASN.1 +.Vt OBJECT IDENTIFIER . +Any names and NIDs contained in the two objects are ignored, +even if they differ between both objects. +.Pp +.Fn OBJ_dup +returns a deep copy of the given +.Fa object +if it is marked as dynamically allocated. +The new object and all data contained in it are marked as dynamically +allocated. +If the given +.Fa object +is not marked as dynamically allocated, +.Fn OBJ_dup +just returns a pointer to the +.Fa object +itself. +.Sh RETURN VALUES +Application code should treat all returned values \(em +objects, names, and NIDs \(em as constants. +.Pp +.Fn OBJ_nid2obj +returns a pointer to a table object owned by the library or +.Dv NULL +if no matching table object is found. +.Pp +.Fn OBJ_nid2ln +and +.Fn OBJ_nid2sn +return a pointer to a string owned by a table object or +.Dv NULL +if no matching table object is found. +For +.Dv NID_undef , +they return the constant static strings +.Qq undefined +and +.Qq UNDEF , +respectively. +.Pp +.Fn OBJ_obj2nid +returns an NID on success, or +.Dv NID_undef +if +.Fa object +is +.Dv NULL , +does not contain an OID, +if no table object matching the OID is found, +or if the matching object does not contain an NID. +.Pp +.Fn OBJ_ln2nid +and +.Fn OBJ_sn2nid +return an NID on success or +.Dv NID_undef +if no matching table object is found +or if the matching object does not contain an NID. +.Pp +.Fn OBJ_txt2nid +returns an NID on success or +.Dv NID_undef +if parsing of +.Fa s +or memory allocation fails, if no matching table object is found, +or if the matching object does not contain an NID. +.Pp +.Fn OBJ_txt2obj +returns a pointer to a table object owned by the library if lookup of +.Fa s +as a long or short name succeeds. +Otherwise, it returns a newly created object, +transferring ownership to the caller, or +.Dv NULL +if parsing of +.Fa s +or memory allocation fails. +.Pp +.Fn OBJ_obj2txt +and +.Fn i2t_ASN1_OBJECT +return the amount of space required in bytes, +including the terminating NUL byte, +or zero if an error occurs before the required space can be calculated, +in particular if +.Fa buf_len +is negative, +.Fa object +is +.Dv NULL +or does not contain an OID, +or if memory allocation fails. +.Pp +.Fn OBJ_cmp +returns 0 if both objects refer to the same OID +or neither of them are associated with any OID, +or a non-zero value if at least one of them refers to an OID +but the other one does not refer to the same OID. +.Pp +.Fn OBJ_dup +returns the pointer to the original +.Fa object +if it is not marked as dynamically allocated. +Otherwise, it returns a newly created object, +transferring ownership to the caller, or +.Dv NULL +if +.Fa object +is +.Dv NULL +or memory allocation fails. +.Pp +.Fn i2a_ASN1_OBJECT +returns the number of bytes written, even if the given +.Fa object +is invalid or contains invalid data, +but a negative value if memory allocation or a write operation fails. +.Pp +In some cases of failure of +.Fn OBJ_nid2obj , +.Fn OBJ_nid2ln , +.Fn OBJ_nid2sn , +.Fn OBJ_txt2nid , +.Fn OBJ_txt2obj , +.Fn OBJ_obj2txt , +.Fn OBJ_dup , +.Fn i2t_ASN1_OBJECT , +and +.Fn i2a_ASN1_OBJECT , +the reason can be determined with +.Xr ERR_get_error 3 . +.Sh EXAMPLES +Retrieve the object for +.Sy commonName : +.Bd -literal -offset indent +ASN1_OBJECT *object; +object = OBJ_nid2obj(NID_commonName); +.Ed +.Pp +Check whether an object contains the OID for +.Sy commonName : +.Bd -literal -offset indent +if (OBJ_obj2nid(object) == NID_commonName) + /* Do something */ +.Ed +.Pp +Create a new object directly: +.Bd -literal -offset indent +object = OBJ_txt2obj("1.2.3.4", 1); +.Ed +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr BIO_new 3 , +.Xr d2i_ASN1_OBJECT 3 , +.Xr OBJ_create 3 , +.Xr OBJ_NAME_add 3 +.Sh HISTORY +.Fn OBJ_nid2obj , +.Fn OBJ_nid2ln , +.Fn OBJ_nid2sn , +.Fn OBJ_obj2nid , +.Fn OBJ_ln2nid , +.Fn OBJ_sn2nid , +.Fn OBJ_txt2nid , +.Fn OBJ_cmp , +and +.Fn OBJ_dup +first appeared in SSLeay 0.5.1. +.Fn i2a_ASN1_OBJECT +first appeared in SSLeay 0.6.0, and +.Fn i2t_ASN1_OBJECT +in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn OBJ_txt2obj +first appeared in OpenSSL 0.9.2b. +.Fn OBJ_obj2txt +first appeared in OpenSSL 0.9.4. +Both functions have been available since +.Ox 2.6 . +.Sh CAVEATS +The API contract of +.Fn OBJ_txt2obj +when called with a +.Fa no_name +argument of 0 and of +.Fn OBJ_dup +is scary in so far as the caller cannot find out from the returned +object whether it is owned by the library or whether ownership was +transferred to the caller. +Consequently, it is best practice to assume that ownership of the object +may have been transferred and call +.Xr ASN1_OBJECT_free 3 +on the returned object when the caller no longer needs it. +In case the library retained ownership of the returned object, +.Xr ASN1_OBJECT_free 3 +has no effect and is harmless. +.Pp +Objects returned from +.Fn OBJ_txt2obj +with a +.Fa no_name +argument of 1 always require +.Xr ASN1_OBJECT_free 3 +to prevent memory leaks. +.Pp +Objects returned from +.Fn OBJ_nid2obj +never require +.Xr ASN1_OBJECT_free 3 , +but calling it anyway has no effect and is harmless. +.Sh BUGS +Usually, an object is expected to contain an NID other than +.Dv NID_undef +if and only if it is a table object. +However, this is not an invariant guaranteed by the API. +In particular, +.Xr ASN1_OBJECT_create 3 +allows the creation of non-table objects containing bogus NIDs. +.Fn OBJ_obj2nid +returns such bogus NIDs even though +.Fn OBJ_nid2obj +cannot use them for retrieval. +On top of that, the global table contains one built-in object with an NID of +.Dv NID_undef . +.Pp +.Fn OBJ_obj2txt +is awkward and messy to use: it doesn't follow the convention of other +OpenSSL functions where the buffer can be set to +.Dv NULL +to determine the amount of data that should be written. +Instead +.Fa buf +must point to a valid buffer and +.Fa buf_len +should be set to a positive value. +A buffer length of 80 should be more than enough to handle any OID +encountered in practice. diff --git a/Libraries/libressl/man/OCSP_CRLID_new.3 b/Libraries/libressl/man/OCSP_CRLID_new.3 new file mode 100644 index 000000000..6feb60865 --- /dev/null +++ b/Libraries/libressl/man/OCSP_CRLID_new.3 @@ -0,0 +1,113 @@ +.\" $OpenBSD: OCSP_CRLID_new.3,v 1.8 2022/01/15 23:38:50 jsg Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt OCSP_CRLID_NEW 3 +.Os +.Sh NAME +.Nm OCSP_CRLID_new , +.Nm OCSP_CRLID_free , +.Nm OCSP_crlID_new +.Nd OCSP CRL extension +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_CRLID * +.Fn OCSP_CRLID_new void +.Ft void +.Fn OCSP_CRLID_free "OCSP_CRLID *crlid" +.Ft X509_EXTENSION * +.Fo OCSP_crlID_new +.Fa "const char *url" +.Fa "long *number" +.Fa "char *time" +.Fc +.Sh DESCRIPTION +If a client asks about the validity of a certificate and it turns +out to be invalid, the responder may optionally communicate which +certificate revocation list the certificate was found on. +The required data is stored as an ASN.1 +.Vt CrlID +structure in the singleExtensions field of the +.Vt SingleResponse +structure. +The +.Vt CrlID +is represented by an +.Vt OCSP_CRLID +object, which will be stored inside the +.Vt OCSP_SINGLERESP +object documented in +.Xr OCSP_SINGLERESP_new 3 . +.Pp +.Fn OCSP_CRLID_new +allocates and initializes an empty +.Vt OCSP_CRLID +object. +.Fn OCSP_CRLID_free +frees +.Fa crlid . +.Pp +.Fn OCSP_crlID_new +accepts the +.Fa url +at which the CRL is available, the CRL +.Fa number , +and/or the +.Fa time +at which the CRL was created. +Each argument can be +.Dv NULL , +in which case the respective field is omitted. +The resulting +.Vt CrlID +structure is encoded in ASN.1 using +.Xr X509V3_EXT_i2d 3 +with criticality 0. +.Sh RETURN VALUES +.Fn OCSP_CRLID_new +returns a new +.Vt OCSP_CRLID +object or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_crlID_new +returns a new +.Vt X509_EXTENSION +object or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_resp_find_status 3 , +.Xr OCSP_response_status 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.4.2: CRL References +.Sh HISTORY +.Fn OCSP_CRLID_new , +.Fn OCSP_CRLID_free , +and +.Fn OCSP_crlID_new +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Sh CAVEATS +The function names +.Fn OCSP_CRLID_new +and +.Fn OCSP_crlID_new +only differ in case. diff --git a/Libraries/libressl/man/OCSP_REQUEST_new.3 b/Libraries/libressl/man/OCSP_REQUEST_new.3 new file mode 100644 index 000000000..a304f6016 --- /dev/null +++ b/Libraries/libressl/man/OCSP_REQUEST_new.3 @@ -0,0 +1,329 @@ +.\" $OpenBSD: OCSP_REQUEST_new.3,v 1.12 2022/02/19 13:09:36 jsg Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2014, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: February 19 2022 $ +.Dt OCSP_REQUEST_NEW 3 +.Os +.Sh NAME +.Nm OCSP_REQUEST_new , +.Nm OCSP_REQUEST_free , +.Nm OCSP_SIGNATURE_new , +.Nm OCSP_SIGNATURE_free , +.Nm OCSP_REQINFO_new , +.Nm OCSP_REQINFO_free , +.Nm OCSP_ONEREQ_new , +.Nm OCSP_ONEREQ_free , +.Nm OCSP_request_add0_id , +.Nm OCSP_request_sign , +.Nm OCSP_request_add1_cert , +.Nm OCSP_request_onereq_count , +.Nm OCSP_request_onereq_get0 +.Nd OCSP request functions +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_REQUEST * +.Fn OCSP_REQUEST_new void +.Ft void +.Fn OCSP_REQUEST_free "OCSP_REQUEST *req" +.Ft OCSP_SIGNATURE * +.Fn OCSP_SIGNATURE_new void +.Ft void +.Fn OCSP_SIGNATURE_free "OCSP_SIGNATURE *signature" +.Ft OCSP_REQINFO * +.Fn OCSP_REQINFO_new void +.Ft void +.Fn OCSP_REQINFO_free "OCSP_REQINFO *reqinfo" +.Ft OCSP_ONEREQ * +.Fn OCSP_ONEREQ_new void +.Ft void +.Fn OCSP_ONEREQ_free "OCSP_ONEREQ *onereq" +.Ft OCSP_ONEREQ * +.Fo OCSP_request_add0_id +.Fa "OCSP_REQUEST *req" +.Fa "OCSP_CERTID *cid" +.Fc +.Ft int +.Fo OCSP_request_sign +.Fa "OCSP_REQUEST *req" +.Fa "X509 *signer" +.Fa "EVP_PKEY *key" +.Fa "const EVP_MD *dgst" +.Fa "STACK_OF(X509) *certs" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo OCSP_request_add1_cert +.Fa "OCSP_REQUEST *req" +.Fa "X509 *cert" +.Fc +.Ft int +.Fo OCSP_request_onereq_count +.Fa "OCSP_REQUEST *req" +.Fc +.Ft OCSP_ONEREQ * +.Fo OCSP_request_onereq_get0 +.Fa "OCSP_REQUEST *req" +.Fa "int i" +.Fc +.Sh DESCRIPTION +.Fn OCSP_REQUEST_new +allocates and initializes an empty +.Vt OCSP_REQUEST +object, representing an ASN.1 +.Vt OCSPRequest +structure defined in RFC 6960. +.Fn OCSP_REQUEST_free +frees +.Fa req . +.Pp +.Fn OCSP_SIGNATURE_new +allocates and initializes an empty +.Vt OCSP_SIGNATURE +object, representing an ASN.1 +.Vt Signature +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_REQUEST . +.Fn OCSP_SIGNATURE_free +frees +.Fa signature . +.Pp +.Fn OCSP_REQINFO_new +allocates and initializes an empty +.Vt OCSP_REQINFO +object, representing an ASN.1 +.Vt TBSRequest +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_REQUEST . +It asks about the validity of one or more certificates. +.Fn OCSP_REQINFO_free +frees +.Fa reqinfo . +.Pp +.Fn OCSP_ONEREQ_new +allocates and initializes an empty +.Vt OCSP_ONEREQ +object, representing an ASN.1 +.Vt Request +structure defined in RFC 6960. +Such objects are used inside +.Vt OCSP_REQINFO . +Each one asks about the validity of one certificate. +.Fn OCSP_ONEREQ_free +frees +.Fa onereq . +.Pp +.Fn OCSP_request_add0_id +adds certificate ID +.Fa cid +to +.Fa req . +It returns the +.Vt OCSP_ONEREQ +object added so an application can add additional extensions to the +request. +The +.Fa cid +parameter must not be freed up after the operation. +.Pp +.Fn OCSP_request_sign +signs OCSP request +.Fa req +using certificate +.Fa signer , +private key +.Fa key , +digest +.Fa dgst , +and additional certificates +.Fa certs . +If the +.Fa flags +option +.Dv OCSP_NOCERTS +is set, then no certificates will be included in the request. +.Pp +.Fn OCSP_request_add1_cert +adds certificate +.Fa cert +to request +.Fa req . +The application is responsible for freeing up +.Fa cert +after use. +.Pp +.Fn OCSP_request_onereq_count +returns the total number of +.Vt OCSP_ONEREQ +objects in +.Fa req . +.Pp +.Fn OCSP_request_onereq_get0 +returns an internal pointer to the +.Vt OCSP_ONEREQ +contained in +.Fa req +of index +.Fa i . +The index value +.Fa i +runs from 0 to +.Fn OCSP_request_onereq_count req No - 1 . +.Pp +.Fn OCSP_request_onereq_count +and +.Fn OCSP_request_onereq_get0 +are mainly used by OCSP responders. +.Sh RETURN VALUES +.Fn OCSP_REQUEST_new , +.Fn OCSP_SIGNATURE_new , +.Fn OCSP_REQINFO_new , +and +.Fn OCSP_ONEREQ_new +return an empty +.Vt OCSP_REQUEST , +.Vt OCSP_SIGNATURE , +.Vt OCSP_REQINFO , +or +.Vt OCSP_ONEREQ +object, respectively, or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_request_add0_id +returns the +.Vt OCSP_ONEREQ +object containing +.Fa cid +or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_request_sign +and +.Fn OCSP_request_add1_cert +return 1 for success or 0 for failure. +.Pp +.Fn OCSP_request_onereq_count +returns the total number of +.Vt OCSP_ONEREQ +objects in +.Fa req . +.Pp +.Fn OCSP_request_onereq_get0 +returns a pointer to an +.Vt OCSP_ONEREQ +object or +.Dv NULL +if the index value is out of range. +.Sh EXAMPLES +Create an +.Vt OCSP_REQUEST +object for certificate +.Fa cert +with issuer +.Fa issuer : +.Bd -literal -offset indent +OCSP_REQUEST *req; +OCSP_ID *cid; + +req = OCSP_REQUEST_new(); +if (req == NULL) + /* error */ +cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer); +if (cid == NULL) + /* error */ + +if (OCSP_REQUEST_add0_id(req, cid) == NULL) + /* error */ + + /* Do something with req, e.g. query responder */ + +OCSP_REQUEST_free(req); +.Ed +.Sh SEE ALSO +.Xr ACCESS_DESCRIPTION_new 3 , +.Xr crypto 3 , +.Xr d2i_OCSP_REQUEST 3 , +.Xr d2i_OCSP_RESPONSE 3 , +.Xr EVP_DigestInit 3 , +.Xr OCSP_cert_to_id 3 , +.Xr OCSP_CRLID_new 3 , +.Xr OCSP_request_add1_nonce 3 , +.Xr OCSP_resp_find_status 3 , +.Xr OCSP_response_status 3 , +.Xr OCSP_sendreq_new 3 , +.Xr OCSP_SERVICELOC_new 3 , +.Xr X509_ocspid_print 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.1: Request Syntax +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OCSP_SERVICELOC_new.3 b/Libraries/libressl/man/OCSP_SERVICELOC_new.3 new file mode 100644 index 000000000..62eb8c320 --- /dev/null +++ b/Libraries/libressl/man/OCSP_SERVICELOC_new.3 @@ -0,0 +1,109 @@ +.\" $OpenBSD: OCSP_SERVICELOC_new.3,v 1.8 2019/08/23 12:23:39 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 23 2019 $ +.Dt OCSP_SERVICELOC_NEW 3 +.Os +.Sh NAME +.Nm OCSP_SERVICELOC_new , +.Nm OCSP_SERVICELOC_free , +.Nm OCSP_url_svcloc_new +.Nd OCSP service locator extension +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_SERVICELOC * +.Fn OCSP_SERVICELOC_new void +.Ft void +.Fn OCSP_SERVICELOC_free "OCSP_SERVICELOC *sloc" +.Ft X509_EXTENSION * +.Fo OCSP_url_svcloc_new +.Fa "X509_NAME *issuer" +.Fa "const char **urls" +.Fc +.Sh DESCRIPTION +Due to restrictions of network routing, a client may be unable to +directly contact the authoritative OCSP server for a certificate +that needs to be checked. +In that case, the request can be sent via a proxy server. +An ASN.1 +.Vt ServiceLocator +structure is included in the singleRequestExtensions field of the +.Vt Request +structure to indicate where to forward the request. +The +.Vt ServiceLocator +is represented by a +.Vt OCSP_SERVICELOC +object, which will be stored inside the +.Vt OCSP_ONEREQ +object documented in +.Xr OCSP_ONEREQ_new 3 . +.Pp +.Fn OCSP_SERVICELOC_new +allocates and initializes an empty +.Vt OCSP_SERVICELOC +object. +.Fn OCSP_SERVICELOC_free +frees +.Fa sloc . +.Pp +.Fn OCSP_url_svcloc_new +requires an +.Fa issuer +name and optionally accepts an array of +.Fa urls . +If +.Fa urls +or its first element is +.Dv NULL , +the locator field is omitted from the +.Vt ServiceLocator +structure and only the issuer is included. +The resulting +.Vt ServiceLocator +structure is encoded in ASN.1 using +.Xr X509V3_EXT_i2d 3 +with criticality 0. +.Sh RETURN VALUES +.Fn OCSP_SERVICELOC_new +returns a new +.Vt OCSP_SERVICELOC +object or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_url_svcloc_new +returns a new +.Vt X509_EXTENSION +object or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr OCSP_REQUEST_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get1_ocsp 3 , +.Xr X509_get_issuer_name 3 , +.Xr X509_NAME_new 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.4.6: Service Locator +.Sh HISTORY +.Fn OCSP_SERVICELOC_new , +.Fn OCSP_SERVICELOC_free , +and +.Fn OCSP_url_svcloc_new +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OCSP_cert_to_id.3 b/Libraries/libressl/man/OCSP_cert_to_id.3 new file mode 100644 index 000000000..73a21867b --- /dev/null +++ b/Libraries/libressl/man/OCSP_cert_to_id.3 @@ -0,0 +1,232 @@ +.\" $OpenBSD: OCSP_cert_to_id.3,v 1.12 2022/03/31 17:27:17 naddy Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2014, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt OCSP_CERT_TO_ID 3 +.Os +.Sh NAME +.Nm OCSP_CERTID_new , +.Nm OCSP_CERTID_free , +.Nm OCSP_cert_to_id , +.Nm OCSP_cert_id_new , +.Nm OCSP_id_issuer_cmp , +.Nm OCSP_id_cmp , +.Nm OCSP_id_get0_info +.Nd OCSP certificate ID utility functions +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_CERTID * +.Fn OCSP_CERTID_new void +.Ft void +.Fn OCSP_CERTID_free "OCSP_CERTID *id" +.Ft OCSP_CERTID * +.Fo OCSP_cert_to_id +.Fa "const EVP_MD *dgst" +.Fa "const X509 *subject" +.Fa "const X509 *issuer" +.Fc +.Ft OCSP_CERTID * +.Fo OCSP_cert_id_new +.Fa "const EVP_MD *dgst" +.Fa "const X509_NAME *issuerName" +.Fa "const ASN1_BIT_STRING *issuerKey" +.Fa "const ASN1_INTEGER *serialNumber" +.Fc +.Ft int +.Fo OCSP_id_issuer_cmp +.Fa "OCSP_CERTID *a" +.Fa "OCSP_CERTID *b" +.Fc +.Ft int +.Fo OCSP_id_cmp +.Fa "OCSP_CERTID *a" +.Fa "OCSP_CERTID *b" +.Fc +.Ft int +.Fo OCSP_id_get0_info +.Fa "ASN1_OCTET_STRING **piNameHash" +.Fa "ASN1_OBJECT **pmd" +.Fa "ASN1_OCTET_STRING **pikeyHash" +.Fa "ASN1_INTEGER **pserial" +.Fa "OCSP_CERTID *cid" +.Fc +.Sh DESCRIPTION +.Fn OCSP_CERTID_new +allocates and initializes an empty +.Vt OCSP_CERTID +object, representing an ASN.1 +.Vt CertID +structure defined in RFC 6960. +It can store hashes of an issuer's distinguished name and public +key together with a serial number of a certificate. +It is used by the +.Vt OCSP_ONEREQ +object described in +.Xr OCSP_ONEREQ_new 3 +and by the +.Vt OCSP_SINGLERESP +object described in +.Xr OCSP_SINGLERESP_new 3 . +.Fn OCSP_CERTID_free +frees +.Fa id . +.Pp +.Fn OCSP_cert_to_id +creates and returns a new +.Vt OCSP_CERTID +object using message digest +.Fa dgst +for certificate +.Fa subject +with issuer +.Fa issuer . +If +.Fa dgst +is +.Dv NULL +then SHA1 is used. +.Pp +.Fn OCSP_cert_id_new +creates and returns a new +.Vt OCSP_CERTID +using +.Fa dgst +and issuer name +.Fa issuerName , +issuer key hash +.Fa issuerKey +and serial number +.Fa serialNumber . +.Pp +.Fn OCSP_id_cmp +compares +.Vt OCSP_CERTID +.Fa a +and +.Fa b . +.Pp +.Fn OCSP_id_issuer_cmp +compares only the issuer name of +.Vt OCSP_CERTID +.Fa a +and +.Fa b . +.Pp +.Fn OCSP_id_get0_info +returns the issuer name hash, hash OID, issuer key hash and serial +number contained in +.Fa cid . +If any of the values are not required, the corresponding parameter can be +set to +.Dv NULL . +The values returned by +.Fn OCSP_id_get0_info +are internal pointers and must not be freed up by an application: +they will be freed when the corresponding +.Vt OCSP_CERTID +object is freed. +.Pp +OCSP clients will typically only use +.Fn OCSP_cert_to_id +or +.Fn OCSP_cert_id_new : +the other functions are used by responder applications. +.Sh RETURN VALUES +.Fn OCSP_CERTID_new , +.Fn OCSP_cert_to_id , +and +.Fn OCSP_cert_id_new +return either a pointer to a valid +.Vt OCSP_CERTID +object or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_id_cmp +and +.Fn OCSP_id_issuer_cmp +return 0 for a match or non-zero otherwise. +.Pp +.Fn OCSP_id_get0_info +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr OCSP_request_add1_nonce 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_resp_find_status 3 , +.Xr OCSP_response_status 3 , +.Xr OCSP_sendreq_new 3 , +.Xr X509_get_issuer_name 3 , +.Xr X509_NAME_new 3 , +.Xr X509_ocspid_print 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4: Details of the Protocol +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OCSP_request_add1_nonce.3 b/Libraries/libressl/man/OCSP_request_add1_nonce.3 new file mode 100644 index 000000000..036c937c6 --- /dev/null +++ b/Libraries/libressl/man/OCSP_request_add1_nonce.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: OCSP_request_add1_nonce.3,v 1.4 2018/03/22 21:08:22 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2014, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt OCSP_REQUEST_ADD1_NONCE 3 +.Os +.Sh NAME +.Nm OCSP_request_add1_nonce , +.Nm OCSP_basic_add1_nonce , +.Nm OCSP_check_nonce , +.Nm OCSP_copy_nonce +.Nd OCSP nonce functions +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft int +.Fo OCSP_request_add1_nonce +.Fa "OCSP_REQUEST *req" +.Fa "unsigned char *val" +.Fa "int len" +.Fc +.Ft int +.Fo OCSP_basic_add1_nonce +.Fa "OCSP_BASICRESP *resp" +.Fa "unsigned char *val" +.Fa "int len" +.Fc +.Ft int +.Fo OCSP_check_nonce +.Fa "OCSP_REQUEST *req" +.Fa "OCSP_BASICRESP *resp" +.Fc +.Ft int +.Fo OCSP_copy_nonce +.Fa "OCSP_BASICRESP *resp" +.Fa "OCSP_REQUEST *req" +.Fc +.Sh DESCRIPTION +An OCSP nonce is typically added to an OCSP request to thwart replay +attacks by checking the same nonce value appears in the response. +.Pp +.Fn OCSP_request_add1_nonce +adds a nonce of value +.Fa val +and length +.Fa len +to OCSP request +.Fa req . +If +.Fa val +is +.Dv NULL , +a random nonce is used. +If +.Fa len +is zero or negative, a default length will be used (currently 16 bytes). +For most purposes the nonce value in a request is set to a random value +so the +.Fa val +parameter in +.Fn OCSP_request_add1_nonce +is usually NULL. +.Pp +.Fn OCSP_basic_add1_nonce +is identical to +.Fn OCSP_request_add1_nonce +except it adds a nonce to OCSP basic response +.Fa resp . +.Pp +.Fn OCSP_check_nonce +compares the nonce value in +.Fa req +and +.Fa resp . +.Pp +.Fn OCSP_copy_nonce +copies any nonce value present in +.Fa req +to +.Fa resp . +.Pp +Some responders may include a nonce in all responses even if one is not +supplied. +.Pp +Some responders cache OCSP responses and do not sign each response for +performance reasons. +As a result they do not support nonces. +.Sh RETURN VALUES +.Fn OCSP_request_add1_nonce +and +.Fn OCSP_basic_add1_nonce +return 1 for success or 0 for failure. +.Pp +.Fn OCSP_copy_nonce +returns 1 if a nonce was successfully copied, 2 if no nonce was +present in +.Fa req , +or 0 if an error occurred. +.Pp +.Fn OCSP_check_nonce +returns positive values for success: 1 if nonces are present and +equal, 2 if both nonces are absent, or 3 if a nonce is present in +the response only. +A zero return value indicates that both nonces are present but +mismatch: this should be treated as an error condition. +A return value of -1 indicates that a nonce is present in the request +only: this will happen if the responder doesn't support nonces. +.Sh SEE ALSO +.Xr OCSP_cert_to_id 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_resp_find_status 3 , +.Xr OCSP_response_status 3 , +.Xr OCSP_sendreq_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OCSP_resp_find_status.3 b/Libraries/libressl/man/OCSP_resp_find_status.3 new file mode 100644 index 000000000..06d0354bd --- /dev/null +++ b/Libraries/libressl/man/OCSP_resp_find_status.3 @@ -0,0 +1,494 @@ +.\" $OpenBSD: OCSP_resp_find_status.3,v 1.11 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: OpenSSL c952780c Jun 21 07:03:34 2016 -0400 +.\" selective merge up to: OpenSSL 1212818e Sep 11 13:22:14 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2018, 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and David von Oheimb . +.\" Copyright (c) 2014, 2018 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt OCSP_RESP_FIND_STATUS 3 +.Os +.Sh NAME +.Nm OCSP_SINGLERESP_new , +.Nm OCSP_SINGLERESP_free , +.Nm OCSP_CERTSTATUS_new , +.Nm OCSP_CERTSTATUS_free , +.Nm OCSP_REVOKEDINFO_new , +.Nm OCSP_REVOKEDINFO_free , +.Nm OCSP_resp_find_status , +.Nm OCSP_cert_status_str , +.Nm OCSP_resp_count , +.Nm OCSP_resp_get0 , +.Nm OCSP_resp_find , +.Nm OCSP_SINGLERESP_get0_id , +.Nm OCSP_single_get0_status , +.Nm OCSP_check_validity , +.Nm OCSP_basic_verify +.Nd OCSP response utility functions +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_SINGLERESP * +.Fn OCSP_SINGLERESP_new void +.Ft void +.Fn OCSP_SINGLERESP_free "OCSP_SINGLERESP *single" +.Ft OCSP_CERTSTATUS * +.Fn OCSP_CERTSTATUS_new void +.Ft void +.Fn OCSP_CERTSTATUS_free "OCSP_CERTSTATUS *certstatus" +.Ft OCSP_REVOKEDINFO * +.Fn OCSP_REVOKEDINFO_new void +.Ft void +.Fn OCSP_REVOKEDINFO_free "OCSP_REVOKEDINFO *revokedinfo" +.Ft int +.Fo OCSP_resp_find_status +.Fa "OCSP_BASICRESP *bs" +.Fa "OCSP_CERTID *id" +.Fa "int *status" +.Fa "int *reason" +.Fa "ASN1_GENERALIZEDTIME **revtime" +.Fa "ASN1_GENERALIZEDTIME **thisupd" +.Fa "ASN1_GENERALIZEDTIME **nextupd" +.Fc +.Ft const char * +.Fo OCSP_cert_status_str +.Fa "long status" +.Fc +.Ft int +.Fo OCSP_resp_count +.Fa "OCSP_BASICRESP *bs" +.Fc +.Ft OCSP_SINGLERESP * +.Fo OCSP_resp_get0 +.Fa "OCSP_BASICRESP *bs" +.Fa "int idx" +.Fc +.Ft int +.Fo OCSP_resp_find +.Fa "OCSP_BASICRESP *bs" +.Fa "OCSP_CERTID *id" +.Fa "int last" +.Fc +.Ft const OCSP_CERTID * +.Fo OCSP_SINGLERESP_get0_id +.Fa "const OCSP_SINGLERESP *single" +.Fc +.Ft int +.Fo OCSP_single_get0_status +.Fa "OCSP_SINGLERESP *single" +.Fa "int *reason" +.Fa "ASN1_GENERALIZEDTIME **revtime" +.Fa "ASN1_GENERALIZEDTIME **thisupd" +.Fa "ASN1_GENERALIZEDTIME **nextupd" +.Fc +.Ft int +.Fo OCSP_check_validity +.Fa "ASN1_GENERALIZEDTIME *thisupd" +.Fa "ASN1_GENERALIZEDTIME *nextupd" +.Fa "long sec" +.Fa "long maxsec" +.Fc +.Ft int +.Fo OCSP_basic_verify +.Fa "OCSP_BASICRESP *bs" +.Fa "STACK_OF(X509) *certs" +.Fa "X509_STORE *st" +.Fa "unsigned long flags" +.Fc +.Sh DESCRIPTION +.Fn OCSP_SINGLERESP_new +allocates and initializes an empty +.Vt OCSP_SINGLERESP +object, representing an ASN.1 +.Vt SingleResponse +structure defined in RFC 6960. +Each such object can store the server's answer regarding the validity +of one individual certificate. +Such objects are used inside the +.Vt OCSP_RESPDATA +of +.Vt OCSP_BASICRESP +objects, which are described in +.Xr OCSP_BASICRESP_new 3 . +.Fn OCSP_SINGLERESP_free +frees +.Fa single . +.Pp +.Fn OCSP_CERTSTATUS_new +allocates and initializes an empty +.Vt OCSP_CERTSTATUS +object, representing an ASN.1 +.Vt CertStatus +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_SINGLERESP . +.Fn OCSP_CERTSTATUS_free +frees +.Fa certstatus . +.Pp +.Fn OCSP_REVOKEDINFO_new +allocates and initializes an empty +.Vt OCSP_REVOKEDINFO +object, representing an ASN.1 +.Vt RevokedInfo +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_CERTSTATUS . +.Fn OCSP_REVOKEDINFO_free +frees +.Fa revokedinfo . +.Pp +.Fn OCSP_resp_find_status +searches +.Fa bs +for an OCSP response for +.Fa id . +If it is successful, the fields of the response are returned in +.Pf * Fa status , +.Pf * Fa reason , +.Pf * Fa revtime , +.Pf * Fa thisupd +and +.Pf * Fa nextupd . +The +.Pf * Fa status +value will be one of +.Dv V_OCSP_CERTSTATUS_GOOD , +.Dv V_OCSP_CERTSTATUS_REVOKED , +or +.Dv V_OCSP_CERTSTATUS_UNKNOWN . +The +.Pf * Fa reason +and +.Pf * Fa revtime +fields are only set if the status is +.Dv V_OCSP_CERTSTATUS_REVOKED . +If set, the +.Pf * Fa reason +field will be set to the revocation reason which will be one of +.Dv OCSP_REVOKED_STATUS_NOSTATUS , +.Dv OCSP_REVOKED_STATUS_UNSPECIFIED , +.Dv OCSP_REVOKED_STATUS_KEYCOMPROMISE , +.Dv OCSP_REVOKED_STATUS_CACOMPROMISE , +.Dv OCSP_REVOKED_STATUS_AFFILIATIONCHANGED , +.Dv OCSP_REVOKED_STATUS_SUPERSEDED , +.Dv OCSP_REVOKED_STATUS_CESSATIONOFOPERATION , +.Dv OCSP_REVOKED_STATUS_CERTIFICATEHOLD +or +.Dv OCSP_REVOKED_STATUS_REMOVEFROMCRL . +.Pp +.Fn OCSP_cert_status_str +converts one of the +.Fa status +codes retrieved by +.Fn OCSP_resp_find_status +to a string consisting of one word. +.Pp +.Fn OCSP_resp_count +returns the number of +.Vt OCSP_SINGLERESP +structures in +.Fa bs . +.Pp +.Fn OCSP_resp_get0 +returns the +.Vt OCSP_SINGLERESP +structure in +.Fa bs +corresponding to index +.Fa idx , +where +.Fa idx +runs from 0 to +.Fn OCSP_resp_count bs No - 1 . +.Pp +.Fn OCSP_resp_find +searches +.Fa bs +for +.Fa id +and returns the index of the first matching entry after +.Fa last +or starting from the beginning if +.Fa last +is -1. +.Pp +.Fn OCSP_single_get0_status +extracts the fields of +.Fa single +in +.Pf * Fa reason , +.Pf * Fa revtime , +.Pf * Fa thisupd , +and +.Pf * Fa nextupd . +.Pp +.Fn OCSP_check_validity +checks the validity of +.Fa thisupd +and +.Fa nextupd +values which will be typically obtained from +.Fn OCSP_resp_find_status +or +.Fn OCSP_single_get0_status . +If +.Fa sec +is non-zero, it indicates how many seconds leeway should be allowed in +the check. +If +.Fa maxsec +is positive, it indicates the maximum age of +.Fa thisupd +in seconds. +.Pp +Applications will typically call +.Fn OCSP_resp_find_status +using the certificate ID of interest and then check its validity using +.Fn OCSP_check_validity . +They can then take appropriate action based on the status of the +certificate. +.Pp +An OCSP response for a certificate contains +.Sy thisUpdate +and +.Sy nextUpdate +fields. +Normally the current time should be between these two values. +To account for clock skew, the +.Fa maxsec +field can be set to non-zero in +.Fn OCSP_check_validity . +Some responders do not set the +.Sy nextUpdate +field. +This would otherwise mean an ancient response would be considered +valid: the +.Fa maxsec +parameter to +.Fn OCSP_check_validity +can be used to limit the permitted age of responses. +.Pp +The values written to +.Pf * Fa revtime , +.Pf * Fa thisupd , +and +.Pf * Fa nextupd +by +.Fn OCSP_resp_find_status +and +.Fn OCSP_single_get0_status +are internal pointers which must not be freed up by the calling +application. +Any or all of these parameters can be set to +.Dv NULL +if their value is not required. +.Pp +.Fn OCSP_basic_verify +checks that the basic response message +.Fa bs +is correctly signed and that the signer certificate can be validated. +It takes +.Fa st +as the trusted store and +.Fa certs +as a set of untrusted intermediate certificates. +The function first tries to find the signer certificate of the response in +.Fa certs . +It also searches the certificates the responder may have included in +.Fa bs +unless the +.Fa flags +contain +.Dv OCSP_NOINTERN . +It fails if the signer certificate cannot be found. +Next, the function checks the signature of +.Fa bs +and fails on error unless the +.Fa flags +contain +.Dv OCSP_NOSIGS . +Then the function already returns +success if the +.Fa flags +contain +.Dv OCSP_NOVERIFY +or if the signer certificate was found in +.Fa certs +and the +.Fa flags +contain +.Dv OCSP_TRUSTOTHER . +Otherwise the function continues by validating the signer certificate. +To this end, all certificates in +.Fa certs +and in +.Fa bs +are considered as untrusted certificates for the construction of +the validation path for the signer certificate unless the +.Dv OCSP_NOCHAIN +flag is set. +After successful path +validation, the function returns success if the +.Dv OCSP_NOCHECKS +flag is set. +Otherwise it verifies that the signer certificate meets the OCSP issuer +criteria including potential delegation. +If this does not succeed and the +.Fa flags +do not contain +.Dv OCSP_NOEXPLICIT , +the function checks for explicit trust for OCSP signing +in the root CA certificate. +.Sh RETURN VALUES +.Fn OCSP_SINGLERESP_new , +.Fn OCSP_CERTSTATUS_new , +and +.Fn OCSP_REVOKEDINFO_new +return a pointer to an empty +.Vt OCSP_SINGLERESP , +.Vt OCSP_CERTSTATUS , +or +.Vt OCSP_REVOKEDINFO +object, respectively, or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_resp_find_status +returns 1 if +.Fa id +is found in +.Fa bs +or 0 otherwise. +.Pp +.Fn OCSP_cert_status_str +returns a pointer to a static string. +.Pp +.Fn OCSP_resp_count +returns the total number of +.Vt OCSP_SINGLERESP +fields in +.Fa bs . +.Pp +.Fn OCSP_resp_get0 +returns a pointer to an +.Vt OCSP_SINGLERESP +structure or +.Dv NULL +if +.Fa idx +is out of range. +.Pp +.Fn OCSP_resp_find +returns the index of +.Fa id +in +.Fa bs +(which may be 0) or -1 if +.Fa id +was not found. +.Pp +.Fn OCSP_SINGLERESP_get0_id +returns an internal pointer to the certificate ID object used by +.Fa single ; +the returned pointer should not be freed by the caller. +.Pp +.Fn OCSP_single_get0_status +returns the status of +.Fa single +or -1 if an error occurred. +.Pp +.Fn OCSP_basic_verify +returns 1 on success, 0 on error, or -1 on fatal error such as malloc failure. +.Sh SEE ALSO +.Xr OCSP_cert_to_id 3 , +.Xr OCSP_CRLID_new 3 , +.Xr OCSP_request_add1_nonce 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_response_status 3 , +.Xr OCSP_sendreq_new 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.2: Response Syntax +.Sh HISTORY +.Fn OCSP_SINGLERESP_new , +.Fn OCSP_SINGLERESP_free , +.Fn OCSP_CERTSTATUS_new , +.Fn OCSP_CERTSTATUS_free , +.Fn OCSP_REVOKEDINFO_new , +.Fn OCSP_REVOKEDINFO_free , +.Fn OCSP_resp_find_status , +.Fn OCSP_cert_status_str , +.Fn OCSP_resp_count , +.Fn OCSP_resp_get0 , +.Fn OCSP_resp_find , +.Fn OCSP_single_get0_status , +and +.Fn OCSP_check_validity +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn OCSP_SINGLERESP_get0_id +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/OCSP_response_status.3 b/Libraries/libressl/man/OCSP_response_status.3 new file mode 100644 index 000000000..4e85384fb --- /dev/null +++ b/Libraries/libressl/man/OCSP_response_status.3 @@ -0,0 +1,308 @@ +.\" $OpenBSD: OCSP_response_status.3,v 1.8 2019/08/27 09:40:29 schwarze Exp $ +.\" full merge up to: OpenSSL bb9ad09e Jun 6 00:43:05 2016 -0400 +.\" selective merge up to: OpenSSL 6738bf14 Feb 13 12:51:29 2018 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2014, 2016, 2018 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 27 2019 $ +.Dt OCSP_RESPONSE_STATUS 3 +.Os +.Sh NAME +.Nm OCSP_RESPONSE_new , +.Nm OCSP_RESPONSE_free , +.Nm OCSP_RESPBYTES_new , +.Nm OCSP_RESPBYTES_free , +.Nm OCSP_BASICRESP_new , +.Nm OCSP_BASICRESP_free , +.Nm OCSP_RESPDATA_new , +.Nm OCSP_RESPDATA_free , +.Nm OCSP_RESPID_new , +.Nm OCSP_RESPID_free , +.Nm OCSP_response_create , +.Nm OCSP_response_status , +.Nm OCSP_response_status_str , +.Nm OCSP_response_get1_basic , +.Nm OCSP_basic_sign +.Nd OCSP response functions +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_RESPONSE * +.Fn OCSP_RESPONSE_new void +.Ft void +.Fn OCSP_RESPONSE_free "OCSP_RESPONSE *resp" +.Ft OCSP_RESPBYTES * +.Fn OCSP_RESPBYTES_new void +.Ft void +.Fn OCSP_RESPBYTES_free "OCSP_RESPBYTES *respbytes" +.Ft OCSP_BASICRESP * +.Fn OCSP_BASICRESP_new void +.Ft void +.Fn OCSP_BASICRESP_free "OCSP_BASICRESP *bs" +.Ft OCSP_RESPDATA * +.Fn OCSP_RESPDATA_new void +.Ft void +.Fn OCSP_RESPDATA_free "OCSP_RESPDATA *respdata" +.Ft OCSP_RESPID * +.Fn OCSP_RESPID_new void +.Ft void +.Fn OCSP_RESPID_free "OCSP_RESPID *respid" +.Ft OCSP_RESPONSE * +.Fo OCSP_response_create +.Fa "int status" +.Fa "OCSP_BASICRESP *bs" +.Fc +.Ft int +.Fo OCSP_response_status +.Fa "OCSP_RESPONSE *resp" +.Fc +.Ft const char * +.Fo OCSP_response_status_str +.Fa "long code" +.Fc +.Ft OCSP_BASICRESP * +.Fo OCSP_response_get1_basic +.Fa "OCSP_RESPONSE *resp" +.Fc +.Ft int +.Fo OCSP_basic_sign +.Fa "OCSP_BASICRESP *bs" +.Fa "X509 *signer" +.Fa "EVP_PKEY *key" +.Fa "const EVP_MD *dgst" +.Fa "STACK_OF(X509) *certs" +.Fa "unsigned long flags" +.Fc +.Sh DESCRIPTION +.Fn OCSP_RESPONSE_new +allocates and initializes an empty +.Vt OCSP_RESPONSE +object, representing an ASN.1 +.Vt OCSPResponse +structure defined in RFC 6960. +.Fn OCSP_RESPONSE_free +frees +.Fa resp . +.Pp +.Fn OCSP_RESPBYTES_new +allocates and initializes an empty +.Vt OCSP_RESPBYTES +object, representing an ASN.1 +.Vt ResponseBytes +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_RESPONSE . +.Fn OCSP_RESPBYTES_free +frees +.Fa respbytes . +.Pp +.Fn OCSP_BASICRESP_new +allocates and initializes an empty +.Vt OCSP_BASICRESP +object, representing an ASN.1 +.Vt BasicOCSPResponse +structure defined in RFC 6960. +.Vt OCSP_RESPBYTES +contains the DER-encoded form of an +.Vt OCSP_BASICRESP +object. +.Fn OCSP_BASICRESP_free +frees +.Fa bs . +.Pp +.Fn OCSP_RESPDATA_new +allocates and initializes an empty +.Vt OCSP_RESPDATA +object, representing an ASN.1 +.Vt ResponseData +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_BASICRESP . +.Fn OCSP_RESPDATA_free +frees +.Fa respdata . +.Pp +.Fn OCSP_RESPID_new +allocates and initializes an empty +.Vt OCSP_RESPID +object, representing an ASN.1 +.Vt ResponderID +structure defined in RFC 6960. +Such an object is used inside +.Vt OCSP_RESPDATA . +.Fn OCSP_RESPID_free +frees +.Fa respid . +.Pp +.Fn OCSP_response_create +creates an +.Vt OCSP_RESPONSE +object for +.Fa status +and optionally including the basic response +.Fa bs . +.Pp +.Fn OCSP_response_status +returns the OCSP response status of +.Fa resp . +It returns one of the values +.Dv OCSP_RESPONSE_STATUS_SUCCESSFUL , +.Dv OCSP_RESPONSE_STATUS_MALFORMEDREQUEST , +.Dv OCSP_RESPONSE_STATUS_INTERNALERROR , +.Dv OCSP_RESPONSE_STATUS_TRYLATER , +.Dv OCSP_RESPONSE_STATUS_SIGREQUIRED , +or +.Dv OCSP_RESPONSE_STATUS_UNAUTHORIZED . +.Pp +.Fn OCSP_response_status_str +converts one of the +.Fa status +codes returned by +.Fn OCSP_response_status +to a string consisting of one word. +.Pp +.Fn OCSP_response_get1_basic +decodes and returns the +.Vt OCSP_BASICRESP +object contained in +.Fa resp . +It is only called if the status of a response is +.Dv OCSP_RESPONSE_STATUS_SUCCESSFUL . +.Pp +.Fn OCSP_basic_sign +signs the OCSP response +.Fa bs +using the certificate +.Fa signer , +the private key +.Fa key , +the digest +.Fa dgst , +and the additional certificates +.Fa certs . +If the +.Fa flags +option +.Dv OCSP_NOCERTS +is set, then no certificates will be included in the request. +If the +.Fa flags +option +.Dv OCSP_RESPID_KEY +is set, then the responder is identified by key ID +rather than by name. +.Sh RETURN VALUES +.Fn OCSP_RESPONSE_new +and +.Fn OCSP_response_create +return a pointer to an +.Vt OCSP_RESPONSE +object or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_BASICRESP_new +and +.Fn OCSP_response_get1_basic +return a pointer to an +.Vt OCSP_BASICRESP +object or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_RESPBYTES_new , +.Fn OCSP_RESPDATA_new , +and +.Fn OCSP_RESPID_new +return a pointer to an empty +.Vt OCSP_RESPBYTES , +.Vt OCSP_RESPDATA , +or +.Vt OCSP_RESPID +object, respectively, or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_response_status +returns a status value. +.Pp +.Fn OCSP_response_status_str +returns a pointer to a static string. +.Pp +.Fn OCSP_basic_sign +return 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr OCSP_cert_to_id 3 , +.Xr OCSP_request_add1_nonce 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_resp_find_status 3 , +.Xr OCSP_sendreq_new 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.2: Response Syntax +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OCSP_sendreq_new.3 b/Libraries/libressl/man/OCSP_sendreq_new.3 new file mode 100644 index 000000000..300f71952 --- /dev/null +++ b/Libraries/libressl/man/OCSP_sendreq_new.3 @@ -0,0 +1,323 @@ +.\" $OpenBSD: OCSP_sendreq_new.3,v 1.10 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2014, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt OCSP_SENDREQ_NEW 3 +.Os +.Sh NAME +.Nm OCSP_sendreq_new , +.Nm OCSP_sendreq_nbio , +.Nm OCSP_REQ_CTX_free , +.Nm OCSP_REQ_CTX_add1_header , +.Nm OCSP_REQ_CTX_set1_req , +.Nm OCSP_parse_url , +.Nm OCSP_sendreq_bio +.Nd OCSP responder query functions +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_REQ_CTX * +.Fo OCSP_sendreq_new +.Fa "BIO *io" +.Fa "const char *path" +.Fa "OCSP_REQUEST *req" +.Fa "int maxline" +.Fc +.Ft int +.Fo OCSP_sendreq_nbio +.Fa "OCSP_RESPONSE **presp" +.Fa "OCSP_REQ_CTX *rctx" +.Fc +.Ft void +.Fo OCSP_REQ_CTX_free +.Fa "OCSP_REQ_CTX *rctx" +.Fc +.Ft int +.Fo OCSP_REQ_CTX_add1_header +.Fa "OCSP_REQ_CTX *rctx" +.Fa "const char *name" +.Fa "const char *value" +.Fc +.Ft int +.Fo OCSP_REQ_CTX_set1_req +.Fa "OCSP_REQ_CTX *rctx" +.Fa "OCSP_REQUEST *req" +.Fc +.Ft int +.Fo OCSP_parse_url +.Fa "const char *url" +.Fa "char **phost" +.Fa "char **pport" +.Fa "char **ppath" +.Fa "int *pssl" +.Fc +.Ft OCSP_RESPONSE * +.Fo OCSP_sendreq_bio +.Fa "BIO *io" +.Fa "const char *path" +.Fa "OCSP_REQUEST *req" +.Fc +.Sh DESCRIPTION +The function +.Fn OCSP_sendreq_new +returns an +.Vt OCSP_REQ_CTX +structure using the responder +.Fa io , +the URI path +.Fa path , +the OCSP request +.Fa req +and with a response header maximum line length of +.Fa maxline . +If +.Fa maxline +is zero, a default value of 4k is used. +The OCSP request +.Fa req +may be set to +.Dv NULL +and provided later if required. +.Pp +The arguments to +.Fn OCSP_sendreq_new +correspond to the components of the URI. +For example, if the responder URI is +.Pa http://ocsp.com/ocspreq , +the BIO +.Fa io +should be connected to host +.Pa ocsp.com +on port 80 and +.Fa path +should be set to +.Qq /ocspreq . +.Pp +.Fn OCSP_sendreq_nbio +performs non-blocking I/O on the OCSP request context +.Fa rctx . +When the operation is complete, it returns the response in +.Pf * Fa presp . +If +.Fn OCSP_sendreq_nbio +indicates an operation should be retried, the corresponding BIO can +be examined to determine which operation (read or write) should be +retried and appropriate action can be taken, for example a +.Xr select 2 +call on the underlying socket. +.Pp +.Fn OCSP_REQ_CTX_free +frees up the OCSP context +.Fa rctx . +.Pp +.Fn OCSP_REQ_CTX_add1_header +adds header +.Fa name +with value +.Fa value +to the context +.Fa rctx . +The added headers are of the form +.Qq Fa name : value +or just +.Qq Fa name +if +.Fa value +is +.Dv NULL . +.Fn OCSP_REQ_CTX_add1_header +can be called more than once to add multiple headers. +It must be called before any calls to +.Fn OCSP_sendreq_nbio . +The +.Fa req +parameter in the initial to +.Fn OCSP_sendreq_new +call must be set to +.Dv NULL +if additional headers are set. +.Pp +.Fn OCSP_REQ_CTX_set1_req +sets the OCSP request in +.Fa rctx +to +.Fa req . +This function should be called after any calls to +.Fn OCSP_REQ_CTX_add1_header . +.Pp +.Fn OCSP_parse_url +is a utility function to parse a +.Fa url +of the form +.Sm off +.Sy http Op Sy s +.Pf :// Ar host +.Op : Ar port +.Op / Ar path +.Sm on +and store pointers to newly allocated copies of the strings +.Ar host , +.Ar port , +and +.Ar path +in +.Pf * phost , +.Pf * pport , +and +.Pf * ppath , +respectively. +By default, +.Pf * ppath +is set to +.Qq / +and +.Pf * pport +to +.Qq 443 +for +.Sy https +or +.Qq 80 +for +.Sy http . +For +.Sy https , +.Pf * Fa pssl +is set to 1; otherwise, to 0. +.Pp +.Fn OCSP_sendreq_bio +performs an OCSP request using the responder +.Fa io , +the URI path +.Fa path , +the OCSP request +.Fa req . +It does not support retries and so cannot handle non-blocking I/O +efficiently. +It is retained for compatibility and its use in new applications +is not recommended. +.Sh RETURN VALUES +.Fn OCSP_sendreq_new +returns a valid +.Vt OCSP_REQ_CTX +structure or +.Dv NULL +if an error occurred. +.Pp +.Fn OCSP_sendreq_nbio +returns 1 if the operation was completed successfully, +-1 if the operation should be retried, +or 0 if an error occurred. +.Pp +.Fn OCSP_REQ_CTX_add1_header , +.Fn OCSP_REQ_CTX_set1_req , +and +.Fn OCSP_parse_url +return 1 for success or 0 for failure. +.Pp +.Fn OCSP_sendreq_bio +returns the +.Vt OCSP_RESPONSE +structure sent by the responder or +.Dv NULL +if an error occurred. +.Sh EXAMPLES +Add a Host header for +.Pa ocsp.com : +.Pp +.Dl OCSP_REQ_CTX_add1_header(ctx, "Host", "ocsp.com"); +.Sh SEE ALSO +.Xr OCSP_cert_to_id 3 , +.Xr OCSP_request_add1_nonce 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_resp_find_status 3 , +.Xr OCSP_response_status 3 , +.Xr X509_get1_ocsp 3 +.Sh HISTORY +.Fn OCSP_parse_url +and +.Fn OCSP_sendreq_bio +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn OCSP_sendreq_new , +.Fn OCSP_sendreq_nbio , +and +.Fn OCSP_REQ_CTX_free +first appeared in OpenSSL 0.9.8h and have been available since +.Ox 4.5 . +.Pp +.Fn OCSP_REQ_CTX_add1_header +and +.Fn OCSP_REQ_CTX_set1_req +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Sh CAVEATS +These functions only perform a minimal HTTP query to a responder. +If an application wishes to support more advanced features, it +should use an alternative, more complete, HTTP library. +.Pp +Currently only HTTP POST queries to responders are supported. diff --git a/Libraries/libressl/man/OPENSSL_VERSION_NUMBER.3 b/Libraries/libressl/man/OPENSSL_VERSION_NUMBER.3 new file mode 100644 index 000000000..06ca55848 --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_VERSION_NUMBER.3 @@ -0,0 +1,281 @@ +.\" $OpenBSD: OPENSSL_VERSION_NUMBER.3,v 1.12 2019/06/06 01:06:58 schwarze Exp $ +.\" full merge up to: OpenSSL 1f13ad31 Dec 25 17:50:39 2017 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017, 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller , +.\" Richard Levitte , and +.\" Bodo Moeller . +.\" Copyright (c) 2000, 2002, 2015, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt OPENSSL_VERSION_NUMBER 3 +.Os +.Sh NAME +.Nm OPENSSL_VERSION_NUMBER , +.Nm LIBRESSL_VERSION_NUMBER , +.Nm LIBRESSL_VERSION_TEXT , +.Nm OPENSSL_VERSION_TEXT , +.Nm OpenSSL_version_num , +.Nm OpenSSL_version , +.Nm SSLeay , +.Nm SSLeay_version +.Nd get OpenSSL version number +.Sh SYNOPSIS +.In openssl/opensslv.h +.Fd #define OPENSSL_VERSION_NUMBER 0x020000000L +.Fd #define LIBRESSL_VERSION_NUMBER 0x02nnnn00fL +.Fd #define LIBRESSL_VERSION_TEXT \(dqLibreSSL 2.n.n\(dq +.Fd #define OPENSSL_VERSION_TEXT LIBRESSL_VERSION_TEXT +.In openssl/crypto.h +.Ft unsigned long +.Fn OpenSSL_version_num void +.Ft const char * +.Fo OpenSSL_version +.Fa "int t" +.Fc +.Ft long +.Fn SSLeay void +.Ft const char * +.Fo SSLeay_version +.Fa "int t" +.Fc +.Sh DESCRIPTION +.Dv OPENSSL_VERSION_NUMBER +and +.Dv LIBRESSL_VERSION_NUMBER +are numeric release version identifiers. +The first two digits contain the major release number, +the third and fourth digits the minor release number, +and the fifth and sixth digits the fix release number. +For OpenSSL, the seventh and eight digits contain the patch release number +and the final digit is 0 for development, 1 to e for betas 1 to 14, or f +for release. +For LibreSSL, +.Dv OPENSSL_VERSION_NUMBER +is always 0x020000000, +and +.Dv LIBRESSL_VERSION_NUMBER +always ends with 00f. +.Pp +For example: +.Bd -literal -offset indent +OPENSSL_VERSION_NUMBER: +0x000906000 == 0.9.6 dev +0x000906023 == 0.9.6b beta 3 +0x00090605f == 0.9.6e release +0x020000000 == 2.0.0 for any version of LibreSSL + +LIBRESSL_VERSION_NUMBER: +0x02070000f == LibreSSL 2.7.0 +.Ed +.Pp +OpenSSL versions prior to 0.9.3 had identifiers < 0x0930. +For versions between 0.9.3 and 0.9.5, +the seventh digit was 1 for release and 0 otherwise, +and the eighth and ninth digits were the patch release number. +.Pp +For example: +.Bd -literal +0x000904100 == 0.9.4 release +0x000905000 == 0.9.5 dev +.Ed +.Pp +OpenSSL version 0.9.5a had an interim interpretation that is like the current +one, except the patch level got the highest bit set, to keep continuity. +The number was therefore 0x0090581f. +.Pp +.Fn OpenSSL_version_num +returns +.Dv OPENSSL_VERSION_NUMBER . +.Pp +.Fn OpenSSL_version +returns different strings depending on +.Fa t : +.Bl -tag -width Ds +.It Dv OPENSSL_VERSION +The text variant of the version number, +.Dv OPENSSL_VERSION_TEXT . +For OpenSSL, it includes the release date, for example +.Qq OpenSSL 0.9.5a 1 Apr 2000 . +For LibreSSL, +.Dv LIBRESSL_VERSION_TEXT +is returned. +.It Dv OPENSSL_CFLAGS +The compiler flags set for the compilation process in the form +.Qq compiler: ... +if available or +.Qq compiler: information not available +otherwise. +LibreSSL never provides compiler information. +.It Dv OPENSSL_BUILT_ON +The date of the build process in the form +.Qq built on: ... +if available or +.Qq built on: date not available +otherwise. +LibreSSL never provides information on the build date. +.It Dv OPENSSL_PLATFORM +The Configure target of the library build in the form +.Qq platform: ... +if available or +.Qq platform: information not available +otherwise. +LibreSSL never provides platform information. +.It Dv OPENSSL_DIR +The +.Dv OPENSSLDIR +setting of the library build in the form +.Qq OPENSSLDIR: Qq ... +if available or +.Qq OPENSSLDIR: N/A +otherwise. +For LibreSSL, the default is +.Qq OPENSSLDIR: Qq /etc/ssl . +.It Dv OPENSSL_ENGINES_DIR +The +.Dv ENGINESDIR +setting of the library build in the form +.Qq ENGINESDIR: Qq ... +if available or +.Qq ENGINESDIR: N/A +otherwise. +LibreSSL never provides or uses an +.Dv ENGINESDIR . +.El +.Pp +For an unknown +.Fa t , +the text +.Qq not available +is returned. +.Pp +For backward compatibility, +.Dv SSLEAY_VERSION_NUMBER +is an alias for +.Dv OPENSSL_VERSION_NUMBER +and +.Fn SSLeay +for +.Dv OpenSSL_version_num . +The legacy function +.Fn SSLeay_version +is similar to +.Fn OpenSSL_version +except that it takes arguments +.Dv SSLEAY_VERSION , +.Dv SSLEAY_CFLAGS , +.Dv SSLEAY_BUILT_ON , +.Dv SSLEAY_PLATFORM , +and +.Dv SSLEAY_DIR +which expand to +.Em other +numerical values than the corresponding +.Dv OPENSSL_* +macros. +.Sh RETURN VALUES +.Fn OpenSSL_version_num +and +.Fn SSLeay +return a constant version number. +.Pp +.Fn OpenSSL_version +and +.Fn SSLeay_version +return pointers to static strings. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr OPENSSL_config 3 +.Sh HISTORY +.Fn SSLeay , +.Fn SSLeay_version , +and +.Dv SSLEAY_VERSION_NUMBER +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . +.Pp +.Dv OPENSSL_VERSION_NUMBER +first appeared in the first OpenSSL release, OpenSSL 0.9.1c, +and has been available since +.Ox 2.6 . +.Pp +.Dv SSLEAY_DIR +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Dv LIBRESSL_VERSION_NUMBER +first appeared in LibreSSL 2.0.0 and +.Ox 5.6 +and got its final format in LibreSSL 2.3.2 and +.Ox 5.9 . +.Dv LIBRESSL_VERSION_TEXT +first appeared in LibreSSL 2.2.2 and +.Ox 5.8 . +.Pp +.Fn OpenSSL_version_num +and +.Fn OpenSSL_version +first appeared in OpenSSL 1.1.0 +and have been available since LibreSSL 2.7.1 and +.Ox 6.3 . diff --git a/Libraries/libressl/man/OPENSSL_cleanse.3 b/Libraries/libressl/man/OPENSSL_cleanse.3 new file mode 100644 index 000000000..95fe6b86f --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_cleanse.3 @@ -0,0 +1,42 @@ +.\" $OpenBSD: OPENSSL_cleanse.3,v 1.4 2019/06/10 09:49:48 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt OPENSSL_CLEANSE 3 +.Os +.Sh NAME +.Nm OPENSSL_cleanse +.Nd OpenSSL memory cleaning operation +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft void +.Fo OPENSSL_cleanse +.Fa "void *ptr" +.Fa "size_t len" +.Fc +.Sh DESCRIPTION +Do not use the interface documented here. +It is provided purely for compatibility with legacy application code. +.Pp +.Fn OPENSSL_cleanse +has the same semantics as, and is a wrapper around, +.Xr explicit_bzero 3 . +.Sh SEE ALSO +.Xr crypto 3 +.Sh HISTORY +.Fn OPENSSL_cleanse +first appeared in OpenSSL 0.9.6h and has been available since +.Ox 3.4 . diff --git a/Libraries/libressl/man/OPENSSL_config.3 b/Libraries/libressl/man/OPENSSL_config.3 new file mode 100644 index 000000000..2960e2389 --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_config.3 @@ -0,0 +1,153 @@ +.\" $OpenBSD: OPENSSL_config.3,v 1.15 2019/06/14 13:41:31 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2004 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 14 2019 $ +.Dt OPENSSL_CONFIG 3 +.Os +.Sh NAME +.Nm OPENSSL_config , +.Nm OPENSSL_no_config +.Nd simple crypto and ssl library configuration +.Sh SYNOPSIS +.In openssl/conf.h +.Ft void +.Fo OPENSSL_config +.Fa "const char *appname" +.Fc +.Ft void +.Fn OPENSSL_no_config void +.Sh DESCRIPTION +.Fn OPENSSL_config +initializes the crypto library and calls +.Xr CONF_modules_load_file 3 +with the standard configuration file and the given +.Fa appname . +If +.Fa appname +is +.Dv NULL , +then the default name +.Sy openssl_conf +is used. +Any errors are ignored. +Further calls to +.Fn OPENSSL_config +have no effect. +.Pp +.Fn OPENSSL_no_config +suppresses the loading of the standard configuration file, so that any +future calls to +.Fn OPENSSL_config +or to +.Xr OPENSSL_init_crypto 3 +will ensure the library is initialized but no configuration +file will be loaded. +.Pp +Calling these functions is optional. +All required initialization of the crypto libraries happens +automatically when needed. +.Pp +To use a non-standard configuration file, refer to +.Xr CONF_modules_load_file 3 . +.Pp +Internally, +.Fn OPENSSL_config +calls +.Xr OPENSSL_init_crypto 3 , +.Xr OPENSSL_load_builtin_modules 3 , +and +.Xr ENGINE_load_builtin_engines 3 . +.Pp +If an application is compiled with the preprocessor symbol +.Dv OPENSSL_LOAD_CONF +#define'd, +.Xr OpenSSL_add_all_algorithms 3 +automatically calls +.Fn OPENSSL_config . +.Pp +Applications should free up configuration at application closedown by +calling +.Xr CONF_modules_free 3 . +.Sh FILES +.Bl -tag -width /etc/ssl/openssl.cnf -compact +.It Pa /etc/ssl/openssl.cnf +standard configuration file +.El +.Sh SEE ALSO +.Xr CONF_modules_free 3 , +.Xr CONF_modules_load_file 3 , +.Xr crypto 3 , +.Xr OPENSSL_load_builtin_modules 3 , +.Xr OPENSSL_VERSION_NUMBER 3 , +.Xr openssl.cnf 5 , +.Xr x509v3.cnf 5 +.Sh HISTORY +.Fn OPENSSL_config +and +.Fn OPENSSL_no_config +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OPENSSL_init_crypto.3 b/Libraries/libressl/man/OPENSSL_init_crypto.3 new file mode 100644 index 000000000..6f38c7bda --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_init_crypto.3 @@ -0,0 +1,115 @@ +.\" $OpenBSD: OPENSSL_init_crypto.3,v 1.5 2020/05/24 12:21:31 schwarze Exp $ +.\" Copyright (c) 2018, 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 24 2020 $ +.Dt OPENSSL_INIT_CRYPTO 3 +.Os +.Sh NAME +.Nm OPENSSL_init_crypto , +.Nm OPENSSL_init +.Nd initialise the crypto library +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft int +.Fo OPENSSL_init_crypto +.Fa "uint64_t options" +.Fa "const void *dummy" +.Fc +.Ft void +.Fn OPENSSL_init void +.Sh DESCRIPTION +These functions are deprecated. +It is never useful for an application program +to call either of them explicitly. +.Pp +The library automatically calls +.Fn OPENSSL_init_crypto +internally with an +.Fa options +argument of 0 whenever needed. +It is safest to assume that any function may do so. +.Pp +To enable or disable the standard configuration file, instead use +.Xr OPENSSL_config 3 +or +.Xr OPENSSL_no_config 3 , +respectively. +To load a non-standard configuration file, refer to +.Xr CONF_modules_load_file 3 . +.Pp +If +.Fn OPENSSL_init_crypto +is called before any other crypto or ssl functions, the crypto +library is initialised by allocating various internal resources, +in particular calling +.Xr ERR_load_crypto_strings 3 , +.Xr OpenSSL_add_all_ciphers 3 , +and +.Xr OpenSSL_add_all_digests 3 . +.Pp +The following +.Fa options +are supported: +.Bl -tag -width Ds +.It Dv OPENSSL_INIT_LOAD_CONFIG +At the end of the initialization, call +.Xr OPENSSL_config 3 +with a +.Dv NULL +argument, loading the default configuration file. +.It Dv OPENSSL_INIT_NO_LOAD_CONFIG +Ignore any later calls to +.Xr OPENSSL_config 3 . +.El +.Pp +The other +.Fa options +flags defined by OpenSSL are all ignored by LibreSSL. +The +.Fa dummy +argument has no effect. +.Pp +If this function is called more than once, none of the calls except +the first one have any effect. +.Pp +.Fn OPENSSL_init +has no effect at all. +.Sh RETURN VALUES +.Fn OPENSSL_init_crypto +is intended to return 1 on success or 0 on error. +.Sh SEE ALSO +.Xr CONF_modules_load_file 3 , +.Xr OPENSSL_config 3 , +.Xr OPENSSL_load_builtin_modules 3 , +.Xr openssl.cnf 5 +.Sh HISTORY +.Fn OPENSSL_init +first appeared in OpenSSL 1.0.0e and has been available since +.Ox 5.3 . +It stopped having any effect in OpenSSL 1.1.1 and in +.Ox 5.6 . +.Pp +.Fn OPENSSL_init_crypto +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Sh BUGS +.Fn OPENSSL_init_crypto +silently ignores almost all kinds of errors. +In particular, if memory allocation fails, initialisation is likely +to remain incomplete, the library may be in an inconsistent internal +state, but the return value will usually indicate success anyway. +There is no way for the application program to find out whether +library initialisation is actually complete, nor to get back to a +consistent state if it isn't. diff --git a/Libraries/libressl/man/OPENSSL_init_ssl.3 b/Libraries/libressl/man/OPENSSL_init_ssl.3 new file mode 100644 index 000000000..f37dccfaa --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_init_ssl.3 @@ -0,0 +1,76 @@ +.\" $OpenBSD: OPENSSL_init_ssl.3,v 1.4 2019/06/14 13:41:31 schwarze Exp $ +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 14 2019 $ +.Dt OPENSSL_INIT_SSL 3 +.Os +.Sh NAME +.Nm OPENSSL_init_ssl +.Nd initialise the crypto and ssl libraries +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo OPENSSL_init_ssl +.Fa "uint64_t options" +.Fa "const void *dummy" +.Fc +.Sh DESCRIPTION +This function is deprecated. +It is never useful for any application program to call it explicitly. +The library automatically calls it internally with an +.Fa options +argument of 0 whenever needed. +It is safest to assume that any function may do so. +.Pp +To enable or disable the standard configuration file, instead use +.Xr OPENSSL_config 3 +or +.Xr OPENSSL_no_config 3 , +respectively. +To load a non-standard configuration file, refer to +.Xr CONF_modules_load_file 3 . +.Pp +.Fn OPENSSL_init_ssl +calls +.Xr OPENSSL_init_crypto 3 , +.Xr SSL_load_error_strings 3 , +and +.Xr SSL_library_init 3 . +.Pp +The +.Fa options +argument is passed on to +.Xr OPENSSL_init_crypto 3 +and the +.Fa dummy +argument is ignored. +.Pp +If this function is called more than once, +none of the calls except the first one have any effect. +.Sh RETURN VALUES +.Fn OPENSSL_init_ssl +is intended to return 1 on success or 0 on error. +.Sh SEE ALSO +.Xr CONF_modules_load_file 3 , +.Xr OPENSSL_config 3 , +.Xr ssl 3 +.Sh HISTORY +.Fn OPENSSL_init_ssl +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Sh BUGS +.Fn OPENSSL_init_ssl +silently ignores even more configuration failures than +.Xr OPENSSL_init_crypto 3 . diff --git a/Libraries/libressl/man/OPENSSL_load_builtin_modules.3 b/Libraries/libressl/man/OPENSSL_load_builtin_modules.3 new file mode 100644 index 000000000..bcfb363ca --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_load_builtin_modules.3 @@ -0,0 +1,107 @@ +.\" $OpenBSD: OPENSSL_load_builtin_modules.3,v 1.6 2019/06/14 13:41:31 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2004, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 14 2019 $ +.Dt OPENSSL_LOAD_BUILTIN_MODULES 3 +.Os +.Sh NAME +.Nm OPENSSL_load_builtin_modules , +.Nm ASN1_add_oid_module , +.Nm ENGINE_add_conf_module +.Nd add standard configuration modules +.Sh SYNOPSIS +.In openssl/conf.h +.Ft void +.Fn OPENSSL_load_builtin_modules void +.Ft void +.Fn ASN1_add_oid_module void +.Ft void +.Fn ENGINE_add_conf_module void +.Sh DESCRIPTION +The function +.Fn OPENSSL_load_builtin_modules +adds all the standard OpenSSL configuration modules to the internal +list. +They can then be used by the OpenSSL configuration code. +.Pp +.Fn ASN1_add_oid_module +adds just the ASN.1 OBJECT module. +.Pp +.Fn ENGINE_add_conf_module +adds just the ENGINE configuration module. +.Pp +If the simple configuration function +.Xr OPENSSL_config 3 +is called then +.Fn OPENSSL_load_builtin_modules +is called automatically. +.Pp +Applications which use configuration functions like +.Xr CONF_modules_load_file 3 +directly need to call +.Fn OPENSSL_load_builtin_modules +themselves +.Em before +any other configuration code. +.Pp +Applications should call +.Xr OPENSSL_config 3 +or +.Fn OPENSSL_load_builtin_modules +to load all configuration modules instead of adding modules selectively: +otherwise functionality may be missing from the application when +new modules are added. +.Sh SEE ALSO +.Xr CONF_modules_load_file 3 , +.Xr OPENSSL_config 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/OPENSSL_malloc.3 b/Libraries/libressl/man/OPENSSL_malloc.3 new file mode 100644 index 000000000..87f8d81ed --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_malloc.3 @@ -0,0 +1,114 @@ +.\" $OpenBSD: OPENSSL_malloc.3,v 1.10 2022/11/06 18:31:15 tb Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 6 2022 $ +.Dt OPENSSL_MALLOC 3 +.Os +.Sh NAME +.Nm OPENSSL_malloc , +.Nm OPENSSL_realloc , +.Nm OPENSSL_free , +.Nm OPENSSL_strdup , +.Nm CRYPTO_malloc , +.Nm CRYPTO_realloc , +.Nm CRYPTO_free , +.Nm CRYPTO_strdup +.Nd legacy OpenSSL memory allocation wrappers +.Sh SYNOPSIS +.In openssl/crypto.h +.Ft void * +.Fo OPENSSL_malloc +.Fa "size_t num" +.Fc +.Ft void * +.Fo OPENSSL_realloc +.Fa "void *addr" +.Fa "size_t num" +.Fc +.Ft void +.Fo OPENSSL_free +.Fa "void *addr" +.Fc +.Ft char * +.Fo OPENSSL_strdup +.Fa "const char *str" +.Fc +.Ft void * +.Fo CRYPTO_malloc +.Fa "size_t num" +.Fa "const char *file" +.Fa "int line" +.Fc +.Ft void * +.Fo CRYPTO_realloc +.Fa "void *p" +.Fa "size_t num" +.Fa "const char *file" +.Fa "int line" +.Fc +.Ft void +.Fo CRYPTO_free +.Fa "void *str" +.Fa "const char *" +.Fa int +.Fc +.Ft char * +.Fo CRYPTO_strdup +.Fa "const char *p" +.Fa "const char *file" +.Fa "int line" +.Fc +.Sh DESCRIPTION +Do not use any of the interfaces documented here in new code. +They are provided purely for compatibility with legacy application code. +.Pp +All 8 of these functions are wrappers around the corresponding +standard +.Xr malloc 3 , +.Xr realloc 3 , +.Xr free 3 , +and +.Xr strdup 3 +functions. +.Sh RETURN VALUES +These functions return the same type and value as the corresponding +standard functions. +.Sh SEE ALSO +.Xr crypto 3 +.Sh HISTORY +.Fn CRYPTO_malloc , +.Fn CRYPTO_realloc , +and +.Fn CRYPTO_free +first appeared in SSLeay 0.6.4 and have been available since +.Ox 2.4 . +.Pp +.Fn OPENSSL_malloc , +.Fn OPENSSL_realloc , +and +.Fn OPENSSL_free +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn CRYPTO_strdup +and +.Fn OPENSSL_strdup +first appeared in OpenSSL 0.9.8j and have been available since +.Ox 4.5 . +.Sh CAVEATS +If interoperability with other implementations is required, +memory returned by the library as bare pointers must be freed with +.Fn OPENSSL_free . diff --git a/Libraries/libressl/man/OPENSSL_sk_new.3 b/Libraries/libressl/man/OPENSSL_sk_new.3 new file mode 100644 index 000000000..5df45534f --- /dev/null +++ b/Libraries/libressl/man/OPENSSL_sk_new.3 @@ -0,0 +1,597 @@ +.\" $OpenBSD: OPENSSL_sk_new.3,v 1.12 2021/03/12 05:18:00 jsg Exp $ +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 12 2021 $ +.Dt OPENSSL_SK_NEW 3 +.Os +.Sh NAME +.Nm sk_new_null , +.Nm sk_new , +.Nm sk_set_cmp_func , +.Nm sk_dup , +.Nm sk_free , +.Nm sk_pop_free , +.Nm sk_num , +.Nm sk_value , +.Nm sk_find , +.Nm sk_find_ex , +.Nm sk_sort , +.Nm sk_is_sorted , +.Nm sk_push , +.Nm sk_unshift , +.Nm sk_insert , +.Nm sk_set , +.Nm sk_pop , +.Nm sk_shift , +.Nm sk_delete , +.Nm sk_delete_ptr , +.Nm sk_zero +.Nd variable-sized arrays of void pointers, called OpenSSL stacks +.Sh SYNOPSIS +.In openssl/stack.h +.Ft _STACK * +.Fn sk_new_null void +.Ft _STACK * +.Fo sk_new +.Fa "int (*compfunc)(const void *, const void *)" +.Fc +.Ft old_function_pointer +.Fo sk_set_cmp_func +.Fa "_STACK *stack" +.Fa "int (*compfunc)(const void *, const void *)" +.Fc +.Ft _STACK * +.Fo sk_dup +.Fa "_STACK *stack" +.Fc +.Ft void +.Fo sk_free +.Fa "_STACK *stack" +.Fc +.Ft void +.Fo sk_pop_free +.Fa "_STACK *stack" +.Fa "void (*freefunc)(void *)" +.Fc +.Ft int +.Fo sk_num +.Fa "const _STACK *stack" +.Fc +.Ft void * +.Fo sk_value +.Fa "const _STACK *stack" +.Fa "int index" +.Fc +.Ft int +.Fo sk_find +.Fa "_STACK *stack" +.Fa "void *wanted" +.Fc +.Ft int +.Fo sk_find_ex +.Fa "_STACK *stack" +.Fa "void *wanted" +.Fc +.Ft void +.Fo sk_sort +.Fa "_STACK *stack" +.Fc +.Ft int +.Fo sk_is_sorted +.Fa "const _STACK *stack" +.Fc +.Ft int +.Fo sk_push +.Fa "_STACK *stack" +.Fa "void *new_item" +.Fc +.Ft int +.Fo sk_unshift +.Fa "_STACK *stack" +.Fa "void *new_item" +.Fc +.Ft int +.Fo sk_insert +.Fa "_STACK *stack" +.Fa "void *new_item" +.Fa "int index" +.Fc +.Ft void * +.Fo sk_set +.Fa "_STACK *stack" +.Fa "int index" +.Fa "void *new_item" +.Fc +.Ft void * +.Fo sk_pop +.Fa "_STACK *stack" +.Fc +.Ft void * +.Fo sk_shift +.Fa "_STACK *stack" +.Fc +.Ft void * +.Fo sk_delete +.Fa "_STACK *stack" +.Fa "int index" +.Fc +.Ft void * +.Fo sk_delete_ptr +.Fa "_STACK *stack" +.Fa "void *wanted" +.Fc +.Ft void +.Fo sk_zero +.Fa "_STACK *stack" +.Fc +.Sh DESCRIPTION +OpenSSL introduced an idiosyncratic concept of variable sized arrays +of pointers and somewhat misleadingly called such an array a +.Dq stack . +Intrinsically, and as documented in this manual page, OpenSSL stacks +are not type safe but only handle +.Vt void * +function arguments and return values. +.Pp +OpenSSL also provides a fragile, unusually complicated system of +macro-generated wrappers that offers superficial type safety at the +expense of extensive obfuscation, implemented using large amounts +of autogenerated code involving exceedingly ugly, nested +.Xr cpp 1 +macros; see the +.Xr STACK_OF 3 +manual page for details. +.Pp +The fundamental data type is the +.Vt _STACK +structure. +It stores a variable number of void pointers +and remembers the number of pointers currently stored. +It can optionally hold a pointer to a comparison function. +As long as no comparison function is installed, the order of pointers +is meaningful; as soon as a comparison function is installed, it +becomes ill-defined. +.Pp +.Fn sk_new_null +allocates and initializes a new, empty stack. +.Fn sk_new +is identical except that it also installs +.Fa compfunc +as the comparison function for the new stack object. +.Fn sk_set_cmp_func +installs +.Fa compfunc +for the existing +.Fa stack . +The +.Fa compfunc +is allowed to be +.Dv NULL , +but the +.Fa stack +is not. +.Pp +.Fn sk_dup +creates a shallow copy of the given +.Fa stack , +which must not be a +.Dv NULL +pointer. +It neither copies the objects pointed to from the stack nor +increases their reference counts, but merely copies the pointers. +Extreme care must be taken in order to avoid freeing the memory twice, +for example by calling +.Fn sk_free +on one copy and only calling +.Fn sk_pop_free +on the other. +.Pp +.Fn sk_free +frees the given +.Fa stack . +It does not free any of the pointers stored on the stack. +Unless these pointers are merely copies of pointers owned by +other objects, they must be freed before calling +.Fn sk_free , +in order to avoid leaking memory. +If +.Fa stack +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn sk_pop_free +is severely misnamed. +It does not at all do what one would expect from a function called +.Dq pop . +Instead, it does the same as +.Fn sk_free , +except that it also calls the function +.Fa freefunc +on each of the pointers contained in the +.Fa stack . +If the calls to +.Fa freefunc +are intended to free the memory in use by the objects on the stack, +ensure that no other pointers to the same objects remain elsewhere. +.Pp +.Fn sk_find +searches the +.Fa stack +for the +.Fa wanted +pointer. +If the +.Fa stack +contains more than one copy of the +.Fa wanted +pointer, only the first match is found. +If a comparison function is installed for the stack, the stack is +first sorted with +.Fn sk_sort , +and instead of comparing pointers, two pointers are considered to match +if the comparison function returns 0. +.Pp +.Fn sk_find_ex +is identical to +.Fn sk_find +except that if the +.Fa stack +is not empty but no match is found, +the index of some pointer considered closest to +.Fa wanted +is returned. +.Pp +.Fn sk_sort +sorts the +.Fa stack +using +.Xr qsort 3 +and the installed comparison function. +If +.Fa stack +is a +.Dv NULL +pointer or already considered sorted, no action occurs. +This function can only be called if a comparison function is installed. +.Pp +.Fn sk_is_sorted +reports whether the +.Fa stack +is considered sorted. +Calling +.Fn sk_new_null +or +.Fn sk_new , +successfully calling +.Fn sk_push , +.Fn sk_unshift , +.Fn sk_insert , +or +.Fn sk_set , +or changing the comparison function sets the state to unsorted. +If a comparison function is installed, calling +.Fn sk_sort , +.Fn sk_find , +or +.Fn sk_find_ex +sets the state to sorted. +.Pp +.Fn sk_push +pushes +.Fa new_item +onto the end of the +.Fa stack , +increasing the number of pointers by 1. +If +.Fa stack +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn sk_unshift +inserts +.Fa new_item +at the beginning of the +.Fa stack , +such that it gets the index 0. +The number of pointers increases by 1. +If +.Fa stack +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn sk_insert +inserts the +.Fa new_item +into the +.Fa stack +such that it gets the given +.Fa index . +If +.Fa index +is less than 0 or greater than or equal to +.Fn sk_num stack , +the effect is the same as for +.Fn sk_push . +If +.Fa stack +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn sk_set +replaces the pointer with the given +.Fa index +on the +.Fa stack +with the +.Fa new_item . +The old pointer is not freed, +which may leak memory if no copy of it exists elsewhere. +If +.Fa stack +is a +.Dv NULL +pointer or if +.Fa index +is less than 0 or greater than or equal to +.Fn sk_num stack , +no action occurs. +.Pp +.Fn sk_pop +and +.Fn sk_shift +remove the pointer with the highest or lowest index from the +.Fa stack , +respectively, reducing the number of pointers by 1. +If +.Fa stack +is a +.Dv NULL +pointer or if it is empty, no action occurs. +.Pp +.Fn sk_delete +removes the pointer with the given +.Fa index +from the +.Fa stack , +reducing the number of pointers by 1. +If +.Fa stack +is a +.Dv NULL +pointer or the +.Fa index +is less than 0 or greater than or equal to +.Fn sk_num stack , +no action occurs. +.Pp +.Fn sk_delete_ptr +removes the +.Fa wanted +pointer from the +.Fa stack , +reducing the number of pointers by 1 if it is found. +It never uses a comparison function +but only compares pointers themselves. +The +.Fa stack +pointer must not be +.Dv NULL . +.Pp +.Fn sk_zero +removes all pointers from the +.Fa stack . +It does not free any of the pointers. +Unless these pointers are merely copies of pointers owned by other +objects, they must be freed before calling +.Fn sk_zero , +in order to avoid leaking memory. +If +.Fa stack +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn sk_new_null , +.Fn sk_new , +and +.Fn sk_dup +return a pointer to the newly allocated stack object or +.Dv NULL +if insufficient memory is available. +.Pp +.Fn sk_set_cmp_func +returns a pointer to the comparison function +that was previously installed for the +.Fa stack +or +.Dv NULL +if none was installed. +.Pp +.Fn sk_num +returns the number of pointers currently stored on the +.Fa stack , +or \-1 if +.Fa stack +is a +.Dv NULL +pointer. +.Pp +.Fn sk_value +returns the pointer with the given +.Fa index +from the +.Fa stack , +or +.Dv NULL +if +.Fa stack +is a +.Dv NULL +pointer or if the +.Fa index +is less than 0 or greater than or equal to +.Fn sk_num stack . +.Pp +.Fn sk_find +returns the lowest index considered to match or \-1 if +.Fa stack +is a +.Dv NULL +pointer or if no match is found. +.Pp +.Fn sk_find_ex +returns some index or \-1 if +.Fa stack +is a +.Dv NULL +pointer or empty. +.Pp +.Fn sk_is_sorted +returns 1 if the +.Fa stack +is considered sorted or if it is a +.Dv NULL +pointer, or 0 otherwise. +.Pp +.Fn sk_push , +.Fn sk_unshift , +and +.Fn sk_insert +return the new number of pointers on the +.Fa stack +or 0 if +.Fa stack +is a +.Dv NULL +pointer or if memory allocation fails. +.Pp +.Fn sk_set +returns +.Fa new_item +or +.Dv NULL +if +.Fa stack +is a +.Dv NULL +pointer or if the +.Fa index +is less than 0 or greater than or equal to +.Fn sk_num stack . +.Pp +.Fn sk_pop +and +.Fn sk_shift +return the deleted pointer or +.Dv NULL +if +.Fa stack +is a +.Dv NULL +pointer or if it is empty. +.Pp +.Fn sk_delete +returns the deleted pointer or +.Dv NULL +if +.Fa stack +is a +.Dv NULL +pointer or if the +.Fa index +is less than 0 or greater than or equal to +.Fn sk_num stack . +.Pp +.Fn sk_delete_ptr +returns +.Fa wanted +or +.Dv NULL +if it is not found. +.Sh SEE ALSO +.Xr STACK_OF 3 +.Sh HISTORY +.Fn sk_new_null , +.Fn sk_new , +.Fn sk_free , +.Fn sk_pop_free , +.Fn sk_num , +.Fn sk_value , +.Fn sk_find , +.Fn sk_push , +.Fn sk_unshift , +.Fn sk_insert , +.Fn sk_pop , +.Fn sk_shift , +.Fn sk_delete , +and +.Fn sk_delete_ptr +first appeared in SSLeay 0.5.1. +.Fn sk_set_cmp_func , +.Fn sk_dup , +and +.Fn sk_zero +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn sk_set +first appeared in OpenSSL 0.9.3. +.Fn sk_sort +first appeared in OpenSSL 0.9.4. +Both functions have been available since +.Ox 2.6 . +.Pp +.Fn sk_is_sorted +first appeared in OpenSSL 0.9.7e and has been available since +.Ox 3.8 . +.Pp +.Fn sk_find_ex +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Sh BUGS +Even if a comparison function is installed, empty stacks and +stacks containing a single pointer are sometimes considered +sorted and sometimes considered unsorted. +.Pp +If a comparison function is installed, the concept of +.Dq first match +in +.Fn sk_find +and +.Fn sk_find_ex +is ill-defined because +.Xr qsort 3 +is not a stable sorting function. +It is probably best to only assume that they return an arbitrary match. +.Pp +The concept of +.Dq closest +for +.Fn sk_find_ex +is even less clearly defined. +The match may sometimes be smaller and sometimes larger than +.Fa wanted , +even if both smaller and larger pointers exist in the +.Fa stack . +Besides, it is again ill-defined +which of several pointers that compare equal is selected. +It is probably best to not assume anything about the selection +for cases where there is no match. diff --git a/Libraries/libressl/man/OpenSSL_add_all_algorithms.3 b/Libraries/libressl/man/OpenSSL_add_all_algorithms.3 new file mode 100644 index 000000000..0c4112087 --- /dev/null +++ b/Libraries/libressl/man/OpenSSL_add_all_algorithms.3 @@ -0,0 +1,148 @@ +.\" $OpenBSD: OpenSSL_add_all_algorithms.3,v 1.14 2023/09/10 14:39:58 schwarze Exp $ +.\" full merge up to: OpenSSL b3696a55 Sep 2 09:35:50 2017 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2000, 2003, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2023 $ +.Dt OPENSSL_ADD_ALL_ALGORITHMS 3 +.Os +.Sh NAME +.Nm OpenSSL_add_all_algorithms , +.Nm OpenSSL_add_all_ciphers , +.Nm OpenSSL_add_all_digests , +.Nm EVP_cleanup , +.Nm SSLeay_add_all_algorithms +.\" .Nm OPENSSL_add_all_algorithms_conf , +.\" .Nm OPENSSL_add_all_algorithms_noconf , +.\" .Nm SSLeay_add_all_ciphers , and +.\" .Nm SSLeay_add_all_digests are intentionally undocumented +.\" because they are unused aliases. +.Nd add algorithms to internal table +.Sh SYNOPSIS +.In openssl/evp.h +.Ft void +.Fn OpenSSL_add_all_algorithms void +.Ft void +.Fn OpenSSL_add_all_ciphers void +.Ft void +.Fn OpenSSL_add_all_digests void +.Ft void +.Fn EVP_cleanup void +.Ft void +.Fn SSLeay_add_all_algorithms void +.Sh DESCRIPTION +These functions are deprecated. +It is never useful for any application program +to call any of them explicitly. +The library automatically calls them internally whenever needed. +.Pp +OpenSSL keeps an internal table of digest algorithms and ciphers. +It uses this table to look up ciphers via functions such as +.Xr EVP_get_cipherbyname 3 . +.Pp +.Fn OpenSSL_add_all_algorithms +adds all algorithms to the table (digests and ciphers). +If an application is compiled with the preprocessor symbol +.Dv OPENSSL_LOAD_CONF +#define'd, it also calls +.Xr OPENSSL_config 3 +with a +.Dv NULL +argument, loading the default configuration file. +.Pp +.Fn OpenSSL_add_all_digests +adds all digest algorithms to the table. +.Pp +.Fn OpenSSL_add_all_ciphers +adds all encryption algorithms to the table including password based +encryption algorithms. +.Pp +If any of the above functions is called more than once, +only the first call has an effect. +.Pp +.Fn EVP_cleanup +removes all ciphers and digests from the table and also calls +.Xr OBJ_NAME_cleanup 3 +with an argument of \-1 , +thus resetting the global associative array of names +and all signature algorithm definitions to their default states, +removing all application-defined types, key-value pairs, and aliases, +including any that are unrelated to the EVP library. +.Pp +.Fn SSLeay_add_all_algorithms +is a deprecated alias for +.Fn OpenSSL_add_all_algorithms . +.Sh SEE ALSO +.Xr evp 3 , +.Xr EVP_add_cipher 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_EncryptInit 3 , +.Xr OBJ_cleanup 3 , +.Xr OBJ_NAME_add 3 , +.Xr OPENSSL_config 3 +.Sh HISTORY +.Fn EVP_cleanup , +.Fn SSLeay_add_all_algorithms , +and precursor functions +.Fn SSLeay_add_all_ciphers +and +.Fn SSLeay_add_all_digests +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn OpenSSL_add_all_algorithms , +.Fn OpenSSL_add_all_ciphers , +and +.Fn OpenSSL_add_all_digests +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Sh BUGS +Although the functions do not return error codes, it is possible for them +to fail. +This will only happen as a result of a memory allocation failure so this +is not too much of a problem in practice. diff --git a/Libraries/libressl/man/PEM_ASN1_read.3 b/Libraries/libressl/man/PEM_ASN1_read.3 new file mode 100644 index 000000000..53ebe5ada --- /dev/null +++ b/Libraries/libressl/man/PEM_ASN1_read.3 @@ -0,0 +1,172 @@ +.\" $OpenBSD: PEM_ASN1_read.3,v 1.2 2020/07/23 17:34:53 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 23 2020 $ +.Dt PEM_ASN1_READ 3 +.Os +.Sh NAME +.Nm d2i_of_void , +.Nm PEM_ASN1_read , +.Nm PEM_ASN1_read_bio +.Nd PEM and DER decode an arbitrary ASN.1 value +.Sh SYNOPSIS +.In openssl/pem.h +.Ft typedef void * +.Fo d2i_of_void +.Fa "void **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft void * +.Fo PEM_ASN1_read +.Fa "d2i_of_void *d2i" +.Fa "const char *name" +.Fa "FILE *in_fp" +.Fa "void **val_out" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft void * +.Fo PEM_ASN1_read_bio +.Fa "d2i_of_void *d2i" +.Fa "const char *name" +.Fa "BIO *in_bp" +.Fa "void **val_out" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Sh DESCRIPTION +These functions read one object from +.Fa in_fp +or +.Fa in_bp +and perform both PEM and DER decoding. +They are needed when more specific decoding functions +like those documented in +.Xr PEM_read_bio_PrivateKey 3 +and +.Xr PEM_read_SSL_SESSION 3 +are inadequate for the type +.Fa name . +.Pp +For PEM decoding, +.Xr PEM_bytes_read_bio 3 +is called internally. +Consequently, the first object of type +.Fa name +is returned and preceding objects of other types are discarded. +If necessary, data is decrypted, using +.Fa cb +and/or +.Fa u +if they are not +.Dv NULL , +as described in the +.Xr pem_password_cb 3 +manual page. +.Pp +For subsequent DER decoding, pass a +.Fa d2i +callback function that is adequate for the type +.Fa name , +typically returning a pointer of a type more specific than +.Ft void * . +For example, +.Xr d2i_ASN1_TYPE 3 +can always be used and its manual page describes the required +behaviour of the callback function to be passed. +Normally, passing a more specific function is more useful; +candidate functions can be found with +.Ql man -k Nm~^d2i_ . +.Pp +For the +.Fa name +argument, the +.Dv PEM_STRING_* +string constants defined in +.In openssl/pem.h +can be used. +.Pp +The +.Fa val_out +argument is useless and its many dangers are described in detail in the +.Xr d2i_ASN1_TYPE 3 +manual page. +To reduce the risk of bugs, always passing +.Dv NULL +is recommended. +.Sh RETURN VALUES +These functions return a pointer to the decoded object or +.Dv NULL +if an error occurs. +They fail if +.Xr PEM_bytes_read_bio 3 +fails, for example because of invalid syntax in the input, an unknown +encryption, or an invalid passphrase entered by the user. +They also fail if +.Fa d2i +returns +.Dv NULL , +for example due to DER decoding errors. +.Pp +.Fn PEM_ASN1_read +may also fail if memory is exhausted. +.Sh EXAMPLES +Typical usage of +.Fn PEM_ASN1_read +is demonstrated by the implementation of the more specific function +to PEM and DER decode an X.509 certificate: +.Bd -literal -offset 2n +X509 * +PEM_read_X509(FILE *fp, X509 **val_out, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_X509, PEM_STRING_X509, + fp, (void **)val_out, cb, u); +} +.Ed +.Sh ERRORS +Diagnostics that can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 +include: +.Bl -tag -width Ds +.It Dv ERR_R_BUF_LIB Qq "BUF lib" +.Fn PEM_ASN1_read +failed to set up a temporary BIO, +for example because memory was exhausted. +.It Dv ERR_R_ASN1_LIB Qq "ASN1 lib" +.Fa d2i +returned +.Dv NULL , +for example due to a DER syntax error. +.El +.Pp +Additional types of errors can result from +.Xr PEM_bytes_read_bio 3 . +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr d2i_ASN1_TYPE 3 , +.Xr PEM_bytes_read_bio 3 , +.Xr PEM_read 3 , +.Xr PEM_read_bio_PrivateKey 3 , +.Xr PEM_read_SSL_SESSION 3 , +.Xr PEM_X509_INFO_read 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.5.1 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/PEM_X509_INFO_read.3 b/Libraries/libressl/man/PEM_X509_INFO_read.3 new file mode 100644 index 000000000..b3216a89b --- /dev/null +++ b/Libraries/libressl/man/PEM_X509_INFO_read.3 @@ -0,0 +1,189 @@ +.\" $OpenBSD: PEM_X509_INFO_read.3,v 1.4 2021/10/19 10:39:33 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 19 2021 $ +.Dt PEM_X509_INFO_READ 3 +.Os +.Sh NAME +.Nm PEM_X509_INFO_read , +.Nm PEM_X509_INFO_read_bio +.Nd PEM and DER decode X.509 certificates, private keys, and revocation lists +.Sh SYNOPSIS +.In openssl/pem.h +.Ft STACK_OF(X509_INFO) * +.Fo PEM_X509_INFO_read +.Fa "FILE *in_fp" +.Fa "STACK_OF(X509_INFO) *sk" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft STACK_OF(X509_INFO) * +.Fo PEM_X509_INFO_read_bio +.Fa "BIO *in_bp" +.Fa "STACK_OF(X509_INFO) *sk" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Sh DESCRIPTION +These functions read zero or more objects +related to X.509 certificates from +.Fa in_fp +or +.Fa in_bp , +perform both PEM and DER decoding, +and wrap the resulting objects in newly allocated +.Vt X509_INFO +containers. +.Pp +Setting +.Fa sk +to +.Dv NULL +is recommended, in which case +a new stack is allocated, populated, and returned. +If an existing +.Fa sk +is passed in, the created +.Vt X509_INFO +objects are pushed onto that stack. +.Pp +For PEM decoding, +.Xr PEM_read_bio 3 +is used internally, implying that any non-PEM data +before, between, and after the objects is silently discarded. +.Pp +For subsequent DER decoding, +the decoding function and the field of the +.Vt X509_INFO +structure to store the new object in +are selected according to the PEM type name: +.Bl -column "TRUSTED CERTIFICATE" "d2i_PrivateKey()" "revocation list" +.It PEM type name Ta decoder Ta Vt X509_INFO No field +.It CERTIFICATE Ta Xr d2i_X509 3 Ta certificate +.It X509 CERTIFICATE Ta Xr d2i_X509 3 Ta certificate +.It TRUSTED CERTIFICATE Ta Xr d2i_X509_AUX 3 Ta certificate +.It X509 CRL Ta Xr d2i_X509_CRL 3 Ta revocation list +.It RSA PRIVATE KEY Ta Xr d2i_PrivateKey 3 Ta private key +.It DSA PRIVATE KEY Ta Xr d2i_PrivateKey 3 Ta private key +.It EC PRIVATE KEY Ta Xr d2i_PrivateKey 3 Ta private key +.El +.Pp +Whenever the selected field is already occupied, another new +.Vt X509_INFO +container is allocated and pushed onto the stack. +Depending on the sequence of objects in the input, this can result +in several partially populated +.Vt X509_INFO +containers being pushed onto the stack. +.Pp +PEM objects of types not listed in the above table are silently skipped. +.Pp +Encrypted certificates and revocation lists are decrypted by calling +.Xr PEM_do_header 3 +internally, passing through the optional arguments +.Fa cb +and +.Fa u . +Encrypted private keys are not decrypted. +Instead, the encrypted form is stored as read. +All the same, +.Xr PEM_get_EVP_CIPHER_INFO 3 +is called internally to check that PEM headers, if there are any, +are valid and specify an encryption the library is prepared to handle. +.Pp +If any error occurs, objects that had already been read +during the same call are deleted again and +.Fa sk +is left unchanged. +.Sh RETURN VALUES +These functions return a pointer to the stack +the objects read were pushed onto or +.Dv NULL +if an error occurs. +They fail if +.Xr PEM_read_bio 3 , +.Xr PEM_get_EVP_CIPHER_INFO 3 , +.Xr PEM_do_header 3 , +or DER decoding fails or if memory is exhausted. +.Sh ERRORS +Diagnostics that can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 +include: +.Bl -tag -width Ds +.It Dv ERR_R_ASN1_LIB Qq "ASN1 lib" +DER decoding of a PEM object failed. +.It Dv ERR_R_BUF_LIB Qq BUF lib +.Fn PEM_X509_INFO_read +failed to set up a temporary BIO, for example because memory was exhausted. +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +.Fn PEM_X509_INFO_read_bio +failed to allocate a new +.Vt X509_INFO , +.Vt STACK_OF(X509_INFO) , +or +.Vt X509_PKEY +object. +.El +.Pp +Additional types of errors can result from +.Xr PEM_read_bio 3 , +.Xr PEM_get_EVP_CIPHER_INFO 3 , +and +.Xr PEM_do_header 3 . +.Pp +After these functions failed due to memory exhaustion, +.Xr ERR_get_error 3 +may sometimes return 0 anyway. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr d2i_PrivateKey 3 , +.Xr d2i_X509 3 , +.Xr d2i_X509_CRL 3 , +.Xr EVP_PKEY_new 3 , +.Xr PEM_read 3 , +.Xr PEM_read_bio_PrivateKey 3 , +.Xr STACK_OF 3 , +.Xr X509_CRL_new 3 , +.Xr X509_INFO_new 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_new 3 , +.Xr X509_PKEY_new 3 +.Sh HISTORY +.Fn PEM_X509_INFO_read +first appeared in SSLeay 0.5.1 and +.Fn PEM_X509_INFO_read_bio +in SSLeay 0.6.0. +Both functions have been available since +.Ox 2.4 . +.Sh CAVEATS +It is not an error +if the input does not contain any objects of the desired types. +In that case, nothing is added to +.Fa sk , +or if +.Fa sk +is +.Dv NULL , +a newly allocated, empty stack is returned. +The only way to detect this situation is by comparing +the number of objects on the stack before and after the call. +.Sh BUGS +When reaching the end of the input, these functions call +.Xr ERR_clear_error 3 , +which may hide errors that occurred before calling these functions. diff --git a/Libraries/libressl/man/PEM_bytes_read_bio.3 b/Libraries/libressl/man/PEM_bytes_read_bio.3 new file mode 100644 index 000000000..20ad6b8a4 --- /dev/null +++ b/Libraries/libressl/man/PEM_bytes_read_bio.3 @@ -0,0 +1,184 @@ +.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.6 2020/07/23 17:34:53 schwarze Exp $ +.\" selective merge up to: +.\" OpenSSL PEM_bytes_read_bio.pod 7671342e Feb 29 15:47:12 2016 -0600 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Benjamin Kaduk . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 23 2020 $ +.Dt PEM_BYTES_READ_BIO 3 +.Os +.Sh NAME +.Nm PEM_bytes_read_bio +.Nd read a PEM-encoded data structure from a BIO +.Sh SYNOPSIS +.In openssl/pem.h +.Ft int +.Fo PEM_bytes_read_bio +.Fa "unsigned char **pdata" +.Fa "long *plen" +.Fa "char **pnm" +.Fa "const char *name" +.Fa "BIO *in_bp" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Sh DESCRIPTION +.Fn PEM_bytes_read_bio +reads and PEM decodes the first object of type +.Fa name +.Pq e.g. RSA PRIVATE KEY, CERTIFICATE, etc.\& +from +.Fa in_bp . +If multiple PEM-encoded data structures are present in the same stream, +it skips non-matching data types and continues reading. +Before reading each PEM object, lines not starting with +.Qq "-----BEGIN " +are also skipped; see +.Xr PEM_read_bio 3 +for details of PEM parsing. +.Pp +The PEM header may indicate that the following data is encrypted; if so, +the data is decrypted, optionally using +.Fa cb +and +.Fa u , +as described in +.Xr pem_password_cb 3 . +.Pp +Some data types have compatibility aliases, such as a file containing +X509 CERTIFICATE matching a request for the deprecated type CERTIFICATE. +The actual type indicated by the file is returned in +.Em *pnm +if +.Fa pnm +is +.Pf non- Dv NULL . +The caller must free the storage pointed to by +.Em *pnm . +.Pp +The returned data is the DER-encoded form of the requested type, in +.Em *pdata +with length +.Em *plen . +The caller must free the storage pointed to by +.Em *pdata . +.Sh RETURN VALUES +.Fn PEM_bytes_read_bio +returns 1 for success or 0 for failure. +.Sh ERRORS +Diagnostics that can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 +include: +.Bl -tag -width Ds +.It Dv PEM_R_NO_START_LINE Qq no start line +No more PEM objects were found in the input. +This can happen when the input contains no PEM objects at all, +or only objects that do not match the type +.Fa name . +.It Dv PEM_R_NOT_PROC_TYPE Qq not proc type +The first PEM header does not start with +.Qq "Proc-Type: " . +.It Dv PEM_R_NOT_ENCRYPTED Qq not encrypted +The Proc-Type header differs from +.Qq 4,ENCRYPTED . +.It Dv PEM_R_SHORT_HEADER Qq short header +The Proc-Type header is the last header line. +.It Dv PEM_R_NOT_DEK_INFO Qq not dek info +The second PEM header does not start with +.Qq "DEK-Info: " . +.It Dv PEM_R_UNSUPPORTED_ENCRYPTION Qq unsupported encryption +The cipher name given in the DEK-Info header is unknown to +.Xr EVP_get_cipherbyname 3 . +.It Dv PEM_R_BAD_IV_CHARS Qq "bad iv chars" +The word following the cipher name in the DEK-Info header +contains bytes that are not hexadecimal digits. +This also happens when the initialization vector is missing or too short. +.It Dv PEM_R_BAD_PASSWORD_READ Qq bad password read +.Fa cb +reported failure. +This may for example happen when the user mistypes the password. +.It Dv PEM_R_BAD_DECRYPT Qq bad decrypt +.Xr EVP_DecryptInit_ex 3 , +.Xr EVP_DecryptUpdate 3 , +or +.Xr EVP_DecryptFinal_ex 3 +failed. +.El +.Pp +Additional types of errors can result from +.Xr PEM_read_bio 3 . +.Sh SEE ALSO +.Xr PEM_ASN1_read 3 , +.Xr PEM_read 3 , +.Xr PEM_read_bio_PrivateKey 3 , +.Xr PEM_X509_INFO_read 3 +.Sh STANDARDS +RFC 1421: Privacy Enhancement for Internet Electronic Mail (PEM), Part I +.Sh HISTORY +.Fn PEM_bytes_read_bio +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/PEM_read.3 b/Libraries/libressl/man/PEM_read.3 new file mode 100644 index 000000000..1493d54fc --- /dev/null +++ b/Libraries/libressl/man/PEM_read.3 @@ -0,0 +1,416 @@ +.\" $OpenBSD: PEM_read.3,v 1.15 2023/09/18 15:26:46 schwarze Exp $ +.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Viktor Dukhovni +.\" and by Rich Salz . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 18 2023 $ +.Dt PEM_READ 3 +.Os +.Sh NAME +.Nm PEM_write , +.Nm PEM_write_bio , +.Nm PEM_read , +.Nm PEM_read_bio , +.Nm PEM_get_EVP_CIPHER_INFO , +.Nm PEM_do_header , +.Nm PEM_def_callback , +.Nm pem_password_cb +.Nd PEM encoding routines +.Sh SYNOPSIS +.In openssl/pem.h +.Ft int +.Fo PEM_write +.Fa "FILE *fp" +.Fa "const char *name" +.Fa "const char *header" +.Fa "const unsigned char *data" +.Fa "long len" +.Fc +.Ft int +.Fo PEM_write_bio +.Fa "BIO *bp" +.Fa "const char *name" +.Fa "const char *header" +.Fa "const unsigned char *data" +.Fa "long len" +.Fc +.Ft int +.Fo PEM_read +.Fa "FILE *fp" +.Fa "char **name" +.Fa "char **header" +.Fa "unsigned char **data" +.Fa "long *len" +.Fc +.Ft int +.Fo PEM_read_bio +.Fa "BIO *bp" +.Fa "char **name" +.Fa "char **header" +.Fa "unsigned char **data" +.Fa "long *len" +.Fc +.Ft int +.Fo PEM_get_EVP_CIPHER_INFO +.Fa "char *header" +.Fa "EVP_CIPHER_INFO *cinfo" +.Fc +.Ft int +.Fo PEM_do_header +.Fa "EVP_CIPHER_INFO *cinfo" +.Fa "unsigned char *data" +.Fa "long *len" +.Fa "pem_password_cb *cb" +.Fa "void *userdata" +.Fc +.Ft int +.Fo PEM_def_callback +.Fa "char *password" +.Fa "int size" +.Fa "int verify" +.Fa "void *userdata" +.Fc +.Ft typedef int +.Fo pem_password_cb +.Fa "char *password" +.Fa "int size" +.Fa "int verify" +.Fa "void *userdata" +.Fc +.Sh DESCRIPTION +These functions read and write PEM-encoded objects, using the PEM type +.Fa name , +any additional +.Fa header +information, and the raw +.Fa data +of length +.Fa len . +.Pp +PEM is the binary content encoding first defined in IETF RFC 1421. +The content is a series of base64-encoded lines, surrounded by +begin/end markers each on their own line. +For example: +.Bd -literal -offset indent +-----BEGIN PRIVATE KEY----- +MIICdg.... +\&... bhTQ== +-----END PRIVATE KEY----- +.Ed +.Pp +Optional header line(s) may appear after the begin line, and their +existence depends on the type of object being written or read. +.Pp +.Fn PEM_write +writes to the file +.Fa fp , +while +.Fn PEM_write_bio +writes to the BIO +.Fa bp . +The +.Fa name +is the name to use in the marker, the +.Fa header +is the header value or +.Dv NULL , +and +.Fa data +and +.Fa len +specify the data and its length. +.Pp +The final +.Fa data +buffer is typically an ASN.1 object which can be decoded with the +.Fn d2i_* +function appropriate to the type +.Fa name ; +see +.Xr d2i_X509 3 +for examples. +.Pp +.Fn PEM_read +reads from the file +.Fa fp , +while +.Fn PEM_read_bio +reads from the BIO +.Fa bp . +Both skip any non-PEM data that precedes the start of the next PEM +object. +When an object is successfully retrieved, the type name from the +"----BEGIN -----" is returned via the +.Fa name +argument, any encapsulation headers are returned in +.Fa header , +and the base64-decoded content and its length are returned via +.Fa data +and +.Fa len , +respectively. +The +.Fa name , +.Fa header , +and +.Fa data +pointers should be freed by the caller when no longer needed. +.Pp +The remaining functions are deprecated because the underlying PEM +encryption format is obsolete and should be avoided. +It uses an encryption format with an OpenSSL-specific key-derivation +function, which employs MD5 with an iteration count of 1. +Instead, private keys should be stored in PKCS#8 form, with a strong +PKCS#5 v2.0 PBE; see +.Xr PEM_write_PrivateKey 3 +and +.Xr d2i_PKCS8PrivateKey_bio 3 . +.Pp +.Fn PEM_get_EVP_CIPHER_INFO +can be used to determine the +.Fa data +returned by +.Fn PEM_read +or +.Fn PEM_read_bio +is encrypted and to retrieve the associated cipher and IV. +The caller passes a pointer to a structure of type +.Vt EVP_CIPHER_INFO +via the +.Fa cinfo +argument and the +.Fa header +returned via +.Fn PEM_read +or +.Fn PEM_read_bio . +If the call is successful, 1 is returned and the cipher and IV are +stored at the address pointed to by +.Fa cinfo . +When the header is malformed or not supported or when the cipher is +unknown or some internal error happens, 0 is returned. +.Pp +.Fn PEM_do_header +can then be used to decrypt the data if the header indicates encryption. +The +.Fa cinfo +argument is a pointer to the structure initialized by a preceding call +to +.Fn PEM_get_EVP_CIPHER_INFO . +If that structure indicates the absence of encryption, +.Fn PEM_do_header +returns successfully without taking any action. +The +.Fa data +and +.Fa len +arguments are used both to pass in the encrypted data that was +returned in the same arguments from the preceding call to +.Fn PEM_read +or +.Fn PEM_read_bio +and to pass out the decrypted data. +.Pp +The callback function +.Fa cb +is used to obtain the encryption +.Fa password ; +if +.Fa cb +is +.Dv NULL , +.Fn PEM_def_callback +is used instead. +The +.Fa password +buffer needs to be at least +.Fa size +bytes long. +Unless +.Fa userdata +is +.Dv NULL , +.Fn PEM_def_callback +ignores the +.Fa verify +argument and copies the NUL-terminated byte string +.Fa userdata +to +.Fa password +without a terminating NUL byte, silently truncating the copy to at most +.Fa size +bytes. +If +.Fa userdata +is +.Dv NULL , +.Fn PEM_def_callback +instead prompts the user for the password with echoing turned off +by calling +.Xr EVP_read_pw_string_min 3 +internally. +In this case, the +.Fa size +is silently reduced to at most +.Dv BUFSIZ +and at most +.Fa size No \- 1 +bytes are accepted from the user and copied into the byte string buffer +.Fa password . +A callback function +.Fa cb +supplied by the application may use +.Fa userdata +for a different purpose than +.Fn PEM_def_callback +does, e.g., as auxiliary data to use while acquiring the password. +For example, a GUI application might pass a window handle. +If the +.Fa verify +flag is non-zero, the user is prompted twice for the password to +make typos less likely and it is checked that both inputs agree. +This flag is not set by +.Fn PEM_do_header +nor by other read functions, but it is typically set by write functions. +.Pp +If the data is a priori known to not be encrypted, then neither +.Fn PEM_get_EVP_CIPHER_INFO +nor +.Fn PEM_do_header +need to be called. +.Sh RETURN VALUES +.Fn PEM_read +and +.Fn PEM_read_bio +return 1 on success or 0 on failure. +The latter includes the case when no more PEM objects remain in the +input file. +To distinguish end of file from more serious errors, the caller +must peek at the error stack and check for +.Dv PEM_R_NO_START_LINE , +which indicates that no more PEM objects were found. +See +.Xr ERR_peek_last_error 3 +and +.Xr ERR_GET_REASON 3 . +.Pp +.Fn PEM_get_EVP_CIPHER_INFO +and +.Fn PEM_do_header +return 1 on success or 0 on failure. +The +.Fa data +is likely meaningless if these functions fail. +.Pp +.Fn PEM_def_callback +returns the number of bytes stored into +.Fa buf +or a negative value on failure, and +.Fa cb +is expected to behave in the same way. +If +.Fa userdata +is +.Dv NULL , +.Fn PEM_def_callback +fails if +.Fa num +is less than 5 +or if an error occurs trying to prompt the user for the password. +Otherwise, it fails when +.Fa num +is negative. +The details of the circumstances that cause +.Fa cb +to fail may differ. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr d2i_PKCS8PrivateKey_bio 3 , +.Xr PEM_ASN1_read 3 , +.Xr PEM_bytes_read_bio 3 , +.Xr PEM_read_bio_PrivateKey 3 , +.Xr PEM_read_SSL_SESSION 3 , +.Xr PEM_write_bio_CMS_stream 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PEM_X509_INFO_read 3 +.Sh HISTORY +.Fn PEM_write , +.Fn PEM_read , +and +.Fn PEM_do_header +appeared in SSLeay 0.4 or earlier. +.Fn PEM_get_EVP_CIPHER_INFO +first appeared in SSLeay 0.5.1. +.Fn PEM_write_bio +and +.Fn PEM_read_bio +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn PEM_def_callback +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/PEM_read_SSL_SESSION.3 b/Libraries/libressl/man/PEM_read_SSL_SESSION.3 new file mode 100644 index 000000000..3eb1414c6 --- /dev/null +++ b/Libraries/libressl/man/PEM_read_SSL_SESSION.3 @@ -0,0 +1,147 @@ +.\" $OpenBSD: PEM_read_SSL_SESSION.3,v 1.4 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL doc/man3/PEM_read_CMS.pod b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Rich Salz . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt PEM_READ_SSL_SESSION 3 +.Os +.Sh NAME +.Nm PEM_read_SSL_SESSION , +.Nm PEM_read_bio_SSL_SESSION , +.Nm PEM_write_SSL_SESSION , +.Nm PEM_write_bio_SSL_SESSION +.Nd encode and decode SSL session objects in PEM format +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_SESSION * +.Fo PEM_read_SSL_SESSION +.Fa "FILE *fp" +.Fa "SSL_SESSION **a" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft SSL_SESSION * +.Fo PEM_read_bio_SSL_SESSION +.Fa "BIO *bp" +.Fa "SSL_SESSION **a" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_SSL_SESSION +.Fa "FILE *fp" +.Fa "const SSL_SESSION *a" +.Fc +.Ft int +.Fo PEM_write_bio_SSL_SESSION +.Fa "BIO *bp" +.Fa "const SSL_SESSION *a" +.Fc +.Sh DESCRIPTION +These routines convert between local instances of ASN.1 +.Vt SSL_SESSION +objects and the PEM encoding. +.Pp +.Fn PEM_read_SSL_SESSION +reads a PEM-encoded +.Vt SSL_SESSION +object from the file +.Fa fp +and returns it. +The +.Fa cb +and +.Fa u +parameters are as described in +.Xr PEM_read_bio_PrivateKey 3 . +.Pp +.Fn PEM_read_bio_SSL_SESSION +is similar to +.Fn PEM_read_SSL_SESSION +but reads from the BIO +.Fa bp . +.Pp +.Fn PEM_write_SSL_SESSION +writes the PEM encoding of the object +.Fa a +to the file +.Fa fp . +.Pp +.Fn PEM_write_bio_SSL_SESSION +similarly writes to the BIO +.Fa bp . +.Sh RETURN VALUES +.Fn PEM_read_SSL_SESSION +and +.Fn PEM_read_bio_SSL_SESSION +return a pointer to an allocated object, which should be released by +calling +.Xr SSL_SESSION_free 3 , +or +.Dv NULL +on error. +.Pp +.Fn PEM_write_SSL_SESSION +and +.Fn PEM_write_bio_SSL_SESSION +return the number of bytes written or 0 on error. +.Sh SEE ALSO +.Xr PEM_read 3 , +.Xr ssl 3 +.Sh HISTORY +.Fn PEM_read_SSL_SESSION +and +.Fn PEM_write_SSL_SESSION +first appeared in SSLeay 0.5.2. +.Fn PEM_read_bio_SSL_SESSION +and +.Fn PEM_write_bio_SSL_SESSION +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/PEM_read_bio_PrivateKey.3 b/Libraries/libressl/man/PEM_read_bio_PrivateKey.3 new file mode 100644 index 000000000..ab703ddea --- /dev/null +++ b/Libraries/libressl/man/PEM_read_bio_PrivateKey.3 @@ -0,0 +1,1338 @@ +.\" $OpenBSD: PEM_read_bio_PrivateKey.3,v 1.21 2023/04/25 18:57:57 tb Exp $ +.\" full merge up to: +.\" OpenSSL man3/PEM_read_bio_PrivateKey.pod 18bad535 Apr 9 15:13:55 2019 +0100 +.\" OpenSSL man3/PEM_read_CMS.pod 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2001-2004, 2009, 2013-2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 25 2023 $ +.Dt PEM_READ_BIO_PRIVATEKEY 3 +.Os +.Sh NAME +.Nm PEM_read_bio_PrivateKey , +.Nm PEM_read_PrivateKey , +.Nm PEM_write_bio_PrivateKey , +.Nm PEM_write_PrivateKey , +.Nm PEM_write_bio_PKCS8PrivateKey , +.Nm PEM_write_PKCS8PrivateKey , +.Nm PEM_write_bio_PKCS8PrivateKey_nid , +.Nm PEM_write_PKCS8PrivateKey_nid , +.Nm PEM_read_bio_PKCS8 , +.Nm PEM_read_PKCS8 , +.Nm PEM_write_bio_PKCS8 , +.Nm PEM_write_PKCS8 , +.Nm PEM_read_bio_PKCS8_PRIV_KEY_INFO , +.Nm PEM_read_PKCS8_PRIV_KEY_INFO , +.Nm PEM_write_bio_PKCS8_PRIV_KEY_INFO , +.Nm PEM_write_PKCS8_PRIV_KEY_INFO , +.Nm PEM_read_bio_PUBKEY , +.Nm PEM_read_PUBKEY , +.Nm PEM_write_bio_PUBKEY , +.Nm PEM_write_PUBKEY , +.Nm PEM_read_bio_RSAPrivateKey , +.Nm PEM_read_RSAPrivateKey , +.Nm PEM_write_bio_RSAPrivateKey , +.Nm PEM_write_RSAPrivateKey , +.Nm PEM_read_bio_RSAPublicKey , +.Nm PEM_read_RSAPublicKey , +.Nm PEM_write_bio_RSAPublicKey , +.Nm PEM_write_RSAPublicKey , +.Nm PEM_read_bio_RSA_PUBKEY , +.Nm PEM_read_RSA_PUBKEY , +.Nm PEM_write_bio_RSA_PUBKEY , +.Nm PEM_write_RSA_PUBKEY , +.Nm PEM_read_bio_DSAPrivateKey , +.Nm PEM_read_DSAPrivateKey , +.Nm PEM_write_bio_DSAPrivateKey , +.Nm PEM_write_DSAPrivateKey , +.Nm PEM_read_bio_DSA_PUBKEY , +.Nm PEM_read_DSA_PUBKEY , +.Nm PEM_write_bio_DSA_PUBKEY , +.Nm PEM_write_DSA_PUBKEY , +.Nm PEM_read_bio_DSAparams , +.Nm PEM_read_DSAparams , +.Nm PEM_write_bio_DSAparams , +.Nm PEM_write_DSAparams , +.Nm PEM_read_bio_DHparams , +.Nm PEM_read_DHparams , +.Nm PEM_write_bio_DHparams , +.Nm PEM_write_DHparams , +.Nm PEM_read_bio_ECPKParameters , +.Nm PEM_read_ECPKParameters , +.Nm PEM_write_bio_ECPKParameters , +.Nm PEM_write_ECPKParameters , +.Nm PEM_read_bio_ECPrivateKey , +.Nm PEM_read_ECPrivateKey , +.Nm PEM_write_bio_ECPrivateKey , +.Nm PEM_write_ECPrivateKey , +.Nm PEM_read_bio_EC_PUBKEY , +.Nm PEM_read_EC_PUBKEY , +.Nm PEM_write_bio_EC_PUBKEY , +.Nm PEM_write_EC_PUBKEY , +.Nm PEM_read_bio_X509 , +.Nm PEM_read_X509 , +.Nm PEM_write_bio_X509 , +.Nm PEM_write_X509 , +.Nm PEM_read_bio_X509_AUX , +.Nm PEM_read_X509_AUX , +.Nm PEM_write_bio_X509_AUX , +.Nm PEM_write_X509_AUX , +.Nm PEM_read_bio_X509_REQ , +.Nm PEM_read_X509_REQ , +.Nm PEM_write_bio_X509_REQ , +.Nm PEM_write_X509_REQ , +.Nm PEM_write_bio_X509_REQ_NEW , +.Nm PEM_write_X509_REQ_NEW , +.Nm PEM_read_bio_X509_CRL , +.Nm PEM_read_X509_CRL , +.Nm PEM_write_bio_X509_CRL , +.Nm PEM_write_X509_CRL , +.Nm PEM_read_bio_PKCS7 , +.Nm PEM_read_PKCS7 , +.Nm PEM_write_bio_PKCS7 , +.Nm PEM_write_PKCS7 , +.Nm PEM_read_CMS , +.Nm PEM_read_bio_CMS , +.Nm PEM_write_CMS , +.Nm PEM_write_bio_CMS +.Nd PEM routines +.Sh SYNOPSIS +.In openssl/pem.h +.Ft EVP_PKEY * +.Fo PEM_read_bio_PrivateKey +.Fa "BIO *bp" +.Fa "EVP_PKEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EVP_PKEY * +.Fo PEM_read_PrivateKey +.Fa "FILE *fp" +.Fa "EVP_PKEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PrivateKey +.Fa "BIO *bp" +.Fa "EVP_PKEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_PrivateKey +.Fa "FILE *fp" +.Fa "EVP_PKEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PKCS8PrivateKey +.Fa "BIO *bp" +.Fa "EVP_PKEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_PKCS8PrivateKey +.Fa "FILE *fp" +.Fa "EVP_PKEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PKCS8PrivateKey_nid +.Fa "BIO *bp" +.Fa "EVP_PKEY *x" +.Fa "int nid" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_PKCS8PrivateKey_nid +.Fa "FILE *fp" +.Fa "EVP_PKEY *x" +.Fa "int nid" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft X509_SIG * +.Fo PEM_read_bio_PKCS8 +.Fa "BIO *bp" +.Fa "X509_SIG **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft X509_SIG * +.Fo PEM_read_PKCS8 +.Fa "FILE *fp" +.Fa "X509_SIG **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PKCS8 +.Fa "BIO *bp" +.Fa "X509_SIG *x" +.Fc +.Ft int +.Fo PEM_write_PKCS8 +.Fa "FILE *fp" +.Fa "X509_SIG *x" +.Fc +.Ft PKCS8_PRIV_KEY_INFO * +.Fo PEM_read_bio_PKCS8_PRIV_KEY_INFO +.Fa "BIO *bp" +.Fa "PKCS8_PRIV_KEY_INFO **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft PKCS8_PRIV_KEY_INFO * +.Fo PEM_read_PKCS8_PRIV_KEY_INFO +.Fa "FILE *fp" +.Fa "PKCS8_PRIV_KEY_INFO **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PKCS8_PRIV_KEY_INFO +.Fa "BIO *bp" +.Fa "PKCS8_PRIV_KEY_INFO *x" +.Fc +.Ft int +.Fo PEM_write_PKCS8_PRIV_KEY_INFO +.Fa "FILE *fp" +.Fa "PKCS8_PRIV_KEY_INFO *x" +.Fc +.Ft EVP_PKEY * +.Fo PEM_read_bio_PUBKEY +.Fa "BIO *bp" +.Fa "EVP_PKEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EVP_PKEY * +.Fo PEM_read_PUBKEY +.Fa "FILE *fp" +.Fa "EVP_PKEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PUBKEY +.Fa "BIO *bp" +.Fa "EVP_PKEY *x" +.Fc +.Ft int +.Fo PEM_write_PUBKEY +.Fa "FILE *fp" +.Fa "EVP_PKEY *x" +.Fc +.Ft RSA * +.Fo PEM_read_bio_RSAPrivateKey +.Fa "BIO *bp" +.Fa "RSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft RSA * +.Fo PEM_read_RSAPrivateKey +.Fa "FILE *fp" +.Fa "RSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_RSAPrivateKey +.Fa "BIO *bp" +.Fa "RSA *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_RSAPrivateKey +.Fa "FILE *fp" +.Fa "RSA *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft RSA * +.Fo PEM_read_bio_RSAPublicKey +.Fa "BIO *bp" +.Fa "RSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft RSA * +.Fo PEM_read_RSAPublicKey +.Fa "FILE *fp" +.Fa "RSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_RSAPublicKey +.Fa "BIO *bp" +.Fa "RSA *x" +.Fc +.Ft int +.Fo PEM_write_RSAPublicKey +.Fa "FILE *fp" +.Fa "RSA *x" +.Fc +.Ft RSA * +.Fo PEM_read_bio_RSA_PUBKEY +.Fa "BIO *bp" +.Fa "RSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft RSA * +.Fo PEM_read_RSA_PUBKEY +.Fa "FILE *fp" +.Fa "RSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_RSA_PUBKEY +.Fa "BIO *bp" +.Fa "RSA *x" +.Fc +.Ft int +.Fo PEM_write_RSA_PUBKEY +.Fa "FILE *fp" +.Fa "RSA *x" +.Fc +.Ft DSA * +.Fo PEM_read_bio_DSAPrivateKey +.Fa "BIO *bp" +.Fa "DSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft DSA * +.Fo PEM_read_DSAPrivateKey +.Fa "FILE *fp" +.Fa "DSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_DSAPrivateKey +.Fa "BIO *bp" +.Fa "DSA *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_DSAPrivateKey +.Fa "FILE *fp" +.Fa "DSA *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft DSA * +.Fo PEM_read_bio_DSA_PUBKEY +.Fa "BIO *bp" +.Fa "DSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft DSA * +.Fo PEM_read_DSA_PUBKEY +.Fa "FILE *fp" +.Fa "DSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_DSA_PUBKEY +.Fa "BIO *bp" +.Fa "DSA *x" +.Fc +.Ft int +.Fo PEM_write_DSA_PUBKEY +.Fa "FILE *fp" +.Fa "DSA *x" +.Fc +.Ft DSA * +.Fo PEM_read_bio_DSAparams +.Fa "BIO *bp" +.Fa "DSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft DSA * +.Fo PEM_read_DSAparams +.Fa "FILE *fp" +.Fa "DSA **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_DSAparams +.Fa "BIO *bp" +.Fa "DSA *x" +.Fc +.Ft int +.Fo PEM_write_DSAparams +.Fa "FILE *fp" +.Fa "DSA *x" +.Fc +.Ft DH * +.Fo PEM_read_bio_DHparams +.Fa "BIO *bp" +.Fa "DH **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft DH * +.Fo PEM_read_DHparams +.Fa "FILE *fp" +.Fa "DH **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_DHparams +.Fa "BIO *bp" +.Fa "DH *x" +.Fc +.Ft int +.Fo PEM_write_DHparams +.Fa "FILE *fp" +.Fa "DH *x" +.Fc +.Ft EC_GROUP * +.Fo PEM_read_bio_ECPKParameters +.Fa "BIO *bp" +.Fa "EC_GROUP **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EC_GROUP * +.Fo PEM_read_ECPKParameters +.Fa "FILE *fp" +.Fa "EC_GROUP **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_ECPKParameters +.Fa "BIO *bp" +.Fa "const EC_GROUP *x" +.Fc +.Ft int +.Fo PEM_write_ECPKParameters +.Fa "FILE *fp" +.Fa "const EC_GROUP *x" +.Fc +.Ft EC_KEY * +.Fo PEM_read_bio_ECPrivateKey +.Fa "BIO *bp" +.Fa "EC_KEY **key" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EC_KEY * +.Fo PEM_read_ECPrivateKey +.Fa "FILE *fp" +.Fa "EC_KEY **eckey" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_ECPrivateKey +.Fa "BIO *bp" +.Fa "EC_KEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_ECPrivateKey +.Fa "FILE *fp" +.Fa "EC_KEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "unsigned char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EC_KEY * +.Fo PEM_read_bio_EC_PUBKEY +.Fa "BIO *bp" +.Fa "EC_KEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EC_KEY * +.Fo PEM_read_EC_PUBKEY +.Fa "FILE *fp" +.Fa "EC_KEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_EC_PUBKEY +.Fa "BIO *bp" +.Fa "EC_KEY *x" +.Fc +.Ft int +.Fo PEM_write_EC_PUBKEY +.Fa "FILE *fp" +.Fa "EC_KEY *x" +.Fc +.Ft X509 * +.Fo PEM_read_bio_X509 +.Fa "BIO *bp" +.Fa "X509 **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft X509 * +.Fo PEM_read_X509 +.Fa "FILE *fp" +.Fa "X509 **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_X509 +.Fa "BIO *bp" +.Fa "X509 *x" +.Fc +.Ft int +.Fo PEM_write_X509 +.Fa "FILE *fp" +.Fa "X509 *x" +.Fc +.Ft X509 * +.Fo PEM_read_bio_X509_AUX +.Fa "BIO *bp" +.Fa "X509 **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft X509 * +.Fo PEM_read_X509_AUX +.Fa "FILE *fp" +.Fa "X509 **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_X509_AUX +.Fa "BIO *bp" +.Fa "X509 *x" +.Fc +.Ft int +.Fo PEM_write_X509_AUX +.Fa "FILE *fp" +.Fa "X509 *x" +.Fc +.Ft X509_REQ * +.Fo PEM_read_bio_X509_REQ +.Fa "BIO *bp" +.Fa "X509_REQ **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft X509_REQ * +.Fo PEM_read_X509_REQ +.Fa "FILE *fp" +.Fa "X509_REQ **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_X509_REQ +.Fa "BIO *bp" +.Fa "X509_REQ *x" +.Fc +.Ft int +.Fo PEM_write_X509_REQ +.Fa "FILE *fp" +.Fa "X509_REQ *x" +.Fc +.Ft int +.Fo PEM_write_bio_X509_REQ_NEW +.Fa "BIO *bp" +.Fa "X509_REQ *x" +.Fc +.Ft int +.Fo PEM_write_X509_REQ_NEW +.Fa "FILE *fp" +.Fa "X509_REQ *x" +.Fc +.Ft X509_CRL * +.Fo PEM_read_bio_X509_CRL +.Fa "BIO *bp" +.Fa "X509_CRL **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft X509_CRL * +.Fo PEM_read_X509_CRL +.Fa "FILE *fp" +.Fa "X509_CRL **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_X509_CRL +.Fa "BIO *bp" +.Fa "X509_CRL *x" +.Fc +.Ft int +.Fo PEM_write_X509_CRL +.Fa "FILE *fp" +.Fa "X509_CRL *x" +.Fc +.Ft PKCS7 * +.Fo PEM_read_bio_PKCS7 +.Fa "BIO *bp" +.Fa "PKCS7 **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft PKCS7 * +.Fo PEM_read_PKCS7 +.Fa "FILE *fp" +.Fa "PKCS7 **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_bio_PKCS7 +.Fa "BIO *bp" +.Fa "PKCS7 *x" +.Fc +.Ft int +.Fo PEM_write_PKCS7 +.Fa "FILE *fp" +.Fa "PKCS7 *x" +.Fc +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo PEM_read_CMS +.Fa "FILE *fp" +.Fa "CMS_ContentInfo **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft CMS_ContentInfo * +.Fo PEM_read_bio_CMS +.Fa "BIO *bp" +.Fa "CMS_ContentInfo **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo PEM_write_CMS +.Fa "FILE *fp" +.Fa "const CMS_ContentInfo *x" +.Fc +.Ft int +.Fo PEM_write_bio_CMS +.Fa "BIO *bp" +.Fa "const CMS_ContentInfo *x" +.Fc +.Sh DESCRIPTION +The PEM functions read or write structures in PEM format. +In this sense PEM format is simply base64-encoded data surrounded by +header lines; see +.Xr PEM_read 3 +for more details. +.Pp +For more details about the meaning of arguments see the +.Sx PEM function arguments +section. +.Pp +Each operation has four functions associated with it. +For brevity the term +.Dq Ar TYPE No functions +will be used to collectively refer to the +.Fn PEM_read_bio_TYPE , +.Fn PEM_read_TYPE , +.Fn PEM_write_bio_TYPE , +and +.Fn PEM_write_TYPE +functions. +If no set of specific functions exists for a given type, +.Xr PEM_ASN1_read 3 +can be used instead. +.Pp +The +.Sy PrivateKey +functions read or write a private key in PEM format using an +.Vt EVP_PKEY +structure. +The write routines use "traditional" private key format and can handle +both RSA and DSA private keys. +The read functions can additionally transparently handle PKCS#8 format +encrypted and unencrypted keys too. +.Pp +.Fn PEM_write_bio_PKCS8PrivateKey +and +.Fn PEM_write_PKCS8PrivateKey +write a private key in an +.Vt EVP_PKEY +structure in PKCS#8 +.Vt EncryptedPrivateKeyInfo +format using PKCS#5 v2.0 password based encryption algorithms. +The +.Fa enc +argument specifies the encryption algorithm to use: unlike all other PEM +routines, the encryption is applied at the PKCS#8 level and not in the +PEM headers. +If +.Fa enc +is +.Dv NULL , +then no encryption is used and a PKCS#8 +.Vt PrivateKeyInfo +structure is used instead. +.Pp +.Fn PEM_write_bio_PKCS8PrivateKey_nid +and +.Fn PEM_write_PKCS8PrivateKey_nid +also write out a private key as a PKCS#8 +.Vt EncryptedPrivateKeyInfo . +However they use PKCS#5 v1.5 or PKCS#12 encryption algorithms instead. +The algorithm to use is specified in the +.Fa nid +parameter and should be the NID of the corresponding OBJECT IDENTIFIER. +.Pp +The +.Sy PKCS8 +functions process an encrypted private key using an +.Vt X509_SIG +structure and the +.Xr d2i_X509_SIG 3 +function. +.Pp +The +.Sy PKCS8_PRIV_KEY_INFO +functions process a private key using a +.Vt PKCS8_PRIV_KEY_INFO +structure. +.Pp +The +.Sy PUBKEY +functions process a public key using an +.Vt EVP_PKEY +structure. +The public key is encoded as an ASN.1 +.Vt SubjectPublicKeyInfo +structure. +.Pp +The +.Sy RSAPrivateKey +functions process an RSA private key using an +.Vt RSA +structure. +They handle the same formats as the +.Sy PrivateKey +functions, but an error occurs if the private key is not RSA. +.Pp +The +.Sy RSAPublicKey +functions process an RSA public key using an +.Vt RSA +structure. +The public key is encoded using a PKCS#1 +.Vt RSAPublicKey +structure. +.Pp +The +.Sy RSA_PUBKEY +functions also process an RSA public key using an +.Vt RSA +structure. +However the public key is encoded using an ASN.1 +.Vt SubjectPublicKeyInfo +structure and an error occurs if the public key is not RSA. +.Pp +The +.Sy DSAPrivateKey +functions process a DSA private key using a +.Vt DSA +structure. +They handle the same formats as the +.Sy PrivateKey +functions but an error occurs if the private key is not DSA. +.Pp +The +.Sy DSA_PUBKEY +functions process a DSA public key using a +.Vt DSA +structure. +The public key is encoded using an ASN.1 +.Vt SubjectPublicKeyInfo +structure and an error occurs if the public key is not DSA. +.Pp +The +.Sy DSAparams +functions process DSA parameters using a +.Vt DSA +structure. +The parameters are encoded using a Dss-Parms structure as defined in RFC 2459. +.Pp +The +.Sy DHparams +functions process DH parameters using a +.Vt DH +structure. +The parameters are encoded using a PKCS#3 DHparameter structure. +.Pp +The +.Sy ECPKParameters +functions process EC parameters using an +.Vt EC_GROUP +structure and the +.Xr d2i_ECPKParameters 3 +function. +.Pp +The +.Sy ECPrivateKey +functions process an EC private key using an +.Vt EC_KEY +structure. +.Pp +The +.Sy EC_PUBKEY +functions process an EC public key using an +.Vt EC_KEY +structure. +.Pp +The +.Sy X509 +functions process an X509 certificate using an +.Vt X509 +structure. +They will also process a trusted X509 certificate but any trust settings +are discarded. +.Pp +The +.Sy X509_AUX +functions process a trusted X509 certificate using an +.Vt X509 +structure. +The +.Xr X509_check_trust 3 +manual explains how the auxiliary trust information is used. +.Pp +The +.Sy X509_REQ +and +.Sy X509_REQ_NEW +functions process a PKCS#10 certificate request using an +.Vt X509_REQ +structure. +The +.Sy X509_REQ +write functions use CERTIFICATE REQUEST in the header whereas the +.Sy X509_REQ_NEW +functions use NEW CERTIFICATE REQUEST (as required by some CAs). +The +.Sy X509_REQ +read functions will handle either form so there are no +.Sy X509_REQ_NEW +read functions. +.Pp +The +.Sy X509_CRL +functions process an X509 CRL using an +.Vt X509_CRL +structure. +.Pp +The +.Sy PKCS7 +functions process a PKCS#7 +.Vt ContentInfo +using a +.Vt PKCS7 +structure. +.Pp +The +.Sy CMS +functions process a +.Vt CMS_ContentInfo +structure. +.Pp +The old +.Sy PrivateKey +write routines are retained for compatibility. +New applications should write private keys using the +.Fn PEM_write_bio_PKCS8PrivateKey +or +.Fn PEM_write_PKCS8PrivateKey +routines because they are more secure (they use an iteration count of +2048 whereas the traditional routines use a count of 1) unless +compatibility with older versions of OpenSSL is important. +.Pp +The +.Sy PrivateKey +read routines can be used in all applications because they handle all +formats transparently. +.Ss PEM function arguments +The PEM functions have many common arguments. +.Pp +The +.Fa bp +parameter specifies the +.Vt BIO +to read from or write to. +.Pp +The +.Fa fp +parameter specifies the +.Vt FILE +pointer to read from or write to. +.Pp +The PEM read functions all take a pointer to pointer argument +.Fa x +and return a pointer of the same type. +If +.Fa x +is +.Dv NULL , +then the parameter is ignored. +If +.Fa x +is not +.Dv NULL +but +.Pf * Fa x +is +.Dv NULL , +then the structure returned will be written to +.Pf * Fa x . +If neither +.Fa x +nor +.Pf * Fa x +are +.Dv NULL , +then an attempt is made to reuse the structure at +.Pf * Fa x , +but see the +.Sx BUGS +and +.Sx EXAMPLES +sections. +Irrespective of the value of +.Fa x , +a pointer to the structure is always returned, or +.Dv NULL +if an error occurred. +.Pp +The PEM functions which write private keys take an +.Fa enc +parameter, which specifies the encryption algorithm to use. +Encryption is done at the PEM level. +If this parameter is set to +.Dv NULL , +then the private key is written in unencrypted form. +.Pp +The optional arguments +.Fa u +and +.Fa cb +are a passphrase used for encrypting a PEM structure +or a callback to obtain the passphrase; see +.Xr pem_password_cb 3 +for details. +.Pp +For the PEM write routines, if the +.Fa kstr +parameter is not +.Dv NULL , +then +.Fa klen +bytes at +.Fa kstr +are used as the passphrase and +.Fa cb +is ignored. +.Ss PEM encryption format +This old +.Sy PrivateKey +routines use a non-standard technique for encryption. +.Pp +The private key (or other data) takes the following form: +.Bd -literal -offset indent +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,3F17F5316E2BAC89 + +\&...base64 encoded data... +-----END RSA PRIVATE KEY----- +.Ed +.Pp +The line beginning with +.Dq DEK-Info +contains two comma separated pieces of information: +the encryption algorithm name as used by +.Xr EVP_get_cipherbyname 3 +and an 8-byte salt encoded as a set of hexadecimal digits. +.Pp +After this is the base64-encoded encrypted data. +.Pp +The encryption key is determined using +.Xr EVP_BytesToKey 3 , +using the salt and an iteration count of 1. +The IV used is the value of the salt and *not* the IV returned by +.Xr EVP_BytesToKey 3 . +.Sh RETURN VALUES +The read routines return either a pointer to the structure read or +.Dv NULL +if an error occurred. +.Pp +The write routines return 1 for success or 0 for failure. +.Sh EXAMPLES +Although the PEM routines take several arguments, in almost all +applications most of them are set to 0 or +.Dv NULL . +.Pp +Read a certificate in PEM format from a +.Vt BIO : +.Bd -literal -offset indent +X509 *x; +x = PEM_read_bio_X509(bp, NULL, 0, NULL); +if (x == NULL) { + /* Error */ +} +.Ed +.Pp +Alternative method: +.Bd -literal -offset indent +X509 *x = NULL; +if (!PEM_read_bio_X509(bp, &x, 0, NULL)) { + /* Error */ +} +.Ed +.Pp +Write a certificate to a +.Vt BIO : +.Bd -literal -offset indent +if (!PEM_write_bio_X509(bp, x)) { + /* Error */ +} +.Ed +.Pp +Write an unencrypted private key to a +.Vt FILE : +.Bd -literal -offset indent +if (!PEM_write_PrivateKey(fp, key, NULL, NULL, 0, 0, NULL)) { + /* Error */ +} +.Ed +.Pp +Write a private key (using traditional format) to a +.Vt BIO +using triple DES encryption; the pass phrase is prompted for: +.Bd -literal -offset indent +if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), + NULL, 0, 0, NULL)) { + /* Error */ +} +.Ed +.Pp +Write a private key (using PKCS#8 format) to a +.Vt BIO +using triple DES encryption, using the pass phrase "hello": +.Bd -literal -offset indent +if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), + NULL, 0, 0, "hello")) { + /* Error */ +} +.Ed +.Pp +Read a private key from a +.Vt BIO +using the pass phrase "hello": +.Bd -literal -offset indent +key = PEM_read_bio_PrivateKey(bp, NULL, 0, "hello"); +if (key == NULL) { + /* Error */ +} +.Ed +.Pp +Read a private key from a +.Vt BIO +using a pass phrase callback: +.Bd -literal -offset indent +key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key"); +if (key == NULL) { + /* Error */ +} +.Ed +.Pp +Skeleton pass phrase callback: +.Bd -literal -offset indent +int +pass_cb(char *buf, int size, int rwflag, void *u) +{ + char *tmp; + size_t len; + + /* We'd probably do something else if 'rwflag' is 1 */ + printf("Enter pass phrase for \e"%s\e"\en", u); + + /* + * Instead of the following line, get the passphrase + * from the user in some way. + */ + tmp = "hello"; + if (tmp == NULL) /* An error occurred. */ + return -1; + + len = strlen(tmp); + if (len == 0) /* Treat an empty passphrase as an error, too. */ + return -1; + + /* if too long, truncate */ + if (len > size) + len = size; + memcpy(buf, tmp, len); + return len; +} +.Ed +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr DSA_new 3 , +.Xr PEM_ASN1_read 3 , +.Xr PEM_bytes_read_bio 3 , +.Xr PEM_read 3 , +.Xr PEM_read_SSL_SESSION 3 , +.Xr PEM_write_bio_CMS_stream 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PEM_X509_INFO_read 3 , +.Xr RSA_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509_SIG_new 3 +.Sh HISTORY +.Fn PEM_read_X509 +and +.Fn PEM_write_X509 +appeared in SSLeay 0.4 or earlier. +.Fn PEM_read_X509_REQ , +.Fn PEM_write_X509_REQ , +.Fn PEM_read_X509_CRL , +and +.Fn PEM_write_X509_CRL +first appeared in SSLeay 0.4.4. +.Fn PEM_read_RSAPrivateKey , +.Fn PEM_write_RSAPrivateKey , +.Fn PEM_read_DHparams , +.Fn PEM_write_DHparams , +.Fn PEM_read_PKCS7 , +and +.Fn PEM_write_PKCS7 +first appeared in SSLeay 0.5.1. +.Fn PEM_read_bio_PrivateKey , +.Fn PEM_read_PrivateKey , +.Fn PEM_read_bio_RSAPrivateKey , +.Fn PEM_write_bio_RSAPrivateKey , +.Fn PEM_read_bio_DSAPrivateKey , +.Fn PEM_read_DSAPrivateKey , +.Fn PEM_write_bio_DSAPrivateKey , +.Fn PEM_write_DSAPrivateKey , +.Fn PEM_read_bio_DHparams , +.Fn PEM_write_bio_DHparams , +.Fn PEM_read_bio_X509 , +.Fn PEM_write_bio_X509 , +.Fn PEM_read_bio_X509_REQ , +.Fn PEM_write_bio_X509_REQ , +.Fn PEM_read_bio_X509_CRL , +.Fn PEM_write_bio_X509_CRL , +.Fn PEM_read_bio_PKCS7 , +and +.Fn PEM_write_bio_PKCS7 +first appeared in SSLeay 0.6.0. +.Fn PEM_write_bio_PrivateKey , +.Fn PEM_write_PrivateKey , +.Fn PEM_read_bio_DSAparams , +.Fn PEM_read_DSAparams , +.Fn PEM_write_bio_DSAparams , +and +.Fn PEM_write_DSAparams +first appeared in SSLeay 0.8.0. +.Fn PEM_read_bio_RSAPublicKey , +.Fn PEM_read_RSAPublicKey , +.Fn PEM_write_bio_RSAPublicKey , +and +.Fn PEM_write_RSAPublicKey +first appeared in SSLeay 0.8.1. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn PEM_write_bio_PKCS8PrivateKey , +.Fn PEM_write_PKCS8PrivateKey , +.Fn PEM_read_bio_PKCS8 , +.Fn PEM_read_PKCS8 , +.Fn PEM_write_bio_PKCS8 , +.Fn PEM_write_PKCS8 , +.Fn PEM_read_bio_PKCS8_PRIV_KEY_INFO , +.Fn PEM_read_PKCS8_PRIV_KEY_INFO , +.Fn PEM_write_bio_PKCS8_PRIV_KEY_INFO , +.Fn PEM_write_PKCS8_PRIV_KEY_INFO , +.Pp +.Fn PEM_write_bio_PKCS8PrivateKey_nid , +.Fn PEM_write_PKCS8PrivateKey_nid , +.Fn PEM_read_bio_PUBKEY , +.Fn PEM_read_PUBKEY , +.Fn PEM_write_bio_PUBKEY , +.Fn PEM_write_PUBKEY , +.Fn PEM_read_bio_RSA_PUBKEY , +.Fn PEM_read_RSA_PUBKEY , +.Fn PEM_write_bio_RSA_PUBKEY , +.Fn PEM_write_RSA_PUBKEY , +.Fn PEM_read_bio_DSA_PUBKEY , +.Fn PEM_read_DSA_PUBKEY , +.Fn PEM_write_bio_DSA_PUBKEY , +.Fn PEM_write_DSA_PUBKEY , +.Fn PEM_write_bio_X509_REQ_NEW , +.Fn PEM_write_X509_REQ_NEW , +.Fn PEM_read_bio_X509_AUX , +.Fn PEM_read_X509_AUX , +.Fn PEM_write_bio_X509_AUX , +and +.Fn PEM_write_X509_AUX +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn PEM_read_bio_ECPKParameters , +.Fn PEM_read_ECPKParameters , +.Fn PEM_write_bio_ECPKParameters , +.Fn PEM_write_ECPKParameters , +.Fn PEM_read_bio_ECPrivateKey , +.Fn PEM_read_ECPrivateKey , +.Fn PEM_write_bio_ECPrivateKey , +.Fn PEM_write_ECPrivateKey , +.Fn PEM_read_bio_EC_PUBKEY , +.Fn PEM_read_EC_PUBKEY , +.Fn PEM_write_bio_EC_PUBKEY , +and +.Fn PEM_write_EC_PUBKEY +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn PEM_read_CMS , +.Fn PEM_read_bio_CMS , +.Fn PEM_write_CMS , +and +.Fn PEM_write_bio_CMS +first appeared in OpenSSL 0.9.8h and have been available since +.Ox 6.7 . +.Sh CAVEATS +A frequent cause of problems is attempting to use the PEM routines like +this: +.Bd -literal -offset indent +X509 *x; +PEM_read_bio_X509(bp, &x, 0, NULL); +.Ed +.Pp +This is a bug because an attempt will be made to reuse the data at +.Fa x , +which is an uninitialised pointer. +.Pp +These functions make no assumption regarding the pass phrase received +from the password callback. +It will simply be treated as a byte sequence. +.Sh BUGS +The PEM read routines in some versions of OpenSSL will not correctly +reuse an existing structure. +Therefore +.Pp +.Dl PEM_read_bio_X509(bp, &x, 0, NULL); +.Pp +where +.Fa x +already contains a valid certificate may not work, whereas +.Bd -literal -offset indent +X509_free(x); +x = PEM_read_bio_X509(bp, NULL, 0, NULL); +.Ed +.Pp +is guaranteed to work. diff --git a/Libraries/libressl/man/PEM_write_bio_CMS_stream.3 b/Libraries/libressl/man/PEM_write_bio_CMS_stream.3 new file mode 100644 index 000000000..88adbba74 --- /dev/null +++ b/Libraries/libressl/man/PEM_write_bio_CMS_stream.3 @@ -0,0 +1,95 @@ +.\" $OpenBSD: PEM_write_bio_CMS_stream.3,v 1.6 2023/05/01 07:28:11 tb Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt PEM_WRITE_BIO_CMS_STREAM 3 +.Os +.Sh NAME +.Nm PEM_write_bio_CMS_stream +.Nd output CMS_ContentInfo structure in PEM format +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo PEM_write_bio_CMS_stream +.Fa "BIO *out" +.Fa "CMS_ContentInfo *cms" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PEM_write_bio_CMS_stream +outputs a +.Vt CMS_ContentInfo +structure in PEM format. +.Pp +It is otherwise identical to the function +.Xr SMIME_write_CMS 3 . +.Pp +This function is effectively a version of +.Xr PEM_write_bio_CMS 3 +supporting streaming. +.Sh RETURN VALUES +.Fn PEM_write_bio_CMS_stream +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_decrypt 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_sign 3 , +.Xr CMS_verify 3 , +.Xr ERR_get_error 3 , +.Xr i2d_CMS_bio_stream 3 , +.Xr PEM_write 3 , +.Xr SMIME_write_CMS 3 +.Sh HISTORY +.Fn PEM_write_bio_CMS_stream +first appeared in OpenSSL 1.0.0 +and has been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/PEM_write_bio_PKCS7_stream.3 b/Libraries/libressl/man/PEM_write_bio_PKCS7_stream.3 new file mode 100644 index 000000000..9050b8562 --- /dev/null +++ b/Libraries/libressl/man/PEM_write_bio_PKCS7_stream.3 @@ -0,0 +1,90 @@ +.\" $OpenBSD: PEM_write_bio_PKCS7_stream.3,v 1.12 2023/05/01 07:28:11 tb Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2007, 2009, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt PEM_WRITE_BIO_PKCS7_STREAM 3 +.Os +.Sh NAME +.Nm PEM_write_bio_PKCS7_stream +.Nd output PKCS7 structure in PEM format +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PEM_write_bio_PKCS7_stream +.Fa "BIO *out" +.Fa "PKCS7 *p7" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PEM_write_bio_PKCS7_stream +outputs a PKCS7 structure in PEM format. +.Pp +It is otherwise identical to the function +.Xr SMIME_write_PKCS7 3 . +.Pp +This function is effectively a version of +.Xr PEM_write_bio_PKCS7 3 +supporting streaming. +.Sh RETURN VALUES +Upon successful completion, 1 is returned; +otherwise 0 is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr i2d_PKCS7_bio_stream 3 , +.Xr PEM_write_PKCS7 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr SMIME_write_PKCS7 3 +.Sh HISTORY +.Fn PEM_write_bio_PKCS7_stream +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/PKCS12_SAFEBAG_new.3 b/Libraries/libressl/man/PKCS12_SAFEBAG_new.3 new file mode 100644 index 000000000..e7d20ea7f --- /dev/null +++ b/Libraries/libressl/man/PKCS12_SAFEBAG_new.3 @@ -0,0 +1,104 @@ +.\" $OpenBSD: PKCS12_SAFEBAG_new.3,v 1.4 2019/06/06 01:06:58 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt PKCS12_SAFEBAG_NEW 3 +.Os +.Sh NAME +.Nm PKCS12_SAFEBAG_new , +.Nm PKCS12_SAFEBAG_free , +.Nm PKCS12_BAGS_new , +.Nm PKCS12_BAGS_free +.Nd PKCS#12 container for one piece of information +.Sh SYNOPSIS +.In openssl/pkcs12.h +.Ft PKCS12_SAFEBAG * +.Fn PKCS12_SAFEBAG_new void +.Ft void +.Fn PKCS12_SAFEBAG_free "PKCS12_SAFEBAG *safebag" +.Ft PKCS12_BAGS * +.Fn PKCS12_BAGS_new void +.Ft void +.Fn PKCS12_BAGS_free "PKCS12_BAGS *bag" +.Sh DESCRIPTION +.Fn PKCS12_SAFEBAG_new +allocates and initializes an empty +.Vt PKCS12_SAFEBAG +object, representing an ASN.1 +.Vt SafeBag +structure defined in RFC 7292 section 4.2. +It can hold a pointer to a +.Vt PKCS12_BAGS +object together with a type identifier and optional attributes. +.Fn PKCS12_SAFEBAG_free +frees +.Fa safebag . +.Pp +.Fn PKCS12_BAGS_new +allocates and initializes an empty +.Vt PKCS12_BAGS +object, representing the bagValue field of an ASN.1 +.Vt SafeBag +structure. +It is used in +.Vt PKCS12_SAFEBAG +and can hold a DER-encoded X.509 certificate, +a base64-encoded SDSI certificate, +a DER-encoded X.509 CRL, +or other user-defined information. +.Pp +If an instance of +.Vt PKCS12_SAFEBAG +contains +.Vt PKCS8_PRIV_KEY_INFO , +.Vt X509_SIG , +or nested +.Vt PKCS12_SAFEBAG +objects, the respective pointers are stored directly in the +.Vt PKCS12_SAFEBAG +object rather than in the contained +.Vt PKCS12_BAGS +object as required by RFC 7292. +.Sh RETURN VALUES +.Fn PKCS12_SAFEBAG_new +and +.Fn PKCS12_BAGS_new +return the new +.Vt PKCS12_SAFEBAG +or +.Vt PKCS12_BAGS +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr PKCS12_create 3 , +.Xr PKCS12_new 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_new 3 , +.Xr X509_SIG_new 3 +.Sh STANDARDS +RFC 7292: PKCS #12: Personal Information Exchange Syntax, +section 4.2: The SafeBag Type +.Sh HISTORY +.Fn PKCS12_SAFEBAG_new , +.Fn PKCS12_SAFEBAG_free , +.Fn PKCS12_BAGS_new , +and +.Fn PKCS12_BAGS_free +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/PKCS12_create.3 b/Libraries/libressl/man/PKCS12_create.3 new file mode 100644 index 000000000..bc00d3df7 --- /dev/null +++ b/Libraries/libressl/man/PKCS12_create.3 @@ -0,0 +1,189 @@ +.\" $OpenBSD: PKCS12_create.3,v 1.12 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt PKCS12_CREATE 3 +.Os +.Sh NAME +.Nm PKCS12_create +.Nd create a PKCS#12 structure +.Sh SYNOPSIS +.In openssl/pkcs12.h +.Ft PKCS12 * +.Fo PKCS12_create +.Fa "const char *pass" +.Fa "const char *name" +.Fa "EVP_PKEY *pkey" +.Fa "X509 *cert" +.Fa "STACK_OF(X509) *ca" +.Fa "int nid_key" +.Fa "int nid_cert" +.Fa "int iter" +.Fa "int mac_iter" +.Fa "int keytype" +.Fc +.Sh DESCRIPTION +.Fn PKCS12_create +creates a PKCS#12 structure. +.Pp +.Fa pass +is the passphrase to use. +.Fa name +is the +.Sy friendlyName +to use for the supplied certificate and key. +.Fa pkey +is the private key to include in the structure and +.Fa cert +its corresponding certificates. +.Fa ca +is an optional set of certificates to also include in the structure. +.Fa pkey , +.Fa cert , +or both can be +.Dv NULL +to indicate that no key or certificate is required. +.Pp +.Fa nid_key +and +.Fa nid_cert +are the encryption algorithms that should be used for the key and +certificate, respectively. +If either +.Fa nid_key +or +.Fa nid_cert +is set to -1, no encryption will be used. +.Pp +.Fa iter +is the encryption algorithm iteration count to use and +.Fa mac_iter +is the MAC iteration count to use. +If +.Fa mac_iter +is set to -1, the MAC will be omitted entirely. +.Pp +.Fa keytype +is the type of key. +.Pp +The parameters +.Fa nid_key , +.Fa nid_cert , +.Fa iter , +.Fa mac_iter , +and +.Fa keytype +can all be set to zero and sensible defaults will be used. +.Pp +These defaults are: 40-bit RC2 encryption for certificates, triple DES +encryption for private keys, a key iteration count of +PKCS12_DEFAULT_ITER (currently 2048) and a MAC iteration count of 1. +.Pp +The default MAC iteration count is 1 in order to retain compatibility +with old software which did not interpret MAC iteration counts. +If such compatibility is not required then +.Fa mac_iter +should be set to PKCS12_DEFAULT_ITER. +.Pp +.Fa keytype +adds a flag to the store private key. +This is a non-standard extension that is only currently interpreted by +MSIE. +If set to zero, the flag is omitted; if set to +.Dv KEY_SIG , +the key can be used for signing only; and if set to +.Dv KEY_EX , +it can be used for signing and encryption. +This option was useful for old export grade software which could use +signing only keys of arbitrary size but had restrictions on the +permissible sizes of keys which could be used for encryption. +.Pp +If a certificate contains an +.Sy alias +or +.Sy keyid +then this will be used for the corresponding +.Sy friendlyName +or +.Sy localKeyID +in the PKCS12 structure. +.Sh RETURN VALUES +.Fn PKCS12_create +returns a valid +.Vt PKCS12 +structure or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr d2i_PKCS12 3 , +.Xr EVP_PKEY_add1_attr 3 , +.Xr PKCS12_new 3 , +.Xr PKCS12_newpass 3 , +.Xr PKCS12_parse 3 , +.Xr PKCS12_SAFEBAG_new 3 , +.Xr X509_keyid_set1 3 +.Sh HISTORY +.Fn PKCS12_create +first appeared in OpenSSL 0.9.3 and has been available since +.Ox 2.6 . +.Pp +Before OpenSSL 0.9.8, neither +.Fa pkey +nor +.Fa cert +were allowed to be +.Dv NULL , +and a value of -1 was not allowed for +.Fa nid_key , +.Fa nid_cert , +and +.Fa mac_iter . diff --git a/Libraries/libressl/man/PKCS12_new.3 b/Libraries/libressl/man/PKCS12_new.3 new file mode 100644 index 000000000..c7ccdb491 --- /dev/null +++ b/Libraries/libressl/man/PKCS12_new.3 @@ -0,0 +1,99 @@ +.\" $OpenBSD: PKCS12_new.3,v 1.4 2019/06/06 01:06:58 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt PKCS12_NEW 3 +.Os +.Sh NAME +.Nm PKCS12_new , +.Nm PKCS12_free , +.Nm PKCS12_MAC_DATA_new , +.Nm PKCS12_MAC_DATA_free +.Nd PKCS#12 personal information exchange (PFX) +.Sh SYNOPSIS +.In openssl/pkcs12.h +.Ft PKCS12 * +.Fn PKCS12_new void +.Ft void +.Fn PKCS12_free "PKCS12 *pfx" +.Ft PKCS12_MAC_DATA * +.Fn PKCS12_MAC_DATA_new void +.Ft void +.Fn PKCS12_MAC_DATA_free "PKCS12_MAC_DATA *mac_data" +.Sh DESCRIPTION +.Fn PKCS12_new +allocates and initializes an empty +.Vt PKCS12 +object, representing an ASN.1 +.Vt PFX +.Pq personal information exchange +structure defined in RFC 7292 section 4. +It can hold a pointer to a +.Vt PKCS7 +object described in +.Xr PKCS7_new 3 +and optionally an instance of +.Vt PKCS12_MAC_DATA +described below. +.Fn PKCS12_free +frees +.Fa pfx . +.Pp +.Fn PKCS12_MAC_DATA_new +allocates and initializes an empty +.Vt PKCS12_MAC_DATA +object, representing an ASN.1 +.Vt MacData +structure defined in RFC 7292 section 4. +It is used inside +.Vt PKCS12 +and can hold a pointer to an +.Vt X509_SIG +object described in +.Xr X509_SIG_new 3 +together with a salt value and an iteration count. +.Fn PKCS12_MAC_DATA_free +frees +.Fa mac_data . +.Sh RETURN VALUES +.Fn PKCS12_new +and +.Fn PKCS12_MAC_DATA_new +return the new +.Vt PKCS12 +or +.Vt PKCS12_MAC_DATA +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_PKCS12 3 , +.Xr PKCS12_create 3 , +.Xr PKCS12_newpass 3 , +.Xr PKCS12_parse 3 , +.Xr PKCS12_SAFEBAG_new 3 , +.Xr PKCS7_new 3 , +.Xr X509_SIG_new 3 +.Sh STANDARDS +RFC 7292: PKCS #12: Personal Information Exchange Syntax +.Sh HISTORY +.Fn PKCS12_new , +.Fn PKCS12_free , +.Fn PKCS12_MAC_DATA_new , +and +.Fn PKCS12_MAC_DATA_free +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/PKCS12_newpass.3 b/Libraries/libressl/man/PKCS12_newpass.3 new file mode 100644 index 000000000..b5642c96e --- /dev/null +++ b/Libraries/libressl/man/PKCS12_newpass.3 @@ -0,0 +1,155 @@ +.\" $OpenBSD: PKCS12_newpass.3,v 1.4 2019/06/14 13:59:32 schwarze Exp $ +.\" OpenSSL c95a8b4e May 5 14:26:26 2016 +0100 +.\" +.\" This file was written by Jeffrey Walton . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 14 2019 $ +.Dt PKCS12_NEWPASS 3 +.Os +.Sh NAME +.Nm PKCS12_newpass +.Nd change the password of a PKCS#12 structure +.Sh SYNOPSIS +.In openssl/pkcs12.h +.Ft int +.Fo PKCS12_newpass +.Fa "PKCS12 *p12" +.Fa "const char *oldpass" +.Fa "const char *newpass" +.Fc +.Sh DESCRIPTION +.Fn PKCS12_newpass +changes the password of a PKCS#12 structure. +.Pp +.Fa p12 +is a pointer to a PKCS#12 structure. +.Fa oldpass +is the existing password and +.Fa newpass +is the new password. +.Pp +If the PKCS#12 structure does not have a password, use the empty +string +.Qq \& +for +.Fa oldpass . +Passing +.Dv NULL +for +.Fa oldpass +results in a +.Fn PKCS12_newpass +failure. +.Pp +If the wrong password is used for +.Fa oldpass , +the function will fail with a MAC verification error. +In rare cases, the PKCS#12 structure does not contain a MAC: +in this case it will usually fail with a decryption padding error. +.Sh RETURN VALUES +Upon successful completion, 1 is returned; +otherwise 0 is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Sh EXAMPLES +This example loads a PKCS#12 file, changes its password, +and writes out the result to a new file. +.Bd -literal +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + FILE *fp; + PKCS12 *p12; + if (argc != 5) { + fprintf(stderr, + "Usage: pkread p12file password newpass opfile\en"); + return 1; + } + if ((fp = fopen(argv[1], "rb")) == NULL) { + fprintf(stderr, "Error opening file %s\en", argv[1]); + return 1; + } + p12 = d2i_PKCS12_fp(fp, NULL); + fclose(fp); + if (p12 == NULL) { + fprintf(stderr, "Error reading PKCS#12 file\en"); + ERR_print_errors_fp(stderr); + return 1; + } + if (PKCS12_newpass(p12, argv[2], argv[3]) == 0) { + fprintf(stderr, "Error changing password\en"); + ERR_print_errors_fp(stderr); + PKCS12_free(p12); + return 1; + } + if ((fp = fopen(argv[4], "wb")) == NULL) { + fprintf(stderr, "Error opening file %s\en", argv[4]); + PKCS12_free(p12); + return 1; + } + i2d_PKCS12_fp(fp, p12); + PKCS12_free(p12); + fclose(fp); + return 0; +} +.Ed +.Sh SEE ALSO +.Xr PKCS12_create 3 , +.Xr PKCS12_new 3 +.Sh HISTORY +.Fn PKCS12_newpass +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Sh BUGS +The password format is a NUL terminated ASCII string which is +converted to Unicode form internally. +As a result, some passwords cannot be supplied to this function. diff --git a/Libraries/libressl/man/PKCS12_parse.3 b/Libraries/libressl/man/PKCS12_parse.3 new file mode 100644 index 000000000..4e92d303c --- /dev/null +++ b/Libraries/libressl/man/PKCS12_parse.3 @@ -0,0 +1,145 @@ +.\" $OpenBSD: PKCS12_parse.3,v 1.7 2021/07/09 12:07:27 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2009 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 9 2021 $ +.Dt PKCS12_PARSE 3 +.Os +.Sh NAME +.Nm PKCS12_parse +.Nd parse a PKCS#12 structure +.Sh SYNOPSIS +.In openssl/pkcs12.h +.Ft int +.Fo PKCS12_parse +.Fa "PKCS12 *p12" +.Fa "const char *pass" +.Fa "EVP_PKEY **pkey" +.Fa "X509 **cert" +.Fa "STACK_OF(X509) **ca" +.Fc +.Sh DESCRIPTION +.Fn PKCS12_parse +parses a PKCS12 structure. +.Pp +.Fa p12 +is the +.Vt PKCS12 +structure to parse. +.Fa pass +is the passphrase to use. +If successful, the private key will be written to +.Pf * Fa pkey , +the corresponding certificate to +.Pf * Fa cert , +and any additional certificates to +.Pf * Fa ca . +.Pp +The parameters +.Fa pkey +and +.Fa cert +cannot be +.Dv NULL . +.Fa ca +can be +.Dv NULL , +in which case additional certificates will be discarded. +.Pf * Fa ca +can also be a valid STACK, in which case additional certificates are +appended to +.Pf * Fa ca . +If +.Pf * Fa ca +is +.Dv NULL , +a new STACK will be allocated. +.Pp +The +.Sy friendlyName +and +.Sy localKeyID +attributes (if present) of each certificate will be stored in the +.Fa alias +and +.Fa keyid +attributes of the +.Vt X509 +structure. +.Sh RETURN VALUES +.Fn PKCS12_parse +returns 1 for success and 0 if an error occurred. +.Pp +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_PKCS12 3 , +.Xr PKCS12_create 3 , +.Xr PKCS12_new 3 , +.Xr X509_keyid_set1 3 +.Sh HISTORY +.Fn PKCS12_parse +first appeared in OpenSSL 0.9.3 and has been available since +.Ox 2.6 . +.Sh BUGS +Only a single private key and corresponding certificate is returned by +this function. +More complex PKCS#12 files with multiple private keys will only return +the first match. +.Pp +Only +.Sy friendlyName +and +.Sy localKeyID +attributes are currently stored in certificates. +Other attributes are discarded. +.Pp +Attributes currently cannot be stored in the private key +.Vt EVP_PKEY +structure. diff --git a/Libraries/libressl/man/PKCS5_PBKDF2_HMAC.3 b/Libraries/libressl/man/PKCS5_PBKDF2_HMAC.3 new file mode 100644 index 000000000..3a448b92a --- /dev/null +++ b/Libraries/libressl/man/PKCS5_PBKDF2_HMAC.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: PKCS5_PBKDF2_HMAC.3,v 1.9 2019/06/07 20:46:25 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Jeffrey Walton . +.\" Copyright (c) 2014, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 7 2019 $ +.Dt PKCS5_PBKDF2_HMAC 3 +.Os +.Sh NAME +.Nm PKCS5_PBKDF2_HMAC , +.Nm PKCS5_PBKDF2_HMAC_SHA1 +.Nd password based derivation routines with salt and iteration count +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo PKCS5_PBKDF2_HMAC +.Fa "const char *pass" +.Fa "int passlen" +.Fa "const unsigned char *salt" +.Fa "int saltlen" +.Fa "int iter" +.Fa "const EVP_MD *digest" +.Fa "int keylen" +.Fa "unsigned char *out" +.Fc +.Ft int +.Fo PKCS5_PBKDF2_HMAC_SHA1 +.Fa "const char *pass" +.Fa "int passlen" +.Fa "const unsigned char *salt" +.Fa "int saltlen" +.Fa "int iter" +.Fa "int keylen" +.Fa "unsigned char *out" +.Fc +.Sh DESCRIPTION +.Fn PKCS5_PBKDF2_HMAC +derives a key from a password using a salt and iteration count as +specified in RFC 2898. +.Pp +.Fa pass +is the password used in the derivation of length +.Fa passlen . +.Fa pass +is an optional parameter and can be +.Dv NULL . +If +.Fa passlen +is -1, then the function will calculate the length of +.Fa pass +using +.Xr strlen 3 . +.Pp +.Fa salt +is the salt used in the derivation of length +.Fa saltlen . +If the +.Fa salt +is +.Dv NULL , +then +.Fa saltlen +must be 0. +The function will not attempt to calculate the length of the +.Fa salt +because it is not assumed to be NUL terminated. +.Pp +.Fa iter +is the iteration count and its value should be greater than or equal to 1. +RFC 2898 suggests an iteration count of at least 1000. +Any +.Fa iter +less than 1 is treated as a single iteration. +.Pp +.Fa digest +is the message digest function used in the derivation. +Values include any of the EVP_* message digests. +.Fn PKCS5_PBKDF2_HMAC_SHA1 +calls +.Fn PKCS5_PBKDF2_HMAC +with +.Xr EVP_sha1 3 . +.Pp +The derived key will be written to +.Fa out . +The size of the +.Fa out +buffer is specified via +.Fa keylen . +.Pp +A typical application of this function is to derive keying material for +an encryption algorithm from a password in the +.Fa pass , +a salt in +.Fa salt , +and an iteration count. +.Pp +Increasing the +.Fa iter +parameter slows down the algorithm which makes it harder for an attacker +to perform a brute force attack using a large number of candidate +passwords. +.Sh RETURN VALUES +.Fn PKCS5_PBKDF2_HMAC +and +.Fn PBKCS5_PBKDF2_HMAC_SHA1 +return 1 on success or 0 on error. +.Sh SEE ALSO +.Xr EVP_BytesToKey 3 , +.Xr EVP_DigestInit 3 +.Sh HISTORY +.Fn PKCS5_PBKDF2_HMAC_SHA1 +first appeared in OpenSSL 0.9.4 and has been available since +.Ox 2.6 . +.Pp +.Fn PKCS5_PBKDF2_HMAC +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/PKCS7_add_attribute.3 b/Libraries/libressl/man/PKCS7_add_attribute.3 new file mode 100644 index 000000000..4a1c350f9 --- /dev/null +++ b/Libraries/libressl/man/PKCS7_add_attribute.3 @@ -0,0 +1,365 @@ +.\" $OpenBSD: PKCS7_add_attribute.3,v 1.3 2020/06/10 11:39:12 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 10 2020 $ +.Dt PKCS7_ADD_ATTRIBUTE 3 +.Os +.Sh NAME +.Nm PKCS7_add_attribute , +.Nm PKCS7_set_attributes , +.Nm PKCS7_get_attribute , +.Nm PKCS7_add_signed_attribute , +.Nm PKCS7_set_signed_attributes , +.Nm PKCS7_get_signed_attribute , +.Nm PKCS7_add_attrib_content_type , +.Nm PKCS7_add1_attrib_digest , +.Nm PKCS7_add0_attrib_signing_time , +.Nm PKCS7_add_attrib_smimecap +.Nd attributes of SignerInfo objects +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_add_attribute +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "int nid" +.Fa "int attrtype" +.Fa "void *value" +.Fc +.Ft int +.Fo PKCS7_set_attributes +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "STACK_OF(X509_ATTRIBUTE) *sk" +.Fc +.Ft ASN1_TYPE * +.Fo PKCS7_get_attribute +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "int nid" +.Fc +.Ft int +.Fo PKCS7_add_signed_attribute +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "int nid" +.Fa "int attrtype" +.Fa "void *value" +.Fc +.Ft int +.Fo PKCS7_set_signed_attributes +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "STACK_OF(X509_ATTRIBUTE) *sk" +.Fc +.Ft ASN1_TYPE * +.Fo PKCS7_get_signed_attribute +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "int nid" +.Fc +.Ft int +.Fo PKCS7_add_attrib_content_type +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "ASN1_OBJECT *coid" +.Fc +.Ft int +.Fo PKCS7_add1_attrib_digest +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "const unsigned char *md" +.Fa "int mdlen" +.Fc +.Ft int +.Fo PKCS7_add0_attrib_signing_time +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "ASN1_TIME *t" +.Fc +.Ft int +.Fo PKCS7_add_attrib_smimecap +.Fa "PKCS7_SIGNER_INFO *si" +.Fa "STACK_OF(X509_ALGOR) *cap" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_add_attribute +appends a new attribute of type +.Fa nid +to the +.Fa unauthenticatedAttributes +list of +.Fa si , +and it adds a new ASN.1 ANY object of type +.Fa attrtype +with the given +.Fa value +to the new attribute. +Ownership of the +.Fa value +is transferred into the new attribute object, so the calling code +must not +.Xr free 3 +the +.Fa value . +If the list already contains an unauthenticated attribute of type +.Fa nid +before the call, the new attribute replaces the old one +instead of being appended to the end of the list. +.Pp +.Fn PKCS7_set_attributes +frees the +.Fa unauthenticatedAttributes +list of +.Fa si +and all the attributes contained in it and replaces it with a deep copy of +.Fa sk . +.Pp +.Fn PKCS7_get_attribute +retrieves the first ASN.1 ANY member of the attribute of type +.Fa nid +from the +.Fa unauthenticatedAttributes +list of +.Fa si . +.Pp +The behaviour of +.Fn PKCS7_add_signed_attribute , +.Fn PKCS7_set_signed_attributes , +and +.Fn PKCS7_get_signed_attribute +is identical except that they operate on the list of +.Fa authenticatedAttributes . +.Pp +The normal way to use +.Fn PKCS7_add_signed_attribute +is to first create a +.Vt SignedInfo +object with +.Xr PKCS7_sign 3 +using the +.Dv PKCS7_PARTIAL +or +.Dv PKCS7_STREAM +flag, retrieve the +.Vt PKCS7_SIGNER_INFO +object with +.Xr PKCS7_get_signer_info 3 +or add an additional one with +.Xr PKCS7_sign_add_signer 3 , +call +.Fn PKCS7_add_signed_attribute +for each desired additional attribute, then do the signing with +.Xr PKCS7_final 3 +or with another finalizing function. +.Pp +The four remaining functions are wrappers around +.Fn PKCS7_add_signed_attribute . +.Pp +.Fn PKCS7_add_attrib_content_type +sets the +.Dv NID_pkcs9_contentType +attribute to +.Fa coid , +which specifies the content type of the +.Vt ContentInfo +value to be signed. +This attribute is mandatory and automatically added by +.Xr PKCS7_sign 3 +and +.Xr PKCS7_sign_add_signer 3 +unless the +.Dv PKCS7_NOATTR +flag is present. +Objects suitable as +.Fa coid +arguments can for example be obtained with +.Xr OBJ_nid2obj 3 . +If +.Fa coid +is +.Dv NULL , +the content type defaults to +.Dv NID_pkcs7_data . +.Pp +.Fn PKCS7_add1_attrib_digest +sets or replaces the +.Dv NID_pkcs9_messageDigest +attribute, which is the message digest of the contents octets +of the DER-encoding of the content field of the +.Vt ContentInfo +value being signed, to a copy of +.Fa md , +which is assumed to be +.Fa mdlen +bytes long. +If +.Fa mdlen +is -1, then +.Fn strlen md +is used instead of +.Fa mdlen . +This attribute is mandatory and automatically added by +.Xr PKCS7_dataFinal 3 +and +.Xr PKCS7_final 3 . +.Pp +.Fn PKCS7_add0_attrib_signing_time +sets or replaces the optional +.Dv NID_pkcs9_signingTime +attribute to +.Fa t , +specifying the time at which the signer performed the signing process. +Ownership of +.Fa t +is transferred into the new attribute object, so the calling code +must not +.Xr free 3 +.Fa t . +If +.Fa t +is +.Dv NULL , +a new +.Vt ASN1_TIME +structure is allocated. +This attribute is automatically added by +.Xr PKCS7_dataFinal 3 +and +.Xr PKCS7_final 3 . +.Pp +.Fn PKCS7_add_attrib_smimecap +sets or replaces the optional +.Dv NID_SMIMECapabilities +attribute, indicating algorithms the sender is prepared to handle. +The +.Fa cap +pointer is not stored in the new attribute object and can be passed to +.Fn sk_X509_ALGOR_pop_free +after the call. +This attribute is automatically added by +.Xr PKCS7_sign 3 +and +.Xr PKCS7_sign_add_signer 3 +unless the +.Dv PKCS7_NOATTR +or +.Dv PKCS7_NOSMIMECAP +flag is present. +.Sh RETURN VALUES +.Fn PKCS7_add_attribute , +.Fn PKCS7_set_attributes , +.Fn PKCS7_add_signed_attribute , +.Fn PKCS7_set_signed_attributes , +.Fn PKCS7_add_attrib_content_type , +.Fn PKCS7_add1_attrib_digest , +.Fn PKCS7_add0_attrib_signing_time , +and +.Fn PKCS7_add_attrib_smimecap +return 1 on success or 0 on failure. +The most common reason for failure is lack of memory. +.Fn PKCS7_add_attribute +and +.Fn PKCS7_add_signed_attribute +also fail if +.Fa nid +is invalid, and +.Fn PKCS7_add_attrib_content_type +if +.Fa si +already contains an authenticated attribute of type +.Dv NID_pkcs9_contentType . +.Pp +.Fn PKCS7_get_attribute +and +.Fn PKCS7_get_signed_attribute +return an internal pointer to an ASN.1 ANY object or +.Dv NULL +on failure. +They fail if +.Fa nid +is invalid, if the respective list in +.Fa si +contains no attribute of the requested type, or if an invalid element +is found in the list before finding the attribute of the requested type. +.Sh SEE ALSO +.Xr ASN1_TIME_new 3 , +.Xr ASN1_TYPE_new 3 , +.Xr OBJ_nid2obj 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_get_signer_info 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 , +.Xr PKCS7_sign_add_signer 3 , +.Xr STACK_OF 3 , +.Xr X509_ALGOR_new 3 , +.Xr X509_ATTRIBUTE_new 3 +.Sh STANDARDS +RFC 2315: PKCS #7: Cryptographic Message Syntax Version 1.5, +section 9.2: SignerInfo type +.Pp +RFC 2985: PKCS #9: Selected Object Classes and Attribute Types Version 2.0, +section 5.3: Attribute types for use in PKCS #7 data +and section 5.6: Attributes defined in S/MIME +.Pp +RFC 8551: Secure/Multipurpose Internet Mail Extensions (S/MIME) +Version 4.0 Message Specification, +section 2.5.2: SMIMECapabilities Attribute +.Sh HISTORY +.Fn PKCS7_add_attribute , +.Fn PKCS7_set_attributes , +.Fn PKCS7_get_attribute , +.Fn PKCS7_add_signed_attribute , +.Fn PKCS7_set_signed_attributes , +and +.Fn PKCS7_get_signed_attribute +first appeared in OpenSSL 0.9.1 and have been available since +.Ox 2.6 . +.Pp +.Fn PKCS7_add_attrib_smimecap +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn PKCS7_add_attrib_content_type , +.Fn PKCS7_add1_attrib_digest , +and +.Fn PKCS7_add0_attrib_signing_time +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Sh CAVEATS +.Fn PKCS7_set_signed_attributes +does not validate that +.Fa sk +contains the PKCS #9 content type and message digest attributes +required by RFC 2315. +It succeeds even when +.Fa sk +is empty, leaving +.Fa si +in a state that violates the standard. +.Pp +.Fn PKCS7_add0_attrib_signing_time +does not validate +.Fa t +in any way. +In particular, it may set the signing time to the future +or to the remote past. +.Sh BUGS +A function to remove individual attributes from these lists +does not appear to exist. +A program desiring to do that might have to manually iterate the fields +.Fa auth_attr +and +.Fa unauth_attr +of +.Fa si , +which are both of type +.Vt STACK_OF(X509_ATTRIBUTE) , +using the facilities described in +.Xr STACK_OF 3 +and +.Xr OPENSSL_sk_new 3 . diff --git a/Libraries/libressl/man/PKCS7_dataFinal.3 b/Libraries/libressl/man/PKCS7_dataFinal.3 new file mode 100644 index 000000000..1a01b2ff6 --- /dev/null +++ b/Libraries/libressl/man/PKCS7_dataFinal.3 @@ -0,0 +1,158 @@ +.\" $OpenBSD: PKCS7_dataFinal.3,v 1.3 2022/12/26 07:18:52 jmc Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 26 2022 $ +.Dt PKCS7_DATAFINAL 3 +.Os +.Sh NAME +.Nm PKCS7_dataFinal +.Nd move data from a BIO chain to a ContentInfo object +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_dataFinal +.Fa "PKCS7 *p7" +.Fa "BIO *chain" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_dataFinal +transfers the data from the memory BIO at the end of the given +.Fa chain +into the appropriate content field of +.Fa p7 +itself or of its appropriate substructure. +It is typically used as the final step of populating +.Fa p7 , +after creating the +.Fa chain +with +.Xr PKCS7_dataInit 3 +and after writing the data into it. +.Pp +After calling +.Fn PKCS7_dataFinal , +the program can call +.Xr BIO_free_all 3 +on the +.Fa chain +because such chains are not designed for reuse. +.Pp +Depending on the +.Fa contentType +of +.Fa p7 , +.Fn PKCS7_dataFinal +sets the following fields: +.Bl -tag -width Ds +.It for Vt SignedData No or Vt DigestedData : +in substructures of the +.Fa content +field of +.Fa p7 : +the +.Fa content +field in the +.Vt ContentInfo +structure (unless +.Fa p7 +is configured to store a detached signature) and the +.Fa encryptedDigest +fields in all the +.Vt SignerInfo +structures +.It for Vt EnvelopedData No or Vt SignedAndEnvelopedData : +the +.Fa encryptedContent +field in the +.Vt EncryptedContentInfo +structure contained in the +.Fa content +field of +.Fa p7 +.It for arbitrary data : +the +.Fa content +field of +.Fa p7 +itself +.El +.Sh RETURN VALUES +.Fn PKCS7_dataFinal +returns 1 on success or 0 on failure. +.Pp +Possible reasons for failure include: +.Pp +.Bl -dash -compact -offset 2n -width 1n +.It +.Fa p7 +is +.Dv NULL . +.It +The +.Fa content +field of +.Fa p7 +is empty. +.It +The +.Fa contentType +of +.Fa p7 +is unsupported. +.It +The +.Fa chain +does not contain the expected memory BIO. +.It +Signing or digesting is requested and +.Fa p7 +is not configured to store a detached signature, +but does not contain the required field to store the content either. +.It +At least one signer lacks a usable digest algorithm. +.It +Signing or digesting fails. +.It +Memory allocation fails. +.El +.Pp +Signers lacking private keys do not cause failure +but are silently skipped. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr PKCS7_dataInit 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 +.Sh HISTORY +.Fn PKCS7_dataFinal +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . +.Sh CAVEATS +This function does not support +.Vt EncryptedData . +.Pp +Even though this function is typically used after +.Xr PKCS7_dataInit 3 +and even though +.Xr PKCS7_dataInit 3 +also supports reading from +.Vt ContentInfo +structures that are already fully populated, do not use +.Fn PKCS7_dataFinal +on fully populated structures. +It is only intended for putting data into new structures +and it is neither needed nor suitable for reading. diff --git a/Libraries/libressl/man/PKCS7_dataInit.3 b/Libraries/libressl/man/PKCS7_dataInit.3 new file mode 100644 index 000000000..cb54d3f95 --- /dev/null +++ b/Libraries/libressl/man/PKCS7_dataInit.3 @@ -0,0 +1,226 @@ +.\" $OpenBSD: PKCS7_dataInit.3,v 1.2 2020/06/03 13:41:27 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 3 2020 $ +.Dt PKCS7_DATAINIT 3 +.Os +.Sh NAME +.Nm PKCS7_dataInit +.Nd construct a BIO chain for adding or retrieving content +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft BIO * +.Fo PKCS7_dataInit +.Fa "PKCS7 *p7" +.Fa "BIO *indata" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_dataInit +constructs a BIO chain in preparation for putting data into +or retrieving data out of +.Fa p7 . +Depending on the +.Fa contentType +of +.Fa p7 , +the created chain starts with: +.Bl -tag -width Ds +.It for Vt SignedData : +one or more +.Xr BIO_f_md 3 +message digest filters +.It for Vt EnvelopedData : +one +.Xr BIO_f_cipher 3 +encryption filter +.It for Vt SignedAndEnvelopedData : +one or more +.Xr BIO_f_md 3 +message digest filters followed by one +.Xr BIO_f_cipher 3 +encryption filter +.It for Vt DigestedData : +one +.Xr BIO_f_md 3 +message digest filter +.It for arbitrary data : +no filter BIO +.El +.Pp +One additional BIO is appended to the end of the chain, +depending on the first condition that holds in the following list: +.Bl -tag -width Ds +.It Fa indata +if the +.Fa indata +argument is not +.Dv NULL . +This only makes sense while verifying a detached signature, in which case +.Fa indata +is expected to supply the content associated with the detached signature. +.It Xr BIO_s_null 3 +if the +.Fa contentType +of +.Fa p7 +is +.Vt SignedData +and it is configured to contain a detached signature. +This only makes sense while creating the detached signature. +.It Xr BIO_new_mem_buf 3 +when reading from a +.Vt SignedData +or +.Vt DigestedData +object. +.Fn PKCS7_dataInit +attaches the end of the chain to the nested content of +.Fa p7 . +.It Xr BIO_s_mem 3 +otherwise. +This is the most common case while writing data to +.Fa p7 . +.Xr PKCS7_dataFinal 3 +can later be used to transfer the data from the memory BIO into +.Fa p7 . +.El +.Ss Adding content +Before calling +.Fn PKCS7_dataInit +in order to add content, +.Xr PKCS7_new 3 , +.Xr PKCS7_set_type 3 , +and +.Xr PKCS7_content_new 3 +are typically required to create +.Fa p7 , +to choose its desired type, and to allocate the nested +.Vt ContentInfo +structure. +Alternatively, for +.Vt SignedData , +.Xr PKCS7_sign 3 +can be used with the +.Dv PKCS7_PARTIAL +or +.Dv PKCS7_STREAM +.Fa flags +or for +.Vt EnvelopedData , +.Xr PKCS7_encrypt 3 +with the +.Dv PKCS7_STREAM +flag. +.Pp +After calling +.Fn PKCS7_dataInit , +the desired data can be written into the returned +.Vt BIO , +.Xr BIO_flush 3 +can be called on it, +.Xr PKCS7_dataFinal 3 +can be used to transfer the processed data +from the returned memory BIO to the +.Fa p7 +structure, and the chain can finally be destroyed with +.Xr BIO_free_all 3 . +.Pp +While +.Fn PKCS7_dataInit +does support the +.Vt EnvelopedData +and +.Vt SignedAndEnvelopedData +types, using it for these types is awkward and error prone +except when using +.Xr PKCS7_encrypt 3 +for the setup because +.Xr PKCS7_content_new 3 +does not support these two types. +So in addition to creating +.Fa p7 +itself and setting its type, the nested +.Fa ContentInfo +structure also needs to be constructed with +.Xr PKCS7_new 3 +and +.Xr PKCS7_set_type 3 +and manually inserted into the correct field +of the respective sub-structure of +.Fa p7 . +.Ss Retrieving content +.Fn PKCS7_dataInit +can also be called on a fully populated object of type +.Vt SignedData +or +.Vt DigestedData . +After that, +.Xr BIO_read 3 +can be used to retrieve data from it. +In this use case, do not call +.Xr PKCS7_dataFinal 3 ; +simply proceed directly to +.Xr BIO_free_all 3 +after reading the data. +.Sh RETURN VALUES +.Fn PKCS7_dataInit +returns a BIO chain on success or +.Dv NULL +on failure. +It fails if +.Fa p7 +is +.Dv NULL , +if the +.Fa content +field of +.Fa p7 +is empty, if the +.Fa contentType +of +.Fa p7 +is unsupported, if a cipher is required but none is configured, or +if any required operation fails, for example due to lack of memory +or for various other reasons. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr BIO_read 3 , +.Xr PKCS7_content_new 3 , +.Xr PKCS7_dataFinal 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_set_type 3 , +.Xr PKCS7_sign 3 +.Sh HISTORY +.Fn PKCS7_dataInit +first appeared in SSLeay 0.8.1 and has been available since +.Ox 2.4 . +.Sh CAVEATS +This function does not support +.Vt EncryptedData . +.Sh BUGS +If +.Fa p7 +is a fully populated structure containing +.Vt EnvelopedData , +.Vt SignedAndEnvelopedData , +or arbitrary data, +.Fn PKCS7_dataInit +returns a BIO chain that ultimately reads from an empty memory BIO, +so reading from it will instantly return an end-of-file indication +rather than reading the actual data contained in +.Fa p7 . diff --git a/Libraries/libressl/man/PKCS7_decrypt.3 b/Libraries/libressl/man/PKCS7_decrypt.3 new file mode 100644 index 000000000..8d00499b5 --- /dev/null +++ b/Libraries/libressl/man/PKCS7_decrypt.3 @@ -0,0 +1,118 @@ +.\" $OpenBSD: PKCS7_decrypt.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt PKCS7_DECRYPT 3 +.Os +.Sh NAME +.Nm PKCS7_decrypt +.Nd decrypt content from a PKCS#7 envelopedData structure +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_decrypt +.Fa "PKCS7 *p7" +.Fa "EVP_PKEY *pkey" +.Fa "X509 *cert" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_decrypt +extracts and decrypts the content from a PKCS#7 envelopedData structure. +.Fa pkey +is the private key of the recipient, +.Fa cert +is the recipient's certificate, +.Fa data +is a +.Vt BIO +to write the content to and +.Fa flags +is an optional set of flags. +.Pp +Although the recipient's certificate is not needed to decrypt the data, +it is needed to locate the appropriate recipients +in the PKCS#7 structure. +.Pp +If the +.Dv PKCS7_TEXT +.Fa flag +is set, MIME headers for type +.Sy text/plain +are deleted from the content. +If the content is not of type +.Sy text/plain , +an error is returned. +.Sh RETURN VALUES +.Fn PKCS7_decrypt +returns 1 for success or 0 for failure. +.Pp +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_verify 3 +.Sh HISTORY +.Fn PKCS7_decrypt +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Sh BUGS +.Fn PKCS7_decrypt +must be passed the correct recipient key and certificate. +It would be better if it could look up the correct key and certificate +from a database. +.Pp +The lack of single pass processing and need to hold all data in memory +as mentioned in +.Xr PKCS7_sign 3 +also applies to +.Fn PKCS7_decrypt . diff --git a/Libraries/libressl/man/PKCS7_encrypt.3 b/Libraries/libressl/man/PKCS7_encrypt.3 new file mode 100644 index 000000000..700498a1d --- /dev/null +++ b/Libraries/libressl/man/PKCS7_encrypt.3 @@ -0,0 +1,169 @@ +.\" $OpenBSD: PKCS7_encrypt.3,v 1.11 2020/06/03 13:41:27 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006, 2007, 2008, 2009 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 3 2020 $ +.Dt PKCS7_ENCRYPT 3 +.Os +.Sh NAME +.Nm PKCS7_encrypt +.Nd create a PKCS#7 envelopedData structure +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft PKCS7 * +.Fo PKCS7_encrypt +.Fa "STACK_OF(X509) *certs" +.Fa "BIO *in" +.Fa "const EVP_CIPHER *cipher" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_encrypt +creates and returns a PKCS#7 envelopedData structure. +.Fa certs +is a list of recipient certificates. +.Fa in +is the content to be encrypted. +.Fa cipher +is the symmetric cipher to use. +.Fa flags +is an optional set of flags. +.Pp +Only RSA keys are supported in PKCS#7 and envelopedData so the recipient +certificates supplied to this function must all contain RSA public keys, +though they do not have to be signed using the RSA algorithm. +.Pp +The algorithm passed in the +.Fa cipher +parameter must support ASN.1 encoding of its parameters. +.Pp +Many browsers implement a "sign and encrypt" option which is simply an +S/MIME envelopedData containing an S/MIME signed message. +This can be readily produced by storing the S/MIME signed message in a +memory +.Vt BIO +and passing it to +.Fn PKCS7_encrypt . +.Pp +The following flags can be passed in the +.Fa flags +parameter. +.Pp +If the +.Dv PKCS7_TEXT +flag is set, MIME headers for type +.Sy text/plain +are prepended to the data. +.Pp +Normally the supplied content is translated into MIME canonical format +(as required by the S/MIME specifications). +If +.Dv PKCS7_BINARY +is set, no translation occurs. +This option should be used if the supplied data is in binary format; +otherwise, the translation will corrupt it. +If +.Dv PKCS7_BINARY +is set, then +.Dv PKCS7_TEXT +is ignored. +.Pp +If the +.Dv PKCS7_STREAM +flag is set, a partial +.Vt PKCS7 +structure is output suitable for streaming I/O: no data is read from +.Fa in . +.Pp +If the flag +.Dv PKCS7_STREAM +is set, the returned +.Vt PKCS7 +structure is +.Sy not +complete and outputting its contents via a function that does not +properly finalize the +.Vt PKCS7 +structure will give unpredictable results. +.Pp +Several functions including +.Xr PKCS7_final 3 , +.Xr SMIME_write_PKCS7 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +and +.Xr i2d_PKCS7_bio_stream 3 +finalize the structure. +Alternatively finalization can be performed by obtaining the streaming +ASN.1 +.Vt BIO +directly using +.Fn BIO_new_PKCS7 . +.Sh RETURN VALUES +.Fn PKCS7_encrypt +returns either a +.Vt PKCS7 +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr PKCS7_decrypt 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 +.Sh HISTORY +.Fn PKCS7_encrypt +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +The +.Dv PKCS7_STREAM +flag was first supported in OpenSSL 1.0.0. diff --git a/Libraries/libressl/man/PKCS7_final.3 b/Libraries/libressl/man/PKCS7_final.3 new file mode 100644 index 000000000..775b84d98 --- /dev/null +++ b/Libraries/libressl/man/PKCS7_final.3 @@ -0,0 +1,202 @@ +.\" $OpenBSD: PKCS7_final.3,v 1.3 2022/12/26 07:18:52 jmc Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 26 2022 $ +.Dt PKCS7_FINAL 3 +.Os +.Sh NAME +.Nm PKCS7_final +.Nd read data from a BIO into a ContentInfo object +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_final +.Fa "PKCS7 *p7" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_final +reads +.Fa data +and puts it into the appropriate content field of +.Fa p7 +itself or of its appropriate substructure, which can be of type +.Vt SignedData , +.Vt EnvelopedData , +.Vt SignedAndEnvelopedData , +.Vt DigestedData , +or arbitrary data. +The +.Xr PKCS7_dataFinal 3 +manual explains which field exactly the data is put into. +.Pp +The following +.Fa flags +are recognized: +.Bl -tag -width PKCS7_BINARY +.It Dv PKCS7_BINARY +Copy the data verbatim without changing any bytes. +By default, line endings are replaced with two-byte +.Qq \er\en +sequences (ASCII CR+LF). +If this flag is set, +.Dv PKCS7_TEXT +is ignored. +.It Dv PKCS7_TEXT +Prepend +.Qq Content-Type: text/plain +followed by a blank line to the data. +This flag is ignored if +.Dv PKCS7_BINARY +is also set. +.El +.Pp +If any other bits are set in +.Fa flags , +for example +.Dv PKCS7_STREAM +or +.Dv PKCS7_PARTIAL , +they are ignored, allowing to pass the same +.Fa flags +argument that was already passed to +.Xr PKCS7_sign 3 +or +.Xr PKCS7_encrypt 3 . +.Pp +.Fn PKCS7_final +is most commonly used to finalize a +.Fa p7 +object returned from a call to +.Xr PKCS7_sign 3 +that used +.Fa flags +including +.Dv PKCS7_PARTIAL +or +.Dv PKCS7_STREAM . +With these flags, +.Xr PKCS7_sign 3 +ignores its +.Fa data +argument. +The partial +.Fa p7 +object returned can then be customized, for example setting up +multiple signers or non-default digest algorithms with +.Xr PKCS7_sign_add_signer 3 , +before calling +.Fn PKCS7_final . +.Pp +Similarly, +.Fn PKCS7_final +can be used to finalize a +.Fa p7 +object returned from a call to +.Xr PKCS7_encrypt 3 +that used +.Fa flags +including +.Dv PKCS7_STREAM . +.Pp +Since +.Fn PKCS7_final +starts by calling +.Xr PKCS7_dataInit 3 +internally, using it to finalize a +.Fa p7 +object containing +.Vt SignedAndEnvelopedData , +.Vt DigestedData , +or arbitrary data requires the setup described in the +.Xr PKCS7_dataInit 3 +manual. +For +.Vt SignedData +and +.Vt EnvelopedData , +such manual setup is also feasible, but it is more easily performed with +.Xr PKCS7_sign 3 +or +.Xr PKCS7_encrypt 3 , +respectively. +.Pp +.Fn PKCS7_final +is only one among several functions that can be used to finalize +.Fa p7 ; +alternatives include +.Xr SMIME_write_PKCS7 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +and +.Xr i2d_PKCS7_bio_stream 3 . +.Sh RETURN VALUES +.Fn PKCS7_final +returns 1 on success or 0 on failure. +.Pp +Possible reasons for failure include: +.Pp +.Bl -dash -compact -offset 2n -width 1n +.It +.Fa p7 +is +.Dv NULL . +.It +The +.Fa content +field of +.Fa p7 +is empty. +.It +The +.Fa contentType +of +.Fa p7 +is unsupported. +.It +Signing or digesting is requested and +.Fa p7 +is not configured to store a detached signature, but does not contain +the required field to store the content either. +.It +At least one signer lacks a usable digest algorithm. +.It +A cipher is required but none is configured. +.It +Any required operation fails, for example signing or digesting. +.It +Memory allocation fails. +.El +.Pp +Signers lacking private keys do not cause failure but are silently skipped. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr i2d_PKCS7_bio_stream 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PKCS7_add_attribute 3 , +.Xr PKCS7_dataFinal 3 , +.Xr PKCS7_dataInit 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 , +.Xr SMIME_write_PKCS7 3 +.Sh HISTORY +.Fn PKCS7_final +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh CAVEATS +This function does not support +.Vt EncryptedData . diff --git a/Libraries/libressl/man/PKCS7_get_signer_info.3 b/Libraries/libressl/man/PKCS7_get_signer_info.3 new file mode 100644 index 000000000..280f373ea --- /dev/null +++ b/Libraries/libressl/man/PKCS7_get_signer_info.3 @@ -0,0 +1,62 @@ +.\" $OpenBSD: PKCS7_get_signer_info.3,v 1.1 2020/06/10 11:43:08 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 10 2020 $ +.Dt PKCS7_GET_SIGNER_INFO 3 +.Os +.Sh NAME +.Nm PKCS7_get_signer_info +.Nd retrieve signerInfos from a SignedData object +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft STACK_OF(PKCS7_SIGNER_INFO) * +.Fn PKCS7_get_signer_info "PKCS7 *p7" +.Sh DESCRIPTION +This function retrieves the set of +.Vt SignerInfo +structures from the +.Fa signerInfos +field of +.Fa p7 . +.Pp +These can subsequently be manipulated with the functions documented in +.Xr PKCS7_add_attribute 3 . +.Sh RETURN VALUES +.Fn PKCS7_get_signer_info +returns an internal pointer to a +.Vt STACK_OF(PKCS7_SIGNER_INFO) +object or +.Dv NULL +on failure. +It fails if +.Fa p7 +is +.Dv NULL , +if it has no content, +or if it is of a type other than +.Vt SignedData +or +.Vt SignedAndEnvelopedData . +.Sh SEE ALSO +.Xr PKCS7_add_attribute 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 , +.Xr PKCS7_sign_add_signer 3 +.Sh HISTORY +.Fn PKCS7_get_signer_info +first appeared in SSLeay 0.8.1 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/PKCS7_new.3 b/Libraries/libressl/man/PKCS7_new.3 new file mode 100644 index 000000000..151261a31 --- /dev/null +++ b/Libraries/libressl/man/PKCS7_new.3 @@ -0,0 +1,269 @@ +.\" $OpenBSD: PKCS7_new.3,v 1.12 2020/06/10 11:43:08 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 10 2020 $ +.Dt PKCS7_NEW 3 +.Os +.Sh NAME +.Nm PKCS7_new , +.Nm PKCS7_free , +.Nm PKCS7_SIGNED_new , +.Nm PKCS7_SIGNED_free , +.Nm PKCS7_ENVELOPE_new , +.Nm PKCS7_ENVELOPE_free , +.Nm PKCS7_SIGN_ENVELOPE_new , +.Nm PKCS7_SIGN_ENVELOPE_free , +.Nm PKCS7_DIGEST_new , +.Nm PKCS7_DIGEST_free , +.Nm PKCS7_ENCRYPT_new , +.Nm PKCS7_ENCRYPT_free , +.Nm PKCS7_ENC_CONTENT_new , +.Nm PKCS7_ENC_CONTENT_free , +.Nm PKCS7_SIGNER_INFO_new , +.Nm PKCS7_SIGNER_INFO_free , +.Nm PKCS7_RECIP_INFO_new , +.Nm PKCS7_RECIP_INFO_free , +.Nm PKCS7_ISSUER_AND_SERIAL_new , +.Nm PKCS7_ISSUER_AND_SERIAL_free +.Nd PKCS#7 data structures +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft PKCS7 * +.Fn PKCS7_new void +.Ft void +.Fn PKCS7_free "PKCS7 *p7" +.Ft PKCS7_SIGNED * +.Fn PKCS7_SIGNED_new void +.Ft void +.Fn PKCS7_SIGNED_free "PKCS7_SIGNED *signed" +.Ft PKCS7_ENVELOPE * +.Fn PKCS7_ENVELOPE_new void +.Ft void +.Fn PKCS7_ENVELOPE_free "PKCS7_ENVELOPE *envelope" +.Ft PKCS7_SIGN_ENVELOPE * +.Fn PKCS7_SIGN_ENVELOPE_new void +.Ft void +.Fn PKCS7_SIGN_ENVELOPE_free "PKCS7_SIGN_ENVELOPE *signed_envelope" +.Ft PKCS7_DIGEST * +.Fn PKCS7_DIGEST_new void +.Ft void +.Fn PKCS7_DIGEST_free "PKCS7_DIGEST *digested" +.Ft PKCS7_ENCRYPT * +.Fn PKCS7_ENCRYPT_new void +.Ft void +.Fn PKCS7_ENCRYPT_free "PKCS7_ENCRYPT *encrypted" +.Ft PKCS7_ENC_CONTENT * +.Fn PKCS7_ENC_CONTENT_new void +.Ft void +.Fn PKCS7_ENC_CONTENT_free "PKCS7_ENC_CONTENT *content" +.Ft PKCS7_SIGNER_INFO * +.Fn PKCS7_SIGNER_INFO_new void +.Ft void +.Fn PKCS7_SIGNER_INFO_free "PKCS7_SIGNER_INFO *signer" +.Ft PKCS7_RECIP_INFO * +.Fn PKCS7_RECIP_INFO_new void +.Ft void +.Fn PKCS7_RECIP_INFO_free "PKCS7_RECIP_INFO *recip" +.Ft PKCS7_ISSUER_AND_SERIAL * +.Fn PKCS7_ISSUER_AND_SERIAL_new void +.Ft void +.Fn PKCS7_ISSUER_AND_SERIAL_free "PKCS7_ISSUER_AND_SERIAL *cert" +.Sh DESCRIPTION +PKCS#7 is an ASN.1-based format for transmitting data that has +cryptography applied to it, in particular signed and encrypted data. +.Pp +.Fn PKCS7_new +allocates and initializes an empty +.Vt PKCS7 +object, representing an ASN.1 +.Vt ContentInfo +structure defined in RFC 2315 section 7. +It is the top-level data structure able to hold any kind of content +that can be transmitted using PKCS#7. +It can be used recursively in +.Vt PKCS7_SIGNED +and +.Vt PKCS7_DIGEST +objects. +.Fn PKCS7_free +frees +.Fa p7 . +.Pp +.Fn PKCS7_SIGNED_new +allocates and initializes an empty +.Vt PKCS7_SIGNED +object, representing an ASN.1 +.Vt SignedData +structure defined in RFC 2315 section 9. +It can be used inside +.Vt PKCS7 +objects and holds any kind of content together with signatures by +zero or more signers and information about the signing algorithm +and certificates used. +.Fn PKCS7_SIGNED_free +frees +.Fa signed . +.Pp +.Fn PKCS7_ENVELOPE_new +allocates and initializes an empty +.Vt PKCS7_ENVELOPE +object, representing an ASN.1 +.Vt EnvelopedData +structure defined in RFC 2315 section 10. +It can be used inside +.Vt PKCS7 +objects and holds any kind of encrypted content together with +content-encryption keys for one or more recipients. +.Fn PKCS7_ENVELOPE_free +frees +.Fa envelope . +.Pp +.Fn PKCS7_SIGN_ENVELOPE_new +allocates and initializes an empty +.Vt PKCS7_SIGN_ENVELOPE +object, representing an ASN.1 +.Vt SignedAndEnvelopedData +structure defined in RFC 2315 section 11. +It can be used inside +.Vt PKCS7 +objects and holds any kind of encrypted content together with +signatures by one or more signers, information about the signing +algorithm and certificates used, and content-encryption keys for +one or more recipients. +.Fn PKCS7_SIGN_ENVELOPE_free +frees +.Fa signed_envelope . +.Pp +.Fn PKCS7_DIGEST_new +allocates and initializes an empty +.Vt PKCS7_DIGEST +object, representing an ASN.1 +.Vt DigestedData +structure defined in RFC 2315 section 12. +It can be used inside +.Vt PKCS7 +objects and holds any kind of content together with a message digest +for checking its integrity and information about the algorithm used. +.Fn PKCS7_DIGEST_free +frees +.Fa digested . +.Pp +.Fn PKCS7_ENCRYPT_new +allocates and initializes an empty +.Vt PKCS7_ENCRYPT +object, representing an ASN.1 +.Vt EncryptedData +structure defined in RFC 2315 section 13. +It can be used inside +.Vt PKCS7 +objects and holds any kind of encrypted content. +Keys are not included and need to be communicated separately. +.Fn PKCS7_ENCRYPT_free +frees +.Fa encrypted . +.Pp +.Fn PKCS7_ENC_CONTENT_new +allocates and initializes an empty +.Vt PKCS7_ENC_CONTENT +object, representing an ASN.1 +.Vt EncryptedContentInfo +structure defined in RFC 2315 section 10.1. +It can be used inside +.Vt PKCS7_ENVELOPE , +.Vt PKCS7_SIGN_ENVELOPE , +and +.Vt PKCS7_ENCRYPT +objects and holds encrypted content together with information about +the encryption algorithm used. +.Fn PKCS7_ENC_CONTENT_free +frees +.Fa content . +.Pp +.Fn PKCS7_SIGNER_INFO_new +allocates and initializes an empty +.Vt PKCS7_SIGNER_INFO +object, representing an ASN.1 +.Vt SignerInfo +structure defined in RFC 2315 section 9.2. +It can be used inside +.Vt PKCS7_SIGNED +and +.Vt PKCS7_SIGN_ENVELOPE +objects and holds a signature together with information about the +signer and the algorithms used. +.Fn PKCS7_SIGNER_INFO_free +frees +.Fa signer . +.Pp +.Fn PKCS7_RECIP_INFO_new +allocates and initializes an empty +.Vt PKCS7_RECIP_INFO +object, representing an ASN.1 +.Vt RecipientInfo +structure defined in RFC 2315 section 10.2. +It can be used inside +.Vt PKCS7_ENVELOPE +and +.Vt PKCS7_SIGN_ENVELOPE +objects and holds a content-encryption key together with information +about the intended recipient and the key encryption algorithm used. +.Fn PKCS7_RECIP_INFO_free +frees +.Fa recip . +.Pp +.Fn PKCS7_ISSUER_AND_SERIAL_new +allocates and initializes an empty +.Vt PKCS7_ISSUER_AND_SERIAL +object, representing an ASN.1 +.Vt IssuerAndSerialNumber +structure defined in RFC 2315 section 6.7. +It can be used inside +.Vt PKCS7_SIGNER_INFO +and +.Vt PKCS7_RECIP_INFO +objects and identifies a certificate by holding the distinguished +name of the certificate issuer and an issuer-specific certificate +serial number. +.Fn PKCS7_ISSUER_AND_SERIAL_free +frees +.Fa cert . +.Sh SEE ALSO +.Xr crypto 3 , +.Xr d2i_PKCS7 3 , +.Xr i2d_PKCS7_bio_stream 3 , +.Xr PEM_read_PKCS7 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PKCS7_add_attribute 3 , +.Xr PKCS7_dataFinal 3 , +.Xr PKCS7_dataInit 3 , +.Xr PKCS7_decrypt 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_get_signer_info 3 , +.Xr PKCS7_ISSUER_AND_SERIAL_digest 3 , +.Xr PKCS7_set_content 3 , +.Xr PKCS7_set_type 3 , +.Xr PKCS7_sign 3 , +.Xr PKCS7_sign_add_signer 3 , +.Xr PKCS7_verify 3 , +.Xr SMIME_read_PKCS7 3 , +.Xr SMIME_write_PKCS7 3 +.Sh STANDARDS +RFC 2315: PKCS #7: Cryptographic Message Syntax Version 1.5 +.Sh HISTORY +These functions first appeared in SSLeay 0.5.1 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/PKCS7_set_content.3 b/Libraries/libressl/man/PKCS7_set_content.3 new file mode 100644 index 000000000..fa057341d --- /dev/null +++ b/Libraries/libressl/man/PKCS7_set_content.3 @@ -0,0 +1,120 @@ +.\" $OpenBSD: PKCS7_set_content.3,v 1.2 2020/05/24 12:37:30 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 24 2020 $ +.Dt PKCS7_SET_CONTENT 3 +.Os +.Sh NAME +.Nm PKCS7_set_content , +.Nm PKCS7_content_new +.Nd set the nested contentInfo in a PKCS#7 structure +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_set_content +.Fa "PKCS7 *outer" +.Fa "PKCS7 *inner" +.Fc +.Ft int +.Fo PKCS7_content_new +.Fa "PKCS7 *outer" +.Fa "int inner_type" +.Fc +.Sh DESCRIPTION +If the +.Fa contentType +of the +.Fa outer +PKCS7 structure is +.Vt SignedData +or +.Vt DigestedData , +.Fn PKCS7_set_content +sets the +.Fa contentInfo +field of the +.Fa content +field of +.Fa outer +to +.Fa inner , +without copying +.Fa inner . +If there was previous +.Fa contentInfo , +it is freed rather than overwritten. +The rest of the internal state of +.Fa outer +and of its +.Fa content +remains unchanged. +.Pp +.Fn PKCS7_content_new +is similar except that it first allocates and initializes a new, empty +.Fa inner +object of the given +.Fa inner_type +using +.Xr PKCS7_new 3 +and +.Xr PKCS7_set_type 3 . +The +.Fa inner_type +can be any of the NIDs listed in the +.Xr PKCS7_set_type 3 +manual. +.Sh RETURN VALUES +These functions return 1 on success or 0 on failure. +They fail if the +.Fa contentType +of +.Fa outer +is unsupported. +.Fn PKCS7_content_new +can also fail when memory is exhausted. +In case of failure, +.Fa outer +remains unchanged. +.Sh SEE ALSO +.Xr PKCS7_dataInit 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_set_type 3 , +.Xr PKCS7_sign 3 +.Sh STANDARDS +RFC 2315: PKCS #7: Cryptographic Message Syntax Version 1.5 +.Bl -bullet -compact -offset 1n -width 1n +.It +Section 7. General syntax +.It +Section 9. Signed-data content type +.It +Section 12.\& Digested-data content type +.El +.Sh HISTORY +These functions first appeared in SSLeay 0.8.1 +and have been available since +.Ox 2.4 . +.Sh CAVEATS +Despite the function names, these functions do not set the +.Fa content +field of +.Fa outer , +but only the +.Fa contentInfo +field inside it. +The rest of the +.Fa content +remains unchanged. diff --git a/Libraries/libressl/man/PKCS7_set_type.3 b/Libraries/libressl/man/PKCS7_set_type.3 new file mode 100644 index 000000000..f414b128a --- /dev/null +++ b/Libraries/libressl/man/PKCS7_set_type.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: PKCS7_set_type.3,v 1.2 2020/05/20 11:40:26 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 20 2020 $ +.Dt PKCS7_SET_TYPE 3 +.Os +.Sh NAME +.Nm PKCS7_set_type , +.Nm PKCS7_set0_type_other +.Nd initialize type of PKCS#7 ContentInfo +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_set_type +.Fa "PKCS7 *p7" +.Fa "int type" +.Fc +.Ft int +.Fo PKCS7_set0_type_other +.Fa "PKCS7 *p7" +.Fa "int type" +.Fa "ASN1_TYPE *content" +.Fc +.Sh DESCRIPTION +These functions set the +.Fa type +of an unused +.Vt ContentInfo +structure +.Fa p7 . +.Pp +The function +.Fn PKCS7_set_type +also allocates and initializes an empty child object in +.Fa p7 . +The +.Fa type +argument can be any of these NIDs, +creating a child object of the indicated data type: +.Pp +.Bl -column NID_pkcs7_signedAndEnveloped PKCS7_SIGN_ENVELOPE n.a. -compact +.It Fa type No argument Ta data type of child Ta version +.It Dv NID_pkcs7_data Ta Vt ASN1_OCTET_STRING Ta n.a. +.It Dv NID_pkcs7_digest Ta Vt PKCS7_DIGEST Ta 0 +.It Dv NID_pkcs7_encrypted Ta Vt PKCS7_ENCRYPT Ta 0 +.It Dv NID_pkcs7_enveloped Ta Vt PKCS7_ENVELOPE Ta 0 +.It Dv NID_pkcs7_signed Ta Vt PKCS7_SIGNED Ta 1 +.It Dv NID_pkcs7_signedAndEnveloped Ta Vt PKCS7_SIGN_ENVELOPE Ta 1 +.El +.Pp +If the provided +.Fa type +is invalid, +.Fa p7 +remains unchanged and +.Fn PKCS7_set_type +fails. +.Pp +If memory allocation fails, +.Fn PKCS7_set_type +fails and +.Fa p7 +may remain in an inconsistent state. +.Pp +The function +.Fn PKCS7_set0_type_other +accepts an arbitrary NID as the +.Fa type +and also sets the +.Fa content , +neither checking it in any way nor copying it. +.Pp +For both functions, the rest of the internal state of +.Fa p7 +remains unchanged. +.Sh RETURN VALUES +The function +.Fn PKCS7_set_type +returns 1 on success or 0 on failure. +.Pp +The function +.Fn PKCS7_set0_type_other +does no error handling at all and always returns 1. +.Sh SEE ALSO +.Xr ASN1_OCTET_STRING_new 3 , +.Xr ASN1_TYPE_new 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_set_content 3 , +.Xr PKCS7_sign 3 +.Sh HISTORY +The function +.Fn PKCS7_set_type +first appeared in SSLeay 0.8.1 and +.Fn PKCS7_set0_type_other +in OpenSSL 0.9.8. +Both have been available since +.Ox 2.4 . +.Sh CAVEATS +If +.Fa p7 +has already been in use before being passed to one of these functions, +it will report success even though it leaks memory. +Later on, if other functions try to use +.Fa p7 +in its former role, they are likely to misbehave. diff --git a/Libraries/libressl/man/PKCS7_sign.3 b/Libraries/libressl/man/PKCS7_sign.3 new file mode 100644 index 000000000..37257e60f --- /dev/null +++ b/Libraries/libressl/man/PKCS7_sign.3 @@ -0,0 +1,251 @@ +.\" $OpenBSD: PKCS7_sign.3,v 1.13 2020/06/10 11:43:08 schwarze Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2003, 2006-2009, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2020 $ +.Dt PKCS7_SIGN 3 +.Os +.Sh NAME +.Nm PKCS7_sign +.Nd create a PKCS#7 signedData structure +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft PKCS7 * +.Fo PKCS7_sign +.Fa "X509 *signcert" +.Fa "EVP_PKEY *pkey" +.Fa "STACK_OF(X509) *certs" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_sign +creates and returns a PKCS#7 signedData structure. +.Fa signcert +is the certificate to sign with, +.Fa pkey +is the corresponding private key. +.Fa certs +is an optional additional set of certificates to include in the PKCS#7 +structure (for example any intermediate CAs in the chain). +.Pp +The data to be signed is read from +.Vt BIO +.Fa data . +.Pp +.Fa flags +is an optional set of flags. +.Pp +Any of the following flags (OR'ed together) can be passed in the +.Fa flags +parameter. +.Pp +Many S/MIME clients expect the signed content to include valid MIME +headers. +If the +.Dv PKCS7_TEXT +flag is set, MIME headers for type +.Sy text/plain +are prepended to the data. +.Pp +If +.Dv PKCS7_NOCERTS +is set, the signer's certificate will not be included in the PKCS7 +structure, though the signer's certificate must still be supplied in the +.Fa signcert +parameter. +This can reduce the size of the signature if the signer's certificate can +be obtained by other means: for example a previously signed message. +.Pp +The data being signed is included in the +.Vt PKCS7 +structure, unless +.Dv PKCS7_DETACHED +is set, in which case it is omitted. +This is used for PKCS7 detached signatures which are used in S/MIME +plaintext signed messages for example. +.Pp +Normally the supplied content is translated into MIME canonical format +(as required by the S/MIME specifications). +If +.Dv PKCS7_BINARY +is set, no translation occurs. +This option should be used if the supplied data is in binary format; +otherwise, the translation will corrupt it. +.Pp +The signedData structure includes several PKCS#7 authenticatedAttributes +including the signing time, the PKCS#7 content type and the supported +list of ciphers in an SMIMECapabilities attribute. +If +.Dv PKCS7_NOATTR +is set, then no authenticatedAttributes will be used. +If +.Dv PKCS7_NOSMIMECAP +is set, then just the SMIMECapabilities are omitted. +.Pp +If present, the SMIMECapabilities attribute indicates support for the +following algorithms: triple DES, 128-bit RC2, 64-bit RC2, DES +and 40-bit RC2. +If any of these algorithms is disabled then it will not be included. +.Pp +If the flags +.Dv PKCS7_STREAM +is set, then the returned +.Vt PKCS7 +structure is just initialized ready to perform the signing operation. +The signing is however +.Sy not +performed and the data to be signed is not read from the +.Fa data +parameter. +Signing is deferred until after the data has been written. +In this way data can be signed in a single pass. +.Pp +If the +.Dv PKCS7_PARTIAL +flag is set, a partial +.Vt PKCS7 +structure is output to which additional signers and capabilities can be +added before finalization. +.Pp +If the flag +.Dv PKCS7_STREAM +is set, the returned +.Vt PKCS7 +structure is +.Sy not +complete and outputting its contents via a function that does not +properly finalize the +.Vt PKCS7 +structure will give unpredictable results. +.Pp +Several functions including +.Xr PKCS7_final 3 , +.Xr SMIME_write_PKCS7 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +and +.Xr i2d_PKCS7_bio_stream 3 +finalize the structure. +Alternatively finalization can be performed by obtaining the streaming +ASN.1 +.Vt BIO +directly using +.Fn BIO_new_PKCS7 . +.Pp +If a signer is specified, it will use the default digest for the +signing algorithm. +This is +.Sy SHA1 +for both RSA and DSA keys. +.Pp +In OpenSSL 1.0.0, the +.Fa certs , +.Fa signcert , +and +.Fa pkey +parameters can all be +.Dv NULL +if the +.Dv PKCS7_PARTIAL +flag is set. +One or more signers can be added using the function +.Xr PKCS7_sign_add_signer 3 +and attributes can be added using the functions described in +.Xr PKCS7_add_attribute 3 . +.Xr PKCS7_final 3 +must also be called to finalize the structure if streaming is not +enabled. +Alternative signing digests can also be specified using this method. +.Pp +In OpenSSL 1.0.0, if +.Fa signcert +and +.Fa pkey +are +.Dv NULL , +then a certificate-only PKCS#7 structure is output. +.Pp +In versions of OpenSSL before 1.0.0 the +.Fa signcert +and +.Fa pkey +parameters must +.Sy NOT +be +.Dv NULL . +.Sh RETURN VALUES +.Fn PKCS7_sign +returns either a valid +.Vt PKCS7 +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr PKCS7_add_attribute 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_get_signer_info 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign_add_signer 3 , +.Xr PKCS7_verify 3 +.Sh HISTORY +.Fn PKCS7_sign +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +The +.Dv PKCS7_PARTIAL +and +.Dv PKCS7_STREAM +flags were added in OpenSSL 1.0.0. +.Sh BUGS +Some advanced attributes such as counter signatures are not supported. diff --git a/Libraries/libressl/man/PKCS7_sign_add_signer.3 b/Libraries/libressl/man/PKCS7_sign_add_signer.3 new file mode 100644 index 000000000..195d6388c --- /dev/null +++ b/Libraries/libressl/man/PKCS7_sign_add_signer.3 @@ -0,0 +1,187 @@ +.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.13 2020/06/10 11:43:08 schwarze Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2007, 2008, 2009, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2020 $ +.Dt PKCS7_SIGN_ADD_SIGNER 3 +.Os +.Sh NAME +.Nm PKCS7_sign_add_signer +.Nd add a signer to a SignedData structure +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft PKCS7_SIGNER_INFO * +.Fo PKCS7_sign_add_signer +.Fa "PKCS7 *p7" +.Fa "X509 *signcert" +.Fa "EVP_PKEY *pkey" +.Fa "const EVP_MD *md" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_sign_add_signer +adds a signer with certificate +.Fa signcert +and private key +.Fa pkey +using message digest +.Fa md +to a +.Vt PKCS7 +signed data structure +.Fa p7 . +.Pp +The +.Vt PKCS7 +structure should be obtained from an initial call to +.Xr PKCS7_sign 3 +with the flag +.Dv PKCS7_PARTIAL +set or, in the case or re-signing, a valid +.Vt PKCS7 +signed data structure. +.Pp +If the +.Fa md +parameter is +.Dv NULL , +then the default digest for the public key algorithm will be used. +.Pp +Unless the +.Dv PKCS7_REUSE_DIGEST +flag is set, the returned +.Dv PKCS7 +structure is not complete and must be +finalized either by streaming (if applicable) or by a call to +.Xr PKCS7_final 3 . +.Pp +The main purpose of this function is to provide finer control over a +PKCS#7 signed data structure where the simpler +.Xr PKCS7_sign 3 +function defaults are not appropriate, for example if multiple +signers or non default digest algorithms are needed. +.Pp +Any of the following flags (OR'ed together) can be passed in the +.Fa flags +parameter. +.Pp +If +.Dv PKCS7_REUSE_DIGEST +is set, then an attempt is made to copy the content digest value from the +.Vt PKCS7 +structure: to add a signer to an existing structure. +An error occurs if a matching digest value cannot be found to copy. +The returned +.Vt PKCS7 +structure will be valid and finalized when this flag is set. +.Pp +If +.Dv PKCS7_PARTIAL +is set in addition to +.Dv PKCS7_REUSE_DIGEST , +then the +.Dv PKCS7_SIGNER_INO +structure will not be finalized, so additional attributes can be added. +In this case an explicit call to +.Fn PKCS7_SIGNER_INFO_sign +is needed to finalize it. +.Pp +If +.Dv PKCS7_NOCERTS +is set, the signer's certificate will not be included in the +.Vt PKCS7 +structure, though the signer's certificate must still be supplied in the +.Fa signcert +parameter. +This can reduce the size of the signature if the signers certificate can +be obtained by other means: for example a previously signed message. +.Pp +The signedData structure includes several PKCS#7 authenticatedAttributes +including the signing time, the PKCS#7 content type and the supported +list of ciphers in an SMIMECapabilities attribute. +If +.Dv PKCS7_NOATTR +is set, then no authenticatedAttributes will be used. +If +.Dv PKCS7_NOSMIMECAP +is set, then just the SMIMECapabilities are omitted. +.Pp +If present, the SMIMECapabilities attribute indicates support for the +following algorithms: triple DES, 128-bit RC2, 64-bit RC2, DES +and 40-bit RC2. +If any of these algorithms is disabled, then it will not be included. +.Pp +.Fn PKCS7_sign_add_signer +returns an internal pointer to the +.Vt PKCS7_SIGNER_INFO +structure just added, which can be used to set additional attributes +with the functions described in +.Xr PKCS7_add_attribute 3 +before it is finalized. +.Sh RETURN VALUES +.Fn PKCS7_sign_add_signer +returns an internal pointer to the +.Vt PKCS7_SIGNER_INFO +structure just added or +.Dv NULL +if an error occurs. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr PKCS7_add_attribute 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_get_signer_info 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 +.Sh HISTORY +.Fn PKCS7_sign_add_signer +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/PKCS7_verify.3 b/Libraries/libressl/man/PKCS7_verify.3 new file mode 100644 index 000000000..d091c03df --- /dev/null +++ b/Libraries/libressl/man/PKCS7_verify.3 @@ -0,0 +1,252 @@ +.\" $OpenBSD: PKCS7_verify.3,v 1.11 2022/03/31 17:27:17 naddy Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006, 2013, 2014, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt PKCS7_VERIFY 3 +.Os +.Sh NAME +.Nm PKCS7_verify , +.Nm PKCS7_get0_signers +.Nd verify a PKCS#7 signedData structure +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_verify +.Fa "PKCS7 *p7" +.Fa "STACK_OF(X509) *certs" +.Fa "X509_STORE *store" +.Fa "BIO *indata" +.Fa "BIO *out" +.Fa "int flags" +.Fc +.Ft STACK_OF(X509) * +.Fo PKCS7_get0_signers +.Fa "PKCS7 *p7" +.Fa "STACK_OF(X509) *certs" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn PKCS7_verify +verifies a PKCS#7 signedData structure. +.Fa p7 +is the +.Vt PKCS7 +structure to verify. +.Fa certs +is a set of certificates in which to search for the signer's +certificate. +.Fa store +is a trusted certificate store (used for chain verification). +.Fa indata +is the signed data if the content is not present in +.Fa p7 , +that is if it is detached. +The content is written to +.Fa out +if it is not +.Dv NULL . +.Pp +.Fa flags +is an optional set of flags, which can be used to modify the verify +operation. +.Pp +.Fn PKCS7_get0_signers +retrieves the signer's certificates from +.Fa p7 . +The signers must be freed with +.Fn sk_X509_free . +It does +.Sy not +check their validity or whether any signatures are valid. +The +.Fa certs +and +.Fa flags +parameters have the same meanings as in +.Fn PKCS7_verify . +.Pp +Normally the verify process proceeds as follows. +.Pp +Initially some sanity checks are performed on +.Fa p7 . +The type of +.Fa p7 +must be signedData. +There must be at least one signature on the data and if the content +is detached, +.Fa indata +cannot be +.Dv NULL . +.Pp +An attempt is made to locate all the signer's certificates, first +looking in the +.Fa certs +parameter (if it is not +.Dv NULL ) +and then looking in any certificates contained in the +.Fa p7 +structure itself. +If any signer's certificates cannot be located, the operation fails. +.Pp +Each signer's certificate is chain verified using the +.Sy smimesign +purpose and the supplied trusted certificate store. +Any internal certificates in the message are used as untrusted CAs. +If any chain verify fails, an error code is returned. +.Pp +Finally, the signed content is read (and written to +.Fa out +if it is not +.Dv NULL ) +and the signature's checked. +.Pp +If all signature's verify correctly then the function is successful. +.Pp +Any of the following flags (OR'ed together) can be passed in the +.Fa flags +parameter to change the default verify behaviour. +Only the flag +.Dv PKCS7_NOINTERN +is meaningful to +.Fn PKCS7_get0_signers . +.Pp +If +.Dv PKCS7_NOINTERN +is set, the certificates in the message itself are not searched when +locating the signer's certificate. +This means that all the signer's certificates must be in the +.Fa certs +parameter. +.Pp +If the +.Dv PKCS7_TEXT +flag is set, MIME headers for type +.Sy text/plain +are deleted from the content. +If the content is not of type +.Sy text/plain , +then an error is returned. +.Pp +If +.Dv PKCS7_NOVERIFY +is set, the signer's certificates are not chain verified. +.Pp +If +.Dv PKCS7_NOCHAIN +is set, then the certificates contained in the message are not used as +untrusted CAs. +This means that the whole verify chain (apart from the signer's +certificate) must be contained in the trusted store. +.Pp +If +.Dv PKCS7_NOSIGS +is set, then the signatures on the data are not checked. +.Pp +One application of +.Dv PKCS7_NOINTERN +is to only accept messages signed by a small number of certificates. +The acceptable certificates would be passed in the +.Fa certs +parameter. +In this case, if the signer is not one of the certificates supplied in +.Fa certs , +then the verify will fail because the signer cannot be found. +.Pp +Care should be taken when modifying the default verify behaviour, for +example setting +.Dv PKCS7_NOVERIFY | PKCS7_NOSIGS +will totally disable all verification and any signed message will be +considered valid. +This combination is however useful if one merely wishes to write the +content to +.Fa out +and its validity is not considered important. +.Pp +Chain verification should arguably be performed using the signing time +rather than the current time. +However since the signing time is supplied by the signer, it cannot be +trusted without additional evidence (such as a trusted timestamp). +.Sh RETURN VALUES +.Fn PKCS7_verify +returns 1 for a successful verification and 0 or a negative value if +an error occurs. +.Pp +.Fn PKCS7_get0_signers +returns all signers or +.Dv NULL +if an error occurred. +The signers must be freed with +.Fn sk_X509_free . +.Pp +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr PKCS7_decrypt 3 , +.Xr PKCS7_new 3 , +.Xr PKCS7_sign 3 , +.Xr X509_STORE_new 3 +.Sh HISTORY +.Fn PKCS7_verify +and +.Fn PKCS7_get0_signers +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Sh BUGS +The trusted certificate store is not searched for the signer's +certificate. +This is primarily due to the inadequacies of the current +.Vt X509_STORE +functionality. +.Pp +The lack of single pass processing and the need to hold all data +in memory as mentioned in +.Xr PKCS7_sign 3 +also applies to +.Fn PKCS7_verify . diff --git a/Libraries/libressl/man/PKCS8_PRIV_KEY_INFO_new.3 b/Libraries/libressl/man/PKCS8_PRIV_KEY_INFO_new.3 new file mode 100644 index 000000000..2eb9aef05 --- /dev/null +++ b/Libraries/libressl/man/PKCS8_PRIV_KEY_INFO_new.3 @@ -0,0 +1,66 @@ +.\" $OpenBSD: PKCS8_PRIV_KEY_INFO_new.3,v 1.6 2021/10/25 13:48:12 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 25 2021 $ +.Dt PKCS8_PRIV_KEY_INFO_NEW 3 +.Os +.Sh NAME +.Nm PKCS8_PRIV_KEY_INFO_new , +.Nm PKCS8_PRIV_KEY_INFO_free +.Nd PKCS#8 private key information +.Sh SYNOPSIS +.In openssl/x509.h +.Ft PKCS8_PRIV_KEY_INFO * +.Fn PKCS8_PRIV_KEY_INFO_new void +.Ft void +.Fn PKCS8_PRIV_KEY_INFO_free "PKCS8_PRIV_KEY_INFO *key" +.Sh DESCRIPTION +.Fn PKCS8_PRIV_KEY_INFO_new +allocates and initializes an empty +.Vt PKCS8_PRIV_KEY_INFO +object, representing an ASN.1 +.Vt PrivateKeyInfo +structure defined in RFC 5208 section 5. +It can hold a private key together with information about the +algorithm to be used with it and optional attributes. +.Pp +.Fn PKCS8_PRIV_KEY_INFO_free +frees +.Fa key . +.Sh RETURN VALUES +.Fn PKCS8_PRIV_KEY_INFO_new +returns the new +.Vt PKCS8_PRIV_KEY_INFO +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_PKCS8_PRIV_KEY_INFO 3 , +.Xr d2i_PKCS8PrivateKey_bio 3 , +.Xr EVP_PKCS82PKEY 3 , +.Xr EVP_PKEY_asn1_set_private 3 , +.Xr PEM_read_PKCS8_PRIV_KEY_INFO 3 , +.Xr PKCS12_parse 3 , +.Xr PKCS8_pkey_set0 3 , +.Xr X509_ATTRIBUTE_new 3 +.Sh STANDARDS +RFC 5208: PKCS#8: Private-Key Information Syntax Specification +.Sh HISTORY +.Fn PKCS8_PRIV_KEY_INFO_new +and +.Fn PKCS8_PRIV_KEY_INFO_free +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/PKCS8_pkey_set0.3 b/Libraries/libressl/man/PKCS8_pkey_set0.3 new file mode 100644 index 000000000..975f3fbeb --- /dev/null +++ b/Libraries/libressl/man/PKCS8_pkey_set0.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: PKCS8_pkey_set0.3,v 1.2 2021/10/25 13:48:12 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 25 2021 $ +.Dt PKCS8_PKEY_SET0 3 +.Os +.Sh NAME +.Nm PKCS8_pkey_set0 , +.Nm PKCS8_pkey_get0 , +.Nm PKCS8_pkey_add1_attr_by_NID , +.Nm PKCS8_pkey_get0_attrs +.Nd change and inspect PKCS#8 PrivateKeyInfo objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo PKCS8_pkey_set0 +.Fa "PKCS8_PRIV_KEY_INFO *keyinfo" +.Fa "ASN1_OBJECT *aobj" +.Fa "int version" +.Fa "int ptype" +.Fa "void *pval" +.Fa "unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo PKCS8_pkey_get0 +.Fa "const ASN1_OBJECT **paobj" +.Fa "const unsigned char **pdata" +.Fa "int *plen" +.Fa "const X509_ALGOR **palgor" +.Fa "const PKCS8_PRIV_KEY_INFO *keyinfo" +.Fc +.Ft int +.Fo PKCS8_pkey_add1_attr_by_NID +.Fa "PKCS8_PRIV_KEY_INFO *keyinfo" +.Fa "int nid" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft const STACK_OF(X509_ATTRIBUTE) * +.Fo PKCS8_pkey_get0_attrs +.Fa "const PKCS8_PRIV_KEY_INFO *keyinfo" +.Fc +.Sh DESCRIPTION +.Fn PKCS8_pkey_set0 +initializes the +.Fa keyinfo +object. +The algorithm is set to +.Fa aobj +with the associated parameter type +.Fa ptype +and parameter value +.Fa pval +using +.Xr X509_ALGOR_set0 3 , +replacing any previous information about the algorithm. +Unless +.Fa data +is +.Dv NULL , +the encoded private key is set to the +.Fa len +bytes starting at +.Fa data +using +.Xr ASN1_STRING_set0 3 , +not performing any validation. +If +.Fa data +is +.Dv NULL , +the key data remains unchanged. +If the +.Fa version +argument is greater than or equal to 0, it replaces any existing version; +otherwise, the version remains unchanged. +If +.Fa keyinfo +contains any attributes, they remain unchanged. +.Pp +.Fn PKCS8_pkey_get0 +retrieves some information from the +.Fa keyinfo +object. +Internal pointers to the algorithm OID, the +.Vt AlgorithmIdentifier , +and the encoded private key are stored in +.Pf * Fa paobj , +.Pf * Fa palgor , +and +.Pf * Fa pdata , +respectively. +.Dv NULL +pointers can be passed for any of these three arguments if the respective +information is not needed. +Unless +.Fa pdata +is +.Dv NULL , +.Pf * Fa plen +is set to the number of bytes in +.Pf * Fa pdata . +.Pp +.Fn PKCS8_pkey_add1_attr_by_NID +creates a new X.501 Attribute object using +.Xr X509_ATTRIBUTE_create_by_NID 3 +and appends it to the attributes of +.Fa keyinfo +using +.Xr X509at_add1_attr 3 . +.Sh RETURN VALUES +.Fn PKCS8_pkey_set0 +and +.Fn PKCS8_pkey_add1_attr_by_NID +return 1 for success or 0 for failure. +.Pp +.Fn PKCS8_pkey_get0 +always returns 1. +.Pp +.Fn PKCS8_pkey_get0_attrs +returns an internal pointer to the array of attributes associated with +.Fa keyinfo +or +.Dv NULL +if no attributes are set. +.Sh SEE ALSO +.Xr ASN1_STRING_set0 3 , +.Xr EVP_PKCS82PKEY 3 , +.Xr OBJ_nid2obj 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +.Xr STACK_OF 3 , +.Xr X509_ALGOR_new 3 , +.Xr X509_ATTRIBUTE_create_by_NID 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509at_add1_attr 3 , +.Xr X509at_get_attr 3 +.Sh HISTORY +.Fn PKCS8_pkey_set0 +and +.Fn PKCS8_pkey_get0 +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn PKCS8_pkey_add1_attr_by_NID +and +.Fn PKCS8_pkey_get0_attrs +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.4 . diff --git a/Libraries/libressl/man/PKEY_USAGE_PERIOD_new.3 b/Libraries/libressl/man/PKEY_USAGE_PERIOD_new.3 new file mode 100644 index 000000000..40735c6f8 --- /dev/null +++ b/Libraries/libressl/man/PKEY_USAGE_PERIOD_new.3 @@ -0,0 +1,74 @@ +.\" $OpenBSD: PKEY_USAGE_PERIOD_new.3,v 1.5 2019/06/06 01:06:59 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt PKEY_USAGE_PERIOD_NEW 3 +.Os +.Sh NAME +.Nm PKEY_USAGE_PERIOD_new , +.Nm PKEY_USAGE_PERIOD_free +.Nd X.509 certificate private key usage period extension +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft PKEY_USAGE_PERIOD * +.Fn PKEY_USAGE_PERIOD_new void +.Ft void +.Fn PKEY_USAGE_PERIOD_free "PKEY_USAGE_PERIOD *period" +.Sh DESCRIPTION +.Fn PKEY_USAGE_PERIOD_new +allocates and initializes an empty +.Vt PKEY_USAGE_PERIOD +object, representing an ASN.1 +.Vt PrivateKeyUsagePeriod +structure defined in RFC 3280 section 4.2.1.4. +It could be used in +.Vt X509 +certificates to specify a validity period for the private key +that differed from the validity period of the certificate. +.Pp +.Fn PKEY_USAGE_PERIOD_free +frees +.Fa period . +.Sh RETURN VALUES +.Fn PKEY_USAGE_PERIOD_new +returns the new +.Vt PKEY_USAGE_PERIOD +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_PKEY_USAGE_PERIOD 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr X509_CINF_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 3280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.2.1.4: Private Key Usage Period +.Pp +RFC 3280 was obsoleted by RFC 5280, which says: "Section 4.2.1.4 +in RFC 3280, which specified the +.Vt PrivateKeyUsagePeriod +certificate extension but deprecated its use, was removed. +Use of this ISO standard extension is neither deprecated +nor recommended for use in the Internet PKI." +.Sh HISTORY +.Fn PKEY_USAGE_PERIOD_new +and +.Fn PKEY_USAGE_PERIOD_free +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/POLICYINFO_new.3 b/Libraries/libressl/man/POLICYINFO_new.3 new file mode 100644 index 000000000..52c004414 --- /dev/null +++ b/Libraries/libressl/man/POLICYINFO_new.3 @@ -0,0 +1,218 @@ +.\" $OpenBSD: POLICYINFO_new.3,v 1.11 2023/05/14 08:03:57 tb Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 14 2023 $ +.Dt POLICYINFO_NEW 3 +.Os +.Sh NAME +.Nm POLICYINFO_new , +.Nm POLICYINFO_free , +.Nm CERTIFICATEPOLICIES_new , +.Nm CERTIFICATEPOLICIES_free , +.Nm POLICYQUALINFO_new , +.Nm POLICYQUALINFO_free , +.Nm USERNOTICE_new , +.Nm USERNOTICE_free , +.Nm NOTICEREF_new , +.Nm NOTICEREF_free , +.Nm POLICY_MAPPING_new , +.Nm POLICY_MAPPING_free , +.Nm POLICY_CONSTRAINTS_new , +.Nm POLICY_CONSTRAINTS_free +.Nd X.509 certificate policies +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft POLICYINFO * +.Fn POLICYINFO_new void +.Ft void +.Fn POLICYINFO_free "POLICYINFO *pi" +.Ft CERTIFICATEPOLICIES * +.Fn CERTIFICATEPOLICIES_new void +.Ft void +.Fn CERTIFICATEPOLICIES_free "CERTIFICATEPOLICIES *pis" +.Ft POLICYQUALINFO * +.Fn POLICYQUALINFO_new void +.Ft void +.Fn POLICYQUALINFO_free "POLICYQUALINFO *pqi" +.Ft USERNOTICE * +.Fn USERNOTICE_new void +.Ft void +.Fn USERNOTICE_free "USERNOTICE *usernotice" +.Ft NOTICEREF * +.Fn NOTICEREF_new void +.Ft void +.Fn NOTICEREF_free "NOTICEREF *noticeref" +.Ft POLICY_MAPPING * +.Fn POLICY_MAPPING_new void +.Ft void +.Fn POLICY_MAPPING_free "POLICY_MAPPING *pm" +.Ft POLICY_CONSTRAINTS * +.Fn POLICY_CONSTRAINTS_new void +.Ft void +.Fn POLICY_CONSTRAINTS_free "POLICY_CONSTRAINTS *pc" +.Sh DESCRIPTION +X.509 CA and end entity certificates can optionally indicate +restrictions on their intended use. +.Pp +.Fn POLICYINFO_new +allocates and initializes an empty +.Vt POLICYINFO +object, representing an ASN.1 +.Vt PolicyInformation +structure defined in RFC 5280 section 4.2.1.4. +It can hold a policy identifier and optional advisory qualifiers. +.Fn POLICYINFO_free +frees +.Fa pi . +.Pp +.Fn CERTIFICATEPOLICIES_new +allocates and initializes an empty +.Vt CERTIFICATEPOLICIES +object, which is a +.Vt STACK_OF(POLICYINFO) +and represents an ASN.1 +.Vt CertificatePolicies +structure defined in RFC 5280 section 4.2.1.4. +It can be used by +.Vt X509 +objects, both by CA certificates and end entity certificates. +.Fn CERTIFICATEPOLICIES_free +frees +.Fa pis . +.Pp +.Fn POLICYQUALINFO_new +allocates and initializes an empty +.Vt POLICYQUALINFO +object, representing an ASN.1 +.Vt PolicyQualifierInfo +structure defined in RFC 5280 section 4.2.1.4. +It can be used in +.Vt POLICYINFO +and it can hold either a uniform resource identifier of a certification +practice statement published by the CA, or a pointer to a +.Vt USERNOTICE +object, or arbitrary other information. +.Fn POLICYQUALINFO_free +frees +.Fa pqi . +.Pp +.Fn USERNOTICE_new +allocates and initializes an empty +.Vt USERNOTICE +object, representing an ASN.1 +.Vt UserNotice +structure defined in RFC 5280 section 4.2.1.4. +It can be used in +.Vt POLICYQUALINFO +and it can hold either an +.Vt ASN1_STRING +intended for display to the user or a pointer to a +.Vt NOTICEREF +object. +.Fn NOTICEREF_free +frees +.Fa usernotice . +.Pp +.Fn NOTICEREF_new +allocates and initializes an empty +.Vt NOTICEREF +object, representing an ASN.1 +.Vt NoticeReference +structure defined in RFC 5280 section 4.2.1.4. +It can be used in +.Vt USERNOTICE +and can hold an organization name and a stack of notice numbers. +.Fn NOTICEREF_free +frees +.Fa noticeref . +.Pp +.Fn POLICY_MAPPING_new +allocates and initializes an empty +.Vt POLICY_MAPPING +object, representing an ASN.1 +.Vt PolicyMappings +structure defined in RFC 5280 section 4.2.1.5. +It can be used in +.Vt X509 +CA certificates and can hold a list of pairs of policy identifiers, +declaring one of the policies in each pair as equivalent to the +other. +.Fn POLICY_MAPPING_free +frees +.Fa pm . +.Pp +.Fn POLICY_CONSTRAINTS_new +allocates and initializes an empty +.Vt POLICY_CONSTRAINTS +object, representing an ASN.1 +.Vt PolicyConstraints +structure defined in RFC 5280 section 4.2.1.11. +It can be used in +.Vt X509 +CA certificates to restrict policy mapping and/or to require explicit +certificate policies in subsequent intermediate certificates in the +certification path. +.Fn POLICY_CONSTRAINTS_free +frees +.Fa pc . +.Sh RETURN VALUES +The constructor functions return a new object of the respective +type or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr d2i_POLICYINFO 3 , +.Xr NAME_CONSTRAINTS_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get_extension_flags 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.1.4: Certificate Policies +.It +section 4.2.1.5: Policy Mappings +.It +section 4.2.1.11: Policy Constraints +.El +.Sh HISTORY +.Fn POLICYINFO_new , +.Fn POLICYINFO_free , +.Fn CERTIFICATEPOLICIES_new , +.Fn CERTIFICATEPOLICIES_free , +.Fn POLICYQUALINFO_new , +.Fn POLICYQUALINFO_free , +.Fn USERNOTICE_new , +.Fn USERNOTICE_free , +.Fn NOTICEREF_new , +and +.Fn NOTICEREF_free +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . +.Pp +.Fn POLICY_MAPPING_new , +.Fn POLICY_MAPPING_free , +.Fn POLICY_CONSTRAINTS_new , +and +.Fn POLICY_CONSTRAINTS_free +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Sh BUGS +This is a lot of nested data structures, but most of them are +designed to have almost no effect. diff --git a/Libraries/libressl/man/RAND_add.3 b/Libraries/libressl/man/RAND_add.3 new file mode 100644 index 000000000..5404f696a --- /dev/null +++ b/Libraries/libressl/man/RAND_add.3 @@ -0,0 +1,73 @@ +.\" $OpenBSD: RAND_add.3,v 1.10 2018/03/27 17:35:50 schwarze Exp $ +.\" content checked up to: OpenSSL c16de9d8 Aug 31 23:16:22 2017 +0200 +.\" +.\" Copyright (c) 2014 Miod Vallat +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt RAND_ADD 3 +.Os +.Sh NAME +.Nm RAND_add , +.Nm RAND_cleanup , +.Nm RAND_poll , +.Nm RAND_seed , +.Nm RAND_status +.Nd manipulate the PRNG state +.Sh SYNOPSIS +.In openssl/rand.h +.Ft void +.Fo RAND_add +.Fa "const void *buf" +.Fa "int num" +.Fa "double entropy" +.Fc +.Ft void +.Fn RAND_cleanup void +.Ft int +.Fn RAND_poll void +.Ft void +.Fo RAND_seed +.Fa "const void *buf" +.Fa "int num" +.Fc +.Ft int +.Fn RAND_status void +.Sh DESCRIPTION +These functions used to allow for the state of the random number +generator to be controlled by external sources. +.Pp +They are kept for ABI compatibility but are no longer functional, and +should not be used in new programs. +.Sh RETURN VALUES +.Fn RAND_poll +and +.Fn RAND_status +always return 1. +.Sh HISTORY +.Fn RAND_cleanup +and +.Fn RAND_seed +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn RAND_add +and +.Fn RAND_status +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn RAND_poll +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/RAND_bytes.3 b/Libraries/libressl/man/RAND_bytes.3 new file mode 100644 index 000000000..19427a82d --- /dev/null +++ b/Libraries/libressl/man/RAND_bytes.3 @@ -0,0 +1,108 @@ +.\" $OpenBSD: RAND_bytes.3,v 1.6 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt RAND_BYTES 3 +.Os +.Sh NAME +.Nm RAND_bytes , +.Nm RAND_pseudo_bytes +.Nd generate random data +.Sh SYNOPSIS +.In openssl/rand.h +.Ft int +.Fo RAND_bytes +.Fa "unsigned char *buf" +.Fa "int num" +.Fc +.Ft int +.Fo RAND_pseudo_bytes +.Fa "unsigned char *buf" +.Fa "int num" +.Fc +.Sh DESCRIPTION +These functions are deprecated and only retained for compatibility +with legacy application programs. +Use +.Xr arc4random_buf 3 +instead. +.Pp +.Fn RAND_bytes +puts +.Fa num +cryptographically strong pseudo-random bytes into +.Fa buf . +.Pp +.Fn RAND_pseudo_bytes +puts +.Fa num +pseudo-random bytes into +.Fa buf . +Pseudo-random byte sequences generated by +.Fn RAND_pseudo_bytes +will be unique if they are of sufficient length, but are not necessarily +unpredictable. +They can be used for non-cryptographic purposes and for certain purposes +in cryptographic protocols, but usually not for key generation etc. +.Sh RETURN VALUES +.Fn RAND_bytes +returns 1. +.Fn RAND_pseudo_bytes +returns 1. +.Sh HISTORY +.Fn RAND_bytes +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . +It has a return value since OpenSSL 0.9.5 and +.Ox 2.7 . +.Pp +.Fn RAND_pseudo_bytes +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/RAND_load_file.3 b/Libraries/libressl/man/RAND_load_file.3 new file mode 100644 index 000000000..9227e2721 --- /dev/null +++ b/Libraries/libressl/man/RAND_load_file.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: RAND_load_file.3,v 1.6 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt RAND_LOAD_FILE 3 +.Os +.Sh NAME +.Nm RAND_file_name , +.Nm RAND_load_file , +.Nm RAND_write_file +.Nd PRNG seed file +.Sh SYNOPSIS +.In openssl/rand.h +.Ft const char * +.Fo RAND_file_name +.Fa "char *buf" +.Fa "size_t num" +.Fc +.Ft int +.Fo RAND_load_file +.Fa "const char *filename" +.Fa "long max_bytes" +.Fc +.Ft int +.Fo RAND_write_file +.Fa "const char *filename" +.Fc +.Sh DESCRIPTION +.Fn RAND_file_name +returns a default path for the random seed file. +.Fa buf +points to a buffer of size +.Fa num +in which to store the filename. +If +.Fa num +is too small for the path name, an error occurs. +.Pp +.Fn RAND_load_file +used to allow for the state of the random number generator to be +controlled by external sources. +It is kept for ABI compatibility but is no longer functional, and should +not be used in new programs. +.Pp +.Fn RAND_write_file +writes a number of random bytes (currently 1024) to file +.Fa filename . +.Sh RETURN VALUES +.Fn RAND_load_file +returns +.Fa max_bytes , +or a bogus positive value if +.Fa max_bytes +is -1. +.Pp +.Fn RAND_write_file +returns the number of bytes written, or a number less than or equal +to 1 if an error occurs. +.Pp +.Fn RAND_file_name +returns a pointer to +.Fa buf +on success or +.Dv NULL +on error. +.Sh HISTORY +.Fn RAND_load_file , +.Fn RAND_write_file , +and +.Fn RAND_file_name +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/RAND_set_rand_method.3 b/Libraries/libressl/man/RAND_set_rand_method.3 new file mode 100644 index 000000000..d94d794da --- /dev/null +++ b/Libraries/libressl/man/RAND_set_rand_method.3 @@ -0,0 +1,55 @@ +.\" $OpenBSD: RAND_set_rand_method.3,v 1.4 2018/03/21 09:03:49 schwarze Exp $ +.\" +.\" Copyright (c) 2014 Miod Vallat +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt RAND_SET_RAND_METHOD 3 +.Os +.Sh NAME +.Nm RAND_set_rand_method , +.Nm RAND_get_rand_method , +.Nm RAND_SSLeay +.Nd select RAND method +.Sh SYNOPSIS +.In openssl/rand.h +.Ft int +.Fo RAND_set_rand_method +.Fa "const RAND_METHOD *meth" +.Fc +.Ft const RAND_METHOD * +.Fn RAND_get_rand_method void +.Ft RAND_METHOD * +.Fn RAND_SSLeay void +.Sh DESCRIPTION +These functions used to allow for the random number generator functions +to be replaced by arbitrary code. +.Pp +They are kept for ABI compatibility but are no longer functional, and +should not be used in new programs. +.Sh RETURN VALUES +.Fn RAND_set_rand_method +always returns 1. +.Fn RAND_get_rand_method +and +.Fn RAND_SSLeay +always return +.Dv NULL . +.Sh HISTORY +.Fn RAND_set_rand_method , +.Fn RAND_get_rand_method , +and +.Fn RAND_SSLeay +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/RC4.3 b/Libraries/libressl/man/RC4.3 new file mode 100644 index 000000000..8b20a434b --- /dev/null +++ b/Libraries/libressl/man/RC4.3 @@ -0,0 +1,126 @@ +.\" $OpenBSD: RC4.3,v 1.8 2020/03/29 17:05:02 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 29 2020 $ +.Dt RC4 3 +.Os +.Sh NAME +.Nm RC4_set_key , +.Nm RC4 +.Nd RC4 encryption +.Sh SYNOPSIS +.In openssl/rc4.h +.Ft void +.Fo RC4_set_key +.Fa "RC4_KEY *key" +.Fa "int len" +.Fa "const unsigned char *data" +.Fc +.Ft void +.Fo RC4 +.Fa "RC4_KEY *key" +.Fa "unsigned long len" +.Fa "const unsigned char *indata" +.Fa "unsigned char *outdata" +.Fc +.Sh DESCRIPTION +This library implements the alleged RC4 cipher, which is described for +example in +.Qq Applied Cryptography . +It is believed to be compatible with RC4[TM], a proprietary cipher of +RSA Security Inc. +.Pp +RC4 is a stream cipher with variable key length. +Typically, 128-bit (16-byte) keys are used for strong encryption, but +shorter insecure key sizes have been widely used due to export +restrictions. +.Pp +RC4 consists of a key setup phase and the actual encryption or +decryption phase. +.Pp +.Fn RC4_set_key +sets up the +.Vt RC4_KEY +.Fa key +using the +.Fa len +bytes long key at +.Fa data . +.Pp +.Fn RC4 +encrypts or decrypts the +.Fa len +bytes of data at +.Fa indata +using +.Fa key +and places the result at +.Fa outdata . +Repeated +.Fn RC4 +calls with the same +.Fa key +yield a continuous key stream. +.Pp +Since RC4 is a stream cipher (the input is XOR'ed with a pseudo-random +key stream to produce the output), decryption uses the same function +calls as encryption. +.Sh SEE ALSO +.Xr blowfish 3 , +.Xr EVP_EncryptInit 3 , +.Xr EVP_rc4 3 +.Sh HISTORY +.Fn RC4_set_key +and +.Fn RC4 +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Sh BUGS +This cipher is broken and should no longer be used. diff --git a/Libraries/libressl/man/RIPEMD160.3 b/Libraries/libressl/man/RIPEMD160.3 new file mode 100644 index 000000000..6fadb56ce --- /dev/null +++ b/Libraries/libressl/man/RIPEMD160.3 @@ -0,0 +1,151 @@ +.\" $OpenBSD: RIPEMD160.3,v 1.7 2019/08/25 15:17:19 schwarze Exp $ +.\" full merge up to: OpenSSL 72a7a702 Feb 26 14:05:09 2019 +0000 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2006, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 25 2019 $ +.Dt RIPEMD160 3 +.Os +.Sh NAME +.Nm RIPEMD160 , +.Nm RIPEMD160_Init , +.Nm RIPEMD160_Update , +.Nm RIPEMD160_Final +.Nd RIPEMD-160 hash function +.Sh SYNOPSIS +.In openssl/ripemd.h +.Ft unsigned char * +.Fo RIPEMD160 +.Fa "const unsigned char *d" +.Fa "unsigned long n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo RIPEMD160_Init +.Fa "RIPEMD160_CTX *c" +.Fc +.Ft int +.Fo RIPEMD160_Update +.Fa "RIPEMD160_CTX *c" +.Fa "const void *data" +.Fa "unsigned long len" +.Fc +.Ft int +.Fo RIPEMD160_Final +.Fa "unsigned char *md" +.Fa "RIPEMD160_CTX *c" +.Fc +.Sh DESCRIPTION +RIPEMD-160 is a cryptographic hash function with a 160-bit output. +.Pp +.Fn RIPEMD160 +computes the RIPEMD-160 message digest of the +.Fa n +bytes at +.Fa d +and places it in +.Fa md , +which must have space for +.Dv RIPEMD160_DIGEST_LENGTH +== 20 bytes of output. +If +.Fa md +is +.Dv NULL , +the digest is placed in a static array. +.Pp +The following functions may be used if the message is not completely +stored in memory: +.Pp +.Fn RIPEMD160_Init +initializes a +.Vt RIPEMD160_CTX +structure. +.Pp +.Fn RIPEMD160_Update +can be called repeatedly with chunks of the message to be hashed +.Pq Fa len No bytes at Fa data . +.Pp +.Fn RIPEMD160_Final +places the message digest in +.Fa md , +which must have space for +.Dv RIPEMD160_DIGEST_LENGTH +== 20 bytes of output, +and erases the +.Vt RIPEMD160_CTX . +.Pp +Applications should use the higher level functions +.Xr EVP_DigestInit 3 +etc. instead of calling the hash functions directly. +.Sh RETURN VALUES +.Fn RIPEMD160 +returns a pointer to the hash value. +.Pp +.Fn RIPEMD160_Init , +.Fn RIPEMD160_Update , +and +.Fn RIPEMD160_Final +return 1 for success or 0 otherwise. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr HMAC 3 +.Sh STANDARDS +.Bd -unfilled +ISO/IEC 10118-3:2004/Cor 1:2011 +Hash-functions \(em Part 3: Dedicated hash-functions +Clause 7: RIPEMD-160 +.Ed +.Sh HISTORY +.Fn RIPEMD160 , +.Fn RIPEMD160_Init , +.Fn RIPEMD160_Update , +and +.Fn RIPEMD160_Final +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/RSA_PSS_PARAMS_new.3 b/Libraries/libressl/man/RSA_PSS_PARAMS_new.3 new file mode 100644 index 000000000..f69f33dbe --- /dev/null +++ b/Libraries/libressl/man/RSA_PSS_PARAMS_new.3 @@ -0,0 +1,60 @@ +.\" $OpenBSD: RSA_PSS_PARAMS_new.3,v 1.4 2019/06/06 01:06:59 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt RSA_PSS_PARAMS_NEW 3 +.Os +.Sh NAME +.Nm RSA_PSS_PARAMS_new , +.Nm RSA_PSS_PARAMS_free +.Nd probabilistic signature scheme with RSA hashing +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft RSA_PSS_PARAMS * +.Fn RSA_PSS_PARAMS_new void +.Ft void +.Fn RSA_PSS_PARAMS_free "RSA_PSS_PARAMS *params" +.Sh DESCRIPTION +.Fn RSA_PSS_PARAMS_new +allocates and initializes an empty +.Vt RSA_PSS_PARAMS +object, representing an ASN.1 +.Vt RSASSA-PSS-params +structure defined in RFC 8017 appendix A.2.3. +It references the hash function and the mask generation function +and stores the length of the salt and the trailer field number. +.Fn RSA_PSS_PARAMS_free +frees +.Fa params . +.Sh RETURN VALUES +.Fn RSA_PSS_PARAMS_new +returns the new +.Vt RSA_PSS_PARAMS +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr RSA_new 3 , +.Xr RSA_padding_add_PKCS1_type_1 3 , +.Xr X509_sign 3 +.Sh STANDARDS +RFC 8017: PKCS#1: RSA Cryptography Specifications Version 2.2 +.Sh HISTORY +.Fn RSA_PSS_PARAMS_new +and +.Fn RSA_PSS_PARAMS_free +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/RSA_blinding_on.3 b/Libraries/libressl/man/RSA_blinding_on.3 new file mode 100644 index 000000000..bd2a30137 --- /dev/null +++ b/Libraries/libressl/man/RSA_blinding_on.3 @@ -0,0 +1,97 @@ +.\" $OpenBSD: RSA_blinding_on.3,v 1.7 2023/07/26 20:08:59 tb Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 26 2023 $ +.Dt RSA_BLINDING_ON 3 +.Os +.Sh NAME +.Nm RSA_blinding_on , +.Nm RSA_blinding_off +.Nd protect the RSA operation from timing attacks +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_blinding_on +.Fa "RSA *rsa" +.Fa "BN_CTX *ctx" +.Fc +.Ft void +.Fo RSA_blinding_off +.Fa "RSA *rsa" +.Fc +.Sh DESCRIPTION +RSA is vulnerable to timing attacks. +In a setup where attackers can measure the time of RSA decryption or +signature operations, blinding must be used to protect the RSA operation +from that attack. +.Pp +.Fn RSA_blinding_on +turns blinding on for key +.Fa rsa +and generates a random blinding factor. +.Fa ctx +is +.Dv NULL +or a pre-allocated and initialized +.Vt BN_CTX . +.Pp +.Fn RSA_blinding_off +turns blinding off and frees the memory used for the blinding factor. +.Sh RETURN VALUES +.Fn RSA_blinding_on +returns 1 on success, and 0 if an error occurred. +.Sh SEE ALSO +.Xr RSA_new 3 +.Sh HISTORY +.Fn RSA_blinding_on +and +.Fn RSA_blinding_off +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/RSA_check_key.3 b/Libraries/libressl/man/RSA_check_key.3 new file mode 100644 index 000000000..c1e6379ac --- /dev/null +++ b/Libraries/libressl/man/RSA_check_key.3 @@ -0,0 +1,151 @@ +.\" $OpenBSD: RSA_check_key.3,v 1.9 2023/05/01 07:28:11 tb Exp $ +.\" OpenSSL 6859cf74 Sep 25 13:33:28 2002 +0000 +.\" +.\" This file was written by Ulf Moeller and +.\" Geoff Thorpe . +.\" Copyright (c) 2000, 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt RSA_CHECK_KEY 3 +.Os +.Sh NAME +.Nm RSA_check_key +.Nd validate private RSA keys +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_check_key +.Fa "RSA *rsa" +.Fc +.Sh DESCRIPTION +This function validates RSA keys. +It checks that +.Fa rsa->p +and +.Fa rsa->q +are in fact prime, and that +.Fa rsa->n +satisfies n = p*q. +.Pp +It also checks that +.Fa rsa->d +and +.Fa rsa->e +satisfy d*e = 1 mod ((p-1)*(q-1)), +and that +.Fa rsa->dmp1 , +.Fa rsa->dmq1 , +and +.Fa resa->iqmp +are set correctly or are +.Dv NULL . +.Pp +This function does not work on RSA public keys that have only the +modulus and public exponent elements populated. +It performs integrity checks on all the RSA key material, so the +.Vt RSA +key structure must contain all the private key data too. +Therefore, it cannot be used with any arbitrary +.Vt RSA +key object, even if it is otherwise fit for regular RSA operation. +.Pp +Unlike most other RSA functions, this function does +.Sy not +work transparently with any underlying +.Vt ENGINE +implementation because it uses the key data in the +.Vt RSA +structure directly. +An +.Vt ENGINE +implementation can override the way key data is stored and handled, +and can even provide support for HSM keys - in which case the +.Vt RSA +structure may contain +.Sy no +key data at all! +If the +.Vt ENGINE +in question is only being used for acceleration or analysis purposes, +then in all likelihood the RSA key data is complete and untouched, +but this can't be assumed in the general case. +.Sh RETURN VALUES +.Fn RSA_check_key +returns 1 if +.Fa rsa +is a valid RSA key, and 0 otherwise. +-1 is returned if an error occurs while checking the key. +.Pp +If the key is invalid or an error occurred, the reason code can be +obtained using +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_is_prime_ex 3 , +.Xr RSA_get0_key 3 , +.Xr RSA_new 3 +.Sh HISTORY +.Fn RSA_check_key +first appeared in OpenSSL 0.9.4 and has been available since +.Ox 2.6 . +.Sh BUGS +A method of verifying the RSA key using opaque RSA API functions might +need to be considered. +Right now +.Fn RSA_check_key +simply uses the +.Vt RSA +structure elements directly, bypassing the +.Vt RSA_METHOD +table altogether (and completely violating encapsulation and +object-orientation in the process). +The best fix will probably be to introduce a +.Fn check_key +handler +to the +.Vt RSA_METHOD +function table so that alternative implementations can also provide +their own verifiers. diff --git a/Libraries/libressl/man/RSA_generate_key.3 b/Libraries/libressl/man/RSA_generate_key.3 new file mode 100644 index 000000000..83703b1ea --- /dev/null +++ b/Libraries/libressl/man/RSA_generate_key.3 @@ -0,0 +1,164 @@ +.\" $OpenBSD: RSA_generate_key.3,v 1.13 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL RSA_generate_key.pod bb6c5e7f Feb 5 10:29:22 2017 -0500 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt RSA_GENERATE_KEY 3 +.Os +.Sh NAME +.Nm RSA_generate_key_ex , +.Nm RSA_generate_key +.Nd generate RSA key pair +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_generate_key_ex +.Fa "RSA *rsa" +.Fa "int bits" +.Fa "BIGNUM *e" +.Fa "BN_GENCB *cb" +.Fc +.Pp +Deprecated: +.Pp +.Ft RSA * +.Fo RSA_generate_key +.Fa "int num" +.Fa "unsigned long e" +.Fa "void (*callback)(int, int, void *)" +.Fa "void *cb_arg" +.Fc +.Sh DESCRIPTION +.Fn RSA_generate_key_ex +generates a key pair and stores it in +.Fa rsa . +.Pp +The modulus size will be of length +.Fa bits , +and the public exponent will be +.Fa e . +Key sizes with +.Fa num +< 1024 should be considered insecure. +The exponent is an odd number, typically 3, 17 or 65537. +.Pp +A callback function may be used to provide feedback about the progress +of the key generation. +If +.Fa cb +is not +.Dv NULL , +it will be called as follows using the +.Xr BN_GENCB_call 3 +function: +.Bl -bullet +.It +While a random prime number is generated, it is called as described in +.Xr BN_generate_prime 3 . +.It +When the +.Fa n Ns -th +randomly generated prime is rejected as not suitable for +the key, +.Fn BN_GENCB_call cb 2 n +is called. +.It +When a random p has been found with p-1 relatively prime to +.Fa e , +it is called as +.Fn BN_GENCB_call cb 3 0 . +.El +.Pp +The process is then repeated for prime q with +.Fn BN_GENCB_call cb 3 1 . +.Pp +.Fn RSA_generate_key +is deprecated. +New applications should use +.Fn RSA_generate_key_ex +instead. +.Fn RSA_generate_key +works in the same way as +.Fn RSA_generate_key_ex +except it uses "old style" call backs. +See +.Xr BN_generate_prime 3 +for further details. +.Sh RETURN VALUES +.Fn RSA_generate_key_ex +returns 1 on success or 0 on error. +.Fn RSA_generate_key +returns the key on success or +.Dv NULL +on error. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr BN_generate_prime 3 , +.Xr RSA_get0_key 3 , +.Xr RSA_meth_set_keygen 3 , +.Xr RSA_new 3 +.Sh HISTORY +.Fn RSA_generate_key +appeared in SSLeay 0.4 or earlier and had its +.Fa cb_arg +argument added in SSLeay 0.9.0. +It has been available since +.Ox 2.4 . +.Pp +.Fn RSA_generate_key_ex +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Sh BUGS +.Fn BN_GENCB_call cb 2 x +is used with two different meanings. +.Pp +.Fn RSA_generate_key +goes into an infinite loop for illegal input values. diff --git a/Libraries/libressl/man/RSA_get0_key.3 b/Libraries/libressl/man/RSA_get0_key.3 new file mode 100644 index 000000000..3fb74b19b --- /dev/null +++ b/Libraries/libressl/man/RSA_get0_key.3 @@ -0,0 +1,467 @@ +.\" $OpenBSD: RSA_get0_key.3,v 1.7 2023/03/06 13:05:32 tb Exp $ +.\" selective merge up to: OpenSSL 665d899f Aug 2 02:19:43 2017 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 6 2023 $ +.Dt RSA_GET0_KEY 3 +.Os +.Sh NAME +.Nm RSA_get0_key , +.Nm RSA_get0_n , +.Nm RSA_get0_e , +.Nm RSA_get0_d , +.Nm RSA_set0_key , +.Nm RSA_get0_factors , +.Nm RSA_get0_p , +.Nm RSA_get0_q , +.Nm RSA_set0_factors , +.Nm RSA_get0_crt_params , +.Nm RSA_get0_dmp1 , +.Nm RSA_get0_dmq1 , +.Nm RSA_get0_iqmp , +.Nm RSA_set0_crt_params , +.Nm RSA_clear_flags , +.Nm RSA_test_flags , +.Nm RSA_set_flags +.Nd get and set data in an RSA object +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft void +.Fo RSA_get0_key +.Fa "const RSA *r" +.Fa "const BIGNUM **n" +.Fa "const BIGNUM **e" +.Fa "const BIGNUM **d" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_n +.Fa "const RSA *r" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_e +.Fa "const RSA *r" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_d +.Fa "const RSA *r" +.Fc +.Ft int +.Fo RSA_set0_key +.Fa "RSA *r" +.Fa "BIGNUM *n" +.Fa "BIGNUM *e" +.Fa "BIGNUM *d" +.Fc +.Ft void +.Fo RSA_get0_factors +.Fa "const RSA *r" +.Fa "const BIGNUM **p" +.Fa "const BIGNUM **q" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_p +.Fa "const RSA *r" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_q +.Fa "const RSA *r" +.Fc +.Ft int +.Fo RSA_set0_factors +.Fa "RSA *r" +.Fa "BIGNUM *p" +.Fa "BIGNUM *q" +.Fc +.Ft void +.Fo RSA_get0_crt_params +.Fa "const RSA *r" +.Fa "const BIGNUM **dmp1" +.Fa "const BIGNUM **dmq1" +.Fa "const BIGNUM **iqmp" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_dmp1 +.Fa "const RSA *r" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_dmq1 +.Fa "const RSA *r" +.Fc +.Ft "const BIGNUM *" +.Fo RSA_get0_iqmp +.Fa "const RSA *r" +.Fc +.Ft int +.Fo RSA_set0_crt_params +.Fa "RSA *r" +.Fa "BIGNUM *dmp1" +.Fa "BIGNUM *dmq1" +.Fa "BIGNUM *iqmp" +.Fc +.Ft void +.Fo RSA_clear_flags +.Fa "RSA *r" +.Fa "int flags" +.Fc +.Ft int +.Fo RSA_test_flags +.Fa "const RSA *r" +.Fa "int flags" +.Fc +.Ft void +.Fo RSA_set_flags +.Fa "RSA *r" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +An +.Vt RSA +object contains the components for the public and private key. +.Fa n +is the modulus common to both public and private key, +.Fa e +is the public exponent and +.Fa d +is the private exponent. +.Fa p , +.Fa q , +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +are the factors for the second representation of a private key +(see PKCS#1 section 3 Key Types), where +.Fa p +and +.Fa q +are the first and second factor of +.Fa n . +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +are the exponents and coefficient +for Chinese Remainder Theorem (CRT) calculations. +.Pp +The +.Fa n , +.Fa e , +and +.Fa d +parameters can be obtained by calling +.Fn RSA_get0_key . +If they have not been set yet, then +.Pf * Fa n , +.Pf * Fa e , +and +.Pf * Fa d +are set to +.Dv NULL . +Otherwise, they are set to pointers to the internal representations +of the values that should not be freed by the caller. +.Pp +The +.Fa n , +.Fa e , +and +.Fa d +parameter values can be set by calling +.Fn RSA_set0_key . +The values +.Fa n +and +.Fa e +must be +.Pf non- Dv NULL +the first time this function is called on a given +.Vt RSA +object. +The value +.Fa d +may be +.Dv NULL . +On subsequent calls, any of these values may be +.Dv NULL , +which means that the corresponding field is left untouched. +Calling this function transfers the memory management of the values to +the RSA object. +Therefore, the values that have been passed in +should not be freed by the caller. +.Pp +In a similar fashion, the +.Fa p +and +.Fa q +parameters can be obtained and set with +.Fn RSA_get0_factors +and +.Fn RSA_set0_factors , +and the +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +parameters can be obtained and set with +.Fn RSA_get0_crt_params +and +.Fn RSA_set0_crt_params . +.Pp +For +.Fn RSA_get0_key , +.Fn RSA_get0_factors , +and +.Fn RSA_get0_crt_params , +.Dv NULL +value +.Vt BIGNUM ** +output arguments are permitted. +The functions +ignore +.Dv NULL +arguments but return values for other, +.Pf non- Dv NULL , +arguments. +.Pp +Values retrieved with +.Fn RSA_get0_key , +.Fn RSA_get0_factors , +and +.Fn RSA_get0_crt_params +are owned by the +.Vt RSA +object used in the call and may therefore +.Em not +be passed to +.Fn RSA_set0_key , +.Fn RSA_set0_factors , +or +.Fn RSA_set0_crt_params . +If needed, duplicate the received value using +.Xr BN_dup 3 +and pass the duplicate. +.Pp +Any of the values +.Fa n , +.Fa e , +.Fa d , +.Fa p , +.Fa q , +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +can also be retrieved separately by the corresponding functions +.Fn RSA_get0_n , +.Fn RSA_get0_e , +.Fn RSA_get0_d , +.Fn RSA_get0_p , +.Fn RSA_get0_q , +.Fn RSA_get0_dmp1 , +.Fn RSA_get0_dmq1 , +and +.Fn RSA_get0_iqmp , +respectively. +The pointers are owned by the +.Vt RSA +object. +.Pp +.Fn RSA_clear_flags +clears the specified +.Fa flags +in +.Fa r . +.Fn RSA_test_flags +tests the +.Fa flags +in +.Fa r . +.Fn RSA_set_flags +sets the +.Fa flags +in +.Fa r ; +any flags already set remain set. +For all three functions, multiple flags can be passed in one call, +OR'ed together bitwise. +.Pp +The following flags are supported: +.Bl -tag -width Ds +.It Dv RSA_FLAG_CACHE_PRIVATE No and Dv RSA_FLAG_CACHE_PUBLIC +Precompute information needed for Montgomery multiplication +from the private and public key, respectively, and cache it in +.Fa r +for repeated use. +These two flags are set by default for the default RSA implementation, +.Xr RSA_PKCS1_SSLeay 3 . +.It Dv RSA_FLAG_EXT_PKEY +The function set with +.Xr RSA_meth_set_mod_exp 3 +is used for private key operations even if +.Fa p , +.Fa q , +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +are all +.Dv NULL . +This flag may be useful with RSA implementations that do not use the +private key components stored in the standard fields, for example +because they store the private key in external hardware. +If this flag is unset, the function set with +.Xr RSA_meth_set_bn_mod_exp 3 +is used with +.Fa n +and +.Fa d +instead. +.It Dv RSA_FLAG_NO_BLINDING +Turn off blinding during private key encryption and decryption. +This flag is set by +.Xr RSA_blinding_off 3 . +.It Dv RSA_FLAG_SIGN_VER +Enable the use of the functions set with +.Xr RSA_meth_set_sign 3 +and +.Xr RSA_meth_set_verify 3 . +If unset, the functions set with +.Xr RSA_meth_set_priv_enc 3 +and +.Xr RSA_meth_set_pub_dec 3 +are used instead, respectively. +.El +.Pp +The flags +.Dv RSA_FLAG_BLINDING , +.Dv RSA_FLAG_CHECKED , +.Dv RSA_FLAG_FIPS_METHOD , +.Dv RSA_FLAG_NON_FIPS_ALLOW , +and +.Dv RSA_FLAG_THREAD_SAFE +are defined for compatibility with existing code but have no effect. +.Sh RETURN VALUES +.Fn RSA_get0_n , +.Fn RSA_get0_e , +.Fn RSA_get0_d , +.Fn RSA_get0_p , +.Fn RSA_get0_q , +.Fn RSA_get0_dmp1 , +.Fn RSA_get0_dmq1 , +and +.Fn RSA_get0_iqmp +return a pointer owned by the +.Vt RSA +object if the corresponding value has been set, +otherwise they return +.Dv NULL . +.Pp +.Fn RSA_set0_key , +.Fn RSA_set0_factors , +and +.Fn RSA_set0_crt_params +return 1 on success or 0 on failure. +.Pp +.Fn RSA_test_flags +returns those of the given +.Fa flags +currently set in +.Fa r +or 0 if none of the given +.Fa flags +are set. +.Sh SEE ALSO +.Xr RSA_check_key 3 , +.Xr RSA_generate_key 3 , +.Xr RSA_new 3 , +.Xr RSA_print 3 , +.Xr RSA_size 3 +.Sh HISTORY +.Fn RSA_get0_key , +.Fn RSA_set0_key , +.Fn RSA_get0_factors , +.Fn RSA_set0_factors , +.Fn RSA_get0_crt_params , +.Fn RSA_set0_crt_params , +.Fn RSA_clear_flags , +.Fn RSA_test_flags , +and +.Fn RSA_set_flags +first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . +.Pp +.Fn RSA_get0_n , +.Fn RSA_get0_e , +.Fn RSA_get0_d , +.Fn RSA_get0_p , +.Fn RSA_get0_q , +.Fn RSA_get0_dmp1 , +.Fn RSA_get0_dmq1 , +and +.Fn RSA_get0_iqmp +first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/RSA_get_ex_new_index.3 b/Libraries/libressl/man/RSA_get_ex_new_index.3 new file mode 100644 index 000000000..51a8f24cd --- /dev/null +++ b/Libraries/libressl/man/RSA_get_ex_new_index.3 @@ -0,0 +1,382 @@ +.\" $OpenBSD: RSA_get_ex_new_index.3,v 1.12 2023/09/18 14:49:43 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 18 2023 $ +.Dt RSA_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm RSA_get_ex_new_index , +.Nm RSA_set_ex_data , +.Nm RSA_get_ex_data +.Nd add application specific data to RSA objects +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fo RSA_set_ex_data +.Fa "RSA *rsa" +.Fa "int idx" +.Fa "void *data" +.Fc +.Ft void * +.Fo RSA_get_ex_data +.Fa "RSA *rsa" +.Fa "int idx" +.Fc +.Sh DESCRIPTION +The following parent objects can have application specific data called +.Dq ex_data +attached to them: +.Vt BIO , DH , DSA , EC_KEY , ENGINE , RSA , +.Vt SSL , SSL_CTX , SSL_SESSION , UI , X509 , X509_STORE , +and +.Vt X509_STORE_CTX . +.\" CRYPTO_EX_INDEX_APP and CRYPTO_EX_INDEX_UI_METHOD are unused. +The present manual page documents the related API functions taking the +.Vt RSA +object type as an example. +The functions for the other object types work in exactly the same way: +just replace the string +.Qq RSA +with the name of the respective object type +throughout the rest of this manual page. +.Pp +By default, each individual +.Vt RSA +object can store one +.Vt void * +pointing to application specific data. +That specific pointer is identified by an +.Fa idx +argument of 0. +.Pp +.Fn RSA_get_ex_new_index +reserves the next consecutive +.Fa idx +argument, enabling storage of one additional +.Vt void * +per +.Vt RSA +object. +It is typically called at program startup. +It can be called more than once if some +.Vt RSA +objects need to store more than two application specific pointers. +Reserving an additional index for one parent object type, for example for +.Vt RSA , +does not change the numbers of indices that can be used +with any other parent object type. +.Pp +It is strongly recommended to always pass three +.Dv NULL +pointers for the arguments +.Fa new_func , +.Fa dup_func , +and +.Fa free_func . +When following this recommendation, the arguments +.Fa argl +and +.Fa argp +are ignored; conventionally, passing 0 and +.Dv NULL +is recommended. +Because using them is discouraged, the three function callback types +are only documented in the low-level +.Xr CRYPTO_EX_new 3 +manual page. +.Pp +.Fn RSA_set_ex_data +stores the +.Fa data +pointer as application specific data at the given +.Fa idx +in the given +.Fa rsa +object. +The meaning of the data pointed to is up to the application. +The caller retains ownership of the +.Fa data +and is responsible for freeing it when neither the caller nor the +.Fa rsa +object need it any longer. +Any other pointer that was previously stored at the same +.Fa idx +in the same +.Fa rsa +object is silently overwritten. +Passing a +.Dv NULL +pointer for the +.Fa data +argument is valid and indicates that no application specific data +currently needs to be stored at the given +.Fa idx . +.Pp +.Fn RSA_get_ex_data +retrieves the last pointer that was stored using +.Fn RSA_set_ex_data +at the given +.Fa idx +in the given +.Fa rsa +object. +.Sh RETURN VALUES +.Fn RSA_get_ex_new_index +returns a new index equal to or greater than 1 +or \-1 if memory allocation fails. +.Pp +.Fn RSA_set_ex_data +returns 1 on success or 0 if memory allocation fails. +.Pp +.Fn RSA_get_ex_data +returns the application specific data or +.Dv NULL +if +.Fa rsa +does not contain application specific data at the given +.Fa idx . +.Sh ERRORS +After failure of +.Fn RSA_get_ex_new_index +or +.Fn RSA_set_ex_data , +the following diagnostic can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +Memory allocation failed. +.El +.Pp +In a few unusual failure cases, +.Xr ERR_get_error 3 +may report different errors caused by +.Xr OPENSSL_init_crypto 3 +or even none at all. +.Pp +.Fn RSA_get_ex_data +does not distinguish success from failure. +Consequently, after +.Fn RSA_get_ex_data +returns +.Dv NULL , +.Xr ERR_get_error 3 +returns 0 unless there is still an earlier error in the queue. +.Sh SEE ALSO +.Xr BIO_set_ex_data 3 , +.Xr CRYPTO_set_ex_data 3 , +.Xr DH_set_ex_data 3 , +.Xr DSA_set_ex_data 3 , +.Xr RSA_new 3 , +.Xr SSL_CTX_set_ex_data 3 , +.Xr SSL_SESSION_set_ex_data 3 , +.Xr SSL_set_ex_data 3 , +.Xr X509_STORE_CTX_set_ex_data 3 , +.Xr X509_STORE_set_ex_data 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.9.0 +and have been available since +.Ox 2.4 . +.Sh CAVEATS +A relatively small minority of application programs +attempt to change the API contract such that +.Fn RSA_set_ex_data +transfers ownership of the +.Fa data +to the +.Fa rsa +object. +They do this by providing a +.Fa free_func +that calls +.Xr free 3 +or higher-level +.Fn *_free +functions on the +.Fa data +and sometimes also attempt additional cleanup work as a side effect. +.Pp +This practice is discouraged for several reasons: +.Bl -enum +.It +Due to a massive design mistake in the low-level API function +.Xr CRYPTO_free_ex_data 3 , +this practice creates a possibility that +.Xr RSA_free 3 +may fail due to memory allocation failure, consequently leaking the +memory containing the application specific data and silently skipping +any additional cleanup work the +.Fa free_func +was supposed to do, leaving the application in an undetectably +inconsistent state. +Arguably, leaking additional memory while trying to free some +is most unfortunate especially when the program +is already starved for memory. +.It +This practice introduces a risk of use-after-free and double-free +bugs in case the +.Fa rsa +object gets destructed while a caller of +.Fn RSA_set_ex_data +or +.Fn RSA_get_ex_data +still holds a +.Fa data +pointer. +No such risk exists when no +.Fa free_func +is installed. +.It +Attempting additional cleanup work in +.Fa free_func +is an even worse idea because +.Fa free_func +is unable to report any issues it might detect while doing that work. +Instead, if any additional cleanup work is needed, it is recommended +that the calling code takes care of that before calling +.Xr RSA_free 3 . +.El +.Pp +Even fewer application programs install a +.Fa new_func +that allocates memory and stores a pointer to it in the +.Fa rsa +object by calling +.Xr CRYPTO_set_ex_data 3 . +That is useless because +.Fa new_func +does not have access to any useful information it could store in such memory +and because the default return value of +.Dv NULL +from +.Fn RSA_get_ex_data +is sufficient to indicate +that no application specific data has been stored yet. +In addition, allocating memory in +.Fa new_func +is also inadvisable because it introduces an additional responsibility +for callers of +.Fn RSA_set_ex_data +to always call +.Fn RSA_get_ex_data +first, even when it is the first time the application wants to set +application specific data in a particular +.Fa rsa +object, and to either modify whatever +.Fn RSA_get_ex_data +returns or to free it before calling +.Fn RSA_set_ex_data . +If that is forgotten, a memory leak results. +.Pp +Consequently, allocating any required memory +is better left to the application code that calls +.Fn RSA_set_ex_data . +.Pp +Installing a +.Fa dup_func +is often seen in combination with installing a +.Fa free_func , +for obvious reasons. +It is rarely useful because for most parent object types +that support ex_data, including for +.Vt RSA , +the library does not provide a copying API function in the first place, and +even where copying functions exist, they tend to be fragile and error-prone. +When a new object is needed, it is usually advisable to construct it from +scratch whenever possible, rather than attempting a copy operation. +.Pp +On top of that, if +.Fa dup_func +fails, for example because of a memory allocation failure, the +failure is neither reported nor detectable in any way, leaving the +new parent object with incomplete data and potentially in an +inconsistent state. +.Sh BUGS +If +.Fn RSA_set_ex_data +fails, recovery is very difficult. +In particular, calling +.Xr RSA_free 3 +on the parent +.Fa rsa +object right afterwards is likely to also hit a memory allocation +failure, leaking all memory internally allocated by all earlier calls of +.Fn RSA_set_ex_data +on +.Fa rsa +rather than freeing that memory. +In order to recover, the application program +would have to free a sufficient amount of +.Em other +memory before calling +.Xr RSA_free 3 , +which will rarely be feasible. +Consequently, after a failure of +.Fn RSA_set_ex_data , +terminating the program is likely the only reasonable option. +.Pp +If +.Fn RSA_set_ex_data +is called with an +.Fa idx +argument greater than the last one previously returned from +.Fn RSA_get_ex_new_index , +it may still succeed, and though that is not guaranteed by the API, +retrieving the +.Fa data +from such a bogus +.Fa idx +may even be possible with +.Fn RSA_get_ex_data , +hiding the bug in the application program that caused passing the bogus +.Fa idx +to +.Fn RSA_set_ex_data +in the first place. +.Pp +If the bogus +.Fa idx +argument is large, +.Fn RSA_set_ex_data +may uselessly allocate a large amount of memory. +Calling +.Xr RSA_free 3 +on the parent +.Fa rsa +object is the only way to recover that memory. +.Pp +If the bogus +.Fa idx +argument is very large, +.Fn RSA_set_ex_data +is likely to cause a significant delay before eventually failing +due to memory exhaustion. +It is likely to return without releasing the memory already +allocated, causing any subsequent attempt to allocate memory +for other purposes to fail, too. +In this situation, what was said above about failure of +.Fn RSA_set_ex_data +applies, so terminating the program is likely the only reasonable option. diff --git a/Libraries/libressl/man/RSA_meth_new.3 b/Libraries/libressl/man/RSA_meth_new.3 new file mode 100644 index 000000000..f42feb3f3 --- /dev/null +++ b/Libraries/libressl/man/RSA_meth_new.3 @@ -0,0 +1,626 @@ +.\" $OpenBSD: RSA_meth_new.3,v 1.5 2019/07/13 17:26:38 schwarze Exp $ +.\" full merge up to: OpenSSL a970b14f Jul 31 18:58:40 2017 -0400 +.\" selective merge up to: OpenSSL 24907560 Sep 17 07:47:42 2018 +1000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Richard Levitte . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2019 $ +.Dt RSA_METH_NEW 3 +.Os +.Sh NAME +.Nm RSA_meth_new , +.Nm RSA_meth_dup , +.Nm RSA_meth_free , +.Nm RSA_meth_get0_name , +.Nm RSA_meth_set1_name , +.Nm RSA_meth_get_flags , +.Nm RSA_meth_set_flags , +.Nm RSA_meth_get0_app_data , +.Nm RSA_meth_set0_app_data , +.Nm RSA_meth_get_init , +.Nm RSA_meth_set_init , +.Nm RSA_meth_get_finish , +.Nm RSA_meth_set_finish , +.Nm RSA_meth_get_pub_enc , +.Nm RSA_meth_set_pub_enc , +.Nm RSA_meth_get_pub_dec , +.Nm RSA_meth_set_pub_dec , +.Nm RSA_meth_get_priv_enc , +.Nm RSA_meth_set_priv_enc , +.Nm RSA_meth_get_priv_dec , +.Nm RSA_meth_set_priv_dec , +.Nm RSA_meth_get_sign , +.Nm RSA_meth_set_sign , +.Nm RSA_meth_get_verify , +.Nm RSA_meth_set_verify , +.Nm RSA_meth_get_mod_exp , +.Nm RSA_meth_set_mod_exp , +.Nm RSA_meth_get_bn_mod_exp , +.Nm RSA_meth_set_bn_mod_exp , +.Nm RSA_meth_get_keygen , +.Nm RSA_meth_set_keygen +.Nd build up RSA methods +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft RSA_METHOD * +.Fo RSA_meth_new +.Fa "const char *name" +.Fa "int flags" +.Fc +.Ft RSA_METHOD * +.Fo RSA_meth_dup +.Fa "const RSA_METHOD *meth" +.Fc +.Ft void +.Fo RSA_meth_free +.Fa "RSA_METHOD *meth" +.Fc +.Ft const char * +.Fo RSA_meth_get0_name +.Fa "const RSA_METHOD *meth" +.Fc +.Ft int +.Fo RSA_meth_set1_name +.Fa "RSA_METHOD *meth" +.Fa "const char *name" +.Fc +.Ft int +.Fo RSA_meth_get_flags +.Fa "const RSA_METHOD *meth" +.Fc +.Ft int +.Fo RSA_meth_set_flags +.Fa "RSA_METHOD *meth" +.Fa "int flags" +.Fc +.Ft void * +.Fo RSA_meth_get0_app_data +.Fa "const RSA_METHOD *meth" +.Fc +.Ft int +.Fo RSA_meth_set0_app_data +.Fa "RSA_METHOD *meth" +.Fa "void *app_data" +.Fc +.Ft int +.Fo "(*RSA_meth_get_init(const RSA_METHOD *meth))" +.Fa "RSA *rsa" +.Fc +.Ft int +.Fo "RSA_meth_set_init" +.Fa "RSA_METHOD *meth" +.Fa "int (*init)(RSA *rsa)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_finish(const RSA_METHOD *meth))" +.Fa "RSA *rsa" +.Fc +.Ft int +.Fo RSA_meth_set_finish +.Fa "RSA_METHOD *meth" +.Fa "int (*finish)(RSA *rsa)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_pub_enc(const RSA_METHOD *meth))" +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Ft int +.Fo RSA_meth_set_pub_enc +.Fa "RSA_METHOD *meth" +.Fa "int (*pub_enc)(int flen, const unsigned char *from,\ + unsigned char *to, RSA *rsa, int padding)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_pub_dec(const RSA_METHOD *meth))" +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Ft int +.Fo RSA_meth_set_pub_dec +.Fa "RSA_METHOD *meth" +.Fa "int (*pub_dec)(int flen, const unsigned char *from,\ + unsigned char *to, RSA *rsa, int padding)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_priv_enc(const RSA_METHOD *meth))" +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Ft int +.Fo RSA_meth_set_priv_enc +.Fa "RSA_METHOD *meth" +.Fa "int (*priv_enc)(int flen, const unsigned char *from,\ + unsigned char *to, RSA *rsa, int padding)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_priv_dec(const RSA_METHOD *meth))" +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Ft int +.Fo RSA_meth_set_priv_dec +.Fa "RSA_METHOD *meth" +.Fa "int (*priv_dec)(int flen, const unsigned char *from,\ + unsigned char *to, RSA *rsa, int padding)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_sign(const RSA_METHOD *meth))" +.Fa "int type" +.Fa "const unsigned char *m" +.Fa "unsigned int m_length" +.Fa "unsigned char *sigret" +.Fa "unsigned int *siglen" +.Fa "const RSA *rsa" +.Fc +.Ft int +.Fo RSA_meth_set_sign +.Fa "RSA_METHOD *rsa" +.Fa "int (*sign)(int type, const unsigned char *m, unsigned int m_length,\ + unsigned char *sigret, unsigned int *siglen, const RSA *rsa)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_verify(const RSA_METHOD *meth))" +.Fa "int dtype" +.Fa "const unsigned char *m" +.Fa "unsigned int m_length" +.Fa "const unsigned char *sigbuf" +.Fa "unsigned int siglen" +.Fa "const RSA *rsa" +.Fc +.Ft int +.Fo RSA_meth_set_verify +.Fa "RSA_METHOD *rsa" +.Fa "int (*verify)(int dtype, const unsigned char *m,\ + unsigned int m_length, const unsigned char *sigbuf,\ + unsigned int siglen, const RSA *rsa)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_mod_exp(const RSA_METHOD *meth))" +.Fa "BIGNUM *r0" +.Fa "const BIGNUM *i" +.Fa "RSA *rsa" +.Fa "BN_CTX *ctx" +.Fc +.Ft int +.Fo RSA_meth_set_mod_exp +.Fa "RSA_METHOD *meth" +.Fa "int (*mod_exp)(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))" +.Fa "BIGNUM *r" +.Fa "const BIGNUM *a" +.Fa "const BIGNUM *p" +.Fa "const BIGNUM *m" +.Fa "BN_CTX *ctx" +.Fa "BN_MONT_CTX *m_ctx" +.Fc +.Ft int +.Fo RSA_meth_set_bn_mod_exp +.Fa "RSA_METHOD *meth" +.Fa "int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,\ + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)" +.Fc +.Ft int +.Fo "(*RSA_meth_get_keygen(const RSA_METHOD *meth))" +.Fa "RSA *rsa" +.Fa "int bits" +.Fa "BIGNUM *e" +.Fa "BN_GENCB *cb" +.Fc +.Ft int +.Fo RSA_meth_set_keygen +.Fa "RSA_METHOD *meth" +.Fa "int (*keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)" +.Fc +.Sh DESCRIPTION +The +.Vt RSA_METHOD +structure holds function pointers for custom RSA implementations. +.Pp +.Fn RSA_meth_new +creates a new +.Vt RSA_METHOD +structure. +A copy of the NUL-terminated +.Fa name +is stored in the new +.Vt RSA_METHOD +object. +Any new +.Vt RSA +object constructed from this +.Vt RSA_METHOD +will have the given +.Fa flags +set by default, as if they were set with +.Xr RSA_set_flags 3 . +.Pp +.Fn RSA_meth_dup +creates a deep copy of +.Fa meth , +except that a pointer stored into it with +.Fn RSA_meth_set0_app_data +is copied as a pointer without creating a copy of its content. +This might be useful for creating a new +.Vt RSA_METHOD +based on an existing one, but with some differences. +.Pp +.Fn RSA_meth_free +destroys +.Fa meth +and frees any memory associated with it, +except that memory pointed to by a pointer set with +.Fn RSA_meth_set0_app_data +is not freed. +If +.Fa meth +is +.Dv NULL , +no action occurs. +.Pp +.Fn RSA_meth_get0_name +returns an internal pointer to the name of +.Fa meth . +.Fn RSA_meth_set1_name +stores a copy of the NUL-terminated +.Fa name +in the +.Vt RSA_METHOD +object after freeing the previously stored name. +Method names are ignored by the default RSA implementation +but can be used by alternative implementations +and by the application program. +.Pp +.Fn RSA_meth_get_flags +retrieves the flags from +.Fa meth . +Flags are documented in +.Xr RSA_test_flags 3 . +.Fn RSA_meth_set_flags +overwrites all flags in +.Fa meth . +Unlike +.Xr RSA_set_flags 3 , +it does not preserve any flags that were set before the call. +.Pp +.Fn RSA_meth_get0_app_data +and +.Fn RSA_meth_set0_app_data +get and set a pointer to implementation-specific data. +The function +.Fn RSA_meth_free +does not +.Xr free 3 +the memory pointed to by +.Fa app_data . +The default RSA implementation does not use +.Fa app_data . +.Pp +.Fn RSA_meth_get_init +and +.Fn RSA_meth_set_init +get and set an optional function used when creating a new +.Vt RSA +object. +Unless +.Fa init +is +.Dv NULL , +it will be called at the end of +.Xr RSA_new 3 , +.Xr RSA_new_method 3 , +and +.Xr RSA_set_method 3 , +passing a pointer to the newly allocated or reset +.Vt RSA +object as an argument. +The default RSA implementation, +.Xr RSA_PKCS1_SSLeay 3 , +contains an +.Fa init +function equivalent to calling +.Xr RSA_set_flags 3 +with an argument of +.Dv RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE . +.Pp +.Fn RSA_meth_get_finish +and +.Fn RSA_meth_set_finish +get and set an optional function for destroying an +.Vt RSA +object. +Unless +.Fa finish +is +.Dv NULL , +it will be called from +.Xr RSA_set_method 3 +and from +.Xr RSA_free 3 . +It takes the same argument as +.Xr RSA_free 3 +and is intended to do RSA implementation specific cleanup. +The memory used by the +.Vt RSA +object itself should not be freed by the +.Fa finish +function. +The default RSA implementation contains a +.Fa finish +function freeing the memory used by the +.Dv RSA_FLAG_CACHE_PUBLIC +and +.Dv RSA_FLAG_CACHE_PRIVATE +caches. +.Pp +.Fn RSA_meth_get_pub_enc , +.Fn RSA_meth_set_pub_enc , +.Fn RSA_meth_get_pub_dec , +.Fn RSA_meth_set_pub_dec , +.Fn RSA_meth_get_priv_enc , +.Fn RSA_meth_set_priv_enc , +.Fn RSA_meth_get_priv_dec , +and +.Fn RSA_meth_set_priv_dec +get and set the mandatory functions +used for public and private key encryption and decryption. +These functions will be called from +.Xr RSA_public_encrypt 3 , +.Xr RSA_public_decrypt 3 , +.Xr RSA_private_encrypt 3 , +and +.Xr RSA_private_decrypt 3 , +respectively, and take the same parameters as those. +.Pp +.Fn RSA_meth_get_sign , +.Fn RSA_meth_set_sign , +.Fn RSA_meth_get_verify , +and +.Fn RSA_meth_set_verify +get and set the optional functions +used for creating and verifying an RSA signature. +If the flag +.Dv RSA_FLAG_SIGN_VER +is set on the +.Vt RSA +object in question and +.Fa sign +or +.Fa verify +is not +.Dv NULL , +it will be called from +.Xr RSA_sign 3 +or +.Xr RSA_verify 3 , +respectively, and take the same parameters as those. +Otherwise, +.Xr RSA_private_encrypt 3 +or +.Xr RSA_public_decrypt 3 +will be used instead. +.Pp +.Fn RSA_meth_get_mod_exp +and +.Fn RSA_meth_set_mod_exp +get and set the function +used for Chinese Remainder Theorem (CRT) computations involving the +.Fa p , +.Fa q , +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +fields of an +.Vt RSA +object. +It is used by the default RSA implementation during +.Xr RSA_private_encrypt 3 +and +.Xr RSA_private_decrypt 3 +when the required components of the private key are available +or when the +.Dv RSA_FLAG_EXT_PKEY +flag is set. +.Pp +.Fn RSA_meth_get_bn_mod_exp +and +.Fn RSA_meth_set_bn_mod_exp +get and set the function used for CRT computations, +specifically the value r = +.Fa a +\(ha +.Fa p +mod +.Fa m . +It is used by the default RSA implementation during +.Xr RSA_public_encrypt 3 +and +.Xr RSA_public_decrypt 3 +and as a fallback during +.Xr RSA_private_encrypt 3 +and +.Xr RSA_private_decrypt 3 . +.Pp +.Fn RSA_meth_get_keygen +and +.Fn RSA_meth_set_keygen +get and set the optional function used for generating a new RSA key pair. +Unless +.Fa keygen +is +.Dv NULL , +it will be called from +.Xr RSA_generate_key_ex 3 +and takes the same parameters. +Otherwise, a builtin default implementation is used. +.Sh RETURN VALUES +.Fn RSA_meth_new +and +.Fn RSA_meth_dup +return the newly allocated +.Vt RSA_METHOD +object or +.Dv NULL +on failure. +.Pp +.Fn RSA_meth_get0_name +returns an internal pointer which must not be freed by the caller. +.Pp +.Fn RSA_meth_get_flags +returns zero or more +.Dv RSA_FLAG_* +constants OR'ed together, or 0 if no flags are set in +.Fa meth . +.Pp +.Fn RSA_meth_get0_app_data +returns the pointer that was earlier passed to +.Fn RSA_meth_set0_app_data +or +.Dv NULL +otherwise. +.Pp +All other +.Fn RSA_meth_get_* +functions return the appropriate function pointer that has been set +with the corresponding +.Fn RSA_meth_set_* +function, or +.Dv NULL +if no such pointer has been set in +.Fa meth . +.Pp +All +.Fn RSA_meth_set* +functions return 1 on success or 0 on failure. +In the current implementation, only +.Fn RSA_meth_set1_name +can actually fail. +.Sh SEE ALSO +.Xr RSA_generate_key_ex 3 , +.Xr RSA_new 3 , +.Xr RSA_private_encrypt 3 , +.Xr RSA_public_encrypt 3 , +.Xr RSA_set_flags 3 , +.Xr RSA_set_method 3 , +.Xr RSA_sign 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0. +.Fn RSA_meth_new , +.Fn RSA_meth_dup , +.Fn RSA_meth_free , +.Fn RSA_meth_set_finish , +.Fn RSA_meth_set_priv_enc , +and +.Fn RSA_meth_set_priv_dec +have been available since +.Ox 6.3 , +.Fn RSA_meth_set1_name +and +.Fn RSA_meth_get_finish +since +.Ox 6.4 , +and +.Fn RSA_meth_get0_name , +.Fn RSA_meth_get_flags , +.Fn RSA_meth_set_flags , +.Fn RSA_meth_get0_app_data , +.Fn RSA_meth_set0_app_data , +.Fn RSA_meth_get_init , +.Fn RSA_meth_set_init , +.Fn RSA_meth_set_finish , +.Fn RSA_meth_get_pub_enc , +.Fn RSA_meth_set_pub_enc , +.Fn RSA_meth_get_pub_dec , +.Fn RSA_meth_set_pub_dec , +.Fn RSA_meth_get_priv_enc , +.Fn RSA_meth_get_priv_dec , +.Fn RSA_meth_get_sign , +.Fn RSA_meth_set_sign , +.Fn RSA_meth_get_verify , +.Fn RSA_meth_set_verify , +.Fn RSA_meth_get_mod_exp , +.Fn RSA_meth_set_mod_exp , +.Fn RSA_meth_get_bn_mod_exp , +.Fn RSA_meth_set_bn_mod_exp , +.Fn RSA_meth_get_keygen , +and +.Fn RSA_meth_set_keygen +since +.Ox 6.6 . diff --git a/Libraries/libressl/man/RSA_new.3 b/Libraries/libressl/man/RSA_new.3 new file mode 100644 index 000000000..b4c595ff2 --- /dev/null +++ b/Libraries/libressl/man/RSA_new.3 @@ -0,0 +1,256 @@ +.\" $OpenBSD: RSA_new.3,v 1.17 2022/07/13 21:51:35 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL doc/man3/RSA_new.pod e9b77246 Jan 20 19:58:49 2017 +0100 +.\" OpenSSL doc/crypto/rsa.pod 35d2e327 Jun 3 16:19:49 2016 -0400 (final) +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt RSA_NEW 3 +.Os +.Sh NAME +.Nm RSA_new , +.Nm RSAPrivateKey_dup , +.Nm RSAPublicKey_dup , +.Nm RSA_up_ref , +.Nm RSA_free +.Nd allocate and free RSA objects +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft RSA * +.Fn RSA_new void +.Ft RSA * +.Fo RSAPrivateKey_dup +.Fa "RSA *rsa" +.Fc +.Ft RSA * +.Fo RSAPublicKey_dup +.Fa "RSA *rsa" +.Fc +.Ft int +.Fo RSA_up_ref +.Fa "RSA *rsa" +.Fc +.Ft void +.Fo RSA_free +.Fa "RSA *rsa" +.Fc +.Sh DESCRIPTION +The RSA functions implement RSA public key encryption and signatures +as defined in PKCS #1 v2.0 (RFC 2437). +.Pp +.Fn RSA_new +allocates and initializes an +.Vt RSA +structure, setting the reference count to 1. +It is equivalent to calling +.Xr RSA_new_method 3 +with a +.Dv NULL +argument. +.Pp +.Fn RSAPrivateKey_dup +calls +.Fn RSA_new +and copies the public and private key components from +.Fa rsa +into the new structure. +.Fn RSAPublicKey_dup +does the same except that it copies the public key components only. +.Pp +.Fn RSA_up_ref +increments the reference count by 1. +.Pp +.Fn RSA_free +decrements the reference count by 1. +If it reaches 0, it calls the optional +.Fa finish +function set up with +.Xr RSA_meth_set_finish 3 , +calls +.Xr ENGINE_finish 3 +if +.Fa rsa +uses an engine, and frees the +.Vt RSA +structure and its components. +The key is erased before the memory is returned to the system. +If +.Fa rsa +is a +.Dv NULL +pointer, no action occurs. +.Pp +The +.Vt RSA +structure consists of several +.Vt BIGNUM +components. +It can contain public as well as private RSA keys: +.Bd -literal +typedef struct { + BIGNUM *n; // public modulus + BIGNUM *e; // public exponent + BIGNUM *d; // private exponent + BIGNUM *p; // secret prime factor + BIGNUM *q; // secret prime factor + BIGNUM *dmp1; // d mod (p-1) + BIGNUM *dmq1; // d mod (q-1) + BIGNUM *iqmp; // q^-1 mod p + // ... +} RSA; +.Ed +.Pp +In public keys, the private exponent +.Fa d +and the related secret values +.Fa p , q , dmp1 , dmp2 , +and +.Fa iqmp +are +.Dv NULL . +.Pp +.Fa p , +.Fa q , +.Fa dmp1 , +.Fa dmq1 , +and +.Fa iqmp +may be +.Dv NULL +in private keys, but the RSA operations are much faster when these +values are available. +.Pp +Note that RSA keys may use non-standard +.Vt RSA_METHOD +implementations, either directly or by the use of +.Vt ENGINE +modules. +In some cases (e.g. an +.Vt ENGINE +providing support for hardware-embedded keys), these +.Vt BIGNUM +values will not be used by the implementation or may be used for +alternative data storage. +For this reason, applications should generally avoid using +.Vt RSA +structure elements directly and instead use API functions to query +or modify keys. +.Sh RETURN VALUES +.Fn RSA_new , +.Fn RSAPrivateKey_dup , +and +.Fn RSAPublicKey_dup +return a pointer to the newly allocated structure, or +.Dv NULL +if an error occurs. +An error code can be obtained by +.Xr ERR_get_error 3 . +.Pp +.Fn RSA_up_ref +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr BN_new 3 , +.Xr crypto 3 , +.Xr d2i_RSAPublicKey 3 , +.Xr DH_new 3 , +.Xr DSA_new 3 , +.Xr EVP_PKEY_set1_RSA 3 , +.Xr RSA_blinding_on 3 , +.Xr RSA_check_key 3 , +.Xr RSA_generate_key 3 , +.Xr RSA_get0_key 3 , +.Xr RSA_get_ex_new_index 3 , +.Xr RSA_meth_new 3 , +.Xr RSA_padding_add_PKCS1_type_1 3 , +.Xr RSA_pkey_ctx_ctrl 3 , +.Xr RSA_print 3 , +.Xr RSA_private_encrypt 3 , +.Xr RSA_PSS_PARAMS_new 3 , +.Xr RSA_public_encrypt 3 , +.Xr RSA_security_bits 3 , +.Xr RSA_set_method 3 , +.Xr RSA_sign 3 , +.Xr RSA_sign_ASN1_OCTET_STRING 3 , +.Xr RSA_size 3 +.Sh STANDARDS +SSL, PKCS #1 v2.0 +.Pp +RSA was covered by a US patent which expired in September 2000. +.Sh HISTORY +.Fn RSA_new +and +.Fn RSA_free +appeared in SSLeay 0.4 or earlier. +.Fn RSAPrivateKey_dup +first appeared in SSLeay 0.5.1 and +.Fn RSAPublicKey_dup +in SSLeay 0.5.2. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn RSA_up_ref +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/RSA_padding_add_PKCS1_type_1.3 b/Libraries/libressl/man/RSA_padding_add_PKCS1_type_1.3 new file mode 100644 index 000000000..e7c3a2a62 --- /dev/null +++ b/Libraries/libressl/man/RSA_padding_add_PKCS1_type_1.3 @@ -0,0 +1,236 @@ +.\" $OpenBSD: RSA_padding_add_PKCS1_type_1.3,v 1.8 2018/03/21 16:09:51 schwarze Exp $ +.\" OpenSSL 1e3f62a3 Jul 17 16:47:13 2017 +0200 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt RSA_PADDING_ADD_PKCS1_TYPE_1 3 +.Os +.Sh NAME +.Nm RSA_padding_add_PKCS1_type_1 , +.Nm RSA_padding_check_PKCS1_type_1 , +.Nm RSA_padding_add_PKCS1_type_2 , +.Nm RSA_padding_check_PKCS1_type_2 , +.Nm RSA_padding_add_PKCS1_OAEP , +.Nm RSA_padding_check_PKCS1_OAEP , +.Nm RSA_padding_add_none , +.Nm RSA_padding_check_none +.Nd asymmetric encryption padding +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_padding_add_PKCS1_type_1 +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fc +.Ft int +.Fo RSA_padding_check_PKCS1_type_1 +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fa "int rsa_len" +.Fc +.Ft int +.Fo RSA_padding_add_PKCS1_type_2 +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fc +.Ft int +.Fo RSA_padding_check_PKCS1_type_2 +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fa "int rsa_len" +.Fc +.Ft int +.Fo RSA_padding_add_PKCS1_OAEP +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fa "unsigned char *p" +.Fa "int pl" +.Fc +.Ft int +.Fo RSA_padding_check_PKCS1_OAEP +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fa "int rsa_len" +.Fa "unsigned char *p" +.Fa "int pl" +.Fc +.Ft int +.Fo RSA_padding_add_none +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fc +.Ft int +.Fo RSA_padding_check_none +.Fa "unsigned char *to" +.Fa "int tlen" +.Fa "unsigned char *f" +.Fa "int fl" +.Fa "int rsa_len" +.Fc +.Sh DESCRIPTION +These functions are called from the RSA encrypt, decrypt, sign, and +verify functions. +Normally they should not be called from application programs. +.Pp +However, they can also be called directly to implement padding for other +asymmetric ciphers. +.Fn RSA_padding_add_PKCS1_OAEP +and +.Fn RSA_padding_check_PKCS1_OAEP +may be used in an application combined with +.Dv RSA_NO_PADDING +in order to implement OAEP with an encoding parameter. +.Pp +.Fn RSA_padding_add_* +encodes +.Fa fl +bytes from +.Fa f +so as to fit into +.Fa tlen +bytes and stores the result at +.Fa to . +An error occurs if +.Fa fl +does not meet the size requirements of the encoding method. +.Pp +The following encoding methods are implemented: +.Pp +.Bl -tag -width PKCS1_type_2 -compact +.It PKCS1_type_1 +PKCS #1 v2.0 EMSA-PKCS1-v1_5 (PKCS #1 v1.5 block type 1); +used for signatures +.It PKCS1_type_2 +PKCS #1 v2.0 EME-PKCS1-v1_5 (PKCS #1 v1.5 block type 2) +.It PKCS1_OAEP +PKCS #1 v2.0 EME-OAEP +.It none +simply copy the data +.El +.Pp +.Fn RSA_padding_check_* +verifies that the +.Fa fl +bytes at +.Fa f +contain a valid encoding for a +.Fa rsa_len +byte RSA key in the respective encoding method and stores the recovered +data of at most +.Fa tlen +bytes (for +.Dv RSA_NO_PADDING : +of size +.Fa tlen ) +at +.Fa to . +.Pp +For +.Fn RSA_padding_*_OAEP , +.Fa p +points to the encoding parameter of length +.Fa pl . +.Fa p +may be +.Dv NULL +if +.Fa pl +is 0. +.Sh RETURN VALUES +The +.Fn RSA_padding_add_* +functions return 1 on success or 0 on error. +The +.Fn RSA_padding_check_* +functions return the length of the recovered data or -1 on error. +Error codes can be obtained by calling +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr RSA_new 3 , +.Xr RSA_private_decrypt 3 , +.Xr RSA_public_encrypt 3 , +.Xr RSA_sign 3 , +.Xr RSA_verify 3 +.Sh HISTORY +.Fn RSA_padding_add_PKCS1_type_1 , +.Fn RSA_padding_check_PKCS1_type_1 , +.Fn RSA_padding_add_PKCS1_type_2 , +.Fn RSA_padding_check_PKCS1_type_2 , +.Fn RSA_padding_add_none , +and +.Fn RSA_padding_check_none +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . +.Pp +.Fn RSA_padding_add_PKCS1_OAEP +and +.Fn RSA_padding_check_PKCS1_OAEP +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Sh BUGS +The +.Fn RSA_padding_check_PKCS1_type_2 +padding check leaks timing information which can potentially be +used to mount a Bleichenbacher padding oracle attack. +This is an inherent weakness in the PKCS #1 v1.5 padding design. +Prefer PKCS1_OAEP padding. diff --git a/Libraries/libressl/man/RSA_pkey_ctx_ctrl.3 b/Libraries/libressl/man/RSA_pkey_ctx_ctrl.3 new file mode 100644 index 000000000..cf16977e7 --- /dev/null +++ b/Libraries/libressl/man/RSA_pkey_ctx_ctrl.3 @@ -0,0 +1,403 @@ +.\" $OpenBSD: RSA_pkey_ctx_ctrl.3,v 1.7 2023/05/05 12:22:21 tb Exp $ +.\" full merge up to: +.\" OpenSSL man3/EVP_PKEY_CTX_ctrl.pod 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" OpenSSL man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.pod +.\" 87103969 Oct 1 14:11:57 2018 -0700 +.\" selective merge up to: +.\" OpenSSL man3/EVP_PKEY_CTX_ctrl.pod df75c2b f Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson +.\" and Antoine Salon . +.\" Copyright (c) 2006, 2009, 2013, 2014, 2015, 2017, 2018 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 5 2023 $ +.Dt RSA_PKEY_CTX_CTRL 3 +.Os +.Sh NAME +.Nm RSA_pkey_ctx_ctrl , +.Nm EVP_PKEY_CTX_set_rsa_padding , +.Nm EVP_PKEY_CTX_get_rsa_padding , +.Nm EVP_PKEY_CTX_set_rsa_keygen_bits , +.Nm EVP_PKEY_CTX_set_rsa_keygen_pubexp , +.Nm EVP_PKEY_CTX_set_rsa_mgf1_md , +.Nm EVP_PKEY_CTX_get_rsa_mgf1_md , +.Nm EVP_PKEY_CTX_set_rsa_oaep_md , +.Nm EVP_PKEY_CTX_get_rsa_oaep_md , +.Nm EVP_PKEY_CTX_set0_rsa_oaep_label , +.Nm EVP_PKEY_CTX_get0_rsa_oaep_label , +.Nm EVP_PKEY_CTX_set_rsa_pss_saltlen , +.Nm EVP_PKEY_CTX_get_rsa_pss_saltlen , +.Nm EVP_PKEY_CTX_set_rsa_pss_keygen_md , +.Nm EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md , +.Nm EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen +.Nd RSA private key control operations +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_pkey_ctx_ctrl +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int optype" +.Fa "int cmd" +.Fa "int p1" +.Fa "void *p2" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_padding +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int pad" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_rsa_padding +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int *ppad" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_keygen_bits +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int mbits" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_keygen_pubexp +.Fa "EVP_PKEY_CTX *ctx" +.Fa "BIGNUM *pubexp" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_mgf1_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_rsa_mgf1_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD **pmd" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_oaep_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_rsa_oaep_md +.Fa "EVP_PKEY_CTX *ctx" +.Fa "const EVP_MD **pmd" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set0_rsa_oaep_label +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char *label" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get0_rsa_oaep_label +.Fa "EVP_PKEY_CTX *ctx" +.Fa "unsigned char **plabel" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_pss_saltlen +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int len" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_get_rsa_pss_saltlen +.Fa "EVP_PKEY_CTX *ctx" +.Fa "int *plen" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_pss_keygen_md +.Fa "EVP_PKEY_CTX *pctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md +.Fa "EVP_PKEY_CTX *pctx" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen +.Fa "EVP_PKEY_CTX *pctx" +.Fa "int saltlen" +.Fc +.Sh DESCRIPTION +The function +.Fn RSA_pkey_ctx_ctrl +is a shallow wrapper around +.Xr EVP_PKEY_CTX_ctrl 3 +which only succeeds if +.Fa ctx +matches either +.Dv EVP_PKEY_RSA +or +.Dv EVP_PKEY_RSA_PSS . +.Pp +All the remaining "functions" are implemented as macros. +.Pp +The +.Fn EVP_PKEY_CTX_set_rsa_padding +macro sets the RSA padding mode for +.Fa ctx . +The +.Fa pad +parameter can take the value +.Dv RSA_PKCS1_PADDING +for PKCS#1 padding, +.Dv RSA_NO_PADDING +for no padding, +.Dv RSA_PKCS1_OAEP_PADDING +for OAEP padding (encrypt and decrypt only), +.Dv RSA_X931_PADDING +for X9.31 padding (signature operations only) and +.Dv RSA_PKCS1_PSS_PADDING +(sign and verify only). +Only the last one can be used with keys of the type +.Dv EVP_PKEY_RSA_PSS . +.Pp +Two RSA padding modes behave differently if +.Xr EVP_PKEY_CTX_set_signature_md 3 +is used. +If this macro is called for PKCS#1 padding, the plaintext buffer is an +actual digest value and is encapsulated in a +.Vt DigestInfo +structure according to PKCS#1 when signing and this structure is +expected (and stripped off) when verifying. +If this control is not used with RSA and PKCS#1 padding then the +supplied data is used directly and not encapsulated. +In the case of X9.31 padding for RSA the algorithm identifier byte is +added or checked and removed if this control is called. +If it is not called then the first byte of the plaintext buffer is +expected to be the algorithm identifier byte. +.Pp +The +.Fn EVP_PKEY_CTX_get_rsa_padding +macro retrieves the RSA padding mode for +.Fa ctx . +.Pp +The +.Fn EVP_PKEY_CTX_set_rsa_keygen_bits +macro sets the RSA key length for RSA or RSA-PSS key generation to +.Fa mbits . +The smallest supported value is 512 bits. +If not specified, 1024 bits is used. +.Pp +The +.Fn EVP_PKEY_CTX_set_rsa_keygen_pubexp +macro sets the public exponent value for RSA or RSA-PSS key generation to +.Fa pubexp . +Currently, it should be an odd integer. +The +.Fa pubexp +pointer is used internally by this function, so it should not be modified +or freed after the call. +If this macro is not called, then 65537 is used. +.Pp +The +.Fn EVP_PKEY_CTX_set_rsa_mgf1_md +macro sets the MGF1 digest for RSA padding schemes to +.Fa md . +Unless explicitly specified, the signing digest is used. +The padding mode must have been set to +.Dv RSA_PKCS1_OAEP_PADDING +or +.Dv RSA_PKCS1_PSS_PADDING . +If the key is of the type +.Dv EVP_PKEY_RSA_PSS +and has usage restrictions, an error occurs if an attempt is made +to set the digest to anything other than the restricted value. +.Pp +The +.Fn EVP_PKEY_CTX_get_rsa_mgf1_md +macro retrieves the MGF1 digest for +.Fa ctx . +Unless explicitly specified, the signing digest is used. +The padding mode must have been set to +.Dv RSA_PKCS1_OAEP_PADDING +or +.Dv RSA_PKCS1_PSS_PADDING . +.Ss Optimal asymmetric encryption padding +The following macros require that the padding mode was set to +.Dv RSA_PKCS1_OAEP_PADDING . +.Pp +The +.Fn EVP_PKEY_CTX_set_rsa_oaep_md +macro sets the message digest type used in RSA OAEP to +.Fa md . +.Pp +The +.Fn EVP_PKEY_CTX_get_rsa_oaep_md +macro gets the message digest type used in RSA OAEP to +.Pf * Fa pmd . +.Pp +The +.Fn EVP_PKEY_CTX_set0_rsa_oaep_label +macro sets the RSA OAEP label to +.Fa label +and its length to +.Fa len . +If +.Fa label +is +.Dv NULL +or +.Fa len +is 0, the label is cleared. +The library takes ownership of the label so the caller should not +free the original memory pointed to by +.Fa label . +.Pp +The +.Fn EVP_PKEY_CTX_get0_rsa_oaep_label +macro gets the RSA OAEP label to +.Pf * Fa plabel . +The return value is the label length. +The resulting pointer is owned by the library and should not be +freed by the caller. +.Ss Probabilistic signature scheme +The following macros require that the padding mode was set to +.Dv RSA_PKCS1_PSS_PADDING . +.Pp +The +.Fn EVP_PKEY_CTX_set_rsa_pss_saltlen +macro sets the RSA PSS salt length to +.Fa len . +Three special values are supported: +.Dv RSA_PSS_SALTLEN_DIGEST +sets the salt length to the digest length. +.Dv RSA_PSS_SALTLEN_MAX +sets the salt length to the maximum permissible value. +When signing, +.Dv RSA_PSS_SALTLEN_AUTO +sets the salt length to the maximum permissible value. +When verifying, +.Dv RSA_PSS_SALTLEN_AUTO +causes the salt length to be automatically determined based on the +PSS block structure. +If this macro is not called, a salt length value of +.Dv RSA_PSS_SALTLEN_AUTO +is used by default. +.Pp +If the key has usage restrictions and an attempt is made to set the +salt length below the minimum value, an error occurs. +Also, if the key has usage restrictions, +.Dv RSA_PSS_SALTLEN_AUTO +is not supported for verification. +.Pp +The +.Fn EVP_PKEY_CTX_get_rsa_pss_saltlen +macro retrieves the RSA PSS salt length for +.Fa ctx . +.Pp +Optional parameter restrictions can be specified when generating a PSS +key. +If any restrictions are set using the macros described below, +then all parameters are restricted. +For example, setting a minimum salt length also restricts the digest and +MGF1 algorithms. +If any restrictions are in place, then they are reflected in the +corresponding parameters of the public key when (for example) a +certificate request is signed. +.Pp +.Fn EVP_PKEY_CTX_set_rsa_pss_keygen_md +restricts the digest algorithm the generated key can use to +.Fa md . +.Pp +.Fn EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md +restricts the MGF1 algorithm the generated key can use to +.Fa md . +.Pp +.Fn EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen +restricts the minimum salt length to +.Fa saltlen . +.Sh RETURN VALUES +These functions return a positive value for success or 0 or a negative +value for failure. +In particular, a return value of -2 indicates the operation is not +supported by the public key algorithm. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr EVP_PKEY_CTX_ctrl 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_get_default_digest_nid 3 , +.Xr EVP_PKEY_keygen 3 , +.Xr EVP_PKEY_meth_set_ctrl 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 +.Sh HISTORY +The functions +.Fn EVP_PKEY_CTX_set_rsa_padding , +.Fn EVP_PKEY_CTX_set_rsa_keygen_bits , +.Fn EVP_PKEY_CTX_set_rsa_keygen_pubexp , +and +.Fn EVP_PKEY_CTX_set_rsa_pss_saltlen +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +The functions +.Fn EVP_PKEY_CTX_get_rsa_padding , +.Fn EVP_PKEY_CTX_set_rsa_mgf1_md , +.Fn EVP_PKEY_CTX_get_rsa_mgf1_md , +and +.Fn EVP_PKEY_CTX_get_rsa_pss_saltlen +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . +.Pp +The functions +.Fn EVP_PKEY_CTX_set_rsa_oaep_md , +.Fn EVP_PKEY_CTX_get_rsa_oaep_md , +.Fn EVP_PKEY_CTX_set0_rsa_oaep_label , +and +.Fn EVP_PKEY_CTX_get0_rsa_oaep_label +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.7 . +.Pp +The function +.Fn RSA_pkey_ctx_ctrl +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/RSA_print.3 b/Libraries/libressl/man/RSA_print.3 new file mode 100644 index 000000000..767241ce1 --- /dev/null +++ b/Libraries/libressl/man/RSA_print.3 @@ -0,0 +1,144 @@ +.\" $OpenBSD: RSA_print.3,v 1.9 2019/06/06 01:06:59 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2002, 2003 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt RSA_PRINT 3 +.Os +.Sh NAME +.Nm RSA_print , +.Nm RSA_print_fp , +.Nm DSAparams_print , +.Nm DSAparams_print_fp , +.Nm DSA_print , +.Nm DSA_print_fp , +.Nm DHparams_print , +.Nm DHparams_print_fp +.Nd print cryptographic parameters +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_print +.Fa "BIO *bp" +.Fa "RSA *x" +.Fa "int offset" +.Fc +.Ft int +.Fo RSA_print_fp +.Fa "FILE *fp" +.Fa "RSA *x" +.Fa "int offset" +.Fc +.In openssl/dsa.h +.Ft int +.Fo DSAparams_print +.Fa "BIO *bp" +.Fa "DSA *x" +.Fc +.Ft int +.Fo DSAparams_print_fp +.Fa "FILE *fp" +.Fa "DSA *x" +.Fc +.Ft int +.Fo DSA_print +.Fa "BIO *bp" +.Fa "DSA *x" +.Fa "int offset" +.Fc +.Ft int +.Fo DSA_print_fp +.Fa "FILE *fp" +.Fa "DSA *x" +.Fa "int offset" +.Fc +.In openssl/dh.h +.Ft int +.Fo DHparams_print +.Fa "BIO *bp" +.Fa "DH *x" +.Fc +.Ft int +.Fo DHparams_print_fp +.Fa "FILE *fp" +.Fa "DH *x" +.Fc +.Sh DESCRIPTION +A human-readable hexadecimal output of the components of the RSA key, +DSA parameters or key or DH parameters is printed to +.Fa bp +or +.Fa fp . +.Pp +The output lines are indented by +.Fa offset +spaces. +.Sh RETURN VALUES +These functions return 1 on success or 0 on error. +.Sh SEE ALSO +.Xr BN_bn2bin 3 , +.Xr DH_get0_pqg 3 , +.Xr DH_new 3 , +.Xr DSA_get0_pqg 3 , +.Xr RSA_get0_key 3 , +.Xr RSA_new 3 +.Sh HISTORY +.Fn RSA_print +and +.Fn DHparams_print +first appeared in SSLeay 0.5.1. +.Fn RSA_print_fp , +.Fn DSA_print , +and +.Fn DHparams_print_fp +first appeared in SSLeay 0.6.0. +.Fn DSA_print_fp +first appeared in SSLeay 0.8.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/RSA_private_encrypt.3 b/Libraries/libressl/man/RSA_private_encrypt.3 new file mode 100644 index 000000000..2bf6c57db --- /dev/null +++ b/Libraries/libressl/man/RSA_private_encrypt.3 @@ -0,0 +1,150 @@ +.\" $OpenBSD: RSA_private_encrypt.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL RSA_private_encrypt.pod b41f6b64 Mar 10 15:49:04 2017 +0000 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt RSA_PRIVATE_ENCRYPT 3 +.Os +.Sh NAME +.Nm RSA_private_encrypt , +.Nm RSA_public_decrypt +.Nd low level signature operations +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_private_encrypt +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Ft int +.Fo RSA_public_decrypt +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Sh DESCRIPTION +These functions handle RSA signatures at a low level. +.Pp +.Fn RSA_private_encrypt +signs the +.Fa flen +bytes at +.Fa from +(usually a message digest with an algorithm identifier) using the +private key +.Fa rsa +and stores the signature in +.Fa to . +.Fa to +must point to +.Fn RSA_size rsa +bytes of memory. +.Pp +.Fa padding +denotes one of the following modes: +.Bl -tag -width Ds +.It Dv RSA_PKCS1_PADDING +PKCS #1 v1.5 padding. +This function does not handle the +.Sy algorithmIdentifier +specified in PKCS #1. +When generating or verifying PKCS #1 signatures, +.Xr RSA_sign 3 +and +.Xr RSA_verify 3 +should be used. +.It Dv RSA_NO_PADDING +Raw RSA signature. +This mode should only be used to implement cryptographically sound +padding modes in the application code. +Signing user data directly with RSA is insecure. +.El +.Pp +.Fn RSA_public_decrypt +recovers the message digest from the +.Fa flen +bytes long signature at +.Fa from +using the signer's public key +.Fa rsa . +.Fa to +must point to a memory section large enough to hold the message digest +(which is smaller than +.Fn RSA_size rsa +- 11). +.Fa padding +is the padding mode that was used to sign the data. +.Sh RETURN VALUES +.Fn RSA_private_encrypt +returns the size of the signature (i.e.\& +.Fn RSA_size rsa ) . +.Fn RSA_public_decrypt +returns the size of the recovered message digest. +.Pp +On error, -1 is returned; the error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr RSA_meth_set_priv_enc 3 , +.Xr RSA_new 3 , +.Xr RSA_sign 3 , +.Xr RSA_verify 3 +.Sh HISTORY +.Fn RSA_private_encrypt +and +.Fn RSA_public_decrypt +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Pp +.Dv RSA_NO_PADDING +is available since SSLeay 0.9.0. diff --git a/Libraries/libressl/man/RSA_public_encrypt.3 b/Libraries/libressl/man/RSA_public_encrypt.3 new file mode 100644 index 000000000..be3afdf40 --- /dev/null +++ b/Libraries/libressl/man/RSA_public_encrypt.3 @@ -0,0 +1,247 @@ +.\" $OpenBSD: RSA_public_encrypt.3,v 1.13 2023/09/10 16:04:15 schwarze Exp $ +.\" OpenSSL RSA_public_encrypt.pod 1e3f62a3 Jul 17 16:47:13 2017 +0200 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2004 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2023 $ +.Dt RSA_PUBLIC_ENCRYPT 3 +.Os +.Sh NAME +.Nm RSA_public_encrypt , +.Nm RSA_private_decrypt , +.Nm EVP_PKEY_encrypt_old , +.Nm EVP_PKEY_decrypt_old +.Nd RSA public key cryptography +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_public_encrypt +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.Ft int +.Fo RSA_private_decrypt +.Fa "int flen" +.Fa "const unsigned char *from" +.Fa "unsigned char *to" +.Fa "RSA *rsa" +.Fa "int padding" +.Fc +.In openssl/evp.h +.Ft int +.Fo EVP_PKEY_encrypt_old +.Fa "unsigned char *to" +.Fa "const unsigned char *from" +.Fa "int flen" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft int +.Fo EVP_PKEY_decrypt_old +.Fa "unsigned char *to" +.Fa "const unsigned char *from" +.Fa "int flen" +.Fa "EVP_PKEY *pkey" +.Fc +.Sh DESCRIPTION +.Fn RSA_public_encrypt +encrypts the +.Fa flen +bytes at +.Fa from +(usually a session key) using the public key +.Fa rsa +and stores the ciphertext in +.Fa to . +.Fa to +must point to +.Fn RSA_size rsa +bytes of memory. +.Pp +.Fa padding +denotes one of the following modes: +.Bl -tag -width Ds +.It Dv RSA_PKCS1_PADDING +PKCS #1 v1.5 padding. +This currently is the most widely used mode. +.It Dv RSA_PKCS1_OAEP_PADDING +EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty +encoding parameter. +This mode is recommended for all new applications. +.It Dv RSA_NO_PADDING +Raw RSA encryption. +This mode should only be used to implement cryptographically sound +padding modes in the application code. +Encrypting user data directly with RSA is insecure. +.El +.Pp +.Fa flen +must be less than +.Fn RSA_size rsa +- 11 for the PKCS #1 v1.5 based padding modes, less than +.Fn RSA_size rsa +- 41 for +.Dv RSA_PKCS1_OAEP_PADDING +and exactly +.Fn RSA_size rsa +for +.Dv RSA_NO_PADDING . +.Pp +.Fn RSA_private_decrypt +decrypts the +.Fa flen +bytes at +.Fa from +using the private key +.Fa rsa +and stores the plaintext in +.Fa to . +.Fa to +must point to a memory section large enough to hold the decrypted data +(which is smaller than +.Fn RSA_size rsa ) . +.Fa padding +is the padding mode that was used to encrypt the data. +.Pp +.Fn EVP_PKEY_encrypt_old +is a deprecated wrapper around +.Fn RSA_public_encrypt +that uses the +.Vt RSA +public key stored in +.Fa pkey +and +.Dv RSA_PKCS1_PADDING . +.Pp +.Fn EVP_PKEY_decrypt_old +is a deprecated wrapper around +.Fn RSA_private_decrypt +that uses the +.Vt RSA +private key stored in +.Fa pkey +and +.Dv RSA_PKCS1_PADDING . +.Sh RETURN VALUES +.Fn RSA_public_encrypt +and +.Fn EVP_PKEY_encrypt_old +return the size of the encrypted data (i.e.\& +.Fn RSA_size rsa ) . +.Fn RSA_private_decrypt +and +.Fn EVP_PKEY_decrypt_old +returns the size of the recovered plaintext. +On error, \-1 is returned; the error codes can be obtained by +.Xr ERR_get_error 3 . +.Pp +In addition to the return values documented above, +.Fn EVP_PKEY_encrypt_old +may return 0 if the +.Xr EVP_PKEY_id 3 +of +.Fa pkey +is not +.Dv EVP_PKEY_RSA . +.Sh SEE ALSO +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr RSA_meth_set_priv_dec 3 , +.Xr RSA_new 3 , +.Xr RSA_size 3 +.Sh STANDARDS +SSL, PKCS #1 v2.0 +.Sh HISTORY +.Fn RSA_public_encrypt +and +.Fn RSA_private_decrypt +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Pp +.Fn EVP_PKEY_encrypt +and +.Fn EVP_PKEY_decrypt +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . +There were renamed to +.Fn EVP_PKEY_encrypt_old +and +.Fn EVP_PKEY_decrypt_old +in OpenSSL 1.0.0 and +.Ox 4.9 . +.Pp +.Dv RSA_NO_PADDING +is available since SSLeay 0.9.0. +OAEP was added in OpenSSL 0.9.2b. +.Sh BUGS +Decryption failures in the +.Dv RSA_PKCS1_PADDING +mode leak information which can potentially be used to mount a +Bleichenbacher padding oracle attack. +This is an inherent weakness in the PKCS #1 v1.5 padding design. +Prefer +.Dv RSA_PKCS1_OAEP_PADDING . diff --git a/Libraries/libressl/man/RSA_security_bits.3 b/Libraries/libressl/man/RSA_security_bits.3 new file mode 100644 index 000000000..f7024a795 --- /dev/null +++ b/Libraries/libressl/man/RSA_security_bits.3 @@ -0,0 +1,137 @@ +.\" $OpenBSD: RSA_security_bits.3,v 1.1 2022/07/13 17:32:16 schwarze Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt RSA_SECURITY_BITS 3 +.Os +.Sh NAME +.Nm RSA_security_bits , +.Nm DSA_security_bits , +.Nm DH_security_bits , +.Nm BN_security_bits +.Nd get security strength +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fn RSA_security_bits "const RSA *rsa" +.In openssl/dsa.h +.Ft int +.Fn DSA_security_bits "const DSA *dsa" +.In openssl/dh.h +.Ft int +.Fn DH_security_bits "const DH *dh" +.In openssl/bn.h +.Ft int +.Fo BN_security_bits +.Fa "int pubbits" +.Fa "int privbits" +.Fc +.Sh DESCRIPTION +These functions return the security strength of some specific types of +cryptographic keys, measured in bits. +It is approximately the binary logarithm of the number of operations +an attacker has to perform in order to break the key. +.Pp +.Fn RSA_security_bits +uses only the number of significant bits in the public modulus of +.Fa rsa +as returned by +.Xr RSA_bits 3 . +It returns +.Bl -column 256 for 15360 last_column -offset indent +.It 256 Ta for Ta 15360 Ta or more significant bits +.It 192 Ta Ta 7680 Ta +.It 128 Ta Ta 3072 Ta +.It 112 Ta Ta 2048 Ta +.It 80 Ta Ta 1024 Ta +.El +.Pp +or 0 otherwise. +.Pp +.Fn DSA_security_bits +uses the number of significant bits in the public domain parameter +.Fa p +contained in the +.Fa dsa +object, which is equal to the size of the public key, in the same way as +.Fn RSA_security_bits . +In addition, the public domain parameter +.Fa q +contained in the +.Fa dsa +object, which is equal to the size of the private key, is inspected. +The return value is either the security strength according to the above table +or half the size of the private key, whichever is smaller. +If the return value would be smaller than 80, 0 is returned instead. +.Pp +.Fn DH_security_bits +uses the number of significant bits in the shared secret contained in the +.Fa dh +object as returned by +.Xr DH_bits 3 +in the same way as +.Fn RSA_security_bits . +If +.Fa dh +contains the domain parameter +.Fa q , +its number of significant bits is used in the same way as for +.Fn DSA_security_bits +to limit the return value. +Otherwise, if +.Fa dh +contains the length of the secret exponent in bits, +that number is used. +If neither is available, only the above table is used +without calculating a minimum. +.Pp +.Fn BN_security_bits +is a combined function. +If \-1 is passed for the +.Fa privbits +argument, it behaves like +.Fn RSA_security_bits . +Otherwise, it behaves like +.Fn DSA_security_bits . +.Sh RETURN VALUES +All these functions return numbers in the range from 0 to 256 inclusive. +.Pp +.Fn DSA_security_bits +fails and returns \-1 unless both of the +.Fa p +and +.Fa q +domain parameters are present. +.Sh SEE ALSO +.Xr BN_num_bits 3 , +.Xr DH_bits 3 , +.Xr DH_get0_pqg 3 , +.Xr DSA_get0_pqg 3 , +.Xr RSA_bits 3 , +.Xr SSL_CTX_set_security_level 3 +.Rs +.%A Elaine Barker +.%T Recommendation for Key Management +.%I U.S. National Institute of Standards and Technology +.%R NIST Special Publication 800-57 Part 1 Revision 5 +.%U https://doi.org/10.6028/NIST.SP.800-57pt1r5 +.%C Gaithersburg, MD +.%D May 2020 +.Re +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 7.2 . diff --git a/Libraries/libressl/man/RSA_set_method.3 b/Libraries/libressl/man/RSA_set_method.3 new file mode 100644 index 000000000..818b64823 --- /dev/null +++ b/Libraries/libressl/man/RSA_set_method.3 @@ -0,0 +1,280 @@ +.\" $OpenBSD: RSA_set_method.3,v 1.17 2023/05/14 09:33:19 tb Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller +.\" and Geoff Thorpe . +.\" Copyright (c) 2000, 2002, 2007, 2014 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 14 2023 $ +.Dt RSA_SET_METHOD 3 +.Os +.Sh NAME +.Nm RSA_set_default_method , +.Nm RSA_get_default_method , +.Nm RSA_set_method , +.Nm RSA_get_method , +.Nm RSA_PKCS1_SSLeay , +.Nm RSA_flags , +.Nm RSA_new_method +.Nd select RSA method +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft void +.Fo RSA_set_default_method +.Fa "const RSA_METHOD *meth" +.Fc +.Ft const RSA_METHOD * +.Fn RSA_get_default_method void +.Ft int +.Fo RSA_set_method +.Fa "RSA *rsa" +.Fa "const RSA_METHOD *meth" +.Fc +.Ft const RSA_METHOD * +.Fo RSA_get_method +.Fa "const RSA *rsa" +.Fc +.Ft const RSA_METHOD * +.Fn RSA_PKCS1_SSLeay void +.Ft int +.Fo RSA_flags +.Fa "const RSA *rsa" +.Fc +.Ft RSA * +.Fo RSA_new_method +.Fa "ENGINE *engine" +.Fc +.Sh DESCRIPTION +An +.Vt RSA_METHOD +object contains pointers to the functions used for RSA operations. +By default, the internal implementation returned by +.Fn RSA_PKCS1_SSLeay +is used. +By selecting another method, alternative implementations +such as hardware accelerators may be used. +.Pp +.Fn RSA_set_default_method +selects +.Fa meth +as the default method for all +.Vt RSA +structures created later. +If any +.Vt ENGINE +was registered with +.Xr ENGINE_register_RSA 3 +that can be successfully initialized, it overrides the default. +.Pp +.Fn RSA_get_default_method +returns a pointer to the current default method, +even if it is actually overridden by an +.Vt ENGINE . +.Pp +.Fn RSA_set_method +selects +.Fa meth +to perform all operations using the key +.Fa rsa . +This replaces the previous +.Vt RSA_METHOD +used by the RSA key, calling the +.Fa finish +function set up with +.Xr RSA_meth_set_finish 3 +if any, and if the previous method was supplied by an +.Vt ENGINE , +.Xr ENGINE_finish 3 +is called on it. +If +.Fa meth +contains an +.Fa init +function set up with +.Xr RSA_meth_set_init 3 , +that function is called just before returning from +.Fn RSA_set_method . +.Pp +It is possible to have RSA keys that only work with certain +.Vt RSA_METHOD +implementations (e.g. from an +.Vt ENGINE +module that supports embedded hardware-protected keys), +and in such cases attempting to change the +.Vt RSA_METHOD +for the key can have unexpected results. +.Pp +.Fn RSA_get_method +returns a pointer to the +.Vt RSA_METHOD +being used by +.Fa rsa . +This method may or may not be supplied by an +.Vt ENGINE +implementation but if it is, the return value can only be guaranteed +to be valid as long as the RSA key itself is valid and does not +have its implementation changed by +.Fn RSA_set_method . +.Pp +The misleadingly named function +.Fn RSA_flags +returns the flags that are set for the current +.Vt RSA_METHOD +of +.Fa rsa . +The flags used by +.Fa rsa +itself can instead be tested with +.Xr RSA_test_flags 3 . +See the +.Sx BUGS +section for more details. +.Pp +.Fn RSA_new_method +allocates and initializes an +.Vt RSA +structure so that +.Fa engine +is used for the RSA operations. +If +.Fa engine +is +.Dv NULL , +.Xr ENGINE_get_default_RSA 3 +is used. +If that returns +.Dv NULL , +the default method controlled by +.Fn RSA_set_default_method +is used. +.Pp +The initial +.Fa flags +are copied from the +.Vt RSA_METHOD +object used and will not be affected by later changes to that object, +but may be modified by the optional +.Fa init +function which may have been set up with +.Xr RSA_meth_set_init 3 +and which is called just before returning from +.Fn RSA_new_method . +.Sh RETURN VALUES +.Fn RSA_PKCS1_SSLeay , +.Fn RSA_get_default_method , +and +.Fn RSA_get_method +return pointers to the respective +.Vt RSA_METHOD . +.Pp +.Fn RSA_set_method +returns 1 on success or 0 on failure. +Currently, it cannot fail. +.Pp +.Fn RSA_new_method +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 +if the allocation fails. +Otherwise it returns a pointer to the newly allocated structure. +.Sh SEE ALSO +.Xr ENGINE_get_default_RSA 3 , +.Xr ENGINE_register_RSA 3 , +.Xr ENGINE_set_default_RSA 3 , +.Xr RSA_meth_new 3 , +.Xr RSA_new 3 +.Sh HISTORY +.Fn RSA_set_default_method , +.Fn RSA_PKCS1_SSLeay , +and +.Fn RSA_new_method +first appeared in SSLeay 0.8.0. +.Fn RSA_flags +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn RSA_get_default_method , +.Fn RSA_set_method , +and +.Fn RSA_get_method +as well as the +.Fa rsa_sign +and +.Fa rsa_verify +components of +.Vt RSA_METHOD +first appeared in OpenSSL 0.9.4 and have been available since +.Ox 2.6 . +.Sh BUGS +The behaviour of +.Fn RSA_flags +is a misfeature that is left as-is for now to avoid creating +compatibility problems. +RSA functionality, such as the encryption functions, are controlled by +the +.Fa flags +value in the +.Vt RSA +key itself, not by the +.Fa flags +value in the +.Vt RSA_METHOD +attached to the RSA key (which is what this function returns). +If the flags element of an +.Vt RSA +key is changed, the changes will be honoured by RSA functionality +but will not be reflected in the return value of the +.Fn RSA_flags +function - in effect +.Fn RSA_flags +behaves more like an +.Fn RSA_default_flags +function, which does not +currently exist. diff --git a/Libraries/libressl/man/RSA_sign.3 b/Libraries/libressl/man/RSA_sign.3 new file mode 100644 index 000000000..65e9dc99b --- /dev/null +++ b/Libraries/libressl/man/RSA_sign.3 @@ -0,0 +1,147 @@ +.\" $OpenBSD: RSA_sign.3,v 1.8 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL aa90ca11 Aug 20 15:48:56 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2005, 2014, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt RSA_SIGN 3 +.Os +.Sh NAME +.Nm RSA_sign , +.Nm RSA_verify +.Nd RSA signatures +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_sign +.Fa "int type" +.Fa "const unsigned char *m" +.Fa "unsigned int m_len" +.Fa "unsigned char *sigret" +.Fa "unsigned int *siglen" +.Fa "RSA *rsa" +.Fc +.Ft int +.Fo RSA_verify +.Fa "int type" +.Fa "const unsigned char *m" +.Fa "unsigned int m_len" +.Fa "unsigned char *sigbuf" +.Fa "unsigned int siglen" +.Fa "RSA *rsa" +.Fc +.Sh DESCRIPTION +.Fn RSA_sign +signs the message digest +.Fa m +of size +.Fa m_len +using the private key +.Fa rsa +using RSASSA-PKCS1-v1_5 as specified in RFC 3447. +It stores the signature in +.Fa sigret +and the signature size in +.Fa siglen . +.Fa sigret +must point to +.Fn RSA_size rsa +bytes of memory. +Note that PKCS #1 adds meta-data, placing limits on the size of the key +that can be used. +See +.Xr RSA_private_encrypt 3 +for lower-level operations. +.Pp +.Fa type +denotes the message digest algorithm that was used to generate +.Fa m . +If +.Fa type +is +.Sy NID_md5_sha1 , +an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding and +no algorithm identifier) is created. +.Pp +.Fn RSA_verify +verifies that the signature +.Fa sigbuf +of size +.Fa siglen +matches a given message digest +.Fa m +of size +.Fa m_len . +.Fa type +denotes the message digest algorithm that was used to generate the +signature. +.Fa rsa +is the signer's public key. +.Sh RETURN VALUES +.Fn RSA_sign +returns 1 on success. +.Fn RSA_verify +returns 1 on successful verification. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr RSA_meth_set_sign 3 , +.Xr RSA_new 3 , +.Xr RSA_private_encrypt 3 , +.Xr RSA_public_decrypt 3 +.Sh STANDARDS +SSL, PKCS #1 v2.0 +.Sh HISTORY +.Fn RSA_sign +first appeared in SSLeay 0.4.4. +.Fn RSA_verify +first appeared in SSLeay 0.6.0. +Both functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/RSA_sign_ASN1_OCTET_STRING.3 b/Libraries/libressl/man/RSA_sign_ASN1_OCTET_STRING.3 new file mode 100644 index 000000000..34aef42c4 --- /dev/null +++ b/Libraries/libressl/man/RSA_sign_ASN1_OCTET_STRING.3 @@ -0,0 +1,131 @@ +.\" $OpenBSD: RSA_sign_ASN1_OCTET_STRING.3,v 1.7 2019/06/10 14:58:48 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 10 2019 $ +.Dt RSA_SIGN_ASN1_OCTET_STRING 3 +.Os +.Sh NAME +.Nm RSA_sign_ASN1_OCTET_STRING , +.Nm RSA_verify_ASN1_OCTET_STRING +.Nd RSA signatures +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_sign_ASN1_OCTET_STRING +.Fa "int dummy" +.Fa "unsigned char *m" +.Fa "unsigned int m_len" +.Fa "unsigned char *sigret" +.Fa "unsigned int *siglen" +.Fa "RSA *rsa" +.Fc +.Ft int +.Fo RSA_verify_ASN1_OCTET_STRING +.Fa "int dummy" +.Fa "unsigned char *m" +.Fa "unsigned int m_len" +.Fa "unsigned char *sigbuf" +.Fa "unsigned int siglen" +.Fa "RSA *rsa" +.Fc +.Sh DESCRIPTION +.Fn RSA_sign_ASN1_OCTET_STRING +signs the octet string +.Fa m +of size +.Fa m_len +using the private key +.Fa rsa +represented in DER using PKCS #1 padding. +It stores the signature in +.Fa sigret +and the signature size in +.Fa siglen . +.Fa sigret +must point to +.Fn RSA_size rsa +bytes of memory. +.Pp +.Fa dummy +is ignored. +.Pp +.Fn RSA_verify_ASN1_OCTET_STRING +verifies that the signature +.Fa sigbuf +of size +.Fa siglen +is the DER representation of a given octet string +.Fa m +of size +.Fa m_len . +.Fa dummy +is ignored. +.Fa rsa +is the signer's public key. +.Sh RETURN VALUES +.Fn RSA_sign_ASN1_OCTET_STRING +returns 1 on success or 0 otherwise. +.Fn RSA_verify_ASN1_OCTET_STRING +returns 1 on successful verification or 0 otherwise. +.Pp +The error codes can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr RSA_new 3 , +.Xr RSA_sign 3 , +.Xr RSA_verify 3 +.Sh HISTORY +.Fn RSA_sign_ASN1_OCTET_STRING +and +.Fn RSA_verify_ASN1_OCTET_STRING +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Sh BUGS +These functions serve no recognizable purpose. diff --git a/Libraries/libressl/man/RSA_size.3 b/Libraries/libressl/man/RSA_size.3 new file mode 100644 index 000000000..8a552b4e6 --- /dev/null +++ b/Libraries/libressl/man/RSA_size.3 @@ -0,0 +1,97 @@ +.\" $OpenBSD: RSA_size.3,v 1.10 2022/07/13 21:51:35 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller and +.\" Kurt Roeckx . +.\" Copyright (c) 2000, 2002, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt RSA_SIZE 3 +.Os +.Sh NAME +.Nm RSA_size , +.Nm RSA_bits +.Nd get the RSA modulus size +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft int +.Fo RSA_size +.Fa "const RSA *rsa" +.Fc +.Ft int +.Fo RSA_bits +.Fa "const RSA *rsa" +.Fc +.Sh DESCRIPTION +.Fn RSA_size +returns the RSA modulus size in bytes. +It can be used to determine how much memory must be allocated for +an RSA encrypted value. +.Pp +.Fn RSA_bits +returns the number of significant bits. +.Pp +.Fa rsa +and +.Fa rsa->n +must not be +.Dv NULL . +.Sh RETURN VALUES +The size. +.Sh SEE ALSO +.Xr BN_num_bits 3 , +.Xr RSA_get0_key 3 , +.Xr RSA_new 3 , +.Xr RSA_security_bits 3 +.Sh HISTORY +.Fn RSA_size +first appeared in SSLeay 0.4.4 and has been available since +.Ox 2.4 . +.Pp +.Fn RSA_bits +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SHA1.3 b/Libraries/libressl/man/SHA1.3 new file mode 100644 index 000000000..f5061e56e --- /dev/null +++ b/Libraries/libressl/man/SHA1.3 @@ -0,0 +1,276 @@ +.\" $OpenBSD: SHA1.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Ulf Moeller and +.\" Matt Caswell . +.\" Copyright (c) 2000, 2006, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SHA1 3 +.Os +.Sh NAME +.Nm SHA1 , +.Nm SHA1_Init , +.Nm SHA1_Update , +.Nm SHA1_Final , +.Nm SHA224 , +.Nm SHA224_Init , +.Nm SHA224_Update , +.Nm SHA224_Final , +.Nm SHA256 , +.Nm SHA256_Init , +.Nm SHA256_Update , +.Nm SHA256_Final , +.Nm SHA384 , +.Nm SHA384_Init , +.Nm SHA384_Update , +.Nm SHA384_Final , +.Nm SHA512 , +.Nm SHA512_Init , +.Nm SHA512_Update , +.Nm SHA512_Final +.Nd Secure Hash Algorithm +.Sh SYNOPSIS +.In openssl/sha.h +.Ft unsigned char * +.Fo SHA1 +.Fa "const unsigned char *d" +.Fa "size_t n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo SHA1_Init +.Fa "SHA_CTX *c" +.Fc +.Ft int +.Fo SHA1_Update +.Fa "SHA_CTX *c" +.Fa "const void *data" +.Fa "size_t len" +.Fc +.Ft int +.Fo SHA1_Final +.Fa "unsigned char *md" +.Fa "SHA_CTX *c" +.Fc +.Ft unsigned char * +.Fo SHA224 +.Fa "const unsigned char *d" +.Fa "size_t n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo SHA224_Init +.Fa "SHA256_CTX *c" +.Fc +.Ft int +.Fo SHA224_Update +.Fa "SHA256_CTX *c" +.Fa "const void *data" +.Fa "size_t len" +.Fc +.Ft int +.Fo SHA224_Final +.Fa "unsigned char *md" +.Fa "SHA256_CTX *c" +.Fc +.Ft unsigned char * +.Fo SHA256 +.Fa "const unsigned char *d" +.Fa "size_t n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo SHA256_Init +.Fa "SHA256_CTX *c" +.Fc +.Ft int +.Fo SHA256_Update +.Fa "SHA256_CTX *c" +.Fa "const void *data" +.Fa "size_t len" +.Fc +.Ft int +.Fo SHA256_Final +.Fa "unsigned char *md" +.Fa "SHA256_CTX *c" +.Fc +.Ft unsigned char * +.Fo SHA384 +.Fa "const unsigned char *d" +.Fa "size_t n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo SHA384_Init +.Fa "SHA512_CTX *c" +.Fc +.Ft int +.Fo SHA384_Update +.Fa "SHA512_CTX *c" +.Fa "const void *data" +.Fa "size_t len" +.Fc +.Ft int +.Fo SHA384_Final +.Fa "unsigned char *md" +.Fa "SHA512_CTX *c" +.Fc +.Ft unsigned char * +.Fo SHA512 +.Fa "const unsigned char *d" +.Fa "size_t n" +.Fa "unsigned char *md" +.Fc +.Ft int +.Fo SHA512_Init +.Fa "SHA512_CTX *c" +.Fc +.Ft int +.Fo SHA512_Update +.Fa "SHA512_CTX *c" +.Fa "const void *data" +.Fa "size_t len" +.Fc +.Ft int +.Fo SHA512_Final +.Fa "unsigned char *md" +.Fa "SHA512_CTX *c" +.Fc +.Sh DESCRIPTION +SHA-1 (Secure Hash Algorithm) is a cryptographic hash function with a +160-bit output. +.Pp +.Fn SHA1 +computes the SHA-1 message digest of the +.Fa n +bytes at +.Fa d +and places it in +.Fa md , +which must have space for +.Dv SHA_DIGEST_LENGTH +== 20 bytes of output. +If +.Fa md +is +.Dv NULL , +the digest is placed in a static array, which is not thread safe. +.Pp +The following functions may be used if the message is not completely +stored in memory: +.Pp +.Fn SHA1_Init +initializes a +.Vt SHA_CTX +structure. +.Pp +.Fn SHA1_Update +can be called repeatedly with chunks of the message to be hashed +.Pq Fa len No bytes at Fa data . +.Pp +.Fn SHA1_Final +places the message digest in +.Fa md , +which must have space for +.Dv SHA_DIGEST_LENGTH +== 20 bytes of output, and erases the +.Vt SHA_CTX . +.Pp +The SHA224, SHA256, SHA384, and SHA512 families of functions operate +in the same way as the SHA1 functions. +Note that SHA224 and SHA256 use a +.Vt SHA256_CTX +object instead of +.Vt SHA_CTX , +and SHA384 and SHA512 use +.Vt SHA512_CTX . +The buffer +.Fa md +must have space for the output from the SHA variant being used: +.Dv SHA224_DIGEST_LENGTH , +.Dv SHA256_DIGEST_LENGTH , +.Dv SHA384_DIGEST_LENGTH , +or +.Dv SHA512_DIGEST_LENGTH +bytes. +.Pp +Applications should use the higher level functions +.Xr EVP_DigestInit 3 +etc. instead of calling the hash functions directly. +.Pp +The predecessor of SHA-1, SHA, is also implemented, but it should be +used only when backward compatibility is required. +.Sh RETURN VALUES +.Fn SHA1 , +.Fn SHA224 , +.Fn SHA256 , +.Fn SHA384 , +and +.Fn SHA512 +return a pointer to the hash value. +The other functions return 1 for success or 0 otherwise. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr HMAC 3 , +.Xr RIPEMD160 3 +.Sh STANDARDS +SHA: US Federal Information Processing Standard FIPS PUB 180 (Secure +Hash Standard), SHA-1: US Federal Information Processing Standard FIPS +PUB 180-1 (Secure Hash Standard), ANSI X9.30 +.Sh HISTORY +.Fn SHA1 , +.Fn SHA1_Init , +.Fn SHA1_Update , +and +.Fn SHA1_Final +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +The other functions first appeared in OpenSSL 0.9.8 +and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/SMIME_crlf_copy.3 b/Libraries/libressl/man/SMIME_crlf_copy.3 new file mode 100644 index 000000000..3b4613847 --- /dev/null +++ b/Libraries/libressl/man/SMIME_crlf_copy.3 @@ -0,0 +1,96 @@ +.\" $OpenBSD: SMIME_crlf_copy.3,v 1.3 2023/05/01 07:28:11 tb Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt SMIME_CRLF_COPY 3 +.Os +.Sh NAME +.Nm SMIME_crlf_copy +.Nd buffered copy between BIOs +.Sh SYNOPSIS +.Ft int +.Fo SMIME_crlf_copy +.Fa "BIO *in_bio" +.Fa "BIO *out_bio" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn SMIME_crlf_copy +copies data from +.Fa in_bio +to +.Fa out_bio . +To avoid many small write operations on +.Fa out_bio , +a buffering BIO created with +.Xr BIO_f_buffer 3 +is temporarily prepended to it. +.Pp +If the bit +.Dv SMIME_BINARY +is set in the +.Fa flags +argument, all the data is copied verbatim using +.Xr BIO_read 3 +and +.Xr BIO_write 3 . +.Pp +Otherwise, the data is read as text. +All trailing carriage return and newline characters are discarded +from every input line and a single pair of carriage return and +newline characters is appended to mark the end of every output line, +except that the last output line will end without such a pair if +the last input line does not have a newline character at the end. +.Pp +If the bit +.Dv SMIME_TEXT +is set in the +.Fa flags +argument and the bit +.Dv SMIME_BINARY +is not set, the line +.Qq Content-Type: text/plain +is prepended to the output +with two pairs of carriage return and newline characters after it. +.Pp +In any case, +.Xr BIO_flush 3 +is called on the output at the end of the function. +.Sh RETURN VALUES +.Fn SMIME_crlf_copy +is intended to return 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr BIO_f_buffer 3 , +.Xr BIO_flush 3 , +.Xr BIO_new 3 , +.Xr BIO_push 3 , +.Xr BIO_read 3 , +.Xr SMIME_text 3 , +.Xr SMIME_write_ASN1 3 +.Sh HISTORY +.Fn SMIME_crlf_copy +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh BUGS +.Fn SMIME_crlf_copy +silently ignores most errors and may return 1 +even if it lost part or all of the data in transit. +.Pp +Only blocking BIOs are supported. +If any of the +.Vt BIO +arguments is non-blocking, part or all of the data is likely +to be silently lost in transit. diff --git a/Libraries/libressl/man/SMIME_read_ASN1.3 b/Libraries/libressl/man/SMIME_read_ASN1.3 new file mode 100644 index 000000000..320064567 --- /dev/null +++ b/Libraries/libressl/man/SMIME_read_ASN1.3 @@ -0,0 +1,124 @@ +.\" $OpenBSD: SMIME_read_ASN1.3,v 1.2 2021/12/14 15:22:49 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL SMIME_read_PKCS7.pod 83cf7abf May 29 13:07:08 2018 +0100 +.\" OpenSSL SMIME_read_CMS.pod b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006, 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt SMIME_READ_ASN1 3 +.Os +.Sh NAME +.Nm SMIME_read_ASN1 +.Nd generic S/MIME message parser +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_VALUE * +.Fo SMIME_read_ASN1 +.Fa "BIO *in_bio" +.Fa "BIO **out_bio" +.Fa "const ASN1_ITEM *it" +.Fc +.Sh DESCRIPTION +.Fn SMIME_read_ASN1 +reads a message in S/MIME format from +.Fa in_bio . +.Pp +If the message uses cleartext signing, the content is saved in a memory +.Vt BIO +which is written to +.Pf * Fa out_bio . +Otherwise, +.Pf * Fa out_bio +is set to +.Dv NULL . +.Pp +To support future functionality, if +.Fa out_bio +is not +.Dv NULL , +.Pf * Fa out_bio +should be initialized to +.Dv NULL +before calling +.Fn SMIME_read_ASN1 . +.Sh RETURN VALUES +.Fn SMIME_read_ASN1 +returns a newly allocated object of type +.Fa it +or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_item_d2i_bio 3 , +.Xr BIO_f_base64 3 , +.Xr BIO_new 3 , +.Xr SMIME_read_CMS 3 , +.Xr SMIME_read_PKCS7 3 , +.Xr SMIME_text 3 +.Sh HISTORY +.Fn SMIME_read_ASN1 +first appeared in OpenSSL 0.9.8h and has been available since +.Ox 4.5 . +.Sh BUGS +The MIME parser used by +.Fn SMIME_read_ASN1 +is somewhat primitive. +While it will handle most S/MIME messages, more complex compound +formats may not work. +.Pp +The parser assumes that the +structure is always base64 encoded, and it will not handle the case +where it is in binary format or uses quoted printable format. +.Pp +The use of a memory +to hold the signed content limits the size of the message which can +be processed due to memory restraints: a streaming single pass +option should be available. diff --git a/Libraries/libressl/man/SMIME_read_CMS.3 b/Libraries/libressl/man/SMIME_read_CMS.3 new file mode 100644 index 000000000..e1b1d0749 --- /dev/null +++ b/Libraries/libressl/man/SMIME_read_CMS.3 @@ -0,0 +1,132 @@ +.\" $OpenBSD: SMIME_read_CMS.3,v 1.7 2021/12/14 14:30:50 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt SMIME_READ_CMS 3 +.Os +.Sh NAME +.Nm SMIME_read_CMS +.Nd extract CMS ContentInfo from an S/MIME message +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo SMIME_read_CMS +.Fa "BIO *in" +.Fa "BIO **bcont" +.Fc +.Sh DESCRIPTION +.Fn SMIME_read_CMS +parses a message in S/MIME format from +.Fa in . +.Pp +If the message uses cleartext signing, the content is saved in a memory BIO +which is written to +.Pf * Fa bcont +and which can then be passed to +.Xr CMS_verify 3 +with the +.Dv CMS_DETACHED +flag set. +Otherwise, +.Pf * Fa bcont +is set to +.Dv NULL +and the type of the returned structure can be determined using +.Xr CMS_get0_type 3 . +.Pp +To support future functionality if +.Fa bcont +is not +.Dv NULL , +.Pf * Fa bcont +should be initialized to +.Dv NULL , +for example: +.Bd -literal -offset indent +BIO *cont = NULL; +CMS_ContentInfo *cms = SMIME_read_CMS(in, &cont); +.Ed +.Sh RETURN VALUES +.Fn SMIME_read_CMS +returns a valid +.Vt CMS_ContentInfo +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_decrypt 3 , +.Xr CMS_get0_type 3 , +.Xr CMS_verify 3 , +.Xr d2i_CMS_ContentInfo 3 , +.Xr SMIME_read_ASN1 3 , +.Xr SMIME_write_CMS 3 +.Sh HISTORY +.Fn SMIME_read_CMS +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . +.Sh BUGS +The MIME parser used by +.Fn SMIME_read_CMS +is somewhat primitive. +While it will handle most S/MIME messages, more complex compound formats +may not work. +.Pp +The parser assumes that the +.Vt CMS_ContentInfo +structure is always base64 encoded and will not handle the case +where it is in binary format or uses quoted printable format. +.Pp +The use of a memory BIO to hold the signed content limits the size of +the message which can be processed due to memory restraints: a streaming +single pass option should be available. diff --git a/Libraries/libressl/man/SMIME_read_PKCS7.3 b/Libraries/libressl/man/SMIME_read_PKCS7.3 new file mode 100644 index 000000000..dbe2765b8 --- /dev/null +++ b/Libraries/libressl/man/SMIME_read_PKCS7.3 @@ -0,0 +1,150 @@ +.\" $OpenBSD: SMIME_read_PKCS7.3,v 1.8 2021/12/14 14:30:50 schwarze Exp $ +.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt SMIME_READ_PKCS7 3 +.Os +.Sh NAME +.Nm SMIME_read_PKCS7 +.Nd extract a PKCS#7 object from an S/MIME message +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft PKCS7 * +.Fo SMIME_read_PKCS7 +.Fa "BIO *in" +.Fa "BIO **bcont" +.Fc +.Sh DESCRIPTION +.Fn SMIME_read_PKCS7 +parses a message in S/MIME format. +.Pp +.Fa in +is a +.Vt BIO +to read the message from. +.Pp +If cleartext signing is used, then the content is saved in a memory +.Vt BIO +which is written to +.Pf * Fa bcont , +otherwise +.Pf * Fa bcont +is set to +.Dv NULL . +.Pp +The parsed PKCS#7 structure is returned, or +.Dv NULL +if an error occurred. +.Pp +If +.Pf * Fa bcont +is not +.Dv NULL , +then the message is clear text signed. +.Pf * Fa bcont +can then be passed to +.Xr PKCS7_verify 3 +with the +.Dv PKCS7_DETACHED +flag set. +.Pp +Otherwise the type of the returned structure can be determined using the +.Fn PKCS7_type_is_* +macros defined in +.In openssl/pkcs7.h . +.Pp +To support future functionality, if +.Fa bcont +is not +.Dv NULL , +.Pf * Fa bcont +should be initialized to +.Dv NULL . +For example: +.Bd -literal -offset indent +BIO *cont = NULL; +PKCS7 *p7; + +p7 = SMIME_read_PKCS7(in, &cont); +.Ed +.Sh RETURN VALUES +.Fn SMIME_read_PKCS7 +returns a valid +.Vt PKCS7 +structure or +.Dv NULL +if an error occurred. +The error can be obtained from +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr PKCS7_new 3 , +.Xr SMIME_read_ASN1 3 , +.Xr SMIME_write_PKCS7 3 +.Sh HISTORY +.Fn SMIME_read_PKCS7 +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Sh BUGS +The MIME parser used by +.Fn SMIME_read_PKCS7 +is somewhat primitive. +While it will handle most S/MIME messages, more complex compound +formats may not work. +.Pp +The parser assumes that the +.Vt PKCS7 +structure is always base64 encoded, and it will not handle the case +where it is in binary format or uses quoted printable format. +.Pp +The use of a memory +.Vt BIO +to hold the signed content limits the size of the message which can +be processed due to memory restraints: a streaming single pass +option should be available. diff --git a/Libraries/libressl/man/SMIME_text.3 b/Libraries/libressl/man/SMIME_text.3 new file mode 100644 index 000000000..a4c968992 --- /dev/null +++ b/Libraries/libressl/man/SMIME_text.3 @@ -0,0 +1,57 @@ +.\" $OpenBSD: SMIME_text.3,v 1.1 2021/12/14 15:22:49 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt SMIME_TEXT 3 +.Os +.Sh NAME +.Nm SMIME_text +.Nd remove text/plain MIME headers +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo SMIME_text +.Fa "BIO *in_bio" +.Fa "BIO *out_bio" +.Fc +.Sh DESCRIPTION +.Fn SMIME_text +reads MIME headers from +.Fa in_bio , +checks that the content type is +.Dq text/plain , +discards the MIME headers, +and copies the text that follows the headers from +.Fa in_bio +to +.Fa out_bio . +.Sh RETURN VALUES +.Fn SMIME_text +returns 1 on success or 0 if memory allocation, reading the input, +or parsing the MIME headers fails, if there is no +.Dq content-type +header, or if the content type is not +.Dq text/plain . +.Sh SEE ALSO +.Xr SMIME_crlf_copy 3 , +.Xr SMIME_read_ASN1 3 +.Sh HISTORY +.Fn SMIME_text +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh CAVEATS +.Fn SMIME_text +does not support non-blocking BIOs. diff --git a/Libraries/libressl/man/SMIME_write_ASN1.3 b/Libraries/libressl/man/SMIME_write_ASN1.3 new file mode 100644 index 000000000..a02fa5857 --- /dev/null +++ b/Libraries/libressl/man/SMIME_write_ASN1.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: SMIME_write_ASN1.3,v 1.2 2023/05/01 07:28:11 tb Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt SMIME_WRITE_ASN1 3 +.Os +.Sh NAME +.Nm SMIME_write_ASN1 +.Nd generate an S/MIME message +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo SMIME_write_ASN1 +.Fa "BIO *out_bio" +.Fa "ASN1_VALUE *val_in" +.Fa "BIO *in_bio" +.Fa "int flags" +.Fa "int ctype_nid" +.Fa "int econt_nid" +.Fa "STACK_OF(X509_ALGOR) *micalg" +.Fa "const ASN1_ITEM *it" +.Fc +.Sh DESCRIPTION +.Fn SMIME_write_ASN1 +generates an S/MIME message on +.Fa out_bio +by writing MIME 1.0 headers +followed by a BER- and base64-encoded serialization of +.Fa val_in , +which can be of the type +.Vt CMS_ContentInfo +or +.Vt PKCS7 +and has to match the +.Fa it +argument. +.Pp +The +.Fa flags +can be the logical OR of zero or more of the following bits: +.Bl -tag -width Ds +.It Dv PKCS7_REUSE_DIGEST +Skip the calls to +.Xr PKCS7_dataInit 3 +and +.Xr PKCS7_dataFinal 3 . +This flag has no effect unless +.Dv SMIME_DETACHED +is also set. +It is normally used if +.Fa out_bio +is already set up to calculate and finalize the digest when written through. +.It Dv SMIME_BINARY +If specified, this flag is passed through to +.Xr SMIME_crlf_copy 3 . +.It Dv SMIME_CRLFEOL +End MIME header lines with pairs of carriage return and newline characters. +By default, no carriage return characters are written +and header lines are ended with newline characters only. +.It Dv SMIME_DETACHED +Use cleartext signing. +Generate a +.Qq multipart/signed +S/MIME message using the +.Fa micalg +argument and ignoring the +.Fa ctype_nid +and +.Fa econt_nid +arguments. +The content is read from +.Fa in_bio . +If +.Fa in_bio +is a +.Dv NULL +pointer, this flag is ignored. +.Pp +If this flag is ignored or not specified, +the smime-type is chosen according to +.Fa ctype_nid +instead: +.Bl -tag -width Ds +.It Dv NID_pkcs7_enveloped +.Qq enveloped-data +.It Dv NID_pkcs7_signed +.Qq signed-receipt +if +.Fa econt_nid +is +.Dv NID_id_smime_ct_receipt +.br +.Qq signed-data +if +.Fa micalg +is not empty +.br +.Qq certs-only +if +.Fa micalg +is empty +.It Dv NID_id_smime_ct_compressedData +.Qq compressed-data +.El +.It Dv SMIME_OLDMIME +In Content-Type headers, use +.Qq application/x-pkcs7-mime +or +.Qq application/x-pkcs7-signature . +By default, +.Qq application/pkcs7-mime +or +.Qq application/pkcs7-signature +are used instead. +.It Dv SMIME_STREAM +Perform streaming by reading the content from +.Fa in_bio . +This only works if +.Dv SMIME_DETACHED +is not specified. +.It SMIME_TEXT +Prepend the line +.Qq Content-Type: text/plain +to the content. +This only makes sense if +.Dv SMIME_DETACHED +is also set. +It is ignored if the flag +.Dv SMIME_BINARY +is also set. +.El +.Sh RETURN VALUES +.Fn SMIME_write_ASN1 +is intended to return 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr ASN1_item_i2d_bio 3 , +.Xr BIO_f_base64 3 , +.Xr BIO_new 3 , +.Xr SMIME_crlf_copy 3 , +.Xr SMIME_write_CMS 3 , +.Xr SMIME_write_PKCS7 3 , +.Xr X509_ALGOR_new 3 +.Sh HISTORY +.Fn SMIME_write_ASN1 +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh BUGS +.Fn SMIME_write_ASN1 +ignores most errors and is likely to return 1 +even after producing corrupt or incomplete output. diff --git a/Libraries/libressl/man/SMIME_write_CMS.3 b/Libraries/libressl/man/SMIME_write_CMS.3 new file mode 100644 index 000000000..c2c6b77e5 --- /dev/null +++ b/Libraries/libressl/man/SMIME_write_CMS.3 @@ -0,0 +1,133 @@ +.\" $OpenBSD: SMIME_write_CMS.3,v 1.6 2021/12/13 17:24:39 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 13 2021 $ +.Dt SMIME_WRITE_CMS 3 +.Os +.Sh NAME +.Nm SMIME_write_CMS +.Nd convert CMS structure to S/MIME format +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo SMIME_write_CMS +.Fa "BIO *out" +.Fa "CMS_ContentInfo *cms" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn SMIME_write_CMS +adds the appropriate MIME headers to the +.Fa cms +structure to produce an S/MIME message and writes it to +.Fa out . +If streaming is enabled, the content must be supplied in the +.Fa data +argument. +.Pp +The following +.Fa flags +can be passed: +.Bl -tag -width Ds +.It Dv CMS_DETACHED +Use cleartext signing. +This option only makes sense if +.Fa cms +is of the type +.Vt SignedData +and +.Dv CMS_DETACHED +was also set when it was created with +.Xr CMS_sign 3 . +.Pp +If +.Dv CMS_STREAM +is not set, the data must be read twice: +once to compute the signature in +.Xr CMS_sign 3 +and once to output the S/MIME message. +.It Dv CMS_TEXT +Add MIME headers for type text/plain to the content. +This only makes sense if +.Dv CMS_DETACHED +is also set. +.It Dv CMS_STREAM +Perform streaming. +This flag should only be set if +.Dv CMS_STREAM +was also passed to the function that created +.Fa cms . +.Pp +The content is output in BER format using indefinite length +constructed encoding except in the case of +.Vt SignedData +with detached content where the content is absent and DER format is +used. +.El +.Sh RETURN VALUES +.Fn SMIME_write_CMS +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_sign 3 , +.Xr d2i_CMS_ContentInfo 3 , +.Xr ERR_get_error 3 , +.Xr SMIME_write_ASN1 3 +.Sh HISTORY +.Fn SMIME_write_CMS +first appeared in OpenSSL 0.9.8h +and has been available since +.Ox 6.7 . +.Sh BUGS +.Fn SMIME_write_CMS +always base64 encodes CMS structures. +There should be an option to disable this. diff --git a/Libraries/libressl/man/SMIME_write_PKCS7.3 b/Libraries/libressl/man/SMIME_write_PKCS7.3 new file mode 100644 index 000000000..c1a9f051d --- /dev/null +++ b/Libraries/libressl/man/SMIME_write_PKCS7.3 @@ -0,0 +1,184 @@ +.\" $OpenBSD: SMIME_write_PKCS7.3,v 1.9 2021/12/14 15:46:48 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2003, 2006, 2007, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 14 2021 $ +.Dt SMIME_WRITE_PKCS7 3 +.Os +.Sh NAME +.Nm SMIME_write_PKCS7 +.Nd convert PKCS#7 structure to S/MIME format +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo SMIME_write_PKCS7 +.Fa "BIO *out" +.Fa "PKCS7 *p7" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn SMIME_write_PKCS7 +adds the appropriate MIME headers to a PKCS#7 structure to produce an +S/MIME message. +.Pp +.Fa out +is the +.Vt BIO +to write the data to. +.Fa p7 +is the appropriate +.Vt PKCS7 +structure. +If streaming is enabled, then the content must be supplied in the +.Fa data +argument. +.Fa flags +is an optional set of flags. +.Pp +The following flags can be passed in the +.Fa flags +parameter. +.Pp +If +.Dv PKCS7_DETACHED +is set, then cleartext signing will be used. +This option only makes sense for signedData where +.Dv PKCS7_DETACHED +is also set when +.Xr PKCS7_sign 3 +is also called. +.Pp +If the +.Dv PKCS7_TEXT +flag is set, MIME headers for type +.Sy text/plain +are added to the content. +This only makes sense if +.Dv PKCS7_DETACHED +is also set. +.Pp +If the +.Dv PKCS7_STREAM +flag is set, streaming is performed. +This flag should only be set if +.Dv PKCS7_STREAM +was also set in the previous call to +.Xr PKCS7_sign 3 +or +.Xr PKCS7_encrypt 3 . +.Pp +The bit +.Dv SMIME_OLDMIME +is inverted before passing on the +.Fa flags +to +.Xr SMIME_write_ASN1 3 . +Consequently, if this bit is set in the +.Fa flags +argument, +.Qq application/pkcs7-mime +or +.Qq application/pkcs7-signature +is used in Content-Type headers. +Otherwise, +.Qq application/x-pkcs7-mime +or +.Qq application/x-pkcs7-signature +is used. +.Pp +If cleartext signing is being used and +.Dv PKCS7_STREAM +is not set, then the data must be read twice: once to compute the +signature in +.Xr PKCS7_sign 3 +and once to output the S/MIME message. +.Pp +If streaming is performed, the content is output in BER format using +indefinite length constructed encoding except in the case of signed +data with detached content where the content is absent and DER +format is used. +.Sh RETURN VALUES +Upon successful completion, 1 is returned; +otherwise 0 is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr i2d_PKCS7_bio_stream 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PEM_write_PKCS7 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr SMIME_read_PKCS7 3 , +.Xr SMIME_write_ASN1 3 +.Sh HISTORY +.Fn SMIME_write_PKCS7 +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Sh BUGS +.Fn SMIME_write_PKCS7 +always base64 encodes PKCS#7 structures. +There should be an option to disable this. diff --git a/Libraries/libressl/man/SSL_CIPHER_get_name.3 b/Libraries/libressl/man/SSL_CIPHER_get_name.3 new file mode 100644 index 000000000..235ff1408 --- /dev/null +++ b/Libraries/libressl/man/SSL_CIPHER_get_name.3 @@ -0,0 +1,378 @@ +.\" $OpenBSD: SSL_CIPHER_get_name.3,v 1.14 2022/07/17 08:51:07 jsg Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Lutz Jaenicke , +.\" Dr. Stephen Henson , Todd Short , +.\" and Paul Yang . +.\" Copyright (c) 2000, 2005, 2009, 2013, 2014, 2015, 2016, 2017 +.\" The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 17 2022 $ +.Dt SSL_CIPHER_GET_NAME 3 +.Os +.Sh NAME +.Nm SSL_CIPHER_get_name , +.Nm SSL_CIPHER_get_bits , +.Nm SSL_CIPHER_get_version , +.Nm SSL_CIPHER_get_cipher_nid , +.Nm SSL_CIPHER_get_digest_nid , +.Nm SSL_CIPHER_get_kx_nid , +.Nm SSL_CIPHER_get_auth_nid , +.Nm SSL_CIPHER_is_aead , +.Nm SSL_CIPHER_find , +.Nm SSL_CIPHER_get_id , +.Nm SSL_CIPHER_description +.Nd get SSL_CIPHER properties +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const char * +.Fn SSL_CIPHER_get_name "const SSL_CIPHER *cipher" +.Ft int +.Fn SSL_CIPHER_get_bits "const SSL_CIPHER *cipher" "int *alg_bits" +.Ft const char * +.Fn SSL_CIPHER_get_version "const SSL_CIPHER *cipher" +.Ft int +.Fn SSL_CIPHER_get_cipher_nid "const SSL_CIPHER *cipher" +.Ft int +.Fn SSL_CIPHER_get_digest_nid "const SSL_CIPHER *cipher" +.Ft int +.Fn SSL_CIPHER_get_kx_nid "const SSL_CIPHER *cipher" +.Ft int +.Fn SSL_CIPHER_get_auth_nid "const SSL_CIPHER *cipher" +.Ft int +.Fn SSL_CIPHER_is_aead "const SSL_CIPHER *cipher" +.Ft const SSL_CIPHER * +.Fn SSL_CIPHER_find "SSL *ssl" "const unsigned char *ptr" +.Ft unsigned long +.Fn SSL_CIPHER_get_id "const SSL_CIPHER *cipher" +.Ft char * +.Fn SSL_CIPHER_description "const SSL_CIPHER *cipher" "char *buf" "int size" +.Sh DESCRIPTION +.Fn SSL_CIPHER_get_name +returns a pointer to the name of +.Fa cipher . +.Pp +.Fn SSL_CIPHER_get_bits +returns the number of secret bits used for +.Fa cipher . +If +.Fa alg_bits +is not +.Dv NULL , +the number of bits processed by the chosen algorithm is stored into it. +.Pp +.Fn SSL_CIPHER_get_version +returns a string which indicates the SSL/TLS protocol version that first +defined the cipher. +This is currently +.Qq TLSv1/SSLv3 . +In some cases it should possibly return +.Qq TLSv1.2 +but the function does not; use +.Fn SSL_CIPHER_description +instead. +.Pp +.Fn SSL_CIPHER_get_cipher_nid +returns the cipher NID corresponding to the +.Fa cipher . +If there is no cipher (e.g. for cipher suites with no encryption), then +.Dv NID_undef +is returned. +.Pp +.Fn SSL_CIPHER_get_digest_nid +returns the digest NID corresponding to the MAC used by the +.Fa cipher +during record encryption/decryption. +If there is no digest (e.g. for AEAD cipher suites), then +.Dv NID_undef +is returned. +.Pp +.Fn SSL_CIPHER_get_kx_nid +returns the key exchange NID corresponding to the method used by the +.Fa cipher . +If there is no key exchange, then +.Dv NID_undef +is returned. +Examples of possible return values include +.Dv NID_kx_rsa , +.Dv NID_kx_dhe , +and +.Dv NID_kx_ecdhe . +.Pp +.Fn SSL_CIPHER_get_auth_nid +returns the authentication NID corresponding to the method used by the +.Fa cipher . +If there is no authentication, +.Dv NID_undef +is returned. +Examples of possible return values include +.Dv NID_auth_rsa +and +.Dv NID_auth_ecdsa . +.Pp +.Fn SSL_CIPHER_is_aead +returns 1 if the +.Fa cipher +is AEAD (e.g. GCM or ChaCha20/Poly1305), or 0 if it is not AEAD. +.Pp +.Fn SSL_CIPHER_find +returns a pointer to a +.Vt SSL_CIPHER +structure which has the cipher ID specified in +.Fa ptr . +The +.Fa ptr +parameter is an array of length two which stores the two-byte +TLS cipher ID (as allocated by IANA) in network byte order. +.Fa SSL_CIPHER_find +returns +.Dv NULL +if an error occurs or the indicated cipher is not found. +.Pp +.Fn SSL_CIPHER_get_id +returns the ID of the given +.Fa cipher , +which must not be +.Dv NULL . +The ID here is an OpenSSL-specific concept, which stores a prefix +of 0x0300 in the higher two bytes and the IANA-specified cipher +suite ID in the lower two bytes. +For instance, TLS_RSA_WITH_NULL_MD5 has IANA ID "0x00, 0x01", so +.Fn SSL_CIPHER_get_id +returns 0x03000001. +.Pp +.Fn SSL_CIPHER_description +copies a textual description of +.Fa cipher +into the buffer +.Fa buf , +which must be at least +.Fa size +bytes long. +The +.Fa cipher +argument must not be a +.Dv NULL +pointer. +If +.Fa buf +is +.Dv NULL , +a buffer is allocated using +.Xr asprintf 3 ; +that buffer should be freed using the +.Xr free 3 +function. +If +.Fa len +is too small to hold the description, a pointer to the static string +.Qq Buffer too small +is returned. +If memory allocation fails, which can happen even if a +.Fa buf +of sufficient size is provided, a pointer to the static string +.Qq OPENSSL_malloc Error +is returned and the content of +.Fa buf +remains unchanged. +.Pp +The string returned by +.Fn SSL_CIPHER_description +consists of several fields separated by whitespace: +.Bl -tag -width Ds +.It Aq Ar ciphername +Textual representation of the cipher name. +.It Aq Ar protocol version +Protocol version: +.Sy SSLv3 , +.Sy TLSv1.2 , +or +.Sy TLSv1.3 . +The TLSv1.0 ciphers are flagged with SSLv3. +No new ciphers were added by TLSv1.1. +.It Kx= Ns Aq Ar key exchange +Key exchange method: +.Sy DH , +.Sy ECDH , +.Sy GOST , +.Sy RSA , +or +.Sy TLSv1.3 . +.It Au= Ns Aq Ar authentication +Authentication method: +.Sy ECDSA , +.Sy GOST01 , +.Sy RSA , +.Sy TLSv1.3 , +or +.Sy None . +.Sy None +is the representation of anonymous ciphers. +.It Enc= Ns Aq Ar symmetric encryption method +Encryption method with number of secret bits: +.Sy 3DES(168) , +.Sy RC4(128) , +.Sy AES(128) , +.Sy AES(256) , +.Sy AESGCM(128) , +.Sy AESGCM(256) , +.Sy Camellia(128) , +.Sy Camellia(256) , +.Sy ChaCha20-Poly1305 , +.Sy GOST-28178-89-CNT , +or +.Sy None . +.It Mac= Ns Aq Ar message authentication code +Message digest: +.Sy MD5 , +.Sy SHA1 , +.Sy SHA256 , +.Sy SHA384 , +.Sy AEAD , +.Sy GOST94 , +.Sy GOST89IMIT , +or +.Sy STREEBOG256 . +.El +.Sh RETURN VALUES +.Fn SSL_CIPHER_get_name +returns an internal pointer to a NUL-terminated string. +.Fn SSL_CIPHER_get_version +returns a pointer to a static NUL-terminated string. +If +.Fa cipher +is a +.Dv NULL +pointer, both functions return a pointer to the static string +.Qq Pq NONE . +.Pp +.Fn SSL_CIPHER_get_bits +returns a positive integer representing the number of secret bits +or 0 if +.Fa cipher +is a +.Dv NULL +pointer. +.Pp +.Fn SSL_CIPHER_get_cipher_nid , +.Fn SSL_CIPHER_get_digest_nid , +.Fn SSL_CIPHER_get_kx_nid , +and +.Fn SSL_CIPHER_get_auth_nid +return an NID constant or +.Dv NID_undef +if an error occurred. +.Pp +.Fn SSL_CIPHER_is_aead +returns 1 if the +.Fa cipher +is AEAD or 0 otherwise. +.Pp +.Fn SSL_CIPHER_find +returns a pointer to a valid +.Vt SSL_CIPHER +structure or +.Dv NULL +if an error occurred. +.Pp +.Fn SSL_CIPHER_get_id +returns a 32-bit unsigned integer. +.Pp +.Fn SSL_CIPHER_description +returns +.Fa buf +or a newly allocated string on success or a pointer to a static +string on error. +.Sh EXAMPLES +An example for the output of +.Fn SSL_CIPHER_description : +.Bd -literal +ECDHE-RSA-AES256-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD +.Ed +.Pp +A complete list can be retrieved by invoking the following command: +.Pp +.Dl $ openssl ciphers -v ALL:COMPLEMENTOFALL +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ssl 3 , +.Xr SSL_get_ciphers 3 , +.Xr SSL_get_current_cipher 3 +.Sh HISTORY +.Fn SSL_CIPHER_description +first appeared in SSLeay 0.8.0. +.Fn SSL_CIPHER_get_name , +.Fn SSL_CIPHER_get_bits , +and +.Fn SSL_CIPHER_get_version +first appeared in SSLeay 0.8.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CIPHER_get_id +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . +.Pp +.Fn SSL_CIPHER_get_cipher_nid , +.Fn SSL_CIPHER_get_digest_nid , +.Fn SSL_CIPHER_get_kx_nid , +.Fn SSL_CIPHER_get_auth_nid , +and +.Fn SSL_CIPHER_is_aead +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Fn SSL_CIPHER_find +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.0 . +.Sh BUGS +If +.Fn SSL_CIPHER_description +cannot handle a built-in cipher, +the according description of the cipher property is +.Qq unknown . +This case should not occur. diff --git a/Libraries/libressl/man/SSL_COMP_add_compression_method.3 b/Libraries/libressl/man/SSL_COMP_add_compression_method.3 new file mode 100644 index 000000000..99e3f87ed --- /dev/null +++ b/Libraries/libressl/man/SSL_COMP_add_compression_method.3 @@ -0,0 +1,58 @@ +.\" $OpenBSD: SSL_COMP_add_compression_method.3,v 1.5 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_COMP_ADD_COMPRESSION_METHOD 3 +.Os +.Sh NAME +.Nm SSL_COMP_add_compression_method , +.Nm SSL_COMP_get_compression_methods +.Nd handle SSL/TLS integrated compression methods +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_COMP_add_compression_method "int id" "COMP_METHOD *cm" +.Ft STACK_OF(SSL_COMP) * +.Fn SSL_COMP_get_compression_methods void +.Sh DESCRIPTION +These functions are deprecated and have no effect. +They are provided purely for compatibility with legacy application code. +.Pp +.Fn SSL_COMP_add_compression_method +used to add the compression method +.Fa cm +with the identifier +.Fa id +to the list of available compression methods. +.Pp +.Fn SSL_COMP_get_compression_methods +used to return a stack of available compression methods. +.Sh RETURN VALUES +.Fn SSL_COMP_add_compression_method +always returns 1. +.Fn SSL_COMP_get_compression_methods +always returns +.Dv NULL . +.Sh SEE ALSO +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_COMP_add_compression_method +first appeared in OpenSSL 0.9.2b and has been available since +.Ox 2.6 . +.Pp +.Fn SSL_COMP_get_compression_methods +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/SSL_CTX_add1_chain_cert.3 b/Libraries/libressl/man/SSL_CTX_add1_chain_cert.3 new file mode 100644 index 000000000..1f60bad14 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_add1_chain_cert.3 @@ -0,0 +1,222 @@ +.\" $OpenBSD: SSL_CTX_add1_chain_cert.3,v 1.1 2019/04/05 18:29:43 schwarze Exp $ +.\" selective merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson +.\" and Rob Stradling . +.\" Copyright (c) 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 5 2019 $ +.Dt SSL_CTX_ADD1_CHAIN_CERT 3 +.Os +.Sh NAME +.Nm SSL_CTX_set0_chain , +.Nm SSL_CTX_set1_chain , +.Nm SSL_CTX_add0_chain_cert , +.Nm SSL_CTX_add1_chain_cert , +.Nm SSL_CTX_get0_chain_certs , +.Nm SSL_CTX_clear_chain_certs , +.Nm SSL_set0_chain , +.Nm SSL_set1_chain , +.Nm SSL_add0_chain_cert , +.Nm SSL_add1_chain_cert , +.Nm SSL_get0_chain_certs , +.Nm SSL_clear_chain_certs +.Nd extra chain certificate processing +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_set0_chain +.Fa "SSL_CTX *ctx" +.Fa "STACK_OF(X509) *chain" +.Fc +.Ft int +.Fo SSL_CTX_set1_chain +.Fa "SSL_CTX *ctx" +.Fa "STACK_OF(X509) *chain" +.Fc +.Ft int +.Fo SSL_CTX_add0_chain_cert +.Fa "SSL_CTX *ctx" +.Fa "X509 *cert" +.Fc +.Ft int +.Fo SSL_CTX_add1_chain_cert +.Fa "SSL_CTX *ctx" +.Fa "X509 *cert" +.Fc +.Ft int +.Fo SSL_CTX_get0_chain_certs +.Fa "SSL_CTX *ctx" +.Fa "STACK_OF(X509) **chain" +.Fc +.Ft int +.Fo SSL_CTX_clear_chain_certs +.Fa "SSL_CTX *ctx" +.Fc +.Ft int +.Fo SSL_set0_chain +.Fa "SSL *ssl" +.Fa "STACK_OF(X509) *chain" +.Fc +.Ft int +.Fo SSL_set1_chain +.Fa "SSL *ssl" +.Fa "STACK_OF(X509) *chain" +.Fc +.Ft int +.Fo SSL_add0_chain_cert +.Fa "SSL *ssl" +.Fa "X509 *cert" +.Fc +.Ft int +.Fo SSL_add1_chain_cert +.Fa "SSL *ssl" +.Fa "X509 *cert" +.Fc +.Ft int +.Fo SSL_get0_chain_certs +.Fa "SSL *ssl" +.Fa "STACK_OF(X509) **chain" +.Fc +.Ft int +.Fo SSL_clear_chain_certs +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set0_chain +and +.Fn SSL_CTX_set1_chain +set the certificate chain associated with the current certificate of +.Fa ctx +to +.Fa chain . +The +.Fa chain +is not supposed to include the current certificate itself. +.Pp +.Fn SSL_CTX_add0_chain_cert +and +.Fn SSL_CTX_add1_chain_cert +append the single certificate +.Fa cert +to the chain associated with the current certificate of +.Fa ctx . +.Pp +.Fn SSL_CTX_get0_chain_certs +retrieves the chain associated with the current certificate of +.Fa ctx . +.Pp +.Fn SSL_CTX_clear_chain_certs +clears the existing chain associated with the current certificate of +.Fa ctx , +if any. +This is equivalent to calling +.Fn SSL_CTX_set0_chain +with +.Fa chain +set to +.Dv NULL . +.Pp +Each of these functions operates on the +.Em current +end entity (i.e. server or client) certificate. +This is the last certificate loaded or selected on the corresponding +.Fa ctx +structure, for example using +.Xr SSL_CTX_use_certificate 3 . +.Pp +.Fn SSL_set0_chain , +.Fn SSL_set1_chain , +.Fn SSL_add0_chain_cert , +.Fn SSL_add1_chain_cert , +.Fn SSL_get0_chain_certs , +and +.Fn SSL_clear_chain_certs +are similar except that they operate on the +.Fa ssl +connection. +.Pp +The functions containing a +.Sy 1 +in their name increment the reference count of the supplied certificate +or chain, so it must be freed at some point after the operation. +Those containing a +.Sy 0 +do not increment reference counts and the supplied certificate or chain +must not be freed after the operation. +.Pp +The chains associated with an +.Vt SSL_CTX +structure are copied to the new +.Vt SSL +structure when +.Xr SSL_new 3 +is called. +Existing +.Vt SSL +structures are not affected by any chains subsequently changed +in the parent +.Vt SSL_CTX . +.Pp +One chain can be set for each key type supported by a server. +So, for example, an RSA and a DSA certificate can (and often will) have +different chains. +.Pp +If any certificates are added using these functions, no certificates +added using +.Xr SSL_CTX_add_extra_chain_cert 3 +will be used. +.Sh RETURN VALUES +These functions return 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_use_certificate 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.2 +and have been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/SSL_CTX_add_extra_chain_cert.3 b/Libraries/libressl/man/SSL_CTX_add_extra_chain_cert.3 new file mode 100644 index 000000000..4c731309e --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_add_extra_chain_cert.3 @@ -0,0 +1,160 @@ +.\" $OpenBSD: SSL_CTX_add_extra_chain_cert.3,v 1.7 2020/01/02 09:09:16 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke and +.\" Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2013, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 2 2020 $ +.Dt SSL_CTX_ADD_EXTRA_CHAIN_CERT 3 +.Os +.Sh NAME +.Nm SSL_CTX_add_extra_chain_cert , +.Nm SSL_CTX_get_extra_chain_certs_only , +.Nm SSL_CTX_get_extra_chain_certs , +.Nm SSL_CTX_clear_extra_chain_certs +.Nd add, retrieve, and clear extra chain certificates +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_add_extra_chain_cert "SSL_CTX *ctx" "X509 *x509" +.Ft long +.Fn SSL_CTX_get_extra_chain_certs_only "SSL_CTX *ctx" "STACK_OF(X509) **certs" +.Ft long +.Fn SSL_CTX_get_extra_chain_certs "SSL_CTX *ctx" "STACK_OF(X509) **certs" +.Ft long +.Fn SSL_CTX_clear_extra_chain_certs "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_add_extra_chain_cert +adds the certificate +.Fa x509 +to the extra chain certificates associated with +.Fa ctx . +Several certificates can be added one after another. +.Pp +.Fn SSL_CTX_get_extra_chain_certs_only +retrieves an internal pointer to the stack of extra chain certificates +associated with +.Fa ctx , +or set +.Pf * Fa certs +to +.Dv NULL +if there are none. +.Pp +.Fn SSL_CTX_get_extra_chain_certs +does the same except that it retrieves an internal pointer +to the chain associated with the certificate +if there are no extra chain certificates. +.Pp +.Fn SSL_CTX_clear_extra_chain_certs +clears all extra chain certificates associated with +.Fa ctx . +.Pp +These functions are implemented as macros. +.Pp +When sending a certificate chain, extra chain certificates are sent +in order following the end entity certificate. +.Pp +If no chain is specified, the library will try to complete the chain from the +available CA certificates in the trusted CA storage, see +.Xr SSL_CTX_load_verify_locations 3 . +.Pp +The x509 certificate provided to +.Fn SSL_CTX_add_extra_chain_cert +will be freed by the library when the +.Vt SSL_CTX +is destroyed. +An application should not free the +.Fa x509 +object, nor the +.Pf * Fa certs +object retrieved by +.Fn SSL_CTX_get_extra_chain_certs . +.Sh RETURN VALUES +These functions return 1 on success or 0 for failure. +Check out the error stack to find out the reason for failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add1_chain_cert 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_CTX_set_client_cert_cb 3 , +.Xr SSL_CTX_use_certificate 3 +.Sh HISTORY +.Fn SSL_CTX_add_extra_chain_cert +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . +.Pp +.Fn SSL_CTX_get_extra_chain_certs +and +.Fn SSL_CTX_clear_extra_chain_certs +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . +.Pp +.Fn SSL_CTX_get_extra_chain_certs_only +first appeared in OpenSSL 1.0.2 and has been available since +.Ox 6.7 . +.Sh CAVEATS +Certificates added with +.Fn SSL_CTX_add_extra_chain_cert +are ignored when certificates are also available that have been +added using the functions documented in +.Xr SSL_CTX_set1_chain 3 . +.Pp +Only one set of extra chain certificates can be specified per +.Vt SSL_CTX +structure using +.Fn SSL_CTX_add_extra_chain_cert . +Different chains for different certificates (for example if both +RSA and DSA certificates are specified by the same server) or +different SSL structures with the same parent +.Vt SSL_CTX +require using the functions documented in +.Xr SSL_CTX_set1_chain 3 +instead. diff --git a/Libraries/libressl/man/SSL_CTX_add_session.3 b/Libraries/libressl/man/SSL_CTX_add_session.3 new file mode 100644 index 000000000..443bdb542 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_add_session.3 @@ -0,0 +1,132 @@ +.\" $OpenBSD: SSL_CTX_add_session.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL SSL_CTX_add_session.pod 1722496f Jun 8 15:18:38 2017 -0400 +.\" +.\" This file was written by Lutz Jaenicke and +.\" Geoff Thorpe . +.\" Copyright (c) 2001, 2002, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_ADD_SESSION 3 +.Os +.Sh NAME +.Nm SSL_CTX_add_session , +.Nm SSL_CTX_remove_session +.Nd manipulate session cache +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_CTX_add_session "SSL_CTX *ctx" "SSL_SESSION *c" +.Ft int +.Fn SSL_CTX_remove_session "SSL_CTX *ctx" "SSL_SESSION *c" +.Sh DESCRIPTION +.Fn SSL_CTX_add_session +adds the session +.Fa c +to the context +.Fa ctx . +The reference count for session +.Fa c +is incremented by 1. +If a session with the same session id already exists, +the old session is removed by calling +.Xr SSL_SESSION_free 3 . +.Pp +.Fn SSL_CTX_remove_session +removes the session +.Fa c +from the context +.Fa ctx +and marks it as non-resumable. +.Xr SSL_SESSION_free 3 +is called once for +.Fa c . +.Pp +When adding a new session to the internal session cache, it is examined +whether a session with the same session id already exists. +In this case it is assumed that both sessions are identical. +If the same session is stored in a different +.Vt SSL_SESSION +object, the old session is removed and replaced by the new session. +If the session is actually identical (the +.Vt SSL_SESSION +object is identical), +.Fn SSL_CTX_add_session +is a no-op, and the return value is 0. +.Pp +If a server +.Vt SSL_CTX +is configured with the +.Dv SSL_SESS_CACHE_NO_INTERNAL_STORE +flag then the internal cache will not be populated automatically by new +sessions negotiated by the SSL/TLS implementation, even though the internal +cache will be searched automatically for session-resume requests (the +latter can be suppressed by +.Dv SSL_SESS_CACHE_NO_INTERNAL_LOOKUP ) . +So the application can use +.Fn SSL_CTX_add_session +directly to have full control over the sessions that can be resumed if desired. +.Sh RETURN VALUES +The following values are returned by all functions: +.Bl -tag -width Ds +.It 0 +The operation failed. +In case of the add operation, it was tried to add the same (identical) session +twice. +In case of the remove operation, the session was not found in the cache. +.It 1 +The operation succeeded. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_SESSION_free 3 +.Sh HISTORY +.Fn SSL_CTX_add_session +and +.Fn SSL_CTX_remove_session +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_ctrl.3 b/Libraries/libressl/man/SSL_CTX_ctrl.3 new file mode 100644 index 000000000..c91ddff37 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_ctrl.3 @@ -0,0 +1,122 @@ +.\" $OpenBSD: SSL_CTX_ctrl.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_CTRL 3 +.Os +.Sh NAME +.Nm SSL_CTX_ctrl , +.Nm SSL_CTX_callback_ctrl , +.Nm SSL_ctrl , +.Nm SSL_callback_ctrl +.Nd internal handling functions for SSL_CTX and SSL objects +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_ctrl "SSL_CTX *ctx" "int cmd" "long larg" "void *parg" +.Ft long +.Fn SSL_CTX_callback_ctrl "SSL_CTX *" "int cmd" "void (*fp)()" +.Ft long +.Fn SSL_ctrl "SSL *ssl" "int cmd" "long larg" "void *parg" +.Ft long +.Fn SSL_callback_ctrl "SSL *" "int cmd" "void (*fp)()" +.Sh DESCRIPTION +The +.Fn SSL_*_ctrl +family of functions is used to manipulate settings of +the +.Vt SSL_CTX +and +.Vt SSL +objects. +Depending on the command +.Fa cmd +the arguments +.Fa larg , +.Fa parg , +or +.Fa fp +are evaluated. +These functions should never be called directly. +All functionalities needed are made available via other functions or macros. +.Sh RETURN VALUES +The return values of the +.Fn SSL*_ctrl +functions depend on the command supplied via the +.Fn cmd +parameter. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_sess_number 3 , +.Xr SSL_CTX_sess_set_cache_size 3 , +.Xr SSL_CTX_set_max_cert_list 3 , +.Xr SSL_CTX_set_mode 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_CTX_set_tlsext_servername_callback 3 , +.Xr SSL_CTX_set_tlsext_status_cb 3 , +.Xr SSL_CTX_set_tlsext_ticket_key_cb 3 , +.Xr SSL_get_server_tmp_key 3 , +.Xr SSL_num_renegotiations 3 , +.Xr SSL_session_reused 3 , +.Xr SSL_set_max_send_fragment 3 +.Sh HISTORY +.Fn SSL_CTX_ctrl +and +.Fn SSL_ctrl +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_callback_ctrl +and +.Fn SSL_callback_ctrl +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/SSL_CTX_flush_sessions.3 b/Libraries/libressl/man/SSL_CTX_flush_sessions.3 new file mode 100644 index 000000000..2ef781cb4 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_flush_sessions.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: SSL_CTX_flush_sessions.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL SSL_CTX_flush_sessions.pod 1722496f Jun 8 15:18:38 2017 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_FLUSH_SESSIONS 3 +.Os +.Sh NAME +.Nm SSL_CTX_flush_sessions +.Nd remove expired sessions +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_CTX_flush_sessions "SSL_CTX *ctx" "long tm" +.Sh DESCRIPTION +.Fn SSL_CTX_flush_sessions +causes a run through the session cache of +.Fa ctx +to remove sessions expired at time +.Fa tm . +.Pp +If enabled, the internal session cache will collect all sessions established +up to the specified maximum number (see +.Xr SSL_CTX_sess_set_cache_size 3 ) . +As sessions will not be reused once they are expired, they should be +removed from the cache to save resources. +This can either be done automatically whenever 255 new sessions were +established (see +.Xr SSL_CTX_set_session_cache_mode 3 ) +or manually by calling +.Fn SSL_CTX_flush_sessions . +.Pp +The parameter +.Fa tm +specifies the time which should be used for the +expiration test, in most cases the actual time given by +.Fn time 0 +will be used. +.Pp +.Fn SSL_CTX_flush_sessions +will only check sessions stored in the internal cache. +When a session is found and removed, the +.Va remove_session_cb +is however called to synchronize with the external cache (see +.Xr SSL_CTX_sess_set_get_cb 3 ) . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_sess_set_get_cb 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_CTX_set_timeout 3 +.Sh HISTORY +.Fn SSL_CTX_flush_sessions +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_free.3 b/Libraries/libressl/man/SSL_CTX_free.3 new file mode 100644 index 000000000..47f247631 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_free.3 @@ -0,0 +1,101 @@ +.\" $OpenBSD: SSL_CTX_free.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2003 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_FREE 3 +.Os +.Sh NAME +.Nm SSL_CTX_free +.Nd free an allocated SSL_CTX object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_CTX_free "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_free +decrements the reference count of +.Fa ctx , +and removes the +.Vt SSL_CTX +object pointed to by +.Fa ctx +and frees up the allocated memory if the reference count has reached 0. +If +.Fa ctx +is a +.Dv NULL +pointer, no action occurs. +.Pp +It also calls the +.Xr free 3 Ns ing +procedures for indirectly affected items, if applicable: +the session cache, the list of ciphers, the list of Client CAs, +the certificates and keys. +.Sh WARNINGS +If a session-remove callback is set +.Pq Xr SSL_CTX_sess_set_remove_cb 3 , +this callback will be called for each session being freed from +.Fa ctx Ns 's +session cache. +This implies that all corresponding sessions from an external session cache are +removed as well. +If this is not desired, the user should explicitly unset the callback by +calling +.Fn SSL_CTX_sess_set_remove_cb ctx NULL +prior to calling +.Fn SSL_CTX_free . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_sess_set_get_cb 3 +.Sh HISTORY +.Fn SSL_CTX_free +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_get0_certificate.3 b/Libraries/libressl/man/SSL_CTX_get0_certificate.3 new file mode 100644 index 000000000..63c86bd5e --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_get0_certificate.3 @@ -0,0 +1,51 @@ +.\" $OpenBSD: SSL_CTX_get0_certificate.3,v 1.3 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_CTX_GET0_CERTIFICATE 3 +.Os +.Sh NAME +.Nm SSL_CTX_get0_certificate +.Nd get the active certificate from an SSL context +.Sh SYNOPSIS +.Ft X509 * +.Fo SSL_CTX_get0_certificate +.Fa "const SSL_CTX *ctx" +.Fc +.Sh DESCRIPTION +The +.Fn SSL_CTX_get0_certificate +function returns an internal pointer +to the ASN.1 certificate currently active in +.Fa ctx +or +.Dv NULL +if none was installed with +.Xr SSL_CTX_use_certificate 3 +or similar functions. +.Pp +The returned pointer must not be freed by the caller. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_use_certificate 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_new 3 +.Sh HISTORY +.Fn SSL_CTX_get0_certificate +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_CTX_get_ex_new_index.3 b/Libraries/libressl/man/SSL_CTX_get_ex_new_index.3 new file mode 100644 index 000000000..3dbaf2e98 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_get_ex_new_index.3 @@ -0,0 +1,124 @@ +.\" $OpenBSD: SSL_CTX_get_ex_new_index.3,v 1.3 2018/03/21 08:06:34 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt SSL_CTX_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm SSL_CTX_get_ex_new_index , +.Nm SSL_CTX_set_ex_data , +.Nm SSL_CTX_get_ex_data +.Nd internal application specific data functions +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fn SSL_CTX_set_ex_data "SSL_CTX *ctx" "int idx" "void *arg" +.Ft void * +.Fn SSL_CTX_get_ex_data "const SSL_CTX *ctx" "int idx" +.Bd -literal + typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); + typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); + typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, + int idx, long argl, void *argp); +.Ed +.Sh DESCRIPTION +Several OpenSSL structures can have application specific data attached to them. +These functions are used internally by OpenSSL to manipulate application +specific data attached to a specific structure. +.Pp +.Fn SSL_CTX_get_ex_new_index +is used to register a new index for application specific data. +.Pp +.Fn SSL_CTX_set_ex_data +is used to store application data at +.Fa arg +for +.Fa idx +into the +.Fa ctx +object. +.Pp +.Fn SSL_CTX_get_ex_data +is used to retrieve the information for +.Fa idx +from +.Fa ctx . +.Pp +A detailed description for the +.Fn *_get_ex_new_index +functionality can be found in +.Xr RSA_get_ex_new_index 3 . +The +.Fn *_get_ex_data +and +.Fn *_set_ex_data +functionality is described in +.Xr CRYPTO_set_ex_data 3 . +.Sh SEE ALSO +.Xr CRYPTO_set_ex_data 3 , +.Xr RSA_get_ex_new_index 3 , +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_CTX_get_ex_new_index , +.Fn SSL_CTX_set_ex_data , +and +.Fn SSL_CTX_get_ex_data +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_get_verify_mode.3 b/Libraries/libressl/man/SSL_CTX_get_verify_mode.3 new file mode 100644 index 000000000..7c8777506 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_get_verify_mode.3 @@ -0,0 +1,131 @@ +.\" $OpenBSD: SSL_CTX_get_verify_mode.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_GET_VERIFY_MODE 3 +.Os +.Sh NAME +.Nm SSL_CTX_get_verify_mode , +.Nm SSL_get_verify_mode , +.Nm SSL_CTX_get_verify_depth , +.Nm SSL_get_verify_depth , +.Nm SSL_get_verify_callback , +.Nm SSL_CTX_get_verify_callback +.Nd get currently set verification parameters +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_CTX_get_verify_mode "const SSL_CTX *ctx" +.Ft int +.Fn SSL_get_verify_mode "const SSL *ssl" +.Ft int +.Fn SSL_CTX_get_verify_depth "const SSL_CTX *ctx" +.Ft int +.Fn SSL_get_verify_depth "const SSL *ssl" +.Ft int +.Fo "(*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))" +.Fa int "X509_STORE_CTX *" +.Fc +.Ft int +.Fo "(*SSL_get_verify_callback(const SSL *ssl))" +.Fa int "X509_STORE_CTX *" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_get_verify_mode +returns the verification mode currently set in +.Fa ctx . +.Pp +.Fn SSL_get_verify_mode +returns the verification mode currently set in +.Fa ssl . +.Pp +.Fn SSL_CTX_get_verify_depth +returns the verification depth limit currently set +in +.Fa ctx . +If no limit has been explicitly set, +\(mi1 is returned and the default value will be used. +.Pp +.Fn SSL_get_verify_depth +returns the verification depth limit currently set in +.Fa ssl . +If no limit has been explicitly set, +\(mi1 is returned and the default value will be used. +.Pp +.Fn SSL_CTX_get_verify_callback +returns a function pointer to the verification callback currently set in +.Fa ctx . +If no callback was explicitly set, the +.Dv NULL +pointer is returned and the default callback will be used. +.Pp +.Fn SSL_get_verify_callback +returns a function pointer to the verification callback currently set in +.Fa ssl . +If no callback was explicitly set, the +.Dv NULL +pointer is returned and the default callback will be used. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_verify 3 +.Sh HISTORY +.Fn SSL_CTX_get_verify_mode , +.Fn SSL_get_verify_mode , +.Fn SSL_get_verify_callback , +and +.Fn SSL_CTX_get_verify_callback +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_get_verify_depth +and +.Fn SSL_get_verify_depth +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/SSL_CTX_load_verify_locations.3 b/Libraries/libressl/man/SSL_CTX_load_verify_locations.3 new file mode 100644 index 000000000..373df2402 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_load_verify_locations.3 @@ -0,0 +1,238 @@ +.\" $OpenBSD: SSL_CTX_load_verify_locations.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_LOAD_VERIFY_LOCATIONS 3 +.Os +.Sh NAME +.Nm SSL_CTX_load_verify_locations , +.Nm SSL_CTX_set_default_verify_paths +.Nd set default locations for trusted CA certificates +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_load_verify_locations +.Fa "SSL_CTX *ctx" "const char *CAfile" "const char *CApath" +.Fc +.Ft int +.Fo SSL_CTX_set_default_verify_paths +.Fa "SSL_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_load_verify_locations +specifies the locations for +.Fa ctx , +at which CA certificates for verification purposes are located. +The certificates available via +.Fa CAfile +and +.Fa CApath +are trusted. +.Pp +.Fn SSL_CTX_set_default_verify_paths +specifies that the default locations from which CA certificates are +loaded should be used. +There is one default directory and one default file. +The default CA certificates directory is called +.Pa certs +in the default OpenSSL directory. +The default CA certificates file is called +.Pa cert.pem +in the default OpenSSL directory. +.Pp +If +.Fa CAfile +is not +.Dv NULL , +it points to a file of CA certificates in PEM format. +The file can contain several CA certificates identified by sequences of: +.Bd -literal + -----BEGIN CERTIFICATE----- + ... (CA certificate in base64 encoding) ... + -----END CERTIFICATE----- +.Ed +.Pp +Before, between, and after the certificates arbitrary text is allowed which can +be used, e.g., for descriptions of the certificates. +.Pp +The +.Fa CAfile +is processed on execution of the +.Fn SSL_CTX_load_verify_locations +function. +.Pp +If +.Fa CApath +is not NULL, it points to a directory containing CA certificates in PEM format. +The files each contain one CA certificate. +The files are looked up by the CA subject name hash value, +which must hence be available. +If more than one CA certificate with the same name hash value exist, +the extension must be different (e.g., +.Pa 9d66eef0.0 , +.Pa 9d66eef0.1 , +etc.). +The search is performed in the ordering of the extension number, +regardless of other properties of the certificates. +.Pp +The certificates in +.Fa CApath +are only looked up when required, e.g., when building the certificate chain or +when actually performing the verification of a peer certificate. +.Pp +When looking up CA certificates, the OpenSSL library will first search the +certificates in +.Fa CAfile , +then those in +.Fa CApath . +Certificate matching is done based on the subject name, the key identifier (if +present), and the serial number as taken from the certificate to be verified. +If these data do not match, the next certificate will be tried. +If a first certificate matching the parameters is found, +the verification process will be performed; +no other certificates for the same parameters will be searched in case of +failure. +.Pp +In server mode, when requesting a client certificate, the server must send +the list of CAs of which it will accept client certificates. +This list is not influenced by the contents of +.Fa CAfile +or +.Fa CApath +and must explicitly be set using the +.Xr SSL_CTX_set_client_CA_list 3 +family of functions. +.Pp +When building its own certificate chain, an OpenSSL client/server will try to +fill in missing certificates from +.Fa CAfile Ns / Fa CApath , +if the +certificate chain was not explicitly specified (see +.Xr SSL_CTX_add_extra_chain_cert 3 +and +.Xr SSL_CTX_use_certificate 3 ) . +.Sh RETURN VALUES +For +.Fn SSL_CTX_load_verify_locations , +the following return values can occur: +.Bl -tag -width Ds +.It 0 +The operation failed because +.Fa CAfile +and +.Fa CApath +are +.Dv NULL +or the processing at one of the locations specified failed. +Check the error stack to find out the reason. +.It 1 +The operation succeeded. +.El +.Pp +.Fn SSL_CTX_set_default_verify_paths +returns 1 on success or 0 on failure. +A missing default location is still treated as a success. +.Sh EXAMPLES +Generate a CA certificate file with descriptive text from the CA certificates +.Pa ca1.pem +.Pa ca2.pem +.Pa ca3.pem : +.Bd -literal +#!/bin/sh +rm CAfile.pem +for i in ca1.pem ca2.pem ca3.pem; do + openssl x509 -in $i -text >> CAfile.pem +done +.Ed +.Pp +Prepare the directory /some/where/certs containing several CA certificates +for use as +.Fa CApath : +.Bd -literal +$ cd /some/where/certs +$ rm -f *.[0-9]* *.r[0-9]* +$ for c in *.pem; do +> [ "$c" = "*.pem" ] && continue +> hash=$(openssl x509 -noout -hash -in "$c") +> if egrep -q -- '-BEGIN( X509 | TRUSTED | )CERTIFICATE-' "$c"; then +> suf=0 +> while [ -e $hash.$suf ]; do suf=$(( $suf + 1 )); done +> ln -s "$c" $hash.$suf +> fi +> if egrep -q -- '-BEGIN X509 CRL-' "$c"; then +> suf=0 +> while [ -e $hash.r$suf ]; do suf=$(( $suf + 1 )); done +> ln -s "$c" $hash.r$suf +> fi +> done +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_set_cert_store 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr SSL_CTX_use_certificate 3 , +.Xr SSL_get_client_CA_list 3 +.Sh HISTORY +.Fn SSL_CTX_load_verify_locations +and +.Fn SSL_CTX_set_default_verify_paths +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Sh CAVEATS +If several CA certificates matching the name, key identifier, and serial +number condition are available, only the first one will be examined. +This may lead to unexpected results if the same CA certificate is available +with different expiration dates. +If a +.Dq certificate expired +verification error occurs, no other certificate will be searched. +Make sure to not have expired certificates mixed with valid ones. diff --git a/Libraries/libressl/man/SSL_CTX_new.3 b/Libraries/libressl/man/SSL_CTX_new.3 new file mode 100644 index 000000000..4b50a03de --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_new.3 @@ -0,0 +1,345 @@ +.\" $OpenBSD: SSL_CTX_new.3,v 1.17 2022/07/13 22:05:53 schwarze Exp $ +.\" full merge up to: OpenSSL 21cd6e00 Oct 21 14:40:15 2015 +0100 +.\" selective merge up to: OpenSSL 8f75443f May 24 14:04:26 2019 +0200 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2005, 2012, 2013, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt SSL_CTX_NEW 3 +.Os +.Sh NAME +.Nm SSL_CTX_new , +.Nm SSL_CTX_up_ref , +.Nm TLS_method , +.Nm TLS_server_method , +.Nm TLS_client_method , +.Nm SSLv23_method , +.Nm SSLv23_server_method , +.Nm SSLv23_client_method , +.Nm TLSv1_method , +.Nm TLSv1_server_method , +.Nm TLSv1_client_method , +.Nm TLSv1_1_method , +.Nm TLSv1_1_server_method , +.Nm TLSv1_1_client_method , +.Nm TLSv1_2_method , +.Nm TLSv1_2_server_method , +.Nm TLSv1_2_client_method , +.Nm DTLS_method , +.Nm DTLS_server_method , +.Nm DTLS_client_method , +.Nm DTLSv1_method , +.Nm DTLSv1_server_method , +.Nm DTLSv1_client_method , +.Nm DTLSv1_2_method , +.Nm DTLSv1_2_server_method , +.Nm DTLSv1_2_client_method +.Nd create a new SSL_CTX object as a framework for TLS enabled functions +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_CTX * +.Fn SSL_CTX_new "const SSL_METHOD *method" +.Ft int +.Fn SSL_CTX_up_ref "SSL_CTX *ctx" +.Ft const SSL_METHOD * +.Fn TLS_method void +.Ft const SSL_METHOD * +.Fn TLS_server_method void +.Ft const SSL_METHOD * +.Fn TLS_client_method void +.Ft const SSL_METHOD * +.Fn SSLv23_method void +.Ft const SSL_METHOD * +.Fn SSLv23_server_method void +.Ft const SSL_METHOD * +.Fn SSLv23_client_method void +.Ft const SSL_METHOD * +.Fn TLSv1_method void +.Ft const SSL_METHOD * +.Fn TLSv1_server_method void +.Ft const SSL_METHOD * +.Fn TLSv1_client_method void +.Ft const SSL_METHOD * +.Fn TLSv1_1_method void +.Ft const SSL_METHOD * +.Fn TLSv1_1_server_method void +.Ft const SSL_METHOD * +.Fn TLSv1_1_client_method void +.Ft const SSL_METHOD * +.Fn TLSv1_2_method void +.Ft const SSL_METHOD * +.Fn TLSv1_2_server_method void +.Ft const SSL_METHOD * +.Fn TLSv1_2_client_method void +.Ft const SSL_METHOD * +.Fn DTLS_method void +.Ft const SSL_METHOD * +.Fn DTLS_server_method void +.Ft const SSL_METHOD * +.Fn DTLS_client_method void +.Ft const SSL_METHOD * +.Fn DTLSv1_method void +.Ft const SSL_METHOD * +.Fn DTLSv1_server_method void +.Ft const SSL_METHOD * +.Fn DTLSv1_client_method void +.Ft const SSL_METHOD * +.Fn DTLSv1_2_method void +.Ft const SSL_METHOD * +.Fn DTLSv1_2_server_method void +.Ft const SSL_METHOD * +.Fn DTLSv1_2_client_method void +.Sh DESCRIPTION +.Fn SSL_CTX_new +creates a new +.Vt SSL_CTX +object as a framework to establish TLS or DTLS enabled connections. +It initializes the list of ciphers, the session cache setting, the +callbacks, the keys and certificates, the options, and the security +level to its default values. +.Pp +An +.Vt SSL_CTX +object is reference counted. +Creating a new +.Vt SSL_CTX +object sets its reference count to 1. +Calling +.Fn SSL_CTX_up_ref +on it increments the reference count by 1. +Calling +.Xr SSL_CTX_free 3 +on it decrements the reference count by 1. +When the reference count drops to zero, +any memory or resources allocated to the +.Vt SSL_CTX +object are freed. +.Pp +The +.Vt SSL_CTX +object uses +.Fa method +as its connection method, which can be: +.Bl -tag -width Ds +.It Fn TLS_method +The general-purpose version-flexible TLS method. +The protocol version used will be negotiated to the highest +version mutually supported by the client and the server. +The supported protocols are TLSv1, TLSv1.1, TLSv1.2, and TLSv1.3. +.It Fn DTLS_method +The version-flexible DTLS method. +The currently supported protocols are DTLSv1 and DTLSv1.2. +.El +.Pp +The following +.Fa method +arguments are deprecated: +.Bl -tag -width Ds +.It Xo +.Fn TLS_server_method , +.Fn TLS_client_method , +.Fn SSLv23_method , +.Fn SSLv23_server_method , +.Fn SSLv23_client_method +.Xc +Deprecated aliases for +.Fn TLS_method . +.It Xo +.Fn DTLS_server_method , +.Fn DTLS_client_method +.Xc +Deprecated aliases for +.Fn DTLS_method . +.It Xo +.Fn TLSv1_method , +.Fn TLSv1_server_method , +.Fn TLSv1_client_method +.Xc +A connection established with these methods will only +understand the TLSv1 protocol. +.It Xo +.Fn TLSv1_1_method , +.Fn TLSv1_1_server_method , +.Fn TLSv1_1_client_method +.Xc +A connection established with these methods will only +understand the TLSv1.1 protocol. +.It Xo +.Fn TLSv1_2_method , +.Fn TLSv1_2_server_method , +.Fn TLSv1_2_client_method +.Xc +A connection established with these methods will only +understand the TLSv1.2 protocol. +.It Xo +.Fn DTLSv1_method , +.Fn DTLSv1_server_method , +.Fn DTLSv1_client_method +.Xc +These are the version-specific methods for DTLSv1. +.It Xo +.Fn DTLSv1_2_method , +.Fn DTLSv1_2_server_method , +.Fn DTLSv1_2_client_method +These are the version-specific methods for DTLSv1.2. +.Xc +.El +.Pp +In LibreSSL, the methods containing the substrings +.Dq _server +or +.Dq _client +in their names return the same objects +as the methods without these substrings. +.Pp +The list of protocols available can also be limited using the +.Dv SSL_OP_NO_TLSv1 , +.Dv SSL_OP_NO_TLSv1_1 , +and +.Dv SSL_OP_NO_TLSv1_2 +options of the +.Xr SSL_CTX_set_options 3 +or +.Xr SSL_set_options 3 +functions, but this approach is not recommended. +Clients should avoid creating "holes" in the set of protocols they support. +When disabling a protocol, make sure that you also disable either +all previous or all subsequent protocol versions. +In clients, when a protocol version is disabled without disabling +all previous protocol versions, the effect is to also disable all +subsequent protocol versions. +.Pp +DTLSv1 and DTLSv1.2 can be disabled with +.Xr SSL_CTX_set_options 3 +or +.Xr SSL_set_options 3 +using the +.Dv SSL_OP_NO_DTLSv1 +and +.Dv SSL_OP_NO_DTLSv1_2 +options, respectively. +.Sh RETURN VALUES +.Fn SSL_CTX_new +returns a pointer to the newly allocated object or +.Dv NULL +on failure. +Check the error stack to find out the reason for failure. +.Pp +.Fn SSL_CTX_up_ref +returns 1 for success or 0 for failure. +.Pp +.Fn TLS_method +and the other +.Fn *_method +functions return pointers to constant static objects. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_CTX_free 3 , +.Xr SSL_CTX_set_min_proto_version 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_CTX_set_security_level 3 , +.Xr SSL_set_connect_state 3 +.Sh HISTORY +.Fn SSL_CTX_new +first appeared in SSLeay 0.5.1. +.Fn SSLv23_method , +.Fn SSLv23_server_method , +and +.Fn SSLv23_client_method +first appeared in SSLeay 0.8.0. +.Fn TLSv1_method , +.Fn TLSv1_server_method , +and +.Fn TLSv1_client_method +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn DTLSv1_method , +.Fn DTLSv1_server_method , +and +.Fn DTLSv1_client_method +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn TLSv1_1_method , +.Fn TLSv1_1_server_method , +.Fn TLSv1_1_client_method , +.Fn TLSv1_2_method , +.Fn TLSv1_2_server_method , +and +.Fn TLSv1_2_client_method +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . +.Pp +.Fn DTLS_method , +.Fn DTLS_server_method , +and +.Fn DTLS_client_method +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.5 . +.Pp +.Fn TLS_method , +.Fn TLS_server_method , +and +.Fn TLS_client_method +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 5.8 . +.Pp +.Fn SSL_CTX_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Pp +.Fn DTLSv1_2_method , +.Fn DTLSv1_2_server_method , +and +.Fn DTLSv1_2_client_method +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.9 . diff --git a/Libraries/libressl/man/SSL_CTX_sess_number.3 b/Libraries/libressl/man/SSL_CTX_sess_number.3 new file mode 100644 index 000000000..76d436cd1 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_sess_number.3 @@ -0,0 +1,168 @@ +.\" $OpenBSD: SSL_CTX_sess_number.3,v 1.9 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL SSL_CTX_sess_number.pod 7bd27895 Mar 29 11:45:29 2017 +1000 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_CTX_SESS_NUMBER 3 +.Os +.Sh NAME +.Nm SSL_CTX_sess_number , +.Nm SSL_CTX_sess_connect , +.Nm SSL_CTX_sess_connect_good , +.Nm SSL_CTX_sess_connect_renegotiate , +.Nm SSL_CTX_sess_accept , +.Nm SSL_CTX_sess_accept_good , +.Nm SSL_CTX_sess_accept_renegotiate , +.Nm SSL_CTX_sess_hits , +.Nm SSL_CTX_sess_cb_hits , +.Nm SSL_CTX_sess_misses , +.Nm SSL_CTX_sess_timeouts , +.Nm SSL_CTX_sess_cache_full +.Nd obtain session cache statistics +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_sess_number "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_connect "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_connect_good "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_connect_renegotiate "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_accept "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_accept_good "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_accept_renegotiate "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_hits "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_cb_hits "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_misses "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_timeouts "SSL_CTX *ctx" +.Ft long +.Fn SSL_CTX_sess_cache_full "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_sess_number +returns the current number of sessions in the internal session cache. +.Pp +.Fn SSL_CTX_sess_connect +returns the number of started SSL/TLS handshakes in client mode. +.Pp +.Fn SSL_CTX_sess_connect_good +returns the number of successfully established SSL/TLS sessions in client mode. +.Pp +.Fn SSL_CTX_sess_connect_renegotiate +returns the number of started renegotiations in client mode. +.Pp +.Fn SSL_CTX_sess_accept +returns the number of started SSL/TLS handshakes in server mode. +.Pp +.Fn SSL_CTX_sess_accept_good +returns the number of successfully established SSL/TLS sessions in server mode. +.Pp +.Fn SSL_CTX_sess_accept_renegotiate +returns the number of started renegotiations in server mode. +.Pp +.Fn SSL_CTX_sess_hits +returns the number of successfully reused sessions. +In client mode a session set with +.Xr SSL_set_session 3 +successfully reused is counted as a hit. +In server mode a session successfully retrieved from internal or external cache +is counted as a hit. +.Pp +.Fn SSL_CTX_sess_cb_hits +returns the number of successfully retrieved sessions from the external session +cache in server mode. +.Pp +.Fn SSL_CTX_sess_misses +returns the number of sessions proposed by clients that were not found in the +internal session cache in server mode. +.Pp +.Fn SSL_CTX_sess_timeouts +returns the number of sessions proposed by clients and either found in the +internal or external session cache in server mode, +but that were invalid due to timeout. +These sessions are not included in the +.Fn SSL_CTX_sess_hits +count. +.Pp +.Fn SSL_CTX_sess_cache_full +returns the number of sessions that were removed because the maximum session +cache size was exceeded. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_sess_set_cache_size 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_set_session 3 +.Sh HISTORY +.Fn SSL_CTX_sess_number , +.Fn SSL_CTX_sess_connect , +.Fn SSL_CTX_sess_connect_good , +.Fn SSL_CTX_sess_accept , +.Fn SSL_CTX_sess_accept_good , +.Fn SSL_CTX_sess_hits , +.Fn SSL_CTX_sess_misses , +and +.Fn SSL_CTX_sess_timeouts +first appeared in SSLeay 0.5.2. +.Fn SSL_CTX_sess_cb_hits +first appeared in SSLeay 0.6.0. +.Fn SSL_CTX_sess_connect_renegotiate , +.Fn SSL_CTX_sess_accept_renegotiate , +and +.Fn SSL_CTX_sess_cache_full +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_sess_set_cache_size.3 b/Libraries/libressl/man/SSL_CTX_sess_set_cache_size.3 new file mode 100644 index 000000000..6d5fede0b --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_sess_set_cache_size.3 @@ -0,0 +1,109 @@ +.\" $OpenBSD: SSL_CTX_sess_set_cache_size.3,v 1.5 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2002, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_CTX_SESS_SET_CACHE_SIZE 3 +.Os +.Sh NAME +.Nm SSL_CTX_sess_set_cache_size , +.Nm SSL_CTX_sess_get_cache_size +.Nd manipulate session cache size +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_sess_set_cache_size "SSL_CTX *ctx" "long t" +.Ft long +.Fn SSL_CTX_sess_get_cache_size "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_sess_set_cache_size +sets the size of the internal session cache of context +.Fa ctx +to +.Fa t . +.Pp +.Fn SSL_CTX_sess_get_cache_size +returns the currently valid session cache size. +.Pp +The internal session cache size is +.Dv SSL_SESSION_CACHE_MAX_SIZE_DEFAULT , +currently 1024\(mu20, so that up to 20000 sessions can be held. +This size can be modified using the +.Fn SSL_CTX_sess_set_cache_size +call. +A special case is the size 0, which is used for unlimited size. +.Pp +If adding the session makes the cache exceed its size, then unused +sessions are dropped from the end of the cache. +Cache space may also be reclaimed by calling +.Xr SSL_CTX_flush_sessions 3 +to remove expired sessions. +.Pp +If the size of the session cache is reduced and more sessions are already in +the session cache, +old session will be removed the next time a session shall be added. +This removal is not synchronized with the expiration of sessions. +.Sh RETURN VALUES +.Fn SSL_CTX_sess_set_cache_size +returns the previously valid size. +.Pp +.Fn SSL_CTX_sess_get_cache_size +returns the currently valid size. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_sess_number 3 , +.Xr SSL_CTX_set_session_cache_mode 3 +.Sh HISTORY +.Fn SSL_CTX_sess_set_cache_size +and +.Fn SSL_CTX_sess_get_cache_size +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_sess_set_get_cb.3 b/Libraries/libressl/man/SSL_CTX_sess_set_get_cb.3 new file mode 100644 index 000000000..e99f2be67 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_sess_set_get_cb.3 @@ -0,0 +1,221 @@ +.\" $OpenBSD: SSL_CTX_sess_set_get_cb.3,v 1.7 2022/03/29 18:15:52 naddy Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2002, 2003, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 29 2022 $ +.Dt SSL_CTX_SESS_SET_GET_CB 3 +.Os +.Sh NAME +.Nm SSL_CTX_sess_set_new_cb , +.Nm SSL_CTX_sess_set_remove_cb , +.Nm SSL_CTX_sess_set_get_cb , +.Nm SSL_CTX_sess_get_new_cb , +.Nm SSL_CTX_sess_get_remove_cb , +.Nm SSL_CTX_sess_get_get_cb +.Nd provide callback functions for server side external session caching +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_sess_set_new_cb +.Fa "SSL_CTX *ctx" +.Fa "int (*new_session_cb)(SSL *, SSL_SESSION *)" +.Fc +.Ft void +.Fo SSL_CTX_sess_set_remove_cb +.Fa "SSL_CTX *ctx" +.Fa "void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *)" +.Fc +.Ft void +.Fo SSL_CTX_sess_set_get_cb +.Fa "SSL_CTX *ctx" +.Fa "SSL_SESSION (*get_session_cb)(SSL *, const unsigned char *, int, int *)" +.Fc +.Ft int +.Fo "(*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))" +.Fa "SSL *ssl" +.Fa "SSL_SESSION *sess" +.Fc +.Ft void +.Fo "(*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))" +.Fa "SSL_CTX *ctx" +.Fa "SSL_SESSION *sess" +.Fc +.Ft SSL_SESSION * +.Fo "(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))" +.Fa "SSL *ssl" +.Fa "const unsigned char *data" +.Fa "int len" +.Fa "int *copy" +.Fc +.Ft int +.Fo "(*new_session_cb)" +.Fa "SSL *ssl" +.Fa "SSL_SESSION *sess" +.Fc +.Ft void +.Fo "(*remove_session_cb)" +.Fa "SSL_CTX *ctx" +.Fa "SSL_SESSION *sess" +.Fc +.Ft SSL_SESSION * +.Fo "(*get_session_cb)" +.Fa "SSL *ssl" +.Fa "unsigned char *data" +.Fa "int len" +.Fa "int *copy" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_sess_set_new_cb +sets the callback function which is automatically called whenever a new session +was negotiated. +.Pp +.Fn SSL_CTX_sess_set_remove_cb +sets the callback function which is automatically called whenever a session is +removed by the SSL engine (because it is considered faulty or the session has +become obsolete because of exceeding the timeout value). +.Pp +.Fn SSL_CTX_sess_set_get_cb +sets the callback function which is called whenever a SSL/TLS client proposes +to resume a session but the session cannot be found in the internal session +cache (see +.Xr SSL_CTX_set_session_cache_mode 3 ) . +(SSL/TLS server only.) +.Pp +.Fn SSL_CTX_sess_get_new_cb , +.Fn SSL_CTX_sess_get_remove_cb , +and +.Fn SSL_CTX_sess_get_get_cb +retrieve the function pointers of the provided callback functions. +If a callback function has not been set, the +.Dv NULL +pointer is returned. +.Pp +In order to allow external session caching, synchronization with the internal +session cache is realized via callback functions. +Inside these callback functions, session can be saved to disk or put into a +database using the +.Xr d2i_SSL_SESSION 3 +interface. +.Pp +The +.Fn new_session_cb +function is called whenever a new session has been negotiated and session +caching is enabled (see +.Xr SSL_CTX_set_session_cache_mode 3 ) . +The +.Fn new_session_cb +function is passed the +.Fa ssl +connection and the ssl session +.Fa sess . +If the callback returns 0, the session will be immediately removed again. +.Pp +The +.Fn remove_session_cb +function is called whenever the SSL engine removes a session from the +internal cache. +This happens when the session is removed because it is expired or when a +connection was not shut down cleanly. +It also happens for all sessions in the internal session cache when +.Xr SSL_CTX_free 3 +is called. +The +.Fn remove_session_cb +function is passed the +.Fa ctx +and the +.Vt ssl +session +.Fa sess . +It does not provide any feedback. +.Pp +The +.Fn get_session_cb +function is only called on SSL/TLS servers with the session id proposed by the +client. +The +.Fn get_session_cb +function is always called, also when session caching was disabled. +The +.Fn get_session_cb +function is passed the +.Fa ssl +connection, the session id of length +.Fa length +at the memory location +.Fa data . +With the parameter +.Fa copy +the callback can require the SSL engine to increment the reference count of the +.Vt SSL_SESSION +object, +Normally the reference count is not incremented and therefore the session must +not be explicitly freed with +.Xr SSL_SESSION_free 3 . +.Sh SEE ALSO +.Xr d2i_SSL_SESSION 3 , +.Xr ssl 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_free 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_SESSION_free 3 +.Sh HISTORY +.Fn SSL_CTX_sess_set_new_cb , +.Fn SSL_CTX_sess_set_get_cb , +.Fn SSL_CTX_sess_get_new_cb , +and +.Fn SSL_CTX_sess_get_get_cb +first appeared in SSLeay 0.6.0. +.Fn SSL_CTX_sess_set_remove_cb +and +.Fn SSL_CTX_sess_get_remove_cb +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_sessions.3 b/Libraries/libressl/man/SSL_CTX_sessions.3 new file mode 100644 index 000000000..964d1a734 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_sessions.3 @@ -0,0 +1,86 @@ +.\" $OpenBSD: SSL_CTX_sessions.3,v 1.5 2018/04/25 14:19:39 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 25 2018 $ +.Dt SSL_CTX_SESSIONS 3 +.Os +.Sh NAME +.Nm SSL_CTX_sessions +.Nd access internal session cache +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft LHASH_OF(SSL_SESSION) * +.Fn SSL_CTX_sessions "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_sessions +returns a pointer to the lhash databases containing the internal session cache +for +.Fa ctx . +.Pp +The sessions in the internal session cache are kept in an +lhash-type database +(see +.Xr lh_new 3 ) . +It is possible to directly access this database, e.g., for searching. +In parallel, +the sessions form a linked list which is maintained separately from the +lhash operations, +so that the database must not be modified directly but by using the +.Xr SSL_CTX_add_session 3 +family of functions. +.Sh SEE ALSO +.Xr lh_new 3 , +.Xr ssl 3 , +.Xr SSL_CTX_add_session 3 , +.Xr SSL_CTX_set_session_cache_mode 3 +.Sh HISTORY +.Fn SSL_CTX_sessions +first appeared in SSLeay 0.5.2 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_set1_groups.3 b/Libraries/libressl/man/SSL_CTX_set1_groups.3 new file mode 100644 index 000000000..0d1eb36ea --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set1_groups.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: SSL_CTX_set1_groups.3,v 1.2 2017/08/19 19:36:39 schwarze Exp $ +.\" OpenSSL SSL_CTX_set1_curves.pod de4d764e Nov 9 14:51:06 2016 +0000 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2013, 2014, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 19 2017 $ +.Dt SSL_CTX_SET1_GROUPS 3 +.Os +.Sh NAME +.Nm SSL_CTX_set1_groups , +.Nm SSL_CTX_set1_groups_list , +.Nm SSL_set1_groups , +.Nm SSL_set1_groups_list , +.Nm SSL_CTX_set1_curves , +.Nm SSL_CTX_set1_curves_list , +.Nm SSL_set1_curves , +.Nm SSL_set1_curves_list +.Nd choose supported EC groups +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_set1_groups +.Fa "SSL_CTX *ctx" +.Fa "const int *glist" +.Fa "size_t glistlen" +.Fc +.Ft int +.Fo SSL_CTX_set1_groups_list +.Fa "SSL_CTX *ctx" +.Fa "const char *list" +.Fc +.Ft int +.Fo SSL_set1_groups +.Fa "SSL *ssl" +.Fa "const int *glist" +.Fa "size_t glistlen" +.Fc +.Ft int +.Fo SSL_set1_groups_list +.Fa "SSL *ssl" +.Fa "const char *list" +.Fc +.Ft int +.Fo SSL_CTX_set1_curves +.Fa "SSL_CTX *ctx" +.Fa "const int *clist" +.Fa "size_t clistlen" +.Fc +.Ft int +.Fo SSL_CTX_set1_curves_list +.Fa "SSL_CTX *ctx" +.Fa "const char *list" +.Fc +.Ft int +.Fo SSL_set1_curves +.Fa "SSL *ssl" +.Fa "const int *clist" +.Fa "size_t clistlen" +.Fc +.Ft int +.Fo SSL_set1_curves_list +.Fa "SSL *ssl" +.Fa "const char *list" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set1_groups +sets the supported groups for +.Fa ctx +to the +.Fa glistlen +groups in the array +.Fa glist . +The array consists of group NIDs in preference order. +For a TLS client, the groups are used directly in the supported groups +extension. +For a TLS server, the groups are used to determine the set of shared +groups. +.Pp +.Fn SSL_CTX_set1_groups_list +sets the supported groups for +.Fa ctx +to the +.Fa list +represented as a colon separated list of group NIDs or names, for example +"P-521:P-384:P-256". +.Pp +.Fn SSL_set1_groups +and +.Fn SSL_set1_groups_list +are similar except that they set supported groups for the SSL structure +.Fa ssl +only. +.Pp +The curve functions are deprecated synonyms for the equivalently +named group functions and are identical in every respect except +that they are implemented as macros. +They exist because prior to TLS1.3, there was only the concept of +supported curves. +In TLS1.3, this was renamed to supported groups and extended to include +Diffie Hellman groups. +.Pp +If an application wishes to make use of several of these functions for +configuration purposes either on a command line or in a file, it should +consider using the SSL_CONF interface instead of manually parsing +options. +.Sh RETURN VALUES +All these functions return 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_set_cipher_list 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_new 3 +.Sh HISTORY +The curve functions first appeared in OpenSSL 1.0.2 +and the group functions in OpenSSL 1.1.1. +Both have been available since +.Ox 6.1 . diff --git a/Libraries/libressl/man/SSL_CTX_set_alpn_select_cb.3 b/Libraries/libressl/man/SSL_CTX_set_alpn_select_cb.3 new file mode 100644 index 000000000..683b6696e --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_alpn_select_cb.3 @@ -0,0 +1,277 @@ +.\" $OpenBSD: SSL_CTX_set_alpn_select_cb.3,v 1.8 2021/09/10 09:25:29 tb Exp $ +.\" OpenSSL 87b81496 Apr 19 12:38:27 2017 -0400 +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Todd Short . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2021 $ +.Dt SSL_CTX_SET_ALPN_SELECT_CB 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_alpn_protos , +.Nm SSL_set_alpn_protos , +.Nm SSL_CTX_set_alpn_select_cb , +.Nm SSL_select_next_proto , +.Nm SSL_get0_alpn_selected +.Nd handle application layer protocol negotiation (ALPN) +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_set_alpn_protos +.Fa "SSL_CTX *ctx" +.Fa "const unsigned char *protos" +.Fa "unsigned int protos_len" +.Fc +.Ft int +.Fo SSL_set_alpn_protos +.Fa "SSL *ssl" +.Fa "const unsigned char *protos" +.Fa "unsigned int protos_len" +.Fc +.Ft void +.Fo SSL_CTX_set_alpn_select_cb +.Fa "SSL_CTX *ctx" +.Fa "int (*cb)(SSL *ssl, const unsigned char **out,\ + unsigned char *outlen, const unsigned char *in,\ + unsigned int inlen, void *arg)" +.Fa "void *arg" +.Fc +.Ft int +.Fo SSL_select_next_proto +.Fa "unsigned char **out" +.Fa "unsigned char *outlen" +.Fa "const unsigned char *server" +.Fa "unsigned int server_len" +.Fa "const unsigned char *client" +.Fa "unsigned int client_len" +.Fc +.Ft void +.Fo SSL_get0_alpn_selected +.Fa "const SSL *ssl" +.Fa "const unsigned char **data" +.Fa "unsigned int *len" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_alpn_protos +and +.Fn SSL_set_alpn_protos +are used by the client to set the list of protocols available to be +negotiated. +The +.Fa protos +must be in protocol-list format, described below. +The length of +.Fa protos +is specified in +.Fa protos_len . +.Pp +.Fn SSL_CTX_set_alpn_select_cb +sets the application callback +.Fa cb +used by a server to select which protocol to use for the incoming +connection. +When +.Fa cb +is +.Dv NULL , +ALPN is not used. +The +.Fa arg +value is a pointer which is passed to the application callback. +.Pp +.Fa cb +is the application defined callback. +The +.Fa in , +.Fa inlen +parameters are a vector in protocol-list format. +The value of the +.Fa out , +.Fa outlen +vector should be set to the value of a single protocol selected from the +.Fa in , +.Fa inlen +vector. +The +.Fa out +buffer may point directly into +.Fa in , +or to a buffer that outlives the handshake. +The +.Fa arg +parameter is the pointer set via +.Fn SSL_CTX_set_alpn_select_cb . +.Pp +.Fn SSL_select_next_proto +is a helper function used to select protocols. +It implements the standard protocol selection. +It is expected that this function is called from the application +callback +.Fa cb . +The protocol data in +.Fa server , +.Fa server_len +and +.Fa client , +.Fa client_len +must be in the protocol-list format described below. +The first item in the +.Fa server , +.Fa server_len +list that matches an item in the +.Fa client , +.Fa client_len +list is selected, and returned in +.Fa out , +.Fa outlen . +The +.Fa out +value will point into either +.Fa server +or +.Fa client , +so it should be copied immediately. +If no match is found, the first item in +.Fa client , +.Fa client_len +is returned in +.Fa out , +.Fa outlen . +.Pp +.Fn SSL_get0_alpn_selected +returns a pointer to the selected protocol in +.Fa data +with length +.Fa len . +It is not NUL-terminated. +.Fa data +is set to +.Dv NULL +and +.Fa len +is set to 0 if no protocol has been selected. +.Fa data +must not be freed. +.Pp +The protocol-lists must be in wire-format, which is defined as a vector +of non-empty, 8-bit length-prefixed byte strings. +The length-prefix byte is not included in the length. +Each string is limited to 255 bytes. +A byte-string length of 0 is invalid. +A truncated byte-string is invalid. +The length of the vector is not in the vector itself, but in a separate +variable. +.Pp +For example: +.Bd -literal +unsigned char vector[] = { + 6, 's', 'p', 'd', 'y', '/', '1', + 8, 'h', 't', 't', 'p', '/', '1', '.', '1' +}; +unsigned int length = sizeof(vector); +.Ed +.Pp +The ALPN callback is executed after the servername callback; as that +servername callback may update the SSL_CTX, and subsequently, the ALPN +callback. +.Pp +If there is no ALPN proposed in the ClientHello, the ALPN callback is +not invoked. +.Sh RETURN VALUES +.Fn SSL_CTX_set_alpn_protos +and +.Fn SSL_set_alpn_protos +return 0 on success or non-zero on failure. +WARNING: these functions reverse the return value convention. +.Pp +.Fn SSL_select_next_proto +returns one of the following: +.Bl -tag -width Ds +.It OPENSSL_NPN_NEGOTIATED +A match was found and is returned in +.Fa out , +.Fa outlen . +.It OPENSSL_NPN_NO_OVERLAP +No match was found. +The first item in +.Fa client , +.Fa client_len +is returned in +.Fa out , +.Fa outlen . +.El +.Pp +The ALPN select callback +.Fa cb +must return one of the following: +.Bl -tag -width Ds +.It SSL_TLSEXT_ERR_OK +ALPN protocol selected. +.It SSL_TLSEXT_ERR_ALERT_FATAL +There was no overlap between the client's supplied list and the +server configuration. +.It SSL_TLSEXT_ERR_NOACK +ALPN protocol not selected, e.g., because no ALPN protocols are +configured for this connection. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_tlsext_servername_arg 3 , +.Xr SSL_CTX_set_tlsext_servername_callback 3 +.Sh HISTORY +.Fn SSL_select_next_proto +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . +.Pp +.Fn SSL_CTX_set_alpn_protos , +.Fn SSL_set_alpn_protos , +.Fn SSL_CTX_set_alpn_select_cb , +and +.Fn SSL_get0_alpn_selected +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 5.7 . diff --git a/Libraries/libressl/man/SSL_CTX_set_cert_store.3 b/Libraries/libressl/man/SSL_CTX_set_cert_store.3 new file mode 100644 index 000000000..b23e3c4a1 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_cert_store.3 @@ -0,0 +1,130 @@ +.\" $OpenBSD: SSL_CTX_set_cert_store.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2002, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_SET_CERT_STORE 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_cert_store , +.Nm SSL_CTX_get_cert_store +.Nd manipulate X509 certificate verification storage +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_CTX_set_cert_store "SSL_CTX *ctx" "X509_STORE *store" +.Ft X509_STORE * +.Fn SSL_CTX_get_cert_store "const SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_cert_store +sets the verification storage of +.Fa ctx +to or replaces it with +.Fa store . +If another +.Vt X509_STORE +object is currently set in +.Fa ctx , +it will be freed. +.Pp +.Fn SSL_CTX_get_cert_store +returns a pointer to the current certificate verification storage. +.Pp +In order to verify the certificates presented by the peer, trusted CA +certificates must be accessed. +These CA certificates are made available via lookup methods, handled inside the +.Vt X509_STORE . +From the +.Vt X509_STORE +the +.Vt X509_STORE_CTX +used when verifying certificates is created. +.Pp +Typically the trusted certificate store is handled indirectly via using +.Xr SSL_CTX_load_verify_locations 3 . +Using the +.Fn SSL_CTX_set_cert_store +and +.Fn SSL_CTX_get_cert_store +functions it is possible to manipulate the +.Vt X509_STORE +object beyond the +.Xr SSL_CTX_load_verify_locations 3 +call. +.Pp +Currently no detailed documentation on how to use the +.Vt X509_STORE +object is available. +Not all members of the +.Vt X509_STORE +are used when the verification takes place. +So will, for example, the +.Fn verify_callback +be overridden with the +.Fn verify_callback +set via the +.Xr SSL_CTX_set_verify 3 +family of functions. +This document must therefore be updated when documentation about the +.Vt X509_STORE +object and its handling becomes available. +.Sh RETURN VALUES +.Fn SSL_CTX_get_cert_store +returns the current setting. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr X509_STORE_new 3 +.Sh HISTORY +.Fn SSL_CTX_set_cert_store +and +.Fn SSL_CTX_get_cert_store +first appeared in SSLeay 0.8.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_set_cert_verify_callback.3 b/Libraries/libressl/man/SSL_CTX_set_cert_verify_callback.3 new file mode 100644 index 000000000..0e12b48c7 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_cert_verify_callback.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: SSL_CTX_set_cert_verify_callback.3,v 1.5 2019/06/08 15:25:43 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 8 2019 $ +.Dt SSL_CTX_SET_CERT_VERIFY_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_cert_verify_callback +.Nd set peer certificate verification procedure +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_cert_verify_callback +.Fa "SSL_CTX *ctx" +.Fa "int (*callback)(X509_STORE_CTX *, void *)" +.Fa "void *arg" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_cert_verify_callback +sets the verification callback function for +.Fa ctx . +.Vt SSL +objects that are created from +.Fa ctx +inherit the setting valid at the time when +.Xr SSL_new 3 +is called. +.Pp +Whenever a certificate is verified during a SSL/TLS handshake, +a verification function is called. +If the application does not explicitly specify a verification callback +function, the built-in verification function is used. +If a verification callback +.Fa callback +is specified via +.Fn SSL_CTX_set_cert_verify_callback , +the supplied callback function is called instead. +By setting +.Fa callback +to +.Dv NULL , +the default behaviour is restored. +.Pp +When the verification must be performed, +.Fa callback +will be called with the arguments +.Fn callback "X509_STORE_CTX *x509_store_ctx" "void *arg" . +The argument +.Fa arg +is specified by the application when setting +.Fa callback . +.Pp +.Fa callback +should return 1 to indicate verification success and 0 to indicate verification +failure. +If +.Dv SSL_VERIFY_PEER +is set and +.Fa callback +returns 0, the handshake will fail. +As the verification procedure may allow the connection to continue in case of +failure (by always returning 1) the verification result must be set in any case +using the +.Fa error +member of +.Fa x509_store_ctx +so that the calling application will be informed about the detailed result of +the verification procedure! +.Pp +Within +.Fa x509_store_ctx , +.Fa callback +has access to the +.Fa verify_callback +function set using +.Xr SSL_CTX_set_verify 3 . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr SSL_get_verify_result 3 +.Sh HISTORY +.Fn SSL_CTX_set_cert_verify_callback +first appeared in SSLeay 0.6.1 and has been available since +.Ox 2.4 . +.Pp +Previous to OpenSSL 0.9.7, the +.Fa arg +argument to +.Fn SSL_CTX_set_cert_verify_callback +was ignored, and +.Fa callback +was called +simply as +.Ft int +.Fn (*callback) "X509_STORE_CTX *" . +To compile software written for previous versions of OpenSSL, +a dummy argument will have to be added to +.Fa callback . +.Sh CAVEATS +Do not mix the verification callback described in this function with the +.Fa verify_callback +function called during the verification process. +The latter is set using the +.Xr SSL_CTX_set_verify 3 +family of functions. +.Pp +Providing a complete verification procedure including certificate purpose +settings, etc., is a complex task. +The built-in procedure is quite powerful and in most cases it should be +sufficient to modify its behaviour using the +.Fa verify_callback +function. +.Sh BUGS +.Fn SSL_CTX_set_cert_verify_callback +does not provide diagnostic information. diff --git a/Libraries/libressl/man/SSL_CTX_set_cipher_list.3 b/Libraries/libressl/man/SSL_CTX_set_cipher_list.3 new file mode 100644 index 000000000..9d24e0088 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_cipher_list.3 @@ -0,0 +1,391 @@ +.\" $OpenBSD: SSL_CTX_set_cipher_list.3,v 1.16 2022/12/11 20:53:27 tb Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 11 2022 $ +.Dt SSL_CTX_SET_CIPHER_LIST 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_cipher_list , +.Nm SSL_set_cipher_list +.Nd choose list of available SSL_CIPHERs +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_CTX_set_cipher_list "SSL_CTX *ctx" "const char *control" +.Ft int +.Fn SSL_set_cipher_list "SSL *ssl" "const char *control" +.Sh DESCRIPTION +.Fn SSL_CTX_set_cipher_list +sets the list of available cipher suites for +.Fa ctx +using the +.Fa control +string. +The list of cipher suites is inherited by all +.Fa ssl +objects created from +.Fa ctx . +.Pp +.Fn SSL_set_cipher_list +sets the list of cipher suites only for +.Fa ssl . +.Pp +The control string consists of one or more control words +separated by colon characters +.Pq Ql \&: . +Space +.Pq Ql \ \& , +semicolon +.Pq Ql \&; , +and comma +.Pq Ql \&, +characters can also be used as separators. +Each control words selects a set of cipher suites +and can take one of the following optional prefix characters: +.Bl -tag -width Ds +.It \&No prefix: +Those of the selected cipher suites that have not been made available +yet are added to the end of the list of available cipher suites, +preserving their order. +.It Prefixed minus sign Pq Ql \- : +Those of the selected cipher suites that have been made available +earlier are moved back from the list of available cipher suites to +the beginning of the list of unavailable cipher suites, +also preserving their order. +.It Prefixed plus sign Pq Ql + : +Those of the selected cipher suites have been made available earlier +are moved to end of the list of available cipher suites, reducing +their priority, but preserving the order among themselves. +.It Prefixed exclamation mark Pq Ql \&! : +The selected cipher suites are permanently deleted, no matter whether +they had earlier been made available or not, and can no longer +be added or re-added by later words. +.El +.Pp +The following special words can only be used without a prefix: +.Bl -tag -width Ds +.It Cm DEFAULT +An alias for +.Sm off +.Cm ALL No :! Cm aNULL No :! Cm eNULL . +.Sm on +It can only be used as the first word. +The +.Cm DEFAULT +cipher list can be displayed with the +.Xr openssl 1 +.Cm ciphers +command. +.It Cm @SECLEVEL=n +Set the security level to n, which should be a number between +zero and five. +See +.Xr SSL_CTX_set_security_level 3 +for details. +.It Cm @STRENGTH +Sort the list by decreasing encryption strength, +preserving the order of cipher suites that have the same strength. +It is usually given as the last word. +.El +.Pp +The following words can be used to select groups of cipher suites, +with or without a prefix character. +If two or more of these words are joined with plus signs +.Pq Ql + +to form a longer word, only the intersection of the specified sets +is selected. +.Bl -tag -width Ds +.It Cm ADH +Cipher suites using ephemeral DH for key exchange +without doing any server authentication. +Equivalent to +.Cm DH Ns + Ns Cm aNULL . +.It Cm AEAD +Cipher suites using Authenticated Encryption with Additional Data. +.It Cm AECDH +Cipher suites using ephemeral ECDH for key exchange +without doing any server authentication. +Equivalent to +.Cm ECDH Ns + Ns Cm aNULL . +.It Cm aECDSA +Cipher suites using ECDSA server authentication. +.It Cm AES +Cipher suites using AES or AESGCM for symmetric encryption. +.It Cm AES128 +Cipher suites using AES(128) or AESGCM(128) for symmetric encryption. +.It Cm AES256 +Cipher suites using AES(256) or AESGCM(256) for symmetric encryption. +.It Cm AESGCM +Cipher suites using AESGCM for symmetric encryption. +.It Cm aGOST +An alias for +.Cm aGOST01 . +.It Cm aGOST01 +Cipher suites using GOST R 34.10-2001 server authentication. +.It Cm ALL +All cipher suites except those selected by +.Cm eNULL . +.It Cm aNULL +Cipher suites that don't do any server authentication. +Not enabled by +.Cm DEFAULT . +Beware of man-in-the-middle attacks. +.It Cm aRSA +Cipher suites using RSA server authentication. +.It Cm CAMELLIA +Cipher suites using Camellia for symmetric encryption. +.It Cm CAMELLIA128 +Cipher suites using Camellia(128) for symmetric encryption. +.It Cm CAMELLIA256 +Cipher suites using Camellia(256) for symmetric encryption. +.It Cm CHACHA20 +Cipher suites using ChaCha20-Poly1305 for symmetric encryption. +.It Cm COMPLEMENTOFALL +Cipher suites that are not included in +.Cm ALL . +Currently an alias for +.Cm eNULL . +.It Cm COMPLEMENTOFDEFAULT +Cipher suites that are included in +.Cm ALL , +but not included in +.Cm DEFAULT . +Currently similar to +.Cm aNULL Ns :! Ns Cm eNULL +except for the order of the cipher suites which are +.Em not +selected. +.It Cm 3DES +Cipher suites using triple DES for symmetric encryption. +.It Cm DH +Cipher suites using ephemeral DH for key exchange. +.It Cm DHE +Cipher suites using ephemeral DH for key exchange, +but excluding those that don't do any server authentication. +Similar to +.Cm DH Ns :! Ns Cm aNULL +except for the order of the cipher suites which are +.Em not +selected. +.It Cm ECDH +Cipher suites using ephemeral ECDH for key exchange. +.It Cm ECDHE +Cipher suites using ephemeral ECDH for key exchange, +but excluding those that don't do any server authentication. +Similar to +.Cm ECDH Ns :! Ns Cm aNULL +except for the order of the cipher suites which are +.Em not +selected. +.It Cm ECDSA +An alias for +.Cm aECDSA . +.It Cm eNULL +Cipher suites that do not use any encryption. +Not enabled by +.Cm DEFAULT , +and not even included in +.Cm ALL . +.It Cm GOST89MAC +Cipher suites using GOST 28147-89 for message authentication +instead of HMAC. +.It Cm GOST94 +Cipher suites using HMAC based on GOST R 34.11-94 +for message authentication. +.It Cm HIGH +Cipher suites of high strength. +.It Cm kGOST +Cipher suites using VKO 34.10 key exchange, specified in RFC 4357. +.It Cm kRSA +Cipher suites using RSA key exchange. +.It Cm LOW +Cipher suites of low strength. +.It Cm MD5 +Cipher suites using MD5 for message authentication. +.It Cm MEDIUM +Cipher suites of medium strength. +.It Cm NULL +An alias for +.Cm eNULL . +.It Cm RC4 +Cipher suites using RC4 for symmetric encryption. +.It Cm RSA +Cipher suites using RSA for both key exchange and server authentication. +Equivalent to +.Cm kRSA Ns + Ns Cm aRSA . +.It Cm SHA +An alias for +.Cm SHA1 . +.It Cm SHA1 +Cipher suites using SHA1 for message authentication. +.It Cm SHA256 +Cipher suites using SHA256 for message authentication. +.It Cm SHA384 +Cipher suites using SHA384 for message authentication. +.It Cm SSLv3 +An alias for +.Cm TLSv1 . +.It Cm STREEBOG256 +Cipher suites using STREEBOG256 for message authentication. +.It Cm TLSv1 +Cipher suites usable with the TLSv1.0, TLSv1.1, and TLSv1.2 protocols. +.It Cm TLSv1.2 +Cipher suites for the TLSv1.2 protocol. +.It Cm TLSv1.3 +Cipher suites for the TLSv1.3 protocol. +If the +.Fa control +string selects at least one cipher suite but neither contains the word +.Cm TLSv1.3 +nor specifically includes nor excludes any TLSv1.3 cipher suites, all the +.Cm TLSv1.3 +cipher suites are made available, too. +.El +.Pp +The full words returned by the +.Xr openssl 1 +.Cm ciphers +command can be used to select individual cipher suites. +.Pp +The following words do not match anything because +LibreSSL no longer provides any such cipher suites: +.Pp +.Bl -tag -width Ds -compact +.It Cm DES +Cipher suites using single DES for symmetric encryption. +.It Cm DSS +Cipher suites using DSS server authentication. +.It Cm IDEA +Cipher suites using IDEA for symmetric encryption. +.El +.Pp +The following are deprecated aliases: +.Pp +.Bl -column kEECDH ECDHE -compact -offset indent +.It avoid: Ta use: +.It Cm EDH Ta Cm DHE +.It Cm EECDH Ta Cm ECDHE +.It Cm kEDH Ta Cm DH +.It Cm kEECDH Ta Cm ECDH +.El +.Pp +Unknown words are silently ignored, selecting no cipher suites. +Failure is only flagged if the +.Fa control +string contains invalid bytes +or if no matching cipher suites are available at all. +.Pp +On the client side, including a cipher suite into the list of +available cipher suites is sufficient for using it. +On the server side, all cipher suites have additional requirements. +ADH ciphers don't need a certificate, but DH-parameters must have been set. +All other cipher suites need a corresponding certificate and key. +.Pp +A RSA cipher can only be chosen when an RSA certificate is available. +RSA ciphers using DHE need a certificate and key and additional DH-parameters +(see +.Xr SSL_CTX_set_tmp_dh_callback 3 ) . +.Pp +A DSA cipher can only be chosen when a DSA certificate is available. +DSA ciphers always use DH key exchange and therefore need DH-parameters (see +.Xr SSL_CTX_set_tmp_dh_callback 3 ) . +.Pp +When these conditions are not met +for any cipher suite in the list (for example, a +client only supports export RSA ciphers with an asymmetric key length of 512 +bits and the server is not configured to use temporary RSA keys), the +.Dq no shared cipher +.Pq Dv SSL_R_NO_SHARED_CIPHER +error is generated and the handshake will fail. +.Sh RETURN VALUES +.Fn SSL_CTX_set_cipher_list +and +.Fn SSL_set_cipher_list +return 1 if any cipher suite could be selected and 0 on complete failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set1_groups 3 , +.Xr SSL_CTX_set_tmp_dh_callback 3 , +.Xr SSL_CTX_use_certificate 3 , +.Xr SSL_get_ciphers 3 +.Sh HISTORY +.Fn SSL_CTX_set_cipher_list +and +.Fn SSL_set_cipher_list +first appeared in SSLeay 0.5.2 and have been available since +.Ox 2.4 . +.Sh CAVEATS +In LibreSSL, +.Fn SSL_CTX_set_cipher_list +and +.Fn SSL_set_cipher_list +can be used to configure the list of available cipher suites for +all versions of the TLS protocol, whereas in OpenSSL, they only +control cipher suites for protocols up to TLSv1.2. +If compatibility with OpenSSL is required, the list of +available TLSv1.3 cipher suites can only be changed with +.Fn SSL_set_ciphersuites . diff --git a/Libraries/libressl/man/SSL_CTX_set_client_CA_list.3 b/Libraries/libressl/man/SSL_CTX_set_client_CA_list.3 new file mode 100644 index 000000000..d19fb93ed --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_client_CA_list.3 @@ -0,0 +1,183 @@ +.\" $OpenBSD: SSL_CTX_set_client_CA_list.3,v 1.6 2020/03/30 10:28:59 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 30 2020 $ +.Dt SSL_CTX_SET_CLIENT_CA_LIST 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_client_CA_list , +.Nm SSL_set_client_CA_list , +.Nm SSL_CTX_add_client_CA , +.Nm SSL_add_client_CA +.Nd set list of CAs sent to the client when requesting a client certificate +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_CTX_set_client_CA_list "SSL_CTX *ctx" "STACK_OF(X509_NAME) *list" +.Ft void +.Fn SSL_set_client_CA_list "SSL *s" "STACK_OF(X509_NAME) *list" +.Ft int +.Fn SSL_CTX_add_client_CA "SSL_CTX *ctx" "X509 *cacert" +.Ft int +.Fn SSL_add_client_CA "SSL *ssl" "X509 *cacert" +.Sh DESCRIPTION +.Fn SSL_CTX_set_client_CA_list +sets the +.Fa list +of CAs sent to the client when requesting a client certificate for +.Fa ctx . +.Pp +.Fn SSL_set_client_CA_list +sets the +.Fa list +of CAs sent to the client when requesting a client certificate for the chosen +.Fa ssl , +overriding the setting valid for +.Fa ssl Ns 's +.Vt SSL_CTX +object. +.Pp +.Fn SSL_CTX_add_client_CA +adds the CA name extracted from +.Fa cacert +to the list of CAs sent to the client when requesting a client certificate for +.Fa ctx . +.Pp +.Fn SSL_add_client_CA +adds the CA name extracted from +.Fa cacert +to the list of CAs sent to the client when requesting a client certificate for +the chosen +.Fa ssl , +overriding the setting valid for +.Fa ssl Ns 's +.Va SSL_CTX +object. +.Pp +When a TLS/SSL server requests a client certificate (see +.Fn SSL_CTX_set_verify ) , +it sends a list of CAs for which it will accept certificates to the client. +.Pp +This list must explicitly be set using +.Fn SSL_CTX_set_client_CA_list +for +.Fa ctx +and +.Fn SSL_set_client_CA_list +for the specific +.Fa ssl . +The list specified overrides the previous setting. +The CAs listed do not become trusted +.Po +.Fa list +only contains the names, not the complete certificates +.Pc ; +use +.Xr SSL_CTX_load_verify_locations 3 +to additionally load them for verification. +.Pp +If the list of acceptable CAs is compiled in a file, the +.Xr SSL_load_client_CA_file 3 +function can be used to help importing the necessary data. +.Pp +.Fn SSL_CTX_add_client_CA +and +.Fn SSL_add_client_CA +can be used to add additional items the list of client CAs. +If no list was specified before using +.Fn SSL_CTX_set_client_CA_list +or +.Fn SSL_set_client_CA_list , +a new client CA list for +.Fa ctx +or +.Fa ssl +(as appropriate) is opened. +.Pp +These functions are only useful for TLS/SSL servers. +.Sh RETURN VALUES +.Fn SSL_CTX_add_client_CA +and +.Fn SSL_add_client_CA +have the following return values: +.Bl -tag -width Ds +.It 0 +A failure while manipulating the +.Dv STACK_OF Ns +.Pq Vt X509_NAME +object occurred or the +.Vt X509_NAME +could not be extracted from +.Fa cacert . +Check the error stack to find out the reason. +.It 1 +The operation succeeded. +.El +.Sh EXAMPLES +Scan all certificates in +.Fa CAfile +and list them as acceptable CAs: +.Bd -literal +SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_get_client_CA_list 3 , +.Xr SSL_load_client_CA_file 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn SSL_CTX_set_client_CA_list , +.Fn SSL_set_client_CA_list , +.Fn SSL_CTX_add_client_CA , +and +.Fn SSL_add_client_CA +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_set_client_cert_cb.3 b/Libraries/libressl/man/SSL_CTX_set_client_cert_cb.3 new file mode 100644 index 000000000..a2433b5e9 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_client_cert_cb.3 @@ -0,0 +1,191 @@ +.\" $OpenBSD: SSL_CTX_set_client_cert_cb.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_SET_CLIENT_CERT_CB 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_client_cert_cb , +.Nm SSL_CTX_get_client_cert_cb +.Nd handle client certificate callback function +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_client_cert_cb +.Fa "SSL_CTX *ctx" +.Fa "int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)" +.Fc +.Ft int +.Fo "(*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))" +.Fa "SSL *ssl" "X509 **x509" "EVP_PKEY **pkey" +.Fc +.Ft int +.Fn "(*client_cert_cb)" "SSL *ssl" "X509 **x509" "EVP_PKEY **pkey" +.Sh DESCRIPTION +.Fn SSL_CTX_set_client_cert_cb +sets the +.Fa client_cert_cb() +callback that is called when a client certificate is requested by a server and +no certificate was yet set for the SSL object. +.Pp +When +.Fa client_cert_cb +is +.Dv NULL , +no callback function is used. +.Pp +.Fn SSL_CTX_get_client_cert_cb +returns a pointer to the currently set callback function. +.Pp +.Fn client_cert_cb +is the application-defined callback. +If it wants to set a certificate, +a certificate/private key combination must be set using the +.Fa x509 +and +.Fa pkey +arguments and 1 must be returned. +The certificate will be installed into +.Fa ssl . +If no certificate should be set, +0 has to be returned and no certificate will be sent. +A negative return value will suspend the handshake and the handshake function +will return immediately. +.Xr SSL_get_error 3 +will return +.Dv SSL_ERROR_WANT_X509_LOOKUP +to indicate that the handshake was suspended. +The next call to the handshake function will again lead to the call of +.Fa client_cert_cb() . +It is the job of the +.Fa client_cert_cb() +to store information +about the state of the last call, if required to continue. +.Pp +During a handshake (or renegotiation) +a server may request a certificate from the client. +A client certificate must only be sent when the server did send the request. +.Pp +When a certificate has been set using the +.Xr SSL_CTX_use_certificate 3 +family of functions, +it will be sent to the server. +The TLS standard requires that only a certificate is sent if it matches the +list of acceptable CAs sent by the server. +This constraint is violated by the default behavior of the OpenSSL library. +Using the callback function it is possible to implement a proper selection +routine or to allow a user interaction to choose the certificate to be sent. +.Pp +If a callback function is defined and no certificate was yet defined for the +.Vt SSL +object, the callback function will be called. +If the callback function returns a certificate, the OpenSSL library +will try to load the private key and certificate data into the +.Vt SSL +object using the +.Fn SSL_use_certificate +and +.Fn SSL_use_private_key +functions. +Thus it will permanently install the certificate and key for this SSL object. +It will not be reset by calling +.Xr SSL_clear 3 . +If the callback returns no certificate, the OpenSSL library will not send a +certificate. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_use_certificate 3 , +.Xr SSL_free 3 , +.Xr SSL_get_client_CA_list 3 +.Sh HISTORY +.Fn SSL_CTX_set_client_cert_cb +and +.Fn SSL_CTX_get_client_cert_cb +first appeared in SSLeay 0.6.6 and have been available since +.Ox 2.4 . +.Sh BUGS +The +.Fa client_cert_cb() +cannot return a complete certificate chain; +it can only return one client certificate. +If the chain only has a length of 2, +the root CA certificate may be omitted according to the TLS standard and +thus a standard conforming answer can be sent to the server. +For a longer chain, the client must send the complete chain +(with the option to leave out the root CA certificate). +This can be accomplished only by either adding the intermediate CA certificates +into the trusted certificate store for the +.Vt SSL_CTX +object (resulting in having to add CA certificates that otherwise maybe would +not be trusted), or by adding the chain certificates using the +.Xr SSL_CTX_add_extra_chain_cert 3 +function, which is only available for the +.Vt SSL_CTX +object as a whole and that therefore probably can only apply for one client +certificate, making the concept of the callback function +(to allow the choice from several certificates) questionable. +.Pp +Once the +.Vt SSL +object has been used in conjunction with the callback function, +the certificate will be set for the +.Vt SSL +object and will not be cleared even when +.Xr SSL_clear 3 +is called. +It is therefore +.Em mandatory +to destroy the +.Vt SSL +object using +.Xr SSL_free 3 +and create a new one to return to the previous state. diff --git a/Libraries/libressl/man/SSL_CTX_set_default_passwd_cb.3 b/Libraries/libressl/man/SSL_CTX_set_default_passwd_cb.3 new file mode 100644 index 000000000..94b4ea543 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_default_passwd_cb.3 @@ -0,0 +1,216 @@ +.\" $OpenBSD: SSL_CTX_set_default_passwd_cb.3,v 1.9 2023/09/19 09:40:35 schwarze Exp $ +.\" full merge up to: OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" selective merge up to: OpenSSL 18bad535 Apr 9 15:13:55 2019 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Lutz Jaenicke +.\" and Christian Heimes . +.\" Copyright (c) 2000, 2001, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 19 2023 $ +.Dt SSL_CTX_SET_DEFAULT_PASSWD_CB 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_default_passwd_cb , +.Nm SSL_CTX_set_default_passwd_cb_userdata , +.Nm SSL_CTX_get_default_passwd_cb , +.Nm SSL_CTX_get_default_passwd_cb_userdata +.Nd set or get passwd callback for encrypted PEM file handling +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_CTX_set_default_passwd_cb "SSL_CTX *ctx" "pem_password_cb *cb" +.Ft void +.Fn SSL_CTX_set_default_passwd_cb_userdata "SSL_CTX *ctx" "void *userdata" +.Ft pem_password_cb * +.Fn SSL_CTX_get_default_passwd_cb "SSL_CTX *ctx" +.Ft void * +.Fn SSL_CTX_get_default_passwd_cb_userdata "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_default_passwd_cb +sets the password callback for loading a certificate or private key +from encrypted PEM format. +In particular, the callback is used by +.Xr SSL_CTX_use_certificate_file 3 , +.Xr SSL_use_certificate_file 3 , +.Xr SSL_CTX_use_certificate_chain_file 3 , +.Xr SSL_use_certificate_chain_file 3 , +.Xr SSL_CTX_use_certificate_chain_mem 3 , +.Xr SSL_CTX_use_PrivateKey_file 3 , +.Xr SSL_use_PrivateKey_file 3 , +.Xr SSL_CTX_use_RSAPrivateKey_file 3 , +and +.Xr SSL_use_RSAPrivateKey_file 3 . +.Pp +The function pointer type of the +.Fa cb +argument is documented in the +.Xr pem_password_cb 3 +manual page. +If +.Fn SSL_CTX_set_default_passwd_cb +is not called on +.Fa ctx +or if it is called with a +.Fa cb +argument of +.Dv NULL , +.Xr PEM_def_callback 3 +is used instead. +.Pp +.Fn SSL_CTX_set_default_passwd_cb_userdata +sets a pointer to the +.Fa userdata +which will be provided to the password callback on invocation. +.Pp +Since the +.Fa cb +passed to +.Fn SSL_CTX_set_default_passwd_cb +will only be used for reading and decryption and not for writing and +encryption, the library will only call it with a +.Fa verify +argument of 0. +.Pp +If an application program only needs to read and decrypt +one single private key, it can be practical to have the +callback handle the password dialog interactively. +This happens by default if neither +.Fn SSL_CTX_set_default_passwd_cb +nor +.Fn SSL_CTX_set_default_passwd_cb_userdata +is called. +In that case, the library uses +.Xr PEM_def_callback 3 +with a +.Fa userdata +argument of +.Dv NULL . +.Pp +If several keys have to be handled, it can be practical +to ask for the password once, for example using +.Xr UI_UTIL_read_pw_string 3 , +then keep it in memory and use it several times by passing a pointer to it to +.Fn SSL_CTX_set_default_passwd_cb_userdata . +.Xr PEM_def_callback 3 +is able to handle this case, too, so calling +.Fn SSL_CTX_set_default_passwd_cb +is not needed in this case either. +.Pp +Other items in PEM formatting (certificates) can also be encrypted; it is +however atypical, as certificate information is considered public. +.Sh RETURN VALUES +.Fn SSL_CTX_get_default_passwd_cb +returns a function pointer to the password callback currently set in +.Fa ctx , +or +.Dv NULL +if none is set. +.Pp +.Fn SSL_CTX_get_default_passwd_cb_userdata +returns a pointer to the userdata currently set in +.Fa ctx , +or +.Dv NULL +if none is set. +.Sh EXAMPLES +The following example provides a subset of the functionality of +.Xr PEM_def_callback 3 , +except that +.Xr PEM_def_callback 3 +does not NUL-terminate and copies up to +.Fa size +rather than +.Fa size No \- 1 +bytes. +It interprets +.Fa userdata +as a NUL-terminated string and copies it to the +.Fa password +buffer, truncating the copy if it does not fit. +.Bd -literal +int +trivial_passwd_cb(char *password, int size, int verify, void *userdata) +{ + strlcpy(password, userdata, size); + return strlen(password); +} +.Ed +.Sh SEE ALSO +.Xr pem_password_cb 3 , +.Xr ssl 3 , +.Xr SSL_CTX_use_certificate 3 +.Sh HISTORY +.Fn SSL_CTX_set_default_passwd_cb +first appeared in SSLeay 0.6.2 and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_set_default_passwd_cb_userdata +first appeared in OpenSSL 0.9.4 and has been available since +.Ox 2.6 . +.Pp +.Fn SSL_CTX_get_default_passwd_cb +and +.Fn SSL_CTX_get_default_passwd_cb_userdata +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_CTX_set_generate_session_id.3 b/Libraries/libressl/man/SSL_CTX_set_generate_session_id.3 new file mode 100644 index 000000000..d85383d77 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_generate_session_id.3 @@ -0,0 +1,221 @@ +.\" $OpenBSD: SSL_CTX_set_generate_session_id.3,v 1.5 2018/03/22 21:09:18 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt SSL_CTX_SET_GENERATE_SESSION_ID 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_generate_session_id , +.Nm SSL_set_generate_session_id , +.Nm SSL_has_matching_session_id , +.Nm GEN_SESSION_CB +.Nd manipulate generation of SSL session IDs (server only) +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft typedef int +.Fo (*GEN_SESSION_CB) +.Fa "const SSL *ssl" +.Fa "unsigned char *id" +.Fa "unsigned int *id_len" +.Fc +.Ft int +.Fn SSL_CTX_set_generate_session_id "SSL_CTX *ctx" "GEN_SESSION_CB cb" +.Ft int +.Fn SSL_set_generate_session_id "SSL *ssl" "GEN_SESSION_CB cb" +.Ft int +.Fo SSL_has_matching_session_id +.Fa "const SSL *ssl" "const unsigned char *id" "unsigned int id_len" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_generate_session_id +sets the callback function for generating new session ids for SSL/TLS sessions +for +.Fa ctx +to be +.Fa cb . +.Pp +.Fn SSL_set_generate_session_id +sets the callback function for generating new session ids for SSL/TLS sessions +for +.Fa ssl +to be +.Fa cb . +.Pp +.Fn SSL_has_matching_session_id +checks, whether a session with id +.Fa id +(of length +.Fa id_len ) +is already contained in the internal session cache +of the parent context of +.Fa ssl . +.Pp +When a new session is established between client and server, +the server generates a session id. +The session id is an arbitrary sequence of bytes. +The length of the session id is between 1 and 32 bytes. +The session id is not security critical but must be unique for the server. +Additionally, the session id is transmitted in the clear when reusing the +session so it must not contain sensitive information. +.Pp +Without a callback being set, an OpenSSL server will generate a unique session +id from pseudo random numbers of the maximum possible length. +Using the callback function, the session id can be changed to contain +additional information like, e.g., a host id in order to improve load balancing +or external caching techniques. +.Pp +The callback function receives a pointer to the memory location to put +.Fa id +into and a pointer to the maximum allowed length +.Fa id_len . +The buffer at location +.Fa id +is only guaranteed to have the size +.Fa id_len . +The callback is only allowed to generate a shorter id and reduce +.Fa id_len ; +the callback +.Em must never +increase +.Fa id_len +or write to the location +.Fa id +exceeding the given limit. +.Pp +The location +.Fa id +is filled with 0x00 before the callback is called, +so the callback may only fill part of the possible length and leave +.Fa id_len +untouched while maintaining reproducibility. +.Pp +Since the sessions must be distinguished, session ids must be unique. +Without the callback a random number is used, +so that the probability of generating the same session id is extremely small +(2^256 for TLSv1). +In order to ensure the uniqueness of the generated session id, +the callback must call +.Fn SSL_has_matching_session_id +and generate another id if a conflict occurs. +If an id conflict is not resolved, the handshake will fail. +If the application codes, e.g., a unique host id, a unique process number, and +a unique sequence number into the session id, uniqueness could easily be +achieved without randomness added (it should however be taken care that +no confidential information is leaked this way). +If the application cannot guarantee uniqueness, +it is recommended to use the maximum +.Fa id_len +and fill in the bytes not used to code special information with random data to +avoid collisions. +.Pp +.Fn SSL_has_matching_session_id +will only query the internal session cache, not the external one. +Since the session id is generated before the handshake is completed, +it is not immediately added to the cache. +If another thread is using the same internal session cache, +a race condition can occur in that another thread generates the same session id. +Collisions can also occur when using an external session cache, +since the external cache is not tested with +.Fn SSL_has_matching_session_id +and the same race condition applies. +.Pp +The callback must return 0 if it cannot generate a session id for whatever +reason and return 1 on success. +.Sh RETURN VALUES +.Fn SSL_CTX_set_generate_session_id +and +.Fn SSL_set_generate_session_id +always return 1. +.Pp +.Fn SSL_has_matching_session_id +returns 1 if another session with the same id is already in the cache. +.Sh EXAMPLES +The callback function listed will generate a session id with the server id +given, and will fill the rest with pseudo random bytes: +.Bd -literal +const char session_id_prefix = "www-18"; + +#define MAX_SESSION_ID_ATTEMPTS 10 +static int +generate_session_id(const SSL *ssl, unsigned char *id, + unsigned int *id_len) +{ + unsigned int count = 0; + + do { + RAND_pseudo_bytes(id, *id_len); + /* + * Prefix the session_id with the required prefix. NB: If + * our prefix is too long, clip it \(en but there will be + * worse effects anyway, e.g., the server could only + * possibly create one session ID (the prefix!) so all + * future session negotiations will fail due to conflicts. + */ + memcpy(id, session_id_prefix, + (strlen(session_id_prefix) < *id_len) ? + strlen(session_id_prefix) : *id_len); + } while (SSL_has_matching_session_id(ssl, id, *id_len) && + (++count < MAX_SESSION_ID_ATTEMPTS)); + + if (count >= MAX_SESSION_ID_ATTEMPTS) + return 0; + return 1; +} +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_version 3 +.Sh HISTORY +.Fn SSL_CTX_set_generate_session_id , +.Fn SSL_set_generate_session_id +and +.Fn SSL_has_matching_session_id +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/SSL_CTX_set_info_callback.3 b/Libraries/libressl/man/SSL_CTX_set_info_callback.3 new file mode 100644 index 000000000..76eb8bee6 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_info_callback.3 @@ -0,0 +1,233 @@ +.\" $OpenBSD: SSL_CTX_set_info_callback.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_SET_INFO_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_info_callback , +.Nm SSL_CTX_get_info_callback , +.Nm SSL_set_info_callback , +.Nm SSL_get_info_callback +.Nd handle information callback for SSL connections +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_info_callback +.Fa "SSL_CTX *ctx" +.Fa "void (*callback)(const SSL *ssl, int where, int ret)" +.Fc +.Ft void +.Fo "(*SSL_CTX_get_info_callback(const SSL_CTX *ctx))" +.Fa "const SSL *ssl" +.Fa "int where" +.Fa "int ret" +.Fc +.Ft void +.Fo SSL_set_info_callback +.Fa "SSL *ssl" +.Fa "void (*callback)(const SSL *ssl, int where, int ret)" +.Fc +.Ft void +.Fo "(*SSL_get_info_callback(const SSL *ssl))" +.Fa "const SSL *ssl" +.Fa "int where" +.Fa "int ret" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_info_callback +sets the +.Fa callback +function that can be used to obtain state information for SSL objects created +from +.Fa ctx +during connection setup and use. +The setting for +.Fa ctx +is overridden from the setting for a specific SSL object, if specified. +When +.Fa callback +is +.Dv NULL , +no callback function is used. +.Pp +.Fn SSL_set_info_callback +sets the +.Fa callback +function that can be used to +obtain state information for +.Fa ssl +during connection setup and use. +When +.Fa callback +is +.Dv NULL , +the callback setting currently valid for +.Fa ctx +is used. +.Pp +.Fn SSL_CTX_get_info_callback +returns a pointer to the currently set information callback function for +.Fa ctx . +.Pp +.Fn SSL_get_info_callback +returns a pointer to the currently set information callback function for +.Fa ssl . +.Pp +When setting up a connection and during use, +it is possible to obtain state information from the SSL/TLS engine. +When set, an information callback function is called whenever the state changes, +an alert appears, or an error occurs. +.Pp +The callback function is called as +.Fn callback "SSL *ssl" "int where" "int ret" . +The +.Fa where +argument specifies information about where (in which context) +the callback function was called. +If +.Fa ret +is 0, an error condition occurred. +If an alert is handled, +.Dv SSL_CB_ALERT +is set and +.Fa ret +specifies the alert information. +.Pp +.Fa where +is a bitmask made up of the following bits: +.Bl -tag -width Ds +.It Dv SSL_CB_LOOP +Callback has been called to indicate state change inside a loop. +.It Dv SSL_CB_EXIT +Callback has been called to indicate error exit of a handshake function. +(May be soft error with retry option for non-blocking setups.) +.It Dv SSL_CB_READ +Callback has been called during read operation. +.It Dv SSL_CB_WRITE +Callback has been called during write operation. +.It Dv SSL_CB_ALERT +Callback has been called due to an alert being sent or received. +.It Dv SSL_CB_READ_ALERT +.It Dv SSL_CB_WRITE_ALERT +.It Dv SSL_CB_ACCEPT_LOOP +.It Dv SSL_CB_ACCEPT_EXIT +.It Dv SSL_CB_CONNECT_LOOP +.It Dv SSL_CB_CONNECT_EXIT +.It Dv SSL_CB_HANDSHAKE_START +Callback has been called because a new handshake is started. +.It Dv SSL_CB_HANDSHAKE_DONE +Callback has been called because a handshake is finished. +.El +.Pp +The current state information can be obtained using the +.Xr SSL_state_string 3 +family of functions. +.Pp +The +.Fa ret +information can be evaluated using the +.Xr SSL_alert_type_string 3 +family of functions. +.Sh RETURN VALUES +.Fn SSL_CTX_get_info_callback +and +.Fn SSL_get_info_callback +return a pointer to the current callback or +.Dv NULL +if none is set. +.Sh EXAMPLES +The following example callback function prints state strings, +information about alerts being handled and error messages to the +.Va bio_err +.Vt BIO . +.Bd -literal +void +apps_ssl_info_callback(SSL *s, int where, int ret) +{ + const char *str; + int w; + + w = where & ~SSL_ST_MASK; + + if (w & SSL_ST_CONNECT) + str = "SSL_connect"; + else if (w & SSL_ST_ACCEPT) + str = "SSL_accept"; + else + str = "undefined"; + + if (where & SSL_CB_LOOP) { + BIO_printf(bio_err, "%s:%s\en", str, + SSL_state_string_long(s)); + } else if (where & SSL_CB_ALERT) { + str = (where & SSL_CB_READ) ? "read" : "write"; + BIO_printf(bio_err, "SSL3 alert %s:%s:%s\en", str, + SSL_alert_type_string_long(ret), + SSL_alert_desc_string_long(ret)); + } else if (where & SSL_CB_EXIT) { + if (ret == 0) + BIO_printf(bio_err, "%s:failed in %s\en", + str, SSL_state_string_long(s)); + else if (ret < 0) { + BIO_printf(bio_err, "%s:error in %s\en", + str, SSL_state_string_long(s)); + } + } +} +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_alert_type_string 3 , +.Xr SSL_state_string 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.6.0 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_set_keylog_callback.3 b/Libraries/libressl/man/SSL_CTX_set_keylog_callback.3 new file mode 100644 index 000000000..04c94fa83 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_keylog_callback.3 @@ -0,0 +1,56 @@ +.\" $OpenBSD: SSL_CTX_set_keylog_callback.3,v 1.2 2021/10/23 13:17:03 schwarze Exp $ +.\" OpenSSL pod checked up to: 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" Copyright (c) 2021 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 23 2021 $ +.Dt SSL_CTX_SET_KEYLOG_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_keylog_callback , +.Nm SSL_CTX_get_keylog_callback +.Nd set and get the unused key logging callback +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft typedef void +.Fo (*SSL_CTX_keylog_cb_func) +.Fa "const SSL *ssl" +.Fa "const char *line" +.Fc +.Ft void +.Fn SSL_CTX_set_keylog_callback "SSL_CTX *ctx" "SSL_CTX_keylog_cb_func cb" +.Ft SSL_CTX_keylog_cb_func +.Fn SSL_CTX_get_keylog_callback "const SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_keylog_callback +sets the TLS key logging callback. +This callback is never called in LibreSSL. +.Pp +.Fn SSL_CTX_set_keylog_callback +retrieves the previously set TLS key logging callback. +.Pp +These functions are provided only for compatibility with OpenSSL. +.Sh RETURN VALUES +.Fn SSL_CTX_get_keylog_callback +returns the previously set TLS key logging callback, or +.Dv NULL +if no callback has been set. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_new 3 +.Sh HISTORY +These function first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/SSL_CTX_set_max_cert_list.3 b/Libraries/libressl/man/SSL_CTX_set_max_cert_list.3 new file mode 100644 index 000000000..89513b100 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_max_cert_list.3 @@ -0,0 +1,154 @@ +.\" $OpenBSD: SSL_CTX_set_max_cert_list.3,v 1.6 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_CTX_SET_MAX_CERT_LIST 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_max_cert_list , +.Nm SSL_CTX_get_max_cert_list , +.Nm SSL_set_max_cert_list , +.Nm SSL_get_max_cert_list +.Nd manipulate allowed size for the peer's certificate chain +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_set_max_cert_list "SSL_CTX *ctx" "long size" +.Ft long +.Fn SSL_CTX_get_max_cert_list "SSL_CTX *ctx" +.Ft long +.Fn SSL_set_max_cert_list "SSL *ssl" "long size" +.Ft long +.Fn SSL_get_max_cert_list "SSL *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_max_cert_list +sets the maximum size allowed for the peer's certificate chain for all +.Vt SSL +objects created from +.Fa ctx +to be +.Fa size +bytes. +The +.Vt SSL +objects inherit the setting valid for +.Fa ctx +at the time +.Xr SSL_new 3 +is being called. +.Pp +.Fn SSL_CTX_get_max_cert_list +returns the currently set maximum size for +.Fa ctx . +.Pp +.Fn SSL_set_max_cert_list +sets the maximum size allowed for the peer's certificate chain for +.Fa ssl +to be +.Fa size +bytes. +This setting stays valid until a new value is set. +.Pp +.Fn SSL_get_max_cert_list +returns the currently set maximum size for +.Fa ssl . +.Pp +During the handshake process, the peer may send a certificate chain. +The TLS/SSL standard does not give any maximum size of the certificate chain. +The OpenSSL library handles incoming data by a dynamically allocated buffer. +In order to prevent this buffer from growing without bound due to data +received from a faulty or malicious peer, a maximum size for the certificate +chain is set. +.Pp +The default value for the maximum certificate chain size is 100kB (30kB +on the 16bit DOS platform). +This should be sufficient for usual certificate chains +(OpenSSL's default maximum chain length is 10, see +.Xr SSL_CTX_set_verify 3 , +and certificates without special extensions have a typical size of 1-2kB). +.Pp +For special applications it can be necessary to extend the maximum certificate +chain size allowed to be sent by the peer. +See for example the work on +.%T "Internet X.509 Public Key Infrastructure Proxy Certificate Profile" +and +.%T "TLS Delegation Protocol" +at +.Lk https://www.ietf.org/ +and +.Lk http://www.globus.org/ . +.Pp +Under normal conditions it should never be necessary to set a value smaller +than the default, as the buffer is handled dynamically and only uses the +memory actually required by the data sent by the peer. +.Pp +If the maximum certificate chain size allowed is exceeded, the handshake will +fail with a +.Dv SSL_R_EXCESSIVE_MESSAGE_SIZE +error. +.Sh RETURN VALUES +.Fn SSL_CTX_set_max_cert_list +and +.Fn SSL_set_max_cert_list +return the previously set value. +.Pp +.Fn SSL_CTX_get_max_cert_list +and +.Fn SSL_get_max_cert_list +return the currently set value. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr SSL_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/SSL_CTX_set_min_proto_version.3 b/Libraries/libressl/man/SSL_CTX_set_min_proto_version.3 new file mode 100644 index 000000000..a2597cda8 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_min_proto_version.3 @@ -0,0 +1,156 @@ +.\" $OpenBSD: SSL_CTX_set_min_proto_version.3,v 1.5 2021/04/15 16:40:32 tb Exp $ +.\" full merge up to: OpenSSL 3edabd3c Sep 14 09:28:39 2017 +0200 +.\" +.\" This file was written by Kurt Roeckx and +.\" Christian Heimes . +.\" Copyright (c) 2015, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 15 2021 $ +.Dt SSL_CTX_SET_MIN_PROTO_VERSION 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_min_proto_version , +.Nm SSL_CTX_set_max_proto_version , +.Nm SSL_CTX_get_min_proto_version , +.Nm SSL_CTX_get_max_proto_version , +.Nm SSL_set_min_proto_version , +.Nm SSL_set_max_proto_version , +.Nm SSL_get_min_proto_version , +.Nm SSL_get_max_proto_version +.Nd get and set minimum and maximum supported protocol version +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_set_min_proto_version +.Fa "SSL_CTX *ctx" +.Fa "uint16_t version" +.Fc +.Ft int +.Fo SSL_CTX_set_max_proto_version +.Fa "SSL_CTX *ctx" +.Fa "uint16_t version" +.Fc +.Ft int +.Fo SSL_CTX_get_min_proto_version +.Fa "SSL_CTX *ctx" +.Fc +.Ft int +.Fo SSL_CTX_get_max_proto_version +.Fa "SSL_CTX *ctx" +.Fc +.Ft int +.Fo SSL_set_min_proto_version +.Fa "SSL *ssl" +.Fa "uint16_t version" +.Fc +.Ft int +.Fo SSL_set_max_proto_version +.Fa "SSL *ssl" +.Fa "uint16_t version" +.Fc +.Ft int +.Fo SSL_get_min_proto_version +.Fa "SSL *ssl" +.Fc +.Ft int +.Fo SSL_get_max_proto_version +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +These functions get or set the minimum and maximum supported protocol +versions for +.Fa ctx +or +.Fa ssl . +This works in combination with the options set via +.Xr SSL_CTX_set_options 3 +that also make it possible to disable specific protocol versions. +Use these functions instead of disabling specific protocol versions. +.Pp +Setting the minimum or maximum version to 0 will enable protocol +versions down to the lowest or up to the highest version supported +by the library, respectively. +.Pp +Currently supported versions are +.Dv TLS1_VERSION , +.Dv TLS1_1_VERSION , +and +.Dv TLS1_2_VERSION +for TLS and +.Dv DTLS1_VERSION +and +.Dv DTLS1_2_VERSION +for DTLS. +.Pp +In other implementations, these functions may be implemented as macros. +.Sh RETURN VALUES +The setter functions return 1 on success or 0 on failure. +.Pp +The getter functions return the configured version or 0 if +.Fa ctx +or +.Fa ssl +has been configured to automatically use the lowest or highest +version supported by the library. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_set_options 3 +.Sh HISTORY +The setter functions first appeared in BoringSSL in December 2014, +with shorter names without the +.Sy proto_ +part. +Two years later, OpenSSL included them in their 1.1.0 release, +gratuitously changing the names; Google shrugged and adopted +the longer names one month later. +They have been available since +.Ox 6.2 . +.Pp +The getter functions first appeared in OpenSSL 1.1.0g +and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_CTX_set_mode.3 b/Libraries/libressl/man/SSL_CTX_set_mode.3 new file mode 100644 index 000000000..fca1a977d --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_mode.3 @@ -0,0 +1,204 @@ +.\" $OpenBSD: SSL_CTX_set_mode.3,v 1.7 2020/10/08 16:02:38 tb Exp $ +.\" full merge up to: OpenSSL 8671b898 Jun 3 02:48:34 2008 +0000 +.\" selective merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Lutz Jaenicke and +.\" Ben Laurie . +.\" Copyright (c) 2001, 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 8 2020 $ +.Dt SSL_CTX_SET_MODE 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_mode , +.Nm SSL_set_mode , +.Nm SSL_CTX_clear_mode , +.Nm SSL_clear_mode , +.Nm SSL_CTX_get_mode , +.Nm SSL_get_mode +.Nd manipulate SSL engine mode +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_set_mode "SSL_CTX *ctx" "long mode" +.Ft long +.Fn SSL_set_mode "SSL *ssl" "long mode" +.Ft long +.Fn SSL_CTX_clear_mode "SSL_CTX *ctx" "long mode" +.Ft long +.Fn SSL_clear_mode "SSL *ssl" "long mode" +.Ft long +.Fn SSL_CTX_get_mode "SSL_CTX *ctx" +.Ft long +.Fn SSL_get_mode "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_CTX_set_mode +and +.Fn SSL_set_mode +enable the options contained in the bitmask +.Fa mode +for the +.Fa ctx +or +.Fa ssl +object, respectively. +Options that were already enabled before the call are not disabled. +.Pp +.Fn SSL_CTX_clear_mode +and +.Fn SSL_clear_mode +disable the options contained in the bitmask +.Fa mode +for the +.Fa ctx +or +.Fa ssl +object. +.Pp +.Fn SSL_CTX_get_mode +and +.Fn SSL_get_mode +return a bitmask representing the options +that are currently enabled for the +.Fa ctx +or +.Fa ssl +object. +.Pp +The following options are available: +.Bl -tag -width Ds +.It Dv SSL_MODE_ENABLE_PARTIAL_WRITE +Allow +.Fn SSL_write ... n +to return +.Ms r +with +.EQ +0 < r < n +.EN +(i.e., report success when just a single record has been written). +When not set (the default), +.Xr SSL_write 3 +will only report success once the complete chunk was written. +Once +.Xr SSL_write 3 +returns with +.Ms r , +.Ms r +bytes have been successfully written and the next call to +.Xr SSL_write 3 +must only send the +.Ms n \(mi r +bytes left, imitating the behaviour of +.Xr write 2 . +.It Dv SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER +Make it possible to retry +.Xr SSL_write 3 +with changed buffer location (the buffer contents must stay the same). +This is not the default to avoid the misconception that non-blocking +.Xr SSL_write 3 +behaves like non-blocking +.Xr write 2 . +.It Dv SSL_MODE_AUTO_RETRY +Never bother the application with retries if the transport is blocking. +If a renegotiation takes place during normal operation, a +.Xr SSL_read 3 +or +.Xr SSL_write 3 +would return +with \(mi1 and indicate the need to retry with +.Dv SSL_ERROR_WANT_READ . +In a non-blocking environment applications must be prepared to handle +incomplete read/write operations. +In a blocking environment, applications are not always prepared to deal with +read/write operations returning without success report. +The flag +.Dv SSL_MODE_AUTO_RETRY +will cause read/write operations to only return after the handshake and +successful completion. +.It Dv SSL_MODE_RELEASE_BUFFERS +When we no longer need a read buffer or a write buffer for a given +.Vt SSL , +then release the memory we were using to hold it. +Using this flag can save around 34k per idle SSL connection. +This flag has no effect on SSL v2 connections, or on DTLS connections. +.El +.Sh RETURN VALUES +.Fn SSL_CTX_set_mode , +.Fn SSL_set_mode , +.Fn SSL_CTX_clear_mode , +and +.Fn SSL_clear_mode +return the new mode bitmask after adding or clearing +.Fa mode . +.Pp +.Fn SSL_CTX_get_mode +and +.Fn SSL_get_mode +return the current bitmask. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_read 3 , +.Xr SSL_write 3 +.Sh HISTORY +.Fn SSL_CTX_set_mode , +.Fn SSL_set_mode , +.Fn SSL_CTX_get_mode , +and +.Fn SSL_get_mode +first appeared in OpenSSL 0.9.4 and have been available since +.Ox 2.6 . +.Pp +.Fn SSL_CTX_clear_mode +and +.Fn SSL_clear_mode +first appeared in OpenSSL 0.9.8m and have been available since +.Ox 4.9 . +.Pp +.Dv SSL_MODE_AUTO_RETRY +was added in OpenSSL 0.9.6. diff --git a/Libraries/libressl/man/SSL_CTX_set_msg_callback.3 b/Libraries/libressl/man/SSL_CTX_set_msg_callback.3 new file mode 100644 index 000000000..a27333e6d --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_msg_callback.3 @@ -0,0 +1,183 @@ +.\" $OpenBSD: SSL_CTX_set_msg_callback.3,v 1.5 2021/04/15 16:43:27 tb Exp $ +.\" OpenSSL SSL_CTX_set_msg_callback.pod e9b77246 Jan 20 19:58:49 2017 +0100 +.\" OpenSSL SSL_CTX_set_msg_callback.pod b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Bodo Moeller . +.\" Copyright (c) 2001, 2014, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 15 2021 $ +.Dt SSL_CTX_SET_MSG_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_msg_callback , +.Nm SSL_CTX_set_msg_callback_arg , +.Nm SSL_set_msg_callback , +.Nm SSL_set_msg_callback_arg +.Nd install callback for observing protocol messages +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_msg_callback +.Fa "SSL_CTX *ctx" +.Fa "void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)" +.Fc +.Ft void +.Fn SSL_CTX_set_msg_callback_arg "SSL_CTX *ctx" "void *arg" +.Ft void +.Fo SSL_set_msg_callback +.Fa "SSL *ssl" +.Fa "void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)" +.Fc +.Ft void +.Fn SSL_set_msg_callback_arg "SSL *ssl" "void *arg" +.Sh DESCRIPTION +.Fn SSL_CTX_set_msg_callback +or +.Fn SSL_set_msg_callback +can be used to define a message callback function +.Fa cb +for observing all SSL/TLS protocol messages (such as handshake messages) +that are received or sent. +.Fn SSL_CTX_set_msg_callback_arg +and +.Fn SSL_set_msg_callback_arg +can be used to set argument +.Fa arg +to the callback function, which is available for arbitrary application use. +.Pp +.Fn SSL_CTX_set_msg_callback +and +.Fn SSL_CTX_set_msg_callback_arg +specify default settings that will be copied to new +.Vt SSL +objects by +.Xr SSL_new 3 . +.Fn SSL_set_msg_callback +and +.Fn SSL_set_msg_callback_arg +modify the actual settings of an +.Vt SSL +object. +Using a +.Dv NULL +pointer for +.Fa cb +disables the message callback. +.Pp +When +.Fa cb +is called by the SSL/TLS library for a protocol message, +the function arguments have the following meaning: +.Bl -tag -width Ds +.It Fa write_p +This flag is 0 when a protocol message has been received and 1 when a protocol +message has been sent. +.It Fa version +The protocol version according to which the protocol message is +interpreted by the library, such as +.Dv TLS1_VERSION , +.Dv TLS1_1_VERSION , +.Dv TLS1_2_VERSION , +.Dv DTLS1_VERSION , +or +.Dv DTLS1_2_VERSION . +.It Fa content_type +This is one of the +.Em ContentType +values defined in the protocol specification +.Po +.Dv SSL3_RT_CHANGE_CIPHER_SPEC , +.Dv SSL3_RT_ALERT , +.Dv SSL3_RT_HANDSHAKE , +but never +.Dv SSL3_RT_APPLICATION_DATA +because the callback will only be called for protocol messages. +.Pc +.It Fa buf , Fa len +.Fa buf +points to a buffer containing the protocol message, which consists of +.Fa len +bytes. +The buffer is no longer valid after the callback function has returned. +.It Fa ssl +The +.Vt SSL +object that received or sent the message. +.It Fa arg +The user-defined argument optionally defined by +.Fn SSL_CTX_set_msg_callback_arg +or +.Fn SSL_set_msg_callback_arg . +.El +.Pp +Protocol messages are passed to the callback function after decryption +and fragment collection where applicable. +(Thus record boundaries are not visible.) +.Pp +If processing a received protocol message results in an error, +the callback function may not be called. +For example, the callback function will never see messages that are considered +too large to be processed. +.Pp +Due to automatic protocol version negotiation, +.Fa version +is not necessarily the protocol version used by the sender of the message: +If a TLS 1.0 ClientHello message is received by an SSL 3.0-only server, +.Fa version +will be +.Dv SSL3_VERSION . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_new 3 +.Sh HISTORY +.Fn SSL_CTX_set_msg_callback , +.Fn SSL_CTX_set_msg_callback_arg , +.Fn SSL_set_msg_callback +and +.Fn SSL_set_msg_callback_arg +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/SSL_CTX_set_num_tickets.3 b/Libraries/libressl/man/SSL_CTX_set_num_tickets.3 new file mode 100644 index 000000000..cb6d7e000 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_num_tickets.3 @@ -0,0 +1,63 @@ +.\" $OpenBSD: SSL_CTX_set_num_tickets.3,v 1.2 2021/10/23 17:20:50 schwarze Exp $ +.\" OpenSSL pod checked up to: 5402f96a Sep 11 09:58:52 2021 +0100 +.\" +.\" Copyright (c) 2021 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 23 2021 $ +.Dt SSL_CTX_SET_NUM_TICKETS 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_num_tickets , +.Nm SSL_CTX_get_num_tickets , +.Nm SSL_set_num_tickets , +.Nm SSL_get_num_tickets +.Nd set and get the number of TLS 1.3 session tickets to be sent +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_CTX_set_num_tickets "SSL_CTX *ctx" "size_t num_tickets" +.Ft size_t +.Fn SSL_CTX_get_num_tickets "const SSL_CTX *ctx" +.Ft int +.Fn SSL_set_num_tickets "SSL *ssl" "size_t num_tickets" +.Ft size_t +.Fn SSL_get_num_tickets "const SSL *ssl" +.Sh DESCRIPTION +These functions set and retrieve +the configured number of session tickets for +.Fa ctx +and +.Fa ssl , +respectively. +.Pp +They are provided only for compatibility with OpenSSL +and have no effect in LibreSSL. +.Sh RETURN VALUES +.Fn SSL_CTX_set_num_tickets +and +.Fn SSL_set_num_tickets +always return 1. +.Pp +.Fn SSL_CTX_get_num_tickets +and +.Fn SSL_get_num_tickets +return the previously set number of tickets, or 0 if it has not been set. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_new 3 +.Sh HISTORY +These function first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/SSL_CTX_set_options.3 b/Libraries/libressl/man/SSL_CTX_set_options.3 new file mode 100644 index 000000000..5df0b0778 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_options.3 @@ -0,0 +1,374 @@ +.\" $OpenBSD: SSL_CTX_set_options.3,v 1.16 2022/03/31 17:27:18 naddy Exp $ +.\" full merge up to: OpenSSL 7946ab33 Dec 6 17:56:41 2015 +0100 +.\" selective merge up to: OpenSSL edb79c3a Mar 29 10:07:14 2017 +1000 +.\" +.\" This file was written by Lutz Jaenicke , +.\" Bodo Moeller , and +.\" Dr. Stephen Henson . +.\" Copyright (c) 2001-2003, 2005, 2007, 2009, 2010, 2013-2015 +.\" The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt SSL_CTX_SET_OPTIONS 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_options , +.Nm SSL_set_options , +.Nm SSL_CTX_clear_options , +.Nm SSL_clear_options , +.Nm SSL_CTX_get_options , +.Nm SSL_get_options , +.Nm SSL_get_secure_renegotiation_support +.Nd manipulate SSL options +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_set_options "SSL_CTX *ctx" "long options" +.Ft long +.Fn SSL_set_options "SSL *ssl" "long options" +.Ft long +.Fn SSL_CTX_clear_options "SSL_CTX *ctx" "long options" +.Ft long +.Fn SSL_clear_options "SSL *ssl" "long options" +.Ft long +.Fn SSL_CTX_get_options "SSL_CTX *ctx" +.Ft long +.Fn SSL_get_options "SSL *ssl" +.Ft long +.Fn SSL_get_secure_renegotiation_support "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_CTX_set_options +adds the options set via bitmask in +.Fa options +to +.Fa ctx . +Options already set before are not cleared! +.Pp +.Fn SSL_set_options +adds the options set via bitmask in +.Fa options +to +.Fa ssl . +Options already set before are not cleared! +.Pp +.Fn SSL_CTX_clear_options +clears the options set via bitmask in +.Fa options +to +.Fa ctx . +.Pp +.Fn SSL_clear_options +clears the options set via bitmask in +.Fa options +to +.Fa ssl . +.Pp +.Fn SSL_CTX_get_options +returns the options set for +.Fa ctx . +.Pp +.Fn SSL_get_options +returns the options set for +.Fa ssl . +.Pp +.Fn SSL_get_secure_renegotiation_support +indicates whether the peer supports secure renegotiation. +.Pp +All these functions are implemented using macros. +.Pp +The behaviour of the SSL library can be changed by setting several options. +The options are coded as bitmasks and can be combined by a bitwise OR +operation (|). +.Pp +.Fn SSL_CTX_set_options +and +.Fn SSL_set_options +affect the (external) protocol behaviour of the SSL library. +The (internal) behaviour of the API can be changed by using the similar +.Xr SSL_CTX_set_mode 3 +and +.Xr SSL_set_mode 3 +functions. +.Pp +During a handshake, the option settings of the SSL object are used. +When a new SSL object is created from a context using +.Xr SSL_new 3 , +the current option setting is copied. +Changes to +.Fa ctx +do not affect already created +.Vt SSL +objects. +.Fn SSL_clear +does not affect the settings. +.Pp +The following +.Em bug workaround +options are available: +.Bl -tag -width Ds +.It Dv SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS +Disables a countermeasure against a TLS 1.0 protocol vulnerability +affecting CBC ciphers, which cannot be handled by some broken SSL +implementations. +This option has no effect for connections using other ciphers. +.It Dv SSL_OP_ALL +This is currently an alias for +.Dv SSL_OP_LEGACY_SERVER_CONNECT . +.El +.Pp +It is usually safe to use +.Dv SSL_OP_ALL +to enable the bug workaround options if compatibility with somewhat broken +implementations is desired. +.Pp +The following +.Em modifying +options are available: +.Bl -tag -width Ds +.It Dv SSL_OP_CIPHER_SERVER_PREFERENCE +When choosing a cipher, use the server's preferences instead of the client +preferences. +When not set, the server will always follow the client's preferences. +When set, the server will choose following its own preferences. +.It Dv SSL_OP_COOKIE_EXCHANGE +Turn on Cookie Exchange as described in RFC 4347 Section 4.2.1. +Only affects DTLS connections. +.It Dv SSL_OP_LEGACY_SERVER_CONNECT +Allow legacy insecure renegotiation between OpenSSL and unpatched servers +.Em only : +this option is currently set by default. +See the +.Sx SECURE RENEGOTIATION +section for more details. +.It Dv SSL_OP_NO_DTLSv1 +Do not use the DTLSv1 protocol. +Deprecated; use +.Xr SSL_CTX_set_min_proto_version 3 +instead. +.It Dv SSL_OP_NO_DTLSv1_2 +Do not use the DTLSv1.2 protocol. +Deprecated; use +.Xr SSL_CTX_set_min_proto_version 3 +instead. +.It Dv SSL_OP_NO_QUERY_MTU +Do not query the MTU. +Only affects DTLS connections. +.It Dv SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION +When performing renegotiation as a server, always start a new session (i.e., +session resumption requests are only accepted in the initial handshake). +This option is not needed for clients. +.It Dv SSL_OP_NO_TICKET +Normally clients and servers using TLSv1.2 and earlier will, where possible, +transparently make use of +RFC 5077 tickets for stateless session resumption. +.Pp +If this option is set, this functionality is disabled and tickets will not be +used by clients or servers. +.It Dv SSL_OP_NO_TLSv1 +Do not use the TLSv1.0 protocol. +Deprecated; use +.Xr SSL_CTX_set_min_proto_version 3 +instead. +.It Dv SSL_OP_NO_TLSv1_1 +Do not use the TLSv1.1 protocol. +Deprecated; use +.Xr SSL_CTX_set_min_proto_version 3 +instead. +.It Dv SSL_OP_NO_TLSv1_2 +Do not use the TLSv1.2 protocol. +Deprecated; use +.Xr SSL_CTX_set_max_proto_version 3 +instead. +.El +.Pp +The following options used to be supported at some point in the past +and no longer have any effect: +.Dv SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION , +.Dv SSL_OP_EPHEMERAL_RSA , +.Dv SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER , +.Dv SSL_OP_MICROSOFT_SESS_ID_BUG , +.Dv SSL_OP_NETSCAPE_CA_DN_BUG , +.Dv SSL_OP_NETSCAPE_CHALLENGE_BUG , +.Dv SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG , +.Dv SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG , +.Dv SSL_OP_NO_COMPRESSION , +.Dv SSL_OP_NO_SSLv2 , +.Dv SSL_OP_NO_SSLv3 , +.Dv SSL_OP_PKCS1_CHECK_1 , +.Dv SSL_OP_PKCS1_CHECK_2 , +.Dv SSL_OP_SAFARI_ECDHE_ECDSA_BUG , +.Dv SSL_OP_SINGLE_DH_USE , +.Dv SSL_OP_SINGLE_ECDH_USE , +.Dv SSL_OP_SSLEAY_080_CLIENT_DH_BUG , +.Dv SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG , +.Dv SSL_OP_TLS_BLOCK_PADDING_BUG , +.Dv SSL_OP_TLS_D5_BUG , +.Dv SSL_OP_TLS_ROLLBACK_BUG , +.Dv SSL_OP_TLSEXT_PADDING . +.Sh SECURE RENEGOTIATION +OpenSSL 0.9.8m and later always attempts to use secure renegotiation as +described in RFC 5746. +This counters the prefix attack described in CVE-2009-3555 and elsewhere. +.Pp +This attack has far-reaching consequences which application writers should be +aware of. +In the description below an implementation supporting secure renegotiation is +referred to as +.Dq patched . +A server not supporting secure +renegotiation is referred to as +.Dq unpatched . +.Pp +The following sections describe the operations permitted by OpenSSL's secure +renegotiation implementation. +.Ss Patched client and server +Connections and renegotiation are always permitted by OpenSSL implementations. +.Ss Unpatched client and patched OpenSSL server +The initial connection succeeds but client renegotiation is denied by the +server with a +.Em no_renegotiation +warning alert. +.Pp +If the patched OpenSSL server attempts to renegotiate, a fatal +.Em handshake_failure +alert is sent. +This is because the server code may be unaware of the unpatched nature of the +client. +.Pp +Note that a bug in OpenSSL clients earlier than 0.9.8m (all of which +are unpatched) will result in the connection hanging if it receives a +.Em no_renegotiation +alert. +OpenSSL versions 0.9.8m and later will regard a +.Em no_renegotiation +alert as fatal and respond with a fatal +.Em handshake_failure +alert. +This is because the OpenSSL API currently has no provision to indicate to an +application that a renegotiation attempt was refused. +.Ss Patched OpenSSL client and unpatched server +If the option +.Dv SSL_OP_LEGACY_SERVER_CONNECT +is set then initial connections and renegotiation between patched OpenSSL +clients and unpatched servers succeeds. +If neither option is set then initial connections to unpatched servers will +fail. +.Pp +The option +.Dv SSL_OP_LEGACY_SERVER_CONNECT +is currently set by default even though it has security implications: +otherwise it would be impossible to connect to unpatched servers (i.e., all of +them initially) and this is clearly not acceptable. +Renegotiation is permitted because this does not add any additional security +issues: during an attack clients do not see any renegotiations anyway. +.Pp +As more servers become patched, the option +.Dv SSL_OP_LEGACY_SERVER_CONNECT +will +.Em not +be set by default in a future version of OpenSSL. +.Pp +OpenSSL client applications wishing to ensure they can connect to unpatched +servers should always +.Em set +.Dv SSL_OP_LEGACY_SERVER_CONNECT . +.Pp +OpenSSL client applications that want to ensure they can +.Em not +connect to unpatched servers (and thus avoid any security issues) should always +.Em clear +.Dv SSL_OP_LEGACY_SERVER_CONNECT +using +.Fn SSL_CTX_clear_options +or +.Fn SSL_clear_options . +.Sh RETURN VALUES +.Fn SSL_CTX_set_options +and +.Fn SSL_set_options +return the new options bitmask after adding +.Fa options . +.Pp +.Fn SSL_CTX_clear_options +and +.Fn SSL_clear_options +return the new options bitmask after clearing +.Fa options . +.Pp +.Fn SSL_CTX_get_options +and +.Fn SSL_get_options +return the current bitmask. +.Pp +.Fn SSL_get_secure_renegotiation_support +returns 1 is the peer supports secure renegotiation and 0 if it does not. +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_set_min_proto_version 3 , +.Xr SSL_new 3 +.Sh HISTORY +.Fn SSL_CTX_set_options +and +.Fn SSL_set_options +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_get_options +and +.Fn SSL_get_options +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Pp +.Fn SSL_CTX_clear_options , +.Fn SSL_clear_options , +and +.Fn SSL_get_secure_renegotiation_support +first appeared in OpenSSL 0.9.8m and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/SSL_CTX_set_quiet_shutdown.3 b/Libraries/libressl/man/SSL_CTX_set_quiet_shutdown.3 new file mode 100644 index 000000000..71463f1ec --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_quiet_shutdown.3 @@ -0,0 +1,161 @@ +.\" $OpenBSD: SSL_CTX_set_quiet_shutdown.3,v 1.6 2020/03/30 10:28:59 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 30 2020 $ +.Dt SSL_CTX_SET_QUIET_SHUTDOWN 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_quiet_shutdown , +.Nm SSL_CTX_get_quiet_shutdown , +.Nm SSL_set_quiet_shutdown , +.Nm SSL_get_quiet_shutdown +.Nd manipulate shutdown behaviour +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_CTX_set_quiet_shutdown "SSL_CTX *ctx" "int mode" +.Ft int +.Fn SSL_CTX_get_quiet_shutdown "const SSL_CTX *ctx" +.Ft void +.Fn SSL_set_quiet_shutdown "SSL *ssl" "int mode" +.Ft int +.Fn SSL_get_quiet_shutdown "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_CTX_set_quiet_shutdown +sets the +.Dq quiet shutdown +flag for +.Fa ctx +to be +.Fa mode . +.Vt SSL +objects created from +.Fa ctx +inherit the +.Fa mode +valid at the time +.Xr SSL_new 3 +is called. +.Fa mode +may be 0 or 1. +.Pp +.Fn SSL_CTX_get_quiet_shutdown +returns the +.Dq quiet shutdown +setting of +.Fa ctx . +.Pp +.Fn SSL_set_quiet_shutdown +sets the +.Dq quiet shutdown +flag for +.Fa ssl +to be +.Fa mode . +The setting stays valid until +.Fa ssl +is removed with +.Xr SSL_free 3 +or +.Fn SSL_set_quiet_shutdown +is called again. +It is not changed when +.Xr SSL_clear 3 +is called. +.Fa mode +may be 0 or 1. +.Pp +.Fn SSL_get_quiet_shutdown +returns the +.Dq quiet shutdown +setting of +.Fa ssl . +.Pp +Normally when a SSL connection is finished, the parties must send out +.Dq close notify +alert messages using +.Xr SSL_shutdown 3 +for a clean shutdown. +.Pp +When setting the +.Dq quiet shutdown +flag to 1, +.Xr SSL_shutdown 3 +will set the internal flags to +.Dv SSL_SENT_SHUTDOWN Ns | Ns Dv SSL_RECEIVED_SHUTDOWN +.Po +.Xr SSL_shutdown 3 +then behaves like +.Xr SSL_set_shutdown 3 +called with +.Dv SSL_SENT_SHUTDOWN Ns | Ns Dv SSL_RECEIVED_SHUTDOWN +.Pc . +The session is thus considered to be shut down, but no +.Dq close notify +alert is sent to the peer. +This behaviour violates the TLS standard. +.Pp +The default is normal shutdown behaviour as described by the TLS standard. +.Sh RETURN VALUES +.Fn SSL_CTX_get_quiet_shutdown +and +.Fn SSL_get_quiet_shutdown +return the current setting. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_free 3 , +.Xr SSL_new 3 , +.Xr SSL_set_shutdown 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.8.1 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_set_read_ahead.3 b/Libraries/libressl/man/SSL_CTX_set_read_ahead.3 new file mode 100644 index 000000000..eae76eb47 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_read_ahead.3 @@ -0,0 +1,144 @@ +.\" $OpenBSD: SSL_CTX_set_read_ahead.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_SET_READ_AHEAD 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_read_ahead , +.Nm SSL_CTX_get_read_ahead , +.Nm SSL_set_read_ahead , +.Nm SSL_get_read_ahead , +.Nm SSL_CTX_get_default_read_ahead +.Nd manage whether to read as many input bytes as possible +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_read_ahead +.Fa "SSL_CTX *ctx" +.Fa "int yes" +.Fc +.Ft long +.Fo SSL_CTX_get_read_ahead +.Fa "SSL_CTX *ctx" +.Fc +.Ft void +.Fo SSL_set_read_ahead +.Fa "SSL *s" +.Fa "int yes" +.Fc +.Ft long +.Fo SSL_get_read_ahead +.Fa "const SSL *s" +.Fc +.Ft long +.Fo SSL_CTX_get_default_read_ahead +.Fa "SSL_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_read_ahead +and +.Fn SSL_set_read_ahead +set whether as many input bytes as possible are read for non-blocking +reads. +For example if +.Ar x +bytes are currently required by OpenSSL, but +.Ar y +bytes are available from the underlying BIO (where +.Ar y No > Ar x ) , +then OpenSSL will read all +.Ar y +bytes into its buffer (provided that the buffer is large enough) if +reading ahead is on, or +.Ar x +bytes otherwise. +The parameter +.Fa yes +should be 0 to ensure reading ahead is off, or non zero otherwise. +.Pp +.Fn SSL_CTX_get_read_ahead +and +.Fn SSL_get_read_ahead +indicate whether reading ahead is set or not. +.Pp +.Fn SSL_CTX_get_default_read_ahead +is identical to +.Fn SSL_CTX_get_read_ahead . +.Pp +These functions are implemented as macros. +.Pp +These functions have no effect when used with DTLS. +.Sh RETURN VALUES +.Fn SSL_CTX_get_read_ahead +and +.Fn SSL_get_read_ahead +return 0 if reading ahead is off or non-zero otherwise, +except that the return values are undefined for DTLS. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_pending 3 +.Sh HISTORY +.Fn SSL_set_read_ahead +and +.Fn SSL_get_read_ahead +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_set_read_ahead , +.Fn SSL_CTX_get_read_ahead , +and +.Fn SSL_CTX_get_default_read_ahead +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Sh CAVEATS +Switching read ahead on can impact the behaviour of the +.Xr SSL_pending 3 +function. diff --git a/Libraries/libressl/man/SSL_CTX_set_security_level.3 b/Libraries/libressl/man/SSL_CTX_set_security_level.3 new file mode 100644 index 000000000..529352cf0 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_security_level.3 @@ -0,0 +1,159 @@ +.\" $OpenBSD: SSL_CTX_set_security_level.3,v 1.1 2022/07/13 20:52:36 schwarze Exp $ +.\" +.\" Copyright (c) 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt SSL_CTX_SET_SECURITY_LEVEL 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_security_level , +.Nm SSL_set_security_level , +.Nm SSL_CTX_get_security_level , +.Nm SSL_get_security_level +.Nd change security level for TLS +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_security_level +.Fa "SSL_CTX *ctx" +.Fa "int level" +.Fc +.Ft void +.Fo SSL_set_security_level +.Fa "SSL *s" +.Fa "int level" +.Fc +.Ft int +.Fo SSL_CTX_get_security_level +.Fa "const SSL_CTX *ctx" +.Fc +.Ft int +.Fo SSL_get_security_level +.Fa "const SSL *s" +.Fc +.Sh DESCRIPTION +A security level is a set of restrictions on algorithms, key lengths, +protocol versions, and other features in TLS connections. +These restrictions apply in addition to those that exist from individually +selecting supported features, for example ciphers, curves, or algorithms. +.Pp +The following table shows properties of the various security levels: +.Bl -column # sec 15360 ECC TLS SHA1 -offset indent +.It # Ta sec Ta \0\0RSA Ta ECC Ta TLS Ta MAC +.It 0 Ta \0\00 Ta \0\0\0\00 Ta \0\00 Ta 1.0 Ta MD5 +.It 1 Ta \080 Ta \01024 Ta 160 Ta 1.0 Ta RC4 +.It 2 Ta 112 Ta \02048 Ta 224 Ta 1.0 Ta +.It 3 Ta 128 Ta \03072 Ta 256 Ta 1.1 Ta SHA1 +.It 4 Ta 192 Ta \07680 Ta 384 Ta 1.2 Ta +.It 5 Ta 256 Ta 15360 Ta 512 Ta 1.2 Ta +.El +.Pp +The meaning of the columns is as follows: +.Pp +.Bl -tag -width features -compact +.It # +The number of the +.Fa level . +.It sec +The minimum security strength measured in bits, which is approximately +the binary logarithm of the number of operations an attacker has +to perform in order to break a cryptographic key. +This minimum strength is enforced for all relevant parameters +including cipher suite encryption algorithms, ECC curves, signature +algorithms, DH parameter sizes, and certificate algorithms and key +sizes. +See SP800-57 below +.Sx SEE ALSO +for details on individual algorithms. +.It RSA +The minimum key length in bits for the RSA, DSA, and DH algorithms. +.It ECC +The minimum key length in bits for ECC algorithms. +.It TLS +The minimum TLS protocol version. +.It MAC +Cipher suites using the given MACs are allowed on this level +and on lower levels, but not on higher levels. +.El +.Pp +Level 0 is only provided for backward compatibility and permits everything. +.Pp +Level 3 and higher disable support for session tickets +and only accept cipher suites that provide forward secrecy. +.Pp +The functions +.Fn SSL_CTX_set_security_level +and +.Fn SSL_set_security_level +choose the security +.Fa level +for +.Fa ctx +or +.Fa s , +respectively. +If not set, security level 1 is used. +.Pp +.Xr SSL_CTX_new 3 +initializes the security level of the new object to 1. +.Pp +.Xr SSL_new 3 +and +.Xr SSL_set_SSL_CTX 3 +copy the security level from the context to the SSL object. +.Pp +.Xr SSL_dup 3 +copies the security level from the old to the new object. +.Sh RETURN VALUES +.Fn SSL_CTX_get_security_level +and +.Fn SSL_get_security_level +return the security level configured in +.Fa ctx +or +.Fa s , +respectively. +.Sh SEE ALSO +.Xr EVP_PKEY_security_bits 3 , +.Xr RSA_security_bits 3 , +.Xr ssl 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_new 3 +.Rs +.%A Elaine Barker +.%T Recommendation for Key Management +.%I U.S. National Institute of Standards and Technology +.%R NIST Special Publication 800-57 Part 1 Revision 5 +.%U https://doi.org/10.6028/NIST.SP.800-57pt1r5 +.%C Gaithersburg, MD +.%D May 2020 +.Re +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 7.2 . +.Sh CAVEATS +Applications which do not check the return values +of configuration functions will misbehave. +For example, if an application does not check the return value +after trying to set a certificate and the certificate is rejected +because of the security level, the application may behave as if +no certificate had been provided at all. +.Pp +While some restrictions may be handled gracefully by negotiations +between the client and the server, other restrictions may be +fatal and abort the TLS handshake. +For example, this can happen if the peer certificate contains a key +that is too short or if the DH parameter size is too small. diff --git a/Libraries/libressl/man/SSL_CTX_set_session_cache_mode.3 b/Libraries/libressl/man/SSL_CTX_set_session_cache_mode.3 new file mode 100644 index 000000000..1fe67b2a7 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_session_cache_mode.3 @@ -0,0 +1,198 @@ +.\" $OpenBSD: SSL_CTX_set_session_cache_mode.3,v 1.7 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL 67adf0a7 Dec 25 19:58:38 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke and +.\" Geoff Thorpe . +.\" Copyright (c) 2001, 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_CTX_SET_SESSION_CACHE_MODE 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_session_cache_mode , +.Nm SSL_CTX_get_session_cache_mode +.Nd enable/disable session caching +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_set_session_cache_mode "SSL_CTX ctx" "long mode" +.Ft long +.Fn SSL_CTX_get_session_cache_mode "SSL_CTX ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_session_cache_mode +enables/disables session caching by setting the operational mode for +.Ar ctx +to +.Ar mode . +.Pp +.Fn SSL_CTX_get_session_cache_mode +returns the currently used cache mode. +.Pp +The OpenSSL library can store/retrieve SSL/TLS sessions for later reuse. +The sessions can be held in memory for each +.Fa ctx , +if more than one +.Vt SSL_CTX +object is being maintained, the sessions are unique for each +.Vt SSL_CTX +object. +.Pp +In order to reuse a session, a client must send the session's id to the server. +It can only send exactly one id. +The server then either agrees to reuse the session or it starts a full +handshake (to create a new session). +.Pp +A server will look up the session in its internal session storage. +If the session is not found in internal storage or lookups for the internal +storage have been deactivated +.Pq Dv SSL_SESS_CACHE_NO_INTERNAL_LOOKUP , +the server will try the external storage if available. +.Pp +Since a client may try to reuse a session intended for use in a different +context, the session id context must be set by the server (see +.Xr SSL_CTX_set_session_id_context 3 ) . +.Pp +The following session cache modes and modifiers are available: +.Bl -tag -width Ds +.It Dv SSL_SESS_CACHE_OFF +No session caching for client or server takes place. +.It Dv SSL_SESS_CACHE_CLIENT +Client sessions are added to the session cache. +As there is no reliable way for the OpenSSL library to know whether a session +should be reused or which session to choose (due to the abstract BIO layer the +SSL engine does not have details about the connection), +the application must select the session to be reused by using the +.Xr SSL_set_session 3 +function. +This option is not activated by default. +.It Dv SSL_SESS_CACHE_SERVER +Server sessions are added to the session cache. +When a client proposes a session to be reused, the server looks for the +corresponding session in (first) the internal session cache (unless +.Dv SSL_SESS_CACHE_NO_INTERNAL_LOOKUP +is set), then (second) in the external cache if available. +If the session is found, the server will try to reuse the session. +This is the default. +.It Dv SSL_SESS_CACHE_BOTH +Enable both +.Dv SSL_SESS_CACHE_CLIENT +and +.Dv SSL_SESS_CACHE_SERVER +at the same time. +.It Dv SSL_SESS_CACHE_NO_AUTO_CLEAR +Normally the session cache is checked for expired sessions every 255 +connections using the +.Xr SSL_CTX_flush_sessions 3 +function. +Since this may lead to a delay which cannot be controlled, +the automatic flushing may be disabled and +.Xr SSL_CTX_flush_sessions 3 +can be called explicitly by the application. +.It Dv SSL_SESS_CACHE_NO_INTERNAL_LOOKUP +By setting this flag, session-resume operations in an SSL/TLS server will not +automatically look up sessions in the internal cache, +even if sessions are automatically stored there. +If external session caching callbacks are in use, +this flag guarantees that all lookups are directed to the external cache. +As automatic lookup only applies for SSL/TLS servers, +the flag has no effect on clients. +.It Dv SSL_SESS_CACHE_NO_INTERNAL_STORE +Depending on the presence of +.Dv SSL_SESS_CACHE_CLIENT +and/or +.Dv SSL_SESS_CACHE_SERVER , +sessions negotiated in an SSL/TLS handshake may be cached for possible reuse. +Normally a new session is added to the internal cache as well as any external +session caching (callback) that is configured for the +.Vt SSL_CTX . +This flag will prevent sessions being stored in the internal cache +(though the application can add them manually using +.Xr SSL_CTX_add_session 3 ) . +Note: +in any SSL/TLS servers where external caching is configured, any successful +session lookups in the external cache (e.g., for session-resume requests) would +normally be copied into the local cache before processing continues \(en this +flag prevents these additions to the internal cache as well. +.It Dv SSL_SESS_CACHE_NO_INTERNAL +Enable both +.Dv SSL_SESS_CACHE_NO_INTERNAL_LOOKUP +and +.Dv SSL_SESS_CACHE_NO_INTERNAL_STORE +at the same time. +.El +.Pp +The default mode is +.Dv SSL_SESS_CACHE_SERVER . +.Sh RETURN VALUES +.Fn SSL_CTX_set_session_cache_mode +returns the previously set cache mode. +.Pp +.Fn SSL_CTX_get_session_cache_mode +returns the currently set cache mode. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add_session 3 , +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_sess_number 3 , +.Xr SSL_CTX_sess_set_cache_size 3 , +.Xr SSL_CTX_sess_set_get_cb 3 , +.Xr SSL_CTX_set_session_id_context 3 , +.Xr SSL_CTX_set_timeout 3 , +.Xr SSL_session_reused 3 , +.Xr SSL_set_session 3 +.Sh HISTORY +.Fn SSL_CTX_set_session_cache_mode +and +.Fn SSL_CTX_get_session_cache_mode +first appeared in SSLeay 0.6.1 and have been available since +.Ox 2.4 . +.Pp +.Dv SSL_SESS_CACHE_NO_INTERNAL_STORE +and +.Dv SSL_SESS_CACHE_NO_INTERNAL +were introduced in OpenSSL 0.9.6h. diff --git a/Libraries/libressl/man/SSL_CTX_set_session_id_context.3 b/Libraries/libressl/man/SSL_CTX_set_session_id_context.3 new file mode 100644 index 000000000..06fd9348a --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_session_id_context.3 @@ -0,0 +1,160 @@ +.\" $OpenBSD: SSL_CTX_set_session_id_context.3,v 1.6 2019/06/08 15:25:43 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2004 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 8 2019 $ +.Dt SSL_CTX_SET_SESSION_ID_CONTEXT 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_session_id_context , +.Nm SSL_set_session_id_context +.Nd set context within which session can be reused (server side only) +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_set_session_id_context +.Fa "SSL_CTX *ctx" +.Fa "const unsigned char *sid_ctx" +.Fa "unsigned int sid_ctx_len" +.Fc +.Ft int +.Fo SSL_set_session_id_context +.Fa "SSL *ssl" +.Fa "const unsigned char *sid_ctx" +.Fa "unsigned int sid_ctx_len" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_session_id_context +sets the context +.Fa sid_ctx +of length +.Fa sid_ctx_len +within which a session can be reused for the +.Fa ctx +object. +.Pp +.Fn SSL_set_session_id_context +sets the context +.Fa sid_ctx +of length +.Fa sid_ctx_len +within which a session can be reused for the +.Fa ssl +object. +.Pp +Sessions are generated within a certain context. +When exporting/importing sessions with +.Xr i2d_SSL_SESSION 3 +and +.Xr d2i_SSL_SESSION 3 , +it would be possible to re-import a session generated from another context +(e.g., another application), which might lead to malfunctions. +Therefore each application must set its own session id context +.Fa sid_ctx +which is used to distinguish the contexts and is stored in exported sessions. +The +.Fa sid_ctx +can be any kind of binary data with a given length; it is therefore possible +to use, for instance, the name of the application, the hostname, the service +name... +.Pp +The session id context becomes part of the session. +The session id context is set by the SSL/TLS server. +The +.Fn SSL_CTX_set_session_id_context +and +.Fn SSL_set_session_id_context +functions are therefore only useful on the server side. +.Pp +OpenSSL clients will check the session id context returned by the server when +reusing a session. +.Pp +The maximum length of the +.Fa sid_ctx +is limited to +.Dv SSL_MAX_SSL_SESSION_ID_LENGTH . +.Sh WARNINGS +If the session id context is not set on an SSL/TLS server and client +certificates are used, stored sessions will not be reused but a fatal error +will be flagged and the handshake will fail. +.Pp +If a server returns a different session id context to an OpenSSL client +when reusing a session, an error will be flagged and the handshake will +fail. +OpenSSL servers will always return the correct session id context, +as an OpenSSL server checks the session id context itself before reusing +a session as described above. +.Sh RETURN VALUES +.Fn SSL_CTX_set_session_id_context +and +.Fn SSL_set_session_id_context +return the following values: +.Bl -tag -width Ds +.It 0 +The length +.Fa sid_ctx_len +of the session id context +.Fa sid_ctx +exceeded +the maximum allowed length of +.Dv SSL_MAX_SSL_SESSION_ID_LENGTH . +The error is logged to the error stack. +.It 1 +The operation succeeded. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_SESSION_set1_id_context 3 +.Sh HISTORY +.Fn SSL_set_session_id_context +first appeared in OpenSSL 0.9.2b. +.Fn SSL_CTX_set_session_id_context +first appeared in OpenSSL 0.9.3. +Both functions have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/SSL_CTX_set_ssl_version.3 b/Libraries/libressl/man/SSL_CTX_set_ssl_version.3 new file mode 100644 index 000000000..b1bdb92bb --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_ssl_version.3 @@ -0,0 +1,146 @@ +.\" $OpenBSD: SSL_CTX_set_ssl_version.3,v 1.5 2021/05/11 19:48:56 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 11 2021 $ +.Dt SSL_CTX_SET_SSL_VERSION 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_ssl_version , +.Nm SSL_set_ssl_method , +.Nm SSL_CTX_get_ssl_method , +.Nm SSL_get_ssl_method +.Nd choose a new TLS/SSL method +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_CTX_set_ssl_version "SSL_CTX *ctx" "const SSL_METHOD *method" +.Ft int +.Fn SSL_set_ssl_method "SSL *s" "const SSL_METHOD *method" +.Ft const SSL_METHOD * +.Fn SSL_CTX_get_ssl_method "SSL_CTX *ctx" +.Ft const SSL_METHOD * +.Fn SSL_get_ssl_method "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_CTX_set_ssl_version +sets a new default TLS/SSL +.Fa method +for +.Vt SSL +objects newly created from this +.Fa ctx . +.Vt SSL +objects already created with +.Xr SSL_new 3 +are not affected, except when +.Xr SSL_clear 3 +is called. +.Pp +.Fn SSL_set_ssl_method +sets a new TLS/SSL +.Fa method +for a particular +.Vt SSL +object +.Fa s . +It may be reset when +.Xr SSL_clear 3 +is called. +.Pp +.Fn SSL_CTX_get_ssl_method +and +.Fn SSL_get_ssl_method +return a function pointer to the TLS/SSL method set in +.Fa ctx +and +.Fa ssl , +respectively. +.Pp +The available +.Fa method +choices are described in +.Xr SSL_CTX_new 3 . +.Pp +When +.Xr SSL_clear 3 +is called and no session is connected to an +.Vt SSL +object, the method of the +.Vt SSL +object is reset to the method currently set in the corresponding +.Vt SSL_CTX +object. +.Sh RETURN VALUES +The following return values can occur for +.Fn SSL_CTX_set_ssl_version +and +.Fn SSL_set_ssl_method : +.Bl -tag -width Ds +.It 0 +The new choice failed. +Check the error stack to find out the reason. +.It 1 +The operation succeeded. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_new 3 , +.Xr SSL_set_connect_state 3 +.Sh HISTORY +.Fn SSL_CTX_set_ssl_version , +.Fn SSL_set_ssl_method , +and +.Fn SSL_get_ssl_method +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Fn SSL_CTX_get_ssl_method +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/SSL_CTX_set_timeout.3 b/Libraries/libressl/man/SSL_CTX_set_timeout.3 new file mode 100644 index 000000000..ab99e2016 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_timeout.3 @@ -0,0 +1,118 @@ +.\" $OpenBSD: SSL_CTX_set_timeout.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CTX_SET_TIMEOUT 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_timeout , +.Nm SSL_CTX_get_timeout +.Nd manipulate timeout values for session caching +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_CTX_set_timeout "SSL_CTX *ctx" "long t" +.Ft long +.Fn SSL_CTX_get_timeout "SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_timeout +sets the timeout for newly created sessions for +.Fa ctx +to +.Fa t . +The timeout value +.Fa t +must be given in seconds. +.Pp +.Fn SSL_CTX_get_timeout +returns the currently set timeout value for +.Fa ctx . +.Pp +Whenever a new session is created, it is assigned a maximum lifetime. +This lifetime is specified by storing the creation time of the session and the +timeout value valid at this time. +If the actual time is later than creation time plus timeout, +the session is not reused. +.Pp +Due to this realization, all sessions behave according to the timeout value +valid at the time of the session negotiation. +Changes of the timeout value do not affect already established sessions. +.Pp +The expiration time of a single session can be modified using the +.Xr SSL_SESSION_get_time 3 +family of functions. +.Pp +Expired sessions are removed from the internal session cache, whenever +.Xr SSL_CTX_flush_sessions 3 +is called, either directly by the application or automatically (see +.Xr SSL_CTX_set_session_cache_mode 3 ) . +.Pp +The default value for session timeout is decided on a per-protocol basis; see +.Xr SSL_get_default_timeout 3 . +All currently supported protocols have the same default timeout value of 300 +seconds. +.Sh RETURN VALUES +.Fn SSL_CTX_set_timeout +returns the previously set timeout value. +.Pp +.Fn SSL_CTX_get_timeout +returns the currently set timeout value. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_get_default_timeout 3 , +.Xr SSL_SESSION_get_time 3 +.Sh HISTORY +.Fn SSL_CTX_set_timeout +and +.Fn SSL_CTX_get_timeout +first appeared in SSLeay 0.6.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_CTX_set_tlsext_servername_callback.3 b/Libraries/libressl/man/SSL_CTX_set_tlsext_servername_callback.3 new file mode 100644 index 000000000..2b54406de --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_tlsext_servername_callback.3 @@ -0,0 +1,247 @@ +.\" $OpenBSD: SSL_CTX_set_tlsext_servername_callback.3,v 1.6 2021/09/01 13:56:03 schwarze Exp $ +.\" full merge up to: OpenSSL 190b9a03 Jun 28 15:46:13 2017 +0800 +.\" selective merge up to: OpenSSL 6328d367 Jul 4 21:58:30 2020 +0200 +.\" +.\" This file was written by Jon Spillett , +.\" Paul Yang , and +.\" Matt Caswell . +.\" Copyright (c) 2017, 2019 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 1 2021 $ +.Dt SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_tlsext_servername_callback , +.Nm SSL_CTX_set_tlsext_servername_arg , +.Nm SSL_get_servername_type , +.Nm SSL_get_servername , +.Nm SSL_set_tlsext_host_name +.Nd handle server name indication (SNI) +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fo SSL_CTX_set_tlsext_servername_callback +.Fa "SSL_CTX *ctx" +.Fa "int (*cb)(SSL *ssl, int *alert, void *arg)" +.Fc +.Ft long +.Fo SSL_CTX_set_tlsext_servername_arg +.Fa "SSL_CTX *ctx" +.Fa "void *arg" +.Fc +.Ft const char * +.Fo SSL_get_servername +.Fa "const SSL *ssl" +.Fa "const int type" +.Fc +.Ft int +.Fo SSL_get_servername_type +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_set_tlsext_host_name +.Fa "const SSL *ssl" +.Fa "const char *name" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_tlsext_servername_callback +sets the application callback +.Fa cb +used by a server to perform any actions or configuration required based +on the servername extension received in the incoming connection. +Like the ALPN callback, it is executed during Client Hello processing. +When +.Fa cb +is +.Dv NULL , +SNI is not used. +.Pp +The servername callback should return one of the following values: +.Bl -tag -width Ds +.It Dv SSL_TLSEXT_ERR_OK +This is used to indicate that the servername requested by the client +has been accepted. +Typically a server will call +.Xr SSL_set_SSL_CTX 3 +in the callback to set up a different configuration +for the selected servername in this case. +.It Dv SSL_TLSEXT_ERR_ALERT_FATAL +In this case the servername requested by the client is not accepted +and the handshake will be aborted. +The value of the alert to be used should be stored in the location +pointed to by the +.Fa alert +parameter to the callback. +By default this value is initialised to +.Dv SSL_AD_UNRECOGNIZED_NAME . +.It Dv SSL_TLSEXT_ERR_ALERT_WARNING +If this value is returned, then the servername is not accepted by the server. +However, the handshake will continue and send a warning alert instead. +The value of the alert should be stored in the location pointed to by the +.Fa alert +parameter as for +.Dv SSL_TLSEXT_ERR_ALERT_FATAL +above. +Note that TLSv1.3 does not support warning alerts, so if TLSv1.3 has +been negotiated then this return value is treated the same way as +.Dv SSL_TLSEXT_ERR_NOACK . +.It Dv SSL_TLSEXT_ERR_NOACK +This return value indicates +that the servername is not accepted by the server. +No alerts are sent +and the server will not acknowledge the requested servername. +.El +.Pp +.Fn SSL_CTX_set_tlsext_servername_arg +sets a context-specific argument to be passed into the callback via the +.Fa arg +parameter for +.Fa ctx . +.ig end_of_get_servername_details +.\" I would suggest to comment out that second wall text of dubious +.\" usefulness and see if we can meet all these documented API +.\" requirements in the future or decide that it's not worth the +.\" effort. -- tb@ Aug 30, 2021 +.Pp +The behaviour of +.Fn SSL_get_servername +depends on a number of different factors. +In particular note that in TLSv1.3, +the servername is negotiated in every handshake. +In TLSv1.2 the servername is only negotiated on initial handshakes +and not on resumption handshakes. +.Bl -tag -width Ds +.It On the client, before the handshake: +If a servername has been set via a call to +.Fn SSL_set_tlsext_host_name , +then it will return that servername. +If one has not been set, but a TLSv1.2 resumption is being attempted +and the session from the original handshake had a servername +accepted by the server, then it will return that servername. +Otherwise it returns +.Dv NULL . +.It On the client, during or after the handshake,\ + if a TLSv1.2 (or below) resumption occurred: +If the session from the original handshake had a servername accepted by the +server, then it will return that servername. +Otherwise it returns the servername set via +.Fn SSL_set_tlsext_host_name +or +.Dv NULL +if it was not called. +.It On the client, during or after the handshake,\ + if a TLSv1.2 (or below) resumption did not occur: +It will return the servername set via +.Fn SSL_set_tlsext_host_name +or +.Dv NULL +if it was not called. +.It On the server, before the handshake: +The function will always return +.Dv NULL +before the handshake. +.It On the server, after the servername extension has been processed,\ + if a TLSv1.2 (or below) resumption occurred: +If a servername was accepted by the server in the original handshake, +then it will return that servername, or +.Dv NULL +otherwise. +.It On the server, after the servername extension has been processed,\ + if a TLSv1.2 (or below) resumption did not occur: +The function will return the servername +requested by the client in this handshake or +.Dv NULL +if none was requested. +.El +.Pp +Note that the early callback occurs before a servername extension +from the client is processed. +The servername, certificate and ALPN callbacks occur +after a servername extension from the client is processed. +.end_of_get_servername_details +.Pp +.Fn SSL_set_tlsext_host_name +sets the server name indication ClientHello extension +to contain the value +.Fa name , +or clears it if +.Fa name +is +.Dv NULL . +The type of server name indication +extension is set to +.Dv TLSEXT_NAMETYPE_host_name +as defined in RFC 3546. +.Pp +All three functions are implemented as macros. +.Sh RETURN VALUES +.Fn SSL_CTX_set_tlsext_servername_callback +and +.Fn SSL_CTX_set_tlsext_servername_arg +always return 1 indicating success. +.Pp +.Fn SSL_get_servername +returns a servername extension value of the specified type if provided +in the Client Hello, or +.Dv NULL +otherwise. +.Pp +.Fn SSL_get_servername_type +returns the servername type or -1 if no servername is present. +Currently the only supported type (defined in RFC 3546) is +.Dv TLSEXT_NAMETYPE_host_name . +.Pp +.Fn SSL_set_tlsext_host_name +returns 1 on success or 0 in case of an error. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_callback_ctrl 3 , +.Xr SSL_CTX_set_alpn_select_cb 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8f +and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/SSL_CTX_set_tlsext_status_cb.3 b/Libraries/libressl/man/SSL_CTX_set_tlsext_status_cb.3 new file mode 100644 index 000000000..d5979af1e --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_tlsext_status_cb.3 @@ -0,0 +1,238 @@ +.\" $OpenBSD: SSL_CTX_set_tlsext_status_cb.3,v 1.8 2021/09/11 18:58:41 schwarze Exp $ +.\" full merge up to: OpenSSL 43c34894 Nov 30 16:04:51 2015 +0000 +.\" selective merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 11 2021 $ +.Dt SSL_CTX_SET_TLSEXT_STATUS_CB 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_tlsext_status_cb , +.Nm SSL_CTX_get_tlsext_status_cb , +.Nm SSL_CTX_set_tlsext_status_arg , +.Nm SSL_CTX_get_tlsext_status_arg , +.Nm SSL_set_tlsext_status_type , +.Nm SSL_get_tlsext_status_type , +.Nm SSL_get_tlsext_status_ocsp_resp , +.Nm SSL_set_tlsext_status_ocsp_resp +.Nd OCSP Certificate Status Request functions +.Sh SYNOPSIS +.In openssl/tls1.h +.Ft long +.Fo SSL_CTX_set_tlsext_status_cb +.Fa "SSL_CTX *ctx" +.Fa "int (*callback)(SSL *, void *)" +.Fc +.Ft long +.Fo SSL_CTX_get_tlsext_status_cb +.Fa "SSL_CTX *ctx" +.Fa "int (*callback)(SSL *, void *)" +.Fc +.Ft long +.Fo SSL_CTX_set_tlsext_status_arg +.Fa "SSL_CTX *ctx" +.Fa "void *arg" +.Fc +.Ft long +.Fo SSL_CTX_get_tlsext_status_arg +.Fa "SSL_CTX *ctx" +.Fa "void **arg" +.Fc +.Ft long +.Fo SSL_set_tlsext_status_type +.Fa "SSL *s" +.Fa "int type" +.Fc +.Ft long +.Fo SSL_get_tlsext_status_type +.Fa "SSL *s" +.Fc +.Ft long +.Fo SSL_get_tlsext_status_ocsp_resp +.Fa ssl +.Fa "unsigned char **resp" +.Fc +.Ft long +.Fo SSL_set_tlsext_status_ocsp_resp +.Fa ssl +.Fa "unsigned char *resp" +.Fa "int len" +.Fc +.Sh DESCRIPTION +A client application may request that a server send back an OCSP status +response (also known as OCSP stapling). +To do so the client should call the +.Fn SSL_set_tlsext_status_type +function on an individual +.Vt SSL +object prior to the start of the handshake. +Currently the only supported type is +.Dv TLSEXT_STATUSTYPE_ocsp . +This value should be passed in the +.Fa type +argument. +.Pp +The client should additionally provide a callback function to decide +what to do with the returned OCSP response by calling +.Fn SSL_CTX_set_tlsext_status_cb . +The callback function should determine whether the returned OCSP +response is acceptable or not. +The callback will be passed as an argument the value previously set via +a call to +.Fn SSL_CTX_set_tlsext_status_arg . +Note that the callback will not be called in the event of a handshake +where session resumption occurs (because there are no Certificates +exchanged in such a handshake). +.Pp +The callback previously set via +.Fn SSL_CTX_set_tlsext_status_cb +can be retrieved by calling +.Fn SSL_CTX_get_tlsext_status_cb , +and the argument by calling +.Fn SSL_CTX_get_tlsext_status_arg . +.Pp +On the client side, +.Fn SSL_get_tlsext_status_type +can be used to determine whether the client has previously called +.Fn SSL_set_tlsext_status_type . +It will return +.Dv TLSEXT_STATUSTYPE_ocsp +if it has been called or \-1 otherwise. +On the server side, +.Fn SSL_get_tlsext_status_type +can be used to determine whether the client requested OCSP stapling. +If the client requested it, then this function will return +.Dv TLSEXT_STATUSTYPE_ocsp , +or \-1 otherwise. +.Pp +The response returned by the server can be obtained via a call to +.Fn SSL_get_tlsext_status_ocsp_resp . +The value +.Pf * Fa resp +will be updated to point to the OCSP response data and the return value +will be the length of that data. +If the server has not provided any response data, then +.Pf * Fa resp +will be +.Dv NULL +and the return value from +.Fn SSL_get_tlsext_status_ocsp_resp +will be -1. +.Pp +A server application must also call the +.Fn SSL_CTX_set_tlsext_status_cb +function if it wants to be able to provide clients with OCSP Certificate +Status responses. +Typically the server callback would obtain the server certificate that +is being sent back to the client via a call to +.Xr SSL_get_certificate 3 , +obtain the OCSP response to be sent back, and then set that response +data by calling +.Fn SSL_set_tlsext_status_ocsp_resp . +A pointer to the response data should be provided in the +.Fa resp +argument, and the length of that data should be in the +.Fa len +argument. +.Sh RETURN VALUES +The callback when used on the client side should return a negative +value on error, 0 if the response is not acceptable (in which case +the handshake will fail), or a positive value if it is acceptable. +.Pp +The callback when used on the server side should return with either +.Dv SSL_TLSEXT_ERR_OK +(meaning that the OCSP response that has been set should be returned), +.Dv SSL_TLSEXT_ERR_NOACK +(meaning that an OCSP response should not be returned), or +.Dv SSL_TLSEXT_ERR_ALERT_FATAL +(meaning that a fatal error has occurred). +.Pp +.Fn SSL_CTX_set_tlsext_status_cb , +.Fn SSL_CTX_get_tlsext_status_cb , +.Fn SSL_CTX_set_tlsext_status_arg , +.Fn SSL_CTX_get_tlsext_status_arg , +.Fn SSL_set_tlsext_status_type , +and +.Fn SSL_set_tlsext_status_ocsp_resp +always return 1, indicating success. +.Pp +.Fn SSL_get_tlsext_status_type +returns +.Dv TLSEXT_STATUSTYPE_ocsp +on the client side if +.Fn SSL_set_tlsext_status_type +was previously called, or on the server side +if the client requested OCSP stapling. +Otherwise \-1 is returned. +.Pp +.Fn SSL_get_tlsext_status_ocsp_resp +returns the length of the OCSP response data +or \-1 if there is no OCSP response data. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_callback_ctrl 3 +.Sh HISTORY +.Fn SSL_CTX_set_tlsext_status_cb , +.Fn SSL_CTX_set_tlsext_status_arg , +.Fn SSL_set_tlsext_status_type , +.Fn SSL_get_tlsext_status_ocsp_resp , +and +.Fn SSL_set_tlsext_status_ocsp_resp +first appeared in OpenSSL 0.9.8h and have been available since +.Ox 4.5 . +.Pp +.Fn SSL_CTX_get_tlsext_status_cb +and +.Fn SSL_CTX_get_tlsext_status_arg +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Pp +.Fn SSL_get_tlsext_status_type +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 b/Libraries/libressl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 new file mode 100644 index 000000000..b6ccabaec --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 @@ -0,0 +1,300 @@ +.\" $OpenBSD: SSL_CTX_set_tlsext_ticket_key_cb.3,v 1.8 2022/01/25 18:01:20 tb Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Rich Salz +.\" Copyright (c) 2014, 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 25 2022 $ +.Dt SSL_CTX_SET_TLSEXT_TICKET_KEY_CB 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_tlsext_ticket_key_cb +.Nd set a callback for session ticket processing +.Sh SYNOPSIS +.In openssl/tls1.h +.Ft long +.Fo SSL_CTX_set_tlsext_ticket_key_cb +.Fa "SSL_CTX sslctx" +.Fa "int (*cb)(SSL *s, unsigned char key_name[16],\ + unsigned char iv[EVP_MAX_IV_LENGTH],\ + EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_tlsext_ticket_key_cb +sets a callback function +.Fa cb +for handling session tickets for the ssl context +.Fa sslctx . +Session tickets, defined in RFC 5077, provide an enhanced session +resumption capability where the server implementation is not required to +maintain per session state. +.Pp +The callback function +.Fa cb +will be called for every client instigated TLS session when session +ticket extension is presented in the TLS hello message. +It is the responsibility of this function to create or retrieve the +cryptographic parameters and to maintain their state. +.Pp +The OpenSSL library uses the callback function to help implement a +common TLS ticket construction state according to RFC 5077 Section 4 such +that per session state is unnecessary and a small set of cryptographic +variables needs to be maintained by the callback function +implementation. +.Pp +In order to reuse a session, a TLS client must send a session ticket +extension to the server. +The client can only send exactly one session ticket. +The server, through the callback function, either agrees to reuse the +session ticket information or it starts a full TLS handshake to create a +new session ticket. +.Pp +The callback is called with +.Fa ctx +and +.Fa hctx +which were newly allocated with +.Xr EVP_CIPHER_CTX_new 3 +and +.Xr HMAC_CTX_new 3 , +respectively. +.Pp +For new sessions tickets, when the client doesn't present a session +ticket, or an attempted retrieval of the ticket failed, or a renew +option was indicated, the callback function will be called with +.Fa enc +equal to 1. +The OpenSSL library expects that the function will set an arbitrary +.Fa key_name , +initialize +.Fa iv , +and set the cipher context +.Fa ctx +and the hash context +.Fa hctx . +.Pp +The +.Fa key_name +is 16 characters long and is used as a key identifier. +.Pp +The +.Fa iv +length is the length of the IV of the corresponding cipher. +The maximum IV length is +.Dv EVP_MAX_IV_LENGTH +bytes defined in +.In openssl/evp.h . +.Pp +The initialization vector +.Fa iv +should be a random value. +The cipher context +.Fa ctx +should use the initialisation vector +.Fa iv . +The cipher context can be set using +.Xr EVP_EncryptInit_ex 3 . +The hmac context can be set using +.Xr HMAC_Init_ex 3 . +.Pp +When the client presents a session ticket, the callback function +with be called with +.Fa enc +set to 0 indicating that the +.Fa cb +function should retrieve a set of parameters. +In this case +.Fa key_name +and +.Fa iv +have already been parsed out of the session ticket. +The OpenSSL library expects that the +.Em key_name +will be used to retrieve a cryptographic parameters and that the +cryptographic context +.Fa ctx +will be set with the retrieved parameters and the initialization vector +.Fa iv +using a function like +.Xr EVP_DecryptInit_ex 3 . +The +.Fa hctx +needs to be set using +.Xr HMAC_Init_ex 3 . +.Pp +If the +.Fa key_name +is still valid but a renewal of the ticket is required, the callback +function should return 2. +The library will call the callback again with an argument of +.Fa enc +equal to 1 to set the new ticket. +.Pp +The return value of the +.Fa cb +function is used by OpenSSL to determine what further processing will +occur. +The following return values have meaning: +.Bl -tag -width Ds +.It 2 +This indicates that the +.Fa ctx +and +.Fa hctx +have been set and the session can continue on those parameters. +Additionally it indicates that the session ticket is in a renewal period +and should be replaced. +The OpenSSL library will call +.Fa cb +again with an +.Fa enc +argument of 1 to set the new ticket (see RFC 5077 3.3 paragraph 2). +.It 1 +This indicates that the +.Fa ctx +and +.Fa hctx +have been set and the session can continue on those parameters. +.It 0 +This indicates that it was not possible to set/retrieve a session ticket +and the SSL/TLS session will continue by negotiating a set of +cryptographic parameters or using the alternate SSL/TLS resumption +mechanism, session ids. +.Pp +If called with +.Fa enc +equal to 0, the library will call the +.Fa cb +again to get a new set of parameters. +.It less than 0 +This indicates an error. +.El +.Pp +Session resumption shortcuts the TLS so that the client certificate +negotiation don't occur. +It makes up for this by storing client certificate and all other +negotiated state information encrypted within the ticket. +In a resumed session the applications will have all this state +information available exactly as if a full negotiation had occurred. +.Pp +If an attacker can obtain the key used to encrypt a session ticket, they +can obtain the master secret for any ticket using that key and decrypt +any traffic using that session: even if the ciphersuite supports forward +secrecy. +As a result applications may wish to use multiple keys and avoid using +long term keys stored in files. +.Pp +Applications can use longer keys to maintain a consistent level of +security. +For example if a ciphersuite uses 256 bit ciphers but only a 128 bit +ticket key the overall security is only 128 bits because breaking the +ticket key will enable an attacker to obtain the session keys. +.Sh RETURN VALUES +This function returns 0 to indicate that the callback function was set. +.Sh EXAMPLES +Reference Implementation: +.Bd -literal +SSL_CTX_set_tlsext_ticket_key_cb(SSL, ssl_tlsext_ticket_key_cb); +\&.... +static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], + unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + if (enc) { /* create new session */ + if (RAND_bytes(iv, EVP_MAX_IV_LENGTH)) + return -1; /* insufficient random */ + + key = currentkey(); /* something you need to implement */ + if (!key) { + /* current key doesn't exist or isn't valid */ + key = createkey(); + /* something that you need to implement. + * createkey needs to initialise a name, + * an aes_key, a hmac_key, and optionally + * an expire time. */ + if (!key) /* key couldn't be created */ + return 0; + } + memcpy(key_name, key->name, 16); + + EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + key->aes_key, iv); + HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL); + + return 1; + + } else { /* retrieve session */ + key = findkey(name); + + if (!key || key->expire < now()) + return 0; + + HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL); + EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + key->aes_key, iv ); + + if (key->expire < (now() - RENEW_TIME)) + /* this session will get a new ticket + * even though the current is still valid */ + return 2; + + return 1; + } +} +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_add_session 3 , +.Xr SSL_CTX_callback_ctrl 3 , +.Xr SSL_CTX_sess_number 3 , +.Xr SSL_CTX_sess_set_get_cb 3 , +.Xr SSL_CTX_set_session_id_context 3 , +.Xr SSL_session_reused 3 , +.Xr SSL_set_session 3 +.Sh HISTORY +.Fn SSL_CTX_set_tlsext_ticket_key_cb +first appeared in OpenSSL 0.9.8h and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/SSL_CTX_set_tlsext_use_srtp.3 b/Libraries/libressl/man/SSL_CTX_set_tlsext_use_srtp.3 new file mode 100644 index 000000000..04c4833c6 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_tlsext_use_srtp.3 @@ -0,0 +1,197 @@ +.\" $OpenBSD: SSL_CTX_set_tlsext_use_srtp.3,v 1.6 2021/06/11 19:41:39 jmc Exp $ +.\" full merge up to: OpenSSL b0edda11 Mar 20 13:00:17 2018 +0000 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 11 2021 $ +.Dt SSL_CTX_SET_TLSEXT_USE_SRTP 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_tlsext_use_srtp , +.Nm SSL_set_tlsext_use_srtp , +.Nm SSL_get_srtp_profiles , +.Nm SSL_get_selected_srtp_profile +.Nd Configure and query SRTP support +.Sh SYNOPSIS +.In openssl/srtp.h +.Ft int +.Fo SSL_CTX_set_tlsext_use_srtp +.Fa "SSL_CTX *ctx" +.Fa "const char *profiles" +.Fc +.Ft int +.Fo SSL_set_tlsext_use_srtp +.Fa "SSL *ssl" +.Fa "const char *profiles" +.Fc +.Ft STACK_OF(SRTP_PROTECTION_PROFILE) * +.Fo SSL_get_srtp_profiles +.Fa "SSL *ssl" +.Fc +.Ft SRTP_PROTECTION_PROFILE * +.Fo SSL_get_selected_srtp_profile +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +SRTP is the Secure Real-Time Transport Protocol. +OpenSSL implements support for the "use_srtp" DTLS extension +defined in RFC 5764. +This provides a mechanism for establishing SRTP keying material, +algorithms and parameters using DTLS. +This capability may be used as part of an implementation that +conforms to RFC 5763. +OpenSSL does not implement SRTP itself or RFC 5763. +Note that OpenSSL does not support the use of SRTP Master Key +Identifiers (MKIs). +Also note that this extension is only supported in DTLS. +Any SRTP configuration is ignored if a TLS connection is attempted. +.Pp +An OpenSSL client wishing to send the "use_srtp" extension should call +.Fn SSL_CTX_set_tlsext_use_srtp +to set its use for all +.Vt SSL +objects subsequently created from +.Fa ctx . +Alternatively a client may call +.Fn SSL_set_tlsext_use_srtp +to set its use for an individual +.Vt SSL +object. +The +.Fa profiles +parameter should point to a NUL-terminated, colon delimited list of +SRTP protection profile names. +.Pp +The currently supported protection profile names are: +.Bl -tag -width Ds +.It Dv SRTP_AES128_CM_SHA1_80 +This corresponds to SRTP_AES128_CM_HMAC_SHA1_80 defined in RFC 5764. +.It Dv SRTP_AES128_CM_SHA1_32 +This corresponds to SRTP_AES128_CM_HMAC_SHA1_32 defined in RFC 5764. +.It Dv SRTP_AEAD_AES_128_GCM +This corresponds to SRTP_AEAD_AES_128_GCM defined in RFC 7714. +.It Dv SRTP_AEAD_AES_256_GCM +This corresponds to SRTP_AEAD_AES_256_GCM defined in RFC 7714. +.El +.Pp +Supplying an unrecognised protection profile name results in an error. +.Pp +An OpenSSL server wishing to support the "use_srtp" extension should +also call +.Fn SSL_CTX_set_tlsext_use_srtp +or +.Fn SSL_set_tlsext_use_srtp +to indicate the protection profiles that it is willing to negotiate. +.Pp +The currently configured list of protection profiles for either a client +or a server can be obtained by calling +.Fn SSL_get_srtp_profiles . +This returns a stack of +.Vt SRTP_PROTECTION_PROFILE +objects. +The memory pointed to in the return value of this function should not be +freed by the caller. +.Pp +After a handshake has been completed, the negotiated SRTP protection +profile (if any) can be obtained (on the client or the server) by +calling +.Fn SSL_get_selected_srtp_profile . +This function returns +.Dv NULL +if no SRTP protection profile was negotiated. +The memory returned from this function should not be freed by the +caller. +.Pp +If an SRTP protection profile has been successfully negotiated, +then the SRTP keying material (on both the client and server) +should be obtained by calling +.Xr SSL_export_keying_material 3 +with a +.Fa label +of +.Qq EXTRACTOR-dtls_srtp , +a +.Fa context +of +.Dv NULL , +and a +.Fa use_context +argument of 0. +The total length of keying material obtained should be equal to two +times the sum of the master key length and the salt length as defined +for the protection profile in use. +This provides the client write master key, the server write master key, +the client write master salt and the server write master salt in that +order. +.Sh RETURN VALUES +Contrary to OpenSSL conventions, +.Fn SSL_CTX_set_tlsext_use_srtp +and +.Fn SSL_set_tlsext_use_srtp +return 0 on success or 1 on error. +.Pp +.Fn SSL_get_srtp_profiles +returns a stack of +.Vt SRTP_PROTECTION_PROFILE +objects on success or +.Dv NULL +on error or if no protection profiles have been configured. +.Pp +.Fn SSL_get_selected_srtp_profile +returns a pointer to an +.Vt SRTP_PROTECTION_PROFILE +object if one has been negotiated or +.Dv NULL +otherwise. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_export_keying_material 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.1 +and have been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/SSL_CTX_set_tmp_dh_callback.3 b/Libraries/libressl/man/SSL_CTX_set_tmp_dh_callback.3 new file mode 100644 index 000000000..8be504d3b --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_tmp_dh_callback.3 @@ -0,0 +1,230 @@ +.\" $OpenBSD: SSL_CTX_set_tmp_dh_callback.3,v 1.10 2022/03/31 17:27:18 naddy Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2014, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt SSL_CTX_SET_TMP_DH_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_tmp_dh_callback , +.Nm SSL_CTX_set_tmp_dh , +.Nm SSL_set_tmp_dh_callback , +.Nm SSL_set_tmp_dh +.Nd handle DH keys for ephemeral key exchange +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_tmp_dh_callback +.Fa "SSL_CTX *ctx" +.Fa "DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength)" +.Fc +.Ft long +.Fn SSL_CTX_set_tmp_dh "SSL_CTX *ctx" "DH *dh" +.Ft void +.Fo SSL_set_tmp_dh_callback +.Fa "SSL *ssl" +.Fa "DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength" +.Fc +.Ft long +.Fn SSL_set_tmp_dh "SSL *ssl" "DH *dh" +.Sh DESCRIPTION +.Fn SSL_CTX_set_tmp_dh_callback +sets the callback function for +.Fa ctx +to be used when a DH parameters are required to +.Fa tmp_dh_callback . +The callback is inherited by all +.Vt ssl +objects created from +.Fa ctx . +.Pp +.Fn SSL_CTX_set_tmp_dh +sets DH parameters to be used by +.Fa ctx . +The key is inherited by all +.Fa ssl +objects created from +.Fa ctx . +.Pp +.Fn SSL_set_tmp_dh_callback +sets the callback only for +.Fa ssl . +.Pp +.Fn SSL_set_tmp_dh +sets the parameters only for +.Fa ssl . +.Pp +These functions apply to SSL/TLS servers only. +.Pp +When using a cipher with RSA authentication, +an ephemeral DH key exchange can take place. +Ciphers with DSA keys always use ephemeral DH keys as well. +In these cases, the session data are negotiated using the ephemeral/temporary +DH key and the key supplied and certified by the certificate chain is only used +for signing. +Anonymous ciphers (without a permanent server key) also use ephemeral DH keys. +.Pp +Using ephemeral DH key exchange yields forward secrecy, +as the connection can only be decrypted when the DH key is known. +By generating a temporary DH key inside the server application that is lost +when the application is left, it becomes impossible for attackers to decrypt +past sessions, even if they get hold of the normal (certified) key, +as this key was only used for signing. +.Pp +In order to perform a DH key exchange, the server must use a DH group +(DH parameters) and generate a DH key. +The server will always generate a new DH key during the negotiation. +.Pp +As generating DH parameters is extremely time consuming, an application should +not generate the parameters on the fly but supply the parameters. +DH parameters can be reused, +as the actual key is newly generated during the negotiation. +The risk in reusing DH parameters is that an attacker may specialize on a very +often used DH group. +Applications should therefore generate their own DH parameters during the +installation process using the +.Xr openssl 1 +.Cm dhparam +application. +This application guarantees that "strong" primes are used. +.Pp +Files +.Pa dh2048.pem +and +.Pa dh4096.pem +in the +.Pa apps +directory of the current version of the OpenSSL distribution contain the +.Sq SKIP +DH parameters, +which use safe primes and were generated verifiably pseudo-randomly. +These files can be converted into C code using the +.Fl C +option of the +.Xr openssl 1 +.Cm dhparam +application. +Generation of custom DH parameters during installation should still +be preferred to stop an attacker from specializing on a commonly +used group. +The file +.Pa dh1024.pem +contains old parameters that must not be used by applications. +.Pp +An application may either directly specify the DH parameters or can supply the +DH parameters via a callback function. +.Pp +Previous versions of the callback used +.Fa is_export +and +.Fa keylength +parameters to control parameter generation for export and non-export +cipher suites. +Modern servers that do not support export ciphersuites are advised +to either use +.Fn SSL_CTX_set_tmp_dh +or alternatively, use the callback but ignore +.Fa keylength +and +.Fa is_export +and simply supply at least 2048-bit parameters in the callback. +.Sh RETURN VALUES +.Fn SSL_CTX_set_tmp_dh +and +.Fn SSL_set_tmp_dh +do return 1 on success and 0 on failure. +Check the error queue to find out the reason of failure. +.Sh EXAMPLES +Set up DH parameters with a key length of 2048 bits. +Error handling is partly left out. +.Pp +Command-line parameter generation: +.Pp +.Dl openssl dhparam -out dh_param_2048.pem 2048 +.Pp +Code for setting up parameters during server initialization: +.Bd -literal +SSL_CTX ctx = SSL_CTX_new(); +\&... + +/* Set up ephemeral DH parameters. */ +DH *dh_2048 = NULL; +FILE *paramfile; +paramfile = fopen("dh_param_2048.pem", "r"); +if (paramfile) { + dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); + fclose(paramfile); +} else { + /* Error. */ +} +if (dh_2048 == NULL) { + /* Error. */ +} +if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) { + /* Error. */ +} +.Ed +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ssl 3 , +.Xr SSL_CTX_set_cipher_list 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_set_tmp_ecdh 3 +.Sh HISTORY +.Fn SSL_CTX_set_tmp_dh_callback +and +.Fn SSL_CTX_set_tmp_dh +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_set_tmp_dh_callback +and +.Fn SSL_set_tmp_dh +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/SSL_CTX_set_tmp_rsa_callback.3 b/Libraries/libressl/man/SSL_CTX_set_tmp_rsa_callback.3 new file mode 100644 index 000000000..b4c3a3c64 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_tmp_rsa_callback.3 @@ -0,0 +1,114 @@ +.\" $OpenBSD: SSL_CTX_set_tmp_rsa_callback.3,v 1.9 2022/03/29 14:27:59 naddy Exp $ +.\" OpenSSL 0b30fc90 Dec 19 15:23:05 2013 -0500 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2006, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 29 2022 $ +.Dt SSL_CTX_SET_TMP_RSA_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_tmp_rsa_callback , +.Nm SSL_CTX_set_tmp_rsa , +.Nm SSL_CTX_need_tmp_RSA , +.Nm SSL_set_tmp_rsa_callback , +.Nm SSL_set_tmp_rsa , +.Nm SSL_need_tmp_RSA +.Nd handle RSA keys for ephemeral key exchange +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_tmp_rsa_callback +.Fa "SSL_CTX *ctx" +.Fa "RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength)" +.Fc +.Ft long +.Fn SSL_CTX_set_tmp_rsa "SSL_CTX *ctx" "RSA *rsa" +.Ft long +.Fn SSL_CTX_need_tmp_RSA "SSL_CTX *ctx" +.Ft void +.Fo SSL_set_tmp_rsa_callback +.Fa "SSL_CTX *ctx" +.Fa "RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength)" +.Fc +.Ft long +.Fn SSL_set_tmp_rsa "SSL *ssl" "RSA *rsa" +.Ft long +.Fn SSL_need_tmp_RSA "SSL *ssl" +.Sh DESCRIPTION +Since they mattered only for deliberately insecure RSA authentication +mandated by historical U.S. export restrictions, these functions +are all deprecated and have no effect except that +.Fn SSL_CTX_set_tmp_rsa_callback , +.Fn SSL_CTX_set_tmp_rsa , +.Fn SSL_set_tmp_rsa_callback , +and +.Fn SSL_set_tmp_rsa +issue error messages when called. +.Sh RETURN VALUES +These functions always return 0, indicating failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_cipher_list 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_CTX_set_tmp_dh_callback 3 , +.Xr SSL_new 3 , +.Xr SSL_set_tmp_ecdh 3 +.Sh HISTORY +.Fn SSL_CTX_set_tmp_rsa_callback , +.Fn SSL_CTX_set_tmp_rsa , +and +.Fn SSL_CTX_need_tmp_RSA +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_set_tmp_rsa_callback , +.Fn SSL_set_tmp_rsa , +and +.Fn SSL_need_tmp_RSA +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/SSL_CTX_set_verify.3 b/Libraries/libressl/man/SSL_CTX_set_verify.3 new file mode 100644 index 000000000..1ed86407e --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_set_verify.3 @@ -0,0 +1,479 @@ +.\" $OpenBSD: SSL_CTX_set_verify.3,v 1.9 2021/06/12 16:59:53 jmc Exp $ +.\" full merge up to: OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" selective merge up to: OpenSSL 1cb7eff4 Sep 10 13:56:40 2019 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2002, 2003, 2014 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2021 $ +.Dt SSL_CTX_SET_VERIFY 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_verify , +.Nm SSL_set_verify , +.Nm SSL_CTX_set_verify_depth , +.Nm SSL_set_verify_depth +.Nd set peer certificate verification parameters +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fo SSL_CTX_set_verify +.Fa "SSL_CTX *ctx" +.Fa "int mode" +.Fa "int (*verify_callback)(int, X509_STORE_CTX *)" +.Fc +.Ft void +.Fo SSL_set_verify +.Fa "SSL *s" +.Fa "int mode" +.Fa "int (*verify_callback)(int, X509_STORE_CTX *)" +.Fc +.Ft void +.Fn SSL_CTX_set_verify_depth "SSL_CTX *ctx" "int depth" +.Ft void +.Fn SSL_set_verify_depth "SSL *s" "int depth" +.Ft int +.Fn verify_callback "int preverify_ok" "X509_STORE_CTX *x509_ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_set_verify +sets the verification flags for +.Fa ctx +to be +.Fa mode +and +specifies the +.Fa verify_callback +function to be used. +If no callback function shall be specified, the +.Dv NULL +pointer can be used for +.Fa verify_callback . +.Pp +.Fn SSL_set_verify +sets the verification flags for +.Fa ssl +to be +.Fa mode +and specifies the +.Fa verify_callback +function to be used. +If no callback function shall be specified, the +.Dv NULL +pointer can be used for +.Fa verify_callback . +In this case last +.Fa verify_callback +set specifically for this +.Fa ssl +remains. +If no special callback was set before, the default callback for the underlying +.Fa ctx +is used, that was valid at the time +.Fa ssl +was created with +.Xr SSL_new 3 . +Within the callback function, +.Xr SSL_get_ex_data_X509_STORE_CTX_idx 3 +can be called to get the data index of the current +.Vt SSL +object that is doing the verification. +.Pp +.Fn SSL_CTX_set_verify_depth +sets the maximum +.Fa depth +for the certificate chain verification that shall be allowed for +.Fa ctx . +(See the +.Sx BUGS +section.) +.Pp +.Fn SSL_set_verify_depth +sets the maximum +.Fa depth +for the certificate chain verification that shall be allowed for +.Fa ssl . +(See the +.Sx BUGS +section.) +.Pp +The verification of certificates can be controlled by a set of bitwise ORed +.Fa mode +flags: +.Bl -tag -width Ds +.It Dv SSL_VERIFY_NONE +.Em Server mode : +the server will not send a client certificate request to the client, +so the client will not send a certificate. +.Pp +.Em Client mode : +if not using an anonymous cipher (by default disabled), +the server will send a certificate which will be checked. +The result of the certificate verification process can be checked after the +TLS/SSL handshake using the +.Xr SSL_get_verify_result 3 +function. +The handshake will be continued regardless of the verification result. +.It Dv SSL_VERIFY_PEER +.Em Server mode : +the server sends a client certificate request to the client. +The certificate returned (if any) is checked. +If the verification process fails, +the TLS/SSL handshake is immediately terminated with an alert message +containing the reason for the verification failure. +The behaviour can be controlled by the additional +.Dv SSL_VERIFY_FAIL_IF_NO_PEER_CERT +and +.Dv SSL_VERIFY_CLIENT_ONCE +flags. +.Pp +.Em Client mode : +the server certificate is verified. +If the verification process fails, +the TLS/SSL handshake is immediately terminated with an alert message +containing the reason for the verification failure. +If no server certificate is sent, because an anonymous cipher is used, +.Dv SSL_VERIFY_PEER +is ignored. +.It Dv SSL_VERIFY_FAIL_IF_NO_PEER_CERT +.Em Server mode : +if the client did not return a certificate, the TLS/SSL +handshake is immediately terminated with a +.Dq handshake failure +alert. +This flag must be used together with +.Dv SSL_VERIFY_PEER . +.Pp +.Em Client mode : +ignored +.It Dv SSL_VERIFY_CLIENT_ONCE +.Em Server mode : +only request a client certificate on the initial TLS/SSL handshake. +Do not ask for a client certificate again in case of a renegotiation. +This flag must be used together with +.Dv SSL_VERIFY_PEER . +.Pp +.Em Client mode : +ignored +.El +.Pp +Exactly one of the +.Fa mode +flags +.Dv SSL_VERIFY_NONE +and +.Dv SSL_VERIFY_PEER +must be set at any time. +.Pp +The actual verification procedure is performed either using the built-in +verification procedure or using another application provided verification +function set with +.Xr SSL_CTX_set_cert_verify_callback 3 . +The following descriptions apply in the case of the built-in procedure. +An application provided procedure also has access to the verify depth +information and the +.Fa verify_callback Ns () +function, but the way this information is used may be different. +.Pp +.Fn SSL_CTX_set_verify_depth +and +.Fn SSL_set_verify_depth +set the limit up to which depth certificates in a chain are used during the +verification procedure. +If the certificate chain is longer than allowed, +the certificates above the limit are ignored. +Error messages are generated as if these certificates would not be present, +most likely a +.Dv X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY +will be issued. +The depth count is +.Dq level 0: peer certificate , +.Dq level 1: CA certificate , +.Dq level 2: higher level CA certificate , +and so on. +Setting the maximum depth to 2 allows the levels 0, 1, and 2. +The default depth limit is 100, +allowing for the peer certificate and an additional 100 CA certificates. +.Pp +The +.Fa verify_callback +function is used to control the behaviour when the +.Dv SSL_VERIFY_PEER +flag is set. +It must be supplied by the application and receives two arguments: +.Fa preverify_ok +indicates whether the verification of the certificate in question was passed +(preverify_ok=1) or not (preverify_ok=0). +.Fa x509_ctx +is a pointer to the complete context used +for the certificate chain verification. +.Pp +The certificate chain is checked starting with the deepest nesting level +(the root CA certificate) and worked upward to the peer's certificate. +At each level signatures and issuer attributes are checked. +Whenever a verification error is found, the error number is stored in +.Fa x509_ctx +and +.Fa verify_callback +is called with +.Fa preverify_ok +equal to 0. +By applying +.Fn X509_CTX_store_* +functions +.Fa verify_callback +can locate the certificate in question and perform additional steps (see +.Sx EXAMPLES ) . +If no error is found for a certificate, +.Fa verify_callback +is called with +.Fa preverify_ok +equal to 1 before advancing to the next level. +.Pp +The return value of +.Fa verify_callback +controls the strategy of the further verification process. +If +.Fa verify_callback +returns 0, the verification process is immediately stopped with +.Dq verification failed +state. +If +.Dv SSL_VERIFY_PEER +is set, a verification failure alert is sent to the peer and the TLS/SSL +handshake is terminated. +If +.Fa verify_callback +returns 1, the verification process is continued. +If +.Fa verify_callback +always returns 1, +the TLS/SSL handshake will not be terminated with respect to verification +failures and the connection will be established. +The calling process can however retrieve the error code of the last +verification error using +.Xr SSL_get_verify_result 3 +or by maintaining its own error storage managed by +.Fa verify_callback . +.Pp +If no +.Fa verify_callback +is specified, the default callback will be used. +Its return value is identical to +.Fa preverify_ok , +so that any verification +failure will lead to a termination of the TLS/SSL handshake with an +alert message, if +.Dv SSL_VERIFY_PEER +is set. +.Sh EXAMPLES +The following code sequence realizes an example +.Fa verify_callback +function that will always continue the TLS/SSL handshake regardless of +verification failure, if wished. +The callback realizes a verification depth limit with more informational output. +.Pp +All verification errors are printed; +information about the certificate chain is printed on request. +The example is realized for a server that does allow but not require client +certificates. +.Pp +The example makes use of the ex_data technique to store application data +into/retrieve application data from the +.Vt SSL +structure (see +.Xr SSL_get_ex_new_index 3 , +.Xr SSL_get_ex_data_X509_STORE_CTX_idx 3 ) . +.Bd -literal +\&... + +typedef struct { + int verbose_mode; + int verify_depth; + int always_continue; +} mydata_t; +int mydata_index; +\&... +static int +verify_callback(int preverify_ok, X509_STORE_CTX *ctx) +{ + char buf[256]; + X509 *err_cert; + int err, depth; + SSL *ssl; + mydata_t *mydata; + + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); + + /* + * Retrieve the pointer to the SSL of the connection currently + * treated * and the application specific data stored into the + * SSL object. + */ + ssl = X509_STORE_CTX_get_ex_data(ctx, + SSL_get_ex_data_X509_STORE_CTX_idx()); + mydata = SSL_get_ex_data(ssl, mydata_index); + + X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); + + /* + * Catch a too long certificate chain. The depth limit set using + * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so + * that whenever the "depth>verify_depth" condition is met, we + * have violated the limit and want to log this error condition. + * We must do it here, because the CHAIN_TOO_LONG error would not + * be found explicitly; only errors introduced by cutting off the + * additional certificates would be logged. + */ + if (depth > mydata->verify_depth) { + preverify_ok = 0; + err = X509_V_ERR_CERT_CHAIN_TOO_LONG; + X509_STORE_CTX_set_error(ctx, err); + } + if (!preverify_ok) { + printf("verify error:num=%d:%s:depth=%d:%s\en", err, + X509_verify_cert_error_string(err), depth, buf); + } else if (mydata->verbose_mode) { + printf("depth=%d:%s\en", depth, buf); + } + + /* + * At this point, err contains the last verification error. + * We can use it for something special + */ + if (!preverify_ok && (err == + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) { + X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), + buf, 256); + printf("issuer= %s\en", buf); + } + + if (mydata->always_continue) + return 1; + else + return preverify_ok; +} +\&... + +mydata_t mydata; + +\&... + +mydata_index = SSL_get_ex_new_index(0, "mydata index", NULL, NULL, NULL); + +\&... + +SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, + verify_callback); + +/* + * Let the verify_callback catch the verify_depth error so that we get + * an appropriate error in the logfile. + */ +SSL_CTX_set_verify_depth(verify_depth + 1); + +/* + * Set up the SSL specific data into "mydata" and store it into the SSL + * structure. + */ +mydata.verify_depth = verify_depth; ... +SSL_set_ex_data(ssl, mydata_index, &mydata); + +\&... + +SSL_accept(ssl); /* check of success left out for clarity */ +if (peer = SSL_get_peer_certificate(ssl)) { + if (SSL_get_verify_result(ssl) == X509_V_OK) { + /* The client sent a certificate which verified OK */ + } +} +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_get_verify_mode 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_CTX_set_cert_verify_callback 3 , +.Xr SSL_get_ex_data_X509_STORE_CTX_idx 3 , +.Xr SSL_get_ex_new_index 3 , +.Xr SSL_get_peer_certificate 3 , +.Xr SSL_get_verify_result 3 , +.Xr SSL_new 3 , +.Xr SSL_set1_host 3 +.Sh HISTORY +.Fn SSL_set_verify +appeared in SSLeay 0.4 or earlier. +.Fn SSL_CTX_set_verify +first appeared in SSLeay 0.6.4. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_set_verify_depth +and +.Fn SSL_set_verify_depth +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . +.Sh BUGS +In client mode, it is not checked whether the +.Dv SSL_VERIFY_PEER +flag is set, but whether +.Dv SSL_VERIFY_NONE +is not set. +This can lead to unexpected behaviour, if the +.Dv SSL_VERIFY_PEER +and +.Dv SSL_VERIFY_NONE +are not used as required (exactly one must be set at any time). +.Pp +The certificate verification depth set with +.Fn SSL[_CTX]_verify_depth +stops the verification at a certain depth. +The error message produced will be that of an incomplete certificate chain and +not +.Dv X509_V_ERR_CERT_CHAIN_TOO_LONG +as may be expected. diff --git a/Libraries/libressl/man/SSL_CTX_use_certificate.3 b/Libraries/libressl/man/SSL_CTX_use_certificate.3 new file mode 100644 index 000000000..fac1245f1 --- /dev/null +++ b/Libraries/libressl/man/SSL_CTX_use_certificate.3 @@ -0,0 +1,451 @@ +.\" $OpenBSD: SSL_CTX_use_certificate.3,v 1.16 2021/03/31 16:53:30 tb Exp $ +.\" full merge up to: OpenSSL 3aaa1bd0 Mar 28 16:35:25 2017 +1000 +.\" selective merge up to: OpenSSL d1f7a1e6 Apr 26 14:05:40 2018 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2002, 2003, 2005 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2021 $ +.Dt SSL_CTX_USE_CERTIFICATE 3 +.Os +.Sh NAME +.Nm SSL_CTX_use_certificate , +.Nm SSL_CTX_use_certificate_ASN1 , +.Nm SSL_CTX_use_certificate_file , +.Nm SSL_use_certificate , +.Nm SSL_use_certificate_ASN1 , +.Nm SSL_use_certificate_chain_file , +.Nm SSL_use_certificate_file , +.Nm SSL_CTX_use_certificate_chain_file , +.Nm SSL_CTX_use_certificate_chain_mem , +.Nm SSL_CTX_use_PrivateKey , +.Nm SSL_CTX_use_PrivateKey_ASN1 , +.Nm SSL_CTX_use_PrivateKey_file , +.Nm SSL_CTX_use_RSAPrivateKey , +.Nm SSL_CTX_use_RSAPrivateKey_ASN1 , +.Nm SSL_CTX_use_RSAPrivateKey_file , +.Nm SSL_use_PrivateKey_file , +.Nm SSL_use_PrivateKey_ASN1 , +.Nm SSL_use_PrivateKey , +.Nm SSL_use_RSAPrivateKey , +.Nm SSL_use_RSAPrivateKey_ASN1 , +.Nm SSL_use_RSAPrivateKey_file , +.Nm SSL_CTX_check_private_key , +.Nm SSL_check_private_key +.Nd load certificate and key data +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_CTX_use_certificate "SSL_CTX *ctx" "X509 *x" +.Ft int +.Fn SSL_CTX_use_certificate_ASN1 "SSL_CTX *ctx" "int len" "unsigned char *d" +.Ft int +.Fn SSL_CTX_use_certificate_file "SSL_CTX *ctx" "const char *file" "int type" +.Ft int +.Fn SSL_use_certificate "SSL *ssl" "X509 *x" +.Ft int +.Fn SSL_use_certificate_ASN1 "SSL *ssl" "unsigned char *d" "int len" +.Ft int +.Fn SSL_use_certificate_chain_file "SSL *ssl" "const char *file" +.Ft int +.Fn SSL_use_certificate_file "SSL *ssl" "const char *file" "int type" +.Ft int +.Fn SSL_CTX_use_certificate_chain_file "SSL_CTX *ctx" "const char *file" +.Ft int +.Fn SSL_CTX_use_certificate_chain_mem "SSL_CTX *ctx" "void *buf" "int len" +.Ft int +.Fn SSL_CTX_use_PrivateKey "SSL_CTX *ctx" "EVP_PKEY *pkey" +.Ft int +.Fo SSL_CTX_use_PrivateKey_ASN1 +.Fa "int pk" "SSL_CTX *ctx" "unsigned char *d" "long len" +.Fc +.Ft int +.Fn SSL_CTX_use_PrivateKey_file "SSL_CTX *ctx" "const char *file" "int type" +.Ft int +.Fn SSL_CTX_use_RSAPrivateKey "SSL_CTX *ctx" "RSA *rsa" +.Ft int +.Fn SSL_CTX_use_RSAPrivateKey_ASN1 "SSL_CTX *ctx" "unsigned char *d" "long len" +.Ft int +.Fn SSL_CTX_use_RSAPrivateKey_file "SSL_CTX *ctx" "const char *file" "int type" +.Ft int +.Fn SSL_use_PrivateKey "SSL *ssl" "EVP_PKEY *pkey" +.Ft int +.Fn SSL_use_PrivateKey_ASN1 "int pk" "SSL *ssl" "unsigned char *d" "long len" +.Ft int +.Fn SSL_use_PrivateKey_file "SSL *ssl" "const char *file" "int type" +.Ft int +.Fn SSL_use_RSAPrivateKey "SSL *ssl" "RSA *rsa" +.Ft int +.Fn SSL_use_RSAPrivateKey_ASN1 "SSL *ssl" "const unsigned char *d" "long len" +.Ft int +.Fn SSL_use_RSAPrivateKey_file "SSL *ssl" "const char *file" "int type" +.Ft int +.Fn SSL_CTX_check_private_key "const SSL_CTX *ctx" +.Ft int +.Fn SSL_check_private_key "const SSL *ssl" +.Sh DESCRIPTION +These functions load the certificates and private keys into the +.Vt SSL_CTX +or +.Vt SSL +object, respectively. +.Pp +The +.Fn SSL_CTX_* +class of functions loads the certificates and keys into the +.Vt SSL_CTX +object +.Fa ctx . +The information is passed to +.Vt SSL +objects +.Fa ssl +created from +.Fa ctx +with +.Xr SSL_new 3 +by copying, so that changes applied to +.Fa ctx +do not propagate to already existing +.Vt SSL +objects. +.Pp +The +.Fn SSL_* +class of functions only loads certificates and keys into a specific +.Vt SSL +object. +The specific information is kept when +.Xr SSL_clear 3 +is called for this +.Vt SSL +object. +.Pp +.Fn SSL_CTX_use_certificate +loads the certificate +.Fa x +into +.Fa ctx ; +.Fn SSL_use_certificate +loads +.Fa x +into +.Fa ssl . +The rest of the certificates needed to form the complete certificate chain can +be specified using the +.Xr SSL_CTX_add_extra_chain_cert 3 +function. +.Pp +.Fn SSL_CTX_use_certificate_ASN1 +loads the ASN1 encoded certificate from the memory location +.Fa d +(with length +.Fa len ) +into +.Fa ctx ; +.Fn SSL_use_certificate_ASN1 +loads the ASN1 encoded certificate into +.Fa ssl . +.Pp +.Fn SSL_CTX_use_certificate_file +loads the first certificate stored in +.Fa file +into +.Fa ctx . +The formatting +.Fa type +of the certificate must be specified from the known types +.Dv SSL_FILETYPE_PEM +and +.Dv SSL_FILETYPE_ASN1 . +.Fn SSL_use_certificate_file +loads the certificate from +.Fa file +into +.Fa ssl . +See the +.Sx NOTES +section on why +.Fn SSL_CTX_use_certificate_chain_file +should be preferred. +.Pp +The +.Fn SSL_CTX_use_certificate_chain* +functions load a certificate chain into +.Fa ctx . +The certificates must be in PEM format and must be sorted starting with the +subject's certificate (actual client or server certificate), +followed by intermediate CA certificates if applicable, +and ending at the highest level (root) CA. +With the exception of +.Fn SSL_use_certificate_chain_file , +there is no corresponding function working on a single +.Vt SSL +object. +.Pp +.Fn SSL_CTX_use_PrivateKey +adds +.Fa pkey +as private key to +.Fa ctx . +.Fn SSL_CTX_use_RSAPrivateKey +adds the private key +.Fa rsa +of type RSA to +.Fa ctx . +.Fn SSL_use_PrivateKey +adds +.Fa pkey +as private key to +.Fa ssl ; +.Fn SSL_use_RSAPrivateKey +adds +.Fa rsa +as private key of type RSA to +.Fa ssl . +If a certificate has already been set and the private does not belong to the +certificate, an error is returned. +To change a certificate private key pair, +the new certificate needs to be set with +.Fn SSL_use_certificate +or +.Fn SSL_CTX_use_certificate +before setting the private key with +.Fn SSL_CTX_use_PrivateKey +or +.Fn SSL_use_PrivateKey . +.Pp +.Fn SSL_CTX_use_PrivateKey_ASN1 +adds the private key of type +.Fa pk +stored at memory location +.Fa d +(length +.Fa len ) +to +.Fa ctx . +.Fn SSL_CTX_use_RSAPrivateKey_ASN1 +adds the private key of type RSA stored at memory location +.Fa d +(length +.Fa len ) +to +.Fa ctx . +.Fn SSL_use_PrivateKey_ASN1 +and +.Fn SSL_use_RSAPrivateKey_ASN1 +add the private key to +.Fa ssl . +.Pp +.Fn SSL_CTX_use_PrivateKey_file +adds the first private key found in +.Fa file +to +.Fa ctx . +The formatting +.Fa type +of the private key must be specified from the known types +.Dv SSL_FILETYPE_PEM +and +.Dv SSL_FILETYPE_ASN1 . +.Fn SSL_CTX_use_RSAPrivateKey_file +adds the first private RSA key found in +.Fa file +to +.Fa ctx . +.Fn SSL_use_PrivateKey_file +adds the first private key found in +.Fa file +to +.Fa ssl ; +.Fn SSL_use_RSAPrivateKey_file +adds the first private RSA key found to +.Fa ssl . +.Pp +The +.Fn SSL_CTX_check_private_key +function is seriously misnamed. +It compares the +.Em public +key components and parameters of an OpenSSL private key with the +corresponding certificate loaded into +.Fa ctx . +If more than one key/certificate pair (RSA/DSA) is installed, +the last item installed will be compared. +If, e.g., the last item was an RSA certificate or key, +the RSA key/certificate pair will be checked. +.Fn SSL_check_private_key +performs the same +.Em public +key comparison for +.Fa ssl . +If no key/certificate was explicitly added for this +.Fa ssl , +the last item added into +.Fa ctx +will be checked. +.Pp +Despite the name, neither +.Fn SSL_CTX_check_private_key +nor +.Fn SSL_check_private_key +checks whether the private key component is indeed a private key, +nor whether it matches the public key component. +They merely compare the public materials (e.g. exponent and modulus of +an RSA key) and/or key parameters (e.g. EC params of an EC key) of a +key pair. +.Sh NOTES +The internal certificate store of OpenSSL can hold several private +key/certificate pairs at a time. +The certificate used depends on the cipher selected. +See also +.Xr SSL_CTX_set_cipher_list 3 . +.Pp +When reading certificates and private keys from file, files of type +.Dv SSL_FILETYPE_ASN1 +(also known as +.Em DER , +binary encoding) can only contain one certificate or private key; consequently, +.Fn SSL_CTX_use_certificate_chain_file +is only applicable to PEM formatting. +Files of type +.Dv SSL_FILETYPE_PEM +can contain more than one item. +.Pp +.Fn SSL_CTX_use_certificate_chain_file +adds the first certificate found in the file to the certificate store. +The other certificates are added to the store of chain certificates using +.Xr SSL_CTX_add1_chain_cert 3 . +It is recommended to use the +.Fn SSL_CTX_use_certificate_chain_file +instead of the +.Fn SSL_CTX_use_certificate_file +function in order to allow the use of complete certificate chains even when no +trusted CA storage is used or when the CA issuing the certificate shall not be +added to the trusted CA storage. +.Pp +If additional certificates are needed to complete the chain during the TLS +negotiation, CA certificates are additionally looked up in the locations of +trusted CA certificates (see +.Xr SSL_CTX_load_verify_locations 3 ) . +.Pp +The private keys loaded from file can be encrypted. +In order to successfully load encrypted keys, +a function returning the passphrase must have been supplied (see +.Xr SSL_CTX_set_default_passwd_cb 3 ) . +(Certificate files might be encrypted as well from the technical point of view, +it however does not make sense as the data in the certificate is considered +public anyway.) +.Sh RETURN VALUES +On success, the functions return 1. +Otherwise check out the error stack to find out the reason. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_add1_chain_cert 3 , +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_CTX_set_cipher_list 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr SSL_CTX_set_client_cert_cb 3 , +.Xr SSL_CTX_set_default_passwd_cb 3 , +.Xr SSL_new 3 , +.Xr X509_check_private_key 3 +.Sh HISTORY +.Fn SSL_use_certificate , +.Fn SSL_use_certificate_file , +.Fn SSL_use_RSAPrivateKey , +and +.Fn SSL_use_RSAPrivateKey_file +appeared in SSLeay 0.4 or earlier. +.Fn SSL_use_certificate_ASN1 +and +.Fn SSL_use_RSAPrivateKey_ASN1 +first appeared in SSLeay 0.5.1. +.Fn SSL_use_PrivateKey_file , +.Fn SSL_use_PrivateKey_ASN1 , +and +.Fn SSL_use_PrivateKey +first appeared in SSLeay 0.6.0. +.Fn SSL_CTX_use_certificate , +.Fn SSL_CTX_use_certificate_ASN1 , +.Fn SSL_CTX_use_certificate_file , +.Fn SSL_CTX_use_PrivateKey , +.Fn SSL_CTX_use_PrivateKey_ASN1 , +.Fn SSL_CTX_use_PrivateKey_file , +.Fn SSL_CTX_use_RSAPrivateKey , +.Fn SSL_CTX_use_RSAPrivateKey_ASN1 , +and +.Fn SSL_CTX_use_RSAPrivateKey_file +first appeared in SSLeay 0.6.1. +.Fn SSL_CTX_check_private_key +and +.Fn SSL_check_private_key +first appeared in SSLeay 0.6.5. +All these functions have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_use_certificate_chain_file +first appeared in OpenSSL 0.9.4 and has been available since +.Ox 2.6 . +.Pp +.Fn SSL_use_certificate_chain_file +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.9 . +.Pp +Support for DER encoded private keys +.Pq Dv SSL_FILETYPE_ASN1 +in +.Fn SSL_CTX_use_PrivateKey_file +and +.Fn SSL_use_PrivateKey_file +was added in 0.9.8. +.Pp +.Fn SSL_CTX_use_certificate_chain_mem +first appeared in +.Ox 5.7 . diff --git a/Libraries/libressl/man/SSL_SESSION_free.3 b/Libraries/libressl/man/SSL_SESSION_free.3 new file mode 100644 index 000000000..3f785e95e --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_free.3 @@ -0,0 +1,148 @@ +.\" $OpenBSD: SSL_SESSION_free.3,v 1.7 2019/06/12 09:36:30 schwarze Exp $ +.\" full merge up to: OpenSSL b31db505 Mar 24 16:01:50 2017 +0000 +.\" +.\" This file was written by Lutz Jaenicke +.\" and Matt Caswell . +.\" Copyright (c) 2000, 2001, 2009, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_SESSION_FREE 3 +.Os +.Sh NAME +.Nm SSL_SESSION_up_ref , +.Nm SSL_SESSION_free +.Nd SSL_SESSION reference counting +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_SESSION_up_ref "SSL_SESSION *session" +.Ft void +.Fn SSL_SESSION_free "SSL_SESSION *session" +.Sh DESCRIPTION +.Fn SSL_SESSION_up_ref +increments the reference count of the given +.Fa session +by 1. +.Pp +.Fn SSL_SESSION_free +decrements the reference count of the given +.Fa session +by 1. +If the reference count reaches 0, it frees the memory used by the +.Fa session . +If +.Fa session +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Vt SSL_SESSION +objects are allocated when a TLS/SSL handshake operation is successfully +completed. +Depending on the settings, see +.Xr SSL_CTX_set_session_cache_mode 3 , +the +.Vt SSL_SESSION +objects are internally referenced by the +.Vt SSL_CTX +and linked into its session cache. +.Vt SSL +objects may be using the +.Vt SSL_SESSION +object; as a session may be reused, several +.Vt SSL +objects may be using one +.Vt SSL_SESSION +object at the same time. +It is therefore crucial to keep the reference count (usage information) correct +and not delete a +.Vt SSL_SESSION +object that is still used, as this may lead to program failures due to dangling +pointers. +These failures may also appear delayed, e.g., when an +.Vt SSL_SESSION +object is completely freed as the reference count incorrectly becomes 0, but it +is still referenced in the internal session cache and the cache list is +processed during a +.Xr SSL_CTX_flush_sessions 3 +operation. +.Pp +.Fn SSL_SESSION_free +must only be called for +.Vt SSL_SESSION +objects, for which the reference count was explicitly incremented (e.g., by +calling +.Xr SSL_get1_session 3 ; +see +.Xr SSL_get_session 3 ) +or when the +.Vt SSL_SESSION +object was generated outside a TLS handshake operation, e.g., by using +.Xr d2i_SSL_SESSION 3 . +It must not be called on other +.Vt SSL_SESSION +objects, as this would cause incorrect reference counts and therefore program +failures. +.Sh RETURN VALUES +.Fn SSL_SESSION_up_ref +returns 1 on success or 0 on error. +.Sh SEE ALSO +.Xr d2i_SSL_SESSION 3 , +.Xr ssl 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_free +first appeared in SSLeay 0.5.2 and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_SESSION_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_SESSION_get0_cipher.3 b/Libraries/libressl/man/SSL_SESSION_get0_cipher.3 new file mode 100644 index 000000000..239a426db --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get0_cipher.3 @@ -0,0 +1,94 @@ +.\" $OpenBSD: SSL_SESSION_get0_cipher.3,v 1.1 2021/05/12 14:16:25 tb Exp $ +.\" full merge up to: OpenSSL d42e7759f Mar 30 19:40:04 2017 +0200 +.\" selective merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Rich Salz . +.\" Copyright (c) 2016, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 12 2021 $ +.Dt SSL_SESSION_GET0_CIPHER 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get0_cipher +.Nd retrieve the SSL cipher associated with a session +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const SSL_CIPHER * +.Fo SSL_SESSION_get0_cipher +.Fa "const SSL_SESSION *session" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_get0_cipher +retrieves the cipher that was used by the connection when the session +was created, or +.Dv NULL +if it cannot be determined. +.Pp +The value returned is a pointer to an object maintained within +.Fa session +and should not be released. +.Sh RETURN VALUES +.Fn SSL_SESSION_get0_cipher +returns the +.Vt SSL_CIPHER +associated with +.Fa session +or +.Dv NULL +if it cannot be determined. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CIPHER_get_name 3 , +.Xr SSL_get_current_cipher 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +The +.Fn SSL_SESSION_get0_cipher +function first appeared in OpenSSL 1.1.0 +and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/SSL_SESSION_get0_peer.3 b/Libraries/libressl/man/SSL_SESSION_get0_peer.3 new file mode 100644 index 000000000..6b1ef6680 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get0_peer.3 @@ -0,0 +1,80 @@ +.\" $OpenBSD: SSL_SESSION_get0_peer.3,v 1.2 2018/03/23 05:50:30 schwarze Exp $ +.\" OpenSSL SSL_SESSION_get0_peer.pod b31db505 Mar 24 16:01:50 2017 +0000 +.\" +.\" This file was written by Matt Caswell +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt SSL_SESSION_GET0_PEER 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get0_peer +.Nd get details about peer's certificate for a session +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft X509 * +.Fo SSL_SESSION_get0_peer +.Fa "SSL_SESSION *s" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_get0_peer +returns a pointer to the peer certificate associated with the session +.Fa s +or +.Dv NULL +if no peer certificate is available. +The caller should not free the returned value, unless +.Xr X509_up_ref 3 +has also been called. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_get0_peer +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/SSL_SESSION_get_compress_id.3 b/Libraries/libressl/man/SSL_SESSION_get_compress_id.3 new file mode 100644 index 000000000..aedc216a1 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get_compress_id.3 @@ -0,0 +1,78 @@ +.\" $OpenBSD: SSL_SESSION_get_compress_id.3,v 1.3 2018/03/23 05:50:30 schwarze Exp $ +.\" OpenSSL SSL_SESSION_get_compress_id.pod b31db505 Mar 24 16:01:50 2017 +.\" +.\" This file was written by Matt Caswell +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt SSL_SESSION_GET_COMPRESS_ID 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get_compress_id +.Nd get details about the compression associated with a session +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft unsigned int +.Fo SSL_SESSION_get_compress_id +.Fa "const SSL_SESSION *s" +.Fc +.Sh DESCRIPTION +If compression has been negotiated for an ssl session, +.Fn SSL_SESSION_get_compress_id +returns the id for the compression method, or 0 otherwise. +The only built-in supported compression method is zlib, +which has an id of 1. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_protocol_version 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_get_compress_id +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/SSL_SESSION_get_ex_new_index.3 b/Libraries/libressl/man/SSL_SESSION_get_ex_new_index.3 new file mode 100644 index 000000000..9fd6949b6 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get_ex_new_index.3 @@ -0,0 +1,134 @@ +.\" $OpenBSD: SSL_SESSION_get_ex_new_index.3,v 1.3 2018/03/21 08:06:34 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt SSL_SESSION_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get_ex_new_index , +.Nm SSL_SESSION_set_ex_data , +.Nm SSL_SESSION_get_ex_data +.Nd internal application specific data functions +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_SESSION_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fn SSL_SESSION_set_ex_data "SSL_SESSION *session" "int idx" "void *arg" +.Ft void * +.Fn SSL_SESSION_get_ex_data "const SSL_SESSION *session" "int idx" +.Bd -literal + typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); + typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); + typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, + int idx, long argl, void *argp); +.Ed +.Sh DESCRIPTION +Several OpenSSL structures can have application specific data attached to them. +These functions are used internally by OpenSSL to manipulate +application-specific data attached to a specific structure. +.Pp +.Fn SSL_SESSION_get_ex_new_index +is used to register a new index for application-specific data. +.Pp +.Fn SSL_SESSION_set_ex_data +is used to store application data at +.Fa arg +for +.Fa idx +into the +.Fa session +object. +.Pp +.Fn SSL_SESSION_get_ex_data +is used to retrieve the information for +.Fa idx +from +.Fa session . +.Pp +A detailed description for the +.Fn *_get_ex_new_index +functionality +can be found in +.Xr RSA_get_ex_new_index 3 . +The +.Fn *_get_ex_data +and +.Fn *_set_ex_data +functionality is described in +.Xr CRYPTO_set_ex_data 3 . +.Sh WARNINGS +The application data is only maintained for sessions held in memory. +The application data is not included when dumping the session with +.Xr i2d_SSL_SESSION 3 +(and all functions indirectly calling the dump functions like +.Xr PEM_write_SSL_SESSION 3 +and +.Xr PEM_write_bio_SSL_SESSION 3 ) +and can therefore not be restored. +.Sh SEE ALSO +.Xr CRYPTO_set_ex_data 3 , +.Xr RSA_get_ex_new_index 3 , +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_SESSION_get_ex_new_index , +.Fn SSL_SESSION_set_ex_data , +and +.Fn SSL_SESSION_get_ex_data +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_SESSION_get_id.3 b/Libraries/libressl/man/SSL_SESSION_get_id.3 new file mode 100644 index 000000000..6d0de1e52 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get_id.3 @@ -0,0 +1,112 @@ +.\" $OpenBSD: SSL_SESSION_get_id.3,v 1.6 2018/03/24 00:55:37 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL SSL_SESSION_set1_id 17b60280 Dec 21 09:08:25 2017 +0100 +.\" +.\" This file was written by Remi Gacogne +.\" and Matt Caswell . +.\" Copyright (c) 2016, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 24 2018 $ +.Dt SSL_SESSION_GET_ID 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get_id , +.Nm SSL_SESSION_set1_id +.Nd get and set the SSL session ID +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const unsigned char * +.Fo SSL_SESSION_get_id +.Fa "const SSL_SESSION *s" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo SSL_SESSION_set1_id +.Fa "SSL_SESSION *s" +.Fa "const unsigned char *sid" +.Fa "unsigned int sid_len" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_get_id +returns a pointer to the internal session ID value for the session +.Fa s . +The length of the ID in bytes is stored in +.Pf * Fa len . +The length may be 0. +The caller should not free the returned pointer directly. +.Pp +.Fn SSL_SESSION_set1_id +sets the session ID for +.Fa s +to a copy of the +.Fa sid +of length +.Fa sid_len . +.Sh RETURN VALUES +.Fn SSL_SESSION_get_id +returns a pointer to the session ID value. +.Pp +.Fn SSL_SESSION_set1_id +returns 1 for success and 0 for failure, +for example if the supplied session ID length exceeds +.Dv SSL_MAX_SSL_SESSION_ID_LENGTH . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_copy_session_id 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_get_compress_id 3 , +.Xr SSL_SESSION_get_protocol_version 3 , +.Xr SSL_SESSION_has_ticket 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_get_id +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . +.Pp +.Fn SSL_SESSION_set1_id +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_SESSION_get_protocol_version.3 b/Libraries/libressl/man/SSL_SESSION_get_protocol_version.3 new file mode 100644 index 000000000..f14c0490e --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get_protocol_version.3 @@ -0,0 +1,84 @@ +.\" $OpenBSD: SSL_SESSION_get_protocol_version.3,v 1.2 2018/03/24 00:55:37 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by TJ Saunders +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 24 2018 $ +.Dt SSL_SESSION_GET_PROTOCOL_VERSION 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get_protocol_version +.Nd get the session protocol version +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_SESSION_get_protocol_version +.Fa "const SSL_SESSION *s" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_get_protocol_version +returns the protocol version number used by the session +.Fa s . +.Sh RETURN VALUES +.Fn SSL_SESSION_get_protocol_version +returns a constant like +.Dv TLS1_VERSION +or +.Dv TLS1_2_VERSION . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_get0_peer 3 , +.Xr SSL_SESSION_get_compress_id 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_get_protocol_version +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_SESSION_get_time.3 b/Libraries/libressl/man/SSL_SESSION_get_time.3 new file mode 100644 index 000000000..aaadec513 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_get_time.3 @@ -0,0 +1,165 @@ +.\" $OpenBSD: SSL_SESSION_get_time.3,v 1.8 2019/06/08 15:25:43 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005, 2006, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 8 2019 $ +.Dt SSL_SESSION_GET_TIME 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get_time , +.Nm SSL_SESSION_set_time , +.Nm SSL_SESSION_get_timeout , +.Nm SSL_SESSION_set_timeout , +.Nm SSL_get_time , +.Nm SSL_set_time , +.Nm SSL_get_timeout , +.Nm SSL_set_timeout +.Nd retrieve and manipulate session time and timeout settings +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_SESSION_get_time "const SSL_SESSION *s" +.Ft long +.Fn SSL_SESSION_set_time "SSL_SESSION *s" "long tm" +.Ft long +.Fn SSL_SESSION_get_timeout "const SSL_SESSION *s" +.Ft long +.Fn SSL_SESSION_set_timeout "SSL_SESSION *s" "long tm" +.Ft long +.Fn SSL_get_time "const SSL_SESSION *s" +.Ft long +.Fn SSL_set_time "SSL_SESSION *s" "long tm" +.Ft long +.Fn SSL_get_timeout "const SSL_SESSION *s" +.Ft long +.Fn SSL_set_timeout "SSL_SESSION *s" "long tm" +.Sh DESCRIPTION +.Fn SSL_SESSION_get_time +returns the time at which the session +.Fa s +was established. +The time is given in seconds since the Epoch and therefore compatible to the +time delivered by the +.Xr time 3 +call. +.Pp +.Fn SSL_SESSION_set_time +replaces the creation time of the session +.Fa s +with +the chosen value +.Fa tm . +.Pp +.Fn SSL_SESSION_get_timeout +returns the timeout value set for session +.Fa s +in seconds. +.Pp +.Fn SSL_SESSION_set_timeout +sets the timeout value for session +.Fa s +in seconds to +.Fa tm . +.Pp +The +.Fn SSL_get_time , +.Fn SSL_set_time , +.Fn SSL_get_timeout , +and +.Fn SSL_set_timeout +functions are synonyms for the +.Fn SSL_SESSION_* +counterparts. +.Pp +Sessions are expired by examining the creation time and the timeout value. +Both are set at creation time of the session to the actual time and the default +timeout value at creation, respectively, as set by +.Xr SSL_CTX_set_timeout 3 . +Using these functions it is possible to extend or shorten the lifetime of the +session. +.Sh RETURN VALUES +.Fn SSL_SESSION_get_time +and +.Fn SSL_SESSION_get_timeout +return the currently valid values. +.Pp +.Fn SSL_SESSION_set_time +and +.Fn SSL_SESSION_set_timeout +return 1 on success. +.Pp +If any of the function is passed the +.Dv NULL +pointer for the session +.Fa s , +0 is returned. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_timeout 3 , +.Xr SSL_get_default_timeout 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_has_ticket 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_get_time , +.Fn SSL_get_timeout , +and +.Fn SSL_set_timeout +appeared in SSLeay 0.4 or earlier. +.Fn SSL_set_time +first appeared in SSLeay 0.5.2. +.Fn SSL_SESSION_get_time , +.Fn SSL_SESSION_set_time , +.Fn SSL_SESSION_get_timeout , +and +.Fn SSL_SESSION_set_timeout +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_SESSION_has_ticket.3 b/Libraries/libressl/man/SSL_SESSION_has_ticket.3 new file mode 100644 index 000000000..322b49fee --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_has_ticket.3 @@ -0,0 +1,85 @@ +.\" $OpenBSD: SSL_SESSION_has_ticket.3,v 1.2 2018/03/24 00:55:37 schwarze Exp $ +.\" full merge up to: OpenSSL f2baac27 Feb 8 15:43:16 2015 +0000 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 24 2018 $ +.Dt SSL_SESSION_HAS_TICKET 3 +.Os +.Sh NAME +.Nm SSL_SESSION_has_ticket , +.Nm SSL_SESSION_get_ticket_lifetime_hint +.Nd get details about the ticket associated with a session +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_SESSION_has_ticket +.Fa "const SSL_SESSION *s" +.Fc +.Ft unsigned long +.Fo SSL_SESSION_get_ticket_lifetime_hint +.Fa "const SSL_SESSION *s" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_has_ticket +returns 1 if there is a Session Ticket associated with +.Fa s +or 0 otherwise. +.Pp +.Fn SSL_SESSION_get_ticket_lifetime_hint +returns the lifetime hint in seconds associated with the session ticket. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_SESSION_is_resumable.3 b/Libraries/libressl/man/SSL_SESSION_is_resumable.3 new file mode 100644 index 000000000..48d7d1788 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_is_resumable.3 @@ -0,0 +1,81 @@ +.\" $OpenBSD: SSL_SESSION_is_resumable.3,v 1.1 2021/09/14 14:08:15 schwarze Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 14 2021 $ +.Dt SSL_SESSION_IS_RESUMABLE 3 +.Os +.Sh NAME +.Nm SSL_SESSION_is_resumable +.Nd determine whether an SSL_SESSION object can be used for resumption +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_SESSION_is_resumable +.Fa "const SSL_SESSION *session" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_is_resumable +determines whether the +.Fa session +object can be used to resume a session. +Note that attempting to resume with a non-resumable session +will result in a full handshake. +.Sh RETURN VALUES +.Fn SSL_SESSION_is_resumable +returns 1 if the session is resumable or 0 otherwise. +It always returns 0 with LibreSSL. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_sess_set_new_cb 3 , +.Xr SSL_get_session 3 +.Sh HISTORY +.Fn SSL_SESSION_is_resumable +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/SSL_SESSION_new.3 b/Libraries/libressl/man/SSL_SESSION_new.3 new file mode 100644 index 000000000..2dcdb264c --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_new.3 @@ -0,0 +1,78 @@ +.\" $OpenBSD: SSL_SESSION_new.3,v 1.9 2021/09/14 14:08:15 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 14 2021 $ +.Dt SSL_SESSION_NEW 3 +.Os +.Sh NAME +.Nm SSL_SESSION_new +.Nd construct a new SSL_SESSION object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_SESSION * +.Fn SSL_SESSION_new void +.Sh DESCRIPTION +.Fn SSL_SESSION_new +allocates and initializes a new +.Vt SSL_SESSION +object. +The reference count is set to 1, the time to the current time, and +the timeout to five minutes. +.Pp +When the object is no longer needed, it can be destructed with +.Xr SSL_SESSION_free 3 . +.Pp +.Fn SSL_SESSION_new +is used internally, for example by +.Xr SSL_connect 3 . +.Sh RETURN VALUES +.Fn SSL_SESSION_new +returns the new +.Vt SSL_SESSION +object or +.Dv NULL +if insufficient memory is available. +.Pp +After failure, +.Xr ERR_get_error 3 +returns +.Dv ERR_R_MALLOC_FAILURE . +.Sh SEE ALSO +.Xr d2i_SSL_SESSION 3 , +.Xr PEM_read_SSL_SESSION 3 , +.Xr ssl 3 , +.Xr SSL_connect 3 , +.Xr SSL_copy_session_id 3 , +.Xr SSL_CTX_add_session 3 , +.Xr SSL_CTX_sess_set_get_cb 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_free 3 , +.Xr SSL_SESSION_get0_peer 3 , +.Xr SSL_SESSION_get_compress_id 3 , +.Xr SSL_SESSION_get_ex_new_index 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_master_key 3 , +.Xr SSL_SESSION_get_protocol_version 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_has_ticket 3 , +.Xr SSL_SESSION_is_resumable 3 , +.Xr SSL_SESSION_print 3 , +.Xr SSL_SESSION_set1_id_context 3 , +.Xr SSL_set_session 3 +.Sh HISTORY +.Fn SSL_SESSION_new +first appeared in SSLeay 0.5.2 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_SESSION_print.3 b/Libraries/libressl/man/SSL_SESSION_print.3 new file mode 100644 index 000000000..e92debde0 --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_print.3 @@ -0,0 +1,74 @@ +.\" $OpenBSD: SSL_SESSION_print.3,v 1.4 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_SESSION_PRINT 3 +.Os +.Sh NAME +.Nm SSL_SESSION_print , +.Nm SSL_SESSION_print_fp +.Nd print some properties of an SSL_SESSION object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_SESSION_print +.Fa "BIO *bp" +.Fa "const SSL_SESSION *session" +.Fc +.Ft int +.Fo SSL_SESSION_print_fp +.Fa "FILE *fp" +.Fa "const SSL_SESSION *session" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_print +prints some properties of +.Fa session +in a human-readable format to the +.Fa "BIO *bp" , +including protocol version, cipher name, session ID, +session ID context, master key, session ticket lifetime hint, +session ticket, start time, timeout, and verify return code. +.Pp +.Fn SSL_SESSION_print_fp +does the same as +.Fn SSL_SESSION_print +except that it prints to the +.Fa "FILE *fp" . +.Sh RETURN VALUES +.Fn SSL_SESSION_print +and +.Fn SSL_SESSION_print_fp +return 1 for success or 0 for failure. +.Pp +In some cases, the reason for failure can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_SSL_SESSION 3 , +.Xr PEM_read_SSL_SESSION 3 , +.Xr ssl 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_free 3 , +.Xr SSL_SESSION_get_ex_new_index 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_print +first appeared in SSLeay 0.5.2. +.Fn SSL_SESSION_print_fp +first appeared in SSLeay 0.6.0. +Both functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_SESSION_set1_id_context.3 b/Libraries/libressl/man/SSL_SESSION_set1_id_context.3 new file mode 100644 index 000000000..dd7595bac --- /dev/null +++ b/Libraries/libressl/man/SSL_SESSION_set1_id_context.3 @@ -0,0 +1,113 @@ +.\" $OpenBSD: SSL_SESSION_set1_id_context.3,v 1.4 2018/03/24 00:55:37 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL SSL_SESSION_get0_id_context b31db505 Mar 24 16:01:50 2017 +.\" +.\" This file was written by Matt Caswell +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 24 2018 $ +.Dt SSL_SESSION_SET1_ID_CONTEXT 3 +.Os +.Sh NAME +.Nm SSL_SESSION_get0_id_context , +.Nm SSL_SESSION_set1_id_context +.Nd get and set the SSL ID context associated with a session +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const unsigned char * +.Fo SSL_SESSION_get0_id_context +.Fa "const SSL_SESSION *s" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo SSL_SESSION_set1_id_context +.Fa "SSL_SESSION *s" +.Fa "const unsigned char *sid_ctx" +.Fa "unsigned int sid_ctx_len" +.Fc +.Sh DESCRIPTION +.Fn SSL_SESSION_get0_id_context +returns the ID context associated with +.Fa s . +The length of the ID context in bytes is written to +.Pf * Fa len +if +.Fa len +is not +.Dv NULL . +.Pp +.Fn SSL_SESSION_set1_id_context +takes a copy of the provided ID context given in +.Fa sid_ctx +and associates it with the session +.Fa s . +The length of the ID context is given by +.Fa sid_ctx_len +which must not exceed +.Dv SSL_MAX_SID_CTX_LENGTH +bytes. +.Sh RETURN VALUES +.Fn SSL_SESSION_get0_id_context +returns an internal pointer to an object maintained within +.Fa s +that should not be freed by the caller. +.Pp +.Fn SSL_SESSION_set1_id_context +returns 1 on success or 0 on error. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_session_id_context 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +.Fn SSL_SESSION_set1_id_context +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . +.Pp +.Fn SSL_SESSION_get0_id_context +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_accept.3 b/Libraries/libressl/man/SSL_accept.3 new file mode 100644 index 000000000..fb1d89eb5 --- /dev/null +++ b/Libraries/libressl/man/SSL_accept.3 @@ -0,0 +1,155 @@ +.\" $OpenBSD: SSL_accept.3,v 1.6 2019/06/08 15:25:43 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2002, 2003 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 8 2019 $ +.Dt SSL_ACCEPT 3 +.Os +.Sh NAME +.Nm SSL_accept +.Nd wait for a TLS/SSL client to initiate a TLS/SSL handshake +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_accept "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_accept +waits for a TLS/SSL client to initiate the TLS/SSL handshake. +The communication channel must already have been set and assigned to the +.Fa ssl +object by setting an underlying +.Vt BIO . +.Pp +The behaviour of +.Fn SSL_accept +depends on the underlying +.Vt BIO . +.Pp +If the underlying +.Vt BIO +is +.Em blocking , +.Fn SSL_accept +will only return once the handshake has been finished or an error occurred. +.Pp +If the underlying +.Vt BIO +is +.Em non-blocking , +.Fn SSL_accept +will also return when the underlying +.Vt BIO +could not satisfy the needs of +.Fn SSL_accept +to continue the handshake, indicating the problem by the return value \(mi1. +In this case a call to +.Xr SSL_get_error 3 +with the +return value of +.Fn SSL_accept +will yield +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE . +The calling process then must repeat the call after taking appropriate action +to satisfy the needs of +.Fn SSL_accept . +The action depends on the underlying +.Dv BIO . +When using a non-blocking socket, nothing is to be done, but +.Xr select 2 +can be used to check for the required condition. +When using a buffering +.Vt BIO , +like a +.Vt BIO +pair, data must be written into or retrieved out of the +.Vt BIO +before being able to continue. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The TLS/SSL handshake was not successful but was shut down controlled and by +the specifications of the TLS/SSL protocol. +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.It 1 +The TLS/SSL handshake was successfully completed, +and a TLS/SSL connection has been established. +.It <0 +The TLS/SSL handshake was not successful because a fatal error occurred either +at the protocol level or a connection failure occurred. +The shutdown was not clean. +It can also occur of action is need to continue the operation for non-blocking +.Vt BIO Ns +s. +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_connect 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_do_handshake 3 , +.Xr SSL_get_error 3 , +.Xr SSL_set_connect_state 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_accept +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_alert_type_string.3 b/Libraries/libressl/man/SSL_alert_type_string.3 new file mode 100644 index 000000000..79cbdaa98 --- /dev/null +++ b/Libraries/libressl/man/SSL_alert_type_string.3 @@ -0,0 +1,244 @@ +.\" $OpenBSD: SSL_alert_type_string.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2011 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_ALERT_TYPE_STRING 3 +.Os +.Sh NAME +.Nm SSL_alert_type_string , +.Nm SSL_alert_type_string_long , +.Nm SSL_alert_desc_string , +.Nm SSL_alert_desc_string_long +.Nd get textual description of alert information +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const char * +.Fn SSL_alert_type_string "int value" +.Ft const char * +.Fn SSL_alert_type_string_long "int value" +.Ft const char * +.Fn SSL_alert_desc_string "int value" +.Ft const char * +.Fn SSL_alert_desc_string_long "int value" +.Sh DESCRIPTION +.Fn SSL_alert_type_string +returns a one letter string indicating the type of the alert specified by +.Fa value . +.Pp +.Fn SSL_alert_type_string_long +returns a string indicating the type of the alert specified by +.Fa value . +.Pp +.Fn SSL_alert_desc_string +returns a two letter string as a short form describing the reason of the alert +specified by +.Fa value . +.Pp +.Fn SSL_alert_desc_string_long +returns a string describing the reason of the alert specified by +.Fa value . +.Pp +When one side of an SSL/TLS communication wants to inform the peer about +a special situation, it sends an alert. +The alert is sent as a special message and does not influence the normal data +stream (unless its contents results in the communication being canceled). +.Pp +A warning alert is sent, when a non-fatal error condition occurs. +The +.Dq close notify +alert is sent as a warning alert. +Other examples for non-fatal errors are certificate errors +.Po +.Dq certificate expired , +.Dq unsupported certificate +.Pc , +for which a warning alert may be sent. +(The sending party may, however, decide to send a fatal error.) +The receiving side may cancel the connection on reception of a warning alert at +its discretion. +.Pp +Several alert messages must be sent as fatal alert messages as specified +by the TLS RFC. +A fatal alert always leads to a connection abort. +.Sh RETURN VALUES +The following strings can occur for +.Fn SSL_alert_type_string +or +.Fn SSL_alert_type_string_long : +.Bl -tag -width Ds +.It \(dqW\(dq/\(dqwarning\(dq +.It \(dqF\(dq/\(dqfatal\(dq +.It \(dqU\(dq/\(dqunknown\(dq +This indicates that no support is available for this alert type. +Probably +.Fa value +does not contain a correct alert message. +.El +.Pp +The following strings can occur for +.Fn SSL_alert_desc_string +or +.Fn SSL_alert_desc_string_long : +.Bl -tag -width Ds +.It \(dqCN\(dq/\(dqclose notify\(dq +The connection shall be closed. +This is a warning alert. +.It \(dqUM\(dq/\(dqunexpected message\(dq +An inappropriate message was received. +This alert is always fatal and should never be observed in communication +between proper implementations. +.It \(dqBM\(dq/\(dqbad record mac\(dq +This alert is returned if a record is received with an incorrect MAC. +This message is always fatal. +.It \(dqDF\(dq/\(dqdecompression failure\(dq +The decompression function received improper input +(e.g., data that would expand to excessive length). +This message is always fatal. +.It \(dqHF\(dq/\(dqhandshake failure\(dq +Reception of a handshake_failure alert message indicates that the sender was +unable to negotiate an acceptable set of security parameters given the options +available. +This is a fatal error. +.It \(dqNC\(dq/\(dqno certificate\(dq +A client, that was asked to send a certificate, does not send a certificate +(SSLv3 only). +.It \(dqBC\(dq/\(dqbad certificate\(dq +A certificate was corrupt, contained signatures that did not verify correctly, +etc. +.It \(dqUC\(dq/\(dqunsupported certificate\(dq +A certificate was of an unsupported type. +.It \(dqCR\(dq/\(dqcertificate revoked\(dq +A certificate was revoked by its signer. +.It \(dqCE\(dq/\(dqcertificate expired\(dq +A certificate has expired or is not currently valid. +.It \(dqCU\(dq/\(dqcertificate unknown\(dq +Some other (unspecified) issue arose in processing the certificate, +rendering it unacceptable. +.It \(dqIP\(dq/\(dqillegal parameter\(dq +A field in the handshake was out of range or inconsistent with other fields. +This is always fatal. +.It \(dqDC\(dq/\(dqdecryption failed\(dq +A TLSCiphertext decrypted in an invalid way: either it wasn't an even multiple +of the block length or its padding values, when checked, weren't correct. +This message is always fatal. +.It \(dqRO\(dq/\(dqrecord overflow\(dq +A TLSCiphertext record was received which had a length more than +2^14+2048 bytes, or a record decrypted to a TLSCompressed record with more than +2^14+1024 bytes. +This message is always fatal. +.It \(dqCA\(dq/\(dqunknown CA\(dq +A valid certificate chain or partial chain was received, +but the certificate was not accepted because the CA certificate could not be +located or couldn't be matched with a known, trusted CA. +This message is always fatal. +.It \(dqAD\(dq/\(dqaccess denied\(dq +A valid certificate was received, but when access control was applied, +the sender decided not to proceed with negotiation. +This message is always fatal. +.It \(dqDE\(dq/\(dqdecode error\(dq +A message could not be decoded because some field was out of the specified +range or the length of the message was incorrect. +This message is always fatal. +.It \(dqCY\(dq/\(dqdecrypt error\(dq +A handshake cryptographic operation failed, including being unable to correctly +verify a signature, decrypt a key exchange, or validate a finished message. +.It \(dqER\(dq/\(dqexport restriction\(dq +A negotiation not in compliance with export restrictions was detected; +for example, attempting to transfer a 1024 bit ephemeral RSA key for the +RSA_EXPORT handshake method. +This message is always fatal. +.It \(dqPV\(dq/\(dqprotocol version\(dq +The protocol version the client has attempted to negotiate is recognized, +but not supported. +(For example, old protocol versions might be avoided for security reasons.) +This message is always fatal. +.It \(dqIS\(dq/\(dqinsufficient security\(dq +Returned instead of handshake_failure when a negotiation has failed +specifically because the server requires ciphers more secure than those +supported by the client. +This message is always fatal. +.It \(dqIE\(dq/\(dqinternal error\(dq +An internal error unrelated to the peer or the correctness of the protocol +makes it impossible to continue (such as a memory allocation failure). +This message is always fatal. +.It \(dqUS\(dq/\(dquser canceled\(dq +This handshake is being canceled for some reason unrelated to a protocol +failure. +If the user cancels an operation after the handshake is complete, +just closing the connection by sending a close_notify is more appropriate. +This alert should be followed by a close_notify. +This message is generally a warning. +.It \(dqNR\(dq/\(dqno renegotiation\(dq +Sent by the client in response to a hello request or by the server in response +to a client hello after initial handshaking. +Either of these would normally lead to renegotiation; when that is not +appropriate, the recipient should respond with this alert; at that point, +the original requester can decide whether to proceed with the connection. +One case where this would be appropriate would be where a server has spawned a +process to satisfy a request; the process might receive security parameters +(key length, authentication, etc.) at startup and it might be difficult to +communicate changes to these parameters after that point. +This message is always a warning. +.It \(dqUP\(dq/\(dqunknown PSK identity\(dq +Sent by the server to indicate that it does not recognize a PSK identity or an +SRP identity. +.It \(dqUK\(dq/\(dqunknown\(dq +This indicates that no description is available for this alert type. +Probably +.Fa value +does not contain a correct alert message. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_info_callback 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.8.0 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_clear.3 b/Libraries/libressl/man/SSL_clear.3 new file mode 100644 index 000000000..809c3b20f --- /dev/null +++ b/Libraries/libressl/man/SSL_clear.3 @@ -0,0 +1,144 @@ +.\" $OpenBSD: SSL_clear.3,v 1.5 2021/06/11 19:41:39 jmc Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2002, 2011, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 11 2021 $ +.Dt SSL_CLEAR 3 +.Os +.Sh NAME +.Nm SSL_clear +.Nd reset SSL object to allow another connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_clear "SSL *ssl" +.Sh DESCRIPTION +Reset +.Fa ssl +to allow another connection. +All settings (method, ciphers, BIOs) are kept. +.Pp +.Fn SSL_clear +is used to prepare an +.Vt SSL +object for a new connection. +While all settings are kept, +a side effect is the handling of the current SSL session. +If a session is still +.Em open , +it is considered bad and will be removed from the session cache, +as required by RFC 2246. +A session is considered open if +.Xr SSL_shutdown 3 +was not called for the connection or at least +.Xr SSL_set_shutdown 3 +was used to +set the +.Dv SSL_SENT_SHUTDOWN +state. +.Pp +If a session was closed cleanly, +the session object will be kept and all settings corresponding. +This explicitly means that for example the special method used during the +session will be kept for the next handshake. +So if the session was a TLSv1 session, a +.Vt SSL +client object will use a TLSv1 client method for the next handshake and a +.Vt SSL +server object will use a TLSv1 server method, even if +.Fn TLS_*_method Ns s +were chosen on startup. +This might lead to connection failures (see +.Xr SSL_new 3 ) +for a description of the method's properties. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The +.Fn SSL_clear +operation could not be performed. +Check the error stack to find out the reason. +.It 1 +The +.Fn SSL_clear +operation was successful. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_client_cert_cb 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_free 3 , +.Xr SSL_new 3 , +.Xr SSL_set_shutdown 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_clear +first appeared in SSLeay 0.4.5b and has been available since +.Ox 2.4 . +.Sh CAVEATS +.Fn SSL_clear +resets the +.Vt SSL +object to allow for another connection. +The reset operation however keeps several settings of the last sessions +(some of these settings were made automatically during the last handshake). +It only makes sense for a new connection with the exact same peer that shares +these settings, +and may fail if that peer changes its settings between connections. +Use the sequence +.Xr SSL_get_session 3 ; +.Xr SSL_new 3 ; +.Xr SSL_set_session 3 ; +.Xr SSL_free 3 +instead to avoid such failures (or simply +.Xr SSL_free 3 ; +.Xr SSL_new 3 +if session reuse is not desired). diff --git a/Libraries/libressl/man/SSL_connect.3 b/Libraries/libressl/man/SSL_connect.3 new file mode 100644 index 000000000..d5b962a48 --- /dev/null +++ b/Libraries/libressl/man/SSL_connect.3 @@ -0,0 +1,154 @@ +.\" $OpenBSD: SSL_connect.3,v 1.6 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2002, 2003 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_CONNECT 3 +.Os +.Sh NAME +.Nm SSL_connect +.Nd initiate the TLS/SSL handshake with a TLS/SSL server +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_connect "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_connect +initiates the TLS/SSL handshake with a server. +The communication channel must already have been set and assigned to the +.Fa ssl +by setting an underlying +.Vt BIO . +.Pp +The behaviour of +.Fn SSL_connect +depends on the underlying +.Vt BIO . +.Pp +If the underlying +.Vt BIO +is +.Em blocking , +.Fn SSL_connect +will only return once the handshake has been finished or an error occurred. +.Pp +If the underlying +.Vt BIO +is +.Em non-blocking , +.Fn SSL_connect +will also return when the underlying +.Vt BIO +could not satisfy the needs of +.Fn SSL_connect +to continue the handshake, indicating the problem with the return value \(mi1. +In this case a call to +.Xr SSL_get_error 3 +with the return value of +.Fn SSL_connect +will yield +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE . +The calling process then must repeat the call after taking appropriate action +to satisfy the needs of +.Fn SSL_connect . +The action depends on the underlying +.Vt BIO . +When using a non-blocking socket, nothing is to be done, but +.Xr select 2 +can be used to check for the required condition. +When using a buffering +.Vt BIO , +like a +.Vt BIO +pair, data must be written into or retrieved out of the +.Vt BIO +before being able to continue. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The TLS/SSL handshake was not successful but was shut down controlled and +by the specifications of the TLS/SSL protocol. +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.It 1 +The TLS/SSL handshake was successfully completed, +and a TLS/SSL connection has been established. +.It <0 +The TLS/SSL handshake was not successful, because either a fatal error occurred +at the protocol level or a connection failure occurred. +The shutdown was not clean. +It can also occur if action is needed to continue the operation for +non-blocking +.Vt BIO Ns s . +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_do_handshake 3 , +.Xr SSL_get_error 3 , +.Xr SSL_set_connect_state 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_connect +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_copy_session_id.3 b/Libraries/libressl/man/SSL_copy_session_id.3 new file mode 100644 index 000000000..a7a7a8aa9 --- /dev/null +++ b/Libraries/libressl/man/SSL_copy_session_id.3 @@ -0,0 +1,79 @@ +.\" $OpenBSD: SSL_copy_session_id.3,v 1.7 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_COPY_SESSION_ID 3 +.Os +.Sh NAME +.Nm SSL_copy_session_id +.Nd copy session details between SSL objects +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_copy_session_id +.Fa "SSL *to" +.Fa "const SSL *from" +.Fc +.Sh DESCRIPTION +.Fn SSL_copy_session_id +copies the following data from +.Fa from +to +.Fa to : +.Bl -dash +.It +the pointer to the +.Vt SSL_SESSION +object, incrementing its reference count by 1 +.It +the pointer to the +.Vt SSL_METHOD +object; if that changes the method, protocol-specific data is +reinitialized +.It +the pointer to the +.Vt CERT +object, incrementing its reference count by 1 +.It +the session ID context +.El +.Pp +This function is used internally by +.Xr SSL_dup 3 +and by +.Xr BIO_ssl_copy_session_id 3 . +.Sh RETURN VALUES +.Fn SSL_copy_session_id +returns 1 on success and 0 on error. +.Sh SEE ALSO +.Xr BIO_ssl_copy_session_id 3 , +.Xr ssl 3 , +.Xr SSL_dup 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_new 3 , +.Xr SSL_set_session 3 , +.Xr SSL_set_session_id_context 3 +.Sh HISTORY +.Fn SSL_copy_session_id +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . +.Sh BUGS +Failures of +.Xr CRYPTO_add 3 +are silently ignored and may leave +.Fa to +in an invalid or inconsistent state. diff --git a/Libraries/libressl/man/SSL_do_handshake.3 b/Libraries/libressl/man/SSL_do_handshake.3 new file mode 100644 index 000000000..e9327b422 --- /dev/null +++ b/Libraries/libressl/man/SSL_do_handshake.3 @@ -0,0 +1,152 @@ +.\" $OpenBSD: SSL_do_handshake.3,v 1.6 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Martin Sjoegren . +.\" Copyright (c) 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_DO_HANDSHAKE 3 +.Os +.Sh NAME +.Nm SSL_do_handshake +.Nd perform a TLS/SSL handshake +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_do_handshake "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_do_handshake +will wait for a SSL/TLS handshake to take place. +If the connection is in client mode, the handshake will be started. +The handshake routines may have to be explicitly set in advance using either +.Xr SSL_set_connect_state 3 +or +.Xr SSL_set_accept_state 3 . +.Pp +The behaviour of +.Fn SSL_do_handshake +depends on the underlying +.Vt BIO . +.Pp +If the underlying +.Vt BIO +is +.Em blocking , +.Fn SSL_do_handshake +will only return once the handshake has been finished or an error occurred. +.Pp +If the underlying +.Vt BIO +is +.Em non-blocking , +.Fn SSL_do_handshake +will also return when the underlying +.Vt BIO +could not satisfy the needs of +.Fn SSL_do_handshake +to continue the handshake. +In this case a call to +.Xr SSL_get_error 3 +with the return value of +.Fn SSL_do_handshake +will yield +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE . +The calling process then must repeat the call after taking appropriate action +to satisfy the needs of +.Fn SSL_do_handshake . +The action depends on the underlying +.Vt BIO . +When using a non-blocking socket, nothing is to be done, but +.Xr select 2 +can be used to check for the required condition. +When using a buffering +.Vt BIO , +like a +.Vt BIO +pair, data must be written into or retrieved out of the +.Vt BIO +before being able to continue. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The TLS/SSL handshake was not successful but was shut down controlled and +by the specifications of the TLS/SSL protocol. +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.It 1 +The TLS/SSL handshake was successfully completed, +and a TLS/SSL connection has been established. +.It <0 +The TLS/SSL handshake was not successful because either a fatal error occurred +at the protocol level or a connection failure occurred. +The shutdown was not clean. +It can also occur if action is needed to continue the operation for +non-blocking +.Vt BIO Ns s . +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_get_error 3 , +.Xr SSL_set_connect_state 3 +.Sh HISTORY +.Fn SSL_do_handshake +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_dup.3 b/Libraries/libressl/man/SSL_dup.3 new file mode 100644 index 000000000..a83440b43 --- /dev/null +++ b/Libraries/libressl/man/SSL_dup.3 @@ -0,0 +1,62 @@ +.\" $OpenBSD: SSL_dup.3,v 1.5 2022/07/13 22:05:53 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt SSL_DUP 3 +.Os +.Sh NAME +.Nm SSL_dup +.Nd deep copy of an SSL object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL * +.Fo SSL_dup +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +.Fn SSL_dup +constructs a new +.Vt SSL +object in the same context as +.Fa ssl +and copies much of the contained data from +.Fa ssl +to the new +.Vt SSL +object, but many fields, for example tlsext data, are not copied. +.Pp +As an exception from deep copying, if a session is already established, +the new object shares +.Fa ssl->cert +with the original object. +.Sh RETURN VALUES +.Fn SSL_dup +returns the new +.Vt SSL +object or +.Dv NULL +on failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_copy_session_id 3 , +.Xr SSL_free 3 , +.Xr SSL_new 3 , +.Xr SSL_set_security_level 3 +.Sh HISTORY +.Fn SSL_dup +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_dup_CA_list.3 b/Libraries/libressl/man/SSL_dup_CA_list.3 new file mode 100644 index 000000000..d073b0717 --- /dev/null +++ b/Libraries/libressl/man/SSL_dup_CA_list.3 @@ -0,0 +1,54 @@ +.\" $OpenBSD: SSL_dup_CA_list.3,v 1.6 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_DUP_CA_LIST 3 +.Os +.Sh NAME +.Nm SSL_dup_CA_list +.Nd deep copy of a stack of X.509 Name objects +.\" The capital "N" in "Name" is intentional (X.509 syntax). +.Sh SYNOPSIS +.Ft STACK_OF(X509_NAME) * +.Fo SSL_dup_CA_list +.Fa "const STACK_OF(X509_NAME) *sk" +.Fc +.Sh DESCRIPTION +.Fn SSL_dup_CA_list +constructs a new +.Vt STACK_OF(X509_NAME) +object and places copies of all the +.Vt X509_NAME +objects found on +.Fa sk +on it. +.Sh RETURN VALUES +.Fn SSL_dup_CA_list +returns the new +.Vt STACK_OF(X509_NAME) +or +.Dv NULL +on failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr SSL_get_client_CA_list 3 , +.Xr SSL_load_client_CA_file 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn SSL_dup_CA_list +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_export_keying_material.3 b/Libraries/libressl/man/SSL_export_keying_material.3 new file mode 100644 index 000000000..e32a5c5d6 --- /dev/null +++ b/Libraries/libressl/man/SSL_export_keying_material.3 @@ -0,0 +1,133 @@ +.\" $OpenBSD: SSL_export_keying_material.3,v 1.3 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL a599574b Jun 28 17:18:27 2017 +0100 +.\" OpenSSL 23cec1f4 Jun 21 13:55:02 2017 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_EXPORT_KEYING_MATERIAL 3 +.Os +.Sh NAME +.Nm SSL_export_keying_material +.Nd obtain keying material for application use +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_export_keying_material +.Fa "SSL *s" +.Fa "unsigned char *out" +.Fa "size_t olen" +.Fa "const char *label" +.Fa "size_t llen" +.Fa "const unsigned char *context" +.Fa "size_t contextlen" +.Fa "int use_context" +.Fc +.Sh DESCRIPTION +During the creation of a TLS or DTLS connection, +shared keying material is established between the two endpoints. +The function +.Fn SSL_export_keying_material +enables an application to use some of this keying material +for its own purposes in accordance with RFC 5705. +.Pp +An application may need to securely establish the context +within which this keying material will be used. +For example, this may include identifiers for the application session, +application algorithms or parameters, or the lifetime of the context. +The context value is left to the application but must be the same on +both sides of the communication. +.Pp +For a given SSL connection +.Fa s , +.Fa olen +bytes of data will be written to +.Fa out . +The application specific context should be supplied +in the location pointed to by +.Fa context +and should be +.Fa contextlen +bytes long. +Provision of a context is optional. +If the context should be omitted entirely, then +.Fa use_context +should be set to 0. +Otherwise it should be any other value. +If +.Fa use_context +is 0, then the values of +.Fa context +and +.Fa contextlen +are ignored. +.Pp +In TLSv1.2 and below, a zero length context is treated differently +from no context at all, and will result in different keying material +being returned. +.Pp +An application specific label should be provided in the location pointed +to by +.Fa label +and should be +.Fa llen +bytes long. +Typically this will be a value from the +.Lk https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#exporter-labels "IANA Exporter Label Registry" . +.Pp +Alternatively, labels beginning with "EXPERIMENTAL" are permitted by the +standard to be used without registration. +.Sh RETURN VALUES +.Fn SSL_export_keying_material +returns 1 on success or 0 or -1 on failure. +.Sh SEE ALSO +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_export_keying_material +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/SSL_free.3 b/Libraries/libressl/man/SSL_free.3 new file mode 100644 index 000000000..c713ded12 --- /dev/null +++ b/Libraries/libressl/man/SSL_free.3 @@ -0,0 +1,115 @@ +.\" $OpenBSD: SSL_free.3,v 1.6 2021/06/11 19:41:39 jmc Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 11 2021 $ +.Dt SSL_FREE 3 +.Os +.Sh NAME +.Nm SSL_free +.Nd free an allocated SSL structure +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_free "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_free +decrements the reference count of +.Fa ssl , +and removes the +.Vt SSL +structure pointed to by +.Fa ssl +and frees up the allocated memory if the reference count has reached 0. +If +.Fa ssl +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn SSL_free +also calls the +.Xr free 3 Ns +ing procedures for indirectly affected items, if applicable: the buffering +.Vt BIO , +the read and write +.Vt BIOs , +cipher lists specially created for this +.Fa ssl , +the +.Sy SSL_SESSION . +Do not explicitly free these indirectly freed up items before or after calling +.Fn SSL_free , +as trying to free things twice may lead to program failure. +.Pp +The +.Fa ssl +session has reference counts from two users: the +.Vt SSL +object, for which the reference count is removed by +.Fn SSL_free +and the internal session cache. +If the session is considered bad, because +.Xr SSL_shutdown 3 +was not called for the connection and +.Xr SSL_set_shutdown 3 +was not used to set the +.Vt SSL_SENT_SHUTDOWN +state, the session will also be removed from the session cache as required by +RFC 2246. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_new 3 , +.Xr SSL_set_shutdown 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_free +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_SSL_CTX.3 b/Libraries/libressl/man/SSL_get_SSL_CTX.3 new file mode 100644 index 000000000..60fda555b --- /dev/null +++ b/Libraries/libressl/man/SSL_get_SSL_CTX.3 @@ -0,0 +1,79 @@ +.\" $OpenBSD: SSL_get_SSL_CTX.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_SSL_CTX 3 +.Os +.Sh NAME +.Nm SSL_get_SSL_CTX +.Nd get the SSL_CTX from which an SSL is created +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_CTX * +.Fn SSL_get_SSL_CTX "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_SSL_CTX +returns a pointer to the +.Vt SSL_CTX +object from which +.Fa ssl +was created with +.Xr SSL_new 3 . +.Sh RETURN VALUES +The pointer to the +.Vt SSL_CTX +object is returned. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_new 3 +.Sh HISTORY +.Fn SSL_get_SSL_CTX +first appeared in SSLeay 0.5.1 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_certificate.3 b/Libraries/libressl/man/SSL_get_certificate.3 new file mode 100644 index 000000000..eb53ea49b --- /dev/null +++ b/Libraries/libressl/man/SSL_get_certificate.3 @@ -0,0 +1,64 @@ +.\" $OpenBSD: SSL_get_certificate.3,v 1.5 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_GET_CERTIFICATE 3 +.Os +.Sh NAME +.Nm SSL_get_certificate , +.Nm SSL_get_privatekey +.Nd get SSL certificate and private key +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft X509 * +.Fo SSL_get_certificate +.Fa "const SSL *ssl" +.Fc +.Ft EVP_PKEY * +.Fo SSL_get_privatekey +.Fa "const SSL *ssl" +.Fc +.Sh DESCRIPTION +These functions retrieve certificate and key data from an +.Vt SSL +object. +They return internal pointers that must not be freed by the application +program. +.Sh RETURN VALUES +.Fn SSL_get_certificate +returns the active X.509 certificate currently used by +.Fa ssl +or +.Dv NULL +if none is active. +.Pp +.Fn SSL_get_privatekey +returns the active private key currently used by +.Fa ssl +or +.Dv NULL +if none is active. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_check_private_key 3 , +.Xr SSL_use_certificate 3 +.Sh HISTORY +.Fn SSL_get_certificate +first appeared in SSLeay 0.5.2a. +.Fn SSL_get_privatekey +first appeared in SSLeay 0.8.0. +Both functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_ciphers.3 b/Libraries/libressl/man/SSL_get_ciphers.3 new file mode 100644 index 000000000..8030f0bbb --- /dev/null +++ b/Libraries/libressl/man/SSL_get_ciphers.3 @@ -0,0 +1,249 @@ +.\" $OpenBSD: SSL_get_ciphers.3,v 1.11 2020/09/16 07:25:15 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" selective merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Lutz Jaenicke , +.\" Nick Mathewson , Kurt Roeckx , +.\" Kazuki Yamaguchi , and Benjamin Kaduk . +.\" Copyright (c) 2000, 2005, 2015, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 16 2020 $ +.Dt SSL_GET_CIPHERS 3 +.Os +.Sh NAME +.Nm SSL_get_ciphers , +.Nm SSL_CTX_get_ciphers , +.Nm SSL_get1_supported_ciphers , +.Nm SSL_get_client_ciphers , +.Nm SSL_get_cipher_list +.Nd get lists of available SSL_CIPHERs +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft STACK_OF(SSL_CIPHER) * +.Fn SSL_get_ciphers "const SSL *ssl" +.Ft STACK_OF(SSL_CIPHER) * +.Fn SSL_CTX_get_ciphers "const SSL_CTX *ctx" +.Ft STACK_OF(SSL_CIPHER) * +.Fn SSL_get1_supported_ciphers "SSL *ssl" +.Ft STACK_OF(SSL_CIPHER) * +.Fn SSL_get_client_ciphers "const SSL *ssl" +.Ft const char * +.Fn SSL_get_cipher_list "const SSL *ssl" "int priority" +.Sh DESCRIPTION +.Fn SSL_get_ciphers +returns the stack of available +.Vt SSL_CIPHER Ns s +for +.Fa ssl , +sorted by preference. +.Pp +.Fn SSL_CTX_get_ciphers +returns the stack of available +.Vt SSL_CIPHER Ns s +for +.Fa ctx . +.Pp +.Fn SSL_get1_supported_ciphers +returns a stack of enabled +.Vt SSL_CIPHER Ns s +for +.Fa ssl +as it would be sent in a ClientHello, sorted by preference. +The list depends on settings like the cipher list, the supported +protocol versions, the security level, and the enabled signature +algorithms. +The list of ciphers that would be sent in a ClientHello can differ +from the list of ciphers that would be acceptable when acting as a +server. +For example, +additional ciphers may be usable by a server if there is a gap in the +list of supported protocols, and some ciphers may not be usable by a +server if there is not a suitable certificate configured. +.Pp +.Fn SSL_get_client_ciphers +returns the stack of available +.Vt SSL_CIPHER Ns s +matching the list received from the client on +.Fa ssl . +.Pp +The details of the ciphers obtained by +.Fn SSL_get_ciphers , +.Fn SSL_CTX_get_ciphers , +.Fn SSL_get1_supported_ciphers , +and +.Fn SSL_get_client_ciphers +can be obtained using the +.Xr SSL_CIPHER_get_name 3 +family of functions. +.Pp +.Fn SSL_get_cipher_list +is deprecated \(em use +.Fn SSL_get_ciphers +instead \(em and badly misnamed; it does not return a list +but the name of one element of the return value of +.Fn SSL_get_ciphers , +with the index given by the +.Fa priority +argument. +Passing 0 selects the cipher with the highest priority. +To iterate over all available ciphers in decreasing priority, +repeatedly increment the argument by 1 until +.Dv NULL +is returned. +.Sh RETURN VALUES +.Fn SSL_get_ciphers +returns an internal pointer to a list of ciphers or +.Dv NULL +if +.Fa ssl +is +.Dv NULL +or if no ciphers are available. +The returned pointer may not only become invalid when +.Fa ssl +is destroyed or when +.Xr SSL_set_cipher_list 3 +is called on it, but also when the +.Vt SSL_CTX +object in use by +.Fa ssl +at the time of the call is freed or when +.Xr SSL_CTX_set_cipher_list 3 +is called on that context object. +.Pp +.Fn SSL_CTX_get_ciphers +returns an internal pointer to a list of ciphers or +.Dv NULL +if +.Fa ctx +is +.Dv NULL +or if no ciphers are available. +The returned pointer becomes invalid when +.Fa ctx +is destroyed or when +.Xr SSL_CTX_set_cipher_list 3 +is called on it. +.Pp +.Fn SSL_get1_supported_ciphers +returns a newly allocated list of ciphers or +.Dv NULL +if +.Fa ssl +is +.Dv NULL , +if no ciphers are available, or if an error occurs. +When the returned pointer is no longer needed, the caller is +responsible for freeing it using +.Fn sk_SSL_CIPHER_free . +.Pp +.Fn SSL_get_client_ciphers +returns an internal pointer to a list of ciphers or +.Dv NULL +if +.Fa ssl +is +.Dv NULL , +has no active session, +or is not operating in server mode. +The returned pointer becomes invalid when the +.Vt SSL_SESSION +object is destroyed, even if the +.Fa ssl +object remains valid. +It may also become invalid in other circumstances, +for example when processing a new ClientHello. +.Pp +.Fn SSL_get_cipher_list +returns an internal pointer to a string or +.Dv NULL +if +.Fa ssl +is +.Dv NULL , +if no ciphers are available, or if +.Fa priority +is greater than or equal to the number of available ciphers. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CIPHER_get_name 3 , +.Xr SSL_CTX_set_cipher_list 3 +.Sh HISTORY +.Fn SSL_get_cipher_list +first appeared in SSLeay 0.5.2. +.Fn SSL_get_ciphers +first appeared in SSLeay 0.8.0. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn SSL_CTX_get_ciphers +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Pp +.Fn SSL_get1_supported_ciphers +and +.Fn SSL_get_client_ciphers +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.5 . diff --git a/Libraries/libressl/man/SSL_get_client_CA_list.3 b/Libraries/libressl/man/SSL_get_client_CA_list.3 new file mode 100644 index 000000000..e80e5cb6f --- /dev/null +++ b/Libraries/libressl/man/SSL_get_client_CA_list.3 @@ -0,0 +1,96 @@ +.\" $OpenBSD: SSL_get_client_CA_list.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2002, 2005 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_CLIENT_CA_LIST 3 +.Os +.Sh NAME +.Nm SSL_get_client_CA_list , +.Nm SSL_CTX_get_client_CA_list +.Nd get list of client CAs +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft STACK_OF(X509_NAME) * +.Fn SSL_get_client_CA_list "const SSL *s" +.Ft STACK_OF(X509_NAME) * +.Fn SSL_CTX_get_client_CA_list "const SSL_CTX *ctx" +.Sh DESCRIPTION +.Fn SSL_CTX_get_client_CA_list +returns the list of client CAs explicitly set for +.Fa ctx +using +.Xr SSL_CTX_set_client_CA_list 3 . +.Pp +.Fn SSL_get_client_CA_list +returns the list of client CAs explicitly set for +.Fa ssl +using +.Fn SSL_set_client_CA_list +or +.Fa ssl Ns 's +.Vt SSL_CTX +object with +.Xr SSL_CTX_set_client_CA_list 3 , +when in server mode. +In client mode, +.Fn SSL_get_client_CA_list +returns the list of client CAs sent from the server, if any. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr SSL_CTX_set_client_cert_cb 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn SSL_get_client_CA_list +and +.Fn SSL_CTX_get_client_CA_list +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_client_random.3 b/Libraries/libressl/man/SSL_get_client_random.3 new file mode 100644 index 000000000..eda74db35 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_client_random.3 @@ -0,0 +1,150 @@ +.\" $OpenBSD: SSL_get_client_random.3,v 1.2 2018/03/24 00:55:37 schwarze Exp $ +.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 +.\" +.\" This file was written by Nick Mathewson +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 24 2018 $ +.Dt SSL_GET_CLIENT_RANDOM 3 +.Os +.Sh NAME +.Nm SSL_get_client_random , +.Nm SSL_get_server_random , +.Nm SSL_SESSION_get_master_key +.Nd get internal TLS handshake random values and master key +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft size_t +.Fo SSL_get_client_random +.Fa "const SSL *ssl" +.Fa "unsigned char *out" +.Fa "size_t outlen" +.Fc +.Ft size_t +.Fo SSL_get_server_random +.Fa "const SSL *ssl" +.Fa "unsigned char *out" +.Fa "size_t outlen" +.Fc +.Ft size_t +.Fo SSL_SESSION_get_master_key +.Fa "const SSL_SESSION *session" +.Fa "unsigned char *out" +.Fa "size_t outlen" +.Fc +.Sh DESCRIPTION +.Fn SSL_get_client_random +extracts the random value that was sent from the client to the server +during the initial TLS handshake. +It copies at most +.Fa outlen +bytes of this value into the buffer +.Fa out . +If +.Fa outlen +is zero, nothing is copied. +.Pp +.Fn SSL_get_server_random +behaves the same, but extracts the random value that was sent +from the server to the client during the initial TLS handshake. +.Pp +.Fn SSL_SESSION_get_master_key +behaves the same, but extracts the master secret used to guarantee the +security of the TLS session. +The security of the TLS session depends on keeping the master key +secret: do not expose it, or any information about it, to anybody. +To calculate another secret value that depends on the master secret, +use +.Xr SSL_export_keying_material 3 +instead. +.Pp +All these functions expose internal values from the TLS handshake, +for use in low-level protocols. +Avoid using them unless implementing a feature +that requires access to the internal protocol details. +.Pp +Despite the names of +.Fn SSL_get_client_random +and +.Fn SSL_get_server_random , +they are not random number generators. +Instead, they return the mostly-random values that were already +generated and used in the TLS protocol. +.Pp +In current versions of the TLS protocols, +the length of client_random and server_random is always +.Dv SSL3_RANDOM_SIZE +bytes. +Support for other +.Fa outlen +arguments is provided for the unlikely event that a future +version or variant of TLS uses some other length. +.Pp +Finally, though the client_random and server_random values are called +.Dq random , +many TLS implementations generate four bytes of those values +based on their view of the current time. +.Sh RETURN VALUES +If +.Fa outlen +is greater than 0, these functions return the number of bytes +actually copied, which is less than or equal to +.Fa outlen . +If +.Fa outlen +is 0, these functions return the maximum number of bytes they would +copy \(em that is, the length of the underlying field. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_export_keying_material 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_get_current_cipher.3 b/Libraries/libressl/man/SSL_get_current_cipher.3 new file mode 100644 index 000000000..6b951d03c --- /dev/null +++ b/Libraries/libressl/man/SSL_get_current_cipher.3 @@ -0,0 +1,122 @@ +.\" $OpenBSD: SSL_get_current_cipher.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2005, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_CURRENT_CIPHER 3 +.Os +.Sh NAME +.Nm SSL_get_current_cipher , +.Nm SSL_get_cipher , +.Nm SSL_get_cipher_name , +.Nm SSL_get_cipher_bits , +.Nm SSL_get_cipher_version +.Nd get SSL_CIPHER of a connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const SSL_CIPHER * +.Fn SSL_get_current_cipher "const SSL *ssl" +.Ft const char * +.Fn SSL_get_cipher "const SSL *ssl" +.Ft const char * +.Fn SSL_get_cipher_name "const SSL *ssl" +.Ft int +.Fn SSL_get_cipher_bits "const SSL *ssl" "int *np" +.Ft char * +.Fn SSL_get_cipher_version "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_current_cipher +returns a pointer to an +.Vt SSL_CIPHER +object containing the description of the actually used cipher of a connection +established with the +.Fa ssl +object. +See +.Xr SSL_CIPHER_get_name 3 +for more details. +.Pp +.Fn SSL_get_cipher_name +obtains the name of the currently used cipher. +.Fn SSL_get_cipher +is identical to +.Fn SSL_get_cipher_name . +.Pp +.Fn SSL_get_cipher_bits +obtains the number of secret/algorithm bits used and +.Fn SSL_get_cipher_version +returns the protocol name. +.Pp +.Fn SSL_get_cipher , +.Fn SSL_get_cipher_name , +.Fn SSL_get_cipher_bits , +and +.Fn SSL_get_cipher_version +are implemented as macros. +.Sh RETURN VALUES +.Fn SSL_get_current_cipher +returns the cipher actually used, or +.Dv NULL +if no session has been established. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CIPHER_get_name 3 +.Sh HISTORY +.Fn SSL_get_cipher +appeared in SSLeay 0.4 or earlier. +.Fn SSL_get_cipher_bits +first appeared in SSLeay 0.6.4. +.Fn SSL_get_cipher_name +and +.Fn SSL_get_cipher_version +first appeared in SSLeay 0.8.0. +.Fn SSL_get_current_cipher +first appeared in SSLeay 0.8.1. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_default_timeout.3 b/Libraries/libressl/man/SSL_get_default_timeout.3 new file mode 100644 index 000000000..47737d8ee --- /dev/null +++ b/Libraries/libressl/man/SSL_get_default_timeout.3 @@ -0,0 +1,85 @@ +.\" $OpenBSD: SSL_get_default_timeout.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_DEFAULT_TIMEOUT 3 +.Os +.Sh NAME +.Nm SSL_get_default_timeout +.Nd get default session timeout value +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_get_default_timeout "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_default_timeout +returns the default timeout value assigned to +.Vt SSL_SESSION +objects negotiated for the protocol valid for +.Fa ssl . +.Pp +Whenever a new session is negotiated, it is assigned a timeout value, +after which it will not be accepted for session reuse. +If the timeout value was not explicitly set using +.Xr SSL_CTX_set_timeout 3 , +the hardcoded default timeout for the protocol will be used. +.Pp +.Fn SSL_get_default_timeout +return this hardcoded value, which is 300 seconds for all currently supported +protocols (SSLv2, SSLv3, and TLSv1). +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_SESSION_get_time 3 +.Sh HISTORY +.Fn SSL_get_default_timeout +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_error.3 b/Libraries/libressl/man/SSL_get_error.3 new file mode 100644 index 000000000..5d325b3f5 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_error.3 @@ -0,0 +1,217 @@ +.\" $OpenBSD: SSL_get_error.3,v 1.5 2018/04/29 07:37:01 guenther Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Bodo Moeller . +.\" Copyright (c) 2000, 2001, 2002, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 29 2018 $ +.Dt SSL_GET_ERROR 3 +.Os +.Sh NAME +.Nm SSL_get_error +.Nd obtain result code for TLS/SSL I/O operation +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_get_error "const SSL *ssl" "int ret" +.Sh DESCRIPTION +.Fn SSL_get_error +returns a result code (suitable for the C +.Dq switch +statement) for a preceding call to +.Xr SSL_connect 3 , +.Xr SSL_accept 3 , +.Xr SSL_do_handshake 3 , +.Xr SSL_read 3 , +.Xr SSL_peek 3 , +or +.Xr SSL_write 3 +on +.Fa ssl . +The value returned by that TLS/SSL I/O function must be passed to +.Fn SSL_get_error +in parameter +.Fa ret . +.Pp +In addition to +.Fa ssl +and +.Fa ret , +.Fn SSL_get_error +inspects the current thread's OpenSSL error queue. +Thus, +.Fn SSL_get_error +must be used in the same thread that performed the TLS/SSL I/O operation, +and no other OpenSSL function calls should appear in between. +The current thread's error queue must be empty before the TLS/SSL I/O operation +is attempted, or +.Fn SSL_get_error +will not work reliably. +.Sh RETURN VALUES +The following return values can currently occur: +.Bl -tag -width Ds +.It Dv SSL_ERROR_NONE +The TLS/SSL I/O operation completed. +This result code is returned if and only if +.Fa ret +> 0. +.It Dv SSL_ERROR_ZERO_RETURN +The TLS/SSL connection has been closed. +If the protocol version is SSL 3.0 or TLS 1.0, this result code is returned +only if a closure alert has occurred in the protocol, i.e., if the connection +has been closed cleanly. +Note that in this case +.Dv SSL_ERROR_ZERO_RETURN +does not necessarily indicate that the underlying transport has been closed. +.It Dv SSL_ERROR_WANT_READ , Dv SSL_ERROR_WANT_WRITE +The operation did not complete; +the same TLS/SSL I/O function should be called again later. +If, by then, the underlying +.Vt BIO +has data available for reading (if the result code is +.Dv SSL_ERROR_WANT_READ ) +or allows writing data +.Pq Dv SSL_ERROR_WANT_WRITE , +then some TLS/SSL protocol progress will take place, +i.e., at least part of a TLS/SSL record will be read or written. +Note that the retry may again lead to a +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE +condition. +There is no fixed upper limit for the number of iterations that may be +necessary until progress becomes visible at application protocol level. +.Pp +For socket +.Fa BIO Ns +s (e.g., when +.Fn SSL_set_fd +was used), +.Xr select 2 +or +.Xr poll 2 +on the underlying socket can be used to find out when the TLS/SSL I/O function +should be retried. +.Pp +Caveat: Any TLS/SSL I/O function can lead to either of +.Dv SSL_ERROR_WANT_READ +and +.Dv SSL_ERROR_WANT_WRITE . +In particular, +.Xr SSL_read 3 +or +.Xr SSL_peek 3 +may want to write data and +.Xr SSL_write 3 +may want +to read data. +This is mainly because TLS/SSL handshakes may occur at any time during the +protocol (initiated by either the client or the server); +.Xr SSL_read 3 , +.Xr SSL_peek 3 , +and +.Xr SSL_write 3 +will handle any pending handshakes. +.It Dv SSL_ERROR_WANT_CONNECT , Dv SSL_ERROR_WANT_ACCEPT +The operation did not complete; the same TLS/SSL I/O function should be +called again later. +The underlying BIO was not connected yet to the peer and the call would block +in +.Xr connect 2 Ns / Ns +.Xr accept 2 . +The SSL function should be +called again when the connection is established. +These messages can only appear with a +.Xr BIO_s_connect 3 +or +.Xr BIO_s_accept 3 +.Vt BIO , +respectively. +In order to find out when the connection has been successfully established, +on many platforms +.Xr select 2 +or +.Xr poll 2 +for writing on the socket file descriptor can be used. +.It Dv SSL_ERROR_WANT_X509_LOOKUP +The operation did not complete because an application callback set by +.Xr SSL_CTX_set_client_cert_cb 3 +has asked to be called again. +The TLS/SSL I/O function should be called again later. +Details depend on the application. +.It Dv SSL_ERROR_SYSCALL +Some I/O error occurred. +The OpenSSL error queue may contain more information on the error. +If the error queue is empty (i.e., +.Fn ERR_get_error +returns 0), +.Fa ret +can be used to find out more about the error: +If +.Fa ret +== 0, an +.Dv EOF +was observed that violates the protocol. +If +.Fa ret +== \(mi1, the underlying +.Vt BIO +reported an +I/O error (for socket I/O on Unix systems, consult +.Dv errno +for details). +.It Dv SSL_ERROR_SSL +A failure in the SSL library occurred, usually a protocol error. +The OpenSSL error queue contains more information on the error. +.El +.Sh SEE ALSO +.Xr err 3 , +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_get_error +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 b/Libraries/libressl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 new file mode 100644 index 000000000..a249cda6a --- /dev/null +++ b/Libraries/libressl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 @@ -0,0 +1,116 @@ +.\" $OpenBSD: SSL_get_ex_data_X509_STORE_CTX_idx.3,v 1.5 2022/02/06 00:29:02 jsg Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: February 6 2022 $ +.Dt SSL_GET_EX_DATA_X509_STORE_CTX_IDX 3 +.Os +.Sh NAME +.Nm SSL_get_ex_data_X509_STORE_CTX_idx +.Nd get ex_data index to access SSL structure from X509_STORE_CTX +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_get_ex_data_X509_STORE_CTX_idx void +.Sh DESCRIPTION +.Fn SSL_get_ex_data_X509_STORE_CTX_idx +returns the index number under which the pointer to the +.Vt SSL +object is stored into the +.Vt X509_STORE_CTX +object. +.Pp +Whenever a +.Vt X509_STORE_CTX +object is created for the verification of the peer's certificate during a +handshake, a pointer to the +.Vt SSL +object is stored into the +.Vt X509_STORE_CTX +object to identify the connection affected. +To retrieve this pointer the +.Xr X509_STORE_CTX_get_ex_data 3 +function can be used with the correct index. +This index is globally the same for all +.Vt X509_STORE_CTX +objects and can be retrieved using +.Fn SSL_get_ex_data_X509_STORE_CTX_idx . +The index value is set when +.Fn SSL_get_ex_data_X509_STORE_CTX_idx +is first called either by the application program directly or indirectly during +other SSL setup functions or during the handshake. +.Pp +The value depends on other index values defined for +.Vt X509_STORE_CTX +objects before the SSL index is created. +.Sh RETURN VALUES +.Bl -tag -width Ds +.It \(>=0 +The index value to access the pointer. +.It <0 +An error occurred, check the error stack for a detailed error message. +.El +.Sh EXAMPLES +The index returned from +.Fn SSL_get_ex_data_X509_STORE_CTX_idx +provides access to +.Vt SSL +object for the connection during the +.Fn verify_callback +when checking the peer's certificate. +Check the example in +.Xr SSL_CTX_set_verify 3 . +.Sh SEE ALSO +.Xr CRYPTO_set_ex_data 3 , +.Xr ssl 3 , +.Xr SSL_CTX_set_verify 3 +.Sh HISTORY +.Fn SSL_get_ex_data_X509_STORE_CTX_idx +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/SSL_get_ex_new_index.3 b/Libraries/libressl/man/SSL_get_ex_new_index.3 new file mode 100644 index 000000000..cecd25fa4 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_ex_new_index.3 @@ -0,0 +1,136 @@ +.\" $OpenBSD: SSL_get_ex_new_index.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm SSL_get_ex_new_index , +.Nm SSL_set_ex_data , +.Nm SSL_get_ex_data +.Nd internal application specific data functions +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fn SSL_set_ex_data "SSL *ssl" "int idx" "void *arg" +.Ft void * +.Fn SSL_get_ex_data "const SSL *ssl" "int idx" +.Bd -literal +typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, + int idx, long argl, void *argp); +.Ed +.Sh DESCRIPTION +Several OpenSSL structures can have application specific data attached to them. +These functions are used internally by OpenSSL to manipulate application +specific data attached to a specific structure. +.Pp +.Fn SSL_get_ex_new_index +is used to register a new index for application specific data. +.Pp +.Fn SSL_set_ex_data +is used to store application data at +.Fa arg +for +.Fa idx +into the +.Fa ssl +object. +.Pp +.Fn SSL_get_ex_data +is used to retrieve the information for +.Fa idx +from +.Fa ssl . +.Pp +A detailed description for the +.Fn *_get_ex_new_index +functionality can be found in +.Xr RSA_get_ex_new_index 3 . +The +.Fn *_get_ex_data +and +.Fn *_set_ex_data +functionality is described in +.Xr CRYPTO_set_ex_data 3 . +.Sh EXAMPLES +An example of how to use the functionality is included in the example +.Fn verify_callback +in +.Xr SSL_CTX_set_verify 3 . +.Sh SEE ALSO +.Xr CRYPTO_set_ex_data 3 , +.Xr RSA_get_ex_new_index 3 , +.Xr ssl 3 , +.Xr SSL_CTX_set_verify 3 +.Sh HISTORY +Precursor functions +.Fn SSL_set_app_data +and +.Fn SSL_get_app_data +first appeared in SSLeay 0.6.1. +.Pp +.Fn SSL_get_ex_new_index , +.Fn SSL_set_ex_data , +and +.Fn SSL_get_ex_data +first appeared in SSLeay 0.9.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_fd.3 b/Libraries/libressl/man/SSL_get_fd.3 new file mode 100644 index 000000000..1e093424c --- /dev/null +++ b/Libraries/libressl/man/SSL_get_fd.3 @@ -0,0 +1,103 @@ +.\" $OpenBSD: SSL_get_fd.3,v 1.6 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2005, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_FD 3 +.Os +.Sh NAME +.Nm SSL_get_fd , +.Nm SSL_get_rfd , +.Nm SSL_get_wfd +.Nd get file descriptor linked to an SSL object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_get_fd "const SSL *ssl" +.Ft int +.Fn SSL_get_rfd "const SSL *ssl" +.Ft int +.Fn SSL_get_wfd "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_fd +returns the file descriptor which is linked to +.Fa ssl . +.Fn SSL_get_rfd +and +.Fn SSL_get_wfd +return the file descriptors for the read or the write channel, +which can be different. +If the read and the write channel are different, +.Fn SSL_get_fd +will return the file descriptor of the read channel. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It \(mi1 +The operation failed, because the underlying +.Vt BIO +is not of the correct type (suitable for file descriptors). +.It \(>=0 +The file descriptor linked to +.Fa ssl . +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_set_fd 3 +.Sh HISTORY +.Fn SSL_get_fd +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_get_rfd +and +.Fn SSL_get_wfd +first appeared in OpenSSL 0.9.6c and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/SSL_get_finished.3 b/Libraries/libressl/man/SSL_get_finished.3 new file mode 100644 index 000000000..3cfb655ea --- /dev/null +++ b/Libraries/libressl/man/SSL_get_finished.3 @@ -0,0 +1,77 @@ +.\" $OpenBSD: SSL_get_finished.3,v 1.2 2021/01/30 10:48:15 tb Exp $ +.\" +.\" Copyright (c) 2020 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 30 2021 $ +.Dt SSL_GET_FINISHED 3 +.Os +.Sh NAME +.Nm SSL_get_finished , +.Nm SSL_get_peer_finished +.Nd get last sent or last expected finished message +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft size_t +.Fn SSL_get_finished "const SSL *ssl" "void *buf" "size_t count" +.Ft size_t +.Fn SSL_get_peer_finished "const SSL *ssl" "void *buf" "size_t count" +.Sh DESCRIPTION +.Fn SSL_get_finished +and +.Fn SSL_get_peer_finished +copy +.Fa count +bytes from the last finished message sent to the peer +or expected from the peer into the +caller-provided buffer +.Fa buf . +.Pp +The finished message is computed from a checksum of the handshake records +exchanged with the peer. +Its length depends on the ciphersuite in use and is at most +.Dv EVP_MAX_MD_SIZE , +i.e., 64 bytes. +.\" In TLSv1.3 the length is equal to the length of the hash algorithm +.\" used by the hash-based message authentication code (HMAC), +.\" which is currently either 32 bytes for SHA-256 or 48 bytes for SHA-384. +.\" In TLSv1.2 the length defaults to 12 bytes, but it can explicitly be +.\" specified by the ciphersuite to be longer. +.\" In TLS versions 1.1 and 1.0, the finished message has a fixed length +.\" of 12 bytes. +.Sh RETURN VALUES +.Fn SSL_get_finished +and +.Fn SSL_get_peer_finished +return the number of bytes copied into +.Fa buf . +The return value is zero if the handshake has not reached the +finished message. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_session 3 , +.Xr SSL_set_session 3 +.Sh STANDARDS +RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3, +section 4.4.4: Finished. +.Pp +RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2, +section 7.4.9: Finished. +.Sh HISTORY +.Fn SSL_get_finished +and +.Fn SSL_get_peer_finished +first appeared in SSLeay 0.9.5 +and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/SSL_get_peer_cert_chain.3 b/Libraries/libressl/man/SSL_get_peer_cert_chain.3 new file mode 100644 index 000000000..eb2ae53dc --- /dev/null +++ b/Libraries/libressl/man/SSL_get_peer_cert_chain.3 @@ -0,0 +1,107 @@ +.\" $OpenBSD: SSL_get_peer_cert_chain.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL SSL_get_peer_cert_chain.pod 1f164c6f Jan 18 01:40:36 2017 +0100 +.\" OpenSSL SSL_get_peer_cert_chain.pod 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2005, 2014, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_PEER_CERT_CHAIN 3 +.Os +.Sh NAME +.Nm SSL_get_peer_cert_chain +.Nd get the X509 certificate chain sent by the peer +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft STACK_OF(X509) * +.Fn SSL_get_peer_cert_chain "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_peer_cert_chain +returns a pointer to +.Dv STACK_OF Ns Po Vt X509 Pc +certificates forming the certificate chain of the peer. +If called on the client side, the stack also contains the peer's certificate; +if called on the server side, the peer's certificate must be obtained +separately using +.Xr SSL_get_peer_certificate 3 . +If the peer did not present a certificate, +.Dv NULL +is returned. +.Pp +.Fn SSL_get_peer_cert_chain +returns the peer chain as sent by the peer: it only consists of +certificates the peer has sent (in the order the peer has sent them) +and it is not a verified chain. +.Pp +If the session is resumed, peers do not send certificates, so a +.Dv NULL +pointer is returned. +Applications can call +.Fn SSL_session_reused +to determine whether a session is resumed. +.Pp +The reference count of the +.Dv STACK_OF Ns Po Vt X509 Pc +object is not incremented. +If the corresponding session is freed, the pointer must not be used any longer. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It Dv NULL +No certificate was presented by the peer or no connection was established or +the certificate chain is no longer available when a session is reused. +.It Pointer to a Dv STACK_OF Ns Po X509 Pc +The return value points to the certificate chain presented by the peer. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_peer_certificate 3 +.Sh HISTORY +.Fn SSL_get_peer_cert_chain +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_peer_certificate.3 b/Libraries/libressl/man/SSL_get_peer_certificate.3 new file mode 100644 index 000000000..99f933028 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_peer_certificate.3 @@ -0,0 +1,105 @@ +.\" $OpenBSD: SSL_get_peer_certificate.3,v 1.6 2021/06/26 17:36:28 tb Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 26 2021 $ +.Dt SSL_GET_PEER_CERTIFICATE 3 +.Os +.Sh NAME +.Nm SSL_get_peer_certificate +.Nd get the X509 certificate of the peer +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft X509 * +.Fn SSL_get_peer_certificate "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_peer_certificate +returns a pointer to the X509 certificate the peer presented. +If the peer did not present a certificate, +.Dv NULL +is returned. +.Pp +Due to the protocol definition, a TLS/SSL server will always send a +certificate, if present. +A client will only send a certificate when explicitly requested to do so by the +server (see +.Xr SSL_CTX_set_verify 3 ) . +If an anonymous cipher is used, no certificates are sent. +.Pp +That a certificate is returned does not indicate information about the +verification state. +Use +.Xr SSL_get_verify_result 3 +to check the verification state. +.Pp +The reference count of the +.Vt X509 +object is incremented by one, so that it will not be destroyed when the session +containing the peer certificate is freed. +The +.Vt X509 +object must be explicitly freed using +.Xr X509_free 3 . +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It Dv NULL +No certificate was presented by the peer or no connection was established. +.It Pointer to an X509 certificate +The return value points to the certificate presented by the peer. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr SSL_get0_peername 3 , +.Xr SSL_get_verify_result 3 +.Sh HISTORY +.Fn SSL_get_peer_certificate +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_rbio.3 b/Libraries/libressl/man/SSL_get_rbio.3 new file mode 100644 index 000000000..38096fbec --- /dev/null +++ b/Libraries/libressl/man/SSL_get_rbio.3 @@ -0,0 +1,98 @@ +.\" $OpenBSD: SSL_get_rbio.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_GET_RBIO 3 +.Os +.Sh NAME +.Nm SSL_get_rbio , +.Nm SSL_get_wbio +.Nd get BIO linked to an SSL object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft BIO * +.Fn SSL_get_rbio "SSL *ssl" +.Ft BIO * +.Fn SSL_get_wbio "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_rbio +and +.Fn SSL_get_wbio +return pointers to the +.Vt BIO Ns s +for the read or the write channel, which can be different. +The reference count of the +.Vt BIO +is not incremented. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It Dv NULL +No +.Vt BIO +was connected to the +.Vt SSL +object. +.It Any other pointer +The +.Vt BIO +linked to +.Fa ssl . +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_set_bio 3 +.Sh HISTORY +.Fn SSL_get_rbio +and +.Fn SSL_get_wbio +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_server_tmp_key.3 b/Libraries/libressl/man/SSL_get_server_tmp_key.3 new file mode 100644 index 000000000..aeeb35824 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_server_tmp_key.3 @@ -0,0 +1,89 @@ +.\" $OpenBSD: SSL_get_server_tmp_key.3,v 1.4 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL SSL_get_server_tmp_key.pod 508fafd8 Apr 3 15:41:21 2017 +0100 +.\" +.\" This file was written by Matt Caswell +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_GET_SERVER_TMP_KEY 3 +.Os +.Sh NAME +.Nm SSL_get_server_tmp_key +.Nd temporary server key during a handshake +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fo SSL_get_server_tmp_key +.Fa "SSL *ssl" +.Fa "EVP_PKEY **key" +.Fc +.Sh DESCRIPTION +.Fn SSL_get_server_tmp_key +retrieves the temporary key provided by the server +and used during key exchange. +For example, if ECDHE is in use, +this represents the server's public ECDHE key. +.Pp +In case of success, a copy of the key is stored in +.Pf * Fa key . +It is the caller's responsibility to free this key after use using +.Xr EVP_PKEY_free 3 . +.Pp +This function may only be called by the client. +.Pp +This function is implemented as a macro. +.Sh RETURN VALUES +.Fn SSL_get_server_tmp_key +returns 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr EVP_PKEY_free 3 , +.Xr ssl 3 , +.Xr SSL_ctrl 3 +.Sh HISTORY +.Fn SSL_get_server_tmp_key +first appeared in OpenSSL 1.0.2 and has been available since +.Ox 6.1 . diff --git a/Libraries/libressl/man/SSL_get_session.3 b/Libraries/libressl/man/SSL_get_session.3 new file mode 100644 index 000000000..2ab43fdd3 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_session.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: SSL_get_session.3,v 1.8 2022/03/31 17:27:18 naddy Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2005, 2013, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt SSL_GET_SESSION 3 +.Os +.Sh NAME +.Nm SSL_get_session , +.Nm SSL_get0_session , +.Nm SSL_get1_session +.Nd retrieve TLS/SSL session data +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_SESSION * +.Fn SSL_get_session "const SSL *ssl" +.Ft SSL_SESSION * +.Fn SSL_get0_session "const SSL *ssl" +.Ft SSL_SESSION * +.Fn SSL_get1_session "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_session +returns a pointer to the +.Vt SSL_SESSION +actually used in +.Fa ssl . +The reference count of the +.Vt SSL_SESSION +is not incremented, so that the pointer can become invalid by other operations. +.Pp +.Fn SSL_get0_session +is the same as +.Fn SSL_get_session . +.Pp +.Fn SSL_get1_session +is the same as +.Fn SSL_get_session , +but the reference count of the +.Vt SSL_SESSION +is incremented by one. +.Pp +The +.Fa ssl +session contains all information required to re-establish the connection +without a new handshake. +.Pp +.Fn SSL_get0_session +returns a pointer to the actual session. +As the reference counter is not incremented, +the pointer is only valid while the connection is in use. +If +.Xr SSL_clear 3 +or +.Xr SSL_free 3 +is called, the session may be removed completely (if considered bad), +and the pointer obtained will become invalid. +Even if the session is valid, +it can be removed at any time due to timeout during +.Xr SSL_CTX_flush_sessions 3 . +.Pp +If the data is to be kept, +.Fn SSL_get1_session +will increment the reference count, so that the session will not be implicitly +removed by other operations but stays in memory. +In order to remove the session, +.Xr SSL_SESSION_free 3 +must be explicitly called once to decrement the reference count again. +.Pp +.Vt SSL_SESSION +objects keep internal link information about the session cache list when being +inserted into one +.Vt SSL_CTX +object's session cache. +One +.Vt SSL_SESSION +object, regardless of its reference count, must therefore only be used with one +.Vt SSL_CTX +object (and the +.Vt SSL +objects created from this +.Vt SSL_CTX +object). +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It Dv NULL +There is no session available in +.Fa ssl . +.It Pointer to an Vt SSL_SESSION +The return value points to the data of an +.Vt SSL +session. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_free 3 , +.Xr SSL_SESSION_free 3 , +.Xr SSL_SESSION_get0_peer 3 , +.Xr SSL_SESSION_get_compress_id 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_protocol_version 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_new 3 , +.Xr SSL_SESSION_print 3 , +.Xr SSL_set_session 3 +.Sh HISTORY +.Fn SSL_get_session +first appeared in SSLeay 0.5.2 and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_get0_session +and +.Fn SSL_get1_session +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/SSL_get_shared_ciphers.3 b/Libraries/libressl/man/SSL_get_shared_ciphers.3 new file mode 100644 index 000000000..207e8c42e --- /dev/null +++ b/Libraries/libressl/man/SSL_get_shared_ciphers.3 @@ -0,0 +1,103 @@ +.\" $OpenBSD: SSL_get_shared_ciphers.3,v 1.5 2021/01/09 10:50:02 tb Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 9 2021 $ +.Dt SSL_GET_SHARED_CIPHERS 3 +.Os +.Sh NAME +.Nm SSL_get_shared_ciphers +.Nd ciphers supported by both client and server +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft char * +.Fo SSL_get_shared_ciphers +.Fa "const SSL *ssl" +.Fa "char *buf" +.Fa "int len" +.Fc +.Sh DESCRIPTION +If +.Fa ssl +contains a session in server mode, +.Fn SSL_get_shared_ciphers +puts as many names of ciphers that are supported by both the client +and the server into the buffer +.Fa buf +as the buffer is long enough to contain. +Names are separated by colons. +At most +.Fa len +bytes are written to +.Fa buf +including the terminating NUL character. +.Sh RETURN VALUES +.Fn SSL_get_shared_ciphers +returns +.Fa buf +on success or +.Dv NULL +on failure. +The following situations cause failure: +.Bl -bullet +.It +.Xr SSL_is_server 3 +is false, i.e., +.Ar ssl +is not set to server mode. +.It +.Xr SSL_get_ciphers 3 +is +.Dv NULL +or empty, i.e., no ciphers are available for use by the server. +.It +.Xr SSL_get_session 3 +is +.Dv NULL , +i.e., +.Ar ssl +contains no session. +.It +.Xr SSL_get_client_ciphers 3 +is +.Dv NULL +or empty, i.e., +.Ar ssl +contains no information about ciphers supported by the client, +or the client does not support any ciphers. +.It +The +.Fa len +argument is less than 2. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_get_ciphers 3 +.Sh HISTORY +.Fn SSL_get_shared_ciphers +first appeared in SSLeay 0.4.5b and has been available since +.Ox 2.4 . +.Sh BUGS +If the list is too long to fit into +.Fa len +bytes, it is silently truncated after the last cipher name that fits, +and all following ciphers are skipped. +If the buffer is very short such that even the first cipher name +does not fit, an empty string is returned even when some shared +ciphers are actually available. +.Pp +There is no easy way to find out how much space is required for +.Fa buf +or whether the supplied space was sufficient. diff --git a/Libraries/libressl/man/SSL_get_state.3 b/Libraries/libressl/man/SSL_get_state.3 new file mode 100644 index 000000000..297bbce87 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_state.3 @@ -0,0 +1,161 @@ +.\" $OpenBSD: SSL_get_state.3,v 1.5 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_GET_STATE 3 +.Os +.Sh NAME +.Nm SSL_get_state , +.Nm SSL_state , +.Nm SSL_in_accept_init , +.Nm SSL_in_before , +.Nm SSL_in_connect_init , +.Nm SSL_in_init , +.Nm SSL_is_init_finished +.Nd inspect the state of the SSL state machine +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_get_state +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_state +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_in_accept_init +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_in_before +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_in_connect_init +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_in_init +.Fa "const SSL *ssl" +.Fc +.Ft int +.Fo SSL_is_init_finished +.Fa "const SSL *ssl" +.Fc +.Sh DESCRIPTION +.Fn SSL_get_state +returns an encoded representation of the current state of the SSL +state machine. +.Fn SSL_state +is a deprecated alias for +.Fn SSL_get_state . +.Pp +The following bits may be set: +.Bl -tag -width Ds +.It Dv SSL_ST_ACCEPT +This bit is set by +.Xr SSL_accept 3 +and by +.Xr SSL_set_accept_state 3 . +It indicates that +.Fa ssl +is set up for server mode and no client initiated the TLS handshake yet. +The function +.Fn SSL_in_accept_init +returns non-zero if this bit is set or 0 otherwise. +.It Dv SSL_ST_BEFORE +This bit is set by the +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_set_accept_state 3 , +and +.Xr SSL_set_connect_state 3 +functions. +It indicates that the TLS handshake was not initiated yet. +The function +.Fn SSL_in_before +returns non-zero if this bit is set or 0 otherwise. +.It Dv SSL_ST_CONNECT +This bit is set by +.Xr SSL_connect 3 +and by +.Xr SSL_set_connect_state 3 . +It indicates that +.Fa ssl +is set up for client mode and no TLS handshake was initiated yet. +The function +.Fn SSL_in_connect_init +returns non-zero if this bit is set or 0 otherwise. +.El +.Pp +The following masks can be used: +.Bl -tag -width Ds +.It Dv SSL_ST_INIT +Set if +.Dv SSL_ST_ACCEPT +or +.Dv SSL_ST_CONNECT +is set. +The function +.Fn SSL_in_init +returns a non-zero value if one of these is set or 0 otherwise. +.It Dv SSL_ST_MASK +This mask includes all bits except +.Dv SSL_ST_ACCEPT , +.Dv SSL_ST_BEFORE , +and +.Dv SSL_ST_CONNECT . +.It Dv SSL_ST_OK +The state is set to this value when a connection is established. +The function +.Fn SSL_is_init_finished +returns a non-zero value if the state equals this constant, or 0 otherwise. +.It Dv SSL_ST_RENEGOTIATE +The program is about to renegotiate, for example when entering +.Xr SSL_read 3 +or +.Xr SSL_write 3 +right after +.Xr SSL_renegotiate 3 +was called. +.El +.Pp +The meaning of other bits is protocol-dependent. +Application programs usually do not need to inspect any of those +other bits. +.Pp +All these functions may be implemented as macros. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_renegotiate 3 , +.Xr SSL_set_connect_state 3 +.Sh HISTORY +.Fn SSL_is_init_finished +first appeared in SSLeay 0.4.5b. +.Fn SSL_state +first appeared in SSLeay 0.5.2. +.Fn SSL_in_accept_init , +.Fn SSL_in_connect_init , +and +.Fn SSL_in_init +first appeared in SSLeay 0.6.0. +.Fn SSL_in_before +first appeared in SSLeay 0.8.0. +.Fn SSL_get_state +first appeared in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_get_verify_result.3 b/Libraries/libressl/man/SSL_get_verify_result.3 new file mode 100644 index 000000000..180cf1bb7 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_verify_result.3 @@ -0,0 +1,102 @@ +.\" $OpenBSD: SSL_get_verify_result.3,v 1.6 2021/06/26 17:36:28 tb Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 26 2021 $ +.Dt SSL_GET_VERIFY_RESULT 3 +.Os +.Sh NAME +.Nm SSL_get_verify_result +.Nd get result of peer certificate verification +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fn SSL_get_verify_result "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_verify_result +returns the result of the verification of the X509 certificate presented by the +peer, if any. +.Pp +.Fn SSL_get_verify_result +can only return one error code while the verification of a certificate can fail +because of many reasons at the same time. +Only the last verification error that occurred during the processing is +available from +.Fn SSL_get_verify_result . +.Pp +The verification result is part of the established session and is restored when +a session is reused. +.Sh RETURN VALUES +The following return values can currently occur: +.Bl -tag -width Ds +.It Dv X509_V_OK +The verification succeeded or no peer certificate was presented. +.It Any other value +Documented in +.Xr openssl 1 . +.El +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ssl 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr SSL_get0_peername 3 , +.Xr SSL_get_peer_certificate 3 , +.Xr SSL_set_verify_result 3 +.Sh HISTORY +.Fn SSL_get_verify_result +first appeared in SSLeay 0.6.1 and has been available since +.Ox 2.4 . +.Sh BUGS +If no peer certificate was presented, the returned result code is +.Dv X509_V_OK . +This is because no verification error occurred; +however, it does not indicate success. +.Fn SSL_get_verify_result +is only useful in connection with +.Xr SSL_get_peer_certificate 3 . diff --git a/Libraries/libressl/man/SSL_get_version.3 b/Libraries/libressl/man/SSL_get_version.3 new file mode 100644 index 000000000..a6cefb055 --- /dev/null +++ b/Libraries/libressl/man/SSL_get_version.3 @@ -0,0 +1,123 @@ +.\" $OpenBSD: SSL_get_version.3,v 1.9 2021/04/15 16:13:22 tb Exp $ +.\" full merge up to: OpenSSL e417070c Jun 8 11:37:06 2016 -0400 +.\" selective merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 15 2021 $ +.Dt SSL_GET_VERSION 3 +.Os +.Sh NAME +.Nm SSL_get_version , +.Nm SSL_is_dtls , +.Nm SSL_version +.\" The following are intentionally undocumented because +.\" - the longer term plan is to remove them +.\" - nothing appears to be using them in the wild +.\" - and they have the wrong namespace prefix +.\" Nm TLS1_get_version +.\" Nm TLS1_get_client_version +.Nd get the protocol information of a connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const char * +.Fn SSL_get_version "const SSL *ssl" +.Ft int +.Fn SSL_is_dtls "const SSL *ssl" +.Ft int +.Fn SSL_version "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_get_version +returns the name of the protocol used for the connection +.Fa ssl . +.Pp +.Fn SSL_is_dtls +returns 1 if the connection is using DTLS, 0 if not. +.Pp +.Fn SSL_version +returns an integer constant representing that protocol. +.Pp +These functions only return reliable results +after the initial handshake has been completed. +.Sh RETURN VALUES +The following strings or integers can be returned by +.Fn SSL_get_version +and +.Fn SSL_version : +.Bl -tag -width Ds +.It Qo TLSv1 Qc No or Dv TLS1_VERSION +The connection uses the TLSv1.0 protocol. +.It Qo TLSv1.1 Qc No or Dv TLS1_1_VERSION +The connection uses the TLSv1.1 protocol. +.It Qo TLSv1.2 Qc No or Dv TLS1_2_VERSION +The connection uses the TLSv1.2 protocol. +.It Qo TLSv1.3 Qc No or Dv TLS1_3_VERSION +The connection uses the TLSv1.3 protocol. +.It Qo DTLSv1 Qc No or Dv DTLS1_VERSION +The connection uses the Datagram Transport Layer Security 1.0 protocol. +.It Qo DTLSv1.2 Qc No or Dv DTLS1_2_VERSION +The connection uses the Datagram Transport Layer Security 1.2 protocol. +.It Qq unknown +This indicates an unknown protocol version; +it cannot currently happen with LibreSSL. +.El +.Pp +.Fn SSL_is_dtls +returns 1 if the connection uses DTLS, 0 if not. +.Sh SEE ALSO +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_get_version +and +.Fn SSL_version +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_is_dtls +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.9 . diff --git a/Libraries/libressl/man/SSL_library_init.3 b/Libraries/libressl/man/SSL_library_init.3 new file mode 100644 index 000000000..053c1e6fc --- /dev/null +++ b/Libraries/libressl/man/SSL_library_init.3 @@ -0,0 +1,98 @@ +.\" $OpenBSD: SSL_library_init.3,v 1.7 2019/06/14 13:41:31 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2006, 2010 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 14 2019 $ +.Dt SSL_LIBRARY_INIT 3 +.Os +.Sh NAME +.Nm SSL_library_init , +.Nm OpenSSL_add_ssl_algorithms , +.Nm SSLeay_add_ssl_algorithms +.Nd initialize SSL library by registering algorithms +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_library_init void +.Ft int +.Fn OpenSSL_add_ssl_algorithms void +.Ft int +.Fn SSLeay_add_ssl_algorithms void +.Sh DESCRIPTION +These functions are deprecated. +It is never useful for any application program to call any of them explicitly. +The library automatically calls them internally whenever needed. +.Pp +.Fn SSL_library_init +registers the available ciphers and digests +which are used directly or indirectly by TLS. +.Pp +.Fn OpenSSL_add_ssl_algorithms +and +.Fn SSLeay_add_ssl_algorithms +are synonyms for +.Fn SSL_library_init +and are implemented as macros. +.Sh RETURN VALUES +.Fn SSL_library_init +always returns 1. +.Sh SEE ALSO +.Xr ssl 3 +.Sh HISTORY +.Fn SSLeay_add_ssl_algorithms +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_library_init +first appeared in OpenSSL 0.9.2b and has been available since +.Ox 2.6 . +.Pp +.Fn OpenSSL_add_ssl_algorithms +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/SSL_load_client_CA_file.3 b/Libraries/libressl/man/SSL_load_client_CA_file.3 new file mode 100644 index 000000000..f782d96dc --- /dev/null +++ b/Libraries/libressl/man/SSL_load_client_CA_file.3 @@ -0,0 +1,185 @@ +.\" $OpenBSD: SSL_load_client_CA_file.3,v 1.9 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Lutz Jaenicke . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_LOAD_CLIENT_CA_FILE 3 +.Os +.Sh NAME +.Nm SSL_load_client_CA_file , +.Nm SSL_add_file_cert_subjects_to_stack , +.Nm SSL_add_dir_cert_subjects_to_stack +.Nd load certificate names from files +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft STACK_OF(X509_NAME) * +.Fn SSL_load_client_CA_file "const char *file" +.Ft int +.Fo SSL_add_file_cert_subjects_to_stack +.Fa "STACK_OF(X509_NAME) *stack" +.Fa "const char *file" +.Fc +.Ft int +.Fo SSL_add_dir_cert_subjects_to_stack +.Fa "STACK_OF(X509_NAME) *stack" +.Fa "const char *dir" +.Fc +.Sh DESCRIPTION +.Fn SSL_load_client_CA_file +reads PEM formatted certificates from +.Fa file +and returns a new +.Vt STACK_OF(X509_NAME) +with the subject names found. +While the name suggests the specific usage as a support function for +.Xr SSL_CTX_set_client_CA_list 3 , +it is not limited to CA certificates. +.Pp +.Fn SSL_add_file_cert_subjects_to_stack +is similar except that the names are added to the existing +.Fa stack . +.Pp +.Fn SSL_add_dir_cert_subjects_to_stack +calls +.Fn SSL_add_file_cert_subjects_to_stack +on every file in the directory +.Fa dir . +.Pp +If a name is already on the stack, all these functions skip it and +do not add it again. +.Sh RETURN VALUES +.Fn SSL_load_client_CA_file +returns a pointer to the new +.Vt STACK_OF(X509_NAME) +or +.Dv NULL on failure . +.Pp +.Fn SSL_add_file_cert_subjects_to_stack +and +.Fn SSL_add_dir_cert_subjects_to_stack +return 1 for success or 0 for failure. +.Pp +All these functions treat empty files and directories as failures. +.Pp +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh EXAMPLES +Load names of CAs from a file and use it as a client CA list: +.Bd -literal +SSL_CTX *ctx; +STACK_OF(X509_NAME) *cert_names; +\&... +cert_names = SSL_load_client_CA_file("/path/to/CAfile.pem"); +if (cert_names != NULL) + SSL_CTX_set_client_CA_list(ctx, cert_names); +else + error_handling(); +\&... +.Ed +.Sh SEE ALSO +.Xr PEM_read_bio_X509 3 , +.Xr ssl 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn SSL_load_client_CA_file +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_add_file_cert_subjects_to_stack +and +.Fn SSL_add_dir_cert_subjects_to_stack +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Sh AUTHORS +.Fn SSL_add_file_cert_subjects_to_stack +and +.Fn SSL_add_dir_cert_subjects_to_stack +were written by +.An Ben Laurie Aq Mt ben@openssl.org +in 1999. +.Sh BUGS +In some cases of failure, for example for empty files and directories, +these functions fail to report an error, in the sense that +.Xr ERR_get_error 3 +does not work. +.Pp +Even in case of failure, for example when parsing one of the +files or certificates fails, +.Fn SSL_add_file_cert_subjects_to_stack +and +.Fn SSL_add_dir_cert_subjects_to_stack +may still have added some certificates to the stack. +.Pp +The behaviour of +.Fn SSL_add_dir_cert_subjects_to_stack +is non-deterministic. +If parsing one file fails, parsing of the whole directory is aborted. +Files in the directory are not parsed in any specific order. +For example, adding an empty file to +.Fa dir +may or may not cause some of the other files to be ignored. diff --git a/Libraries/libressl/man/SSL_new.3 b/Libraries/libressl/man/SSL_new.3 new file mode 100644 index 000000000..22c5dbf2d --- /dev/null +++ b/Libraries/libressl/man/SSL_new.3 @@ -0,0 +1,110 @@ +.\" $OpenBSD: SSL_new.3,v 1.7 2022/07/13 22:05:53 schwarze Exp $ +.\" full merge up to: OpenSSL 1c7ae3dd Mar 29 19:17:55 2017 +1000 +.\" +.\" This file was written by Richard Levitte +.\" and Matt Caswell . +.\" Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt SSL_NEW 3 +.Os +.Sh NAME +.Nm SSL_new , +.Nm SSL_up_ref +.Nd create a new SSL structure for a connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL * +.Fn SSL_new "SSL_CTX *ctx" +.Ft int +.Fn SSL_up_ref "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_new +creates a new +.Vt SSL +structure which is needed to hold the data for a TLS/SSL connection. +The new structure inherits the settings of the underlying context +.Fa ctx : +connection method, options, verification settings, +timeout settings, security level. +The reference count of the new structure is set to 1. +.Pp +.Fn SSL_up_ref +increments the reference count of +.Fa ssl +by 1. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It Dv NULL +The creation of a new +.Vt SSL +structure failed. +Check the error stack to find out the reason. +.It Pointer to an Vt SSL No structure +The return value points to an allocated +.Vt SSL +structure. +.El +.Pp +.Fn SSL_up_ref +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_CTX_set_security_level 3 , +.Xr SSL_free 3 , +.Xr SSL_get_SSL_CTX 3 +.Sh HISTORY +.Fn SSL_new +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_num_renegotiations.3 b/Libraries/libressl/man/SSL_num_renegotiations.3 new file mode 100644 index 000000000..6a81b76a6 --- /dev/null +++ b/Libraries/libressl/man/SSL_num_renegotiations.3 @@ -0,0 +1,75 @@ +.\" $OpenBSD: SSL_num_renegotiations.3,v 1.5 2019/06/12 09:36:30 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_NUM_RENEGOTIATIONS 3 +.Os +.Sh NAME +.Nm SSL_num_renegotiations , +.Nm SSL_clear_num_renegotiations , +.Nm SSL_total_renegotiations +.Nd renegotiation counters +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fo SSL_num_renegotiations +.Fa "SSL *ssl" +.Fc +.Ft long +.Fo SSL_clear_num_renegotiations +.Fa "SSL *ssl" +.Fc +.Ft long +.Fo SSL_total_renegotiations +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +.Fn SSL_num_renegotiations +reports the number of renegotiations initiated in +.Fa ssl +since +.Xr SSL_new 3 , +.Xr SSL_clear 3 , +or +.Fn SSL_clear_num_renegotiations +was last called on that object. +.Pp +.Fn SSL_clear_num_renegotiations +does the same and additionally resets the renegotiation counter to 0. +.Pp +.Fn SSL_total_renegotiations +reports the number of renegotiations initiated in +.Fa ssl +since +.Xr SSL_new 3 +or +.Xr SSL_clear 3 +was last called on that object. +.Pp +These functions are implemented as macros. +.Sh RETURN VALUES +All these functions return a number of renegotiations. +.Sh SEE ALSO +.Xr BIO_set_ssl_renegotiate_bytes 3 , +.Xr ssl 3 , +.Xr SSL_ctrl 3 , +.Xr SSL_read 3 , +.Xr SSL_renegotiate 3 , +.Xr SSL_write 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.9.0 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_pending.3 b/Libraries/libressl/man/SSL_pending.3 new file mode 100644 index 000000000..bbc2e9bdd --- /dev/null +++ b/Libraries/libressl/man/SSL_pending.3 @@ -0,0 +1,90 @@ +.\" $OpenBSD: SSL_pending.3,v 1.5 2020/01/23 03:40:18 beck Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke , +.\" Bodo Moeller , and Matt Caswell . +.\" Copyright (c) 2000, 2005, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 23 2020 $ +.Dt SSL_PENDING 3 +.Os +.Sh NAME +.Nm SSL_pending +.Nd obtain number of readable bytes buffered in an SSL object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_pending "const SSL *ssl" +.Sh DESCRIPTION +Data is received in whole blocks known as records from the peer. +A whole record is processed, for example decrypted, in one go and +is buffered until it is read by the application via a call to +.Xr SSL_read 3 . +.Pp +.Fn SSL_pending +returns the number of bytes of application data which are available +for immediate read. +.Pp +.Fn SSL_pending +takes into account only bytes from the TLS/SSL record that is +currently being processed (if any). +.Sh RETURN VALUES +.Fn SSL_pending +returns the number of buffered and processed application data +bytes that are pending and are available for immediate read. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_read 3 +.Sh HISTORY +.Fn SSL_pending +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . +.Sh BUGS +Up to OpenSSL 0.9.6, +.Fn SSL_pending +did not check if the record type of pending data is application data. diff --git a/Libraries/libressl/man/SSL_read.3 b/Libraries/libressl/man/SSL_read.3 new file mode 100644 index 000000000..bb72a8ed8 --- /dev/null +++ b/Libraries/libressl/man/SSL_read.3 @@ -0,0 +1,278 @@ +.\" $OpenBSD: SSL_read.3,v 1.8 2021/10/24 15:10:13 schwarze Exp $ +.\" full merge up to: OpenSSL 5a2443ae Nov 14 11:37:36 2016 +0000 +.\" partial merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file was written by Lutz Jaenicke and +.\" Matt Caswell . +.\" Copyright (c) 2000, 2001, 2008, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 24 2021 $ +.Dt SSL_READ 3 +.Os +.Sh NAME +.Nm SSL_read_ex , +.Nm SSL_read , +.Nm SSL_peek_ex , +.Nm SSL_peek +.Nd read bytes from a TLS connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_read_ex "SSL *ssl" "void *buf" "size_t num" "size_t *readbytes" +.Ft int +.Fn SSL_read "SSL *ssl" "void *buf" "int num" +.Ft int +.Fn SSL_peek_ex "SSL *ssl" "void *buf" "size_t num" "size_t *readbytes" +.Ft int +.Fn SSL_peek "SSL *ssl" "void *buf" "int num" +.Sh DESCRIPTION +.Fn SSL_read_ex +and +.Fn SSL_read +try to read +.Fa num +bytes from the specified +.Fa ssl +into the buffer +.Fa buf . +On success +.Fn SSL_read_ex +stores the number of bytes actually read in +.Pf * Fa readbytes . +.Pp +.Fn SSL_peek_ex +and +.Fn SSL_peek +are identical to +.Fn SSL_read_ex +and +.Fn SSL_read , +respectively, +except that no bytes are removed from the underlying BIO during +the read, such that a subsequent call to +.Fn SSL_read_ex +or +.Fn SSL_read +will yield at least the same bytes once again. +.Pp +In the following, +.Fn SSL_read_ex , +.Fn SSL_read , +.Fn SSL_peek_ex , +and +.Fn SSL_peek +are called +.Dq read functions . +.Pp +If necessary, a read function will negotiate a TLS session, if +not already explicitly performed by +.Xr SSL_connect 3 +or +.Xr SSL_accept 3 . +If the peer requests a re-negotiation, it will be performed +transparently during the read function operation. +The behaviour of the read functions depends on the underlying +.Vt BIO . +.Pp +For the transparent negotiation to succeed, the +.Fa ssl +must have been initialized to client or server mode. +This is done by calling +.Xr SSL_set_connect_state 3 +or +.Xr SSL_set_accept_state 3 +before the first call to a read function. +.Pp +The read functions work based on the TLS records. +The data are received in records (with a maximum record size of 16kB). +Only when a record has been completely received, it can be processed +(decrypted and checked for integrity). +Therefore, data that was not retrieved at the last read call can +still be buffered inside the TLS layer and will be retrieved on the +next read call. +If +.Fa num +is higher than the number of bytes buffered, the read functions +will return with the bytes buffered. +If no more bytes are in the buffer, the read functions will trigger +the processing of the next record. +Only when the record has been received and processed completely +will the read functions return reporting success. +At most the contents of the record will be returned. +As the size of a TLS record may exceed the maximum packet size +of the underlying transport (e.g., TCP), it may be necessary to +read several packets from the transport layer before the record is +complete and the read call can succeed. +.Pp +If the underlying +.Vt BIO +is blocking, +a read function will only return once the read operation has been +finished or an error occurred, except when a renegotiation takes +place, in which case an +.Dv SSL_ERROR_WANT_READ +may occur. +This behavior can be controlled with the +.Dv SSL_MODE_AUTO_RETRY +flag of the +.Xr SSL_CTX_set_mode 3 +call. +.Pp +If the underlying +.Vt BIO +is non-blocking, a read function will also return when the underlying +.Vt BIO +could not satisfy the needs of the function to continue the operation. +In this case a call to +.Xr SSL_get_error 3 +with the return value of the read function will yield +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE . +As at any time a re-negotiation is possible, a read function may +also cause write operations. +The calling process must then repeat the call after taking appropriate +action to satisfy the needs of the read function. +The action depends on the underlying +.Vt BIO . +When using a non-blocking socket, nothing is to be done, but +.Xr select 2 +can be used to check for the required condition. +When using a buffering +.Vt BIO , +like a +.Vt BIO +pair, data must be written into or retrieved out of the +.Vt BIO +before being able to continue. +.Pp +.Xr SSL_pending 3 +can be used to find out whether there are buffered bytes available for +immediate retrieval. +In this case a read function can be called without blocking or +actually receiving new data from the underlying socket. +.Pp +When a read function operation has to be repeated because of +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE , +it must be repeated with the same arguments. +.Sh RETURN VALUES +.Fn SSL_read_ex +and +.Fn SSL_peek_ex +return 1 for success or 0 for failure. +Success means that one or more application data bytes +have been read from the SSL connection. +Failure means that no bytes could be read from the SSL connection. +Failures can be retryable (e.g. we are waiting for more bytes to be +delivered by the network) or non-retryable (e.g. a fatal network error). +In the event of a failure, call +.Xr SSL_get_error 3 +to find out the reason which indicates whether the call is retryable or not. +.Pp +For +.Fn SSL_read +and +.Fn SSL_peek , +the following return values can occur: +.Bl -tag -width Ds +.It >0 +The read operation was successful. +The return value is the number of bytes actually read from the +TLS connection. +.It 0 +The read operation was not successful. +The reason may either be a clean shutdown due to a +.Dq close notify +alert sent by the peer (in which case the +.Dv SSL_RECEIVED_SHUTDOWN +flag in the ssl shutdown state is set (see +.Xr SSL_shutdown 3 +and +.Xr SSL_set_shutdown 3 ) . +It is also possible that the peer simply shut down the underlying transport and +the shutdown is incomplete. +Call +.Xr SSL_get_error 3 +with the return value to find out whether an error occurred or the connection +was shut down cleanly +.Pq Dv SSL_ERROR_ZERO_RETURN . +.It <0 +The read operation was not successful, because either an error occurred or +action must be taken by the calling process. +Call +.Xr SSL_get_error 3 +with the return value to find out the reason. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_set_mode 3 , +.Xr SSL_get_error 3 , +.Xr SSL_pending 3 , +.Xr SSL_set_connect_state 3 , +.Xr SSL_set_shutdown 3 , +.Xr SSL_shutdown 3 , +.Xr SSL_write 3 +.Sh HISTORY +.Fn SSL_read +appeared in SSLeay 0.4 or earlier. +.Fn SSL_peek +first appeared in SSLeay 0.6.6. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn SSL_read_ex +and +.Fn SSL_peek_ex +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/SSL_read_early_data.3 b/Libraries/libressl/man/SSL_read_early_data.3 new file mode 100644 index 000000000..1435c1593 --- /dev/null +++ b/Libraries/libressl/man/SSL_read_early_data.3 @@ -0,0 +1,174 @@ +.\" $OpenBSD: SSL_read_early_data.3,v 1.4 2021/11/26 13:48:22 jsg Exp $ +.\" content checked up to: OpenSSL 6328d367 Jul 4 21:58:30 2020 +0200 +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 26 2021 $ +.Dt SSL_READ_EARLY_DATA 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_max_early_data , +.Nm SSL_set_max_early_data , +.Nm SSL_SESSION_set_max_early_data , +.Nm SSL_CTX_get_max_early_data , +.Nm SSL_get_max_early_data , +.Nm SSL_SESSION_get_max_early_data , +.Nm SSL_write_early_data , +.Nm SSL_read_early_data , +.Nm SSL_get_early_data_status +.Nd transmit application data during the handshake +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_CTX_set_max_early_data +.Fa "SSL_CTX *ctx" +.Fa "uint32_t max_bytes" +.Fc +.Ft int +.Fo SSL_set_max_early_data +.Fa "SSL *ssl" +.Fa "uint32_t max_bytes" +.Fc +.Ft int +.Fo SSL_SESSION_set_max_early_data +.Fa "SSL_SESSION *session" +.Fa "uint32_t max_bytes" +.Fc +.Ft uint32_t +.Fo SSL_CTX_get_max_early_data +.Fa "const SSL_CTX *ctx" +.Fc +.Ft uint32_t +.Fo SSL_get_max_early_data +.Fa "const SSL *ssl" +.Fc +.Ft uint32_t +.Fo SSL_SESSION_get_max_early_data +.Fa "const SSL_SESSION *session" +.Fc +.Ft int +.Fo SSL_write_early_data +.Fa "SSL *ssl" +.Fa "const void *buf" +.Fa "size_t len" +.Fa "size_t *written" +.Fc +.Ft int +.Fo SSL_read_early_data +.Fa "SSL *ssl" +.Fa "void *buf" +.Fa "size_t maxlen" +.Fa "size_t *readbytes" +.Fc +.Ft int +.Fo SSL_get_early_data_status +.Fa "const SSL *ssl" +.Fc +.Sh DESCRIPTION +In LibreSSL, these functions have no effect. +They are only provided because some application programs +expect the API to be available when TLSv1.3 is supported. +Using these functions is strongly discouraged because they provide +marginal benefit in the first place even when implemented and +used as designed, because they have absurdly complicated semantics, +and because when they are used, inconspicuous oversights are likely +to cause serious security vulnerabilities. +.Pp +If these functions are used, other TLS implementations +may allow the transfer of application data during the initial handshake. +Even when used as designed, security of the connection is compromised; +in particular, application data is exchanged with unauthenticated peers, +and there is no forward secrecy. +Other downsides include an increased risk of replay attacks. +.Pp +.Fn SSL_CTX_set_max_early_data , +.Fn SSL_set_max_early_data , +and +.Fn SSL_SESSION_set_max_early_data +are intended to configure the maximum number of bytes per session +that can be transmitted during the handshake. +With LibreSSL, all arguments are ignored. +.Pp +An endpoint can attempt to send application data with +.Fn SSL_write_early_data +during the handshake. +With LibreSSL, such attempts always fail and set +.Pf * Fa written +to 0. +.Pp +A server can attempt to read application data from the client using +.Fn SSL_read_early_data +during the handshake. +With LibreSSL, no such data is ever accepted and +.Pf * Fa readbytes +is always set to 0. +.Sh RETURN VALUES +.Fn SSL_CTX_set_max_early_data , +.Fn SSL_set_max_early_data , +and +.Fn SSL_SESSION_set_max_early_data +return 1 for success or 0 for failure. +With LibreSSL, they always succeed. +.Pp +.Fn SSL_CTX_get_max_early_data , +.Fn SSL_get_max_early_data , +and +.Fn SSL_SESSION_get_max_early_data +return the maximum number of bytes of application data +that will be accepted from the peer during the handshake. +With LibreSSL, they always return 0. +.Pp +.Fn SSL_write_early_data +returns 1 for success or 0 for failure. +With LibreSSL, it always fails. +.Pp +With LibreSSL, +.Fn SSL_read_early_data +always returns +.Dv SSL_READ_EARLY_DATA_FINISH +on the server side and +.Dv SSL_READ_EARLY_DATA_ERROR +on the client side. +.Dv SSL_READ_EARLY_DATA_SUCCESS +can occur with other implementations, but not with LibreSSL. +.Pp +With LibreSSL, +.Fn SSL_get_early_data_status +always returns +.Dv SSL_EARLY_DATA_REJECTED . +With other implementations, it might also return +.Dv SSL_EARLY_DATA_NOT_SENT +or +.Dv SSL_EARLY_DATA_ACCEPTED . +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_read 3 , +.Xr SSL_write 3 +.Sh STANDARDS +RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3: +.Bl -tag -width "section 4.2.10" -compact +.It Section 2.3 +0-RTT data +.It Section 4.2.10 +Early Data Indication +.It Section 8 +0-RTT and Anti-Replay +.It Appendix E.5 +Replay Attacks on 0-RTT +.El +.Sh HISTORY +These functions first appeared in OpenSSL 1.1.1 +and have been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/SSL_renegotiate.3 b/Libraries/libressl/man/SSL_renegotiate.3 new file mode 100644 index 000000000..8188d3732 --- /dev/null +++ b/Libraries/libressl/man/SSL_renegotiate.3 @@ -0,0 +1,166 @@ +.\" $OpenBSD: SSL_renegotiate.3,v 1.9 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL SSL_key_update.pod 4fbfe86a Feb 16 17:04:40 2017 +0000 +.\" +.\" This file is a derived work. +.\" Some parts are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Other parts were written by Matt Caswell . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_RENEGOTIATE 3 +.Os +.Sh NAME +.Nm SSL_renegotiate , +.Nm SSL_renegotiate_abbreviated , +.Nm SSL_renegotiate_pending +.Nd initiate a new TLS handshake +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_renegotiate +.Fa "SSL *ssl" +.Fc +.Ft int +.Fo SSL_renegotiate_abbreviated +.Fa "SSL *ssl" +.Fc +.Ft int +.Fo SSL_renegotiate_pending +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +When called from the client side, +.Fn SSL_renegotiate +schedules a completely new handshake over an existing TLS connection. +The next time an I/O operation such as +.Fn SSL_read +or +.Fn SSL_write +takes place on the connection, a check is performed to confirm +that it is a suitable time to start a renegotiation. +If so, a new handshake is initiated immediately. +An existing session associated with the connection is not resumed. +.Pp +This function is automatically called by +.Xr SSL_read 3 +and +.Xr SSL_write 3 +whenever the renegotiation byte count set by +.Xr BIO_set_ssl_renegotiate_bytes 3 +or the timeout set by +.Xr BIO_set_ssl_renegotiate_timeout 3 +are exceeded. +.Pp +When called from the client side, +.Fn SSL_renegotiate_abbreviated +is similar to +.Fn SSL_renegotiate +except that resuming the session associated with the current +connection is attempted in the new handshake. +.Pp +When called from the server side, +.Fn SSL_renegotiate +and +.Fn SSL_renegotiate_abbreviated +behave identically. +They both schedule a request for a new handshake to be sent to the client. +The next time an I/O operation is performed, the same checks as on +the client side are performed and then, if appropriate, the request +is sent. +The client may or may not respond with a new handshake and it may +or may not attempt to resume an existing session. +If a new handshake is started, it is handled transparently during +any I/O function. +.Pp +If a LibreSSL client receives a renegotiation request from a server, +it is also handled transparently during any I/O function. +The client attempts to resume the current session in the new +handshake. +For historical reasons, DTLS clients do not attempt to resume +the session in the new handshake. +.Sh RETURN VALUES +.Fn SSL_renegotiate +and +.Fn SSL_renegotiate_abbreviated +return 1 on success or 0 on error. +.Pp +.Fn SSL_renegotiate_pending +returns 1 if a renegotiation or renegotiation request has been +scheduled but not yet acted on, or 0 otherwise. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_do_handshake 3 , +.Xr SSL_num_renegotiations 3 , +.Xr SSL_read 3 , +.Xr SSL_write 3 +.Sh HISTORY +.Fn SSL_renegotiate +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_renegotiate_pending +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Pp +.Fn SSL_renegotiate_abbreviated +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/SSL_rstate_string.3 b/Libraries/libressl/man/SSL_rstate_string.3 new file mode 100644 index 000000000..99613ba3c --- /dev/null +++ b/Libraries/libressl/man/SSL_rstate_string.3 @@ -0,0 +1,108 @@ +.\" $OpenBSD: SSL_rstate_string.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_RSTATE_STRING 3 +.Os +.Sh NAME +.Nm SSL_rstate_string , +.Nm SSL_rstate_string_long +.Nd get textual description of state of an SSL object during read operation +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const char * +.Fn SSL_rstate_string "SSL *ssl" +.Ft const char * +.Fn SSL_rstate_string_long "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_rstate_string +returns a 2-letter string indicating the current read state of the +.Vt SSL +object +.Fa ssl . +.Pp +.Fn SSL_rstate_string_long +returns a string indicating the current read state of the +.Vt SSL +object +.Fa ssl . +.Pp +When performing a read operation, the SSL/TLS engine must parse the record, +consisting of header and body. +When working in a blocking environment, +.Fn SSL_rstate_string[_long] +should always return +.Qo RD Qc Ns / Ns Qo read done Qc . +.Pp +This function should only seldom be needed in applications. +.Sh RETURN VALUES +.Fn SSL_rstate_string +and +.Fn SSL_rstate_string_long +can return the following values: +.Bl -tag -width Ds +.It Qo RH Qc Ns / Ns Qo read header Qc +The header of the record is being evaluated. +.It Qo RB Qc Ns / Ns Qo read body Qc +The body of the record is being evaluated. +.It Qo RD Qc Ns / Ns Qo read done Qc +The record has been completely processed. +.It Qo unknown Qc Ns / Ns Qo unknown Qc +The read state is unknown. +This should never happen. +.El +.Sh SEE ALSO +.Xr ssl 3 +.Sh HISTORY +.Fn SSL_rstate_string +and +.Fn SSL_rstate_string_long +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_session_reused.3 b/Libraries/libressl/man/SSL_session_reused.3 new file mode 100644 index 000000000..add61a904 --- /dev/null +++ b/Libraries/libressl/man/SSL_session_reused.3 @@ -0,0 +1,84 @@ +.\" $OpenBSD: SSL_session_reused.3,v 1.6 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_SESSION_REUSED 3 +.Os +.Sh NAME +.Nm SSL_session_reused +.Nd query whether a reused session was negotiated during handshake +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_session_reused "SSL *ssl" +.Sh DESCRIPTION +Query whether a reused session was negotiated during the handshake. +.Pp +During the negotiation, a client can propose to reuse a session. +The server then looks up the session in its cache. +If both client and server agree on the session, +it will be reused and a flag is set that can be queried by the application. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +A new session was negotiated. +.It 1 +A session was reused. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_ctrl 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_set_session 3 +.Sh HISTORY +.Fn SSL_session_reused +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_set1_host.3 b/Libraries/libressl/man/SSL_set1_host.3 new file mode 100644 index 000000000..2a3935c3f --- /dev/null +++ b/Libraries/libressl/man/SSL_set1_host.3 @@ -0,0 +1,172 @@ +.\" $OpenBSD: SSL_set1_host.3,v 1.4 2021/03/31 16:56:46 tb Exp $ +.\" selective merge up to: OpenSSL 6328d367 Jul 4 21:58:30 2020 +0200 +.\" +.\" This file was written by Viktor Dukhovni +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2021 $ +.Dt SSL_SET1_HOST 3 +.Os +.Sh NAME +.Nm SSL_set1_host , +.Nm SSL_set_hostflags , +.Nm SSL_get0_peername +.Nd SSL server verification parameters +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fo SSL_set1_host +.Fa "SSL *ssl" +.Fa "const char *hostname" +.Fc +.Ft void +.Fo SSL_set_hostflags +.Fa "SSL *ssl" +.Fa "unsigned int flags" +.Fc +.Ft const char * +.Fo SSL_get0_peername +.Fa "SSL *ssl" +.Fc +.Sh DESCRIPTION +.Fn SSL_set1_host +configures a server hostname check in the +.Fa ssl +client, setting the expected DNS hostname to +.Fa hostname +and clearing any previously specified hostname. +If +.Fa hostname +is +.Dv NULL +or the empty string, name checks are not performed on the peer certificate. +If a nonempty +.Fa hostname +is specified, certificate verification automatically checks the peer +hostname via +.Xr X509_check_host 3 +with +.Fa flags +set to 0. +.Pp +.Fn SSL_set_hostflags +sets the flags that will be passed to +.Xr X509_check_host 3 +when name checks are applicable, +by default the flags value is 0. +See +.Xr X509_check_host 3 +for the list of available flags and their meaning. +.Pp +.Fn SSL_get0_peername +returns the DNS hostname or subject CommonName from the peer certificate +that matched one of the reference identifiers. +Unless wildcard matching is disabled, the name matched in the peer +certificate may be a wildcard name. +A reference identifier starting with +.Sq \&. +indicates a parent domain prefix rather than a fixed name. +In this case, the matched peername may be a sub-domain +of the reference identifier. +The returned string is owned by the library and is no longer valid +once the associated +.Fa ssl +object is cleared or freed, or if a renegotiation takes place. +Applications must not free the return value. +.Pp +SSL clients are advised to use these functions in preference to +explicitly calling +.Xr X509_check_host 3 . +.Sh RETURN VALUES +.Fn SSL_set1_host +returns 1 for success or 0 for failure. +.Pp +.Fn SSL_get0_peername +returns the matched peername or +.Dv NULL +if peername verification is not applicable +or no trusted peername was matched. +Use +.Xr SSL_get_verify_result 3 +to determine whether verification succeeded. +.Sh EXAMPLES +The calls below check the hostname. +Wildcards are supported, but they must match the entire label. +The actual name matched in the certificate (which might be a wildcard) +is retrieved, and must be copied by the application if it is to be +retained beyond the lifetime of the SSL connection. +.Bd -literal +if (!SSL_set1_host(ssl, "smtp.example.com")) + /* error */ + +/* XXX: Perform SSL_connect() handshake and handle errors here */ + +if (SSL_get_verify_result(ssl) == X509_V_OK) { + const char *peername = SSL_get0_peername(ssl); + + if (peername != NULL) + /* Name checks were in scope and matched the peername */ +} +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr SSL_get_peer_certificate 3 , +.Xr SSL_get_verify_result 3 , +.Xr X509_check_host 3 , +.Xr X509_VERIFY_PARAM_set1_host 3 +.Sh HISTORY +All three functions first appeared in OpenSSL 1.1.0. +.Fn SSL_set1_host +has been available since +.Ox 6.5 , +and +.Fn SSL_set_hostflags +and +.Fn SSL_get0_peername +since +.Ox 6.9 . diff --git a/Libraries/libressl/man/SSL_set1_param.3 b/Libraries/libressl/man/SSL_set1_param.3 new file mode 100644 index 000000000..cd8ad40ad --- /dev/null +++ b/Libraries/libressl/man/SSL_set1_param.3 @@ -0,0 +1,137 @@ +.\" $OpenBSD: SSL_set1_param.3,v 1.6 2022/09/10 10:22:46 jsg Exp $ +.\" full merge up to: +.\" OpenSSL man3/SSL_CTX_get0_param 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2022 $ +.Dt SSL_SET1_PARAM 3 +.Os +.Sh NAME +.Nm SSL_CTX_get0_param , +.Nm SSL_get0_param , +.Nm SSL_CTX_set1_param , +.Nm SSL_set1_param +.Nd get and set verification parameters +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft X509_VERIFY_PARAM * +.Fo SSL_CTX_get0_param +.Fa "SSL_CTX *ctx" +.Fc +.Ft X509_VERIFY_PARAM * +.Fo SSL_get0_param +.Fa "SSL *ssl" +.Fc +.Ft int +.Fo SSL_CTX_set1_param +.Fa "SSL_CTX *ctx" +.Fa "X509_VERIFY_PARAM *vpm" +.Fc +.Ft int +.Fo SSL_set1_param +.Fa "SSL *ssl" +.Fa "X509_VERIFY_PARAM *vpm" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_get0_param +and +.Fn SSL_get0_param +retrieve an internal pointer to the verification parameters for +.Fa ctx +or +.Fa ssl , +respectively. +The returned pointer must not be freed by the calling application, +but the application can modify the parameters pointed to, +to suit its needs: for example to add a hostname check. +.Pp +.Fn SSL_CTX_set1_param +and +.Fn SSL_set1_param +set the verification parameters to +.Fa vpm +for +.Fa ctx +or +.Fa ssl . +.Sh RETURN VALUES +.Fn SSL_CTX_get0_param +and +.Fn SSL_get0_param +return a pointer to an +.Vt X509_VERIFY_PARAM +structure. +.Pp +.Fn SSL_CTX_set1_param +and +.Fn SSL_set1_param +return 1 for success or 0 for failure. +.Sh EXAMPLES +Check that the hostname matches +.Pa www.foo.com +in the peer certificate: +.Bd -literal -offset indent +X509_VERIFY_PARAM *vpm = SSL_get0_param(ssl); +X509_VERIFY_PARAM_set1_host(vpm, "www.foo.com", 0); +.Ed +.Sh SEE ALSO +.Xr ssl 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn SSL_CTX_set1_param +and +.Fn SSL_set1_param +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn SSL_CTX_get0_param +and +.Fn SSL_get0_param +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_set_SSL_CTX.3 b/Libraries/libressl/man/SSL_set_SSL_CTX.3 new file mode 100644 index 000000000..2abaefb29 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_SSL_CTX.3 @@ -0,0 +1,67 @@ +.\" $OpenBSD: SSL_set_SSL_CTX.3,v 1.4 2022/07/13 22:05:53 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 13 2022 $ +.Dt SSL_SET_SSL_CTX 3 +.Os +.Sh NAME +.Nm SSL_set_SSL_CTX +.Nd modify an SSL connection object to use another context +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_CTX * +.Fo SSL_set_SSL_CTX +.Fa "SSL *ssl" +.Fa "SSL_CTX* ctx" +.Fc +.Sh DESCRIPTION +.Fn SSL_set_SSL_CTX +causes +.Fa ssl +to use the context +.Fa ctx . +.Pp +If +.Fa ctx +is +.Dv NULL , +.Fa ssl +reverts to using the context that it was initially created from with +.Xr SSL_new 3 . +.Pp +If +.Fa ssl +already uses +.Fa ctx , +no action occurs. +.Sh RETURN VALUES +.Fn SSL_set_SSL_CTX +returns an internal pointer to the context that +.Fa ssl +is using as a result of the call, or +.Dv NULL +if memory allocation fails. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_get_SSL_CTX 3 , +.Xr SSL_new 3 , +.Xr SSL_set_security_level 3 +.Sh HISTORY +.Fn SSL_set_SSL_CTX +first appeared in OpenSSL 0.9.8f and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/SSL_set_bio.3 b/Libraries/libressl/man/SSL_set_bio.3 new file mode 100644 index 000000000..e727f442d --- /dev/null +++ b/Libraries/libressl/man/SSL_set_bio.3 @@ -0,0 +1,99 @@ +.\" $OpenBSD: SSL_set_bio.3,v 1.6 2020/10/08 18:21:30 tb Exp $ +.\" OpenSSL acb5b343 Sep 16 16:00:38 2000 +0000 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 8 2020 $ +.Dt SSL_SET_BIO 3 +.Os +.Sh NAME +.Nm SSL_set_bio +.Nd connect the SSL object with a BIO +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_set_bio "SSL *ssl" "BIO *rbio" "BIO *wbio" +.Sh DESCRIPTION +.Fn SSL_set_bio +connects the +.Vt BIO Ns +s +.Fa rbio +and +.Fa wbio +for the read and write operations of the TLS/SSL (encrypted) side of +.Fa ssl . +.Pp +The SSL engine inherits the behaviour of +.Fa rbio +and +.Fa wbio , +respectively. +If a +.Vt BIO +is non-blocking, the +.Fa ssl +will also have non-blocking behaviour. +.Pp +If there was already a +.Vt BIO +connected to +.Fa ssl , +.Xr BIO_free 3 +will be called (for both the reading and writing side, if different). +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_get_rbio 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_set_bio +first appeared in SSLeay 0.6.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_set_connect_state.3 b/Libraries/libressl/man/SSL_set_connect_state.3 new file mode 100644 index 000000000..c2072c437 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_connect_state.3 @@ -0,0 +1,153 @@ +.\" $OpenBSD: SSL_set_connect_state.3,v 1.6 2018/03/27 17:35:50 schwarze Exp $ +.\" full merge up to OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" selective merge up to: OpenSSL dbd007d7 Jul 28 13:31:27 2017 +0800 +.\" +.\" This file was written by Lutz Jaenicke +.\" and Paul Yang . +.\" Copyright (c) 2001, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_SET_CONNECT_STATE 3 +.Os +.Sh NAME +.Nm SSL_set_connect_state , +.Nm SSL_set_accept_state , +.Nm SSL_is_server +.Nd prepare SSL object to work in client or server mode +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_set_connect_state "SSL *ssl" +.Ft void +.Fn SSL_set_accept_state "SSL *ssl" +.Ft int +.Fn SSL_is_server "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_set_connect_state +sets +.Fa ssl +to work in client mode. +.Pp +.Fn SSL_set_accept_state +sets +.Fa ssl +to work in server mode. +.Pp +.Fn SSL_is_server +checks whether +.Fa ssl +is set to server mode. +.Pp +When the +.Vt SSL_CTX +object was created with +.Xr SSL_CTX_new 3 , +it was either assigned a dedicated client method, a dedicated server method, or +a generic method, that can be used for both client and server connections. +(The method might have been changed with +.Xr SSL_CTX_set_ssl_version 3 +or +.Xr SSL_set_ssl_method 3 . ) +.Pp +When beginning a new handshake, the SSL engine must know whether it must call +the connect (client) or accept (server) routines. +Even though it may be clear from the method chosen whether client or server +mode was requested, the handshake routines must be explicitly set. +.Pp +When using the +.Xr SSL_connect 3 +or +.Xr SSL_accept 3 +routines, the correct handshake routines are automatically set. +When performing a transparent negotiation using +.Xr SSL_write 3 +or +.Xr SSL_read 3 , +the handshake routines must be explicitly set in advance using either +.Fn SSL_set_connect_state +or +.Fn SSL_set_accept_state . +.Pp +If +.Fn SSL_is_server +is called before +.Fn SSL_set_connect_state +or +.Fn SSL_set_accept_state +was called either automatically or explicitly, +the result depends on what method was used when the +.Fa SSL_CTX +was created. +If a generic method or a dedicated server method was passed to +.Xr SSL_CTX_new 3 , +.Fn SSL_is_server +returns 1; otherwise, it returns 0. +.Sh RETURN VALUES +.Fn SSL_is_server +returns 1 if +.Fa ssl +is set to server mode or 0 if it is set to client mode. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_set_ssl_version 3 , +.Xr SSL_do_handshake 3 , +.Xr SSL_new 3 , +.Xr SSL_read 3 , +.Xr SSL_write 3 +.Sh HISTORY +.Fn SSL_set_connect_state +and +.Fn SSL_set_accept_state +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . +.Pp +.Fn SSL_is_server +first appeared in OpenSSL 1.0.2 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/SSL_set_fd.3 b/Libraries/libressl/man/SSL_set_fd.3 new file mode 100644 index 000000000..7b9727e9a --- /dev/null +++ b/Libraries/libressl/man/SSL_set_fd.3 @@ -0,0 +1,129 @@ +.\" $OpenBSD: SSL_set_fd.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2013 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_SET_FD 3 +.Os +.Sh NAME +.Nm SSL_set_fd , +.Nm SSL_set_rfd , +.Nm SSL_set_wfd +.Nd connect the SSL object with a file descriptor +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_set_fd "SSL *ssl" "int fd" +.Ft int +.Fn SSL_set_rfd "SSL *ssl" "int fd" +.Ft int +.Fn SSL_set_wfd "SSL *ssl" "int fd" +.Sh DESCRIPTION +.Fn SSL_set_fd +sets the file descriptor +.Fa fd +as the input/output facility for the TLS/SSL (encrypted) side of +.Fa ssl . +.Fa fd +will typically be the socket file descriptor of a network connection. +.Pp +When performing the operation, a socket +.Vt BIO +is automatically created to interface between the +.Fa ssl +and +.Fa fd . +The +.Vt BIO +and hence the SSL engine inherit the behaviour of +.Fa fd . +If +.Fa fd +is non-blocking, the +.Fa ssl +will also have non-blocking behaviour. +.Pp +If there was already a +.Vt BIO +connected to +.Fa ssl , +.Xr BIO_free 3 +will be called (for both the reading and writing side, if different). +.Pp +.Fn SSL_set_rfd +and +.Fn SSL_set_wfd +perform the respective action, but only for the read channel or the write +channel, which can be set independently. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The operation failed. +Check the error stack to find out why. +.It 1 +The operation succeeded. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_get_fd 3 , +.Xr SSL_set_bio 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_set_fd +appeared in SSLeay 0.4 or earlier. +.Fn SSL_set_rfd +and +.Fn SSL_set_wfd +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_set_max_send_fragment.3 b/Libraries/libressl/man/SSL_set_max_send_fragment.3 new file mode 100644 index 000000000..7de087a74 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_max_send_fragment.3 @@ -0,0 +1,97 @@ +.\" $OpenBSD: SSL_set_max_send_fragment.3,v 1.5 2019/06/12 09:36:30 schwarze Exp $ +.\" OpenSSL doc/man3/SSL_CTX_set_split_send_fragment.pod +.\" OpenSSL 6782e5fd Oct 21 16:16:20 2016 +0100 +.\" +.\" This file was written by Matt Caswell . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 12 2019 $ +.Dt SSL_SET_MAX_SEND_FRAGMENT 3 +.Os +.Sh NAME +.Nm SSL_CTX_set_max_send_fragment , +.Nm SSL_set_max_send_fragment +.Nd control fragment sizes +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fo SSL_CTX_set_max_send_fragment +.Fa "SSL_CTX *ctx" +.Fa "long m" +.Fc +.Ft long +.Fo SSL_set_max_send_fragment +.Fa "SSL *ssl" +.Fa "long m" +.Fc +.Sh DESCRIPTION +.Fn SSL_CTX_set_max_send_fragment +and +.Fn SSL_set_max_send_fragment +set the +.Sy max_send_fragment +parameter for SSL_CTX and SSL objects respectively. +This value restricts the amount of plaintext bytes that will be sent in +any one SSL/TLS record. +By default its value is SSL3_RT_MAX_PLAIN_LENGTH (16384). +These functions will only accept a value in the range 512 - +SSL3_RT_MAX_PLAIN_LENGTH. +.Pp +These functions are implemented using macros. +.Sh RETURN VALUES +These functions return 1 on success or 0 on failure. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_ctrl 3 , +.Xr SSL_CTX_set_read_ahead 3 , +.Xr SSL_pending 3 +.Sh HISTORY +.Fn SSL_CTX_set_max_send_fragment +and +.Fn SSL_set_max_send_fragment +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/SSL_set_psk_use_session_callback.3 b/Libraries/libressl/man/SSL_set_psk_use_session_callback.3 new file mode 100644 index 000000000..7f2bfcc01 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_psk_use_session_callback.3 @@ -0,0 +1,86 @@ +.\" $OpenBSD: SSL_set_psk_use_session_callback.3,v 1.1 2021/09/14 14:30:57 schwarze Exp $ +.\" OpenSSL man3/SSL_CTX_set_psk_client_callback.pod +.\" checked up to 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 14 2021 $ +.Dt SSL_SET_PSK_USE_SESSION_CALLBACK 3 +.Os +.Sh NAME +.Nm SSL_set_psk_use_session_callback , +.Nm SSL_psk_use_session_cb_func +.Nd set TLS pre-shared key client callback +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft typedef int +.Fo (*SSL_psk_use_session_cb_func) +.Fa "SSL *ssl" +.Fa "const EVP_MD *md" +.Fa "const unsigned char **id" +.Fa "size_t *idlen" +.Fa "SSL_SESSION **session" +.Fc +.Ft void +.Fo SSL_set_psk_use_session_callback +.Fa "SSL *ssl" +.Fa "SSL_psk_use_session_cb_func cb" +.Fc +.Sh DESCRIPTION +LibreSSL provides the stub function +.Fn SSL_set_psk_use_session_callback +to allow compiling application programs +that contain optional support for TLSv1.3 pre-shared keys. +.Pp +LibreSSL does not support TLS pre-shared keys, +and no action occurs when +.Fn SSL_set_psk_use_session_callback +is called. +In particular, both arguments are ignored. +During session negotiation, +LibreSSL never calls the callback +.Fa cb +and always behaves as if that callback succeeded and set the +.Pf * Fa session +pointer to +.Dv NULL . +That is, LibreSSL never sends a pre-shared key to the server +and never aborts the handshake for lack of a pre-shared key. +.Pp +With OpenSSL, a client application wishing to use TLSv1.3 pre-shared keys +can install a callback function +.Fa cb +using +.Fn SSL_set_psk_use_session_callback . +The OpenSSL library may call +.Fa cb +once or twice during session negotiation. +If the callback fails, OpenSSL aborts connection setup. +If the callback succeeds but sets the +.Pf * Fa session +pointer to +.Dv NULL , +OpenSSL continues the handshake +but does not send a pre-shared key to the server. +.Sh RETURN VALUES +The +.Fn SSL_psk_use_session_cb_func +callback is expected to return 1 on success or 0 on failure. +.Sh HISTORY +.Fn SSL_set_psk_use_session_callback +and +.Fn SSL_psk_use_session_cb_func +first appeared in OpenSSL 1.1.1 and have been available since +.Ox 7.0 . diff --git a/Libraries/libressl/man/SSL_set_session.3 b/Libraries/libressl/man/SSL_set_session.3 new file mode 100644 index 000000000..7d85f5ad0 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_session.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: SSL_set_session.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_SET_SESSION 3 +.Os +.Sh NAME +.Nm SSL_set_session +.Nd set a TLS/SSL session to be used during TLS/SSL connect +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_set_session "SSL *ssl" "SSL_SESSION *session" +.Sh DESCRIPTION +.Fn SSL_set_session +sets +.Fa session +to be used when the TLS/SSL connection is to be established. +.Fn SSL_set_session +is only useful for TLS/SSL clients. +When the session is set, the reference count of +.Fa session +is incremented +by 1. +If the session is not reused, the reference count is decremented again during +.Fn SSL_connect . +Whether the session was reused can be queried with the +.Xr SSL_session_reused 3 +call. +.Pp +If there is already a session set inside +.Fa ssl +(because it was set with +.Fn SSL_set_session +before or because the same +.Fa ssl +was already used for a connection), +.Xr SSL_SESSION_free 3 +will be called for that session. +.Pp +.Vt SSL_SESSION +objects keep internal link information about the session cache list when being +inserted into one +.Vt SSL_CTX +object's session cache. +One +.Vt SSL_SESSION +object, regardless of its reference count, must therefore only be used with one +.Vt SSL_CTX +object (and the +.Vt SSL +objects created from this +.Vt SSL_CTX +object). +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The operation failed; check the error stack to find out the reason. +.It 1 +The operation succeeded. +.El +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_get_session 3 , +.Xr SSL_SESSION_free 3 , +.Xr SSL_session_reused 3 +.Sh HISTORY +.Fn SSL_set_session +first appeared in SSLeay 0.5.2 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_set_shutdown.3 b/Libraries/libressl/man/SSL_set_shutdown.3 new file mode 100644 index 000000000..678086f88 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_shutdown.3 @@ -0,0 +1,138 @@ +.\" $OpenBSD: SSL_set_shutdown.3,v 1.6 2021/06/11 19:41:39 jmc Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 11 2021 $ +.Dt SSL_SET_SHUTDOWN 3 +.Os +.Sh NAME +.Nm SSL_set_shutdown , +.Nm SSL_get_shutdown +.Nd manipulate shutdown state of an SSL connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_set_shutdown "SSL *ssl" "int mode" +.Ft int +.Fn SSL_get_shutdown "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_set_shutdown +sets the shutdown state of +.Fa ssl +to +.Fa mode . +.Pp +.Fn SSL_get_shutdown +returns the shutdown mode of +.Fa ssl . +.Pp +The shutdown state of an ssl connection is a bitmask of: +.Bl -tag -width Ds +.It 0 +No shutdown setting, yet. +.It Dv SSL_SENT_SHUTDOWN +A +.Dq close notify +shutdown alert was sent to the peer; the connection is being considered closed +and the session is closed and correct. +.It Dv SSL_RECEIVED_SHUTDOWN +A shutdown alert was received form the peer, either a normal +.Dq close notify +or a fatal error. +.El +.Pp +.Dv SSL_SENT_SHUTDOWN +and +.Dv SSL_RECEIVED_SHUTDOWN +can be set at the same time. +.Pp +The shutdown state of the connection is used to determine the state of the +.Fa ssl +session. +If the session is still open when +.Xr SSL_clear 3 +or +.Xr SSL_free 3 +is called, it is considered bad and removed according to RFC 2246. +The actual condition for a correctly closed session is +.Dv SSL_SENT_SHUTDOWN +(according to the TLS RFC, it is acceptable to only send the +.Dq close notify +alert but to not wait for the peer's answer when the underlying connection is +closed). +.Fn SSL_set_shutdown +can be used to set this state without sending a close alert to the peer (see +.Xr SSL_shutdown 3 ) . +.Pp +If a +.Dq close notify +was received, +.Dv SSL_RECEIVED_SHUTDOWN +will be set, but to set +.Dv SSL_SENT_SHUTDOWN +the application must still call +.Xr SSL_shutdown 3 +or +.Fn SSL_set_shutdown +itself. +.Sh RETURN VALUES +.Fn SSL_get_shutdown +returns the current setting. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_clear 3 , +.Xr SSL_CTX_set_quiet_shutdown 3 , +.Xr SSL_free 3 , +.Xr SSL_shutdown 3 +.Sh HISTORY +.Fn SSL_set_shutdown +and +.Fn SSL_get_shutdown +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_set_tmp_ecdh.3 b/Libraries/libressl/man/SSL_set_tmp_ecdh.3 new file mode 100644 index 000000000..8fd2d9fd5 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_tmp_ecdh.3 @@ -0,0 +1,119 @@ +.\" $OpenBSD: SSL_set_tmp_ecdh.3,v 1.6 2021/11/30 15:58:08 jsing Exp $ +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 30 2021 $ +.Dt SSL_SET_TMP_ECDH 3 +.Os +.Sh NAME +.Nm SSL_set_tmp_ecdh , +.Nm SSL_CTX_set_tmp_ecdh , +.Nm SSL_set_ecdh_auto , +.Nm SSL_CTX_set_ecdh_auto , +.Nm SSL_set_tmp_ecdh_callback , +.Nm SSL_CTX_set_tmp_ecdh_callback +.Nd select a curve for ECDH ephemeral key exchange +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft long +.Fo SSL_set_tmp_ecdh +.Fa "SSL *ssl" +.Fa "EC_KEY *ecdh" +.Fc +.Ft long +.Fo SSL_CTX_set_tmp_ecdh +.Fa "SSL_CTX *ctx" +.Fa "EC_KEY *ecdh" +.Fc +.Ft long +.Fo SSL_set_ecdh_auto +.Fa "SSL *ssl" +.Fa "int state" +.Fc +.Ft long +.Fo SSL_CTX_set_ecdh_auto +.Fa "SSL_CTX *ctx" +.Fa "int state" +.Fc +.Ft void +.Fo SSL_set_tmp_ecdh_callback +.Fa "SSL *ssl" +.Fa "EC_KEY *(*ecdh)(SSL *ssl, int is_export, int keylength)" +.Fc +.Ft void +.Fo SSL_CTX_set_tmp_ecdh_callback +.Fa "SSL_CTX *ctx" +.Fa "EC_KEY *(*ecdh)(SSL *ssl, int is_export, int keylength)" +.Fc +.Sh DESCRIPTION +Automatic EC curve selection and generation is always enabled in +LibreSSL, and applications cannot manually provide EC keys for use +with ECDH key exchange. +.Pp +The only remaining effect of +.Fn SSL_set_tmp_ecdh +is that the curve of the given +.Fa ecdh +key becomes the only curve enabled for the +.Fa ssl +connection, so it is equivalent to calling +.Xr SSL_set1_groups_list 3 +with the same single curve name. +.Pp +.Fn SSL_CTX_set_tmp_ecdh +has the same effect on all connections that will be created from +.Fa ctx +in the future. +.Pp +The functions +.Fn SSL_set_ecdh_auto , +.Fn SSL_CTX_set_ecdh_auto , +.Fn SSL_set_tmp_ecdh_callback , +and +.Fn SSL_CTX_set_tmp_ecdh_callback +are deprecated and have no effect. +.Sh RETURN VALUES +.Fn SSL_set_tmp_ecdh +and +.Fn SSL_CTX_set_tmp_ecdh +return 1 on success or 0 on failure. +.Pp +.Fn SSL_set_ecdh_auto , +.Fn SSL_CTX_set_ecdh_auto , +.Fn SSL_set_tmp_ecdh_callback , +and +.Fn SSL_CTX_set_tmp_ecdh_callback +always return 1. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set1_groups 3 , +.Xr SSL_CTX_set_cipher_list 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_CTX_set_tmp_dh_callback 3 , +.Xr SSL_new 3 +.Sh HISTORY +.Fn SSL_set_tmp_ecdh , +.Fn SSL_CTX_set_tmp_ecdh , +.Fn SSL_set_tmp_ecdh_callback , +and +.Fn SSL_CTX_set_tmp_ecdh_callback +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn SSL_CTX_set_ecdh_auto +and +.Fn SSL_set_ecdh_auto +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 5.7 . diff --git a/Libraries/libressl/man/SSL_set_verify_result.3 b/Libraries/libressl/man/SSL_set_verify_result.3 new file mode 100644 index 000000000..4b7cc6ec3 --- /dev/null +++ b/Libraries/libressl/man/SSL_set_verify_result.3 @@ -0,0 +1,90 @@ +.\" $OpenBSD: SSL_set_verify_result.3,v 1.5 2020/03/29 17:05:02 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 29 2020 $ +.Dt SSL_SET_VERIFY_RESULT 3 +.Os +.Sh NAME +.Nm SSL_set_verify_result +.Nd override result of peer certificate verification +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft void +.Fn SSL_set_verify_result "SSL *ssl" "long verify_result" +.Sh DESCRIPTION +.Fn SSL_set_verify_result +sets +.Fa verify_result +of the object +.Fa ssl +to be the result of the verification of the X509 certificate presented by the +peer, if any. +.Pp +.Fn SSL_set_verify_result +overrides the verification result. +It only changes the verification result of the +.Fa ssl +object. +It does not become part of the established session, so if the session is to be +reused later, the original value will reappear. +.Pp +The valid codes for +.Fa verify_result +are documented in +.Xr openssl 1 . +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ssl 3 , +.Xr SSL_get_peer_certificate 3 , +.Xr SSL_get_verify_result 3 +.Sh HISTORY +.Fn SSL_set_verify_result +first appeared in SSLeay 0.6.1 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_shutdown.3 b/Libraries/libressl/man/SSL_shutdown.3 new file mode 100644 index 000000000..bfb1e91ea --- /dev/null +++ b/Libraries/libressl/man/SSL_shutdown.3 @@ -0,0 +1,253 @@ +.\" $OpenBSD: SSL_shutdown.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2000, 2001, 2004, 2014 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_SHUTDOWN 3 +.Os +.Sh NAME +.Nm SSL_shutdown +.Nd shut down a TLS/SSL connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_shutdown "SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_shutdown +shuts down an active TLS/SSL connection. +It sends the +.Dq close notify +shutdown alert to the peer. +.Pp +.Fn SSL_shutdown +tries to send the +.Dq close notify +shutdown alert to the peer. +Whether the operation succeeds or not, the +.Dv SSL_SENT_SHUTDOWN +flag is set and a currently open session is considered closed and good and will +be kept in the session cache for further reuse. +.Pp +The shutdown procedure consists of 2 steps: the sending of the +.Dq close notify +shutdown alert and the reception of the peer's +.Dq close notify +shutdown alert. +According to the TLS standard, it is acceptable for an application to only send +its shutdown alert and then close the underlying connection without waiting for +the peer's response (this way resources can be saved, as the process can +already terminate or serve another connection). +When the underlying connection shall be used for more communications, +the complete shutdown procedure (bidirectional +.Dq close notify +alerts) must be performed, so that the peers stay synchronized. +.Pp +.Fn SSL_shutdown +supports both uni- and bidirectional shutdown by its 2 step behavior. +.Pp +When the application is the first party to send the +.Dq close notify +alert, +.Fn SSL_shutdown +will only send the alert and then set the +.Dv SSL_SENT_SHUTDOWN +flag (so that the session is considered good and will be kept in cache). +.Fn SSL_shutdown +will then return 0. +If a unidirectional shutdown is enough +(the underlying connection shall be closed anyway), this first call to +.Fn SSL_shutdown +is sufficient. +In order to complete the bidirectional shutdown handshake, +.Fn SSL_shutdown +must be called again. +The second call will make +.Fn SSL_shutdown +wait for the peer's +.Dq close notify +shutdown alert. +On success, the second call to +.Fn SSL_shutdown +will return 1. +.Pp +If the peer already sent the +.Dq close notify +alert and it was already processed implicitly inside another function +.Pq Xr SSL_read 3 , +the +.Dv SSL_RECEIVED_SHUTDOWN +flag is set. +.Fn SSL_shutdown +will send the +.Dq close notify +alert, set the +.Dv SSL_SENT_SHUTDOWN +flag and will immediately return with 1. +Whether +.Dv SSL_RECEIVED_SHUTDOWN +is already set can be checked using the +.Fn SSL_get_shutdown +(see also the +.Xr SSL_set_shutdown 3 +call). +.Pp +It is therefore recommended to check the return value of +.Fn SSL_shutdown +and call +.Fn SSL_shutdown +again, if the bidirectional shutdown is not yet complete (return value of the +first call is 0). +.Pp +The behaviour of +.Fn SSL_shutdown +additionally depends on the underlying +.Vt BIO . +.Pp +If the underlying +.Vt BIO +is +.Em blocking , +.Fn SSL_shutdown +will only return once the +handshake step has been finished or an error occurred. +.Pp +If the underlying +.Vt BIO +is +.Em non-blocking , +.Fn SSL_shutdown +will also return when the underlying +.Vt BIO +could not satisfy the needs of +.Fn SSL_shutdown +to continue the handshake. +In this case a call to +.Xr SSL_get_error 3 +with the +return value of +.Fn SSL_shutdown +will yield +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE . +The calling process then must repeat the call after taking appropriate action +to satisfy the needs of +.Fn SSL_shutdown . +The action depends on the underlying +.Vt BIO . +When using a non-blocking socket, nothing is to be done, but +.Xr select 2 +can be used to check for the required condition. +When using a buffering +.Vt BIO , +like a +.Vt BIO +pair, data must be written into or retrieved out of the +.Vt BIO +before being able to continue. +.Pp +.Fn SSL_shutdown +can be modified to only set the connection to +.Dq shutdown +state but not actually send the +.Dq close notify +alert messages; see +.Xr SSL_CTX_set_quiet_shutdown 3 . +When +.Dq quiet shutdown +is enabled, +.Fn SSL_shutdown +will always succeed and return 1. +.Sh RETURN VALUES +The following return values can occur: +.Bl -tag -width Ds +.It 0 +The shutdown is not yet finished. +Call +.Fn SSL_shutdown +for a second time, if a bidirectional shutdown shall be performed. +The output of +.Xr SSL_get_error 3 +may be misleading, as an erroneous +.Dv SSL_ERROR_SYSCALL +may be flagged even though no error occurred. +.It 1 +The shutdown was successfully completed. +The +.Dq close notify +alert was sent and the peer's +.Dq close notify +alert was received. +.It \(mi1 +The shutdown was not successful because a fatal error occurred either +at the protocol level or a connection failure occurred. +It can also occur if action is need to continue the operation for non-blocking +.Vt BIO Ns +s. +Call +.Xr SSL_get_error 3 +with the return value +.Fa ret +to find out the reason. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_clear 3 , +.Xr SSL_connect 3 , +.Xr SSL_CTX_set_quiet_shutdown 3 , +.Xr SSL_free 3 , +.Xr SSL_get_error 3 , +.Xr SSL_set_shutdown 3 +.Sh HISTORY +.Fn SSL_shutdown +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_state_string.3 b/Libraries/libressl/man/SSL_state_string.3 new file mode 100644 index 000000000..107033544 --- /dev/null +++ b/Libraries/libressl/man/SSL_state_string.3 @@ -0,0 +1,110 @@ +.\" $OpenBSD: SSL_state_string.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_STATE_STRING 3 +.Os +.Sh NAME +.Nm SSL_state_string , +.Nm SSL_state_string_long +.Nd get textual description of state of an SSL object +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft const char * +.Fn SSL_state_string "const SSL *ssl" +.Ft const char * +.Fn SSL_state_string_long "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_state_string +returns a 6 letter string indicating the current state of the +.Vt SSL +object +.Fa ssl . +.Pp +.Fn SSL_state_string_long +returns a string indicating the current state of the +.Vt SSL +object +.Fa ssl . +.Pp +During its use, an +.Vt SSL +object passes several states. +The state is internally maintained. +Querying the state information is not very informative before or when a +connection has been established. +It however can be of significant interest during the handshake. +.Pp +When using non-blocking sockets, +the function call performing the handshake may return with +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE +condition, so that +.Fn SSL_state_string[_long] +may be called. +.Pp +For both blocking or non-blocking sockets, +the details state information can be used within the +.Fn info_callback +function set with the +.Xr SSL_set_info_callback 3 +call. +.Sh RETURN VALUES +Detailed description of possible states to be included later. +.Sh SEE ALSO +.Xr ssl 3 , +.Xr SSL_CTX_set_info_callback 3 +.Sh HISTORY +.Fn SSL_state_string +and +.Fn SSL_state_string_long +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_want.3 b/Libraries/libressl/man/SSL_want.3 new file mode 100644 index 000000000..24e8645ba --- /dev/null +++ b/Libraries/libressl/man/SSL_want.3 @@ -0,0 +1,161 @@ +.\" $OpenBSD: SSL_want.3,v 1.5 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt SSL_WANT 3 +.Os +.Sh NAME +.Nm SSL_want , +.Nm SSL_want_nothing , +.Nm SSL_want_read , +.Nm SSL_want_write , +.Nm SSL_want_x509_lookup +.Nd obtain state information TLS/SSL I/O operation +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_want "const SSL *ssl" +.Ft int +.Fn SSL_want_nothing "const SSL *ssl" +.Ft int +.Fn SSL_want_read "const SSL *ssl" +.Ft int +.Fn SSL_want_write "const SSL *ssl" +.Ft int +.Fn SSL_want_x509_lookup "const SSL *ssl" +.Sh DESCRIPTION +.Fn SSL_want +returns state information for the +.Vt SSL +object +.Fa ssl . +.Pp +The other +.Fn SSL_want_* +calls are shortcuts for the possible states returned by +.Fn SSL_want . +.Pp +.Fn SSL_want +examines the internal state information of the +.Vt SSL +object. +Its return values are similar to those of +.Xr SSL_get_error 3 . +Unlike +.Xr SSL_get_error 3 , +which also evaluates the error queue, +the results are obtained by examining an internal state flag only. +The information must therefore only be used for normal operation under +non-blocking I/O. +Error conditions are not handled and must be treated using +.Xr SSL_get_error 3 . +.Pp +The result returned by +.Fn SSL_want +should always be consistent with the result of +.Xr SSL_get_error 3 . +.Sh RETURN VALUES +The following return values can currently occur for +.Fn SSL_want : +.Bl -tag -width Ds +.It Dv SSL_NOTHING +There is no data to be written or to be read. +.It Dv SSL_WRITING +There are data in the SSL buffer that must be written to the underlying +.Vt BIO +layer in order to complete the actual +.Fn SSL_* +operation. +A call to +.Xr SSL_get_error 3 +should return +.Dv SSL_ERROR_WANT_WRITE . +.It Dv SSL_READING +More data must be read from the underlying +.Vt BIO +layer in order to +complete the actual +.Fn SSL_* +operation. +A call to +.Xr SSL_get_error 3 +should return +.Dv SSL_ERROR_WANT_READ . +.It Dv SSL_X509_LOOKUP +The operation did not complete because an application callback set by +.Xr SSL_CTX_set_client_cert_cb 3 +has asked to be called again. +A call to +.Xr SSL_get_error 3 +should return +.Dv SSL_ERROR_WANT_X509_LOOKUP . +.El +.Pp +.Fn SSL_want_nothing , +.Fn SSL_want_read , +.Fn SSL_want_write , +and +.Fn SSL_want_x509_lookup +return 1 when the corresponding condition is true or 0 otherwise. +.Sh SEE ALSO +.Xr err 3 , +.Xr ssl 3 , +.Xr SSL_get_error 3 +.Sh HISTORY +.Fn SSL_want , +.Fn SSL_want_nothing , +.Fn SSL_want_read , +and +.Fn SSL_want_write +first appeared in SSLeay 0.5.2. +.Fn SSL_want_x509_lookup +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/SSL_write.3 b/Libraries/libressl/man/SSL_write.3 new file mode 100644 index 000000000..2c6fbcef0 --- /dev/null +++ b/Libraries/libressl/man/SSL_write.3 @@ -0,0 +1,249 @@ +.\" $OpenBSD: SSL_write.3,v 1.7 2021/10/24 15:10:13 schwarze Exp $ +.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" partial merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file was written by Lutz Jaenicke +.\" and Matt Caswell . +.\" Copyright (c) 2000, 2001, 2002, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 24 2021 $ +.Dt SSL_WRITE 3 +.Os +.Sh NAME +.Nm SSL_write_ex , +.Nm SSL_write +.Nd write bytes to a TLS connection +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft int +.Fn SSL_write_ex "SSL *ssl" "const void *buf" "size_t num" "size_t *written" +.Ft int +.Fn SSL_write "SSL *ssl" "const void *buf" "int num" +.Sh DESCRIPTION +.Fn SSL_write_ex +and +.Fn SSL_write +write +.Fa num +bytes from the buffer +.Fa buf +into the specified +.Fa ssl +connection. +On success +.Fn SSL_write_ex +stores the number of bytes written in +.Pf * Fa written . +.Pp +In the following, +.Fn SSL_write_ex +and +.Fn SSL_write +are called +.Dq write functions . +.Pp +If necessary, a write function negotiates a TLS session, +if not already explicitly performed by +.Xr SSL_connect 3 +or +.Xr SSL_accept 3 . +If the peer requests a re-negotiation, +it will be performed transparently during the +write function operation. +The behaviour of the write functions depends on the underlying +.Vt BIO . +.Pp +For the transparent negotiation to succeed, the +.Fa ssl +must have been initialized to client or server mode. +This is done by calling +.Xr SSL_set_connect_state 3 +or +.Xr SSL_set_accept_state 3 +before the first call to a write function. +.Pp +If the underlying +.Vt BIO +is +.Em blocking , +the write function +will only return once the write operation has been finished or an error +occurred, except when a renegotiation takes place, in which case a +.Dv SSL_ERROR_WANT_READ +may occur. +This behaviour can be controlled with the +.Dv SSL_MODE_AUTO_RETRY +flag of the +.Xr SSL_CTX_set_mode 3 +call. +.Pp +If the underlying +.Vt BIO +is +.Em non-blocking , +the write function will also return when the underlying +.Vt BIO +could not satisfy the needs of the function to continue the operation. +In this case a call to +.Xr SSL_get_error 3 +with the return value of the write function will yield +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE . +As at any time a re-negotiation is possible, a call to +a write function can also cause read operations. +The calling process then must repeat the call after taking appropriate action +to satisfy the needs of the write function. +The action depends on the underlying +.Vt BIO . +When using a non-blocking socket, nothing is to be done, but +.Xr select 2 +can be used to check for the required condition. +When using a buffering +.Vt BIO , +like a +.Vt BIO +pair, data must be written into or retrieved out of the BIO before being able +to continue. +.Pp +The write functions +will only return with success when the complete contents of +.Fa buf +of length +.Fa num +have been written. +This default behaviour can be changed with the +.Dv SSL_MODE_ENABLE_PARTIAL_WRITE +option of +.Xr SSL_CTX_set_mode 3 . +When this flag is set, the write functions will also return with +success when a partial write has been successfully completed. +In this case the write function operation is considered completed. +The bytes are sent and a new write call with a new buffer (with the +already sent bytes removed) must be started. +A partial write is performed with the size of a message block, +which is 16kB. +.Pp +When a write function call has to be repeated because +.Xr SSL_get_error 3 +returned +.Dv SSL_ERROR_WANT_READ +or +.Dv SSL_ERROR_WANT_WRITE , +it must be repeated with the same arguments. +.Pp +When calling +.Fn SSL_write +with +.Fa num Ns =0 +bytes to be sent, the behaviour is undefined. +.Fn SSL_write_ex +can be called with +.Fa num Ns =0 , +but will not send application data to the peer. +.Sh RETURN VALUES +.Fn SSL_write_ex +returns 1 for success or 0 for failure. +Success means that all requested application data bytes have been +written to the TLS connection or, if +.Dv SSL_MODE_ENABLE_PARTIAL_WRITE +is in use, at least one application data byte has been written +to the TLS connection. +Failure means that not all the requested bytes have been written yet (if +.Dv SSL_MODE_ENABLE_PARTIAL_WRITE +is not in use) or no bytes could be written to the TLS connection (if +.Dv SSL_MODE_ENABLE_PARTIAL_WRITE +is in use). +Failures can be retryable (e.g. the network write buffer has temporarily +filled up) or non-retryable (e.g. a fatal network error). +In the event of a failure, call +.Xr SSL_get_error 3 +to find out the reason +which indicates whether the call is retryable or not. +.Pp +For +.Fn SSL_write , +the following return values can occur: +.Bl -tag -width Ds +.It >0 +The write operation was successful. +The return value is the number of bytes actually written to the TLS +connection. +.It 0 +The write operation was not successful. +Probably the underlying connection was closed. +Call +.Xr SSL_get_error 3 +with the return value to find out whether an error occurred or the connection +was shut down cleanly +.Pq Dv SSL_ERROR_ZERO_RETURN . +.It <0 +The write operation was not successful, because either an error occurred or +action must be taken by the calling process. +Call +.Xr SSL_get_error 3 +with the return value to find out the reason. +.El +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ssl 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_set_mode 3 , +.Xr SSL_get_error 3 , +.Xr SSL_read 3 , +.Xr SSL_set_connect_state 3 +.Sh HISTORY +.Fn SSL_write +appeared in SSLeay 0.4 or earlier and has been available since +.Ox 2.4 . +.Pp +.Fn SSL_write_ex +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/STACK_OF.3 b/Libraries/libressl/man/STACK_OF.3 new file mode 100644 index 000000000..4c627eed9 --- /dev/null +++ b/Libraries/libressl/man/STACK_OF.3 @@ -0,0 +1,207 @@ +.\" $OpenBSD: STACK_OF.3,v 1.5 2021/10/24 13:10:46 schwarze Exp $ +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 24 2021 $ +.Dt STACK_OF 3 +.Os +.Sh NAME +.Nm STACK_OF +.Nd variable-sized arrays of pointers, called OpenSSL stacks +.Sh SYNOPSIS +.In openssl/safestack.h +.Fn STACK_OF type +.Sh DESCRIPTION +The +.In openssl/safestack.h +header provides a fragile, unusually complicated system of +macro-generated wrappers around the functions described in the +.Xr OPENSSL_sk_new 3 +manual page. +It is intended to implement superficially type-safe variable-sized +arrays of pointers, somewhat misleadingly called +.Dq stacks +by OpenSSL. +Due to the excessive number of API functions, it is impossible to +properly document this system. +In particular, calling +.Xr man 1 +for any of the functions operating on stacks cannot yield any result. +.Pp +Unfortunately, application programs can hardly avoid using the concept +because several important OpenSSL APIs rely on it; see the +.Sx SEE ALSO +section for examples. +Even though both pages are more complicated than any manual page +ought to be, using the concept safely requires a complete understanding +of all the details in both this manual page and in +.Xr OPENSSL_sk_new 3 . +.Pp +The +.Fn STACK_OF +macro takes a +.Fa type +name as its argument, typically the name of a type +that has been defined as an alias for a specific +.Vt struct +type using a +.Sy typedef +declaration. +It expands to an incomplete +.Vt struct +type which is intended to represent a +.Dq stack +of objects of the given +.Fa type . +That type does not actually exist, so it is not possible to define, +for example, an automatic variable +.Ql STACK_OF(X509) my_certificates ; +it is only possible to define pointers to stacks, for example +.Ql STACK_OF(X509) *my_certificates . +The only way such pointers can ever be used is by wrapper functions +casting them to the type +.Vt _STACK * +described in +.Xr OPENSSL_sk_new 3 . +.Pp +For a considerable number of types, OpenSSL provides one wrapper +function for each function described in +.Xr OPENSSL_sk_new 3 . +The names of these wrapper functions are usually constructed by +inserting the name of the type and an underscore after the +.Sq sk_ +prefix of the function name. +Usually, where the real functions take +.Vt void * +arguments, the wrappers take pointers to the +.Fa type +in questions, and where the real functions take +.Vt _STACK * +arguments, the wrappers take pointers to +.Fn STACK_OF type . +The same applies to return values. +Various exceptions to all this exist, but the above applies to +all the types listed below. +.Pp +Using the above may make sense for the following types because +public API functions exist that take stacks of these types as +arguments or return them: +.Vt ASN1_INTEGER , +.Vt ASN1_OBJECT , +.Vt ASN1_UTF8STRING , +.Vt CMS_RecipientInfo , +.Vt CMS_SignerInfo , +.Vt CONF_VALUE , +.Vt GENERAL_NAMES , +.Vt GENERAL_SUBTREE , +.Vt OPENSSL_STRING Pq which is just Vt char * , +.Vt PKCS12_SAFEBAG , +.Vt PKCS7 , +.Vt PKCS7_RECIP_INFO , +.Vt PKCS7_SIGNER_INFO , +.Vt POLICYQUALINFO , +.Vt SRTP_PROTECTION_PROFILE , +.Vt SSL_CIPHER , +.Vt SSL_COMP , +.Vt X509 , +.Vt X509_ALGOR , +.Vt X509_ATTRIBUTE , +.Vt X509_CRL , +.Vt X509_EXTENSION , +.Vt X509_INFO , +.Vt X509_NAME , +.Vt X509_OBJECT , +.Vt X509_POLICY_NODE , +.Vt X509_REVOKED . +.Pp +Additionally, some public API functions use the following types +which are declared with +.Sy typedef : +.Bl -column STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS +.It Vt STACK_OF(ACCESS_DESCRIPTION) Ta Vt AUTHORITY_INFO_ACCESS +.It Vt STACK_OF(ASN1_OBJECT) Ta Vt EXTENDED_KEY_USAGE +.It Vt STACK_OF(ASN1_TYPE) Ta Vt ASN1_SEQUENCE_ANY +.It Vt STACK_OF(DIST_POINT) Ta Vt CRL_DIST_POINTS +.It Vt STACK_OF(GENERAL_NAME) Ta Vt GENERAL_NAMES +.It Vt STACK_OF(IPAddressFamily) Ta Vt IPAddrBlocks +.It Vt STACK_OF(POLICY_MAPPING) Ta Vt POLICY_MAPPINGS +.It Vt STACK_OF(POLICYINFO) Ta Vt CERTIFICATEPOLICIES +.It Vt STACK_OF(X509_ALGOR) Ta Vt X509_ALGORS +.It Vt STACK_OF(X509_EXTENSION) Ta Vt X509_EXTENSIONS +.El +.Pp +Even though the OpenSSL headers declare wrapper functions for many +more types and even though the OpenSSL documentation says that users +can declare their own stack types, using +.Fn STACK_OF +with any type not listed here is strongly discouraged. +For other types, there may be subtle, undocumented differences +in syntax and semantics, and attempting to declare custom stack +types is very error prone; using plain C arrays of pointers to +the desired type is much simpler and less dangerous. +.Sh EXAMPLES +The following program creates a certificate object, puts two +pointers to it on a stack, and uses +.Xr X509_free 3 +to clean up properly: +.Bd -literal +#include +#include +#include + +int +main(void) +{ + STACK_OF(X509) *stack; + X509 *x; + + if ((stack = sk_X509_new_null()) == NULL) + err(1, NULL); + if ((x = X509_new()) == NULL) + err(1, NULL); + if (sk_X509_push(stack, x) == 0) + err(1, NULL); + if (X509_up_ref(x) == 0) + errx(1, "X509_up_ref failed"); + if (sk_X509_push(stack, x) == 0) + err(1, NULL); + printf("%d pointers: %p, %p\en", sk_X509_num(stack), + sk_X509_value(stack, 0), sk_X509_value(stack, 1)); + sk_X509_pop_free(stack, X509_free); + + return 0; +} +.Ed +.Pp +The output looks similar to: +.Pp +.Dl 2 pointers: 0x4693ff24c00, 0x4693ff24c00 +.Sh SEE ALSO +.Xr crypto 3 , +.Xr OCSP_request_sign 3 , +.Xr OPENSSL_sk_new 3 , +.Xr PKCS12_parse 3 , +.Xr PKCS7_encrypt 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr SSL_get_ciphers 3 , +.Xr SSL_get_peer_cert_chain 3 , +.Xr SSL_load_client_CA_file 3 , +.Xr X509_CRL_get_REVOKED 3 , +.Xr X509_STORE_CTX_get0_chain 3 +.Sh HISTORY +The +.Fn STACK_OF +macro first appeared in OpenSSL 0.9.3 and has been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/TS_REQ_new.3 b/Libraries/libressl/man/TS_REQ_new.3 new file mode 100644 index 000000000..8dbd15ea7 --- /dev/null +++ b/Libraries/libressl/man/TS_REQ_new.3 @@ -0,0 +1,182 @@ +.\" $OpenBSD: TS_REQ_new.3,v 1.6 2019/06/06 01:06:59 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt TS_REQ_NEW 3 +.Os +.Sh NAME +.Nm TS_REQ_new , +.Nm TS_REQ_free , +.Nm TS_RESP_new , +.Nm TS_RESP_free , +.Nm TS_STATUS_INFO_new , +.Nm TS_STATUS_INFO_free , +.Nm TS_TST_INFO_new , +.Nm TS_TST_INFO_free , +.Nm TS_ACCURACY_new , +.Nm TS_ACCURACY_free , +.Nm TS_MSG_IMPRINT_new , +.Nm TS_MSG_IMPRINT_free +.Nd X.509 time-stamp protocol +.Sh SYNOPSIS +.In openssl/ts.h +.Ft TS_REQ * +.Fn TS_REQ_new void +.Ft void +.Fn TS_REQ_free "TS_REQ *req" +.Ft TS_RESP * +.Fn TS_RESP_new void +.Ft void +.Fn TS_RESP_free "TS_RESP *resp" +.Ft TS_STATUS_INFO * +.Fn TS_STATUS_INFO_new void +.Ft void +.Fn TS_STATUS_INFO_free "TS_STATUS_INFO *status" +.Ft TS_TST_INFO * +.Fn TS_TST_INFO_new void +.Ft void +.Fn TS_TST_INFO_free "TS_TST_INFO *token" +.Ft TS_ACCURACY * +.Fn TS_ACCURACY_new void +.Ft void +.Fn TS_ACCURACY_free "TS_ACCURACY *accuracy" +.Ft TS_MSG_IMPRINT * +.Fn TS_MSG_IMPRINT_new void +.Ft void +.Fn TS_MSG_IMPRINT_free "TS_MSG_IMPRINT *imprint" +.Sh DESCRIPTION +A time-stamping authority is a trusted third party which allows its +clients to prove that specific data existed at a particular point +in time. +Clients send time-stamping requests to the time-stamping server, +which returns time-stamp tokens to the clients. +.Pp +.Fn TS_REQ_new +allocates and initializes an empty +.Vt TS_REQ +object, representing an ASN.1 +.Vt TimeStampReq +structure defined in RFC 3161 section 2.4.1. +It can hold a hash of the datum to be time-stamped and some +auxiliary, optional information. +.Fn TS_REQ_free +frees +.Fa req . +.Pp +.Fn TS_RESP_new +allocates and initializes an empty +.Vt TS_RESP +object, representing an ASN.1 +.Vt TimeStampResp +structure defined in RFC 3161 section 2.4.2. +It can hold status information and a time-stamp token. +.Fn TS_RESP_free +frees +.Fa resp . +.Pp +.Fn TS_STATUS_INFO_new +allocates and initializes an empty +.Vt TS_STATUS_INFO +object, representing an ASN.1 +.Vt PKIStatusInfo +structure defined in RFC 3161 section 2.4.2. +It is used inside +.Vt TS_RESP +and describes the outcome of one time-stamp request. +.Fn TS_STATUS_INFO_free +frees +.Fa status . +.Pp +.Fn TS_TST_INFO_new +allocates and initializes an empty +.Vt TS_TST_INFO +object, representing an ASN.1 +.Vt TSTInfo +structure defined in RFC 3161 section 2.4.2. +It is the time-stamp token included in a +.Vt TS_RESP +object in case of success, and it can hold the hash of the datum +copied from a request, the time of generation, and some auxiliary +information. +.Fn TS_TST_INFO_free +frees +.Fa token . +.Pp +.Fn TS_ACCURACY_new +allocates and initializes an empty +.Vt TS_ACCURACY +object, representing an ASN.1 +.Vt Accuracy +structure defined in RFC 3161 section 2.4.2. +It can be used inside a +.Vt TS_TST_INFO +object and indicates the maximum error of the time stated in the token. +.Fn TS_ACCURACY_free +frees +.Fa accuracy . +.Pp +.Fn TS_MSG_IMPRINT_new +allocates and initializes an empty +.Vt TS_MSG_IMPRINT +object, representing an ASN.1 +.Vt MessageImprint +structure defined in RFC 3161 section 2.4.1. +It is used inside +.Vt TS_REQ +and +.Vt TS_RESP +objects. +It specifies a hash algorithm and stores the hash value of the datum. +.Fn TS_MSG_IMPRINT_free +frees +.Fa imprint . +.Sh RETURN VALUES +.Fn TS_REQ_new , +.Fn TS_RESP_new , +.Fn TS_STATUS_INFO_new , +.Fn TS_TST_INFO_new , +.Fn TS_ACCURACY_new , +and +.Fn TS_MSG_IMPRINT_new +return the new +.Vt TS_REQ , +.Vt TS_RESP , +.Vt TS_STATUS_INFO , +.Vt TS_TST_INFO , +.Vt TS_ACCURACY , +or +.Vt TS_MSG_IMPRINT +object, respectively, or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr ACCESS_DESCRIPTION_new 3 , +.Xr ESS_SIGNING_CERT_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 3161: Internet X.509 Public Key Infrastructure Time-Stamp Protocol +.Pp +Note that RFC 3161 has been updated +by RFC 5816: ESSCertIDv2 Update for RFC 3161. +That update allows using the Signing Certificate Attribute Definition +Version 2 according to RFC 5035, but the current implementation +only supports the Signing Certificate Attribute Definition Version +1 according to RFC 2634, and hence only supports RFC 3161, but not +RFC 5816 functionality. +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/UI_UTIL_read_pw.3 b/Libraries/libressl/man/UI_UTIL_read_pw.3 new file mode 100644 index 000000000..aa3cefe8d --- /dev/null +++ b/Libraries/libressl/man/UI_UTIL_read_pw.3 @@ -0,0 +1,107 @@ +.\" $OpenBSD: UI_UTIL_read_pw.3,v 1.3 2018/03/22 21:08:22 schwarze Exp $ +.\" full merge up to: OpenSSL 23103a52 Jan 12 15:17:42 2017 +0100 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Richard Levitte . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt UI_UTIL_READ_PW 3 +.Os +.Sh NAME +.Nm UI_UTIL_read_pw , +.Nm UI_UTIL_read_pw_string +.Nd get a password from the user +.Sh SYNOPSIS +.In openssl/ui.h +.Ft int +.Fo UI_UTIL_read_pw_string +.Fa "char *buf" +.Fa "int length" +.Fa "const char *prompt" +.Fa "int verify" +.Fc +.Ft int +.Fo UI_UTIL_read_pw +.Fa "char *buf" +.Fa "char *buff" +.Fa "int size" +.Fa "const char *prompt" +.Fa "int verify" +.Fc +.Sh DESCRIPTION +.Fn UI_UTIL_read_pw_string +asks for a passphrase, using +.Fa prompt +as a prompt, and stores it in +.Fa buf . +The maximum allowed size is given with +.Fa length , +including the terminating NUL byte. +If +.Fa verify +is non-zero, the password will be verified as well. +.Pp +.Fn UI_UTIL_read_pw +does the same as +.Fn UI_UTIL_read_pw_string , +but takes an external buffer +.Fa buff +for the verification passphrase. +.Sh RETURN VALUES +.Fn UI_UTIL_read_pw_string +and +.Fn UI_UTIL_read_pw +return 0 on success or a negative value on error. +.Sh SEE ALSO +.Xr UI_new 3 +.Sh HISTORY +.Fn UI_UTIL_read_pw +and +.Fn UI_UTIL_read_pw_string +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/UI_create_method.3 b/Libraries/libressl/man/UI_create_method.3 new file mode 100644 index 000000000..ffd6b9815 --- /dev/null +++ b/Libraries/libressl/man/UI_create_method.3 @@ -0,0 +1,284 @@ +.\" $OpenBSD: UI_create_method.3,v 1.6 2023/05/22 19:38:04 tb Exp $ +.\" OpenSSL UI_create_method.pod 8e3d46e5 Mar 11 10:51:04 2017 +0100 +.\" +.\" This file was written by Richard Levitte . +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 22 2023 $ +.Dt UI_CREATE_METHOD 3 +.Os +.Sh NAME +.Nm UI_create_method , +.Nm UI_destroy_method , +.Nm UI_method_set_opener , +.Nm UI_method_set_writer , +.Nm UI_method_set_flusher , +.Nm UI_method_set_reader , +.Nm UI_method_set_closer , +.Nm UI_method_set_prompt_constructor , +.Nm UI_method_get_opener , +.Nm UI_method_get_writer , +.Nm UI_method_get_flusher , +.Nm UI_method_get_reader , +.Nm UI_method_get_closer , +.Nm UI_method_get_prompt_constructor +.Nd user interface method creation and destruction +.Sh SYNOPSIS +.In openssl/ui.h +.Ft UI_METHOD * +.Fo UI_create_method +.Fa "const char *name" +.Fc +.Ft void +.Fo UI_destroy_method +.Fa "UI_METHOD *ui_method" +.Fc +.Ft int +.Fo UI_method_set_opener +.Fa "UI_METHOD *method" +.Fa "int (*opener)(UI *ui)" +.Fc +.Ft int +.Fo UI_method_set_writer +.Fa "UI_METHOD *method" +.Fa "int (*writer)(UI *ui, UI_STRING *uis)" +.Fc +.Ft int +.Fo UI_method_set_flusher +.Fa "UI_METHOD *method" +.Fa "int (*flusher)(UI *ui)" +.Fc +.Ft int +.Fo UI_method_set_reader +.Fa "UI_METHOD *method" +.Fa "int (*reader)(UI *ui, UI_STRING *uis)" +.Fc +.Ft int +.Fo UI_method_set_closer +.Fa "UI_METHOD *method" +.Fa "int (*closer)(UI *ui)" +.Fc +.Ft int +.Fo UI_method_set_prompt_constructor +.Fa "UI_METHOD *method" +.Fa "char *(*prompt_constructor)(UI *ui, const char *object_desc,\ + const char *object_name)" +.Fc +.Ft int +.Fo "(*UI_method_get_opener(const UI_METHOD *method))" +.Fa "UI *" +.Fc +.Ft int +.Fo "(*UI_method_get_writer(const UI_METHOD *method))" +.Fa "UI *" +.Fa "UI_STRING *" +.Fc +.Ft int +.Fo "(*UI_method_get_flusher(const UI_METHOD *method))" +.Fa "UI *" +.Fc +.Ft int +.Fo "(*UI_method_get_reader(const UI_METHOD *method))" +.Fa "UI *" +.Fa "UI_STRING *" +.Fc +.Ft int +.Fo "(*UI_method_get_closer(const UI_METHOD *method))" +.Fa "UI *" +.Fc +.Ft char * +.Fo "(*UI_method_get_prompt_constructor(UI_METHOD *method))" +.Fa "UI *" +.Fa "const char *" +.Fa "const char *" +.Fc +.Sh DESCRIPTION +A method contains a few functions that implement the low level of the +User Interface. +These functions are: +.Bl -tag -width Ds +.It an opener +This function takes a reference to a UI and starts a session, for +example by opening a channel to a tty, or by creating a dialog box. +.It a writer +This function takes a reference to a UI and a UI String, and writes the +string where appropriate, maybe to the tty, maybe added as a field label +in a dialog box. +Note that this gets fed all strings associated with a UI, one after the +other, so care must be taken which ones it actually uses. +.It a flusher +This function takes a reference to a UI, and flushes everything that has +been output so far. +For example, if the method builds up a dialog box, this can be used to +actually display it and accepting input ended with a pressed button. +.It a reader +This function takes a reference to a UI and a UI string and reads off +the given prompt, maybe from the tty, maybe from a field in a dialog +box. +Note that this gets fed all strings associated with a UI, one after the +other, so care must be taken which ones it actually uses. +.It a closer +This function takes a reference to a UI, and closes the session, maybe +by closing the channel to the tty, maybe by destroying a dialog box. +.El +.Pp +All of these functions are expected to return 0 on error, 1 on success, +or -1 on out-off-band events, for example if some prompting has been +cancelled (by pressing Ctrl-C, for example). +Only the flusher or the reader are expected to return -1. +If returned by another of the functions, it's treated as if 0 was returned. +.Pp +Regarding the writer and the reader, don't assume the former should only +write and don't assume the latter should only read. +This depends on the needs of the method. +.Pp +For example, a typical tty reader wouldn't write the prompts in the +write, but would rather do so in the reader, because of the sequential +nature of prompting on a tty. +This is how the +.Xr UI_OpenSSL 3 +method does it. +.Pp +In contrast, a method that builds up a dialog box would add all prompt +text in the writer, have all input read in the flusher and store the +results in some temporary buffer, and finally have the reader just fetch +those results. +.Pp +The central function that uses these method functions is +.Xr UI_process 3 , +and it does it in five steps: +.Bl -enum +.It +Open the session using the opener function if that one is defined. +If an error occurs, jump to 5. +.It +For every UI String associated with the UI, call the writer function if +that one is defined. +If an error occurs, jump to 5. +.It +Flush everything using the flusher function if that one is defined. +If an error occurs, jump to 5. +.It +For every UI String associated with the UI, call the reader function if +that one is defined. +If an error occurs, jump to 5. +.It +Close the session using the closer function if that one is defined. +.El +.Pp +.Fn UI_create_method +creates a new UI method with a given +.Fa name . +.Pp +.Fn UI_destroy_method +destroys the given +.Fa ui_method . +.Pp +.Fn UI_method_set_opener , +.Fn UI_method_set_writer , +.Fn UI_method_set_flusher , +.Fn UI_method_set_reader +and +.Fn UI_method_set_closer +set one of the five main methods to the given function pointer. +.Pp +.Fn UI_method_set_prompt_constructor +sets the prompt constructor, see +.Xr UI_construct_prompt 3 . +.Sh RETURN VALUES +.Fn UI_create_method +returns a +.Vt UI_METHOD +pointer on success or +.Dv NULL +on error. +.Pp +.Fn UI_method_set_opener , +.Fn UI_method_set_writer , +.Fn UI_method_set_flusher , +.Fn UI_method_set_reader , +.Fn UI_method_set_closer , +and +.Fn UI_method_set_prompt_constructor +return 0 on success or -1 if the given method is +.Dv NULL . +.Pp +.Fn UI_method_get_opener , +.Fn UI_method_get_writer , +.Fn UI_method_get_flusher , +.Fn UI_method_get_reader , +.Fn UI_method_get_closer , +and +.Fn UI_method_get_prompt_constructor +return the requested function pointer if it is set in the method, +or otherwise +.Dv NULL . +.Sh SEE ALSO +.Xr UI_get_string_type 3 , +.Xr UI_new 3 +.Sh HISTORY +.Fn UI_create_method , +.Fn UI_destroy_method , +.Fn UI_method_set_opener , +.Fn UI_method_set_writer , +.Fn UI_method_set_flusher , +.Fn UI_method_set_reader , +.Fn UI_method_set_closer , +.Fn UI_method_get_opener , +.Fn UI_method_get_writer , +.Fn UI_method_get_flusher , +.Fn UI_method_get_reader , +and +.Fn UI_method_get_closer +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn UI_method_set_prompt_constructor +and +.Fn UI_method_get_prompt_constructor +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/UI_get_string_type.3 b/Libraries/libressl/man/UI_get_string_type.3 new file mode 100644 index 000000000..bc0449a90 --- /dev/null +++ b/Libraries/libressl/man/UI_get_string_type.3 @@ -0,0 +1,281 @@ +.\" $OpenBSD: UI_get_string_type.3,v 1.4 2018/03/22 21:08:22 schwarze Exp $ +.\" OpenSSL UI_STRING.pod e9c9971b Jul 1 18:28:50 2017 +0200 +.\" +.\" This file was written by Richard Levitte +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt UI_GET_STRING_TYPE 3 +.Os +.Sh NAME +.Nm UI_get_string_type , +.Nm UI_get_input_flags , +.Nm UI_get0_output_string , +.Nm UI_get0_action_string , +.Nm UI_get0_result_string , +.Nm UI_get0_test_string , +.Nm UI_get_result_minsize , +.Nm UI_get_result_maxsize , +.Nm UI_set_result +.Nd OpenSSL user interface string parsing +.Sh SYNOPSIS +.In openssl/ui.h +.Bd -literal +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; +.Ed +.Pp +.Ft enum UI_string_types +.Fo UI_get_string_type +.Fa "UI_STRING *uis" +.Fc +.Ft int +.Fo UI_get_input_flags +.Fa "UI_STRING *uis" +.Fc +.Ft const char * +.Fo UI_get0_output_string +.Fa "UI_STRING *uis" +.Fc +.Ft const char * +.Fo UI_get0_action_string +.Fa "UI_STRING *uis" +.Fc +.Ft const char * +.Fo UI_get0_result_string +.Fa "UI_STRING *uis" +.Fc +.Ft const char * +.Fo UI_get0_test_string +.Fa "UI_STRING *uis" +.Fc +.Ft int +.Fo UI_get_result_minsize +.Fa "UI_STRING *uis" +.Fc +.Ft int +.Fo UI_get_result_maxsize +.Fa "UI_STRING *uis" +.Fc +.Ft int +.Fo UI_set_result +.Fa "UI *ui" +.Fa "UI_STRING *uis" +.Fa "const char *result" +.Fc +.Sh DESCRIPTION +A +.Vt UI_STRING +gets created internally and added to a +.Vt UI +object whenever one of the functions +.Xr UI_add_input_string 3 , +.Xr UI_dup_input_string 3 , +.Xr UI_add_verify_string 3 , +.Xr UI_dup_verify_string 3 , +.Xr UI_add_input_boolean 3 , +.Xr UI_dup_input_boolean 3 , +.Xr UI_add_info_string 3 , +.Xr UI_dup_info_string 3 , +.Xr UI_add_error_string 3 +or +.Xr UI_dup_error_string 3 +is called. +For a +.Vt UI_METHOD +user, there's no need to know more. +For a +.Vt UI_METHOD +creator, it is of interest to fetch text from these +.Vt UI_STRING +objects as well as adding results to some of them. +.Pp +.Fn UI_get_string_type +is used to retrieve the type of the given +.Vt UI_STRING . +.Pp +.Fn UI_get_input_flags +is used to retrieve the flags associated with the given +.Vt UI_STRING . +.Pp +.Fn UI_get0_output_string +is used to retrieve the actual string to output (prompt, info, error, ...). +.Pp +.Fn UI_get0_action_string +is used to retrieve the action description associated with a +.Dv UIT_BOOLEAN +type +.Vt UI_STRING . +See +.Xr UI_add_input_boolean 3 . +.Pp +.Fn UI_get0_result_string +is used to retrieve the result of a prompt. +This is only useful for +.Dv UIT_PROMPT +and +.Dv UIT_VERIFY +type strings. +.Pp +.Fn UI_get0_test_string +is used to retrieve the string to compare the prompt result with. +This is only useful for +.Dv UIT_VERIFY +type strings. +.Pp +.Fn UI_get_result_minsize +and +.Fn UI_get_result_maxsize +are used to retrieve the minimum and maximum required size of the +result. +This is only useful for +.Dv UIT_PROMPT +and +.Dv UIT_VERIFY +type strings. +.Pp +.Fn UI_set_result +is used to set the result value of a prompt. +For +.Sy UIT_PROMPT +and +.Sy UIT_VERIFY +type UI strings, this sets the result retrievable with +.Fn UI_get0_result_string +by copying the contents of +.Fa result +if its length fits the minimum and maximum size requirements. +For +.Dv UIT_BOOLEAN +type UI strings, this sets the first character of the result retrievable +with +.Fn UI_get0_result_string +to the first of the +.Fa ok_chars +given with +.Xr UI_add_input_boolean 3 +or +.Xr UI_dup_input_boolean 3 +if the +.Fa result +matched any of them, or the first of the +.Fa cancel_chars +if the +.Fa result +matched any of them, otherwise it's set to the NUL char. +See +.Xr UI_add_input_boolean 3 +for more information on +.Fa ok_chars +and +.Fa cancel_chars . +.Sh RETURN VALUES +.Fn UI_get_string_type +returns the UI string type. +.Pp +.Fn UI_get_input_flags +returns the UI string flags. +.Pp +.Fn UI_get0_output_string +returns the UI string output string. +.Pp +.Fn UI_get0_action_string +returns the UI string action description string for +.Dv UIT_BOOLEAN +type UI strings, or +.Dv NULL +for any other type. +.Pp +.Fn UI_get0_result_string +returns the UI string result buffer for +.Dv UIT_PROMPT +and +.Dv UIT_VERIFY +type UI strings, or +.Dv NULL +for any other type. +.Pp +.Fn UI_get0_test_string +returns the UI string action description string for +.Dv UIT_VERIFY +type UI strings, or +.Dv NULL +for any other type. +.Pp +.Fn UI_get_result_minsize +returns the minimum allowed result size for the UI string for +.Dv UIT_PROMPT +and +.Dv UIT_VERIFY +type strings, or -1 for any other type. +.Pp +.Fn UI_get_result_maxsize +returns the minimum allowed result size for the UI string for +.Dv UIT_PROMPT +and +.Dv UIT_VERIFY +type strings, or -1 for any other type. +.Pp +.Fn UI_set_result +returns 0 on success or when the UI string is of any type other than +.Dv UIT_PROMPT , +.Dv UIT_VERIFY , +or +.Dv UIT_BOOLEAN , +or -1 on error. +.Sh SEE ALSO +.Xr UI_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/UI_new.3 b/Libraries/libressl/man/UI_new.3 new file mode 100644 index 000000000..d71135919 --- /dev/null +++ b/Libraries/libressl/man/UI_new.3 @@ -0,0 +1,530 @@ +.\" $OpenBSD: UI_new.3,v 1.11 2022/12/17 22:23:31 tb Exp $ +.\" full merge up to: OpenSSL 78b19e90 Jan 11 00:12:01 2017 +0100 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Richard Levitte . +.\" Copyright (c) 2001, 2016, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 17 2022 $ +.Dt UI_NEW 3 +.Os +.Sh NAME +.Nm UI_new , +.Nm UI_new_method , +.Nm UI_free , +.Nm UI_add_input_string , +.Nm UI_dup_input_string , +.Nm UI_add_verify_string , +.Nm UI_dup_verify_string , +.Nm UI_add_input_boolean , +.Nm UI_dup_input_boolean , +.Nm UI_add_info_string , +.Nm UI_dup_info_string , +.Nm UI_add_error_string , +.Nm UI_dup_error_string , +.Nm UI_construct_prompt , +.Nm UI_add_user_data , +.Nm UI_get0_user_data , +.Nm UI_get0_result , +.Nm UI_process , +.Nm UI_ctrl , +.Nm UI_set_default_method , +.Nm UI_get_default_method , +.Nm UI_get_method , +.Nm UI_set_method , +.Nm UI_OpenSSL , +.Nm UI_null +.Nd New User Interface +.Sh SYNOPSIS +.In openssl/ui.h +.Ft UI * +.Fn UI_new void +.Ft UI * +.Fo UI_new_method +.Fa "const UI_METHOD *method" +.Fc +.Ft void +.Fo UI_free +.Fa "UI *ui" +.Fc +.Ft int +.Fo UI_add_input_string +.Fa "UI *ui" +.Fa "const char *prompt" +.Fa "int flags" +.Fa "char *result_buf" +.Fa "int minsize" +.Fa "int maxsize" +.Fc +.Ft int +.Fo UI_dup_input_string +.Fa "UI *ui" +.Fa "const char *prompt" +.Fa "int flags" +.Fa "char *result_buf" +.Fa "int minsize" +.Fa "int maxsize" +.Fc +.Ft int +.Fo UI_add_verify_string +.Fa "UI *ui" +.Fa "const char *prompt" +.Fa "int flags" +.Fa "char *result_buf" +.Fa "int minsize" +.Fa "int maxsize" +.Fa "const char *test_buf" +.Fc +.Ft int +.Fo UI_dup_verify_string +.Fa "UI *ui" +.Fa "const char *prompt" +.Fa "int flags" +.Fa "char *result_buf" +.Fa "int minsize" +.Fa "int maxsize" +.Fa "const char *test_buf" +.Fc +.Ft int +.Fo UI_add_input_boolean +.Fa "UI *ui" +.Fa "const char *prompt" +.Fa "const char *action_desc" +.Fa "const char *ok_chars" +.Fa "const char *cancel_chars" +.Fa "int flags" +.Fa "char *result_buf" +.Fc +.Ft int +.Fo UI_dup_input_boolean +.Fa "UI *ui" +.Fa "const char *prompt" +.Fa "const char *action_desc" +.Fa "const char *ok_chars" +.Fa "const char *cancel_chars" +.Fa "int flags" +.Fa "char *result_buf" +.Fc +.Ft int +.Fo UI_add_info_string +.Fa "UI *ui" +.Fa "const char *text" +.Fc +.Ft int +.Fo UI_dup_info_string +.Fa "UI *ui" +.Fa "const char *text" +.Fc +.Ft int +.Fo UI_add_error_string +.Fa "UI *ui" +.Fa "const char *text" +.Fc +.Ft int +.Fo UI_dup_error_string +.Fa "UI *ui" +.Fa "const char *text" +.Fc +.Fd /* These are the possible flags. They can be OR'ed together. */ +.Fd #define UI_INPUT_FLAG_ECHO 0x01 +.Fd #define UI_INPUT_FLAG_DEFAULT_PWD 0x02 +.Ft char * +.Fo UI_construct_prompt +.Fa "UI *ui_method" +.Fa "const char *object_desc" +.Fa "const char *object_name" +.Fc +.Ft void * +.Fo UI_add_user_data +.Fa "UI *ui" +.Fa "void *user_data" +.Fc +.Ft void * +.Fo UI_get0_user_data +.Fa "UI *ui" +.Fc +.Ft const char * +.Fo UI_get0_result +.Fa "UI *ui" +.Fa "int i" +.Fc +.Ft int +.Fo UI_process +.Fa "UI *ui" +.Fc +.Ft int +.Fo UI_ctrl +.Fa "UI *ui" +.Fa "int cmd" +.Fa "long i" +.Fa "void *p" +.Fa "void (*f)()" +.Fc +.Fd #define UI_CTRL_PRINT_ERRORS 1 +.Fd #define UI_CTRL_IS_REDOABLE 2 +.Ft void +.Fo UI_set_default_method +.Fa "const UI_METHOD *meth" +.Fc +.Ft const UI_METHOD * +.Fo UI_get_default_method +.Fa void +.Fc +.Ft const UI_METHOD * +.Fo UI_get_method +.Fa "UI *ui" +.Fc +.Ft const UI_METHOD * +.Fo UI_set_method +.Fa "UI *ui" +.Fa "const UI_METHOD *meth" +.Fc +.Ft UI_METHOD * +.Fo UI_OpenSSL +.Fa void +.Fc +.Ft const UI_METHOD * +.Fo UI_null +.Fa void +.Fc +.Sh DESCRIPTION +UI stands for User Interface, and is a general purpose set of routines +to prompt the user for text-based information. +Through user-written methods (see +.Xr UI_create_method 3 ) , +prompting can be done in any way imaginable, be it plain text prompting, +through dialog boxes or from a cell phone. +.Pp +All the functions work through a context of the type +.Vt UI . +This context contains all the information needed to prompt correctly +as well as a reference to a +.Vt UI_METHOD , +which is an ordered vector of functions that carry out the actual +prompting. +.Pp +The first thing to do is to create a +.Vt UI +with +.Fn UI_new +or +.Fn UI_new_method , +then add information to it with the +.Fn UI_add_* +or +.Fn UI_dup_* +functions. +Also, user-defined random data can be passed down to the underlying +method through calls to +.Fn UI_add_user_data . +The default UI method doesn't care about these data, but other methods +might. +Finally, use +.Fn UI_process +to actually perform the prompting and +.Fn UI_get0_result +to find the result to the prompt. +.Pp +A +.Vt UI +can contain more than one prompt, which are performed in the given +sequence. +Each prompt gets an index number which is returned by the +.Fn UI_add_* +and +.Fn UI_dup_* +functions, and has to be used to get the corresponding result with +.Fn UI_get0_result . +.Pp +The functions are as follows: +.Pp +.Fn UI_new +creates a new +.Vt UI +using the default UI method. +When done with this UI, it should be freed using +.Fn UI_free . +.Pp +.Fn UI_new_method +creates a new +.Vt UI +using the given UI method. +When done with this UI, it should be freed using +.Fn UI_free . +.Pp +.Fn UI_OpenSSL +returns the built-in UI method (note: not necessarily the default one, +since the default can be changed. +See further on). +This method is the most machine/OS dependent part of OpenSSL and +normally generates the most problems when porting. +.Pp +.Fn UI_null +returns a UI method that does nothing. +Its use is to avoid getting internal defaults for passed +.Vt UI_METHOD +pointers. +.Pp +.Fn UI_free +removes +.Fa ui +from memory, along with all other pieces of memory that are connected +to it, like duplicated input strings, results and others. +If +.Fa ui +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn UI_add_input_string +and +.Fn UI_add_verify_string +add a prompt to +.Fa ui , +as well as flags and a result buffer and the desired minimum and +maximum sizes of the result, not counting the final NUL character. +The given information is used to prompt for information, for example +a password, and to verify a password (i.e. having the user enter +it twice and check that the same string was entered twice). +.Fn UI_add_verify_string +takes an extra argument that should be a pointer to the result buffer +of the input string that it's supposed to verify, or verification will +fail. +.Pp +.Fn UI_add_input_boolean +adds a prompt to +.Fa ui +that's supposed to be answered in a boolean way, with a single +character for yes and a different character for no. +A set of characters that can be used to cancel the prompt is given as +well. +The prompt itself is really divided in two, one part being the +descriptive text (given through the +.Fa prompt +argument) and one describing the possible answers (given through the +.Fa action_desc +argument). +.Pp +.Fn UI_add_info_string +and +.Fn UI_add_error_string +add strings that are shown at the same time as the prompt for extra +information or to show an error string. +The difference between the two is only conceptual. +With the builtin method, there's no technical difference between them. +Other methods may make a difference between them, however. +.Pp +The flags currently supported are +.Dv UI_INPUT_FLAG_ECHO , +which is relevant for +.Fn UI_add_input_string +and will have the users response be echoed (when prompting for a +password, this flag should obviously not be used), and +.Dv UI_INPUT_FLAG_DEFAULT_PWD , +which means that a default password of some sort will be used +(completely depending on the application and the UI method). +.Pp +.Fn UI_dup_input_string , +.Fn UI_dup_verify_string , +.Fn UI_dup_input_boolean , +.Fn UI_dup_info_string , +and +.Fn UI_dup_error_string +are basically the same as their +.Fn UI_add_* +counterparts, except that they make their own copies of all strings. +.Pp +.Fn UI_construct_prompt +is a helper function that can be used to create a prompt from two pieces +of information: a description and a name. +The default constructor (if there is none provided by the method used) +creates a string "Enter +.Em description +for +.Em name Ns :". +With the description "pass phrase" and the file name "foo.key", that +becomes "Enter pass phrase for foo.key:". Other methods may create +whatever string and may include encodings that will be processed by the +other method functions. +.Pp +.Fn UI_add_user_data +adds a user data pointer for the method to use at any time. +The builtin UI method doesn't care about this info. +Note that several calls to this function doesn't add data - +the previous blob is replaced with the one given as argument. +.Pp +.Fn UI_get0_user_data +retrieves the data that has last been given to the +.Fa ui +with +.Fn UI_add_user_data . +.Pp +.Fn UI_get0_result +returns a pointer to the result buffer associated with the information +indexed by +.Fa i . +.Pp +.Fn UI_process +goes through the information given so far, does all the printing and +prompting and returns the final status, which is -2 on out-of-band +events (Interrupt, Cancel, ...), -1 on error, or 0 on success. +.Pp +.Fn UI_ctrl +adds extra control for the application author. +For now, it understands two commands: +.Dv UI_CTRL_PRINT_ERRORS , +which makes +.Fn UI_process +print the OpenSSL error stack as part of processing the +.Fa ui , +and +.Dv UI_CTRL_IS_REDOABLE , +which returns a flag saying if the used +.Fa ui +can be used again or not. +.Pp +.Fn UI_set_default_method +changes the default UI method to the one given. +This function is not thread-safe and should not be called at the +same time as other OpenSSL functions. +.Pp +.Fn UI_get_default_method +returns a pointer to the current default UI method. +.Pp +.Fn UI_get_method +returns the UI method associated with a given +.Fa ui . +.Pp +.Fn UI_set_method +changes the UI method associated with a given +.Fa ui . +.Sh RETURN VALUES +.Fn UI_new +and +.Fn UI_new_method +return a valid +.Vt UI +structure or +.Dv NULL +if an error occurred. +.Pp +.Fn UI_add_input_string , +.Fn UI_dup_input_string , +.Fn UI_add_verify_string , +.Fn UI_dup_verify_string , +.Fn UI_add_input_boolean , +.Fn UI_dup_input_boolean , +.Fn UI_add_info_string , +.Fn UI_dup_info_string , +.Fn UI_add_error_string , +and +.Fn UI_dup_error_string +return a positive number on success or a number +less than or equal to zero otherwise. +.Pp +.Fn UI_construct_prompt +and +.Fn UI_get0_result +return a string or +.Dv NULL +if an error occurred. +.Pp +.Fn UI_add_user_data +and +.Fn UI_get0_user_data +return a pointer to the user data that was contained in +.Fa ui +before the call. +In particular, +.Dv NULL +is a valid return value. +.Pp +.Fn UI_process +returns 0 on success or a negative value on error. +.Pp +.Fn UI_ctrl +returns a mask on success or \-1 on error. +.Pp +.Fn UI_get_default_method , +.Fn UI_OpenSSL +and +.Fn UI_null +always return a pointer to a valid +.Vt UI_METHOD +structure. +.Pp +.Fn UI_get_method +and +.Fn UI_set_method +return a pointer to the +.Vt UI_METHOD +structure that is installed in +.Fa ui +after the call. +The OpenSSL documentation says that they can fail and return +.Dv NULL , +but currently, this can only happen when and after +.Fn UI_set_method +is called with an explicit +.Dv NULL +argument. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr UI_create_method 3 , +.Xr UI_get_string_type 3 , +.Xr UI_UTIL_read_pw 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . +.Pp +.Fn UI_null +first appeared in OpenSSL 1.1.1 and has been available since +.Ox 7.3 . +.Sh AUTHORS +.An Richard Levitte Aq Mt richard@levitte.org +for the OpenSSL project. diff --git a/Libraries/libressl/man/X25519.3 b/Libraries/libressl/man/X25519.3 new file mode 100644 index 000000000..a327f8c7b --- /dev/null +++ b/Libraries/libressl/man/X25519.3 @@ -0,0 +1,211 @@ +.\" $OpenBSD: X25519.3,v 1.7 2022/12/15 17:20:48 schwarze Exp $ +.\" contains some text from: BoringSSL curve25519.h, curve25519.c +.\" content also checked up to: OpenSSL f929439f Mar 15 12:19:16 2018 +0000 +.\" +.\" Copyright (c) 2015 Google Inc. +.\" Copyright (c) 2018, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and/or distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" According to the BoringSSL git history, those parts of the text in +.\" the present manual page that are Copyrighted by Google were probably +.\" written by Adam Langley in 2015. +.\" I fail to see any such text in the public domain files written +.\" by Daniel J. Bernstein and others that are included in SUPERCOP +.\" and that Adam Langley's BoringSSL implementation is based on. +.\" +.Dd $Mdocdate: December 15 2022 $ +.Dt X25519 3 +.Os +.Sh NAME +.Nm X25519 , +.Nm X25519_keypair , +.Nm ED25519_keypair , +.Nm ED25519_sign , +.Nm ED25519_verify +.Nd Elliptic Curve Diffie-Hellman and signature primitives based on Curve25519 +.Sh SYNOPSIS +.In openssl/curve25519.h +.Ft int +.Fo X25519 +.Fa "uint8_t out_shared_key[X25519_KEY_LENGTH]" +.Fa "const uint8_t private_key[X25519_KEY_LENGTH]" +.Fa "const uint8_t peer_public_value[X25519_KEY_LENGTH]" +.Fc +.Ft void +.Fo X25519_keypair +.Fa "uint8_t out_public_value[X25519_KEY_LENGTH]" +.Fa "uint8_t out_private_key[X25519_KEY_LENGTH]" +.Fc +.Ft void +.Fo ED25519_keypair +.Fa "uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH]" +.Fa "uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]" +.Fc +.Ft int +.Fo ED25519_sign +.Fa "uint8_t *out_sig" +.Fa "const uint8_t *message" +.Fa "size_t message_len" +.Fa "const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]" +.Fa "const uint8_t private_key_seed[ED25519_PRIVATE_KEY_LENGTH]" +.Fc +.Ft int +.Fo ED25519_verify +.Fa "const uint8_t *message" +.Fa "size_t message_len" +.Fa "const uint8_t signature[ED25519_SIGNATURE_LENGTH]" +.Fa "const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]" +.Fc +.Sh DESCRIPTION +Curve25519 is an elliptic curve over a prime field +specified in RFC 7748 section 4.1. +The prime field is defined by the prime number 2^255 - 19. +.Pp +X25519 +is the Diffie-Hellman primitive built from Curve25519 as described +in RFC 7748 section 5. +Section 6.1 describes the intended use in an Elliptic Curve Diffie-Hellman +(ECDH) protocol. +.Pp +.Fn X25519 +writes a shared key to +.Fa out_shared_key +that is calculated from the given +.Fa private_key +and the +.Fa peer_public_value +by scalar multiplication. +Do not use the shared key directly, rather use a key derivation +function and also include the two public values as inputs. +.Pp +.Fn X25519_keypair +sets +.Fa out_public_value +and +.Fa out_private_key +to a freshly generated public/private key pair. +First, the +.Fa out_private_key +is generated with +.Xr arc4random_buf 3 . +Then, the opposite of the masking described in RFC 7748 section 5 +is applied to it to make sure that the generated private key is never +correctly masked. +The purpose is to cause incorrect implementations on the peer side +to consistently fail. +Correct implementations will decode the key correctly even when it is +not correctly masked. +Finally, the +.Fa out_public_value +is calculated from the +.Fa out_private_key +by multiplying it with the Montgomery base point +.Vt uint8_t u[32] No = Brq 9 . +.Pp +The size of a public and private key is +.Dv X25519_KEY_LENGTH No = 32 +bytes each. +.Pp +Ed25519 is a signature scheme using a twisted Edwards curve +that is birationally equivalent to Curve25519. +.Pp +.Fn ED25519_keypair +sets +.Fa out_public_key +and +.Fa out_private_key +to a freshly generated public/private key pair. +First, the +.Fa out_private_key +is generated with +.Xr arc4random_buf 3 . +Then, the +.Fa out_public_key +is calculated from the private key. +.Pp +.Fn ED25519_sign +signs the +.Fa message +of +.Fa message_len +bytes using the +.Fa public_key +and the +.Fa private_key +and writes the signature to +.Fa out_sig . +.Pp +.Fn ED25519_verify +checks that signing the +.Fa message +of +.Fa message_len +bytes using the +.Fa public_key +would indeed result in the given +.Fa signature . +.Pp +The sizes of a public and private keys are +.Dv ED25519_PUBLIC_KEY_LENGTH +and +.Dv ED25519_PRIVATE_KEY_LENGTH , +which are both 32 bytes, and the size of a signature is +.Dv ED25519_SIGNATURE_LENGTH No = 64 +bytes. +.Sh RETURN VALUES +.Fn X25519 +and +.Fn ED25519_sign +return 1 on success or 0 on error. +.Fn X25519 +can fail if the input is a point of small order. +.Fn ED25519_sign +always succeeds in LibreSSL, but the API reserves the return value 0 +for memory allocation failure. +.Pp +.Fn ED25519_verify +returns 1 if the +.Fa signature +is valid or 0 otherwise. +.Sh SEE ALSO +.Xr ECDH_compute_key 3 , +.Xr EVP_DigestSign 3 , +.Xr EVP_DigestVerify 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_keygen 3 +.Rs +.%A Daniel J. Bernstein +.%R A state-of-the-art Diffie-Hellman function:\ + How do I use Curve25519 in my own software? +.%U https://cr.yp.to/ecdh.html +.Re +.Rs +.%A Daniel J. Bernstein +.%A Niels Duif +.%A Tanja Lange +.%A Peter Schwabe +.%A Bo-Yin Yang +.%T High-Speed High-Security Signatures +.%B Cryptographic Hardware and Embedded Systems \(em CHES 2011 +.%I Springer +.%J Lecture Notes in Computer Science +.%V vol 6917 +.%U https://doi.org/10.1007/978-3-642-23951-9_9 +.%C Nara, Japan +.%D September 29, 2011 +.Re +.Sh STANDARDS +RFC 7748: Elliptic Curves for Security +.Pp +RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA) diff --git a/Libraries/libressl/man/X509V3_EXT_print.3 b/Libraries/libressl/man/X509V3_EXT_print.3 new file mode 100644 index 000000000..0c695842b --- /dev/null +++ b/Libraries/libressl/man/X509V3_EXT_print.3 @@ -0,0 +1,156 @@ +.\" $OpenBSD: X509V3_EXT_print.3,v 1.2 2021/07/12 14:54:00 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 12 2021 $ +.Dt X509V3_EXT_PRINT 3 +.Os +.Sh NAME +.Nm X509V3_EXT_print +.Nd pretty-print an X.509 extension +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509V3_EXT_print +.Fa "BIO *bio" +.Fa "X509_EXTENSION *ext" +.Fa "unsigned long flags" +.Fa "int indent" +.Fc +.Sh DESCRIPTION +.Fn X509V3_EXT_print +decodes +.Fa ext +and prints the data contained in it to +.Fa bio +in a human-readable format with a left margin of +.Fa indent +space characters. +The details of both the decoding and the printing depend on the type of +.Fa ext . +.Pp +For most extension types, the decoding is done in the same way +as it would be done by the appropriate public API function, for example: +.Pp +.Bl -tag -width NID_authority_key_identifier -compact +.It Sy extension type +.Sy decoding function +.It Dv NID_subject_key_identifier +.Xr d2i_ASN1_OCTET_STRING 3 +.It Dv NID_key_usage +.Xr d2i_ASN1_BIT_STRING 3 +.It Dv NID_crl_number +.Xr d2i_ASN1_INTEGER 3 +.It Dv NID_crl_reason +.Xr d2i_ASN1_ENUMERATED 3 +.It Dv NID_invalidity_date +.Xr d2i_ASN1_GENERALIZEDTIME 3 +.It Dv NID_subject_alt_name +.Xr d2i_GENERAL_NAMES 3 +.It Dv NID_hold_instruction_code +.Xr d2i_ASN1_OBJECT 3 +.It Dv NID_id_pkix_OCSP_noCheck +.Xr d2i_ASN1_NULL 3 +.It Dv NID_authority_key_identifier +.Xr d2i_AUTHORITY_KEYID 3 +.It Dv NID_certificate_policies +.Xr d2i_CERTIFICATEPOLICIES 3 +.It Dv NID_id_pkix_OCSP_CrlID +.Xr d2i_OCSP_CRLID 3 +.It Dv NID_id_pkix_OCSP_Nonce +non-public function built into the library +.El +.Pp +For some types, the printing is performed +by a dedicated non-public function built into the library. +For some other types, the printing function is a public API function, +but none of these printing functions are documented yet. +.Pp +If +.Fa ext +is of an unknown extension type or if decoding fails +while using the decoding function for the relevant type, +the action taken depends on the +.Fa flags +argument: +.Bl -bullet +.It +If the bit +.Dv X509V3_EXT_PARSE_UNKNOWN +is set, +.Xr ASN1_parse_dump 3 +is called on the BER-encoded data of the extension, passing \-1 for the +.Fa dump +argument. +Thus, some information about the encoding of the extension gets printed +and some about its decoded content, falling back to +.Xr BIO_dump_indent 3 +for the decoded content unless a dedicated printing method is known +for the respective data type(s). +Note that even if an extension type is unknown, the data type used +by the unknown extension, or, if that data type is constructed, of +the values contained in it, may still be known, which may allow +printing the content of even an unknown extension in a structured +or partially structured form. +.It +If the bit +.Dv X509V3_EXT_DUMP_UNKNOWN +is set, +.Xr BIO_dump_indent 3 +is called on the BER-encoded data of the extension without decoding +it first, which is usually less readable than the above but poses +a smaller risk of omitting or misrepresenting parts of the information. +.It +If the bit +.Dv X509V3_EXT_ERROR_UNKNOWN +is set, only the fixed string +.Qq "" +is printed for an unknown type or only the fixed string +.Qq "" +if the parsing functions fails, +but printing is considered as successful anyway. +.It +If more than one of these three bits is set, or if a bit in +.Dv X509V3_EXT_UNKNOWN_MASK +is set that is not listed above, nothing is printed, but printing +is considered as successful anyway. +.It +If none of the bits in +.Dv X509V3_EXT_UNKNOWN_MASK +are set, nothing is printed and printing is considered as failed. +.El +.Sh RETURN VALUES +.Fn X509V3_EXT_print +returns 0 if failure was both detected and considered relevant. +Otherwise, 1 is returned, and in general the user cannot tell whether +failure simply went undetected, whether the function detected failure +but regarded it as irrelevant, or whether printing did indeed +succeed. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get0_extensions 3 , +.Xr X509_get_ext 3 , +.Xr X509V3_extensions_print 3 +.Sh HISTORY +.Fn X509V3_EXT_print +first appeared in OpenSSL 0.9.2 and has been available since +.Ox 2.6 . +.Sh BUGS +.Fn X509V3_EXT_print +lacks error handling throughout. +When a write operation fails, it will usually ignore the fact that +information was omitted from the output and report success to the +caller anyway. diff --git a/Libraries/libressl/man/X509V3_extensions_print.3 b/Libraries/libressl/man/X509V3_extensions_print.3 new file mode 100644 index 000000000..8c43fe9b0 --- /dev/null +++ b/Libraries/libressl/man/X509V3_extensions_print.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: X509V3_extensions_print.3,v 1.2 2021/11/26 13:48:21 jsg Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 26 2021 $ +.Dt X509V3_EXTENSIONS_PRINT 3 +.Os +.Sh NAME +.Nm X509V3_extensions_print +.Nd pretty-print an array of X.509 extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509V3_extensions_print +.Fa "BIO *bio" +.Fa "char *title" +.Fa "const STACK_OF(X509_EXTENSION) *sk" +.Fa "unsigned long flags" +.Fa "int indent" +.Fc +.Sh DESCRIPTION +For each member of the variable sized array +.Fa sk , +.Fn X509V3_extensions_print +prints the following information to +.Fa bio +in the following order: +.Bl -bullet +.It +The extension type as printed by +.Xr i2a_ASN1_OBJECT 3 . +.It +If the extension is critical, the fixed string +.Qq "critical" . +.It +A human-readable representation of the data contained in the extension +as printed by +.Xr X509V3_EXT_print 3 , +passing through the +.Fa flags . +If that function indicates failure, +the BER-encoded data of the extension is dumped with +.Xr ASN1_STRING_print 3 +without decoding it first. +In both cases, an +.Fa indent +incremented by 4 space characters is used. +.El +.Pp +If +.Fa sk +is a +.Dv NULL +pointer or empty, +.Fn X509V3_extensions_print +prints nothing and indicates success. +.Pp +Unless +.Fa title +is +.Dv NULL , +it is printed on its own output line before the rest of the output, and +.Fa indent +is increased by 4 space characters. +This additional global indentation is cumulative +to the one applied to individual extensions mentioned above. +.Sh RETURN VALUES +.Fn X509V3_extensions_print +is intended to return 1 on success or 0 if an error occurs. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr STACK_OF 3 , +.Xr X509_EXTENSION_get_critical 3 , +.Xr X509_get0_extensions 3 , +.Xr X509_get_ext 3 , +.Xr X509V3_EXT_print 3 +.Sh HISTORY +.Fn X509V3_extensions_print +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh BUGS +Many parsing and printing errors are silently ignored, +and the function may return indicating success even though +.Fa sk +contains invalid data. +Even if all the data is valid, success may be indicated even when the +information printed is incomplete for various reasons, for example +due to memory allocation failures or I/O errors. diff --git a/Libraries/libressl/man/X509V3_get_d2i.3 b/Libraries/libressl/man/X509V3_get_d2i.3 new file mode 100644 index 000000000..ed9e150c9 --- /dev/null +++ b/Libraries/libressl/man/X509V3_get_d2i.3 @@ -0,0 +1,475 @@ +.\" $OpenBSD: X509V3_get_d2i.3,v 1.21 2023/09/25 07:47:52 tb Exp $ +.\" full merge up to: OpenSSL ff7fbfd5 Nov 2 11:52:01 2015 +0000 +.\" selective merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2014, 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 25 2023 $ +.Dt X509V3_GET_D2I 3 +.Os +.Sh NAME +.Nm X509V3_get_d2i , +.Nm X509V3_add1_i2d , +.Nm X509V3_EXT_d2i , +.Nm X509V3_EXT_i2d , +.Nm X509_get_ext_d2i , +.Nm X509_add1_ext_i2d , +.Nm X509_CRL_get_ext_d2i , +.Nm X509_CRL_add1_ext_i2d , +.Nm X509_REVOKED_get_ext_d2i , +.Nm X509_REVOKED_add1_ext_i2d , +.Nm X509_get0_extensions , +.Nm X509_CRL_get0_extensions , +.Nm X509_REVOKED_get0_extensions , +.Nm X509_get0_uids +.Nd X509 extension decode and encode functions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft void * +.Fo X509V3_get_d2i +.Fa "const STACK_OF(X509_EXTENSION) *x" +.Fa "int nid" +.Fa "int *crit" +.Fa "int *idx" +.Fc +.Ft int +.Fo X509V3_add1_i2d +.Fa "STACK_OF(X509_EXTENSION) **x" +.Fa "int nid" +.Fa "void *value" +.Fa "int crit" +.Fa "unsigned long flags" +.Fc +.Ft void * +.Fo X509V3_EXT_d2i +.Fa "X509_EXTENSION *ext" +.Fc +.Ft X509_EXTENSION * +.Fo X509V3_EXT_i2d +.Fa "int ext_nid" +.Fa "int crit" +.Fa "void *ext" +.Fc +.Ft void * +.Fo X509_get_ext_d2i +.Fa "const X509 *x" +.Fa "int nid" +.Fa "int *crit" +.Fa "int *idx" +.Fc +.Ft int +.Fo X509_add1_ext_i2d +.Fa "X509 *x" +.Fa "int nid" +.Fa "void *value" +.Fa "int crit" +.Fa "unsigned long flags" +.Fc +.Ft void * +.Fo X509_CRL_get_ext_d2i +.Fa "const X509_CRL *crl" +.Fa "int nid" +.Fa "int *crit" +.Fa "int *idx" +.Fc +.Ft int +.Fo X509_CRL_add1_ext_i2d +.Fa "X509_CRL *crl" +.Fa "int nid" +.Fa "void *value" +.Fa "int crit" +.Fa "unsigned long flags" +.Fc +.Ft void * +.Fo X509_REVOKED_get_ext_d2i +.Fa "const X509_REVOKED *r" +.Fa "int nid" +.Fa "int *crit" +.Fa "int *idx" +.Fc +.Ft int +.Fo X509_REVOKED_add1_ext_i2d +.Fa "X509_REVOKED *r" +.Fa "int nid" +.Fa "void *value" +.Fa "int crit" +.Fa "unsigned long flags" +.Fc +.Ft const STACK_OF(X509_EXTENSION) * +.Fo X509_get0_extensions +.Fa "const X509 *x" +.Fc +.Ft const STACK_OF(X509_EXTENSION) * +.Fo X509_CRL_get0_extensions +.Fa "const X509_CRL *crl" +.Fc +.Ft const STACK_OF(X509_EXTENSION) * +.Fo X509_REVOKED_get0_extensions +.Fa "const X509_REVOKED *r" +.Fc +.Ft void +.Fo X509_get0_uids +.Fa "const X509 *x" +.Fa "const ASN1_BIT_STRING **piuid" +.Fa "const ASN1_BIT_STRING **psuid" +.Fc +.Sh DESCRIPTION +.Fn X509V3_get_d2i +looks for an extension with OID +.Fa nid +in the extensions +.Fa x +and, if found, decodes it. +If +.Fa idx +is +.Dv NULL , +then only one occurrence of an extension is permissible. +Otherwise the first extension after index +.Pf * Fa idx +is returned and +.Pf * Fa idx +is updated to the location of the extension. +If +.Fa crit +is not +.Dv NULL , +then +.Pf * Fa crit +is set to a status value: -2 if the extension occurs multiple times +(this is only returned if +.Fa idx +is +.Dv NULL ) , +-1 if the extension could not be found, 0 if the extension is found +and is not critical, and 1 if it is critical. +A pointer to an extension specific structure or +.Dv NULL +is returned. +.Pp +.Fn X509V3_add1_i2d +adds extension +.Fa value +to STACK +.Pf * Fa x +(allocating a new STACK if necessary) using OID +.Fa nid +and criticality +.Fa crit +according to +.Fa flags . +.Pp +.Fn X509V3_EXT_d2i +attempts to decode the ASN.1 data contained in extension +.Fa ext +and returns a pointer to an extension specific structure or +.Dv NULL +if the extension could not be decoded (invalid syntax or not supported). +.Pp +.Fn X509V3_EXT_i2d +encodes the extension specific structure +.Fa ext +with OID +.Fa ext_nid +and criticality +.Fa crit . +.Pp +.Fn X509_get_ext_d2i +and +.Fn X509_add1_ext_i2d +operate on the extensions of certificate +.Fa x , +and are otherwise identical to +.Fn X509V3_get_d2i +and +.Fn X509V3_add1_i2d . +.Pp +.Fn X509_CRL_get_ext_d2i +and +.Fn X509_CRL_add1_ext_i2d +operate on the extensions of CRL +.Fa crl , +and are otherwise identical to +.Fn X509V3_get_d2i +and +.Fn X509V3_add1_i2d . +.Pp +.Fn X509_REVOKED_get_ext_d2i +and +.Fn X509_REVOKED_add1_ext_i2d +operate on the extensions of the +.Vt X509_REVOKED +structure +.Fa r +(i.e. for CRL entry extensions), and are otherwise identical to +.Fn X509V3_get_d2i +and +.Fn X509V3_add1_i2d . +.Pp +.Fn X509_get0_extensions , +.Fn X509_CRL_get0_extensions , +and +.Fn X509_REVOKED_get0_extensions +return a stack of all the extensions of a certificate, a CRL, +or a CRL entry, respectively. +.Pp +In almost all cases an extension can occur at most once and multiple +occurrences is an error. +Therefore the +.Fa idx +parameter is usually +.Dv NULL . +.Pp +The +.Fa flags +parameter may be one of the following values. +.Pp +.Dv X509V3_ADD_DEFAULT +appends a new extension only if the extension does not already exist. +An error is returned if the extension does already exist. +.Pp +.Dv X509V3_ADD_APPEND +appends a new extension, ignoring whether the extension already exists. +.Pp +.Dv X509V3_ADD_REPLACE +replaces an extension if it exists otherwise appends a new extension. +.Pp +.Dv X509V3_ADD_REPLACE_EXISTING +replaces an existing extension if it exists otherwise returns an error. +.Pp +.Dv X509V3_ADD_KEEP_EXISTING +appends a new extension only if the extension does not already exist. +An error +.Sy is not +returned if the extension does already exist. +.Pp +.Dv X509V3_ADD_DELETE +deletes extension +.Fa nid . +No new extension is added. +.Pp +If +.Dv X509V3_ADD_SILENT +is OR'd with +.Fa flags , +any error returned will not be added to the error queue. +.Pp +The function +.Fn X509V3_get_d2i +will return +.Dv NULL +if the extension is not found, occurs multiple times or cannot be +decoded. +It is possible to determine the precise reason by checking the value of +.Pf * Fa crit . +.Pp +.Fn X509_get0_uids +sets +.Fa *piuid +and +.Fa *psuid +to the issuer and subject unique identifiers of certificate +.Fa x +or NULL if the fields are not present. +These fields are rarely used. +.Sh SUPPORTED EXTENSIONS +The following sections contain a list of all supported extensions +including their name and NID. +.Ss PKIX Certificate Extensions +The following certificate extensions are defined in PKIX standards such +as RFC 5280. +.Bl -column 30n 30n +.It Basic Constraints Ta Dv NID_basic_constraints +.It Key Usage Ta Dv NID_key_usage +.It Extended Key Usage Ta Dv NID_ext_key_usage +.It Subject Key Identifier Ta Dv NID_subject_key_identifier +.It Authority Key Identifier Ta Dv NID_authority_key_identifier +.It Private Key Usage Period Ta Dv NID_private_key_usage_period +.It Subject Alternative Name Ta Dv NID_subject_alt_name +.It Issuer Alternative Name Ta Dv NID_issuer_alt_name +.It Authority Information Access Ta Dv NID_info_access +.It Subject Information Access Ta Dv NID_sinfo_access +.It Name Constraints Ta Dv NID_name_constraints +.It Certificate Policies Ta Dv NID_certificate_policies +.It Policy Mappings Ta Dv NID_policy_mappings +.It Policy Constraints Ta Dv NID_policy_constraints +.It Inhibit Any Policy Ta Dv NID_inhibit_any_policy +.It IP Address Delegation Ta Dv NID_sbgp_ipAddrBlock +.It Autonomous System Identifier Delegation\ + Ta Dv NID_sbgp_autonomousSysNum +.El +.Ss Netscape Certificate Extensions +The following are (largely obsolete) Netscape certificate extensions. +.Bl -column 30n 30n +.It Netscape Cert Type Ta Dv NID_netscape_cert_type +.It Netscape Base Url Ta Dv NID_netscape_base_url +.It Netscape Revocation Url Ta Dv NID_netscape_revocation_url +.It Netscape CA Revocation Url Ta Dv NID_netscape_ca_revocation_url +.It Netscape Renewal Url Ta Dv NID_netscape_renewal_url +.It Netscape CA Policy Url Ta Dv NID_netscape_ca_policy_url +.It Netscape SSL Server Name Ta Dv NID_netscape_ssl_server_name +.It Netscape Comment Ta Dv NID_netscape_comment +.El +.Ss Miscellaneous Certificate Extensions +.Bl -column 30n 30n +.It Strong Extranet ID Ta Dv NID_sxnet +.It Proxy Certificate Information Ta Dv NID_proxyCertInfo +.El +.Ss PKIX CRL Extensions +The following are CRL extensions from PKIX standards such as RFC 5280. +.Bl -column 30n 30n +.It CRL Number Ta Dv NID_crl_number +.It CRL Distribution Points Ta Dv NID_crl_distribution_points +.It Delta CRL Indicator Ta Dv NID_delta_crl +.It Freshest CRL Ta Dv NID_freshest_crl +.It Invalidity Date Ta Dv NID_invalidity_date +.It Issuing Distribution Point Ta Dv NID_issuing_distribution_point +.El +.Pp +The following are CRL entry extensions from PKIX standards such as +RFC 5280. +.Bl -column 30n 30n +.It CRL Reason Code Ta Dv NID_crl_reason +.It Certificate Issuer Ta Dv NID_certificate_issuer +.El +.Ss OCSP Extensions +.Bl -column 30n 30n +.It OCSP Nonce Ta Dv NID_id_pkix_OCSP_Nonce +.It OCSP CRL ID Ta Dv NID_id_pkix_OCSP_CrlID +.It Acceptable OCSP Responses Ta Dv NID_id_pkix_OCSP_acceptableResponses +.It OCSP No Check Ta Dv NID_id_pkix_OCSP_noCheck +.It OCSP Archive Cutoff Ta Dv NID_id_pkix_OCSP_archiveCutoff +.It OCSP Service Locator Ta Dv NID_id_pkix_OCSP_serviceLocator +.It Hold Instruction Code Ta Dv NID_hold_instruction_code +.El +.Sh RETURN VALUES +.Fn X509V3_get_d2i , +.Fn X509V3_EXT_d2i , +.Fn X509_get_ext_d2i , +.Fn X509_CRL_get_ext_d2i , +and +.Fn X509_REVOKED_get_ext_d2i +return a pointer to an extension specific structure or +.Dv NULL +if an error occurs. +.Pp +.Fn X509V3_add1_i2d , +.Fn X509_add1_ext_i2d , +.Fn X509_CRL_add1_ext_i2d , +and +.Fn X509_REVOKED_add1_ext_i2d +return 1 if the operation is successful, 0 if it fails due to a +non-fatal error (extension not found, already exists, cannot be encoded), +or -1 due to a fatal error such as a memory allocation failure. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Pp +The +.Fn X509V3_EXT_i2d +function returns a pointer to an +.Vt X509_EXTENSION +structure if successful; otherwise +.Dv NULL +is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_get0_extensions , +.Fn X509_CRL_get0_extensions , +and +.Fn X509_REVOKED_get0_extensions +return a stack of extensions, or +.Dv NULL +if no extensions are present. +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr d2i_X509_EXTENSION 3 , +.Xr X509_check_purpose 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_get_version 3 , +.Xr X509_new 3 , +.Xr X509_REVOKED_new 3 , +.Xr X509V3_EXT_print 3 , +.Xr X509V3_extensions_print 3 +.Sh HISTORY +.Fn X509V3_EXT_d2i +first appeared in OpenSSL 0.9.2b. +.Fn X509V3_EXT_i2d +first appeared in OpenSSL 0.9.3. +Both functions have been available since +.Ox 2.6 . +.Pp +.Fn X509V3_get_d2i , +.Fn X509_get_ext_d2i , +.Fn X509_CRL_get_ext_d2i , +and +.Fn X509_REVOKED_get_ext_d2i +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn X509V3_add1_i2d , +.Fn X509_add1_ext_i2d , +.Fn X509_CRL_add1_ext_i2d , +and +.Fn X509_REVOKED_add1_ext_i2d +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn X509_get0_extensions , +.Fn X509_CRL_get0_extensions , +and +.Fn X509_REVOKED_get0_extensions +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Pp +.Fn X509_get0_uids +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.3 . diff --git a/Libraries/libressl/man/X509_ALGOR_dup.3 b/Libraries/libressl/man/X509_ALGOR_dup.3 new file mode 100644 index 000000000..2cfe36184 --- /dev/null +++ b/Libraries/libressl/man/X509_ALGOR_dup.3 @@ -0,0 +1,242 @@ +.\" $OpenBSD: X509_ALGOR_dup.3,v 1.16 2021/07/06 16:05:44 schwarze Exp $ +.\" OpenSSL 4692340e Jun 7 15:49:08 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 6 2021 $ +.Dt X509_ALGOR_DUP 3 +.Os +.Sh NAME +.Nm X509_ALGOR_new , +.Nm X509_ALGOR_free , +.Nm X509_ALGOR_dup , +.Nm X509_ALGOR_set0 , +.Nm X509_ALGOR_get0 , +.Nm X509_ALGOR_set_md , +.Nm X509_ALGOR_cmp +.Nd create, change, and inspect algorithm identifiers +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_ALGOR * +.Fn X509_ALGOR_new void +.Ft void +.Fn X509_ALGOR_free "X509_ALGOR *alg" +.Ft X509_ALGOR * +.Fo X509_ALGOR_dup +.Fa "X509_ALGOR *alg" +.Fc +.Ft int +.Fo X509_ALGOR_set0 +.Fa "X509_ALGOR *alg" +.Fa "ASN1_OBJECT *aobj" +.Fa "int ptype" +.Fa "void *pval" +.Fc +.Ft void +.Fo X509_ALGOR_get0 +.Fa "const ASN1_OBJECT **paobj" +.Fa "int *pptype" +.Fa "const void **ppval" +.Fa "const X509_ALGOR *alg" +.Fc +.Ft void +.Fo X509_ALGOR_set_md +.Fa "X509_ALGOR *alg" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo X509_ALGOR_cmp +.Fa "const X509_ALGOR *a" +.Fa "const X509_ALGOR *b" +.Fc +.Sh DESCRIPTION +.Fn X509_ALGOR_new +allocates and initializes an empty +.Vt X509_ALGOR +object, representing an ASN.1 +.Vt AlgorithmIdentifier +structure defined in RFC 5280 section 4.1.1.2. +Such objects can specify a cryptographic algorithm together +with algorithm-specific parameters. +They are used by many other objects, for example certificates, +certificate revocation lists, and certificate requests. +.Pp +.Fn X509_ALGOR_free +frees +.Fa alg . +.Pp +.Fn X509_ALGOR_dup +copies +.Fa alg +by calling +.Xr i2d_X509_ALGOR 3 +and +.Xr d2i_X509_ALGOR 3 . +.Pp +.Fn X509_ALGOR_set0 +sets the algorithm OID of +.Fa alg +to +.Fa aobj +and the associated parameter type to +.Fa ptype +with value +.Fa pval . +If +.Fa ptype +is +.Dv V_ASN1_UNDEF +the parameter is omitted, otherwise +.Fa ptype +and +.Fa pval +have the same meaning as the +.Fa type +and +.Fa value +parameters to +.Xr ASN1_TYPE_set 3 . +All the supplied parameters are used internally so must +.Sy NOT +be freed after this call. +.Pp +.Fn X509_ALGOR_get0 +is the inverse of +.Fn X509_ALGOR_set0 : +it returns the algorithm OID in +.Pf * Fa paobj +and the associated parameter in +.Pf * Fa pptype +and +.Pf * Fa ppval +from +.Fa alg . +.Pp +.Fn X509_ALGOR_set_md +sets +.Fa alg +to appropriate values for the message digest +.Fa md . +.Pp +.Fn X509_ALGOR_cmp +compares +.Fa a +and +.Fa b . +.Sh RETURN VALUES +.Fn X509_ALGOR_new +and +.Fn X509_ALGOR_dup +return a new +.Vt X509_ALGOR +object or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_ALGOR_set0 +returns 1 for success or 0 for failure. +.Pp +.Fn X509_ALGOR_cmp +returns 0 if +.Fa a +and +.Fa b +have identical encodings or non-zero otherwise. +.Sh SEE ALSO +.Xr ASN1_TYPE_set 3 , +.Xr d2i_X509_ALGOR 3 , +.Xr EVP_DigestInit 3 , +.Xr X509_get0_signature 3 , +.Xr X509_new 3 , +.Xr X509_PUBKEY_get0_param 3 , +.Xr X509_signature_dump 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn X509_ALGOR_new +and +.Fn X509_ALGOR_free +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Pp +.Fn X509_ALGOR_dup +first appeared in SSLeay 0.9.1 and has been available since +.Ox 2.6 . +.Pp +.Fn X509_ALGOR_set0 +and +.Fn X509_ALGOR_get0 +first appeared in OpenSSL 0.9.8h and have been available since +.Ox 4.5 . +.Pp +.Fn X509_ALGOR_cmp +first appeared in OpenSSL 0.9.8zd, 1.0.0p, and 1.0.1k +and has been available since +.Ox 4.9 . +.Pp +.Fn X509_ALGOR_set_md +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/X509_ATTRIBUTE_get0_object.3 b/Libraries/libressl/man/X509_ATTRIBUTE_get0_object.3 new file mode 100644 index 000000000..4212e27d7 --- /dev/null +++ b/Libraries/libressl/man/X509_ATTRIBUTE_get0_object.3 @@ -0,0 +1,136 @@ +.\" $OpenBSD: X509_ATTRIBUTE_get0_object.3,v 1.2 2021/10/21 16:26:34 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 21 2021 $ +.Dt X509_ATTRIBUTE_GET0_OBJECT 3 +.Os +.Sh NAME +.Nm X509_ATTRIBUTE_get0_object , +.Nm X509_ATTRIBUTE_count , +.Nm X509_ATTRIBUTE_get0_type , +.Nm X509_ATTRIBUTE_get0_data +.\" In the following line, "X.501" and "Attribute" are not typos. +.\" The "Attribute" type is defined in X.501, not in X.509. +.\" The type is called "Attribute" with capital "A", not "attribute". +.Nd X.501 Attribute read accessors +.Sh SYNOPSIS +.In openssl/x509.h +.Ft ASN1_OBJECT * +.Fo X509_ATTRIBUTE_get0_object +.Fa "X509_ATTRIBUTE *attr" +.Fc +.Ft int +.Fo X509_ATTRIBUTE_count +.Fa "const X509_ATTRIBUTE *attr" +.Fc +.Ft ASN1_TYPE * +.Fo X509_ATTRIBUTE_get0_type +.Fa "X509_ATTRIBUTE *attr" +.Fa "int index" +.Fc +.Ft void * +.Fo X509_ATTRIBUTE_get0_data +.Fa "X509_ATTRIBUTE *attr" +.Fa "int index" +.Fa "int type" +.Fa "void *data" +.Fc +.Sh DESCRIPTION +These functions provide read access to the X.501 Attribute object +.Fa attr . +.Pp +For +.Fn X509_ATTRIBUTE_get0_data , +the +.Fa type +argument usually is one of the +.Dv V_ASN1_* +constants defined in +.In openssl/asn1.h . +For example, if a return value of the type +.Vt ASN1_OCTET_STRING +is expected, pass +.Dv V_ASN1_OCTET_STRING +as the +.Fa type +argument. +The +.Fa data +argument is ignored; passing +.Dv NULL +is recommended. +.Sh RETURN VALUES +.Fn X509_ATTRIBUTE_get0_object +returns an internal pointer to the type of +.Fa attr +or +.Dv NULL +if +.Fa attr +is +.Dv NULL +or if its type is not set. +.Pp +.Fn X509_ATTRIBUTE_count +returns the number of values stored in +.Fa attr +or 0 if no value or values are set. +.Pp +.Fn X509_ATTRIBUTE_get0_type +returns an internal pointer to the ASN.1 ANY object +representing the value with the given zero-based +.Fa index +or +.Dv NULL +if +.Fa attr +is +.Dv NULL , +if the +.Fa index +is larger than or equal to the number of values stored in +.Fa attr , +or if no value or values are set. +.Pp +.Fn X509_ATTRIBUTE_get0_data +returns an internal pointer to the data +contained in the value with the given zero-based +.Fa index +or +.Dv NULL +if +.Fa attr +is +.Dv NULL , +if the +.Fa index +is larger than or equal to the number of values stored in +.Fa attr , +if no value or values are set, +or if the ASN.1 ANY object representing the value with the given +.Fa index +is not of the requested +.Fa type . +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr ASN1_TYPE_new 3 , +.Xr OPENSSL_sk_new 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509_ATTRIBUTE_set1_object 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_ATTRIBUTE_new.3 b/Libraries/libressl/man/X509_ATTRIBUTE_new.3 new file mode 100644 index 000000000..5dcdc6e21 --- /dev/null +++ b/Libraries/libressl/man/X509_ATTRIBUTE_new.3 @@ -0,0 +1,183 @@ +.\" $OpenBSD: X509_ATTRIBUTE_new.3,v 1.16 2021/10/26 12:56:48 schwarze Exp $ +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 26 2021 $ +.Dt X509_ATTRIBUTE_NEW 3 +.Os +.Sh NAME +.Nm X509_ATTRIBUTE_new , +.Nm X509_ATTRIBUTE_create , +.Nm X509_ATTRIBUTE_dup , +.Nm X509_ATTRIBUTE_free +.\" In the following line, "X.501" and "Attribute" are not typos. +.\" The "Attribute" type is defined in X.501, not in X.509. +.\" The type is called "Attribute" with capital "A", not "attribute". +.Nd generic X.501 Attribute +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_ATTRIBUTE * +.Fn X509_ATTRIBUTE_new void +.Ft X509_ATTRIBUTE * +.Fn X509_ATTRIBUTE_create "int nid" "int type" "void *value" +.Ft X509_ATTRIBUTE * +.Fn X509_ATTRIBUTE_dup "X509_ATTRIBUTE *attr" +.Ft void +.Fn X509_ATTRIBUTE_free "X509_ATTRIBUTE *attr" +.Sh DESCRIPTION +In the X.501 standard, an +.Vt Attribute +is the fundamental ASN.1 data type used to represent any kind of +property of any kind of directory entry. +In OpenSSL, very few objects use it directly, most notably the +.Vt X509_REQ_INFO +object used for PKCS#10 certification requests described in +.Xr X509_REQ_new 3 , +the +.Vt PKCS8_PRIV_KEY_INFO +object used for PKCS#8 private key information described in +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +and the +.Vt PKCS12_SAFEBAG +container object described in +.Xr PKCS12_SAFEBAG_new 3 . +.Pp +.Fn X509_ATTRIBUTE_new +allocates and initializes an empty +.Vt X509_ATTRIBUTE +object. +.Pp +.Fn X509_ATTRIBUTE_create +allocates a new multi-valued +.Vt X509_ATTRIBUTE +object of the type +.Fa nid +and initializes its set of values +to contain one new ASN.1 ANY object with the given +.Fa value +and +.Fa type . +The +.Fa type +usually is one of the +.Dv V_ASN1_* +constants defined in +.In openssl/asn1.h ; +it is stored without validating it. +If the function succeeds, ownership of the +.Fa value +is transferred to the new +.Vt X509_ATTRIBUTE +object. +.Pp +Be careful to not confuse the type of the attribute +and the type of the value. +.Pp +.Fn X509_ATTRIBUTE_dup +creates a deep copy of +.Fa attr . +.Pp +.Fn X509_ATTRIBUTE_free +frees +.Fa attr . +.Sh RETURN VALUES +.Fn X509_ATTRIBUTE_new , +.Fn X509_ATTRIBUTE_create , +and +.Fn X509_ATTRIBUTE_dup +return the new +.Vt X509_ATTRIBUTE +object or +.Dv NULL +if an error occurs. +.Pp +In particular, these functions fail if memory allocation fails. +.Fn X509_ATTRIBUTE_create +also fails if +.Xr OBJ_nid2obj 3 +fails on +.Fa nid . +.Sh SEE ALSO +.Xr d2i_X509_ATTRIBUTE 3 , +.Xr EVP_PKEY_add1_attr 3 , +.Xr OBJ_nid2obj 3 , +.Xr PKCS12_SAFEBAG_new 3 , +.Xr PKCS7_add_attribute 3 , +.Xr PKCS8_pkey_get0_attrs 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +.Xr X509_ATTRIBUTE_get0_object 3 , +.Xr X509_ATTRIBUTE_set1_object 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 , +.Xr X509_REQ_add1_attr 3 , +.Xr X509_REQ_new 3 , +.Xr X509at_add1_attr 3 , +.Xr X509at_get_attr 3 +.Sh STANDARDS +.Bl -ohang +.It Xo +For the general definition of the +.Vt Attribute +data type: +.Xc +ITU-T Recommendation X.501, also known as ISO/IEC 9594-2: +Information Technology \(en Open Systems Interconnection \(en +The Directory: Models, section 8.2: Overall structure +.It For the specific definition in the context of certification requests: +RFC 2986: PKCS #10: Certification Request Syntax Specification, +section 4.1: CertificationRequestInfo +.It For the specific use in the context of private key information: +RFC 5208: Public-Key Cryptography Standards (PKCS) #8: +Private-Key Information Syntax Specification +.It For the specific definition in the context of PFX: +RFC 7292: PKCS #12: Personal Information Exchange Syntax, +section 4.2: The SafeBag Type +.El +.Sh HISTORY +.Fn X509_ATTRIBUTE_new +and +.Fn X509_ATTRIBUTE_free +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_ATTRIBUTE_create +and +.Fn X509_ATTRIBUTE_dup +first appeared in SSLeay 0.9.1 and have been available since +.Ox 2.6 . +.Sh BUGS +A data type designed to hold arbitrary data is an oxymoron. +.Pp +While it may occasionally be useful for abstract syntax specification +or for generic container objects, using it for the representation +of specific data in a specific data structure feels like dubious +design. +.Pp +Having two distinct data types to hold arbitrary data \(en +in this case, +.Vt X509_ATTRIBUTE +on the X.501 language level and +.Vt X509_EXTENSION +as described in +.Xr X509_EXTENSION_new 3 +on the X.509 language level \(en feels even more questionable, +in particular considering that Attributes in certification requests +can be used to ask for Extensions in certificates. +.Pp +At the very least, the direct use of the low-level generic +.Vt X509_ATTRIBUTE +type in specific data types like certification requests or private +key information looks like a layering violation and appears to put +type safety into jeopardy. diff --git a/Libraries/libressl/man/X509_ATTRIBUTE_set1_object.3 b/Libraries/libressl/man/X509_ATTRIBUTE_set1_object.3 new file mode 100644 index 000000000..3555d4b16 --- /dev/null +++ b/Libraries/libressl/man/X509_ATTRIBUTE_set1_object.3 @@ -0,0 +1,267 @@ +.\" $OpenBSD: X509_ATTRIBUTE_set1_object.3,v 1.3 2021/11/26 13:48:21 jsg Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 26 2021 $ +.Dt X509_ATTRIBUTE_SET1_OBJECT 3 +.Os +.Sh NAME +.Nm X509_ATTRIBUTE_set1_object , +.Nm X509_ATTRIBUTE_set1_data , +.Nm X509_ATTRIBUTE_create_by_OBJ , +.Nm X509_ATTRIBUTE_create_by_NID , +.Nm X509_ATTRIBUTE_create_by_txt +.\" In the following line, "X.501" and "Attribute" are not typos. +.\" The "Attribute" type is defined in X.501, not in X.509. +.\" The type is called "Attribute" with capital "A", not "attribute". +.Nd modify an X.501 Attribute +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_ATTRIBUTE_set1_object +.Fa "X509_ATTRIBUTE *attr" +.Fa "const ASN1_OBJECT *obj" +.Fc +.Ft int +.Fo X509_ATTRIBUTE_set1_data +.Fa "X509_ATTRIBUTE *attr" +.Fa "int type" +.Fa "const void *data" +.Fa "int len" +.Fc +.Ft X509_ATTRIBUTE * +.Fo X509_ATTRIBUTE_create_by_OBJ +.Fa "X509_ATTRIBUTE **pattr" +.Fa "const ASN1_OBJECT *obj" +.Fa "int type" +.Fa "const void *data" +.Fa "int len" +.Fc +.Ft X509_ATTRIBUTE * +.Fo X509_ATTRIBUTE_create_by_NID +.Fa "X509_ATTRIBUTE **pattr" +.Fa "int nid" +.Fa "int type" +.Fa "const void *data" +.Fa "int len" +.Fc +.Ft X509_ATTRIBUTE * +.Fo X509_ATTRIBUTE_create_by_txt +.Fa "X509_ATTRIBUTE **pattr" +.Fa "const char *name" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Sh DESCRIPTION +.Fn X509_ATTRIBUTE_set1_object +sets the type of +.Fa attr +to +.Fa obj . +If +.Fa obj +is dynamically allocated, a deep copy is created. +If the type of +.Fa attr +was already set, the old type is freed +as far as it was dynamically allocated. +After calling this function, +.Fa attr +may be in an inconsistent state +because its values may not agree with the new attribute type. +.Pp +.Fn X509_ATTRIBUTE_set1_data +sets +.Fa attr +to be multi-valued and initializes its set of values +to contain a single new ASN.1 ANY object representing the +.Fa data . +.Pp +The interpretation of the +.Fa data +depends on the values of the +.Fa type +and +.Fa len +arguments; there are four different cases. +.Pp +If the +.Fa type +argument has the bit +.Dv MBSTRING_FLAG +set, +.Fa data +is expected to point to a multibyte character string that is +.Fa len +bytes long and uses the encoding specified by the +.Fa type +argument, and it is expected that an attribute type was already assigned to +.Fa attr , +for example by calling +.Fn X509_ATTRIBUTE_set1_object +before calling +.Fn X509_ATTRIBUTE_set1_data . +In this case, an appropriate ASN.1 multibyte string type is chosen and +a new object of that type is allocated and populated to represent the +.Fa data +by calling +.Xr ASN1_STRING_set_by_NID 3 . +The type of that new ASN.1 string object is subsequently used instead of the +.Fa type +argument. +.Pp +If the +.Fa type +argument does not have the bit +.Dv MBSTRING_FLAG +set and the +.Fa len argument +is not \-1, the +.Fa type +argument is expected to be one of the types documented in +.Xr ASN1_STRING_new 3 +and +.Fa data +is expected to point to a buffer of +.Fa len +bytes. +In this case, a new object is allocated with +.Xr ASN1_STRING_type_new 3 +and populated with +.Xr ASN1_STRING_set 3 . +.Pp +If the +.Fa type +argument does not have the bit +.Dv MBSTRING_FLAG +set and the +.Fa len argument +is \-1, +.Fa data +is expected to point to an object of the given +.Fa type +rather than to a buffer. +In this case, a deep copy of the existing object +into the new ASN.1 ANY object is performed with +.Xr ASN1_TYPE_set1 3 . +.Pp +If the +.Fa type +argument is 0, the +.Fa data +and +.Fa len +arguments are ignored and the set of values is left empty +instead of adding a single ASN.1 ANY object to it. +This violates section 8.2 of the X.501 standard, which requires +every attribute to contain at least one value, but some attribute +types used by the library use empty sets of values anyway. +.Pp +.Fn X509_ATTRIBUTE_create_by_OBJ +sets the type of +.Pf ** Fa attr +to +.Fa obj +using +.Fn X509_ATTRIBUTE_set1_object +and copies the +.Fa data +into it using +.Fn X509_ATTRIBUTE_set1_data . +If +.Fa attr +or +.Pf * Fa attr +is +.Dv NULL , +a new +.Vt X509_ATTRIBUTE +object is allocated, populated, and returned. +.Pp +.Fn X509_ATTRIBUTE_create_by_NID +is a wrapper around +.Fn X509_ATTRIBUTE_create_by_OBJ +that obtains the required +.Fa obj +argument by calling +.Xr OBJ_nid2obj 3 +on the +.Fa nid +argument. +.Pp +.Fn X509_ATTRIBUTE_create_by_txt +is a similar wrapper that obtains +.Fa obj +by calling +.Xr OBJ_txt2obj 3 +with the arguments +.Fa name +and 0, which means that long names, short names, and numerical OID +strings are all acceptable. +.Sh RETURN VALUES +.Fn X509_ATTRIBUTE_set1_object +returns 1 if successful or 0 if +.Fa attr +or +.Fa obj +is +.Dv NULL +or if memory allocation fails. +.Pp +.Fn X509_ATTRIBUTE_set1_data +returns 1 if successful or 0 if +.Fa attr +is +.Dv NULL +or if +.Xr ASN1_STRING_set_by_NID 3 , +.Xr ASN1_STRING_set 3 , +.Xr ASN1_TYPE_set1 3 , +or memory allocation fails. +.Pp +.Fn X509_ATTRIBUTE_create_by_OBJ , +.Fn X509_ATTRIBUTE_create_by_NID , +and +.Fn X509_ATTRIBUTE_create_by_txt +return a pointer to the changed or new object or +.Dv NULL +if obtaining +.Fa obj , +allocating memory, or copying fails. +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr ASN1_STRING_new 3 , +.Xr ASN1_STRING_set 3 , +.Xr ASN1_STRING_set_by_NID 3 , +.Xr ASN1_TYPE_new 3 , +.Xr OBJ_nid2obj 3 , +.Xr X509_ATTRIBUTE_get0_object 3 , +.Xr X509_ATTRIBUTE_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . +.Sh BUGS +If +.Fa attr +already contains one or more values, +.Fn X509_ATTRIBUTE_set1_data , +.Fn X509_ATTRIBUTE_create_by_OBJ , +.Fn X509_ATTRIBUTE_create_by_NID , +and +.Fn X509_ATTRIBUTE_create_by_txt +silently overwrite the pointers to the old values +and leak the memory used for them. diff --git a/Libraries/libressl/man/X509_CINF_new.3 b/Libraries/libressl/man/X509_CINF_new.3 new file mode 100644 index 000000000..f7de4d952 --- /dev/null +++ b/Libraries/libressl/man/X509_CINF_new.3 @@ -0,0 +1,118 @@ +.\" $OpenBSD: X509_CINF_new.3,v 1.10 2021/07/24 14:33:14 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 24 2021 $ +.Dt X509_CINF_NEW 3 +.Os +.Sh NAME +.Nm X509_CINF_new , +.Nm X509_CINF_free , +.Nm X509_VAL_new , +.Nm X509_VAL_free , +.Nm X509_CERT_AUX_new , +.Nm X509_CERT_AUX_free +.Nd X.509 certificate information objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_CINF * +.Fn X509_CINF_new void +.Ft void +.Fn X509_CINF_free "X509_CINF *inf" +.Ft X509_VAL * +.Fn X509_VAL_new void +.Ft void +.Fn X509_VAL_free "X509_VAL *val" +.Ft X509_CERT_AUX * +.Fn X509_CERT_AUX_new void +.Ft void +.Fn X509_CERT_AUX_free "X509_CERT_AUX *aux" +.Sh DESCRIPTION +.Fn X509_CINF_new +allocates and initializes an empty +.Vt X509_CINF +object, representing an ASN.1 +.Vt TBSCertificate +structure defined in RFC 5280 section 4.1. +It is used inside the +.Vt X509 +object and holds the main information contained in the X.509 +certificate including subject, public key, issuer, serial number, +validity period, and extensions. +.Fn X509_CINF_free +frees +.Fa inf . +.Pp +.Fn X509_VAL_new +allocates and initializes an empty +.Vt X509_VAL +object, representing an ASN.1 +.Vt Validity +structure defined in RFC 5280 section 4.1. +It is used inside the +.Vt X509_CINF +object and holds the validity period of the certificate. +.Fn X509_VAL_free +frees +.Fa val . +.Pp +.Fn X509_CERT_AUX_new +allocates and initializes an empty +.Vt X509_CERT_AUX +structure. +It can be used inside an +.Vt X509 +object to hold optional non-standard auxiliary data appended to a +certificate, for example friendly alias names and trust data. +.Fn X509_CERT_AUX_free +frees +.Fa aux . +.Sh RETURN VALUES +.Fn X509_CINF_new , +.Fn X509_VAL_new , +and +.Fn X509_CERT_AUX_new +return the new +.Vt X509_CINF , +.Vt X509_VAL , +or +.Vt X509_CERT_AUX +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_X509_CINF 3 , +.Xr X509_add1_trust_object 3 , +.Xr X509_CERT_AUX_print 3 , +.Xr X509_check_trust 3 , +.Xr X509_keyid_set1 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn X509_CINF_new , +.Fn X509_CINF_free , +.Fn X509_VAL_new , +and +.Fn X509_VAL_free +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . +.Pp +.Fn X509_CERT_AUX_new +and +.Fn X509_CERT_AUX_free +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_CRL_METHOD_new.3 b/Libraries/libressl/man/X509_CRL_METHOD_new.3 new file mode 100644 index 000000000..f80ce743c --- /dev/null +++ b/Libraries/libressl/man/X509_CRL_METHOD_new.3 @@ -0,0 +1,182 @@ +.\" $OpenBSD: X509_CRL_METHOD_new.3,v 1.1 2021/10/30 16:20:35 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 30 2021 $ +.Dt X509_CRL_METHOD_NEW 3 +.Os +.Sh NAME +.Nm X509_CRL_METHOD_new , +.Nm X509_CRL_METHOD_free , +.Nm X509_CRL_set_default_method , +.Nm X509_CRL_set_meth_data , +.Nm X509_CRL_get_meth_data +.Nd customize CRL handling +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_CRL_METHOD * +.Fo X509_CRL_METHOD_new +.Fa "int (*crl_init)(X509_CRL *crl)" +.Fa "int (*crl_free)(X509_CRL *crl)" +.Fa "int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,\ + ASN1_INTEGER *ser, X509_NAME *issuer)" +.Fa "int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)" +.Fc +.Ft void +.Fn X509_CRL_METHOD_free "X509_CRL_METHOD *method" +.Ft void +.Fn X509_CRL_set_default_method "const X509_CRL_METHOD *method" +.Ft void +.Fn X509_CRL_set_meth_data "X509_CRL *crl" "void *data" +.Ft void * +.Fn X509_CRL_get_meth_data "X509_CRL *crl" +.Sh DESCRIPTION +These functions customize BER decoding and signature verification +of X.509 certificate revocation lists, +as well as retrieval of revoked entries from such lists. +.Pp +.Fn X509_CRL_METHOD_new +allocates and initializes a new +.Vt X509_CRL_METHOD +object, storing the four pointers to callback functions in it +that are provided as arguments. +.Pp +.Fn X509_CRL_METHOD_free +frees the given +.Fa method +object. +If +.Fa method +is a +.Dv NULL +pointer or points to the static object built into the library, +no action occurs. +.Pp +.Fn X509_CRL_set_default_method +designates the given +.Fa method +to be used for objects that will be created with +.Xr X509_CRL_new 3 +in the future. +It has no effect on +.Vt X509_CRL +objects that already exist. +If +.Fa method +is +.Dv NULL , +any previously installed method will no longer be used for new +.Vt X509_CRL +objects created in the future, and those future objects will adhere +to the default behaviour instead. +.Pp +The optional function +.Fn crl_init +will be called at the end of +.Xr d2i_X509_CRL 3 , +the optional function +.Fn crl_free +near the end of +.Xr X509_CRL_free 3 , +immediately before freeing +.Fa crl +itself. +The function +.Fn crl_lookup +will be called by +.Xr X509_CRL_get0_by_serial 3 , +setting +.Fa issuer +to +.Dv NULL , +and by +.Xr X509_CRL_get0_by_cert 3 , +both instead of performing the default action. +The function +.Fn crl_verify +will be called by +.Xr X509_CRL_verify 3 +instead of performing the default action. +.Pp +.Fn X509_CRL_set_meth_data +stores the pointer to the auxiliary +.Fa data +inside the +.Fa crl +object. +The pointer is expected to remain valid during the whole lifetime of the +.Fa crl +object but is not automatically freed when the +.Fa crl +object is freed. +.Pp +.Fn X509_CRL_get_meth_data +retrieves the +.Fa data +from +.Fa crl +the was added with +.Fn X509_CRL_set_meth_data . +This may for example be useful inside the four callback methods +installed with +.Fn X509_CRL_METHOD_new . +.Sh RETURN VALUES +.Fn X509_CRL_METHOD_new +returns a pointer to the new object or +.Dv NULL +if memory allocation fails. +.Pp +.Fn X509_CRL_get_meth_data +returns the pointer previously installed with +.Fn X509_CRL_set_meth_data +or +.Dv NULL +if +.Fn X509_CRL_set_meth_data +was not called on +.Fa crl . +.Pp +The callback functions +.Fn crl_init +and +.Fn crl_free +are supposed to return 1 for success or 0 for failure. +.Pp +The callback function +.Fn crl_lookup +is supposed to return 0 for failure or 1 for success, +except if the revoked entry has the reason +.Qq removeFromCRL , +in which case it is supposed to return 2. +.Pp +The callback function +.Fn crl_verify +is supposed to return 1 if the signature is valid +or 0 if the signature check fails. +If the signature could not be checked at all because it was invalid +or some other error occurred, \-1 may be returned. +.Sh SEE ALSO +.Xr ASN1_INTEGER_new 3 , +.Xr d2i_X509_CRL 3 , +.Xr EVP_PKEY_new 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_CRL_verify 3 , +.Xr X509_NAME_new 3 , +.Xr X509_REVOKED_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/X509_CRL_get0_by_serial.3 b/Libraries/libressl/man/X509_CRL_get0_by_serial.3 new file mode 100644 index 000000000..865e86feb --- /dev/null +++ b/Libraries/libressl/man/X509_CRL_get0_by_serial.3 @@ -0,0 +1,192 @@ +.\" $OpenBSD: X509_CRL_get0_by_serial.3,v 1.12 2021/10/30 16:20:35 schwarze Exp $ +.\" full merge up to: OpenSSL cdd6c8c5 Mar 20 12:29:37 2017 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 30 2021 $ +.Dt X509_CRL_GET0_BY_SERIAL 3 +.Os +.Sh NAME +.Nm X509_CRL_get0_by_serial , +.Nm X509_CRL_get0_by_cert , +.Nm X509_CRL_get_REVOKED , +.Nm X509_CRL_add0_revoked , +.Nm X509_CRL_sort +.Nd add, sort, and retrieve CRL entries +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_CRL_get0_by_serial +.Fa "X509_CRL *crl" +.Fa "X509_REVOKED **ret" +.Fa "ASN1_INTEGER *serial" +.Fc +.Ft int +.Fo X509_CRL_get0_by_cert +.Fa "X509_CRL *crl" +.Fa "X509_REVOKED **ret" +.Fa "X509 *x" +.Fc +.Ft STACK_OF(X509_REVOKED) * +.Fo X509_CRL_get_REVOKED +.Fa "X509_CRL *crl" +.Fc +.Ft int +.Fo X509_CRL_add0_revoked +.Fa "X509_CRL *crl" +.Fa "X509_REVOKED *rev" +.Fc +.Ft int +.Fo X509_CRL_sort +.Fa "X509_CRL *crl" +.Fc +.Sh DESCRIPTION +.Fn X509_CRL_get0_by_serial +attempts to find a revoked entry in +.Fa crl +for serial number +.Fa serial . +If it is successful, it sets +.Pf * Fa ret +to the internal pointer of the matching entry. +Consequently, +.Pf * Fa ret +must not be freed up after the call. +.Pp +.Fn X509_CRL_get0_by_cert +is similar to +.Fn X509_CRL_get0_by_serial +except that it looks for a revoked entry using the serial number +of certificate +.Fa x . +.Pp +If +.Xr X509_CRL_set_default_method 3 +was in effect at the time the +.Fa crl +object was created, +.Fn X509_CRL_get0_by_serial +and +.Fn X509_CRL_get0_by_cert +invoke the +.Fn crl_lookup +callback function instead of performing the default action. +.Pp +.Fn X509_CRL_get_REVOKED +returns an internal pointer to a stack of all revoked entries for +.Fa crl . +.Pp +.Fn X509_CRL_add0_revoked +appends revoked entry +.Fa rev +to CRL +.Fa crl . +The pointer +.Fa rev +is used internally so it must not be freed up after the call: it is +freed when the parent CRL is freed. +.Pp +.Fn X509_CRL_sort +sorts the revoked entries of +.Fa crl +into ascending serial number order. +.Pp +Applications can determine the number of revoked entries returned by +.Fn X509_CRL_get_revoked +using +.Fn sk_X509_REVOKED_num +and examine each one in turn using +.Fn sk_X509_REVOKED_value , +both defined in +.In openssl/safestack.h . +.Sh RETURN VALUES +.Fn X509_CRL_get0_by_serial +and +.Fn X509_CRL_get0_by_cert +return 0 for failure or 1 for success, except if the revoked entry +has the reason +.Qq removeFromCRL , +in which case 2 is returned. +.Pp +The +.Fn X509_CRL_add0_revoked +function returns 1 if successful; +otherwise 0 is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_CRL_sort +returns 1 for success or 0 for failure. +The current implementation cannot fail. +.Pp +.Fn X509_CRL_get_REVOKED +returns a STACK of revoked entries. +.Sh SEE ALSO +.Xr d2i_X509_CRL 3 , +.Xr X509_CRL_get_ext 3 , +.Xr X509_CRL_get_issuer 3 , +.Xr X509_CRL_get_version 3 , +.Xr X509_CRL_METHOD_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_REVOKED_new 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +.Fn X509_CRL_get_REVOKED +first appeared in OpenSSL 0.9.2b and has been available since +.Ox 2.6 . +.Pp +.Fn X509_CRL_add0_revoked +and +.Fn X509_CRL_sort +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn X509_CRL_get0_by_serial +and +.Fn X509_CRL_get0_by_cert +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/X509_CRL_new.3 b/Libraries/libressl/man/X509_CRL_new.3 new file mode 100644 index 000000000..82ba18266 --- /dev/null +++ b/Libraries/libressl/man/X509_CRL_new.3 @@ -0,0 +1,157 @@ +.\" $OpenBSD: X509_CRL_new.3,v 1.13 2021/10/30 16:20:35 schwarze Exp $ +.\" +.\" Copyright (c) 2016, 2018, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 30 2021 $ +.Dt X509_CRL_NEW 3 +.Os +.Sh NAME +.Nm X509_CRL_new , +.Nm X509_CRL_dup , +.Nm X509_CRL_up_ref , +.Nm X509_CRL_free , +.Nm X509_CRL_INFO_new , +.Nm X509_CRL_INFO_free +.Nd X.509 certificate revocation lists +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_CRL * +.Fn X509_CRL_new void +.Ft X509_CRL * +.Fn X509_CRL_dup "X509_CRL *crl" +.Ft int +.Fn X509_CRL_up_ref "X509_CRL *crl" +.Ft void +.Fn X509_CRL_free "X509_CRL *crl" +.Ft X509_CRL_INFO * +.Fn X509_CRL_INFO_new void +.Ft void +.Fn X509_CRL_INFO_free "X509_CRL_INFO *crl_info" +.Sh DESCRIPTION +.Fn X509_CRL_new +allocates and initializes an empty +.Vt X509_CRL +object, representing an ASN.1 +.Vt CertificateList +structure defined in RFC 5280 section 5.1. +It can hold a pointer to an +.Vt X509_CRL_INFO +object discussed below together with a cryptographic signature +and information about the signature algorithm used. +The reference count is set to 1. +.Pp +.Fn X509_CRL_dup +creates a deep copy of +.Fa crl . +.Pp +.Fn X509_CRL_up_ref +increments the reference count of +.Fa crl +by 1. +.Pp +.Fn X509_CRL_free +decrements the reference count of +.Fa crl +by 1. +If the reference count reaches 0, it frees +.Fa crl . +If +.Xr X509_CRL_set_default_method 3 +was in effect at the time +.Fa crl +was created and the +.Fn crl_free +callback is not +.Dv NULL , +that callback is invoked near the end of +.Fn X509_CRL_free , +right before freeing +.Fa crl +itself. +.Pp +.Fn X509_CRL_INFO_new +allocates and initializes an empty +.Vt X509_CRL_INFO +object, representing an ASN.1 +.Vt TBSCertList +structure defined in RFC 5280 section 5.1. +It is used inside the +.Vt X509_CRL +object and can hold a list of revoked certificates, an issuer name, +the time the list was issued, the time when the next update of the +list is due, and optional extensions. +.Fn X509_CRL_INFO_free +frees +.Fa crl_info . +.Sh RETURN VALUES +.Fn X509_CRL_new , +.Fn X509_CRL_dup , +and +.Fn X509_CRL_INFO_new +return the new +.Vt X509_CRL +or +.Vt X509_CRL_INFO +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_CRL_up_ref +returns 1 on success or 0 on error. +.Sh SEE ALSO +.Xr ACCESS_DESCRIPTION_new 3 , +.Xr AUTHORITY_KEYID_new 3 , +.Xr d2i_X509_CRL 3 , +.Xr DIST_POINT_new 3 , +.Xr PEM_read_X509_CRL 3 , +.Xr X509_CRL_digest 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_get0_lastUpdate 3 , +.Xr X509_CRL_get0_signature 3 , +.Xr X509_CRL_get_ext 3 , +.Xr X509_CRL_get_ext_d2i 3 , +.Xr X509_CRL_get_issuer 3 , +.Xr X509_CRL_get_version 3 , +.Xr X509_CRL_match 3 , +.Xr X509_CRL_METHOD_new 3 , +.Xr X509_CRL_print 3 , +.Xr X509_CRL_sign 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_INFO_new 3 , +.Xr X509_load_crl_file 3 , +.Xr X509_new 3 , +.Xr X509_OBJECT_get0_X509_CRL 3 , +.Xr X509_REVOKED_new 3 , +.Xr X509_STORE_CTX_set0_crls 3 , +.Xr X509_STORE_get1_crls 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, section 5: CRL and CRL +Extensions Profile +.Sh HISTORY +.Fn X509_CRL_new , +.Fn X509_CRL_free , +.Fn X509_CRL_INFO_new , +and +.Fn X509_CRL_INFO_free +first appeared in SSLeay 0.4.4. +.Fn X509_CRL_dup +first appeared in SSLeay 0.5.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_CRL_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_CRL_print.3 b/Libraries/libressl/man/X509_CRL_print.3 new file mode 100644 index 000000000..2f4832f0e --- /dev/null +++ b/Libraries/libressl/man/X509_CRL_print.3 @@ -0,0 +1,113 @@ +.\" $OpenBSD: X509_CRL_print.3,v 1.1 2021/07/19 13:16:43 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 19 2021 $ +.Dt X509_CRL_PRINT 3 +.Os +.Sh NAME +.Nm X509_CRL_print , +.Nm X509_CRL_print_fp +.Nd pretty-print a certificate revocation list +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_CRL_print +.Fa "BIO *bio" +.Fa "X509_CRL *crl" +.Fc +.Ft int +.Fo X509_CRL_print_fp +.Fa "FILE *fp" +.Fa "X509_CRL *crl" +.Fc +.Sh DESCRIPTION +.Fn X509_CRL_print +prints information contained in +.Fa crl +to +.Fa bio +in human-readable form, in the following order: +.Bl -bullet +.It +The certificate revocation list version number as defined by +the standard, followed in parentheses by the value contained +in the version field in hexadecimal notation. +See +.Xr X509_CRL_get_version 3 +for details. +.It +The name of the signature algorithm is printed with +.Xr X509_signature_print 3 . +.It +The issuer name as returned by +.Xr X509_CRL_get_issuer 3 . +.It +The times of the last and next updates as returned by +.Xr X509_CRL_get0_lastUpdate 3 +and +.Xr X509_CRL_get0_nextUpdate 3 +are printed with +.Xr ASN1_TIME_print 3 . +.It +All X.509 extensions directly contained +in the certificate revocation list object +.Fa crl +are printed with +.Xr X509V3_extensions_print 3 . +.It +Information about revoked certificates is retrieved with +.Xr X509_CRL_get_REVOKED 3 , +and for each revoked certificate, the following is printed: +.Bl -bullet +.It +The serial number of the certificate is printed with +.Xr i2a_ASN1_INTEGER 3 . +.It +The revocation date is printed with +.Xr ASN1_TIME_print 3 . +.It +All X.509 extensions contained in the revocation entry are printed with +.Xr X509V3_extensions_print 3 . +.El +.It +The signature of +.Fa crl +is printed with +.Xr X509_signature_print 3 . +.El +.Pp +.Fn X509_CRL_print_fp +is similar to +.Fn X509_CRL_print +except that it prints to +.Fa fp . +.Sh RETURN VALUES +These functions are intended to return 1 for success and 0 for error. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_print_ex 3 , +.Xr X509_REVOKED_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.2 and have been available since +.Ox 2.6 . +.Sh BUGS +Most I/O errors are silently ignored. +Even if the information printed is incomplete, these functions may +return 1 anyway. +.Pp +If the version number is invalid, no information from the CRL is printed +and the functions fail. diff --git a/Libraries/libressl/man/X509_EXTENSION_set_object.3 b/Libraries/libressl/man/X509_EXTENSION_set_object.3 new file mode 100644 index 000000000..dcfe075eb --- /dev/null +++ b/Libraries/libressl/man/X509_EXTENSION_set_object.3 @@ -0,0 +1,325 @@ +.\" $OpenBSD: X509_EXTENSION_set_object.3,v 1.17 2023/04/30 19:40:23 tb Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt X509_EXTENSION_SET_OBJECT 3 +.Os +.Sh NAME +.Nm X509_EXTENSION_new , +.Nm X509_EXTENSION_dup , +.Nm X509_EXTENSION_free , +.Nm X509_EXTENSION_create_by_NID , +.Nm X509_EXTENSION_create_by_OBJ , +.Nm X509_EXTENSION_set_object , +.Nm X509_EXTENSION_set_critical , +.Nm X509_EXTENSION_set_data , +.Nm X509_EXTENSION_get_object , +.Nm X509_EXTENSION_get_critical , +.Nm X509_EXTENSION_get_data +.\" In the next line, the capital "E" is not a typo. +.\" The ASN.1 structure is called "Extension", not "extension". +.Nd create, change, and inspect X.509 Extension objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_EXTENSION * +.Fn X509_EXTENSION_new void +.Ft X509_EXTENSION * +.Fn X509_EXTENSION_dup "X509_EXTENSION *ex" +.Ft void +.Fn X509_EXTENSION_free "X509_EXTENSION *ex" +.Ft X509_EXTENSION * +.Fo X509_EXTENSION_create_by_NID +.Fa "X509_EXTENSION **ex" +.Fa "int nid" +.Fa "int crit" +.Fa "ASN1_OCTET_STRING *data" +.Fc +.Ft X509_EXTENSION * +.Fo X509_EXTENSION_create_by_OBJ +.Fa "X509_EXTENSION **ex" +.Fa "const ASN1_OBJECT *obj" +.Fa "int crit" +.Fa "ASN1_OCTET_STRING *data" +.Fc +.Ft int +.Fo X509_EXTENSION_set_object +.Fa "X509_EXTENSION *ex" +.Fa "const ASN1_OBJECT *obj" +.Fc +.Ft int +.Fo X509_EXTENSION_set_critical +.Fa "X509_EXTENSION *ex" +.Fa "int crit" +.Fc +.Ft int +.Fo X509_EXTENSION_set_data +.Fa "X509_EXTENSION *ex" +.Fa "ASN1_OCTET_STRING *data" +.Fc +.Ft ASN1_OBJECT * +.Fo X509_EXTENSION_get_object +.Fa "X509_EXTENSION *ex" +.Fc +.Ft int +.Fo X509_EXTENSION_get_critical +.Fa "const X509_EXTENSION *ex" +.Fc +.Ft ASN1_OCTET_STRING * +.Fo X509_EXTENSION_get_data +.Fa "X509_EXTENSION *ex" +.Fc +.Sh DESCRIPTION +.Fn X509_EXTENSION_new +allocates and initializes an empty +.Vt X509_EXTENSION +object, representing an ASN.1 +.Vt Extension +structure defined in RFC 5280 section 4.1. +It is a wrapper object around specific extension objects of different +types and stores an extension type identifier and a criticality +flag in addition to the DER-encoded form of the wrapped object. +.Vt X509_EXTENSION +objects can be used for X.509 v3 certificates inside +.Vt X509_CINF +objects and for X.509 v2 certificate revocation lists inside +.Vt X509_CRL_INFO +and +.Vt X509_REVOKED +objects. +.Pp +.Fn X509_EXTENSION_dup +creates a deep copy of +.Fa ex +using +.Xr ASN1_item_dup 3 . +.Pp +.Fn X509_EXTENSION_free +frees +.Fa ex +and all objects it is using. +.Pp +.Fn X509_EXTENSION_create_by_NID +creates an extension of type +.Fa nid +and criticality +.Fa crit +using data +.Fa data . +The created extension is returned and written to +.Pf * Fa ex +reusing or allocating a new extension if necessary, so +.Pf * Fa ex +should either be +.Dv NULL +or a valid +.Vt X509_EXTENSION +structure. +It must not be an uninitialised pointer. +.Pp +.Fn X509_EXTENSION_create_by_OBJ +is identical to +.Fn X509_EXTENSION_create_by_NID +except that it creates an extension using +.Fa obj +instead of a NID. +.Pp +.Fn X509_EXTENSION_set_object +sets the extension type of +.Fa ex +to +.Fa obj . +The +.Fa obj +pointer is duplicated internally so +.Fa obj +should be freed up after use. +.Pp +.Fn X509_EXTENSION_set_critical +sets the criticality of +.Fa ex +to +.Fa crit . +If +.Fa crit +is zero, the extension in non-critical, otherwise it is critical. +.Pp +.Fn X509_EXTENSION_set_data +sets the data in extension +.Fa ex +to +.Fa data . +The +.Fa data +pointer is duplicated internally. +.Pp +.Fn X509_EXTENSION_get_object +returns the extension type of +.Fa ex +as an +.Vt ASN1_OBJECT +pointer. +The returned pointer is an internal value which must not be freed up. +.Pp +.Fn X509_EXTENSION_get_critical +returns the criticality of extension +.Fa ex +it returns 1 for critical and 0 for non-critical. +.Pp +.Fn X509_EXTENSION_get_data +returns the data of extension +.Fa ex . +The returned pointer is an internal value which must not be freed up. +.Pp +These functions manipulate the contents of an extension directly. +Most applications will want to parse or encode and add an extension: +they should use the extension encode and decode functions instead +such as +.Xr X509_add1_ext_i2d 3 +and +.Xr X509_get_ext_d2i 3 . +.Pp +The +.Fa data +associated with an extension is the extension encoding in an +.Vt ASN1_OCTET_STRING +structure. +.Sh RETURN VALUES +.Fn X509_EXTENSION_new , +.Fn X509_EXTENSION_dup , +.Fn X509_EXTENSION_create_by_NID , +and +.Fn X509_EXTENSION_create_by_OBJ +return an +.Vt X509_EXTENSION +pointer or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_EXTENSION_set_object , +.Fn X509_EXTENSION_set_critical , +and +.Fn X509_EXTENSION_set_data +return 1 for success or 0 for failure. +.Pp +.Fn X509_EXTENSION_get_object +returns an +.Vt ASN1_OBJECT +pointer. +.Pp +.Fn X509_EXTENSION_get_critical +returns 0 for non-critical or 1 for critical. +.Pp +.Fn X509_EXTENSION_get_data +returns an +.Vt ASN1_OCTET_STRING +pointer. +.Sh SEE ALSO +.Xr ACCESS_DESCRIPTION_new 3 , +.Xr AUTHORITY_KEYID_new 3 , +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr d2i_X509_EXTENSION 3 , +.Xr DIST_POINT_new 3 , +.Xr ESS_SIGNING_CERT_new 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr GENERAL_NAME_new 3 , +.Xr NAME_CONSTRAINTS_new 3 , +.Xr OCSP_CRLID_new 3 , +.Xr OCSP_SERVICELOC_new 3 , +.Xr PKEY_USAGE_PERIOD_new 3 , +.Xr POLICYINFO_new 3 , +.Xr TS_REQ_new 3 , +.Xr X509_check_ca 3 , +.Xr X509_check_host 3 , +.Xr X509_check_issued 3 , +.Xr X509_get_extension_flags 3 , +.Xr X509_REQ_add_extensions 3 , +.Xr X509V3_EXT_print 3 , +.Xr X509V3_extensions_print 3 , +.Xr X509V3_get_d2i 3 , +.Xr X509v3_get_ext_by_NID 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn X509_EXTENSION_new +and +.Fn X509_EXTENSION_free +first appeared in SSLeay 0.6.2, +.Fn X509_EXTENSION_dup +in SSLeay 0.6.5, and +.Fn X509_EXTENSION_create_by_NID , +.Fn X509_EXTENSION_create_by_OBJ , +.Fn X509_EXTENSION_set_object , +.Fn X509_EXTENSION_set_critical , +.Fn X509_EXTENSION_set_data , +.Fn X509_EXTENSION_get_object , +.Fn X509_EXTENSION_get_critical , +and +.Fn X509_EXTENSION_get_data +in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_INFO_new.3 b/Libraries/libressl/man/X509_INFO_new.3 new file mode 100644 index 000000000..1e9bb832f --- /dev/null +++ b/Libraries/libressl/man/X509_INFO_new.3 @@ -0,0 +1,72 @@ +.\" $OpenBSD: X509_INFO_new.3,v 1.3 2021/10/19 10:39:33 schwarze Exp $ +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 19 2021 $ +.Dt X509_INFO_NEW 3 +.Os +.Sh NAME +.Nm X509_INFO_new , +.Nm X509_INFO_free +.Nd X.509 certificate wrapper object +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_INFO * +.Fn X509_INFO_new void +.Ft void +.Fn X509_INFO_free "X509_INFO *info" +.Sh DESCRIPTION +.Vt X509_INFO +is a reference-counted wrapper object storing a pointer to an X.509 +certificate together with pointers to the associated private key +and to an associated certificate revocation list. +It is for example used internally by +.Xr X509_load_cert_crl_file 3 . +.Pp +.Fn X509_INFO_new +allocates and initializes an empty +.Vt X509_INFO +object and sets its reference count to 1. +.Pp +.Fn X509_INFO_free +decrements the reference count of +.Fa info +by 1. +If the reference count reaches 0, it frees all referenced objects +as well as the storage needed for +.Fa info +itself. +If +.Fa info +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn X509_INFO_new +returns the newly allocated +.Vt X509_INFO +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr PEM_X509_INFO_read 3 , +.Xr X509_CRL_new 3 , +.Xr X509_new 3 , +.Xr X509_PKEY_new 3 +.Sh HISTORY +.Fn X509_INFO_new +and +.Fn X509_INFO_free +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_LOOKUP_hash_dir.3 b/Libraries/libressl/man/X509_LOOKUP_hash_dir.3 new file mode 100644 index 000000000..f6321351e --- /dev/null +++ b/Libraries/libressl/man/X509_LOOKUP_hash_dir.3 @@ -0,0 +1,188 @@ +.\" $OpenBSD: X509_LOOKUP_hash_dir.3,v 1.12 2021/11/12 14:05:28 schwarze Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Victor B. Wagner +.\" and Claus Assmann. +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 12 2021 $ +.Dt X509_LOOKUP_HASH_DIR 3 +.Os +.Sh NAME +.Nm X509_LOOKUP_hash_dir , +.Nm X509_LOOKUP_file , +.Nm X509_LOOKUP_mem +.Nd certificate lookup methods +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft X509_LOOKUP_METHOD * +.Fn X509_LOOKUP_hash_dir void +.Ft X509_LOOKUP_METHOD * +.Fn X509_LOOKUP_file void +.Ft X509_LOOKUP_METHOD * +.Fn X509_LOOKUP_mem void +.Sh DESCRIPTION +.Fn X509_LOOKUP_hash_dir , +.Fn X509_LOOKUP_file , +and +.Fn X509_LOOKUP_mem +return pointers to static certificate lookup method objects +built into the library, for use with +.Vt X509_STORE . +.Pp +Users of the library typically do not need +to retrieve pointers to these method objects manually. +They are automatically used by the +.Xr X509_STORE_load_locations 3 +or +.Xr SSL_CTX_load_verify_locations 3 +functions. +.Ss File Method +The +.Fn X509_LOOKUP_file +method loads all the certificates or CRLs present in a file into memory +at the time the file is added as a lookup source. +.Pp +The file format is ASCII text which contains concatenated PEM +certificates and CRLs. +.Pp +This method should be used by applications which work with a small set +of CAs. +.Ss Hashed Directory Method +.Fa X509_LOOKUP_hash_dir +is a more advanced method which loads certificates and CRLs on demand, +and caches them in memory once they are loaded. +As of OpenSSL 1.0.0, it also checks for newer CRLs upon each lookup, so +that newer CRLs are used as soon as they appear in the directory. +.Pp +The directory should contain one certificate or CRL per file in PEM +format, with a filename of the form +.Ar hash . Ns Ar N +for a certificate, or +.Ar hash . Ns Sy r Ns Ar N +for a CRL. +The +.Ar hash +is the value returned by the +.Xr X509_NAME_hash 3 +function applied to the subject name for certificates or issuer +name for CRLs. +The hash can also be obtained via the +.Fl hash +option of the +.Xr openssl 1 +.Cm x509 +or +.Cm crl +commands. +.Pp +The +.Ar N +suffix is a sequence number that starts at zero and is incremented +consecutively for each certificate or CRL with the same +.Ar hash +value. +Gaps in the sequence numbers are not supported. +It is assumed that there are no more objects with the same hash +beyond the first missing number in the sequence. +.Pp +Sequence numbers make it possible for the directory to contain multiple +certificates with the same subject name hash value. +For example, it is possible to have in the store several certificates +with the same subject or several CRLs with the same issuer (and, for +example, a different validity period). +.Pp +When checking for new CRLs, once one CRL for a given hash value is +loaded, hash_dir lookup method checks only for certificates with +sequence number greater than that of the already cached CRL. +.Pp +Note that the hash algorithm used for subject name hashing changed in +OpenSSL 1.0.0, and all certificate stores have to be rehashed when +moving from OpenSSL 0.9.8 to 1.0.0. +.Ss Memory Method +The +.Fn X509_LOOKUP_mem +method supports loading PEM-encoded certificates and revocation lists +that are already stored in memory, using the function +.Xr X509_LOOKUP_add_mem 3 . +This is particularly useful in processes using +.Xr chroot 2 . +.Sh RETURN VALUES +These functions always return a pointer to a static object. +.Sh SEE ALSO +.Xr SSL_CTX_load_verify_locations 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_STORE_load_locations 3 , +.Xr X509_STORE_new 3 +.Sh HISTORY +.Fn X509_LOOKUP_hash_dir +and +.Fn X509_LOOKUP_file +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_LOOKUP_mem +first appeared in +.Ox 5.7 . diff --git a/Libraries/libressl/man/X509_LOOKUP_new.3 b/Libraries/libressl/man/X509_LOOKUP_new.3 new file mode 100644 index 000000000..f368cbb60 --- /dev/null +++ b/Libraries/libressl/man/X509_LOOKUP_new.3 @@ -0,0 +1,588 @@ +.\" $OpenBSD: X509_LOOKUP_new.3,v 1.9 2021/11/12 14:05:28 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 12 2021 $ +.Dt X509_LOOKUP_NEW 3 +.Os +.Sh NAME +.Nm X509_LOOKUP_new , +.Nm X509_LOOKUP_free , +.Nm X509_LOOKUP_ctrl , +.Nm X509_LOOKUP_add_dir , +.Nm X509_LOOKUP_load_file , +.Nm X509_LOOKUP_add_mem , +.Nm X509_LOOKUP_by_subject , +.Nm X509_LOOKUP_init , +.Nm X509_LOOKUP_shutdown , +.Nm X509_LOOKUP_by_issuer_serial , +.Nm X509_LOOKUP_by_fingerprint , +.Nm X509_LOOKUP_by_alias , +.Nm X509_get_default_cert_dir , +.Nm X509_get_default_cert_file , +.Nm X509_get_default_cert_dir_env , +.Nm X509_get_default_cert_file_env +.\" X509_get_default_private_dir is intentionally undocumented +.\" because it appears to be unused by any real-world software +.\" and because it doesn't do much in the first place. +.Nd certificate lookup object +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft X509_LOOKUP * +.Fn X509_LOOKUP_new "X509_LOOKUP_METHOD *method" +.Ft void +.Fn X509_LOOKUP_free "X509_LOOKUP *lookup" +.Ft int +.Fo X509_LOOKUP_ctrl +.Fa "X509_LOOKUP *lookup" +.Fa "int command" +.Fa "const char *source" +.Fa "long type" +.Fa "char **ret" +.Fc +.Ft int +.Fo X509_LOOKUP_add_dir +.Fa "X509_LOOKUP *lookup" +.Fa "const char *source" +.Fa "long type" +.Fc +.Ft int +.Fo X509_LOOKUP_load_file +.Fa "X509_LOOKUP *lookup" +.Fa "const char *source" +.Fa "long type" +.Fc +.Ft int +.Fo X509_LOOKUP_add_mem +.Fa "X509_LOOKUP *lookup" +.Fa "const struct iovec *source" +.Fa "long type" +.Fc +.Ft int +.Fo X509_LOOKUP_by_subject +.Fa "X509_LOOKUP *lookup" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fa "X509_OBJECT *object" +.Fc +.Ft int +.Fn X509_LOOKUP_init "X509_LOOKUP *lookup" +.Ft int +.Fn X509_LOOKUP_shutdown "X509_LOOKUP *lookup" +.Ft int +.Fo X509_LOOKUP_by_issuer_serial +.Fa "X509_LOOKUP *lookup" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fa "ASN1_INTEGER *serial" +.Fa "X509_OBJECT *object" +.Fc +.Ft int +.Fo X509_LOOKUP_by_fingerprint +.Fa "X509_LOOKUP *lookup" +.Fa "X509_LOOKUP_TYPE type" +.Fa "const unsigned char *bytes" +.Fa "int length" +.Fa "X509_OBJECT *object" +.Fc +.Ft int +.Fo X509_LOOKUP_by_alias +.Fa "X509_LOOKUP *lookup" +.Fa "X509_LOOKUP_TYPE type" +.Fa "const char *string" +.Fa "int length" +.Fa "X509_OBJECT *object" +.Fc +.In openssl/x509.h +.Ft const char * +.Fn X509_get_default_cert_dir void +.Ft const char * +.Fn X509_get_default_cert_file void +.Ft const char * +.Fn X509_get_default_cert_dir_env void +.Ft const char * +.Fn X509_get_default_cert_file_env void +.Sh DESCRIPTION +.Fn X509_LOOKUP_new +allocates a new, empty +.Vt X509_LOOKUP +object and associates it with the +.Fa method +which is a static object returned from either +.Xr X509_LOOKUP_hash_dir 3 +or +.Xr X509_LOOKUP_file 3 +or +.Xr X509_LOOKUP_mem 3 . +.Pp +.Fn X509_LOOKUP_free +releases the memory used by +.Fa lookup . +If +.Fa lookup +is a +.Dv NULL +pointer, no action occurs. +.Pp +The operation of +.Fn X509_LOOKUP_ctrl +depends on the +.Vt X509_LOOKUP_METHOD +used by +.Fa lookup : +.Bl -tag -width 4n +.It Xr X509_LOOKUP_hash_dir 3 +The +.Fa command +is required to be +.Dv X509_L_ADD_DIR +and the +.Fa source +argument is interpreted +as a colon-separated, NUL-terminated list of directory names. +These directories are added to an internal list of directories to search +for certificate files of the given +.Fa type . +.Pp +If +.Fa type +is +.Dv X509_FILETYPE_DEFAULT , +the +.Fa source +argument is ignored and +.Pa /etc/ssl/certs +and a type of +.Dv X509_FILETYPE_PEM +are used instead. +.Pp +.Fn X509_LOOKUP_add_dir +is a macro that calls +.Fn X509_LOOKUP_ctrl +with a +.Fa command +of +.Dv X509_L_ADD_DIR +and +.Fa ret +set to +.Dv NULL . +.Pp +This lookup method is peculiar in so far as calling +.Fn X509_LOOKUP_ctrl +on a lookup object using it does not yet add any certificates to the associated +.Vt X509_STORE +object. +They need to be added selectively using +.Fn X509_LOOKUP_by_subject . +.It Xr X509_LOOKUP_file 3 +The +.Fa command +is required to be +.Dv X509_L_FILE_LOAD +and the +.Fa source +argument is interpreted as a NUL-terminated file name. +If the +.Fa type +is +.Dv X509_FILETYPE_PEM , +the file is read with +.Xr BIO_new_file 3 +and +.Xr PEM_X509_INFO_read_bio 3 +and the certificates and revocation lists found are added to the +.Vt X509_STORE +object associated with +.Fa lookup +using +.Xr X509_STORE_add_cert 3 +and +.Xr X509_STORE_add_crl 3 . +If +.Fa type +is +.Dv X509_FILETYPE_DEFAULT , +the +.Fa source +argument is ignored and +.Pa /etc/ssl/certs.pem +and a type of +.Dv X509_FILETYPE_PEM +are used instead. +If +.Fa type +is +.Dv X509_FILETYPE_ASN1 , +the file is read with +.Xr d2i_X509_bio 3 +and the single certificate is added to the +.Vt X509_STORE +object associated with +.Fa lookup +using +.Xr X509_STORE_add_cert 3 . +.Pp +.Fn X509_LOOKUP_load_file +is a macro calling +.Fn X509_LOOKUP_ctrl +with a +.Fa command +of +.Dv X509_L_FILE_LOAD +and +.Fa ret +set to +.Dv NULL . +.It Xr X509_LOOKUP_mem 3 +The +.Fa command +and +.Fa type +are required to be +.Dv X509_L_MEM +and +.Dv X509_FILETYPE_PEM , +respectively. +The +.Fa source +argument is interpreted as a pointer to an +.Vt iovec +structure defined in +.In sys/uio.h . +The memory area described by that structure is read with +.Xr BIO_new_mem_buf 3 +and +.Xr PEM_X509_INFO_read_bio 3 +and the certificates and revocation lists found are added to the +.Vt X509_STORE +object associated with +.Fa lookup +using +.Xr X509_STORE_add_cert 3 +and +.Xr X509_STORE_add_crl 3 . +.Pp +.Fn X509_LOOKUP_add_mem +is a macro calling +.Fn X509_LOOKUP_ctrl +with a command of +.Dv X509_L_MEM +and +.Fa ret +set to +.Dv NULL . +.El +.Pp +With LibreSSL, +.Fn X509_LOOKUP_ctrl +always ignores the +.Fa ret +argument. +.Pp +With LibreSSL, +.Fn X509_LOOKUP_by_subject +is only useful if +.Fa lookup +uses +.Xr X509_LOOKUP_hash_dir 3 . +It passes the +.Fa name +to +.Xr X509_NAME_hash 3 +and converts the resulting hash to an eight-digit lower-case +hexadecimal number. +.Pp +If the +.Fa type +is +.Dv X509_LU_X509 , +it searches the configured directories for files having that name, +with a file name extension that is a small, non-negative decimal integer +starting at +.Qq ".0" . +These files are read with +.Xr X509_load_cert_file 3 . +In each directory, the search is ended once a file with the expected name +and extension does not exists. +.Pp +If the +.Fa type +is +.Dv X509_LU_CRL , +the file name extensions are expected to have a prefix of +.Qq "r" , +i.e. they start with +.Qq ".r0" , +and the files are read with +.Xr X509_load_crl_file 3 . +.Pp +In case of success, the first match is returned in the +.Pf * Fa object +provided by the caller, overwriting any previous content. +.Pp +With LibreSSL, +.Fn X509_LOOKUP_init , +.Fn X509_LOOKUP_shutdown , +.Fn X509_LOOKUP_by_issuer_serial , +.Fn X509_LOOKUP_by_fingerprint , +and +.Fn X509_LOOKUP_by_alias +have no effect. +.Sh RETURN VALUES +.Fn X509_LOOKUP_new +returns the new object or +.Dv NULL +if memory allocation fails. +.Pp +.Fn X509_LOOKUP_ctrl +returns 1 for success or 0 for failure. +With library implementations other than LibreSSL, +it might also return \-1 for internal errors. +.Pp +.Fn X509_LOOKUP_by_subject +returns 1 for success or 0 for failure. +In particular, it fails if +.Fa lookup +uses +.Xr X509_LOOKUP_file 3 +or +.Xr X509_LOOKUP_mem 3 , +if +.Fa name +is +.Dv NULL , +if +.Fa type +is neither +.Dv X509_LU_X509 +nor +.Dv X509_LU_CRL , +if no match is found, or if memory allocation fails. +With library implementations other than LibreSSL, +it might also return negative values for internal errors. +.Pp +.Fn X509_LOOKUP_init +and +.Fn X509_LOOKUP_shutdown +are supposed to return 1 for success and 0 for failure. +With LibreSSL, they always return 1. +.Pp +With LibreSSL, +.Fn X509_LOOKUP_by_issuer_serial , +.Fn X509_LOOKUP_by_fingerprint , +and +.Fn X509_LOOKUP_by_alias +always return 0. +.Pp +.Fn X509_get_default_cert_dir +returns a pointer to the constant string +.Qq /etc/ssl/certs , +.Fn X509_get_default_cert_file +to +.Qq /etc/ssl/certs.pem , +.Fn X509_get_default_cert_dir_env +to +.Qq SSL_CERT_DIR , +and +.Fn X509_get_default_cert_file_env +to +.Qq SSL_CERT_FILE . +.Sh ENVIRONMENT +For reasons of security and simplicity, +LibreSSL ignores the environment variables +.Ev SSL_CERT_DIR +and +.Ev SSL_CERT_FILE , +but other library implementations may use their contents instead +of the standard locations for trusted certificates, and a few +third-party application programs also inspect these variables +directly and may pass their values to +.Fn X509_LOOKUP_add_dir +and +.Fn X509_LOOKUP_load_file . +.Sh FILES +.Bl -tag -width /etc/ssl/certs.pem -compact +.It Pa /etc/ssl/certs/ +default directory for storing trusted certificates +.It Pa /etc/ssl/certs.pem +default file for storing trusted certificates +.El +.Sh ERRORS +The following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv ERR_R_ASN1_LIB Qq "ASN1 lib" +.Xr d2i_X509_bio 3 +failed in +.Fn X509_LOOKUP_ctrl . +.It Dv X509_R_BAD_X509_FILETYPE Qq "bad x509 filetype" +.Fn X509_LOOKUP_ctrl +was called with an invalid +.Fa type . +.It Dv ERR_R_BUF_LIB Qq "BUF lib" +Memory allocation failed in +.Fn X509_LOOKUP_by_subject . +.It Dv X509_R_INVALID_DIRECTORY Qq "invalid directory" +The +.Fa source +argument of +.Fn X509_LOOKUP_ctrl +with +.Dv X509_L_ADD_DIR +or +.Fn X509_LOOKUP_add_dir +was +.Dv NULL +or an empty string. +.It Dv X509_R_LOADING_CERT_DIR Qq "loading cert dir" +.Fn X509_LOOKUP_ctrl +with +.Dv X509_L_ADD_DIR +or +.Fn X509_LOOKUP_add_dir +was called with +.Dv X509_FILETYPE_DEFAULT +and adding the default directories failed. +This error is added after and in addition to a more specific diagnostic. +.It Dv X509_R_LOADING_DEFAULTS Qq "loading defaults" +.Fn X509_LOOKUP_ctrl +with +.Dv X509_L_FILE_LOAD +or +.Fn X509_LOOKUP_load_file +was called with +.Dv X509_FILETYPE_DEFAULT +and adding the certificates and revocation lists failed. +This error is added after and in addition to a more specific diagnostic. +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +Memory allocation failed in +.Fn X509_LOOKUP_ctrl +or +.Fn X509_LOOKUP_by_subject . +.It Dv ERR_R_PEM_LIB Qq "PEM lib" +.Xr PEM_X509_INFO_read_bio 3 , +.Xr PEM_read_bio_X509_AUX 3 , +or +.Xr PEM_read_bio_X509_CRL 3 +failed in +.Fn X509_LOOKUP_ctrl . +.It Dv ERR_R_SYS_LIB Qq "system lib" +.Xr BIO_new 3 , +.Xr BIO_new_file 3 , +or +.Xr BIO_read_filename 3 +failed in +.Fn X509_LOOKUP_ctrl . +.It Dv X509_R_WRONG_LOOKUP_TYPE Qq "wrong lookup type" +.Fn X509_LOOKUP_by_subject +was called with an invalid +.Fa type . +.El +.Pp +Passing an invalid +.Fa command +to +.Fn X509_LOOKUP_ctrl +or calling +.Fn X509_LOOKUP_by_subject +with a +.Dv NULL +.Fa name +or with arguments that yield no match +causes failure but provides no diagnostics. +.Sh SEE ALSO +.Xr d2i_X509_bio 3 , +.Xr PEM_read_bio_X509_AUX 3 , +.Xr PEM_X509_INFO_read_bio 3 , +.Xr X509_load_cert_file 3 , +.Xr X509_LOOKUP_hash_dir 3 , +.Xr X509_NAME_hash 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 , +.Xr X509_OBJECT_get_type 3 , +.Xr X509_STORE_add_cert 3 , +.Xr X509_STORE_get_by_subject 3 +.Sh HISTORY +.Fn X509_get_default_cert_dir , +.Fn X509_get_default_cert_file , +.Fn X509_get_default_cert_dir_env , +and +.Fn X509_get_default_cert_file_env +first appeared in SSLeay 0.4.1 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_LOOKUP_add_mem +first appeared in +.Ox 5.7 . +.Pp +The other functions first appeared in SSLeay 0.8.0 +and have been available since +.Ox 2.4 . +.Sh BUGS +If the +.Fa type +is +.Dv X509_FILETYPE_DEFAULT +or +.Dv X509_FILETYPE_PEM , +.Fn X509_LOOKUP_ctrl +with +.Dv X509_L_FILE_LOAD +and +.Fn X509_LOOKUP_load_file +silently ignore failure of +.Xr X509_STORE_add_cert 3 +and +.Xr X509_STORE_add_crl 3 +and indicate success anyway. +.Pp +Handling of a +.Dv NULL +.Fa source +is inconsistent for +.Fn X509_LOOKUP_ctrl +with +.Dv X509_L_FILE_LOAD +and for +.Fn X509_LOOKUP_load_file . +With +.Dv X509_FILETYPE_PEM , +it causes failure, but with +.Dv X509_FILETYPE_ASN1 , +no action occurs and success is indicated. +.Pp +When called on a +.Fa lookup +object using +.Xr X509_LOOKUP_mem 3 , +.Fn X509_LOOKUP_ctrl +raises +.Dv ERR_R_PEM_LIB +when called with an invalid +.Fa command +or +.Fa type , +when +.Xr BIO_new_mem_buf 3 +fails, when +.Fa source +contains zero objects, or when +.Xr X509_STORE_add_cert 3 +fails on the first object encountered, which is all inconsistent +with the behaviour of the other lookup methods. diff --git a/Libraries/libressl/man/X509_NAME_ENTRY_get_object.3 b/Libraries/libressl/man/X509_NAME_ENTRY_get_object.3 new file mode 100644 index 000000000..2eadec7b4 --- /dev/null +++ b/Libraries/libressl/man/X509_NAME_ENTRY_get_object.3 @@ -0,0 +1,391 @@ +.\" $OpenBSD: X509_NAME_ENTRY_get_object.3,v 1.16 2021/12/10 16:58:20 schwarze Exp $ +.\" full merge up to: OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 +.\" selective merge up to: OpenSSL ca34e08d Dec 12 07:38:07 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2018, 2019, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2005, 2006, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: December 10 2021 $ +.Dt X509_NAME_ENTRY_GET_OBJECT 3 +.Os +.Sh NAME +.Nm X509_NAME_ENTRY_new , +.Nm X509_NAME_ENTRY_free , +.Nm X509_NAME_ENTRY_get_object , +.Nm X509_NAME_ENTRY_get_data , +.Nm X509_NAME_ENTRY_set , +.Nm X509_NAME_ENTRY_set_object , +.Nm X509_NAME_ENTRY_set_data , +.Nm X509_NAME_ENTRY_create_by_txt , +.Nm X509_NAME_ENTRY_create_by_NID , +.Nm X509_NAME_ENTRY_create_by_OBJ +.\" In the following line, "X.501" is not a typo. +.\" This object defined in X.501, not in X.509. +.Nd X.501 relative distinguished name +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_NAME_ENTRY * +.Fn X509_NAME_ENTRY_new void +.Ft void +.Fo X509_NAME_ENTRY_free +.Fa "X509_NAME_ENTRY* ne" +.Fc +.Ft ASN1_OBJECT * +.Fo X509_NAME_ENTRY_get_object +.Fa "const X509_NAME_ENTRY *ne" +.Fc +.Ft ASN1_STRING * +.Fo X509_NAME_ENTRY_get_data +.Fa "const X509_NAME_ENTRY *ne" +.Fc +.Ft int +.Fo X509_NAME_ENTRY_set +.Fa "const X509_NAME_ENTRY *ne" +.Fc +.Ft int +.Fo X509_NAME_ENTRY_set_object +.Fa "X509_NAME_ENTRY *ne" +.Fa "const ASN1_OBJECT *obj" +.Fc +.Ft int +.Fo X509_NAME_ENTRY_set_data +.Fa "X509_NAME_ENTRY *ne" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fc +.Ft X509_NAME_ENTRY * +.Fo X509_NAME_ENTRY_create_by_txt +.Fa "X509_NAME_ENTRY **ne" +.Fa "const char *field" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fc +.Ft X509_NAME_ENTRY * +.Fo X509_NAME_ENTRY_create_by_NID +.Fa "X509_NAME_ENTRY **ne" +.Fa "int nid" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fc +.Ft X509_NAME_ENTRY * +.Fo X509_NAME_ENTRY_create_by_OBJ +.Fa "X509_NAME_ENTRY **ne" +.Fa "const ASN1_OBJECT *obj" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fc +.Sh DESCRIPTION +An X.501 +.Vt RelativeDistinguishedName +is an ordered set of field type and value pairs. +It is the building block for constructing X.501 +.Vt Name +objects. +The +.Vt X509_NAME_ENTRY +object stores one such pair, containing one field type and one value. +.Pp +.Vt X509_NAME_ENTRY +objects are intended for use by the +.Vt X509_NAME +objects documented in +.Xr X509_NAME_new 3 . +Since part of the information about how several +.Vt X509_NAME_ENTRY +objects combine to form an X.501 +.Vt Name +is stored in the individual +.Vt X509_NAME_ENTRY +objects rather than in the +.Vt X509_NAME +object, any given +.Vt X509_NAME_ENTRY +object can only be used by one +.Vt X509_NAME +object at a time. +.Pp +.Fn X509_NAME_ENTRY_new +allocates and initializes an empty +.Vt X509_NAME_ENTRY +object, representing an ASN.1 +.Vt RelativeDistinguishedName +structure defined in RFC 5280 section 4.1.2.4, but containing not more +than one type-value-pair. +.Pp +.Fn X509_NAME_ENTRY_free +frees +.Fa ne +and the type and value contained in it. +.Pp +.Fn X509_NAME_ENTRY_get_object +retrieves the field type of +.Fa ne +in an +.Vt ASN1_OBJECT +structure. +.Fn X509_NAME_ENTRY_get_data +retrieves the field value of +.Fa ne +in an +.Vt ASN1_STRING +structure. +These two functions can be used to examine an +.Vt X509_NAME_ENTRY +object as returned by +.Xr X509_NAME_get_entry 3 . +.Pp +.Fn X509_NAME_ENTRY_set +retrieves the index of the X.501 +.Vt RelativeDistinguishedName Pq RDN +that +.Fa ne +is part of in the X.501 +.Vt Name +object using it. +The first RDN has index 0. +If an RDN consists of more than one +.Vt X509_NAME_ENTRY +object, they all share the same index. +In practice, RDNs containing more than one type-value-pair are rarely +used, so if an +.Va X509_NAME *name +object uses +.Fa ne , +then +.Fn X509_NAME_ENTRY_set ne +usually agrees with +.Fn sk_X509_NAME_ENTRY_find name->entries ne , +but when multi-pair RDNs are used, it may be smaller. +.Pp +.Fn X509_NAME_ENTRY_set_object +sets the field type of +.Fa ne +to +.Fa obj . +.Pp +.Fn X509_NAME_ENTRY_set_data +sets the field value of +.Fa ne +to the given string +.Fa type +and the value determined by +.Fa bytes +and +.Fa len . +If the +.Fa type +argument is positive and includes the +.Fa MBSTRING_FLAG +bit, +.Xr ASN1_STRING_set_by_NID 3 +is used for setting the value, passing the +.Fa type +as the +.Fa inform +argument and using the +.Fa nid +corresponding to +.Fa ne . +Otherwise, if the +.Fa type +argument is +.Dv V_ASN1_APP_CHOOSE , +the type of +.Fa ne +is set to the return value of +.Xr ASN1_PRINTABLE_type 3 . +.Pp +.Fn X509_NAME_ENTRY_create_by_txt , +.Fn X509_NAME_ENTRY_create_by_NID , +and +.Fn X509_NAME_ENTRY_create_by_OBJ +create and return an +.Vt X509_NAME_ENTRY +structure. +.Pp +Except for +.Fn X509_NAME_ENTRY_get_object +and +.Fn X509_NAME_ENTRY_get_data , +these functions are rarely used because +.Vt X509_NAME_ENTRY +structures are almost always part of +.Vt X509_NAME +structures and the functions described in +.Xr X509_NAME_add_entry_by_txt 3 +are typically used to create and add new entries in a single operation. +.Pp +The arguments of these functions support similar options to the +similarly named ones described in +.Xr X509_NAME_add_entry_by_txt 3 . +So for example +.Fa type +can be set to +.Dv MBSTRING_ASC , +but in the case of +.Fn X509_NAME_ENTRY_set_data +the field type must be set first so the relevant field information +can be looked up internally. +.Sh RETURN VALUES +The +.Fn X509_NAME_ENTRY_new +function returns a valid +.Vt X509_NAME_ENTRY +structure if successful; otherwise +.Dv NULL +is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_NAME_ENTRY_get_object +returns a valid +.Vt ASN1_OBJECT +structure if it is set or +.Dv NULL +if an error occurred. +.Pp +.Fn X509_NAME_ENTRY_get_data +returns a valid +.Vt ASN1_STRING +structure if it is set or +.Dv NULL +if an error occurred. +.Pp +.Fn X509_NAME_ENTRY_set +returns the zero-based index of the RDN +.Fa ne +is used in, or 0 if +.Fa ne +is not yet used by any +.Vt X509_NAME +object. +.Pp +The +.Fn X509_NAME_ENTRY_set_object +function returns 1 if successful; +otherwise 0 is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_NAME_ENTRY_set_data +returns 1 on success or 0 on error. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_NAME_ENTRY_create_by_txt , +.Fn X509_NAME_ENTRY_create_by_NID , +and +.Fn X509_NAME_ENTRY_create_by_OBJ +return a valid +.Vt X509_NAME_ENTRY +structure on success or +.Dv NULL +if an error occurred. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr OBJ_nid2obj 3 , +.Xr X509_NAME_add_entry 3 , +.Xr X509_NAME_get_entry 3 , +.Xr X509_NAME_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Pp +ITU-T Recommendation X.501, also known as ISO/IEC 9594-2: Information +Technology Open Systems Interconnection The Directory: Models, +section 9.3: Relative distinguished name +.Sh HISTORY +.Fn X509_NAME_ENTRY_new +and +.Fn X509_NAME_ENTRY_free +first appeared in SSLeay 0.5.1. +.Fn X509_NAME_ENTRY_get_object , +.Fn X509_NAME_ENTRY_get_data , +.Fn X509_NAME_ENTRY_set_object , +.Fn X509_NAME_ENTRY_set_data , +.Fn X509_NAME_ENTRY_create_by_NID , +and +.Fn X509_NAME_ENTRY_create_by_OBJ +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_NAME_ENTRY_create_by_txt +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn X509_NAME_ENTRY_set +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Sh CAVEATS +Despite its name, +.Fn X509_NAME_ENTRY_set +does not set anything. +Something like +.Dq X509_NAME_ENTRY_get_set +would have been a better name. diff --git a/Libraries/libressl/man/X509_NAME_add_entry_by_txt.3 b/Libraries/libressl/man/X509_NAME_add_entry_by_txt.3 new file mode 100644 index 000000000..3c1237d20 --- /dev/null +++ b/Libraries/libressl/man/X509_NAME_add_entry_by_txt.3 @@ -0,0 +1,283 @@ +.\" $OpenBSD: X509_NAME_add_entry_by_txt.3,v 1.16 2022/03/31 17:27:17 naddy Exp $ +.\" OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2005, 2006, 2013, 2014 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt X509_NAME_ADD_ENTRY_BY_TXT 3 +.Os +.Sh NAME +.Nm X509_NAME_add_entry_by_txt , +.Nm X509_NAME_add_entry_by_OBJ , +.Nm X509_NAME_add_entry_by_NID , +.Nm X509_NAME_add_entry , +.Nm X509_NAME_delete_entry +.Nd X509_NAME modification functions +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_NAME_add_entry_by_txt +.Fa "X509_NAME *name" +.Fa "const char *field" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fa "int loc" +.Fa "int set" +.Fc +.Ft int +.Fo X509_NAME_add_entry_by_OBJ +.Fa "X509_NAME *name" +.Fa "const ASN1_OBJECT *obj" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fa "int loc" +.Fa "int set" +.Fc +.Ft int +.Fo X509_NAME_add_entry_by_NID +.Fa "X509_NAME *name" +.Fa "int nid" +.Fa "int type" +.Fa "const unsigned char *bytes" +.Fa "int len" +.Fa "int loc" +.Fa "int set" +.Fc +.Ft int +.Fo X509_NAME_add_entry +.Fa "X509_NAME *name" +.Fa "const X509_NAME_ENTRY *ne" +.Fa "int loc" +.Fa "int set" +.Fc +.Ft X509_NAME_ENTRY * +.Fo X509_NAME_delete_entry +.Fa "X509_NAME *name" +.Fa "int loc" +.Fc +.Sh DESCRIPTION +.Fn X509_NAME_add_entry_by_txt , +.Fn X509_NAME_add_entry_by_OBJ , +and +.Fn X509_NAME_add_entry_by_NID +add a field whose name is defined by a string +.Fa field , +an object +.Fa obj +or a NID +.Fa nid , +respectively. +The field value to be added is in +.Fa bytes +of length +.Fa len . +If +.Fa len +is -1 then the field length is calculated internally using +.Fn strlen bytes . +.Pp +The type of field is determined by +.Fa type +which can either be a definition of the type of +.Fa bytes +(such as +.Dv MBSTRING_ASC ) +or a standard ASN.1 type (such as +.Dv V_ASN1_IA5STRING ) . +The new entry is added to a position determined by +.Fa loc +and +.Fa set . +.Pp +.Fn X509_NAME_add_entry +adds a copy of an +.Vt X509_NAME_ENTRY +structure +.Fa ne +to +.Fa name . +The new entry is added to a position determined by +.Fa loc +and +.Fa set . +Since a copy of +.Fa ne +is added, +.Fa ne +must be freed up after the call. +.Pp +.Fn X509_NAME_delete_entry +deletes an entry from +.Fa name +at position +.Fa loc . +The deleted entry is returned and must be freed up. +.Pp +The use of string types such as +.Dv MBSTRING_ASC +or +.Dv MBSTRING_UTF8 +is strongly recommended for the +.Fa type +parameter. +This allows the internal code to correctly determine the type of the +field and to apply length checks according to the relevant standards. +.Pp +If instead an ASN.1 type is used, no checks are performed and the supplied +data in +.Fa bytes +is used directly. +.Pp +In +.Fn X509_NAME_add_entry_by_txt +the +.Fa field +string represents the field name using +.Fn OBJ_txt2obj field 0 . +.Pp +The +.Fa loc +and +.Fa set +parameters determine where a new entry should be added. +For almost all applications, +.Fa loc +can be set to -1 and +.Fa set +to 0. +This adds a new entry to the end of +.Fa name +as a single valued +.Vt RelativeDistinguishedName +(RDN). +.Pp +.Fa loc +actually determines the index where the new entry is inserted: +if it is -1 it is appended. +.Pp +.Fa set +determines how the new type is added. +If it is zero, a new RDN is created. +.Pp +If +.Fa set +is -1 or 1, it is added to the previous or next RDN structure +respectively. +This will then be a multivalued RDN: since multivalue RDNs are very +seldom used, +.Fa set +is almost always set to zero. +.Sh RETURN VALUES +.Fn X509_NAME_add_entry_by_txt , +.Fn X509_NAME_add_entry_by_OBJ , +.Fn X509_NAME_add_entry_by_NID , +and +.Fn X509_NAME_add_entry +return 1 for success or 0 if an error occurred. +.Pp +.Fn X509_NAME_delete_entry +returns either the deleted +.Vt X509_NAME_ENTRY +structure or +.Dv NULL +if an error occurred. +.Pp +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh EXAMPLES +Create an +.Vt X509_NAME +structure: +.Bd -literal -offset indent +C=UK, O=Disorganized Organization, CN=Joe Bloggs + +X509_NAME *nm; +nm = X509_NAME_new(); +if (nm == NULL) + /* Some error */ +if (!X509_NAME_add_entry_by_txt(nm, "C", MBSTRING_ASC, + "UK", -1, -1, 0)) + /* Error */ +if (!X509_NAME_add_entry_by_txt(nm, "O", MBSTRING_ASC, + "Disorganized Organization", -1, -1, 0)) + /* Error */ +if (!X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, + "Joe Bloggs", -1, -1, 0)) + /* Error */ +.Ed +.Sh SEE ALSO +.Xr d2i_X509_NAME 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn X509_NAME_add_entry +and +.Fn X509_NAME_delete_entry +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_NAME_add_entry_by_txt , +.Fn X509_NAME_add_entry_by_OBJ , +and +.Fn X509_NAME_add_entry_by_NID +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Sh BUGS +.Fa type +can still be set to +.Dv V_ASN1_APP_CHOOSE +to use +.Xr ASN1_PRINTABLE_type 3 +to determine field types. +Since this form does not understand multicharacter types, performs +no length checks, and can result in invalid field types, its use +is strongly discouraged. diff --git a/Libraries/libressl/man/X509_NAME_get_index_by_NID.3 b/Libraries/libressl/man/X509_NAME_get_index_by_NID.3 new file mode 100644 index 000000000..a2ceb10eb --- /dev/null +++ b/Libraries/libressl/man/X509_NAME_get_index_by_NID.3 @@ -0,0 +1,265 @@ +.\" $OpenBSD: X509_NAME_get_index_by_NID.3,v 1.16 2023/05/29 11:54:50 beck Exp $ +.\" OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006, 2014, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 29 2023 $ +.Dt X509_NAME_GET_INDEX_BY_NID 3 +.Os +.Sh NAME +.Nm X509_NAME_get_index_by_NID , +.Nm X509_NAME_get_index_by_OBJ , +.Nm X509_NAME_entry_count , +.Nm X509_NAME_get_entry , +.Nm X509_NAME_get_text_by_NID , +.Nm X509_NAME_get_text_by_OBJ +.Nd X509_NAME lookup and enumeration functions +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_NAME_get_index_by_NID +.Fa "const X509_NAME *name" +.Fa "int nid" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_NAME_get_index_by_OBJ +.Fa "const X509_NAME *name" +.Fa "const ASN1_OBJECT *obj" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_NAME_entry_count +.Fa "const X509_NAME *name" +.Fc +.Ft X509_NAME_ENTRY * +.Fo X509_NAME_get_entry +.Fa "const X509_NAME *name" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_NAME_get_text_by_NID +.Fa "X509_NAME *name" +.Fa "int nid" +.Fa "char *buf" +.Fa "int len" +.Fc +.Ft int +.Fo X509_NAME_get_text_by_OBJ +.Fa "X509_NAME *name" +.Fa "const ASN1_OBJECT *obj" +.Fa "char *buf" +.Fa "int len" +.Fc +.Sh DESCRIPTION +These functions allow an +.Vt X509_NAME +structure to be examined. +The +.Vt X509_NAME +structure is the same as the ASN.1 +.Vt Name +type defined in RFC 2459 (and elsewhere) and used, for example, +in certificate subject and issuer names. +.Pp +.Fn X509_NAME_get_index_by_NID +and +.Fn X509_NAME_get_index_by_OBJ +retrieve the next index matching +.Fa nid +or +.Fa obj +after +.Fa lastpos . +.Fa lastpos +should initially be set to -1. +.Pp +.Fn X509_NAME_get_entry +retrieves the +.Vt X509_NAME_ENTRY +from +.Fa name +corresponding to index +.Fa loc . +Acceptable values for +.Fa loc +run from 0 to +.Fn X509_NAME_entry_count name +- 1. +.Pp +.Fn X509_NAME_get_text_by_NID +and +.Fn X509_NAME_get_text_by_OBJ +retrieve the bytes encoded as UTF-8 from the first entry in +.Fa name +which matches +.Fa nid +or +.Fa obj . +If +.Fa buf +is +.Dv NULL , +nothing is written, but the return value is calculated as usual. +If +.Fa buf +is not +.Dv NULL , +no more than +.Fa len +bytes will be written and the text written to +.Fa buf +will be NUL terminated. +.Pp +If +.Fa len +is not large enough to hold the NUL byte terminated UTF-8 encoding of +the text, or if the UTF-8 encoding of the text would contains a NUL +byte, no data will be written and the call will return failure. +.Pp +All relevant +.Dv NID_* +and +.Dv OBJ_* +codes can be found in the +.In openssl/objects.h +header file. +.Pp +Applications which could pass invalid NIDs to +.Fn X509_NAME_get_index_by_NID +should check for the return value of -2. +Alternatively the NID validity can be determined first by checking that +.Fn OBJ_nid2obj nid +is not +.Dv NULL . +.Sh RETURN VALUES +.Fn X509_NAME_get_index_by_NID +returns the index of the next matching entry, -1 if not found, or -2 if the +.Fa nid +does not correspond to a valid OID. +.Pp +.Fn X509_NAME_get_index_by_OBJ +returns the index of the next matching entry or -1 if not found. +.Pp +.Fn X509_NAME_entry_count +returns the total number of entries in +.Fa name . +.Pp +.Fn X509_NAME_get_entry +returns an internal pointer which must not be freed by the caller or +.Dv NULL +if the index is invalid. +.Pp +.Fn X509_NAME_get_text_by_NID +and +.Fn X509_NAME_get_text_by_OBJ +return the length of the output UTF-8 string written, not counting the +terminating NUL, or -1 in the case of an error or no match being found. +.Pp +In some cases of failure of +.Fn X509_NAME_get_index_by_NID +and +.Fn X509_NAME_get_text_by_NID , +the reason can be determined with +.Xr ERR_get_error 3 . +.Sh EXAMPLES +Process all entries: +.Bd -literal +int i; +X509_NAME_ENTRY *e; + +for (i = 0; i < X509_NAME_entry_count(nm); i++) { + e = X509_NAME_get_entry(nm, i); + /* Do something with e */ +} +.Ed +.Pp +Process all commonName entries: +.Bd -literal +int lastpos = -1; +X509_NAME_ENTRY *e; + +for (;;) { + lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos); + if (lastpos == -1) + break; + e = X509_NAME_get_entry(nm, lastpos); + /* Do something with e */ +} +.Ed +.Sh SEE ALSO +.Xr d2i_X509_NAME 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.8.0 +and have been available since +.Ox 2.4 . +.Sh CAVEATS +.Fn X509_NAME_get_text_by_NID +and +.Fn X509_NAME_get_text_by_OBJ +are legacy functions which have various limitations which make them of +minimal use in practice. +They can only find the first matching entry and will copy the contents +of the field verbatim: this can be highly confusing if the target is a +multicharacter string type like a +.Vt BMPString +or a +.Vt UTF8String . +.Pp +For a more general solution, +.Fn X509_NAME_get_index_by_NID +or +.Fn X509_NAME_get_index_by_OBJ +should be used, followed by +.Fn X509_NAME_get_entry +on any matching indices and then the various +.Vt X509_NAME_ENTRY +utility functions on the result. diff --git a/Libraries/libressl/man/X509_NAME_hash.3 b/Libraries/libressl/man/X509_NAME_hash.3 new file mode 100644 index 000000000..876610952 --- /dev/null +++ b/Libraries/libressl/man/X509_NAME_hash.3 @@ -0,0 +1,97 @@ +.\" $OpenBSD: X509_NAME_hash.3,v 1.3 2021/07/31 14:54:33 schwarze Exp $ +.\" +.\" Copyright (c) 2017, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 31 2021 $ +.Dt X509_NAME_HASH 3 +.Os +.Sh NAME +.Nm X509_NAME_hash , +.Nm X509_issuer_name_hash , +.Nm X509_subject_name_hash , +.\" X509_issuer_and_serial_hash() is intentionally undocumented +.\" because it uses MD5 only and is unused in real-world code. +.Nm X509_NAME_hash_old , +.Nm X509_issuer_name_hash_old , +.Nm X509_subject_name_hash_old +.\" In the following line, "X.501" and "Name" are not typos. +.\" The "Name" type is defined in X.501, not in X.509. +.\" The type is called "Name" with capital "N", not "name". +.Nd calculate SHA-1 or MD5 hashes of X.501 Name objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft unsigned long +.Fn X509_NAME_hash "X509_NAME *name" +.Ft unsigned long +.Fn X509_issuer_name_hash "X509 *x" +.Ft unsigned long +.Fn X509_subject_name_hash "X509 *x" +.Ft unsigned long +.Fn X509_NAME_hash_old "X509_NAME *name" +.Ft unsigned long +.Fn X509_issuer_name_hash_old "X509 *x" +.Ft unsigned long +.Fn X509_subject_name_hash_old "X509 *x" +.Sh DESCRIPTION +.Fn X509_NAME_hash +calculates an +.Xr SHA1 3 +hash of the DER-encoded form of +.Fa name . +It is for example used by +.Xr X509_LOOKUP_hash_dir 3 +to locate certificate files in the file system. +.Pp +.Fn X509_issuer_name_hash +and +.Fn X509_subject_name_hash +are wrappers to calculate this hash of the issuer or subject name of +.Fa x , +respectively. +.Pp +.Fn X509_NAME_hash_old , +.Fn X509_issuer_name_hash_old , +and +.Fn X509_subject_name_hash_old +are variants that use MD5 instead of SHA-1. +.Sh RETURN VALUES +These functions return the hash value or 0 if an error occurs. +.Sh SEE ALSO +.Xr i2d_X509_NAME 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_NAME_digest 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn X509_subject_name_hash +first appeared in SSLeay 0.4.0, +.Fn X509_issuer_name_hash +in SSLeay 0.5.1, and +.Fn X509_NAME_hash +in SSLeay 0.8.0. +They were switched to hashing the DER representation of the name +rather than an ASCII rendering in SSLeay 0.9.0 and have all been +available since +.Ox 2.4 . +.Pp +They were switched to using SHA1 instead of MD5 in OpenSSL 1.0.0 and in +.Ox 4.9 . +.Pp +.Fn X509_NAME_hash_old , +.Fn X509_issuer_name_hash_old , +and +.Fn X509_subject_name_hash_old +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/X509_NAME_new.3 b/Libraries/libressl/man/X509_NAME_new.3 new file mode 100644 index 000000000..3a4786a9a --- /dev/null +++ b/Libraries/libressl/man/X509_NAME_new.3 @@ -0,0 +1,103 @@ +.\" $OpenBSD: X509_NAME_new.3,v 1.9 2021/07/20 17:31:32 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 20 2021 $ +.Dt X509_NAME_NEW 3 +.Os +.Sh NAME +.Nm X509_NAME_new , +.Nm X509_NAME_free +.\" In the following line, "X.501" and "Name" are not typos. +.\" The "Name" type is defined in X.501, not in X.509. +.\" The type in called "Name" with capital "N", not "name". +.Nd X.501 Name object +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_NAME * +.Fn X509_NAME_new void +.Ft void +.Fn X509_NAME_free "X509_NAME *name" +.Sh DESCRIPTION +An X.501 +.Vt Name +is an ordered sequence of relative distinguished names. +A relative distinguished name is a set of key-value pairs; see +.Xr X509_NAME_ENTRY_new 3 +for details. +.Pp +Various X.509 structures contain X.501 +.Vt Name +substructures. +They are for example used for the issuers of certificates and +certificate revocation lists and for the subjects of certificates +and certificate requests. +.Pp +.Fn X509_NAME_new +allocates and initializes an empty +.Vt X509_NAME +object, representing an ASN.1 +.Vt Name +structure defined in RFC 5280 section 4.1.2.4. +Data can be added to such objects with the functions described in +.Xr X509_NAME_add_entry_by_txt 3 , +and they can be inspected with the functions described in +.Xr X509_NAME_get_index_by_NID 3 . +.Pp +.Fn X509_NAME_free +frees +.Fa name +and all the +.Vt X509_NAME_ENTRY +objects contained in it. +If +.Fa name +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn X509_NAME_new +returns a new +.Vt X509_NAME +object or +.Dv NULL +if an error occurred. +.Sh SEE ALSO +.Xr d2i_X509_NAME 3 , +.Xr GENERAL_NAME_new 3 , +.Xr NAME_CONSTRAINTS_new 3 , +.Xr SSL_load_client_CA_file 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_NAME_add_entry_by_txt 3 , +.Xr X509_NAME_cmp 3 , +.Xr X509_NAME_digest 3 , +.Xr X509_NAME_ENTRY_new 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_hash 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Pp +ITU-T Recommendation X.501, also known as ISO/IEC 9594-2: +Information Technology \(en Open Systems Interconnection \(en +The Directory: Models, section 9: Names +.Sh HISTORY +.Fn X509_NAME_new +and +.Fn X509_NAME_free +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_NAME_print_ex.3 b/Libraries/libressl/man/X509_NAME_print_ex.3 new file mode 100644 index 000000000..8024d8380 --- /dev/null +++ b/Libraries/libressl/man/X509_NAME_print_ex.3 @@ -0,0 +1,290 @@ +.\" $OpenBSD: X509_NAME_print_ex.3,v 1.12 2021/11/11 15:58:49 schwarze Exp $ +.\" full merge up to: OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 +.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2004, 2007, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 11 2021 $ +.Dt X509_NAME_PRINT_EX 3 +.Os +.Sh NAME +.Nm X509_NAME_print_ex , +.Nm X509_NAME_print_ex_fp , +.Nm X509_NAME_oneline , +.Nm X509_NAME_print +.Nd X509_NAME printing routines +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_NAME_print_ex +.Fa "BIO *out" +.Fa "const X509_NAME *nm" +.Fa "int indent" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo X509_NAME_print_ex_fp +.Fa "FILE *fp" +.Fa "const X509_NAME *nm" +.Fa "int indent" +.Fa "unsigned long flags" +.Fc +.Ft char * +.Fo X509_NAME_oneline +.Fa "const X509_NAME *a" +.Fa "char *buf" +.Fa "int size" +.Fc +.Ft int +.Fo X509_NAME_print +.Fa "BIO *bp" +.Fa "const X509_NAME *name" +.Fa "int obase" +.Fc +.Sh DESCRIPTION +.Fn X509_NAME_print_ex +prints a human readable version of +.Fa nm +to +.Vt BIO +.Fa out . +Each line (for multiline formats) is indented by +.Fa indent +spaces. +The output format can be extensively customised by use of the +.Fa flags +parameter. +.Pp +.Fn X509_NAME_print_ex_fp +is identical to +.Fn X509_NAME_print_ex +except the output is written to the +.Vt FILE +pointer +.Fa fp . +.Pp +.Fn X509_NAME_oneline +prints an ASCII version of +.Fa a +to +.Fa buf . +If +.Fa buf +is +.Dv NULL , +then a buffer is dynamically allocated and returned, and +.Fa size +is ignored. +Otherwise, at most +.Fa size +bytes will be written, including the ending NUL, and +.Fa buf +is returned. +.Pp +.Fn X509_NAME_print +prints out +.Fa name +to +.Fa bp +indenting each line by +.Fa obase +characters. +Multiple lines are used if the output (including indent) exceeds 80 +characters. +.Pp +The functions +.Fn X509_NAME_oneline +and +.Fn X509_NAME_print +are legacy functions which produce a non-standard output form. +They don't handle multi-character fields and have various quirks +and inconsistencies. +Their use is strongly discouraged in new applications. +.Pp +Although there are a large number of possible flags, for most purposes +.Dv XN_FLAG_ONELINE , +.Dv XN_FLAG_MULTILINE , +or +.Dv XN_FLAG_RFC2253 +will suffice. +As noted on the +.Xr ASN1_STRING_print_ex 3 +manual page, for UTF-8 terminals the +.Dv ASN1_STRFLGS_ESC_MSB +should be unset: so for example +.Dv XN_FLAG_ONELINE No & Pf ~ Dv ASN1_STRFLGS_ESC_MSB +would be used. +.Pp +The complete set of the flags supported by +.Dv X509_NAME_print_ex +is listed below. +.Pp +Several options can be OR'ed together. +.Pp +The options +.Dv XN_FLAG_SEP_COMMA_PLUS , +.Dv XN_FLAG_SEP_CPLUS_SPC , +.Dv XN_FLAG_SEP_SPLUS_SPC , +and +.Dv XN_FLAG_SEP_MULTILINE +determine the field separators to use. +Two distinct separators are used between distinct +.Vt RelativeDistinguishedName +components and separate values in the same RDN for a multi-valued RDN. +Multi-valued RDNs are currently very rare so the second separator +will hardly ever be used. +.Pp +.Dv XN_FLAG_SEP_COMMA_PLUS +uses comma and plus as separators. +.Dv XN_FLAG_SEP_CPLUS_SPC +uses comma and plus with spaces: +this is more readable that plain comma and plus. +.Dv XN_FLAG_SEP_SPLUS_SPC +uses spaced semicolon and plus. +.Dv XN_FLAG_SEP_MULTILINE +uses spaced newline and plus respectively. +.Dv XN_FLAG_SEP_MASK +contains the bits used to represent these four options. +.Pp +If +.Dv XN_FLAG_DN_REV +is set, the whole DN is printed in reversed order. +.Pp +The fields +.Dv XN_FLAG_FN_SN , +.Dv XN_FLAG_FN_LN , +.Dv XN_FLAG_FN_OID , +and +.Dv XN_FLAG_FN_NONE +determine how a field name is displayed. +It will use the short name (e.g. CN), the long name (e.g. commonName), +always use OID numerical form (normally OIDs are only used if the +field name is not recognised) and no field name, respectively. +.Dv XN_FLAG_FN_MASK +contains the bits used to represent these four options. +.Pp +If +.Dv XN_FLAG_SPC_EQ +is set, then spaces will be placed around the +.Ql = +character separating field names and values. +.Pp +If +.Dv XN_FLAG_DUMP_UNKNOWN_FIELDS +is set, then the encoding of unknown fields is printed instead of the +values. +.Pp +If +.Dv XN_FLAG_FN_ALIGN +is set, then field names are padded to 20 characters: +this is only of use for multiline format. +.Pp +Additionally, all the options supported by +.Xr ASN1_STRING_print_ex 3 +can be used to control how each field value is displayed. +.Pp +In addition a number of options can be set for commonly used formats. +.Pp +.Dv XN_FLAG_RFC2253 +sets options which produce an output compatible with RFC 2253. +It is equivalent to +.Dv ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | +.Dv XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS . +.Pp +.Dv XN_FLAG_ONELINE +is a more readable one line format which is the same as: +.Dv ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | +.Dv XN_FLAG_SPC_EQ | XN_FLAG_FN_SN . +.Pp +.Dv XN_FLAG_MULTILINE +is a multiline format which is the same as: +.Dv ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | +.Dv XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN . +.Pp +.Dv XN_FLAG_COMPAT +uses a format identical to +.Fn X509_NAME_print : +in fact it calls +.Fn X509_NAME_print +internally. +.Sh RETURN VALUES +.Fn X509_NAME_print_ex +and +.Fn X509_NAME_print_ex_fp +return 1 on success or 0 on error if +.Dv XN_FLAG_COMPAT +is set in +.Fa flags . +Otherwise, they return the number of printed bytes including the +indentation or \-1 on error. +.Pp +.Fn X509_NAME_oneline +returns a valid string on success or +.Dv NULL +on error. +.Pp +.Fn X509_NAME_print +returns 1 on success or 0 on error. +.Sh SEE ALSO +.Xr ASN1_STRING_print_ex 3 , +.Xr d2i_X509_NAME 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_new 3 +.Sh HISTORY +.Fn X509_NAME_oneline +and +.Fn X509_NAME_print +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_NAME_print_ex +and +.Fn X509_NAME_print_ex_fp +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/X509_OBJECT_get0_X509.3 b/Libraries/libressl/man/X509_OBJECT_get0_X509.3 new file mode 100644 index 000000000..099e8658f --- /dev/null +++ b/Libraries/libressl/man/X509_OBJECT_get0_X509.3 @@ -0,0 +1,290 @@ +.\" $OpenBSD: X509_OBJECT_get0_X509.3,v 1.14 2022/01/15 23:38:50 jsg Exp $ +.\" +.\" Copyright (c) 2018, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 15 2022 $ +.Dt X509_OBJECT_GET0_X509 3 +.Os +.Sh NAME +.Nm X509_OBJECT_get_type , +.Nm X509_OBJECT_new , +.Nm X509_OBJECT_up_ref_count , +.Nm X509_OBJECT_free_contents , +.Nm X509_OBJECT_free , +.Nm X509_OBJECT_get0_X509 , +.Nm X509_OBJECT_get0_X509_CRL , +.Nm X509_OBJECT_idx_by_subject , +.Nm X509_OBJECT_retrieve_by_subject , +.Nm X509_OBJECT_retrieve_match +.Nd certificate, CRL, private key, and string wrapper for certificate stores +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft X509_LOOKUP_TYPE +.Fo X509_OBJECT_get_type +.Fa "const X509_OBJECT *obj" +.Fc +.Ft X509_OBJECT * +.Fo X509_OBJECT_new +.Fa void +.Fc +.Ft int +.Fo X509_OBJECT_up_ref_count +.Fa "X509_OBJECT *obj" +.Fc +.Ft void +.Fo X509_OBJECT_free_contents +.Fa "X509_OBJECT *obj" +.Fc +.Ft void +.Fo X509_OBJECT_free +.Fa "X509_OBJECT *obj" +.Fc +.Ft X509 * +.Fo X509_OBJECT_get0_X509 +.Fa "const X509_OBJECT *obj" +.Fc +.Ft X509_CRL * +.Fo X509_OBJECT_get0_X509_CRL +.Fa "X509_OBJECT *obj" +.Fc +.Ft int +.Fo X509_OBJECT_idx_by_subject +.Fa "STACK_OF(X509_OBJECT) *stack" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fc +.Ft X509_OBJECT * +.Fo X509_OBJECT_retrieve_by_subject +.Fa "STACK_OF(X509_OBJECT) *stack" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fc +.Ft X509_OBJECT * +.Fo X509_OBJECT_retrieve_match +.Fa "STACK_OF(X509_OBJECT) *stack" +.Fa "X509_OBJECT *obj" +.Fc +.Sh DESCRIPTION +The +.Vt X509_OBJECT +structure is a shallow wrapper around one +.Vt X509 +certificate object or one +.Vt X509_CRL +certificate revocation list object. +The type of object stored at any given time can be inspected with +.Fn X509_OBJECT_get_type . +.Pp +Each +.Vt X509_STORE +object uses one stack of +.Vt X509_OBJECT +structures as its main storage area. +.Pp +.Fn X509_OBJECT_new +allocates a new +.Vt X509_OBJECT +structure. +It sets the object type to +.Dv X509_LU_NONE +and the pointer to the certificate or CRL to +.Dv NULL . +.Pp +If +.Fa obj +contains an +.Vt X509 +certificate or an +.Vt X509_CRL +certificate revocation list, +.Fn X509_OBJECT_up_ref_count +increments the reference count of that inner object by 1. +Otherwise, no action occurs. +.Pp +If +.Fa obj +contains an +.Vt X509 +certificate, +.Fn X509_OBJECT_free_contents +calls +.Xr X509_free 3 +on that inner object. +If +.Fa obj +contains an +.Vt X509_CRL +certificate revocation list, it calls +.Xr X509_CRL_free 3 +on that inner list. +Otherwise, no action occurs. +.Fn X509_OBJECT_free_contents +does not free +.Fa obj +itself. +.Pp +.Fn X509_OBJECT_free +calls +.Fn X509_OBJECT_free_contents +and then frees the storage used for the +.Fa obj +itself. +.Pp +If +.Fa type +is +.Dv X509_LU_X509 , +.Fn X509_OBJECT_idx_by_subject +and +.Fn X509_OBJECT_retrieve_by_subject +search the given +.Fa stack +for a certificate with the subject +.Fa name . +If +.Fa type +is +.Dv X509_LU_CRL , +they search for a certificate revocation list with the issuer +.Fa name +instead. +.Pp +If +.Fa obj +contains a certificate, +.Fn X509_OBJECT_retrieve_match +searches the given +.Fa stack +for a certificate with a matching subject name; +if it contains a certificate revocation list, it searches for a +certificate revocation list with a matching issuer name instead; +otherwise, it searches for an +.Vt X509_OBJECT +with a matching type. +.Sh RETURN VALUES +.Fn X509_OBJECT_get_type +returns +.Dv X509_LU_X509 +if +.Fa obj +contains a certificate, +.Dv X509_LU_CRL +if it contains a certificate revocation list, or +.Dv X509_LU_NONE +if it contains neither. +.Pp +.Fn X509_OBJECT_up_ref_count +returns 1 on success and 0 on failure. +.Pp +.Fn X509_OBJECT_new +returns the new object or +.Dv NULL +if memory allocation fails. +.Pp +.Fn X509_OBJECT_get0_X509 +returns an internal pointer to the certificate contained in +.Fa obj +or +.Dv NULL +if +.Fa obj +is +.Dv NULL +or contains no certificate. +.Pp +.Fn X509_OBJECT_get0_X509_CRL +returns an internal pointer to the certificate revocation list contained in +.Fa obj +or +.Dv NULL +if +.Fa obj +is +.Dv NULL +or contains no certificate revocation list. +.Pp +.Fn X509_OBJECT_idx_by_subject +returns the zero-based index of the first matching certificate +or revocation list in the +.Fa stack +or \-1 if +.Fa type +is neither +.Dv X509_LU_X509 +nor +.Dv X509_LU_CRL +or if no match is found. +.Pp +.Fn X509_OBJECT_retrieve_by_subject +returns the first matching certificate or revocation list in the +.Fa stack +or +.Dv NULL +if +.Fa type +is neither +.Dv X509_LU_X509 +nor +.Dv X509_LU_CRL +or if no match is found. +.Pp +.Fn X509_OBJECT_retrieve_match +returns the first matching +.Vt X509_OBJECT +or +.Dv NULL +if +.Fa stack +or +.Fa obj +is +.Dv NULL +or no match is found. +.Sh SEE ALSO +.Xr STACK_OF 3 , +.Xr X509_CRL_new 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 , +.Xr X509_STORE_get0_objects 3 , +.Xr X509_STORE_get_by_subject 3 , +.Xr X509_STORE_load_locations 3 , +.Xr X509_STORE_new 3 +.Sh HISTORY +.Fn X509_OBJECT_up_ref_count +and +.Fn X509_OBJECT_free_contents +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_OBJECT_idx_by_subject , +.Fn X509_OBJECT_retrieve_by_subject , +and +.Fn X509_OBJECT_retrieve_match +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn X509_OBJECT_get_type , +.Fn X509_OBJECT_get0_X509 , +and +.Fn X509_OBJECT_get0_X509_CRL +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . +.Pp +.Fn X509_OBJECT_new +and +.Fn X509_OBJECT_free +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509_PKEY_new.3 b/Libraries/libressl/man/X509_PKEY_new.3 new file mode 100644 index 000000000..253b0f6db --- /dev/null +++ b/Libraries/libressl/man/X509_PKEY_new.3 @@ -0,0 +1,92 @@ +.\" $OpenBSD: X509_PKEY_new.3,v 1.1 2021/10/19 10:39:33 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 19 2021 $ +.Dt X509_PKEY_NEW 3 +.Os +.Sh NAME +.Nm X509_PKEY_new , +.Nm X509_PKEY_free +.Nd X.509 private key wrapper object +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_PKEY * +.Fn X509_PKEY_new void +.Ft void +.Fn X509_PKEY_free "X509_PKEY *wrapper" +.Sh DESCRIPTION +.Vt X509_PKEY +is a reference-counted wrapper object that can store +.Bl -bullet -width 1n +.It +a pointer to an encrypted and ASN.1-encoded private key +.It +a pointer to an +.Vt EVP_PKEY +object representing the same key in decrypted form +.It +a pointer to an +.Vt X509_ALGOR +object identifying the algorithm used by the key +.El +.Pp +The object may contain only the encrypted key or only the decrypted +key or both. +.Pp +.Vt X509_PKEY +is used as a sub-object of the +.Vt X509_INFO +object created by +.Xr PEM_X509_INFO_read_bio 3 +if the PEM file contains any RSA, DSA, or EC PRIVATE KEY object. +.Pp +.Fn X509_PKEY_new +allocates and initializes an empty +.Vt X509_PKEY +object and sets its reference count to 1. +.Pp +.Fn X509_PKEY_free +decrements the reference count of the +.Fa wrapper +object by 1. +If the reference count reaches 0, +it frees all internal objects allocated by the +.Fa wrapper +as well as the storage needed for the +.Fa wrapper +object itself. +If +.Fa wrapper +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn X509_PKEY_new +returns a pointer to the new +.Vt X509_PKEY +object or +.Dv NULL +if memory allocation fails. +.Sh SEE ALSO +.Xr EVP_PKEY_new 3 , +.Xr PEM_X509_INFO_read 3 , +.Xr X509_INFO_new 3 +.Sh HISTORY +.Fn X509_PKEY_new +and +.Fn X509_PKEY_free +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_PUBKEY_new.3 b/Libraries/libressl/man/X509_PUBKEY_new.3 new file mode 100644 index 000000000..648b028d5 --- /dev/null +++ b/Libraries/libressl/man/X509_PUBKEY_new.3 @@ -0,0 +1,402 @@ +.\" $OpenBSD: X509_PUBKEY_new.3,v 1.17 2021/10/26 10:01:23 schwarze Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2020, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 26 2021 $ +.Dt X509_PUBKEY_NEW 3 +.Os +.Sh NAME +.Nm X509_PUBKEY_new , +.Nm X509_PUBKEY_free , +.Nm X509_PUBKEY_set , +.Nm X509_PUBKEY_get0 , +.Nm X509_PUBKEY_get , +.Nm d2i_X509_PUBKEY , +.Nm i2d_X509_PUBKEY , +.Nm d2i_PUBKEY , +.Nm i2d_PUBKEY , +.Nm d2i_PUBKEY_bio , +.Nm d2i_PUBKEY_fp , +.Nm i2d_PUBKEY_fp , +.Nm i2d_PUBKEY_bio , +.Nm X509_PUBKEY_set0_param , +.Nm X509_PUBKEY_get0_param +.Nd X.509 SubjectPublicKeyInfo structure +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_PUBKEY * +.Fn X509_PUBKEY_new void +.Ft void +.Fo X509_PUBKEY_free +.Fa "X509_PUBKEY *a" +.Fc +.Ft int +.Fo X509_PUBKEY_set +.Fa "X509_PUBKEY **x" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft EVP_PKEY * +.Fo X509_PUBKEY_get0 +.Fa "X509_PUBKEY *key" +.Fc +.Ft EVP_PKEY * +.Fo X509_PUBKEY_get +.Fa "X509_PUBKEY *key" +.Fc +.Ft X509_PUBKEY * +.Fo d2i_X509_PUBKEY +.Fa "X509_PUBKEY **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_PUBKEY +.Fa "X509_PUBKEY *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PUBKEY +.Fa "EVP_PKEY **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PUBKEY +.Fa "EVP_PKEY *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PUBKEY_bio +.Fa "BIO *bp" +.Fa "EVP_PKEY **val_out" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PUBKEY_fp +.Fa "FILE *fp" +.Fa "EVP_PKEY **val_out" +.Fc +.Ft int +.Fo i2d_PUBKEY_fp +.Fa "FILE *fp" +.Fa "EVP_PKEY *val_in" +.Fc +.Ft int +.Fo i2d_PUBKEY_bio +.Fa "BIO *bp" +.Fa "EVP_PKEY *val_in" +.Fc +.Ft int +.Fo X509_PUBKEY_set0_param +.Fa "X509_PUBKEY *pub" +.Fa "ASN1_OBJECT *aobj" +.Fa "int ptype" +.Fa "void *pval" +.Fa "unsigned char *penc" +.Fa "int penclen" +.Fc +.Ft int +.Fo X509_PUBKEY_get0_param +.Fa "ASN1_OBJECT **ppkalg" +.Fa "const unsigned char **pk" +.Fa "int *ppklen" +.Fa "X509_ALGOR **pa" +.Fa "X509_PUBKEY *pub" +.Fc +.Sh DESCRIPTION +The +.Vt X509_PUBKEY +structure represents the ASN.1 +.Vt SubjectPublicKeyInfo +structure defined in RFC 5280 section 4.1 and used in certificates +and certificate requests. +.Pp +.Fn X509_PUBKEY_new +allocates and initializes an +.Vt X509_PUBKEY +structure. +.Pp +.Fn X509_PUBKEY_free +frees up the +.Vt X509_PUBKEY +structure +.Fa a . +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn X509_PUBKEY_set +sets the public key in +.Pf * Fa x +to the public key contained in the +.Vt EVP_PKEY +structure +.Fa pkey . +If +.Pf * Fa x +is not +.Dv NULL , +any existing public key structure will be freed. +.Pp +.Fn X509_PUBKEY_get0 +returns the public key contained in +.Fa key . +The returned value is an internal pointer which must not be freed after use. +.Pp +.Fn X509_PUBKEY_get +is similar to +.Fn X509_PUBKEY_get0 +except that the reference +count on the returned key is incremented so it must be freed using +.Xr EVP_PKEY_free 3 +after use. +.Pp +.Fn d2i_X509_PUBKEY , +.Fn i2d_X509_PUBKEY , +.Fn d2i_PUBKEY , +and +.Fn i2d_PUBKEY +decode and encode an ASN.1 +.Vt SubjectPublicKeyInfo +structure using either the +.Vt X509_PUBKEY +or the +.Vt EVP_PKEY +object type, respectively. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Fn d2i_PUBKEY_bio , +.Fn d2i_PUBKEY_fp , +.Fn i2d_PUBKEY_bio +and +.Fn i2d_PUBKEY_fp +are similar to +.Fn d2i_PUBKEY +and +.Fn i2d_PUBKEY +except they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn X509_PUBKEY_set0_param +sets the public key parameters of +.Fa pub . +The OID associated with the algorithm is set to +.Fa aobj . +The type of the algorithm parameters is set to +.Fa ptype +using the structure +.Fa pval . +The encoding of the public key itself is set to the +.Fa penclen +bytes contained in buffer +.Fa penc . +On success ownership of all the supplied parameters is passed to +.Fa pub +so they must not be freed after the call. +.Pp +.Fn X509_PUBKEY_get0_param +retrieves the public key parameters from +.Fa pub , +.Pf * Fa ppkalg +is set to the associated OID and the encoding consists of +.Pf * Fa ppklen +bytes at +.Pf * Fa pk , +and +.Pf * Fa pa +is set to the associated +.Vt AlgorithmIdentifier +for the public key. +If the value of any of these parameters is not required, +it can be set to +.Dv NULL . +All of the retrieved pointers are internal and must not be freed after +the call. +.Sh RETURN VALUES +If the allocation fails, +.Fn X509_PUBKEY_new +returns +.Dv NULL +and sets an error code that can be obtained by +.Xr ERR_get_error 3 . +Otherwise it returns a pointer to the newly allocated structure. +.Pp +.Fn X509_PUBKEY_get0 +returns an internal pointer or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_PUBKEY_get +returns a pointer to an object that had its reference count incremented or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_X509_PUBKEY , +.Fn d2i_PUBKEY , +.Fn d2i_PUBKEY_bio , +and +.Fn d2i_PUBKEY_fp +return a pointer to a valid object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509_PUBKEY +and +.Fn i2d_PUBKEY +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn X509_PUBKEY_set , +.Fn X509_PUBKEY_set0_param , +.Fn X509_PUBKEY_get0_param , +.Fn i2d_PUBKEY_fp , +and +.Fn i2d_PUBKEY_bio +return 1 for success and 0 if an error occurred. +.Sh ERRORS +After failure of +.Fn X509_PUBKEY_get0 +or +.Fn X509_PUBKEY_get , +one of the following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv X509_R_UNSUPPORTED_ALGORITHM Qq "unsupported algorithm" +The public key uses an algorithm unsupported by +.Xr EVP_PKEY_set_type 3 . +.It X509_R_METHOD_NOT_SUPPORTED Qq "method not supported" +While the algorithm is known to +.Xr EVP_PKEY_set_type 3 , +using it for decoding is not supported. +.It X509_R_PUBLIC_KEY_DECODE_ERROR Qq "public key decode error" +Decoding the public key failed. +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +Memory was exhausted when trying to allocate the new +.Vt EVP_PKEY +object. +.El +.Pp +If +.Fa key +is +.Dv NULL +or does not contain a public key, +these functions fail but no error is pushed onto the stack. +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr EVP_PKEY_asn1_set_public 3 , +.Xr X509_ALGOR_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn X509_PUBKEY_new +and +.Fn X509_PUBKEY_free +appeared in SSLeay 0.4 or earlier. +.Fn d2i_X509_PUBKEY +and +.Fn i2d_X509_PUBKEY +first appeared in SSLeay 0.5.1. +.Fn X509_PUBKEY_set +and +.Fn X509_PUBKEY_get +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn d2i_PUBKEY +and +.Fn i2d_PUBKEY +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn d2i_PUBKEY_bio , +.Fn d2i_PUBKEY_fp , +.Fn i2d_PUBKEY_fp , +and +.Fn i2d_PUBKEY_bio +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn X509_PUBKEY_set0_param +and +.Fn X509_PUBKEY_get0_param +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn X509_PUBKEY_get0 +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_PURPOSE_set.3 b/Libraries/libressl/man/X509_PURPOSE_set.3 new file mode 100644 index 000000000..1f723e9b9 --- /dev/null +++ b/Libraries/libressl/man/X509_PURPOSE_set.3 @@ -0,0 +1,295 @@ +.\" $OpenBSD: X509_PURPOSE_set.3,v 1.1 2021/07/23 14:27:32 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 23 2021 $ +.Dt X509_PURPOSE_SET 3 +.Os +.Sh NAME +.Nm X509_PURPOSE_set , +.Nm X509_PURPOSE_get_by_id , +.Nm X509_PURPOSE_add , +.Nm X509_PURPOSE_get_count , +.Nm X509_PURPOSE_cleanup , +.Nm X509_PURPOSE_get0 , +.Nm X509_PURPOSE_get_by_sname , +.Nm X509_PURPOSE_get_id , +.Nm X509_PURPOSE_get0_name , +.Nm X509_PURPOSE_get0_sname , +.Nm X509_PURPOSE_get_trust +.Nd purpose objects, indices, and identifiers +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509_PURPOSE_set +.Fa "int *id_out" +.Fa "int id_in" +.Fc +.Ft int +.Fn X509_PURPOSE_get_by_id "int identifier" +.Ft int +.Fo X509_PURPOSE_add +.Fa "int identifier" +.Fa "int trust" +.Fa "int flags" +.Fa "int (*check_purpose)(const X509_PURPOSE *, const X509 *, int)" +.Fa "const char *name" +.Fa "const char *sname" +.Fa "void *usr_data" +.Fc +.Ft int +.Fn X509_PURPOSE_get_count void +.Ft void +.Fn X509_PURPOSE_cleanup void +.Ft X509_PURPOSE * +.Fn X509_PURPOSE_get0 "int index" +.Ft int +.Fn X509_PURPOSE_get_by_sname "const char *sname" +.Ft int +.Fn X509_PURPOSE_get_id "const X509_PURPOSE *object" +.Ft char * +.Fn X509_PURPOSE_get0_name "const X509_PURPOSE *object" +.Ft char * +.Fn X509_PURPOSE_get0_sname "const X509_PURPOSE *object" +.Ft int +.Fn X509_PURPOSE_get_trust "const X509_PURPOSE *object" +.Sh DESCRIPTION +The purposes that an X.509 certificate is intended to be used for +can be identified in three equivalent ways: +.Bl -enum +.It +By purpose identifiers, which are positive integer constants. +Standard purpose identifiers lie in the range from +.Dv X509_PURPOSE_MIN +to +.Dv X509_PURPOSE_MAX , +inclusive, and are listed in the +.Xr X509_check_purpose 3 +manual page. +User defined purpose identifiers are larger than +.Dv X509_PURPOSE_MAX . +.It +By purpose indices, which are non-negative integer constants +but differ from the purpose identifiers for the same purpose. +Standard purpose indices are smaller than +.Dv X509_PURPOSE_MAX . +User defined purpose indices are larger than or equal to +.Dv X509_PURPOSE_MAX . +.It +By purpose objects of the type +.Vt X509_PURPOSE . +Standard purpose objects are available in static storage. +User defined purpose objects can be created with +.Fn X509_PURPOSE_add . +.El +.Pp +Application programmers cannot choose the way to identify purposes +that they like best; depending on the circumstances, all three ways +are needed. +Be warned that the naming of most functions is misleading. +.Pp +Most API functions documented outside the present manual page +use purpose identifiers rather than purpose indices. +.Ss Using purpose identifiers +.Fn X509_PURPOSE_set +validates the purpose identifier +.Fa id_in . +If it is valid, it is copied to +.Pf * Fa id_out . +Otherwise, +.Pf * Fa id_out +remains unchanged. +.Pp +.Fn X509_PURPOSE_get_by_id +converts the purpose +.Fa identifier +to the corresponding purpose index. +To find the corresponding purpose object, pass the result to +.Fn X509_PURPOSE_get0 . +.Pp +.Fn X509_PURPOSE_add +defines a purpose with the given +.Fa identifier +or modifies its properties if it already exists. +The purpose +.Fa identifier , +the +.Fa trust +identifier, the +.Fa flags , +the +.Fa check_purpose +function, the +.Fa name , +the short name +.Fa sname , +and the +.Fa usr_data +pointer are copied into the +.Vt X509_PURPOSE +object. +When modifying an existing purpose object, previous values of fields are +overwritten and previous +.Fa name +and +.Fa sname +strings are freed if they were dynamically allocated. +When creating a new purpose object, +it is added to the global array of user-defined purpose objects. +.Pp +.Dv X509_PURPOSE_DYNAMIC +and +.Dv X509_PURPOSE_DYNAMIC_NAME +are always ignored in the +.Fa flags +argument. +.Dv X509_PURPOSE_DYNAMIC +is automatically set if the object was created by the user. +It is never set for standard objects, not even if they were +modified by the user. +.Dv X509_PURPOSE_DYNAMIC_NAME +is automatically set if the object was created or modified by the user. +It is only unset for unmodified standard objects. +The library does not appear to define any other flags, so the +.Fa flags +argument is probably useless unless users define their own flags +and use them in the +.Fa check_purpose +function. +.Pp +The third and final argument of the +.Fa check_purpose +function is the +.Fa ca +argument documented in +.Xr X509_check_purpose 3 . +.Pp +.Fn X509_PURPOSE_get_count +returns the total number of purposes currently defined, +including both standard and user-defined purposes. +If no user-defined purposes exist, the returned value is +.Dv X509_PURPOSE_MAX . +.Pp +.Fn X509_PURPOSE_cleanup +deletes all user-defined purpose objects +and invalidates their purpose identifiers and purpose indices. +If any of the standard purpose objects were modified by the user, +those changes are +.Em not +reverted. +.Ss Using purpose indices +.Fn X509_PURPOSE_get0 +converts the purpose +.Fa index +to a pointer to the corresponding purpose object. +To find the corresponding purpose identifier, pass the result to +.Fn X509_PURPOSE_get_id . +.Pp +.Fn X509_PURPOSE_get_by_sname +returns the lowest index of a purpose with the given short name. +.Ss Using purpose objects +.Fn X509_PURPOSE_get_id +converts a pointer to a purpose +.Fa object +to the corresponding purpose identifier. +To find the corresponding purpose index, pass the result to +.Fn X509_PURPOSE_get_by_id . +.Pp +.Fn X509_PURPOSE_get0_name , +.Fn X509_PURPOSE_get0_sname , +and +.Fn X509_PURPOSE_get_trust +retrieve the name, short name, and trust identifier from the +.Fa object , +respectively. +.Sh RETURN VALUES +.Fn X509_PURPOSE_set +returns 1 if +.Fa id_in +is valid or 0 otherwise. +.Pp +.Fn X509_PURPOSE_get_by_id +and +.Fn X509_PURPOSE_get_by_sname +return the corresponding purpose index +or \-1 if no matching purpose is found. +.Pp +.Fn X509_PURPOSE_add +returns 1 for success or 0 for failure. +.Pp +.Fn X509_PURPOSE_get_count +returns the total number of purposes currently defined. +.Pp +.Fn X509_PURPOSE_get0 +returns a standard or user-defined purpose object or +.Dv NULL +if the +.Fa index +is invalid. +.Pp +.Fn X509_PURPOSE_get_id +always returns a valid purpose identifier. +.Pp +.Fn X509_PURPOSE_get0_name +and +.Fn X509_PURPOSE_get0_sname +return pointers to storage owned by the +.Fa object . +.Pp +.Fn X509_PURPOSE_get_trust +returns the trust identifier associated with the +.Fa object . +.Sh ERRORS +The following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv X509V3_R_INVALID_PURPOSE Qq "invalid purpose" +.Fn X509_PURPOSE_set +was called with an invalid +.Fa id_in +argument. +.It Dv X509V3_R_INVALID_NULL_ARGUMENT Qq "invalid null argument" +.Fn X509_PURPOSE_add +was called with a +.Fa name +or +.Fa sname +argument of +.Dv NULL . +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +.Fn X509_PURPOSE_add +failed to allocate memory. +.El +.Pp +The other functions provide no diagnostics. +.Sh SEE ALSO +.Xr X509_check_purpose 3 , +.Xr X509_new 3 , +.Xr X509_STORE_set_purpose 3 , +.Xr X509_VERIFY_PARAM_set_purpose 3 +.Sh HISTORY +.Fn X509_PURPOSE_set +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Pp +The other functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . +.Sh CAVEATS +The difference between purpose identifiers and purpose indices provides +an ideal breeding ground for off-by-one bugs. diff --git a/Libraries/libressl/man/X509_REQ_add1_attr.3 b/Libraries/libressl/man/X509_REQ_add1_attr.3 new file mode 100644 index 000000000..26eb4f144 --- /dev/null +++ b/Libraries/libressl/man/X509_REQ_add1_attr.3 @@ -0,0 +1,186 @@ +.\" $OpenBSD: X509_REQ_add1_attr.3,v 1.2 2021/10/26 18:50:38 jmc Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 26 2021 $ +.Dt X509_REQ_ADD1_ATTR 3 +.Os +.Sh NAME +.Nm X509_REQ_add1_attr , +.Nm X509_REQ_add1_attr_by_OBJ , +.Nm X509_REQ_add1_attr_by_NID , +.Nm X509_REQ_add1_attr_by_txt , +.Nm X509_REQ_delete_attr , +.Nm X509_REQ_get_attr , +.Nm X509_REQ_get_attr_count , +.Nm X509_REQ_get_attr_by_OBJ , +.Nm X509_REQ_get_attr_by_NID +.Nd X.501 Attributes of PKCS#10 certification requests +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_REQ_add1_attr +.Fa "X509_REQ *req" +.Fa "X509_ATTRIBUTE *attr" +.Fc +.Ft int +.Fo X509_REQ_add1_attr_by_OBJ +.Fa "X509_REQ *req" +.Fa "const ASN1_OBJECT *obj" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo X509_REQ_add1_attr_by_NID +.Fa "X509_REQ *req" +.Fa "int nid" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft int +.Fo X509_REQ_add1_attr_by_txt +.Fa "X509_REQ *req" +.Fa "const char *name" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft X509_ATTRIBUTE * +.Fo X509_REQ_delete_attr +.Fa "X509_REQ *req" +.Fa "int index" +.Fc +.Ft X509_ATTRIBUTE * +.Fo X509_REQ_get_attr +.Fa "const X509_REQ *req" +.Fa "int index" +.Fc +.Ft int +.Fo X509_REQ_get_attr_count +.Fa "const X509_REQ *req" +.Fc +.Ft int +.Fo X509_REQ_get_attr_by_OBJ +.Fa "const X509_REQ *req" +.Fa "const ASN1_OBJECT *obj" +.Fa "int start_after" +.Fc +.Ft int +.Fo X509_REQ_get_attr_by_NID +.Fa "const X509_REQ *req" +.Fa "int nid" +.Fa "int start_after" +.Fc +.Sh DESCRIPTION +These functions support associating an array of X.501 Attributes +with a PKCS#10 certification request. +.Pp +.Fn X509_REQ_add1_attr +appends a deep copy of the +.Fa attr +using +.Xr X509at_add1_attr 3 . +.Pp +.Fn X509_REQ_add1_attr_by_OBJ , +.Fn X509_REQ_add1_attr_by_NID , +and +.Fn X509_REQ_add1_attr_by_txt +create a new X.501 Attribute object using +.Xr X509_ATTRIBUTE_create_by_OBJ 3 , +.Xr X509_ATTRIBUTE_create_by_NID 3 , +or +.Xr X509_ATTRIBUTE_create_by_txt 3 , +respectively, and append it using +.Xr X509at_add1_attr 3 . +.Pp +.Fn X509_REQ_delete_attr +deletes the attribute with the zero-based +.Fa index +using +.Xr X509at_delete_attr 3 . +.Pp +.Fn X509_REQ_get_attr +returns the attribute with the zero-based +.Fa index +using +.Xr X509at_get_attr 3 . +.Pp +.Fn X509_REQ_get_attr_count +returns the number of attributes currently associated with +.Fa req +using +.Xr X509at_get_attr_count 3 . +.Pp +.Fn X509_REQ_get_attr_by_OBJ +and +.Fn X509_REQ_get_attr_by_NID +search for an attribute of the type +.Fa obj +or +.Fa nid +using +.Xr X509at_get_attr_by_OBJ 3 +or +.Xr X509at_get_attr_by_NID 3 , +respectively. +.Sh RETURN VALUES +.Fn X509_REQ_add1_attr , +.Fn X509_REQ_add1_attr_by_OBJ , +.Fn X509_REQ_add1_attr_by_NID , +and +.Fn X509_REQ_add1_attr_by_txt +return 1 for success or 0 for failure. +.Pp +.Fn X509_REQ_delete_attr +and +.Fn X509_REQ_get_attr +return the deleted or requested attribute or +.Dv NULL +if the requested index is negative or greater than or equal to +the current number of attributes associated with +.Fa req . +.Pp +.Fn X509_REQ_get_attr_count +returns the current number of attributes. +.Pp +.Fn X509_REQ_get_attr_by_OBJ +and +.Fn X509_REQ_get_attr_by_NID +return the index of the first attribute that has an index greater than +.Fa start_after +and a type matching +.Fa obj +or +.Fa nid , +respectively, or \-1 on failure. +In addition, +.Fn X509_REQ_get_attr_by_NID +returns \-2 if +.Xr OBJ_nid2obj 3 +fails on the requested +.Fa nid . +.Sh SEE ALSO +.Xr OBJ_nid2obj 3 , +.Xr X509_ATTRIBUTE_create_by_OBJ 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509at_add1_attr 3 , +.Xr X509at_get_attr 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_REQ_add_extensions.3 b/Libraries/libressl/man/X509_REQ_add_extensions.3 new file mode 100644 index 000000000..8610edf8c --- /dev/null +++ b/Libraries/libressl/man/X509_REQ_add_extensions.3 @@ -0,0 +1,141 @@ +.\" $OpenBSD: X509_REQ_add_extensions.3,v 1.1 2021/10/27 14:54:07 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 27 2021 $ +.Dt X509_REQ_ADD_EXTENSIONS 3 +.Os +.Sh NAME +.Nm X509_REQ_add_extensions , +.Nm X509_REQ_add_extensions_nid , +.Nm X509_REQ_get_extensions , +.Nm X509_REQ_set_extension_nids , +.Nm X509_REQ_get_extension_nids , +.Nm X509_REQ_extension_nid +.Nd extensions in certification requests +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_REQ_add_extensions +.Fa "X509_REQ *req" +.Fa "STACK_OF(X509_EXTENSION) *extensions" +.Fc +.Ft int +.Fo X509_REQ_add_extensions_nid +.Fa "X509_REQ *req" +.Fa "STACK_OF(X509_EXTENSION) *extensions" +.Fa "int nid" +.Fc +.Ft STACK_OF(X509_EXTENSION) * +.Fn X509_REQ_get_extensions "X509_REQ *req" +.Ft void +.Fn X509_REQ_set_extension_nids "int *nids" +.Ft int * +.Fn X509_REQ_get_extension_nids void +.Ft int +.Fn X509_REQ_extension_nid "int nid" +.Sh DESCRIPTION +.Fn X509_REQ_add_extensions +encodes the array of +.Fa extensions +using +.Xr i2d_X509_EXTENSIONS 3 +and adds a new X.501 Attribute object of the type +.Dv NID_ext_req +to +.Fa req +using the equivalent of +.Xr X509_ATTRIBUTE_create_by_NID 3 +with a +.Fa type +of +.Dv V_ASN1_SEQUENCE . +.Pp +.Fn X509_REQ_add_extensions_nid +is identical except that the specified +.Fa nid +is used as the X.501 Attribute type instead of +.Dv NID_ext_req . +.Pp +.Fn X509_REQ_get_extensions +retrieves the first value of the first X.501 Attribute of appropriate type. +By default, the attribute types +.Dv NID_ext_req +and +.Dv NID_ms_ext_req +are considered appropriate. +.Pp +.Fn X509_REQ_set_extension_nids +replaces the list of attribute types that +.Fn X509_REQ_get_extensions +considers appropriate for storing extensions. +The +.Fa nids +argument is interpreted as a pointer to the first element +of a variable-sized array of +.Vt int . +The last element of the array has to be +.Dv NID_undef . +The array needs to remain valid until +.Fn X509_REQ_set_extension_nids +is called again with a different argument. +.Pp +.Fn X509_REQ_extension_nid +checks whether +.Fn X509_REQ_get_extensions +regards the +.Fa nid +argument as a type appropriate for storing extensions. +.Sh RETURN VALUES +.Fn X509_REQ_add_extensions +and +.Fn X509_REQ_add_extensions_nid +returns 1 for success or 0 for failure. +.Pp +.Fn X509_REQ_get_extensions +returns a newly allocated array of ASN.1 +.Vt Extension +objects or +.Dv NULL +if +.Fa req +is +.Dv NULL , +does not contain +.Vt CertificationRequestInfo , +contains no attribute of an appropriate type, +or if decoding or memory allocation fails. +.Pp +.Fn X509_REQ_get_extension_nids +returns the pointer installed with +.Fn X509_REQ_set_extension_nids +or a pointer to a static array +.Brq Dv NID_ext_req , NID_ms_ext_req , NID_undef +by default. +.Pp +.Fn X509_REQ_extension_nid +returns 1 if +.Fa nid +is considered appropriate or 0 otherwise. +.Sh SEE ALSO +.Xr d2i_X509_EXTENSION 3 , +.Xr STACK_OF 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509V3_extensions_print 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_REQ_new.3 b/Libraries/libressl/man/X509_REQ_new.3 new file mode 100644 index 000000000..0a5828d5d --- /dev/null +++ b/Libraries/libressl/man/X509_REQ_new.3 @@ -0,0 +1,145 @@ +.\" $OpenBSD: X509_REQ_new.3,v 1.11 2021/10/29 09:42:07 schwarze Exp $ +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 29 2021 $ +.Dt X509_REQ_NEW 3 +.Os +.Sh NAME +.Nm X509_REQ_new , +.Nm X509_REQ_dup , +.Nm X509_to_X509_REQ , +.Nm X509_REQ_free , +.Nm X509_REQ_INFO_new , +.Nm X509_REQ_INFO_free +.Nd PKCS#10 certification requests +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_REQ * +.Fn X509_REQ_new void +.Ft X509_REQ * +.Fn X509_REQ_dup "X509_REQ *req" +.Ft X509_REQ * +.Fn X509_to_X509_REQ "X509 *x" "EVP_PKEY *pkey" "const EVP_MD *md" +.Ft void +.Fn X509_REQ_free "X509_REQ *req" +.Ft X509_REQ_INFO * +.Fn X509_REQ_INFO_new void +.Ft void +.Fn X509_REQ_INFO_free "X509_REQ_INFO *req_info" +.Sh DESCRIPTION +.Fn X509_REQ_new +allocates and initializes an empty +.Vt X509_REQ +object, representing an ASN.1 +.Vt CertificationRequest +structure defined in RFC 2986 section 4.2. +It can hold a pointer to an +.Vt X509_REQ_INFO +object discussed below together with a cryptographic signature and +information about the signature algorithm used. +.Pp +.Fn X509_REQ_dup +creates a deep copy of +.Fa req +using +.Xr ASN1_item_dup 3 , +setting the reference count of the copy to 1. +.Pp +.Fn X509_to_X509_REQ +allocates a new certification request object, copies +the subject name and the public key into it from the certificate +.Fa x , +and sets the version to zero. +Unless +.Fa pkey +is +.Dv NULL , +it also signs the request with +.Xr X509_REQ_sign 3 +using +.Fa pkey +and +.Fa md . +.Pp +.Fn X509_REQ_free +frees +.Fa req . +If +.Fa req +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn X509_REQ_INFO_new +allocates and initializes an empty +.Vt X509_REQ_INFO +object, representing an ASN.1 +.Vt CertificationRequestInfo +structure defined in RFC 2986 section 4.1. +It is used inside the +.Vt X509_REQ +object and can hold the subject and the public key of the requested +certificate and additional attributes. +.Fn X509_REQ_INFO_free +frees +.Fa req_info . +If +.Fa req_info +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn X509_REQ_new , +.Fn X509_REQ_dup , +.Fn X509_to_X509_REQ , +and +.Fn X509_REQ_INFO_new +return the new +.Vt X509_REQ +or +.Vt X509_REQ_INFO +object, respectively, or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_X509_REQ 3 , +.Xr PEM_read_X509_REQ 3 , +.Xr X509_new 3 , +.Xr X509_REQ_add1_attr 3 , +.Xr X509_REQ_add_extensions 3 , +.Xr X509_REQ_check_private_key 3 , +.Xr X509_REQ_digest 3 , +.Xr X509_REQ_get0_signature 3 , +.Xr X509_REQ_get_pubkey 3 , +.Xr X509_REQ_get_subject_name 3 , +.Xr X509_REQ_get_version 3 , +.Xr X509_REQ_print_ex 3 , +.Xr X509_REQ_sign 3 +.Sh STANDARDS +RFC 2986: PKCS #10: Certification Request Syntax Specification +.Sh HISTORY +.Fn X509_REQ_new , +.Fn X509_REQ_free , +.Fn X509_REQ_INFO_new , +and +.Fn X509_REQ_INFO_free +first appeared in SSLeay 0.4.4, +.Fn X509_REQ_dup +in SSLeay 0.5.1, and +.Fn X509_to_X509_REQ +in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_REQ_print_ex.3 b/Libraries/libressl/man/X509_REQ_print_ex.3 new file mode 100644 index 000000000..b8fb690cc --- /dev/null +++ b/Libraries/libressl/man/X509_REQ_print_ex.3 @@ -0,0 +1,175 @@ +.\" $OpenBSD: X509_REQ_print_ex.3,v 1.2 2021/11/19 15:50:46 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 19 2021 $ +.Dt X509_REQ_PRINT_EX 3 +.Os +.Sh NAME +.Nm X509_REQ_print_ex , +.Nm X509_REQ_print , +.Nm X509_REQ_print_fp +.Nd pretty-print a PKCS#10 certification request +.Sh SYNOPSIS +.Ft int +.Fo X509_REQ_print_ex +.Fa "BIO *bio" +.Fa "X509_REQ *req" +.Fa "unsigned long nameflags" +.Fa "unsigned long skipflags" +.Fc +.Ft int +.Fo X509_REQ_print +.Fa "BIO *bio" +.Fa "X509_REQ *req" +.Fc +.Ft int +.Fo X509_REQ_print_fp +.Fa "FILE *fp" +.Fa "X509_REQ *req" +.Fc +.Sh DESCRIPTION +.Fn X509_REQ_print_ex +prints information contained in +.Fa req +to +.Fa bio +in human-readable form. +Printing is aborted as soon as any operation fails, with the exception +that failures while attempting to decode or print the public key +are not considered as errors. +.Pp +By default, the following blocks of information +are printed in the following order. +Each block can be skipped by setting the corresponding bit in +.Fa skipflags , +provided in parentheses after each block description. +.Bl -bullet +.It +A pair of lines reading +.Qq Certificate Request:\& +and +.Qq Data:\& +containing no information. +.Pq Dv X509_FLAG_NO_HEADER +.It +The value contained in the version field +in decimal and hexadecimal notation. +.Pq Dv X509_FLAG_NO_VERSION +.It +The subject name is printed with +.Xr X509_NAME_print_ex 3 . +.Pq Dv X509_FLAG_NO_SUBJECT +.It +The public key algorithm is printed with +.Xr i2a_ASN1_OBJECT 3 , +and the public key returned from +.Xr X509_REQ_get_pubkey 3 +with +.Xr EVP_PKEY_print_public 3 . +.Pq Dv X509_FLAG_NO_PUBKEY +.It +For each X.501 attribute that is not a requested extension according to +.Xr X509_REQ_extension_nid 3 , +the object identifier is printed with +.Xr i2a_ASN1_OBJECT 3 , +and all values of the types +.Dv V_ASN1_PRINTABLESTRING , +.Dv V_ASN1_T61STRING , +and +.Dv V_ASN1_IA5STRING +are printed with +.Xr BIO_write 3 . +.Pq Dv X509_FLAG_NO_ATTRIBUTES +.It +The requested extensions are retrieved with +.Xr X509_REQ_get_extensions 3 +and their types and values are printed with +.Xr i2a_ASN1_OBJECT 3 +and +.Xr X509V3_EXT_print 3 , +or, if the latter fails, with +.Xr ASN1_STRING_print 3 . +.Pq Dv X509_FLAG_NO_EXTENSIONS +.It +The signature is printed with +.Xr X509_signature_print 3 . +.Pq Dv X509_FLAG_NO_SIGDUMP +.El +.Pp +The +.Fa nameflags +argument modifies the format for printing X.501 +.Vt Name +objects contained in +.Fa req . +It is passed through to +.Xr X509_NAME_print_ex 3 . +If +.Fa nameflags +is +.Dv X509_FLAG_COMPAT , +the +.Fa indent +argument of +.Xr X509_NAME_print_ex 3 +is set to 16 spaces and the traditional SSLeay format generated by +.Xr X509_NAME_print 3 +is used. +Otherwise, if the only bit set in +.Dv XN_FLAG_SEP_MASK +is +.Dv XN_FLAG_SEP_MULTILINE , +.Fa indent +is set to 12 spaces. +Otherwise, indent is set to zero. +.Pp +.Fn X509_REQ_print +is a wrapper function setting the +.Fa nameflags +to +.Dv XN_FLAG_COMPAT +and the +.Fa skipflags +to +.Dv X509_FLAG_COMPAT . +.Pp +.Fn X509_REQ_print_fp +is similar to +.Fn X509_REQ_print +except that it prints to +.Fa fp . +.Sh RETURN VALUES +These functions return 1 if all requested information was successfully +printed, even if failures occurred while attempting to decode or +print the public key, or 0 if any operation fails. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr X509_print_ex 3 , +.Xr X509_REQ_new 3 +.Sh HISTORY +.Fn X509_REQ_print +first appeared in SSLeay 0.4.4 and +.Fn X509_REQ_print_fp +in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_REQ_print_ex +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Sh BUGS +Some printing failures are silently ignored while printing extensions, +which may result in incomplete data being printed. diff --git a/Libraries/libressl/man/X509_REVOKED_new.3 b/Libraries/libressl/man/X509_REVOKED_new.3 new file mode 100644 index 000000000..c1a50d1c9 --- /dev/null +++ b/Libraries/libressl/man/X509_REVOKED_new.3 @@ -0,0 +1,213 @@ +.\" $OpenBSD: X509_REVOKED_new.3,v 1.12 2021/07/19 13:16:43 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL man3/X509_CRL_get0_by_serial cdd6c8c5 Mar 20 12:29:37 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 19 2021 $ +.Dt X509_REVOKED_NEW 3 +.Os +.Sh NAME +.Nm X509_REVOKED_new , +.Nm X509_REVOKED_dup , +.Nm X509_REVOKED_free , +.Nm X509_REVOKED_get0_serialNumber , +.Nm X509_REVOKED_get0_revocationDate , +.Nm X509_REVOKED_set_serialNumber , +.Nm X509_REVOKED_set_revocationDate +.Nd create, change, and inspect an X.509 CRL revoked entry +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_REVOKED * +.Fn X509_REVOKED_new void +.Ft X509_REVOKED * +.Fo X509_REVOKED_dup +.Fa "X509_REVOKED *r" +.Fc +.Ft void +.Fn X509_REVOKED_free "X509_REVOKED *r" +.Ft const ASN1_INTEGER * +.Fo X509_REVOKED_get0_serialNumber +.Fa "const X509_REVOKED *r" +.Fc +.Ft const ASN1_TIME * +.Fo X509_REVOKED_get0_revocationDate +.Fa "const X509_REVOKED *r" +.Fc +.Ft int +.Fo X509_REVOKED_set_serialNumber +.Fa "X509_REVOKED *r" +.Fa "ASN1_INTEGER *serial" +.Fc +.Ft int +.Fo X509_REVOKED_set_revocationDate +.Fa "X509_REVOKED *r" +.Fa "ASN1_TIME *tm" +.Fc +.Sh DESCRIPTION +.Fn X509_REVOKED_new +allocates and initializes an empty +.Vt X509_REVOKED +object, representing one of the elements of +the revokedCertificates field of the ASN.1 +.Vt TBSCertList +structure defined in RFC 5280 section 5.1. +It is used by +.Vt X509_CRL +objects and can hold information about one revoked certificate +including issuer names, serial number, revocation date, and revocation +reason. +.Pp +.Fn X509_REVOKED_dup +creates a deep copy of +.Fa r . +.Pp +.Fn X509_REVOKED_free +frees +.Fa r . +.Pp +.Fn X509_REVOKED_set_serialNumber +sets the serial number of +.Fa r +to +.Fa serial . +The supplied +.Fa serial +pointer is not used internally so it should be freed up after use. +.Pp +.Fn X509_REVOKED_set_revocationDate +sets the revocation date of +.Fa r +to +.Fa tm . +The supplied +.Fa tm +pointer is not used internally so it should be freed up after use. +.Sh RETURN VALUES +The +.Fn X509_REVOKED_new +function returns the new +.Vt X509_REVOKED +object if successful; otherwise +.Dv NULL +is returned and an error code can be retrieved with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_REVOKED_dup +return the new +.Vt X509_REVOKED +object or +.Dv NULL +if an error occurs. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Pp +.Fn X509_REVOKED_get0_serialNumber +returns an internal pointer to the serial number of +.Fa r . +.Pp +.Fn X509_REVOKED_get0_revocationDate +returns an internal pointer to the revocation date of +.Fa r . +.Pp +.Fn X509_REVOKED_set_serialNumber +and +.Fn X509_REVOKED_set_revocationDate +return 1 for success or 0 for failure. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_X509_CRL 3 , +.Xr PEM_read_X509_CRL 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_CRL_print 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_REVOKED_get_ext 3 , +.Xr X509_REVOKED_get_ext_d2i 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, section 5.1: CRL Fields +.Sh HISTORY +.Fn X509_REVOKED_new +and +.Fn X509_REVOKED_free +first appeared in SSLeay 0.4.4 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_REVOKED_set_serialNumber +and +.Fn X509_REVOKED_set_revocationDate +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn X509_REVOKED_dup +first appeared in OpenSSL 1.0.2. +.Fn X509_REVOKED_get0_serialNumber +and +.Fn X509_REVOKED_get0_revocationDate +first appeared in OpenSSL 1.1.0. +These functions have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_SIG_get0.3 b/Libraries/libressl/man/X509_SIG_get0.3 new file mode 100644 index 000000000..456261ca3 --- /dev/null +++ b/Libraries/libressl/man/X509_SIG_get0.3 @@ -0,0 +1,90 @@ +.\" $OpenBSD: X509_SIG_get0.3,v 1.1 2021/10/23 15:39:06 tb Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 23 2021 $ +.Dt X509_SIG_GET0 3 +.Os +.Sh NAME +.Nm X509_SIG_get0 , +.Nm X509_SIG_getm +.Nd DigestInfo functions +.Sh SYNOPSIS +.In openssl/x509.h +.Ft void +.Fo X509_SIG_get0 +.Fa "const X509_SIG *sig" +.Fa "const X509_ALGOR **palg" +.Fa "const ASN1_OCTET_STRING **pdigest" +.Fc +.Ft void +.Fo X509_SIG_getm +.Fa "X509_SIG *sig" +.Fa "X509_ALGOR **palg" +.Fa "ASN1_OCTET_STRING **pdigest" +.Fc +.Sh DESCRIPTION +.Fn X509_SIG_get0 +returns pointers to the algorithm identifier and digest value in +.Fa sig . +.Fn X509_SIG_getm +is identical to +.Fn X509_SIG_get0 , +except the pointers returned are not constant and can be modified, +for example to initialise them. +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr X509_SIG_new 3 +.Sh HISTORY +.Fn X509_SIG_get0 +and +.Fn X509_SIG_getm +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509_SIG_new.3 b/Libraries/libressl/man/X509_SIG_new.3 new file mode 100644 index 000000000..8e6b29dea --- /dev/null +++ b/Libraries/libressl/man/X509_SIG_new.3 @@ -0,0 +1,68 @@ +.\" $OpenBSD: X509_SIG_new.3,v 1.5 2021/10/27 11:24:47 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 27 2021 $ +.Dt X509_SIG_NEW 3 +.Os +.Sh NAME +.Nm X509_SIG_new , +.Nm X509_SIG_free +.Nd PKCS#7 digest information +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_SIG * +.Fn X509_SIG_new void +.Ft void +.Fn X509_SIG_free "X509_SIG *sig" +.Sh DESCRIPTION +.Fn X509_SIG_new +allocates and initializes an empty +.Vt X509_SIG +object, representing an ASN.1 +.Vt DigestInfo +structure defined in RFC 2315 section 9.4 +and equivalently in RFC 8017 section 9.2. +It can hold a message digest together with information about +the algorithm used. +.Pp +.Fn X509_SIG_free +frees +.Fa sig . +.Sh RETURN VALUES +.Fn X509_SIG_new +returns the new +.Vt X509_SIG +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr d2i_X509_SIG 3 , +.Xr PEM_read_PKCS8 3 , +.Xr RSA_sign 3 , +.Xr X509_new 3 , +.Xr X509_SIG_get0 3 +.Sh STANDARDS +RFC 2315: PKCS #7: Cryptographic Message Syntax, +section 9: Signed-data content type +.Pp +RFC 8017: PKCS #1: RSA Cryptography Specifications, +section 9: Encoding Methods for Signatures +.Sh HISTORY +.Fn X509_SIG_new +and +.Fn X509_SIG_free +appeared in SSLeay 0.4 or earlier and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_STORE_CTX_get_error.3 b/Libraries/libressl/man/X509_STORE_CTX_get_error.3 new file mode 100644 index 000000000..1f221563c --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_CTX_get_error.3 @@ -0,0 +1,591 @@ +.\" $OpenBSD: X509_STORE_CTX_get_error.3,v 1.28 2023/06/06 16:20:13 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL man3/X509_STORE_CTX_get_error 24a535ea Sep 22 13:14:20 2020 +0100 +.\" OpenSSL man3/X509_STORE_CTX_new 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Rich Salz . +.\" Copyright (c) 2009, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2023 $ +.Dt X509_STORE_CTX_GET_ERROR 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_get_error , +.Nm X509_STORE_CTX_set_error , +.Nm X509_STORE_CTX_get_error_depth , +.Nm X509_STORE_CTX_set_error_depth , +.Nm X509_STORE_CTX_get_current_cert , +.Nm X509_STORE_CTX_set_current_cert , +.Nm X509_STORE_CTX_get0_current_issuer , +.Nm X509_STORE_CTX_get0_current_crl , +.Nm X509_STORE_CTX_get0_parent_ctx , +.Nm X509_STORE_CTX_get_num_untrusted , +.Nm X509_STORE_CTX_get0_chain , +.Nm X509_STORE_CTX_get_chain , +.Nm X509_STORE_CTX_get1_chain , +.Nm X509_STORE_CTX_set0_verified_chain , +.Nm X509_verify_cert_error_string +.Nd get or set certificate verification status information +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft int +.Fo X509_STORE_CTX_get_error +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_error +.Fa "X509_STORE_CTX *ctx" +.Fa "int s" +.Fc +.Ft int +.Fo X509_STORE_CTX_get_error_depth +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_error_depth +.Fa "X509_STORE_CTX *ctx" +.Fa "int depth" +.Fc +.Ft X509 * +.Fo X509_STORE_CTX_get_current_cert +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_current_cert +.Fa "X509_STORE_CTX *ctx" +.Fa "X509 *cert" +.Fc +.Ft X509 * +.Fo X509_STORE_CTX_get0_current_issuer +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft X509_CRL * +.Fo X509_STORE_CTX_get0_current_crl +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft X509_STORE_CTX * +.Fo X509_STORE_CTX_get0_parent_ctx +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft int +.Fo X509_STORE_CTX_get_num_untrusted +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_STORE_CTX_get0_chain +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_STORE_CTX_get_chain +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_STORE_CTX_get1_chain +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set0_verified_chain +.Fa "X509_STORE_CTX *ctx" +.Fa "STACK_OF(X509) *chain" +.Fc +.In openssl/x509.h +.Ft const char * +.Fo X509_verify_cert_error_string +.Fa "long n" +.Fc +.Sh DESCRIPTION +Most of these functions are typically called after +.Xr X509_verify_cert 3 +to inspect status information related to certificate verification. +Some may also be called in a verification callback to determine the +nature of an error. +.Pp +.Fn X509_STORE_CTX_get_error +returns the error code of +.Fa ctx . +See the +.Sy ERROR CODES +section for a full description of all error codes. +.Pp +.Fn X509_STORE_CTX_set_error +sets the error code of +.Fa ctx +to +.Fa s . +For example it might be used in a verification callback to set an error +based on additional checks. +.Pp +.Fn X509_STORE_CTX_get_error_depth +returns the depth of the error. +This is a non-negative integer representing where in the certificate +chain the error occurred. +If it is zero, it occurred in the end entity certificate, one if it is +the certificate which signed the end entity certificate, and so on. +.Pp +.Fn X509_STORE_CTX_set_error_depth +sets the error depth. +This can be used in combination with +.Fn X509_STORE_CTX_set_error +to set the depth at which an error condition was detected. +.Pp +.Fn X509_STORE_CTX_get_current_cert +returns the certificate in +.Fa ctx +which caused the error or +.Dv NULL +if no certificate is relevant. +.Pp +.Fn X509_STORE_CTX_set_current_cert +sets the certificate which caused the error in +.Fa ctx +to the given +.Fa cert . +This value is not intended to remain valid for very long, +and remains owned by the caller. +It may be examined by a verification callback invoked to handle +each error encountered during chain verification and is no longer +required after such a callback. +If a callback wishes the save the certificate for use after it returns, +it needs to increment its reference count via +.Xr X509_up_ref 3 . +Once such a saved certificate is no longer needed, it can be freed with +.Xr X509_free 3 . +.Pp +.Fn X509_STORE_CTX_get0_current_issuer +returns the certificate that caused issuer validation to fail or +.Dv NULL +if no CA certificate is relevant. +.Pp +.Fn X509_STORE_CTX_get0_current_crl +returns the certificate revocation list that caused CRL checking to fail or +.Dv NULL +if no CRL is relevant. +.Pp +When, during certification path validation, the need arises to check +the validity of the certification path of a CRL issuer certificate, +the library creates a new, temporary +.Vt X509_STORE_CTX +object. +If +.Fn X509_STORE_CTX_get0_parent_ctx +is called on that temporary object, a pointer to the original +certification path validation context is returned. +This may be useful in callback functions called from +.Xr X509_verify_cert 3 +or from its subroutines to find out whether the callback is called +from the path validation of the target certificate or from the path +validation of a related CRL issuer certificate, and if the latter, +what the target certificate is. +.Pp +.Fn X509_STORE_CTX_get0_chain +returns an internal pointer to a complete validate chain +if a previous call to +.Xr X509_verify_cert 3 +was successful. +If the call to +.Xr X509_verify_cert 3 +was not successful, the returned chain may be incomplete or invalid. +.Fn X509_STORE_CTX_get_chain +is a deprecated alias of +.Fn X509_STORE_CTX_get0_chain . +.Fn X509_STORE_CTX_get1_chain +returns a deep copy of the same chain which persists even after the +.Fa ctx +structure is freed. +When it is no longer needed, it should be freed using +.Fn sk_X509_pop_free chain X509_free . +.Pp +.Fn X509_STORE_CTX_set0_verified_chain +frees the validate chain generated by if a previous call to +.Xr X509_verify_cert 3 , +if any, and replaces it with the given +.Fa chain . +Ownership of the +.Fa chain +is transferred to the +.Fa ctx , +so it should not be freed by the caller. +.Pp +.Fn X509_verify_cert_error_string +returns a human readable error string for verification error +.Fa n . +.Pp +The above functions should be used instead of directly referencing the +fields in the +.Sy X509_VERIFY_CTX +structure. +.Pp +In versions of OpenSSL before 1.0, the current certificate returned by +.Fn X509_STORE_CTX_get_current_cert +was never +.Dv NULL . +Applications should check the return value before printing out any +debugging information relating to the current certificate. +.Pp +If an unrecognised error code is passed to +.Fn X509_verify_cert_error_string , +"Unknown certificate verification error" +is returned. +This should never happen unless an invalid code is passed. +.Sh RETURN VALUES +.Fn X509_STORE_CTX_get_error +returns +.Dv X509_V_OK +or an error code. +.Pp +.Fn X509_STORE_CTX_get_error_depth +returns a non-negative error depth. +.Pp +.Fn X509_STORE_CTX_get_current_cert , +.Fn X509_STORE_CTX_get0_current_issuer , +and +.Fn X509_STORE_CTX_get0_current_crl +return the object which caused the error or +.Dv NULL +if no object of the requested kind is relevant to the error. +.Pp +.Fn X509_STORE_CTX_get0_parent_ctx +returns the parent context or +.Dv NULL +if +.Fa ctx +is not a temporary child context +used for path validation of a CRL issuer certificate. +.Pp +.Fn X509_STORE_CTX_get_num_untrusted +returns the number of untrusted certificates +that were used in building the chain during a call to +.Xr X509_verify_cert 3 . +.Pp +.Fn X509_STORE_CTX_get0_chain , +.Fn X509_STORE_CTX_get_chain , +and +.Fn X509_STORE_CTX_get1_chain +return a pointer to a stack of certificates or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_verify_cert_error_string +returns a human readable error string for verification error +.Fa n . +.Sh ERROR CODES +A list of error codes and messages is shown below. +Some of the error codes are defined but currently never returned: +these are described as "unused". +.Bl -tag -width Ds +.It Dv X509_V_OK : No ok +The operation was successful. +.It Dv X509_V_ERR_UNSPECIFIED : \ + No Unspecified certificate verification error +An error was encountered during certificate verification and +the internal routines failed to set a more specific error. +.It Dv X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT : \ + No unable to get issuer certificate +The issuer certificate of a locally looked up certificate could not be found. +This normally means the list of trusted certificates is not complete. +.It Dv X509_V_ERR_UNABLE_TO_GET_CRL : No unable to get certificate CRL +The CRL of a certificate could not be found. +.It Dv X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE : \ + No unable to decrypt certificate's signature +The certificate signature could not be decrypted. +This means that the actual signature value could not be determined +rather than it not matching the expected value. +This is only meaningful for RSA keys. +.It Dv X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE : \ + No unable to decrypt CRL's signature +The CRL signature could not be decrypted: this means that the actual +signature value could not be determined rather than it not matching the +expected value. +Unused. +.It Dv X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY : \ + No unable to decode issuer public key +The public key in the certificate +.Vt SubjectPublicKeyInfo +could not be read. +.It Dv X509_V_ERR_CERT_SIGNATURE_FAILURE : No certificate signature failure +The signature of the certificate is invalid. +.It Dv X509_V_ERR_CRL_SIGNATURE_FAILURE : No CRL signature failure +The signature of the CRL is invalid. +.It Dv X509_V_ERR_CERT_NOT_YET_VALID : No certificate is not yet valid +The certificate is not yet valid: the notBefore date is after the +current time. +.It Dv X509_V_ERR_CERT_HAS_EXPIRED : No certificate has expired +The certificate has expired: that is the notAfter date is before the +current time. +.It Dv X509_V_ERR_CRL_NOT_YET_VALID : No CRL is not yet valid +The CRL is not yet valid. +.It Dv X509_V_ERR_CRL_HAS_EXPIRED : No CRL has expired +The CRL has expired. +.It Dv X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD : \ + No format error in certificate's notBefore field +The certificate notBefore field contains an invalid time. +.It Dv X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD : \ + No format error in certificate's notAfter field +The certificate notAfter field contains an invalid time. +.It Dv X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD : \ + No format error in CRL's lastUpdate field +The CRL thisUpdate field (sic!) contains an invalid time. +Both the name of the error constant and the text of the error message +give a wrong name for the field that contains the problem. +.It Dv X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD : \ + No format error in CRL's nextUpdate field +The CRL nextUpdate field contains an invalid time. +.It Dv X509_V_ERR_OUT_OF_MEM : No out of memory +An error occurred trying to allocate memory. +This should never happen. +.It Dv X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT : No self signed certificate +The passed certificate is self signed and the same certificate cannot be +found in the list of trusted certificates. +.It Dv X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN : \ + No self signed certificate in certificate chain +The certificate chain could be built up using the untrusted certificates +but the root could not be found locally. +.It Dv X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY : \ + No unable to get local issuer certificate +The issuer certificate could not be found: this occurs if the issuer +certificate of an untrusted certificate cannot be found. +.It Dv X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE : \ + No unable to verify the first certificate +No signatures could be verified because the chain contains only one +certificate and it is not self signed. +.It Dv X509_V_ERR_CERT_CHAIN_TOO_LONG : No certificate chain too long +The certificate chain length is greater than the supplied maximum depth. +.It Dv X509_V_ERR_CERT_REVOKED : No certificate revoked +The certificate has been revoked. +.It Dv X509_V_ERR_INVALID_CA : No invalid CA certificate +A CA certificate is invalid. +Either it is not a CA or its extensions are not consistent with the +supplied purpose. +.It Dv X509_V_ERR_PATH_LENGTH_EXCEEDED : No path length constraint exceeded +The basicConstraints path-length parameter has been exceeded. +.It Dv X509_V_ERR_INVALID_PURPOSE : No unsupported certificate purpose +The supplied certificate cannot be used for the specified purpose. +.It Dv X509_V_ERR_CERT_UNTRUSTED : No certificate not trusted +The root CA is not marked as trusted for the specified purpose. +.It Dv X509_V_ERR_CERT_REJECTED : No certificate rejected +The root CA is marked to reject the specified purpose. +.It Dv X509_V_ERR_SUBJECT_ISSUER_MISMATCH : No subject issuer mismatch +The current candidate issuer certificate was rejected because its +subject name did not match the issuer name of the current certificate. +This is only set if issuer check debugging is enabled; it is used for +status notification and is +.Sy not +in itself an error. +.It Dv X509_V_ERR_AKID_SKID_MISMATCH : \ + No authority and subject key identifier mismatch +The current candidate issuer certificate was rejected because its +subject key identifier was present and did not match the authority key +identifier current certificate. +This is only set if issuer check debugging is enabled; it is used for +status notification and is +.Sy not +in itself an error. +.It Dv X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH : \ + No authority and issuer serial number mismatch +The current candidate issuer certificate was rejected because its issuer +name and serial number was present and did not match the authority key +identifier of the current certificate. +This is only set if issuer check debugging is enabled; it is used for +status notification and is +.Sy not +in itself an error. +.It Dv X509_V_ERR_KEYUSAGE_NO_CERTSIGN : \ + No key usage does not include certificate signing +The current candidate issuer certificate was rejected because its +keyUsage extension does not permit certificate signing. +This is only set if issuer check debugging is enabled it is used for +status notification and is +.Sy not +in itself an error. +.It Dv X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER : \ + No unable to get CRL issuer certificate +The CRL's issuer could not be found: +there is no alternative CRL issuer set on +.Ar ctx +and the last certificate in the chain is not self signed. +.It Dv X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION : \ + No unhandled critical extension +The certificate contains a critical extension that is unsupported +by the library. +.It Dv X509_V_ERR_KEYUSAGE_NO_CRL_SIGN : \ + No key usage does not include CRL signing +The CRL issuer has a key usage extension with unset cRLSign bit. +.It Dv X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION : \ + No unhandled critical CRL extension +The CRL contains a critical extension that is unsupported +by the library. +.\" XXX - The following are unreachable (X509_V_ERR_INVALID_NON_CA) or unused. +.\" .It Dv X509_V_ERR_INVALID_NON_CA : \ +.\" No invalid non-CA certificate (has CA markings) +.\" .It Dv X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED : \ +.\" No proxy path length constraint exceeded +.\" .It Dv X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE : \ +.\" No key usage does not include digital signature +.\" .It Dv X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED : \ +.\" No proxy certificates not allowed, please set the appropriate flag +.It Dv X509_V_ERR_INVALID_EXTENSION : \ + No invalid or inconsistent certificate extension +A certificate extension had an invalid value (for example an incorrect +encoding) or some value inconsistent with other extensions. +.It Dv X509_V_ERR_INVALID_POLICY_EXTENSION : \ + No invalid or inconsistent certificate policy extension +A certificate policies extension had an invalid value (for example an +incorrect encoding) or some value inconsistent with other extensions. +This error only occurs if policy processing is enabled. +.It Dv X509_V_ERR_NO_EXPLICIT_POLICY : No no explicit policy +The verification flags were set to require an explicit policy but none +was present. +.It Dv X509_V_ERR_DIFFERENT_CRL_SCOPE : No different CRL scope +The only CRLs that could be found did not match the scope of the +certificate. +.It Dv X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE : \ + No unsupported extension feature +Some feature of a certificate extension is not supported. +Unused. +.It Dv X509_V_ERR_UNNESTED_RESOURCE : \ + No RFC 3779 resource not subset of parent's resources +When walking up a certificate chain, all resources specified in +RFC 3779 extensions must be contained in the resources delegated in +the issuer's RFC 3779 extensions. +The error indicates that this is not the case or that the trust anchor +has inheritance. +.It Dv X509_V_ERR_PERMITTED_VIOLATION : No permitted subtree violation +A name constraint violation occurred in the permitted subtrees. +.It Dv X509_V_ERR_EXCLUDED_VIOLATION : No excluded subtree violation +A name constraint violation occurred in the excluded subtrees. +.It Dv X509_V_ERR_SUBTREE_MINMAX : \ + No name constraints minimum and maximum not supported +A certificate name constraints extension included a minimum or maximum +field: this is not supported. +.It Dv X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE : \ + No unsupported name constraint type +An unsupported name constraint type was encountered. +OpenSSL currently only supports directory name, DNS name, email and URI +types. +.It Dv X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX : \ + No unsupported or invalid name constraint syntax +The format of the name constraint is not recognised: for example an +email address format of a form not mentioned in RFC 3280. +This could be caused by a garbage extension or some new feature not +currently supported. +.\" X509_V_ERR_UNSUPPORTED_NAME_SYNTAX : No unsupported or invalid name syntax +.It Dv X509_V_ERR_CRL_PATH_VALIDATION_ERROR : No CRL path validation error +An error occurred when attempting to verify the CRL path. +This error can only happen if extended CRL checking is enabled. +.It Dv X509_V_ERR_APPLICATION_VERIFICATION : \ + No application verification failure +An application specific error. +This will never be returned unless explicitly set by an application. +.\" .It Dv X509_V_ERR_HOSTNAME_MISMATCH : No Hostname mismatch +.\" .It Dv X509_V_ERR_EMAIL_MISMATCH : No Email address mismatch +.\" .It Dv X509_V_ERR_IP_ADDRESS_MISMATCH : No IP address mismatch +.\" .It Dv X509_V_ERR_INVALID_CALL : \ +.\" No Invalid certificate verification context +.\" .It Dv X509_V_ERR_STORE_LOOKUP : No Issuer certificate lookup error +.\" .It Dv X509_V_ERR_EE_KEY_TOO_SMALL : No EE certificate key too weak +.\" .It Dv X509_V_ERR_CA_KEY_TOO_SMALL : No CA certificate key too weak +.\" .It Dv X509_V_ERR_CA_MD_TOO_WEAK : \ +.\" No CA signature digest algorithm too weak +.El +.Sh SEE ALSO +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_CTX_set_verify 3 , +.Xr X509_STORE_CTX_set_verify_cb 3 , +.Xr X509_STORE_set_verify_cb 3 , +.Xr X509_up_ref 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_STORE_CTX_get_error , +.Fn X509_STORE_CTX_set_error , +.Fn X509_STORE_CTX_get_error_depth , +.Fn X509_STORE_CTX_get_current_cert , +.Fn X509_STORE_CTX_get_chain , +and +.Fn X509_verify_cert_error_string +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_CTX_get1_chain +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn X509_STORE_CTX_get0_current_issuer , +.Fn X509_STORE_CTX_get0_current_crl , +and +.Fn X509_STORE_CTX_get0_parent_ctx +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn X509_STORE_CTX_get0_chain +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Pp +.Fn X509_STORE_CTX_set_error_depth , +.Fn X509_STORE_CTX_set_current_cert , +.Fn X509_STORE_CTX_get_num_untrusted , +and +.Fn X509_STORE_CTX_set0_verified_chain +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509_STORE_CTX_get_ex_new_index.3 b/Libraries/libressl/man/X509_STORE_CTX_get_ex_new_index.3 new file mode 100644 index 000000000..bfec65a12 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_CTX_get_ex_new_index.3 @@ -0,0 +1,153 @@ +.\" $OpenBSD: X509_STORE_CTX_get_ex_new_index.3,v 1.6 2021/07/29 08:32:13 schwarze Exp $ +.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2009, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 29 2021 $ +.Dt X509_STORE_CTX_GET_EX_NEW_INDEX 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_get_ex_new_index , +.Nm X509_STORE_CTX_set_ex_data , +.Nm X509_STORE_CTX_get_ex_data , +.Nm X509_STORE_CTX_set_app_data , +.Nm X509_STORE_CTX_get_app_data +.Nd add application specific data to X509_STORE_CTX structures +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft int +.Fo X509_STORE_CTX_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fo X509_STORE_CTX_set_ex_data +.Fa "X509_STORE_CTX *d" +.Fa "int idx" +.Fa "void *arg" +.Fc +.Ft void * +.Fo X509_STORE_CTX_get_ex_data +.Fa "X509_STORE_CTX *d" +.Fa "int idx" +.Fc +.Ft int +.Fo X509_STORE_CTX_set_app_data +.Fa "X509_STORE_CTX *d" +.Fa "void *arg" +.Fc +.Ft void * +.Fo X509_STORE_CTX_get_app_data +.Fa "X509_STORE_CTX *d" +.Fc +.Sh DESCRIPTION +These functions handle application specific data in +.Vt X509_STORE_CTX +structures. +Their usage is identical to that of +.Xr RSA_get_ex_new_index 3 , +.Xr RSA_set_ex_data 3 , +and +.Xr RSA_get_ex_data 3 . +.Pp +This mechanism is used internally by the +.Xr ssl 3 +library to store the +.Vt SSL +structure associated with a verification operation in an +.Vt X509_STORE_CTX +structure. +.Pp +.Fn X509_STORE_CTX_set_app_data +and +.Fn X509_STORE_CTX_get_app_data +are macros calling +.Fn X509_STORE_CTX_set_ex_data +and +.Fn X509_STORE_CTX_get_ex_data , +respectively, with an +.Fa idx +of 0. +.Sh RETURN VALUES +.Fn X509_STORE_CTX_get_ex_new_index +returns a new index or \-1 on failure. +.Pp +.Fn X509_STORE_CTX_set_ex_data +and +.Fn X509_STORE_CTX_set_app_data +return 1 on success or 0 on failure. +.Pp +.Fn X509_STORE_CTX_get_ex_data +and +.Fn X509_STORE_CTX_get_app_data +return the application data or +.Dv NULL +on failure. +.Dv NULL +may also be valid application data, but currently these functions +can only fail if given an invalid +.Fa idx +argument. +.Sh SEE ALSO +.Xr RSA_get_ex_new_index 3 , +.Xr X509_STORE_CTX_new 3 +.Sh HISTORY +.Fn X509_STORE_CTX_set_app_data +and +.Fn X509_STORE_CTX_get_app_data +first appeared in SSLeay 0.8.0 and +.Fn X509_STORE_CTX_get_ex_new_index , +.Fn X509_STORE_CTX_set_ex_data , +and +.Fn X509_STORE_CTX_get_ex_data +in SSLeay 0.9.0. +All these functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_STORE_CTX_new.3 b/Libraries/libressl/man/X509_STORE_CTX_new.3 new file mode 100644 index 000000000..96af7a8af --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_CTX_new.3 @@ -0,0 +1,365 @@ +.\" $OpenBSD: X509_STORE_CTX_new.3,v 1.27 2022/11/16 14:55:40 schwarze Exp $ +.\" full merge up to: OpenSSL aae41f8c Jun 25 09:47:15 2015 +0100 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Rich Salz . +.\" Copyright (c) 2009, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 16 2022 $ +.Dt X509_STORE_CTX_NEW 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_new , +.Nm X509_STORE_CTX_init , +.Nm X509_STORE_CTX_cleanup , +.Nm X509_STORE_CTX_free , +.Nm X509_STORE_CTX_get0_store , +.Nm X509_STORE_CTX_set0_trusted_stack , +.Nm X509_STORE_CTX_trusted_stack , +.Nm X509_STORE_CTX_set_cert , +.Nm X509_STORE_CTX_get0_cert , +.\" X509_STORE_CTX_get0_chain moved to X509_STORE_CTX_get_error(3) +.Nm X509_STORE_CTX_set_chain , +.Nm X509_STORE_CTX_set0_untrusted , +.Nm X509_STORE_CTX_get0_untrusted , +.Nm X509_STORE_CTX_set0_crls +.\" X509_STORE_CTX_verify_fn moved to X509_STORE_CTX_set_verify(3) +.\" X509_STORE_CTX_set_verify moved to X509_STORE_CTX_set_verify(3) +.Nd X509_STORE_CTX initialisation +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft X509_STORE_CTX * +.Fn X509_STORE_CTX_new void +.Ft int +.Fo X509_STORE_CTX_init +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_STORE *store" +.Fa "X509 *x" +.Fa "STACK_OF(X509) *untrusted" +.Fc +.Ft void +.Fo X509_STORE_CTX_cleanup +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_free +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft X509_STORE * +.Fo X509_STORE_CTX_get0_store +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set0_trusted_stack +.Fa "X509_STORE_CTX *ctx" +.Fa "STACK_OF(X509) *trusted" +.Fc +.Ft void +.Fo X509_STORE_CTX_trusted_stack +.Fa "X509_STORE_CTX *ctx" +.Fa "STACK_OF(X509) *trusted" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_cert +.Fa "X509_STORE_CTX *ctx" +.Fa "X509 *x" +.Fc +.Ft X509 * +.Fo X509_STORE_CTX_get0_cert +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_chain +.Fa "X509_STORE_CTX *ctx" +.Fa "STACK_OF(X509) *untrusted" +.Fc +.Ft void +.Fo X509_STORE_CTX_set0_untrusted +.Fa "X509_STORE_CTX *ctx" +.Fa "STACK_OF(X509) *untrusted" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_STORE_CTX_get0_untrusted +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set0_crls +.Fa "X509_STORE_CTX *ctx" +.Fa "STACK_OF(X509_CRL) *crls" +.Fc +.Sh DESCRIPTION +These functions set up an +.Vt X509_STORE_CTX +object for subsequent use by +.Xr X509_verify_cert 3 . +.Pp +.Fn X509_STORE_CTX_new +allocates an empty +.Vt X509_STORE_CTX +object not yet containing the subobjects required for normal operation. +.Pp +.Fn X509_STORE_CTX_init +needs to be called on each new +.Fa ctx +before any of the other functions become useful. +It prepares +.Fa ctx +for one single verification operation using +.Xr X509_verify_cert 3 . +The trusted certificate +.Fa store +to be used, the end entity certificate +.Fa x +to be verified, and a set of additional +.Fa untrusted +certificates, to be used for building the chain, +can be supplied, or any or all of them can be set to +.Dv NULL . +The three pointers passed in are stored internally, the three objects +pointed to are not copied, their reference count is not incremented, +and the caller remains responsible for managing their storage and for +not freeing them before +.Fn X509_STORE_CTX_free +is called on +.Fa ctx . +If a +.Fa store +is provided, the verification parameters contained in it are copied using +.Xr X509_VERIFY_PARAM_inherit 3 . +.Pp +.Fn X509_STORE_CTX_cleanup +internally cleans up +.Fa ctx , +returning it to an empty state similar to the one after +.Fn X509_STORE_CTX_new . +It can then be reused with a new call to +.Fn X509_STORE_CTX_init . +.Pp +.Fn X509_STORE_CTX_free +calls +.Fn X509_STORE_CTX_cleanup +and frees the storage pointed to by +.Fa ctx . +If +.Fa ctx +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn X509_STORE_CTX_get0_store +returns the internal pointer to the trusted certificate +.Fa store +that was set with +.Fn X509_STORE_CTX_init . +.Pp +.Fn X509_STORE_CTX_set0_trusted_stack +sets the set of +.Fa trusted +certificates used by +.Fa ctx . +This is an alternative way of specifying trusted certificates instead of +using the +.Fa store . +.Fn X509_STORE_CTX_trusted_stack +is a deprecated alias for +.Fn X509_STORE_CTX_set0_trusted_stack . +.Pp +.Fn X509_STORE_CTX_set_cert +sets the certificate to be verified in +.Fa ctx +to +.Fa x , +overriding the certificate that was set with +.Fn X509_STORE_CTX_init . +Again, the certificate is not copied +and its reference count is not incremented. +.Pp +.Fn X509_STORE_CTX_get0_cert +retrieves the internal pointer to the certificate being verified by +.Fa ctx , +i.e. the last one set using either +.Fn X509_STORE_CTX_init +or +.Fn X509_STORE_CTX_set_cert . +.Pp +.Fn X509_STORE_CTX_set_chain +and +.Fn X509_STORE_CTX_set0_untrusted +are identical and set the additional, +.Fa untrusted +certificates used by +.Fa ctx , +overriding the set of additional, untrusted certificates that was set with +.Fn X509_STORE_CTX_init . +Again, the set and the certificates contained in it are not copied +and their reference counts are not incremented. +.Pp +.Fn X509_STORE_CTX_get0_untrusted +retrieves the internal pointer +to the set of additional, untrusted certificates associated with +.Fa ctx , +i.e. the last one set using either +.Fn X509_STORE_CTX_init , +.Fn X509_STORE_CTX_set_chain , +or +.Fn X509_STORE_CTX_set0_untrusted . +.Pp +.Fn X509_STORE_CTX_set0_crls +sets a set of +.Fa crls +to use during certificate verification. +These CRLs will only be used if CRL verification is enabled in the +associated +.Vt X509_VERIFY_PARAM +structure. +This might be used where additional "useful" CRLs are supplied as part +of a protocol, for example in a PKCS#7 structure. +.Pp +Legacy applications might implicitly use an +.Vt X509_STORE_CTX +like this: +.Bd -literal -offset indent +X509_STORE_CTX ctx; +X509_STORE_CTX_init(&ctx, store, cert, chain); +.Ed +.Pp +This is +.Sy not +recommended in new applications. +They should instead do: +.Bd -literal -offset indent +X509_STORE_CTX *ctx; +ctx = X509_STORE_CTX_new(); +if (ctx == NULL) + /* Bad error */ +X509_STORE_CTX_init(ctx, store, cert, chain); +.Ed +.Sh RETURN VALUES +.Fn X509_STORE_CTX_new +returns a newly allocated context or +.Dv NULL +if an error occurred. +.Pp +.Fn X509_STORE_CTX_init +returns 1 for success or 0 if an error occurred. +.Pp +.Fn X509_STORE_CTX_get0_store +returns the internal pointer to the trusted certificate store or +.Dv NULL +if none was set. +.Pp +.Fn X509_STORE_CTX_get0_cert +returns the internal pointer to the certificate to be verified or +.Dv NULL +if no such certificate was set. +.Pp +.Fn X509_STORE_CTX_get0_untrusted +returns the internal pointer +to the set of additional, untrusted certificates or +.Dv NULL +if no set of additional certificates was provided. +.Sh SEE ALSO +.Xr X509_CRL_new 3 , +.Xr X509_STORE_CTX_get_error 3 , +.Xr X509_STORE_CTX_get_ex_new_index 3 , +.Xr X509_STORE_CTX_set_flags 3 , +.Xr X509_STORE_CTX_set_verify 3 , +.Xr X509_STORE_CTX_set_verify_cb 3 , +.Xr X509_STORE_get_by_subject 3 , +.Xr X509_STORE_new 3 , +.Xr X509_STORE_set1_param 3 , +.Xr X509_STORE_set_verify_cb 3 , +.Xr X509_verify_cert 3 , +.Xr X509_VERIFY_PARAM_inherit 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_STORE_CTX_init , +.Fn X509_STORE_CTX_cleanup , +.Fn X509_STORE_CTX_set_cert , +and +.Fn X509_STORE_CTX_set_chain +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_CTX_new +and +.Fn X509_STORE_CTX_free +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn X509_STORE_CTX_trusted_stack +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn X509_STORE_CTX_get0_store +first appeared in OpenSSL 1.0.2. +.Fn X509_STORE_CTX_set0_trusted_stack , +.Fn X509_STORE_CTX_get0_cert , +.Fn X509_STORE_CTX_set0_untrusted , +and +.Fn X509_STORE_CTX_get0_untrusted +first appeared in OpenSSL 1.1.0. +These functions have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_STORE_CTX_set_flags.3 b/Libraries/libressl/man/X509_STORE_CTX_set_flags.3 new file mode 100644 index 000000000..2ac76951f --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_CTX_set_flags.3 @@ -0,0 +1,426 @@ +.\" $OpenBSD: X509_STORE_CTX_set_flags.3,v 1.6 2021/11/17 16:08:32 schwarze Exp $ +.\" full merge up to: OpenSSL aae41f8c Jun 25 09:47:15 2015 +0100 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Claudio Jeker +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2009 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 17 2021 $ +.Dt X509_STORE_CTX_SET_FLAGS 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_set_flags , +.Nm X509_STORE_CTX_set_time , +.Nm X509_STORE_CTX_set_depth , +.Nm X509_STORE_CTX_set_trust , +.Nm X509_STORE_CTX_set_purpose , +.Nm X509_STORE_CTX_purpose_inherit , +.Nm X509_STORE_CTX_get0_param , +.Nm X509_STORE_CTX_set0_param , +.Nm X509_STORE_CTX_set_default +.Nd X509_STORE_CTX parameter initialisation +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft void +.Fo X509_STORE_CTX_set_flags +.Fa "X509_STORE_CTX *ctx" +.Fa "unsigned long flags" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_time +.Fa "X509_STORE_CTX *ctx" +.Fa "unsigned long dummy" +.Fa "time_t time" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_depth +.Fa "X509_STORE_CTX *ctx" +.Fa "int depth" +.Fc +.Ft int +.Fo X509_STORE_CTX_set_trust +.Fa "X509_STORE_CTX *ctx" +.Fa "int trust" +.Fc +.Ft int +.Fo X509_STORE_CTX_set_purpose +.Fa "X509_STORE_CTX *ctx" +.Fa "int purpose" +.Fc +.Ft int +.Fo X509_STORE_CTX_purpose_inherit +.Fa "X509_STORE_CTX *ctx" +.Fa "int def_purpose" +.Fa "int purpose" +.Fa "int trust" +.Fc +.Ft X509_VERIFY_PARAM * +.Fo X509_STORE_CTX_get0_param +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set0_param +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_VERIFY_PARAM *param" +.Fc +.Ft int +.Fo X509_STORE_CTX_set_default +.Fa "X509_STORE_CTX *ctx" +.Fa "const char *name" +.Fc +.Sh DESCRIPTION +These functions operate on the +.Vt X509_VERIFY_PARAM +object used by +.Fa ctx . +Usually, +.Xr X509_STORE_CTX_init 3 +is called on +.Fa ctx +before these functions, and +.Xr X509_verify_cert 3 +afterwards. +.Pp +.Fn X509_STORE_CTX_set_flags +sets the internal verification parameter flags to +.Fa flags . +See +.Xr X509_VERIFY_PARAM_set_flags 3 +for a description of the verification flags. +.Pp +.Fn X509_STORE_CTX_set_time +sets the verification +.Fa time +using +.Xr X509_VERIFY_PARAM_set_time 3 . +The +.Fa dummy +argument is ignored. +.Pp +.Fn X509_STORE_CTX_set_depth +sets the maximum verification +.Fa depth +using +.Xr X509_VERIFY_PARAM_set_depth 3 . +That is the maximum number of untrusted CA certificates +that can appear in a chain. +.Pp +.Fn X509_STORE_CTX_set_trust +sets the +.Fa trust +identifier that can also be set using +.Xr X509_VERIFY_PARAM_set_trust 3 . +If the +.Fa trust +argument is 0 or invalid +or the trust identifier is already set to a non-zero value in the +.Vt X509_VERIFY_PARAM +object, no action occurs. +Here and in the following, +.Dv X509_TRUST_DEFAULT +counts as invalid. +.Pp +.Fn X509_STORE_CTX_set_purpose +sets the +.Fa purpose +identifier that can also be set using +.Xr X509_VERIFY_PARAM_set_purpose 3 . +If the +.Fa purpose +argument is 0 or any failure occurs, nothing is changed. +.Pp +In the following, the trust identifier contained in the +.Vt X509_PURPOSE +object associated with +.Fa purpose +is called the +.Dq associated trust . +.Pp +The function fails if the +.Fa purpose +argument or the associated trust is not 0 but invalid; otherwise, +.Fn X509_STORE_CTX_set_purpose +also does the equivalent of calling +.Fn X509_STORE_CTX_set_trust +with the associated trust. +.Pp +If the purpose identifier is already set to a non-zero value in the +.Vt X509_VERIFY_PARAM +object, it is not changed, even if the +.Fa purpose +argument is valid, too. +.Pp +.Fn X509_STORE_CTX_purpose_inherit +is similar to +.Fn X509_STORE_CTX_set_purpose , +with the following modifications: +.Bl -bullet +.It +If the +.Fa purpose +argument is 0, +.Fa def_purpose +is used instead. +.It +If the associated trust is +.Dv X509_TRUST_DEFAULT , +the trust associated with +.Fa def_purpose +is used instead, or if +.Fa def_purpose +is 0 or invalid, the function fails. +.It +If the +.Fa trust +argument is not 0, it is used instead of the associated trust, +and the equivalent of calling +.Fn X509_STORE_CTX_set_trust +is done even if both +.Fa purpose +and +.Fa def_purpose +are 0. +Even if the +.Fa trust +argument is not 0, if the (then unused) associated trust is +.Dv X509_TRUST_DEFAULT , +.Fa def_purpose +is still required to be valid. +.El +.Pp +Note that, even if all arguments are valid and the return value is 1, +it is possible that nothing changed, or that only either one of the +purpose and trust identifiers were set, or that both were set. +It can also happen that the purpose identifier gets set according to the +.Fa purpose +argument, but the trust identifier gets set according to the +.Fa def_purpose +argument in the same call. +.Pp +The intended way of using this function is to pass the purpose and +trust attributes of another structure of an arbitrary type as the +.Fa purpose +and +.Fa trust +arguments, and to provide +.Fa def_purpose +as a fallback in case the settings in the other structure are incomplete. +.Pp +.Fn X509_STORE_CTX_get0_param +retrieves an internal pointer to the verification parameters associated +with +.Fa ctx . +.Pp +.Fn X509_STORE_CTX_set0_param +sets the internal verification parameter pointer to +.Fa param . +After this call +.Fa param +should not be used. +.Pp +.Fn X509_STORE_CTX_set_default +looks up and sets the default verification method to +.Fa name . +This uses the function +.Xr X509_VERIFY_PARAM_lookup 3 +to find an appropriate set of parameters from +.Fa name +and copies them using +.Xr X509_VERIFY_PARAM_inherit 3 . +.Sh RETURN VALUES +.Fn X509_STORE_CTX_set_trust +returns 1 if the +.Fa trust +argument is 0 or valid or 0 if it is not 0 but invalid. +A return value of 1 does +.Em not +imply that the trust identifier stored in the +.Vt X509_VERIFY_PARAM +object was changed. +.Pp +.Fn X509_STORE_CTX_set_purpose +returns 1 if both the +.Fa purpose +argument and the associated trust are 0 or valid. +It returns 0 if either the +.Fa purpose +argument or the associated trust is not 0 but invalid. +A return value of 1 does not imply that any data was changed. +.Pp +.Fn X509_STORE_CTX_purpose_inherit +returns 0 if: +.Bl -bullet +.It +The +.Fa purpose +argument is not 0 and invalid. +.It +The +.Fa purpose +argument is 0 and the +.Fa def_purpose +argument is not 0 and invalid. +.It +The associated trust is +.Dv X509_TRUST_DEFAULT +and the +.Fa def_purpose +argument is 0 or invalid, +or the trust identifier associated with it is not 0 but invalid. +.It +The +.Fa trust +argument is not 0 and invalid. +.It +The +.Fa trust +argument is 0 and the associated trust is neither 0 nor +.Dv X509_TRUST_DEFAULT +but invalid. +.El +.Pp +Otherwise, +.Fn X509_STORE_CTX_purpose_inherit +returns 1, which does not imply that any data was changed. +.Pp +.Fn X509_STORE_CTX_get0_param +returns a pointer to an +.Vt X509_VERIFY_PARAM +structure or +.Dv NULL +if an error occurred. +.Pp +.Fn X509_STORE_CTX_set_default +returns 1 for success or 0 if an error occurred. +.Sh ERRORS +For +.Fn X509_STORE_CTX_set_trust , +.Fn X509_STORE_CTX_set_purpose , +and +.Fn X509_STORE_CTX_purpose_inherit , +the following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv X509_R_UNKNOWN_TRUST_ID Qq "unknown trust id" +The +.Fa trust +argument or the trust identifier associated with +.Fa purpose +or +.Fa def_purpose +is not 0 but invalid, +.It Dv X509_R_UNKNOWN_PURPOSE_ID Qq "unknown purpose id" +The +.Fa purpose +argument is not 0 and invalid. +Or it is 0 and the +.Fa def_purpose +argument is not 0 and invalid. +Or the associated trust is +.Dv X509_TRUST_DEFAULT +and +.Fa def_purpose +is 0 or invalid. +.El +.Pp +The other functions provide no diagnostics. +.Sh SEE ALSO +.Xr X509_STORE_CTX_get_error 3 , +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_CTX_set_verify 3 , +.Xr X509_STORE_CTX_set_verify_cb 3 , +.Xr X509_STORE_new 3 , +.Xr X509_STORE_set1_param 3 , +.Xr X509_STORE_set_verify_cb 3 , +.Xr X509_verify_cert 3 , +.Xr X509_VERIFY_PARAM_new 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_STORE_CTX_set_depth +first appeared in OpenSSL 0.9.3 and has been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_CTX_set_trust , +.Fn X509_STORE_CTX_set_purpose , +and +.Fn X509_STORE_CTX_purpose_inherit +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn X509_STORE_CTX_set_flags +and +.Fn X509_STORE_CTX_set_time +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn X509_STORE_CTX_get0_param , +.Fn X509_STORE_CTX_set0_param , +and +.Fn X509_STORE_CTX_set_default +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/X509_STORE_CTX_set_verify.3 b/Libraries/libressl/man/X509_STORE_CTX_set_verify.3 new file mode 100644 index 000000000..2c0bd692a --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_CTX_set_verify.3 @@ -0,0 +1,223 @@ +.\" $OpenBSD: X509_STORE_CTX_set_verify.3,v 1.7 2023/08/10 16:15:42 schwarze Exp $ +.\" +.\" Copyright (c) 2021, 2022 Ingo Schwarze +.\" Copyright (c) 2023 Job Snijders +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 10 2023 $ +.Dt X509_STORE_CTX_SET_VERIFY 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_verify_fn , +.Nm X509_STORE_CTX_set_verify , +.Nm X509_STORE_CTX_get_verify , +.Nm X509_STORE_set_verify , +.Nm X509_STORE_set_verify_func , +.Nm X509_STORE_get_verify , +.Nm X509_STORE_CTX_check_issued_fn , +.Nm X509_STORE_set_check_issued , +.Nm X509_STORE_get_check_issued , +.Nm X509_STORE_CTX_get_check_issued +.Nd user-defined certificate chain verification function +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft typedef int +.Fo (*X509_STORE_CTX_verify_fn) +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_verify +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_STORE_CTX_verify_fn verify" +.Fc +.Ft X509_STORE_CTX_verify_fn +.Fo X509_STORE_CTX_get_verify +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_set_verify +.Fa "X509_STORE *store" +.Fa "X509_STORE_CTX_verify_fn verify" +.Fc +.Ft void +.Fo X509_STORE_set_verify_func +.Fa "X509_STORE *store" +.Fa "X509_STORE_CTX_verify_fn verify" +.Fc +.Ft X509_STORE_CTX_verify_fn +.Fo X509_STORE_get_verify +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft typedef int +.Fo (*X509_STORE_CTX_check_issued_fn) +.Fa "X509_STORE_CTX *ctx" +.Fa "X509 *subject" +.Fa "X509 *issuer" +.Fc +.Ft void +.Fo X509_STORE_set_check_issued +.Fa "X509_STORE *store" +.Fa "X509_STORE_CTX_check_issued_fn check_issued" +.Fc +.Ft X509_STORE_CTX_check_issued_fn +.Fo X509_STORE_get_check_issued +.Fa "X509_STORE *store" +.Fc +.Ft X509_STORE_CTX_check_issued_fn +.Fo X509_STORE_CTX_get_check_issued +.Fa "X509_STORE_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_CTX_set_verify +configures +.Fa ctx +to use the +.Fa verify +argument as the X.509 certificate chain verification function instead +of the default verification function built into the library when +.Xr X509_verify_cert 3 +is called. +.Pp +The +.Fa verify +function provided by the user is only called if the +.Dv X509_V_FLAG_LEGACY_VERIFY +or +.Dv X509_V_FLAG_NO_ALT_CHAINS +flag was set on +.Fa ctx +using +.Xr X509_STORE_CTX_set_flags 3 +or +.Xr X509_VERIFY_PARAM_set_flags 3 . +Otherwise, it is ignored and a different algorithm is used that does +not support replacing the verification function. +.Pp +.Fn X509_STORE_set_verify +saves the function pointer +.Fa verify +in the given +.Fa store +object. +That pointer will be copied to an +.Vt X509_STORE_CTX +object when +.Fa store +is later passed as an argument to +.Xr X509_STORE_CTX_init 3 . +.Pp +.Fn X509_STORE_set_verify_func +is an alias for +.Fn X509_STORE_set_verify +implemented as a macro. +.Pp +.Fn X509_STORE_set_check_issued +saves the function pointer +.Fa check_issued +in the given +.Fa store +object. +That pointer will be copied to an +.Vt X509_STORE_CTX +object when +.Fa store +is later passed as an argument to +.Fn X509_STORE_CTX_init 3 . +.Pp +The +.Fa check_issued +function provided by the user should check whether a given certificate +.Fa subject +was issued using the CA certificate +.Fa issuer , +and must return 0 on failure and 1 on success. +.Sh RETURN VALUES +.Fn X509_STORE_CTX_verify_fn +is supposed to return 1 to indicate that the chain is valid +or 0 if it is not or if an error occurred. +.Pp +.Fn X509_STORE_CTX_get_verify +returns a function pointer previously set with +.Fn X509_STORE_CTX_set_verify +or +.Xr X509_STORE_CTX_init 3 , +or +.Dv NULL +if +.Fa ctx +is uninitialized. +.Pp +.Fn X509_STORE_get_verify +returns the function pointer previously set with +.Fn X509_STORE_set_verify , +or +.Dv NULL +if that function was not called on the +.Fa store . +.Pp +.Fn X509_STORE_get_check_issued +returns the function pointer previously set with +.Fn X509_STORE_set_check_issued , +or +.Dv NULL +if that function was not called on the +.Fa store . +.Pp +.Fn X509_STORE_CTX_get_check_issued +returns the +.Fn check_issued +function pointer set on the +.Vt X509_STORE_CTX . +This is either the +.Fn check_issued +function inherited from the +.Fa store +used in +.Xr X509_STORE_CTX_init 3 +or the library's default implementation. +.Sh SEE ALSO +.Xr X509_check_issued 3 , +.Xr X509_STORE_CTX_init 3 , +.Xr X509_STORE_CTX_set_error 3 , +.Xr X509_STORE_CTX_set_flags 3 , +.Xr X509_STORE_CTX_set_verify_cb 3 , +.Xr X509_STORE_new 3 , +.Xr X509_STORE_set_flags 3 , +.Xr X509_STORE_set_verify_cb 3 , +.Xr X509_verify_cert 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_STORE_set_verify_func +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_CTX_set_verify +and +.Fn X509_STORE_CTX_get_verify +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . +.Pp +.Fn X509_STORE_CTX_verify_fn , +.Fn X509_STORE_set_verify , +and +.Fn X509_STORE_get_verify +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.2 . +.Pp +.Fn X509_STORE_set_check_issued , +.Fn X509_STORE_get_check_issued , +and +.Fn X509_STORE_CTX_get_check_issued +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.3 . diff --git a/Libraries/libressl/man/X509_STORE_CTX_set_verify_cb.3 b/Libraries/libressl/man/X509_STORE_CTX_set_verify_cb.3 new file mode 100644 index 000000000..0fe086b72 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_CTX_set_verify_cb.3 @@ -0,0 +1,309 @@ +.\" $OpenBSD: X509_STORE_CTX_set_verify_cb.3,v 1.12 2023/05/30 07:37:34 op Exp $ +.\" full merge up to: OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2009 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 30 2023 $ +.Dt X509_STORE_CTX_SET_VERIFY_CB 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_verify_cb , +.Nm X509_STORE_CTX_set_verify_cb , +.Nm X509_STORE_CTX_get_verify_cb +.Nd set and retrieve verification callback +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft typedef int +.Fo (*X509_STORE_CTX_verify_cb) +.Fa "int ok" +.Fa "X509_STORE_CTX *ctx" +.Fc +.Ft void +.Fo X509_STORE_CTX_set_verify_cb +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_STORE_CTX_verify_cb verify_cb" +.Fc +.Ft X509_STORE_CTX_verify_cb +.Fo X509_STORE_CTX_get_verify_cb +.Fa "X509_STORE_CTX *ctx" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_CTX_set_verify_cb +sets the verification callback of +.Fa ctx +to +.Fa verify_cb +overwriting any existing callback. +.Pp +The verification callback can be used to modify the operation of +certificate verification, either by overriding error conditions or +logging errors for debugging purposes. +The use of a verification callback is not essential, and should not +be used in security sensitive programs. +.Pp +Do not use this function. +It is extremely fragile and unpredictable. +This callback exposes implementation details of certificate verification, +which change as the library evolves. +Attempting to use it for security checks can introduce vulnerabilities if +making incorrect assumptions about when the callback is called. +Additionally, overriding +.Fa ok +may leave +.Fa ctx +in an inconsistent state and break invariants. +.Pp +Instead, customize certificate verification by configuring options on the +.Vt X509_STORE_CTX +before verification, or applying additional checks after +.Xr X509_verify_cert 3 +completes successfully. +.Pp +The +.Fa ok +parameter to the callback indicates the value the callback should return +to retain the default behaviour. +If it is zero then an error condition is indicated. +If it is 1 then no error occurred. +As the default behaviour is internal to the verifier, and possibly unknown +to the caller, changing this parameter is inherently dangerous and should not +normally be done except for debugging purposes, and should not be expected to +be consistent if the verifier changes. +If the flag +.Dv X509_V_FLAG_NOTIFY_POLICY +is set, then +.Fa ok +is set to 2 to indicate the policy checking is complete. +.Pp +The +.Fa ctx +parameter to the callback is the +.Vt X509_STORE_CTX +structure that is performing the verification operation. +A callback can examine this structure and receive additional information +about the error, for example by calling +.Xr X509_STORE_CTX_get_current_cert 3 . +Additional application data can be passed to the callback via the +.Sy ex_data +mechanism. +.Pp +The verification callback can be set and inherited from the parent +structure performing the operation. +In some cases (such as S/MIME verification) the +.Vt X509_STORE_CTX +structure is created and destroyed internally and the only way to set a +custom verification callback is by inheriting it from the associated +.Vt X509_STORE . +.Sh RETURN VALUES +.Fn X509_STORE_CTX_get_verify_cb +returns a pointer to the current callback function +used by the specified +.Fa ctx . +If no callback was set using +.Fn X509_STORE_CTX_set_verify_cb , +that is a pointer to a built-in static function +which does nothing except returning the +.Fa ok +argument passed to it. +.Sh EXAMPLES +Default callback operation: +.Bd -literal +int +verify_callback(int ok, X509_STORE_CTX *ctx) +{ + return ok; +} +.Ed +.Pp +This is likely the only safe callback to use. +.Pp +Simple and terrible example that should not be used. +Suppose a certificate in the chain is expired and we +wish to continue after this error: +.Bd -literal +int +verify_callback(int ok, X509_STORE_CTX *ctx) +{ + /* Tolerate certificate expiration */ + if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED) + return 1; + /* Otherwise don't override */ + return ok; +} +.Ed +.Pp +While this example is presented for historical purposes, +this is not the correct way to accomplish this. +The verification flag +.Dv X509_V_FLAG_NO_CHECK_TIME +should be set on the +.Vt STORE_CTX +using +.Xr X509_VERIFY_PARAM_set_flags 3 +instead. +.Pp +Full featured debugging logging callback - note that the output and +order that things happen from this can change over time and should not +be parsed or expected to be consistent. +In this case the +.Fa bio_err +is assumed to be a global logging +.Vt BIO , +an alternative would to store a +.Vt BIO +in +.Fa ctx +using +.Sy ex_data . +.Bd -literal +int +verify_callback(int ok, X509_STORE_CTX *ctx) +{ + X509 *err_cert; + int err,depth; + + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); + + BIO_printf(bio_err,"depth=%d ",depth); + if (err_cert) { + X509_NAME_print_ex(bio_err, + X509_get_subject_name(err_cert), 0, + XN_FLAG_ONELINE); + BIO_puts(bio_err, "\en"); + } else + BIO_puts(bio_err, "\en"); + if (!ok) + BIO_printf(bio_err, "verify error:num=%d:%s\en", + err, X509_verify_cert_error_string(err)); + switch (err) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + BIO_puts(bio_err, "issuer= "); + X509_NAME_print_ex(bio_err, + X509_get_issuer_name(err_cert), 0, + XN_FLAG_ONELINE); + BIO_puts(bio_err, "\en"); + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + BIO_printf(bio_err, "notBefore="); + ASN1_TIME_print(bio_err, + X509_get_notBefore(err_cert)); + BIO_printf(bio_err, "\en"); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + BIO_printf(bio_err, "notAfter="); + ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert)); + BIO_printf(bio_err, "\en"); + break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(bio_err, ctx); + break; + } + if (err == X509_V_OK && ok == 2) + /* print out policies */ + + BIO_printf(bio_err,"verify return:%d\en",ok); + return(ok); +} +.Ed +.Sh SEE ALSO +.Xr X509_STORE_CTX_get_error 3 , +.Xr X509_STORE_CTX_get_ex_new_index 3 , +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_CTX_set_error 3 , +.Xr X509_STORE_CTX_set_flags 3 , +.Xr X509_STORE_CTX_set_verify 3 , +.Xr X509_STORE_set_verify_cb 3 , +.Xr X509_verify_cert 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_STORE_CTX_set_verify_cb +first appeared in OpenSSL 0.9.6c and has been available since +.Ox 3.2 . +.Pp +.Fn X509_STORE_CTX_get_verify_cb +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.1 . +.Pp +.Fn X509_STORE_CTX_verify_cb +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.2 . +.Sh CAVEATS +In general a verification callback should +.Sy NOT +return a changed value of +.Fa ok +because this can allow the verification to appear to succeed +in an unpredictable way. +This can effectively remove all security from the application because +untrusted or invalid certificates may be accepted. +Doing this can possibly make +.Xr X509_verify_cert 3 +return what appears to be a validated chain of certificates that has not +been validated or even had the signatures checked. diff --git a/Libraries/libressl/man/X509_STORE_get_by_subject.3 b/Libraries/libressl/man/X509_STORE_get_by_subject.3 new file mode 100644 index 000000000..3fb6c1c25 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_get_by_subject.3 @@ -0,0 +1,249 @@ +.\" $OpenBSD: X509_STORE_get_by_subject.3,v 1.4 2023/08/10 14:15:16 schwarze Exp $ +.\" +.\" Copyright (c) 2021, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 10 2023 $ +.Dt X509_STORE_GET_BY_SUBJECT 3 +.Os +.Sh NAME +.Nm X509_STORE_CTX_get_by_subject , +.Nm X509_STORE_CTX_get_obj_by_subject , +.Nm X509_STORE_CTX_get1_certs , +.Nm X509_STORE_CTX_get1_crls , +.Nm X509_STORE_CTX_get1_issuer , +.Nm X509_STORE_get_by_subject , +.Nm X509_STORE_get1_certs , +.Nm X509_STORE_get1_crls +.Nd retrieve objects from a certificate store +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft int +.Fo X509_STORE_CTX_get_by_subject +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fa "X509_OBJECT *object" +.Fc +.Ft X509_OBJECT * +.Fo X509_STORE_CTX_get_obj_by_subject +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_STORE_CTX_get1_certs +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_NAME *name" +.Fc +.Ft STACK_OF(X509_CRL) * +.Fo X509_STORE_CTX_get1_crls +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_NAME *name" +.Fc +.Ft int +.Fo X509_STORE_CTX_get1_issuer +.Fa "X509 **issuer" +.Fa "X509_STORE_CTX *ctx" +.Fa "X509 *certificate" +.Fc +.Ft int +.Fo X509_STORE_get_by_subject +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_LOOKUP_TYPE type" +.Fa "X509_NAME *name" +.Fa "X509_OBJECT *object" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_STORE_get1_certs +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_NAME *name" +.Fc +.Ft STACK_OF(X509_CRL) * +.Fo X509_STORE_get1_crls +.Fa "X509_STORE_CTX *ctx" +.Fa "X509_NAME *name" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_CTX_get_by_subject +retrieves the first object having a matching +.Fa type +and +.Fa name +from the +.Vt X509_STORE +associated with the +.Fa ctx . +The +.Fa type +can be +.Dv X509_LU_X509 +to retrieve a certificate or +.Dv X509_LU_CRL +to retrieve a revocation list. +.Pp +If the store does not yet contain a matching object or if the type is +.Dv X509_LU_CRL , +.Xr X509_LOOKUP_by_subject 3 +is called on +.Vt X509_LOOKUP +objects associated with the store until a match is found, +which may add zero or more objects to the store. +.Pp +In case of success, the content of the +.Fa object +provided by the caller is overwritten with a pointer to the first +match, and the reference count of that certificate or revocation +list is incremented by 1. +Avoiding a memory leak by making sure the provided +.Fa object +is empty is the responsibility of the caller. +.Pp +.Fn X509_STORE_CTX_get_obj_by_subject +is similar except that a new object is allocated and returned. +.Pp +.Fn X509_STORE_CTX_get1_certs +retrieves all certificates matching the subject +.Vt name +from the +.Vt X509_STORE +associated with +.Fa ctx . +If there are none yet, +.Fn X509_STORE_CTX_get_by_subject +is called to try and add some. +In case of success, the reference counts of all certificates +added to the returned array are incremented by 1. +.Pp +.Fn X509_STORE_CTX_get1_crls +is similar except that it operates on certificate revocation lists +rather than on certificates and that it always calls +.Fn X509_STORE_CTX_get_by_subject , +even if the +.Vt X509_STORE +already contains a matching revocation list. +.Pp +.Fn X509_STORE_CTX_get1_issuer +retrieves the +.Fa issuer +CA certificate for the given +.Fa certificate +from the +.Vt X509_STORE +associated with +.Fa ctx . +Internally, the issuer name is retrieved with +.Xr X509_get_issuer_name 3 +and the candidate issuer CA certificate with +.Fn X509_STORE_X509_get_by_subject +using that issuer name. +.Xr X509_check_issued 3 +or a user-supplied replacement function is used to check whether the +.Fa certificate +was indeed issued using the +.Fa issuer +CA certificate before returning it. +If verification parameters associated with +.Fa ctx +encourage checking of validity times, CAs with a valid time are +preferred, but if no matching CA has a valid time, one with an +invalid time is accepted anyway. +.Pp +The following are deprecated aliases: +.Bl -column X509_STORE_get_by_subject F X509_STORE_CTX_get_by_subject +.It Fn X509_STORE_get_by_subject Ta for Ta Fn X509_STORE_CTX_get_by_subject +.It Fn X509_STORE_get1_certs Ta for Ta Fn X509_STORE_CTX_get1_certs +.It Fn X509_STORE_get1_crls Ta for Ta Fn X509_STORE_CTX_get1_crls +.El +.Sh RETURN VALUES +.Fn X509_STORE_CTX_get_by_subject +and +.Fn X509_STORE_get_by_subject +return 1 if a match is found or 0 on failure. +In addition to simply not finding a match, +they may also fail due to memory allocation failure in +.Xr X509_LOOKUP_by_subject 3 . +With library implementations other than LibreSSL, +they might also return negative values for internal errors. +.Pp +.Fn X509_STORE_CTX_get_obj_by_subject +returns the new object or +.Dv NULL +on failure, in particular if no match is found or memory allocation fails. +.Pp +.Fn X509_STORE_CTX_get1_certs +and +.Fn X509_STORE_get1_certs +return a newly allocated and populated array of certificates or +.Dv NULL +on failure. +They fail if no match is found, if +.Fn X509_STORE_CTX_get_by_subject +fails, or if memory allocation fails. +.Pp +.Fn X509_STORE_CTX_get1_crls +and +.Fn X509_STORE_get1_crls +return a newly allocated and populated array of CRLs or +.Dv NULL +on failure. +They fail if +.Fn X509_STORE_CTX_get_by_subject +finds no new match, even if the associated +.Vt X509_STORE +already contains matching CRLs, or if memory allocation fails. +.Pp +.Fn X509_STORE_CTX_get1_issuer +returns 1 if a matching +.Fa issuer +CA certificate is found or 0 otherwise. +With library implementations other than LibreSSL, +it might also return negative values for internal errors. +.Sh SEE ALSO +.Xr STACK_OF 3 , +.Xr X509_check_issued 3 , +.Xr X509_CRL_new 3 , +.Xr X509_get_issuer_name 3 , +.Xr X509_LOOKUP_by_subject 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 , +.Xr X509_OBJECT_retrieve_by_subject 3 , +.Xr X509_STORE_CTX_new 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_STORE_get_by_subject +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_CTX_get1_issuer +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn X509_STORE_get1_certs +and +.Fn X509_STORE_get1_crls +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . +.Pp +.Fn X509_STORE_CTX_get_by_subject +and +.Fn X509_STORE_CTX_get_obj_by_subject +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . +.Pp +.Fn X509_STORE_CTX_get1_certs +and +.Fn X509_STORE_CTX_get1_crls +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.4 . diff --git a/Libraries/libressl/man/X509_STORE_load_locations.3 b/Libraries/libressl/man/X509_STORE_load_locations.3 new file mode 100644 index 000000000..f38eeb667 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_load_locations.3 @@ -0,0 +1,187 @@ +.\" $OpenBSD: X509_STORE_load_locations.3,v 1.10 2021/11/12 14:05:28 schwarze Exp $ +.\" full merge up to: +.\" OpenSSL X509_STORE_add_cert b0edda11 Mar 20 13:00:17 2018 +0000 +.\" +.\" Copyright (c) 2017, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 12 2021 $ +.Dt X509_STORE_LOAD_LOCATIONS 3 +.Os +.Sh NAME +.Nm X509_STORE_load_locations , +.Nm X509_STORE_set_default_paths , +.Nm X509_STORE_load_mem , +.Nm X509_STORE_add_lookup +.Nd configure files and directories used by a certificate store +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft int +.Fo X509_STORE_load_locations +.Fa "X509_STORE *store" +.Fa "const char *file" +.Fa "const char *dirs" +.Fc +.Ft int +.Fo X509_STORE_set_default_paths +.Fa "X509_STORE *store" +.Fc +.Ft int +.Fo X509_STORE_load_mem +.Fa "X509_STORE *store" +.Fa "void *buffer" +.Fa "int length" +.Fc +.Ft X509_LOOKUP * +.Fo X509_STORE_add_lookup +.Fa "X509_STORE *store" +.Fa "X509_LOOKUP_METHOD *method" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_load_locations +instructs the +.Fa store +to use the PEM +.Fa file +and all the PEM files in the directories +contained in the colon-separated list +.Fa dirs +for looking up certificates, in addition to files and directories +that are already configured. +The certificates in the directories must be in hashed form, as documented in +.Xr X509_LOOKUP_hash_dir 3 . +Directories already in use are not added again. +If +.Dv NULL +is passed for +.Fa file +or +.Fa dirs , +no new file or no new directories are added, respectively. +.Pp +.Fn X509_STORE_load_locations +is identical to +.Xr SSL_CTX_load_verify_locations 3 +except that it operates directly on an +.Vt X509_STORE +object, rather than on the store used by an SSL context. +See that manual page for more information. +.Pp +.Fn X509_STORE_set_default_paths +is similar except that it instructs the +.Fa store +to use the default PEM file and directory +(as documented in +.Sx FILES ) +in addition to what is already configured. +It ignores errors that occur while trying to load the file or to +add the directory, but it may still fail for other reasons, for +example when out of memory while trying to allocate the required +.Vt X509_LOOKUP +objects. +.Pp +.Fn X509_STORE_set_default_paths +is identical to +.Xr SSL_CTX_set_default_verify_paths 3 +except that it operates directly on an +.Vt X509_STORE +object, rather than on the store used by an SSL context. +See that manual page for more information. +.Pp +The above functions are wrappers around +.Xr X509_LOOKUP_load_file 3 +and +.Xr X509_LOOKUP_add_dir 3 . +.Pp +.Fn X509_STORE_load_mem +instructs the +.Fa store +to use the certificates contained in the memory +.Fa buffer +of the given +.Fa length +for certificate lookup. +It is a wrapper around +.Xr X509_LOOKUP_add_mem 3 . +.Pp +.Fn X509_STORE_add_lookup +checks whether the +.Fa store +already contains an +.Vt X509_LOOKUP +object using the given +.Fa method ; +if it does, no action occurs. +Otherwise, a new +.Vt X509_LOOKUP +object is allocated, added, and returned. +This function is used internally by all the functions listed above. +.Sh RETURN VALUES +.Fn X509_STORE_load_locations +returns 1 if all files and directories specified were successfully +added. +It returns 0 for failure. +That can happen if adding the file failed, if adding any of the +directories failed, or if both arguments were +.Dv NULL . +.Pp +.Fn X509_STORE_set_default_paths +returns 0 for some error conditions and 1 otherwise, not just for +success, but also for various cases of failure. +.Pp +.Fn X509_STORE_load_mem +returns 1 for success or 0 for failure. +In particular, parse errors or lack of memory can cause failure. +.Pp +.Fn X509_STORE_add_lookup +returns the existing or new lookup object or +.Dv NULL +on failure. +With LibreSSL, the only reason for failure is lack of memory. +.Sh FILES +.Bl -tag -width Ds +.It Pa /etc/ssl/cert.pem +default PEM file for +.Fn X509_STORE_set_default_paths +.It Pa /etc/ssl/certs/ +default directory for +.Fn X509_STORE_set_default_paths +.El +.Sh SEE ALSO +.Xr SSL_CTX_load_verify_locations 3 , +.Xr X509_load_cert_file 3 , +.Xr X509_LOOKUP_hash_dir 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_STORE_new 3 , +.Xr X509_STORE_set1_param 3 , +.Xr X509_STORE_set_verify_cb 3 +.Sh HISTORY +.Fn X509_STORE_load_locations , +.Fn X509_STORE_set_default_paths , +and +.Fn X509_STORE_add_lookup +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_load_mem +first appeared in +.Ox 5.7 . +.Sh BUGS +By the time that adding a directory is found to have failed, +the file and some other directories may already have been successfully loaded, +so these functions may change the state of the store even when they fail. +.Pp +.Fn X509_STORE_set_default_paths +clears the error queue, deleting even error information that was +already present when it was called. diff --git a/Libraries/libressl/man/X509_STORE_new.3 b/Libraries/libressl/man/X509_STORE_new.3 new file mode 100644 index 000000000..a17da03a4 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_new.3 @@ -0,0 +1,145 @@ +.\" $OpenBSD: X509_STORE_new.3,v 1.7 2021/11/17 16:08:32 schwarze Exp $ +.\" full merge up to: OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" selective merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by +.\" Alessandro Ghedini . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 17 2021 $ +.Dt X509_STORE_NEW 3 +.Os +.Sh NAME +.Nm X509_STORE_new , +.Nm X509_STORE_up_ref , +.Nm X509_STORE_free +.Nd allocate and free X.509 certificate stores +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft X509_STORE * +.Fn X509_STORE_new void +.Ft int +.Fo X509_STORE_up_ref +.Fa "X509_STORE *store" +.Fc +.Ft void +.Fo X509_STORE_free +.Fa "X509_STORE *store" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_new +allocates and initializes an empty X.509 certificate store +and sets its reference count to 1. +.Pp +.Fn X509_STORE_up_ref +increments the reference count of +.Fa store +by 1. +.Pp +.Fn X509_STORE_free +decrements the reference count of +.Fa store +by 1. +If the reference count reaches 0, +all resources used by the store, including all certificates +contained in it, are released and +.Fa store +itself is freed. +If +.Fa store +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn X509_STORE_new +returns a newly created +.Vt X509_STORE +object or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_STORE_up_ref +returns 1 for success and 0 for failure. +.Sh SEE ALSO +.Xr PKCS7_verify 3 , +.Xr SSL_CTX_set_cert_store 3 , +.Xr X509_load_cert_file 3 , +.Xr X509_LOOKUP_hash_dir 3 , +.Xr X509_OBJECT_get0_X509 3 , +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_get_ex_new_index 3 , +.Xr X509_STORE_load_locations 3 , +.Xr X509_STORE_set1_param 3 , +.Xr X509_STORE_set_verify_cb 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_STORE_new +and +.Fn X509_STORE_free +first appeared in SSLeay 0.8.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_STORE_set1_param.3 b/Libraries/libressl/man/X509_STORE_set1_param.3 new file mode 100644 index 000000000..354d87385 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_set1_param.3 @@ -0,0 +1,232 @@ +.\" $OpenBSD: X509_STORE_set1_param.3,v 1.19 2021/10/18 18:20:39 schwarze Exp $ +.\" content checked up to: +.\" OpenSSL man3/X509_STORE_add_cert b0edda11 Mar 20 13:00:17 2018 +0000 +.\" OpenSSL man3/X509_STORE_get0_param e90fc053 Jul 15 09:39:45 2017 -0400 +.\" +.\" Copyright (c) 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 18 2021 $ +.Dt X509_STORE_SET1_PARAM 3 +.Os +.Sh NAME +.Nm X509_STORE_set1_param , +.Nm X509_STORE_set_flags , +.Nm X509_STORE_set_purpose , +.Nm X509_STORE_set_trust , +.Nm X509_STORE_set_depth , +.Nm X509_STORE_add_cert , +.Nm X509_STORE_add_crl , +.Nm X509_STORE_get0_param , +.Nm X509_STORE_get0_objects , +.Nm X509_STORE_get_ex_new_index , +.Nm X509_STORE_set_ex_data , +.Nm X509_STORE_get_ex_data +.Nd get and set X509_STORE data +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft int +.Fo X509_STORE_set1_param +.Fa "X509_STORE *store" +.Fa "X509_VERIFY_PARAM *pm" +.Fc +.Ft int +.Fo X509_STORE_set_flags +.Fa "X509_STORE *store" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo X509_STORE_set_purpose +.Fa "X509_STORE *store" +.Fa "int purpose" +.Fc +.Ft int +.Fo X509_STORE_set_trust +.Fa "X509_STORE *store" +.Fa "int trust" +.Fc +.Ft int +.Fo X509_STORE_set_depth +.Fa "X509_STORE *store" +.Fa "int depth" +.Fc +.Ft int +.Fo X509_STORE_add_cert +.Fa "X509_STORE *store" +.Fa "X509 *x" +.Fc +.Ft int +.Fo X509_STORE_add_crl +.Fa "X509_STORE *store" +.Fa "X509_CRL *crl" +.Fc +.Ft X509_VERIFY_PARAM * +.Fo X509_STORE_get0_param +.Fa "X509_STORE *store" +.Fc +.Ft STACK_OF(X509_OBJECT) * +.Fo X509_STORE_get0_objects +.Fa "X509_STORE *store" +.Fc +.Ft int +.Fo X509_STORE_get_ex_new_index +.Fa "long argl" +.Fa "void *argp" +.Fa "CRYPTO_EX_new *new_func" +.Fa "CRYPTO_EX_dup *dup_func" +.Fa "CRYPTO_EX_free *free_func" +.Fc +.Ft int +.Fo X509_STORE_set_ex_data +.Fa "X509_STORE *store" +.Fa "int idx" +.Fa "void *arg" +.Fc +.Ft void * +.Fo X509_STORE_get_ex_data +.Fa "X509_STORE *store" +.Fa "int idx" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_set1_param +copies the verification parameters from +.Fa pm +using +.Xr X509_VERIFY_PARAM_set1 3 +into the verification parameter object contained in the +.Fa store . +.Pp +.Fn X509_VERIFY_PARAM_set_flags , +.Fn X509_STORE_set_purpose , +.Fn X509_STORE_set_trust , +and +.Fn X509_STORE_set_depth +call +.Fn X509_VERIFY_PARAM_set_flags , +.Fn X509_VERIFY_PARAM_set_purpose , +.Fn X509_VERIFY_PARAM_set_trust , +and +.Fn X509_VERIFY_PARAM_set_depth +on the verification parameter object contained in the +.Fa store . +.Pp +.Fn X509_STORE_add_cert +and +.Fn X509_STORE_add_crl +add the certificate +.Fa x +or the certificate revocation list +.Fa crl +to the +.Fa store , +increasing its reference count by 1 in case of success. +Untrusted objects should not be added in this way. +.Pp +.Fn X509_STORE_get_ex_new_index , +.Fn X509_STORE_set_ex_data , +and +.Fn X509_STORE_get_ex_data +handle application specific data in +.Vt X509_STORE +objects. +Their usage is identical to that of +.Xr RSA_get_ex_new_index 3 , +.Xr RSA_set_ex_data 3 , +and +.Xr RSA_get_ex_data 3 . +.Sh RETURN VALUES +.Fn X509_STORE_set1_param , +.Fn X509_STORE_set_purpose , +.Fn X509_STORE_set_trust , +and +.Fn X509_STORE_set_ex_data +return 1 for success or 0 for failure. +.Pp +.Fn X509_STORE_set_flags +and +.Fn X509_STORE_set_depth +always return 1, indicating success. +.Pp +.Fn X509_STORE_add_cert +and +.Fn X509_STORE_add_crl +return 1 for success or 0 for failure. +For example, they fail if +.Fa x +or +.Fa crl +is a +.Dv NULL +pointer, if a certificate with the same subject name as +.Fa x +or a revocation list with the same issuer name as +.Fa crl +are already contained in the +.Fa store , +or if memory allocation fails. +.Pp +.Fn X509_STORE_get0_param +returns an internal pointer to the verification parameter object +contained in the +.Fa store , +.Fn X509_STORE_get0_objects +to the stack of certificates, revocation lists, and private keys. +The returned pointers must not be freed by the calling application. +.Pp +.Fn X509_STORE_get_ex_new_index +returns a new index or \-1 on failure. +.Pp +.Fn X509_STORE_get_ex_data +returns the application data or +.Dv NULL +on failure. +.Sh SEE ALSO +.Xr RSA_get_ex_new_index 3 , +.Xr SSL_set1_param 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_OBJECT_get0_X509 3 , +.Xr X509_STORE_CTX_set0_param 3 , +.Xr X509_STORE_load_locations 3 , +.Xr X509_STORE_new 3 , +.Xr X509_VERIFY_PARAM_new 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_STORE_add_cert +first appeared in SSLeay 0.8.0. +.Fn X509_STORE_add_crl +first appeared in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_set_flags , +.Fn X509_STORE_set_purpose , +and +.Fn X509_STORE_set_trust +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +.Fn X509_STORE_set1_param +and +.Fn X509_STORE_set_depth +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn X509_STORE_get0_param , +.Fn X509_STORE_get0_objects , +.Fn X509_STORE_get_ex_new_index , +.Fn X509_STORE_set_ex_data , +and +.Fn X509_STORE_get_ex_data +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_STORE_set_verify_cb_func.3 b/Libraries/libressl/man/X509_STORE_set_verify_cb_func.3 new file mode 100644 index 000000000..bdd5ea504 --- /dev/null +++ b/Libraries/libressl/man/X509_STORE_set_verify_cb_func.3 @@ -0,0 +1,121 @@ +.\" $OpenBSD: X509_STORE_set_verify_cb_func.3,v 1.12 2022/11/16 14:51:08 schwarze Exp $ +.\" full merge up to: OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" selective merge up to: OpenSSL 315c47e0 Dec 1 14:22:16 2020 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2009 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 16 2022 $ +.Dt X509_STORE_SET_VERIFY_CB_FUNC 3 +.Os +.Sh NAME +.Nm X509_STORE_set_verify_cb , +.Nm X509_STORE_set_verify_cb_func , +.Nm X509_STORE_get_verify_cb +.Nd set verification callback +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft void +.Fo X509_STORE_set_verify_cb +.Fa "X509_STORE *st" +.Fa "X509_STORE_CTX_verify_cb verify_cb" +.Fc +.Ft void +.Fo X509_STORE_set_verify_cb_func +.Fa "X509_STORE *st" +.Fa "X509_STORE_CTX_verify_cb verify_cb" +.Fc +.Ft X509_STORE_CTX_verify_cb +.Fo X509_STORE_get_verify_cb +.Fa "X509_STORE *st" +.Fc +.Sh DESCRIPTION +.Fn X509_STORE_set_verify_cb +sets the verification callback of +.Sy ctx +to +.Sy verify_cb , +overwriting any existing callback. +.Pp +.Fn X509_STORE_set_verify_cb_func +also sets the verification callback but it is implemented as a macro. +.Pp +The verification callback from an +.Vt X509_STORE +is inherited by the corresponding +.Vt X509_STORE_CTX +structure when it is initialized. +This can be used to set the verification callback when the +.Vt X509_STORE_CTX +is otherwise inaccessible (for example during S/MIME verification). +.Sh RETURN VALUES +.Fn X509_STORE_get_verify_cb +returns the function pointer set with +.Fn X509_STORE_set_verify_cb , +or +.Dv NULL +if that function was not called on +.Fa st . +.Sh SEE ALSO +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_CTX_set_verify 3 , +.Xr X509_STORE_CTX_set_verify_cb 3 , +.Xr X509_STORE_new 3 , +.Xr X509_STORE_set_flags 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_STORE_set_verify_cb_func +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn X509_STORE_set_verify_cb +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Pp +.Fn X509_STORE_get_verify_cb +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.2 . diff --git a/Libraries/libressl/man/X509_TRUST_set.3 b/Libraries/libressl/man/X509_TRUST_set.3 new file mode 100644 index 000000000..f363ead18 --- /dev/null +++ b/Libraries/libressl/man/X509_TRUST_set.3 @@ -0,0 +1,286 @@ +.\" $OpenBSD: X509_TRUST_set.3,v 1.1 2021/07/24 14:33:14 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 24 2021 $ +.Dt X509_TRUST_SET 3 +.Os +.Sh NAME +.Nm X509_TRUST_set , +.Nm X509_TRUST_get_by_id , +.Nm X509_TRUST_add , +.Nm X509_TRUST_get_count , +.Nm X509_TRUST_cleanup , +.Nm X509_TRUST_get0 , +.Nm X509_TRUST_get_trust , +.Nm X509_TRUST_get0_name , +.Nm X509_TRUST_get_flags +.Nd trust objects, indices, and identifiers +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_TRUST_set +.Fa "int *id_out" +.Fa "int id_in" +.Fc +.Ft int +.Fn X509_TRUST_get_by_id "int identifier" +.Ft int +.Fo X509_TRUST_add +.Fa "int identifier" +.Fa "int flags" +.Fa "int (*check_trust)(X509_TRUST *, X509 *, int)" +.Fa "const char *name" +.Fa "int arg1" +.Fa "void *arg2" +.Fc +.Ft int +.Fn X509_TRUST_get_count void +.Ft void +.Fn X509_TRUST_cleanup void +.Ft X509_TRUST * +.Fn X509_TRUST_get0 "int index" +.Ft int +.Fn X509_TRUST_get_trust "const X509_TRUST *object" +.Ft char * +.Fn X509_TRUST_get0_name "const X509_TRUST *object" +.Ft int +.Fn X509_TRUST_get_flags "const X509_TRUST *object" +.Sh DESCRIPTION +The purposes that an X.509 certificate is trusted for +can be identified in three equivalent ways: +.Bl -enum +.It +By trust identifiers, which are positive integer constants. +Standard trust identifiers lie in the range from +.Dv X509_TRUST_MIN +to +.Dv X509_TRUST_MAX , +inclusive. +User defined trust identifiers are larger than +.Dv X509_TRUST_MAX . +.It +By trust indices, which are non-negative integer constants but +differ from the trust identifiers expressing the same kind of trust. +Standard trust indices are smaller than +.Dv X509_TRUST_MAX . +User defined trust indices are larger than or equal to +.Dv X509_TRUST_MAX . +.It +By trust objects of the type +.Vt X509_TRUST . +Standard trust objects are available in static storage. +User defined trust objects can be created with +.Fn X509_TRUST_add . +.El +.Pp +Application programmers cannot choose the way to identify kinds of trust +that they like best; depending on the circumstances, all three ways +are needed. +Be warned that the naming of most functions is misleading. +.Pp +Most API functions documented outside the present manual page +use trust identifiers rather than trust indices. +.Pp +ASN.1 object identifiers and NIDs provide a fourth and a fifth way +to identify purposes that a certificate is trusted for. +These are almost, but not exactly, equivalent +to the three ways listed above; see the +.Xr X509_check_trust 3 +manual for details. +.Ss Using trust identifiers +.Fn X509_TRUST_set +validates the trust identifier +.Fa id_in . +If it is valid, it is copied to +.Pf * Fa id_out . +Otherwise, +.Pf * Fa id_out +remains unchanged. +.Pp +.Fn X509_TRUST_get_by_id +converts the trust +.Fa identifier +to the corresponding trust +.Fa index . +To find the corresponding trust object, pass the result to +.Fn X509_TRUST_get0 . +.Pp +.Fn X509_TRUST_add +defines a purpose certificates can be trusted for with the given +.Fa identifier +or modifies its properties if it already exists. +The trust +.Fa identifier , +the +.Fa flags , +the +.Fa check_trust +function, the +.Fa name , +the number +.Fa arg1 , +and the pointer +.Fa arg2 +are copied into the +.Vt X509_TRUST +object. +When modifying an existing trust object, previous +values of fields are overwritten and a previous +.Fa name +string is freed if it was dynamically allocated. +When creating a new trust object, +it is added to the global array of user-defined trust objects. +.Pp +.Dv X509_TRUST_DYNAMIC +and +.Dv X509_TRUST_DYNAMIC_NAME +are always ignored in the +.Fa flags +argument. +.Dv X509_TRUST_DYNAMIC +is automatically set if the object was created by the user. +It is never set for standard objects, +not even if they were modified by the user. +.Dv X509_trust_DYNAMIC_NAME +is automatically set if the object was created or modified by the user. +It is only unset for unmodified standard objects. +The library does not appear to define any other flags, +so the flags argument is probably useless +unless users define their own flags and use them in the +.Fa check_trust +function. +.Pp +The third and final argument of the +.Fa check_trust +function is the +.Fa flags +argument of +.Fn X509_check_trust . +.Pp +The built-in trust checking functions documented in the +.Xr X509_check_trust 3 +manual page use +.Fa arg1 +as the corresponding ASN.1 object NID and ignore +.Fa arg2 +and +.Fa flags , +but a user-supplied +.Fa check_trust +function can use these fields in any arbitrary way. +.Pp +.Fn X509_TRUST_get_count +returns the total number of trust objects currently existing, +including both standard and user-defined objects. +If no user-defined objects exist, the returned value is +.Dv X509_TRUST_MAX . +.Pp +.Fn X509_TRUST_cleanup +deletes all user-defined trust objects +and invalidates their trust identifiers and trust indices. +If any of the standard trust objects were modified by the user, +those changes are +.Em not +reverted. +.Ss Using trust indices +.Fn X509_TRUST_get0 +converts the trust +.Fa index +to a pointer to the corresponding trust object. +To find the corresponding trust identifier, pass the result to +.Fn X509_TRUST_get_trust . +.Ss Using trust objects +.Fn X509_TRUST_get_trust +converts a pointer to a trust +.Fa object +to the corresponding trust identifier. +To find the corresponding trust index, pass the result to +.Fn X509_TRUST_get_by_id . +.Pp +.Fn X509_TRUST_get0_name +and +.Fn X509_TRUST_get_flags +retrieve the name and flags from the +.Fa object , +respectively. +.Sh RETURN VALUES +.Fn X509_TRUST_set +returns 1 if +.Fa id_in +is valid or 0 otherwise. +.Pp +.Fn X509_TRUST_get_by_id +returns the corresponding trust index or -1 if the +.Fa identifier +is invalid. +.Pp +.Fn X509_TRUST_add +returns 1 for success or 0 for failure. +.Pp +.Fn X509_TRUST_get_count +returns the total number of trust objects currently existing. +.Pp +.Fn X509_TRUST_get0 +returns a standard or user-defined trust object or +.Dv NULL +if the +.Fa index +is invalid. +.Pp +.Fn X509_TRUST_get_trust +always returns a valid trust identifier. +.Pp +.Fn X509_TRUST_get0_name +returns a pointer to storage owned by the +.Fa object . +.Pp +.Fn X509_TRUST_get_flags +returns the flags associated with the +.Fa object . +.Sh ERRORS +The following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv X509_R_INVALID_TRUST Qq "invalid trust" +.Fn X509_TRUST_set +was called with an invalid +.Fa id_in +argument. +.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" +.Fn X509_TRUST_add +failed to allocate memory. +.El +.Pp +The other functions provide no diagnostics. +.Sh SEE ALSO +.Xr X509_check_trust 3 , +.Xr X509_new 3 , +.Xr X509_PURPOSE_set 3 , +.Xr X509_VERIFY_PARAM_set_trust 3 +.Sh HISTORY +.Fn X509_TRUST_set +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Pp +The other functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . +.Sh CAVEATS +The difference between trust identifiers and trust indices +provides an ideal breeding ground for off-by-one bugs. diff --git a/Libraries/libressl/man/X509_VERIFY_PARAM_new.3 b/Libraries/libressl/man/X509_VERIFY_PARAM_new.3 new file mode 100644 index 000000000..a22d2b1b4 --- /dev/null +++ b/Libraries/libressl/man/X509_VERIFY_PARAM_new.3 @@ -0,0 +1,306 @@ +.\" $OpenBSD: X509_VERIFY_PARAM_new.3,v 1.5 2023/05/24 09:57:50 tb Exp $ +.\" +.\" Copyright (c) 2018, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 24 2023 $ +.Dt X509_VERIFY_PARAM_NEW 3 +.Os +.Sh NAME +.Nm X509_VERIFY_PARAM_new , +.Nm X509_VERIFY_PARAM_inherit , +.Nm X509_VERIFY_PARAM_set1 , +.Nm X509_VERIFY_PARAM_free , +.Nm X509_VERIFY_PARAM_add0_table , +.Nm X509_VERIFY_PARAM_lookup , +.Nm X509_VERIFY_PARAM_get_count , +.Nm X509_VERIFY_PARAM_get0 , +.Nm X509_VERIFY_PARAM_table_cleanup +.\" The following constants defined in the public header +.\" are intentionally undocumented because X509_VERIFY_PARAM is an opaque +.\" struct and LibreSSL provides neither X509_VERIFY_PARAM_set_inh_flags(3) +.\" nor X509_VERIFY_PARAM_get_inh_flags(3): +.\" X509_VP_FLAG_DEFAULT +.\" X509_VP_FLAG_OVERWRITE +.\" X509_VP_FLAG_RESET_FLAGS +.\" X509_VP_FLAG_LOCKED +.\" X509_VP_FLAG_ONCE +.Nd X509 verification parameter objects +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft X509_VERIFY_PARAM * +.Fo X509_VERIFY_PARAM_new +.Fa void +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_inherit +.Fa "X509_VERIFY_PARAM *destination" +.Fa "const X509_VERIFY_PARAM *source" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1 +.Fa "X509_VERIFY_PARAM *destination" +.Fa "const X509_VERIFY_PARAM *source" +.Fc +.Ft void +.Fo X509_VERIFY_PARAM_free +.Fa "X509_VERIFY_PARAM *param" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_add0_table +.Fa "X509_VERIFY_PARAM *param" +.Fc +.Ft const X509_VERIFY_PARAM * +.Fo X509_VERIFY_PARAM_lookup +.Fa "const char *name" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_get_count +.Fa void +.Fc +.Ft const X509_VERIFY_PARAM * +.Fo X509_VERIFY_PARAM_get0 +.Fa "int id" +.Fc +.Ft void +.Fo X509_VERIFY_PARAM_table_cleanup +.Fa void +.Fc +.Sh DESCRIPTION +.Fn X509_VERIFY_PARAM_new +allocates and initializes an empty +.Vt X509_VERIFY_PARAM +object. +.Pp +.Fn X509_VERIFY_PARAM_inherit +copies some data from the +.Fa source +object to the +.Fa destination +object. +.Pp +The verification flags set with +.Xr X509_VERIFY_PARAM_set_flags 3 +in the +.Fa source +object are always OR'ed into the verification flags of the +.Fa destination +object. +.Pp +Fields having their default value in the +.Fa source +object are not copied. +.Pp +By default, fields in the +.Fa destination +object already having a non-default value are not overwritten. +However, if at least one of the +.Fa source +or +.Fa destination +objects was created during a call to +.Xr X509_STORE_CTX_init 3 +that did not have a +.Fa store +argument, and if that object was not previously used as the +.Fa destination +in an earlier call to +.Fn X509_VERIFY_PARAM_inherit , +this restriction is waived and even non-default fields in the +.Fa destination +object get overwritten. +If fields overwritten in this way contain pointers to allocated memory, +that memory is freed. +.Pp +As far as permitted by the above rules, the following fields are copied: +.Bl -bullet -width 1n +.It +the verification purpose identifier set with +.Xr X509_VERIFY_PARAM_set_purpose 3 +.It +the trust setting set with +.Xr X509_VERIFY_PARAM_set_trust 3 +.It +the verification time set with +.Xr X509_VERIFY_PARAM_set_time 3 ; +in this case, the only condition is that +.Dv X509_V_FLAG_USE_CHECK_TIME +is not set in the +.Fa destination +object, whereas the time value in the +.Fa destination +object is not inspected before overwriting it +.It +the acceptable policy set with +.Xr X509_VERIFY_PARAM_set1_policies 3 +.It +the maximum verification depth set with +.Xr X509_VERIFY_PARAM_set_depth 3 +.It +flags that were set with +.Xr X509_VERIFY_PARAM_set_hostflags 3 +.It +the list of expected DNS hostnames built with +.Xr X509_VERIFY_PARAM_set1_host 3 +and +.Xr X509_VERIFY_PARAM_add1_host 3 +.It +the expected RFC 822 email address set with +.Xr X509_VERIFY_PARAM_set1_email 3 +.It +the expected IP address set with +.Xr X509_VERIFY_PARAM_set1_ip 3 +or +.Xr X509_VERIFY_PARAM_set1_ip_asc 3 +.El +.Pp +Some data that may be contained in the +.Fa source +object is never copied, for example the subject name of the peer +certificate that can be retrieved with +.Xr X509_VERIFY_PARAM_get0_peername 3 . +.Pp +If +.Fa source +is a +.Dv NULL +pointer, the function has no effect but returns successfully. +.Pp +.Fn X509_VERIFY_PARAM_set1 +is identical to +.Fn X509_VERIFY_PARAM_inherit +except that fields in the +.Fa destination +object are overwritten even if they do not match their default values. +Still, fields having their default value in the +.Fa source +object are not copied. +.Pp +If +.Fn X509_VERIFY_PARAM_inherit +or +.Fn X509_VERIFY_PARAM_set1 +fail, partial copying may have occurred, so all data in the +.Fa destination +object should be regarded as invalid. +.Pp +.Fn X509_VERIFY_PARAM_inherit +is used internally by +.Xr X509_STORE_CTX_init 3 +and by +.Xr X509_STORE_CTX_set_default 3 , +and +.Fn X509_VERIFY_PARAM_set1 +is used internally by +.Xr X509_STORE_set1_param 3 . +.Pp +.Fn X509_VERIFY_PARAM_free +clears all data contained in +.Fa param +and releases all memory used by it. +If +.Fa param +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn X509_VERIFY_PARAM_add0_table +adds +.Fa param +to a static list of +.Vt X509_VERIFY_PARAM +objects maintained by the library. +This function is extremely dangerous because contrary to the name +of the function, if the list already contains an object that happens +to have the same name, that old object is not only silently removed +from the list, but also silently freed, which may silently invalidate +various pointers existing elsewhere in the program. +.Pp +.Fn X509_VERIFY_PARAM_lookup +searches this list for an object of the given +.Fa name . +If no match is found, the predefined objects built-in to the library +are also inspected. +.Pp +.Fn X509_VERIFY_PARAM_get_count +returns the sum of the number of objects on this list and the number +of predefined objects built-in to the library. +Note that this is not necessarily the total number of +.Vt X509_VERIFY_PARAM +objects existing in the program because there may be additional such +objects that were never added to the list. +.Pp +.Fn X509_VERIFY_PARAM_get0 +accesses predefined and user-defined objects using +.Fa id +as an index, useful for looping over objects without knowing their names. +An argument less than the number of predefined objects selects +one of the predefined objects; a higher argument selects an object +from the list. +.Pp +.Fn X509_VERIFY_PARAM_table_cleanup +deletes all objects from this list. +It is extremely dangerous because it also invalidates all data that +was contained in all objects that were on the list and because it +frees all these objects, which may invalidate various pointers +existing elsewhere in the program. +.Sh RETURN VALUES +.Fn X509_VERIFY_PARAM_new +returns a pointer to the new object, or +.Dv NULL +on allocation failure. +.Pp +.Fn X509_VERIFY_PARAM_inherit , +.Fn X509_VERIFY_PARAM_set1 , +and +.Fn X509_VERIFY_PARAM_add0_table +return 1 for success or 0 for failure. +.Pp +.Fn X509_VERIFY_PARAM_lookup +and +.Fn X509_VERIFY_PARAM_get0 +return a pointer to an existing built-in or user-defined object, or +.Dv NULL +if no object with the given +.Fa name +is found, or if +.Fa id +is at least +.Fn X509_VERIFY_PARAM_get_count . +.Pp +.Fn X509_VERIFY_PARAM_get_count +returns a number of objects. +.Sh SEE ALSO +.Xr SSL_set1_param 3 , +.Xr X509_STORE_CTX_set0_param 3 , +.Xr X509_STORE_set1_param 3 , +.Xr X509_verify_cert 3 , +.Xr X509_VERIFY_PARAM_set_flags 3 +.Sh HISTORY +.Fn X509_VERIFY_PARAM_new , +.Fn X509_VERIFY_PARAM_inherit , +.Fn X509_VERIFY_PARAM_set1 , +.Fn X509_VERIFY_PARAM_free , +.Fn X509_VERIFY_PARAM_add0_table , +.Fn X509_VERIFY_PARAM_lookup , +and +.Fn X509_VERIFY_PARAM_table_cleanup +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . +.Pp +.Fn X509_VERIFY_PARAM_get_count +and +.Fn X509_VERIFY_PARAM_get0 +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_VERIFY_PARAM_set_flags.3 b/Libraries/libressl/man/X509_VERIFY_PARAM_set_flags.3 new file mode 100644 index 000000000..a0ae839f9 --- /dev/null +++ b/Libraries/libressl/man/X509_VERIFY_PARAM_set_flags.3 @@ -0,0 +1,736 @@ +.\" $OpenBSD: X509_VERIFY_PARAM_set_flags.3,v 1.29 2023/04/30 19:40:23 tb Exp $ +.\" full merge up to: OpenSSL d33def66 Feb 9 14:17:13 2016 -0500 +.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2018, 2021, 2022 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson +.\" and Viktor Dukhovni . +.\" Copyright (c) 2009, 2013, 2014, 2015, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt X509_VERIFY_PARAM_SET_FLAGS 3 +.Os +.Sh NAME +.Nm X509_VERIFY_PARAM_get0_name , +.Nm X509_VERIFY_PARAM_set1_name , +.Nm X509_VERIFY_PARAM_set_flags , +.Nm X509_VERIFY_PARAM_clear_flags , +.Nm X509_VERIFY_PARAM_get_flags , +.Nm X509_VERIFY_PARAM_set_purpose , +.Nm X509_VERIFY_PARAM_set_trust , +.Nm X509_VERIFY_PARAM_set_time , +.Nm X509_VERIFY_PARAM_get_time , +.Nm X509_VERIFY_PARAM_add0_policy , +.Nm X509_VERIFY_PARAM_set1_policies , +.Nm X509_VERIFY_PARAM_set_depth , +.Nm X509_VERIFY_PARAM_get_depth , +.Nm X509_VERIFY_PARAM_set_auth_level , +.Nm X509_VERIFY_PARAM_set1_host , +.Nm X509_VERIFY_PARAM_add1_host , +.Nm X509_VERIFY_PARAM_set_hostflags , +.Nm X509_VERIFY_PARAM_get0_peername , +.Nm X509_VERIFY_PARAM_set1_email , +.Nm X509_VERIFY_PARAM_set1_ip , +.Nm X509_VERIFY_PARAM_set1_ip_asc +.Nd X509 verification parameters +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft const char * +.Fo X509_VERIFY_PARAM_get0_name +.Fa "const X509_VERIFY_PARAM *param" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1_name +.Fa "X509_VERIFY_PARAM *param" +.Fa "const char *name" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set_flags +.Fa "X509_VERIFY_PARAM *param" +.Fa "unsigned long flags" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_clear_flags +.Fa "X509_VERIFY_PARAM *param" +.Fa "unsigned long flags" +.Fc +.Ft unsigned long +.Fo X509_VERIFY_PARAM_get_flags +.Fa "X509_VERIFY_PARAM *param" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set_purpose +.Fa "X509_VERIFY_PARAM *param" +.Fa "int purpose" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set_trust +.Fa "X509_VERIFY_PARAM *param" +.Fa "int trust" +.Fc +.Ft void +.Fo X509_VERIFY_PARAM_set_time +.Fa "X509_VERIFY_PARAM *param" +.Fa "time_t t" +.Fc +.Ft time_t +.Fo X509_VERIFY_PARAM_get_time +.Fa const X509_VERIFY_PARAM *param" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_add0_policy +.Fa "X509_VERIFY_PARAM *param" +.Fa "ASN1_OBJECT *policy" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1_policies +.Fa "X509_VERIFY_PARAM *param" +.Fa "STACK_OF(ASN1_OBJECT) *policies" +.Fc +.Ft void +.Fo X509_VERIFY_PARAM_set_depth +.Fa "X509_VERIFY_PARAM *param" +.Fa "int depth" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_get_depth +.Fa "const X509_VERIFY_PARAM *param" +.Fc +.Ft void +.Fo X509_VERIFY_PARAM_set_auth_level +.Fa "X509_VERIFY_PARAM *param" +.Fa "int auth_level" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1_host +.Fa "X509_VERIFY_PARAM *param" +.Fa "const char *name" +.Fa "size_t namelen" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_add1_host +.Fa "X509_VERIFY_PARAM *param" +.Fa "const char *name" +.Fa "size_t namelen" +.Fc +.Ft void +.Fo X509_VERIFY_PARAM_set_hostflags +.Fa "X509_VERIFY_PARAM *param" +.Fa "unsigned int flags" +.Fc +.Ft char * +.Fo X509_VERIFY_PARAM_get0_peername +.Fa "X509_VERIFY_PARAM *param" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1_email +.Fa "X509_VERIFY_PARAM *param" +.Fa "const char *email" +.Fa "size_t emaillen" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1_ip +.Fa "X509_VERIFY_PARAM *param" +.Fa "const unsigned char *ip" +.Fa "size_t iplen" +.Fc +.Ft int +.Fo X509_VERIFY_PARAM_set1_ip_asc +.Fa "X509_VERIFY_PARAM *param" +.Fa "const char *ipasc" +.Fc +.Sh DESCRIPTION +These functions manipulate an +.Vt X509_VERIFY_PARAM +object associated with a certificate verification operation. +.Pp +.Fn X509_VERIFY_PARAM_get0_name +returns the name of the given +.Fa param +object, usually describing its purpose, for example +.Qq default , +.Qq pkcs7 , +.Qq smime_sign , +.Qq ssl_client , +or +.Qq ssl_server . +For user-defined objects, the returned pointer may be +.Dv NULL +even if the object is otherwise valid. +.Pp +.Fn X509_VERIFY_PARAM_set1_name +sets the name of +.Fa param +to a copy of +.Fa name , +or to +.Dv NULL +if +.Fa name +is +.Dv NULL . +.Pp +.Fn X509_VERIFY_PARAM_set_flags +sets the flags in +.Fa param +by OR'ing it with +.Fa flags . +See the +.Sx VERIFICATION FLAGS +section for a complete description of values the +.Fa flags +parameter can take. +.Pp +If the +.Fa flags +argument includes any of the flags contained in +.Dv X509_V_FLAG_POLICY_MASK , +that is, any of +.Dv X509_V_FLAG_POLICY_CHECK , +.Dv X509_V_FLAG_EXPLICIT_POLICY , +.Dv X509_V_FLAG_INHIBIT_ANY , +and +.Dv X509_V_FLAG_INHIBIT_MAP , +then +.Dv X509_V_FLAG_POLICY_CHECK +is set in addition to the flags contained in the +.Fa flags +argument. +.Pp +.Fn X509_VERIFY_PARAM_get_flags +returns the flags in +.Fa param . +.Pp +.Fn X509_VERIFY_PARAM_clear_flags +clears the specified +.Fa flags +in +.Fa param . +.Pp +Calling this function can result in unusual internal states of the +.Fa param +object, for example having a verification time configured but having +.Dv X509_V_FLAG_USE_CHECK_TIME +unset, or having +.Dv X509_V_FLAG_EXPLICIT_POLICY +set but +.Dv X509_V_FLAG_POLICY_CHECK +unset, which may have surprising effects. +.Pp +.Fn X509_VERIFY_PARAM_set_purpose +sets the verification +.Fa purpose +identifier in +.Fa param . +This determines the acceptable purpose of the certificate chain, for example +.Dv X509_PURPOSE_SSL_CLIENT +or +.Dv X509_PURPOSE_SSL_SERVER . +Standard purposes are listed in +.Xr X509_check_purpose 3 , +and additional purposes can be defined with +.Xr X509_PURPOSE_add 3 . +.Pp +.Fn X509_VERIFY_PARAM_set_trust +sets the trust setting in +.Fa param +to +.Fa trust . +.Pp +.Fn X509_VERIFY_PARAM_set_time +sets the flag +.Dv X509_V_FLAG_USE_CHECK_TIME +in +.Fa param +in addition to the flags already set and sets the verification time to +.Fa t . +If this function is not called, the current time is used instead, +or the UNIX Epoch (January 1, 1970) if +.Dv X509_V_FLAG_USE_CHECK_TIME +is manually set using +.Fn X509_VERIFY_PARAM_set_flags . +.Pp +.Fn X509_VERIFY_PARAM_add0_policy +enables policy checking (it is disabled by default) and adds +.Fa policy +to the acceptable policy set. +.Pp +.Fn X509_VERIFY_PARAM_set1_policies +enables policy checking (it is disabled by default) and sets the +acceptable policy set to +.Fa policies . +Any existing policy set is cleared. +The +.Fa policies +parameter can be +.Dv NULL +to clear an existing policy set. +.Pp +.Fn X509_VERIFY_PARAM_set_depth +sets the maximum verification depth to +.Fa depth . +That is the maximum number of untrusted CA certificates that can appear +in a chain. +.Pp +.Fn X509_VERIFY_PARAM_set_auth_level +sets the security level as defined in +.Xr SSL_CTX_set_security_level 3 +for certificate chain validation. +For a certificate chain to validate, the public keys of all the +certificates must meet the specified security level. +The signature algorithm security level is not enforced for the +chain's trust anchor certificate, which is either directly trusted +or validated by means other than its signature. +.Pp +From the point of view of the X.509 library, +the default security level is 0. +However, the SSL library +uses a different default security level of 1 and calls +.Fn X509_VERIFY_PARAM_set_auth_level +with its own level before validating a certificate chain. +.Pp +.Fn X509_VERIFY_PARAM_set1_host +sets the expected DNS hostname to +.Fa name +clearing any previously specified hostname or names. +If +.Fa name +is +.Dv NULL +or empty, the list of hostnames is cleared, and name checks are not +performed on the peer certificate. +.Fa namelen +should be set to the length of +.Fa name . +For historical compatibility, if +.Fa name +is NUL-terminated, +.Fa namelen +may be specified as zero. +When a hostname is specified, certificate verification automatically +invokes +.Xr X509_check_host 3 +with flags equal to the +.Fa flags +argument given to +.Fn X509_VERIFY_PARAM_set_hostflags +(default zero). +.Fn X509_VERIFY_PARAM_set1_host +will fail if +.Fa name +contains any embedded 0 bytes. +.Pp +.Fn X509_VERIFY_PARAM_add1_host +adds +.Fa name +as an additional reference identifier that can match the peer's +certificate. +Any previous names set via +.Fn X509_VERIFY_PARAM_set1_host +and +.Fn X509_VERIFY_PARAM_add1_host +are retained. +No change is made if +.Fa name +is +.Dv NULL +or empty. +.Fa namelen +should be set to the length of +.Fa name . +For historical compatibility, if +.Fa name +is NUL-terminated, +.Fa namelen +may be specified as zero. +.Fn X509_VERIFY_PARAM_add1_host +will fail if +.Fa name +contains any embedded 0 bytes. +When multiple names are configured, the peer is considered verified when +any name matches. +.Pp +.Fn X509_VERIFY_PARAM_get0_peername +returns the DNS hostname or subject CommonName from the peer certificate +that matched one of the reference identifiers. +When wildcard matching is not disabled, or when a reference identifier +specifies a parent domain (starts with ".") rather than a hostname, the +peer name may be a wildcard name or a sub-domain of the reference +identifier respectively. +.Pp +.Fn X509_VERIFY_PARAM_set1_email +sets the expected RFC 822 email address to +.Fa email . +.Fa emaillen +should be set to the length of +.Fa email . +For historical compatibility, if +.Fa email +is NUL-terminated, +.Fa emaillen +may be specified as zero, +.Fn X509_VERIFY_PARAM_set1_email +will fail if +.Fa email +is NULL, an empty string, or contains embedded 0 bytes. +When an email address is specified, certificate verification +automatically invokes +.Xr X509_check_email 3 . +.Pp +.Fn X509_VERIFY_PARAM_set1_ip +sets the expected IP address to +.Fa ip . +The +.Fa ip +argument is in binary format, in network byte-order, and +.Fa iplen +must be set to 4 for IPv4 and 16 for IPv6. +.Fn X509_VERIFY_PARAM_set1_ip +will fail if +.Fa ip +is NULL or if +.Fa iplen +is not 4 or 16. +When an IP address is specified, +certificate verification automatically invokes +.Xr X509_check_ip 3 . +.Pp +.Fn X509_VERIFY_PARAM_set1_ip_asc +sets the expected IP address to +.Fa ipasc . +The +.Fa ipasc +argument is a NUL-terminal ASCII string: +dotted decimal quad for IPv4 and colon-separated hexadecimal for IPv6. +The condensed "::" notation is supported for IPv6 addresses. +.Fn X509_VERIFY_PARAM_set1_ip_asc +will fail if +.Fa ipasc +is unparsable. +.Sh RETURN VALUES +.Fn X509_VERIFY_PARAM_set1_name , +.Fn X509_VERIFY_PARAM_set_flags , +.Fn X509_VERIFY_PARAM_clear_flags , +.Fn X509_VERIFY_PARAM_set_purpose , +.Fn X509_VERIFY_PARAM_set_trust , +.Fn X509_VERIFY_PARAM_add0_policy , +and +.Fn X509_VERIFY_PARAM_set1_policies +return 1 for success or 0 for failure. +.Pp +.Fn X509_VERIFY_PARAM_set1_host , +.Fn X509_VERIFY_PARAM_add1_host , +.Fn X509_VERIFY_PARAM_set1_email , +.Fn X509_VERIFY_PARAM_set1_ip , +and +.Fn X509_VERIFY_PARAM_set1_ip_asc +return 1 for success or 0 for failure. +A failure from these routines will poison +the +.Vt X509_VERIFY_PARAM +object so that future calls to +.Xr X509_verify_cert 3 +using the poisoned object will fail. +.Pp +.Fn X509_VERIFY_PARAM_get_flags +returns the current verification flags. +.Pp +.Fn X509_VERIFY_PARAM_get_time +always returns the configured verification time. +It does so even if the returned time will not be used because the flag +.Dv X509_V_FLAG_USE_CHECK_TIME +is unset. +.Pp +.Fn X509_VERIFY_PARAM_get_depth +returns the current verification depth. +.Pp +.Fn X509_VERIFY_PARAM_get0_name +and +.Fn X509_VERIFY_PARAM_get0_peername +return pointers to strings that are only valid +during the lifetime of the given +.Fa param +object and that must not be freed by the application program. +.Sh VERIFICATION FLAGS +The verification flags consists of zero or more of the following +flags OR'ed together. +.Pp +.Dv X509_V_FLAG_CRL_CHECK +enables CRL checking for the certificate chain leaf certificate. +An error occurs if a suitable CRL cannot be found. +.Pp +.Dv X509_V_FLAG_CRL_CHECK_ALL +enables CRL checking for the entire certificate chain. +.Pp +.Dv X509_V_FLAG_IGNORE_CRITICAL +disables critical extension checking. +By default any unhandled critical extensions in certificates or (if +checked) CRLs results in a fatal error. +If this flag is set, unhandled critical extensions are ignored. +.Sy WARNING : +setting this option for anything other than debugging purposes can be a +security risk. +Finer control over which extensions are supported can be performed in +the verification callback. +.Pp +The +.Dv X509_V_FLAG_X509_STRICT +flag disables workarounds for some broken certificates and makes the +verification strictly apply X509 rules. +.Pp +.Dv X509_V_FLAG_ALLOW_PROXY_CERTS +deprecated flag that used to +enable proxy certificate verification. +In LibreSSL, this flag has no effect. +.Pp +.Dv X509_V_FLAG_POLICY_CHECK +enables certificate policy checking; by default no policy checking is +performed. +Additional information is sent to the verification callback relating to +policy checking. +.Pp +.Dv X509_V_FLAG_EXPLICIT_POLICY , +.Dv X509_V_FLAG_INHIBIT_ANY , +and +.Dv X509_V_FLAG_INHIBIT_MAP +set the +.Dq require explicit policy , +.Dq inhibit any policy , +and +.Dq inhibit policy mapping +flags, respectively, as defined in RFC 3280. +These three flags are ignored unless +.Dv X509_V_FLAG_POLICY_CHECK +is also set. +.Pp +If +.Dv X509_V_FLAG_NOTIFY_POLICY +is set and policy checking is successful, a special status code is +sent to the verification callback. +.Pp +By default some additional features such as indirect CRLs and CRLs +signed by different keys are disabled. +If +.Dv X509_V_FLAG_EXTENDED_CRL_SUPPORT +is set, they are enabled. +.Pp +If +.Dv X509_V_FLAG_USE_DELTAS +is set, delta CRLs (if present) are used to determine certificate +status. +If not set, deltas are ignored. +.Pp +.Dv X509_V_FLAG_CHECK_SS_SIGNATURE +enables checking of the root CA self signed certificate signature. +By default this check is disabled because it doesn't add any additional +security but in some cases applications might want to check the +signature anyway. +A side effect of not checking the root CA signature is that disabled or +unsupported message digests on the root CA are not treated as fatal +errors. +.Pp +The deprecated +.Dv X509_V_FLAG_CB_ISSUER_CHECK +flag used to enable debugging of certificate issuer checks. +It is provided for binary backwards compatibility and has no effect. +.Pp +When +.Dv X509_V_FLAG_TRUSTED_FIRST +is set, construction of the certificate chain in +.Xr X509_verify_cert 3 +will search the trust store for issuer certificates before searching the +provided untrusted certificates. +Local issuer certificates are often more likely to satisfy local +security requirements and lead to a locally trusted root. +This is especially important when some certificates in the trust store +have explicit trust settings; see the trust settings options of the +.Cm x509 +command in +.Xr openssl 1 . +.Pp +The +.Dv X509_V_FLAG_NO_ALT_CHAINS +flag suppresses checking for alternative chains. +By default, unless +.Dv X509_V_FLAG_TRUSTED_FIRST +is set, when building a certificate chain, if the first certificate +chain found is not trusted, then OpenSSL will attempt to replace +untrusted certificates supplied by the peer with certificates from the +trust store to see if an alternative chain can be found that is trusted. +.Pp +The +.Dv X509_V_FLAG_PARTIAL_CHAIN +flag causes intermediate certificates in the trust store to be treated +as trust-anchors, in the same way as the self-signed root CA +certificates. +This makes it possible to trust certificates issued by an intermediate +CA without having to trust its ancestor root CA. +.Pp +If +.Dv X509_V_FLAG_USE_CHECK_TIME +is set, the validity period of certificates and CRLs is checked. +In this case, +.Dv X509_V_FLAG_NO_CHECK_TIME +is ignored. +If the validation time was set with +.Fn X509_VERIFY_PARAM_set_time , +that time is used. +If +.Fn X509_VERIFY_PARAM_set_time +was not called, the UNIX Epoch (January 1, 1970) is used. +.Pp +If neither +.Dv X509_V_FLAG_USE_CHECK_TIME +nor +.Dv X509_V_FLAG_NO_CHECK_TIME +is set, the validity period of certificates and CRLs is checked +using the current time. +This is the default behaviour. +In this case, if a validation time was set with +.Fn X509_VERIFY_PARAM_set_time +but +.Dv X509_V_FLAG_USE_CHECK_TIME +was later cleared with +.Fn X509_VERIFY_PARAM_clear_flags , +the configured validation time is ignored +and the current time is used anyway. +.Pp +If +.Dv X509_V_FLAG_USE_CHECK_TIME +is not set but +.Dv X509_V_FLAG_NO_CHECK_TIME +is set, the validity period of certificates and CRLs is not checked +at all, and like in the previous case, any configured validation +time is ignored. +.Sh EXAMPLES +Enable CRL checking when performing certificate verification during +SSL connections associated with an +.Vt SSL_CTX +structure +.Fa ctx : +.Bd -literal -offset indent +X509_VERIFY_PARAM *param; + +param = X509_VERIFY_PARAM_new(); +X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); +SSL_CTX_set1_param(ctx, param); +X509_VERIFY_PARAM_free(param); +.Ed +.Sh SEE ALSO +.Xr SSL_set1_host 3 , +.Xr SSL_set1_param 3 , +.Xr X509_check_host 3 , +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_new 3 , +.Xr X509_verify_cert 3 , +.Xr X509_VERIFY_PARAM_new 3 +.Sh HISTORY +.Fn X509_VERIFY_PARAM_set1_name , +.Fn X509_VERIFY_PARAM_set_flags , +.Fn X509_VERIFY_PARAM_set_purpose , +.Fn X509_VERIFY_PARAM_set_trust , +.Fn X509_VERIFY_PARAM_set_time , +.Fn X509_VERIFY_PARAM_add0_policy , +.Fn X509_VERIFY_PARAM_set1_policies , +.Fn X509_VERIFY_PARAM_set_depth , +and +.Fn X509_VERIFY_PARAM_get_depth +first appeared in OpenSSL 0.9.8. +.Fn X509_VERIFY_PARAM_clear_flags +and +.Fn X509_VERIFY_PARAM_get_flags +first appeared in OpenSSL 0.9.8a. +All these functions have been available since +.Ox 4.5 . +.Pp +.Fn X509_VERIFY_PARAM_get0_name , +.Fn X509_VERIFY_PARAM_set1_host , +.Fn X509_VERIFY_PARAM_add1_host , +.Fn X509_VERIFY_PARAM_set_hostflags , +.Fn X509_VERIFY_PARAM_get0_peername , +.Fn X509_VERIFY_PARAM_set1_email , +.Fn X509_VERIFY_PARAM_set1_ip , +and +.Fn X509_VERIFY_PARAM_set1_ip_asc +first appeared in OpenSSL 1.0.2 and have been available since +.Ox 6.3 . +.Pp +.Fn X509_VERIFY_PARAM_set_auth_level +first appeared in OpenSSL 1.1.0 and +.Fn X509_VERIFY_PARAM_get_time +in OpenSSL 1.1.0d. +Both functions have been available since +.Ox 7.2 . +.Sh BUGS +Delta CRL checking is currently primitive. +Only a single delta can be used and (partly due to limitations of +.Vt X509_STORE ) +constructed CRLs are not maintained. +.Pp +If CRLs checking is enabled, CRLs are expected to be available in +the corresponding +.Vt X509_STORE +structure. +No attempt is made to download CRLs from the CRL distribution points +extension. diff --git a/Libraries/libressl/man/X509_add1_trust_object.3 b/Libraries/libressl/man/X509_add1_trust_object.3 new file mode 100644 index 000000000..e1e382420 --- /dev/null +++ b/Libraries/libressl/man/X509_add1_trust_object.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: X509_add1_trust_object.3,v 1.3 2021/07/24 14:33:14 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 24 2021 $ +.Dt X509_ADD1_TRUST_OBJECT 3 +.Os +.Sh NAME +.Nm X509_add1_trust_object , +.Nm X509_trust_clear , +.Nm X509_add1_reject_object , +.Nm X509_reject_clear +.Nd mark an X.509 certificate as intended for a specific purpose +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_add1_trust_object +.Fa "X509 *x" +.Fa "const ASN1_OBJECT *purpose" +.Fc +.Ft void +.Fo X509_trust_clear +.Fa "X509 *x" +.Fc +.Ft int +.Fo X509_add1_reject_object +.Fa "X509 *x" +.Fa "const ASN1_OBJECT *purpose" +.Fc +.Ft void +.Fo X509_reject_clear +.Fa "X509 *x" +.Fc +.Sh DESCRIPTION +.Fn X509_add1_trust_object +appends a deep copy of the +.Fa purpose +object to the set of intended purposes that +.Fa x +contains as non-standard auxiliary data. +The function +.Xr OBJ_nid2obj 3 +can be used to create appropriate purpose objects from the +.Dv NID_* +constants mentioned in +.Xr X509_check_purpose 3 , +even though the +.Dv X509_PURPOSE_* +constants listed in that manual page are not intended for use with +.Fn X509_add1_trust_object . +.Pp +.Fn X509_trust_clear +frees and removes all purpose objects from the set of intended +purposes in the non-standard auxiliary data of +.Fa x . +.Pp +.Fn X509_add1_reject_object +and +.Fn X509_reject_clear +are similar except that they operate on a set of unintended purposes. +.Pp +As an alternative to using the functions documented in the present +manual page, X.509 certificate extensions can be used. +At the price of higher complexity, those allow storing the purpose +inside the certificate itself in a standard-conforming way rather than +merely in non-standard auxiliary data associated with the certificate. +See +.Xr EXTENDED_KEY_USAGE_new 3 +for details. +.Sh RETURN VALUES +.Fn X509_add1_trust_object +and +.Fn X509_add1_reject_object +return the new number of purposes in the respective set +or 0 if an error occurs, in particular if memory +allocation fails or if +.Fa x +does not contain a sub-object that can hold non-standard auxiliary data. +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr OBJ_nid2obj 3 , +.Xr X509_CERT_AUX_new 3 , +.Xr X509_check_trust 3 , +.Xr X509_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.4 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_check_ca.3 b/Libraries/libressl/man/X509_check_ca.3 new file mode 100644 index 000000000..114bac69e --- /dev/null +++ b/Libraries/libressl/man/X509_check_ca.3 @@ -0,0 +1,117 @@ +.\" $OpenBSD: X509_check_ca.3,v 1.7 2022/05/10 19:44:29 tb Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Victor B. Wagner . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 10 2022 $ +.Dt X509_CHECK_CA 3 +.Os +.Sh NAME +.Nm X509_check_ca +.Nd check whether a certificate is a CA certificate +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509_check_ca +.Fa "X509 *cert" +.Fc +.Sh DESCRIPTION +The +.Fn X509_check_ca +function checks whether the given certificate is a CA certificate, +that is, whether it can be used to sign other certificates. +.Sh RETURN VALUES +If +.Fa cert +is a CA certificate, a non-zero value is returned; 0 otherwise. +.Pp +The following return values identify specific kinds of CA certificates: +.Bl -tag -width 2n +.It 1 +an X.509 v3 CA certificate with +.Sy basicConstraints +extension CA:TRUE +.It 3 +a self-signed X.509 v1 certificate +.It 4 +a certificate with +.Sy keyUsage +extension with bit +.Sy keyCertSign +set, but without +.Sy basicConstraints +.It 5 +a certificate with an outdated Netscape Certificate Type extension telling +that it is a CA certificate +.El +.Sh SEE ALSO +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr X509_check_issued 3 , +.Xr X509_check_purpose 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_check_ca +first appeared in OpenSSL 0.9.7f and has been available since +.Ox 3.8 . +.Sh BUGS +If +.Fn X509_check_ca +fails to cache X509v3 extension values, the return value may +be incorrect. +An application should +call +.Xr X509_check_purpose 3 +with a +.Fa purpose +argument of \-1, +ensuring that the X509v3 extensions are cached, +before calling +.Fn X509_check_ca . diff --git a/Libraries/libressl/man/X509_check_host.3 b/Libraries/libressl/man/X509_check_host.3 new file mode 100644 index 000000000..dbc56c0d2 --- /dev/null +++ b/Libraries/libressl/man/X509_check_host.3 @@ -0,0 +1,246 @@ +.\" $OpenBSD: X509_check_host.3,v 1.6 2020/09/17 08:04:22 schwarze Exp $ +.\" full merge up to: OpenSSL a09e4d24 Jun 12 01:56:31 2014 -0400 +.\" selective merge up to: OpenSSL 6328d367 Jul 4 21:58:30 2020 +0200 +.\" +.\" This file was written by Florian Weimer and +.\" Viktor Dukhovni . +.\" Copyright (c) 2012, 2014, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 17 2020 $ +.Dt X509_CHECK_HOST 3 +.Os +.Sh NAME +.Nm X509_check_host , +.Nm X509_check_email , +.Nm X509_check_ip , +.Nm X509_check_ip_asc +.Nd X.509 certificate matching +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509_check_host +.Fa "X509 *x" +.Fa "const char *name" +.Fa "size_t namelen" +.Fa "unsigned int flags" +.Fa "char **peername" +.Fc +.Ft int +.Fo X509_check_email +.Fa "X509 *x" +.Fa "const char *address" +.Fa "size_t addresslen" +.Fa "unsigned int flags" +.Fc +.Ft int +.Fo X509_check_ip +.Fa "X509 *x" +.Fa "const unsigned char *address" +.Fa "size_t addresslen" +.Fa "unsigned int flags" +.Fc +.Ft int +.Fo X509_check_ip_asc +.Fa "X509 *x" +.Fa "const char *address" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +The certificate matching functions are used to check whether a +certificate matches a given hostname, email address, or IP address. +The validity of the certificate and its trust level has to be checked by +other means. +.Pp +.Fn X509_check_host +checks if the certificate Subject Alternative Name (SAN) or Subject +CommonName (CN) matches the specified hostname, which must be encoded +in the preferred name syntax described in section 3.5 of RFC 1034. +By default, wildcards are supported and they match only in the +left-most label; they may match part of that label with an +explicit prefix or suffix. +For example, by default, the host +.Fa name +.Qq www.example.com +would match a certificate with a SAN or CN value of +.Qq *.example.com , +.Qq w*.example.com +or +.Qq *w.example.com . +.Pp +Per section 6.4.2 of RFC 6125, +.Fa name +values representing international domain names must be given in A-label +form. +The +.Fa namelen +argument must be the number of characters in the name string or zero, in +which case the length is calculated with +.Fn strlen name . +When +.Fa name +starts with a dot (e.g.\& +.Qq .example.com ) , +it will be matched by a certificate valid for any sub-domain of +.Fa name ; +see also +.Fa X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS +below. +.Pp +When the certificate is matched and +.Fa peername +is not +.Dv NULL , +a pointer to a copy of the matching SAN or CN from the peer +certificate is stored at the address passed in +.Fa peername . +The application is responsible for freeing the peername via +.Xr free 3 +when it is no longer needed. +.Pp +.Fn X509_check_email +checks if the certificate matches the specified email +.Fa address . +Only the mailbox syntax of RFC 822 is supported. +Comments are not allowed, +and no attempt is made to normalize quoted characters. +The +.Fa addresslen +argument must be the number of characters in the address string or zero, +in which case the length is calculated with +.Fn strlen address . +.Pp +.Fn X509_check_ip +checks if the certificate matches a specified IPv4 or IPv6 address. +The +.Fa address +array is in binary format, in network byte order. +The length is either 4 (IPv4) or 16 (IPv6). +Only explicitly marked addresses in the certificates are considered; +IP addresses stored in DNS names and Common Names are ignored. +.Pp +.Fn X509_check_ip_asc +is similar, except that the NUL-terminated string +.Fa address +is first converted to the internal representation. +.Pp +The +.Fa flags +argument is usually 0, but it can be the bitwise OR of the following +flags. +.Pp +The +.Dv X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT +flag causes the function to consider the subject DN even if the +certificate contains at least one subject alternative name of the right +type (DNS name or email address as appropriate); the default is to +ignore the subject DN when at least one corresponding subject +alternative names is present. +.Pp +The remaining flags are only meaningful for +.Fn X509_check_host . +.Pp +The +.Dv X509_CHECK_FLAG_NO_WILDCARDS +flag disables wildcard expansion. +.Pp +The +.Dv X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS +flag suppresses support for +.Qq * +as a wildcard pattern in labels that have a +prefix or suffix, such as +.Qq www* +or +.Qq *www . +.Pp +The +.Dv X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS +flag allows a +.Qq * +that constitutes the complete label of a DNS name (e.g.\& +.Qq *.example.com ) +to match more than one label in +.Fa name . +.Pp +The +.Dv X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS +flag restricts +.Fa name +values which start with +.Qq \&. , +that would otherwise match any sub-domain in the peer certificate, +to only match direct child sub-domains. +Thus, for instance, with this flag set a +.Fa name +of +.Qq .example.com +would match a peer certificate with a DNS name of +.Qq www.example.com , +but would not match a peer certificate with a DNS name of +.Qq www.sub.example.com . +.Sh RETURN VALUES +The functions return 1 for a successful match, 0 for a failed match and +-1 for an internal error: typically a memory allocation failure or an +ASN.1 decoding error. +.Pp +All functions can also return -2 if the input is malformed. +For example, +.Fn X509_check_host +returns -2 if the provided +.Fa name +contains embedded NUL bytes. +.Sh SEE ALSO +.Xr SSL_set1_host 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get1_email 3 , +.Xr X509_new 3 , +.Xr X509_VERIFY_PARAM_set1_host 3 +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.2 +and have been available since +.Ox 6.1 . diff --git a/Libraries/libressl/man/X509_check_issued.3 b/Libraries/libressl/man/X509_check_issued.3 new file mode 100644 index 000000000..f8c2a5297 --- /dev/null +++ b/Libraries/libressl/man/X509_check_issued.3 @@ -0,0 +1,109 @@ +.\" $OpenBSD: X509_check_issued.3,v 1.4 2019/06/06 01:06:59 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Victor B. Wagner . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt X509_CHECK_ISSUED 3 +.Os +.Sh NAME +.Nm X509_check_issued +.Nd check whether a certificate was issued using a given CA certificate +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509_check_issued +.Fa "X509 *issuer" +.Fa "X509 *subject" +.Fc +.Sh DESCRIPTION +This function checks whether the certificate +.Fa subject +was issued using the CA certificate +.Fa issuer . +It does the following checks: +.Bl -bullet +.It +match the issuer field of +.Fa subject +against the subject field of +.Fa issuer +.It +if +.Sy authorityKeyIdentifier +is present in the +.Fa subject +certificate, +compare it to the +.Sy subjectKeyIdentifier +of +.Fa issuer +.It +check the +.Sy keyUsage +field of +.Fa issuer . +.El +.Sh RETURN VALUES +This function returns +.Dv X509_V_OK +if the certificate +.Fa subject +is issued by +.Fa issuer , +or some +.Dv X509_V_ERR* +constant to indicate an error. +.Sh SEE ALSO +.Xr X509_check_ca 3 , +.Xr X509_new 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_check_issued +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . diff --git a/Libraries/libressl/man/X509_check_private_key.3 b/Libraries/libressl/man/X509_check_private_key.3 new file mode 100644 index 000000000..31df2126c --- /dev/null +++ b/Libraries/libressl/man/X509_check_private_key.3 @@ -0,0 +1,73 @@ +.\" $OpenBSD: X509_check_private_key.3,v 1.6 2019/06/06 01:06:59 schwarze Exp $ +.\" OpenSSL X509_check_private_key.pod 09ddb878 Jun 5 03:56:07 2017 +0800 +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt X509_CHECK_PRIVATE_KEY 3 +.Os +.Sh NAME +.Nm X509_check_private_key , +.Nm X509_REQ_check_private_key +.Nd compare public key components +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_check_private_key +.Fa "const X509 *x" +.Fa "const EVP_PKEY *k" +.Fc +.Ft int +.Fo X509_REQ_check_private_key +.Fa "X509_REQ *x" +.Fa "EVP_PKEY *k" +.Fc +.Sh DESCRIPTION +These functions are seriously misnamed. +.Fn X509_check_private_key +compares the +.Em public +key components (e.g. exponent and modulus of an RSA key) +and parameters (e.g. EC params of an EC key) of +.Fa k +with the corresponding properties of +.Fa x . +Despite the name, it neither checks whether +.Fa k +contains private key components at all, nor, if any are present, +whether they are consistent with the public key components. +.Pp +.Fn X509_REQ_check_private_key +is equivalent to +.Fn X509_check_private_key +except that it compares to the public key +contained in a certificate request. +.Sh RETURN VALUES +These functions return 1 if the public key components and parameters +match, or 0 if they do not or if an error occurs. +On error or mismatch, a reason code can be obtained using +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr SSL_check_private_key 3 , +.Xr X509_new 3 , +.Xr X509_REQ_new 3 +.Sh HISTORY +.Fn X509_check_private_key +first appeared in SSLeay 0.6.5 and has been available since +.Ox 2.4 . +.Pp +.Fn X509_REQ_check_private_key +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/X509_check_purpose.3 b/Libraries/libressl/man/X509_check_purpose.3 new file mode 100644 index 000000000..ebd627bd5 --- /dev/null +++ b/Libraries/libressl/man/X509_check_purpose.3 @@ -0,0 +1,432 @@ +.\" $OpenBSD: X509_check_purpose.3,v 1.11 2023/06/25 13:54:58 tb Exp $ +.\" +.\" Copyright (c) 2019, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 25 2023 $ +.Dt X509_CHECK_PURPOSE 3 +.Os +.Sh NAME +.Nm X509_check_purpose +.Nd check intended usage of a public key +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509_check_purpose +.Fa "X509 *certificate" +.Fa "int purpose" +.Fa "int ca" +.Fc +.Sh DESCRIPTION +If the +.Fa purpose +argument is \-1, +.Fn X509_check_purpose +ignores the +.Fa ca +argument and checks that all the extensions of the +.Fa certificate +can be parsed and pass minimal sanity checks, ensuring that +no extension occurs more than once. +It also makes sure that all extensions are cached in the +.Vt X509 +object. +.Pp +If the +.Fa purpose +argument is not \-1 and the +.Fa ca +flag is 0, +.Fn X509_check_purpose +also checks whether the public key contained in the +.Fa certificate +is intended to be used for the given +.Fa purpose , +which can be one of the following integer constants. +The check succeeds if none of the conditions given in the list below +are violated. +It always fails if parsing fails for any extension contained in the +.Fa certificate . +.Bl -tag -width 1n +.It Dv X509_PURPOSE_SSL_CLIENT +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq TLS WWW client authentication +purpose +.Pq Dv NID_client_auth . +.It +If the +.Fa certificate +contains a Key Usage extension, the +.Dv digitalSignature +bit is set. +.It +If the +.Fa certificate +contains a Netscape Cert Type extension, the +.Dq SSL client certificate +bit is set +.Pq Dv NS_SSL_CLIENT . +.El +.It Dv X509_PURPOSE_SSL_SERVER +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq TLS WWW server authentication +purpose +.Pq Dv NID_server_auth +or the private +.Dq Netscape Server Gated Crypto +.Pq Dv NID_ns_sgc +or +.Dq Microsoft Server Gated Crypto +.Pq Dv NID_ms_sgc +purpose. +.It +If the +.Fa certificate +contains a Key Usage extension, at least one of the +.Dv digitalSignature +and +.Dv keyEncipherment +bits is set. +.It +If the +.Fa certificate +contains a Netscape Cert Type extension, the +.Dq SSL server certificate +bit is set +.Pq Dv NS_SSL_SERVER +.El +.It Dv X509_PURPOSE_NS_SSL_SERVER +.\" check_purpose_ns_ssl_server, "Netscape SSL server" +This does the same checks as +.Dv X509_PURPOSE_SSL_SERVER +and additionally requires that a Key Usage extension, if present, +has the +.Dv keyEncipherment +bit set. +.It Dv X509_PURPOSE_SMIME_SIGN +.\" check_purpose_smime_sign, "S/MIME signing" +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq Email protection +purpose +.Pq Dv NID_email_protect . +.It +If the +.Fa certificate +contains a Key Usage extension, at least one of the +.Dv digitalSignature +and +.Dv nonRepudiation +bits is set. +.It +If the +.Fa certificate +contains a Netscape Cert Type extension, it has the +.Dq S/MIME certificate +bit set. +If the +.Dq SSL client certificate +bit is set but the +.Dq S/MIME certificate +bit is not, no decision is made. +.El +.It Dv X509_PURPOSE_SMIME_ENCRYPT +.\" check_purpose_smime_encrypt, "S/MIME encryption" +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq Email protection +purpose +.Pq Dv NID_email_protect . +.It +If the +.Fa certificate +contains a Key Usage extension, the +.Dv keyEncipherment +bit is set. +.It +If the +.Fa certificate +contains a Netscape Cert Type extension, it has the +.Dq S/MIME certificate +bit set. +If the +.Dq SSL client certificate +bit is set but the +.Dq S/MIME certificate +bit is not, no decision is made. +.El +.It Dv X509_PURPOSE_CRL_SIGN +.\" check_purpose_crl_sign, "CRL signing" +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains a Key Usage extension, the +.Dv cRLSign +bit is set. +.El +.It Dv X509_PURPOSE_ANY +Nothing is required except that, if any extensions are present, +parsing them needs to succeed. +.It Dv X509_PURPOSE_OCSP_HELPER +.\" ocsp_helper, "OCSP helper" +Nothing is required except that, if any extensions are present, +parsing them needs to succeed. +The application program is expected +to do the actual checking by other means. +.It Dv X509_PURPOSE_TIMESTAMP_SIGN +.\" check_purpose_timestamp_sign, "Time Stamp signing" +.Bl -dash -width 1n -compact +.It +The +.Fa certificate +contains an Extended Key Usage extension containing the RFC 5280 +.Dq Time Stamping +purpose and no other purpose. +This extension is marked as critical. +.It +If the +.Fa certificate +contains a Key Usage extension, at least one of the +.Dv digitalSignature +and +.Dv nonRepudiation +bits is set, and no other bits are set. +.El +.El +.Pp +If the +.Fa purpose +argument is not \-1 and the +.Fa ca +flag is non-zero, +.Fn X509_check_purpose +instead checks, in addition to the minimal sanity checks, whether the +.Fa certificate +can be used as a certificate authority certificate +in the context of the given +.Fa purpose . +To succeed, the check always requires that none of the following +conditions are violated: +.Pp +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains any extensions, parsing them succeeds. +.It +If the +.Fa certificate +contains a Key Usage extension, the +.Dv keyCertSign +bit is set. +.It +If the +.Fa certificate +contains a Basic Constraints extension, the +.Fa cA +field is set. +.It +If the +.Fa certificate +is a version 1 certificate, the subject name matches the issuer name +and the certificate is self signed. +.El +.Pp +The check succeeds if none of the additional conditions given in +the list below are violated. +.Bl -tag -width 1n +.It Dv X509_PURPOSE_SSL_CLIENT +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq TLS WWW client authentication +purpose +.Pq Dv NID_client_auth . +.It +If the +.Fa certificate +is not a version 1 certificate and does not contain a Basic Constraints +extension, it contains a Key Usage extension with the +.Dv keyCertSign +bit set or a Netscape Cert Type extension with the +.Dq SSL CA certificate +bit set. +.El +.It Dv X509_PURPOSE_SSL_SERVER No or Dv X509_PURPOSE_NS_SSL_SERVER +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq TLS WWW server authentication +purpose +.Pq Dv NID_server_auth +or the private +.Dq Netscape Server Gated Crypto +.Pq Dv NID_ns_sgc +or +.Dq Microsoft Server Gated Crypto +.Pq Dv NID_ms_sgc +purpose. +.It +If the +.Fa certificate +is not a version 1 certificate and does not contain a Basic Constraints +extension, it contains a Key Usage extension with the +.Dv keyCertSign +bit set or a Netscape Cert Type extension with the +.Dq SSL CA certificate +bit set. +.El +.It Dv X509_PURPOSE_SMIME_SIGN No or Dv X509_PURPOSE_SMIME_ENCRYPT +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +contains an Extended Key Usage extension, it contains the RFC 5280 +.Dq Email protection +purpose +.Pq Dv NID_email_protect . +.It +If the +.Fa certificate +is not a version 1 certificate and does not contain a Basic Constraints +extension, it contains a Key Usage extension with the +.Dv keyCertSign +bit set or a Netscape Cert Type extension with the +.Dq S/MIME CA certificate +bit set. +.El +.It Xo +.Dv X509_PURPOSE_CRL_SIGN , +.Dv X509_PURPOSE_OCSP_HELPER , +or +.Dv X509_PURPOSE_TIMESTAMP_SIGN +.Xc +.Bl -dash -width 1n -compact +.It +If the +.Fa certificate +is not a version 1 certificate and does not contain a Basic Constraints +extension, it contains a Key Usage extension with the +.Dv keyCertSign +bit set or a Netscape Cert Type extension with at least one of the +.Dq SSL CA certificate , +.Dq S/MIME CA certificate , +or +.Dq Object-signing CA certificate +bits set. +.El +.It Dv X509_PURPOSE_ANY +Nothing is required except that, if any extensions are present, +parsing them needs to succeed. +The check even succeeds if the three other common conditions +cited above this list are violated. +.El +.Pp +If the function +.Xr X509_PURPOSE_add 3 +was called before +.Fn X509_check_purpose , +it may have installed different, user-supplied checking functions +for some of the standard purposes listed above, or it may have +installed additional, user-supplied checking functions for user-defined +.Fa purpose +identifiers not listed above. +.Sh RETURN VALUES +If the parsing of certificate extensions fails, sanity checks fail or the +.Fa purpose +is invalid, +.Fn X509_check_purpose +returns \-1 to indicate the error. +.Pp +If the +.Fa purpose +argument is \-1 and parsing and minimal sanity checks succeed, +.Fn X509_check_purpose +returns 1 to indicate success. +.Pp +Otherwise, it returns the following values: +.Pp +If +.Fa ca +is 0: +.Bl -column -1 Failure -compact +.It 0 Ta Failure Ta The +.Fa certificate +cannot be used for the +.Fa purpose . +.It 1 Ta Success Ta The +.Fa certificate +can be used for the +.Fa purpose . +.It 2 Ta Unknown Ta \&No decision can be made. +.El +.Pp +If +.Fa ca +is non-zero: +.Bl -column -1 Failure -compact +.It 0 Ta Failure Ta The +.Fa certificate +cannot be used as a CA for the +.Fa purpose . +.It 1 Ta Success Ta The +.Fa certificate +can be used as a CA for the +.Fa purpose . +.It 3 Ta Success Ta The Fa certificate No is a version 1 CA . +.It 4 Ta Success Ta The Key Usage allows Dv keyCertSign . +.It 5 Ta Success Ta A Netscape Cert Type allows usage as a CA. +.El +.Sh SEE ALSO +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr X509_check_trust 3 , +.Xr X509_new 3 , +.Xr X509_PURPOSE_set 3 , +.Xr X509V3_get_d2i 3 , +.Xr x509v3.cnf 5 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Bl -dash -offset indent -compact +.It +section 4.2.1.3: Key Usage +.It +section 4.2.1.9: Basic Constraints +.It +section 4.2.1.12: Extended Key Usage +.El +.Sh HISTORY +.Fn X509_check_purpose +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_check_trust.3 b/Libraries/libressl/man/X509_check_trust.3 new file mode 100644 index 000000000..0f02a1b1e --- /dev/null +++ b/Libraries/libressl/man/X509_check_trust.3 @@ -0,0 +1,248 @@ +.\" $OpenBSD: X509_check_trust.3,v 1.8 2023/04/30 14:49:47 tb Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt X509_CHECK_TRUST 3 +.Os +.Sh NAME +.Nm X509_check_trust , +.Nm X509_TRUST_set_default +.Nd check whether a certificate is trusted +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_check_trust +.Fa "X509 *certificate" +.Fa "int trust" +.Fa "int flags" +.Fc +.Ft int +.Fo "(*X509_TRUST_set_default(int (*handler)(int, X509 *, int)))" +.Fa "int trust" +.Fa "X509 *certificate" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn X509_check_trust +checks whether the +.Fa certificate +is marked as trusted for the purpose corresponding to the requested +.Fa trust +identifier. +.Pp +The standard algorithm used by all built-in trust checking functions +performs the following tests in the following order. +The first matching test terminates the algorithm +and decides the return value. +.Bl -enum +.It +If +.Xr X509_add1_reject_object 3 +was previously called on the +.Fa certificate +with the ASN.1 object identifier corresponding to the requested +.Fa trust +identifier, +.Dv X509_TRUST_REJECTED +is returned. +.It +If +.Xr X509_add1_trust_object 3 +was previously called on the +.Fa certificate +with the ASN.1 object identifier corresponding to the requested +.Fa trust +identifier, +.Dv X509_TRUST_TRUSTED +is returned. +.It +If +.Xr X509_add1_reject_object 3 +or +.Xr X509_add1_trust_object 3 +were previously called on the +.Fa certificate , +but neither of them +with the ASN.1 object identifier corresponding to the requested +.Fa trust +identifier, +.Dv X509_TRUST_UNTRUSTED +is returned. +.It +This so-called +.Dq compatibility +step is skipped by some of the trust checking functions. +If neither +.Xr X509_add1_reject_object 3 +nor +.Xr X509_add1_trust_object 3 +was previously called on the +.Fa certificate +and if the +.Fa certificate +is a self-signed, +.Dv X509_TRUST_TRUSTED +is returned. +.It +Otherwise, +.Dv X509_TRUST_UNTRUSTED +is returned. +.El +.Pp +By default, the following +.Fa trust +identifiers are supported. +The +.Dq ASN.1 NID +column indicates the corresponding ASN.1 object identifier; +for the relationship between ASN.1 NIDs and OIDs, see the +.Xr OBJ_nid2obj 3 +manual page. +The +.Qq compat +column indicates whether the compatibility step in the standard algorithm +detailed above is used or skipped. +.Pp +.Bl -column X509_TRUST_OCSP_REQUEST NID_anyExtendedKeyUsage compat -compact +.It Fa trust No identifier Ta Em ASN.1 NID Ta Em compat +.It Dv X509_TRUST_SSL_CLIENT Ta Dv NID_client_auth Ta use +.It Dv X509_TRUST_SSL_SERVER Ta Dv NID_server_auth Ta use +.It Dv X509_TRUST_EMAIL Ta Dv NID_email_protect Ta use +.It Dv X509_TRUST_OBJECT_SIGN Ta Dv NID_code_sign Ta use +.It Dv X509_TRUST_OCSP_SIGN Ta Dv NID_OCSP_sign Ta skip +.It Dv X509_TRUST_OCSP_REQUEST Ta Dv NID_ad_OCSP Ta skip +.It Dv X509_TRUST_TSA Ta Dv NID_time_stamp Ta use +.It Dv X509_TRUST_COMPAT Ta none Ta only +.It 0 Ta Dv NID_anyExtendedKeyUsage Ta special +.It \-1 Ta none Ta trusted +.It invalid Ta Fa trust No argument Ta skip +.El +.Pp +For the following +.Fa trust +identifiers, the standard algorithm is modified: +.Bl -tag -width Ds +.It Dv X509_TRUST_COMPAT +.Xr X509_add1_reject_object 3 +and +.Xr X509_add1_trust_object 3 +settings are completely ignored +and all steps before the compatibility step are skipped. +The +.Fa certificate +is trusted if and only if it is self-signed. +.It 0 +The third step in the standard algorithm is skipped, and the +compatibility step is used even if +.Xr X509_add1_reject_object 3 +or +.Xr X509_add1_trust_object 3 +were called with ASN.1 object identifiers not corresponding to +.Dv NID_anyExtendedKeyUsage . +.It \-1 +The +.Fa certificate +is not inspected and +.Dv X509_TRUST_TRUSTED +is always returned. +.It invalid +If the +.Fa trust +argument is neither 0 nor \-1 nor valid as a trust identifier, +it is re-interpreted as an ASN.1 NID +and used itself for the standard algorithm. +The compatibility step is skipped in this case. +.El +.Pp +The +.Fa flags +argument is ignored by all built-in trust checking functions, +but user-specified trust checking functions might use it. +.Pp +If the function +.Xr X509_TRUST_add 3 +was called before +.Fn X509_check_trust , +it may have installed different, user-supplied checking functions +for some of the standard +.Fa trust +identifiers listed above, or it may have installed additional, +user-supplied checking functions for user-defined +.Fa trust +identifiers not listed above. +.Pp +If the function +.Fn X509_TRUST_set_default +was called, the +.Fa handler +function passed to it is used instead of the standard algorithm, +but only in the case where the +.Fa trust +argument of +.Fn X509_check_trust +is invalid. +The compatibility step is not used in this case. +.Pp +If the return value of the first call to +.Fn X509_TRUST_set_default +is saved and passed back to +.Fn X509_TRUST_set_default +later on, the standard behaviour +of using the standard algorithm for invalid +.Fa trust +arguments is restored. +.Sh RETURN VALUES +.Fn X509_check_trust +returns the following values: +.Bl -tag -width Ds +.It Dv X509_TRUST_TRUSTED +The +.Fa certificate +is explicitly or implicitly trusted for the requested purpose. +.It Dv X509_TRUST_REJECTED +The +.Fa certificate +is explicitly rejected for the requested purpose. +.It Dv X509_TRUST_UNTRUSTED +The +.Fa certificate +is neither trusted nor explicitly rejected, +which implies that it is not trusted. +.El +.Pp +.Fn X509_TRUST_set_default +returns a pointer to the handler function for invalid +.Fa trust +that was installed before the call, which may either be a pointer +to a function installed by a previous call to +.Fn X509_TRUST_set_default +or a pointer to the built-in function implementing the standard algorithm if +.Fn X509_TRUST_set_default +was never called before. +.Sh SEE ALSO +.Xr PEM_read_X509_AUX 3 , +.Xr X509_add1_trust_object 3 , +.Xr X509_CERT_AUX_new 3 , +.Xr X509_check_purpose 3 , +.Xr X509_new 3 , +.Xr X509_TRUST_set 3 , +.Xr X509_VERIFY_PARAM_set_trust 3 +.Sh HISTORY +.Fn X509_check_trust +and +.Fn X509_TRUST_set_default +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_cmp.3 b/Libraries/libressl/man/X509_cmp.3 new file mode 100644 index 000000000..f90bc0e6d --- /dev/null +++ b/Libraries/libressl/man/X509_cmp.3 @@ -0,0 +1,231 @@ +.\" $OpenBSD: X509_cmp.3,v 1.3 2021/07/02 10:50:39 schwarze Exp $ +.\" full merge up to: OpenSSL ea5d4b89 Jun 6 11:42:02 2019 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Paul Yang . +.\" Copyright (c) 2019 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 2 2021 $ +.Dt X509_CMP 3 +.Os +.Sh NAME +.Nm X509_cmp , +.Nm X509_NAME_cmp , +.\" The alias X509_name_cmp(3) is intentionally undocumented +.\" because it is almost unused in real-world code. +.Nm X509_issuer_and_serial_cmp , +.Nm X509_issuer_name_cmp , +.Nm X509_subject_name_cmp , +.Nm X509_CRL_cmp , +.Nm X509_CRL_match +.Nd compare X.509 certificates and related values +.\" The function name_cmp() is intentionally undocumented. +.\" It was a mistake to make it public in the first place, +.\" and it is no longer part of the public API in OpenSSL 1.1. +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_cmp +.Fa "const X509 *a" +.Fa "const X509 *b" +.Fc +.Ft int +.Fo X509_NAME_cmp +.Fa "const X509_NAME *a" +.Fa "const X509_NAME *b" +.Fc +.Ft int +.Fo X509_issuer_and_serial_cmp +.Fa "const X509 *a" +.Fa "const X509 *b" +.Fc +.Ft int +.Fo X509_issuer_name_cmp +.Fa "const X509 *a" +.Fa "const X509 *b" +.Fc +.Ft int +.Fo X509_subject_name_cmp +.Fa "const X509 *a" +.Fa "const X509 *b" +.Fc +.Ft int +.Fo X509_CRL_cmp +.Fa "const X509_CRL *a" +.Fa "const X509_CRL *b" +.Fc +.Ft int +.Fo X509_CRL_match +.Fa "const X509_CRL *a" +.Fa "const X509_CRL *b" +.Fc +.Sh DESCRIPTION +.Fn X509_cmp +compares two X.509 certificates using +.Xr memcmp 3 +on the SHA1 hashes of their canonical (DER) representations as generated with +.Xr X509_digest 3 . +.Pp +.Fn X509_NAME_cmp +compares two X.501 +.Vt Name +objects using their canonical (DER) representations generated with +.Xr i2d_X509_NAME 3 . +.Pp +.Fn X509_issuer_and_serial_cmp +compares the +.Fa issuer +and +.Fa serialNumber +fields of two +.Vt TBSCertificate +structures, using +.Fn X509_NAME_cmp +for the +.Fa issuer +fields. +.Pp +.Fn X509_issuer_name_cmp +compares the +.Fa issuer +fields of two +.Vt TBSCertificate +structures using +.Fn X509_NAME_cmp . +.Pp +.Fn X509_subject_name_cmp +compares the +.Fa subject +fields of two +.Vt TBSCertificate +structures using +.Fn X509_NAME_cmp . +.Pp +.Fn X509_CRL_cmp +is misnamed; it only compares the +.Fa issuer +fields of two +.Vt TBSCertList +structures using +.Fn X509_NAME_cmp . +.Pp +.Fn X509_CRL_match +compares two certificate revocation lists using +.Xr memcmp 3 +on the SHA1 hashes of their canonical (DER) representations as generated with +.Xr X509_CRL_digest 3 . +.Sh RETURN VALUES +All these functions return 0 to indicate a match or a non-zero value +to indicate a mismatch. +.Pp +.Fn X509_NAME_cmp , +.Fn X509_issuer_and_serial_cmp , +.Fn X509_issuer_name_cmp , +.Fn X509_subject_name_cmp +and +.Fn X509_CRL_cmp +may return -2 to indicate an error. +.Sh SEE ALSO +.Xr i2d_X509_NAME 3 , +.Xr X509_CRL_new 3 , +.Xr X509_digest 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate +and Certificate Revocation List (CRL) Profile +.Bl -dash -compact -offset indent +.It +section 4.1: Basic Certificate Fields +.It +section 5.1: CRL Fields +.El +.Sh HISTORY +.Fn X509_issuer_and_serial_cmp , +.Fn X509_issuer_name_cmp , +and +.Fn X509_subject_name_cmp +first appeared in SSLeay 0.5.1 and +.Fn X509_NAME_cmp +and +.Fn X509_CRL_cmp +in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_cmp +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn X509_CRL_match +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh BUGS +For +.Fn X509_NAME_cmp , +.Fn X509_issuer_and_serial_cmp , +.Fn X509_issuer_name_cmp , +.Fn X509_subject_name_cmp +and +.Fn X509_CRL_cmp , +the return value -2 sometimes indicates a mismatch and sometimes an error. diff --git a/Libraries/libressl/man/X509_cmp_time.3 b/Libraries/libressl/man/X509_cmp_time.3 new file mode 100644 index 000000000..0f2afdad0 --- /dev/null +++ b/Libraries/libressl/man/X509_cmp_time.3 @@ -0,0 +1,203 @@ +.\" $OpenBSD: X509_cmp_time.3,v 1.11 2021/11/12 14:34:57 schwarze Exp $ +.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2017, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Emilia Kasper +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: November 12 2021 $ +.Dt X509_CMP_TIME 3 +.Os +.Sh NAME +.Nm X509_cmp_time , +.Nm X509_cmp_current_time , +.Nm X509_time_adj_ex , +.Nm X509_time_adj , +.Nm X509_gmtime_adj +.Nd ASN.1 Time utilities +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_cmp_time +.Fa "const ASN1_TIME *asn1_time" +.Fa "time_t *cmp_time" +.Fc +.Ft int +.Fo X509_cmp_current_time +.Fa "const ASN1_TIME *asn1_time" +.Fc +.Ft ASN1_TIME * +.Fo X509_time_adj_ex +.Fa "ASN1_TIME *out_time" +.Fa "int offset_day" +.Fa "long offset_sec" +.Fa "time_t *in_time" +.Fc +.Ft ASN1_TIME * +.Fo X509_time_adj +.Fa "ASN1_TIME *out_time" +.Fa "long offset_sec" +.Fa "time_t *in_time" +.Fc +.Ft ASN1_TIME * +.Fo X509_gmtime_adj +.Fa "ASN1_TIME *out_time" +.Fa "long offset_sec" +.Fc +.Sh DESCRIPTION +.Fn X509_cmp_time +parses +.Fa asn1_time +with +.Xr ASN1_time_parse 3 +and compares it to +.Fa cmp_time , +or to the current time if +.Fa cmp_time +is +.Dv NULL . +.Fn X509_cmp_current_time +compares it to the current time. +.Pp +.Fn X509_time_adj_ex +sets +.Fa out_time +to a time +.Fa offset_day +and +.Fa offset_sec +later than +.Fa in_time . +The values of +.Fa offset_day +and +.Fa offset_sec +can be negative to set a time before +.Fa in_time . +The +.Fa offset_sec +value can also exceed the number of seconds in a day. +If +.Fa in_time +is +.Dv NULL , +the current time is used instead. +If +.Fa out_time +is +.Dv NULL , +a new +.Vt ASN1_TIME +structure is allocated and returned. +.Pp +.Fn X509_time_adj +does the same with a 0 day offset. +.Pp +.Fn X509_gmtime_adj +does the same using the current time instead of +.Fa in_time , +that is, it sets +.Fa out_time +to a time +.Fa offset_sec +seconds later than the current time. +.Sh RETURN VALUES +.Fn X509_cmp_time +and +.Fn X509_cmp_current_time +return -1 if +.Fa asn1_time +is earlier than or equal to +.Fa cmp_time , +1 if it is later, or 0 on error. +.Pp +.Fn X509_time_adj_ex , +.Fn X509_time_adj , +and +.Fn X509_gmtime_adj +return a pointer to the updated or newly allocated +.Vt ASN1_TIME +structure or +.Dv NULL +on error. +.Sh SEE ALSO +.Xr ASN1_TIME_new 3 , +.Xr ASN1_time_parse 3 , +.Xr ASN1_TIME_set 3 , +.Xr time 3 +.Sh HISTORY +.Fn X509_cmp_current_time +and +.Fn X509_gmtime_adj +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_cmp_time +and +.Fn X509_time_adj +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn X509_time_adj_ex +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/X509_digest.3 b/Libraries/libressl/man/X509_digest.3 new file mode 100644 index 000000000..7627e0773 --- /dev/null +++ b/Libraries/libressl/man/X509_digest.3 @@ -0,0 +1,155 @@ +.\" $OpenBSD: X509_digest.3,v 1.8 2019/08/20 13:27:19 schwarze Exp $ +.\" full merge up to: OpenSSL 1212818e Sep 11 13:22:14 2018 +0100 +.\" +.\" This file was written by Rich Salz +.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 20 2019 $ +.Dt X509_DIGEST 3 +.Os +.Sh NAME +.Nm X509_digest , +.Nm X509_CRL_digest , +.Nm X509_pubkey_digest , +.Nm X509_NAME_digest , +.Nm X509_REQ_digest , +.Nm PKCS7_ISSUER_AND_SERIAL_digest +.Nd get digests of various objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_digest +.Fa "const X509 *data" +.Fa "const EVP_MD *type" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo X509_CRL_digest +.Fa "const X509_CRL *data" +.Fa "const EVP_MD *type" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo X509_pubkey_digest +.Fa "const X509 *data" +.Fa "const EVP_MD *type" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo X509_REQ_digest +.Fa "const X509_REQ *data" +.Fa "const EVP_MD *type" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.Ft int +.Fo X509_NAME_digest +.Fa "const X509_NAME *data" +.Fa "const EVP_MD *type" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.In openssl/pkcs7.h +.Ft int +.Fo PKCS7_ISSUER_AND_SERIAL_digest +.Fa "PKCS7_ISSUER_AND_SERIAL *data" +.Fa "const EVP_MD *type" +.Fa "unsigned char *md" +.Fa "unsigned int *len" +.Fc +.Sh DESCRIPTION +.Fn X509_pubkey_digest +returns a digest of the DER representation of the public key contained in +.Fa data . +All other functions described here return a digest of the DER +representation of their entire +.Fa data +object. +.Pp +The +.Fa type +parameter specifies the digest to be used, such as +.Xr EVP_sha1 3 . +.Fa md +is a pointer to the buffer where the digest will be copied and is +assumed to be large enough; a size of at least +.Dv EVP_MAX_MD_SIZE +bytes is suggested. +The +.Fa len +parameter, if not +.Dv NULL , +points to a place where the digest size will be stored. +.Sh RETURN VALUES +These functions return 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr EVP_get_digestbyname 3 , +.Xr X509_cmp 3 , +.Xr X509_CRL_new 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 , +.Xr X509_REQ_new 3 +.Sh HISTORY +.Fn X509_digest , +.Fn X509_NAME_digest , +and +.Fn PKCS7_ISSUER_AND_SERIAL_digest +first appeared in SSLeay 0.6.5 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_CRL_digest +and +.Fn X509_REQ_digest +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn X509_pubkey_digest +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/X509_find_by_subject.3 b/Libraries/libressl/man/X509_find_by_subject.3 new file mode 100644 index 000000000..98a76a1fc --- /dev/null +++ b/Libraries/libressl/man/X509_find_by_subject.3 @@ -0,0 +1,69 @@ +.\" $OpenBSD: X509_find_by_subject.3,v 1.1 2021/07/04 12:56:27 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 4 2021 $ +.Dt X509_FIND_BY_SUBJECT 3 +.Os +.Sh NAME +.Nm X509_find_by_subject , +.Nm X509_find_by_issuer_and_serial +.Nd search an array of X.509 certificates +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509 * +.Fo X509_find_by_subject +.Fa "STACK_OF(X509) *sk" +.Fa "X509_NAME *subject" +.Fc +.Ft X509 * +.Fo X509_find_by_issuer_and_serial +.Fa "STACK_OF(X509) *sk" +.Fa "X509_NAME *issuer" +.Fa "ASN1_INTEGER *serial" +.Fc +.Sh DESCRIPTION +.Fn X509_find_by_subject +searches the variable-sized array +.Fa sk +for a certificate with a matching +.Fa subject +name. +.Pp +.Fn X509_find_by_issuer_and_serial +searches the array for a certificate where both the +.Fa issuer +name and the +.Fa serial +number match the arguments. +.Sh RETURN VALUES +These functions return a pointer to the first matching certificate or +.Dv NULL +if +.Fa sk +is +.Dv NULL +or does not contain a matching certificate. +.Sh SEE ALSO +.Xr ASN1_INTEGER_new 3 , +.Xr STACK_OF 3 , +.Xr X509_cmp 3 , +.Xr X509_get_serialNumber 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_NAME_new 3 , +.Xr X509_new 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.8.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/X509_get0_notBefore.3 b/Libraries/libressl/man/X509_get0_notBefore.3 new file mode 100644 index 000000000..53b18d599 --- /dev/null +++ b/Libraries/libressl/man/X509_get0_notBefore.3 @@ -0,0 +1,265 @@ +.\" $OpenBSD: X509_get0_notBefore.3,v 1.6 2023/06/06 16:20:13 schwarze Exp $ +.\" content checked up to: OpenSSL 27b138e9 May 19 00:16:38 2017 +0000 +.\" +.\" Copyright (c) 2018, 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: June 6 2023 $ +.Dt X509_GET0_NOTBEFORE 3 +.Os +.Sh NAME +.Nm X509_get0_notBefore , +.Nm X509_get0_notAfter , +.Nm X509_getm_notBefore , +.Nm X509_getm_notAfter , +.Nm X509_get_notBefore , +.Nm X509_get_notAfter , +.Nm X509_CRL_get0_lastUpdate , +.Nm X509_CRL_get0_nextUpdate , +.Nm X509_CRL_get_lastUpdate , +.Nm X509_CRL_get_nextUpdate , +.Nm X509_set1_notBefore , +.Nm X509_set1_notAfter , +.Nm X509_set_notBefore , +.Nm X509_set_notAfter , +.Nm X509_CRL_set1_lastUpdate , +.Nm X509_CRL_set1_nextUpdate , +.Nm X509_CRL_set_lastUpdate , +.Nm X509_CRL_set_nextUpdate +.Nd get and set certificate and CRL validity dates +.Sh SYNOPSIS +.In openssl/x509.h +.Ft const ASN1_TIME * +.Fo X509_get0_notBefore +.Fa "const X509 *x" +.Fc +.Ft const ASN1_TIME * +.Fo X509_get0_notAfter +.Fa "const X509 *x" +.Fc +.Ft ASN1_TIME * +.Fo X509_getm_notBefore +.Fa "const X509 *x" +.Fc +.Ft ASN1_TIME * +.Fo X509_getm_notAfter +.Fa "const X509 *x" +.Fc +.Ft ASN1_TIME * +.Fo X509_get_notBefore +.Fa "const X509 *x" +.Fc +.Ft ASN1_TIME * +.Fo X509_get_notAfter +.Fa "const X509 *x" +.Fc +.Ft const ASN1_TIME * +.Fo X509_CRL_get0_lastUpdate +.Fa "const X509_CRL *crl" +.Fc +.Ft const ASN1_TIME * +.Fo X509_CRL_get0_nextUpdate +.Fa "const X509_CRL *crl" +.Fc +.Ft ASN1_TIME * +.Fo X509_CRL_get_lastUpdate +.Fa "X509_CRL *crl" +.Fc +.Ft ASN1_TIME * +.Fo X509_CRL_get_nextUpdate +.Fa "X509_CRL *crl" +.Fc +.Ft int +.Fo X509_set1_notBefore +.Fa "X509 *x" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_set1_notAfter +.Fa "X509 *x" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_set_notBefore +.Fa "X509 *x" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_set_notAfter +.Fa "X509 *x" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_CRL_set1_lastUpdate +.Fa "X509_CRL *crl" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_CRL_set1_nextUpdate +.Fa "X509_CRL *crl" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_CRL_set_lastUpdate +.Fa "X509_CRL *crl" +.Fa "const ASN1_TIME *tm" +.Fc +.Ft int +.Fo X509_CRL_set_nextUpdate +.Fa "X509_CRL *crl" +.Fa "const ASN1_TIME *tm" +.Fc +.Sh DESCRIPTION +.Fn X509_getm_notBefore +and +.Fn X509_getm_notAfter +return pointers to the +.Fa notBefore +and +.Fa notAfter +fields of the validity period of the certificate +.Fa x , +respectively. +.Fn X509_get_notBefore +and +.Fn X509_get_notAfter +are deprecated aliases implemented as macros. +.Pp +.Fn X509_get0_notBefore +and +.Fn X509_get0_notAfter +are identical except for the const qualifier on the return type. +.Pp +.Fn X509_CRL_get0_lastUpdate +is misnamed in a confusing way: it returns a pointer to the +.Fa thisUpdate +field of the +.Fa crl , +indicating the time when this +.Fa crl +was issued. +.Pp +.Fn X509_CRL_get0_nextUpdate +returns a pointer to the +.Fa nextUpdate +field of the +.Fa crl , +indicating the time when issuing the subsequent CRL will be due. +.Pp +.Fn X509_CRL_get_lastUpdate +and +.Fn X509_CRL_get_nextUpdate +are deprecated and identical except for the const qualifier +on the argument and on the return type. +.Pp +.Fn X509_set1_notBefore , +.Fn X509_set1_notAfter , +.Fn X509_CRL_set1_lastUpdate , +and +.Fn X509_CRL_set1_nextUpdate +set the +.Fa notBefore , +.Fa notAfter , +.Fa thisUpdate Pq sic!\& , +or +.Fa nextUpdate +field of +.Fa x +or +.Fa crl , +respectively, to a deep copy of +.Fa tm +and free the +.Vt ASN1_TIME +value that they replace. +.Pp +.Fn X509_set_notBefore , +.Fn X509_set_notAfter , +.Fn X509_CRL_set_lastUpdate , +and +.Fn X509_CRL_set_nextUpdate +are deprecated aliases. +.Sh RETURN VALUES +The +.Sy get +functions return internal pointers +which must not be freed by the application, or +.Dv NULL +if the requested field is not available. +They may crash with a +.Dv NULL +pointer access if +.Fa x +or +.Fa crl +is +.Dv NULL . +.Pp +The +.Sy set +functions return 1 on success or 0 on failure. +They fail if +.Fa x +is +.Dv NULL +or does not contain a +.Fa validity +substructure, if +.Fa crl +is +.Dv NULL , +or if +.Xr ASN1_STRING_dup 3 +fails. +.Pp +Except for some cases of +.Xr ASN1_STRING_dup 3 +failure, these functions do not support +determining reasons for failure with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_TIME_set 3 , +.Xr ASN1_TIME_set_tm 3 , +.Xr X509_cmp_time 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_new 3 , +.Xr X509_sign 3 , +.Xr X509_VAL_new 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_get_notBefore , +.Fn X509_get_notAfter , +.Fn X509_set_notBefore , +and +.Fn X509_set_notAfter +first appeared in SSLeay 0.6.5 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_CRL_get_lastUpdate +and +.Fn X509_CRL_get_nextUpdate +first appeared in OpenSSL 0.9.2 and have been available since +.Ox 2.6 . +.Pp +.Fn X509_CRL_set_lastUpdate +and +.Fn X509_CRL_set_nextUpdate +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Pp +The remaining functions first appeared in OpenSSL 1.1.0 +and have been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/X509_get0_signature.3 b/Libraries/libressl/man/X509_get0_signature.3 new file mode 100644 index 000000000..f3ad3982a --- /dev/null +++ b/Libraries/libressl/man/X509_get0_signature.3 @@ -0,0 +1,213 @@ +.\" $OpenBSD: X509_get0_signature.3,v 1.8 2023/03/16 12:01:47 job Exp $ +.\" selective merge up to: +.\" OpenSSL man3/X509_get0_signature 2f7a2520 Apr 25 17:28:08 2017 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2020 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 16 2023 $ +.Dt X509_GET0_SIGNATURE 3 +.Os +.Sh NAME +.Nm X509_get0_signature , +.Nm X509_REQ_get0_signature , +.Nm X509_CRL_get0_signature , +.Nm X509_get0_tbs_sigalg , +.Nm X509_CRL_get0_tbs_sigalg , +.Nm X509_get_signature_type , +.Nm X509_get_signature_nid , +.Nm X509_REQ_get_signature_nid , +.Nm X509_CRL_get_signature_nid +.Nd signature information +.Sh SYNOPSIS +.In openssl/x509.h +.Ft void +.Fo X509_get0_signature +.Fa "const ASN1_BIT_STRING **psig" +.Fa "const X509_ALGOR **palg" +.Fa "const X509 *x" +.Fc +.Ft void +.Fo X509_REQ_get0_signature +.Fa "const X509_REQ *req" +.Fa "const ASN1_BIT_STRING **psig" +.Fa "const X509_ALGOR **palg" +.Fc +.Ft void +.Fo X509_CRL_get0_signature +.Fa "const X509_CRL *crl" +.Fa "const ASN1_BIT_STRING **psig" +.Fa "const X509_ALGOR **palg" +.Fc +.Ft const X509_ALGOR * +.Fo X509_get0_tbs_sigalg +.Fa "const X509 *x" +.Fc +.Ft const X509_ALGOR * +.Fo X509_CRL_get0_tbs_sigalg +.Fa "const X509_CRL *crl" +.Fc +.Ft int +.Fo X509_get_signature_type +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_get_signature_nid +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_REQ_get_signature_nid +.Fa "const X509_REQ *req" +.Fc +.Ft int +.Fo X509_CRL_get_signature_nid +.Fa "const X509_CRL *crl" +.Fc +.Sh DESCRIPTION +.Fn X509_get0_signature , +.Fn X509_REQ_get0_signature , +and +.Fn X509_CRL_get0_signature +set +.Pf * Fa psig +to the signature and +.Pf * Fa palg +to the signature algorithm of +.Fa x , +.Fa req , +or +.Fa crl , +respectively. +.Fn X509_get0_tbs_sigalg +and +.Fn X509_CRL_get0_tbs_sigalg +return the signature algorithm in the signed portion of +.Fa x +or +.Fa crl , +respectively. +The values returned are internal pointers +that must not be freed by the caller. +.Pp +.Fn X509_get_signature_type +returns the base NID corresponding to the signature algorithm of +.Fa x +just like +.Xr EVP_PKEY_base_id 3 +does. +.Pp +.Fn X509_get_signature_nid , +.Fn X509_REQ_get_signature_nid , +and +.Fn X509_CRL_get_signature_nid +return the NID corresponding to the signature algorithm of +.Fa x , +.Fa req , +or +.Fa crl , +respectively, just like +.Xr EVP_PKEY_id 3 +does. +.Pp +These functions provide lower level access to the signature +for cases where an application wishes to analyse or generate a +signature in a form where +.Xr X509_sign 3 +is not appropriate, for example in a non-standard or unsupported format. +.Sh SEE ALSO +.Xr EVP_PKEY_base_id 3 , +.Xr OBJ_obj2nid 3 , +.Xr X509_ALGOR_new 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_get_version 3 , +.Xr X509_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509_sign 3 , +.Xr X509_signature_dump 3 , +.Xr X509_verify_cert 3 +.Sh HISTORY +.Fn X509_get_signature_type +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Pp +.Fn X509_get0_signature +and +.Fn X509_get_signature_nid +first appeared in OpenSSL 1.0.2. +.Fn X509_REQ_get0_signature , +.Fn X509_CRL_get0_signature , +.Fn X509_get0_tbs_sigalg , +.Fn X509_REQ_get_signature_nid , +and +.Fn X509_CRL_get_signature_nid +first appeared in OpenSSL 1.1.0. +All these functions have been available since +.Ox 6.3 . +.Pp +.Fn X509_CRL_get0_tbs_sigalg +first appeared in LibreSSL 3.7.1 and has been available since +.Ox 7.3 . diff --git a/Libraries/libressl/man/X509_get1_email.3 b/Libraries/libressl/man/X509_get1_email.3 new file mode 100644 index 000000000..c38a60489 --- /dev/null +++ b/Libraries/libressl/man/X509_get1_email.3 @@ -0,0 +1,123 @@ +.\" $OpenBSD: X509_get1_email.3,v 1.1 2019/08/23 12:23:39 schwarze Exp $ +.\" +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 23 2019 $ +.Dt X509_GET1_EMAIL 3 +.Os +.Sh NAME +.Nm X509_get1_email , +.Nm X509_get1_ocsp , +.Nm X509_email_free +.Nd utilities for stacks of strings +.Sh SYNOPSIS +.In openssl/x509v3.h +.Vt typedef char *OPENSSL_STRING ; +.Ft STACK_OF(OPENSSL_STRING) * +.Fo X509_get1_email +.Fa "X509 *certificate" +.Fc +.Ft STACK_OF(OPENSSL_STRING) * +.Fo X509_get1_ocsp +.Fa "X509 *certificate" +.Fc +.Ft void +.Fo X509_email_free +.Fa "STACK_OF(OPENSSL_STRING) *stack" +.Fc +.Sh DESCRIPTION +.Fn X509_get1_email +retrieves all email addresses from the +.Fa subject +field and from any +Subject Alternative Name extension of the +.Fa certificate . +.Pp +.Fn X509_get1_ocsp +retrieves all uniform resource identifiers +from all +.Vt AccessDescription +objects having an +.Fa accessMethod +of OCSP which are contained in the Authority Information Access extension +of the +.Fa certificate . +.Pp +.Fn X509_email_free +frees all strings stored in the +.Fa stack +as well as the stack itself. +If +.Fa stack +is a +.Dv NULL +pointer, no action occurs. +.Sh RETURN VALUES +.Fn X509_REQ_get1_email +and +.Fn X509_get1_ocsp +return newly allocated stacks of +.Vt char * +containing copies of the addresses in question, or +.Dv NULL +if there are no addresses or if an error occurs. +.Sh SEE ALSO +.Xr OCSP_sendreq_new 3 , +.Xr OCSP_SERVICELOC_new 3 , +.Xr OPENSSL_sk_new 3 , +.Xr STACK_OF 3 , +.Xr X509_check_email 3 , +.Xr X509_get_ext_d2i 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_new 3 , +.Xr x509v3.cnf 5 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Bl -dash -offset indent -compact +.It +section 4.1: Basic Certificate Fields +.It +section 4.1.2.6: Subject +.It +section 4.2.1.6: Subject Alternative Name +.It +section 4.2.2.1: Authority Information Access +.El +.Pp +RFC 2985: PKCS #9: Selected Object Classes and Attribute Types +.Bl -dash -offset indent -compact +.It +section 5.2.1: Electronic-mail address +.It +appendix B.3.5: emailAddress +.El +.Sh HISTORY +.Fn X509_get1_email +and +.Fn X509_email_free +first appeared in OpenSSL 0.9.6 and have been available since +.Ox 2.9 . +.Pp +.Fn X509_get1_ocsp +first appeared in OpenSSL 0.9.8h and has been available since +.Ox 4.5 . +.Sh BUGS +.Fn X509_email_free +is utterly misnamed. +It does not operate on any +.Vt X509 +object, nor is it in any way restricted to email addresses; +instead, it simply frees a stack of strings. diff --git a/Libraries/libressl/man/X509_get_extension_flags.3 b/Libraries/libressl/man/X509_get_extension_flags.3 new file mode 100644 index 000000000..1d7f29c68 --- /dev/null +++ b/Libraries/libressl/man/X509_get_extension_flags.3 @@ -0,0 +1,234 @@ +.\" $OpenBSD: X509_get_extension_flags.3,v 1.4 2023/04/30 19:40:23 tb Exp $ +.\" full merge up to: OpenSSL 361136f4 Sep 1 18:56:58 2015 +0100 +.\" selective merge up to: OpenSSL 2b2e3106f Feb 16 15:04:45 2021 +0000 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 30 2023 $ +.Dt X509_GET_EXTENSION_FLAGS 3 +.Os +.Sh NAME +.Nm X509_get_extension_flags , +.Nm X509_get_key_usage , +.Nm X509_get_extended_key_usage +.Nd retrieve certificate extension data +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft uint32_t +.Fo X509_get_extension_flags +.Fa "X509 *x" +.Fc +.Ft uint32_t +.Fo X509_get_key_usage +.Fa "X509 *x" +.Fc +.Ft uint32_t +.Fo X509_get_extended_key_usage +.Fa "X509 *x" +.Fc +.Sh DESCRIPTION +These functions retrieve information related to commonly used +certificate extensions. +.Pp +.Fn X509_get_extension_flags +retrieves general information about a certificate. +It returns one or more of the following flags OR'ed together. +.Bl -tag -width Ds +.It Dv EXFLAG_V1 +The certificate is an obsolete version 1 certificate. +.It Dv EXFLAG_BCONS +The certificate contains a basic constraints extension. +.It Dv EXFLAG_CA +The certificate contains basic constraints and asserts the CA flag. +.It Dv EXFLAG_PROXY +The certificate is a valid proxy certificate. +In LibreSSL this flag is never set. +.It Dv EXFLAG_SI +The certificate is self issued (that is subject and issuer names match). +.It Dv EXFLAG_SS +The subject and issuer names match and extension values imply it is self +signed. +.It Dv EXFLAG_FRESHEST +The freshest CRL extension is present in the certificate. +.It Dv EXFLAG_CRITICAL +The certificate contains an unhandled critical extension. +.It Dv EXFLAG_INVALID +Some certificate extension values are invalid or inconsistent. +The certificate should be rejected. +This bit may also be raised after an out-of-memory error while +processing the X509 object, so it may not be related to the processed +ASN1 object itself. +.\" EXFLAG_NO_FINGERPRINT is not available in LibreSSL. Do we need +.\" https://github.com/openssl/openssl/issues/13698 and the fix it fixes? +.\".It Dv EXFLAG_NO_FINGERPRINT +.\" Failed to compute the internal SHA1 hash value of the certificate. +.\" This may be due to malloc failure or because no SHA1 implementation was +.\" found. +.It Dv EXFLAG_INVALID_POLICY +The +.Dv NID_certificate_policies +certificate extension is invalid or inconsistent. +The certificate should be rejected. +This bit may also be raised after an out-of-memory error while +processing the X509 object, so it may not be related to the processed +ASN1 object itself. +.It Dv EXFLAG_KUSAGE +The certificate contains a key usage extension. +The value can be retrieved using +.Fn X509_get_key_usage . +.It Dv EXFLAG_XKUSAGE +The certificate contains an extended key usage extension. +The value can be retrieved using +.Fn X509_get_extended_key_usage . +.El +.Pp +.Fn X509_get_key_usage +returns the value of the key usage extension. +If key usage is present, it returns zero or more of these flags: +.Dv KU_DIGITAL_SIGNATURE , +.Dv KU_NON_REPUDIATION , +.Dv KU_KEY_ENCIPHERMENT , +.Dv KU_DATA_ENCIPHERMENT , +.Dv KU_KEY_AGREEMENT , +.Dv KU_KEY_CERT_SIGN , +.Dv KU_CRL_SIGN , +.Dv KU_ENCIPHER_ONLY , +or +.Dv KU_DECIPHER_ONLY , +corresponding to individual key usage bits. +If key usage is absent, +.Dv UINT32_MAX +is returned. +.Pp +The following aliases for these flags are defined in +.In openssl/x509.h : +.Dv X509v3_KU_DIGITAL_SIGNATURE , +.Dv X509v3_KU_NON_REPUDIATION , +.Dv X509v3_KU_KEY_ENCIPHERMENT , +.Dv X509v3_KU_DATA_ENCIPHERMENT , +.Dv X509v3_KU_KEY_AGREEMENT , +.Dv X509v3_KU_KEY_CERT_SIGN , +.Dv X509v3_KU_CRL_SIGN , +.Dv X509v3_KU_ENCIPHER_ONLY , +and +.Dv X509v3_KU_DECIPHER_ONLY . +.\" X509v3_KU_UNDEF is intentionally undocumented because nothing uses it. +.Pp +.Fn X509_get_extended_key_usage +returns the value of the extended key usage extension. +If extended key usage is present, it returns zero or more of these +flags: +.Dv XKU_SSL_SERVER , +.Dv XKU_SSL_CLIENT , +.Dv XKU_SMIME , +.Dv XKU_CODE_SIGN +.Dv XKU_OCSP_SIGN , +.Dv XKU_TIMESTAMP , +.Dv XKU_DVCS , +or +.Dv XKU_ANYEKU . +These correspond to the OIDs +.Qq id-kp-serverAuth , +.Qq id-kp-clientAuth , +.Qq id-kp-emailProtection , +.Qq id-kp-codeSigning , +.Qq id-kp-OCSPSigning , +.Qq id-kp-timeStamping , +.Qq id-kp-dvcs , +and +.Qq anyExtendedKeyUsage , +respectively. +Additionally, +.Dv XKU_SGC +is set if either Netscape or Microsoft SGC OIDs are present. +.Pp +The value of the flags correspond to extension values which are cached +in the +.Vt X509 +structure. +If the flags returned do not provide sufficient information, +an application should examine extension values directly, +for example using +.Xr X509_get_ext_d2i 3 . +.Pp +If the key usage or extended key usage extension is absent then +typically usage is unrestricted. +For this reason +.Fn X509_get_key_usage +and +.Fn X509_get_extended_key_usage +return +.Dv UINT32_MAX +when the corresponding extension is absent. +Applications can additionally check the return value of +.Fn X509_get_extension_flags +and take appropriate action if an extension is absent. +.Sh RETURN VALUES +.Fn X509_get_extension_flags , +.Fn X509_get_key_usage +and +.Fn X509_get_extended_key_usage +return sets of flags corresponding to the certificate extension values. +.Sh SEE ALSO +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr POLICYINFO_new 3 , +.Xr X509_check_ca 3 , +.Xr X509_check_purpose 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_get_ext_d2i 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_get_version 3 , +.Xr X509_new 3 +.Sh HISTORY +.Nm X509_get_extension_flags , +.Nm X509_get_key_usage , +and +.Nm X509_get_extended_key_usage +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509_get_pubkey.3 b/Libraries/libressl/man/X509_get_pubkey.3 new file mode 100644 index 000000000..082939798 --- /dev/null +++ b/Libraries/libressl/man/X509_get_pubkey.3 @@ -0,0 +1,296 @@ +.\" $OpenBSD: X509_get_pubkey.3,v 1.13 2022/03/31 17:27:17 naddy Exp $ +.\" selective merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2020, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt X509_GET_PUBKEY 3 +.Os +.Sh NAME +.Nm X509_get_pubkey , +.Nm X509_get0_pubkey , +.Nm X509_set_pubkey , +.Nm X509_get_X509_PUBKEY , +.Nm X509_get0_pubkey_bitstr , +.Nm X509_REQ_get_pubkey , +.Nm X509_REQ_get0_pubkey , +.Nm X509_REQ_set_pubkey , +.Nm X509_extract_key , +.Nm X509_REQ_extract_key +.Nd get or set certificate or certificate request public key +.Sh SYNOPSIS +.In openssl/x509.h +.Ft EVP_PKEY * +.Fo X509_get_pubkey +.Fa "X509 *x" +.Fc +.Ft EVP_PKEY * +.Fo X509_get0_pubkey +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_set_pubkey +.Fa "X509 *x" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft X509_PUBKEY * +.Fo X509_get_X509_PUBKEY +.Fa "const X509 *x" +.Fc +.Ft ASN1_BIT_STRING * +.Fo X509_get0_pubkey_bitstr +.Fa "const X509 *x" +.Fc +.Ft EVP_PKEY * +.Fo X509_REQ_get_pubkey +.Fa "X509_REQ *req" +.Fc +.Ft EVP_PKEY * +.Fo X509_REQ_get0_pubkey +.Fa "X509_REQ *req" +.Fc +.Ft int +.Fo X509_REQ_set_pubkey +.Fa "X509_REQ *x" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft EVP_PKEY * +.Fo X509_extract_key +.Fa "X509 *x" +.Fc +.Ft EVP_PKEY * +.Fo X509_REQ_extract_key +.Fa "X509_REQ *req" +.Fc +.Sh DESCRIPTION +.Fn X509_get_pubkey +attempts to decode the public key for certificate +.Fa x . +If successful, it returns the public key as an +.Vt EVP_PKEY +pointer with its reference count incremented: this means the returned +key must be freed up after use. +.Fn X509_get0_pubkey +is similar except that it does not increment the reference count +of the returned +.Vt EVP_PKEY , +so it must not be freed up after use. +.Pp +.Fn X509_get_X509_PUBKEY +returns an internal pointer to the +.Vt SubjectPublicKeyInfo +structure contained in +.Fa x . +The returned value must not be freed up after use. +.Pp +.Fn X509_get0_pubkey_bitstr +returns an internal pointer to just the public key contained in this +.Vt SubjectPublicKeyInfo +structure, without the information about the algorithm used. +.Pp +.Fn X509_set_pubkey +attempts to set the public key for certificate +.Fa x +to +.Fa pkey . +The key +.Fa pkey +should be freed up after use. +.Pp +.Fn X509_REQ_get_pubkey , +.Fn X509_REQ_get0_pubkey , +and +.Fn X509_REQ_set_pubkey +are similar but operate on certificate request +.Fa req . +.Pp +The first time a public key is decoded, the +.Vt EVP_PKEY +structure is cached in the certificate or certificate request itself. +Subsequent calls return the cached structure with its reference count +incremented to improve performance. +.Pp +.Fn X509_extract_key +and +.Fn X509_REQ_extract_key +are deprecated aliases for +.Fn X509_get_pubkey +and +.Fn X509_REQ_get_pubkey , +respectively, implemented as macros. +.Sh RETURN VALUES +.Fn X509_get_pubkey , +.Fn X509_get0_pubkey , +.Fn X509_get_X509_PUBKEY , +.Fn X509_get0_pubkey_bitstr , +.Fn X509_REQ_get_pubkey , +.Fn X509_REQ_get0_pubkey , +.Fn X509_extract_key , +and +.Fn X509_REQ_extract_key +return a public key or +.Dv NULL +if an error occurred. +.Pp +.Fn X509_set_pubkey +and +.Fn X509_REQ_set_pubkey +return 1 for success or 0 for failure. +.Pp +In some cases of failure of +.Fn X509_get0_pubkey , +.Fn X509_set_pubkey , +.Fn X509_REQ_get_pubkey , +.Fn X509_REQ_get0_pubkey , +and +.Fn X509_REQ_set_pubkey , +the reason can be determined with +.Xr ERR_get_error 3 . +.Sh ERRORS +.Fn X509_get_pubkey , +.Fn X509_get0_pubkey , +.Fn X509_REQ_get_pubkey , +.Fn X509_extract_key , +and +.Fn X509_REQ_extract_key +provide diagnostics as documented for +.Xr X509_PUBKEY_get 3 . +If +.Fa x +or +.Fa req +is +.Dv NULL +or contains no certificate information, +they fail without pushing an error onto the stack. +.Pp +.Fn X509_get_X509_PUBKEY +provides no diagnostics and crashes by accessing a +.Dv NULL +pointer if +.Fa x +is +.Dv NULL +or contains no certificate information, +.Pp +.Fn X509_get0_pubkey_bitstr +provides no diagnostics +and fails without pushing an error onto the stack if +.Fa x +is +.Dv NULL , +but it crashes by accessing a +.Dv NULL +pointer if +.Fa x +contains no certificate information. +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_NAME_add_entry_by_txt 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_new 3 , +.Xr X509_PUBKEY_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509_sign 3 , +.Xr X509_verify_cert 3 , +.Xr X509V3_get_d2i 3 +.Sh STANDARDS +RFC 5280, Internet X.509 Public Key Infrastructure Certificate +and Certificate Revocation List (CRL) Profile, +section 4.1 Basic Certificate Fields +.Pp +RFC 2986: PKCS #10: Certification Request Syntax Specification, +section 4.1 CertificationRequestInfo +.Sh HISTORY +.Fn X509_extract_key +and +.Fn X509_REQ_extract_key +first appeared in SSLeay 0.5.1 but returned a pointer to an +.Vt RSA +object before SSLeay 0.6.0. +.Fn X509_get_pubkey , +.Fn X509_set_pubkey , +.Fn X509_REQ_get_pubkey , +and +.Fn X509_REQ_set_pubkey +first appeared in SSLeay 0.6.5. +.Fn X509_get_X509_PUBKEY +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_get0_pubkey_bitstr +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.4 . +.Pp +.Fn X509_get0_pubkey +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . +.Fn X509_REQ_get0_pubkey +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509_get_pubkey_parameters.3 b/Libraries/libressl/man/X509_get_pubkey_parameters.3 new file mode 100644 index 000000000..181361477 --- /dev/null +++ b/Libraries/libressl/man/X509_get_pubkey_parameters.3 @@ -0,0 +1,99 @@ +.\" $OpenBSD: X509_get_pubkey_parameters.3,v 1.2 2021/11/26 13:35:10 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 26 2021 $ +.Dt X509_GET_PUBKEY_PARAMETERS 3 +.Os +.Sh NAME +.Nm X509_get_pubkey_parameters +.Nd copy public key parameters from a chain +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_get_pubkey_parameters +.Fa "EVP_PKEY *pkey" +.Fa "STACK_OF(X509) *chain" +.Fc +.Sh DESCRIPTION +.Fn X509_get_pubkey_parameters +copies public key parameters from the first appropriate certificate in the +.Fa chain . +.Pp +If +.Fa pkey +is not +.Dv NULL +and already contains complete public key parameters or uses an +algorithm that does not use any parameters, no action occurs and +the function indicates success without inspecting the existing +parameters, without inspecting the +.Fa chain , +and without comparing any parameters. +.Pp +Otherwise, all public key parameters are copied +from the first certificate in the +.Fa chain +that contains complete public key parameters +to each certificate preceding it in the +.Fa chain . +Unless +.Fa pkey +is a +.Dv NULL +pointer, the same parameters are also copied to +.Fa pkey . +.Sh RETURN VALUES +.Fn X509_get_pubkey_parameters +returns 1 for success or 0 for failure. +.Sh ERRORS +The following diagnostics can be retrieved with +.Xr ERR_get_error 3 , +.Xr ERR_GET_REASON 3 , +and +.Xr ERR_reason_error_string 3 : +.Bl -tag -width Ds +.It Dv X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY Qq unable to get certs public key +Retrieving the public key from a certificate in the +.Fa chain +failed before a certificate containing complete public key parameters +could be found. +.It Xo +.Dv X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN +.Qq unable to find parameters in chain +.Xc +None of the certificates in the chain +contain complete public key parameters. +.El +.Sh SEE ALSO +.Xr EVP_PKEY_copy_parameters 3 , +.Xr EVP_PKEY_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_new 3 +.Sh HISTORY +.Fn X509_get_pubkey_parameters +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Sh CAVEATS +If +.Fn X509_get_pubkey_parameters +fails and returns 0, a part of the parameters may or may not have +been copied before the failure was detected, whereas other parts of +.Fa pkey +and +.Fa chain +may remain unchanged. +So in case of failure, the state of the arguments may change +and possibly become inconsistent. diff --git a/Libraries/libressl/man/X509_get_serialNumber.3 b/Libraries/libressl/man/X509_get_serialNumber.3 new file mode 100644 index 000000000..7d757c7a7 --- /dev/null +++ b/Libraries/libressl/man/X509_get_serialNumber.3 @@ -0,0 +1,129 @@ +.\" $OpenBSD: X509_get_serialNumber.3,v 1.5 2020/06/19 12:01:20 schwarze Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 19 2020 $ +.Dt X509_GET_SERIALNUMBER 3 +.Os +.Sh NAME +.Nm X509_get_serialNumber , +.Nm X509_get0_serialNumber , +.Nm X509_set_serialNumber +.Nd get or set certificate serial number +.Sh SYNOPSIS +.In openssl/x509.h +.Ft ASN1_INTEGER * +.Fo X509_get_serialNumber +.Fa "X509 *x" +.Fc +.Ft const ASN1_INTEGER * +.Fo X509_get0_serialNumber +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_set_serialNumber +.Fa "X509 *x" +.Fa "ASN1_INTEGER *serial" +.Fc +.Sh DESCRIPTION +.Fn X509_get_serialNumber +returns the serial number of certificate +.Fa x +as an +.Vt ASN1_INTEGER +structure which can be examined or initialised. +The value returned is an internal pointer which must not be freed +up after the call. +.Pp +.Fn X509_get0_serialNumber +does the same except that it accepts a constant argument +and returns a constant result. +.Pp +.Fn X509_set_serialNumber +sets the serial number of certificate +.Fa x +to +.Fa serial . +A copy of the serial number is used internally so +.Fa serial +should be freed up after use. +.Sh RETURN VALUES +.Fn X509_get_serialNumber +and +.Fn X509_get0_serialNumber +return a pointer to an +.Vt ASN1_INTEGER +structure. +.Pp +.Fn X509_set_serialNumber +returns 1 for success or 0 for failure. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_NAME_add_entry_by_txt 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_new 3 , +.Xr X509_sign 3 , +.Xr X509_verify_cert 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +.Fn X509_get_serialNumber +and +.Fn X509_set_serialNumber +first appeared in SSLeay 0.6.5 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_get0_serialNumber +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.4 . diff --git a/Libraries/libressl/man/X509_get_subject_name.3 b/Libraries/libressl/man/X509_get_subject_name.3 new file mode 100644 index 000000000..fb9611f64 --- /dev/null +++ b/Libraries/libressl/man/X509_get_subject_name.3 @@ -0,0 +1,189 @@ +.\" $OpenBSD: X509_get_subject_name.3,v 1.10 2020/10/21 17:17:44 tb Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 21 2020 $ +.Dt X509_GET_SUBJECT_NAME 3 +.Os +.Sh NAME +.Nm X509_get_subject_name , +.Nm X509_set_subject_name , +.Nm X509_get_issuer_name , +.Nm X509_set_issuer_name , +.Nm X509_REQ_get_subject_name , +.Nm X509_REQ_set_subject_name , +.Nm X509_CRL_get_issuer , +.Nm X509_CRL_set_issuer_name +.Nd get and set issuer or subject names +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_NAME * +.Fo X509_get_subject_name +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_set_subject_name +.Fa "X509 *x" +.Fa "X509_NAME *name" +.Fc +.Ft X509_NAME * +.Fo X509_get_issuer_name +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_set_issuer_name +.Fa "X509 *x" +.Fa "X509_NAME *name" +.Fc +.Ft X509_NAME * +.Fo X509_REQ_get_subject_name +.Fa "const X509_REQ *req" +.Fc +.Ft int +.Fo X509_REQ_set_subject_name +.Fa "X509_REQ *req" +.Fa "X509_NAME *name" +.Fc +.Ft X509_NAME * +.Fo X509_CRL_get_issuer +.Fa "const X509_CRL *crl" +.Fc +.Ft int +.Fo X509_CRL_set_issuer_name +.Fa "X509_CRL *x" +.Fa "X509_NAME *name" +.Fc +.Sh DESCRIPTION +.Fn X509_get_subject_name +returns the subject name of certificate +.Fa x . +The returned value is an internal pointer which must not be freed. +.Pp +.Fn X509_set_subject_name +sets the issuer name of certificate +.Fa x +to +.Fa name . +The +.Fa name +parameter is copied internally and should be freed up when it is no +longer needed. +.Pp +.Fn X509_get_issuer_name +and +.Fn X509_set_issuer_name +are identical to +.Fn X509_get_subject_name +and +.Fn X509_set_subject_name +except that they get and set the issuer name of +.Fa x . +.Pp +Similarly +.Fn X509_REQ_get_subject_name , +.Fn X509_REQ_set_subject_name , +.Fn X509_CRL_get_issuer , +and +.Fn X509_CRL_set_issuer_name +get or set the subject or issuer names of certificate requests +of CRLs, respectively. +.Sh RETURN VALUES +.Fn X509_get_subject_name , +.Fn X509_get_issuer_name , +.Fn X509_REQ_get_subject_name , +and +.Fn X509_CRL_get_issuer +return a pointer to an +.Vt X509_NAME +object. +.Pp +.Fn X509_set_subject_name , +.Fn X509_set_issuer_name , +.Fn X509_REQ_set_subject_name , +and +.Fn X509_CRL_set_issuer_name +return 1 for success or 0 for failure. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_X509_NAME 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_NAME_add_entry_by_txt 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_new 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509_sign 3 , +.Xr X509_verify_cert 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +.Fn X509_get_subject_name +and +.Fn X509_get_issuer_name +appeared in SSLeay 0.4 or earlier. +.Fn X509_set_subject_name , +.Fn X509_set_issuer_name , +.Fn X509_REQ_get_subject_name , +and +.Fn X509_REQ_set_subject_name +first appeared in SSLeay 0.6.5. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_CRL_get_issuer +first appeared in OpenSSL 0.9.2b and has been available since +.Ox 2.6 . +.Pp +.Fn X509_CRL_set_issuer_name +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/X509_get_version.3 b/Libraries/libressl/man/X509_get_version.3 new file mode 100644 index 000000000..ee46ff7c8 --- /dev/null +++ b/Libraries/libressl/man/X509_get_version.3 @@ -0,0 +1,162 @@ +.\" $OpenBSD: X509_get_version.3,v 1.8 2020/10/21 17:17:44 tb Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 21 2020 $ +.Dt X509_GET_VERSION 3 +.Os +.Sh NAME +.Nm X509_get_version , +.Nm X509_set_version , +.Nm X509_REQ_get_version , +.Nm X509_REQ_set_version , +.Nm X509_CRL_get_version , +.Nm X509_CRL_set_version +.Nd get or set certificate, certificate request, or CRL version +.Sh SYNOPSIS +.In openssl/x509.h +.Ft long +.Fo X509_get_version +.Fa "const X509 *x" +.Fc +.Ft int +.Fo X509_set_version +.Fa "X509 *x" +.Fa "long version" +.Fc +.Ft long +.Fo X509_REQ_get_version +.Fa "const X509_REQ *req" +.Fc +.Ft int +.Fo X509_REQ_set_version +.Fa "X509_REQ *x" +.Fa "long version" +.Fc +.Ft long +.Fo X509_CRL_get_version +.Fa "const X509_CRL *crl" +.Fc +.Ft int +.Fo X509_CRL_set_version +.Fa "X509_CRL *x" +.Fa "long version" +.Fc +.Sh DESCRIPTION +.Fn X509_get_version +returns the numerical value of the version field of certificate +.Fa x . +Note: this is defined by standards (X.509 et al.) to be one less +than the certificate version. +So a version 3 certificate will return 2 and a version 1 certificate +will return 0. +.Pp +.Fn X509_set_version +sets the numerical value of the version field of certificate +.Fa x +to +.Fa version . +.Pp +Similarly +.Fn X509_REQ_get_version , +.Fn X509_REQ_set_version , +.Fn X509_CRL_get_version , +and +.Fn X509_CRL_set_version +get and set the version number of certificate requests and CRLs. +.Pp +The version field of certificates, certificate requests, and CRLs +has a DEFAULT value of v1(0) meaning the field should be omitted +for version 1. +This is handled transparently by these functions. +.Sh RETURN VALUES +.Fn X509_get_version , +.Fn X509_REQ_get_version , +and +.Fn X509_CRL_get_version +return the numerical value of the version field. +.Pp +.Fn X509_set_version , +.Fn X509_REQ_set_version , +and +.Fn X509_CRL_set_version +return 1 for success or 0 for failure. +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_NAME_add_entry_by_txt 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509_sign 3 , +.Xr X509_verify_cert 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +.Fn X509_get_version , +.Fn X509_set_version , +.Fn X509_REQ_get_version , +and +.Fn X509_REQ_set_version +first appeared in SSLeay 0.6.5 and have been available since +.Ox 2.4 . +.Pp +.Fn X509_CRL_get_version +first appeared in OpenSSL 0.9.2b and has been available since +.Ox 2.6 . +.Pp +.Fn X509_CRL_set_version +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/X509_keyid_set1.3 b/Libraries/libressl/man/X509_keyid_set1.3 new file mode 100644 index 000000000..c529fc742 --- /dev/null +++ b/Libraries/libressl/man/X509_keyid_set1.3 @@ -0,0 +1,171 @@ +.\" $OpenBSD: X509_keyid_set1.3,v 1.2 2021/07/09 14:41:14 tb Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 9 2021 $ +.Dt X509_KEYID_SET1 3 +.Os +.Sh NAME +.Nm X509_keyid_set1 , +.Nm X509_keyid_get0 , +.Nm X509_alias_set1 , +.Nm X509_alias_get0 +.Nd auxiliary certificate data for PKCS#12 +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_keyid_set1 +.Fa "X509 *x" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft unsigned char * +.Fo X509_keyid_get0 +.Fa "X509 *x" +.Fa "int *plen" +.Fc +.Ft int +.Fo X509_alias_set1 +.Fa "X509 *x" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft unsigned char * +.Fo X509_alias_get0 +.Fa "X509 *x" +.Fa "int *plen" +.Fc +.Sh DESCRIPTION +These functions store non-standard auxiliary data in +.Fa x +and retrieve it. +.Pp +The +.Fa len +bytes of +.Fa data +stored using +.Fn X509_keyid_set1 +will be written to the +.Sy localKeyID +attribute of the PKCS#12 structure if +.Xr PKCS12_create 3 +is later called on +.Fa x , +and the +.Fa data +stored using +.Fn X509_alias_set1 +will be written to the +.Sy friendlyName +attribute. +If +.Fa data +points to a NUL-terminated string, \-1 can be passed as the +.Fa len +argument to let +.Fa len +be calculated internally using +.Xr strlen 3 . +If a +.Dv NULL +pointer is passed as the +.Fa data +argument, the respective auxiliary data stored in +.Fa x , +if any, is removed from +.Fa x +and freed. +.Pp +Conversely, +.Xr PKCS12_parse 3 +retrieves these attributes from a PKCS#12 structure such that they can +subsequently be accessed with +.Fn X509_keyid_get0 +and +.Fn X509_alias_get0 . +Unless +.Dv NULL +is passed for the +.Fa plen +argument, these functions store the size of the returned buffer in bytes in +.Pf * Fa plen . +After the call, the returned buffer is not necessarily NUL-terminated, +but it may contain internal NUL bytes. +.Pp +API design is very incomplete; given the complexity of PKCS#12, +that's probably an asset rather than a defect. +The PKCS#12 standard defines many attributes that cannot be stored in +.Vt X509 +objects. +.Pp +To associate certificates with alternative names and key identifiers, +X.509 certificate extensions are more commonly used than PKCS#12 +attributes, for example using +.Xr X509_EXTENSION_create_by_NID 3 +with +.Dv NID_subject_alt_name +or +.Dv NID_subject_key_identifier . +.Sh RETURN VALUES +.Fn X509_keyid_set1 +and +.Fn X509_alias_set1 +return 1 if +.Fa data +is +.Dv NULL +or if the input +.Fa data +was successfully copied into +.Fa x , +or 0 if +.Fa data +is not +.Dv NULL +but could not be copied because +.Fa x +is +.Dv NULL +or memory allocation failed. +.Pp +.Fn X509_keyid_get0 +and +.Fn X509_alias_get0 +return an internal pointer to an array of bytes or +.Dv NULL +if +.Fa x +does not contain auxiliary data of the requested kind. +.Sh SEE ALSO +.Xr ASN1_STRING_set 3 , +.Xr X509_CERT_AUX_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +.Fn X509_alias_set1 +and +.Fn X509_alias_get0 +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn X509_keyid_set1 +first appeared in OpenSSL 0.9.6 and has been available since +.Ox 2.9 . +.Pp +.Fn X509_keyid_get0 +first appeared in OpenSSL 0.9.8 and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/X509_load_cert_file.3 b/Libraries/libressl/man/X509_load_cert_file.3 new file mode 100644 index 000000000..95a83dd00 --- /dev/null +++ b/Libraries/libressl/man/X509_load_cert_file.3 @@ -0,0 +1,133 @@ +.\" $OpenBSD: X509_load_cert_file.3,v 1.1 2021/11/09 16:23:04 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 9 2021 $ +.Dt X509_LOAD_CERT_FILE 3 +.Os +.Sh NAME +.Nm X509_load_cert_file , +.Nm X509_load_crl_file , +.Nm X509_load_cert_crl_file +.Nd read, decode, and cache certificates and CRLs +.Sh SYNOPSIS +.In openssl/x509_vfy.h +.Ft int +.Fo X509_load_cert_file +.Fa "X509_LOOKUP *ctx" +.Fa "const char *file" +.Fa "int type" +.Fc +.Ft int +.Fo X509_load_crl_file +.Fa "X509_LOOKUP *ctx" +.Fa "const char *file" +.Fa "int type" +.Fc +.Ft int +.Fo X509_load_cert_crl_file +.Fa "X509_LOOKUP *ctx" +.Fa "const char *file" +.Fa "int type" +.Fc +.Sh DESCRIPTION +.Fn X509_load_cert_file +with a +.Fa type +of +.Dv X509_FILETYPE_PEM +reads one or more certificates in PEM format from the given +.Fa file +using +.Xr PEM_read_bio_X509_AUX 3 ; +with a type of +.Dv X509_FILETYPE_ASN1 , +if reads one certificate in DER format using +.Xr d2i_X509_bio 3 . +The certificates read are added to the +.Vt X509_STORE +memory cache object associated with the given +.Fa ctx +using +.Xr X509_STORE_add_cert 3 . +.Pp +.Fn X509_load_crl_file +with a +.Fa type +of +.Dv X509_FILETYPE_PEM +reads one or more certificate revocation lists in PEM format from the given +.Fa file +using +.Xr PEM_read_bio_X509_CRL 3 ; +with a type of +.Dv X509_FILETYPE_ASN1 , +if reads one certificate revocation lists in DER format using +.Xr d2i_X509_CRL_bio 3 . +The certificate revocation lists read are added to the +.Vt X509_STORE +memory cache object associated with the given +.Fa ctx +using +.Xr X509_STORE_add_crl 3 . +.Pp +.Fn X509_load_cert_crl_file +with a +.Fa type +of +.Dv X509_FILETYPE_PEM +read one or more certificates and/or certificate revocation lists +in PEM format from the given +.Fa file +using +.Xr PEM_X509_INFO_read_bio 3 +and adds them to the +.Vt X509_STORE +memory cache object associated with the given +.Fa ctx +using +.Xr X509_STORE_add_cert 3 +and +.Xr X509_STORE_add_crl 3 , +respectively. +.Pp +.Fn X509_load_cert_crl_file +with a +.Fa type +of +.Dv X509_FILETYPE_ASN1 +is equivalent to +.Fn X509_load_cert_file +and cannot be used to read a certificate revocation list. +.Sh RETURN VALUES +These functions return the number of objects loaded or 0 on error. +.Sh SEE ALSO +.Xr d2i_X509_bio 3 , +.Xr PEM_read_PrivateKey 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_OBJECT_get0_X509 3 , +.Xr X509_STORE_load_locations 3 , +.Xr X509_STORE_new 3 +.Sh HISTORY +.Fn X509_load_cert_file +first appeared in SSLeay 0.8.0 and +.Fn X509_load_crl_file +in SSLeay 0.9.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_load_cert_crl_file +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509_new.3 b/Libraries/libressl/man/X509_new.3 new file mode 100644 index 000000000..3e7fb0a79 --- /dev/null +++ b/Libraries/libressl/man/X509_new.3 @@ -0,0 +1,281 @@ +.\" $OpenBSD: X509_new.3,v 1.43 2023/09/29 08:57:49 tb Exp $ +.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2018, 2019, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2006, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 29 2023 $ +.Dt X509_NEW 3 +.Os +.Sh NAME +.Nm X509_new , +.Nm X509_dup , +.Nm X509_REQ_to_X509 , +.Nm X509_free , +.Nm X509_up_ref , +.Nm X509_chain_up_ref +.Nd X.509 certificate object +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509 * +.Fn X509_new void +.Ft X509 * +.Fo X509_dup +.Fa "X509 *a" +.Fc +.Ft X509 * +.Fo X509_REQ_to_X509 +.Fa "X509_REQ *req" +.Fa "int days" +.Fa "EVP_PKEY *pkey" +.Fc +.Ft void +.Fo X509_free +.Fa "X509 *a" +.Fc +.Ft int +.Fo X509_up_ref +.Fa "X509 *a" +.Fc +.Ft STACK_OF(X509) * +.Fo X509_chain_up_ref +.Fa "STACK_OF(X509) *chain" +.Fc +.Sh DESCRIPTION +.Fn X509_new +allocates and initializes an empty +.Vt X509 +object with reference count 1. +It represents an ASN.1 +.Vt Certificate +structure defined in RFC 5280 section 4.1. +It can hold a public key together with information about the person, +organization, device, or function the associated private key belongs to. +.Pp +.Fn X509_dup +creates a deep copy of +.Fa a +using +.Xr ASN1_item_dup 3 , +setting the reference count of the copy to 1. +.Pp +.Fn X509_REQ_to_X509 +allocates a new certificate object, copies the public key from +.Fa req +into it, copies the subject name of +.Fa req +to both the subject and issuer names of the new certificate, sets the +.Fa notBefore +field to the current time and the +.Fa notAfter +field to the given number of +.Fa days +in the future, and signs the new certificate with +.Xr X509_sign 3 +using +.Fa pkey +and the MD5 algorithm. +If +.Fa req +contains at least one attribute, +the version of the new certificate is set to 2. +.Pp +.Fn X509_free +decrements the reference count of the +.Vt X509 +structure +.Fa a +and frees it up if the reference count reaches 0. +If +.Fa a +is a +.Dv NULL +pointer, no action occurs. +.Pp +.Fn X509_up_ref +increments the reference count of +.Fa a +by 1. +This function is useful if a certificate structure is being used +by several different operations each of which will free it up after +use: this avoids the need to duplicate the entire certificate +structure. +.Pp +.Fn X509_chain_up_ref +performs a shallow copy of the given +.Fa chain +using +.Fn sk_X509_dup +and increments the reference count of each contained certificate +by 1. +Its purpose is similar to +.Fn X509_up_ref : +The returned chain persists after the original is freed. +.Sh RETURN VALUES +.Fn X509_new , +.Fn X509_dup , +and +.Fn X509_REQ_to_X509 +return a pointer to the newly allocated object or +.Dv NULL +if an error occurs; an error code can be obtained by +.Xr ERR_get_error 3 . +.Pp +.Fn X509_up_ref +returns 1 for success or 0 for failure. +.Pp +.Fn X509_chain_up_ref +returns the copy of the +.Fa chain +or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr ASRange_new 3 , +.Xr AUTHORITY_KEYID_new 3 , +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr crypto 3 , +.Xr d2i_X509 3 , +.Xr IPAddressRange_new 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +.Xr X509_ALGOR_new 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509_check_ca 3 , +.Xr X509_check_host 3 , +.Xr X509_check_issued 3 , +.Xr X509_check_private_key 3 , +.Xr X509_check_purpose 3 , +.Xr X509_check_trust 3 , +.Xr X509_CINF_new 3 , +.Xr X509_cmp 3 , +.Xr X509_CRL_new 3 , +.Xr X509_digest 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_find_by_subject 3 , +.Xr X509_get0_notBefore 3 , +.Xr X509_get0_signature 3 , +.Xr X509_get1_email 3 , +.Xr X509_get_ex_new_index 3 , +.Xr X509_get_extension_flags 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_pubkey_parameters 3 , +.Xr X509_get_serialNumber 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_get_version 3 , +.Xr X509_INFO_new 3 , +.Xr X509_load_cert_file 3 , +.Xr X509_LOOKUP_hash_dir 3 , +.Xr X509_LOOKUP_new 3 , +.Xr X509_NAME_new 3 , +.Xr X509_OBJECT_new 3 , +.Xr X509_PKEY_new 3 , +.Xr X509_print_ex 3 , +.Xr X509_PUBKEY_new 3 , +.Xr X509_PURPOSE_set 3 , +.Xr X509_REQ_new 3 , +.Xr X509_SIG_new 3 , +.Xr X509_sign 3 , +.Xr X509_STORE_CTX_new 3 , +.Xr X509_STORE_get_by_subject 3 , +.Xr X509_STORE_new 3 , +.Xr X509_TRUST_set 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_addr_get_range 3 , +.Xr X509v3_addr_inherits 3 , +.Xr X509v3_addr_subset 3 , +.Xr X509v3_addr_validate_path 3 , +.Xr X509v3_asid_add_id_or_range 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn X509_new +and +.Fn X509_free +appeared in SSLeay 0.4 or earlier, +.Fn X509_dup +in SSLeay 0.4.4, and +.Fn X509_REQ_to_X509 +in SSLeay 0.6.0 . +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_up_ref +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.1 . +.Pp +.Fn X509_chain_up_ref +first appeared in OpenSSL 1.0.2 and has been available since +.Ox 6.3 . +.Sh BUGS +The X.509 public key infrastructure and its data types contain too +many design bugs to list them. +For lots of examples, see the classic +.Lk https://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt\ + "X.509 Style Guide" +that +.An Peter Gutmann +published in 2000. diff --git a/Libraries/libressl/man/X509_ocspid_print.3 b/Libraries/libressl/man/X509_ocspid_print.3 new file mode 100644 index 000000000..b9b6c92fb --- /dev/null +++ b/Libraries/libressl/man/X509_ocspid_print.3 @@ -0,0 +1,58 @@ +.\" $OpenBSD: X509_ocspid_print.3,v 1.1 2021/08/06 21:45:55 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 6 2021 $ +.Dt X509_OCSPID_PRINT 3 +.Os +.Sh NAME +.Nm X509_ocspid_print +.Nd pretty-print hashes of subject name and public key +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_ocspid_print +.Fa "BIO *bio" +.Fa "X509 *issuer" +.Fc +.Sh DESCRIPTION +.Fn X509_ocspid_print +produces human-readable output to +.Fa bio +containing hexadecimal representations of SHA-1 hashes of the +DER-encoded forms of the subject name and the public key of the +.Fa issuer +certificate, as these hashes appear in OCSP requests. +.Sh RETURN VALUES +.Fn X509_ocspid_print +returns 1 for success or 0 for failure. +.Sh EXAMPLES +This function is used by the +.Fl ocspid +flag of the +.Xr openssl 1 +.Cm x509 +command. +.Sh SEE ALSO +.Xr EVP_sha1 3 , +.Xr i2d_X509_NAME 3 , +.Xr OCSP_cert_to_id 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_subject_name 3 +.Sh HISTORY +.Fn X509_ocspid_print +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/X509_print_ex.3 b/Libraries/libressl/man/X509_print_ex.3 new file mode 100644 index 000000000..1a2e0edbd --- /dev/null +++ b/Libraries/libressl/man/X509_print_ex.3 @@ -0,0 +1,281 @@ +.\" $OpenBSD: X509_print_ex.3,v 1.4 2021/10/29 09:42:07 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 29 2021 $ +.Dt X509_PRINT_EX 3 +.Os +.Sh NAME +.Nm X509_print_ex , +.Nm X509_CERT_AUX_print , +.Nm X509_print_ex_fp , +.Nm X509_print , +.Nm X509_print_fp +.Nd pretty-print an X.509 certificate +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_print_ex +.Fa "BIO *bio" +.Fa "X509 *x" +.Fa "unsigned long nameflags" +.Fa "unsigned long skipflags" +.Fc +.Ft int +.Fo X509_CERT_AUX_print +.Fa "BIO *bio" +.Fa "X509_CERT_AUX *aux" +.Fa "int indent" +.Fc +.Ft int +.Fo X509_print_ex_fp +.Fa "FILE *fp" +.Fa "X509 *x" +.Fa "unsigned long nameflags" +.Fa "unsigned long skipflags" +.Fc +.Ft int +.Fo X509_print +.Fa "BIO *bio" +.Fa "X509 *x" +.Fc +.Ft int +.Fo X509_print_fp +.Fa "FILE *fp" +.Fa "X509 *x" +.Fc +.Sh DESCRIPTION +.Fn X509_print_ex +prints information contained in +.Fa x +to +.Fa bio +in human-readable form. +Printing is aborted as soon as any operation fails, with the exception +that failures while attempting to decode or print the public key, +the X.509 version 3 extensions, or non-standard auxiliary data are +not considered as errors. +.Pp +By default, the following blocks of information are printed +in the following order. +Each block can be skipped by setting the corresponding bit in +.Fa skipflags , +provided in parentheses after each block description. +.Bl -bullet +.It +A pair of lines reading +.Qq Certificate:\& +and +.Qq Data:\& +containing no information. +.Pq Dv X509_FLAG_NO_HEADER +.It +The certificate version number as defined by the standard, +followed in parentheses by the value contained in the version field +in hexadecimal notation. +See +.Xr X509_get_version 3 +for details. +.Pq Dv X509_FLAG_NO_VERSION +.It +The serial number of the certificate as returned by +.Xr X509_get_serialNumber 3 . +If it is not \-1 and converting it to +.Vt long +succeeds, it is printed in both decimal and hexadecimal format. +If it is \-1, too wide to fit in +.Vt long , +or conversion fails, it is printed byte-by-byte in hexadecimal notation. +.Pq Dv X509_FLAG_NO_SERIAL +.It +The name of the signature algorithm is printed with +.Xr X509_signature_print 3 . +.Pq Dv X509_FLAG_NO_SIGNAME +.It +The issuer name returned by +.Xr X509_get_issuer_name 3 +is printed with +.Xr X509_NAME_print_ex 3 . +.Pq Dv X509_FLAG_NO_ISSUER +.It +The validity period from +.Xr X509_get_notBefore 3 +to +.Xr X509_get_notAfter 3 +is printed using +.Xr ASN1_TIME_print 3 . +.Pq Dv X509_FLAG_NO_VALIDITY +.It +The subject name returned from +.Xr X509_get_subject_name 3 +is printed with +.Xr X509_NAME_print_ex 3 . +.Pq Dv X509_FLAG_NO_SUBJECT +.It +The public key algorithm is printed with +.Xr i2a_ASN1_OBJECT 3 , +and the public key returned from +.Xr X509_get_pubkey 3 +with +.Xr EVP_PKEY_print_public 3 . +.Pq Dv X509_FLAG_NO_PUBKEY +.It +All X.509 extensions contained in the certificate are printed with +.Xr X509V3_extensions_print 3 . +.Pq Dv X509_FLAG_NO_EXTENSIONS +.It +The signature is printed with +.Xr X509_signature_print 3 . +.Pq Dv X509_FLAG_NO_SIGDUMP +.It +Non-standard auxiliary data associated with the certificate is printed +using the function +.Fn X509_CERT_AUX_print +documented below. +.Pq Dv X509_FLAG_NO_AUX +.El +.Pp +The +.Fa nameflags +argument modifies the format for printing X.501 +.Vt Name +objects contained in +.Fa x . +It is passed through to +.Xr X509_NAME_print_ex 3 . +If +.Fa nameflags +is +.Dv X509_FLAG_COMPAT , +the +.Fa indent +argument of +.Xr X509_NAME_print_ex 3 +is set to 16 spaces and the traditional SSLeay format generated by +.Xr X509_NAME_print 3 +is used. +Otherwise, if the only bit set in +.Dv XN_FLAG_SEP_MASK +is +.Dv XN_FLAG_SEP_MULTILINE , +.Fa indent +is set to 12 spaces. +Otherwise, +.Fa indent +is set to zero. +.Pp +.Fn X509_CERT_AUX_print +prints information contained in +.Fa aux +to +.Fa bio +in human-readable form with a left margin of +.Fa indent +spaces. +If +.Fa aux +is +.Dv NULL , +it prints nothing. +.Pp +Information is printed in the following order: +.Bl -bullet +.It +Purposes the certificate is intended to be used for as set with +.Xr X509_add1_trust_object 3 , +each printed with +.Xr OBJ_obj2txt 3 . +.It +Purposes the certificate is explicitly +.Em not +intended to be used for as set with +.Xr X509_add1_reject_object 3 , +again each printed with +.Xr OBJ_obj2txt 3 . +.It +If +.Fa aux +contains data set with +.Xr X509_alias_set1 3 , +the raw bytes are printed in unencoded form. +.It +If +.Fa aux +contains data set with +.Xr X509_keyid_set1 3 , +the bytes are printed in hexadecimal notation with colons in between. +.El +.Pp +.Fn X509_print_ex_fp +is similar to +.Fn X509_print_ex +except that it prints to +.Fa fp . +.Pp +.Fn X509_print +and +.Fn X509_print_fp +are wrapper functions setting the +.Fa nameflags +to +.Dv XN_FLAG_COMPAT +and the +.Fa skipflags +to +.Dv X509_FLAG_COMPAT . +.Sh RETURN VALUES +.Fn X509_print_ex , +.Fn X509_print_ex_fp , +.Fn X509_print , +and +.Fn X509_print_fp +return 1 if all requested information was successfully printed, +even if failures occurred while attempting to decode or print the +public key or X.509 version 3 extensions, or 0 if any other operation +failed. +.Pp +.Fn X509_CERT_AUX_print +always returns 1 and silently ignores write errors. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr X509_CERT_AUX_new 3 , +.Xr X509_CRL_print 3 , +.Xr X509_new 3 , +.Xr X509_REQ_print_ex 3 +.Sh HISTORY +.Fn X509_print +first appeared in SSLeay 0.5.1 and was changed to print to a +.Vt BIO +in SSLeay 0.6.0. +.Fn X509_print_fp +first appeared in SSLeay 0.6.0. +Both functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_CERT_AUX_print +first appeared in OpenSSL 0.9.5 and has been available since +.Ox 2.7 . +.Pp +.Fn X509_print_ex +and +.Fn X509_print_ex_fp +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . +.Sh BUGS +If arbitrary data was stored into +.Fa x +using +.Xr X509_alias_set1 3 , +these functions may print binary data and even NUL bytes. diff --git a/Libraries/libressl/man/X509_sign.3 b/Libraries/libressl/man/X509_sign.3 new file mode 100644 index 000000000..52890207f --- /dev/null +++ b/Libraries/libressl/man/X509_sign.3 @@ -0,0 +1,220 @@ +.\" $OpenBSD: X509_sign.3,v 1.10 2023/04/28 15:51:18 job Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015, 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: April 28 2023 $ +.Dt X509_SIGN 3 +.Os +.Sh NAME +.Nm X509_sign , +.Nm X509_sign_ctx , +.Nm X509_verify , +.Nm X509_REQ_sign , +.Nm X509_REQ_sign_ctx , +.Nm X509_REQ_verify , +.Nm X509_CRL_sign , +.Nm X509_CRL_sign_ctx , +.Nm X509_CRL_verify +.Nd sign or verify certificate, certificate request, or CRL signature +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_sign +.Fa "X509 *x" +.Fa "EVP_PKEY *pkey" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo X509_sign_ctx +.Fa "X509 *x" +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft int +.Fo X509_verify +.Fa "X509 *a" +.Fa "EVP_PKEY *r" +.Fc +.Ft int +.Fo X509_REQ_sign +.Fa "X509_REQ *x" +.Fa "EVP_PKEY *pkey" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo X509_REQ_sign_ctx +.Fa "X509_REQ *x" +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft int +.Fo X509_REQ_verify +.Fa "X509_REQ *a" +.Fa "EVP_PKEY *r" +.Fc +.Ft int +.Fo X509_CRL_sign +.Fa "X509_CRL *x" +.Fa "EVP_PKEY *pkey" +.Fa "const EVP_MD *md" +.Fc +.Ft int +.Fo X509_CRL_sign_ctx +.Fa "X509_CRL *x" +.Fa "EVP_MD_CTX *ctx" +.Fc +.Ft int +.Fo X509_CRL_verify +.Fa "X509_CRL *a" +.Fa "EVP_PKEY *r" +.Fc +.Sh DESCRIPTION +.Fn X509_sign +signs the certificate +.Fa x +using the private key +.Fa pkey +and the message digest +.Fa md +and sets the signature in +.Fa x . +.Fn X509_sign_ctx +also signs the certificate +.Fa x +but uses the parameters contained in digest context +.Fa ctx . +.Pp +.Fn X509_verify +verifies the signature of certificate +.Fa x +using the public key +.Fa pkey . +Only the signature is checked: no other checks (such as certificate +chain validity) are performed. +.Pp +.Fn X509_REQ_sign , +.Fn X509_REQ_sign_ctx , +.Fn X509_REQ_verify , +.Fn X509_CRL_sign , +.Fn X509_CRL_sign_ctx , +and +.Fn X509_CRL_verify +sign and verify certificate requests and CRLs, respectively. +.Pp +If +.Xr X509_CRL_set_default_method 3 +was in effect at the time the +.Vt X509_CRL +object was created, +.Fn X509_CRL_verify +calls the +.Fn crl_verify +callback function instead of performing the default action. +.Pp +.Fn X509_sign_ctx +is used where the default parameters for the corresponding public key +and digest are not suitable. +It can be used to sign keys using RSA-PSS for example. +.Sh RETURN VALUES +.Fn X509_sign , +.Fn X509_sign_ctx , +.Fn X509_REQ_sign , +.Fn X509_REQ_sign_ctx , +.Fn X509_CRL_sign , +and +.Fn X509_CRL_sign_ctx +return the size of the signature in bytes for success or 0 for failure. +.Pp +.Fn X509_verify , +.Fn X509_REQ_verify , +and +.Fn X509_CRL_verify +return 1 if the signature is valid or 0 if the signature check fails. +If the signature could not be checked at all because it was invalid or +some other error occurred, then -1 is returned. +.Pp +In some cases of failure, the reason can be determined with +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr EVP_DigestInit 3 , +.Xr X509_CRL_get0_by_serial 3 , +.Xr X509_CRL_METHOD_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_get_subject_name 3 , +.Xr X509_get_version 3 , +.Xr X509_NAME_add_entry_by_txt 3 , +.Xr X509_NAME_ENTRY_get_object 3 , +.Xr X509_NAME_get_index_by_NID 3 , +.Xr X509_NAME_print_ex 3 , +.Xr X509_new 3 , +.Xr X509_REQ_new 3 , +.Xr X509_verify_cert 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +.Fn X509_verify +appeared in SSLeay 0.4 or earlier. +.Fn X509_sign +and +.Fn X509_REQ_sign +first appeared in SSLeay 0.4.4. +.Fn X509_REQ_verify +and +.Fn X509_CRL_verify +first appeared in SSLeay 0.4.5b. +.Fn X509_CRL_sign +first appeared in SSLeay 0.5.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_sign_ctx , +.Fn X509_REQ_sign_ctx , +and +.Fn X509_CRL_sign_ctx +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/X509_signature_dump.3 b/Libraries/libressl/man/X509_signature_dump.3 new file mode 100644 index 000000000..bc41cc8b6 --- /dev/null +++ b/Libraries/libressl/man/X509_signature_dump.3 @@ -0,0 +1,85 @@ +.\" $OpenBSD: X509_signature_dump.3,v 1.2 2021/12/18 17:47:45 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 18 2021 $ +.Dt X509_SIGNATURE_DUMP 3 +.Os +.Sh NAME +.Nm X509_signature_dump , +.Nm X509_signature_print +.Nd pretty-print ASN.1 strings +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_signature_dump +.Fa "BIO *bio" +.Fa "const ASN1_STRING *signature" +.Fa "int indent" +.Fc +.Ft int +.Fo X509_signature_print +.Fa "BIO *bio" +.Fa "const X509_ALGOR *algorithm" +.Fa "const ASN1_STRING *signature" +.Fc +.Sh DESCRIPTION +.Fn X509_signature_dump +writes the data bytes contained in the +.Fa signature +to +.Fa bio +in hexadecimal format with colons between bytes, +18 bytes per output line, each line indented with +.Fa indent +space characters. +.Pp +.Fn X509_signature_print +writes the name of the signature +.Fa algorithm , +or, if no name for it is known, its object identifier (OID) to +.Fa bio +using +.Xr i2a_ASN1_OBJECT 3 . +After that, if a method object for the algorithm can be retrieved with +.Xr EVP_PKEY_asn1_find 3 +and if that object defines a printing method, that printing method is +used to print the +.Fa signature . +Otherwise, unless the +.Fa signature +is +.Dv NULL , +it is printed using +.Fn X509_signature_dump . +.Sh RETURN VALUES +These functions return 1 on success or 0 on failure. +They fail and return as soon as any write operation fails. +.Sh SEE ALSO +.Xr ASN1_STRING_new 3 , +.Xr ASN1_STRING_print_ex 3 , +.Xr BIO_new 3 , +.Xr EVP_PKEY_asn1_new 3 , +.Xr OBJ_find_sigid_algs 3 , +.Xr X509_ALGOR_new 3 , +.Xr X509_get0_signature 3 +.Sh HISTORY +.Fn X509_signature_print +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . +.Pp +.Fn X509_signature_dump +first appeared in OpenSSL 1.0.1 and has been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/X509_verify_cert.3 b/Libraries/libressl/man/X509_verify_cert.3 new file mode 100644 index 000000000..9c085d778 --- /dev/null +++ b/Libraries/libressl/man/X509_verify_cert.3 @@ -0,0 +1,93 @@ +.\" $OpenBSD: X509_verify_cert.3,v 1.8 2019/06/06 01:06:59 schwarze Exp $ +.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2009, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 6 2019 $ +.Dt X509_VERIFY_CERT 3 +.Os +.Sh NAME +.Nm X509_verify_cert +.Nd discover and verify X509 certificate chain +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509_verify_cert +.Fa "X509_STORE_CTX *ctx" +.Fc +.Sh DESCRIPTION +The +.Fn X509_verify_cert +function attempts to discover and validate a certificate chain based on +parameters in +.Fa ctx . +.Pp +Applications rarely call this function directly, but it is used by +OpenSSL internally for certificate validation, in both the S/MIME and +SSL/TLS code. +.Sh RETURN VALUES +If a complete chain can be built and validated this function returns 1, +otherwise it returns a value <= 0 indicating failure. +.Pp +Additional error information can be obtained by examining +.Fa ctx , +using +.Xr X509_STORE_CTX_get_error 3 . +.Sh SEE ALSO +.Xr openssl 1 , +.Xr X509_STORE_CTX_get_error 3 , +.Xr X509_STORE_CTX_new 3 +.Sh HISTORY +.Fn X509_verify_cert +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . +.Sh BUGS +This function uses the header +.In openssl/x509.h +as opposed to most chain verification functions which use +.In openssl/x509_vfy.h . diff --git a/Libraries/libressl/man/X509at_add1_attr.3 b/Libraries/libressl/man/X509at_add1_attr.3 new file mode 100644 index 000000000..3d29c56ef --- /dev/null +++ b/Libraries/libressl/man/X509at_add1_attr.3 @@ -0,0 +1,134 @@ +.\" $OpenBSD: X509at_add1_attr.3,v 1.5 2021/10/26 12:56:48 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 26 2021 $ +.Dt X509AT_ADD1_ATTR 3 +.Os +.Sh NAME +.Nm X509at_add1_attr , +.Nm X509at_add1_attr_by_OBJ , +.Nm X509at_add1_attr_by_NID , +.Nm X509at_add1_attr_by_txt , +.Nm X509at_delete_attr +.Nd change an array of X.501 Attribute objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft STACK_OF(X509_ATTRIBUTE) * +.Fo X509at_add1_attr +.Fa "STACK_OF(X509_ATTRIBUTE) **pattrs" +.Fa "X509_ATTRIBUTE *attr" +.Fc +.Ft STACK_OF(X509_ATTRIBUTE) * +.Fo X509at_add1_attr_by_OBJ +.Fa "STACK_OF(X509_ATTRIBUTE) **pattrs" +.Fa "const ASN1_OBJECT *obj" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft STACK_OF(X509_ATTRIBUTE) * +.Fo X509at_add1_attr_by_NID +.Fa "STACK_OF(X509_ATTRIBUTE) **pattrs" +.Fa "int nid" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft STACK_OF(X509_ATTRIBUTE) * +.Fo X509at_add1_attr_by_txt +.Fa "STACK_OF(X509_ATTRIBUTE) **pattrs" +.Fa "const char *name" +.Fa "int type" +.Fa "const unsigned char *data" +.Fa "int len" +.Fc +.Ft X509_ATTRIBUTE * +.Fo X509at_delete_attr +.Fa "STACK_OF(X509_ATTRIBUTE) *attrs" +.Fa "int index" +.Fc +.Sh DESCRIPTION +.Fn X509at_add1_attr +appends a deep copy of +.Fa attr +to the end of +.Pf ** Fa pattrs . +If +.Pf * Fa pattrs +is +.Dv NULL , +a new array is allocated, and in case of success, +a pointer to it is assigned to +.Pf * Fa pattrs . +.Pp +.Fn X509at_add1_attr_by_OBJ , +.Fn X509at_add1_attr_by_NID , +and +.Fn X509at_add1_attr_by_txt +create a new X.501 Attribute object using +.Xr X509_ATTRIBUTE_create_by_OBJ 3 , +.Xr X509_ATTRIBUTE_create_by_NID 3 , +or +.Xr X509_ATTRIBUTE_create_by_txt 3 , +respectively, and append it to +.Pf ** Fa pattrs +using +.Fn X509at_add1_attr . +.Pp +.Fn X509at_delete_attr +deletes the element with the zero-based +.Fa index +from the array +.Pf * Fa attrs . +.Sh RETURN VALUES +.Fn X509at_add1_attr , +.Fn X509at_add1_attr_by_OBJ , +.Fn X509at_add1_attr_by_NID , +and +.Fn X509at_add1_attr_by_txt +return a pointer to the modified or new array or +.Dv NULL +if the +.Fa pattrs +argument is +.Dv NULL +or if creating or copying the X.501 Attribute object +or memory allocation fails. +.Pp +.Fn X509at_delete_attr +returns the deleted element or +.Dv NULL +if +.Fa attrs +is +.Dv NULL +or if the requested +.Fa index +is negative or greater than or equal to the number of objects in +.Pf * Fa attrs . +.Sh SEE ALSO +.Xr EVP_PKEY_add1_attr 3 , +.Xr OBJ_nid2obj 3 , +.Xr PKCS8_pkey_add1_attr_by_NID 3 , +.Xr STACK_OF 3 , +.Xr X509_ATTRIBUTE_create_by_OBJ 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509_REQ_add1_attr 3 , +.Xr X509at_get_attr 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/X509at_get_attr.3 b/Libraries/libressl/man/X509at_get_attr.3 new file mode 100644 index 000000000..82f786a41 --- /dev/null +++ b/Libraries/libressl/man/X509at_get_attr.3 @@ -0,0 +1,160 @@ +.\" $OpenBSD: X509at_get_attr.3,v 1.7 2022/03/28 08:18:13 claudio Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 28 2022 $ +.Dt X509AT_GET_ATTR 3 +.Os +.Sh NAME +.Nm X509at_get_attr , +.Nm X509at_get_attr_count , +.Nm X509at_get_attr_by_OBJ , +.Nm X509at_get_attr_by_NID , +.Nm X509at_get0_data_by_OBJ +.\" In the following line, "X.501" and "Attribute" are not typos. +.\" The "Attribute" type is defined in X.501, not in X.509. +.\" The type is called "Attribute" with capital "A", not "attribute". +.Nd X.501 Attribute array read accessors +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_ATTRIBUTE * +.Fo X509at_get_attr +.Fa "const STACK_OF(X509_ATTRIBUTE) *attrs" +.Fa "int index" +.Fc +.Ft int +.Fo X509at_get_attr_count +.Fa "const STACK_OF(X509_ATTRIBUTE) *attrs" +.Fc +.Ft int +.Fo X509at_get_attr_by_OBJ +.Fa "const STACK_OF(X509_ATTRIBUTE) *attrs" +.Fa "const ASN1_OBJECT *obj" +.Fa "int start_after" +.Fc +.Ft int +.Fo X509at_get_attr_by_NID +.Fa "const STACK_OF(X509_ATTRIBUTE) *attrs" +.Fa "int nid" +.Fa "int start_after" +.Fc +.Ft void * +.Fo X509at_get0_data_by_OBJ +.Fa "STACK_OF(X509_ATTRIBUTE) *attrs" +.Fa "const ASN1_OBJECT *obj" +.Fa "int start_after" +.Fa "int type" +.Fc +.Sh DESCRIPTION +These functions retrieve information from the +.Fa attrs +array of X.501 Attribute objects. +They all fail if +.Fa attrs +is a +.Dv NULL +pointer. +.Pp +.Fn X509at_get_attr +returns the array element at the zero-based +.Fa index . +It fails if the +.Fa index +is negative or greater than or equal to the number of objects in the array. +.Pp +.Fn X509at_get_attr_count +returns the number of objects currently stored in the array. +.Pp +The three remaining functions search the array starting after the index +.Fa start_after . +They fail if no matching object is found. +.Fn X509at_get0_data_by_OBJ +also fails if the data is not of the requested +.Fa type . +.Pp +Additionally, the +.Fa start_after +argument of +.Fn X509at_get0_data_by_OBJ +is interpreted in a special way. +If +.Fa start_after +is \-2 or smaller, +.Fn X509at_get0_data_by_OBJ +also fails if +.Fa attrs +contains more than one matching object. +If +.Fa start_after +is \-3 or smaller, it also fails unless the matching object +contains exactly one value. +.Sh RETURN VALUES +.Fn X509at_get_attr +returns an internal pointer or +.Dv NULL +on failure. +.Pp +.Fn X509at_get_attr_count +returns the number of array elements or \-1 on failure. +.Pp +.Fn X509at_get_attr_by_OBJ +and +.Fn X509at_get_attr_by_NID +return the index of the first object in the array +that has an index greater than +.Fa start_after +and a type matching +.Fa obj +or +.Fa nid , +respectively, or \-1 on failure. +In addition, +.Fn X509at_get_attr_by_NID +returns \-2 +if +.Xr OBJ_nid2obj 3 +fails on the requested +.Fa nid . +.Pp +.Fn X509at_get0_data_by_OBJ +returns an internal pointer to the data contained in the value +of the first object that has an index greater than +.Fa start_after +and a type matching +.Fa obj , +or +.Dv NULL +on failure. +.Sh SEE ALSO +.Xr EVP_PKEY_get_attr 3 , +.Xr OBJ_nid2obj 3 , +.Xr PKCS8_pkey_get0_attrs 3 , +.Xr STACK_OF 3 , +.Xr X509_ATTRIBUTE_get0_data 3 , +.Xr X509_ATTRIBUTE_new 3 , +.Xr X509_REQ_get_attr 3 , +.Xr X509at_add1_attr 3 +.Sh HISTORY +.Fn X509at_get_attr , +.Fn X509at_get_attr_count , +.Fn X509at_get_attr_by_OBJ , +and +.Fn X509at_get_attr_by_NID +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn X509at_get0_data_by_OBJ +first appeared in OpenSSL 0.9.8h and has been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/X509v3_addr_add_inherit.3 b/Libraries/libressl/man/X509v3_addr_add_inherit.3 new file mode 100644 index 000000000..4b2d150c8 --- /dev/null +++ b/Libraries/libressl/man/X509v3_addr_add_inherit.3 @@ -0,0 +1,475 @@ +.\" $OpenBSD: X509v3_addr_add_inherit.3,v 1.11 2023/10/01 22:46:21 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 1 2023 $ +.Dt X509V3_ADDR_ADD_INHERIT 3 +.Os +.Sh NAME +.Nm X509v3_addr_add_inherit , +.Nm X509v3_addr_add_prefix , +.Nm X509v3_addr_add_range , +.Nm X509v3_addr_canonize , +.Nm X509v3_addr_is_canonical +.Nd RFC 3779 IP address delegation extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509v3_addr_add_inherit +.Fa "IPAddrBlocks *addrblocks" +.Fa "const unsigned afi" +.Fa "const unsigned *safi" +.Fc +.Ft int +.Fo X509v3_addr_add_prefix +.Fa "IPAddrBlocks *addrblocks" +.Fa "const unsigned afi" +.Fa "const unsigned *safi" +.Fa "unsigned char *prefix" +.Fa "const int prefixlen" +.Fc +.Ft int +.Fo X509v3_addr_add_range +.Fa "IPAddrBlocks *addrblocks" +.Fa "const unsigned afi" +.Fa "const unsigned *safi" +.Fa "unsigned char *min" +.Fa "unsigned char *max" +.Fc +.Ft int +.Fo X509v3_addr_canonize +.Fa "IPAddrBlocks *addrblocks" +.Fc +.Ft int +.Fo X509v3_addr_is_canonical +.Fa "IPAddrBlocks *addrblocks" +.Fc +.Sh DESCRIPTION +An +.Vt IPAddrBlocks +object represents the content of +an IP address delegation extension +as defined in RFC 3779, section 2.2.3.1. +It holds lists of IP address prefixes and IP address ranges +delegated from the issuer to the subject of the certificate. +It can be instantiated as explained in the EXAMPLES section +and its internals are documented in +.Xr IPAddressRange_new 3 . +.Pp +Each list in a well-formed +.Vt IPAddrBlocks +object is uniquely identified by +an address family identifier (AFI) and +an optional subsequent address family identifier (SAFI). +Lists can be absent or can contain an +.Dq inherit +marker to indicate that the resources are to be inherited +from the corresponding list of the issuer certificate. +.Pp +Per specification, an AFI is an unsigned 16-bit integer and +a SAFI is an unsigned 8-bit integer. +For IPv4 and IPv6 there are the predefined constants +.Dv IANA_AFI_IPV4 +and +.Dv IANA_AFI_IPV6 , +which should be the only values used for +.Fa afi +in this API. +In practice, +.Fa safi +is always NULL. +.Fa afi +is generally silently truncated to its lowest 16 bits and, if +.Fa safi +is non-NULL, +only the lowest 8 bits of the value pointed at are used. +.Pp +.Fn X509v3_addr_add_inherit +adds a list with an +.Dq inherit +marker to +.Fa addrblocks . +If a list corresponding to +.Fa afi +and +.Fa safi +already exists, no action occurs if it is marked +.Dq inherit , +otherwise the call fails. +.Pp +.Fn X509v3_addr_add_prefix +adds a newly allocated internal representation of the +.Fa prefix +of length +.Fa prefixlen +to the list corresponding to +.Fa afi +and the optional +.Fa safi +in +.Fa addrblocks . +If no such list exists, it is created first. +If the list exists and is marked +.Dq inherit , +the call fails. +.Fa prefix +is expected to be a byte array in network byte order. +It should point at enough memory to accommodate +.Fa prefixlen +bits and it is recommended that all the bits not covered by the +.Fa prefixlen +be set to 0. +It is the caller's responsibility to ensure that the +.Fa prefix +has no address in common with any of +the prefixes or ranges already in the list. +If +.Fa afi +is +.Dv IANA_AFI_IPV4 , +.Fa prefixlen +should be between 0 and 32 (inclusive) and if +.Fa afi +is +.Dv IANA_AFI_IPV6 , +.Fa prefixlen +should be between 0 and 128 (inclusive). +.Pp +.Fn X509v3_addr_add_range +is similar to +.Fn X509v3_addr_add_prefix +for the closed interval of IP addresses between +.Fa min +and +.Fa max +in network presentation. +If +.Fa afi +is +.Dv IANA_AFI_IPV4 , +.Fa min +and +.Fa max +should point at 4 bytes of memory +and if +.Fa afi +is +.Dv IANA_AFI_IPV6 , +.Fa min +and +.Fa max +should point at 16 bytes of memory. +In case the range of IP addresses between +.Fa min +and +.Fa max +is a prefix, a prefix will be added instead of a range. +It is the caller's responsibility to ensure that +.Fa min +is less than or equal to +.Fa max +and that it does not contain any address already present +in the list. +Failure to do so will result in a subsequent failure of +.Fn X509v3_addr_canonize . +.Pp +.Fn X509v3_addr_canonize +attempts to bring the +.Pf non- Dv NULL +.Fa addrblocks +into canonical form. +An +.Vt IPAddrBlocks +object is said to be in canonical form if it conforms +to the ordering specified in RFC 3779: +section 2.2.3.3 requires that +the list of lists be sorted first by increasing +.Fa afi +and then by increasing +.Fa safi , +where NULL is the minimal SAFI; +section 2.2.3.6 requires that each list be in minimal form and sorted. +The minimality requirement is that all adjacent prefixes +and ranges must be merged into a single range and that each +range must be expressed as a prefix, if possible. +In particular, any given address can be in at most one list entry. +The order is by increasing minimal IP address in network byte order. +.Pp +.Fn X509v3_addr_is_canonical +indicates whether +.Fa addrblocks +is in canonical form. +.Sh RETURN VALUES +All these functions return 1 on success and 0 on failure. +Memory allocation failure is one possible reason for all of them. +Sometimes an error code can be obtained by +.Xr ERR_get_error 3 . +.Pp +.Fn X509v3_addr_add_inherit +fails if the list corresponding to +.Fa afi +and the optional +.Fa safi +already exists and is not marked +.Dq inherit . +.Pp +.Fn X509v3_addr_add_prefix +and +.Fn X509v3_addr_add_range +fail if a list corresponding to +.Fa afi +and the optional +.Fa safi +already exists and is marked +.Dq inherit , +or if +.Fa prefixlen +is outside the interval [0,32] for IPv4 addresses +or [0,128] for IPv6 addresses. +.Pp +.Fn X509v3_addr_canonize +fails if one of the lists in +.Fa addrblocks +is malformed, +in particular if it contains corrupt, overlapping, +or duplicate entries. +Corruption includes ranges where +.Fa max +is strictly smaller than +.Fa min . +The error conditions are generally indistinguishable. +.Pp +.Fn X509v3_addr_is_canonical +returns 1 if +.Fa addrblocks +is in canonical form. +A return value of 0 can indicate non-canonical form or a corrupted list. +.Sh EXAMPLES +Construct the first extension from RFC 3779, Appendix B. +.Bd -literal +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +const char *prefixes[] = { + "10.0.32/20", "10.0.64/24", "10.1/16", + "10.2.48/20", "10.2.64/24", "10.3/16", +}; +#define N_PREFIXES (sizeof(prefixes) / sizeof(prefixes[0])) + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + printf(" 0x%02x,%s", buf[i \- 1], i % 8 ? "" : "\en"); + if (len % 8) + printf("\en"); +} + +int +main(void) +{ + IPAddrBlocks *addrblocks; + X509_EXTENSION *ext; + unsigned char *der; + int der_len; + size_t i; + + if (pledge("stdio", NULL) == \-1) + err(1, "pledge"); + + /* + * Somebody forgot to implement IPAddrBlocks_new(). IPAddrBlocks + * is the same as STACK_OF(IPAddressFamily). As such, it should + * have IPAddressFamily_cmp() as its comparison function. It is + * not possible to call sk_new(3) because IPAddressFamily_cmp() + * is not part of the public API. The correct comparison function + * can be installed as a side-effect of X509v3_addr_canonize(3). + */ + if ((addrblocks = sk_IPAddressFamily_new_null()) == NULL) + err(1, "sk_IPAddressFamily_new_null"); + if (!X509v3_addr_canonize(addrblocks)) + errx(1, "X509v3_addr_canonize"); + + /* Add the prefixes as IPv4 unicast. */ + for (i = 0; i < N_PREFIXES; i++) { + unsigned char addr[16] = {0}; + int len; + int unicast = 1; /* SAFI for unicast forwarding. */ + + len = inet_net_pton(AF_INET, prefixes[i], addr, + sizeof(addr)); + if (len == \-1) + errx(1, "inet_net_pton(%s)", prefixes[i]); + if (!X509v3_addr_add_prefix(addrblocks, IANA_AFI_IPV4, + &unicast, addr, len)) + errx(1, "X509v3_addr_add_prefix(%s)", prefixes[i]); + } + if (!X509v3_addr_add_inherit(addrblocks, IANA_AFI_IPV6, NULL)) + errx(1, "X509v3_addr_add_inherit"); + + /* + * Ensure the extension is in canonical form. Otherwise the two + * adjacent prefixes 10.2.48/20 and 10.2.64/24 are not merged into + * the range 10.2.48.0--10.2.64.255. This results in invalid DER + * encoding from X509V3_EXT_i2d(3) and i2d_X509_EXTENSION(3). + */ + if (!X509v3_addr_canonize(addrblocks)) + errx(1, "X509v3_addr_canonize"); + + /* Create the extension with the correct OID; mark it critical. */ + ext = X509V3_EXT_i2d(NID_sbgp_ipAddrBlock, 1, addrblocks); + if (ext == NULL) + errx(1, "X509V3_EXT_i2d"); + + der = NULL; + if ((der_len = i2d_X509_EXTENSION(ext, &der)) <= 0) + errx(1, "i2d_X509_EXTENSION"); + + hexdump(der, der_len); + + /* One way of implementing IPAddrBlocks_free(). */ + sk_IPAddressFamily_pop_free(addrblocks, IPAddressFamily_free); + X509_EXTENSION_free(ext); + free(der); + + return 0; +} +.Ed +.Pp +Implement the missing public API +.Fn d2i_IPAddrBlocks +and +.Fn i2d_IPAddrBlocks +using +.Xr ASN1_item_d2i 3 : +.Bd -literal +IPAddrBlocks * +d2i_IPAddrBlocks(IPAddrBlocks **addrblocks, const unsigned char **in, + long len) +{ + const X509V3_EXT_METHOD *v3_addr; + + if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) + return NULL; + return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrblocks, + in, len, ASN1_ITEM_ptr(v3_addr\->it)); +} + +int +i2d_IPAddrBlocks(IPAddrBlocks *addrblocks, unsigned char **out) +{ + const X509V3_EXT_METHOD *v3_addr; + + if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) + return \-1; + return ASN1_item_i2d((ASN1_VALUE *)addrblocks, out, + ASN1_ITEM_ptr(v3_addr\->it)); +} +.Ed +.Pp +The use of the undocumented macro +.Dv ASN1_ITEM_ptr() +is necessary if compatibility with modern versions of other implementations +is desired. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr crypto 3 , +.Xr inet_net_ntop 3 , +.Xr inet_ntop 3 , +.Xr IPAddressRange_new 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_get_range 3 , +.Xr X509v3_addr_validate_path 3 , +.Xr X509v3_asid_add_id_or_range 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 2: IP Address delegation extension +.El +.Pp +RFC 7020: The Internet Numbers Registry System +.Pp +RFC 7249: Internet Number Registries +.Pp +.Rs +.%T Address Family Numbers +.%U https://www.iana.org/assignments/address\-family\-numbers +.Re +.Pp +.Rs +.%T Subsequent Address Family Identifiers (SAFI) Parameters +.%U https://www.iana.org/assignments/safi\-namespace +.Re +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +.Fn IPAddrBlocks_new , +.Fn IPAddrBlocks_free , +.Fn d2i_IPAddrBlocks , +and +.Fn i2d_IPAddrBlocks +do not exist and +.Fa IPAddrBlocks_it +is not public. +The above examples show how to implement the four missing functions +with public API. +.Pp +.Fn X509v3_addr_add_range +should check for inverted range bounds and overlaps +on insertion and fail instead of creating a nonsensical +.Fa addrblocks +that fails to be canonized by +.Fn X509v3_addr_canonize . +.Pp +If +.Dv NULL +is passed to +.Xr X509v3_asid_canonize 3 , +it succeeds. +.Fn X509v3_addr_is_canonical +considers +.Dv NULL +to be a canonical +.Vt IPAddrBlocks . +In contrast, +.Fn X509v3_addr_canonize +crashes with a +.Dv NULL +dereference. +.Pp +The code only supports the IPv4 and IPv6 AFIs. +This is not consistently enforced across implementations. +.Pp +.Fn X509v3_addr_add_range +fails to clear the unused bits set to 1 in the last octet of +the +.Vt ASN1_BIT_STRING +representation of +.Fa max . +This confuses some software. diff --git a/Libraries/libressl/man/X509v3_addr_get_range.3 b/Libraries/libressl/man/X509v3_addr_get_range.3 new file mode 100644 index 000000000..e0d83b116 --- /dev/null +++ b/Libraries/libressl/man/X509v3_addr_get_range.3 @@ -0,0 +1,132 @@ +.\" $OpenBSD: X509v3_addr_get_range.3,v 1.2 2023/09/30 14:12:40 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 30 2023 $ +.Dt X509V3_ADDR_GET_RANGE 3 +.Os +.Sh NAME +.Nm X509v3_addr_get_afi , +.Nm X509v3_addr_get_range +.Nd parse helpers for the IP address delegation extension +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft unsigned +.Fn X509v3_addr_get_afi "const IPAddressFamily *af" +.Ft int +.Fo X509v3_addr_get_range +.Fa "IPAddressOrRange *aor" +.Fa "const unsigned afi" +.Fa "unsigned char *min" +.Fa "unsigned char *max" +.Fa "const int length" +.Fc +.Sh DESCRIPTION +.Fn X509v3_addr_get_afi +returns the address family identifier (AFI) of +.Fa af . +.Pp +.Fn X509v3_addr_get_range +converts the minimum and maximum addresses in +the address prefix or range +.Fa aor +from internal encoding to IP addresses in network byte order +and places copies in the arrays +.Fa min +and +.Fa max , +of size +.Fa length . +The +.Fa length +must be large enough to accommodate an address for +.Fa afi , +which is at least 4 for +.Dv IANA_AFI_IPV4 +and at least 16 for +.Dv IANA_AFI_IPV6 . +.Sh RETURN VALUES +.Fn X509v3_addr_get_afi +returns the AFI encoded in +.Fa af +or 0 if +.Fa af +does not contain a valid AFI, or if the AFI is not IPv4 or IPv6. +.Pp +.Fn X509v3_addr_get_range +returns the number of bytes copied into +.Fa min +and +.Fa max +or 0 on error. +An error occurs if +.Fa aor +is malformed, if +.Fa afi +is not +.Dv IANA_AFI_IPV4 +or +.Dv IANA_AFI_IPV6 , +if either +.Fa min +or +.Fa max +is +.Dv NULL , +or if +.Fa length +is smaller than 4 or 16, respectively. +.Sh SEE ALSO +.Xr crypto 3 , +.Xr inet_ntop 3 , +.Xr IPAddressRange_new 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 2: IP Address delegation extension +.It +section 2.2.3.3: Element addressFamily +.It +section 2.2.3.7: Type IPAddressOrRange +.It +section 2.2.3.8: Element addressPrefix and Type IPAddress +.El +.Pp +.Rs +.%T Address Family Numbers +.%U https://www.iana.org/assignments/address-family-numbers +.Re +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +There is no accessor for the SAFI of +.Fa af . +.Pp +An error from +.Fn X509v3_addr_get_afi +is indistinguishable from the reserved AFI 0 being set on +.Fa af . +.Pp +It is not entirely clear how a caller is supposed to obtain an +.Vt IPAddressFamily +object or an +.Vt IPAddressOrRange +object without reaching into various structs documented in +.Xr IPAddressRange_new 3 . diff --git a/Libraries/libressl/man/X509v3_addr_inherits.3 b/Libraries/libressl/man/X509v3_addr_inherits.3 new file mode 100644 index 000000000..8e3cecf7a --- /dev/null +++ b/Libraries/libressl/man/X509v3_addr_inherits.3 @@ -0,0 +1,104 @@ +.\" $OpenBSD: X509v3_addr_inherits.3,v 1.3 2023/09/30 14:21:57 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 30 2023 $ +.Dt X509V3_ADDR_INHERITS 3 +.Os +.Sh NAME +.Nm X509v3_addr_inherits , +.Nm X509v3_asid_inherits +.Nd RFC 3779 inheritance +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fn X509v3_addr_inherits "IPAddrBlocks *addrblocks" +.Ft int +.Fn X509v3_asid_inherits "ASIdentifiers *asids" +.Sh DESCRIPTION +.Fn X509v3_addr_inherits +determines if there is at least one address family in +.Fa addrblocks +that uses inheritance. +.Pp +.Fn X509v3_asid_inherits +is intended to determine if at least one of +the list of autonomous system numbers or +the list of routing domain identifiers +uses inheritance. +.Sh RETURN VALUES +.Fn X509v3_addr_inherits +returns 1 if and only if +.Fa addrblocks +contains at least one +.Fa IPAddressFamily +object that is correctly marked +.Dq inherit : +its +.Fa IPAddressChoice +is of +.Fa type +.Dv IPAddressChoice_inherit +and its +.Fa inherit +element is present. +Otherwise it returns 0. +.Pp +.Fn X509v3_asid_inherits +returns 1 if and only if +at least one of the +.Fa asnum +or the +.Fa rdi +lists has +.Fa type +.Dv ASIdentifierChoice_inherit . +Otherwise it returns 0. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr ASRange_new 3 , +.Xr crypto 3 , +.Xr IPAddressRange_new 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_asid_add_inherit 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 2: IP Address delegation extension +.It +section 2.2.3.5: Element inherit +.It +section 3: AS identifiers delegation extension +.It +section 3.2.3.3: Element inherit +.El +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +.Fn X509v3_asid_inherits +ignores whether the +.Fa inherit +element is present or absent in the list that is considered to use inheritance. +.Pp +There is no API that determines whether all lists contained in an +.Vt ASIdentifiers +or an +.Vt IPAddrBlocks +object inherit. +See RFC 9287, 5.1.2 for an example where this is relevant. diff --git a/Libraries/libressl/man/X509v3_addr_subset.3 b/Libraries/libressl/man/X509v3_addr_subset.3 new file mode 100644 index 000000000..93714a26f --- /dev/null +++ b/Libraries/libressl/man/X509v3_addr_subset.3 @@ -0,0 +1,176 @@ +.\" $OpenBSD: X509v3_addr_subset.3,v 1.2 2023/09/30 14:24:00 schwarze Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 30 2023 $ +.Dt X509V3_ADDR_SUBSET 3 +.Os +.Sh NAME +.Nm X509v3_addr_subset , +.Nm X509v3_asid_subset +.Nd RFC 3779 subset relationship +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fn X509v3_addr_subset "IPAddrBlocks *child" "IPAddrBlocks *parent" +.Ft int +.Fn X509v3_asid_subset "ASIdentifiers *child" "ASIdentifiers *parent" +.Sh DESCRIPTION +.Fn X509v3_addr_subset +determines if all IP address resources present in +.Fa child +are contained in the corresponding resources in +.Fa parent . +.Pp +The implementation assumes but does not ensure that both +.Fa child +and +.Fa parent +are in canonical form as described in +.Xr X509v3_addr_is_canonical 3 . +In particular, both +.Fa child +and +.Fa parent +are sorted appropriately and they contain at most one +.Vt IPAddressFamily +object per address family identifier (AFI) and optional +subsequent address family identifier (SAFI). +.Pp +The checks are, in order: +.Bl -enum +.It +If +.Fa child +is +.Dv NULL +or identical to +.Fa parent +then +.Fa child +is a subset of +.Fa parent . +In particular, a +.Dv NULL +.Fa parent +is allowed for a +.Dv NULL +.Fa child . +.It +If +.Fa parent +is +.Dv NULL +then +.Fa child +is not a subset of +.Fa parent . +.It +If +.Xr X509v3_addr_inherits 3 +determines that +.Fa child +inherits or that +.Fa parent +inherits +then +.Fa child +is not a subset of +.Fa parent . +.It +Each address prefix or range in +.Fa child +must be a subset of an address prefix or range in the +.Fa parent , +taking AFI and optional SAFI into account: +.Bl -bullet -compact +.It +For each +.Vt IPAddressFamily +of +.Fa child +there must be an +.Vt IPAddressFamily +of +.Fa parent +with the same AFI and optional SAFI. +.It +Since the address prefixes and ranges in corresponding +.Vt IPAddressFamily +objects in +.Fa child +and +.Fa parent +are sorted in ascending order, +and do not overlap, +they can be traversed simultaneously in linear time. +For each prefix or range in +.Fa child +there must be a prefix or range in +.Fa parent +whose minimal address is smaller +and whose maximal address is larger. +.El +If any of these steps fails, +.Fa child +is not a subset of +.Fa parent . +.El +.Pp +.Fn X509v3_asid_subset +determines if all AS identifier resources in +.Fa child +are contained in the corresponding resources in +.Fa parent . +.Pp +The description for +.Fn X509v3_addr_subset +applies mutatis mutandis. +In particular, +.Fa child +and +.Fa parent +must be in canonical form per +.Xr X509v3_asid_is_canonical 3 , +but this is not enforced. +.Sh RETURN VALUES +.Fn X509v3_addr_subset +and +.Fn X509v3_asid_subset +return 1 if and only if +.Fa child +is a subset of +.Fa parent , +otherwise they return 0. +If both +.Fa child +and +.Fa parent +are in canonical form, +these functions cannot fail. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr ASRange_new 3 , +.Xr crypto 3 , +.Xr IPAddressRange_new 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_asid_add_inherit 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers. +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509v3_addr_validate_path.3 b/Libraries/libressl/man/X509v3_addr_validate_path.3 new file mode 100644 index 000000000..fe6065d59 --- /dev/null +++ b/Libraries/libressl/man/X509v3_addr_validate_path.3 @@ -0,0 +1,203 @@ +.\" $OpenBSD: X509v3_addr_validate_path.3,v 1.5 2023/09/30 19:07:38 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 30 2023 $ +.Dt X509V3_ADDR_VALIDATE_PATH 3 +.Os +.Sh NAME +.Nm X509v3_addr_validate_path , +.Nm X509v3_addr_validate_resource_set , +.Nm X509v3_asid_validate_path , +.Nm X509v3_asid_validate_resource_set +.Nd RFC 3779 path validation for IP address and AS number delegation +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fn X509v3_addr_validate_path "X509_STORE_CTX *ctx" +.Ft int +.Fo X509v3_addr_validate_resource_set +.Fa "STACK_OF(X509) *chain" +.Fa "IPAddrBlocks *addrblocks" +.Fa "int allow_inherit" +.Fc +.Ft int +.Fn X509v3_asid_validate_path "X509_STORE_CTX *ctx" +.Ft int +.Fo X509v3_asid_validate_resource_set +.Fa "STACK_OF(X509) *chain" +.Fa "ASIdentifiers *asid" +.Fa "int allow_inherit" +.Fc +.Sh DESCRIPTION +Both RFC 3779 extensions require additional checking in the certification +path validation. +.Bl -enum +.It +The initial set of allowed IP address and AS number resources is defined in +the trust anchor, where inheritance is not allowed. +.It +An issuer may only delegate subsets of resources present in its +RFC 3779 extensions or subsets of resources inherited from its issuer. +.It +If an RFC 3779 extension is present in a certificate, +the same type of extension must also be present in its issuer. +.It +All RFC 3779 extensions +appearing in the validation path must be in canonical form +according to +.Xr X509v3_addr_is_canonical 3 +and +.Xr X509v3_asid_is_canonical 3 . +.El +.Pp +.Fn X509v3_addr_validate_path +and +.Fn X509v3_asid_validate_path +are called from +.Xr X509_verify_cert 3 +as part of the verification chain building. +On encountering an error or a violation of the above rules, +.Fa error , +.Fa error_depth , +and +.Fa current_cert +are set on +.Fa ctx +and the verify callback is called with +.Fa ok +set to 0. +.Dv X509_V_ERR_INVALID_EXTENSION +indicates a non-canonical resource, +.Dv X509_V_ERR_UNNESTED_RESOURCE +indicates a violation of the other rules above. +In rare circumstances, the error can be +.Dv X509_V_ERR_UNSPECIFIED +and for IP address resources +.Dv X509_V_ERR_OUT_OF_MEM +is also possible. +.Pp +.Fn X509v3_addr_validate_resource_set +validates the resources in +.Fa addrblocks +against a specific certificate +.Fa chain . +After checking that +.Fa addrblocks +is canonical, its IP addresses are checked to be covered in +the certificate at depth 0, +then the chain is walked all the way to the trust anchor +until an error or a violation of the above rules is encountered. +.Fa addrblocks +is allowed to use inheritance according to +.Xr X509v3_addr_inherits 3 +if and only if +.Fa allow_inherit +is non-zero. +.Pp +.Fn X509v3_asid_validate_resource_set +performs similar checks as +.Fn X509v3_addr_validate_resource_set +for +.Fa asid . +.Sh RETURN VALUES +All these functions return 1 on successful validation and 0 otherwise. +.Pp +For +.Fn X509v3_addr_validate_path +and +.Fn X509v3_asid_validate_path +a non-empty +.Fa chain +and a +.Fa verify_cb +must be present on +.Fa ctx , +otherwise they fail and set the +.Fa error +on +.Fa ctx +to +.Dv X509_V_ERR_UNSPECIFIED . +The +.Fa verify_cb +is called with the error codes described above +on most errors encountered during validation. +Some malformed extensions can lead to an error +that cannot be intercepted by the callback. +With the exception of an allocation error, +no error codes are set on the error stack. +.Pp +.Fn X509v3_addr_validate_resource_set +accepts a +.Dv NULL +.Fa addrblocks +and +.Fn X509v3_asid_validate_resource_set +accepts a +.Dv NULL +.Fa asid +as valid. +They fail if +.Fa chain +is +.Dv NULL +or empty. +If +.Fa allow_inherit +is 0, +.Fa addrblocks +or +.Fa asid +is checked for inheritance with +.Xr X509v3_addr_inherits 3 +or +.Xr X509v3_asid_inherits 3 . +The remaining failure cases are the same as for +.Fn X509v3_addr_validate_path +and +.Fn X509v3_asid_validate_path . +They cannot and do not attempt to communicate +the cause of the error to the caller. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr crypto 3 , +.Xr IPAddressRange_new 3 , +.Xr X509_new 3 , +.Xr X509_STORE_CTX_get_error 3 , +.Xr X509_verify_cert 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_addr_inherits 3 , +.Xr X509v3_asid_add_id_or_range 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 2.3: IP Address Delegation Extension Certification Path Validation +.It +section 3.3: Autonomous System Identifier Delegation Extension Certification +Path Validation +.El +.Pp +RFC 5280: Internet X.509 Public Key Infrastructure Certificate +and Certificate Revocation List (CRL) Profile +.Bl -dash -compact +.It +section 6: Certification Path Validation +.El +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/X509v3_asid_add_id_or_range.3 b/Libraries/libressl/man/X509v3_asid_add_id_or_range.3 new file mode 100644 index 000000000..81221ca9b --- /dev/null +++ b/Libraries/libressl/man/X509v3_asid_add_id_or_range.3 @@ -0,0 +1,327 @@ +.\" $OpenBSD: X509v3_asid_add_id_or_range.3,v 1.9 2023/09/30 18:16:44 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 30 2023 $ +.Dt X509V3_ASID_ADD_ID_OR_RANGE 3 +.Os +.Sh NAME +.Nm X509v3_asid_add_id_or_range , +.Nm X509v3_asid_add_inherit , +.Nm X509v3_asid_canonize , +.Nm X509v3_asid_is_canonical +.Nd RFC 3779 autonomous system identifier delegation extension +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft int +.Fo X509v3_asid_add_id_or_range +.Fa "ASIdentifiers *asid" +.Fa "int type" +.Fa "ASN1_INTEGER *min" +.Fa "ASN1_INTEGER *max" +.Fc +.Ft int +.Fo X509v3_asid_add_inherit +.Fa "ASIdentifiers *asid" +.Fa "int type" +.Fc +.Ft int +.Fo X509v3_asid_canonize +.Fa "ASIdentifiers *asid" +.Fc +.Ft int +.Fo X509v3_asid_is_canonical +.Fa "ASIdentifiers *asid" +.Fc +.Sh DESCRIPTION +An +.Vt ASIdentifiers +object represents the content of the certificate extension +defined in RFC 3779, section 3.2.3.1. +It can be instantiated with +.Xr ASIdentifiers_new 3 +and its internals are documented in +.Xr ASRange_new 3 . +.Pp +An autonomous system is identified by an unsigned 32-bit integer, +called an AS identifier or AS number. +An +.Vt ASIdentifiers +object can hold two lists: +a list of +.Fa type +.Dv V3_ASID_ASNUM +containing individual AS identifiers and ranges of AS identifiers, +and an obsolete list of +.Fa type +.Dv V3_ASID_RDI +containing routing domain identifiers (RDIs). +Either of these lists may be absent, or it may contain nothing +but a special +.Dq inherit +marker that indicates that the list is inherited from the issuer +of the certificate. +.Pp +.Fn X509v3_asid_add_id_or_range +adds an individual identifier or a range of identifiers to the list of +.Fa type +(either +.Dv V3_ASID_ASNUM +or +.Dv V3_ASID_RDI ) +in +.Fa asid . +If no such list exists, it is created first. +If a list of +.Fa type +already exists and contains the +.Dq inherit +marker, the call fails. +.Fa min +must be a +.Pf non- Dv NULL +.Vt ASN1_INTEGER . +If +.Fa max +is +.Dv NULL , +.Fa min +is added as an individual identifier. +Ownership of +.Fa min +and +.Fa max +is transferred to +.Fa asid +on success. +It is the responsibility of the caller to ensure that +the resulting +.Fa asid +does not contain lists with overlapping ranges and that +.Fa min +is strictly less than +.Fa max +if both are +.Pf non- Dv NULL . +The caller should also ensure that the AS identifiers are +32-bit integers. +Failure to do so may result in an +.Fa asid +that cannot be brought into canonical form by +.Fn X509v3_asid_canonize . +.Pp +.Fn X509v3_asid_add_inherit +adds the list of +.Fa type +(either +.Dv V3_ASID_ASNUM +or +.Dv V3_ASID_RDI ) +in +.Fa asid +if necessary and marks it +.Dq inherit . +This fails if +.Fa asid +already contains a list of +.Fa type +that is not marked +.Dq inherit . +.Pp +.Fn X509v3_asid_canonize +attempts to bring both lists in +.Fa asid +into canonical form. +If +.Fa asid +is +.Dv NULL +the call succeeds and no action occurs. +A list is in canonical form if it is either one of +.Bl -dash -compact +.It +absent, +.It +marked +.Dq inherit , +.It +non-empty and all identifiers and ranges are listed in increasing order. +Ranges must not overlap, +.\" the following is not currently specified and leads to ambiguity: +.\" contain at least two elements, +and adjacent ranges must be fully merged. +.El +.Pp +.Fn X509v3_asid_canonize +merges adjacent ranges +but refuses to merge overlapping ranges or to discard duplicates. +For example, the adjacent ranges [a,b] and [b+1,c] are merged +into the single range [a,c], but if both [a,b] and [b,c] appear in a list, +this results in an error since they are considered overlapping. +Likewise, the identifier a is absorbed into the adjacent +range [a+1,b] to yield [a,b]. +.Fn X509v3_asid_canonize +errors if the minimum of any range is larger than the maximum. +In contrast, minimum and maximum of a range may be equal. +.Pp +.Fn X509v3_asid_is_canonical +checks whether +.Fa asid +is in canonical form. +Once +.Fn X509v3_asid_canonize +is called successfully on +.Fa asid , +all subsequent calls to +.Fn X509v3_asid_is_canonical +succeed on an unmodified +.Fa asid +unless memory allocation fails. +.Sh RETURN VALUES +All these functions return 1 on success and 0 on failure. +.Pp +.Fn X509v3_asid_add_id_or_range +and +.Fn X509v3_asid_add_inherit +fail if +.Fa asid +is +.Dv NULL +or if +.Fa type +is distinct from +.Dv V3_ASID_ASNUM +and +.Dv V3_ASID_RDI , +or on memory allocation failure. +In addition, +.Fn X509v3_asid_add_id_or_range +fails if +.Fa asid +contains a list of +.Fa type +that is marked +.Dq inherit , +and +.Fn X509v3_asid_add_inherit +fails if +.Fa asid +contains a list of +.Fa type +that is not marked +.Dq inherit . +.Pp +.Fn X509v3_asid_canonize +fails if either list is empty and not marked +.Dq inherit , +or if it is malformed, or if memory allocation fails. +Malformed lists include lists containing duplicate, overlapping, +or malformed elements, for example AS ranges where the minimum is +larger than the maximum. +Some of these failure modes result in an error being pushed onto the +error stack. +.Pp +.Fn X509v3_asid_is_canonical +returns 1 if +.Fa asid +is canonical and 0 if it is not canonical or on memory allocation +failure. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr crypto 3 , +.Xr s2i_ASN1_INTEGER 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 , +.Xr X509v3_addr_validate_path 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers, +.Bl -dash -compact +.It +section 3: Autonomous System Delegation Extension +.El +.Pp +.Rs +.%T Autonomous System (AS) Numbers +.%U https://www.iana.org/assignments/as-numbers +.Re +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +.Fn X509v3_asid_add_id_or_range +does not check for inverted range bounds and overlaps +on insertion. +It is very easy to create an +.Fa asid +that fails to be canonized by +.Fn X509v3_asid_canonize +and it is very hard to diagnose why. +.Pp +Both +.Fn X509v3_asid_add_id_or_range +and +.Fn X509v3_asid_add_inherit +can leave +.Fa asid +in a corrupted state if memory allocation fails during their execution. +In addition, +.Fn X509v3_asid_add_id_or_range +may already have freed the +.Fa min +and +.Fa max +arguments on failure. +.Pp +RFC 3779 does not explicitly disallow ranges where the minimum +is equal to the maximum. +The isolated AS identifier +.Fa min +and the AS range +.Bq Fa min , Ns Fa min +where the minimum and the maximum are equal to +.Fa min +have the same semantics. +.Fn X509v3_asid_is_canonical +accepts both representations as valid and +.Fn X509v3_asid_canonize +does not prefer either representation over the other. +The encodings of the two representations produced by +.Xr i2d_ASIdentifiers 3 +are distinct. +.Pp +.Fn X509v3_asid_is_canonical +does not fully check inheriting lists to be well formed. +It only checks the +.Fa type +to be +.Dv ASIdentifierChoice_inherit +and ignores the presence or absence of the +.Fa inherit +element. +.Fn X509v3_asid_canonize +does not fix that up. +This can lead to incorrect or unexpected DER encoding of +.Dq canonical +.Vt ASIdentifiers +objects. +In particular, it is possible to construct an +.Vt ASIdentifiers +object for which both +.Fn X509v3_asid_is_canonical +and +.Xr X509v3_asid_inherits 3 +return 1, and after a round trip through DER the latter +returns 0. diff --git a/Libraries/libressl/man/X509v3_get_ext_by_NID.3 b/Libraries/libressl/man/X509v3_get_ext_by_NID.3 new file mode 100644 index 000000000..54e4b583f --- /dev/null +++ b/Libraries/libressl/man/X509v3_get_ext_by_NID.3 @@ -0,0 +1,401 @@ +.\" $OpenBSD: X509v3_get_ext_by_NID.3,v 1.13 2021/07/12 14:54:00 schwarze Exp $ +.\" full merge up to: OpenSSL fd38836b Jun 20 15:25:43 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: July 12 2021 $ +.Dt X509V3_GET_EXT_BY_NID 3 +.Os +.Sh NAME +.Nm X509v3_get_ext_count , +.Nm X509v3_get_ext , +.Nm X509v3_get_ext_by_NID , +.Nm X509v3_get_ext_by_OBJ , +.Nm X509v3_get_ext_by_critical , +.Nm X509v3_delete_ext , +.Nm X509v3_add_ext , +.Nm X509_get_ext_count , +.Nm X509_get_ext , +.Nm X509_get_ext_by_NID , +.Nm X509_get_ext_by_OBJ , +.Nm X509_get_ext_by_critical , +.Nm X509_delete_ext , +.Nm X509_add_ext , +.Nm X509_CRL_get_ext_count , +.Nm X509_CRL_get_ext , +.Nm X509_CRL_get_ext_by_NID , +.Nm X509_CRL_get_ext_by_OBJ , +.Nm X509_CRL_get_ext_by_critical , +.Nm X509_CRL_delete_ext , +.Nm X509_CRL_add_ext , +.Nm X509_REVOKED_get_ext_count , +.Nm X509_REVOKED_get_ext , +.Nm X509_REVOKED_get_ext_by_NID , +.Nm X509_REVOKED_get_ext_by_OBJ , +.Nm X509_REVOKED_get_ext_by_critical , +.Nm X509_REVOKED_delete_ext , +.Nm X509_REVOKED_add_ext +.Nd extension stack utility functions +.Sh SYNOPSIS +.In openssl/x509.h +.Ft int +.Fo X509v3_get_ext_count +.Fa "const STACK_OF(X509_EXTENSION) *x" +.Fc +.Ft X509_EXTENSION * +.Fo X509v3_get_ext +.Fa "const STACK_OF(X509_EXTENSION) *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509v3_get_ext_by_NID +.Fa "const STACK_OF(X509_EXTENSION) *x" +.Fa "int nid" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509v3_get_ext_by_OBJ +.Fa "const STACK_OF(X509_EXTENSION) *x" +.Fa "const ASN1_OBJECT *obj" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509v3_get_ext_by_critical +.Fa "const STACK_OF(X509_EXTENSION) *x" +.Fa "int crit" +.Fa "int lastpos" +.Fc +.Ft X509_EXTENSION * +.Fo X509v3_delete_ext +.Fa "STACK_OF(X509_EXTENSION) *x" +.Fa "int loc" +.Fc +.Ft STACK_OF(X509_EXTENSION) * +.Fo X509v3_add_ext +.Fa "STACK_OF(X509_EXTENSION) **x" +.Fa "X509_EXTENSION *ex" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_get_ext_count +.Fa "const X509 *x" +.Fc +.Ft X509_EXTENSION * +.Fo X509_get_ext +.Fa "const X509 *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_get_ext_by_NID +.Fa "const X509 *x" +.Fa "int nid" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_get_ext_by_OBJ +.Fa "const X509 *x" +.Fa "const ASN1_OBJECT *obj" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_get_ext_by_critical +.Fa "const X509 *x" +.Fa "int crit" +.Fa "int lastpos" +.Fc +.Ft X509_EXTENSION * +.Fo X509_delete_ext +.Fa "X509 *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_add_ext +.Fa "X509 *x" +.Fa "X509_EXTENSION *ex" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_CRL_get_ext_count +.Fa "const X509_CRL *x" +.Fc +.Ft X509_EXTENSION * +.Fo X509_CRL_get_ext +.Fa "const X509_CRL *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_CRL_get_ext_by_NID +.Fa "const X509_CRL *x" +.Fa "int nid" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_CRL_get_ext_by_OBJ +.Fa "const X509_CRL *x" +.Fa "const ASN1_OBJECT *obj" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_CRL_get_ext_by_critical +.Fa "const X509_CRL *x" +.Fa "int crit" +.Fa "int lastpos" +.Fc +.Ft X509_EXTENSION * +.Fo X509_CRL_delete_ext +.Fa "X509_CRL *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_CRL_add_ext +.Fa "X509_CRL *x" +.Fa "X509_EXTENSION *ex" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_REVOKED_get_ext_count +.Fa "const X509_REVOKED *x" +.Fc +.Ft X509_EXTENSION * +.Fo X509_REVOKED_get_ext +.Fa "const X509_REVOKED *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_REVOKED_get_ext_by_NID +.Fa "const X509_REVOKED *x" +.Fa "int nid" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_REVOKED_get_ext_by_OBJ +.Fa "const X509_REVOKED *x" +.Fa "const ASN1_OBJECT *obj" +.Fa "int lastpos" +.Fc +.Ft int +.Fo X509_REVOKED_get_ext_by_critical +.Fa "const X509_REVOKED *x" +.Fa "int crit" +.Fa "int lastpos" +.Fc +.Ft X509_EXTENSION * +.Fo X509_REVOKED_delete_ext +.Fa "X509_REVOKED *x" +.Fa "int loc" +.Fc +.Ft int +.Fo X509_REVOKED_add_ext +.Fa "X509_REVOKED *x" +.Fa "X509_EXTENSION *ex" +.Fa "int loc" +.Fc +.Sh DESCRIPTION +.Fn X509v3_get_ext_count +retrieves the number of extensions in +.Fa x . +.Pp +.Fn X509v3_get_ext +retrieves extension +.Fa loc +from +.Fa x . +The index +.Fa loc +can take any value from 0 to +.Fn X509_get_ext_count x No - 1 . +The returned extension is an internal pointer which must not be +freed up by the application. +.Pp +.Fn X509v3_get_ext_by_NID +and +.Fn X509v3_get_ext_by_OBJ +look for an extension with +.Fa nid +or +.Fa obj +from extension stack +.Fa x . +The search starts from the extension after +.Fa lastpos +or from the beginning if +.Fa lastpos +is -1. +If the extension is found, its index is returned; otherwise, -1 is +returned. +.Pp +.Fn X509v3_get_ext_by_critical +is similar to +.Fn X509v3_get_ext_by_NID +except that it looks for an extension of criticality +.Fa crit . +A zero value for +.Fa crit +looks for a non-critical extension; a non-zero value looks for a +critical extension. +.Pp +.Fn X509v3_delete_ext +deletes the extension with index +.Fa loc +from +.Fa x . +The deleted extension is returned and must be freed by the caller. +If +.Fa loc +is an invalid index value, +.Dv NULL +is returned. +.Pp +.Fn X509v3_add_ext +adds the extension +.Fa ex +to the stack +.Pf * Fa x +at position +.Fa loc . +If +.Fa loc +is -1, the new extension is added to the end. +If +.Pf * Fa x +is +.Dv NULL , +a new stack will be allocated. +The passed extension +.Fa ex +is duplicated internally so it must be freed after use. +.Pp +.Fn X509_get_ext_count , +.Fn X509_get_ext , +.Fn X509_get_ext_by_NID , +.Fn X509_get_ext_by_OBJ , +.Fn X509_get_ext_by_critical , +.Fn X509_delete_ext , +and +.Fn X509_add_ext +operate on the extensions of certificate +.Fa x . +They are otherwise identical to the X509v3 functions. +.Pp +.Fn X509_CRL_get_ext_count , +.Fn X509_CRL_get_ext , +.Fn X509_CRL_get_ext_by_NID , +.Fn X509_CRL_get_ext_by_OBJ , +.Fn X509_CRL_get_ext_by_critical , +.Fn X509_CRL_delete_ext , +and +.Fn X509_CRL_add_ext +operate on the extensions of the CRL +.Fa x . +They are otherwise identical to the X509v3 functions. +.Pp +.Fn X509_REVOKED_get_ext_count , +.Fn X509_REVOKED_get_ext , +.Fn X509_REVOKED_get_ext_by_NID , +.Fn X509_REVOKED_get_ext_by_OBJ , +.Fn X509_REVOKED_get_ext_by_critical , +.Fn X509_REVOKED_delete_ext , +and +.Fn X509_REVOKED_add_ext +operate on the extensions of the CRL entry +.Fa x . +They are otherwise identical to the X509v3 functions. +.Pp +These functions are used to examine stacks of extensions directly. +Many applications will want to parse or encode and add an extension: +they should use the extension encode and decode functions instead +such as +.Xr X509_get_ext_d2i 3 . +.Pp +Extension indices start from zero, so a zero index return value is +not an error. +These search functions start from the extension +.Em after +the +.Fa lastpos +parameter, so it should initially be set to -1. +If it is set to 0, the initial extension will not be checked. +.Sh RETURN VALUES +.Fn X509v3_get_ext_count +returns the extension count. +.Pp +.Fn X509v3_get_ext , +.Fn X509v3_delete_ext , +and +.Fn X509_delete_ext +return an +.Vt X509_EXTENSION +pointer or +.Dv NULL +if an error occurs. +.Pp +.Fn X509v3_get_ext_by_NID , +.Fn X509v3_get_ext_by_OBJ , +and +.Fn X509v3_get_ext_by_critical +return the extension index or -1 if an error occurs. +.Pp +.Fn X509v3_add_ext +returns a stack of extensions or +.Dv NULL +on error. +.Pp +.Fn X509_add_ext +returns 1 on success or 0 on error. +.Sh SEE ALSO +.Xr X509_CRL_new 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509_new 3 , +.Xr X509_REVOKED_new 3 , +.Xr X509V3_EXT_print 3 , +.Xr X509V3_extensions_print 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +These functions first appeared in SSLeay 0.8.0 +and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/a2d_ASN1_OBJECT.3 b/Libraries/libressl/man/a2d_ASN1_OBJECT.3 new file mode 100644 index 000000000..7d36a54be --- /dev/null +++ b/Libraries/libressl/man/a2d_ASN1_OBJECT.3 @@ -0,0 +1,84 @@ +.\" $OpenBSD: a2d_ASN1_OBJECT.3,v 1.3 2023/08/09 17:34:39 schwarze Exp $ +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 9 2023 $ +.Dt A2D_ASN1_OBJECT 3 +.Os +.Sh NAME +.Nm a2d_ASN1_OBJECT +.Nd DER content octets of an ASN.1 object identifier +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo a2d_ASN1_OBJECT +.Fa "unsigned char *der_out" +.Fa "int olen" +.Fa "const char *val_in" +.Fa "int ilen" +.Fc +.Sh DESCRIPTION +.Fn a2d_ASN1_OBJECT +accepts an ASCII string +.Fa val_in +of +.Fa ilen +bytes and interprets it as the numerical form of an ASN.1 object identifier. +It writes the content octets of the DER encoding of the object identifier +to the buffer +.Fa der_out +which is +.Fa olen +bytes long. +The identifier and length octets of the DER encoding are not written. +.Pp +If +.Fa ilen +is \-1, the +.Xr strlen 3 +of +.Fa val_in +is used instead. +.Pp +If +.Fa der_out +is a +.Dv NULL +pointer, writing the content octets is skipped +and only the return value is calculated. +.Sh RETURN VALUES +.Fn a2d_ASN1_OBJECT +returns the number of content octets that were or would be written or 0 if +.Fa ilen +is 0, if +.Fa val_in +is not a valid representation of an object identifier, +if memory allocation fails, or if the number of content octets +would be larger than +.Fa olen . +.Sh SEE ALSO +.Xr ASN1_OBJECT_new 3 , +.Xr i2d_ASN1_OBJECT 3 , +.Xr OBJ_create 3 +.Sh STANDARDS +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.19: Encoding of an object identifier value +.Sh HISTORY +.Fn a2d_ASN1_OBJECT +first appeared in SSLeay 0.8.0 and has been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/bn_dump.3 b/Libraries/libressl/man/bn_dump.3 new file mode 100644 index 000000000..cfe707b77 --- /dev/null +++ b/Libraries/libressl/man/bn_dump.3 @@ -0,0 +1,698 @@ +.\" $OpenBSD: bn_dump.3,v 1.8 2023/01/20 12:16:46 jsing Exp $ +.\" full merge up to: +.\" OpenSSL crypto/bn/README.pod aebb9aac Jul 19 09:27:53 2016 -0400 +.\" +.\" This file was written by Ulf Moeller . +.\" Copyright (c) 2000, 2003, 2006, 2009 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: January 20 2023 $ +.Dt BN_DUMP 3 +.Os +.Sh NAME +.Nm bn_mul_words , +.Nm bn_mul_add_words , +.Nm bn_sqr_words , +.Nm bn_div_words , +.Nm bn_add_words , +.Nm bn_sub_words , +.Nm bn_mul_comba4 , +.Nm bn_mul_comba8 , +.Nm bn_sqr_comba4 , +.Nm bn_sqr_comba8 , +.Nm bn_cmp_words , +.Nm bn_mul_normal , +.Nm bn_mul_recursive , +.Nm bn_mul_part_recursive , +.Nm bn_sqr_normal , +.Nm bn_sqr_recursive , +.Nm bn_expand , +.Nm bn_wexpand , +.Nm bn_expand2 , +.Nm bn_fix_top , +.Nm bn_check_top , +.Nm bn_print , +.Nm bn_dump , +.Nm bn_set_max , +.Nm bn_set_high , +.Nm bn_set_low , +.Nm mul , +.Nm mul_add , +.Nm sqr +.Nd BIGNUM library internal functions +.Sh SYNOPSIS +.In openssl/bn.h +.Ft BN_ULONG +.Fo bn_mul_words +.Fa "BN_ULONG *rp" +.Fa "BN_ULONG *ap" +.Fa "int num" +.Fa "BN_ULONG w" +.Fc +.Ft BN_ULONG +.Fo bn_mul_add_words +.Fa "BN_ULONG *rp" +.Fa "BN_ULONG *ap" +.Fa "int num" +.Fa "BN_ULONG w" +.Fc +.Ft void +.Fo bn_sqr_words +.Fa "BN_ULONG *rp" +.Fa "BN_ULONG *ap" +.Fa "int num" +.Fc +.Ft BN_ULONG +.Fo bn_div_words +.Fa "BN_ULONG h" +.Fa "BN_ULONG l" +.Fa "BN_ULONG d" +.Fc +.Ft BN_ULONG +.Fo bn_add_words +.Fa "BN_ULONG *rp" +.Fa "BN_ULONG *ap" +.Fa "BN_ULONG *bp" +.Fa "int num" +.Fc +.Ft BN_ULONG +.Fo bn_sub_words +.Fa "BN_ULONG *rp" +.Fa "BN_ULONG *ap" +.Fa "BN_ULONG *bp" +.Fa "int num" +.Fc +.Ft void +.Fo bn_mul_comba4 +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "BN_ULONG *b" +.Fc +.Ft void +.Fo bn_mul_comba8 +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "BN_ULONG *b" +.Fc +.Ft void +.Fo bn_sqr_comba4 +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fc +.Ft void +.Fo bn_sqr_comba8 +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fc +.Ft int +.Fo bn_cmp_words +.Fa "BN_ULONG *a" +.Fa "BN_ULONG *b" +.Fa "int n" +.Fc +.Ft void +.Fo bn_mul_normal +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "int na" +.Fa "BN_ULONG *b" +.Fa "int nb" +.Fc +.Ft void +.Fo bn_mul_recursive +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "BN_ULONG *b" +.Fa "int n2" +.Fa "int dna" +.Fa "int dnb" +.Fa "BN_ULONG *tmp" +.Fc +.Ft void +.Fo bn_mul_part_recursive +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "BN_ULONG *b" +.Fa "int n" +.Fa "int tna" +.Fa "int tnb" +.Fa "BN_ULONG *tmp" +.Fc +.Ft void +.Fo bn_sqr_normal +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "int n" +.Fa "BN_ULONG *tmp" +.Fc +.Ft void +.Fo bn_sqr_recursive +.Fa "BN_ULONG *r" +.Fa "BN_ULONG *a" +.Fa "int n2" +.Fa "BN_ULONG *tmp" +.Fc +.Ft void +.Fo mul +.Fa "BN_ULONG r" +.Fa "BN_ULONG a" +.Fa "BN_ULONG w" +.Fa "BN_ULONG c" +.Fc +.Ft void +.Fo mul_add +.Fa "BN_ULONG r" +.Fa "BN_ULONG a" +.Fa "BN_ULONG w" +.Fa "BN_ULONG c" +.Fc +.Ft void +.Fo sqr +.Fa "BN_ULONG r0" +.Fa "BN_ULONG r1" +.Fa "BN_ULONG a" +.Fc +.Ft BIGNUM * +.Fo bn_expand +.Fa "BIGNUM *a" +.Fa "int bits" +.Fc +.Ft BIGNUM * +.Fo bn_wexpand +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Ft BIGNUM * +.Fo bn_expand2 +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Ft void +.Fo bn_fix_top +.Fa "BIGNUM *a" +.Fc +.Ft void +.Fo bn_check_top +.Fa "BIGNUM *a" +.Fc +.Ft void +.Fo bn_print +.Fa "BIGNUM *a" +.Fc +.Ft void +.Fo bn_dump +.Fa "BN_ULONG *d" +.Fa "int n" +.Fc +.Ft void +.Fo bn_set_max +.Fa "BIGNUM *a" +.Fc +.Ft void +.Fo bn_set_high +.Fa "BIGNUM *r" +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Ft void +.Fo bn_set_low +.Fa "BIGNUM *r" +.Fa "BIGNUM *a" +.Fa "int n" +.Fc +.Sh DESCRIPTION +This page documents the internal functions used by the OpenSSL +.Vt BIGNUM +implementation. +They are described here to facilitate debugging and extending the +library. +They are +.Em not +to be used by applications. +.Ss The BIGNUM structure +.Bd -literal +typedef struct bignum_st BIGNUM; + +struct bignum_st { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; +}; +.Ed +.Pp +The integer value is stored in +.Fa d , +a +.Xr malloc 3 Ap ed +array of words +.Pq Vt BN_ULONG , +least significant word first. +.Vt BN_ULONG +is a macro that expands to +.Vt unsigned long Pq = Vt uint64_t +on +.Dv _LP64 +platforms and +.Vt unsigned int Pq = Vt uint32_t +elsewhere. +.Pp +.Fa dmax +is the size of the +.Fa d +array that has been allocated. +.Fa top +is the number of words being used, so for a value of 4, bn.d[0]=4 and +bn.top=1. +.Fa neg +is 1 if the number is negative. +When a +.Vt BIGNUM +is 0, the +.Fa d +field can be +.Dv NULL +and +.Fa top +== 0. +.Pp +.Fa flags +is a bit field of flags which are defined in +.In openssl/bn.h . +The flags begin with +.Dv BN_FLG_ . +The macros +.Fn BN_set_flags b n +and +.Fn BN_get_flags b n +exist to enable or fetch flag(s) +.Fa n +from a +.Vt BIGNUM +structure +.Fa b . +.Pp +Various routines in this library require the use of temporary +.Vt BIGNUM +variables during their execution. +Since dynamic memory allocation to create +.Vt BIGNUM Ns s +is rather expensive when used in conjunction with repeated subroutine +calls, the +.Vt BN_CTX +structure is used. +This structure contains BN_CTX_NUM +.Vt BIGNUM Ns s ; +see +.Xr BN_CTX_start 3 . +.Ss Low level arithmetic operations +These functions are implemented in C and for several platforms in +assembly language: +.Pp +.Fn bn_mul_words rp ap num w +operates on the +.Fa num +word arrays +.Fa rp +and +.Fa ap . +It computes +.Fa ap +* +.Fa w , +places the result in +.Fa rp , +and returns the high word (carry). +.Pp +.Fn bn_mul_add_words rp ap num w +operates on the +.Fa num +word arrays +.Fa rp +and +.Fa ap . +It computes +.Fa ap +* +.Fa w ++ +.Fa rp , +places the result in +.Fa rp , +and returns the high word (carry). +.Pp +.Fn bn_sqr_words rp ap num +operates on the +.Fa num +word array +.Fa ap +and the +.Pf 2* Fa num +word array +.Fa ap . +It computes +.Fa ap +* +.Fa ap +word-wise, and places the low and high bytes of the result in +.Fa rp . +.Pp +.Fn bn_div_words h l d +divides the two word number +.Pq Fa h , Fa l +by +.Fa d +and returns the result. +.Pp +.Fn bn_add_words rp ap bp num +operates on the +.Fa num +word arrays +.Fa ap , +.Fa bp +and +.Fa rp . +It computes +.Fa ap ++ +.Fa bp , +places the result in +.Fa rp , +and returns the high word (carry). +.Pp +.Fn bn_sub_words rp ap bp num +operates on the +.Fa num +word arrays +.Fa ap , +.Fa bp +and +.Fa rp . +It computes +.Fa ap +- +.Fa bp , +places the result in +.Fa rp , +and returns the carry (1 if +.Fa bp +\(ra +.Fa ap , +0 otherwise). +.Pp +.Fn bn_mul_comba4 r a b +operates on the 4 word arrays +.Fa a +and +.Fa b +and the 8-word array +.Fa r . +It computes +.Fa a Ns * Ns Fa b +and places the result in +.Fa r . +.Pp +.Fn bn_mul_comba8 r a b +operates on the 8-word arrays +.Fa a +and +.Fa b +and the 16-word array +.Fa r . +It computes +.Fa a Ns * Ns Fa b +and places the result in +.Fa r . +.Pp +.Fn bn_sqr_comba4 r a b +operates on the 4-word arrays +.Fa a +and +.Fa b +and the 8-word array +.Fa r . +.Pp +.Fn bn_sqr_comba8 r a b +operates on the 8-word arrays +.Fa a +and +.Fa b +and the 16 word array +.Fa r . +.Pp +The following functions are implemented in C: +.Pp +.Fn bn_cmp_words a b n +operates on the +.Fa n +word arrays +.Fa a +and +.Fa b . +It returns 1, 0 and -1 if +.Fa a +is greater than, equal and less than +.Fa b . +.Pp +.Fn bn_mul_normal r a na b nb +operates on the +.Fa na +word array +.Fa a , +the +.Fa nb +word array +.Fa b +and the +.Fa na Ns + Ns Fa nb +word array +.Fa r . +It computes +.Fa a Ns * Ns Fa b +and places the result in +.Fa r . +.Pp +.Fn bn_mul_recursive r a b n2 dna dnb t +operates on the word arrays +.Fa a +and +.Fa b +of length +.Fa n2 Ns + Ns Fa dna +and +.Fa n2 Ns + Ns Fa dnb +.Pf ( Fa dna +and +.Fa dnb +are currently allowed to be 0 or negative) and the +.Pf 2* Fa n2 +word arrays +.Fa r +and +.Sy t . +.Fa n2 +must be a power of 2. +It computes +.Fa a Ns * Ns Fa b +and places the result in +.Fa r . +.Pp +.Fn bn_mul_part_recursive r a b n tna tnb tmp +operates on the word arrays +.Fa a +and +.Fa b +of length +.Fa n Ns + Ns Fa tna +and +.Fa n Ns + Ns Fa tnb +and the +.Pf 4* Fa n +word arrays +.Fa r +and +.Fa tmp . +.Pp +.Xr BN_mul 3 +calls +.Fn bn_mul_normal , +or an optimized implementation if the factors have the same size: +.Fn bn_mul_comba8 +is used if they are 8 words long, +.Fn bn_mul_recursive +if they are larger than +.Dv BN_MULL_SIZE_NORMAL +and the size is an exact multiple of the word size, and +.Fn bn_mul_part_recursive +for others that are larger than +.Dv BN_MULL_SIZE_NORMAL . +.Pp +.Fn bn_sqr_normal r a n tmp +operates on the +.Fa n +word array +.Fa a +and the +.Pf 2* Fa n +word arrays +.Fa tmp +and +.Fa r . +.Pp +The implementations use the following macros which, depending on the +architecture, may use +.Vt long long +C operations or inline assembler. +They are defined in +.Pa bn_lcl.h . +.Pp +.Fn mul r a w c +computes +.Fa w Ns * Ns Fa a Ns + Ns Fa c +and places the low word of the result in +.Fa r +and the high word in +.Fa c . +.Pp +.Fn mul_add r a w c +computes +.Fa w Ns * Ns Fa a Ns + Ns Fa r Ns + Ns Fa c +and places the low word of the result in +.Fa r +and the high word in +.Fa c . +.Pp +.Fn sqr r0 r1 a +computes +.Fa a Ns * Ns Fa a +and places the low word of the result in +.Fa r0 +and the high word in +.Fa r1 . +.Ss Size changes +.Fn bn_expand +ensures that +.Fa b +has enough space for a +.Fa bits +bit number. +.Fn bn_wexpand +ensures that +.Fa b +has enough space for an +.Fa n +word number. +If the number has to be expanded, both macros call +.Fn bn_expand2 , +which allocates a new +.Fa d +array and copies the data. +They return +.Dv NULL +on error, +.Fa b +otherwise. +.Pp +The +.Fn bn_fix_top +macro reduces +.Fa a Ns -> Ns Fa top +to point to the most significant non-zero word plus one when +.Fa a +has shrunk. +.Ss Debugging +.Fn bn_check_top +verifies that +.Ql ((a)-\(ratop \(ra= 0 && (a)-\(ratop \(la= (a)-\(radmax) . +A violation will cause the program to abort. +.Pp +.Fn bn_print +prints +.Fa a +to +.Dv stderr . +.Fn bn_dump +prints +.Fa n +words at +.Fa d +(in reverse order, i.e.\& +most significant word first) to +.Dv stderr . +.Pp +.Fn bn_set_max +makes +.Fa a +a static number with a +.Fa dmax +of its current size. +This is used by +.Fn bn_set_low +and +.Fn bn_set_high +to make +.Fa r +a read-only +.Vt BIGNUM +that contains the +.Fa n +low or high words of +.Fa a . +.Pp +If +.Dv BN_DEBUG +is not defined, +.Fn bn_check_top , +.Fn bn_print , +.Fn bn_dump +and +.Fn bn_set_max +are defined as empty macros. +.Sh SEE ALSO +.Xr BN_new 3 diff --git a/Libraries/libressl/man/crypto.3 b/Libraries/libressl/man/crypto.3 new file mode 100644 index 000000000..e63c1a78d --- /dev/null +++ b/Libraries/libressl/man/crypto.3 @@ -0,0 +1,418 @@ +.\" $OpenBSD: crypto.3,v 1.29 2023/05/01 07:37:45 tb Exp $ +.\" OpenSSL a9c85cea Nov 11 09:33:55 2016 +0100 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller and +.\" Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt CRYPTO 3 +.Os +.Sh NAME +.Nm crypto +.Nd OpenSSL cryptographic library +.Sh DESCRIPTION +The OpenSSL crypto library implements a wide range of cryptographic +algorithms used in various Internet standards. +The services provided by this library are used by the OpenSSL +implementations of TLS and S/MIME, and they have also been used to +implement SSH, OpenPGP, and other cryptographic standards. +.Pp +.Sy Symmetric ciphers +including AES, Blowfish, CAST, ChaCha20, IDEA, DES, RC2, and RC4 +are provided by the generic interface +.Xr EVP_EncryptInit 3 . +Low-level stand-alone interfaces include +.Xr AES_encrypt 3 , +.Xr BF_set_key 3 , +.Xr ChaCha 3 , +.Xr DES_set_key 3 , +and +.Xr RC4 3 . +.Pp +.Sy Public key cryptography and key agreement +are provided by +.Xr DH_new 3 , +.Xr ECDH_compute_key 3 , +.Xr X25519 3 , +.Xr DSA_new 3 , +.Xr ECDSA_SIG_new 3 , +.Xr RSA_new 3 , +and +.Xr EVP_PKEY_new 3 . +.Pp +.Sy Certificates +are handled by +.Xr X509_new 3 +and +.Xr X509v3_add_ext 3 . +.Pp +.Sy Authentication codes and hash functions +offered include +.Xr EVP_DigestInit 3 , +.Xr CMAC_Init 3 , +.Xr HMAC 3 , +.Xr MD4 3 , +.Xr MD5 3 , +.Xr RIPEMD160 3 , +.Xr SHA1 3 , +and +.Xr SHA256 3 . +.Pp +.Sy Input, output, and data encoding +facilities include +.Xr ASN1_TYPE_get 3 , +.Xr BIO_new 3 , +.Xr CMS_ContentInfo_new 3 , +.Xr evp 3 , +.Xr EVP_EncodeInit 3 , +.Xr PEM_read 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_sign 3 , +.Xr PKCS12_create 3 , +and +.Xr SMIME_write_PKCS7 3 . +.Pp +.Sy Auxiliary features include: +.Bl -dash -compact +.It +configuration file handling: see +.Xr OPENSSL_config 3 +.It +error reporting: see +.Xr ERR 3 +.It +.Xr OCSP_REQUEST_new 3 +.It +.Xr UI_new 3 +.El +.Pp +.Sy Internal utilities +include +.Xr BIO_f_buffer 3 , +.Xr BN_new 3 , +.Xr EC_GROUP_new 3 , +.Xr lh_new 3 , +and +.Xr STACK_OF 3 . +.Sh NAMING CONVENTIONS +Elements used in the names of API functions include the following: +.Bl -tag -width Ds +.It add0 +See +.Dq set0 +below. +.It add1 +See +.Dq set1 +below. +.It BIO +basic input and/or output abstraction: +The function manipulates objects of the idiosyncratic OpenSSL +.Vt BIO +object type. +See +.Xr BIO_new 3 . +.It bio +The function uses a +.Vt BIO +object for input or output. +In many cases, simpler variants of the function are available +that operate directly on +.In stdio.h +.Vt FILE +objects or directly in RAM, usually using byte arrays. +.It BIO_f_ +filter BIO: +The function returns a pointer to a static built-in object that, +when passed to +.Xr BIO_new 3 , +results in the creation of a BIO object that can write data to +and/or read data from another +.Vt BIO +object. +.It BIO_s_ +source and/or sink BIO: +The function returns a pointer to a static built-in object that, +when passed to +.Xr BIO_new 3 , +results in the creation of a BIO object +that can write data to an external destination +and/or read data from an external source, +for example a file descriptor or object, a memory buffer, or the network. +.It BN +big number: +The function operates on +.Vt BIGNUM +objects representing integer numbers of variable, almost unlimited size. +See +.Xr BN_new 3 . +.It cb +callback: +The function takes or returns a function pointer +that is called by API functions from inside the library. +The function pointed to may be defined by the application program. +In some cases, API functions with +.Dq cb +in their name may return function pointers to internal functions +defined inside the library that are not API functions. +The element +.Dq cb +is also used in the names of some function pointer datatypes +declared with +.Sy typedef . +In a small number of cases, the all caps form +.Dq CB +is used with the same meaning. +.It CTX +context: +The function operates on a wrapper object around another object. +The purposes and properties of such +.Dq CTX +wrapper objects vary wildly depending on the objects in question. +A few function names use the lower case form +.Dq ctx +in the same sense. +.It d2i +DER to internal: +The function decodes input conforming to ASN.1 basic encoding rules (BER) +and either stores the result in an existing object +or in a newly allocated object. +The latter is usually preferable because +creating a new object is more robust and less error prone. +In spite of the name, the input usually does not need to conform to ASN.1 +distinguished encoding rules (DER), which are more restrictive than BER. +.It EVP +digital EnVeloPe library: +See +.Xr evp 3 . +.It ex +This name element is used for two completely unrelated purposes. +.Pp +extended version: +The function is similar to an older function without the +.Dq ex +in its name, but takes one or more additional arguments +in order to make it more versatile. +In several cases, the older version is now deprecated. +.Pp +extra data: +Some object types support storing additional, application-specific data +inside objects in addition to the data the object is designed to hold. +The function sets, retrieves, or prepares for using such extra data. +Related function names usually contain +.Dq ex_data +or +.Dq ex_new_index . +See +.Xr CRYPTO_set_ex_data 3 . +.It fp +file pointer: +The function takes a +.Vt FILE * +argument. +Usually, the function is a variant of another function taking a +.Vt BIO * +argument instead. +.It i2d +internal to DER: +The function encodes an object passed as an argument +according to ASN.1 distinguished encoding rules (DER). +There are a few rare exceptions of functions that have +.Dq i2d +in their name but produce output anyway +that only conforms to ASN.1 basic encoding rules (BER) and not to DER. +.It get0 +The function returns an internal pointer +owned by the object passed as an argument. +The returned pointer must not be freed by the calling code. +It will be freed automatically +when the object owning the pointer will be freed. +.It get1 +The function returns a copy of a sub-object +of an object passed as an argument. +The caller is responsible for freeing the returned object +when it is no longer needed. +.Pp +If the object type is reference counted, usually the reference count +is incremented instead of copying the object. +Consequently, modifying the returned object may still impact all +objects containing references to it. +The caller is responsible for freeing the returned object +when it is no longer needed; for reference-counted objects still +referenced elsewhere, this will merely decrement the reference count. +.It get +Functions containing +.Dq get +in their name without a following digit may behave in +.Dq get0 +or, more rarely, in +.Dq get1 +style. +To find out which is the case, refer to the individual manual pages. +.It lh +linear hash: +The function manipulates a dynamic hash table. +See +.Xr lh_new 3 . +.It md +message digest. +Some function names use the all caps form +.Dq MD +in the same sense. +.It meth +The function manipulates an object holding a function table. +Usually, such function tables allow the application program +to implement additional cryptographic or I/O algorithms +and to use them with the same high-level API functions as the +algorithms provided by the library itself, or to replace the +implementations of algorithms provided by the library with +custom implementations provided by the application program. +Some API functions use the name elements +.Dq method +or +.Dq METHOD +in the same sense. +See also the +.Dq cb +entry in the present list. +.It nid +numerical identifier: +A non-standard, LibreSSL-specific +.Vt int +number associated with an ASN.1 object identifier. +In several cases, the all caps form +.Dq NID +is used in the same sense. +See +.Xr OBJ_nid2obj 3 . +.It obj +This name element and its all caps form +.Dq OBJ +usually refer to ASN.1 object identifiers represented by the +.Vt ASN1_OBJECT +data type. +See +.Xr ASN1_OBJECT_new 3 . +.It PKEY +In most cases, this name element and its lower case form +.Dq pkey +mean +.Dq private key , +but for both forms, there are some cases where they mean +.Dq public key +instead. +.It set0 +The function transfers ownership of a pointer passed as an argument +to an object passed as another argument, +by storing the pointer inside the object. +The transferred pointer must not be freed by the calling code. +It will be freed automatically +when the object now owning the pointer will be freed. +.It set1 +The function copies the content of one object passed as an argument +into another object also passed as an argument. +When the calling code no longer needs the copied object, +it can free that object. +.Pp +In some cases, if the object to be copied is reference counted, +the function does not actually copy the object but merely increments +its reference count and stores the pointer to it in the other object. +When the calling code no longer needs its original pointer to +the now inner object, it can free the original pointer, thus +decrementing the reference count of the inner object +and transferring ownership of the inner object to the outer object. +The inner object will then be freed automatically +when the outer object is freed later on. +.It set +Functions containing +.Dq set +in their name without a following digit may behave in +.Dq set0 +or, more rarely, in +.Dq set1 +style. +To find out which is the case, refer to the individual manual pages. +.It sk +stack: +The function manipulates a variable-sized array of pointers +in the idiosyncratic style described in +.Xr OPENSSL_sk_new 3 . +.It TS +X.509 time-stamp protocol: +See +.Xr TS_REQ_new 3 . +.It up_ref +The function increments the reference count of the argument by one. +Only a minority of object types support reference counting. +For those that do, if the reference count is greater than one, +the corresponding +.Dq free +function reverses the effect of one call to the +.Dq up_ref +function rather than freeing the object. +.El +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ssl 3 diff --git a/Libraries/libressl/man/d2i_ASN1_NULL.3 b/Libraries/libressl/man/d2i_ASN1_NULL.3 new file mode 100644 index 000000000..037c9c93e --- /dev/null +++ b/Libraries/libressl/man/d2i_ASN1_NULL.3 @@ -0,0 +1,92 @@ +.\" $OpenBSD: d2i_ASN1_NULL.3,v 1.5 2023/09/26 09:36:22 tb Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 26 2023 $ +.Dt D2I_ASN1_NULL 3 +.Os +.Sh NAME +.Nm d2i_ASN1_NULL , +.Nm i2d_ASN1_NULL +.Nd decode and encode an ASN.1 NULL type +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_NULL * +.Fo d2i_ASN1_NULL +.Fa "ASN1_NULL **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_NULL +.Fa "ASN1_NULL *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode the ASN.1 value NULL of type NULL. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_ASN1_NULL +verifies that the BER-encoded value at +.Pf * Fa der_in +is NULL and of type NULL. +It fails if +.Fa length +is less than 2 or if the first two bytes of +.Pf * Fa der_in +differ from 0x05 and 0x00. +In case of success, +.Pf * Fa der_in +is advanced by two bytes and +.Pf * Fa val_out +is set to a specific invalid pointer representing the unique +.Vt ASN1_NULL +object. +.Pp +.Fn i2d_ASN1_NULL +ignores +.Fa val_in +and encodes the ASN.1 value NULL of type NULL using DER. +Specifically, it writes the identifier octet for the type NULL, +0x05, followed by the length octet 0x00, and no content or +end-of-content octets. +.Sh RETURN VALUES +.Fn d2i_ASN1_NULL +returns a specific invalid pointer representing the unique +.Vt ASN1_NULL +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_ASN1_NULL +returns 2 if successful or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr ASN1_item_new 3 , +.Xr ASN1_NULL_new 3 , +.Xr ASN1_TYPE_get 3 +.Sh STANDARDS +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.8: Encoding of a null value +.Sh HISTORY +.Fn d2i_ASN1_NULL +and +.Fn i2d_ASN1_NULL +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/d2i_ASN1_OBJECT.3 b/Libraries/libressl/man/d2i_ASN1_OBJECT.3 new file mode 100644 index 000000000..cf750162e --- /dev/null +++ b/Libraries/libressl/man/d2i_ASN1_OBJECT.3 @@ -0,0 +1,164 @@ +.\" $OpenBSD: d2i_ASN1_OBJECT.3,v 1.14 2023/08/09 17:27:26 schwarze Exp $ +.\" +.\" Copyright (c) 2017, 2022, 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 9 2023 $ +.Dt D2I_ASN1_OBJECT 3 +.Os +.Sh NAME +.Nm d2i_ASN1_OBJECT , +.Nm i2d_ASN1_OBJECT , +.Nm OBJ_get0_data , +.Nm OBJ_length +.Nd decode and encode ASN.1 object identifiers +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_OBJECT * +.Fo d2i_ASN1_OBJECT +.Fa "ASN1_OBJECT **val_out" +.Fa "unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_OBJECT +.Fa "const ASN1_OBJECT *val_in" +.Fa "unsigned char **der_out" +.Fc +.In openssl/objects.h +.Ft const unsigned char * +.Fn OBJ_get0_data "const ASN1_OBJECT *val_in" +.Ft size_t +.Fn OBJ_length "const ASN1_OBJECT *val_in" +.Sh DESCRIPTION +These functions decode and encode ASN.1 object identifiers. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +The LibreSSL implementation of +.Fn d2i_ASN1_OBJECT +always calls +.Xr ASN1_OBJECT_free 3 +if an existing object is passed in via +.Fa val_out +and it always creates a new object from scratch. +Other implementations may attempt to reuse an existing object, +which is fragile and prone to bugs. +Consequently, always passing +.Dv NULL +for the +.Fa val_out +argument is recommended. +.Pp +The objects returned from +.Fn d2i_ASN1_OBJECT +and the data contained in them are always marked as dynamically +allocated, so when they are no longer needed, +.Xr ASN1_OBJECT_free 3 +can be called on them. +.Pp +.Fn i2d_ASN1_OBJECT +encodes the object identifier pointed to by +.Fa val_in +into DER format. +.Fn OBJ_get0_data +and +.Fn OBJ_length +only deal with the content octets of that DER encoding, +without taking the identifier and length octets into account. +.Sh RETURN VALUES +.Fn d2i_ASN1_OBJECT +returns a pointer to the new +.Vt ASN1_OBJECT +object or +.Dv NULL +if an error occurs. +With other implementations, it might return a pointer to the reused +.Vt ASN1_OBJECT . +.Pp +.Fn i2d_ASN1_OBJECT +returns the number of octets successfully encoded +or a value <= 0 if an error occurs. +.Pp +.Fn OBJ_get0_data +returns an internal pointer to the first content octet of the DER +encoding of +.Fa val_in . +The other content octets follow the returned pointer contiguously. +.Fn OBJ_length +returns the number of content octets contained in the DER encoding of +.Fa val_in . +This number is always smaller than the total length of the encoding +returned by +.Xr ASN1_object_size 3 . +.Pp +If +.Fa val_in +is a +.Dv NULL +pointer or points to an empty object, for example one freshly created with +.Xr ASN1_OBJECT_new 3 , +.Fn OBJ_get0_data +returns +.Dv NULL +and +.Fn OBJ_length +returns zero. +.Sh SEE ALSO +.Xr a2d_ASN1_OBJECT 3 , +.Xr ASN1_item_d2i 3 , +.Xr ASN1_OBJECT_new 3 , +.Xr ASN1_put_object 3 , +.Xr OBJ_nid2obj 3 +.Sh STANDARDS +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.19: Encoding of an object identifier value +.Sh HISTORY +.Fn d2i_ASN1_OBJECT +and +.Fn i2d_ASN1_OBJECT +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn OBJ_get0_data +and +.Fn OBJ_length +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . +.Sh CAVEATS +.Fn d2i_ASN1_OBJECT +never sets the long and short names of the object, not even if the +object identifier matches one that is built into the library. +To find the names of an object identifier parsed from DER or BER +input, call +.Xr OBJ_obj2nid 3 +on the returned object, and then +.Xr OBJ_nid2sn 3 +and +.Xr OBJ_nid2ln 3 +on the result. +.Pp +Calling +.Fn OBJ_get0_data +and then accessing memory in front of the returned pointer +results in undefined behaviour. +In particular, it is not possible to find the identifier or +length octets in that way; use +.Xr ASN1_put_object 3 +or +.Fn i2d_ASN1_OBJECT +instead. diff --git a/Libraries/libressl/man/d2i_ASN1_OCTET_STRING.3 b/Libraries/libressl/man/d2i_ASN1_OCTET_STRING.3 new file mode 100644 index 000000000..6d79ae403 --- /dev/null +++ b/Libraries/libressl/man/d2i_ASN1_OCTET_STRING.3 @@ -0,0 +1,454 @@ +.\" $OpenBSD: d2i_ASN1_OCTET_STRING.3,v 1.19 2022/09/12 14:36:09 tb Exp $ +.\" +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 12 2022 $ +.Dt D2I_ASN1_OCTET_STRING 3 +.Os +.Sh NAME +.Nm d2i_ASN1_OCTET_STRING , +.Nm i2d_ASN1_OCTET_STRING , +.Nm d2i_ASN1_BIT_STRING , +.Nm i2d_ASN1_BIT_STRING , +.Nm d2i_ASN1_INTEGER , +.Nm i2d_ASN1_INTEGER , +.Nm d2i_ASN1_UINTEGER , +.Nm d2i_ASN1_ENUMERATED , +.Nm i2d_ASN1_ENUMERATED , +.Nm d2i_ASN1_UTF8STRING , +.Nm i2d_ASN1_UTF8STRING , +.Nm d2i_ASN1_IA5STRING , +.Nm i2d_ASN1_IA5STRING , +.Nm d2i_ASN1_UNIVERSALSTRING , +.Nm i2d_ASN1_UNIVERSALSTRING , +.Nm d2i_ASN1_BMPSTRING , +.Nm i2d_ASN1_BMPSTRING , +.Nm d2i_ASN1_GENERALSTRING , +.Nm i2d_ASN1_GENERALSTRING , +.Nm d2i_ASN1_T61STRING , +.Nm i2d_ASN1_T61STRING , +.Nm d2i_ASN1_VISIBLESTRING , +.Nm i2d_ASN1_VISIBLESTRING , +.Nm d2i_ASN1_PRINTABLESTRING , +.Nm i2d_ASN1_PRINTABLESTRING , +.Nm d2i_ASN1_PRINTABLE , +.Nm i2d_ASN1_PRINTABLE , +.Nm d2i_DIRECTORYSTRING , +.Nm i2d_DIRECTORYSTRING , +.Nm d2i_DISPLAYTEXT , +.Nm i2d_DISPLAYTEXT , +.Nm d2i_ASN1_GENERALIZEDTIME , +.Nm i2d_ASN1_GENERALIZEDTIME , +.Nm d2i_ASN1_UTCTIME , +.Nm i2d_ASN1_UTCTIME , +.Nm d2i_ASN1_TIME , +.Nm i2d_ASN1_TIME +.Nd decode and encode ASN1_STRING objects +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_OCTET_STRING * +.Fo d2i_ASN1_OCTET_STRING +.Fa "ASN1_OCTET_STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_OCTET_STRING +.Fa "ASN1_OCTET_STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_BIT_STRING * +.Fo d2i_ASN1_BIT_STRING +.Fa "ASN1_BIT_STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_BIT_STRING +.Fa "ASN1_BIT_STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_INTEGER * +.Fo d2i_ASN1_INTEGER +.Fa "ASN1_INTEGER **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_INTEGER +.Fa "ASN1_INTEGER *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_INTEGER * +.Fo d2i_ASN1_UINTEGER +.Fa "ASN1_INTEGER **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft ASN1_ENUMERATED * +.Fo d2i_ASN1_ENUMERATED +.Fa "ASN1_ENUMERATED **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_ENUMERATED +.Fa "ASN1_ENUMERATED *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_UTF8STRING * +.Fo d2i_ASN1_UTF8STRING +.Fa "ASN1_UTF8STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_UTF8STRING +.Fa "ASN1_UTF8STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_IA5STRING * +.Fo d2i_ASN1_IA5STRING +.Fa "ASN1_IA5STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_IA5STRING +.Fa "ASN1_IA5STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_UNIVERSALSTRING * +.Fo d2i_ASN1_UNIVERSALSTRING +.Fa "ASN1_UNIVERSALSTRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_UNIVERSALSTRING +.Fa "ASN1_UNIVERSALSTRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_BMPSTRING * +.Fo d2i_ASN1_BMPSTRING +.Fa "ASN1_BMPSTRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_BMPSTRING +.Fa "ASN1_BMPSTRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_GENERALSTRING * +.Fo d2i_ASN1_GENERALSTRING +.Fa "ASN1_GENERALSTRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_GENERALSTRING +.Fa "ASN1_GENERALSTRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_T61STRING * +.Fo d2i_ASN1_T61STRING +.Fa "ASN1_T61STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_T61STRING +.Fa "ASN1_T61STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_VISIBLESTRING * +.Fo d2i_ASN1_VISIBLESTRING +.Fa "ASN1_VISIBLESTRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_VISIBLESTRING +.Fa "ASN1_VISIBLESTRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_PRINTABLESTRING * +.Fo d2i_ASN1_PRINTABLESTRING +.Fa "ASN1_PRINTABLESTRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_PRINTABLESTRING +.Fa "ASN1_PRINTABLESTRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_STRING * +.Fo d2i_ASN1_PRINTABLE +.Fa "ASN1_STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_PRINTABLE +.Fa "ASN1_STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_STRING * +.Fo d2i_DIRECTORYSTRING +.Fa "ASN1_STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DIRECTORYSTRING +.Fa "ASN1_STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_STRING * +.Fo d2i_DISPLAYTEXT +.Fa "ASN1_STRING **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DISPLAYTEXT +.Fa "ASN1_STRING *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_GENERALIZEDTIME * +.Fo d2i_ASN1_GENERALIZEDTIME +.Fa "ASN1_GENERALIZEDTIME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_GENERALIZEDTIME +.Fa "ASN1_GENERALIZEDTIME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_UTCTIME * +.Fo d2i_ASN1_UTCTIME +.Fa "ASN1_UTCTIME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_UTCTIME +.Fa "ASN1_UTCTIME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_TIME * +.Fo d2i_ASN1_TIME +.Fa "ASN1_TIME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_TIME +.Fa "ASN1_TIME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode various ASN.1 built-in types +that can be represented by +.Vt ASN1_STRING +objects. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +The format consists of one identifier byte, one or more length bytes, +and one or more content bytes. +The identifier bytes and corresponding ASN.1 types are as follows: +.Bl -column ASN1_GENERALIZEDTIME identifier +.It Em OpenSSL type Ta Em identifier Ta Em ASN.1 type +.It Ta +.It Vt ASN1_OCTET_STRING Ta 0x04 Ta OCTET STRING +.It Vt ASN1_BIT_STRING Ta 0x03 Ta BIT STRING +.It Vt ASN1_INTEGER Ta 0x02 Ta INTEGER +.It Vt ASN1_ENUMERATED Ta 0x0a Ta ENUMERATED +.It Vt ASN1_UTF8STRING Ta 0x0c Ta UTF8String +.It Vt ASN1_IA5STRING Ta 0x16 Ta IA5String +.It Vt ASN1_UNIVERSALSTRING Ta 0x1c Ta UniversalString +.It Vt ASN1_BMPSTRING Ta 0x1e Ta BMPString +.It Vt ASN1_GENERALSTRING Ta 0x1b Ta GeneralString +.It Vt ASN1_T61STRING Ta 0x14 Ta T61String +.It Vt ASN1_VISIBLESTRING Ta 0x1a Ta VisibleString +.It Vt ASN1_PRINTABLESTRING Ta 0x13 Ta PrintableString +.It Vt ASN1_GENERALIZEDTIME Ta 0x18 Ta GeneralizedTime +.It Vt ASN1_UTCTIME Ta 0x17 Ta UTCTime +.El +.Pp +.Fn d2i_DIRECTORYSTRING +and +.Fn i2d_DIRECTORYSTRING +decode and encode an ASN.1 +.Vt DirectoryString +structure defined in RFC 5280 section 4.1.2.4 +and used for ASN.1 +.Vt EDIPartyName +structures; see +.Xr EDIPARTYNAME_new 3 . +When decoding, it accepts any of the types UTF8String, UniversalString, +BMPString, T61String, or PrintableString. +When encoding, +it writes out the character string type that is actually passed in. +.Pp +.Fn d2i_ASN1_PRINTABLE +and +.Fn i2d_ASN1_PRINTABLE +are non-standard variants of +.Fn d2i_DIRECTORYSTRING +and +.Fn i2d_DIRECTORYSTRING +that also accept IA5String, NumericString, BIT STRING, and SEQUENCE +ASN.1 values as well as ASN.1 values with unknown identifier +bytes (0x07, 0x08, 0x09, 0x0b, 0x0d, 0x0e, 0x0f, 0x1d, and 0x1f). +Even though the standard requires the use of +.Vt DirectoryString +in the relative distinguished names described in +.Xr X509_NAME_ENTRY_new 3 , +the library accepts this wider range of choices. +.Pp +.Fn d2i_DISPLAYTEXT +and +.Fn i2d_DISPLAYTEXT +decode and encode an ASN.1 +.Vt DisplayText +structure defined in RFC 5280 section 4.2.1.4 +and used for ASN.1 +.Vt UserNotice +structures in certificate policies; see +.Xr USERNOTICE_new 3 . +When decoding, it accepts any of the types UTF8String, IA5String, +BMPString, or VisibleString. +When encoding, +it writes out the character string type that is actually passed in. +.Pp +.Fn d2i_ASN1_TIME +and +.Fn i2d_ASN1_TIME +decode and encode an ASN.1 +.Vt Time +structure defined in RFC 5280 section 4.1 +and used for ASN.1 +.Vt Validity +structures in certificates; see +.Xr X509_VAL_new 3 . +They are also used for certificate revocation lists; see +.Xr X509_CRL_INFO_new 3 . +When decoding, it accepts either GeneralizedTime or UTCTime. +When encoding, it writes out the time type that is actually passed in. +.Pp +The following constants describe the ASN.1 tags that are valid +when decoding with the above functions. +See +.Xr ASN1_tag2bit 3 +for more details about the +.Dv B_ASN1_* +constants. +.Bl -column d2i_DIRECTORYSTRING() B_ASN1_DIRECTORYSTRING -offset indent +.It decoding function Ta mask constant +.It Fn d2i_DIRECTORYSTRING Ta Dv B_ASN1_DIRECTORYSTRING +.It Fn d2i_ASN1_PRINTABLE Ta Dv B_ASN1_PRINTABLE +.It Fn d2i_DISPLAYTEXT Ta Dv B_ASN1_DISPLAYTEXT +.It Fn d2i_ASN1_TIME Ta Dv B_ASN1_TIME +.El +.Pp +.Fn d2i_ASN1_UINTEGER +is similar to +.Fn d2i_ASN1_INTEGER +except that it ignores the sign bit in the BER encoding and treats +all integers as positive. +It helps to process BER input produced by broken software +that neglects adding a leading NUL content byte where required. +.Sh RETURN VALUES +The +.Fn d2i_* +decoding functions return an +.Vt ASN1_STRING +object or +.Dv NULL +if an error occurs. +.Pp +The +.Fn i2d_* +encoding functions return the number of bytes successfully encoded +or a negative value if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr ASN1_STRING_new 3 +.Sh STANDARDS +ITU-T Recommendation X.680, also known as ISO/IEC 8824-1: +Information technology - Abstract Syntax Notation One (ASN.1): +Specification of basic notation +.Pp +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn d2i_ASN1_OCTET_STRING , +.Fn i2d_ASN1_OCTET_STRING , +.Fn d2i_ASN1_BIT_STRING , +.Fn i2d_ASN1_BIT_STRING , +.Fn d2i_ASN1_INTEGER , +.Fn i2d_ASN1_INTEGER , +.Fn d2i_ASN1_IA5STRING , +.Fn i2d_ASN1_IA5STRING , +.Fn d2i_ASN1_T61STRING , +.Fn i2d_ASN1_T61STRING , +.Fn d2i_ASN1_PRINTABLESTRING , +.Fn i2d_ASN1_PRINTABLESTRING , +.Fn d2i_ASN1_PRINTABLE , +.Fn i2d_ASN1_PRINTABLE , +.Fn d2i_ASN1_UTCTIME , +and +.Fn i2d_ASN1_UTCTIME +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn d2i_ASN1_BMPSTRING +and +.Fn i2d_ASN1_BMPSTRING +first appeared in SSLeay 0.9.1. +.Fn d2i_ASN1_ENUMERATED , +.Fn i2d_ASN1_ENUMERATED , +.Fn d2i_ASN1_GENERALIZEDTIME , +.Fn i2d_ASN1_GENERALIZEDTIME , +.Fn d2i_ASN1_TIME , +and +.Fn i2d_ASN1_TIME +first appeared in OpenSSL 0.9.2b. +.Fn d2i_ASN1_UINTEGER , +.Fn d2i_ASN1_UTF8STRING , +.Fn i2d_ASN1_UTF8STRING , +.Fn d2i_ASN1_VISIBLESTRING , +.Fn i2d_ASN1_VISIBLESTRING , +.Fn d2i_DIRECTORYSTRING , +.Fn i2d_DIRECTORYSTRING , +.Fn d2i_DISPLAYTEXT +and +.Fn i2d_DISPLAYTEXT +first appeared in OpenSSL 0.9.3. +These functions have been available since +.Ox 2.6 . +.Pp +.Fn d2i_ASN1_UNIVERSALSTRING , +.Fn i2d_ASN1_UNIVERSALSTRING , +.Fn d2i_ASN1_GENERALSTRING , +and +.Fn i2d_ASN1_GENERALSTRING +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/d2i_ASN1_SEQUENCE_ANY.3 b/Libraries/libressl/man/d2i_ASN1_SEQUENCE_ANY.3 new file mode 100644 index 000000000..654f0b1e6 --- /dev/null +++ b/Libraries/libressl/man/d2i_ASN1_SEQUENCE_ANY.3 @@ -0,0 +1,98 @@ +.\" $OpenBSD: d2i_ASN1_SEQUENCE_ANY.3,v 1.3 2021/12/09 19:05:09 schwarze Exp $ +.\" +.\" Copyright (c) 2017, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 9 2021 $ +.Dt D2I_ASN1_SEQUENCE_ANY 3 +.Os +.Sh NAME +.Nm d2i_ASN1_SEQUENCE_ANY , +.Nm i2d_ASN1_SEQUENCE_ANY , +.Nm d2i_ASN1_SET_ANY , +.Nm i2d_ASN1_SET_ANY +.Nd decode and encode ASN.1 sequences and sets +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft ASN1_SEQUENCE_ANY * +.Fo d2i_ASN1_SEQUENCE_ANY +.Fa "ASN1_SEQUENCE_ANY **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_SEQUENCE_ANY +.Fa "const ASN1_SEQUENCE_ANY *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ASN1_SEQUENCE_ANY * +.Fo d2i_ASN1_SET_ANY +.Fa "ASN1_SEQUENCE_ANY **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ASN1_SET_ANY +.Fa "const ASN1_SEQUENCE_ANY *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode ASN.1 sequences and sets, +which are also represented by the +.Dv V_ASN1_SEQUENCE +and +.Dv V_ASN1_SET +type identifier constants, respectively. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +The type +.Vt ASN1_SEQUENCE_ANY +is defined as +.Vt STACK_OF(ASN1_TYPE) . +Whether such an object represents a sequence or a set is not stored +in the object itself but needs to be remembered separately. +.Pp +Like for +.Xr d2i_ASN1_TYPE 3 +and +.Xr i2d_ASN1_TYPE 3 , +the type of the individual values contained in the sequence or set +is not specified when calling the functions. +It might vary among the members, and it is stored together with +each value in each +.Vt ASN1_TYPE +object contained in the sequence or set. +.Sh RETURN VALUES +.Fn d2i_ASN1_SEQUENCE_ANY +returns an +.Vt ASN1_SEQUENCE_ANY +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_ASN1_SEQUENCE_ANY +returns the number of bytes written or a negative value if an error +occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr ASN1_TYPE_new 3 +.Sh HISTORY +.Fn d2i_ASN1_SEQUENCE_ANY , +.Fn i2d_ASN1_SEQUENCE_ANY , +.Fn d2i_ASN1_SET_ANY , +and +.Fn i2d_ASN1_SET_ANY +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/d2i_AUTHORITY_KEYID.3 b/Libraries/libressl/man/d2i_AUTHORITY_KEYID.3 new file mode 100644 index 000000000..413f41e17 --- /dev/null +++ b/Libraries/libressl/man/d2i_AUTHORITY_KEYID.3 @@ -0,0 +1,75 @@ +.\" $OpenBSD: d2i_AUTHORITY_KEYID.3,v 1.2 2018/03/21 16:09:51 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt D2I_AUTHORITY_KEYID 3 +.Os +.Sh NAME +.Nm d2i_AUTHORITY_KEYID , +.Nm i2d_AUTHORITY_KEYID +.Nd decode and encode X.509 authority key identifiers +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft AUTHORITY_KEYID * +.Fo d2i_AUTHORITY_KEYID +.Fa "AUTHORITY_KEYID **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_AUTHORITY_KEYID +.Fa "AUTHORITY_KEYID *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Fn d2i_AUTHORITY_KEYID +and +.Fn i2d_AUTHORITY_KEYID +decode and encode an ASN.1 +.Vt AuthorityKeyIdentifier +structure defined in RFC 5280 section 4.2.1.1. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Sh RETURN VALUES +.Fn d2i_AUTHORITY_KEYID +returns an +.Vt AUTHORITY_KEYID +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_AUTHORITY_KEYID +returns the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr AUTHORITY_KEYID_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile: +.Bl -dash -compact +.It +section 4.2.1.1: Certificate Extensions: Authority Key Identifier +.It +section 5.2.1: CRL Extensions: Authority Key Identifier +.El +.Sh HISTORY +.Fn d2i_AUTHORITY_KEYID +and +.Fn i2d_AUTHORITY_KEYID +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/d2i_BASIC_CONSTRAINTS.3 b/Libraries/libressl/man/d2i_BASIC_CONSTRAINTS.3 new file mode 100644 index 000000000..2964a1f90 --- /dev/null +++ b/Libraries/libressl/man/d2i_BASIC_CONSTRAINTS.3 @@ -0,0 +1,106 @@ +.\" $OpenBSD: d2i_BASIC_CONSTRAINTS.3,v 1.3 2018/03/22 21:08:22 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt D2I_BASIC_CONSTRAINTS 3 +.Os +.Sh NAME +.Nm d2i_BASIC_CONSTRAINTS , +.Nm i2d_BASIC_CONSTRAINTS , +.Nm d2i_EXTENDED_KEY_USAGE , +.Nm i2d_EXTENDED_KEY_USAGE +.Nd decode and encode X.509 key usage purposes +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft BASIC_CONSTRAINTS * +.Fo d2i_BASIC_CONSTRAINTS +.Fa "BASIC_CONSTRAINTS **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_BASIC_CONSTRAINTS +.Fa "BASIC_CONSTRAINTS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft EXTENDED_KEY_USAGE * +.Fo d2i_EXTENDED_KEY_USAGE +.Fa "EXTENDED_KEY_USAGE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_EXTENDED_KEY_USAGE +.Fa "EXTENDED_KEY_USAGE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode data structures describing the +intended purposes that the key contained in an X.509 certificate +is to be used for. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_BASIC_CONSTRAINTS +and +.Fn i2d_BASIC_CONSTRAINTS +decode and encode an ASN.1 +.Vt BasicConstraints +structure defined in RFC 5280 section 4.2.1.9. +.Pp +.Fn d2i_EXTENDED_KEY_USAGE +and +.Fn i2d_EXTENDED_KEY_USAGE +decode and encode an ASN.1 +.Vt ExtKeyUsageSyntax +structure defined in RFC 5280 section 4.2.1.12. +.Sh RETURN VALUES +.Fn d2i_BASIC_CONSTRAINTS +and +.Fn d2i_EXTENDED_KEY_USAGE +return a +.Vt BASIC_CONSTRAINTS +or +.Vt EXTENDED_KEY_USAGE +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_BASIC_CONSTRAINTS +and +.Fn i2d_EXTENDED_KEY_USAGE +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr BASIC_CONSTRAINTS_new 3 , +.Xr EXTENDED_KEY_USAGE_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn d2i_BASIC_CONSTRAINTS +and +.Fn i2d_BASIC_CONSTRAINTS +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Pp +.Fn d2i_EXTENDED_KEY_USAGE +and +.Fn i2d_EXTENDED_KEY_USAGE +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/d2i_CMS_ContentInfo.3 b/Libraries/libressl/man/d2i_CMS_ContentInfo.3 new file mode 100644 index 000000000..0c61047c4 --- /dev/null +++ b/Libraries/libressl/man/d2i_CMS_ContentInfo.3 @@ -0,0 +1,128 @@ +.\" $OpenBSD: d2i_CMS_ContentInfo.3,v 1.3 2019/11/02 15:39:46 schwarze Exp $ +.\" Copyright (c) 2019 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt D2I_CMS_CONTENTINFO 3 +.Os +.Sh NAME +.Nm d2i_CMS_ContentInfo , +.Nm i2d_CMS_ContentInfo , +.Nm d2i_CMS_bio , +.Nm i2d_CMS_bio , +.Nm d2i_CMS_ReceiptRequest , +.Nm i2d_CMS_ReceiptRequest +.Nd decode and encode Cryptographic Message Syntax data +.Sh SYNOPSIS +.In openssl/cms.h +.Ft CMS_ContentInfo * +.Fo d2i_CMS_ContentInfo +.Fa "CMS_ContentInfo **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_CMS_ContentInfo +.Fa "CMS_ContentInfo *val_in" +.Fa "unsigned char **out" +.Fc +.Ft CMS_ContentInfo * +.Fo d2i_CMS_bio +.Fa "BIO *in_bio" +.Fa "CMS_ContentInfo **val_out" +.Fc +.Ft int +.Fo i2d_CMS_bio +.Fa "BIO *out_bio" +.Fa "CMS_ContentInfo *val_in" +.Fc +.Ft CMS_ReceiptRequest * +.Fo d2i_CMS_ReceiptRequest +.Fa "CMS_ReceiptRequest **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_CMS_ReceiptRequest +.Fa "CMS_ReceiptRequest *val_in" +.Fa "unsigned char **out" +.Fc +.Sh DESCRIPTION +These functions decode and encode Cryptographic Message Syntax +data structures. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_CMS_ContentInfo +and +.Fn i2d_CMS_ContentInfo +decode and encode a +.Vt CMS_ContentInfo +structure defined in RFC 5652 section 3. +.Fn d2i_CMS_bio +and +.Fn i2d_CMS_bio +are similar except that they decode or encode using a +.Vt BIO +pointer. +.Pp +.Fn d2i_CMS_ReceiptRequest +and +.Fn i2d_CMS_ReceiptRequest +decode and encode a +.Vt CMS_ReceiptRequest +structure defined in RFC 2634 section 2.7. +.Sh RETURN VALUES +.Fn d2i_CMS_ContentInfo +and +.Fn d2i_CMS_bio +return a valid +.Vt CMS_ContentInfo +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_CMS_ReceiptRequest +returns a valid +.Vt CMS_ReceiptRequest +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_CMS_ContentInfo +and +.Fn i2d_CMS_ReceiptRequest +return the number of bytes successfully encoded +or a negative value if an error occurs. +.Pp +.Fn i2d_CMS_bio +returns 1 for success or 0 if an error occurs. +.Pp +For all functions, the error code can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_get0_type 3 , +.Xr CMS_ReceiptRequest_create0 3 , +.Xr i2d_CMS_bio_stream 3 +.Sh STANDARDS +RFC 5652: Cryptographic Message Syntax, section 3: General Syntax +.Pp +RFC 2634: Enhanced Security Services for S/MIME, +section 2.7: Receipt Request Syntax +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8h +and have been available since +.Ox 6.7 . diff --git a/Libraries/libressl/man/d2i_DHparams.3 b/Libraries/libressl/man/d2i_DHparams.3 new file mode 100644 index 000000000..7fd9878dc --- /dev/null +++ b/Libraries/libressl/man/d2i_DHparams.3 @@ -0,0 +1,99 @@ +.\" $OpenBSD: d2i_DHparams.3,v 1.8 2018/03/27 17:35:50 schwarze Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Ulf Moeller and +.\" Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2015, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt D2I_DHPARAMS 3 +.Os +.Sh NAME +.Nm d2i_DHparams , +.Nm i2d_DHparams +.Nd PKCS#3 DH parameter functions +.Sh SYNOPSIS +.In openssl/dh.h +.Ft DH * +.Fo d2i_DHparams +.Fa "DH **a" +.Fa "unsigned char **pp" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DHparams +.Fa "DH *a" +.Fa "unsigned char **pp" +.Fc +.Sh DESCRIPTION +These functions decode and encode PKCS#3 DH parameters using the +DHparameter structure described in PKCS#3. +They otherwise behave in a way similar to +.Xr d2i_X509 3 +and +.Xr i2d_X509 3 . +.Sh RETURN VALUES +.Fn d2i_DHparams +returns a +.Vt DH +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_DHparams +returns the number of bytes successfully encoded or a value <= 0 +if an error occurs. +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr DH_new 3 +.Sh HISTORY +.Fn d2i_DHparams +and +.Fn i2d_DHparams +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/d2i_DIST_POINT.3 b/Libraries/libressl/man/d2i_DIST_POINT.3 new file mode 100644 index 000000000..34bdb26fb --- /dev/null +++ b/Libraries/libressl/man/d2i_DIST_POINT.3 @@ -0,0 +1,201 @@ +.\" $OpenBSD: d2i_DIST_POINT.3,v 1.4 2018/03/23 04:34:23 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt D2I_DIST_POINT 3 +.Os +.Sh NAME +.Nm d2i_DIST_POINT , +.Nm i2d_DIST_POINT , +.Nm d2i_CRL_DIST_POINTS , +.Nm i2d_CRL_DIST_POINTS , +.Nm d2i_DIST_POINT_NAME , +.Nm i2d_DIST_POINT_NAME , +.Nm d2i_ISSUING_DIST_POINT , +.Nm i2d_ISSUING_DIST_POINT , +.Nm d2i_ACCESS_DESCRIPTION , +.Nm i2d_ACCESS_DESCRIPTION , +.Nm d2i_AUTHORITY_INFO_ACCESS , +.Nm i2d_AUTHORITY_INFO_ACCESS +.Nd decode and encode X.509 data access extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft DIST_POINT * +.Fo d2i_DIST_POINT +.Fa "DIST_POINT_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DIST_POINT +.Fa "DIST_POINT *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft CRL_DIST_POINTS * +.Fo d2i_CRL_DIST_POINTS +.Fa "CRL_DIST_POINTS_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_CRL_DIST_POINTS +.Fa "CRL_DIST_POINTS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft DIST_POINT_NAME * +.Fo d2i_DIST_POINT_NAME +.Fa "DIST_POINT_NAME_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DIST_POINT_NAME +.Fa "DIST_POINT_NAME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ISSUING_DIST_POINT * +.Fo d2i_ISSUING_DIST_POINT +.Fa "ISSUING_DIST_POINT_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ISSUING_DIST_POINT +.Fa "ISSUING_DIST_POINT *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ACCESS_DESCRIPTION * +.Fo d2i_ACCESS_DESCRIPTION +.Fa "ACCESS_DESCRIPTION_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ACCESS_DESCRIPTION +.Fa "ACCESS_DESCRIPTION *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft AUTHORITY_INFO_ACCESS * +.Fo d2i_AUTHORITY_INFO_ACCESS +.Fa "AUTHORITY_INFO_ACCESS_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_AUTHORITY_INFO_ACCESS +.Fa "AUTHORITY_INFO_ACCESS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode X.509 extensions that communicate +where to retrieve additional information online. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_DIST_POINT +and +.Fn i2d_DIST_POINT +decode and encode an ASN.1 +.Vt DistributionPoint +structure defined in RFC 5280 section 4.2.1.13. +.Pp +.Fn d2i_CRL_DIST_POINTS +and +.Fn i2d_CRL_DIST_POINTS +decode and encode an ASN.1 +.Vt CRLDistributionPoints +structure defined in RFC 5280 section 4.2.1.13. +.Pp +.Fn d2i_DIST_POINT_NAME +and +.Fn i2d_DIST_POINT_NAME +decode and encode an ASN.1 +.Vt DistributionPointName +structure defined in RFC 5280 section 4.2.1.13. +.Pp +.Fn d2i_ISSUING_DIST_POINT +and +.Fn i2d_ISSUING_DIST_POINT +decode and encode an ASN.1 +.Vt IssuingDistributionPoint +structure defined in RFC 5280 section 5.2.5. +.Pp +.Fn d2i_ACCESS_DESCRIPTION +and +.Fn i2d_ACCESS_DESCRIPTION +decode and encode an ASN.1 +.Vt AccessDescription +structure defined in RFC 5280 section 4.2.2.1. +.Pp +.Fn d2i_AUTHORITY_INFO_ACCESS +and +.Fn i2d_AUTHORITY_INFO_ACCESS +decode and encode an ASN.1 +.Vt AuthorityInfoAccessSyntax +structure defined in RFC 5280 section 4.2.2.1. +.Sh RETURN VALUES +.Fn d2i_DIST_POINT , +.Fn d2i_CRL_DIST_POINTS , +.Fn d2i_DIST_POINT_NAME , +.Fn d2i_ISSUING_DIST_POINT , +.Fn d2i_ACCESS_DESCRIPTION , +and +.Fn d2i_AUTHORITY_INFO_ACCESS +return an object of the respective type or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_DIST_POINT , +.Fn i2d_CRL_DIST_POINTS , +.Fn i2d_DIST_POINT_NAME , +.Fn i2d_ISSUING_DIST_POINT , +.Fn i2d_ACCESS_DESCRIPTION , +and +.Fn i2d_AUTHORITY_INFO_ACCESS +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ACCESS_DESCRIPTION_new 3 , +.Xr ASN1_item_d2i 3 , +.Xr DIST_POINT_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn d2i_DIST_POINT , +.Fn i2d_DIST_POINT , +.Fn d2i_CRL_DIST_POINTS , +.Fn i2d_CRL_DIST_POINTS , +.Fn d2i_DIST_POINT_NAME , +and +.Fn i2d_DIST_POINT_NAME +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . +.Pp +.Fn d2i_ACCESS_DESCRIPTION , +.Fn i2d_ACCESS_DESCRIPTION , +.Fn d2i_AUTHORITY_INFO_ACCESS , +and +.Fn i2d_AUTHORITY_INFO_ACCESS +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn d2i_ISSUING_DIST_POINT +and +.Fn i2d_ISSUING_DIST_POINT +first appeared in OpenSSL 1.0.0 and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/d2i_DSAPublicKey.3 b/Libraries/libressl/man/d2i_DSAPublicKey.3 new file mode 100644 index 000000000..37ef22e1b --- /dev/null +++ b/Libraries/libressl/man/d2i_DSAPublicKey.3 @@ -0,0 +1,412 @@ +.\" $OpenBSD: d2i_DSAPublicKey.3,v 1.14 2018/08/26 17:03:32 tb Exp $ +.\" OpenSSL bb9ad09e Jun 6 00:43:05 2016 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2003, 2013, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: August 26 2018 $ +.Dt D2I_DSAPUBLICKEY 3 +.Os +.Sh NAME +.Nm d2i_DSAPublicKey , +.Nm i2d_DSAPublicKey , +.Nm d2i_DSA_PUBKEY , +.Nm i2d_DSA_PUBKEY , +.Nm d2i_DSA_PUBKEY_bio , +.Nm d2i_DSA_PUBKEY_fp , +.Nm i2d_DSA_PUBKEY_bio , +.Nm i2d_DSA_PUBKEY_fp , +.Nm d2i_DSAPrivateKey , +.Nm i2d_DSAPrivateKey , +.Nm d2i_DSAPrivateKey_bio , +.Nm d2i_DSAPrivateKey_fp , +.Nm i2d_DSAPrivateKey_bio , +.Nm i2d_DSAPrivateKey_fp , +.Nm d2i_DSAparams , +.Nm i2d_DSAparams , +.Nm d2i_DSAparams_bio , +.Nm i2d_DSAparams_bio , +.Nm d2i_DSAparams_fp , +.Nm i2d_DSAparams_fp , +.Nm DSAparams_dup , +.Nm d2i_DSA_SIG , +.Nm i2d_DSA_SIG +.Nd decode and encode DSA keys +.Sh SYNOPSIS +.In openssl/dsa.h +.Ft DSA * +.Fo d2i_DSAPublicKey +.Fa "DSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DSAPublicKey +.Fa "const DSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.In openssl/x509.h +.Ft DSA * +.Fo d2i_DSA_PUBKEY +.Fa "DSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DSA_PUBKEY +.Fa "const DSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft DSA * +.Fo d2i_DSA_PUBKEY_bio +.Fa "BIO *in_bio" +.Fa "DSA **val_out" +.Fc +.Ft DSA * +.Fo d2i_DSA_PUBKEY_fp +.Fa "FILE *in_fp" +.Fa "DSA **val_out" +.Fc +.Ft int +.Fo i2d_DSA_PUBKEY_bio +.Fa "BIO *out_bio" +.Fa "DSA *val_in" +.Fc +.Ft int +.Fo i2d_DSA_PUBKEY_fp +.Fa "FILE *out_fp" +.Fa "DSA *val_in" +.Fc +.In openssl/dsa.h +.Ft DSA * +.Fo d2i_DSAPrivateKey +.Fa "DSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DSAPrivateKey +.Fa "const DSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.In openssl/x509.h +.Ft DSA * +.Fo d2i_DSAPrivateKey_bio +.Fa "BIO *in_bio" +.Fa "DSA **val_out" +.Fc +.Ft DSA * +.Fo d2i_DSAPrivateKey_fp +.Fa "FILE *in_fp" +.Fa "DSA **val_out" +.Fc +.Ft int +.Fo i2d_DSAPrivateKey_bio +.Fa "BIO *out_bio" +.Fa "DSA *val_in" +.Fc +.Ft int +.Fo i2d_DSAPrivateKey_fp +.Fa "FILE *out_fp" +.Fa "DSA *val_in" +.Fc +.In openssl/dsa.h +.Ft DSA * +.Fo d2i_DSAparams +.Fa "DSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DSAparams +.Fa "const DSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft DSA * +.Fo d2i_DSAparams_bio +.Fa "BIO *in_bio" +.Fa "DSA **val_out" +.Fc +.Ft int +.Fo i2d_DSAparams_bio +.Fa "BIO *out_bio" +.Fa "DSA *val_in" +.Fc +.Ft DSA * +.Fo d2i_DSAparams_fp +.Fa "FILE *in_fp" +.Fa "DSA **val_out" +.Fc +.Ft int +.Fo i2d_DSAparams_fp +.Fa FILE *out_fp +.Fa "DSA *val_in" +.Fc +.Ft DSA * +.Fo DSAparams_dup +.Fa "DSA *val_in" +.Fc +.Ft DSA_SIG * +.Fo d2i_DSA_SIG +.Fa "DSA_SIG **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_DSA_SIG +.Fa "const DSA_SIG *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode DSA keys and parameters. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_DSAPublicKey +and +.Fn i2d_DSAPublicKey +decode and encode the DSA public key components using a non-standard +format, so consider using +.Fn d2i_DSA_PUBKEY +and +.Fn i2d_DSA_PUBKEY +instead. +The actual data encoded depends on the value of +.Fa val_in->write_params . +If +.Fa val_in->write_params +is zero, only the +.Fa val_in->pub_key +field is encoded as an ASN.1 INTEGER. +If +.Fa val_in->write_params +is 1, then a SEQUENCE consisting of the +.Fa val_in->p , +.Fa val_in->q , +.Fa val_in->g , +and +.Fa val_in->pub_key +fields is encoded. +.Pp +.Fn d2i_DSA_PUBKEY +and +.Fn i2d_DSA_PUBKEY +decode and encode a DSA public key using an ASN.1 +.Vt SubjectPublicKeyInfo +structure defined in RFC 5280 section 4.1 +and documented in +.Xr X509_PUBKEY_new 3 . +.Fn d2i_DSA_PUBKEY_bio , +.Fn d2i_DSA_PUBKEY_fp , +.Fn i2d_DSA_PUBKEY_bio , +and +.Fn i2d_DSA_PUBKEY_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_DSAPrivateKey +and +.Fn i2d_DSAPrivateKey +decode and encode the DSA private key components. +The +.Vt DSA +object passed to the private key encoding functions should have all +the private key components present. +These functions use a non-standard structure consisting of a +SEQUENCE containing the +.Fa val_in->p , +.Fa val_in->q , +.Fa val_in->g , +.Fa val_in->pub_key , +and +.Fa val_in->priv_key +fields. +This data format is unencrypted. +For private key security when writing private keys to files, +consider using +.Xr PEM_write_DSAPrivateKey 3 +instead. +.Fn d2i_DSAPrivateKey_bio , +.Fn d2i_DSAPrivateKey_fp , +.Fn i2d_DSAPrivateKey_bio , +and +.Fn i2d_DSAPrivateKey_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_DSAparams +and +.Fn i2d_DSAparams +decode and encode the DSA parameters using an ASN.1 +.Vt Dss-Parms +structure defined in RFC 3279 section 2.3.2 +and used for the parameters field of the ASN.1 +.Vt AlgorithmIdentifier +structure defined in RFC 5280 section 4.1.1.2. +.Fn d2i_DSAparams_bio , +.Fn i2d_DSAparams_bio , +.Fn d2i_DSAparams_fp , +.Fn i2d_DSAparams_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn DSAparams_dup +allocates and initializes an empty +.Vt DSA +object and copies the DSA parameters from +.Fa val_in +to it by calling +.Fn i2d_DSAparams +and +.Fn d2i_DSAparams . +If a private or public key are present in +.Fa val_in , +they are not copied. +.Pp +.Fn d2i_DSA_SIG +and +.Fn i2d_DSA_SIG +decode and encode a DSA signature using an ASN.1 +.Vt Dss-Sig-Value +structure as defined in RFC 3279 section 2.2.2 +and used for the signatureValue field of the ASN.1 +.Vt Certificate +structure described in RFC 5280 sections 4.1.1.3 and 5.1.1.3. +.Sh RETURN VALUES +.Fn d2i_DSAPublicKey , +.Fn d2i_DSA_PUBKEY , +.Fn d2i_DSA_PUBKEY_bio , +.Fn d2i_DSA_PUBKEY_fp , +.Fn d2i_DSAPrivateKey , +.Fn d2i_DSAPrivateKey_bio , +.Fn d2i_DSAPrivateKey_fp , +.Fn d2i_DSAparams , +.Fn d2i_DSAparams_bio , +.Fn d2i_DSAparams_fp , +and +.Fn DSAparams_dup +return a valid +.Vt DSA +object or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_DSA_SIG +returns a valid +.Vt DSA_SIG +object or +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr DSA_new 3 , +.Xr DSA_SIG_new 3 , +.Xr EVP_PKEY_set1_DSA 3 , +.Xr PEM_write_DSAPrivateKey 3 , +.Xr X509_PUBKEY_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.1: Basic Certificate Fields +.Pp +RFC 3279: Algorithms and Identifiers for the Internet X.509 Public +Key Infrastructure Certificate and Certificate Revocation List (CRL) +Profile: +.Bl -dash -compact +.It +section 2.2.2: DSA Signature Algorithm +.It +section 2.3.2: DSA Signature Keys +.El +.Sh HISTORY +.Fn d2i_DSAPublicKey , +.Fn i2d_DSAPublicKey , +.Fn d2i_DSAPrivateKey , +and +.Fn i2d_DSAPrivateKey +first appeared in SSLeay 0.6.0. +.Fn d2i_DSAPrivateKey_bio , +.Fn d2i_DSAPrivateKey_fp , +.Fn i2d_DSAPrivateKey_bio , +.Fn i2d_DSAPrivateKey_fp , +.Fn d2i_DSAparams , +.Fn i2d_DSAparams , +.Fn d2i_DSAparams_bio , +.Fn i2d_DSAparams_bio , +.Fn d2i_DSAparams_fp , +.Fn i2d_DSAparams_fp , +and +.Fn DSAparams_dup +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn d2i_DSA_SIG +and +.Fn i2d_DSA_SIG +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . +.Pp +.Fn d2i_DSA_PUBKEY , +.Fn i2d_DSA_PUBKEY , +.Fn d2i_DSA_PUBKEY_bio , +.Fn d2i_DSA_PUBKEY_fp , +.Fn i2d_DSA_PUBKEY_bio , +and +.Fn i2d_DSA_PUBKEY_fp +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/d2i_ECPKParameters.3 b/Libraries/libressl/man/d2i_ECPKParameters.3 new file mode 100644 index 000000000..e82e7911d --- /dev/null +++ b/Libraries/libressl/man/d2i_ECPKParameters.3 @@ -0,0 +1,467 @@ +.\" $OpenBSD: d2i_ECPKParameters.3,v 1.12 2018/05/19 22:51:40 schwarze Exp $ +.\" OpenSSL 05ea606a May 20 20:52:46 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Matt Caswell . +.\" Copyright (c) 2013, 2015 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 19 2018 $ +.Dt D2I_ECPKPARAMETERS 3 +.Os +.Sh NAME +.Nm d2i_ECPKParameters , +.Nm i2d_ECPKParameters , +.Nm d2i_ECPKParameters_bio , +.Nm i2d_ECPKParameters_bio , +.Nm d2i_ECPKParameters_fp , +.Nm i2d_ECPKParameters_fp , +.Nm d2i_ECParameters , +.Nm i2d_ECParameters , +.Nm ECParameters_dup , +.Nm d2i_ECPrivateKey , +.Nm i2d_ECPrivateKey , +.Nm d2i_ECPrivateKey_bio , +.Nm i2d_ECPrivateKey_bio , +.Nm d2i_ECPrivateKey_fp , +.Nm i2d_ECPrivateKey_fp , +.Nm o2i_ECPublicKey , +.Nm i2o_ECPublicKey , +.Nm ECPKParameters_print , +.Nm ECPKParameters_print_fp , +.Nm ECParameters_print , +.Nm ECParameters_print_fp , +.Nm d2i_EC_PUBKEY , +.Nm i2d_EC_PUBKEY , +.Nm d2i_EC_PUBKEY_bio , +.Nm i2d_EC_PUBKEY_bio , +.Nm d2i_EC_PUBKEY_fp , +.Nm i2d_EC_PUBKEY_fp +.Nd decode and encode ASN.1 representations of elliptic curve entities +.Sh SYNOPSIS +.In openssl/ec.h +.Ft EC_GROUP * +.Fo d2i_ECPKParameters +.Fa "EC_GROUP **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ECPKParameters +.Fa "const EC_GROUP *val_in" +.Fa "unsigned char **des_out" +.Fc +.Ft EC_GROUP * +.Fo d2i_ECPKParameters_bio +.Fa "BIO *in_bio" +.Fa "EC_GROUP **val_out" +.Fc +.Ft int +.Fo i2d_ECPKParameters_bio +.Fa "BIO *out_bio" +.Fa "EC_GROUP *val_in" +.Fc +.Ft EC_GROUP * +.Fo d2i_ECPKParameters_fp +.Fa "FILE *in_fp" +.Fa "EC_GROUP **val_out" +.Fc +.Ft int +.Fo i2d_ECPKParameters_fp +.Fa "FILE *out_fp" +.Fa "EC_GROUP *val_in" +.Fc +.Ft EC_KEY * +.Fo d2i_ECParameters +.Fa "EC_KEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ECParameters +.Fa "EC_KEY *val_in" +.Fa "unsigned char **des_out" +.Fc +.Ft EC_KEY * +.Fo ECParameters_dup +.Fa "EC_KEY *val_in" +.Fc +.Ft EC_KEY * +.Fo d2i_ECPrivateKey +.Fa "EC_KEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ECPrivateKey +.Fa "EC_KEY *val_in" +.Fa "unsigned char **des_out" +.Fc +.Ft EC_KEY * +.Fo d2i_ECPrivateKey_bio +.Fa "BIO *in_bio" +.Fa "EC_KEY **val_out" +.Fc +.Ft int +.Fo i2d_ECPrivateKey_bio +.Fa "BIO *out_bio" +.Fa "EC_KEY *val_in" +.Fc +.Ft EC_KEY * +.Fo d2i_ECPrivateKey_fp +.Fa "FILE *in_fp" +.Fa "EC_KEY **val_out" +.Fc +.Ft int +.Fo i2d_ECPrivateKey_fp +.Fa "FILE *out_fp" +.Fa "EC_KEY *val_in" +.Fc +.Ft EC_KEY * +.Fo o2i_ECPublicKey +.Fa "EC_KEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2o_ECPublicKey +.Fa "const EC_KEY *val_in" +.Fa "unsigned char **des_out" +.Fc +.Ft int +.Fo ECPKParameters_print +.Fa "BIO *out_bio" +.Fa "const EC_GROUP *val_in" +.Fa "int indent" +.Fc +.Ft int +.Fo ECPKParameters_print_fp +.Fa "FILE *out_fp" +.Fa "const EC_GROUP *val_in" +.Fa "int indent" +.Fc +.Ft int +.Fo ECParameters_print +.Fa "BIO *out_bio" +.Fa "const EC_KEY *val_in" +.Fc +.Ft int +.Fo ECParameters_print_fp +.Fa "FILE *out_fp" +.Fa "const EC_KEY *val_in" +.Fc +.In openssl/x509.h +.Ft EC_KEY * +.Fo d2i_EC_PUBKEY +.Fa "EC_KEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_EC_PUBKEY +.Fa "EC_KEY *val_in" +.Fa "unsigned char **des_out" +.Fc +.Ft EC_KEY * +.Fo d2i_EC_PUBKEY_bio +.Fa "BIO *in_bio" +.Fa "EC_KEY **val_out" +.Fc +.Ft int +.Fo i2d_EC_PUBKEY_bio +.Fa "BIO *out_bio" +.Fa "EC_KEY *val_in" +.Fc +.Ft EC_KEY * +.Fo d2i_EC_PUBKEY_fp +.Fa "FILE *in_fp" +.Fa "EC_KEY **val_out" +.Fc +.Ft int +.Fo i2d_EC_PUBKEY_fp +.Fa "FILE *out_fp" +.Fa "EC_KEY *val_in" +.Fc +.Sh DESCRIPTION +These functions decode and encode elliptic curve keys and parameters. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_ECPKParameters +and +.Fn i2d_ECPKParameters +decode and encode the parameters of an elliptic curve. +.Fn d2i_ECPKParameters_bio , +.Fn i2d_ECPKParameters_bio , +.Fn d2i_ECPKParameters_fp , +and +.Fn i2d_ECPKParameters_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +These four functions are currently implemented as macros. +.Pp +.Fn d2i_ECParameters +does the same parsing as +.Fn d2i_ECPKParameters +but saves the result in the +.Fa group +field of an +.Vt EC_KEY +structure. +.Pp +.Fn i2d_ECParameters +produces the same output as +.Fn i2d_ECPKParameters +but uses +.Fa val_in->group +for input instead of +.Fa val_in . +.Pp +.Fn ECParameters_dup +allocates and initializes an empty +.Vt EC_KEY +object and copies the EC parameters from +.Fa val_in +to it by calling +.Fn i2d_ECParameters +and +.Fn d2i_ECParameters . +If a private or public key or any flags are present in +.Fa val_in , +they are not copied. +.Pp +.Fn d2i_ECPrivateKey +and +.Fn i2d_ECPrivateKey +decode and encode an EC private key using an ASN.1 +.Vt ECPrivateKey +structure defined in RFC 5915 section 3 and used for the privateKey +field of the ASN.1 +.Vt PrivateKeyInfo +structure defined in RFC 5208 section 5, see +.Xr PKCS8_PRIV_KEY_INFO_new 3 . +.Fn d2i_ECPrivateKey_bio , +.Fn i2d_ECPrivateKey_bio , +.Fn d2i_ECPrivateKey_fp , +and +.Fn i2d_ECPrivateKey_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn o2i_ECPublicKey +and +.Fn i2o_ECPublicKey +decode and encode an EC public key. +In contrast to +.Xr ASN1_item_d2i 3 , +.Fn o2i_ECPublicKey +requires +.Fa val_out , +.Pf * Fa val_out , +and +.Po Pf * Fa val_out Pc Ns -> Ns Fa group +to be +.Pf non- Dv NULL . +.Pp +.Fn ECPKParameters_print +and +.Fn ECPKParameters_print_fp +print human-readable output of the public parameters of the +.Vt EC_GROUP +to +.Fa out_bio +or +.Fa out_fp . +The output lines are indented by +.Fa indent +spaces. +.Pp +.Fn ECParameters_print +and +.Fn ECParameters_print_fp +print the parameter components of +.Fa val_in +to +.Fa out_bio +or +.Fa out_fp . +.Pp +.Fn d2i_EC_PUBKEY +and +.Fn i2d_EC_PUBKEY +decode and encode an EC public key using an ASN.1 +.Vt SubjectPublicKeyInfo +structure defined in RFC 5280 section 4.1 and documented in +.Xr X509_PUBKEY_new 3 . +.Fn d2i_EC_PUBKEY_bio , +.Fn i2d_EC_PUBKEY_bio , +.Fn d2i_EC_PUBKEY_fp , +and +.Fn i2d_EC_PUBKEY_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Sh RETURN VALUES +.Fn d2i_ECPKParameters , +.Fn d2i_ECPKParameters_bio , +and +.Fn d2i_ECPKParameters_fp +return a valid +.Vt EC_GROUP +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_ECParameters , +.Fn ECParameters_dup , +.Fn d2i_ECPrivateKey , +.Fn d2i_ECPrivateKey_bio , +.Fn d2i_ECPrivateKey_fp , +.Fn o2i_ECPublicKey , +.Fn d2i_EC_PUBKEY , +.Fn d2i_EC_PUBKEY_bio , +and +.Fn d2i_EC_PUBKEY_fp +return a valid +.Vt EC_KEY +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_ECPKParameters , +.Fn i2d_ECParameters , +.Fn i2d_ECPrivateKey , +.Fn i2o_ECPublicKey , +and +.Fn i2d_EC_PUBKEY +return the number of bytes successfully encoded or a negative value if +an error occurs. +.Pp +.Fn i2d_ECPKParameters_bio , +.Fn i2d_ECPKParameters_fp , +.Fn i2d_ECPrivateKey_bio , +.Fn i2d_ECPrivateKey_fp , +.Fn ECPKParameters_print , +.Fn ECPKParameters_print_fp , +.Fn ECParameters_print , +.Fn ECParameters_print_fp , +.Fn i2d_EC_PUBKEY_bio , +and +.Fn i2d_EC_PUBKEY_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr EC_GROUP_copy 3 , +.Xr EC_GROUP_new 3 , +.Xr EC_KEY_new 3 , +.Xr EVP_PKEY_set1_EC_KEY 3 , +.Xr PEM_write_ECPrivateKey 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 , +.Xr X509_PUBKEY_new 3 +.Sh STANDARDS +RFC 5915: Elliptic Curve Private Key Structure +.Pp +RFC 5208: Public-Key Cryptography Standards (PKCS) #8: +Private-Key Information Syntax Specification +.Pp +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.1: Basic Certificate Fields +.Sh HISTORY +.Fn d2i_ECPKParameters , +.Fn i2d_ECPKParameters , +.Fn d2i_ECPKParameters_bio , +.Fn i2d_ECPKParameters_bio , +.Fn d2i_ECPKParameters_fP , +.Fn i2d_ECPKParameters_fp , +.Fn d2i_ECParameters , +.Fn i2d_ECParameters , +.Fn ECParameters_dup , +.Fn d2i_ECPrivateKey , +.Fn i2d_ECPrivateKey , +.Fn d2i_ECPrivateKey_bio , +.Fn i2d_ECPrivateKey_bio , +.Fn d2i_ECPrivateKey_fp , +.Fn i2d_ECPrivateKey_fp , +.Fn o2i_ECPublicKey , +.Fn i2o_ECPublicKey , +.Fn ECPKParameters_print , +.Fn ECPKParameters_print_fp , +.Fn ECParameters_print , +.Fn ECParameters_print_fp , +.Fn d2i_EC_PUBKEY , +.Fn i2d_EC_PUBKEY , +.Fn d2i_EC_PUBKEY_bio , +.Fn i2d_EC_PUBKEY_bio , +.Fn d2i_EC_PUBKEY_fp , +and +.Fn i2d_EC_PUBKEY_fp +first appeared in OpenSSL 0.9.8 and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/d2i_ESS_SIGNING_CERT.3 b/Libraries/libressl/man/d2i_ESS_SIGNING_CERT.3 new file mode 100644 index 000000000..c1d61d3b5 --- /dev/null +++ b/Libraries/libressl/man/d2i_ESS_SIGNING_CERT.3 @@ -0,0 +1,118 @@ +.\" $OpenBSD: d2i_ESS_SIGNING_CERT.3,v 1.2 2018/03/23 04:34:23 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt D2I_ESS_SIGNING_CERT 3 +.Os +.Sh NAME +.Nm d2i_ESS_SIGNING_CERT , +.Nm i2d_ESS_SIGNING_CERT , +.Nm d2i_ESS_CERT_ID , +.Nm i2d_ESS_CERT_ID , +.Nm d2i_ESS_ISSUER_SERIAL , +.Nm i2d_ESS_ISSUER_SERIAL +.Nd decode and encode signing certificates for S/MIME +.Sh SYNOPSIS +.In openssl/ts.h +.Ft ESS_SIGNING_CERT * +.Fo d2i_ESS_SIGNING_CERT +.Fa "ESS_SIGNING_CERT **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ESS_SIGNING_CERT +.Fa "const ESS_SIGNING_CERT *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ESS_CERT_ID * +.Fo d2i_ESS_CERT_ID +.Fa "ESS_CERT_ID **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ESS_CERT_ID +.Fa "const ESS_CERT_ID *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft ESS_ISSUER_SERIAL * +.Fo d2i_ESS_ISSUER_SERIAL +.Fa "ESS_ISSUER_SERIAL **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_ESS_ISSUER_SERIAL +.Fa "const ESS_ISSUER_SERIAL *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode signing certificate attribute +structures. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_ESS_SIGNING_CERT +and +.Fn i2d_ESS_SIGNING_CERT +decode and encode an ASN.1 +.Vt SigningCertificate +structure defined in RFC 2634 section 5.4. +.Pp +.Fn d2i_ESS_CERT_ID +and +.Fn i2d_ESS_CERT_ID +decode and encode an ASN.1 +.Vt ESSCertID +structure defined in RFC 2634 section 5.4.1. +.Pp +.Fn d2i_ESS_ISSUER_SERIAL +and +.Fn i2d_ESS_ISSUER_SERIAL +decode and encode an ASN.1 +.Vt IssuerSerial +structure defined in RFC 2634 section 5.4.1. +.Sh RETURN VALUES +.Fn d2i_ESS_SIGNING_CERT , +.Fn d2i_ESS_CERT_ID , +and +.Fn d2i_ESS_ISSUER_SERIAL +return an +.Vt ESS_SIGNING_CERT , +.Vt ESS_CERT_ID , +or +.Vt ESS_ISSUER_SERIAL +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_ESS_SIGNING_CERT , +.Fn i2d_ESS_CERT_ID , +and +.Fn i2d_ESS_ISSUER_SERIAL +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr ESS_SIGNING_CERT_new 3 +.Sh STANDARDS +RFC 2634: Enhanced Security Services for S/MIME, +section 5: Signing Certificate Attribute +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/d2i_GENERAL_NAME.3 b/Libraries/libressl/man/d2i_GENERAL_NAME.3 new file mode 100644 index 000000000..bfdcc6c67 --- /dev/null +++ b/Libraries/libressl/man/d2i_GENERAL_NAME.3 @@ -0,0 +1,160 @@ +.\" $OpenBSD: d2i_GENERAL_NAME.3,v 1.4 2018/03/22 21:08:22 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 22 2018 $ +.Dt D2I_GENERAL_NAME 3 +.Os +.Sh NAME +.Nm d2i_GENERAL_NAME , +.Nm i2d_GENERAL_NAME , +.Nm d2i_GENERAL_NAMES , +.Nm i2d_GENERAL_NAMES , +.Nm d2i_EDIPARTYNAME , +.Nm i2d_EDIPARTYNAME , +.Nm d2i_OTHERNAME , +.Nm i2d_OTHERNAME +.Nd decode and encode names for use in X.509 extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft GENERAL_NAME * +.Fo d2i_GENERAL_NAME +.Fa "GENERAL_NAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_GENERAL_NAME +.Fa "GENERAL_NAME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft GENERAL_NAMES * +.Fo d2i_GENERAL_NAMES +.Fa "GENERAL_NAMES **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_GENERAL_NAMES +.Fa "GENERAL_NAMES *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft EDIPARTYNAME * +.Fo d2i_EDIPARTYNAME +.Fa "EDIPARTYNAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_EDIPARTYNAME +.Fa "EDIPARTYNAME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OTHERNAME * +.Fo d2i_OTHERNAME +.Fa "OTHERNAME **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OTHERNAME +.Fa "OTHERNAME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode names that can be used in X.509 +extensions. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_GENERAL_NAME +and +.Fn i2d_GENERAL_NAME +decode and encode an ASN.1 +.Vt GeneralName +structure defined in RFC 5280 section 4.2.1.6. +.Pp +.Fn d2i_GENERAL_NAMES +and +.Fn i2d_GENERAL_NAMES +decode and encode an ASN.1 +.Vt GeneralNames +structure defined in RFC 5280 section 4.2.1.6. +.Pp +.Fn d2i_EDIPARTYNAME +and +.Fn i2d_EDIPARTYNAME +decode and encode an ASN.1 +.Vt EDIPartyName +structure defined in RFC 5280 section 4.2.1.6. +.Pp +.Fn d2i_OTHERNAME +and +.Fn i2d_OTHERNAME +decode and encode an ASN.1 +.Vt OtherName +structure defined in RFC 5280 section 4.2.1.6. +.Sh RETURN VALUES +.Fn d2i_GENERAL_NAME , +.Fn d2i_GENERAL_NAMES , +.Fn d2i_EDIPARTYNAME , +and +.Fn d2i_OTHERNAME +return a +.Vt GENERAL_NAME , +.Vt GENERAL_NAMES , +.Vt EDIPARTYNAME , +or +.Vt OTHERNAME +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_GENERAL_NAME , +.Fn i2d_GENERAL_NAMES , +.Fn i2d_EDIPARTYNAME , +and +.Fn i2d_OTHERNAME +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr d2i_X509_NAME 3 , +.Xr GENERAL_NAME_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.2: Certificate Extensions +.Sh HISTORY +.Fn d2i_GENERAL_NAME , +.Fn i2d_GENERAL_NAME , +.Fn d2i_GENERAL_NAMES , +and +.Fn i2d_GENERAL_NAMES +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . +.Pp +.Fn d2i_OTHERNAME +and +.Fn i2d_OTHERNAME +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn d2i_EDIPARTYNAME +and +.Fn i2d_EDIPARTYNAME +first appeared in OpenSSL 0.9.7 and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/d2i_OCSP_REQUEST.3 b/Libraries/libressl/man/d2i_OCSP_REQUEST.3 new file mode 100644 index 000000000..07a990556 --- /dev/null +++ b/Libraries/libressl/man/d2i_OCSP_REQUEST.3 @@ -0,0 +1,181 @@ +.\" $OpenBSD: d2i_OCSP_REQUEST.3,v 1.3 2021/03/12 05:18:00 jsg Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 12 2021 $ +.Dt D2I_OCSP_REQUEST 3 +.Os +.Sh NAME +.Nm d2i_OCSP_REQUEST , +.Nm i2d_OCSP_REQUEST , +.Nm d2i_OCSP_SIGNATURE , +.Nm i2d_OCSP_SIGNATURE , +.Nm d2i_OCSP_REQINFO , +.Nm i2d_OCSP_REQINFO , +.Nm d2i_OCSP_ONEREQ , +.Nm i2d_OCSP_ONEREQ , +.Nm d2i_OCSP_CERTID , +.Nm i2d_OCSP_CERTID , +.Nm d2i_OCSP_SERVICELOC , +.Nm i2d_OCSP_SERVICELOC +.Nd decode and encode OCSP requests +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_REQUEST * +.Fo d2i_OCSP_REQUEST +.Fa "OCSP_REQUEST **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_REQUEST +.Fa "OCSP_REQUEST *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_SIGNATURE * +.Fo d2i_OCSP_SIGNATURE +.Fa "OCSP_SIGNATURE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_SIGNATURE +.Fa "OCSP_SIGNATURE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_REQINFO * +.Fo d2i_OCSP_REQINFO +.Fa "OCSP_REQINFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_REQINFO +.Fa "OCSP_REQINFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_ONEREQ * +.Fo d2i_OCSP_ONEREQ +.Fa "OCSP_ONEREQ **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_ONEREQ +.Fa "OCSP_ONEREQ *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_CERTID * +.Fo d2i_OCSP_CERTID +.Fa "OCSP_CERTID **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_CERTID +.Fa "OCSP_CERTID *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_SERVICELOC * +.Fo d2i_OCSP_SERVICELOC +.Fa "OCSP_SERVICELOC **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_SERVICELOC +.Fa "OCSP_SERVICELOC *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode ASN.1 structures used for OCSP +requests. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_OCSP_REQUEST +and +.Fn i2d_OCSP_REQUEST +decode and encode an ASN.1 +.Vt OCSPRequest +structure defined in RFC 6960 section 4.1.1. +.Pp +.Fn d2i_OCSP_SIGNATURE +and +.Fn i2d_OCSP_SIGNATURE +decode and encode an ASN.1 +.Vt Signature +structure defined in RFC 6960 section 4.1.1. +.Pp +.Fn d2i_OCSP_REQINFO +and +.Fn i2d_OCSP_REQINFO +decode and encode an ASN.1 +.Vt TBSRequest +structure defined in RFC 6960 section 4.1.1. +.Pp +.Fn d2i_OCSP_ONEREQ +and +.Fn i2d_OCSP_ONEREQ +decode and encode an ASN.1 +.Vt Request +structure defined in RFC 6960 section 4.1.1. +.Pp +.Fn d2i_OCSP_CERTID +and +.Fn i2d_OCSP_CERTID +decode and encode an ASN.1 +.Vt CertID +structure defined in RFC 6960 section 4.1.1. +.Pp +.Fn d2i_OCSP_SERVICELOC +and +.Fn i2d_OCSP_SERVICELOC +decode and encode an ASN.1 +.Vt ServiceLocator +structure defined in RFC 6960 section 4.4.6. +.Sh RETURN VALUES +.Fn d2i_OCSP_REQUEST , +.Fn d2i_OCSP_SIGNATURE , +.Fn d2i_OCSP_REQINFO , +.Fn d2i_OCSP_ONEREQ , +.Fn d2i_OCSP_CERTID , +and +.Fn d2i_OCSP_SERVICELOC +return an object of the respective type or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_OCSP_REQUEST , +.Fn i2d_OCSP_SIGNATURE , +.Fn i2d_OCSP_REQINFO , +.Fn i2d_OCSP_ONEREQ , +.Fn i2d_OCSP_CERTID , +and +.Fn i2d_OCSP_SERVICELOC +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr OCSP_CERTID_new 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_SERVICELOC_new 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.1: Request Syntax +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/d2i_OCSP_RESPONSE.3 b/Libraries/libressl/man/d2i_OCSP_RESPONSE.3 new file mode 100644 index 000000000..716e85dc6 --- /dev/null +++ b/Libraries/libressl/man/d2i_OCSP_RESPONSE.3 @@ -0,0 +1,248 @@ +.\" $OpenBSD: d2i_OCSP_RESPONSE.3,v 1.4 2021/03/12 05:18:00 jsg Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 12 2021 $ +.Dt D2I_OCSP_RESPONSE 3 +.Os +.Sh NAME +.Nm d2i_OCSP_RESPONSE , +.Nm i2d_OCSP_RESPONSE , +.Nm d2i_OCSP_RESPBYTES , +.Nm i2d_OCSP_RESPBYTES , +.Nm d2i_OCSP_BASICRESP , +.Nm i2d_OCSP_BASICRESP , +.Nm d2i_OCSP_RESPDATA , +.Nm i2d_OCSP_RESPDATA , +.Nm d2i_OCSP_RESPID , +.Nm i2d_OCSP_RESPID , +.Nm d2i_OCSP_SINGLERESP , +.Nm i2d_OCSP_SINGLERESP , +.Nm d2i_OCSP_CERTSTATUS , +.Nm i2d_OCSP_CERTSTATUS , +.Nm d2i_OCSP_REVOKEDINFO , +.Nm i2d_OCSP_REVOKEDINFO , +.Nm d2i_OCSP_CRLID , +.Nm i2d_OCSP_CRLID +.Nd decode and encode OCSP responses +.Sh SYNOPSIS +.In openssl/ocsp.h +.Ft OCSP_RESPONSE * +.Fo d2i_OCSP_RESPONSE +.Fa "OCSP_RESPONSE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_RESPONSE +.Fa "OCSP_RESPONSE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_RESPBYTES * +.Fo d2i_OCSP_RESPBYTES +.Fa "OCSP_RESPBYTES **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_RESPBYTES +.Fa "OCSP_RESPBYTES *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_BASICRESP * +.Fo d2i_OCSP_BASICRESP +.Fa "OCSP_BASICRESP **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_BASICRESP +.Fa "OCSP_BASICRESP *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_RESPDATA * +.Fo d2i_OCSP_RESPDATA +.Fa "OCSP_RESPDATA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_RESPDATA +.Fa "OCSP_RESPDATA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_RESPID * +.Fo d2i_OCSP_RESPID +.Fa "OCSP_RESPID **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_RESPID +.Fa "OCSP_RESPID *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_SINGLERESP * +.Fo d2i_OCSP_SINGLERESP +.Fa "OCSP_SINGLERESP **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_SINGLERESP +.Fa "OCSP_SINGLERESP *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_CERTSTATUS * +.Fo d2i_OCSP_CERTSTATUS +.Fa "OCSP_CERTSTATUS **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_CERTSTATUS +.Fa "OCSP_CERTSTATUS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_REVOKEDINFO * +.Fo d2i_OCSP_REVOKEDINFO +.Fa "OCSP_REVOKEDINFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_REVOKEDINFO +.Fa "OCSP_REVOKEDINFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft OCSP_CRLID * +.Fo d2i_OCSP_CRLID +.Fa "OCSP_CRLID **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_OCSP_CRLID +.Fa "OCSP_CRLID *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode ASN.1 structures used for OCSP +responses. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_OCSP_RESPONSE +and +.Fn i2d_OCSP_RESPONSE +decode and encode an ASN.1 +.Vt OCSPResponse +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_RESPBYTES +and +.Fn i2d_OCSP_RESPBYTES +decode and encode an ASN.1 +.Vt ResponseBytes +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_BASICRESP +and +.Fn i2d_OCSP_BASICRESP +decode and encode an ASN.1 +.Vt BasicOCSPResponse +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_RESPDATA +and +.Fn i2d_OCSP_RESPDATA +decode and encode an ASN.1 +.Vt ResponseData +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_RESPID +and +.Fn i2d_OCSP_RESPID +decode and encode an ASN.1 +.Vt ResponderID +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_SINGLERESP +and +.Fn i2d_OCSP_SINGLERESP +decode and encode an ASN.1 +.Vt SingleResponse +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_CERTSTATUS +and +.Fn i2d_OCSP_CERTSTATUS +decode and encode an ASN.1 +.Vt CertStatus +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_REVOKEDINFO +and +.Fn i2d_OCSP_REVOKEDINFO +decode and encode an ASN.1 +.Vt RevokedInfo +structure defined in RFC 6960 section 4.2.1. +.Pp +.Fn d2i_OCSP_CRLID +and +.Fn i2d_OCSP_CRLID +decode and encode an ASN.1 +.Vt CrlID +structure defined in RFC 6960 section 4.4.2. +.Sh RETURN VALUES +.Fn d2i_OCSP_RESPONSE , +.Fn d2i_OCSP_RESPBYTES , +.Fn d2i_OCSP_BASICRESP , +.Fn d2i_OCSP_RESPDATA , +.Fn d2i_OCSP_RESPID , +.Fn d2i_OCSP_SINGLERESP , +.Fn d2i_OCSP_CERTSTATUS , +.Fn d2i_OCSP_REVOKEDINFO , +and +.Fn d2i_OCSP_CRLID +return an object of the respective type or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_OCSP_RESPONSE , +.Fn i2d_OCSP_RESPBYTES , +.Fn i2d_OCSP_BASICRESP , +.Fn i2d_OCSP_RESPDATA , +.Fn i2d_OCSP_RESPID , +.Fn i2d_OCSP_SINGLERESP , +.Fn i2d_OCSP_CERTSTATUS , +.Fn i2d_OCSP_REVOKEDINFO , +and +.Fn i2d_OCSP_CRLID +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr OCSP_CRLID_new 3 , +.Xr OCSP_REQUEST_new 3 , +.Xr OCSP_RESPONSE_new 3 , +.Xr OCSP_SINGLERESP_new 3 +.Sh STANDARDS +RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate +Status Protocol, section 4.2: Response Syntax +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.7 +and have been available since +.Ox 3.2 . diff --git a/Libraries/libressl/man/d2i_PKCS12.3 b/Libraries/libressl/man/d2i_PKCS12.3 new file mode 100644 index 000000000..55272d1f3 --- /dev/null +++ b/Libraries/libressl/man/d2i_PKCS12.3 @@ -0,0 +1,202 @@ +.\" $OpenBSD: d2i_PKCS12.3,v 1.2 2018/03/21 17:57:48 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt D2I_PKCS12 3 +.Os +.Sh NAME +.Nm d2i_PKCS12 , +.Nm i2d_PKCS12 , +.Nm d2i_PKCS12_bio , +.Nm i2d_PKCS12_bio , +.Nm d2i_PKCS12_fp , +.Nm i2d_PKCS12_fp , +.Nm d2i_PKCS12_MAC_DATA , +.Nm i2d_PKCS12_MAC_DATA , +.Nm d2i_PKCS12_SAFEBAG , +.Nm i2d_PKCS12_SAFEBAG , +.Nm d2i_PKCS12_BAGS , +.Nm i2d_PKCS12_BAGS +.Nd decode and encode PKCS#12 structures +.Sh SYNOPSIS +.In openssl/pkcs12.h +.Ft PKCS12 * +.Fo d2i_PKCS12 +.Fa "PKCS12 **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS12 +.Fa "PKCS12 *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS12 * +.Fo d2i_PKCS12_bio +.Fa "BIO *in_bio" +.Fa "PKCS12 **val_out" +.Fc +.Ft int +.Fo i2d_PKCS12_bio +.Fa "BIO *out_bio" +.Fa "PKCS12 *val_in" +.Fc +.Ft PKCS12 * +.Fo d2i_PKCS12_fp +.Fa "FILE *in_fp" +.Fa "PKCS12 **val_out" +.Fc +.Ft int +.Fo i2d_PKCS12_fp +.Fa "FILE *out_fp" +.Fa "PKCS12 *val_in" +.Fc +.Ft PKCS12_MAC_DATA * +.Fo d2i_PKCS12_MAC_DATA +.Fa "PKCS12_MAC_DATA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS12_MAC_DATA +.Fa "PKCS12_MAC_DATA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS12_SAFEBAG * +.Fo d2i_PKCS12_SAFEBAG +.Fa "PKCS12_SAFEBAG **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS12_SAFEBAG +.Fa "PKCS12_SAFEBAG *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS12_BAGS * +.Fo d2i_PKCS12_BAGS +.Fa "PKCS12_BAGS **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS12_BAGS +.Fa "PKCS12_BAGS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode PKCS#12 structures. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_PKCS12 +and +.Fn i2d_PKCS12 +decode and encode an ASN.1 +.Vt PFX +.Pq personal information exchange +structure defined in RFC 7292 section 4. +.Fn d2i_PKCS12_bio , +.Fn i2d_PKCS12_bio , +.Fn d2i_PKCS12_fp , +and +.Fn i2d_PKCS12_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_PKCS12_MAC_DATA +and +.Fn i2d_PKCS12_MAC_DATA +decode and encode an ASN.1 +.Vt MacData +structure defined in RFC 7292 section 4. +.Pp +.Fn d2i_PKCS12_SAFEBAG +and +.Fn i2d_PKCS12_SAFEBAG +decode and encode an ASN.1 +.Vt SafeBag +structure defined in RFC 7292 section 4.2. +.Pp +.Fn d2i_PKCS12_BAGS +and +.Fn i2d_PKCS12_BAGS +decode and encode the bagValue field of an ASN.1 +.Vt SafeBag +structure. +.Sh RETURN VALUES +.Fn d2i_PKCS12 , +.Fn d2i_PKCS12_bio , +and +.Fn d2i_PKCS12_fp +return a +.Vt PKCS12 +object or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_PKCS12_MAC_DATA , +.Fn d2i_PKCS12_SAFEBAG , +and +.Fn d2i_PKCS12_BAGS +return a +.Vt PKCS12_MAC_DATA , +.Vt PKCS12_SAFEBAG , +or +.Vt PKCS12_BAGS +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_PKCS12 , +.Fn i2d_PKCS12_MAC_DATA , +.Fn i2d_PKCS12_SAFEBAG , +and +.Fn i2d_PKCS12_BAGS +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_PKCS12_bio +and +.Fn i2d_PKCS12_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr PKCS12_create 3 , +.Xr PKCS12_new 3 , +.Xr PKCS12_parse 3 , +.Xr PKCS12_SAFEBAG_new 3 +.Sh STANDARDS +RFC 7292: PKCS #12: Personal Information Exchange Syntax +.Sh HISTORY +.Fn d2i_PKCS12 , +.Fn i2d_PKCS12 , +.Fn d2i_PKCS12_bio , +.Fn i2d_PKCS12_bio , +.Fn d2i_PKCS12_fp , +.Fn i2d_PKCS12_fp , +.Fn d2i_PKCS12_MAC_DATA , +.Fn i2d_PKCS12_MAC_DATA , +.Fn d2i_PKCS12_SAFEBAG , +.Fn i2d_PKCS12_SAFEBAG , +.Fn d2i_PKCS12_BAGS , +and +.Fn i2d_PKCS12_BAGS +first appeared in OpenSSL 0.9.3 and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/d2i_PKCS7.3 b/Libraries/libressl/man/d2i_PKCS7.3 new file mode 100644 index 000000000..e58778746 --- /dev/null +++ b/Libraries/libressl/man/d2i_PKCS7.3 @@ -0,0 +1,341 @@ +.\" $OpenBSD: d2i_PKCS7.3,v 1.7 2023/04/25 18:05:07 tb Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 25 2023 $ +.Dt D2I_PKCS7 3 +.Os +.Sh NAME +.Nm d2i_PKCS7 , +.Nm i2d_PKCS7 , +.Nm d2i_PKCS7_bio , +.Nm i2d_PKCS7_bio , +.Nm d2i_PKCS7_fp , +.Nm i2d_PKCS7_fp , +.Nm d2i_PKCS7_DIGEST , +.Nm i2d_PKCS7_DIGEST , +.Nm d2i_PKCS7_ENCRYPT , +.Nm i2d_PKCS7_ENCRYPT , +.Nm d2i_PKCS7_ENC_CONTENT , +.Nm i2d_PKCS7_ENC_CONTENT , +.Nm d2i_PKCS7_ENVELOPE , +.Nm i2d_PKCS7_ENVELOPE , +.Nm d2i_PKCS7_ISSUER_AND_SERIAL , +.Nm i2d_PKCS7_ISSUER_AND_SERIAL , +.Nm d2i_PKCS7_RECIP_INFO , +.Nm i2d_PKCS7_RECIP_INFO , +.Nm d2i_PKCS7_SIGNED , +.Nm i2d_PKCS7_SIGNED , +.Nm d2i_PKCS7_SIGNER_INFO , +.Nm i2d_PKCS7_SIGNER_INFO , +.Nm d2i_PKCS7_SIGN_ENVELOPE , +.Nm i2d_PKCS7_SIGN_ENVELOPE +.Nd decode and encode PKCS#7 data structures +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft PKCS7 * +.Fo d2i_PKCS7 +.Fa "PKCS7 **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7 +.Fa "PKCS7 *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7 * +.Fo d2i_PKCS7_bio +.Fa "BIO *in_bio" +.Fa "PKCS7 **val_out" +.Fc +.Ft int +.Fo i2d_PKCS7_bio +.Fa "BIO *out_bio" +.Fa "PKCS7 *val_in" +.Fc +.Ft PKCS7 * +.Fo d2i_PKCS7_fp +.Fa "FILE *in_fp" +.Fa "PKCS7 **val_out" +.Fc +.Ft int +.Fo i2d_PKCS7_fp +.Fa "FILE *out_fp" +.Fa "PKCS7 *val_in" +.Fc +.Ft PKCS7_DIGEST * +.Fo d2i_PKCS7_DIGEST +.Fa "PKCS7_DIGEST **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_DIGEST +.Fa "PKCS7_DIGEST *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_ENCRYPT * +.Fo d2i_PKCS7_ENCRYPT +.Fa "PKCS7_ENCRYPT **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_ENCRYPT +.Fa "PKCS7_ENCRYPT *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_ENC_CONTENT * +.Fo d2i_PKCS7_ENC_CONTENT +.Fa "PKCS7_ENC_CONTENT **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_ENC_CONTENT +.Fa "PKCS7_ENC_CONTENT *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_ENVELOPE * +.Fo d2i_PKCS7_ENVELOPE +.Fa "PKCS7_ENVELOPE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_ENVELOPE +.Fa "PKCS7_ENVELOPE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_ISSUER_AND_SERIAL * +.Fo d2i_PKCS7_ISSUER_AND_SERIAL +.Fa "PKCS7_ISSUER_AND_SERIAL **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_ISSUER_AND_SERIAL +.Fa "PKCS7_ISSUER_AND_SERIAL *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_RECIP_INFO * +.Fo d2i_PKCS7_RECIP_INFO +.Fa "PKCS7_RECIP_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_RECIP_INFO +.Fa "PKCS7_RECIP_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_SIGNED * +.Fo d2i_PKCS7_SIGNED +.Fa "PKCS7_SIGNED **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_SIGNED +.Fa "PKCS7_SIGNED *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_SIGNER_INFO * +.Fo d2i_PKCS7_SIGNER_INFO +.Fa "PKCS7_SIGNER_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_SIGNER_INFO +.Fa "PKCS7_SIGNER_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS7_SIGN_ENVELOPE * +.Fo d2i_PKCS7_SIGN_ENVELOPE +.Fa "PKCS7_SIGN_ENVELOPE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS7_SIGN_ENVELOPE +.Fa "PKCS7_SIGN_ENVELOPE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode PKCS#7 data structures. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_PKCS7 +and +.Fn i2d_PKCS7 +decode and encode an ASN.1 +.Vt ContentInfo +structure defined in RFC 2315 section 7. +.Fn d2i_PKCS7_bio , +.Fn i2d_PKCS7_bio , +.Fn d2i_PKCS7_fp , +and +.Fn i2d_PKCS7_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_PKCS7_DIGEST +and +.Fn i2d_PKCS7_DIGEST +decode and encode an ASN.1 +.Vt DigestedData +structure defined in RFC 2315 section 12. +.Pp +.Fn d2i_PKCS7_ENCRYPT +and +.Fn i2d_PKCS7_ENCRYPT +decode and encode an ASN.1 +.Vt EncryptedData +structure defined in RFC 2315 section 13. +.Pp +.Fn d2i_PKCS7_ENC_CONTENT +and +.Fn i2d_PKCS7_ENC_CONTENT +decode and encode an ASN.1 +.Vt EncryptedContentInfo +structure defined in RFC 2315 section 10.1. +.Pp +.Fn d2i_PKCS7_ENVELOPE +and +.Fn i2d_PKCS7_ENVELOPE +decode and encode an ASN.1 +.Vt EnvelopedData +structure defined in RFC 2315 section 10. +.Pp +.Fn d2i_PKCS7_ISSUER_AND_SERIAL +and +.Fn i2d_PKCS7_ISSUER_AND_SERIAL +decode and encode an ASN.1 +.Vt IssuerAndSerialNumber +structure defined in RFC 2315 section 6.7. +.Pp +.Fn d2i_PKCS7_RECIP_INFO +and +.Fn i2d_PKCS7_RECIP_INFO +decode and encode an ASN.1 +.Vt RecipientInfo +structure defined in RFC 2315 section 10.2. +.Pp +.Fn d2i_PKCS7_SIGNED +and +.Fn i2d_PKCS7_SIGNED +decode and encode an ASN.1 +.Vt SignedData +structure defined in RFC 2315 section 9. +.Pp +.Fn d2i_PKCS7_SIGNER_INFO +and +.Fn i2d_PKCS7_SIGNER_INFO +decode and encode an ASN.1 +.Vt SignerInfo +structure defined in RFC 2315 section 9.2. +.Pp +.Fn d2i_PKCS7_SIGN_ENVELOPE +and +.Fn i2d_PKCS7_SIGN_ENVELOPE +decode and encode an ASN.1 +.Vt SignedAndEnvelopedData +structure defined in RFC 2315 section 11. +.Sh RETURN VALUES +.Fn d2i_PKCS7 , +.Fn d2i_PKCS7_bio , +and +.Fn d2i_PKCS7_fp +return a +.Vt PKCS7 +object or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_PKCS7_DIGEST , +.Fn d2i_PKCS7_ENCRYPT , +.Fn d2i_PKCS7_ENC_CONTENT , +.Fn d2i_PKCS7_ENVELOPE , +.Fn d2i_PKCS7_ISSUER_AND_SERIAL , +.Fn d2i_PKCS7_RECIP_INFO , +.Fn d2i_PKCS7_SIGNED , +.Fn d2i_PKCS7_SIGNER_INFO , +and +.Fn d2i_PKCS7_SIGN_ENVELOPE +return an object of the respective type or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_PKCS7 , +.Fn i2d_PKCS7_DIGEST , +.Fn i2d_PKCS7_ENCRYPT , +.Fn i2d_PKCS7_ENC_CONTENT , +.Fn i2d_PKCS7_ENVELOPE , +.Fn i2d_PKCS7_ISSUER_AND_SERIAL , +.Fn i2d_PKCS7_RECIP_INFO , +.Fn i2d_PKCS7_SIGNED , +.Fn i2d_PKCS7_SIGNER_INFO , +and +.Fn i2d_PKCS7_SIGN_ENVELOPE +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_PKCS7_bio +and +.Fn i2d_PKCS7_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr i2d_PKCS7_bio_stream 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PEM_write_PKCS7 3 , +.Xr PKCS7_new 3 , +.Xr SMIME_write_PKCS7 3 +.Sh STANDARDS +RFC 2315: PKCS #7: Cryptographic Message Syntax Version 1.5 +.Sh HISTORY +.Fn d2i_PKCS7 , +.Fn i2d_PKCS7 , +.Fn d2i_PKCS7_bio , +.Fn i2d_PKCS7_bio , +.Fn d2i_PKCS7_fp , +.Fn i2d_PKCS7_fp , +.Fn d2i_PKCS7_DIGEST , +.Fn i2d_PKCS7_DIGEST , +.Fn d2i_PKCS7_ENCRYPT , +.Fn i2d_PKCS7_ENCRYPT , +.Fn d2i_PKCS7_ENC_CONTENT , +.Fn i2d_PKCS7_ENC_CONTENT , +.Fn d2i_PKCS7_ENVELOPE , +.Fn i2d_PKCS7_ENVELOPE , +.Fn d2i_PKCS7_ISSUER_AND_SERIAL , +.Fn i2d_PKCS7_ISSUER_AND_SERIAL , +.Fn d2i_PKCS7_RECIP_INFO , +.Fn i2d_PKCS7_RECIP_INFO , +.Fn d2i_PKCS7_SIGNED , +.Fn i2d_PKCS7_SIGNED , +.Fn d2i_PKCS7_SIGNER_INFO , +.Fn i2d_PKCS7_SIGNER_INFO , +.Fn d2i_PKCS7_SIGN_ENVELOPE , +and +.Fn i2d_PKCS7_SIGN_ENVELOPE +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/d2i_PKCS8PrivateKey_bio.3 b/Libraries/libressl/man/d2i_PKCS8PrivateKey_bio.3 new file mode 100644 index 000000000..58dd989fa --- /dev/null +++ b/Libraries/libressl/man/d2i_PKCS8PrivateKey_bio.3 @@ -0,0 +1,172 @@ +.\" $OpenBSD: d2i_PKCS8PrivateKey_bio.3,v 1.11 2019/06/07 19:28:52 schwarze Exp $ +.\" full merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2002, 2016, 2017 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 7 2019 $ +.Dt D2I_PKCS8PRIVATEKEY_BIO 3 +.Os +.Sh NAME +.Nm d2i_PKCS8PrivateKey_bio , +.Nm d2i_PKCS8PrivateKey_fp , +.Nm i2d_PKCS8PrivateKey_bio , +.Nm i2d_PKCS8PrivateKey_fp , +.Nm i2d_PKCS8PrivateKey_nid_bio , +.Nm i2d_PKCS8PrivateKey_nid_fp +.Nd PKCS#8 format private key functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_PKEY * +.Fo d2i_PKCS8PrivateKey_bio +.Fa "BIO *bp" +.Fa "EVP_PKEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PKCS8PrivateKey_fp +.Fa "FILE *fp" +.Fa "EVP_PKEY **x" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo i2d_PKCS8PrivateKey_bio +.Fa "BIO *bp" +.Fa "EVP_PKEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo i2d_PKCS8PrivateKey_fp +.Fa "FILE *fp" +.Fa "EVP_PKEY *x" +.Fa "const EVP_CIPHER *enc" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo i2d_PKCS8PrivateKey_nid_bio +.Fa "BIO *bp" +.Fa "EVP_PKEY *x" +.Fa "int nid" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Ft int +.Fo i2d_PKCS8PrivateKey_nid_fp +.Fa "FILE *fp" +.Fa "EVP_PKEY *x" +.Fa "int nid" +.Fa "char *kstr" +.Fa "int klen" +.Fa "pem_password_cb *cb" +.Fa "void *u" +.Fc +.Sh DESCRIPTION +The PKCS#8 functions encode and decode private keys in PKCS#8 format +using both PKCS#5 v1.5 and PKCS#5 v2.0 password based encryption +algorithms. +.Pp +Other than the use of DER as opposed to PEM these functions are +identical to the corresponding functions described in +.Xr PEM_read_PrivateKey 3 . +.Pp +These functions are currently the only way to store encrypted private +keys using DER format. +.Pp +Currently all the functions use +.Vt BIO +or +.Vt FILE +pointers. +There are no functions which work directly on memory, +though this can be readily worked around +by converting the buffers to memory BIOs; +see +.Xr BIO_s_mem 3 +for details. +.Sh RETURN VALUES +.Fn d2i_PKCS8PrivateKey_bio +and +.Fn d2i_PKCS8PrivateKey_fp +return a +.Vt EVP_PKEY +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_PKCS8PrivateKey_bio , +.Fn i2d_PKCS8PrivateKey_fp , +.Fn i2d_PKCS8PrivateKey_nid_bio , +and +.Fn i2d_PKCS8PrivateKey_nid_fp +return 1 on success or 0 on error. +.Sh SEE ALSO +.Xr d2i_X509_SIG 3 , +.Xr PEM_write_PKCS8PrivateKey 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.5 +and have been available since +.Ox 2.7 . +.Sh CAVEATS +Do not confuse these functions with +.Xr i2d_PKCS8PrivateKeyInfo_bio 3 +and +.Xr i2d_PKCS8PrivateKeyInfo_fp 3 , +which write out private keys in +.Sy unencrypted +DER format. diff --git a/Libraries/libressl/man/d2i_PKCS8_PRIV_KEY_INFO.3 b/Libraries/libressl/man/d2i_PKCS8_PRIV_KEY_INFO.3 new file mode 100644 index 000000000..1ac0f2c30 --- /dev/null +++ b/Libraries/libressl/man/d2i_PKCS8_PRIV_KEY_INFO.3 @@ -0,0 +1,127 @@ +.\" $OpenBSD: d2i_PKCS8_PRIV_KEY_INFO.3,v 1.3 2018/03/21 21:18:08 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt D2I_PKCS8_PRIV_KEY_INFO 3 +.Os +.Sh NAME +.Nm d2i_PKCS8_PRIV_KEY_INFO , +.Nm i2d_PKCS8_PRIV_KEY_INFO , +.Nm d2i_PKCS8_PRIV_KEY_INFO_bio , +.Nm i2d_PKCS8_PRIV_KEY_INFO_bio , +.Nm d2i_PKCS8_PRIV_KEY_INFO_fp , +.Nm i2d_PKCS8_PRIV_KEY_INFO_fp +.Nd decode and encode PKCS#8 private key +.Sh SYNOPSIS +.In openssl/x509.h +.Ft PKCS8_PRIV_KEY_INFO * +.Fo d2i_PKCS8_PRIV_KEY_INFO +.Fa "PKCS8_PRIV_KEY_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKCS8_PRIV_KEY_INFO +.Fa "PKCS8_PRIV_KEY_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft PKCS8_PRIV_KEY_INFO * +.Fo d2i_PKCS8_PRIV_KEY_INFO_bio +.Fa "BIO *in_bio" +.Fa "PKCS8_PRIV_KEY_INFO **val_out" +.Fc +.Ft int +.Fo i2d_PKCS8_PRIV_KEY_INFO_bio +.Fa "BIO *out_bio" +.Fa "PKCS8_PRIV_KEY_INFO *val_in" +.Fc +.Ft PKCS8_PRIV_KEY_INFO * +.Fo d2i_PKCS8_PRIV_KEY_INFO_fp +.Fa "FILE *in_fp" +.Fa "PKCS8_PRIV_KEY_INFO **val_out" +.Fc +.Ft int +.Fo i2d_PKCS8_PRIV_KEY_INFO_fp +.Fa "BIO *out_fp" +.Fa "PKCS8_PRIV_KEY_INFO *val_in" +.Fc +.Sh DESCRIPTION +.Fn d2i_PKCS8_PRIV_KEY_INFO +and +.Fn i2d_PKCS8_PRIV_KEY_INFO +decode and encode an ASN.1 +.Vt PrivateKeyInfo +structure defined in RFC 5208 section 5. +.Pp +.Fn d2i_PKCS8_PRIV_KEY_INFO_bio , +.Fn i2d_PKCS8_PRIV_KEY_INFO_bio , +.Fn d2i_PKCS8_PRIV_KEY_INFO_fp , +and +.Fn i2d_PKCS8_PRIV_KEY_INFO_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +These functions all use unencrypted DER format. +To store private keys in encrypted form, consider +.Xr d2i_PKCS8PrivateKey_bio 3 +or +.Xr PEM_write_PKCS8PrivateKey 3 . +.Sh RETURN VALUES +.Fn d2i_PKCS8_PRIV_KEY_INFO , +.Fn d2i_PKCS8_PRIV_KEY_INFO_bio , +and +.Fn d2i_PKCS8_PRIV_KEY_INFO_fp +return a +.Vt PKCS8_PRIV_KEY_INFO +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_PKCS8_PRIV_KEY_INFO +returns the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_PKCS8_PRIV_KEY_INFO_bio +and +.Fn i2d_PKCS8_PRIV_KEY_INFO_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr d2i_PKCS8PrivateKey_bio 3 , +.Xr d2i_PrivateKey 3 , +.Xr PEM_write_PKCS8_PRIV_KEY_INFO 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 +.Sh STANDARDS +RFC 5208: PKCS#8: Private-Key Information Syntax Specification +.Sh HISTORY +.Fn d2i_PKCS8_PRIV_KEY_INFO +and +.Fn i2d_PKCS8_PRIV_KEY_INFO +first appeared in OpenSSL 0.9.3. +.Fn d2i_PKCS8_PRIV_KEY_INFO_bio , +.Fn i2d_PKCS8_PRIV_KEY_INFO_bio , +.Fn d2i_PKCS8_PRIV_KEY_INFO_fp , +and +.Fn i2d_PKCS8_PRIV_KEY_INFO_fp +first appeared in OpenSSL 0.9.4. +All these functions have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/d2i_PKEY_USAGE_PERIOD.3 b/Libraries/libressl/man/d2i_PKEY_USAGE_PERIOD.3 new file mode 100644 index 000000000..df8639264 --- /dev/null +++ b/Libraries/libressl/man/d2i_PKEY_USAGE_PERIOD.3 @@ -0,0 +1,74 @@ +.\" $OpenBSD: d2i_PKEY_USAGE_PERIOD.3,v 1.2 2018/03/21 16:09:51 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt D2I_PKEY_USAGE_PERIOD 3 +.Os +.Sh NAME +.Nm d2i_PKEY_USAGE_PERIOD , +.Nm i2d_PKEY_USAGE_PERIOD +.Nd decode and encode X.509 key usage period extensions +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft PKEY_USAGE_PERIOD * +.Fo d2i_PKEY_USAGE_PERIOD +.Fa "PKEY_USAGE_PERIOD **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PKEY_USAGE_PERIOD +.Fa "PKEY_USAGE_PERIOD *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Fn d2i_PKEY_USAGE_PERIOD +and +.Fn i2d_PKEY_USAGE_PERIOD +decode and encode an ASN.1 +.Vt PrivateKeyUsagePeriod +structure defined in RFC 3280 section 4.2.1.4. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Sh RETURN VALUES +.Fn d2i_PKEY_USAGE_PERIOD +returns a +.Vt PKEY_USAGE_PERIOD +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_PKEY_USAGE_PERIOD +returns the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr PKEY_USAGE_PERIOD_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 3280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.2.1.4: Private Key Usage Period +.Pp +RFC 3280 was obsoleted by RFC 5280; see +.Xr PKEY_USAGE_PERIOD_new 3 +for details. +.Sh HISTORY +.Fn d2i_PKEY_USAGE_PERIOD +and +.Fn i2d_PKEY_USAGE_PERIOD +first appeared in OpenSSL 0.9.2b and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/d2i_POLICYINFO.3 b/Libraries/libressl/man/d2i_POLICYINFO.3 new file mode 100644 index 000000000..bae78b17c --- /dev/null +++ b/Libraries/libressl/man/d2i_POLICYINFO.3 @@ -0,0 +1,165 @@ +.\" $OpenBSD: d2i_POLICYINFO.3,v 1.2 2018/03/21 17:57:48 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 21 2018 $ +.Dt D2I_POLICYINFO 3 +.Os +.Sh NAME +.Nm d2i_POLICYINFO , +.Nm i2d_POLICYINFO , +.Nm d2i_CERTIFICATEPOLICIES , +.Nm i2d_CERTIFICATEPOLICIES , +.Nm d2i_POLICYQUALINFO , +.Nm i2d_POLICYQUALINFO , +.Nm d2i_USERNOTICE , +.Nm i2d_USERNOTICE , +.Nm d2i_NOTICEREF , +.Nm i2d_NOTICEREF +.Nd decode and encode X.509 certificate policies +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft POLICYINFO * +.Fo d2i_POLICYINFO +.Fa "POLICYINFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_POLICYINFO +.Fa "POLICYINFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft CERTIFICATEPOLICIES * +.Fo d2i_CERTIFICATEPOLICIES +.Fa "CERTIFICATEPOLICIES **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_CERTIFICATEPOLICIES +.Fa "CERTIFICATEPOLICIES *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft POLICYQUALINFO * +.Fo d2i_POLICYQUALINFO +.Fa "POLICYQUALINFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_POLICYQUALINFO +.Fa "POLICYQUALINFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft USERNOTICE * +.Fo d2i_USERNOTICE +.Fa "USERNOTICE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_USERNOTICE +.Fa "USERNOTICE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft NOTICEREF * +.Fo d2i_NOTICEREF +.Fa "NOTICEREF **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_NOTICEREF +.Fa "NOTICEREF *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode X.509 certificate policies. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_POLICYINFO +and +.Fn i2d_POLICYINFO +decode and encode an ASN.1 +.Vt PolicyInformation +structure defined in RFC 5280 section 4.2.1.4. +.Pp +.Fn d2i_CERTIFICATEPOLICIES +and +.Fn i2d_CERTIFICATEPOLICIES +decode and encode an ASN.1 +.Vt CertificatePolicies +structure defined in RFC 5280 section 4.2.1.4. +.Pp +.Fn d2i_POLICYQUALINFO +and +.Fn i2d_POLICYQUALINFO +decode and encode an ASN.1 +.Vt PolicyQualifierInfo +structure defined in RFC 5280 section 4.2.1.4. +.Pp +.Fn d2i_USERNOTICE +and +.Fn i2d_USERNOTICE +decode and encode an ASN.1 +.Vt UserNotice +structure defined in RFC 5280 section 4.2.1.4. +.Pp +.Fn d2i_NOTICEREF +and +.Fn i2d_NOTICEREF +decode and encode an ASN.1 +.Vt NoticeReference +structure defined in RFC 5280 section 4.2.1.4. +.Sh RETURN VALUES +.Fn d2i_POLICYINFO , +.Fn d2i_CERTIFICATEPOLICIES , +.Fn d2i_POLICYQUALINFO , +.Fn d2i_USERNOTICE , +and +.Fn d2i_NOTICEREF +return a +.Vt POLICYINFO , +.Vt CERTIFICATEPOLICIES , +.Vt POLICYQUALINFO , +.Vt USERNOTICE , +or +.Vt NOTICEREF +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_POLICYINFO , +.Fn i2d_CERTIFICATEPOLICIES , +.Fn i2d_POLICYQUALINFO , +.Fn i2d_USERNOTICE , +and +.Fn i2d_NOTICEREF +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr POLICYINFO_new 3 , +.Xr X509_EXTENSION_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.2.1.4: Certificate Policies +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.3 +and have been available since +.Ox 2.6 . diff --git a/Libraries/libressl/man/d2i_PrivateKey.3 b/Libraries/libressl/man/d2i_PrivateKey.3 new file mode 100644 index 000000000..864541430 --- /dev/null +++ b/Libraries/libressl/man/d2i_PrivateKey.3 @@ -0,0 +1,312 @@ +.\" $OpenBSD: d2i_PrivateKey.3,v 1.10 2021/10/19 12:03:46 schwarze Exp $ +.\" full merge up to: OpenSSL b0edda11 Mar 20 13:00:17 2018 +0000 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Dr. Stephen Henson . +.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 19 2021 $ +.Dt D2I_PRIVATEKEY 3 +.Os +.Sh NAME +.Nm d2i_PrivateKey , +.Nm d2i_AutoPrivateKey , +.Nm d2i_PrivateKey_bio , +.Nm d2i_PrivateKey_fp , +.Nm i2d_PrivateKey , +.Nm i2d_PrivateKey_bio , +.Nm i2d_PrivateKey_fp , +.Nm i2d_PKCS8PrivateKeyInfo_bio , +.Nm i2d_PKCS8PrivateKeyInfo_fp , +.Nm d2i_PublicKey , +.Nm i2d_PublicKey +.Nd decode and encode EVP_PKEY objects +.Sh SYNOPSIS +.In openssl/evp.h +.Ft EVP_PKEY * +.Fo d2i_PrivateKey +.Fa "int type" +.Fa "EVP_PKEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft EVP_PKEY * +.Fo d2i_AutoPrivateKey +.Fa "EVP_PKEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PrivateKey_bio +.Fa "BIO *in_bio" +.Fa "EVP_PKEY **val_out" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PrivateKey_fp +.Fa "FILE *in_fp" +.Fa "EVP_PKEY **val_out" +.Fc +.Ft int +.Fo i2d_PrivateKey +.Fa "EVP_PKEY *val_in" +.Fa "unsigned char **des_out" +.Fc +.Ft int +.Fo i2d_PrivateKey_bio +.Fa "BIO *out_bio" +.Fa "EVP_PKEY *val_in" +.Fc +.Ft int +.Fo i2d_PrivateKey_fp +.Fa "FILE *out_fp" +.Fa "EVP_PKEY *val_in" +.Fc +.Ft int +.Fo i2d_PKCS8PrivateKeyInfo_bio +.Fa "BIO *out_bio" +.Fa "EVP_PKEY *val_in" +.Fc +.Ft int +.Fo i2d_PKCS8PrivateKeyInfo_fp +.Fa "FILE *out_fp" +.Fa "EVP_PKEY *val_in" +.Fc +.Ft EVP_PKEY * +.Fo d2i_PublicKey +.Fa "int type" +.Fa "EVP_PKEY **val_out" +.Fa "const unsigned char **des_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_PublicKey +.Fa "EVP_PKEY *val_in" +.Fa "unsigned char **des_out" +.Fc +.Sh DESCRIPTION +These are algorithm-independent interfaces to decode and encode +private and public keys. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_PrivateKey +decodes a private key using algorithm +.Fa type . +It attempts to use any algorithm specific format or the PKCS#8 unencrypted +.Vt PrivateKeyInfo +format defined in RFC 5208 section 5. +The +.Fa type +parameter should be a public key algorithm constant such as +.Dv EVP_PKEY_RSA . +An error occurs if the decoded key does not match +.Fa type . +.Pp +.Fn d2i_AutoPrivateKey +is similar to +.Fn d2i_PrivateKey +except that it attempts to automatically detect the algorithm. +.Pp +.Fn d2i_PrivateKey_bio +and +.Fn d2i_PrivateKey_fp +are similar to +.Fn d2i_PrivateKey +except that they read from a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn i2d_PrivateKey +encodes +.Fa val_in . +It uses an algorithm specific format or, if none is defined for +that key type, the PKCS#8 unencrypted +.Vt PrivateKeyInfo +format. +.Pp +.Fn i2d_PrivateKey_bio +and +.Fn i2d_PrivateKey_fp +are similar to +.Fn i2d_PrivateKey +except that they write to a +.Vt BIO +or +.Vt FILE +pointer and use a different convention for their return values. +.Pp +.Fn i2d_PKCS8PrivateKeyInfo_bio +and +.Fn i2d_PKCS8PrivateKeyInfo_fp +encode +.Fa val_in +in PKCS#8 unencrypted +.Vt PrivateKeyInfo +format. +They are similar to +.Fn i2d_PrivateKey +except that they don't use any algorithm-specific formats +and that they write to a +.Vt BIO +or +.Vt FILE +pointer rather than to a buffer. +.Pp +All these functions use DER format and unencrypted keys. +Applications wishing to encrypt or decrypt private keys should use other +functions such as +.Xr d2i_PKCS8PrivateKey_bio 3 +instead. +.Pp +If +.Pf * Fa val_out +is not +.Dv NULL +when calling +.Fn d2i_PrivateKey +or +.Fn d2i_AutoPrivateKey +(i.e. an existing structure is being reused) and the key format is +PKCS#8, then +.Pf * Fa val_out +will be freed and replaced on a successful call. +.Pp +.Fn d2i_PublicKey +calls +.Xr d2i_DSAPublicKey 3 , +.Xr o2i_ECPublicKey 3 , +or +.Xr d2i_RSAPublicKey 3 +depending on +.Fa type +and stores the result in the returned +.Vt EVP_PKEY +object. +.Pp +.Fn i2d_PublicKey +calls +.Xr i2d_DSAPublicKey 3 , +.Xr i2o_ECPublicKey 3 , +or +.Xr i2d_RSAPublicKey 3 +depending on the algorithm used by +.Fa val_in . +.Sh RETURN VALUES +.Fn d2i_PrivateKey , +.Fn d2i_AutoPrivateKey , +.Fn d2i_PrivateKey_bio , +.Fn d2i_PrivateKey_fp , +and +.Fn d2i_PublicKey +return a valid +.Vt EVP_PKEY +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_PrivateKey +and +.Fn i2d_PublicKey +return the number of bytes successfully encoded or a negative value if +an error occurs. +.Pp +.Fn i2d_PrivateKey_bio , +.Fn i2d_PrivateKey_fp , +.Fn i2d_PKCS8PrivateKeyInfo_bio , +and +.Fn i2d_PKCS8PrivateKeyInfo_fp +return 1 for success or 0 if an error occurs. +.Pp +For all functions, the error code can be obtained by calling +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr d2i_PKCS8_PRIV_KEY_INFO 3 , +.Xr d2i_PKCS8PrivateKey_bio 3 , +.Xr EVP_PKEY_new 3 , +.Xr EVP_PKEY_type 3 , +.Xr PEM_write_PrivateKey 3 , +.Xr PKCS8_PRIV_KEY_INFO_new 3 +.Sh STANDARDS +RFC 5208: Public-Key Cryptography Standards (PKCS) #8: Private-Key +Information Syntax Specification +.Sh HISTORY +.Fn d2i_PrivateKey , +.Fn i2d_PrivateKey , +.Fn d2i_PublicKey , +and +.Fn i2d_PublicKey +first appeared in SSLeay 0.6.0 and have been available since +.Ox 2.4 . +.Pp +.Fn d2i_AutoPrivateKey , +.Fn d2i_PrivateKey_bio , +.Fn d2i_PrivateKey_fp , +.Fn i2d_PrivateKey_bio , +.Fn i2d_PrivateKey_fp , +.Fn i2d_PKCS8PrivateKeyInfo_bio , +and +.Fn i2d_PKCS8PrivateKeyInfo_fp +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . diff --git a/Libraries/libressl/man/d2i_RSAPublicKey.3 b/Libraries/libressl/man/d2i_RSAPublicKey.3 new file mode 100644 index 000000000..d6c376d84 --- /dev/null +++ b/Libraries/libressl/man/d2i_RSAPublicKey.3 @@ -0,0 +1,389 @@ +.\" $OpenBSD: d2i_RSAPublicKey.3,v 1.13 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL bb9ad09e Jun 6 00:43:05 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller and +.\" Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2003, 2009, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt D2I_RSAPUBLICKEY 3 +.Os +.Sh NAME +.Nm d2i_RSAPublicKey , +.Nm i2d_RSAPublicKey , +.Nm d2i_RSAPrivateKey , +.Nm i2d_RSAPrivateKey , +.Nm d2i_Netscape_RSA , +.Nm i2d_Netscape_RSA , +.Nm d2i_RSA_PSS_PARAMS , +.Nm i2d_RSA_PSS_PARAMS , +.Nm d2i_RSAPublicKey_bio , +.Nm d2i_RSAPublicKey_fp , +.Nm i2d_RSAPublicKey_bio , +.Nm i2d_RSAPublicKey_fp , +.Nm d2i_RSAPrivateKey_bio , +.Nm d2i_RSAPrivateKey_fp , +.Nm i2d_RSAPrivateKey_bio , +.Nm i2d_RSAPrivateKey_fp , +.Nm d2i_RSA_PUBKEY , +.Nm i2d_RSA_PUBKEY , +.Nm d2i_RSA_PUBKEY_bio , +.Nm d2i_RSA_PUBKEY_fp , +.Nm i2d_RSA_PUBKEY_bio , +.Nm i2d_RSA_PUBKEY_fp +.Nd decode and encode RSA keys and parameters +.Sh SYNOPSIS +.In openssl/rsa.h +.Ft RSA * +.Fo d2i_RSAPublicKey +.Fa "RSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_RSAPublicKey +.Fa "RSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft RSA * +.Fo d2i_RSAPrivateKey +.Fa "RSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_RSAPrivateKey +.Fa "RSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft RSA * +.Fo d2i_Netscape_RSA +.Fa "RSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fa "int (*cb)()" +.Fc +.Ft int +.Fo i2d_Netscape_RSA +.Fa "RSA *val_in" +.Fa "unsigned char **der_out" +.Fa "int (*cb)()" +.Fc +.Ft RSA_PSS_PARAMS * +.Fo d2i_RSA_PSS_PARAMS +.Fa "RSA_PSS_PARAMS **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_RSA_PSS_PARAMS +.Fa "RSA_PSS_PARAMS *val_in" +.Fa "unsigned char **der_out" +.Fc +.In openssl/x509.h +.Ft RSA * +.Fo d2i_RSAPublicKey_bio +.Fa "BIO *in_bio" +.Fa "RSA **val_out" +.Fc +.Ft RSA * +.Fo d2i_RSAPublicKey_fp +.Fa "FILE *in_fp" +.Fa "RSA **val_out" +.Fc +.Ft int +.Fo i2d_RSAPublicKey_bio +.Fa "BIO *out_bio" +.Fa "RSA *val_in" +.Fc +.Ft int +.Fo i2d_RSAPublicKey_fp +.Fa "FILE *out_fp" +.Fa "RSA *val_in" +.Fc +.Ft RSA * +.Fo d2i_RSAPrivateKey_bio +.Fa "BIO *in_bio" +.Fa "RSA **val_out" +.Fc +.Ft RSA * +.Fo d2i_RSAPrivateKey_fp +.Fa "FILE *in_fp" +.Fa "RSA **val_out" +.Fc +.Ft int +.Fo i2d_RSAPrivateKey_bio +.Fa "BIO *out_bio" +.Fa "RSA *val_in" +.Fc +.Ft int +.Fo i2d_RSAPrivateKey_fp +.Fa "FILE *out_fp" +.Fa "RSA *val_in" +.Fc +.Ft RSA * +.Fo d2i_RSA_PUBKEY +.Fa "RSA **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_RSA_PUBKEY +.Fa "RSA *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft RSA * +.Fo d2i_RSA_PUBKEY_bio +.Fa "BIO *in_bio" +.Fa "RSA **val_out" +.Fc +.Ft RSA * +.Fo d2i_RSA_PUBKEY_fp +.Fa "FILE *in_fp" +.Fa "RSA **val_out" +.Fc +.Ft int +.Fo i2d_RSA_PUBKEY_bio +.Fa "BIO *out_bio" +.Fa "RSA *val_in" +.Fc +.Ft int +.Fo i2d_RSA_PUBKEY_fp +.Fa "FILE *out_fp" +.Fa "RSA *val_in" +.Fc +.Sh DESCRIPTION +These functions decode and encode RSA private and public keys. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_RSAPublicKey +and +.Fn i2d_RSAPublicKey +decode and encode a PKCS#1 +.Vt RSAPublicKey +structure defined in RFC 8017 appendix A.1.1. +.Fn d2i_RSAPublicKey_bio , +.Fn d2i_RSAPublicKey_fp , +.Fn i2d_RSAPublicKey_bio , +and +.Fn i2d_RSAPublicKey_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_RSAPrivateKey +and +.Fn i2d_RSAPrivateKey +decode and encode a PKCS#1 +.Vt RSAPrivateKey +structure defined in RFC 8017 appendix A.1.2. +The +.Vt RSA +structure passed to the private key encoding functions should have +all the PKCS#1 private key components present. +The data encoded by the private key functions is unencrypted and +therefore offers no private key security. +.Fn d2i_RSAPrivateKey_bio , +.Fn d2i_RSAPrivateKey_fp , +.Fn i2d_RSAPrivateKey_bio , +and +.Fn i2d_RSAPrivateKey_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_Netscape_RSA +and +.Fn i2d_Netscape_RSA +decode and encode an RSA private key in NET format. +These functions are present to provide compatibility with +certain very old software. +The NET format has some severe security weaknesses and should be +avoided if possible. +.Pp +.Fn d2i_RSA_PSS_PARAMS +and +.Fn i2d_RSA_PSS_PARAMS +decode and encode a PKCS#1 +.Vt RSASSA-PSS-params +structure defined in RFC 8017 appendix A.2.3 and documented in +.Xr RSA_PSS_PARAMS_new 3 . +.Pp +.Fn d2i_RSA_PUBKEY +and +.Fn i2d_RSA_PUBKEY +decode and encode an RSA public key using an ASN.1 +.Vt SubjectPublicKeyInfo +structure defined in RFC 5280 section 4.1 and documented in +.Xr X509_PUBKEY_new 3 . +.Fn d2i_RSA_PUBKEY_bio , +.Fn d2i_RSA_PUBKEY_fp , +.Fn i2d_RSA_PUBKEY_bio , +and +.Fn i2d_RSA_PUBKEY_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Sh RETURN VALUES +.Fn d2i_RSAPublicKey , +.Fn d2i_RSAPublicKey_bio , +.Fn d2i_RSAPublicKey_fp , +.Fn d2i_RSAPrivateKey , +.Fn d2i_RSAPrivateKey_bio , +.Fn d2i_RSAPrivateKey_fp , +.Fn d2i_Netscape_RSA , +.Fn d2i_RSA_PUBKEY , +.Fn d2i_RSA_PUBKEY_bio , +and +.Fn d2i_RSA_PUBKEY_fp +return a valid +.Vt RSA +object or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_RSA_PSS_PARAMS +returns a valid +.Vt RSA_PSS_PARAMS +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_RSAPublicKey , +.Fn i2d_RSAPrivateKey , +.Fn i2d_Netscape_RSA , +.Fn i2d_RSA_PSS_PARAMS , +and +.Fn i2d_RSA_PUBKEY +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_RSAPublicKey_bio , +.Fn i2d_RSAPublicKey_fp , +.Fn i2d_RSAPrivateKey_bio , +.Fn i2d_RSAPrivateKey_fp , +.Fn i2d_RSA_PUBKEY_bio , +and +.Fn i2d_RSA_PUBKEY_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr EVP_PKEY_set1_RSA 3 , +.Xr PEM_write_RSAPrivateKey 3 , +.Xr RSA_new 3 , +.Xr RSA_PSS_PARAMS_new 3 , +.Xr X509_PUBKEY_new 3 +.Sh STANDARDS +RFC 8017: PKCS #1: RSA Cryptography Specifications +.Pp +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 4.1: Basic Certificate Fields +.Sh HISTORY +.Fn d2i_RSAPublicKey , +.Fn i2d_RSAPublicKey , +.Fn d2i_RSAPrivateKey , +.Fn i2d_RSAPrivateKey , +.Fn d2i_RSAPrivateKey_fp , +.Fn i2d_RSAPrivateKey_fp , +.Fn d2i_Netscape_RSA , +and +.Fn i2d_Netscape_RSA +first appeared in SSLeay 0.5.1. +.Fn d2i_RSAPrivateKey_bio +and +.Fn i2d_RSAPrivateKey_bio +first appeared in SSLeay 0.6.0. +.Fn d2i_RSAPublicKey_bio , +.Fn d2i_RSAPublicKey_fp , +.Fn i2d_RSAPublicKey_bio , +and +.Fn i2d_RSAPublicKey_fp +first appeared in SSLeay 0.8.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn d2i_RSA_PUBKEY , +.Fn i2d_RSA_PUBKEY , +.Fn d2i_RSA_PUBKEY_bio , +.Fn d2i_RSA_PUBKEY_fp , +.Fn i2d_RSA_PUBKEY_bio , +and +.Fn i2d_RSA_PUBKEY_fp +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn d2i_RSA_PSS_PARAMS +and +.Fn i2d_RSA_PSS_PARAMS +first appeared in OpenSSL 1.0.1 and have been available since +.Ox 5.3 . diff --git a/Libraries/libressl/man/d2i_SSL_SESSION.3 b/Libraries/libressl/man/d2i_SSL_SESSION.3 new file mode 100644 index 000000000..7a2bc529a --- /dev/null +++ b/Libraries/libressl/man/d2i_SSL_SESSION.3 @@ -0,0 +1,181 @@ +.\" $OpenBSD: d2i_SSL_SESSION.3,v 1.7 2019/06/08 15:25:43 schwarze Exp $ +.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 +.\" +.\" This file was written by Lutz Jaenicke . +.\" Copyright (c) 2001, 2005, 2014 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: June 8 2019 $ +.Dt D2I_SSL_SESSION 3 +.Os +.Sh NAME +.Nm d2i_SSL_SESSION , +.Nm i2d_SSL_SESSION +.Nd convert SSL_SESSION object from/to ASN1 representation +.Sh SYNOPSIS +.In openssl/ssl.h +.Ft SSL_SESSION * +.Fn d2i_SSL_SESSION "SSL_SESSION **a" "const unsigned char **pp" "long length" +.Ft int +.Fn i2d_SSL_SESSION "SSL_SESSION *in" "unsigned char **pp" +.Sh DESCRIPTION +.Fn d2i_SSL_SESSION +transforms the external ASN1 representation of an SSL/TLS session, +stored as binary data at location +.Fa pp +with length +.Fa length , +into +an +.Vt SSL_SESSION +object. +.Pp +.Fn i2d_SSL_SESSION +transforms the +.Vt SSL_SESSION +object +.Fa in +into the ASN1 representation and stores it into the memory location pointed to +by +.Fa pp . +The length of the resulting ASN1 representation is returned. +If +.Fa pp +is the +.Dv NULL +pointer, only the length is calculated and returned. +.Pp +The +.Vt SSL_SESSION +object is built from several +.Xr malloc 3 Ns +-ed parts; it can therefore not be moved, copied or stored directly. +In order to store session data on disk or into a database, +it must be transformed into a binary ASN1 representation. +.Pp +When using +.Fn d2i_SSL_SESSION , +the +.Vt SSL_SESSION +object is automatically allocated. +The reference count is 1, so that the session must be explicitly removed using +.Xr SSL_SESSION_free 3 , +unless the +.Vt SSL_SESSION +object is completely taken over, when being called inside the +.Fn get_session_cb , +see +.Xr SSL_CTX_sess_set_get_cb 3 . +.Pp +.Vt SSL_SESSION +objects keep internal link information about the session cache list when being +inserted into one +.Vt SSL_CTX +object's session cache. +One +.Vt SSL_SESSION +object, regardless of its reference count, must therefore only be used with one +.Vt SSL_CTX +object (and the +.Vt SSL +objects created from this +.Vt SSL_CTX +object). +.Pp +When using +.Fn i2d_SSL_SESSION , +the memory location pointed to by +.Fa pp +must be large enough to hold the binary representation of the session. +There is no known limit on the size of the created ASN1 representation, +so call +.Fn i2d_SSL_SESSION +first with +.Fa pp Ns = Ns Dv NULL +to obtain the encoded size, before allocating the required amount of memory and +calling +.Fn i2d_SSL_SESSION +again. +Note that this will advance the value contained in +.Fa *pp +so it is necessary to save a copy of the original allocation. +For example: +.Bd -literal -offset indent +char *p, *pp; +int elen, len; + +elen = i2d_SSL_SESSION(sess, NULL); +p = pp = malloc(elen); +if (p != NULL) { + len = i2d_SSL_SESSION(sess, &pp); + assert(elen == len); + assert(p + len == pp); +} +.Ed +.Sh RETURN VALUES +.Fn d2i_SSL_SESSION +returns a pointer to the newly allocated +.Vt SSL_SESSION +object. +In case of failure a +.Dv NULL +pointer is returned and the error message can be retrieved from the error +stack. +.Pp +.Fn i2d_SSL_SESSION +returns the size of the ASN1 representation in bytes. +When the session is not valid, 0 is returned and no operation is performed. +.Sh SEE ALSO +.Xr d2i_X509 3 , +.Xr ssl 3 , +.Xr SSL_CTX_sess_set_get_cb 3 , +.Xr SSL_SESSION_free 3 +.Sh HISTORY +.Fn d2i_SSL_SESSION +and +.Fn i2d_SSL_SESSION +first appeared in SSLeay 0.5.2 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/d2i_TS_REQ.3 b/Libraries/libressl/man/d2i_TS_REQ.3 new file mode 100644 index 000000000..9f7c860fa --- /dev/null +++ b/Libraries/libressl/man/d2i_TS_REQ.3 @@ -0,0 +1,333 @@ +.\" $OpenBSD: d2i_TS_REQ.3,v 1.2 2018/03/23 04:34:23 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 23 2018 $ +.Dt D2I_TS_REQ 3 +.Os +.Sh NAME +.Nm d2i_TS_REQ , +.Nm i2d_TS_REQ , +.Nm d2i_TS_REQ_bio , +.Nm i2d_TS_REQ_bio , +.Nm d2i_TS_REQ_fp , +.Nm i2d_TS_REQ_fp , +.Nm d2i_TS_RESP , +.Nm i2d_TS_RESP , +.Nm d2i_TS_RESP_bio , +.Nm i2d_TS_RESP_bio , +.Nm d2i_TS_RESP_fp , +.Nm i2d_TS_RESP_fp , +.Nm d2i_TS_STATUS_INFO , +.Nm i2d_TS_STATUS_INFO , +.Nm d2i_TS_TST_INFO , +.Nm i2d_TS_TST_INFO , +.Nm d2i_TS_TST_INFO_bio , +.Nm i2d_TS_TST_INFO_bio , +.Nm d2i_TS_TST_INFO_fp , +.Nm i2d_TS_TST_INFO_fp , +.Nm d2i_TS_ACCURACY , +.Nm i2d_TS_ACCURACY , +.Nm d2i_TS_MSG_IMPRINT , +.Nm i2d_TS_MSG_IMPRINT , +.Nm d2i_TS_MSG_IMPRINT_bio , +.Nm i2d_TS_MSG_IMPRINT_bio , +.Nm d2i_TS_MSG_IMPRINT_fp , +.Nm i2d_TS_MSG_IMPRINT_fp +.Nd decode and encode X.509 time-stamp protocol structures +.Sh SYNOPSIS +.In openssl/ts.h +.Ft TS_REQ * +.Fo d2i_TS_REQ +.Fa "TS_REQ **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_TS_REQ +.Fa "const TS_REQ *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft TS_REQ * +.Fo d2i_TS_REQ_bio +.Fa "BIO *in_bio" +.Fa "TS_REQ **val_out" +.Fc +.Ft int +.Fo i2d_TS_REQ_bio +.Fa "BIO *out_bio" +.Fa "TS_REQ *val_in" +.Fc +.Ft TS_REQ * +.Fo d2i_TS_REQ_fp +.Fa "FILE *in_fp" +.Fa "TS_REQ **val_out" +.Fc +.Ft int +.Fo i2d_TS_REQ_fp +.Fa "FILE *out_fp" +.Fa "TS_REQ *val_in" +.Fc +.Ft TS_RESP * +.Fo d2i_TS_RESP +.Fa "TS_RESP **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_TS_RESP +.Fa "const TS_RESP *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft TS_RESP * +.Fo d2i_TS_RESP_bio +.Fa "BIO *in_bio" +.Fa "TS_RESP **val_out" +.Fc +.Ft int +.Fo i2d_TS_RESP_bio +.Fa "BIO *out_bio" +.Fa "TS_RESP *val_in" +.Fc +.Ft TS_RESP * +.Fo d2i_TS_RESP_fp +.Fa "FILE *in_fp" +.Fa "TS_RESP **val_out" +.Fc +.Ft int +.Fo i2d_TS_RESP_fp +.Fa "FILE *out_fp" +.Fa "TS_RESP *val_in" +.Fc +.Ft TS_STATUS_INFO * +.Fo d2i_TS_STATUS_INFO +.Fa "TS_STATUS_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_TS_STATUS_INFO +.Fa "const TS_STATUS_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft TS_TST_INFO * +.Fo d2i_TS_TST_INFO +.Fa "TS_TST_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_TS_TST_INFO +.Fa "const TS_TST_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft TS_TST_INFO * +.Fo d2i_TS_TST_INFO_bio +.Fa "BIO *in_bio" +.Fa "TS_TST_INFO **val_out" +.Fc +.Ft int +.Fo i2d_TS_TST_INFO_bio +.Fa "BIO *out_bio" +.Fa "TS_TST_INFO *val_in" +.Fc +.Ft TS_TST_INFO * +.Fo d2i_TS_TST_INFO_fp +.Fa "FILE *in_fp" +.Fa "TS_TST_INFO **val_out" +.Fc +.Ft int +.Fo i2d_TS_TST_INFO_fp +.Fa "FILE *out_fp" +.Fa "TS_TST_INFO *val_in" +.Fc +.Ft TS_ACCURACY * +.Fo d2i_TS_ACCURACY +.Fa "TS_ACCURACY **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_TS_ACCURACY +.Fa "const TS_ACCURACY *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft TS_MSG_IMPRINT * +.Fo d2i_TS_MSG_IMPRINT +.Fa "TS_MSG_IMPRINT **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_TS_MSG_IMPRINT +.Fa "const TS_MSG_IMPRINT *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft TS_MSG_IMPRINT * +.Fo d2i_TS_MSG_IMPRINT_bio +.Fa "BIO *in_bio" +.Fa "TS_MSG_IMPRINT **val_out" +.Fc +.Ft int +.Fo i2d_TS_MSG_IMPRINT_bio +.Fa "BIO *out_bio" +.Fa "TS_MSG_IMPRINT *val_in" +.Fc +.Ft TS_MSG_IMPRINT * +.Fo d2i_TS_MSG_IMPRINT_fp +.Fa "FILE *in_fp" +.Fa "TS_MSG_IMPRINT **val_out" +.Fc +.Ft int +.Fo i2d_TS_MSG_IMPRINT_fp +.Fa "FILE *out_fp" +.Fa "TS_MSG_IMPRINT *val_in" +.Fc +.Sh DESCRIPTION +These functions decode and encode X.509 structures used for the +time-stamp protocol. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_TS_REQ +and +.Fn i2d_TS_REQ +decode and encode an ASN.1 +.Vt TimeStampReq +structure defined in RFC 3161 section 2.4.1. +.Fn d2i_TS_REQ_bio , +.Fn i2d_TS_REQ_bio , +.Fn d2i_TS_REQ_fp , +and +.Fn i2d_TS_REQ_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_TS_RESP +and +.Fn i2d_TS_RESP +decode and encode an ASN.1 +.Vt TimeStampResp +structure defined in RFC 3161 section 2.4.2. +.Fn d2i_TS_RESP_bio , +.Fn i2d_TS_RESP_bio , +.Fn d2i_TS_RESP_fp , +and +.Fn i2d_TS_RESP_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_TS_STATUS_INFO +and +.Fn i2d_TS_STATUS_INFO +decode and encode an ASN.1 +.Vt PKIStatusInfo +structure defined in RFC 3161 section 2.4.2. +.Pp +.Fn d2i_TS_TST_INFO +and +.Fn i2d_TS_TST_INFO +decode and encode an ASN.1 +.Vt TSTInfo +structure defined in RFC 3161 section 2.4.2. +.Fn d2i_TS_TST_INFO_bio , +.Fn i2d_TS_TST_INFO_bio , +.Fn d2i_TS_TST_INFO_fp , +and +.Fn i2d_TS_TST_INFO_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_TS_ACCURACY +and +.Fn i2d_TS_ACCURACY +decode and encode an ASN.1 +.Vt Accuracy +structure defined in RFC 3161 section 2.4.2. +.Pp +.Fn d2i_TS_MSG_IMPRINT +and +.Fn i2d_TS_MSG_IMPRINT +decode and encode an ASN.1 +.Vt MessageImprint +structure defined in RFC 3161 section 2.4.1. +.Fn d2i_TS_MSG_IMPRINT_bio , +.Fn i2d_TS_MSG_IMPRINT_bio , +.Fn d2i_TS_MSG_IMPRINT_fp , +and +.Fn i2d_TS_MSG_IMPRINT_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Sh RETURN VALUES +.Fn d2i_TS_REQ , +.Fn d2i_TS_REQ_bio , +.Fn d2i_TS_REQ_fp , +.Fn d2i_TS_RESP , +.Fn d2i_TS_RESP_bio , +.Fn d2i_TS_RESP_fp , +.Fn d2i_TS_STATUS_INFO , +.Fn d2i_TS_TST_INFO , +.Fn d2i_TS_TST_INFO_bio , +.Fn d2i_TS_TST_INFO_fp , +.Fn d2i_TS_ACCURACY , +.Fn d2i_TS_MSG_IMPRINT , +.Fn d2i_TS_MSG_IMPRINT_bio , +and +.Fn d2i_TS_MSG_IMPRINT_fp +return an object of the respective type or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_TS_REQ , +.Fn i2d_TS_RESP , +.Fn i2d_TS_STATUS_INFO , +.Fn i2d_TS_TST_INFO , +.Fn i2d_TS_ACCURACY , +and +.Fn i2d_TS_MSG_IMPRINT +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_TS_REQ_bio , +.Fn i2d_TS_REQ_fp , +.Fn i2d_TS_RESP_bio , +.Fn i2d_TS_RESP_fp , +.Fn i2d_TS_TST_INFO_bio , +.Fn i2d_TS_TST_INFO_fp , +.Fn i2d_TS_MSG_IMPRINT_bio , +and +.Fn i2d_TS_MSG_IMPRINT_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr TS_REQ_new 3 +.Sh STANDARDS +RFC 3161: Internet X.509 Public Key Infrastructure Time-Stamp Protocol +.Sh HISTORY +These functions first appeared in OpenSSL 1.0.0 +and have been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/d2i_X509.3 b/Libraries/libressl/man/d2i_X509.3 new file mode 100644 index 000000000..6102e49e0 --- /dev/null +++ b/Libraries/libressl/man/d2i_X509.3 @@ -0,0 +1,362 @@ +.\" $OpenBSD: d2i_X509.3,v 1.11 2021/10/27 10:35:43 schwarze Exp $ +.\" OpenSSL d2i_X509.pod checked up to: +.\" 256989ce4 Jun 19 15:00:32 2020 +0200 +.\" OpenSSL i2d_re_X509_tbs.pod checked up to: +.\" 61f805c1 Jan 16 01:01:46 2018 +0800 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original files were written by Dr. Stephen Henson , +.\" Emilia Kasper , Viktor Dukhovni , +.\" and Rich Salz . +.\" Copyright (c) 2002, 2014, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: October 27 2021 $ +.Dt D2I_X509 3 +.Os +.Sh NAME +.Nm d2i_X509 , +.Nm i2d_X509 , +.Nm d2i_X509_bio , +.Nm d2i_X509_fp , +.Nm i2d_X509_bio , +.Nm i2d_X509_fp , +.Nm d2i_X509_AUX , +.Nm i2d_X509_AUX , +.Nm d2i_X509_CERT_AUX , +.Nm i2d_X509_CERT_AUX , +.Nm d2i_X509_CINF , +.Nm i2d_X509_CINF , +.Nm d2i_X509_VAL , +.Nm i2d_X509_VAL , +.Nm i2d_re_X509_tbs , +.Nm i2d_re_X509_CRL_tbs , +.Nm i2d_re_X509_REQ_tbs +.Nd decode and encode X.509 certificates +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509 * +.Fo d2i_X509 +.Fa "X509 **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509 +.Fa "X509 *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509 * +.Fo d2i_X509_bio +.Fa "BIO *in_bio" +.Fa "X509 **val_out" +.Fc +.Ft X509 * +.Fo d2i_X509_fp +.Fa "FILE *in_fp" +.Fa "X509 **val_out" +.Fc +.Ft int +.Fo i2d_X509_bio +.Fa "BIO *out_bio" +.Fa "X509 *val_in" +.Fc +.Ft int +.Fo i2d_X509_fp +.Fa "FILE *out_fp" +.Fa "X509 *val_in" +.Fc +.Ft X509 * +.Fo d2i_X509_AUX +.Fa "X509 **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_AUX +.Fa "X509 *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_CERT_AUX * +.Fo d2i_X509_CERT_AUX +.Fa "X509_CERT_AUX **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_CERT_AUX +.Fa "X509_CERT_AUX *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_CINF * +.Fo d2i_X509_CINF +.Fa "X509_CINF **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_CINF +.Fa "X509_CINF *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_VAL * +.Fo d2i_X509_VAL +.Fa "X509_VAL **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_VAL +.Fa "X509_VAL *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft int +.Fo i2d_re_X509_tbs +.Fa "X509 *x" +.Fa "unsigned char **out" +.Fc +.Ft int +.Fo i2d_re_X509_CRL_tbs +.Fa "X509_CRL *crl" +.Fa "unsigned char **pp" +.Fc +.Ft int +.Fo i2d_re_X509_REQ_tbs +.Fa "X509_REQ *req" +.Fa "unsigned char **pp" +.Fc +.Sh DESCRIPTION +These functions decode and encode X.509 certificates +and some of their substructures. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_X509 +and +.Fn i2d_X509 +decode and encode an ASN.1 +.Vt Certificate +structure defined in RFC 5280 section 4.1. +.Pp +.Fn d2i_X509_bio , +.Fn d2i_X509_fp , +.Fn i2d_X509_bio , +and +.Fn i2d_X509_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_X509_AUX +is similar to +.Fn d2i_X509 , +but the input is expected to consist of an X.509 certificate followed +by auxiliary trust information. +This is used by the PEM routines to read TRUSTED CERTIFICATE objects. +This function should not be called on untrusted input. +.Pp +.Fn i2d_X509_AUX +is similar to +.Fn i2d_X509 , +but the encoded output contains both the certificate and any auxiliary +trust information. +This is used by the PEM routines to write TRUSTED CERTIFICATE objects. +Note that this is a non-standard OpenSSL-specific data format. +.Pp +.Fn d2i_X509_CERT_AUX +and +.Fn i2d_X509_CERT_AUX +decode and encode optional non-standard auxiliary data appended to +a certificate, for example friendly alias names and trust data. +.Pp +.Fn d2i_X509_CINF +and +.Fn i2d_X509_CINF +decode and encode an ASN.1 +.Vt TBSCertificate +structure defined in RFC 5280 section 4.1. +.Pp +.Fn d2i_X509_VAL +and +.Fn i2d_X509_VAL +decode and encode an ASN.1 +.Vt Validity +structure defined in RFC 5280 section 4.1. +.Pp +.Fn i2d_re_X509_tbs +is similar to +.Fn i2d_X509 , +except it encodes only the TBSCertificate portion of the certificate. +.Fn i2d_re_X509_CRL_tbs +and +.Fn i2d_re_X509_REQ_tbs +are analogous for CRL and certificate request, respectively. +The "re" in +.Fn i2d_re_X509_tbs +stands for "re-encode", and ensures that a fresh encoding is generated +in case the object has been modified after creation. +.Pp +The encoding of the TBSCertificate portion of a certificate is cached in +the +.Vt X509 +structure internally to improve encoding performance and to ensure +certificate signatures are verified correctly in some certificates with +broken (non-DER) encodings. +.Pp +If, after modification, the +.Vt X509 +object is re-signed with +.Xr X509_sign 3 , +the encoding is automatically renewed. +Otherwise, the encoding of the TBSCertificate portion of the +.Vt X509 +can be manually renewed by calling +.Fn i2d_re_X509_tbs . +.Sh RETURN VALUES +.Fn d2i_X509 , +.Fn d2i_X509_bio , +.Fn d2i_X509_fp , +and +.Fn d2i_X509_AUX +return a valid +.Vt X509 +structure or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_X509_CERT_AUX , +.Fn d2i_X509_CINF , +and +.Fn d2i_X509_VAL +return an +.Vt X509_CERT_AUX , +.Vt X509_CINF , +or +.Vt X509_VAL +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509 , +.Fn i2d_X509_AUX , +.Fn i2d_X509_CERT_AUX , +.Fn i2d_X509_CINF , +and +.Fn i2d_X509_VAL +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_X509_bio +and +.Fn i2d_X509_fp +return 1 for success or 0 if an error occurs. +.Pp +.Fn i2d_re_X509_tbs , +.Fn i2d_re_X509_CRL_tbs , +and +.Fn i2d_re_X509_REQ_tbs +return the number of bytes successfully encoded or 0 if an error occurs. +.Pp +For all functions, the error code can be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr X509_CINF_new 3 , +.Xr X509_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn d2i_X509 , +.Fn i2d_X509 , +.Fn d2i_X509_fp , +.Fn i2d_X509_fp , +.Fn d2i_X509_CINF , +.Fn i2d_X509_CINF , +.Fn d2i_X509_VAL , +and +.Fn i2d_X509_VAL +first appeared in SSLeay 0.5.1. +.Fn d2i_X509_bio +and +.Fn i2d_X509_bio +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn d2i_X509_AUX , +.Fn i2d_X509_AUX , +.Fn d2i_X509_CERT_AUX , +and +.Fn i2d_X509_CERT_AUX +first appeared in OpenSSL 0.9.5 and have been available since +.Ox 2.7 . +.Pp +.Fn i2d_re_X509_tbs , +.Fn i2d_re_X509_CRL_tbs , +and +.Fn i2d_re_X509_REQ_tbs +first appeared in OpenSSL 1.1.0 and have been available since +.Ox 7.1 . diff --git a/Libraries/libressl/man/d2i_X509_ALGOR.3 b/Libraries/libressl/man/d2i_X509_ALGOR.3 new file mode 100644 index 000000000..7c53d5ae6 --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_ALGOR.3 @@ -0,0 +1,89 @@ +.\" $OpenBSD: d2i_X509_ALGOR.3,v 1.10 2021/11/03 15:02:14 schwarze Exp $ +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 3 2021 $ +.Dt D2I_X509_ALGOR 3 +.Os +.Sh NAME +.Nm d2i_X509_ALGOR , +.Nm i2d_X509_ALGOR , +.Nm d2i_X509_ALGORS , +.Nm i2d_X509_ALGORS +.Nd decode and encode algorithm identifiers +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_ALGOR * +.Fo d2i_X509_ALGOR +.Fa "X509_ALGOR **val_out" +.Fa "unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_ALGOR +.Fa "X509_ALGOR *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_ALGORS * +.Fo d2i_X509_ALGORS +.Fa "X509_ALGORS **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_ALGORS +.Fa "X509_ALGORS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Fn d2i_X509_ALGOR +and +.Fn i2d_X509_ALGOR +decode and encode an ASN.1 +.Vt AlgorithmIdentifier +structure defined in RFC 5280 section 4.1.1.2. +.Pp +.Fn d2i_X509_ALGORS +and +.Fn i2d_X509_ALGORS +decode and encode an ASN.1 sequence of +.Vt AlgorithmIdentifier +structures. +The data type +.Vt X509_ALGORS +is defined as +.Vt STACK_OF(X509_ALGOR) . +.Pp +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr STACK_OF 3 , +.Xr X509_ALGOR_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn d2i_X509_ALGOR +and +.Fn i2d_X509_ALGOR +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn d2i_X509_ALGORS +and +.Fn i2d_X509_ALGORS +first appeared in OpenSSL 0.9.8h and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/d2i_X509_ATTRIBUTE.3 b/Libraries/libressl/man/d2i_X509_ATTRIBUTE.3 new file mode 100644 index 000000000..6b070e5e5 --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_ATTRIBUTE.3 @@ -0,0 +1,76 @@ +.\" $OpenBSD: d2i_X509_ATTRIBUTE.3,v 1.3 2018/03/27 17:35:50 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt D2I_X509_ATTRIBUTE 3 +.Os +.Sh NAME +.Nm d2i_X509_ATTRIBUTE , +.Nm i2d_X509_ATTRIBUTE +.\" In the following line, "X.501" and "Attribute" are not typos. +.\" The "Attribute" type is defined in X.501, not in X.509. +.\" The type in called "Attribute" with capital "A", not "attribute". +.Nd decode and encode generic X.501 Attribute +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_ATTRIBUTE * +.Fo d2i_X509_ATTRIBUTE +.Fa "X509_ATTRIBUTE **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_ATTRIBUTE +.Fa "X509_ATTRIBUTE *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Fn d2i_X509_ATTRIBUTE +and +.Fn i2d_X509_ATTRIBUTE +decode and encode a generic ASN.1 +.Vt Attribute +structure defined in X.501 section 8.2. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Sh RETURN VALUES +.Fn d2i_X509_ATTRIBUTE +returns an +.Vt X509_ATTRIBUTE +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509_ATTRIBUTE +returns the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr d2i_PKCS12 3 , +.Xr d2i_PKCS8_PRIV_KEY_INFO 3 , +.Xr d2i_X509_EXTENSION 3 , +.Xr d2i_X509_REQ 3 , +.Xr X509_ATTRIBUTE_new 3 +.Sh STANDARDS +ITU-T Recommendation X.501, also known as ISO/IEC 9594-2: Information +Technology Open Systems Interconnection The Directory: Models, +section 8.2: Overall structure +.Sh HISTORY +.Fn d2i_X509_ATTRIBUTE +and +.Fn i2d_X509_ATTRIBUTE +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/d2i_X509_CRL.3 b/Libraries/libressl/man/d2i_X509_CRL.3 new file mode 100644 index 000000000..a0a19b4f5 --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_CRL.3 @@ -0,0 +1,158 @@ +.\" $OpenBSD: d2i_X509_CRL.3,v 1.8 2021/10/30 16:20:35 schwarze Exp $ +.\" +.\" Copyright (c) 2016, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 30 2021 $ +.Dt D2I_X509_CRL 3 +.Os +.Sh NAME +.Nm d2i_X509_CRL , +.Nm i2d_X509_CRL , +.Nm d2i_X509_CRL_bio , +.Nm d2i_X509_CRL_fp , +.Nm i2d_X509_CRL_bio , +.Nm i2d_X509_CRL_fp , +.Nm d2i_X509_CRL_INFO , +.Nm i2d_X509_CRL_INFO , +.Nm d2i_X509_REVOKED , +.Nm i2d_X509_REVOKED +.Nd decode and encode X.509 certificate revocation lists +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_CRL * +.Fo d2i_X509_CRL +.Fa "X509_CRL **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_CRL +.Fa "X509_CRL *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_CRL * +.Fo d2i_X509_CRL_bio +.Fa "BIO *in_bio" +.Fa "X509_CRL **der_out" +.Fc +.Ft X509_CRL * +.Fo d2i_X509_CRL_fp +.Fa "FILE *in_fp" +.Fa "X509_CRL **der_out" +.Fc +.Ft int +.Fo i2d_X509_CRL_bio +.Fa "BIO *out_bio" +.Fa "X509_CRL *der_in" +.Fc +.Ft int +.Fo i2d_X509_CRL_fp +.Fa "FILE *out_fp" +.Fa "X509_CRL *der_in" +.Fc +.Ft X509_CRL_INFO * +.Fo d2i_X509_CRL_INFO +.Fa "X509_CRL_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_CRL_INFO +.Fa "X509_CRL_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_REVOKED * +.Fo d2i_X509_REVOKED +.Fa "X509_REVOKED **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_REVOKED +.Fa "X509_REVOKED *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode X.509 certificate revocation lists. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_X509_CRL +and +.Fn i2d_X509_CRL +decode and encode an ASN.1 +.Vt CertificateList +structure defined in RFC 5280 section 5.1. +.Pp +If +.Xr X509_CRL_set_default_method 3 +is in effect and the +.Fn crl_init +callback is not +.Dv NULL , +that callback is invoked at the end of +.Fn d2i_X509_CRL . +.Pp +.Fn d2i_X509_CRL_bio , +.Fn d2i_X509_CRL_fp , +.Fn i2d_X509_CRL_bio , +and +.Fn i2d_X509_CRL_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_X509_CRL_INFO +and +.Fn i2d_X509_CRL_INFO +decode and encode an ASN.1 +.Vt TBSCertList +structure defined in RFC 5280 section 5.1. +.Pp +.Fn d2i_X509_REVOKED +and +.Fn i2d_X509_REVOKED +decode and encode an ASN.1 structure representing one element of +the revokedCertificates field of the ASN.1 +.Vt TBSCertList +structure. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr X509_CRL_METHOD_new 3 , +.Xr X509_CRL_new 3 , +.Xr X509_REVOKED_new 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile, +section 5: CRL and CRL Extensions Profile +.Sh HISTORY +.Fn d2i_X509_CRL , +.Fn i2d_X509_CRL , +.Fn d2i_X509_CRL_fp , +.Fn i2d_X509_CRL_fp , +.Fn d2i_X509_CRL_INFO , +.Fn i2d_X509_CRL_INFO , +.Fn d2i_X509_REVOKED , +and +.Fn i2d_X509_REVOKED +first appeared in SSLeay 0.5.1. +.Fn d2i_X509_CRL_bio +and +.Fn i2d_X509_CRL_bio +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/d2i_X509_EXTENSION.3 b/Libraries/libressl/man/d2i_X509_EXTENSION.3 new file mode 100644 index 000000000..46a680c1b --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_EXTENSION.3 @@ -0,0 +1,104 @@ +.\" $OpenBSD: d2i_X509_EXTENSION.3,v 1.4 2018/03/27 17:35:50 schwarze Exp $ +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt D2I_X509_EXTENSION 3 +.Os +.Sh NAME +.Nm d2i_X509_EXTENSION , +.Nm i2d_X509_EXTENSION , +.Nm d2i_X509_EXTENSIONS , +.Nm i2d_X509_EXTENSIONS +.\" In the next line, the capital "E" is not a typo. +.\" The ASN.1 structure is called "Extensions", not "extensions". +.Nd decode and encode X.509 Extensions +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_EXTENSION * +.Fo d2i_X509_EXTENSION +.Fa "X509_EXTENSION **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_EXTENSION +.Fa "X509_EXTENSION *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_EXTENSIONS * +.Fo d2i_X509_EXTENSIONS +.Fa "X509_EXTENSIONS **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_EXTENSIONS +.Fa "X509_EXTENSIONS *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Fn d2i_X509_EXTENSION +and +.Fn i2d_X509_EXTENSION +decode and encode an ASN.1 +.Vt Extension +structure defined in RFC 5280 section 4.1. +.Pp +.Fn d2i_X509_EXTENSIONS +and +.Fn i2d_X509_EXTENSIONS +decode and encode an ASN.1 +.Vt Extensions +structure defined in RFC 5280 section 4.1, +which is a SEQUENCE OF +.Vt Extension . +.Sh RETURN VALUES +.Fn d2i_X509_EXTENSION +and +.Fn d2i_X509_EXTENSIONS +return an +.Vt X509_EXTENSION +or +.Vt X509_EXTENSIONS +object, respectively, or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509_EXTENSION +and +.Fn i2d_X509_EXTENSIONS +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr X509_EXTENSION_new 3 , +.Xr X509V3_get_d2i 3 , +.Xr X509v3_get_ext_by_NID 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Sh HISTORY +.Fn d2i_X509_EXTENSION +and +.Fn i2d_X509_EXTENSION +first appeared in SSLeay 0.6.2 and have been available since +.Ox 2.4 . +.Pp +.Fn d2i_X509_EXTENSIONS +and +.Fn i2d_X509_EXTENSIONS +first appeared in OpenSSL 0.9.8h and have been available since +.Ox 4.5 . diff --git a/Libraries/libressl/man/d2i_X509_NAME.3 b/Libraries/libressl/man/d2i_X509_NAME.3 new file mode 100644 index 000000000..97b18e9cd --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_NAME.3 @@ -0,0 +1,213 @@ +.\" $OpenBSD: d2i_X509_NAME.3,v 1.17 2021/12/11 17:25:10 jmc Exp $ +.\" checked up to: +.\" OpenSSL crypto/d2i_X509_NAME 4692340e Jun 7 15:49:08 2016 -0400 and +.\" OpenSSL man3/X509_NAME_get0_der 99d63d46 Oct 26 13:56:48 2016 -0400 +.\" +.\" Copyright (c) 2016, 2018 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 11 2021 $ +.Dt D2I_X509_NAME 3 +.Os +.Sh NAME +.Nm d2i_X509_NAME , +.Nm i2d_X509_NAME , +.Nm X509_NAME_get0_der , +.Nm X509_NAME_dup , +.Nm X509_NAME_set , +.Nm d2i_X509_NAME_ENTRY , +.Nm i2d_X509_NAME_ENTRY , +.Nm X509_NAME_ENTRY_dup +.\" In the following line, "X.501" and "Name" are not typos. +.\" The "Name" type is defined in X.501, not in X.509. +.\" The type is called "Name" with capital "N", not "name". +.Nd decode and encode X.501 Name objects +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_NAME * +.Fo d2i_X509_NAME +.Fa "X509_NAME **val_out" +.Fa "unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_NAME +.Fa "X509_NAME *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft int +.Fo X509_NAME_get0_der +.Fa "X509_NAME *val_in" +.Fa "const unsigned char **der_out" +.Fa "size_t *out_len" +.Fc +.Ft X509_NAME * +.Fo X509_NAME_dup +.Fa "X509_NAME *val_in" +.Fc +.Ft int +.Fo X509_NAME_set +.Fa "X509_NAME **val_out" +.Fa "X509_NAME *val_in" +.Fc +.Ft X509_NAME_ENTRY * +.Fo d2i_X509_NAME_ENTRY +.Fa "X509_NAME_ENTRY **val_out" +.Fa "unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_NAME_ENTRY +.Fa "X509_NAME_ENTRY *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_NAME_ENTRY * +.Fo X509_NAME_ENTRY_dup +.Fa "X509_NAME_ENTRY *val_in" +.Fc +.Sh DESCRIPTION +These functions decode and encode X.501 +.Vt Name +objects using DER format. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_X509_NAME +and +.Fn i2d_X509_NAME +decode and encode an ASN.1 +.Vt Name +structure defined in RFC 5280 section 4.1.2.4. +.Pp +.Fn X509_NAME_get0_der +is a variant of +.Fn i2d_X509_NAME +that does not copy the encoded output but instead returns a pointer +to the internally cached DER-encoded version of the name. +Also, it does not return the length of the output in bytes, +but instead stores it in +.Fa out_len . +If the cached encoded form happens to be out of date, both functions +update it before copying it or returning a pointer to it. +.Pp +.Fn X509_NAME_dup +copies +.Fa val_in +by calling +.Fn i2d_X509_NAME +and +.Fn d2i_X509_NAME . +.Pp +.Fn X509_NAME_set +makes sure that +.Pf * Fa val_out +contains the same data as +.Fa val_in +after the call, except that it fails if +.Fa val_in +is +.Dv NULL . +If +.Pf * Fa val_out +is the same pointer as +.Fa val_in , +the function succeeds without changing anything. +Otherwise, it copies +.Fa val_in +using +.Fn X509_NAME_dup , +and in case of success, it frees +.Pf * Fa val_out +and sets it to a pointer to the new object. +When the function fails, it never changes anything. +In any case, +.Fa val_in +remains valid and may or may not be the same pointer as +.Pf * Fa val_out +after the call. +.Pp +.Fn d2i_X509_NAME_ENTRY +and +.Fn i2d_X509_NAME_ENTRY +decode and encode an ASN.1 +.Vt RelativeDistinguishedName +structure defined in RFC 5280 section 4.1.2.4. +.Pp +.Fn X509_NAME_ENTRY_dup +copies +.Fa val_in +by calling +.Fn i2d_X509_NAME_ENTRY +and +.Fn d2i_X509_NAME_ENTRY . +.Sh RETURN VALUES +.Fn d2i_X509_NAME +and +.Fn X509_NAME_dup +return the new +.Vt X509_NAME +object or +.Dv NULL +if an error occurs. +.Pp +.Fn X509_NAME_set +and +.Fn X509_NAME_get0_der +return 1 on success or 0 if an error occurs. +.Pp +.Fn d2i_X509_NAME_ENTRY +and +.Fn X509_NAME_ENTRY_dup +return the new +.Vt X509_NAME_ENTRY +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509_NAME +and +.Fn i2d_X509_NAME_ENTRY +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr X509_NAME_ENTRY_new 3 , +.Xr X509_NAME_new 3 , +.Xr X509_NAME_print_ex 3 +.Sh STANDARDS +RFC 5280: Internet X.509 Public Key Infrastructure Certificate and +Certificate Revocation List (CRL) Profile +.Pp +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER). +.Sh HISTORY +.Fn X509_NAME_dup +first appeared in SSLeay 0.4.4. +.Fn d2i_X509_NAME , +.Fn i2d_X509_NAME , +.Fn d2i_X509_NAME_ENTRY , +.Fn i2d_X509_NAME_ENTRY , +and +.Fn X509_NAME_ENTRY_dup +first appeared in SSLeay 0.5.1. +.Fn X509_NAME_set +first appeared in SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn X509_NAME_get0_der +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 6.3 . diff --git a/Libraries/libressl/man/d2i_X509_REQ.3 b/Libraries/libressl/man/d2i_X509_REQ.3 new file mode 100644 index 000000000..95785a2d2 --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_REQ.3 @@ -0,0 +1,151 @@ +.\" $OpenBSD: d2i_X509_REQ.3,v 1.7 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL bb9ad09e Jun 6 00:43:05 2016 -0400 +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt D2I_X509_REQ 3 +.Os +.Sh NAME +.Nm d2i_X509_REQ , +.Nm i2d_X509_REQ , +.Nm d2i_X509_REQ_bio , +.Nm d2i_X509_REQ_fp , +.Nm i2d_X509_REQ_bio , +.Nm i2d_X509_REQ_fp , +.Nm d2i_X509_REQ_INFO , +.Nm i2d_X509_REQ_INFO +.Nd decode and encode PKCS#10 certification requests +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_REQ * +.Fo d2i_X509_REQ +.Fa "X509_REQ **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_REQ +.Fa "X509_REQ *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_REQ * +.Fo d2i_X509_REQ_bio +.Fa "BIO *in_bio" +.Fa "X509_REQ **val_out" +.Fc +.Ft X509_REQ * +.Fo d2i_X509_REQ_fp +.Fa "FILE *in_fp" +.Fa "X509_REQ **val_out" +.Fc +.Ft int +.Fo i2d_X509_REQ_bio +.Fa "BIO *out_bio" +.Fa "X509_REQ *val_in" +.Fc +.Ft int +.Fo i2d_X509_REQ_fp +.Fa "FILE *out_fp" +.Fa "X509_REQ *val_in" +.Fc +.Ft X509_REQ_INFO * +.Fo d2i_X509_REQ_INFO +.Fa "X509_REQ_INFO **val_out" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_REQ_INFO +.Fa "X509_REQ_INFO *val_in" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +These functions decode and encode PKCS#10 certification requests. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_X509_REQ +and +.Fn i2d_X509_REQ +decode and encode an ASN.1 +.Vt CertificationRequest +structure defined in RFC 2986 section 4.2. +.Fn d2i_X509_REQ_bio , +.Fn d2i_X509_REQ_fp , +.Fn i2d_X509_REQ_bio , +and +.Fn i2d_X509_REQ_fp +are similar except that they decode or encode using a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn d2i_X509_REQ_INFO +and +.Fn i2d_X509_REQ_INFO +decode and encode an ASN.1 +.Vt CertificationRequestInfo +structure defined in RFC 2986 section 4.1. +.Sh RETURN VALUES +.Fn d2i_X509_REQ , +.Fn d2i_X509_REQ_bio , +and +.Fn d2i_X509_REQ_fp +return an +.Vt X509_REQ +object or +.Dv NULL +if an error occurs. +.Pp +.Fn d2i_X509_REQ_INFO +returns an +.Vt X509_REQ_INFO +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509_REQ +and +.Fn i2d_X509_REQ_INFO +return the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_X509_REQ_bio +and +.Fn i2d_X509_REQ_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr PEM_read_X509_REQ 3 , +.Xr X509_REQ_new 3 +.Sh STANDARDS +RFC 2986: PKCS #10: Certification Request Syntax Specification +.Sh HISTORY +.Fn d2i_X509_REQ , +.Fn i2d_X509_REQ , +.Fn d2i_X509_REQ_fp , +.Fn i2d_X509_REQ_fp , +.Fn d2i_X509_REQ_INFO , +and +.Fn i2d_X509_REQ_INFO +first appeared in SSLeay 0.5.1. +.Fn d2i_X509_REQ_bio +and +.Fn i2d_X509_REQ_bio +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . diff --git a/Libraries/libressl/man/d2i_X509_SIG.3 b/Libraries/libressl/man/d2i_X509_SIG.3 new file mode 100644 index 000000000..fddeed79b --- /dev/null +++ b/Libraries/libressl/man/d2i_X509_SIG.3 @@ -0,0 +1,159 @@ +.\" $OpenBSD: d2i_X509_SIG.3,v 1.9 2018/03/27 17:35:50 schwarze Exp $ +.\" OpenSSL 9b86974e Aug 17 15:21:33 2015 -0400 +.\" +.\" Copyright (c) 2016 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 27 2018 $ +.Dt D2I_X509_SIG 3 +.Os +.Sh NAME +.Nm d2i_X509_SIG , +.Nm i2d_X509_SIG , +.Nm d2i_PKCS8_bio , +.Nm i2d_PKCS8_bio , +.Nm d2i_PKCS8_fp , +.Nm i2d_PKCS8_fp +.\" In the next line, the number "7" is not a typo. +.\" These functions are misnamed. +.Nd decode and encode PKCS#7 digest information +.Sh SYNOPSIS +.In openssl/x509.h +.Ft X509_SIG * +.Fo d2i_X509_SIG +.Fa "X509_SIG **val_out" +.Fa "unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_X509_SIG +.Fa "X509_SIG *val_in" +.Fa "unsigned char **der_out" +.Fc +.Ft X509_SIG * +.Fo d2i_PKCS8_bio +.Fa "BIO *in_bio" +.Fa "X509_SIG **val_out" +.Fc +.Ft int +.Fo i2d_PKCS8_bio +.Fa "BIO *out_bio" +.Fa "X509_SIG *val_in" +.Fc +.Ft X509_SIG * +.Fo d2i_PKCS8_fp +.Fa "FILE *in_fp" +.Fa "X509_SIG **val_out" +.Fc +.Ft int +.Fo i2d_PKCS8_fp +.Fa "FILE *out_fp" +.Fa "X509_SIG *val_in" +.Fc +.Sh DESCRIPTION +.Fn d2i_X509_SIG +and +.Fn i2d_X509_SIG +decode and encode an ASN.1 +.Vt DigestInfo +structure defined in RFC 2315 section 9.4 +and equivalently in RFC 8017 section 9.2. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +.Pp +.Fn d2i_PKCS8_bio +and +.Fn d2i_PKCS8_fp +are similar to +.Fn d2i_X509_SIG +except that they read from a +.Vt BIO +or +.Vt FILE +pointer. +.Pp +.Fn i2d_PKCS8_bio +and +.Fn i2d_PKCS8_fp +are similar to +.Fn i2d_X509_SIG +except that they write to a +.Vt BIO +or +.Vt FILE +pointer. +.Sh RETURN VALUES +.Fn d2i_X509_SIG , +.Fn d2i_PKCS8_bio , +and +.Fn d2i_PKCS8_fp +return a +.Vt X509_SIG +object or +.Dv NULL +if an error occurs. +.Pp +.Fn i2d_X509_SIG +returns the number of bytes successfully encoded or a negative value +if an error occurs. +.Pp +.Fn i2d_PKCS8_bio +and +.Fn i2d_PKCS8_fp +return 1 for success or 0 if an error occurs. +.Sh SEE ALSO +.Xr ASN1_item_d2i 3 , +.Xr PKCS7_new 3 , +.Xr RSA_sign 3 , +.Xr X509_SIG_new 3 +.Sh STANDARDS +RFC 2315: PKCS #7: Cryptographic Message Syntax, +section 9: Signed-data content type +.Pp +RFC 8017: PKCS #1: RSA Cryptography Specifications, +section 9: Encoding Methods for Signatures +.Sh HISTORY +.Fn d2i_X509_SIG +and +.Fn i2d_X509_SIG +first appeared in SSLeay 0.5.1 and have been available since +.Ox 2.4 . +.Pp +.Fn d2i_PKCS8_bio , +.Fn i2d_PKCS8_bio , +.Fn d2i_PKCS8_fp , +and +.Fn i2d_PKCS8_fp +first appeared in OpenSSL 0.9.4 and have been available since +.Ox 2.6 . +.Sh BUGS +.Fn d2i_PKCS8_bio , +.Fn i2d_PKCS8_bio , +.Fn d2i_PKCS8_fp , +and +.Fn i2d_PKCS8_fp +are severely misnamed and should have been called +.Dq d2i_X509_SIG_bio +and so on. +.Pp +Or arguably, the +.Vt X509_SIG +object is misnamed itself, considering that it represents +.Vt DigestInfo +from PKCS#7 and PKCS#1. +Then again, calling it +.Dq PKCS8 +instead clearly isn't an improvement. +.Pp +Either way, these names just don't fit. diff --git a/Libraries/libressl/man/des_read_pw.3 b/Libraries/libressl/man/des_read_pw.3 new file mode 100644 index 000000000..41f8553de --- /dev/null +++ b/Libraries/libressl/man/des_read_pw.3 @@ -0,0 +1,203 @@ +.\" $OpenBSD: des_read_pw.3,v 1.11 2023/09/10 13:58:46 schwarze Exp $ +.\" full merge up to: OpenSSL doc/crypto/des.pod +.\" 53934822 Jun 9 16:39:19 2016 -0400 +.\" +.\" This file is a derived work. +.\" The changes are covered by the following Copyright and license: +.\" +.\" Copyright (c) 2023 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" The original file was written by Ulf Moeller . +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 10 2023 $ +.Dt DES_READ_PW 3 +.Os +.Sh NAME +.Nm EVP_read_pw_string , +.Nm EVP_read_pw_string_min , +.Nm EVP_set_pw_prompt , +.Nm EVP_get_pw_prompt +.Nd compatibility user interface functions +.Sh SYNOPSIS +.In openssl/evp.h +.Ft int +.Fo EVP_read_pw_string +.Fa "char *buf" +.Fa "int length" +.Fa "const char *prompt" +.Fa "int verify" +.Fc +.Ft int +.Fo EVP_read_pw_string_min +.Fa "char *buf" +.Fa "int min_length" +.Fa "int length" +.Fa "const char *prompt" +.Fa "int verify" +.Fc +.Ft void +.Fo EVP_set_pw_prompt +.Fa "const char *default_prompt" +.Fc +.Ft char * +.Fn EVP_get_pw_prompt void +.Sh DESCRIPTION +These functions are deprecated. +Use +.Xr UI_UTIL_read_pw 3 +instead. +.Pp +.Fn EVP_read_pw_string +writes the +.Fa prompt +to +.Pa /dev/tty , +or, if that could not be opened, to standard output, turns echo off, +and reads an input string from +.Pa /dev/tty , +or, if that could not be opened, from standard input. +The string is returned in +.Fa buf , +which must have space for at least +.Fa length +bytes. +If the +.Fa length +argument exceeds +.Dv BUFSIZ , +.Dv BUFSIZ +is used instead. +If +.Fa verify +is set, the user is asked for the password twice and unless the two +copies match, an error is returned. +.Pp +.Fn EVP_read_pw_string_min +additionally checks that the password is at least +.Fa min_length +bytes long. +.Pp +.Fn EVP_set_pw_prompt +sets a default prompt to a copy of +.Fa default_prompt , +or clears the default prompt if the +.Fa default_prompt +argument is +.Dv NULL +or an empty string. +If the +.Fa default_prompt +argument is longer than 79 bytes, +the copy is silently truncated to a string length of 79 bytes. +.Pp +As long as a default prompt is set, +.Fn EVP_read_pw_string +and +.Fn EVP_read_pw_string_min +can be called with a +.Fa prompt +argument of +.Dv NULL , +in which case the default prompt is used instead. +.Sh RETURN VALUES +.Fn EVP_read_pw_string +and +.Fn EVP_read_pw_string_min +return 0 on success or a negative value on failure. +.Pp +They return \-1 if +.Fa length +is less than or equal to zero or on memory allocation failure. +They return \-1 or \-2 if the internal call to +.Xr UI_process 3 +fails. +.Pp +In addition, +.Fa EVP_read_pw_string_min +returns \-1 if +.Fa min_length +is negative, if +.Fa length +is less than or equal to +.Fa min_length , +or if the user entered a password shorter than +.Fa min_length . +.Pp +.Fn EVP_get_pw_prompt +returns an internal pointer to static memory containing the default prompt, or +.Dv NULL +if no default prompt is set. +.Sh SEE ALSO +.Xr UI_new 3 , +.Xr UI_UTIL_read_pw 3 +.Sh HISTORY +.Fn EVP_read_pw_string +first appeared in SSLeay 0.5.1 and +.Fn EVP_set_pw_prompt +and +.Fn EVP_get_pw_prompt +in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn EVP_read_pw_string_min +first appeared in OpenSSL 1.0.0 +and has been available since +.Ox 4.9 . diff --git a/Libraries/libressl/man/evp.3 b/Libraries/libressl/man/evp.3 new file mode 100644 index 000000000..b29f76480 --- /dev/null +++ b/Libraries/libressl/man/evp.3 @@ -0,0 +1,269 @@ +.\" $OpenBSD: evp.3,v 1.24 2023/09/09 14:39:09 schwarze Exp $ +.\" full merge up to: OpenSSL man7/evp 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" This file was written by Ulf Moeller , +.\" Matt Caswell , Geoff Thorpe , +.\" and Dr. Stephen Henson . +.\" Copyright (c) 2000, 2002, 2006, 2013, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 9 2023 $ +.Dt EVP 3 +.Os +.Sh NAME +.Nm evp +.Nd high-level cryptographic functions +.Sh SYNOPSIS +.In openssl/evp.h +.Sh DESCRIPTION +The EVP library provides a high-level interface to cryptographic +functions. +.Pp +.Xr EVP_SealInit 3 +and +.Xr EVP_OpenInit 3 +provide public key encryption and decryption to implement digital +"envelopes". +.Pp +The +.Xr EVP_DigestSignInit 3 +and +.Xr EVP_DigestVerifyInit 3 +functions implement digital signatures and Message Authentication Codes +(MACs). +Also see the older +.Xr EVP_SignInit 3 +and +.Xr EVP_VerifyInit 3 +functions. +.Pp +Symmetric encryption is available with the +.Xr EVP_EncryptInit 3 +functions. +The +.Xr EVP_DigestInit 3 +functions provide message digests. +.Pp +Authenticated encryption with additional data (AEAD) is available with +the +.Xr EVP_AEAD_CTX_init 3 +functions. +.Pp +The +.Fn EVP_PKEY_* +functions provide a high-level interface to asymmetric algorithms. +To create a new +.Vt EVP_PKEY , +see +.Xr EVP_PKEY_new 3 . +.Vt EVP_PKEY Ns s +can be associated with a private key of a particular algorithm +by using the functions described in the +.Xr EVP_PKEY_set1_RSA 3 +page, or new keys can be generated using +.Xr EVP_PKEY_keygen 3 . +.Vt EVP_PKEY Ns s +can be compared using +.Xr EVP_PKEY_cmp 3 +or printed using +.Xr EVP_PKEY_print_private 3 . +.Pp +The +.Fn EVP_PKEY_* +functions support the full range of asymmetric algorithm operations: +.Bl -bullet +.It +For key agreement, see +.Xr EVP_PKEY_derive 3 . +.It +For signing and verifying, see +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_verify 3 , +and +.Xr EVP_PKEY_verify_recover 3 . +However, note that these functions do not perform a digest of the +data to be signed. +Therefore, normally you would use the +.Xr EVP_DigestSignInit 3 +functions for this purpose. +.It +For encryption and decryption see +.Xr EVP_PKEY_encrypt 3 +and +.Xr EVP_PKEY_decrypt 3 , +respectively. +However, note that these functions perform encryption and decryption only. +As public key encryption is an expensive operation, normally you +would wrap an encrypted message in a digital envelope using the +.Xr EVP_SealInit 3 +and +.Xr EVP_OpenInit 3 +functions. +.El +.Pp +The +.Xr EVP_BytesToKey 3 +function provides some limited support for password based encryption. +Careful selection of the parameters will provide a PKCS#5 PBKDF1 +compatible implementation. +However, new applications should typically not use this (preferring, for +example, PBKDF2 from PCKS#5). +.Pp +The +.Xr EVP_EncodeInit 3 +family of functions provides base64 encoding and decoding. +.Pp +All the symmetric algorithms (ciphers), digests and asymmetric +algorithms (public key algorithms) can be replaced by +.Vt ENGINE +modules providing alternative implementations; see +.Xr ENGINE_register_RSA 3 +and the related manual pages for more information. +If +.Vt ENGINE +implementations of ciphers or digests are registered as defaults, +then the various EVP functions will automatically use those +implementations in preference to built in software implementations. +.Pp +Although low-level algorithm specific functions exist for many +algorithms, their use is discouraged. +They cannot be used with an +.Vt ENGINE , +and +.Vt ENGINE +versions of new algorithms cannot be accessed using the low-level +functions. +Using them also makes code harder to adapt to new algorithms, some +options are not cleanly supported at the low level, and some +operations are more efficient using the high-level interfaces. +.Sh SEE ALSO +.Xr ASN1_item_digest 3 , +.Xr ASN1_item_sign 3 , +.Xr BIO_f_cipher 3 , +.Xr BIO_f_md 3 , +.Xr CMAC_Init 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_sign 3 , +.Xr crypto 3 , +.Xr d2i_PKCS8PrivateKey_bio 3 , +.Xr d2i_PrivateKey 3 , +.Xr ENGINE_get_cipher 3 , +.Xr ENGINE_register_RSA 3 , +.Xr EVP_add_cipher 3 , +.Xr EVP_AEAD_CTX_init 3 , +.Xr EVP_aes_128_cbc 3 , +.Xr EVP_BytesToKey 3 , +.Xr EVP_camellia_128_cbc 3 , +.Xr EVP_chacha20 3 , +.Xr EVP_CIPHER_CTX_ctrl 3 , +.Xr EVP_CIPHER_CTX_get_cipher_data 3 , +.Xr EVP_CIPHER_CTX_set_flags 3 , +.Xr EVP_CIPHER_do_all 3 , +.Xr EVP_CIPHER_meth_new 3 , +.Xr EVP_CIPHER_nid 3 , +.Xr EVP_des_cbc 3 , +.Xr EVP_DigestInit 3 , +.Xr EVP_DigestSignInit 3 , +.Xr EVP_DigestVerifyInit 3 , +.Xr EVP_EncodeInit 3 , +.Xr EVP_EncryptInit 3 , +.Xr EVP_MD_CTX_ctrl 3 , +.Xr EVP_MD_meth_new 3 , +.Xr EVP_MD_nid 3 , +.Xr EVP_OpenInit 3 , +.Xr EVP_PKCS82PKEY 3 , +.Xr EVP_PKEY_add1_attr 3 , +.Xr EVP_PKEY_asn1_get_count 3 , +.Xr EVP_PKEY_asn1_new 3 , +.Xr EVP_PKEY_check 3 , +.Xr EVP_PKEY_cmp 3 , +.Xr EVP_PKEY_CTX_ctrl 3 , +.Xr EVP_PKEY_CTX_get_operation 3 , +.Xr EVP_PKEY_CTX_new 3 , +.Xr EVP_PKEY_CTX_set_hkdf_md 3 , +.Xr EVP_PKEY_decrypt 3 , +.Xr EVP_PKEY_derive 3 , +.Xr EVP_PKEY_encrypt 3 , +.Xr EVP_PKEY_get_default_digest_nid 3 , +.Xr EVP_PKEY_keygen 3 , +.Xr EVP_PKEY_meth_get0_info 3 , +.Xr EVP_PKEY_meth_new 3 , +.Xr EVP_PKEY_new 3 , +.Xr EVP_PKEY_print_private 3 , +.Xr EVP_PKEY_set1_RSA 3 , +.Xr EVP_PKEY_sign 3 , +.Xr EVP_PKEY_size 3 , +.Xr EVP_PKEY_verify 3 , +.Xr EVP_PKEY_verify_recover 3 , +.Xr EVP_rc4 3 , +.Xr EVP_SealInit 3 , +.Xr EVP_sha1 3 , +.Xr EVP_sha3_224 3 , +.Xr EVP_SignInit 3 , +.Xr EVP_sm3 3 , +.Xr EVP_sm4_cbc 3 , +.Xr EVP_VerifyInit 3 , +.Xr EVP_whirlpool 3 , +.Xr HMAC 3 , +.Xr OCSP_basic_sign 3 , +.Xr OCSP_request_sign 3 , +.Xr PEM_get_EVP_CIPHER_INFO 3 , +.Xr PEM_read_bio_PrivateKey 3 , +.Xr PKCS12_create 3 , +.Xr PKCS5_PBKDF2_HMAC 3 , +.Xr PKCS7_encrypt 3 , +.Xr PKCS7_sign 3 , +.Xr RSA_pkey_ctx_ctrl 3 , +.Xr SSL_CTX_set_tlsext_ticket_key_cb 3 , +.Xr X509_ALGOR_set_md 3 , +.Xr X509_check_private_key 3 , +.Xr X509_CRL_METHOD_new 3 , +.Xr X509_digest 3 , +.Xr X509_get_pubkey 3 , +.Xr X509_PUBKEY_set 3 , +.Xr X509_sign 3 , +.Xr X509_to_X509_REQ 3 diff --git a/Libraries/libressl/man/i2a_ASN1_STRING.3 b/Libraries/libressl/man/i2a_ASN1_STRING.3 new file mode 100644 index 000000000..daa74ca64 --- /dev/null +++ b/Libraries/libressl/man/i2a_ASN1_STRING.3 @@ -0,0 +1,253 @@ +.\" $OpenBSD: i2a_ASN1_STRING.3,v 1.4 2022/09/10 12:36:18 jsg Exp $ +.\" +.\" Copyright (c) 2019, 2021 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 10 2022 $ +.Dt I2A_ASN1_STRING 3 +.Os +.Sh NAME +.Nm i2a_ASN1_STRING , +.Nm i2a_ASN1_INTEGER , +.Nm i2a_ASN1_ENUMERATED , +.Nm a2i_ASN1_STRING , +.Nm a2i_ASN1_INTEGER , +.Nm a2i_ASN1_ENUMERATED +.Nd hexadecimal dump of an ASN.1 string +.Sh SYNOPSIS +.In openssl/asn1.h +.Ft int +.Fo i2a_ASN1_STRING +.Fa "BIO *out_bio" +.Fa "const ASN1_STRING *a" +.Fa "int type" +.Fc +.Ft int +.Fo i2a_ASN1_INTEGER +.Fa "BIO *out_bio" +.Fa "const ASN1_INTEGER *a" +.Fc +.Ft int +.Fo i2a_ASN1_ENUMERATED +.Fa "BIO *out_bio" +.Fa "const i2a_ASN1_ENUMERATED *a" +.Fc +.Ft int +.Fo a2i_ASN1_STRING +.Fa "BIO *in_bio" +.Fa "ASN1_STRING *out_string" +.Fa "char *buffer" +.Fa "int size" +.Fc +.Ft int +.Fo a2i_ASN1_INTEGER +.Fa "BIO *in_bio" +.Fa "ASN1_INTEGER *out_string" +.Fa "char *buffer" +.Fa "int size" +.Fc +.Ft int +.Fo a2i_ASN1_ENUMERATED +.Fa "BIO *in_bio" +.Fa "ASN1_ENUMERATED *out_string" +.Fa "char *buffer" +.Fa "int size" +.Fc +.Sh DESCRIPTION +The functions +.Fn i2a_ASN1_STRING , +.Fn i2a_ASN1_INTEGER , +and +.Fn i2a_ASN1_ENUMERATED +write a hexadecimal representation of +.Fa a +to +.Fa out_bio . +The +.Fa type +argument is ignored. +.Pp +Each byte of +.Xr ASN1_STRING_get0_data 3 +is written as a number consisting of two upper-case hexadecimal digits. +After each group of 70 digits, a backslash and a linefeed +are inserted before the next digit. +.Pp +If the +.Xr ASN1_STRING_length 3 +of +.Fa a +is 0, instead a pair of zero digits +.Pq Qq 00 +is written by +.Fn i2a_ASN1_INTEGER +and +.Fn i2a_ASN1_ENUMERATED +and a single zero digit +.Pq Qq 0 +by +.Fn i2a_ASN1_STRING . +If +.Fa a +is a +.Dv NULL +pointer, nothing is written. +.Pp +If +.Fa a +represents a negative integer, +.Fn i2a_ASN1_INTEGER +prepends a minus sign to the output. +.Pp +The functions +.Fn a2i_ASN1_STRING , +.Fn a2i_ASN1_INTEGER , +and +.Fn a2i_ASN1_ENUMERATED +parse a hexadecimal representation of an ASN.1 string into +.Fa out_string . +Both lower-case and upper-case hexadecimal digits are accepted. +Every pair of input digits is converted into one output byte. +.Pp +On every input line, the trailing newline character and an optional +carriage return character preceding it are ignored. +The trailing newline need not be present on the last line. +If there is a backslash character before the newline character, +parsing is continued on the next input line. +.Pp +At least one pair of input digits is required by +.Fn a2i_ASN1_INTEGER +and +.Fn a2i_ASN1_ENUMERATED , +whereas +.Fn a2i_ASN1_STRING +converts empty input to an empty string. +.Pp +These functions are able to parse the output of +.Fn i2a_ASN1_ENUMERATED . +They can parse the output of +.Fn i2a_ASN1_INTEGER +unless +.Fa a +was negative, and they can parse the output of +.Fn i2a_ASN1_STRING +unless the +.Xr ASN1_STRING_length 3 +of +.Fa a +was 0. +.Pp +Parsing fails if an input line contains an odd number of input +digits or if memory allocation fails. +.Pp +These functions use the +.Fa buffer +provided by the caller and assume it is at least +.Fa size +bytes long. +It is unspecified what the buffer contains after the functions return. +.Sh RETURN VALUES +The functions +.Fn i2a_ASN1_STRING , +.Fn i2a_ASN1_INTEGER , +and +.Fn i2a_ASN1_ENUMERATED +return the number of bytes written or \-1 if +.Xr BIO_write 3 +fails. +In particular, they all return 0 when +.Fa a +is a +.Dv NULL +pointer. +.Fn i2a_ASN1_STRING +returns 1 for an empty string or an even number greater than 1 +for a string that is not empty. +.Fn i2a_ASN1_INTEGER +returns an even number greater than 1 for positive input +or an odd number greater than 2 for negative input. +.Fn i2a_ASN1_ENUMERATED +always returns a non-negative even number when successful. +.Pp +The functions +.Fn a2i_ASN1_STRING , +.Fn a2i_ASN1_INTEGER , +and +.Fn a2i_ASN1_ENUMERATED +are intended to return 1 for success or 0 for failure, but see the +.Sx BUGS +section for a number of traps. +.Sh SEE ALSO +.Xr ASN1_STRING_length 3 , +.Xr ASN1_STRING_new 3 , +.Xr ASN1_STRING_print_ex 3 , +.Xr i2a_ASN1_OBJECT 3 +.Sh HISTORY +.Fn i2a_ASN1_INTEGER +and +.Fn a2i_ASN1_INTEGER +first appeared in SSLeay 0.6.0. +.Fn i2a_ASN1_STRING +and +.Fn a2i_ASN1_STRING +first appeared in SSLeay 0.6.5. +.Fn a2i_ASN1_STRING +has been part of the public API since SSLeay 0.6.5 and +.Fn i2a_ASN1_STRING +since SSLeay 0.8.0. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn i2a_ASN1_ENUMERATED +and +.Fn a2i_ASN1_ENUMERATED +first appeared in OpenSSL 0.9.2 and have been available since +.Ox 2.6 . +.Sh BUGS +If the first call to +.Xr BIO_gets 3 +does not return any data, even if that is caused by a fatal I/O error, +if the BIO type does not support the +.Dq gets +operation, or if it is caused by the BIO being non-blocking, +.Fn a2i_ASN1_STRING +immediately succeeds and returns an empty +.Fa out_string . +.Pp +If +.Fn BIO_gets 3 +returns a partial line, for example because the given +.Fa size +is insufficient to contain one of the input lines +or for reasons specific to the BIO type, +.Fn a2i_ASN1_STRING , +.Fn a2i_ASN1_INTEGER , +and +.Fn a2i_ASN1_ENUMERATED +may fail or silently return a truncated result. +The caller is responsible for providing a +.Fa buffer +of sufficient size to contain the longest possible input line +and for choosing a BIO of a type that only returns complete +input lines and does not perform partial reads. +.Pp +The functions +.Fn a2i_ASN1_STRING , +.Fn a2i_ASN1_INTEGER , +and +.Fn a2i_ASN1_ENUMERATED +do not support non-blocking BIOs. +Reading is terminated as soon as +.Xr BIO_gets 3 +returns a value less than 1. diff --git a/Libraries/libressl/man/i2d_CMS_bio_stream.3 b/Libraries/libressl/man/i2d_CMS_bio_stream.3 new file mode 100644 index 000000000..b60468464 --- /dev/null +++ b/Libraries/libressl/man/i2d_CMS_bio_stream.3 @@ -0,0 +1,95 @@ +.\" $OpenBSD: i2d_CMS_bio_stream.3,v 1.6 2023/05/01 07:28:11 tb Exp $ +.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2008 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt I2D_CMS_BIO_STREAM 3 +.Os +.Sh NAME +.Nm i2d_CMS_bio_stream +.Nd output CMS_ContentInfo structure in BER format +.Sh SYNOPSIS +.In openssl/cms.h +.Ft int +.Fo i2d_CMS_bio_stream +.Fa "BIO *out" +.Fa "CMS_ContentInfo *cms" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn i2d_CMS_bio_stream +outputs a +.Vt CMS_ContentInfo +structure in BER format. +.Pp +It is otherwise identical to the function +.Xr SMIME_write_CMS 3 . +.Pp +This function is effectively a version of +.Xr i2d_CMS_bio 3 +supporting streaming. +.Sh RETURN VALUES +.Fn i2d_CMS_bio_stream +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr CMS_ContentInfo_new 3 , +.Xr CMS_encrypt 3 , +.Xr CMS_sign 3 , +.Xr ERR_get_error 3 , +.Xr PEM_write_bio_CMS_stream 3 , +.Xr SMIME_write_CMS 3 +.Sh HISTORY +.Fn i2d_CMS_bio_stream +first appeared in OpenSSL 1.0.0 +and has been available since +.Ox 6.7 . +.Sh BUGS +The prefix "i2d" is arguably wrong because the function outputs BER +format. diff --git a/Libraries/libressl/man/i2d_PKCS7_bio_stream.3 b/Libraries/libressl/man/i2d_PKCS7_bio_stream.3 new file mode 100644 index 000000000..7a47ba302 --- /dev/null +++ b/Libraries/libressl/man/i2d_PKCS7_bio_stream.3 @@ -0,0 +1,94 @@ +.\" $OpenBSD: i2d_PKCS7_bio_stream.3,v 1.11 2023/05/01 07:28:11 tb Exp $ +.\" OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2007, 2008, 2009, 2013 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 1 2023 $ +.Dt I2D_PKCS7_BIO_STREAM 3 +.Os +.Sh NAME +.Nm i2d_PKCS7_bio_stream +.Nd output PKCS7 structure in BER format +.Sh SYNOPSIS +.In openssl/pkcs7.h +.Ft int +.Fo i2d_PKCS7_bio_stream +.Fa "BIO *out" +.Fa "PKCS7 *p7" +.Fa "BIO *data" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +.Fn i2d_PKCS7_bio_stream +outputs a +.Vt PKCS7 +structure in BER format. +It is otherwise identical to the function +.Xr SMIME_write_PKCS7 3 . +This function is effectively a version of +.Xr i2d_PKCS7_bio 3 +supporting streaming. +.Sh RETURN VALUES +.Fn i2d_PKCS7_bio_stream +returns 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr ERR_get_error 3 , +.Xr PEM_write_bio_PKCS7_stream 3 , +.Xr PEM_write_PKCS7 3 , +.Xr PKCS7_final 3 , +.Xr PKCS7_new 3 , +.Xr SMIME_write_PKCS7 3 +.Sh HISTORY +.Fn i2d_PKCS7_bio_stream +first appeared in OpenSSL 1.0.0 and has been available since +.Ox 4.9 . +.Sh BUGS +The prefix "i2d" is arguably wrong because the function outputs BER +format. diff --git a/Libraries/libressl/man/lh_new.3 b/Libraries/libressl/man/lh_new.3 new file mode 100644 index 000000000..c848eed82 --- /dev/null +++ b/Libraries/libressl/man/lh_new.3 @@ -0,0 +1,564 @@ +.\" $OpenBSD: lh_new.3,v 1.9 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: +.\" OpenSSL doc/crypto/lhash.pod 1bc74519 May 20 08:11:46 2016 -0400 +.\" selective merge up to: +.\" OpenSSL doc/man3/OPENSSL_LH_COMPFUNC.pod 24a535ea Sep 22 13:14:20 2020 +0100 +.\" +.\" -------------------------------------------------------------------------- +.\" Major patches to this file were contributed by +.\" Ulf Moeller , Geoff Thorpe , +.\" and Ben Laurie . +.\" -------------------------------------------------------------------------- +.\" Copyright (c) 2000, 2001, 2002, 2008, 2009 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" -------------------------------------------------------------------------- +.\" Parts of this file are derived from SSLeay documentation, +.\" which is covered by the following Copyright and license: +.\" -------------------------------------------------------------------------- +.\" +.\" Copyright (C) 1995-1998 Tim Hudson (tjh@cryptsoft.com) +.\" All rights reserved. +.\" +.\" This package is an SSL implementation written +.\" by Eric Young (eay@cryptsoft.com). +.\" The implementation was written so as to conform with Netscapes SSL. +.\" +.\" This library is free for commercial and non-commercial use as long as +.\" the following conditions are aheared to. The following conditions +.\" apply to all code found in this distribution, be it the RC4, RSA, +.\" lhash, DES, etc., code; not just the SSL code. The SSL documentation +.\" included with this distribution is covered by the same copyright terms +.\" except that the holder is Tim Hudson (tjh@cryptsoft.com). +.\" +.\" Copyright remains Eric Young's, and as such any Copyright notices in +.\" the code are not to be removed. +.\" If this package is used in a product, Eric Young should be given +.\" attribution as the author of the parts of the library used. +.\" This can be in the form of a textual message at program startup or +.\" in documentation (online or textual) provided with the package. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" "This product includes cryptographic software written by +.\" Eric Young (eay@cryptsoft.com)" +.\" The word 'cryptographic' can be left out if the rouines from the +.\" library being used are not cryptographic related :-). +.\" 4. If you include any Windows specific code (or a derivative thereof) +.\" from the apps directory (application code) you must include an +.\" acknowledgement: "This product includes software written by +.\" Tim Hudson (tjh@cryptsoft.com)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" The licence and distribution terms for any publically available version or +.\" derivative of this code cannot be changed. i.e. this code cannot simply be +.\" copied and put under another distribution licence +.\" [including the GNU Public Licence.] +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt LH_NEW 3 +.Os +.Sh NAME +.Nm lh_new , +.Nm lh_free , +.Nm lh_insert , +.Nm lh_delete , +.Nm lh_retrieve , +.Nm lh_doall , +.Nm lh_doall_arg , +.Nm lh_error , +.Nm LHASH_COMP_FN_TYPE , +.Nm LHASH_HASH_FN_TYPE , +.Nm LHASH_DOALL_FN_TYPE , +.Nm LHASH_DOALL_ARG_FN_TYPE , +.Nm lh_strhash +.Nd dynamic hash table +.Sh SYNOPSIS +.In openssl/lhash.h +.Fn DECLARE_LHASH_OF +.Ft LHASH * +.Fn lh__new void +.Ft void +.Fo lh__free +.Fa "LHASH_OF() *table" +.Fc +.Ft * +.Fo lh__insert +.Fa "LHASH_OF() *table" +.Fa " *data" +.Fc +.Ft * +.Fo lh__delete +.Fa "LHASH_OF() *table" +.Fa " *data" +.Fc +.Ft * +.Fo lh__retrieve +.Fa "LHASH_OF() *table" +.Fa " *data" +.Fc +.Ft void +.Fo lh__doall +.Fa "LHASH_OF() *table" +.Fa "LHASH_DOALL_FN_TYPE func" +.Fc +.Ft void +.Fo lh__doall_arg +.Fa "LHASH_OF() *table" +.Fa "LHASH_DOALL_ARG_FN_TYPE func" +.Fa "" +.Fa " *arg" +.Fc +.Ft int +.Fo lh__error +.Fa "LHASH_OF() *table" +.Fc +.Ft typedef int +.Fo (*LHASH_COMP_FN_TYPE) +.Fa "const void *" +.Fa "const void *" +.Fc +.Ft typedef unsigned long +.Fo (*LHASH_HASH_FN_TYPE) +.Fa "const void *" +.Fc +.Ft typedef void +.Fo (*LHASH_DOALL_FN_TYPE) +.Fa "const void *" +.Fc +.Ft typedef void +.Fo (*LHASH_DOALL_ARG_FN_TYPE) +.Fa "const void *" +.Fa "const void *" +.Fc +.Ft unsigned long +.Fo lh_strhash +.Fa "const char *c" +.Fc +.Sh DESCRIPTION +This library implements type-checked dynamic hash tables. +The hash table entries can be arbitrary structures. +Usually they consist of key and value fields. +.Pp +.Fn lh__new +creates a new +.Vt LHASH_OF() +structure to store arbitrary data entries, and provides the hash and +compare callbacks to be used in organising the table's entries. +The hash callback takes a pointer to a table entry as its argument +and returns an unsigned long hash value for its key field. +The hash value is normally truncated to a power of 2, so make sure that +your hash function returns well mixed low order bits. +The compare callback takes two arguments (pointers to two hash table +entries), and returns 0 if their keys are equal, non-zero otherwise. +If your hash table will contain items of some particular type and the +hash and compare callbacks hash and compare these types, then the +.Fn DECLARE_LHASH_HASH_FN +and +.Fn IMPLEMENT_LHASH_COMP_FN +macros can be used to create callback wrappers of the prototypes +required by +.Fn lh__new . +These provide per-variable casts before calling the type-specific +callbacks written by the application author. +These macros, as well as those used for the doall callbacks, are +defined as; +.Bd -literal -offset 2n +#define DECLARE_LHASH_HASH_FN(name, o_type) \e + unsigned long name##_LHASH_HASH(const void *); +#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \e + unsigned long name##_LHASH_HASH(const void *arg) { \e + const o_type *a = arg; \e + return name##_hash(a); } +#define LHASH_HASH_FN(name) name##_LHASH_HASH + +#define DECLARE_LHASH_COMP_FN(name, o_type) \e + int name##_LHASH_COMP(const void *, const void *); +#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \e + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \e + const o_type *a = arg1; \e + const o_type *b = arg2; \e + return name##_cmp(a,b); } +#define LHASH_COMP_FN(name) name##_LHASH_COMP + +#define DECLARE_LHASH_DOALL_FN(name, o_type) \e + void name##_LHASH_DOALL(void *); +#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \e + void name##_LHASH_DOALL(void *arg) { \e + o_type *a = arg; \e + name##_doall(a); } +#define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e + void name##_LHASH_DOALL_ARG(void *, void *); +#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \e + o_type *a = arg1; \e + a_type *b = arg2; \e + name##_doall_arg(a, b); } +#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG +.Ed +.Pp +An example of a hash table storing (pointers to) structures of type +\&'STUFF' could be defined as follows; +.Bd -literal -offset 2n +/* Calculate the hash value of 'tohash' (implemented elsewhere) */ +unsigned long STUFF_hash(const STUFF *tohash); +/* Order 'arg1' and 'arg2' (implemented elsewhere) */ +int stuff_cmp(const STUFF *arg1, const STUFF *arg2); +/* Create type-safe wrapper functions for use in the LHASH internals */ +static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF); +static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF); +/* ... */ +int main(int argc, char *argv[]) { + /* Create the new hash table using the hash/compare wrappers */ + LHASH_OF(STUFF) *hashtable = + lh_STUFF_new(LHASH_HASH_FN(STUFF_hash), + LHASH_COMP_FN(STUFF_cmp)); + /* ... */ +} +.Ed +.Pp +.Fn lh__free +frees the +.Vt LHASH_OF() +structure +.Fa table . +Allocated hash table entries will not be freed; consider using +.Fn lh__doall +to deallocate any remaining entries in the hash table (see below). +.Pp +.Fn lh__insert +inserts the structure pointed to by +.Fa data +into +.Fa table . +If there already is an entry with the same key, the old value is +replaced. +Note that +.Fn lh__insert +stores pointers, the data are not copied. +.Pp +.Fn lh__delete +deletes an entry from +.Fa table . +.Pp +.Fn lh__retrieve +looks up an entry in +.Fa table . +Normally, +.Fa data +is a structure with the key field(s) set; the function will return a +pointer to a fully populated structure. +.Pp +.Fn lh__doall +will, for every entry in the hash table, call +.Fa func +with the data item as its parameter. +For +.Fn lh__doall +and +.Fn lh__doall_arg , +function pointer casting should be avoided in the callbacks (see +.Sx NOTES ) +\(em instead use the declare/implement macros to create type-checked +wrappers that cast variables prior to calling your type-specific +callbacks. +An example of this is illustrated here where the callback is used to +cleanup resources for items in the hash table prior to the hashtable +itself being deallocated: +.Bd -literal -offset 2n +/* Clean up resources belonging to 'a' (this is implemented elsewhere) */ +void STUFF_cleanup_doall(STUFF *a); +/* Implement a prototype-compatible wrapper for "STUFF_cleanup" */ +IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF) + /* ... then later in the code ... */ +/* So to run "STUFF_cleanup" against all items in a hash table ... */ +lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); +/* Then the hash table itself can be deallocated */ +lh_STUFF_free(hashtable); +.Ed +.Pp +When doing this, be careful if you delete entries from the hash table in +your callbacks: the table may decrease in size, moving the item that you +are currently on down lower in the hash table \(em this could cause some +entries to be skipped during the iteration. +The second best solution to this problem is to set hash->down_load=0 +before you start (which will stop the hash table ever decreasing in +size). +The best solution is probably to avoid deleting items from the hash +table inside a doall callback! +.Pp +.Fn lh__doall_arg +is the same as +.Fn lh__doall +except that +.Fa func +will be called with +.Fa arg +as the second argument and +.Fa func +should be of type +.Vt LHASH_DOALL_ARG_FN_TYPE +(a callback prototype that is passed both the table entry and an extra +argument). +As with +.Fn lh__doall , +you can instead choose to declare your callback with a prototype +matching the types you are dealing with and use the declare/implement +macros to create compatible wrappers that cast variables before calling +your type-specific callbacks. +An example of this is demonstrated here (printing all hash table entries +to a BIO that is provided by the caller): +.Bd -literal -offset 2n +/* Print item 'a' to 'output_bio' (this is implemented elsewhere) */ +void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio); +/* Implement a prototype-compatible wrapper for "STUFF_print" */ +static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO) + /* ... then later in the code ... */ +/* Print out the entire hashtable to a particular BIO */ +lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO, + logging_bio); +.Ed +.Pp +.Fn lh__error +can be used to determine if an error occurred in the last operation. +.Fn lh__error +is a macro. +.Sh RETURN VALUES +.Fn lh__new +returns +.Dv NULL +on error, otherwise a pointer to the new +.Vt LHASH +structure. +.Pp +When a hash table entry is replaced, +.Fn lh__insert +returns the value being replaced. +.Dv NULL +is returned on normal operation and on error. +.Pp +.Fn lh__delete +returns the entry being deleted. +.Dv NULL +is returned if there is no such value in the hash table. +.Pp +.Fn lh__retrieve +returns the hash table entry if it has been found, or +.Dv NULL +otherwise. +.Pp +.Fn lh__error +returns 1 if an error occurred in the last operation, or 0 otherwise. +.Sh NOTES +The various LHASH macros and callback types exist to make it possible to +write type-checked code without resorting to function-prototype casting +\(em an evil that makes application code much harder to audit/verify and +also opens the window of opportunity for stack corruption and other +hard-to-find bugs. +It also, apparently, violates ANSI-C. +.Pp +The LHASH code regards table entries as constant data. +As such, it internally represents +.Fn lh__insert Ap ed +items with a +.Vt const void * +pointer type. +This is why callbacks such as those used by +.Fn lh__doall +and +.Fn lh__doall_arg +declare their prototypes with "const", even for the parameters that pass +back the table items' data pointers \(em for consistency, user-provided +data is "const" at all times as far as the LHASH code is concerned. +However, as callers are themselves providing these pointers, they can +choose whether they too should be treating all such parameters as +constant. +.Pp +As an example, a hash table may be maintained by code that, for +reasons of encapsulation, has only "const" access to the data being +indexed in the hash table (i.e. it is returned as "const" from +elsewhere in their code) \(em in this case the LHASH prototypes are +appropriate as-is. +Conversely, if the caller is responsible for the life-time of the data +in question, then they may well wish to make modifications to table item +passed back in the +.Fn lh__doall +or +.Fn lh__doall_arg +callbacks (see the "STUFF_cleanup" example above). +If so, the caller can either cast the "const" away (if they're providing +the raw callbacks themselves) or use the macros to declare/implement the +wrapper functions without "const" types. +.Pp +Callers that only have "const" access to data they are indexing in a +table, yet declare callbacks without constant types (or cast the "const" +away themselves), are therefore creating their own risks/bugs without +being encouraged to do so by the API. +On a related note, those auditing code should pay special attention +to any instances of DECLARE/IMPLEMENT_LHASH_DOALL_[ARG_]_FN macros +that provide types without any "const" qualifiers. +.Sh INTERNALS +The following description is based on the SSLeay documentation: +.Pp +The lhash library implements a hash table described in the +.Em Communications of the ACM +in 1991. +What makes this hash table different is that as the table fills, +the hash table is increased (or decreased) in size via +.Xr reallocarray 3 . +When a 'resize' is done, instead of all hashes being redistributed over +twice as many 'buckets', one bucket is split. +So when an 'expand' is done, there is only a minimal cost to +redistribute some values. +Subsequent inserts will cause more single 'bucket' redistributions but +there will never be a sudden large cost due to redistributing all the +\&'buckets'. +.Pp +The state for a particular hash table is kept in the +.Vt LHASH +structure. +The decision to increase or decrease the hash table size is made +depending on the 'load' of the hash table. +The load is the number of items in the hash table divided by the size of +the hash table. +The default values are as follows. +If (hash->up_load < load) => expand. +If (hash->down_load > load) => contract. +The +.Fa up_load +has a default value of 1 and +.Fa down_load +has a default value of 2. +These numbers can be modified by the application by just playing +with the +.Fa up_load +and +.Fa down_load +variables. +The 'load' is kept in a form which is multiplied by 256. +So hash->up_load=8*256 will cause a load of 8 to be set. +.Pp +If you are interested in performance, the field to watch is +.Fa num_comp_calls . +The hash library keeps track of the 'hash' value for each item so when a +lookup is done, the 'hashes' are compared, if there is a match, then a +full compare is done, and hash->num_comp_calls is incremented. +If num_comp_calls is not equal to num_delete plus num_retrieve, it means +that your hash function is generating hashes that are the same for +different values. +It is probably worth changing your hash function if this is the case +because even if your hash table has 10 items in a 'bucket', it can be +searched with 10 +.Vt unsigned long +compares and 10 linked list traverses. +This will be much less expensive that 10 calls to your compare function. +.Pp +.Fn lh_strhash +is a demo string hashing function. +Since the LHASH routines would normally be passed structures, this +routine would not normally be passed to +.Fn lh__new , +rather it would be used in the function passed to +.Fn lh__new . +.Sh SEE ALSO +.Xr crypto 3 , +.Xr lh_stats 3 +.Sh HISTORY +.Fn lh_new , +.Fn lh_free , +.Fn lh_insert , +.Fn lh_delete , +.Fn lh_retrieve , +.Fn lh_doall , +and +.Fn lh_strhash +appeared in SSLeay 0.4 or earlier. +.Fn lh_doall_arg +first appeared in SSLeay 0.5.1. +These functions have been available since +.Ox 2.4 . +.Pp +.Fn lh__error +was added in SSLeay 0.9.1b. +.Pp +In OpenSSL 0.9.7, all lhash functions that were passed function pointers +were changed for better type safety, and the function types +.Vt LHASH_COMP_FN_TYPE , +.Vt LHASH_HASH_FN_TYPE , +.Vt LHASH_DOALL_FN_TYPE , +and +.Vt LHASH_DOALL_ARG_FN_TYPE +became available. +.Pp +In OpenSSL 1.0.0, the lhash interface was revamped for even better type +checking. +.Sh BUGS +.Fn lh__insert +returns +.Dv NULL +both for success and error. diff --git a/Libraries/libressl/man/lh_stats.3 b/Libraries/libressl/man/lh_stats.3 new file mode 100644 index 000000000..5041721fe --- /dev/null +++ b/Libraries/libressl/man/lh_stats.3 @@ -0,0 +1,206 @@ +.\" $OpenBSD: lh_stats.3,v 1.7 2020/03/29 17:05:02 schwarze Exp $ +.\" OpenSSL e2f92610 May 18 11:44:05 2016 -0400 +.\" +.\" -------------------------------------------------------------------------- +.\" Major patches to this file were contributed by +.\" Ulf Moeller . +.\" -------------------------------------------------------------------------- +.\" Copyright (c) 2000 The OpenSSL Project. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" -------------------------------------------------------------------------- +.\" Parts of this file are derived from SSLeay documentation, +.\" which is covered by the following Copyright and license: +.\" -------------------------------------------------------------------------- +.\" +.\" Copyright (C) 1995-1998 Tim Hudson (tjh@cryptsoft.com) +.\" All rights reserved. +.\" +.\" This package is an SSL implementation written +.\" by Eric Young (eay@cryptsoft.com). +.\" The implementation was written so as to conform with Netscapes SSL. +.\" +.\" This library is free for commercial and non-commercial use as long as +.\" the following conditions are aheared to. The following conditions +.\" apply to all code found in this distribution, be it the RC4, RSA, +.\" lhash, DES, etc., code; not just the SSL code. The SSL documentation +.\" included with this distribution is covered by the same copyright terms +.\" except that the holder is Tim Hudson (tjh@cryptsoft.com). +.\" +.\" Copyright remains Eric Young's, and as such any Copyright notices in +.\" the code are not to be removed. +.\" If this package is used in a product, Eric Young should be given +.\" attribution as the author of the parts of the library used. +.\" This can be in the form of a textual message at program startup or +.\" in documentation (online or textual) provided with the package. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" "This product includes cryptographic software written by +.\" Eric Young (eay@cryptsoft.com)" +.\" The word 'cryptographic' can be left out if the rouines from the +.\" library being used are not cryptographic related :-). +.\" 4. If you include any Windows specific code (or a derivative thereof) +.\" from the apps directory (application code) you must include an +.\" acknowledgement: "This product includes software written by +.\" Tim Hudson (tjh@cryptsoft.com)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" The licence and distribution terms for any publically available version or +.\" derivative of this code cannot be changed. i.e. this code cannot simply be +.\" copied and put under another distribution licence +.\" [including the GNU Public Licence.] +.\" +.Dd $Mdocdate: March 29 2020 $ +.Dt LH_STATS 3 +.Os +.Sh NAME +.Nm lh_stats , +.Nm lh_node_stats , +.Nm lh_node_usage_stats , +.Nm lh_stats_bio , +.Nm lh_node_stats_bio , +.Nm lh_node_usage_stats_bio +.Nd LHASH statistics +.Sh SYNOPSIS +.In openssl/lhash.h +.Ft void +.Fo lh_stats +.Fa "LHASH *table" +.Fa "FILE *out" +.Fc +.Ft void +.Fo lh_node_stats +.Fa "LHASH *table" +.Fa "FILE *out" +.Fc +.Ft void +.Fo lh_node_usage_stats +.Fa "LHASH *table" +.Fa "FILE *out" +.Fc +.Ft void +.Fo lh_stats_bio +.Fa "LHASH *table" +.Fa "BIO *out" +.Fc +.Ft void +.Fo lh_node_stats_bio +.Fa "LHASH *table" +.Fa "BIO *out" +.Fc +.Ft void +.Fo lh_node_usage_stats_bio +.Fa "LHASH *table" +.Fa "BIO *out" +.Fc +.Sh DESCRIPTION +The +.Vt LHASH +structure records statistics about most aspects of accessing the hash +table. +.Pp +.Fn lh_stats +prints out statistics on the size of the hash table, how many entries +are in it, and the number and result of calls to the routines in this +library. +.Pp +.Fn lh_node_stats +prints the number of entries for each 'bucket' in the hash table. +.Pp +.Fn lh_node_usage_stats +prints out a short summary of the state of the hash table. +It prints the 'load' and the 'actual load'. +The load is the average number of data items per 'bucket' in the hash +table. +The 'actual load' is the average number of items per 'bucket', but only +for buckets which contain entries. +So the 'actual load' is the average number of searches that will need to +find an item in the hash table, while the 'load' is the average number +that will be done to record a miss. +.Pp +.Fn lh_stats_bio , +.Fn lh_node_stats_bio , +and +.Fn lh_node_usage_stats_bio +are the same as the above, except that the output goes to a +.Vt BIO . +.Sh SEE ALSO +.Xr BIO_new 3 , +.Xr lh_new 3 +.Sh HISTORY +.Fn lh_stats , +.Fn lh_node_stats , +.Fn lh_node_usage_stats +appeared in SSLeay 0.4. +.Fn lh_stats_bio , +.Fn lh_node_stats_bio , +and +.Fn lh_node_usage_stats_bio +first appeared in SSLeay 0.6.0. +These functions have been available since +.Ox 2.4 . +.Sh AUTHORS +.An Eric Young diff --git a/Libraries/libressl/man/openssl.cnf.5 b/Libraries/libressl/man/openssl.cnf.5 new file mode 100644 index 000000000..48ca66cf4 --- /dev/null +++ b/Libraries/libressl/man/openssl.cnf.5 @@ -0,0 +1,468 @@ +.\" $OpenBSD: openssl.cnf.5,v 1.8 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: OpenSSL man5/config b53338cb Feb 28 12:30:28 2017 +0100 +.\" selective merge up to: OpenSSL a8c5ed81 Jul 18 13:57:25 2017 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 1999, 2000, 2004, 2013, 2015, 2016, 2017 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt OPENSSL.CNF 5 +.Os +.Sh NAME +.Nm openssl.cnf +.Nd OpenSSL configuration files +.Sh DESCRIPTION +The OpenSSL CONF library can be used to read configuration files; see +.Xr CONF_modules_load_file 3 . +It is used for the OpenSSL master configuration file +.Pa /etc/ssl/openssl.cnf +and in a few other places like +.Sy SPKAC +files and certificate extension files for the +.Xr openssl 1 +.Cm x509 +utility. +OpenSSL applications can also use the CONF library for their own +purposes. +.Pp +A configuration file is divided into a number of sections. +Each section starts with a line +.Bq Ar section_name +and ends when a new section is started or the end of the file is reached. +A section name can consist of alphanumeric characters and underscores. +.Pp +The first section of a configuration file is special and is referred to +as the +.Dq default section . +It is usually unnamed and extends from the start of file to the +first named section. +When a name is being looked up, it is first looked up in a named +section (if any) and then in the default section. +.Pp +The environment is mapped onto a section called +.Ic ENV . +.Pp +Comments can be included by preceding them with the +.Ql # +character. +.Pp +Each section in a configuration file consists of a number of name and +value pairs of the form +.Ar name Ns = Ns Ar value . +.Pp +The +.Ar name +string can contain any alphanumeric characters as well as a few +punctuation symbols such as +.Ql \&. +.Ql \&, +.Ql \&; +and +.Ql _ . +.Pp +The +.Ar value +string consists of the string following the +.Ql = +character until the end of the line with any leading and trailing +whitespace removed. +.Pp +The value string undergoes variable expansion. +This can be done by including substrings of the form +.Pf $ Ar name +or +.Pf $ Brq Ar name : +this will substitute the value of the named variable in the current +section. +It is also possible to substitute a value from another section using the +syntax +.Pf $ Ar section Ns :: Ns Ar name +or +.Pf $ Brq Ar section Ns :: Ns Ar name . +By using the form +.Pf $ Ic ENV Ns :: Ns Ar name , +environment variables can be substituted. +It is also possible to assign values to environment variables by using +the name +.Ic ENV Ns :: Ns Ar name . +This will work if the program looks up environment variables using +the CONF library instead of calling +.Xr getenv 3 +directly. +The value string must not exceed 64k in length after variable expansion or an +error will occur. +.Pp +It is possible to escape certain characters by using any kind of quote +or the +.Ql \e +character. +By making the last character of a line a +.Ql \e , +a +.Ar value +string can be spread across multiple lines. +In addition the sequences +.Ql \en , +.Ql \er , +.Ql \eb , +and +.Ql \et +are recognized. +.Sh OPENSSL LIBRARY CONFIGURATION +Applications can automatically configure certain aspects of OpenSSL +using the master OpenSSL configuration file, or optionally an +alternative configuration file. +The +.Xr openssl 1 +utility includes this functionality: any sub command uses the master +OpenSSL configuration file unless an option is used in the sub command +to use an alternative configuration file. +.Pp +To enable library configuration, the default section needs to contain +an appropriate line which points to the main configuration section. +The default name is +.Ic openssl_conf , +which is used by the +.Xr openssl 1 +utility. +Other applications may use an alternative name such as +.Sy myapplication_conf . +All library configuration lines appear in the default section +at the start of the configuration file. +.Pp +The configuration section should consist of a set of name value pairs +which contain specific module configuration information. +The +.Ar name +represents the name of the configuration module. +The meaning of the +.Ar value +is module specific: it may, for example, represent a further +configuration section containing configuration module specific +information. +For example: +.Bd -literal -offset indent +# The following line must be in the default section. +openssl_conf = openssl_init + +[openssl_init] +oid_section = new_oids +engines = engine_section + +[new_oids] +\&... new oids here ... + +[engine_section] +\&... engine stuff here ... +.Ed +.Pp +The features of each configuration module are described below. +.Ss ASN1 Object Configuration Module +This module has the name +.Ic oid_section . +The value of this variable points to a section containing name value +pairs of OIDs: the name is the OID short and long name, and the value is the +numerical form of the OID. +Although some of the +.Xr openssl 1 +utility subcommands already have their own ASN1 OBJECT section +functionality, not all do. +By using the ASN1 OBJECT configuration module, all the +.Xr openssl 1 +utility subcommands can see the new objects as well as any compliant +applications. +For example: +.Bd -literal -offset indent +[new_oids] +some_new_oid = 1.2.3.4 +some_other_oid = 1.2.3.5 +.Ed +.Pp +It is also possible to set the value to the long name followed by a +comma and the numerical OID form. +For example: +.Pp +.Dl shortName = some object long name, 1.2.3.4 +.Ss Engine Configuration Module +This ENGINE configuration module has the name +.Ic engines . +The value of this variable points to a section containing further ENGINE +configuration information. +.Pp +The section pointed to by +.Ic engines +is a table of engine names (though see +.Ic engine_id +below) and further sections containing configuration information +specific to each ENGINE. +.Pp +Each ENGINE specific section is used to set default algorithms, load +dynamic ENGINEs, perform initialization and send ctrls. +The actual operation performed depends on the command +name which is the name of the name value pair. +The currently supported commands are listed below. +.Pp +For example: +.Bd -literal -offset indent +[engine_section] +# Configure ENGINE named "foo" +foo = foo_section +# Configure ENGINE named "bar" +bar = bar_section + +[foo_section] +\&... foo ENGINE specific commands ... + +[bar_section] +\&... "bar" ENGINE specific commands ... +.Ed +.Pp +The command +.Ic engine_id +is used to give the ENGINE name. +If used, this command must be first. +For example: +.Bd -literal -offset indent +[engine_section] +# This would normally handle an ENGINE named "foo" +foo = foo_section + +[foo_section] +# Override default name and use "myfoo" instead. +engine_id = myfoo +.Ed +.Pp +The command +.Ic dynamic_path +loads and adds an ENGINE from the given path. +It is equivalent to sending the ctrls +.Sy SO_PATH +with the path argument followed by +.Sy LIST_ADD +with value 2 and +.Sy LOAD +to the dynamic ENGINE. +If this is not the required behaviour then alternative ctrls can be sent +directly to the dynamic ENGINE using ctrl commands. +.Pp +The command +.Ic init +determines whether to initialize the ENGINE. +If the value is 0, the ENGINE will not be initialized. +If it is 1, an attempt is made to initialized the ENGINE immediately. +If the +.Ic init +command is not present, then an attempt will be made to initialize +the ENGINE after all commands in its section have been processed. +.Pp +The command +.Ic default_algorithms +sets the default algorithms an ENGINE will supply using the functions +.Xr ENGINE_set_default_string 3 . +.Pp +If the name matches none of the above command names, it is assumed +to be a ctrl command which is sent to the ENGINE. +The value of the command is the argument to the ctrl command. +If the value is the string +.Cm EMPTY , +then no value is sent to the command. +.Pp +For example: +.Bd -literal -offset indent +[engine_section] +# Configure ENGINE named "foo" +foo = foo_section + +[foo_section] +# Load engine from DSO +dynamic_path = /some/path/fooengine.so +# A foo specific ctrl. +some_ctrl = some_value +# Another ctrl that doesn't take a value. +other_ctrl = EMPTY +# Supply all default algorithms +default_algorithms = ALL +.Ed +.Sh FILES +.Bl -tag -width /etc/ssl/openssl.cnf -compact +.It Pa /etc/ssl/openssl.cnf +standard configuration file +.El +.Sh EXAMPLES +Here is a sample configuration file using some of the features +mentioned above: +.Bd -literal -offset indent +# This is the default section. +HOME=/temp +RANDFILE= ${ENV::HOME}/.rnd +configdir=$ENV::HOME/config + +[ section_one ] +# We are now in section one. + +# Quotes permit leading and trailing whitespace +any = " any variable name " + +other = A string that can \e +cover several lines \e +by including \e\e characters + +message = Hello World\en + +[ section_two ] +greeting = $section_one::message +.Ed +.Pp +This next example shows how to expand environment variables safely. +.Pp +Suppose you want a variable called +.Sy tmpfile +to refer to a temporary filename. +The directory it is placed in can determined by the +.Ev TEMP +or +.Ev TMP +environment variables but they may not be set to any value at all. +If you just include the environment variable names and the variable +doesn't exist then this will cause an error when an attempt is made to +load the configuration file. +By making use of the default section both values can be looked up with +.Ev TEMP +taking priority and +.Pa /tmp +used if neither is defined: +.Bd -literal -offset indent +TMP=/tmp +# The above value is used if TMP isn't in the environment +TEMP=$ENV::TMP +# The above value is used if TEMP isn't in the environment +tmpfile=${ENV::TEMP}/tmp.filename +.Ed +.Pp +More complex OpenSSL library configuration. +Add OID: +.Bd -literal -offset indent +# Default appname: should match "appname" parameter (if any) +# supplied to CONF_modules_load_file et al. +openssl_conf = openssl_conf_section + +[openssl_conf_section] +# Configuration module list +alg_section = evp_sect +oid_section = new_oids + +[new_oids] +# New OID, just short name +newoid1 = 1.2.3.4.1 +# New OID shortname and long name +newoid2 = New OID 2 long name, 1.2.3.4.2 +.Ed +.Pp +The above examples can be used with any application supporting library +configuration if "openssl_conf" is modified to match the appropriate +"appname". +.Pp +For example if the second sample file above is saved to "example.cnf" +then the command line: +.Pp +.Dl OPENSSL_CONF=example.cnf openssl asn1parse -genstr OID:1.2.3.4.1 +.Pp +will output: +.Dl 0:d=0 hl=2 l= 4 prim: OBJECT :newoid1 +.Pp +showing that the OID "newoid1" has been added as "1.2.3.4.1". +.Sh SEE ALSO +.Xr openssl 1 , +.Xr CONF_modules_load_file 3 , +.Xr OPENSSL_config 3 , +.Xr x509v3.cnf 5 +.Sh CAVEATS +If a configuration file attempts to expand a variable that doesn't +exist, then an error is flagged and the file will not load. +This can also happen if an attempt is made to expand an environment +variable that doesn't exist. +For example, in a previous version of OpenSSL the default OpenSSL +master configuration file used the value of +.Ev HOME +which may not be defined on non Unix systems and would cause an error. +.Pp +This can be worked around by including a default section to provide +a default value: then if the environment lookup fails, the default +value will be used instead. +For this to work properly, the default value must be defined earlier +in the configuration file than the expansion. +See the +.Sx EXAMPLES +section for an example of how to do this. +.Pp +If the same variable is defined more than once in the same section, +then all but the last value will be silently ignored. +In certain circumstances such as with DNs, the same field may occur +multiple times. +This is usually worked around by ignoring any characters before an +initial +.Ql \&. , +for example: +.Bd -literal -offset indent +1.OU="My first OU" +2.OU="My Second OU" +.Ed +.Sh BUGS +Currently there is no way to include characters using the octal +.Pf \e Ar nnn +form. +Strings are all NUL terminated, so NUL bytes cannot form part of +the value. +.Pp +The escaping isn't quite right: if you want to use sequences like +.Ql \en , +you can't use any quote escaping on the same line. +.Pp +Files are loaded in a single pass. +This means that a variable expansion will only work if the variables +referenced are defined earlier in the file. diff --git a/Libraries/libressl/man/s2i_ASN1_INTEGER.3 b/Libraries/libressl/man/s2i_ASN1_INTEGER.3 new file mode 100644 index 000000000..0f0cf2919 --- /dev/null +++ b/Libraries/libressl/man/s2i_ASN1_INTEGER.3 @@ -0,0 +1,209 @@ +.\" $OpenBSD: s2i_ASN1_INTEGER.3,v 1.6 2023/10/01 10:51:19 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 1 2023 $ +.Dt I2S_ASN1_INTEGER 3 +.Os +.Sh NAME +.Nm i2s_ASN1_ENUMERATED , +.Nm i2s_ASN1_ENUMERATED_TABLE , +.Nm i2s_ASN1_INTEGER , +.Nm s2i_ASN1_INTEGER , +.Nm i2s_ASN1_OCTET_STRING , +.Nm s2i_ASN1_OCTET_STRING +.Nd ASN.1 data type conversion utilities for certificate extensions +.Sh SYNOPSIS +.In openssl/asn1.h +.In openssl/x509v3.h +.Ft "char *" +.Fo i2s_ASN1_ENUMERATED +.Fa "X509V3_EXT_METHOD *method" +.Fa "const ASN1_ENUMERATED *a" +.Fc +.Ft "char *" +.Fo i2s_ASN1_INTEGER +.Fa "X509V3_EXT_METHOD *method" +.Fa "const ASN1_INTEGER *a" +.Fc +.Ft "ASN1_INTEGER *" +.Fo s2i_ASN1_INTEGER +.Fa "X509V3_EXT_METHOD *method" +.Fa "const char *value" +.Fc +.Ft "char *" +.Fo i2s_ASN1_OCTET_STRING +.Fa "X509V3_EXT_METHOD *method" +.Fa "const ASN1_OCTET_STRING *aos" +.Fc +.Ft "ASN1_OCTET_STRING *" +.Fo s2i_ASN1_OCTET_STRING +.Fa "X509V3_EXT_METHOD *method" +.Fa "X509V3_CTX *ctx" +.Fa "const char *value" +.Fc +.Ft "char *" +.Fo i2s_ASN1_ENUMERATED_TABLE +.Fa "X509V3_EXT_METHOD *method" +.Fa "const ASN1_ENUMERATED *aenum" +.Fc +.Sh DESCRIPTION +These functions convert to and from +.Vt ASN1_ENUMERATED , +.Vt ASN1_INTEGER , +and +.Vt ASN1_OCTET_STRING +objects. +They are primarily used internally for parsing configuration files and +displaying X.509v3 certificate extensions. +With the exception of +.Fn i2s_ASN1_ENUMERATED_TABLE , +these functions ignore the +.Fa method +argument. +Any object or string returned by these functions must be freed by the caller. +.Pp +.Fn i2s_ASN1_ENUMERATED +and +.Fn i2s_ASN1_INTEGER +first convert +.Fa a +into a +.Vt BIGNUM +object with +.Xr ASN1_ENUMERATED_to_BN 3 +or +.Xr ASN1_INTEGER_to_BN 3 +and then derive a string representation using +.Xr BN_bn2dec 3 +or +.Xr BN_bn2hex 3 . +Decimal representation is used if the number has less than 128 bits, +otherwise hexadecimal representation is used to avoid excessive conversion cost. +.Pp +.Fn s2i_ASN1_INTEGER +converts the NUL-terminated decimal or hexadecimal string representation of +an integer in +.Fa value +into an +.Vt ASN1_INTEGER +object. +A sign prefix of +.Sq - +indicates a negative number and the base prefixes +.Sq 0x +and +.Sq 0X +indicate hexadecimal representation, +otherwise decimal representation is assumed. +After skipping the sign and base prefixes, an intermediate conversion into a +.Vt BIGNUM +is performed using +.Xr BN_dec2bn 3 +or +.Xr BN_hex2bn 3 +and the +.Vt ASN1_INTEGER +is then obtained with +.Xr BN_to_ASN1_INTEGER 3 . +.Pp +.Fn i2s_ASN1_OCTET_STRING +converts the octets in +.Fa aos +into a string where the octets are colon-separated and +represented as pairs of uppercase hexadecimal digits. +.Pp +.Fn s2i_ASN1_OCTET_STRING +converts the NUL-terminated string +.Fa str +into an +.Vt ASN1_OCTET_STRING . +The +.Fa method +and +.Fa ctx +arguments are ignored. +Every pair of hexadecimal digits is converted into an octet. +Colons are ignored if they are at the start, the end or +if they separate two pairs of digits. +.Pp +.Fn i2s_ASN1_ENUMERATED_TABLE +uses strings provided in the usr_data field of the non-NULL +.Fa method +to convert the value of +.Fa a +into a string. +If no such string is available, +.Fa a +is passed to +.Fn i2s_ASN1_ENUMERATED . +The +.Fa method +argument can be provided by application programs or it can be a +default method obtained from +.Xr X509V3_EXT_get_nid 3 . +The default +.Fa methods +corresponding to the following +.Fa nid +arguments have strings configured in their usr_data field: +.Pp +.Bl -column NID_netscape_cert_type "Netscape certificate type (obsolete)" -compact +.It Dv NID_crl_reason Ta reason codes, RFC 5280, 5.3.1 +.It Dv NID_key_usage Ta key usage, RFC 5280, 4.2.1.3 +.It Dv NID_netscape_cert_type Ta Netscape certificate type (obsolete) +.El +.Sh RETURN VALUES +.Fn i2s_ASN1_ENUMERATED , +.Fn i2s_ASN1_ENUMERATED_TABLE , +.Fn i2s_ASN1_INTEGER , +and +.Fn i2s_ASN1_OCTET_STRING +return a NUL-terminated string, or NULL on memory allocation failure. +.Pp +.Fn s2i_ASN1_INTEGER +returns an +.Vt ASN1_INTEGER , +or NULL on error. +Error conditions are memory allocation failure or if +.Fa value +is not a valid decimal or hexadecimal encoding of an integer. +.Pp +.Fn s2i_ASN1_OCTET_STRING +returns an +.Vt ASN1_OCTET_STRING , +or NULL on error. +Error conditions are memory allocation failure or if +.Fa value +contains an odd number of hexadecimal digits or anything except +colons at the start, the end or between pairs of hexadecimal digits. +.Pp +Error codes can sometimes be obtained by +.Xr ERR_get_error 3 . +.Sh SEE ALSO +.Xr ASN1_INTEGER_new 3 , +.Xr ASN1_INTEGER_to_BN 3 , +.Xr ASN1_OCTET_STRING_new 3 , +.Xr crypto 3 , +.Xr X509V3_get_d2i 3 +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.4 and +have been available since +.Ox 2.6 . +.Sh BUGS +Of these functions at least +.Fn i2s_ASN1_ENUMERATED_TABLE +can succeed while setting an error and fail without setting an error +on the error stack. diff --git a/Libraries/libressl/man/ssl.3 b/Libraries/libressl/man/ssl.3 new file mode 100644 index 000000000..4dd3d23f1 --- /dev/null +++ b/Libraries/libressl/man/ssl.3 @@ -0,0 +1,367 @@ +.\" $OpenBSD: ssl.3,v 1.22 2022/09/17 16:03:21 kn Exp $ +.\" full merge up to: OpenSSL e330f55d Nov 11 00:51:04 2016 +0100 +.\" selective merge up to: OpenSSL 322755cc Sep 1 08:40:51 2018 +0800 +.\" +.\" This file was written by Ralf S. Engelschall , +.\" Ben Laurie , and Ulf Moeller . +.\" Copyright (c) 1998-2002, 2005, 2013, 2015 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: September 17 2022 $ +.Dt SSL 3 +.Os +.Sh NAME +.Nm ssl +.Nd OpenSSL SSL/TLS library +.Sh DESCRIPTION +The OpenSSL +.Nm ssl +library implements the Transport Layer Security (TLS v1) protocols. +.Pp +An +.Vt SSL_CTX +object is created as a framework to establish TLS/SSL enabled connections (see +.Xr SSL_CTX_new 3 ) . +Various options regarding certificates, algorithms, etc., can be set in this +object. +.Pp +When a network connection has been created, it can be assigned to an +.Vt SSL +object. +After the +.Vt SSL +object has been created using +.Xr SSL_new 3 , +.Xr SSL_set_fd 3 +or +.Xr SSL_set_bio 3 +can be used to associate the network connection with the object. +.Pp +Then the TLS/SSL handshake is performed using +.Xr SSL_accept 3 +or +.Xr SSL_connect 3 +respectively. +.Xr SSL_read 3 +and +.Xr SSL_write 3 +are used to read and write data on the TLS/SSL connection. +.Xr SSL_shutdown 3 +can be used to shut down the TLS/SSL connection. +.Sh DATA STRUCTURES +Currently the OpenSSL +.Nm ssl +library functions deal with the following data structures: +.Bl -tag -width Ds +.It Vt SSL_METHOD No (SSL Method) +That's a dispatch structure describing the internal +.Nm ssl +library methods/functions which implement the various protocol versions. +It's needed to create an +.Vt SSL_CTX . +See +.Xr TLS_method 3 +for constructors. +.It Vt SSL_CIPHER No (SSL Cipher) +This structure holds the algorithm information for a particular cipher which +is a core part of the SSL/TLS protocol. +The available ciphers are configured on an +.Vt SSL_CTX +basis and the actually used ones are then part of the +.Vt SSL_SESSION . +.It Vt SSL_CTX No (SSL Context) +That's the global context structure which is created by a server or client +once per program lifetime and which holds mainly default values for the +.Vt SSL +structures which are later created for the connections. +.It Vt SSL_SESSION No (SSL Session) +This is a structure containing the current TLS/SSL session details for a +connection: +.Vt SSL_CIPHER Ns s , +client and server certificates, keys, etc. +.It Vt SSL No (SSL Connection) +That's the main SSL/TLS structure which is created by a server or client per +established connection. +This actually is the core structure in the SSL API. +At run-time the application usually deals with this structure which has +links to mostly all other structures. +.El +.Sh HEADER FILES +Currently the OpenSSL +.Nm ssl +library provides the following C header files containing the prototypes for the +data structures and functions: +.Bl -tag -width Ds +.It Pa ssl.h +That's the common header file for the SSL/TLS API. +Include it into your program to make the API of the +.Nm ssl +library available. +It internally includes both more private SSL headers and headers from the +.Em crypto +library. +Whenever you need hardcore details on the internals of the SSL API, look inside +this header file. +.It Pa ssl2.h +That's the sub header file dealing with the SSLv2 protocol only. +.Bf Em + Usually you don't have to include it explicitly because it's already included +by +.Pa ssl.h . +.Ef +.It Pa ssl3.h +That's the sub header file dealing with the SSLv3 protocol only. +.Bf Em +Usually you don't have to include it explicitly because it's already included +by +.Pa ssl.h . +.Ef +.It Pa ssl23.h +That's the sub header file dealing with the combined use of the SSLv2 and SSLv3 +protocols. +.Bf Em +Usually you don't have to include it explicitly because it's already included +by +.Pa ssl.h . +.Ef +.It Pa tls1.h +That's the sub header file dealing with the TLSv1 protocol only. +.Bf Em +Usually you don't have to include it explicitly because it's already included +by +.Pa ssl.h . +.Ef +.El +.Sh API FUNCTIONS +.Ss Ciphers +The following pages describe functions acting on +.Vt SSL_CIPHER +objects: +.Xr SSL_get_ciphers 3 , +.Xr SSL_get_current_cipher 3 , +.Xr SSL_CIPHER_get_name 3 +.Ss Protocol contexts +The following pages describe functions acting on +.Vt SSL_CTX +objects. +.Pp +Constructors and destructors: +.Xr SSL_CTX_new 3 , +.Xr SSL_CTX_set_ssl_version 3 , +.Xr SSL_CTX_free 3 +.Pp +Certificate configuration: +.Xr SSL_CTX_add_extra_chain_cert 3 , +.Xr SSL_CTX_get0_certificate 3 , +.Xr SSL_CTX_load_verify_locations 3 , +.Xr SSL_CTX_set_cert_store 3 , +.Xr SSL_CTX_set_cert_verify_callback 3 , +.Xr SSL_CTX_set_client_cert_cb 3 , +.Xr SSL_CTX_set_default_passwd_cb 3 , +.Xr SSL_CTX_set_tlsext_status_cb 3 +.Pp +Session configuration: +.Xr SSL_CTX_add_session 3 , +.Xr SSL_CTX_flush_sessions 3 , +.Xr SSL_CTX_sess_number 3 , +.Xr SSL_CTX_sess_set_cache_size 3 , +.Xr SSL_CTX_sess_set_get_cb 3 , +.Xr SSL_CTX_sessions 3 , +.Xr SSL_CTX_set_session_cache_mode 3 , +.Xr SSL_CTX_set_timeout 3 , +.Xr SSL_CTX_set_tlsext_ticket_key_cb 3 +.Pp +Various configuration: +.Xr SSL_CTX_get_ex_new_index 3 , +.Xr SSL_CTX_set_tlsext_servername_callback 3 +.Ss Common configuration of contexts and connections +The functions on the following pages each come in two variants: +one to directly configure a single +.Vt SSL +connection and another to be called on an +.Vt SSL_CTX +object, to set up defaults for all future +.Vt SSL +connections created from that context. +.Pp +Protocol and algorithm configuration: +.Xr SSL_CTX_set_alpn_select_cb 3 , +.Xr SSL_CTX_set_cipher_list 3 , +.Xr SSL_CTX_set_min_proto_version 3 , +.Xr SSL_CTX_set_options 3 , +.Xr SSL_CTX_set_security_level 3 , +.Xr SSL_CTX_set_tlsext_use_srtp 3 , +.Xr SSL_CTX_set_tmp_dh_callback 3 , +.Xr SSL_CTX_set1_groups 3 +.Pp +Certificate configuration: +.Xr SSL_CTX_add1_chain_cert 3 , +.Xr SSL_CTX_get_verify_mode 3 , +.Xr SSL_CTX_set_client_CA_list 3 , +.Xr SSL_CTX_set_max_cert_list 3 , +.Xr SSL_CTX_set_verify 3 , +.Xr SSL_CTX_use_certificate 3 , +.Xr SSL_get_client_CA_list 3 +.Xr SSL_set1_param 3 +.Pp +Session configuration: +.Xr SSL_CTX_set_generate_session_id 3 , +.Xr SSL_CTX_set_session_id_context 3 +.Pp +Various configuration: +.Xr SSL_CTX_ctrl 3 , +.Xr SSL_CTX_set_info_callback 3 , +.Xr SSL_CTX_set_mode 3 , +.Xr SSL_CTX_set_msg_callback 3 , +.Xr SSL_CTX_set_quiet_shutdown 3 , +.Xr SSL_CTX_set_read_ahead 3 , +.Xr SSL_set_max_send_fragment 3 +.Ss Sessions +The following pages describe functions acting on +.Vt SSL_SESSION +objects. +.Pp +Constructors and destructors: +.Xr SSL_SESSION_new 3 , +.Xr SSL_SESSION_free 3 +.Pp +Accessors: +.Xr SSL_SESSION_get_compress_id 3 , +.Xr SSL_SESSION_get_ex_new_index 3 , +.Xr SSL_SESSION_get_id 3 , +.Xr SSL_SESSION_get_protocol_version 3 , +.Xr SSL_SESSION_get_time 3 , +.Xr SSL_SESSION_get0_peer 3 , +.Xr SSL_SESSION_has_ticket 3 , +.Xr SSL_SESSION_set1_id_context 3 +.Pp +Encoding and decoding: +.Xr d2i_SSL_SESSION 3 , +.Xr PEM_read_SSL_SESSION 3 , +.Xr SSL_SESSION_print 3 +.Ss Connections +The following pages describe functions acting on +.Vt SSL +connection objects: +.Pp +Constructors and destructors: +.Xr SSL_new 3 , +.Xr SSL_dup 3 , +.Xr SSL_free 3 , +.Xr BIO_f_ssl 3 +.Pp +To change the configuration: +.Xr SSL_clear 3 , +.Xr SSL_set_SSL_CTX 3 , +.Xr SSL_copy_session_id 3 , +.Xr SSL_set_bio 3 , +.Xr SSL_set_connect_state 3 , +.Xr SSL_set_fd 3 , +.Xr SSL_set_session 3 , +.Xr SSL_set1_host 3 , +.Xr SSL_set_verify_result 3 +.Pp +To inspect the configuration: +.Xr SSL_get_certificate 3 , +.Xr SSL_get_default_timeout 3 , +.Xr SSL_get_ex_new_index 3 , +.Xr SSL_get_fd 3 , +.Xr SSL_get_rbio 3 , +.Xr SSL_get_SSL_CTX 3 +.Pp +To transmit data: +.Xr DTLSv1_listen 3 , +.Xr SSL_accept 3 , +.Xr SSL_connect 3 , +.Xr SSL_do_handshake 3 , +.Xr SSL_read 3 , +.Xr SSL_read_early_data 3 , +.Xr SSL_renegotiate 3 , +.Xr SSL_shutdown 3 , +.Xr SSL_write 3 +.Pp +To inspect the state after a connection is established: +.Xr SSL_export_keying_material 3 , +.Xr SSL_get_client_random 3 , +.Xr SSL_get_ex_data_X509_STORE_CTX_idx 3 , +.Xr SSL_get_peer_cert_chain 3 , +.Xr SSL_get_peer_certificate 3 , +.Xr SSL_get_server_tmp_key 3 , +.Xr SSL_get_servername 3 , +.Xr SSL_get_session 3 , +.Xr SSL_get_shared_ciphers 3 , +.Xr SSL_get_verify_result 3 , +.Xr SSL_get_version 3 , +.Xr SSL_session_reused 3 +.Pp +To inspect the state during ongoing communication: +.Xr SSL_get_error 3 , +.Xr SSL_get_shutdown 3 , +.Xr SSL_get_state 3 , +.Xr SSL_num_renegotiations 3 , +.Xr SSL_pending 3 , +.Xr SSL_rstate_string 3 , +.Xr SSL_state_string 3 , +.Xr SSL_want 3 +.Ss Utility functions +.Xr SSL_alert_type_string 3 , +.Xr SSL_dup_CA_list 3 , +.Xr SSL_load_client_CA_file 3 +.Ss Obsolete functions +.Xr OPENSSL_init_ssl 3 , +.Xr SSL_COMP_add_compression_method 3 , +.Xr SSL_CTX_set_tmp_rsa_callback 3 , +.Xr SSL_library_init 3 , +.Xr SSL_set_tmp_ecdh 3 +.Sh SEE ALSO +.Xr openssl 1 , +.Xr crypto 3 , +.Xr tls_init 3 +.Sh HISTORY +The +.Nm +document appeared in OpenSSL 0.9.2. diff --git a/Libraries/libressl/man/tls_accept_socket.3 b/Libraries/libressl/man/tls_accept_socket.3 new file mode 100644 index 000000000..931b9346e --- /dev/null +++ b/Libraries/libressl/man/tls_accept_socket.3 @@ -0,0 +1,107 @@ +.\" $OpenBSD: tls_accept_socket.3,v 1.4 2018/05/26 12:35:26 schwarze Exp $ +.\" +.\" Copyright (c) 2015 Ted Unangst +.\" Copyright (c) 2015 Joel Sing +.\" Copyright (c) 2016 Brent Cook +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: May 26 2018 $ +.Dt TLS_ACCEPT_SOCKET 3 +.Os +.Sh NAME +.Nm tls_accept_socket , +.Nm tls_accept_fds , +.Nm tls_accept_cbs +.Nd accept an incoming client connection in a TLS server +.Sh SYNOPSIS +.In tls.h +.Ft int +.Fo tls_accept_socket +.Fa "struct tls *tls" +.Fa "struct tls **cctx" +.Fa "int socket" +.Fc +.Ft int +.Fo tls_accept_fds +.Fa "struct tls *tls" +.Fa "struct tls **cctx" +.Fa "int fd_read" +.Fa "int fd_write" +.Fc +.Ft int +.Fo tls_accept_cbs +.Fa "struct tls *tls" +.Fa "struct tls **cctx" +.Fa "ssize_t (*tls_read_cb)(struct tls *ctx,\ + void *buf, size_t buflen, void *cb_arg)" +.Fa "ssize_t (*tls_write_cb)(struct tls *ctx,\ + const void *buf, size_t buflen, void *cb_arg)" +.Fa "void *cb_arg" +.Fc +.Sh DESCRIPTION +After creating a TLS server context +.Fa tls +with +.Xr tls_server 3 +and configuring it with +.Xr tls_configure 3 , +a server can accept a new client connection by calling +.Fn tls_accept_socket +on an already established socket connection. +.Pp +Alternatively, a new client connection can be accepted over a pair of existing +file descriptors by calling +.Fn tls_accept_fds . +.Pp +Calling +.Fn tls_accept_cbs +allows read and write callback functions to handle data transfers. +The specified +.Fa cb_arg +parameter is passed back to the functions, +and can contain a pointer to any caller-specified data. +.Pp +All these functions create a new context suitable for reading and writing +and return it in +.Pf * Fa cctx . +.Sh RETURN VALUES +These functions return 0 on success or -1 on error. +.Sh SEE ALSO +.Xr tls_close 3 , +.Xr tls_config_set_session_id 3 , +.Xr tls_configure 3 , +.Xr tls_connect 3 , +.Xr tls_init 3 , +.Xr tls_server 3 +.Sh HISTORY +.Fn tls_accept_socket +appeared in +.Ox 5.6 +and got its final name in +.Ox 5.7 . +.Pp +.Fn tls_accept_fds +appeared in +.Ox 5.8 +and +.Fn tls_accept_cbs +in +.Ox 6.1 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +.Pp +.An -nosplit +.Fn tls_accept_cbs +was written by +.An Tobias Pape Aq Mt tobias@netshed.de . diff --git a/Libraries/libressl/man/tls_client.3 b/Libraries/libressl/man/tls_client.3 new file mode 100644 index 000000000..98f58d4c2 --- /dev/null +++ b/Libraries/libressl/man/tls_client.3 @@ -0,0 +1,110 @@ +.\" $OpenBSD: tls_client.3,v 1.4 2017/08/12 03:41:48 jsing Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 12 2017 $ +.Dt TLS_CLIENT 3 +.Os +.Sh NAME +.Nm tls_client , +.Nm tls_server , +.Nm tls_configure , +.Nm tls_reset , +.Nm tls_free +.Nd configure a TLS connection +.Sh SYNOPSIS +.In tls.h +.Ft struct tls * +.Fn tls_client void +.Ft struct tls * +.Fn tls_server void +.Ft int +.Fo tls_configure +.Fa "struct tls *ctx" +.Fa "struct tls_config *config" +.Fc +.Ft void +.Fn tls_free "struct tls *ctx" +.Ft void +.Fn tls_reset "struct tls *ctx" +.Sh DESCRIPTION +A TLS connection is represented as a +.Vt struct tls +object called a +.Dq context . +A new context is created by either the +.Fn tls_client +or +.Fn tls_server +functions. +.Fn tls_client +is used in TLS client programs, +.Fn tls_server +in TLS server programs. +.Pp +The context can then be configured with the function +.Fn tls_configure . +The same +.Vt tls_config +object can be used to configure multiple contexts. +.Pp +After configuration, +.Xr tls_connect 3 +can be called on objects created with +.Fn tls_client , +and +.Xr tls_accept_socket 3 +on objects created with +.Fn tls_server . +.Pp +After use, a TLS context should be closed with +.Xr tls_close 3 , +and then freed by calling +.Fn tls_free . +If +.Fn tls_free +is called with an argument of +.Dv NULL , +no action occurs. +.Pp +A TLS context can be reset by calling +.Fn tls_reset , +allowing for it to be reused. +This is essentially equivalent to calling +.Fn tls_free , +followed by a call to the same function that was used to originally allocate +the TLS context. +.Sh RETURN VALUES +.Fn tls_client +and +.Fn tls_server +return +.Dv NULL +on error or an out of memory condition. +.Pp +.Fn tls_configure +returns 0 on success or -1 on error. +.Sh SEE ALSO +.Xr tls_accept_socket 3 , +.Xr tls_config_new 3 , +.Xr tls_connect 3 , +.Xr tls_init 3 +.Sh HISTORY +These functions appeared in +.Ox 5.6 +and got their final names in +.Ox 5.7 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org diff --git a/Libraries/libressl/man/tls_config_ocsp_require_stapling.3 b/Libraries/libressl/man/tls_config_ocsp_require_stapling.3 new file mode 100644 index 000000000..a0694d304 --- /dev/null +++ b/Libraries/libressl/man/tls_config_ocsp_require_stapling.3 @@ -0,0 +1,40 @@ +.\" $OpenBSD: tls_config_ocsp_require_stapling.3,v 1.5 2017/01/31 20:53:50 jmc Exp $ +.\" +.\" Copyright (c) 2016 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 31 2017 $ +.Dt TLS_CONFIG_OCSP_REQUIRE_STAPLING 3 +.Os +.Sh NAME +.Nm tls_config_ocsp_require_stapling +.Nd OCSP configuration for libtls +.Sh SYNOPSIS +.In tls.h +.Ft void +.Fn tls_config_ocsp_require_stapling "struct tls_config *config" +.Sh DESCRIPTION +.Fn tls_config_ocsp_require_stapling +requires that a valid stapled OCSP response be provided +during the TLS handshake. +.Sh SEE ALSO +.Xr tls_config_add_keypair_file 3 , +.Xr tls_handshake 3 , +.Xr tls_init 3 , +.Xr tls_ocsp_process_response 3 +.Sh HISTORY +These functions appeared in +.Ox 6.1 . +.Sh AUTHORS +.An Bob Beck Aq Mt beck@openbsd.org diff --git a/Libraries/libressl/man/tls_config_set_protocols.3 b/Libraries/libressl/man/tls_config_set_protocols.3 new file mode 100644 index 000000000..32b8cce75 --- /dev/null +++ b/Libraries/libressl/man/tls_config_set_protocols.3 @@ -0,0 +1,229 @@ +.\" $OpenBSD: tls_config_set_protocols.3,v 1.12 2023/07/02 06:37:27 beck Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst +.\" Copyright (c) 2015, 2016 Joel Sing +.\" Copyright (c) 2015 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 2 2023 $ +.Dt TLS_CONFIG_SET_PROTOCOLS 3 +.Os +.Sh NAME +.Nm tls_config_set_protocols , +.Nm tls_config_parse_protocols , +.Nm tls_config_set_alpn , +.Nm tls_config_set_ciphers , +.Nm tls_config_set_dheparams , +.Nm tls_config_set_ecdhecurves , +.Nm tls_config_prefer_ciphers_client , +.Nm tls_config_prefer_ciphers_server +.Nd TLS protocol and cipher selection +.Sh SYNOPSIS +.In tls.h +.Ft int +.Fo tls_config_set_protocols +.Fa "struct tls_config *config" +.Fa "uint32_t protocols" +.Fc +.Ft int +.Fo tls_config_parse_protocols +.Fa "uint32_t *protocols" +.Fa "const char *protostr" +.Fc +.Ft int +.Fo tls_config_set_alpn +.Fa "struct tls_config *config" +.Fa "const char *alpn" +.Fc +.Ft int +.Fo tls_config_set_ciphers +.Fa "struct tls_config *config" +.Fa "const char *ciphers" +.Fc +.Ft int +.Fo tls_config_set_dheparams +.Fa "struct tls_config *config" +.Fa "const char *params" +.Fc +.Ft int +.Fo tls_config_set_ecdhecurves +.Fa "struct tls_config *config" +.Fa "const char *curves" +.Fc +.Ft void +.Fn tls_config_prefer_ciphers_client "struct tls_config *config" +.Ft void +.Fn tls_config_prefer_ciphers_server "struct tls_config *config" +.Sh DESCRIPTION +These functions modify a configuration by setting parameters. +The configuration options apply to both clients and servers, unless noted +otherwise. +.Pp +.Fn tls_config_set_protocols +specifies which versions of the TLS protocol may be used. +Possible values are the bitwise OR of: +.Pp +.Bl -item -offset indent -compact +.It +.Dv TLS_PROTOCOL_TLSv1_2 +.It +.Dv TLS_PROTOCOL_TLSv1_3 +.El +.Pp +Additionally, the values +.Dv TLS_PROTOCOL_TLSv1 +(TLSv1.2, TLSv1.3), +.Dv TLS_PROTOCOLS_ALL +(all supported protocols) and +.Dv TLS_PROTOCOLS_DEFAULT +(TLSv1.2 and TLSv1.3) may be used. +.Pp +The +.Fn tls_config_parse_protocols +utility function parses a protocol string and returns the corresponding +value via the +.Ar protocols +argument. +This value can then be passed to the +.Fn tls_config_set_protocols +function. +The protocol string is a comma or colon separated list of keywords. +Valid keywords are: +.Pp +.Bl -tag -width "tlsv1.3" -offset indent -compact +.It Dv tlsv1.2 +.It Dv tlsv1.3 +.It Dv all +.Pq all supported protocols +.It Dv default +.Pq an alias for Dv secure +.It Dv legacy +.Pq an alias for Dv all +.It Dv secure +.Pq currently TLSv1.2 and TLSv1.3 +.El +.Pp +If a value has a negative prefix (in the form of a leading exclamation mark) +then it is removed from the list of available protocols, rather than being +added to it. +.Pp +.Fn tls_config_set_alpn +sets the ALPN protocols that are supported. +The alpn string is a comma separated list of protocols, in order of preference. +.Pp +.Fn tls_config_set_ciphers +sets the list of ciphers that may be used. +Lists of ciphers are specified by name, and the +permitted names are: +.Pp +.Bl -item -offset indent -compact +.It +.Dv secure Pq or alias Dv default +.It +.Dv compat +.It +.Dv legacy +.It +.Dv insecure Pq or alias Dv all +.El +.Pp +Alternatively, libssl cipher strings can be specified. +See the CIPHERS section of +.Xr openssl 1 +for further information. +.Pp +.Fn tls_config_set_dheparams +specifies the parameters that will be used during Diffie-Hellman Ephemeral +(DHE) key exchange. +Possible values are: +.Pp +.Bl -item -offset indent -compact +.It +.Dv none +.It +.Dv auto +.It +.Dv legacy +.El +.Pp +In +.Dv auto +mode, the key size for the ephemeral key is automatically selected +based on the size of the private key being used for signing. +In +.Dv legacy +mode, 1024 bit ephemeral keys are used. +The default value is +.Dv none , +which disables DHE key exchange. +.Pp +.Fn tls_config_set_ecdhecurves +specifies the names of the elliptic curves that may be used during Elliptic +Curve Diffie-Hellman Ephemeral (ECDHE) key exchange. +This is a comma separated list, given in order of preference. +The special value of "default" will use the default curves (currently X25519, +P-256 and P-384). +This function replaces +.Fn tls_config_set_ecdhecurve , +which is deprecated. +.Pp +.Fn tls_config_prefer_ciphers_client +prefers ciphers in the client's cipher list when selecting a cipher suite +(server only). +This is considered to be less secure than preferring the server's list. +.Pp +.Fn tls_config_prefer_ciphers_server +prefers ciphers in the server's cipher list when selecting a cipher suite +(server only). +This is considered to be more secure than preferring the client's list and is +the default. +.Sh RETURN VALUES +These functions return 0 on success or -1 on error. +.Sh SEE ALSO +.Xr tls_config_ocsp_require_stapling 3 , +.Xr tls_config_set_session_id 3 , +.Xr tls_config_verify 3 , +.Xr tls_init 3 , +.Xr tls_load_file 3 +.Sh HISTORY +.Fn tls_config_set_ciphers +appeared in +.Ox 5.6 +and got its final name in +.Ox 5.7 . +.Pp +.Fn tls_config_set_protocols , +.Fn tls_config_parse_protocols , +.Fn tls_config_set_dheparams , +and +.Fn tls_config_set_ecdhecurve +appeared in +.Ox 5.7 , +.Fn tls_config_prefer_ciphers_client +and +.Fn tls_config_prefer_ciphers_server +in +.Ox 5.9 , +and +.Fn tls_config_set_alpn +in +.Ox 6.1 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +with contributions from +.An Ted Unangst Aq Mt tedu@openbsd.org +.Pq Fn tls_config_set_ciphers +and +.An Reyk Floeter Aq Mt reyk@openbsd.org +.Pq Fn tls_config_set_ecdhecurve diff --git a/Libraries/libressl/man/tls_config_set_session_id.3 b/Libraries/libressl/man/tls_config_set_session_id.3 new file mode 100644 index 000000000..d969e01e3 --- /dev/null +++ b/Libraries/libressl/man/tls_config_set_session_id.3 @@ -0,0 +1,105 @@ +.\" $OpenBSD: tls_config_set_session_id.3,v 1.5 2018/02/10 06:07:43 jsing Exp $ +.\" +.\" Copyright (c) 2017 Claudio Jeker +.\" Copyright (c) 2018 Joel Sing +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 10 2018 $ +.Dt TLS_CONFIG_SET_SESSION_ID 3 +.Os +.Sh NAME +.Nm tls_config_set_session_fd , +.Nm tls_config_set_session_id , +.Nm tls_config_set_session_lifetime , +.Nm tls_config_add_ticket_key +.Nd configure resuming of TLS handshakes +.Sh SYNOPSIS +.In tls.h +.Ft int +.Fo tls_config_set_session_fd +.Fa "struct tls_config *config" +.Fa "int session_fd" +.Fc +.Ft int +.Fo tls_config_set_session_id +.Fa "struct tls_config *config" +.Fa "const unsigned char *session_id" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_session_lifetime +.Fa "struct tls_config *config" +.Fa "int lifetime" +.Fc +.Ft int +.Fo tls_config_add_ticket_key +.Fa "struct tls_config *config" +.Fa "uint32_t keyrev" +.Fa "unsigned char *key" +.Fa "size_t keylen" +.Fc +.Sh DESCRIPTION +.Fn tls_config_set_session_fd +sets a file descriptor to be used to manage data for TLS sessions (client only). +The given file descriptor must be a regular file and be owned by the current +user, with permissions being restricted to only allow the owner to read and +write the file (0600). +If the file has a non-zero length, the client will attempt to read session +data from this file and resume the previous TLS session with the server. +Upon a successful handshake the file will be updated with current session +data, if available. +The caller is responsible for closing this file descriptor, after all TLS +contexts that have been configured to use it have been freed via +.Fn tls_free . +.Pp +.Fn tls_config_set_session_id +sets the session identifier that will be used by the TLS server when +sessions are enabled (server only). +By default a random value is used. +.Pp +.Fn tls_config_set_session_lifetime +sets the lifetime to be used for TLS sessions (server only). +Session support is disabled if a lifetime of zero is specified, which is the +default. +.Pp +.Fn tls_config_add_ticket_key +adds a key used for the encryption and authentication of TLS tickets +(server only). +By default keys are generated and rotated automatically based on their lifetime. +This function should only be used to synchronise ticket encryption key across +multiple processes. +Re-adding a known key will result in an error, unless it is the most recently +added key. +.Sh RETURN VALUES +These functions return 0 on success or -1 on error. +.Sh SEE ALSO +.Xr tls_accept_socket 3 , +.Xr tls_config_set_protocols 3 , +.Xr tls_init 3 , +.Xr tls_load_file 3 , +.Xr tls_server 3 +.Sh HISTORY +.Fn tls_config_set_session_id , +.Fn tls_config_set_session_lifetime +and +.Fn tls_config_add_ticket_key +appeared in +.Ox 6.1 . +.Pp +.Fn tls_config_set_session_fd +appeared in +.Ox 6.3 . +.Sh AUTHORS +.An Claudio Jeker Aq Mt claudio@openbsd.org +.An Joel Sing Aq Mt jsing@openbsd.org diff --git a/Libraries/libressl/man/tls_config_verify.3 b/Libraries/libressl/man/tls_config_verify.3 new file mode 100644 index 000000000..4a43c834d --- /dev/null +++ b/Libraries/libressl/man/tls_config_verify.3 @@ -0,0 +1,79 @@ +.\" $OpenBSD: tls_config_verify.3,v 1.4 2017/03/02 11:05:50 jmc Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst +.\" Copyright (c) 2015 Joel Sing +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 2 2017 $ +.Dt TLS_CONFIG_VERIFY 3 +.Os +.Sh NAME +.Nm tls_config_verify , +.Nm tls_config_insecure_noverifycert , +.Nm tls_config_insecure_noverifyname , +.Nm tls_config_insecure_noverifytime +.Nd insecure TLS configuration +.Sh SYNOPSIS +.In tls.h +.Ft void +.Fn tls_config_verify "struct tls_config *config" +.Ft void +.Fn tls_config_insecure_noverifycert "struct tls_config *config" +.Ft void +.Fn tls_config_insecure_noverifyname "struct tls_config *config" +.Ft void +.Fn tls_config_insecure_noverifytime "struct tls_config *config" +.Sh DESCRIPTION +These functions disable parts of the normal certificate verification +process, resulting in insecure configurations. +Be very careful when using them. +.Pp +.Fn tls_config_insecure_noverifycert +disables certificate verification and OCSP validation. +.Pp +.Fn tls_config_insecure_noverifyname +disables server name verification (client only). +.Pp +.Fn tls_config_insecure_noverifytime +disables validity checking of certificates and OCSP validation. +.Pp +.Fn tls_config_verify +reenables server name and certificate verification. +.Sh SEE ALSO +.Xr tls_client 3 , +.Xr tls_config_ocsp_require_stapling 3 , +.Xr tls_config_set_protocols 3 , +.Xr tls_conn_version 3 , +.Xr tls_connect 3 , +.Xr tls_handshake 3 , +.Xr tls_init 3 +.Sh HISTORY +.Fn tls_config_verify +appeared in +.Ox 5.6 +and got its final name in +.Ox 5.7 . +.Pp +.Fn tls_config_insecure_noverifycert +and +.Fn tls_config_insecure_noverifyname +appeared in +.Ox 5.7 +and +.Nm tls_config_insecure_noverifytime +in +.Ox 5.9 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +.An Ted Unangst Aq Mt tedu@openbsd.org diff --git a/Libraries/libressl/man/tls_conn_version.3 b/Libraries/libressl/man/tls_conn_version.3 new file mode 100644 index 000000000..9ab6932f5 --- /dev/null +++ b/Libraries/libressl/man/tls_conn_version.3 @@ -0,0 +1,214 @@ +.\" $OpenBSD: tls_conn_version.3,v 1.10 2019/11/02 13:43:14 jsing Exp $ +.\" +.\" Copyright (c) 2015 Bob Beck +.\" Copyright (c) 2016, 2018 Joel Sing +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 2 2019 $ +.Dt TLS_CONN_VERSION 3 +.Os +.Sh NAME +.Nm tls_conn_version , +.Nm tls_conn_cipher , +.Nm tls_conn_cipher_strength , +.Nm tls_conn_alpn_selected , +.Nm tls_conn_servername , +.Nm tls_conn_session_resumed , +.Nm tls_peer_cert_provided , +.Nm tls_peer_cert_contains_name , +.Nm tls_peer_cert_chain_pem , +.Nm tls_peer_cert_issuer , +.Nm tls_peer_cert_subject , +.Nm tls_peer_cert_hash , +.Nm tls_peer_cert_notbefore , +.Nm tls_peer_cert_notafter +.Nd inspect an established TLS connection +.Sh SYNOPSIS +.In tls.h +.Ft const char * +.Fn tls_conn_version "struct tls *ctx" +.Ft const char * +.Fn tls_conn_cipher "struct tls *ctx" +.Ft int +.Fn tls_conn_cipher_strength "struct tls *ctx" +.Ft const char * +.Fn tls_conn_alpn_selected "struct tls *ctx" +.Ft const char * +.Fn tls_conn_servername "struct tls *ctx" +.Ft int +.Fn tls_conn_session_resumed "struct tls *ctx" +.Ft int +.Fn tls_peer_cert_provided "struct tls *ctx" +.Ft int +.Fo tls_peer_cert_contains_name +.Fa "struct tls *ctx" +.Fa "const char *name" +.Fc +.Ft const uint8_t * +.Fo tls_peer_cert_chain_pem +.Fa "struct tls *ctx" +.Fa "size_t *size" +.Fc +.Ft const char * +.Fn tls_peer_cert_issuer "struct tls *ctx" +.Ft const char * +.Fn tls_peer_cert_subject "struct tls *ctx" +.Ft const char * +.Fn tls_peer_cert_hash "struct tls *ctx" +.Ft time_t +.Fn tls_peer_cert_notbefore "struct tls *ctx" +.Ft time_t +.Fn tls_peer_cert_notafter "struct tls *ctx" +.Sh DESCRIPTION +These functions return information about a TLS connection and will only +succeed after the handshake is complete (the connection information applies +to both clients and servers, unless noted otherwise): +.Pp +.Fn tls_conn_version +returns a string corresponding to a TLS version negotiated with the peer +connected to +.Ar ctx . +.Pp +.Fn tls_conn_cipher +returns a string corresponding to the cipher suite negotiated with the peer +connected to +.Ar ctx . +.Pp +.Fn tls_conn_cipher_strength +returns the strength in bits for the symmetric cipher that is being +used with the peer connected to +.Ar ctx . +.Pp +.Fn tls_conn_alpn_selected +returns a string that specifies the ALPN protocol selected for use with the peer +connected to +.Ar ctx . +If no protocol was selected then NULL is returned. +.Pp +.Fn tls_conn_servername +returns a string corresponding to the servername that the client connected to +.Ar ctx +requested by sending a TLS Server Name Indication extension (server only). +.Pp +.Fn tls_conn_session_resumed +indicates whether a TLS session has been resumed during the handshake with +the server connected to +.Ar ctx +(client only). +.Pp +.Fn tls_peer_cert_provided +checks if the peer of +.Ar ctx +has provided a certificate. +.Pp +.Fn tls_peer_cert_contains_name +checks if the peer of a TLS +.Ar ctx +has provided a certificate that contains a +SAN or CN that matches +.Ar name . +.Pp +.Fn tls_peer_cert_chain_pem +returns a pointer to memory containing a PEM-encoded certificate chain for the +peer certificate from +.Ar ctx . +.Pp +.Fn tls_peer_cert_subject +returns a string +corresponding to the subject of the peer certificate from +.Ar ctx . +.Pp +.Fn tls_peer_cert_issuer +returns a string +corresponding to the issuer of the peer certificate from +.Ar ctx . +.Pp +.Fn tls_peer_cert_hash +returns a string +corresponding to a hash of the raw peer certificate from +.Ar ctx +prefixed by a hash name followed by a colon. +The hash currently used is SHA256, though this +could change in the future. +The hash string for a certificate in file +.Ar mycert.crt +can be generated using the commands: +.Bd -literal -offset indent +h=$(openssl x509 -outform der -in mycert.crt | sha256) +printf "SHA256:${h}\\n" +.Ed +.Pp +.Fn tls_peer_cert_notbefore +returns the time corresponding to the start of the validity period of +the peer certificate from +.Ar ctx . +.Pp +.Fn tls_peer_cert_notafter +returns the time corresponding to the end of the validity period of +the peer certificate from +.Ar ctx . +.Sh RETURN VALUES +The +.Fn tls_conn_session_resumed +function returns 1 if a TLS session was resumed or 0 if it was not. +.Pp +The +.Fn tls_peer_cert_provided +and +.Fn tls_peer_cert_contains_name +functions return 1 if the check succeeds or 0 if it does not. +.Pp +.Fn tls_peer_cert_notbefore +and +.Fn tls_peer_cert_notafter +return a time in epoch-seconds on success or -1 on error. +.Pp +The functions that return a pointer return +.Dv NULL +on error or an out of memory condition. +.Sh SEE ALSO +.Xr tls_configure 3 , +.Xr tls_handshake 3 , +.Xr tls_init 3 , +.Xr tls_ocsp_process_response 3 +.Sh HISTORY +.Fn tls_conn_version , +.Fn tls_conn_cipher , +.Fn tls_peer_cert_provided , +.Fn tls_peer_cert_contains_name , +.Fn tls_peer_cert_issuer , +.Fn tls_peer_cert_subject , +.Fn tls_peer_cert_hash , +.Fn tls_peer_cert_notbefore , +and +.Fn tls_peer_cert_notafter +appeared in +.Ox 5.9 . +.Pp +.Fn tls_conn_servername +and +.Fn tls_conn_alpn_selected +appeared in +.Ox 6.1 . +.Pp +.Fn tls_conn_session_resumed +appeared in +.Ox 6.3 . +.Pp +.Fn tls_conn_cipher_strength +appeared in +.Ox 6.7 . +.Sh AUTHORS +.An Bob Beck Aq Mt beck@openbsd.org +.An Joel Sing Aq Mt jsing@openbsd.org diff --git a/Libraries/libressl/man/tls_connect.3 b/Libraries/libressl/man/tls_connect.3 new file mode 100644 index 000000000..4c4f01c25 --- /dev/null +++ b/Libraries/libressl/man/tls_connect.3 @@ -0,0 +1,144 @@ +.\" $OpenBSD: tls_connect.3,v 1.4 2018/07/09 19:51:18 tb Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst +.\" Copyright (c) 2014, 2015 Joel Sing +.\" Copyright (c) 2016 Brent Cook +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 9 2018 $ +.Dt TLS_CONNECT 3 +.Os +.Sh NAME +.Nm tls_connect , +.Nm tls_connect_fds , +.Nm tls_connect_servername , +.Nm tls_connect_socket , +.Nm tls_connect_cbs +.Nd instruct a TLS client to establish a connection +.Sh SYNOPSIS +.In tls.h +.Ft int +.Fo tls_connect +.Fa "struct tls *ctx" +.Fa "const char *host" +.Fa "const char *port" +.Fc +.Ft int +.Fo tls_connect_fds +.Fa "struct tls *ctx" +.Fa "int fd_read" +.Fa "int fd_write" +.Fa "const char *servername" +.Fc +.Ft int +.Fo tls_connect_servername +.Fa "struct tls *ctx" +.Fa "const char *host" +.Fa "const char *port" +.Fa "const char *servername" +.Fc +.Ft int +.Fo tls_connect_socket +.Fa "struct tls *ctx" +.Fa "int s" +.Fa "const char *servername" +.Fc +.Ft int +.Fo tls_connect_cbs +.Fa "struct tls *ctx" +.Fa "ssize_t (*tls_read_cb)(struct tls *ctx,\ + void *buf, size_t buflen, void *cb_arg)" +.Fa "ssize_t (*tls_write_cb)(struct tls *ctx,\ + const void *buf, size_t buflen, void *cb_arg)" +.Fa "void *cb_arg" +.Fa "const char *servername" +.Fc +.Sh DESCRIPTION +After creating a TLS client context with +.Xr tls_client 3 +and configuring it with +.Xr tls_configure 3 , +a client connection is initiated by calling +.Fn tls_connect . +This function will create a new socket, connect to the specified +.Fa host +and +.Fa port , +and then establish a secure connection. +The +.Fa port +may be numeric or a service name. +If it is +.Dv NULL , +then a +.Fa host +of the format "hostname:port" is permitted. +The name to use for verification is inferred from the +.Ar host +value. +.Pp +The +.Fn tls_connect_servername +function has the same behaviour, however the name to use for verification is +explicitly provided, for the case where the TLS server name differs from the +DNS name. +.Pp +An already existing socket can be upgraded to a secure connection by calling +.Fn tls_connect_socket . +.Pp +Alternatively, a secure connection can be established over a pair of existing +file descriptors by calling +.Fn tls_connect_fds . +.Pp +Calling +.Fn tls_connect_cbs +allows read and write callback functions to handle data transfers. +The specified cb_arg parameter is passed back to the functions, +and can contain a pointer to any caller-specified data. +.Sh RETURN VALUES +These functions return 0 on success or -1 on error. +.Sh SEE ALSO +.Xr tls_accept_socket 3 , +.Xr tls_client 3 , +.Xr tls_close 3 , +.Xr tls_config_ocsp_require_stapling 3 , +.Xr tls_configure 3 , +.Xr tls_handshake 3 , +.Xr tls_init 3 +.Sh HISTORY +.Fn tls_connect +and +.Fn tls_connect_socket +appeared in +.Ox 5.6 +and got their final names in +.Ox 5.7 . +.Pp +.Fn tls_connect_fds +and +.Fn tls_connect_servername +appeared in +.Ox 5.7 +and +.Fn tls_connect_cbs +in +.Ox 6.1 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +.An Reyk Floeter Aq Mt reyk@openbsd.org +.Pp +.An -nosplit +.Fn tls_connect_cbs +was written by +.An Tobias Pape Aq Mt tobias@netshed.de . diff --git a/Libraries/libressl/man/tls_init.3 b/Libraries/libressl/man/tls_init.3 new file mode 100644 index 000000000..557998107 --- /dev/null +++ b/Libraries/libressl/man/tls_init.3 @@ -0,0 +1,180 @@ +.\" $OpenBSD: tls_init.3,v 1.13 2018/07/09 19:47:20 tb Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst +.\" Copyright (c) 2016 Joel Sing +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 9 2018 $ +.Dt TLS_INIT 3 +.Os +.Sh NAME +.Nm tls_init , +.Nm tls_config_new , +.Nm tls_config_free , +.Nm tls_config_error +.Nd initialize TLS client and server API +.Sh SYNOPSIS +.In tls.h +.Ft int +.Fn tls_init void +.Ft struct tls_config * +.Fn tls_config_new void +.Ft void +.Fn tls_config_free "struct tls_config *config" +.Ft const char * +.Fn tls_config_error "struct tls_config *config" +.Sh DESCRIPTION +The +.Nm tls +family of functions establishes a secure communications channel +using the TLS socket protocol. +Both clients and servers are supported. +.Pp +The +.Fn tls_init +function initializes global data structures. +It is no longer necessary to call this function directly, +since it is invoked internally when needed. +It may be called more than once, and may be called concurrently. +.Pp +Before a connection is created, a configuration must be created. +The +.Fn tls_config_new +function allocates, initializes, and returns a new default configuration +object that can be used for future connections. +Several functions exist to change the options of the configuration; see +.Xr tls_config_set_protocols 3 , +.Xr tls_load_file 3 , +.Xr tls_config_ocsp_require_stapling 3 , +and +.Xr tls_config_verify 3 . +.Pp +The +.Fn tls_config_error +function may be used to retrieve a string containing more information +about the most recent error relating to a configuration. +.Pp +A TLS connection object is created by +.Xr tls_client 3 +or +.Xr tls_server 3 +and configured with +.Xr tls_configure 3 . +.Pp +A client connection is initiated after configuration by calling +.Xr tls_connect 3 . +A server can accept a new client connection by calling +.Xr tls_accept_socket 3 +on an already established socket connection. +.Pp +Two functions are provided for input and output, +.Xr tls_read 3 +and +.Xr tls_write 3 . +Both automatically perform the +.Xr tls_handshake 3 +when needed. +.Pp +The properties of established TLS connections +can be inspected with the functions described in +.Xr tls_conn_version 3 +and +.Xr tls_ocsp_process_response 3 . +.Pp +After use, a TLS connection should be closed with +.Xr tls_close 3 +and then freed by calling +.Xr tls_free 3 . +.Pp +When no more contexts are to be configured, +the configuration object should be freed by calling +.Fn tls_config_free . +It is safe to call +.Fn tls_config_free +as soon as the final call to +.Fn tls_configure +has been made. +If +.Fa config +is +.Dv NULL , +no action occurs. +.Sh RETURN VALUES +.Fn tls_init +returns 0 on success or -1 on error. +.Pp +.Fn tls_config_new +returns +.Dv NULL +on error or an out of memory condition. +.Pp +.Fn tls_config_error +returns +.Dv NULL +if no error occurred with +.Fa config +at all, or if memory allocation failed while trying to assemble the +string describing the most recent error related to +.Fa config . +.Sh SEE ALSO +.Xr tls_accept_socket 3 , +.Xr tls_client 3 , +.Xr tls_config_ocsp_require_stapling 3 , +.Xr tls_config_set_protocols 3 , +.Xr tls_config_verify 3 , +.Xr tls_conn_version 3 , +.Xr tls_connect 3 , +.Xr tls_load_file 3 , +.Xr tls_ocsp_process_response 3 , +.Xr tls_read 3 +.Sh HISTORY +The +.Nm tls +API first appeared in +.Ox 5.6 +as a response to the unnecessary challenges other APIs present in +order to use them safely. +.Pp +All functions were renamed from +.Fn ressl_* +to +.Fn tls_* +for +.Ox 5.7 . +.Pp +.Fn tls_config_error +appeared in +.Ox 6.0 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +.An Ted Unangst Aq Mt tedu@openbsd.org +.Pp +Many others contributed to various parts of the library; see the +individual manual pages for more information. +.Sh CAVEATS +The function +.Fn tls_config_error +returns an internal pointer. +It must not be freed by the application, or a double free error +will occur. +The pointer will become invalid when the next error occurs with +.Fa config . +Consequently, if the application may need the message at a later +time, it has to copy the string before calling the next +.Sy libtls +function involving +.Fa config , +or a segmentation fault or read access to unintended data is the +likely result. diff --git a/Libraries/libressl/man/tls_load_file.3 b/Libraries/libressl/man/tls_load_file.3 new file mode 100644 index 000000000..cf33b575e --- /dev/null +++ b/Libraries/libressl/man/tls_load_file.3 @@ -0,0 +1,369 @@ +.\" $OpenBSD: tls_load_file.3,v 1.14 2022/01/01 02:18:28 jsg Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst +.\" Copyright (c) 2015 Reyk Floeter +.\" Copyright (c) 2015 Bob Beck +.\" Copyright (c) 2016, 2017 Joel Sing +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: January 1 2022 $ +.Dt TLS_LOAD_FILE 3 +.Os +.Sh NAME +.Nm tls_load_file , +.Nm tls_unload_file , +.Nm tls_config_set_ca_file , +.Nm tls_config_set_ca_path , +.Nm tls_config_set_ca_mem , +.Nm tls_config_set_cert_file , +.Nm tls_config_set_cert_mem , +.Nm tls_config_set_crl_file , +.Nm tls_config_set_crl_mem , +.Nm tls_config_set_key_file , +.Nm tls_config_set_key_mem , +.Nm tls_config_set_ocsp_staple_mem , +.Nm tls_config_set_ocsp_staple_file , +.Nm tls_config_set_keypair_file , +.Nm tls_config_set_keypair_mem , +.Nm tls_config_set_keypair_ocsp_file , +.Nm tls_config_set_keypair_ocsp_mem , +.Nm tls_config_add_keypair_file , +.Nm tls_config_add_keypair_ocsp_mem , +.Nm tls_config_add_keypair_ocsp_file , +.Nm tls_config_add_keypair_mem , +.Nm tls_config_clear_keys , +.Nm tls_config_set_verify_depth , +.Nm tls_config_verify_client , +.Nm tls_config_verify_client_optional , +.Nm tls_default_ca_cert_file +.Nd TLS certificate and key configuration +.Sh SYNOPSIS +.In tls.h +.Ft uint8_t * +.Fo tls_load_file +.Fa "const char *file" +.Fa "size_t *len" +.Fa "char *password" +.Fc +.Ft void +.Fo tls_unload_file +.Fa "uint8_t *buf" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_ca_file +.Fa "struct tls_config *config" +.Fa "const char *ca_file" +.Fc +.Ft int +.Fo tls_config_set_ca_path +.Fa "struct tls_config *config" +.Fa "const char *ca_path" +.Fc +.Ft int +.Fo tls_config_set_ca_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *cert" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_cert_file +.Fa "struct tls_config *config" +.Fa "const char *cert_file" +.Fc +.Ft int +.Fo tls_config_set_cert_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *cert" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_crl_file +.Fa "struct tls_config *config" +.Fa "const char *crl_file" +.Fc +.Ft int +.Fo tls_config_set_crl_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *crl" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_key_file +.Fa "struct tls_config *config" +.Fa "const char *key_file" +.Fc +.Ft int +.Fo tls_config_set_key_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *key" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_ocsp_staple_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *staple" +.Fa "size_t len" +.Fc +.Ft int +.Fo tls_config_set_ocsp_staple_file +.Fa "struct tls_config *config" +.Fa "const char *staple_file" +.Fc +.Ft int +.Fo tls_config_set_keypair_file +.Fa "struct tls_config *config" +.Fa "const char *cert_file" +.Fa "const char *key_file" +.Fc +.Ft int +.Fo tls_config_set_keypair_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *cert" +.Fa "size_t cert_len" +.Fa "const uint8_t *key" +.Fa "size_t key_len" +.Fc +.Ft int +.Fo tls_config_set_keypair_ocsp_file +.Fa "struct tls_config *config" +.Fa "const char *cert_file" +.Fa "const char *key_file" +.Fa "const char *staple_file" +.Fc +.Ft int +.Fo tls_config_set_keypair_ocsp_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *cert" +.Fa "size_t cert_len" +.Fa "const uint8_t *key" +.Fa "size_t key_len" +.Fa "const uint8_t *staple" +.Fa "size_t staple_len" +.Fc +.Ft int +.Fo tls_config_add_keypair_file +.Fa "struct tls_config *config" +.Fa "const char *cert_file" +.Fa "const char *key_file" +.Fc +.Ft int +.Fo tls_config_add_keypair_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *cert" +.Fa "size_t cert_len" +.Fa "const uint8_t *key" +.Fa "size_t key_len" +.Fc +.Ft int +.Fo tls_config_add_keypair_ocsp_file +.Fa "struct tls_config *config" +.Fa "const char *cert_file" +.Fa "const char *key_file" +.Fa "const char *staple_file" +.Fc +.Ft int +.Fo tls_config_add_keypair_ocsp_mem +.Fa "struct tls_config *config" +.Fa "const uint8_t *cert" +.Fa "size_t cert_len" +.Fa "const uint8_t *key" +.Fa "size_t key_len" +.Fa "const uint8_t *staple" +.Fa "size_t staple_len" +.Fc +.Ft void +.Fn tls_config_clear_keys "struct tls_config *config" +.Ft int +.Fo tls_config_set_verify_depth +.Fa "struct tls_config *config" +.Fa "int verify_depth" +.Fc +.Ft void +.Fn tls_config_verify_client "struct tls_config *config" +.Ft void +.Fn tls_config_verify_client_optional "struct tls_config *config" +.Ft const char * +.Fn tls_default_ca_cert_file "void" +.Sh DESCRIPTION +.Fn tls_load_file +loads a certificate or key from disk into memory to be used with +.Fn tls_config_set_ca_mem , +.Fn tls_config_set_cert_mem , +.Fn tls_config_set_crl_mem +or +.Fn tls_config_set_key_mem . +A private key will be decrypted if the optional +.Ar password +argument is specified. +.Pp +.Fn tls_unload_file +unloads the memory that was returned from an earlier +.Fn tls_load_file +call, ensuring that the memory contents is discarded. +.Pp +.Fn tls_default_ca_cert_file +returns the path of the file that contains the default root certificates. +.Pp +.Fn tls_config_set_ca_file +loads a file containing the root certificates. +.Pp +.Fn tls_config_set_ca_path +sets the path (directory) which should be searched for root +certificates. +.Pp +.Fn tls_config_set_ca_mem +sets the root certificates directly from memory. +.Pp +.Fn tls_config_set_cert_file +loads a file containing the public certificate. +.Pp +.Fn tls_config_set_cert_mem +sets the public certificate directly from memory. +.Pp +.Fn tls_config_set_crl_file +loads a file containing the Certificate Revocation List (CRL). +.Pp +.Fn tls_config_set_crl_mem +sets the CRL directly from memory. +.Pp +.Fn tls_config_set_key_file +loads a file containing the private key. +.Pp +.Fn tls_config_set_key_mem +directly sets the private key from memory. +.Pp +.Fn tls_config_set_ocsp_staple_file +loads a file containing a DER-encoded OCSP response to be stapled +during the TLS handshake. +.Pp +.Fn tls_config_set_ocsp_staple_mem +sets a DER-encoded OCSP response to be stapled during the TLS handshake from +memory. +.Pp +.Fn tls_config_set_keypair_file +loads two files from which the public certificate and private key will be read. +.Pp +.Fn tls_config_set_keypair_mem +directly sets the public certificate and private key from memory. +.Pp +.Fn tls_config_set_keypair_ocsp_file +loads three files containing the public certificate, private key, +and DER-encoded OCSP staple. +.Pp +.Fn tls_config_set_keypair_ocsp_mem +directly sets the public certificate, private key, and DER-encoded OCSP staple +from memory. +.Pp +.Fn tls_config_add_keypair_file +adds an additional public certificate and private key from the specified files, +used as an alternative certificate for Server Name Indication (server only). +.Pp +.Fn tls_config_add_keypair_mem +adds an additional public certificate and private key from memory, used as an +alternative certificate for Server Name Indication (server only). +.Pp +.Fn tls_config_add_keypair_ocsp_file +adds an additional public certificate, private key, and DER-encoded OCSP staple +from the specified files, used as an alternative certificate for Server Name +Indication (server only). +.Pp +.Fn tls_config_add_keypair_ocsp_mem +adds an additional public certificate, private key, and DER-encoded OCSP staple +from memory, used as an alternative certificate for Server Name Indication +(server only). +.Pp +.Fn tls_config_clear_keys +clears any secret keys from memory. +.Pp +.Fn tls_config_set_verify_depth +limits the number of intermediate certificates that will be followed during +certificate validation. +.Pp +.Fn tls_config_verify_client +enables client certificate verification, requiring the client to send +a certificate (server only). +.Pp +.Fn tls_config_verify_client_optional +enables client certificate verification, without requiring the client +to send a certificate (server only). +.Sh RETURN VALUES +.Fn tls_load_file +returns +.Dv NULL +on error or an out of memory condition. +.Pp +The other functions return 0 on success or -1 on error. +.Sh SEE ALSO +.Xr tls_config_ocsp_require_stapling 3 , +.Xr tls_config_set_protocols 3 , +.Xr tls_config_set_session_id 3 , +.Xr tls_configure 3 , +.Xr tls_init 3 +.Sh HISTORY +.Fn tls_config_set_ca_file , +.Fn tls_config_set_ca_path , +.Fn tls_config_set_cert_file , +.Fn tls_config_set_cert_mem , +.Fn tls_config_set_key_file , +.Fn tls_config_set_key_mem , +and +.Fn tls_config_set_verify_depth +appeared in +.Ox 5.6 +and got their final names in +.Ox 5.7 . +.Pp +.Fn tls_load_file , +.Fn tls_config_set_ca_mem , +and +.Fn tls_config_clear_keys +appeared in +.Ox 5.7 . +.Pp +.Fn tls_config_verify_client +and +.Fn tls_config_verify_client_optional +appeared in +.Ox 5.9 . +.Pp +.Fn tls_config_set_keypair_file +and +.Fn tls_config_set_keypair_mem +appeared in +.Ox 6.0 , +and +.Fn tls_config_add_keypair_file +and +.Fn tls_config_add_keypair_mem +in +.Ox 6.1 . +.Pp +.Fn tls_config_set_crl_file +and +.Fn tls_config_set_crl_mem +appeared in +.Ox 6.2 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +with contributions from +.An Ted Unangst Aq Mt tedu@openbsd.org +and +.An Bob Beck Aq Mt beck@openbsd.org . +.Pp +.Fn tls_load_file +and +.Fn tls_config_set_ca_mem +were written by +.An Reyk Floeter Aq Mt reyk@openbsd.org . diff --git a/Libraries/libressl/man/tls_ocsp_process_response.3 b/Libraries/libressl/man/tls_ocsp_process_response.3 new file mode 100644 index 000000000..6e3aa4aec --- /dev/null +++ b/Libraries/libressl/man/tls_ocsp_process_response.3 @@ -0,0 +1,167 @@ +.\" $OpenBSD: tls_ocsp_process_response.3,v 1.6 2018/07/24 02:01:34 tb Exp $ +.\" +.\" Copyright (c) 2016 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: July 24 2018 $ +.Dt TLS_OCSP_PROCESS_RESPONSE 3 +.Os +.Sh NAME +.Nm tls_ocsp_process_response , +.Nm tls_peer_ocsp_url , +.Nm tls_peer_ocsp_response_status , +.Nm tls_peer_ocsp_cert_status , +.Nm tls_peer_ocsp_crl_reason , +.Nm tls_peer_ocsp_result , +.Nm tls_peer_ocsp_revocation_time , +.Nm tls_peer_ocsp_this_update , +.Nm tls_peer_ocsp_next_update +.Nd inspect an OCSP response +.Sh SYNOPSIS +.In tls.h +.Ft int +.Fo tls_ocsp_process_response +.Fa "struct tls *ctx" +.Fa "const unsigned char *response" +.Fa "size_t size" +.Fc +.Ft const char * +.Fn tls_peer_ocsp_url "struct tls *ctx" +.Ft int +.Fn tls_peer_ocsp_response_status "struct tls *ctx" +.Ft int +.Fn tls_peer_ocsp_cert_status "struct tls *ctx" +.Ft int +.Fn tls_peer_ocsp_crl_reason "struct tls *ctx" +.Ft const char * +.Fn tls_peer_ocsp_result "struct tls *ctx" +.Ft time_t +.Fn tls_peer_ocsp_revocation_time "struct tls *ctx" +.Ft time_t +.Fn tls_peer_ocsp_this_update "struct tls *ctx" +.Ft time_t +.Fn tls_peer_ocsp_next_update "struct tls *ctx" +.Sh DESCRIPTION +.Fn tls_ocsp_process_response +processes a raw OCSP response in +.Ar response +of size +.Ar size +to check the revocation status of the peer certificate from +.Ar ctx . +A successful return code of 0 indicates that the certificate +has not been revoked. +.Pp +.Fn tls_peer_ocsp_url +returns the URL for OCSP validation of the peer certificate from +.Ar ctx . +.Pp +The following functions return information about the peer certificate from +.Ar ctx +that was obtained by validating a stapled OCSP response during the handshake, +or via a previous call to +.Fn tls_ocsp_process_response . +.Pp +.Fn tls_peer_ocsp_response_status +returns the OCSP response status as per RFC 6960 section 2.3. +.Pp +.Fn tls_peer_ocsp_cert_status +returns the OCSP certificate status code as per RFC 6960 section 2.2. +.Pp +.Fn tls_peer_ocsp_crl_reason +returns the OCSP certificate revocation reason status code as per RFC 5280 +section 5.3.1. +.Pp +.Fn tls_peer_ocsp_result +returns a textual representation of the OCSP status code +returned by one of the previous three functions. +If the OCSP response was valid and the certificate was not +revoked, the string indicates the OCSP certificate status. +Otherwise, the string indicates +the OCSP certificate revocation reason or the OCSP error. +.Pp +.Fn tls_peer_ocsp_revocation_time +returns the OCSP revocation time. +.Pp +.Fn tls_peer_ocsp_this_update +returns the OCSP this update time. +.Pp +.Fn tls_peer_ocsp_next_update +returns the OCSP next update time. +.Sh RETURN VALUES +.Fn tls_ocsp_process_response +returns 0 on success or -1 on error. +.Pp +.Fn tls_peer_ocsp_url +and +.Fn tls_peer_ocsp_result +return +.Dv NULL +on error or an out of memory condition. +.Pp +The +.Fn tls_peer_ocsp_response_status +function returns one of +.Dv TLS_OCSP_RESPONSE_SUCCESSFUL , +.Dv TLS_OCSP_RESPONSE_MALFORMED , +.Dv TLS_OCSP_RESPONSE_INTERNALERROR , +.Dv TLS_OCSP_RESPONSE_TRYLATER , +.Dv TLS_OCSP_RESPONSE_SIGREQUIRED , +or +.Dv TLS_OCSP_RESPONSE_UNAUTHORIZED +on success or -1 on error. +.Pp +The +.Fn tls_peer_ocsp_cert_status +function returns one of +.Dv TLS_OCSP_CERT_GOOD , +.Dv TLS_OCSP_CERT_REVOKED , +or +.Dv TLS_OCSP_CERT_UNKNOWN +on success, and -1 on error. +.Pp +The +.Fn tls_peer_ocsp_crl_reason +function returns one of +.Dv TLS_CRL_REASON_UNSPECIFIED , +.Dv TLS_CRL_REASON_KEY_COMPROMISE , +.Dv TLS_CRL_REASON_CA_COMPROMISE , +.Dv TLS_CRL_REASON_AFFILIATION_CHANGED , +.Dv TLS_CRL_REASON_SUPERSEDED , +.Dv TLS_CRL_REASON_CESSATION_OF_OPERATION , +.Dv TLS_CRL_REASON_CERTIFICATE_HOLD , +.Dv TLS_CRL_REASON_REMOVE_FROM_CRL , +.Dv TLS_CRL_REASON_PRIVILEGE_WITHDRAWN , +or +.Dv TLS_CRL_REASON_AA_COMPROMISE +on success or -1 on error. +.Pp +.Fn tls_peer_ocsp_revocation_time , +.Fn tls_peer_ocsp_this_update , +and +.Fn tls_peer_ocsp_next_update +return a time in epoch-seconds on success or -1 on error. +.Sh SEE ALSO +.Xr tls_client 3 , +.Xr tls_config_ocsp_require_stapling 3 , +.Xr tls_conn_version 3 , +.Xr tls_connect 3 , +.Xr tls_handshake 3 , +.Xr tls_init 3 +.Sh HISTORY +These functions appeared in +.Ox 6.1 . +.Sh AUTHORS +.An Bob Beck Aq Mt beck@openbsd.org +.An Marko Kreen Aq Mt markokr@gmail.com diff --git a/Libraries/libressl/man/tls_read.3 b/Libraries/libressl/man/tls_read.3 new file mode 100644 index 000000000..f9d949eef --- /dev/null +++ b/Libraries/libressl/man/tls_read.3 @@ -0,0 +1,240 @@ +.\" $OpenBSD: tls_read.3,v 1.8 2023/09/18 17:25:15 schwarze Exp $ +.\" +.\" Copyright (c) 2014, 2015 Ted Unangst +.\" Copyright (c) 2015 Doug Hogan +.\" Copyright (c) 2015 Joel Sing +.\" Copyright (c) 2015 Bob Beck +.\" Copyright (c) 2017 Ingo Schwarze +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 18 2023 $ +.Dt TLS_READ 3 +.Os +.Sh NAME +.Nm tls_read , +.Nm tls_write , +.Nm tls_handshake , +.Nm tls_error , +.Nm tls_close +.Nd use a TLS connection +.Sh SYNOPSIS +.In tls.h +.Ft ssize_t +.Fo tls_read +.Fa "struct tls *ctx" +.Fa "void *buf" +.Fa "size_t buflen" +.Fc +.Ft ssize_t +.Fo tls_write +.Fa "struct tls *ctx" +.Fa "const void *buf" +.Fa "size_t buflen" +.Fc +.Ft int +.Fn tls_handshake "struct tls *ctx" +.Ft const char * +.Fn tls_error "struct tls *ctx" +.Ft int +.Fn tls_close "struct tls *ctx" +.Sh DESCRIPTION +.Fn tls_read +reads +.Fa buflen +bytes of data from the socket into +.Fa buf . +It returns the amount of data read. +.Pp +.Fn tls_write +writes +.Fa buflen +bytes of data from +.Fa buf +to the socket. +It returns the amount of data written. +.Pp +.Fn tls_handshake +explicitly performs the TLS handshake. +It is only necessary to call this function if you need to guarantee that the +handshake has completed, as both +.Fn tls_read +and +.Fn tls_write +automatically perform the TLS handshake when necessary. +.Pp +The +.Fn tls_error +function may be used to retrieve a string containing more information +about the most recent error relating to a context. +.Pp +.Fn tls_close +closes a connection after use. +Only the TLS layer will be shut down and the caller is responsible for closing +the file descriptors, unless the connection was established using +.Xr tls_connect 3 +or +.Xr tls_connect_servername 3 . +After closing the connection, +.Fa ctx +can be passed to +.Xr tls_free 3 . +.Sh RETURN VALUES +.Fn tls_read +and +.Fn tls_write +return a size on success or -1 on error. +.Pp +.Fn tls_handshake +and +.Fn tls_close +return 0 on success or -1 on error. +.Pp +The +.Fn tls_read , +.Fn tls_write , +.Fn tls_handshake , +and +.Fn tls_close +functions also have two special return values: +.Pp +.Bl -tag -width "TLS_WANT_POLLOUT" -offset indent -compact +.It Dv TLS_WANT_POLLIN +The underlying read file descriptor needs to be readable in order to continue. +.It Dv TLS_WANT_POLLOUT +The underlying write file descriptor needs to be writeable in order to continue. +.El +.Pp +In the case of blocking file descriptors, the same function call should be +repeated immediately. +In the case of non-blocking file descriptors, the same function call should be +repeated when the required condition has been met. +.Pp +Callers of these functions cannot rely on the value of the global +.Ar errno . +To prevent mishandling of error conditions, +.Fn tls_read , +.Fn tls_write , +.Fn tls_handshake , +and +.Fn tls_close +all explicitly clear +.Ar errno . +.Pp +.Fn tls_error +returns +.Dv NULL +if no error occurred with +.Fa ctx +during or since the last call to +.Fn tls_handshake , +.Fn tls_read , +.Fn tls_write , +.Fn tls_close , +or +.Xr tls_reset 3 +involving +.Fa ctx , +or if memory allocation failed while trying to assemble the string +describing the most recent error related to +.Fa ctx . +.Sh EXAMPLES +The following example demonstrates how to handle TLS writes on a blocking +file descriptor: +.Bd -literal -offset indent +\&... +while (len > 0) { + ssize_t ret; + + ret = tls_write(ctx, buf, len); + if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) + continue; + if (ret == -1) + errx(1, "tls_write: %s", tls_error(ctx)); + buf += ret; + len -= ret; +} +\&... +.Ed +.Pp +The following example demonstrates how to handle TLS writes on a +non-blocking file descriptor using +.Xr poll 2 : +.Bd -literal -offset indent +\&... +pfd[0].fd = fd; +pfd[0].events = POLLIN|POLLOUT; +while (len > 0) { + nready = poll(pfd, 1, 0); + if (nready == -1) + err(1, "poll"); + if ((pfd[0].revents & (POLLERR|POLLNVAL))) + errx(1, "bad fd %d", pfd[0].fd); + if ((pfd[0].revents & (pfd[0].events|POLLHUP))) { + ssize_t ret; + + ret = tls_write(ctx, buf, len); + if (ret == TLS_WANT_POLLIN) + pfd[0].events = POLLIN; + else if (ret == TLS_WANT_POLLOUT) + pfd[0].events = POLLOUT; + else if (ret == -1) + errx(1, "tls_write: %s", tls_error(ctx)); + else { + buf += ret; + len -= ret; + } + } +} +\&... +.Ed +.Sh SEE ALSO +.Xr tls_accept_socket 3 , +.Xr tls_configure 3 , +.Xr tls_conn_version 3 , +.Xr tls_connect 3 , +.Xr tls_init 3 , +.Xr tls_ocsp_process_response 3 +.Sh HISTORY +.Fn tls_read , +.Fn tls_write , +.Fn tls_error , +and +.Fn tls_close +appeared in +.Ox 5.6 +and got their final names in +.Ox 5.7 . +.Pp +.Fn tls_handshake +appeared in +.Ox 5.9 . +.Sh AUTHORS +.An Joel Sing Aq Mt jsing@openbsd.org +with contributions from +.An Bob Beck Aq Mt beck@openbsd.org +.Sh CAVEATS +The function +.Fn tls_error +returns an internal pointer. +It must not be freed by the application, or a double free error +will occur. +The pointer will become invalid when the next error occurs with +.Fa ctx . +Consequently, if the application may need the message at a later +time, it has to copy the string before calling the next +.Sy libtls +function involving +.Fa ctx , +or a segmentation fault or read access to unintended data is the +likely result. diff --git a/Libraries/libressl/man/x509_verify.3 b/Libraries/libressl/man/x509_verify.3 new file mode 100644 index 000000000..b9fe13a54 --- /dev/null +++ b/Libraries/libressl/man/x509_verify.3 @@ -0,0 +1,221 @@ +.\" $OpenBSD: x509_verify.3,v 1.2 2020/09/14 14:21:46 schwarze Exp $ +.\" +.\" Copyright (c) 2020 Bob Beck +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 14 2020 $ +.Dt X509_VERIFY 3 +.Os +.Sh NAME +.Nm x509_verify , +.Nm x509_verify_ctx_new , +.Nm x509_verify_ctx_free , +.Nm x509_verify_ctx_set_max_depth , +.Nm x509_verify_ctx_set_max_signatures , +.Nm x509_verify_ctx_set_max_chains , +.Nm x509_verify_ctx_set_purpose , +.Nm x509_verify_ctx_set_intermediates , +.Nm x509_verify_ctx_error_string , +.Nm x509_verify_ctx_error_depth , +.Nm x509_verify_ctx_chain +.Nd discover and verify X.509 certificate chains +.Sh SYNOPSIS +.In openssl/x509_verify.h +.Ft size_t +.Fo x509_verify +.Fa "X509_VERIFY_CTX *ctx" +.Fa "X509 *leaf" +.Fa "char *name" +.Fc +.Ft X509_VERIFY_CTX * +.Fo x509_verify_ctx_new +.Fa "STACK_OF(X509) *roots" +.Fc +.Ft void +.Fo x509_verify_ctx_free +.Fa "X509_VERIFY_CTX *ctx" +.Fc +.Ft int +.Fo x509_verify_ctx_set_max_depth +.Fa "X509_VERIFY_CTX *ctx" +.Fa "size_t max" +.Fc +.Ft int +.Fo x509_verify_ctx_set_max_signatures +.Fa "X509_VERIFY_CTX *ctx" +.Fa "size_t max" +.Fc +.Ft int +.Fo x509_verify_ctx_set_max_chains +.Fa "X509_VERIFY_CTX *ctx" +.Fa "size_t max" +.Fc +.Ft int +.Fo x509_verify_ctx_set_purpose +.Fa "X509_VERIFY_CTX *ctx" +.Fa "int purpose_id" +.Fc +.Ft int +.Fo x509_verify_ctx_set_intermediates +.Fa "X509_VERIFY_CTX *ctx" +.Fa "STACK_OF(X509) *intermediates" +.Fc +.Ft const char * +.Fo x509_verify_ctx_error_string +.Fa "X509_VERIFY_CTX *ctx" +.Fc +.Ft size_t +.Fo x509_verify_ctx_error_depth +.Fa "X509_VERIFY_CTX *ctx" +.Fc +.Ft STACK_OF(X509) * +.Fo x509_verify_ctx_chain +.Fa "X509_VERIFY_CTX *ctx" +.Fa "size_t index" +.Fc +.Sh DESCRIPTION +The +.Fn x509_verify +function attempts to discover and validate all certificate chains +for the +.Fa name +from the +.Fa leaf +certificate based on the parameters in +.Fa ctx . +Multiple chains may be built and validated. +Revocation checking is not done by this function, and should be +performed by the caller on any returned chains if so desired. +.Pp +.Fn x509_verify_ctx_new +allocates a new context using the trusted +.Fa roots . +In case of success, it increments the reference count of +.Fa roots . +.Pp +.Fn x509_verify_ctx_free +frees +.Fa ctx +and decrements the reference count of the +.Fa roots +and +.Fa intermediates +associated with it. +If +.Fa ctx +is +.Dv NULL , +no action occurs. +.Pp +.Fn x509_verify_ctx_set_max_depth +sets the maximum depth of certificate chains that will be constructed to +.Fa max , +which can be in the range from 1 to the default of 32. +.Pp +.Fn x509_verify_ctx_set_max_signatures +sets the maximum number of public key signature operations that will be +used when verifying certificate chains to +.Fa max , +which can be in the range from 1 to 100000. +The default is 256. +.Pp +.Fn x509_verify_ctx_set_max_chains +sets the maximum number of chains which may be returned to +.Fa max , +which can be in the range from 1 to the default of 8. +.Pp +.Fn x509_verify_ctx_set_purpose +sets the certificate purpose for validation to +.Fa purpose_id . +The +.Dv X509_PURPOSE_* +constants listed in +.Xr X509_check_purpose 3 +can be used. +.Pp +.Fn x509_verify_ctx_set_intermediates +provides some intermediate certificates, typically received from +the peer, to be used for building chains. +In case of success, this function increases the reference count of +.Fa intermediates . +.Pp +.Fn x509_verify_ctx_error_string +extracts a description of the last error encountered by a previous +call to +.Fn x509_verify +from +.Fa ctx . +.Pp +.Fn x509_verify_ctx_error_depth +extracts the depth of the last error encountered by a previous +call to +.Fn x509_verify +from +.Fa ctx . +.Pp +.Fn x509_verify_ctx_chain +extracts the validated chain with the given +.Fa index +from +.Fa ctx +after a previous call to +.Fn x509_verify . +The +.Fa index +starts at 0, and it is an error to pass a number +greater than or equal to the return value of +.Fn x509_verify . +The returned chain is neither copied, +nor is its reference count increased. +.Sh RETURN VALUES +.Fn x509_verify +returns the number of chains successfully built and validated +or 0 on failure. +.Pp +.Fn x509_verify_ctx_new +returns a newly allocated context or +.Dv NULL +on failure. +.Pp +.Fn x509_verify_ctx_set_max_depth , +.Fn x509_verify_ctx_set_max_signatures , +.Fn x509_verify_ctx_set_max_chains , +.Fn x509_verify_ctx_set_purpose , +and +.Fn x509_verify_ctx_set_intermediates +return 1 on success or 0 on failure. +.Pp +.Fn x509_verify_ctx_error_string +returns a pointer to a human readable error string. +If no error occurred, +.Qq ok +is returned. +.Pp +.Fn x509_verify_ctx_chain +returns an internal pointer to a validated chain or +.Dv NULL +if +.Fa index +is greater than or equal to the number of chains +that were successfully built and validated. +The returned pointer becomes invalid when +.Fa ctx +is destroyed. +.Sh SEE ALSO +.Xr X509_verify_cert 3 +.Sh HISTORY +These functions first appeared in +.Ox 6.8 . +.Sh AUTHORS +.An Bob Beck Aq Mt beck@openbsd.org diff --git a/Libraries/libressl/man/x509v3.cnf.5 b/Libraries/libressl/man/x509v3.cnf.5 new file mode 100644 index 000000000..89f52d6a0 --- /dev/null +++ b/Libraries/libressl/man/x509v3.cnf.5 @@ -0,0 +1,738 @@ +.\" $OpenBSD: x509v3.cnf.5,v 1.8 2022/03/31 17:27:17 naddy Exp $ +.\" full merge up to: +.\" OpenSSL man5/x509v3_config a41815f0 Mar 17 18:43:53 2017 -0700 +.\" selective merge up to: OpenSSL 36cf10cf Oct 4 02:11:08 2017 -0400 +.\" +.\" This file was written by Dr. Stephen Henson . +.\" Copyright (c) 2004, 2006, 2013, 2014, 2015, 2016 The OpenSSL Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. All advertising materials mentioning features or use of this +.\" software must display the following acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate: March 31 2022 $ +.Dt X509V3.CNF 5 +.Os +.Sh NAME +.Nm x509v3.cnf +.Nd X.509 V3 certificate extension configuration format +.Sh DESCRIPTION +Several of the OpenSSL utilities can add extensions to a certificate or +certificate request based on the contents of a configuration file. +The file format is based on the +.Xr openssl.cnf 5 +format. +.Pp +Typically the application will contain an option to point to an +extension section. +Each line of the extension section takes the form: +.Pp +.D1 Ar extension_name Ns = Ns Oo Cm critical , Oc Ar extension_options +.Pp +If +.Cm critical +is present, then the extension will be critical. +.Pp +The format of +.Ar extension_options +depends on the value of +.Ar extension_name . +.Pp +There are four main types of extension: string extensions, multi-valued +extensions, raw extensions, and arbitrary extensions. +.Pp +String extensions simply have a string which contains either the value +itself or how it is obtained. +For example: +.Pp +.Dl nsComment="This is a Comment" +.Pp +Multi-valued extensions have a short form and a long form. +The short form is a list of names and values: +.Pp +.Dl basicConstraints=critical,CA:true,pathlen:1 +.Pp +The long form allows the values to be placed in a separate section: +.Bd -literal -offset indent +basicConstraints=critical,@bs_section + +[bs_section] +CA=true +pathlen=1 +.Ed +.Pp +Both forms are equivalent. +.Pp +The syntax of raw extensions is governed by the extension code: +it can for example contain data in multiple sections. +The correct syntax to use is defined by the extension code itself: +check out the certificate policies extension for an example. +.Pp +If an extension type is unsupported, then the arbitrary extension +syntax must be used; see the +.Sx ARBITRARY EXTENSIONS +section for more details. +.Sh STANDARD EXTENSIONS +The following sections describe each supported extension in detail. +.Ss Basic constraints +This is a multi-valued extension which indicates whether a certificate +is a CA certificate. +The first (mandatory) name is +.Ic CA +followed by +.Cm TRUE +or +.Cm FALSE . +If +.Ic CA +is +.Cm TRUE , +then an optional +.Ic pathlen +name followed by a non-negative value can be included. +For example: +.Bd -literal -offset indent +basicConstraints=CA:TRUE +basicConstraints=CA:FALSE +basicConstraints=critical,CA:TRUE, pathlen:0 +.Ed +.Pp +A CA certificate must include the +.Ic basicConstraints +value with the +.Ic CA +field set to +.Cm TRUE . +An end user certificate must either set +.Ic CA +to +.Cm FALSE +or exclude the extension entirely. +Some software may require the inclusion of +.Ic basicConstraints +with +.Ic CA +set to +.Cm FALSE +for end entity certificates. +.Pp +The +.Ic pathlen +parameter indicates the maximum number of CAs that can appear below +this one in a chain. +So if you have a CA with a +.Ic pathlen +of zero, it can only be used to sign end user certificates and not +further CAs. +.Ss Key usage +Key usage is a multi-valued extension consisting of a list of names of +the permitted key usages. +.Pp +The supported names are: +.Ic digitalSignature , +.Ic nonRepudiation , +.Ic keyEncipherment , +.Ic dataEncipherment , +.Ic keyAgreement , +.Ic keyCertSign , +.Ic cRLSign , +.Ic encipherOnly , +and +.Ic decipherOnly . +Examples: +.Bd -literal -offset indent +keyUsage=digitalSignature, nonRepudiation +keyUsage=critical, keyCertSign +.Ed +.Ss Extended key usage +This extension consists of a list of purposes for +which the certificate public key can be used. +.Pp +These can either be object short names or the dotted numerical form of OIDs. +While any OID can be used, only certain values make sense. +In particular the following PKIX, NS and MS values are meaningful: +.Bl -column emailProtection +.It Em value Ta Em meaning +.It Ic serverAuth Ta TLS server authentication +.It Ic clientAuth Ta TLS client authentication +.It Ic codeSigning Ta code signing +.It Ic emailProtection Ta E-mail protection (S/MIME) +.It Ic timeStamping Ta trusted timestamping +.It Ic OCSPSigning Ta OCSP signing +.It Ic ipsecIKE Ta IPsec internet key exchange +.It Ic msCodeInd Ta Microsoft individual code signing (authenticode) +.It Ic msCodeCom Ta Microsoft commercial code signing (authenticode) +.It Ic msCTLSign Ta Microsoft trust list signing +.It Ic msEFS Ta Microsoft encrypted file system +.El +.Pp +Examples: +.Bd -literal -offset indent +extendedKeyUsage=critical,codeSigning,1.2.3.4 +extendedKeyUsage=serverAuth,clientAuth +.Ed +.Ss Subject key identifier +This is really a string extension and can take two possible values. +Either the word +.Cm hash +which will automatically follow the guidelines in RFC 3280 +or a hex string giving the extension value to include. +The use of the hex string is strongly discouraged. +Example: +.Pp +.Dl subjectKeyIdentifier=hash +.Ss Authority key identifier +The authority key identifier extension permits two options, +.Cm keyid +and +.Cm issuer : +both can take the optional value +.Cm always . +.Pp +If the +.Cm keyid +option is present, an attempt is made to copy the subject +key identifier from the parent certificate. +If the value +.Cm always +is present, then an error is returned if the option fails. +.Pp +The +.Cm issuer +option copies the issuer and serial number from the issuer certificate. +This will only be done if the +.Cm keyid +option fails or is not included unless the +.Cm always +flag will always include the value. +Example: +.Pp +.Dl authorityKeyIdentifier=keyid,issuer +.Ss Subject alternative name +The subject alternative name extension allows various literal values to +be included in the configuration file. +These include +.Ic email +(an email address), +.Ic URI +(a uniform resource indicator), +.Ic DNS +(a DNS domain name), +.Ic RID +(a registered ID: OBJECT IDENTIFIER), +.Ic IP +(an IP address), +.Ic dirName +(a distinguished name), and +.Ic otherName . +.Pp +The +.Ic email +option can include a special +.Cm copy +value. +This will automatically include any email addresses contained in the +certificate subject name in the extension. +.Pp +The IP address used in the +.Ic IP +options can be in either IPv4 or IPv6 format. +.Pp +The value of +.Ic dirName +should point to a section containing the distinguished name to use as a +set of name value pairs. +Multi values AVAs can be formed by prefacing the name with a +.Ql + +character. +.Pp +.Ic otherName +can include arbitrary data associated with an OID: the value should +be the OID followed by a semicolon and the content in standard +.Xr ASN1_generate_nconf 3 +format. +Examples: +.Bd -literal -offset 2n +subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/ +subjectAltName=IP:192.168.7.1 +subjectAltName=IP:13::17 +subjectAltName=email:my@other.address,RID:1.2.3.4 +subjectAltName=otherName:1.2.3.4;UTF8:some other identifier + +subjectAltName=dirName:dir_sect + +[dir_sect] +C=UK +O=My Organization +OU=My Unit +CN=My Name +.Ed +.Ss Issuer alternative name +The issuer alternative name option supports all the literal options of +subject alternative name. +It does not support the +.Ic email : Ns Cm copy +option because that would not make sense. +It does support an additional +.Ic issuer : Ns Cm copy +option that will copy all the subject alternative name values from +the issuer certificate (if possible). +Example: +.Pp +.Dl issuerAltName = issuer:copy +.Ss Authority info access +The authority information access extension gives details about how to +access certain information relating to the CA. +Its syntax is +.Ar accessOID ; location +where +.Ar location +has the same syntax as subject alternative name (except that +.Ic email : Ns Cm copy +is not supported). +.Ar accessOID +can be any valid OID but only certain values are meaningful, +for example +.Cm OCSP +and +.Cm caIssuers . +Example: +.Bd -literal -offset indent +authorityInfoAccess = OCSP;URI:http://ocsp.my.host/ +authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html +.Ed +.Ss CRL distribution points +This is a multi-valued extension whose options can be either in +.Ar name : Ns Ar value +pair form using the same form as subject alternative name or a +single value representing a section name containing all the +distribution point fields. +.Pp +For a +.Ar name : Ns Ar value +pair a new DistributionPoint with the fullName field set to the +given value, both the cRLissuer and reasons fields are omitted in +this case. +.Pp +In the single option case, the section indicated contains values +for each field. +In this section: +.Pp +If the name is +.Ic fullname , +the value field should contain the full name of the distribution +point in the same format as subject alternative name. +.Pp +If the name is +.Ic relativename , +then the value field should contain a section name whose contents +represent a DN fragment to be placed in this field. +.Pp +The name +.Ic CRLIssuer , +if present, should contain a value for this field in subject +alternative name format. +.Pp +If the name is +.Ic reasons , +the value field should consist of a comma separated field containing +the reasons. +Valid reasons are: +.Cm keyCompromise , +.Cm CACompromise , +.Cm affiliationChanged , +.Cm superseded , +.Cm cessationOfOperation , +.Cm certificateHold , +.Cm privilegeWithdrawn , +and +.Cm AACompromise . +.Pp +Simple examples: +.Bd -literal -offset indent +crlDistributionPoints=URI:http://myhost.com/myca.crl +crlDistributionPoints=URI:http://my.com/my.crl,URI:http://oth.com/my.crl +.Ed +.Pp +Full distribution point example: +.Bd -literal -offset indent +crlDistributionPoints=crldp1_section + +[crldp1_section] +fullname=URI:http://myhost.com/myca.crl +CRLissuer=dirName:issuer_sect +reasons=keyCompromise, CACompromise + +[issuer_sect] +C=UK +O=Organisation +CN=Some Name +.Ed +.Ss Issuing distribution point +This extension should only appear in CRLs. +It is a multi-valued extension whose syntax is similar to the "section" +pointed to by the CRL distribution points extension with a few +differences. +.Pp +The names +.Ic reasons +and +.Ic CRLissuer +are not recognized. +.Pp +The name +.Ic onlysomereasons +is accepted, which sets this field. +The value is in the same format as the CRL distribution point +.Ic reasons +field. +.Pp +The names +.Ic onlyuser , +.Ic onlyCA , +.Ic onlyAA , +and +.Ic indirectCRL +are also accepted. +The values should be a boolean values +.Cm ( TRUE +or +.Cm FALSE ) +to indicate the value of the corresponding field. +Example: +.Bd -literal -offset indent +issuingDistributionPoint=critical, @idp_section + +[idp_section] +fullname=URI:http://myhost.com/myca.crl +indirectCRL=TRUE +onlysomereasons=keyCompromise, CACompromise + +[issuer_sect] +C=UK +O=Organisation +CN=Some Name +.Ed +.Ss Certificate policies +This is a raw extension. +All the fields of this extension can be set by using the appropriate +syntax. +.Pp +If you follow the PKIX recommendations and just use one OID, then you +just include the value of that OID. +Multiple OIDs can be set separated by commas, for example: +.Pp +.Dl certificatePolicies= 1.2.4.5, 1.1.3.4 +.Pp +If you wish to include qualifiers, then the policy OID and qualifiers +need to be specified in a separate section: this is done by using the +.Pf @ Ar section +syntax instead of a literal OID value. +.Pp +The section referred to must include the policy OID using the name +.Ic policyIdentifier . +.Ic CPSuri +qualifiers can be included using the syntax: +.Pp +.D1 Ic CPS . Ns Ar nnn Ns = Ns Ar value +.Pp +.Ic userNotice +qualifiers can be set using the syntax: +.Pp +.D1 Ic userNotice . Ns Ar nnn Ns =@ Ns Ar notice +.Pp +The value of the +.Ic userNotice +qualifier is specified in the relevant section. +This section can include +.Ic explicitText , +.Ic organization , +and +.Ic noticeNumbers +options. +.Ic explicitText +and +.Ic organization +are text strings, +and +.Ic noticeNumbers +is a comma separated list of numbers. +The +.Ic organization +and +.Ic noticeNumbers +options (if included) must +.Em both +be present. +If you use the +.Ic userNotice +option with IE5 then you need the +.Ic ia5org +option at the top level to modify the encoding: otherwise it will +not be interpreted properly. +Example: +.Bd -literal -offset indent +certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect + +[polsect] +policyIdentifier = 1.3.5.8 +CPS.1="http://my.host.name/" +CPS.2="http://my.your.name/" +userNotice.1=@notice + +[notice] +explicitText="Explicit Text Here" +organization="Organisation Name" +noticeNumbers=1,2,3,4 +.Ed +.Pp +The +.Ic ia5org +option changes the type of the +.Ic organization +field. +In RFC 2459, it can only be of type +.Vt DisplayText . +In RFC 3280, +.Vt IA5String +is also permissible. +Some software (for example some versions of MSIE) may require +.Ic ia5org . +.Ss Policy constraints +This is a multi-valued extension which consists of the names +.Ic requireExplicitPolicy +or +.Ic inhibitPolicyMapping +and a non-negative integer value. +At least one component must be present. +Example: +.Pp +.Dl policyConstraints = requireExplicitPolicy:3 +.Ss Inhibit any policy +This is a string extension whose value must be a non-negative integer. +Example: +.Pp +.Dl inhibitAnyPolicy = 2 +.Ss Name constraints +The name constraints extension is a multi-valued extension. +The name should begin with the word +.Cm permitted +or +.Cm excluded , +followed by a semicolon. +The rest of the name and the value follows the syntax of subjectAltName +except +.Ic email : Ns Cm copy +is not supported and the +.Ic IP +form should consist of an IP addresses and subnet mask separated +by a slash. +Examples: +.Bd -literal -offset indent +nameConstraints=permitted;IP:192.168.0.0/255.255.0.0 +nameConstraints=permitted;email:.somedomain.com +nameConstraints=excluded;email:.com +.Ed +.Ss OCSP no check +The OCSP no check extension is a string extension, +but its value is ignored. +Example: +.Pp +.Dl noCheck = ignored +.Ss TLS Feature (aka must staple) +This is a multi-valued extension consisting of a list of TLS extension +identifiers. +Each identifier may be a number in the range from 0 to 65535 or a +supported name. +When a TLS client sends a listed extension, the TLS server is expected +to include that extension in its reply. +.Pp +The supported names are: +.Cm status_request +and +.Cm status_request_v2 . +Example: +.Pp +.Dl tlsfeature = status_request +.Sh DEPRECATED EXTENSIONS +The following extensions are non-standard, Netscape specific and largely +obsolete. +Their use in new applications is discouraged. +.Ss Netscape string extensions +Netscape comment +.Ic ( nsComment ) +is a string extension containing a comment which will be displayed when +the certificate is viewed in some browsers. +Example: +.Pp +.Dl nsComment = "Some Random Comment" +.Pp +Other supported extensions in this category are: +.Ic nsBaseUrl , +.Ic nsRevocationUrl , +.Ic nsCaRevocationUrl , +.Ic nsRenewalUrl , +.Ic nsCaPolicyUrl , +and +.Ic nsSslServerName . +.Ss Netscape certificate type +This is a multi-valued extensions which consists of a list of flags to +be included. +It was used to indicate the purposes for which a certificate could be +used. +The +.Ic basicConstraints , +.Ic keyUsage , +and extended key usage extensions are now used instead. +.Pp +Acceptable values for +.Ic nsCertType +are: +.Cm client , +.Cm server , +.Cm email , +.Cm objsign , +.Cm reserved , +.Cm sslCA , +.Cm emailCA , +.Cm objCA . +.Sh ARBITRARY EXTENSIONS +If an extension is not supported by the OpenSSL code, then it must +be encoded using the arbitrary extension format. +It is also possible to use the arbitrary format for supported +extensions. +Extreme care should be taken to ensure that the data is formatted +correctly for the given extension type. +.Pp +There are two ways to encode arbitrary extensions. +.Pp +The first way is to use the word +.Cm ASN1 +followed by the extension content using the same syntax as +.Xr ASN1_generate_nconf 3 . +For example: +.Bd -literal -offset indent +1.2.3.4=critical,ASN1:UTF8String:Some random data +1.2.3.4=ASN1:SEQUENCE:seq_sect + +[seq_sect] +field1 = UTF8:field1 +field2 = UTF8:field2 +.Ed +.Pp +It is also possible to use the word +.Cm DER +to include the raw encoded data in any extension. +.Bd -literal -offset indent +1.2.3.4=critical,DER:01:02:03:04 +1.2.3.4=DER:01020304 +.Ed +.Pp +The value following +.Cm DER +is a hex dump of the DER encoding of the extension. +Any extension can be placed in this form to override the default behaviour. +For example: +.Pp +.Dl basicConstraints=critical,DER:00:01:02:03 +.Sh FILES +.Bl -tag -width /etc/ssl/x509v3.cnf -compact +.It Pa /etc/ssl/x509v3.cnf +standard configuration file +.El +.Sh SEE ALSO +.Xr openssl 1 , +.Xr ASN1_generate_nconf 3 , +.Xr OPENSSL_config 3 , +.Xr openssl.cnf 5 +.Sh HISTORY +X509v3 extension code was first added to OpenSSL 0.9.2. +.Sh CAVEATS +There is no guarantee that a specific implementation will process a +given extension. +It may therefore sometimes be possible to use certificates for purposes +prohibited by their extensions because a specific application does not +recognize or honour the values of the relevant extensions. +.Pp +The +.Cm DER +and +.Cm ASN1 +options should be used with caution. +It is possible to create totally invalid extensions if they are not used +carefully. +.Pp +If an extension is multi-value and a field value must contain a comma, +the long form must be used. +Otherwise the comma would be misinterpreted as a field separator. +For example, +.Pp +.Dl subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar +.Pp +will produce an error, but the following form is valid: +.Bd -literal -offset indent +subjectAltName=@subject_alt_section + +[subject_alt_section] +subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar +.Ed +.Pp +Due to the behaviour of the OpenSSL CONF library, the same field +name can only occur once in a section. +That means that +.Bd -literal -offset indent +subjectAltName=@alt_section + +[alt_section] +email=steve@here +email=steve@there +.Ed +.Pp +will only use the last value. +This can be worked around by using the form: +.Bd -literal -offset indent +[alt_section] +email.1=steve@here +email.2=steve@there +.Ed diff --git a/Libraries/libressl/missing b/Libraries/libressl/missing new file mode 100644 index 000000000..1fe1611f1 --- /dev/null +++ b/Libraries/libressl/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/Libraries/libressl/openssl.cnf b/Libraries/libressl/openssl.cnf new file mode 100644 index 000000000..8ce83bf90 --- /dev/null +++ b/Libraries/libressl/openssl.cnf @@ -0,0 +1,24 @@ +[ req ] +#default_bits = 2048 +#default_md = sha256 +#default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_min = 2 +countryName_max = 2 +stateOrProvinceName = State or Province Name (full name) +localityName = Locality Name (eg, city) +0.organizationName = Organization Name (eg, company) +organizationalUnitName = Organizational Unit Name (eg, section) +commonName = Common Name (eg, fully qualified host name) +commonName_max = 64 +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 diff --git a/Libraries/libressl/openssl.pc.in b/Libraries/libressl/openssl.pc.in new file mode 100644 index 000000000..b4acfa5c9 --- /dev/null +++ b/Libraries/libressl/openssl.pc.in @@ -0,0 +1,11 @@ +#openssl pkg-config source file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: LibreSSL +Description: Secure Sockets Layer and cryptography libraries and tools +Version: @VERSION@ +Requires: libssl libcrypto diff --git a/Libraries/libressl/scripts/config.guess b/Libraries/libressl/scripts/config.guess new file mode 100644 index 000000000..980b02083 --- /dev/null +++ b/Libraries/libressl/scripts/config.guess @@ -0,0 +1,1774 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2022 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-09-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2022 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/Libraries/libressl/scripts/config.sub b/Libraries/libressl/scripts/config.sub new file mode 100644 index 000000000..baf1512b3 --- /dev/null +++ b/Libraries/libressl/scripts/config.sub @@ -0,0 +1,1907 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2022 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-09-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2022 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x$basic_os != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* | linux-mlibc* ) + ;; + uclinux-uclibc* ) + ;; + managarm-mlibc* | managarm-kernel* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* | -mlibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + -kernel* ) + echo "Invalid configuration \`$1': \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + *-kernel* ) + echo "Invalid configuration \`$1': \`$kernel' does not support \`$os'." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/Libraries/libressl/scripts/i686-w64-mingw32.cmake b/Libraries/libressl/scripts/i686-w64-mingw32.cmake new file mode 100644 index 000000000..bad60db7a --- /dev/null +++ b/Libraries/libressl/scripts/i686-w64-mingw32.cmake @@ -0,0 +1,9 @@ +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_PROCESSOR i386) +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + diff --git a/Libraries/libressl/scripts/test b/Libraries/libressl/scripts/test new file mode 100644 index 000000000..97e316e0b --- /dev/null +++ b/Libraries/libressl/scripts/test @@ -0,0 +1,186 @@ +#!/bin/sh +set -e +set -x + +unset CC +ENABLE_ASM="${ENABLE_ASM:=ON}" + +if type apt-get >/dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y cmake ninja-build +fi + +# generate source tree +./autogen.sh + +if [ "$ARCH" = "" ]; then + ARCH=`uname -m` +fi + +# test macOS +if [ `uname` = "Darwin" ]; then + # test autotools + ./configure + + # make distribution + make -j 4 distcheck + + # test cmake + tar zxvf libressl-*.tar.gz + cd libressl-* + + ( + mkdir build-static + cd build-static + cmake -DCMAKE_OSX_ARCHITECTURES=$ARCH .. + make -j 4 + if [ "$ARCH" = "x86_64" ]; then + make test + fi + ) + + ( + mkdir build-shared + cd build-shared + cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_OSX_ARCHITECTURES=$ARCH .. + make -j 4 + if [ "$ARCH" = "x86_64" ]; then + make test + fi + ) + +# assuming Linux below +elif [ "$ARCH" = "native" ]; then + # test autotools + ./configure + + # make distribution + make -j 4 distcheck + + tar zxvf libressl-*.tar.gz + cd libressl-* + + + # test cmake and ninja + ( + mkdir build-static + cd build-static + cmake -GNinja -DENABLE_ASM=${ENABLE_ASM} .. + ninja + ninja test + ) + + ( + mkdir build-shared + cd build-shared + cmake -GNinja -DBUILD_SHARED_LIBS=ON -DENABLE_ASM=${ENABLE_ASM} .. + ninja + ninja test + ) + +elif [ "$ARCH" = "mingw32" -o "$ARCH" = "mingw64" ]; then + CPU=i686 + if [ "$ARCH" = "mingw64" ]; then + CPU=x86_64 + fi + + if ! type i686-w64-mingw32-gcc > /dev/null; then + sudo apt-get install -y mingw-w64 + fi + + ./configure --host=$CPU-w64-mingw32 + make -j 4 + + ( + rm -fr build-static + mkdir build-static + cd build-static + cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../scripts/$CPU-w64-mingw32.cmake -DENABLE_ASM=${ENABLE_ASM} .. + ninja -j 4 + ) + ( + rm -fr build-shared + mkdir build-shared + cd build-shared + cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../scripts/$CPU-w64-mingw32.cmake -DBUILD_SHARED_LIBS=ON -DENABLE_ASM=${ENABLE_ASM} .. + ninja -j 4 + ) + +elif [ "$ARCH" = "arm32" -o "$ARCH" = "arm64" ]; then + sudo apt-get install -y qemu-user-static binfmt-support + + if [ "$ARCH" = "arm32" ]; then + sudo apt-get install -y g++-arm-linux-gnueabihf + sudo ln -sf /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 /lib/ + ./configure --host=arm-linux-gnueabihf + LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib make -j 4 check + else + sudo apt-get install -y g++-aarch64-linux-gnu + sudo ln -sf /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib/ + ./configure --host=aarch64-linux-gnu + LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib make -j 4 check + fi + + file apps/openssl/.libs/openssl + +elif [ "$ARCH" = "mips32" -o "$ARCH" = "mips64" ]; then + sudo apt-get install -y qemu-user-static binfmt-support + + if [ "$ARCH" = "mips32" ]; then + sudo apt-get install -y g++-mips-linux-gnu + sudo ln -sf /usr/mipsel-linux-gnu/lib/ld.so.1 /lib/ + ./configure --host=mipsel-linux-gnu + LD_LIBRARY_PATH=/usr/mipsel-linux-gnu/lib make -j 4 check + else + sudo apt-get install -y g++-mips64el-linux-gnuabi64 + sudo ln -sf /usr/mips64el-linux-gnuabi64/lib64/ld.so.1 /lib64 + ./configure --host=mips64el-linux-gnuabi64 + LD_LIBRARY_PATH=/usr/mips64el-linux-gnuabi64/lib make -j 4 check + fi + + file apps/openssl/.libs/openssl + +elif [ "$ARCH" = "android" ]; then + export TC_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake + + # set target API level and architecture + level_arch="" + level=$MIN_NAL + while [ $level -le $MAX_NAL ] + do + level_arch="$level_arch $level;x86_64" + level_arch="$level_arch $level;x86" + level_arch="$level_arch $level;arm64-v8a" + + level=`expr $level + 1` + done + + echo "##### level_arch = $level_arch" + + # build each API level and architecture + for la in $level_arch + do + NAL=`echo $la | cut -d ';' -f 1` + ABI=`echo $la | cut -d ';' -f 2` + echo "" + echo "##### Date: `date`, Native API level: $NAL, ABI: $ABI" + + ( + build_dir=build-$NAL_$ABI + rm -fr $build_dir include/openssl/opensslconf.h + mkdir $build_dir + cd $build_dir + echo "##### cmake -GNinja -DCMAKE_MAKE_PROGRAM=ninja -DANDROID_NDK=$ANDROID_NDK_HOME -DCMAKE_TOOLCHAIN_FILE=$TC_FILE -DANDROID_ABI=$ABI -DANDROID_NATIVE_API_LEVEL=$NAL .." + cmake -GNinja -DCMAKE_MAKE_PROGRAM=ninja \ + -DANDROID_NDK=$ANDROID_NDK_HOME \ + -DCMAKE_TOOLCHAIN_FILE=$TC_FILE \ + -DANDROID_ABI=$ABI -DANDROID_NATIVE_API_LEVEL=$NAL \ + -DENABLE_ASM=${ENABLE_ASM} .. + + ninja -j 4 + + echo "" + file apps/openssl/openssl + ) + done +fi diff --git a/Libraries/libressl/scripts/wrap-compiler-for-flag-check b/Libraries/libressl/scripts/wrap-compiler-for-flag-check new file mode 100644 index 000000000..b014f11e7 --- /dev/null +++ b/Libraries/libressl/scripts/wrap-compiler-for-flag-check @@ -0,0 +1,31 @@ +#!/bin/sh + +# This file is in the public domain. +# https://github.com/kmcallister/autoharden/blob/c5c7842f39c2f8d19836bb5427d6479db4436d62/LICENSE +# +# From kmcallister: +# https://github.com/kmcallister/autoharden/blob/efaf5a16612589808c276a11536ea9a47071f74b/scripts/wrap-compiler-for-flag-check + +# Prior to clang v5.1, there was no way to make +# clang's "argument unused" warning fatal. This +# wrapper script that greps for this warning message. Newer clang's have no issues. +# +# Ideally the search string would also include 'clang: ' but this output might +# depend on clang's argv[0]. +# +set -o errexit +set -o nounset + +if out=`"$@" 2>&1`; then + echo "$out" + if echo "$out" | grep 'warning: argument unused' >/dev/null; then + echo "$0: found clang warning" + exit 1 + else + exit 0 + fi +else + code=$? + echo "$out" + exit $code +fi diff --git a/Libraries/libressl/scripts/x86_64-w64-mingw32.cmake b/Libraries/libressl/scripts/x86_64-w64-mingw32.cmake new file mode 100644 index 000000000..df65165f8 --- /dev/null +++ b/Libraries/libressl/scripts/x86_64-w64-mingw32.cmake @@ -0,0 +1,9 @@ +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_PROCESSOR amd64) +SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + diff --git a/Libraries/libressl/ssl/CMakeLists.txt b/Libraries/libressl/ssl/CMakeLists.txt new file mode 100644 index 000000000..9ba2a9e6f --- /dev/null +++ b/Libraries/libressl/ssl/CMakeLists.txt @@ -0,0 +1,138 @@ +set( + SSL_SRC + bio_ssl.c + d1_both.c + d1_lib.c + d1_pkt.c + d1_srtp.c + pqueue.c + s3_cbc.c + s3_lib.c + ssl_algs.c + ssl_asn1.c + ssl_both.c + ssl_cert.c + ssl_ciph.c + ssl_ciphers.c + ssl_clnt.c + ssl_err.c + ssl_init.c + ssl_kex.c + ssl_lib.c + ssl_methods.c + ssl_packet.c + ssl_pkt.c + ssl_rsa.c + ssl_seclevel.c + ssl_sess.c + ssl_sigalgs.c + ssl_srvr.c + ssl_stat.c + ssl_tlsext.c + ssl_transcript.c + ssl_txt.c + ssl_versions.c + t1_enc.c + t1_lib.c + tls_buffer.c + tls_content.c + tls_key_share.c + tls_lib.c + tls12_key_schedule.c + tls12_lib.c + tls12_record_layer.c + tls13_client.c + tls13_error.c + tls13_handshake.c + tls13_handshake_msg.c + tls13_key_schedule.c + tls13_legacy.c + tls13_lib.c + tls13_quic.c + tls13_record.c + tls13_record_layer.c + tls13_server.c +) + +set( + BS_SRC + bs_ber.c + bs_cbb.c + bs_cbs.c +) + +add_library(ssl_obj OBJECT ${SSL_SRC}) +target_include_directories(ssl_obj + PRIVATE + . + hidden + ../crypto/bio + ../include/compat + PUBLIC + ../include + ${CMAKE_BINARY_DIR}/include) + +add_library(bs_obj OBJECT ${BS_SRC}) +target_include_directories(bs_obj + PRIVATE + . + ../include/compat) + +if(BUILD_SHARED_LIBS) + add_library(ssl $ $) +else() + add_library(ssl $ empty.c) +endif() + +export_symbol(ssl ${CMAKE_CURRENT_SOURCE_DIR}/ssl.sym) +target_link_libraries(ssl crypto ${PLATFORM_LIBS}) +if (WIN32) + set(SSL_POSTFIX -${SSL_MAJOR_VERSION} PARENT_SCOPE) +endif() +set_target_properties(ssl PROPERTIES + OUTPUT_NAME ssl${SSL_POSTFIX} + ARCHIVE_OUTPUT_NAME ssl${SSL_POSTFIX} + EXPORT_NAME SSL + VERSION ${SSL_VERSION} + SOVERSION ${SSL_MAJOR_VERSION} +) + +target_include_directories( + ssl + PUBLIC + $ + $ +) + +install( + TARGETS ssl + EXPORT SSL-target +) + +export( + EXPORT SSL-target + FILE "${LibreSSL_BINARY_DIR}/LibreSSL-SSL.cmake" + NAMESPACE LibreSSL:: +) + +if(ENABLE_LIBRESSL_INSTALL) + install( + TARGETS ssl + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + install( + EXPORT SSL-target + FILE "LibreSSL-SSL.cmake" + NAMESPACE LibreSSL:: + DESTINATION "${LIBRESSL_INSTALL_CMAKEDIR}" + ) +endif(ENABLE_LIBRESSL_INSTALL) + +# build static library for regression test +if(BUILD_SHARED_LIBS) + add_library(ssl-static STATIC $) + target_link_libraries(ssl-static crypto-static ${PLATFORM_LIBS}) +endif() + diff --git a/Libraries/libressl/ssl/Makefile.am b/Libraries/libressl/ssl/Makefile.am new file mode 100644 index 000000000..9acacd7bc --- /dev/null +++ b/Libraries/libressl/ssl/Makefile.am @@ -0,0 +1,116 @@ +include $(top_srcdir)/Makefile.am.common + +-include $(abs_top_builddir)/crypto/libcrypto_la_objects.mk + +AM_CPPFLAGS += -I$(top_srcdir)/crypto/bio + +noinst_LTLIBRARIES = libbs.la + +if ENABLE_LIBTLS_ONLY +noinst_LTLIBRARIES += libssl.la +else +lib_LTLIBRARIES = libssl.la +endif + +noinst_DATA = remove_bs_objects + +EXTRA_DIST = VERSION +EXTRA_DIST += CMakeLists.txt +EXTRA_DIST += ssl.sym +EXTRA_DIST += empty.c + +CLEANFILES = libssl_la_objects.mk + +EXTRA_libssl_la_DEPENDENCIES = libssl_la_objects.mk + +libssl_la_objects.mk: Makefile + @echo "libssl_la_objects= $(libssl_la_OBJECTS)" \ + | sed 's/ */ $$\(abs_top_builddir\)\/ssl\//g' \ + > libssl_la_objects.mk + +.PHONY: remove_bs_objects +remove_bs_objects: libssl.la + -$(AR) dv $(abs_top_builddir)/ssl/.libs/libssl.a \ + bs_ber.o bs_cbb.o bs_cbs.o + +libssl_la_CPPFLAGS = -I$(top_srcdir)/ssl/hidden ${AM_CPPFLAGS} +libssl_la_LDFLAGS = -version-info @LIBSSL_VERSION@ -no-undefined -export-symbols $(top_srcdir)/ssl/ssl.sym +libssl_la_LIBADD = $(abs_top_builddir)/crypto/libcrypto.la $(PLATFORM_LDADD) +libssl_la_LIBADD += $(libcompat_la_objects) +libssl_la_LIBADD += $(libcompatnoopt_la_objects) +libssl_la_LIBADD += libbs.la + +libbs_la_SOURCES = bs_ber.c +libbs_la_SOURCES += bs_cbb.c +libbs_la_SOURCES += bs_cbs.c +noinst_HEADERS = bytestring.h + +noinst_HEADERS += hidden/ssl_namespace.h +noinst_HEADERS += hidden/openssl/srtp.h +noinst_HEADERS += hidden/openssl/tls1.h +noinst_HEADERS += hidden/openssl/ssl.h + +libssl_la_SOURCES = bio_ssl.c +libssl_la_SOURCES += d1_both.c +libssl_la_SOURCES += d1_lib.c +libssl_la_SOURCES += d1_pkt.c +libssl_la_SOURCES += d1_srtp.c +libssl_la_SOURCES += pqueue.c +libssl_la_SOURCES += s3_cbc.c +libssl_la_SOURCES += s3_lib.c +libssl_la_SOURCES += ssl_algs.c +libssl_la_SOURCES += ssl_asn1.c +libssl_la_SOURCES += ssl_both.c +libssl_la_SOURCES += ssl_cert.c +libssl_la_SOURCES += ssl_ciph.c +libssl_la_SOURCES += ssl_ciphers.c +libssl_la_SOURCES += ssl_clnt.c +libssl_la_SOURCES += ssl_err.c +libssl_la_SOURCES += ssl_init.c +libssl_la_SOURCES += ssl_kex.c +libssl_la_SOURCES += ssl_lib.c +libssl_la_SOURCES += ssl_methods.c +libssl_la_SOURCES += ssl_packet.c +libssl_la_SOURCES += ssl_pkt.c +libssl_la_SOURCES += ssl_rsa.c +libssl_la_SOURCES += ssl_seclevel.c +libssl_la_SOURCES += ssl_sess.c +libssl_la_SOURCES += ssl_sigalgs.c +libssl_la_SOURCES += ssl_srvr.c +libssl_la_SOURCES += ssl_stat.c +libssl_la_SOURCES += ssl_tlsext.c +libssl_la_SOURCES += ssl_transcript.c +libssl_la_SOURCES += ssl_txt.c +libssl_la_SOURCES += ssl_versions.c +libssl_la_SOURCES += t1_enc.c +libssl_la_SOURCES += t1_lib.c +libssl_la_SOURCES += tls_buffer.c +libssl_la_SOURCES += tls_content.c +libssl_la_SOURCES += tls_key_share.c +libssl_la_SOURCES += tls_lib.c +libssl_la_SOURCES += tls12_key_schedule.c +libssl_la_SOURCES += tls12_lib.c +libssl_la_SOURCES += tls12_record_layer.c +libssl_la_SOURCES += tls13_client.c +libssl_la_SOURCES += tls13_error.c +libssl_la_SOURCES += tls13_handshake.c +libssl_la_SOURCES += tls13_handshake_msg.c +libssl_la_SOURCES += tls13_key_schedule.c +libssl_la_SOURCES += tls13_legacy.c +libssl_la_SOURCES += tls13_lib.c +libssl_la_SOURCES += tls13_quic.c +libssl_la_SOURCES += tls13_record.c +libssl_la_SOURCES += tls13_record_layer.c +libssl_la_SOURCES += tls13_server.c + +noinst_HEADERS += srtp.h +noinst_HEADERS += dtls_local.h +noinst_HEADERS += ssl_local.h +noinst_HEADERS += ssl_sigalgs.h +noinst_HEADERS += ssl_tlsext.h +noinst_HEADERS += tls_content.h +noinst_HEADERS += tls_internal.h +noinst_HEADERS += tls12_internal.h +noinst_HEADERS += tls13_internal.h +noinst_HEADERS += tls13_handshake.h +noinst_HEADERS += tls13_record.h diff --git a/Libraries/libressl/ssl/Makefile.in b/Libraries/libressl/ssl/Makefile.in new file mode 100644 index 000000000..dbd2862d5 --- /dev/null +++ b/Libraries/libressl/ssl/Makefile.in @@ -0,0 +1,1344 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_LIBTLS_ONLY_TRUE@am__append_1 = libssl.la +subdir = ssl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_add_fortify_source.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/check-hardening-options.m4 \ + $(top_srcdir)/m4/check-libc.m4 \ + $(top_srcdir)/m4/check-os-options.m4 \ + $(top_srcdir)/m4/disable-compiler-warnings.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +libbs_la_LIBADD = +am_libbs_la_OBJECTS = bs_ber.lo bs_cbb.lo bs_cbs.lo +libbs_la_OBJECTS = $(am_libbs_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am__DEPENDENCIES_1 = +libssl_la_DEPENDENCIES = $(abs_top_builddir)/crypto/libcrypto.la \ + $(am__DEPENDENCIES_1) libbs.la +am_libssl_la_OBJECTS = libssl_la-bio_ssl.lo libssl_la-d1_both.lo \ + libssl_la-d1_lib.lo libssl_la-d1_pkt.lo libssl_la-d1_srtp.lo \ + libssl_la-pqueue.lo libssl_la-s3_cbc.lo libssl_la-s3_lib.lo \ + libssl_la-ssl_algs.lo libssl_la-ssl_asn1.lo \ + libssl_la-ssl_both.lo libssl_la-ssl_cert.lo \ + libssl_la-ssl_ciph.lo libssl_la-ssl_ciphers.lo \ + libssl_la-ssl_clnt.lo libssl_la-ssl_err.lo \ + libssl_la-ssl_init.lo libssl_la-ssl_kex.lo \ + libssl_la-ssl_lib.lo libssl_la-ssl_methods.lo \ + libssl_la-ssl_packet.lo libssl_la-ssl_pkt.lo \ + libssl_la-ssl_rsa.lo libssl_la-ssl_seclevel.lo \ + libssl_la-ssl_sess.lo libssl_la-ssl_sigalgs.lo \ + libssl_la-ssl_srvr.lo libssl_la-ssl_stat.lo \ + libssl_la-ssl_tlsext.lo libssl_la-ssl_transcript.lo \ + libssl_la-ssl_txt.lo libssl_la-ssl_versions.lo \ + libssl_la-t1_enc.lo libssl_la-t1_lib.lo \ + libssl_la-tls_buffer.lo libssl_la-tls_content.lo \ + libssl_la-tls_key_share.lo libssl_la-tls_lib.lo \ + libssl_la-tls12_key_schedule.lo libssl_la-tls12_lib.lo \ + libssl_la-tls12_record_layer.lo libssl_la-tls13_client.lo \ + libssl_la-tls13_error.lo libssl_la-tls13_handshake.lo \ + libssl_la-tls13_handshake_msg.lo \ + libssl_la-tls13_key_schedule.lo libssl_la-tls13_legacy.lo \ + libssl_la-tls13_lib.lo libssl_la-tls13_quic.lo \ + libssl_la-tls13_record.lo libssl_la-tls13_record_layer.lo \ + libssl_la-tls13_server.lo +libssl_la_OBJECTS = $(am_libssl_la_OBJECTS) +libssl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libssl_la_LDFLAGS) $(LDFLAGS) -o $@ +@ENABLE_LIBTLS_ONLY_FALSE@am_libssl_la_rpath = -rpath $(libdir) +@ENABLE_LIBTLS_ONLY_TRUE@am_libssl_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/bs_ber.Plo ./$(DEPDIR)/bs_cbb.Plo \ + ./$(DEPDIR)/bs_cbs.Plo ./$(DEPDIR)/libssl_la-bio_ssl.Plo \ + ./$(DEPDIR)/libssl_la-d1_both.Plo \ + ./$(DEPDIR)/libssl_la-d1_lib.Plo \ + ./$(DEPDIR)/libssl_la-d1_pkt.Plo \ + ./$(DEPDIR)/libssl_la-d1_srtp.Plo \ + ./$(DEPDIR)/libssl_la-pqueue.Plo \ + ./$(DEPDIR)/libssl_la-s3_cbc.Plo \ + ./$(DEPDIR)/libssl_la-s3_lib.Plo \ + ./$(DEPDIR)/libssl_la-ssl_algs.Plo \ + ./$(DEPDIR)/libssl_la-ssl_asn1.Plo \ + ./$(DEPDIR)/libssl_la-ssl_both.Plo \ + ./$(DEPDIR)/libssl_la-ssl_cert.Plo \ + ./$(DEPDIR)/libssl_la-ssl_ciph.Plo \ + ./$(DEPDIR)/libssl_la-ssl_ciphers.Plo \ + ./$(DEPDIR)/libssl_la-ssl_clnt.Plo \ + ./$(DEPDIR)/libssl_la-ssl_err.Plo \ + ./$(DEPDIR)/libssl_la-ssl_init.Plo \ + ./$(DEPDIR)/libssl_la-ssl_kex.Plo \ + ./$(DEPDIR)/libssl_la-ssl_lib.Plo \ + ./$(DEPDIR)/libssl_la-ssl_methods.Plo \ + ./$(DEPDIR)/libssl_la-ssl_packet.Plo \ + ./$(DEPDIR)/libssl_la-ssl_pkt.Plo \ + ./$(DEPDIR)/libssl_la-ssl_rsa.Plo \ + ./$(DEPDIR)/libssl_la-ssl_seclevel.Plo \ + ./$(DEPDIR)/libssl_la-ssl_sess.Plo \ + ./$(DEPDIR)/libssl_la-ssl_sigalgs.Plo \ + ./$(DEPDIR)/libssl_la-ssl_srvr.Plo \ + ./$(DEPDIR)/libssl_la-ssl_stat.Plo \ + ./$(DEPDIR)/libssl_la-ssl_tlsext.Plo \ + ./$(DEPDIR)/libssl_la-ssl_transcript.Plo \ + ./$(DEPDIR)/libssl_la-ssl_txt.Plo \ + ./$(DEPDIR)/libssl_la-ssl_versions.Plo \ + ./$(DEPDIR)/libssl_la-t1_enc.Plo \ + ./$(DEPDIR)/libssl_la-t1_lib.Plo \ + ./$(DEPDIR)/libssl_la-tls12_key_schedule.Plo \ + ./$(DEPDIR)/libssl_la-tls12_lib.Plo \ + ./$(DEPDIR)/libssl_la-tls12_record_layer.Plo \ + ./$(DEPDIR)/libssl_la-tls13_client.Plo \ + ./$(DEPDIR)/libssl_la-tls13_error.Plo \ + ./$(DEPDIR)/libssl_la-tls13_handshake.Plo \ + ./$(DEPDIR)/libssl_la-tls13_handshake_msg.Plo \ + ./$(DEPDIR)/libssl_la-tls13_key_schedule.Plo \ + ./$(DEPDIR)/libssl_la-tls13_legacy.Plo \ + ./$(DEPDIR)/libssl_la-tls13_lib.Plo \ + ./$(DEPDIR)/libssl_la-tls13_quic.Plo \ + ./$(DEPDIR)/libssl_la-tls13_record.Plo \ + ./$(DEPDIR)/libssl_la-tls13_record_layer.Plo \ + ./$(DEPDIR)/libssl_la-tls13_server.Plo \ + ./$(DEPDIR)/libssl_la-tls_buffer.Plo \ + ./$(DEPDIR)/libssl_la-tls_content.Plo \ + ./$(DEPDIR)/libssl_la-tls_key_share.Plo \ + ./$(DEPDIR)/libssl_la-tls_lib.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libbs_la_SOURCES) $(libssl_la_SOURCES) +DIST_SOURCES = $(libbs_la_SOURCES) $(libssl_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(noinst_DATA) +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.common $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTO_VERSION = @LIBCRYPTO_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSL_VERSION = @LIBSSL_VERSION@ +LIBTLS_VERSION = @LIBTLS_VERSION@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSLDIR = @OPENSSLDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_LDADD = @PLATFORM_LDADD@ +PROG_LDADD = @PROG_LDADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(abs_top_builddir)/include \ + -I$(top_srcdir)/include/compat -DLIBRESSL_INTERNAL \ + -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= \ + -I$(top_srcdir)/crypto/bio +noinst_LTLIBRARIES = libbs.la $(am__append_1) +@ENABLE_LIBTLS_ONLY_FALSE@lib_LTLIBRARIES = libssl.la +noinst_DATA = remove_bs_objects +EXTRA_DIST = VERSION CMakeLists.txt ssl.sym empty.c +CLEANFILES = libssl_la_objects.mk +EXTRA_libssl_la_DEPENDENCIES = libssl_la_objects.mk +libssl_la_CPPFLAGS = -I$(top_srcdir)/ssl/hidden ${AM_CPPFLAGS} +libssl_la_LDFLAGS = -version-info @LIBSSL_VERSION@ -no-undefined -export-symbols $(top_srcdir)/ssl/ssl.sym +libssl_la_LIBADD = $(abs_top_builddir)/crypto/libcrypto.la \ + $(PLATFORM_LDADD) $(libcompat_la_objects) \ + $(libcompatnoopt_la_objects) libbs.la +libbs_la_SOURCES = bs_ber.c bs_cbb.c bs_cbs.c +noinst_HEADERS = bytestring.h hidden/ssl_namespace.h \ + hidden/openssl/srtp.h hidden/openssl/tls1.h \ + hidden/openssl/ssl.h srtp.h dtls_local.h ssl_local.h \ + ssl_sigalgs.h ssl_tlsext.h tls_content.h tls_internal.h \ + tls12_internal.h tls13_internal.h tls13_handshake.h \ + tls13_record.h +libssl_la_SOURCES = bio_ssl.c d1_both.c d1_lib.c d1_pkt.c d1_srtp.c \ + pqueue.c s3_cbc.c s3_lib.c ssl_algs.c ssl_asn1.c ssl_both.c \ + ssl_cert.c ssl_ciph.c ssl_ciphers.c ssl_clnt.c ssl_err.c \ + ssl_init.c ssl_kex.c ssl_lib.c ssl_methods.c ssl_packet.c \ + ssl_pkt.c ssl_rsa.c ssl_seclevel.c ssl_sess.c ssl_sigalgs.c \ + ssl_srvr.c ssl_stat.c ssl_tlsext.c ssl_transcript.c ssl_txt.c \ + ssl_versions.c t1_enc.c t1_lib.c tls_buffer.c tls_content.c \ + tls_key_share.c tls_lib.c tls12_key_schedule.c tls12_lib.c \ + tls12_record_layer.c tls13_client.c tls13_error.c \ + tls13_handshake.c tls13_handshake_msg.c tls13_key_schedule.c \ + tls13_legacy.c tls13_lib.c tls13_quic.c tls13_record.c \ + tls13_record_layer.c tls13_server.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ssl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ssl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.am.common $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libbs.la: $(libbs_la_OBJECTS) $(libbs_la_DEPENDENCIES) $(EXTRA_libbs_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libbs_la_OBJECTS) $(libbs_la_LIBADD) $(LIBS) + +libssl.la: $(libssl_la_OBJECTS) $(libssl_la_DEPENDENCIES) $(EXTRA_libssl_la_DEPENDENCIES) + $(AM_V_CCLD)$(libssl_la_LINK) $(am_libssl_la_rpath) $(libssl_la_OBJECTS) $(libssl_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bs_ber.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bs_cbb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bs_cbs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-bio_ssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-d1_both.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-d1_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-d1_pkt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-d1_srtp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-pqueue.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-s3_cbc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-s3_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_algs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_both.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_cert.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_ciph.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_ciphers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_clnt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_err.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_init.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_kex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_methods.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_packet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_pkt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_rsa.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_seclevel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_sess.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_sigalgs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_srvr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_stat.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_tlsext.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_transcript.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_txt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-ssl_versions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-t1_enc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-t1_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls12_key_schedule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls12_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls12_record_layer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_client.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_error.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_handshake.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_handshake_msg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_key_schedule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_legacy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_quic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_record.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_record_layer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls13_server.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls_buffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls_content.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls_key_share.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libssl_la-tls_lib.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libssl_la-bio_ssl.lo: bio_ssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-bio_ssl.lo -MD -MP -MF $(DEPDIR)/libssl_la-bio_ssl.Tpo -c -o libssl_la-bio_ssl.lo `test -f 'bio_ssl.c' || echo '$(srcdir)/'`bio_ssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-bio_ssl.Tpo $(DEPDIR)/libssl_la-bio_ssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bio_ssl.c' object='libssl_la-bio_ssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-bio_ssl.lo `test -f 'bio_ssl.c' || echo '$(srcdir)/'`bio_ssl.c + +libssl_la-d1_both.lo: d1_both.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-d1_both.lo -MD -MP -MF $(DEPDIR)/libssl_la-d1_both.Tpo -c -o libssl_la-d1_both.lo `test -f 'd1_both.c' || echo '$(srcdir)/'`d1_both.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-d1_both.Tpo $(DEPDIR)/libssl_la-d1_both.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='d1_both.c' object='libssl_la-d1_both.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-d1_both.lo `test -f 'd1_both.c' || echo '$(srcdir)/'`d1_both.c + +libssl_la-d1_lib.lo: d1_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-d1_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-d1_lib.Tpo -c -o libssl_la-d1_lib.lo `test -f 'd1_lib.c' || echo '$(srcdir)/'`d1_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-d1_lib.Tpo $(DEPDIR)/libssl_la-d1_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='d1_lib.c' object='libssl_la-d1_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-d1_lib.lo `test -f 'd1_lib.c' || echo '$(srcdir)/'`d1_lib.c + +libssl_la-d1_pkt.lo: d1_pkt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-d1_pkt.lo -MD -MP -MF $(DEPDIR)/libssl_la-d1_pkt.Tpo -c -o libssl_la-d1_pkt.lo `test -f 'd1_pkt.c' || echo '$(srcdir)/'`d1_pkt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-d1_pkt.Tpo $(DEPDIR)/libssl_la-d1_pkt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='d1_pkt.c' object='libssl_la-d1_pkt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-d1_pkt.lo `test -f 'd1_pkt.c' || echo '$(srcdir)/'`d1_pkt.c + +libssl_la-d1_srtp.lo: d1_srtp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-d1_srtp.lo -MD -MP -MF $(DEPDIR)/libssl_la-d1_srtp.Tpo -c -o libssl_la-d1_srtp.lo `test -f 'd1_srtp.c' || echo '$(srcdir)/'`d1_srtp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-d1_srtp.Tpo $(DEPDIR)/libssl_la-d1_srtp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='d1_srtp.c' object='libssl_la-d1_srtp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-d1_srtp.lo `test -f 'd1_srtp.c' || echo '$(srcdir)/'`d1_srtp.c + +libssl_la-pqueue.lo: pqueue.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-pqueue.lo -MD -MP -MF $(DEPDIR)/libssl_la-pqueue.Tpo -c -o libssl_la-pqueue.lo `test -f 'pqueue.c' || echo '$(srcdir)/'`pqueue.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-pqueue.Tpo $(DEPDIR)/libssl_la-pqueue.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pqueue.c' object='libssl_la-pqueue.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-pqueue.lo `test -f 'pqueue.c' || echo '$(srcdir)/'`pqueue.c + +libssl_la-s3_cbc.lo: s3_cbc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-s3_cbc.lo -MD -MP -MF $(DEPDIR)/libssl_la-s3_cbc.Tpo -c -o libssl_la-s3_cbc.lo `test -f 's3_cbc.c' || echo '$(srcdir)/'`s3_cbc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-s3_cbc.Tpo $(DEPDIR)/libssl_la-s3_cbc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='s3_cbc.c' object='libssl_la-s3_cbc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-s3_cbc.lo `test -f 's3_cbc.c' || echo '$(srcdir)/'`s3_cbc.c + +libssl_la-s3_lib.lo: s3_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-s3_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-s3_lib.Tpo -c -o libssl_la-s3_lib.lo `test -f 's3_lib.c' || echo '$(srcdir)/'`s3_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-s3_lib.Tpo $(DEPDIR)/libssl_la-s3_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='s3_lib.c' object='libssl_la-s3_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-s3_lib.lo `test -f 's3_lib.c' || echo '$(srcdir)/'`s3_lib.c + +libssl_la-ssl_algs.lo: ssl_algs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_algs.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_algs.Tpo -c -o libssl_la-ssl_algs.lo `test -f 'ssl_algs.c' || echo '$(srcdir)/'`ssl_algs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_algs.Tpo $(DEPDIR)/libssl_la-ssl_algs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_algs.c' object='libssl_la-ssl_algs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_algs.lo `test -f 'ssl_algs.c' || echo '$(srcdir)/'`ssl_algs.c + +libssl_la-ssl_asn1.lo: ssl_asn1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_asn1.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_asn1.Tpo -c -o libssl_la-ssl_asn1.lo `test -f 'ssl_asn1.c' || echo '$(srcdir)/'`ssl_asn1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_asn1.Tpo $(DEPDIR)/libssl_la-ssl_asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_asn1.c' object='libssl_la-ssl_asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_asn1.lo `test -f 'ssl_asn1.c' || echo '$(srcdir)/'`ssl_asn1.c + +libssl_la-ssl_both.lo: ssl_both.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_both.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_both.Tpo -c -o libssl_la-ssl_both.lo `test -f 'ssl_both.c' || echo '$(srcdir)/'`ssl_both.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_both.Tpo $(DEPDIR)/libssl_la-ssl_both.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_both.c' object='libssl_la-ssl_both.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_both.lo `test -f 'ssl_both.c' || echo '$(srcdir)/'`ssl_both.c + +libssl_la-ssl_cert.lo: ssl_cert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_cert.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_cert.Tpo -c -o libssl_la-ssl_cert.lo `test -f 'ssl_cert.c' || echo '$(srcdir)/'`ssl_cert.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_cert.Tpo $(DEPDIR)/libssl_la-ssl_cert.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_cert.c' object='libssl_la-ssl_cert.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_cert.lo `test -f 'ssl_cert.c' || echo '$(srcdir)/'`ssl_cert.c + +libssl_la-ssl_ciph.lo: ssl_ciph.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_ciph.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_ciph.Tpo -c -o libssl_la-ssl_ciph.lo `test -f 'ssl_ciph.c' || echo '$(srcdir)/'`ssl_ciph.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_ciph.Tpo $(DEPDIR)/libssl_la-ssl_ciph.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_ciph.c' object='libssl_la-ssl_ciph.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_ciph.lo `test -f 'ssl_ciph.c' || echo '$(srcdir)/'`ssl_ciph.c + +libssl_la-ssl_ciphers.lo: ssl_ciphers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_ciphers.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_ciphers.Tpo -c -o libssl_la-ssl_ciphers.lo `test -f 'ssl_ciphers.c' || echo '$(srcdir)/'`ssl_ciphers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_ciphers.Tpo $(DEPDIR)/libssl_la-ssl_ciphers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_ciphers.c' object='libssl_la-ssl_ciphers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_ciphers.lo `test -f 'ssl_ciphers.c' || echo '$(srcdir)/'`ssl_ciphers.c + +libssl_la-ssl_clnt.lo: ssl_clnt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_clnt.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_clnt.Tpo -c -o libssl_la-ssl_clnt.lo `test -f 'ssl_clnt.c' || echo '$(srcdir)/'`ssl_clnt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_clnt.Tpo $(DEPDIR)/libssl_la-ssl_clnt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_clnt.c' object='libssl_la-ssl_clnt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_clnt.lo `test -f 'ssl_clnt.c' || echo '$(srcdir)/'`ssl_clnt.c + +libssl_la-ssl_err.lo: ssl_err.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_err.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_err.Tpo -c -o libssl_la-ssl_err.lo `test -f 'ssl_err.c' || echo '$(srcdir)/'`ssl_err.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_err.Tpo $(DEPDIR)/libssl_la-ssl_err.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_err.c' object='libssl_la-ssl_err.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_err.lo `test -f 'ssl_err.c' || echo '$(srcdir)/'`ssl_err.c + +libssl_la-ssl_init.lo: ssl_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_init.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_init.Tpo -c -o libssl_la-ssl_init.lo `test -f 'ssl_init.c' || echo '$(srcdir)/'`ssl_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_init.Tpo $(DEPDIR)/libssl_la-ssl_init.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_init.c' object='libssl_la-ssl_init.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_init.lo `test -f 'ssl_init.c' || echo '$(srcdir)/'`ssl_init.c + +libssl_la-ssl_kex.lo: ssl_kex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_kex.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_kex.Tpo -c -o libssl_la-ssl_kex.lo `test -f 'ssl_kex.c' || echo '$(srcdir)/'`ssl_kex.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_kex.Tpo $(DEPDIR)/libssl_la-ssl_kex.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_kex.c' object='libssl_la-ssl_kex.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_kex.lo `test -f 'ssl_kex.c' || echo '$(srcdir)/'`ssl_kex.c + +libssl_la-ssl_lib.lo: ssl_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_lib.Tpo -c -o libssl_la-ssl_lib.lo `test -f 'ssl_lib.c' || echo '$(srcdir)/'`ssl_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_lib.Tpo $(DEPDIR)/libssl_la-ssl_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_lib.c' object='libssl_la-ssl_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_lib.lo `test -f 'ssl_lib.c' || echo '$(srcdir)/'`ssl_lib.c + +libssl_la-ssl_methods.lo: ssl_methods.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_methods.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_methods.Tpo -c -o libssl_la-ssl_methods.lo `test -f 'ssl_methods.c' || echo '$(srcdir)/'`ssl_methods.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_methods.Tpo $(DEPDIR)/libssl_la-ssl_methods.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_methods.c' object='libssl_la-ssl_methods.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_methods.lo `test -f 'ssl_methods.c' || echo '$(srcdir)/'`ssl_methods.c + +libssl_la-ssl_packet.lo: ssl_packet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_packet.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_packet.Tpo -c -o libssl_la-ssl_packet.lo `test -f 'ssl_packet.c' || echo '$(srcdir)/'`ssl_packet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_packet.Tpo $(DEPDIR)/libssl_la-ssl_packet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_packet.c' object='libssl_la-ssl_packet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_packet.lo `test -f 'ssl_packet.c' || echo '$(srcdir)/'`ssl_packet.c + +libssl_la-ssl_pkt.lo: ssl_pkt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_pkt.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_pkt.Tpo -c -o libssl_la-ssl_pkt.lo `test -f 'ssl_pkt.c' || echo '$(srcdir)/'`ssl_pkt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_pkt.Tpo $(DEPDIR)/libssl_la-ssl_pkt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_pkt.c' object='libssl_la-ssl_pkt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_pkt.lo `test -f 'ssl_pkt.c' || echo '$(srcdir)/'`ssl_pkt.c + +libssl_la-ssl_rsa.lo: ssl_rsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_rsa.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_rsa.Tpo -c -o libssl_la-ssl_rsa.lo `test -f 'ssl_rsa.c' || echo '$(srcdir)/'`ssl_rsa.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_rsa.Tpo $(DEPDIR)/libssl_la-ssl_rsa.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_rsa.c' object='libssl_la-ssl_rsa.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_rsa.lo `test -f 'ssl_rsa.c' || echo '$(srcdir)/'`ssl_rsa.c + +libssl_la-ssl_seclevel.lo: ssl_seclevel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_seclevel.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_seclevel.Tpo -c -o libssl_la-ssl_seclevel.lo `test -f 'ssl_seclevel.c' || echo '$(srcdir)/'`ssl_seclevel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_seclevel.Tpo $(DEPDIR)/libssl_la-ssl_seclevel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_seclevel.c' object='libssl_la-ssl_seclevel.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_seclevel.lo `test -f 'ssl_seclevel.c' || echo '$(srcdir)/'`ssl_seclevel.c + +libssl_la-ssl_sess.lo: ssl_sess.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_sess.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_sess.Tpo -c -o libssl_la-ssl_sess.lo `test -f 'ssl_sess.c' || echo '$(srcdir)/'`ssl_sess.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_sess.Tpo $(DEPDIR)/libssl_la-ssl_sess.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_sess.c' object='libssl_la-ssl_sess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_sess.lo `test -f 'ssl_sess.c' || echo '$(srcdir)/'`ssl_sess.c + +libssl_la-ssl_sigalgs.lo: ssl_sigalgs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_sigalgs.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_sigalgs.Tpo -c -o libssl_la-ssl_sigalgs.lo `test -f 'ssl_sigalgs.c' || echo '$(srcdir)/'`ssl_sigalgs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_sigalgs.Tpo $(DEPDIR)/libssl_la-ssl_sigalgs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_sigalgs.c' object='libssl_la-ssl_sigalgs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_sigalgs.lo `test -f 'ssl_sigalgs.c' || echo '$(srcdir)/'`ssl_sigalgs.c + +libssl_la-ssl_srvr.lo: ssl_srvr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_srvr.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_srvr.Tpo -c -o libssl_la-ssl_srvr.lo `test -f 'ssl_srvr.c' || echo '$(srcdir)/'`ssl_srvr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_srvr.Tpo $(DEPDIR)/libssl_la-ssl_srvr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_srvr.c' object='libssl_la-ssl_srvr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_srvr.lo `test -f 'ssl_srvr.c' || echo '$(srcdir)/'`ssl_srvr.c + +libssl_la-ssl_stat.lo: ssl_stat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_stat.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_stat.Tpo -c -o libssl_la-ssl_stat.lo `test -f 'ssl_stat.c' || echo '$(srcdir)/'`ssl_stat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_stat.Tpo $(DEPDIR)/libssl_la-ssl_stat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_stat.c' object='libssl_la-ssl_stat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_stat.lo `test -f 'ssl_stat.c' || echo '$(srcdir)/'`ssl_stat.c + +libssl_la-ssl_tlsext.lo: ssl_tlsext.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_tlsext.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_tlsext.Tpo -c -o libssl_la-ssl_tlsext.lo `test -f 'ssl_tlsext.c' || echo '$(srcdir)/'`ssl_tlsext.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_tlsext.Tpo $(DEPDIR)/libssl_la-ssl_tlsext.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_tlsext.c' object='libssl_la-ssl_tlsext.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_tlsext.lo `test -f 'ssl_tlsext.c' || echo '$(srcdir)/'`ssl_tlsext.c + +libssl_la-ssl_transcript.lo: ssl_transcript.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_transcript.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_transcript.Tpo -c -o libssl_la-ssl_transcript.lo `test -f 'ssl_transcript.c' || echo '$(srcdir)/'`ssl_transcript.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_transcript.Tpo $(DEPDIR)/libssl_la-ssl_transcript.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_transcript.c' object='libssl_la-ssl_transcript.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_transcript.lo `test -f 'ssl_transcript.c' || echo '$(srcdir)/'`ssl_transcript.c + +libssl_la-ssl_txt.lo: ssl_txt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_txt.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_txt.Tpo -c -o libssl_la-ssl_txt.lo `test -f 'ssl_txt.c' || echo '$(srcdir)/'`ssl_txt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_txt.Tpo $(DEPDIR)/libssl_la-ssl_txt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_txt.c' object='libssl_la-ssl_txt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_txt.lo `test -f 'ssl_txt.c' || echo '$(srcdir)/'`ssl_txt.c + +libssl_la-ssl_versions.lo: ssl_versions.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-ssl_versions.lo -MD -MP -MF $(DEPDIR)/libssl_la-ssl_versions.Tpo -c -o libssl_la-ssl_versions.lo `test -f 'ssl_versions.c' || echo '$(srcdir)/'`ssl_versions.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-ssl_versions.Tpo $(DEPDIR)/libssl_la-ssl_versions.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_versions.c' object='libssl_la-ssl_versions.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-ssl_versions.lo `test -f 'ssl_versions.c' || echo '$(srcdir)/'`ssl_versions.c + +libssl_la-t1_enc.lo: t1_enc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-t1_enc.lo -MD -MP -MF $(DEPDIR)/libssl_la-t1_enc.Tpo -c -o libssl_la-t1_enc.lo `test -f 't1_enc.c' || echo '$(srcdir)/'`t1_enc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-t1_enc.Tpo $(DEPDIR)/libssl_la-t1_enc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_enc.c' object='libssl_la-t1_enc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-t1_enc.lo `test -f 't1_enc.c' || echo '$(srcdir)/'`t1_enc.c + +libssl_la-t1_lib.lo: t1_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-t1_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-t1_lib.Tpo -c -o libssl_la-t1_lib.lo `test -f 't1_lib.c' || echo '$(srcdir)/'`t1_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-t1_lib.Tpo $(DEPDIR)/libssl_la-t1_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_lib.c' object='libssl_la-t1_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-t1_lib.lo `test -f 't1_lib.c' || echo '$(srcdir)/'`t1_lib.c + +libssl_la-tls_buffer.lo: tls_buffer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls_buffer.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls_buffer.Tpo -c -o libssl_la-tls_buffer.lo `test -f 'tls_buffer.c' || echo '$(srcdir)/'`tls_buffer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls_buffer.Tpo $(DEPDIR)/libssl_la-tls_buffer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_buffer.c' object='libssl_la-tls_buffer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls_buffer.lo `test -f 'tls_buffer.c' || echo '$(srcdir)/'`tls_buffer.c + +libssl_la-tls_content.lo: tls_content.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls_content.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls_content.Tpo -c -o libssl_la-tls_content.lo `test -f 'tls_content.c' || echo '$(srcdir)/'`tls_content.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls_content.Tpo $(DEPDIR)/libssl_la-tls_content.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_content.c' object='libssl_la-tls_content.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls_content.lo `test -f 'tls_content.c' || echo '$(srcdir)/'`tls_content.c + +libssl_la-tls_key_share.lo: tls_key_share.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls_key_share.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls_key_share.Tpo -c -o libssl_la-tls_key_share.lo `test -f 'tls_key_share.c' || echo '$(srcdir)/'`tls_key_share.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls_key_share.Tpo $(DEPDIR)/libssl_la-tls_key_share.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_key_share.c' object='libssl_la-tls_key_share.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls_key_share.lo `test -f 'tls_key_share.c' || echo '$(srcdir)/'`tls_key_share.c + +libssl_la-tls_lib.lo: tls_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls_lib.Tpo -c -o libssl_la-tls_lib.lo `test -f 'tls_lib.c' || echo '$(srcdir)/'`tls_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls_lib.Tpo $(DEPDIR)/libssl_la-tls_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_lib.c' object='libssl_la-tls_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls_lib.lo `test -f 'tls_lib.c' || echo '$(srcdir)/'`tls_lib.c + +libssl_la-tls12_key_schedule.lo: tls12_key_schedule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls12_key_schedule.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls12_key_schedule.Tpo -c -o libssl_la-tls12_key_schedule.lo `test -f 'tls12_key_schedule.c' || echo '$(srcdir)/'`tls12_key_schedule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls12_key_schedule.Tpo $(DEPDIR)/libssl_la-tls12_key_schedule.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls12_key_schedule.c' object='libssl_la-tls12_key_schedule.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls12_key_schedule.lo `test -f 'tls12_key_schedule.c' || echo '$(srcdir)/'`tls12_key_schedule.c + +libssl_la-tls12_lib.lo: tls12_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls12_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls12_lib.Tpo -c -o libssl_la-tls12_lib.lo `test -f 'tls12_lib.c' || echo '$(srcdir)/'`tls12_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls12_lib.Tpo $(DEPDIR)/libssl_la-tls12_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls12_lib.c' object='libssl_la-tls12_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls12_lib.lo `test -f 'tls12_lib.c' || echo '$(srcdir)/'`tls12_lib.c + +libssl_la-tls12_record_layer.lo: tls12_record_layer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls12_record_layer.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls12_record_layer.Tpo -c -o libssl_la-tls12_record_layer.lo `test -f 'tls12_record_layer.c' || echo '$(srcdir)/'`tls12_record_layer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls12_record_layer.Tpo $(DEPDIR)/libssl_la-tls12_record_layer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls12_record_layer.c' object='libssl_la-tls12_record_layer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls12_record_layer.lo `test -f 'tls12_record_layer.c' || echo '$(srcdir)/'`tls12_record_layer.c + +libssl_la-tls13_client.lo: tls13_client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_client.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_client.Tpo -c -o libssl_la-tls13_client.lo `test -f 'tls13_client.c' || echo '$(srcdir)/'`tls13_client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_client.Tpo $(DEPDIR)/libssl_la-tls13_client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_client.c' object='libssl_la-tls13_client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_client.lo `test -f 'tls13_client.c' || echo '$(srcdir)/'`tls13_client.c + +libssl_la-tls13_error.lo: tls13_error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_error.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_error.Tpo -c -o libssl_la-tls13_error.lo `test -f 'tls13_error.c' || echo '$(srcdir)/'`tls13_error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_error.Tpo $(DEPDIR)/libssl_la-tls13_error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_error.c' object='libssl_la-tls13_error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_error.lo `test -f 'tls13_error.c' || echo '$(srcdir)/'`tls13_error.c + +libssl_la-tls13_handshake.lo: tls13_handshake.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_handshake.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_handshake.Tpo -c -o libssl_la-tls13_handshake.lo `test -f 'tls13_handshake.c' || echo '$(srcdir)/'`tls13_handshake.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_handshake.Tpo $(DEPDIR)/libssl_la-tls13_handshake.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_handshake.c' object='libssl_la-tls13_handshake.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_handshake.lo `test -f 'tls13_handshake.c' || echo '$(srcdir)/'`tls13_handshake.c + +libssl_la-tls13_handshake_msg.lo: tls13_handshake_msg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_handshake_msg.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_handshake_msg.Tpo -c -o libssl_la-tls13_handshake_msg.lo `test -f 'tls13_handshake_msg.c' || echo '$(srcdir)/'`tls13_handshake_msg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_handshake_msg.Tpo $(DEPDIR)/libssl_la-tls13_handshake_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_handshake_msg.c' object='libssl_la-tls13_handshake_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_handshake_msg.lo `test -f 'tls13_handshake_msg.c' || echo '$(srcdir)/'`tls13_handshake_msg.c + +libssl_la-tls13_key_schedule.lo: tls13_key_schedule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_key_schedule.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_key_schedule.Tpo -c -o libssl_la-tls13_key_schedule.lo `test -f 'tls13_key_schedule.c' || echo '$(srcdir)/'`tls13_key_schedule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_key_schedule.Tpo $(DEPDIR)/libssl_la-tls13_key_schedule.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_key_schedule.c' object='libssl_la-tls13_key_schedule.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_key_schedule.lo `test -f 'tls13_key_schedule.c' || echo '$(srcdir)/'`tls13_key_schedule.c + +libssl_la-tls13_legacy.lo: tls13_legacy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_legacy.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_legacy.Tpo -c -o libssl_la-tls13_legacy.lo `test -f 'tls13_legacy.c' || echo '$(srcdir)/'`tls13_legacy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_legacy.Tpo $(DEPDIR)/libssl_la-tls13_legacy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_legacy.c' object='libssl_la-tls13_legacy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_legacy.lo `test -f 'tls13_legacy.c' || echo '$(srcdir)/'`tls13_legacy.c + +libssl_la-tls13_lib.lo: tls13_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_lib.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_lib.Tpo -c -o libssl_la-tls13_lib.lo `test -f 'tls13_lib.c' || echo '$(srcdir)/'`tls13_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_lib.Tpo $(DEPDIR)/libssl_la-tls13_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_lib.c' object='libssl_la-tls13_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_lib.lo `test -f 'tls13_lib.c' || echo '$(srcdir)/'`tls13_lib.c + +libssl_la-tls13_quic.lo: tls13_quic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_quic.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_quic.Tpo -c -o libssl_la-tls13_quic.lo `test -f 'tls13_quic.c' || echo '$(srcdir)/'`tls13_quic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_quic.Tpo $(DEPDIR)/libssl_la-tls13_quic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_quic.c' object='libssl_la-tls13_quic.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_quic.lo `test -f 'tls13_quic.c' || echo '$(srcdir)/'`tls13_quic.c + +libssl_la-tls13_record.lo: tls13_record.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_record.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_record.Tpo -c -o libssl_la-tls13_record.lo `test -f 'tls13_record.c' || echo '$(srcdir)/'`tls13_record.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_record.Tpo $(DEPDIR)/libssl_la-tls13_record.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_record.c' object='libssl_la-tls13_record.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_record.lo `test -f 'tls13_record.c' || echo '$(srcdir)/'`tls13_record.c + +libssl_la-tls13_record_layer.lo: tls13_record_layer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_record_layer.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_record_layer.Tpo -c -o libssl_la-tls13_record_layer.lo `test -f 'tls13_record_layer.c' || echo '$(srcdir)/'`tls13_record_layer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_record_layer.Tpo $(DEPDIR)/libssl_la-tls13_record_layer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_record_layer.c' object='libssl_la-tls13_record_layer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_record_layer.lo `test -f 'tls13_record_layer.c' || echo '$(srcdir)/'`tls13_record_layer.c + +libssl_la-tls13_server.lo: tls13_server.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libssl_la-tls13_server.lo -MD -MP -MF $(DEPDIR)/libssl_la-tls13_server.Tpo -c -o libssl_la-tls13_server.lo `test -f 'tls13_server.c' || echo '$(srcdir)/'`tls13_server.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libssl_la-tls13_server.Tpo $(DEPDIR)/libssl_la-tls13_server.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls13_server.c' object='libssl_la-tls13_server.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libssl_la-tls13_server.lo `test -f 'tls13_server.c' || echo '$(srcdir)/'`tls13_server.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/bs_ber.Plo + -rm -f ./$(DEPDIR)/bs_cbb.Plo + -rm -f ./$(DEPDIR)/bs_cbs.Plo + -rm -f ./$(DEPDIR)/libssl_la-bio_ssl.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_both.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_pkt.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_srtp.Plo + -rm -f ./$(DEPDIR)/libssl_la-pqueue.Plo + -rm -f ./$(DEPDIR)/libssl_la-s3_cbc.Plo + -rm -f ./$(DEPDIR)/libssl_la-s3_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_algs.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_asn1.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_both.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_cert.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_ciph.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_ciphers.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_clnt.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_err.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_init.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_kex.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_methods.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_packet.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_pkt.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_rsa.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_seclevel.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_sess.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_sigalgs.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_srvr.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_stat.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_tlsext.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_transcript.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_txt.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_versions.Plo + -rm -f ./$(DEPDIR)/libssl_la-t1_enc.Plo + -rm -f ./$(DEPDIR)/libssl_la-t1_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls12_key_schedule.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls12_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls12_record_layer.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_client.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_error.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_handshake.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_handshake_msg.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_key_schedule.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_legacy.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_quic.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_record.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_record_layer.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_server.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_buffer.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_content.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_key_share.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_lib.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/bs_ber.Plo + -rm -f ./$(DEPDIR)/bs_cbb.Plo + -rm -f ./$(DEPDIR)/bs_cbs.Plo + -rm -f ./$(DEPDIR)/libssl_la-bio_ssl.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_both.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_pkt.Plo + -rm -f ./$(DEPDIR)/libssl_la-d1_srtp.Plo + -rm -f ./$(DEPDIR)/libssl_la-pqueue.Plo + -rm -f ./$(DEPDIR)/libssl_la-s3_cbc.Plo + -rm -f ./$(DEPDIR)/libssl_la-s3_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_algs.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_asn1.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_both.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_cert.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_ciph.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_ciphers.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_clnt.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_err.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_init.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_kex.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_methods.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_packet.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_pkt.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_rsa.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_seclevel.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_sess.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_sigalgs.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_srvr.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_stat.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_tlsext.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_transcript.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_txt.Plo + -rm -f ./$(DEPDIR)/libssl_la-ssl_versions.Plo + -rm -f ./$(DEPDIR)/libssl_la-t1_enc.Plo + -rm -f ./$(DEPDIR)/libssl_la-t1_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls12_key_schedule.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls12_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls12_record_layer.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_client.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_error.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_handshake.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_handshake_msg.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_key_schedule.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_legacy.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_lib.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_quic.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_record.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_record_layer.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls13_server.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_buffer.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_content.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_key_share.Plo + -rm -f ./$(DEPDIR)/libssl_la-tls_lib.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +-include $(abs_top_builddir)/crypto/libcrypto_la_objects.mk + +libssl_la_objects.mk: Makefile + @echo "libssl_la_objects= $(libssl_la_OBJECTS)" \ + | sed 's/ */ $$\(abs_top_builddir\)\/ssl\//g' \ + > libssl_la_objects.mk + +.PHONY: remove_bs_objects +remove_bs_objects: libssl.la + -$(AR) dv $(abs_top_builddir)/ssl/.libs/libssl.a \ + bs_ber.o bs_cbb.o bs_cbs.o + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Libraries/libressl/ssl/VERSION b/Libraries/libressl/ssl/VERSION new file mode 100644 index 000000000..f3d740eb7 --- /dev/null +++ b/Libraries/libressl/ssl/VERSION @@ -0,0 +1 @@ +55:0:0 diff --git a/Libraries/libressl/ssl/bio_ssl.c b/Libraries/libressl/ssl/bio_ssl.c new file mode 100644 index 000000000..6dd169960 --- /dev/null +++ b/Libraries/libressl/ssl/bio_ssl.c @@ -0,0 +1,596 @@ +/* $OpenBSD: bio_ssl.c,v 1.40 2023/07/19 13:34:33 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "bio_local.h" +#include "ssl_local.h" + +static int ssl_write(BIO *h, const char *buf, int num); +static int ssl_read(BIO *h, char *buf, int size); +static int ssl_puts(BIO *h, const char *str); +static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int ssl_new(BIO *h); +static int ssl_free(BIO *data); +static long ssl_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); +typedef struct bio_ssl_st { + SSL *ssl; /* The ssl handle :-) */ + /* re-negotiate every time the total number of bytes is this size */ + int num_renegotiates; + unsigned long renegotiate_count; + unsigned long byte_count; + unsigned long renegotiate_timeout; + time_t last_time; +} BIO_SSL; + +static const BIO_METHOD methods_sslp = { + .type = BIO_TYPE_SSL, + .name = "ssl", + .bwrite = ssl_write, + .bread = ssl_read, + .bputs = ssl_puts, + .ctrl = ssl_ctrl, + .create = ssl_new, + .destroy = ssl_free, + .callback_ctrl = ssl_callback_ctrl, +}; + +const BIO_METHOD * +BIO_f_ssl(void) +{ + return (&methods_sslp); +} +LSSL_ALIAS(BIO_f_ssl); + +static int +ssl_new(BIO *bi) +{ + BIO_SSL *bs; + + bs = calloc(1, sizeof(BIO_SSL)); + if (bs == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (0); + } + bi->init = 0; + bi->ptr = (char *)bs; + bi->flags = 0; + return (1); +} +LSSL_ALIAS(BIO_f_ssl); + +static int +ssl_free(BIO *a) +{ + BIO_SSL *bs; + + if (a == NULL) + return (0); + bs = (BIO_SSL *)a->ptr; + if (bs->ssl != NULL) + SSL_shutdown(bs->ssl); + if (a->shutdown) { + if (a->init && (bs->ssl != NULL)) + SSL_free(bs->ssl); + a->init = 0; + a->flags = 0; + } + free(a->ptr); + return (1); +} + +static int +ssl_read(BIO *b, char *out, int outl) +{ + int ret = 1; + BIO_SSL *sb; + SSL *ssl; + int retry_reason = 0; + int r = 0; + + if (out == NULL) + return (0); + sb = (BIO_SSL *)b->ptr; + ssl = sb->ssl; + + BIO_clear_retry_flags(b); + + ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (sb->renegotiate_count > 0) { + sb->byte_count += ret; + if (sb->byte_count > sb->renegotiate_count) { + sb->byte_count = 0; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((sb->renegotiate_timeout > 0) && (!r)) { + time_t tm; + + tm = time(NULL); + if (tm > sb->last_time + sb->renegotiate_timeout) { + sb->last_time = tm; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_ACCEPT; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static int +ssl_write(BIO *b, const char *out, int outl) +{ + int ret, r = 0; + int retry_reason = 0; + SSL *ssl; + BIO_SSL *bs; + + if (out == NULL) + return (0); + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + + BIO_clear_retry_flags(b); + +/* ret=SSL_do_handshake(ssl); + if (ret > 0) */ + ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (bs->renegotiate_count > 0) { + bs->byte_count += ret; + if (bs->byte_count > bs->renegotiate_count) { + bs->byte_count = 0; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((bs->renegotiate_timeout > 0) && (!r)) { + time_t tm; + + tm = time(NULL); + if (tm > bs->last_time + bs->renegotiate_timeout) { + bs->last_time = tm; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static long +ssl_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + SSL **sslp, *ssl; + BIO_SSL *bs; + BIO *dbio, *bio; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) + return (0); + switch (cmd) { + case BIO_CTRL_RESET: + SSL_shutdown(ssl); + + if (ssl->handshake_func == ssl->method->ssl_connect) + SSL_set_connect_state(ssl); + else if (ssl->handshake_func == ssl->method->ssl_accept) + SSL_set_accept_state(ssl); + + SSL_clear(ssl); + + if (b->next_bio != NULL) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + else if (ssl->rbio != NULL) + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + else + ret = 1; + break; + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SSL_MODE: + if (num) /* client mode */ + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + break; + case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: + ret = bs->renegotiate_timeout; + if (num < 60) + num = 5; + bs->renegotiate_timeout = (unsigned long)num; + bs->last_time = time(NULL); + break; + case BIO_C_SET_SSL_RENEGOTIATE_BYTES: + ret = bs->renegotiate_count; + if ((long)num >=512) + bs->renegotiate_count = (unsigned long)num; + break; + case BIO_C_GET_SSL_NUM_RENEGOTIATES: + ret = bs->num_renegotiates; + break; + case BIO_C_SET_SSL: + if (ssl != NULL) { + ssl_free(b); + if (!ssl_new(b)) + return 0; + } + b->shutdown = (int)num; + ssl = (SSL *)ptr; + ((BIO_SSL *)b->ptr)->ssl = ssl; + bio = SSL_get_rbio(ssl); + if (bio != NULL) { + if (b->next_bio != NULL) + BIO_push(bio, b->next_bio); + b->next_bio = bio; + CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); + } + b->init = 1; + break; + case BIO_C_GET_SSL: + if (ptr != NULL) { + sslp = (SSL **)ptr; + *sslp = ssl; + } else + ret = 0; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_WPENDING: + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: + ret = SSL_pending(ssl); + if (ret == 0) + ret = BIO_pending(ssl->rbio); + break; + case BIO_CTRL_FLUSH: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_PUSH: + if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { + SSL_set_bio(ssl, b->next_bio, b->next_bio); + CRYPTO_add(&b->next_bio->references, 1, + CRYPTO_LOCK_BIO); + } + break; + case BIO_CTRL_POP: + /* Only detach if we are the BIO explicitly being popped */ + if (b == ptr) { + /* Shouldn't happen in practice because the + * rbio and wbio are the same when pushed. + */ + if (ssl->rbio != ssl->wbio) + BIO_free_all(ssl->wbio); + if (b->next_bio != NULL) + CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO); + ssl->wbio = NULL; + ssl->rbio = NULL; + } + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + + b->retry_reason = 0; + ret = (int)SSL_do_handshake(ssl); + + switch (SSL_get_error(ssl, (int)ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_flags(b, + BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_flags(b, + BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_flags(b, + BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); + b->retry_reason = b->next_bio->retry_reason; + break; + default: + break; + } + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (((BIO_SSL *)dbio->ptr)->ssl != NULL) + SSL_free(((BIO_SSL *)dbio->ptr)->ssl); + ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl); + ((BIO_SSL *)dbio->ptr)->renegotiate_count = + ((BIO_SSL *)b->ptr)->renegotiate_count; + ((BIO_SSL *)dbio->ptr)->byte_count = + ((BIO_SSL *)b->ptr)->byte_count; + ((BIO_SSL *)dbio->ptr)->renegotiate_timeout = + ((BIO_SSL *)b->ptr)->renegotiate_timeout; + ((BIO_SSL *)dbio->ptr)->last_time = + ((BIO_SSL *)b->ptr)->last_time; + ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL); + break; + case BIO_C_GET_FD: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + case BIO_CTRL_SET_CALLBACK: + { + ret = 0; + } + break; + case BIO_CTRL_GET_CALLBACK: + { + void (**fptr)(const SSL *xssl, int type, int val); + + fptr = (void (**)(const SSL *xssl, int type, int val)) + ptr; + *fptr = SSL_get_info_callback(ssl); + } + break; + default: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + } + return (ret); +} + +static long +ssl_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + SSL *ssl; + BIO_SSL *bs; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + { + /* FIXME: setting this via a completely different prototype + seems like a crap idea */ + SSL_set_info_callback(ssl, + (void (*)(const SSL *, int, int))fp); + } + break; + default: + ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); + break; + } + return (ret); +} + +static int +ssl_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = BIO_write(bp, str, n); + return (ret); +} + +BIO * +BIO_new_buffer_ssl_connect(SSL_CTX *ctx) +{ + BIO *ret = NULL, *buf = NULL, *ssl = NULL; + + if ((buf = BIO_new(BIO_f_buffer())) == NULL) + goto err; + if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) + goto err; + if ((ret = BIO_push(buf, ssl)) == NULL) + goto err; + return (ret); + + err: + BIO_free(buf); + BIO_free(ssl); + return (NULL); +} +LSSL_ALIAS(BIO_new_buffer_ssl_connect); + +BIO * +BIO_new_ssl_connect(SSL_CTX *ctx) +{ + BIO *ret = NULL, *con = NULL, *ssl = NULL; + + if ((con = BIO_new(BIO_s_connect())) == NULL) + goto err; + if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) + goto err; + if ((ret = BIO_push(ssl, con)) == NULL) + goto err; + return (ret); + + err: + BIO_free(con); + BIO_free(ssl); + return (NULL); +} +LSSL_ALIAS(BIO_new_ssl_connect); + +BIO * +BIO_new_ssl(SSL_CTX *ctx, int client) +{ + BIO *ret; + SSL *ssl; + + if ((ret = BIO_new(BIO_f_ssl())) == NULL) + goto err; + if ((ssl = SSL_new(ctx)) == NULL) + goto err; + + if (client) + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + + BIO_set_ssl(ret, ssl, BIO_CLOSE); + return (ret); + + err: + BIO_free(ret); + return (NULL); +} +LSSL_ALIAS(BIO_new_ssl); + +int +BIO_ssl_copy_session_id(BIO *t, BIO *f) +{ + t = BIO_find_type(t, BIO_TYPE_SSL); + f = BIO_find_type(f, BIO_TYPE_SSL); + if ((t == NULL) || (f == NULL)) + return (0); + if ((((BIO_SSL *)t->ptr)->ssl == NULL) || + (((BIO_SSL *)f->ptr)->ssl == NULL)) + return (0); + if (!SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, + ((BIO_SSL *)f->ptr)->ssl)) + return (0); + return (1); +} +LSSL_ALIAS(BIO_ssl_copy_session_id); + +void +BIO_ssl_shutdown(BIO *b) +{ + SSL *s; + + while (b != NULL) { + if (b->method->type == BIO_TYPE_SSL) { + s = ((BIO_SSL *)b->ptr)->ssl; + SSL_shutdown(s); + break; + } + b = b->next_bio; + } +} +LSSL_ALIAS(BIO_ssl_shutdown); diff --git a/Libraries/libressl/ssl/bs_ber.c b/Libraries/libressl/ssl/bs_ber.c new file mode 100644 index 000000000..5cace24d9 --- /dev/null +++ b/Libraries/libressl/ssl/bs_ber.c @@ -0,0 +1,269 @@ +/* $OpenBSD: bs_ber.c,v 1.11 2021/05/16 10:58:27 jsing Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bytestring.h" + +/* + * kMaxDepth is a just a sanity limit. The code should be such that the length + * of the input being processes always decreases. None the less, a very large + * input could otherwise cause the stack to overflow. + */ +static const unsigned int kMaxDepth = 2048; + +/* Non-strict version that allows a relaxed DER with indefinite form. */ +static int +cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len) +{ + return cbs_get_any_asn1_element_internal(cbs, out, + out_tag, out_header_len, 0); +} + +/* + * cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets + * |*indefinite_found| depending on whether an indefinite length element was + * found. The value of |orig_in| is not modified. + * + * Returns one on success (i.e. |*indefinite_found| was set) and zero on error. + */ +static int +cbs_find_indefinite(const CBS *orig_in, char *indefinite_found, + unsigned int depth) +{ + CBS in; + + if (depth > kMaxDepth) + return 0; + + CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); + + while (CBS_len(&in) > 0) { + CBS contents; + unsigned int tag; + size_t header_len; + + if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag, + &header_len)) + return 0; + + /* Indefinite form not allowed by DER. */ + if (CBS_len(&contents) == header_len && header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + *indefinite_found = 1; + return 1; + } + if (tag & CBS_ASN1_CONSTRUCTED) { + if (!CBS_skip(&contents, header_len) || + !cbs_find_indefinite(&contents, indefinite_found, + depth + 1)) + return 0; + } + } + + *indefinite_found = 0; + return 1; +} + +/* + * is_primitive_type returns true if |tag| likely a primitive type. Normally + * one can just test the "constructed" bit in the tag but, in BER, even + * primitive tags can have the constructed bit if they have indefinite + * length. + */ +static char +is_primitive_type(unsigned int tag) +{ + return (tag & 0xc0) == 0 && + (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) && + (tag & 0x1f) != (CBS_ASN1_SET & 0x1f); +} + +/* + * is_eoc returns true if |header_len| and |contents|, as returned by + * |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC) + * value. + */ +static char +is_eoc(size_t header_len, CBS *contents) +{ + const unsigned char eoc[] = {0x0, 0x0}; + + return header_len == 2 && CBS_mem_equal(contents, eoc, 2); +} + +/* + * cbs_convert_indefinite reads data with DER encoding (but relaxed to allow + * indefinite form) from |in| and writes definite form DER data to |out|. If + * |squash_header| is set then the top-level of elements from |in| will not + * have their headers written. This is used when concatenating the fragments of + * an indefinite length, primitive value. If |looking_for_eoc| is set then any + * EOC elements found will cause the function to return after consuming it. + * It returns one on success and zero on error. + */ +static int +cbs_convert_indefinite(CBS *in, CBB *out, char squash_header, + char looking_for_eoc, unsigned int depth) +{ + if (depth > kMaxDepth) + return 0; + + while (CBS_len(in) > 0) { + CBS contents; + unsigned int tag; + size_t header_len; + CBB *out_contents, out_contents_storage; + + if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag, + &header_len)) + return 0; + + out_contents = out; + + if (CBS_len(&contents) == header_len) { + if (is_eoc(header_len, &contents)) + return looking_for_eoc; + + if (header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + /* + * This is an indefinite length element. If + * it's a SEQUENCE or SET then we just need to + * write the out the contents as normal, but + * with a concrete length prefix. + * + * If it's a something else then the contents + * will be a series of DER elements of the same + * type which need to be concatenated. + */ + const char context_specific = (tag & 0xc0) + == 0x80; + char squash_child_headers = + is_primitive_type(tag); + + /* + * This is a hack, but it sufficies to handle + * NSS's output. If we find an indefinite + * length, context-specific tag with a definite, + * primtive tag inside it, then we assume that + * the context-specific tag is implicit and the + * tags within are fragments of a primitive type + * that need to be concatenated. + */ + if (context_specific && + (tag & CBS_ASN1_CONSTRUCTED)) { + CBS in_copy, inner_contents; + unsigned int inner_tag; + size_t inner_header_len; + + CBS_init(&in_copy, CBS_data(in), + CBS_len(in)); + if (!cbs_nonstrict_get_any_asn1_element( + &in_copy, &inner_contents, + &inner_tag, &inner_header_len)) + return 0; + + if (CBS_len(&inner_contents) > + inner_header_len && + is_primitive_type(inner_tag)) + squash_child_headers = 1; + } + + if (!squash_header) { + unsigned int out_tag = tag; + + if (squash_child_headers) + out_tag &= + ~CBS_ASN1_CONSTRUCTED; + + if (!CBB_add_asn1(out, + &out_contents_storage, out_tag)) + return 0; + + out_contents = &out_contents_storage; + } + + if (!cbs_convert_indefinite(in, out_contents, + squash_child_headers, + 1 /* looking for eoc */, depth + 1)) + return 0; + + if (out_contents != out && !CBB_flush(out)) + return 0; + + continue; + } + } + + if (!squash_header) { + if (!CBB_add_asn1(out, &out_contents_storage, tag)) + return 0; + + out_contents = &out_contents_storage; + } + + if (!CBS_skip(&contents, header_len)) + return 0; + + if (tag & CBS_ASN1_CONSTRUCTED) { + if (!cbs_convert_indefinite(&contents, out_contents, + 0 /* don't squash header */, + 0 /* not looking for eoc */, depth + 1)) + return 0; + } else { + if (!CBB_add_bytes(out_contents, CBS_data(&contents), + CBS_len(&contents))) + return 0; + } + + if (out_contents != out && !CBB_flush(out)) + return 0; + } + + return looking_for_eoc == 0; +} + +int +CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len) +{ + CBB cbb; + + /* + * First, do a quick walk to find any indefinite-length elements. Most + * of the time we hope that there aren't any and thus we can quickly + * return. + */ + char conversion_needed; + if (!cbs_find_indefinite(in, &conversion_needed, 0)) + return 0; + + if (!conversion_needed) { + *out = NULL; + *out_len = 0; + return 1; + } + + if (!CBB_init(&cbb, CBS_len(in))) + return 0; + if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) { + CBB_cleanup(&cbb); + return 0; + } + + return CBB_finish(&cbb, out, out_len); +} diff --git a/Libraries/libressl/ssl/bs_cbb.c b/Libraries/libressl/ssl/bs_cbb.c new file mode 100644 index 000000000..e2f87be4d --- /dev/null +++ b/Libraries/libressl/ssl/bs_cbb.c @@ -0,0 +1,483 @@ +/* $OpenBSD: bs_cbb.c,v 1.28 2022/07/07 17:12:15 tb Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "bytestring.h" + +#define CBB_INITIAL_SIZE 64 + +static int +cbb_init(CBB *cbb, uint8_t *buf, size_t cap) +{ + struct cbb_buffer_st *base; + + if ((base = calloc(1, sizeof(struct cbb_buffer_st))) == NULL) + return 0; + + base->buf = buf; + base->len = 0; + base->cap = cap; + base->can_resize = 1; + + cbb->base = base; + cbb->is_top_level = 1; + + return 1; +} + +int +CBB_init(CBB *cbb, size_t initial_capacity) +{ + uint8_t *buf = NULL; + + memset(cbb, 0, sizeof(*cbb)); + + if (initial_capacity == 0) + initial_capacity = CBB_INITIAL_SIZE; + + if ((buf = calloc(1, initial_capacity)) == NULL) + return 0; + + if (!cbb_init(cbb, buf, initial_capacity)) { + free(buf); + return 0; + } + + return 1; +} + +int +CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) +{ + memset(cbb, 0, sizeof(*cbb)); + + if (!cbb_init(cbb, buf, len)) + return 0; + + cbb->base->can_resize = 0; + + return 1; +} + +void +CBB_cleanup(CBB *cbb) +{ + if (cbb->base) { + if (cbb->base->can_resize) + freezero(cbb->base->buf, cbb->base->cap); + free(cbb->base); + } + cbb->base = NULL; + cbb->child = NULL; +} + +static int +cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len) +{ + size_t newlen; + + if (base == NULL) + return 0; + + newlen = base->len + len; + if (newlen < base->len) + /* Overflow */ + return 0; + + if (newlen > base->cap) { + size_t newcap = base->cap * 2; + uint8_t *newbuf; + + if (!base->can_resize) + return 0; + + if (newcap < base->cap || newcap < newlen) + newcap = newlen; + + newbuf = recallocarray(base->buf, base->cap, newcap, 1); + if (newbuf == NULL) + return 0; + + base->buf = newbuf; + base->cap = newcap; + } + + if (out) + *out = base->buf + base->len; + + base->len = newlen; + return 1; +} + +static int +cbb_add_u(CBB *cbb, uint32_t v, size_t len_len) +{ + uint8_t *buf; + size_t i; + + if (len_len == 0) + return 1; + + if (len_len > 4) + return 0; + + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len)) + return 0; + + for (i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + return 1; +} + +int +CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) +{ + if (!cbb->is_top_level) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) + /* + * |out_data| and |out_len| can only be NULL if the CBB is + * fixed. + */ + return 0; + + if (out_data != NULL && *out_data != NULL) + return 0; + + if (out_data != NULL) + *out_data = cbb->base->buf; + + if (out_len != NULL) + *out_len = cbb->base->len; + + cbb->base->buf = NULL; + CBB_cleanup(cbb); + return 1; +} + +/* + * CBB_flush recurses and then writes out any pending length prefix. The current + * length of the underlying base is taken to be the length of the + * length-prefixed data. + */ +int +CBB_flush(CBB *cbb) +{ + size_t child_start, i, len; + + if (cbb->base == NULL) + return 0; + + if (cbb->child == NULL || cbb->pending_len_len == 0) + return 1; + + child_start = cbb->offset + cbb->pending_len_len; + + if (!CBB_flush(cbb->child) || child_start < cbb->offset || + cbb->base->len < child_start) + return 0; + + len = cbb->base->len - child_start; + + if (cbb->pending_is_asn1) { + /* + * For ASN.1, we assumed that we were using short form which + * only requires a single byte for the length octet. + * + * If it turns out that we need long form, we have to move + * the contents along in order to make space for more length + * octets. + */ + size_t len_len = 1; /* total number of length octets */ + uint8_t initial_length_byte; + + /* We already wrote 1 byte for the length. */ + if (cbb->pending_len_len != 1) + return 0; + + /* Check for long form */ + if (len > 0xfffffffe) + return 0; /* 0xffffffff is reserved */ + else if (len > 0xffffff) + len_len = 5; + else if (len > 0xffff) + len_len = 4; + else if (len > 0xff) + len_len = 3; + else if (len > 0x7f) + len_len = 2; + + if (len_len == 1) { + /* For short form, the initial byte is the length. */ + initial_length_byte = len; + len = 0; + + } else { + /* + * For long form, the initial byte is the number of + * subsequent length octets (plus bit 8 set). + */ + initial_length_byte = 0x80 | (len_len - 1); + + /* + * We need to move the contents along in order to make + * space for the long form length octets. + */ + size_t extra_bytes = len_len - 1; + if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) + return 0; + + memmove(cbb->base->buf + child_start + extra_bytes, + cbb->base->buf + child_start, len); + } + cbb->base->buf[cbb->offset++] = initial_length_byte; + cbb->pending_len_len = len_len - 1; + } + + for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { + cbb->base->buf[cbb->offset + i] = len; + len >>= 8; + } + if (len != 0) + return 0; + + cbb->child->base = NULL; + cbb->child = NULL; + cbb->pending_len_len = 0; + cbb->pending_is_asn1 = 0; + cbb->offset = 0; + + return 1; +} + +void +CBB_discard_child(CBB *cbb) +{ + if (cbb->child == NULL) + return; + + cbb->base->len = cbb->offset; + + cbb->child->base = NULL; + cbb->child = NULL; + cbb->pending_len_len = 0; + cbb->pending_is_asn1 = 0; + cbb->offset = 0; +} + +static int +cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len) +{ + uint8_t *prefix_bytes; + + if (!CBB_flush(cbb)) + return 0; + + cbb->offset = cbb->base->len; + if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) + return 0; + + memset(prefix_bytes, 0, len_len); + memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->pending_len_len = len_len; + cbb->pending_is_asn1 = 0; + + return 1; +} + +int +CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 1); +} + +int +CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 2); +} + +int +CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 3); +} + +int +CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag) +{ + if (tag > UINT8_MAX) + return 0; + + /* Long form identifier octets are not supported. */ + if ((tag & 0x1f) == 0x1f) + return 0; + + /* Short-form identifier octet only needs a single byte */ + if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) + return 0; + + /* + * Add 1 byte to cover the short-form length octet case. If it turns + * out we need long-form, it will be extended later. + */ + cbb->offset = cbb->base->len; + if (!CBB_add_u8(cbb, 0)) + return 0; + + memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->pending_len_len = 1; + cbb->pending_is_asn1 = 1; + + return 1; +} + +int +CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) +{ + uint8_t *dest; + + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len)) + return 0; + + memcpy(dest, data, len); + return 1; +} + +int +CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) +{ + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len)) + return 0; + + memset(*out_data, 0, len); + return 1; +} + +int +CBB_add_u8(CBB *cbb, size_t value) +{ + if (value > UINT8_MAX) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 1); +} + +int +CBB_add_u16(CBB *cbb, size_t value) +{ + if (value > UINT16_MAX) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 2); +} + +int +CBB_add_u24(CBB *cbb, size_t value) +{ + if (value > 0xffffffUL) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 3); +} + +int +CBB_add_u32(CBB *cbb, size_t value) +{ + if (value > 0xffffffffUL) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 4); +} + +int +CBB_add_u64(CBB *cbb, uint64_t value) +{ + uint32_t a, b; + + a = value >> 32; + b = value & 0xffffffff; + + if (!CBB_add_u32(cbb, a)) + return 0; + return CBB_add_u32(cbb, b); +} + +int +CBB_add_asn1_uint64(CBB *cbb, uint64_t value) +{ + CBB child; + size_t i; + int started = 0; + + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) + return 0; + + for (i = 0; i < 8; i++) { + uint8_t byte = (value >> 8 * (7 - i)) & 0xff; + + /* + * ASN.1 restriction: first 9 bits cannot be all zeroes or + * all ones. Since this function only encodes unsigned + * integers, the only concerns are not encoding leading + * zeros and adding a padding byte if necessary. + * + * In practice, this means: + * 1) Skip leading octets of all zero bits in the value + * 2) After skipping the leading zero octets, if the next 9 + * bits are all ones, add an all zero prefix octet (and + * set the high bit of the prefix octet if negative). + * + * Additionally, for an unsigned value, add an all zero + * prefix if the high bit of the first octet would be one. + */ + if (!started) { + if (byte == 0) + /* Don't encode leading zeros. */ + continue; + + /* + * If the high bit is set, add a padding byte to make it + * unsigned. + */ + if ((byte & 0x80) && !CBB_add_u8(&child, 0)) + return 0; + + started = 1; + } + if (!CBB_add_u8(&child, byte)) + return 0; + } + + /* 0 is encoded as a single 0, not the empty string. */ + if (!started && !CBB_add_u8(&child, 0)) + return 0; + + return CBB_flush(cbb); +} diff --git a/Libraries/libressl/ssl/bs_cbs.c b/Libraries/libressl/ssl/bs_cbs.c new file mode 100644 index 000000000..63c078c9b --- /dev/null +++ b/Libraries/libressl/ssl/bs_cbs.c @@ -0,0 +1,615 @@ +/* $OpenBSD: bs_cbs.c,v 1.24 2021/12/15 17:36:49 jsing Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "bytestring.h" + +void +CBS_init(CBS *cbs, const uint8_t *data, size_t len) +{ + cbs->data = data; + cbs->initial_len = len; + cbs->len = len; +} + +void +CBS_dup(const CBS *cbs, CBS *out) +{ + CBS_init(out, CBS_data(cbs), CBS_len(cbs)); + out->initial_len = cbs->initial_len; +} + +static int +cbs_get(CBS *cbs, const uint8_t **p, size_t n) +{ + if (cbs->len < n) + return 0; + + *p = cbs->data; + cbs->data += n; + cbs->len -= n; + return 1; +} + +static int +cbs_peek(CBS *cbs, const uint8_t **p, size_t n) +{ + if (cbs->len < n) + return 0; + + *p = cbs->data; + return 1; +} + +size_t +CBS_offset(const CBS *cbs) +{ + return cbs->initial_len - cbs->len; +} + +int +CBS_skip(CBS *cbs, size_t len) +{ + const uint8_t *dummy; + return cbs_get(cbs, &dummy, len); +} + +const uint8_t * +CBS_data(const CBS *cbs) +{ + return cbs->data; +} + +size_t +CBS_len(const CBS *cbs) +{ + return cbs->len; +} + +int +CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) +{ + free(*out_ptr); + *out_ptr = NULL; + *out_len = 0; + + if (cbs->len == 0) + return 1; + + if ((*out_ptr = malloc(cbs->len)) == NULL) + return 0; + + memcpy(*out_ptr, cbs->data, cbs->len); + + *out_len = cbs->len; + return 1; +} + +int +CBS_strdup(const CBS *cbs, char **out_ptr) +{ + free(*out_ptr); + *out_ptr = NULL; + + if (CBS_contains_zero_byte(cbs)) + return 0; + + *out_ptr = strndup((const char *)cbs->data, cbs->len); + return (*out_ptr != NULL); +} + +int +CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied) +{ + if (dst_len < cbs->len) + return 0; + + memmove(dst, cbs->data, cbs->len); + + if (copied != NULL) + *copied = cbs->len; + + return 1; +} + +int +CBS_contains_zero_byte(const CBS *cbs) +{ + return memchr(cbs->data, 0, cbs->len) != NULL; +} + +int +CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) +{ + if (len != cbs->len) + return 0; + + return timingsafe_memcmp(cbs->data, data, len) == 0; +} + +static int +cbs_get_u(CBS *cbs, uint32_t *out, size_t len) +{ + uint32_t result = 0; + size_t i; + const uint8_t *data; + + if (len < 1 || len > 4) + return 0; + + if (!cbs_get(cbs, &data, len)) + return 0; + + for (i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int +CBS_get_u8(CBS *cbs, uint8_t *out) +{ + const uint8_t *v; + + if (!cbs_get(cbs, &v, 1)) + return 0; + + *out = *v; + return 1; +} + +int +CBS_get_u16(CBS *cbs, uint16_t *out) +{ + uint32_t v; + + if (!cbs_get_u(cbs, &v, 2)) + return 0; + + *out = v; + return 1; +} + +int +CBS_get_u24(CBS *cbs, uint32_t *out) +{ + return cbs_get_u(cbs, out, 3); +} + +int +CBS_get_u32(CBS *cbs, uint32_t *out) +{ + return cbs_get_u(cbs, out, 4); +} + +int +CBS_get_u64(CBS *cbs, uint64_t *out) +{ + uint32_t a, b; + + if (cbs->len < 8) + return 0; + + if (!CBS_get_u32(cbs, &a)) + return 0; + if (!CBS_get_u32(cbs, &b)) + return 0; + + *out = (uint64_t)a << 32 | b; + return 1; +} + +int +CBS_get_last_u8(CBS *cbs, uint8_t *out) +{ + if (cbs->len == 0) + return 0; + + *out = cbs->data[cbs->len - 1]; + cbs->len--; + return 1; +} + +int +CBS_get_bytes(CBS *cbs, CBS *out, size_t len) +{ + const uint8_t *v; + + if (!cbs_get(cbs, &v, len)) + return 0; + + CBS_init(out, v, len); + return 1; +} + +static int +cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) +{ + uint32_t len; + + if (!cbs_get_u(cbs, &len, len_len)) + return 0; + + return CBS_get_bytes(cbs, out, len); +} + +int +CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 1); +} + +int +CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 2); +} + +int +CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 3); +} + +static int +cbs_peek_u(CBS *cbs, uint32_t *out, size_t len) +{ + uint32_t result = 0; + size_t i; + const uint8_t *data; + + if (len < 1 || len > 4) + return 0; + + if (!cbs_peek(cbs, &data, len)) + return 0; + + for (i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int +CBS_peek_u8(CBS *cbs, uint8_t *out) +{ + const uint8_t *v; + + if (!cbs_peek(cbs, &v, 1)) + return 0; + + *out = *v; + return 1; +} + +int +CBS_peek_u16(CBS *cbs, uint16_t *out) +{ + uint32_t v; + + if (!cbs_peek_u(cbs, &v, 2)) + return 0; + + *out = v; + return 1; +} + +int +CBS_peek_u24(CBS *cbs, uint32_t *out) +{ + return cbs_peek_u(cbs, out, 3); +} + +int +CBS_peek_u32(CBS *cbs, uint32_t *out) +{ + return cbs_peek_u(cbs, out, 4); +} + +int +CBS_peek_last_u8(CBS *cbs, uint8_t *out) +{ + if (cbs->len == 0) + return 0; + + *out = cbs->data[cbs->len - 1]; + return 1; +} + +int +CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len) +{ + return cbs_get_any_asn1_element_internal(cbs, out, out_tag, + out_header_len, 1); +} + +/* + * Review X.690 for details on ASN.1 DER encoding. + * + * If non-strict mode is enabled, then DER rules are relaxed + * for indefinite constructs (violates DER but a little closer to BER). + * Non-strict mode should only be used by bs_ber.c + * + * Sections 8, 10 and 11 for DER encoding + */ +int +cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len, int strict) +{ + uint8_t tag, length_byte; + CBS header = *cbs; + CBS throwaway; + size_t len; + + if (out == NULL) + out = &throwaway; + + /* + * Get identifier octet and length octet. Only 1 octet for each + * is a CBS limitation. + */ + if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) + return 0; + + /* CBS limitation: long form tags are not supported. */ + if ((tag & 0x1f) == 0x1f) + return 0; + + if (out_tag != NULL) + *out_tag = tag; + + if ((length_byte & 0x80) == 0) { + /* Short form length. */ + len = ((size_t) length_byte) + 2; + if (out_header_len != NULL) + *out_header_len = 2; + + } else { + /* Long form length. */ + const size_t num_bytes = length_byte & 0x7f; + uint32_t len32; + + /* ASN.1 reserved value for future extensions */ + if (num_bytes == 0x7f) + return 0; + + /* Handle indefinite form length */ + if (num_bytes == 0) { + /* DER encoding doesn't allow for indefinite form. */ + if (strict) + return 0; + + /* Primitive cannot use indefinite in BER or DER. */ + if ((tag & CBS_ASN1_CONSTRUCTED) == 0) + return 0; + + /* Constructed, indefinite length allowed in BER. */ + if (out_header_len != NULL) + *out_header_len = 2; + return CBS_get_bytes(cbs, out, 2); + } + + /* CBS limitation. */ + if (num_bytes > 4) + return 0; + + if (!cbs_get_u(&header, &len32, num_bytes)) + return 0; + + /* DER has a minimum length octet requirement. */ + if (len32 < 128) + /* Should have used short form instead */ + return 0; + + if ((len32 >> ((num_bytes - 1) * 8)) == 0) + /* Length should have been at least one byte shorter. */ + return 0; + + len = len32; + if (len + 2 + num_bytes < len) + /* Overflow. */ + return 0; + + len += 2 + num_bytes; + if (out_header_len != NULL) + *out_header_len = 2 + num_bytes; + } + + return CBS_get_bytes(cbs, out, len); +} + +static int +cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header) +{ + size_t header_len; + unsigned int tag; + CBS throwaway; + + if (out == NULL) + out = &throwaway; + + if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || + tag != tag_value) + return 0; + + if (skip_header && !CBS_skip(out, header_len)) + return 0; + + return 1; +} + +int +CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value) +{ + return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); +} + +int +CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value) +{ + return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); +} + +int +CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value) +{ + if (CBS_len(cbs) < 1) + return 0; + + /* + * Tag number 31 indicates the start of a long form number. + * This is valid in ASN.1, but CBS only supports short form. + */ + if ((tag_value & 0x1f) == 0x1f) + return 0; + + return CBS_data(cbs)[0] == tag_value; +} + +/* Encoding details are in ASN.1: X.690 section 8.3 */ +int +CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) +{ + CBS bytes; + const uint8_t *data; + size_t i, len; + + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) + return 0; + + *out = 0; + data = CBS_data(&bytes); + len = CBS_len(&bytes); + + if (len == 0) + /* An INTEGER is encoded with at least one content octet. */ + return 0; + + if ((data[0] & 0x80) != 0) + /* Negative number. */ + return 0; + + if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) + /* Violates smallest encoding rule: excessive leading zeros. */ + return 0; + + for (i = 0; i < len; i++) { + if ((*out >> 56) != 0) + /* Too large to represent as a uint64_t. */ + return 0; + + *out <<= 8; + *out |= data[i]; + } + + return 1; +} + +int +CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag) +{ + if (CBS_peek_asn1_tag(cbs, tag)) { + if (!CBS_get_asn1(cbs, out, tag)) + return 0; + + *out_present = 1; + } else { + *out_present = 0; + } + return 1; +} + +int +CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned int tag) +{ + CBS child; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) + return 0; + } else { + CBS_init(out, NULL, 0); + } + if (out_present) + *out_present = present; + + return 1; +} + +int +CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, + uint64_t default_value) +{ + CBS child; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + if (!CBS_get_asn1_uint64(&child, out) || + CBS_len(&child) != 0) + return 0; + } else { + *out = default_value; + } + return 1; +} + +int +CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, + int default_value) +{ + CBS child, child2; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + uint8_t boolean; + + if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || + CBS_len(&child2) != 1 || CBS_len(&child) != 0) + return 0; + + boolean = CBS_data(&child2)[0]; + if (boolean == 0) + *out = 0; + else if (boolean == 0xff) + *out = 1; + else + return 0; + + } else { + *out = default_value; + } + return 1; +} diff --git a/Libraries/libressl/ssl/bytestring.h b/Libraries/libressl/ssl/bytestring.h new file mode 100644 index 000000000..51284da8d --- /dev/null +++ b/Libraries/libressl/ssl/bytestring.h @@ -0,0 +1,564 @@ +/* $OpenBSD: bytestring.h,v 1.24 2022/11/09 23:14:51 jsing Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENSSL_HEADER_BYTESTRING_H +#define OPENSSL_HEADER_BYTESTRING_H + +#include +#include + +__BEGIN_HIDDEN_DECLS + +/* + * Bytestrings are used for parsing and building TLS and ASN.1 messages. + * + * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and + * provides utility functions for safely parsing length-prefixed structures + * like TLS and ASN.1 from it. + * + * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and + * provides utility functions for building length-prefixed messages. + */ + +/* CRYPTO ByteString */ +typedef struct cbs_st { + const uint8_t *data; + size_t initial_len; + size_t len; +} CBS; + +/* + * CBS_init sets |cbs| to point to |data|. It does not take ownership of + * |data|. + */ +void CBS_init(CBS *cbs, const uint8_t *data, size_t len); + +/* + * CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero + * otherwise. + */ +int CBS_skip(CBS *cbs, size_t len); + +/* + * CBS_data returns a pointer to the contents of |cbs|. + */ +const uint8_t *CBS_data(const CBS *cbs); + +/* + * CBS_len returns the number of bytes remaining in |cbs|. + */ +size_t CBS_len(const CBS *cbs); + +/* + * CBS_offset returns the current offset into the original data of |cbs|. + */ +size_t CBS_offset(const CBS *cbs); + +/* + * CBS_stow copies the current contents of |cbs| into |*out_ptr| and + * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with + * free. It returns one on success and zero on allocation failure. On + * success, |*out_ptr| should be freed with free. If |cbs| is empty, + * |*out_ptr| will be NULL. + */ +int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); + +/* + * CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a + * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed + * with free. It returns one on success and zero on failure. On success, + * |*out_ptr| should be freed with free. If |cbs| contains NUL bytes, + * CBS_strdup will fail. + */ +int CBS_strdup(const CBS *cbs, char **out_ptr); + +/* + * CBS_write_bytes writes all of the remaining data from |cbs| into |dst| + * if it is at most |dst_len| bytes. If |copied| is not NULL, it will be set + * to the amount copied. It returns one on success and zero otherwise. + */ +int CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, + size_t *copied); + +/* + * CBS_contains_zero_byte returns one if the current contents of |cbs| contains + * a NUL byte and zero otherwise. + */ +int CBS_contains_zero_byte(const CBS *cbs); + +/* + * CBS_mem_equal compares the current contents of |cbs| with the |len| bytes + * starting at |data|. If they're equal, it returns one, otherwise zero. If the + * lengths match, it uses a constant-time comparison. + */ +int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len); + +/* + * CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It + * returns one on success and zero on error. + */ +int CBS_get_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and + * advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u16(CBS *cbs, uint16_t *out); + +/* + * CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and + * advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u24(CBS *cbs, uint32_t *out); + +/* + * CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| + * and advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u32(CBS *cbs, uint32_t *out); + +/* + * CBS_get_u64 sets |*out| to the next, big-endian uint64_t value from |cbs| + * and advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u64(CBS *cbs, uint64_t *out); + +/* + * CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens + * |cbs|. It returns one on success and zero on error. + */ +int CBS_get_last_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances + * |cbs|. It returns one on success and zero on error. + */ +int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); + +/* + * CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, + * length-prefixed value from |cbs| and advances |cbs| over it. It returns one + * on success and zero on error. + */ +int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, + * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It + * returns one on success and zero on error. + */ +int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, + * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It + * returns one on success and zero on error. + */ +int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_peek_u8 sets |*out| to the next uint8_t from |cbs|, but does not advance + * |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_peek_u16 sets |*out| to the next, big-endian uint16_t from |cbs|, but + * does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u16(CBS *cbs, uint16_t *out); + +/* + * CBS_peek_u24 sets |*out| to the next, big-endian 24-bit value from |cbs|, but + * does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u24(CBS *cbs, uint32_t *out); + +/* + * CBS_peek_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|, + * but does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u32(CBS *cbs, uint32_t *out); + +/* + * CBS_peek_last_u8 sets |*out| to the last uint8_t from |cbs|, but does not + * shorten |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_last_u8(CBS *cbs, uint8_t *out); + + +/* Parsing ASN.1 */ + +/* + * While an identifier can be multiple octets, this library only handles the + * single octet variety currently. This limits support up to tag number 30 + * since tag number 31 is a reserved value to indicate multiple octets. + */ + +/* Bits 8 and 7: class tag type: See X.690 section 8.1.2.2. */ +#define CBS_ASN1_UNIVERSAL 0x00 +#define CBS_ASN1_APPLICATION 0x40 +#define CBS_ASN1_CONTEXT_SPECIFIC 0x80 +#define CBS_ASN1_PRIVATE 0xc0 + +/* Bit 6: Primitive or constructed: See X.690 section 8.1.2.3. */ +#define CBS_ASN1_PRIMITIVE 0x00 +#define CBS_ASN1_CONSTRUCTED 0x20 + +/* + * Bits 5 to 1 are the tag number. See X.680 section 8.6 for tag numbers of + * the universal class. + */ + +/* + * Common universal identifier octets. + * See X.690 section 8.1 and X.680 section 8.6 for universal tag numbers. + * + * Note: These definitions are the cause of some of the strange behavior in + * CBS's bs_ber.c. + * + * In BER, it is the sender's option to use primitive or constructed for + * bitstring (X.690 section 8.6.1) and octetstring (X.690 section 8.7.1). + * + * In DER, bitstring and octetstring are required to be primitive + * (X.690 section 10.2). + */ +#define CBS_ASN1_BOOLEAN (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x1) +#define CBS_ASN1_INTEGER (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x2) +#define CBS_ASN1_BITSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x3) +#define CBS_ASN1_OCTETSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x4) +#define CBS_ASN1_OBJECT (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x6) +#define CBS_ASN1_ENUMERATED (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0xa) +#define CBS_ASN1_SEQUENCE (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x10) +#define CBS_ASN1_SET (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x11) + +/* + * CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not + * including tag and length bytes) and advances |cbs| over it. The ASN.1 + * element must match |tag_value|. It returns one on success and zero + * on error. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value); + +/* + * CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the + * ASN.1 header bytes too. + */ +int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value); + +/* + * CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one + * if the next ASN.1 element on |cbs| would have tag |tag_value|. If + * |cbs| is empty or the tag does not match, it returns zero. Note: if + * it returns one, CBS_get_asn1 may still fail if the rest of the + * element is malformed. + */ +int CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value); + +/* + * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from + * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to + * the tag number and |*out_header_len| to the length of the ASN.1 header. + * Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore + * the value. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len); + +/* + * CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| + * and sets |*out| to its value. It returns one on success and zero on error, + * where error includes the integer being negative, or too large to represent + * in 64 bits. + */ +int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); + +/* + * CBS_get_optional_asn1 gets an optional explicitly-tagged element + * from |cbs| tagged with |tag| and sets |*out| to its contents. If + * present, it sets |*out_present| to one, otherwise zero. It returns + * one on success, whether or not the element was present, and zero on + * decode failure. + */ +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, + unsigned int tag); + +/* + * CBS_get_optional_asn1_octet_string gets an optional + * explicitly-tagged OCTET STRING from |cbs|. If present, it sets + * |*out| to the string and |*out_present| to one. Otherwise, it sets + * |*out| to empty and |*out_present| to zero. |out_present| may be + * NULL. It returns one on success, whether or not the element was + * present, and zero on decode failure. + */ +int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned int tag); + +/* + * CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged + * INTEGER from |cbs|. If present, it sets |*out| to the + * value. Otherwise, it sets |*out| to |default_value|. It returns one + * on success, whether or not the element was present, and zero on + * decode failure. + */ +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, + uint64_t default_value); + +/* + * CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from + * |cbs|. If present, it sets |*out| to either zero or one, based on the + * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on + * success, whether or not the element was present, and zero on decode + * failure. + */ +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, + int default_value); + + +/* + * CRYPTO ByteBuilder. + * + * |CBB| objects allow one to build length-prefixed serialisations. A |CBB| + * object is associated with a buffer and new buffers are created with + * |CBB_init|. Several |CBB| objects can point at the same buffer when a + * length-prefix is pending, however only a single |CBB| can be 'current' at + * any one time. For example, if one calls |CBB_add_u8_length_prefixed| then + * the new |CBB| points at the same buffer as the original. But if the original + * |CBB| is used then the length prefix is written out and the new |CBB| must + * not be used again. + * + * If one needs to force a length prefix to be written out because a |CBB| is + * going out of scope, use |CBB_flush|. + */ + +struct cbb_buffer_st { + uint8_t *buf; + + /* The number of valid bytes. */ + size_t len; + + /* The size of buf. */ + size_t cap; + + /* + * One iff |buf| is owned by this object. If not then |buf| cannot be + * resized. + */ + char can_resize; +}; + +typedef struct cbb_st { + struct cbb_buffer_st *base; + + /* + * offset is the offset from the start of |base->buf| to the position of any + * pending length-prefix. + */ + size_t offset; + + /* child points to a child CBB if a length-prefix is pending. */ + struct cbb_st *child; + + /* + * pending_len_len contains the number of bytes in a pending length-prefix, + * or zero if no length-prefix is pending. + */ + uint8_t pending_len_len; + + char pending_is_asn1; + + /* + * is_top_level is true iff this is a top-level |CBB| (as opposed to a child + * |CBB|). Top-level objects are valid arguments for |CBB_finish|. + */ + char is_top_level; +} CBB; + +/* + * CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as + * needed, the |initial_capacity| is just a hint. It returns one on success or + * zero on error. + */ +int CBB_init(CBB *cbb, size_t initial_capacity); + +/* + * CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since + * |buf| cannot grow, trying to write more than |len| bytes will cause CBB + * functions to fail. It returns one on success or zero on error. + */ +int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); + +/* + * CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects + * writing to the same buffer. This should be used in an error case where a + * serialisation is abandoned. + */ +void CBB_cleanup(CBB *cbb); + +/* + * CBB_finish completes any pending length prefix and sets |*out_data| to a + * malloced buffer and |*out_len| to the length of that buffer. The caller + * takes ownership of the buffer and, unless the buffer was fixed with + * |CBB_init_fixed|, must call |free| when done. + * + * It can only be called on a "top level" |CBB|, i.e. one initialised with + * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on + * error. + */ +int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); + +/* + * CBB_flush causes any pending length prefixes to be written out and any child + * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero + * on error. + */ +int CBB_flush(CBB *cbb); + +/* + * CBB_discard_child discards the current unflushed child of |cbb|. Neither the + * child's contents nor the length prefix will be included in the output. + */ +void CBB_discard_child(CBB *cbb); + +/* + * CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The + * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit + * length. It returns one on success or zero on error. + */ +int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. + * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, + * big-endian length. It returns one on success or zero on error. + */ +int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. + * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, + * big-endian length. It returns one on success or zero on error. + */ +int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an + * ASN.1 object can be written. The |tag| argument will be used as the tag for + * the object. Passing in |tag| number 31 will return in an error since only + * single octet identifiers are supported. It returns one on success or zero + * on error. + */ +int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag); + +/* + * CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on + * success and zero otherwise. + */ +int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); + +/* + * CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to + * the beginning of that space. The caller must then write |len| bytes of + * actual contents to |*out_data|. It returns one on success and zero + * otherwise. + */ +int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); + +/* + * CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on + * success and zero otherwise. + */ +int CBB_add_u8(CBB *cbb, size_t value); + +/* + * CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u16(CBB *cbb, size_t value); + +/* + * CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u24(CBB *cbb, size_t value); + +/* + * CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u32(CBB *cbb, size_t value); + +/* + * CBB_add_u64 appends a 64-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u64(CBB *cbb, uint64_t value); + +/* + * CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| + * and writes |value| in its contents. It returns one on success and zero on + * error. + */ +int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); + +#ifdef LIBRESSL_INTERNAL +/* + * CBS_dup sets |out| to point to cbs's |data| and |len|. It results in two + * CBS that point to the same buffer. + */ +void CBS_dup(const CBS *cbs, CBS *out); + +/* + * cbs_get_any_asn1_element sets |*out| to contain the next ASN.1 element from + * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to + * the tag number and |*out_header_len| to the length of the ASN.1 header. If + * strict mode is disabled and the element has indefinite length then |*out| + * will only contain the header. Each of |out|, |out_tag|, and + * |out_header_len| may be NULL to ignore the value. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len, int strict); + +/* + * CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it + * finds indefinite-length elements that otherwise appear to be valid DER, it + * attempts to convert the DER-like data to DER and sets |*out| and + * |*out_length| to describe a malloced buffer containing the DER data. + * Additionally, |*in| will be advanced over the ASN.1 data. + * + * If it doesn't find any indefinite-length elements then it sets |*out| to + * NULL and |*in| is unmodified. + * + * This is NOT a conversion from BER to DER. There are many restrictions when + * dealing with DER data. This is only concerned with one: indefinite vs. + * definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output + * from NSS. + * + * It returns one on success and zero otherwise. + */ +int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len); +#endif /* LIBRESSL_INTERNAL */ + +__END_HIDDEN_DECLS + +#endif /* OPENSSL_HEADER_BYTESTRING_H */ diff --git a/Libraries/libressl/ssl/d1_both.c b/Libraries/libressl/ssl/d1_both.c new file mode 100644 index 000000000..b5c68a173 --- /dev/null +++ b/Libraries/libressl/ssl/d1_both.c @@ -0,0 +1,1198 @@ +/* $OpenBSD: d1_both.c,v 1.84 2022/12/26 07:31:44 jmc Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "bytestring.h" +#include "dtls_local.h" +#include "pqueue.h" +#include "ssl_local.h" + +#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) + +#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ + if ((end) - (start) <= 8) { \ + long ii; \ + for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ + } else { \ + long ii; \ + bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ + for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ + bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ + } } + +#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ + long ii; \ + OPENSSL_assert((msg_len) > 0); \ + is_complete = 1; \ + if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ + if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ + if (bitmask[ii] != 0xff) { is_complete = 0; break; } } + +static const unsigned char bitmask_start_values[] = { + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 +}; +static const unsigned char bitmask_end_values[] = { + 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f +}; + +/* XDTLS: figure out the right values */ +static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; + +static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); +static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, + unsigned long frag_len); +static int dtls1_write_message_header(const struct hm_header_st *msg_hdr, + unsigned long frag_off, unsigned long frag_len, unsigned char *p); +static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, + int *ok); + +void dtls1_hm_fragment_free(hm_fragment *frag); + +static hm_fragment * +dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) +{ + hm_fragment *frag; + + if ((frag = calloc(1, sizeof(*frag))) == NULL) + goto err; + + if (frag_len > 0) { + if ((frag->fragment = calloc(1, frag_len)) == NULL) + goto err; + } + + /* Initialize reassembly bitmask if necessary. */ + if (reassembly) { + if ((frag->reassembly = calloc(1, + RSMBLY_BITMASK_SIZE(frag_len))) == NULL) + goto err; + } + + return frag; + + err: + dtls1_hm_fragment_free(frag); + return NULL; +} + +void +dtls1_hm_fragment_free(hm_fragment *frag) +{ + if (frag == NULL) + return; + + free(frag->fragment); + free(frag->reassembly); + free(frag); +} + +/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ +int +dtls1_do_write(SSL *s, int type) +{ + int ret; + int curr_mtu; + unsigned int len, frag_off; + size_t overhead; + + /* AHA! Figure out the MTU, and stick to the right size */ + if (s->d1->mtu < dtls1_min_mtu() && + !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + + /* + * I've seen the kernel return bogus numbers when it + * doesn't know the MTU (ie., the initial write), so just + * make sure we have a reasonable number + */ + if (s->d1->mtu < dtls1_min_mtu()) { + s->d1->mtu = 0; + s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, + s->d1->mtu, NULL); + } + } + + OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); + /* should have something reasonable now */ + + if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) + OPENSSL_assert(s->init_num == + (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); + + if (!tls12_record_layer_write_overhead(s->rl, &overhead)) + return -1; + + frag_off = 0; + while (s->init_num) { + curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - + DTLS1_RT_HEADER_LENGTH - overhead; + + if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { + /* grr.. we could get an error if MTU picked was wrong */ + ret = BIO_flush(SSL_get_wbio(s)); + if (ret <= 0) + return ret; + curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - + overhead; + } + + if (s->init_num > curr_mtu) + len = curr_mtu; + else + len = s->init_num; + + /* XDTLS: this function is too long. split out the CCS part */ + if (type == SSL3_RT_HANDSHAKE) { + if (s->init_off != 0) { + OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); + s->init_off -= DTLS1_HM_HEADER_LENGTH; + s->init_num += DTLS1_HM_HEADER_LENGTH; + + if (s->init_num > curr_mtu) + len = curr_mtu; + else + len = s->init_num; + } + + dtls1_fix_message_header(s, frag_off, + len - DTLS1_HM_HEADER_LENGTH); + + if (!dtls1_write_message_header(&s->d1->w_msg_hdr, + s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len, + (unsigned char *)&s->init_buf->data[s->init_off])) + return -1; + + OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); + } + + ret = dtls1_write_bytes(s, type, + &s->init_buf->data[s->init_off], len); + if (ret < 0) { + /* + * Might need to update MTU here, but we don't know + * which previous packet caused the failure -- so + * can't really retransmit anything. continue as + * if everything is fine and wait for an alert to + * handle the retransmit + */ + if (BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + else + return (-1); + } else { + + /* + * Bad if this assert fails, only part of the + * handshake message got sent. but why would + * this happen? + */ + OPENSSL_assert(len == (unsigned int)ret); + + if (type == SSL3_RT_HANDSHAKE && + !s->d1->retransmitting) { + /* + * Should not be done for 'Hello Request's, + * but in that case we'll ignore the result + * anyway + */ + unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; + const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + int xlen; + + if (frag_off == 0) { + /* + * Reconstruct message header is if it + * is being sent in single fragment + */ + if (!dtls1_write_message_header(msg_hdr, + 0, msg_hdr->msg_len, p)) + return (-1); + xlen = ret; + } else { + p += DTLS1_HM_HEADER_LENGTH; + xlen = ret - DTLS1_HM_HEADER_LENGTH; + } + + tls1_transcript_record(s, p, xlen); + } + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, + s->init_buf->data, + (size_t)(s->init_off + s->init_num), + s, s->msg_callback_arg); + + s->init_off = 0; + /* done writing this message */ + s->init_num = 0; + + return (1); + } + s->init_off += ret; + s->init_num -= ret; + frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); + } + } + return (0); +} + + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), + * maximum acceptable body length 'max'. + * Read an entire handshake message. Handshake messages arrive in + * fragments. + */ +int +dtls1_get_message(SSL *s, int st1, int stn, int mt, long max) +{ + struct hm_header_st *msg_hdr; + unsigned char *p; + unsigned long msg_len; + int i, al, ok; + + /* + * s3->tmp is used to store messages that are unexpected, caused + * by the absence of an optional handshake message + */ + if (s->s3->hs.tls12.reuse_message) { + s->s3->hs.tls12.reuse_message = 0; + if ((mt >= 0) && (s->s3->hs.tls12.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + goto fatal_err; + } + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + s->init_num = (int)s->s3->hs.tls12.message_size; + return 1; + } + + msg_hdr = &s->d1->r_msg_hdr; + memset(msg_hdr, 0, sizeof(struct hm_header_st)); + + again: + i = dtls1_get_message_fragment(s, st1, stn, max, &ok); + if (i == DTLS1_HM_BAD_FRAGMENT || + i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ + goto again; + else if (i <= 0 && !ok) + return i; + + p = (unsigned char *)s->init_buf->data; + msg_len = msg_hdr->msg_len; + + /* reconstruct message header */ + if (!dtls1_write_message_header(msg_hdr, 0, msg_len, p)) + return -1; + + msg_len += DTLS1_HM_HEADER_LENGTH; + + tls1_transcript_record(s, p, msg_len); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, msg_len, + s, s->msg_callback_arg); + + memset(msg_hdr, 0, sizeof(struct hm_header_st)); + + /* Don't change sequence numbers while listening */ + if (!s->d1->listen) + s->d1->handshake_read_seq++; + + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + return 1; + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; +} + +static int +dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, int max) +{ + size_t frag_off, frag_len, msg_len; + + msg_len = msg_hdr->msg_len; + frag_off = msg_hdr->frag_off; + frag_len = msg_hdr->frag_len; + + /* sanity checking */ + if ((frag_off + frag_len) > msg_len) { + SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if ((frag_off + frag_len) > (unsigned long)max) { + SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ + { + /* + * msg_len is limited to 2^24, but is effectively checked + * against max above + */ + if (!BUF_MEM_grow_clean(s->init_buf, + msg_len + DTLS1_HM_HEADER_LENGTH)) { + SSLerror(s, ERR_R_BUF_LIB); + return SSL_AD_INTERNAL_ERROR; + } + + s->s3->hs.tls12.message_size = msg_len; + s->d1->r_msg_hdr.msg_len = msg_len; + s->s3->hs.tls12.message_type = msg_hdr->type; + s->d1->r_msg_hdr.type = msg_hdr->type; + s->d1->r_msg_hdr.seq = msg_hdr->seq; + } else if (msg_len != s->d1->r_msg_hdr.msg_len) { + /* + * They must be playing with us! BTW, failure to enforce + * upper limit would open possibility for buffer overrun. + */ + SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + return 0; /* no error */ +} + +static int +dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) +{ + /* + * (0) check whether the desired fragment is available + * if so: + * (1) copy over the fragment to s->init_buf->data[] + * (2) update s->init_num + */ + pitem *item; + hm_fragment *frag; + int al; + + *ok = 0; + item = pqueue_peek(s->d1->buffered_messages); + if (item == NULL) + return 0; + + frag = (hm_fragment *)item->data; + + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; + + if (s->d1->handshake_read_seq == frag->msg_header.seq) { + unsigned long frag_len = frag->msg_header.frag_len; + pqueue_pop(s->d1->buffered_messages); + + al = dtls1_preprocess_fragment(s, &frag->msg_header, max); + + if (al == 0) /* no alert */ + { + unsigned char *p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + memcpy(&p[frag->msg_header.frag_off], + frag->fragment, frag->msg_header.frag_len); + } + + dtls1_hm_fragment_free(frag); + pitem_free(item); + + if (al == 0) { + *ok = 1; + return frag_len; + } + + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + *ok = 0; + return -1; + } else + return 0; +} + +/* + * dtls1_max_handshake_message_len returns the maximum number of bytes + * permitted in a DTLS handshake message for |s|. The minimum is 16KB, + * but may be greater if the maximum certificate list size requires it. + */ +static unsigned long +dtls1_max_handshake_message_len(const SSL *s) +{ + unsigned long max_len; + + max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + if (max_len < (unsigned long)s->max_cert_list) + return s->max_cert_list; + return max_len; +} + +static int +dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) +{ + hm_fragment *frag = NULL; + pitem *item = NULL; + int i = -1, is_complete; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || + msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + goto err; + + if (frag_len == 0) { + i = DTLS1_HM_FRAGMENT_RETRY; + goto err; + } + + /* Try to find item in queue */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + if (item == NULL) { + frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); + if (frag == NULL) + goto err; + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + frag->msg_header.frag_len = frag->msg_header.msg_len; + frag->msg_header.frag_off = 0; + } else { + frag = (hm_fragment*)item->data; + if (frag->msg_header.msg_len != msg_hdr->msg_len) { + item = NULL; + frag = NULL; + goto err; + } + } + + /* + * If message is already reassembled, this must be a + * retransmit and can be dropped. + */ + if (frag->reassembly == NULL) { + unsigned char devnull [256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, frag_len > sizeof(devnull) ? + sizeof(devnull) : frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + i = DTLS1_HM_FRAGMENT_RETRY; + goto err; + } + + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment + msg_hdr->frag_off, frag_len, 0); + if (i <= 0 || (unsigned long)i != frag_len) + goto err; + + RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, + (long)(msg_hdr->frag_off + frag_len)); + + RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, + is_complete); + + if (is_complete) { + free(frag->reassembly); + frag->reassembly = NULL; + } + + if (item == NULL) { + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)(msg_hdr->seq); + + item = pitem_new(seq64be, frag); + if (item == NULL) { + i = -1; + goto err; + } + + pqueue_insert(s->d1->buffered_messages, item); + } + + return DTLS1_HM_FRAGMENT_RETRY; + + err: + if (item == NULL && frag != NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + + +static int +dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) +{ + int i = -1; + hm_fragment *frag = NULL; + pitem *item = NULL; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) + goto err; + + /* Try to find item in queue, to prevent duplicate entries */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char) (msg_hdr->seq >> 8); + seq64be[7] = (unsigned char) msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + /* + * If we already have an entry and this one is a fragment, + * don't discard it and rather try to reassemble it. + */ + if (item != NULL && frag_len < msg_hdr->msg_len) + item = NULL; + + /* + * Discard the message if sequence number was already there, is + * too far in the future, already in the queue or if we received + * a FINISHED before the SERVER_HELLO, which then must be a stale + * retransmit. + */ + if (msg_hdr->seq <= s->d1->handshake_read_seq || + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || + (s->d1->handshake_read_seq == 0 && + msg_hdr->type == SSL3_MT_FINISHED)) { + unsigned char devnull [256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, frag_len > sizeof(devnull) ? + sizeof(devnull) : frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + } else { + if (frag_len < msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); + + if (frag_len > dtls1_max_handshake_message_len(s)) + goto err; + + frag = dtls1_hm_fragment_new(frag_len, 0); + if (frag == NULL) + goto err; + + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + + if (frag_len) { + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment, frag_len, 0); + if (i <= 0 || (unsigned long)i != frag_len) + goto err; + } + + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)(msg_hdr->seq); + + item = pitem_new(seq64be, frag); + if (item == NULL) + goto err; + + pqueue_insert(s->d1->buffered_messages, item); + } + + return DTLS1_HM_FRAGMENT_RETRY; + + err: + if (item == NULL && frag != NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + + +static long +dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) +{ + unsigned char wire[DTLS1_HM_HEADER_LENGTH]; + unsigned long len, frag_off, frag_len; + struct hm_header_st msg_hdr; + int i, al; + CBS cbs; + + again: + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) { + if (*ok) + s->init_num = frag_len; + return frag_len; + } + + /* read handshake message header */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire, + DTLS1_HM_HEADER_LENGTH, 0); + if (i <= 0) { + /* nbio, or an error */ + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + + CBS_init(&cbs, wire, i); + if (!dtls1_get_message_header(&cbs, &msg_hdr)) { + /* Handshake fails if message header is incomplete. */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + goto fatal_err; + } + + /* + * if this is a future (or stale) message it gets buffered + * (or dropped)--no further processing at this time + * While listening, we accept seq 1 (ClientHello with cookie) + * although we're still expecting seq 0 (ClientHello) + */ + if (msg_hdr.seq != s->d1->handshake_read_seq && + !(s->d1->listen && msg_hdr.seq == 1)) + return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); + + len = msg_hdr.msg_len; + frag_off = msg_hdr.frag_off; + frag_len = msg_hdr.frag_len; + + if (frag_len && frag_len < len) + return dtls1_reassemble_fragment(s, &msg_hdr, ok); + + if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && + wire[0] == SSL3_MT_HELLO_REQUEST) { + /* + * The server may always send 'Hello Request' messages -- + * we are doing a handshake anyway now, so ignore them + * if their format is correct. Does not count for + * 'Finished' MAC. + */ + if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { + if (s->msg_callback) + s->msg_callback(0, s->version, + SSL3_RT_HANDSHAKE, wire, + DTLS1_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + + s->init_num = 0; + goto again; + } + else /* Incorrectly formatted Hello request */ + { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + goto fatal_err; + } + } + + if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) + goto fatal_err; + + /* XDTLS: resurrect this when restart is in place */ + s->s3->hs.state = stn; + + if (frag_len > 0) { + unsigned char *p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[frag_off], frag_len, 0); + /* XDTLS: fix this--message fragments cannot span multiple packets */ + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + } else + i = 0; + + /* + * XDTLS: an incorrectly formatted fragment should cause the + * handshake to fail + */ + if (i != (int)frag_len) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER); + goto fatal_err; + } + + /* + * Note that s->init_num is *not* used as current offset in + * s->init_buf->data, but as a counter summing up fragments' + * lengths: as soon as they sum up to handshake packet + * length, we assume we have got all the fragments. + */ + s->init_num = frag_len; + *ok = 1; + return frag_len; + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + + *ok = 0; + return (-1); +} + +int +dtls1_read_failed(SSL *s, int code) +{ + if (code > 0) { +#ifdef DEBUG + fprintf(stderr, "invalid state reached %s:%d", + __FILE__, __LINE__); +#endif + return 1; + } + + if (!dtls1_is_timer_expired(s)) { + /* + * not a timeout, none of our business, let higher layers + * handle this. in fact it's probably an error + */ + return code; + } + + if (!SSL_in_init(s)) /* done, no need to send a retransmit */ + { + BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + return code; + } + + return dtls1_handle_timeout(s); +} + +int +dtls1_get_queue_priority(unsigned short seq, int is_ccs) +{ + /* + * The index of the retransmission queue actually is the message + * sequence number, since the queue only contains messages of a + * single handshake. However, the ChangeCipherSpec has no message + * sequence number and so using only the sequence will result in + * the CCS and Finished having the same index. To prevent this, the + * sequence number is multiplied by 2. In case of a CCS 1 is + * subtracted. This does not only differ CSS and Finished, it also + * maintains the order of the index (important for priority queues) + * and fits in the unsigned short variable. + */ + return seq * 2 - is_ccs; +} + +int +dtls1_retransmit_buffered_messages(SSL *s) +{ + pqueue sent = s->d1->sent_messages; + piterator iter; + pitem *item; + hm_fragment *frag; + int found = 0; + + iter = pqueue_iterator(sent); + + for (item = pqueue_next(&iter); item != NULL; + item = pqueue_next(&iter)) { + frag = (hm_fragment *)item->data; + if (dtls1_retransmit_message(s, + (unsigned short)dtls1_get_queue_priority( + frag->msg_header.seq, frag->msg_header.is_ccs), 0, + &found) <= 0 && found) { +#ifdef DEBUG + fprintf(stderr, "dtls1_retransmit_message() failed\n"); +#endif + return -1; + } + } + + return 1; +} + +int +dtls1_buffer_message(SSL *s, int is_ccs) +{ + pitem *item; + hm_fragment *frag; + unsigned char seq64be[8]; + + /* Buffer the message in order to handle DTLS retransmissions. */ + + /* + * This function is called immediately after a message has + * been serialized + */ + OPENSSL_assert(s->init_off == 0); + + frag = dtls1_hm_fragment_new(s->init_num, 0); + if (frag == NULL) + return 0; + + memcpy(frag->fragment, s->init_buf->data, s->init_num); + + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) == + (unsigned int)s->init_num); + + frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.seq = s->d1->w_msg_hdr.seq; + frag->msg_header.type = s->d1->w_msg_hdr.type; + frag->msg_header.frag_off = 0; + frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.is_ccs = is_ccs; + + /* save current state*/ + frag->msg_header.saved_retransmit_state.session = s->session; + frag->msg_header.saved_retransmit_state.epoch = + tls12_record_layer_write_epoch(s->rl); + + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(dtls1_get_queue_priority( + frag->msg_header.seq, frag->msg_header.is_ccs) >> 8); + seq64be[7] = (unsigned char)(dtls1_get_queue_priority( + frag->msg_header.seq, frag->msg_header.is_ccs)); + + item = pitem_new(seq64be, frag); + if (item == NULL) { + dtls1_hm_fragment_free(frag); + return 0; + } + + pqueue_insert(s->d1->sent_messages, item); + return 1; +} + +int +dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, + int *found) +{ + int ret; + /* XDTLS: for now assuming that read/writes are blocking */ + pitem *item; + hm_fragment *frag; + unsigned long header_length; + unsigned char seq64be[8]; + struct dtls1_retransmit_state saved_state; + + /* + OPENSSL_assert(s->init_num == 0); + OPENSSL_assert(s->init_off == 0); + */ + + /* XDTLS: the requested message ought to be found, otherwise error */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(seq >> 8); + seq64be[7] = (unsigned char)seq; + + item = pqueue_find(s->d1->sent_messages, seq64be); + if (item == NULL) { +#ifdef DEBUG + fprintf(stderr, "retransmit: message %d non-existent\n", seq); +#endif + *found = 0; + return 0; + } + + *found = 1; + frag = (hm_fragment *)item->data; + + if (frag->msg_header.is_ccs) + header_length = DTLS1_CCS_HEADER_LENGTH; + else + header_length = DTLS1_HM_HEADER_LENGTH; + + memcpy(s->init_buf->data, frag->fragment, + frag->msg_header.msg_len + header_length); + s->init_num = frag->msg_header.msg_len + header_length; + + dtls1_set_message_header_int(s, frag->msg_header.type, + frag->msg_header.msg_len, frag->msg_header.seq, 0, + frag->msg_header.frag_len); + + /* save current state */ + saved_state.session = s->session; + saved_state.epoch = tls12_record_layer_write_epoch(s->rl); + + s->d1->retransmitting = 1; + + /* restore state in which the message was originally sent */ + s->session = frag->msg_header.saved_retransmit_state.session; + if (!tls12_record_layer_use_write_epoch(s->rl, + frag->msg_header.saved_retransmit_state.epoch)) + return 0; + + ret = dtls1_do_write(s, frag->msg_header.is_ccs ? + SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); + + /* restore current state */ + s->session = saved_state.session; + if (!tls12_record_layer_use_write_epoch(s->rl, + saved_state.epoch)) + return 0; + + s->d1->retransmitting = 0; + + (void)BIO_flush(SSL_get_wbio(s)); + return ret; +} + +/* call this function when the buffered messages are no longer needed */ +void +dtls1_clear_record_buffer(SSL *s) +{ + hm_fragment *frag; + pitem *item; + + for(item = pqueue_pop(s->d1->sent_messages); item != NULL; + item = pqueue_pop(s->d1->sent_messages)) { + frag = item->data; + if (frag->msg_header.is_ccs) + tls12_record_layer_write_epoch_done(s->rl, + frag->msg_header.saved_retransmit_state.epoch); + dtls1_hm_fragment_free(frag); + pitem_free(item); + } +} + +void +dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len, + unsigned long frag_off, unsigned long frag_len) +{ + /* Don't change sequence numbers while listening */ + if (frag_off == 0 && !s->d1->listen) { + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->d1->next_handshake_write_seq++; + } + + dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, + frag_off, frag_len); +} + +/* don't actually do the writing, wait till the MTU has been retrieved */ +void +dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len, + unsigned short seq_num, unsigned long frag_off, unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->type = mt; + msg_hdr->msg_len = len; + msg_hdr->seq = seq_num; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static void +dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static int +dtls1_write_message_header(const struct hm_header_st *msg_hdr, + unsigned long frag_off, unsigned long frag_len, unsigned char *p) +{ + CBB cbb; + + /* We assume DTLS1_HM_HEADER_LENGTH bytes are available for now... */ + if (!CBB_init_fixed(&cbb, p, DTLS1_HM_HEADER_LENGTH)) + return 0; + if (!CBB_add_u8(&cbb, msg_hdr->type)) + goto err; + if (!CBB_add_u24(&cbb, msg_hdr->msg_len)) + goto err; + if (!CBB_add_u16(&cbb, msg_hdr->seq)) + goto err; + if (!CBB_add_u24(&cbb, frag_off)) + goto err; + if (!CBB_add_u24(&cbb, frag_len)) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; + + return 1; + + err: + CBB_cleanup(&cbb); + return 0; +} + +unsigned int +dtls1_min_mtu(void) +{ + return (g_probable_mtu[(sizeof(g_probable_mtu) / + sizeof(g_probable_mtu[0])) - 1]); +} + +static unsigned int +dtls1_guess_mtu(unsigned int curr_mtu) +{ + unsigned int i; + + if (curr_mtu == 0) + return g_probable_mtu[0]; + + for (i = 0; i < sizeof(g_probable_mtu) / sizeof(g_probable_mtu[0]); i++) + if (curr_mtu > g_probable_mtu[i]) + return g_probable_mtu[i]; + + return curr_mtu; +} + +int +dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr) +{ + uint32_t msg_len, frag_off, frag_len; + uint16_t seq; + uint8_t type; + + memset(msg_hdr, 0, sizeof(*msg_hdr)); + + if (!CBS_get_u8(header, &type)) + return 0; + if (!CBS_get_u24(header, &msg_len)) + return 0; + if (!CBS_get_u16(header, &seq)) + return 0; + if (!CBS_get_u24(header, &frag_off)) + return 0; + if (!CBS_get_u24(header, &frag_len)) + return 0; + + msg_hdr->type = type; + msg_hdr->msg_len = msg_len; + msg_hdr->seq = seq; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; + + return 1; +} diff --git a/Libraries/libressl/ssl/d1_lib.c b/Libraries/libressl/ssl/d1_lib.c new file mode 100644 index 000000000..ae6a6650a --- /dev/null +++ b/Libraries/libressl/ssl/d1_lib.c @@ -0,0 +1,435 @@ +/* $OpenBSD: d1_lib.c,v 1.64 2022/11/26 16:08:55 tb Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include + +#include + +#include + +#include "dtls_local.h" +#include "pqueue.h" +#include "ssl_local.h" + +void dtls1_hm_fragment_free(hm_fragment *frag); + +static int dtls1_listen(SSL *s, struct sockaddr *client); + +int +dtls1_new(SSL *s) +{ + if (!ssl3_new(s)) + goto err; + + if ((s->d1 = calloc(1, sizeof(*s->d1))) == NULL) + goto err; + + if ((s->d1->unprocessed_rcds.q = pqueue_new()) == NULL) + goto err; + if ((s->d1->buffered_messages = pqueue_new()) == NULL) + goto err; + if ((s->d1->sent_messages = pqueue_new()) == NULL) + goto err; + if ((s->d1->buffered_app_data.q = pqueue_new()) == NULL) + goto err; + + if (s->server) + s->d1->cookie_len = sizeof(s->d1->cookie); + + s->method->ssl_clear(s); + return (1); + + err: + dtls1_free(s); + return (0); +} + +static void +dtls1_drain_rcontents(pqueue queue) +{ + DTLS1_RCONTENT_DATA_INTERNAL *rdata; + pitem *item; + + if (queue == NULL) + return; + + while ((item = pqueue_pop(queue)) != NULL) { + rdata = (DTLS1_RCONTENT_DATA_INTERNAL *)item->data; + tls_content_free(rdata->rcontent); + free(item->data); + pitem_free(item); + } +} + +static void +dtls1_drain_records(pqueue queue) +{ + pitem *item; + DTLS1_RECORD_DATA_INTERNAL *rdata; + + if (queue == NULL) + return; + + while ((item = pqueue_pop(queue)) != NULL) { + rdata = (DTLS1_RECORD_DATA_INTERNAL *)item->data; + ssl3_release_buffer(&rdata->rbuf); + free(item->data); + pitem_free(item); + } +} + +static void +dtls1_drain_fragments(pqueue queue) +{ + pitem *item; + + if (queue == NULL) + return; + + while ((item = pqueue_pop(queue)) != NULL) { + dtls1_hm_fragment_free(item->data); + pitem_free(item); + } +} + +static void +dtls1_clear_queues(SSL *s) +{ + dtls1_drain_records(s->d1->unprocessed_rcds.q); + dtls1_drain_fragments(s->d1->buffered_messages); + dtls1_drain_fragments(s->d1->sent_messages); + dtls1_drain_rcontents(s->d1->buffered_app_data.q); +} + +void +dtls1_free(SSL *s) +{ + if (s == NULL) + return; + + ssl3_free(s); + + if (s->d1 == NULL) + return; + + dtls1_clear_queues(s); + + pqueue_free(s->d1->unprocessed_rcds.q); + pqueue_free(s->d1->buffered_messages); + pqueue_free(s->d1->sent_messages); + pqueue_free(s->d1->buffered_app_data.q); + + freezero(s->d1, sizeof(*s->d1)); + s->d1 = NULL; +} + +void +dtls1_clear(SSL *s) +{ + pqueue unprocessed_rcds; + pqueue buffered_messages; + pqueue sent_messages; + pqueue buffered_app_data; + unsigned int mtu; + + if (s->d1) { + unprocessed_rcds = s->d1->unprocessed_rcds.q; + buffered_messages = s->d1->buffered_messages; + sent_messages = s->d1->sent_messages; + buffered_app_data = s->d1->buffered_app_data.q; + mtu = s->d1->mtu; + + dtls1_clear_queues(s); + + memset(s->d1, 0, sizeof(*s->d1)); + + s->d1->unprocessed_rcds.epoch = + tls12_record_layer_read_epoch(s->rl) + 1; + + if (s->server) { + s->d1->cookie_len = sizeof(s->d1->cookie); + } + + if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { + s->d1->mtu = mtu; + } + + s->d1->unprocessed_rcds.q = unprocessed_rcds; + s->d1->buffered_messages = buffered_messages; + s->d1->sent_messages = sent_messages; + s->d1->buffered_app_data.q = buffered_app_data; + } + + ssl3_clear(s); + + s->version = DTLS1_VERSION; +} + +long +dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + switch (cmd) { + case DTLS_CTRL_GET_TIMEOUT: + if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) { + ret = 1; + } + break; + case DTLS_CTRL_HANDLE_TIMEOUT: + ret = dtls1_handle_timeout(s); + break; + case DTLS_CTRL_LISTEN: + ret = dtls1_listen(s, parg); + break; + + default: + ret = ssl3_ctrl(s, cmd, larg, parg); + break; + } + return (ret); +} + +/* + * As it's impossible to use stream ciphers in "datagram" mode, this + * simple filter is designed to disengage them in DTLS. Unfortunately + * there is no universal way to identify stream SSL_CIPHER, so we have + * to explicitly list their SSL_* codes. Currently RC4 is the only one + * available, but if new ones emerge, they will have to be added... + */ +const SSL_CIPHER * +dtls1_get_cipher(unsigned int u) +{ + const SSL_CIPHER *cipher; + + if ((cipher = ssl3_get_cipher(u)) == NULL) + return NULL; + + if (cipher->algorithm_enc == SSL_RC4) + return NULL; + + return cipher; +} + +void +dtls1_start_timer(SSL *s) +{ + + /* If timer is not set, initialize duration with 1 second */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + s->d1->timeout_duration = 1; + } + + /* Set timeout to current time */ + gettimeofday(&(s->d1->next_timeout), NULL); + + /* Add duration to current time */ + s->d1->next_timeout.tv_sec += s->d1->timeout_duration; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &s->d1->next_timeout); +} + +struct timeval* +dtls1_get_timeout(SSL *s, struct timeval* timeleft) +{ + struct timeval timenow; + + /* If no timeout is set, just return NULL */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + return NULL; + } + + /* Get current time */ + gettimeofday(&timenow, NULL); + + /* If timer already expired, set remaining time to 0 */ + if (s->d1->next_timeout.tv_sec < timenow.tv_sec || + (s->d1->next_timeout.tv_sec == timenow.tv_sec && + s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + memset(timeleft, 0, sizeof(struct timeval)); + return timeleft; + } + + /* Calculate time left until timer expires */ + memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); + timeleft->tv_sec -= timenow.tv_sec; + timeleft->tv_usec -= timenow.tv_usec; + if (timeleft->tv_usec < 0) { + timeleft->tv_sec--; + timeleft->tv_usec += 1000000; + } + + /* If remaining time is less than 15 ms, set it to 0 + * to prevent issues because of small devergences with + * socket timeouts. + */ + if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { + memset(timeleft, 0, sizeof(struct timeval)); + } + + + return timeleft; +} + +int +dtls1_is_timer_expired(SSL *s) +{ + struct timeval timeleft; + + /* Get time left until timeout, return false if no timer running */ + if (dtls1_get_timeout(s, &timeleft) == NULL) { + return 0; + } + + /* Return false if timer is not expired yet */ + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return 0; + } + + /* Timer expired, so return true */ + return 1; +} + +void +dtls1_double_timeout(SSL *s) +{ + s->d1->timeout_duration *= 2; + if (s->d1->timeout_duration > 60) + s->d1->timeout_duration = 60; + dtls1_start_timer(s); +} + +void +dtls1_stop_timer(SSL *s) +{ + /* Reset everything */ + memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); + memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); + s->d1->timeout_duration = 1; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ + dtls1_clear_record_buffer(s); +} + +int +dtls1_check_timeout_num(SSL *s) +{ + s->d1->timeout.num_alerts++; + + /* Reduce MTU after 2 unsuccessful retransmissions */ + if (s->d1->timeout.num_alerts > 2) { + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); + + } + + if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { + /* fail the connection, enough alerts have been sent */ + SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED); + return -1; + } + + return 0; +} + +int +dtls1_handle_timeout(SSL *s) +{ + /* if no timer is expired, don't do anything */ + if (!dtls1_is_timer_expired(s)) { + return 0; + } + + dtls1_double_timeout(s); + + if (dtls1_check_timeout_num(s) < 0) + return -1; + + s->d1->timeout.read_timeouts++; + if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { + s->d1->timeout.read_timeouts = 1; + } + + dtls1_start_timer(s); + return dtls1_retransmit_buffered_messages(s); +} + +int +dtls1_listen(SSL *s, struct sockaddr *client) +{ + int ret; + + /* Ensure there is no state left over from a previous invocation */ + SSL_clear(s); + + SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); + s->d1->listen = 1; + + ret = SSL_accept(s); + if (ret <= 0) + return ret; + + (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); + return 1; +} diff --git a/Libraries/libressl/ssl/d1_pkt.c b/Libraries/libressl/ssl/d1_pkt.c new file mode 100644 index 000000000..df9581a3c --- /dev/null +++ b/Libraries/libressl/ssl/d1_pkt.c @@ -0,0 +1,1116 @@ +/* $OpenBSD: d1_pkt.c,v 1.128 2023/07/02 20:16:47 tb Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include + +#include "bytestring.h" +#include "dtls_local.h" +#include "pqueue.h" +#include "ssl_local.h" +#include "tls_content.h" + +/* mod 128 saturating subtract of two 64-bit values in big-endian order */ +static int +satsub64be(const unsigned char *v1, const unsigned char *v2) +{ + int ret, sat, brw, i; + + if (sizeof(long) == 8) + do { + long l; + + if (BYTE_ORDER == LITTLE_ENDIAN) + break; + /* not reached on little-endians */ + /* following test is redundant, because input is + * always aligned, but I take no chances... */ + if (((size_t)v1 | (size_t)v2) & 0x7) + break; + + l = *((long *)v1); + l -= *((long *)v2); + if (l > 128) + return 128; + else if (l<-128) + return -128; + else + return (int)l; + } while (0); + + ret = (int)v1[7] - (int)v2[7]; + sat = 0; + brw = ret >> 8; /* brw is either 0 or -1 */ + if (ret & 0x80) { + for (i = 6; i >= 0; i--) { + brw += (int)v1[i]-(int)v2[i]; + sat |= ~brw; + brw >>= 8; + } + } else { + for (i = 6; i >= 0; i--) { + brw += (int)v1[i]-(int)v2[i]; + sat |= brw; + brw >>= 8; + } + } + brw <<= 8; /* brw is either 0 or -256 */ + + if (sat & 0xff) + return brw | 0x80; + else + return brw + (ret & 0xFF); +} + +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, + const unsigned char *seq); +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap, + const unsigned char *seq); +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD_INTERNAL *rr, + unsigned int *is_next_epoch); +static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +static int dtls1_process_record(SSL *s); + +/* copy buffered record into SSL structure */ +static int +dtls1_copy_record(SSL *s, DTLS1_RECORD_DATA_INTERNAL *rdata) +{ + ssl3_release_buffer(&s->s3->rbuf); + + s->packet = rdata->packet; + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER_INTERNAL)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD_INTERNAL)); + + return (1); +} + +static int +dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) +{ + DTLS1_RECORD_DATA_INTERNAL *rdata = NULL; + pitem *item = NULL; + + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + + if ((rdata = malloc(sizeof(*rdata))) == NULL) + goto init_err; + if ((item = pitem_new(priority, rdata)) == NULL) + goto init_err; + + rdata->packet = s->packet; + rdata->packet_length = s->packet_length; + memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER_INTERNAL)); + memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD_INTERNAL)); + + item->data = rdata; + + s->packet = NULL; + s->packet_length = 0; + memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER_INTERNAL)); + memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD_INTERNAL)); + + if (!ssl3_setup_buffers(s)) + goto err; + + /* insert should not fail, since duplicates are dropped */ + if (pqueue_insert(queue->q, item) == NULL) + goto err; + + return (1); + + err: + ssl3_release_buffer(&rdata->rbuf); + + init_err: + SSLerror(s, ERR_R_INTERNAL_ERROR); + free(rdata); + pitem_free(item); + return (-1); +} + +static int +dtls1_buffer_rcontent(SSL *s, rcontent_pqueue *queue, unsigned char *priority) +{ + DTLS1_RCONTENT_DATA_INTERNAL *rdata = NULL; + pitem *item = NULL; + + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + + if ((rdata = malloc(sizeof(*rdata))) == NULL) + goto init_err; + if ((item = pitem_new(priority, rdata)) == NULL) + goto init_err; + + rdata->rcontent = s->s3->rcontent; + s->s3->rcontent = NULL; + + item->data = rdata; + + /* insert should not fail, since duplicates are dropped */ + if (pqueue_insert(queue->q, item) == NULL) + goto err; + + if ((s->s3->rcontent = tls_content_new()) == NULL) + goto err; + + return (1); + + err: + tls_content_free(rdata->rcontent); + + init_err: + SSLerror(s, ERR_R_INTERNAL_ERROR); + free(rdata); + pitem_free(item); + return (-1); +} + +static int +dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) +{ + pitem *item; + + item = pqueue_pop(queue->q); + if (item) { + dtls1_copy_record(s, item->data); + + free(item->data); + pitem_free(item); + + return (1); + } + + return (0); +} + +static int +dtls1_retrieve_buffered_rcontent(SSL *s, rcontent_pqueue *queue) +{ + DTLS1_RCONTENT_DATA_INTERNAL *rdata; + pitem *item; + + item = pqueue_pop(queue->q); + if (item) { + rdata = item->data; + + tls_content_free(s->s3->rcontent); + s->s3->rcontent = rdata->rcontent; + s->s3->rrec.epoch = tls_content_epoch(s->s3->rcontent); + + free(item->data); + pitem_free(item); + + return (1); + } + + return (0); +} + +static int +dtls1_process_buffered_record(SSL *s) +{ + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != + tls12_record_layer_read_epoch(s->rl)) + return (0); + + /* Update epoch once all unprocessed records have been processed. */ + if (pqueue_peek(s->d1->unprocessed_rcds.q) == NULL) { + s->d1->unprocessed_rcds.epoch = + tls12_record_layer_read_epoch(s->rl) + 1; + return (0); + } + + /* Process one of the records. */ + if (!dtls1_retrieve_buffered_record(s, &s->d1->unprocessed_rcds)) + return (-1); + if (!dtls1_process_record(s)) + return (-1); + + return (1); +} + +static int +dtls1_process_record(SSL *s) +{ + SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec); + uint8_t alert_desc; + + tls12_record_layer_set_version(s->rl, s->version); + + if (!tls12_record_layer_open_record(s->rl, s->packet, s->packet_length, + s->s3->rcontent)) { + tls12_record_layer_alert(s->rl, &alert_desc); + + if (alert_desc == 0) + goto err; + + /* + * DTLS should silently discard invalid records, including those + * with a bad MAC, as per RFC 6347 section 4.1.2.1. + */ + if (alert_desc == SSL_AD_BAD_RECORD_MAC) + goto done; + + if (alert_desc == SSL_AD_RECORD_OVERFLOW) + SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + + goto fatal_err; + } + + /* XXX move to record layer. */ + tls_content_set_epoch(s->s3->rcontent, rr->epoch); + + done: + s->packet_length = 0; + + return (1); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, alert_desc); + err: + return (0); +} + +/* Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by dtls1_read_bytes */ +int +dtls1_get_record(SSL *s) +{ + SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec); + unsigned char *p = NULL; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + int ret, n; + + /* See if there are pending records that can now be processed. */ + if ((ret = dtls1_process_buffered_record(s)) != 0) + return (ret); + + /* get something from the wire */ + if (0) { + again: + /* dump this record on all retries */ + rr->length = 0; + s->packet_length = 0; + } + + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { + CBS header, seq_no; + uint16_t epoch, len, ssl_version; + uint8_t type; + + n = ssl3_packet_read(s, DTLS1_RT_HEADER_LENGTH); + if (n <= 0) + return (n); + + /* If this packet contained a partial record, dump it. */ + if (n != DTLS1_RT_HEADER_LENGTH) + goto again; + + s->rstate = SSL_ST_READ_BODY; + + CBS_init(&header, s->packet, s->packet_length); + + /* Pull apart the header into the DTLS1_RECORD */ + if (!CBS_get_u8(&header, &type)) + goto again; + if (!CBS_get_u16(&header, &ssl_version)) + goto again; + + /* Sequence number is 64 bits, with top 2 bytes = epoch. */ + if (!CBS_get_bytes(&header, &seq_no, SSL3_SEQUENCE_SIZE)) + goto again; + if (!CBS_get_u16(&seq_no, &epoch)) + goto again; + if (!CBS_write_bytes(&seq_no, &rr->seq_num[2], + sizeof(rr->seq_num) - 2, NULL)) + goto again; + + if (!CBS_get_u16(&header, &len)) + goto again; + + rr->type = type; + rr->epoch = epoch; + rr->length = len; + + /* unexpected version, silently discard */ + if (!s->first_packet && ssl_version != s->version) + goto again; + + /* wrong version, silently discard record */ + if ((ssl_version & 0xff00) != (s->version & 0xff00)) + goto again; + + /* record too long, silently discard it */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) + goto again; + + /* now s->rstate == SSL_ST_READ_BODY */ + p = (unsigned char *)CBS_data(&header); + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + n = ssl3_packet_extend(s, DTLS1_RT_HEADER_LENGTH + rr->length); + if (n <= 0) + return (n); + + /* If this packet contained a partial record, dump it. */ + if (n != DTLS1_RT_HEADER_LENGTH + rr->length) + goto again; + + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* match epochs. NULL means the packet is dropped on the floor */ + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) + goto again; + + /* + * Check whether this is a repeat, or aged record. + * Don't check if we're listening and this message is + * a ClientHello. They can look as if they're replayed, + * since they arrive from different connections and + * would be dropped unnecessarily. + */ + if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && + p != NULL && *p == SSL3_MT_CLIENT_HELLO) && + !dtls1_record_replay_check(s, bitmap, rr->seq_num)) + goto again; + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + + /* If this record is from the next epoch (either HM or ALERT), + * and a handshake is currently in progress, buffer it since it + * cannot be processed at this time. However, do not buffer + * anything while listening. + */ + if (is_next_epoch) { + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { + if (dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), + rr->seq_num) < 0) + return (-1); + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap, rr->seq_num); + } + goto again; + } + + if (!dtls1_process_record(s)) + goto again; + + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap, rr->seq_num); + + return (1); +} + +static int +dtls1_read_handshake_unexpected(SSL *s) +{ + struct hm_header_st hs_msg_hdr; + CBS cbs; + int ret; + + if (s->in_handshake) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* Parse handshake message header. */ + CBS_dup(tls_content_cbs(s->s3->rcontent), &cbs); + if (!dtls1_get_message_header(&cbs, &hs_msg_hdr)) + return -1; /* XXX - probably should drop/continue. */ + + /* This may just be a stale retransmit. */ + if (tls_content_epoch(s->s3->rcontent) != + tls12_record_layer_read_epoch(s->rl)) { + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + return 1; + } + + if (hs_msg_hdr.type == SSL3_MT_HELLO_REQUEST) { + /* + * Incoming HelloRequest messages should only be received by a + * client. A server may send these at any time - a client should + * ignore the message if received in the middle of a handshake. + * See RFC 5246 sections 7.4 and 7.4.1.1. + */ + if (s->server) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + /* XXX - should also check frag offset/length. */ + if (hs_msg_hdr.msg_len != 0) { + SSLerror(s, SSL_R_BAD_HELLO_REQUEST); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return -1; + } + + ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, + tls_content_cbs(s->s3->rcontent)); + + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + + /* + * It should be impossible to hit this, but keep the safety + * harness for now... + */ + if (s->session == NULL || s->session->cipher == NULL) + return 1; + + /* + * Ignore this message if we're currently handshaking, + * renegotiation is already pending or renegotiation is disabled + * via flags. + */ + if (!SSL_is_init_finished(s) || s->s3->renegotiate || + (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) + return 1; + + s->d1->handshake_read_seq++; + + /* XXX - why is this set here but not in ssl3? */ + s->new_session = 1; + + if (!ssl3_renegotiate(s)) + return 1; + if (!ssl3_renegotiate_check(s)) + return 1; + + } else if (hs_msg_hdr.type == SSL3_MT_CLIENT_HELLO) { + /* + * Incoming ClientHello messages should only be received by a + * server. A client may send these in response to server + * initiated renegotiation (HelloRequest) or in order to + * initiate renegotiation by the client. See RFC 5246 section + * 7.4.1.2. + */ + if (!s->server) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * A client should not be sending a ClientHello unless we're not + * currently handshaking. + */ + if (!SSL_is_init_finished(s)) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_NO_RENEGOTIATION); + return -1; + } + + if (s->session == NULL || s->session->cipher == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* Client requested renegotiation but it is not permitted. */ + if (!s->s3->send_connection_binding || + (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) { + ssl3_send_alert(s, SSL3_AL_WARNING, + SSL_AD_NO_RENEGOTIATION); + return 1; + } + + s->s3->hs.state = SSL_ST_ACCEPT; + s->renegotiate = 1; + s->new_session = 1; + + } else if (hs_msg_hdr.type == SSL3_MT_FINISHED && s->server) { + /* + * If we are server, we may have a repeated FINISHED of the + * client here, then retransmit our CCS and FINISHED. + */ + if (dtls1_check_timeout_num(s) < 0) + return -1; + + /* XXX - should this be calling ssl_msg_callback()? */ + + dtls1_retransmit_buffered_messages(s); + + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + + return 1; + + } else { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if ((ret = s->handshake_func(s)) < 0) + return ret; + if (ret == 0) { + SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { + ssl_force_want_read(s); + return -1; + } + } + + /* + * We either finished a handshake or ignored the request, now try again + * to obtain the (application) data we were asked for. + */ + return 1; +} + +/* Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int +dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int rrcount = 0; + ssize_t ssret; + int ret; + + if (s->s3->rbuf.buf == NULL) { + if (!ssl3_setup_buffers(s)) + return -1; + } + + if (s->s3->rcontent == NULL) { + if ((s->s3->rcontent = tls_content_new()) == NULL) + return -1; + } + + if (len < 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (type != 0 && type != SSL3_RT_APPLICATION_DATA && + type != SSL3_RT_HANDSHAKE) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + if (peek && type != SSL3_RT_APPLICATION_DATA) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (SSL_in_init(s) && !s->in_handshake) { + if ((ret = s->handshake_func(s)) < 0) + return ret; + if (ret == 0) { + SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + start: + /* + * Do not process more than three consecutive records, otherwise the + * peer can cause us to loop indefinitely. Instead, return with an + * SSL_ERROR_WANT_READ so the caller can choose when to handle further + * processing. In the future, the total number of non-handshake and + * non-application data records per connection should probably also be + * limited... + */ + if (rrcount++ >= 3) { + ssl_force_want_read(s); + return -1; + } + + s->rwstate = SSL_NOTHING; + + /* + * We are not handshaking and have no data yet, so process data buffered + * during the last handshake in advance, if any. + */ + if (s->s3->hs.state == SSL_ST_OK && + tls_content_remaining(s->s3->rcontent) == 0) + dtls1_retrieve_buffered_rcontent(s, &s->d1->buffered_app_data); + + if (dtls1_handle_timeout(s) > 0) + goto start; + + if (tls_content_remaining(s->s3->rcontent) == 0) { + if ((ret = dtls1_get_record(s)) <= 0) { + /* Anything other than a timeout is an error. */ + if ((ret = dtls1_read_failed(s, ret)) <= 0) + return ret; + goto start; + } + } + + if (s->d1->listen && + tls_content_type(s->s3->rcontent) != SSL3_RT_HANDSHAKE) { + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + goto start; + } + + /* We now have a packet which can be read and processed. */ + + if (s->s3->change_cipher_spec && + tls_content_type(s->s3->rcontent) != SSL3_RT_HANDSHAKE) { + /* + * We now have application data between CCS and Finished. + * Most likely the packets were reordered on their way, so + * buffer the application data for later processing rather + * than dropping the connection. + */ + if (dtls1_buffer_rcontent(s, &s->d1->buffered_app_data, + s->s3->rrec.seq_num) < 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return (-1); + } + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + goto start; + } + + /* + * If the other end has shut down, throw anything we read away (even in + * 'peek' mode). + */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + return 0; + } + + /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ + if (tls_content_type(s->s3->rcontent) == type) { + /* + * Make sure that we are not getting application data when we + * are doing a handshake for the first time. + */ + if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && + !tls12_record_layer_read_protected(s->rl)) { + SSLerror(s, SSL_R_APP_DATA_IN_HANDSHAKE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if (len <= 0) + return len; + + if (peek) { + ssret = tls_content_peek(s->s3->rcontent, buf, len); + } else { + ssret = tls_content_read(s->s3->rcontent, buf, len); + } + if (ssret < INT_MIN || ssret > INT_MAX) + return -1; + if (ssret < 0) + return (int)ssret; + + if (tls_content_remaining(s->s3->rcontent) == 0) + s->rstate = SSL_ST_READ_HEADER; + + return (int)ssret; + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_ALERT) { + if ((ret = ssl3_read_alert(s)) <= 0) + return ret; + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + return (0); + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_APPLICATION_DATA) { + /* + * At this point, we were expecting handshake data, but have + * application data. If the library was running inside + * ssl3_read() (i.e. in_read_app_data is set) and it makes + * sense to read application data at this point (session + * renegotiation not yet started), we will indulge it. + */ + if (s->s3->in_read_app_data != 0 && + s->s3->total_renegotiations != 0 && + (((s->s3->hs.state & SSL_ST_CONNECT) && + (s->s3->hs.state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->s3->hs.state <= SSL3_ST_CR_SRVR_HELLO_A)) || ( + (s->s3->hs.state & SSL_ST_ACCEPT) && + (s->s3->hs.state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->s3->hs.state >= SSL3_ST_SR_CLNT_HELLO_A)))) { + s->s3->in_read_app_data = 2; + return -1; + } else { + SSLerror(s, SSL_R_UNEXPECTED_RECORD); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_CHANGE_CIPHER_SPEC) { + if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) + return ret; + goto start; + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_HANDSHAKE) { + if ((ret = dtls1_read_handshake_unexpected(s)) <= 0) + return ret; + goto start; + } + + /* Unknown record type. */ + SSLerror(s, SSL_R_UNEXPECTED_RECORD); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; +} + +int +dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) +{ + int i; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerror(s, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + i = dtls1_write_bytes(s, type, buf_, len); + return i; +} + +/* Call this to write data in records of type 'type' + * It will return <= 0 if not all data has been sent or non-blocking IO. + */ +int +dtls1_write_bytes(SSL *s, int type, const void *buf, int len) +{ + int i; + + OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + s->rwstate = SSL_NOTHING; + i = do_dtls1_write(s, type, buf, len); + return i; +} + +int +do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) +{ + SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf); + size_t out_len; + CBB cbb; + int ret; + + memset(&cbb, 0, sizeof(cbb)); + + /* + * First check if there is a SSL3_BUFFER_INTERNAL still being written + * out. This will happen with non blocking IO. + */ + if (wb->left != 0) { + OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ + return (ssl3_write_pending(s, type, buf, len)); + } + + /* If we have an alert to send, let's send it */ + if (s->s3->alert_dispatch) { + if ((ret = ssl3_dispatch_alert(s)) <= 0) + return (ret); + /* If it went, fall through and send more stuff. */ + } + + if (len == 0) + return 0; + + wb->offset = 0; + + if (!CBB_init_fixed(&cbb, wb->buf, wb->len)) + goto err; + + tls12_record_layer_set_version(s->rl, s->version); + + if (!tls12_record_layer_seal_record(s->rl, type, buf, len, &cbb)) + goto err; + + if (!CBB_finish(&cbb, NULL, &out_len)) + goto err; + + wb->left = out_len; + + /* + * Memorize arguments so that ssl3_write_pending can detect + * bad write retries later. + */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* We now just need to write the buffer. */ + return ssl3_write_pending(s, type, buf, len); + + err: + CBB_cleanup(&cbb); + + return -1; +} + +static int +dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, + const unsigned char *seq) +{ + unsigned int shift; + int cmp; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) + return 1; /* this record in new */ + shift = -cmp; + if (shift >= sizeof(bitmap->map)*8) + return 0; /* stale, outside the window */ + else if (bitmap->map & (1UL << shift)) + return 0; /* record previously received */ + + return 1; +} + +static void +dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap, + const unsigned char *seq) +{ + unsigned int shift; + int cmp; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + shift = cmp; + if (shift < sizeof(bitmap->map)*8) + bitmap->map <<= shift, bitmap->map |= 1UL; + else + bitmap->map = 1UL; + memcpy(bitmap->max_seq_num, seq, 8); + } else { + shift = -cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map |= 1UL << shift; + } +} + +static DTLS1_BITMAP * +dtls1_get_bitmap(SSL *s, SSL3_RECORD_INTERNAL *rr, unsigned int *is_next_epoch) +{ + uint16_t read_epoch, read_epoch_next; + + *is_next_epoch = 0; + + read_epoch = tls12_record_layer_read_epoch(s->rl); + read_epoch_next = read_epoch + 1; + + /* In current epoch, accept HM, CCS, DATA, & ALERT */ + if (rr->epoch == read_epoch) + return &s->d1->bitmap; + + /* Only HM and ALERT messages can be from the next epoch */ + if (rr->epoch == read_epoch_next && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; + } + + return NULL; +} + +void +dtls1_reset_read_seq_numbers(SSL *s) +{ + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0, sizeof(DTLS1_BITMAP)); +} diff --git a/Libraries/libressl/ssl/d1_srtp.c b/Libraries/libressl/ssl/d1_srtp.c new file mode 100644 index 000000000..67c4495a1 --- /dev/null +++ b/Libraries/libressl/ssl/d1_srtp.c @@ -0,0 +1,266 @@ +/* $OpenBSD: d1_srtp.c,v 1.33 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. + * Copyright (C) 2011, RTFM, Inc. + */ + +#include + +#include +#include + +#ifndef OPENSSL_NO_SRTP + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" +#include "srtp.h" + +static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { + { + "SRTP_AES128_CM_SHA1_80", + SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", + SRTP_AES128_CM_SHA1_32, + }, + { + "SRTP_AEAD_AES_128_GCM", + SRTP_AEAD_AES_128_GCM, + }, + { + "SRTP_AEAD_AES_256_GCM", + SRTP_AEAD_AES_256_GCM, + }, + {0} +}; + +int +srtp_find_profile_by_name(const char *profile_name, + const SRTP_PROTECTION_PROFILE **pptr, unsigned int len) +{ + const SRTP_PROTECTION_PROFILE *p; + + p = srtp_known_profiles; + while (p->name) { + if ((len == strlen(p->name)) && + !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 0; + } + + p++; + } + + return 1; +} + +int +srtp_find_profile_by_num(unsigned int profile_num, + const SRTP_PROTECTION_PROFILE **pptr) +{ + const SRTP_PROTECTION_PROFILE *p; + + p = srtp_known_profiles; + while (p->name) { + if (p->id == profile_num) { + *pptr = p; + return 0; + } + p++; + } + + return 1; +} + +static int +ssl_ctx_make_profiles(const char *profiles_string, + STACK_OF(SRTP_PROTECTION_PROFILE) **out) +{ + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; + char *col; + const char *ptr = profiles_string; + const SRTP_PROTECTION_PROFILE *p; + + if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) { + SSLerrorx(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 1; + } + + do { + col = strchr(ptr, ':'); + + if (!srtp_find_profile_by_name(ptr, &p, + col ? col - ptr : (int)strlen(ptr))) { + if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) { + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + } else { + SSLerrorx(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + + if (col) + ptr = col + 1; + } while (col); + + sk_SRTP_PROTECTION_PROFILE_free(*out); + *out = profiles; + + return 0; +} + +int +SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} +LSSL_ALIAS(SSL_CTX_set_tlsext_use_srtp); + +int +SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); +} +LSSL_ALIAS(SSL_set_tlsext_use_srtp); + + +STACK_OF(SRTP_PROTECTION_PROFILE) * +SSL_get_srtp_profiles(SSL *s) +{ + if (s != NULL) { + if (s->srtp_profiles != NULL) { + return s->srtp_profiles; + } else if ((s->ctx != NULL) && + (s->ctx->srtp_profiles != NULL)) { + return s->ctx->srtp_profiles; + } + } + + return NULL; +} +LSSL_ALIAS(SSL_get_srtp_profiles); + +SRTP_PROTECTION_PROFILE * +SSL_get_selected_srtp_profile(SSL *s) +{ + /* XXX cast away the const */ + return (SRTP_PROTECTION_PROFILE *)s->srtp_profile; +} +LSSL_ALIAS(SSL_get_selected_srtp_profile); + +#endif diff --git a/Libraries/libressl/ssl/dtls_local.h b/Libraries/libressl/ssl/dtls_local.h new file mode 100644 index 000000000..c7c413fef --- /dev/null +++ b/Libraries/libressl/ssl/dtls_local.h @@ -0,0 +1,232 @@ +/* $OpenBSD: dtls_local.h,v 1.2 2022/11/26 17:23:18 tb Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS_LOCL_H +#define HEADER_DTLS_LOCL_H + +#include + +#include + +#include "ssl_local.h" +#include "tls_content.h" + +__BEGIN_HIDDEN_DECLS + +typedef struct dtls1_bitmap_st { + unsigned long map; /* track 32 packets on 32-bit systems + and 64 - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, + 64-bit value in big-endian + encoding */ +} DTLS1_BITMAP; + +struct dtls1_retransmit_state { + SSL_SESSION *session; + unsigned short epoch; +}; + +struct hm_header_st { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; +}; + +struct dtls1_timeout_st { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + + /* Number of write timeouts so far */ + unsigned int write_timeouts; + + /* Number of alerts received so far */ + unsigned int num_alerts; +}; + +struct _pqueue; + +typedef struct record_pqueue_st { + unsigned short epoch; + struct _pqueue *q; +} record_pqueue; + +typedef struct rcontent_pqueue_st { + unsigned short epoch; + struct _pqueue *q; +} rcontent_pqueue; + +typedef struct hm_fragment_st { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; +} hm_fragment; + +typedef struct dtls1_record_data_internal_st { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER_INTERNAL rbuf; + SSL3_RECORD_INTERNAL rrec; +} DTLS1_RECORD_DATA_INTERNAL; + +typedef struct dtls1_rcontent_data_internal_st { + struct tls_content *rcontent; +} DTLS1_RCONTENT_DATA_INTERNAL; + +struct dtls1_state_st { + /* Buffered (sent) handshake records */ + struct _pqueue *sent_messages; + + /* Indicates when the last handshake msg or heartbeat sent will timeout */ + struct timeval next_timeout; + + /* Timeout duration */ + unsigned short timeout_duration; + + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + + unsigned short handshake_read_seq; + + /* Received handshake records (unprocessed) */ + record_pqueue unprocessed_rcds; + + /* Buffered handshake messages */ + struct _pqueue *buffered_messages; + + /* Buffered application records. + * Only for records between CCS and Finished + * to prevent either protocol violation or + * unnecessary message loss. + */ + rcontent_pqueue buffered_app_data; + + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + + unsigned int mtu; /* max DTLS packet size */ + + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + + struct dtls1_timeout_st timeout; + + unsigned int retransmitting; + unsigned int change_cipher_spec_ok; +}; + +int dtls1_do_write(SSL *s, int type); +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +void dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len, + unsigned long frag_off, unsigned long frag_len); +void dtls1_set_message_header_int(SSL *s, unsigned char mt, + unsigned long len, unsigned short seq_num, unsigned long frag_off, + unsigned long frag_len); + +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + unsigned int len); + +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len); +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); + +int dtls1_read_failed(SSL *s, int code); +int dtls1_buffer_message(SSL *s, int ccs); +int dtls1_retransmit_message(SSL *s, unsigned short seq, + unsigned long frag_off, int *found); +int dtls1_get_queue_priority(unsigned short seq, int is_ccs); +int dtls1_retransmit_buffered_messages(SSL *s); +void dtls1_clear_record_buffer(SSL *s); +int dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr); +void dtls1_reset_read_seq_numbers(SSL *s); +struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); +int dtls1_check_timeout_num(SSL *s); +int dtls1_handle_timeout(SSL *s); +const SSL_CIPHER *dtls1_get_cipher(unsigned int u); +void dtls1_start_timer(SSL *s); +void dtls1_stop_timer(SSL *s); +int dtls1_is_timer_expired(SSL *s); +void dtls1_double_timeout(SSL *s); +unsigned int dtls1_min_mtu(void); + +int dtls1_new(SSL *s); +void dtls1_free(SSL *s); +void dtls1_clear(SSL *s); +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); + +int dtls1_get_message(SSL *s, int st1, int stn, int mt, long max); +int dtls1_get_record(SSL *s); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_DTLS_LOCL_H */ diff --git a/Libraries/libressl/ssl/empty.c b/Libraries/libressl/ssl/empty.c new file mode 100644 index 000000000..e69de29bb diff --git a/Libraries/libressl/ssl/hidden/openssl/srtp.h b/Libraries/libressl/ssl/hidden/openssl/srtp.h new file mode 100644 index 000000000..2440fc93d --- /dev/null +++ b/Libraries/libressl/ssl/hidden/openssl/srtp.h @@ -0,0 +1,33 @@ +/* $OpenBSD: srtp.h,v 1.1 2023/07/08 16:40:14 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBSSL_SRTP_H +#define _LIBSSL_SRTP_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/srtp.h" +#endif +#include "ssl_namespace.h" + +LSSL_USED(SSL_CTX_set_tlsext_use_srtp); +LSSL_USED(SSL_set_tlsext_use_srtp); +LSSL_USED(SSL_get_srtp_profiles); +LSSL_USED(SSL_get_selected_srtp_profile); + +#endif /* _LIBSSL_SRTP_H */ diff --git a/Libraries/libressl/ssl/hidden/openssl/ssl.h b/Libraries/libressl/ssl/hidden/openssl/ssl.h new file mode 100644 index 000000000..e4ec6d625 --- /dev/null +++ b/Libraries/libressl/ssl/hidden/openssl/ssl.h @@ -0,0 +1,384 @@ +/* $OpenBSD: ssl.h,v 1.4 2023/07/28 09:53:55 tb Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBSSL_SSL_H +#define _LIBSSL_SSL_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/ssl.h" +#endif +#include "ssl_namespace.h" + +LSSL_USED(SSL_CTX_set_msg_callback); +LSSL_USED(SSL_set_msg_callback); +LSSL_USED(SSL_CTX_set_keylog_callback); +LSSL_USED(SSL_CTX_get_keylog_callback); +LSSL_USED(SSL_set_num_tickets); +LSSL_USED(SSL_get_num_tickets); +LSSL_USED(SSL_CTX_set_num_tickets); +LSSL_USED(SSL_CTX_get_num_tickets); +LSSL_USED(SSL_get0_verified_chain); +LSSL_USED(SSL_CTX_sessions); +LSSL_USED(SSL_CTX_sess_set_new_cb); +LSSL_USED(SSL_CTX_sess_get_new_cb); +LSSL_USED(SSL_CTX_sess_set_remove_cb); +LSSL_USED(SSL_CTX_sess_get_remove_cb); +LSSL_USED(SSL_CTX_sess_set_get_cb); +LSSL_USED(SSL_CTX_set_info_callback); +LSSL_USED(SSL_CTX_get_info_callback); +LSSL_USED(SSL_CTX_set_client_cert_cb); +LSSL_USED(SSL_CTX_get_client_cert_cb); +LSSL_USED(SSL_CTX_set_cookie_generate_cb); +LSSL_USED(SSL_CTX_set_cookie_verify_cb); +LSSL_USED(SSL_CTX_set_next_protos_advertised_cb); +LSSL_USED(SSL_CTX_set_next_proto_select_cb); +LSSL_USED(SSL_select_next_proto); +LSSL_USED(SSL_get0_next_proto_negotiated); +LSSL_USED(SSL_CTX_set_alpn_protos); +LSSL_USED(SSL_set_alpn_protos); +LSSL_USED(SSL_CTX_set_alpn_select_cb); +LSSL_USED(SSL_get0_alpn_selected); +LSSL_USED(SSL_set_psk_use_session_callback); +LSSL_USED(SSL_get_finished); +LSSL_USED(SSL_get_peer_finished); +LSSL_USED(SSL_verify_client_post_handshake); +LSSL_USED(SSL_CTX_set_post_handshake_auth); +LSSL_USED(SSL_set_post_handshake_auth); +LSSL_USED(PEM_read_bio_SSL_SESSION); +LSSL_USED(PEM_read_SSL_SESSION); +LSSL_USED(PEM_write_bio_SSL_SESSION); +LSSL_USED(PEM_write_SSL_SESSION); +LSSL_USED(SSL_CTX_set0_chain); +LSSL_USED(SSL_CTX_set1_chain); +LSSL_USED(SSL_CTX_add0_chain_cert); +LSSL_USED(SSL_CTX_add1_chain_cert); +LSSL_USED(SSL_CTX_get0_chain_certs); +LSSL_USED(SSL_CTX_clear_chain_certs); +LSSL_USED(SSL_set0_chain); +LSSL_USED(SSL_set1_chain); +LSSL_USED(SSL_add0_chain_cert); +LSSL_USED(SSL_add1_chain_cert); +LSSL_USED(SSL_get0_chain_certs); +LSSL_USED(SSL_clear_chain_certs); +LSSL_USED(SSL_CTX_set1_groups); +LSSL_USED(SSL_CTX_set1_groups_list); +LSSL_USED(SSL_set1_groups); +LSSL_USED(SSL_set1_groups_list); +LSSL_USED(SSL_CTX_get_min_proto_version); +LSSL_USED(SSL_CTX_get_max_proto_version); +LSSL_USED(SSL_CTX_set_min_proto_version); +LSSL_USED(SSL_CTX_set_max_proto_version); +LSSL_USED(SSL_get_min_proto_version); +LSSL_USED(SSL_get_max_proto_version); +LSSL_USED(SSL_set_min_proto_version); +LSSL_USED(SSL_set_max_proto_version); +LSSL_USED(SSL_CTX_get_ssl_method); +LSSL_USED(BIO_f_ssl); +LSSL_USED(BIO_new_ssl); +LSSL_USED(BIO_new_ssl_connect); +LSSL_USED(BIO_new_buffer_ssl_connect); +LSSL_USED(BIO_ssl_copy_session_id); +LSSL_USED(BIO_ssl_shutdown); +LSSL_USED(SSL_CTX_get_ciphers); +LSSL_USED(SSL_CTX_set_cipher_list); +LSSL_USED(SSL_CTX_set_ciphersuites); +LSSL_USED(SSL_CTX_new); +LSSL_USED(SSL_CTX_free); +LSSL_USED(SSL_CTX_up_ref); +LSSL_USED(SSL_CTX_set_timeout); +LSSL_USED(SSL_CTX_get_timeout); +LSSL_USED(SSL_CTX_get_cert_store); +LSSL_USED(SSL_CTX_set_cert_store); +LSSL_USED(SSL_CTX_get0_certificate); +LSSL_USED(SSL_CTX_get0_privatekey); +LSSL_USED(SSL_want); +LSSL_USED(SSL_clear); +LSSL_USED(SSL_CTX_flush_sessions); +LSSL_USED(SSL_get_current_cipher); +LSSL_USED(SSL_CIPHER_get_by_id); +LSSL_USED(SSL_CIPHER_get_by_value); +LSSL_USED(SSL_CIPHER_get_bits); +LSSL_USED(SSL_CIPHER_get_version); +LSSL_USED(SSL_CIPHER_get_name); +LSSL_USED(SSL_CIPHER_get_id); +LSSL_USED(SSL_CIPHER_get_value); +LSSL_USED(SSL_CIPHER_find); +LSSL_USED(SSL_CIPHER_get_cipher_nid); +LSSL_USED(SSL_CIPHER_get_digest_nid); +LSSL_USED(SSL_CIPHER_get_kx_nid); +LSSL_USED(SSL_CIPHER_get_auth_nid); +LSSL_USED(SSL_CIPHER_is_aead); +LSSL_USED(SSL_get_fd); +LSSL_USED(SSL_get_rfd); +LSSL_USED(SSL_get_wfd); +LSSL_USED(SSL_get_cipher_list); +LSSL_USED(SSL_get_shared_ciphers); +LSSL_USED(SSL_get_read_ahead); +LSSL_USED(SSL_pending); +LSSL_USED(SSL_set_fd); +LSSL_USED(SSL_set_rfd); +LSSL_USED(SSL_set_wfd); +LSSL_USED(SSL_set_bio); +LSSL_USED(SSL_get_rbio); +LSSL_USED(SSL_set0_rbio); +LSSL_USED(SSL_get_wbio); +LSSL_USED(SSL_set_cipher_list); +LSSL_USED(SSL_set_ciphersuites); +LSSL_USED(SSL_set_read_ahead); +LSSL_USED(SSL_get_verify_mode); +LSSL_USED(SSL_get_verify_depth); +LSSL_USED(SSL_get_verify_callback); +LSSL_USED(SSL_set_verify); +LSSL_USED(SSL_set_verify_depth); +LSSL_USED(SSL_use_RSAPrivateKey); +LSSL_USED(SSL_use_RSAPrivateKey_ASN1); +LSSL_USED(SSL_use_PrivateKey); +LSSL_USED(SSL_use_PrivateKey_ASN1); +LSSL_USED(SSL_use_certificate); +LSSL_USED(SSL_use_certificate_ASN1); +LSSL_USED(SSL_use_RSAPrivateKey_file); +LSSL_USED(SSL_use_PrivateKey_file); +LSSL_USED(SSL_use_certificate_file); +LSSL_USED(SSL_use_certificate_chain_file); +LSSL_USED(SSL_CTX_use_RSAPrivateKey_file); +LSSL_USED(SSL_CTX_use_PrivateKey_file); +LSSL_USED(SSL_CTX_use_certificate_file); +LSSL_USED(SSL_CTX_use_certificate_chain_file); +LSSL_USED(SSL_CTX_use_certificate_chain_mem); +LSSL_USED(SSL_load_client_CA_file); +LSSL_USED(SSL_add_file_cert_subjects_to_stack); +LSSL_USED(SSL_add_dir_cert_subjects_to_stack); +LSSL_USED(SSL_load_error_strings); +LSSL_USED(SSL_state_string); +LSSL_USED(SSL_rstate_string); +LSSL_USED(SSL_state_string_long); +LSSL_USED(SSL_rstate_string_long); +LSSL_USED(SSL_SESSION_get0_cipher); +LSSL_USED(SSL_SESSION_get_master_key); +LSSL_USED(SSL_SESSION_get_protocol_version); +LSSL_USED(SSL_SESSION_get_time); +LSSL_USED(SSL_SESSION_set_time); +LSSL_USED(SSL_SESSION_get_timeout); +LSSL_USED(SSL_SESSION_set_timeout); +LSSL_USED(SSL_copy_session_id); +LSSL_USED(SSL_SESSION_get0_peer); +LSSL_USED(SSL_SESSION_set1_id); +LSSL_USED(SSL_SESSION_set1_id_context); +LSSL_USED(SSL_SESSION_is_resumable); +LSSL_USED(SSL_SESSION_new); +LSSL_USED(SSL_SESSION_free); +LSSL_USED(SSL_SESSION_up_ref); +LSSL_USED(SSL_SESSION_get_id); +LSSL_USED(SSL_SESSION_get0_id_context); +LSSL_USED(SSL_SESSION_get_max_early_data); +LSSL_USED(SSL_SESSION_set_max_early_data); +LSSL_USED(SSL_SESSION_get_ticket_lifetime_hint); +LSSL_USED(SSL_SESSION_has_ticket); +LSSL_USED(SSL_SESSION_get_compress_id); +LSSL_USED(SSL_SESSION_print_fp); +LSSL_USED(SSL_SESSION_print); +LSSL_USED(i2d_SSL_SESSION); +LSSL_USED(SSL_set_session); +LSSL_USED(SSL_CTX_add_session); +LSSL_USED(SSL_CTX_remove_session); +LSSL_USED(SSL_CTX_set_generate_session_id); +LSSL_USED(SSL_set_generate_session_id); +LSSL_USED(SSL_has_matching_session_id); +LSSL_USED(d2i_SSL_SESSION); +LSSL_USED(SSL_get_peer_cert_chain); +LSSL_USED(SSL_CTX_get_verify_mode); +LSSL_USED(SSL_CTX_get_verify_depth); +LSSL_USED(SSL_CTX_get_verify_callback); +LSSL_USED(SSL_CTX_set_verify); +LSSL_USED(SSL_CTX_set_verify_depth); +LSSL_USED(SSL_CTX_set_cert_verify_callback); +LSSL_USED(SSL_CTX_use_RSAPrivateKey); +LSSL_USED(SSL_CTX_use_RSAPrivateKey_ASN1); +LSSL_USED(SSL_CTX_use_PrivateKey); +LSSL_USED(SSL_CTX_use_PrivateKey_ASN1); +LSSL_USED(SSL_CTX_use_certificate); +LSSL_USED(SSL_CTX_use_certificate_ASN1); +LSSL_USED(SSL_CTX_get_default_passwd_cb); +LSSL_USED(SSL_CTX_set_default_passwd_cb); +LSSL_USED(SSL_CTX_get_default_passwd_cb_userdata); +LSSL_USED(SSL_CTX_set_default_passwd_cb_userdata); +LSSL_USED(SSL_CTX_check_private_key); +LSSL_USED(SSL_check_private_key); +LSSL_USED(SSL_CTX_set_session_id_context); +LSSL_USED(SSL_set_session_id_context); +LSSL_USED(SSL_CTX_set_purpose); +LSSL_USED(SSL_set_purpose); +LSSL_USED(SSL_CTX_set_trust); +LSSL_USED(SSL_set_trust); +LSSL_USED(SSL_set1_host); +LSSL_USED(SSL_set_hostflags); +LSSL_USED(SSL_get0_peername); +LSSL_USED(SSL_CTX_get0_param); +LSSL_USED(SSL_CTX_set1_param); +LSSL_USED(SSL_get0_param); +LSSL_USED(SSL_set1_param); +LSSL_USED(SSL_new); +LSSL_USED(SSL_free); +LSSL_USED(SSL_up_ref); +LSSL_USED(SSL_accept); +LSSL_USED(SSL_connect); +LSSL_USED(SSL_is_dtls); +LSSL_USED(SSL_is_server); +LSSL_USED(SSL_read); +LSSL_USED(SSL_peek); +LSSL_USED(SSL_write); +LSSL_USED(SSL_read_ex); +LSSL_USED(SSL_peek_ex); +LSSL_USED(SSL_write_ex); +LSSL_USED(SSL_CTX_get_max_early_data); +LSSL_USED(SSL_CTX_set_max_early_data); +LSSL_USED(SSL_get_max_early_data); +LSSL_USED(SSL_set_max_early_data); +LSSL_USED(SSL_get_early_data_status); +LSSL_USED(SSL_read_early_data); +LSSL_USED(SSL_write_early_data); +LSSL_USED(SSL_ctrl); +LSSL_USED(SSL_callback_ctrl); +LSSL_USED(SSL_CTX_ctrl); +LSSL_USED(SSL_CTX_callback_ctrl); +LSSL_USED(SSL_get_error); +LSSL_USED(SSL_get_version); +LSSL_USED(SSL_CTX_set_ssl_version); +LSSL_USED(SSLv23_method); +LSSL_USED(SSLv23_server_method); +LSSL_USED(SSLv23_client_method); +LSSL_USED(TLSv1_method); +LSSL_USED(TLSv1_server_method); +LSSL_USED(TLSv1_client_method); +LSSL_USED(TLSv1_1_method); +LSSL_USED(TLSv1_1_server_method); +LSSL_USED(TLSv1_1_client_method); +LSSL_USED(TLSv1_2_method); +LSSL_USED(TLSv1_2_server_method); +LSSL_USED(TLSv1_2_client_method); +LSSL_USED(TLS_method); +LSSL_USED(TLS_server_method); +LSSL_USED(TLS_client_method); +LSSL_USED(DTLSv1_method); +LSSL_USED(DTLSv1_server_method); +LSSL_USED(DTLSv1_client_method); +LSSL_USED(DTLSv1_2_method); +LSSL_USED(DTLSv1_2_server_method); +LSSL_USED(DTLSv1_2_client_method); +LSSL_USED(DTLS_method); +LSSL_USED(DTLS_server_method); +LSSL_USED(DTLS_client_method); +LSSL_USED(SSL_get_ciphers); +LSSL_USED(SSL_get_client_ciphers); +LSSL_USED(SSL_get1_supported_ciphers); +LSSL_USED(SSL_do_handshake); +LSSL_USED(SSL_renegotiate); +LSSL_USED(SSL_renegotiate_abbreviated); +LSSL_USED(SSL_renegotiate_pending); +LSSL_USED(SSL_shutdown); +LSSL_USED(SSL_get_ssl_method); +LSSL_USED(SSL_set_ssl_method); +LSSL_USED(SSL_alert_type_string_long); +LSSL_USED(SSL_alert_type_string); +LSSL_USED(SSL_alert_desc_string_long); +LSSL_USED(SSL_alert_desc_string); +LSSL_USED(SSL_set_client_CA_list); +LSSL_USED(SSL_CTX_set_client_CA_list); +LSSL_USED(SSL_get_client_CA_list); +LSSL_USED(SSL_CTX_get_client_CA_list); +LSSL_USED(SSL_add_client_CA); +LSSL_USED(SSL_CTX_add_client_CA); +LSSL_USED(SSL_set_connect_state); +LSSL_USED(SSL_set_accept_state); +LSSL_USED(SSL_get_default_timeout); +LSSL_USED(SSL_library_init); +LSSL_USED(SSL_CIPHER_description); +LSSL_USED(SSL_dup_CA_list); +LSSL_USED(SSL_dup); +LSSL_USED(SSL_get_certificate); +LSSL_USED(SSL_get_privatekey); +LSSL_USED(SSL_CTX_set_quiet_shutdown); +LSSL_USED(SSL_CTX_get_quiet_shutdown); +LSSL_USED(SSL_set_quiet_shutdown); +LSSL_USED(SSL_get_quiet_shutdown); +LSSL_USED(SSL_set_shutdown); +LSSL_USED(SSL_get_shutdown); +LSSL_USED(SSL_version); +LSSL_USED(SSL_CTX_set_default_verify_paths); +LSSL_USED(SSL_CTX_load_verify_locations); +LSSL_USED(SSL_CTX_load_verify_mem); +LSSL_USED(SSL_get_session); +LSSL_USED(SSL_get1_session); +LSSL_USED(SSL_get_SSL_CTX); +LSSL_USED(SSL_set_SSL_CTX); +LSSL_USED(SSL_set_info_callback); +LSSL_USED(SSL_get_info_callback); +LSSL_USED(SSL_state); +LSSL_USED(SSL_set_state); +LSSL_USED(SSL_set_verify_result); +LSSL_USED(SSL_get_verify_result); +LSSL_USED(SSL_set_ex_data); +LSSL_USED(SSL_get_ex_data); +LSSL_USED(SSL_get_ex_new_index); +LSSL_USED(SSL_SESSION_set_ex_data); +LSSL_USED(SSL_SESSION_get_ex_data); +LSSL_USED(SSL_SESSION_get_ex_new_index); +LSSL_USED(SSL_CTX_set_ex_data); +LSSL_USED(SSL_CTX_get_ex_data); +LSSL_USED(SSL_CTX_get_ex_new_index); +LSSL_USED(SSL_get_ex_data_X509_STORE_CTX_idx); +LSSL_USED(SSL_CTX_set_tmp_rsa_callback); +LSSL_USED(SSL_set_tmp_rsa_callback); +LSSL_USED(SSL_CTX_set_tmp_dh_callback); +LSSL_USED(SSL_set_tmp_dh_callback); +LSSL_USED(SSL_CTX_set_tmp_ecdh_callback); +LSSL_USED(SSL_set_tmp_ecdh_callback); +LSSL_USED(SSL_get_client_random); +LSSL_USED(SSL_get_server_random); +LSSL_USED(SSL_get_current_compression); +LSSL_USED(SSL_get_current_expansion); +LSSL_USED(SSL_get_peer_certificate); +LSSL_USED(SSL_COMP_get_name); +LSSL_USED(SSL_COMP_get_compression_methods); +LSSL_USED(SSL_COMP_add_compression_method); +LSSL_USED(SSL_set_session_ticket_ext); +LSSL_USED(SSL_set_session_ticket_ext_cb); +LSSL_USED(SSL_set_session_secret_cb); +LSSL_USED(SSL_set_debug); +LSSL_USED(SSL_cache_hit); +LSSL_USED(SSL_set_security_level); +LSSL_USED(SSL_get_security_level); +LSSL_USED(SSL_CTX_set_security_level); +LSSL_USED(SSL_CTX_get_security_level); +LSSL_USED(SSL_CTX_set_quic_method); +LSSL_USED(SSL_CTX_sess_get_get_cb); +LSSL_USED(SSL_set_quic_method); +LSSL_USED(SSL_is_quic); +LSSL_USED(SSL_quic_max_handshake_flight_len); +LSSL_USED(SSL_quic_read_level); +LSSL_USED(SSL_quic_write_level); +LSSL_USED(SSL_provide_quic_data); +LSSL_USED(SSL_process_quic_post_handshake); +LSSL_USED(SSL_set_quic_transport_params); +LSSL_USED(SSL_get_peer_quic_transport_params); +LSSL_USED(SSL_set_quic_use_legacy_codepoint); +LSSL_USED(ERR_load_SSL_strings); +LSSL_USED(OPENSSL_init_ssl); + +#endif /* _LIBSSL_SSL_H */ diff --git a/Libraries/libressl/ssl/hidden/openssl/tls1.h b/Libraries/libressl/ssl/hidden/openssl/tls1.h new file mode 100644 index 000000000..de93f9aa2 --- /dev/null +++ b/Libraries/libressl/ssl/hidden/openssl/tls1.h @@ -0,0 +1,32 @@ +/* $OpenBSD: tls1.h,v 1.1 2023/07/08 16:40:14 beck Exp $ */ +/* + * Copyright (c) 2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBSSL_TLS1_H +#define _LIBSSL_TLS1_H + +#ifndef _MSC_VER +#include_next +#else +#include "../include/openssl/tls1.h" +#endif +#include "ssl_namespace.h" + +LSSL_USED(SSL_get_servername); +LSSL_USED(SSL_get_servername_type); +LSSL_USED(SSL_export_keying_material); + +#endif /* _LIBSSL_TLS1_H */ diff --git a/Libraries/libressl/ssl/hidden/ssl_namespace.h b/Libraries/libressl/ssl/hidden/ssl_namespace.h new file mode 100644 index 000000000..b79f7ccd3 --- /dev/null +++ b/Libraries/libressl/ssl/hidden/ssl_namespace.h @@ -0,0 +1,43 @@ +/* $OpenBSD: ssl_namespace.h,v 1.2 2023/02/16 08:38:17 tb Exp $ */ +/* + * Copyright (c) 2016 Philip Guenther + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBSSL_SSL_NAMESPACE_H_ +#define _LIBSSL_SSL_NAMESPACE_H_ + +/* + * If marked as 'used', then internal calls use the name with prefix "_lssl_" + * and we alias that to the normal name. + */ + +#ifdef _MSC_VER +#define LSSL_UNUSED(x) +#define LSSL_USED(x) +#define LSSL_ALIAS(x) +#else +#ifdef LIBRESSL_NAMESPACE +#define LSSL_UNUSED(x) typeof(x) x __attribute__((deprecated)) +#define LSSL_USED(x) __attribute__((visibility("hidden"))) \ + typeof(x) x asm("_lssl_"#x) +#define LSSL_ALIAS(x) asm(".global "#x"; "#x" = _lssl_"#x) +#else +#define LSSL_UNUSED(x) +#define LSSL_USED(x) +#define LSSL_ALIAS(x) asm("") +#endif +#endif /* _MSC_VER */ + +#endif /* _LIBSSL_SSL_NAMESPACE_H_ */ diff --git a/Libraries/libressl/ssl/pqueue.c b/Libraries/libressl/ssl/pqueue.c new file mode 100644 index 000000000..602969deb --- /dev/null +++ b/Libraries/libressl/ssl/pqueue.c @@ -0,0 +1,201 @@ +/* $OpenBSD: pqueue.c,v 1.5 2014/06/12 15:49:31 deraadt Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pqueue.h" + +typedef struct _pqueue { + pitem *items; + int count; +} pqueue_s; + +pitem * +pitem_new(unsigned char *prio64be, void *data) +{ + pitem *item = malloc(sizeof(pitem)); + + if (item == NULL) + return NULL; + + memcpy(item->priority, prio64be, sizeof(item->priority)); + + item->data = data; + item->next = NULL; + + return item; +} + +void +pitem_free(pitem *item) +{ + free(item); +} + +pqueue_s * +pqueue_new(void) +{ + return calloc(1, sizeof(pqueue_s)); +} + +void +pqueue_free(pqueue_s *pq) +{ + free(pq); +} + +pitem * +pqueue_insert(pqueue_s *pq, pitem *item) +{ + pitem *curr, *next; + + if (pq->items == NULL) { + pq->items = item; + return item; + } + + for (curr = NULL, next = pq->items; next != NULL; + curr = next, next = next->next) { + /* we can compare 64-bit value in big-endian encoding + * with memcmp:-) */ + int cmp = memcmp(next->priority, item->priority, + sizeof(item->priority)); + if (cmp > 0) { /* next > item */ + item->next = next; + + if (curr == NULL) + pq->items = item; + else + curr->next = item; + + return item; + } else if (cmp == 0) /* duplicates not allowed */ + return NULL; + } + + item->next = NULL; + curr->next = item; + + return item; +} + +pitem * +pqueue_peek(pqueue_s *pq) +{ + return pq->items; +} + +pitem * +pqueue_pop(pqueue_s *pq) +{ + pitem *item = pq->items; + + if (pq->items != NULL) + pq->items = pq->items->next; + + return item; +} + +pitem * +pqueue_find(pqueue_s *pq, unsigned char *prio64be) +{ + pitem *next; + + for (next = pq->items; next != NULL; next = next->next) + if (memcmp(next->priority, prio64be, + sizeof(next->priority)) == 0) + return next; + + return NULL; +} + +pitem * +pqueue_iterator(pqueue_s *pq) +{ + return pqueue_peek(pq); +} + +pitem * +pqueue_next(pitem **item) +{ + pitem *ret; + + if (item == NULL || *item == NULL) + return NULL; + + /* *item != NULL */ + ret = *item; + *item = (*item)->next; + + return ret; +} + +int +pqueue_size(pqueue_s *pq) +{ + pitem *item = pq->items; + int count = 0; + + while (item != NULL) { + count++; + item = item->next; + } + return count; +} diff --git a/Libraries/libressl/ssl/s3_cbc.c b/Libraries/libressl/ssl/s3_cbc.c new file mode 100644 index 000000000..32b746087 --- /dev/null +++ b/Libraries/libressl/ssl/s3_cbc.c @@ -0,0 +1,628 @@ +/* $OpenBSD: s3_cbc.c,v 1.26 2022/11/26 16:08:55 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "ssl_local.h" + +/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length + * field. (SHA-384/512 have 128-bit length.) */ +#define MAX_HASH_BIT_COUNT_BYTES 16 + +/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. + * Currently SHA-384/512 has a 128-byte block size and that's the largest + * supported by TLS.) */ +#define MAX_HASH_BLOCK_SIZE 128 + +/* Some utility functions are needed: + * + * These macros return the given value with the MSB copied to all the other + * bits. They use the fact that arithmetic shift shifts-in the sign bit. + * However, this is not ensured by the C standard so you may need to replace + * them with something else on odd CPUs. */ +#define DUPLICATE_MSB_TO_ALL(x) ((unsigned int)((int)(x) >> (sizeof(int) * 8 - 1))) +#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x))) + +/* constant_time_lt returns 0xff if a=b and 0x00 otherwise. */ +static unsigned int +constant_time_ge(unsigned int a, unsigned int b) +{ + a -= b; + return DUPLICATE_MSB_TO_ALL(~a); +} + +/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */ +static unsigned char +constant_time_eq_8(unsigned int a, unsigned int b) +{ + unsigned int c = a ^ b; + c--; + return DUPLICATE_MSB_TO_ALL_8(c); +} + +/* ssl3_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC + * record in |rec| in constant time and returns 1 if the padding is valid and + * -1 otherwise. It also removes any explicit IV from the start of the record + * without leaking any timing about whether there was enough space after the + * padding was removed. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. */ +int +ssl3_cbc_remove_padding(SSL3_RECORD_INTERNAL *rec, unsigned int eiv_len, + unsigned int mac_size) +{ + unsigned int padding_length, good, to_check, i; + const unsigned int overhead = 1 /* padding length byte */ + mac_size; + + /* + * These lengths are all public so we can test them in + * non-constant time. + */ + if (overhead + eiv_len > rec->length) + return 0; + + /* We can now safely skip explicit IV, if any. */ + rec->data += eiv_len; + rec->input += eiv_len; + rec->length -= eiv_len; + + padding_length = rec->data[rec->length - 1]; + + good = constant_time_ge(rec->length, overhead + padding_length); + /* The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the + * length byte. Thus, with the length byte included, there are i+1 + * bytes of padding. + * + * We can't check just |padding_length+1| bytes because that leaks + * decrypted information. Therefore we always have to check the maximum + * amount of padding possible. (Again, the length of the record is + * public information so we can use it.) */ + to_check = 256; /* maximum amount of padding, inc length byte. */ + if (to_check > rec->length) + to_check = rec->length; + + for (i = 0; i < to_check; i++) { + unsigned char mask = constant_time_ge(padding_length, i); + unsigned char b = rec->data[rec->length - 1 - i]; + /* The final |padding_length+1| bytes should all have the value + * |padding_length|. Therefore the XOR should be zero. */ + good &= ~(mask&(padding_length ^ b)); + } + + /* If any of the final |padding_length+1| bytes had the wrong value, + * one or more of the lower eight bits of |good| will be cleared. We + * AND the bottom 8 bits together and duplicate the result to all the + * bits. */ + good &= good >> 4; + good &= good >> 2; + good &= good >> 1; + good <<= sizeof(good)*8 - 1; + good = DUPLICATE_MSB_TO_ALL(good); + + padding_length = good & (padding_length + 1); + rec->length -= padding_length; + rec->padding_length = padding_length; + + return (int)((good & 1) | (~good & -1)); +} + +/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in + * constant time (independent of the concrete value of rec->length, which may + * vary within a 256-byte window). + * + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to + * this function. + * + * On entry: + * rec->orig_len >= md_size + * md_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single or pair of cache-lines, then the variable memory accesses don't + * actually affect the timing. CPUs with smaller cache-lines [if any] are + * not multi-core and are not considered vulnerable to cache-timing attacks. + */ +#define CBC_MAC_ROTATE_IN_PLACE + +void +ssl3_cbc_copy_mac(unsigned char* out, const SSL3_RECORD_INTERNAL *rec, + unsigned int md_size, unsigned int orig_len) +{ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + + /* mac_end is the index of |rec->data| just after the end of the MAC. */ + unsigned int mac_end = rec->length; + unsigned int mac_start = mac_end - md_size; + /* scan_start contains the number of bytes that we can ignore because + * the MAC's position can only vary by 255 bytes. */ + unsigned int scan_start = 0; + unsigned int i, j; + unsigned int div_spoiler; + unsigned int rotate_offset; + + OPENSSL_assert(orig_len >= md_size); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf)&63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (orig_len > md_size + 255 + 1) + scan_start = orig_len - (md_size + 255 + 1); + /* div_spoiler contains a multiple of md_size that is used to cause the + * modulo operation to be constant time. Without this, the time varies + * based on the amount of padding when running on Intel chips at least. + * + * The aim of right-shifting md_size is so that the compiler doesn't + * figure out that it can remove div_spoiler as that would require it + * to prove that md_size is always even, which I hope is beyond it. */ + div_spoiler = md_size >> 1; + div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; + rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + + memset(rotated_mac, 0, md_size); + for (i = scan_start, j = 0; i < orig_len; i++) { + unsigned char mac_started = constant_time_ge(i, mac_start); + unsigned char mac_ended = constant_time_ge(i, mac_end); + unsigned char b = rec->data[i]; + rotated_mac[j++] |= b & mac_started & ~mac_ended; + j &= constant_time_lt(j, md_size); + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) { + /* in case cache-line is 32 bytes, touch second line */ + ((volatile unsigned char *)rotated_mac)[rotate_offset^32]; + out[j++] = rotated_mac[rotate_offset++]; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#else + memset(out, 0, md_size); + rotate_offset = md_size - rotate_offset; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + for (i = 0; i < md_size; i++) { + for (j = 0; j < md_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); + rotate_offset++; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#endif +} + +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in + * little-endian order. The value of p is advanced by four. */ +#define u32toLE(n, p) \ + (*((p)++)=(unsigned char)(n), \ + *((p)++)=(unsigned char)(n>>8), \ + *((p)++)=(unsigned char)(n>>16), \ + *((p)++)=(unsigned char)(n>>24)) + +/* These functions serialize the state of a hash and thus perform the standard + * "final" operation without adding the padding and length that such a function + * typically does. */ +static void +tls1_md5_final_raw(void* ctx, unsigned char *md_out) +{ + MD5_CTX *md5 = ctx; + u32toLE(md5->A, md_out); + u32toLE(md5->B, md_out); + u32toLE(md5->C, md_out); + u32toLE(md5->D, md_out); +} + +static void +tls1_sha1_final_raw(void* ctx, unsigned char *md_out) +{ + SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); + l2n(sha1->h1, md_out); + l2n(sha1->h2, md_out); + l2n(sha1->h3, md_out); + l2n(sha1->h4, md_out); +} + +static void +tls1_sha256_final_raw(void* ctx, unsigned char *md_out) +{ + SHA256_CTX *sha256 = ctx; + unsigned int i; + + for (i = 0; i < 8; i++) { + l2n(sha256->h[i], md_out); + } +} + +static void +tls1_sha512_final_raw(void* ctx, unsigned char *md_out) +{ + SHA512_CTX *sha512 = ctx; + unsigned int i; + + for (i = 0; i < 8; i++) { + l2n8(sha512->h[i], md_out); + } +} + +/* Largest hash context ever used by the functions above. */ +#define LARGEST_DIGEST_CTX SHA512_CTX + +/* Type giving the alignment needed by the above */ +#define LARGEST_DIGEST_CTX_ALIGNMENT SHA_LONG64 + +/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. */ +char +ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + return 1; + default: + return 0; + } +} + +/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded TLS + * record. + * + * ctx: the EVP_MD_CTX from which we take the hash function. + * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. + * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. + * md_out_size: if non-NULL, the number of output bytes is written here. + * header: the 13-byte, TLS record header. + * data: the record data itself, less any preceeding explicit IV. + * data_plus_mac_size: the secret, reported length of the data and MAC + * once the padding has been removed. + * data_plus_mac_plus_padding_size: the public length of the whole + * record, including padding. + * + * On entry: by virtue of having been through one of the remove_padding + * functions, above, we know that data_plus_mac_size is large enough to contain + * a padding byte and MAC. (If the padding was invalid, it might contain the + * padding too. ) + */ +int +ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out, + size_t* md_out_size, const unsigned char header[13], + const unsigned char *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, + unsigned int mac_secret_length) +{ + union { + /* + * Alignment here is to allow this to be cast as SHA512_CTX + * without losing alignment required by the 64-bit SHA_LONG64 + * integer it contains. + */ + LARGEST_DIGEST_CTX_ALIGNMENT align; + unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; + } md_state; + void (*md_final_raw)(void *ctx, unsigned char *md_out); + void (*md_transform)(void *ctx, const unsigned char *block); + unsigned int md_size, md_block_size = 64; + unsigned int header_length, variance_blocks, + len, max_mac_bytes, num_blocks, + num_starting_blocks, k, mac_end_offset, c, index_a, index_b; + unsigned int bits; /* at most 18 bits */ + unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + /* hmac_pad is the masked HMAC key. */ + unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; + unsigned char first_block[MAX_HASH_BLOCK_SIZE]; + unsigned char mac_out[EVP_MAX_MD_SIZE]; + unsigned int i, j, md_out_size_u; + EVP_MD_CTX *md_ctx; + /* mdLengthSize is the number of bytes in the length field that terminates + * the hash. */ + unsigned int md_length_size = 8; + char length_is_big_endian = 1; + + /* This is a, hopefully redundant, check that allows us to forget about + * many possible overflows later in this function. */ + OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024); + + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + MD5_Init((MD5_CTX*)md_state.c); + md_final_raw = tls1_md5_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; + md_size = 16; + length_is_big_endian = 0; + break; + case NID_sha1: + SHA1_Init((SHA_CTX*)md_state.c); + md_final_raw = tls1_sha1_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; + md_size = 20; + break; + case NID_sha224: + SHA224_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 224/8; + break; + case NID_sha256: + SHA256_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 32; + break; + case NID_sha384: + SHA384_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 384/8; + md_block_size = 128; + md_length_size = 16; + break; + case NID_sha512: + SHA512_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 64; + md_block_size = 128; + md_length_size = 16; + break; + default: + /* ssl3_cbc_record_digest_supported should have been + * called first to check that the hash function is + * supported. */ + OPENSSL_assert(0); + if (md_out_size) + *md_out_size = 0; + return 0; + } + + OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + + header_length = 13; + + /* variance_blocks is the number of blocks of the hash that we have to + * calculate in constant time because they could be altered by the + * padding value. + * + * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not + * required to be minimal. Therefore we say that the final six blocks + * can vary based on the padding. + * + * Later in the function, if the message is short and there obviously + * cannot be this many blocks then variance_blocks can be reduced. */ + variance_blocks = 6; + /* From now on we're dealing with the MAC, which conceptually has 13 + * bytes of `header' before the start of the data (TLS) */ + len = data_plus_mac_plus_padding_size + header_length; + /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including + * |header|, assuming that there's no padding. */ + max_mac_bytes = len - md_size - 1; + /* num_blocks is the maximum number of hash blocks. */ + num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; + /* In order to calculate the MAC in constant time we have to handle + * the final blocks specially because the padding value could cause the + * end to appear somewhere in the final |variance_blocks| blocks and we + * can't leak where. However, |num_starting_blocks| worth of data can + * be hashed right away because no padding value can affect whether + * they are plaintext. */ + num_starting_blocks = 0; + /* k is the starting byte offset into the conceptual header||data where + * we start processing. */ + k = 0; + /* mac_end_offset is the index just past the end of the data to be + * MACed. */ + mac_end_offset = data_plus_mac_size + header_length - md_size; + /* c is the index of the 0x80 byte in the final hash block that + * contains application data. */ + c = mac_end_offset % md_block_size; + /* index_a is the hash block number that contains the 0x80 terminating + * value. */ + index_a = mac_end_offset / md_block_size; + /* index_b is the hash block number that contains the 64-bit hash + * length, in bits. */ + index_b = (mac_end_offset + md_length_size) / md_block_size; + /* bits is the hash-length in bits. It includes the additional hash + * block for the masked HMAC key. */ + + if (num_blocks > variance_blocks) { + num_starting_blocks = num_blocks - variance_blocks; + k = md_block_size*num_starting_blocks; + } + + bits = 8*mac_end_offset; + /* Compute the initial HMAC block. */ + bits += 8*md_block_size; + memset(hmac_pad, 0, md_block_size); + OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x36; + + md_transform(md_state.c, hmac_pad); + + if (length_is_big_endian) { + memset(length_bytes, 0, md_length_size - 4); + length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 1] = (unsigned char)bits; + } else { + memset(length_bytes, 0, md_length_size); + length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 8] = (unsigned char)bits; + } + + if (k > 0) { + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block + 13, data, md_block_size - 13); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size; i++) + md_transform(md_state.c, data + md_block_size*i - 13); + } + + memset(mac_out, 0, sizeof(mac_out)); + + /* We now process the final hash blocks. For each block, we construct + * it in constant time. If the |i==index_a| then we'll include the 0x80 + * bytes and zero pad etc. For each block we selectively copy it, in + * constant time, to |mac_out|. */ + for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; i++) { + unsigned char block[MAX_HASH_BLOCK_SIZE]; + unsigned char is_block_a = constant_time_eq_8(i, index_a); + unsigned char is_block_b = constant_time_eq_8(i, index_b); + for (j = 0; j < md_block_size; j++) { + unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) + b = header[k]; + else if (k < data_plus_mac_plus_padding_size + header_length) + b = data[k - header_length]; + k++; + + is_past_c = is_block_a & constant_time_ge(j, c); + is_past_cp1 = is_block_a & constant_time_ge(j, c + 1); + /* If this is the block containing the end of the + * application data, and we are at the offset for the + * 0x80 value, then overwrite b with 0x80. */ + b = (b&~is_past_c) | (0x80&is_past_c); + /* If this is the block containing the end of the + * application data and we're past the 0x80 value then + * just write zero. */ + b = b&~is_past_cp1; + /* If this is index_b (the final block), but not + * index_a (the end of the data), then the 64-bit + * length didn't fit into index_a and we're having to + * add an extra block of zeros. */ + b &= ~is_block_b | is_block_a; + + /* The final bytes of one of the blocks contains the + * length. */ + if (j >= md_block_size - md_length_size) { + /* If this is index_b, write a length byte. */ + b = (b&~is_block_b) | (is_block_b&length_bytes[j - (md_block_size - md_length_size)]); + } + block[j] = b; + } + + md_transform(md_state.c, block); + md_final_raw(md_state.c, block); + /* If this is index_b, copy the hash value to |mac_out|. */ + for (j = 0; j < md_size; j++) + mac_out[j] |= block[j]&is_block_b; + } + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + return 0; + if (!EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */)) { + EVP_MD_CTX_free(md_ctx); + return 0; + } + + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x6a; + + EVP_DigestUpdate(md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(md_ctx, mac_out, md_size); + + EVP_DigestFinal(md_ctx, md_out, &md_out_size_u); + if (md_out_size) + *md_out_size = md_out_size_u; + EVP_MD_CTX_free(md_ctx); + + return 1; +} diff --git a/Libraries/libressl/ssl/s3_lib.c b/Libraries/libressl/ssl/s3_lib.c new file mode 100644 index 000000000..7ab688013 --- /dev/null +++ b/Libraries/libressl/ssl/s3_lib.c @@ -0,0 +1,2827 @@ +/* $OpenBSD: s3_lib.c,v 1.246 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" +#include "tls_content.h" + +#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers) / sizeof(SSL_CIPHER)) + +/* + * FIXED_NONCE_LEN is a macro that provides in the correct value to set the + * fixed nonce length in algorithms2. It is the inverse of the + * SSL_CIPHER_AEAD_FIXED_NONCE_LEN macro. + */ +#define FIXED_NONCE_LEN(x) (((x / 2) & 0xf) << 24) + +/* list of available SSLv3 ciphers (sorted by id) */ +const SSL_CIPHER ssl3_ciphers[] = { + + /* The RSA ciphers */ + /* Cipher 01 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_NULL_MD5, + .id = SSL3_CK_RSA_NULL_MD5, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_MD5, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher 02 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_NULL_SHA, + .id = SSL3_CK_RSA_NULL_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher 04 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_RC4_128_MD5, + .id = SSL3_CK_RSA_RC4_128_MD5, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_MD5, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 05 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_RC4_128_SHA, + .id = SSL3_CK_RSA_RC4_128_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 0A */ + { + .valid = 1, + .name = SSL3_TXT_RSA_DES_192_CBC3_SHA, + .id = SSL3_CK_RSA_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* + * Ephemeral DH (DHE) ciphers. + */ + + /* Cipher 16 */ + { + .valid = 1, + .name = SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, + .id = SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher 18 */ + { + .valid = 1, + .name = SSL3_TXT_ADH_RC4_128_MD5, + .id = SSL3_CK_ADH_RC4_128_MD5, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_MD5, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 1B */ + { + .valid = 1, + .name = SSL3_TXT_ADH_DES_192_CBC_SHA, + .id = SSL3_CK_ADH_DES_192_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* + * AES ciphersuites. + */ + + /* Cipher 2F */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_128_SHA, + .id = TLS1_CK_RSA_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 33 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, + .id = TLS1_CK_DHE_RSA_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 34 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_128_SHA, + .id = TLS1_CK_ADH_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 35 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_256_SHA, + .id = TLS1_CK_RSA_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 39 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, + .id = TLS1_CK_DHE_RSA_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 3A */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_256_SHA, + .id = TLS1_CK_ADH_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* TLS v1.2 ciphersuites */ + /* Cipher 3B */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_NULL_SHA256, + .id = TLS1_CK_RSA_WITH_NULL_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher 3C */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 3D */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_256_SHA256, + .id = TLS1_CK_RSA_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (128-bit portion) */ + + /* Cipher 41 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 45 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 46 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + + /* TLS v1.2 ciphersuites */ + /* Cipher 67 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 6B */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 6C */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_128_SHA256, + .id = TLS1_CK_ADH_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 6D */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_256_SHA256, + .id = TLS1_CK_ADH_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* GOST Ciphersuites */ + + /* Cipher 81 */ + { + .valid = 1, + .name = "GOST2001-GOST89-GOST89", + .id = 0x3000081, + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eGOST2814789CNT, + .algorithm_mac = SSL_GOST89MAC, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94| + TLS1_STREAM_MAC, + .strength_bits = 256, + .alg_bits = 256 + }, + + /* Cipher 83 */ + { + .valid = 1, + .name = "GOST2001-NULL-GOST94", + .id = 0x3000083, + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_GOST94, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94, + .strength_bits = 0, + .alg_bits = 0 + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (256-bit portion) */ + + /* Cipher 84 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 88 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 89 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + + /* + * GCM ciphersuites from RFC5288. + */ + + /* Cipher 9C */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 9D */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 9E */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 9F */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher A6 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher A7 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ + + /* Cipher BA */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher BE */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher BF */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C0 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C4 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C5 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + + /* + * TLSv1.3 cipher suites. + */ + +#ifdef LIBRESSL_HAS_TLS1_3 + /* Cipher 1301 */ + { + .valid = 1, + .name = TLS1_3_RFC_AES_128_GCM_SHA256, + .id = TLS1_3_CK_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kTLS1_3, + .algorithm_auth = SSL_aTLS1_3, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256, /* XXX */ + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 1302 */ + { + .valid = 1, + .name = TLS1_3_RFC_AES_256_GCM_SHA384, + .id = TLS1_3_CK_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kTLS1_3, + .algorithm_auth = SSL_aTLS1_3, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384, /* XXX */ + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 1303 */ + { + .valid = 1, + .name = TLS1_3_RFC_CHACHA20_POLY1305_SHA256, + .id = TLS1_3_CK_CHACHA20_POLY1305_SHA256, + .algorithm_mkey = SSL_kTLS1_3, + .algorithm_auth = SSL_aTLS1_3, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256, /* XXX */ + .strength_bits = 256, + .alg_bits = 256, + }, +#endif + + /* Cipher C006 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C007 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C008 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C009 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C00A */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C010 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C011 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C012 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C013 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C014 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C015 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_NULL_SHA, + .id = TLS1_CK_ECDH_anon_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C016 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C017 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C018 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C019 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + + /* HMAC based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C023 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C024 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA384, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C027 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C028 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA384, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* GCM based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C02B */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C02C */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C02F */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C030 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CCA8 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305, + .id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(12), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CCA9 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + .id = TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(12), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CCAA */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305, + .id = TLS1_CK_DHE_RSA_CHACHA20_POLY1305, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + FIXED_NONCE_LEN(12), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher FF85 FIXME IANA */ + { + .valid = 1, + .name = "GOST2012256-GOST89-GOST89", + .id = 0x300ff85, /* FIXME IANA */ + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eGOST2814789CNT, + .algorithm_mac = SSL_GOST89MAC, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256| + TLS1_STREAM_MAC, + .strength_bits = 256, + .alg_bits = 256 + }, + + /* Cipher FF87 FIXME IANA */ + { + .valid = 1, + .name = "GOST2012256-NULL-STREEBOG256", + .id = 0x300ff87, /* FIXME IANA */ + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_STREEBOG256, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256, + .strength_bits = 0, + .alg_bits = 0 + }, + + + /* end of list */ +}; + +int +ssl3_num_ciphers(void) +{ + return (SSL3_NUM_CIPHERS); +} + +const SSL_CIPHER * +ssl3_get_cipher(unsigned int u) +{ + if (u < SSL3_NUM_CIPHERS) + return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u])); + else + return (NULL); +} + +const SSL_CIPHER * +ssl3_get_cipher_by_id(unsigned int id) +{ + const SSL_CIPHER *cp; + SSL_CIPHER c; + + c.id = id; + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); + if (cp != NULL && cp->valid == 1) + return (cp); + + return (NULL); +} + +const SSL_CIPHER * +ssl3_get_cipher_by_value(uint16_t value) +{ + return ssl3_get_cipher_by_id(SSL3_CK_ID | value); +} + +uint16_t +ssl3_cipher_get_value(const SSL_CIPHER *c) +{ + return (c->id & SSL3_CK_VALUE_MASK); +} + +int +ssl3_pending(const SSL *s) +{ + if (s->s3->rcontent == NULL) + return 0; + if (tls_content_type(s->s3->rcontent) != SSL3_RT_APPLICATION_DATA) + return 0; + + return tls_content_remaining(s->s3->rcontent); +} + +int +ssl3_handshake_msg_hdr_len(SSL *s) +{ + return (SSL_is_dtls(s) ? DTLS1_HM_HEADER_LENGTH : + SSL3_HM_HEADER_LENGTH); +} + +int +ssl3_handshake_msg_start(SSL *s, CBB *handshake, CBB *body, uint8_t msg_type) +{ + int ret = 0; + + if (!CBB_init(handshake, SSL3_RT_MAX_PLAIN_LENGTH)) + goto err; + if (!CBB_add_u8(handshake, msg_type)) + goto err; + if (SSL_is_dtls(s)) { + unsigned char *data; + + if (!CBB_add_space(handshake, &data, DTLS1_HM_HEADER_LENGTH - + SSL3_HM_HEADER_LENGTH)) + goto err; + } + if (!CBB_add_u24_length_prefixed(handshake, body)) + goto err; + + ret = 1; + + err: + return (ret); +} + +int +ssl3_handshake_msg_finish(SSL *s, CBB *handshake) +{ + unsigned char *data = NULL; + size_t outlen; + int ret = 0; + + if (!CBB_finish(handshake, &data, &outlen)) + goto err; + + if (outlen > INT_MAX) + goto err; + + if (!BUF_MEM_grow_clean(s->init_buf, outlen)) + goto err; + + memcpy(s->init_buf->data, data, outlen); + + s->init_num = (int)outlen; + s->init_off = 0; + + if (SSL_is_dtls(s)) { + unsigned long len; + uint8_t msg_type; + CBS cbs; + + CBS_init(&cbs, data, outlen); + if (!CBS_get_u8(&cbs, &msg_type)) + goto err; + + len = outlen - ssl3_handshake_msg_hdr_len(s); + + dtls1_set_message_header(s, msg_type, len, 0, len); + dtls1_buffer_message(s, 0); + } + + ret = 1; + + err: + free(data); + + return (ret); +} + +int +ssl3_handshake_write(SSL *s) +{ + return ssl3_record_write(s, SSL3_RT_HANDSHAKE); +} + +int +ssl3_record_write(SSL *s, int type) +{ + if (SSL_is_dtls(s)) + return dtls1_do_write(s, type); + + return ssl3_do_write(s, type); +} + +int +ssl3_new(SSL *s) +{ + if ((s->s3 = calloc(1, sizeof(*s->s3))) == NULL) + return (0); + + s->method->ssl_clear(s); + + return (1); +} + +void +ssl3_free(SSL *s) +{ + if (s == NULL) + return; + + tls1_cleanup_key_block(s); + ssl3_release_read_buffer(s); + ssl3_release_write_buffer(s); + + tls_content_free(s->s3->rcontent); + + tls_buffer_free(s->s3->alert_fragment); + tls_buffer_free(s->s3->handshake_fragment); + + freezero(s->s3->hs.sigalgs, s->s3->hs.sigalgs_len); + sk_X509_pop_free(s->s3->hs.peer_certs, X509_free); + sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); + sk_X509_pop_free(s->s3->hs.verified_chain, X509_free); + tls_key_share_free(s->s3->hs.key_share); + + tls13_secrets_destroy(s->s3->hs.tls13.secrets); + freezero(s->s3->hs.tls13.cookie, s->s3->hs.tls13.cookie_len); + tls13_clienthello_hash_clear(&s->s3->hs.tls13); + + tls_buffer_free(s->s3->hs.tls13.quic_read_buffer); + + sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free); + + tls1_transcript_free(s); + tls1_transcript_hash_free(s); + + free(s->s3->alpn_selected); + + freezero(s->s3->peer_quic_transport_params, + s->s3->peer_quic_transport_params_len); + + freezero(s->s3, sizeof(*s->s3)); + + s->s3 = NULL; +} + +void +ssl3_clear(SSL *s) +{ + unsigned char *rp, *wp; + size_t rlen, wlen; + + tls1_cleanup_key_block(s); + sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free); + + tls_buffer_free(s->s3->alert_fragment); + s->s3->alert_fragment = NULL; + tls_buffer_free(s->s3->handshake_fragment); + s->s3->handshake_fragment = NULL; + + freezero(s->s3->hs.sigalgs, s->s3->hs.sigalgs_len); + s->s3->hs.sigalgs = NULL; + s->s3->hs.sigalgs_len = 0; + + sk_X509_pop_free(s->s3->hs.peer_certs, X509_free); + s->s3->hs.peer_certs = NULL; + sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); + s->s3->hs.peer_certs_no_leaf = NULL; + sk_X509_pop_free(s->s3->hs.verified_chain, X509_free); + s->s3->hs.verified_chain = NULL; + + tls_key_share_free(s->s3->hs.key_share); + s->s3->hs.key_share = NULL; + + tls13_secrets_destroy(s->s3->hs.tls13.secrets); + s->s3->hs.tls13.secrets = NULL; + freezero(s->s3->hs.tls13.cookie, s->s3->hs.tls13.cookie_len); + s->s3->hs.tls13.cookie = NULL; + s->s3->hs.tls13.cookie_len = 0; + tls13_clienthello_hash_clear(&s->s3->hs.tls13); + + tls_buffer_free(s->s3->hs.tls13.quic_read_buffer); + s->s3->hs.tls13.quic_read_buffer = NULL; + s->s3->hs.tls13.quic_read_level = ssl_encryption_initial; + s->s3->hs.tls13.quic_write_level = ssl_encryption_initial; + + s->s3->hs.extensions_seen = 0; + + rp = s->s3->rbuf.buf; + wp = s->s3->wbuf.buf; + rlen = s->s3->rbuf.len; + wlen = s->s3->wbuf.len; + + tls_content_free(s->s3->rcontent); + s->s3->rcontent = NULL; + + tls1_transcript_free(s); + tls1_transcript_hash_free(s); + + free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + s->s3->alpn_selected_len = 0; + + freezero(s->s3->peer_quic_transport_params, + s->s3->peer_quic_transport_params_len); + s->s3->peer_quic_transport_params = NULL; + s->s3->peer_quic_transport_params_len = 0; + + memset(s->s3, 0, sizeof(*s->s3)); + + s->s3->rbuf.buf = rp; + s->s3->wbuf.buf = wp; + s->s3->rbuf.len = rlen; + s->s3->wbuf.len = wlen; + + ssl_free_wbio_buffer(s); + + /* Not needed... */ + s->s3->renegotiate = 0; + s->s3->total_renegotiations = 0; + s->s3->num_renegotiations = 0; + s->s3->in_read_app_data = 0; + + s->packet_length = 0; + s->version = TLS1_2_VERSION; + + s->s3->hs.state = SSL_ST_BEFORE|((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); +} + +long +_SSL_get_shared_group(SSL *s, long n) +{ + size_t count; + int nid; + + /* OpenSSL document that they return -1 for clients. They return 0. */ + if (!s->server) + return 0; + + if (n == -1) { + if (!tls1_count_shared_groups(s, &count)) + return 0; + + if (count > LONG_MAX) + count = LONG_MAX; + + return count; + } + + /* Undocumented special case added for Suite B profile support. */ + if (n == -2) + n = 0; + + if (n < 0) + return 0; + + if (!tls1_get_shared_group_by_index(s, n, &nid)) + return NID_undef; + + return nid; +} + +long +_SSL_get_peer_tmp_key(SSL *s, EVP_PKEY **key) +{ + EVP_PKEY *pkey = NULL; + int ret = 0; + + *key = NULL; + + if (s->s3->hs.key_share == NULL) + goto err; + + if ((pkey = EVP_PKEY_new()) == NULL) + goto err; + if (!tls_key_share_peer_pkey(s->s3->hs.key_share, pkey)) + goto err; + + *key = pkey; + pkey = NULL; + + ret = 1; + + err: + EVP_PKEY_free(pkey); + + return (ret); +} + +static int +_SSL_session_reused(SSL *s) +{ + return s->hit; +} + +static int +_SSL_num_renegotiations(SSL *s) +{ + return s->s3->num_renegotiations; +} + +static int +_SSL_clear_num_renegotiations(SSL *s) +{ + int renegs; + + renegs = s->s3->num_renegotiations; + s->s3->num_renegotiations = 0; + + return renegs; +} + +static int +_SSL_total_renegotiations(SSL *s) +{ + return s->s3->total_renegotiations; +} + +static int +_SSL_set_tmp_dh(SSL *s, DH *dh) +{ + DH *dhe_params; + + if (dh == NULL) { + SSLerror(s, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ssl_security_dh(s, dh)) { + SSLerror(s, SSL_R_DH_KEY_TOO_SMALL); + return 0; + } + + if ((dhe_params = DHparams_dup(dh)) == NULL) { + SSLerror(s, ERR_R_DH_LIB); + return 0; + } + + DH_free(s->cert->dhe_params); + s->cert->dhe_params = dhe_params; + + return 1; +} + +static int +_SSL_set_dh_auto(SSL *s, int state) +{ + s->cert->dhe_params_auto = state; + return 1; +} + +static int +_SSL_set_tmp_ecdh(SSL *s, EC_KEY *ecdh) +{ + const EC_GROUP *group; + int nid; + + if (ecdh == NULL) + return 0; + if ((group = EC_KEY_get0_group(ecdh)) == NULL) + return 0; + + nid = EC_GROUP_get_curve_name(group); + return SSL_set1_groups(s, &nid, 1); +} + +static int +_SSL_set_ecdh_auto(SSL *s, int state) +{ + return 1; +} + +static int +_SSL_set_tlsext_host_name(SSL *s, const char *name) +{ + int is_ip; + CBS cbs; + + free(s->tlsext_hostname); + s->tlsext_hostname = NULL; + + if (name == NULL) + return 1; + + CBS_init(&cbs, name, strlen(name)); + + if (!tlsext_sni_is_valid_hostname(&cbs, &is_ip)) { + SSLerror(s, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + if ((s->tlsext_hostname = strdup(name)) == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +static int +_SSL_set_tlsext_debug_arg(SSL *s, void *arg) +{ + s->tlsext_debug_arg = arg; + return 1; +} + +static int +_SSL_get_tlsext_status_type(SSL *s) +{ + return s->tlsext_status_type; +} + +static int +_SSL_set_tlsext_status_type(SSL *s, int type) +{ + s->tlsext_status_type = type; + return 1; +} + +static int +_SSL_get_tlsext_status_exts(SSL *s, STACK_OF(X509_EXTENSION) **exts) +{ + *exts = s->tlsext_ocsp_exts; + return 1; +} + +static int +_SSL_set_tlsext_status_exts(SSL *s, STACK_OF(X509_EXTENSION) *exts) +{ + /* XXX - leak... */ + s->tlsext_ocsp_exts = exts; + return 1; +} + +static int +_SSL_get_tlsext_status_ids(SSL *s, STACK_OF(OCSP_RESPID) **ids) +{ + *ids = s->tlsext_ocsp_ids; + return 1; +} + +static int +_SSL_set_tlsext_status_ids(SSL *s, STACK_OF(OCSP_RESPID) *ids) +{ + /* XXX - leak... */ + s->tlsext_ocsp_ids = ids; + return 1; +} + +static int +_SSL_get_tlsext_status_ocsp_resp(SSL *s, unsigned char **resp) +{ + if (s->tlsext_ocsp_resp != NULL && + s->tlsext_ocsp_resp_len < INT_MAX) { + *resp = s->tlsext_ocsp_resp; + return (int)s->tlsext_ocsp_resp_len; + } + + *resp = NULL; + + return -1; +} + +static int +_SSL_set_tlsext_status_ocsp_resp(SSL *s, unsigned char *resp, int resp_len) +{ + free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resp_len = 0; + + if (resp_len < 0) + return 0; + + s->tlsext_ocsp_resp = resp; + s->tlsext_ocsp_resp_len = (size_t)resp_len; + + return 1; +} + +int +SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) +{ + return ssl_cert_set0_chain(NULL, ssl, chain); +} +LSSL_ALIAS(SSL_set0_chain); + +int +SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) +{ + return ssl_cert_set1_chain(NULL, ssl, chain); +} +LSSL_ALIAS(SSL_set1_chain); + +int +SSL_add0_chain_cert(SSL *ssl, X509 *x509) +{ + return ssl_cert_add0_chain_cert(NULL, ssl, x509); +} +LSSL_ALIAS(SSL_add0_chain_cert); + +int +SSL_add1_chain_cert(SSL *ssl, X509 *x509) +{ + return ssl_cert_add1_chain_cert(NULL, ssl, x509); +} +LSSL_ALIAS(SSL_add1_chain_cert); + +int +SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) +{ + *out_chain = NULL; + + if (ssl->cert->key != NULL) + *out_chain = ssl->cert->key->chain; + + return 1; +} +LSSL_ALIAS(SSL_get0_chain_certs); + +int +SSL_clear_chain_certs(SSL *ssl) +{ + return ssl_cert_set0_chain(NULL, ssl, NULL); +} +LSSL_ALIAS(SSL_clear_chain_certs); + +int +SSL_set1_groups(SSL *s, const int *groups, size_t groups_len) +{ + return tls1_set_groups(&s->tlsext_supportedgroups, + &s->tlsext_supportedgroups_length, groups, groups_len); +} +LSSL_ALIAS(SSL_set1_groups); + +int +SSL_set1_groups_list(SSL *s, const char *groups) +{ + return tls1_set_group_list(&s->tlsext_supportedgroups, + &s->tlsext_supportedgroups_length, groups); +} +LSSL_ALIAS(SSL_set1_groups_list); + +static int +_SSL_get_signature_nid(SSL *s, int *nid) +{ + const struct ssl_sigalg *sigalg; + + if ((sigalg = s->s3->hs.our_sigalg) == NULL) + return 0; + + *nid = EVP_MD_type(sigalg->md()); + + return 1; +} + +static int +_SSL_get_peer_signature_nid(SSL *s, int *nid) +{ + const struct ssl_sigalg *sigalg; + + if ((sigalg = s->s3->hs.peer_sigalg) == NULL) + return 0; + + *nid = EVP_MD_type(sigalg->md()); + + return 1; +} + +int +SSL_get_signature_type_nid(const SSL *s, int *nid) +{ + const struct ssl_sigalg *sigalg; + + if ((sigalg = s->s3->hs.our_sigalg) == NULL) + return 0; + + *nid = sigalg->key_type; + if (sigalg->key_type == EVP_PKEY_RSA && + (sigalg->flags & SIGALG_FLAG_RSA_PSS)) + *nid = EVP_PKEY_RSA_PSS; + + return 1; +} + +int +SSL_get_peer_signature_type_nid(const SSL *s, int *nid) +{ + const struct ssl_sigalg *sigalg; + + if ((sigalg = s->s3->hs.peer_sigalg) == NULL) + return 0; + + *nid = sigalg->key_type; + if (sigalg->key_type == EVP_PKEY_RSA && + (sigalg->flags & SIGALG_FLAG_RSA_PSS)) + *nid = EVP_PKEY_RSA_PSS; + + return 1; +} + +long +ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + switch (cmd) { + case SSL_CTRL_GET_SESSION_REUSED: + return _SSL_session_reused(s); + + case SSL_CTRL_GET_NUM_RENEGOTIATIONS: + return _SSL_num_renegotiations(s); + + case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: + return _SSL_clear_num_renegotiations(s); + + case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: + return _SSL_total_renegotiations(s); + + case SSL_CTRL_SET_TMP_DH: + return _SSL_set_tmp_dh(s, parg); + + case SSL_CTRL_SET_TMP_DH_CB: + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + + case SSL_CTRL_SET_DH_AUTO: + return _SSL_set_dh_auto(s, larg); + + case SSL_CTRL_SET_TMP_ECDH: + return _SSL_set_tmp_ecdh(s, parg); + + case SSL_CTRL_SET_TMP_ECDH_CB: + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + + case SSL_CTRL_SET_ECDH_AUTO: + return _SSL_set_ecdh_auto(s, larg); + + case SSL_CTRL_SET_TLSEXT_HOSTNAME: + if (larg != TLSEXT_NAMETYPE_host_name) { + SSLerror(s, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); + return 0; + } + return _SSL_set_tlsext_host_name(s, parg); + + case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: + return _SSL_set_tlsext_debug_arg(s, parg); + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE: + return _SSL_get_tlsext_status_type(s); + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: + return _SSL_set_tlsext_status_type(s, larg); + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: + return _SSL_get_tlsext_status_exts(s, parg); + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: + return _SSL_set_tlsext_status_exts(s, parg); + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: + return _SSL_get_tlsext_status_ids(s, parg); + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: + return _SSL_set_tlsext_status_ids(s, parg); + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: + return _SSL_get_tlsext_status_ocsp_resp(s, parg); + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: + return _SSL_set_tlsext_status_ocsp_resp(s, parg, larg); + + case SSL_CTRL_CHAIN: + if (larg == 0) + return SSL_set0_chain(s, (STACK_OF(X509) *)parg); + else + return SSL_set1_chain(s, (STACK_OF(X509) *)parg); + + case SSL_CTRL_CHAIN_CERT: + if (larg == 0) + return SSL_add0_chain_cert(s, (X509 *)parg); + else + return SSL_add1_chain_cert(s, (X509 *)parg); + + case SSL_CTRL_GET_CHAIN_CERTS: + return SSL_get0_chain_certs(s, (STACK_OF(X509) **)parg); + + case SSL_CTRL_SET_GROUPS: + return SSL_set1_groups(s, parg, larg); + + case SSL_CTRL_SET_GROUPS_LIST: + return SSL_set1_groups_list(s, parg); + + case SSL_CTRL_GET_SHARED_GROUP: + return _SSL_get_shared_group(s, larg); + + /* XXX - rename to SSL_CTRL_GET_PEER_TMP_KEY and remove server check. */ + case SSL_CTRL_GET_SERVER_TMP_KEY: + if (s->server != 0) + return 0; + return _SSL_get_peer_tmp_key(s, parg); + + case SSL_CTRL_GET_MIN_PROTO_VERSION: + return SSL_get_min_proto_version(s); + + case SSL_CTRL_GET_MAX_PROTO_VERSION: + return SSL_get_max_proto_version(s); + + case SSL_CTRL_SET_MIN_PROTO_VERSION: + if (larg < 0 || larg > UINT16_MAX) + return 0; + return SSL_set_min_proto_version(s, larg); + + case SSL_CTRL_SET_MAX_PROTO_VERSION: + if (larg < 0 || larg > UINT16_MAX) + return 0; + return SSL_set_max_proto_version(s, larg); + + case SSL_CTRL_GET_SIGNATURE_NID: + return _SSL_get_signature_nid(s, parg); + + case SSL_CTRL_GET_PEER_SIGNATURE_NID: + return _SSL_get_peer_signature_nid(s, parg); + + /* + * Legacy controls that should eventually be removed. + */ + case SSL_CTRL_GET_CLIENT_CERT_REQUEST: + return 0; + + case SSL_CTRL_GET_FLAGS: + return (int)(s->s3->flags); + + case SSL_CTRL_NEED_TMP_RSA: + return 0; + + case SSL_CTRL_SET_TMP_RSA: + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return 0; +} + +long +ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) +{ + switch (cmd) { + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + + case SSL_CTRL_SET_TMP_DH_CB: + s->cert->dhe_params_cb = (DH *(*)(SSL *, int, int))fp; + return 1; + + case SSL_CTRL_SET_TMP_ECDH_CB: + return 1; + + case SSL_CTRL_SET_TLSEXT_DEBUG_CB: + s->tlsext_debug_cb = (void (*)(SSL *, int , int, + unsigned char *, int, void *))fp; + return 1; + } + + return 0; +} + +static int +_SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh) +{ + DH *dhe_params; + + if (dh == NULL) { + SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ssl_ctx_security_dh(ctx, dh)) { + SSLerrorx(SSL_R_DH_KEY_TOO_SMALL); + return 0; + } + + if ((dhe_params = DHparams_dup(dh)) == NULL) { + SSLerrorx(ERR_R_DH_LIB); + return 0; + } + + DH_free(ctx->cert->dhe_params); + ctx->cert->dhe_params = dhe_params; + + return 1; +} + +static int +_SSL_CTX_set_dh_auto(SSL_CTX *ctx, int state) +{ + ctx->cert->dhe_params_auto = state; + return 1; +} + +static int +_SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, EC_KEY *ecdh) +{ + const EC_GROUP *group; + int nid; + + if (ecdh == NULL) + return 0; + if ((group = EC_KEY_get0_group(ecdh)) == NULL) + return 0; + + nid = EC_GROUP_get_curve_name(group); + return SSL_CTX_set1_groups(ctx, &nid, 1); +} + +static int +_SSL_CTX_set_ecdh_auto(SSL_CTX *ctx, int state) +{ + return 1; +} + +static int +_SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg) +{ + ctx->tlsext_servername_arg = arg; + return 1; +} + +static int +_SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, unsigned char *keys, int keys_len) +{ + if (keys == NULL) + return 48; + + if (keys_len != 48) { + SSLerrorx(SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + + memcpy(keys, ctx->tlsext_tick_key_name, 16); + memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16); + memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16); + + return 1; +} + +static int +_SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, unsigned char *keys, int keys_len) +{ + if (keys == NULL) + return 48; + + if (keys_len != 48) { + SSLerrorx(SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + + memcpy(ctx->tlsext_tick_key_name, keys, 16); + memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16); + memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); + + return 1; +} + +static int +_SSL_CTX_get_tlsext_status_arg(SSL_CTX *ctx, void **arg) +{ + *arg = ctx->tlsext_status_arg; + return 1; +} + +static int +_SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg) +{ + ctx->tlsext_status_arg = arg; + return 1; +} + +int +SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) +{ + return ssl_cert_set0_chain(ctx, NULL, chain); +} +LSSL_ALIAS(SSL_CTX_set0_chain); + +int +SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) +{ + return ssl_cert_set1_chain(ctx, NULL, chain); +} +LSSL_ALIAS(SSL_CTX_set1_chain); + +int +SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) +{ + return ssl_cert_add0_chain_cert(ctx, NULL, x509); +} +LSSL_ALIAS(SSL_CTX_add0_chain_cert); + +int +SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) +{ + return ssl_cert_add1_chain_cert(ctx, NULL, x509); +} +LSSL_ALIAS(SSL_CTX_add1_chain_cert); + +int +SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) +{ + *out_chain = NULL; + + if (ctx->cert->key != NULL) + *out_chain = ctx->cert->key->chain; + + return 1; +} +LSSL_ALIAS(SSL_CTX_get0_chain_certs); + +int +SSL_CTX_clear_chain_certs(SSL_CTX *ctx) +{ + return ssl_cert_set0_chain(ctx, NULL, NULL); +} +LSSL_ALIAS(SSL_CTX_clear_chain_certs); + +static int +_SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *cert) +{ + if (ctx->extra_certs == NULL) { + if ((ctx->extra_certs = sk_X509_new_null()) == NULL) + return 0; + } + if (sk_X509_push(ctx->extra_certs, cert) == 0) + return 0; + + return 1; +} + +static int +_SSL_CTX_get_extra_chain_certs(SSL_CTX *ctx, STACK_OF(X509) **certs) +{ + *certs = ctx->extra_certs; + if (*certs == NULL) + *certs = ctx->cert->key->chain; + + return 1; +} + +static int +_SSL_CTX_get_extra_chain_certs_only(SSL_CTX *ctx, STACK_OF(X509) **certs) +{ + *certs = ctx->extra_certs; + return 1; +} + +static int +_SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) +{ + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + return 1; +} + +int +SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, size_t groups_len) +{ + return tls1_set_groups(&ctx->tlsext_supportedgroups, + &ctx->tlsext_supportedgroups_length, groups, groups_len); +} +LSSL_ALIAS(SSL_CTX_set1_groups); + +int +SSL_CTX_set1_groups_list(SSL_CTX *ctx, const char *groups) +{ + return tls1_set_group_list(&ctx->tlsext_supportedgroups, + &ctx->tlsext_supportedgroups_length, groups); +} +LSSL_ALIAS(SSL_CTX_set1_groups_list); + +long +ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + switch (cmd) { + case SSL_CTRL_SET_TMP_DH: + return _SSL_CTX_set_tmp_dh(ctx, parg); + + case SSL_CTRL_SET_TMP_DH_CB: + SSLerrorx(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + + case SSL_CTRL_SET_DH_AUTO: + return _SSL_CTX_set_dh_auto(ctx, larg); + + case SSL_CTRL_SET_TMP_ECDH: + return _SSL_CTX_set_tmp_ecdh(ctx, parg); + + case SSL_CTRL_SET_TMP_ECDH_CB: + SSLerrorx(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + + case SSL_CTRL_SET_ECDH_AUTO: + return _SSL_CTX_set_ecdh_auto(ctx, larg); + + case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: + return _SSL_CTX_set_tlsext_servername_arg(ctx, parg); + + case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: + return _SSL_CTX_get_tlsext_ticket_keys(ctx, parg, larg); + + case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: + return _SSL_CTX_set_tlsext_ticket_keys(ctx, parg, larg); + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG: + return _SSL_CTX_get_tlsext_status_arg(ctx, parg); + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: + return _SSL_CTX_set_tlsext_status_arg(ctx, parg); + + case SSL_CTRL_CHAIN: + if (larg == 0) + return SSL_CTX_set0_chain(ctx, (STACK_OF(X509) *)parg); + else + return SSL_CTX_set1_chain(ctx, (STACK_OF(X509) *)parg); + + case SSL_CTRL_CHAIN_CERT: + if (larg == 0) + return SSL_CTX_add0_chain_cert(ctx, (X509 *)parg); + else + return SSL_CTX_add1_chain_cert(ctx, (X509 *)parg); + + case SSL_CTRL_GET_CHAIN_CERTS: + return SSL_CTX_get0_chain_certs(ctx, (STACK_OF(X509) **)parg); + + case SSL_CTRL_EXTRA_CHAIN_CERT: + return _SSL_CTX_add_extra_chain_cert(ctx, parg); + + case SSL_CTRL_GET_EXTRA_CHAIN_CERTS: + if (larg == 0) + return _SSL_CTX_get_extra_chain_certs(ctx, parg); + else + return _SSL_CTX_get_extra_chain_certs_only(ctx, parg); + + case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: + return _SSL_CTX_clear_extra_chain_certs(ctx); + + case SSL_CTRL_SET_GROUPS: + return SSL_CTX_set1_groups(ctx, parg, larg); + + case SSL_CTRL_SET_GROUPS_LIST: + return SSL_CTX_set1_groups_list(ctx, parg); + + case SSL_CTRL_GET_MIN_PROTO_VERSION: + return SSL_CTX_get_min_proto_version(ctx); + + case SSL_CTRL_GET_MAX_PROTO_VERSION: + return SSL_CTX_get_max_proto_version(ctx); + + case SSL_CTRL_SET_MIN_PROTO_VERSION: + if (larg < 0 || larg > UINT16_MAX) + return 0; + return SSL_CTX_set_min_proto_version(ctx, larg); + + case SSL_CTRL_SET_MAX_PROTO_VERSION: + if (larg < 0 || larg > UINT16_MAX) + return 0; + return SSL_CTX_set_max_proto_version(ctx, larg); + + /* + * Legacy controls that should eventually be removed. + */ + case SSL_CTRL_NEED_TMP_RSA: + return 0; + + case SSL_CTRL_SET_TMP_RSA: + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerrorx(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return 0; +} + +long +ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) +{ + switch (cmd) { + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerrorx(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + + case SSL_CTRL_SET_TMP_DH_CB: + ctx->cert->dhe_params_cb = + (DH *(*)(SSL *, int, int))fp; + return 1; + + case SSL_CTRL_SET_TMP_ECDH_CB: + return 1; + + case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: + ctx->tlsext_servername_callback = + (int (*)(SSL *, int *, void *))fp; + return 1; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB: + *(int (**)(SSL *, void *))fp = ctx->tlsext_status_cb; + return 1; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: + ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp; + return 1; + + case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: + ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *, + unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int))fp; + return 1; + } + + return 0; +} + +SSL_CIPHER * +ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr) +{ + unsigned long alg_k, alg_a, mask_k, mask_a; + STACK_OF(SSL_CIPHER) *prio, *allow; + SSL_CIPHER *c, *ret = NULL; + int can_use_ecc; + int i, ii, nid, ok; + SSL_CERT *cert; + + /* Let's see which ciphers we can support */ + cert = s->cert; + + can_use_ecc = tls1_get_supported_group(s, &nid); + + /* + * Do not set the compare functions, because this may lead to a + * reordering by "id". We want to keep the original ordering. + * We may pay a price in performance during sk_SSL_CIPHER_find(), + * but would have to pay with the price of sk_SSL_CIPHER_dup(). + */ + + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = srvr; + allow = clnt; + } else { + prio = clnt; + allow = srvr; + } + + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + c = sk_SSL_CIPHER_value(prio, i); + + /* Skip TLS v1.2 only ciphersuites if not supported. */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + !SSL_USE_TLS1_2_CIPHERS(s)) + continue; + + /* Skip TLS v1.3 only ciphersuites if not supported. */ + if ((c->algorithm_ssl & SSL_TLSV1_3) && + !SSL_USE_TLS1_3_CIPHERS(s)) + continue; + + /* If TLS v1.3, only allow TLS v1.3 ciphersuites. */ + if (SSL_USE_TLS1_3_CIPHERS(s) && + !(c->algorithm_ssl & SSL_TLSV1_3)) + continue; + + if (!ssl_security_shared_cipher(s, c)) + continue; + + ssl_set_cert_masks(cert, c); + mask_k = cert->mask_k; + mask_a = cert->mask_a; + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + + ok = (alg_k & mask_k) && (alg_a & mask_a); + + /* + * If we are considering an ECC cipher suite that uses our + * certificate check it. + */ + if (alg_a & SSL_aECDSA) + ok = ok && tls1_check_ec_server_key(s); + /* + * If we are considering an ECC cipher suite that uses + * an ephemeral EC key check it. + */ + if (alg_k & SSL_kECDHE) + ok = ok && can_use_ecc; + + if (!ok) + continue; + ii = sk_SSL_CIPHER_find(allow, c); + if (ii >= 0) { + ret = sk_SSL_CIPHER_value(allow, ii); + break; + } + } + return (ret); +} + +int +ssl3_get_req_cert_types(SSL *s, CBB *cbb) +{ + unsigned long alg_k; + + alg_k = s->s3->hs.cipher->algorithm_mkey; + +#ifndef OPENSSL_NO_GOST + if ((alg_k & SSL_kGOST) != 0) { + if (!CBB_add_u8(cbb, TLS_CT_GOST01_SIGN)) + return 0; + if (!CBB_add_u8(cbb, TLS_CT_GOST12_256_SIGN)) + return 0; + if (!CBB_add_u8(cbb, TLS_CT_GOST12_512_SIGN)) + return 0; + if (!CBB_add_u8(cbb, TLS_CT_GOST12_256_SIGN_COMPAT)) + return 0; + if (!CBB_add_u8(cbb, TLS_CT_GOST12_512_SIGN_COMPAT)) + return 0; + } +#endif + + if ((alg_k & SSL_kDHE) != 0) { + if (!CBB_add_u8(cbb, SSL3_CT_RSA_FIXED_DH)) + return 0; + } + + if (!CBB_add_u8(cbb, SSL3_CT_RSA_SIGN)) + return 0; + + /* + * ECDSA certs can be used with RSA cipher suites as well + * so we don't need to check for SSL_kECDH or SSL_kECDHE. + */ + if (!CBB_add_u8(cbb, TLS_CT_ECDSA_SIGN)) + return 0; + + return 1; +} + +int +ssl3_shutdown(SSL *s) +{ + int ret; + + /* + * Don't do anything much if we have not done the handshake or + * we don't want to send messages :-) + */ + if ((s->quiet_shutdown) || (s->s3->hs.state == SSL_ST_BEFORE)) { + s->shutdown = (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); + return (1); + } + + if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { + s->shutdown|=SSL_SENT_SHUTDOWN; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); + /* + * Our shutdown alert has been sent now, and if it still needs + * to be written, s->s3->alert_dispatch will be true + */ + if (s->s3->alert_dispatch) + return (-1); /* return WANT_WRITE */ + } else if (s->s3->alert_dispatch) { + /* resend it if not sent */ + ret = ssl3_dispatch_alert(s); + if (ret == -1) { + /* + * We only get to return -1 here the 2nd/Nth + * invocation, we must have already signalled + * return 0 upon a previous invoation, + * return WANT_WRITE + */ + return (ret); + } + } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + /* If we are waiting for a close from our peer, we are closed */ + s->method->ssl_read_bytes(s, 0, NULL, 0, 0); + if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + return (-1); /* return WANT_READ */ + } + } + + if ((s->shutdown == (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) && + !s->s3->alert_dispatch) + return (1); + else + return (0); +} + +int +ssl3_write(SSL *s, const void *buf, int len) +{ + errno = 0; + + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + + return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, + buf, len); +} + +static int +ssl3_read_internal(SSL *s, void *buf, int len, int peek) +{ + int ret; + + errno = 0; + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + s->s3->in_read_app_data = 1; + + ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, + peek); + if ((ret == -1) && (s->s3->in_read_app_data == 2)) { + /* + * ssl3_read_bytes decided to call s->handshake_func, + * which called ssl3_read_bytes to read handshake data. + * However, ssl3_read_bytes actually found application data + * and thinks that application data makes sense here; so disable + * handshake processing and try to read application data again. + */ + s->in_handshake++; + ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, + buf, len, peek); + s->in_handshake--; + } else + s->s3->in_read_app_data = 0; + + return (ret); +} + +int +ssl3_read(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 0); +} + +int +ssl3_peek(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 1); +} + +int +ssl3_renegotiate(SSL *s) +{ + if (s->handshake_func == NULL) + return 1; + + if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) + return 0; + + s->s3->renegotiate = 1; + + return 1; +} + +int +ssl3_renegotiate_check(SSL *s) +{ + if (!s->s3->renegotiate) + return 0; + if (SSL_in_init(s) || s->s3->rbuf.left != 0 || s->s3->wbuf.left != 0) + return 0; + + s->s3->hs.state = SSL_ST_RENEGOTIATE; + s->s3->renegotiate = 0; + s->s3->num_renegotiations++; + s->s3->total_renegotiations++; + + return 1; +} diff --git a/Libraries/libressl/ssl/srtp.h b/Libraries/libressl/ssl/srtp.h new file mode 100644 index 000000000..89ce86202 --- /dev/null +++ b/Libraries/libressl/ssl/srtp.h @@ -0,0 +1,146 @@ +/* $OpenBSD: srtp.h,v 1.7 2021/06/11 15:28:13 landry Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. + * Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +#define HEADER_D1_SRTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRTP_AES128_CM_SHA1_80 0x0001 +#define SRTP_AES128_CM_SHA1_32 0x0002 +#define SRTP_AES128_F8_SHA1_80 0x0003 +#define SRTP_AES128_F8_SHA1_32 0x0004 +#define SRTP_NULL_SHA1_80 0x0005 +#define SRTP_NULL_SHA1_32 0x0006 + +/* AEAD SRTP protection profiles from RFC 7714 */ +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libraries/libressl/ssl/ssl.sym b/Libraries/libressl/ssl/ssl.sym new file mode 100644 index 000000000..9f261bb97 --- /dev/null +++ b/Libraries/libressl/ssl/ssl.sym @@ -0,0 +1,363 @@ +BIO_f_ssl +BIO_new_buffer_ssl_connect +BIO_new_ssl +BIO_new_ssl_connect +BIO_ssl_copy_session_id +BIO_ssl_shutdown +DTLS_client_method +DTLS_method +DTLS_server_method +DTLSv1_2_client_method +DTLSv1_2_method +DTLSv1_2_server_method +DTLSv1_client_method +DTLSv1_method +DTLSv1_server_method +ERR_load_SSL_strings +OPENSSL_init_ssl +PEM_read_SSL_SESSION +PEM_read_bio_SSL_SESSION +PEM_write_SSL_SESSION +PEM_write_bio_SSL_SESSION +SSL_CIPHER_description +SSL_CIPHER_find +SSL_CIPHER_get_auth_nid +SSL_CIPHER_get_bits +SSL_CIPHER_get_by_id +SSL_CIPHER_get_by_value +SSL_CIPHER_get_cipher_nid +SSL_CIPHER_get_digest_nid +SSL_CIPHER_get_id +SSL_CIPHER_get_kx_nid +SSL_CIPHER_get_name +SSL_CIPHER_get_value +SSL_CIPHER_get_version +SSL_CIPHER_is_aead +SSL_COMP_add_compression_method +SSL_COMP_get_compression_methods +SSL_COMP_get_name +SSL_CTX_add0_chain_cert +SSL_CTX_add1_chain_cert +SSL_CTX_add_client_CA +SSL_CTX_add_session +SSL_CTX_callback_ctrl +SSL_CTX_check_private_key +SSL_CTX_clear_chain_certs +SSL_CTX_ctrl +SSL_CTX_flush_sessions +SSL_CTX_free +SSL_CTX_get0_certificate +SSL_CTX_get0_chain_certs +SSL_CTX_get0_param +SSL_CTX_get0_privatekey +SSL_CTX_get_cert_store +SSL_CTX_get_ciphers +SSL_CTX_get_client_CA_list +SSL_CTX_get_client_cert_cb +SSL_CTX_get_default_passwd_cb +SSL_CTX_get_default_passwd_cb_userdata +SSL_CTX_get_ex_data +SSL_CTX_get_ex_new_index +SSL_CTX_get_info_callback +SSL_CTX_get_keylog_callback +SSL_CTX_get_max_early_data +SSL_CTX_get_max_proto_version +SSL_CTX_get_min_proto_version +SSL_CTX_get_num_tickets +SSL_CTX_get_quiet_shutdown +SSL_CTX_get_security_level +SSL_CTX_get_ssl_method +SSL_CTX_get_timeout +SSL_CTX_get_verify_callback +SSL_CTX_get_verify_depth +SSL_CTX_get_verify_mode +SSL_CTX_load_verify_locations +SSL_CTX_load_verify_mem +SSL_CTX_new +SSL_CTX_remove_session +SSL_CTX_sess_get_get_cb +SSL_CTX_sess_get_new_cb +SSL_CTX_sess_get_remove_cb +SSL_CTX_sess_set_get_cb +SSL_CTX_sess_set_new_cb +SSL_CTX_sess_set_remove_cb +SSL_CTX_sessions +SSL_CTX_set0_chain +SSL_CTX_set1_chain +SSL_CTX_set1_groups +SSL_CTX_set1_groups_list +SSL_CTX_set1_param +SSL_CTX_set_alpn_protos +SSL_CTX_set_alpn_select_cb +SSL_CTX_set_cert_store +SSL_CTX_set_cert_verify_callback +SSL_CTX_set_cipher_list +SSL_CTX_set_ciphersuites +SSL_CTX_set_client_CA_list +SSL_CTX_set_client_cert_cb +SSL_CTX_set_cookie_generate_cb +SSL_CTX_set_cookie_verify_cb +SSL_CTX_set_default_passwd_cb +SSL_CTX_set_default_passwd_cb_userdata +SSL_CTX_set_default_verify_paths +SSL_CTX_set_ex_data +SSL_CTX_set_generate_session_id +SSL_CTX_set_info_callback +SSL_CTX_set_keylog_callback +SSL_CTX_set_max_early_data +SSL_CTX_set_max_proto_version +SSL_CTX_set_min_proto_version +SSL_CTX_set_msg_callback +SSL_CTX_set_next_proto_select_cb +SSL_CTX_set_next_protos_advertised_cb +SSL_CTX_set_num_tickets +SSL_CTX_set_post_handshake_auth +SSL_CTX_set_purpose +SSL_CTX_set_quic_method +SSL_CTX_set_quiet_shutdown +SSL_CTX_set_security_level +SSL_CTX_set_session_id_context +SSL_CTX_set_ssl_version +SSL_CTX_set_timeout +SSL_CTX_set_tlsext_use_srtp +SSL_CTX_set_tmp_dh_callback +SSL_CTX_set_tmp_ecdh_callback +SSL_CTX_set_tmp_rsa_callback +SSL_CTX_set_trust +SSL_CTX_set_verify +SSL_CTX_set_verify_depth +SSL_CTX_up_ref +SSL_CTX_use_PrivateKey +SSL_CTX_use_PrivateKey_ASN1 +SSL_CTX_use_PrivateKey_file +SSL_CTX_use_RSAPrivateKey +SSL_CTX_use_RSAPrivateKey_ASN1 +SSL_CTX_use_RSAPrivateKey_file +SSL_CTX_use_certificate +SSL_CTX_use_certificate_ASN1 +SSL_CTX_use_certificate_chain_file +SSL_CTX_use_certificate_chain_mem +SSL_CTX_use_certificate_file +SSL_SESSION_free +SSL_SESSION_get0_cipher +SSL_SESSION_get0_id_context +SSL_SESSION_get0_peer +SSL_SESSION_get_compress_id +SSL_SESSION_get_ex_data +SSL_SESSION_get_ex_new_index +SSL_SESSION_get_id +SSL_SESSION_get_master_key +SSL_SESSION_get_max_early_data +SSL_SESSION_get_protocol_version +SSL_SESSION_get_ticket_lifetime_hint +SSL_SESSION_get_time +SSL_SESSION_get_timeout +SSL_SESSION_has_ticket +SSL_SESSION_is_resumable +SSL_SESSION_new +SSL_SESSION_print +SSL_SESSION_print_fp +SSL_SESSION_set1_id +SSL_SESSION_set1_id_context +SSL_SESSION_set_ex_data +SSL_SESSION_set_max_early_data +SSL_SESSION_set_time +SSL_SESSION_set_timeout +SSL_SESSION_up_ref +SSL_accept +SSL_add0_chain_cert +SSL_add1_chain_cert +SSL_add_client_CA +SSL_add_dir_cert_subjects_to_stack +SSL_add_file_cert_subjects_to_stack +SSL_alert_desc_string +SSL_alert_desc_string_long +SSL_alert_type_string +SSL_alert_type_string_long +SSL_cache_hit +SSL_callback_ctrl +SSL_check_private_key +SSL_clear +SSL_clear_chain_certs +SSL_connect +SSL_copy_session_id +SSL_ctrl +SSL_do_handshake +SSL_dup +SSL_dup_CA_list +SSL_export_keying_material +SSL_free +SSL_get0_alpn_selected +SSL_get0_chain_certs +SSL_get0_next_proto_negotiated +SSL_get0_param +SSL_get0_peername +SSL_get0_verified_chain +SSL_get1_session +SSL_get1_supported_ciphers +SSL_get_SSL_CTX +SSL_get_certificate +SSL_get_cipher_list +SSL_get_ciphers +SSL_get_client_CA_list +SSL_get_client_ciphers +SSL_get_client_random +SSL_get_current_cipher +SSL_get_current_compression +SSL_get_current_expansion +SSL_get_default_timeout +SSL_get_early_data_status +SSL_get_error +SSL_get_ex_data +SSL_get_ex_data_X509_STORE_CTX_idx +SSL_get_ex_new_index +SSL_get_fd +SSL_get_finished +SSL_get_info_callback +SSL_get_max_early_data +SSL_get_max_proto_version +SSL_get_min_proto_version +SSL_get_num_tickets +SSL_get_peer_cert_chain +SSL_get_peer_certificate +SSL_get_peer_finished +SSL_get_peer_quic_transport_params +SSL_get_privatekey +SSL_get_quiet_shutdown +SSL_get_rbio +SSL_get_read_ahead +SSL_get_rfd +SSL_get_security_level +SSL_get_selected_srtp_profile +SSL_get_server_random +SSL_get_servername +SSL_get_servername_type +SSL_get_session +SSL_get_shared_ciphers +SSL_get_shutdown +SSL_get_srtp_profiles +SSL_get_ssl_method +SSL_get_verify_callback +SSL_get_verify_depth +SSL_get_verify_mode +SSL_get_verify_result +SSL_get_version +SSL_get_wbio +SSL_get_wfd +SSL_has_matching_session_id +SSL_is_dtls +SSL_is_quic +SSL_is_server +SSL_library_init +SSL_load_client_CA_file +SSL_load_error_strings +SSL_new +SSL_peek +SSL_peek_ex +SSL_pending +SSL_process_quic_post_handshake +SSL_provide_quic_data +SSL_quic_max_handshake_flight_len +SSL_quic_read_level +SSL_quic_write_level +SSL_read +SSL_read_early_data +SSL_read_ex +SSL_renegotiate +SSL_renegotiate_abbreviated +SSL_renegotiate_pending +SSL_rstate_string +SSL_rstate_string_long +SSL_select_next_proto +SSL_set0_chain +SSL_set0_rbio +SSL_set1_chain +SSL_set1_groups +SSL_set1_groups_list +SSL_set1_host +SSL_set1_param +SSL_set_SSL_CTX +SSL_set_accept_state +SSL_set_alpn_protos +SSL_set_bio +SSL_set_cipher_list +SSL_set_ciphersuites +SSL_set_client_CA_list +SSL_set_connect_state +SSL_set_debug +SSL_set_ex_data +SSL_set_fd +SSL_set_generate_session_id +SSL_set_hostflags +SSL_set_info_callback +SSL_set_max_early_data +SSL_set_max_proto_version +SSL_set_min_proto_version +SSL_set_msg_callback +SSL_set_num_tickets +SSL_set_post_handshake_auth +SSL_set_psk_use_session_callback +SSL_set_purpose +SSL_set_quic_method +SSL_set_quic_transport_params +SSL_set_quic_use_legacy_codepoint +SSL_set_quiet_shutdown +SSL_set_read_ahead +SSL_set_rfd +SSL_set_security_level +SSL_set_session +SSL_set_session_id_context +SSL_set_session_secret_cb +SSL_set_session_ticket_ext +SSL_set_session_ticket_ext_cb +SSL_set_shutdown +SSL_set_ssl_method +SSL_set_state +SSL_set_tlsext_use_srtp +SSL_set_tmp_dh_callback +SSL_set_tmp_ecdh_callback +SSL_set_tmp_rsa_callback +SSL_set_trust +SSL_set_verify +SSL_set_verify_depth +SSL_set_verify_result +SSL_set_wfd +SSL_shutdown +SSL_state +SSL_state_string +SSL_state_string_long +SSL_up_ref +SSL_use_PrivateKey +SSL_use_PrivateKey_ASN1 +SSL_use_PrivateKey_file +SSL_use_RSAPrivateKey +SSL_use_RSAPrivateKey_ASN1 +SSL_use_RSAPrivateKey_file +SSL_use_certificate +SSL_use_certificate_ASN1 +SSL_use_certificate_chain_file +SSL_use_certificate_file +SSL_verify_client_post_handshake +SSL_version +SSL_version_str +SSL_want +SSL_write +SSL_write_early_data +SSL_write_ex +SSLv23_client_method +SSLv23_method +SSLv23_server_method +TLS_client_method +TLS_method +TLS_server_method +TLSv1_1_client_method +TLSv1_1_method +TLSv1_1_server_method +TLSv1_2_client_method +TLSv1_2_method +TLSv1_2_server_method +TLSv1_client_method +TLSv1_method +TLSv1_server_method +d2i_SSL_SESSION +i2d_SSL_SESSION diff --git a/Libraries/libressl/ssl/ssl_algs.c b/Libraries/libressl/ssl/ssl_algs.c new file mode 100644 index 000000000..684697df5 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_algs.c @@ -0,0 +1,125 @@ +/* $OpenBSD: ssl_algs.c,v 1.32 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include "ssl_local.h" + +int +SSL_library_init(void) +{ + +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); +#endif +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); +#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) + EVP_add_cipher(EVP_rc4_hmac_md5()); +#endif +#endif +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_cbc()); + /* Not actually used for SSL/TLS but this makes PKCS#12 work + * if an application only calls SSL_library_init(). + */ + EVP_add_cipher(EVP_rc2_40_cbc()); +#endif + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_256_cbc()); +#endif +#ifndef OPENSSL_NO_GOST + EVP_add_cipher(EVP_gost2814789_cfb64()); + EVP_add_cipher(EVP_gost2814789_cnt()); +#endif + + EVP_add_digest(EVP_md5()); + EVP_add_digest(EVP_md5_sha1()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); + + EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#ifndef OPENSSL_NO_GOST + EVP_add_digest(EVP_gostr341194()); + EVP_add_digest(EVP_gost2814789imit()); + EVP_add_digest(EVP_streebog256()); + EVP_add_digest(EVP_streebog512()); +#endif + + return (1); +} +LSSL_ALIAS(SSL_library_init); diff --git a/Libraries/libressl/ssl/ssl_asn1.c b/Libraries/libressl/ssl/ssl_asn1.c new file mode 100644 index 000000000..f4552f1c9 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_asn1.c @@ -0,0 +1,420 @@ +/* $OpenBSD: ssl_asn1.c,v 1.67 2023/07/08 16:40:13 beck Exp $ */ +/* + * Copyright (c) 2016 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "bytestring.h" +#include "ssl_local.h" + +#define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC) +#define SSLASN1_TIME_TAG (SSLASN1_TAG | 1) +#define SSLASN1_TIMEOUT_TAG (SSLASN1_TAG | 2) +#define SSLASN1_PEER_CERT_TAG (SSLASN1_TAG | 3) +#define SSLASN1_SESSION_ID_CTX_TAG (SSLASN1_TAG | 4) +#define SSLASN1_VERIFY_RESULT_TAG (SSLASN1_TAG | 5) +#define SSLASN1_HOSTNAME_TAG (SSLASN1_TAG | 6) +#define SSLASN1_LIFETIME_TAG (SSLASN1_TAG | 9) +#define SSLASN1_TICKET_TAG (SSLASN1_TAG | 10) + +static uint64_t +time_max(void) +{ + if (sizeof(time_t) == sizeof(int32_t)) + return INT32_MAX; + if (sizeof(time_t) == sizeof(int64_t)) + return INT64_MAX; + return 0; +} + +static int +SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len, + int ticket_encoding) +{ + CBB cbb, session, cipher_suite, session_id, master_key, time, timeout; + CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket, value; + unsigned char *peer_cert_bytes = NULL; + int len, rv = 0; + uint16_t cid; + + if (!CBB_init(&cbb, 0)) + goto err; + + if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE)) + goto err; + + /* Session ASN1 version. */ + if (!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION)) + goto err; + + /* TLS/SSL protocol version. */ + if (s->ssl_version < 0) + goto err; + if (!CBB_add_asn1_uint64(&session, s->ssl_version)) + goto err; + + /* Cipher suite ID. */ + /* XXX - require cipher to be non-NULL or always/only use cipher_id. */ + cid = (uint16_t)(s->cipher_id & SSL3_CK_VALUE_MASK); + if (s->cipher != NULL) + cid = ssl3_cipher_get_value(s->cipher); + if (!CBB_add_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBB_add_u16(&cipher_suite, cid)) + goto err; + + /* Session ID - zero length for a ticket. */ + if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBB_add_bytes(&session_id, s->session_id, + ticket_encoding ? 0 : s->session_id_length)) + goto err; + + /* Master key. */ + if (!CBB_add_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBB_add_bytes(&master_key, s->master_key, s->master_key_length)) + goto err; + + /* Time [1]. */ + if (s->time != 0) { + if (s->time < 0) + goto err; + if (!CBB_add_asn1(&session, &time, SSLASN1_TIME_TAG)) + goto err; + if (!CBB_add_asn1_uint64(&time, s->time)) + goto err; + } + + /* Timeout [2]. */ + if (s->timeout != 0) { + if (s->timeout < 0) + goto err; + if (!CBB_add_asn1(&session, &timeout, SSLASN1_TIMEOUT_TAG)) + goto err; + if (!CBB_add_asn1_uint64(&timeout, s->timeout)) + goto err; + } + + /* Peer certificate [3]. */ + if (s->peer_cert != NULL) { + if ((len = i2d_X509(s->peer_cert, &peer_cert_bytes)) <= 0) + goto err; + if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG)) + goto err; + if (!CBB_add_bytes(&peer_cert, peer_cert_bytes, len)) + goto err; + } + + /* Session ID context [4]. */ + /* XXX - Actually handle this as optional? */ + if (!CBB_add_asn1(&session, &sidctx, SSLASN1_SESSION_ID_CTX_TAG)) + goto err; + if (!CBB_add_asn1(&sidctx, &value, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBB_add_bytes(&value, s->sid_ctx, s->sid_ctx_length)) + goto err; + + /* Verify result [5]. */ + if (s->verify_result != X509_V_OK) { + if (s->verify_result < 0) + goto err; + if (!CBB_add_asn1(&session, &verify_result, + SSLASN1_VERIFY_RESULT_TAG)) + goto err; + if (!CBB_add_asn1_uint64(&verify_result, s->verify_result)) + goto err; + } + + /* Hostname [6]. */ + if (s->tlsext_hostname != NULL) { + if (!CBB_add_asn1(&session, &hostname, SSLASN1_HOSTNAME_TAG)) + goto err; + if (!CBB_add_asn1(&hostname, &value, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBB_add_bytes(&value, (const uint8_t *)s->tlsext_hostname, + strlen(s->tlsext_hostname))) + goto err; + } + + /* PSK identity hint [7]. */ + /* PSK identity [8]. */ + + /* Ticket lifetime hint [9]. */ + if (s->tlsext_tick_lifetime_hint > 0) { + if (!CBB_add_asn1(&session, &lifetime, SSLASN1_LIFETIME_TAG)) + goto err; + if (!CBB_add_asn1_uint64(&lifetime, + s->tlsext_tick_lifetime_hint)) + goto err; + } + + /* Ticket [10]. */ + if (s->tlsext_tick != NULL) { + if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG)) + goto err; + if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBB_add_bytes(&value, s->tlsext_tick, s->tlsext_ticklen)) + goto err; + } + + /* Compression method [11]. */ + /* SRP username [12]. */ + + if (!CBB_finish(&cbb, out, out_len)) + goto err; + + rv = 1; + + err: + CBB_cleanup(&cbb); + free(peer_cert_bytes); + + return rv; +} + +int +SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len) +{ + if (ss == NULL) + return 0; + + if (ss->cipher == NULL && ss->cipher_id == 0) + return 0; + + return SSL_SESSION_encode(ss, out, out_len, 1); +} + +int +i2d_SSL_SESSION(SSL_SESSION *ss, unsigned char **pp) +{ + unsigned char *data = NULL; + size_t data_len = 0; + int rv = -1; + + if (ss == NULL) + return 0; + + if (ss->cipher == NULL && ss->cipher_id == 0) + return 0; + + if (!SSL_SESSION_encode(ss, &data, &data_len, 0)) + goto err; + + if (data_len > INT_MAX) + goto err; + + if (pp != NULL) { + if (*pp == NULL) { + *pp = data; + data = NULL; + } else { + memcpy(*pp, data, data_len); + *pp += data_len; + } + } + + rv = (int)data_len; + + err: + freezero(data, data_len); + + return rv; +} +LSSL_ALIAS(i2d_SSL_SESSION); + +SSL_SESSION * +d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length) +{ + CBS cbs, session, cipher_suite, session_id, master_key, peer_cert; + CBS hostname, ticket; + uint64_t version, tls_version, stime, timeout, verify_result, lifetime; + const unsigned char *peer_cert_bytes; + uint16_t cipher_value; + SSL_SESSION *s = NULL; + size_t data_len; + int present; + + if (a != NULL) + s = *a; + + if (s == NULL) { + if ((s = SSL_SESSION_new()) == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (NULL); + } + } + + CBS_init(&cbs, *pp, length); + + if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE)) + goto err; + + /* Session ASN1 version. */ + if (!CBS_get_asn1_uint64(&session, &version)) + goto err; + if (version != SSL_SESSION_ASN1_VERSION) + goto err; + + /* TLS/SSL Protocol Version. */ + if (!CBS_get_asn1_uint64(&session, &tls_version)) + goto err; + if (tls_version > INT_MAX) + goto err; + s->ssl_version = (int)tls_version; + + /* Cipher suite. */ + if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBS_get_u16(&cipher_suite, &cipher_value)) + goto err; + if (CBS_len(&cipher_suite) != 0) + goto err; + + /* XXX - populate cipher instead? */ + s->cipher = NULL; + s->cipher_id = SSL3_CK_ID | cipher_value; + + /* Session ID. */ + if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id), + &s->session_id_length)) + goto err; + + /* Master key. */ + if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING)) + goto err; + if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key), + &s->master_key_length)) + goto err; + + /* Time [1]. */ + s->time = time(NULL); + if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG, + 0)) + goto err; + if (stime > time_max()) + goto err; + if (stime != 0) + s->time = (time_t)stime; + + /* Timeout [2]. */ + s->timeout = 3; + if (!CBS_get_optional_asn1_uint64(&session, &timeout, + SSLASN1_TIMEOUT_TAG, 0)) + goto err; + if (timeout > LONG_MAX) + goto err; + if (timeout != 0) + s->timeout = (long)timeout; + + /* Peer certificate [3]. */ + X509_free(s->peer_cert); + s->peer_cert = NULL; + if (!CBS_get_optional_asn1(&session, &peer_cert, &present, + SSLASN1_PEER_CERT_TAG)) + goto err; + if (present) { + data_len = CBS_len(&peer_cert); + if (data_len > LONG_MAX) + goto err; + peer_cert_bytes = CBS_data(&peer_cert); + if (d2i_X509(&s->peer_cert, &peer_cert_bytes, + (long)data_len) == NULL) + goto err; + } + + /* Session ID context [4]. */ + s->sid_ctx_length = 0; + if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present, + SSLASN1_SESSION_ID_CTX_TAG)) + goto err; + if (present) { + if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx, + sizeof(s->sid_ctx), &s->sid_ctx_length)) + goto err; + } + + /* Verify result [5]. */ + s->verify_result = X509_V_OK; + if (!CBS_get_optional_asn1_uint64(&session, &verify_result, + SSLASN1_VERIFY_RESULT_TAG, X509_V_OK)) + goto err; + if (verify_result > LONG_MAX) + goto err; + s->verify_result = (long)verify_result; + + /* Hostname [6]. */ + free(s->tlsext_hostname); + s->tlsext_hostname = NULL; + if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present, + SSLASN1_HOSTNAME_TAG)) + goto err; + if (present) { + if (CBS_contains_zero_byte(&hostname)) + goto err; + if (!CBS_strdup(&hostname, &s->tlsext_hostname)) + goto err; + } + + /* PSK identity hint [7]. */ + /* PSK identity [8]. */ + + /* Ticket lifetime [9]. */ + s->tlsext_tick_lifetime_hint = 0; + if (!CBS_get_optional_asn1_uint64(&session, &lifetime, + SSLASN1_LIFETIME_TAG, 0)) + goto err; + if (lifetime > UINT32_MAX) + goto err; + if (lifetime > 0) + s->tlsext_tick_lifetime_hint = (uint32_t)lifetime; + + /* Ticket [10]. */ + free(s->tlsext_tick); + s->tlsext_tick = NULL; + if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present, + SSLASN1_TICKET_TAG)) + goto err; + if (present) { + if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen)) + goto err; + } + + /* Compression method [11]. */ + /* SRP username [12]. */ + + *pp = CBS_data(&cbs); + + if (a != NULL) + *a = s; + + return (s); + + err: + ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp)); + + if (s != NULL && (a == NULL || *a != s)) + SSL_SESSION_free(s); + + return (NULL); +} +LSSL_ALIAS(d2i_SSL_SESSION); diff --git a/Libraries/libressl/ssl/ssl_both.c b/Libraries/libressl/ssl/ssl_both.c new file mode 100644 index 000000000..14d9aa85a --- /dev/null +++ b/Libraries/libressl/ssl/ssl_both.c @@ -0,0 +1,580 @@ +/* $OpenBSD: ssl_both.c,v 1.46 2023/07/07 08:53:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" + +/* + * Send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC). + */ +int +ssl3_do_write(SSL *s, int type) +{ + int ret; + + ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + s->init_num); + if (ret < 0) + return (-1); + + if (type == SSL3_RT_HANDSHAKE) + /* + * Should not be done for 'Hello Request's, but in that case + * we'll ignore the result anyway. + */ + tls1_transcript_record(s, + (unsigned char *)&s->init_buf->data[s->init_off], ret); + + if (ret == s->init_num) { + ssl_msg_callback(s, 1, type, s->init_buf->data, + (size_t)(s->init_off + s->init_num)); + return (1); + } + + s->init_off += ret; + s->init_num -= ret; + + return (0); +} + +static int +ssl3_add_cert(CBB *cbb, X509 *x) +{ + unsigned char *data; + int cert_len; + int ret = 0; + CBB cert; + + if ((cert_len = i2d_X509(x, NULL)) < 0) + goto err; + + if (!CBB_add_u24_length_prefixed(cbb, &cert)) + goto err; + if (!CBB_add_space(&cert, &data, cert_len)) + goto err; + if (i2d_X509(x, &data) < 0) + goto err; + if (!CBB_flush(cbb)) + goto err; + + ret = 1; + + err: + return (ret); +} + +int +ssl3_output_cert_chain(SSL *s, CBB *cbb, SSL_CERT_PKEY *cpk) +{ + X509_STORE_CTX *xs_ctx = NULL; + STACK_OF(X509) *chain; + CBB cert_list; + X509 *x; + int ret = 0; + int i; + + if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) + goto err; + + /* Send an empty certificate list when no certificate is available. */ + if (cpk == NULL) + goto done; + + if ((chain = cpk->chain) == NULL) + chain = s->ctx->extra_certs; + + if (chain != NULL || (s->mode & SSL_MODE_NO_AUTO_CHAIN)) { + if (!ssl3_add_cert(&cert_list, cpk->x509)) + goto err; + } else { + if ((xs_ctx = X509_STORE_CTX_new()) == NULL) + goto err; + if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store, + cpk->x509, NULL)) { + SSLerror(s, ERR_R_X509_LIB); + goto err; + } + X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(xs_ctx), + X509_V_FLAG_LEGACY_VERIFY); + X509_verify_cert(xs_ctx); + ERR_clear_error(); + chain = X509_STORE_CTX_get0_chain(xs_ctx); + } + + for (i = 0; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + if (!ssl3_add_cert(&cert_list, x)) + goto err; + } + + done: + if (!CBB_flush(cbb)) + goto err; + + ret = 1; + + err: + X509_STORE_CTX_free(xs_ctx); + + return (ret); +} + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), + * maximum acceptable body length 'max'. + * The first four bytes (msg_type and length) are read in state 'st1', + * the body is read in state 'stn'. + */ +int +ssl3_get_message(SSL *s, int st1, int stn, int mt, long max) +{ + unsigned char *p; + uint32_t l; + long n; + int i, al; + CBS cbs; + uint8_t u8; + + if (SSL_is_dtls(s)) + return dtls1_get_message(s, st1, stn, mt, max); + + if (s->s3->hs.tls12.reuse_message) { + s->s3->hs.tls12.reuse_message = 0; + if ((mt >= 0) && (s->s3->hs.tls12.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + goto fatal_err; + } + s->init_msg = s->init_buf->data + + SSL3_HM_HEADER_LENGTH; + s->init_num = (int)s->s3->hs.tls12.message_size; + return 1; + } + + p = (unsigned char *)s->init_buf->data; + + if (s->s3->hs.state == st1) { + int skip_message; + + do { + while (s->init_num < SSL3_HM_HEADER_LENGTH) { + i = s->method->ssl_read_bytes(s, + SSL3_RT_HANDSHAKE, &p[s->init_num], + SSL3_HM_HEADER_LENGTH - s->init_num, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + return i; + } + s->init_num += i; + } + + skip_message = 0; + if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) { + /* + * The server may always send 'Hello Request' + * messages -- we are doing a handshake anyway + * now, so ignore them if their format is + * correct. Does not count for 'Finished' MAC. + */ + if (p[1] == 0 && p[2] == 0 &&p[3] == 0) { + s->init_num = 0; + skip_message = 1; + + ssl_msg_callback(s, 0, + SSL3_RT_HANDSHAKE, p, + SSL3_HM_HEADER_LENGTH); + } + } + } while (skip_message); + + if ((mt >= 0) && (*p != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + goto fatal_err; + } + + CBS_init(&cbs, p, SSL3_HM_HEADER_LENGTH); + if (!CBS_get_u8(&cbs, &u8) || + !CBS_get_u24(&cbs, &l)) { + SSLerror(s, ERR_R_BUF_LIB); + goto err; + } + s->s3->hs.tls12.message_type = u8; + + if (l > (unsigned long)max) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto fatal_err; + } + if (l && !BUF_MEM_grow_clean(s->init_buf, + l + SSL3_HM_HEADER_LENGTH)) { + SSLerror(s, ERR_R_BUF_LIB); + goto err; + } + s->s3->hs.tls12.message_size = l; + s->s3->hs.state = stn; + + s->init_msg = s->init_buf->data + + SSL3_HM_HEADER_LENGTH; + s->init_num = 0; + } + + /* next state (stn) */ + p = s->init_msg; + n = s->s3->hs.tls12.message_size - s->init_num; + while (n > 0) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[s->init_num], n, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + return i; + } + s->init_num += i; + n -= i; + } + + /* Feed this message into MAC computation. */ + if (s->mac_packet) { + tls1_transcript_record(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH); + + ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, + s->init_buf->data, + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH); + } + + return 1; + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return -1; +} + +int +ssl_cert_type(EVP_PKEY *pkey) +{ + if (pkey == NULL) + return -1; + + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_EC: + return SSL_PKEY_ECC; + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001_cc: + return SSL_PKEY_GOST01; + case EVP_PKEY_RSA: + case EVP_PKEY_RSA_PSS: + return SSL_PKEY_RSA; + } + + return -1; +} + +int +ssl_verify_alarm_type(long type) +{ + int al; + + switch (type) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_CERT_UNTRUSTED: + case X509_V_ERR_CERT_REJECTED: + al = SSL_AD_BAD_CERTIFICATE; + break; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + al = SSL_AD_DECRYPT_ERROR; + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CRL_HAS_EXPIRED: + al = SSL_AD_CERTIFICATE_EXPIRED; + break; + case X509_V_ERR_CERT_REVOKED: + al = SSL_AD_CERTIFICATE_REVOKED; + break; + case X509_V_ERR_OUT_OF_MEM: + al = SSL_AD_INTERNAL_ERROR; + break; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_CA: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_APPLICATION_VERIFICATION: + al = SSL_AD_HANDSHAKE_FAILURE; + break; + case X509_V_ERR_INVALID_PURPOSE: + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + break; + default: + al = SSL_AD_CERTIFICATE_UNKNOWN; + break; + } + return (al); +} + +int +ssl3_setup_init_buffer(SSL *s) +{ + BUF_MEM *buf = NULL; + + if (s->init_buf != NULL) + return (1); + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) + goto err; + + s->init_buf = buf; + return (1); + + err: + BUF_MEM_free(buf); + return (0); +} + +void +ssl3_release_init_buffer(SSL *s) +{ + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + s->init_msg = NULL; + s->init_num = 0; + s->init_off = 0; +} + +int +ssl3_setup_read_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align, headerlen; + + if (SSL_is_dtls(s)) + headerlen = DTLS1_RT_HEADER_LENGTH; + else + headerlen = SSL3_RT_HEADER_LENGTH; + + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); + + if (s->s3->rbuf.buf == NULL) { + len = SSL3_RT_MAX_PLAIN_LENGTH + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if ((p = calloc(1, len)) == NULL) + goto err; + s->s3->rbuf.buf = p; + s->s3->rbuf.len = len; + } + + s->packet = s->s3->rbuf.buf; + return 1; + + err: + SSLerror(s, ERR_R_MALLOC_FAILURE); + return 0; +} + +int +ssl3_setup_write_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align, headerlen; + + if (SSL_is_dtls(s)) + headerlen = DTLS1_RT_HEADER_LENGTH + 1; + else + headerlen = SSL3_RT_HEADER_LENGTH; + + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); + + if (s->s3->wbuf.buf == NULL) { + len = s->max_send_fragment + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) + len += headerlen + align + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; + + if ((p = calloc(1, len)) == NULL) + goto err; + s->s3->wbuf.buf = p; + s->s3->wbuf.len = len; + } + + return 1; + + err: + SSLerror(s, ERR_R_MALLOC_FAILURE); + return 0; +} + +int +ssl3_setup_buffers(SSL *s) +{ + if (!ssl3_setup_read_buffer(s)) + return 0; + if (!ssl3_setup_write_buffer(s)) + return 0; + return 1; +} + +void +ssl3_release_buffer(SSL3_BUFFER_INTERNAL *b) +{ + freezero(b->buf, b->len); + b->buf = NULL; + b->len = 0; +} + +void +ssl3_release_read_buffer(SSL *s) +{ + ssl3_release_buffer(&s->s3->rbuf); +} + +void +ssl3_release_write_buffer(SSL *s) +{ + ssl3_release_buffer(&s->s3->wbuf); +} diff --git a/Libraries/libressl/ssl/ssl_cert.c b/Libraries/libressl/ssl/ssl_cert.c new file mode 100644 index 000000000..a28805026 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_cert.c @@ -0,0 +1,741 @@ +/* $OpenBSD: ssl_cert.c,v 1.107 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ssl_local.h" + +int +SSL_get_ex_data_X509_STORE_CTX_idx(void) +{ + static volatile int ssl_x509_store_ctx_idx = -1; + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + + if (ssl_x509_store_ctx_idx < 0) { + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + got_write_lock = 1; + + if (ssl_x509_store_ctx_idx < 0) { + ssl_x509_store_ctx_idx = + X509_STORE_CTX_get_ex_new_index( + 0, "SSL for verify callback", NULL, NULL, NULL); + } + } + + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + else + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + return ssl_x509_store_ctx_idx; +} +LSSL_ALIAS(SSL_get_ex_data_X509_STORE_CTX_idx); + +SSL_CERT * +ssl_cert_new(void) +{ + SSL_CERT *ret; + + ret = calloc(1, sizeof(SSL_CERT)); + if (ret == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->key = &(ret->pkeys[SSL_PKEY_RSA]); + ret->references = 1; + ret->security_cb = ssl_security_default_cb; + ret->security_level = OPENSSL_TLS_SECURITY_LEVEL; + ret->security_ex_data = NULL; + return (ret); +} + +SSL_CERT * +ssl_cert_dup(SSL_CERT *cert) +{ + SSL_CERT *ret; + int i; + + ret = calloc(1, sizeof(SSL_CERT)); + if (ret == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (NULL); + } + + /* + * same as ret->key = ret->pkeys + (cert->key - cert->pkeys), + * if you find that more readable + */ + ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; + + ret->valid = cert->valid; + ret->mask_k = cert->mask_k; + ret->mask_a = cert->mask_a; + + if (cert->dhe_params != NULL) { + ret->dhe_params = DHparams_dup(cert->dhe_params); + if (ret->dhe_params == NULL) { + SSLerrorx(ERR_R_DH_LIB); + goto err; + } + } + ret->dhe_params_cb = cert->dhe_params_cb; + ret->dhe_params_auto = cert->dhe_params_auto; + + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (cert->pkeys[i].x509 != NULL) { + ret->pkeys[i].x509 = cert->pkeys[i].x509; + X509_up_ref(ret->pkeys[i].x509); + } + + if (cert->pkeys[i].privatekey != NULL) { + ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; + EVP_PKEY_up_ref(ret->pkeys[i].privatekey); + switch (i) { + /* + * If there was anything special to do for + * certain types of keys, we'd do it here. + * (Nothing at the moment, I think.) + */ + + case SSL_PKEY_RSA: + /* We have an RSA key. */ + break; + + case SSL_PKEY_ECC: + /* We have an ECC key */ + break; + + case SSL_PKEY_GOST01: + /* We have a GOST key */ + break; + + default: + /* Can't happen. */ + SSLerrorx(SSL_R_LIBRARY_BUG); + } + } + + if (cert->pkeys[i].chain != NULL) { + if ((ret->pkeys[i].chain = + X509_chain_up_ref(cert->pkeys[i].chain)) == NULL) + goto err; + } + } + + ret->security_cb = cert->security_cb; + ret->security_level = cert->security_level; + ret->security_ex_data = cert->security_ex_data; + + /* + * ret->extra_certs *should* exist, but currently the own certificate + * chain is held inside SSL_CTX + */ + + ret->references = 1; + + return (ret); + + err: + DH_free(ret->dhe_params); + + for (i = 0; i < SSL_PKEY_NUM; i++) { + X509_free(ret->pkeys[i].x509); + EVP_PKEY_free(ret->pkeys[i].privatekey); + sk_X509_pop_free(ret->pkeys[i].chain, X509_free); + } + free (ret); + return NULL; +} + + +void +ssl_cert_free(SSL_CERT *c) +{ + int i; + + if (c == NULL) + return; + + i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); + if (i > 0) + return; + + DH_free(c->dhe_params); + + for (i = 0; i < SSL_PKEY_NUM; i++) { + X509_free(c->pkeys[i].x509); + EVP_PKEY_free(c->pkeys[i].privatekey); + sk_X509_pop_free(c->pkeys[i].chain, X509_free); + } + + free(c); +} + +SSL_CERT * +ssl_get0_cert(SSL_CTX *ctx, SSL *ssl) +{ + if (ssl != NULL) + return ssl->cert; + + return ctx->cert; +} + +int +ssl_cert_set0_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain) +{ + SSL_CERT *ssl_cert; + SSL_CERT_PKEY *cpk; + X509 *x509; + int ssl_err; + int i; + + if ((ssl_cert = ssl_get0_cert(ctx, ssl)) == NULL) + return 0; + + if ((cpk = ssl_cert->key) == NULL) + return 0; + + for (i = 0; i < sk_X509_num(chain); i++) { + x509 = sk_X509_value(chain, i); + if (!ssl_security_cert(ctx, ssl, x509, 0, &ssl_err)) { + SSLerrorx(ssl_err); + return 0; + } + } + + sk_X509_pop_free(cpk->chain, X509_free); + cpk->chain = chain; + + return 1; +} + +int +ssl_cert_set1_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain) +{ + STACK_OF(X509) *new_chain = NULL; + + if (chain != NULL) { + if ((new_chain = X509_chain_up_ref(chain)) == NULL) + return 0; + } + if (!ssl_cert_set0_chain(ctx, ssl, new_chain)) { + sk_X509_pop_free(new_chain, X509_free); + return 0; + } + + return 1; +} + +int +ssl_cert_add0_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert) +{ + SSL_CERT *ssl_cert; + SSL_CERT_PKEY *cpk; + int ssl_err; + + if ((ssl_cert = ssl_get0_cert(ctx, ssl)) == NULL) + return 0; + + if ((cpk = ssl_cert->key) == NULL) + return 0; + + if (!ssl_security_cert(ctx, ssl, cert, 0, &ssl_err)) { + SSLerrorx(ssl_err); + return 0; + } + + if (cpk->chain == NULL) { + if ((cpk->chain = sk_X509_new_null()) == NULL) + return 0; + } + if (!sk_X509_push(cpk->chain, cert)) + return 0; + + return 1; +} + +int +ssl_cert_add1_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert) +{ + if (!ssl_cert_add0_chain_cert(ctx, ssl, cert)) + return 0; + + X509_up_ref(cert); + + return 1; +} + +int +ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *certs) +{ + X509_STORE_CTX *ctx = NULL; + X509_VERIFY_PARAM *param; + X509 *cert; + int ret = 0; + + if (sk_X509_num(certs) < 1) + goto err; + + if ((ctx = X509_STORE_CTX_new()) == NULL) + goto err; + + cert = sk_X509_value(certs, 0); + if (!X509_STORE_CTX_init(ctx, s->ctx->cert_store, cert, certs)) { + SSLerror(s, ERR_R_X509_LIB); + goto err; + } + X509_STORE_CTX_set_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); + + /* + * We need to inherit the verify parameters. These can be + * determined by the context: if its a server it will verify + * SSL client certificates or vice versa. + */ + X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server"); + + param = X509_STORE_CTX_get0_param(ctx); + + X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s)); + + /* + * Anything non-default in "param" should overwrite anything + * in the ctx. + */ + X509_VERIFY_PARAM_set1(param, s->param); + + if (s->verify_callback) + X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback); + + if (s->ctx->app_verify_callback != NULL) + ret = s->ctx->app_verify_callback(ctx, + s->ctx->app_verify_arg); + else + ret = X509_verify_cert(ctx); + + s->verify_result = X509_STORE_CTX_get_error(ctx); + sk_X509_pop_free(s->s3->hs.verified_chain, X509_free); + s->s3->hs.verified_chain = NULL; + if (X509_STORE_CTX_get0_chain(ctx) != NULL) { + s->s3->hs.verified_chain = X509_STORE_CTX_get1_chain(ctx); + if (s->s3->hs.verified_chain == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + ret = 0; + } + } + + err: + X509_STORE_CTX_free(ctx); + + return (ret); +} + +static void +set_client_CA_list(STACK_OF(X509_NAME) **ca_list, + STACK_OF(X509_NAME) *name_list) +{ + sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); + *ca_list = name_list; +} + +STACK_OF(X509_NAME) * +SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) +{ + int i; + STACK_OF(X509_NAME) *ret; + X509_NAME *name = NULL; + + if ((ret = sk_X509_NAME_new_null()) == NULL) + goto err; + + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + if ((name = X509_NAME_dup(sk_X509_NAME_value(sk, i))) == NULL) + goto err; + if (!sk_X509_NAME_push(ret, name)) + goto err; + } + return (ret); + + err: + X509_NAME_free(name); + sk_X509_NAME_pop_free(ret, X509_NAME_free); + return NULL; +} +LSSL_ALIAS(SSL_dup_CA_list); + +void +SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(s->client_CA), name_list); +} +LSSL_ALIAS(SSL_set_client_CA_list); + +void +SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(ctx->client_CA), name_list); +} +LSSL_ALIAS(SSL_CTX_set_client_CA_list); + +STACK_OF(X509_NAME) * +SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) +{ + return (ctx->client_CA); +} +LSSL_ALIAS(SSL_CTX_get_client_CA_list); + +STACK_OF(X509_NAME) * +SSL_get_client_CA_list(const SSL *s) +{ + if (!s->server) { + /* We are in the client. */ + if ((s->version >> 8) == SSL3_VERSION_MAJOR) + return (s->s3->hs.tls12.ca_names); + else + return (NULL); + } else { + if (s->client_CA != NULL) + return (s->client_CA); + else + return (s->ctx->client_CA); + } +} +LSSL_ALIAS(SSL_get_client_CA_list); + +static int +add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) +{ + X509_NAME *name; + + if (x == NULL) + return (0); + if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) + return (0); + + if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) + return (0); + + if (!sk_X509_NAME_push(*sk, name)) { + X509_NAME_free(name); + return (0); + } + return (1); +} + +int +SSL_add_client_CA(SSL *ssl, X509 *x) +{ + return (add_client_CA(&(ssl->client_CA), x)); +} +LSSL_ALIAS(SSL_add_client_CA); + +int +SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + return (add_client_CA(&(ctx->client_CA), x)); +} +LSSL_ALIAS(SSL_CTX_add_client_CA); + +static int +xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +/*! + * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; + * it doesn't really have anything to do with clients (except that a common use + * for a stack of CAs is to send it to the client). Actually, it doesn't have + * much to do with CAs, either, since it will load any old cert. + * \param file the file containing one or more certs. + * \return a ::STACK containing the certs. + */ +STACK_OF(X509_NAME) * +SSL_load_client_CA_file(const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + STACK_OF(X509_NAME) *ret = NULL, *sk; + + sk = sk_X509_NAME_new(xname_cmp); + + in = BIO_new(BIO_s_file()); + + if ((sk == NULL) || (in == NULL)) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if (ret == NULL) { + ret = sk_X509_NAME_new_null(); + if (ret == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + } + if ((xn = X509_get_subject_name(x)) == NULL) + goto err; + /* check for duplicates */ + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(sk, xn) >= 0) + X509_NAME_free(xn); + else { + if (!sk_X509_NAME_push(sk, xn)) + goto err; + if (!sk_X509_NAME_push(ret, xn)) + goto err; + } + } + + if (0) { + err: + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + sk_X509_NAME_free(sk); + BIO_free(in); + X509_free(x); + if (ret != NULL) + ERR_clear_error(); + + return (ret); +} +LSSL_ALIAS(SSL_load_client_CA_file); + +/*! + * Add a file of certs to a stack. + * \param stack the stack to add to. + * \param file the file to add from. All certs in this file that are not + * already in the stack will be added. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int +SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + int ret = 1; + int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + + in = BIO_new(BIO_s_file()); + + if (in == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if ((xn = X509_get_subject_name(x)) == NULL) + goto err; + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(stack, xn) >= 0) + X509_NAME_free(xn); + else + if (!sk_X509_NAME_push(stack, xn)) + goto err; + } + + ERR_clear_error(); + + if (0) { + err: + ret = 0; + } + BIO_free(in); + X509_free(x); + + (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} +LSSL_ALIAS(SSL_add_file_cert_subjects_to_stack); + +/*! + * Add a directory of certs to a stack. + * \param stack the stack to append to. + * \param dir the directory to append from. All files in this directory will be + * examined as potential certs. Any that are acceptable to + * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will + * be included. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int +SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir) +{ + DIR *dirp = NULL; + char *path = NULL; + int ret = 0; + + dirp = opendir(dir); + if (dirp) { + struct dirent *dp; + while ((dp = readdir(dirp)) != NULL) { + if (asprintf(&path, "%s/%s", dir, dp->d_name) != -1) { + ret = SSL_add_file_cert_subjects_to_stack( + stack, path); + free(path); + } + if (!ret) + break; + } + (void) closedir(dirp); + } + if (!ret) { + SYSerror(errno); + ERR_asprintf_error_data("opendir ('%s')", dir); + SSLerrorx(ERR_R_SYS_LIB); + } + return ret; +} +LSSL_ALIAS(SSL_add_dir_cert_subjects_to_stack); diff --git a/Libraries/libressl/ssl/ssl_ciph.c b/Libraries/libressl/ssl/ssl_ciph.c new file mode 100644 index 000000000..b735cd7b3 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_ciph.c @@ -0,0 +1,1768 @@ +/* $OpenBSD: ssl_ciph.c,v 1.136 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "ssl_local.h" + +#define CIPHER_ADD 1 +#define CIPHER_KILL 2 +#define CIPHER_DEL 3 +#define CIPHER_ORD 4 +#define CIPHER_SPECIAL 5 + +typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + int active; + int dead; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +static const SSL_CIPHER cipher_aliases[] = { + + /* "ALL" doesn't include eNULL (must be specifically enabled) */ + { + .name = SSL_TXT_ALL, + .algorithm_enc = ~SSL_eNULL, + }, + + /* "COMPLEMENTOFALL" */ + { + .name = SSL_TXT_CMPALL, + .algorithm_enc = SSL_eNULL, + }, + + /* + * "COMPLEMENTOFDEFAULT" + * (does *not* include ciphersuites not found in ALL!) + */ + { + .name = SSL_TXT_CMPDEF, + .algorithm_mkey = SSL_kDHE|SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = ~SSL_eNULL, + }, + + /* + * key exchange aliases + * (some of those using only a single bit here combine multiple key + * exchange algs according to the RFCs, e.g. kEDH combines DHE_DSS + * and DHE_RSA) + */ + { + .name = SSL_TXT_kRSA, + .algorithm_mkey = SSL_kRSA, + }, + { + .name = SSL_TXT_kEDH, + .algorithm_mkey = SSL_kDHE, + }, + { + .name = SSL_TXT_DH, + .algorithm_mkey = SSL_kDHE, + }, + { + .name = SSL_TXT_kEECDH, + .algorithm_mkey = SSL_kECDHE, + }, + { + .name = SSL_TXT_ECDH, + .algorithm_mkey = SSL_kECDHE, + }, + { + .name = SSL_TXT_kGOST, + .algorithm_mkey = SSL_kGOST, + }, + + /* server authentication aliases */ + { + .name = SSL_TXT_aRSA, + .algorithm_auth = SSL_aRSA, + }, + { + .name = SSL_TXT_aDSS, + .algorithm_auth = SSL_aDSS, + }, + { + .name = SSL_TXT_DSS, + .algorithm_auth = SSL_aDSS, + }, + { + .name = SSL_TXT_aNULL, + .algorithm_auth = SSL_aNULL, + }, + { + .name = SSL_TXT_aECDSA, + .algorithm_auth = SSL_aECDSA, + }, + { + .name = SSL_TXT_ECDSA, + .algorithm_auth = SSL_aECDSA, + }, + { + .name = SSL_TXT_aGOST01, + .algorithm_auth = SSL_aGOST01, + }, + { + .name = SSL_TXT_aGOST, + .algorithm_auth = SSL_aGOST01, + }, + + /* aliases combining key exchange and server authentication */ + { + .name = SSL_TXT_DHE, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_EDH, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_ECDHE, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_EECDH, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_NULL, + .algorithm_enc = SSL_eNULL, + }, + { + .name = SSL_TXT_RSA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + }, + { + .name = SSL_TXT_ADH, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + }, + { + .name = SSL_TXT_AECDH, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + }, + + /* symmetric encryption aliases */ + { + .name = SSL_TXT_3DES, + .algorithm_enc = SSL_3DES, + }, + { + .name = SSL_TXT_RC4, + .algorithm_enc = SSL_RC4, + }, + { + .name = SSL_TXT_eNULL, + .algorithm_enc = SSL_eNULL, + }, + { + .name = SSL_TXT_AES128, + .algorithm_enc = SSL_AES128|SSL_AES128GCM, + }, + { + .name = SSL_TXT_AES256, + .algorithm_enc = SSL_AES256|SSL_AES256GCM, + }, + { + .name = SSL_TXT_AES, + .algorithm_enc = SSL_AES, + }, + { + .name = SSL_TXT_AES_GCM, + .algorithm_enc = SSL_AES128GCM|SSL_AES256GCM, + }, + { + .name = SSL_TXT_CAMELLIA128, + .algorithm_enc = SSL_CAMELLIA128, + }, + { + .name = SSL_TXT_CAMELLIA256, + .algorithm_enc = SSL_CAMELLIA256, + }, + { + .name = SSL_TXT_CAMELLIA, + .algorithm_enc = SSL_CAMELLIA128|SSL_CAMELLIA256, + }, + { + .name = SSL_TXT_CHACHA20, + .algorithm_enc = SSL_CHACHA20POLY1305, + }, + + /* MAC aliases */ + { + .name = SSL_TXT_AEAD, + .algorithm_mac = SSL_AEAD, + }, + { + .name = SSL_TXT_MD5, + .algorithm_mac = SSL_MD5, + }, + { + .name = SSL_TXT_SHA1, + .algorithm_mac = SSL_SHA1, + }, + { + .name = SSL_TXT_SHA, + .algorithm_mac = SSL_SHA1, + }, + { + .name = SSL_TXT_GOST94, + .algorithm_mac = SSL_GOST94, + }, + { + .name = SSL_TXT_GOST89MAC, + .algorithm_mac = SSL_GOST89MAC, + }, + { + .name = SSL_TXT_SHA256, + .algorithm_mac = SSL_SHA256, + }, + { + .name = SSL_TXT_SHA384, + .algorithm_mac = SSL_SHA384, + }, + { + .name = SSL_TXT_STREEBOG256, + .algorithm_mac = SSL_STREEBOG256, + }, + + /* protocol version aliases */ + { + .name = SSL_TXT_SSLV3, + .algorithm_ssl = SSL_SSLV3, + }, + { + .name = SSL_TXT_TLSV1, + .algorithm_ssl = SSL_TLSV1, + }, + { + .name = SSL_TXT_TLSV1_2, + .algorithm_ssl = SSL_TLSV1_2, + }, + { + .name = SSL_TXT_TLSV1_3, + .algorithm_ssl = SSL_TLSV1_3, + }, + + /* cipher suite aliases */ +#ifdef LIBRESSL_HAS_TLS1_3 + { + .valid = 1, + .name = "TLS_AES_128_GCM_SHA256", + .id = TLS1_3_CK_AES_128_GCM_SHA256, + .algorithm_ssl = SSL_TLSV1_3, + }, + { + .valid = 1, + .name = "TLS_AES_256_GCM_SHA384", + .id = TLS1_3_CK_AES_256_GCM_SHA384, + .algorithm_ssl = SSL_TLSV1_3, + }, + { + .valid = 1, + .name = "TLS_CHACHA20_POLY1305_SHA256", + .id = TLS1_3_CK_CHACHA20_POLY1305_SHA256, + .algorithm_ssl = SSL_TLSV1_3, + }, +#endif + + /* strength classes */ + { + .name = SSL_TXT_LOW, + .algo_strength = SSL_LOW, + }, + { + .name = SSL_TXT_MEDIUM, + .algo_strength = SSL_MEDIUM, + }, + { + .name = SSL_TXT_HIGH, + .algo_strength = SSL_HIGH, + }, +}; + +int +ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size) +{ + *enc = NULL; + *md = NULL; + *mac_pkey_type = NID_undef; + *mac_secret_size = 0; + + if (ss->cipher == NULL) + return 0; + + /* + * This function does not handle EVP_AEAD. + * See ssl_cipher_get_evp_aead instead. + */ + if (ss->cipher->algorithm_mac & SSL_AEAD) + return 0; + + switch (ss->cipher->algorithm_enc) { + case SSL_3DES: + *enc = EVP_des_ede3_cbc(); + break; + case SSL_RC4: + *enc = EVP_rc4(); + break; + case SSL_eNULL: + *enc = EVP_enc_null(); + break; + case SSL_AES128: + *enc = EVP_aes_128_cbc(); + break; + case SSL_AES256: + *enc = EVP_aes_256_cbc(); + break; + case SSL_CAMELLIA128: + *enc = EVP_camellia_128_cbc(); + break; + case SSL_CAMELLIA256: + *enc = EVP_camellia_256_cbc(); + break; +#ifndef OPENSSL_NO_GOST + case SSL_eGOST2814789CNT: + *enc = EVP_gost2814789_cnt(); + break; +#endif + } + + switch (ss->cipher->algorithm_mac) { + case SSL_MD5: + *md = EVP_md5(); + break; + case SSL_SHA1: + *md = EVP_sha1(); + break; + case SSL_SHA256: + *md = EVP_sha256(); + break; + case SSL_SHA384: + *md = EVP_sha384(); + break; +#ifndef OPENSSL_NO_GOST + case SSL_GOST89MAC: + *md = EVP_gost2814789imit(); + break; + case SSL_GOST94: + *md = EVP_gostr341194(); + break; + case SSL_STREEBOG256: + *md = EVP_streebog256(); + break; +#endif + } + if (*enc == NULL || *md == NULL) + return 0; + + /* + * EVP_CIPH_FLAG_AEAD_CIPHER and EVP_CIPH_GCM_MODE ciphers are not + * supported via EVP_CIPHER (they should be using EVP_AEAD instead). + */ + if (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER) + return 0; + if (EVP_CIPHER_mode(*enc) == EVP_CIPH_GCM_MODE) + return 0; +#ifndef OPENSSL_NO_GOST + /* XXX JFC. die in fire already */ + if (ss->cipher->algorithm_mac == SSL_GOST89MAC) { + *mac_pkey_type = EVP_PKEY_GOSTIMIT; + *mac_secret_size = 32; /* XXX */ + } else { +#endif + *mac_pkey_type = EVP_PKEY_HMAC; + *mac_secret_size = EVP_MD_size(*md); +#ifndef OPENSSL_NO_GOST + } +#endif + return 1; +} + +/* + * ssl_cipher_get_evp_aead sets aead to point to the correct EVP_AEAD object + * for s->cipher. It returns 1 on success and 0 on error. + */ +int +ssl_cipher_get_evp_aead(const SSL_SESSION *ss, const EVP_AEAD **aead) +{ + *aead = NULL; + + if (ss->cipher == NULL) + return 0; + if ((ss->cipher->algorithm_mac & SSL_AEAD) == 0) + return 0; + + switch (ss->cipher->algorithm_enc) { + case SSL_AES128GCM: + *aead = EVP_aead_aes_128_gcm(); + return 1; + case SSL_AES256GCM: + *aead = EVP_aead_aes_256_gcm(); + return 1; + case SSL_CHACHA20POLY1305: + *aead = EVP_aead_chacha20_poly1305(); + return 1; + default: + break; + } + return 0; +} + +int +ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md) +{ + unsigned long handshake_mac; + + *md = NULL; + + if (s->s3->hs.cipher == NULL) + return 0; + + handshake_mac = s->s3->hs.cipher->algorithm2 & + SSL_HANDSHAKE_MAC_MASK; + + /* For TLSv1.2 we upgrade the default MD5+SHA1 MAC to SHA256. */ + if (SSL_USE_SHA256_PRF(s) && handshake_mac == SSL_HANDSHAKE_MAC_DEFAULT) + handshake_mac = SSL_HANDSHAKE_MAC_SHA256; + + switch (handshake_mac) { + case SSL_HANDSHAKE_MAC_DEFAULT: + *md = EVP_md5_sha1(); + return 1; +#ifndef OPENSSL_NO_GOST + case SSL_HANDSHAKE_MAC_GOST94: + *md = EVP_gostr341194(); + return 1; + case SSL_HANDSHAKE_MAC_STREEBOG256: + *md = EVP_streebog256(); + return 1; +#endif + case SSL_HANDSHAKE_MAC_SHA256: + *md = EVP_sha256(); + return 1; + case SSL_HANDSHAKE_MAC_SHA384: + *md = EVP_sha384(); + return 1; + default: + break; + } + + return 0; +} + +#define ITEM_SEP(a) \ + (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) + +static void +ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *tail) + return; + if (curr == *head) + *head = curr->next; + if (curr->prev != NULL) + curr->prev->next = curr->next; + if (curr->next != NULL) + curr->next->prev = curr->prev; + (*tail)->next = curr; + curr->prev= *tail; + curr->next = NULL; + *tail = curr; +} + +static void +ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *head) + return; + if (curr == *tail) + *tail = curr->prev; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + (*head)->prev = curr; + curr->next= *head; + curr->prev = NULL; + *head = curr; +} + +static void +ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, + unsigned long *enc, unsigned long *mac, unsigned long *ssl) +{ + *mkey = 0; + *auth = 0; + *enc = 0; + *mac = 0; + *ssl = 0; + + /* + * Check for the availability of GOST 34.10 public/private key + * algorithms. If they are not available disable the associated + * authentication and key exchange algorithms. + */ + if (EVP_PKEY_meth_find(NID_id_GostR3410_2001) == NULL) { + *auth |= SSL_aGOST01; + *mkey |= SSL_kGOST; + } + +#ifdef SSL_FORBID_ENULL + *enc |= SSL_eNULL; +#endif +} + +static void +ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, int num_of_ciphers, + unsigned long disabled_mkey, unsigned long disabled_auth, + unsigned long disabled_enc, unsigned long disabled_mac, + unsigned long disabled_ssl, CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) +{ + int i, co_list_num; + const SSL_CIPHER *c; + + /* + * We have num_of_ciphers descriptions compiled in, depending on the + * method selected (SSLv3, TLSv1, etc). These will later be sorted in + * a linked list with at most num entries. + */ + + /* Get the initial list of ciphers */ + co_list_num = 0; /* actual count of ciphers */ + for (i = 0; i < num_of_ciphers; i++) { + c = ssl_method->get_cipher(i); + /* + * Drop any invalid ciphers and any which use unavailable + * algorithms. + */ + if ((c != NULL) && c->valid && + !(c->algorithm_mkey & disabled_mkey) && + !(c->algorithm_auth & disabled_auth) && + !(c->algorithm_enc & disabled_enc) && + !(c->algorithm_mac & disabled_mac) && + !(c->algorithm_ssl & disabled_ssl)) { + co_list[co_list_num].cipher = c; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = 0; + co_list_num++; + } + } + + /* + * Prepare linked list from list entries + */ + if (co_list_num > 0) { + co_list[0].prev = NULL; + + if (co_list_num > 1) { + co_list[0].next = &co_list[1]; + + for (i = 1; i < co_list_num - 1; i++) { + co_list[i].prev = &co_list[i - 1]; + co_list[i].next = &co_list[i + 1]; + } + + co_list[co_list_num - 1].prev = + &co_list[co_list_num - 2]; + } + + co_list[co_list_num - 1].next = NULL; + + *head_p = &co_list[0]; + *tail_p = &co_list[co_list_num - 1]; + } +} + +static void +ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, int num_of_group_aliases, + unsigned long disabled_mkey, unsigned long disabled_auth, + unsigned long disabled_enc, unsigned long disabled_mac, + unsigned long disabled_ssl, CIPHER_ORDER *head) +{ + CIPHER_ORDER *ciph_curr; + const SSL_CIPHER **ca_curr; + int i; + unsigned long mask_mkey = ~disabled_mkey; + unsigned long mask_auth = ~disabled_auth; + unsigned long mask_enc = ~disabled_enc; + unsigned long mask_mac = ~disabled_mac; + unsigned long mask_ssl = ~disabled_ssl; + + /* + * First, add the real ciphers as already collected + */ + ciph_curr = head; + ca_curr = ca_list; + while (ciph_curr != NULL) { + *ca_curr = ciph_curr->cipher; + ca_curr++; + ciph_curr = ciph_curr->next; + } + + /* + * Now we add the available ones from the cipher_aliases[] table. + * They represent either one or more algorithms, some of which + * in any affected category must be supported (set in enabled_mask), + * or represent a cipher strength value (will be added in any case because algorithms=0). + */ + for (i = 0; i < num_of_group_aliases; i++) { + unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; + unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; + unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; + unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; + unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; + + if (algorithm_mkey) + if ((algorithm_mkey & mask_mkey) == 0) + continue; + + if (algorithm_auth) + if ((algorithm_auth & mask_auth) == 0) + continue; + + if (algorithm_enc) + if ((algorithm_enc & mask_enc) == 0) + continue; + + if (algorithm_mac) + if ((algorithm_mac & mask_mac) == 0) + continue; + + if (algorithm_ssl) + if ((algorithm_ssl & mask_ssl) == 0) + continue; + + *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); + ca_curr++; + } + + *ca_curr = NULL; /* end of list */ +} + +static void +ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long alg_mkey, + unsigned long alg_auth, unsigned long alg_enc, unsigned long alg_mac, + unsigned long alg_ssl, unsigned long algo_strength, int rule, + int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) +{ + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + int reverse = 0; + + if (rule == CIPHER_DEL) + reverse = 1; /* needed to maintain sorting between currently deleted ciphers */ + + head = *head_p; + tail = *tail_p; + + if (reverse) { + next = tail; + last = head; + } else { + next = head; + last = tail; + } + + curr = NULL; + for (;;) { + if (curr == last) + break; + curr = next; + next = reverse ? curr->prev : curr->next; + + cp = curr->cipher; + + if (cipher_id && cp->id != cipher_id) + continue; + + /* + * Selection criteria is either the value of strength_bits + * or the algorithms used. + */ + if (strength_bits >= 0) { + if (strength_bits != cp->strength_bits) + continue; + } else { + if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) + continue; + if (alg_auth && !(alg_auth & cp->algorithm_auth)) + continue; + if (alg_enc && !(alg_enc & cp->algorithm_enc)) + continue; + if (alg_mac && !(alg_mac & cp->algorithm_mac)) + continue; + if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) + continue; + if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) + continue; + } + + /* add the cipher if it has not been added yet. */ + if (rule == CIPHER_ADD) { + /* reverse == 0 */ + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = 1; + } + } + /* Move the added cipher to this location */ + else if (rule == CIPHER_ORD) { + /* reverse == 0 */ + if (curr->active) { + ll_append_tail(&head, curr, &tail); + } + } else if (rule == CIPHER_DEL) { + /* reverse == 1 */ + if (curr->active) { + /* most recently deleted ciphersuites get best positions + * for any future CIPHER_ADD (note that the CIPHER_DEL loop + * works in reverse to maintain the order) */ + ll_append_head(&head, curr, &tail); + curr->active = 0; + } + } else if (rule == CIPHER_KILL) { + /* reverse == 0 */ + if (head == curr) + head = curr->next; + else + curr->prev->next = curr->next; + if (tail == curr) + tail = curr->prev; + curr->active = 0; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + curr->next = NULL; + curr->prev = NULL; + } + } + + *head_p = head; + *tail_p = tail; +} + +static int +ssl_cipher_strength_sort(CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) +{ + int max_strength_bits, i, *number_uses; + CIPHER_ORDER *curr; + + /* + * This routine sorts the ciphers with descending strength. The sorting + * must keep the pre-sorted sequence, so we apply the normal sorting + * routine as '+' movement to the end of the list. + */ + max_strength_bits = 0; + curr = *head_p; + while (curr != NULL) { + if (curr->active && + (curr->cipher->strength_bits > max_strength_bits)) + max_strength_bits = curr->cipher->strength_bits; + curr = curr->next; + } + + number_uses = calloc((max_strength_bits + 1), sizeof(int)); + if (!number_uses) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (0); + } + + /* + * Now find the strength_bits values actually used + */ + curr = *head_p; + while (curr != NULL) { + if (curr->active) + number_uses[curr->cipher->strength_bits]++; + curr = curr->next; + } + /* + * Go through the list of used strength_bits values in descending + * order. + */ + for (i = max_strength_bits; i >= 0; i--) + if (number_uses[i] > 0) + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p); + + free(number_uses); + return (1); +} + +static int +ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, const SSL_CIPHER **ca_list, SSL_CERT *cert, + int *tls13_seen) +{ + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl; + unsigned long algo_strength; + int j, multi, found, rule, retval, ok, buflen; + unsigned long cipher_id = 0; + const char *l, *buf; + char ch; + + *tls13_seen = 0; + + retval = 1; + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') + break; + + if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; + } else { + rule = CIPHER_ADD; + } + + if (ITEM_SEP(ch)) { + l++; + continue; + } + + alg_mkey = 0; + alg_auth = 0; + alg_enc = 0; + alg_mac = 0; + alg_ssl = 0; + algo_strength = 0; + + for (;;) { + ch = *l; + buf = l; + buflen = 0; + while (((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || + (ch == '-') || (ch == '.') || + (ch == '_') || (ch == '=')) { + ch = *(++l); + buflen++; + } + + if (buflen == 0) { + /* + * We hit something we cannot deal with, + * it is no command or separator nor + * alphanumeric, so we call this an error. + */ + SSLerrorx(SSL_R_INVALID_COMMAND); + return 0; + } + + if (rule == CIPHER_SPECIAL) { + /* unused -- avoid compiler warning */ + found = 0; + /* special treatment */ + break; + } + + /* check for multi-part specification */ + if (ch == '+') { + multi = 1; + l++; + } else + multi = 0; + + /* + * Now search for the cipher alias in the ca_list. + * Be careful with the strncmp, because the "buflen" + * limitation will make the rule "ADH:SOME" and the + * cipher "ADH-MY-CIPHER" look like a match for + * buflen=3. So additionally check whether the cipher + * name found has the correct length. We can save a + * strlen() call: just checking for the '\0' at the + * right place is sufficient, we have to strncmp() + * anyway (we cannot use strcmp(), because buf is not + * '\0' terminated.) + */ + j = found = 0; + cipher_id = 0; + while (ca_list[j]) { + if (!strncmp(buf, ca_list[j]->name, buflen) && + (ca_list[j]->name[buflen] == '\0')) { + found = 1; + break; + } else + j++; + } + + if (!found) + break; /* ignore this entry */ + + if (ca_list[j]->algorithm_mkey) { + if (alg_mkey) { + alg_mkey &= ca_list[j]->algorithm_mkey; + if (!alg_mkey) { + found = 0; + break; + } + } else + alg_mkey = ca_list[j]->algorithm_mkey; + } + + if (ca_list[j]->algorithm_auth) { + if (alg_auth) { + alg_auth &= ca_list[j]->algorithm_auth; + if (!alg_auth) { + found = 0; + break; + } + } else + alg_auth = ca_list[j]->algorithm_auth; + } + + if (ca_list[j]->algorithm_enc) { + if (alg_enc) { + alg_enc &= ca_list[j]->algorithm_enc; + if (!alg_enc) { + found = 0; + break; + } + } else + alg_enc = ca_list[j]->algorithm_enc; + } + + if (ca_list[j]->algorithm_mac) { + if (alg_mac) { + alg_mac &= ca_list[j]->algorithm_mac; + if (!alg_mac) { + found = 0; + break; + } + } else + alg_mac = ca_list[j]->algorithm_mac; + } + + if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { + if (algo_strength & SSL_STRONG_MASK) { + algo_strength &= + (ca_list[j]->algo_strength & + SSL_STRONG_MASK) | ~SSL_STRONG_MASK; + if (!(algo_strength & + SSL_STRONG_MASK)) { + found = 0; + break; + } + } else + algo_strength |= + ca_list[j]->algo_strength & + SSL_STRONG_MASK; + } + + if (ca_list[j]->valid) { + /* + * explicit ciphersuite found; its protocol + * version does not become part of the search + * pattern! + */ + cipher_id = ca_list[j]->id; + if (ca_list[j]->algorithm_ssl == SSL_TLSV1_3) + *tls13_seen = 1; + } else { + /* + * not an explicit ciphersuite; only in this + * case, the protocol version is considered + * part of the search pattern + */ + if (ca_list[j]->algorithm_ssl) { + if (alg_ssl) { + alg_ssl &= + ca_list[j]->algorithm_ssl; + if (!alg_ssl) { + found = 0; + break; + } + } else + alg_ssl = + ca_list[j]->algorithm_ssl; + } + } + + if (!multi) + break; + } + + /* + * Ok, we have the rule, now apply it + */ + if (rule == CIPHER_SPECIAL) { + /* special command */ + ok = 0; + if (buflen == 8 && strncmp(buf, "STRENGTH", 8) == 0) { + ok = ssl_cipher_strength_sort(head_p, tail_p); + } else if (buflen == 10 && + strncmp(buf, "SECLEVEL=", 9) == 0) { + int level = buf[9] - '0'; + + if (level >= 0 && level <= 5) { + cert->security_level = level; + ok = 1; + } else { + SSLerrorx(SSL_R_INVALID_COMMAND); + } + } else { + SSLerrorx(SSL_R_INVALID_COMMAND); + } + if (ok == 0) + retval = 0; + + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } else if (found) { + if (alg_ssl == SSL_TLSV1_3) + *tls13_seen = 1; + ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, + alg_enc, alg_mac, alg_ssl, algo_strength, rule, + -1, head_p, tail_p); + } else { + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } + if (*l == '\0') + break; /* done */ + } + + return (retval); +} + +static inline int +ssl_aes_is_accelerated(void) +{ +#if defined(__i386__) || defined(__x86_64__) + return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); +#else + return (0); +#endif +} + +STACK_OF(SSL_CIPHER) * +ssl_create_cipher_list(const SSL_METHOD *ssl_method, + STACK_OF(SSL_CIPHER) **cipher_list, + STACK_OF(SSL_CIPHER) *cipher_list_tls13, + const char *rule_str, SSL_CERT *cert) +{ + int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; + unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl; + STACK_OF(SSL_CIPHER) *cipherstack = NULL, *ret = NULL; + const char *rule_p; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + const SSL_CIPHER **ca_list = NULL; + const SSL_CIPHER *cipher; + int tls13_seen = 0; + int any_active; + int i; + + /* + * Return with error if nothing to do. + */ + if (rule_str == NULL || cipher_list == NULL) + goto err; + + /* + * To reduce the work to do we only want to process the compiled + * in algorithms, so we first get the mask of disabled ciphers. + */ + ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl); + + /* + * Now we have to collect the available ciphers from the compiled + * in ciphers. We cannot get more than the number compiled in, so + * it is used for allocation. + */ + num_of_ciphers = ssl3_num_ciphers(); + co_list = reallocarray(NULL, num_of_ciphers, sizeof(CIPHER_ORDER)); + if (co_list == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + + ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, + disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl, + co_list, &head, &tail); + + + /* Now arrange all ciphers by preference: */ + + /* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */ + ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + if (ssl_aes_is_accelerated()) { + /* + * We have hardware assisted AES - prefer AES as a symmetric + * cipher, with CHACHA20 second. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, + CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, + 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + } else { + /* + * CHACHA20 is fast and safe on all hardware and is thus our + * preferred symmetric cipher, with AES second. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, + 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, + CIPHER_ADD, -1, &head, &tail); + } + + /* Temporarily enable everything else for sorting */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + + /* Low priority for MD5 */ + ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Move anonymous ciphers to the end. Usually, these will remain disabled. + * (For applications that allow them, they aren't too bad, but we prefer + * authenticated ciphers.) */ + ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Move ciphers without forward secrecy to the end */ + ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* RC4 is sort of broken - move it to the end */ + ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Now sort by symmetric encryption strength. The above ordering remains + * in force within each class */ + if (!ssl_cipher_strength_sort(&head, &tail)) + goto err; + + /* Now disable everything (maintaining the ordering!) */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + /* TLSv1.3 first. */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_3, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_3, 0, CIPHER_DEL, -1, &head, &tail); + + /* + * We also need cipher aliases for selecting based on the rule_str. + * There might be two types of entries in the rule_str: 1) names + * of ciphers themselves 2) aliases for groups of ciphers. + * For 1) we need the available ciphers and for 2) the cipher + * groups of cipher_aliases added together in one list (otherwise + * we would be happy with just the cipher_aliases table). + */ + num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; + ca_list = reallocarray(NULL, num_of_alias_max, sizeof(SSL_CIPHER *)); + if (ca_list == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mkey, + disabled_auth, disabled_enc, disabled_mac, disabled_ssl, head); + + /* + * If the rule_string begins with DEFAULT, apply the default rule + * before using the (possibly available) additional rules. + */ + ok = 1; + rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, + &head, &tail, ca_list, cert, &tls13_seen); + rule_p += 7; + if (*rule_p == ':') + rule_p++; + } + + if (ok && (strlen(rule_p) > 0)) + ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, + cert, &tls13_seen); + + if (!ok) { + /* Rule processing failure */ + goto err; + } + + /* + * Allocate new "cipherstack" for the result, return with error + * if we cannot get one. + */ + if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Prefer TLSv1.3 cipher suites. */ + if (cipher_list_tls13 != NULL) { + for (i = 0; i < sk_SSL_CIPHER_num(cipher_list_tls13); i++) { + cipher = sk_SSL_CIPHER_value(cipher_list_tls13, i); + if (!sk_SSL_CIPHER_push(cipherstack, cipher)) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + } + tls13_seen = 1; + } + + /* + * The cipher selection for the list is done. The ciphers are added + * to the resulting precedence to the STACK_OF(SSL_CIPHER). + * + * If the rule string did not contain any references to TLSv1.3 and + * TLSv1.3 cipher suites have not been configured separately, + * include inactive TLSv1.3 cipher suites. This avoids attempts to + * use TLSv1.3 with an older rule string that does not include + * TLSv1.3 cipher suites. If the rule string resulted in no active + * cipher suites then we return an empty stack. + */ + any_active = 0; + for (curr = head; curr != NULL; curr = curr->next) { + if (curr->active || + (!tls13_seen && curr->cipher->algorithm_ssl == SSL_TLSV1_3)) { + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + } + any_active |= curr->active; + } + if (!any_active) + sk_SSL_CIPHER_zero(cipherstack); + + sk_SSL_CIPHER_free(*cipher_list); + *cipher_list = cipherstack; + cipherstack = NULL; + + ret = *cipher_list; + + err: + sk_SSL_CIPHER_free(cipherstack); + free((void *)ca_list); + free(co_list); + + return ret; +} + +const SSL_CIPHER * +SSL_CIPHER_get_by_id(unsigned int id) +{ + return ssl3_get_cipher_by_id(id); +} +LSSL_ALIAS(SSL_CIPHER_get_by_id); + +const SSL_CIPHER * +SSL_CIPHER_get_by_value(uint16_t value) +{ + return ssl3_get_cipher_by_value(value); +} +LSSL_ALIAS(SSL_CIPHER_get_by_value); + +char * +SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +{ + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; + const char *ver, *kx, *au, *enc, *mac; + char *ret; + int l; + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + alg_ssl = cipher->algorithm_ssl; + + alg2 = cipher->algorithm2; + + if (alg_ssl & SSL_SSLV3) + ver = "SSLv3"; + else if (alg_ssl & SSL_TLSV1_2) + ver = "TLSv1.2"; + else if (alg_ssl & SSL_TLSV1_3) + ver = "TLSv1.3"; + else + ver = "unknown"; + + switch (alg_mkey) { + case SSL_kRSA: + kx = "RSA"; + break; + case SSL_kDHE: + kx = "DH"; + break; + case SSL_kECDHE: + kx = "ECDH"; + break; + case SSL_kGOST: + kx = "GOST"; + break; + case SSL_kTLS1_3: + kx = "TLSv1.3"; + break; + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + case SSL_aDSS: + au = "DSS"; + break; + case SSL_aNULL: + au = "None"; + break; + case SSL_aECDSA: + au = "ECDSA"; + break; + case SSL_aGOST01: + au = "GOST01"; + break; + case SSL_aTLS1_3: + au = "TLSv1.3"; + break; + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_3DES: + enc = "3DES(168)"; + break; + case SSL_RC4: + enc = alg2 & SSL2_CF_8_BYTE_ENC ? "RC4(64)" : "RC4(128)"; + break; + case SSL_eNULL: + enc = "None"; + break; + case SSL_AES128: + enc = "AES(128)"; + break; + case SSL_AES256: + enc = "AES(256)"; + break; + case SSL_AES128GCM: + enc = "AESGCM(128)"; + break; + case SSL_AES256GCM: + enc = "AESGCM(256)"; + break; + case SSL_CAMELLIA128: + enc = "Camellia(128)"; + break; + case SSL_CAMELLIA256: + enc = "Camellia(256)"; + break; + case SSL_CHACHA20POLY1305: + enc = "ChaCha20-Poly1305"; + break; + case SSL_eGOST2814789CNT: + enc = "GOST-28178-89-CNT"; + break; + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_MD5: + mac = "MD5"; + break; + case SSL_SHA1: + mac = "SHA1"; + break; + case SSL_SHA256: + mac = "SHA256"; + break; + case SSL_SHA384: + mac = "SHA384"; + break; + case SSL_AEAD: + mac = "AEAD"; + break; + case SSL_GOST94: + mac = "GOST94"; + break; + case SSL_GOST89MAC: + mac = "GOST89IMIT"; + break; + case SSL_STREEBOG256: + mac = "STREEBOG256"; + break; + default: + mac = "unknown"; + break; + } + + if (asprintf(&ret, "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n", + cipher->name, ver, kx, au, enc, mac) == -1) + return "OPENSSL_malloc Error"; + + if (buf != NULL) { + l = strlcpy(buf, ret, len); + free(ret); + ret = buf; + if (l >= len) + ret = "Buffer too small"; + } + + return (ret); +} +LSSL_ALIAS(SSL_CIPHER_description); + +const char * +SSL_CIPHER_get_version(const SSL_CIPHER *c) +{ + if (c == NULL) + return("(NONE)"); + if ((c->id >> 24) == 3) + return("TLSv1/SSLv3"); + else + return("unknown"); +} +LSSL_ALIAS(SSL_CIPHER_get_version); + +/* return the actual cipher being used */ +const char * +SSL_CIPHER_get_name(const SSL_CIPHER *c) +{ + if (c != NULL) + return (c->name); + return("(NONE)"); +} +LSSL_ALIAS(SSL_CIPHER_get_name); + +/* number of bits for symmetric cipher */ +int +SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) +{ + int ret = 0; + + if (c != NULL) { + if (alg_bits != NULL) + *alg_bits = c->alg_bits; + ret = c->strength_bits; + } + return (ret); +} +LSSL_ALIAS(SSL_CIPHER_get_bits); + +unsigned long +SSL_CIPHER_get_id(const SSL_CIPHER *c) +{ + return c->id; +} +LSSL_ALIAS(SSL_CIPHER_get_id); + +uint16_t +SSL_CIPHER_get_value(const SSL_CIPHER *c) +{ + return ssl3_cipher_get_value(c); +} +LSSL_ALIAS(SSL_CIPHER_get_value); + +const SSL_CIPHER * +SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) +{ + uint16_t cipher_value; + CBS cbs; + + /* This API is documented with ptr being an array of length two. */ + CBS_init(&cbs, ptr, 2); + if (!CBS_get_u16(&cbs, &cipher_value)) + return NULL; + + return ssl3_get_cipher_by_value(cipher_value); +} +LSSL_ALIAS(SSL_CIPHER_find); + +int +SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c) +{ + switch (c->algorithm_enc) { + case SSL_eNULL: + return NID_undef; + case SSL_3DES: + return NID_des_ede3_cbc; + case SSL_AES128: + return NID_aes_128_cbc; + case SSL_AES128GCM: + return NID_aes_128_gcm; + case SSL_AES256: + return NID_aes_256_cbc; + case SSL_AES256GCM: + return NID_aes_256_gcm; + case SSL_CAMELLIA128: + return NID_camellia_128_cbc; + case SSL_CAMELLIA256: + return NID_camellia_256_cbc; + case SSL_CHACHA20POLY1305: + return NID_chacha20_poly1305; + case SSL_DES: + return NID_des_cbc; + case SSL_RC4: + return NID_rc4; + case SSL_eGOST2814789CNT: + return NID_gost89_cnt; + default: + return NID_undef; + } +} +LSSL_ALIAS(SSL_CIPHER_get_cipher_nid); + +int +SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c) +{ + switch (c->algorithm_mac) { + case SSL_AEAD: + return NID_undef; + case SSL_GOST89MAC: + return NID_id_Gost28147_89_MAC; + case SSL_GOST94: + return NID_id_GostR3411_94; + case SSL_MD5: + return NID_md5; + case SSL_SHA1: + return NID_sha1; + case SSL_SHA256: + return NID_sha256; + case SSL_SHA384: + return NID_sha384; + case SSL_STREEBOG256: + return NID_id_tc26_gost3411_2012_256; + default: + return NID_undef; + } +} +LSSL_ALIAS(SSL_CIPHER_get_digest_nid); + +int +SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c) +{ + switch (c->algorithm_mkey) { + case SSL_kDHE: + return NID_kx_dhe; + case SSL_kECDHE: + return NID_kx_ecdhe; + case SSL_kGOST: + return NID_kx_gost; + case SSL_kRSA: + return NID_kx_rsa; + default: + return NID_undef; + } +} +LSSL_ALIAS(SSL_CIPHER_get_kx_nid); + +int +SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c) +{ + switch (c->algorithm_auth) { + case SSL_aNULL: + return NID_auth_null; + case SSL_aECDSA: + return NID_auth_ecdsa; + case SSL_aGOST01: + return NID_auth_gost01; + case SSL_aRSA: + return NID_auth_rsa; + default: + return NID_undef; + } +} +LSSL_ALIAS(SSL_CIPHER_get_auth_nid); + +int +SSL_CIPHER_is_aead(const SSL_CIPHER *c) +{ + return (c->algorithm_mac & SSL_AEAD) == SSL_AEAD; +} +LSSL_ALIAS(SSL_CIPHER_is_aead); + +void * +SSL_COMP_get_compression_methods(void) +{ + return NULL; +} +LSSL_ALIAS(SSL_COMP_get_compression_methods); + +int +SSL_COMP_add_compression_method(int id, void *cm) +{ + return 1; +} +LSSL_ALIAS(SSL_COMP_add_compression_method); + +const char * +SSL_COMP_get_name(const void *comp) +{ + return NULL; +} +LSSL_ALIAS(SSL_COMP_get_name); diff --git a/Libraries/libressl/ssl/ssl_ciphers.c b/Libraries/libressl/ssl/ssl_ciphers.c new file mode 100644 index 000000000..4ec1b099b --- /dev/null +++ b/Libraries/libressl/ssl/ssl_ciphers.c @@ -0,0 +1,286 @@ +/* $OpenBSD: ssl_ciphers.c,v 1.17 2022/11/26 16:08:55 tb Exp $ */ +/* + * Copyright (c) 2015-2017 Doug Hogan + * Copyright (c) 2015-2018, 2020 Joel Sing + * Copyright (c) 2019 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bytestring.h" +#include "ssl_local.h" + +int +ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher) +{ + int i; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + if (sk_SSL_CIPHER_value(ciphers, i)->id == cipher->id) + return 1; + } + + return 0; +} + +int +ssl_cipher_allowed_in_tls_version_range(const SSL_CIPHER *cipher, uint16_t min_ver, + uint16_t max_ver) +{ + switch(cipher->algorithm_ssl) { + case SSL_SSLV3: + return (min_ver <= TLS1_2_VERSION); + case SSL_TLSV1_2: + return (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver); + case SSL_TLSV1_3: + return (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver); + } + return 0; +} + +int +ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb) +{ + SSL_CIPHER *cipher; + int num_ciphers = 0; + uint16_t min_vers, max_vers; + int i; + + if (ciphers == NULL) + return 0; + + if (!ssl_supported_tls_version_range(s, &min_vers, &max_vers)) + return 0; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL) + return 0; + if (!ssl_cipher_allowed_in_tls_version_range(cipher, min_vers, + max_vers)) + continue; + if (!ssl_security_cipher_check(s, cipher)) + continue; + if (!CBB_add_u16(cbb, ssl3_cipher_get_value(cipher))) + return 0; + + num_ciphers++; + } + + /* Add SCSV if there are other ciphers and we're not renegotiating. */ + if (num_ciphers > 0 && !s->renegotiate) { + if (!CBB_add_u16(cbb, SSL3_CK_SCSV & SSL3_CK_VALUE_MASK)) + return 0; + } + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +STACK_OF(SSL_CIPHER) * +ssl_bytes_to_cipher_list(SSL *s, CBS *cbs) +{ + STACK_OF(SSL_CIPHER) *ciphers = NULL; + const SSL_CIPHER *cipher; + uint16_t cipher_value; + unsigned long cipher_id; + + s->s3->send_connection_binding = 0; + + if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + while (CBS_len(cbs) > 0) { + if (!CBS_get_u16(cbs, &cipher_value)) { + SSLerror(s, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + goto err; + } + + cipher_id = SSL3_CK_ID | cipher_value; + + if (cipher_id == SSL3_CK_SCSV) { + /* + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if + * renegotiating. + */ + if (s->renegotiate) { + SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + + goto err; + } + s->s3->send_connection_binding = 1; + continue; + } + + if (cipher_id == SSL3_CK_FALLBACK_SCSV) { + /* + * TLS_FALLBACK_SCSV indicates that the client + * previously tried a higher protocol version. + * Fail if the current version is an unexpected + * downgrade. + */ + if (s->s3->hs.negotiated_tls_version < + s->s3->hs.our_max_tls_version) { + SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INAPPROPRIATE_FALLBACK); + goto err; + } + continue; + } + + if ((cipher = ssl3_get_cipher_by_value(cipher_value)) != NULL) { + if (!sk_SSL_CIPHER_push(ciphers, cipher)) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } + + return (ciphers); + + err: + sk_SSL_CIPHER_free(ciphers); + + return (NULL); +} + +struct ssl_tls13_ciphersuite { + const char *name; + const char *alias; + unsigned long cid; +}; + +static const struct ssl_tls13_ciphersuite ssl_tls13_ciphersuites[] = { + { + .name = TLS1_3_RFC_AES_128_GCM_SHA256, + .alias = TLS1_3_TXT_AES_128_GCM_SHA256, + .cid = TLS1_3_CK_AES_128_GCM_SHA256, + }, + { + .name = TLS1_3_RFC_AES_256_GCM_SHA384, + .alias = TLS1_3_TXT_AES_256_GCM_SHA384, + .cid = TLS1_3_CK_AES_256_GCM_SHA384, + }, + { + .name = TLS1_3_RFC_CHACHA20_POLY1305_SHA256, + .alias = TLS1_3_TXT_CHACHA20_POLY1305_SHA256, + .cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256, + }, + { + .name = TLS1_3_RFC_AES_128_CCM_SHA256, + .alias = TLS1_3_TXT_AES_128_CCM_SHA256, + .cid = TLS1_3_CK_AES_128_CCM_SHA256, + }, + { + .name = TLS1_3_RFC_AES_128_CCM_8_SHA256, + .alias = TLS1_3_TXT_AES_128_CCM_8_SHA256, + .cid = TLS1_3_CK_AES_128_CCM_8_SHA256, + }, + { + .name = NULL, + }, +}; + +int +ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str) +{ + const struct ssl_tls13_ciphersuite *ciphersuite; + STACK_OF(SSL_CIPHER) *ciphers; + const SSL_CIPHER *cipher; + char *s = NULL; + char *p, *q; + int i; + int ret = 0; + + if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) + goto err; + + /* An empty string is valid and means no ciphers. */ + if (strcmp(str, "") == 0) + goto done; + + if ((s = strdup(str)) == NULL) + goto err; + + q = s; + while ((p = strsep(&q, ":")) != NULL) { + ciphersuite = &ssl_tls13_ciphersuites[0]; + for (i = 0; ciphersuite->name != NULL; i++) { + if (strcmp(p, ciphersuite->name) == 0) + break; + if (strcmp(p, ciphersuite->alias) == 0) + break; + ciphersuite = &ssl_tls13_ciphersuites[i]; + } + if (ciphersuite->name == NULL) + goto err; + + /* We know about the cipher suite, but it is not supported. */ + if ((cipher = ssl3_get_cipher_by_id(ciphersuite->cid)) == NULL) + continue; + + if (!sk_SSL_CIPHER_push(ciphers, cipher)) + goto err; + } + + done: + sk_SSL_CIPHER_free(*out_ciphers); + *out_ciphers = ciphers; + ciphers = NULL; + ret = 1; + + err: + sk_SSL_CIPHER_free(ciphers); + free(s); + + return ret; +} + +int +ssl_merge_cipherlists(STACK_OF(SSL_CIPHER) *cipherlist, + STACK_OF(SSL_CIPHER) *cipherlist_tls13, + STACK_OF(SSL_CIPHER) **out_cipherlist) +{ + STACK_OF(SSL_CIPHER) *ciphers = NULL; + const SSL_CIPHER *cipher; + int i, ret = 0; + + if ((ciphers = sk_SSL_CIPHER_dup(cipherlist_tls13)) == NULL) + goto err; + for (i = 0; i < sk_SSL_CIPHER_num(cipherlist); i++) { + cipher = sk_SSL_CIPHER_value(cipherlist, i); + if (cipher->algorithm_ssl == SSL_TLSV1_3) + continue; + if (!sk_SSL_CIPHER_push(ciphers, cipher)) + goto err; + } + + sk_SSL_CIPHER_free(*out_cipherlist); + *out_cipherlist = ciphers; + ciphers = NULL; + + ret = 1; + + err: + sk_SSL_CIPHER_free(ciphers); + + return ret; +} diff --git a/Libraries/libressl/ssl/ssl_clnt.c b/Libraries/libressl/ssl/ssl_clnt.c new file mode 100644 index 000000000..441da643f --- /dev/null +++ b/Libraries/libressl/ssl/ssl_clnt.c @@ -0,0 +1,2678 @@ +/* $OpenBSD: ssl_clnt.c,v 1.161 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#ifndef OPENSSL_NO_GOST +#include +#endif + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" + +static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b); + +static int ssl3_send_client_hello(SSL *s); +static int ssl3_get_dtls_hello_verify(SSL *s); +static int ssl3_get_server_hello(SSL *s); +static int ssl3_get_certificate_request(SSL *s); +static int ssl3_get_new_session_ticket(SSL *s); +static int ssl3_get_cert_status(SSL *s); +static int ssl3_get_server_done(SSL *s); +static int ssl3_send_client_verify(SSL *s); +static int ssl3_send_client_certificate(SSL *s); +static int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); +static int ssl3_send_client_key_exchange(SSL *s); +static int ssl3_get_server_key_exchange(SSL *s); +static int ssl3_get_server_certificate(SSL *s); +static int ssl3_check_cert_and_algorithm(SSL *s); +static int ssl3_check_finished(SSL *s); +static int ssl3_send_client_change_cipher_spec(SSL *s); +static int ssl3_send_client_finished(SSL *s); +static int ssl3_get_server_finished(SSL *s); + +int +ssl3_connect(SSL *s) +{ + int new_state, state, skip = 0; + int ret = -1; + + ERR_clear_error(); + errno = 0; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->s3->hs.state; + + switch (s->s3->hs.state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->s3->hs.state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE|SSL_ST_CONNECT: + case SSL_ST_OK|SSL_ST_CONNECT: + + s->server = 0; + + ssl_info_callback(s, SSL_CB_HANDSHAKE_START, 1); + + if (!ssl_legacy_stack_version(s, s->version)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + if (!ssl_supported_tls_version_range(s, + &s->s3->hs.our_min_tls_version, + &s->s3->hs.our_max_tls_version)) { + SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); + ret = -1; + goto end; + } + + if (!ssl_security_version(s, + s->s3->hs.our_min_tls_version)) { + SSLerror(s, SSL_R_VERSION_TOO_LOW); + ret = -1; + goto end; + } + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + if (!tls1_transcript_init(s)) { + ret = -1; + goto end; + } + + s->s3->hs.state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + + if (SSL_is_dtls(s)) { + /* mark client_random uninitialized */ + memset(s->s3->client_random, 0, + sizeof(s->s3->client_random)); + s->d1->send_cookie = 0; + s->hit = 0; + } + break; + + case SSL3_ST_CW_CLNT_HELLO_A: + case SSL3_ST_CW_CLNT_HELLO_B: + s->shutdown = 0; + + if (SSL_is_dtls(s)) { + /* every DTLS ClientHello resets Finished MAC */ + tls1_transcript_reset(s); + + dtls1_start_timer(s); + } + + ret = ssl3_send_client_hello(s); + if (ret <= 0) + goto end; + + if (SSL_is_dtls(s) && s->d1->send_cookie) { + s->s3->hs.state = SSL3_ST_CW_FLUSH; + s->s3->hs.tls12.next_state = SSL3_ST_CR_SRVR_HELLO_A; + } else + s->s3->hs.state = SSL3_ST_CR_SRVR_HELLO_A; + + s->init_num = 0; + + /* turn on buffering for the next lot of output */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { + s->s3->hs.state = SSL3_ST_CR_FINISHED_A; + if (!SSL_is_dtls(s)) { + if (s->tlsext_ticket_expected) { + /* receive renewed session ticket */ + s->s3->hs.state = SSL3_ST_CR_SESSION_TICKET_A; + } + + /* No client certificate verification. */ + tls1_transcript_free(s); + } + } else if (SSL_is_dtls(s)) { + s->s3->hs.state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; + } else { + s->s3->hs.state = SSL3_ST_CR_CERT_A; + } + s->init_num = 0; + break; + + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + ret = ssl3_get_dtls_hello_verify(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->d1->send_cookie) /* start again, with a cookie */ + s->s3->hs.state = SSL3_ST_CW_CLNT_HELLO_A; + else + s->s3->hs.state = SSL3_ST_CR_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: + ret = ssl3_check_finished(s); + if (ret <= 0) + goto end; + if (ret == 2) { + s->hit = 1; + if (s->tlsext_ticket_expected) + s->s3->hs.state = SSL3_ST_CR_SESSION_TICKET_A; + else + s->s3->hs.state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + } + /* Check if it is anon DH/ECDH. */ + if (!(s->s3->hs.cipher->algorithm_auth & + SSL_aNULL)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; + if (s->tlsext_status_expected) + s->s3->hs.state = SSL3_ST_CR_CERT_STATUS_A; + else + s->s3->hs.state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->s3->hs.state = SSL3_ST_CR_KEY_EXCH_A; + } + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_server_key_exchange(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* + * At this point we check that we have the + * required stuff from the server. + */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; + if (SSL_is_dtls(s)) + dtls1_stop_timer(s); + if (s->s3->hs.tls12.cert_request) + s->s3->hs.state = SSL3_ST_CW_CERT_A; + else + s->s3->hs.state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_client_certificate(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_client_key_exchange(s); + if (ret <= 0) + goto end; + /* + * EAY EAY EAY need to check for DH fix cert + * sent back + */ + /* + * For TLS, cert_req is set to 2, so a cert chain + * of nothing is sent, but no verify packet is sent + */ + /* + * XXX: For now, we do not support client + * authentication in ECDH cipher suites with + * ECDH (rather than ECDSA) certificates. + * We need to skip the certificate verify + * message when client's ECDH public key is sent + * inside the client certificate. + */ + if (s->s3->hs.tls12.cert_request == 1) { + s->s3->hs.state = SSL3_ST_CW_CERT_VRFY_A; + } else { + s->s3->hs.state = SSL3_ST_CW_CHANGE_A; + s->s3->change_cipher_spec = 0; + } + if (!SSL_is_dtls(s)) { + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + s->s3->hs.state = SSL3_ST_CW_CHANGE_A; + s->s3->change_cipher_spec = 0; + } + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_client_verify(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + s->s3->change_cipher_spec = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + if (SSL_is_dtls(s) && !s->hit) + dtls1_start_timer(s); + ret = ssl3_send_client_change_cipher_spec(s); + if (ret <= 0) + goto end; + + s->s3->hs.state = SSL3_ST_CW_FINISHED_A; + s->init_num = 0; + s->session->cipher = s->s3->hs.cipher; + + if (!tls1_setup_key_block(s)) { + ret = -1; + goto end; + } + if (!tls1_change_write_cipher_state(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + if (SSL_is_dtls(s) && !s->hit) + dtls1_start_timer(s); + ret = ssl3_send_client_finished(s); + if (ret <= 0) + goto end; + if (!SSL_is_dtls(s)) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->s3->hs.state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + if (s->hit) { + s->s3->hs.tls12.next_state = SSL_ST_OK; + } else { + /* Allow NewSessionTicket if ticket expected */ + if (s->tlsext_ticket_expected) + s->s3->hs.tls12.next_state = + SSL3_ST_CR_SESSION_TICKET_A; + else + s->s3->hs.tls12.next_state = + SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + if (SSL_is_dtls(s)) + s->d1->change_cipher_spec_ok = 1; + else + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_server_finished(s); + if (ret <= 0) + goto end; + if (SSL_is_dtls(s)) + dtls1_stop_timer(s); + + if (s->hit) + s->s3->hs.state = SSL3_ST_CW_CHANGE_A; + else + s->s3->hs.state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + if (SSL_is_dtls(s)) { + /* If the write error was fatal, stop trying */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->s3->hs.state = s->s3->hs.tls12.next_state; + } + } + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->s3->hs.state = s->s3->hs.tls12.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + tls1_cleanup_key_block(s); + + if (s->s3->handshake_transcript != NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + if (!SSL_is_dtls(s)) + ssl3_release_init_buffer(s); + + ssl_free_wbio_buffer(s); + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = ssl3_connect; + s->ctx->stats.sess_connect_good++; + + ssl_info_callback(s, SSL_CB_HANDSHAKE_DONE, 1); + + if (SSL_is_dtls(s)) { + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; + } + + goto end; + /* break; */ + + default: + SSLerror(s, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->hs.tls12.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if (s->s3->hs.state != state) { + new_state = s->s3->hs.state; + s->s3->hs.state = state; + ssl_info_callback(s, SSL_CB_CONNECT_LOOP, 1); + s->s3->hs.state = new_state; + } + } + skip = 0; + } + + end: + s->in_handshake--; + ssl_info_callback(s, SSL_CB_CONNECT_EXIT, ret); + + return (ret); +} + +static int +ssl3_send_client_hello(SSL *s) +{ + CBB cbb, client_hello, session_id, cookie, cipher_suites; + CBB compression_methods; + uint16_t max_version; + size_t sl; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_CW_CLNT_HELLO_A) { + SSL_SESSION *sess = s->session; + + if (!ssl_max_supported_version(s, &max_version)) { + SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); + return (-1); + } + s->version = max_version; + + if (sess == NULL || sess->ssl_version != s->version || + (sess->session_id_length == 0 && sess->tlsext_tick == NULL) || + sess->not_resumable) { + if (!ssl_get_new_session(s, 0)) + goto err; + } + /* else use the pre-loaded session */ + + /* + * If a DTLS ClientHello message is being resent after a + * HelloVerifyRequest, we must retain the original client + * random value. + */ + if (!SSL_is_dtls(s) || s->d1->send_cookie == 0) + arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); + + if (!ssl3_handshake_msg_start(s, &cbb, &client_hello, + SSL3_MT_CLIENT_HELLO)) + goto err; + + if (!CBB_add_u16(&client_hello, s->version)) + goto err; + + /* Random stuff */ + if (!CBB_add_bytes(&client_hello, s->s3->client_random, + sizeof(s->s3->client_random))) + goto err; + + /* Session ID */ + if (!CBB_add_u8_length_prefixed(&client_hello, &session_id)) + goto err; + if (!s->new_session && + s->session->session_id_length > 0) { + sl = s->session->session_id_length; + if (sl > sizeof(s->session->session_id)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!CBB_add_bytes(&session_id, + s->session->session_id, sl)) + goto err; + } + + /* DTLS Cookie. */ + if (SSL_is_dtls(s)) { + if (s->d1->cookie_len > sizeof(s->d1->cookie)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!CBB_add_u8_length_prefixed(&client_hello, &cookie)) + goto err; + if (!CBB_add_bytes(&cookie, s->d1->cookie, + s->d1->cookie_len)) + goto err; + } + + /* Ciphers supported */ + if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites)) + return 0; + if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), + &cipher_suites)) { + SSLerror(s, SSL_R_NO_CIPHERS_AVAILABLE); + goto err; + } + + /* Add in compression methods (null) */ + if (!CBB_add_u8_length_prefixed(&client_hello, + &compression_methods)) + goto err; + if (!CBB_add_u8(&compression_methods, 0)) + goto err; + + /* TLS extensions */ + if (!tlsext_client_build(s, SSL_TLSEXT_MSG_CH, &client_hello)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_CW_CLNT_HELLO_B; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_get_dtls_hello_verify(SSL *s) +{ + CBS hello_verify_request, cookie; + size_t cookie_len; + uint16_t ssl_version; + int al, ret; + + if ((ret = ssl3_get_message(s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1, s->max_cert_list)) <= 0) + return ret; + + if (s->s3->hs.tls12.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + s->d1->send_cookie = 0; + s->s3->hs.tls12.reuse_message = 1; + return (1); + } + + if (s->init_num < 0) + goto decode_err; + + CBS_init(&hello_verify_request, s->init_msg, + s->init_num); + + if (!CBS_get_u16(&hello_verify_request, &ssl_version)) + goto decode_err; + if (!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie)) + goto decode_err; + if (CBS_len(&hello_verify_request) != 0) + goto decode_err; + + /* + * Per RFC 6347 section 4.2.1, the HelloVerifyRequest should always + * contain DTLSv1.0 the version that is going to be negotiated. + * Tolerate DTLSv1.2 just in case. + */ + if (ssl_version != DTLS1_VERSION && ssl_version != DTLS1_2_VERSION) { + SSLerror(s, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | (ssl_version & 0xff); + al = SSL_AD_PROTOCOL_VERSION; + goto fatal_err; + } + + if (!CBS_write_bytes(&cookie, s->d1->cookie, + sizeof(s->d1->cookie), &cookie_len)) { + s->d1->cookie_len = 0; + al = SSL_AD_ILLEGAL_PARAMETER; + goto fatal_err; + } + s->d1->cookie_len = cookie_len; + s->d1->send_cookie = 1; + + return 1; + + decode_err: + al = SSL_AD_DECODE_ERROR; + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; +} + +static int +ssl3_get_server_hello(SSL *s) +{ + CBS cbs, server_random, session_id; + uint16_t server_version, cipher_suite; + uint8_t compression_method; + const SSL_CIPHER *cipher; + const SSL_METHOD *method; + unsigned long alg_k; + int al, ret; + + s->first_packet = 1; + if ((ret = ssl3_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, + SSL3_ST_CR_SRVR_HELLO_B, -1, 20000 /* ?? */)) <= 0) + return ret; + s->first_packet = 0; + + if (s->init_num < 0) + goto decode_err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + if (SSL_is_dtls(s)) { + if (s->s3->hs.tls12.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { + if (s->d1->send_cookie == 0) { + s->s3->hs.tls12.reuse_message = 1; + return (1); + } else { + /* Already sent a cookie. */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_BAD_MESSAGE_TYPE); + goto fatal_err; + } + } + } + + if (s->s3->hs.tls12.message_type != SSL3_MT_SERVER_HELLO) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_BAD_MESSAGE_TYPE); + goto fatal_err; + } + + if (!CBS_get_u16(&cbs, &server_version)) + goto decode_err; + + if (!ssl_check_version_from_server(s, server_version)) { + SSLerror(s, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | (server_version & 0xff); + al = SSL_AD_PROTOCOL_VERSION; + goto fatal_err; + } + s->s3->hs.peer_legacy_version = server_version; + s->version = server_version; + + s->s3->hs.negotiated_tls_version = ssl_tls_version(server_version); + if (s->s3->hs.negotiated_tls_version == 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((method = ssl_get_method(server_version)) == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + s->method = method; + + /* Server random. */ + if (!CBS_get_bytes(&cbs, &server_random, SSL3_RANDOM_SIZE)) + goto decode_err; + if (!CBS_write_bytes(&server_random, s->s3->server_random, + sizeof(s->s3->server_random), NULL)) + goto err; + + if (s->s3->hs.our_max_tls_version >= TLS1_2_VERSION && + s->s3->hs.negotiated_tls_version < s->s3->hs.our_max_tls_version) { + /* + * RFC 8446 section 4.1.3. We must not downgrade if the server + * random value contains the TLS 1.2 or TLS 1.1 magical value. + */ + if (!CBS_skip(&server_random, + CBS_len(&server_random) - sizeof(tls13_downgrade_12))) + goto err; + if (s->s3->hs.negotiated_tls_version == TLS1_2_VERSION && + CBS_mem_equal(&server_random, tls13_downgrade_12, + sizeof(tls13_downgrade_12))) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK); + goto fatal_err; + } + if (CBS_mem_equal(&server_random, tls13_downgrade_11, + sizeof(tls13_downgrade_11))) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK); + goto fatal_err; + } + } + + /* Session ID. */ + if (!CBS_get_u8_length_prefixed(&cbs, &session_id)) + goto decode_err; + + if (CBS_len(&session_id) > SSL3_SESSION_ID_SIZE) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto fatal_err; + } + + /* Cipher suite. */ + if (!CBS_get_u16(&cbs, &cipher_suite)) + goto decode_err; + + /* + * Check if we want to resume the session based on external + * pre-shared secret. + */ + if (s->tls_session_secret_cb != NULL) { + SSL_CIPHER *pref_cipher = NULL; + int master_key_length = sizeof(s->session->master_key); + + if (!s->tls_session_secret_cb(s, + s->session->master_key, &master_key_length, NULL, + &pref_cipher, s->tls_session_secret_cb_arg)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (master_key_length <= 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + s->session->master_key_length = master_key_length; + + if ((s->session->cipher = pref_cipher) == NULL) + s->session->cipher = + ssl3_get_cipher_by_value(cipher_suite); + s->s3->flags |= SSL3_FLAGS_CCS_OK; + } + + if (s->session->session_id_length != 0 && + CBS_mem_equal(&session_id, s->session->session_id, + s->session->session_id_length)) { + if (s->sid_ctx_length != s->session->sid_ctx_length || + timingsafe_memcmp(s->session->sid_ctx, + s->sid_ctx, s->sid_ctx_length) != 0) { + /* actually a client application bug */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto fatal_err; + } + s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->hit = 1; + } else { + /* a miss or crap from the other end */ + + /* If we were trying for session-id reuse, make a new + * SSL_SESSION so we don't stuff up other people */ + s->hit = 0; + if (s->session->session_id_length > 0) { + if (!ssl_get_new_session(s, 0)) { + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + } + + /* + * XXX - improve the handling for the case where there is a + * zero length session identifier. + */ + if (!CBS_write_bytes(&session_id, s->session->session_id, + sizeof(s->session->session_id), + &s->session->session_id_length)) + goto err; + + s->session->ssl_version = s->version; + } + + if ((cipher = ssl3_get_cipher_by_value(cipher_suite)) == NULL) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_UNKNOWN_CIPHER_RETURNED); + goto fatal_err; + } + + /* TLS v1.2 only ciphersuites require v1.2 or later. */ + if ((cipher->algorithm_ssl & SSL_TLSV1_2) && + s->s3->hs.negotiated_tls_version < TLS1_2_VERSION) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_WRONG_CIPHER_RETURNED); + goto fatal_err; + } + + if (!ssl_cipher_in_list(SSL_get_ciphers(s), cipher)) { + /* we did not say we would use this cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_WRONG_CIPHER_RETURNED); + goto fatal_err; + } + + /* + * Depending on the session caching (internal/external), the cipher + * and/or cipher_id values may not be set. Make sure that + * cipher_id is set and use it for comparison. + */ + if (s->session->cipher) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != cipher->id)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + goto fatal_err; + } + s->s3->hs.cipher = cipher; + + if (!tls1_transcript_hash_init(s)) + goto err; + + /* + * Don't digest cached records if no sigalgs: we may need them for + * client authentication. + */ + alg_k = s->s3->hs.cipher->algorithm_mkey; + if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST))) + tls1_transcript_free(s); + + if (!CBS_get_u8(&cbs, &compression_method)) + goto decode_err; + + if (compression_method != 0) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + goto fatal_err; + } + + if (!tlsext_client_parse(s, SSL_TLSEXT_MSG_SH, &cbs, &al)) { + SSLerror(s, SSL_R_PARSE_TLSEXT); + goto fatal_err; + } + + if (CBS_len(&cbs) != 0) + goto decode_err; + + /* + * Determine if we need to see RI. Strictly speaking if we want to + * avoid an attack we should *always* see RI even on initial server + * hello because the client doesn't see any renegotiation during an + * attack. However this would mean we could not connect to any server + * which doesn't support RI so for the immediate future tolerate RI + * absence on initial connect only. + */ + if (!s->s3->renegotiate_seen && + !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + goto fatal_err; + } + + if (ssl_check_serverhello_tlsext(s) <= 0) { + SSLerror(s, SSL_R_SERVERHELLO_TLSEXT); + goto err; + } + + return (1); + + decode_err: + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +static int +ssl3_get_server_certificate(SSL *s) +{ + CBS cbs, cert_list, cert_data; + STACK_OF(X509) *certs = NULL; + X509 *cert = NULL; + const uint8_t *p; + int al, ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, -1, s->max_cert_list)) <= 0) + return ret; + + ret = -1; + + if (s->s3->hs.tls12.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) { + s->s3->hs.tls12.reuse_message = 1; + return (1); + } + + if (s->s3->hs.tls12.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_BAD_MESSAGE_TYPE); + goto fatal_err; + } + + if ((certs = sk_X509_new_null()) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (s->init_num < 0) + goto decode_err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + if (!CBS_get_u24_length_prefixed(&cbs, &cert_list)) + goto decode_err; + if (CBS_len(&cbs) != 0) + goto decode_err; + + while (CBS_len(&cert_list) > 0) { + if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) + goto decode_err; + p = CBS_data(&cert_data); + if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) { + al = SSL_AD_BAD_CERTIFICATE; + SSLerror(s, ERR_R_ASN1_LIB); + goto fatal_err; + } + if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) + goto decode_err; + if (!sk_X509_push(certs, cert)) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + cert = NULL; + } + + /* A server must always provide a non-empty certificate list. */ + if (sk_X509_num(certs) < 1) { + SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + goto decode_err; + } + + if (ssl_verify_cert_chain(s, certs) <= 0 && + s->verify_mode != SSL_VERIFY_NONE) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerror(s, SSL_R_CERTIFICATE_VERIFY_FAILED); + goto fatal_err; + } + s->session->verify_result = s->verify_result; + ERR_clear_error(); + + if (!tls_process_peer_certs(s, certs)) + goto err; + + ret = 1; + + if (0) { + decode_err: + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } + err: + sk_X509_pop_free(certs, X509_free); + X509_free(cert); + + return (ret); +} + +static int +ssl3_get_server_kex_dhe(SSL *s, CBS *cbs) +{ + int decode_error, invalid_params, invalid_key; + int nid = NID_dhKeyAgreement; + + tls_key_share_free(s->s3->hs.key_share); + if ((s->s3->hs.key_share = tls_key_share_new_nid(nid)) == NULL) + goto err; + + if (!tls_key_share_peer_params(s->s3->hs.key_share, cbs, + &decode_error, &invalid_params)) { + if (decode_error) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + } + goto err; + } + if (!tls_key_share_peer_public(s->s3->hs.key_share, cbs, + &decode_error, &invalid_key)) { + if (decode_error) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + } + goto err; + } + + if (invalid_params) { + SSLerror(s, SSL_R_BAD_DH_P_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + goto err; + } + if (invalid_key) { + SSLerror(s, SSL_R_BAD_DH_PUB_KEY_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + goto err; + } + + if (!tls_key_share_peer_security(s, s->s3->hs.key_share)) { + SSLerror(s, SSL_R_DH_KEY_TOO_SMALL); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return 0; + } + + return 1; + + err: + return 0; +} + +static int +ssl3_get_server_kex_ecdhe(SSL *s, CBS *cbs) +{ + uint8_t curve_type; + uint16_t group_id; + int decode_error; + CBS public; + + if (!CBS_get_u8(cbs, &curve_type)) + goto decode_err; + if (!CBS_get_u16(cbs, &group_id)) + goto decode_err; + + /* Only named curves are supported. */ + if (curve_type != NAMED_CURVE_TYPE) { + SSLerror(s, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + + if (!CBS_get_u8_length_prefixed(cbs, &public)) + goto decode_err; + + /* + * Check that the group is one of our preferences - if it is not, + * the server has sent us an invalid group. + */ + if (!tls1_check_group(s, group_id)) { + SSLerror(s, SSL_R_WRONG_CURVE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + goto err; + } + + tls_key_share_free(s->s3->hs.key_share); + if ((s->s3->hs.key_share = tls_key_share_new(group_id)) == NULL) + goto err; + + if (!tls_key_share_peer_public(s->s3->hs.key_share, &public, + &decode_error, NULL)) { + if (decode_error) + goto decode_err; + goto err; + } + + return 1; + + decode_err: + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + err: + return 0; +} + +static int +ssl3_get_server_key_exchange(SSL *s) +{ + CBB cbb; + CBS cbs, params, signature; + EVP_MD_CTX *md_ctx; + unsigned char *signed_params = NULL; + size_t signed_params_len; + size_t params_len; + long alg_k, alg_a; + int al, ret; + + memset(&cbb, 0, sizeof(cbb)); + + alg_k = s->s3->hs.cipher->algorithm_mkey; + alg_a = s->s3->hs.cipher->algorithm_auth; + + /* + * Use same message size as in ssl3_get_certificate_request() + * as ServerKeyExchange message may be skipped. + */ + if ((ret = ssl3_get_message(s, SSL3_ST_CR_KEY_EXCH_A, + SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list)) <= 0) + return ret; + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if (s->init_num < 0) + goto err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + if (s->s3->hs.tls12.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { + /* + * Do not skip server key exchange if this cipher suite uses + * ephemeral keys. + */ + if (alg_k & (SSL_kDHE|SSL_kECDHE)) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto fatal_err; + } + + s->s3->hs.tls12.reuse_message = 1; + EVP_MD_CTX_free(md_ctx); + return (1); + } + + if (!CBB_init(&cbb, 0)) + goto err; + if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE)) + goto err; + if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE)) + goto err; + + CBS_dup(&cbs, ¶ms); + + if (alg_k & SSL_kDHE) { + if (!ssl3_get_server_kex_dhe(s, &cbs)) + goto err; + } else if (alg_k & SSL_kECDHE) { + if (!ssl3_get_server_kex_ecdhe(s, &cbs)) + goto err; + } else if (alg_k != 0) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + goto fatal_err; + } + + if ((params_len = CBS_offset(&cbs)) > CBS_len(¶ms)) + goto err; + if (!CBB_add_bytes(&cbb, CBS_data(¶ms), params_len)) + goto err; + if (!CBB_finish(&cbb, &signed_params, &signed_params_len)) + goto err; + + /* if it was signed, check the signature */ + if ((alg_a & SSL_aNULL) == 0) { + uint16_t sigalg_value = SIGALG_NONE; + const struct ssl_sigalg *sigalg; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey = NULL; + + if ((alg_a & SSL_aRSA) != 0 && + s->session->peer_cert_type == SSL_PKEY_RSA) { + pkey = X509_get0_pubkey(s->session->peer_cert); + } else if ((alg_a & SSL_aECDSA) != 0 && + s->session->peer_cert_type == SSL_PKEY_ECC) { + pkey = X509_get0_pubkey(s->session->peer_cert); + } + if (pkey == NULL) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto fatal_err; + } + + if (SSL_USE_SIGALGS(s)) { + if (!CBS_get_u16(&cbs, &sigalg_value)) + goto decode_err; + } + if (!CBS_get_u16_length_prefixed(&cbs, &signature)) + goto decode_err; + if (CBS_len(&signature) > EVP_PKEY_size(pkey)) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_WRONG_SIGNATURE_LENGTH); + goto fatal_err; + } + + if ((sigalg = ssl_sigalg_for_peer(s, pkey, + sigalg_value)) == NULL) { + al = SSL_AD_DECODE_ERROR; + goto fatal_err; + } + s->s3->hs.peer_sigalg = sigalg; + + if (!EVP_DigestVerifyInit(md_ctx, &pctx, sigalg->md(), + NULL, pkey)) + goto err; + if ((sigalg->flags & SIGALG_FLAG_RSA_PSS) && + (!EVP_PKEY_CTX_set_rsa_padding(pctx, + RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))) + goto err; + if (EVP_DigestVerify(md_ctx, CBS_data(&signature), + CBS_len(&signature), signed_params, signed_params_len) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_BAD_SIGNATURE); + goto fatal_err; + } + } + + if (CBS_len(&cbs) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_EXTRA_DATA_IN_MESSAGE); + goto fatal_err; + } + + EVP_MD_CTX_free(md_ctx); + free(signed_params); + + return (1); + + decode_err: + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + + err: + CBB_cleanup(&cbb); + EVP_MD_CTX_free(md_ctx); + free(signed_params); + + return (-1); +} + +static int +ssl3_get_certificate_request(SSL *s) +{ + CBS cert_request, cert_types, rdn_list; + X509_NAME *xn = NULL; + const unsigned char *q; + STACK_OF(X509_NAME) *ca_sk = NULL; + int ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_CR_CERT_REQ_A, + SSL3_ST_CR_CERT_REQ_B, -1, s->max_cert_list)) <= 0) + return ret; + + ret = 0; + + s->s3->hs.tls12.cert_request = 0; + + if (s->s3->hs.tls12.message_type == SSL3_MT_SERVER_DONE) { + s->s3->hs.tls12.reuse_message = 1; + /* + * If we get here we don't need any cached handshake records + * as we wont be doing client auth. + */ + tls1_transcript_free(s); + return (1); + } + + if (s->s3->hs.tls12.message_type != SSL3_MT_CERTIFICATE_REQUEST) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerror(s, SSL_R_WRONG_MESSAGE_TYPE); + goto err; + } + + /* TLS does not like anon-DH with client cert */ + if (s->s3->hs.cipher->algorithm_auth & SSL_aNULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerror(s, SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); + goto err; + } + + if (s->init_num < 0) + goto decode_err; + CBS_init(&cert_request, s->init_msg, s->init_num); + + if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!CBS_get_u8_length_prefixed(&cert_request, &cert_types)) + goto decode_err; + + if (SSL_USE_SIGALGS(s)) { + CBS sigalgs; + + if (CBS_len(&cert_request) < 2) { + SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + if (!CBS_get_u16_length_prefixed(&cert_request, &sigalgs)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + if (CBS_len(&sigalgs) % 2 != 0 || CBS_len(&sigalgs) > 64) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } + if (!CBS_stow(&sigalgs, &s->s3->hs.sigalgs, + &s->s3->hs.sigalgs_len)) + goto err; + } + + /* get the CA RDNs */ + if (CBS_len(&cert_request) < 2) { + SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (!CBS_get_u16_length_prefixed(&cert_request, &rdn_list) || + CBS_len(&cert_request) != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerror(s, SSL_R_LENGTH_MISMATCH); + goto err; + } + + while (CBS_len(&rdn_list) > 0) { + CBS rdn; + + if (CBS_len(&rdn_list) < 2) { + SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (!CBS_get_u16_length_prefixed(&rdn_list, &rdn)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerror(s, SSL_R_CA_DN_TOO_LONG); + goto err; + } + + q = CBS_data(&rdn); + if ((xn = d2i_X509_NAME(NULL, &q, CBS_len(&rdn))) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_DECODE_ERROR); + SSLerror(s, ERR_R_ASN1_LIB); + goto err; + } + + if (q != CBS_data(&rdn) + CBS_len(&rdn)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerror(s, SSL_R_CA_DN_LENGTH_MISMATCH); + goto err; + } + if (!sk_X509_NAME_push(ca_sk, xn)) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + xn = NULL; /* avoid free in err block */ + } + + /* we should setup a certificate to return.... */ + s->s3->hs.tls12.cert_request = 1; + sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free); + s->s3->hs.tls12.ca_names = ca_sk; + ca_sk = NULL; + + ret = 1; + if (0) { + decode_err: + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + } + err: + X509_NAME_free(xn); + sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); + return (ret); +} + +static int +ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +static int +ssl3_get_new_session_ticket(SSL *s) +{ + uint32_t lifetime_hint; + CBS cbs, session_ticket; + unsigned int session_id_length = 0; + int al, ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_CR_SESSION_TICKET_A, + SSL3_ST_CR_SESSION_TICKET_B, -1, 16384)) <= 0) + return ret; + + if (s->s3->hs.tls12.message_type == SSL3_MT_FINISHED) { + s->s3->hs.tls12.reuse_message = 1; + return (1); + } + if (s->s3->hs.tls12.message_type != SSL3_MT_NEWSESSION_TICKET) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_BAD_MESSAGE_TYPE); + goto fatal_err; + } + + if (s->init_num < 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_LENGTH_MISMATCH); + goto fatal_err; + } + + CBS_init(&cbs, s->init_msg, s->init_num); + if (!CBS_get_u32(&cbs, &lifetime_hint) || + !CBS_get_u16_length_prefixed(&cbs, &session_ticket) || + CBS_len(&cbs) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_LENGTH_MISMATCH); + goto fatal_err; + } + s->session->tlsext_tick_lifetime_hint = lifetime_hint; + + if (!CBS_stow(&session_ticket, &s->session->tlsext_tick, + &s->session->tlsext_ticklen)) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * There are two ways to detect a resumed ticket session. + * One is to set an appropriate session ID and then the server + * must return a match in ServerHello. This allows the normal + * client session ID matching to work and we know much + * earlier that the ticket has been accepted. + * + * The other way is to set zero length session ID when the + * ticket is presented and rely on the handshake to determine + * session resumption. + * + * We choose the former approach because this fits in with + * assumptions elsewhere in OpenSSL. The session ID is set + * to the SHA256 hash of the ticket. + */ + /* XXX - ensure this doesn't overflow session_id if hash is changed. */ + if (!EVP_Digest(CBS_data(&session_ticket), CBS_len(&session_ticket), + s->session->session_id, &session_id_length, EVP_sha256(), NULL)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_EVP_LIB); + goto fatal_err; + } + s->session->session_id_length = session_id_length; + + return (1); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +static int +ssl3_get_cert_status(SSL *s) +{ + CBS cert_status, response; + uint8_t status_type; + int al, ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_CR_CERT_STATUS_A, + SSL3_ST_CR_CERT_STATUS_B, -1, 16384)) <= 0) + return ret; + + if (s->s3->hs.tls12.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) { + /* + * Tell the callback the server did not send us an OSCP + * response, and has decided to head directly to key exchange. + */ + if (s->ctx->tlsext_status_cb) { + free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resp_len = 0; + + ret = s->ctx->tlsext_status_cb(s, + s->ctx->tlsext_status_arg); + if (ret == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + SSLerror(s, SSL_R_INVALID_STATUS_RESPONSE); + goto fatal_err; + } + if (ret < 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto fatal_err; + } + } + s->s3->hs.tls12.reuse_message = 1; + return (1); + } + + if (s->s3->hs.tls12.message_type != SSL3_MT_CERTIFICATE && + s->s3->hs.tls12.message_type != SSL3_MT_CERTIFICATE_STATUS) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_BAD_MESSAGE_TYPE); + goto fatal_err; + } + + if (s->init_num < 0) { + /* need at least status type + length */ + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_LENGTH_MISMATCH); + goto fatal_err; + } + + CBS_init(&cert_status, s->init_msg, s->init_num); + if (!CBS_get_u8(&cert_status, &status_type) || + CBS_len(&cert_status) < 3) { + /* need at least status type + length */ + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_LENGTH_MISMATCH); + goto fatal_err; + } + + if (status_type != TLSEXT_STATUSTYPE_ocsp) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_UNSUPPORTED_STATUS_TYPE); + goto fatal_err; + } + + if (!CBS_get_u24_length_prefixed(&cert_status, &response) || + CBS_len(&cert_status) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_LENGTH_MISMATCH); + goto fatal_err; + } + + if (!CBS_stow(&response, &s->tlsext_ocsp_resp, + &s->tlsext_ocsp_resp_len)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto fatal_err; + } + + if (s->ctx->tlsext_status_cb) { + ret = s->ctx->tlsext_status_cb(s, + s->ctx->tlsext_status_arg); + if (ret == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + SSLerror(s, SSL_R_INVALID_STATUS_RESPONSE); + goto fatal_err; + } + if (ret < 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto fatal_err; + } + } + return (1); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (-1); +} + +static int +ssl3_get_server_done(SSL *s) +{ + int ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_CR_SRVR_DONE_A, + SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE, + 30 /* should be very small, like 0 :-) */)) <= 0) + return ret; + + if (s->init_num != 0) { + /* should contain no data */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerror(s, SSL_R_LENGTH_MISMATCH); + return -1; + } + + return 1; +} + +static int +ssl3_send_client_kex_rsa(SSL *s, CBB *cbb) +{ + unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char *enc_pms = NULL; + uint16_t max_legacy_version; + EVP_PKEY *pkey; + RSA *rsa; + int ret = 0; + int enc_len; + CBB epms; + + /* + * RSA-Encrypted Premaster Secret Message - RFC 5246 section 7.4.7.1. + */ + + pkey = X509_get0_pubkey(s->session->peer_cert); + if (pkey == NULL || (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * Our maximum legacy protocol version - while RFC 5246 section 7.4.7.1 + * says "The latest (newest) version supported by the client", if we're + * doing RSA key exchange then we have to presume that we're talking to + * a server that does not understand the supported versions extension + * and therefore our maximum version is that sent in the ClientHello. + */ + if (!ssl_max_legacy_version(s, &max_legacy_version)) + goto err; + pms[0] = max_legacy_version >> 8; + pms[1] = max_legacy_version & 0xff; + arc4random_buf(&pms[2], sizeof(pms) - 2); + + if ((enc_pms = malloc(RSA_size(rsa))) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + enc_len = RSA_public_encrypt(sizeof(pms), pms, enc_pms, rsa, + RSA_PKCS1_PADDING); + if (enc_len <= 0) { + SSLerror(s, SSL_R_BAD_RSA_ENCRYPT); + goto err; + } + + if (!CBB_add_u16_length_prefixed(cbb, &epms)) + goto err; + if (!CBB_add_bytes(&epms, enc_pms, enc_len)) + goto err; + if (!CBB_flush(cbb)) + goto err; + + if (!tls12_derive_master_secret(s, pms, sizeof(pms))) + goto err; + + ret = 1; + + err: + explicit_bzero(pms, sizeof(pms)); + free(enc_pms); + + return ret; +} + +static int +ssl3_send_client_kex_dhe(SSL *s, CBB *cbb) +{ + uint8_t *key = NULL; + size_t key_len = 0; + int ret = 0; + + /* Ensure that we have an ephemeral key from the server for DHE. */ + if (s->s3->hs.key_share == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerror(s, SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); + goto err; + } + + if (!tls_key_share_generate(s->s3->hs.key_share)) + goto err; + if (!tls_key_share_public(s->s3->hs.key_share, cbb)) + goto err; + if (!tls_key_share_derive(s->s3->hs.key_share, &key, &key_len)) + goto err; + + if (!tls_key_share_peer_security(s, s->s3->hs.key_share)) { + SSLerror(s, SSL_R_DH_KEY_TOO_SMALL); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return 0; + } + + if (!tls12_derive_master_secret(s, key, key_len)) + goto err; + + ret = 1; + + err: + freezero(key, key_len); + + return ret; +} + +static int +ssl3_send_client_kex_ecdhe(SSL *s, CBB *cbb) +{ + uint8_t *key = NULL; + size_t key_len = 0; + CBB public; + int ret = 0; + + /* Ensure that we have an ephemeral key for ECDHE. */ + if (s->s3->hs.key_share == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!tls_key_share_generate(s->s3->hs.key_share)) + goto err; + + if (!CBB_add_u8_length_prefixed(cbb, &public)) + return 0; + if (!tls_key_share_public(s->s3->hs.key_share, &public)) + goto err; + if (!CBB_flush(cbb)) + goto err; + + if (!tls_key_share_derive(s->s3->hs.key_share, &key, &key_len)) + goto err; + + if (!tls12_derive_master_secret(s, key, key_len)) + goto err; + + ret = 1; + + err: + freezero(key, key_len); + + return ret; +} + +static int +ssl3_send_client_kex_gost(SSL *s, CBB *cbb) +{ + unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_MD_CTX *ukm_hash = NULL; + EVP_PKEY *pkey; + size_t msglen; + unsigned int md_len; + CBB gostblob; + int nid; + int ret = 0; + + /* Get server certificate PKEY and create ctx from it */ + pkey = X509_get0_pubkey(s->session->peer_cert); + if (pkey == NULL || s->session->peer_cert_type != SSL_PKEY_GOST01) { + SSLerror(s, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + goto err; + } + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * If we have send a certificate, and certificate key parameters match + * those of server certificate, use certificate key for key exchange. + * Otherwise, generate ephemeral key pair. + */ + if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0) + goto err; + + /* Generate session key. */ + arc4random_buf(premaster_secret, sizeof(premaster_secret)); + + /* + * If we have client certificate, use its secret as peer key. + * XXX - this presumably lacks PFS. + */ + if (s->s3->hs.tls12.cert_request != 0 && + s->cert->key->privatekey != NULL) { + if (EVP_PKEY_derive_set_peer(pkey_ctx, + s->cert->key->privatekey) <=0) { + /* + * If there was an error - just ignore it. + * Ephemeral key would be used. + */ + ERR_clear_error(); + } + } + + /* + * Compute shared IV and store it in algorithm-specific context data. + */ + if ((ukm_hash = EVP_MD_CTX_new()) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* XXX check handshake hash instead. */ + if (s->s3->hs.cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94) + nid = NID_id_GostR3411_94; + else + nid = NID_id_tc26_gost3411_2012_256; + if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid))) + goto err; + if (!EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE)) + goto err; + if (!EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE)) + goto err; + if (!EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len)) + goto err; + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { + SSLerror(s, SSL_R_LIBRARY_BUG); + goto err; + } + + /* + * Make GOST keytransport blob message, encapsulate it into sequence. + */ + msglen = 255; + if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, + sizeof(premaster_secret)) < 0) { + SSLerror(s, SSL_R_LIBRARY_BUG); + goto err; + } + + if (!CBB_add_asn1(cbb, &gostblob, CBS_ASN1_SEQUENCE)) + goto err; + if (!CBB_add_bytes(&gostblob, tmp, msglen)) + goto err; + if (!CBB_flush(cbb)) + goto err; + + /* Check if pubkey from client certificate was used. */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, + NULL) > 0) + s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; + + if (!tls12_derive_master_secret(s, premaster_secret, 32)) + goto err; + + ret = 1; + + err: + explicit_bzero(premaster_secret, sizeof(premaster_secret)); + EVP_PKEY_CTX_free(pkey_ctx); + EVP_MD_CTX_free(ukm_hash); + + return ret; +} + +static int +ssl3_send_client_key_exchange(SSL *s) +{ + unsigned long alg_k; + CBB cbb, kex; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_CW_KEY_EXCH_A) { + alg_k = s->s3->hs.cipher->algorithm_mkey; + + if (!ssl3_handshake_msg_start(s, &cbb, &kex, + SSL3_MT_CLIENT_KEY_EXCHANGE)) + goto err; + + if (alg_k & SSL_kRSA) { + if (!ssl3_send_client_kex_rsa(s, &kex)) + goto err; + } else if (alg_k & SSL_kDHE) { + if (!ssl3_send_client_kex_dhe(s, &kex)) + goto err; + } else if (alg_k & SSL_kECDHE) { + if (!ssl3_send_client_kex_ecdhe(s, &kex)) + goto err; + } else if (alg_k & SSL_kGOST) { + if (!ssl3_send_client_kex_gost(s, &kex)) + goto err; + } else { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_CW_KEY_EXCH_B; + } + + /* SSL3_ST_CW_KEY_EXCH_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_send_client_verify_sigalgs(SSL *s, EVP_PKEY *pkey, + const struct ssl_sigalg *sigalg, CBB *cert_verify) +{ + CBB cbb_signature; + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX *mctx = NULL; + const unsigned char *hdata; + unsigned char *signature = NULL; + size_t signature_len, hdata_len; + int ret = 0; + + if ((mctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if (!tls1_transcript_data(s, &hdata, &hdata_len)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!EVP_DigestSignInit(mctx, &pctx, sigalg->md(), NULL, pkey)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } +#ifndef OPENSSL_NO_GOST + if (sigalg->key_type == EVP_PKEY_GOSTR01 && + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, GOST_SIG_FORMAT_RS_LE, NULL) <= 0) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } +#endif + if ((sigalg->flags & SIGALG_FLAG_RSA_PSS) && + (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if (!EVP_DigestSign(mctx, NULL, &signature_len, hdata, hdata_len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if ((signature = calloc(1, signature_len)) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_DigestSign(mctx, signature, &signature_len, hdata, hdata_len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + + if (!CBB_add_u16(cert_verify, sigalg->value)) + goto err; + if (!CBB_add_u16_length_prefixed(cert_verify, &cbb_signature)) + goto err; + if (!CBB_add_bytes(&cbb_signature, signature, signature_len)) + goto err; + if (!CBB_flush(cert_verify)) + goto err; + + ret = 1; + + err: + EVP_MD_CTX_free(mctx); + free(signature); + return ret; +} + +static int +ssl3_send_client_verify_rsa(SSL *s, EVP_PKEY *pkey, CBB *cert_verify) +{ + CBB cbb_signature; + RSA *rsa; + unsigned char data[EVP_MAX_MD_SIZE]; + unsigned char *signature = NULL; + unsigned int signature_len; + size_t data_len; + int ret = 0; + + if (!tls1_transcript_hash_value(s, data, sizeof(data), &data_len)) + goto err; + if ((signature = calloc(1, EVP_PKEY_size(pkey))) == NULL) + goto err; + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) + goto err; + if (RSA_sign(NID_md5_sha1, data, data_len, signature, &signature_len, + rsa) <= 0 ) { + SSLerror(s, ERR_R_RSA_LIB); + goto err; + } + + if (!CBB_add_u16_length_prefixed(cert_verify, &cbb_signature)) + goto err; + if (!CBB_add_bytes(&cbb_signature, signature, signature_len)) + goto err; + if (!CBB_flush(cert_verify)) + goto err; + + ret = 1; + err: + free(signature); + return ret; +} + +static int +ssl3_send_client_verify_ec(SSL *s, EVP_PKEY *pkey, CBB *cert_verify) +{ + CBB cbb_signature; + EC_KEY *eckey; + unsigned char data[EVP_MAX_MD_SIZE]; + unsigned char *signature = NULL; + unsigned int signature_len; + int ret = 0; + + if (!tls1_transcript_hash_value(s, data, sizeof(data), NULL)) + goto err; + if ((signature = calloc(1, EVP_PKEY_size(pkey))) == NULL) + goto err; + if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) + goto err; + if (!ECDSA_sign(0, &data[MD5_DIGEST_LENGTH], SHA_DIGEST_LENGTH, + signature, &signature_len, eckey)) { + SSLerror(s, ERR_R_ECDSA_LIB); + goto err; + } + + if (!CBB_add_u16_length_prefixed(cert_verify, &cbb_signature)) + goto err; + if (!CBB_add_bytes(&cbb_signature, signature, signature_len)) + goto err; + if (!CBB_flush(cert_verify)) + goto err; + + ret = 1; + err: + free(signature); + return ret; +} + +#ifndef OPENSSL_NO_GOST +static int +ssl3_send_client_verify_gost(SSL *s, EVP_PKEY *pkey, CBB *cert_verify) +{ + CBB cbb_signature; + EVP_MD_CTX *mctx; + EVP_PKEY_CTX *pctx; + const EVP_MD *md; + const unsigned char *hdata; + unsigned char *signature = NULL; + size_t signature_len; + size_t hdata_len; + int nid; + int ret = 0; + + if ((mctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if (!tls1_transcript_data(s, &hdata, &hdata_len)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || + (md = EVP_get_digestbynid(nid)) == NULL) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if (!EVP_DigestSignInit(mctx, &pctx, md, NULL, pkey)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } +#ifndef OPENSSL_NO_GOST + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, GOST_SIG_FORMAT_RS_LE, NULL) <= 0) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } +#endif + if (!EVP_DigestSign(mctx, NULL, &signature_len, hdata, hdata_len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if ((signature = calloc(1, signature_len)) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_DigestSign(mctx, signature, &signature_len, hdata, hdata_len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + + if (!CBB_add_u16_length_prefixed(cert_verify, &cbb_signature)) + goto err; + if (!CBB_add_bytes(&cbb_signature, signature, signature_len)) + goto err; + if (!CBB_flush(cert_verify)) + goto err; + + ret = 1; + err: + EVP_MD_CTX_free(mctx); + free(signature); + return ret; +} +#endif + +static int +ssl3_send_client_verify(SSL *s) +{ + const struct ssl_sigalg *sigalg; + CBB cbb, cert_verify; + EVP_PKEY *pkey; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_CW_CERT_VRFY_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &cert_verify, + SSL3_MT_CERTIFICATE_VERIFY)) + goto err; + + pkey = s->cert->key->privatekey; + if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) { + SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } + s->s3->hs.our_sigalg = sigalg; + + /* + * For TLS v1.2 send signature algorithm and signature using + * agreed digest and cached handshake records. + */ + if (SSL_USE_SIGALGS(s)) { + if (!ssl3_send_client_verify_sigalgs(s, pkey, sigalg, + &cert_verify)) + goto err; + } else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + if (!ssl3_send_client_verify_rsa(s, pkey, &cert_verify)) + goto err; + } else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + if (!ssl3_send_client_verify_ec(s, pkey, &cert_verify)) + goto err; +#ifndef OPENSSL_NO_GOST + } else if (EVP_PKEY_id(pkey) == NID_id_GostR3410_94 || + EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) { + if (!ssl3_send_client_verify_gost(s, pkey, &cert_verify)) + goto err; +#endif + } else { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + tls1_transcript_free(s); + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_CW_CERT_VRFY_B; + } + + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_send_client_certificate(SSL *s) +{ + EVP_PKEY *pkey = NULL; + X509 *x509 = NULL; + CBB cbb, client_cert; + int i; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_CW_CERT_A) { + if (s->cert->key->x509 == NULL || + s->cert->key->privatekey == NULL) + s->s3->hs.state = SSL3_ST_CW_CERT_B; + else + s->s3->hs.state = SSL3_ST_CW_CERT_C; + } + + /* We need to get a client cert */ + if (s->s3->hs.state == SSL3_ST_CW_CERT_B) { + /* + * If we get an error, we need to + * ssl->rwstate = SSL_X509_LOOKUP; return(-1); + * We then get retried later. + */ + i = ssl_do_client_cert_cb(s, &x509, &pkey); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->s3->hs.state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(s, x509) || + !SSL_use_PrivateKey(s, pkey)) + i = 0; + } else if (i == 1) { + i = 0; + SSLerror(s, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + } + + X509_free(x509); + EVP_PKEY_free(pkey); + if (i == 0) { + s->s3->hs.tls12.cert_request = 2; + + /* There is no client certificate to verify. */ + tls1_transcript_free(s); + } + + /* Ok, we have a cert */ + s->s3->hs.state = SSL3_ST_CW_CERT_C; + } + + if (s->s3->hs.state == SSL3_ST_CW_CERT_C) { + if (!ssl3_handshake_msg_start(s, &cbb, &client_cert, + SSL3_MT_CERTIFICATE)) + goto err; + if (!ssl3_output_cert_chain(s, &client_cert, + (s->s3->hs.tls12.cert_request == 2) ? NULL : s->cert->key)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_CW_CERT_D; + } + + /* SSL3_ST_CW_CERT_D */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (0); +} + +#define has_bits(i,m) (((i)&(m)) == (m)) + +static int +ssl3_check_cert_and_algorithm(SSL *s) +{ + long alg_k, alg_a; + int nid = NID_undef; + int i; + + alg_k = s->s3->hs.cipher->algorithm_mkey; + alg_a = s->s3->hs.cipher->algorithm_auth; + + /* We don't have a certificate. */ + if (alg_a & SSL_aNULL) + return (1); + + if (s->s3->hs.key_share != NULL) + nid = tls_key_share_nid(s->s3->hs.key_share); + + /* This is the passed certificate. */ + + if (s->session->peer_cert_type == SSL_PKEY_ECC) { + if (!ssl_check_srvr_ecc_cert_and_alg(s, s->session->peer_cert)) { + SSLerror(s, SSL_R_BAD_ECC_CERT); + goto fatal_err; + } + return (1); + } + + i = X509_certificate_type(s->session->peer_cert, NULL); + + /* Check that we have a certificate if we require one. */ + if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA|EVP_PKT_SIGN)) { + SSLerror(s, SSL_R_MISSING_RSA_SIGNING_CERT); + goto fatal_err; + } + if ((alg_k & SSL_kRSA) && !has_bits(i, EVP_PK_RSA|EVP_PKT_ENC)) { + SSLerror(s, SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto fatal_err; + } + if ((alg_k & SSL_kDHE) && + !(has_bits(i, EVP_PK_DH|EVP_PKT_EXCH) || (nid == NID_dhKeyAgreement))) { + SSLerror(s, SSL_R_MISSING_DH_KEY); + goto fatal_err; + } + + return (1); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + + return (0); +} + +/* + * Check to see if handshake is full or resumed. Usually this is just a + * case of checking to see if a cache hit has occurred. In the case of + * session tickets we have to check the next message to be sure. + */ + +static int +ssl3_check_finished(SSL *s) +{ + int ret; + + /* If we have no ticket it cannot be a resumed session. */ + if (!s->session->tlsext_tick) + return (1); + /* this function is called when we really expect a Certificate + * message, so permit appropriate message length */ + if ((ret = ssl3_get_message(s, SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, -1, s->max_cert_list)) <= 0) + return ret; + + s->s3->hs.tls12.reuse_message = 1; + if ((s->s3->hs.tls12.message_type == SSL3_MT_FINISHED) || + (s->s3->hs.tls12.message_type == SSL3_MT_NEWSESSION_TICKET)) + return (2); + + return (1); +} + +static int +ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) +{ + int i = 0; + +#ifndef OPENSSL_NO_ENGINE + if (s->ctx->client_cert_engine) { + i = ENGINE_load_ssl_client_cert( + s->ctx->client_cert_engine, s, + SSL_get_client_CA_list(s), px509, ppkey, NULL, NULL, NULL); + if (i != 0) + return (i); + } +#endif + if (s->ctx->client_cert_cb) + i = s->ctx->client_cert_cb(s, px509, ppkey); + return (i); +} + +static int +ssl3_send_client_change_cipher_spec(SSL *s) +{ + size_t outlen; + CBB cbb; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_CW_CHANGE_A) { + if (!CBB_init_fixed(&cbb, s->init_buf->data, + s->init_buf->length)) + goto err; + if (!CBB_add_u8(&cbb, SSL3_MT_CCS)) + goto err; + if (!CBB_finish(&cbb, NULL, &outlen)) + goto err; + + if (outlen > INT_MAX) + goto err; + + s->init_num = (int)outlen; + s->init_off = 0; + + if (SSL_is_dtls(s)) { + s->d1->handshake_write_seq = + s->d1->next_handshake_write_seq; + dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, + s->d1->handshake_write_seq, 0, 0); + dtls1_buffer_message(s, 1); + } + + s->s3->hs.state = SSL3_ST_CW_CHANGE_B; + } + + /* SSL3_ST_CW_CHANGE_B */ + return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); + + err: + CBB_cleanup(&cbb); + + return -1; +} + +static int +ssl3_send_client_finished(SSL *s) +{ + CBB cbb, finished; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_CW_FINISHED_A) { + if (!tls12_derive_finished(s)) + goto err; + + /* Copy finished so we can use it for renegotiation checks. */ + memcpy(s->s3->previous_client_finished, + s->s3->hs.finished, s->s3->hs.finished_len); + s->s3->previous_client_finished_len = + s->s3->hs.finished_len; + + if (!ssl3_handshake_msg_start(s, &cbb, &finished, + SSL3_MT_FINISHED)) + goto err; + if (!CBB_add_bytes(&finished, s->s3->hs.finished, + s->s3->hs.finished_len)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_CW_FINISHED_B; + } + + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_get_server_finished(SSL *s) +{ + int al, md_len, ret; + CBS cbs; + + /* should actually be 36+4 :-) */ + if ((ret = ssl3_get_message(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B, SSL3_MT_FINISHED, 64)) <= 0) + return ret; + + /* If this occurs, we have missed a message */ + if (!s->s3->change_cipher_spec) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS); + goto fatal_err; + } + s->s3->change_cipher_spec = 0; + + md_len = TLS1_FINISH_MAC_LENGTH; + + if (s->init_num < 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_DIGEST_LENGTH); + goto fatal_err; + } + + CBS_init(&cbs, s->init_msg, s->init_num); + + if (s->s3->hs.peer_finished_len != md_len || + CBS_len(&cbs) != md_len) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_DIGEST_LENGTH); + goto fatal_err; + } + + if (!CBS_mem_equal(&cbs, s->s3->hs.peer_finished, CBS_len(&cbs))) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_DIGEST_CHECK_FAILED); + goto fatal_err; + } + + /* Copy finished so we can use it for renegotiation checks. */ + OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, + s->s3->hs.peer_finished, md_len); + s->s3->previous_server_finished_len = md_len; + + return (1); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (0); +} diff --git a/Libraries/libressl/ssl/ssl_err.c b/Libraries/libressl/ssl/ssl_err.c new file mode 100644 index 000000000..28097ea70 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_err.c @@ -0,0 +1,673 @@ +/* $OpenBSD: ssl_err.c,v 1.46 2023/07/08 16:40:13 beck Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +#include "ssl_local.h" + +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason) + +/* See SSL_state_func_code below */ +static ERR_STRING_DATA SSL_str_functs[]= { + {ERR_FUNC(1), "CONNECT_CW_FLUSH"}, + {ERR_FUNC(2), "CONNECT_CW_CLNT_HELLO"}, + {ERR_FUNC(3), "CONNECT_CW_CLNT_HELLO"}, + {ERR_FUNC(4), "CONNECT_CR_SRVR_HELLO"}, + {ERR_FUNC(5), "CONNECT_CR_SRVR_HELLO"}, + {ERR_FUNC(6), "CONNECT_CR_CERT"}, + {ERR_FUNC(7), "CONNECT_CR_CERT"}, + {ERR_FUNC(8), "CONNECT_CR_KEY_EXCH"}, + {ERR_FUNC(9), "CONNECT_CR_KEY_EXCH"}, + {ERR_FUNC(10), "CONNECT_CR_CERT_REQ"}, + {ERR_FUNC(11), "CONNECT_CR_CERT_REQ"}, + {ERR_FUNC(12), "CONNECT_CR_SRVR_DONE"}, + {ERR_FUNC(13), "CONNECT_CR_SRVR_DONE"}, + {ERR_FUNC(14), "CONNECT_CW_CERT"}, + {ERR_FUNC(15), "CONNECT_CW_CERT"}, + {ERR_FUNC(16), "CONNECT_CW_CERT_C"}, + {ERR_FUNC(17), "CONNECT_CW_CERT_D"}, + {ERR_FUNC(18), "CONNECT_CW_KEY_EXCH"}, + {ERR_FUNC(19), "CONNECT_CW_KEY_EXCH"}, + {ERR_FUNC(20), "CONNECT_CW_CERT_VRFY"}, + {ERR_FUNC(21), "CONNECT_CW_CERT_VRFY"}, + {ERR_FUNC(22), "CONNECT_CW_CHANGE"}, + {ERR_FUNC(23), "CONNECT_CW_CHANGE"}, + {ERR_FUNC(26), "CONNECT_CW_FINISHED"}, + {ERR_FUNC(27), "CONNECT_CW_FINISHED"}, + {ERR_FUNC(28), "CONNECT_CR_CHANGE"}, + {ERR_FUNC(29), "CONNECT_CR_CHANGE"}, + {ERR_FUNC(30), "CONNECT_CR_FINISHED"}, + {ERR_FUNC(31), "CONNECT_CR_FINISHED"}, + {ERR_FUNC(32), "CONNECT_CR_SESSION_TICKET"}, + {ERR_FUNC(33), "CONNECT_CR_SESSION_TICKET"}, + {ERR_FUNC(34), "CONNECT_CR_CERT_STATUS"}, + {ERR_FUNC(35), "CONNECT_CR_CERT_STATUS"}, + {ERR_FUNC(36), "ACCEPT_SW_FLUSH"}, + {ERR_FUNC(37), "ACCEPT_SR_CLNT_HELLO"}, + {ERR_FUNC(38), "ACCEPT_SR_CLNT_HELLO"}, + {ERR_FUNC(39), "ACCEPT_SR_CLNT_HELLO_C"}, + {ERR_FUNC(40), "ACCEPT_SW_HELLO_REQ"}, + {ERR_FUNC(41), "ACCEPT_SW_HELLO_REQ"}, + {ERR_FUNC(42), "ACCEPT_SW_HELLO_REQ_C"}, + {ERR_FUNC(43), "ACCEPT_SW_SRVR_HELLO"}, + {ERR_FUNC(44), "ACCEPT_SW_SRVR_HELLO"}, + {ERR_FUNC(45), "ACCEPT_SW_CERT"}, + {ERR_FUNC(46), "ACCEPT_SW_CERT"}, + {ERR_FUNC(47), "ACCEPT_SW_KEY_EXCH"}, + {ERR_FUNC(48), "ACCEPT_SW_KEY_EXCH"}, + {ERR_FUNC(49), "ACCEPT_SW_CERT_REQ"}, + {ERR_FUNC(50), "ACCEPT_SW_CERT_REQ"}, + {ERR_FUNC(51), "ACCEPT_SW_SRVR_DONE"}, + {ERR_FUNC(52), "ACCEPT_SW_SRVR_DONE"}, + {ERR_FUNC(53), "ACCEPT_SR_CERT"}, + {ERR_FUNC(54), "ACCEPT_SR_CERT"}, + {ERR_FUNC(55), "ACCEPT_SR_KEY_EXCH"}, + {ERR_FUNC(56), "ACCEPT_SR_KEY_EXCH"}, + {ERR_FUNC(57), "ACCEPT_SR_CERT_VRFY"}, + {ERR_FUNC(58), "ACCEPT_SR_CERT_VRFY"}, + {ERR_FUNC(59), "ACCEPT_SR_CHANGE"}, + {ERR_FUNC(60), "ACCEPT_SR_CHANGE"}, + {ERR_FUNC(63), "ACCEPT_SR_FINISHED"}, + {ERR_FUNC(64), "ACCEPT_SR_FINISHED"}, + {ERR_FUNC(65), "ACCEPT_SW_CHANGE"}, + {ERR_FUNC(66), "ACCEPT_SW_CHANGE"}, + {ERR_FUNC(67), "ACCEPT_SW_FINISHED"}, + {ERR_FUNC(68), "ACCEPT_SW_FINISHED"}, + {ERR_FUNC(69), "ACCEPT_SW_SESSION_TICKET"}, + {ERR_FUNC(70), "ACCEPT_SW_SESSION_TICKET"}, + {ERR_FUNC(71), "ACCEPT_SW_CERT_STATUS"}, + {ERR_FUNC(72), "ACCEPT_SW_CERT_STATUS"}, + {ERR_FUNC(73), "ST_BEFORE"}, + {ERR_FUNC(74), "ST_ACCEPT"}, + {ERR_FUNC(75), "ST_CONNECT"}, + {ERR_FUNC(76), "ST_OK"}, + {ERR_FUNC(77), "ST_RENEGOTIATE"}, + {ERR_FUNC(78), "ST_BEFORE_CONNECT"}, + {ERR_FUNC(79), "ST_OK_CONNECT"}, + {ERR_FUNC(80), "ST_BEFORE_ACCEPT"}, + {ERR_FUNC(81), "ST_OK_ACCEPT"}, + {ERR_FUNC(83), "DTLS1_ST_CR_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(84), "DTLS1_ST_CR_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(85), "DTLS1_ST_SW_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(86), "DTLS1_ST_SW_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(0xfff), "(UNKNOWN)SSL_internal"}, + {0, NULL} +}; + +static ERR_STRING_DATA SSL_str_reasons[]= { + {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) , "app data in handshake"}, + {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), "attempt to reuse session in different context"}, + {ERR_REASON(SSL_R_BAD_ALERT_RECORD) , "bad alert record"}, + {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"}, + {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, + {ERR_REASON(SSL_R_BAD_CHECKSUM) , "bad checksum"}, + {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), "bad data returned by callback"}, + {ERR_REASON(SSL_R_BAD_DECOMPRESSION) , "bad decompression"}, + {ERR_REASON(SSL_R_BAD_DH_G_LENGTH) , "bad dh g length"}, + {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH) , "bad dh pub key length"}, + {ERR_REASON(SSL_R_BAD_DH_P_LENGTH) , "bad dh p length"}, + {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH) , "bad digest length"}, + {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE) , "bad dsa signature"}, + {ERR_REASON(SSL_R_BAD_ECC_CERT) , "bad ecc cert"}, + {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE) , "bad ecdsa signature"}, + {ERR_REASON(SSL_R_BAD_ECPOINT) , "bad ecpoint"}, + {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH) , "bad handshake length"}, + {ERR_REASON(SSL_R_BAD_HELLO_REQUEST) , "bad hello request"}, + {ERR_REASON(SSL_R_BAD_LENGTH) , "bad length"}, + {ERR_REASON(SSL_R_BAD_MAC_DECODE) , "bad mac decode"}, + {ERR_REASON(SSL_R_BAD_MAC_LENGTH) , "bad mac length"}, + {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE) , "bad message type"}, + {ERR_REASON(SSL_R_BAD_PACKET_LENGTH) , "bad packet length"}, + {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), "bad protocol version number"}, + {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), "bad psk identity hint length"}, + {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) , "bad response argument"}, + {ERR_REASON(SSL_R_BAD_RSA_DECRYPT) , "bad rsa decrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT) , "bad rsa encrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH) , "bad rsa e length"}, + {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"}, + {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) , "bad rsa signature"}, + {ERR_REASON(SSL_R_BAD_SIGNATURE) , "bad signature"}, + {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) , "bad srp a length"}, + {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) , "bad srp b length"}, + {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) , "bad srp g length"}, + {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) , "bad srp n length"}, + {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) , "bad srp s length"}, + {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE) , "bad srtp mki value"}, + {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), "bad srtp protection profile list"}, + {ERR_REASON(SSL_R_BAD_SSL_FILETYPE) , "bad ssl filetype"}, + {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), "bad ssl session id length"}, + {ERR_REASON(SSL_R_BAD_STATE) , "bad state"}, + {ERR_REASON(SSL_R_BAD_WRITE_RETRY) , "bad write retry"}, + {ERR_REASON(SSL_R_BIO_NOT_SET) , "bio not set"}, + {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), "block cipher pad is wrong"}, + {ERR_REASON(SSL_R_BN_LIB) , "bn lib"}, + {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) , "ca dn length mismatch"}, + {ERR_REASON(SSL_R_CA_DN_TOO_LONG) , "ca dn too long"}, + {ERR_REASON(SSL_R_CA_KEY_TOO_SMALL) , "ca key too small"}, + {ERR_REASON(SSL_R_CA_MD_TOO_WEAK) , "ca md too weak"}, + {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) , "ccs received early"}, + {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), "certificate verify failed"}, + {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) , "cert length mismatch"}, + {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"}, + {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, + {ERR_REASON(SSL_R_CIPHER_COMPRESSION_UNAVAILABLE), "cipher compression unavailable"}, + {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), "cipher or hash unavailable"}, + {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"}, + {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) , "clienthello tlsext"}, + {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), "compressed length too long"}, + {ERR_REASON(SSL_R_COMPRESSION_DISABLED) , "compression disabled"}, + {ERR_REASON(SSL_R_COMPRESSION_FAILURE) , "compression failure"}, + {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), "compression id not within private range"}, + {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), "compression library error"}, + {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), "connection id is different"}, + {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, + {ERR_REASON(SSL_R_COOKIE_MISMATCH) , "cookie mismatch"}, + {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), "data between ccs and finished"}, + {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) , "data length too long"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED) , "decryption failed"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), "decryption failed or bad record mac"}, + {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL) , "dh key too small"}, + {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), "dh public value length is wrong"}, + {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) , "digest check failed"}, + {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) , "dtls message too big"}, + {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), "ecc cert not for key agreement"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), "ecc cert should have rsa signature"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), "ecc cert should have sha1 signature"}, + {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), "ecgroup too large for cipher"}, + {ERR_REASON(SSL_R_EE_KEY_TOO_SMALL) , "ee key too small"}, + {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), "empty srtp protection profile list"}, + {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), "encrypted length too long"}, + {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), "error generating tmp rsa key"}, + {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), "error in received cipher list"}, + {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"}, + {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) , "extra data in message"}, + {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), "got next proto before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), "got next proto without seeing extension"}, + {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"}, + {ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"}, + {ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"}, + {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"}, + {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, + {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, + {ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"}, + {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), "invalid compression algorithm"}, + {ERR_REASON(SSL_R_INVALID_PURPOSE) , "invalid purpose"}, + {ERR_REASON(SSL_R_INVALID_SRP_USERNAME) , "invalid srp username"}, + {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"}, + {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), "invalid ticket keys length"}, + {ERR_REASON(SSL_R_INVALID_TRUST) , "invalid trust"}, + {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG) , "key arg too long"}, + {ERR_REASON(SSL_R_KRB5) , "krb5"}, + {ERR_REASON(SSL_R_KRB5_C_CC_PRINC) , "krb5 client cc principal (no tkt?)"}, + {ERR_REASON(SSL_R_KRB5_C_GET_CRED) , "krb5 client get cred"}, + {ERR_REASON(SSL_R_KRB5_C_INIT) , "krb5 client init"}, + {ERR_REASON(SSL_R_KRB5_C_MK_REQ) , "krb5 client mk_req (expired tkt?)"}, + {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET) , "krb5 server bad ticket"}, + {ERR_REASON(SSL_R_KRB5_S_INIT) , "krb5 server init"}, + {ERR_REASON(SSL_R_KRB5_S_RD_REQ) , "krb5 server rd_req (keytab perms?)"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED) , "krb5 server tkt expired"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_NYV) , "krb5 server tkt not yet valid"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW) , "krb5 server tkt skew"}, + {ERR_REASON(SSL_R_LENGTH_MISMATCH) , "length mismatch"}, + {ERR_REASON(SSL_R_LENGTH_TOO_SHORT) , "length too short"}, + {ERR_REASON(SSL_R_LIBRARY_BUG) , "library bug"}, + {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, + {ERR_REASON(SSL_R_MESSAGE_TOO_LONG) , "message too long"}, + {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT) , "missing dh dsa cert"}, + {ERR_REASON(SSL_R_MISSING_DH_KEY) , "missing dh key"}, + {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT) , "missing dh rsa cert"}, + {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), "missing export tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), "missing export tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"}, + {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), "missing rsa encrypting cert"}, + {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_SRP_PARAM) , "can't find SRP server param"}, + {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) , "missing tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) , "missing tmp ecdh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) , "missing tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) , "missing tmp rsa pkey"}, + {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"}, + {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) , "multiple sgc restarts"}, + {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"}, + {ERR_REASON(SSL_R_NO_APPLICATION_PROTOCOL), "no application protocol"}, + {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SET) , "no certificate set"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"}, + {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE) , "no ciphers available"}, + {ERR_REASON(SSL_R_NO_CIPHERS_PASSED) , "no ciphers passed"}, + {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED) , "no ciphers specified"}, + {ERR_REASON(SSL_R_NO_CIPHER_LIST) , "no cipher list"}, + {ERR_REASON(SSL_R_NO_CIPHER_MATCH) , "no cipher match"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) , "no client cert method"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"}, + {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"}, + {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), "Peer haven't sent GOST certificate, required for selected ciphersuite"}, + {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) , "no method specified"}, + {ERR_REASON(SSL_R_NO_PRIVATEKEY) , "no privatekey"}, + {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"}, + {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"}, + {ERR_REASON(SSL_R_NO_PUBLICKEY) , "no publickey"}, + {ERR_REASON(SSL_R_NO_RENEGOTIATION) , "no renegotiation"}, + {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST) , "digest requred for handshake isn't computed"}, + {ERR_REASON(SSL_R_NO_SHARED_CIPHER) , "no shared cipher"}, + {ERR_REASON(SSL_R_NO_SRTP_PROFILES) , "no srtp profiles"}, + {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) , "no verify callback"}, + {ERR_REASON(SSL_R_NULL_SSL_CTX) , "null ssl ctx"}, + {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"}, + {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), "old session cipher not returned"}, + {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), "old session compression algorithm not returned"}, + {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), "only tls allowed in fips mode"}, + {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, + {ERR_REASON(SSL_R_PARSE_TLSEXT) , "parse tlsext"}, + {ERR_REASON(SSL_R_PATH_TOO_LONG) , "path too long"}, + {ERR_REASON(SSL_R_PEER_BEHAVING_BADLY) , "peer is doing strange or hostile things"}, + {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), "peer did not return a certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR) , "peer error"}, + {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), "peer error no certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER) , "peer error no cipher"}, + {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), "peer error unsupported certificate type"}, + {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"}, + {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), "problems mapping cipher functions"}, + {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN) , "protocol is shutdown"}, + {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"}, + {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB) , "psk no client cb"}, + {ERR_REASON(SSL_R_PSK_NO_SERVER_CB) , "psk no server cb"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) , "public key is not rsa"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA) , "public key not rsa"}, + {ERR_REASON(SSL_R_QUIC_INTERNAL_ERROR) , "QUIC: internal error"}, + {ERR_REASON(SSL_R_READ_BIO_NOT_SET) , "read bio not set"}, + {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED) , "read timeout expired"}, + {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"}, + {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, + {ERR_REASON(SSL_R_RECORD_TOO_LARGE) , "record too large"}, + {ERR_REASON(SSL_R_RECORD_TOO_SMALL) , "record too small"}, + {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, + {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), "renegotiation encoding err"}, + {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"}, + {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"}, + {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), "required compresssion algorithm missing"}, + {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), "reuse cert length not zero"}, + {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"}, + {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), "reuse cipher list not zero"}, + {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), "scsv received when renegotiating"}, + {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) , "serverhello tlsext"}, + {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), "session id context uninitialized"}, + {ERR_REASON(SSL_R_SHORT_READ) , "short read"}, + {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), "signature algorithms error"}, + {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), "signature for non signing certificate"}, + {ERR_REASON(SSL_R_SRP_A_CALC) , "error with the srp params"}, + {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), "srtp could not allocate profiles"}, + {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), "srtp protection profile list too long"}, + {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), "srtp unknown protection profile"}, + {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), "ssl23 doing session id reuse"}, + {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), "ssl2 connection id too long"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), "ssl3 ext invalid ecpointformat"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), "ssl3 ext invalid servername"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), "ssl3 ext invalid servername type"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), "ssl3 session id too short"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), "sslv3 alert bad certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), "sslv3 alert bad record mac"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), "sslv3 alert certificate expired"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), "sslv3 alert certificate revoked"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), "sslv3 alert certificate unknown"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), "sslv3 alert decompression failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), "sslv3 alert handshake failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), "sslv3 alert illegal parameter"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), "sslv3 alert no certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), "sslv3 alert unexpected message"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), "sslv3 alert unsupported certificate"}, + {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), "ssl ctx has no default ssl version"}, + {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE) , "ssl handshake failure"}, + {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), "ssl library has no ciphers"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), "ssl session id callback failed"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), "ssl session id context too long"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), "ssl session id has bad length"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), "ssl session id is different"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_TOO_LONG), "ssl session id is too long"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), "tlsv1 alert access denied"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), "tlsv1 alert inappropriate fallback"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), "tlsv1 alert protocol version"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), "tlsv1 alert record overflow"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), "tlsv1 alert user cancelled"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), "tlsv1 bad certificate hash value"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), "tlsv1 bad certificate status response"}, + {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), "tlsv1 certificate unobtainable"}, + {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"}, + {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), "tlsv1 unsupported extension"}, + {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), "tls client cert req with anon cipher"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), "peer does not accept heartbeats"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) , "heartbeat request already pending"}, + {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), "tls illegal exporter label"}, + {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), "tls invalid ecpointformat list"}, + {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), "tls peer did not respond with certificate list"}, + {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), "tls rsa encrypted value length is wrong"}, + {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), "tried to use unsupported cipher"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), "unable to decode dh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), "unable to decode ecdh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), "unable to extract public key"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), "unable to find dh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), "unable to find ecdh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), "unable to find public key parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), "unable to find ssl method"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), "unable to load ssl2 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), "unable to load ssl3 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), "unable to load ssl3 sha1 routines"}, + {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE) , "unexpected message"}, + {ERR_REASON(SSL_R_UNEXPECTED_RECORD) , "unexpected record"}, + {ERR_REASON(SSL_R_UNINITIALIZED) , "uninitialized"}, + {ERR_REASON(SSL_R_UNKNOWN), "unknown failure occurred"}, + {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) , "unknown alert type"}, + {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) , "unknown cipher type"}, + {ERR_REASON(SSL_R_UNKNOWN_DIGEST) , "unknown digest"}, + {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), "unknown key exchange type"}, + {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) , "unknown pkey type"}, + {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL) , "unknown protocol"}, + {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), "unknown remote error type"}, + {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION) , "unknown ssl version"}, + {ERR_REASON(SSL_R_UNKNOWN_STATE) , "unknown state"}, + {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), "unsafe legacy renegotiation disabled"}, + {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) , "unsupported cipher"}, + {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), "unsupported compression algorithm"}, + {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"}, + {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), "unsupported elliptic curve"}, + {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL) , "unsupported protocol"}, + {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, + {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, + {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, + {ERR_REASON(SSL_R_VERSION_TOO_LOW) , "version too low"}, + {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) , "write bio not set"}, + {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) , "wrong cipher returned"}, + {ERR_REASON(SSL_R_WRONG_CURVE) , "wrong curve"}, + {ERR_REASON(SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED), "QUIC: wrong encryption level received"}, + {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) , "wrong message type"}, + {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE) , "wrong signature size"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE) , "wrong signature type"}, + {ERR_REASON(SSL_R_WRONG_SSL_VERSION) , "wrong ssl version"}, + {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) , "wrong version number"}, + {ERR_REASON(SSL_R_X509_LIB) , "x509 lib"}, + {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), "x509 verification setup problems"}, + {0, NULL} +}; + +#endif + +void +ERR_load_SSL_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { + ERR_load_strings(0, SSL_str_functs); + ERR_load_strings(0, SSL_str_reasons); + } +#endif +} +LSSL_ALIAS(ERR_load_SSL_strings); + +void +SSL_load_error_strings(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); +#endif +} +LSSL_ALIAS(SSL_load_error_strings); + +int +SSL_state_func_code(int state) { + switch (state) { + case SSL3_ST_CW_FLUSH: + return 1; + case SSL3_ST_CW_CLNT_HELLO_A: + return 2; + case SSL3_ST_CW_CLNT_HELLO_B: + return 3; + case SSL3_ST_CR_SRVR_HELLO_A: + return 4; + case SSL3_ST_CR_SRVR_HELLO_B: + return 5; + case SSL3_ST_CR_CERT_A: + return 6; + case SSL3_ST_CR_CERT_B: + return 7; + case SSL3_ST_CR_KEY_EXCH_A: + return 8; + case SSL3_ST_CR_KEY_EXCH_B: + return 9; + case SSL3_ST_CR_CERT_REQ_A: + return 10; + case SSL3_ST_CR_CERT_REQ_B: + return 11; + case SSL3_ST_CR_SRVR_DONE_A: + return 12; + case SSL3_ST_CR_SRVR_DONE_B: + return 13; + case SSL3_ST_CW_CERT_A: + return 14; + case SSL3_ST_CW_CERT_B: + return 15; + case SSL3_ST_CW_CERT_C: + return 16; + case SSL3_ST_CW_CERT_D: + return 17; + case SSL3_ST_CW_KEY_EXCH_A: + return 18; + case SSL3_ST_CW_KEY_EXCH_B: + return 19; + case SSL3_ST_CW_CERT_VRFY_A: + return 20; + case SSL3_ST_CW_CERT_VRFY_B: + return 21; + case SSL3_ST_CW_CHANGE_A: + return 22; + case SSL3_ST_CW_CHANGE_B: + return 23; + case SSL3_ST_CW_FINISHED_A: + return 26; + case SSL3_ST_CW_FINISHED_B: + return 27; + case SSL3_ST_CR_CHANGE_A: + return 28; + case SSL3_ST_CR_CHANGE_B: + return 29; + case SSL3_ST_CR_FINISHED_A: + return 30; + case SSL3_ST_CR_FINISHED_B: + return 31; + case SSL3_ST_CR_SESSION_TICKET_A: + return 32; + case SSL3_ST_CR_SESSION_TICKET_B: + return 33; + case SSL3_ST_CR_CERT_STATUS_A: + return 34; + case SSL3_ST_CR_CERT_STATUS_B: + return 35; + case SSL3_ST_SW_FLUSH: + return 36; + case SSL3_ST_SR_CLNT_HELLO_A: + return 37; + case SSL3_ST_SR_CLNT_HELLO_B: + return 38; + case SSL3_ST_SR_CLNT_HELLO_C: + return 39; + case SSL3_ST_SW_HELLO_REQ_A: + return 40; + case SSL3_ST_SW_HELLO_REQ_B: + return 41; + case SSL3_ST_SW_HELLO_REQ_C: + return 42; + case SSL3_ST_SW_SRVR_HELLO_A: + return 43; + case SSL3_ST_SW_SRVR_HELLO_B: + return 44; + case SSL3_ST_SW_CERT_A: + return 45; + case SSL3_ST_SW_CERT_B: + return 46; + case SSL3_ST_SW_KEY_EXCH_A: + return 47; + case SSL3_ST_SW_KEY_EXCH_B: + return 48; + case SSL3_ST_SW_CERT_REQ_A: + return 49; + case SSL3_ST_SW_CERT_REQ_B: + return 50; + case SSL3_ST_SW_SRVR_DONE_A: + return 51; + case SSL3_ST_SW_SRVR_DONE_B: + return 52; + case SSL3_ST_SR_CERT_A: + return 53; + case SSL3_ST_SR_CERT_B: + return 54; + case SSL3_ST_SR_KEY_EXCH_A: + return 55; + case SSL3_ST_SR_KEY_EXCH_B: + return 56; + case SSL3_ST_SR_CERT_VRFY_A: + return 57; + case SSL3_ST_SR_CERT_VRFY_B: + return 58; + case SSL3_ST_SR_CHANGE_A: + return 59; + case SSL3_ST_SR_CHANGE_B: + return 60; + case SSL3_ST_SR_FINISHED_A: + return 63; + case SSL3_ST_SR_FINISHED_B: + return 64; + case SSL3_ST_SW_CHANGE_A: + return 65; + case SSL3_ST_SW_CHANGE_B: + return 66; + case SSL3_ST_SW_FINISHED_A: + return 67; + case SSL3_ST_SW_FINISHED_B: + return 68; + case SSL3_ST_SW_SESSION_TICKET_A: + return 69; + case SSL3_ST_SW_SESSION_TICKET_B: + return 70; + case SSL3_ST_SW_CERT_STATUS_A: + return 71; + case SSL3_ST_SW_CERT_STATUS_B: + return 72; + case SSL_ST_BEFORE: + return 73; + case SSL_ST_ACCEPT: + return 74; + case SSL_ST_CONNECT: + return 75; + case SSL_ST_OK: + return 76; + case SSL_ST_RENEGOTIATE: + return 77; + case SSL_ST_BEFORE|SSL_ST_CONNECT: + return 78; + case SSL_ST_OK|SSL_ST_CONNECT: + return 79; + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + return 80; + case SSL_ST_OK|SSL_ST_ACCEPT: + return 81; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + return 83; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + return 84; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + return 85; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + return 86; + default: + break; + } + return 0xfff; +} + +void +SSL_error_internal(const SSL *s, int r, char *f, int l) +{ + ERR_PUT_error(ERR_LIB_SSL, + (SSL_state_func_code(s->s3->hs.state)), r, f, l); +} diff --git a/Libraries/libressl/ssl/ssl_init.c b/Libraries/libressl/ssl/ssl_init.c new file mode 100644 index 000000000..a8646cc09 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_init.c @@ -0,0 +1,52 @@ +/* $OpenBSD: ssl_init.c,v 1.4 2023/07/08 16:40:13 beck Exp $ */ +/* + * Copyright (c) 2018 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OpenSSL style init */ + +#include +#include + +#include + +#include "ssl_local.h" + +static pthread_t ssl_init_thread; + +static void +OPENSSL_init_ssl_internal(void) +{ + ssl_init_thread = pthread_self(); + SSL_load_error_strings(); + SSL_library_init(); +} + +int +OPENSSL_init_ssl(uint64_t opts, const void *settings) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + if (pthread_equal(pthread_self(), ssl_init_thread)) + return 1; /* don't recurse */ + + OPENSSL_init_crypto(opts, settings); + + if (pthread_once(&once, OPENSSL_init_ssl_internal) != 0) + return 0; + + return 1; +} +LSSL_ALIAS(OPENSSL_init_ssl); diff --git a/Libraries/libressl/ssl/ssl_kex.c b/Libraries/libressl/ssl/ssl_kex.c new file mode 100644 index 000000000..fa420a35a --- /dev/null +++ b/Libraries/libressl/ssl/ssl_kex.c @@ -0,0 +1,422 @@ +/* $OpenBSD: ssl_kex.c,v 1.12 2023/07/28 16:02:34 tb Exp $ */ +/* + * Copyright (c) 2020, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "bytestring.h" + +#define DHE_MINIMUM_BITS 1024 + +int +ssl_kex_generate_dhe(DH *dh, DH *dh_params) +{ + BIGNUM *p = NULL, *g = NULL; + int ret = 0; + + if ((p = BN_dup(DH_get0_p(dh_params))) == NULL) + goto err; + if ((g = BN_dup(DH_get0_g(dh_params))) == NULL) + goto err; + + if (!DH_set0_pqg(dh, p, NULL, g)) + goto err; + p = NULL; + g = NULL; + + if (!DH_generate_key(dh)) + goto err; + + ret = 1; + + err: + BN_free(p); + BN_free(g); + + return ret; +} + +int +ssl_kex_generate_dhe_params_auto(DH *dh, size_t key_bits) +{ + BIGNUM *p = NULL, *g = NULL; + int ret = 0; + + if (key_bits >= 8192) + p = BN_get_rfc3526_prime_8192(NULL); + else if (key_bits >= 4096) + p = BN_get_rfc3526_prime_4096(NULL); + else if (key_bits >= 3072) + p = BN_get_rfc3526_prime_3072(NULL); + else if (key_bits >= 2048) + p = BN_get_rfc3526_prime_2048(NULL); + else if (key_bits >= 1536) + p = BN_get_rfc3526_prime_1536(NULL); + else + p = BN_get_rfc2409_prime_1024(NULL); + + if (p == NULL) + goto err; + + if ((g = BN_new()) == NULL) + goto err; + if (!BN_set_word(g, 2)) + goto err; + + if (!DH_set0_pqg(dh, p, NULL, g)) + goto err; + p = NULL; + g = NULL; + + if (!DH_generate_key(dh)) + goto err; + + ret = 1; + + err: + BN_free(p); + BN_free(g); + + return ret; +} + +int +ssl_kex_params_dhe(DH *dh, CBB *cbb) +{ + int dh_p_len, dh_g_len; + CBB dh_p, dh_g; + uint8_t *data; + + if ((dh_p_len = BN_num_bytes(DH_get0_p(dh))) <= 0) + return 0; + if ((dh_g_len = BN_num_bytes(DH_get0_g(dh))) <= 0) + return 0; + + if (!CBB_add_u16_length_prefixed(cbb, &dh_p)) + return 0; + if (!CBB_add_space(&dh_p, &data, dh_p_len)) + return 0; + if (BN_bn2bin(DH_get0_p(dh), data) != dh_p_len) + return 0; + + if (!CBB_add_u16_length_prefixed(cbb, &dh_g)) + return 0; + if (!CBB_add_space(&dh_g, &data, dh_g_len)) + return 0; + if (BN_bn2bin(DH_get0_g(dh), data) != dh_g_len) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +int +ssl_kex_public_dhe(DH *dh, CBB *cbb) +{ + uint8_t *data; + int dh_y_len; + CBB dh_y; + + if ((dh_y_len = BN_num_bytes(DH_get0_pub_key(dh))) <= 0) + return 0; + + if (!CBB_add_u16_length_prefixed(cbb, &dh_y)) + return 0; + if (!CBB_add_space(&dh_y, &data, dh_y_len)) + return 0; + if (BN_bn2bin(DH_get0_pub_key(dh), data) != dh_y_len) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +int +ssl_kex_peer_params_dhe(DH *dh, CBS *cbs, int *decode_error, + int *invalid_params) +{ + BIGNUM *p = NULL, *g = NULL; + CBS dh_p, dh_g; + int ret = 0; + + *decode_error = 0; + *invalid_params = 0; + + if (!CBS_get_u16_length_prefixed(cbs, &dh_p)) { + *decode_error = 1; + goto err; + } + if (!CBS_get_u16_length_prefixed(cbs, &dh_g)) { + *decode_error = 1; + goto err; + } + + if ((p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL) + goto err; + if ((g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL) + goto err; + + if (!DH_set0_pqg(dh, p, NULL, g)) + goto err; + p = NULL; + g = NULL; + + /* XXX - consider calling DH_check(). */ + + if (DH_bits(dh) < DHE_MINIMUM_BITS) + *invalid_params = 1; + + ret = 1; + + err: + BN_free(p); + BN_free(g); + + return ret; +} + +int +ssl_kex_peer_public_dhe(DH *dh, CBS *cbs, int *decode_error, + int *invalid_key) +{ + BIGNUM *pub_key = NULL; + int check_flags; + CBS dh_y; + int ret = 0; + + *decode_error = 0; + *invalid_key = 0; + + if (!CBS_get_u16_length_prefixed(cbs, &dh_y)) { + *decode_error = 1; + goto err; + } + + if ((pub_key = BN_bin2bn(CBS_data(&dh_y), CBS_len(&dh_y), + NULL)) == NULL) + goto err; + + if (!DH_set0_key(dh, pub_key, NULL)) + goto err; + pub_key = NULL; + + if (!DH_check_pub_key(dh, DH_get0_pub_key(dh), &check_flags)) + goto err; + if (check_flags != 0) + *invalid_key = 1; + + ret = 1; + + err: + BN_free(pub_key); + + return ret; +} + +int +ssl_kex_derive_dhe(DH *dh, DH *dh_peer, + uint8_t **shared_key, size_t *shared_key_len) +{ + uint8_t *key = NULL; + int key_len = 0; + int ret = 0; + + if ((key_len = DH_size(dh)) <= 0) + goto err; + if ((key = calloc(1, key_len)) == NULL) + goto err; + + if ((key_len = DH_compute_key(key, DH_get0_pub_key(dh_peer), dh)) <= 0) + goto err; + + *shared_key = key; + *shared_key_len = key_len; + key = NULL; + + ret = 1; + + err: + freezero(key, key_len); + + return ret; +} + +int +ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey) +{ + EC_GROUP *group = NULL; + EC_POINT *point = NULL; + EC_KEY *ec_key = NULL; + BIGNUM *order = NULL; + int ret = 0; + + /* Fudge up an EC_KEY that looks like X25519... */ + if ((group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL) + goto err; + if ((point = EC_POINT_new(group)) == NULL) + goto err; + if ((order = BN_new()) == NULL) + goto err; + if (!BN_set_bit(order, 252)) + goto err; + if (!EC_GROUP_set_generator(group, point, order, NULL)) + goto err; + EC_GROUP_set_curve_name(group, NID_X25519); + if ((ec_key = EC_KEY_new()) == NULL) + goto err; + if (!EC_KEY_set_group(ec_key, group)) + goto err; + if (!EVP_PKEY_set1_EC_KEY(pkey, ec_key)) + goto err; + + ret = 1; + + err: + EC_GROUP_free(group); + EC_POINT_free(point); + EC_KEY_free(ec_key); + BN_free(order); + + return ret; +} + +int +ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid) +{ + EC_GROUP *group; + int ret = 0; + + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) + goto err; + + if (!EC_KEY_set_group(ecdh, group)) + goto err; + if (!EC_KEY_generate_key(ecdh)) + goto err; + + ret = 1; + + err: + EC_GROUP_free(group); + + return ret; +} + +int +ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb) +{ + const EC_GROUP *group; + const EC_POINT *point; + uint8_t *ecp; + size_t ecp_len; + int ret = 0; + + if ((group = EC_KEY_get0_group(ecdh)) == NULL) + goto err; + if ((point = EC_KEY_get0_public_key(ecdh)) == NULL) + goto err; + + if ((ecp_len = EC_POINT_point2oct(group, point, + POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)) == 0) + goto err; + if (!CBB_add_space(cbb, &ecp, ecp_len)) + goto err; + if ((EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, + ecp, ecp_len, NULL)) == 0) + goto err; + + ret = 1; + + err: + return ret; +} + +int +ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs) +{ + EC_GROUP *group = NULL; + EC_POINT *point = NULL; + int ret = 0; + + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) + goto err; + + if (!EC_KEY_set_group(ecdh, group)) + goto err; + + if ((point = EC_POINT_new(group)) == NULL) + goto err; + if (EC_POINT_oct2point(group, point, CBS_data(cbs), CBS_len(cbs), + NULL) == 0) + goto err; + if (!EC_KEY_set_public_key(ecdh, point)) + goto err; + + ret = 1; + + err: + EC_GROUP_free(group); + EC_POINT_free(point); + + return ret; +} + +int +ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer, + uint8_t **shared_key, size_t *shared_key_len) +{ + const EC_POINT *point; + uint8_t *key = NULL; + int key_len = 0; + int ret = 0; + + if (!EC_GROUP_check(EC_KEY_get0_group(ecdh), NULL)) + goto err; + if (!EC_GROUP_check(EC_KEY_get0_group(ecdh_peer), NULL)) + goto err; + + if ((point = EC_KEY_get0_public_key(ecdh_peer)) == NULL) + goto err; + + if ((key_len = ECDH_size(ecdh)) <= 0) + goto err; + if ((key = calloc(1, key_len)) == NULL) + goto err; + + if (ECDH_compute_key(key, key_len, point, ecdh, NULL) <= 0) + goto err; + + *shared_key = key; + *shared_key_len = key_len; + key = NULL; + + ret = 1; + + err: + freezero(key, key_len); + + return ret; +} diff --git a/Libraries/libressl/ssl/ssl_lib.c b/Libraries/libressl/ssl/ssl_lib.c new file mode 100644 index 000000000..0ac393f73 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_lib.c @@ -0,0 +1,3695 @@ +/* $OpenBSD: ssl_lib.c,v 1.314 2023/09/19 01:22:31 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" +#include "tls12_internal.h" + +const char *SSL_version_str = OPENSSL_VERSION_TEXT; + +int +SSL_clear(SSL *s) +{ + if (s->method == NULL) { + SSLerror(s, SSL_R_NO_METHOD_SPECIFIED); + return (0); + } + + if (ssl_clear_bad_session(s)) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + s->error = 0; + s->hit = 0; + s->shutdown = 0; + + if (s->renegotiate) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return (0); + } + + s->version = s->method->version; + s->client_version = s->version; + s->rwstate = SSL_NOTHING; + s->rstate = SSL_ST_READ_HEADER; + + tls13_ctx_free(s->tls13); + s->tls13 = NULL; + + ssl3_release_init_buffer(s); + + ssl_clear_cipher_state(s); + + s->first_packet = 0; + + /* + * Check to see if we were changed into a different method, if + * so, revert back if we are not doing session-id reuse. + */ + if (!s->in_handshake && (s->session == NULL) && + (s->method != s->ctx->method)) { + s->method->ssl_free(s); + s->method = s->ctx->method; + if (!s->method->ssl_new(s)) + return (0); + } else + s->method->ssl_clear(s); + + return (1); +} +LSSL_ALIAS(SSL_clear); + +/* Used to change an SSL_CTXs default SSL method type */ +int +SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ + STACK_OF(SSL_CIPHER) *ciphers; + + ctx->method = meth; + + ciphers = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, + ctx->cipher_list_tls13, SSL_DEFAULT_CIPHER_LIST, + ctx->cert); + if (ciphers == NULL || sk_SSL_CIPHER_num(ciphers) <= 0) { + SSLerrorx(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + return (0); + } + return (1); +} +LSSL_ALIAS(SSL_CTX_set_ssl_version); + +SSL * +SSL_new(SSL_CTX *ctx) +{ + SSL *s; + CBS cbs; + + if (ctx == NULL) { + SSLerrorx(SSL_R_NULL_SSL_CTX); + return (NULL); + } + if (ctx->method == NULL) { + SSLerrorx(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + return (NULL); + } + + if ((s = calloc(1, sizeof(*s))) == NULL) + goto err; + + if ((s->rl = tls12_record_layer_new()) == NULL) + goto err; + + s->min_tls_version = ctx->min_tls_version; + s->max_tls_version = ctx->max_tls_version; + s->min_proto_version = ctx->min_proto_version; + s->max_proto_version = ctx->max_proto_version; + + s->options = ctx->options; + s->mode = ctx->mode; + s->max_cert_list = ctx->max_cert_list; + s->num_tickets = ctx->num_tickets; + + if ((s->cert = ssl_cert_dup(ctx->cert)) == NULL) + goto err; + + s->read_ahead = ctx->read_ahead; + s->msg_callback = ctx->msg_callback; + s->msg_callback_arg = ctx->msg_callback_arg; + s->verify_mode = ctx->verify_mode; + s->sid_ctx_length = ctx->sid_ctx_length; + OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); + memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); + s->verify_callback = ctx->default_verify_callback; + s->generate_session_id = ctx->generate_session_id; + + s->param = X509_VERIFY_PARAM_new(); + if (!s->param) + goto err; + X509_VERIFY_PARAM_inherit(s->param, ctx->param); + s->quiet_shutdown = ctx->quiet_shutdown; + s->max_send_fragment = ctx->max_send_fragment; + + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->ctx = ctx; + s->tlsext_debug_cb = NULL; + s->tlsext_debug_arg = NULL; + s->tlsext_ticket_expected = 0; + s->tlsext_status_type = -1; + s->tlsext_status_expected = 0; + s->tlsext_ocsp_ids = NULL; + s->tlsext_ocsp_exts = NULL; + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resp_len = 0; + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->initial_ctx = ctx; + + if (!tlsext_randomize_build_order(s)) + goto err; + + if (ctx->tlsext_ecpointformatlist != NULL) { + s->tlsext_ecpointformatlist = + calloc(ctx->tlsext_ecpointformatlist_length, + sizeof(ctx->tlsext_ecpointformatlist[0])); + if (s->tlsext_ecpointformatlist == NULL) + goto err; + memcpy(s->tlsext_ecpointformatlist, + ctx->tlsext_ecpointformatlist, + ctx->tlsext_ecpointformatlist_length * + sizeof(ctx->tlsext_ecpointformatlist[0])); + s->tlsext_ecpointformatlist_length = + ctx->tlsext_ecpointformatlist_length; + } + if (ctx->tlsext_supportedgroups != NULL) { + s->tlsext_supportedgroups = + calloc(ctx->tlsext_supportedgroups_length, + sizeof(ctx->tlsext_supportedgroups[0])); + if (s->tlsext_supportedgroups == NULL) + goto err; + memcpy(s->tlsext_supportedgroups, + ctx->tlsext_supportedgroups, + ctx->tlsext_supportedgroups_length * + sizeof(ctx->tlsext_supportedgroups[0])); + s->tlsext_supportedgroups_length = + ctx->tlsext_supportedgroups_length; + } + + CBS_init(&cbs, ctx->alpn_client_proto_list, + ctx->alpn_client_proto_list_len); + if (!CBS_stow(&cbs, &s->alpn_client_proto_list, + &s->alpn_client_proto_list_len)) + goto err; + + s->verify_result = X509_V_OK; + + s->method = ctx->method; + s->quic_method = ctx->quic_method; + + if (!s->method->ssl_new(s)) + goto err; + + s->references = 1; + s->server = ctx->method->server; + + SSL_clear(s); + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + + return (s); + + err: + SSL_free(s); + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (NULL); +} +LSSL_ALIAS(SSL_new); + +int +SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > sizeof ctx->sid_ctx) { + SSLerrorx(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return (0); + } + ctx->sid_ctx_length = sid_ctx_len; + memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len); + + return (1); +} +LSSL_ALIAS(SSL_CTX_set_session_id_context); + +int +SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerror(ssl, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return (0); + } + ssl->sid_ctx_length = sid_ctx_len; + memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); + + return (1); +} +LSSL_ALIAS(SSL_set_session_id_context); + +int +SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + ctx->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return (1); +} +LSSL_ALIAS(SSL_CTX_set_generate_session_id); + +int +SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + ssl->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + return (1); +} +LSSL_ALIAS(SSL_set_generate_session_id); + +int +SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len) +{ + /* + * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp + * shows how we can "construct" a session to give us the desired + * check - ie. to find if there's a session in the hash table + * that would conflict with any new session built out of this + * id/id_len and the ssl_version in use by this SSL. + */ + SSL_SESSION r, *p; + + if (id_len > sizeof r.session_id) + return (0); + + r.ssl_version = ssl->version; + r.session_id_length = id_len; + memcpy(r.session_id, id, id_len); + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + return (p != NULL); +} +LSSL_ALIAS(SSL_has_matching_session_id); + +int +SSL_CTX_set_purpose(SSL_CTX *s, int purpose) +{ + return (X509_VERIFY_PARAM_set_purpose(s->param, purpose)); +} +LSSL_ALIAS(SSL_CTX_set_purpose); + +int +SSL_set_purpose(SSL *s, int purpose) +{ + return (X509_VERIFY_PARAM_set_purpose(s->param, purpose)); +} +LSSL_ALIAS(SSL_set_purpose); + +int +SSL_CTX_set_trust(SSL_CTX *s, int trust) +{ + return (X509_VERIFY_PARAM_set_trust(s->param, trust)); +} +LSSL_ALIAS(SSL_CTX_set_trust); + +int +SSL_set_trust(SSL *s, int trust) +{ + return (X509_VERIFY_PARAM_set_trust(s->param, trust)); +} +LSSL_ALIAS(SSL_set_trust); + +int +SSL_set1_host(SSL *s, const char *hostname) +{ + struct in_addr ina; + struct in6_addr in6a; + + if (hostname != NULL && *hostname != '\0' && + (inet_pton(AF_INET, hostname, &ina) == 1 || + inet_pton(AF_INET6, hostname, &in6a) == 1)) + return X509_VERIFY_PARAM_set1_ip_asc(s->param, hostname); + else + return X509_VERIFY_PARAM_set1_host(s->param, hostname, 0); +} +LSSL_ALIAS(SSL_set1_host); + +void +SSL_set_hostflags(SSL *s, unsigned int flags) +{ + X509_VERIFY_PARAM_set_hostflags(s->param, flags); +} +LSSL_ALIAS(SSL_set_hostflags); + +const char * +SSL_get0_peername(SSL *s) +{ + return X509_VERIFY_PARAM_get0_peername(s->param); +} +LSSL_ALIAS(SSL_get0_peername); + +X509_VERIFY_PARAM * +SSL_CTX_get0_param(SSL_CTX *ctx) +{ + return (ctx->param); +} +LSSL_ALIAS(SSL_CTX_get0_param); + +int +SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) +{ + return (X509_VERIFY_PARAM_set1(ctx->param, vpm)); +} +LSSL_ALIAS(SSL_CTX_set1_param); + +X509_VERIFY_PARAM * +SSL_get0_param(SSL *ssl) +{ + return (ssl->param); +} +LSSL_ALIAS(SSL_get0_param); + +int +SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) +{ + return (X509_VERIFY_PARAM_set1(ssl->param, vpm)); +} +LSSL_ALIAS(SSL_set1_param); + +void +SSL_free(SSL *s) +{ + int i; + + if (s == NULL) + return; + + i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL); + if (i > 0) + return; + + X509_VERIFY_PARAM_free(s->param); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + + if (s->bbio != NULL) { + /* If the buffering BIO is in place, pop it off */ + if (s->bbio == s->wbio) { + s->wbio = BIO_pop(s->wbio); + } + BIO_free(s->bbio); + s->bbio = NULL; + } + + if (s->rbio != s->wbio) + BIO_free_all(s->rbio); + BIO_free_all(s->wbio); + + tls13_ctx_free(s->tls13); + + ssl3_release_init_buffer(s); + + sk_SSL_CIPHER_free(s->cipher_list); + sk_SSL_CIPHER_free(s->cipher_list_tls13); + + /* Make the next call work :-) */ + if (s->session != NULL) { + ssl_clear_bad_session(s); + SSL_SESSION_free(s->session); + } + + ssl_clear_cipher_state(s); + + ssl_cert_free(s->cert); + + free(s->tlsext_build_order); + + free(s->tlsext_hostname); + SSL_CTX_free(s->initial_ctx); + + free(s->tlsext_ecpointformatlist); + free(s->tlsext_supportedgroups); + + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + free(s->tlsext_ocsp_resp); + + sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); + + if (s->method != NULL) + s->method->ssl_free(s); + + SSL_CTX_free(s->ctx); + + free(s->alpn_client_proto_list); + + free(s->quic_transport_params); + +#ifndef OPENSSL_NO_SRTP + sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); +#endif + + tls12_record_layer_free(s->rl); + + free(s); +} +LSSL_ALIAS(SSL_free); + +int +SSL_up_ref(SSL *s) +{ + int refs = CRYPTO_add(&s->references, 1, CRYPTO_LOCK_SSL); + return (refs > 1) ? 1 : 0; +} +LSSL_ALIAS(SSL_up_ref); + +void +SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +{ + /* If the output buffering BIO is still in place, remove it */ + if (s->bbio != NULL) { + if (s->wbio == s->bbio) { + s->wbio = BIO_next(s->wbio); + BIO_set_next(s->bbio, NULL); + } + } + + if (s->rbio != rbio && s->rbio != s->wbio) + BIO_free_all(s->rbio); + if (s->wbio != wbio) + BIO_free_all(s->wbio); + s->rbio = rbio; + s->wbio = wbio; +} +LSSL_ALIAS(SSL_set_bio); + +BIO * +SSL_get_rbio(const SSL *s) +{ + return (s->rbio); +} +LSSL_ALIAS(SSL_get_rbio); + +void +SSL_set0_rbio(SSL *s, BIO *rbio) +{ + BIO_free_all(s->rbio); + s->rbio = rbio; +} +LSSL_ALIAS(SSL_set0_rbio); + +BIO * +SSL_get_wbio(const SSL *s) +{ + return (s->wbio); +} +LSSL_ALIAS(SSL_get_wbio); + +int +SSL_get_fd(const SSL *s) +{ + return (SSL_get_rfd(s)); +} +LSSL_ALIAS(SSL_get_fd); + +int +SSL_get_rfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_rbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} +LSSL_ALIAS(SSL_get_rfd); + +int +SSL_get_wfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_wbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} +LSSL_ALIAS(SSL_get_wfd); + +int +SSL_set_fd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerror(s, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, bio); + ret = 1; + err: + return (ret); +} +LSSL_ALIAS(SSL_set_fd); + +int +SSL_set_wfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->rbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerror(s, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, SSL_get_rbio(s), bio); + } else + SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s)); + ret = 1; + err: + return (ret); +} +LSSL_ALIAS(SSL_set_wfd); + +int +SSL_set_rfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->wbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerror(s, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, SSL_get_wbio(s)); + } else + SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s)); + ret = 1; + err: + return (ret); +} +LSSL_ALIAS(SSL_set_rfd); + + +/* return length of latest Finished message we sent, copy to 'buf' */ +size_t +SSL_get_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret; + + ret = s->s3->hs.finished_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->hs.finished, count); + return (ret); +} +LSSL_ALIAS(SSL_get_finished); + +/* return length of latest Finished message we expected, copy to 'buf' */ +size_t +SSL_get_peer_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret; + + ret = s->s3->hs.peer_finished_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->hs.peer_finished, count); + return (ret); +} +LSSL_ALIAS(SSL_get_peer_finished); + + +int +SSL_get_verify_mode(const SSL *s) +{ + return (s->verify_mode); +} +LSSL_ALIAS(SSL_get_verify_mode); + +int +SSL_get_verify_depth(const SSL *s) +{ + return (X509_VERIFY_PARAM_get_depth(s->param)); +} +LSSL_ALIAS(SSL_get_verify_depth); + +int +(*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) +{ + return (s->verify_callback); +} +LSSL_ALIAS(SSL_get_verify_callback); + +void +SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb) +{ + ctx->keylog_callback = cb; +} +LSSL_ALIAS(SSL_CTX_set_keylog_callback); + +SSL_CTX_keylog_cb_func +SSL_CTX_get_keylog_callback(const SSL_CTX *ctx) +{ + return (ctx->keylog_callback); +} +LSSL_ALIAS(SSL_CTX_get_keylog_callback); + +int +SSL_set_num_tickets(SSL *s, size_t num_tickets) +{ + s->num_tickets = num_tickets; + + return 1; +} +LSSL_ALIAS(SSL_set_num_tickets); + +size_t +SSL_get_num_tickets(const SSL *s) +{ + return s->num_tickets; +} +LSSL_ALIAS(SSL_get_num_tickets); + +int +SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets) +{ + ctx->num_tickets = num_tickets; + + return 1; +} +LSSL_ALIAS(SSL_CTX_set_num_tickets); + +size_t +SSL_CTX_get_num_tickets(const SSL_CTX *ctx) +{ + return ctx->num_tickets; +} +LSSL_ALIAS(SSL_CTX_get_num_tickets); + +int +SSL_CTX_get_verify_mode(const SSL_CTX *ctx) +{ + return (ctx->verify_mode); +} +LSSL_ALIAS(SSL_CTX_get_verify_mode); + +int +SSL_CTX_get_verify_depth(const SSL_CTX *ctx) +{ + return (X509_VERIFY_PARAM_get_depth(ctx->param)); +} +LSSL_ALIAS(SSL_CTX_get_verify_depth); + +int +(*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) +{ + return (ctx->default_verify_callback); +} +LSSL_ALIAS(SSL_CTX_get_verify_callback); + +void +SSL_set_verify(SSL *s, int mode, + int (*callback)(int ok, X509_STORE_CTX *ctx)) +{ + s->verify_mode = mode; + if (callback != NULL) + s->verify_callback = callback; +} +LSSL_ALIAS(SSL_set_verify); + +void +SSL_set_verify_depth(SSL *s, int depth) +{ + X509_VERIFY_PARAM_set_depth(s->param, depth); +} +LSSL_ALIAS(SSL_set_verify_depth); + +void +SSL_set_read_ahead(SSL *s, int yes) +{ + s->read_ahead = yes; +} +LSSL_ALIAS(SSL_set_read_ahead); + +int +SSL_get_read_ahead(const SSL *s) +{ + return (s->read_ahead); +} +LSSL_ALIAS(SSL_get_read_ahead); + +int +SSL_pending(const SSL *s) +{ + return (s->method->ssl_pending(s)); +} +LSSL_ALIAS(SSL_pending); + +X509 * +SSL_get_peer_certificate(const SSL *s) +{ + X509 *cert; + + if (s == NULL || s->session == NULL) + return NULL; + + if ((cert = s->session->peer_cert) == NULL) + return NULL; + + X509_up_ref(cert); + + return cert; +} +LSSL_ALIAS(SSL_get_peer_certificate); + +STACK_OF(X509) * +SSL_get_peer_cert_chain(const SSL *s) +{ + if (s == NULL) + return NULL; + + /* + * Achtung! Due to API inconsistency, a client includes the peer's leaf + * certificate in the peer certificate chain, while a server does not. + */ + if (!s->server) + return s->s3->hs.peer_certs; + + return s->s3->hs.peer_certs_no_leaf; +} +LSSL_ALIAS(SSL_get_peer_cert_chain); + +STACK_OF(X509) * +SSL_get0_verified_chain(const SSL *s) +{ + if (s->s3 == NULL) + return NULL; + return s->s3->hs.verified_chain; +} +LSSL_ALIAS(SSL_get0_verified_chain); + +/* + * Now in theory, since the calling process own 't' it should be safe to + * modify. We need to be able to read f without being hassled + */ +int +SSL_copy_session_id(SSL *t, const SSL *f) +{ + SSL_CERT *tmp; + + /* Do we need to do SSL locking? */ + if (!SSL_set_session(t, SSL_get_session(f))) + return 0; + + /* What if we are set up for one protocol but want to talk another? */ + if (t->method != f->method) { + t->method->ssl_free(t); + t->method = f->method; + if (!t->method->ssl_new(t)) + return 0; + } + + tmp = t->cert; + if (f->cert != NULL) { + CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + t->cert = f->cert; + } else + t->cert = NULL; + ssl_cert_free(tmp); + + if (!SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length)) + return 0; + + return 1; +} +LSSL_ALIAS(SSL_copy_session_id); + +/* Fix this so it checks all the valid key/cert options */ +int +SSL_CTX_check_private_key(const SSL_CTX *ctx) +{ + if ((ctx == NULL) || (ctx->cert == NULL) || + (ctx->cert->key->x509 == NULL)) { + SSLerrorx(SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ctx->cert->key->privatekey == NULL) { + SSLerrorx(SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key(ctx->cert->key->x509, + ctx->cert->key->privatekey)); +} +LSSL_ALIAS(SSL_CTX_check_private_key); + +/* Fix this function so that it takes an optional type parameter */ +int +SSL_check_private_key(const SSL *ssl) +{ + if (ssl == NULL) { + SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (ssl->cert == NULL) { + SSLerror(ssl, SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ssl->cert->key->x509 == NULL) { + SSLerror(ssl, SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ssl->cert->key->privatekey == NULL) { + SSLerror(ssl, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key(ssl->cert->key->x509, + ssl->cert->key->privatekey)); +} +LSSL_ALIAS(SSL_check_private_key); + +int +SSL_accept(SSL *s) +{ + if (s->handshake_func == NULL) + SSL_set_accept_state(s); /* Not properly initialized yet */ + + return (s->method->ssl_accept(s)); +} +LSSL_ALIAS(SSL_accept); + +int +SSL_connect(SSL *s) +{ + if (s->handshake_func == NULL) + SSL_set_connect_state(s); /* Not properly initialized yet */ + + return (s->method->ssl_connect(s)); +} +LSSL_ALIAS(SSL_connect); + +int +SSL_is_dtls(const SSL *s) +{ + return s->method->dtls; +} +LSSL_ALIAS(SSL_is_dtls); + +int +SSL_is_server(const SSL *s) +{ + return s->server; +} +LSSL_ALIAS(SSL_is_server); + +static long +ssl_get_default_timeout() +{ + /* + * 2 hours, the 24 hours mentioned in the TLSv1 spec + * is way too long for http, the cache would over fill. + */ + return (2 * 60 * 60); +} + +long +SSL_get_default_timeout(const SSL *s) +{ + return (ssl_get_default_timeout()); +} +LSSL_ALIAS(SSL_get_default_timeout); + +int +SSL_read(SSL *s, void *buf, int num) +{ + if (num < 0) { + SSLerror(s, SSL_R_BAD_LENGTH); + return -1; + } + + if (SSL_is_quic(s)) { + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (-1); + } + + if (s->handshake_func == NULL) { + SSLerror(s, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } + return ssl3_read(s, buf, num); +} +LSSL_ALIAS(SSL_read); + +int +SSL_read_ex(SSL *s, void *buf, size_t num, size_t *bytes_read) +{ + int ret; + + /* We simply don't bother supporting enormous reads */ + if (num > INT_MAX) { + SSLerror(s, SSL_R_BAD_LENGTH); + return 0; + } + + ret = SSL_read(s, buf, (int)num); + if (ret < 0) + ret = 0; + *bytes_read = ret; + + return ret > 0; +} +LSSL_ALIAS(SSL_read_ex); + +int +SSL_peek(SSL *s, void *buf, int num) +{ + if (num < 0) { + SSLerror(s, SSL_R_BAD_LENGTH); + return -1; + } + + if (SSL_is_quic(s)) { + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (-1); + } + + if (s->handshake_func == NULL) { + SSLerror(s, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + return (0); + } + return ssl3_peek(s, buf, num); +} +LSSL_ALIAS(SSL_peek); + +int +SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *bytes_peeked) +{ + int ret; + + /* We simply don't bother supporting enormous peeks */ + if (num > INT_MAX) { + SSLerror(s, SSL_R_BAD_LENGTH); + return 0; + } + + ret = SSL_peek(s, buf, (int)num); + if (ret < 0) + ret = 0; + *bytes_peeked = ret; + + return ret > 0; +} +LSSL_ALIAS(SSL_peek_ex); + +int +SSL_write(SSL *s, const void *buf, int num) +{ + if (num < 0) { + SSLerror(s, SSL_R_BAD_LENGTH); + return -1; + } + + if (SSL_is_quic(s)) { + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (-1); + } + + if (s->handshake_func == NULL) { + SSLerror(s, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + SSLerror(s, SSL_R_PROTOCOL_IS_SHUTDOWN); + return (-1); + } + return ssl3_write(s, buf, num); +} +LSSL_ALIAS(SSL_write); + +int +SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *bytes_written) +{ + int ret; + + /* We simply don't bother supporting enormous writes */ + if (num > INT_MAX) { + SSLerror(s, SSL_R_BAD_LENGTH); + return 0; + } + + if (num == 0) { + /* This API is special */ + bytes_written = 0; + return 1; + } + + ret = SSL_write(s, buf, (int)num); + if (ret < 0) + ret = 0; + *bytes_written = ret; + + return ret > 0; +} +LSSL_ALIAS(SSL_write_ex); + +uint32_t +SSL_CTX_get_max_early_data(const SSL_CTX *ctx) +{ + return 0; +} +LSSL_ALIAS(SSL_CTX_get_max_early_data); + +int +SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data) +{ + return 1; +} +LSSL_ALIAS(SSL_CTX_set_max_early_data); + +uint32_t +SSL_get_max_early_data(const SSL *s) +{ + return 0; +} +LSSL_ALIAS(SSL_get_max_early_data); + +int +SSL_set_max_early_data(SSL *s, uint32_t max_early_data) +{ + return 1; +} +LSSL_ALIAS(SSL_set_max_early_data); + +int +SSL_get_early_data_status(const SSL *s) +{ + return SSL_EARLY_DATA_REJECTED; +} +LSSL_ALIAS(SSL_get_early_data_status); + +int +SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) +{ + *readbytes = 0; + + if (!s->server) { + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return SSL_READ_EARLY_DATA_ERROR; + } + + return SSL_READ_EARLY_DATA_FINISH; +} +LSSL_ALIAS(SSL_read_early_data); + +int +SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) +{ + *written = 0; + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; +} +LSSL_ALIAS(SSL_write_early_data); + +int +SSL_shutdown(SSL *s) +{ + /* + * Note that this function behaves differently from what one might + * expect. Return values are 0 for no success (yet), + * 1 for success; but calling it once is usually not enough, + * even if blocking I/O is used (see ssl3_shutdown). + */ + + if (s->handshake_func == NULL) { + SSLerror(s, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s != NULL && !SSL_in_init(s)) + return (s->method->ssl_shutdown(s)); + + return (1); +} +LSSL_ALIAS(SSL_shutdown); + +int +SSL_renegotiate(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 1; + + return (s->method->ssl_renegotiate(s)); +} +LSSL_ALIAS(SSL_renegotiate); + +int +SSL_renegotiate_abbreviated(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 0; + + return (s->method->ssl_renegotiate(s)); +} +LSSL_ALIAS(SSL_renegotiate_abbreviated); + +int +SSL_renegotiate_pending(SSL *s) +{ + /* + * Becomes true when negotiation is requested; + * false again once a handshake has finished. + */ + return (s->renegotiate != 0); +} +LSSL_ALIAS(SSL_renegotiate_pending); + +long +SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (s->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = s->read_ahead; + s->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + s->msg_callback_arg = parg; + return (1); + + case SSL_CTRL_OPTIONS: + return (s->options|=larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (s->options&=~larg); + case SSL_CTRL_MODE: + return (s->mode|=larg); + case SSL_CTRL_CLEAR_MODE: + return (s->mode &=~larg); + case SSL_CTRL_GET_MAX_CERT_LIST: + return (s->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = s->max_cert_list; + s->max_cert_list = larg; + return (l); + case SSL_CTRL_SET_MTU: +#ifndef OPENSSL_NO_DTLS1 + if (larg < (long)dtls1_min_mtu()) + return (0); +#endif + if (SSL_is_dtls(s)) { + s->d1->mtu = larg; + return (larg); + } + return (0); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return (0); + s->max_send_fragment = larg; + return (1); + case SSL_CTRL_GET_RI_SUPPORT: + if (s->s3) + return (s->s3->send_connection_binding); + else return (0); + default: + if (SSL_is_dtls(s)) + return dtls1_ctrl(s, cmd, larg, parg); + return ssl3_ctrl(s, cmd, larg, parg); + } +} +LSSL_ALIAS(SSL_ctrl); + +long +SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + s->msg_callback = (ssl_msg_callback_fn *)(fp); + return (1); + + default: + return (ssl3_callback_ctrl(s, cmd, fp)); + } +} +LSSL_ALIAS(SSL_callback_ctrl); + +struct lhash_st_SSL_SESSION * +SSL_CTX_sessions(SSL_CTX *ctx) +{ + return (ctx->sessions); +} +LSSL_ALIAS(SSL_CTX_sessions); + +long +SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (ctx->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = ctx->read_ahead; + ctx->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + ctx->msg_callback_arg = parg; + return (1); + + case SSL_CTRL_GET_MAX_CERT_LIST: + return (ctx->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = ctx->max_cert_list; + ctx->max_cert_list = larg; + return (l); + + case SSL_CTRL_SET_SESS_CACHE_SIZE: + l = ctx->session_cache_size; + ctx->session_cache_size = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_SIZE: + return (ctx->session_cache_size); + case SSL_CTRL_SET_SESS_CACHE_MODE: + l = ctx->session_cache_mode; + ctx->session_cache_mode = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_MODE: + return (ctx->session_cache_mode); + + case SSL_CTRL_SESS_NUMBER: + return (lh_SSL_SESSION_num_items(ctx->sessions)); + case SSL_CTRL_SESS_CONNECT: + return (ctx->stats.sess_connect); + case SSL_CTRL_SESS_CONNECT_GOOD: + return (ctx->stats.sess_connect_good); + case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: + return (ctx->stats.sess_connect_renegotiate); + case SSL_CTRL_SESS_ACCEPT: + return (ctx->stats.sess_accept); + case SSL_CTRL_SESS_ACCEPT_GOOD: + return (ctx->stats.sess_accept_good); + case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: + return (ctx->stats.sess_accept_renegotiate); + case SSL_CTRL_SESS_HIT: + return (ctx->stats.sess_hit); + case SSL_CTRL_SESS_CB_HIT: + return (ctx->stats.sess_cb_hit); + case SSL_CTRL_SESS_MISSES: + return (ctx->stats.sess_miss); + case SSL_CTRL_SESS_TIMEOUTS: + return (ctx->stats.sess_timeout); + case SSL_CTRL_SESS_CACHE_FULL: + return (ctx->stats.sess_cache_full); + case SSL_CTRL_OPTIONS: + return (ctx->options|=larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (ctx->options&=~larg); + case SSL_CTRL_MODE: + return (ctx->mode|=larg); + case SSL_CTRL_CLEAR_MODE: + return (ctx->mode&=~larg); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return (0); + ctx->max_send_fragment = larg; + return (1); + default: + return (ssl3_ctx_ctrl(ctx, cmd, larg, parg)); + } +} +LSSL_ALIAS(SSL_CTX_ctrl); + +long +SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + ctx->msg_callback = (ssl_msg_callback_fn *)fp; + return (1); + + default: + return (ssl3_ctx_callback_ctrl(ctx, cmd, fp)); + } +} +LSSL_ALIAS(SSL_CTX_callback_ctrl); + +int +ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b) +{ + long l; + + l = a->id - b->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1:-1); +} + +STACK_OF(SSL_CIPHER) * +SSL_get_ciphers(const SSL *s) +{ + if (s == NULL) + return (NULL); + if (s->cipher_list != NULL) + return (s->cipher_list); + + return (s->ctx->cipher_list); +} +LSSL_ALIAS(SSL_get_ciphers); + +STACK_OF(SSL_CIPHER) * +SSL_get_client_ciphers(const SSL *s) +{ + if (s == NULL || s->session == NULL || !s->server) + return NULL; + return s->session->ciphers; +} +LSSL_ALIAS(SSL_get_client_ciphers); + +STACK_OF(SSL_CIPHER) * +SSL_get1_supported_ciphers(SSL *s) +{ + STACK_OF(SSL_CIPHER) *supported_ciphers = NULL, *ciphers; + SSL_CIPHER *cipher; + uint16_t min_vers, max_vers; + int i; + + if (s == NULL) + return NULL; + if (!ssl_supported_tls_version_range(s, &min_vers, &max_vers)) + return NULL; + if ((ciphers = SSL_get_ciphers(s)) == NULL) + return NULL; + if ((supported_ciphers = sk_SSL_CIPHER_new_null()) == NULL) + return NULL; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL) + goto err; + if (!ssl_cipher_allowed_in_tls_version_range(cipher, min_vers, + max_vers)) + continue; + if (!ssl_security_supported_cipher(s, cipher)) + continue; + if (!sk_SSL_CIPHER_push(supported_ciphers, cipher)) + goto err; + } + + if (sk_SSL_CIPHER_num(supported_ciphers) > 0) + return supported_ciphers; + + err: + sk_SSL_CIPHER_free(supported_ciphers); + return NULL; +} +LSSL_ALIAS(SSL_get1_supported_ciphers); + +/* See if we have any ECC cipher suites. */ +int +ssl_has_ecc_ciphers(SSL *s) +{ + STACK_OF(SSL_CIPHER) *ciphers; + unsigned long alg_k, alg_a; + SSL_CIPHER *cipher; + int i; + + if ((ciphers = SSL_get_ciphers(s)) == NULL) + return 0; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + cipher = sk_SSL_CIPHER_value(ciphers, i); + + alg_k = cipher->algorithm_mkey; + alg_a = cipher->algorithm_auth; + + if ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) + return 1; + } + + return 0; +} + +/* The old interface to get the same thing as SSL_get_ciphers(). */ +const char * +SSL_get_cipher_list(const SSL *s, int n) +{ + STACK_OF(SSL_CIPHER) *ciphers; + const SSL_CIPHER *cipher; + + if ((ciphers = SSL_get_ciphers(s)) == NULL) + return (NULL); + if ((cipher = sk_SSL_CIPHER_value(ciphers, n)) == NULL) + return (NULL); + + return (cipher->name); +} +LSSL_ALIAS(SSL_get_cipher_list); + +STACK_OF(SSL_CIPHER) * +SSL_CTX_get_ciphers(const SSL_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->cipher_list; +} +LSSL_ALIAS(SSL_CTX_get_ciphers); + +/* Specify the ciphers to be used by default by the SSL_CTX. */ +int +SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) +{ + STACK_OF(SSL_CIPHER) *ciphers; + + /* + * ssl_create_cipher_list may return an empty stack if it was unable to + * find a cipher matching the given rule string (for example if the + * rule string specifies a cipher which has been disabled). This is not + * an error as far as ssl_create_cipher_list is concerned, and hence + * ctx->cipher_list has been updated. + */ + ciphers = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, + ctx->cipher_list_tls13, str, ctx->cert); + if (ciphers == NULL) { + return (0); + } else if (sk_SSL_CIPHER_num(ciphers) == 0) { + SSLerrorx(SSL_R_NO_CIPHER_MATCH); + return (0); + } + return (1); +} +LSSL_ALIAS(SSL_CTX_set_cipher_list); + +int +SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) +{ + if (!ssl_parse_ciphersuites(&ctx->cipher_list_tls13, str)) { + SSLerrorx(SSL_R_NO_CIPHER_MATCH); + return 0; + } + if (!ssl_merge_cipherlists(ctx->cipher_list, + ctx->cipher_list_tls13, &ctx->cipher_list)) + return 0; + + return 1; +} +LSSL_ALIAS(SSL_CTX_set_ciphersuites); + +/* Specify the ciphers to be used by the SSL. */ +int +SSL_set_cipher_list(SSL *s, const char *str) +{ + STACK_OF(SSL_CIPHER) *ciphers, *ciphers_tls13; + + if ((ciphers_tls13 = s->cipher_list_tls13) == NULL) + ciphers_tls13 = s->ctx->cipher_list_tls13; + + /* See comment in SSL_CTX_set_cipher_list. */ + ciphers = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, + ciphers_tls13, str, s->cert); + if (ciphers == NULL) { + return (0); + } else if (sk_SSL_CIPHER_num(ciphers) == 0) { + SSLerror(s, SSL_R_NO_CIPHER_MATCH); + return (0); + } + return (1); +} +LSSL_ALIAS(SSL_set_cipher_list); + +int +SSL_set_ciphersuites(SSL *s, const char *str) +{ + STACK_OF(SSL_CIPHER) *ciphers; + + if ((ciphers = s->cipher_list) == NULL) + ciphers = s->ctx->cipher_list; + + if (!ssl_parse_ciphersuites(&s->cipher_list_tls13, str)) { + SSLerrorx(SSL_R_NO_CIPHER_MATCH); + return (0); + } + if (!ssl_merge_cipherlists(ciphers, s->cipher_list_tls13, + &s->cipher_list)) + return 0; + + return 1; +} +LSSL_ALIAS(SSL_set_ciphersuites); + +char * +SSL_get_shared_ciphers(const SSL *s, char *buf, int len) +{ + STACK_OF(SSL_CIPHER) *client_ciphers, *server_ciphers; + const SSL_CIPHER *cipher; + size_t curlen = 0; + char *end; + int i; + + if (!s->server || s->session == NULL || len < 2) + return NULL; + + if ((client_ciphers = s->session->ciphers) == NULL) + return NULL; + if ((server_ciphers = SSL_get_ciphers(s)) == NULL) + return NULL; + if (sk_SSL_CIPHER_num(client_ciphers) == 0 || + sk_SSL_CIPHER_num(server_ciphers) == 0) + return NULL; + + buf[0] = '\0'; + for (i = 0; i < sk_SSL_CIPHER_num(client_ciphers); i++) { + cipher = sk_SSL_CIPHER_value(client_ciphers, i); + + if (sk_SSL_CIPHER_find(server_ciphers, cipher) < 0) + continue; + + end = buf + curlen; + if (strlcat(buf, cipher->name, len) >= len || + (curlen = strlcat(buf, ":", len)) >= len) { + /* remove truncated cipher from list */ + *end = '\0'; + break; + } + } + /* remove trailing colon */ + if ((end = strrchr(buf, ':')) != NULL) + *end = '\0'; + return buf; +} +LSSL_ALIAS(SSL_get_shared_ciphers); + +/* + * Return a servername extension value if provided in Client Hello, or NULL. + * So far, only host_name types are defined (RFC 3546). + */ +const char * +SSL_get_servername(const SSL *s, const int type) +{ + if (type != TLSEXT_NAMETYPE_host_name) + return (NULL); + + return (s->session && !s->tlsext_hostname ? + s->session->tlsext_hostname : + s->tlsext_hostname); +} +LSSL_ALIAS(SSL_get_servername); + +int +SSL_get_servername_type(const SSL *s) +{ + if (s->session && + (!s->tlsext_hostname ? + s->session->tlsext_hostname : s->tlsext_hostname)) + return (TLSEXT_NAMETYPE_host_name); + return (-1); +} +LSSL_ALIAS(SSL_get_servername_type); + +/* + * SSL_select_next_proto implements standard protocol selection. It is + * expected that this function is called from the callback set by + * SSL_CTX_set_alpn_select_cb. + * + * The protocol data is assumed to be a vector of 8-bit, length prefixed byte + * strings. The length byte itself is not included in the length. A byte + * string of length 0 is invalid. No byte string may be truncated. + * + * It returns either: + * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or + * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. + */ +int +SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *server, unsigned int server_len, + const unsigned char *client, unsigned int client_len) +{ + unsigned int i, j; + const unsigned char *result; + int status = OPENSSL_NPN_UNSUPPORTED; + + /* + * For each protocol in server preference order, + * see if we support it. + */ + for (i = 0; i < server_len; ) { + for (j = 0; j < client_len; ) { + if (server[i] == client[j] && + memcmp(&server[i + 1], + &client[j + 1], server[i]) == 0) { + /* We found a match */ + result = &server[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += client[j]; + j++; + } + i += server[i]; + i++; + } + + /* There's no overlap between our protocols and the server's list. */ + result = client; + status = OPENSSL_NPN_NO_OVERLAP; + + found: + *out = (unsigned char *) result + 1; + *outlen = result[0]; + return (status); +} +LSSL_ALIAS(SSL_select_next_proto); + +/* SSL_get0_next_proto_negotiated is deprecated. */ +void +SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned int *len) +{ + *data = NULL; + *len = 0; +} +LSSL_ALIAS(SSL_get0_next_proto_negotiated); + +/* SSL_CTX_set_next_protos_advertised_cb is deprecated. */ +void +SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, + const unsigned char **out, unsigned int *outlen, void *arg), void *arg) +{ +} +LSSL_ALIAS(SSL_CTX_set_next_protos_advertised_cb); + +/* SSL_CTX_set_next_proto_select_cb is deprecated. */ +void +SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, + unsigned char **out, unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg), void *arg) +{ +} +LSSL_ALIAS(SSL_CTX_set_next_proto_select_cb); + +/* + * SSL_CTX_set_alpn_protos sets the ALPN protocol list to the specified + * protocols, which must be in wire-format (i.e. a series of non-empty, + * 8-bit length-prefixed strings). Returns 0 on success. + */ +int +SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len) +{ + CBS cbs; + int failed = 1; + + if (protos == NULL) + protos_len = 0; + + CBS_init(&cbs, protos, protos_len); + + if (protos_len > 0) { + if (!tlsext_alpn_check_format(&cbs)) + goto err; + } + + if (!CBS_stow(&cbs, &ctx->alpn_client_proto_list, + &ctx->alpn_client_proto_list_len)) + goto err; + + failed = 0; + + err: + /* NOTE: Return values are the reverse of what you expect. */ + return failed; +} +LSSL_ALIAS(SSL_CTX_set_alpn_protos); + +/* + * SSL_set_alpn_protos sets the ALPN protocol list to the specified + * protocols, which must be in wire-format (i.e. a series of non-empty, + * 8-bit length-prefixed strings). Returns 0 on success. + */ +int +SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len) +{ + CBS cbs; + int failed = 1; + + if (protos == NULL) + protos_len = 0; + + CBS_init(&cbs, protos, protos_len); + + if (protos_len > 0) { + if (!tlsext_alpn_check_format(&cbs)) + goto err; + } + + if (!CBS_stow(&cbs, &ssl->alpn_client_proto_list, + &ssl->alpn_client_proto_list_len)) + goto err; + + failed = 0; + + err: + /* NOTE: Return values are the reverse of what you expect. */ + return failed; +} +LSSL_ALIAS(SSL_set_alpn_protos); + +/* + * SSL_CTX_set_alpn_select_cb sets a callback function that is called during + * ClientHello processing in order to select an ALPN protocol from the + * client's list of offered protocols. + */ +void +SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx, + int (*cb) (SSL *ssl, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg), void *arg) +{ + ctx->alpn_select_cb = cb; + ctx->alpn_select_cb_arg = arg; +} +LSSL_ALIAS(SSL_CTX_set_alpn_select_cb); + +/* + * SSL_get0_alpn_selected gets the selected ALPN protocol (if any). On return + * it sets data to point to len bytes of protocol name (not including the + * leading length-prefix byte). If the server didn't respond with* a negotiated + * protocol then len will be zero. + */ +void +SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len) +{ + *data = ssl->s3->alpn_selected; + *len = ssl->s3->alpn_selected_len; +} +LSSL_ALIAS(SSL_get0_alpn_selected); + +void +SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb) +{ + return; +} +LSSL_ALIAS(SSL_set_psk_use_session_callback); + +int +SSL_export_keying_material(SSL *s, unsigned char *out, size_t out_len, + const char *label, size_t label_len, const unsigned char *context, + size_t context_len, int use_context) +{ + if (s->tls13 != NULL && s->version == TLS1_3_VERSION) { + if (!use_context) { + context = NULL; + context_len = 0; + } + return tls13_exporter(s->tls13, label, label_len, context, + context_len, out, out_len); + } + + return tls12_exporter(s, label, label_len, context, context_len, + use_context, out, out_len); +} +LSSL_ALIAS(SSL_export_keying_material); + +static unsigned long +ssl_session_hash(const SSL_SESSION *a) +{ + unsigned long l; + + l = (unsigned long) + ((unsigned int) a->session_id[0] )| + ((unsigned int) a->session_id[1]<< 8L)| + ((unsigned long)a->session_id[2]<<16L)| + ((unsigned long)a->session_id[3]<<24L); + return (l); +} + +/* + * NB: If this function (or indeed the hash function which uses a sort of + * coarser function than this one) is changed, ensure + * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being + * able to construct an SSL_SESSION that will collide with any existing session + * with a matching session ID. + */ +static int +ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) +{ + if (a->ssl_version != b->ssl_version) + return (1); + if (a->session_id_length != b->session_id_length) + return (1); + if (timingsafe_memcmp(a->session_id, b->session_id, a->session_id_length) != 0) + return (1); + return (0); +} + +/* + * These wrapper functions should remain rather than redeclaring + * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each + * variable. The reason is that the functions aren't static, they're exposed via + * ssl.h. + */ +static unsigned long +ssl_session_LHASH_HASH(const void *arg) +{ + const SSL_SESSION *a = arg; + + return ssl_session_hash(a); +} + +static int +ssl_session_LHASH_COMP(const void *arg1, const void *arg2) +{ + const SSL_SESSION *a = arg1; + const SSL_SESSION *b = arg2; + + return ssl_session_cmp(a, b); +} + +SSL_CTX * +SSL_CTX_new(const SSL_METHOD *meth) +{ + SSL_CTX *ret; + + if (!OPENSSL_init_ssl(0, NULL)) { + SSLerrorx(SSL_R_LIBRARY_BUG); + return (NULL); + } + + if (meth == NULL) { + SSLerrorx(SSL_R_NULL_SSL_METHOD_PASSED); + return (NULL); + } + + if ((ret = calloc(1, sizeof(*ret))) == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (NULL); + } + + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { + SSLerrorx(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); + goto err; + } + + ret->method = meth; + ret->min_tls_version = meth->min_tls_version; + ret->max_tls_version = meth->max_tls_version; + ret->min_proto_version = 0; + ret->max_proto_version = 0; + ret->mode = SSL_MODE_AUTO_RETRY; + + ret->cert_store = NULL; + ret->session_cache_mode = SSL_SESS_CACHE_SERVER; + ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + ret->session_cache_head = NULL; + ret->session_cache_tail = NULL; + + /* We take the system default */ + ret->session_timeout = ssl_get_default_timeout(); + + ret->new_session_cb = NULL; + ret->remove_session_cb = NULL; + ret->get_session_cb = NULL; + ret->generate_session_id = NULL; + + memset((char *)&ret->stats, 0, sizeof(ret->stats)); + + ret->references = 1; + ret->quiet_shutdown = 0; + + ret->info_callback = NULL; + + ret->app_verify_callback = NULL; + ret->app_verify_arg = NULL; + + ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + ret->read_ahead = 0; + ret->msg_callback = NULL; + ret->msg_callback_arg = NULL; + ret->verify_mode = SSL_VERIFY_NONE; + ret->sid_ctx_length = 0; + ret->default_verify_callback = NULL; + + if ((ret->cert = ssl_cert_new()) == NULL) + goto err; + + ret->default_passwd_callback = NULL; + ret->default_passwd_callback_userdata = NULL; + ret->client_cert_cb = NULL; + ret->app_gen_cookie_cb = NULL; + ret->app_verify_cookie_cb = NULL; + + ret->sessions = lh_SSL_SESSION_new(); + if (ret->sessions == NULL) + goto err; + ret->cert_store = X509_STORE_new(); + if (ret->cert_store == NULL) + goto err; + + ssl_create_cipher_list(ret->method, &ret->cipher_list, + NULL, SSL_DEFAULT_CIPHER_LIST, ret->cert); + if (ret->cipher_list == NULL || + sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { + SSLerrorx(SSL_R_LIBRARY_HAS_NO_CIPHERS); + goto err2; + } + + ret->param = X509_VERIFY_PARAM_new(); + if (!ret->param) + goto err; + + if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL) + goto err; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); + + ret->extra_certs = NULL; + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + + ret->tlsext_servername_callback = 0; + ret->tlsext_servername_arg = NULL; + + /* Setup RFC4507 ticket keys */ + arc4random_buf(ret->tlsext_tick_key_name, 16); + arc4random_buf(ret->tlsext_tick_hmac_key, 16); + arc4random_buf(ret->tlsext_tick_aes_key, 16); + + ret->tlsext_status_cb = 0; + ret->tlsext_status_arg = NULL; + +#ifndef OPENSSL_NO_ENGINE + ret->client_cert_engine = NULL; +#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +#define eng_strx(x) #x +#define eng_str(x) eng_strx(x) + /* Use specific client engine automatically... ignore errors */ + { + ENGINE *eng; + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + if (!eng) { + ERR_clear_error(); + ENGINE_load_builtin_engines(); + eng = ENGINE_by_id(eng_str( + OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + } + if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) + ERR_clear_error(); + } +#endif +#endif + /* + * Default is to connect to non-RI servers. When RI is more widely + * deployed might change this. + */ + ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + + return (ret); + err: + SSLerrorx(ERR_R_MALLOC_FAILURE); + err2: + SSL_CTX_free(ret); + return (NULL); +} +LSSL_ALIAS(SSL_CTX_new); + +void +SSL_CTX_free(SSL_CTX *ctx) +{ + int i; + + if (ctx == NULL) + return; + + i = CRYPTO_add(&ctx->references, -1, CRYPTO_LOCK_SSL_CTX); + if (i > 0) + return; + + X509_VERIFY_PARAM_free(ctx->param); + + /* + * Free internal session cache. However: the remove_cb() may reference + * the ex_data of SSL_CTX, thus the ex_data store can only be removed + * after the sessions were flushed. + * As the ex_data handling routines might also touch the session cache, + * the most secure solution seems to be: empty (flush) the cache, then + * free ex_data, then finally free the cache. + * (See ticket [openssl.org #212].) + */ + if (ctx->sessions != NULL) + SSL_CTX_flush_sessions(ctx, 0); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ctx, &ctx->ex_data); + + lh_SSL_SESSION_free(ctx->sessions); + + X509_STORE_free(ctx->cert_store); + sk_SSL_CIPHER_free(ctx->cipher_list); + sk_SSL_CIPHER_free(ctx->cipher_list_tls13); + ssl_cert_free(ctx->cert); + sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free); + sk_X509_pop_free(ctx->extra_certs, X509_free); + +#ifndef OPENSSL_NO_SRTP + if (ctx->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles); +#endif + +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(ctx->client_cert_engine); +#endif + + free(ctx->tlsext_ecpointformatlist); + free(ctx->tlsext_supportedgroups); + + free(ctx->alpn_client_proto_list); + + free(ctx); +} +LSSL_ALIAS(SSL_CTX_free); + +int +SSL_CTX_up_ref(SSL_CTX *ctx) +{ + int refs = CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + return ((refs > 1) ? 1 : 0); +} +LSSL_ALIAS(SSL_CTX_up_ref); + +pem_password_cb * +SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) +{ + return (ctx->default_passwd_callback); +} +LSSL_ALIAS(SSL_CTX_get_default_passwd_cb); + +void +SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) +{ + ctx->default_passwd_callback = cb; +} +LSSL_ALIAS(SSL_CTX_set_default_passwd_cb); + +void * +SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) +{ + return ctx->default_passwd_callback_userdata; +} +LSSL_ALIAS(SSL_CTX_get_default_passwd_cb_userdata); + +void +SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) +{ + ctx->default_passwd_callback_userdata = u; +} +LSSL_ALIAS(SSL_CTX_set_default_passwd_cb_userdata); + +void +SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb)(X509_STORE_CTX *, void *), void *arg) +{ + ctx->app_verify_callback = cb; + ctx->app_verify_arg = arg; +} +LSSL_ALIAS(SSL_CTX_set_cert_verify_callback); + +void +SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*cb)(int, X509_STORE_CTX *)) +{ + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} +LSSL_ALIAS(SSL_CTX_set_verify); + +void +SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} +LSSL_ALIAS(SSL_CTX_set_verify_depth); + +void +ssl_set_cert_masks(SSL_CERT *c, const SSL_CIPHER *cipher) +{ + unsigned long mask_a, mask_k; + SSL_CERT_PKEY *cpk; + + if (c == NULL) + return; + + mask_a = SSL_aNULL | SSL_aTLS1_3; + mask_k = SSL_kECDHE | SSL_kTLS1_3; + + if (c->dhe_params != NULL || c->dhe_params_cb != NULL || + c->dhe_params_auto != 0) + mask_k |= SSL_kDHE; + + cpk = &(c->pkeys[SSL_PKEY_ECC]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + /* Key usage, if present, must allow signing. */ + if (X509_get_key_usage(cpk->x509) & X509v3_KU_DIGITAL_SIGNATURE) + mask_a |= SSL_aECDSA; + } + + cpk = &(c->pkeys[SSL_PKEY_GOST01]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST01; + } + + cpk = &(c->pkeys[SSL_PKEY_RSA]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + mask_a |= SSL_aRSA; + mask_k |= SSL_kRSA; + } + + c->mask_k = mask_k; + c->mask_a = mask_a; + c->valid = 1; +} + +/* See if this handshake is using an ECC cipher suite. */ +int +ssl_using_ecc_cipher(SSL *s) +{ + unsigned long alg_a, alg_k; + + alg_a = s->s3->hs.cipher->algorithm_auth; + alg_k = s->s3->hs.cipher->algorithm_mkey; + + return s->session->tlsext_ecpointformatlist != NULL && + s->session->tlsext_ecpointformatlist_length > 0 && + ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)); +} + +int +ssl_check_srvr_ecc_cert_and_alg(SSL *s, X509 *x) +{ + const SSL_CIPHER *cs = s->s3->hs.cipher; + unsigned long alg_a; + + alg_a = cs->algorithm_auth; + + if (alg_a & SSL_aECDSA) { + /* Key usage, if present, must allow signing. */ + if (!(X509_get_key_usage(x) & X509v3_KU_DIGITAL_SIGNATURE)) { + SSLerror(s, SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return (0); + } + } + + return (1); +} + +SSL_CERT_PKEY * +ssl_get_server_send_pkey(const SSL *s) +{ + unsigned long alg_a; + SSL_CERT *c; + int i; + + c = s->cert; + ssl_set_cert_masks(c, s->s3->hs.cipher); + + alg_a = s->s3->hs.cipher->algorithm_auth; + + if (alg_a & SSL_aECDSA) { + i = SSL_PKEY_ECC; + } else if (alg_a & SSL_aRSA) { + i = SSL_PKEY_RSA; + } else if (alg_a & SSL_aGOST01) { + i = SSL_PKEY_GOST01; + } else { /* if (alg_a & SSL_aNULL) */ + SSLerror(s, ERR_R_INTERNAL_ERROR); + return (NULL); + } + + return (c->pkeys + i); +} + +EVP_PKEY * +ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd, + const struct ssl_sigalg **sap) +{ + const struct ssl_sigalg *sigalg = NULL; + EVP_PKEY *pkey = NULL; + unsigned long alg_a; + SSL_CERT *c; + int idx = -1; + + alg_a = cipher->algorithm_auth; + c = s->cert; + + if (alg_a & SSL_aRSA) { + idx = SSL_PKEY_RSA; + } else if ((alg_a & SSL_aECDSA) && + (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) + idx = SSL_PKEY_ECC; + if (idx == -1) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return (NULL); + } + + pkey = c->pkeys[idx].privatekey; + if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) { + SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR); + return (NULL); + } + *pmd = sigalg->md(); + *sap = sigalg; + + return (pkey); +} + +size_t +ssl_dhe_params_auto_key_bits(SSL *s) +{ + SSL_CERT_PKEY *cpk; + int key_bits; + + if (s->cert->dhe_params_auto == 2) { + key_bits = 1024; + } else if (s->s3->hs.cipher->algorithm_auth & SSL_aNULL) { + key_bits = 1024; + if (s->s3->hs.cipher->strength_bits == 256) + key_bits = 3072; + } else { + if ((cpk = ssl_get_server_send_pkey(s)) == NULL) + return 0; + if (cpk->privatekey == NULL || + EVP_PKEY_get0_RSA(cpk->privatekey) == NULL) + return 0; + if ((key_bits = EVP_PKEY_bits(cpk->privatekey)) <= 0) + return 0; + } + + return key_bits; +} + +static int +ssl_should_update_external_cache(SSL *s, int mode) +{ + int cache_mode; + + cache_mode = s->session_ctx->session_cache_mode; + + /* Don't cache if mode says not to */ + if ((cache_mode & mode) == 0) + return 0; + + /* if it is not already cached, cache it */ + if (!s->hit) + return 1; + + /* If it's TLS 1.3, do it to match OpenSSL */ + if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION) + return 1; + + return 0; +} + +static int +ssl_should_update_internal_cache(SSL *s, int mode) +{ + int cache_mode; + + cache_mode = s->session_ctx->session_cache_mode; + + /* Don't cache if mode says not to */ + if ((cache_mode & mode) == 0) + return 0; + + /* If it is already cached, don't cache it again */ + if (s->hit) + return 0; + + if ((cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) != 0) + return 0; + + /* If we are lesser than TLS 1.3, Cache it. */ + if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION) + return 1; + + /* Below this we consider TLS 1.3 or later */ + + /* If it's not a server, add it? OpenSSL does this. */ + if (!s->server) + return 1; + + /* XXX if we support early data / PSK need to add */ + + /* + * If we have the remove session callback, we will want + * to know about this even if it's a stateless ticket + * from 1.3 so we can know when it is removed. + */ + if (s->session_ctx->remove_session_cb != NULL) + return 1; + + /* If we have set OP_NO_TICKET, cache it. */ + if ((s->options & SSL_OP_NO_TICKET) != 0) + return 1; + + /* Otherwise do not cache */ + return 0; +} + +void +ssl_update_cache(SSL *s, int mode) +{ + int cache_mode, do_callback; + + if (s->session->session_id_length == 0) + return; + + cache_mode = s->session_ctx->session_cache_mode; + do_callback = ssl_should_update_external_cache(s, mode); + + if (ssl_should_update_internal_cache(s, mode)) { + /* + * XXX should we fail if the add to the internal cache + * fails? OpenSSL doesn't care.. + */ + (void) SSL_CTX_add_session(s->session_ctx, s->session); + } + + /* + * Update the "external cache" by calling the new session + * callback if present, even with TLS 1.3 without early data + * "because some application just want to know about the + * creation of a session and aren't doing a full cache". + * Apparently, if they are doing a full cache, they'll have + * some fun, but we endeavour to give application writers the + * same glorious experience they expect from OpenSSL which + * does it this way. + */ + if (do_callback && s->session_ctx->new_session_cb != NULL) { + CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (!s->session_ctx->new_session_cb(s, s->session)) + SSL_SESSION_free(s->session); + } + + /* Auto flush every 255 connections. */ + if (!(cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) && + (cache_mode & mode) != 0) { + int connections; + if (mode & SSL_SESS_CACHE_CLIENT) + connections = s->session_ctx->stats.sess_connect_good; + else + connections = s->session_ctx->stats.sess_accept_good; + if ((connections & 0xff) == 0xff) + SSL_CTX_flush_sessions(s->session_ctx, time(NULL)); + } +} + +const SSL_METHOD * +SSL_get_ssl_method(SSL *s) +{ + return (s->method); +} +LSSL_ALIAS(SSL_get_ssl_method); + +int +SSL_set_ssl_method(SSL *s, const SSL_METHOD *method) +{ + int (*handshake_func)(SSL *) = NULL; + int ret = 1; + + if (s->method == method) + return (ret); + + if (s->handshake_func == s->method->ssl_connect) + handshake_func = method->ssl_connect; + else if (s->handshake_func == s->method->ssl_accept) + handshake_func = method->ssl_accept; + + if (s->method->version == method->version) { + s->method = method; + } else { + s->method->ssl_free(s); + s->method = method; + ret = s->method->ssl_new(s); + } + s->handshake_func = handshake_func; + + return (ret); +} +LSSL_ALIAS(SSL_set_ssl_method); + +int +SSL_get_error(const SSL *s, int i) +{ + unsigned long l; + int reason; + BIO *bio; + + if (i > 0) + return (SSL_ERROR_NONE); + + /* + * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake + * etc, where we do encode the error. + */ + if ((l = ERR_peek_error()) != 0) { + if (ERR_GET_LIB(l) == ERR_LIB_SYS) + return (SSL_ERROR_SYSCALL); + else + return (SSL_ERROR_SSL); + } + + if (SSL_want_read(s)) { + bio = SSL_get_rbio(s); + if (BIO_should_read(bio)) { + return (SSL_ERROR_WANT_READ); + } else if (BIO_should_write(bio)) { + /* + * This one doesn't make too much sense... We never + * try to write to the rbio, and an application + * program where rbio and wbio are separate couldn't + * even know what it should wait for. However if we + * ever set s->rwstate incorrectly (so that we have + * SSL_want_read(s) instead of SSL_want_write(s)) + * and rbio and wbio *are* the same, this test works + * around that bug; so it might be safer to keep it. + */ + return (SSL_ERROR_WANT_WRITE); + } else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); /* unknown */ + } + } + + if (SSL_want_write(s)) { + bio = SSL_get_wbio(s); + if (BIO_should_write(bio)) { + return (SSL_ERROR_WANT_WRITE); + } else if (BIO_should_read(bio)) { + /* + * See above (SSL_want_read(s) with + * BIO_should_write(bio)) + */ + return (SSL_ERROR_WANT_READ); + } else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); + } + } + + if (SSL_want_x509_lookup(s)) + return (SSL_ERROR_WANT_X509_LOOKUP); + + if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && + (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) + return (SSL_ERROR_ZERO_RETURN); + + return (SSL_ERROR_SYSCALL); +} +LSSL_ALIAS(SSL_get_error); + +int +SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method) +{ + if (ctx->method->dtls) + return 0; + + ctx->quic_method = quic_method; + + return 1; +} +LSSL_ALIAS(SSL_CTX_set_quic_method); + +int +SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method) +{ + if (ssl->method->dtls) + return 0; + + ssl->quic_method = quic_method; + + return 1; +} +LSSL_ALIAS(SSL_set_quic_method); + +size_t +SSL_quic_max_handshake_flight_len(const SSL *ssl, + enum ssl_encryption_level_t level) +{ + size_t flight_len; + + /* Limit flights to 16K when there are no large certificate messages. */ + flight_len = 16384; + + switch (level) { + case ssl_encryption_initial: + return flight_len; + + case ssl_encryption_early_data: + /* QUIC does not send EndOfEarlyData. */ + return 0; + + case ssl_encryption_handshake: + if (ssl->server) { + /* + * Servers may receive Certificate message if configured + * to request client certificates. + */ + if ((SSL_get_verify_mode(ssl) & SSL_VERIFY_PEER) != 0 && + ssl->max_cert_list > flight_len) + flight_len = ssl->max_cert_list; + } else { + /* + * Clients may receive both Certificate message and a + * CertificateRequest message. + */ + if (ssl->max_cert_list * 2 > flight_len) + flight_len = ssl->max_cert_list * 2; + } + return flight_len; + case ssl_encryption_application: + /* + * Note there is not actually a bound on the number of + * NewSessionTickets one may send in a row. This level may need + * more involved flow control. + */ + return flight_len; + } + + return 0; +} +LSSL_ALIAS(SSL_quic_max_handshake_flight_len); + +enum ssl_encryption_level_t +SSL_quic_read_level(const SSL *ssl) +{ + return ssl->s3->hs.tls13.quic_read_level; +} +LSSL_ALIAS(SSL_quic_read_level); + +enum ssl_encryption_level_t +SSL_quic_write_level(const SSL *ssl) +{ + return ssl->s3->hs.tls13.quic_write_level; +} +LSSL_ALIAS(SSL_quic_write_level); + +int +SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *data, size_t len) +{ + if (!SSL_is_quic(ssl)) { + SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (level != SSL_quic_read_level(ssl)) { + SSLerror(ssl, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); + return 0; + } + + if (ssl->s3->hs.tls13.quic_read_buffer == NULL) { + ssl->s3->hs.tls13.quic_read_buffer = tls_buffer_new(0); + if (ssl->s3->hs.tls13.quic_read_buffer == NULL) { + SSLerror(ssl, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + /* XXX - note that this does not currently downsize. */ + tls_buffer_set_capacity_limit(ssl->s3->hs.tls13.quic_read_buffer, + SSL_quic_max_handshake_flight_len(ssl, level)); + + /* + * XXX - an append that fails due to exceeding capacity should set + * SSL_R_EXCESSIVE_MESSAGE_SIZE. + */ + return tls_buffer_append(ssl->s3->hs.tls13.quic_read_buffer, data, len); +} +LSSL_ALIAS(SSL_provide_quic_data); + +int +SSL_process_quic_post_handshake(SSL *ssl) +{ + /* XXX - this needs to run PHH received. */ + return 1; +} +LSSL_ALIAS(SSL_process_quic_post_handshake); + +int +SSL_do_handshake(SSL *s) +{ + if (s->handshake_func == NULL) { + SSLerror(s, SSL_R_CONNECTION_TYPE_NOT_SET); + return (-1); + } + + s->method->ssl_renegotiate_check(s); + + if (!SSL_in_init(s) && !SSL_in_before(s)) + return 1; + + return s->handshake_func(s); +} +LSSL_ALIAS(SSL_do_handshake); + +/* + * For the next 2 functions, SSL_clear() sets shutdown and so + * one of these calls will reset it + */ +void +SSL_set_accept_state(SSL *s) +{ + s->server = 1; + s->shutdown = 0; + s->s3->hs.state = SSL_ST_ACCEPT|SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_accept; + ssl_clear_cipher_state(s); +} +LSSL_ALIAS(SSL_set_accept_state); + +void +SSL_set_connect_state(SSL *s) +{ + s->server = 0; + s->shutdown = 0; + s->s3->hs.state = SSL_ST_CONNECT|SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_connect; + ssl_clear_cipher_state(s); +} +LSSL_ALIAS(SSL_set_connect_state); + +int +ssl_undefined_function(SSL *s) +{ + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int +ssl_undefined_void_function(void) +{ + SSLerrorx(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int +ssl_undefined_const_function(const SSL *s) +{ + SSLerror(s, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +const char * +ssl_version_string(int ver) +{ + switch (ver) { + case TLS1_VERSION: + return (SSL_TXT_TLSV1); + case TLS1_1_VERSION: + return (SSL_TXT_TLSV1_1); + case TLS1_2_VERSION: + return (SSL_TXT_TLSV1_2); + case TLS1_3_VERSION: + return (SSL_TXT_TLSV1_3); + case DTLS1_VERSION: + return (SSL_TXT_DTLS1); + case DTLS1_2_VERSION: + return (SSL_TXT_DTLS1_2); + default: + return ("unknown"); + } +} + +const char * +SSL_get_version(const SSL *s) +{ + return ssl_version_string(s->version); +} +LSSL_ALIAS(SSL_get_version); + +SSL * +SSL_dup(SSL *s) +{ + STACK_OF(X509_NAME) *sk; + X509_NAME *xn; + SSL *ret; + int i; + + if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) + goto err; + + ret->version = s->version; + ret->method = s->method; + + if (s->session != NULL) { + if (!SSL_copy_session_id(ret, s)) + goto err; + } else { + /* + * No session has been established yet, so we have to expect + * that s->cert or ret->cert will be changed later -- + * they should not both point to the same object, + * and thus we can't use SSL_copy_session_id. + */ + + ret->method->ssl_free(ret); + ret->method = s->method; + ret->method->ssl_new(ret); + + ssl_cert_free(ret->cert); + if ((ret->cert = ssl_cert_dup(s->cert)) == NULL) + goto err; + + if (!SSL_set_session_id_context(ret, s->sid_ctx, + s->sid_ctx_length)) + goto err; + } + + ret->options = s->options; + ret->mode = s->mode; + SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); + SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); + ret->msg_callback = s->msg_callback; + ret->msg_callback_arg = s->msg_callback_arg; + SSL_set_verify(ret, SSL_get_verify_mode(s), + SSL_get_verify_callback(s)); + SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); + ret->generate_session_id = s->generate_session_id; + + SSL_set_info_callback(ret, SSL_get_info_callback(s)); + + ret->debug = s->debug; + + /* copy app data, a little dangerous perhaps */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, + &ret->ex_data, &s->ex_data)) + goto err; + + /* setup rbio, and wbio */ + if (s->rbio != NULL) { + if (!BIO_dup_state(s->rbio,(char *)&ret->rbio)) + goto err; + } + if (s->wbio != NULL) { + if (s->wbio != s->rbio) { + if (!BIO_dup_state(s->wbio,(char *)&ret->wbio)) + goto err; + } else + ret->wbio = ret->rbio; + } + ret->rwstate = s->rwstate; + ret->in_handshake = s->in_handshake; + ret->handshake_func = s->handshake_func; + ret->server = s->server; + ret->renegotiate = s->renegotiate; + ret->new_session = s->new_session; + ret->quiet_shutdown = s->quiet_shutdown; + ret->shutdown = s->shutdown; + /* SSL_dup does not really work at any state, though */ + ret->s3->hs.state = s->s3->hs.state; + ret->rstate = s->rstate; + + /* + * Would have to copy ret->init_buf, ret->init_msg, ret->init_num, + * ret->init_off + */ + ret->init_num = 0; + + ret->hit = s->hit; + + X509_VERIFY_PARAM_inherit(ret->param, s->param); + + if (s->cipher_list != NULL) { + if ((ret->cipher_list = + sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) + goto err; + } + if (s->cipher_list_tls13 != NULL) { + if ((ret->cipher_list_tls13 = + sk_SSL_CIPHER_dup(s->cipher_list_tls13)) == NULL) + goto err; + } + + /* Dup the client_CA list */ + if (s->client_CA != NULL) { + if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL) goto err; + ret->client_CA = sk; + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + xn = sk_X509_NAME_value(sk, i); + if (sk_X509_NAME_set(sk, i, + X509_NAME_dup(xn)) == NULL) { + X509_NAME_free(xn); + goto err; + } + } + } + + return ret; + err: + SSL_free(ret); + return NULL; +} +LSSL_ALIAS(SSL_dup); + +void +ssl_clear_cipher_state(SSL *s) +{ + tls12_record_layer_clear_read_state(s->rl); + tls12_record_layer_clear_write_state(s->rl); +} + +void +ssl_info_callback(const SSL *s, int type, int value) +{ + ssl_info_callback_fn *cb; + + if ((cb = s->info_callback) == NULL) + cb = s->ctx->info_callback; + if (cb != NULL) + cb(s, type, value); +} + +void +ssl_msg_callback(SSL *s, int is_write, int content_type, + const void *msg_buf, size_t msg_len) +{ + if (s->msg_callback == NULL) + return; + + s->msg_callback(is_write, s->version, content_type, + msg_buf, msg_len, s, s->msg_callback_arg); +} + +void +ssl_msg_callback_cbs(SSL *s, int is_write, int content_type, CBS *cbs) +{ + ssl_msg_callback(s, is_write, content_type, CBS_data(cbs), CBS_len(cbs)); +} + +/* Fix this function so that it takes an optional type parameter */ +X509 * +SSL_get_certificate(const SSL *s) +{ + return (s->cert->key->x509); +} +LSSL_ALIAS(SSL_get_certificate); + +/* Fix this function so that it takes an optional type parameter */ +EVP_PKEY * +SSL_get_privatekey(const SSL *s) +{ + return (s->cert->key->privatekey); +} +LSSL_ALIAS(SSL_get_privatekey); + +const SSL_CIPHER * +SSL_get_current_cipher(const SSL *s) +{ + if ((s->session != NULL) && (s->session->cipher != NULL)) + return (s->session->cipher); + return (NULL); +} +LSSL_ALIAS(SSL_get_current_cipher); +const void * +SSL_get_current_compression(SSL *s) +{ + return (NULL); +} +LSSL_ALIAS(SSL_get_current_compression); + +const void * +SSL_get_current_expansion(SSL *s) +{ + return (NULL); +} +LSSL_ALIAS(SSL_get_current_expansion); + +size_t +SSL_get_client_random(const SSL *s, unsigned char *out, size_t max_out) +{ + size_t len = sizeof(s->s3->client_random); + + if (out == NULL) + return len; + + if (len > max_out) + len = max_out; + + memcpy(out, s->s3->client_random, len); + + return len; +} +LSSL_ALIAS(SSL_get_client_random); + +size_t +SSL_get_server_random(const SSL *s, unsigned char *out, size_t max_out) +{ + size_t len = sizeof(s->s3->server_random); + + if (out == NULL) + return len; + + if (len > max_out) + len = max_out; + + memcpy(out, s->s3->server_random, len); + + return len; +} +LSSL_ALIAS(SSL_get_server_random); + +int +ssl_init_wbio_buffer(SSL *s, int push) +{ + BIO *bbio; + + if (s->bbio == NULL) { + bbio = BIO_new(BIO_f_buffer()); + if (bbio == NULL) + return (0); + s->bbio = bbio; + } else { + bbio = s->bbio; + if (s->bbio == s->wbio) + s->wbio = BIO_pop(s->wbio); + } + (void)BIO_reset(bbio); +/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ + if (!BIO_set_read_buffer_size(bbio, 1)) { + SSLerror(s, ERR_R_BUF_LIB); + return (0); + } + if (push) { + if (s->wbio != bbio) + s->wbio = BIO_push(bbio, s->wbio); + } else { + if (s->wbio == bbio) + s->wbio = BIO_pop(bbio); + } + return (1); +} + +void +ssl_free_wbio_buffer(SSL *s) +{ + if (s == NULL) + return; + + if (s->bbio == NULL) + return; + + if (s->bbio == s->wbio) { + /* remove buffering */ + s->wbio = BIO_pop(s->wbio); + } + BIO_free(s->bbio); + s->bbio = NULL; +} + +void +SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) +{ + ctx->quiet_shutdown = mode; +} +LSSL_ALIAS(SSL_CTX_set_quiet_shutdown); + +int +SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) +{ + return (ctx->quiet_shutdown); +} +LSSL_ALIAS(SSL_CTX_get_quiet_shutdown); + +void +SSL_set_quiet_shutdown(SSL *s, int mode) +{ + s->quiet_shutdown = mode; +} +LSSL_ALIAS(SSL_set_quiet_shutdown); + +int +SSL_get_quiet_shutdown(const SSL *s) +{ + return (s->quiet_shutdown); +} +LSSL_ALIAS(SSL_get_quiet_shutdown); + +void +SSL_set_shutdown(SSL *s, int mode) +{ + s->shutdown = mode; +} +LSSL_ALIAS(SSL_set_shutdown); + +int +SSL_get_shutdown(const SSL *s) +{ + return (s->shutdown); +} +LSSL_ALIAS(SSL_get_shutdown); + +int +SSL_version(const SSL *s) +{ + return (s->version); +} +LSSL_ALIAS(SSL_version); + +SSL_CTX * +SSL_get_SSL_CTX(const SSL *ssl) +{ + return (ssl->ctx); +} +LSSL_ALIAS(SSL_get_SSL_CTX); + +SSL_CTX * +SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) +{ + SSL_CERT *new_cert; + + if (ctx == NULL) + ctx = ssl->initial_ctx; + if (ssl->ctx == ctx) + return (ssl->ctx); + + if ((new_cert = ssl_cert_dup(ctx->cert)) == NULL) + return NULL; + ssl_cert_free(ssl->cert); + ssl->cert = new_cert; + + SSL_CTX_up_ref(ctx); + SSL_CTX_free(ssl->ctx); /* decrement reference count */ + ssl->ctx = ctx; + + return (ssl->ctx); +} +LSSL_ALIAS(SSL_set_SSL_CTX); + +int +SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) +{ + return (X509_STORE_set_default_paths(ctx->cert_store)); +} +LSSL_ALIAS(SSL_CTX_set_default_verify_paths); + +int +SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); +} +LSSL_ALIAS(SSL_CTX_load_verify_locations); + +int +SSL_CTX_load_verify_mem(SSL_CTX *ctx, void *buf, int len) +{ + return (X509_STORE_load_mem(ctx->cert_store, buf, len)); +} +LSSL_ALIAS(SSL_CTX_load_verify_mem); + +void +SSL_set_info_callback(SSL *ssl, void (*cb)(const SSL *ssl, int type, int val)) +{ + ssl->info_callback = cb; +} +LSSL_ALIAS(SSL_set_info_callback); + +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, int val) +{ + return (ssl->info_callback); +} +LSSL_ALIAS(SSL_get_info_callback); + +int +SSL_state(const SSL *ssl) +{ + return (ssl->s3->hs.state); +} +LSSL_ALIAS(SSL_state); + +void +SSL_set_state(SSL *ssl, int state) +{ + ssl->s3->hs.state = state; +} +LSSL_ALIAS(SSL_set_state); + +void +SSL_set_verify_result(SSL *ssl, long arg) +{ + ssl->verify_result = arg; +} +LSSL_ALIAS(SSL_set_verify_result); + +long +SSL_get_verify_result(const SSL *ssl) +{ + return (ssl->verify_result); +} +LSSL_ALIAS(SSL_get_verify_result); + +int +SSL_verify_client_post_handshake(SSL *ssl) +{ + return 0; +} +LSSL_ALIAS(SSL_verify_client_post_handshake); + +void +SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val) +{ + return; +} +LSSL_ALIAS(SSL_CTX_set_post_handshake_auth); + +void +SSL_set_post_handshake_auth(SSL *ssl, int val) +{ + return; +} +LSSL_ALIAS(SSL_set_post_handshake_auth); + +int +SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return (CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, + new_func, dup_func, free_func)); +} +LSSL_ALIAS(SSL_get_ex_new_index); + +int +SSL_set_ex_data(SSL *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} +LSSL_ALIAS(SSL_set_ex_data); + +void * +SSL_get_ex_data(const SSL *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} +LSSL_ALIAS(SSL_get_ex_data); + +int +SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return (CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, + new_func, dup_func, free_func)); +} +LSSL_ALIAS(SSL_CTX_get_ex_new_index); + +int +SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} +LSSL_ALIAS(SSL_CTX_set_ex_data); + +void * +SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} +LSSL_ALIAS(SSL_CTX_get_ex_data); + +int +ssl_ok(SSL *s) +{ + return (1); +} + +X509_STORE * +SSL_CTX_get_cert_store(const SSL_CTX *ctx) +{ + return (ctx->cert_store); +} +LSSL_ALIAS(SSL_CTX_get_cert_store); + +void +SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) +{ + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} +LSSL_ALIAS(SSL_CTX_set_cert_store); + +X509 * +SSL_CTX_get0_certificate(const SSL_CTX *ctx) +{ + if (ctx->cert == NULL) + return NULL; + + return ctx->cert->key->x509; +} +LSSL_ALIAS(SSL_CTX_get0_certificate); + +EVP_PKEY * +SSL_CTX_get0_privatekey(const SSL_CTX *ctx) +{ + if (ctx->cert == NULL) + return NULL; + + return ctx->cert->key->privatekey; +} +LSSL_ALIAS(SSL_CTX_get0_privatekey); + +int +SSL_want(const SSL *s) +{ + return (s->rwstate); +} +LSSL_ALIAS(SSL_want); + +void +SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb); +} +LSSL_ALIAS(SSL_CTX_set_tmp_rsa_callback); + +void +SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb); +} +LSSL_ALIAS(SSL_set_tmp_rsa_callback); + +void +SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, DH *(*dh)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); +} +LSSL_ALIAS(SSL_CTX_set_tmp_dh_callback); + +void +SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); +} +LSSL_ALIAS(SSL_set_tmp_dh_callback); + +void +SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, EC_KEY *(*ecdh)(SSL *ssl, + int is_export, int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, + (void (*)(void))ecdh); +} +LSSL_ALIAS(SSL_CTX_set_tmp_ecdh_callback); + +void +SSL_set_tmp_ecdh_callback(SSL *ssl, EC_KEY *(*ecdh)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh); +} +LSSL_ALIAS(SSL_set_tmp_ecdh_callback); + + +void +SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, void *arg)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, + (void (*)(void))cb); +} +LSSL_ALIAS(SSL_CTX_set_msg_callback); + +void +SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, void *arg)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); +} +LSSL_ALIAS(SSL_set_msg_callback); + +void +SSL_set_debug(SSL *s, int debug) +{ + s->debug = debug; +} +LSSL_ALIAS(SSL_set_debug); + +int +SSL_cache_hit(SSL *s) +{ + return (s->hit); +} +LSSL_ALIAS(SSL_cache_hit); + +int +SSL_CTX_get_min_proto_version(SSL_CTX *ctx) +{ + return ctx->min_proto_version; +} +LSSL_ALIAS(SSL_CTX_get_min_proto_version); + +int +SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) +{ + return ssl_version_set_min(ctx->method, version, + ctx->max_tls_version, &ctx->min_tls_version, + &ctx->min_proto_version); +} +LSSL_ALIAS(SSL_CTX_set_min_proto_version); + +int +SSL_CTX_get_max_proto_version(SSL_CTX *ctx) +{ + return ctx->max_proto_version; +} +LSSL_ALIAS(SSL_CTX_get_max_proto_version); + +int +SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) +{ + return ssl_version_set_max(ctx->method, version, + ctx->min_tls_version, &ctx->max_tls_version, + &ctx->max_proto_version); +} +LSSL_ALIAS(SSL_CTX_set_max_proto_version); + +int +SSL_get_min_proto_version(SSL *ssl) +{ + return ssl->min_proto_version; +} +LSSL_ALIAS(SSL_get_min_proto_version); + +int +SSL_set_min_proto_version(SSL *ssl, uint16_t version) +{ + return ssl_version_set_min(ssl->method, version, + ssl->max_tls_version, &ssl->min_tls_version, + &ssl->min_proto_version); +} +LSSL_ALIAS(SSL_set_min_proto_version); +int +SSL_get_max_proto_version(SSL *ssl) +{ + return ssl->max_proto_version; +} +LSSL_ALIAS(SSL_get_max_proto_version); + +int +SSL_set_max_proto_version(SSL *ssl, uint16_t version) +{ + return ssl_version_set_max(ssl->method, version, + ssl->min_tls_version, &ssl->max_tls_version, + &ssl->max_proto_version); +} +LSSL_ALIAS(SSL_set_max_proto_version); + +const SSL_METHOD * +SSL_CTX_get_ssl_method(const SSL_CTX *ctx) +{ + return ctx->method; +} +LSSL_ALIAS(SSL_CTX_get_ssl_method); + +int +SSL_CTX_get_security_level(const SSL_CTX *ctx) +{ + return ctx->cert->security_level; +} +LSSL_ALIAS(SSL_CTX_get_security_level); + +void +SSL_CTX_set_security_level(SSL_CTX *ctx, int level) +{ + ctx->cert->security_level = level; +} +LSSL_ALIAS(SSL_CTX_set_security_level); + +int +SSL_get_security_level(const SSL *ssl) +{ + return ssl->cert->security_level; +} +LSSL_ALIAS(SSL_get_security_level); + +void +SSL_set_security_level(SSL *ssl, int level) +{ + ssl->cert->security_level = level; +} +LSSL_ALIAS(SSL_set_security_level); + +int +SSL_is_quic(const SSL *ssl) +{ + return ssl->quic_method != NULL; +} +LSSL_ALIAS(SSL_is_quic); + +int +SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, + size_t params_len) +{ + freezero(ssl->quic_transport_params, + ssl->quic_transport_params_len); + ssl->quic_transport_params = NULL; + ssl->quic_transport_params_len = 0; + + if ((ssl->quic_transport_params = malloc(params_len)) == NULL) + return 0; + + memcpy(ssl->quic_transport_params, params, params_len); + ssl->quic_transport_params_len = params_len; + + return 1; +} +LSSL_ALIAS(SSL_set_quic_transport_params); + +void +SSL_get_peer_quic_transport_params(const SSL *ssl, const uint8_t **out_params, + size_t *out_params_len) +{ + *out_params = ssl->s3->peer_quic_transport_params; + *out_params_len = ssl->s3->peer_quic_transport_params_len; +} +LSSL_ALIAS(SSL_get_peer_quic_transport_params); + +void +SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy) +{ + /* Not supported. */ +} +LSSL_ALIAS(SSL_set_quic_use_legacy_codepoint); + +static int +ssl_cipher_id_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) +{ + SSL_CIPHER const *a = a_; + SSL_CIPHER const *b = b_; + return ssl_cipher_id_cmp(a, b); +} + +SSL_CIPHER * +OBJ_bsearch_ssl_cipher_id(SSL_CIPHER *key, SSL_CIPHER const *base, int num) +{ + return (SSL_CIPHER *)OBJ_bsearch_(key, base, num, sizeof(SSL_CIPHER), + ssl_cipher_id_cmp_BSEARCH_CMP_FN); +} diff --git a/Libraries/libressl/ssl/ssl_local.h b/Libraries/libressl/ssl/ssl_local.h new file mode 100644 index 000000000..9666f3882 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_local.h @@ -0,0 +1,1531 @@ +/* $OpenBSD: ssl_local.h,v 1.7 2023/07/06 07:56:32 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_LOCL_H +#define HEADER_SSL_LOCL_H + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "bytestring.h" +#include "tls_content.h" +#include "tls13_internal.h" + +__BEGIN_HIDDEN_DECLS + +#define CTASSERT(x) extern char _ctassert[(x) ? 1 : -1 ] \ + __attribute__((__unused__)) + +#ifndef LIBRESSL_HAS_DTLS1_2 +#define LIBRESSL_HAS_DTLS1_2 +#endif + +/* LOCAL STUFF */ + +#define SSL_DECRYPT 0 +#define SSL_ENCRYPT 1 + +/* + * Define the Bitmasks for SSL_CIPHER.algorithms. + * This bits are used packed as dense as possible. If new methods/ciphers + * etc will be added, the bits a likely to change, so this information + * is for internal library use only, even though SSL_CIPHER.algorithms + * can be publicly accessed. + * Use the according functions for cipher management instead. + * + * The bit mask handling in the selection and sorting scheme in + * ssl_create_cipher_list() has only limited capabilities, reflecting + * that the different entities within are mutually exclusive: + * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. + */ + +/* Bits for algorithm_mkey (key exchange algorithm) */ +#define SSL_kRSA 0x00000001L /* RSA key exchange */ +#define SSL_kDHE 0x00000008L /* tmp DH key no DH cert */ +#define SSL_kECDHE 0x00000080L /* ephemeral ECDH */ +#define SSL_kGOST 0x00000200L /* GOST key exchange */ +#define SSL_kTLS1_3 0x00000400L /* TLSv1.3 key exchange */ + +/* Bits for algorithm_auth (server authentication) */ +#define SSL_aRSA 0x00000001L /* RSA auth */ +#define SSL_aDSS 0x00000002L /* DSS auth */ +#define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */ +#define SSL_aECDSA 0x00000040L /* ECDSA auth*/ +#define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */ +#define SSL_aTLS1_3 0x00000400L /* TLSv1.3 authentication */ + +/* Bits for algorithm_enc (symmetric encryption) */ +#define SSL_DES 0x00000001L +#define SSL_3DES 0x00000002L +#define SSL_RC4 0x00000004L +#define SSL_IDEA 0x00000008L +#define SSL_eNULL 0x00000010L +#define SSL_AES128 0x00000020L +#define SSL_AES256 0x00000040L +#define SSL_CAMELLIA128 0x00000080L +#define SSL_CAMELLIA256 0x00000100L +#define SSL_eGOST2814789CNT 0x00000200L +#define SSL_AES128GCM 0x00000400L +#define SSL_AES256GCM 0x00000800L +#define SSL_CHACHA20POLY1305 0x00001000L + +#define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) +#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) + + +/* Bits for algorithm_mac (symmetric authentication) */ + +#define SSL_MD5 0x00000001L +#define SSL_SHA1 0x00000002L +#define SSL_GOST94 0x00000004L +#define SSL_GOST89MAC 0x00000008L +#define SSL_SHA256 0x00000010L +#define SSL_SHA384 0x00000020L +/* Not a real MAC, just an indication it is part of cipher */ +#define SSL_AEAD 0x00000040L +#define SSL_STREEBOG256 0x00000080L + +/* Bits for algorithm_ssl (protocol version) */ +#define SSL_SSLV3 0x00000002L +#define SSL_TLSV1 SSL_SSLV3 /* for now */ +#define SSL_TLSV1_2 0x00000004L +#define SSL_TLSV1_3 0x00000008L + + +/* Bits for algorithm2 (handshake digests and other extra flags) */ + +#define SSL_HANDSHAKE_MAC_MASK 0xff0 +#define SSL_HANDSHAKE_MAC_MD5 0x010 +#define SSL_HANDSHAKE_MAC_SHA 0x020 +#define SSL_HANDSHAKE_MAC_GOST94 0x040 +#define SSL_HANDSHAKE_MAC_SHA256 0x080 +#define SSL_HANDSHAKE_MAC_SHA384 0x100 +#define SSL_HANDSHAKE_MAC_STREEBOG256 0x200 +#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) + +#define SSL3_CK_ID 0x03000000 +#define SSL3_CK_VALUE_MASK 0x0000ffff + +#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) + +#define TLS1_PRF_DGST_SHIFT 10 +#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_STREEBOG256 (SSL_HANDSHAKE_MAC_STREEBOG256 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) + +/* + * Stream MAC for GOST ciphersuites from cryptopro draft + * (currently this also goes into algorithm2). + */ +#define TLS1_STREAM_MAC 0x04 + +/* + * SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD is an algorithm2 flag that + * indicates that the variable part of the nonce is included as a prefix of + * the record (AES-GCM, for example, does this with an 8-byte variable nonce.) + */ +#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD (1 << 22) + +/* + * SSL_CIPHER_AEAD_FIXED_NONCE_LEN returns the number of bytes of fixed nonce + * for an SSL_CIPHER with an algorithm_mac of SSL_AEAD. + */ +#define SSL_CIPHER_AEAD_FIXED_NONCE_LEN(ssl_cipher) \ + (((ssl_cipher->algorithm2 >> 24) & 0xf) * 2) + +/* + * Cipher strength information. + */ +#define SSL_STRONG_MASK 0x000001fcL +#define SSL_STRONG_NONE 0x00000004L +#define SSL_LOW 0x00000020L +#define SSL_MEDIUM 0x00000040L +#define SSL_HIGH 0x00000080L + +/* + * The keylength (measured in RSA key bits, I guess) for temporary keys. + * Cipher argument is so that this can be variable in the future. + */ +#define SSL_C_PKEYLENGTH(c) 1024 + +/* See if we use signature algorithms extension. */ +#define SSL_USE_SIGALGS(s) \ + (s->method->enc_flags & SSL_ENC_FLAG_SIGALGS) + +/* See if we use SHA256 default PRF. */ +#define SSL_USE_SHA256_PRF(s) \ + (s->method->enc_flags & SSL_ENC_FLAG_SHA256_PRF) + +/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2. */ +#define SSL_USE_TLS1_2_CIPHERS(s) \ + (s->method->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) + +/* Allow TLS 1.3 ciphersuites only. */ +#define SSL_USE_TLS1_3_CIPHERS(s) \ + (s->method->enc_flags & SSL_ENC_FLAG_TLS1_3_CIPHERS) + +#define SSL_PKEY_RSA 0 +#define SSL_PKEY_ECC 1 +#define SSL_PKEY_GOST01 2 +#define SSL_PKEY_NUM 3 + +#define SSL_MAX_EMPTY_RECORDS 32 + +/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | + * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) + * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) + * SSL_kDHE <- RSA_ENC | RSA_SIGN | DSA_SIGN + * SSL_aRSA <- RSA_ENC | RSA_SIGN + * SSL_aDSS <- DSA_SIGN + */ + +/* From ECC-TLS draft, used in encoding the curve type in + * ECParameters + */ +#define EXPLICIT_PRIME_CURVE_TYPE 1 +#define EXPLICIT_CHAR2_CURVE_TYPE 2 +#define NAMED_CURVE_TYPE 3 + +typedef struct ssl_cert_pkey_st { + X509 *x509; + EVP_PKEY *privatekey; + STACK_OF(X509) *chain; +} SSL_CERT_PKEY; + +typedef struct ssl_cert_st { + /* Current active set */ + /* ALWAYS points to an element of the pkeys array + * Probably it would make more sense to store + * an index, not a pointer. */ + SSL_CERT_PKEY *key; + + SSL_CERT_PKEY pkeys[SSL_PKEY_NUM]; + + /* The following masks are for the key and auth + * algorithms that are supported by the certs below */ + int valid; + unsigned long mask_k; + unsigned long mask_a; + + DH *dhe_params; + DH *(*dhe_params_cb)(SSL *ssl, int is_export, int keysize); + int dhe_params_auto; + + int (*security_cb)(const SSL *s, const SSL_CTX *ctx, int op, int bits, + int nid, void *other, void *ex_data); /* Not exposed in API. */ + int security_level; + void *security_ex_data; /* Not exposed in API. */ + + int references; /* >1 only if SSL_copy_session_id is used */ +} SSL_CERT; + +struct ssl_comp_st { + int id; + const char *name; +}; + +struct ssl_cipher_st { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ +}; + +struct ssl_method_st { + int dtls; + int server; + int version; + + uint16_t min_tls_version; + uint16_t max_tls_version; + + int (*ssl_new)(SSL *s); + void (*ssl_clear)(SSL *s); + void (*ssl_free)(SSL *s); + + int (*ssl_accept)(SSL *s); + int (*ssl_connect)(SSL *s); + int (*ssl_shutdown)(SSL *s); + + int (*ssl_renegotiate)(SSL *s); + int (*ssl_renegotiate_check)(SSL *s); + + int (*ssl_pending)(const SSL *s); + int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len); + + const SSL_CIPHER *(*get_cipher)(unsigned int ncipher); + + unsigned int enc_flags; /* SSL_ENC_FLAG_* */ +}; + +/* + * Let's make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 2 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity + * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket + * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) + * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method + * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +struct ssl_session_st { + int ssl_version; /* what ssl version session info is + * being kept in here? */ + + size_t master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + + /* session_id - valid? */ + size_t session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + + /* this is used to determine whether the session is being reused in + * the appropriate context. It is up to the application to set this, + * via SSL_new */ + size_t sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + /* Peer provided leaf (end-entity) certificate. */ + X509 *peer_cert; + int peer_cert_type; + + /* when app_verify_callback accepts a session where the peer's certificate + * is not ok, we must remember the error for session reuse: */ + long verify_result; /* only for servers */ + + long timeout; + time_t time; + int references; + + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this + * needs to be used to load + * the 'cipher' structure */ + + STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ + + char *tlsext_hostname; + + /* Session resumption - RFC 5077 and RFC 8446. */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + uint32_t tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ + uint32_t tlsext_tick_age_add; /* TLSv1.3 ticket age obfuscation (in ms) */ + struct tls13_secret resumption_master_secret; + + CRYPTO_EX_DATA ex_data; /* application specific data */ + + /* These are used to make removal of session-ids more + * efficient and to implement a maximum cache size. */ + struct ssl_session_st *prev, *next; + + /* Used to indicate that session resumption is not allowed. + * Applications can also set this bit for a new session via + * not_resumable_session_cb to disable session caching and tickets. */ + int not_resumable; + + size_t tlsext_ecpointformatlist_length; + uint8_t *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_supportedgroups_length; + uint16_t *tlsext_supportedgroups; /* peer's list */ +}; + +struct ssl_sigalg; + +typedef struct ssl_handshake_tls12_st { + /* Used when SSL_ST_FLUSH_DATA is entered. */ + int next_state; + + /* Handshake message type and size. */ + int message_type; + unsigned long message_size; + + /* Reuse current handshake message. */ + int reuse_message; + + /* Client certificate requests. */ + int cert_request; + STACK_OF(X509_NAME) *ca_names; + + /* Record-layer key block for TLS 1.2 and earlier. */ + struct tls12_key_block *key_block; + + /* Transcript hash prior to sending certificate verify message. */ + uint8_t cert_verify[EVP_MAX_MD_SIZE]; +} SSL_HANDSHAKE_TLS12; + +typedef struct ssl_handshake_tls13_st { + int use_legacy; + int hrr; + + /* Client indicates psk_dhe_ke support in PskKeyExchangeMode. */ + int use_psk_dhe_ke; + + /* Certificate selected for use (static pointer). */ + const SSL_CERT_PKEY *cpk; + + /* Version proposed by peer server. */ + uint16_t server_version; + + uint16_t server_group; + struct tls13_secrets *secrets; + + uint8_t *cookie; + size_t cookie_len; + + /* Preserved transcript hash. */ + uint8_t transcript_hash[EVP_MAX_MD_SIZE]; + size_t transcript_hash_len; + + /* Legacy session ID. */ + uint8_t legacy_session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + size_t legacy_session_id_len; + + /* ClientHello hash, used to validate following HelloRetryRequest */ + EVP_MD_CTX *clienthello_md_ctx; + unsigned char *clienthello_hash; + unsigned int clienthello_hash_len; + + /* QUIC read buffer and read/write encryption levels. */ + struct tls_buffer *quic_read_buffer; + enum ssl_encryption_level_t quic_read_level; + enum ssl_encryption_level_t quic_write_level; +} SSL_HANDSHAKE_TLS13; + +typedef struct ssl_handshake_st { + /* + * Minimum and maximum versions supported for this handshake. These are + * initialised at the start of a handshake based on the method in use + * and the current protocol version configuration. + */ + uint16_t our_min_tls_version; + uint16_t our_max_tls_version; + + /* + * Version negotiated for this session. For a client this is set once + * the server selected version is parsed from the ServerHello (either + * from the legacy version or supported versions extension). For a + * server this is set once we select the version we will use with the + * client. + */ + uint16_t negotiated_tls_version; + + /* + * Legacy version advertised by our peer. For a server this is the + * version specified by the client in the ClientHello message. For a + * client, this is the version provided in the ServerHello message. + */ + uint16_t peer_legacy_version; + + /* + * Current handshake state - contains one of the SSL3_ST_* values and + * is used by the TLSv1.2 state machine, as well as being updated by + * the TLSv1.3 stack due to it being exposed externally. + */ + int state; + + /* Cipher being negotiated in this handshake. */ + const SSL_CIPHER *cipher; + + /* Extensions seen in this handshake. */ + uint32_t extensions_seen; + + /* Signature algorithms selected for use (static pointers). */ + const struct ssl_sigalg *our_sigalg; + const struct ssl_sigalg *peer_sigalg; + + /* sigalgs offered in this handshake in wire form */ + uint8_t *sigalgs; + size_t sigalgs_len; + + /* Key share for ephemeral key exchange. */ + struct tls_key_share *key_share; + + /* + * Copies of the verify data sent in our finished message and the + * verify data received in the finished message sent by our peer. + */ + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + uint8_t peer_finished[EVP_MAX_MD_SIZE]; + size_t peer_finished_len; + + /* List of certificates received from our peer. */ + STACK_OF(X509) *peer_certs; + STACK_OF(X509) *peer_certs_no_leaf; + + /* Certificate chain resulting from X.509 verification. */ + STACK_OF(X509) *verified_chain; + + SSL_HANDSHAKE_TLS12 tls12; + SSL_HANDSHAKE_TLS13 tls13; +} SSL_HANDSHAKE; + +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; + +/* TLS Session Ticket extension struct. */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +struct tls12_key_block; + +struct tls12_key_block *tls12_key_block_new(void); +void tls12_key_block_free(struct tls12_key_block *kb); +void tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key, + CBS *key, CBS *iv); +void tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key, + CBS *key, CBS *iv); +int tls12_key_block_generate(struct tls12_key_block *kb, SSL *s, + const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash); + +struct tls12_record_layer; + +struct tls12_record_layer *tls12_record_layer_new(void); +void tls12_record_layer_free(struct tls12_record_layer *rl); +void tls12_record_layer_alert(struct tls12_record_layer *rl, + uint8_t *alert_desc); +int tls12_record_layer_write_overhead(struct tls12_record_layer *rl, + size_t *overhead); +int tls12_record_layer_read_protected(struct tls12_record_layer *rl); +int tls12_record_layer_write_protected(struct tls12_record_layer *rl); +void tls12_record_layer_set_aead(struct tls12_record_layer *rl, + const EVP_AEAD *aead); +void tls12_record_layer_set_cipher_hash(struct tls12_record_layer *rl, + const EVP_CIPHER *cipher, const EVP_MD *handshake_hash, + const EVP_MD *mac_hash); +void tls12_record_layer_set_version(struct tls12_record_layer *rl, + uint16_t version); +void tls12_record_layer_set_initial_epoch(struct tls12_record_layer *rl, + uint16_t epoch); +uint16_t tls12_record_layer_read_epoch(struct tls12_record_layer *rl); +uint16_t tls12_record_layer_write_epoch(struct tls12_record_layer *rl); +int tls12_record_layer_use_write_epoch(struct tls12_record_layer *rl, + uint16_t epoch); +void tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, + uint16_t epoch); +void tls12_record_layer_clear_read_state(struct tls12_record_layer *rl); +void tls12_record_layer_clear_write_state(struct tls12_record_layer *rl); +void tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl); +int tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl, + CBS *mac_key, CBS *key, CBS *iv); +int tls12_record_layer_change_write_cipher_state(struct tls12_record_layer *rl, + CBS *mac_key, CBS *key, CBS *iv); +int tls12_record_layer_open_record(struct tls12_record_layer *rl, + uint8_t *buf, size_t buf_len, struct tls_content *out); +int tls12_record_layer_seal_record(struct tls12_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len, + CBB *out); + +typedef void (ssl_info_callback_fn)(const SSL *s, int type, int val); +typedef void (ssl_msg_callback_fn)(int is_write, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + +struct ssl_ctx_st { + const SSL_METHOD *method; + const SSL_QUIC_METHOD *quic_method; + + STACK_OF(SSL_CIPHER) *cipher_list; + + struct x509_store_st /* X509_STORE */ *cert_store; + + /* If timeout is not 0, it is the default timeout value set + * when SSL_new() is called. This has been put in to make + * life easier to set things up */ + long session_timeout; + + int references; + + /* Default values to use in SSL structures follow (these are copied by SSL_new) */ + + STACK_OF(X509) *extra_certs; + + int verify_mode; + size_t sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + X509_VERIFY_PARAM *param; + + /* + * XXX + * default_passwd_cb used by python and openvpn, need to keep it until we + * add an accessor + */ + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + uint16_t min_tls_version; + uint16_t max_tls_version; + + /* + * These may be zero to imply minimum or maximum version supported by + * the method. + */ + uint16_t min_proto_version; + uint16_t max_proto_version; + + unsigned long options; + unsigned long mode; + + /* If this callback is not null, it will be called each + * time a session id is added to the cache. If this function + * returns 1, it means that the callback will do a + * SSL_SESSION_free() when it has finished using it. Otherwise, + * on 0, it means the callback has finished with it. + * If remove_session_cb is not null, it will be called when + * a session-id is removed from the cache. After the call, + * OpenSSL will SSL_SESSION_free() it. */ + int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess); + void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, + const unsigned char *data, int len, int *copy); + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback)(X509_STORE_CTX *, void *); + void *app_verify_arg; + + /* get client cert callback */ + int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb)(SSL *ssl, const unsigned char *cookie, + unsigned int cookie_len); + + ssl_info_callback_fn *info_callback; + + /* callback that allows applications to peek at protocol messages */ + ssl_msg_callback_fn *msg_callback; + void *msg_callback_arg; + + int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */ + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + /* TLS extensions servername callback */ + int (*tlsext_servername_callback)(SSL*, int *, void *); + void *tlsext_servername_arg; + + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb)(SSL *ssl, unsigned char *name, + unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb)(SSL *ssl, void *arg); + void *tlsext_status_arg; + + struct lhash_st_SSL_SESSION *sessions; + + /* Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + + /* This can have one of 2 values, ored together, + * SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, + * Default is SSL_SESSION_CACHE_SERVER, which means only + * SSL_accept which cache SSL_SESSIONS. */ + int session_cache_mode; + + struct { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate;/* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate;/* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not + * in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + CRYPTO_EX_DATA ex_data; + + STACK_OF(SSL_CIPHER) *cipher_list_tls13; + + SSL_CERT *cert; + + /* Default values used when no per-SSL value is defined follow */ + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + long max_cert_list; + + int read_ahead; + + int quiet_shutdown; + + /* Maximum amount of data to send in one fragment. + * actual record size can be more than this due to + * padding and MAC overheads. + */ + unsigned int max_send_fragment; + +#ifndef OPENSSL_NO_ENGINE + /* Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +#endif + + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + + /* SRTP profiles we are willing to do from RFC 5764 */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + /* + * ALPN information. + */ + + /* + * Server callback function that allows the server to select the + * protocol for the connection. + * out: on successful return, this must point to the raw protocol + * name (without the length prefix). + * outlen: on successful return, this contains the length of out. + * in: points to the client's list of supported protocols in + * wire-format. + * inlen: the length of in. + */ + int (*alpn_select_cb)(SSL *s, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, unsigned int inlen, + void *arg); + void *alpn_select_cb_arg; + + /* Client list of supported protocols in wire format. */ + uint8_t *alpn_client_proto_list; + size_t alpn_client_proto_list_len; + + size_t tlsext_ecpointformatlist_length; + uint8_t *tlsext_ecpointformatlist; /* our list */ + size_t tlsext_supportedgroups_length; + uint16_t *tlsext_supportedgroups; /* our list */ + SSL_CTX_keylog_cb_func keylog_callback; /* Unused. For OpenSSL compatibility. */ + size_t num_tickets; /* Unused, for OpenSSL compatibility */ +}; + +struct ssl_st { + /* protocol version + * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION) + */ + int version; + + const SSL_METHOD *method; + const SSL_QUIC_METHOD *quic_method; + + /* There are 2 BIO's even though they are normally both the + * same. This is so data can be read and written to different + * handlers */ + + BIO *rbio; /* used by SSL_read */ + BIO *wbio; /* used by SSL_write */ + BIO *bbio; /* used during session-id reuse to concatenate + * messages */ + int server; /* are we the server side? - mostly used by SSL_clear*/ + + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + + X509_VERIFY_PARAM *param; + + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + + /* This is used to hold the server certificate used */ + SSL_CERT *cert; + + /* the session_id_context is used to ensure sessions are only reused + * in the appropriate context */ + size_t sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + + /* Used in SSL2 and SSL3 */ + int verify_mode; /* 0 don't care about verify failure. + * 1 fail if verify fails */ + int error; /* error bytes to be written */ + int error_code; /* actual code */ + + SSL_CTX *ctx; + + long verify_result; + + int references; + + int client_version; /* what was passed, used for + * SSLv3/TLS rollback check */ + + unsigned int max_send_fragment; + + const struct tls_extension **tlsext_build_order; + size_t tlsext_build_order_len; + + char *tlsext_hostname; + + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + + SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ +#define session_ctx initial_ctx + + struct tls13_ctx *tls13; + + uint16_t min_tls_version; + uint16_t max_tls_version; + + /* + * These may be zero to imply minimum or maximum version supported by + * the method. + */ + uint16_t min_proto_version; + uint16_t max_proto_version; + + unsigned long options; /* protocol behaviour */ + unsigned long mode; /* API behaviour */ + + /* Client list of supported protocols in wire format. */ + uint8_t *alpn_client_proto_list; + size_t alpn_client_proto_list_len; + + /* QUIC transport params we will send */ + uint8_t *quic_transport_params; + size_t quic_transport_params_len; + + /* XXX Callbacks */ + + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func)(SSL *); + + ssl_info_callback_fn *info_callback; + + /* callback that allows applications to peek at protocol messages */ + ssl_msg_callback_fn *msg_callback; + void *msg_callback_arg; + + int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */ + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + /* TLS extension debug callback */ + void (*tlsext_debug_cb)(SSL *s, int client_server, int type, + unsigned char *data, int len, void *arg); + void *tlsext_debug_arg; + + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + + /* XXX non-callback */ + + /* This holds a variable that indicates what we were doing + * when a 0 or -1 is returned. This is needed for + * non-blocking IO so we know what request needs re-doing when + * in SSL_accept or SSL_connect */ + int rwstate; + + /* Imagine that here's a boolean member "init" that is + * switched as soon as SSL_set_{accept/connect}_state + * is called for the first time, so that "state" and + * "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this + * test instead of an "init" member. + */ + + int new_session;/* Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ + int quiet_shutdown;/* don't send shutdown packets */ + int shutdown; /* we have shut things down, 0x01 sent, 0x02 + * for received */ + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + + int read_ahead; /* Read as many input bytes as possible + * (for non-blocking reads) */ + + int hit; /* reusing a previous session */ + + STACK_OF(SSL_CIPHER) *cipher_list_tls13; + + struct tls12_record_layer *rl; + + /* session info */ + + /* extra application data */ + CRYPTO_EX_DATA ex_data; + + /* client cert? */ + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + + /* set this flag to 1 and a sleep(1) is put into all SSL_read() + * and SSL_write() calls, good for nbio debugging :-) */ + int debug; + long max_cert_list; + int first_packet; + + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + size_t tlsext_ocsp_resp_len; + + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; + + size_t tlsext_ecpointformatlist_length; + uint8_t *tlsext_ecpointformatlist; /* our list */ + size_t tlsext_supportedgroups_length; + uint16_t *tlsext_supportedgroups; /* our list */ + + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; /* What we'll do */ + const SRTP_PROTECTION_PROFILE *srtp_profile; /* What's been chosen */ + + int renegotiate;/* 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) */ + + int rstate; /* where we are when reading */ + + int mac_packet; + + int empty_record_count; + + size_t num_tickets; /* Unused, for OpenSSL compatibility */ +}; + +typedef struct ssl3_record_internal_st { + int type; /* type of record */ + unsigned int length; /* How many bytes available */ + unsigned int padding_length; /* Number of padding bytes. */ + unsigned int off; /* read/write offset into 'buf' */ + unsigned char *data; /* pointer to the record data */ + unsigned char *input; /* where the decode bytes are */ + uint16_t epoch; /* epoch number, needed by DTLS1 */ + unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */ +} SSL3_RECORD_INTERNAL; + +typedef struct ssl3_buffer_internal_st { + unsigned char *buf; /* at least SSL3_RT_MAX_PACKET_SIZE bytes, + * see ssl3_setup_buffers() */ + size_t len; /* buffer size */ + int offset; /* where to 'copy from' */ + int left; /* how many bytes left */ +} SSL3_BUFFER_INTERNAL; + +typedef struct ssl3_state_st { + long flags; + + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + + SSL3_BUFFER_INTERNAL rbuf; /* read IO goes into here */ + SSL3_BUFFER_INTERNAL wbuf; /* write IO goes into here */ + + SSL3_RECORD_INTERNAL rrec; /* each decoded record goes in here */ + + struct tls_content *rcontent; /* Content from opened TLS records. */ + + /* we allow one fatal and one warning alert to be outstanding, + * send close alert via the warning alert */ + int alert_dispatch; + unsigned char send_alert[2]; + + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + + /* Unprocessed Alert/Handshake protocol data. */ + struct tls_buffer *alert_fragment; + struct tls_buffer *handshake_fragment; + + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + + /* Transcript of handshake messages that have been sent and received. */ + struct tls_buffer *handshake_transcript; + + /* Rolling hash of handshake messages. */ + EVP_MD_CTX *handshake_hash; + + /* this is set whenerver we see a change_cipher_spec message + * come in when we are not looking for one */ + int change_cipher_spec; + + int warn_alert; + int fatal_alert; + + /* This flag is set when we should renegotiate ASAP, basically when + * there is no more data in the read or write buffers */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + + int in_read_app_data; + + SSL_HANDSHAKE hs; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + + /* Set if we saw a Renegotiation Indication extension from our peer. */ + int renegotiate_seen; + + /* + * ALPN information. + * + * In a server these point to the selected ALPN protocol after the + * ClientHello has been processed. In a client these contain the + * protocol that the server selected once the ServerHello has been + * processed. + */ + uint8_t *alpn_selected; + size_t alpn_selected_len; + + /* Contains the QUIC transport params received from our peer. */ + uint8_t *peer_quic_transport_params; + size_t peer_quic_transport_params_len; +} SSL3_STATE; + +/* + * Flag values for enc_flags. + */ + +/* Uses signature algorithms extension. */ +#define SSL_ENC_FLAG_SIGALGS (1 << 1) + +/* Uses SHA256 default PRF. */ +#define SSL_ENC_FLAG_SHA256_PRF (1 << 2) + +/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2. */ +#define SSL_ENC_FLAG_TLS1_2_CIPHERS (1 << 4) + +/* Allow TLS 1.3 ciphersuites only. */ +#define SSL_ENC_FLAG_TLS1_3_CIPHERS (1 << 5) + +#define TLSV1_ENC_FLAGS 0 +#define TLSV1_1_ENC_FLAGS 0 +#define TLSV1_2_ENC_FLAGS (SSL_ENC_FLAG_SIGALGS | \ + SSL_ENC_FLAG_SHA256_PRF | \ + SSL_ENC_FLAG_TLS1_2_CIPHERS) +#define TLSV1_3_ENC_FLAGS (SSL_ENC_FLAG_SIGALGS | \ + SSL_ENC_FLAG_TLS1_3_CIPHERS) + +extern const SSL_CIPHER ssl3_ciphers[]; + +const char *ssl_version_string(int ver); +int ssl_version_set_min(const SSL_METHOD *meth, uint16_t proto_ver, + uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver); +int ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver, + uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver); +int ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver); +int ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver); +uint16_t ssl_tls_version(uint16_t version); +uint16_t ssl_effective_tls_version(SSL *s); +int ssl_max_supported_version(SSL *s, uint16_t *max_ver); +int ssl_max_legacy_version(SSL *s, uint16_t *max_ver); +int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver); +int ssl_check_version_from_server(SSL *s, uint16_t server_version); +int ssl_legacy_stack_version(SSL *s, uint16_t version); +int ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher); +int ssl_cipher_allowed_in_tls_version_range(const SSL_CIPHER *cipher, + uint16_t min_ver, uint16_t max_ver); + +const SSL_METHOD *tls_legacy_method(void); +const SSL_METHOD *ssl_get_method(uint16_t version); + +void ssl_clear_cipher_state(SSL *s); +int ssl_clear_bad_session(SSL *s); + +void ssl_info_callback(const SSL *s, int type, int value); +void ssl_msg_callback(SSL *s, int is_write, int content_type, + const void *msg_buf, size_t msg_len); +void ssl_msg_callback_cbs(SSL *s, int is_write, int content_type, CBS *cbs); + +SSL_CERT *ssl_cert_new(void); +SSL_CERT *ssl_cert_dup(SSL_CERT *cert); +void ssl_cert_free(SSL_CERT *c); +SSL_CERT *ssl_get0_cert(SSL_CTX *ctx, SSL *ssl); +int ssl_cert_set0_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain); +int ssl_cert_set1_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain); +int ssl_cert_add0_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert); +int ssl_cert_add1_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert); + +int ssl_security_default_cb(const SSL *ssl, const SSL_CTX *ctx, int op, + int bits, int nid, void *other, void *ex_data); + +int ssl_security_cipher_check(const SSL *ssl, SSL_CIPHER *cipher); +int ssl_security_shared_cipher(const SSL *ssl, SSL_CIPHER *cipher); +int ssl_security_supported_cipher(const SSL *ssl, SSL_CIPHER *cipher); +int ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh); +int ssl_security_dh(const SSL *ssl, DH *dh); +int ssl_security_sigalg_check(const SSL *ssl, const EVP_PKEY *pkey); +int ssl_security_tickets(const SSL *ssl); +int ssl_security_version(const SSL *ssl, int version); +int ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, + int is_peer, int *out_error); +int ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, + X509 *x509, int *out_error); +int ssl_security_shared_group(const SSL *ssl, uint16_t group_id); +int ssl_security_supported_group(const SSL *ssl, uint16_t group_id); + +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int include_ticket); +int ssl_get_new_session(SSL *s, int session); +int ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, + int *alert); +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); +SSL_CIPHER *OBJ_bsearch_ssl_cipher_id(SSL_CIPHER *key, SSL_CIPHER const *base, + int num); +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb); +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, CBS *cbs); +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, + STACK_OF(SSL_CIPHER) **pref, STACK_OF(SSL_CIPHER) *tls13, + const char *rule_str, SSL_CERT *cert); +int ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str); +int ssl_merge_cipherlists(STACK_OF(SSL_CIPHER) *cipherlist, + STACK_OF(SSL_CIPHER) *cipherlist_tls13, + STACK_OF(SSL_CIPHER) **out_cipherlist); +void ssl_update_cache(SSL *s, int mode); +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size); +int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead); +int ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md); + +int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); +int ssl_undefined_function(SSL *s); +int ssl_undefined_void_function(void); +int ssl_undefined_const_function(const SSL *s); +SSL_CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd, + const struct ssl_sigalg **sap); +size_t ssl_dhe_params_auto_key_bits(SSL *s); +int ssl_cert_type(EVP_PKEY *pkey); +void ssl_set_cert_masks(SSL_CERT *c, const SSL_CIPHER *cipher); +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); +int ssl_has_ecc_ciphers(SSL *s); +int ssl_verify_alarm_type(long type); + +int SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len); + +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); +int ssl3_do_write(SSL *s, int type); +int ssl3_send_alert(SSL *s, int level, int desc); +int ssl3_get_req_cert_types(SSL *s, CBB *cbb); +int ssl3_get_message(SSL *s, int st1, int stn, int mt, long max); +int ssl3_num_ciphers(void); +const SSL_CIPHER *ssl3_get_cipher(unsigned int u); +const SSL_CIPHER *ssl3_get_cipher_by_id(unsigned int id); +const SSL_CIPHER *ssl3_get_cipher_by_value(uint16_t value); +uint16_t ssl3_cipher_get_value(const SSL_CIPHER *c); +int ssl3_renegotiate(SSL *ssl); + +int ssl3_renegotiate_check(SSL *ssl); + +void ssl_force_want_read(SSL *s); + +int ssl3_dispatch_alert(SSL *s); +int ssl3_read_alert(SSL *s); +int ssl3_read_change_cipher_spec(SSL *s); +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); +int ssl3_output_cert_chain(SSL *s, CBB *cbb, SSL_CERT_PKEY *cpk); +SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr); +int ssl3_setup_buffers(SSL *s); +int ssl3_setup_init_buffer(SSL *s); +void ssl3_release_init_buffer(SSL *s); +int ssl3_setup_read_buffer(SSL *s); +int ssl3_setup_write_buffer(SSL *s); +void ssl3_release_buffer(SSL3_BUFFER_INTERNAL *b); +void ssl3_release_read_buffer(SSL *s); +void ssl3_release_write_buffer(SSL *s); +int ssl3_new(SSL *s); +void ssl3_free(SSL *s); +int ssl3_accept(SSL *s); +int ssl3_connect(SSL *s); +int ssl3_read(SSL *s, void *buf, int len); +int ssl3_peek(SSL *s, void *buf, int len); +int ssl3_write(SSL *s, const void *buf, int len); +int ssl3_shutdown(SSL *s); +void ssl3_clear(SSL *s); +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); +long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void)); +long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp)(void)); +int ssl3_pending(const SSL *s); + +int ssl3_handshake_msg_hdr_len(SSL *s); +int ssl3_handshake_msg_start(SSL *s, CBB *handshake, CBB *body, + uint8_t msg_type); +int ssl3_handshake_msg_finish(SSL *s, CBB *handshake); +int ssl3_handshake_write(SSL *s); +int ssl3_record_write(SSL *s, int type); + +int ssl3_do_change_cipher_spec(SSL *ssl); + +int ssl3_packet_read(SSL *s, int plen); +int ssl3_packet_extend(SSL *s, int plen); +int ssl_server_legacy_first_packet(SSL *s); +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, + unsigned int len); + +int ssl_kex_generate_dhe(DH *dh, DH *dh_params); +int ssl_kex_generate_dhe_params_auto(DH *dh, size_t key_len); +int ssl_kex_params_dhe(DH *dh, CBB *cbb); +int ssl_kex_public_dhe(DH *dh, CBB *cbb); +int ssl_kex_peer_params_dhe(DH *dh, CBS *cbs, int *decode_error, + int *invalid_params); +int ssl_kex_peer_public_dhe(DH *dh, CBS *cbs, int *decode_error, + int *invalid_key); +int ssl_kex_derive_dhe(DH *dh, DH *dh_peer, + uint8_t **shared_key, size_t *shared_key_len); + +int ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey); +int ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid); +int ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb); +int ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs); +int ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer, + uint8_t **shared_key, size_t *shared_key_len); + +int tls1_new(SSL *s); +void tls1_free(SSL *s); +void tls1_clear(SSL *s); + +int ssl_init_wbio_buffer(SSL *s, int push); +void ssl_free_wbio_buffer(SSL *s); + +int tls1_transcript_hash_init(SSL *s); +int tls1_transcript_hash_update(SSL *s, const unsigned char *buf, size_t len); +int tls1_transcript_hash_value(SSL *s, unsigned char *out, size_t len, + size_t *outlen); +void tls1_transcript_hash_free(SSL *s); + +int tls1_transcript_init(SSL *s); +void tls1_transcript_free(SSL *s); +void tls1_transcript_reset(SSL *s); +int tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len); +int tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len); +void tls1_transcript_freeze(SSL *s); +void tls1_transcript_unfreeze(SSL *s); +int tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len); + +int tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len, + const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len, + const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len, + const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len); + +void tls1_cleanup_key_block(SSL *s); +int tls1_change_read_cipher_state(SSL *s); +int tls1_change_write_cipher_state(SSL *s); +int tls1_setup_key_block(SSL *s); +int tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len); +int ssl_ok(SSL *s); + +int tls12_derive_finished(SSL *s); +int tls12_derive_peer_finished(SSL *s); +int tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret, + size_t premaster_secret_len); + +int ssl_using_ecc_cipher(SSL *s); +int ssl_check_srvr_ecc_cert_and_alg(SSL *s, X509 *x); + +void tls1_get_formatlist(const SSL *s, int client_formats, + const uint8_t **pformats, size_t *pformatslen); +void tls1_get_group_list(const SSL *s, int client_groups, + const uint16_t **pgroups, size_t *pgroupslen); + +int tls1_set_groups(uint16_t **out_group_ids, size_t *out_group_ids_len, + const int *groups, size_t ngroups); +int tls1_set_group_list(uint16_t **out_group_ids, size_t *out_group_ids_len, + const char *groups); + +int tls1_ec_group_id2nid(uint16_t group_id, int *out_nid); +int tls1_ec_group_id2bits(uint16_t group_id, int *out_bits); +int tls1_ec_nid2group_id(int nid, uint16_t *out_group_id); +int tls1_check_group(SSL *s, uint16_t group_id); +int tls1_count_shared_groups(const SSL *ssl, size_t *out_count); +int tls1_get_shared_group_by_index(const SSL *ssl, size_t index, int *out_nid); +int tls1_get_supported_group(const SSL *s, int *out_nid); + +int ssl_check_clienthello_tlsext_early(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s); +int ssl_check_serverhello_tlsext(SSL *s); + +#define TLS1_TICKET_FATAL_ERROR -1 +#define TLS1_TICKET_NONE 0 +#define TLS1_TICKET_EMPTY 1 +#define TLS1_TICKET_NOT_DECRYPTED 2 +#define TLS1_TICKET_DECRYPTED 3 + +int tls1_process_ticket(SSL *s, CBS *ext_block, int *alert, SSL_SESSION **ret); + +int tls1_check_ec_server_key(SSL *s); + +/* s3_cbc.c */ +void ssl3_cbc_copy_mac(unsigned char *out, const SSL3_RECORD_INTERNAL *rec, + unsigned int md_size, unsigned int orig_len); +int ssl3_cbc_remove_padding(SSL3_RECORD_INTERNAL *rec, unsigned int eiv_len, + unsigned int mac_size); +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char *md_out, + size_t *md_out_size, const unsigned char header[13], + const unsigned char *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, + unsigned int mac_secret_length); +int SSL_state_func_code(int _state); + +#define SSLerror(s, r) SSL_error_internal(s, r, __FILE__, __LINE__) +#define SSLerrorx(r) ERR_PUT_error(ERR_LIB_SSL,(0xfff),(r),__FILE__,__LINE__) +void SSL_error_internal(const SSL *s, int r, char *f, int l); + +#ifndef OPENSSL_NO_SRTP + +int srtp_find_profile_by_name(const char *profile_name, + const SRTP_PROTECTION_PROFILE **pptr, unsigned int len); +int srtp_find_profile_by_num(unsigned int profile_num, + const SRTP_PROTECTION_PROFILE **pptr); + +#endif /* OPENSSL_NO_SRTP */ + +int tls_process_peer_certs(SSL *s, STACK_OF(X509) *peer_certs); + +__END_HIDDEN_DECLS + +#endif /* !HEADER_SSL_LOCL_H */ diff --git a/Libraries/libressl/ssl/ssl_methods.c b/Libraries/libressl/ssl/ssl_methods.c new file mode 100644 index 000000000..ca80da62f --- /dev/null +++ b/Libraries/libressl/ssl/ssl_methods.c @@ -0,0 +1,569 @@ +/* $OpenBSD: ssl_methods.c,v 1.31 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "dtls_local.h" +#include "ssl_local.h" +#include "tls13_internal.h" + +static const SSL_METHOD DTLS_method_data = { + .dtls = 1, + .server = 1, + .version = DTLS1_2_VERSION, + .min_tls_version = TLS1_1_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .get_cipher = dtls1_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +static const SSL_METHOD DTLS_client_method_data = { + .dtls = 1, + .server = 0, + .version = DTLS1_2_VERSION, + .min_tls_version = TLS1_1_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .get_cipher = dtls1_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +static const SSL_METHOD DTLSv1_method_data = { + .dtls = 1, + .server = 1, + .version = DTLS1_VERSION, + .min_tls_version = TLS1_1_VERSION, + .max_tls_version = TLS1_1_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .get_cipher = dtls1_get_cipher, + .enc_flags = TLSV1_1_ENC_FLAGS, +}; + +static const SSL_METHOD DTLSv1_client_method_data = { + .dtls = 1, + .server = 0, + .version = DTLS1_VERSION, + .min_tls_version = TLS1_1_VERSION, + .max_tls_version = TLS1_1_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .get_cipher = dtls1_get_cipher, + .enc_flags = TLSV1_1_ENC_FLAGS, +}; + +static const SSL_METHOD DTLSv1_2_method_data = { + .dtls = 1, + .server = 1, + .version = DTLS1_2_VERSION, + .min_tls_version = TLS1_2_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .get_cipher = dtls1_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +static const SSL_METHOD DTLSv1_2_client_method_data = { + .dtls = 1, + .server = 0, + .version = DTLS1_2_VERSION, + .min_tls_version = TLS1_2_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .get_cipher = dtls1_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +const SSL_METHOD * +DTLSv1_client_method(void) +{ + return &DTLSv1_client_method_data; +} +LSSL_ALIAS(DTLSv1_client_method); + +const SSL_METHOD * +DTLSv1_method(void) +{ + return &DTLSv1_method_data; +} +LSSL_ALIAS(DTLSv1_method); + +const SSL_METHOD * +DTLSv1_server_method(void) +{ + return &DTLSv1_method_data; +} +LSSL_ALIAS(DTLSv1_server_method); + +const SSL_METHOD * +DTLSv1_2_client_method(void) +{ + return &DTLSv1_2_client_method_data; +} +LSSL_ALIAS(DTLSv1_2_client_method); + +const SSL_METHOD * +DTLSv1_2_method(void) +{ + return &DTLSv1_2_method_data; +} +LSSL_ALIAS(DTLSv1_2_method); + +const SSL_METHOD * +DTLSv1_2_server_method(void) +{ + return &DTLSv1_2_method_data; +} +LSSL_ALIAS(DTLSv1_2_server_method); + +const SSL_METHOD * +DTLS_client_method(void) +{ + return &DTLS_client_method_data; +} +LSSL_ALIAS(DTLS_client_method); + +const SSL_METHOD * +DTLS_method(void) +{ + return &DTLS_method_data; +} +LSSL_ALIAS(DTLS_method); + +const SSL_METHOD * +DTLS_server_method(void) +{ + return &DTLS_method_data; +} +LSSL_ALIAS(DTLS_server_method); + +static const SSL_METHOD TLS_method_data = { + .dtls = 0, + .server = 1, + .version = TLS1_3_VERSION, + .min_tls_version = TLS1_VERSION, + .max_tls_version = TLS1_3_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = tls13_legacy_accept, + .ssl_connect = tls13_legacy_connect, + .ssl_shutdown = tls13_legacy_shutdown, + .ssl_renegotiate = ssl_undefined_function, + .ssl_renegotiate_check = ssl_ok, + .ssl_pending = tls13_legacy_pending, + .ssl_read_bytes = tls13_legacy_read_bytes, + .ssl_write_bytes = tls13_legacy_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_3_ENC_FLAGS, +}; + +static const SSL_METHOD TLS_legacy_method_data = { + .dtls = 0, + .server = 1, + .version = TLS1_2_VERSION, + .min_tls_version = TLS1_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl_undefined_function, + .ssl_renegotiate_check = ssl_ok, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +static const SSL_METHOD TLS_client_method_data = { + .dtls = 0, + .server = 0, + .version = TLS1_3_VERSION, + .min_tls_version = TLS1_VERSION, + .max_tls_version = TLS1_3_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = tls13_legacy_accept, + .ssl_connect = tls13_legacy_connect, + .ssl_shutdown = tls13_legacy_shutdown, + .ssl_renegotiate = ssl_undefined_function, + .ssl_renegotiate_check = ssl_ok, + .ssl_pending = tls13_legacy_pending, + .ssl_read_bytes = tls13_legacy_read_bytes, + .ssl_write_bytes = tls13_legacy_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_3_ENC_FLAGS, +}; + +static const SSL_METHOD TLSv1_method_data = { + .dtls = 0, + .server = 1, + .version = TLS1_VERSION, + .min_tls_version = TLS1_VERSION, + .max_tls_version = TLS1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_ENC_FLAGS, +}; + +static const SSL_METHOD TLSv1_client_method_data = { + .dtls = 0, + .server = 0, + .version = TLS1_VERSION, + .min_tls_version = TLS1_VERSION, + .max_tls_version = TLS1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_ENC_FLAGS, +}; + +static const SSL_METHOD TLSv1_1_method_data = { + .dtls = 0, + .server = 1, + .version = TLS1_1_VERSION, + .min_tls_version = TLS1_1_VERSION, + .max_tls_version = TLS1_1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_1_ENC_FLAGS, +}; + +static const SSL_METHOD TLSv1_1_client_method_data = { + .dtls = 0, + .server = 0, + .version = TLS1_1_VERSION, + .min_tls_version = TLS1_1_VERSION, + .max_tls_version = TLS1_1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_1_ENC_FLAGS, +}; + +static const SSL_METHOD TLSv1_2_method_data = { + .dtls = 0, + .server = 1, + .version = TLS1_2_VERSION, + .min_tls_version = TLS1_2_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +static const SSL_METHOD TLSv1_2_client_method_data = { + .dtls = 0, + .server = 0, + .version = TLS1_2_VERSION, + .min_tls_version = TLS1_2_VERSION, + .max_tls_version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_pending = ssl3_pending, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .get_cipher = ssl3_get_cipher, + .enc_flags = TLSV1_2_ENC_FLAGS, +}; + +const SSL_METHOD * +TLS_client_method(void) +{ + return (&TLS_client_method_data); +} +LSSL_ALIAS(TLS_client_method); + +const SSL_METHOD * +TLS_method(void) +{ + return (&TLS_method_data); +} +LSSL_ALIAS(TLS_method); + +const SSL_METHOD * +TLS_server_method(void) +{ + return TLS_method(); +} +LSSL_ALIAS(TLS_server_method); + +const SSL_METHOD * +tls_legacy_method(void) +{ + return (&TLS_legacy_method_data); +} + +const SSL_METHOD * +SSLv23_client_method(void) +{ + return TLS_client_method(); +} +LSSL_ALIAS(SSLv23_client_method); + +const SSL_METHOD * +SSLv23_method(void) +{ + return TLS_method(); +} +LSSL_ALIAS(SSLv23_method); + +const SSL_METHOD * +SSLv23_server_method(void) +{ + return TLS_method(); +} +LSSL_ALIAS(SSLv23_server_method); + +const SSL_METHOD * +TLSv1_client_method(void) +{ + return (&TLSv1_client_method_data); +} +LSSL_ALIAS(TLSv1_client_method); + +const SSL_METHOD * +TLSv1_method(void) +{ + return (&TLSv1_method_data); +} +LSSL_ALIAS(TLSv1_method); + +const SSL_METHOD * +TLSv1_server_method(void) +{ + return (&TLSv1_method_data); +} +LSSL_ALIAS(TLSv1_server_method); + +const SSL_METHOD * +TLSv1_1_client_method(void) +{ + return (&TLSv1_1_client_method_data); +} +LSSL_ALIAS(TLSv1_1_client_method); + +const SSL_METHOD * +TLSv1_1_method(void) +{ + return (&TLSv1_1_method_data); +} +LSSL_ALIAS(TLSv1_1_method); + +const SSL_METHOD * +TLSv1_1_server_method(void) +{ + return (&TLSv1_1_method_data); +} +LSSL_ALIAS(TLSv1_1_server_method); + +const SSL_METHOD * +TLSv1_2_client_method(void) +{ + return (&TLSv1_2_client_method_data); +} +LSSL_ALIAS(TLSv1_2_client_method); + +const SSL_METHOD * +TLSv1_2_method(void) +{ + return (&TLSv1_2_method_data); +} +LSSL_ALIAS(TLSv1_2_method); + +const SSL_METHOD * +TLSv1_2_server_method(void) +{ + return (&TLSv1_2_method_data); +} +LSSL_ALIAS(TLSv1_2_server_method); + +const SSL_METHOD * +ssl_get_method(uint16_t version) +{ + if (version == TLS1_3_VERSION) + return (TLS_method()); + if (version == TLS1_2_VERSION) + return (TLSv1_2_method()); + if (version == TLS1_1_VERSION) + return (TLSv1_1_method()); + if (version == TLS1_VERSION) + return (TLSv1_method()); + if (version == DTLS1_VERSION) + return (DTLSv1_method()); + if (version == DTLS1_2_VERSION) + return (DTLSv1_2_method()); + + return (NULL); +} diff --git a/Libraries/libressl/ssl/ssl_packet.c b/Libraries/libressl/ssl/ssl_packet.c new file mode 100644 index 000000000..70017b466 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_packet.c @@ -0,0 +1,292 @@ +/* $OpenBSD: ssl_packet.c,v 1.15 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2016, 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "bytestring.h" +#include "ssl_local.h" + +static int +ssl_is_sslv2_client_hello(CBS *header) +{ + uint16_t record_length; + uint8_t message_type; + CBS cbs; + + CBS_dup(header, &cbs); + + if (!CBS_get_u16(&cbs, &record_length) || + !CBS_get_u8(&cbs, &message_type)) + return 0; + + /* + * The SSLv2 record length field uses variable length (2 or 3 byte) + * encoding. Given the size of a client hello, we expect/require the + * 2-byte form which is indicated by a one in the most significant bit. + */ + if ((record_length & 0x8000) == 0) + return 0; + if ((record_length & ~0x8000) < 3) + return 0; + if (message_type != SSL2_MT_CLIENT_HELLO) + return 0; + + return 1; +} + +static int +ssl_is_sslv3_handshake(CBS *header) +{ + uint16_t record_version; + uint8_t record_type; + CBS cbs; + + CBS_dup(header, &cbs); + + if (!CBS_get_u8(&cbs, &record_type) || + !CBS_get_u16(&cbs, &record_version)) + return 0; + + if (record_type != SSL3_RT_HANDSHAKE) + return 0; + if ((record_version >> 8) != SSL3_VERSION_MAJOR) + return 0; + + return 1; +} + +static int +ssl_convert_sslv2_client_hello(SSL *s) +{ + CBB cbb, handshake, client_hello, cipher_suites, compression, session_id; + CBS cbs, challenge, cipher_specs, session; + uint16_t record_length, client_version, cipher_specs_length; + uint16_t session_id_length, challenge_length; + unsigned char *client_random = NULL, *data = NULL; + size_t data_len, pad_len, len; + uint32_t cipher_spec; + uint8_t message_type; + unsigned char *pad; + int ret = -1; + int n; + + memset(&cbb, 0, sizeof(cbb)); + + CBS_init(&cbs, s->packet, SSL3_RT_HEADER_LENGTH); + + if (!CBS_get_u16(&cbs, &record_length) || + !CBS_get_u8(&cbs, &message_type) || + !CBS_get_u16(&cbs, &client_version)) + return -1; + + /* + * The SSLv2 record length field uses variable length (2 or 3 byte) + * encoding. Given the size of a client hello, we expect/require the + * 2-byte form which is indicated by a one in the most significant bit. + * Also note that the record length value does not include the bytes + * used for the record length field. + */ + if ((record_length & 0x8000) == 0) + return -1; + record_length &= ~0x8000; + if (record_length < SSL3_RT_HEADER_LENGTH - 2) + return -1; + if (message_type != SSL2_MT_CLIENT_HELLO) + return -1; + + if (record_length < 9) { + SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH); + return -1; + } + if (record_length > 4096) { + SSLerror(s, SSL_R_RECORD_TOO_LARGE); + return -1; + } + + n = ssl3_packet_extend(s, record_length + 2); + if (n != record_length + 2) + return n; + + tls1_transcript_record(s, s->packet + 2, + s->packet_length - 2); + s->mac_packet = 0; + + if (s->msg_callback) + s->msg_callback(0, SSL2_VERSION, 0, + s->packet + 2, s->packet_length - 2, s, + s->msg_callback_arg); + + /* Decode the SSLv2 record containing the client hello. */ + CBS_init(&cbs, s->packet, s->packet_length); + + if (!CBS_get_u16(&cbs, &record_length)) + return -1; + if (!CBS_get_u8(&cbs, &message_type)) + return -1; + if (!CBS_get_u16(&cbs, &client_version)) + return -1; + if (!CBS_get_u16(&cbs, &cipher_specs_length)) + return -1; + if (!CBS_get_u16(&cbs, &session_id_length)) + return -1; + if (!CBS_get_u16(&cbs, &challenge_length)) + return -1; + if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length)) + return -1; + if (!CBS_get_bytes(&cbs, &session, session_id_length)) + return -1; + if (!CBS_get_bytes(&cbs, &challenge, challenge_length)) + return -1; + if (CBS_len(&cbs) != 0) { + SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH); + return -1; + } + + /* + * Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or + * left-padding with zero bytes. + */ + if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL) + goto err; + if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE)) + goto err; + if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE) + len = SSL3_RANDOM_SIZE; + pad_len = SSL3_RANDOM_SIZE - len; + if (!CBB_add_space(&cbb, &pad, pad_len)) + goto err; + memset(pad, 0, pad_len); + if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len)) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; + + /* Build SSLv3/TLS record with client hello. */ + if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH)) + goto err; + if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE)) + goto err; + if (!CBB_add_u16(&cbb, 0x0301)) + goto err; + if (!CBB_add_u16_length_prefixed(&cbb, &handshake)) + goto err; + if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO)) + goto err; + if (!CBB_add_u24_length_prefixed(&handshake, &client_hello)) + goto err; + if (!CBB_add_u16(&client_hello, client_version)) + goto err; + if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE)) + goto err; + if (!CBB_add_u8_length_prefixed(&client_hello, &session_id)) + goto err; + if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites)) + goto err; + while (CBS_len(&cipher_specs) > 0) { + if (!CBS_get_u24(&cipher_specs, &cipher_spec)) + goto err; + if ((cipher_spec & 0xff0000) != 0) + continue; + if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff)) + goto err; + } + if (!CBB_add_u8_length_prefixed(&client_hello, &compression)) + goto err; + if (!CBB_add_u8(&compression, 0)) + goto err; + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; + + if (data_len > s->s3->rbuf.len) + goto err; + + s->packet = s->s3->rbuf.buf; + s->packet_length = data_len; + memcpy(s->packet, data, data_len); + ret = 1; + + err: + CBB_cleanup(&cbb); + free(client_random); + free(data); + + return (ret); +} + +/* + * Potentially do legacy processing on the first packet received by a TLS + * server. We return 1 if we want SSLv3/TLS record processing to continue + * normally, otherwise we must set an SSLerr and return -1. + */ +int +ssl_server_legacy_first_packet(SSL *s) +{ + uint16_t min_version; + const char *data; + CBS header; + + if (SSL_is_dtls(s)) + return 1; + + CBS_init(&header, s->packet, SSL3_RT_HEADER_LENGTH); + + if (ssl_is_sslv3_handshake(&header) == 1) + return 1; + + /* Only continue if this is not a version locked method. */ + if (s->method->min_tls_version == s->method->max_tls_version) + return 1; + + if (ssl_is_sslv2_client_hello(&header) == 1) { + /* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */ + if (ssl_enabled_tls_version_range(s, &min_version, NULL) != 1) { + SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); + return -1; + } + if (min_version > TLS1_VERSION) + return 1; + + if (ssl_convert_sslv2_client_hello(s) != 1) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + return -1; + } + + return 1; + } + + /* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */ + if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + data = (const char *)CBS_data(&header); + + /* Is this a cleartext protocol? */ + if (strncmp("GET ", data, 4) == 0 || + strncmp("POST ", data, 5) == 0 || + strncmp("HEAD ", data, 5) == 0 || + strncmp("PUT ", data, 4) == 0) { + SSLerror(s, SSL_R_HTTP_REQUEST); + return -1; + } + if (strncmp("CONNE", data, 5) == 0) { + SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST); + return -1; + } + + SSLerror(s, SSL_R_UNKNOWN_PROTOCOL); + + return -1; +} diff --git a/Libraries/libressl/ssl/ssl_pkt.c b/Libraries/libressl/ssl/ssl_pkt.c new file mode 100644 index 000000000..2c33c4538 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_pkt.c @@ -0,0 +1,1313 @@ +/* $OpenBSD: ssl_pkt.c,v 1.66 2023/07/11 17:02:47 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include +#include + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" +#include "tls_content.h" + +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len); +static int ssl3_get_record(SSL *s); + +/* + * Force a WANT_READ return for certain error conditions where + * we don't want to spin internally. + */ +void +ssl_force_want_read(SSL *s) +{ + BIO *bio; + + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + + s->rwstate = SSL_READING; +} + +/* + * If extend == 0, obtain new n-byte packet; if extend == 1, increase + * packet by another n bytes. + * The packet will be in the sub-array of s->s3->rbuf.buf specified + * by s->packet and s->packet_length. + * (If s->read_ahead is set, 'max' bytes may be stored in rbuf + * [plus s->packet_length bytes if extend == 1].) + */ +static int +ssl3_read_n(SSL *s, int n, int max, int extend) +{ + SSL3_BUFFER_INTERNAL *rb = &(s->s3->rbuf); + int i, len, left; + size_t align; + unsigned char *pkt; + + if (n <= 0) + return n; + + if (rb->buf == NULL) { + if (!ssl3_setup_read_buffer(s)) + return -1; + } + if (rb->buf == NULL) + return -1; + + left = rb->left; + align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); + + if (!extend) { + /* start with empty packet ... */ + if (left == 0) + rb->offset = align; + else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { + /* check if next packet length is large + * enough to justify payload alignment... */ + pkt = rb->buf + rb->offset; + if (pkt[0] == SSL3_RT_APPLICATION_DATA && + (pkt[3]<<8|pkt[4]) >= 128) { + /* Note that even if packet is corrupted + * and its length field is insane, we can + * only be led to wrong decision about + * whether memmove will occur or not. + * Header values has no effect on memmove + * arguments and therefore no buffer + * overrun can be triggered. */ + memmove(rb->buf + align, pkt, left); + rb->offset = align; + } + } + s->packet = rb->buf + rb->offset; + s->packet_length = 0; + /* ... now we can act as if 'extend' was set */ + } + + /* For DTLS/UDP reads should not span multiple packets + * because the read operation returns the whole packet + * at once (as long as it fits into the buffer). */ + if (SSL_is_dtls(s)) { + if (left > 0 && n > left) + n = left; + } + + /* if there is enough in the buffer from a previous read, take some */ + if (left >= n) { + s->packet_length += n; + rb->left = left - n; + rb->offset += n; + return (n); + } + + /* else we need to read more data */ + + len = s->packet_length; + pkt = rb->buf + align; + /* Move any available bytes to front of buffer: + * 'len' bytes already pointed to by 'packet', + * 'left' extra ones at the end */ + if (s->packet != pkt) { + /* len > 0 */ + memmove(pkt, s->packet, len + left); + s->packet = pkt; + rb->offset = len + align; + } + + if (n > (int)(rb->len - rb->offset)) { + /* does not happen */ + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (s->read_ahead || SSL_is_dtls(s)) { + if (max < n) + max = n; + if (max > (int)(rb->len - rb->offset)) + max = rb->len - rb->offset; + } else { + /* ignore max parameter */ + max = n; + } + + while (left < n) { + /* Now we have len+left bytes at the front of s->s3->rbuf.buf + * and need to read in more until we have len+n (up to + * len+max if possible) */ + + errno = 0; + if (s->rbio != NULL) { + s->rwstate = SSL_READING; + i = BIO_read(s->rbio, pkt + len + left, max - left); + } else { + SSLerror(s, SSL_R_READ_BIO_NOT_SET); + i = -1; + } + + if (i <= 0) { + rb->left = left; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + !SSL_is_dtls(s)) { + if (len + left == 0) + ssl3_release_read_buffer(s); + } + return (i); + } + left += i; + + /* + * reads should *never* span multiple packets for DTLS because + * the underlying transport protocol is message oriented as + * opposed to byte oriented as in the TLS case. + */ + if (SSL_is_dtls(s)) { + if (n > left) + n = left; /* makes the while condition false */ + } + } + + /* done reading, now the book-keeping */ + rb->offset += n; + rb->left = left - n; + s->packet_length += n; + s->rwstate = SSL_NOTHING; + + return (n); +} + +int +ssl3_packet_read(SSL *s, int plen) +{ + int n; + + n = ssl3_read_n(s, plen, s->s3->rbuf.len, 0); + if (n <= 0) + return n; + if (s->packet_length < plen) + return s->packet_length; + + return plen; +} + +int +ssl3_packet_extend(SSL *s, int plen) +{ + int rlen, n; + + if (s->packet_length >= plen) + return plen; + rlen = plen - s->packet_length; + + n = ssl3_read_n(s, rlen, rlen, 1); + if (n <= 0) + return n; + if (s->packet_length < plen) + return s->packet_length; + + return plen; +} + +/* Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by ssl3_read_bytes */ +static int +ssl3_get_record(SSL *s) +{ + SSL3_BUFFER_INTERNAL *rb = &(s->s3->rbuf); + SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec); + uint8_t alert_desc; + int al, n; + int ret = -1; + + again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < SSL3_RT_HEADER_LENGTH)) { + CBS header; + uint16_t len, ssl_version; + uint8_t type; + + n = ssl3_packet_read(s, SSL3_RT_HEADER_LENGTH); + if (n <= 0) + return (n); + + s->mac_packet = 1; + s->rstate = SSL_ST_READ_BODY; + + if (s->server && s->first_packet) { + if ((ret = ssl_server_legacy_first_packet(s)) != 1) + return (ret); + ret = -1; + } + + CBS_init(&header, s->packet, SSL3_RT_HEADER_LENGTH); + + /* Pull apart the header into the SSL3_RECORD_INTERNAL */ + if (!CBS_get_u8(&header, &type) || + !CBS_get_u16(&header, &ssl_version) || + !CBS_get_u16(&header, &len)) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + goto err; + } + + rr->type = type; + rr->length = len; + + /* Lets check version */ + if (!s->first_packet && ssl_version != s->version) { + if ((s->version & 0xFF00) == (ssl_version & 0xFF00) && + !tls12_record_layer_write_protected(s->rl)) { + /* Send back error using their minor version number :-) */ + s->version = ssl_version; + } + SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); + al = SSL_AD_PROTOCOL_VERSION; + goto fatal_err; + } + + if ((ssl_version >> 8) != SSL3_VERSION_MAJOR) { + SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); + goto err; + } + + if (rr->length > rb->len - SSL3_RT_HEADER_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerror(s, SSL_R_PACKET_LENGTH_TOO_LONG); + goto fatal_err; + } + } + + n = ssl3_packet_extend(s, SSL3_RT_HEADER_LENGTH + rr->length); + if (n <= 0) + return (n); + if (n != SSL3_RT_HEADER_LENGTH + rr->length) + return (n); + + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* + * A full record has now been read from the wire, which now needs + * to be processed. + */ + tls12_record_layer_set_version(s->rl, s->version); + + if (!tls12_record_layer_open_record(s->rl, s->packet, s->packet_length, + s->s3->rcontent)) { + tls12_record_layer_alert(s->rl, &alert_desc); + + if (alert_desc == 0) + goto err; + + if (alert_desc == SSL_AD_RECORD_OVERFLOW) + SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + else if (alert_desc == SSL_AD_BAD_RECORD_MAC) + SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + + al = alert_desc; + goto fatal_err; + } + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + + if (tls_content_remaining(s->s3->rcontent) == 0) { + /* + * Zero-length fragments are only permitted for application + * data, as per RFC 5246 section 6.2.1. + */ + if (rr->type != SSL3_RT_APPLICATION_DATA) { + SSLerror(s, SSL_R_BAD_LENGTH); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto fatal_err; + } + + tls_content_clear(s->s3->rcontent); + + /* + * CBC countermeasures for known IV weaknesses can legitimately + * insert a single empty record, so we allow ourselves to read + * once past a single empty record without forcing want_read. + */ + if (s->empty_record_count++ > SSL_MAX_EMPTY_RECORDS) { + SSLerror(s, SSL_R_PEER_BEHAVING_BADLY); + return -1; + } + if (s->empty_record_count > 1) { + ssl_force_want_read(s); + return -1; + } + goto again; + } + + s->empty_record_count = 0; + + return (1); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (ret); +} + +/* Call this to write data in records of type 'type' + * It will return <= 0 if not all data has been sent or non-blocking IO. + */ +int +ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) +{ + const unsigned char *buf = buf_; + unsigned int tot, n, nw; + int i; + + if (len < 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + s->rwstate = SSL_NOTHING; + tot = s->s3->wnum; + s->s3->wnum = 0; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + if (len < tot) + len = tot; + n = (len - tot); + for (;;) { + if (n > s->max_send_fragment) + nw = s->max_send_fragment; + else + nw = n; + + i = do_ssl3_write(s, type, &(buf[tot]), nw); + if (i <= 0) { + s->s3->wnum = tot; + return i; + } + + if ((i == (int)n) || (type == SSL3_RT_APPLICATION_DATA && + (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { + /* + * Next chunk of data should get another prepended + * empty fragment in ciphersuites with known-IV + * weakness. + */ + s->s3->empty_fragment_done = 0; + + return tot + i; + } + + n -= i; + tot += i; + } +} + +static int +do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) +{ + SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf); + SSL_SESSION *sess = s->session; + int need_empty_fragment = 0; + size_t align, out_len; + CBB cbb; + int ret; + + memset(&cbb, 0, sizeof(cbb)); + + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + + /* + * First check if there is a SSL3_BUFFER_INTERNAL still being written + * out. This will happen with non blocking IO. + */ + if (wb->left != 0) + return (ssl3_write_pending(s, type, buf, len)); + + /* If we have an alert to send, let's send it. */ + if (s->s3->alert_dispatch) { + if ((ret = ssl3_dispatch_alert(s)) <= 0) + return (ret); + /* If it went, fall through and send more stuff. */ + + /* We may have released our buffer, if so get it again. */ + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + } + + if (len == 0) + return 0; + + /* + * Countermeasure against known-IV weakness in CBC ciphersuites + * (see http://www.openssl.org/~bodo/tls-cbc.txt). Note that this + * is unnecessary for AEAD. + */ + if (sess != NULL && tls12_record_layer_write_protected(s->rl)) { + if (s->s3->need_empty_fragments && + !s->s3->empty_fragment_done && + type == SSL3_RT_APPLICATION_DATA) + need_empty_fragment = 1; + } + + /* + * An extra fragment would be a couple of cipher blocks, which would + * be a multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real + * payload, then we can just simply pretend we have two headers. + */ + align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; + if (need_empty_fragment) + align += SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); + wb->offset = align; + + if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align)) + goto err; + + tls12_record_layer_set_version(s->rl, s->version); + + if (need_empty_fragment) { + if (!tls12_record_layer_seal_record(s->rl, type, + buf, 0, &cbb)) + goto err; + s->s3->empty_fragment_done = 1; + } + + if (!tls12_record_layer_seal_record(s->rl, type, buf, len, &cbb)) + goto err; + + if (!CBB_finish(&cbb, NULL, &out_len)) + goto err; + + wb->left = out_len; + + /* + * Memorize arguments so that ssl3_write_pending can detect + * bad write retries later. + */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* We now just need to write the buffer. */ + return ssl3_write_pending(s, type, buf, len); + + err: + CBB_cleanup(&cbb); + + return -1; +} + +/* if s->s3->wbuf.left != 0, we need to call this */ +int +ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) +{ + int i; + SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf); + + /* XXXX */ + if ((s->s3->wpend_tot > (int)len) || ((s->s3->wpend_buf != buf) && + !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) || + (s->s3->wpend_type != type)) { + SSLerror(s, SSL_R_BAD_WRITE_RETRY); + return (-1); + } + + for (;;) { + errno = 0; + if (s->wbio != NULL) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, (char *)&(wb->buf[wb->offset]), + (unsigned int)wb->left); + } else { + SSLerror(s, SSL_R_BIO_NOT_SET); + i = -1; + } + if (i == wb->left) { + wb->left = 0; + wb->offset += i; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + !SSL_is_dtls(s)) + ssl3_release_write_buffer(s); + s->rwstate = SSL_NOTHING; + return (s->s3->wpend_ret); + } else if (i <= 0) { + /* + * For DTLS, just drop it. That's kind of the + * whole point in using a datagram service. + */ + if (SSL_is_dtls(s)) + wb->left = 0; + return (i); + } + wb->offset += i; + wb->left -= i; + } +} + +static ssize_t +ssl3_read_cb(void *buf, size_t n, void *cb_arg) +{ + SSL *s = cb_arg; + + return tls_content_read(s->s3->rcontent, buf, n); +} + +#define SSL3_ALERT_LENGTH 2 + +int +ssl3_read_alert(SSL *s) +{ + uint8_t alert_level, alert_descr; + ssize_t ret; + CBS cbs; + + /* + * TLSv1.2 permits an alert to be fragmented across multiple records or + * for multiple alerts to be be coalesced into a single alert record. + * In the case of DTLS, there is no way to reassemble an alert + * fragmented across multiple records, hence a full alert must be + * available in the record. + */ + if (s->s3->alert_fragment == NULL) { + if ((s->s3->alert_fragment = tls_buffer_new(0)) == NULL) + return -1; + tls_buffer_set_capacity_limit(s->s3->alert_fragment, + SSL3_ALERT_LENGTH); + } + ret = tls_buffer_extend(s->s3->alert_fragment, SSL3_ALERT_LENGTH, + ssl3_read_cb, s); + if (ret <= 0 && ret != TLS_IO_WANT_POLLIN) + return -1; + if (ret != SSL3_ALERT_LENGTH) { + if (SSL_is_dtls(s)) { + SSLerror(s, SSL_R_BAD_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return -1; + } + return 1; + } + + if (!tls_buffer_data(s->s3->alert_fragment, &cbs)) + return -1; + + ssl_msg_callback_cbs(s, 0, SSL3_RT_ALERT, &cbs); + + if (!CBS_get_u8(&cbs, &alert_level)) + return -1; + if (!CBS_get_u8(&cbs, &alert_descr)) + return -1; + + tls_buffer_free(s->s3->alert_fragment); + s->s3->alert_fragment = NULL; + + ssl_info_callback(s, SSL_CB_READ_ALERT, + (alert_level << 8) | alert_descr); + + if (alert_level == SSL3_AL_WARNING) { + s->s3->warn_alert = alert_descr; + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return 0; + } + /* We requested renegotiation and the peer rejected it. */ + if (alert_descr == SSL_AD_NO_RENEGOTIATION) { + SSLerror(s, SSL_R_NO_RENEGOTIATION); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + return -1; + } + } else if (alert_level == SSL3_AL_FATAL) { + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerror(s, SSL_AD_REASON_OFFSET + alert_descr); + ERR_asprintf_error_data("SSL alert number %d", alert_descr); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->ctx, s->session); + return 0; + } else { + SSLerror(s, SSL_R_UNKNOWN_ALERT_TYPE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return -1; + } + + return 1; +} + +int +ssl3_read_change_cipher_spec(SSL *s) +{ + const uint8_t ccs[1] = { SSL3_MT_CCS }; + + /* + * 'Change Cipher Spec' is just a single byte, so we know exactly what + * the record payload has to look like. + */ + if (tls_content_remaining(s->s3->rcontent) != sizeof(ccs)) { + SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return -1; + } + if (!tls_content_equal(s->s3->rcontent, ccs, sizeof(ccs))) { + SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return -1; + } + + /* XDTLS: check that epoch is consistent */ + + ssl_msg_callback_cbs(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, + tls_content_cbs(s->s3->rcontent)); + + /* Check that we have a cipher to change to. */ + if (s->s3->hs.cipher == NULL) { + SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + /* Check that we should be receiving a Change Cipher Spec. */ + if (SSL_is_dtls(s)) { + if (!s->d1->change_cipher_spec_ok) { + /* + * We can't process a CCS now, because previous + * handshake messages are still missing, so just + * drop it. + */ + tls_content_clear(s->s3->rcontent); + return 1; + } + s->d1->change_cipher_spec_ok = 0; + } else { + if ((s->s3->flags & SSL3_FLAGS_CCS_OK) == 0) { + SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + } + + tls_content_clear(s->s3->rcontent); + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + return -1; + + return 1; +} + +static int +ssl3_read_handshake_unexpected(SSL *s) +{ + uint32_t hs_msg_length; + uint8_t hs_msg_type; + ssize_t ssret; + CBS cbs; + int ret; + + /* + * We need four bytes of handshake data so we have a handshake message + * header - this may be in the same record or fragmented across multiple + * records. + */ + if (s->s3->handshake_fragment == NULL) { + if ((s->s3->handshake_fragment = tls_buffer_new(0)) == NULL) + return -1; + tls_buffer_set_capacity_limit(s->s3->handshake_fragment, + SSL3_HM_HEADER_LENGTH); + } + ssret = tls_buffer_extend(s->s3->handshake_fragment, SSL3_HM_HEADER_LENGTH, + ssl3_read_cb, s); + if (ssret <= 0 && ssret != TLS_IO_WANT_POLLIN) + return -1; + if (ssret != SSL3_HM_HEADER_LENGTH) + return 1; + + if (s->in_handshake) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* + * This code currently deals with HelloRequest and ClientHello messages - + * anything else is pushed to the handshake_func. Almost all of this + * belongs in the client/server handshake code. + */ + + /* Parse handshake message header. */ + if (!tls_buffer_data(s->s3->handshake_fragment, &cbs)) + return -1; + if (!CBS_get_u8(&cbs, &hs_msg_type)) + return -1; + if (!CBS_get_u24(&cbs, &hs_msg_length)) + return -1; + + if (hs_msg_type == SSL3_MT_HELLO_REQUEST) { + /* + * Incoming HelloRequest messages should only be received by a + * client. A server may send these at any time - a client should + * ignore the message if received in the middle of a handshake. + * See RFC 5246 sections 7.4 and 7.4.1.1. + */ + if (s->server) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if (hs_msg_length != 0) { + SSLerror(s, SSL_R_BAD_HELLO_REQUEST); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return -1; + } + + if (!tls_buffer_data(s->s3->handshake_fragment, &cbs)) + return -1; + ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, &cbs); + + tls_buffer_free(s->s3->handshake_fragment); + s->s3->handshake_fragment = NULL; + + /* + * It should be impossible to hit this, but keep the safety + * harness for now... + */ + if (s->session == NULL || s->session->cipher == NULL) + return 1; + + /* + * Ignore this message if we're currently handshaking, + * renegotiation is already pending or renegotiation is disabled + * via flags. + */ + if (!SSL_is_init_finished(s) || s->s3->renegotiate || + (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) + return 1; + + if (!ssl3_renegotiate(s)) + return 1; + if (!ssl3_renegotiate_check(s)) + return 1; + + } else if (hs_msg_type == SSL3_MT_CLIENT_HELLO) { + /* + * Incoming ClientHello messages should only be received by a + * server. A client may send these in response to server + * initiated renegotiation (HelloRequest) or in order to + * initiate renegotiation by the client. See RFC 5246 section + * 7.4.1.2. + */ + if (!s->server) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * A client should not be sending a ClientHello unless we're not + * currently handshaking. + */ + if (!SSL_is_init_finished(s)) { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_NO_RENEGOTIATION); + return -1; + } + + if (s->session == NULL || s->session->cipher == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* Client requested renegotiation but it is not permitted. */ + if (!s->s3->send_connection_binding || + (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) { + ssl3_send_alert(s, SSL3_AL_WARNING, + SSL_AD_NO_RENEGOTIATION); + return 1; + } + + s->s3->hs.state = SSL_ST_ACCEPT; + s->renegotiate = 1; + s->new_session = 1; + + } else { + SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if ((ret = s->handshake_func(s)) < 0) + return ret; + if (ret == 0) { + SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { + ssl_force_want_read(s); + return -1; + } + } + + /* + * We either finished a handshake or ignored the request, now try again + * to obtain the (application) data we were asked for. + */ + return 1; +} + +/* Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int +ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int rrcount = 0; + ssize_t ssret; + int ret; + + if (s->s3->rbuf.buf == NULL) { + if (!ssl3_setup_read_buffer(s)) + return -1; + } + + if (s->s3->rcontent == NULL) { + if ((s->s3->rcontent = tls_content_new()) == NULL) + return -1; + } + + if (len < 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (type != 0 && type != SSL3_RT_APPLICATION_DATA && + type != SSL3_RT_HANDSHAKE) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + if (peek && type != SSL3_RT_APPLICATION_DATA) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (type == SSL3_RT_HANDSHAKE && + s->s3->handshake_fragment != NULL && + tls_buffer_remaining(s->s3->handshake_fragment) > 0) { + ssize_t ssn; + + if ((ssn = tls_buffer_read(s->s3->handshake_fragment, buf, + len)) <= 0) + return -1; + + if (tls_buffer_remaining(s->s3->handshake_fragment) == 0) { + tls_buffer_free(s->s3->handshake_fragment); + s->s3->handshake_fragment = NULL; + } + + return (int)ssn; + } + + if (SSL_in_init(s) && !s->in_handshake) { + if ((ret = s->handshake_func(s)) < 0) + return ret; + if (ret == 0) { + SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + start: + /* + * Do not process more than three consecutive records, otherwise the + * peer can cause us to loop indefinitely. Instead, return with an + * SSL_ERROR_WANT_READ so the caller can choose when to handle further + * processing. In the future, the total number of non-handshake and + * non-application data records per connection should probably also be + * limited... + */ + if (rrcount++ >= 3) { + ssl_force_want_read(s); + return -1; + } + + s->rwstate = SSL_NOTHING; + + if (tls_content_remaining(s->s3->rcontent) == 0) { + if ((ret = ssl3_get_record(s)) <= 0) + return ret; + } + + /* We now have a packet which can be read and processed. */ + + if (s->s3->change_cipher_spec && + tls_content_type(s->s3->rcontent) != SSL3_RT_HANDSHAKE) { + SSLerror(s, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * If the other end has shut down, throw anything we read away (even in + * 'peek' mode). + */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + return 0; + } + + /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ + if (tls_content_type(s->s3->rcontent) == type) { + /* + * Make sure that we are not getting application data when we + * are doing a handshake for the first time. + */ + if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && + !tls12_record_layer_read_protected(s->rl)) { + SSLerror(s, SSL_R_APP_DATA_IN_HANDSHAKE); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + if (len <= 0) + return len; + + if (peek) { + ssret = tls_content_peek(s->s3->rcontent, buf, len); + } else { + ssret = tls_content_read(s->s3->rcontent, buf, len); + } + if (ssret < INT_MIN || ssret > INT_MAX) + return -1; + if (ssret < 0) + return (int)ssret; + + if (tls_content_remaining(s->s3->rcontent) == 0) { + s->rstate = SSL_ST_READ_HEADER; + + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + s->s3->rbuf.left == 0) + ssl3_release_read_buffer(s); + } + + return ssret; + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_ALERT) { + if ((ret = ssl3_read_alert(s)) <= 0) + return ret; + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + tls_content_clear(s->s3->rcontent); + s->s3->rrec.length = 0; + return 0; + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_APPLICATION_DATA) { + /* + * At this point, we were expecting handshake data, but have + * application data. If the library was running inside + * ssl3_read() (i.e. in_read_app_data is set) and it makes + * sense to read application data at this point (session + * renegotiation not yet started), we will indulge it. + */ + if (s->s3->in_read_app_data != 0 && + s->s3->total_renegotiations != 0 && + (((s->s3->hs.state & SSL_ST_CONNECT) && + (s->s3->hs.state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->s3->hs.state <= SSL3_ST_CR_SRVR_HELLO_A)) || ( + (s->s3->hs.state & SSL_ST_ACCEPT) && + (s->s3->hs.state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->s3->hs.state >= SSL3_ST_SR_CLNT_HELLO_A)))) { + s->s3->in_read_app_data = 2; + return -1; + } else { + SSLerror(s, SSL_R_UNEXPECTED_RECORD); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_CHANGE_CIPHER_SPEC) { + if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) + return ret; + goto start; + } + + if (tls_content_type(s->s3->rcontent) == SSL3_RT_HANDSHAKE) { + if ((ret = ssl3_read_handshake_unexpected(s)) <= 0) + return ret; + goto start; + } + + /* + * Unknown record type - TLSv1.2 sends an unexpected message alert while + * earlier versions silently ignore the record. + */ + if (ssl_effective_tls_version(s) <= TLS1_1_VERSION) { + tls_content_clear(s->s3->rcontent); + goto start; + } + SSLerror(s, SSL_R_UNEXPECTED_RECORD); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; +} + +int +ssl3_do_change_cipher_spec(SSL *s) +{ + if (s->s3->hs.tls12.key_block == NULL) { + if (s->session == NULL || s->session->master_key_length == 0) { + /* might happen if dtls1_read_bytes() calls this */ + SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); + return (0); + } + + s->session->cipher = s->s3->hs.cipher; + if (!tls1_setup_key_block(s)) + return (0); + } + + if (!tls1_change_read_cipher_state(s)) + return (0); + + /* + * We have to record the message digest at this point so we can get it + * before we read the finished message. + */ + if (!tls12_derive_peer_finished(s)) + return (0); + + return (1); +} + +static int +ssl3_write_alert(SSL *s) +{ + if (SSL_is_dtls(s)) + return do_dtls1_write(s, SSL3_RT_ALERT, s->s3->send_alert, + sizeof(s->s3->send_alert)); + + return do_ssl3_write(s, SSL3_RT_ALERT, s->s3->send_alert, + sizeof(s->s3->send_alert)); +} + +int +ssl3_send_alert(SSL *s, int level, int desc) +{ + /* If alert is fatal, remove session from cache. */ + if (level == SSL3_AL_FATAL) + SSL_CTX_remove_session(s->ctx, s->session); + + s->s3->alert_dispatch = 1; + s->s3->send_alert[0] = level; + s->s3->send_alert[1] = desc; + + /* + * If data is still being written out, the alert will be dispatched at + * some point in the future. + */ + if (s->s3->wbuf.left != 0) + return -1; + + return ssl3_dispatch_alert(s); +} + +int +ssl3_dispatch_alert(SSL *s) +{ + int ret; + + s->s3->alert_dispatch = 0; + if ((ret = ssl3_write_alert(s)) <= 0) { + s->s3->alert_dispatch = 1; + return ret; + } + + /* + * Alert sent to BIO. If it is important, flush it now. + * If the message does not get sent due to non-blocking IO, + * we will not worry too much. + */ + if (s->s3->send_alert[0] == SSL3_AL_FATAL) + (void)BIO_flush(s->wbio); + + ssl_msg_callback(s, 1, SSL3_RT_ALERT, s->s3->send_alert, 2); + + ssl_info_callback(s, SSL_CB_WRITE_ALERT, + (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]); + + return ret; +} diff --git a/Libraries/libressl/ssl/ssl_rsa.c b/Libraries/libressl/ssl/ssl_rsa.c new file mode 100644 index 000000000..68137bc5f --- /dev/null +++ b/Libraries/libressl/ssl/ssl_rsa.c @@ -0,0 +1,769 @@ +/* $OpenBSD: ssl_rsa.c,v 1.50 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include + +#include "ssl_local.h" + +static int ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl, + pem_password_cb **passwd_cb, void **passwd_arg); +static int ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x509); +static int ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey); +static int ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in); +static int ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, + const char *file); + +int +SSL_use_certificate(SSL *ssl, X509 *x) +{ + if (x == NULL) { + SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + return ssl_set_cert(NULL, ssl, x); +} +LSSL_ALIAS(SSL_use_certificate); + +int +SSL_use_certificate_file(SSL *ssl, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerror(ssl, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerror(ssl, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, + ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerror(ssl, j); + goto end; + } + + ret = SSL_use_certificate(ssl, x); + end: + X509_free(x); + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_use_certificate_file); + +int +SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerror(ssl, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_certificate(ssl, x); + X509_free(x); + return (ret); +} +LSSL_ALIAS(SSL_use_certificate_ASN1); + +int +SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) +{ + EVP_PKEY *pkey; + int ret; + + if (rsa == NULL) { + SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerror(ssl, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + EVP_PKEY_assign_RSA(pkey, rsa); + + ret = ssl_set_pkey(NULL, ssl, pkey); + EVP_PKEY_free(pkey); + return (ret); +} +LSSL_ALIAS(SSL_use_RSAPrivateKey); + +static int +ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey) +{ + SSL_CERT *c; + int i; + + i = ssl_cert_type(pkey); + if (i < 0) { + SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return (0); + } + + if ((c = ssl_get0_cert(ctx, ssl)) == NULL) + return (0); + + if (c->pkeys[i].x509 != NULL) { + EVP_PKEY *pktmp; + + if ((pktmp = X509_get0_pubkey(c->pkeys[i].x509)) == NULL) + return 0; + + /* + * Callers of EVP_PKEY_copy_parameters() can't distinguish + * errors from the absence of a param_copy() method. So + * pretend it can never fail. + */ + EVP_PKEY_copy_parameters(pktmp, pkey); + + ERR_clear_error(); + + /* + * Don't check the public/private key, this is mostly + * for smart cards. + */ + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA || + !(RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK)) { + if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { + X509_free(c->pkeys[i].x509); + c->pkeys[i].x509 = NULL; + return 0; + } + } + } + + EVP_PKEY_free(c->pkeys[i].privatekey); + EVP_PKEY_up_ref(pkey); + c->pkeys[i].privatekey = pkey; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return 1; +} + +int +SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerror(ssl, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerror(ssl, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerror(ssl, j); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + end: + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_use_RSAPrivateKey_file); + +int +SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) +{ + int ret; + RSA *rsa; + + if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) { + SSLerror(ssl, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + return (ret); +} +LSSL_ALIAS(SSL_use_RSAPrivateKey_ASN1); + +int +SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) +{ + int ret; + + if (pkey == NULL) { + SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + ret = ssl_set_pkey(NULL, ssl, pkey); + return (ret); +} +LSSL_ALIAS(SSL_use_PrivateKey); + +int +SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerror(ssl, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerror(ssl, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerror(ssl, j); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + end: + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_use_PrivateKey_file); + +int +SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) +{ + int ret; + EVP_PKEY *pkey; + + if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) { + SSLerror(ssl, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + return (ret); +} +LSSL_ALIAS(SSL_use_PrivateKey_ASN1); + +int +SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + if (x == NULL) { + SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + return ssl_set_cert(ctx, NULL, x); +} +LSSL_ALIAS(SSL_CTX_use_certificate); + +static int +ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl, + pem_password_cb **passwd_cb, void **passwd_arg) +{ + if (ssl != NULL) + ctx = ssl->ctx; + + *passwd_cb = ctx->default_passwd_callback; + *passwd_arg = ctx->default_passwd_callback_userdata; + + return 1; +} + +static int +ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x) +{ + SSL_CERT *c; + EVP_PKEY *pkey; + int ssl_err; + int i; + + if (!ssl_security_cert(ctx, ssl, x, 1, &ssl_err)) { + SSLerrorx(ssl_err); + return (0); + } + + if ((c = ssl_get0_cert(ctx, ssl)) == NULL) + return (0); + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + SSLerrorx(SSL_R_X509_LIB); + return (0); + } + + i = ssl_cert_type(pkey); + if (i < 0) { + SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE); + EVP_PKEY_free(pkey); + return (0); + } + + if (c->pkeys[i].privatekey != NULL) { + EVP_PKEY *priv_key = c->pkeys[i].privatekey; + + EVP_PKEY_copy_parameters(pkey, priv_key); + ERR_clear_error(); + + /* + * Don't check the public/private key, this is mostly + * for smart cards. + */ + if (EVP_PKEY_id(priv_key) != EVP_PKEY_RSA || + !(RSA_flags(EVP_PKEY_get0_RSA(priv_key)) & RSA_METHOD_FLAG_NO_CHECK)) { + if (!X509_check_private_key(x, priv_key)) { + /* + * don't fail for a cert/key mismatch, just free + * current private key (when switching to a + * different cert & key, first this function + * should be used, then ssl_set_pkey. + */ + EVP_PKEY_free(c->pkeys[i].privatekey); + c->pkeys[i].privatekey = NULL; + ERR_clear_error(); + } + } + } + + EVP_PKEY_free(pkey); + + X509_free(c->pkeys[i].x509); + X509_up_ref(x); + c->pkeys[i].x509 = x; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +int +SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerrorx(ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerrorx(ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerrorx(SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerrorx(j); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + end: + X509_free(x); + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_certificate_file); + +int +SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerrorx(ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_certificate(ctx, x); + X509_free(x); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_certificate_ASN1); + +int +SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) +{ + int ret; + EVP_PKEY *pkey; + + if (rsa == NULL) { + SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerrorx(ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + EVP_PKEY_assign_RSA(pkey, rsa); + + ret = ssl_set_pkey(ctx, NULL, pkey); + EVP_PKEY_free(pkey); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_RSAPrivateKey); + +int +SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerrorx(ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerrorx(ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerrorx(SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerrorx(j); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + end: + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_RSAPrivateKey_file); + +int +SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) +{ + int ret; + RSA *rsa; + + if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) { + SSLerrorx(ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_RSAPrivateKey_ASN1); + +int +SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + if (pkey == NULL) { + SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + return ssl_set_pkey(ctx, NULL, pkey); +} +LSSL_ALIAS(SSL_CTX_use_PrivateKey); + +int +SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerrorx(ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerrorx(ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerrorx(SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerrorx(j); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + end: + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_PrivateKey_file); + +int +SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, + long len) +{ + int ret; + EVP_PKEY *pkey; + + if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) { + SSLerrorx(ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_PrivateKey_ASN1); + + +/* + * Read a bio that contains our certificate in "PEM" format, + * possibly followed by a sequence of CA certificates that should be + * sent to the peer in the Certificate message. + */ +static int +ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in) +{ + pem_password_cb *passwd_cb; + void *passwd_arg; + X509 *ca, *x = NULL; + unsigned long err; + int ret = 0; + + if (!ssl_get_password_cb_and_arg(ctx, ssl, &passwd_cb, &passwd_arg)) + goto err; + + if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) == + NULL) { + SSLerrorx(ERR_R_PEM_LIB); + goto err; + } + + if (!ssl_set_cert(ctx, ssl, x)) + goto err; + + if (!ssl_cert_set0_chain(ctx, ssl, NULL)) + goto err; + + /* Process any additional CA certificates. */ + while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) != + NULL) { + if (!ssl_cert_add0_chain_cert(ctx, ssl, ca)) { + X509_free(ca); + goto err; + } + } + + /* When the while loop ends, it's usually just EOF. */ + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && + ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + ret = 1; + } + + err: + X509_free(x); + + return (ret); +} + +int +ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) +{ + BIO *in; + int ret = 0; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerrorx(ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerrorx(ERR_R_SYS_LIB); + goto end; + } + + ret = ssl_use_certificate_chain_bio(ctx, ssl, in); + + end: + BIO_free(in); + return (ret); +} + +int +SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) +{ + return ssl_use_certificate_chain_file(ctx, NULL, file); +} +LSSL_ALIAS(SSL_CTX_use_certificate_chain_file); + +int +SSL_use_certificate_chain_file(SSL *ssl, const char *file) +{ + return ssl_use_certificate_chain_file(NULL, ssl, file); +} +LSSL_ALIAS(SSL_use_certificate_chain_file); + +int +SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len) +{ + BIO *in; + int ret = 0; + + in = BIO_new_mem_buf(buf, len); + if (in == NULL) { + SSLerrorx(ERR_R_BUF_LIB); + goto end; + } + + ret = ssl_use_certificate_chain_bio(ctx, NULL, in); + + end: + BIO_free(in); + return (ret); +} +LSSL_ALIAS(SSL_CTX_use_certificate_chain_mem); diff --git a/Libraries/libressl/ssl/ssl_seclevel.c b/Libraries/libressl/ssl/ssl_seclevel.c new file mode 100644 index 000000000..1869c8108 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_seclevel.c @@ -0,0 +1,473 @@ +/* $OpenBSD: ssl_seclevel.c,v 1.27 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2020-2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bytestring.h" +#include "ssl_local.h" + +static int +ssl_security_normalize_level(const SSL_CTX *ctx, const SSL *ssl, int *out_level) +{ + int security_level; + + if (ctx != NULL) + security_level = SSL_CTX_get_security_level(ctx); + else + security_level = SSL_get_security_level(ssl); + + if (security_level < 0) + security_level = 0; + if (security_level > 5) + security_level = 5; + + *out_level = security_level; + + return 1; +} + +static int +ssl_security_level_to_minimum_bits(int security_level, int *out_minimum_bits) +{ + if (security_level < 0) + return 0; + + if (security_level == 0) + *out_minimum_bits = 0; + else if (security_level == 1) + *out_minimum_bits = 80; + else if (security_level == 2) + *out_minimum_bits = 112; + else if (security_level == 3) + *out_minimum_bits = 128; + else if (security_level == 4) + *out_minimum_bits = 192; + else if (security_level >= 5) + *out_minimum_bits = 256; + + return 1; +} + +static int +ssl_security_level_and_minimum_bits(const SSL_CTX *ctx, const SSL *ssl, + int *out_level, int *out_minimum_bits) +{ + int security_level = 0, minimum_bits = 0; + + if (!ssl_security_normalize_level(ctx, ssl, &security_level)) + return 0; + if (!ssl_security_level_to_minimum_bits(security_level, &minimum_bits)) + return 0; + + if (out_level != NULL) + *out_level = security_level; + if (out_minimum_bits != NULL) + *out_minimum_bits = minimum_bits; + + return 1; +} + +static int +ssl_security_secop_cipher(const SSL_CTX *ctx, const SSL *ssl, int bits, + void *arg) +{ + const SSL_CIPHER *cipher = arg; + int security_level, minimum_bits; + + if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, + &minimum_bits)) + return 0; + + if (security_level <= 0) + return 1; + + if (bits < minimum_bits) + return 0; + + /* No unauthenticated ciphersuites. */ + if (cipher->algorithm_auth & SSL_aNULL) + return 0; + + if (cipher->algorithm_mac & SSL_MD5) + return 0; + + if (security_level <= 1) + return 1; + + if (cipher->algorithm_enc & SSL_RC4) + return 0; + + if (security_level <= 2) + return 1; + + /* Security level >= 3 requires a cipher with forward secrecy. */ + if ((cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) == 0 && + cipher->algorithm_ssl != SSL_TLSV1_3) + return 0; + + if (security_level <= 3) + return 1; + + if (cipher->algorithm_mac & SSL_SHA1) + return 0; + + return 1; +} + +static int +ssl_security_secop_version(const SSL_CTX *ctx, const SSL *ssl, int version) +{ + int min_version = TLS1_2_VERSION; + int security_level; + + if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL)) + return 0; + + if (security_level < 4) + min_version = TLS1_1_VERSION; + if (security_level < 3) + min_version = TLS1_VERSION; + + return ssl_tls_version(version) >= min_version; +} + +static int +ssl_security_secop_compression(const SSL_CTX *ctx, const SSL *ssl) +{ + return 0; +} + +static int +ssl_security_secop_tickets(const SSL_CTX *ctx, const SSL *ssl) +{ + int security_level; + + if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL)) + return 0; + + return security_level < 3; +} + +static int +ssl_security_secop_tmp_dh(const SSL_CTX *ctx, const SSL *ssl, int bits) +{ + int security_level, minimum_bits; + + if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, + &minimum_bits)) + return 0; + + /* Disallow DHE keys weaker than 1024 bits even at security level 0. */ + if (security_level <= 0 && bits < 80) + return 0; + + return bits >= minimum_bits; +} + +static int +ssl_security_secop_default(const SSL_CTX *ctx, const SSL *ssl, int bits) +{ + int minimum_bits; + + if (!ssl_security_level_and_minimum_bits(ctx, ssl, NULL, &minimum_bits)) + return 0; + + return bits >= minimum_bits; +} + +int +ssl_security_default_cb(const SSL *ssl, const SSL_CTX *ctx, int secop, int bits, + int version, void *cipher, void *ex_data) +{ + switch (secop) { + case SSL_SECOP_CIPHER_SUPPORTED: + case SSL_SECOP_CIPHER_SHARED: + case SSL_SECOP_CIPHER_CHECK: + return ssl_security_secop_cipher(ctx, ssl, bits, cipher); + case SSL_SECOP_VERSION: + return ssl_security_secop_version(ctx, ssl, version); + case SSL_SECOP_COMPRESSION: + return ssl_security_secop_compression(ctx, ssl); + case SSL_SECOP_TICKET: + return ssl_security_secop_tickets(ctx, ssl); + case SSL_SECOP_TMP_DH: + return ssl_security_secop_tmp_dh(ctx, ssl, bits); + default: + return ssl_security_secop_default(ctx, ssl, bits); + } +} + +static int +ssl_ctx_security(const SSL_CTX *ctx, int secop, int bits, int nid, void *other) +{ + return ctx->cert->security_cb(NULL, ctx, secop, bits, nid, + other, ctx->cert->security_ex_data); +} + +static int +ssl_security(const SSL *ssl, int secop, int bits, int nid, void *other) +{ + return ssl->cert->security_cb(ssl, NULL, secop, bits, nid, other, + ssl->cert->security_ex_data); +} + +int +ssl_security_sigalg_check(const SSL *ssl, const EVP_PKEY *pkey) +{ + int bits; + + bits = EVP_PKEY_security_bits(pkey); + + return ssl_security(ssl, SSL_SECOP_SIGALG_CHECK, bits, 0, NULL); +} + +int +ssl_security_tickets(const SSL *ssl) +{ + return ssl_security(ssl, SSL_SECOP_TICKET, 0, 0, NULL); +} + +int +ssl_security_version(const SSL *ssl, int version) +{ + return ssl_security(ssl, SSL_SECOP_VERSION, 0, version, NULL); +} + +static int +ssl_security_cipher(const SSL *ssl, SSL_CIPHER *cipher, int secop) +{ + return ssl_security(ssl, secop, cipher->strength_bits, 0, cipher); +} + +int +ssl_security_cipher_check(const SSL *ssl, SSL_CIPHER *cipher) +{ + return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_CHECK); +} + +int +ssl_security_shared_cipher(const SSL *ssl, SSL_CIPHER *cipher) +{ + return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SHARED); +} + +int +ssl_security_supported_cipher(const SSL *ssl, SSL_CIPHER *cipher) +{ + return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SUPPORTED); +} + +int +ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh) +{ + int bits; + + bits = DH_security_bits(dh); + + return ssl_ctx_security(ctx, SSL_SECOP_TMP_DH, bits, 0, dh); +} + +int +ssl_security_dh(const SSL *ssl, DH *dh) +{ + int bits; + + bits = DH_security_bits(dh); + + return ssl_security(ssl, SSL_SECOP_TMP_DH, bits, 0, dh); +} + +static int +ssl_cert_pubkey_security_bits(const X509 *x509) +{ + EVP_PKEY *pkey; + + if ((pkey = X509_get0_pubkey(x509)) == NULL) + return -1; + + /* + * XXX: DSA_security_bits() returns -1 on keys without parameters and + * makes the default security callback fail. + */ + + return EVP_PKEY_security_bits(pkey); +} + +static int +ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop) +{ + int security_bits; + + security_bits = ssl_cert_pubkey_security_bits(x509); + + if (ssl != NULL) + return ssl_security(ssl, secop, security_bits, 0, x509); + + return ssl_ctx_security(ctx, secop, security_bits, 0, x509); +} + +static int +ssl_cert_signature_md_nid(X509 *x509) +{ + int md_nid, signature_nid; + + if ((signature_nid = X509_get_signature_nid(x509)) == NID_undef) + return NID_undef; + + if (!OBJ_find_sigid_algs(signature_nid, &md_nid, NULL)) + return NID_undef; + + return md_nid; +} + +static int +ssl_cert_md_nid_security_bits(int md_nid) +{ + const EVP_MD *md; + + if (md_nid == NID_undef) + return -1; + + if ((md = EVP_get_digestbynid(md_nid)) == NULL) + return -1; + + /* Assume 4 bits of collision resistance for each hash octet. */ + return EVP_MD_size(md) * 4; +} + +static int +ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop) +{ + int md_nid, security_bits; + + /* Don't check signature if self signed. */ + if ((X509_get_extension_flags(x509) & EXFLAG_SS) != 0) + return 1; + + md_nid = ssl_cert_signature_md_nid(x509); + security_bits = ssl_cert_md_nid_security_bits(md_nid); + + if (ssl != NULL) + return ssl_security(ssl, secop, security_bits, md_nid, x509); + + return ssl_ctx_security(ctx, secop, security_bits, md_nid, x509); +} + +int +ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, + int is_ee, int *out_error) +{ + int key_error, operation; + + *out_error = 0; + + if (is_ee) { + operation = SSL_SECOP_EE_KEY; + key_error = SSL_R_EE_KEY_TOO_SMALL; + } else { + operation = SSL_SECOP_CA_KEY; + key_error = SSL_R_CA_KEY_TOO_SMALL; + } + + if (!ssl_security_cert_key(ctx, ssl, x509, operation)) { + *out_error = key_error; + return 0; + } + + if (!ssl_security_cert_sig(ctx, ssl, x509, SSL_SECOP_CA_MD)) { + *out_error = SSL_R_CA_MD_TOO_WEAK; + return 0; + } + + return 1; +} + +/* + * Check security of a chain. If |sk| includes the end entity certificate + * then |x509| must be NULL. + */ +int +ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, X509 *x509, + int *out_error) +{ + int start_idx = 0; + int is_ee; + int i; + + if (x509 == NULL) { + x509 = sk_X509_value(sk, 0); + start_idx = 1; + } + + is_ee = 1; + if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error)) + return 0; + + is_ee = 0; + for (i = start_idx; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + + if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error)) + return 0; + } + + return 1; +} + +static int +ssl_security_group(const SSL *ssl, uint16_t group_id, int secop) +{ + CBB cbb; + int bits, nid; + uint8_t group[2]; + + if (!tls1_ec_group_id2bits(group_id, &bits)) + return 0; + if (!tls1_ec_group_id2nid(group_id, &nid)) + return 0; + + if (!CBB_init_fixed(&cbb, group, sizeof(group))) + return 0; + if (!CBB_add_u16(&cbb, group_id)) + return 0; + if (!CBB_finish(&cbb, NULL, NULL)) + return 0; + + return ssl_security(ssl, secop, bits, nid, group); +} + +int +ssl_security_shared_group(const SSL *ssl, uint16_t group_id) +{ + return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SHARED); +} + +int +ssl_security_supported_group(const SSL *ssl, uint16_t group_id) +{ + return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SUPPORTED); +} diff --git a/Libraries/libressl/ssl/ssl_sess.c b/Libraries/libressl/ssl/ssl_sess.c new file mode 100644 index 000000000..aa6b08eae --- /dev/null +++ b/Libraries/libressl/ssl/ssl_sess.c @@ -0,0 +1,1388 @@ +/* $OpenBSD: ssl_sess.c,v 1.122 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "ssl_local.h" + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); + +/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ +SSL_SESSION * +SSL_get_session(const SSL *ssl) +{ + return (ssl->session); +} +LSSL_ALIAS(SSL_get_session); + +/* variant of SSL_get_session: caller really gets something */ +SSL_SESSION * +SSL_get1_session(SSL *ssl) +{ + SSL_SESSION *sess; + + /* + * Need to lock this all up rather than just use CRYPTO_add so that + * somebody doesn't free ssl->session between when we check it's + * non-null and when we up the reference count. + */ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); + sess = ssl->session; + if (sess) + sess->references++; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); + + return (sess); +} +LSSL_ALIAS(SSL_get1_session); + +int +SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, + argl, argp, new_func, dup_func, free_func); +} +LSSL_ALIAS(SSL_SESSION_get_ex_new_index); + +int +SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} +LSSL_ALIAS(SSL_SESSION_set_ex_data); + +void * +SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} +LSSL_ALIAS(SSL_SESSION_get_ex_data); + +uint32_t +SSL_SESSION_get_max_early_data(const SSL_SESSION *s) +{ + return 0; +} +LSSL_ALIAS(SSL_SESSION_get_max_early_data); + +int +SSL_SESSION_set_max_early_data(SSL_SESSION *s, uint32_t max_early_data) +{ + return 1; +} +LSSL_ALIAS(SSL_SESSION_set_max_early_data); + +SSL_SESSION * +SSL_SESSION_new(void) +{ + SSL_SESSION *ss; + + if (!OPENSSL_init_ssl(0, NULL)) { + SSLerrorx(SSL_R_LIBRARY_BUG); + return(NULL); + } + + if ((ss = calloc(1, sizeof(*ss))) == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ + ss->references = 1; + ss->timeout = 60 * 5 + 4; /* 5 minutes 4 seconds timeout by default */ + ss->time = time(NULL); + ss->prev = NULL; + ss->next = NULL; + ss->tlsext_hostname = NULL; + + ss->peer_cert_type = -1; + + ss->tlsext_ecpointformatlist_length = 0; + ss->tlsext_ecpointformatlist = NULL; + ss->tlsext_supportedgroups_length = 0; + ss->tlsext_supportedgroups = NULL; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); + + return (ss); +} +LSSL_ALIAS(SSL_SESSION_new); + +SSL_SESSION * +ssl_session_dup(SSL_SESSION *sess, int include_ticket) +{ + SSL_SESSION *copy; + CBS cbs; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + + copy->ssl_version = sess->ssl_version; + + CBS_init(&cbs, sess->master_key, sess->master_key_length); + if (!CBS_write_bytes(&cbs, copy->master_key, sizeof(copy->master_key), + ©->master_key_length)) + goto err; + + CBS_init(&cbs, sess->session_id, sess->session_id_length); + if (!CBS_write_bytes(&cbs, copy->session_id, sizeof(copy->session_id), + ©->session_id_length)) + goto err; + + CBS_init(&cbs, sess->sid_ctx, sess->sid_ctx_length); + if (!CBS_write_bytes(&cbs, copy->sid_ctx, sizeof(copy->sid_ctx), + ©->sid_ctx_length)) + goto err; + + if (sess->peer_cert != NULL) { + if (!X509_up_ref(sess->peer_cert)) + goto err; + copy->peer_cert = sess->peer_cert; + } + copy->peer_cert_type = sess->peer_cert_type; + + copy->verify_result = sess->verify_result; + + copy->timeout = sess->timeout; + copy->time = sess->time; + copy->references = 1; + + copy->cipher = sess->cipher; + copy->cipher_id = sess->cipher_id; + + if (sess->ciphers != NULL) { + if ((copy->ciphers = sk_SSL_CIPHER_dup(sess->ciphers)) == NULL) + goto err; + } + + if (sess->tlsext_hostname != NULL) { + copy->tlsext_hostname = strdup(sess->tlsext_hostname); + if (copy->tlsext_hostname == NULL) + goto err; + } + + if (include_ticket) { + CBS_init(&cbs, sess->tlsext_tick, sess->tlsext_ticklen); + if (!CBS_stow(&cbs, ©->tlsext_tick, ©->tlsext_ticklen)) + goto err; + copy->tlsext_tick_lifetime_hint = + sess->tlsext_tick_lifetime_hint; + + /* + * XXX - copy sess->resumption_master_secret and all other + * TLSv1.3 info here. + */ + } + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, copy, + ©->ex_data)) + goto err; + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ©->ex_data, + &sess->ex_data)) + goto err; + + /* Omit prev/next: the new session gets its own slot in the cache. */ + + copy->not_resumable = sess->not_resumable; + + CBS_init(&cbs, sess->tlsext_ecpointformatlist, + sess->tlsext_ecpointformatlist_length); + if (!CBS_stow(&cbs, ©->tlsext_ecpointformatlist, + ©->tlsext_ecpointformatlist_length)) + goto err; + + if (sess->tlsext_supportedgroups != NULL) { + if ((copy->tlsext_supportedgroups = calloc(sizeof(uint16_t), + sess->tlsext_supportedgroups_length)) == NULL) + goto err; + memcpy(copy->tlsext_supportedgroups, + sess->tlsext_supportedgroups, + sizeof(uint16_t) * sess->tlsext_supportedgroups_length); + copy->tlsext_supportedgroups_length = + sess->tlsext_supportedgroups_length; + } + + return copy; + + err: + SSL_SESSION_free(copy); + + return NULL; +} + +const unsigned char * +SSL_SESSION_get_id(const SSL_SESSION *ss, unsigned int *len) +{ + if (len != NULL) + *len = (unsigned int)ss->session_id_length; + return ss->session_id; +} +LSSL_ALIAS(SSL_SESSION_get_id); + +const unsigned char * +SSL_SESSION_get0_id_context(const SSL_SESSION *ss, unsigned int *len) +{ + if (len != NULL) + *len = (unsigned int)ss->sid_ctx_length; + return ss->sid_ctx; +} +LSSL_ALIAS(SSL_SESSION_get0_id_context); + +unsigned int +SSL_SESSION_get_compress_id(const SSL_SESSION *ss) +{ + return 0; +} +LSSL_ALIAS(SSL_SESSION_get_compress_id); + +unsigned long +SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) +{ + return s->tlsext_tick_lifetime_hint; +} +LSSL_ALIAS(SSL_SESSION_get_ticket_lifetime_hint); + +int +SSL_SESSION_has_ticket(const SSL_SESSION *s) +{ + return (s->tlsext_ticklen > 0) ? 1 : 0; +} +LSSL_ALIAS(SSL_SESSION_has_ticket); + +/* + * SSLv3/TLSv1 has 32 bytes (256 bits) of session ID space. As such, filling + * the ID with random gunk repeatedly until we have no conflict is going to + * complete in one iteration pretty much "most" of the time (btw: + * understatement). So, if it takes us 10 iterations and we still can't avoid + * a conflict - well that's a reasonable point to call it quits. Either the + * arc4random code is broken or someone is trying to open roughly very close to + * 2^128 (or 2^256) SSL sessions to our server. How you might store that many + * sessions is perhaps a more interesting question... + */ + +#define MAX_SESS_ID_ATTEMPTS 10 + +static int +def_generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len) +{ + unsigned int retry = 0; + + do { + arc4random_buf(id, *id_len); + } while (SSL_has_matching_session_id(ssl, id, *id_len) && + (++retry < MAX_SESS_ID_ATTEMPTS)); + + if (retry < MAX_SESS_ID_ATTEMPTS) + return 1; + + /* else - woops a session_id match */ + /* XXX We should also check the external cache -- + * but the probability of a collision is negligible, and + * we could not prevent the concurrent creation of sessions + * with identical IDs since we currently don't have means + * to atomically check whether a session ID already exists + * and make a reservation for it if it does not + * (this problem applies to the internal cache as well). + */ + return 0; +} + +int +ssl_get_new_session(SSL *s, int session) +{ + unsigned int tmp; + SSL_SESSION *ss = NULL; + GEN_SESSION_CB cb = def_generate_session_id; + + /* This gets used by clients and servers. */ + + if ((ss = SSL_SESSION_new()) == NULL) + return (0); + + /* If the context has a default timeout, use it */ + if (s->session_ctx->session_timeout == 0) + ss->timeout = SSL_get_default_timeout(s); + else + ss->timeout = s->session_ctx->session_timeout; + + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + if (session) { + switch (s->version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + case DTLS1_VERSION: + case DTLS1_2_VERSION: + ss->ssl_version = s->version; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + break; + default: + SSLerror(s, SSL_R_UNSUPPORTED_SSL_VERSION); + SSL_SESSION_free(ss); + return (0); + } + + /* If RFC4507 ticket use empty session ID. */ + if (s->tlsext_ticket_expected) { + ss->session_id_length = 0; + goto sess_id_done; + } + + /* Choose which callback will set the session ID. */ + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + if (s->generate_session_id) + cb = s->generate_session_id; + else if (s->session_ctx->generate_session_id) + cb = s->session_ctx->generate_session_id; + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + /* Choose a session ID. */ + tmp = ss->session_id_length; + if (!cb(s, ss->session_id, &tmp)) { + /* The callback failed */ + SSLerror(s, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); + SSL_SESSION_free(ss); + return (0); + } + + /* + * Don't allow the callback to set the session length to zero. + * nor set it higher than it was. + */ + if (tmp == 0 || tmp > ss->session_id_length) { + /* The callback set an illegal length */ + SSLerror(s, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); + SSL_SESSION_free(ss); + return (0); + } + ss->session_id_length = tmp; + + /* Finally, check for a conflict. */ + if (SSL_has_matching_session_id(s, ss->session_id, + ss->session_id_length)) { + SSLerror(s, SSL_R_SSL_SESSION_ID_CONFLICT); + SSL_SESSION_free(ss); + return (0); + } + + sess_id_done: + if (s->tlsext_hostname) { + ss->tlsext_hostname = strdup(s->tlsext_hostname); + if (ss->tlsext_hostname == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + } + } else { + ss->session_id_length = 0; + } + + if (s->sid_ctx_length > sizeof ss->sid_ctx) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + + memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); + ss->sid_ctx_length = s->sid_ctx_length; + s->session = ss; + ss->ssl_version = s->version; + ss->verify_result = X509_V_OK; + + return (1); +} + +static SSL_SESSION * +ssl_session_from_cache(SSL *s, CBS *session_id) +{ + SSL_SESSION *sess; + SSL_SESSION data; + + if ((s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) + return NULL; + + memset(&data, 0, sizeof(data)); + + data.ssl_version = s->version; + + if (!CBS_write_bytes(session_id, data.session_id, + sizeof(data.session_id), &data.session_id_length)) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + sess = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); + if (sess != NULL) + CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + if (sess == NULL) + s->session_ctx->stats.sess_miss++; + + return sess; +} + +static SSL_SESSION * +ssl_session_from_callback(SSL *s, CBS *session_id) +{ + SSL_SESSION *sess; + int copy; + + if (s->session_ctx->get_session_cb == NULL) + return NULL; + + copy = 1; + if ((sess = s->session_ctx->get_session_cb(s, + CBS_data(session_id), CBS_len(session_id), ©)) == NULL) + return NULL; + /* + * The copy handler may have set copy == 0 to indicate that the session + * structures are shared between threads and that it handles the + * reference count itself. If it didn't set copy to zero, we must + * increment the reference count. + */ + if (copy) + CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); + + s->session_ctx->stats.sess_cb_hit++; + + /* Add the externally cached session to the internal cache as well. */ + if (!(s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) { + /* + * The following should not return 1, + * otherwise, things are very strange. + */ + SSL_CTX_add_session(s->session_ctx, sess); + } + + return sess; +} + +static SSL_SESSION * +ssl_session_by_id(SSL *s, CBS *session_id) +{ + SSL_SESSION *sess; + + if (CBS_len(session_id) == 0) + return NULL; + + if ((sess = ssl_session_from_cache(s, session_id)) == NULL) + sess = ssl_session_from_callback(s, session_id); + + return sess; +} + +/* + * ssl_get_prev_session attempts to find an SSL_SESSION to be used to resume + * this connection. It is only called by servers. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * ext_block: a CBS for the ClientHello extensions block. + * alert: alert that the caller should send in case of failure. + * + * Returns: + * -1: error + * 0: a session may have been found. + * + * Side effects: + * - If a session is found then s->session is pointed at it (after freeing + * an existing session if need be) and s->verify_result is set from the + * session. + * - For both new and resumed sessions, s->tlsext_ticket_expected + * indicates whether the server should issue a new session ticket or not. + */ +int +ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, int *alert) +{ + SSL_SESSION *sess = NULL; + int alert_desc = SSL_AD_INTERNAL_ERROR, fatal = 0; + int ticket_decrypted = 0; + + /* This is used only by servers. */ + + if (CBS_len(session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) + goto err; + + /* Sets s->tlsext_ticket_expected. */ + switch (tls1_process_ticket(s, ext_block, &alert_desc, &sess)) { + case TLS1_TICKET_FATAL_ERROR: + fatal = 1; + goto err; + case TLS1_TICKET_NONE: + case TLS1_TICKET_EMPTY: + if ((sess = ssl_session_by_id(s, session_id)) == NULL) + goto err; + break; + case TLS1_TICKET_NOT_DECRYPTED: + goto err; + case TLS1_TICKET_DECRYPTED: + ticket_decrypted = 1; + + /* + * The session ID is used by some clients to detect that the + * ticket has been accepted so we copy it into sess. + */ + if (!CBS_write_bytes(session_id, sess->session_id, + sizeof(sess->session_id), &sess->session_id_length)) { + fatal = 1; + goto err; + } + break; + default: + SSLerror(s, ERR_R_INTERNAL_ERROR); + fatal = 1; + goto err; + } + + /* Now sess is non-NULL and we own one of its reference counts. */ + + if (sess->sid_ctx_length != s->sid_ctx_length || + timingsafe_memcmp(sess->sid_ctx, s->sid_ctx, + sess->sid_ctx_length) != 0) { + /* + * We have the session requested by the client, but we don't + * want to use it in this context. Treat it like a cache miss. + */ + goto err; + } + + if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { + /* + * We can't be sure if this session is being used out of + * context, which is especially important for SSL_VERIFY_PEER. + * The application should have used + * SSL[_CTX]_set_session_id_context. + * + * For this error case, we generate an error instead of treating + * the event like a cache miss (otherwise it would be easy for + * applications to effectively disable the session cache by + * accident without anyone noticing). + */ + SSLerror(s, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); + fatal = 1; + goto err; + } + + if (sess->cipher == NULL) { + sess->cipher = ssl3_get_cipher_by_id(sess->cipher_id); + if (sess->cipher == NULL) + goto err; + } + + if (sess->timeout < (time(NULL) - sess->time)) { + s->session_ctx->stats.sess_timeout++; + if (!ticket_decrypted) { + /* The session was from the cache, so remove it. */ + SSL_CTX_remove_session(s->session_ctx, sess); + } + goto err; + } + + s->session_ctx->stats.sess_hit++; + + SSL_SESSION_free(s->session); + s->session = sess; + s->verify_result = s->session->verify_result; + + return 1; + + err: + SSL_SESSION_free(sess); + if (ticket_decrypted) { + /* + * The session was from a ticket. Issue a ticket for the new + * session. + */ + s->tlsext_ticket_expected = 1; + } + if (fatal) { + *alert = alert_desc; + return -1; + } + return 0; +} + +int +SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + int ret = 0; + SSL_SESSION *s; + + /* + * Add just 1 reference count for the SSL_CTX's session cache + * even though it has two ways of access: each session is in a + * doubly linked list and an lhash. + */ + CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); + + /* + * If session c is in already in cache, we take back the increment + * later. + */ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + s = lh_SSL_SESSION_insert(ctx->sessions, c); + + /* + * s != NULL iff we already had a session with the given PID. + * In this case, s == c should hold (then we did not really modify + * ctx->sessions), or we're in trouble. + */ + if (s != NULL && s != c) { + /* We *are* in trouble ... */ + SSL_SESSION_list_remove(ctx, s); + SSL_SESSION_free(s); + /* + * ... so pretend the other session did not exist in cache + * (we cannot handle two SSL_SESSION structures with identical + * session ID in the same cache, which could happen e.g. when + * two threads concurrently obtain the same session from an + * external cache). + */ + s = NULL; + } + + /* Put at the head of the queue unless it is already in the cache */ + if (s == NULL) + SSL_SESSION_list_add(ctx, c); + + if (s != NULL) { + /* + * existing cache entry -- decrement previously incremented + * reference count because it already takes into account the + * cache. + */ + SSL_SESSION_free(s); /* s == c */ + ret = 0; + } else { + /* + * New cache entry -- remove old ones if cache has become + * too large. + */ + + ret = 1; + + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (SSL_CTX_sess_number(ctx) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session_lock(ctx, + ctx->session_cache_tail, 0)) + break; + else + ctx->stats.sess_cache_full++; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return (ret); +} +LSSL_ALIAS(SSL_CTX_add_session); + +int +SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + return remove_session_lock(ctx, c, 1); +} +LSSL_ALIAS(SSL_CTX_remove_session); + +static int +remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) +{ + SSL_SESSION *r; + int ret = 0; + + if (c == NULL || c->session_id_length == 0) + return 0; + + if (lck) + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { + ret = 1; + r = lh_SSL_SESSION_delete(ctx->sessions, c); + SSL_SESSION_list_remove(ctx, c); + } + if (lck) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + if (ret) { + r->not_resumable = 1; + if (ctx->remove_session_cb != NULL) + ctx->remove_session_cb(ctx, r); + SSL_SESSION_free(r); + } + + return ret; +} + +void +SSL_SESSION_free(SSL_SESSION *ss) +{ + int i; + + if (ss == NULL) + return; + + i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); + if (i > 0) + return; + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); + + explicit_bzero(ss->master_key, sizeof ss->master_key); + explicit_bzero(ss->session_id, sizeof ss->session_id); + + X509_free(ss->peer_cert); + + sk_SSL_CIPHER_free(ss->ciphers); + + free(ss->tlsext_hostname); + free(ss->tlsext_tick); + free(ss->tlsext_ecpointformatlist); + free(ss->tlsext_supportedgroups); + + tls13_secret_cleanup(&ss->resumption_master_secret); + + freezero(ss, sizeof(*ss)); +} +LSSL_ALIAS(SSL_SESSION_free); + +int +SSL_SESSION_up_ref(SSL_SESSION *ss) +{ + int refs = CRYPTO_add(&ss->references, 1, CRYPTO_LOCK_SSL_SESSION); + return (refs > 1) ? 1 : 0; +} +LSSL_ALIAS(SSL_SESSION_up_ref); + +int +SSL_set_session(SSL *s, SSL_SESSION *session) +{ + const SSL_METHOD *method; + + if (session == NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + + return SSL_set_ssl_method(s, s->ctx->method); + } + + if ((method = ssl_get_method(session->ssl_version)) == NULL) { + SSLerror(s, SSL_R_UNABLE_TO_FIND_SSL_METHOD); + return (0); + } + + if (!SSL_set_ssl_method(s, method)) + return (0); + + CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); + SSL_SESSION_free(s->session); + s->session = session; + s->verify_result = s->session->verify_result; + + return (1); +} +LSSL_ALIAS(SSL_set_session); + +size_t +SSL_SESSION_get_master_key(const SSL_SESSION *ss, unsigned char *out, + size_t max_out) +{ + size_t len = ss->master_key_length; + + if (out == NULL) + return len; + + if (len > max_out) + len = max_out; + + memcpy(out, ss->master_key, len); + + return len; +} +LSSL_ALIAS(SSL_SESSION_get_master_key); + +long +SSL_SESSION_set_timeout(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->timeout = t; + return (1); +} +LSSL_ALIAS(SSL_SESSION_set_timeout); + +long +SSL_SESSION_get_timeout(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->timeout); +} +LSSL_ALIAS(SSL_SESSION_get_timeout); + +/* XXX 2038 */ +long +SSL_SESSION_get_time(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->time); +} +LSSL_ALIAS(SSL_SESSION_get_time); + +/* XXX 2038 */ +long +SSL_SESSION_set_time(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->time = t; + return (t); +} +LSSL_ALIAS(SSL_SESSION_set_time); + +int +SSL_SESSION_get_protocol_version(const SSL_SESSION *s) +{ + return s->ssl_version; +} +LSSL_ALIAS(SSL_SESSION_get_protocol_version); + +const SSL_CIPHER * +SSL_SESSION_get0_cipher(const SSL_SESSION *s) +{ + return s->cipher; +} +LSSL_ALIAS(SSL_SESSION_get0_cipher); + +X509 * +SSL_SESSION_get0_peer(SSL_SESSION *s) +{ + return s->peer_cert; +} +LSSL_ALIAS(SSL_SESSION_get0_peer); + +int +SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, + unsigned int sid_len) +{ + if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { + SSLerrorx(SSL_R_SSL_SESSION_ID_TOO_LONG); + return 0; + } + s->session_id_length = sid_len; + memmove(s->session_id, sid, sid_len); + return 1; +} +LSSL_ALIAS(SSL_SESSION_set1_id); + +int +SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerrorx(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + s->sid_ctx_length = sid_ctx_len; + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} +LSSL_ALIAS(SSL_SESSION_set1_id_context); + +int +SSL_SESSION_is_resumable(const SSL_SESSION *s) +{ + return 0; +} +LSSL_ALIAS(SSL_SESSION_is_resumable); + +long +SSL_CTX_set_timeout(SSL_CTX *s, long t) +{ + long l; + + if (s == NULL) + return (0); + l = s->session_timeout; + s->session_timeout = t; + + return (l); +} +LSSL_ALIAS(SSL_CTX_set_timeout); + +long +SSL_CTX_get_timeout(const SSL_CTX *s) +{ + if (s == NULL) + return (0); + return (s->session_timeout); +} +LSSL_ALIAS(SSL_CTX_get_timeout); + +int +SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, + void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, + SSL_CIPHER **cipher, void *arg), void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_secret_cb = tls_session_secret_cb; + s->tls_session_secret_cb_arg = arg; + return (1); +} +LSSL_ALIAS(SSL_set_session_secret_cb); + +int +SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_ticket_ext_cb = cb; + s->tls_session_ticket_ext_cb_arg = arg; + return (1); +} +LSSL_ALIAS(SSL_set_session_ticket_ext_cb); + +int +SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) +{ + if (s->version >= TLS1_VERSION) { + free(s->tlsext_session_ticket); + s->tlsext_session_ticket = + malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); + if (!s->tlsext_session_ticket) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ext_data) { + s->tlsext_session_ticket->length = ext_len; + s->tlsext_session_ticket->data = + s->tlsext_session_ticket + 1; + memcpy(s->tlsext_session_ticket->data, + ext_data, ext_len); + } else { + s->tlsext_session_ticket->length = 0; + s->tlsext_session_ticket->data = NULL; + } + + return 1; + } + + return 0; +} +LSSL_ALIAS(SSL_set_session_ticket_ext); + +typedef struct timeout_param_st { + SSL_CTX *ctx; + long time; + struct lhash_st_SSL_SESSION *cache; +} TIMEOUT_PARAM; + +static void +timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) +{ + if ((p->time == 0) || (p->time > (s->time + s->timeout))) { + /* timeout */ + /* The reason we don't call SSL_CTX_remove_session() is to + * save on locking overhead */ + (void)lh_SSL_SESSION_delete(p->cache, s); + SSL_SESSION_list_remove(p->ctx, s); + s->not_resumable = 1; + if (p->ctx->remove_session_cb != NULL) + p->ctx->remove_session_cb(p->ctx, s); + SSL_SESSION_free(s); + } +} + +static void +timeout_LHASH_DOALL_ARG(void *arg1, void *arg2) +{ + SSL_SESSION *a = arg1; + TIMEOUT_PARAM *b = arg2; + + timeout_doall_arg(a, b); +} + +/* XXX 2038 */ +void +SSL_CTX_flush_sessions(SSL_CTX *s, long t) +{ + unsigned long i; + TIMEOUT_PARAM tp; + + tp.ctx = s; + tp.cache = s->sessions; + if (tp.cache == NULL) + return; + tp.time = t; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; + lh_SSL_SESSION_doall_arg(tp.cache, timeout_LHASH_DOALL_ARG, + TIMEOUT_PARAM, &tp); + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); +} +LSSL_ALIAS(SSL_CTX_flush_sessions); + +int +ssl_clear_bad_session(SSL *s) +{ + if ((s->session != NULL) && !(s->shutdown & SSL_SENT_SHUTDOWN) && + !(SSL_in_init(s) || SSL_in_before(s))) { + SSL_CTX_remove_session(s->ctx, s->session); + return (1); + } else + return (0); +} + +/* locked by SSL_CTX in the calling function */ +static void +SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) +{ + if (s->next == NULL || s->prev == NULL) + return; + + if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { + /* last element in list */ + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* only one element in list */ + ctx->session_cache_head = NULL; + ctx->session_cache_tail = NULL; + } else { + ctx->session_cache_tail = s->prev; + s->prev->next = + (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* first element in list */ + ctx->session_cache_head = s->next; + s->next->prev = + (SSL_SESSION *)&(ctx->session_cache_head); + } else { + /* middle of list */ + s->next->prev = s->prev; + s->prev->next = s->next; + } + } + s->prev = s->next = NULL; +} + +static void +SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) +{ + if (s->next != NULL && s->prev != NULL) + SSL_SESSION_list_remove(ctx, s); + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = s; + ctx->session_cache_tail = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + s->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + s->next = ctx->session_cache_head; + s->next->prev = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = s; + } +} + +void +SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) { + ctx->new_session_cb = cb; +} +LSSL_ALIAS(SSL_CTX_sess_set_new_cb); + +int +(*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) +{ + return ctx->new_session_cb; +} +LSSL_ALIAS(SSL_CTX_sess_get_new_cb); + +void +SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) +{ + ctx->remove_session_cb = cb; +} +LSSL_ALIAS(SSL_CTX_sess_set_remove_cb); + +void +(*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx, SSL_SESSION *sess) +{ + return ctx->remove_session_cb; +} +LSSL_ALIAS(SSL_CTX_sess_get_remove_cb); + +void +SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*cb)(struct ssl_st *ssl, + const unsigned char *data, int len, int *copy)) +{ + ctx->get_session_cb = cb; +} +LSSL_ALIAS(SSL_CTX_sess_set_get_cb); + +SSL_SESSION * +(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, const unsigned char *data, + int len, int *copy) +{ + return ctx->get_session_cb; +} +LSSL_ALIAS(SSL_CTX_sess_get_get_cb); + +void +SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, int type, int val)) +{ + ctx->info_callback = cb; +} +LSSL_ALIAS(SSL_CTX_set_info_callback); + +void +(*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, int val) +{ + return ctx->info_callback; +} +LSSL_ALIAS(SSL_CTX_get_info_callback); + +void +SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)) +{ + ctx->client_cert_cb = cb; +} +LSSL_ALIAS(SSL_CTX_set_client_cert_cb); + +int +(*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509, + EVP_PKEY **pkey) +{ + return ctx->client_cert_cb; +} +LSSL_ALIAS(SSL_CTX_get_client_cert_cb); + +#ifndef OPENSSL_NO_ENGINE +int +SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) +{ + if (!ENGINE_init(e)) { + SSLerrorx(ERR_R_ENGINE_LIB); + return 0; + } + if (!ENGINE_get_ssl_client_cert_function(e)) { + SSLerrorx(SSL_R_NO_CLIENT_CERT_METHOD); + ENGINE_finish(e); + return 0; + } + ctx->client_cert_engine = e; + return 1; +} +LSSL_ALIAS(SSL_CTX_set_client_cert_engine); +#endif + +void +SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)) +{ + ctx->app_gen_cookie_cb = cb; +} +LSSL_ALIAS(SSL_CTX_set_cookie_generate_cb); + +void +SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, const unsigned char *cookie, unsigned int cookie_len)) +{ + ctx->app_verify_cookie_cb = cb; +} +LSSL_ALIAS(SSL_CTX_set_cookie_verify_cb); + +int +PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x) +{ + return PEM_ASN1_write((i2d_of_void *)i2d_SSL_SESSION, + PEM_STRING_SSL_SESSION, fp, x, NULL, NULL, 0, NULL, NULL); +} +LSSL_ALIAS(PEM_write_SSL_SESSION); + +SSL_SESSION * +PEM_read_SSL_SESSION(FILE *fp, SSL_SESSION **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read((d2i_of_void *)d2i_SSL_SESSION, + PEM_STRING_SSL_SESSION, fp, (void **)x, cb, u); +} +LSSL_ALIAS(PEM_read_SSL_SESSION); + +SSL_SESSION * +PEM_read_bio_SSL_SESSION(BIO *bp, SSL_SESSION **x, pem_password_cb *cb, void *u) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_SSL_SESSION, + PEM_STRING_SSL_SESSION, bp, (void **)x, cb, u); +} +LSSL_ALIAS(PEM_read_bio_SSL_SESSION); + +int +PEM_write_bio_SSL_SESSION(BIO *bp, SSL_SESSION *x) +{ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_SSL_SESSION, + PEM_STRING_SSL_SESSION, bp, x, NULL, NULL, 0, NULL, NULL); +} +LSSL_ALIAS(PEM_write_bio_SSL_SESSION); diff --git a/Libraries/libressl/ssl/ssl_sigalgs.c b/Libraries/libressl/ssl/ssl_sigalgs.c new file mode 100644 index 000000000..f59beb432 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_sigalgs.c @@ -0,0 +1,388 @@ +/* $OpenBSD: ssl_sigalgs.c,v 1.48 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2018-2020 Bob Beck + * Copyright (c) 2021 Joel Sing + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "tls13_internal.h" + +const struct ssl_sigalg sigalgs[] = { + { + .value = SIGALG_RSA_PKCS1_SHA512, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha512, + .security_level = 5, + }, + { + .value = SIGALG_ECDSA_SECP521R1_SHA512, + .key_type = EVP_PKEY_EC, + .md = EVP_sha512, + .security_level = 5, + .group_nid = NID_secp521r1, + }, +#ifndef OPENSSL_NO_GOST + { + .value = SIGALG_GOSTR12_512_STREEBOG_512, + .key_type = EVP_PKEY_GOSTR12_512, + .md = EVP_streebog512, + .security_level = 0, + }, +#endif + { + .value = SIGALG_RSA_PKCS1_SHA384, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha384, + .security_level = 4, + }, + { + .value = SIGALG_ECDSA_SECP384R1_SHA384, + .key_type = EVP_PKEY_EC, + .md = EVP_sha384, + .security_level = 4, + .group_nid = NID_secp384r1, + }, + { + .value = SIGALG_RSA_PKCS1_SHA256, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha256, + .security_level = 3, + }, + { + .value = SIGALG_ECDSA_SECP256R1_SHA256, + .key_type = EVP_PKEY_EC, + .md = EVP_sha256, + .security_level = 3, + .group_nid = NID_X9_62_prime256v1, + }, +#ifndef OPENSSL_NO_GOST + { + .value = SIGALG_GOSTR12_256_STREEBOG_256, + .key_type = EVP_PKEY_GOSTR12_256, + .md = EVP_streebog256, + .security_level = 0, + }, + { + .value = SIGALG_GOSTR01_GOST94, + .key_type = EVP_PKEY_GOSTR01, + .md = EVP_gostr341194, + .security_level = 0, /* XXX */ + }, +#endif + { + .value = SIGALG_RSA_PSS_RSAE_SHA256, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha256, + .security_level = 3, + .flags = SIGALG_FLAG_RSA_PSS, + }, + { + .value = SIGALG_RSA_PSS_RSAE_SHA384, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha384, + .security_level = 4, + .flags = SIGALG_FLAG_RSA_PSS, + }, + { + .value = SIGALG_RSA_PSS_RSAE_SHA512, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha512, + .security_level = 5, + .flags = SIGALG_FLAG_RSA_PSS, + }, + { + .value = SIGALG_RSA_PSS_PSS_SHA256, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha256, + .security_level = 3, + .flags = SIGALG_FLAG_RSA_PSS, + }, + { + .value = SIGALG_RSA_PSS_PSS_SHA384, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha384, + .security_level = 4, + .flags = SIGALG_FLAG_RSA_PSS, + }, + { + .value = SIGALG_RSA_PSS_PSS_SHA512, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha512, + .security_level = 5, + .flags = SIGALG_FLAG_RSA_PSS, + }, + { + .value = SIGALG_RSA_PKCS1_SHA224, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha224, + .security_level = 2, + }, + { + .value = SIGALG_ECDSA_SECP224R1_SHA224, + .key_type = EVP_PKEY_EC, + .md = EVP_sha224, + .security_level = 2, + }, + { + .value = SIGALG_RSA_PKCS1_SHA1, + .key_type = EVP_PKEY_RSA, + .md = EVP_sha1, + .security_level = 1, + }, + { + .value = SIGALG_ECDSA_SHA1, + .key_type = EVP_PKEY_EC, + .md = EVP_sha1, + .security_level = 1, + }, + { + .value = SIGALG_RSA_PKCS1_MD5_SHA1, + .key_type = EVP_PKEY_RSA, + .md = EVP_md5_sha1, + .security_level = 1, + }, + { + .value = SIGALG_NONE, + }, +}; + +/* Sigalgs for TLSv1.3, in preference order. */ +const uint16_t tls13_sigalgs[] = { + SIGALG_RSA_PSS_RSAE_SHA512, + SIGALG_RSA_PKCS1_SHA512, + SIGALG_ECDSA_SECP521R1_SHA512, + SIGALG_RSA_PSS_RSAE_SHA384, + SIGALG_RSA_PKCS1_SHA384, + SIGALG_ECDSA_SECP384R1_SHA384, + SIGALG_RSA_PSS_RSAE_SHA256, + SIGALG_RSA_PKCS1_SHA256, + SIGALG_ECDSA_SECP256R1_SHA256, +}; +const size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0])); + +/* Sigalgs for TLSv1.2, in preference order. */ +const uint16_t tls12_sigalgs[] = { + SIGALG_RSA_PSS_RSAE_SHA512, + SIGALG_RSA_PKCS1_SHA512, + SIGALG_ECDSA_SECP521R1_SHA512, + SIGALG_RSA_PSS_RSAE_SHA384, + SIGALG_RSA_PKCS1_SHA384, + SIGALG_ECDSA_SECP384R1_SHA384, + SIGALG_RSA_PSS_RSAE_SHA256, + SIGALG_RSA_PKCS1_SHA256, + SIGALG_ECDSA_SECP256R1_SHA256, + SIGALG_RSA_PKCS1_SHA1, /* XXX */ + SIGALG_ECDSA_SHA1, /* XXX */ +}; +const size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0])); + +static void +ssl_sigalgs_for_version(uint16_t tls_version, const uint16_t **out_values, + size_t *out_len) +{ + if (tls_version >= TLS1_3_VERSION) { + *out_values = tls13_sigalgs; + *out_len = tls13_sigalgs_len; + } else { + *out_values = tls12_sigalgs; + *out_len = tls12_sigalgs_len; + } +} + +static const struct ssl_sigalg * +ssl_sigalg_lookup(uint16_t value) +{ + int i; + + for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) { + if (sigalgs[i].value == value) + return &sigalgs[i]; + } + + return NULL; +} + +static const struct ssl_sigalg * +ssl_sigalg_from_value(SSL *s, uint16_t value) +{ + const uint16_t *values; + size_t len; + int i; + + ssl_sigalgs_for_version(s->s3->hs.negotiated_tls_version, + &values, &len); + + for (i = 0; i < len; i++) { + if (values[i] == value) + return ssl_sigalg_lookup(value); + } + + return NULL; +} + +int +ssl_sigalgs_build(uint16_t tls_version, CBB *cbb, int security_level) +{ + const struct ssl_sigalg *sigalg; + const uint16_t *values; + size_t len; + size_t i; + int ret = 0; + + ssl_sigalgs_for_version(tls_version, &values, &len); + + /* Add values in order as long as they are supported. */ + for (i = 0; i < len; i++) { + /* Do not allow the legacy value for < 1.2 to be used. */ + if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1) + return 0; + if ((sigalg = ssl_sigalg_lookup(values[i])) == NULL) + return 0; + if (sigalg->security_level < security_level) + continue; + + if (!CBB_add_u16(cbb, values[i])) + return 0; + + ret = 1; + } + return ret; +} + +static const struct ssl_sigalg * +ssl_sigalg_for_legacy(SSL *s, EVP_PKEY *pkey) +{ + if (SSL_get_security_level(s) > 1) + return NULL; + + /* Default signature algorithms used for TLSv1.2 and earlier. */ + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_RSA: + if (s->s3->hs.negotiated_tls_version < TLS1_2_VERSION) + return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1); + return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); + case EVP_PKEY_EC: + return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); +#ifndef OPENSSL_NO_GOST + case EVP_PKEY_GOSTR01: + return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); +#endif + } + SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); + return NULL; +} + +static int +ssl_sigalg_pkey_ok(SSL *s, const struct ssl_sigalg *sigalg, EVP_PKEY *pkey) +{ + if (sigalg == NULL || pkey == NULL) + return 0; + if (sigalg->key_type != EVP_PKEY_id(pkey)) + return 0; + + /* RSA PSS must have a sufficiently large RSA key. */ + if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) { + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA || + EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2)) + return 0; + } + + if (!ssl_security_sigalg_check(s, pkey)) + return 0; + + if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION) + return 1; + + /* RSA cannot be used without PSS in TLSv1.3. */ + if (sigalg->key_type == EVP_PKEY_RSA && + (sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0) + return 0; + + /* Ensure that group matches for EC keys. */ + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + if (sigalg->group_nid == 0) + return 0; + if (EC_GROUP_get_curve_name(EC_KEY_get0_group( + EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->group_nid) + return 0; + } + + return 1; +} + +const struct ssl_sigalg * +ssl_sigalg_select(SSL *s, EVP_PKEY *pkey) +{ + CBS cbs; + + if (!SSL_USE_SIGALGS(s)) + return ssl_sigalg_for_legacy(s, pkey); + + /* + * RFC 5246 allows a TLS 1.2 client to send no sigalgs extension, + * in which case the server must use the default. + */ + if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION && + s->s3->hs.sigalgs == NULL) + return ssl_sigalg_for_legacy(s, pkey); + + /* + * If we get here, we have client or server sent sigalgs, use one. + */ + CBS_init(&cbs, s->s3->hs.sigalgs, s->s3->hs.sigalgs_len); + while (CBS_len(&cbs) > 0) { + const struct ssl_sigalg *sigalg; + uint16_t sigalg_value; + + if (!CBS_get_u16(&cbs, &sigalg_value)) + return NULL; + + if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL) + continue; + if (ssl_sigalg_pkey_ok(s, sigalg, pkey)) + return sigalg; + } + + SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); + return NULL; +} + +const struct ssl_sigalg * +ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey, uint16_t sigalg_value) +{ + const struct ssl_sigalg *sigalg; + + if (!SSL_USE_SIGALGS(s)) + return ssl_sigalg_for_legacy(s, pkey); + + if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL) { + SSLerror(s, SSL_R_UNKNOWN_DIGEST); + return NULL; + } + if (!ssl_sigalg_pkey_ok(s, sigalg, pkey)) { + SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE); + return NULL; + } + + return sigalg; +} diff --git a/Libraries/libressl/ssl/ssl_sigalgs.h b/Libraries/libressl/ssl/ssl_sigalgs.h new file mode 100644 index 000000000..21a54d642 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_sigalgs.h @@ -0,0 +1,79 @@ +/* $OpenBSD: ssl_sigalgs.h,v 1.26 2022/07/02 16:00:12 tb Exp $ */ +/* + * Copyright (c) 2018-2019 Bob Beck + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_SSL_SIGALGS_H +#define HEADER_SSL_SIGALGS_H + +__BEGIN_HIDDEN_DECLS + +#define SIGALG_NONE 0x0000 + +/* + * RFC 8446 Section 4.2.3 + * RFC 5246 Section 7.4.1.4.1 + */ +#define SIGALG_RSA_PKCS1_SHA224 0x0301 +#define SIGALG_RSA_PKCS1_SHA256 0x0401 +#define SIGALG_RSA_PKCS1_SHA384 0x0501 +#define SIGALG_RSA_PKCS1_SHA512 0x0601 +#define SIGALG_ECDSA_SECP224R1_SHA224 0x0303 +#define SIGALG_ECDSA_SECP256R1_SHA256 0x0403 +#define SIGALG_ECDSA_SECP384R1_SHA384 0x0503 +#define SIGALG_ECDSA_SECP521R1_SHA512 0x0603 +#define SIGALG_RSA_PSS_RSAE_SHA256 0x0804 +#define SIGALG_RSA_PSS_RSAE_SHA384 0x0805 +#define SIGALG_RSA_PSS_RSAE_SHA512 0x0806 +#define SIGALG_ED25519 0x0807 +#define SIGALG_ED448 0x0808 +#define SIGALG_RSA_PSS_PSS_SHA256 0x0809 +#define SIGALG_RSA_PSS_PSS_SHA384 0x080a +#define SIGALG_RSA_PSS_PSS_SHA512 0x080b +#define SIGALG_RSA_PKCS1_SHA1 0x0201 +#define SIGALG_ECDSA_SHA1 0x0203 +#define SIGALG_PRIVATE_START 0xFE00 +#define SIGALG_PRIVATE_END 0xFFFF + +/* + * If Russia can elect the US President, surely + * IANA could fix this problem. + */ +#define SIGALG_GOSTR12_512_STREEBOG_512 0xEFEF +#define SIGALG_GOSTR12_256_STREEBOG_256 0xEEEE +#define SIGALG_GOSTR01_GOST94 0xEDED + +/* Legacy sigalg for < TLSv1.2 same value as BoringSSL uses. */ +#define SIGALG_RSA_PKCS1_MD5_SHA1 0xFF01 + +#define SIGALG_FLAG_RSA_PSS 0x00000001 + +struct ssl_sigalg { + uint16_t value; + int key_type; + const EVP_MD *(*md)(void); + int security_level; + int group_nid; + int flags; +}; + +int ssl_sigalgs_build(uint16_t tls_version, CBB *cbb, int security_level); +const struct ssl_sigalg *ssl_sigalg_select(SSL *s, EVP_PKEY *pkey); +const struct ssl_sigalg *ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey, + uint16_t sigalg_value); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/ssl_srvr.c b/Libraries/libressl/ssl/ssl_srvr.c new file mode 100644 index 000000000..a518e1ac9 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_srvr.c @@ -0,0 +1,2629 @@ +/* $OpenBSD: ssl_srvr.c,v 1.156 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_GOST +#include +#endif + +#include "bytestring.h" +#include "dtls_local.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" + +static int ssl3_get_client_hello(SSL *s); +static int ssl3_send_dtls_hello_verify_request(SSL *s); +static int ssl3_send_server_hello(SSL *s); +static int ssl3_send_hello_request(SSL *s); +static int ssl3_send_server_certificate(SSL *s); +static int ssl3_send_server_key_exchange(SSL *s); +static int ssl3_send_certificate_request(SSL *s); +static int ssl3_send_server_done(SSL *s); +static int ssl3_get_client_certificate(SSL *s); +static int ssl3_get_client_key_exchange(SSL *s); +static int ssl3_get_cert_verify(SSL *s); +static int ssl3_send_newsession_ticket(SSL *s); +static int ssl3_send_cert_status(SSL *s); +static int ssl3_send_server_change_cipher_spec(SSL *s); +static int ssl3_send_server_finished(SSL *s); +static int ssl3_get_client_finished(SSL *s); + +int +ssl3_accept(SSL *s) +{ + unsigned long alg_k; + int new_state, state, skip = 0; + int listen = 0; + int ret = -1; + + ERR_clear_error(); + errno = 0; + + if (SSL_is_dtls(s)) + listen = s->d1->listen; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + if (SSL_is_dtls(s)) + s->d1->listen = listen; + + for (;;) { + state = s->s3->hs.state; + + switch (s->s3->hs.state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->s3->hs.state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + case SSL_ST_OK|SSL_ST_ACCEPT: + s->server = 1; + + ssl_info_callback(s, SSL_CB_HANDSHAKE_START, 1); + + if (!ssl_legacy_stack_version(s, s->version)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + if (!ssl_supported_tls_version_range(s, + &s->s3->hs.our_min_tls_version, + &s->s3->hs.our_max_tls_version)) { + SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); + ret = -1; + goto end; + } + + if (!ssl_security_version(s, + s->s3->hs.our_min_tls_version)) { + SSLerror(s, SSL_R_VERSION_TOO_LOW); + ret = -1; + goto end; + } + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + + s->init_num = 0; + + if (s->s3->hs.state != SSL_ST_RENEGOTIATE) { + /* + * Ok, we now need to push on a buffering BIO + * so that the output is sent in a way that + * TCP likes :-) + */ + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + goto end; + } + + if (!tls1_transcript_init(s)) { + ret = -1; + goto end; + } + + s->s3->hs.state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else if (!SSL_is_dtls(s) && !s->s3->send_connection_binding) { + /* + * Server attempting to renegotiate with + * client that doesn't support secure + * renegotiation. + */ + SSLerror(s, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + goto end; + } else { + /* + * s->s3->hs.state == SSL_ST_RENEGOTIATE, + * we will just send a HelloRequest. + */ + s->ctx->stats.sess_accept_renegotiate++; + s->s3->hs.state = SSL3_ST_SW_HELLO_REQ_A; + } + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + s->shutdown = 0; + if (SSL_is_dtls(s)) { + dtls1_clear_record_buffer(s); + dtls1_start_timer(s); + } + ret = ssl3_send_hello_request(s); + if (ret <= 0) + goto end; + if (SSL_is_dtls(s)) + s->s3->hs.tls12.next_state = SSL3_ST_SR_CLNT_HELLO_A; + else + s->s3->hs.tls12.next_state = SSL3_ST_SW_HELLO_REQ_C; + s->s3->hs.state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + if (SSL_is_dtls(s)) { + if (!tls1_transcript_init(s)) { + ret = -1; + goto end; + } + } + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->s3->hs.state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + s->shutdown = 0; + if (SSL_is_dtls(s)) { + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (ret == 1 && + (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) + s->s3->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; + else + s->s3->hs.state = SSL3_ST_SW_SRVR_HELLO_A; + + s->init_num = 0; + + /* + * Reflect ClientHello sequence to remain + * stateless while listening. + */ + if (listen) { + tls12_record_layer_reflect_seq_num( + s->rl); + } + + /* If we're just listening, stop here */ + if (listen && s->s3->hs.state == SSL3_ST_SW_SRVR_HELLO_A) { + ret = 2; + s->d1->listen = 0; + /* + * Set expected sequence numbers to + * continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; + goto end; + } + } else { + if (s->rwstate != SSL_X509_LOOKUP) { + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + } + + s->renegotiate = 2; + s->s3->hs.state = SSL3_ST_SW_SRVR_HELLO_A; + s->init_num = 0; + } + break; + + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + ret = ssl3_send_dtls_hello_verify_request(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SW_FLUSH; + s->s3->hs.tls12.next_state = SSL3_ST_SR_CLNT_HELLO_A; + + /* HelloVerifyRequest resets Finished MAC. */ + tls1_transcript_reset(s); + break; + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + if (SSL_is_dtls(s)) { + s->renegotiate = 2; + dtls1_start_timer(s); + } + ret = ssl3_send_server_hello(s); + if (ret <= 0) + goto end; + if (s->hit) { + if (s->tlsext_ticket_expected) + s->s3->hs.state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->s3->hs.state = SSL3_ST_SW_CHANGE_A; + } else { + s->s3->hs.state = SSL3_ST_SW_CERT_A; + } + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH or anon ECDH. */ + if (!(s->s3->hs.cipher->algorithm_auth & + SSL_aNULL)) { + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_server_certificate(s); + if (ret <= 0) + goto end; + if (s->tlsext_status_expected) + s->s3->hs.state = SSL3_ST_SW_CERT_STATUS_A; + else + s->s3->hs.state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->s3->hs.state = SSL3_ST_SW_KEY_EXCH_A; + } + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->hs.cipher->algorithm_mkey; + + /* + * Only send if using a DH key exchange. + * + * For ECC ciphersuites, we send a ServerKeyExchange + * message only if the cipher suite is ECDHE. In other + * cases, the server certificate contains the server's + * public key for key exchange. + */ + if (alg_k & (SSL_kDHE|SSL_kECDHE)) { + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->s3->hs.state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + /* + * Determine whether or not we need to request a + * certificate. + * + * Do not request a certificate if: + * + * - We did not ask for it (SSL_VERIFY_PEER is unset). + * + * - SSL_VERIFY_CLIENT_ONCE is set and we are + * renegotiating. + * + * - We are using an anonymous ciphersuites + * (see section "Certificate request" in SSL 3 drafts + * and in RFC 2246) ... except when the application + * insists on verification (against the specs, but + * s3_clnt.c accepts this for SSL 3). + */ + if (!(s->verify_mode & SSL_VERIFY_PEER) || + ((s->session->peer_cert != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + ((s->s3->hs.cipher->algorithm_auth & + SSL_aNULL) && !(s->verify_mode & + SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) { + /* No cert request. */ + skip = 1; + s->s3->hs.tls12.cert_request = 0; + s->s3->hs.state = SSL3_ST_SW_SRVR_DONE_A; + + if (!SSL_is_dtls(s)) + tls1_transcript_free(s); + } else { + s->s3->hs.tls12.cert_request = 1; + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_certificate_request(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SW_SRVR_DONE_A; + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + if (SSL_is_dtls(s)) + dtls1_start_timer(s); + ret = ssl3_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->hs.tls12.next_state = SSL3_ST_SR_CERT_A; + s->s3->hs.state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + /* + * This code originally checked to see if + * any data was pending using BIO_CTRL_INFO + * and then flushed. This caused problems + * as documented in PR#1939. The proposed + * fix doesn't completely resolve this issue + * as buggy implementations of BIO_CTRL_PENDING + * still exist. So instead we just flush + * unconditionally. + */ + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + if (SSL_is_dtls(s)) { + /* If the write error was fatal, stop trying. */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->s3->hs.state = s->s3->hs.tls12.next_state; + } + } + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->s3->hs.state = s->s3->hs.tls12.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + if (s->s3->hs.tls12.cert_request != 0) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->s3->hs.state = SSL3_ST_SR_KEY_EXCH_A; + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; + + if (SSL_is_dtls(s)) { + s->s3->hs.state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + } + + alg_k = s->s3->hs.cipher->algorithm_mkey; + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + /* + * A GOST client may use the key from its + * certificate for key exchange, in which case + * the CertificateVerify message is not sent. + */ + s->s3->hs.state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + } else if (SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) { + s->s3->hs.state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + if (!s->session->peer_cert) + break; + /* + * Freeze the transcript for use during client + * certificate verification. + */ + tls1_transcript_freeze(s); + } else { + s->s3->hs.state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + tls1_transcript_free(s); + + /* + * We need to get hashes here so if there is + * a client cert, it can be verified. + */ + if (!tls1_transcript_hash_value(s, + s->s3->hs.tls12.cert_verify, + sizeof(s->s3->hs.tls12.cert_verify), + NULL)) { + ret = -1; + goto end; + } + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + if (SSL_is_dtls(s)) + s->d1->change_cipher_spec_ok = 1; + else + s->s3->flags |= SSL3_FLAGS_CCS_OK; + + /* we should decide if we expected this one */ + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + if (SSL_is_dtls(s)) + s->d1->change_cipher_spec_ok = 1; + else + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_client_finished(s); + if (ret <= 0) + goto end; + if (SSL_is_dtls(s)) + dtls1_stop_timer(s); + if (s->hit) + s->s3->hs.state = SSL_ST_OK; + else if (s->tlsext_ticket_expected) + s->s3->hs.state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->s3->hs.state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = ssl3_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + ret = ssl3_send_server_change_cipher_spec(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + s->session->cipher = s->s3->hs.cipher; + + if (!tls1_setup_key_block(s)) { + ret = -1; + goto end; + } + if (!tls1_change_write_cipher_state(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = ssl3_send_server_finished(s); + if (ret <= 0) + goto end; + s->s3->hs.state = SSL3_ST_SW_FLUSH; + if (s->hit) { + s->s3->hs.tls12.next_state = SSL3_ST_SR_FINISHED_A; + tls1_transcript_free(s); + } else + s->s3->hs.tls12.next_state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + tls1_cleanup_key_block(s); + + if (s->s3->handshake_transcript != NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + if (!SSL_is_dtls(s)) + ssl3_release_init_buffer(s); + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + /* Skipped if we just sent a HelloRequest. */ + if (s->renegotiate == 2) { + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = ssl3_accept; + + ssl_info_callback(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + + if (SSL_is_dtls(s)) { + /* Done handshaking, next message is client hello. */ + s->d1->handshake_read_seq = 0; + /* Next message is server hello. */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; + } + goto end; + /* break; */ + + default: + SSLerror(s, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->hs.tls12.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + + if (s->s3->hs.state != state) { + new_state = s->s3->hs.state; + s->s3->hs.state = state; + ssl_info_callback(s, SSL_CB_ACCEPT_LOOP, 1); + s->s3->hs.state = new_state; + } + } + skip = 0; + } + end: + /* BIO_flush(s->wbio); */ + s->in_handshake--; + ssl_info_callback(s, SSL_CB_ACCEPT_EXIT, ret); + + return (ret); +} + +static int +ssl3_send_hello_request(SSL *s) +{ + CBB cbb, hello; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_HELLO_REQ_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &hello, + SSL3_MT_HELLO_REQUEST)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_HELLO_REQ_B; + } + + /* SSL3_ST_SW_HELLO_REQ_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_get_client_hello(SSL *s) +{ + CBS cbs, client_random, session_id, cookie, cipher_suites; + CBS compression_methods; + uint16_t client_version; + uint8_t comp_method; + int comp_null; + int i, j, al, ret, cookie_valid = 0; + unsigned long id; + SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *ciphers = NULL; + unsigned long alg_k; + const SSL_METHOD *method; + uint16_t shared_version; + + /* + * We do this so that we will respond with our native type. + * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, + * This down switching should be handled by a different method. + * If we are SSLv3, we will respond with SSLv3, even if prompted with + * TLSv1. + */ + if (s->s3->hs.state == SSL3_ST_SR_CLNT_HELLO_A) + s->s3->hs.state = SSL3_ST_SR_CLNT_HELLO_B; + + s->first_packet = 1; + if ((ret = ssl3_get_message(s, SSL3_ST_SR_CLNT_HELLO_B, + SSL3_ST_SR_CLNT_HELLO_C, SSL3_MT_CLIENT_HELLO, + SSL3_RT_MAX_PLAIN_LENGTH)) <= 0) + return ret; + s->first_packet = 0; + + ret = -1; + + if (s->init_num < 0) + goto err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + /* Parse client hello up until the extensions (if any). */ + if (!CBS_get_u16(&cbs, &client_version)) + goto decode_err; + if (!CBS_get_bytes(&cbs, &client_random, SSL3_RANDOM_SIZE)) + goto decode_err; + if (!CBS_get_u8_length_prefixed(&cbs, &session_id)) + goto decode_err; + if (CBS_len(&session_id) > SSL3_SESSION_ID_SIZE) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto fatal_err; + } + if (SSL_is_dtls(s)) { + if (!CBS_get_u8_length_prefixed(&cbs, &cookie)) + goto decode_err; + } + if (!CBS_get_u16_length_prefixed(&cbs, &cipher_suites)) + goto decode_err; + if (!CBS_get_u8_length_prefixed(&cbs, &compression_methods)) + goto decode_err; + + /* + * Use version from inside client hello, not from record header. + * (may differ: see RFC 2246, Appendix E, second paragraph) + */ + if (!ssl_max_shared_version(s, client_version, &shared_version)) { + if ((client_version >> 8) == SSL3_VERSION_MAJOR && + !tls12_record_layer_write_protected(s->rl)) { + /* + * Similar to ssl3_get_record, send alert using remote + * version number. + */ + s->version = client_version; + } + SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); + al = SSL_AD_PROTOCOL_VERSION; + goto fatal_err; + } + s->s3->hs.peer_legacy_version = client_version; + s->version = shared_version; + + s->s3->hs.negotiated_tls_version = ssl_tls_version(shared_version); + if (s->s3->hs.negotiated_tls_version == 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((method = ssl_get_method(shared_version)) == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + s->method = method; + + /* + * If we require cookies (DTLS) and this ClientHello does not contain + * one, just return since we do not want to allocate any memory yet. + * So check cookie length... + */ + if (SSL_is_dtls(s)) { + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { + if (CBS_len(&cookie) == 0) + return (1); + } + } + + if (!CBS_write_bytes(&client_random, s->s3->client_random, + sizeof(s->s3->client_random), NULL)) + goto err; + + s->hit = 0; + + /* + * Versions before 0.9.7 always allow clients to resume sessions in + * renegotiation. 0.9.7 and later allow this by default, but optionally + * ignore resumption requests with flag + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag + * rather than a change to default behavior so that applications + * relying on this for security won't even compile against older + * library versions). + * + * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() + * to request renegotiation but not a new session (s->new_session + * remains unset): for servers, this essentially just means that the + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be + * ignored. + */ + if ((s->new_session && (s->options & + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (!ssl_get_new_session(s, 1)) + goto err; + } else { + CBS ext_block; + + CBS_dup(&cbs, &ext_block); + + i = ssl_get_prev_session(s, &session_id, &ext_block, &al); + if (i == 1) { /* previous session */ + s->hit = 1; + } else if (i == -1) + goto fatal_err; + else { + /* i == 0 */ + if (!ssl_get_new_session(s, 1)) + goto err; + } + } + + if (SSL_is_dtls(s)) { + /* + * The ClientHello may contain a cookie even if the HelloVerify + * message has not been sent - make sure that it does not cause + * an overflow. + */ + if (CBS_len(&cookie) > sizeof(s->d1->rcvd_cookie)) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_COOKIE_MISMATCH); + goto fatal_err; + } + + /* Verify the cookie if appropriate option is set. */ + if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && + CBS_len(&cookie) > 0) { + size_t cookie_len; + + /* XXX - rcvd_cookie seems to only be used here... */ + if (!CBS_write_bytes(&cookie, s->d1->rcvd_cookie, + sizeof(s->d1->rcvd_cookie), &cookie_len)) + goto err; + + if (s->ctx->app_verify_cookie_cb != NULL) { + if (s->ctx->app_verify_cookie_cb(s, + s->d1->rcvd_cookie, cookie_len) == 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_COOKIE_MISMATCH); + goto fatal_err; + } + /* else cookie verification succeeded */ + /* XXX - can d1->cookie_len > sizeof(rcvd_cookie) ? */ + } else if (timingsafe_memcmp(s->d1->rcvd_cookie, + s->d1->cookie, s->d1->cookie_len) != 0) { + /* default verification */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_COOKIE_MISMATCH); + goto fatal_err; + } + cookie_valid = 1; + } + } + + /* XXX - This logic seems wrong... */ + if (CBS_len(&cipher_suites) == 0 && CBS_len(&session_id) != 0) { + /* we need a cipher if we are not resuming a session */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_NO_CIPHERS_SPECIFIED); + goto fatal_err; + } + + if (CBS_len(&cipher_suites) > 0) { + if ((ciphers = ssl_bytes_to_cipher_list(s, + &cipher_suites)) == NULL) + goto err; + } + + /* If it is a hit, check that the cipher is in the list */ + /* XXX - CBS_len(&cipher_suites) will always be zero here... */ + if (s->hit && CBS_len(&cipher_suites) > 0) { + j = 0; + id = s->session->cipher->id; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + c = sk_SSL_CIPHER_value(ciphers, i); + if (c->id == id) { + j = 1; + break; + } + } + if (j == 0) { + /* + * We need to have the cipher in the cipher + * list if we are asked to reuse it + */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_REQUIRED_CIPHER_MISSING); + goto fatal_err; + } + } + + comp_null = 0; + while (CBS_len(&compression_methods) > 0) { + if (!CBS_get_u8(&compression_methods, &comp_method)) + goto decode_err; + if (comp_method == 0) + comp_null = 1; + } + if (comp_null == 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_NO_COMPRESSION_SPECIFIED); + goto fatal_err; + } + + if (!tlsext_server_parse(s, SSL_TLSEXT_MSG_CH, &cbs, &al)) { + SSLerror(s, SSL_R_PARSE_TLSEXT); + goto fatal_err; + } + + if (CBS_len(&cbs) != 0) + goto decode_err; + + if (!s->s3->renegotiate_seen && s->renegotiate) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + goto fatal_err; + } + + if (ssl_check_clienthello_tlsext_early(s) <= 0) { + SSLerror(s, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + + /* + * Check if we want to use external pre-shared secret for this + * handshake for not reused session only. We need to generate + * server_random before calling tls_session_secret_cb in order to allow + * SessionTicket processing to use it in key derivation. + */ + arc4random_buf(s->s3->server_random, SSL3_RANDOM_SIZE); + + if (s->s3->hs.our_max_tls_version >= TLS1_2_VERSION && + s->s3->hs.negotiated_tls_version < s->s3->hs.our_max_tls_version) { + /* + * RFC 8446 section 4.1.3. If we are downgrading from TLS 1.3 + * we must set the last 8 bytes of the server random to magical + * values to indicate we meant to downgrade. For TLS 1.2 it is + * recommended that we do the same. + */ + size_t index = SSL3_RANDOM_SIZE - sizeof(tls13_downgrade_12); + uint8_t *magic = &s->s3->server_random[index]; + if (s->s3->hs.negotiated_tls_version == TLS1_2_VERSION) { + /* Indicate we chose to downgrade to 1.2. */ + memcpy(magic, tls13_downgrade_12, + sizeof(tls13_downgrade_12)); + } else { + /* Indicate we chose to downgrade to 1.1 or lower */ + memcpy(magic, tls13_downgrade_11, + sizeof(tls13_downgrade_11)); + } + } + + if (!s->hit && s->tls_session_secret_cb != NULL) { + SSL_CIPHER *pref_cipher = NULL; + int master_key_length = sizeof(s->session->master_key); + + if (!s->tls_session_secret_cb(s, + s->session->master_key, &master_key_length, ciphers, + &pref_cipher, s->tls_session_secret_cb_arg)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (master_key_length <= 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + s->session->master_key_length = master_key_length; + + s->hit = 1; + s->session->verify_result = X509_V_OK; + + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = ciphers; + ciphers = NULL; + + /* Check if some cipher was preferred by the callback. */ + if (pref_cipher == NULL) + pref_cipher = ssl3_choose_cipher(s, s->session->ciphers, + SSL_get_ciphers(s)); + if (pref_cipher == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_NO_SHARED_CIPHER); + goto fatal_err; + } + s->session->cipher = pref_cipher; + + sk_SSL_CIPHER_free(s->cipher_list); + s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); + } + + /* + * Given s->session->ciphers and SSL_get_ciphers, we must + * pick a cipher + */ + + if (!s->hit) { + if (ciphers == NULL) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerror(s, SSL_R_NO_CIPHERS_PASSED); + goto fatal_err; + } + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = ciphers; + ciphers = NULL; + + if ((c = ssl3_choose_cipher(s, s->session->ciphers, + SSL_get_ciphers(s))) == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_NO_SHARED_CIPHER); + goto fatal_err; + } + s->s3->hs.cipher = c; + } else { + s->s3->hs.cipher = s->session->cipher; + } + + if (!tls1_transcript_hash_init(s)) + goto err; + + alg_k = s->s3->hs.cipher->algorithm_mkey; + if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) || + !(s->verify_mode & SSL_VERIFY_PEER)) + tls1_transcript_free(s); + + /* + * We now have the following setup. + * client_random + * cipher_list - our preferred list of ciphers + * ciphers - the clients preferred list of ciphers + * compression - basically ignored right now + * ssl version is set - sslv3 + * s->session - The ssl session has been setup. + * s->hit - session reuse flag + * s->hs.cipher - the new cipher to use. + */ + + /* Handles TLS extensions that we couldn't check earlier */ + if (ssl_check_clienthello_tlsext_late(s) <= 0) { + SSLerror(s, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + + ret = cookie_valid ? 2 : 1; + + if (0) { + decode_err: + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } + err: + sk_SSL_CIPHER_free(ciphers); + + return (ret); +} + +static int +ssl3_send_dtls_hello_verify_request(SSL *s) +{ + CBB cbb, verify, cookie; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) { + if (s->ctx->app_gen_cookie_cb == NULL || + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* + * Per RFC 6347 section 4.2.1, the HelloVerifyRequest should + * always contain DTLSv1.0 regardless of the version that is + * going to be negotiated. + */ + if (!ssl3_handshake_msg_start(s, &cbb, &verify, + DTLS1_MT_HELLO_VERIFY_REQUEST)) + goto err; + if (!CBB_add_u16(&verify, DTLS1_VERSION)) + goto err; + if (!CBB_add_u8_length_prefixed(&verify, &cookie)) + goto err; + if (!CBB_add_bytes(&cookie, s->d1->cookie, s->d1->cookie_len)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; + } + + /* s->s3->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_send_server_hello(SSL *s) +{ + CBB cbb, server_hello, session_id; + size_t sl; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_SRVR_HELLO_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &server_hello, + SSL3_MT_SERVER_HELLO)) + goto err; + + if (!CBB_add_u16(&server_hello, s->version)) + goto err; + if (!CBB_add_bytes(&server_hello, s->s3->server_random, + sizeof(s->s3->server_random))) + goto err; + + /* + * There are several cases for the session ID to send + * back in the server hello: + * + * - For session reuse from the session cache, + * we send back the old session ID. + * - If stateless session reuse (using a session ticket) + * is successful, we send back the client's "session ID" + * (which doesn't actually identify the session). + * - If it is a new session, we send back the new + * session ID. + * - However, if we want the new session to be single-use, + * we send back a 0-length session ID. + * + * s->hit is non-zero in either case of session reuse, + * so the following won't overwrite an ID that we're supposed + * to send back. + */ + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) + && !s->hit) + s->session->session_id_length = 0; + + sl = s->session->session_id_length; + if (sl > sizeof(s->session->session_id)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!CBB_add_u8_length_prefixed(&server_hello, &session_id)) + goto err; + if (!CBB_add_bytes(&session_id, s->session->session_id, sl)) + goto err; + + /* Cipher suite. */ + if (!CBB_add_u16(&server_hello, + ssl3_cipher_get_value(s->s3->hs.cipher))) + goto err; + + /* Compression method (null). */ + if (!CBB_add_u8(&server_hello, 0)) + goto err; + + /* TLS extensions */ + if (!tlsext_server_build(s, SSL_TLSEXT_MSG_SH, &server_hello)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + } + + /* SSL3_ST_SW_SRVR_HELLO_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_send_server_done(SSL *s) +{ + CBB cbb, done; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_SRVR_DONE_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &done, + SSL3_MT_SERVER_DONE)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_SRVR_DONE_B; + } + + /* SSL3_ST_SW_SRVR_DONE_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_send_server_kex_dhe(SSL *s, CBB *cbb) +{ + int nid = NID_dhKeyAgreement; + + tls_key_share_free(s->s3->hs.key_share); + if ((s->s3->hs.key_share = tls_key_share_new_nid(nid)) == NULL) + goto err; + + if (s->cert->dhe_params_auto != 0) { + size_t key_bits; + + if ((key_bits = ssl_dhe_params_auto_key_bits(s)) == 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INTERNAL_ERROR); + goto err; + } + tls_key_share_set_key_bits(s->s3->hs.key_share, + key_bits); + } else { + DH *dh_params = s->cert->dhe_params; + + if (dh_params == NULL && s->cert->dhe_params_cb != NULL) + dh_params = s->cert->dhe_params_cb(s, 0, + SSL_C_PKEYLENGTH(s->s3->hs.cipher)); + + if (dh_params == NULL) { + SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + + if (!tls_key_share_set_dh_params(s->s3->hs.key_share, dh_params)) + goto err; + } + + if (!tls_key_share_generate(s->s3->hs.key_share)) + goto err; + + if (!tls_key_share_params(s->s3->hs.key_share, cbb)) + goto err; + if (!tls_key_share_public(s->s3->hs.key_share, cbb)) + goto err; + + if (!tls_key_share_peer_security(s, s->s3->hs.key_share)) { + SSLerror(s, SSL_R_DH_KEY_TOO_SMALL); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return 0; + } + + return 1; + + err: + return 0; +} + +static int +ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) +{ + CBB public; + int nid; + + if (!tls1_get_supported_group(s, &nid)) { + SSLerror(s, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + + tls_key_share_free(s->s3->hs.key_share); + if ((s->s3->hs.key_share = tls_key_share_new_nid(nid)) == NULL) + goto err; + + if (!tls_key_share_generate(s->s3->hs.key_share)) + goto err; + + /* + * ECC key exchange - see RFC 8422, section 5.4. + */ + if (!CBB_add_u8(cbb, NAMED_CURVE_TYPE)) + goto err; + if (!CBB_add_u16(cbb, tls_key_share_group(s->s3->hs.key_share))) + goto err; + if (!CBB_add_u8_length_prefixed(cbb, &public)) + goto err; + if (!tls_key_share_public(s->s3->hs.key_share, &public)) + goto err; + if (!CBB_flush(cbb)) + goto err; + + return 1; + + err: + return 0; +} + +static int +ssl3_send_server_key_exchange(SSL *s) +{ + CBB cbb, cbb_signature, cbb_signed_params, server_kex; + CBS params; + const struct ssl_sigalg *sigalg = NULL; + unsigned char *signed_params = NULL; + size_t signed_params_len; + unsigned char *signature = NULL; + size_t signature_len = 0; + const EVP_MD *md = NULL; + unsigned long type; + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + int al; + + memset(&cbb, 0, sizeof(cbb)); + memset(&cbb_signed_params, 0, sizeof(cbb_signed_params)); + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if (s->s3->hs.state == SSL3_ST_SW_KEY_EXCH_A) { + + if (!ssl3_handshake_msg_start(s, &cbb, &server_kex, + SSL3_MT_SERVER_KEY_EXCHANGE)) + goto err; + + if (!CBB_init(&cbb_signed_params, 0)) + goto err; + + if (!CBB_add_bytes(&cbb_signed_params, s->s3->client_random, + SSL3_RANDOM_SIZE)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!CBB_add_bytes(&cbb_signed_params, s->s3->server_random, + SSL3_RANDOM_SIZE)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto err; + } + + type = s->s3->hs.cipher->algorithm_mkey; + if (type & SSL_kDHE) { + if (!ssl3_send_server_kex_dhe(s, &cbb_signed_params)) + goto err; + } else if (type & SSL_kECDHE) { + if (!ssl3_send_server_kex_ecdhe(s, &cbb_signed_params)) + goto err; + } else { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto fatal_err; + } + + if (!CBB_finish(&cbb_signed_params, &signed_params, + &signed_params_len)) + goto err; + + CBS_init(¶ms, signed_params, signed_params_len); + if (!CBS_skip(¶ms, 2 * SSL3_RANDOM_SIZE)) + goto err; + + if (!CBB_add_bytes(&server_kex, CBS_data(¶ms), + CBS_len(¶ms))) + goto err; + + /* Add signature unless anonymous. */ + if (!(s->s3->hs.cipher->algorithm_auth & SSL_aNULL)) { + if ((pkey = ssl_get_sign_pkey(s, s->s3->hs.cipher, + &md, &sigalg)) == NULL) { + al = SSL_AD_DECODE_ERROR; + goto fatal_err; + } + s->s3->hs.our_sigalg = sigalg; + + /* Send signature algorithm. */ + if (SSL_USE_SIGALGS(s)) { + if (!CBB_add_u16(&server_kex, sigalg->value)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_INTERNAL_ERROR); + goto fatal_err; + } + } + + if (!EVP_DigestSignInit(md_ctx, &pctx, md, NULL, pkey)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if ((sigalg->flags & SIGALG_FLAG_RSA_PSS) && + (!EVP_PKEY_CTX_set_rsa_padding(pctx, + RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if (!EVP_DigestSign(md_ctx, NULL, &signature_len, + signed_params, signed_params_len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if ((signature = calloc(1, signature_len)) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_DigestSign(md_ctx, signature, &signature_len, + signed_params, signed_params_len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + + if (!CBB_add_u16_length_prefixed(&server_kex, + &cbb_signature)) + goto err; + if (!CBB_add_bytes(&cbb_signature, signature, + signature_len)) + goto err; + } + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_KEY_EXCH_B; + } + + EVP_MD_CTX_free(md_ctx); + free(signature); + free(signed_params); + + return (ssl3_handshake_write(s)); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + CBB_cleanup(&cbb_signed_params); + CBB_cleanup(&cbb); + EVP_MD_CTX_free(md_ctx); + free(signature); + free(signed_params); + + return (-1); +} + +static int +ssl3_send_certificate_request(SSL *s) +{ + CBB cbb, cert_request, cert_types, sigalgs, cert_auth, dn; + STACK_OF(X509_NAME) *sk = NULL; + X509_NAME *name; + int i; + + /* + * Certificate Request - RFC 5246 section 7.4.4. + */ + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_CERT_REQ_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &cert_request, + SSL3_MT_CERTIFICATE_REQUEST)) + goto err; + + if (!CBB_add_u8_length_prefixed(&cert_request, &cert_types)) + goto err; + if (!ssl3_get_req_cert_types(s, &cert_types)) + goto err; + + if (SSL_USE_SIGALGS(s)) { + if (!CBB_add_u16_length_prefixed(&cert_request, + &sigalgs)) + goto err; + if (!ssl_sigalgs_build(s->s3->hs.negotiated_tls_version, + &sigalgs, SSL_get_security_level(s))) + goto err; + } + + if (!CBB_add_u16_length_prefixed(&cert_request, &cert_auth)) + goto err; + + sk = SSL_get_client_CA_list(s); + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + unsigned char *name_data; + size_t name_len; + + name = sk_X509_NAME_value(sk, i); + name_len = i2d_X509_NAME(name, NULL); + + if (!CBB_add_u16_length_prefixed(&cert_auth, &dn)) + goto err; + if (!CBB_add_space(&dn, &name_data, name_len)) + goto err; + if (i2d_X509_NAME(name, &name_data) != name_len) + goto err; + } + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_CERT_REQ_B; + } + + /* SSL3_ST_SW_CERT_REQ_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) +{ + unsigned char fakekey[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char *pms = NULL; + unsigned char *p; + size_t pms_len = 0; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + CBS enc_pms; + int decrypt_len; + int al = -1; + + arc4random_buf(fakekey, sizeof(fakekey)); + + fakekey[0] = s->s3->hs.peer_legacy_version >> 8; + fakekey[1] = s->s3->hs.peer_legacy_version & 0xff; + + pkey = s->cert->pkeys[SSL_PKEY_RSA].privatekey; + if (pkey == NULL || (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_MISSING_RSA_CERTIFICATE); + goto fatal_err; + } + + pms_len = RSA_size(rsa); + if (pms_len < SSL_MAX_MASTER_KEY_LENGTH) + goto err; + if ((pms = malloc(pms_len)) == NULL) + goto err; + p = pms; + + if (!CBS_get_u16_length_prefixed(cbs, &enc_pms)) + goto decode_err; + if (CBS_len(cbs) != 0 || CBS_len(&enc_pms) != RSA_size(rsa)) { + SSLerror(s, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto err; + } + + decrypt_len = RSA_private_decrypt(CBS_len(&enc_pms), CBS_data(&enc_pms), + pms, rsa, RSA_PKCS1_PADDING); + + ERR_clear_error(); + + if (decrypt_len != SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_DECODE_ERROR; + /* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */ + } + + if ((al == -1) && !((pms[0] == (s->s3->hs.peer_legacy_version >> 8)) && + (pms[1] == (s->s3->hs.peer_legacy_version & 0xff)))) { + /* + * The premaster secret must contain the same version number + * as the ClientHello to detect version rollback attacks + * (strangely, the protocol does not offer such protection for + * DH ciphersuites). + * + * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits the version + * number check as a "bad version oracle" -- an alert would + * reveal that the plaintext corresponding to some ciphertext + * made up by the adversary is properly formatted except that + * the version number is wrong. To avoid such attacks, we should + * treat this just like any other decryption error. + */ + al = SSL_AD_DECODE_ERROR; + /* SSLerror(s, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */ + } + + if (al != -1) { + /* + * Some decryption failure -- use random value instead + * as countermeasure against Bleichenbacher's attack + * on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). + */ + p = fakekey; + } + + if (!tls12_derive_master_secret(s, p, SSL_MAX_MASTER_KEY_LENGTH)) + goto err; + + freezero(pms, pms_len); + + return 1; + + decode_err: + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + freezero(pms, pms_len); + + return 0; +} + +static int +ssl3_get_client_kex_dhe(SSL *s, CBS *cbs) +{ + uint8_t *key = NULL; + size_t key_len = 0; + int decode_error, invalid_key; + int ret = 0; + + if (s->s3->hs.key_share == NULL) { + SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + + if (!tls_key_share_peer_public(s->s3->hs.key_share, cbs, + &decode_error, &invalid_key)) { + if (decode_error) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + } + goto err; + } + if (invalid_key) { + SSLerror(s, SSL_R_BAD_DH_PUB_KEY_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + goto err; + } + + if (!tls_key_share_derive(s->s3->hs.key_share, &key, &key_len)) + goto err; + + if (!tls12_derive_master_secret(s, key, key_len)) + goto err; + + ret = 1; + + err: + freezero(key, key_len); + + return ret; +} + +static int +ssl3_get_client_kex_ecdhe(SSL *s, CBS *cbs) +{ + uint8_t *key = NULL; + size_t key_len = 0; + int decode_error; + CBS public; + int ret = 0; + + if (s->s3->hs.key_share == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); + goto err; + } + + if (!CBS_get_u8_length_prefixed(cbs, &public)) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + goto err; + } + if (!tls_key_share_peer_public(s->s3->hs.key_share, &public, + &decode_error, NULL)) { + if (decode_error) { + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + } + goto err; + } + + if (!tls_key_share_derive(s->s3->hs.key_share, &key, &key_len)) + goto err; + + if (!tls12_derive_master_secret(s, key, key_len)) + goto err; + + ret = 1; + + err: + freezero(key, key_len); + + return ret; +} + +static int +ssl3_get_client_kex_gost(SSL *s, CBS *cbs) +{ + unsigned char premaster_secret[32]; + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *client_pubkey; + EVP_PKEY *pkey = NULL; + size_t outlen; + CBS gostblob; + + /* Get our certificate private key*/ +#ifndef OPENSSL_NO_GOST + if ((s->s3->hs.cipher->algorithm_auth & SSL_aGOST01) != 0) + pkey = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; +#endif + + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) + goto err; + if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) + goto err; + + /* + * If client certificate is present and is of the same type, + * maybe use it for key exchange. + * Don't mind errors from EVP_PKEY_derive_set_peer, because + * it is completely valid to use a client certificate for + * authorization only. + */ + if ((client_pubkey = X509_get0_pubkey(s->session->peer_cert)) != NULL) { + if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pubkey) <= 0) + ERR_clear_error(); + } + + /* Decrypt session key */ + if (!CBS_get_asn1(cbs, &gostblob, CBS_ASN1_SEQUENCE)) + goto decode_err; + if (CBS_len(cbs) != 0) + goto decode_err; + outlen = sizeof(premaster_secret); + if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, + CBS_data(&gostblob), CBS_len(&gostblob)) <= 0) { + SSLerror(s, SSL_R_DECRYPTION_FAILED); + goto err; + } + + if (!tls12_derive_master_secret(s, premaster_secret, + sizeof(premaster_secret))) + goto err; + + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, + 2, NULL) > 0) + s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; + + explicit_bzero(premaster_secret, sizeof(premaster_secret)); + EVP_PKEY_CTX_free(pkey_ctx); + + return 1; + + decode_err: + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + err: + explicit_bzero(premaster_secret, sizeof(premaster_secret)); + EVP_PKEY_CTX_free(pkey_ctx); + + return 0; +} + +static int +ssl3_get_client_key_exchange(SSL *s) +{ + unsigned long alg_k; + int al, ret; + CBS cbs; + + /* 2048 maxlen is a guess. How long a key does that permit? */ + if ((ret = ssl3_get_message(s, SSL3_ST_SR_KEY_EXCH_A, + SSL3_ST_SR_KEY_EXCH_B, SSL3_MT_CLIENT_KEY_EXCHANGE, 2048)) <= 0) + return ret; + + if (s->init_num < 0) + goto err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + alg_k = s->s3->hs.cipher->algorithm_mkey; + + if (alg_k & SSL_kRSA) { + if (!ssl3_get_client_kex_rsa(s, &cbs)) + goto err; + } else if (alg_k & SSL_kDHE) { + if (!ssl3_get_client_kex_dhe(s, &cbs)) + goto err; + } else if (alg_k & SSL_kECDHE) { + if (!ssl3_get_client_kex_ecdhe(s, &cbs)) + goto err; + } else if (alg_k & SSL_kGOST) { + if (!ssl3_get_client_kex_gost(s, &cbs)) + goto err; + } else { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerror(s, SSL_R_UNKNOWN_CIPHER_TYPE); + goto fatal_err; + } + + if (CBS_len(&cbs) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + goto fatal_err; + } + + return (1); + + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +static int +ssl3_get_cert_verify(SSL *s) +{ + CBS cbs, signature; + const struct ssl_sigalg *sigalg = NULL; + uint16_t sigalg_value = SIGALG_NONE; + EVP_PKEY *pkey; + X509 *peer_cert = NULL; + EVP_MD_CTX *mctx = NULL; + int al, verify; + const unsigned char *hdata; + size_t hdatalen; + int type = 0; + int ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_SR_CERT_VRFY_A, + SSL3_ST_SR_CERT_VRFY_B, -1, SSL3_RT_MAX_PLAIN_LENGTH)) <= 0) + return ret; + + ret = 0; + + if (s->init_num < 0) + goto err; + + if ((mctx = EVP_MD_CTX_new()) == NULL) + goto err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + peer_cert = s->session->peer_cert; + pkey = X509_get0_pubkey(peer_cert); + type = X509_certificate_type(peer_cert, pkey); + + if (s->s3->hs.tls12.message_type != SSL3_MT_CERTIFICATE_VERIFY) { + s->s3->hs.tls12.reuse_message = 1; + if (peer_cert != NULL) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_MISSING_VERIFY_MESSAGE); + goto fatal_err; + } + ret = 1; + goto end; + } + + if (peer_cert == NULL) { + SSLerror(s, SSL_R_NO_CLIENT_CERT_RECEIVED); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto fatal_err; + } + + if (!(type & EVP_PKT_SIGN)) { + SSLerror(s, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); + al = SSL_AD_ILLEGAL_PARAMETER; + goto fatal_err; + } + + if (s->s3->change_cipher_spec) { + SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto fatal_err; + } + + if (SSL_USE_SIGALGS(s)) { + if (!CBS_get_u16(&cbs, &sigalg_value)) + goto decode_err; + } + if (!CBS_get_u16_length_prefixed(&cbs, &signature)) + goto err; + if (CBS_len(&cbs) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_EXTRA_DATA_IN_MESSAGE); + goto fatal_err; + } + + if (CBS_len(&signature) > EVP_PKEY_size(pkey)) { + SSLerror(s, SSL_R_WRONG_SIGNATURE_SIZE); + al = SSL_AD_DECODE_ERROR; + goto fatal_err; + } + + if ((sigalg = ssl_sigalg_for_peer(s, pkey, + sigalg_value)) == NULL) { + al = SSL_AD_DECODE_ERROR; + goto fatal_err; + } + s->s3->hs.peer_sigalg = sigalg; + + if (SSL_USE_SIGALGS(s)) { + EVP_PKEY_CTX *pctx; + + if (!tls1_transcript_data(s, &hdata, &hdatalen)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + if (!EVP_DigestVerifyInit(mctx, &pctx, sigalg->md(), + NULL, pkey)) { + SSLerror(s, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + if ((sigalg->flags & SIGALG_FLAG_RSA_PSS) && + (!EVP_PKEY_CTX_set_rsa_padding(pctx, + RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))) { + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } +#ifndef OPENSSL_NO_GOST + if (sigalg->key_type == EVP_PKEY_GOSTR01 && + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, GOST_SIG_FORMAT_RS_LE, + NULL) <= 0) { + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } +#endif + if (EVP_DigestVerify(mctx, CBS_data(&signature), + CBS_len(&signature), hdata, hdatalen) <= 0) { + SSLerror(s, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + } else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + RSA *rsa; + + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_EVP_LIB); + goto fatal_err; + } + verify = RSA_verify(NID_md5_sha1, s->s3->hs.tls12.cert_verify, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, CBS_data(&signature), + CBS_len(&signature), rsa); + if (verify < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_BAD_RSA_DECRYPT); + goto fatal_err; + } + if (verify == 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_BAD_RSA_SIGNATURE); + goto fatal_err; + } + } else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + EC_KEY *eckey; + + if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerror(s, ERR_R_EVP_LIB); + goto fatal_err; + } + verify = ECDSA_verify(0, + &(s->s3->hs.tls12.cert_verify[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, CBS_data(&signature), + CBS_len(&signature), eckey); + if (verify <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_BAD_ECDSA_SIGNATURE); + goto fatal_err; + } +#ifndef OPENSSL_NO_GOST + } else if (EVP_PKEY_id(pkey) == NID_id_GostR3410_94 || + EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) { + unsigned char sigbuf[128]; + unsigned int siglen = sizeof(sigbuf); + EVP_PKEY_CTX *pctx; + const EVP_MD *md; + int nid; + + if (!tls1_transcript_data(s, &hdata, &hdatalen)) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || + !(md = EVP_get_digestbynid(nid))) { + SSLerror(s, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + SSLerror(s, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto fatal_err; + } + if (!EVP_DigestInit_ex(mctx, md, NULL) || + !EVP_DigestUpdate(mctx, hdata, hdatalen) || + !EVP_DigestFinal(mctx, sigbuf, &siglen) || + (EVP_PKEY_verify_init(pctx) <= 0) || + (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || + (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, + GOST_SIG_FORMAT_RS_LE, NULL) <= 0)) { + SSLerror(s, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + EVP_PKEY_CTX_free(pctx); + goto fatal_err; + } + if (EVP_PKEY_verify(pctx, CBS_data(&signature), + CBS_len(&signature), sigbuf, siglen) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_BAD_SIGNATURE); + EVP_PKEY_CTX_free(pctx); + goto fatal_err; + } + + EVP_PKEY_CTX_free(pctx); +#endif + } else { + SSLerror(s, ERR_R_INTERNAL_ERROR); + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + goto fatal_err; + } + + ret = 1; + if (0) { + decode_err: + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } + end: + tls1_transcript_free(s); + err: + EVP_MD_CTX_free(mctx); + + return (ret); +} + +static int +ssl3_get_client_certificate(SSL *s) +{ + CBS cbs, cert_list, cert_data; + STACK_OF(X509) *certs = NULL; + X509 *cert = NULL; + const uint8_t *p; + int al, ret; + + if ((ret = ssl3_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, + -1, s->max_cert_list)) <= 0) + return ret; + + ret = -1; + + if (s->s3->hs.tls12.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto fatal_err; + } + + /* + * If we asked for a client certificate and the client has none, + * it must respond with a certificate list of length zero. + */ + if (s->s3->hs.tls12.cert_request != 0) { + SSLerror(s, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto fatal_err; + } + s->s3->hs.tls12.reuse_message = 1; + return (1); + } + + if (s->s3->hs.tls12.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_WRONG_MESSAGE_TYPE); + goto fatal_err; + } + + if (s->init_num < 0) + goto decode_err; + + CBS_init(&cbs, s->init_msg, s->init_num); + + if (!CBS_get_u24_length_prefixed(&cbs, &cert_list)) + goto decode_err; + if (CBS_len(&cbs) != 0) + goto decode_err; + + /* + * A TLS client must send an empty certificate list, if no suitable + * certificate is available (rather than omitting the Certificate + * handshake message) - see RFC 5246 section 7.4.6. + */ + if (CBS_len(&cert_list) == 0) { + if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerror(s, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto fatal_err; + } + /* No client certificate so free transcript. */ + tls1_transcript_free(s); + goto done; + } + + if ((certs = sk_X509_new_null()) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + + while (CBS_len(&cert_list) > 0) { + if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) + goto decode_err; + p = CBS_data(&cert_data); + if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) { + SSLerror(s, ERR_R_ASN1_LIB); + goto err; + } + if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) + goto decode_err; + if (!sk_X509_push(certs, cert)) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + cert = NULL; + } + + if (ssl_verify_cert_chain(s, certs) <= 0) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerror(s, SSL_R_NO_CERTIFICATE_RETURNED); + goto fatal_err; + } + s->session->verify_result = s->verify_result; + ERR_clear_error(); + + if (!tls_process_peer_certs(s, certs)) + goto err; + + done: + ret = 1; + if (0) { + decode_err: + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } + err: + sk_X509_pop_free(certs, X509_free); + X509_free(cert); + + return (ret); +} + +static int +ssl3_send_server_certificate(SSL *s) +{ + CBB cbb, server_cert; + SSL_CERT_PKEY *cpk; + + /* + * Server Certificate - RFC 5246, section 7.4.2. + */ + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_CERT_A) { + if ((cpk = ssl_get_server_send_pkey(s)) == NULL) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return (0); + } + + if (!ssl3_handshake_msg_start(s, &cbb, &server_cert, + SSL3_MT_CERTIFICATE)) + goto err; + if (!ssl3_output_cert_chain(s, &server_cert, cpk)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_CERT_B; + } + + /* SSL3_ST_SW_CERT_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (0); +} + +/* send a new session ticket (not necessarily for a new session) */ +static int +ssl3_send_newsession_ticket(SSL *s) +{ + CBB cbb, session_ticket, ticket; + SSL_CTX *tctx = s->initial_ctx; + size_t enc_session_len, enc_session_max_len, hmac_len; + size_t session_len = 0; + unsigned char *enc_session = NULL, *session = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char key_name[16]; + unsigned char *hmac; + unsigned int hlen; + EVP_CIPHER_CTX *ctx = NULL; + HMAC_CTX *hctx = NULL; + int len; + + /* + * New Session Ticket - RFC 5077, section 3.3. + */ + + memset(&cbb, 0, sizeof(cbb)); + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + if ((hctx = HMAC_CTX_new()) == NULL) + goto err; + + if (s->s3->hs.state == SSL3_ST_SW_SESSION_TICKET_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &session_ticket, + SSL3_MT_NEWSESSION_TICKET)) + goto err; + + if (!SSL_SESSION_ticket(s->session, &session, &session_len)) + goto err; + if (session_len > 0xffff) + goto err; + + /* + * Initialize HMAC and cipher contexts. If callback is present + * it does all the work, otherwise use generated values from + * parent context. + */ + if (tctx->tlsext_ticket_key_cb != NULL) { + if (tctx->tlsext_ticket_key_cb(s, + key_name, iv, ctx, hctx, 1) < 0) + goto err; + } else { + arc4random_buf(iv, 16); + EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, iv); + HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, + 16, EVP_sha256(), NULL); + memcpy(key_name, tctx->tlsext_tick_key_name, 16); + } + + /* Encrypt the session state. */ + enc_session_max_len = session_len + EVP_MAX_BLOCK_LENGTH; + if ((enc_session = calloc(1, enc_session_max_len)) == NULL) + goto err; + enc_session_len = 0; + if (!EVP_EncryptUpdate(ctx, enc_session, &len, session, + session_len)) + goto err; + enc_session_len += len; + if (!EVP_EncryptFinal_ex(ctx, enc_session + enc_session_len, + &len)) + goto err; + enc_session_len += len; + + if (enc_session_len > enc_session_max_len) + goto err; + + /* Generate the HMAC. */ + if (!HMAC_Update(hctx, key_name, sizeof(key_name))) + goto err; + if (!HMAC_Update(hctx, iv, EVP_CIPHER_CTX_iv_length(ctx))) + goto err; + if (!HMAC_Update(hctx, enc_session, enc_session_len)) + goto err; + + if ((hmac_len = HMAC_size(hctx)) <= 0) + goto err; + + /* + * Ticket lifetime hint (advisory only): + * We leave this unspecified for resumed session + * (for simplicity), and guess that tickets for new + * sessions will live as long as their sessions. + */ + if (!CBB_add_u32(&session_ticket, + s->hit ? 0 : s->session->timeout)) + goto err; + + if (!CBB_add_u16_length_prefixed(&session_ticket, &ticket)) + goto err; + if (!CBB_add_bytes(&ticket, key_name, sizeof(key_name))) + goto err; + if (!CBB_add_bytes(&ticket, iv, EVP_CIPHER_CTX_iv_length(ctx))) + goto err; + if (!CBB_add_bytes(&ticket, enc_session, enc_session_len)) + goto err; + if (!CBB_add_space(&ticket, &hmac, hmac_len)) + goto err; + + if (!HMAC_Final(hctx, hmac, &hlen)) + goto err; + if (hlen != hmac_len) + goto err; + + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_SESSION_TICKET_B; + } + + EVP_CIPHER_CTX_free(ctx); + HMAC_CTX_free(hctx); + freezero(session, session_len); + free(enc_session); + + /* SSL3_ST_SW_SESSION_TICKET_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + EVP_CIPHER_CTX_free(ctx); + HMAC_CTX_free(hctx); + freezero(session, session_len); + free(enc_session); + + return (-1); +} + +static int +ssl3_send_cert_status(SSL *s) +{ + CBB cbb, certstatus, ocspresp; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_CERT_STATUS_A) { + if (!ssl3_handshake_msg_start(s, &cbb, &certstatus, + SSL3_MT_CERTIFICATE_STATUS)) + goto err; + if (!CBB_add_u8(&certstatus, s->tlsext_status_type)) + goto err; + if (!CBB_add_u24_length_prefixed(&certstatus, &ocspresp)) + goto err; + if (!CBB_add_bytes(&ocspresp, s->tlsext_ocsp_resp, + s->tlsext_ocsp_resp_len)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_CERT_STATUS_B; + } + + /* SSL3_ST_SW_CERT_STATUS_B */ + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} + +static int +ssl3_send_server_change_cipher_spec(SSL *s) +{ + size_t outlen; + CBB cbb; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_CHANGE_A) { + if (!CBB_init_fixed(&cbb, s->init_buf->data, + s->init_buf->length)) + goto err; + if (!CBB_add_u8(&cbb, SSL3_MT_CCS)) + goto err; + if (!CBB_finish(&cbb, NULL, &outlen)) + goto err; + + if (outlen > INT_MAX) + goto err; + + s->init_num = (int)outlen; + s->init_off = 0; + + if (SSL_is_dtls(s)) { + s->d1->handshake_write_seq = + s->d1->next_handshake_write_seq; + dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, + s->d1->handshake_write_seq, 0, 0); + dtls1_buffer_message(s, 1); + } + + s->s3->hs.state = SSL3_ST_SW_CHANGE_B; + } + + /* SSL3_ST_SW_CHANGE_B */ + return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); + + err: + CBB_cleanup(&cbb); + + return -1; +} + +static int +ssl3_get_client_finished(SSL *s) +{ + int al, md_len, ret; + CBS cbs; + + /* should actually be 36+4 :-) */ + if ((ret = ssl3_get_message(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B, SSL3_MT_FINISHED, 64)) <= 0) + return ret; + + /* If this occurs, we have missed a message */ + if (!s->s3->change_cipher_spec) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS); + goto fatal_err; + } + s->s3->change_cipher_spec = 0; + + md_len = TLS1_FINISH_MAC_LENGTH; + + if (s->init_num < 0) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_DIGEST_LENGTH); + goto fatal_err; + } + + CBS_init(&cbs, s->init_msg, s->init_num); + + if (s->s3->hs.peer_finished_len != md_len || + CBS_len(&cbs) != md_len) { + al = SSL_AD_DECODE_ERROR; + SSLerror(s, SSL_R_BAD_DIGEST_LENGTH); + goto fatal_err; + } + + if (!CBS_mem_equal(&cbs, s->s3->hs.peer_finished, CBS_len(&cbs))) { + al = SSL_AD_DECRYPT_ERROR; + SSLerror(s, SSL_R_DIGEST_CHECK_FAILED); + goto fatal_err; + } + + /* Copy finished so we can use it for renegotiation checks. */ + OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, + s->s3->hs.peer_finished, md_len); + s->s3->previous_client_finished_len = md_len; + + return (1); + fatal_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (0); +} + +static int +ssl3_send_server_finished(SSL *s) +{ + CBB cbb, finished; + + memset(&cbb, 0, sizeof(cbb)); + + if (s->s3->hs.state == SSL3_ST_SW_FINISHED_A) { + if (!tls12_derive_finished(s)) + goto err; + + /* Copy finished so we can use it for renegotiation checks. */ + memcpy(s->s3->previous_server_finished, + s->s3->hs.finished, s->s3->hs.finished_len); + s->s3->previous_server_finished_len = s->s3->hs.finished_len; + + if (!ssl3_handshake_msg_start(s, &cbb, &finished, + SSL3_MT_FINISHED)) + goto err; + if (!CBB_add_bytes(&finished, s->s3->hs.finished, + s->s3->hs.finished_len)) + goto err; + if (!ssl3_handshake_msg_finish(s, &cbb)) + goto err; + + s->s3->hs.state = SSL3_ST_SW_FINISHED_B; + } + + return (ssl3_handshake_write(s)); + + err: + CBB_cleanup(&cbb); + + return (-1); +} diff --git a/Libraries/libressl/ssl/ssl_stat.c b/Libraries/libressl/ssl/ssl_stat.c new file mode 100644 index 000000000..803b83bb9 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_stat.c @@ -0,0 +1,797 @@ +/* $OpenBSD: ssl_stat.c,v 1.21 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include "ssl_local.h" + +const char * +SSL_state_string_long(const SSL *s) +{ + const char *str; + + switch (s->s3->hs.state) { + case SSL_ST_BEFORE: + str = "before SSL initialization"; + break; + case SSL_ST_ACCEPT: + str = "before accept initialization"; + break; + case SSL_ST_CONNECT: + str = "before connect initialization"; + break; + case SSL_ST_OK: + str = "SSL negotiation finished successfully"; + break; + case SSL_ST_RENEGOTIATE: + str = "SSL renegotiate ciphers"; + break; + case SSL_ST_BEFORE|SSL_ST_CONNECT: + str = "before/connect initialization"; + break; + case SSL_ST_OK|SSL_ST_CONNECT: + str = "ok/connect SSL initialization"; + break; + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + str = "before/accept initialization"; + break; + case SSL_ST_OK|SSL_ST_ACCEPT: + str = "ok/accept SSL initialization"; + break; + + /* SSLv3 additions */ + case SSL3_ST_CW_CLNT_HELLO_A: + str = "SSLv3 write client hello A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "SSLv3 write client hello B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "SSLv3 read server hello A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "SSLv3 read server hello B"; + break; + case SSL3_ST_CR_CERT_A: + str = "SSLv3 read server certificate A"; + break; + case SSL3_ST_CR_CERT_B: + str = "SSLv3 read server certificate B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "SSLv3 read server key exchange A"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "SSLv3 read server key exchange B"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "SSLv3 read server certificate request A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "SSLv3 read server certificate request B"; + break; + case SSL3_ST_CR_SESSION_TICKET_A: + str = "SSLv3 read server session ticket A"; + break; + case SSL3_ST_CR_SESSION_TICKET_B: + str = "SSLv3 read server session ticket B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "SSLv3 read server done A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "SSLv3 read server done B"; + break; + case SSL3_ST_CW_CERT_A: + str = "SSLv3 write client certificate A"; + break; + case SSL3_ST_CW_CERT_B: + str = "SSLv3 write client certificate B"; + break; + case SSL3_ST_CW_CERT_C: + str = "SSLv3 write client certificate C"; + break; + case SSL3_ST_CW_CERT_D: + str = "SSLv3 write client certificate D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "SSLv3 write client key exchange A"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "SSLv3 write client key exchange B"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "SSLv3 write certificate verify A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "SSLv3 write certificate verify B"; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_SW_CHANGE_A: + str = "SSLv3 write change cipher spec A"; + break; + case SSL3_ST_CW_CHANGE_B: + case SSL3_ST_SW_CHANGE_B: + str = "SSLv3 write change cipher spec B"; + break; + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_SW_FINISHED_A: + str = "SSLv3 write finished A"; + break; + case SSL3_ST_CW_FINISHED_B: + case SSL3_ST_SW_FINISHED_B: + str = "SSLv3 write finished B"; + break; + case SSL3_ST_CR_CHANGE_A: + case SSL3_ST_SR_CHANGE_A: + str = "SSLv3 read change cipher spec A"; + break; + case SSL3_ST_CR_CHANGE_B: + case SSL3_ST_SR_CHANGE_B: + str = "SSLv3 read change cipher spec B"; + break; + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_SR_FINISHED_A: + str = "SSLv3 read finished A"; + break; + case SSL3_ST_CR_FINISHED_B: + case SSL3_ST_SR_FINISHED_B: + str = "SSLv3 read finished B"; + break; + + case SSL3_ST_CW_FLUSH: + case SSL3_ST_SW_FLUSH: + str = "SSLv3 flush data"; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + str = "SSLv3 read client hello A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "SSLv3 read client hello B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "SSLv3 read client hello C"; + break; + case SSL3_ST_SW_HELLO_REQ_A: + str = "SSLv3 write hello request A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "SSLv3 write hello request B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "SSLv3 write hello request C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "SSLv3 write server hello A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "SSLv3 write server hello B"; + break; + case SSL3_ST_SW_CERT_A: + str = "SSLv3 write certificate A"; + break; + case SSL3_ST_SW_CERT_B: + str = "SSLv3 write certificate B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "SSLv3 write key exchange A"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "SSLv3 write key exchange B"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "SSLv3 write certificate request A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "SSLv3 write certificate request B"; + break; + case SSL3_ST_SW_SESSION_TICKET_A: + str = "SSLv3 write session ticket A"; + break; + case SSL3_ST_SW_SESSION_TICKET_B: + str = "SSLv3 write session ticket B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "SSLv3 write server done A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "SSLv3 write server done B"; + break; + case SSL3_ST_SR_CERT_A: + str = "SSLv3 read client certificate A"; + break; + case SSL3_ST_SR_CERT_B: + str = "SSLv3 read client certificate B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "SSLv3 read client key exchange A"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "SSLv3 read client key exchange B"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "SSLv3 read certificate verify A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "SSLv3 read certificate verify B"; + break; + + /* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 read hello verify request A"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 read hello verify request B"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 write hello verify request A"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 write hello verify request B"; + break; + + default: + str = "unknown state"; + break; + } + return (str); +} +LSSL_ALIAS(SSL_state_string_long); + +const char * +SSL_rstate_string_long(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "read header"; + break; + case SSL_ST_READ_BODY: + str = "read body"; + break; + case SSL_ST_READ_DONE: + str = "read done"; + break; + default: + str = "unknown"; + break; + } + return (str); +} +LSSL_ALIAS(SSL_rstate_string_long); + +const char * +SSL_state_string(const SSL *s) +{ + const char *str; + + switch (s->s3->hs.state) { + case SSL_ST_BEFORE: + str = "PINIT "; + break; + case SSL_ST_ACCEPT: + str = "AINIT "; + break; + case SSL_ST_CONNECT: + str = "CINIT "; + break; + case SSL_ST_OK: + str = "SSLOK "; + break; + + /* SSLv3 additions */ + case SSL3_ST_SW_FLUSH: + case SSL3_ST_CW_FLUSH: + str = "3FLUSH"; + break; + case SSL3_ST_CW_CLNT_HELLO_A: + str = "3WCH_A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "3WCH_B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "3RSH_A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "3RSH_B"; + break; + case SSL3_ST_CR_CERT_A: + str = "3RSC_A"; + break; + case SSL3_ST_CR_CERT_B: + str = "3RSC_B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "3RSKEA"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "3RSKEB"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "3RCR_A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "3RCR_B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "3RSD_A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "3RSD_B"; + break; + case SSL3_ST_CW_CERT_A: + str = "3WCC_A"; + break; + case SSL3_ST_CW_CERT_B: + str = "3WCC_B"; + break; + case SSL3_ST_CW_CERT_C: + str = "3WCC_C"; + break; + case SSL3_ST_CW_CERT_D: + str = "3WCC_D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "3WCKEA"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "3WCKEB"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "3WCV_A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "3WCV_B"; + break; + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_CW_CHANGE_A: + str = "3WCCSA"; + break; + case SSL3_ST_SW_CHANGE_B: + case SSL3_ST_CW_CHANGE_B: + str = "3WCCSB"; + break; + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_CW_FINISHED_A: + str = "3WFINA"; + break; + case SSL3_ST_SW_FINISHED_B: + case SSL3_ST_CW_FINISHED_B: + str = "3WFINB"; + break; + case SSL3_ST_SR_CHANGE_A: + case SSL3_ST_CR_CHANGE_A: + str = "3RCCSA"; + break; + case SSL3_ST_SR_CHANGE_B: + case SSL3_ST_CR_CHANGE_B: + str = "3RCCSB"; + break; + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_CR_FINISHED_A: + str = "3RFINA"; + break; + case SSL3_ST_SR_FINISHED_B: + case SSL3_ST_CR_FINISHED_B: + str = "3RFINB"; + break; + + case SSL3_ST_SW_HELLO_REQ_A: + str = "3WHR_A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "3WHR_B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "3WHR_C"; + break; + case SSL3_ST_SR_CLNT_HELLO_A: + str = "3RCH_A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "3RCH_B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "3RCH_C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "3WSH_A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "3WSH_B"; + break; + case SSL3_ST_SW_CERT_A: + str = "3WSC_A"; + break; + case SSL3_ST_SW_CERT_B: + str = "3WSC_B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "3WSKEA"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "3WSKEB"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "3WCR_A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "3WCR_B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "3WSD_A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "3WSD_B"; + break; + case SSL3_ST_SR_CERT_A: + str = "3RCC_A"; + break; + case SSL3_ST_SR_CERT_B: + str = "3RCC_B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "3RCKEA"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "3RCKEB"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "3RCV_A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "3RCV_B"; + break; + + /* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DRCHVA"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DRCHVB"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DWCHVA"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DWCHVB"; + break; + + default: + str = "UNKWN "; + break; + } + return (str); +} +LSSL_ALIAS(SSL_state_string); + +const char * +SSL_alert_type_string_long(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("warning"); + else if (value == SSL3_AL_FATAL) + return ("fatal"); + else + return ("unknown"); +} +LSSL_ALIAS(SSL_alert_type_string_long); + +const char * +SSL_alert_type_string(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("W"); + else if (value == SSL3_AL_FATAL) + return ("F"); + else + return ("U"); +} +LSSL_ALIAS(SSL_alert_type_string); + +const char * +SSL_alert_desc_string(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL_AD_CLOSE_NOTIFY: + str = "CN"; + break; + case SSL_AD_UNEXPECTED_MESSAGE: + str = "UM"; + break; + case SSL_AD_BAD_RECORD_MAC: + str = "BM"; + break; + case SSL_AD_DECOMPRESSION_FAILURE: + str = "DF"; + break; + case SSL_AD_HANDSHAKE_FAILURE: + str = "HF"; + break; + case SSL_AD_BAD_CERTIFICATE: + str = "BC"; + break; + case SSL_AD_UNSUPPORTED_CERTIFICATE: + str = "UC"; + break; + case SSL_AD_CERTIFICATE_REVOKED: + str = "CR"; + break; + case SSL_AD_CERTIFICATE_EXPIRED: + str = "CE"; + break; + case SSL_AD_CERTIFICATE_UNKNOWN: + str = "CU"; + break; + case SSL_AD_ILLEGAL_PARAMETER: + str = "IP"; + break; + case SSL_AD_RECORD_OVERFLOW: + str = "RO"; + break; + case SSL_AD_UNKNOWN_CA: + str = "CA"; + break; + case SSL_AD_ACCESS_DENIED: + str = "AD"; + break; + case SSL_AD_DECODE_ERROR: + str = "DE"; + break; + case SSL_AD_DECRYPT_ERROR: + str = "CY"; + break; + case SSL_AD_PROTOCOL_VERSION: + str = "PV"; + break; + case SSL_AD_INSUFFICIENT_SECURITY: + str = "IS"; + break; + case SSL_AD_INTERNAL_ERROR: + str = "IE"; + break; + case SSL_AD_USER_CANCELLED: + str = "US"; + break; + case SSL_AD_NO_RENEGOTIATION: + str = "NR"; + break; + case SSL_AD_MISSING_EXTENSION: + str = "ME"; + break; + case SSL_AD_UNSUPPORTED_EXTENSION: + str = "UE"; + break; + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + str = "CO"; + break; + case SSL_AD_UNRECOGNIZED_NAME: + str = "UN"; + break; + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "BR"; + break; + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "BH"; + break; + case SSL_AD_UNKNOWN_PSK_IDENTITY: + str = "UP"; + break; + default: + str = "UK"; + break; + } + return (str); +} +LSSL_ALIAS(SSL_alert_desc_string); + +const char * +SSL_alert_desc_string_long(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL_AD_CLOSE_NOTIFY: + str = "close notify"; + break; + case SSL_AD_UNEXPECTED_MESSAGE: + str = "unexpected_message"; + break; + case SSL_AD_BAD_RECORD_MAC: + str = "bad record mac"; + break; + case SSL_AD_DECOMPRESSION_FAILURE: + str = "decompression failure"; + break; + case SSL_AD_HANDSHAKE_FAILURE: + str = "handshake failure"; + break; + case SSL_AD_BAD_CERTIFICATE: + str = "bad certificate"; + break; + case SSL_AD_UNSUPPORTED_CERTIFICATE: + str = "unsupported certificate"; + break; + case SSL_AD_CERTIFICATE_REVOKED: + str = "certificate revoked"; + break; + case SSL_AD_CERTIFICATE_EXPIRED: + str = "certificate expired"; + break; + case SSL_AD_CERTIFICATE_UNKNOWN: + str = "certificate unknown"; + break; + case SSL_AD_ILLEGAL_PARAMETER: + str = "illegal parameter"; + break; + case SSL_AD_RECORD_OVERFLOW: + str = "record overflow"; + break; + case SSL_AD_UNKNOWN_CA: + str = "unknown CA"; + break; + case SSL_AD_ACCESS_DENIED: + str = "access denied"; + break; + case SSL_AD_DECODE_ERROR: + str = "decode error"; + break; + case SSL_AD_DECRYPT_ERROR: + str = "decrypt error"; + break; + case SSL_AD_PROTOCOL_VERSION: + str = "protocol version"; + break; + case SSL_AD_INSUFFICIENT_SECURITY: + str = "insufficient security"; + break; + case SSL_AD_INTERNAL_ERROR: + str = "internal error"; + break; + case SSL_AD_USER_CANCELLED: + str = "user canceled"; + break; + case SSL_AD_NO_RENEGOTIATION: + str = "no renegotiation"; + break; + case SSL_AD_MISSING_EXTENSION: + str = "missing extension"; + break; + case SSL_AD_UNSUPPORTED_EXTENSION: + str = "unsupported extension"; + break; + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + str = "certificate unobtainable"; + break; + case SSL_AD_UNRECOGNIZED_NAME: + str = "unrecognized name"; + break; + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "bad certificate status response"; + break; + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "bad certificate hash value"; + break; + case SSL_AD_UNKNOWN_PSK_IDENTITY: + str = "unknown PSK identity"; + break; + default: + str = "unknown"; + break; + } + return (str); +} +LSSL_ALIAS(SSL_alert_desc_string_long); + +const char * +SSL_rstate_string(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "RH"; + break; + case SSL_ST_READ_BODY: + str = "RB"; + break; + case SSL_ST_READ_DONE: + str = "RD"; + break; + default: + str = "unknown"; + break; + } + return (str); +} +LSSL_ALIAS(SSL_rstate_string); diff --git a/Libraries/libressl/ssl/ssl_tlsext.c b/Libraries/libressl/ssl/ssl_tlsext.c new file mode 100644 index 000000000..5dd4b69dc --- /dev/null +++ b/Libraries/libressl/ssl/ssl_tlsext.c @@ -0,0 +1,2519 @@ +/* $OpenBSD: ssl_tlsext.c,v 1.137 2023/04/28 18:14:59 tb Exp $ */ +/* + * Copyright (c) 2016, 2017, 2019 Joel Sing + * Copyright (c) 2017 Doug Hogan + * Copyright (c) 2018-2019 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include + +#include +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" + +#define TLSEXT_TYPE_alpn TLSEXT_TYPE_application_layer_protocol_negotiation + +/* + * Supported Application-Layer Protocol Negotiation - RFC 7301 + */ + +static int +tlsext_alpn_client_needs(SSL *s, uint16_t msg_type) +{ + /* ALPN protos have been specified and this is the initial handshake */ + return s->alpn_client_proto_list != NULL && + s->s3->hs.finished_len == 0; +} + +static int +tlsext_alpn_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB protolist; + + if (!CBB_add_u16_length_prefixed(cbb, &protolist)) + return 0; + + if (!CBB_add_bytes(&protolist, s->alpn_client_proto_list, + s->alpn_client_proto_list_len)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +int +tlsext_alpn_check_format(CBS *cbs) +{ + CBS proto_name_list; + + if (CBS_len(cbs) == 0) + return 0; + + CBS_dup(cbs, &proto_name_list); + while (CBS_len(&proto_name_list) > 0) { + CBS proto_name; + + if (!CBS_get_u8_length_prefixed(&proto_name_list, &proto_name)) + return 0; + if (CBS_len(&proto_name) == 0) + return 0; + } + + return 1; +} + +static int +tlsext_alpn_server_parse(SSL *s, uint16_t msg_types, CBS *cbs, int *alert) +{ + CBS alpn, selected_cbs; + const unsigned char *selected; + unsigned char selected_len; + int r; + + if (!CBS_get_u16_length_prefixed(cbs, &alpn)) + return 0; + + if (!tlsext_alpn_check_format(&alpn)) + return 0; + + if (s->ctx->alpn_select_cb == NULL) + return 1; + + /* + * XXX - A few things should be considered here: + * 1. Ensure that the same protocol is selected on session resumption. + * 2. Should the callback be called even if no ALPN extension was sent? + * 3. TLSv1.2 and earlier: ensure that SNI has already been processed. + */ + r = s->ctx->alpn_select_cb(s, &selected, &selected_len, + CBS_data(&alpn), CBS_len(&alpn), + s->ctx->alpn_select_cb_arg); + + if (r == SSL_TLSEXT_ERR_OK) { + CBS_init(&selected_cbs, selected, selected_len); + + if (!CBS_stow(&selected_cbs, &s->s3->alpn_selected, + &s->s3->alpn_selected_len)) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + return 1; + } + + /* On SSL_TLSEXT_ERR_NOACK behave as if no callback was present. */ + if (r == SSL_TLSEXT_ERR_NOACK) + return 1; + + *alert = SSL_AD_NO_APPLICATION_PROTOCOL; + SSLerror(s, SSL_R_NO_APPLICATION_PROTOCOL); + + return 0; +} + +static int +tlsext_alpn_server_needs(SSL *s, uint16_t msg_type) +{ + return s->s3->alpn_selected != NULL; +} + +static int +tlsext_alpn_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB list, selected; + + if (!CBB_add_u16_length_prefixed(cbb, &list)) + return 0; + + if (!CBB_add_u8_length_prefixed(&list, &selected)) + return 0; + + if (!CBB_add_bytes(&selected, s->s3->alpn_selected, + s->s3->alpn_selected_len)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_alpn_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS list, proto; + + if (s->alpn_client_proto_list == NULL) { + *alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + if (!CBS_get_u16_length_prefixed(cbs, &list)) + return 0; + + if (!CBS_get_u8_length_prefixed(&list, &proto)) + return 0; + + if (CBS_len(&list) != 0) + return 0; + if (CBS_len(&proto) == 0) + return 0; + + if (!CBS_stow(&proto, &s->s3->alpn_selected, &s->s3->alpn_selected_len)) + return 0; + + return 1; +} + +/* + * Supported Groups - RFC 7919 section 2 + */ +static int +tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type) +{ + return ssl_has_ecc_ciphers(s) || + (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION); +} + +static int +tlsext_supportedgroups_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + const uint16_t *groups; + size_t groups_len; + CBB grouplist; + int i; + + tls1_get_group_list(s, 0, &groups, &groups_len); + if (groups_len == 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!CBB_add_u16_length_prefixed(cbb, &grouplist)) + return 0; + + for (i = 0; i < groups_len; i++) { + if (!ssl_security_supported_group(s, groups[i])) + continue; + if (!CBB_add_u16(&grouplist, groups[i])) + return 0; + } + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_supportedgroups_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, + int *alert) +{ + CBS grouplist; + uint16_t *groups; + size_t groups_len; + int i; + + if (!CBS_get_u16_length_prefixed(cbs, &grouplist)) + return 0; + + groups_len = CBS_len(&grouplist); + if (groups_len == 0 || groups_len % 2 != 0) + return 0; + groups_len /= 2; + + if (s->hit) + return 1; + + if (s->s3->hs.tls13.hrr) { + if (s->session->tlsext_supportedgroups == NULL) { + *alert = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + /* + * The ClientHello extension hashing ensures that the client + * did not change its list of supported groups. + */ + + return 1; + } + + if (s->session->tlsext_supportedgroups != NULL) + return 0; /* XXX internal error? */ + + if ((groups = reallocarray(NULL, groups_len, sizeof(uint16_t))) == NULL) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + for (i = 0; i < groups_len; i++) { + if (!CBS_get_u16(&grouplist, &groups[i])) { + free(groups); + return 0; + } + } + + if (CBS_len(&grouplist) != 0) { + free(groups); + return 0; + } + + s->session->tlsext_supportedgroups = groups; + s->session->tlsext_supportedgroups_length = groups_len; + + return 1; +} + +/* This extension is never used by the server. */ +static int +tlsext_supportedgroups_server_needs(SSL *s, uint16_t msg_type) +{ + return 0; +} + +static int +tlsext_supportedgroups_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return 0; +} + +static int +tlsext_supportedgroups_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, + int *alert) +{ + /* + * Servers should not send this extension per the RFC. + * + * However, certain F5 BIG-IP systems incorrectly send it. This bug is + * from at least 2014 but as of 2017, there are still large sites with + * this unpatched in production. As a result, we need to currently skip + * over the extension and ignore its content: + * + * https://support.f5.com/csp/article/K37345003 + */ + if (!CBS_skip(cbs, CBS_len(cbs))) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + return 1; +} + +/* + * Supported Point Formats Extension - RFC 4492 section 5.1.2 + */ +static int +tlsext_ecpf_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB ecpf; + size_t formats_len; + const uint8_t *formats; + + tls1_get_formatlist(s, 0, &formats, &formats_len); + + if (formats_len == 0) { + SSLerror(s, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!CBB_add_u8_length_prefixed(cbb, &ecpf)) + return 0; + if (!CBB_add_bytes(&ecpf, formats, formats_len)) + return 0; + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_ecpf_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS ecpf; + + if (!CBS_get_u8_length_prefixed(cbs, &ecpf)) + return 0; + if (CBS_len(&ecpf) == 0) + return 0; + + /* Must contain uncompressed (0) - RFC 8422, section 5.1.2. */ + if (!CBS_contains_zero_byte(&ecpf)) { + SSLerror(s, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (!s->hit) { + if (!CBS_stow(&ecpf, &(s->session->tlsext_ecpointformatlist), + &(s->session->tlsext_ecpointformatlist_length))) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + return 1; +} + +static int +tlsext_ecpf_client_needs(SSL *s, uint16_t msg_type) +{ + return ssl_has_ecc_ciphers(s); +} + +static int +tlsext_ecpf_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return tlsext_ecpf_build(s, msg_type, cbb); +} + +static int +tlsext_ecpf_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + return tlsext_ecpf_parse(s, msg_type, cbs, alert); +} + +static int +tlsext_ecpf_server_needs(SSL *s, uint16_t msg_type) +{ + return ssl_using_ecc_cipher(s); +} + +static int +tlsext_ecpf_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return tlsext_ecpf_build(s, msg_type, cbb); +} + +static int +tlsext_ecpf_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + return tlsext_ecpf_parse(s, msg_type, cbs, alert); +} + +/* + * Renegotiation Indication - RFC 5746. + */ +static int +tlsext_ri_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->renegotiate); +} + +static int +tlsext_ri_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB reneg; + + if (!CBB_add_u8_length_prefixed(cbb, &reneg)) + return 0; + if (!CBB_add_bytes(&reneg, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) + return 0; + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_ri_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS reneg; + + if (!CBS_get_u8_length_prefixed(cbs, &reneg)) { + SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + + if (!CBS_mem_equal(&reneg, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); + *alert = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + s->s3->renegotiate_seen = 1; + s->s3->send_connection_binding = 1; + + return 1; +} + +static int +tlsext_ri_server_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION && + s->s3->send_connection_binding); +} + +static int +tlsext_ri_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB reneg; + + if (!CBB_add_u8_length_prefixed(cbb, &reneg)) + return 0; + if (!CBB_add_bytes(&reneg, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) + return 0; + if (!CBB_add_bytes(&reneg, s->s3->previous_server_finished, + s->s3->previous_server_finished_len)) + return 0; + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_ri_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS reneg, prev_client, prev_server; + + /* + * Ensure that the previous client and server values are both not + * present, or that they are both present. + */ + if ((s->s3->previous_client_finished_len == 0 && + s->s3->previous_server_finished_len != 0) || + (s->s3->previous_client_finished_len != 0 && + s->s3->previous_server_finished_len == 0)) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + if (!CBS_get_u8_length_prefixed(cbs, &reneg)) { + SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + if (!CBS_get_bytes(&reneg, &prev_client, + s->s3->previous_client_finished_len)) { + SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + if (!CBS_get_bytes(&reneg, &prev_server, + s->s3->previous_server_finished_len)) { + SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + if (CBS_len(&reneg) != 0) { + SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + + if (!CBS_mem_equal(&prev_client, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); + *alert = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + if (!CBS_mem_equal(&prev_server, s->s3->previous_server_finished, + s->s3->previous_server_finished_len)) { + SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); + *alert = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + s->s3->renegotiate_seen = 1; + s->s3->send_connection_binding = 1; + + return 1; +} + +/* + * Signature Algorithms - RFC 5246 section 7.4.1.4.1. + */ +static int +tlsext_sigalgs_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.our_max_tls_version >= TLS1_2_VERSION); +} + +static int +tlsext_sigalgs_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + uint16_t tls_version = s->s3->hs.negotiated_tls_version; + CBB sigalgs; + + if (msg_type == SSL_TLSEXT_MSG_CH) + tls_version = s->s3->hs.our_min_tls_version; + + if (!CBB_add_u16_length_prefixed(cbb, &sigalgs)) + return 0; + if (!ssl_sigalgs_build(tls_version, &sigalgs, SSL_get_security_level(s))) + return 0; + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_sigalgs_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS sigalgs; + + if (!CBS_get_u16_length_prefixed(cbs, &sigalgs)) + return 0; + if (CBS_len(&sigalgs) % 2 != 0 || CBS_len(&sigalgs) > 64) + return 0; + if (!CBS_stow(&sigalgs, &s->s3->hs.sigalgs, &s->s3->hs.sigalgs_len)) + return 0; + + return 1; +} + +static int +tlsext_sigalgs_server_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION); +} + +static int +tlsext_sigalgs_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB sigalgs; + + if (!CBB_add_u16_length_prefixed(cbb, &sigalgs)) + return 0; + if (!ssl_sigalgs_build(s->s3->hs.negotiated_tls_version, &sigalgs, + SSL_get_security_level(s))) + return 0; + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_sigalgs_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS sigalgs; + + if (ssl_effective_tls_version(s) < TLS1_3_VERSION) + return 0; + + if (!CBS_get_u16_length_prefixed(cbs, &sigalgs)) + return 0; + if (CBS_len(&sigalgs) % 2 != 0 || CBS_len(&sigalgs) > 64) + return 0; + if (!CBS_stow(&sigalgs, &s->s3->hs.sigalgs, &s->s3->hs.sigalgs_len)) + return 0; + + return 1; +} + +/* + * Server Name Indication - RFC 6066, section 3. + */ +static int +tlsext_sni_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->tlsext_hostname != NULL); +} + +static int +tlsext_sni_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB server_name_list, host_name; + + if (!CBB_add_u16_length_prefixed(cbb, &server_name_list)) + return 0; + if (!CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name)) + return 0; + if (!CBB_add_u16_length_prefixed(&server_name_list, &host_name)) + return 0; + if (!CBB_add_bytes(&host_name, (const uint8_t *)s->tlsext_hostname, + strlen(s->tlsext_hostname))) + return 0; + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_sni_is_ip_literal(CBS *cbs, int *is_ip) +{ + union { + struct in_addr ip4; + struct in6_addr ip6; + } addrbuf; + char *hostname = NULL; + + *is_ip = 0; + + if (!CBS_strdup(cbs, &hostname)) + return 0; + + if (inet_pton(AF_INET, hostname, &addrbuf) == 1 || + inet_pton(AF_INET6, hostname, &addrbuf) == 1) + *is_ip = 1; + + free(hostname); + + return 1; +} + +/* + * Validate that the CBS contains only a hostname consisting of RFC 5890 + * compliant A-labels (see RFC 6066 section 3). Not a complete check + * since we don't parse punycode to verify its validity but limits to + * correct structure and character set. + */ +int +tlsext_sni_is_valid_hostname(CBS *cbs, int *is_ip) +{ + uint8_t prev, c = 0; + int component = 0; + CBS hostname; + + *is_ip = 0; + + CBS_dup(cbs, &hostname); + + if (CBS_len(&hostname) > TLSEXT_MAXLEN_host_name) + return 0; + + /* An IP literal is invalid as a host name (RFC 6066 section 3). */ + if (!tlsext_sni_is_ip_literal(&hostname, is_ip)) + return 0; + if (*is_ip) + return 0; + + while (CBS_len(&hostname) > 0) { + prev = c; + if (!CBS_get_u8(&hostname, &c)) + return 0; + /* Everything has to be ASCII, with no NUL byte. */ + if (!isascii(c) || c == '\0') + return 0; + /* It must be alphanumeric, a '-', or a '.' */ + if (!isalnum(c) && c != '-' && c != '.') + return 0; + /* '-' and '.' must not start a component or be at the end. */ + if (component == 0 || CBS_len(&hostname) == 0) { + if (c == '-' || c == '.') + return 0; + } + if (c == '.') { + /* Components can not end with a dash. */ + if (prev == '-') + return 0; + /* Start new component */ + component = 0; + continue; + } + /* Components must be 63 chars or less. */ + if (++component > 63) + return 0; + } + + return 1; +} + +static int +tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS server_name_list, host_name; + uint8_t name_type; + int is_ip; + + if (!CBS_get_u16_length_prefixed(cbs, &server_name_list)) + goto err; + + if (!CBS_get_u8(&server_name_list, &name_type)) + goto err; + + /* + * RFC 6066 section 3, only one type (host_name) is specified. + * We do not tolerate unknown types, neither does BoringSSL. + * other implementations appear more tolerant. + */ + if (name_type != TLSEXT_NAMETYPE_host_name) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + goto err; + } + + /* + * RFC 6066 section 3 specifies a host name must be at least 1 byte + * so 0 length is a decode error. + */ + if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name)) + goto err; + if (CBS_len(&host_name) < 1) + goto err; + + if (!tlsext_sni_is_valid_hostname(&host_name, &is_ip)) { + /* + * Various pieces of software have been known to set the SNI + * host name to an IP address, even though that violates the + * RFC. If this is the case, pretend the SNI extension does + * not exist. + */ + if (is_ip) + goto done; + + *alert = SSL_AD_ILLEGAL_PARAMETER; + goto err; + } + + if (s->hit || s->s3->hs.tls13.hrr) { + if (s->session->tlsext_hostname == NULL) { + *alert = SSL_AD_UNRECOGNIZED_NAME; + goto err; + } + if (!CBS_mem_equal(&host_name, s->session->tlsext_hostname, + strlen(s->session->tlsext_hostname))) { + *alert = SSL_AD_UNRECOGNIZED_NAME; + goto err; + } + } else { + if (s->session->tlsext_hostname != NULL) + goto err; + if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) { + *alert = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + + done: + /* + * RFC 6066 section 3 forbids multiple host names with the same type, + * therefore we allow only one entry. + */ + if (CBS_len(&server_name_list) != 0) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + goto err; + } + + return 1; + + err: + return 0; +} + +static int +tlsext_sni_server_needs(SSL *s, uint16_t msg_type) +{ + if (s->hit) + return 0; + + return (s->session->tlsext_hostname != NULL); +} + +static int +tlsext_sni_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return 1; +} + +static int +tlsext_sni_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + if (s->tlsext_hostname == NULL || CBS_len(cbs) != 0) { + *alert = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + + if (s->hit) { + if (s->session->tlsext_hostname == NULL) { + *alert = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + if (strcmp(s->tlsext_hostname, + s->session->tlsext_hostname) != 0) { + *alert = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + } else { + if (s->session->tlsext_hostname != NULL) + return 0; + if ((s->session->tlsext_hostname = + strdup(s->tlsext_hostname)) == NULL) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + return 1; +} + +/* + * Certificate Status Request - RFC 6066 section 8. + */ + +static int +tlsext_ocsp_client_needs(SSL *s, uint16_t msg_type) +{ + if (msg_type != SSL_TLSEXT_MSG_CH) + return 0; + + return (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp); +} + +static int +tlsext_ocsp_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB respid_list, respid, exts; + unsigned char *ext_data; + size_t ext_len; + int i; + + if (!CBB_add_u8(cbb, TLSEXT_STATUSTYPE_ocsp)) + return 0; + if (!CBB_add_u16_length_prefixed(cbb, &respid_list)) + return 0; + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + unsigned char *respid_data; + OCSP_RESPID *id; + size_t id_len; + + if ((id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, + i)) == NULL) + return 0; + if ((id_len = i2d_OCSP_RESPID(id, NULL)) == -1) + return 0; + if (!CBB_add_u16_length_prefixed(&respid_list, &respid)) + return 0; + if (!CBB_add_space(&respid, &respid_data, id_len)) + return 0; + if ((i2d_OCSP_RESPID(id, &respid_data)) != id_len) + return 0; + } + if (!CBB_add_u16_length_prefixed(cbb, &exts)) + return 0; + if ((ext_len = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, + NULL)) == -1) + return 0; + if (!CBB_add_space(&exts, &ext_data, ext_len)) + return 0; + if ((i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ext_data) != + ext_len)) + return 0; + if (!CBB_flush(cbb)) + return 0; + return 1; +} + +static int +tlsext_ocsp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + int alert_desc = SSL_AD_DECODE_ERROR; + CBS respid_list, respid, exts; + const unsigned char *p; + uint8_t status_type; + int ret = 0; + + if (msg_type != SSL_TLSEXT_MSG_CH) + goto err; + + if (!CBS_get_u8(cbs, &status_type)) + goto err; + if (status_type != TLSEXT_STATUSTYPE_ocsp) { + /* ignore unknown status types */ + s->tlsext_status_type = -1; + + if (!CBS_skip(cbs, CBS_len(cbs))) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + return 1; + } + s->tlsext_status_type = status_type; + if (!CBS_get_u16_length_prefixed(cbs, &respid_list)) + goto err; + + /* XXX */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + s->tlsext_ocsp_ids = NULL; + if (CBS_len(&respid_list) > 0) { + s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); + if (s->tlsext_ocsp_ids == NULL) { + alert_desc = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + + while (CBS_len(&respid_list) > 0) { + OCSP_RESPID *id; + + if (!CBS_get_u16_length_prefixed(&respid_list, &respid)) + goto err; + p = CBS_data(&respid); + if ((id = d2i_OCSP_RESPID(NULL, &p, CBS_len(&respid))) == NULL) + goto err; + if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { + alert_desc = SSL_AD_INTERNAL_ERROR; + OCSP_RESPID_free(id); + goto err; + } + } + + /* Read in request_extensions */ + if (!CBS_get_u16_length_prefixed(cbs, &exts)) + goto err; + if (CBS_len(&exts) > 0) { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + p = CBS_data(&exts); + if ((s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, + &p, CBS_len(&exts))) == NULL) + goto err; + } + + ret = 1; + err: + if (ret == 0) + *alert = alert_desc; + return ret; +} + +static int +tlsext_ocsp_server_needs(SSL *s, uint16_t msg_type) +{ + if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION && + s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && + s->ctx->tlsext_status_cb != NULL) { + s->tlsext_status_expected = 0; + if (s->ctx->tlsext_status_cb(s, + s->ctx->tlsext_status_arg) == SSL_TLSEXT_ERR_OK && + s->tlsext_ocsp_resp_len > 0) + s->tlsext_status_expected = 1; + } + return s->tlsext_status_expected; +} + +static int +tlsext_ocsp_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB ocsp_response; + + if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION) { + if (!CBB_add_u8(cbb, TLSEXT_STATUSTYPE_ocsp)) + return 0; + if (!CBB_add_u24_length_prefixed(cbb, &ocsp_response)) + return 0; + if (!CBB_add_bytes(&ocsp_response, + s->tlsext_ocsp_resp, + s->tlsext_ocsp_resp_len)) + return 0; + if (!CBB_flush(cbb)) + return 0; + } + return 1; +} + +static int +tlsext_ocsp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + uint8_t status_type; + CBS response; + + if (ssl_effective_tls_version(s) >= TLS1_3_VERSION) { + if (msg_type == SSL_TLSEXT_MSG_CR) { + /* + * RFC 8446, 4.4.2.1 - the server may request an OCSP + * response with an empty status_request. + */ + if (CBS_len(cbs) == 0) + return 1; + + SSLerror(s, SSL_R_LENGTH_MISMATCH); + return 0; + } + if (!CBS_get_u8(cbs, &status_type)) { + SSLerror(s, SSL_R_LENGTH_MISMATCH); + return 0; + } + if (status_type != TLSEXT_STATUSTYPE_ocsp) { + SSLerror(s, SSL_R_UNSUPPORTED_STATUS_TYPE); + return 0; + } + if (!CBS_get_u24_length_prefixed(cbs, &response)) { + SSLerror(s, SSL_R_LENGTH_MISMATCH); + return 0; + } + if (CBS_len(&response) > 65536) { + SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (!CBS_stow(&response, &s->tlsext_ocsp_resp, + &s->tlsext_ocsp_resp_len)) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + } else { + if (s->tlsext_status_type == -1) { + *alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* Set flag to expect CertificateStatus message */ + s->tlsext_status_expected = 1; + } + return 1; +} + +/* + * SessionTicket extension - RFC 5077 section 3.2 + */ +static int +tlsext_sessionticket_client_needs(SSL *s, uint16_t msg_type) +{ + /* + * Send session ticket extension when enabled and not overridden. + * + * When renegotiating, send an empty session ticket to indicate support. + */ + if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0) + return 0; + + if (!ssl_security_tickets(s)) + return 0; + + if (s->new_session) + return 1; + + if (s->tlsext_session_ticket != NULL && + s->tlsext_session_ticket->data == NULL) + return 0; + + return 1; +} + +static int +tlsext_sessionticket_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + /* + * Signal that we support session tickets by sending an empty + * extension when renegotiating or no session found. + */ + if (s->new_session || s->session == NULL) + return 1; + + if (s->session->tlsext_tick != NULL) { + /* Attempt to resume with an existing session ticket */ + if (!CBB_add_bytes(cbb, s->session->tlsext_tick, + s->session->tlsext_ticklen)) + return 0; + + } else if (s->tlsext_session_ticket != NULL) { + /* + * Attempt to resume with a custom provided session ticket set + * by SSL_set_session_ticket_ext(). + */ + if (s->tlsext_session_ticket->length > 0) { + size_t ticklen = s->tlsext_session_ticket->length; + + if ((s->session->tlsext_tick = malloc(ticklen)) == NULL) + return 0; + memcpy(s->session->tlsext_tick, + s->tlsext_session_ticket->data, + ticklen); + s->session->tlsext_ticklen = ticklen; + + if (!CBB_add_bytes(cbb, s->session->tlsext_tick, + s->session->tlsext_ticklen)) + return 0; + } + } + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_sessionticket_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, + int *alert) +{ + if (s->tls_session_ticket_ext_cb) { + if (!s->tls_session_ticket_ext_cb(s, CBS_data(cbs), + (int)CBS_len(cbs), + s->tls_session_ticket_ext_cb_arg)) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + /* We need to signal that this was processed fully */ + if (!CBS_skip(cbs, CBS_len(cbs))) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + return 1; +} + +static int +tlsext_sessionticket_server_needs(SSL *s, uint16_t msg_type) +{ + return (s->tlsext_ticket_expected && + !(SSL_get_options(s) & SSL_OP_NO_TICKET) && + ssl_security_tickets(s)); +} + +static int +tlsext_sessionticket_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + /* Empty ticket */ + return 1; +} + +static int +tlsext_sessionticket_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, + int *alert) +{ + if (s->tls_session_ticket_ext_cb) { + if (!s->tls_session_ticket_ext_cb(s, CBS_data(cbs), + (int)CBS_len(cbs), + s->tls_session_ticket_ext_cb_arg)) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0 || CBS_len(cbs) > 0) { + *alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + s->tlsext_ticket_expected = 1; + + return 1; +} + +/* + * DTLS extension for SRTP key establishment - RFC 5764 + */ + +#ifndef OPENSSL_NO_SRTP + +static int +tlsext_srtp_client_needs(SSL *s, uint16_t msg_type) +{ + return SSL_is_dtls(s) && SSL_get_srtp_profiles(s) != NULL; +} + +static int +tlsext_srtp_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB profiles, mki; + int ct, i; + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL; + const SRTP_PROTECTION_PROFILE *prof; + + if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { + SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); + return 0; + } + + if ((ct = sk_SRTP_PROTECTION_PROFILE_num(clnt)) < 1) { + SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); + return 0; + } + + if (!CBB_add_u16_length_prefixed(cbb, &profiles)) + return 0; + + for (i = 0; i < ct; i++) { + if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) == NULL) + return 0; + if (!CBB_add_u16(&profiles, prof->id)) + return 0; + } + + if (!CBB_add_u8_length_prefixed(cbb, &mki)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_srtp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + const SRTP_PROTECTION_PROFILE *cprof, *sprof; + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL, *srvr; + int i, j; + int ret; + uint16_t id; + CBS profiles, mki; + + ret = 0; + + if (!CBS_get_u16_length_prefixed(cbs, &profiles)) + goto err; + if (CBS_len(&profiles) == 0 || CBS_len(&profiles) % 2 != 0) + goto err; + + if ((clnt = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) + goto err; + + while (CBS_len(&profiles) > 0) { + if (!CBS_get_u16(&profiles, &id)) + goto err; + + if (!srtp_find_profile_by_num(id, &cprof)) { + if (!sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof)) + goto err; + } + } + + if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { + SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); + goto done; + } + + /* + * Per RFC 5764 section 4.1.1 + * + * Find the server preferred profile using the client's list. + * + * The server MUST send a profile if it sends the use_srtp + * extension. If one is not found, it should fall back to the + * negotiated DTLS cipher suite or return a DTLS alert. + */ + if ((srvr = SSL_get_srtp_profiles(s)) == NULL) + goto err; + for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) { + if ((sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i)) == NULL) + goto err; + + for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) { + if ((cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j)) + == NULL) + goto err; + + if (cprof->id == sprof->id) { + s->srtp_profile = sprof; + ret = 1; + goto done; + } + } + } + + /* If we didn't find anything, fall back to the negotiated */ + ret = 1; + goto done; + + err: + SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + + done: + sk_SRTP_PROTECTION_PROFILE_free(clnt); + return ret; +} + +static int +tlsext_srtp_server_needs(SSL *s, uint16_t msg_type) +{ + return SSL_is_dtls(s) && SSL_get_selected_srtp_profile(s) != NULL; +} + +static int +tlsext_srtp_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + SRTP_PROTECTION_PROFILE *profile; + CBB srtp, mki; + + if (!CBB_add_u16_length_prefixed(cbb, &srtp)) + return 0; + + if ((profile = SSL_get_selected_srtp_profile(s)) == NULL) + return 0; + + if (!CBB_add_u16(&srtp, profile->id)) + return 0; + + if (!CBB_add_u8_length_prefixed(cbb, &mki)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_srtp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; + const SRTP_PROTECTION_PROFILE *prof; + int i; + uint16_t id; + CBS profile_ids, mki; + + if (!CBS_get_u16_length_prefixed(cbs, &profile_ids)) { + SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return 0; + } + + if (!CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) { + SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return 0; + } + + if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { + SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { + SSLerror(s, SSL_R_NO_SRTP_PROFILES); + return 0; + } + + for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { + if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) + == NULL) { + SSLerror(s, SSL_R_NO_SRTP_PROFILES); + return 0; + } + + if (prof->id == id) { + s->srtp_profile = prof; + return 1; + } + } + + SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + + return 0; +} + +#endif /* OPENSSL_NO_SRTP */ + +/* + * TLSv1.3 Key Share - RFC 8446 section 4.2.8. + */ +static int +tlsext_keyshare_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION); +} + +static int +tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB client_shares, key_exchange; + + if (!CBB_add_u16_length_prefixed(cbb, &client_shares)) + return 0; + + if (!CBB_add_u16(&client_shares, + tls_key_share_group(s->s3->hs.key_share))) + return 0; + if (!CBB_add_u16_length_prefixed(&client_shares, &key_exchange)) + return 0; + if (!tls_key_share_public(s->s3->hs.key_share, &key_exchange)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS client_shares, key_exchange; + int decode_error; + uint16_t group; + + if (!CBS_get_u16_length_prefixed(cbs, &client_shares)) + return 0; + + while (CBS_len(&client_shares) > 0) { + + /* Unpack client share. */ + if (!CBS_get_u16(&client_shares, &group)) + return 0; + if (!CBS_get_u16_length_prefixed(&client_shares, &key_exchange)) + return 0; + + /* + * XXX - check key exchange against supported groups from client. + * XXX - check that groups only appear once. + */ + + /* + * Ignore this client share if we're using earlier than TLSv1.3 + * or we've already selected a key share. + */ + if (s->s3->hs.our_max_tls_version < TLS1_3_VERSION) + continue; + if (s->s3->hs.key_share != NULL) + continue; + + /* XXX - consider implementing server preference. */ + if (!tls1_check_group(s, group)) + continue; + + /* Decode and store the selected key share. */ + if ((s->s3->hs.key_share = tls_key_share_new(group)) == NULL) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + if (!tls_key_share_peer_public(s->s3->hs.key_share, + &key_exchange, &decode_error, NULL)) { + if (!decode_error) + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + return 1; +} + +static int +tlsext_keyshare_server_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION && + tlsext_extension_seen(s, TLSEXT_TYPE_key_share)); +} + +static int +tlsext_keyshare_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB key_exchange; + + /* In the case of a HRR, we only send the server selected group. */ + if (s->s3->hs.tls13.hrr) { + if (s->s3->hs.tls13.server_group == 0) + return 0; + return CBB_add_u16(cbb, s->s3->hs.tls13.server_group); + } + + if (s->s3->hs.key_share == NULL) + return 0; + + if (!CBB_add_u16(cbb, tls_key_share_group(s->s3->hs.key_share))) + return 0; + if (!CBB_add_u16_length_prefixed(cbb, &key_exchange)) + return 0; + if (!tls_key_share_public(s->s3->hs.key_share, &key_exchange)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_keyshare_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS key_exchange; + int decode_error; + uint16_t group; + + /* Unpack server share. */ + if (!CBS_get_u16(cbs, &group)) + return 0; + + if (CBS_len(cbs) == 0) { + /* HRR does not include an actual key share, only the group. */ + if (msg_type != SSL_TLSEXT_MSG_HRR) + return 0; + + s->s3->hs.tls13.server_group = group; + return 1; + } + + if (!CBS_get_u16_length_prefixed(cbs, &key_exchange)) + return 0; + + if (s->s3->hs.key_share == NULL) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + if (tls_key_share_group(s->s3->hs.key_share) != group) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + if (!tls_key_share_peer_public(s->s3->hs.key_share, + &key_exchange, &decode_error, NULL)) { + if (!decode_error) + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + return 1; +} + +/* + * Supported Versions - RFC 8446 section 4.2.1. + */ +static int +tlsext_versions_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION); +} + +static int +tlsext_versions_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + uint16_t max, min; + uint16_t version; + CBB versions; + + max = s->s3->hs.our_max_tls_version; + min = s->s3->hs.our_min_tls_version; + + if (!CBB_add_u8_length_prefixed(cbb, &versions)) + return 0; + + /* XXX - fix, but contiguous for now... */ + for (version = max; version >= min; version--) { + if (!CBB_add_u16(&versions, version)) + return 0; + } + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_versions_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS versions; + uint16_t version; + uint16_t max, min; + uint16_t matched_version = 0; + + max = s->s3->hs.our_max_tls_version; + min = s->s3->hs.our_min_tls_version; + + if (!CBS_get_u8_length_prefixed(cbs, &versions)) + return 0; + + while (CBS_len(&versions) > 0) { + if (!CBS_get_u16(&versions, &version)) + return 0; + /* + * XXX What is below implements client preference, and + * ignores any server preference entirely. + */ + if (matched_version == 0 && version >= min && version <= max) + matched_version = version; + } + + if (matched_version > 0) { + /* XXX - this should be stored for later processing. */ + s->version = matched_version; + return 1; + } + + *alert = SSL_AD_PROTOCOL_VERSION; + return 0; +} + +static int +tlsext_versions_server_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION); +} + +static int +tlsext_versions_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return CBB_add_u16(cbb, TLS1_3_VERSION); +} + +static int +tlsext_versions_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + uint16_t selected_version; + + if (!CBS_get_u16(cbs, &selected_version)) + return 0; + + /* XXX - need to fix for DTLS 1.3 */ + if (selected_version < TLS1_3_VERSION) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* XXX test between min and max once initialization code goes in */ + s->s3->hs.tls13.server_version = selected_version; + + return 1; +} + + +/* + * Cookie - RFC 8446 section 4.2.2. + */ + +static int +tlsext_cookie_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION && + s->s3->hs.tls13.cookie_len > 0 && s->s3->hs.tls13.cookie != NULL); +} + +static int +tlsext_cookie_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB cookie; + + if (!CBB_add_u16_length_prefixed(cbb, &cookie)) + return 0; + + if (!CBB_add_bytes(&cookie, s->s3->hs.tls13.cookie, + s->s3->hs.tls13.cookie_len)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_cookie_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS cookie; + + if (!CBS_get_u16_length_prefixed(cbs, &cookie)) + return 0; + + if (CBS_len(&cookie) != s->s3->hs.tls13.cookie_len) + return 0; + + /* + * Check provided cookie value against what server previously + * sent - client *MUST* send the same cookie with new CR after + * a cookie is sent by the server with an HRR. + */ + if (!CBS_mem_equal(&cookie, s->s3->hs.tls13.cookie, + s->s3->hs.tls13.cookie_len)) { + /* XXX special cookie mismatch alert? */ + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + return 1; +} + +static int +tlsext_cookie_server_needs(SSL *s, uint16_t msg_type) +{ + /* + * Server needs to set cookie value in tls13 handshake + * in order to send one, should only be sent with HRR. + */ + return (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION && + s->s3->hs.tls13.cookie_len > 0 && s->s3->hs.tls13.cookie != NULL); +} + +static int +tlsext_cookie_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB cookie; + + /* XXX deduplicate with client code */ + + if (!CBB_add_u16_length_prefixed(cbb, &cookie)) + return 0; + + if (!CBB_add_bytes(&cookie, s->s3->hs.tls13.cookie, + s->s3->hs.tls13.cookie_len)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_cookie_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + CBS cookie; + + /* + * XXX This currently assumes we will not get a second + * HRR from a server with a cookie to process after accepting + * one from the server in the same handshake + */ + if (s->s3->hs.tls13.cookie != NULL || + s->s3->hs.tls13.cookie_len != 0) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (!CBS_get_u16_length_prefixed(cbs, &cookie)) + return 0; + + if (!CBS_stow(&cookie, &s->s3->hs.tls13.cookie, + &s->s3->hs.tls13.cookie_len)) + return 0; + + return 1; +} + +/* + * Pre-Shared Key Exchange Modes - RFC 8446, 4.2.9. + */ + +static int +tlsext_psk_kex_modes_client_needs(SSL *s, uint16_t msg_type) +{ + return (s->s3->hs.tls13.use_psk_dhe_ke && + s->s3->hs.our_max_tls_version >= TLS1_3_VERSION); +} + +static int +tlsext_psk_kex_modes_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + CBB ke_modes; + + if (!CBB_add_u8_length_prefixed(cbb, &ke_modes)) + return 0; + + /* Only indicate support for PSK with DHE key establishment. */ + if (!CBB_add_u8(&ke_modes, TLS13_PSK_DHE_KE)) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +static int +tlsext_psk_kex_modes_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, + int *alert) +{ + CBS ke_modes; + uint8_t ke_mode; + + if (!CBS_get_u8_length_prefixed(cbs, &ke_modes)) + return 0; + + while (CBS_len(&ke_modes) > 0) { + if (!CBS_get_u8(&ke_modes, &ke_mode)) + return 0; + + if (ke_mode == TLS13_PSK_DHE_KE) + s->s3->hs.tls13.use_psk_dhe_ke = 1; + } + + return 1; +} + +static int +tlsext_psk_kex_modes_server_needs(SSL *s, uint16_t msg_type) +{ + /* Servers MUST NOT send this extension. */ + return 0; +} + +static int +tlsext_psk_kex_modes_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return 0; +} + +static int +tlsext_psk_kex_modes_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, + int *alert) +{ + return 0; +} + +/* + * Pre-Shared Key Extension - RFC 8446, 4.2.11 + */ + +static int +tlsext_psk_client_needs(SSL *s, uint16_t msg_type) +{ + return 0; +} + +static int +tlsext_psk_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return 0; +} + +static int +tlsext_psk_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + return CBS_skip(cbs, CBS_len(cbs)); +} + +static int +tlsext_psk_server_needs(SSL *s, uint16_t msg_type) +{ + return 0; +} + +static int +tlsext_psk_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return 0; +} + +static int +tlsext_psk_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + return CBS_skip(cbs, CBS_len(cbs)); +} + +/* + * QUIC transport parameters extension - RFC 9001 section 8.2. + */ + +static int +tlsext_quic_transport_parameters_client_needs(SSL *s, uint16_t msg_type) +{ + return SSL_is_quic(s) && s->quic_transport_params_len > 0; +} + +static int +tlsext_quic_transport_parameters_client_build(SSL *s, uint16_t msg_type, + CBB *cbb) +{ + if (!CBB_add_bytes(cbb, s->quic_transport_params, + s->quic_transport_params_len)) + return 0; + + return 1; +} + +static int +tlsext_quic_transport_parameters_client_parse(SSL *s, uint16_t msg_type, + CBS *cbs, int *alert) +{ + if (!SSL_is_quic(s)) { + *alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + if (!CBS_stow(cbs, &s->s3->peer_quic_transport_params, + &s->s3->peer_quic_transport_params_len)) + return 0; + if (!CBS_skip(cbs, s->s3->peer_quic_transport_params_len)) + return 0; + + return 1; +} + +static int +tlsext_quic_transport_parameters_server_needs(SSL *s, uint16_t msg_type) +{ + return SSL_is_quic(s) && s->quic_transport_params_len > 0; +} + +static int +tlsext_quic_transport_parameters_server_build(SSL *s, uint16_t msg_type, + CBB *cbb) +{ + if (!CBB_add_bytes(cbb, s->quic_transport_params, + s->quic_transport_params_len)) + return 0; + + return 1; +} + +static int +tlsext_quic_transport_parameters_server_parse(SSL *s, uint16_t msg_type, + CBS *cbs, int *alert) +{ + if (!SSL_is_quic(s)) { + *alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + if (!CBS_stow(cbs, &s->s3->peer_quic_transport_params, + &s->s3->peer_quic_transport_params_len)) + return 0; + if (!CBS_skip(cbs, s->s3->peer_quic_transport_params_len)) + return 0; + + return 1; +} + +struct tls_extension_funcs { + int (*needs)(SSL *s, uint16_t msg_type); + int (*build)(SSL *s, uint16_t msg_type, CBB *cbb); + int (*parse)(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); +}; + +struct tls_extension { + uint16_t type; + uint16_t messages; + struct tls_extension_funcs client; + struct tls_extension_funcs server; +}; + +static const struct tls_extension tls_extensions[] = { + { + .type = TLSEXT_TYPE_supported_versions, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH | + SSL_TLSEXT_MSG_HRR, + .client = { + .needs = tlsext_versions_client_needs, + .build = tlsext_versions_client_build, + .parse = tlsext_versions_client_parse, + }, + .server = { + .needs = tlsext_versions_server_needs, + .build = tlsext_versions_server_build, + .parse = tlsext_versions_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_key_share, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH | + SSL_TLSEXT_MSG_HRR, + .client = { + .needs = tlsext_keyshare_client_needs, + .build = tlsext_keyshare_client_build, + .parse = tlsext_keyshare_client_parse, + }, + .server = { + .needs = tlsext_keyshare_server_needs, + .build = tlsext_keyshare_server_build, + .parse = tlsext_keyshare_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_server_name, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_EE, + .client = { + .needs = tlsext_sni_client_needs, + .build = tlsext_sni_client_build, + .parse = tlsext_sni_client_parse, + }, + .server = { + .needs = tlsext_sni_server_needs, + .build = tlsext_sni_server_build, + .parse = tlsext_sni_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_renegotiate, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH, + .client = { + .needs = tlsext_ri_client_needs, + .build = tlsext_ri_client_build, + .parse = tlsext_ri_client_parse, + }, + .server = { + .needs = tlsext_ri_server_needs, + .build = tlsext_ri_server_build, + .parse = tlsext_ri_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_status_request, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_CR | + SSL_TLSEXT_MSG_CT, + .client = { + .needs = tlsext_ocsp_client_needs, + .build = tlsext_ocsp_client_build, + .parse = tlsext_ocsp_client_parse, + }, + .server = { + .needs = tlsext_ocsp_server_needs, + .build = tlsext_ocsp_server_build, + .parse = tlsext_ocsp_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_ec_point_formats, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH, + .client = { + .needs = tlsext_ecpf_client_needs, + .build = tlsext_ecpf_client_build, + .parse = tlsext_ecpf_client_parse, + }, + .server = { + .needs = tlsext_ecpf_server_needs, + .build = tlsext_ecpf_server_build, + .parse = tlsext_ecpf_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_supported_groups, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_EE, + .client = { + .needs = tlsext_supportedgroups_client_needs, + .build = tlsext_supportedgroups_client_build, + .parse = tlsext_supportedgroups_client_parse, + }, + .server = { + .needs = tlsext_supportedgroups_server_needs, + .build = tlsext_supportedgroups_server_build, + .parse = tlsext_supportedgroups_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_session_ticket, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH, + .client = { + .needs = tlsext_sessionticket_client_needs, + .build = tlsext_sessionticket_client_build, + .parse = tlsext_sessionticket_client_parse, + }, + .server = { + .needs = tlsext_sessionticket_server_needs, + .build = tlsext_sessionticket_server_build, + .parse = tlsext_sessionticket_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_signature_algorithms, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_CR, + .client = { + .needs = tlsext_sigalgs_client_needs, + .build = tlsext_sigalgs_client_build, + .parse = tlsext_sigalgs_client_parse, + }, + .server = { + .needs = tlsext_sigalgs_server_needs, + .build = tlsext_sigalgs_server_build, + .parse = tlsext_sigalgs_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_alpn, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_EE, + .client = { + .needs = tlsext_alpn_client_needs, + .build = tlsext_alpn_client_build, + .parse = tlsext_alpn_client_parse, + }, + .server = { + .needs = tlsext_alpn_server_needs, + .build = tlsext_alpn_server_build, + .parse = tlsext_alpn_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_cookie, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_HRR, + .client = { + .needs = tlsext_cookie_client_needs, + .build = tlsext_cookie_client_build, + .parse = tlsext_cookie_client_parse, + }, + .server = { + .needs = tlsext_cookie_server_needs, + .build = tlsext_cookie_server_build, + .parse = tlsext_cookie_server_parse, + }, + }, +#ifndef OPENSSL_NO_SRTP + { + .type = TLSEXT_TYPE_use_srtp, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH /* XXX */ | + SSL_TLSEXT_MSG_EE, + .client = { + .needs = tlsext_srtp_client_needs, + .build = tlsext_srtp_client_build, + .parse = tlsext_srtp_client_parse, + }, + .server = { + .needs = tlsext_srtp_server_needs, + .build = tlsext_srtp_server_build, + .parse = tlsext_srtp_server_parse, + }, + }, +#endif /* OPENSSL_NO_SRTP */ + { + .type = TLSEXT_TYPE_quic_transport_parameters, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_EE, + .client = { + .needs = tlsext_quic_transport_parameters_client_needs, + .build = tlsext_quic_transport_parameters_client_build, + .parse = tlsext_quic_transport_parameters_client_parse, + }, + .server = { + .needs = tlsext_quic_transport_parameters_server_needs, + .build = tlsext_quic_transport_parameters_server_build, + .parse = tlsext_quic_transport_parameters_server_parse, + }, + }, + { + .type = TLSEXT_TYPE_psk_key_exchange_modes, + .messages = SSL_TLSEXT_MSG_CH, + .client = { + .needs = tlsext_psk_kex_modes_client_needs, + .build = tlsext_psk_kex_modes_client_build, + .parse = tlsext_psk_kex_modes_client_parse, + }, + .server = { + .needs = tlsext_psk_kex_modes_server_needs, + .build = tlsext_psk_kex_modes_server_build, + .parse = tlsext_psk_kex_modes_server_parse, + }, + }, + { + /* MUST be last extension in CH per RFC 8446 section 4.2. */ + + .type = TLSEXT_TYPE_pre_shared_key, + .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH, + .client = { + .needs = tlsext_psk_client_needs, + .build = tlsext_psk_client_build, + .parse = tlsext_psk_client_parse, + }, + .server = { + .needs = tlsext_psk_server_needs, + .build = tlsext_psk_server_build, + .parse = tlsext_psk_server_parse, + }, + }, +}; + +#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) + +/* Ensure that extensions fit in a uint32_t bitmask. */ +CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8)); + +uint16_t +tls_extension_type(const struct tls_extension *extension) +{ + return extension->type; +} + +const struct tls_extension * +tls_extension_find(uint16_t type, size_t *tls_extensions_idx) +{ + size_t i; + + for (i = 0; i < N_TLS_EXTENSIONS; i++) { + if (tls_extensions[i].type == type) { + *tls_extensions_idx = i; + return &tls_extensions[i]; + } + } + + return NULL; +} + +int +tlsext_extension_seen(SSL *s, uint16_t type) +{ + size_t idx; + + if (tls_extension_find(type, &idx) == NULL) + return 0; + return ((s->s3->hs.extensions_seen & (1 << idx)) != 0); +} + +const struct tls_extension_funcs * +tlsext_funcs(const struct tls_extension *tlsext, int is_server) +{ + if (is_server) + return &tlsext->server; + + return &tlsext->client; +} + +int +tlsext_randomize_build_order(SSL *s) +{ + size_t idx, new_idx, psk_idx; + size_t alpn_idx = 0, sni_idx = 0; + + free(s->tlsext_build_order); + s->tlsext_build_order_len = 0; + + if ((s->tlsext_build_order = calloc(sizeof(*s->tlsext_build_order), + N_TLS_EXTENSIONS)) == NULL) + return 0; + s->tlsext_build_order_len = N_TLS_EXTENSIONS; + + /* RFC 8446, section 4.2: PSK must be the last extension in the CH. */ + psk_idx = N_TLS_EXTENSIONS - 1; + s->tlsext_build_order[psk_idx] = &tls_extensions[psk_idx]; + + /* Fisher-Yates shuffle with PSK fixed. */ + for (idx = 0; idx < psk_idx; idx++) { + new_idx = arc4random_uniform(idx + 1); + s->tlsext_build_order[idx] = s->tlsext_build_order[new_idx]; + s->tlsext_build_order[new_idx] = &tls_extensions[idx]; + } + + /* + * XXX - Apache2 special until year 2025: ensure that SNI precedes ALPN + * for clients so that virtual host setups work correctly. + */ + + if (s->server) + return 1; + + for (idx = 0; idx < N_TLS_EXTENSIONS; idx++) { + if (s->tlsext_build_order[idx]->type == TLSEXT_TYPE_alpn) + alpn_idx = idx; + if (s->tlsext_build_order[idx]->type == TLSEXT_TYPE_server_name) + sni_idx = idx; + } + if (alpn_idx < sni_idx) { + const struct tls_extension *tmp; + + tmp = s->tlsext_build_order[alpn_idx]; + s->tlsext_build_order[alpn_idx] = s->tlsext_build_order[sni_idx]; + s->tlsext_build_order[sni_idx] = tmp; + } + + return 1; +} + +int +tlsext_linearize_build_order(SSL *s) +{ + size_t idx; + + free(s->tlsext_build_order); + s->tlsext_build_order_len = 0; + + if ((s->tlsext_build_order = calloc(sizeof(*s->tlsext_build_order), + N_TLS_EXTENSIONS)) == NULL) + return 0; + s->tlsext_build_order_len = N_TLS_EXTENSIONS; + + for (idx = 0; idx < N_TLS_EXTENSIONS; idx++) + s->tlsext_build_order[idx] = &tls_extensions[idx]; + + return 1; +} + +static int +tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb) +{ + const struct tls_extension_funcs *ext; + const struct tls_extension *tlsext; + CBB extensions, extension_data; + int extensions_present = 0; + uint16_t tls_version; + size_t i; + + tls_version = ssl_effective_tls_version(s); + + if (!CBB_add_u16_length_prefixed(cbb, &extensions)) + return 0; + + for (i = 0; i < N_TLS_EXTENSIONS; i++) { + tlsext = s->tlsext_build_order[i]; + ext = tlsext_funcs(tlsext, is_server); + + /* RFC 8446 Section 4.2 */ + if (tls_version >= TLS1_3_VERSION && + !(tlsext->messages & msg_type)) + continue; + + if (!ext->needs(s, msg_type)) + continue; + + if (!CBB_add_u16(&extensions, tlsext->type)) + return 0; + if (!CBB_add_u16_length_prefixed(&extensions, &extension_data)) + return 0; + + if (!ext->build(s, msg_type, &extension_data)) + return 0; + + extensions_present = 1; + } + + if (!extensions_present && + (msg_type & (SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_SH)) != 0) + CBB_discard_child(cbb); + + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +int +tlsext_clienthello_hash_extension(SSL *s, uint16_t type, CBS *cbs) +{ + /* + * RFC 8446 4.1.2. For subsequent CH, early data will be removed, + * cookie may be added, padding may be removed. + */ + struct tls13_ctx *ctx = s->tls13; + + if (type == TLSEXT_TYPE_early_data || type == TLSEXT_TYPE_cookie || + type == TLSEXT_TYPE_padding) + return 1; + if (!tls13_clienthello_hash_update_bytes(ctx, (void *)&type, + sizeof(type))) + return 0; + /* + * key_share data may be changed, and pre_shared_key data may + * be changed + */ + if (type == TLSEXT_TYPE_pre_shared_key || type == TLSEXT_TYPE_key_share) + return 1; + if (!tls13_clienthello_hash_update(ctx, cbs)) + return 0; + + return 1; +} + +static int +tlsext_parse(SSL *s, int is_server, uint16_t msg_type, CBS *cbs, int *alert) +{ + const struct tls_extension_funcs *ext; + const struct tls_extension *tlsext; + CBS extensions, extension_data; + uint16_t type; + size_t idx; + uint16_t tls_version; + int alert_desc; + + tls_version = ssl_effective_tls_version(s); + + s->s3->hs.extensions_seen = 0; + + /* An empty extensions block is valid. */ + if (CBS_len(cbs) == 0) + return 1; + + alert_desc = SSL_AD_DECODE_ERROR; + + if (!CBS_get_u16_length_prefixed(cbs, &extensions)) + goto err; + + while (CBS_len(&extensions) > 0) { + if (!CBS_get_u16(&extensions, &type)) + goto err; + if (!CBS_get_u16_length_prefixed(&extensions, &extension_data)) + goto err; + + if (s->tlsext_debug_cb != NULL) + s->tlsext_debug_cb(s, !is_server, type, + (unsigned char *)CBS_data(&extension_data), + CBS_len(&extension_data), + s->tlsext_debug_arg); + + /* Unknown extensions are ignored. */ + if ((tlsext = tls_extension_find(type, &idx)) == NULL) + continue; + + if (tls_version >= TLS1_3_VERSION && is_server && + msg_type == SSL_TLSEXT_MSG_CH) { + if (!tlsext_clienthello_hash_extension(s, type, + &extension_data)) + goto err; + } + + /* RFC 8446 Section 4.2 */ + if (tls_version >= TLS1_3_VERSION && + !(tlsext->messages & msg_type)) { + alert_desc = SSL_AD_ILLEGAL_PARAMETER; + goto err; + } + + /* Check for duplicate known extensions. */ + if ((s->s3->hs.extensions_seen & (1 << idx)) != 0) + goto err; + s->s3->hs.extensions_seen |= (1 << idx); + + ext = tlsext_funcs(tlsext, is_server); + if (!ext->parse(s, msg_type, &extension_data, &alert_desc)) + goto err; + + if (CBS_len(&extension_data) != 0) + goto err; + } + + return 1; + + err: + *alert = alert_desc; + + return 0; +} + +static void +tlsext_server_reset_state(SSL *s) +{ + s->tlsext_status_type = -1; + s->s3->renegotiate_seen = 0; + free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + s->s3->alpn_selected_len = 0; + s->srtp_profile = NULL; +} + +int +tlsext_server_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return tlsext_build(s, 1, msg_type, cbb); +} + +int +tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + /* XXX - this should be done by the caller... */ + if (msg_type == SSL_TLSEXT_MSG_CH) + tlsext_server_reset_state(s); + + return tlsext_parse(s, 1, msg_type, cbs, alert); +} + +static void +tlsext_client_reset_state(SSL *s) +{ + s->s3->renegotiate_seen = 0; + free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + s->s3->alpn_selected_len = 0; +} + +int +tlsext_client_build(SSL *s, uint16_t msg_type, CBB *cbb) +{ + return tlsext_build(s, 0, msg_type, cbb); +} + +int +tlsext_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) +{ + /* XXX - this should be done by the caller... */ + if (msg_type == SSL_TLSEXT_MSG_SH) + tlsext_client_reset_state(s); + + return tlsext_parse(s, 0, msg_type, cbs, alert); +} diff --git a/Libraries/libressl/ssl/ssl_tlsext.h b/Libraries/libressl/ssl/ssl_tlsext.h new file mode 100644 index 000000000..da14f7fa9 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_tlsext.h @@ -0,0 +1,48 @@ +/* $OpenBSD: ssl_tlsext.h,v 1.33 2023/04/23 18:51:53 tb Exp $ */ +/* + * Copyright (c) 2016, 2017 Joel Sing + * Copyright (c) 2017 Doug Hogan + * Copyright (c) 2019 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_SSL_TLSEXT_H +#define HEADER_SSL_TLSEXT_H + +/* TLSv1.3 - RFC 8446 Section 4.2. */ +#define SSL_TLSEXT_MSG_CH 0x0001 /* ClientHello */ +#define SSL_TLSEXT_MSG_SH 0x0002 /* ServerHello */ +#define SSL_TLSEXT_MSG_EE 0x0004 /* EncryptedExtension */ +#define SSL_TLSEXT_MSG_CT 0x0008 /* Certificate */ +#define SSL_TLSEXT_MSG_CR 0x0010 /* CertificateRequest */ +#define SSL_TLSEXT_MSG_NST 0x0020 /* NewSessionTicket */ +#define SSL_TLSEXT_MSG_HRR 0x0040 /* HelloRetryRequest */ + +__BEGIN_HIDDEN_DECLS + +int tlsext_alpn_check_format(CBS *cbs); +int tlsext_sni_is_valid_hostname(CBS *cbs, int *is_ip); + +int tlsext_client_build(SSL *s, uint16_t msg_type, CBB *cbb); +int tlsext_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); + +int tlsext_server_build(SSL *s, uint16_t msg_type, CBB *cbb); +int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); + +int tlsext_extension_seen(SSL *s, uint16_t); +int tlsext_randomize_build_order(SSL *s); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/ssl_transcript.c b/Libraries/libressl/ssl/ssl_transcript.c new file mode 100644 index 000000000..22cd6c3cf --- /dev/null +++ b/Libraries/libressl/ssl/ssl_transcript.c @@ -0,0 +1,197 @@ +/* $OpenBSD: ssl_transcript.c,v 1.9 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" +#include "tls_internal.h" + +int +tls1_transcript_hash_init(SSL *s) +{ + const unsigned char *data; + const EVP_MD *md; + size_t len; + + tls1_transcript_hash_free(s); + + if (!ssl_get_handshake_evp_md(s, &md)) { + SSLerrorx(ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((s->s3->handshake_hash = EVP_MD_CTX_new()) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_DigestInit_ex(s->s3->handshake_hash, md, NULL)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + + if (!tls1_transcript_data(s, &data, &len)) { + SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH); + goto err; + } + if (!tls1_transcript_hash_update(s, data, len)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + + return 1; + + err: + tls1_transcript_hash_free(s); + + return 0; +} + +int +tls1_transcript_hash_update(SSL *s, const unsigned char *buf, size_t len) +{ + if (s->s3->handshake_hash == NULL) + return 1; + + return EVP_DigestUpdate(s->s3->handshake_hash, buf, len); +} + +int +tls1_transcript_hash_value(SSL *s, unsigned char *out, size_t len, + size_t *outlen) +{ + EVP_MD_CTX *mdctx = NULL; + unsigned int mdlen; + int ret = 0; + + if (s->s3->handshake_hash == NULL) + goto err; + + if (EVP_MD_CTX_size(s->s3->handshake_hash) > len) + goto err; + + if ((mdctx = EVP_MD_CTX_new()) == NULL) { + SSLerror(s, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_MD_CTX_copy_ex(mdctx, s->s3->handshake_hash)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if (!EVP_DigestFinal_ex(mdctx, out, &mdlen)) { + SSLerror(s, ERR_R_EVP_LIB); + goto err; + } + if (outlen != NULL) + *outlen = mdlen; + + ret = 1; + + err: + EVP_MD_CTX_free(mdctx); + + return (ret); +} + +void +tls1_transcript_hash_free(SSL *s) +{ + EVP_MD_CTX_free(s->s3->handshake_hash); + s->s3->handshake_hash = NULL; +} + +int +tls1_transcript_init(SSL *s) +{ + if (s->s3->handshake_transcript != NULL) + return 0; + + if ((s->s3->handshake_transcript = tls_buffer_new(0)) == NULL) + return 0; + + tls1_transcript_reset(s); + + return 1; +} + +void +tls1_transcript_free(SSL *s) +{ + tls_buffer_free(s->s3->handshake_transcript); + s->s3->handshake_transcript = NULL; +} + +void +tls1_transcript_reset(SSL *s) +{ + tls_buffer_clear(s->s3->handshake_transcript); + + tls1_transcript_unfreeze(s); +} + +int +tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len) +{ + if (s->s3->handshake_transcript == NULL) + return 1; + + if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT) + return 1; + + return tls_buffer_append(s->s3->handshake_transcript, buf, len); +} + +int +tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len) +{ + CBS cbs; + + if (s->s3->handshake_transcript == NULL) + return 0; + + if (!tls_buffer_data(s->s3->handshake_transcript, &cbs)) + return 0; + + /* XXX - change to caller providing a CBS argument. */ + *data = CBS_data(&cbs); + *len = CBS_len(&cbs); + + return 1; +} + +void +tls1_transcript_freeze(SSL *s) +{ + s->s3->flags |= TLS1_FLAGS_FREEZE_TRANSCRIPT; +} + +void +tls1_transcript_unfreeze(SSL *s) +{ + s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT; +} + +int +tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len) +{ + if (!tls1_transcript_hash_update(s, buf, len)) + return 0; + + if (!tls1_transcript_append(s, buf, len)) + return 0; + + return 1; +} diff --git a/Libraries/libressl/ssl/ssl_txt.c b/Libraries/libressl/ssl/ssl_txt.c new file mode 100644 index 000000000..ee3d218d6 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_txt.c @@ -0,0 +1,201 @@ +/* $OpenBSD: ssl_txt.c,v 1.37 2023/07/08 16:40:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include + +#include "ssl_local.h" + +int +SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + SSLerrorx(ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = SSL_SESSION_print(b, x); + BIO_free(b); + return ret; +} +LSSL_ALIAS(SSL_SESSION_print_fp); + +int +SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) +{ + size_t i; + int ret = 0; + + if (x == NULL) + goto err; + + if (BIO_puts(bp, "SSL-Session:\n") <= 0) + goto err; + + if (BIO_printf(bp, " Protocol : %s\n", + ssl_version_string(x->ssl_version)) <= 0) + goto err; + + if (x->cipher == NULL) { + if (BIO_printf(bp, " Cipher : %04lX\n", + x->cipher_id & SSL3_CK_VALUE_MASK) <= 0) + goto err; + } else { + const char *cipher_name = "unknown"; + + if (x->cipher->name != NULL) + cipher_name = x->cipher->name; + + if (BIO_printf(bp, " Cipher : %s\n", cipher_name) <= 0) + goto err; + } + + if (BIO_puts(bp, " Session-ID: ") <= 0) + goto err; + + for (i = 0; i < x->session_id_length; i++) { + if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) + goto err; + } + + if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) + goto err; + + for (i = 0; i < x->sid_ctx_length; i++) { + if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) + goto err; + } + + if (BIO_puts(bp, "\n Master-Key: ") <= 0) + goto err; + + for (i = 0; i < x->master_key_length; i++) { + if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) + goto err; + } + + if (x->tlsext_tick_lifetime_hint > 0) { + if (BIO_printf(bp, + "\n TLS session ticket lifetime hint: %u (seconds)", + x->tlsext_tick_lifetime_hint) <= 0) + goto err; + } + + if (x->tlsext_tick != NULL) { + if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) + goto err; + if (BIO_dump_indent(bp, x->tlsext_tick, x->tlsext_ticklen, + 4) <= 0) + goto err; + } + + if (x->time != 0) { + if (BIO_printf(bp, "\n Start Time: %lld", + (long long)x->time) <= 0) + goto err; + } + + if (x->timeout != 0) { + if (BIO_printf(bp, "\n Timeout : %ld (sec)", + x->timeout) <= 0) + goto err; + } + + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (BIO_printf(bp, " Verify return code: %ld (%s)\n", + x->verify_result, + X509_verify_cert_error_string(x->verify_result)) <= 0) + goto err; + + ret = 1; + err: + return ret; +} +LSSL_ALIAS(SSL_SESSION_print); diff --git a/Libraries/libressl/ssl/ssl_versions.c b/Libraries/libressl/ssl/ssl_versions.c new file mode 100644 index 000000000..827354606 --- /dev/null +++ b/Libraries/libressl/ssl/ssl_versions.c @@ -0,0 +1,373 @@ +/* $OpenBSD: ssl_versions.c,v 1.27 2023/07/02 17:21:32 beck Exp $ */ +/* + * Copyright (c) 2016, 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ssl_local.h" + +static uint16_t +ssl_dtls_to_tls_version(uint16_t dtls_ver) +{ + if (dtls_ver == DTLS1_VERSION) + return TLS1_1_VERSION; + if (dtls_ver == DTLS1_2_VERSION) + return TLS1_2_VERSION; + return 0; +} + +static uint16_t +ssl_tls_to_dtls_version(uint16_t tls_ver) +{ + if (tls_ver == TLS1_1_VERSION) + return DTLS1_VERSION; + if (tls_ver == TLS1_2_VERSION) + return DTLS1_2_VERSION; + return 0; +} + +static int +ssl_clamp_tls_version_range(uint16_t *min_ver, uint16_t *max_ver, + uint16_t clamp_min, uint16_t clamp_max) +{ + if (clamp_min > clamp_max || *min_ver > *max_ver) + return 0; + if (clamp_max < *min_ver || clamp_min > *max_ver) + return 0; + + if (*min_ver < clamp_min) + *min_ver = clamp_min; + if (*max_ver > clamp_max) + *max_ver = clamp_max; + + return 1; +} + +int +ssl_version_set_min(const SSL_METHOD *meth, uint16_t proto_ver, + uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver) +{ + uint16_t min_proto, min_version, max_version; + + if (proto_ver == 0) { + *out_tls_ver = meth->min_tls_version; + *out_proto_ver = 0; + return 1; + } + + min_version = proto_ver; + max_version = max_tls_ver; + + if (meth->dtls) { + if ((min_version = ssl_dtls_to_tls_version(proto_ver)) == 0) + return 0; + } + + if (!ssl_clamp_tls_version_range(&min_version, &max_version, + meth->min_tls_version, meth->max_tls_version)) + return 0; + + min_proto = min_version; + if (meth->dtls) { + if ((min_proto = ssl_tls_to_dtls_version(min_version)) == 0) + return 0; + } + *out_tls_ver = min_version; + *out_proto_ver = min_proto; + + return 1; +} + +int +ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver, + uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver) +{ + uint16_t max_proto, min_version, max_version; + + if (proto_ver == 0) { + *out_tls_ver = meth->max_tls_version; + *out_proto_ver = 0; + return 1; + } + + min_version = min_tls_ver; + max_version = proto_ver; + + if (meth->dtls) { + if ((max_version = ssl_dtls_to_tls_version(proto_ver)) == 0) + return 0; + } + + if (!ssl_clamp_tls_version_range(&min_version, &max_version, + meth->min_tls_version, meth->max_tls_version)) + return 0; + + max_proto = max_version; + if (meth->dtls) { + if ((max_proto = ssl_tls_to_dtls_version(max_version)) == 0) + return 0; + } + *out_tls_ver = max_version; + *out_proto_ver = max_proto; + + return 1; +} + +int +ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver) +{ + uint16_t min_version, max_version; + unsigned long options; + + /* + * The enabled versions have to be a contiguous range, which means we + * cannot enable and disable single versions at our whim, even though + * this is what the OpenSSL flags allow. The historical way this has + * been handled is by making a flag mean that all higher versions + * are disabled, if any version lower than the flag is enabled. + */ + + min_version = 0; + max_version = TLS1_3_VERSION; + options = s->options; + + if (SSL_is_dtls(s)) { + options = 0; + if (s->options & SSL_OP_NO_DTLSv1) + options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1; + if (s->options & SSL_OP_NO_DTLSv1_2) + options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2; + } + + if ((options & SSL_OP_NO_TLSv1_2) == 0) + min_version = TLS1_2_VERSION; + else if ((options & SSL_OP_NO_TLSv1_3) == 0) + min_version = TLS1_3_VERSION; + + if ((options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION) + max_version = TLS1_2_VERSION; + if ((options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION) + max_version = 0; + + /* Everything has been disabled... */ + if (min_version == 0 || max_version == 0) + return 0; + + /* Limit to configured version range. */ + if (!ssl_clamp_tls_version_range(&min_version, &max_version, + s->min_tls_version, s->max_tls_version)) + return 0; + + /* QUIC requires a minimum of TLSv1.3. */ + if (SSL_is_quic(s)) { + if (max_version < TLS1_3_VERSION) + return 0; + if (min_version < TLS1_3_VERSION) + min_version = TLS1_3_VERSION; + } + + if (min_ver != NULL) + *min_ver = min_version; + if (max_ver != NULL) + *max_ver = max_version; + + return 1; +} + +int +ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver) +{ + uint16_t min_version, max_version; + + if (!ssl_enabled_tls_version_range(s, &min_version, &max_version)) + return 0; + + /* Limit to the versions supported by this method. */ + if (!ssl_clamp_tls_version_range(&min_version, &max_version, + s->method->min_tls_version, s->method->max_tls_version)) + return 0; + + if (min_ver != NULL) + *min_ver = min_version; + if (max_ver != NULL) + *max_ver = max_version; + + return 1; +} + +uint16_t +ssl_tls_version(uint16_t version) +{ + if (version == TLS1_VERSION || version == TLS1_1_VERSION || + version == TLS1_2_VERSION || version == TLS1_3_VERSION) + return version; + + if (version == DTLS1_VERSION) + return TLS1_1_VERSION; + if (version == DTLS1_2_VERSION) + return TLS1_2_VERSION; + + return 0; +} + +uint16_t +ssl_effective_tls_version(SSL *s) +{ + if (s->s3->hs.negotiated_tls_version > 0) + return s->s3->hs.negotiated_tls_version; + + return s->s3->hs.our_max_tls_version; +} + +int +ssl_max_supported_version(SSL *s, uint16_t *max_ver) +{ + uint16_t max_version; + + *max_ver = 0; + + if (!ssl_supported_tls_version_range(s, NULL, &max_version)) + return 0; + + if (SSL_is_dtls(s)) { + if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0) + return 0; + } + + *max_ver = max_version; + + return 1; +} + +int +ssl_max_legacy_version(SSL *s, uint16_t *max_ver) +{ + uint16_t max_version; + + if ((max_version = s->s3->hs.our_max_tls_version) > TLS1_2_VERSION) + max_version = TLS1_2_VERSION; + + if (SSL_is_dtls(s)) { + if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0) + return 0; + } + + *max_ver = max_version; + + return 1; +} + +int +ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) +{ + uint16_t min_version, max_version, peer_tls_version, shared_version; + + *max_ver = 0; + peer_tls_version = peer_ver; + + if (SSL_is_dtls(s)) { + if ((peer_ver >> 8) != DTLS1_VERSION_MAJOR) + return 0; + + /* + * Convert the peer version to a TLS version - DTLS versions are + * the 1's complement of TLS version numbers (but not the actual + * protocol version numbers, that would be too sensible). Not to + * mention that DTLSv1.0 is really equivalent to DTLSv1.1. + */ + peer_tls_version = ssl_dtls_to_tls_version(peer_ver); + + /* + * This may be a version that we do not know about, if it is + * newer than DTLS1_2_VERSION (yes, less than is correct due + * to the "clever" versioning scheme), use TLS1_2_VERSION. + */ + if (peer_tls_version == 0) { + if (peer_ver < DTLS1_2_VERSION) + peer_tls_version = TLS1_2_VERSION; + } + } + + if (peer_tls_version >= TLS1_3_VERSION) + shared_version = TLS1_3_VERSION; + else if (peer_tls_version >= TLS1_2_VERSION) + shared_version = TLS1_2_VERSION; + else if (peer_tls_version >= TLS1_1_VERSION) + shared_version = TLS1_1_VERSION; + else if (peer_tls_version >= TLS1_VERSION) + shared_version = TLS1_VERSION; + else + return 0; + + if (!ssl_supported_tls_version_range(s, &min_version, &max_version)) + return 0; + + if (shared_version < min_version) + return 0; + + if (shared_version > max_version) + shared_version = max_version; + + if (SSL_is_dtls(s)) { + /* + * The resulting shared version will by definition be something + * that we know about. Switch back from TLS to DTLS. + */ + shared_version = ssl_tls_to_dtls_version(shared_version); + if (shared_version == 0) + return 0; + } + + if (!ssl_security_version(s, shared_version)) + return 0; + + *max_ver = shared_version; + + return 1; +} + +int +ssl_check_version_from_server(SSL *s, uint16_t server_version) +{ + uint16_t min_tls_version, max_tls_version, server_tls_version; + + /* Ensure that the version selected by the server is valid. */ + + server_tls_version = server_version; + if (SSL_is_dtls(s)) { + server_tls_version = ssl_dtls_to_tls_version(server_version); + if (server_tls_version == 0) + return 0; + } + + if (!ssl_supported_tls_version_range(s, &min_tls_version, + &max_tls_version)) + return 0; + + if (server_tls_version < min_tls_version || + server_tls_version > max_tls_version) + return 0; + + return ssl_security_version(s, server_tls_version); +} + +int +ssl_legacy_stack_version(SSL *s, uint16_t version) +{ + if (SSL_is_dtls(s)) + return version == DTLS1_VERSION || version == DTLS1_2_VERSION; + + return version == TLS1_VERSION || version == TLS1_1_VERSION || + version == TLS1_2_VERSION; +} diff --git a/Libraries/libressl/ssl/t1_enc.c b/Libraries/libressl/ssl/t1_enc.c new file mode 100644 index 000000000..c6140e9b3 --- /dev/null +++ b/Libraries/libressl/ssl/t1_enc.c @@ -0,0 +1,415 @@ +/* $OpenBSD: t1_enc.c,v 1.157 2022/11/26 16:08:56 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include + +#include +#include +#include +#include + +#include "dtls_local.h" +#include "ssl_local.h" + +void +tls1_cleanup_key_block(SSL *s) +{ + tls12_key_block_free(s->s3->hs.tls12.key_block); + s->s3->hs.tls12.key_block = NULL; +} + +/* + * TLS P_hash() data expansion function - see RFC 5246, section 5. + */ +static int +tls1_P_hash(const EVP_MD *md, const unsigned char *secret, size_t secret_len, + const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len, + const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len, + const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len) +{ + unsigned char A1[EVP_MAX_MD_SIZE], hmac[EVP_MAX_MD_SIZE]; + size_t A1_len, hmac_len; + EVP_MD_CTX *ctx = NULL; + EVP_PKEY *mac_key = NULL; + int ret = 0; + int chunk; + size_t i; + + chunk = EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); + + if ((ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret, secret_len); + if (mac_key == NULL) + goto err; + if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len)) + goto err; + if (!EVP_DigestSignFinal(ctx, A1, &A1_len)) + goto err; + + for (;;) { + if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignUpdate(ctx, A1, A1_len)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len)) + goto err; + if (!EVP_DigestSignFinal(ctx, hmac, &hmac_len)) + goto err; + + if (hmac_len > out_len) + hmac_len = out_len; + + for (i = 0; i < hmac_len; i++) + out[i] ^= hmac[i]; + + out += hmac_len; + out_len -= hmac_len; + + if (out_len == 0) + break; + + if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignUpdate(ctx, A1, A1_len)) + goto err; + if (!EVP_DigestSignFinal(ctx, A1, &A1_len)) + goto err; + } + ret = 1; + + err: + EVP_PKEY_free(mac_key); + EVP_MD_CTX_free(ctx); + + explicit_bzero(A1, sizeof(A1)); + explicit_bzero(hmac, sizeof(hmac)); + + return ret; +} + +int +tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len, + const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len, + const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len, + const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len) +{ + const EVP_MD *md; + size_t half_len; + + memset(out, 0, out_len); + + if (!ssl_get_handshake_evp_md(s, &md)) + return (0); + + if (EVP_MD_type(md) == NID_md5_sha1) { + /* + * Partition secret between MD5 and SHA1, then XOR result. + * If the secret length is odd, a one byte overlap is used. + */ + half_len = secret_len - (secret_len / 2); + if (!tls1_P_hash(EVP_md5(), secret, half_len, seed1, seed1_len, + seed2, seed2_len, seed3, seed3_len, seed4, seed4_len, + seed5, seed5_len, out, out_len)) + return (0); + + secret += secret_len - half_len; + if (!tls1_P_hash(EVP_sha1(), secret, half_len, seed1, seed1_len, + seed2, seed2_len, seed3, seed3_len, seed4, seed4_len, + seed5, seed5_len, out, out_len)) + return (0); + + return (1); + } + + if (!tls1_P_hash(md, secret, secret_len, seed1, seed1_len, + seed2, seed2_len, seed3, seed3_len, seed4, seed4_len, + seed5, seed5_len, out, out_len)) + return (0); + + return (1); +} + +int +tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len) +{ + return tls1_PRF(s, + s->session->master_key, s->session->master_key_length, + TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, + s->s3->server_random, SSL3_RANDOM_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, key_block, key_block_len); +} + +static int +tls1_change_cipher_state(SSL *s, int is_write) +{ + CBS mac_key, key, iv; + + /* Use client write keys on client write and server read. */ + if ((!s->server && is_write) || (s->server && !is_write)) { + tls12_key_block_client_write(s->s3->hs.tls12.key_block, + &mac_key, &key, &iv); + } else { + tls12_key_block_server_write(s->s3->hs.tls12.key_block, + &mac_key, &key, &iv); + } + + if (!is_write) { + if (!tls12_record_layer_change_read_cipher_state(s->rl, + &mac_key, &key, &iv)) + goto err; + if (SSL_is_dtls(s)) + dtls1_reset_read_seq_numbers(s); + } else { + if (!tls12_record_layer_change_write_cipher_state(s->rl, + &mac_key, &key, &iv)) + goto err; + } + return (1); + + err: + return (0); +} + +int +tls1_change_read_cipher_state(SSL *s) +{ + return tls1_change_cipher_state(s, 0); +} + +int +tls1_change_write_cipher_state(SSL *s) +{ + return tls1_change_cipher_state(s, 1); +} + +int +tls1_setup_key_block(SSL *s) +{ + struct tls12_key_block *key_block; + int mac_type = NID_undef, mac_secret_size = 0; + const EVP_CIPHER *cipher = NULL; + const EVP_AEAD *aead = NULL; + const EVP_MD *handshake_hash = NULL; + const EVP_MD *mac_hash = NULL; + int ret = 0; + + /* + * XXX - callers should be changed so that they only call this + * function once. + */ + if (s->s3->hs.tls12.key_block != NULL) + return (1); + + if (s->session->cipher && + (s->session->cipher->algorithm_mac & SSL_AEAD)) { + if (!ssl_cipher_get_evp_aead(s->session, &aead)) { + SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + } else { + /* XXX - mac_type and mac_secret_size are now unused. */ + if (!ssl_cipher_get_evp(s->session, &cipher, &mac_hash, + &mac_type, &mac_secret_size)) { + SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + } + + if (!ssl_get_handshake_evp_md(s, &handshake_hash)) + return (0); + + tls12_record_layer_set_aead(s->rl, aead); + tls12_record_layer_set_cipher_hash(s->rl, cipher, + handshake_hash, mac_hash); + + if ((key_block = tls12_key_block_new()) == NULL) + goto err; + if (!tls12_key_block_generate(key_block, s, aead, cipher, mac_hash)) + goto err; + + s->s3->hs.tls12.key_block = key_block; + key_block = NULL; + + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) && + s->method->version <= TLS1_VERSION) { + /* + * Enable vulnerability countermeasure for CBC ciphers with + * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if (s->session->cipher->algorithm_enc == SSL_eNULL) + s->s3->need_empty_fragments = 0; + +#ifndef OPENSSL_NO_RC4 + if (s->session->cipher->algorithm_enc == SSL_RC4) + s->s3->need_empty_fragments = 0; +#endif + } + } + + ret = 1; + + err: + tls12_key_block_free(key_block); + + return (ret); +} diff --git a/Libraries/libressl/ssl/t1_lib.c b/Libraries/libressl/ssl/t1_lib.c new file mode 100644 index 000000000..85d5eaa63 --- /dev/null +++ b/Libraries/libressl/ssl/t1_lib.c @@ -0,0 +1,1132 @@ +/* $OpenBSD: t1_lib.c,v 1.197 2022/11/26 16:08:56 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" + +static int tls_decrypt_ticket(SSL *s, CBS *ticket, int *alert, + SSL_SESSION **psess); + +int +tls1_new(SSL *s) +{ + if (!ssl3_new(s)) + return (0); + s->method->ssl_clear(s); + return (1); +} + +void +tls1_free(SSL *s) +{ + if (s == NULL) + return; + + free(s->tlsext_session_ticket); + ssl3_free(s); +} + +void +tls1_clear(SSL *s) +{ + ssl3_clear(s); + s->version = s->method->version; +} + +struct supported_group { + int nid; + int bits; +}; + +/* + * Supported groups (formerly known as named curves) + * https://www.iana.org/assignments/tls-parameters/#tls-parameters-8 + */ +static const struct supported_group nid_list[] = { + [1] = { + .nid = NID_sect163k1, + .bits = 80, + }, + [2] = { + .nid = NID_sect163r1, + .bits = 80, + }, + [3] = { + .nid = NID_sect163r2, + .bits = 80, + }, + [4] = { + .nid = NID_sect193r1, + .bits = 80, + }, + [5] = { + .nid = NID_sect193r2, + .bits = 80, + }, + [6] = { + .nid = NID_sect233k1, + .bits = 112, + }, + [7] = { + .nid = NID_sect233r1, + .bits = 112, + }, + [8] = { + .nid = NID_sect239k1, + .bits = 112, + }, + [9] = { + .nid = NID_sect283k1, + .bits = 128, + }, + [10] = { + .nid = NID_sect283r1, + .bits = 128, + }, + [11] = { + .nid = NID_sect409k1, + .bits = 192, + }, + [12] = { + .nid = NID_sect409r1, + .bits = 192, + }, + [13] = { + .nid = NID_sect571k1, + .bits = 256, + }, + [14] = { + .nid = NID_sect571r1, + .bits = 256, + }, + [15] = { + .nid = NID_secp160k1, + .bits = 80, + }, + [16] = { + .nid = NID_secp160r1, + .bits = 80, + }, + [17] = { + .nid = NID_secp160r2, + .bits = 80, + }, + [18] = { + .nid = NID_secp192k1, + .bits = 80, + }, + [19] = { + .nid = NID_X9_62_prime192v1, /* aka secp192r1 */ + .bits = 80, + }, + [20] = { + .nid = NID_secp224k1, + .bits = 112, + }, + [21] = { + .nid = NID_secp224r1, + .bits = 112, + }, + [22] = { + .nid = NID_secp256k1, + .bits = 128, + }, + [23] = { + .nid = NID_X9_62_prime256v1, /* aka secp256r1 */ + .bits = 128, + }, + [24] = { + .nid = NID_secp384r1, + .bits = 192, + }, + [25] = { + .nid = NID_secp521r1, + .bits = 256, + }, + [26] = { + .nid = NID_brainpoolP256r1, + .bits = 128, + }, + [27] = { + .nid = NID_brainpoolP384r1, + .bits = 192, + }, + [28] = { + .nid = NID_brainpoolP512r1, + .bits = 256, + }, + [29] = { + .nid = NID_X25519, + .bits = 128, + }, +}; + +#define NID_LIST_LEN (sizeof(nid_list) / sizeof(nid_list[0])) + +#if 0 +static const uint8_t ecformats_list[] = { + TLSEXT_ECPOINTFORMAT_uncompressed, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 +}; +#endif + +static const uint8_t ecformats_default[] = { + TLSEXT_ECPOINTFORMAT_uncompressed, +}; + +#if 0 +static const uint16_t ecgroups_list[] = { + 29, /* X25519 (29) */ + 14, /* sect571r1 (14) */ + 13, /* sect571k1 (13) */ + 25, /* secp521r1 (25) */ + 28, /* brainpoolP512r1 (28) */ + 11, /* sect409k1 (11) */ + 12, /* sect409r1 (12) */ + 27, /* brainpoolP384r1 (27) */ + 24, /* secp384r1 (24) */ + 9, /* sect283k1 (9) */ + 10, /* sect283r1 (10) */ + 26, /* brainpoolP256r1 (26) */ + 22, /* secp256k1 (22) */ + 23, /* secp256r1 (23) */ + 8, /* sect239k1 (8) */ + 6, /* sect233k1 (6) */ + 7, /* sect233r1 (7) */ + 20, /* secp224k1 (20) */ + 21, /* secp224r1 (21) */ + 4, /* sect193r1 (4) */ + 5, /* sect193r2 (5) */ + 18, /* secp192k1 (18) */ + 19, /* secp192r1 (19) */ + 1, /* sect163k1 (1) */ + 2, /* sect163r1 (2) */ + 3, /* sect163r2 (3) */ + 15, /* secp160k1 (15) */ + 16, /* secp160r1 (16) */ + 17, /* secp160r2 (17) */ +}; +#endif + +static const uint16_t ecgroups_client_default[] = { + 29, /* X25519 (29) */ + 23, /* secp256r1 (23) */ + 24, /* secp384r1 (24) */ + 25, /* secp521r1 (25) */ +}; + +static const uint16_t ecgroups_server_default[] = { + 29, /* X25519 (29) */ + 23, /* secp256r1 (23) */ + 24, /* secp384r1 (24) */ +}; + +int +tls1_ec_group_id2nid(uint16_t group_id, int *out_nid) +{ + int nid; + + if (group_id >= NID_LIST_LEN) + return 0; + + if ((nid = nid_list[group_id].nid) == 0) + return 0; + + *out_nid = nid; + + return 1; +} + +int +tls1_ec_group_id2bits(uint16_t group_id, int *out_bits) +{ + int bits; + + if (group_id >= NID_LIST_LEN) + return 0; + + if ((bits = nid_list[group_id].bits) == 0) + return 0; + + *out_bits = bits; + + return 1; +} + +int +tls1_ec_nid2group_id(int nid, uint16_t *out_group_id) +{ + uint16_t group_id; + + if (nid == 0) + return 0; + + for (group_id = 0; group_id < NID_LIST_LEN; group_id++) { + if (nid_list[group_id].nid == nid) { + *out_group_id = group_id; + return 1; + } + } + + return 0; +} + +/* + * Return the appropriate format list. If client_formats is non-zero, return + * the client/session formats. Otherwise return the custom format list if one + * exists, or the default formats if a custom list has not been specified. + */ +void +tls1_get_formatlist(const SSL *s, int client_formats, const uint8_t **pformats, + size_t *pformatslen) +{ + if (client_formats != 0) { + *pformats = s->session->tlsext_ecpointformatlist; + *pformatslen = s->session->tlsext_ecpointformatlist_length; + return; + } + + *pformats = s->tlsext_ecpointformatlist; + *pformatslen = s->tlsext_ecpointformatlist_length; + if (*pformats == NULL) { + *pformats = ecformats_default; + *pformatslen = sizeof(ecformats_default); + } +} + +/* + * Return the appropriate group list. If client_groups is non-zero, return + * the client/session groups. Otherwise return the custom group list if one + * exists, or the default groups if a custom list has not been specified. + */ +void +tls1_get_group_list(const SSL *s, int client_groups, const uint16_t **pgroups, + size_t *pgroupslen) +{ + if (client_groups != 0) { + *pgroups = s->session->tlsext_supportedgroups; + *pgroupslen = s->session->tlsext_supportedgroups_length; + return; + } + + *pgroups = s->tlsext_supportedgroups; + *pgroupslen = s->tlsext_supportedgroups_length; + if (*pgroups != NULL) + return; + + if (!s->server) { + *pgroups = ecgroups_client_default; + *pgroupslen = sizeof(ecgroups_client_default) / 2; + } else { + *pgroups = ecgroups_server_default; + *pgroupslen = sizeof(ecgroups_server_default) / 2; + } +} + +static int +tls1_get_group_lists(const SSL *ssl, const uint16_t **pref, size_t *preflen, + const uint16_t **supp, size_t *supplen) +{ + unsigned long server_pref; + + /* Cannot do anything on the client side. */ + if (!ssl->server) + return 0; + + server_pref = (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE); + tls1_get_group_list(ssl, (server_pref == 0), pref, preflen); + tls1_get_group_list(ssl, (server_pref != 0), supp, supplen); + + return 1; +} + +static int +tls1_group_id_present(uint16_t group_id, const uint16_t *list, size_t list_len) +{ + size_t i; + + for (i = 0; i < list_len; i++) { + if (group_id == list[i]) + return 1; + } + + return 0; +} + +int +tls1_count_shared_groups(const SSL *ssl, size_t *out_count) +{ + size_t count, preflen, supplen, i; + const uint16_t *pref, *supp; + + if (!tls1_get_group_lists(ssl, &pref, &preflen, &supp, &supplen)) + return 0; + + count = 0; + for (i = 0; i < preflen; i++) { + if (!tls1_group_id_present(pref[i], supp, supplen)) + continue; + + if (!ssl_security_shared_group(ssl, pref[i])) + continue; + + count++; + } + + *out_count = count; + + return 1; +} + +static int +tls1_group_by_index(const SSL *ssl, size_t n, int *out_nid, + int (*ssl_security_fn)(const SSL *, uint16_t)) +{ + size_t count, preflen, supplen, i; + const uint16_t *pref, *supp; + + if (!tls1_get_group_lists(ssl, &pref, &preflen, &supp, &supplen)) + return 0; + + count = 0; + for (i = 0; i < preflen; i++) { + if (!tls1_group_id_present(pref[i], supp, supplen)) + continue; + + if (!ssl_security_fn(ssl, pref[i])) + continue; + + if (count++ == n) + return tls1_ec_group_id2nid(pref[i], out_nid); + } + + return 0; +} + +int +tls1_get_shared_group_by_index(const SSL *ssl, size_t index, int *out_nid) +{ + return tls1_group_by_index(ssl, index, out_nid, + ssl_security_shared_group); +} + +int +tls1_get_supported_group(const SSL *ssl, int *out_nid) +{ + return tls1_group_by_index(ssl, 0, out_nid, + ssl_security_supported_group); +} + +int +tls1_set_groups(uint16_t **out_group_ids, size_t *out_group_ids_len, + const int *groups, size_t ngroups) +{ + uint16_t *group_ids; + size_t i; + + if ((group_ids = calloc(ngroups, sizeof(uint16_t))) == NULL) + return 0; + + for (i = 0; i < ngroups; i++) { + if (!tls1_ec_nid2group_id(groups[i], &group_ids[i])) { + free(group_ids); + return 0; + } + } + + free(*out_group_ids); + *out_group_ids = group_ids; + *out_group_ids_len = ngroups; + + return 1; +} + +int +tls1_set_group_list(uint16_t **out_group_ids, size_t *out_group_ids_len, + const char *groups) +{ + uint16_t *new_group_ids, *group_ids = NULL; + size_t ngroups = 0; + char *gs, *p, *q; + int nid; + + if ((gs = strdup(groups)) == NULL) + return 0; + + q = gs; + while ((p = strsep(&q, ":")) != NULL) { + nid = OBJ_sn2nid(p); + if (nid == NID_undef) + nid = OBJ_ln2nid(p); + if (nid == NID_undef) + nid = EC_curve_nist2nid(p); + if (nid == NID_undef) + goto err; + + if ((new_group_ids = reallocarray(group_ids, ngroups + 1, + sizeof(uint16_t))) == NULL) + goto err; + group_ids = new_group_ids; + + if (!tls1_ec_nid2group_id(nid, &group_ids[ngroups])) + goto err; + + ngroups++; + } + + free(gs); + free(*out_group_ids); + *out_group_ids = group_ids; + *out_group_ids_len = ngroups; + + return 1; + + err: + free(gs); + free(group_ids); + + return 0; +} + +/* Check that a group is one of our preferences. */ +int +tls1_check_group(SSL *s, uint16_t group_id) +{ + const uint16_t *groups; + size_t groupslen, i; + + tls1_get_group_list(s, 0, &groups, &groupslen); + + for (i = 0; i < groupslen; i++) { + if (!ssl_security_supported_group(s, groups[i])) + continue; + if (groups[i] == group_id) + return 1; + } + return 0; +} + +/* For an EC key set TLS ID and required compression based on parameters. */ +static int +tls1_set_ec_id(uint16_t *group_id, uint8_t *comp_id, EC_KEY *ec) +{ + const EC_GROUP *grp; + const EC_METHOD *meth; + int prime_field; + int nid; + + if (ec == NULL) + return (0); + + /* Determine whether the group is defined over a prime field. */ + if ((grp = EC_KEY_get0_group(ec)) == NULL) + return (0); + if ((meth = EC_GROUP_method_of(grp)) == NULL) + return (0); + prime_field = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); + + /* Determine group ID. */ + nid = EC_GROUP_get_curve_name(grp); + /* If we have an ID set it, otherwise set arbitrary explicit group. */ + if (!tls1_ec_nid2group_id(nid, group_id)) + *group_id = prime_field ? 0xff01 : 0xff02; + + if (comp_id == NULL) + return (1); + + /* Specify the compression identifier. */ + if (EC_KEY_get0_public_key(ec) == NULL) + return (0); + *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; + if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { + *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + if (prime_field) + *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + } + + return (1); +} + +/* Check that an EC key is compatible with extensions. */ +static int +tls1_check_ec_key(SSL *s, const uint16_t *group_id, const uint8_t *comp_id) +{ + size_t groupslen, formatslen, i; + const uint16_t *groups; + const uint8_t *formats; + + /* + * Check point formats extension if present, otherwise everything + * is supported (see RFC4492). + */ + tls1_get_formatlist(s, 1, &formats, &formatslen); + if (comp_id != NULL && formats != NULL) { + for (i = 0; i < formatslen; i++) { + if (formats[i] == *comp_id) + break; + } + if (i == formatslen) + return (0); + } + + /* + * Check group list if present, otherwise everything is supported. + */ + tls1_get_group_list(s, 1, &groups, &groupslen); + if (group_id != NULL && groups != NULL) { + for (i = 0; i < groupslen; i++) { + if (groups[i] == *group_id) + break; + } + if (i == groupslen) + return (0); + } + + return (1); +} + +/* Check EC server key is compatible with client extensions. */ +int +tls1_check_ec_server_key(SSL *s) +{ + SSL_CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC; + uint16_t group_id; + uint8_t comp_id; + EC_KEY *eckey; + EVP_PKEY *pkey; + + if (cpk->x509 == NULL || cpk->privatekey == NULL) + return (0); + if ((pkey = X509_get0_pubkey(cpk->x509)) == NULL) + return (0); + if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) + return (0); + if (!tls1_set_ec_id(&group_id, &comp_id, eckey)) + return (0); + + return tls1_check_ec_key(s, &group_id, &comp_id); +} + +int +ssl_check_clienthello_tlsext_early(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + /* The handling of the ECPointFormats extension is done elsewhere, namely in + * ssl3_choose_cipher in s3_lib.c. + */ + /* The handling of the EllipticCurves extension is done elsewhere, namely in + * ssl3_choose_cipher in s3_lib.c. + */ + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = s->ctx->tlsext_servername_callback(s, &al, + s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) + ret = s->initial_ctx->tlsext_servername_callback(s, &al, + s->initial_ctx->tlsext_servername_arg); + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + case SSL_TLSEXT_ERR_NOACK: + default: + return 1; + } +} + +int +ssl_check_clienthello_tlsext_late(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_OK; + int al = 0; /* XXX gcc3 */ + + /* If status request then ask callback what to do. + * Note: this must be called after servername callbacks in case + * the certificate has changed, and must be called after the cipher + * has been chosen because this may influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && + s->ctx && s->ctx->tlsext_status_cb) { + int r; + SSL_CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey == NULL) { + s->tlsext_status_expected = 0; + return 1; + } + /* Set current certificate to one we will use so + * SSL_get_certificate et al can pick it up. + */ + s->cert->key = certpkey; + r = s->ctx->tlsext_status_cb(s, + s->ctx->tlsext_status_arg); + switch (r) { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + else + s->tlsext_status_expected = 0; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } else + s->tlsext_status_expected = 0; + + err: + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + default: + return 1; + } +} + +int +ssl_check_serverhello_tlsext(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + ret = SSL_TLSEXT_ERR_OK; + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = s->ctx->tlsext_servername_callback(s, &al, + s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) + ret = s->initial_ctx->tlsext_servername_callback(s, &al, + s->initial_ctx->tlsext_servername_arg); + + /* If we've requested certificate status and we wont get one + * tell the callback + */ + if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) && + s->ctx && s->ctx->tlsext_status_cb) { + int r; + + free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resp_len = 0; + + r = s->ctx->tlsext_status_cb(s, + s->ctx->tlsext_status_arg); + if (r == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + if (r < 0) { + al = SSL_AD_INTERNAL_ERROR; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + case SSL_TLSEXT_ERR_NOACK: + default: + return 1; + } +} + +/* Since the server cache lookup is done early on in the processing of the + * ClientHello, and other operations depend on the result, we need to handle + * any TLS session ticket extension at the same time. + * + * ext_block: a CBS for the ClientHello extensions block. + * ret: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * If s->tls_session_secret_cb is set then we are expecting a pre-shared key + * ciphersuite, in which case we have no use for session tickets and one will + * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. + * + * Returns: + * TLS1_TICKET_FATAL_ERROR: error from parsing or decrypting the ticket. + * TLS1_TICKET_NONE: no ticket was found (or was ignored, based on settings). + * TLS1_TICKET_EMPTY: a zero length extension was found, indicating that the + * client supports session tickets but doesn't currently have one to offer. + * TLS1_TICKET_NOT_DECRYPTED: either s->tls_session_secret_cb was + * set, or a ticket was offered but couldn't be decrypted because of a + * non-fatal error. + * TLS1_TICKET_DECRYPTED: a ticket was successfully decrypted and *ret was set. + * + * Side effects: + * Sets s->tlsext_ticket_expected to 1 if the server will have to issue + * a new session ticket to the client because the client indicated support + * (and s->tls_session_secret_cb is NULL) but the client either doesn't have + * a session ticket or we couldn't use the one it gave us, or if + * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. + * Otherwise, s->tlsext_ticket_expected is set to 0. + */ +int +tls1_process_ticket(SSL *s, CBS *ext_block, int *alert, SSL_SESSION **ret) +{ + CBS extensions, ext_data; + uint16_t ext_type = 0; + + s->tlsext_ticket_expected = 0; + *ret = NULL; + + /* + * If tickets disabled behave as if no ticket present to permit stateful + * resumption. + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return TLS1_TICKET_NONE; + + /* + * An empty extensions block is valid, but obviously does not contain + * a session ticket. + */ + if (CBS_len(ext_block) == 0) + return TLS1_TICKET_NONE; + + if (!CBS_get_u16_length_prefixed(ext_block, &extensions)) { + *alert = SSL_AD_DECODE_ERROR; + return TLS1_TICKET_FATAL_ERROR; + } + + while (CBS_len(&extensions) > 0) { + if (!CBS_get_u16(&extensions, &ext_type) || + !CBS_get_u16_length_prefixed(&extensions, &ext_data)) { + *alert = SSL_AD_DECODE_ERROR; + return TLS1_TICKET_FATAL_ERROR; + } + + if (ext_type == TLSEXT_TYPE_session_ticket) + break; + } + + if (ext_type != TLSEXT_TYPE_session_ticket) + return TLS1_TICKET_NONE; + + if (CBS_len(&ext_data) == 0) { + /* + * The client will accept a ticket but does not currently + * have one. + */ + s->tlsext_ticket_expected = 1; + return TLS1_TICKET_EMPTY; + } + + if (s->tls_session_secret_cb != NULL) { + /* + * Indicate that the ticket could not be decrypted rather than + * generating the session from ticket now, trigger abbreviated + * handshake based on external mechanism to calculate the master + * secret later. + */ + return TLS1_TICKET_NOT_DECRYPTED; + } + + return tls_decrypt_ticket(s, &ext_data, alert, ret); +} + +/* tls_decrypt_ticket attempts to decrypt a session ticket. + * + * ticket: a CBS containing the body of the session ticket extension. + * psess: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * Returns: + * TLS1_TICKET_FATAL_ERROR: error from parsing or decrypting the ticket. + * TLS1_TICKET_NOT_DECRYPTED: the ticket couldn't be decrypted. + * TLS1_TICKET_DECRYPTED: a ticket was decrypted and *psess was set. + */ +static int +tls_decrypt_ticket(SSL *s, CBS *ticket, int *alert, SSL_SESSION **psess) +{ + CBS ticket_name, ticket_iv, ticket_encdata, ticket_hmac; + SSL_SESSION *sess = NULL; + unsigned char *sdec = NULL; + size_t sdec_len = 0; + const unsigned char *p; + unsigned char hmac[EVP_MAX_MD_SIZE]; + HMAC_CTX *hctx = NULL; + EVP_CIPHER_CTX *cctx = NULL; + SSL_CTX *tctx = s->initial_ctx; + int slen, hlen; + int alert_desc = SSL_AD_INTERNAL_ERROR; + int ret = TLS1_TICKET_FATAL_ERROR; + + *psess = NULL; + + if (!CBS_get_bytes(ticket, &ticket_name, 16)) + goto derr; + + /* + * Initialize session ticket encryption and HMAC contexts. + */ + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + if ((hctx = HMAC_CTX_new()) == NULL) + goto err; + + if (tctx->tlsext_ticket_key_cb != NULL) { + int rv; + + /* + * The API guarantees EVP_MAX_IV_LENGTH bytes of space for + * the iv to tlsext_ticket_key_cb(). Since the total space + * required for a session cookie is never less than this, + * this check isn't too strict. The exact check comes later. + */ + if (CBS_len(ticket) < EVP_MAX_IV_LENGTH) + goto derr; + + if ((rv = tctx->tlsext_ticket_key_cb(s, + (unsigned char *)CBS_data(&ticket_name), + (unsigned char *)CBS_data(ticket), cctx, hctx, 0)) < 0) + goto err; + if (rv == 0) + goto derr; + if (rv == 2) { + /* Renew ticket. */ + s->tlsext_ticket_expected = 1; + } + + /* + * Now that the cipher context is initialised, we can extract + * the IV since its length is known. + */ + if (!CBS_get_bytes(ticket, &ticket_iv, + EVP_CIPHER_CTX_iv_length(cctx))) + goto derr; + } else { + /* Check that the key name matches. */ + if (!CBS_mem_equal(&ticket_name, + tctx->tlsext_tick_key_name, + sizeof(tctx->tlsext_tick_key_name))) + goto derr; + if (!CBS_get_bytes(ticket, &ticket_iv, + EVP_CIPHER_iv_length(EVP_aes_128_cbc()))) + goto derr; + if (!EVP_DecryptInit_ex(cctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, CBS_data(&ticket_iv))) + goto err; + if (!HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, + sizeof(tctx->tlsext_tick_hmac_key), EVP_sha256(), + NULL)) + goto err; + } + + /* + * Attempt to process session ticket. + */ + + if ((hlen = HMAC_size(hctx)) < 0) + goto err; + + if (hlen > CBS_len(ticket)) + goto derr; + if (!CBS_get_bytes(ticket, &ticket_encdata, CBS_len(ticket) - hlen)) + goto derr; + if (!CBS_get_bytes(ticket, &ticket_hmac, hlen)) + goto derr; + if (CBS_len(ticket) != 0) { + alert_desc = SSL_AD_DECODE_ERROR; + goto err; + } + + /* Check HMAC of encrypted ticket. */ + if (HMAC_Update(hctx, CBS_data(&ticket_name), + CBS_len(&ticket_name)) <= 0) + goto err; + if (HMAC_Update(hctx, CBS_data(&ticket_iv), + CBS_len(&ticket_iv)) <= 0) + goto err; + if (HMAC_Update(hctx, CBS_data(&ticket_encdata), + CBS_len(&ticket_encdata)) <= 0) + goto err; + if (HMAC_Final(hctx, hmac, &hlen) <= 0) + goto err; + + if (!CBS_mem_equal(&ticket_hmac, hmac, hlen)) + goto derr; + + /* Attempt to decrypt session data. */ + sdec_len = CBS_len(&ticket_encdata); + if ((sdec = calloc(1, sdec_len)) == NULL) + goto err; + if (EVP_DecryptUpdate(cctx, sdec, &slen, CBS_data(&ticket_encdata), + CBS_len(&ticket_encdata)) <= 0) + goto derr; + if (EVP_DecryptFinal_ex(cctx, sdec + slen, &hlen) <= 0) + goto derr; + + slen += hlen; + + /* + * For session parse failures, indicate that we need to send a new + * ticket. + */ + p = sdec; + if ((sess = d2i_SSL_SESSION(NULL, &p, slen)) == NULL) + goto derr; + *psess = sess; + sess = NULL; + + ret = TLS1_TICKET_DECRYPTED; + goto done; + + derr: + ERR_clear_error(); + s->tlsext_ticket_expected = 1; + ret = TLS1_TICKET_NOT_DECRYPTED; + goto done; + + err: + *alert = alert_desc; + ret = TLS1_TICKET_FATAL_ERROR; + goto done; + + done: + freezero(sdec, sdec_len); + EVP_CIPHER_CTX_free(cctx); + HMAC_CTX_free(hctx); + SSL_SESSION_free(sess); + + return ret; +} diff --git a/Libraries/libressl/ssl/tls12_internal.h b/Libraries/libressl/ssl/tls12_internal.h new file mode 100644 index 000000000..d416b2e3f --- /dev/null +++ b/Libraries/libressl/ssl/tls12_internal.h @@ -0,0 +1,29 @@ +/* $OpenBSD: tls12_internal.h,v 1.1 2022/11/07 11:58:45 jsing Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS12_INTERNAL_H +#define HEADER_TLS12_INTERNAL_H + +__BEGIN_HIDDEN_DECLS + +int tls12_exporter(SSL *s, const uint8_t *label, size_t label_len, + const uint8_t *context_value, size_t context_value_len, int use_context, + uint8_t *out, size_t out_len); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/tls12_key_schedule.c b/Libraries/libressl/ssl/tls12_key_schedule.c new file mode 100644 index 000000000..6d714c118 --- /dev/null +++ b/Libraries/libressl/ssl/tls12_key_schedule.c @@ -0,0 +1,295 @@ +/* $OpenBSD: tls12_key_schedule.c,v 1.3 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "tls12_internal.h" + +struct tls12_key_block { + CBS client_write_mac_key; + CBS server_write_mac_key; + CBS client_write_key; + CBS server_write_key; + CBS client_write_iv; + CBS server_write_iv; + + uint8_t *key_block; + size_t key_block_len; +}; + +struct tls12_key_block * +tls12_key_block_new(void) +{ + return calloc(1, sizeof(struct tls12_key_block)); +} + +static void +tls12_key_block_clear(struct tls12_key_block *kb) +{ + CBS_init(&kb->client_write_mac_key, NULL, 0); + CBS_init(&kb->server_write_mac_key, NULL, 0); + CBS_init(&kb->client_write_key, NULL, 0); + CBS_init(&kb->server_write_key, NULL, 0); + CBS_init(&kb->client_write_iv, NULL, 0); + CBS_init(&kb->server_write_iv, NULL, 0); + + freezero(kb->key_block, kb->key_block_len); + kb->key_block = NULL; + kb->key_block_len = 0; +} + +void +tls12_key_block_free(struct tls12_key_block *kb) +{ + if (kb == NULL) + return; + + tls12_key_block_clear(kb); + + freezero(kb, sizeof(struct tls12_key_block)); +} + +void +tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key, + CBS *key, CBS *iv) +{ + CBS_dup(&kb->client_write_mac_key, mac_key); + CBS_dup(&kb->client_write_key, key); + CBS_dup(&kb->client_write_iv, iv); +} + +void +tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key, + CBS *key, CBS *iv) +{ + CBS_dup(&kb->server_write_mac_key, mac_key); + CBS_dup(&kb->server_write_key, key); + CBS_dup(&kb->server_write_iv, iv); +} + +int +tls12_key_block_generate(struct tls12_key_block *kb, SSL *s, + const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash) +{ + size_t mac_key_len = 0, key_len = 0, iv_len = 0; + uint8_t *key_block = NULL; + size_t key_block_len = 0; + CBS cbs; + + /* + * Generate a TLSv1.2 key block and partition into individual secrets, + * as per RFC 5246 section 6.3. + */ + + tls12_key_block_clear(kb); + + /* Must have AEAD or cipher/MAC pair. */ + if (aead == NULL && (cipher == NULL || mac_hash == NULL)) + goto err; + + if (aead != NULL) { + key_len = EVP_AEAD_key_length(aead); + + /* AEAD fixed nonce length. */ + if (aead == EVP_aead_aes_128_gcm() || + aead == EVP_aead_aes_256_gcm()) + iv_len = 4; + else if (aead == EVP_aead_chacha20_poly1305()) + iv_len = 12; + else + goto err; + } else if (cipher != NULL && mac_hash != NULL) { + /* + * A negative integer return value will be detected via the + * EVP_MAX_* checks against the size_t variables below. + */ + mac_key_len = EVP_MD_size(mac_hash); + key_len = EVP_CIPHER_key_length(cipher); + iv_len = EVP_CIPHER_iv_length(cipher); + + /* Special handling for GOST... */ + if (EVP_MD_type(mac_hash) == NID_id_Gost28147_89_MAC) + mac_key_len = 32; + } + + if (mac_key_len > EVP_MAX_MD_SIZE) + goto err; + if (key_len > EVP_MAX_KEY_LENGTH) + goto err; + if (iv_len > EVP_MAX_IV_LENGTH) + goto err; + + key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len; + if ((key_block = calloc(1, key_block_len)) == NULL) + goto err; + + if (!tls1_generate_key_block(s, key_block, key_block_len)) + goto err; + + kb->key_block = key_block; + kb->key_block_len = key_block_len; + key_block = NULL; + key_block_len = 0; + + /* Partition key block into individual secrets. */ + CBS_init(&cbs, kb->key_block, kb->key_block_len); + if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len)) + goto err; + if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len)) + goto err; + if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len)) + goto err; + if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len)) + goto err; + if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len)) + goto err; + if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len)) + goto err; + if (CBS_len(&cbs) != 0) + goto err; + + return 1; + + err: + tls12_key_block_clear(kb); + freezero(key_block, key_block_len); + + return 0; +} + +struct tls12_reserved_label { + const char *label; + size_t label_len; +}; + +/* + * RFC 5705 section 6. + */ +static const struct tls12_reserved_label tls12_reserved_labels[] = { + { + .label = TLS_MD_CLIENT_FINISH_CONST, + .label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, + }, + { + .label = TLS_MD_SERVER_FINISH_CONST, + .label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, + }, + { + .label = TLS_MD_MASTER_SECRET_CONST, + .label_len = TLS_MD_MASTER_SECRET_CONST_SIZE, + }, + { + .label = TLS_MD_KEY_EXPANSION_CONST, + .label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE, + }, + { + .label = NULL, + .label_len = 0, + }, +}; + +int +tls12_exporter(SSL *s, const uint8_t *label, size_t label_len, + const uint8_t *context_value, size_t context_value_len, int use_context, + uint8_t *out, size_t out_len) +{ + uint8_t *data = NULL; + size_t data_len = 0; + CBB cbb, context; + CBS seed; + size_t i; + int ret = 0; + + /* + * RFC 5705 - Key Material Exporters for TLS. + */ + + memset(&cbb, 0, sizeof(cbb)); + + if (!SSL_is_init_finished(s)) { + SSLerror(s, SSL_R_BAD_STATE); + goto err; + } + + if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION) + goto err; + + /* + * Due to exceptional design choices, we need to build a concatenation + * of the label and the seed value, before checking for reserved + * labels. This prevents a reserved label from being split across the + * label and the seed (that includes the client random), which are + * concatenated by the PRF. + */ + if (!CBB_init(&cbb, 0)) + goto err; + if (!CBB_add_bytes(&cbb, label, label_len)) + goto err; + if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE)) + goto err; + if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE)) + goto err; + if (use_context) { + if (!CBB_add_u16_length_prefixed(&cbb, &context)) + goto err; + if (context_value_len > 0) { + if (!CBB_add_bytes(&context, context_value, + context_value_len)) + goto err; + } + } + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; + + /* + * Ensure that the block (label + seed) does not start with a reserved + * label - in an ideal world we would ensure that the label has an + * explicitly permitted prefix instead, but of course this also got + * messed up by the standards. + */ + for (i = 0; tls12_reserved_labels[i].label != NULL; i++) { + /* XXX - consider adding/using CBS_has_prefix(). */ + if (tls12_reserved_labels[i].label_len > data_len) + goto err; + if (memcmp(data, tls12_reserved_labels[i].label, + tls12_reserved_labels[i].label_len) == 0) { + SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); + goto err; + } + } + + CBS_init(&seed, data, data_len); + if (!CBS_skip(&seed, label_len)) + goto err; + + if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length, + label, label_len, CBS_data(&seed), CBS_len(&seed), NULL, 0, NULL, 0, + NULL, 0, out, out_len)) + goto err; + + ret = 1; + + err: + freezero(data, data_len); + CBB_cleanup(&cbb); + + return ret; +} diff --git a/Libraries/libressl/ssl/tls12_lib.c b/Libraries/libressl/ssl/tls12_lib.c new file mode 100644 index 000000000..96b3abcd2 --- /dev/null +++ b/Libraries/libressl/ssl/tls12_lib.c @@ -0,0 +1,118 @@ +/* $OpenBSD: tls12_lib.c,v 1.6 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ssl_local.h" + +static int +tls12_finished_verify_data(SSL *s, const char *finished_label, + size_t finished_label_len, uint8_t *verify_data, size_t verify_data_len, + size_t *out_len) +{ + uint8_t transcript_hash[EVP_MAX_MD_SIZE]; + size_t transcript_hash_len; + + *out_len = 0; + + if (s->session->master_key_length == 0) + return 0; + + if (verify_data_len < TLS1_FINISH_MAC_LENGTH) + return 0; + + if (!tls1_transcript_hash_value(s, transcript_hash, + sizeof(transcript_hash), &transcript_hash_len)) + return 0; + + if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length, + finished_label, finished_label_len, transcript_hash, + transcript_hash_len, NULL, 0, NULL, 0, NULL, 0, verify_data, + TLS1_FINISH_MAC_LENGTH)) + return 0; + + *out_len = TLS1_FINISH_MAC_LENGTH; + + return 1; +} + +static int +tls12_client_finished_verify_data(SSL *s, uint8_t *verify_data, + size_t verify_data_len, size_t *out_len) +{ + return tls12_finished_verify_data(s, TLS_MD_CLIENT_FINISH_CONST, + TLS_MD_CLIENT_FINISH_CONST_SIZE, verify_data, verify_data_len, + out_len); +} + +static int +tls12_server_finished_verify_data(SSL *s, uint8_t *verify_data, + size_t verify_data_len, size_t *out_len) +{ + return tls12_finished_verify_data(s, TLS_MD_SERVER_FINISH_CONST, + TLS_MD_SERVER_FINISH_CONST_SIZE, verify_data, verify_data_len, + out_len); +} + +int +tls12_derive_finished(SSL *s) +{ + if (!s->server) { + return tls12_client_finished_verify_data(s, + s->s3->hs.finished, sizeof(s->s3->hs.finished), + &s->s3->hs.finished_len); + } else { + return tls12_server_finished_verify_data(s, + s->s3->hs.finished, sizeof(s->s3->hs.finished), + &s->s3->hs.finished_len); + } +} + +int +tls12_derive_peer_finished(SSL *s) +{ + if (s->server) { + return tls12_client_finished_verify_data(s, + s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished), + &s->s3->hs.peer_finished_len); + } else { + return tls12_server_finished_verify_data(s, + s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished), + &s->s3->hs.peer_finished_len); + } +} + +int +tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret, + size_t premaster_secret_len) +{ + s->session->master_key_length = 0; + + if (premaster_secret_len == 0) + return 0; + + CTASSERT(sizeof(s->session->master_key) == SSL_MAX_MASTER_KEY_LENGTH); + + if (!tls1_PRF(s, premaster_secret, premaster_secret_len, + TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, + s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, + s->session->master_key, sizeof(s->session->master_key))) + return 0; + + s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; + + return 1; +} diff --git a/Libraries/libressl/ssl/tls12_record_layer.c b/Libraries/libressl/ssl/tls12_record_layer.c new file mode 100644 index 000000000..997026be9 --- /dev/null +++ b/Libraries/libressl/ssl/tls12_record_layer.c @@ -0,0 +1,1342 @@ +/* $OpenBSD: tls12_record_layer.c,v 1.40 2023/07/08 20:38:23 beck Exp $ */ +/* + * Copyright (c) 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +#include "ssl_local.h" + +#define TLS12_RECORD_SEQ_NUM_LEN 8 +#define TLS12_AEAD_FIXED_NONCE_MAX_LEN 12 + +struct tls12_record_protection { + uint16_t epoch; + uint8_t seq_num[TLS12_RECORD_SEQ_NUM_LEN]; + + EVP_AEAD_CTX *aead_ctx; + + uint8_t *aead_nonce; + size_t aead_nonce_len; + + uint8_t *aead_fixed_nonce; + size_t aead_fixed_nonce_len; + + size_t aead_variable_nonce_len; + size_t aead_tag_len; + + int aead_xor_nonces; + int aead_variable_nonce_in_record; + + EVP_CIPHER_CTX *cipher_ctx; + EVP_MD_CTX *hash_ctx; + + int stream_mac; + + uint8_t *mac_key; + size_t mac_key_len; +}; + +static struct tls12_record_protection * +tls12_record_protection_new(void) +{ + return calloc(1, sizeof(struct tls12_record_protection)); +} + +static void +tls12_record_protection_clear(struct tls12_record_protection *rp) +{ + EVP_AEAD_CTX_free(rp->aead_ctx); + + freezero(rp->aead_nonce, rp->aead_nonce_len); + freezero(rp->aead_fixed_nonce, rp->aead_fixed_nonce_len); + + EVP_CIPHER_CTX_free(rp->cipher_ctx); + EVP_MD_CTX_free(rp->hash_ctx); + + freezero(rp->mac_key, rp->mac_key_len); + + memset(rp, 0, sizeof(*rp)); +} + +static void +tls12_record_protection_free(struct tls12_record_protection *rp) +{ + if (rp == NULL) + return; + + tls12_record_protection_clear(rp); + + freezero(rp, sizeof(struct tls12_record_protection)); +} + +static int +tls12_record_protection_engaged(struct tls12_record_protection *rp) +{ + return rp->aead_ctx != NULL || rp->cipher_ctx != NULL; +} + +static int +tls12_record_protection_unused(struct tls12_record_protection *rp) +{ + return rp->aead_ctx == NULL && rp->cipher_ctx == NULL && + rp->hash_ctx == NULL && rp->mac_key == NULL; +} + +static int +tls12_record_protection_eiv_len(struct tls12_record_protection *rp, + size_t *out_eiv_len) +{ + int eiv_len; + + *out_eiv_len = 0; + + if (rp->cipher_ctx == NULL) + return 0; + + eiv_len = 0; + if (EVP_CIPHER_CTX_mode(rp->cipher_ctx) == EVP_CIPH_CBC_MODE) + eiv_len = EVP_CIPHER_CTX_iv_length(rp->cipher_ctx); + if (eiv_len < 0 || eiv_len > EVP_MAX_IV_LENGTH) + return 0; + + *out_eiv_len = eiv_len; + + return 1; +} + +static int +tls12_record_protection_block_size(struct tls12_record_protection *rp, + size_t *out_block_size) +{ + int block_size; + + *out_block_size = 0; + + if (rp->cipher_ctx == NULL) + return 0; + + block_size = EVP_CIPHER_CTX_block_size(rp->cipher_ctx); + if (block_size < 0 || block_size > EVP_MAX_BLOCK_LENGTH) + return 0; + + *out_block_size = block_size; + + return 1; +} + +static int +tls12_record_protection_mac_len(struct tls12_record_protection *rp, + size_t *out_mac_len) +{ + int mac_len; + + *out_mac_len = 0; + + if (rp->hash_ctx == NULL) + return 0; + + mac_len = EVP_MD_CTX_size(rp->hash_ctx); + if (mac_len <= 0 || mac_len > EVP_MAX_MD_SIZE) + return 0; + + *out_mac_len = mac_len; + + return 1; +} + +struct tls12_record_layer { + uint16_t version; + uint16_t initial_epoch; + int dtls; + + uint8_t alert_desc; + + const EVP_AEAD *aead; + const EVP_CIPHER *cipher; + const EVP_MD *handshake_hash; + const EVP_MD *mac_hash; + + /* Pointers to active record protection (memory is not owned). */ + struct tls12_record_protection *read; + struct tls12_record_protection *write; + + struct tls12_record_protection *read_current; + struct tls12_record_protection *write_current; + struct tls12_record_protection *write_previous; +}; + +struct tls12_record_layer * +tls12_record_layer_new(void) +{ + struct tls12_record_layer *rl; + + if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL) + goto err; + if ((rl->read_current = tls12_record_protection_new()) == NULL) + goto err; + if ((rl->write_current = tls12_record_protection_new()) == NULL) + goto err; + + rl->read = rl->read_current; + rl->write = rl->write_current; + + return rl; + + err: + tls12_record_layer_free(rl); + + return NULL; +} + +void +tls12_record_layer_free(struct tls12_record_layer *rl) +{ + if (rl == NULL) + return; + + tls12_record_protection_free(rl->read_current); + tls12_record_protection_free(rl->write_current); + tls12_record_protection_free(rl->write_previous); + + freezero(rl, sizeof(struct tls12_record_layer)); +} + +void +tls12_record_layer_alert(struct tls12_record_layer *rl, uint8_t *alert_desc) +{ + *alert_desc = rl->alert_desc; +} + +int +tls12_record_layer_write_overhead(struct tls12_record_layer *rl, + size_t *overhead) +{ + size_t block_size, eiv_len, mac_len; + + *overhead = 0; + + if (rl->write->aead_ctx != NULL) { + *overhead = rl->write->aead_tag_len; + } else if (rl->write->cipher_ctx != NULL) { + eiv_len = 0; + if (rl->version != TLS1_VERSION) { + if (!tls12_record_protection_eiv_len(rl->write, &eiv_len)) + return 0; + } + if (!tls12_record_protection_block_size(rl->write, &block_size)) + return 0; + if (!tls12_record_protection_mac_len(rl->write, &mac_len)) + return 0; + + *overhead = eiv_len + block_size + mac_len; + } + + return 1; +} + +int +tls12_record_layer_read_protected(struct tls12_record_layer *rl) +{ + return tls12_record_protection_engaged(rl->read); +} + +int +tls12_record_layer_write_protected(struct tls12_record_layer *rl) +{ + return tls12_record_protection_engaged(rl->write); +} + +void +tls12_record_layer_set_aead(struct tls12_record_layer *rl, const EVP_AEAD *aead) +{ + rl->aead = aead; +} + +void +tls12_record_layer_set_cipher_hash(struct tls12_record_layer *rl, + const EVP_CIPHER *cipher, const EVP_MD *handshake_hash, + const EVP_MD *mac_hash) +{ + rl->cipher = cipher; + rl->handshake_hash = handshake_hash; + rl->mac_hash = mac_hash; +} + +void +tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) +{ + rl->version = version; + rl->dtls = ((version >> 8) == DTLS1_VERSION_MAJOR); +} + +void +tls12_record_layer_set_initial_epoch(struct tls12_record_layer *rl, + uint16_t epoch) +{ + rl->initial_epoch = epoch; +} + +uint16_t +tls12_record_layer_read_epoch(struct tls12_record_layer *rl) +{ + return rl->read->epoch; +} + +uint16_t +tls12_record_layer_write_epoch(struct tls12_record_layer *rl) +{ + return rl->write->epoch; +} + +int +tls12_record_layer_use_write_epoch(struct tls12_record_layer *rl, uint16_t epoch) +{ + if (rl->write->epoch == epoch) + return 1; + + if (rl->write_current->epoch == epoch) { + rl->write = rl->write_current; + return 1; + } + + if (rl->write_previous != NULL && rl->write_previous->epoch == epoch) { + rl->write = rl->write_previous; + return 1; + } + + return 0; +} + +void +tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, uint16_t epoch) +{ + if (rl->write_previous == NULL || rl->write_previous->epoch != epoch) + return; + + rl->write = rl->write_current; + + tls12_record_protection_free(rl->write_previous); + rl->write_previous = NULL; +} + +void +tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) +{ + tls12_record_protection_clear(rl->read); + rl->read->epoch = rl->initial_epoch; +} + +void +tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) +{ + tls12_record_protection_clear(rl->write); + rl->write->epoch = rl->initial_epoch; + + tls12_record_protection_free(rl->write_previous); + rl->write_previous = NULL; +} + +void +tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl) +{ + memcpy(rl->write->seq_num, rl->read->seq_num, + sizeof(rl->write->seq_num)); +} + +static const uint8_t tls12_max_seq_num[TLS12_RECORD_SEQ_NUM_LEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +int +tls12_record_layer_inc_seq_num(struct tls12_record_layer *rl, uint8_t *seq_num) +{ + CBS max_seq_num; + int i; + + /* + * RFC 5246 section 6.1 and RFC 6347 section 4.1 - both TLS and DTLS + * sequence numbers must not wrap. Note that for DTLS the first two + * bytes are used as an "epoch" and not part of the sequence number. + */ + CBS_init(&max_seq_num, seq_num, TLS12_RECORD_SEQ_NUM_LEN); + if (rl->dtls) { + if (!CBS_skip(&max_seq_num, 2)) + return 0; + } + if (CBS_mem_equal(&max_seq_num, tls12_max_seq_num, + CBS_len(&max_seq_num))) + return 0; + + for (i = TLS12_RECORD_SEQ_NUM_LEN - 1; i >= 0; i--) { + if (++seq_num[i] != 0) + break; + } + + return 1; +} + +static int +tls12_record_layer_set_mac_key(struct tls12_record_protection *rp, + const uint8_t *mac_key, size_t mac_key_len) +{ + freezero(rp->mac_key, rp->mac_key_len); + rp->mac_key = NULL; + rp->mac_key_len = 0; + + if (mac_key == NULL || mac_key_len == 0) + return 1; + + if ((rp->mac_key = calloc(1, mac_key_len)) == NULL) + return 0; + + memcpy(rp->mac_key, mac_key, mac_key_len); + rp->mac_key_len = mac_key_len; + + return 1; +} + +static int +tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, + struct tls12_record_protection *rp, int is_write, CBS *mac_key, CBS *key, + CBS *iv) +{ + if (!tls12_record_protection_unused(rp)) + return 0; + + if ((rp->aead_ctx = EVP_AEAD_CTX_new()) == NULL) + return 0; + + /* AES GCM cipher suites use variable nonce in record. */ + if (rl->aead == EVP_aead_aes_128_gcm() || + rl->aead == EVP_aead_aes_256_gcm()) + rp->aead_variable_nonce_in_record = 1; + + /* ChaCha20 Poly1305 XORs the fixed and variable nonces. */ + if (rl->aead == EVP_aead_chacha20_poly1305()) + rp->aead_xor_nonces = 1; + + if (!CBS_stow(iv, &rp->aead_fixed_nonce, &rp->aead_fixed_nonce_len)) + return 0; + + rp->aead_nonce = calloc(1, EVP_AEAD_nonce_length(rl->aead)); + if (rp->aead_nonce == NULL) + return 0; + + rp->aead_nonce_len = EVP_AEAD_nonce_length(rl->aead); + rp->aead_tag_len = EVP_AEAD_max_overhead(rl->aead); + rp->aead_variable_nonce_len = TLS12_RECORD_SEQ_NUM_LEN; + + if (rp->aead_xor_nonces) { + /* Fixed nonce length must match, variable must not exceed. */ + if (rp->aead_fixed_nonce_len != rp->aead_nonce_len) + return 0; + if (rp->aead_variable_nonce_len > rp->aead_nonce_len) + return 0; + } else { + /* Concatenated nonce length must equal AEAD nonce length. */ + if (rp->aead_fixed_nonce_len + + rp->aead_variable_nonce_len != rp->aead_nonce_len) + return 0; + } + + if (!EVP_AEAD_CTX_init(rp->aead_ctx, rl->aead, CBS_data(key), + CBS_len(key), EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) + return 0; + + return 1; +} + +static int +tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl, + struct tls12_record_protection *rp, int is_write, CBS *mac_key, CBS *key, + CBS *iv) +{ + EVP_PKEY *mac_pkey = NULL; + int gost_param_nid; + int mac_type; + int ret = 0; + + if (!tls12_record_protection_unused(rp)) + goto err; + + mac_type = EVP_PKEY_HMAC; + rp->stream_mac = 0; + + if (CBS_len(iv) > INT_MAX || CBS_len(key) > INT_MAX) + goto err; + if (EVP_CIPHER_iv_length(rl->cipher) != CBS_len(iv)) + goto err; + if (EVP_CIPHER_key_length(rl->cipher) != CBS_len(key)) + goto err; + +#ifndef OPENSSL_NO_GOST + /* XXX die die die */ + /* Special handling for GOST... */ + if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) { + if (CBS_len(mac_key) != 32) + goto err; + mac_type = EVP_PKEY_GOSTIMIT; + rp->stream_mac = 1; + } else { +#endif + if (CBS_len(mac_key) > INT_MAX) + goto err; + if (EVP_MD_size(rl->mac_hash) != CBS_len(mac_key)) + goto err; +#ifndef OPENSSL_NO_GOST + } +#endif + + if ((rp->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + if ((rp->hash_ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if (!tls12_record_layer_set_mac_key(rp, CBS_data(mac_key), + CBS_len(mac_key))) + goto err; + + if ((mac_pkey = EVP_PKEY_new_mac_key(mac_type, NULL, CBS_data(mac_key), + CBS_len(mac_key))) == NULL) + goto err; + + if (!EVP_CipherInit_ex(rp->cipher_ctx, rl->cipher, NULL, CBS_data(key), + CBS_data(iv), is_write)) + goto err; + + if (EVP_DigestSignInit(rp->hash_ctx, NULL, rl->mac_hash, NULL, + mac_pkey) <= 0) + goto err; + + /* More special handling for GOST... */ + if (EVP_CIPHER_type(rl->cipher) == NID_gost89_cnt) { + gost_param_nid = NID_id_tc26_gost_28147_param_Z; + if (EVP_MD_type(rl->handshake_hash) == NID_id_GostR3411_94) + gost_param_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; + + if (EVP_CIPHER_CTX_ctrl(rp->cipher_ctx, EVP_CTRL_GOST_SET_SBOX, + gost_param_nid, 0) <= 0) + goto err; + + if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) { + if (EVP_MD_CTX_ctrl(rp->hash_ctx, EVP_MD_CTRL_GOST_SET_SBOX, + gost_param_nid, 0) <= 0) + goto err; + } + } + + ret = 1; + + err: + EVP_PKEY_free(mac_pkey); + + return ret; +} + +static int +tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl, + struct tls12_record_protection *rp, int is_write, CBS *mac_key, CBS *key, + CBS *iv) +{ + if (rl->aead != NULL) + return tls12_record_layer_ccs_aead(rl, rp, is_write, mac_key, + key, iv); + + return tls12_record_layer_ccs_cipher(rl, rp, is_write, mac_key, + key, iv); +} + +int +tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl, + CBS *mac_key, CBS *key, CBS *iv) +{ + struct tls12_record_protection *read_new = NULL; + int ret = 0; + + if ((read_new = tls12_record_protection_new()) == NULL) + goto err; + + /* Read sequence number gets reset to zero. */ + + /* DTLS epoch is incremented and is permitted to wrap. */ + if (rl->dtls) + read_new->epoch = rl->read_current->epoch + 1; + + if (!tls12_record_layer_change_cipher_state(rl, read_new, 0, + mac_key, key, iv)) + goto err; + + tls12_record_protection_free(rl->read_current); + rl->read = rl->read_current = read_new; + read_new = NULL; + + ret = 1; + + err: + tls12_record_protection_free(read_new); + + return ret; +} + +int +tls12_record_layer_change_write_cipher_state(struct tls12_record_layer *rl, + CBS *mac_key, CBS *key, CBS *iv) +{ + struct tls12_record_protection *write_new; + int ret = 0; + + if ((write_new = tls12_record_protection_new()) == NULL) + goto err; + + /* Write sequence number gets reset to zero. */ + + /* DTLS epoch is incremented and is permitted to wrap. */ + if (rl->dtls) + write_new->epoch = rl->write_current->epoch + 1; + + if (!tls12_record_layer_change_cipher_state(rl, write_new, 1, + mac_key, key, iv)) + goto err; + + if (rl->dtls) { + tls12_record_protection_free(rl->write_previous); + rl->write_previous = rl->write_current; + rl->write_current = NULL; + } + tls12_record_protection_free(rl->write_current); + rl->write = rl->write_current = write_new; + write_new = NULL; + + ret = 1; + + err: + tls12_record_protection_free(write_new); + + return ret; +} + +static int +tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, + uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) +{ + CBS seq; + + CBS_init(&seq, seq_num, seq_num_len); + + if (rl->dtls) { + if (!CBB_add_u16(cbb, epoch)) + return 0; + if (!CBS_skip(&seq, 2)) + return 0; + } + + return CBB_add_bytes(cbb, CBS_data(&seq), CBS_len(&seq)); +} + +static int +tls12_record_layer_pseudo_header(struct tls12_record_layer *rl, + uint8_t content_type, uint16_t record_len, CBS *seq_num, uint8_t **out, + size_t *out_len) +{ + CBB cbb; + + *out = NULL; + *out_len = 0; + + /* Build the pseudo-header used for MAC/AEAD. */ + if (!CBB_init(&cbb, 13)) + goto err; + + if (!CBB_add_bytes(&cbb, CBS_data(seq_num), CBS_len(seq_num))) + goto err; + if (!CBB_add_u8(&cbb, content_type)) + goto err; + if (!CBB_add_u16(&cbb, rl->version)) + goto err; + if (!CBB_add_u16(&cbb, record_len)) + goto err; + + if (!CBB_finish(&cbb, out, out_len)) + goto err; + + return 1; + + err: + CBB_cleanup(&cbb); + + return 0; +} + +static int +tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb, + EVP_MD_CTX *hash_ctx, int stream_mac, CBS *seq_num, uint8_t content_type, + const uint8_t *content, size_t content_len, size_t *out_len) +{ + EVP_MD_CTX *mac_ctx = NULL; + uint8_t *header = NULL; + size_t header_len = 0; + size_t mac_len; + uint8_t *mac; + int ret = 0; + + if ((mac_ctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_MD_CTX_copy(mac_ctx, hash_ctx)) + goto err; + + if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, + seq_num, &header, &header_len)) + goto err; + + if (EVP_DigestSignUpdate(mac_ctx, header, header_len) <= 0) + goto err; + if (EVP_DigestSignUpdate(mac_ctx, content, content_len) <= 0) + goto err; + if (EVP_DigestSignFinal(mac_ctx, NULL, &mac_len) <= 0) + goto err; + if (!CBB_add_space(cbb, &mac, mac_len)) + goto err; + if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0) + goto err; + if (mac_len == 0) + goto err; + + if (stream_mac) { + if (!EVP_MD_CTX_copy(hash_ctx, mac_ctx)) + goto err; + } + + *out_len = mac_len; + ret = 1; + + err: + EVP_MD_CTX_free(mac_ctx); + freezero(header, header_len); + + return ret; +} + +static int +tls12_record_layer_read_mac_cbc(struct tls12_record_layer *rl, CBB *cbb, + uint8_t content_type, CBS *seq_num, const uint8_t *content, + size_t content_len, size_t mac_len, size_t padding_len) +{ + uint8_t *header = NULL; + size_t header_len = 0; + uint8_t *mac = NULL; + size_t out_mac_len = 0; + int ret = 0; + + /* + * Must be constant time to avoid leaking details about CBC padding. + */ + + if (!ssl3_cbc_record_digest_supported(rl->read->hash_ctx)) + goto err; + + if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, + seq_num, &header, &header_len)) + goto err; + + if (!CBB_add_space(cbb, &mac, mac_len)) + goto err; + if (!ssl3_cbc_digest_record(rl->read->hash_ctx, mac, &out_mac_len, header, + content, content_len + mac_len, content_len + mac_len + padding_len, + rl->read->mac_key, rl->read->mac_key_len)) + goto err; + if (mac_len != out_mac_len) + goto err; + + ret = 1; + + err: + freezero(header, header_len); + + return ret; +} + +static int +tls12_record_layer_read_mac(struct tls12_record_layer *rl, CBB *cbb, + uint8_t content_type, CBS *seq_num, const uint8_t *content, + size_t content_len) +{ + EVP_CIPHER_CTX *enc = rl->read->cipher_ctx; + size_t out_len; + + if (EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) + return 0; + + return tls12_record_layer_mac(rl, cbb, rl->read->hash_ctx, + rl->read->stream_mac, seq_num, content_type, content, content_len, + &out_len); +} + +static int +tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, + uint8_t content_type, CBS *seq_num, const uint8_t *content, + size_t content_len, size_t *out_len) +{ + return tls12_record_layer_mac(rl, cbb, rl->write->hash_ctx, + rl->write->stream_mac, seq_num, content_type, content, content_len, + out_len); +} + +static int +tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, + struct tls12_record_protection *rp, CBS *seq_num) +{ + CBB cbb; + + if (rp->aead_variable_nonce_len > CBS_len(seq_num)) + return 0; + + /* Fixed nonce and variable nonce (sequence number) are concatenated. */ + if (!CBB_init_fixed(&cbb, rp->aead_nonce, rp->aead_nonce_len)) + goto err; + if (!CBB_add_bytes(&cbb, rp->aead_fixed_nonce, + rp->aead_fixed_nonce_len)) + goto err; + if (!CBB_add_bytes(&cbb, CBS_data(seq_num), + rp->aead_variable_nonce_len)) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; + + return 1; + + err: + CBB_cleanup(&cbb); + + return 0; +} + +static int +tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, + struct tls12_record_protection *rp, CBS *seq_num) +{ + uint8_t *pad; + CBB cbb; + int i; + + if (rp->aead_variable_nonce_len > CBS_len(seq_num)) + return 0; + if (rp->aead_fixed_nonce_len < rp->aead_variable_nonce_len) + return 0; + if (rp->aead_fixed_nonce_len != rp->aead_nonce_len) + return 0; + + /* + * Variable nonce (sequence number) is right padded, before the fixed + * nonce is XOR'd in. + */ + if (!CBB_init_fixed(&cbb, rp->aead_nonce, rp->aead_nonce_len)) + goto err; + if (!CBB_add_space(&cbb, &pad, + rp->aead_fixed_nonce_len - rp->aead_variable_nonce_len)) + goto err; + if (!CBB_add_bytes(&cbb, CBS_data(seq_num), + rp->aead_variable_nonce_len)) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; + + for (i = 0; i < rp->aead_fixed_nonce_len; i++) + rp->aead_nonce[i] ^= rp->aead_fixed_nonce[i]; + + return 1; + + err: + CBB_cleanup(&cbb); + + return 0; +} + +static int +tls12_record_layer_open_record_plaintext(struct tls12_record_layer *rl, + uint8_t content_type, CBS *fragment, struct tls_content *out) +{ + if (tls12_record_protection_engaged(rl->read)) + return 0; + + return tls_content_dup_data(out, content_type, CBS_data(fragment), + CBS_len(fragment)); +} + +static int +tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, + uint8_t content_type, CBS *seq_num, CBS *fragment, struct tls_content *out) +{ + struct tls12_record_protection *rp = rl->read; + uint8_t *header = NULL; + size_t header_len = 0; + uint8_t *content = NULL; + size_t content_len = 0; + size_t out_len = 0; + CBS var_nonce; + int ret = 0; + + if (rp->aead_xor_nonces) { + if (!tls12_record_layer_aead_xored_nonce(rl, rp, seq_num)) + goto err; + } else if (rp->aead_variable_nonce_in_record) { + if (!CBS_get_bytes(fragment, &var_nonce, + rp->aead_variable_nonce_len)) + goto err; + if (!tls12_record_layer_aead_concat_nonce(rl, rp, &var_nonce)) + goto err; + } else { + if (!tls12_record_layer_aead_concat_nonce(rl, rp, seq_num)) + goto err; + } + + /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ + if (CBS_len(fragment) < rp->aead_tag_len) { + rl->alert_desc = SSL_AD_BAD_RECORD_MAC; + goto err; + } + if (CBS_len(fragment) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + rl->alert_desc = SSL_AD_RECORD_OVERFLOW; + goto err; + } + + content_len = CBS_len(fragment) - rp->aead_tag_len; + if ((content = calloc(1, CBS_len(fragment))) == NULL) { + content_len = 0; + goto err; + } + + if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, + seq_num, &header, &header_len)) + goto err; + + if (!EVP_AEAD_CTX_open(rp->aead_ctx, content, &out_len, content_len, + rp->aead_nonce, rp->aead_nonce_len, CBS_data(fragment), + CBS_len(fragment), header, header_len)) { + rl->alert_desc = SSL_AD_BAD_RECORD_MAC; + goto err; + } + + if (out_len > SSL3_RT_MAX_PLAIN_LENGTH) { + rl->alert_desc = SSL_AD_RECORD_OVERFLOW; + goto err; + } + + if (out_len != content_len) + goto err; + + tls_content_set_data(out, content_type, content, content_len); + content = NULL; + content_len = 0; + + ret = 1; + + err: + freezero(header, header_len); + freezero(content, content_len); + + return ret; +} + +static int +tls12_record_layer_open_record_protected_cipher(struct tls12_record_layer *rl, + uint8_t content_type, CBS *seq_num, CBS *fragment, struct tls_content *out) +{ + EVP_CIPHER_CTX *enc = rl->read->cipher_ctx; + SSL3_RECORD_INTERNAL rrec; + size_t block_size, eiv_len; + uint8_t *mac = NULL; + size_t mac_len = 0; + uint8_t *out_mac = NULL; + size_t out_mac_len = 0; + uint8_t *content = NULL; + size_t content_len = 0; + size_t min_len; + CBB cbb_mac; + int ret = 0; + + memset(&cbb_mac, 0, sizeof(cbb_mac)); + memset(&rrec, 0, sizeof(rrec)); + + if (!tls12_record_protection_block_size(rl->read, &block_size)) + goto err; + + /* Determine explicit IV length. */ + eiv_len = 0; + if (rl->version != TLS1_VERSION) { + if (!tls12_record_protection_eiv_len(rl->read, &eiv_len)) + goto err; + } + + mac_len = 0; + if (rl->read->hash_ctx != NULL) { + if (!tls12_record_protection_mac_len(rl->read, &mac_len)) + goto err; + } + + /* CBC has at least one padding byte. */ + min_len = eiv_len + mac_len; + if (EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) + min_len += 1; + + if (CBS_len(fragment) < min_len) { + rl->alert_desc = SSL_AD_BAD_RECORD_MAC; + goto err; + } + if (CBS_len(fragment) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + rl->alert_desc = SSL_AD_RECORD_OVERFLOW; + goto err; + } + if (CBS_len(fragment) % block_size != 0) { + rl->alert_desc = SSL_AD_BAD_RECORD_MAC; + goto err; + } + + if ((content = calloc(1, CBS_len(fragment))) == NULL) + goto err; + content_len = CBS_len(fragment); + + if (!EVP_Cipher(enc, content, CBS_data(fragment), CBS_len(fragment))) + goto err; + + rrec.data = content; + rrec.input = content; + rrec.length = content_len; + + /* + * We now have to remove padding, extract MAC, calculate MAC + * and compare MAC in constant time. + */ + if (block_size > 1) + ssl3_cbc_remove_padding(&rrec, eiv_len, mac_len); + + if ((mac = calloc(1, mac_len)) == NULL) + goto err; + + if (!CBB_init(&cbb_mac, EVP_MAX_MD_SIZE)) + goto err; + if (EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) { + ssl3_cbc_copy_mac(mac, &rrec, mac_len, rrec.length + + rrec.padding_length); + rrec.length -= mac_len; + if (!tls12_record_layer_read_mac_cbc(rl, &cbb_mac, content_type, + seq_num, rrec.input, rrec.length, mac_len, + rrec.padding_length)) + goto err; + } else { + rrec.length -= mac_len; + memcpy(mac, rrec.data + rrec.length, mac_len); + if (!tls12_record_layer_read_mac(rl, &cbb_mac, content_type, + seq_num, rrec.input, rrec.length)) + goto err; + } + if (!CBB_finish(&cbb_mac, &out_mac, &out_mac_len)) + goto err; + if (mac_len != out_mac_len) + goto err; + + if (timingsafe_memcmp(mac, out_mac, mac_len) != 0) { + rl->alert_desc = SSL_AD_BAD_RECORD_MAC; + goto err; + } + + if (rrec.length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_len) { + rl->alert_desc = SSL_AD_BAD_RECORD_MAC; + goto err; + } + if (rrec.length > SSL3_RT_MAX_PLAIN_LENGTH) { + rl->alert_desc = SSL_AD_RECORD_OVERFLOW; + goto err; + } + + tls_content_set_data(out, content_type, content, content_len); + content = NULL; + content_len = 0; + + /* Actual content is after EIV, minus padding and MAC. */ + if (!tls_content_set_bounds(out, eiv_len, rrec.length)) + goto err; + + ret = 1; + + err: + CBB_cleanup(&cbb_mac); + freezero(mac, mac_len); + freezero(out_mac, out_mac_len); + freezero(content, content_len); + + return ret; +} + +int +tls12_record_layer_open_record(struct tls12_record_layer *rl, uint8_t *buf, + size_t buf_len, struct tls_content *out) +{ + CBS cbs, fragment, seq_num; + uint16_t version; + uint8_t content_type; + + CBS_init(&cbs, buf, buf_len); + CBS_init(&seq_num, rl->read->seq_num, sizeof(rl->read->seq_num)); + + if (!CBS_get_u8(&cbs, &content_type)) + return 0; + if (!CBS_get_u16(&cbs, &version)) + return 0; + if (rl->dtls) { + /* + * The DTLS sequence number is split into a 16 bit epoch and + * 48 bit sequence number, however for the purposes of record + * processing it is treated the same as a TLS 64 bit sequence + * number. DTLS also uses explicit read sequence numbers, which + * we need to extract from the DTLS record header. + */ + if (!CBS_get_bytes(&cbs, &seq_num, SSL3_SEQUENCE_SIZE)) + return 0; + if (!CBS_write_bytes(&seq_num, rl->read->seq_num, + sizeof(rl->read->seq_num), NULL)) + return 0; + } + if (!CBS_get_u16_length_prefixed(&cbs, &fragment)) + return 0; + + if (rl->read->aead_ctx != NULL) { + if (!tls12_record_layer_open_record_protected_aead(rl, + content_type, &seq_num, &fragment, out)) + return 0; + } else if (rl->read->cipher_ctx != NULL) { + if (!tls12_record_layer_open_record_protected_cipher(rl, + content_type, &seq_num, &fragment, out)) + return 0; + } else { + if (!tls12_record_layer_open_record_plaintext(rl, + content_type, &fragment, out)) + return 0; + } + + if (!rl->dtls) { + if (!tls12_record_layer_inc_seq_num(rl, rl->read->seq_num)) + return 0; + } + + return 1; +} + +static int +tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out) +{ + if (tls12_record_protection_engaged(rl->write)) + return 0; + + return CBB_add_bytes(out, content, content_len); +} + +static int +tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, + uint8_t content_type, CBS *seq_num, const uint8_t *content, + size_t content_len, CBB *out) +{ + struct tls12_record_protection *rp = rl->write; + uint8_t *header = NULL; + size_t header_len = 0; + size_t enc_record_len, out_len; + uint8_t *enc_data; + int ret = 0; + + if (rp->aead_xor_nonces) { + if (!tls12_record_layer_aead_xored_nonce(rl, rp, seq_num)) + goto err; + } else { + if (!tls12_record_layer_aead_concat_nonce(rl, rp, seq_num)) + goto err; + } + + if (rp->aead_variable_nonce_in_record) { + if (rp->aead_variable_nonce_len > CBS_len(seq_num)) + goto err; + if (!CBB_add_bytes(out, CBS_data(seq_num), + rp->aead_variable_nonce_len)) + goto err; + } + + if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, + seq_num, &header, &header_len)) + goto err; + + /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ + enc_record_len = content_len + rp->aead_tag_len; + if (enc_record_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) + goto err; + if (!CBB_add_space(out, &enc_data, enc_record_len)) + goto err; + + if (!EVP_AEAD_CTX_seal(rp->aead_ctx, enc_data, &out_len, enc_record_len, + rp->aead_nonce, rp->aead_nonce_len, content, content_len, header, + header_len)) + goto err; + + if (out_len != enc_record_len) + goto err; + + ret = 1; + + err: + freezero(header, header_len); + + return ret; +} + +static int +tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl, + uint8_t content_type, CBS *seq_num, const uint8_t *content, + size_t content_len, CBB *out) +{ + EVP_CIPHER_CTX *enc = rl->write->cipher_ctx; + size_t block_size, eiv_len, mac_len, pad_len; + uint8_t *enc_data, *eiv, *pad, pad_val; + uint8_t *plain = NULL; + size_t plain_len = 0; + int ret = 0; + CBB cbb; + + if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH)) + goto err; + + /* Add explicit IV if necessary. */ + eiv_len = 0; + if (rl->version != TLS1_VERSION) { + if (!tls12_record_protection_eiv_len(rl->write, &eiv_len)) + goto err; + } + if (eiv_len > 0) { + if (!CBB_add_space(&cbb, &eiv, eiv_len)) + goto err; + arc4random_buf(eiv, eiv_len); + } + + if (!CBB_add_bytes(&cbb, content, content_len)) + goto err; + + mac_len = 0; + if (rl->write->hash_ctx != NULL) { + if (!tls12_record_layer_write_mac(rl, &cbb, content_type, + seq_num, content, content_len, &mac_len)) + goto err; + } + + plain_len = eiv_len + content_len + mac_len; + + /* Add padding to block size, if necessary. */ + if (!tls12_record_protection_block_size(rl->write, &block_size)) + goto err; + if (block_size > 1) { + pad_len = block_size - (plain_len % block_size); + pad_val = pad_len - 1; + + if (pad_len > 255) + goto err; + if (!CBB_add_space(&cbb, &pad, pad_len)) + goto err; + memset(pad, pad_val, pad_len); + } + + if (!CBB_finish(&cbb, &plain, &plain_len)) + goto err; + + if (plain_len % block_size != 0) + goto err; + if (plain_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) + goto err; + + if (!CBB_add_space(out, &enc_data, plain_len)) + goto err; + if (!EVP_Cipher(enc, enc_data, plain, plain_len)) + goto err; + + ret = 1; + + err: + CBB_cleanup(&cbb); + freezero(plain, plain_len); + + return ret; +} + +int +tls12_record_layer_seal_record(struct tls12_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len, CBB *cbb) +{ + uint8_t *seq_num_data = NULL; + size_t seq_num_len = 0; + CBB fragment, seq_num_cbb; + CBS seq_num; + int ret = 0; + + /* + * Construct the effective sequence number - this is used in both + * the DTLS header and for MAC calculations. + */ + if (!CBB_init(&seq_num_cbb, SSL3_SEQUENCE_SIZE)) + goto err; + if (!tls12_record_layer_build_seq_num(rl, &seq_num_cbb, rl->write->epoch, + rl->write->seq_num, sizeof(rl->write->seq_num))) + goto err; + if (!CBB_finish(&seq_num_cbb, &seq_num_data, &seq_num_len)) + goto err; + CBS_init(&seq_num, seq_num_data, seq_num_len); + + if (!CBB_add_u8(cbb, content_type)) + goto err; + if (!CBB_add_u16(cbb, rl->version)) + goto err; + if (rl->dtls) { + if (!CBB_add_bytes(cbb, CBS_data(&seq_num), CBS_len(&seq_num))) + goto err; + } + if (!CBB_add_u16_length_prefixed(cbb, &fragment)) + goto err; + + if (rl->write->aead_ctx != NULL) { + if (!tls12_record_layer_seal_record_protected_aead(rl, + content_type, &seq_num, content, content_len, &fragment)) + goto err; + } else if (rl->write->cipher_ctx != NULL) { + if (!tls12_record_layer_seal_record_protected_cipher(rl, + content_type, &seq_num, content, content_len, &fragment)) + goto err; + } else { + if (!tls12_record_layer_seal_record_plaintext(rl, + content_type, content, content_len, &fragment)) + goto err; + } + + if (!CBB_flush(cbb)) + goto err; + + if (!tls12_record_layer_inc_seq_num(rl, rl->write->seq_num)) + goto err; + + ret = 1; + + err: + CBB_cleanup(&seq_num_cbb); + free(seq_num_data); + + return ret; +} diff --git a/Libraries/libressl/ssl/tls13_client.c b/Libraries/libressl/ssl/tls13_client.c new file mode 100644 index 000000000..053cf1689 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_client.c @@ -0,0 +1,1060 @@ +/* $OpenBSD: tls13_client.c,v 1.102 2023/06/10 15:34:36 tb Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" +#include "tls13_handshake.h" +#include "tls13_internal.h" + +int +tls13_client_init(struct tls13_ctx *ctx) +{ + const uint16_t *groups; + size_t groups_len; + SSL *s = ctx->ssl; + + if (!ssl_supported_tls_version_range(s, &ctx->hs->our_min_tls_version, + &ctx->hs->our_max_tls_version)) { + SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); + return 0; + } + s->version = ctx->hs->our_max_tls_version; + + tls13_record_layer_set_retry_after_phh(ctx->rl, + (s->mode & SSL_MODE_AUTO_RETRY) != 0); + + if (!ssl_get_new_session(s, 0)) /* XXX */ + return 0; + + if (!tls1_transcript_init(s)) + return 0; + + /* Generate a key share using our preferred group. */ + tls1_get_group_list(s, 0, &groups, &groups_len); + if (groups_len < 1) + return 0; + if ((ctx->hs->key_share = tls_key_share_new(groups[0])) == NULL) + return 0; + if (!tls_key_share_generate(ctx->hs->key_share)) + return 0; + + arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); + + /* + * The legacy session identifier should either be set to an + * unpredictable 32-byte value or zero length... a non-zero length + * legacy session identifier triggers compatibility mode (see RFC 8446 + * Appendix D.4). In the pre-TLSv1.3 case a zero length value is used. + */ + if (ctx->middlebox_compat && + ctx->hs->our_max_tls_version >= TLS1_3_VERSION) { + arc4random_buf(ctx->hs->tls13.legacy_session_id, + sizeof(ctx->hs->tls13.legacy_session_id)); + ctx->hs->tls13.legacy_session_id_len = + sizeof(ctx->hs->tls13.legacy_session_id); + } + + return 1; +} + +int +tls13_client_connect(struct tls13_ctx *ctx) +{ + if (ctx->mode != TLS13_HS_CLIENT) + return TLS13_IO_FAILURE; + + return tls13_handshake_perform(ctx); +} + +static int +tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb) +{ + CBB cipher_suites, compression_methods, session_id; + uint16_t client_version; + SSL *s = ctx->ssl; + + /* Legacy client version is capped at TLS 1.2. */ + if (!ssl_max_legacy_version(s, &client_version)) + goto err; + + if (!CBB_add_u16(cbb, client_version)) + goto err; + if (!CBB_add_bytes(cbb, s->s3->client_random, SSL3_RANDOM_SIZE)) + goto err; + + if (!CBB_add_u8_length_prefixed(cbb, &session_id)) + goto err; + if (!CBB_add_bytes(&session_id, ctx->hs->tls13.legacy_session_id, + ctx->hs->tls13.legacy_session_id_len)) + goto err; + + if (!CBB_add_u16_length_prefixed(cbb, &cipher_suites)) + goto err; + if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &cipher_suites)) { + SSLerror(s, SSL_R_NO_CIPHERS_AVAILABLE); + goto err; + } + + if (!CBB_add_u8_length_prefixed(cbb, &compression_methods)) + goto err; + if (!CBB_add_u8(&compression_methods, 0)) + goto err; + + if (!tlsext_client_build(s, SSL_TLSEXT_MSG_CH, cbb)) + goto err; + + if (!CBB_flush(cbb)) + goto err; + + return 1; + + err: + return 0; +} + +int +tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb) +{ + if (ctx->hs->our_min_tls_version < TLS1_2_VERSION) + tls13_record_layer_set_legacy_version(ctx->rl, TLS1_VERSION); + + /* We may receive a pre-TLSv1.3 alert in response to the client hello. */ + tls13_record_layer_allow_legacy_alerts(ctx->rl, 1); + + if (!tls13_client_hello_build(ctx, cbb)) + return 0; + + return 1; +} + +int +tls13_client_hello_sent(struct tls13_ctx *ctx) +{ + tls1_transcript_freeze(ctx->ssl); + + if (ctx->middlebox_compat) { + tls13_record_layer_allow_ccs(ctx->rl, 1); + ctx->send_dummy_ccs = 1; + } + + return 1; +} + +static int +tls13_server_hello_is_legacy(CBS *cbs) +{ + CBS extensions_block, extensions, extension_data; + uint16_t selected_version = 0; + uint16_t type; + + CBS_dup(cbs, &extensions_block); + + if (!CBS_get_u16_length_prefixed(&extensions_block, &extensions)) + return 1; + + while (CBS_len(&extensions) > 0) { + if (!CBS_get_u16(&extensions, &type)) + return 1; + if (!CBS_get_u16_length_prefixed(&extensions, &extension_data)) + return 1; + + if (type != TLSEXT_TYPE_supported_versions) + continue; + if (!CBS_get_u16(&extension_data, &selected_version)) + return 1; + if (CBS_len(&extension_data) != 0) + return 1; + } + + return (selected_version < TLS1_3_VERSION); +} + +static int +tls13_server_hello_is_retry(CBS *cbs) +{ + CBS server_hello, server_random; + uint16_t legacy_version; + + CBS_dup(cbs, &server_hello); + + if (!CBS_get_u16(&server_hello, &legacy_version)) + return 0; + if (!CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE)) + return 0; + + /* See if this is a HelloRetryRequest. */ + return CBS_mem_equal(&server_random, tls13_hello_retry_request_hash, + sizeof(tls13_hello_retry_request_hash)); +} + +static int +tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) +{ + CBS server_random, session_id; + uint16_t tlsext_msg_type = SSL_TLSEXT_MSG_SH; + uint16_t cipher_suite, legacy_version; + uint8_t compression_method; + const SSL_CIPHER *cipher; + int alert_desc; + SSL *s = ctx->ssl; + + if (!CBS_get_u16(cbs, &legacy_version)) + goto err; + if (!CBS_get_bytes(cbs, &server_random, SSL3_RANDOM_SIZE)) + goto err; + if (!CBS_get_u8_length_prefixed(cbs, &session_id)) + goto err; + if (!CBS_get_u16(cbs, &cipher_suite)) + goto err; + if (!CBS_get_u8(cbs, &compression_method)) + goto err; + + if (tls13_server_hello_is_legacy(cbs)) { + if (ctx->hs->our_max_tls_version >= TLS1_3_VERSION) { + /* + * RFC 8446 section 4.1.3: we must not downgrade if + * the server random value contains the TLS 1.2 or 1.1 + * magical value. + */ + if (!CBS_skip(&server_random, CBS_len(&server_random) - + sizeof(tls13_downgrade_12))) + goto err; + if (CBS_mem_equal(&server_random, tls13_downgrade_12, + sizeof(tls13_downgrade_12)) || + CBS_mem_equal(&server_random, tls13_downgrade_11, + sizeof(tls13_downgrade_11))) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + } + + if (!CBS_skip(cbs, CBS_len(cbs))) + goto err; + + ctx->hs->tls13.use_legacy = 1; + return 1; + } + + /* From here on in we know we are doing TLSv1.3. */ + tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION); + tls13_record_layer_allow_legacy_alerts(ctx->rl, 0); + + /* See if this is a HelloRetryRequest. */ + /* XXX - see if we can avoid doing this twice. */ + if (CBS_mem_equal(&server_random, tls13_hello_retry_request_hash, + sizeof(tls13_hello_retry_request_hash))) { + tlsext_msg_type = SSL_TLSEXT_MSG_HRR; + ctx->hs->tls13.hrr = 1; + } + + if (!tlsext_client_parse(s, tlsext_msg_type, cbs, &alert_desc)) { + ctx->alert = alert_desc; + goto err; + } + + /* + * The supported versions extension indicated 0x0304 or greater. + * Ensure that it was 0x0304 and that legacy version is set to 0x0303 + * (RFC 8446 section 4.2.1). + */ + if (ctx->hs->tls13.server_version != TLS1_3_VERSION || + legacy_version != TLS1_2_VERSION) { + ctx->alert = TLS13_ALERT_PROTOCOL_VERSION; + goto err; + } + ctx->hs->negotiated_tls_version = ctx->hs->tls13.server_version; + ctx->hs->peer_legacy_version = legacy_version; + + /* The session_id must match. */ + if (!CBS_mem_equal(&session_id, ctx->hs->tls13.legacy_session_id, + ctx->hs->tls13.legacy_session_id_len)) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + + /* + * Ensure that the cipher suite is one that we offered in the client + * hello and that it is a TLSv1.3 cipher suite. + */ + cipher = ssl3_get_cipher_by_value(cipher_suite); + if (cipher == NULL || !ssl_cipher_in_list(SSL_get_ciphers(s), cipher)) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + if (cipher->algorithm_ssl != SSL_TLSV1_3) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + if (!(ctx->handshake_stage.hs_type & WITHOUT_HRR) && !ctx->hs->tls13.hrr) { + /* + * A ServerHello following a HelloRetryRequest MUST use the same + * cipher suite (RFC 8446 section 4.1.4). + */ + if (ctx->hs->cipher != cipher) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + } + ctx->hs->cipher = cipher; + + if (compression_method != 0) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + + return 1; + + err: + if (ctx->alert == 0) + ctx->alert = TLS13_ALERT_DECODE_ERROR; + + return 0; +} + +static int +tls13_client_engage_record_protection(struct tls13_ctx *ctx) +{ + struct tls13_secrets *secrets; + struct tls13_secret context; + unsigned char buf[EVP_MAX_MD_SIZE]; + uint8_t *shared_key = NULL; + size_t shared_key_len = 0; + size_t hash_len; + SSL *s = ctx->ssl; + int ret = 0; + + /* Derive the shared key and engage record protection. */ + + if (!tls_key_share_derive(ctx->hs->key_share, &shared_key, + &shared_key_len)) + goto err; + + s->session->cipher = ctx->hs->cipher; + s->session->ssl_version = ctx->hs->tls13.server_version; + + if ((ctx->aead = tls13_cipher_aead(ctx->hs->cipher)) == NULL) + goto err; + if ((ctx->hash = tls13_cipher_hash(ctx->hs->cipher)) == NULL) + goto err; + + if ((secrets = tls13_secrets_create(ctx->hash, 0)) == NULL) + goto err; + ctx->hs->tls13.secrets = secrets; + + /* XXX - pass in hash. */ + if (!tls1_transcript_hash_init(s)) + goto err; + tls1_transcript_free(s); + if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len)) + goto err; + context.data = buf; + context.len = hash_len; + + /* Early secrets. */ + if (!tls13_derive_early_secrets(secrets, secrets->zeros.data, + secrets->zeros.len, &context)) + goto err; + + /* Handshake secrets. */ + if (!tls13_derive_handshake_secrets(ctx->hs->tls13.secrets, shared_key, + shared_key_len, &context)) + goto err; + + tls13_record_layer_set_aead(ctx->rl, ctx->aead); + tls13_record_layer_set_hash(ctx->rl, ctx->hash); + + if (!tls13_record_layer_set_read_traffic_key(ctx->rl, + &secrets->server_handshake_traffic, ssl_encryption_handshake)) + goto err; + if (!tls13_record_layer_set_write_traffic_key(ctx->rl, + &secrets->client_handshake_traffic, ssl_encryption_handshake)) + goto err; + + ret = 1; + + err: + freezero(shared_key, shared_key_len); + + return ret; +} + +int +tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + /* + * The state machine has no way of knowing if we're going to receive a + * HelloRetryRequest or a ServerHello. As such, we have to handle + * this case here and hand off to the appropriate function. + */ + if (!tls13_server_hello_is_retry(cbs)) { + ctx->handshake_stage.hs_type |= WITHOUT_HRR; + return tls13_server_hello_recv(ctx, cbs); + } + + if (!tls13_server_hello_process(ctx, cbs)) + return 0; + + /* + * This may have been a TLSv1.2 or earlier ServerHello that just + * happened to have matching server random... + */ + if (ctx->hs->tls13.use_legacy) + return tls13_use_legacy_client(ctx); + + if (!ctx->hs->tls13.hrr) + return 0; + + if (!tls13_synthetic_handshake_message(ctx)) + return 0; + if (!tls13_handshake_msg_record(ctx)) + return 0; + + ctx->hs->tls13.hrr = 0; + + return 1; +} + +int +tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb) +{ + /* + * Ensure that the server supported group is one that we listed in our + * supported groups and is not the same as the key share we previously + * offered. + */ + if (!tls1_check_group(ctx->ssl, ctx->hs->tls13.server_group)) + return 0; /* XXX alert */ + if (ctx->hs->tls13.server_group == tls_key_share_group(ctx->hs->key_share)) + return 0; /* XXX alert */ + + /* Switch to new key share. */ + tls_key_share_free(ctx->hs->key_share); + if ((ctx->hs->key_share = + tls_key_share_new(ctx->hs->tls13.server_group)) == NULL) + return 0; + if (!tls_key_share_generate(ctx->hs->key_share)) + return 0; + + if (!tls13_client_hello_build(ctx, cbb)) + return 0; + + return 1; +} + +int +tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + SSL *s = ctx->ssl; + + /* + * We may have received a legacy (pre-TLSv1.3) ServerHello or a TLSv1.3 + * ServerHello. HelloRetryRequests have already been handled. + */ + if (!tls13_server_hello_process(ctx, cbs)) + return 0; + + if (ctx->handshake_stage.hs_type & WITHOUT_HRR) { + tls1_transcript_unfreeze(s); + if (!tls13_handshake_msg_record(ctx)) + return 0; + } + + if (ctx->hs->tls13.use_legacy) { + if (!(ctx->handshake_stage.hs_type & WITHOUT_HRR)) + return 0; + return tls13_use_legacy_client(ctx); + } + + if (ctx->hs->tls13.hrr) { + /* The server has sent two HelloRetryRequests. */ + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + return 0; + } + + if (!tls13_client_engage_record_protection(ctx)) + return 0; + + ctx->handshake_stage.hs_type |= NEGOTIATED; + + return 1; +} + +int +tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + int alert_desc; + + if (!tlsext_client_parse(ctx->ssl, SSL_TLSEXT_MSG_EE, cbs, &alert_desc)) { + ctx->alert = alert_desc; + return 0; + } + + return 1; +} + +int +tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + CBS cert_request_context; + int alert_desc; + + /* + * Thanks to poor state design in the RFC, this function can be called + * when we actually have a certificate message instead of a certificate + * request... in that case we call the certificate handler after + * switching state, to avoid advancing state. + */ + if (tls13_handshake_msg_type(ctx->hs_msg) == TLS13_MT_CERTIFICATE) { + ctx->handshake_stage.hs_type |= WITHOUT_CR; + return tls13_server_certificate_recv(ctx, cbs); + } + + if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context)) + goto err; + if (CBS_len(&cert_request_context) != 0) + goto err; + + if (!tlsext_client_parse(ctx->ssl, SSL_TLSEXT_MSG_CR, cbs, &alert_desc)) { + ctx->alert = alert_desc; + goto err; + } + + return 1; + + err: + if (ctx->alert == 0) + ctx->alert = TLS13_ALERT_DECODE_ERROR; + + return 0; +} + +int +tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + CBS cert_request_context, cert_list, cert_data; + struct stack_st_X509 *certs = NULL; + SSL *s = ctx->ssl; + X509 *cert = NULL; + const uint8_t *p; + int alert_desc; + int ret = 0; + + if ((certs = sk_X509_new_null()) == NULL) + goto err; + + if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context)) + goto err; + if (CBS_len(&cert_request_context) != 0) + goto err; + if (!CBS_get_u24_length_prefixed(cbs, &cert_list)) + goto err; + + while (CBS_len(&cert_list) > 0) { + if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) + goto err; + + if (!tlsext_client_parse(ctx->ssl, SSL_TLSEXT_MSG_CT, + &cert_list, &alert_desc)) { + ctx->alert = alert_desc; + goto err; + } + + p = CBS_data(&cert_data); + if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) + goto err; + if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) + goto err; + + if (!sk_X509_push(certs, cert)) + goto err; + + cert = NULL; + } + + /* A server must always provide a non-empty certificate list. */ + if (sk_X509_num(certs) < 1) { + ctx->alert = TLS13_ALERT_DECODE_ERROR; + tls13_set_errorx(ctx, TLS13_ERR_NO_PEER_CERTIFICATE, 0, + "peer failed to provide a certificate", NULL); + goto err; + } + + /* + * At this stage we still have no proof of possession. As such, it would + * be preferable to keep the chain and verify once we have successfully + * processed the CertificateVerify message. + */ + if (ssl_verify_cert_chain(s, certs) <= 0 && + s->verify_mode != SSL_VERIFY_NONE) { + ctx->alert = ssl_verify_alarm_type(s->verify_result); + tls13_set_errorx(ctx, TLS13_ERR_VERIFY_FAILED, 0, + "failed to verify peer certificate", NULL); + goto err; + } + s->session->verify_result = s->verify_result; + ERR_clear_error(); + + if (!tls_process_peer_certs(s, certs)) + goto err; + + if (ctx->ocsp_status_recv_cb != NULL && + !ctx->ocsp_status_recv_cb(ctx)) + goto err; + + ret = 1; + + err: + sk_X509_pop_free(certs, X509_free); + X509_free(cert); + + return ret; +} + +int +tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + const struct ssl_sigalg *sigalg; + uint16_t signature_scheme; + uint8_t *sig_content = NULL; + size_t sig_content_len; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + X509 *cert; + CBS signature; + CBB cbb; + int ret = 0; + + memset(&cbb, 0, sizeof(cbb)); + + if (!CBS_get_u16(cbs, &signature_scheme)) + goto err; + if (!CBS_get_u16_length_prefixed(cbs, &signature)) + goto err; + + if (!CBB_init(&cbb, 0)) + goto err; + if (!CBB_add_bytes(&cbb, tls13_cert_verify_pad, + sizeof(tls13_cert_verify_pad))) + goto err; + if (!CBB_add_bytes(&cbb, tls13_cert_server_verify_context, + strlen(tls13_cert_server_verify_context))) + goto err; + if (!CBB_add_u8(&cbb, 0)) + goto err; + if (!CBB_add_bytes(&cbb, ctx->hs->tls13.transcript_hash, + ctx->hs->tls13.transcript_hash_len)) + goto err; + if (!CBB_finish(&cbb, &sig_content, &sig_content_len)) + goto err; + + if ((cert = ctx->ssl->session->peer_cert) == NULL) + goto err; + if ((pkey = X509_get0_pubkey(cert)) == NULL) + goto err; + if ((sigalg = ssl_sigalg_for_peer(ctx->ssl, pkey, + signature_scheme)) == NULL) + goto err; + ctx->hs->peer_sigalg = sigalg; + + if (CBS_len(&signature) > EVP_PKEY_size(pkey)) + goto err; + + if ((mdctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_DigestVerifyInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) + goto err; + if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) + goto err; + if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) + goto err; + } + if (EVP_DigestVerify(mdctx, CBS_data(&signature), CBS_len(&signature), + sig_content, sig_content_len) <= 0) { + ctx->alert = TLS13_ALERT_DECRYPT_ERROR; + goto err; + } + + ret = 1; + + err: + if (!ret && ctx->alert == 0) + ctx->alert = TLS13_ALERT_DECODE_ERROR; + CBB_cleanup(&cbb); + EVP_MD_CTX_free(mdctx); + free(sig_content); + + return ret; +} + +int +tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret context = { .data = "", .len = 0 }; + struct tls13_secret finished_key; + uint8_t transcript_hash[EVP_MAX_MD_SIZE]; + size_t transcript_hash_len; + uint8_t *verify_data = NULL; + size_t verify_data_len; + uint8_t key[EVP_MAX_MD_SIZE]; + HMAC_CTX *hmac_ctx = NULL; + unsigned int hlen; + int ret = 0; + + /* + * Verify server finished. + */ + finished_key.data = key; + finished_key.len = EVP_MD_size(ctx->hash); + + if (!tls13_hkdf_expand_label(&finished_key, ctx->hash, + &secrets->server_handshake_traffic, "finished", + &context)) + goto err; + + if ((hmac_ctx = HMAC_CTX_new()) == NULL) + goto err; + if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len, + ctx->hash, NULL)) + goto err; + if (!HMAC_Update(hmac_ctx, ctx->hs->tls13.transcript_hash, + ctx->hs->tls13.transcript_hash_len)) + goto err; + verify_data_len = HMAC_size(hmac_ctx); + if ((verify_data = calloc(1, verify_data_len)) == NULL) + goto err; + if (!HMAC_Final(hmac_ctx, verify_data, &hlen)) + goto err; + if (hlen != verify_data_len) + goto err; + + if (!CBS_mem_equal(cbs, verify_data, verify_data_len)) { + ctx->alert = TLS13_ALERT_DECRYPT_ERROR; + goto err; + } + + if (!CBS_write_bytes(cbs, ctx->hs->peer_finished, + sizeof(ctx->hs->peer_finished), + &ctx->hs->peer_finished_len)) + goto err; + + if (!CBS_skip(cbs, verify_data_len)) + goto err; + + /* + * Derive application traffic keys. + */ + if (!tls1_transcript_hash_value(ctx->ssl, transcript_hash, + sizeof(transcript_hash), &transcript_hash_len)) + goto err; + + context.data = transcript_hash; + context.len = transcript_hash_len; + + if (!tls13_derive_application_secrets(secrets, &context)) + goto err; + + /* + * Any records following the server finished message must be encrypted + * using the server application traffic keys. + */ + if (!tls13_record_layer_set_read_traffic_key(ctx->rl, + &secrets->server_application_traffic, ssl_encryption_application)) + goto err; + + tls13_record_layer_allow_ccs(ctx->rl, 0); + + ret = 1; + + err: + HMAC_CTX_free(hmac_ctx); + free(verify_data); + + return ret; +} + +static int +tls13_client_check_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY *cpk, + int *ok, const struct ssl_sigalg **out_sigalg) +{ + const struct ssl_sigalg *sigalg; + SSL *s = ctx->ssl; + + *ok = 0; + *out_sigalg = NULL; + + if (cpk->x509 == NULL || cpk->privatekey == NULL) + goto done; + + if ((sigalg = ssl_sigalg_select(s, cpk->privatekey)) == NULL) + goto done; + + *ok = 1; + *out_sigalg = sigalg; + + done: + return 1; +} + +static int +tls13_client_select_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY **out_cpk, + const struct ssl_sigalg **out_sigalg) +{ + SSL *s = ctx->ssl; + const struct ssl_sigalg *sigalg; + SSL_CERT_PKEY *cpk; + int cert_ok; + + *out_cpk = NULL; + *out_sigalg = NULL; + + /* + * XXX - RFC 8446, 4.4.2.3: the server can communicate preferences + * with the certificate_authorities (4.2.4) and oid_filters (4.2.5) + * extensions. We should honor the former and must apply the latter. + */ + + cpk = &s->cert->pkeys[SSL_PKEY_ECC]; + if (!tls13_client_check_certificate(ctx, cpk, &cert_ok, &sigalg)) + return 0; + if (cert_ok) + goto done; + + cpk = &s->cert->pkeys[SSL_PKEY_RSA]; + if (!tls13_client_check_certificate(ctx, cpk, &cert_ok, &sigalg)) + return 0; + if (cert_ok) + goto done; + + cpk = NULL; + sigalg = NULL; + + done: + *out_cpk = cpk; + *out_sigalg = sigalg; + + return 1; +} + +int +tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb) +{ + SSL *s = ctx->ssl; + CBB cert_request_context, cert_list; + const struct ssl_sigalg *sigalg; + STACK_OF(X509) *chain; + SSL_CERT_PKEY *cpk; + X509 *cert; + int i, ret = 0; + + if (!tls13_client_select_certificate(ctx, &cpk, &sigalg)) + goto err; + + ctx->hs->tls13.cpk = cpk; + ctx->hs->our_sigalg = sigalg; + + if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context)) + goto err; + if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) + goto err; + + /* No certificate selected. */ + if (cpk == NULL) + goto done; + + if ((chain = cpk->chain) == NULL) + chain = s->ctx->extra_certs; + + if (!tls13_cert_add(ctx, &cert_list, cpk->x509, tlsext_client_build)) + goto err; + + for (i = 0; i < sk_X509_num(chain); i++) { + cert = sk_X509_value(chain, i); + if (!tls13_cert_add(ctx, &cert_list, cert, tlsext_client_build)) + goto err; + } + + ctx->handshake_stage.hs_type |= WITH_CCV; + done: + if (!CBB_flush(cbb)) + goto err; + + ret = 1; + + err: + return ret; +} + +int +tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) +{ + const struct ssl_sigalg *sigalg; + uint8_t *sig = NULL, *sig_content = NULL; + size_t sig_len, sig_content_len; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + const SSL_CERT_PKEY *cpk; + CBB sig_cbb; + int ret = 0; + + memset(&sig_cbb, 0, sizeof(sig_cbb)); + + if ((cpk = ctx->hs->tls13.cpk) == NULL) + goto err; + if ((sigalg = ctx->hs->our_sigalg) == NULL) + goto err; + pkey = cpk->privatekey; + + if (!CBB_init(&sig_cbb, 0)) + goto err; + if (!CBB_add_bytes(&sig_cbb, tls13_cert_verify_pad, + sizeof(tls13_cert_verify_pad))) + goto err; + if (!CBB_add_bytes(&sig_cbb, tls13_cert_client_verify_context, + strlen(tls13_cert_client_verify_context))) + goto err; + if (!CBB_add_u8(&sig_cbb, 0)) + goto err; + if (!CBB_add_bytes(&sig_cbb, ctx->hs->tls13.transcript_hash, + ctx->hs->tls13.transcript_hash_len)) + goto err; + if (!CBB_finish(&sig_cbb, &sig_content, &sig_content_len)) + goto err; + + if ((mdctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_DigestSignInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) + goto err; + if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) + goto err; + if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) + goto err; + } + if (!EVP_DigestSign(mdctx, NULL, &sig_len, sig_content, sig_content_len)) + goto err; + if ((sig = calloc(1, sig_len)) == NULL) + goto err; + if (!EVP_DigestSign(mdctx, sig, &sig_len, sig_content, sig_content_len)) + goto err; + + if (!CBB_add_u16(cbb, sigalg->value)) + goto err; + if (!CBB_add_u16_length_prefixed(cbb, &sig_cbb)) + goto err; + if (!CBB_add_bytes(&sig_cbb, sig, sig_len)) + goto err; + + if (!CBB_flush(cbb)) + goto err; + + ret = 1; + + err: + if (!ret && ctx->alert == 0) + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + + CBB_cleanup(&sig_cbb); + EVP_MD_CTX_free(mdctx); + free(sig_content); + free(sig); + + return ret; +} + +int +tls13_client_end_of_early_data_send(struct tls13_ctx *ctx, CBB *cbb) +{ + return 0; +} + +int +tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret context = { .data = "", .len = 0 }; + struct tls13_secret finished_key = { .data = NULL, .len = 0 }; + uint8_t transcript_hash[EVP_MAX_MD_SIZE]; + size_t transcript_hash_len; + uint8_t *verify_data; + size_t verify_data_len; + unsigned int hlen; + HMAC_CTX *hmac_ctx = NULL; + CBS cbs; + int ret = 0; + + if (!tls13_secret_init(&finished_key, EVP_MD_size(ctx->hash))) + goto err; + + if (!tls13_hkdf_expand_label(&finished_key, ctx->hash, + &secrets->client_handshake_traffic, "finished", + &context)) + goto err; + + if (!tls1_transcript_hash_value(ctx->ssl, transcript_hash, + sizeof(transcript_hash), &transcript_hash_len)) + goto err; + + if ((hmac_ctx = HMAC_CTX_new()) == NULL) + goto err; + if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len, + ctx->hash, NULL)) + goto err; + if (!HMAC_Update(hmac_ctx, transcript_hash, transcript_hash_len)) + goto err; + + verify_data_len = HMAC_size(hmac_ctx); + if (!CBB_add_space(cbb, &verify_data, verify_data_len)) + goto err; + if (!HMAC_Final(hmac_ctx, verify_data, &hlen)) + goto err; + if (hlen != verify_data_len) + goto err; + + CBS_init(&cbs, verify_data, verify_data_len); + if (!CBS_write_bytes(&cbs, ctx->hs->finished, + sizeof(ctx->hs->finished), &ctx->hs->finished_len)) + goto err; + + ret = 1; + + err: + tls13_secret_cleanup(&finished_key); + HMAC_CTX_free(hmac_ctx); + + return ret; +} + +int +tls13_client_finished_sent(struct tls13_ctx *ctx) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + + /* + * Any records following the client finished message must be encrypted + * using the client application traffic keys. + */ + return tls13_record_layer_set_write_traffic_key(ctx->rl, + &secrets->client_application_traffic, ssl_encryption_application); +} diff --git a/Libraries/libressl/ssl/tls13_error.c b/Libraries/libressl/ssl/tls13_error.c new file mode 100644 index 000000000..295b6c4fa --- /dev/null +++ b/Libraries/libressl/ssl/tls13_error.c @@ -0,0 +1,99 @@ +/* $OpenBSD: tls13_error.c,v 1.1 2020/01/20 13:10:37 jsing Exp $ */ +/* + * Copyright (c) 2014,2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "tls13_internal.h" + +void +tls13_error_clear(struct tls13_error *error) +{ + error->code = 0; + error->subcode = 0; + error->errnum = 0; + error->file = NULL; + error->line = 0; + free(error->msg); + error->msg = NULL; +} + +static int +tls13_error_vset(struct tls13_error *error, int code, int subcode, int errnum, + const char *file, int line, const char *fmt, va_list ap) +{ + char *errmsg = NULL; + int rv = -1; + + tls13_error_clear(error); + + error->code = code; + error->subcode = subcode; + error->errnum = errnum; + error->file = file; + error->line = line; + + if (vasprintf(&errmsg, fmt, ap) == -1) { + errmsg = NULL; + goto err; + } + + if (errnum == -1) { + error->msg = errmsg; + return 0; + } + + if (asprintf(&error->msg, "%s: %s", errmsg, strerror(errnum)) == -1) { + error->msg = NULL; + goto err; + } + rv = 0; + + err: + free(errmsg); + + return rv; +} + +int +tls13_error_set(struct tls13_error *error, int code, int subcode, + const char *file, int line, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls13_error_vset(error, code, subcode, errnum, file, line, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls13_error_setx(struct tls13_error *error, int code, int subcode, + const char *file, int line, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls13_error_vset(error, code, subcode, -1, file, line, fmt, ap); + va_end(ap); + + return (rv); +} diff --git a/Libraries/libressl/ssl/tls13_handshake.c b/Libraries/libressl/ssl/tls13_handshake.c new file mode 100644 index 000000000..9723edfea --- /dev/null +++ b/Libraries/libressl/ssl/tls13_handshake.c @@ -0,0 +1,721 @@ +/* $OpenBSD: tls13_handshake.c,v 1.72 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2018-2021 Theo Buehler + * Copyright (c) 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" +#include "tls13_handshake.h" +#include "tls13_internal.h" + +/* Based on RFC 8446 and inspired by s2n's TLS 1.2 state machine. */ + +struct tls13_handshake_action { + uint8_t handshake_type; + uint8_t sender; + uint8_t handshake_complete; + uint8_t send_preserve_transcript_hash; + uint8_t recv_preserve_transcript_hash; + + int (*send)(struct tls13_ctx *ctx, CBB *cbb); + int (*sent)(struct tls13_ctx *ctx); + int (*recv)(struct tls13_ctx *ctx, CBS *cbs); +}; + +static enum tls13_message_type + tls13_handshake_active_state(struct tls13_ctx *ctx); + +static const struct tls13_handshake_action * + tls13_handshake_active_action(struct tls13_ctx *ctx); +static int tls13_handshake_advance_state_machine(struct tls13_ctx *ctx); + +static int tls13_handshake_send_action(struct tls13_ctx *ctx, + const struct tls13_handshake_action *action); +static int tls13_handshake_recv_action(struct tls13_ctx *ctx, + const struct tls13_handshake_action *action); + +static int tls13_handshake_set_legacy_state(struct tls13_ctx *ctx); +static int tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx); + +static const struct tls13_handshake_action state_machine[] = { + [CLIENT_HELLO] = { + .handshake_type = TLS13_MT_CLIENT_HELLO, + .sender = TLS13_HS_CLIENT, + .send = tls13_client_hello_send, + .sent = tls13_client_hello_sent, + .recv = tls13_client_hello_recv, + }, + [CLIENT_HELLO_RETRY] = { + .handshake_type = TLS13_MT_CLIENT_HELLO, + .sender = TLS13_HS_CLIENT, + .send = tls13_client_hello_retry_send, + .recv = tls13_client_hello_retry_recv, + }, + [CLIENT_END_OF_EARLY_DATA] = { + .handshake_type = TLS13_MT_END_OF_EARLY_DATA, + .sender = TLS13_HS_CLIENT, + .send = tls13_client_end_of_early_data_send, + .recv = tls13_client_end_of_early_data_recv, + }, + [CLIENT_CERTIFICATE] = { + .handshake_type = TLS13_MT_CERTIFICATE, + .sender = TLS13_HS_CLIENT, + .send_preserve_transcript_hash = 1, + .send = tls13_client_certificate_send, + .recv = tls13_client_certificate_recv, + }, + [CLIENT_CERTIFICATE_VERIFY] = { + .handshake_type = TLS13_MT_CERTIFICATE_VERIFY, + .sender = TLS13_HS_CLIENT, + .recv_preserve_transcript_hash = 1, + .send = tls13_client_certificate_verify_send, + .recv = tls13_client_certificate_verify_recv, + }, + [CLIENT_FINISHED] = { + .handshake_type = TLS13_MT_FINISHED, + .sender = TLS13_HS_CLIENT, + .recv_preserve_transcript_hash = 1, + .send = tls13_client_finished_send, + .sent = tls13_client_finished_sent, + .recv = tls13_client_finished_recv, + }, + [SERVER_HELLO] = { + .handshake_type = TLS13_MT_SERVER_HELLO, + .sender = TLS13_HS_SERVER, + .send = tls13_server_hello_send, + .sent = tls13_server_hello_sent, + .recv = tls13_server_hello_recv, + }, + [SERVER_HELLO_RETRY_REQUEST] = { + .handshake_type = TLS13_MT_SERVER_HELLO, + .sender = TLS13_HS_SERVER, + .send = tls13_server_hello_retry_request_send, + .recv = tls13_server_hello_retry_request_recv, + .sent = tls13_server_hello_retry_request_sent, + }, + [SERVER_ENCRYPTED_EXTENSIONS] = { + .handshake_type = TLS13_MT_ENCRYPTED_EXTENSIONS, + .sender = TLS13_HS_SERVER, + .send = tls13_server_encrypted_extensions_send, + .recv = tls13_server_encrypted_extensions_recv, + }, + [SERVER_CERTIFICATE] = { + .handshake_type = TLS13_MT_CERTIFICATE, + .sender = TLS13_HS_SERVER, + .send_preserve_transcript_hash = 1, + .send = tls13_server_certificate_send, + .recv = tls13_server_certificate_recv, + }, + [SERVER_CERTIFICATE_REQUEST] = { + .handshake_type = TLS13_MT_CERTIFICATE_REQUEST, + .sender = TLS13_HS_SERVER, + .send = tls13_server_certificate_request_send, + .recv = tls13_server_certificate_request_recv, + }, + [SERVER_CERTIFICATE_VERIFY] = { + .handshake_type = TLS13_MT_CERTIFICATE_VERIFY, + .sender = TLS13_HS_SERVER, + .recv_preserve_transcript_hash = 1, + .send = tls13_server_certificate_verify_send, + .recv = tls13_server_certificate_verify_recv, + }, + [SERVER_FINISHED] = { + .handshake_type = TLS13_MT_FINISHED, + .sender = TLS13_HS_SERVER, + .recv_preserve_transcript_hash = 1, + .send_preserve_transcript_hash = 1, + .send = tls13_server_finished_send, + .sent = tls13_server_finished_sent, + .recv = tls13_server_finished_recv, + }, + [APPLICATION_DATA] = { + .handshake_complete = 1, + }, +}; + +const enum tls13_message_type handshakes[][TLS13_NUM_MESSAGE_TYPES] = { + [INITIAL] = { + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + }, + [NEGOTIATED] = { + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE_REQUEST, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_CERTIFICATE, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITHOUT_HRR] = { + CLIENT_HELLO, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE_REQUEST, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_CERTIFICATE, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITHOUT_CR] = { + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITHOUT_HRR | WITHOUT_CR] = { + CLIENT_HELLO, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITH_PSK] = { + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_FINISHED, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITHOUT_HRR | WITH_PSK] = { + CLIENT_HELLO, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_FINISHED, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITH_CCV] = { + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE_REQUEST, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_CERTIFICATE, + CLIENT_CERTIFICATE_VERIFY, + CLIENT_FINISHED, + APPLICATION_DATA, + }, + [NEGOTIATED | WITHOUT_HRR | WITH_CCV] = { + CLIENT_HELLO, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE_REQUEST, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_CERTIFICATE, + CLIENT_CERTIFICATE_VERIFY, + CLIENT_FINISHED, + APPLICATION_DATA, + }, +}; + +const size_t handshake_count = sizeof(handshakes) / sizeof(handshakes[0]); + +#ifndef TLS13_DEBUG +#define DEBUGF(...) +#else +#define DEBUGF(...) fprintf(stderr, __VA_ARGS__) + +static const char * +tls13_handshake_mode_name(uint8_t mode) +{ + switch (mode) { + case TLS13_HS_CLIENT: + return "Client"; + case TLS13_HS_SERVER: + return "Server"; + } + return "Unknown"; +} + +static const char * +tls13_handshake_message_name(uint8_t msg_type) +{ + switch (msg_type) { + case TLS13_MT_CLIENT_HELLO: + return "ClientHello"; + case TLS13_MT_SERVER_HELLO: + return "ServerHello"; + case TLS13_MT_NEW_SESSION_TICKET: + return "NewSessionTicket"; + case TLS13_MT_END_OF_EARLY_DATA: + return "EndOfEarlyData"; + case TLS13_MT_ENCRYPTED_EXTENSIONS: + return "EncryptedExtensions"; + case TLS13_MT_CERTIFICATE: + return "Certificate"; + case TLS13_MT_CERTIFICATE_REQUEST: + return "CertificateRequest"; + case TLS13_MT_CERTIFICATE_VERIFY: + return "CertificateVerify"; + case TLS13_MT_FINISHED: + return "Finished"; + } + return "Unknown"; +} +#endif + +static enum tls13_message_type +tls13_handshake_active_state(struct tls13_ctx *ctx) +{ + struct tls13_handshake_stage hs = ctx->handshake_stage; + + if (hs.hs_type >= handshake_count) + return INVALID; + if (hs.message_number >= TLS13_NUM_MESSAGE_TYPES) + return INVALID; + + return handshakes[hs.hs_type][hs.message_number]; +} + +static const struct tls13_handshake_action * +tls13_handshake_active_action(struct tls13_ctx *ctx) +{ + enum tls13_message_type mt = tls13_handshake_active_state(ctx); + + if (mt == INVALID) + return NULL; + + return &state_machine[mt]; +} + +static int +tls13_handshake_advance_state_machine(struct tls13_ctx *ctx) +{ + if (++ctx->handshake_stage.message_number >= TLS13_NUM_MESSAGE_TYPES) + return 0; + + return 1; +} + +static int +tls13_handshake_end_of_flight(struct tls13_ctx *ctx, + const struct tls13_handshake_action *previous) +{ + const struct tls13_handshake_action *current; + + if ((current = tls13_handshake_active_action(ctx)) == NULL) + return 1; + + return current->sender != previous->sender; +} + +int +tls13_handshake_msg_record(struct tls13_ctx *ctx) +{ + CBS cbs; + + tls13_handshake_msg_data(ctx->hs_msg, &cbs); + return tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs)); +} + +int +tls13_handshake_perform(struct tls13_ctx *ctx) +{ + const struct tls13_handshake_action *action; + int sending; + int ret; + + if (!ctx->handshake_started) { + /* + * Set legacy state to connect/accept and call info callback + * to signal that the handshake started. + */ + if (!tls13_handshake_set_legacy_state(ctx)) + return TLS13_IO_FAILURE; + if (!tls13_handshake_legacy_info_callback(ctx)) + return TLS13_IO_FAILURE; + + ctx->handshake_started = 1; + + /* Set legacy state for initial ClientHello read or write. */ + if (!tls13_handshake_set_legacy_state(ctx)) + return TLS13_IO_FAILURE; + } + + for (;;) { + if ((action = tls13_handshake_active_action(ctx)) == NULL) + return TLS13_IO_FAILURE; + + if (ctx->need_flush) { + if ((ret = tls13_record_layer_flush(ctx->rl)) != + TLS13_IO_SUCCESS) + return ret; + ctx->need_flush = 0; + } + + if (action->handshake_complete) { + ctx->handshake_completed = 1; + tls13_record_layer_handshake_completed(ctx->rl); + + if (!tls13_handshake_set_legacy_state(ctx)) + return TLS13_IO_FAILURE; + if (!tls13_handshake_legacy_info_callback(ctx)) + return TLS13_IO_FAILURE; + + return TLS13_IO_SUCCESS; + } + + sending = action->sender == ctx->mode; + + DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode), + sending ? "sending" : "receiving", + tls13_handshake_message_name(action->handshake_type)); + + if (ctx->alert != 0) + return tls13_send_alert(ctx->rl, ctx->alert); + + if (sending) + ret = tls13_handshake_send_action(ctx, action); + else + ret = tls13_handshake_recv_action(ctx, action); + + if (ctx->alert != 0) + return tls13_send_alert(ctx->rl, ctx->alert); + + if (ret <= 0) { + DEBUGF("%s %s returned %d\n", + tls13_handshake_mode_name(ctx->mode), + (action->sender == ctx->mode) ? "send" : "recv", + ret); + return ret; + } + + if (!tls13_handshake_legacy_info_callback(ctx)) + return TLS13_IO_FAILURE; + + if (!tls13_handshake_advance_state_machine(ctx)) + return TLS13_IO_FAILURE; + + if (sending) + ctx->need_flush = tls13_handshake_end_of_flight(ctx, + action); + + if (!tls13_handshake_set_legacy_state(ctx)) + return TLS13_IO_FAILURE; + } +} + +static int +tls13_handshake_send_action(struct tls13_ctx *ctx, + const struct tls13_handshake_action *action) +{ + ssize_t ret; + CBB cbb; + + if (ctx->send_dummy_ccs) { + if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS) + return ret; + ctx->send_dummy_ccs = 0; + if (ctx->send_dummy_ccs_after) { + ctx->send_dummy_ccs_after = 0; + return TLS13_IO_SUCCESS; + } + } + + /* If we have no handshake message, we need to build one. */ + if (ctx->hs_msg == NULL) { + if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL) + return TLS13_IO_FAILURE; + if (!tls13_handshake_msg_start(ctx->hs_msg, &cbb, + action->handshake_type)) + return TLS13_IO_FAILURE; + if (!action->send(ctx, &cbb)) + return TLS13_IO_FAILURE; + if (!tls13_handshake_msg_finish(ctx->hs_msg)) + return TLS13_IO_FAILURE; + } + + if ((ret = tls13_handshake_msg_send(ctx->hs_msg, ctx->rl)) <= 0) + return ret; + + if (!tls13_handshake_msg_record(ctx)) + return TLS13_IO_FAILURE; + + if (action->send_preserve_transcript_hash) { + if (!tls1_transcript_hash_value(ctx->ssl, + ctx->hs->tls13.transcript_hash, + sizeof(ctx->hs->tls13.transcript_hash), + &ctx->hs->tls13.transcript_hash_len)) + return TLS13_IO_FAILURE; + } + + if (ctx->handshake_message_sent_cb != NULL) + ctx->handshake_message_sent_cb(ctx); + + tls13_handshake_msg_free(ctx->hs_msg); + ctx->hs_msg = NULL; + + if (action->sent != NULL && !action->sent(ctx)) + return TLS13_IO_FAILURE; + + if (ctx->send_dummy_ccs_after) { + ctx->send_dummy_ccs = 1; + if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS) + return ret; + ctx->send_dummy_ccs = 0; + ctx->send_dummy_ccs_after = 0; + } + + return TLS13_IO_SUCCESS; +} + +static int +tls13_handshake_recv_action(struct tls13_ctx *ctx, + const struct tls13_handshake_action *action) +{ + uint8_t msg_type; + ssize_t ret; + CBS cbs; + + if (ctx->hs_msg == NULL) { + if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL) + return TLS13_IO_FAILURE; + } + + if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl)) <= 0) + return ret; + + if (action->recv_preserve_transcript_hash) { + if (!tls1_transcript_hash_value(ctx->ssl, + ctx->hs->tls13.transcript_hash, + sizeof(ctx->hs->tls13.transcript_hash), + &ctx->hs->tls13.transcript_hash_len)) + return TLS13_IO_FAILURE; + } + + if (!tls13_handshake_msg_record(ctx)) + return TLS13_IO_FAILURE; + + if (ctx->handshake_message_recv_cb != NULL) + ctx->handshake_message_recv_cb(ctx); + + /* + * In TLSv1.3 there is no way to know if you're going to receive a + * certificate request message or not, hence we have to special case it + * here. The receive handler also knows how to deal with this situation. + */ + msg_type = tls13_handshake_msg_type(ctx->hs_msg); + if (msg_type != action->handshake_type && + (msg_type != TLS13_MT_CERTIFICATE || + action->handshake_type != TLS13_MT_CERTIFICATE_REQUEST)) + return tls13_send_alert(ctx->rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + + if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) + return TLS13_IO_FAILURE; + + ret = TLS13_IO_FAILURE; + if (action->recv(ctx, &cbs)) { + if (CBS_len(&cbs) != 0) { + tls13_set_errorx(ctx, TLS13_ERR_TRAILING_DATA, 0, + "trailing data in handshake message", NULL); + ctx->alert = TLS13_ALERT_DECODE_ERROR; + } else { + ret = TLS13_IO_SUCCESS; + } + } + + tls13_handshake_msg_free(ctx->hs_msg); + ctx->hs_msg = NULL; + + if (ctx->ssl->method->version < TLS1_3_VERSION) + return TLS13_IO_USE_LEGACY; + + return ret; +} + +struct tls13_handshake_legacy_state { + int recv; + int send; +}; + +static const struct tls13_handshake_legacy_state legacy_states[] = { + [CLIENT_HELLO] = { + .recv = SSL3_ST_SR_CLNT_HELLO_A, + .send = SSL3_ST_CW_CLNT_HELLO_A, + }, + [SERVER_HELLO_RETRY_REQUEST] = { + .recv = SSL3_ST_CR_SRVR_HELLO_A, + .send = SSL3_ST_SW_SRVR_HELLO_A, + }, + [CLIENT_HELLO_RETRY] = { + .recv = SSL3_ST_SR_CLNT_HELLO_A, + .send = SSL3_ST_CW_CLNT_HELLO_A, + }, + [SERVER_HELLO] = { + .recv = SSL3_ST_CR_SRVR_HELLO_A, + .send = SSL3_ST_SW_SRVR_HELLO_A, + }, + [SERVER_ENCRYPTED_EXTENSIONS] = { + .send = 0, + .recv = 0, + }, + [SERVER_CERTIFICATE_REQUEST] = { + .recv = SSL3_ST_CR_CERT_REQ_A, + .send = SSL3_ST_SW_CERT_REQ_A, + }, + [SERVER_CERTIFICATE] = { + .recv = SSL3_ST_CR_CERT_A, + .send = SSL3_ST_SW_CERT_A, + }, + [SERVER_CERTIFICATE_VERIFY] = { + .send = 0, + .recv = 0, + }, + [SERVER_FINISHED] = { + .recv = SSL3_ST_CR_FINISHED_A, + .send = SSL3_ST_SW_FINISHED_A, + }, + [CLIENT_END_OF_EARLY_DATA] = { + .send = 0, + .recv = 0, + }, + [CLIENT_CERTIFICATE] = { + .recv = SSL3_ST_SR_CERT_VRFY_A, + .send = SSL3_ST_CW_CERT_VRFY_B, + }, + [CLIENT_CERTIFICATE_VERIFY] = { + .send = 0, + .recv = 0, + }, + [CLIENT_FINISHED] = { + .recv = SSL3_ST_SR_FINISHED_A, + .send = SSL3_ST_CW_FINISHED_A, + }, + [APPLICATION_DATA] = { + .recv = 0, + .send = 0, + }, +}; + +CTASSERT(sizeof(state_machine) / sizeof(state_machine[0]) == + sizeof(legacy_states) / sizeof(legacy_states[0])); + +static int +tls13_handshake_legacy_state(struct tls13_ctx *ctx, int *out_state) +{ + const struct tls13_handshake_action *action; + enum tls13_message_type mt; + + *out_state = 0; + + if (!ctx->handshake_started) { + if (ctx->mode == TLS13_HS_CLIENT) + *out_state = SSL_ST_CONNECT; + else + *out_state = SSL_ST_ACCEPT; + + return 1; + } + + if (ctx->handshake_completed) { + *out_state = SSL_ST_OK; + return 1; + } + + if ((mt = tls13_handshake_active_state(ctx)) == INVALID) + return 0; + + if ((action = tls13_handshake_active_action(ctx)) == NULL) + return 0; + + if (action->sender == ctx->mode) + *out_state = legacy_states[mt].send; + else + *out_state = legacy_states[mt].recv; + + return 1; +} + +static int +tls13_handshake_info_position(struct tls13_ctx *ctx) +{ + if (!ctx->handshake_started) + return TLS13_INFO_HANDSHAKE_STARTED; + + if (ctx->handshake_completed) + return TLS13_INFO_HANDSHAKE_COMPLETED; + + if (ctx->mode == TLS13_HS_CLIENT) + return TLS13_INFO_CONNECT_LOOP; + else + return TLS13_INFO_ACCEPT_LOOP; +} + +static int +tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx) +{ + int state, where; + + if (!tls13_handshake_legacy_state(ctx, &state)) + return 0; + + /* Do nothing if there's no corresponding legacy state. */ + if (state == 0) + return 1; + + if (ctx->info_cb != NULL) { + where = tls13_handshake_info_position(ctx); + ctx->info_cb(ctx, where, 1); + } + + return 1; +} + +static int +tls13_handshake_set_legacy_state(struct tls13_ctx *ctx) +{ + int state; + + if (!tls13_handshake_legacy_state(ctx, &state)) + return 0; + + /* Do nothing if there's no corresponding legacy state. */ + if (state == 0) + return 1; + + ctx->hs->state = state; + + return 1; +} diff --git a/Libraries/libressl/ssl/tls13_handshake.h b/Libraries/libressl/ssl/tls13_handshake.h new file mode 100644 index 000000000..8a08b9fd5 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_handshake.h @@ -0,0 +1,54 @@ +/* $OpenBSD: tls13_handshake.h,v 1.5 2020/04/22 17:05:07 jsing Exp $ */ +/* + * Copyright (c) 2019 Theo Buehler + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS13_HANDSHAKE_H +#define HEADER_TLS13_HANDSHAKE_H + +#include /* for NULL */ + +__BEGIN_HIDDEN_DECLS + +#define INITIAL 0x00 +#define NEGOTIATED 0x01 +#define WITHOUT_HRR 0x02 +#define WITHOUT_CR 0x04 +#define WITH_PSK 0x08 +#define WITH_CCV 0x10 +#define WITH_0RTT 0x20 + +enum tls13_message_type { + INVALID, + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + SERVER_ENCRYPTED_EXTENSIONS, + SERVER_CERTIFICATE_REQUEST, + SERVER_CERTIFICATE, + SERVER_CERTIFICATE_VERIFY, + SERVER_FINISHED, + CLIENT_END_OF_EARLY_DATA, + CLIENT_CERTIFICATE, + CLIENT_CERTIFICATE_VERIFY, + CLIENT_FINISHED, + APPLICATION_DATA, + TLS13_NUM_MESSAGE_TYPES, +}; + +__END_HIDDEN_DECLS + +#endif /* !HEADER_TLS13_HANDSHAKE_H */ diff --git a/Libraries/libressl/ssl/tls13_handshake_msg.c b/Libraries/libressl/ssl/tls13_handshake_msg.c new file mode 100644 index 000000000..134cfb217 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_handshake_msg.c @@ -0,0 +1,188 @@ +/* $OpenBSD: tls13_handshake_msg.c,v 1.6 2022/07/22 19:33:53 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "bytestring.h" +#include "tls13_internal.h" + +#define TLS13_HANDSHAKE_MSG_HEADER_LEN 4 +#define TLS13_HANDSHAKE_MSG_INITIAL_LEN 256 +#define TLS13_HANDSHAKE_MSG_MAX_LEN (256 * 1024) + +struct tls13_handshake_msg { + uint8_t msg_type; + uint32_t msg_len; + uint8_t *data; + size_t data_len; + + struct tls_buffer *buf; + CBS cbs; + CBB cbb; +}; + +struct tls13_handshake_msg * +tls13_handshake_msg_new() +{ + struct tls13_handshake_msg *msg = NULL; + + if ((msg = calloc(1, sizeof(struct tls13_handshake_msg))) == NULL) + goto err; + if ((msg->buf = tls_buffer_new(0)) == NULL) + goto err; + + return msg; + + err: + tls13_handshake_msg_free(msg); + + return NULL; +} + +void +tls13_handshake_msg_free(struct tls13_handshake_msg *msg) +{ + if (msg == NULL) + return; + + tls_buffer_free(msg->buf); + + CBB_cleanup(&msg->cbb); + + freezero(msg->data, msg->data_len); + freezero(msg, sizeof(struct tls13_handshake_msg)); +} + +void +tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs) +{ + CBS_init(cbs, msg->data, msg->data_len); +} + +uint8_t +tls13_handshake_msg_type(struct tls13_handshake_msg *msg) +{ + return msg->msg_type; +} + +int +tls13_handshake_msg_content(struct tls13_handshake_msg *msg, CBS *cbs) +{ + tls13_handshake_msg_data(msg, cbs); + + return CBS_skip(cbs, TLS13_HANDSHAKE_MSG_HEADER_LEN); +} + +int +tls13_handshake_msg_start(struct tls13_handshake_msg *msg, CBB *body, + uint8_t msg_type) +{ + if (!CBB_init(&msg->cbb, TLS13_HANDSHAKE_MSG_INITIAL_LEN)) + return 0; + if (!CBB_add_u8(&msg->cbb, msg_type)) + return 0; + if (!CBB_add_u24_length_prefixed(&msg->cbb, body)) + return 0; + + return 1; +} + +int +tls13_handshake_msg_finish(struct tls13_handshake_msg *msg) +{ + if (!CBB_finish(&msg->cbb, &msg->data, &msg->data_len)) + return 0; + + CBS_init(&msg->cbs, msg->data, msg->data_len); + + return 1; +} + +static ssize_t +tls13_handshake_msg_read_cb(void *buf, size_t n, void *cb_arg) +{ + struct tls13_record_layer *rl = cb_arg; + + return tls13_read_handshake_data(rl, buf, n); +} + +int +tls13_handshake_msg_recv(struct tls13_handshake_msg *msg, + struct tls13_record_layer *rl) +{ + uint8_t msg_type; + uint32_t msg_len; + CBS cbs; + int ret; + + if (msg->data != NULL) + return TLS13_IO_FAILURE; + + if (msg->msg_type == 0) { + if ((ret = tls_buffer_extend(msg->buf, + TLS13_HANDSHAKE_MSG_HEADER_LEN, + tls13_handshake_msg_read_cb, rl)) <= 0) + return ret; + + if (!tls_buffer_data(msg->buf, &cbs)) + return TLS13_IO_FAILURE; + + if (!CBS_get_u8(&cbs, &msg_type)) + return TLS13_IO_FAILURE; + if (!CBS_get_u24(&cbs, &msg_len)) + return TLS13_IO_FAILURE; + + /* XXX - do we want to make this variable on message type? */ + if (msg_len > TLS13_HANDSHAKE_MSG_MAX_LEN) + return TLS13_IO_FAILURE; + + msg->msg_type = msg_type; + msg->msg_len = msg_len; + } + + if ((ret = tls_buffer_extend(msg->buf, + TLS13_HANDSHAKE_MSG_HEADER_LEN + msg->msg_len, + tls13_handshake_msg_read_cb, rl)) <= 0) + return ret; + + if (!tls_buffer_finish(msg->buf, &msg->data, &msg->data_len)) + return TLS13_IO_FAILURE; + + return TLS13_IO_SUCCESS; +} + +int +tls13_handshake_msg_send(struct tls13_handshake_msg *msg, + struct tls13_record_layer *rl) +{ + ssize_t ret; + + if (msg->data == NULL) + return TLS13_IO_FAILURE; + + if (CBS_len(&msg->cbs) == 0) + return TLS13_IO_FAILURE; + + while (CBS_len(&msg->cbs) > 0) { + if ((ret = tls13_write_handshake_data(rl, CBS_data(&msg->cbs), + CBS_len(&msg->cbs))) <= 0) + return ret; + + if (!CBS_skip(&msg->cbs, ret)) + return TLS13_IO_FAILURE; + } + + return TLS13_IO_SUCCESS; +} diff --git a/Libraries/libressl/ssl/tls13_internal.h b/Libraries/libressl/ssl/tls13_internal.h new file mode 100644 index 000000000..f4b17bdf2 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_internal.h @@ -0,0 +1,443 @@ +/* $OpenBSD: tls13_internal.h,v 1.101 2022/07/24 14:28:16 jsing Exp $ */ +/* + * Copyright (c) 2018 Bob Beck + * Copyright (c) 2018 Theo Buehler + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS13_INTERNAL_H +#define HEADER_TLS13_INTERNAL_H + +#include +#include + +#include "bytestring.h" +#include "tls_internal.h" + +__BEGIN_HIDDEN_DECLS + +#define TLS13_HS_CLIENT 1 +#define TLS13_HS_SERVER 2 + +#define TLS13_IO_SUCCESS 1 +#define TLS13_IO_EOF 0 +#define TLS13_IO_FAILURE -1 +#define TLS13_IO_ALERT -2 +#define TLS13_IO_WANT_POLLIN -3 +#define TLS13_IO_WANT_POLLOUT -4 +#define TLS13_IO_WANT_RETRY -5 /* Retry the previous call immediately. */ +#define TLS13_IO_USE_LEGACY -6 +#define TLS13_IO_RECORD_VERSION -7 +#define TLS13_IO_RECORD_OVERFLOW -8 + +#define TLS13_ERR_VERIFY_FAILED 16 +#define TLS13_ERR_HRR_FAILED 17 +#define TLS13_ERR_TRAILING_DATA 18 +#define TLS13_ERR_NO_SHARED_CIPHER 19 +#define TLS13_ERR_NO_CERTIFICATE 20 +#define TLS13_ERR_NO_PEER_CERTIFICATE 21 + +#define TLS13_ALERT_LEVEL_WARNING 1 +#define TLS13_ALERT_LEVEL_FATAL 2 + +#define TLS13_ALERT_CLOSE_NOTIFY 0 +#define TLS13_ALERT_UNEXPECTED_MESSAGE 10 +#define TLS13_ALERT_BAD_RECORD_MAC 20 +#define TLS13_ALERT_RECORD_OVERFLOW 22 +#define TLS13_ALERT_HANDSHAKE_FAILURE 40 +#define TLS13_ALERT_BAD_CERTIFICATE 42 +#define TLS13_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define TLS13_ALERT_CERTIFICATE_REVOKED 44 +#define TLS13_ALERT_CERTIFICATE_EXPIRED 45 +#define TLS13_ALERT_CERTIFICATE_UNKNOWN 46 +#define TLS13_ALERT_ILLEGAL_PARAMETER 47 +#define TLS13_ALERT_UNKNOWN_CA 48 +#define TLS13_ALERT_ACCESS_DENIED 49 +#define TLS13_ALERT_DECODE_ERROR 50 +#define TLS13_ALERT_DECRYPT_ERROR 51 +#define TLS13_ALERT_PROTOCOL_VERSION 70 +#define TLS13_ALERT_INSUFFICIENT_SECURITY 71 +#define TLS13_ALERT_INTERNAL_ERROR 80 +#define TLS13_ALERT_INAPPROPRIATE_FALLBACK 86 +#define TLS13_ALERT_USER_CANCELED 90 +#define TLS13_ALERT_MISSING_EXTENSION 109 +#define TLS13_ALERT_UNSUPPORTED_EXTENSION 110 +#define TLS13_ALERT_UNRECOGNIZED_NAME 112 +#define TLS13_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define TLS13_ALERT_UNKNOWN_PSK_IDENTITY 115 +#define TLS13_ALERT_CERTIFICATE_REQUIRED 116 +#define TLS13_ALERT_NO_APPLICATION_PROTOCOL 120 + +#define TLS13_INFO_HANDSHAKE_STARTED SSL_CB_HANDSHAKE_START +#define TLS13_INFO_HANDSHAKE_COMPLETED SSL_CB_HANDSHAKE_DONE +#define TLS13_INFO_ACCEPT_LOOP SSL_CB_ACCEPT_LOOP +#define TLS13_INFO_CONNECT_LOOP SSL_CB_CONNECT_LOOP +#define TLS13_INFO_ACCEPT_EXIT SSL_CB_ACCEPT_EXIT +#define TLS13_INFO_CONNECT_EXIT SSL_CB_CONNECT_EXIT + +typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg); +typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg); +typedef void (*tls13_phh_sent_cb)(void *_cb_arg); +typedef void (*tls13_handshake_message_cb)(void *_cb_arg); +typedef void (*tls13_info_cb)(void *_cb_arg, int _state, int _ret); +typedef int (*tls13_ocsp_status_cb)(void *_cb_arg); + +/* + * PSK support. + */ + +/* + * Known PskKeyExchangeMode values. + * https://www.iana.org/assignments/tls-parameters/#tls-pskkeyexchangemode + */ +#define TLS13_PSK_KE 0 +#define TLS13_PSK_DHE_KE 1 + +/* + * Secrets. + */ +struct tls13_secret { + uint8_t *data; + size_t len; +}; + +/* RFC 8446 Section 7.1 Page 92 */ +struct tls13_secrets { + const EVP_MD *digest; + int resumption; + int init_done; + int early_done; + int handshake_done; + int schedule_done; + int insecure; /* Set by tests */ + struct tls13_secret zeros; + struct tls13_secret empty_hash; + struct tls13_secret extracted_early; + struct tls13_secret binder_key; + struct tls13_secret client_early_traffic; + struct tls13_secret early_exporter_master; + struct tls13_secret derived_early; + struct tls13_secret extracted_handshake; + struct tls13_secret client_handshake_traffic; + struct tls13_secret server_handshake_traffic; + struct tls13_secret derived_handshake; + struct tls13_secret extracted_master; + struct tls13_secret client_application_traffic; + struct tls13_secret server_application_traffic; + struct tls13_secret exporter_master; + struct tls13_secret resumption_master; +}; + +int tls13_secret_init(struct tls13_secret *secret, size_t len); +void tls13_secret_cleanup(struct tls13_secret *secret); +struct tls13_secrets *tls13_secrets_create(const EVP_MD *digest, + int resumption); +void tls13_secrets_destroy(struct tls13_secrets *secrets); + +int tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest, + const struct tls13_secret *secret, const char *label, + const struct tls13_secret *context); +int tls13_hkdf_expand_label_with_length(struct tls13_secret *out, + const EVP_MD *digest, const struct tls13_secret *secret, + const uint8_t *label, size_t label_len, const struct tls13_secret *context); + +int tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest, + const struct tls13_secret *secret, const char *label, + const struct tls13_secret *context); +int tls13_derive_secret_with_label_length(struct tls13_secret *out, + const EVP_MD *digest, const struct tls13_secret *secret, + const uint8_t *label, size_t label_len, const struct tls13_secret *context); + +int tls13_derive_early_secrets(struct tls13_secrets *secrets, uint8_t *psk, + size_t psk_len, const struct tls13_secret *context); +int tls13_derive_handshake_secrets(struct tls13_secrets *secrets, + const uint8_t *ecdhe, size_t ecdhe_len, const struct tls13_secret *context); +int tls13_derive_application_secrets(struct tls13_secrets *secrets, + const struct tls13_secret *context); +int tls13_update_client_traffic_secret(struct tls13_secrets *secrets); +int tls13_update_server_traffic_secret(struct tls13_secrets *secrets); + +/* + * Record Layer. + */ +struct tls13_record_layer; + +struct tls13_record_layer_callbacks { + /* Wire callbacks. */ + tls_read_cb wire_read; + tls_write_cb wire_write; + tls_flush_cb wire_flush; + + /* Interceptors. */ + tls_handshake_read_cb handshake_read; + tls_handshake_write_cb handshake_write; + tls_traffic_key_cb set_read_traffic_key; + tls_traffic_key_cb set_write_traffic_key; + tls_alert_send_cb alert_send; + + /* Notification callbacks. */ + tls13_alert_cb alert_recv; + tls13_alert_cb alert_sent; + tls13_phh_recv_cb phh_recv; + tls13_phh_sent_cb phh_sent; +}; + +struct tls13_record_layer *tls13_record_layer_new( + const struct tls13_record_layer_callbacks *callbacks, void *cb_arg); +void tls13_record_layer_free(struct tls13_record_layer *rl); +void tls13_record_layer_set_callbacks(struct tls13_record_layer *rl, + const struct tls13_record_layer_callbacks *callbacks, void *cb_arg); +void tls13_record_layer_allow_ccs(struct tls13_record_layer *rl, int allow); +void tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer *rl, int allow); +void tls13_record_layer_rcontent(struct tls13_record_layer *rl, CBS *cbs); +void tls13_record_layer_set_aead(struct tls13_record_layer *rl, + const EVP_AEAD *aead); +void tls13_record_layer_set_hash(struct tls13_record_layer *rl, + const EVP_MD *hash); +void tls13_record_layer_set_legacy_version(struct tls13_record_layer *rl, + uint16_t version); +void tls13_record_layer_set_retry_after_phh(struct tls13_record_layer *rl, int retry); +void tls13_record_layer_handshake_completed(struct tls13_record_layer *rl); +int tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl, + struct tls13_secret *read_key, enum ssl_encryption_level_t read_level); +int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, + struct tls13_secret *write_key, enum ssl_encryption_level_t write_level); +ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl); +ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs); +ssize_t tls13_record_layer_flush(struct tls13_record_layer *rl); + +ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); +ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, + size_t n); +ssize_t tls13_pending_application_data(struct tls13_record_layer *rl); +ssize_t tls13_peek_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); +ssize_t tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); +ssize_t tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf, + size_t n); + +ssize_t tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc); +ssize_t tls13_send_dummy_ccs(struct tls13_record_layer *rl); + +/* + * Handshake Messages. + */ +struct tls13_handshake_msg; + +struct tls13_handshake_msg *tls13_handshake_msg_new(void); +void tls13_handshake_msg_free(struct tls13_handshake_msg *msg); +void tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs); +uint8_t tls13_handshake_msg_type(struct tls13_handshake_msg *msg); +int tls13_handshake_msg_content(struct tls13_handshake_msg *msg, CBS *cbs); +int tls13_handshake_msg_start(struct tls13_handshake_msg *msg, CBB *body, + uint8_t msg_type); +int tls13_handshake_msg_finish(struct tls13_handshake_msg *msg); +int tls13_handshake_msg_recv(struct tls13_handshake_msg *msg, + struct tls13_record_layer *rl); +int tls13_handshake_msg_send(struct tls13_handshake_msg *msg, + struct tls13_record_layer *rl); + +struct tls13_handshake_stage { + uint8_t hs_type; + uint8_t message_number; +}; + +struct ssl_handshake_tls13_st; + +struct tls13_error { + int code; + int subcode; + int errnum; + const char *file; + int line; + char *msg; +}; + +struct tls13_ctx { + struct tls13_error error; + + SSL *ssl; + struct ssl_handshake_st *hs; + uint8_t mode; + struct tls13_handshake_stage handshake_stage; + int handshake_started; + int handshake_completed; + int need_flush; + int middlebox_compat; + int send_dummy_ccs; + int send_dummy_ccs_after; + + int close_notify_sent; + int close_notify_recv; + + const EVP_AEAD *aead; + const EVP_MD *hash; + + struct tls13_record_layer *rl; + struct tls13_handshake_msg *hs_msg; + uint8_t key_update_request; + uint8_t alert; + int phh_count; + time_t phh_last_seen; + + tls13_handshake_message_cb handshake_message_sent_cb; + tls13_handshake_message_cb handshake_message_recv_cb; + tls13_info_cb info_cb; + tls13_ocsp_status_cb ocsp_status_recv_cb; +}; +#ifndef TLS13_PHH_LIMIT_TIME +#define TLS13_PHH_LIMIT_TIME 3600 +#endif +#ifndef TLS13_PHH_LIMIT +#define TLS13_PHH_LIMIT 100 +#endif + +struct tls13_ctx *tls13_ctx_new(int mode, SSL *ssl); +void tls13_ctx_free(struct tls13_ctx *ctx); + +const EVP_AEAD *tls13_cipher_aead(const SSL_CIPHER *cipher); +const EVP_MD *tls13_cipher_hash(const SSL_CIPHER *cipher); + +void tls13_alert_received_cb(uint8_t alert_desc, void *arg); +void tls13_alert_sent_cb(uint8_t alert_desc, void *arg); +ssize_t tls13_phh_received_cb(void *cb_arg); +void tls13_phh_done_cb(void *cb_arg); + +int tls13_quic_init(struct tls13_ctx *ctx); + +/* + * Legacy interfaces. + */ +int tls13_use_legacy_client(struct tls13_ctx *ctx); +int tls13_use_legacy_server(struct tls13_ctx *ctx); +int tls13_legacy_accept(SSL *ssl); +int tls13_legacy_connect(SSL *ssl); +int tls13_legacy_return_code(SSL *ssl, ssize_t ret); +ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg); +ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg); +ssize_t tls13_legacy_wire_flush_cb(void *arg); +int tls13_legacy_pending(const SSL *ssl); +int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, + int peek); +int tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len); +int tls13_legacy_shutdown(SSL *ssl); +int tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert); + +/* + * Message Types - RFC 8446, Section B.3. + * + * Values listed as "_RESERVED" were used in previous versions of TLS and are + * listed here for completeness. TLS 1.3 implementations MUST NOT send them but + * might receive them from older TLS implementations. + */ +#define TLS13_MT_HELLO_REQUEST_RESERVED 0 +#define TLS13_MT_CLIENT_HELLO 1 +#define TLS13_MT_SERVER_HELLO 2 +#define TLS13_MT_HELLO_VERIFY_REQUEST_RESERVED 3 +#define TLS13_MT_NEW_SESSION_TICKET 4 +#define TLS13_MT_END_OF_EARLY_DATA 5 +#define TLS13_MT_HELLO_RETRY_REQUEST_RESERVED 6 +#define TLS13_MT_ENCRYPTED_EXTENSIONS 8 +#define TLS13_MT_CERTIFICATE 11 +#define TLS13_MT_SERVER_KEY_EXCHANGE_RESERVED 12 +#define TLS13_MT_CERTIFICATE_REQUEST 13 +#define TLS13_MT_SERVER_HELLO_DONE_RESERVED 14 +#define TLS13_MT_CERTIFICATE_VERIFY 15 +#define TLS13_MT_CLIENT_KEY_EXCHANGE_RESERVED 16 +#define TLS13_MT_FINISHED 20 +#define TLS13_MT_CERTIFICATE_URL_RESERVED 21 +#define TLS13_MT_CERTIFICATE_STATUS_RESERVED 22 +#define TLS13_MT_SUPPLEMENTAL_DATA_RESERVED 23 +#define TLS13_MT_KEY_UPDATE 24 +#define TLS13_MT_MESSAGE_HASH 254 + +int tls13_handshake_msg_record(struct tls13_ctx *ctx); +int tls13_handshake_perform(struct tls13_ctx *ctx); + +int tls13_client_init(struct tls13_ctx *ctx); +int tls13_server_init(struct tls13_ctx *ctx); +int tls13_client_connect(struct tls13_ctx *ctx); +int tls13_server_accept(struct tls13_ctx *ctx); + +int tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_client_hello_sent(struct tls13_ctx *ctx); +int tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_client_end_of_early_data_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_client_finished_sent(struct tls13_ctx *ctx); +int tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_hello_sent(struct tls13_ctx *ctx); +int tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_hello_retry_request_sent(struct tls13_ctx *ctx); +int tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs); +int tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb); +int tls13_server_finished_sent(struct tls13_ctx *ctx); + +void tls13_error_clear(struct tls13_error *error); +int tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert, + int(*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb)); + +int tls13_synthetic_handshake_message(struct tls13_ctx *ctx); +int tls13_clienthello_hash_init(struct tls13_ctx *ctx); +void tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs); +int tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data, + size_t len); +int tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs); +int tls13_clienthello_hash_finalize(struct tls13_ctx *ctx); +int tls13_clienthello_hash_validate(struct tls13_ctx *ctx); + +int tls13_error_set(struct tls13_error *error, int code, int subcode, + const char *file, int line, const char *fmt, ...); +int tls13_error_setx(struct tls13_error *error, int code, int subcode, + const char *file, int line, const char *fmt, ...); + +#define tls13_set_error(ctx, code, subcode, fmt, ...) \ + tls13_error_set(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \ + (fmt), __VA_ARGS__) +#define tls13_set_errorx(ctx, code, subcode, fmt, ...) \ + tls13_error_setx(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \ + (fmt), __VA_ARGS__) + +int tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len, + const uint8_t *context_value, size_t context_value_len, uint8_t *out, + size_t out_len); + +extern const uint8_t tls13_downgrade_12[8]; +extern const uint8_t tls13_downgrade_11[8]; +extern const uint8_t tls13_hello_retry_request_hash[32]; +extern const uint8_t tls13_cert_verify_pad[64]; +extern const uint8_t tls13_cert_client_verify_context[]; +extern const uint8_t tls13_cert_server_verify_context[]; + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/tls13_key_schedule.c b/Libraries/libressl/ssl/tls13_key_schedule.c new file mode 100644 index 000000000..05bcf0f00 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_key_schedule.c @@ -0,0 +1,458 @@ +/* $OpenBSD: tls13_key_schedule.c,v 1.18 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2018, Bob Beck + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "tls13_internal.h" + +int +tls13_secret_init(struct tls13_secret *secret, size_t len) +{ + if (secret->data != NULL) + return 0; + + if ((secret->data = calloc(1, len)) == NULL) + return 0; + secret->len = len; + + return 1; +} + +void +tls13_secret_cleanup(struct tls13_secret *secret) +{ + freezero(secret->data, secret->len); + secret->data = NULL; + secret->len = 0; +} + +/* + * Allocate a set of secrets for a key schedule using + * a size of hash_length from RFC 8446 section 7.1. + */ +struct tls13_secrets * +tls13_secrets_create(const EVP_MD *digest, int resumption) +{ + struct tls13_secrets *secrets = NULL; + EVP_MD_CTX *mdctx = NULL; + unsigned int mdlen; + size_t hash_length; + + hash_length = EVP_MD_size(digest); + + if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL) + goto err; + + if (!tls13_secret_init(&secrets->zeros, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->empty_hash, hash_length)) + goto err; + + if (!tls13_secret_init(&secrets->extracted_early, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->binder_key, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->client_early_traffic, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->early_exporter_master, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->derived_early, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->extracted_handshake, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->derived_handshake, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->extracted_master, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->client_application_traffic, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->server_application_traffic, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->exporter_master, hash_length)) + goto err; + if (!tls13_secret_init(&secrets->resumption_master, hash_length)) + goto err; + + /* + * Calculate the hash of a zero-length string - this is needed during + * the "derived" step for key extraction. + */ + if ((mdctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_DigestInit_ex(mdctx, digest, NULL)) + goto err; + if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0)) + goto err; + if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen)) + goto err; + EVP_MD_CTX_free(mdctx); + mdctx = NULL; + + if (secrets->empty_hash.len != mdlen) + goto err; + + secrets->digest = digest; + secrets->resumption = resumption; + secrets->init_done = 1; + + return secrets; + + err: + tls13_secrets_destroy(secrets); + EVP_MD_CTX_free(mdctx); + + return NULL; +} + +void +tls13_secrets_destroy(struct tls13_secrets *secrets) +{ + if (secrets == NULL) + return; + + /* you can never be too sure :) */ + tls13_secret_cleanup(&secrets->zeros); + tls13_secret_cleanup(&secrets->empty_hash); + + tls13_secret_cleanup(&secrets->extracted_early); + tls13_secret_cleanup(&secrets->binder_key); + tls13_secret_cleanup(&secrets->client_early_traffic); + tls13_secret_cleanup(&secrets->early_exporter_master); + tls13_secret_cleanup(&secrets->derived_early); + tls13_secret_cleanup(&secrets->extracted_handshake); + tls13_secret_cleanup(&secrets->client_handshake_traffic); + tls13_secret_cleanup(&secrets->server_handshake_traffic); + tls13_secret_cleanup(&secrets->derived_handshake); + tls13_secret_cleanup(&secrets->extracted_master); + tls13_secret_cleanup(&secrets->client_application_traffic); + tls13_secret_cleanup(&secrets->server_application_traffic); + tls13_secret_cleanup(&secrets->exporter_master); + tls13_secret_cleanup(&secrets->resumption_master); + + freezero(secrets, sizeof(struct tls13_secrets)); +} + +int +tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest, + const struct tls13_secret *secret, const char *label, + const struct tls13_secret *context) +{ + return tls13_hkdf_expand_label_with_length(out, digest, secret, label, + strlen(label), context); +} + +int +tls13_hkdf_expand_label_with_length(struct tls13_secret *out, + const EVP_MD *digest, const struct tls13_secret *secret, + const uint8_t *label, size_t label_len, const struct tls13_secret *context) +{ + const char tls13_plabel[] = "tls13 "; + uint8_t *hkdf_label = NULL; + size_t hkdf_label_len; + CBB cbb, child; + int ret; + + if (!CBB_init(&cbb, 256)) + goto err; + + if (out->data == NULL || out->len == 0) + goto err; + + if (!CBB_add_u16(&cbb, out->len)) + goto err; + if (!CBB_add_u8_length_prefixed(&cbb, &child)) + goto err; + if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel))) + goto err; + if (!CBB_add_bytes(&child, label, label_len)) + goto err; + if (!CBB_add_u8_length_prefixed(&cbb, &child)) + goto err; + if (!CBB_add_bytes(&child, context->data, context->len)) + goto err; + if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) + goto err; + + ret = HKDF_expand(out->data, out->len, digest, secret->data, + secret->len, hkdf_label, hkdf_label_len); + + free(hkdf_label); + return(ret); + err: + CBB_cleanup(&cbb); + return(0); +} + +int +tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest, + const struct tls13_secret *secret, const char *label, + const struct tls13_secret *context) +{ + return tls13_hkdf_expand_label(out, digest, secret, label, context); +} + +int +tls13_derive_secret_with_label_length(struct tls13_secret *out, + const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label, + size_t label_len, const struct tls13_secret *context) +{ + return tls13_hkdf_expand_label_with_length(out, digest, secret, label, + label_len, context); +} + +int +tls13_derive_early_secrets(struct tls13_secrets *secrets, + uint8_t *psk, size_t psk_len, const struct tls13_secret *context) +{ + if (!secrets->init_done || secrets->early_done) + return 0; + + if (!HKDF_extract(secrets->extracted_early.data, + &secrets->extracted_early.len, secrets->digest, psk, psk_len, + secrets->zeros.data, secrets->zeros.len)) + return 0; + + if (secrets->extracted_early.len != secrets->zeros.len) + return 0; + + if (!tls13_derive_secret(&secrets->binder_key, secrets->digest, + &secrets->extracted_early, + secrets->resumption ? "res binder" : "ext binder", + &secrets->empty_hash)) + return 0; + if (!tls13_derive_secret(&secrets->client_early_traffic, + secrets->digest, &secrets->extracted_early, "c e traffic", + context)) + return 0; + if (!tls13_derive_secret(&secrets->early_exporter_master, + secrets->digest, &secrets->extracted_early, "e exp master", + context)) + return 0; + if (!tls13_derive_secret(&secrets->derived_early, + secrets->digest, &secrets->extracted_early, "derived", + &secrets->empty_hash)) + return 0; + + /* RFC 8446 recommends */ + if (!secrets->insecure) + explicit_bzero(secrets->extracted_early.data, + secrets->extracted_early.len); + secrets->early_done = 1; + return 1; +} + +int +tls13_derive_handshake_secrets(struct tls13_secrets *secrets, + const uint8_t *ecdhe, size_t ecdhe_len, + const struct tls13_secret *context) +{ + if (!secrets->init_done || !secrets->early_done || + secrets->handshake_done) + return 0; + + if (!HKDF_extract(secrets->extracted_handshake.data, + &secrets->extracted_handshake.len, secrets->digest, + ecdhe, ecdhe_len, secrets->derived_early.data, + secrets->derived_early.len)) + return 0; + + if (secrets->extracted_handshake.len != secrets->zeros.len) + return 0; + + /* XXX */ + if (!secrets->insecure) + explicit_bzero(secrets->derived_early.data, + secrets->derived_early.len); + + if (!tls13_derive_secret(&secrets->client_handshake_traffic, + secrets->digest, &secrets->extracted_handshake, "c hs traffic", + context)) + return 0; + if (!tls13_derive_secret(&secrets->server_handshake_traffic, + secrets->digest, &secrets->extracted_handshake, "s hs traffic", + context)) + return 0; + if (!tls13_derive_secret(&secrets->derived_handshake, + secrets->digest, &secrets->extracted_handshake, "derived", + &secrets->empty_hash)) + return 0; + + /* RFC 8446 recommends */ + if (!secrets->insecure) + explicit_bzero(secrets->extracted_handshake.data, + secrets->extracted_handshake.len); + + secrets->handshake_done = 1; + + return 1; +} + +int +tls13_derive_application_secrets(struct tls13_secrets *secrets, + const struct tls13_secret *context) +{ + if (!secrets->init_done || !secrets->early_done || + !secrets->handshake_done || secrets->schedule_done) + return 0; + + if (!HKDF_extract(secrets->extracted_master.data, + &secrets->extracted_master.len, secrets->digest, + secrets->zeros.data, secrets->zeros.len, + secrets->derived_handshake.data, secrets->derived_handshake.len)) + return 0; + + if (secrets->extracted_master.len != secrets->zeros.len) + return 0; + + /* XXX */ + if (!secrets->insecure) + explicit_bzero(secrets->derived_handshake.data, + secrets->derived_handshake.len); + + if (!tls13_derive_secret(&secrets->client_application_traffic, + secrets->digest, &secrets->extracted_master, "c ap traffic", + context)) + return 0; + if (!tls13_derive_secret(&secrets->server_application_traffic, + secrets->digest, &secrets->extracted_master, "s ap traffic", + context)) + return 0; + if (!tls13_derive_secret(&secrets->exporter_master, + secrets->digest, &secrets->extracted_master, "exp master", + context)) + return 0; + if (!tls13_derive_secret(&secrets->resumption_master, + secrets->digest, &secrets->extracted_master, "res master", + context)) + return 0; + + /* RFC 8446 recommends */ + if (!secrets->insecure) + explicit_bzero(secrets->extracted_master.data, + secrets->extracted_master.len); + + secrets->schedule_done = 1; + + return 1; +} + +int +tls13_update_client_traffic_secret(struct tls13_secrets *secrets) +{ + struct tls13_secret context = { .data = "", .len = 0 }; + + if (!secrets->init_done || !secrets->early_done || + !secrets->handshake_done || !secrets->schedule_done) + return 0; + + return tls13_hkdf_expand_label(&secrets->client_application_traffic, + secrets->digest, &secrets->client_application_traffic, + "traffic upd", &context); +} + +int +tls13_update_server_traffic_secret(struct tls13_secrets *secrets) +{ + struct tls13_secret context = { .data = "", .len = 0 }; + + if (!secrets->init_done || !secrets->early_done || + !secrets->handshake_done || !secrets->schedule_done) + return 0; + + return tls13_hkdf_expand_label(&secrets->server_application_traffic, + secrets->digest, &secrets->server_application_traffic, + "traffic upd", &context); +} + +int +tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len, + const uint8_t *context_value, size_t context_value_len, uint8_t *out, + size_t out_len) +{ + struct tls13_secret context, export_out, export_secret; + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + EVP_MD_CTX *md_ctx = NULL; + unsigned int md_out_len; + int md_len; + int ret = 0; + + /* + * RFC 8446 Section 7.5. + */ + + memset(&context, 0, sizeof(context)); + memset(&export_secret, 0, sizeof(export_secret)); + + export_out.data = out; + export_out.len = out_len; + + if (!ctx->handshake_completed) + return 0; + + md_len = EVP_MD_size(secrets->digest); + if (md_len <= 0 || md_len > EVP_MAX_MD_SIZE) + goto err; + + if (!tls13_secret_init(&export_secret, md_len)) + goto err; + if (!tls13_secret_init(&context, md_len)) + goto err; + + /* In TLSv1.3 no context is equivalent to an empty context. */ + if (context_value == NULL) { + context_value = ""; + context_value_len = 0; + } + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_DigestInit_ex(md_ctx, secrets->digest, NULL)) + goto err; + if (!EVP_DigestUpdate(md_ctx, context_value, context_value_len)) + goto err; + if (!EVP_DigestFinal_ex(md_ctx, context.data, &md_out_len)) + goto err; + if (md_len != md_out_len) + goto err; + + if (!tls13_derive_secret_with_label_length(&export_secret, + secrets->digest, &secrets->exporter_master, label, label_len, + &secrets->empty_hash)) + goto err; + + if (!tls13_hkdf_expand_label(&export_out, secrets->digest, + &export_secret, "exporter", &context)) + goto err; + + ret = 1; + + err: + EVP_MD_CTX_free(md_ctx); + tls13_secret_cleanup(&context); + tls13_secret_cleanup(&export_secret); + + return ret; +} diff --git a/Libraries/libressl/ssl/tls13_legacy.c b/Libraries/libressl/ssl/tls13_legacy.c new file mode 100644 index 000000000..1d6a5a129 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_legacy.c @@ -0,0 +1,556 @@ +/* $OpenBSD: tls13_legacy.c,v 1.40 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" +#include "tls13_internal.h" + +static ssize_t +tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len) +{ + int n; + + if (ssl->rbio == NULL) { + SSLerror(ssl, SSL_R_BIO_NOT_SET); + return TLS13_IO_FAILURE; + } + + ssl->rwstate = SSL_READING; + errno = 0; + + if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) { + if (BIO_should_read(ssl->rbio)) + return TLS13_IO_WANT_POLLIN; + if (n == 0) + return TLS13_IO_EOF; + + if (ERR_peek_error() == 0 && errno != 0) + SYSerror(errno); + + return TLS13_IO_FAILURE; + } + + if (n == len) + ssl->rwstate = SSL_NOTHING; + + return n; +} + +ssize_t +tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg) +{ + struct tls13_ctx *ctx = arg; + + return tls13_legacy_wire_read(ctx->ssl, buf, n); +} + +static ssize_t +tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len) +{ + int n; + + if (ssl->wbio == NULL) { + SSLerror(ssl, SSL_R_BIO_NOT_SET); + return TLS13_IO_FAILURE; + } + + ssl->rwstate = SSL_WRITING; + errno = 0; + + if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) { + if (BIO_should_write(ssl->wbio)) + return TLS13_IO_WANT_POLLOUT; + + if (ERR_peek_error() == 0 && errno != 0) + SYSerror(errno); + + return TLS13_IO_FAILURE; + } + + if (n == len) + ssl->rwstate = SSL_NOTHING; + + return n; +} + +ssize_t +tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg) +{ + struct tls13_ctx *ctx = arg; + + return tls13_legacy_wire_write(ctx->ssl, buf, n); +} + +static ssize_t +tls13_legacy_wire_flush(SSL *ssl) +{ + if (BIO_flush(ssl->wbio) <= 0) { + if (BIO_should_write(ssl->wbio)) + return TLS13_IO_WANT_POLLOUT; + + if (ERR_peek_error() == 0 && errno != 0) + SYSerror(errno); + + return TLS13_IO_FAILURE; + } + + return TLS13_IO_SUCCESS; +} + +ssize_t +tls13_legacy_wire_flush_cb(void *arg) +{ + struct tls13_ctx *ctx = arg; + + return tls13_legacy_wire_flush(ctx->ssl); +} + +static void +tls13_legacy_error(SSL *ssl) +{ + struct tls13_ctx *ctx = ssl->tls13; + int reason = SSL_R_UNKNOWN; + + /* If we received a fatal alert we already put an error on the stack. */ + if (ssl->s3->fatal_alert != 0) + return; + + switch (ctx->error.code) { + case TLS13_ERR_VERIFY_FAILED: + reason = SSL_R_CERTIFICATE_VERIFY_FAILED; + break; + case TLS13_ERR_HRR_FAILED: + reason = SSL_R_NO_CIPHERS_AVAILABLE; + break; + case TLS13_ERR_TRAILING_DATA: + reason = SSL_R_EXTRA_DATA_IN_MESSAGE; + break; + case TLS13_ERR_NO_SHARED_CIPHER: + reason = SSL_R_NO_SHARED_CIPHER; + break; + case TLS13_ERR_NO_CERTIFICATE: + reason = SSL_R_MISSING_RSA_CERTIFICATE; /* XXX */ + break; + case TLS13_ERR_NO_PEER_CERTIFICATE: + reason = SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE; + break; + } + + /* Something (probably libcrypto) already pushed an error on the stack. */ + if (reason == SSL_R_UNKNOWN && ERR_peek_error() != 0) + return; + + ERR_put_error(ERR_LIB_SSL, (0xfff), reason, ctx->error.file, + ctx->error.line); +} + +int +tls13_legacy_return_code(SSL *ssl, ssize_t ret) +{ + if (ret > INT_MAX) { + SSLerror(ssl, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* A successful read, write or other operation. */ + if (ret > 0) + return ret; + + ssl->rwstate = SSL_NOTHING; + + switch (ret) { + case TLS13_IO_EOF: + return 0; + + case TLS13_IO_FAILURE: + tls13_legacy_error(ssl); + return -1; + + case TLS13_IO_ALERT: + tls13_legacy_error(ssl); + return -1; + + case TLS13_IO_WANT_POLLIN: + BIO_set_retry_read(ssl->rbio); + ssl->rwstate = SSL_READING; + return -1; + + case TLS13_IO_WANT_POLLOUT: + BIO_set_retry_write(ssl->wbio); + ssl->rwstate = SSL_WRITING; + return -1; + + case TLS13_IO_WANT_RETRY: + SSLerror(ssl, ERR_R_INTERNAL_ERROR); + return -1; + } + + SSLerror(ssl, ERR_R_INTERNAL_ERROR); + return -1; +} + +int +tls13_legacy_pending(const SSL *ssl) +{ + struct tls13_ctx *ctx = ssl->tls13; + ssize_t ret; + + if (ctx == NULL) + return 0; + + ret = tls13_pending_application_data(ctx->rl); + if (ret < 0 || ret > INT_MAX) + return 0; + + return ret; +} + +int +tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek) +{ + struct tls13_ctx *ctx = ssl->tls13; + ssize_t ret; + + if (ctx == NULL || !ctx->handshake_completed) { + if ((ret = ssl->handshake_func(ssl)) <= 0) + return ret; + if (len == 0) + return 0; + return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN); + } + + tls13_record_layer_set_retry_after_phh(ctx->rl, + (ctx->ssl->mode & SSL_MODE_AUTO_RETRY) != 0); + + if (type != SSL3_RT_APPLICATION_DATA) { + SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + if (len < 0) { + SSLerror(ssl, SSL_R_BAD_LENGTH); + return -1; + } + + if (peek) + ret = tls13_peek_application_data(ctx->rl, buf, len); + else + ret = tls13_read_application_data(ctx->rl, buf, len); + + return tls13_legacy_return_code(ssl, ret); +} + +int +tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len) +{ + struct tls13_ctx *ctx = ssl->tls13; + const uint8_t *buf = vbuf; + size_t n, sent; + ssize_t ret; + + if (ctx == NULL || !ctx->handshake_completed) { + if ((ret = ssl->handshake_func(ssl)) <= 0) + return ret; + if (len == 0) + return 0; + return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLOUT); + } + + if (type != SSL3_RT_APPLICATION_DATA) { + SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + if (len < 0) { + SSLerror(ssl, SSL_R_BAD_LENGTH); + return -1; + } + + /* + * The TLSv1.3 record layer write behaviour is the same as + * SSL_MODE_ENABLE_PARTIAL_WRITE. + */ + if (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE) { + ret = tls13_write_application_data(ctx->rl, buf, len); + return tls13_legacy_return_code(ssl, ret); + } + + /* + * In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until + * we have written out all of the requested data. + */ + sent = ssl->s3->wnum; + if (len < sent) { + SSLerror(ssl, SSL_R_BAD_LENGTH); + return -1; + } + n = len - sent; + for (;;) { + if (n == 0) { + ssl->s3->wnum = 0; + return sent; + } + if ((ret = tls13_write_application_data(ctx->rl, + &buf[sent], n)) <= 0) { + ssl->s3->wnum = sent; + return tls13_legacy_return_code(ssl, ret); + } + sent += ret; + n -= ret; + } +} + +static int +tls13_use_legacy_stack(struct tls13_ctx *ctx) +{ + SSL *s = ctx->ssl; + CBB cbb, fragment; + CBS cbs; + + memset(&cbb, 0, sizeof(cbb)); + + s->method = tls_legacy_method(); + + if (!ssl3_setup_init_buffer(s)) + goto err; + if (!ssl3_setup_buffers(s)) + goto err; + if (!ssl_init_wbio_buffer(s, 1)) + goto err; + + /* Stash any unprocessed data from the last record. */ + tls13_record_layer_rcontent(ctx->rl, &cbs); + if (CBS_len(&cbs) > 0) { + if (!CBB_init_fixed(&cbb, s->s3->rbuf.buf, + s->s3->rbuf.len)) + goto err; + if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE)) + goto err; + if (!CBB_add_u16(&cbb, TLS1_2_VERSION)) + goto err; + if (!CBB_add_u16_length_prefixed(&cbb, &fragment)) + goto err; + if (!CBB_add_bytes(&fragment, CBS_data(&cbs), CBS_len(&cbs))) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; + + s->s3->rbuf.offset = SSL3_RT_HEADER_LENGTH; + s->s3->rbuf.left = CBS_len(&cbs); + s->s3->rrec.type = SSL3_RT_HANDSHAKE; + s->s3->rrec.length = CBS_len(&cbs); + s->rstate = SSL_ST_READ_BODY; + s->packet = s->s3->rbuf.buf; + s->packet_length = SSL3_RT_HEADER_LENGTH; + s->mac_packet = 1; + } + + /* Stash the current handshake message. */ + tls13_handshake_msg_data(ctx->hs_msg, &cbs); + if (!BUF_MEM_grow_clean(s->init_buf, CBS_len(&cbs))) + goto err; + if (!CBS_write_bytes(&cbs, s->init_buf->data, + s->init_buf->length, NULL)) + goto err; + + s->s3->hs.tls12.reuse_message = 1; + s->s3->hs.tls12.message_type = tls13_handshake_msg_type(ctx->hs_msg); + s->s3->hs.tls12.message_size = CBS_len(&cbs) - SSL3_HM_HEADER_LENGTH; + + return 1; + + err: + CBB_cleanup(&cbb); + + return 0; +} + +int +tls13_use_legacy_client(struct tls13_ctx *ctx) +{ + SSL *s = ctx->ssl; + + if (!tls13_use_legacy_stack(ctx)) + return 0; + + s->handshake_func = s->method->ssl_connect; + s->version = s->method->max_tls_version; + + return 1; +} + +int +tls13_use_legacy_server(struct tls13_ctx *ctx) +{ + SSL *s = ctx->ssl; + + if (!tls13_use_legacy_stack(ctx)) + return 0; + + s->handshake_func = s->method->ssl_accept; + s->version = s->method->max_tls_version; + s->server = 1; + + return 1; +} + +int +tls13_legacy_accept(SSL *ssl) +{ + struct tls13_ctx *ctx = ssl->tls13; + int ret; + + if (ctx == NULL) { + if ((ctx = tls13_ctx_new(TLS13_HS_SERVER, ssl)) == NULL) { + SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ + return -1; + } + if (!tls13_server_init(ctx)) { + if (ERR_peek_error() == 0) + SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ + return -1; + } + } + + ERR_clear_error(); + + ret = tls13_server_accept(ctx); + if (ret == TLS13_IO_USE_LEGACY) + return ssl->method->ssl_accept(ssl); + + ret = tls13_legacy_return_code(ssl, ret); + + if (ctx->info_cb != NULL) + ctx->info_cb(ctx, TLS13_INFO_ACCEPT_EXIT, ret); + + return ret; +} + +int +tls13_legacy_connect(SSL *ssl) +{ + struct tls13_ctx *ctx = ssl->tls13; + int ret; + + if (ctx == NULL) { + if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT, ssl)) == NULL) { + SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ + return -1; + } + if (!tls13_client_init(ctx)) { + if (ERR_peek_error() == 0) + SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ + return -1; + } + } + + ERR_clear_error(); + + ret = tls13_client_connect(ctx); + if (ret == TLS13_IO_USE_LEGACY) + return ssl->method->ssl_connect(ssl); + + ret = tls13_legacy_return_code(ssl, ret); + + if (ctx->info_cb != NULL) + ctx->info_cb(ctx, TLS13_INFO_CONNECT_EXIT, ret); + + return ret; +} + +int +tls13_legacy_shutdown(SSL *ssl) +{ + struct tls13_ctx *ctx = ssl->tls13; + uint8_t buf[512]; /* XXX */ + ssize_t ret; + + /* + * We need to return 0 at the point that we have completed sending a + * close-notify. We return 1 when we have sent and received close-notify + * alerts. All other cases, including EOF, return -1 and set internal + * state appropriately. + */ + if (ctx == NULL || ssl->quiet_shutdown) { + ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN; + return 1; + } + + if (!ctx->close_notify_sent) { + /* Enqueue and send close notify. */ + if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) { + ssl->shutdown |= SSL_SENT_SHUTDOWN; + if ((ret = tls13_send_alert(ctx->rl, + TLS13_ALERT_CLOSE_NOTIFY)) < 0) + return tls13_legacy_return_code(ssl, ret); + } + ret = tls13_record_layer_send_pending(ctx->rl); + if (ret == TLS13_IO_EOF) + return -1; + if (ret != TLS13_IO_SUCCESS) + return tls13_legacy_return_code(ssl, ret); + } else if (!ctx->close_notify_recv) { + /* + * If there is no application data pending, attempt to read more + * data in order to receive a close-notify. This should trigger + * a record to be read from the wire, which may be application + * handshake or alert data. Only one attempt is made to match + * previous semantics. + */ + if (tls13_pending_application_data(ctx->rl) == 0) { + if ((ret = tls13_read_application_data(ctx->rl, buf, + sizeof(buf))) < 0) + return tls13_legacy_return_code(ssl, ret); + if (!ctx->close_notify_recv) + return -1; + } + } + + if (ctx->close_notify_recv) + return 1; + + return 0; +} + +int +tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert) +{ + int legacy_alert = SSL_AD_UNRECOGNIZED_NAME; + int ret = SSL_TLSEXT_ERR_NOACK; + SSL_CTX *ssl_ctx = ctx->ssl->ctx; + SSL *s = ctx->ssl; + + if (ssl_ctx->tlsext_servername_callback == NULL) + ssl_ctx = s->initial_ctx; + if (ssl_ctx->tlsext_servername_callback == NULL) + return 1; + + ret = ssl_ctx->tlsext_servername_callback(s, &legacy_alert, + ssl_ctx->tlsext_servername_arg); + + /* + * Ignore SSL_TLSEXT_ERR_ALERT_WARNING returns to match OpenSSL's + * behavior: the only warning alerts in TLSv1.3 are close_notify and + * user_canceled, neither of which should be returned by the callback. + */ + if (ret == SSL_TLSEXT_ERR_ALERT_FATAL) { + if (legacy_alert >= 0 && legacy_alert <= 255) + *alert = legacy_alert; + return 0; + } + + return 1; +} diff --git a/Libraries/libressl/ssl/tls13_lib.c b/Libraries/libressl/ssl/tls13_lib.c new file mode 100644 index 000000000..05f125adc --- /dev/null +++ b/Libraries/libressl/ssl/tls13_lib.c @@ -0,0 +1,701 @@ +/* $OpenBSD: tls13_lib.c,v 1.76 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * Copyright (c) 2019 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "ssl_local.h" +#include "ssl_tlsext.h" +#include "tls13_internal.h" + +/* + * RFC 8446, section 4.6.1. Servers must not indicate a lifetime longer than + * 7 days and clients must not cache tickets for longer than 7 days. + */ + +#define TLS13_MAX_TICKET_LIFETIME (7 * 24 * 3600) + +/* + * Downgrade sentinels - RFC 8446 section 4.1.3, magic values which must be set + * by the server in server random if it is willing to downgrade but supports + * TLSv1.3 + */ +const uint8_t tls13_downgrade_12[8] = { + 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01, +}; +const uint8_t tls13_downgrade_11[8] = { + 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00, +}; + +/* + * HelloRetryRequest hash - RFC 8446 section 4.1.3. + */ +const uint8_t tls13_hello_retry_request_hash[32] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, + 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, + 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, + 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, +}; + +/* + * Certificate Verify padding - RFC 8446 section 4.4.3. + */ +const uint8_t tls13_cert_verify_pad[64] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +}; + +const uint8_t tls13_cert_client_verify_context[] = + "TLS 1.3, client CertificateVerify"; +const uint8_t tls13_cert_server_verify_context[] = + "TLS 1.3, server CertificateVerify"; + +const EVP_AEAD * +tls13_cipher_aead(const SSL_CIPHER *cipher) +{ + if (cipher == NULL) + return NULL; + if (cipher->algorithm_ssl != SSL_TLSV1_3) + return NULL; + + switch (cipher->algorithm_enc) { + case SSL_AES128GCM: + return EVP_aead_aes_128_gcm(); + case SSL_AES256GCM: + return EVP_aead_aes_256_gcm(); + case SSL_CHACHA20POLY1305: + return EVP_aead_chacha20_poly1305(); + } + + return NULL; +} + +const EVP_MD * +tls13_cipher_hash(const SSL_CIPHER *cipher) +{ + if (cipher == NULL) + return NULL; + if (cipher->algorithm_ssl != SSL_TLSV1_3) + return NULL; + + switch (cipher->algorithm2) { + case SSL_HANDSHAKE_MAC_SHA256: + return EVP_sha256(); + case SSL_HANDSHAKE_MAC_SHA384: + return EVP_sha384(); + } + + return NULL; +} + +void +tls13_alert_received_cb(uint8_t alert_desc, void *arg) +{ + struct tls13_ctx *ctx = arg; + + if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) { + ctx->close_notify_recv = 1; + ctx->ssl->shutdown |= SSL_RECEIVED_SHUTDOWN; + ctx->ssl->s3->warn_alert = alert_desc; + return; + } + + if (alert_desc == TLS13_ALERT_USER_CANCELED) { + /* + * We treat this as advisory, since a close_notify alert + * SHOULD follow this alert (RFC 8446 section 6.1). + */ + return; + } + + /* All other alerts are treated as fatal in TLSv1.3. */ + ctx->ssl->s3->fatal_alert = alert_desc; + + SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc); + ERR_asprintf_error_data("SSL alert number %d", alert_desc); + + SSL_CTX_remove_session(ctx->ssl->ctx, ctx->ssl->session); +} + +void +tls13_alert_sent_cb(uint8_t alert_desc, void *arg) +{ + struct tls13_ctx *ctx = arg; + + if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) { + ctx->close_notify_sent = 1; + return; + } + + if (alert_desc == TLS13_ALERT_USER_CANCELED) { + return; + } + + /* All other alerts are treated as fatal in TLSv1.3. */ + if (ctx->error.code == 0) + SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc); +} + +static void +tls13_legacy_handshake_message_recv_cb(void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *s = ctx->ssl; + CBS cbs; + + if (s->msg_callback == NULL) + return; + + tls13_handshake_msg_data(ctx->hs_msg, &cbs); + ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, &cbs); +} + +static void +tls13_legacy_handshake_message_sent_cb(void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *s = ctx->ssl; + CBS cbs; + + if (s->msg_callback == NULL) + return; + + tls13_handshake_msg_data(ctx->hs_msg, &cbs); + ssl_msg_callback_cbs(s, 1, SSL3_RT_HANDSHAKE, &cbs); +} + +static void +tls13_legacy_info_cb(void *arg, int state, int ret) +{ + struct tls13_ctx *ctx = arg; + SSL *s = ctx->ssl; + + ssl_info_callback(s, state, ret); +} + +static int +tls13_legacy_ocsp_status_recv_cb(void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *s = ctx->ssl; + int ret; + + if (s->ctx->tlsext_status_cb == NULL) + return 1; + + ret = s->ctx->tlsext_status_cb(s, + s->ctx->tlsext_status_arg); + if (ret < 0) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + SSLerror(s, ERR_R_MALLOC_FAILURE); + return 0; + } + if (ret == 0) { + ctx->alert = TLS13_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE; + SSLerror(s, SSL_R_INVALID_STATUS_RESPONSE); + return 0; + } + + return 1; +} + +static int +tls13_phh_update_read_traffic_secret(struct tls13_ctx *ctx) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret *secret; + + if (ctx->mode == TLS13_HS_CLIENT) { + secret = &secrets->server_application_traffic; + if (!tls13_update_server_traffic_secret(secrets)) + return 0; + } else { + secret = &secrets->client_application_traffic; + if (!tls13_update_client_traffic_secret(secrets)) + return 0; + } + + return tls13_record_layer_set_read_traffic_key(ctx->rl, + secret, ssl_encryption_application); +} + +static int +tls13_phh_update_write_traffic_secret(struct tls13_ctx *ctx) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret *secret; + + if (ctx->mode == TLS13_HS_CLIENT) { + secret = &secrets->client_application_traffic; + if (!tls13_update_client_traffic_secret(secrets)) + return 0; + } else { + secret = &secrets->server_application_traffic; + if (!tls13_update_server_traffic_secret(secrets)) + return 0; + } + + return tls13_record_layer_set_write_traffic_key(ctx->rl, + secret, ssl_encryption_application); +} + +/* + * XXX arbitrarily chosen limit of 100 post handshake handshake + * messages in an hour - to avoid a hostile peer from constantly + * requesting certificates or key renegotiaitons, etc. + */ +static int +tls13_phh_limit_check(struct tls13_ctx *ctx) +{ + time_t now = time(NULL); + + if (ctx->phh_last_seen > now - TLS13_PHH_LIMIT_TIME) { + if (ctx->phh_count > TLS13_PHH_LIMIT) + return 0; + } else + ctx->phh_count = 0; + ctx->phh_count++; + ctx->phh_last_seen = now; + return 1; +} + +static ssize_t +tls13_key_update_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + struct tls13_handshake_msg *hs_msg = NULL; + CBB cbb_hs; + CBS cbs_hs; + uint8_t alert = TLS13_ALERT_INTERNAL_ERROR; + uint8_t key_update_request; + ssize_t ret; + + if (!CBS_get_u8(cbs, &key_update_request)) { + alert = TLS13_ALERT_DECODE_ERROR; + goto err; + } + if (CBS_len(cbs) != 0) { + alert = TLS13_ALERT_DECODE_ERROR; + goto err; + } + if (key_update_request > 1) { + alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + + if (!tls13_phh_update_read_traffic_secret(ctx)) + goto err; + + if (key_update_request == 0) + return TLS13_IO_SUCCESS; + + /* Our peer requested that we update our write traffic keys. */ + if ((hs_msg = tls13_handshake_msg_new()) == NULL) + goto err; + if (!tls13_handshake_msg_start(hs_msg, &cbb_hs, TLS13_MT_KEY_UPDATE)) + goto err; + if (!CBB_add_u8(&cbb_hs, 0)) + goto err; + if (!tls13_handshake_msg_finish(hs_msg)) + goto err; + + ctx->key_update_request = 1; + tls13_handshake_msg_data(hs_msg, &cbs_hs); + ret = tls13_record_layer_phh(ctx->rl, &cbs_hs); + + tls13_handshake_msg_free(hs_msg); + hs_msg = NULL; + + return ret; + + err: + tls13_handshake_msg_free(hs_msg); + + return tls13_send_alert(ctx->rl, alert); +} + +/* RFC 8446 section 4.6.1 */ +static ssize_t +tls13_new_session_ticket_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret nonce; + uint32_t ticket_lifetime, ticket_age_add; + CBS ticket_nonce, ticket; + SSL_SESSION *sess = NULL; + int alert, session_id_length; + ssize_t ret = 0; + + memset(&nonce, 0, sizeof(nonce)); + + if (ctx->mode != TLS13_HS_CLIENT) { + alert = TLS13_ALERT_UNEXPECTED_MESSAGE; + goto err; + } + + alert = TLS13_ALERT_DECODE_ERROR; + + if (!CBS_get_u32(cbs, &ticket_lifetime)) + goto err; + if (!CBS_get_u32(cbs, &ticket_age_add)) + goto err; + if (!CBS_get_u8_length_prefixed(cbs, &ticket_nonce)) + goto err; + if (!CBS_get_u16_length_prefixed(cbs, &ticket)) + goto err; + /* Extensions can only contain early_data, which we currently ignore. */ + if (!tlsext_client_parse(ctx->ssl, SSL_TLSEXT_MSG_NST, cbs, &alert)) + goto err; + + if (CBS_len(cbs) != 0) + goto err; + + /* Zero indicates that the ticket should be discarded immediately. */ + if (ticket_lifetime == 0) { + ret = TLS13_IO_SUCCESS; + goto done; + } + + /* Servers MUST NOT use any value larger than 7 days. */ + if (ticket_lifetime > TLS13_MAX_TICKET_LIFETIME) { + alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + + alert = TLS13_ALERT_INTERNAL_ERROR; + + /* + * Create new session instead of modifying the current session. + * The current session could already be in the session cache. + */ + if ((sess = ssl_session_dup(ctx->ssl->session, 0)) == NULL) + goto err; + + sess->time = time(NULL); + + sess->tlsext_tick_lifetime_hint = ticket_lifetime; + sess->tlsext_tick_age_add = ticket_age_add; + + if (!CBS_stow(&ticket, &sess->tlsext_tick, &sess->tlsext_ticklen)) + goto err; + + /* XXX - ensure this doesn't overflow session_id if hash is changed. */ + if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), + sess->session_id, &session_id_length, EVP_sha256(), NULL)) + goto err; + sess->session_id_length = session_id_length; + + if (!CBS_stow(&ticket_nonce, &nonce.data, &nonce.len)) + goto err; + + if (!tls13_secret_init(&sess->resumption_master_secret, 256)) + goto err; + + if (!tls13_derive_secret(&sess->resumption_master_secret, + secrets->digest, &secrets->resumption_master, "resumption", + &nonce)) + goto err; + + SSL_SESSION_free(ctx->ssl->session); + ctx->ssl->session = sess; + sess = NULL; + + ssl_update_cache(ctx->ssl, SSL_SESS_CACHE_CLIENT); + + ret = TLS13_IO_SUCCESS; + goto done; + + err: + ret = tls13_send_alert(ctx->rl, alert); + + done: + tls13_secret_cleanup(&nonce); + SSL_SESSION_free(sess); + + return ret; +} + +ssize_t +tls13_phh_received_cb(void *cb_arg) +{ + ssize_t ret = TLS13_IO_FAILURE; + struct tls13_ctx *ctx = cb_arg; + CBS cbs; + + if (!tls13_phh_limit_check(ctx)) + return tls13_send_alert(ctx->rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + + if ((ctx->hs_msg == NULL) && + ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)) + return TLS13_IO_FAILURE; + + if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl)) != + TLS13_IO_SUCCESS) + return ret; + + if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) + return TLS13_IO_FAILURE; + + switch(tls13_handshake_msg_type(ctx->hs_msg)) { + case TLS13_MT_KEY_UPDATE: + ret = tls13_key_update_recv(ctx, &cbs); + break; + case TLS13_MT_NEW_SESSION_TICKET: + ret = tls13_new_session_ticket_recv(ctx, &cbs); + break; + case TLS13_MT_CERTIFICATE_REQUEST: + /* XXX add support if we choose to advertise this */ + /* FALLTHROUGH */ + default: + ret = TLS13_IO_FAILURE; /* XXX send alert */ + break; + } + + tls13_handshake_msg_free(ctx->hs_msg); + ctx->hs_msg = NULL; + return ret; +} + +void +tls13_phh_done_cb(void *cb_arg) +{ + struct tls13_ctx *ctx = cb_arg; + + if (ctx->key_update_request) { + tls13_phh_update_write_traffic_secret(ctx); + ctx->key_update_request = 0; + } +} + +static const struct tls13_record_layer_callbacks tls13_rl_callbacks = { + .wire_read = tls13_legacy_wire_read_cb, + .wire_write = tls13_legacy_wire_write_cb, + .wire_flush = tls13_legacy_wire_flush_cb, + + .alert_recv = tls13_alert_received_cb, + .alert_sent = tls13_alert_sent_cb, + .phh_recv = tls13_phh_received_cb, + .phh_sent = tls13_phh_done_cb, +}; + +struct tls13_ctx * +tls13_ctx_new(int mode, SSL *ssl) +{ + struct tls13_ctx *ctx = NULL; + + if ((ctx = calloc(sizeof(struct tls13_ctx), 1)) == NULL) + goto err; + + ctx->hs = &ssl->s3->hs; + ctx->mode = mode; + ctx->ssl = ssl; + + if ((ctx->rl = tls13_record_layer_new(&tls13_rl_callbacks, ctx)) == NULL) + goto err; + + ctx->handshake_message_sent_cb = tls13_legacy_handshake_message_sent_cb; + ctx->handshake_message_recv_cb = tls13_legacy_handshake_message_recv_cb; + ctx->info_cb = tls13_legacy_info_cb; + ctx->ocsp_status_recv_cb = tls13_legacy_ocsp_status_recv_cb; + + ctx->middlebox_compat = 1; + + ssl->tls13 = ctx; + + if (SSL_is_quic(ssl)) { + if (!tls13_quic_init(ctx)) + goto err; + } + + return ctx; + + err: + tls13_ctx_free(ctx); + + return NULL; +} + +void +tls13_ctx_free(struct tls13_ctx *ctx) +{ + if (ctx == NULL) + return; + + tls13_error_clear(&ctx->error); + tls13_record_layer_free(ctx->rl); + tls13_handshake_msg_free(ctx->hs_msg); + + freezero(ctx, sizeof(struct tls13_ctx)); +} + +int +tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert, + int (*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb)) +{ + CBB cert_data, cert_exts; + uint8_t *data; + int cert_len; + + if ((cert_len = i2d_X509(cert, NULL)) < 0) + return 0; + + if (!CBB_add_u24_length_prefixed(cbb, &cert_data)) + return 0; + if (!CBB_add_space(&cert_data, &data, cert_len)) + return 0; + if (i2d_X509(cert, &data) != cert_len) + return 0; + if (build_extensions != NULL) { + if (!build_extensions(ctx->ssl, SSL_TLSEXT_MSG_CT, cbb)) + return 0; + } else { + if (!CBB_add_u16_length_prefixed(cbb, &cert_exts)) + return 0; + } + if (!CBB_flush(cbb)) + return 0; + + return 1; +} + +int +tls13_synthetic_handshake_message(struct tls13_ctx *ctx) +{ + struct tls13_handshake_msg *hm = NULL; + unsigned char buf[EVP_MAX_MD_SIZE]; + size_t hash_len; + CBB cbb; + CBS cbs; + SSL *s = ctx->ssl; + int ret = 0; + + /* + * Replace ClientHello with synthetic handshake message - see + * RFC 8446 section 4.4.1. + */ + if (!tls1_transcript_hash_init(s)) + goto err; + if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len)) + goto err; + + if ((hm = tls13_handshake_msg_new()) == NULL) + goto err; + if (!tls13_handshake_msg_start(hm, &cbb, TLS13_MT_MESSAGE_HASH)) + goto err; + if (!CBB_add_bytes(&cbb, buf, hash_len)) + goto err; + if (!tls13_handshake_msg_finish(hm)) + goto err; + + tls13_handshake_msg_data(hm, &cbs); + + tls1_transcript_reset(ctx->ssl); + if (!tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs))) + goto err; + + ret = 1; + + err: + tls13_handshake_msg_free(hm); + + return ret; +} + +int +tls13_clienthello_hash_init(struct tls13_ctx *ctx) +{ + if (ctx->hs->tls13.clienthello_md_ctx != NULL) + return 0; + if ((ctx->hs->tls13.clienthello_md_ctx = EVP_MD_CTX_new()) == NULL) + return 0; + if (!EVP_DigestInit_ex(ctx->hs->tls13.clienthello_md_ctx, + EVP_sha256(), NULL)) + return 0; + + if ((ctx->hs->tls13.clienthello_hash == NULL) && + (ctx->hs->tls13.clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) == + NULL) + return 0; + + return 1; +} + +void +tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs) /* XXX */ +{ + EVP_MD_CTX_free(hs->clienthello_md_ctx); + hs->clienthello_md_ctx = NULL; + freezero(hs->clienthello_hash, EVP_MAX_MD_SIZE); + hs->clienthello_hash = NULL; +} + +int +tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data, + size_t len) +{ + return EVP_DigestUpdate(ctx->hs->tls13.clienthello_md_ctx, data, len); +} + +int +tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs) +{ + return tls13_clienthello_hash_update_bytes(ctx, (void *)CBS_data(cbs), + CBS_len(cbs)); +} + +int +tls13_clienthello_hash_finalize(struct tls13_ctx *ctx) +{ + if (!EVP_DigestFinal_ex(ctx->hs->tls13.clienthello_md_ctx, + ctx->hs->tls13.clienthello_hash, + &ctx->hs->tls13.clienthello_hash_len)) + return 0; + EVP_MD_CTX_free(ctx->hs->tls13.clienthello_md_ctx); + ctx->hs->tls13.clienthello_md_ctx = NULL; + return 1; +} + +int +tls13_clienthello_hash_validate(struct tls13_ctx *ctx) +{ + unsigned char new_ch_hash[EVP_MAX_MD_SIZE]; + unsigned int new_ch_hash_len; + + if (ctx->hs->tls13.clienthello_hash == NULL) + return 0; + + if (!EVP_DigestFinal_ex(ctx->hs->tls13.clienthello_md_ctx, + new_ch_hash, &new_ch_hash_len)) + return 0; + EVP_MD_CTX_free(ctx->hs->tls13.clienthello_md_ctx); + ctx->hs->tls13.clienthello_md_ctx = NULL; + + if (ctx->hs->tls13.clienthello_hash_len != new_ch_hash_len) + return 0; + if (memcmp(ctx->hs->tls13.clienthello_hash, new_ch_hash, + new_ch_hash_len) != 0) + return 0; + + return 1; +} diff --git a/Libraries/libressl/ssl/tls13_quic.c b/Libraries/libressl/ssl/tls13_quic.c new file mode 100644 index 000000000..e5c386ea3 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_quic.c @@ -0,0 +1,181 @@ +/* $OpenBSD: tls13_quic.c,v 1.7 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ssl_local.h" +#include "tls13_internal.h" + +static ssize_t +tls13_quic_wire_read_cb(void *buf, size_t n, void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR); + return TLS13_IO_FAILURE; +} + +static ssize_t +tls13_quic_wire_write_cb(const void *buf, size_t n, void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR); + return TLS13_IO_FAILURE; +} + +static ssize_t +tls13_quic_wire_flush_cb(void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + if (!ssl->quic_method->flush_flight(ssl)) { + SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR); + return TLS13_IO_FAILURE; + } + + return TLS13_IO_SUCCESS; +} + +static ssize_t +tls13_quic_handshake_read_cb(void *buf, size_t n, void *arg) +{ + struct tls13_ctx *ctx = arg; + + if (ctx->hs->tls13.quic_read_buffer == NULL) + return TLS13_IO_WANT_POLLIN; + + return tls_buffer_read(ctx->hs->tls13.quic_read_buffer, buf, n); +} + +static ssize_t +tls13_quic_handshake_write_cb(const void *buf, size_t n, void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + if (!ssl->quic_method->add_handshake_data(ssl, + ctx->hs->tls13.quic_write_level, buf, n)) { + SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR); + return TLS13_IO_FAILURE; + } + + return n; +} + +static int +tls13_quic_set_read_traffic_key(struct tls13_secret *read_key, + enum ssl_encryption_level_t read_level, void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + ctx->hs->tls13.quic_read_level = read_level; + + /* Handle both the new (BoringSSL) and old (quictls) APIs. */ + + if (ssl->quic_method->set_read_secret != NULL) + return ssl->quic_method->set_read_secret(ssl, + ctx->hs->tls13.quic_read_level, ctx->hs->cipher, + read_key->data, read_key->len); + + if (ssl->quic_method->set_encryption_secrets != NULL) + return ssl->quic_method->set_encryption_secrets(ssl, + ctx->hs->tls13.quic_read_level, read_key->data, NULL, + read_key->len); + + return 0; +} + +static int +tls13_quic_set_write_traffic_key(struct tls13_secret *write_key, + enum ssl_encryption_level_t write_level, void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + ctx->hs->tls13.quic_write_level = write_level; + + /* Handle both the new (BoringSSL) and old (quictls) APIs. */ + + if (ssl->quic_method->set_write_secret != NULL) + return ssl->quic_method->set_write_secret(ssl, + ctx->hs->tls13.quic_write_level, ctx->hs->cipher, + write_key->data, write_key->len); + + if (ssl->quic_method->set_encryption_secrets != NULL) + return ssl->quic_method->set_encryption_secrets(ssl, + ctx->hs->tls13.quic_write_level, NULL, write_key->data, + write_key->len); + + return 0; +} + +static int +tls13_quic_alert_send_cb(int alert_desc, void *arg) +{ + struct tls13_ctx *ctx = arg; + SSL *ssl = ctx->ssl; + + if (!ssl->quic_method->send_alert(ssl, ctx->hs->tls13.quic_write_level, + alert_desc)) { + SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR); + return TLS13_IO_FAILURE; + } + + return TLS13_IO_SUCCESS; +} + +static const struct tls13_record_layer_callbacks quic_rl_callbacks = { + .wire_read = tls13_quic_wire_read_cb, + .wire_write = tls13_quic_wire_write_cb, + .wire_flush = tls13_quic_wire_flush_cb, + + .handshake_read = tls13_quic_handshake_read_cb, + .handshake_write = tls13_quic_handshake_write_cb, + .set_read_traffic_key = tls13_quic_set_read_traffic_key, + .set_write_traffic_key = tls13_quic_set_write_traffic_key, + .alert_send = tls13_quic_alert_send_cb, + + .alert_recv = tls13_alert_received_cb, + .alert_sent = tls13_alert_sent_cb, + .phh_recv = tls13_phh_received_cb, + .phh_sent = tls13_phh_done_cb, +}; + +int +tls13_quic_init(struct tls13_ctx *ctx) +{ + BIO *bio; + + tls13_record_layer_set_callbacks(ctx->rl, &quic_rl_callbacks, ctx); + + ctx->middlebox_compat = 0; + + /* + * QUIC does not use BIOs, however we currently expect a BIO to exist + * for status handling. + */ + if ((bio = BIO_new(BIO_s_null())) == NULL) + return 0; + + SSL_set_bio(ctx->ssl, bio, bio); + bio = NULL; + + return 1; +} diff --git a/Libraries/libressl/ssl/tls13_record.c b/Libraries/libressl/ssl/tls13_record.c new file mode 100644 index 000000000..dbc835c54 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_record.c @@ -0,0 +1,186 @@ +/* $OpenBSD: tls13_record.c,v 1.10 2022/07/22 19:33:53 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "tls13_internal.h" +#include "tls13_record.h" + +struct tls13_record { + uint16_t version; + uint8_t content_type; + size_t rec_len; + uint8_t *data; + size_t data_len; + CBS cbs; + + struct tls_buffer *buf; +}; + +struct tls13_record * +tls13_record_new(void) +{ + struct tls13_record *rec = NULL; + + if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL) + goto err; + if ((rec->buf = tls_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL) + goto err; + + return rec; + + err: + tls13_record_free(rec); + + return NULL; +} + +void +tls13_record_free(struct tls13_record *rec) +{ + if (rec == NULL) + return; + + tls_buffer_free(rec->buf); + + freezero(rec->data, rec->data_len); + freezero(rec, sizeof(struct tls13_record)); +} + +uint16_t +tls13_record_version(struct tls13_record *rec) +{ + return rec->version; +} + +uint8_t +tls13_record_content_type(struct tls13_record *rec) +{ + return rec->content_type; +} + +int +tls13_record_header(struct tls13_record *rec, CBS *cbs) +{ + if (rec->data_len < TLS13_RECORD_HEADER_LEN) + return 0; + + CBS_init(cbs, rec->data, TLS13_RECORD_HEADER_LEN); + + return 1; +} + +int +tls13_record_content(struct tls13_record *rec, CBS *cbs) +{ + CBS content; + + tls13_record_data(rec, &content); + + if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN)) + return 0; + + CBS_dup(&content, cbs); + + return 1; +} + +void +tls13_record_data(struct tls13_record *rec, CBS *cbs) +{ + CBS_init(cbs, rec->data, rec->data_len); +} + +int +tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len) +{ + if (data_len > TLS13_RECORD_MAX_LEN) + return 0; + + freezero(rec->data, rec->data_len); + rec->data = data; + rec->data_len = data_len; + CBS_init(&rec->cbs, rec->data, rec->data_len); + + return 1; +} + +ssize_t +tls13_record_recv(struct tls13_record *rec, tls_read_cb wire_read, + void *wire_arg) +{ + uint16_t rec_len, rec_version; + uint8_t content_type; + ssize_t ret; + CBS cbs; + + if (rec->data != NULL) + return TLS13_IO_FAILURE; + + if (rec->content_type == 0) { + if ((ret = tls_buffer_extend(rec->buf, + TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0) + return ret; + + if (!tls_buffer_data(rec->buf, &cbs)) + return TLS13_IO_FAILURE; + + if (!CBS_get_u8(&cbs, &content_type)) + return TLS13_IO_FAILURE; + if (!CBS_get_u16(&cbs, &rec_version)) + return TLS13_IO_FAILURE; + if (!CBS_get_u16(&cbs, &rec_len)) + return TLS13_IO_FAILURE; + + if ((rec_version >> 8) != SSL3_VERSION_MAJOR) + return TLS13_IO_RECORD_VERSION; + if (rec_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN) + return TLS13_IO_RECORD_OVERFLOW; + + rec->content_type = content_type; + rec->version = rec_version; + rec->rec_len = rec_len; + } + + if ((ret = tls_buffer_extend(rec->buf, + TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0) + return ret; + + if (!tls_buffer_finish(rec->buf, &rec->data, &rec->data_len)) + return TLS13_IO_FAILURE; + + return rec->data_len; +} + +ssize_t +tls13_record_send(struct tls13_record *rec, tls_write_cb wire_write, + void *wire_arg) +{ + ssize_t ret; + + if (rec->data == NULL) + return TLS13_IO_FAILURE; + + while (CBS_len(&rec->cbs) > 0) { + if ((ret = wire_write(CBS_data(&rec->cbs), + CBS_len(&rec->cbs), wire_arg)) <= 0) + return ret; + + if (!CBS_skip(&rec->cbs, ret)) + return TLS13_IO_FAILURE; + } + + return rec->data_len; +} diff --git a/Libraries/libressl/ssl/tls13_record.h b/Libraries/libressl/ssl/tls13_record.h new file mode 100644 index 000000000..18e4fa1ab --- /dev/null +++ b/Libraries/libressl/ssl/tls13_record.h @@ -0,0 +1,66 @@ +/* $OpenBSD: tls13_record.h,v 1.5 2021/10/23 13:12:14 jsing Exp $ */ +/* + * Copyright (c) 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS13_RECORD_H +#define HEADER_TLS13_RECORD_H + +#include "bytestring.h" + +__BEGIN_HIDDEN_DECLS + +/* + * TLSv1.3 Record Protocol - RFC 8446 section 5. + * + * The maximum plaintext is 2^14, however for inner plaintext an additional + * byte is allowed for the content type. A maximum AEAD overhead of 255-bytes + * is permitted, along with a 5-byte header, giving a maximum size of + * 5 + 2^14 + 1 + 255 = 16,645-bytes. + */ +#define TLS13_RECORD_HEADER_LEN 5 +#define TLS13_RECORD_MAX_AEAD_OVERHEAD 255 +#define TLS13_RECORD_MAX_PLAINTEXT_LEN 16384 +#define TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN \ + (TLS13_RECORD_MAX_PLAINTEXT_LEN + 1) +#define TLS13_RECORD_MAX_CIPHERTEXT_LEN \ + (TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN + TLS13_RECORD_MAX_AEAD_OVERHEAD) +#define TLS13_RECORD_MAX_LEN \ + (TLS13_RECORD_HEADER_LEN + TLS13_RECORD_MAX_CIPHERTEXT_LEN) + +/* + * TLSv1.3 Per-Record Nonces and Sequence Numbers - RFC 8446 section 5.3. + */ +#define TLS13_RECORD_SEQ_NUM_LEN 8 + +struct tls13_record; + +struct tls13_record *tls13_record_new(void); +void tls13_record_free(struct tls13_record *_rec); +uint16_t tls13_record_version(struct tls13_record *_rec); +uint8_t tls13_record_content_type(struct tls13_record *_rec); +int tls13_record_header(struct tls13_record *_rec, CBS *_cbs); +int tls13_record_content(struct tls13_record *_rec, CBS *_cbs); +void tls13_record_data(struct tls13_record *_rec, CBS *_cbs); +int tls13_record_set_data(struct tls13_record *_rec, uint8_t *_data, + size_t _data_len); +ssize_t tls13_record_recv(struct tls13_record *_rec, tls_read_cb _wire_read, + void *_wire_arg); +ssize_t tls13_record_send(struct tls13_record *_rec, tls_write_cb _wire_write, + void *_wire_arg); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/tls13_record_layer.c b/Libraries/libressl/ssl/tls13_record_layer.c new file mode 100644 index 000000000..4ae4e298e --- /dev/null +++ b/Libraries/libressl/ssl/tls13_record_layer.c @@ -0,0 +1,1222 @@ +/* $OpenBSD: tls13_record_layer.c,v 1.72 2022/11/11 17:15:27 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "tls13_internal.h" +#include "tls13_record.h" +#include "tls_content.h" + +static ssize_t tls13_record_layer_write_chunk(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *buf, size_t n); +static ssize_t tls13_record_layer_write_record(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len); + +struct tls13_record_protection { + EVP_AEAD_CTX *aead_ctx; + struct tls13_secret iv; + struct tls13_secret nonce; + uint8_t seq_num[TLS13_RECORD_SEQ_NUM_LEN]; +}; + +struct tls13_record_protection * +tls13_record_protection_new(void) +{ + return calloc(1, sizeof(struct tls13_record_protection)); +} + +void +tls13_record_protection_clear(struct tls13_record_protection *rp) +{ + EVP_AEAD_CTX_free(rp->aead_ctx); + + tls13_secret_cleanup(&rp->iv); + tls13_secret_cleanup(&rp->nonce); + + memset(rp, 0, sizeof(*rp)); +} + +void +tls13_record_protection_free(struct tls13_record_protection *rp) +{ + if (rp == NULL) + return; + + tls13_record_protection_clear(rp); + + freezero(rp, sizeof(struct tls13_record_protection)); +} + +struct tls13_record_layer { + uint16_t legacy_version; + + int ccs_allowed; + int ccs_seen; + int ccs_sent; + int handshake_completed; + int legacy_alerts_allowed; + int phh; + int phh_retry; + + /* + * Read and/or write channels are closed due to an alert being + * sent or received. In the case of an error alert both channels + * are closed, whereas in the case of a close notify only one + * channel is closed. + */ + int read_closed; + int write_closed; + + struct tls13_record *rrec; + + struct tls13_record *wrec; + uint8_t wrec_content_type; + size_t wrec_appdata_len; + size_t wrec_content_len; + + /* Alert to be sent on return from current read handler. */ + uint8_t alert; + + /* Pending alert messages. */ + uint8_t *alert_data; + size_t alert_len; + uint8_t alert_level; + uint8_t alert_desc; + + /* Pending post-handshake handshake messages (RFC 8446, section 4.6). */ + CBS phh_cbs; + uint8_t *phh_data; + size_t phh_len; + + /* Content from opened records. */ + struct tls_content *rcontent; + + /* Record protection. */ + const EVP_MD *hash; + const EVP_AEAD *aead; + struct tls13_record_protection *read; + struct tls13_record_protection *write; + + /* Callbacks. */ + struct tls13_record_layer_callbacks cb; + void *cb_arg; +}; + +static void +tls13_record_layer_rrec_free(struct tls13_record_layer *rl) +{ + tls13_record_free(rl->rrec); + rl->rrec = NULL; +} + +static void +tls13_record_layer_wrec_free(struct tls13_record_layer *rl) +{ + tls13_record_free(rl->wrec); + rl->wrec = NULL; +} + +struct tls13_record_layer * +tls13_record_layer_new(const struct tls13_record_layer_callbacks *callbacks, + void *cb_arg) +{ + struct tls13_record_layer *rl; + + if ((rl = calloc(1, sizeof(struct tls13_record_layer))) == NULL) + goto err; + + if ((rl->rcontent = tls_content_new()) == NULL) + goto err; + + if ((rl->read = tls13_record_protection_new()) == NULL) + goto err; + if ((rl->write = tls13_record_protection_new()) == NULL) + goto err; + + rl->legacy_version = TLS1_2_VERSION; + + tls13_record_layer_set_callbacks(rl, callbacks, cb_arg); + + return rl; + + err: + tls13_record_layer_free(rl); + + return NULL; +} + +void +tls13_record_layer_free(struct tls13_record_layer *rl) +{ + if (rl == NULL) + return; + + tls13_record_layer_rrec_free(rl); + tls13_record_layer_wrec_free(rl); + + freezero(rl->alert_data, rl->alert_len); + freezero(rl->phh_data, rl->phh_len); + + tls_content_free(rl->rcontent); + + tls13_record_protection_free(rl->read); + tls13_record_protection_free(rl->write); + + freezero(rl, sizeof(struct tls13_record_layer)); +} + +void +tls13_record_layer_set_callbacks(struct tls13_record_layer *rl, + const struct tls13_record_layer_callbacks *callbacks, void *cb_arg) +{ + rl->cb = *callbacks; + rl->cb_arg = cb_arg; +} + +void +tls13_record_layer_rcontent(struct tls13_record_layer *rl, CBS *cbs) +{ + CBS_dup(tls_content_cbs(rl->rcontent), cbs); +} + +static const uint8_t tls13_max_seq_num[TLS13_RECORD_SEQ_NUM_LEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +int +tls13_record_layer_inc_seq_num(uint8_t *seq_num) +{ + int i; + + /* RFC 8446 section 5.3 - sequence numbers must not wrap. */ + if (memcmp(seq_num, tls13_max_seq_num, TLS13_RECORD_SEQ_NUM_LEN) == 0) + return 0; + + for (i = TLS13_RECORD_SEQ_NUM_LEN - 1; i >= 0; i--) { + if (++seq_num[i] != 0) + break; + } + + return 1; +} + +static int +tls13_record_layer_update_nonce(struct tls13_secret *nonce, + struct tls13_secret *iv, uint8_t *seq_num) +{ + ssize_t i, j; + + if (nonce->len != iv->len) + return 0; + + /* + * RFC 8446 section 5.3 - sequence number is zero padded and XOR'd + * with the IV to produce a per-record nonce. The IV will also be + * at least 8-bytes in length. + */ + for (i = nonce->len - 1, j = TLS13_RECORD_SEQ_NUM_LEN - 1; i >= 0; i--, j--) + nonce->data[i] = iv->data[i] ^ (j >= 0 ? seq_num[j] : 0); + + return 1; +} + +void +tls13_record_layer_allow_ccs(struct tls13_record_layer *rl, int allow) +{ + rl->ccs_allowed = allow; +} + +void +tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer *rl, int allow) +{ + rl->legacy_alerts_allowed = allow; +} + +void +tls13_record_layer_set_aead(struct tls13_record_layer *rl, + const EVP_AEAD *aead) +{ + rl->aead = aead; +} + +void +tls13_record_layer_set_hash(struct tls13_record_layer *rl, + const EVP_MD *hash) +{ + rl->hash = hash; +} + +void +tls13_record_layer_set_legacy_version(struct tls13_record_layer *rl, + uint16_t version) +{ + rl->legacy_version = version; +} + +void +tls13_record_layer_handshake_completed(struct tls13_record_layer *rl) +{ + rl->handshake_completed = 1; +} + +void +tls13_record_layer_set_retry_after_phh(struct tls13_record_layer *rl, int retry) +{ + rl->phh_retry = retry; +} + +static ssize_t +tls13_record_layer_process_alert(struct tls13_record_layer *rl) +{ + uint8_t alert_level, alert_desc; + ssize_t ret = TLS13_IO_FAILURE; + + /* + * RFC 8446 - sections 5.1 and 6. + * + * A TLSv1.3 alert record can only contain a single alert - this means + * that processing the alert must consume all of the record. The alert + * will result in one of three things - continuation (user_cancelled), + * read channel closure (close_notify) or termination (all others). + */ + if (tls_content_type(rl->rcontent) != SSL3_RT_ALERT) + return TLS13_IO_FAILURE; + + if (!CBS_get_u8(tls_content_cbs(rl->rcontent), &alert_level)) + return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR); + if (!CBS_get_u8(tls_content_cbs(rl->rcontent), &alert_desc)) + return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR); + + if (tls_content_remaining(rl->rcontent) != 0) + return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR); + + tls_content_clear(rl->rcontent); + + /* + * Alert level is ignored for closure alerts (RFC 8446 section 6.1), + * however for error alerts (RFC 8446 section 6.2), the alert level + * must be specified as fatal. + */ + if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) { + rl->read_closed = 1; + ret = TLS13_IO_EOF; + } else if (alert_desc == TLS13_ALERT_USER_CANCELED) { + /* Ignored at the record layer. */ + ret = TLS13_IO_WANT_RETRY; + } else if (alert_level == TLS13_ALERT_LEVEL_FATAL) { + rl->read_closed = 1; + rl->write_closed = 1; + ret = TLS13_IO_ALERT; + } else if (rl->legacy_alerts_allowed && + alert_level == TLS13_ALERT_LEVEL_WARNING) { + /* Ignored and not passed to the callback. */ + return TLS13_IO_WANT_RETRY; + } else { + return tls13_send_alert(rl, TLS13_ALERT_ILLEGAL_PARAMETER); + } + + rl->cb.alert_recv(alert_desc, rl->cb_arg); + + return ret; +} + +static ssize_t +tls13_record_layer_send_alert(struct tls13_record_layer *rl) +{ + ssize_t ret; + + /* This has to fit into a single record, per RFC 8446 section 5.1. */ + if ((ret = tls13_record_layer_write_record(rl, SSL3_RT_ALERT, + rl->alert_data, rl->alert_len)) != rl->alert_len) { + if (ret == TLS13_IO_EOF) + ret = TLS13_IO_ALERT; + return ret; + } + + freezero(rl->alert_data, rl->alert_len); + rl->alert_data = NULL; + rl->alert_len = 0; + + if (rl->alert_desc == TLS13_ALERT_CLOSE_NOTIFY) { + rl->write_closed = 1; + ret = TLS13_IO_SUCCESS; + } else if (rl->alert_desc == TLS13_ALERT_USER_CANCELED) { + /* Ignored at the record layer. */ + ret = TLS13_IO_SUCCESS; + } else { + rl->read_closed = 1; + rl->write_closed = 1; + ret = TLS13_IO_ALERT; + } + + rl->cb.alert_sent(rl->alert_desc, rl->cb_arg); + + return ret; +} + +static ssize_t +tls13_record_layer_send_phh(struct tls13_record_layer *rl) +{ + ssize_t ret; + + /* Push out pending post-handshake handshake messages. */ + if ((ret = tls13_record_layer_write_chunk(rl, SSL3_RT_HANDSHAKE, + CBS_data(&rl->phh_cbs), CBS_len(&rl->phh_cbs))) <= 0) + return ret; + if (!CBS_skip(&rl->phh_cbs, ret)) + return TLS13_IO_FAILURE; + if (CBS_len(&rl->phh_cbs) != 0) + return TLS13_IO_WANT_RETRY; + + freezero(rl->phh_data, rl->phh_len); + rl->phh_data = NULL; + rl->phh_len = 0; + + CBS_init(&rl->phh_cbs, rl->phh_data, rl->phh_len); + + rl->cb.phh_sent(rl->cb_arg); + + return TLS13_IO_SUCCESS; +} + +ssize_t +tls13_record_layer_send_pending(struct tls13_record_layer *rl) +{ + /* + * If an alert is pending, then it needs to be sent. However, + * if we're already part of the way through sending post-handshake + * handshake messages, then we need to finish that first... + */ + + if (rl->phh_data != NULL && CBS_len(&rl->phh_cbs) != rl->phh_len) + return tls13_record_layer_send_phh(rl); + + if (rl->alert_data != NULL) + return tls13_record_layer_send_alert(rl); + + if (rl->phh_data != NULL) + return tls13_record_layer_send_phh(rl); + + return TLS13_IO_SUCCESS; +} + +static ssize_t +tls13_record_layer_enqueue_alert(struct tls13_record_layer *rl, + uint8_t alert_level, uint8_t alert_desc) +{ + CBB cbb; + + if (rl->alert_data != NULL) + return TLS13_IO_FAILURE; + + if (!CBB_init(&cbb, 0)) + goto err; + + if (!CBB_add_u8(&cbb, alert_level)) + goto err; + if (!CBB_add_u8(&cbb, alert_desc)) + goto err; + if (!CBB_finish(&cbb, &rl->alert_data, &rl->alert_len)) + goto err; + + rl->alert_level = alert_level; + rl->alert_desc = alert_desc; + + return tls13_record_layer_send_pending(rl); + + err: + CBB_cleanup(&cbb); + + return TLS13_IO_FAILURE; +} + +ssize_t +tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs) +{ + if (rl->phh_data != NULL) + return TLS13_IO_FAILURE; + + if (!CBS_stow(cbs, &rl->phh_data, &rl->phh_len)) + return TLS13_IO_FAILURE; + + CBS_init(&rl->phh_cbs, rl->phh_data, rl->phh_len); + + return tls13_record_layer_send_pending(rl); +} + +static int +tls13_record_layer_set_traffic_key(const EVP_AEAD *aead, const EVP_MD *hash, + struct tls13_record_protection *rp, struct tls13_secret *traffic_key) +{ + struct tls13_secret context = { .data = "", .len = 0 }; + struct tls13_secret key = { .data = NULL, .len = 0 }; + int ret = 0; + + tls13_record_protection_clear(rp); + + if ((rp->aead_ctx = EVP_AEAD_CTX_new()) == NULL) + return 0; + + if (!tls13_secret_init(&rp->iv, EVP_AEAD_nonce_length(aead))) + goto err; + if (!tls13_secret_init(&rp->nonce, EVP_AEAD_nonce_length(aead))) + goto err; + if (!tls13_secret_init(&key, EVP_AEAD_key_length(aead))) + goto err; + + if (!tls13_hkdf_expand_label(&rp->iv, hash, traffic_key, "iv", &context)) + goto err; + if (!tls13_hkdf_expand_label(&key, hash, traffic_key, "key", &context)) + goto err; + + if (!EVP_AEAD_CTX_init(rp->aead_ctx, aead, key.data, key.len, + EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) + goto err; + + ret = 1; + + err: + tls13_secret_cleanup(&key); + + return ret; +} + +int +tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl, + struct tls13_secret *read_key, enum ssl_encryption_level_t read_level) +{ + if (rl->cb.set_read_traffic_key != NULL) + return rl->cb.set_read_traffic_key(read_key, read_level, + rl->cb_arg); + + return tls13_record_layer_set_traffic_key(rl->aead, rl->hash, + rl->read, read_key); +} + +int +tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, + struct tls13_secret *write_key, enum ssl_encryption_level_t write_level) +{ + if (rl->cb.set_write_traffic_key != NULL) + return rl->cb.set_write_traffic_key(write_key, write_level, + rl->cb_arg); + + return tls13_record_layer_set_traffic_key(rl->aead, rl->hash, + rl->write, write_key); +} + +static int +tls13_record_layer_open_record_plaintext(struct tls13_record_layer *rl) +{ + CBS cbs; + + if (rl->aead != NULL) + return 0; + + /* + * We're still operating in plaintext mode, so just copy the + * content from the record to the plaintext buffer. + */ + if (!tls13_record_content(rl->rrec, &cbs)) + return 0; + + if (CBS_len(&cbs) > TLS13_RECORD_MAX_PLAINTEXT_LEN) { + rl->alert = TLS13_ALERT_RECORD_OVERFLOW; + return 0; + } + + if (!tls_content_dup_data(rl->rcontent, + tls13_record_content_type(rl->rrec), CBS_data(&cbs), CBS_len(&cbs))) + return 0; + + return 1; +} + +static int +tls13_record_layer_open_record_protected(struct tls13_record_layer *rl) +{ + CBS header, enc_record, inner; + uint8_t *content = NULL; + size_t content_len = 0; + uint8_t content_type; + size_t out_len; + + if (rl->aead == NULL) + goto err; + + if (!tls13_record_header(rl->rrec, &header)) + goto err; + if (!tls13_record_content(rl->rrec, &enc_record)) + goto err; + + /* XXX - minus tag len? */ + if ((content = calloc(1, CBS_len(&enc_record))) == NULL) + goto err; + content_len = CBS_len(&enc_record); + + if (!tls13_record_layer_update_nonce(&rl->read->nonce, &rl->read->iv, + rl->read->seq_num)) + goto err; + + if (!EVP_AEAD_CTX_open(rl->read->aead_ctx, + content, &out_len, content_len, + rl->read->nonce.data, rl->read->nonce.len, + CBS_data(&enc_record), CBS_len(&enc_record), + CBS_data(&header), CBS_len(&header))) + goto err; + + if (out_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN) { + rl->alert = TLS13_ALERT_RECORD_OVERFLOW; + goto err; + } + + if (!tls13_record_layer_inc_seq_num(rl->read->seq_num)) + goto err; + + /* + * The real content type is hidden at the end of the record content and + * it may be followed by padding that consists of one or more zeroes. + * Time to hunt for that elusive content type! + */ + CBS_init(&inner, content, out_len); + content_type = 0; + while (CBS_get_last_u8(&inner, &content_type)) { + if (content_type != 0) + break; + } + if (content_type == 0) { + /* Unexpected message per RFC 8446 section 5.4. */ + rl->alert = TLS13_ALERT_UNEXPECTED_MESSAGE; + goto err; + } + if (CBS_len(&inner) > TLS13_RECORD_MAX_PLAINTEXT_LEN) { + rl->alert = TLS13_ALERT_RECORD_OVERFLOW; + goto err; + } + + tls_content_set_data(rl->rcontent, content_type, CBS_data(&inner), + CBS_len(&inner)); + + return 1; + + err: + freezero(content, content_len); + + return 0; +} + +static int +tls13_record_layer_open_record(struct tls13_record_layer *rl) +{ + if (rl->handshake_completed && rl->aead == NULL) + return 0; + + if (rl->aead == NULL) + return tls13_record_layer_open_record_plaintext(rl); + + return tls13_record_layer_open_record_protected(rl); +} + +static int +tls13_record_layer_seal_record_plaintext(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len) +{ + uint8_t *data = NULL; + size_t data_len = 0; + CBB cbb, body; + + /* + * Allow dummy CCS messages to be sent in plaintext even when + * record protection has been engaged, as long as the handshake + * has not yet completed. + */ + if (rl->handshake_completed) + return 0; + if (rl->aead != NULL && content_type != SSL3_RT_CHANGE_CIPHER_SPEC) + return 0; + + /* + * We're still operating in plaintext mode, so just copy the + * content into the record. + */ + if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN + content_len)) + goto err; + + if (!CBB_add_u8(&cbb, content_type)) + goto err; + if (!CBB_add_u16(&cbb, rl->legacy_version)) + goto err; + if (!CBB_add_u16_length_prefixed(&cbb, &body)) + goto err; + if (!CBB_add_bytes(&body, content, content_len)) + goto err; + + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; + + if (!tls13_record_set_data(rl->wrec, data, data_len)) + goto err; + + rl->wrec_content_len = content_len; + rl->wrec_content_type = content_type; + + return 1; + + err: + CBB_cleanup(&cbb); + freezero(data, data_len); + + return 0; +} + +static int +tls13_record_layer_seal_record_protected(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len) +{ + uint8_t *data = NULL, *header = NULL, *inner = NULL; + size_t data_len = 0, header_len = 0, inner_len = 0; + uint8_t *enc_record; + size_t enc_record_len; + ssize_t ret = 0; + size_t out_len; + CBB cbb; + + if (rl->aead == NULL) + return 0; + + memset(&cbb, 0, sizeof(cbb)); + + /* Build inner plaintext. */ + if (!CBB_init(&cbb, content_len + 1)) + goto err; + if (!CBB_add_bytes(&cbb, content, content_len)) + goto err; + if (!CBB_add_u8(&cbb, content_type)) + goto err; + /* XXX - padding? */ + if (!CBB_finish(&cbb, &inner, &inner_len)) + goto err; + + if (inner_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN) + goto err; + + /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ + enc_record_len = inner_len + EVP_AEAD_max_tag_len(rl->aead); + if (enc_record_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN) + goto err; + + /* Build the record header. */ + if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN)) + goto err; + if (!CBB_add_u8(&cbb, SSL3_RT_APPLICATION_DATA)) + goto err; + if (!CBB_add_u16(&cbb, TLS1_2_VERSION)) + goto err; + if (!CBB_add_u16(&cbb, enc_record_len)) + goto err; + if (!CBB_finish(&cbb, &header, &header_len)) + goto err; + + /* Build the actual record. */ + if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN + enc_record_len)) + goto err; + if (!CBB_add_bytes(&cbb, header, header_len)) + goto err; + if (!CBB_add_space(&cbb, &enc_record, enc_record_len)) + goto err; + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; + + if (!tls13_record_layer_update_nonce(&rl->write->nonce, + &rl->write->iv, rl->write->seq_num)) + goto err; + + /* + * XXX - consider a EVP_AEAD_CTX_seal_iov() that takes an iovec... + * this would avoid a copy since the inner would be passed as two + * separate pieces. + */ + if (!EVP_AEAD_CTX_seal(rl->write->aead_ctx, + enc_record, &out_len, enc_record_len, + rl->write->nonce.data, rl->write->nonce.len, + inner, inner_len, header, header_len)) + goto err; + + if (out_len != enc_record_len) + goto err; + + if (!tls13_record_layer_inc_seq_num(rl->write->seq_num)) + goto err; + + if (!tls13_record_set_data(rl->wrec, data, data_len)) + goto err; + + rl->wrec_content_len = content_len; + rl->wrec_content_type = content_type; + + data = NULL; + data_len = 0; + + ret = 1; + + err: + CBB_cleanup(&cbb); + + freezero(data, data_len); + freezero(header, header_len); + freezero(inner, inner_len); + + return ret; +} + +static int +tls13_record_layer_seal_record(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len) +{ + if (rl->handshake_completed && rl->aead == NULL) + return 0; + + tls13_record_layer_wrec_free(rl); + + if ((rl->wrec = tls13_record_new()) == NULL) + return 0; + + if (rl->aead == NULL || content_type == SSL3_RT_CHANGE_CIPHER_SPEC) + return tls13_record_layer_seal_record_plaintext(rl, + content_type, content, content_len); + + return tls13_record_layer_seal_record_protected(rl, content_type, + content, content_len); +} + +static ssize_t +tls13_record_layer_read_record(struct tls13_record_layer *rl) +{ + uint8_t content_type, ccs; + ssize_t ret; + CBS cbs; + + if (rl->rrec == NULL) { + if ((rl->rrec = tls13_record_new()) == NULL) + goto err; + } + + if ((ret = tls13_record_recv(rl->rrec, rl->cb.wire_read, rl->cb_arg)) <= 0) { + switch (ret) { + case TLS13_IO_RECORD_VERSION: + return tls13_send_alert(rl, TLS13_ALERT_PROTOCOL_VERSION); + case TLS13_IO_RECORD_OVERFLOW: + return tls13_send_alert(rl, TLS13_ALERT_RECORD_OVERFLOW); + } + return ret; + } + + content_type = tls13_record_content_type(rl->rrec); + + /* + * In response to a client hello we may receive an alert in a + * record with a legacy version. Otherwise enforce that the + * legacy record version is 0x0303 per RFC 8446, section 5.1. + */ + if (rl->legacy_version == TLS1_2_VERSION && + tls13_record_version(rl->rrec) != TLS1_2_VERSION && + (content_type != SSL3_RT_ALERT || !rl->legacy_alerts_allowed)) + return tls13_send_alert(rl, TLS13_ALERT_PROTOCOL_VERSION); + + /* + * Bag of hacks ahead... after the first ClientHello message has been + * sent or received and before the peer's Finished message has been + * received, we may receive an unencrypted ChangeCipherSpec record + * (see RFC 8446 section 5 and appendix D.4). This record must be + * ignored. + */ + if (content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { + if (!rl->ccs_allowed || rl->ccs_seen >= 2) + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + if (!tls13_record_content(rl->rrec, &cbs)) + return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR); + if (!CBS_get_u8(&cbs, &ccs)) + return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR); + if (ccs != 1) + return tls13_send_alert(rl, TLS13_ALERT_ILLEGAL_PARAMETER); + if (CBS_len(&cbs) != 0) + return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR); + rl->ccs_seen++; + tls13_record_layer_rrec_free(rl); + return TLS13_IO_WANT_RETRY; + } + + /* + * Once record protection is engaged, we should only receive + * protected application data messages (aside from the + * dummy ChangeCipherSpec messages, handled above). + */ + if (rl->aead != NULL && content_type != SSL3_RT_APPLICATION_DATA) + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + + if (!tls13_record_layer_open_record(rl)) + goto err; + + tls13_record_layer_rrec_free(rl); + + /* + * On receiving a handshake or alert record with empty inner plaintext, + * we must terminate the connection with an unexpected_message alert. + * See RFC 8446 section 5.4. + */ + if (tls_content_remaining(rl->rcontent) == 0 && + (tls_content_type(rl->rcontent) == SSL3_RT_ALERT || + tls_content_type(rl->rcontent) == SSL3_RT_HANDSHAKE)) + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + + switch (tls_content_type(rl->rcontent)) { + case SSL3_RT_ALERT: + return tls13_record_layer_process_alert(rl); + + case SSL3_RT_HANDSHAKE: + break; + + case SSL3_RT_APPLICATION_DATA: + if (!rl->handshake_completed) + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + break; + + default: + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + } + + return TLS13_IO_SUCCESS; + + err: + return TLS13_IO_FAILURE; +} + +static ssize_t +tls13_record_layer_pending(struct tls13_record_layer *rl, uint8_t content_type) +{ + if (tls_content_type(rl->rcontent) != content_type) + return 0; + + return tls_content_remaining(rl->rcontent); +} + +static ssize_t +tls13_record_layer_recv_phh(struct tls13_record_layer *rl) +{ + ssize_t ret = TLS13_IO_FAILURE; + + rl->phh = 1; + + /* + * The post handshake handshake receive callback is allowed to return: + * + * TLS13_IO_WANT_POLLIN need more handshake data. + * TLS13_IO_WANT_POLLOUT got whole handshake message, response enqueued. + * TLS13_IO_SUCCESS got the whole handshake, nothing more to do. + * TLS13_IO_FAILURE something broke. + */ + if (rl->cb.phh_recv != NULL) + ret = rl->cb.phh_recv(rl->cb_arg); + + tls_content_clear(rl->rcontent); + + /* Leave post handshake handshake mode unless we need more data. */ + if (ret != TLS13_IO_WANT_POLLIN) + rl->phh = 0; + + if (ret == TLS13_IO_SUCCESS) { + if (rl->phh_retry) + return TLS13_IO_WANT_RETRY; + + return TLS13_IO_WANT_POLLIN; + } + + return ret; +} + +static ssize_t +tls13_record_layer_read_internal(struct tls13_record_layer *rl, + uint8_t content_type, uint8_t *buf, size_t n, int peek) +{ + ssize_t ret; + + if ((ret = tls13_record_layer_send_pending(rl)) != TLS13_IO_SUCCESS) + return ret; + + if (rl->read_closed) + return TLS13_IO_EOF; + + /* If necessary, pull up the next record. */ + if (tls_content_remaining(rl->rcontent) == 0) { + if ((ret = tls13_record_layer_read_record(rl)) <= 0) + return ret; + + /* + * We may have read a valid 0-byte application data record, + * in which case we need to read the next record. + */ + if (tls_content_remaining(rl->rcontent) == 0) + return TLS13_IO_WANT_POLLIN; + } + + /* + * If we are in post handshake handshake mode, we must not see + * any record type that isn't a handshake until we are done. + */ + if (rl->phh && tls_content_type(rl->rcontent) != SSL3_RT_HANDSHAKE) + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + + /* + * Handshake content can appear as post-handshake messages (yup, + * the RFC reused the same content type...), which means we can + * be trying to read application data and need to handle a + * post-handshake handshake message instead... + */ + if (tls_content_type(rl->rcontent) != content_type) { + if (tls_content_type(rl->rcontent) == SSL3_RT_HANDSHAKE) { + if (rl->handshake_completed) + return tls13_record_layer_recv_phh(rl); + } + return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE); + } + + if (peek) + return tls_content_peek(rl->rcontent, buf, n); + + return tls_content_read(rl->rcontent, buf, n); +} + +static ssize_t +tls13_record_layer_peek(struct tls13_record_layer *rl, uint8_t content_type, + uint8_t *buf, size_t n) +{ + ssize_t ret; + + do { + ret = tls13_record_layer_read_internal(rl, content_type, buf, n, 1); + } while (ret == TLS13_IO_WANT_RETRY); + + if (rl->alert != 0) + return tls13_send_alert(rl, rl->alert); + + return ret; +} + +static ssize_t +tls13_record_layer_read(struct tls13_record_layer *rl, uint8_t content_type, + uint8_t *buf, size_t n) +{ + ssize_t ret; + + do { + ret = tls13_record_layer_read_internal(rl, content_type, buf, n, 0); + } while (ret == TLS13_IO_WANT_RETRY); + + if (rl->alert != 0) + return tls13_send_alert(rl, rl->alert); + + return ret; +} + +static ssize_t +tls13_record_layer_write_record(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *content, size_t content_len) +{ + ssize_t ret; + + if (rl->write_closed) + return TLS13_IO_EOF; + + /* + * If we pushed out application data while handling other messages, + * we need to return content length on the next call. + */ + if (content_type == SSL3_RT_APPLICATION_DATA && + rl->wrec_appdata_len != 0) { + ret = rl->wrec_appdata_len; + rl->wrec_appdata_len = 0; + return ret; + } + + /* See if there is an existing record and attempt to push it out... */ + if (rl->wrec != NULL) { + if ((ret = tls13_record_send(rl->wrec, rl->cb.wire_write, + rl->cb_arg)) <= 0) + return ret; + tls13_record_layer_wrec_free(rl); + + if (rl->wrec_content_type == content_type) { + ret = rl->wrec_content_len; + rl->wrec_content_len = 0; + rl->wrec_content_type = 0; + return ret; + } + + /* + * The only partial record type should be application data. + * All other cases are handled to completion. + */ + if (rl->wrec_content_type != SSL3_RT_APPLICATION_DATA) + return TLS13_IO_FAILURE; + rl->wrec_appdata_len = rl->wrec_content_len; + } + + if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN) + goto err; + + if (!tls13_record_layer_seal_record(rl, content_type, content, content_len)) + goto err; + + if ((ret = tls13_record_send(rl->wrec, rl->cb.wire_write, rl->cb_arg)) <= 0) + return ret; + + tls13_record_layer_wrec_free(rl); + + return content_len; + + err: + return TLS13_IO_FAILURE; +} + +static ssize_t +tls13_record_layer_write_chunk(struct tls13_record_layer *rl, + uint8_t content_type, const uint8_t *buf, size_t n) +{ + if (n > TLS13_RECORD_MAX_PLAINTEXT_LEN) + n = TLS13_RECORD_MAX_PLAINTEXT_LEN; + + return tls13_record_layer_write_record(rl, content_type, buf, n); +} + +static ssize_t +tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type, + const uint8_t *buf, size_t n) +{ + ssize_t ret; + + do { + ret = tls13_record_layer_send_pending(rl); + } while (ret == TLS13_IO_WANT_RETRY); + if (ret != TLS13_IO_SUCCESS) + return ret; + + do { + ret = tls13_record_layer_write_chunk(rl, content_type, buf, n); + } while (ret == TLS13_IO_WANT_RETRY); + + return ret; +} + +ssize_t +tls13_record_layer_flush(struct tls13_record_layer *rl) +{ + return rl->cb.wire_flush(rl->cb_arg); +} + +static const uint8_t tls13_dummy_ccs[] = { 0x01 }; + +ssize_t +tls13_send_dummy_ccs(struct tls13_record_layer *rl) +{ + ssize_t ret; + + if (rl->ccs_sent) + return TLS13_IO_FAILURE; + + if ((ret = tls13_record_layer_write(rl, SSL3_RT_CHANGE_CIPHER_SPEC, + tls13_dummy_ccs, sizeof(tls13_dummy_ccs))) <= 0) + return ret; + + rl->ccs_sent = 1; + + return TLS13_IO_SUCCESS; +} + +ssize_t +tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) +{ + if (rl->cb.handshake_read != NULL) + return rl->cb.handshake_read(buf, n, rl->cb_arg); + + return tls13_record_layer_read(rl, SSL3_RT_HANDSHAKE, buf, n); +} + +ssize_t +tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, + size_t n) +{ + if (rl->cb.handshake_write != NULL) + return rl->cb.handshake_write(buf, n, rl->cb_arg); + + return tls13_record_layer_write(rl, SSL3_RT_HANDSHAKE, buf, n); +} + +ssize_t +tls13_pending_application_data(struct tls13_record_layer *rl) +{ + if (!rl->handshake_completed) + return 0; + + return tls13_record_layer_pending(rl, SSL3_RT_APPLICATION_DATA); +} + +ssize_t +tls13_peek_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) +{ + if (!rl->handshake_completed) + return TLS13_IO_FAILURE; + + return tls13_record_layer_peek(rl, SSL3_RT_APPLICATION_DATA, buf, n); +} + +ssize_t +tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) +{ + if (!rl->handshake_completed) + return TLS13_IO_FAILURE; + + return tls13_record_layer_read(rl, SSL3_RT_APPLICATION_DATA, buf, n); +} + +ssize_t +tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf, + size_t n) +{ + if (!rl->handshake_completed) + return TLS13_IO_FAILURE; + + return tls13_record_layer_write(rl, SSL3_RT_APPLICATION_DATA, buf, n); +} + +ssize_t +tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc) +{ + uint8_t alert_level = TLS13_ALERT_LEVEL_FATAL; + ssize_t ret; + + if (rl->cb.alert_send != NULL) + return rl->cb.alert_send(alert_desc, rl->cb_arg); + + if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY || + alert_desc == TLS13_ALERT_USER_CANCELED) + alert_level = TLS13_ALERT_LEVEL_WARNING; + + do { + ret = tls13_record_layer_enqueue_alert(rl, alert_level, + alert_desc); + } while (ret == TLS13_IO_WANT_RETRY); + + return ret; +} diff --git a/Libraries/libressl/ssl/tls13_server.c b/Libraries/libressl/ssl/tls13_server.c new file mode 100644 index 000000000..dfeb1e016 --- /dev/null +++ b/Libraries/libressl/ssl/tls13_server.c @@ -0,0 +1,1095 @@ +/* $OpenBSD: tls13_server.c,v 1.106 2023/06/10 15:34:36 tb Exp $ */ +/* + * Copyright (c) 2019, 2020 Joel Sing + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" +#include "ssl_sigalgs.h" +#include "ssl_tlsext.h" +#include "tls13_handshake.h" +#include "tls13_internal.h" + +int +tls13_server_init(struct tls13_ctx *ctx) +{ + SSL *s = ctx->ssl; + + if (!ssl_supported_tls_version_range(s, &ctx->hs->our_min_tls_version, + &ctx->hs->our_max_tls_version)) { + SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); + return 0; + } + s->version = ctx->hs->our_max_tls_version; + + tls13_record_layer_set_retry_after_phh(ctx->rl, + (s->mode & SSL_MODE_AUTO_RETRY) != 0); + + if (!ssl_get_new_session(s, 0)) /* XXX */ + return 0; + + tls13_record_layer_set_legacy_version(ctx->rl, TLS1_VERSION); + + if (!tls1_transcript_init(s)) + return 0; + + arc4random_buf(s->s3->server_random, SSL3_RANDOM_SIZE); + + return 1; +} + +int +tls13_server_accept(struct tls13_ctx *ctx) +{ + if (ctx->mode != TLS13_HS_SERVER) + return TLS13_IO_FAILURE; + + return tls13_handshake_perform(ctx); +} + +static int +tls13_client_hello_is_legacy(CBS *cbs) +{ + CBS extensions_block, extensions, extension_data, versions; + uint16_t version, max_version = 0; + uint16_t type; + + CBS_dup(cbs, &extensions_block); + + if (!CBS_get_u16_length_prefixed(&extensions_block, &extensions)) + return 1; + + while (CBS_len(&extensions) > 0) { + if (!CBS_get_u16(&extensions, &type)) + return 1; + if (!CBS_get_u16_length_prefixed(&extensions, &extension_data)) + return 1; + + if (type != TLSEXT_TYPE_supported_versions) + continue; + if (!CBS_get_u8_length_prefixed(&extension_data, &versions)) + return 1; + while (CBS_len(&versions) > 0) { + if (!CBS_get_u16(&versions, &version)) + return 1; + if (version >= max_version) + max_version = version; + } + if (CBS_len(&extension_data) != 0) + return 1; + } + + return (max_version < TLS1_3_VERSION); +} + +int +tls13_client_hello_required_extensions(struct tls13_ctx *ctx) +{ + SSL *s = ctx->ssl; + + /* + * RFC 8446, section 9.2. If the ClientHello has supported_versions + * containing TLSv1.3, presence or absence of some extensions requires + * presence or absence of others. + */ + + /* + * RFC 8446 section 4.2.9 - if we received a pre_shared_key, then we + * also need psk_key_exchange_modes. Otherwise, section 9.2 specifies + * that we need both signature_algorithms and supported_groups. + */ + if (tlsext_extension_seen(s, TLSEXT_TYPE_pre_shared_key)) { + if (!tlsext_extension_seen(s, + TLSEXT_TYPE_psk_key_exchange_modes)) + return 0; + } else { + if (!tlsext_extension_seen(s, TLSEXT_TYPE_signature_algorithms)) + return 0; + if (!tlsext_extension_seen(s, TLSEXT_TYPE_supported_groups)) + return 0; + } + + /* + * supported_groups and key_share must either both be present or + * both be absent. + */ + if (tlsext_extension_seen(s, TLSEXT_TYPE_supported_groups) != + tlsext_extension_seen(s, TLSEXT_TYPE_key_share)) + return 0; + + /* + * XXX - Require server_name from client? If so, we SHOULD enforce + * this here - RFC 8446, 9.2. + */ + + return 1; +} + +static const uint8_t tls13_compression_null_only[] = { 0 }; + +static int +tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs) +{ + CBS cipher_suites, client_random, compression_methods, session_id; + STACK_OF(SSL_CIPHER) *ciphers = NULL; + const SSL_CIPHER *cipher; + uint16_t legacy_version; + int alert_desc; + SSL *s = ctx->ssl; + int ret = 0; + + if (!CBS_get_u16(cbs, &legacy_version)) + goto err; + if (!CBS_get_bytes(cbs, &client_random, SSL3_RANDOM_SIZE)) + goto err; + if (!CBS_get_u8_length_prefixed(cbs, &session_id)) + goto err; + if (!CBS_get_u16_length_prefixed(cbs, &cipher_suites)) + goto err; + if (!CBS_get_u8_length_prefixed(cbs, &compression_methods)) + goto err; + + if (tls13_client_hello_is_legacy(cbs) || s->version < TLS1_3_VERSION) { + if (!CBS_skip(cbs, CBS_len(cbs))) + goto err; + return tls13_use_legacy_server(ctx); + } + ctx->hs->negotiated_tls_version = TLS1_3_VERSION; + ctx->hs->peer_legacy_version = legacy_version; + + /* Ensure we send subsequent alerts with the correct record version. */ + tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION); + + /* + * Ensure that the client has not requested middlebox compatibility mode + * if it is prohibited from doing so. + */ + if (!ctx->middlebox_compat && CBS_len(&session_id) != 0) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + + /* Add decoded values to the current ClientHello hash */ + if (!tls13_clienthello_hash_init(ctx)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + if (!tls13_clienthello_hash_update_bytes(ctx, (void *)&legacy_version, + sizeof(legacy_version))) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + if (!tls13_clienthello_hash_update(ctx, &client_random)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + if (!tls13_clienthello_hash_update(ctx, &session_id)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + if (!tls13_clienthello_hash_update(ctx, &cipher_suites)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + if (!tls13_clienthello_hash_update(ctx, &compression_methods)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + + if (!tlsext_server_parse(s, SSL_TLSEXT_MSG_CH, cbs, &alert_desc)) { + ctx->alert = alert_desc; + goto err; + } + + /* Finalize first ClientHello hash, or validate against it */ + if (!ctx->hs->tls13.hrr) { + if (!tls13_clienthello_hash_finalize(ctx)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + } else { + if (!tls13_clienthello_hash_validate(ctx)) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + tls13_clienthello_hash_clear(&ctx->hs->tls13); + } + + if (!tls13_client_hello_required_extensions(ctx)) { + ctx->alert = TLS13_ALERT_MISSING_EXTENSION; + goto err; + } + + /* + * If we got this far we have a supported versions extension that offers + * TLS 1.3 or later. This requires the legacy version be set to 0x0303. + */ + if (legacy_version != TLS1_2_VERSION) { + ctx->alert = TLS13_ALERT_PROTOCOL_VERSION; + goto err; + } + + /* + * The legacy session identifier must either be zero length or a 32 byte + * value (in which case the client is requesting middlebox compatibility + * mode), as per RFC 8446 section 4.1.2. If it is valid, store the value + * so that we can echo it back to the client. + */ + if (CBS_len(&session_id) != 0 && + CBS_len(&session_id) != sizeof(ctx->hs->tls13.legacy_session_id)) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + if (!CBS_write_bytes(&session_id, ctx->hs->tls13.legacy_session_id, + sizeof(ctx->hs->tls13.legacy_session_id), + &ctx->hs->tls13.legacy_session_id_len)) { + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + goto err; + } + + /* Parse cipher suites list and select preferred cipher. */ + if ((ciphers = ssl_bytes_to_cipher_list(s, &cipher_suites)) == NULL) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + cipher = ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s)); + if (cipher == NULL) { + tls13_set_errorx(ctx, TLS13_ERR_NO_SHARED_CIPHER, 0, + "no shared cipher found", NULL); + ctx->alert = TLS13_ALERT_HANDSHAKE_FAILURE; + goto err; + } + ctx->hs->cipher = cipher; + + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = ciphers; + ciphers = NULL; + + /* Ensure only the NULL compression method is advertised. */ + if (!CBS_mem_equal(&compression_methods, tls13_compression_null_only, + sizeof(tls13_compression_null_only))) { + ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; + goto err; + } + + ret = 1; + + err: + sk_SSL_CIPHER_free(ciphers); + + return ret; +} + +int +tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + SSL *s = ctx->ssl; + + if (!tls13_client_hello_process(ctx, cbs)) + goto err; + + /* See if we switched back to the legacy client method. */ + if (s->method->version < TLS1_3_VERSION) + return 1; + + /* + * If a matching key share was provided, we do not need to send a + * HelloRetryRequest. + */ + /* + * XXX - ideally NEGOTIATED would only be added after record protection + * has been enabled. This would probably mean using either an + * INITIAL | WITHOUT_HRR state, or another intermediate state. + */ + if (ctx->hs->key_share != NULL) + ctx->handshake_stage.hs_type |= NEGOTIATED | WITHOUT_HRR; + + tls13_record_layer_allow_ccs(ctx->rl, 1); + + return 1; + + err: + return 0; +} + +static int +tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb, int hrr) +{ + uint16_t tlsext_msg_type = SSL_TLSEXT_MSG_SH; + const uint8_t *server_random; + CBB session_id; + SSL *s = ctx->ssl; + uint16_t cipher; + + cipher = SSL_CIPHER_get_value(ctx->hs->cipher); + server_random = s->s3->server_random; + + if (hrr) { + server_random = tls13_hello_retry_request_hash; + tlsext_msg_type = SSL_TLSEXT_MSG_HRR; + } + + if (!CBB_add_u16(cbb, TLS1_2_VERSION)) + goto err; + if (!CBB_add_bytes(cbb, server_random, SSL3_RANDOM_SIZE)) + goto err; + if (!CBB_add_u8_length_prefixed(cbb, &session_id)) + goto err; + if (!CBB_add_bytes(&session_id, ctx->hs->tls13.legacy_session_id, + ctx->hs->tls13.legacy_session_id_len)) + goto err; + if (!CBB_add_u16(cbb, cipher)) + goto err; + if (!CBB_add_u8(cbb, 0)) + goto err; + if (!tlsext_server_build(s, tlsext_msg_type, cbb)) + goto err; + + if (!CBB_flush(cbb)) + goto err; + + return 1; + err: + return 0; +} + +static int +tls13_server_engage_record_protection(struct tls13_ctx *ctx) +{ + struct tls13_secrets *secrets; + struct tls13_secret context; + unsigned char buf[EVP_MAX_MD_SIZE]; + uint8_t *shared_key = NULL; + size_t shared_key_len = 0; + size_t hash_len; + SSL *s = ctx->ssl; + int ret = 0; + + if (!tls_key_share_derive(ctx->hs->key_share, &shared_key, + &shared_key_len)) + goto err; + + s->session->cipher = ctx->hs->cipher; + + if ((ctx->aead = tls13_cipher_aead(ctx->hs->cipher)) == NULL) + goto err; + if ((ctx->hash = tls13_cipher_hash(ctx->hs->cipher)) == NULL) + goto err; + + if ((secrets = tls13_secrets_create(ctx->hash, 0)) == NULL) + goto err; + ctx->hs->tls13.secrets = secrets; + + /* XXX - pass in hash. */ + if (!tls1_transcript_hash_init(s)) + goto err; + tls1_transcript_free(s); + if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len)) + goto err; + context.data = buf; + context.len = hash_len; + + /* Early secrets. */ + if (!tls13_derive_early_secrets(secrets, secrets->zeros.data, + secrets->zeros.len, &context)) + goto err; + + /* Handshake secrets. */ + if (!tls13_derive_handshake_secrets(ctx->hs->tls13.secrets, shared_key, + shared_key_len, &context)) + goto err; + + tls13_record_layer_set_aead(ctx->rl, ctx->aead); + tls13_record_layer_set_hash(ctx->rl, ctx->hash); + + if (!tls13_record_layer_set_read_traffic_key(ctx->rl, + &secrets->client_handshake_traffic, ssl_encryption_handshake)) + goto err; + if (!tls13_record_layer_set_write_traffic_key(ctx->rl, + &secrets->server_handshake_traffic, ssl_encryption_handshake)) + goto err; + + ctx->handshake_stage.hs_type |= NEGOTIATED; + if (!(SSL_get_verify_mode(s) & SSL_VERIFY_PEER)) + ctx->handshake_stage.hs_type |= WITHOUT_CR; + + ret = 1; + + err: + freezero(shared_key, shared_key_len); + return ret; +} + +int +tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb) +{ + int nid; + + ctx->hs->tls13.hrr = 1; + + if (!tls13_synthetic_handshake_message(ctx)) + return 0; + + if (ctx->hs->key_share != NULL) + return 0; + if (!tls1_get_supported_group(ctx->ssl, &nid)) + return 0; + if (!tls1_ec_nid2group_id(nid, &ctx->hs->tls13.server_group)) + return 0; + + if (!tls13_server_hello_build(ctx, cbb, 1)) + return 0; + + return 1; +} + +int +tls13_server_hello_retry_request_sent(struct tls13_ctx *ctx) +{ + /* + * If the client has requested middlebox compatibility mode, + * we MUST send a dummy CCS following our first handshake message. + * See RFC 8446 Appendix D.4. + */ + if (ctx->hs->tls13.legacy_session_id_len > 0) + ctx->send_dummy_ccs_after = 1; + + return 1; +} + +int +tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + SSL *s = ctx->ssl; + + if (!tls13_client_hello_process(ctx, cbs)) + return 0; + + /* XXX - need further checks. */ + if (s->method->version < TLS1_3_VERSION) + return 0; + + ctx->hs->tls13.hrr = 0; + + return 1; +} + +static int +tls13_servername_process(struct tls13_ctx *ctx) +{ + uint8_t alert = TLS13_ALERT_INTERNAL_ERROR; + + if (!tls13_legacy_servername_process(ctx, &alert)) { + ctx->alert = alert; + return 0; + } + + return 1; +} + +int +tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb) +{ + if (ctx->hs->key_share == NULL) + return 0; + if (!tls_key_share_generate(ctx->hs->key_share)) + return 0; + if (!tls13_servername_process(ctx)) + return 0; + + ctx->hs->tls13.server_group = 0; + + if (!tls13_server_hello_build(ctx, cbb, 0)) + return 0; + + return 1; +} + +int +tls13_server_hello_sent(struct tls13_ctx *ctx) +{ + /* + * If the client has requested middlebox compatibility mode, + * we MUST send a dummy CCS following our first handshake message. + * See RFC 8446 Appendix D.4. + */ + if ((ctx->handshake_stage.hs_type & WITHOUT_HRR) && + ctx->hs->tls13.legacy_session_id_len > 0) + ctx->send_dummy_ccs_after = 1; + + return tls13_server_engage_record_protection(ctx); +} + +int +tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb) +{ + if (!tlsext_server_build(ctx->ssl, SSL_TLSEXT_MSG_EE, cbb)) + goto err; + + return 1; + err: + return 0; +} + +int +tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb) +{ + CBB certificate_request_context; + + if (!CBB_add_u8_length_prefixed(cbb, &certificate_request_context)) + goto err; + if (!tlsext_server_build(ctx->ssl, SSL_TLSEXT_MSG_CR, cbb)) + goto err; + + if (!CBB_flush(cbb)) + goto err; + + return 1; + err: + return 0; +} + +static int +tls13_server_check_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY *cpk, + int *ok, const struct ssl_sigalg **out_sigalg) +{ + const struct ssl_sigalg *sigalg; + SSL *s = ctx->ssl; + + *ok = 0; + *out_sigalg = NULL; + + if (cpk->x509 == NULL || cpk->privatekey == NULL) + goto done; + + /* + * The digitalSignature bit MUST be set if the Key Usage extension is + * present as per RFC 8446 section 4.4.2.2. + */ + if (!(X509_get_key_usage(cpk->x509) & X509v3_KU_DIGITAL_SIGNATURE)) + goto done; + + if ((sigalg = ssl_sigalg_select(s, cpk->privatekey)) == NULL) + goto done; + + *ok = 1; + *out_sigalg = sigalg; + + done: + return 1; +} + +static int +tls13_server_select_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY **out_cpk, + const struct ssl_sigalg **out_sigalg) +{ + SSL *s = ctx->ssl; + const struct ssl_sigalg *sigalg; + SSL_CERT_PKEY *cpk; + int cert_ok; + + *out_cpk = NULL; + *out_sigalg = NULL; + + cpk = &s->cert->pkeys[SSL_PKEY_ECC]; + if (!tls13_server_check_certificate(ctx, cpk, &cert_ok, &sigalg)) + return 0; + if (cert_ok) + goto done; + + cpk = &s->cert->pkeys[SSL_PKEY_RSA]; + if (!tls13_server_check_certificate(ctx, cpk, &cert_ok, &sigalg)) + return 0; + if (cert_ok) + goto done; + + cpk = NULL; + sigalg = NULL; + + done: + *out_cpk = cpk; + *out_sigalg = sigalg; + + return 1; +} + +int +tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb) +{ + SSL *s = ctx->ssl; + CBB cert_request_context, cert_list; + const struct ssl_sigalg *sigalg; + X509_STORE_CTX *xsc = NULL; + STACK_OF(X509) *chain; + SSL_CERT_PKEY *cpk; + X509 *cert; + int i, ret = 0; + + if (!tls13_server_select_certificate(ctx, &cpk, &sigalg)) + goto err; + + if (cpk == NULL) { + /* A server must always provide a certificate. */ + ctx->alert = TLS13_ALERT_HANDSHAKE_FAILURE; + tls13_set_errorx(ctx, TLS13_ERR_NO_CERTIFICATE, 0, + "no server certificate", NULL); + goto err; + } + + ctx->hs->tls13.cpk = cpk; + ctx->hs->our_sigalg = sigalg; + + if ((chain = cpk->chain) == NULL) + chain = s->ctx->extra_certs; + + if (chain == NULL && !(s->mode & SSL_MODE_NO_AUTO_CHAIN)) { + if ((xsc = X509_STORE_CTX_new()) == NULL) + goto err; + if (!X509_STORE_CTX_init(xsc, s->ctx->cert_store, cpk->x509, NULL)) + goto err; + X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(xsc), + X509_V_FLAG_LEGACY_VERIFY); + X509_verify_cert(xsc); + ERR_clear_error(); + chain = X509_STORE_CTX_get0_chain(xsc); + } + + if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context)) + goto err; + if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) + goto err; + + if (!tls13_cert_add(ctx, &cert_list, cpk->x509, tlsext_server_build)) + goto err; + + for (i = 0; i < sk_X509_num(chain); i++) { + cert = sk_X509_value(chain, i); + + /* + * In the case of auto chain, the leaf certificate will be at + * the top of the chain - skip over it as we've already added + * it earlier. + */ + if (i == 0 && cert == cpk->x509) + continue; + + /* + * XXX we don't send extensions with chain certs to avoid sending + * a leaf ocsp staple with the chain certs. This needs to get + * fixed. + */ + if (!tls13_cert_add(ctx, &cert_list, cert, NULL)) + goto err; + } + + if (!CBB_flush(cbb)) + goto err; + + ret = 1; + + err: + X509_STORE_CTX_free(xsc); + + return ret; +} + +int +tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb) +{ + const struct ssl_sigalg *sigalg; + uint8_t *sig = NULL, *sig_content = NULL; + size_t sig_len, sig_content_len; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + const SSL_CERT_PKEY *cpk; + CBB sig_cbb; + int ret = 0; + + memset(&sig_cbb, 0, sizeof(sig_cbb)); + + if ((cpk = ctx->hs->tls13.cpk) == NULL) + goto err; + if ((sigalg = ctx->hs->our_sigalg) == NULL) + goto err; + pkey = cpk->privatekey; + + if (!CBB_init(&sig_cbb, 0)) + goto err; + if (!CBB_add_bytes(&sig_cbb, tls13_cert_verify_pad, + sizeof(tls13_cert_verify_pad))) + goto err; + if (!CBB_add_bytes(&sig_cbb, tls13_cert_server_verify_context, + strlen(tls13_cert_server_verify_context))) + goto err; + if (!CBB_add_u8(&sig_cbb, 0)) + goto err; + if (!CBB_add_bytes(&sig_cbb, ctx->hs->tls13.transcript_hash, + ctx->hs->tls13.transcript_hash_len)) + goto err; + if (!CBB_finish(&sig_cbb, &sig_content, &sig_content_len)) + goto err; + + if ((mdctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_DigestSignInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) + goto err; + if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) + goto err; + if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) + goto err; + } + if (!EVP_DigestSign(mdctx, NULL, &sig_len, sig_content, sig_content_len)) + goto err; + if ((sig = calloc(1, sig_len)) == NULL) + goto err; + if (!EVP_DigestSign(mdctx, sig, &sig_len, sig_content, sig_content_len)) + goto err; + + if (!CBB_add_u16(cbb, sigalg->value)) + goto err; + if (!CBB_add_u16_length_prefixed(cbb, &sig_cbb)) + goto err; + if (!CBB_add_bytes(&sig_cbb, sig, sig_len)) + goto err; + + if (!CBB_flush(cbb)) + goto err; + + ret = 1; + + err: + if (!ret && ctx->alert == 0) + ctx->alert = TLS13_ALERT_INTERNAL_ERROR; + + CBB_cleanup(&sig_cbb); + EVP_MD_CTX_free(mdctx); + free(sig_content); + free(sig); + + return ret; +} + +int +tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret context = { .data = "", .len = 0 }; + struct tls13_secret finished_key = { .data = NULL, .len = 0 } ; + uint8_t transcript_hash[EVP_MAX_MD_SIZE]; + size_t transcript_hash_len; + uint8_t *verify_data; + size_t verify_data_len; + unsigned int hlen; + HMAC_CTX *hmac_ctx = NULL; + CBS cbs; + int ret = 0; + + if (!tls13_secret_init(&finished_key, EVP_MD_size(ctx->hash))) + goto err; + + if (!tls13_hkdf_expand_label(&finished_key, ctx->hash, + &secrets->server_handshake_traffic, "finished", + &context)) + goto err; + + if (!tls1_transcript_hash_value(ctx->ssl, transcript_hash, + sizeof(transcript_hash), &transcript_hash_len)) + goto err; + + if ((hmac_ctx = HMAC_CTX_new()) == NULL) + goto err; + if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len, + ctx->hash, NULL)) + goto err; + if (!HMAC_Update(hmac_ctx, transcript_hash, transcript_hash_len)) + goto err; + + verify_data_len = HMAC_size(hmac_ctx); + if (!CBB_add_space(cbb, &verify_data, verify_data_len)) + goto err; + if (!HMAC_Final(hmac_ctx, verify_data, &hlen)) + goto err; + if (hlen != verify_data_len) + goto err; + + CBS_init(&cbs, verify_data, verify_data_len); + if (!CBS_write_bytes(&cbs, ctx->hs->finished, + sizeof(ctx->hs->finished), &ctx->hs->finished_len)) + goto err; + + ret = 1; + + err: + tls13_secret_cleanup(&finished_key); + HMAC_CTX_free(hmac_ctx); + + return ret; +} + +int +tls13_server_finished_sent(struct tls13_ctx *ctx) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret context = { .data = "", .len = 0 }; + + /* + * Derive application traffic keys. + */ + context.data = ctx->hs->tls13.transcript_hash; + context.len = ctx->hs->tls13.transcript_hash_len; + + if (!tls13_derive_application_secrets(secrets, &context)) + return 0; + + /* + * Any records following the server finished message must be encrypted + * using the server application traffic keys. + */ + return tls13_record_layer_set_write_traffic_key(ctx->rl, + &secrets->server_application_traffic, ssl_encryption_application); +} + +int +tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + CBS cert_request_context, cert_list, cert_data, cert_exts; + struct stack_st_X509 *certs = NULL; + SSL *s = ctx->ssl; + X509 *cert = NULL; + const uint8_t *p; + int ret = 0; + + if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context)) + goto err; + if (CBS_len(&cert_request_context) != 0) + goto err; + if (!CBS_get_u24_length_prefixed(cbs, &cert_list)) + goto err; + if (CBS_len(&cert_list) == 0) { + if (!(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) + return 1; + ctx->alert = TLS13_ALERT_CERTIFICATE_REQUIRED; + tls13_set_errorx(ctx, TLS13_ERR_NO_PEER_CERTIFICATE, 0, + "peer did not provide a certificate", NULL); + goto err; + } + + if ((certs = sk_X509_new_null()) == NULL) + goto err; + while (CBS_len(&cert_list) > 0) { + if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) + goto err; + if (!CBS_get_u16_length_prefixed(&cert_list, &cert_exts)) + goto err; + + p = CBS_data(&cert_data); + if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) + goto err; + if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) + goto err; + + if (!sk_X509_push(certs, cert)) + goto err; + + cert = NULL; + } + + /* + * At this stage we still have no proof of possession. As such, it would + * be preferable to keep the chain and verify once we have successfully + * processed the CertificateVerify message. + */ + if (ssl_verify_cert_chain(s, certs) <= 0) { + ctx->alert = ssl_verify_alarm_type(s->verify_result); + tls13_set_errorx(ctx, TLS13_ERR_VERIFY_FAILED, 0, + "failed to verify peer certificate", NULL); + goto err; + } + s->session->verify_result = s->verify_result; + ERR_clear_error(); + + if (!tls_process_peer_certs(s, certs)) + goto err; + + ctx->handshake_stage.hs_type |= WITH_CCV; + ret = 1; + + err: + sk_X509_pop_free(certs, X509_free); + X509_free(cert); + + return ret; +} + +int +tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + const struct ssl_sigalg *sigalg; + uint16_t signature_scheme; + uint8_t *sig_content = NULL; + size_t sig_content_len; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + X509 *cert; + CBS signature; + CBB cbb; + int ret = 0; + + memset(&cbb, 0, sizeof(cbb)); + + if (!CBS_get_u16(cbs, &signature_scheme)) + goto err; + if (!CBS_get_u16_length_prefixed(cbs, &signature)) + goto err; + + if (!CBB_init(&cbb, 0)) + goto err; + if (!CBB_add_bytes(&cbb, tls13_cert_verify_pad, + sizeof(tls13_cert_verify_pad))) + goto err; + if (!CBB_add_bytes(&cbb, tls13_cert_client_verify_context, + strlen(tls13_cert_client_verify_context))) + goto err; + if (!CBB_add_u8(&cbb, 0)) + goto err; + if (!CBB_add_bytes(&cbb, ctx->hs->tls13.transcript_hash, + ctx->hs->tls13.transcript_hash_len)) + goto err; + if (!CBB_finish(&cbb, &sig_content, &sig_content_len)) + goto err; + + if ((cert = ctx->ssl->session->peer_cert) == NULL) + goto err; + if ((pkey = X509_get0_pubkey(cert)) == NULL) + goto err; + if ((sigalg = ssl_sigalg_for_peer(ctx->ssl, pkey, + signature_scheme)) == NULL) + goto err; + ctx->hs->peer_sigalg = sigalg; + + if (CBS_len(&signature) > EVP_PKEY_size(pkey)) + goto err; + + if ((mdctx = EVP_MD_CTX_new()) == NULL) + goto err; + if (!EVP_DigestVerifyInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) + goto err; + if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) + goto err; + if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) + goto err; + } + if (EVP_DigestVerify(mdctx, CBS_data(&signature), CBS_len(&signature), + sig_content, sig_content_len) <= 0) { + ctx->alert = TLS13_ALERT_DECRYPT_ERROR; + goto err; + } + + ret = 1; + + err: + if (!ret && ctx->alert == 0) + ctx->alert = TLS13_ALERT_DECODE_ERROR; + + CBB_cleanup(&cbb); + EVP_MD_CTX_free(mdctx); + free(sig_content); + + return ret; +} + +int +tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + return 0; +} + +int +tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs) +{ + struct tls13_secrets *secrets = ctx->hs->tls13.secrets; + struct tls13_secret context = { .data = "", .len = 0 }; + struct tls13_secret finished_key; + uint8_t *verify_data = NULL; + size_t verify_data_len; + uint8_t key[EVP_MAX_MD_SIZE]; + HMAC_CTX *hmac_ctx = NULL; + unsigned int hlen; + int ret = 0; + + /* + * Verify client finished. + */ + finished_key.data = key; + finished_key.len = EVP_MD_size(ctx->hash); + + if (!tls13_hkdf_expand_label(&finished_key, ctx->hash, + &secrets->client_handshake_traffic, "finished", + &context)) + goto err; + + if ((hmac_ctx = HMAC_CTX_new()) == NULL) + goto err; + if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len, + ctx->hash, NULL)) + goto err; + if (!HMAC_Update(hmac_ctx, ctx->hs->tls13.transcript_hash, + ctx->hs->tls13.transcript_hash_len)) + goto err; + verify_data_len = HMAC_size(hmac_ctx); + if ((verify_data = calloc(1, verify_data_len)) == NULL) + goto err; + if (!HMAC_Final(hmac_ctx, verify_data, &hlen)) + goto err; + if (hlen != verify_data_len) + goto err; + + if (!CBS_mem_equal(cbs, verify_data, verify_data_len)) { + ctx->alert = TLS13_ALERT_DECRYPT_ERROR; + goto err; + } + + if (!CBS_write_bytes(cbs, ctx->hs->peer_finished, + sizeof(ctx->hs->peer_finished), + &ctx->hs->peer_finished_len)) + goto err; + + if (!CBS_skip(cbs, verify_data_len)) + goto err; + + /* + * Any records following the client finished message must be encrypted + * using the client application traffic keys. + */ + if (!tls13_record_layer_set_read_traffic_key(ctx->rl, + &secrets->client_application_traffic, ssl_encryption_application)) + goto err; + + tls13_record_layer_allow_ccs(ctx->rl, 0); + + ret = 1; + + err: + HMAC_CTX_free(hmac_ctx); + free(verify_data); + + return ret; +} diff --git a/Libraries/libressl/ssl/tls_buffer.c b/Libraries/libressl/ssl/tls_buffer.c new file mode 100644 index 000000000..517d66d68 --- /dev/null +++ b/Libraries/libressl/ssl/tls_buffer.c @@ -0,0 +1,257 @@ +/* $OpenBSD: tls_buffer.c,v 1.4 2022/11/10 18:06:37 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019, 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "bytestring.h" +#include "tls_internal.h" + +#define TLS_BUFFER_CAPACITY_LIMIT (1024 * 1024) + +struct tls_buffer { + size_t capacity; + size_t capacity_limit; + uint8_t *data; + size_t len; + size_t offset; +}; + +static int tls_buffer_resize(struct tls_buffer *buf, size_t capacity); + +struct tls_buffer * +tls_buffer_new(size_t init_size) +{ + struct tls_buffer *buf = NULL; + + if ((buf = calloc(1, sizeof(struct tls_buffer))) == NULL) + goto err; + + buf->capacity_limit = TLS_BUFFER_CAPACITY_LIMIT; + + if (!tls_buffer_resize(buf, init_size)) + goto err; + + return buf; + + err: + tls_buffer_free(buf); + + return NULL; +} + +void +tls_buffer_clear(struct tls_buffer *buf) +{ + freezero(buf->data, buf->capacity); + + buf->data = NULL; + buf->capacity = 0; + buf->len = 0; + buf->offset = 0; +} + +void +tls_buffer_free(struct tls_buffer *buf) +{ + if (buf == NULL) + return; + + tls_buffer_clear(buf); + + freezero(buf, sizeof(struct tls_buffer)); +} + +static int +tls_buffer_grow(struct tls_buffer *buf, size_t capacity) +{ + if (buf->capacity >= capacity) + return 1; + + return tls_buffer_resize(buf, capacity); +} + +static int +tls_buffer_resize(struct tls_buffer *buf, size_t capacity) +{ + uint8_t *data; + + /* + * XXX - Consider maintaining a minimum size and growing more + * intelligently (rather than exactly). + */ + if (buf->capacity == capacity) + return 1; + + if (capacity > buf->capacity_limit) + return 0; + + if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL) + return 0; + + buf->data = data; + buf->capacity = capacity; + + /* Ensure that len and offset are valid if capacity decreased. */ + if (buf->len > buf->capacity) + buf->len = buf->capacity; + if (buf->offset > buf->len) + buf->offset = buf->len; + + return 1; +} + +void +tls_buffer_set_capacity_limit(struct tls_buffer *buf, size_t limit) +{ + /* + * XXX - do we want to force a resize if this limit is less than current + * capacity... and what do we do with existing data? Force a clear? + */ + buf->capacity_limit = limit; +} + +ssize_t +tls_buffer_extend(struct tls_buffer *buf, size_t len, + tls_read_cb read_cb, void *cb_arg) +{ + ssize_t ret; + + if (len == buf->len) + return buf->len; + + if (len < buf->len) + return TLS_IO_FAILURE; + + if (!tls_buffer_resize(buf, len)) + return TLS_IO_FAILURE; + + for (;;) { + if ((ret = read_cb(&buf->data[buf->len], + buf->capacity - buf->len, cb_arg)) <= 0) + return ret; + + if (ret > buf->capacity - buf->len) + return TLS_IO_FAILURE; + + buf->len += ret; + + if (buf->len == buf->capacity) + return buf->len; + } +} + +size_t +tls_buffer_remaining(struct tls_buffer *buf) +{ + if (buf->offset > buf->len) + return 0; + + return buf->len - buf->offset; +} + +ssize_t +tls_buffer_read(struct tls_buffer *buf, uint8_t *rbuf, size_t n) +{ + if (buf->offset > buf->len) + return TLS_IO_FAILURE; + + if (buf->offset == buf->len) + return TLS_IO_WANT_POLLIN; + + if (n > buf->len - buf->offset) + n = buf->len - buf->offset; + + memcpy(rbuf, &buf->data[buf->offset], n); + + buf->offset += n; + + return n; +} + +ssize_t +tls_buffer_write(struct tls_buffer *buf, const uint8_t *wbuf, size_t n) +{ + if (buf->offset > buf->len) + return TLS_IO_FAILURE; + + /* + * To avoid continually growing the buffer, pull data up to the + * start of the buffer. If all data has been read then we can simply + * reset, otherwise wait until we're going to save at least 4KB of + * memory to reduce overhead. + */ + if (buf->offset == buf->len) { + buf->len = 0; + buf->offset = 0; + } + if (buf->offset >= 4096) { + memmove(buf->data, &buf->data[buf->offset], + buf->len - buf->offset); + buf->len -= buf->offset; + buf->offset = 0; + } + + if (buf->len > SIZE_MAX - n) + return TLS_IO_FAILURE; + if (!tls_buffer_grow(buf, buf->len + n)) + return TLS_IO_FAILURE; + + memcpy(&buf->data[buf->len], wbuf, n); + + buf->len += n; + + return n; +} + +int +tls_buffer_append(struct tls_buffer *buf, const uint8_t *wbuf, size_t n) +{ + return tls_buffer_write(buf, wbuf, n) == n; +} + +int +tls_buffer_data(struct tls_buffer *buf, CBS *out_cbs) +{ + CBS cbs; + + CBS_init(&cbs, buf->data, buf->len); + + if (!CBS_skip(&cbs, buf->offset)) + return 0; + + CBS_dup(&cbs, out_cbs); + + return 1; +} + +int +tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len) +{ + if (out == NULL || out_len == NULL) + return 0; + + *out = buf->data; + *out_len = buf->len; + + buf->data = NULL; + buf->capacity = 0; + buf->len = 0; + buf->offset = 0; + + return 1; +} diff --git a/Libraries/libressl/ssl/tls_content.c b/Libraries/libressl/ssl/tls_content.c new file mode 100644 index 000000000..726de0fdc --- /dev/null +++ b/Libraries/libressl/ssl/tls_content.c @@ -0,0 +1,164 @@ +/* $OpenBSD: tls_content.c,v 1.2 2022/11/11 17:15:27 jsing Exp $ */ +/* + * Copyright (c) 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "tls_content.h" + +/* Content from a TLS record. */ +struct tls_content { + uint8_t type; + uint16_t epoch; + + const uint8_t *data; + size_t data_len; + CBS cbs; +}; + +struct tls_content * +tls_content_new(void) +{ + return calloc(1, sizeof(struct tls_content)); +} + +void +tls_content_clear(struct tls_content *content) +{ + freezero((void *)content->data, content->data_len); + memset(content, 0, sizeof(*content)); +} + +void +tls_content_free(struct tls_content *content) +{ + if (content == NULL) + return; + + tls_content_clear(content); + + freezero(content, sizeof(struct tls_content)); +} + +CBS * +tls_content_cbs(struct tls_content *content) +{ + return &content->cbs; +} + +int +tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n) +{ + return CBS_mem_equal(&content->cbs, buf, n); +} + +size_t +tls_content_remaining(struct tls_content *content) +{ + return CBS_len(&content->cbs); +} + +uint8_t +tls_content_type(struct tls_content *content) +{ + return content->type; +} + +int +tls_content_dup_data(struct tls_content *content, uint8_t type, + const uint8_t *data, size_t data_len) +{ + uint8_t *dup; + + if ((dup = calloc(1, data_len)) == NULL) + return 0; + memcpy(dup, data, data_len); + + tls_content_set_data(content, type, dup, data_len); + + return 1; +} + +uint16_t +tls_content_epoch(struct tls_content *content) +{ + return content->epoch; +} + +void +tls_content_set_epoch(struct tls_content *content, uint16_t epoch) +{ + content->epoch = epoch; +} + +void +tls_content_set_data(struct tls_content *content, uint8_t type, + const uint8_t *data, size_t data_len) +{ + tls_content_clear(content); + + content->type = type; + content->data = data; + content->data_len = data_len; + + CBS_init(&content->cbs, content->data, content->data_len); +} + +int +tls_content_set_bounds(struct tls_content *content, size_t offset, size_t len) +{ + size_t content_len; + + content_len = offset + len; + if (content_len < len) + return 0; + if (content_len > content->data_len) + return 0; + + CBS_init(&content->cbs, content->data, content_len); + return CBS_skip(&content->cbs, offset); +} + +static ssize_t +tls_content_read_internal(struct tls_content *content, uint8_t *buf, size_t n, + int peek) +{ + if (n > CBS_len(&content->cbs)) + n = CBS_len(&content->cbs); + + /* XXX - CBS_memcpy? CBS_copy_bytes? */ + memcpy(buf, CBS_data(&content->cbs), n); + + if (!peek) { + if (!CBS_skip(&content->cbs, n)) + return -1; + } + + return n; +} + +ssize_t +tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n) +{ + return tls_content_read_internal(content, buf, n, 1); +} + +ssize_t +tls_content_read(struct tls_content *content, uint8_t *buf, size_t n) +{ + return tls_content_read_internal(content, buf, n, 0); +} diff --git a/Libraries/libressl/ssl/tls_content.h b/Libraries/libressl/ssl/tls_content.h new file mode 100644 index 000000000..b807248f6 --- /dev/null +++ b/Libraries/libressl/ssl/tls_content.h @@ -0,0 +1,50 @@ +/* $OpenBSD: tls_content.h,v 1.2 2022/11/11 17:15:27 jsing Exp $ */ +/* + * Copyright (c) 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS_CONTENT_H +#define HEADER_TLS_CONTENT_H + +#include "bytestring.h" + +__BEGIN_HIDDEN_DECLS + +struct tls_content; + +struct tls_content *tls_content_new(void); +void tls_content_clear(struct tls_content *content); +void tls_content_free(struct tls_content *content); + +CBS *tls_content_cbs(struct tls_content *content); +int tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n); +size_t tls_content_remaining(struct tls_content *content); +uint8_t tls_content_type(struct tls_content *content); +uint16_t tls_content_epoch(struct tls_content *content); + +int tls_content_dup_data(struct tls_content *content, uint8_t type, + const uint8_t *data, size_t data_len); +void tls_content_set_data(struct tls_content *content, uint8_t type, + const uint8_t *data, size_t data_len); +int tls_content_set_bounds(struct tls_content *content, size_t offset, + size_t len); +void tls_content_set_epoch(struct tls_content *content, uint16_t epoch); + +ssize_t tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n); +ssize_t tls_content_read(struct tls_content *content, uint8_t *buf, size_t n); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/tls_internal.h b/Libraries/libressl/ssl/tls_internal.h new file mode 100644 index 000000000..84edde847 --- /dev/null +++ b/Libraries/libressl/ssl/tls_internal.h @@ -0,0 +1,101 @@ +/* $OpenBSD: tls_internal.h,v 1.10 2022/11/10 18:06:37 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS_INTERNAL_H +#define HEADER_TLS_INTERNAL_H + +#include +#include + +#include "bytestring.h" + +__BEGIN_HIDDEN_DECLS + +#define TLS_IO_SUCCESS 1 +#define TLS_IO_EOF 0 +#define TLS_IO_FAILURE -1 +#define TLS_IO_ALERT -2 +#define TLS_IO_WANT_POLLIN -3 +#define TLS_IO_WANT_POLLOUT -4 +#define TLS_IO_WANT_RETRY -5 /* Retry the previous call immediately. */ + +enum ssl_encryption_level_t; + +struct tls13_secret; + +/* + * Callbacks. + */ +typedef ssize_t (*tls_read_cb)(void *_buf, size_t _buflen, void *_cb_arg); +typedef ssize_t (*tls_write_cb)(const void *_buf, size_t _buflen, + void *_cb_arg); +typedef ssize_t (*tls_flush_cb)(void *_cb_arg); + +typedef ssize_t (*tls_handshake_read_cb)(void *_buf, size_t _buflen, + void *_cb_arg); +typedef ssize_t (*tls_handshake_write_cb)(const void *_buf, size_t _buflen, + void *_cb_arg); +typedef int (*tls_traffic_key_cb)(struct tls13_secret *key, + enum ssl_encryption_level_t level, void *_cb_arg); +typedef int (*tls_alert_send_cb)(int _alert_desc, void *_cb_arg); + +/* + * Buffers. + */ +struct tls_buffer; + +struct tls_buffer *tls_buffer_new(size_t init_size); +void tls_buffer_clear(struct tls_buffer *buf); +void tls_buffer_free(struct tls_buffer *buf); +void tls_buffer_set_capacity_limit(struct tls_buffer *buf, size_t limit); +ssize_t tls_buffer_extend(struct tls_buffer *buf, size_t len, + tls_read_cb read_cb, void *cb_arg); +size_t tls_buffer_remaining(struct tls_buffer *buf); +ssize_t tls_buffer_read(struct tls_buffer *buf, uint8_t *rbuf, size_t n); +ssize_t tls_buffer_write(struct tls_buffer *buf, const uint8_t *wbuf, size_t n); +int tls_buffer_append(struct tls_buffer *buf, const uint8_t *wbuf, size_t n); +int tls_buffer_data(struct tls_buffer *buf, CBS *cbs); +int tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len); + +/* + * Key shares. + */ +struct tls_key_share; + +struct tls_key_share *tls_key_share_new(uint16_t group_id); +struct tls_key_share *tls_key_share_new_nid(int nid); +void tls_key_share_free(struct tls_key_share *ks); + +uint16_t tls_key_share_group(struct tls_key_share *ks); +int tls_key_share_nid(struct tls_key_share *ks); +void tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits); +int tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params); +int tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey); +int tls_key_share_generate(struct tls_key_share *ks); +int tls_key_share_params(struct tls_key_share *ks, CBB *cbb); +int tls_key_share_public(struct tls_key_share *ks, CBB *cbb); +int tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs, + int *decode_error, int *invalid_params); +int tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs, + int *decode_error, int *invalid_key); +int tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key, + size_t *shared_key_len); +int tls_key_share_peer_security(const SSL *ssl, struct tls_key_share *ks); + +__END_HIDDEN_DECLS + +#endif diff --git a/Libraries/libressl/ssl/tls_key_share.c b/Libraries/libressl/ssl/tls_key_share.c new file mode 100644 index 000000000..cf7b1da26 --- /dev/null +++ b/Libraries/libressl/ssl/tls_key_share.c @@ -0,0 +1,484 @@ +/* $OpenBSD: tls_key_share.c,v 1.8 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2020, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include + +#include "bytestring.h" +#include "ssl_local.h" +#include "tls_internal.h" + +struct tls_key_share { + int nid; + uint16_t group_id; + size_t key_bits; + + DH *dhe; + DH *dhe_peer; + + EC_KEY *ecdhe; + EC_KEY *ecdhe_peer; + + uint8_t *x25519_public; + uint8_t *x25519_private; + uint8_t *x25519_peer_public; +}; + +static struct tls_key_share * +tls_key_share_new_internal(int nid, uint16_t group_id) +{ + struct tls_key_share *ks; + + if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL) + return NULL; + + ks->group_id = group_id; + ks->nid = nid; + + return ks; +} + +struct tls_key_share * +tls_key_share_new(uint16_t group_id) +{ + int nid; + + if (!tls1_ec_group_id2nid(group_id, &nid)) + return NULL; + + return tls_key_share_new_internal(nid, group_id); +} + +struct tls_key_share * +tls_key_share_new_nid(int nid) +{ + uint16_t group_id = 0; + + if (nid != NID_dhKeyAgreement) { + if (!tls1_ec_nid2group_id(nid, &group_id)) + return NULL; + } + + return tls_key_share_new_internal(nid, group_id); +} + +void +tls_key_share_free(struct tls_key_share *ks) +{ + if (ks == NULL) + return; + + DH_free(ks->dhe); + DH_free(ks->dhe_peer); + + EC_KEY_free(ks->ecdhe); + EC_KEY_free(ks->ecdhe_peer); + + freezero(ks->x25519_public, X25519_KEY_LENGTH); + freezero(ks->x25519_private, X25519_KEY_LENGTH); + freezero(ks->x25519_peer_public, X25519_KEY_LENGTH); + + freezero(ks, sizeof(*ks)); +} + +uint16_t +tls_key_share_group(struct tls_key_share *ks) +{ + return ks->group_id; +} + +int +tls_key_share_nid(struct tls_key_share *ks) +{ + return ks->nid; +} + +void +tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits) +{ + ks->key_bits = key_bits; +} + +int +tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params) +{ + if (ks->nid != NID_dhKeyAgreement) + return 0; + if (ks->dhe != NULL || ks->dhe_peer != NULL) + return 0; + + if ((ks->dhe = DHparams_dup(dh_params)) == NULL) + return 0; + if ((ks->dhe_peer = DHparams_dup(dh_params)) == NULL) + return 0; + + return 1; +} + +int +tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey) +{ + if (ks->nid == NID_dhKeyAgreement && ks->dhe_peer != NULL) + return EVP_PKEY_set1_DH(pkey, ks->dhe_peer); + + if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) + return ssl_kex_dummy_ecdhe_x25519(pkey); + + if (ks->ecdhe_peer != NULL) + return EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer); + + return 0; +} + +static int +tls_key_share_generate_dhe(struct tls_key_share *ks) +{ + /* + * If auto params are not being used then we must already have DH + * parameters set. + */ + if (ks->key_bits == 0) { + if (ks->dhe == NULL) + return 0; + + return ssl_kex_generate_dhe(ks->dhe, ks->dhe); + } + + if (ks->dhe != NULL || ks->dhe_peer != NULL) + return 0; + + if ((ks->dhe = DH_new()) == NULL) + return 0; + if (!ssl_kex_generate_dhe_params_auto(ks->dhe, ks->key_bits)) + return 0; + if ((ks->dhe_peer = DHparams_dup(ks->dhe)) == NULL) + return 0; + + return 1; +} + +static int +tls_key_share_generate_ecdhe_ecp(struct tls_key_share *ks) +{ + EC_KEY *ecdhe = NULL; + int ret = 0; + + if (ks->ecdhe != NULL) + goto err; + + if ((ecdhe = EC_KEY_new()) == NULL) + goto err; + if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid)) + goto err; + + ks->ecdhe = ecdhe; + ecdhe = NULL; + + ret = 1; + + err: + EC_KEY_free(ecdhe); + + return ret; +} + +static int +tls_key_share_generate_x25519(struct tls_key_share *ks) +{ + uint8_t *public = NULL, *private = NULL; + int ret = 0; + + if (ks->x25519_public != NULL || ks->x25519_private != NULL) + goto err; + + if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL) + goto err; + if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL) + goto err; + + X25519_keypair(public, private); + + ks->x25519_public = public; + ks->x25519_private = private; + public = NULL; + private = NULL; + + ret = 1; + + err: + freezero(public, X25519_KEY_LENGTH); + freezero(private, X25519_KEY_LENGTH); + + return ret; +} + +int +tls_key_share_generate(struct tls_key_share *ks) +{ + if (ks->nid == NID_dhKeyAgreement) + return tls_key_share_generate_dhe(ks); + + if (ks->nid == NID_X25519) + return tls_key_share_generate_x25519(ks); + + return tls_key_share_generate_ecdhe_ecp(ks); +} + +static int +tls_key_share_params_dhe(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->dhe == NULL) + return 0; + + return ssl_kex_params_dhe(ks->dhe, cbb); +} + +int +tls_key_share_params(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->nid == NID_dhKeyAgreement) + return tls_key_share_params_dhe(ks, cbb); + + return 0; +} + +static int +tls_key_share_public_dhe(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->dhe == NULL) + return 0; + + return ssl_kex_public_dhe(ks->dhe, cbb); +} + +static int +tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->ecdhe == NULL) + return 0; + + return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb); +} + +static int +tls_key_share_public_x25519(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->x25519_public == NULL) + return 0; + + return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH); +} + +int +tls_key_share_public(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->nid == NID_dhKeyAgreement) + return tls_key_share_public_dhe(ks, cbb); + + if (ks->nid == NID_X25519) + return tls_key_share_public_x25519(ks, cbb); + + return tls_key_share_public_ecdhe_ecp(ks, cbb); +} + +static int +tls_key_share_peer_params_dhe(struct tls_key_share *ks, CBS *cbs, + int *decode_error, int *invalid_params) +{ + if (ks->dhe != NULL || ks->dhe_peer != NULL) + return 0; + + if ((ks->dhe_peer = DH_new()) == NULL) + return 0; + if (!ssl_kex_peer_params_dhe(ks->dhe_peer, cbs, decode_error, + invalid_params)) + return 0; + if ((ks->dhe = DHparams_dup(ks->dhe_peer)) == NULL) + return 0; + + return 1; +} + +int +tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs, + int *decode_error, int *invalid_params) +{ + if (ks->nid != NID_dhKeyAgreement) + return 0; + + return tls_key_share_peer_params_dhe(ks, cbs, decode_error, + invalid_params); +} + +static int +tls_key_share_peer_public_dhe(struct tls_key_share *ks, CBS *cbs, + int *decode_error, int *invalid_key) +{ + if (ks->dhe_peer == NULL) + return 0; + + return ssl_kex_peer_public_dhe(ks->dhe_peer, cbs, decode_error, + invalid_key); +} + +static int +tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share *ks, CBS *cbs) +{ + EC_KEY *ecdhe = NULL; + int ret = 0; + + if (ks->ecdhe_peer != NULL) + goto err; + + if ((ecdhe = EC_KEY_new()) == NULL) + goto err; + if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs)) + goto err; + + ks->ecdhe_peer = ecdhe; + ecdhe = NULL; + + ret = 1; + + err: + EC_KEY_free(ecdhe); + + return ret; +} + +static int +tls_key_share_peer_public_x25519(struct tls_key_share *ks, CBS *cbs, + int *decode_error) +{ + size_t out_len; + + *decode_error = 0; + + if (ks->x25519_peer_public != NULL) + return 0; + + if (CBS_len(cbs) != X25519_KEY_LENGTH) { + *decode_error = 1; + return 0; + } + + return CBS_stow(cbs, &ks->x25519_peer_public, &out_len); +} + +int +tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs, int *decode_error, + int *invalid_key) +{ + *decode_error = 0; + + if (invalid_key != NULL) + *invalid_key = 0; + + if (ks->nid == NID_dhKeyAgreement) + return tls_key_share_peer_public_dhe(ks, cbs, decode_error, + invalid_key); + + if (ks->nid == NID_X25519) + return tls_key_share_peer_public_x25519(ks, cbs, decode_error); + + return tls_key_share_peer_public_ecdhe_ecp(ks, cbs); +} + +static int +tls_key_share_derive_dhe(struct tls_key_share *ks, + uint8_t **shared_key, size_t *shared_key_len) +{ + if (ks->dhe == NULL || ks->dhe_peer == NULL) + return 0; + + return ssl_kex_derive_dhe(ks->dhe, ks->dhe_peer, shared_key, + shared_key_len); +} + +static int +tls_key_share_derive_ecdhe_ecp(struct tls_key_share *ks, + uint8_t **shared_key, size_t *shared_key_len) +{ + if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL) + return 0; + + return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer, + shared_key, shared_key_len); +} + +static int +tls_key_share_derive_x25519(struct tls_key_share *ks, + uint8_t **shared_key, size_t *shared_key_len) +{ + uint8_t *sk = NULL; + int ret = 0; + + if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL) + goto err; + + if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL) + goto err; + if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public)) + goto err; + + *shared_key = sk; + *shared_key_len = X25519_KEY_LENGTH; + sk = NULL; + + ret = 1; + + err: + freezero(sk, X25519_KEY_LENGTH); + + return ret; +} + +int +tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key, + size_t *shared_key_len) +{ + if (*shared_key != NULL) + return 0; + + *shared_key_len = 0; + + if (ks->nid == NID_dhKeyAgreement) + return tls_key_share_derive_dhe(ks, shared_key, + shared_key_len); + + if (ks->nid == NID_X25519) + return tls_key_share_derive_x25519(ks, shared_key, + shared_key_len); + + return tls_key_share_derive_ecdhe_ecp(ks, shared_key, + shared_key_len); +} + +int +tls_key_share_peer_security(const SSL *ssl, struct tls_key_share *ks) +{ + switch (ks->nid) { + case NID_dhKeyAgreement: + return ssl_security_dh(ssl, ks->dhe_peer); + default: + return 0; + } +} diff --git a/Libraries/libressl/ssl/tls_lib.c b/Libraries/libressl/ssl/tls_lib.c new file mode 100644 index 000000000..db734c34e --- /dev/null +++ b/Libraries/libressl/ssl/tls_lib.c @@ -0,0 +1,68 @@ +/* $OpenBSD: tls_lib.c,v 1.3 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2019, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ssl_local.h" + +int +tls_process_peer_certs(SSL *s, STACK_OF(X509) *peer_certs) +{ + STACK_OF(X509) *peer_certs_no_leaf; + X509 *peer_cert = NULL; + EVP_PKEY *pkey; + int cert_type; + int ret = 0; + + if (sk_X509_num(peer_certs) < 1) + goto err; + peer_cert = sk_X509_value(peer_certs, 0); + X509_up_ref(peer_cert); + + if ((pkey = X509_get0_pubkey(peer_cert)) == NULL) { + SSLerror(s, SSL_R_NO_PUBLICKEY); + goto err; + } + if (EVP_PKEY_missing_parameters(pkey)) { + SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); + goto err; + } + if ((cert_type = ssl_cert_type(pkey)) < 0) { + SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto err; + } + + s->session->peer_cert_type = cert_type; + + X509_free(s->session->peer_cert); + s->session->peer_cert = peer_cert; + peer_cert = NULL; + + sk_X509_pop_free(s->s3->hs.peer_certs, X509_free); + if ((s->s3->hs.peer_certs = X509_chain_up_ref(peer_certs)) == NULL) + goto err; + + if ((peer_certs_no_leaf = X509_chain_up_ref(peer_certs)) == NULL) + goto err; + X509_free(sk_X509_shift(peer_certs_no_leaf)); + sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); + s->s3->hs.peer_certs_no_leaf = peer_certs_no_leaf; + + ret = 1; + err: + X509_free(peer_cert); + + return ret; +} diff --git a/Libraries/libressl/tap-driver.sh b/Libraries/libressl/tap-driver.sh new file mode 100644 index 000000000..fea066f56 --- /dev/null +++ b/Libraries/libressl/tap-driver.sh @@ -0,0 +1,651 @@ +#! /bin/sh +# Copyright (C) 2011-2021 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +scriptversion=2013-12-23.17; # UTC + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +me=tap-driver.sh + +fatal () +{ + echo "$me: fatal: $*" >&2 + exit 1 +} + +usage_error () +{ + echo "$me: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat < + # + trap : 1 3 2 13 15 + if test $merge -gt 0; then + exec 2>&1 + else + exec 2>&3 + fi + "$@" + echo $? + ) | LC_ALL=C ${AM_TAP_AWK-awk} \ + -v me="$me" \ + -v test_script_name="$test_name" \ + -v log_file="$log_file" \ + -v trs_file="$trs_file" \ + -v expect_failure="$expect_failure" \ + -v merge="$merge" \ + -v ignore_exit="$ignore_exit" \ + -v comments="$comments" \ + -v diag_string="$diag_string" \ +' +# TODO: the usages of "cat >&3" below could be optimized when using +# GNU awk, and/on on systems that supports /dev/fd/. + +# Implementation note: in what follows, `result_obj` will be an +# associative array that (partly) simulates a TAP result object +# from the `TAP::Parser` perl module. + +## ----------- ## +## FUNCTIONS ## +## ----------- ## + +function fatal(msg) +{ + print me ": " msg | "cat >&2" + exit 1 +} + +function abort(where) +{ + fatal("internal error " where) +} + +# Convert a boolean to a "yes"/"no" string. +function yn(bool) +{ + return bool ? "yes" : "no"; +} + +function add_test_result(result) +{ + if (!test_results_index) + test_results_index = 0 + test_results_list[test_results_index] = result + test_results_index += 1 + test_results_seen[result] = 1; +} + +# Whether the test script should be re-run by "make recheck". +function must_recheck() +{ + for (k in test_results_seen) + if (k != "XFAIL" && k != "PASS" && k != "SKIP") + return 1 + return 0 +} + +# Whether the content of the log file associated to this test should +# be copied into the "global" test-suite.log. +function copy_in_global_log() +{ + for (k in test_results_seen) + if (k != "PASS") + return 1 + return 0 +} + +function get_global_test_result() +{ + if ("ERROR" in test_results_seen) + return "ERROR" + if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) + return "FAIL" + all_skipped = 1 + for (k in test_results_seen) + if (k != "SKIP") + all_skipped = 0 + if (all_skipped) + return "SKIP" + return "PASS"; +} + +function stringify_result_obj(result_obj) +{ + if (result_obj["is_unplanned"] || result_obj["number"] != testno) + return "ERROR" + + if (plan_seen == LATE_PLAN) + return "ERROR" + + if (result_obj["directive"] == "TODO") + return result_obj["is_ok"] ? "XPASS" : "XFAIL" + + if (result_obj["directive"] == "SKIP") + return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; + + if (length(result_obj["directive"])) + abort("in function stringify_result_obj()") + + return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL +} + +function decorate_result(result) +{ + color_name = color_for_result[result] + if (color_name) + return color_map[color_name] "" result "" color_map["std"] + # If we are not using colorized output, or if we do not know how + # to colorize the given result, we should return it unchanged. + return result +} + +function report(result, details) +{ + if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) + { + msg = ": " test_script_name + add_test_result(result) + } + else if (result == "#") + { + msg = " " test_script_name ":" + } + else + { + abort("in function report()") + } + if (length(details)) + msg = msg " " details + # Output on console might be colorized. + print decorate_result(result) msg + # Log the result in the log file too, to help debugging (this is + # especially true when said result is a TAP error or "Bail out!"). + print result msg | "cat >&3"; +} + +function testsuite_error(error_message) +{ + report("ERROR", "- " error_message) +} + +function handle_tap_result() +{ + details = result_obj["number"]; + if (length(result_obj["description"])) + details = details " " result_obj["description"] + + if (plan_seen == LATE_PLAN) + { + details = details " # AFTER LATE PLAN"; + } + else if (result_obj["is_unplanned"]) + { + details = details " # UNPLANNED"; + } + else if (result_obj["number"] != testno) + { + details = sprintf("%s # OUT-OF-ORDER (expecting %d)", + details, testno); + } + else if (result_obj["directive"]) + { + details = details " # " result_obj["directive"]; + if (length(result_obj["explanation"])) + details = details " " result_obj["explanation"] + } + + report(stringify_result_obj(result_obj), details) +} + +# `skip_reason` should be empty whenever planned > 0. +function handle_tap_plan(planned, skip_reason) +{ + planned += 0 # Avoid getting confused if, say, `planned` is "00" + if (length(skip_reason) && planned > 0) + abort("in function handle_tap_plan()") + if (plan_seen) + { + # Error, only one plan per stream is acceptable. + testsuite_error("multiple test plans") + return; + } + planned_tests = planned + # The TAP plan can come before or after *all* the TAP results; we speak + # respectively of an "early" or a "late" plan. If we see the plan line + # after at least one TAP result has been seen, assume we have a late + # plan; in this case, any further test result seen after the plan will + # be flagged as an error. + plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) + # If testno > 0, we have an error ("too many tests run") that will be + # automatically dealt with later, so do not worry about it here. If + # $plan_seen is true, we have an error due to a repeated plan, and that + # has already been dealt with above. Otherwise, we have a valid "plan + # with SKIP" specification, and should report it as a particular kind + # of SKIP result. + if (planned == 0 && testno == 0) + { + if (length(skip_reason)) + skip_reason = "- " skip_reason; + report("SKIP", skip_reason); + } +} + +function extract_tap_comment(line) +{ + if (index(line, diag_string) == 1) + { + # Strip leading `diag_string` from `line`. + line = substr(line, length(diag_string) + 1) + # And strip any leading and trailing whitespace left. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + # Return what is left (if any). + return line; + } + return ""; +} + +# When this function is called, we know that line is a TAP result line, +# so that it matches the (perl) RE "^(not )?ok\b". +function setup_result_obj(line) +{ + # Get the result, and remove it from the line. + result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) + sub("^(not )?ok[ \t]*", "", line) + + # If the result has an explicit number, get it and strip it; otherwise, + # automatically assign the next test number to it. + if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) + { + match(line, "^[0-9]+") + # The final `+ 0` is to normalize numbers with leading zeros. + result_obj["number"] = substr(line, 1, RLENGTH) + 0 + line = substr(line, RLENGTH + 1) + } + else + { + result_obj["number"] = testno + } + + if (plan_seen == LATE_PLAN) + # No further test results are acceptable after a "late" TAP plan + # has been seen. + result_obj["is_unplanned"] = 1 + else if (plan_seen && testno > planned_tests) + result_obj["is_unplanned"] = 1 + else + result_obj["is_unplanned"] = 0 + + # Strip trailing and leading whitespace. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + + # This will have to be corrected if we have a "TODO"/"SKIP" directive. + result_obj["description"] = line + result_obj["directive"] = "" + result_obj["explanation"] = "" + + if (index(line, "#") == 0) + return # No possible directive, nothing more to do. + + # Directives are case-insensitive. + rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" + + # See whether we have the directive, and if yes, where. + pos = match(line, rx "$") + if (!pos) + pos = match(line, rx "[^a-zA-Z0-9_]") + + # If there was no TAP directive, we have nothing more to do. + if (!pos) + return + + # Let`s now see if the TAP directive has been escaped. For example: + # escaped: ok \# SKIP + # not escaped: ok \\# SKIP + # escaped: ok \\\\\# SKIP + # not escaped: ok \ # SKIP + if (substr(line, pos, 1) == "#") + { + bslash_count = 0 + for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) + bslash_count += 1 + if (bslash_count % 2) + return # Directive was escaped. + } + + # Strip the directive and its explanation (if any) from the test + # description. + result_obj["description"] = substr(line, 1, pos - 1) + # Now remove the test description from the line, that has been dealt + # with already. + line = substr(line, pos) + # Strip the directive, and save its value (normalized to upper case). + sub("^[ \t]*#[ \t]*", "", line) + result_obj["directive"] = toupper(substr(line, 1, 4)) + line = substr(line, 5) + # Now get the explanation for the directive (if any), with leading + # and trailing whitespace removed. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + result_obj["explanation"] = line +} + +function get_test_exit_message(status) +{ + if (status == 0) + return "" + if (status !~ /^[1-9][0-9]*$/) + abort("getting exit status") + if (status < 127) + exit_details = "" + else if (status == 127) + exit_details = " (command not found?)" + else if (status >= 128 && status <= 255) + exit_details = sprintf(" (terminated by signal %d?)", status - 128) + else if (status > 256 && status <= 384) + # We used to report an "abnormal termination" here, but some Korn + # shells, when a child process die due to signal number n, can leave + # in $? an exit status of 256+n instead of the more standard 128+n. + # Apparently, both behaviours are allowed by POSIX (2008), so be + # prepared to handle them both. See also Austing Group report ID + # 0000051 + exit_details = sprintf(" (terminated by signal %d?)", status - 256) + else + # Never seen in practice. + exit_details = " (abnormal termination)" + return sprintf("exited with status %d%s", status, exit_details) +} + +function write_test_results() +{ + print ":global-test-result: " get_global_test_result() > trs_file + print ":recheck: " yn(must_recheck()) > trs_file + print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file + for (i = 0; i < test_results_index; i += 1) + print ":test-result: " test_results_list[i] > trs_file + close(trs_file); +} + +BEGIN { + +## ------- ## +## SETUP ## +## ------- ## + +'"$init_colors"' + +# Properly initialized once the TAP plan is seen. +planned_tests = 0 + +COOKED_PASS = expect_failure ? "XPASS": "PASS"; +COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; + +# Enumeration-like constants to remember which kind of plan (if any) +# has been seen. It is important that NO_PLAN evaluates "false" as +# a boolean. +NO_PLAN = 0 +EARLY_PLAN = 1 +LATE_PLAN = 2 + +testno = 0 # Number of test results seen so far. +bailed_out = 0 # Whether a "Bail out!" directive has been seen. + +# Whether the TAP plan has been seen or not, and if yes, which kind +# it is ("early" is seen before any test result, "late" otherwise). +plan_seen = NO_PLAN + +## --------- ## +## PARSING ## +## --------- ## + +is_first_read = 1 + +while (1) + { + # Involutions required so that we are able to read the exit status + # from the last input line. + st = getline + if (st < 0) # I/O error. + fatal("I/O error while reading from input stream") + else if (st == 0) # End-of-input + { + if (is_first_read) + abort("in input loop: only one input line") + break + } + if (is_first_read) + { + is_first_read = 0 + nextline = $0 + continue + } + else + { + curline = nextline + nextline = $0 + $0 = curline + } + # Copy any input line verbatim into the log file. + print | "cat >&3" + # Parsing of TAP input should stop after a "Bail out!" directive. + if (bailed_out) + continue + + # TAP test result. + if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) + { + testno += 1 + setup_result_obj($0) + handle_tap_result() + } + # TAP plan (normal or "SKIP" without explanation). + else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) + { + # The next two lines will put the number of planned tests in $0. + sub("^1\\.\\.", "") + sub("[^0-9]*$", "") + handle_tap_plan($0, "") + continue + } + # TAP "SKIP" plan, with an explanation. + else if ($0 ~ /^1\.\.0+[ \t]*#/) + { + # The next lines will put the skip explanation in $0, stripping + # any leading and trailing whitespace. This is a little more + # tricky in truth, since we want to also strip a potential leading + # "SKIP" string from the message. + sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") + sub("[ \t]*$", ""); + handle_tap_plan(0, $0) + } + # "Bail out!" magic. + # Older versions of prove and TAP::Harness (e.g., 3.17) did not + # recognize a "Bail out!" directive when preceded by leading + # whitespace, but more modern versions (e.g., 3.23) do. So we + # emulate the latter, "more modern" behaviour. + else if ($0 ~ /^[ \t]*Bail out!/) + { + bailed_out = 1 + # Get the bailout message (if any), with leading and trailing + # whitespace stripped. The message remains stored in `$0`. + sub("^[ \t]*Bail out![ \t]*", ""); + sub("[ \t]*$", ""); + # Format the error message for the + bailout_message = "Bail out!" + if (length($0)) + bailout_message = bailout_message " " $0 + testsuite_error(bailout_message) + } + # Maybe we have too look for dianogtic comments too. + else if (comments != 0) + { + comment = extract_tap_comment($0); + if (length(comment)) + report("#", comment); + } + } + +## -------- ## +## FINISH ## +## -------- ## + +# A "Bail out!" directive should cause us to ignore any following TAP +# error, as well as a non-zero exit status from the TAP producer. +if (!bailed_out) + { + if (!plan_seen) + { + testsuite_error("missing test plan") + } + else if (planned_tests != testno) + { + bad_amount = testno > planned_tests ? "many" : "few" + testsuite_error(sprintf("too %s tests run (expected %d, got %d)", + bad_amount, planned_tests, testno)) + } + if (!ignore_exit) + { + # Fetch exit status from the last line. + exit_message = get_test_exit_message(nextline) + if (exit_message) + testsuite_error(exit_message) + } + } + +write_test_results() + +exit 0 + +} # End of "BEGIN" block. +' + +# TODO: document that we consume the file descriptor 3 :-( +} 3>"$log_file" + +test $? -eq 0 || fatal "I/O or internal error" + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/Libraries/libressl/test-driver b/Libraries/libressl/test-driver new file mode 100644 index 000000000..be73b80ad --- /dev/null +++ b/Libraries/libressl/test-driver @@ -0,0 +1,153 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 2011-2021 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <"$log_file" +"$@" >>"$log_file" 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>"$log_file" + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/Libraries/libressl/tests/CMakeLists.txt b/Libraries/libressl/tests/CMakeLists.txt new file mode 100644 index 000000000..d09b9da40 --- /dev/null +++ b/Libraries/libressl/tests/CMakeLists.txt @@ -0,0 +1,798 @@ +add_definitions(-DLIBRESSL_CRYPTO_INTERNAL) + +include_directories( + . + ../crypto/asn1 + ../crypto/bio + ../crypto/bn + ../crypto/curve25519 + ../crypto/evp + ../crypto/modes + ../crypto/x509 + ../ssl + ../apps/openssl + ../apps/openssl/compat + ../include + ${CMAKE_BINARY_DIR}/include + ../include/compat +) + +add_definitions(-D_PATH_SSL_CA_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/../cert.pem\") + +file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} TEST_SOURCE_DIR) + +# aeadtest +add_executable(aeadtest aeadtest.c) +target_link_libraries(aeadtest ${OPENSSL_TEST_LIBS}) +if(NOT WIN32) + add_test(NAME aeadtest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/aeadtest.sh) + set_tests_properties(aeadtest PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") +else() + add_test(aeadtest aeadtest aead ${CMAKE_CURRENT_SOURCE_DIR}/aeadtests.txt) +endif() + +# aes_test +add_executable(aes_test aes_test.c) +target_link_libraries(aes_test ${OPENSSL_TEST_LIBS}) +add_test(aes_test aes_test) + +# aes_wrap +add_executable(aes_wrap aes_wrap.c) +target_link_libraries(aes_wrap ${OPENSSL_TEST_LIBS}) +add_test(aes_wrap aes_wrap) + +# apitest +add_executable(apitest apitest.c) +target_link_libraries(apitest ${OPENSSL_TEST_LIBS}) +set_source_files_properties(apitest.c PROPERTIES COMPILE_FLAGS + -DCERTSDIR=\\"${CMAKE_CURRENT_SOURCE_DIR}\\") +add_test(apitest apitest) + +# arc4randomforktest +# Windows/mingw does not have fork, but Cygwin does. +if(NOT (WIN32 OR (CMAKE_SYSTEM_NAME MATCHES "MINGW"))) + add_executable(arc4randomforktest arc4randomforktest.c) + target_link_libraries(arc4randomforktest ${OPENSSL_TEST_LIBS}) + add_test(arc4randomforktest ${CMAKE_CURRENT_SOURCE_DIR}/arc4randomforktest.sh) +endif() + +# asn1api +add_executable(asn1api asn1api.c) +target_link_libraries(asn1api ${OPENSSL_TEST_LIBS}) +add_test(asn1api asn1api) + +# asn1basic +add_executable(asn1basic asn1basic.c) +target_link_libraries(asn1basic ${OPENSSL_TEST_LIBS}) +add_test(asn1basic asn1basic) + +# asn1complex +add_executable(asn1complex asn1complex.c) +target_link_libraries(asn1complex ${OPENSSL_TEST_LIBS}) +add_test(asn1complex asn1complex) + +# asn1evp +add_executable(asn1evp asn1evp.c) +target_link_libraries(asn1evp ${OPENSSL_TEST_LIBS}) +add_test(asn1evp asn1evp) + +# asn1object +add_executable(asn1object asn1object.c) +target_link_libraries(asn1object ${OPENSSL_TEST_LIBS}) +add_test(asn1object asn1object) + +# asn1oct +add_executable(asn1oct asn1oct.c) +target_link_libraries(asn1oct ${OPENSSL_TEST_LIBS}) +add_test(asn1oct asn1oct) + +# asn1string_copy +add_executable(asn1string_copy asn1string_copy.c) +target_link_libraries(asn1string_copy ${OPENSSL_TEST_LIBS}) +add_test(asn1string_copy asn1string_copy) + +# asn1test +add_executable(asn1test asn1test.c) +target_link_libraries(asn1test ${OPENSSL_TEST_LIBS}) +add_test(asn1test asn1test) + +# asn1time +add_executable(asn1time asn1time.c) +target_link_libraries(asn1time ${OPENSSL_TEST_LIBS}) +add_test(asn1time asn1time) + +# asn1x509 +add_executable(asn1x509 asn1x509.c) +target_link_libraries(asn1x509 ${OPENSSL_TEST_LIBS}) +add_test(asn1x509 asn1x509) + +# asn1_string_to_utf8 +add_executable(asn1_string_to_utf8 asn1_string_to_utf8.c) +target_link_libraries(asn1_string_to_utf8 ${OPENSSL_TEST_LIBS}) +add_test(asn1_string_to_utf8 asn1_string_to_utf8) + +# base64test +add_executable(base64test base64test.c) +target_link_libraries(base64test ${OPENSSL_TEST_LIBS}) +add_test(base64test base64test) + +# bf_test +add_executable(bf_test bf_test.c) +target_link_libraries(bf_test ${OPENSSL_TEST_LIBS}) +add_test(bf_test bf_test) + +# bio_asn1 +add_executable(bio_asn1 bio_asn1.c) +target_link_libraries(bio_asn1 ${OPENSSL_TEST_LIBS}) +add_test(bio_asn1 bio_asn1) + +# bio_chain +add_executable(bio_chain bio_chain.c) +target_link_libraries(bio_chain ${OPENSSL_TEST_LIBS}) +add_test(bio_chain bio_chain) + +# bio_host +# this test relies on resolver results that are OS and environment-specific +if(ENABLE_EXTRATESTS) + add_executable(bio_host bio_host.c) + target_link_libraries(bio_host ${OPENSSL_TEST_LIBS}) + add_test(bio_host bio_host) +endif() + +# bio_mem +add_executable(bio_mem bio_mem.c) +target_link_libraries(bio_mem ${OPENSSL_TEST_LIBS}) +add_test(bio_mem bio_mem) + +# bn_add_sub +add_executable(bn_add_sub bn_add_sub.c) +target_link_libraries(bn_add_sub ${OPENSSL_TEST_LIBS}) +add_test(bn_add_sub bn_add_sub) + +# bn_cmp +add_executable(bn_cmp bn_cmp.c) +target_link_libraries(bn_cmp ${OPENSSL_TEST_LIBS}) +add_test(bn_cmp bn_cmp) + +# bn_convert +add_executable(bn_convert bn_convert.c) +target_link_libraries(bn_convert ${OPENSSL_TEST_LIBS}) +add_test(bn_convert bn_convert) + +# bn_gcd +add_executable(bn_gcd bn_cmp.c) +target_link_libraries(bn_gcd ${OPENSSL_TEST_LIBS}) +add_test(bn_gcd bn_gcd) + +# bn_general is a benchmark + +# bn_isqrt +add_executable(bn_isqrt bn_isqrt.c) +target_link_libraries(bn_isqrt ${OPENSSL_TEST_LIBS}) +add_test(bn_isqrt bn_isqrt) + +# bn_mod_exp +add_executable(bn_mod_exp bn_mod_exp.c) +set_source_files_properties(bn_mod_exp.c PROPERTIES COMPILE_FLAGS + -ULIBRESSL_INTERNAL) +target_link_libraries(bn_mod_exp ${OPENSSL_TEST_LIBS}) +add_test(bn_mod_exp bn_mod_exp) + +# bn_mod_inverse +add_executable(bn_mod_inverse bn_mod_inverse.c) +target_link_libraries(bn_mod_inverse ${OPENSSL_TEST_LIBS}) +add_test(bn_mod_inverse bn_mod_inverse) + +# bn_mod_sqrt +add_executable(bn_mod_sqrt bn_mod_sqrt.c) +target_link_libraries(bn_mod_sqrt ${OPENSSL_TEST_LIBS}) +add_test(bn_mod_sqrt bn_mod_sqrt) + +# bn_mont +add_executable(bn_mont bn_mont.c) +target_link_libraries(bn_mont ${OPENSSL_TEST_LIBS}) +add_test(bn_mont bn_mont) + +# bn_primes +add_executable(bn_primes bn_primes.c) +target_link_libraries(bn_primes ${OPENSSL_TEST_LIBS}) +add_test(bn_primes bn_primes) + +# bn_print +add_executable(bn_print bn_print.c) +target_link_libraries(bn_print ${OPENSSL_TEST_LIBS}) +add_test(bn_print bn_print) + +# bn_shift +add_executable(bn_shift bn_shift.c) +target_link_libraries(bn_shift ${OPENSSL_TEST_LIBS}) +add_test(bn_shift bn_shift) + +# bn_test +add_executable(bn_test bn_test.c) +set_source_files_properties(bn_test.c PROPERTIES COMPILE_FLAGS + -ULIBRESSL_INTERNAL) +target_link_libraries(bn_test ${OPENSSL_TEST_LIBS}) +add_test(bn_test bn_test) + +# bn_to_string +add_executable(bn_to_string bn_to_string.c) +target_link_libraries(bn_to_string ${OPENSSL_TEST_LIBS}) +add_test(bn_to_string bn_to_string) + +# bn_unit +add_executable(bn_unit bn_unit.c) +target_link_libraries(bn_unit ${OPENSSL_TEST_LIBS}) +add_test(bn_unit bn_unit) + +# bn_word +add_executable(bn_word bn_word.c) +target_link_libraries(bn_word ${OPENSSL_TEST_LIBS}) +add_test(bn_word bn_word) + +# buffertest +add_executable(buffertest buffertest.c) +target_link_libraries(buffertest ${OPENSSL_TEST_LIBS}) +add_test(buffertest buffertest) + +# bytestringtest +add_executable(bytestringtest bytestringtest.c) +target_link_libraries(bytestringtest ${OPENSSL_TEST_LIBS}) +add_test(bytestringtest bytestringtest) + +# callback +# callbackfailures + +# casttest +add_executable(casttest casttest.c) +target_link_libraries(casttest ${OPENSSL_TEST_LIBS}) +add_test(casttest casttest) + +# chachatest +add_executable(chachatest chachatest.c) +target_link_libraries(chachatest ${OPENSSL_TEST_LIBS}) +add_test(chachatest chachatest) + +# cipher_list +add_executable(cipher_list cipher_list.c) +target_link_libraries(cipher_list ${OPENSSL_TEST_LIBS}) +add_test(cipher_list cipher_list) + +# cipherstest +add_executable(cipherstest cipherstest.c) +target_link_libraries(cipherstest ${OPENSSL_TEST_LIBS}) +add_test(cipherstest cipherstest) + +# clienttest +add_executable(clienttest clienttest.c) +target_link_libraries(clienttest ${OPENSSL_TEST_LIBS}) +add_test(clienttest clienttest) + +# cmstest +add_executable(cmstest cmstest.c) +target_link_libraries(cmstest ${OPENSSL_TEST_LIBS}) +add_test(cmstest cmstest) + +# configtest +add_executable(configtest configtest.c) +target_link_libraries(configtest ${LIBTLS_TEST_LIBS}) +add_test(configtest configtest) + +# constraints +add_executable(constraints constraints.c) +target_link_libraries(constraints ${OPENSSL_TEST_LIBS}) +add_test(constraints constraints) + +# cttest +add_executable(cttest cttest.c) +target_link_libraries(cttest ${OPENSSL_TEST_LIBS}) +set_source_files_properties(cttest.c PROPERTIES COMPILE_FLAGS + -DCTPATH=\\"${CMAKE_CURRENT_SOURCE_DIR}\\") +add_test(cttest cttest) + +# destest +add_executable(destest destest.c) +target_link_libraries(destest ${OPENSSL_TEST_LIBS}) +add_test(destest destest) + +# dhtest +add_executable(dhtest dhtest.c) +target_link_libraries(dhtest ${OPENSSL_TEST_LIBS}) +add_test(dhtest dhtest) + +# dsatest +add_executable(dsatest dsatest.c) +target_link_libraries(dsatest ${OPENSSL_TEST_LIBS}) +add_test(dsatest dsatest) + +# XXX This test is too flaky for CI. Disable it until it is fixed. +# # dtlstest +# if(NOT WIN32) +# add_executable(dtlstest dtlstest.c) +# target_link_libraries(dtlstest ${OPENSSL_TEST_LIBS}) +# add_test(NAME dtlstest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/dtlstest.sh) +# set_tests_properties(dtlstest PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") +# endif() + +# ecc_cdh +add_executable(ecc_cdh ecc_cdh.c) +target_link_libraries(ecc_cdh ${OPENSSL_TEST_LIBS}) +add_test(ecc_cdh ecc_cdh) + +# ec_asn1_test +add_executable(ec_asn1_test ec_asn1_test.c) +target_link_libraries(ec_asn1_test ${OPENSSL_TEST_LIBS}) +add_test(ec_asn1_test ec_asn1_test) + +# ec_point_conversion +add_executable(ec_point_conversion ec_point_conversion.c) +target_link_libraries(ec_point_conversion ${OPENSSL_TEST_LIBS}) +add_test(ec_point_conversion ec_point_conversion) + +# ecdhtest +add_executable(ecdhtest ecdhtest.c) +target_link_libraries(ecdhtest ${OPENSSL_TEST_LIBS}) +add_test(ecdhtest ecdhtest) + +# ecdsatest +add_executable(ecdsatest ecdsatest.c) +target_link_libraries(ecdsatest ${OPENSSL_TEST_LIBS}) +add_test(ecdsatest ecdsatest) + +# ectest +add_executable(ectest ectest.c) +target_link_libraries(ectest ${OPENSSL_TEST_LIBS}) +add_test(ectest ectest) + +# ed25519test +add_executable(ed25519test ed25519test.c) +target_link_libraries(ed25519test ${OPENSSL_TEST_LIBS}) +add_test(ed25519test ed25519test) + +# enginetest +add_executable(enginetest enginetest.c) +target_link_libraries(enginetest ${OPENSSL_TEST_LIBS}) +add_test(enginetest enginetest) + +# evp_ecx_test +add_executable(evp_ecx_test evp_ecx_test.c) +target_link_libraries(evp_ecx_test ${OPENSSL_TEST_LIBS}) +add_test(evp_ecx_test evp_ecx_test) + +# evp_pkey_check +add_executable(evp_pkey_check evp_pkey_check.c) +target_link_libraries(evp_pkey_check ${OPENSSL_TEST_LIBS}) +add_test(evp_pkey_check evp_pkey_check) + +# evp_pkey_cleanup +add_executable(evp_pkey_cleanup evp_pkey_cleanup.c) +target_link_libraries(evp_pkey_cleanup ${OPENSSL_TEST_LIBS}) +add_test(evp_pkey_cleanup evp_pkey_cleanup) + +# evptest +add_executable(evptest evptest.c) +target_link_libraries(evptest ${OPENSSL_TEST_LIBS}) +add_test(evptest evptest ${CMAKE_CURRENT_SOURCE_DIR}/evptests.txt) + +# evp_test +add_executable(evp_test evp_test.c) +target_link_libraries(evp_test ${OPENSSL_TEST_LIBS}) +add_test(evp_test evp_test) + +# expirecallback.c + +# explicit_bzero +# explicit_bzero relies on SA_ONSTACK, which is unavailable on Windows +if(NOT WIN32) + if(HAVE_MEMMEM) + add_executable(explicit_bzero explicit_bzero.c) + else() + add_executable(explicit_bzero explicit_bzero.c compat/memmem.c) + endif() + target_link_libraries(explicit_bzero ${OPENSSL_TEST_LIBS}) + add_test(explicit_bzero explicit_bzero) +endif() + +# exportertest +add_executable(exportertest exportertest.c) +target_link_libraries(exportertest ${OPENSSL_TEST_LIBS}) +add_test(exportertest exportertest) + +# freenull +add_executable(freenull freenull.c) +set_source_files_properties(freenull.c PROPERTIES COMPILE_FLAGS + -ULIBRESSL_INTERNAL) +target_link_libraries(freenull ${OPENSSL_TEST_LIBS}) +add_test(freenull freenull) + +# gcm128test +add_executable(gcm128test gcm128test.c) +target_link_libraries(gcm128test ${OPENSSL_TEST_LIBS}) +add_test(gcm128test gcm128test) + +# gost2814789t +add_executable(gost2814789t gost2814789t.c) +target_link_libraries(gost2814789t ${OPENSSL_TEST_LIBS}) +add_test(gost2814789t gost2814789t) + +# handshake_table +add_executable(handshake_table handshake_table.c) +target_link_libraries(handshake_table ${OPENSSL_TEST_LIBS}) +add_test(handshake_table handshake_table) + +# hkdf_test +add_executable(hkdf_test hkdf_test.c) +target_link_libraries(hkdf_test ${OPENSSL_TEST_LIBS}) +add_test(hkdf_test hkdf_test) + +# hmactest +add_executable(hmactest hmactest.c) +target_link_libraries(hmactest ${OPENSSL_TEST_LIBS}) +add_test(hmactest hmactest) + +# ideatest +add_executable(ideatest ideatest.c) +target_link_libraries(ideatest ${OPENSSL_TEST_LIBS}) +add_test(ideatest ideatest) + +# igetest +add_executable(igetest igetest.c) +target_link_libraries(igetest ${OPENSSL_TEST_LIBS}) +add_test(igetest igetest) + +# init_pledge + +# key_schedule +add_executable(key_schedule key_schedule.c) +target_link_libraries(key_schedule ${OPENSSL_TEST_LIBS}) +add_test(key_schedule key_schedule) + +# keypair +add_executable(keypairtest keypairtest.c) +target_link_libraries(keypairtest ${LIBTLS_TEST_LIBS}) +target_include_directories(keypairtest BEFORE PUBLIC ../tls) +add_test(keypairtest keypairtest + ${CMAKE_CURRENT_SOURCE_DIR}/ca.pem + ${CMAKE_CURRENT_SOURCE_DIR}/server.pem + ${CMAKE_CURRENT_SOURCE_DIR}/server.pem) + +# md_test +add_executable(md_test md_test.c) +target_link_libraries(md_test ${OPENSSL_TEST_LIBS}) +add_test(md_test md_test) + +# objectstest +add_executable(objectstest objectstest.c) +target_link_libraries(objectstest ${OPENSSL_TEST_LIBS}) +add_test(objectstest objectstest) + +# ocsp_test +if(ENABLE_EXTRATESTS) + add_executable(ocsp_test ocsp_test.c) + target_link_libraries(ocsp_test ${OPENSSL_TEST_LIBS}) + if(NOT MSVC) + add_test(NAME ocsptest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ocsptest.sh) + else() + add_test(NAME ocsptest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ocsptest.bat $) + endif() +endif() + +# optionstest +add_executable(optionstest optionstest.c) +target_link_libraries(optionstest ${OPENSSL_TEST_LIBS}) +add_test(optionstest optionstest) + +# pbkdf2 +add_executable(pbkdf2 pbkdf2.c) +target_link_libraries(pbkdf2 ${OPENSSL_TEST_LIBS}) +add_test(pbkdf2 pbkdf2) + +# pidwraptest +# pidwraptest relies on an OS-specific way to give out pids and is generally +# awkward on systems with slow fork +if(ENABLE_EXTRATESTS AND NOT MSVC) + add_executable(pidwraptest pidwraptest.c) + target_link_libraries(pidwraptest ${OPENSSL_TEST_LIBS}) + add_test(pidwraptest ${CMAKE_CURRENT_SOURCE_DIR}/pidwraptest.sh) +endif() + +# pkcs7test +add_executable(pkcs7test pkcs7test.c) +target_link_libraries(pkcs7test ${OPENSSL_TEST_LIBS}) +add_test(pkcs7test pkcs7test) + +# poly1305test +add_executable(poly1305test poly1305test.c) +target_link_libraries(poly1305test ${OPENSSL_TEST_LIBS}) +add_test(poly1305test poly1305test) + +# policy +add_executable(policy policy.c) +set_source_files_properties(policy.c PROPERTIES COMPILE_FLAGS + -DCERTSDIR=\\"${CMAKE_CURRENT_SOURCE_DIR}\\") +target_link_libraries(policy ${OPENSSL_TEST_LIBS}) +add_test(policy policy) + +# pq_test +add_executable(pq_test pq_test.c) +target_link_libraries(pq_test ${OPENSSL_TEST_LIBS}) +if(NOT MSVC) + add_test(NAME pq_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/pq_test.sh) +else() + add_test(NAME pq_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/pq_test.bat + $) +endif() +set_tests_properties(pq_test PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# quictest +set(QUICTEST_SRC quictest.c) +add_executable(quictest ${QUICTEST_SRC}) +target_link_libraries(quictest ${OPENSSL_TEST_LIBS}) +if(NOT MSVC) + add_test(NAME quictest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/quictest.sh) +else() + add_test(NAME quictest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/quictest.bat $) +endif() +set_tests_properties(quictest PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# randtest +add_executable(randtest randtest.c) +target_link_libraries(randtest ${OPENSSL_TEST_LIBS}) +add_test(randtest randtest) + +# rc2_test +add_executable(rc2_test rc2_test.c) +target_link_libraries(rc2_test ${OPENSSL_TEST_LIBS}) +add_test(rc2_test rc2_test) + +# rc4_test +add_executable(rc4_test rc4_test.c) +target_link_libraries(rc4_test ${OPENSSL_TEST_LIBS}) +add_test(rc4_test rc4_test) + +# recordtest +add_executable(recordtest recordtest.c) +target_link_libraries(recordtest ${OPENSSL_TEST_LIBS}) +add_test(recordtest recordtest) + +# record_layer_test +add_executable(record_layer_test record_layer_test.c) +target_link_libraries(record_layer_test ${OPENSSL_TEST_LIBS}) +add_test(record_layer_test record_layer_test) + +# rfc3779 +add_executable(rfc3779 rfc3779.c) +target_link_libraries(rfc3779 ${OPENSSL_TEST_LIBS}) +add_test(rfc3779 rfc3779) + +# rfc5280time +add_executable(rfc5280time rfc5280time.c) +target_link_libraries(rfc5280time ${OPENSSL_TEST_LIBS}) +if(SMALL_TIME_T) + add_test(rfc5280time ${CMAKE_CURRENT_SOURCE_DIR}/rfc5280time_small.test) +else() + add_test(rfc5280time rfc5280time) +endif() + +# rmd_test +add_executable(rmd_test rmd_test.c) +target_link_libraries(rmd_test ${OPENSSL_TEST_LIBS}) +add_test(rmd_test rmd_test) + +# rsa_test +add_executable(rsa_test rsa_test.c) +target_link_libraries(rsa_test ${OPENSSL_TEST_LIBS}) +add_test(rsa_test rsa_test) + +# server.c + +# servertest +add_executable(servertest servertest.c) +target_link_libraries(servertest ${OPENSSL_TEST_LIBS}) +if(NOT MSVC) + add_test(NAME servertest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/servertest.sh) +else() + add_test(NAME servertest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/servertest.bat $) +endif() +set_tests_properties(servertest PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# sha_test +add_executable(sha_test sha_test.c) +target_link_libraries(sha_test ${OPENSSL_TEST_LIBS}) +add_test(sha_test sha_test) + +# signertest +if(NOT CMAKE_SYSTEM_NAME MATCHES "WindowsStore") + set(SIGNERTEST_SRC signertest.c) + check_function_exists(pipe2 HAVE_PIPE2) + if(HAVE_PIPE2) + add_definitions(-DHAVE_PIPE2) + else() + set(SIGNERTEST_SRC ${SIGNERTEST_SRC} compat/pipe2.c) + endif() + + set_source_files_properties(signertest.c PROPERTIES COMPILE_FLAGS + -DCERTSDIR=\\"${CMAKE_CURRENT_SOURCE_DIR}\\") + add_executable(signertest ${SIGNERTEST_SRC}) + target_link_libraries(signertest ${LIBTLS_TEST_LIBS}) + target_include_directories(signertest BEFORE PUBLIC ../tls) + add_test(signertest signertest) +endif() + +# sm2crypttest +# sm2evptest +# sm2sigtest + +# sm3test +add_executable(sm3test sm3test.c) +target_link_libraries(sm3test ${OPENSSL_TEST_LIBS}) +add_test(sm3test sm3test) + +# sm4test +add_executable(sm4test sm4test.c) +target_link_libraries(sm4test ${OPENSSL_TEST_LIBS}) +add_test(sm4test sm4test) + +# ssl_get_shared_ciphers +add_executable(ssl_get_shared_ciphers ssl_get_shared_ciphers.c) +set_source_files_properties(ssl_get_shared_ciphers.c PROPERTIES COMPILE_FLAGS + -DCERTSDIR=\\"${CMAKE_CURRENT_SOURCE_DIR}\\") +target_link_libraries(ssl_get_shared_ciphers ${OPENSSL_TEST_LIBS}) +add_test(ssl_get_shared_ciphers ssl_get_shared_ciphers) + +# ssl_methods +add_executable(ssl_methods ssl_methods.c) +target_link_libraries(ssl_methods ${OPENSSL_TEST_LIBS}) +add_test(ssl_methods ssl_methods) + +# ssl_set_alpn_protos +add_executable(ssl_set_alpn_protos ssl_set_alpn_protos.c) +target_link_libraries(ssl_set_alpn_protos ${OPENSSL_TEST_LIBS}) +add_test(ssl_set_alpn_protos ssl_set_alpn_protos) + +# ssl_verify_param +add_executable(ssl_verify_param ssl_verify_param.c) +target_link_libraries(ssl_verify_param ${OPENSSL_TEST_LIBS}) +add_test(ssl_verify_param ssl_verify_param) + +# ssl_versions +add_executable(ssl_versions ssl_versions.c) +target_link_libraries(ssl_versions ${OPENSSL_TEST_LIBS}) +add_test(ssl_versions ssl_versions) + +# ssltest +add_executable(ssltest ssltest.c) +target_link_libraries(ssltest ${OPENSSL_TEST_LIBS}) +if(NOT MSVC) + add_test(NAME ssltest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ssltest.sh) +else() + add_test(NAME ssltest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ssltest.bat $ $) +endif() +set_tests_properties(ssltest PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# string_table +add_executable(string_table string_table.c) +target_link_libraries(string_table ${OPENSSL_TEST_LIBS}) +add_test(string_table string_table) + +# testdsa +if(NOT MSVC) + add_test(NAME testdsa COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testdsa.sh) +else() + add_test(NAME testdsa COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testdsa.bat $) +endif() +set_tests_properties(testdsa PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# testenc +if(NOT MSVC) + add_test(NAME testenc COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testenc.sh) +else() + add_test(NAME testenc COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testenc.bat $) +endif() +set_tests_properties(testenc PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# testrsa +if(NOT MSVC) + add_test(NAME testrsa COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testrsa.sh) +else() + add_test(NAME testrsa COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testrsa.bat $) +endif() +set_tests_properties(testrsa PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") + +# timingsafe +add_executable(timingsafe timingsafe.c) +target_link_libraries(timingsafe ${OPENSSL_TEST_LIBS}) +add_test(timingsafe timingsafe) + +# tlsexttest +add_executable(tlsexttest tlsexttest.c) +target_link_libraries(tlsexttest ${OPENSSL_TEST_LIBS}) +add_test(tlsexttest tlsexttest) + +# tlslegacytest +add_executable(tlslegacytest tlslegacytest.c) +target_link_libraries(tlslegacytest ${OPENSSL_TEST_LIBS}) +add_test(tlslegacytest tlslegacytest) + +# tlstest +if(NOT CMAKE_SYSTEM_NAME MATCHES "WindowsStore") + set(TLSTEST_SRC tlstest.c) + check_function_exists(pipe2 HAVE_PIPE2) + if(HAVE_PIPE2) + add_definitions(-DHAVE_PIPE2) + else() + set(TLSTEST_SRC ${TLSTEST_SRC} compat/pipe2.c) + endif() + + add_executable(tlstest ${TLSTEST_SRC}) + target_link_libraries(tlstest ${LIBTLS_TEST_LIBS}) + if(NOT MSVC) + add_test(NAME tlstest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tlstest.sh) + else() + add_test(NAME tlstest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tlstest.bat $) + endif() + set_tests_properties(tlstest PROPERTIES ENVIRONMENT "srcdir=${TEST_SOURCE_DIR}") +endif() + +# tls_ext_alpn +add_executable(tls_ext_alpn tls_ext_alpn.c) +target_link_libraries(tls_ext_alpn ${OPENSSL_TEST_LIBS}) +add_test(tls_ext_alpn tls_ext_alpn) + +# tls_prf +add_executable(tls_prf tls_prf.c) +target_link_libraries(tls_prf ${OPENSSL_TEST_LIBS}) +add_test(tls_prf tls_prf) + +# utf8test +add_executable(utf8test utf8test.c) +target_link_libraries(utf8test ${OPENSSL_TEST_LIBS}) +add_test(utf8test utf8test) + +# valid_handshakes_terminate +add_executable(valid_handshakes_terminate valid_handshakes_terminate.c) +target_link_libraries(valid_handshakes_terminate ${OPENSSL_TEST_LIBS}) +add_test(valid_handshakes_terminate valid_handshakes_terminate) + +# verifytest +add_executable(verifytest verifytest.c) +target_link_libraries(verifytest ${LIBTLS_TEST_LIBS}) +add_test(verifytest verifytest) + +# x25519test +add_executable(x25519test x25519test.c) +target_link_libraries(x25519test ${OPENSSL_TEST_LIBS}) +add_test(x25519test x25519test) + +# x509attribute +add_executable(x509attribute x509attribute.c) +target_link_libraries(x509attribute ${OPENSSL_TEST_LIBS}) +add_test(x509attribute x509attribute) + +# x509_asn1 +add_executable(x509_asn1 x509_asn1.c) +target_link_libraries(x509_asn1 ${OPENSSL_TEST_LIBS}) +add_test(x509_asn1 x509_asn1) + +# x509_info +add_executable(x509_info x509_info.c) +target_link_libraries(x509_info ${OPENSSL_TEST_LIBS}) +add_test(x509_info x509_info) + +# x509name +add_executable(x509name x509name.c) +target_link_libraries(x509name ${OPENSSL_TEST_LIBS}) +add_test(x509name x509name) + +# x509req_ext +add_executable(x509req_ext x509req_ext.c) +target_link_libraries(x509req_ext ${OPENSSL_TEST_LIBS}) +add_test(x509req_ext x509req_ext) + +add_custom_command(TARGET x25519test POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$" + "$" + "$" + "${CMAKE_CURRENT_BINARY_DIR}" + COMMENT "Copying DLLs for regression tests") diff --git a/Libraries/libressl/tests/Makefile.am b/Libraries/libressl/tests/Makefile.am new file mode 100644 index 000000000..b860acef0 --- /dev/null +++ b/Libraries/libressl/tests/Makefile.am @@ -0,0 +1,796 @@ +include $(top_srcdir)/Makefile.am.common + +-include $(abs_top_builddir)/crypto/libcrypto_la_objects.mk +-include $(abs_top_builddir)/ssl/libssl_la_objects.mk +-include $(abs_top_builddir)/tls/libtls_la_objects.mk + +AM_CPPFLAGS += -DLIBRESSL_CRYPTO_INTERNAL + +AM_CPPFLAGS += -I $(top_srcdir)/crypto/asn1 +AM_CPPFLAGS += -I $(top_srcdir)/crypto/bio +AM_CPPFLAGS += -I $(top_srcdir)/crypto/bn +AM_CPPFLAGS += -I $(top_srcdir)/crypto/curve25519 +AM_CPPFLAGS += -I $(top_srcdir)/crypto/evp +AM_CPPFLAGS += -I $(top_srcdir)/crypto/modes +AM_CPPFLAGS += -I $(top_srcdir)/crypto/x509 +AM_CPPFLAGS += -I $(top_srcdir)/ssl +AM_CPPFLAGS += -I $(top_srcdir)/apps/openssl +AM_CPPFLAGS += -I $(top_srcdir)/apps/openssl/compat +AM_CPPFLAGS += -D_PATH_SSL_CA_FILE=\"$(top_srcdir)/cert.pem\" + +noinst_LTLIBRARIES = libtest.la +libtest_la_LIBADD = $(libcrypto_la_objects) +libtest_la_LIBADD += $(libcompat_la_objects) +libtest_la_LIBADD += $(libcompatnoopt_la_objects) +libtest_la_LIBADD += $(libssl_la_objects) +libtest_la_LIBADD += $(libtls_la_objects) +libtest_la_SOURCES = empty.c + +LDADD = libtest.la $(PLATFORM_LDADD) $(PROG_LDADD) + +TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh + +TESTS = +check_PROGRAMS = +EXTRA_DIST = CMakeLists.txt +DISTCLEANFILES = pidwraptest.txt + +# aeadtest +TESTS += aeadtest.sh +check_PROGRAMS += aeadtest +aeadtest_SOURCES = aeadtest.c +EXTRA_DIST += aeadtest.sh +EXTRA_DIST += aeadtests.txt +EXTRA_DIST += aes_128_gcm_tests.txt +EXTRA_DIST += aes_192_gcm_tests.txt +EXTRA_DIST += aes_256_gcm_tests.txt +EXTRA_DIST += chacha20_poly1305_tests.txt +EXTRA_DIST += xchacha20_poly1305_tests.txt + +# aes +TESTS += aes_test +check_PROGRAMS += aes_test +aes_test_SOURCES = aes_test.c + +# aes_wrap +TESTS += aes_wrap +check_PROGRAMS += aes_wrap +aes_wrap_SOURCES = aes_wrap.c + +# apitest +TESTS += apitest +check_PROGRAMS += apitest +apitest_SOURCES = apitest.c +apitest_CPPFLAGS = $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" + +# arc4randomforktest +# Windows/mingw does not have fork, but Cygwin does. +if !HOST_WIN +TESTS += arc4randomforktest.sh +check_PROGRAMS += arc4randomforktest +arc4randomforktest_SOURCES = arc4randomforktest.c +endif +EXTRA_DIST += arc4randomforktest.sh + +# asn1_string_to_utf8 +TESTS += asn1_string_to_utf8 +check_PROGRAMS += asn1_string_to_utf8 +asn1_string_to_utf8_SOURCES = asn1_string_to_utf8.c + +# asn1api +TESTS += asn1api +check_PROGRAMS += asn1api +asn1api_SOURCES = asn1api.c + +# asn1basic +TESTS += asn1basic +check_PROGRAMS += asn1basic +asn1basic_SOURCES = asn1basic.c + +# asn1complex +TESTS += asn1complex +check_PROGRAMS += asn1complex +asn1complex_SOURCES = asn1complex.c + +# asn1evp +TESTS += asn1evp +check_PROGRAMS += asn1evp +asn1evp_SOURCES = asn1evp.c + +# asn1object +TESTS += asn1object +check_PROGRAMS += asn1object +asn1object_SOURCES = asn1object.c + +# asn1oct +TESTS += asn1oct +check_PROGRAMS += asn1oct +asn1oct_SOURCES = asn1oct.c + +# asn1string_copy +TESTS += asn1string_copy +check_PROGRAMS += asn1string_copy +asn1string_copy_SOURCES = asn1string_copy.c + +# asn1test +TESTS += asn1test +check_PROGRAMS += asn1test +asn1test_SOURCES = asn1test.c + +# asn1time +TESTS += asn1time +check_PROGRAMS += asn1time +asn1time_SOURCES = asn1time.c + +# asn1x509 +TESTS += asn1x509 +check_PROGRAMS += asn1x509 +asn1x509_SOURCES = asn1x509.c + +# base64test +TESTS += base64test +check_PROGRAMS += base64test +base64test_SOURCES = base64test.c + +# bf_test +TESTS += bf_test +check_PROGRAMS += bf_test +bf_test_SOURCES = bf_test.c + +# bio_asn1 +TESTS += bio_asn1 +check_PROGRAMS += bio_asn1 +bio_asn1_SOURCES = bio_asn1.c + +# bio_chain +TESTS += bio_chain +check_PROGRAMS += bio_chain +bio_chain_SOURCES = bio_chain.c + +# bio_host +# this test relies on resolver results that are OS and environment-specific +if ENABLE_EXTRATESTS +TESTS += bio_host +check_PROGRAMS += bio_host +bio_host_SOURCES = bio_host.c +endif + +# bio_mem +TESTS += bio_mem +check_PROGRAMS += bio_mem +bio_mem_SOURCES = bio_mem.c + +# bn_add_sub +TESTS += bn_add_sub +check_PROGRAMS += bn_add_sub +bn_add_sub_SOURCES = bn_add_sub.c + +# bn_cmp +TESTS += bn_cmp +check_PROGRAMS += bn_cmp +bn_cmp_SOURCES = bn_cmp.c + +# bn_convert +TESTS += bn_convert +check_PROGRAMS += bn_convert +bn_convert_SOURCES = bn_convert.c + +# bn_gcd +TESTS += bn_gcd +check_PROGRAMS += bn_gcd +bn_gcd_SOURCES = bn_gcd.c + +# bn_general is a benchmark. + +# bn_isqrt +TESTS += bn_isqrt +check_PROGRAMS += bn_isqrt +bn_isqrt_SOURCES = bn_isqrt.c + +# bn_mod_exp +TESTS += bn_mod_exp +check_PROGRAMS += bn_mod_exp +bn_mod_exp_CPPFLAGS = $(AM_CPPFLAGS) -ULIBRESSL_INTERNAL +bn_mod_exp_SOURCES = bn_mod_exp.c + +# bn_mod_inverse +TESTS += bn_mod_inverse +check_PROGRAMS += bn_mod_inverse +bn_mod_inverse_SOURCES = bn_mod_inverse.c + +# bn_mod_sqrt +TESTS += bn_mod_sqrt +check_PROGRAMS += bn_mod_sqrt +bn_mod_sqrt_SOURCES = bn_mod_sqrt.c + +# bn_mont +TESTS += bn_mont +check_PROGRAMS += bn_mont +bn_mont_SOURCES = bn_mont.c + +# bn_primes +TESTS += bn_primes +check_PROGRAMS += bn_primes +bn_primes_SOURCES = bn_primes.c + +# bn_print +TESTS += bn_print +check_PROGRAMS += bn_print +bn_print_SOURCES = bn_print.c + +# bn_shift +TESTS += bn_shift +check_PROGRAMS += bn_shift +bn_shift_SOURCES = bn_shift.c + +# bn_test +TESTS += bn_test +bn_test_CPPFLAGS = $(AM_CPPFLAGS) -ULIBRESSL_INTERNAL +check_PROGRAMS += bn_test +bn_test_SOURCES = bn_test.c + +# bn_to_string +TESTS += bn_to_string +check_PROGRAMS += bn_to_string +bn_to_string_SOURCES = bn_to_string.c + +# bn_unit +TESTS += bn_unit +check_PROGRAMS += bn_unit +bn_unit_SOURCES = bn_unit.c + +# bn_word +TESTS += bn_word +check_PROGRAMS += bn_word +bn_word_SOURCES = bn_word.c + +# buffertest +TESTS += buffertest +check_PROGRAMS += buffertest +buffertest_SOURCES = buffertest.c + +# bytestringtest +TESTS += bytestringtest +check_PROGRAMS += bytestringtest +bytestringtest_SOURCES = bytestringtest.c + +# callback +# callbackfailures + +# casttest +TESTS += casttest +check_PROGRAMS += casttest +casttest_SOURCES = casttest.c + +# chachatest +TESTS += chachatest +check_PROGRAMS += chachatest +chachatest_SOURCES = chachatest.c + +# cipher_list +TESTS += cipher_list +check_PROGRAMS += cipher_list +cipher_list_SOURCES = cipher_list.c +noinst_HEADERS = tests.h + +# cipherstest +TESTS += cipherstest +check_PROGRAMS += cipherstest +cipherstest_SOURCES = cipherstest.c + +# clienttest +TESTS += clienttest +check_PROGRAMS += clienttest +clienttest_SOURCES = clienttest.c + +# cmstest +TESTS += cmstest +check_PROGRAMS += cmstest +cmstest_SOURCES = cmstest.c + +# configtest +TESTS += configtest +check_PROGRAMS += configtest +configtest_SOURCES = configtest.c + +# constraints +TESTS += constraints +check_PROGRAMS += constraints +constraints_SOURCES = constraints.c + +# cttest +TESTS += cttest +check_PROGRAMS += cttest +cttest_SOURCES = cttest.c +cttest_CPPFLAGS = $(AM_CPPFLAGS) -DCTPATH=\"$(srcdir)\" +EXTRA_DIST += ctlog.conf +EXTRA_DIST += letsencrypt-r3.crt +EXTRA_DIST += libressl.org.crt + +# destest +TESTS += destest +check_PROGRAMS += destest +destest_SOURCES = destest.c + +# dhtest +TESTS += dhtest +check_PROGRAMS += dhtest +dhtest_SOURCES = dhtest.c + +# dsatest +TESTS += dsatest +check_PROGRAMS += dsatest +dsatest_SOURCES = dsatest.c + +# XXX this test is too flaky for CI. Disable it until it is fixed. +## dtlstest +#if !HOST_WIN +#TESTS += dtlstest.sh +#check_PROGRAMS += dtlstest +#dtlstest_SOURCES = dtlstest.c +#endif +#EXTRA_DIST += dtlstest.sh + +# ecc_cdh +TESTS += ecc_cdh +check_PROGRAMS += ecc_cdh +ecc_cdh_SOURCES = ecc_cdh.c + +# ec_asn1_test +TESTS += ec_asn1_test +check_PROGRAMS += ec_asn1_test +ec_asn1_test_SOURCES = ec_asn1_test.c + +# ec_point_conversion +TESTS += ec_point_conversion +check_PROGRAMS += ec_point_conversion +ec_point_conversion_SOURCES = ec_point_conversion.c + +# ecdhtest +TESTS += ecdhtest +check_PROGRAMS += ecdhtest +ecdhtest_SOURCES = ecdhtest.c + +# ecdsatest +TESTS += ecdsatest +check_PROGRAMS += ecdsatest +ecdsatest_SOURCES = ecdsatest.c + +# ectest +TESTS += ectest +check_PROGRAMS += ectest +ectest_SOURCES = ectest.c + +# ed25519test +TESTS += ed25519test +check_PROGRAMS += ed25519test +ed25519test_SOURCES = ed25519test.c + +# enginetest +TESTS += enginetest +check_PROGRAMS += enginetest +enginetest_SOURCES = enginetest.c + +# evp_ecx_test +TESTS += evp_ecx_test +check_PROGRAMS += evp_ecx_test +evp_ecx_test_SOURCES = evp_ecx_test.c + +# evp_pkey_check +TESTS += evp_pkey_check +check_PROGRAMS += evp_pkey_check +evp_pkey_check_SOURCES = evp_pkey_check.c + +# evp_pkey_cleanup +TESTS += evp_pkey_cleanup +check_PROGRAMS += evp_pkey_cleanup +evp_pkey_cleanup_SOURCES = evp_pkey_cleanup.c + +# evptest +TESTS += evptest.sh +check_PROGRAMS += evptest +evptest_SOURCES = evptest.c +EXTRA_DIST += evptest.sh +EXTRA_DIST += evptests.txt + +# evp_test +TESTS += evp_test +check_PROGRAMS += evp_test +evp_test_SOURCES = evp_test.c + +# expirecallback.c + +# explicit_bzero +# explicit_bzero relies on SA_ONSTACK, which is unavailable on Windows +if !HOST_WIN +if !HOST_CYGWIN +TESTS += explicit_bzero +check_PROGRAMS += explicit_bzero +explicit_bzero_SOURCES = explicit_bzero.c +if !HAVE_MEMMEM +explicit_bzero_SOURCES += compat/memmem.c +endif +endif +endif + +# exportertest +TESTS += exportertest +check_PROGRAMS += exportertest +exportertest_SOURCES = exportertest.c + +# freenull +TESTS += freenull +freenull_CPPFLAGS = $(AM_CPPFLAGS) -ULIBRESSL_INTERNAL +check_PROGRAMS += freenull +freenull_SOURCES = freenull.c + +# gcm128test +TESTS += gcm128test +check_PROGRAMS += gcm128test +gcm128test_SOURCES = gcm128test.c + +# gost2814789t +TESTS += gost2814789t +check_PROGRAMS += gost2814789t +gost2814789t_SOURCES = gost2814789t.c + +# handshake_table +TESTS += handshake_table +check_PROGRAMS += handshake_table +handshake_table_SOURCES = handshake_table.c + +# hkdf_test +TESTS += hkdftest +check_PROGRAMS += hkdftest +hkdftest_SOURCES = hkdf_test.c + +# hmactest +TESTS += hmactest +check_PROGRAMS += hmactest +hmactest_SOURCES = hmactest.c + +# ideatest +TESTS += ideatest +check_PROGRAMS += ideatest +ideatest_SOURCES = ideatest.c + +# igetest +TESTS += igetest +check_PROGRAMS += igetest +igetest_SOURCES = igetest.c + +# init_pledge.c + +# key_schedule +TESTS += key_schedule +check_PROGRAMS += key_schedule +key_schedule_SOURCES = key_schedule.c + +# keypairtest +TESTS += keypairtest.sh +keypairtest_CPPFLAGS = -I $(top_srcdir)/tls $(AM_CPPFLAGS) +check_PROGRAMS += keypairtest +keypairtest_SOURCES = keypairtest.c +EXTRA_DIST += keypairtest.sh + +# md_test +TESTS += md_test +check_PROGRAMS += md_test +md_test_SOURCES = md_test.c + +# objectstest +TESTS += objectstest +check_PROGRAMS += objectstest +objectstest_SOURCES = objectstest.c + +# ocsp_test +if ENABLE_EXTRATESTS +TESTS += ocsptest.sh +check_PROGRAMS += ocsp_test +ocsp_test_SOURCES = ocsp_test.c +endif +EXTRA_DIST += ocsptest.sh ocsptest.bat + +# optionstest +TESTS += optionstest +check_PROGRAMS += optionstest +optionstest_SOURCES = optionstest.c + +# pbkdf2 +TESTS += pbkdf2 +check_PROGRAMS += pbkdf2 +pbkdf2_SOURCES = pbkdf2.c + +# pidwraptest +# pidwraptest relies on an OS-specific way to give out pids and is generally +# awkward on systems with slow fork +if ENABLE_EXTRATESTS +TESTS += pidwraptest.sh +check_PROGRAMS += pidwraptest +pidwraptest_SOURCES = pidwraptest.c +endif +EXTRA_DIST += pidwraptest.sh + +# pkcs7test +TESTS += pkcs7test +check_PROGRAMS += pkcs7test +pkcs7test_SOURCES = pkcs7test.c + +# poly1305test +TESTS += poly1305test +check_PROGRAMS += poly1305test +poly1305test_SOURCES = poly1305test.c + +# policy +TESTS += policy +check_PROGRAMS += policy +policy_CPPFLAGS = $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +policy_SOURCES = policy.c +EXTRA_DIST += policy_intermediate.pem +EXTRA_DIST += policy_intermediate_any.pem +EXTRA_DIST += policy_intermediate_duplicate.pem +EXTRA_DIST += policy_intermediate_invalid.pem +EXTRA_DIST += policy_intermediate_mapped.pem +EXTRA_DIST += policy_intermediate_mapped_any.pem +EXTRA_DIST += policy_intermediate_mapped_oid3.pem +EXTRA_DIST += policy_intermediate_require.pem +EXTRA_DIST += policy_intermediate_require1.pem +EXTRA_DIST += policy_intermediate_require2.pem +EXTRA_DIST += policy_intermediate_require_duplicate.pem +EXTRA_DIST += policy_intermediate_require_no_policies.pem +EXTRA_DIST += policy_leaf.pem +EXTRA_DIST += policy_leaf_any.pem +EXTRA_DIST += policy_leaf_duplicate.pem +EXTRA_DIST += policy_leaf_invalid.pem +EXTRA_DIST += policy_leaf_none.pem +EXTRA_DIST += policy_leaf_oid1.pem +EXTRA_DIST += policy_leaf_oid2.pem +EXTRA_DIST += policy_leaf_oid3.pem +EXTRA_DIST += policy_leaf_oid4.pem +EXTRA_DIST += policy_leaf_oid5.pem +EXTRA_DIST += policy_leaf_require.pem +EXTRA_DIST += policy_leaf_require1.pem +EXTRA_DIST += policy_root.pem +EXTRA_DIST += policy_root2.pem +EXTRA_DIST += policy_root_cross_inhibit_mapping.pem + +# pq_test +TESTS += pq_test.sh +check_PROGRAMS += pq_test +pq_test_SOURCES = pq_test.c +EXTRA_DIST += pq_test.sh pq_test.bat +EXTRA_DIST += pq_expected.txt + +# quictest +TESTS += quictest.sh +check_PROGRAMS += quictest +quictest_SOURCES = quictest.c +EXTRA_DIST += quictest.sh quictest.bat + +# randtest +TESTS += randtest +check_PROGRAMS += randtest +randtest_SOURCES = randtest.c + +# rc2_test +TESTS += rc2_test +check_PROGRAMS += rc2_test +rc2_test_SOURCES = rc2_test.c + +# rc4_test +TESTS += rc4_test +check_PROGRAMS += rc4_test +rc4_test_SOURCES = rc4_test.c + +# recordtest +TESTS += recordtest +check_PROGRAMS += recordtest +recordtest_SOURCES = recordtest.c + +# record_layer_test +TESTS += record_layer_test +check_PROGRAMS += record_layer_test +record_layer_test_SOURCES = record_layer_test.c + +# rfc3779 +TESTS += rfc3779 +rfc3779_CPPFLAGS = $(AM_CPPFLAGS) +check_PROGRAMS += rfc3779 +rfc3779_SOURCES = rfc3779.c + +# rfc5280time +check_PROGRAMS += rfc5280time +rfc5280time_SOURCES = rfc5280time.c +if SMALL_TIME_T +TESTS += rfc5280time_small.test +else +TESTS += rfc5280time +endif +EXTRA_DIST += rfc5280time_small.test + +# rmd_test +TESTS += rmd_test +check_PROGRAMS += rmd_test +rmd_test_SOURCES = rmd_test.c + +# rsa_test +TESTS += rsa_test +check_PROGRAMS += rsa_test +rsa_test_SOURCES = rsa_test.c + +# server.c + +# servertest +TESTS += servertest.sh +check_PROGRAMS += servertest +servertest_SOURCES = servertest.c +EXTRA_DIST += servertest.sh servertest.bat + +# sha_test +TESTS += sha_test +check_PROGRAMS += sha_test +sha_test_SOURCES = sha_test.c + +# signertest +TESTS += signertest +check_PROGRAMS += signertest +signertest_CPPFLAGS = -I $(top_srcdir)/tls $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +signertest_SOURCES = signertest.c +if !HAVE_PIPE2 +signertest_SOURCES += compat/pipe2.c +endif + +# sm2crypttest +# sm2evptest +# sm2sigtest + +# sm3test +TESTS += sm3test +check_PROGRAMS += sm3test +sm3test_SOURCES = sm3test.c + +# sm4test +TESTS += sm4test +check_PROGRAMS += sm4test +sm4test_SOURCES = sm4test.c + +# ssl_get_shared_ciphers +TESTS += ssl_get_shared_ciphers +ssl_get_shared_ciphers_CPPFLAGS = $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +check_PROGRAMS += ssl_get_shared_ciphers +ssl_get_shared_ciphers_SOURCES = ssl_get_shared_ciphers.c + +# ssl_methods +TESTS += ssl_methods +check_PROGRAMS += ssl_methods +ssl_methods_SOURCES = ssl_methods.c + +# ssl_set_alpn_protos +TESTS += ssl_set_alpn_protos +check_PROGRAMS += ssl_set_alpn_protos +ssl_set_alpn_protos_SOURCES = ssl_set_alpn_protos.c + +# ssl_verify_param +TESTS += ssl_verify_param +check_PROGRAMS += ssl_verify_param +ssl_verify_param_SOURCES = ssl_verify_param.c + +# ssl_versions +TESTS += ssl_versions +check_PROGRAMS += ssl_versions +ssl_versions_SOURCES = ssl_versions.c + +# ssltest +TESTS += ssltest.sh +check_PROGRAMS += ssltest +ssltest_SOURCES = ssltest.c +EXTRA_DIST += ssltest.sh ssltest.bat +EXTRA_DIST += testssl testssl.bat +EXTRA_DIST += ca-int-ecdsa.crl ca-int-ecdsa.pem ca-int-rsa.crl ca-int-rsa.pem +EXTRA_DIST += ca-root-ecdsa.pem ca-root-rsa.pem ca.pem client.pem +EXTRA_DIST += client1-ecdsa-chain.pem client1-ecdsa.pem client1-rsa-chain.pem +EXTRA_DIST += client1-rsa.pem client2-ecdsa-chain.pem client2-ecdsa.pem +EXTRA_DIST += client2-rsa-chain.pem client2-rsa.pem client3-ecdsa-chain.pem +EXTRA_DIST += client3-ecdsa.pem client3-rsa-chain.pem client3-rsa.pem +EXTRA_DIST += server.pem server1-ecdsa-chain.pem server1-ecdsa.pem +EXTRA_DIST += server1-rsa-chain.pem server1-rsa.pem server2-ecdsa-chain.pem +EXTRA_DIST += server2-ecdsa.pem server2-rsa-chain.pem server2-rsa.pem +EXTRA_DIST += server3-ecdsa-chain.pem server3-ecdsa.pem server3-rsa-chain.pem +EXTRA_DIST += server3-rsa.pem + +# string_table +TESTS += string_table +check_PROGRAMS += string_table +string_table_SOURCES = string_table.c + +# testdsa +TESTS += testdsa.sh +EXTRA_DIST += testdsa.sh testdsa.bat +EXTRA_DIST += openssl.cnf + +# testenc +TESTS += testenc.sh +EXTRA_DIST += testenc.sh testenc.bat + +# testrsa +TESTS += testrsa.sh +EXTRA_DIST += testrsa.sh testrsa.bat + +# timingsafe +TESTS += timingsafe +check_PROGRAMS += timingsafe +timingsafe_SOURCES = timingsafe.c + +# tlsexttest +TESTS += tlsexttest +check_PROGRAMS += tlsexttest +tlsexttest_SOURCES = tlsexttest.c + +# tlslegacytest +TESTS += tlslegacytest +check_PROGRAMS += tlslegacytest +tlslegacytest_SOURCES = tlslegacytest.c + +# tlstest +TESTS += tlstest.sh +check_PROGRAMS += tlstest +tlstest_SOURCES = tlstest.c +if !HAVE_PIPE2 +tlstest_SOURCES += compat/pipe2.c +endif +EXTRA_DIST += tlstest.sh tlstest.bat + +# tls_ext_alpn +TESTS += tls_ext_alpn +check_PROGRAMS += tls_ext_alpn +tls_ext_alpn_SOURCES = tls_ext_alpn.c + +# tls_prf +TESTS += tls_prf +check_PROGRAMS += tls_prf +tls_prf_SOURCES = tls_prf.c + +# utf8test +TESTS += utf8test +check_PROGRAMS += utf8test +utf8test_SOURCES = utf8test.c + +# valid_handshakes_terminate +TESTS += valid_handshakes_terminate +check_PROGRAMS += valid_handshakes_terminate +valid_handshakes_terminate_SOURCES = valid_handshakes_terminate.c + +# verifytest +TESTS += verifytest +check_PROGRAMS += verifytest +verifytest_SOURCES = verifytest.c + +# x25519test +TESTS += x25519test +check_PROGRAMS += x25519test +x25519test_SOURCES = x25519test.c + +# x509attribute +TESTS += x509attribute +check_PROGRAMS += x509attribute +x509attribute_SOURCES = x509attribute.c + +# x509_asn1 +TESTS += x509_asn1 +check_PROGRAMS += x509_asn1 +x509_asn1_SOURCES = x509_asn1.c + +# x509_info +TESTS += x509_info +check_PROGRAMS += x509_info +x509_info_SOURCES = x509_info.c + +# x509name +TESTS += x509name +check_PROGRAMS += x509name +x509name_SOURCES = x509name.c + +# x509req_ext +TESTS += x509req_ext +check_PROGRAMS += x509req_ext +x509req_ext_SOURCES = x509req_ext.c diff --git a/Libraries/libressl/tests/Makefile.in b/Libraries/libressl/tests/Makefile.in new file mode 100644 index 000000000..75bca5a1b --- /dev/null +++ b/Libraries/libressl/tests/Makefile.in @@ -0,0 +1,4061 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = aeadtest.sh aes_test$(EXEEXT) aes_wrap$(EXEEXT) \ + apitest$(EXEEXT) $(am__append_1) asn1_string_to_utf8$(EXEEXT) \ + asn1api$(EXEEXT) asn1basic$(EXEEXT) asn1complex$(EXEEXT) \ + asn1evp$(EXEEXT) asn1object$(EXEEXT) asn1oct$(EXEEXT) \ + asn1string_copy$(EXEEXT) asn1test$(EXEEXT) asn1time$(EXEEXT) \ + asn1x509$(EXEEXT) base64test$(EXEEXT) bf_test$(EXEEXT) \ + bio_asn1$(EXEEXT) bio_chain$(EXEEXT) $(am__EXEEXT_2) \ + bio_mem$(EXEEXT) bn_add_sub$(EXEEXT) bn_cmp$(EXEEXT) \ + bn_convert$(EXEEXT) bn_gcd$(EXEEXT) bn_isqrt$(EXEEXT) \ + bn_mod_exp$(EXEEXT) bn_mod_inverse$(EXEEXT) \ + bn_mod_sqrt$(EXEEXT) bn_mont$(EXEEXT) bn_primes$(EXEEXT) \ + bn_print$(EXEEXT) bn_shift$(EXEEXT) bn_test$(EXEEXT) \ + bn_to_string$(EXEEXT) bn_unit$(EXEEXT) bn_word$(EXEEXT) \ + buffertest$(EXEEXT) bytestringtest$(EXEEXT) casttest$(EXEEXT) \ + chachatest$(EXEEXT) cipher_list$(EXEEXT) cipherstest$(EXEEXT) \ + clienttest$(EXEEXT) cmstest$(EXEEXT) configtest$(EXEEXT) \ + constraints$(EXEEXT) cttest$(EXEEXT) destest$(EXEEXT) \ + dhtest$(EXEEXT) dsatest$(EXEEXT) ecc_cdh$(EXEEXT) \ + ec_asn1_test$(EXEEXT) ec_point_conversion$(EXEEXT) \ + ecdhtest$(EXEEXT) ecdsatest$(EXEEXT) ectest$(EXEEXT) \ + ed25519test$(EXEEXT) enginetest$(EXEEXT) evp_ecx_test$(EXEEXT) \ + evp_pkey_check$(EXEEXT) evp_pkey_cleanup$(EXEEXT) evptest.sh \ + evp_test$(EXEEXT) $(am__EXEEXT_3) exportertest$(EXEEXT) \ + freenull$(EXEEXT) gcm128test$(EXEEXT) gost2814789t$(EXEEXT) \ + handshake_table$(EXEEXT) hkdftest$(EXEEXT) hmactest$(EXEEXT) \ + ideatest$(EXEEXT) igetest$(EXEEXT) key_schedule$(EXEEXT) \ + keypairtest.sh md_test$(EXEEXT) objectstest$(EXEEXT) \ + $(am__append_8) optionstest$(EXEEXT) pbkdf2$(EXEEXT) \ + $(am__append_10) pkcs7test$(EXEEXT) poly1305test$(EXEEXT) \ + policy$(EXEEXT) pq_test.sh quictest.sh randtest$(EXEEXT) \ + rc2_test$(EXEEXT) rc4_test$(EXEEXT) recordtest$(EXEEXT) \ + record_layer_test$(EXEEXT) rfc3779$(EXEEXT) $(am__append_12) \ + $(am__EXEEXT_6) rmd_test$(EXEEXT) rsa_test$(EXEEXT) \ + servertest.sh sha_test$(EXEEXT) signertest$(EXEEXT) \ + sm3test$(EXEEXT) sm4test$(EXEEXT) \ + ssl_get_shared_ciphers$(EXEEXT) ssl_methods$(EXEEXT) \ + ssl_set_alpn_protos$(EXEEXT) ssl_verify_param$(EXEEXT) \ + ssl_versions$(EXEEXT) ssltest.sh string_table$(EXEEXT) \ + testdsa.sh testenc.sh testrsa.sh timingsafe$(EXEEXT) \ + tlsexttest$(EXEEXT) tlslegacytest$(EXEEXT) tlstest.sh \ + tls_ext_alpn$(EXEEXT) tls_prf$(EXEEXT) utf8test$(EXEEXT) \ + valid_handshakes_terminate$(EXEEXT) verifytest$(EXEEXT) \ + x25519test$(EXEEXT) x509attribute$(EXEEXT) x509_asn1$(EXEEXT) \ + x509_info$(EXEEXT) x509name$(EXEEXT) x509req_ext$(EXEEXT) +check_PROGRAMS = aeadtest$(EXEEXT) aes_test$(EXEEXT) aes_wrap$(EXEEXT) \ + apitest$(EXEEXT) $(am__EXEEXT_1) asn1_string_to_utf8$(EXEEXT) \ + asn1api$(EXEEXT) asn1basic$(EXEEXT) asn1complex$(EXEEXT) \ + asn1evp$(EXEEXT) asn1object$(EXEEXT) asn1oct$(EXEEXT) \ + asn1string_copy$(EXEEXT) asn1test$(EXEEXT) asn1time$(EXEEXT) \ + asn1x509$(EXEEXT) base64test$(EXEEXT) bf_test$(EXEEXT) \ + bio_asn1$(EXEEXT) bio_chain$(EXEEXT) $(am__EXEEXT_2) \ + bio_mem$(EXEEXT) bn_add_sub$(EXEEXT) bn_cmp$(EXEEXT) \ + bn_convert$(EXEEXT) bn_gcd$(EXEEXT) bn_isqrt$(EXEEXT) \ + bn_mod_exp$(EXEEXT) bn_mod_inverse$(EXEEXT) \ + bn_mod_sqrt$(EXEEXT) bn_mont$(EXEEXT) bn_primes$(EXEEXT) \ + bn_print$(EXEEXT) bn_shift$(EXEEXT) bn_test$(EXEEXT) \ + bn_to_string$(EXEEXT) bn_unit$(EXEEXT) bn_word$(EXEEXT) \ + buffertest$(EXEEXT) bytestringtest$(EXEEXT) casttest$(EXEEXT) \ + chachatest$(EXEEXT) cipher_list$(EXEEXT) cipherstest$(EXEEXT) \ + clienttest$(EXEEXT) cmstest$(EXEEXT) configtest$(EXEEXT) \ + constraints$(EXEEXT) cttest$(EXEEXT) destest$(EXEEXT) \ + dhtest$(EXEEXT) dsatest$(EXEEXT) ecc_cdh$(EXEEXT) \ + ec_asn1_test$(EXEEXT) ec_point_conversion$(EXEEXT) \ + ecdhtest$(EXEEXT) ecdsatest$(EXEEXT) ectest$(EXEEXT) \ + ed25519test$(EXEEXT) enginetest$(EXEEXT) evp_ecx_test$(EXEEXT) \ + evp_pkey_check$(EXEEXT) evp_pkey_cleanup$(EXEEXT) \ + evptest$(EXEEXT) evp_test$(EXEEXT) $(am__EXEEXT_3) \ + exportertest$(EXEEXT) freenull$(EXEEXT) gcm128test$(EXEEXT) \ + gost2814789t$(EXEEXT) handshake_table$(EXEEXT) \ + hkdftest$(EXEEXT) hmactest$(EXEEXT) ideatest$(EXEEXT) \ + igetest$(EXEEXT) key_schedule$(EXEEXT) keypairtest$(EXEEXT) \ + md_test$(EXEEXT) objectstest$(EXEEXT) $(am__EXEEXT_4) \ + optionstest$(EXEEXT) pbkdf2$(EXEEXT) $(am__EXEEXT_5) \ + pkcs7test$(EXEEXT) poly1305test$(EXEEXT) policy$(EXEEXT) \ + pq_test$(EXEEXT) quictest$(EXEEXT) randtest$(EXEEXT) \ + rc2_test$(EXEEXT) rc4_test$(EXEEXT) recordtest$(EXEEXT) \ + record_layer_test$(EXEEXT) rfc3779$(EXEEXT) \ + rfc5280time$(EXEEXT) rmd_test$(EXEEXT) rsa_test$(EXEEXT) \ + servertest$(EXEEXT) sha_test$(EXEEXT) signertest$(EXEEXT) \ + sm3test$(EXEEXT) sm4test$(EXEEXT) \ + ssl_get_shared_ciphers$(EXEEXT) ssl_methods$(EXEEXT) \ + ssl_set_alpn_protos$(EXEEXT) ssl_verify_param$(EXEEXT) \ + ssl_versions$(EXEEXT) ssltest$(EXEEXT) string_table$(EXEEXT) \ + timingsafe$(EXEEXT) tlsexttest$(EXEEXT) tlslegacytest$(EXEEXT) \ + tlstest$(EXEEXT) tls_ext_alpn$(EXEEXT) tls_prf$(EXEEXT) \ + utf8test$(EXEEXT) valid_handshakes_terminate$(EXEEXT) \ + verifytest$(EXEEXT) x25519test$(EXEEXT) x509attribute$(EXEEXT) \ + x509_asn1$(EXEEXT) x509_info$(EXEEXT) x509name$(EXEEXT) \ + x509req_ext$(EXEEXT) + +# arc4randomforktest +# Windows/mingw does not have fork, but Cygwin does. +@HOST_WIN_FALSE@am__append_1 = arc4randomforktest.sh +@HOST_WIN_FALSE@am__append_2 = arc4randomforktest + +# bio_host +# this test relies on resolver results that are OS and environment-specific +@ENABLE_EXTRATESTS_TRUE@am__append_3 = bio_host +@ENABLE_EXTRATESTS_TRUE@am__append_4 = bio_host + +# expirecallback.c + +# explicit_bzero +# explicit_bzero relies on SA_ONSTACK, which is unavailable on Windows +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@am__append_5 = explicit_bzero +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@am__append_6 = explicit_bzero +@HAVE_MEMMEM_FALSE@@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@am__append_7 = compat/memmem.c + +# ocsp_test +@ENABLE_EXTRATESTS_TRUE@am__append_8 = ocsptest.sh +@ENABLE_EXTRATESTS_TRUE@am__append_9 = ocsp_test + +# pidwraptest +# pidwraptest relies on an OS-specific way to give out pids and is generally +# awkward on systems with slow fork +@ENABLE_EXTRATESTS_TRUE@am__append_10 = pidwraptest.sh +@ENABLE_EXTRATESTS_TRUE@am__append_11 = pidwraptest +@SMALL_TIME_T_TRUE@am__append_12 = rfc5280time_small.test +@SMALL_TIME_T_FALSE@am__append_13 = rfc5280time +@HAVE_PIPE2_FALSE@am__append_14 = compat/pipe2.c +@HAVE_PIPE2_FALSE@am__append_15 = compat/pipe2.c +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_add_fortify_source.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/check-hardening-options.m4 \ + $(top_srcdir)/m4/check-libc.m4 \ + $(top_srcdir)/m4/check-os-options.m4 \ + $(top_srcdir)/m4/disable-compiler-warnings.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@HOST_WIN_FALSE@am__EXEEXT_1 = arc4randomforktest$(EXEEXT) +@ENABLE_EXTRATESTS_TRUE@am__EXEEXT_2 = bio_host$(EXEEXT) +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@am__EXEEXT_3 = \ +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@ explicit_bzero$(EXEEXT) +@ENABLE_EXTRATESTS_TRUE@am__EXEEXT_4 = ocsp_test$(EXEEXT) +@ENABLE_EXTRATESTS_TRUE@am__EXEEXT_5 = pidwraptest$(EXEEXT) +LTLIBRARIES = $(noinst_LTLIBRARIES) +libtest_la_DEPENDENCIES = +am_libtest_la_OBJECTS = empty.lo +libtest_la_OBJECTS = $(am_libtest_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am_aeadtest_OBJECTS = aeadtest.$(OBJEXT) +aeadtest_OBJECTS = $(am_aeadtest_OBJECTS) +aeadtest_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +aeadtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_aes_test_OBJECTS = aes_test.$(OBJEXT) +aes_test_OBJECTS = $(am_aes_test_OBJECTS) +aes_test_LDADD = $(LDADD) +aes_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_aes_wrap_OBJECTS = aes_wrap.$(OBJEXT) +aes_wrap_OBJECTS = $(am_aes_wrap_OBJECTS) +aes_wrap_LDADD = $(LDADD) +aes_wrap_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_apitest_OBJECTS = apitest-apitest.$(OBJEXT) +apitest_OBJECTS = $(am_apitest_OBJECTS) +apitest_LDADD = $(LDADD) +apitest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__arc4randomforktest_SOURCES_DIST = arc4randomforktest.c +@HOST_WIN_FALSE@am_arc4randomforktest_OBJECTS = \ +@HOST_WIN_FALSE@ arc4randomforktest.$(OBJEXT) +arc4randomforktest_OBJECTS = $(am_arc4randomforktest_OBJECTS) +arc4randomforktest_LDADD = $(LDADD) +arc4randomforktest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1_string_to_utf8_OBJECTS = asn1_string_to_utf8.$(OBJEXT) +asn1_string_to_utf8_OBJECTS = $(am_asn1_string_to_utf8_OBJECTS) +asn1_string_to_utf8_LDADD = $(LDADD) +asn1_string_to_utf8_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1api_OBJECTS = asn1api.$(OBJEXT) +asn1api_OBJECTS = $(am_asn1api_OBJECTS) +asn1api_LDADD = $(LDADD) +asn1api_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1basic_OBJECTS = asn1basic.$(OBJEXT) +asn1basic_OBJECTS = $(am_asn1basic_OBJECTS) +asn1basic_LDADD = $(LDADD) +asn1basic_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1complex_OBJECTS = asn1complex.$(OBJEXT) +asn1complex_OBJECTS = $(am_asn1complex_OBJECTS) +asn1complex_LDADD = $(LDADD) +asn1complex_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1evp_OBJECTS = asn1evp.$(OBJEXT) +asn1evp_OBJECTS = $(am_asn1evp_OBJECTS) +asn1evp_LDADD = $(LDADD) +asn1evp_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1object_OBJECTS = asn1object.$(OBJEXT) +asn1object_OBJECTS = $(am_asn1object_OBJECTS) +asn1object_LDADD = $(LDADD) +asn1object_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1oct_OBJECTS = asn1oct.$(OBJEXT) +asn1oct_OBJECTS = $(am_asn1oct_OBJECTS) +asn1oct_LDADD = $(LDADD) +asn1oct_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1string_copy_OBJECTS = asn1string_copy.$(OBJEXT) +asn1string_copy_OBJECTS = $(am_asn1string_copy_OBJECTS) +asn1string_copy_LDADD = $(LDADD) +asn1string_copy_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1test_OBJECTS = asn1test.$(OBJEXT) +asn1test_OBJECTS = $(am_asn1test_OBJECTS) +asn1test_LDADD = $(LDADD) +asn1test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1time_OBJECTS = asn1time.$(OBJEXT) +asn1time_OBJECTS = $(am_asn1time_OBJECTS) +asn1time_LDADD = $(LDADD) +asn1time_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_asn1x509_OBJECTS = asn1x509.$(OBJEXT) +asn1x509_OBJECTS = $(am_asn1x509_OBJECTS) +asn1x509_LDADD = $(LDADD) +asn1x509_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_base64test_OBJECTS = base64test.$(OBJEXT) +base64test_OBJECTS = $(am_base64test_OBJECTS) +base64test_LDADD = $(LDADD) +base64test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bf_test_OBJECTS = bf_test.$(OBJEXT) +bf_test_OBJECTS = $(am_bf_test_OBJECTS) +bf_test_LDADD = $(LDADD) +bf_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bio_asn1_OBJECTS = bio_asn1.$(OBJEXT) +bio_asn1_OBJECTS = $(am_bio_asn1_OBJECTS) +bio_asn1_LDADD = $(LDADD) +bio_asn1_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bio_chain_OBJECTS = bio_chain.$(OBJEXT) +bio_chain_OBJECTS = $(am_bio_chain_OBJECTS) +bio_chain_LDADD = $(LDADD) +bio_chain_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__bio_host_SOURCES_DIST = bio_host.c +@ENABLE_EXTRATESTS_TRUE@am_bio_host_OBJECTS = bio_host.$(OBJEXT) +bio_host_OBJECTS = $(am_bio_host_OBJECTS) +bio_host_LDADD = $(LDADD) +bio_host_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bio_mem_OBJECTS = bio_mem.$(OBJEXT) +bio_mem_OBJECTS = $(am_bio_mem_OBJECTS) +bio_mem_LDADD = $(LDADD) +bio_mem_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_add_sub_OBJECTS = bn_add_sub.$(OBJEXT) +bn_add_sub_OBJECTS = $(am_bn_add_sub_OBJECTS) +bn_add_sub_LDADD = $(LDADD) +bn_add_sub_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_cmp_OBJECTS = bn_cmp.$(OBJEXT) +bn_cmp_OBJECTS = $(am_bn_cmp_OBJECTS) +bn_cmp_LDADD = $(LDADD) +bn_cmp_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_convert_OBJECTS = bn_convert.$(OBJEXT) +bn_convert_OBJECTS = $(am_bn_convert_OBJECTS) +bn_convert_LDADD = $(LDADD) +bn_convert_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_gcd_OBJECTS = bn_gcd.$(OBJEXT) +bn_gcd_OBJECTS = $(am_bn_gcd_OBJECTS) +bn_gcd_LDADD = $(LDADD) +bn_gcd_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_isqrt_OBJECTS = bn_isqrt.$(OBJEXT) +bn_isqrt_OBJECTS = $(am_bn_isqrt_OBJECTS) +bn_isqrt_LDADD = $(LDADD) +bn_isqrt_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_mod_exp_OBJECTS = bn_mod_exp-bn_mod_exp.$(OBJEXT) +bn_mod_exp_OBJECTS = $(am_bn_mod_exp_OBJECTS) +bn_mod_exp_LDADD = $(LDADD) +bn_mod_exp_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_mod_inverse_OBJECTS = bn_mod_inverse.$(OBJEXT) +bn_mod_inverse_OBJECTS = $(am_bn_mod_inverse_OBJECTS) +bn_mod_inverse_LDADD = $(LDADD) +bn_mod_inverse_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_mod_sqrt_OBJECTS = bn_mod_sqrt.$(OBJEXT) +bn_mod_sqrt_OBJECTS = $(am_bn_mod_sqrt_OBJECTS) +bn_mod_sqrt_LDADD = $(LDADD) +bn_mod_sqrt_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_mont_OBJECTS = bn_mont.$(OBJEXT) +bn_mont_OBJECTS = $(am_bn_mont_OBJECTS) +bn_mont_LDADD = $(LDADD) +bn_mont_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_primes_OBJECTS = bn_primes.$(OBJEXT) +bn_primes_OBJECTS = $(am_bn_primes_OBJECTS) +bn_primes_LDADD = $(LDADD) +bn_primes_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_print_OBJECTS = bn_print.$(OBJEXT) +bn_print_OBJECTS = $(am_bn_print_OBJECTS) +bn_print_LDADD = $(LDADD) +bn_print_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_shift_OBJECTS = bn_shift.$(OBJEXT) +bn_shift_OBJECTS = $(am_bn_shift_OBJECTS) +bn_shift_LDADD = $(LDADD) +bn_shift_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_test_OBJECTS = bn_test-bn_test.$(OBJEXT) +bn_test_OBJECTS = $(am_bn_test_OBJECTS) +bn_test_LDADD = $(LDADD) +bn_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_to_string_OBJECTS = bn_to_string.$(OBJEXT) +bn_to_string_OBJECTS = $(am_bn_to_string_OBJECTS) +bn_to_string_LDADD = $(LDADD) +bn_to_string_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_unit_OBJECTS = bn_unit.$(OBJEXT) +bn_unit_OBJECTS = $(am_bn_unit_OBJECTS) +bn_unit_LDADD = $(LDADD) +bn_unit_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bn_word_OBJECTS = bn_word.$(OBJEXT) +bn_word_OBJECTS = $(am_bn_word_OBJECTS) +bn_word_LDADD = $(LDADD) +bn_word_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_buffertest_OBJECTS = buffertest.$(OBJEXT) +buffertest_OBJECTS = $(am_buffertest_OBJECTS) +buffertest_LDADD = $(LDADD) +buffertest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_bytestringtest_OBJECTS = bytestringtest.$(OBJEXT) +bytestringtest_OBJECTS = $(am_bytestringtest_OBJECTS) +bytestringtest_LDADD = $(LDADD) +bytestringtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_casttest_OBJECTS = casttest.$(OBJEXT) +casttest_OBJECTS = $(am_casttest_OBJECTS) +casttest_LDADD = $(LDADD) +casttest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_chachatest_OBJECTS = chachatest.$(OBJEXT) +chachatest_OBJECTS = $(am_chachatest_OBJECTS) +chachatest_LDADD = $(LDADD) +chachatest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_cipher_list_OBJECTS = cipher_list.$(OBJEXT) +cipher_list_OBJECTS = $(am_cipher_list_OBJECTS) +cipher_list_LDADD = $(LDADD) +cipher_list_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_cipherstest_OBJECTS = cipherstest.$(OBJEXT) +cipherstest_OBJECTS = $(am_cipherstest_OBJECTS) +cipherstest_LDADD = $(LDADD) +cipherstest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_clienttest_OBJECTS = clienttest.$(OBJEXT) +clienttest_OBJECTS = $(am_clienttest_OBJECTS) +clienttest_LDADD = $(LDADD) +clienttest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_cmstest_OBJECTS = cmstest.$(OBJEXT) +cmstest_OBJECTS = $(am_cmstest_OBJECTS) +cmstest_LDADD = $(LDADD) +cmstest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_configtest_OBJECTS = configtest.$(OBJEXT) +configtest_OBJECTS = $(am_configtest_OBJECTS) +configtest_LDADD = $(LDADD) +configtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_constraints_OBJECTS = constraints.$(OBJEXT) +constraints_OBJECTS = $(am_constraints_OBJECTS) +constraints_LDADD = $(LDADD) +constraints_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_cttest_OBJECTS = cttest-cttest.$(OBJEXT) +cttest_OBJECTS = $(am_cttest_OBJECTS) +cttest_LDADD = $(LDADD) +cttest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_destest_OBJECTS = destest.$(OBJEXT) +destest_OBJECTS = $(am_destest_OBJECTS) +destest_LDADD = $(LDADD) +destest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_dhtest_OBJECTS = dhtest.$(OBJEXT) +dhtest_OBJECTS = $(am_dhtest_OBJECTS) +dhtest_LDADD = $(LDADD) +dhtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_dsatest_OBJECTS = dsatest.$(OBJEXT) +dsatest_OBJECTS = $(am_dsatest_OBJECTS) +dsatest_LDADD = $(LDADD) +dsatest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ec_asn1_test_OBJECTS = ec_asn1_test.$(OBJEXT) +ec_asn1_test_OBJECTS = $(am_ec_asn1_test_OBJECTS) +ec_asn1_test_LDADD = $(LDADD) +ec_asn1_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ec_point_conversion_OBJECTS = ec_point_conversion.$(OBJEXT) +ec_point_conversion_OBJECTS = $(am_ec_point_conversion_OBJECTS) +ec_point_conversion_LDADD = $(LDADD) +ec_point_conversion_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ecc_cdh_OBJECTS = ecc_cdh.$(OBJEXT) +ecc_cdh_OBJECTS = $(am_ecc_cdh_OBJECTS) +ecc_cdh_LDADD = $(LDADD) +ecc_cdh_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ecdhtest_OBJECTS = ecdhtest.$(OBJEXT) +ecdhtest_OBJECTS = $(am_ecdhtest_OBJECTS) +ecdhtest_LDADD = $(LDADD) +ecdhtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ecdsatest_OBJECTS = ecdsatest.$(OBJEXT) +ecdsatest_OBJECTS = $(am_ecdsatest_OBJECTS) +ecdsatest_LDADD = $(LDADD) +ecdsatest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ectest_OBJECTS = ectest.$(OBJEXT) +ectest_OBJECTS = $(am_ectest_OBJECTS) +ectest_LDADD = $(LDADD) +ectest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ed25519test_OBJECTS = ed25519test.$(OBJEXT) +ed25519test_OBJECTS = $(am_ed25519test_OBJECTS) +ed25519test_LDADD = $(LDADD) +ed25519test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_enginetest_OBJECTS = enginetest.$(OBJEXT) +enginetest_OBJECTS = $(am_enginetest_OBJECTS) +enginetest_LDADD = $(LDADD) +enginetest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_evp_ecx_test_OBJECTS = evp_ecx_test.$(OBJEXT) +evp_ecx_test_OBJECTS = $(am_evp_ecx_test_OBJECTS) +evp_ecx_test_LDADD = $(LDADD) +evp_ecx_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_evp_pkey_check_OBJECTS = evp_pkey_check.$(OBJEXT) +evp_pkey_check_OBJECTS = $(am_evp_pkey_check_OBJECTS) +evp_pkey_check_LDADD = $(LDADD) +evp_pkey_check_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_evp_pkey_cleanup_OBJECTS = evp_pkey_cleanup.$(OBJEXT) +evp_pkey_cleanup_OBJECTS = $(am_evp_pkey_cleanup_OBJECTS) +evp_pkey_cleanup_LDADD = $(LDADD) +evp_pkey_cleanup_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_evp_test_OBJECTS = evp_test.$(OBJEXT) +evp_test_OBJECTS = $(am_evp_test_OBJECTS) +evp_test_LDADD = $(LDADD) +evp_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_evptest_OBJECTS = evptest.$(OBJEXT) +evptest_OBJECTS = $(am_evptest_OBJECTS) +evptest_LDADD = $(LDADD) +evptest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__explicit_bzero_SOURCES_DIST = explicit_bzero.c compat/memmem.c +am__dirstamp = $(am__leading_dot)dirstamp +@HAVE_MEMMEM_FALSE@@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@am__objects_1 = compat/memmem.$(OBJEXT) +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@am_explicit_bzero_OBJECTS = \ +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@ explicit_bzero.$(OBJEXT) \ +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@ $(am__objects_1) +explicit_bzero_OBJECTS = $(am_explicit_bzero_OBJECTS) +explicit_bzero_LDADD = $(LDADD) +explicit_bzero_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_exportertest_OBJECTS = exportertest.$(OBJEXT) +exportertest_OBJECTS = $(am_exportertest_OBJECTS) +exportertest_LDADD = $(LDADD) +exportertest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_freenull_OBJECTS = freenull-freenull.$(OBJEXT) +freenull_OBJECTS = $(am_freenull_OBJECTS) +freenull_LDADD = $(LDADD) +freenull_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_gcm128test_OBJECTS = gcm128test.$(OBJEXT) +gcm128test_OBJECTS = $(am_gcm128test_OBJECTS) +gcm128test_LDADD = $(LDADD) +gcm128test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_gost2814789t_OBJECTS = gost2814789t.$(OBJEXT) +gost2814789t_OBJECTS = $(am_gost2814789t_OBJECTS) +gost2814789t_LDADD = $(LDADD) +gost2814789t_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_handshake_table_OBJECTS = handshake_table.$(OBJEXT) +handshake_table_OBJECTS = $(am_handshake_table_OBJECTS) +handshake_table_LDADD = $(LDADD) +handshake_table_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_hkdftest_OBJECTS = hkdf_test.$(OBJEXT) +hkdftest_OBJECTS = $(am_hkdftest_OBJECTS) +hkdftest_LDADD = $(LDADD) +hkdftest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_hmactest_OBJECTS = hmactest.$(OBJEXT) +hmactest_OBJECTS = $(am_hmactest_OBJECTS) +hmactest_LDADD = $(LDADD) +hmactest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ideatest_OBJECTS = ideatest.$(OBJEXT) +ideatest_OBJECTS = $(am_ideatest_OBJECTS) +ideatest_LDADD = $(LDADD) +ideatest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_igetest_OBJECTS = igetest.$(OBJEXT) +igetest_OBJECTS = $(am_igetest_OBJECTS) +igetest_LDADD = $(LDADD) +igetest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_key_schedule_OBJECTS = key_schedule.$(OBJEXT) +key_schedule_OBJECTS = $(am_key_schedule_OBJECTS) +key_schedule_LDADD = $(LDADD) +key_schedule_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_keypairtest_OBJECTS = keypairtest-keypairtest.$(OBJEXT) +keypairtest_OBJECTS = $(am_keypairtest_OBJECTS) +keypairtest_LDADD = $(LDADD) +keypairtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_md_test_OBJECTS = md_test.$(OBJEXT) +md_test_OBJECTS = $(am_md_test_OBJECTS) +md_test_LDADD = $(LDADD) +md_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_objectstest_OBJECTS = objectstest.$(OBJEXT) +objectstest_OBJECTS = $(am_objectstest_OBJECTS) +objectstest_LDADD = $(LDADD) +objectstest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__ocsp_test_SOURCES_DIST = ocsp_test.c +@ENABLE_EXTRATESTS_TRUE@am_ocsp_test_OBJECTS = ocsp_test.$(OBJEXT) +ocsp_test_OBJECTS = $(am_ocsp_test_OBJECTS) +ocsp_test_LDADD = $(LDADD) +ocsp_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_optionstest_OBJECTS = optionstest.$(OBJEXT) +optionstest_OBJECTS = $(am_optionstest_OBJECTS) +optionstest_LDADD = $(LDADD) +optionstest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_pbkdf2_OBJECTS = pbkdf2.$(OBJEXT) +pbkdf2_OBJECTS = $(am_pbkdf2_OBJECTS) +pbkdf2_LDADD = $(LDADD) +pbkdf2_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__pidwraptest_SOURCES_DIST = pidwraptest.c +@ENABLE_EXTRATESTS_TRUE@am_pidwraptest_OBJECTS = \ +@ENABLE_EXTRATESTS_TRUE@ pidwraptest.$(OBJEXT) +pidwraptest_OBJECTS = $(am_pidwraptest_OBJECTS) +pidwraptest_LDADD = $(LDADD) +pidwraptest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_pkcs7test_OBJECTS = pkcs7test.$(OBJEXT) +pkcs7test_OBJECTS = $(am_pkcs7test_OBJECTS) +pkcs7test_LDADD = $(LDADD) +pkcs7test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_policy_OBJECTS = policy-policy.$(OBJEXT) +policy_OBJECTS = $(am_policy_OBJECTS) +policy_LDADD = $(LDADD) +policy_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_poly1305test_OBJECTS = poly1305test.$(OBJEXT) +poly1305test_OBJECTS = $(am_poly1305test_OBJECTS) +poly1305test_LDADD = $(LDADD) +poly1305test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_pq_test_OBJECTS = pq_test.$(OBJEXT) +pq_test_OBJECTS = $(am_pq_test_OBJECTS) +pq_test_LDADD = $(LDADD) +pq_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_quictest_OBJECTS = quictest.$(OBJEXT) +quictest_OBJECTS = $(am_quictest_OBJECTS) +quictest_LDADD = $(LDADD) +quictest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_randtest_OBJECTS = randtest.$(OBJEXT) +randtest_OBJECTS = $(am_randtest_OBJECTS) +randtest_LDADD = $(LDADD) +randtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_rc2_test_OBJECTS = rc2_test.$(OBJEXT) +rc2_test_OBJECTS = $(am_rc2_test_OBJECTS) +rc2_test_LDADD = $(LDADD) +rc2_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_rc4_test_OBJECTS = rc4_test.$(OBJEXT) +rc4_test_OBJECTS = $(am_rc4_test_OBJECTS) +rc4_test_LDADD = $(LDADD) +rc4_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_record_layer_test_OBJECTS = record_layer_test.$(OBJEXT) +record_layer_test_OBJECTS = $(am_record_layer_test_OBJECTS) +record_layer_test_LDADD = $(LDADD) +record_layer_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_recordtest_OBJECTS = recordtest.$(OBJEXT) +recordtest_OBJECTS = $(am_recordtest_OBJECTS) +recordtest_LDADD = $(LDADD) +recordtest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_rfc3779_OBJECTS = rfc3779-rfc3779.$(OBJEXT) +rfc3779_OBJECTS = $(am_rfc3779_OBJECTS) +rfc3779_LDADD = $(LDADD) +rfc3779_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_rfc5280time_OBJECTS = rfc5280time.$(OBJEXT) +rfc5280time_OBJECTS = $(am_rfc5280time_OBJECTS) +rfc5280time_LDADD = $(LDADD) +rfc5280time_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_rmd_test_OBJECTS = rmd_test.$(OBJEXT) +rmd_test_OBJECTS = $(am_rmd_test_OBJECTS) +rmd_test_LDADD = $(LDADD) +rmd_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_rsa_test_OBJECTS = rsa_test.$(OBJEXT) +rsa_test_OBJECTS = $(am_rsa_test_OBJECTS) +rsa_test_LDADD = $(LDADD) +rsa_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_servertest_OBJECTS = servertest.$(OBJEXT) +servertest_OBJECTS = $(am_servertest_OBJECTS) +servertest_LDADD = $(LDADD) +servertest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_sha_test_OBJECTS = sha_test.$(OBJEXT) +sha_test_OBJECTS = $(am_sha_test_OBJECTS) +sha_test_LDADD = $(LDADD) +sha_test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__signertest_SOURCES_DIST = signertest.c compat/pipe2.c +@HAVE_PIPE2_FALSE@am__objects_2 = compat/signertest-pipe2.$(OBJEXT) +am_signertest_OBJECTS = signertest-signertest.$(OBJEXT) \ + $(am__objects_2) +signertest_OBJECTS = $(am_signertest_OBJECTS) +signertest_LDADD = $(LDADD) +signertest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_sm3test_OBJECTS = sm3test.$(OBJEXT) +sm3test_OBJECTS = $(am_sm3test_OBJECTS) +sm3test_LDADD = $(LDADD) +sm3test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_sm4test_OBJECTS = sm4test.$(OBJEXT) +sm4test_OBJECTS = $(am_sm4test_OBJECTS) +sm4test_LDADD = $(LDADD) +sm4test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ssl_get_shared_ciphers_OBJECTS = \ + ssl_get_shared_ciphers-ssl_get_shared_ciphers.$(OBJEXT) +ssl_get_shared_ciphers_OBJECTS = $(am_ssl_get_shared_ciphers_OBJECTS) +ssl_get_shared_ciphers_LDADD = $(LDADD) +ssl_get_shared_ciphers_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ssl_methods_OBJECTS = ssl_methods.$(OBJEXT) +ssl_methods_OBJECTS = $(am_ssl_methods_OBJECTS) +ssl_methods_LDADD = $(LDADD) +ssl_methods_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ssl_set_alpn_protos_OBJECTS = ssl_set_alpn_protos.$(OBJEXT) +ssl_set_alpn_protos_OBJECTS = $(am_ssl_set_alpn_protos_OBJECTS) +ssl_set_alpn_protos_LDADD = $(LDADD) +ssl_set_alpn_protos_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ssl_verify_param_OBJECTS = ssl_verify_param.$(OBJEXT) +ssl_verify_param_OBJECTS = $(am_ssl_verify_param_OBJECTS) +ssl_verify_param_LDADD = $(LDADD) +ssl_verify_param_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ssl_versions_OBJECTS = ssl_versions.$(OBJEXT) +ssl_versions_OBJECTS = $(am_ssl_versions_OBJECTS) +ssl_versions_LDADD = $(LDADD) +ssl_versions_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_ssltest_OBJECTS = ssltest.$(OBJEXT) +ssltest_OBJECTS = $(am_ssltest_OBJECTS) +ssltest_LDADD = $(LDADD) +ssltest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_string_table_OBJECTS = string_table.$(OBJEXT) +string_table_OBJECTS = $(am_string_table_OBJECTS) +string_table_LDADD = $(LDADD) +string_table_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_timingsafe_OBJECTS = timingsafe.$(OBJEXT) +timingsafe_OBJECTS = $(am_timingsafe_OBJECTS) +timingsafe_LDADD = $(LDADD) +timingsafe_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_tls_ext_alpn_OBJECTS = tls_ext_alpn.$(OBJEXT) +tls_ext_alpn_OBJECTS = $(am_tls_ext_alpn_OBJECTS) +tls_ext_alpn_LDADD = $(LDADD) +tls_ext_alpn_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_tls_prf_OBJECTS = tls_prf.$(OBJEXT) +tls_prf_OBJECTS = $(am_tls_prf_OBJECTS) +tls_prf_LDADD = $(LDADD) +tls_prf_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_tlsexttest_OBJECTS = tlsexttest.$(OBJEXT) +tlsexttest_OBJECTS = $(am_tlsexttest_OBJECTS) +tlsexttest_LDADD = $(LDADD) +tlsexttest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_tlslegacytest_OBJECTS = tlslegacytest.$(OBJEXT) +tlslegacytest_OBJECTS = $(am_tlslegacytest_OBJECTS) +tlslegacytest_LDADD = $(LDADD) +tlslegacytest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__tlstest_SOURCES_DIST = tlstest.c compat/pipe2.c +@HAVE_PIPE2_FALSE@am__objects_3 = compat/pipe2.$(OBJEXT) +am_tlstest_OBJECTS = tlstest.$(OBJEXT) $(am__objects_3) +tlstest_OBJECTS = $(am_tlstest_OBJECTS) +tlstest_LDADD = $(LDADD) +tlstest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_utf8test_OBJECTS = utf8test.$(OBJEXT) +utf8test_OBJECTS = $(am_utf8test_OBJECTS) +utf8test_LDADD = $(LDADD) +utf8test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_valid_handshakes_terminate_OBJECTS = \ + valid_handshakes_terminate.$(OBJEXT) +valid_handshakes_terminate_OBJECTS = \ + $(am_valid_handshakes_terminate_OBJECTS) +valid_handshakes_terminate_LDADD = $(LDADD) +valid_handshakes_terminate_DEPENDENCIES = libtest.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_verifytest_OBJECTS = verifytest.$(OBJEXT) +verifytest_OBJECTS = $(am_verifytest_OBJECTS) +verifytest_LDADD = $(LDADD) +verifytest_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_x25519test_OBJECTS = x25519test.$(OBJEXT) +x25519test_OBJECTS = $(am_x25519test_OBJECTS) +x25519test_LDADD = $(LDADD) +x25519test_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_x509_asn1_OBJECTS = x509_asn1.$(OBJEXT) +x509_asn1_OBJECTS = $(am_x509_asn1_OBJECTS) +x509_asn1_LDADD = $(LDADD) +x509_asn1_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_x509_info_OBJECTS = x509_info.$(OBJEXT) +x509_info_OBJECTS = $(am_x509_info_OBJECTS) +x509_info_LDADD = $(LDADD) +x509_info_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_x509attribute_OBJECTS = x509attribute.$(OBJEXT) +x509attribute_OBJECTS = $(am_x509attribute_OBJECTS) +x509attribute_LDADD = $(LDADD) +x509attribute_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_x509name_OBJECTS = x509name.$(OBJEXT) +x509name_OBJECTS = $(am_x509name_OBJECTS) +x509name_LDADD = $(LDADD) +x509name_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_x509req_ext_OBJECTS = x509req_ext.$(OBJEXT) +x509req_ext_OBJECTS = $(am_x509req_ext_OBJECTS) +x509req_ext_LDADD = $(LDADD) +x509req_ext_DEPENDENCIES = libtest.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/aeadtest.Po ./$(DEPDIR)/aes_test.Po \ + ./$(DEPDIR)/aes_wrap.Po ./$(DEPDIR)/apitest-apitest.Po \ + ./$(DEPDIR)/arc4randomforktest.Po \ + ./$(DEPDIR)/asn1_string_to_utf8.Po ./$(DEPDIR)/asn1api.Po \ + ./$(DEPDIR)/asn1basic.Po ./$(DEPDIR)/asn1complex.Po \ + ./$(DEPDIR)/asn1evp.Po ./$(DEPDIR)/asn1object.Po \ + ./$(DEPDIR)/asn1oct.Po ./$(DEPDIR)/asn1string_copy.Po \ + ./$(DEPDIR)/asn1test.Po ./$(DEPDIR)/asn1time.Po \ + ./$(DEPDIR)/asn1x509.Po ./$(DEPDIR)/base64test.Po \ + ./$(DEPDIR)/bf_test.Po ./$(DEPDIR)/bio_asn1.Po \ + ./$(DEPDIR)/bio_chain.Po ./$(DEPDIR)/bio_host.Po \ + ./$(DEPDIR)/bio_mem.Po ./$(DEPDIR)/bn_add_sub.Po \ + ./$(DEPDIR)/bn_cmp.Po ./$(DEPDIR)/bn_convert.Po \ + ./$(DEPDIR)/bn_gcd.Po ./$(DEPDIR)/bn_isqrt.Po \ + ./$(DEPDIR)/bn_mod_exp-bn_mod_exp.Po \ + ./$(DEPDIR)/bn_mod_inverse.Po ./$(DEPDIR)/bn_mod_sqrt.Po \ + ./$(DEPDIR)/bn_mont.Po ./$(DEPDIR)/bn_primes.Po \ + ./$(DEPDIR)/bn_print.Po ./$(DEPDIR)/bn_shift.Po \ + ./$(DEPDIR)/bn_test-bn_test.Po ./$(DEPDIR)/bn_to_string.Po \ + ./$(DEPDIR)/bn_unit.Po ./$(DEPDIR)/bn_word.Po \ + ./$(DEPDIR)/buffertest.Po ./$(DEPDIR)/bytestringtest.Po \ + ./$(DEPDIR)/casttest.Po ./$(DEPDIR)/chachatest.Po \ + ./$(DEPDIR)/cipher_list.Po ./$(DEPDIR)/cipherstest.Po \ + ./$(DEPDIR)/clienttest.Po ./$(DEPDIR)/cmstest.Po \ + ./$(DEPDIR)/configtest.Po ./$(DEPDIR)/constraints.Po \ + ./$(DEPDIR)/cttest-cttest.Po ./$(DEPDIR)/destest.Po \ + ./$(DEPDIR)/dhtest.Po ./$(DEPDIR)/dsatest.Po \ + ./$(DEPDIR)/ec_asn1_test.Po ./$(DEPDIR)/ec_point_conversion.Po \ + ./$(DEPDIR)/ecc_cdh.Po ./$(DEPDIR)/ecdhtest.Po \ + ./$(DEPDIR)/ecdsatest.Po ./$(DEPDIR)/ectest.Po \ + ./$(DEPDIR)/ed25519test.Po ./$(DEPDIR)/empty.Plo \ + ./$(DEPDIR)/enginetest.Po ./$(DEPDIR)/evp_ecx_test.Po \ + ./$(DEPDIR)/evp_pkey_check.Po ./$(DEPDIR)/evp_pkey_cleanup.Po \ + ./$(DEPDIR)/evp_test.Po ./$(DEPDIR)/evptest.Po \ + ./$(DEPDIR)/explicit_bzero.Po ./$(DEPDIR)/exportertest.Po \ + ./$(DEPDIR)/freenull-freenull.Po ./$(DEPDIR)/gcm128test.Po \ + ./$(DEPDIR)/gost2814789t.Po ./$(DEPDIR)/handshake_table.Po \ + ./$(DEPDIR)/hkdf_test.Po ./$(DEPDIR)/hmactest.Po \ + ./$(DEPDIR)/ideatest.Po ./$(DEPDIR)/igetest.Po \ + ./$(DEPDIR)/key_schedule.Po \ + ./$(DEPDIR)/keypairtest-keypairtest.Po ./$(DEPDIR)/md_test.Po \ + ./$(DEPDIR)/objectstest.Po ./$(DEPDIR)/ocsp_test.Po \ + ./$(DEPDIR)/optionstest.Po ./$(DEPDIR)/pbkdf2.Po \ + ./$(DEPDIR)/pidwraptest.Po ./$(DEPDIR)/pkcs7test.Po \ + ./$(DEPDIR)/policy-policy.Po ./$(DEPDIR)/poly1305test.Po \ + ./$(DEPDIR)/pq_test.Po ./$(DEPDIR)/quictest.Po \ + ./$(DEPDIR)/randtest.Po ./$(DEPDIR)/rc2_test.Po \ + ./$(DEPDIR)/rc4_test.Po ./$(DEPDIR)/record_layer_test.Po \ + ./$(DEPDIR)/recordtest.Po ./$(DEPDIR)/rfc3779-rfc3779.Po \ + ./$(DEPDIR)/rfc5280time.Po ./$(DEPDIR)/rmd_test.Po \ + ./$(DEPDIR)/rsa_test.Po ./$(DEPDIR)/servertest.Po \ + ./$(DEPDIR)/sha_test.Po ./$(DEPDIR)/signertest-signertest.Po \ + ./$(DEPDIR)/sm3test.Po ./$(DEPDIR)/sm4test.Po \ + ./$(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Po \ + ./$(DEPDIR)/ssl_methods.Po ./$(DEPDIR)/ssl_set_alpn_protos.Po \ + ./$(DEPDIR)/ssl_verify_param.Po ./$(DEPDIR)/ssl_versions.Po \ + ./$(DEPDIR)/ssltest.Po ./$(DEPDIR)/string_table.Po \ + ./$(DEPDIR)/timingsafe.Po ./$(DEPDIR)/tls_ext_alpn.Po \ + ./$(DEPDIR)/tls_prf.Po ./$(DEPDIR)/tlsexttest.Po \ + ./$(DEPDIR)/tlslegacytest.Po ./$(DEPDIR)/tlstest.Po \ + ./$(DEPDIR)/utf8test.Po \ + ./$(DEPDIR)/valid_handshakes_terminate.Po \ + ./$(DEPDIR)/verifytest.Po ./$(DEPDIR)/x25519test.Po \ + ./$(DEPDIR)/x509_asn1.Po ./$(DEPDIR)/x509_info.Po \ + ./$(DEPDIR)/x509attribute.Po ./$(DEPDIR)/x509name.Po \ + ./$(DEPDIR)/x509req_ext.Po compat/$(DEPDIR)/memmem.Po \ + compat/$(DEPDIR)/pipe2.Po compat/$(DEPDIR)/signertest-pipe2.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtest_la_SOURCES) $(aeadtest_SOURCES) \ + $(aes_test_SOURCES) $(aes_wrap_SOURCES) $(apitest_SOURCES) \ + $(arc4randomforktest_SOURCES) $(asn1_string_to_utf8_SOURCES) \ + $(asn1api_SOURCES) $(asn1basic_SOURCES) $(asn1complex_SOURCES) \ + $(asn1evp_SOURCES) $(asn1object_SOURCES) $(asn1oct_SOURCES) \ + $(asn1string_copy_SOURCES) $(asn1test_SOURCES) \ + $(asn1time_SOURCES) $(asn1x509_SOURCES) $(base64test_SOURCES) \ + $(bf_test_SOURCES) $(bio_asn1_SOURCES) $(bio_chain_SOURCES) \ + $(bio_host_SOURCES) $(bio_mem_SOURCES) $(bn_add_sub_SOURCES) \ + $(bn_cmp_SOURCES) $(bn_convert_SOURCES) $(bn_gcd_SOURCES) \ + $(bn_isqrt_SOURCES) $(bn_mod_exp_SOURCES) \ + $(bn_mod_inverse_SOURCES) $(bn_mod_sqrt_SOURCES) \ + $(bn_mont_SOURCES) $(bn_primes_SOURCES) $(bn_print_SOURCES) \ + $(bn_shift_SOURCES) $(bn_test_SOURCES) $(bn_to_string_SOURCES) \ + $(bn_unit_SOURCES) $(bn_word_SOURCES) $(buffertest_SOURCES) \ + $(bytestringtest_SOURCES) $(casttest_SOURCES) \ + $(chachatest_SOURCES) $(cipher_list_SOURCES) \ + $(cipherstest_SOURCES) $(clienttest_SOURCES) \ + $(cmstest_SOURCES) $(configtest_SOURCES) \ + $(constraints_SOURCES) $(cttest_SOURCES) $(destest_SOURCES) \ + $(dhtest_SOURCES) $(dsatest_SOURCES) $(ec_asn1_test_SOURCES) \ + $(ec_point_conversion_SOURCES) $(ecc_cdh_SOURCES) \ + $(ecdhtest_SOURCES) $(ecdsatest_SOURCES) $(ectest_SOURCES) \ + $(ed25519test_SOURCES) $(enginetest_SOURCES) \ + $(evp_ecx_test_SOURCES) $(evp_pkey_check_SOURCES) \ + $(evp_pkey_cleanup_SOURCES) $(evp_test_SOURCES) \ + $(evptest_SOURCES) $(explicit_bzero_SOURCES) \ + $(exportertest_SOURCES) $(freenull_SOURCES) \ + $(gcm128test_SOURCES) $(gost2814789t_SOURCES) \ + $(handshake_table_SOURCES) $(hkdftest_SOURCES) \ + $(hmactest_SOURCES) $(ideatest_SOURCES) $(igetest_SOURCES) \ + $(key_schedule_SOURCES) $(keypairtest_SOURCES) \ + $(md_test_SOURCES) $(objectstest_SOURCES) $(ocsp_test_SOURCES) \ + $(optionstest_SOURCES) $(pbkdf2_SOURCES) \ + $(pidwraptest_SOURCES) $(pkcs7test_SOURCES) $(policy_SOURCES) \ + $(poly1305test_SOURCES) $(pq_test_SOURCES) $(quictest_SOURCES) \ + $(randtest_SOURCES) $(rc2_test_SOURCES) $(rc4_test_SOURCES) \ + $(record_layer_test_SOURCES) $(recordtest_SOURCES) \ + $(rfc3779_SOURCES) $(rfc5280time_SOURCES) $(rmd_test_SOURCES) \ + $(rsa_test_SOURCES) $(servertest_SOURCES) $(sha_test_SOURCES) \ + $(signertest_SOURCES) $(sm3test_SOURCES) $(sm4test_SOURCES) \ + $(ssl_get_shared_ciphers_SOURCES) $(ssl_methods_SOURCES) \ + $(ssl_set_alpn_protos_SOURCES) $(ssl_verify_param_SOURCES) \ + $(ssl_versions_SOURCES) $(ssltest_SOURCES) \ + $(string_table_SOURCES) $(timingsafe_SOURCES) \ + $(tls_ext_alpn_SOURCES) $(tls_prf_SOURCES) \ + $(tlsexttest_SOURCES) $(tlslegacytest_SOURCES) \ + $(tlstest_SOURCES) $(utf8test_SOURCES) \ + $(valid_handshakes_terminate_SOURCES) $(verifytest_SOURCES) \ + $(x25519test_SOURCES) $(x509_asn1_SOURCES) \ + $(x509_info_SOURCES) $(x509attribute_SOURCES) \ + $(x509name_SOURCES) $(x509req_ext_SOURCES) +DIST_SOURCES = $(libtest_la_SOURCES) $(aeadtest_SOURCES) \ + $(aes_test_SOURCES) $(aes_wrap_SOURCES) $(apitest_SOURCES) \ + $(am__arc4randomforktest_SOURCES_DIST) \ + $(asn1_string_to_utf8_SOURCES) $(asn1api_SOURCES) \ + $(asn1basic_SOURCES) $(asn1complex_SOURCES) $(asn1evp_SOURCES) \ + $(asn1object_SOURCES) $(asn1oct_SOURCES) \ + $(asn1string_copy_SOURCES) $(asn1test_SOURCES) \ + $(asn1time_SOURCES) $(asn1x509_SOURCES) $(base64test_SOURCES) \ + $(bf_test_SOURCES) $(bio_asn1_SOURCES) $(bio_chain_SOURCES) \ + $(am__bio_host_SOURCES_DIST) $(bio_mem_SOURCES) \ + $(bn_add_sub_SOURCES) $(bn_cmp_SOURCES) $(bn_convert_SOURCES) \ + $(bn_gcd_SOURCES) $(bn_isqrt_SOURCES) $(bn_mod_exp_SOURCES) \ + $(bn_mod_inverse_SOURCES) $(bn_mod_sqrt_SOURCES) \ + $(bn_mont_SOURCES) $(bn_primes_SOURCES) $(bn_print_SOURCES) \ + $(bn_shift_SOURCES) $(bn_test_SOURCES) $(bn_to_string_SOURCES) \ + $(bn_unit_SOURCES) $(bn_word_SOURCES) $(buffertest_SOURCES) \ + $(bytestringtest_SOURCES) $(casttest_SOURCES) \ + $(chachatest_SOURCES) $(cipher_list_SOURCES) \ + $(cipherstest_SOURCES) $(clienttest_SOURCES) \ + $(cmstest_SOURCES) $(configtest_SOURCES) \ + $(constraints_SOURCES) $(cttest_SOURCES) $(destest_SOURCES) \ + $(dhtest_SOURCES) $(dsatest_SOURCES) $(ec_asn1_test_SOURCES) \ + $(ec_point_conversion_SOURCES) $(ecc_cdh_SOURCES) \ + $(ecdhtest_SOURCES) $(ecdsatest_SOURCES) $(ectest_SOURCES) \ + $(ed25519test_SOURCES) $(enginetest_SOURCES) \ + $(evp_ecx_test_SOURCES) $(evp_pkey_check_SOURCES) \ + $(evp_pkey_cleanup_SOURCES) $(evp_test_SOURCES) \ + $(evptest_SOURCES) $(am__explicit_bzero_SOURCES_DIST) \ + $(exportertest_SOURCES) $(freenull_SOURCES) \ + $(gcm128test_SOURCES) $(gost2814789t_SOURCES) \ + $(handshake_table_SOURCES) $(hkdftest_SOURCES) \ + $(hmactest_SOURCES) $(ideatest_SOURCES) $(igetest_SOURCES) \ + $(key_schedule_SOURCES) $(keypairtest_SOURCES) \ + $(md_test_SOURCES) $(objectstest_SOURCES) \ + $(am__ocsp_test_SOURCES_DIST) $(optionstest_SOURCES) \ + $(pbkdf2_SOURCES) $(am__pidwraptest_SOURCES_DIST) \ + $(pkcs7test_SOURCES) $(policy_SOURCES) $(poly1305test_SOURCES) \ + $(pq_test_SOURCES) $(quictest_SOURCES) $(randtest_SOURCES) \ + $(rc2_test_SOURCES) $(rc4_test_SOURCES) \ + $(record_layer_test_SOURCES) $(recordtest_SOURCES) \ + $(rfc3779_SOURCES) $(rfc5280time_SOURCES) $(rmd_test_SOURCES) \ + $(rsa_test_SOURCES) $(servertest_SOURCES) $(sha_test_SOURCES) \ + $(am__signertest_SOURCES_DIST) $(sm3test_SOURCES) \ + $(sm4test_SOURCES) $(ssl_get_shared_ciphers_SOURCES) \ + $(ssl_methods_SOURCES) $(ssl_set_alpn_protos_SOURCES) \ + $(ssl_verify_param_SOURCES) $(ssl_versions_SOURCES) \ + $(ssltest_SOURCES) $(string_table_SOURCES) \ + $(timingsafe_SOURCES) $(tls_ext_alpn_SOURCES) \ + $(tls_prf_SOURCES) $(tlsexttest_SOURCES) \ + $(tlslegacytest_SOURCES) $(am__tlstest_SOURCES_DIST) \ + $(utf8test_SOURCES) $(valid_handshakes_terminate_SOURCES) \ + $(verifytest_SOURCES) $(x25519test_SOURCES) \ + $(x509_asn1_SOURCES) $(x509_info_SOURCES) \ + $(x509attribute_SOURCES) $(x509name_SOURCES) \ + $(x509req_ext_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +@SMALL_TIME_T_FALSE@am__EXEEXT_6 = rfc5280time$(EXEEXT) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.common $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTO_VERSION = @LIBCRYPTO_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSL_VERSION = @LIBSSL_VERSION@ +LIBTLS_VERSION = @LIBTLS_VERSION@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSLDIR = @OPENSSLDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_LDADD = @PLATFORM_LDADD@ +PROG_LDADD = @PROG_LDADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(abs_top_builddir)/include \ + -I$(top_srcdir)/include/compat -DLIBRESSL_INTERNAL \ + -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= \ + -DLIBRESSL_CRYPTO_INTERNAL -I $(top_srcdir)/crypto/asn1 -I \ + $(top_srcdir)/crypto/bio -I $(top_srcdir)/crypto/bn -I \ + $(top_srcdir)/crypto/curve25519 -I $(top_srcdir)/crypto/evp -I \ + $(top_srcdir)/crypto/modes -I $(top_srcdir)/crypto/x509 -I \ + $(top_srcdir)/ssl -I $(top_srcdir)/apps/openssl -I \ + $(top_srcdir)/apps/openssl/compat \ + -D_PATH_SSL_CA_FILE=\"$(top_srcdir)/cert.pem\" +noinst_LTLIBRARIES = libtest.la +libtest_la_LIBADD = $(libcrypto_la_objects) $(libcompat_la_objects) \ + $(libcompatnoopt_la_objects) $(libssl_la_objects) \ + $(libtls_la_objects) +libtest_la_SOURCES = empty.c +LDADD = libtest.la $(PLATFORM_LDADD) $(PROG_LDADD) +TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh +EXTRA_DIST = CMakeLists.txt aeadtest.sh aeadtests.txt \ + aes_128_gcm_tests.txt aes_192_gcm_tests.txt \ + aes_256_gcm_tests.txt chacha20_poly1305_tests.txt \ + xchacha20_poly1305_tests.txt arc4randomforktest.sh ctlog.conf \ + letsencrypt-r3.crt libressl.org.crt evptest.sh evptests.txt \ + keypairtest.sh ocsptest.sh ocsptest.bat pidwraptest.sh \ + policy_intermediate.pem policy_intermediate_any.pem \ + policy_intermediate_duplicate.pem \ + policy_intermediate_invalid.pem policy_intermediate_mapped.pem \ + policy_intermediate_mapped_any.pem \ + policy_intermediate_mapped_oid3.pem \ + policy_intermediate_require.pem \ + policy_intermediate_require1.pem \ + policy_intermediate_require2.pem \ + policy_intermediate_require_duplicate.pem \ + policy_intermediate_require_no_policies.pem policy_leaf.pem \ + policy_leaf_any.pem policy_leaf_duplicate.pem \ + policy_leaf_invalid.pem policy_leaf_none.pem \ + policy_leaf_oid1.pem policy_leaf_oid2.pem policy_leaf_oid3.pem \ + policy_leaf_oid4.pem policy_leaf_oid5.pem \ + policy_leaf_require.pem policy_leaf_require1.pem \ + policy_root.pem policy_root2.pem \ + policy_root_cross_inhibit_mapping.pem pq_test.sh pq_test.bat \ + pq_expected.txt quictest.sh quictest.bat \ + rfc5280time_small.test servertest.sh servertest.bat ssltest.sh \ + ssltest.bat testssl testssl.bat ca-int-ecdsa.crl \ + ca-int-ecdsa.pem ca-int-rsa.crl ca-int-rsa.pem \ + ca-root-ecdsa.pem ca-root-rsa.pem ca.pem client.pem \ + client1-ecdsa-chain.pem client1-ecdsa.pem \ + client1-rsa-chain.pem client1-rsa.pem client2-ecdsa-chain.pem \ + client2-ecdsa.pem client2-rsa-chain.pem client2-rsa.pem \ + client3-ecdsa-chain.pem client3-ecdsa.pem \ + client3-rsa-chain.pem client3-rsa.pem server.pem \ + server1-ecdsa-chain.pem server1-ecdsa.pem \ + server1-rsa-chain.pem server1-rsa.pem server2-ecdsa-chain.pem \ + server2-ecdsa.pem server2-rsa-chain.pem server2-rsa.pem \ + server3-ecdsa-chain.pem server3-ecdsa.pem \ + server3-rsa-chain.pem server3-rsa.pem testdsa.sh testdsa.bat \ + openssl.cnf testenc.sh testenc.bat testrsa.sh testrsa.bat \ + tlstest.sh tlstest.bat +DISTCLEANFILES = pidwraptest.txt +aeadtest_SOURCES = aeadtest.c +aes_test_SOURCES = aes_test.c +aes_wrap_SOURCES = aes_wrap.c +apitest_SOURCES = apitest.c +apitest_CPPFLAGS = $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +@HOST_WIN_FALSE@arc4randomforktest_SOURCES = arc4randomforktest.c +asn1_string_to_utf8_SOURCES = asn1_string_to_utf8.c +asn1api_SOURCES = asn1api.c +asn1basic_SOURCES = asn1basic.c +asn1complex_SOURCES = asn1complex.c +asn1evp_SOURCES = asn1evp.c +asn1object_SOURCES = asn1object.c +asn1oct_SOURCES = asn1oct.c +asn1string_copy_SOURCES = asn1string_copy.c +asn1test_SOURCES = asn1test.c +asn1time_SOURCES = asn1time.c +asn1x509_SOURCES = asn1x509.c +base64test_SOURCES = base64test.c +bf_test_SOURCES = bf_test.c +bio_asn1_SOURCES = bio_asn1.c +bio_chain_SOURCES = bio_chain.c +@ENABLE_EXTRATESTS_TRUE@bio_host_SOURCES = bio_host.c +bio_mem_SOURCES = bio_mem.c +bn_add_sub_SOURCES = bn_add_sub.c +bn_cmp_SOURCES = bn_cmp.c +bn_convert_SOURCES = bn_convert.c +bn_gcd_SOURCES = bn_gcd.c +bn_isqrt_SOURCES = bn_isqrt.c +bn_mod_exp_CPPFLAGS = $(AM_CPPFLAGS) -ULIBRESSL_INTERNAL +bn_mod_exp_SOURCES = bn_mod_exp.c +bn_mod_inverse_SOURCES = bn_mod_inverse.c +bn_mod_sqrt_SOURCES = bn_mod_sqrt.c +bn_mont_SOURCES = bn_mont.c +bn_primes_SOURCES = bn_primes.c +bn_print_SOURCES = bn_print.c +bn_shift_SOURCES = bn_shift.c +bn_test_CPPFLAGS = $(AM_CPPFLAGS) -ULIBRESSL_INTERNAL +bn_test_SOURCES = bn_test.c +bn_to_string_SOURCES = bn_to_string.c +bn_unit_SOURCES = bn_unit.c +bn_word_SOURCES = bn_word.c +buffertest_SOURCES = buffertest.c +bytestringtest_SOURCES = bytestringtest.c +casttest_SOURCES = casttest.c +chachatest_SOURCES = chachatest.c +cipher_list_SOURCES = cipher_list.c +noinst_HEADERS = tests.h +cipherstest_SOURCES = cipherstest.c +clienttest_SOURCES = clienttest.c +cmstest_SOURCES = cmstest.c +configtest_SOURCES = configtest.c +constraints_SOURCES = constraints.c +cttest_SOURCES = cttest.c +cttest_CPPFLAGS = $(AM_CPPFLAGS) -DCTPATH=\"$(srcdir)\" +destest_SOURCES = destest.c +dhtest_SOURCES = dhtest.c +dsatest_SOURCES = dsatest.c +ecc_cdh_SOURCES = ecc_cdh.c +ec_asn1_test_SOURCES = ec_asn1_test.c +ec_point_conversion_SOURCES = ec_point_conversion.c +ecdhtest_SOURCES = ecdhtest.c +ecdsatest_SOURCES = ecdsatest.c +ectest_SOURCES = ectest.c +ed25519test_SOURCES = ed25519test.c +enginetest_SOURCES = enginetest.c +evp_ecx_test_SOURCES = evp_ecx_test.c +evp_pkey_check_SOURCES = evp_pkey_check.c +evp_pkey_cleanup_SOURCES = evp_pkey_cleanup.c +evptest_SOURCES = evptest.c +evp_test_SOURCES = evp_test.c +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@explicit_bzero_SOURCES = \ +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@ explicit_bzero.c \ +@HOST_CYGWIN_FALSE@@HOST_WIN_FALSE@ $(am__append_7) +exportertest_SOURCES = exportertest.c +freenull_CPPFLAGS = $(AM_CPPFLAGS) -ULIBRESSL_INTERNAL +freenull_SOURCES = freenull.c +gcm128test_SOURCES = gcm128test.c +gost2814789t_SOURCES = gost2814789t.c +handshake_table_SOURCES = handshake_table.c +hkdftest_SOURCES = hkdf_test.c +hmactest_SOURCES = hmactest.c +ideatest_SOURCES = ideatest.c +igetest_SOURCES = igetest.c +key_schedule_SOURCES = key_schedule.c +keypairtest_CPPFLAGS = -I $(top_srcdir)/tls $(AM_CPPFLAGS) +keypairtest_SOURCES = keypairtest.c +md_test_SOURCES = md_test.c +objectstest_SOURCES = objectstest.c +@ENABLE_EXTRATESTS_TRUE@ocsp_test_SOURCES = ocsp_test.c +optionstest_SOURCES = optionstest.c +pbkdf2_SOURCES = pbkdf2.c +@ENABLE_EXTRATESTS_TRUE@pidwraptest_SOURCES = pidwraptest.c +pkcs7test_SOURCES = pkcs7test.c +poly1305test_SOURCES = poly1305test.c +policy_CPPFLAGS = $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +policy_SOURCES = policy.c +pq_test_SOURCES = pq_test.c +quictest_SOURCES = quictest.c +randtest_SOURCES = randtest.c +rc2_test_SOURCES = rc2_test.c +rc4_test_SOURCES = rc4_test.c +recordtest_SOURCES = recordtest.c +record_layer_test_SOURCES = record_layer_test.c +rfc3779_CPPFLAGS = $(AM_CPPFLAGS) +rfc3779_SOURCES = rfc3779.c +rfc5280time_SOURCES = rfc5280time.c +rmd_test_SOURCES = rmd_test.c +rsa_test_SOURCES = rsa_test.c +servertest_SOURCES = servertest.c +sha_test_SOURCES = sha_test.c +signertest_CPPFLAGS = -I $(top_srcdir)/tls $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +signertest_SOURCES = signertest.c $(am__append_14) +sm3test_SOURCES = sm3test.c +sm4test_SOURCES = sm4test.c +ssl_get_shared_ciphers_CPPFLAGS = $(AM_CPPFLAGS) -DCERTSDIR=\"$(srcdir)\" +ssl_get_shared_ciphers_SOURCES = ssl_get_shared_ciphers.c +ssl_methods_SOURCES = ssl_methods.c +ssl_set_alpn_protos_SOURCES = ssl_set_alpn_protos.c +ssl_verify_param_SOURCES = ssl_verify_param.c +ssl_versions_SOURCES = ssl_versions.c +ssltest_SOURCES = ssltest.c +string_table_SOURCES = string_table.c +timingsafe_SOURCES = timingsafe.c +tlsexttest_SOURCES = tlsexttest.c +tlslegacytest_SOURCES = tlslegacytest.c +tlstest_SOURCES = tlstest.c $(am__append_15) +tls_ext_alpn_SOURCES = tls_ext_alpn.c +tls_prf_SOURCES = tls_prf.c +utf8test_SOURCES = utf8test.c +valid_handshakes_terminate_SOURCES = valid_handshakes_terminate.c +verifytest_SOURCES = verifytest.c +x25519test_SOURCES = x25519test.c +x509attribute_SOURCES = x509attribute.c +x509_asn1_SOURCES = x509_asn1.c +x509_info_SOURCES = x509_info.c +x509name_SOURCES = x509name.c +x509req_ext_SOURCES = x509req_ext.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.am.common $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libtest.la: $(libtest_la_OBJECTS) $(libtest_la_DEPENDENCIES) $(EXTRA_libtest_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libtest_la_OBJECTS) $(libtest_la_LIBADD) $(LIBS) + +aeadtest$(EXEEXT): $(aeadtest_OBJECTS) $(aeadtest_DEPENDENCIES) $(EXTRA_aeadtest_DEPENDENCIES) + @rm -f aeadtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(aeadtest_OBJECTS) $(aeadtest_LDADD) $(LIBS) + +aes_test$(EXEEXT): $(aes_test_OBJECTS) $(aes_test_DEPENDENCIES) $(EXTRA_aes_test_DEPENDENCIES) + @rm -f aes_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(aes_test_OBJECTS) $(aes_test_LDADD) $(LIBS) + +aes_wrap$(EXEEXT): $(aes_wrap_OBJECTS) $(aes_wrap_DEPENDENCIES) $(EXTRA_aes_wrap_DEPENDENCIES) + @rm -f aes_wrap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(aes_wrap_OBJECTS) $(aes_wrap_LDADD) $(LIBS) + +apitest$(EXEEXT): $(apitest_OBJECTS) $(apitest_DEPENDENCIES) $(EXTRA_apitest_DEPENDENCIES) + @rm -f apitest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(apitest_OBJECTS) $(apitest_LDADD) $(LIBS) + +arc4randomforktest$(EXEEXT): $(arc4randomforktest_OBJECTS) $(arc4randomforktest_DEPENDENCIES) $(EXTRA_arc4randomforktest_DEPENDENCIES) + @rm -f arc4randomforktest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(arc4randomforktest_OBJECTS) $(arc4randomforktest_LDADD) $(LIBS) + +asn1_string_to_utf8$(EXEEXT): $(asn1_string_to_utf8_OBJECTS) $(asn1_string_to_utf8_DEPENDENCIES) $(EXTRA_asn1_string_to_utf8_DEPENDENCIES) + @rm -f asn1_string_to_utf8$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1_string_to_utf8_OBJECTS) $(asn1_string_to_utf8_LDADD) $(LIBS) + +asn1api$(EXEEXT): $(asn1api_OBJECTS) $(asn1api_DEPENDENCIES) $(EXTRA_asn1api_DEPENDENCIES) + @rm -f asn1api$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1api_OBJECTS) $(asn1api_LDADD) $(LIBS) + +asn1basic$(EXEEXT): $(asn1basic_OBJECTS) $(asn1basic_DEPENDENCIES) $(EXTRA_asn1basic_DEPENDENCIES) + @rm -f asn1basic$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1basic_OBJECTS) $(asn1basic_LDADD) $(LIBS) + +asn1complex$(EXEEXT): $(asn1complex_OBJECTS) $(asn1complex_DEPENDENCIES) $(EXTRA_asn1complex_DEPENDENCIES) + @rm -f asn1complex$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1complex_OBJECTS) $(asn1complex_LDADD) $(LIBS) + +asn1evp$(EXEEXT): $(asn1evp_OBJECTS) $(asn1evp_DEPENDENCIES) $(EXTRA_asn1evp_DEPENDENCIES) + @rm -f asn1evp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1evp_OBJECTS) $(asn1evp_LDADD) $(LIBS) + +asn1object$(EXEEXT): $(asn1object_OBJECTS) $(asn1object_DEPENDENCIES) $(EXTRA_asn1object_DEPENDENCIES) + @rm -f asn1object$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1object_OBJECTS) $(asn1object_LDADD) $(LIBS) + +asn1oct$(EXEEXT): $(asn1oct_OBJECTS) $(asn1oct_DEPENDENCIES) $(EXTRA_asn1oct_DEPENDENCIES) + @rm -f asn1oct$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1oct_OBJECTS) $(asn1oct_LDADD) $(LIBS) + +asn1string_copy$(EXEEXT): $(asn1string_copy_OBJECTS) $(asn1string_copy_DEPENDENCIES) $(EXTRA_asn1string_copy_DEPENDENCIES) + @rm -f asn1string_copy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1string_copy_OBJECTS) $(asn1string_copy_LDADD) $(LIBS) + +asn1test$(EXEEXT): $(asn1test_OBJECTS) $(asn1test_DEPENDENCIES) $(EXTRA_asn1test_DEPENDENCIES) + @rm -f asn1test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1test_OBJECTS) $(asn1test_LDADD) $(LIBS) + +asn1time$(EXEEXT): $(asn1time_OBJECTS) $(asn1time_DEPENDENCIES) $(EXTRA_asn1time_DEPENDENCIES) + @rm -f asn1time$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1time_OBJECTS) $(asn1time_LDADD) $(LIBS) + +asn1x509$(EXEEXT): $(asn1x509_OBJECTS) $(asn1x509_DEPENDENCIES) $(EXTRA_asn1x509_DEPENDENCIES) + @rm -f asn1x509$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asn1x509_OBJECTS) $(asn1x509_LDADD) $(LIBS) + +base64test$(EXEEXT): $(base64test_OBJECTS) $(base64test_DEPENDENCIES) $(EXTRA_base64test_DEPENDENCIES) + @rm -f base64test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(base64test_OBJECTS) $(base64test_LDADD) $(LIBS) + +bf_test$(EXEEXT): $(bf_test_OBJECTS) $(bf_test_DEPENDENCIES) $(EXTRA_bf_test_DEPENDENCIES) + @rm -f bf_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bf_test_OBJECTS) $(bf_test_LDADD) $(LIBS) + +bio_asn1$(EXEEXT): $(bio_asn1_OBJECTS) $(bio_asn1_DEPENDENCIES) $(EXTRA_bio_asn1_DEPENDENCIES) + @rm -f bio_asn1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bio_asn1_OBJECTS) $(bio_asn1_LDADD) $(LIBS) + +bio_chain$(EXEEXT): $(bio_chain_OBJECTS) $(bio_chain_DEPENDENCIES) $(EXTRA_bio_chain_DEPENDENCIES) + @rm -f bio_chain$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bio_chain_OBJECTS) $(bio_chain_LDADD) $(LIBS) + +bio_host$(EXEEXT): $(bio_host_OBJECTS) $(bio_host_DEPENDENCIES) $(EXTRA_bio_host_DEPENDENCIES) + @rm -f bio_host$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bio_host_OBJECTS) $(bio_host_LDADD) $(LIBS) + +bio_mem$(EXEEXT): $(bio_mem_OBJECTS) $(bio_mem_DEPENDENCIES) $(EXTRA_bio_mem_DEPENDENCIES) + @rm -f bio_mem$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bio_mem_OBJECTS) $(bio_mem_LDADD) $(LIBS) + +bn_add_sub$(EXEEXT): $(bn_add_sub_OBJECTS) $(bn_add_sub_DEPENDENCIES) $(EXTRA_bn_add_sub_DEPENDENCIES) + @rm -f bn_add_sub$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_add_sub_OBJECTS) $(bn_add_sub_LDADD) $(LIBS) + +bn_cmp$(EXEEXT): $(bn_cmp_OBJECTS) $(bn_cmp_DEPENDENCIES) $(EXTRA_bn_cmp_DEPENDENCIES) + @rm -f bn_cmp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_cmp_OBJECTS) $(bn_cmp_LDADD) $(LIBS) + +bn_convert$(EXEEXT): $(bn_convert_OBJECTS) $(bn_convert_DEPENDENCIES) $(EXTRA_bn_convert_DEPENDENCIES) + @rm -f bn_convert$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_convert_OBJECTS) $(bn_convert_LDADD) $(LIBS) + +bn_gcd$(EXEEXT): $(bn_gcd_OBJECTS) $(bn_gcd_DEPENDENCIES) $(EXTRA_bn_gcd_DEPENDENCIES) + @rm -f bn_gcd$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_gcd_OBJECTS) $(bn_gcd_LDADD) $(LIBS) + +bn_isqrt$(EXEEXT): $(bn_isqrt_OBJECTS) $(bn_isqrt_DEPENDENCIES) $(EXTRA_bn_isqrt_DEPENDENCIES) + @rm -f bn_isqrt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_isqrt_OBJECTS) $(bn_isqrt_LDADD) $(LIBS) + +bn_mod_exp$(EXEEXT): $(bn_mod_exp_OBJECTS) $(bn_mod_exp_DEPENDENCIES) $(EXTRA_bn_mod_exp_DEPENDENCIES) + @rm -f bn_mod_exp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_mod_exp_OBJECTS) $(bn_mod_exp_LDADD) $(LIBS) + +bn_mod_inverse$(EXEEXT): $(bn_mod_inverse_OBJECTS) $(bn_mod_inverse_DEPENDENCIES) $(EXTRA_bn_mod_inverse_DEPENDENCIES) + @rm -f bn_mod_inverse$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_mod_inverse_OBJECTS) $(bn_mod_inverse_LDADD) $(LIBS) + +bn_mod_sqrt$(EXEEXT): $(bn_mod_sqrt_OBJECTS) $(bn_mod_sqrt_DEPENDENCIES) $(EXTRA_bn_mod_sqrt_DEPENDENCIES) + @rm -f bn_mod_sqrt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_mod_sqrt_OBJECTS) $(bn_mod_sqrt_LDADD) $(LIBS) + +bn_mont$(EXEEXT): $(bn_mont_OBJECTS) $(bn_mont_DEPENDENCIES) $(EXTRA_bn_mont_DEPENDENCIES) + @rm -f bn_mont$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_mont_OBJECTS) $(bn_mont_LDADD) $(LIBS) + +bn_primes$(EXEEXT): $(bn_primes_OBJECTS) $(bn_primes_DEPENDENCIES) $(EXTRA_bn_primes_DEPENDENCIES) + @rm -f bn_primes$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_primes_OBJECTS) $(bn_primes_LDADD) $(LIBS) + +bn_print$(EXEEXT): $(bn_print_OBJECTS) $(bn_print_DEPENDENCIES) $(EXTRA_bn_print_DEPENDENCIES) + @rm -f bn_print$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_print_OBJECTS) $(bn_print_LDADD) $(LIBS) + +bn_shift$(EXEEXT): $(bn_shift_OBJECTS) $(bn_shift_DEPENDENCIES) $(EXTRA_bn_shift_DEPENDENCIES) + @rm -f bn_shift$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_shift_OBJECTS) $(bn_shift_LDADD) $(LIBS) + +bn_test$(EXEEXT): $(bn_test_OBJECTS) $(bn_test_DEPENDENCIES) $(EXTRA_bn_test_DEPENDENCIES) + @rm -f bn_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_test_OBJECTS) $(bn_test_LDADD) $(LIBS) + +bn_to_string$(EXEEXT): $(bn_to_string_OBJECTS) $(bn_to_string_DEPENDENCIES) $(EXTRA_bn_to_string_DEPENDENCIES) + @rm -f bn_to_string$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_to_string_OBJECTS) $(bn_to_string_LDADD) $(LIBS) + +bn_unit$(EXEEXT): $(bn_unit_OBJECTS) $(bn_unit_DEPENDENCIES) $(EXTRA_bn_unit_DEPENDENCIES) + @rm -f bn_unit$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_unit_OBJECTS) $(bn_unit_LDADD) $(LIBS) + +bn_word$(EXEEXT): $(bn_word_OBJECTS) $(bn_word_DEPENDENCIES) $(EXTRA_bn_word_DEPENDENCIES) + @rm -f bn_word$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bn_word_OBJECTS) $(bn_word_LDADD) $(LIBS) + +buffertest$(EXEEXT): $(buffertest_OBJECTS) $(buffertest_DEPENDENCIES) $(EXTRA_buffertest_DEPENDENCIES) + @rm -f buffertest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(buffertest_OBJECTS) $(buffertest_LDADD) $(LIBS) + +bytestringtest$(EXEEXT): $(bytestringtest_OBJECTS) $(bytestringtest_DEPENDENCIES) $(EXTRA_bytestringtest_DEPENDENCIES) + @rm -f bytestringtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bytestringtest_OBJECTS) $(bytestringtest_LDADD) $(LIBS) + +casttest$(EXEEXT): $(casttest_OBJECTS) $(casttest_DEPENDENCIES) $(EXTRA_casttest_DEPENDENCIES) + @rm -f casttest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(casttest_OBJECTS) $(casttest_LDADD) $(LIBS) + +chachatest$(EXEEXT): $(chachatest_OBJECTS) $(chachatest_DEPENDENCIES) $(EXTRA_chachatest_DEPENDENCIES) + @rm -f chachatest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(chachatest_OBJECTS) $(chachatest_LDADD) $(LIBS) + +cipher_list$(EXEEXT): $(cipher_list_OBJECTS) $(cipher_list_DEPENDENCIES) $(EXTRA_cipher_list_DEPENDENCIES) + @rm -f cipher_list$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(cipher_list_OBJECTS) $(cipher_list_LDADD) $(LIBS) + +cipherstest$(EXEEXT): $(cipherstest_OBJECTS) $(cipherstest_DEPENDENCIES) $(EXTRA_cipherstest_DEPENDENCIES) + @rm -f cipherstest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(cipherstest_OBJECTS) $(cipherstest_LDADD) $(LIBS) + +clienttest$(EXEEXT): $(clienttest_OBJECTS) $(clienttest_DEPENDENCIES) $(EXTRA_clienttest_DEPENDENCIES) + @rm -f clienttest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(clienttest_OBJECTS) $(clienttest_LDADD) $(LIBS) + +cmstest$(EXEEXT): $(cmstest_OBJECTS) $(cmstest_DEPENDENCIES) $(EXTRA_cmstest_DEPENDENCIES) + @rm -f cmstest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(cmstest_OBJECTS) $(cmstest_LDADD) $(LIBS) + +configtest$(EXEEXT): $(configtest_OBJECTS) $(configtest_DEPENDENCIES) $(EXTRA_configtest_DEPENDENCIES) + @rm -f configtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(configtest_OBJECTS) $(configtest_LDADD) $(LIBS) + +constraints$(EXEEXT): $(constraints_OBJECTS) $(constraints_DEPENDENCIES) $(EXTRA_constraints_DEPENDENCIES) + @rm -f constraints$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(constraints_OBJECTS) $(constraints_LDADD) $(LIBS) + +cttest$(EXEEXT): $(cttest_OBJECTS) $(cttest_DEPENDENCIES) $(EXTRA_cttest_DEPENDENCIES) + @rm -f cttest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(cttest_OBJECTS) $(cttest_LDADD) $(LIBS) + +destest$(EXEEXT): $(destest_OBJECTS) $(destest_DEPENDENCIES) $(EXTRA_destest_DEPENDENCIES) + @rm -f destest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(destest_OBJECTS) $(destest_LDADD) $(LIBS) + +dhtest$(EXEEXT): $(dhtest_OBJECTS) $(dhtest_DEPENDENCIES) $(EXTRA_dhtest_DEPENDENCIES) + @rm -f dhtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dhtest_OBJECTS) $(dhtest_LDADD) $(LIBS) + +dsatest$(EXEEXT): $(dsatest_OBJECTS) $(dsatest_DEPENDENCIES) $(EXTRA_dsatest_DEPENDENCIES) + @rm -f dsatest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dsatest_OBJECTS) $(dsatest_LDADD) $(LIBS) + +ec_asn1_test$(EXEEXT): $(ec_asn1_test_OBJECTS) $(ec_asn1_test_DEPENDENCIES) $(EXTRA_ec_asn1_test_DEPENDENCIES) + @rm -f ec_asn1_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ec_asn1_test_OBJECTS) $(ec_asn1_test_LDADD) $(LIBS) + +ec_point_conversion$(EXEEXT): $(ec_point_conversion_OBJECTS) $(ec_point_conversion_DEPENDENCIES) $(EXTRA_ec_point_conversion_DEPENDENCIES) + @rm -f ec_point_conversion$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ec_point_conversion_OBJECTS) $(ec_point_conversion_LDADD) $(LIBS) + +ecc_cdh$(EXEEXT): $(ecc_cdh_OBJECTS) $(ecc_cdh_DEPENDENCIES) $(EXTRA_ecc_cdh_DEPENDENCIES) + @rm -f ecc_cdh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecc_cdh_OBJECTS) $(ecc_cdh_LDADD) $(LIBS) + +ecdhtest$(EXEEXT): $(ecdhtest_OBJECTS) $(ecdhtest_DEPENDENCIES) $(EXTRA_ecdhtest_DEPENDENCIES) + @rm -f ecdhtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecdhtest_OBJECTS) $(ecdhtest_LDADD) $(LIBS) + +ecdsatest$(EXEEXT): $(ecdsatest_OBJECTS) $(ecdsatest_DEPENDENCIES) $(EXTRA_ecdsatest_DEPENDENCIES) + @rm -f ecdsatest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecdsatest_OBJECTS) $(ecdsatest_LDADD) $(LIBS) + +ectest$(EXEEXT): $(ectest_OBJECTS) $(ectest_DEPENDENCIES) $(EXTRA_ectest_DEPENDENCIES) + @rm -f ectest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ectest_OBJECTS) $(ectest_LDADD) $(LIBS) + +ed25519test$(EXEEXT): $(ed25519test_OBJECTS) $(ed25519test_DEPENDENCIES) $(EXTRA_ed25519test_DEPENDENCIES) + @rm -f ed25519test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ed25519test_OBJECTS) $(ed25519test_LDADD) $(LIBS) + +enginetest$(EXEEXT): $(enginetest_OBJECTS) $(enginetest_DEPENDENCIES) $(EXTRA_enginetest_DEPENDENCIES) + @rm -f enginetest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(enginetest_OBJECTS) $(enginetest_LDADD) $(LIBS) + +evp_ecx_test$(EXEEXT): $(evp_ecx_test_OBJECTS) $(evp_ecx_test_DEPENDENCIES) $(EXTRA_evp_ecx_test_DEPENDENCIES) + @rm -f evp_ecx_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(evp_ecx_test_OBJECTS) $(evp_ecx_test_LDADD) $(LIBS) + +evp_pkey_check$(EXEEXT): $(evp_pkey_check_OBJECTS) $(evp_pkey_check_DEPENDENCIES) $(EXTRA_evp_pkey_check_DEPENDENCIES) + @rm -f evp_pkey_check$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(evp_pkey_check_OBJECTS) $(evp_pkey_check_LDADD) $(LIBS) + +evp_pkey_cleanup$(EXEEXT): $(evp_pkey_cleanup_OBJECTS) $(evp_pkey_cleanup_DEPENDENCIES) $(EXTRA_evp_pkey_cleanup_DEPENDENCIES) + @rm -f evp_pkey_cleanup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(evp_pkey_cleanup_OBJECTS) $(evp_pkey_cleanup_LDADD) $(LIBS) + +evp_test$(EXEEXT): $(evp_test_OBJECTS) $(evp_test_DEPENDENCIES) $(EXTRA_evp_test_DEPENDENCIES) + @rm -f evp_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(evp_test_OBJECTS) $(evp_test_LDADD) $(LIBS) + +evptest$(EXEEXT): $(evptest_OBJECTS) $(evptest_DEPENDENCIES) $(EXTRA_evptest_DEPENDENCIES) + @rm -f evptest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(evptest_OBJECTS) $(evptest_LDADD) $(LIBS) +compat/$(am__dirstamp): + @$(MKDIR_P) compat + @: > compat/$(am__dirstamp) +compat/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) compat/$(DEPDIR) + @: > compat/$(DEPDIR)/$(am__dirstamp) +compat/memmem.$(OBJEXT): compat/$(am__dirstamp) \ + compat/$(DEPDIR)/$(am__dirstamp) + +explicit_bzero$(EXEEXT): $(explicit_bzero_OBJECTS) $(explicit_bzero_DEPENDENCIES) $(EXTRA_explicit_bzero_DEPENDENCIES) + @rm -f explicit_bzero$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(explicit_bzero_OBJECTS) $(explicit_bzero_LDADD) $(LIBS) + +exportertest$(EXEEXT): $(exportertest_OBJECTS) $(exportertest_DEPENDENCIES) $(EXTRA_exportertest_DEPENDENCIES) + @rm -f exportertest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(exportertest_OBJECTS) $(exportertest_LDADD) $(LIBS) + +freenull$(EXEEXT): $(freenull_OBJECTS) $(freenull_DEPENDENCIES) $(EXTRA_freenull_DEPENDENCIES) + @rm -f freenull$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(freenull_OBJECTS) $(freenull_LDADD) $(LIBS) + +gcm128test$(EXEEXT): $(gcm128test_OBJECTS) $(gcm128test_DEPENDENCIES) $(EXTRA_gcm128test_DEPENDENCIES) + @rm -f gcm128test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gcm128test_OBJECTS) $(gcm128test_LDADD) $(LIBS) + +gost2814789t$(EXEEXT): $(gost2814789t_OBJECTS) $(gost2814789t_DEPENDENCIES) $(EXTRA_gost2814789t_DEPENDENCIES) + @rm -f gost2814789t$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gost2814789t_OBJECTS) $(gost2814789t_LDADD) $(LIBS) + +handshake_table$(EXEEXT): $(handshake_table_OBJECTS) $(handshake_table_DEPENDENCIES) $(EXTRA_handshake_table_DEPENDENCIES) + @rm -f handshake_table$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(handshake_table_OBJECTS) $(handshake_table_LDADD) $(LIBS) + +hkdftest$(EXEEXT): $(hkdftest_OBJECTS) $(hkdftest_DEPENDENCIES) $(EXTRA_hkdftest_DEPENDENCIES) + @rm -f hkdftest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(hkdftest_OBJECTS) $(hkdftest_LDADD) $(LIBS) + +hmactest$(EXEEXT): $(hmactest_OBJECTS) $(hmactest_DEPENDENCIES) $(EXTRA_hmactest_DEPENDENCIES) + @rm -f hmactest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(hmactest_OBJECTS) $(hmactest_LDADD) $(LIBS) + +ideatest$(EXEEXT): $(ideatest_OBJECTS) $(ideatest_DEPENDENCIES) $(EXTRA_ideatest_DEPENDENCIES) + @rm -f ideatest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ideatest_OBJECTS) $(ideatest_LDADD) $(LIBS) + +igetest$(EXEEXT): $(igetest_OBJECTS) $(igetest_DEPENDENCIES) $(EXTRA_igetest_DEPENDENCIES) + @rm -f igetest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(igetest_OBJECTS) $(igetest_LDADD) $(LIBS) + +key_schedule$(EXEEXT): $(key_schedule_OBJECTS) $(key_schedule_DEPENDENCIES) $(EXTRA_key_schedule_DEPENDENCIES) + @rm -f key_schedule$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(key_schedule_OBJECTS) $(key_schedule_LDADD) $(LIBS) + +keypairtest$(EXEEXT): $(keypairtest_OBJECTS) $(keypairtest_DEPENDENCIES) $(EXTRA_keypairtest_DEPENDENCIES) + @rm -f keypairtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(keypairtest_OBJECTS) $(keypairtest_LDADD) $(LIBS) + +md_test$(EXEEXT): $(md_test_OBJECTS) $(md_test_DEPENDENCIES) $(EXTRA_md_test_DEPENDENCIES) + @rm -f md_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(md_test_OBJECTS) $(md_test_LDADD) $(LIBS) + +objectstest$(EXEEXT): $(objectstest_OBJECTS) $(objectstest_DEPENDENCIES) $(EXTRA_objectstest_DEPENDENCIES) + @rm -f objectstest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(objectstest_OBJECTS) $(objectstest_LDADD) $(LIBS) + +ocsp_test$(EXEEXT): $(ocsp_test_OBJECTS) $(ocsp_test_DEPENDENCIES) $(EXTRA_ocsp_test_DEPENDENCIES) + @rm -f ocsp_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ocsp_test_OBJECTS) $(ocsp_test_LDADD) $(LIBS) + +optionstest$(EXEEXT): $(optionstest_OBJECTS) $(optionstest_DEPENDENCIES) $(EXTRA_optionstest_DEPENDENCIES) + @rm -f optionstest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(optionstest_OBJECTS) $(optionstest_LDADD) $(LIBS) + +pbkdf2$(EXEEXT): $(pbkdf2_OBJECTS) $(pbkdf2_DEPENDENCIES) $(EXTRA_pbkdf2_DEPENDENCIES) + @rm -f pbkdf2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pbkdf2_OBJECTS) $(pbkdf2_LDADD) $(LIBS) + +pidwraptest$(EXEEXT): $(pidwraptest_OBJECTS) $(pidwraptest_DEPENDENCIES) $(EXTRA_pidwraptest_DEPENDENCIES) + @rm -f pidwraptest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pidwraptest_OBJECTS) $(pidwraptest_LDADD) $(LIBS) + +pkcs7test$(EXEEXT): $(pkcs7test_OBJECTS) $(pkcs7test_DEPENDENCIES) $(EXTRA_pkcs7test_DEPENDENCIES) + @rm -f pkcs7test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pkcs7test_OBJECTS) $(pkcs7test_LDADD) $(LIBS) + +policy$(EXEEXT): $(policy_OBJECTS) $(policy_DEPENDENCIES) $(EXTRA_policy_DEPENDENCIES) + @rm -f policy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(policy_OBJECTS) $(policy_LDADD) $(LIBS) + +poly1305test$(EXEEXT): $(poly1305test_OBJECTS) $(poly1305test_DEPENDENCIES) $(EXTRA_poly1305test_DEPENDENCIES) + @rm -f poly1305test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(poly1305test_OBJECTS) $(poly1305test_LDADD) $(LIBS) + +pq_test$(EXEEXT): $(pq_test_OBJECTS) $(pq_test_DEPENDENCIES) $(EXTRA_pq_test_DEPENDENCIES) + @rm -f pq_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pq_test_OBJECTS) $(pq_test_LDADD) $(LIBS) + +quictest$(EXEEXT): $(quictest_OBJECTS) $(quictest_DEPENDENCIES) $(EXTRA_quictest_DEPENDENCIES) + @rm -f quictest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(quictest_OBJECTS) $(quictest_LDADD) $(LIBS) + +randtest$(EXEEXT): $(randtest_OBJECTS) $(randtest_DEPENDENCIES) $(EXTRA_randtest_DEPENDENCIES) + @rm -f randtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(randtest_OBJECTS) $(randtest_LDADD) $(LIBS) + +rc2_test$(EXEEXT): $(rc2_test_OBJECTS) $(rc2_test_DEPENDENCIES) $(EXTRA_rc2_test_DEPENDENCIES) + @rm -f rc2_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rc2_test_OBJECTS) $(rc2_test_LDADD) $(LIBS) + +rc4_test$(EXEEXT): $(rc4_test_OBJECTS) $(rc4_test_DEPENDENCIES) $(EXTRA_rc4_test_DEPENDENCIES) + @rm -f rc4_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rc4_test_OBJECTS) $(rc4_test_LDADD) $(LIBS) + +record_layer_test$(EXEEXT): $(record_layer_test_OBJECTS) $(record_layer_test_DEPENDENCIES) $(EXTRA_record_layer_test_DEPENDENCIES) + @rm -f record_layer_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(record_layer_test_OBJECTS) $(record_layer_test_LDADD) $(LIBS) + +recordtest$(EXEEXT): $(recordtest_OBJECTS) $(recordtest_DEPENDENCIES) $(EXTRA_recordtest_DEPENDENCIES) + @rm -f recordtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(recordtest_OBJECTS) $(recordtest_LDADD) $(LIBS) + +rfc3779$(EXEEXT): $(rfc3779_OBJECTS) $(rfc3779_DEPENDENCIES) $(EXTRA_rfc3779_DEPENDENCIES) + @rm -f rfc3779$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rfc3779_OBJECTS) $(rfc3779_LDADD) $(LIBS) + +rfc5280time$(EXEEXT): $(rfc5280time_OBJECTS) $(rfc5280time_DEPENDENCIES) $(EXTRA_rfc5280time_DEPENDENCIES) + @rm -f rfc5280time$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rfc5280time_OBJECTS) $(rfc5280time_LDADD) $(LIBS) + +rmd_test$(EXEEXT): $(rmd_test_OBJECTS) $(rmd_test_DEPENDENCIES) $(EXTRA_rmd_test_DEPENDENCIES) + @rm -f rmd_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rmd_test_OBJECTS) $(rmd_test_LDADD) $(LIBS) + +rsa_test$(EXEEXT): $(rsa_test_OBJECTS) $(rsa_test_DEPENDENCIES) $(EXTRA_rsa_test_DEPENDENCIES) + @rm -f rsa_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rsa_test_OBJECTS) $(rsa_test_LDADD) $(LIBS) + +servertest$(EXEEXT): $(servertest_OBJECTS) $(servertest_DEPENDENCIES) $(EXTRA_servertest_DEPENDENCIES) + @rm -f servertest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(servertest_OBJECTS) $(servertest_LDADD) $(LIBS) + +sha_test$(EXEEXT): $(sha_test_OBJECTS) $(sha_test_DEPENDENCIES) $(EXTRA_sha_test_DEPENDENCIES) + @rm -f sha_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sha_test_OBJECTS) $(sha_test_LDADD) $(LIBS) +compat/signertest-pipe2.$(OBJEXT): compat/$(am__dirstamp) \ + compat/$(DEPDIR)/$(am__dirstamp) + +signertest$(EXEEXT): $(signertest_OBJECTS) $(signertest_DEPENDENCIES) $(EXTRA_signertest_DEPENDENCIES) + @rm -f signertest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(signertest_OBJECTS) $(signertest_LDADD) $(LIBS) + +sm3test$(EXEEXT): $(sm3test_OBJECTS) $(sm3test_DEPENDENCIES) $(EXTRA_sm3test_DEPENDENCIES) + @rm -f sm3test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sm3test_OBJECTS) $(sm3test_LDADD) $(LIBS) + +sm4test$(EXEEXT): $(sm4test_OBJECTS) $(sm4test_DEPENDENCIES) $(EXTRA_sm4test_DEPENDENCIES) + @rm -f sm4test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sm4test_OBJECTS) $(sm4test_LDADD) $(LIBS) + +ssl_get_shared_ciphers$(EXEEXT): $(ssl_get_shared_ciphers_OBJECTS) $(ssl_get_shared_ciphers_DEPENDENCIES) $(EXTRA_ssl_get_shared_ciphers_DEPENDENCIES) + @rm -f ssl_get_shared_ciphers$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ssl_get_shared_ciphers_OBJECTS) $(ssl_get_shared_ciphers_LDADD) $(LIBS) + +ssl_methods$(EXEEXT): $(ssl_methods_OBJECTS) $(ssl_methods_DEPENDENCIES) $(EXTRA_ssl_methods_DEPENDENCIES) + @rm -f ssl_methods$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ssl_methods_OBJECTS) $(ssl_methods_LDADD) $(LIBS) + +ssl_set_alpn_protos$(EXEEXT): $(ssl_set_alpn_protos_OBJECTS) $(ssl_set_alpn_protos_DEPENDENCIES) $(EXTRA_ssl_set_alpn_protos_DEPENDENCIES) + @rm -f ssl_set_alpn_protos$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ssl_set_alpn_protos_OBJECTS) $(ssl_set_alpn_protos_LDADD) $(LIBS) + +ssl_verify_param$(EXEEXT): $(ssl_verify_param_OBJECTS) $(ssl_verify_param_DEPENDENCIES) $(EXTRA_ssl_verify_param_DEPENDENCIES) + @rm -f ssl_verify_param$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ssl_verify_param_OBJECTS) $(ssl_verify_param_LDADD) $(LIBS) + +ssl_versions$(EXEEXT): $(ssl_versions_OBJECTS) $(ssl_versions_DEPENDENCIES) $(EXTRA_ssl_versions_DEPENDENCIES) + @rm -f ssl_versions$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ssl_versions_OBJECTS) $(ssl_versions_LDADD) $(LIBS) + +ssltest$(EXEEXT): $(ssltest_OBJECTS) $(ssltest_DEPENDENCIES) $(EXTRA_ssltest_DEPENDENCIES) + @rm -f ssltest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ssltest_OBJECTS) $(ssltest_LDADD) $(LIBS) + +string_table$(EXEEXT): $(string_table_OBJECTS) $(string_table_DEPENDENCIES) $(EXTRA_string_table_DEPENDENCIES) + @rm -f string_table$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(string_table_OBJECTS) $(string_table_LDADD) $(LIBS) + +timingsafe$(EXEEXT): $(timingsafe_OBJECTS) $(timingsafe_DEPENDENCIES) $(EXTRA_timingsafe_DEPENDENCIES) + @rm -f timingsafe$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(timingsafe_OBJECTS) $(timingsafe_LDADD) $(LIBS) + +tls_ext_alpn$(EXEEXT): $(tls_ext_alpn_OBJECTS) $(tls_ext_alpn_DEPENDENCIES) $(EXTRA_tls_ext_alpn_DEPENDENCIES) + @rm -f tls_ext_alpn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tls_ext_alpn_OBJECTS) $(tls_ext_alpn_LDADD) $(LIBS) + +tls_prf$(EXEEXT): $(tls_prf_OBJECTS) $(tls_prf_DEPENDENCIES) $(EXTRA_tls_prf_DEPENDENCIES) + @rm -f tls_prf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tls_prf_OBJECTS) $(tls_prf_LDADD) $(LIBS) + +tlsexttest$(EXEEXT): $(tlsexttest_OBJECTS) $(tlsexttest_DEPENDENCIES) $(EXTRA_tlsexttest_DEPENDENCIES) + @rm -f tlsexttest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlsexttest_OBJECTS) $(tlsexttest_LDADD) $(LIBS) + +tlslegacytest$(EXEEXT): $(tlslegacytest_OBJECTS) $(tlslegacytest_DEPENDENCIES) $(EXTRA_tlslegacytest_DEPENDENCIES) + @rm -f tlslegacytest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlslegacytest_OBJECTS) $(tlslegacytest_LDADD) $(LIBS) +compat/pipe2.$(OBJEXT): compat/$(am__dirstamp) \ + compat/$(DEPDIR)/$(am__dirstamp) + +tlstest$(EXEEXT): $(tlstest_OBJECTS) $(tlstest_DEPENDENCIES) $(EXTRA_tlstest_DEPENDENCIES) + @rm -f tlstest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlstest_OBJECTS) $(tlstest_LDADD) $(LIBS) + +utf8test$(EXEEXT): $(utf8test_OBJECTS) $(utf8test_DEPENDENCIES) $(EXTRA_utf8test_DEPENDENCIES) + @rm -f utf8test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(utf8test_OBJECTS) $(utf8test_LDADD) $(LIBS) + +valid_handshakes_terminate$(EXEEXT): $(valid_handshakes_terminate_OBJECTS) $(valid_handshakes_terminate_DEPENDENCIES) $(EXTRA_valid_handshakes_terminate_DEPENDENCIES) + @rm -f valid_handshakes_terminate$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(valid_handshakes_terminate_OBJECTS) $(valid_handshakes_terminate_LDADD) $(LIBS) + +verifytest$(EXEEXT): $(verifytest_OBJECTS) $(verifytest_DEPENDENCIES) $(EXTRA_verifytest_DEPENDENCIES) + @rm -f verifytest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(verifytest_OBJECTS) $(verifytest_LDADD) $(LIBS) + +x25519test$(EXEEXT): $(x25519test_OBJECTS) $(x25519test_DEPENDENCIES) $(EXTRA_x25519test_DEPENDENCIES) + @rm -f x25519test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(x25519test_OBJECTS) $(x25519test_LDADD) $(LIBS) + +x509_asn1$(EXEEXT): $(x509_asn1_OBJECTS) $(x509_asn1_DEPENDENCIES) $(EXTRA_x509_asn1_DEPENDENCIES) + @rm -f x509_asn1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(x509_asn1_OBJECTS) $(x509_asn1_LDADD) $(LIBS) + +x509_info$(EXEEXT): $(x509_info_OBJECTS) $(x509_info_DEPENDENCIES) $(EXTRA_x509_info_DEPENDENCIES) + @rm -f x509_info$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(x509_info_OBJECTS) $(x509_info_LDADD) $(LIBS) + +x509attribute$(EXEEXT): $(x509attribute_OBJECTS) $(x509attribute_DEPENDENCIES) $(EXTRA_x509attribute_DEPENDENCIES) + @rm -f x509attribute$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(x509attribute_OBJECTS) $(x509attribute_LDADD) $(LIBS) + +x509name$(EXEEXT): $(x509name_OBJECTS) $(x509name_DEPENDENCIES) $(EXTRA_x509name_DEPENDENCIES) + @rm -f x509name$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(x509name_OBJECTS) $(x509name_LDADD) $(LIBS) + +x509req_ext$(EXEEXT): $(x509req_ext_OBJECTS) $(x509req_ext_DEPENDENCIES) $(EXTRA_x509req_ext_DEPENDENCIES) + @rm -f x509req_ext$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(x509req_ext_OBJECTS) $(x509req_ext_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f compat/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aeadtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_wrap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apitest-apitest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc4randomforktest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_string_to_utf8.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1api.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1basic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1complex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1evp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1object.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1oct.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1string_copy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1time.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1x509.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bf_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_asn1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_chain.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_host.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_mem.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_add_sub.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_cmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_convert.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_gcd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_isqrt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_mod_exp-bn_mod_exp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_mod_inverse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_mod_sqrt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_mont.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_primes.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_print.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_shift.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_test-bn_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_to_string.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_unit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bn_word.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffertest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bytestringtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/casttest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chachatest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher_list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipherstest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clienttest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmstest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/configtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constraints.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cttest-cttest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/destest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsatest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec_asn1_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec_point_conversion.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc_cdh.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdhtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsatest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ectest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed25519test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/empty.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enginetest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evp_ecx_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evp_pkey_check.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evp_pkey_cleanup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evp_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evptest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/explicit_bzero.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exportertest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freenull-freenull.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcm128test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gost2814789t.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/handshake_table.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hkdf_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmactest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ideatest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igetest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key_schedule.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keypairtest-keypairtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objectstest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionstest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pbkdf2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pidwraptest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs7test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy-policy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pq_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quictest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc2_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc4_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/record_layer_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recordtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc3779-rfc3779.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc5280time.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmd_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/servertest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signertest-signertest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm3test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm4test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_methods.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_set_alpn_protos.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify_param.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_versions.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssltest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_table.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timingsafe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_ext_alpn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_prf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlsexttest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlslegacytest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlstest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utf8test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/valid_handshakes_terminate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verifytest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x25519test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_asn1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509attribute.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509name.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509req_ext.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@compat/$(DEPDIR)/memmem.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@compat/$(DEPDIR)/pipe2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@compat/$(DEPDIR)/signertest-pipe2.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +apitest-apitest.o: apitest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(apitest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT apitest-apitest.o -MD -MP -MF $(DEPDIR)/apitest-apitest.Tpo -c -o apitest-apitest.o `test -f 'apitest.c' || echo '$(srcdir)/'`apitest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/apitest-apitest.Tpo $(DEPDIR)/apitest-apitest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='apitest.c' object='apitest-apitest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(apitest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o apitest-apitest.o `test -f 'apitest.c' || echo '$(srcdir)/'`apitest.c + +apitest-apitest.obj: apitest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(apitest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT apitest-apitest.obj -MD -MP -MF $(DEPDIR)/apitest-apitest.Tpo -c -o apitest-apitest.obj `if test -f 'apitest.c'; then $(CYGPATH_W) 'apitest.c'; else $(CYGPATH_W) '$(srcdir)/apitest.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/apitest-apitest.Tpo $(DEPDIR)/apitest-apitest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='apitest.c' object='apitest-apitest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(apitest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o apitest-apitest.obj `if test -f 'apitest.c'; then $(CYGPATH_W) 'apitest.c'; else $(CYGPATH_W) '$(srcdir)/apitest.c'; fi` + +bn_mod_exp-bn_mod_exp.o: bn_mod_exp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_mod_exp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bn_mod_exp-bn_mod_exp.o -MD -MP -MF $(DEPDIR)/bn_mod_exp-bn_mod_exp.Tpo -c -o bn_mod_exp-bn_mod_exp.o `test -f 'bn_mod_exp.c' || echo '$(srcdir)/'`bn_mod_exp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bn_mod_exp-bn_mod_exp.Tpo $(DEPDIR)/bn_mod_exp-bn_mod_exp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bn_mod_exp.c' object='bn_mod_exp-bn_mod_exp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_mod_exp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bn_mod_exp-bn_mod_exp.o `test -f 'bn_mod_exp.c' || echo '$(srcdir)/'`bn_mod_exp.c + +bn_mod_exp-bn_mod_exp.obj: bn_mod_exp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_mod_exp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bn_mod_exp-bn_mod_exp.obj -MD -MP -MF $(DEPDIR)/bn_mod_exp-bn_mod_exp.Tpo -c -o bn_mod_exp-bn_mod_exp.obj `if test -f 'bn_mod_exp.c'; then $(CYGPATH_W) 'bn_mod_exp.c'; else $(CYGPATH_W) '$(srcdir)/bn_mod_exp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bn_mod_exp-bn_mod_exp.Tpo $(DEPDIR)/bn_mod_exp-bn_mod_exp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bn_mod_exp.c' object='bn_mod_exp-bn_mod_exp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_mod_exp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bn_mod_exp-bn_mod_exp.obj `if test -f 'bn_mod_exp.c'; then $(CYGPATH_W) 'bn_mod_exp.c'; else $(CYGPATH_W) '$(srcdir)/bn_mod_exp.c'; fi` + +bn_test-bn_test.o: bn_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bn_test-bn_test.o -MD -MP -MF $(DEPDIR)/bn_test-bn_test.Tpo -c -o bn_test-bn_test.o `test -f 'bn_test.c' || echo '$(srcdir)/'`bn_test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bn_test-bn_test.Tpo $(DEPDIR)/bn_test-bn_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bn_test.c' object='bn_test-bn_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bn_test-bn_test.o `test -f 'bn_test.c' || echo '$(srcdir)/'`bn_test.c + +bn_test-bn_test.obj: bn_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bn_test-bn_test.obj -MD -MP -MF $(DEPDIR)/bn_test-bn_test.Tpo -c -o bn_test-bn_test.obj `if test -f 'bn_test.c'; then $(CYGPATH_W) 'bn_test.c'; else $(CYGPATH_W) '$(srcdir)/bn_test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bn_test-bn_test.Tpo $(DEPDIR)/bn_test-bn_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bn_test.c' object='bn_test-bn_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bn_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bn_test-bn_test.obj `if test -f 'bn_test.c'; then $(CYGPATH_W) 'bn_test.c'; else $(CYGPATH_W) '$(srcdir)/bn_test.c'; fi` + +cttest-cttest.o: cttest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cttest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cttest-cttest.o -MD -MP -MF $(DEPDIR)/cttest-cttest.Tpo -c -o cttest-cttest.o `test -f 'cttest.c' || echo '$(srcdir)/'`cttest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cttest-cttest.Tpo $(DEPDIR)/cttest-cttest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cttest.c' object='cttest-cttest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cttest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cttest-cttest.o `test -f 'cttest.c' || echo '$(srcdir)/'`cttest.c + +cttest-cttest.obj: cttest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cttest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cttest-cttest.obj -MD -MP -MF $(DEPDIR)/cttest-cttest.Tpo -c -o cttest-cttest.obj `if test -f 'cttest.c'; then $(CYGPATH_W) 'cttest.c'; else $(CYGPATH_W) '$(srcdir)/cttest.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cttest-cttest.Tpo $(DEPDIR)/cttest-cttest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cttest.c' object='cttest-cttest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cttest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cttest-cttest.obj `if test -f 'cttest.c'; then $(CYGPATH_W) 'cttest.c'; else $(CYGPATH_W) '$(srcdir)/cttest.c'; fi` + +freenull-freenull.o: freenull.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(freenull_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT freenull-freenull.o -MD -MP -MF $(DEPDIR)/freenull-freenull.Tpo -c -o freenull-freenull.o `test -f 'freenull.c' || echo '$(srcdir)/'`freenull.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/freenull-freenull.Tpo $(DEPDIR)/freenull-freenull.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='freenull.c' object='freenull-freenull.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(freenull_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freenull-freenull.o `test -f 'freenull.c' || echo '$(srcdir)/'`freenull.c + +freenull-freenull.obj: freenull.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(freenull_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT freenull-freenull.obj -MD -MP -MF $(DEPDIR)/freenull-freenull.Tpo -c -o freenull-freenull.obj `if test -f 'freenull.c'; then $(CYGPATH_W) 'freenull.c'; else $(CYGPATH_W) '$(srcdir)/freenull.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/freenull-freenull.Tpo $(DEPDIR)/freenull-freenull.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='freenull.c' object='freenull-freenull.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(freenull_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freenull-freenull.obj `if test -f 'freenull.c'; then $(CYGPATH_W) 'freenull.c'; else $(CYGPATH_W) '$(srcdir)/freenull.c'; fi` + +keypairtest-keypairtest.o: keypairtest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(keypairtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT keypairtest-keypairtest.o -MD -MP -MF $(DEPDIR)/keypairtest-keypairtest.Tpo -c -o keypairtest-keypairtest.o `test -f 'keypairtest.c' || echo '$(srcdir)/'`keypairtest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/keypairtest-keypairtest.Tpo $(DEPDIR)/keypairtest-keypairtest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keypairtest.c' object='keypairtest-keypairtest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(keypairtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o keypairtest-keypairtest.o `test -f 'keypairtest.c' || echo '$(srcdir)/'`keypairtest.c + +keypairtest-keypairtest.obj: keypairtest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(keypairtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT keypairtest-keypairtest.obj -MD -MP -MF $(DEPDIR)/keypairtest-keypairtest.Tpo -c -o keypairtest-keypairtest.obj `if test -f 'keypairtest.c'; then $(CYGPATH_W) 'keypairtest.c'; else $(CYGPATH_W) '$(srcdir)/keypairtest.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/keypairtest-keypairtest.Tpo $(DEPDIR)/keypairtest-keypairtest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keypairtest.c' object='keypairtest-keypairtest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(keypairtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o keypairtest-keypairtest.obj `if test -f 'keypairtest.c'; then $(CYGPATH_W) 'keypairtest.c'; else $(CYGPATH_W) '$(srcdir)/keypairtest.c'; fi` + +policy-policy.o: policy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(policy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT policy-policy.o -MD -MP -MF $(DEPDIR)/policy-policy.Tpo -c -o policy-policy.o `test -f 'policy.c' || echo '$(srcdir)/'`policy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/policy-policy.Tpo $(DEPDIR)/policy-policy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='policy.c' object='policy-policy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(policy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o policy-policy.o `test -f 'policy.c' || echo '$(srcdir)/'`policy.c + +policy-policy.obj: policy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(policy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT policy-policy.obj -MD -MP -MF $(DEPDIR)/policy-policy.Tpo -c -o policy-policy.obj `if test -f 'policy.c'; then $(CYGPATH_W) 'policy.c'; else $(CYGPATH_W) '$(srcdir)/policy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/policy-policy.Tpo $(DEPDIR)/policy-policy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='policy.c' object='policy-policy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(policy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o policy-policy.obj `if test -f 'policy.c'; then $(CYGPATH_W) 'policy.c'; else $(CYGPATH_W) '$(srcdir)/policy.c'; fi` + +rfc3779-rfc3779.o: rfc3779.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rfc3779_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rfc3779-rfc3779.o -MD -MP -MF $(DEPDIR)/rfc3779-rfc3779.Tpo -c -o rfc3779-rfc3779.o `test -f 'rfc3779.c' || echo '$(srcdir)/'`rfc3779.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rfc3779-rfc3779.Tpo $(DEPDIR)/rfc3779-rfc3779.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rfc3779.c' object='rfc3779-rfc3779.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rfc3779_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rfc3779-rfc3779.o `test -f 'rfc3779.c' || echo '$(srcdir)/'`rfc3779.c + +rfc3779-rfc3779.obj: rfc3779.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rfc3779_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rfc3779-rfc3779.obj -MD -MP -MF $(DEPDIR)/rfc3779-rfc3779.Tpo -c -o rfc3779-rfc3779.obj `if test -f 'rfc3779.c'; then $(CYGPATH_W) 'rfc3779.c'; else $(CYGPATH_W) '$(srcdir)/rfc3779.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rfc3779-rfc3779.Tpo $(DEPDIR)/rfc3779-rfc3779.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rfc3779.c' object='rfc3779-rfc3779.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rfc3779_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rfc3779-rfc3779.obj `if test -f 'rfc3779.c'; then $(CYGPATH_W) 'rfc3779.c'; else $(CYGPATH_W) '$(srcdir)/rfc3779.c'; fi` + +signertest-signertest.o: signertest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signertest-signertest.o -MD -MP -MF $(DEPDIR)/signertest-signertest.Tpo -c -o signertest-signertest.o `test -f 'signertest.c' || echo '$(srcdir)/'`signertest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/signertest-signertest.Tpo $(DEPDIR)/signertest-signertest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='signertest.c' object='signertest-signertest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signertest-signertest.o `test -f 'signertest.c' || echo '$(srcdir)/'`signertest.c + +signertest-signertest.obj: signertest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signertest-signertest.obj -MD -MP -MF $(DEPDIR)/signertest-signertest.Tpo -c -o signertest-signertest.obj `if test -f 'signertest.c'; then $(CYGPATH_W) 'signertest.c'; else $(CYGPATH_W) '$(srcdir)/signertest.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/signertest-signertest.Tpo $(DEPDIR)/signertest-signertest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='signertest.c' object='signertest-signertest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signertest-signertest.obj `if test -f 'signertest.c'; then $(CYGPATH_W) 'signertest.c'; else $(CYGPATH_W) '$(srcdir)/signertest.c'; fi` + +compat/signertest-pipe2.o: compat/pipe2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat/signertest-pipe2.o -MD -MP -MF compat/$(DEPDIR)/signertest-pipe2.Tpo -c -o compat/signertest-pipe2.o `test -f 'compat/pipe2.c' || echo '$(srcdir)/'`compat/pipe2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) compat/$(DEPDIR)/signertest-pipe2.Tpo compat/$(DEPDIR)/signertest-pipe2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat/pipe2.c' object='compat/signertest-pipe2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat/signertest-pipe2.o `test -f 'compat/pipe2.c' || echo '$(srcdir)/'`compat/pipe2.c + +compat/signertest-pipe2.obj: compat/pipe2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat/signertest-pipe2.obj -MD -MP -MF compat/$(DEPDIR)/signertest-pipe2.Tpo -c -o compat/signertest-pipe2.obj `if test -f 'compat/pipe2.c'; then $(CYGPATH_W) 'compat/pipe2.c'; else $(CYGPATH_W) '$(srcdir)/compat/pipe2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) compat/$(DEPDIR)/signertest-pipe2.Tpo compat/$(DEPDIR)/signertest-pipe2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat/pipe2.c' object='compat/signertest-pipe2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(signertest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat/signertest-pipe2.obj `if test -f 'compat/pipe2.c'; then $(CYGPATH_W) 'compat/pipe2.c'; else $(CYGPATH_W) '$(srcdir)/compat/pipe2.c'; fi` + +ssl_get_shared_ciphers-ssl_get_shared_ciphers.o: ssl_get_shared_ciphers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ssl_get_shared_ciphers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ssl_get_shared_ciphers-ssl_get_shared_ciphers.o -MD -MP -MF $(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Tpo -c -o ssl_get_shared_ciphers-ssl_get_shared_ciphers.o `test -f 'ssl_get_shared_ciphers.c' || echo '$(srcdir)/'`ssl_get_shared_ciphers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Tpo $(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_get_shared_ciphers.c' object='ssl_get_shared_ciphers-ssl_get_shared_ciphers.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ssl_get_shared_ciphers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ssl_get_shared_ciphers-ssl_get_shared_ciphers.o `test -f 'ssl_get_shared_ciphers.c' || echo '$(srcdir)/'`ssl_get_shared_ciphers.c + +ssl_get_shared_ciphers-ssl_get_shared_ciphers.obj: ssl_get_shared_ciphers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ssl_get_shared_ciphers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ssl_get_shared_ciphers-ssl_get_shared_ciphers.obj -MD -MP -MF $(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Tpo -c -o ssl_get_shared_ciphers-ssl_get_shared_ciphers.obj `if test -f 'ssl_get_shared_ciphers.c'; then $(CYGPATH_W) 'ssl_get_shared_ciphers.c'; else $(CYGPATH_W) '$(srcdir)/ssl_get_shared_ciphers.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Tpo $(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl_get_shared_ciphers.c' object='ssl_get_shared_ciphers-ssl_get_shared_ciphers.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ssl_get_shared_ciphers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ssl_get_shared_ciphers-ssl_get_shared_ciphers.obj `if test -f 'ssl_get_shared_ciphers.c'; then $(CYGPATH_W) 'ssl_get_shared_ciphers.c'; else $(CYGPATH_W) '$(srcdir)/ssl_get_shared_ciphers.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +aeadtest.sh.log: aeadtest.sh + @p='aeadtest.sh'; \ + b='aeadtest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +aes_test.log: aes_test$(EXEEXT) + @p='aes_test$(EXEEXT)'; \ + b='aes_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +aes_wrap.log: aes_wrap$(EXEEXT) + @p='aes_wrap$(EXEEXT)'; \ + b='aes_wrap'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +apitest.log: apitest$(EXEEXT) + @p='apitest$(EXEEXT)'; \ + b='apitest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +arc4randomforktest.sh.log: arc4randomforktest.sh + @p='arc4randomforktest.sh'; \ + b='arc4randomforktest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1_string_to_utf8.log: asn1_string_to_utf8$(EXEEXT) + @p='asn1_string_to_utf8$(EXEEXT)'; \ + b='asn1_string_to_utf8'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1api.log: asn1api$(EXEEXT) + @p='asn1api$(EXEEXT)'; \ + b='asn1api'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1basic.log: asn1basic$(EXEEXT) + @p='asn1basic$(EXEEXT)'; \ + b='asn1basic'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1complex.log: asn1complex$(EXEEXT) + @p='asn1complex$(EXEEXT)'; \ + b='asn1complex'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1evp.log: asn1evp$(EXEEXT) + @p='asn1evp$(EXEEXT)'; \ + b='asn1evp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1object.log: asn1object$(EXEEXT) + @p='asn1object$(EXEEXT)'; \ + b='asn1object'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1oct.log: asn1oct$(EXEEXT) + @p='asn1oct$(EXEEXT)'; \ + b='asn1oct'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1string_copy.log: asn1string_copy$(EXEEXT) + @p='asn1string_copy$(EXEEXT)'; \ + b='asn1string_copy'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1test.log: asn1test$(EXEEXT) + @p='asn1test$(EXEEXT)'; \ + b='asn1test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1time.log: asn1time$(EXEEXT) + @p='asn1time$(EXEEXT)'; \ + b='asn1time'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asn1x509.log: asn1x509$(EXEEXT) + @p='asn1x509$(EXEEXT)'; \ + b='asn1x509'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +base64test.log: base64test$(EXEEXT) + @p='base64test$(EXEEXT)'; \ + b='base64test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bf_test.log: bf_test$(EXEEXT) + @p='bf_test$(EXEEXT)'; \ + b='bf_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bio_asn1.log: bio_asn1$(EXEEXT) + @p='bio_asn1$(EXEEXT)'; \ + b='bio_asn1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bio_chain.log: bio_chain$(EXEEXT) + @p='bio_chain$(EXEEXT)'; \ + b='bio_chain'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bio_host.log: bio_host$(EXEEXT) + @p='bio_host$(EXEEXT)'; \ + b='bio_host'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bio_mem.log: bio_mem$(EXEEXT) + @p='bio_mem$(EXEEXT)'; \ + b='bio_mem'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_add_sub.log: bn_add_sub$(EXEEXT) + @p='bn_add_sub$(EXEEXT)'; \ + b='bn_add_sub'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_cmp.log: bn_cmp$(EXEEXT) + @p='bn_cmp$(EXEEXT)'; \ + b='bn_cmp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_convert.log: bn_convert$(EXEEXT) + @p='bn_convert$(EXEEXT)'; \ + b='bn_convert'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_gcd.log: bn_gcd$(EXEEXT) + @p='bn_gcd$(EXEEXT)'; \ + b='bn_gcd'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_isqrt.log: bn_isqrt$(EXEEXT) + @p='bn_isqrt$(EXEEXT)'; \ + b='bn_isqrt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_mod_exp.log: bn_mod_exp$(EXEEXT) + @p='bn_mod_exp$(EXEEXT)'; \ + b='bn_mod_exp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_mod_inverse.log: bn_mod_inverse$(EXEEXT) + @p='bn_mod_inverse$(EXEEXT)'; \ + b='bn_mod_inverse'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_mod_sqrt.log: bn_mod_sqrt$(EXEEXT) + @p='bn_mod_sqrt$(EXEEXT)'; \ + b='bn_mod_sqrt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_mont.log: bn_mont$(EXEEXT) + @p='bn_mont$(EXEEXT)'; \ + b='bn_mont'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_primes.log: bn_primes$(EXEEXT) + @p='bn_primes$(EXEEXT)'; \ + b='bn_primes'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_print.log: bn_print$(EXEEXT) + @p='bn_print$(EXEEXT)'; \ + b='bn_print'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_shift.log: bn_shift$(EXEEXT) + @p='bn_shift$(EXEEXT)'; \ + b='bn_shift'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_test.log: bn_test$(EXEEXT) + @p='bn_test$(EXEEXT)'; \ + b='bn_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_to_string.log: bn_to_string$(EXEEXT) + @p='bn_to_string$(EXEEXT)'; \ + b='bn_to_string'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_unit.log: bn_unit$(EXEEXT) + @p='bn_unit$(EXEEXT)'; \ + b='bn_unit'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bn_word.log: bn_word$(EXEEXT) + @p='bn_word$(EXEEXT)'; \ + b='bn_word'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +buffertest.log: buffertest$(EXEEXT) + @p='buffertest$(EXEEXT)'; \ + b='buffertest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bytestringtest.log: bytestringtest$(EXEEXT) + @p='bytestringtest$(EXEEXT)'; \ + b='bytestringtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +casttest.log: casttest$(EXEEXT) + @p='casttest$(EXEEXT)'; \ + b='casttest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +chachatest.log: chachatest$(EXEEXT) + @p='chachatest$(EXEEXT)'; \ + b='chachatest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +cipher_list.log: cipher_list$(EXEEXT) + @p='cipher_list$(EXEEXT)'; \ + b='cipher_list'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +cipherstest.log: cipherstest$(EXEEXT) + @p='cipherstest$(EXEEXT)'; \ + b='cipherstest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +clienttest.log: clienttest$(EXEEXT) + @p='clienttest$(EXEEXT)'; \ + b='clienttest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +cmstest.log: cmstest$(EXEEXT) + @p='cmstest$(EXEEXT)'; \ + b='cmstest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +configtest.log: configtest$(EXEEXT) + @p='configtest$(EXEEXT)'; \ + b='configtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +constraints.log: constraints$(EXEEXT) + @p='constraints$(EXEEXT)'; \ + b='constraints'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +cttest.log: cttest$(EXEEXT) + @p='cttest$(EXEEXT)'; \ + b='cttest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +destest.log: destest$(EXEEXT) + @p='destest$(EXEEXT)'; \ + b='destest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dhtest.log: dhtest$(EXEEXT) + @p='dhtest$(EXEEXT)'; \ + b='dhtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dsatest.log: dsatest$(EXEEXT) + @p='dsatest$(EXEEXT)'; \ + b='dsatest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ecc_cdh.log: ecc_cdh$(EXEEXT) + @p='ecc_cdh$(EXEEXT)'; \ + b='ecc_cdh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ec_asn1_test.log: ec_asn1_test$(EXEEXT) + @p='ec_asn1_test$(EXEEXT)'; \ + b='ec_asn1_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ec_point_conversion.log: ec_point_conversion$(EXEEXT) + @p='ec_point_conversion$(EXEEXT)'; \ + b='ec_point_conversion'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ecdhtest.log: ecdhtest$(EXEEXT) + @p='ecdhtest$(EXEEXT)'; \ + b='ecdhtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ecdsatest.log: ecdsatest$(EXEEXT) + @p='ecdsatest$(EXEEXT)'; \ + b='ecdsatest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ectest.log: ectest$(EXEEXT) + @p='ectest$(EXEEXT)'; \ + b='ectest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ed25519test.log: ed25519test$(EXEEXT) + @p='ed25519test$(EXEEXT)'; \ + b='ed25519test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +enginetest.log: enginetest$(EXEEXT) + @p='enginetest$(EXEEXT)'; \ + b='enginetest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +evp_ecx_test.log: evp_ecx_test$(EXEEXT) + @p='evp_ecx_test$(EXEEXT)'; \ + b='evp_ecx_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +evp_pkey_check.log: evp_pkey_check$(EXEEXT) + @p='evp_pkey_check$(EXEEXT)'; \ + b='evp_pkey_check'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +evp_pkey_cleanup.log: evp_pkey_cleanup$(EXEEXT) + @p='evp_pkey_cleanup$(EXEEXT)'; \ + b='evp_pkey_cleanup'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +evptest.sh.log: evptest.sh + @p='evptest.sh'; \ + b='evptest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +evp_test.log: evp_test$(EXEEXT) + @p='evp_test$(EXEEXT)'; \ + b='evp_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +explicit_bzero.log: explicit_bzero$(EXEEXT) + @p='explicit_bzero$(EXEEXT)'; \ + b='explicit_bzero'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +exportertest.log: exportertest$(EXEEXT) + @p='exportertest$(EXEEXT)'; \ + b='exportertest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +freenull.log: freenull$(EXEEXT) + @p='freenull$(EXEEXT)'; \ + b='freenull'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +gcm128test.log: gcm128test$(EXEEXT) + @p='gcm128test$(EXEEXT)'; \ + b='gcm128test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +gost2814789t.log: gost2814789t$(EXEEXT) + @p='gost2814789t$(EXEEXT)'; \ + b='gost2814789t'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +handshake_table.log: handshake_table$(EXEEXT) + @p='handshake_table$(EXEEXT)'; \ + b='handshake_table'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +hkdftest.log: hkdftest$(EXEEXT) + @p='hkdftest$(EXEEXT)'; \ + b='hkdftest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +hmactest.log: hmactest$(EXEEXT) + @p='hmactest$(EXEEXT)'; \ + b='hmactest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ideatest.log: ideatest$(EXEEXT) + @p='ideatest$(EXEEXT)'; \ + b='ideatest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +igetest.log: igetest$(EXEEXT) + @p='igetest$(EXEEXT)'; \ + b='igetest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +key_schedule.log: key_schedule$(EXEEXT) + @p='key_schedule$(EXEEXT)'; \ + b='key_schedule'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +keypairtest.sh.log: keypairtest.sh + @p='keypairtest.sh'; \ + b='keypairtest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +md_test.log: md_test$(EXEEXT) + @p='md_test$(EXEEXT)'; \ + b='md_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +objectstest.log: objectstest$(EXEEXT) + @p='objectstest$(EXEEXT)'; \ + b='objectstest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ocsptest.sh.log: ocsptest.sh + @p='ocsptest.sh'; \ + b='ocsptest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +optionstest.log: optionstest$(EXEEXT) + @p='optionstest$(EXEEXT)'; \ + b='optionstest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pbkdf2.log: pbkdf2$(EXEEXT) + @p='pbkdf2$(EXEEXT)'; \ + b='pbkdf2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pidwraptest.sh.log: pidwraptest.sh + @p='pidwraptest.sh'; \ + b='pidwraptest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pkcs7test.log: pkcs7test$(EXEEXT) + @p='pkcs7test$(EXEEXT)'; \ + b='pkcs7test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +poly1305test.log: poly1305test$(EXEEXT) + @p='poly1305test$(EXEEXT)'; \ + b='poly1305test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +policy.log: policy$(EXEEXT) + @p='policy$(EXEEXT)'; \ + b='policy'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pq_test.sh.log: pq_test.sh + @p='pq_test.sh'; \ + b='pq_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +quictest.sh.log: quictest.sh + @p='quictest.sh'; \ + b='quictest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +randtest.log: randtest$(EXEEXT) + @p='randtest$(EXEEXT)'; \ + b='randtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rc2_test.log: rc2_test$(EXEEXT) + @p='rc2_test$(EXEEXT)'; \ + b='rc2_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rc4_test.log: rc4_test$(EXEEXT) + @p='rc4_test$(EXEEXT)'; \ + b='rc4_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +recordtest.log: recordtest$(EXEEXT) + @p='recordtest$(EXEEXT)'; \ + b='recordtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +record_layer_test.log: record_layer_test$(EXEEXT) + @p='record_layer_test$(EXEEXT)'; \ + b='record_layer_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rfc3779.log: rfc3779$(EXEEXT) + @p='rfc3779$(EXEEXT)'; \ + b='rfc3779'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rfc5280time.log: rfc5280time$(EXEEXT) + @p='rfc5280time$(EXEEXT)'; \ + b='rfc5280time'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rmd_test.log: rmd_test$(EXEEXT) + @p='rmd_test$(EXEEXT)'; \ + b='rmd_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rsa_test.log: rsa_test$(EXEEXT) + @p='rsa_test$(EXEEXT)'; \ + b='rsa_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +servertest.sh.log: servertest.sh + @p='servertest.sh'; \ + b='servertest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +sha_test.log: sha_test$(EXEEXT) + @p='sha_test$(EXEEXT)'; \ + b='sha_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +signertest.log: signertest$(EXEEXT) + @p='signertest$(EXEEXT)'; \ + b='signertest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +sm3test.log: sm3test$(EXEEXT) + @p='sm3test$(EXEEXT)'; \ + b='sm3test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +sm4test.log: sm4test$(EXEEXT) + @p='sm4test$(EXEEXT)'; \ + b='sm4test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ssl_get_shared_ciphers.log: ssl_get_shared_ciphers$(EXEEXT) + @p='ssl_get_shared_ciphers$(EXEEXT)'; \ + b='ssl_get_shared_ciphers'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ssl_methods.log: ssl_methods$(EXEEXT) + @p='ssl_methods$(EXEEXT)'; \ + b='ssl_methods'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ssl_set_alpn_protos.log: ssl_set_alpn_protos$(EXEEXT) + @p='ssl_set_alpn_protos$(EXEEXT)'; \ + b='ssl_set_alpn_protos'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ssl_verify_param.log: ssl_verify_param$(EXEEXT) + @p='ssl_verify_param$(EXEEXT)'; \ + b='ssl_verify_param'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ssl_versions.log: ssl_versions$(EXEEXT) + @p='ssl_versions$(EXEEXT)'; \ + b='ssl_versions'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ssltest.sh.log: ssltest.sh + @p='ssltest.sh'; \ + b='ssltest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +string_table.log: string_table$(EXEEXT) + @p='string_table$(EXEEXT)'; \ + b='string_table'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +testdsa.sh.log: testdsa.sh + @p='testdsa.sh'; \ + b='testdsa.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +testenc.sh.log: testenc.sh + @p='testenc.sh'; \ + b='testenc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +testrsa.sh.log: testrsa.sh + @p='testrsa.sh'; \ + b='testrsa.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +timingsafe.log: timingsafe$(EXEEXT) + @p='timingsafe$(EXEEXT)'; \ + b='timingsafe'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlsexttest.log: tlsexttest$(EXEEXT) + @p='tlsexttest$(EXEEXT)'; \ + b='tlsexttest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlslegacytest.log: tlslegacytest$(EXEEXT) + @p='tlslegacytest$(EXEEXT)'; \ + b='tlslegacytest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlstest.sh.log: tlstest.sh + @p='tlstest.sh'; \ + b='tlstest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tls_ext_alpn.log: tls_ext_alpn$(EXEEXT) + @p='tls_ext_alpn$(EXEEXT)'; \ + b='tls_ext_alpn'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tls_prf.log: tls_prf$(EXEEXT) + @p='tls_prf$(EXEEXT)'; \ + b='tls_prf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +utf8test.log: utf8test$(EXEEXT) + @p='utf8test$(EXEEXT)'; \ + b='utf8test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +valid_handshakes_terminate.log: valid_handshakes_terminate$(EXEEXT) + @p='valid_handshakes_terminate$(EXEEXT)'; \ + b='valid_handshakes_terminate'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +verifytest.log: verifytest$(EXEEXT) + @p='verifytest$(EXEEXT)'; \ + b='verifytest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +x25519test.log: x25519test$(EXEEXT) + @p='x25519test$(EXEEXT)'; \ + b='x25519test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +x509attribute.log: x509attribute$(EXEEXT) + @p='x509attribute$(EXEEXT)'; \ + b='x509attribute'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +x509_asn1.log: x509_asn1$(EXEEXT) + @p='x509_asn1$(EXEEXT)'; \ + b='x509_asn1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +x509_info.log: x509_info$(EXEEXT) + @p='x509_info$(EXEEXT)'; \ + b='x509_info'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +x509name.log: x509name$(EXEEXT) + @p='x509name$(EXEEXT)'; \ + b='x509name'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +x509req_ext.log: x509req_ext$(EXEEXT) + @p='x509req_ext$(EXEEXT)'; \ + b='x509req_ext'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f compat/$(DEPDIR)/$(am__dirstamp) + -rm -f compat/$(am__dirstamp) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/aeadtest.Po + -rm -f ./$(DEPDIR)/aes_test.Po + -rm -f ./$(DEPDIR)/aes_wrap.Po + -rm -f ./$(DEPDIR)/apitest-apitest.Po + -rm -f ./$(DEPDIR)/arc4randomforktest.Po + -rm -f ./$(DEPDIR)/asn1_string_to_utf8.Po + -rm -f ./$(DEPDIR)/asn1api.Po + -rm -f ./$(DEPDIR)/asn1basic.Po + -rm -f ./$(DEPDIR)/asn1complex.Po + -rm -f ./$(DEPDIR)/asn1evp.Po + -rm -f ./$(DEPDIR)/asn1object.Po + -rm -f ./$(DEPDIR)/asn1oct.Po + -rm -f ./$(DEPDIR)/asn1string_copy.Po + -rm -f ./$(DEPDIR)/asn1test.Po + -rm -f ./$(DEPDIR)/asn1time.Po + -rm -f ./$(DEPDIR)/asn1x509.Po + -rm -f ./$(DEPDIR)/base64test.Po + -rm -f ./$(DEPDIR)/bf_test.Po + -rm -f ./$(DEPDIR)/bio_asn1.Po + -rm -f ./$(DEPDIR)/bio_chain.Po + -rm -f ./$(DEPDIR)/bio_host.Po + -rm -f ./$(DEPDIR)/bio_mem.Po + -rm -f ./$(DEPDIR)/bn_add_sub.Po + -rm -f ./$(DEPDIR)/bn_cmp.Po + -rm -f ./$(DEPDIR)/bn_convert.Po + -rm -f ./$(DEPDIR)/bn_gcd.Po + -rm -f ./$(DEPDIR)/bn_isqrt.Po + -rm -f ./$(DEPDIR)/bn_mod_exp-bn_mod_exp.Po + -rm -f ./$(DEPDIR)/bn_mod_inverse.Po + -rm -f ./$(DEPDIR)/bn_mod_sqrt.Po + -rm -f ./$(DEPDIR)/bn_mont.Po + -rm -f ./$(DEPDIR)/bn_primes.Po + -rm -f ./$(DEPDIR)/bn_print.Po + -rm -f ./$(DEPDIR)/bn_shift.Po + -rm -f ./$(DEPDIR)/bn_test-bn_test.Po + -rm -f ./$(DEPDIR)/bn_to_string.Po + -rm -f ./$(DEPDIR)/bn_unit.Po + -rm -f ./$(DEPDIR)/bn_word.Po + -rm -f ./$(DEPDIR)/buffertest.Po + -rm -f ./$(DEPDIR)/bytestringtest.Po + -rm -f ./$(DEPDIR)/casttest.Po + -rm -f ./$(DEPDIR)/chachatest.Po + -rm -f ./$(DEPDIR)/cipher_list.Po + -rm -f ./$(DEPDIR)/cipherstest.Po + -rm -f ./$(DEPDIR)/clienttest.Po + -rm -f ./$(DEPDIR)/cmstest.Po + -rm -f ./$(DEPDIR)/configtest.Po + -rm -f ./$(DEPDIR)/constraints.Po + -rm -f ./$(DEPDIR)/cttest-cttest.Po + -rm -f ./$(DEPDIR)/destest.Po + -rm -f ./$(DEPDIR)/dhtest.Po + -rm -f ./$(DEPDIR)/dsatest.Po + -rm -f ./$(DEPDIR)/ec_asn1_test.Po + -rm -f ./$(DEPDIR)/ec_point_conversion.Po + -rm -f ./$(DEPDIR)/ecc_cdh.Po + -rm -f ./$(DEPDIR)/ecdhtest.Po + -rm -f ./$(DEPDIR)/ecdsatest.Po + -rm -f ./$(DEPDIR)/ectest.Po + -rm -f ./$(DEPDIR)/ed25519test.Po + -rm -f ./$(DEPDIR)/empty.Plo + -rm -f ./$(DEPDIR)/enginetest.Po + -rm -f ./$(DEPDIR)/evp_ecx_test.Po + -rm -f ./$(DEPDIR)/evp_pkey_check.Po + -rm -f ./$(DEPDIR)/evp_pkey_cleanup.Po + -rm -f ./$(DEPDIR)/evp_test.Po + -rm -f ./$(DEPDIR)/evptest.Po + -rm -f ./$(DEPDIR)/explicit_bzero.Po + -rm -f ./$(DEPDIR)/exportertest.Po + -rm -f ./$(DEPDIR)/freenull-freenull.Po + -rm -f ./$(DEPDIR)/gcm128test.Po + -rm -f ./$(DEPDIR)/gost2814789t.Po + -rm -f ./$(DEPDIR)/handshake_table.Po + -rm -f ./$(DEPDIR)/hkdf_test.Po + -rm -f ./$(DEPDIR)/hmactest.Po + -rm -f ./$(DEPDIR)/ideatest.Po + -rm -f ./$(DEPDIR)/igetest.Po + -rm -f ./$(DEPDIR)/key_schedule.Po + -rm -f ./$(DEPDIR)/keypairtest-keypairtest.Po + -rm -f ./$(DEPDIR)/md_test.Po + -rm -f ./$(DEPDIR)/objectstest.Po + -rm -f ./$(DEPDIR)/ocsp_test.Po + -rm -f ./$(DEPDIR)/optionstest.Po + -rm -f ./$(DEPDIR)/pbkdf2.Po + -rm -f ./$(DEPDIR)/pidwraptest.Po + -rm -f ./$(DEPDIR)/pkcs7test.Po + -rm -f ./$(DEPDIR)/policy-policy.Po + -rm -f ./$(DEPDIR)/poly1305test.Po + -rm -f ./$(DEPDIR)/pq_test.Po + -rm -f ./$(DEPDIR)/quictest.Po + -rm -f ./$(DEPDIR)/randtest.Po + -rm -f ./$(DEPDIR)/rc2_test.Po + -rm -f ./$(DEPDIR)/rc4_test.Po + -rm -f ./$(DEPDIR)/record_layer_test.Po + -rm -f ./$(DEPDIR)/recordtest.Po + -rm -f ./$(DEPDIR)/rfc3779-rfc3779.Po + -rm -f ./$(DEPDIR)/rfc5280time.Po + -rm -f ./$(DEPDIR)/rmd_test.Po + -rm -f ./$(DEPDIR)/rsa_test.Po + -rm -f ./$(DEPDIR)/servertest.Po + -rm -f ./$(DEPDIR)/sha_test.Po + -rm -f ./$(DEPDIR)/signertest-signertest.Po + -rm -f ./$(DEPDIR)/sm3test.Po + -rm -f ./$(DEPDIR)/sm4test.Po + -rm -f ./$(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Po + -rm -f ./$(DEPDIR)/ssl_methods.Po + -rm -f ./$(DEPDIR)/ssl_set_alpn_protos.Po + -rm -f ./$(DEPDIR)/ssl_verify_param.Po + -rm -f ./$(DEPDIR)/ssl_versions.Po + -rm -f ./$(DEPDIR)/ssltest.Po + -rm -f ./$(DEPDIR)/string_table.Po + -rm -f ./$(DEPDIR)/timingsafe.Po + -rm -f ./$(DEPDIR)/tls_ext_alpn.Po + -rm -f ./$(DEPDIR)/tls_prf.Po + -rm -f ./$(DEPDIR)/tlsexttest.Po + -rm -f ./$(DEPDIR)/tlslegacytest.Po + -rm -f ./$(DEPDIR)/tlstest.Po + -rm -f ./$(DEPDIR)/utf8test.Po + -rm -f ./$(DEPDIR)/valid_handshakes_terminate.Po + -rm -f ./$(DEPDIR)/verifytest.Po + -rm -f ./$(DEPDIR)/x25519test.Po + -rm -f ./$(DEPDIR)/x509_asn1.Po + -rm -f ./$(DEPDIR)/x509_info.Po + -rm -f ./$(DEPDIR)/x509attribute.Po + -rm -f ./$(DEPDIR)/x509name.Po + -rm -f ./$(DEPDIR)/x509req_ext.Po + -rm -f compat/$(DEPDIR)/memmem.Po + -rm -f compat/$(DEPDIR)/pipe2.Po + -rm -f compat/$(DEPDIR)/signertest-pipe2.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/aeadtest.Po + -rm -f ./$(DEPDIR)/aes_test.Po + -rm -f ./$(DEPDIR)/aes_wrap.Po + -rm -f ./$(DEPDIR)/apitest-apitest.Po + -rm -f ./$(DEPDIR)/arc4randomforktest.Po + -rm -f ./$(DEPDIR)/asn1_string_to_utf8.Po + -rm -f ./$(DEPDIR)/asn1api.Po + -rm -f ./$(DEPDIR)/asn1basic.Po + -rm -f ./$(DEPDIR)/asn1complex.Po + -rm -f ./$(DEPDIR)/asn1evp.Po + -rm -f ./$(DEPDIR)/asn1object.Po + -rm -f ./$(DEPDIR)/asn1oct.Po + -rm -f ./$(DEPDIR)/asn1string_copy.Po + -rm -f ./$(DEPDIR)/asn1test.Po + -rm -f ./$(DEPDIR)/asn1time.Po + -rm -f ./$(DEPDIR)/asn1x509.Po + -rm -f ./$(DEPDIR)/base64test.Po + -rm -f ./$(DEPDIR)/bf_test.Po + -rm -f ./$(DEPDIR)/bio_asn1.Po + -rm -f ./$(DEPDIR)/bio_chain.Po + -rm -f ./$(DEPDIR)/bio_host.Po + -rm -f ./$(DEPDIR)/bio_mem.Po + -rm -f ./$(DEPDIR)/bn_add_sub.Po + -rm -f ./$(DEPDIR)/bn_cmp.Po + -rm -f ./$(DEPDIR)/bn_convert.Po + -rm -f ./$(DEPDIR)/bn_gcd.Po + -rm -f ./$(DEPDIR)/bn_isqrt.Po + -rm -f ./$(DEPDIR)/bn_mod_exp-bn_mod_exp.Po + -rm -f ./$(DEPDIR)/bn_mod_inverse.Po + -rm -f ./$(DEPDIR)/bn_mod_sqrt.Po + -rm -f ./$(DEPDIR)/bn_mont.Po + -rm -f ./$(DEPDIR)/bn_primes.Po + -rm -f ./$(DEPDIR)/bn_print.Po + -rm -f ./$(DEPDIR)/bn_shift.Po + -rm -f ./$(DEPDIR)/bn_test-bn_test.Po + -rm -f ./$(DEPDIR)/bn_to_string.Po + -rm -f ./$(DEPDIR)/bn_unit.Po + -rm -f ./$(DEPDIR)/bn_word.Po + -rm -f ./$(DEPDIR)/buffertest.Po + -rm -f ./$(DEPDIR)/bytestringtest.Po + -rm -f ./$(DEPDIR)/casttest.Po + -rm -f ./$(DEPDIR)/chachatest.Po + -rm -f ./$(DEPDIR)/cipher_list.Po + -rm -f ./$(DEPDIR)/cipherstest.Po + -rm -f ./$(DEPDIR)/clienttest.Po + -rm -f ./$(DEPDIR)/cmstest.Po + -rm -f ./$(DEPDIR)/configtest.Po + -rm -f ./$(DEPDIR)/constraints.Po + -rm -f ./$(DEPDIR)/cttest-cttest.Po + -rm -f ./$(DEPDIR)/destest.Po + -rm -f ./$(DEPDIR)/dhtest.Po + -rm -f ./$(DEPDIR)/dsatest.Po + -rm -f ./$(DEPDIR)/ec_asn1_test.Po + -rm -f ./$(DEPDIR)/ec_point_conversion.Po + -rm -f ./$(DEPDIR)/ecc_cdh.Po + -rm -f ./$(DEPDIR)/ecdhtest.Po + -rm -f ./$(DEPDIR)/ecdsatest.Po + -rm -f ./$(DEPDIR)/ectest.Po + -rm -f ./$(DEPDIR)/ed25519test.Po + -rm -f ./$(DEPDIR)/empty.Plo + -rm -f ./$(DEPDIR)/enginetest.Po + -rm -f ./$(DEPDIR)/evp_ecx_test.Po + -rm -f ./$(DEPDIR)/evp_pkey_check.Po + -rm -f ./$(DEPDIR)/evp_pkey_cleanup.Po + -rm -f ./$(DEPDIR)/evp_test.Po + -rm -f ./$(DEPDIR)/evptest.Po + -rm -f ./$(DEPDIR)/explicit_bzero.Po + -rm -f ./$(DEPDIR)/exportertest.Po + -rm -f ./$(DEPDIR)/freenull-freenull.Po + -rm -f ./$(DEPDIR)/gcm128test.Po + -rm -f ./$(DEPDIR)/gost2814789t.Po + -rm -f ./$(DEPDIR)/handshake_table.Po + -rm -f ./$(DEPDIR)/hkdf_test.Po + -rm -f ./$(DEPDIR)/hmactest.Po + -rm -f ./$(DEPDIR)/ideatest.Po + -rm -f ./$(DEPDIR)/igetest.Po + -rm -f ./$(DEPDIR)/key_schedule.Po + -rm -f ./$(DEPDIR)/keypairtest-keypairtest.Po + -rm -f ./$(DEPDIR)/md_test.Po + -rm -f ./$(DEPDIR)/objectstest.Po + -rm -f ./$(DEPDIR)/ocsp_test.Po + -rm -f ./$(DEPDIR)/optionstest.Po + -rm -f ./$(DEPDIR)/pbkdf2.Po + -rm -f ./$(DEPDIR)/pidwraptest.Po + -rm -f ./$(DEPDIR)/pkcs7test.Po + -rm -f ./$(DEPDIR)/policy-policy.Po + -rm -f ./$(DEPDIR)/poly1305test.Po + -rm -f ./$(DEPDIR)/pq_test.Po + -rm -f ./$(DEPDIR)/quictest.Po + -rm -f ./$(DEPDIR)/randtest.Po + -rm -f ./$(DEPDIR)/rc2_test.Po + -rm -f ./$(DEPDIR)/rc4_test.Po + -rm -f ./$(DEPDIR)/record_layer_test.Po + -rm -f ./$(DEPDIR)/recordtest.Po + -rm -f ./$(DEPDIR)/rfc3779-rfc3779.Po + -rm -f ./$(DEPDIR)/rfc5280time.Po + -rm -f ./$(DEPDIR)/rmd_test.Po + -rm -f ./$(DEPDIR)/rsa_test.Po + -rm -f ./$(DEPDIR)/servertest.Po + -rm -f ./$(DEPDIR)/sha_test.Po + -rm -f ./$(DEPDIR)/signertest-signertest.Po + -rm -f ./$(DEPDIR)/sm3test.Po + -rm -f ./$(DEPDIR)/sm4test.Po + -rm -f ./$(DEPDIR)/ssl_get_shared_ciphers-ssl_get_shared_ciphers.Po + -rm -f ./$(DEPDIR)/ssl_methods.Po + -rm -f ./$(DEPDIR)/ssl_set_alpn_protos.Po + -rm -f ./$(DEPDIR)/ssl_verify_param.Po + -rm -f ./$(DEPDIR)/ssl_versions.Po + -rm -f ./$(DEPDIR)/ssltest.Po + -rm -f ./$(DEPDIR)/string_table.Po + -rm -f ./$(DEPDIR)/timingsafe.Po + -rm -f ./$(DEPDIR)/tls_ext_alpn.Po + -rm -f ./$(DEPDIR)/tls_prf.Po + -rm -f ./$(DEPDIR)/tlsexttest.Po + -rm -f ./$(DEPDIR)/tlslegacytest.Po + -rm -f ./$(DEPDIR)/tlstest.Po + -rm -f ./$(DEPDIR)/utf8test.Po + -rm -f ./$(DEPDIR)/valid_handshakes_terminate.Po + -rm -f ./$(DEPDIR)/verifytest.Po + -rm -f ./$(DEPDIR)/x25519test.Po + -rm -f ./$(DEPDIR)/x509_asn1.Po + -rm -f ./$(DEPDIR)/x509_info.Po + -rm -f ./$(DEPDIR)/x509attribute.Po + -rm -f ./$(DEPDIR)/x509name.Po + -rm -f ./$(DEPDIR)/x509req_ext.Po + -rm -f compat/$(DEPDIR)/memmem.Po + -rm -f compat/$(DEPDIR)/pipe2.Po + -rm -f compat/$(DEPDIR)/signertest-pipe2.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +-include $(abs_top_builddir)/crypto/libcrypto_la_objects.mk +-include $(abs_top_builddir)/ssl/libssl_la_objects.mk +-include $(abs_top_builddir)/tls/libtls_la_objects.mk + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Libraries/libressl/tests/aeadtest.c b/Libraries/libressl/tests/aeadtest.c new file mode 100644 index 000000000..82fe72823 --- /dev/null +++ b/Libraries/libressl/tests/aeadtest.c @@ -0,0 +1,591 @@ +/* $OpenBSD: aeadtest.c,v 1.26 2023/09/28 14:55:48 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * This program tests an AEAD against a series of test vectors from a file. The + * test vector file consists of key-value lines where the key and value are + * separated by a colon and optional whitespace. The keys are listed in + * NAMES, below. The values are hex-encoded data. + * + * After a number of key-value lines, a blank line indicates the end of the + * test case. + * + * For example, here's a valid test case: + * + * AEAD: chacha20-poly1305 + * KEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5 + * NONCE: 1e8b4c510f5ca083 + * IN: 8c8419bc27 + * AD: 34ab88c265 + * CT: 1a7c2f33f5 + * TAG: 2875c659d0f2808de3a40027feff91a4 + */ + +#define BUF_MAX 1024 + +/* MS defines in global headers, remove it */ +#ifdef _MSC_VER +#ifdef IN +#undef IN +#endif +#endif + +/* These are the different types of line that are found in the input file. */ +enum { + AEAD = 0, /* name of the AEAD algorithm. */ + KEY, /* hex encoded key. */ + NONCE, /* hex encoded nonce. */ + IN, /* hex encoded plaintext. */ + AD, /* hex encoded additional data. */ + CT, /* hex encoded ciphertext (not including the + * authenticator, which is next. */ + TAG, /* hex encoded authenticator. */ + NUM_TYPES +}; + +static const char NAMES[NUM_TYPES][6] = { + "AEAD", + "KEY", + "NONCE", + "IN", + "AD", + "CT", + "TAG", +}; + +static unsigned char +hex_digit(char h) +{ + if (h >= '0' && h <= '9') + return h - '0'; + else if (h >= 'a' && h <= 'f') + return h - 'a' + 10; + else if (h >= 'A' && h <= 'F') + return h - 'A' + 10; + else + return 16; +} + +static int +aead_from_name(const EVP_AEAD **aead, const EVP_CIPHER **cipher, + const char *name) +{ + *aead = NULL; + *cipher = NULL; + + if (strcmp(name, "aes-128-gcm") == 0) { + *aead = EVP_aead_aes_128_gcm(); + *cipher = EVP_aes_128_gcm(); + } else if (strcmp(name, "aes-192-gcm") == 0) { + *cipher = EVP_aes_192_gcm(); + } else if (strcmp(name, "aes-256-gcm") == 0) { + *aead = EVP_aead_aes_256_gcm(); + *cipher = EVP_aes_256_gcm(); + } else if (strcmp(name, "chacha20-poly1305") == 0) { + *aead = EVP_aead_chacha20_poly1305(); + *cipher = EVP_chacha20_poly1305(); + } else if (strcmp(name, "xchacha20-poly1305") == 0) { + *aead = EVP_aead_xchacha20_poly1305(); + } else { + fprintf(stderr, "Unknown AEAD: %s\n", name); + return 0; + } + + return 1; +} + +static int +run_aead_test(const EVP_AEAD *aead, unsigned char bufs[NUM_TYPES][BUF_MAX], + const unsigned int lengths[NUM_TYPES], unsigned int line_no) +{ + EVP_AEAD_CTX *ctx; + unsigned char out[BUF_MAX + EVP_AEAD_MAX_TAG_LENGTH], out2[BUF_MAX]; + size_t out_len, out_len2; + int ret = 0; + + if ((ctx = EVP_AEAD_CTX_new()) == NULL) { + fprintf(stderr, "Failed to allocate AEAD context on line %u\n", + line_no); + goto err; + } + + if (!EVP_AEAD_CTX_init(ctx, aead, bufs[KEY], lengths[KEY], + lengths[TAG], NULL)) { + fprintf(stderr, "Failed to init AEAD on line %u\n", line_no); + goto err; + } + + if (!EVP_AEAD_CTX_seal(ctx, out, &out_len, sizeof(out), bufs[NONCE], + lengths[NONCE], bufs[IN], lengths[IN], bufs[AD], lengths[AD])) { + fprintf(stderr, "Failed to run AEAD on line %u\n", line_no); + goto err; + } + + if (out_len != lengths[CT] + lengths[TAG]) { + fprintf(stderr, "Bad output length on line %u: %zu vs %u\n", + line_no, out_len, (unsigned)(lengths[CT] + lengths[TAG])); + goto err; + } + + if (memcmp(out, bufs[CT], lengths[CT]) != 0) { + fprintf(stderr, "Bad output on line %u\n", line_no); + goto err; + } + + if (memcmp(out + lengths[CT], bufs[TAG], lengths[TAG]) != 0) { + fprintf(stderr, "Bad tag on line %u\n", line_no); + goto err; + } + + if (!EVP_AEAD_CTX_open(ctx, out2, &out_len2, lengths[IN], bufs[NONCE], + lengths[NONCE], out, out_len, bufs[AD], lengths[AD])) { + fprintf(stderr, "Failed to decrypt on line %u\n", line_no); + goto err; + } + + if (out_len2 != lengths[IN]) { + fprintf(stderr, "Bad decrypt on line %u: %zu\n", + line_no, out_len2); + goto err; + } + + if (memcmp(out2, bufs[IN], out_len2) != 0) { + fprintf(stderr, "Plaintext mismatch on line %u\n", line_no); + goto err; + } + + out[0] ^= 0x80; + if (EVP_AEAD_CTX_open(ctx, out2, &out_len2, lengths[IN], bufs[NONCE], + lengths[NONCE], out, out_len, bufs[AD], lengths[AD])) { + fprintf(stderr, "Decrypted bad data on line %u\n", line_no); + goto err; + } + + ret = 1; + + err: + EVP_AEAD_CTX_free(ctx); + + return ret; +} + +static int +run_cipher_aead_encrypt_test(const EVP_CIPHER *cipher, + unsigned char bufs[NUM_TYPES][BUF_MAX], + const unsigned int lengths[NUM_TYPES], unsigned int line_no) +{ + unsigned char out[BUF_MAX + EVP_AEAD_MAX_TAG_LENGTH]; + EVP_CIPHER_CTX *ctx; + size_t out_len; + int len; + int ivlen; + int ret = 0; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_CIPHER_CTX_new\n"); + goto err; + } + + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL)) { + fprintf(stderr, "FAIL: EVP_EncryptInit_ex with cipher\n"); + goto err; + } + + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, lengths[NONCE], NULL)) { + fprintf(stderr, "FAIL: EVP_CTRL_AEAD_SET_IVLEN\n"); + goto err; + } + + ivlen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivlen != (int)lengths[NONCE]) { + fprintf(stderr, "FAIL: ivlen %d != nonce length %d\n", ivlen, + (int)lengths[NONCE]); + goto err; + } + + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, bufs[KEY], NULL)) { + fprintf(stderr, "FAIL: EVP_EncryptInit_ex with key\n"); + goto err; + } + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, bufs[NONCE])) { + fprintf(stderr, "FAIL: EVP_EncryptInit_ex with nonce\n"); + goto err; + } + + if (!EVP_EncryptUpdate(ctx, NULL, &len, bufs[AD], lengths[AD])) { + fprintf(stderr, "FAIL: EVP_EncryptUpdate with AD\n"); + goto err; + } + if ((unsigned int)len != lengths[AD]) { + fprintf(stderr, "FAIL: EVP_EncryptUpdate with AD length = %u, " + "want %u\n", len, lengths[AD]); + goto err; + } + if (!EVP_EncryptUpdate(ctx, out, &len, bufs[IN], lengths[IN])) { + fprintf(stderr, "FAIL: EVP_EncryptUpdate with plaintext\n"); + goto err; + } + out_len = len; + if (!EVP_EncryptFinal_ex(ctx, out + out_len, &len)) { + fprintf(stderr, "FAIL: EVP_EncryptFinal_ex\n"); + goto err; + } + out_len += len; + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, lengths[TAG], + out + out_len)) { + fprintf(stderr, "FAIL: EVP_EncryptInit_ex with cipher\n"); + goto err; + } + out_len += lengths[TAG]; + + if (out_len != lengths[CT] + lengths[TAG]) { + fprintf(stderr, "Bad output length on line %u: %zu vs %u\n", + line_no, out_len, (unsigned)(lengths[CT] + lengths[TAG])); + goto err; + } + + if (memcmp(out, bufs[CT], lengths[CT]) != 0) { + fprintf(stderr, "Bad output on line %u\n", line_no); + goto err; + } + + if (memcmp(out + lengths[CT], bufs[TAG], lengths[TAG]) != 0) { + fprintf(stderr, "Bad tag on line %u\n", line_no); + goto err; + } + + ret = 1; + + err: + EVP_CIPHER_CTX_free(ctx); + + return ret; +} + +static int +run_cipher_aead_decrypt_test(const EVP_CIPHER *cipher, int invalid, + unsigned char bufs[NUM_TYPES][BUF_MAX], + const unsigned int lengths[NUM_TYPES], unsigned int line_no) +{ + unsigned char in[BUF_MAX], out[BUF_MAX + EVP_AEAD_MAX_TAG_LENGTH]; + EVP_CIPHER_CTX *ctx; + size_t out_len; + int len; + int ret = 0; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_CIPHER_CTX_new\n"); + goto err; + } + + if (!EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL)) { + fprintf(stderr, "FAIL: EVP_DecryptInit_ex with cipher\n"); + goto err; + } + + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, lengths[NONCE], + NULL)) { + fprintf(stderr, "FAIL: EVP_CTRL_AEAD_SET_IVLEN\n"); + goto err; + } + + memcpy(in, bufs[TAG], lengths[TAG]); + if (invalid && lengths[CT] == 0) + in[0] ^= 0x80; + + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, lengths[TAG], in)) { + fprintf(stderr, "FAIL: EVP_CTRL_AEAD_SET_TAG\n"); + goto err; + } + + if (!EVP_DecryptInit_ex(ctx, NULL, NULL, bufs[KEY], NULL)) { + fprintf(stderr, "FAIL: EVP_DecryptInit_ex with key\n"); + goto err; + } + if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, bufs[NONCE])) { + fprintf(stderr, "FAIL: EVP_DecryptInit_ex with nonce\n"); + goto err; + } + + if (!EVP_DecryptUpdate(ctx, NULL, &len, bufs[AD], lengths[AD])) { + fprintf(stderr, "FAIL: EVP_DecryptUpdate with AD\n"); + goto err; + } + if ((unsigned int)len != lengths[AD]) { + fprintf(stderr, "FAIL: EVP_EncryptUpdate with AD length = %u, " + "want %u\n", len, lengths[AD]); + goto err; + } + + memcpy(in, bufs[CT], lengths[CT]); + if (invalid && lengths[CT] > 0) + in[0] ^= 0x80; + + if (!EVP_DecryptUpdate(ctx, out, &len, in, lengths[CT])) { + fprintf(stderr, "FAIL: EVP_DecryptUpdate with ciphertext\n"); + goto err; + } + out_len = len; + + if (invalid) { + if (EVP_DecryptFinal_ex(ctx, out + out_len, &len)) { + fprintf(stderr, "FAIL: EVP_DecryptFinal_ex succeeded " + "with invalid ciphertext on line %u\n", line_no); + goto err; + } + goto done; + } + + if (!EVP_DecryptFinal_ex(ctx, out + out_len, &len)) { + fprintf(stderr, "FAIL: EVP_DecryptFinal_ex\n"); + goto err; + } + out_len += len; + + if (out_len != lengths[IN]) { + fprintf(stderr, "Bad decrypt on line %u: %zu\n", + line_no, out_len); + goto err; + } + + if (memcmp(out, bufs[IN], out_len) != 0) { + fprintf(stderr, "Plaintext mismatch on line %u\n", line_no); + goto err; + } + + done: + ret = 1; + + err: + EVP_CIPHER_CTX_free(ctx); + + return ret; +} + +static int +run_cipher_aead_test(const EVP_CIPHER *cipher, + unsigned char bufs[NUM_TYPES][BUF_MAX], + const unsigned int lengths[NUM_TYPES], unsigned int line_no) +{ + if (!run_cipher_aead_encrypt_test(cipher, bufs, lengths, line_no)) + return 0; + if (!run_cipher_aead_decrypt_test(cipher, 0, bufs, lengths, line_no)) + return 0; + if (!run_cipher_aead_decrypt_test(cipher, 1, bufs, lengths, line_no)) + return 0; + + return 1; +} + +int +main(int argc, char **argv) +{ + FILE *f; + const EVP_AEAD *aead = NULL; + const EVP_CIPHER *cipher = NULL; + unsigned int line_no = 0, num_tests = 0, j; + unsigned char bufs[NUM_TYPES][BUF_MAX]; + unsigned int lengths[NUM_TYPES]; + const char *aeadname; + + if (argc != 3) { + fprintf(stderr, "%s \n", argv[0]); + return 1; + } + + if ((f = fopen(argv[2], "r")) == NULL) { + perror("failed to open input"); + return 1; + } + + for (j = 0; j < NUM_TYPES; j++) + lengths[j] = 0; + + for (;;) { + char line[4096]; + unsigned int i, type_len = 0; + + unsigned char *buf = NULL; + unsigned int *buf_len = NULL; + + if (!fgets(line, sizeof(line), f)) + break; + + line_no++; + if (line[0] == '#') + continue; + + if (line[0] == '\n' || line[0] == 0) { + /* Run a test, if possible. */ + char any_values_set = 0; + for (j = 0; j < NUM_TYPES; j++) { + if (lengths[j] != 0) { + any_values_set = 1; + break; + } + } + + if (!any_values_set) + continue; + + aeadname = argv[1]; + if (lengths[AEAD] != 0) + aeadname = bufs[AEAD]; + + if (!aead_from_name(&aead, &cipher, aeadname)) { + fprintf(stderr, "Aborting...\n"); + return 4; + } + + if (aead != NULL) { + if (!run_aead_test(aead, bufs, lengths, + line_no)) + return 4; + } + if (cipher != NULL) { + if (!run_cipher_aead_test(cipher, bufs, lengths, + line_no)) + return 4; + } + + for (j = 0; j < NUM_TYPES; j++) + lengths[j] = 0; + + num_tests++; + continue; + } + + /* + * Each line looks like: + * TYPE: 0123abc + * Where "TYPE" is the type of the data on the line, + * e.g. "KEY". + */ + for (i = 0; line[i] != 0 && line[i] != '\n'; i++) { + if (line[i] == ':') { + type_len = i; + break; + } + } + i++; + + if (type_len == 0) { + fprintf(stderr, "Parse error on line %u\n", line_no); + return 3; + } + + /* After the colon, there's optional whitespace. */ + for (; line[i] != 0 && line[i] != '\n'; i++) { + if (line[i] != ' ' && line[i] != '\t') + break; + } + + line[type_len] = 0; + for (j = 0; j < NUM_TYPES; j++) { + if (strcmp(line, NAMES[j]) != 0) + continue; + if (lengths[j] != 0) { + fprintf(stderr, "Duplicate value on line %u\n", + line_no); + return 3; + } + buf = bufs[j]; + buf_len = &lengths[j]; + break; + } + + if (buf == NULL) { + fprintf(stderr, "Unknown line type on line %u\n", + line_no); + return 3; + } + + if (j == AEAD) { + *buf_len = strlcpy(buf, line + i, BUF_MAX); + for (j = 0; j < BUF_MAX; j++) { + if (buf[j] == '\n') + buf[j] = '\0'; + } + continue; + } + + if (line[i] == '"') { + i++; + for (j = 0; line[i] != 0 && line[i] != '\n'; i++) { + if (line[i] == '"') + break; + if (j == BUF_MAX) { + fprintf(stderr, "Too much data on " + "line %u (max is %u bytes)\n", + line_no, (unsigned) BUF_MAX); + return 3; + } + buf[j++] = line[i]; + *buf_len = *buf_len + 1; + } + if (line[i + 1] != 0 && line[i + 1] != '\n') { + fprintf(stderr, "Trailing data on line %u\n", + line_no); + return 3; + } + } else { + for (j = 0; line[i] != 0 && line[i] != '\n'; i++) { + unsigned char v, v2; + v = hex_digit(line[i++]); + if (line[i] == 0 || line[i] == '\n') { + fprintf(stderr, "Odd-length hex data " + "on line %u\n", line_no); + return 3; + } + v2 = hex_digit(line[i]); + if (v > 15 || v2 > 15) { + fprintf(stderr, "Invalid hex char on " + "line %u\n", line_no); + return 3; + } + v <<= 4; + v |= v2; + + if (j == BUF_MAX) { + fprintf(stderr, "Too much hex data on " + "line %u (max is %u bytes)\n", + line_no, (unsigned) BUF_MAX); + return 3; + } + buf[j++] = v; + *buf_len = *buf_len + 1; + } + } + } + + printf("Completed %u test cases\n", num_tests); + printf("PASS\n"); + fclose(f); + + return 0; +} diff --git a/Libraries/libressl/tests/aeadtest.sh b/Libraries/libressl/tests/aeadtest.sh new file mode 100644 index 000000000..9f59595af --- /dev/null +++ b/Libraries/libressl/tests/aeadtest.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e +TEST=./aeadtest +if [ -e ./aeadtest.exe ]; then + TEST=./aeadtest.exe +fi +$TEST aead $srcdir/aeadtests.txt +$TEST aes-128-gcm $srcdir/aes_128_gcm_tests.txt +$TEST aes-192-gcm $srcdir/aes_192_gcm_tests.txt +$TEST aes-256-gcm $srcdir/aes_256_gcm_tests.txt +$TEST chacha20-poly1305 $srcdir/chacha20_poly1305_tests.txt +$TEST xchacha20-poly1305 $srcdir/xchacha20_poly1305_tests.txt + diff --git a/Libraries/libressl/tests/aeadtests.txt b/Libraries/libressl/tests/aeadtests.txt new file mode 100644 index 000000000..4ca47303b --- /dev/null +++ b/Libraries/libressl/tests/aeadtests.txt @@ -0,0 +1,86 @@ +# $OpenBSD: aeadtests.txt,v 1.8 2019/01/22 00:59:21 dlg Exp $ +# +# MACsec GCM-AES Test Vectors (bn-randall-test-vectors-0511-v1.pdf) +# + +# 2.5.1 65-byte Packet Authentication Using GCM-AES-128 +AEAD: aes-128-gcm +KEY: 013FE00B5F11BE7F866D0CBBC55A7A90 +NONCE: 7CFDE9F9E33724C68932D612 +IN: +AD: 84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005 +CT: +TAG: 217867E50C2DAD74C28C3B50ABDF695A + +# 2.5.2 65-byte Packet Authentication Using GCM-AES-256 +AEAD: aes-256-gcm +KEY: 83C093B58DE7FFE1C0DA926AC43FB3609AC1C80FEE1B624497EF942E2F79A823 +NONCE: 7CFDE9F9E33724C68932D612 +IN: +AD: 84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005 +CT: +TAG: 6EE160E8FAECA4B36C86B234920CA975 + +# 2.8.1 75-byte Packet Encryption Using GCM-AES-128 +AEAD: aes-128-gcm +KEY: 88EE087FD95DA9FBF6725AA9D757B0CD +NONCE: 7AE8E2CA4EC500012E58495C +IN: 08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008 +AD: 68F2E77696CE7AE8E2CA4EC588E54D002E58495C +CT: C31F53D99E5687F7365119B832D2AAE70741D593F1F9E2AB3455779B078EB8FEACDFEC1F8E3E5277F8180B43361F6512ADB16D2E38548A2C719DBA7228D840 +TAG: 88F8757ADB8AA788D8F65AD668BE70E7 + +# 2.8.2 75-byte Packet Encryption Using GCM-AES-256 +AEAD: aes-256-gcm +KEY: 4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 +NONCE: 7AE8E2CA4EC500012E58495C +IN: 08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008 +AD: 68F2E77696CE7AE8E2CA4EC588E54D002E58495C +CT: BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0 +TAG: 2611CD7DAA01D61C5C886DC1A8170107 + +# Test vector from RFC7539 2.8.2 +AEAD: chacha20-poly1305 +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e +AD: 50515253c0c1c2c3c4c5c6c7 +CT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116 +TAG: 1ae10b594f09e26a7e902ecbd0600691 + +# Test vector from RFC7539 Appendix A.5 +AEAD: chacha20-poly1305 +KEY: 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0 +NONCE: 000000000102030405060708 +IN: 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d +AD: f33388860000000000004e91 +CT: 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b +TAG: eead9d67890cbb22392336fea1851f38 + +# Test vector from RFC7634 Appendix A +AEAD: chacha20-poly1305 +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: a0a1a2a31011121314151617 +IN: 45000054a6f200004001e778c6336405c000020508005b7a3a080000553bec100007362708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363701020204 +AD: 0102030400000005 +CT: 24039428b97f417e3c13753a4f05087b67c352e6a7fab1b982d466ef407ae5c614ee8099d52844eb61aa95dfab4c02f72aa71e7c4c4f64c9befe2facc638e8f3cbec163fac469b502773f6fb94e664da9165b82829f641e0 +TAG: 76aaa8266b7fb0f7b11b369907e1ad43 + +# Test vector from RFC7634 Appendix B +AEAD: chacha20-poly1305 +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: a0a1a2a31011121314151617 +IN: 0000000c000040010000000a00 +AD: c0c1c2c3c4c5c6c7d0d1d2d3d4d5d6d72e202500000000090000004529000029 +CT: 610394701f8d017f7c12924889 +TAG: 6b71bfe25236efd7cdc67066906315b2 + +# Test vector from draft-arciszewski-xchacha-02 +AEAD: xchacha20-poly1305 +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 404142434445464748494a4b4c4d4e4f5051525354555657 +IN: 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e +AD: 50515253c0c1c2c3c4c5c6c7 +CT: bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e +TAG: c0875924c1c7987947deafd8780acf49 + diff --git a/Libraries/libressl/tests/aes_128_gcm_tests.txt b/Libraries/libressl/tests/aes_128_gcm_tests.txt new file mode 100644 index 000000000..3ca8cbfa6 --- /dev/null +++ b/Libraries/libressl/tests/aes_128_gcm_tests.txt @@ -0,0 +1,532 @@ +# The AES-128-GCM test cases from cipher_tests.txt have been merged into this +# file. + +KEY: d480429666d48b400633921c5407d1d1 +NONCE: 3388c676dc754acfa66e172a +IN: +AD: +CT: +TAG: 7d7daf44850921a34e636b01adeb104f + +KEY: 3881e7be1bb3bbcaff20bdb78e5d1b67 +NONCE: dcf5b7ae2d7552e2297fcfa9 +IN: 0a2714aa7d +AD: c60c64bbf7 +CT: 5626f96ecb +TAG: ff4c4f1d92b0abb1d0820833d9eb83c7 + +KEY: ea4f6f3c2fed2b9dd9708c2e721ae00f +NONCE: f975809ddb5172382745634f +IN: 8d6c08446cb10d9a2075 +AD: 5c65d4f261d2c54ffe6a +CT: 0f51f7a83c5b5aa796b9 +TAG: 70259cddfe8f9a15a5c5eb485af578fb + +KEY: cdbc90e60aab7905bdffdfd8d13c0138 +NONCE: 9d987184c4b4e873d4774931 +IN: cb75a0f9134c579bebbd27fe4a3011 +AD: 7dc79f38e1df9383e5d3a1378b56ef +CT: c6a899758b6c11208241627c8a0096 +TAG: 7525125e650d397d0e176fa21315f09a + +KEY: 819bc8d2f41996baca697441f982ad37 +NONCE: 08b7a15f388fafb16711ce19 +IN: 9b1ddd177d2842a701b794450e3c81f151f195a1 +AD: 277c372784559784b0e047c6f8b7e9efb6f7491e +CT: de9b9c8fe09f705f558c62dc6d40b75e3aa625b6 +TAG: 52e2d2f153a4235eb6fac87ff6b96926 + +KEY: 682769d52fa0bfeaebe0d0c898d3cda7 +NONCE: 6af0738b249d09547837883c +IN: 3461523cd98a6e8bdddd01150812e6c58d5cfa25d385cdbbc4 +AD: abe8302d7d5595698d9f31011c24d4d180a637597098361354 +CT: aa3ecb46b9330554b36d0cf6f6ac4cf5e27bfd5f602da1b3c9 +TAG: 0ba547961eba5c58726c418f51d31311 + +KEY: e2b30b9b040bce7902c54ca7eec00d09 +NONCE: 28ccf218e8de56ea91422a25 +IN: 483080d7e2fb42580dfb862d2d266fad9fdce7cdcdb1158d415f84b6e269 +AD: 9f06fbe67eb2ace15c8011032feeaf72fdf6d316e1e08ef4cc0a176588af +CT: 67e1980ced4cd232ce893938e40b0798b17a1692476342e520b480a18570 +TAG: 9994185d4329cfa5f4bbeb170ef3a54b + +KEY: eaafa992ef6dbcc29cc58b6b8684f7c7 +NONCE: 1ded022dbc56e9ad733e880f +IN: 900951f487221c7125aa140104b776ba77e7b656194933fa4b94a6d7f9722aad51b2fe +AD: 863ceb297cb90c445dbcf2fcffe85b71db88d8c935158f697023e2cea103ec39766679 +CT: e0b3aaa890e45f1c39ad4f13ba7592f5251d6a02ca40fe3633651b35fba74a579f48c5 +TAG: 5c95fd941b272bafbd757553f394991b + +KEY: a43859049b2702e8807ac55b0ad27b0e +NONCE: bbe8c571342cac7fcc5d66cd +IN: 8673d6ee2903265c92446ce110d5bb30aa2dd1b1ac5558029f23974acb8a2fbf4c74858fc73d6104 +AD: f77c998ad3ace0839a8657e350bed15ffbd58f152a0dc04ffc227d6beb5738ad061d0f83c2a26999 +CT: 40e201a513979b093637445275b2db5ed4cb1fa050af0e20e43b21af6bc56dec654541e55b295b72 +TAG: 41bbef45727d19ee544fba5b360312f0 + +KEY: 68fd608c8697243d30bd3f1f028c5b74 +NONCE: 319a210b33c523d8bc39fbea +IN: 2c088f38f7a58e68bdd92632da84770303cd1ff115d6364479fb0aa706571f68d51be745f5c1d1b44fa1501cd5 +AD: 1417a65249b85a918622472a49df50bdb2766aae7bc74a6230b056549851b3c2f0cef727dc805ba2160727fbb2 +CT: 9d376b147620c2ac6a5eaa8ee44f82f179f61c9bc8acdd21680a7ff03acec953437a3cc9660c7ecb1204563944 +TAG: 05a4fb5be11e3edd89e34d0b7132d0fa + +KEY: 6edd3bd2aa318f78b4a51103cb08d489 +NONCE: ef0027b144691bc9716fbeca +IN: e98f2f99680dc748fe0b57390df38a99950faaf555a888d463d005ef4e4b1c22663d3d3daa812b20ae35ac934c2e187cbba7 +AD: 97337902507391de0f15c88462aa5ffc5e4760543850719ccd8a0cfef89484d8095c23ff8c1d06eae4ff6d758c95e65cc3b5 +CT: 3c54842c2099b73daa9c3f1cb64bb913c0527955d923510f3f3046df471c1365db97333bc5a86dc7c5f23047e938fac976c0 +TAG: 375b2a25421434e5e3a021d434fb2d04 + +KEY: f70482d53d3ef70cdc3cd3c4a37aeb2b +NONCE: e69d3de363e225749cb1666f +IN: 4cb68874e69125e1a6f6e68669b48317e1b361d0f7f95ec4cf613b7da2c835832010e8f95eaef4e6800b79bd86cd7cda869d2df258c267 +AD: d72975f15721bd0957f5cb1edecaad2d1ef047afb0e779035f777f94cd7ed1bdf8ca9d4f357d2a1e195f195e7483dea1476133235f7e6b +CT: caa1e48decbda18e314057c5ec32f8733a5cf03ed0d05c3654531bf56faa70751a6c7f70fbd7d39f7e9775a772aba8fe7731cd0230beab +TAG: 47d909cbdd1c7f8b485fc3232bb7185f + +KEY: 98a12fe16a02ec2a4b3a45c82138ae82 +NONCE: 4b3404684825dfcf81966e96 +IN: 899710fc8333c0d2d87f4496436349259cf57c592e98ec1e3c54c037bc7ef24d039a8c573ec7868e8ce9610b0404ea1b553ae10cc8cec26468cc975c +AD: ea1a99cee666bf56c8c3667ef4c73c2e1e6534800d6e39a97de3bd5d39068bb3e2f74f96c03463afa18f1ee88c21209bae87f37e5d0269b68db370fe +CT: 0431b7fc4889ae401eab5edba07a60f9682fe58419d4140cbf4f20c62d79d8a3cc1f23fabead0e96e1c8c90929756ea1efab508336e1d0ed552eafd0 +TAG: 01053ceeb4f9c797eef9426930573d23 + +KEY: 6538e8c8753928960ffc9356d43306b6 +NONCE: eee386a2b1e310665e335746 +IN: a92eb9a93a90fdbb2c74dea91d273a48efe9582f8af7a4e3a377b114770a69ca45421959fcf36107815e53dc61b7bf018fc42965fb71d1eafce0961d7698fabbd4 +AD: c5e572e464718398374c8b45ff8749cd9f517bbd97767f77a96cd021176c49c0acec8b055ef761f49aa6d910375a45b2f572cd5420b99153971a682b377ac88f09 +CT: f36353de609d0b5246f64a519d89a4dfcd9d53325a2d2cf910e7692e68391b0357b056b944e0b53e41568f304bea8822f9ff7a0375a5a8087509799226862f707f +TAG: f7f9b891089d02cac1181337d95b6725 + +KEY: cabdcf541aebf917bac019f13925d267 +NONCE: 2c34c00c42dae382279d7974 +IN: 88cc1e07dfde8e08082e6766e0a88103384742af378d7b6b8a87fce036af7441c13961c25afea7f6e56193f54bee0011cb78642c3ab9e6d5b2e35833ec16cd355515af1a190f +AD: dd10e371b22e15671c31afee552bf1dea07cbbf685e2caa0e0363716a276e120c6c0eb4acb1a4d1ba73fde6615f708aaa46bc76c7ff345a4f76bda117fe56f0dc9b939040ddd +CT: 049453baf1578787d68ed5478726c0b8a636337a0b8a82b86836f91cde25e6e44c345940e819a0c505751e603cb8f8c4fe98719185562794a185e5dec415c81f2f162cdcd650 +TAG: dce7198728bfc1b5f949b9b5374199c6 + +KEY: fd1dd6a237a12d7f64f68eb96890c872 +NONCE: 459ced97ebc385ab3a8da8d5 +IN: 04a9709fdc0a4edb423fe8cf61c33a40043f1a585d5458c7512ec8e4e066a0f95e2e6609abf3c95a5d3ae2c738269533855daedd92eca20bdedbbd5677cd4eee84b7a1efae0904364f1e54 +AD: d253b829a2fbc5877b0fbe92e7b79f38886a49ca889ae72b91f2c3aebe257a3ffe0d390b5d320bea22d6a5536cd9213612f5ed6e3b0ea33ac91cfee284cb25eaaf6b85b15f7ca894317182 +CT: 4a565d3ba4f2ec461c9bd8dd0f96bc00d2a561bfb56443c8cf47681bdf1c61f55854bea060c4219696cac79c09aa9400a7e5c59c6b6ca556f38c619a662905fc5f0e8437b906af6138e3fb +TAG: be5f93201d7980af4c5bceb24ac1d238 + +KEY: b09a4d99112e1637d7f89a058988b417 +NONCE: 74348f7126c0cac836e9de5d +IN: 6b3c4cfd1eb139b62d91ed5d1d8b0f3b52278d5c48787ce46f12b9f026e3eed1bfbc8c6684c6662f06614c69440b3d7cff7c46b2e4aebaa4b5b89236a3cc75535bc600104f240d01de91e0fb3bcad02c +AD: 7883ad259fa5d856ce283419f6da371b444b9b64ea0ddb371b17ec0a9ada27b0eb61b53bd3605f21a848b1e7ed91162f3d51f25481f32d61ec902a7f2cbd6938a7ce466a37e4467e4ec2b2c82b4e66ca +CT: 5e1b783b20fd740310333eddde99a06b5740428cb1a910812219fabd394b72a22a6e3ca31df0afae0a965f0bc0ae631feeaa5ce4c9a38cd5233140b8557bde9f878e65e8932b9e3c3f6e57a73cda36cc +TAG: 784b73ee7824adf7279c0a18e46d9a2b + +KEY: 284bd8c4b5d7b16aebce1b12988fa1d3 +NONCE: 7ff05007c5d018b17562f803 +IN: 903416331583dcbd31420906c64dc76e14d0c5044d728cd9b605b531ddc350fdaadeabe67d08f0b4c7179f82a1044696716cd96459506453141e9ec3130e893d8c2ff9b8b4c241b73866ca4fc1f712d17d7a88bf4a +AD: d0a1f92f80094c1fad630ca584edd953bf44cdde404f22c8e476df8708a97a0712e7fbd8054caa7d65144d0be3b30442d0dfa5469ba720afe1d00aa6bb53c79c1c178ed42fce596eeb6c638c8a8dedf76a431976c5 +CT: 9bc3708f70a68fc16bcc33099325c821a0ae9a2fd0a6a98382fa21b42ddb3a9ac6c34a13c4805d3beb92586cdf0f4dce3885793d49abce33190685e7009a79242dd93594722a1ceaa44886371c30bcc8312fa2bf67 +TAG: 3fd8a4d760d5b878852b1ca2d34dde6e + +KEY: 6d76dd7dea607a5cf5c21cd44c21a315 +NONCE: c1d13e56b080a500f1cb80bd +IN: cb959b92e777f835afc4ae4149b190638851238b7b13c9bf65343adb3130e8ad2356101037f30997d4a5fcc0a1d6415210179fdec881236a799f6e90dd43ea3817819b432611eaafd072368b9c7036c7a88c8b7774a8ed986134 +AD: 92a2bc3b6b6ca9de0cef10d8bdeaadf6f54782cdb2b09e66cce8cb5b56895636e982f7a3c7bd9d221ade62c9ecf68bde70becf683804386606ab1c48ac764c4e11620064545c5beaa5911c118856dfc5cdb8df50052b01762c6c +CT: 522ba9bfb47efc624cd8933fc9e17784919d2b3ccfaeec46af414c1b316355f65b9f9fd7f0be6ac3064b4016e43b8fb2028459f0fa0d81fb6656be0ab8fd841d05d24682b4a57c7c59d89af384db22c2f77ce10abc4d1c352a1a +TAG: 5ea4a77381679876e0e272b53519d533 + +KEY: 1dbcbe45a47e527e3b6f9c5c9c89e675 +NONCE: 98f2da8ed8aa23e137148913 +IN: bb23b884c897103b7850b83f65b2fea85264784737d40f93ecf867bfdba1052f41f10d2c5607127da2c10c23b1fbd3a05ce378a9583b1a29c0efbf78a84b382698346e27469330a898b341ec1554d7bf408cf979d81807c0cc78260afdb214 +AD: 46f1bde51f6c97a9dae712e653fcac4da639d93a10b39350956681e121fb9ea969d9dc8ef6ddfb2203fad7ab7e3ef7b71eb90b5089844d60d666e8b55388d8afb261f92b6252f4d56240fe8c6c48bfde63e54bd994ff17e0bf9380ebfb653b +CT: 0d90e869d2f4c85b511fdf85b947ba3ab75c6b1845d8191634770413d7574a6fbd9d86897cb3d3b5d3d8e6f74fac3bd2a9b783cb16cfbec55dd7d2f7fc5c39fe85d39bf186a3fdd3564bc27d86f4019ae0cb73f5f516b602331433689c1b08 +TAG: 8777f2002d5a5214a7bd8ef5a3ccfbbb + +KEY: fe33f47136506e5cc14114eb62d26d64 +NONCE: 9534a10af0c96d8981eaf6b3 +IN: 3ca38385513eaf1fcd03ac837e4db95c0ed1a2528b7ab3ac8e09ecc95698d52b7d90bf974bf96d8f791aa595965e2527aa466fb76da53b5743eda30bb3ebd9f6a8a7721fbfe71fe637d99a7b4b622e6da89e0824ac8aea299ea15e43250d2eccb0d4d553 +AD: 50b7bd342df76bea99b2e9118a525c0f7041c7acdf4a3b17912b5cbb9650900246ed945cfc7db2b34a988af822c763451ac2e769ec67361eded9bcab37ac41f04cdb1d2471c9520a02db9673daaf07001570f9d9f4ac38f09da03ff1c56fdefe16a855ac +CT: 927fe3c924d914a7aae6695ddad54961142b7dd5ff4c0ba5ca3e0cf3d73bdb576afd59bd2b54d820d2a5da03286c124507a48008c571c28a0ce76f0ed68dbac3a61848e7e2162be8e0bee8147b9bf60da625cdab8601bfb37dfcd165f533e94a32c26952 +TAG: 9bd47a4a2acaf865a8a260179aabf8ad + +KEY: dec1b34b7b81fb19586c6ec948ecf462 +NONCE: d9faf07e72e3c39a0165fecd +IN: f7b0bbe9f0ff4dcf162792e9ee14d1ed286114f411c834ad06b143cadbbe10a6fbc86f6664e0e07ff7c6876d4543e5b01ff5ddb629f896c30c8cefd56c15d9f24dfd2ed590304a6aae24caac5870ddafc0e672ac3aacae1867891942998c712d45efbfa4d99a8a6f03 +AD: d3c4fc4838cb3cda3937455229ddaf1cb9102e815cb9f519a5434677c68b11a0bae1280faee82f1a5bee593e669e6f81d5ece3675b8af63f1491bb298531aacc940f53678ba56ae96fc66be92b904bc35f2d5b68b3ed98569a4d04e8f8a9689ad9fa4b51db0938a9f3 +CT: 2f44ecf549077b98ba551819538097bb80304a55c48ef853e20ed8c3f808dc8cb5eb41c2463d19fed2606b59cee4b458958ea75715f7654146df4519dc63524a0569a00d7bbc4b32a372f82d955be5f190d09d35c267da1017e8b16096ae84f8a671b45aaf0d1ca59c +TAG: bc3af80cf9388d35deadecff5455d515 + +KEY: 021add6030bd9f3fed8b0d1f16f83783 +NONCE: 4e460f51fe6b5eb9558c4571 +IN: d9aa1d0db5de536cfbacb59bb75c592ae3f34a5f9c5ff4f22d14e8e4bd0754af19570221893797f60c89a251cd6a19c2953662dca51264afc21099ed5c80077b0e10a5295b3c4c6fe47d3c1c84fee69ebf7d8a7d9b1b338dae162e657e6cf5277ca70d47b9290aa7efe67b0ce574 +AD: 38d99cfd7578d40ffa1749d5fe83500362ceee76c5af38935806837b2f2d1b3422a5057bf617b07868dd95d8e5f4a24e74f96177d53a0275450b429a2b1f364805030765e376151ae35001d6a4872200142fdce82017f3e976ab0edac1a08d2649d297648320e7dd9143b554fa3d +CT: 8863ad51578fd1c9dc40702e34236adee885955f0478ad9a094a6941f95f900e466882dcd5b86e1563ba89aa105f56f3ba5ed860ec3338ee1b750a2f9332acb3f0f61718de7e40fb80442d046b35f147f178bd05362f0559a20a53ebbf78e920fe14c9d80d1c9fb21bee152f8ab2 +TAG: 614539247fdcf1a2aa851102d25bb3bc + +KEY: 311c2045d5486bfadd698e5e14faa58a +NONCE: f1cd8b373cec6451ae405618 +IN: bd154e428369aac5c13128d29bd3031364939abd071c34bacac6ea7292b657b794b2e717d9bcb5d7d01496d805283fffd8f7de6a3493ddd8d1dd7f58835a44d43ea22d95468d1239ca5567d6c80bdf432fce2afc544a731a2852ef733667b9f8f4f8923eaa9de3aa32addddf99b607efce966f +AD: f70cb7e67b2842207df55fc7582013bbddff8c7f3bd9ebbaf43827aa40f8490e65397934ee6a412de6272cd568566ea172789a006a92e5920140ca5f93f292b47dc262cefc66b75543f94365c08795b7c5e9c6c29b7dc67b2532fbf8a6487d40a3eff504e75c3f2bb2cc3969621028e2112e67 +CT: f88f4ef0431d0f23911aaa38a4022e700d3a33c31e0c7bdebe00f62ca3b55d358385de25ceb0538242871eb9c24530e557d7981fa0182436e1e49272d52689541f09517fd147a8da0f0d2bb32d54911a36eded0b87bcba54d6842edf461b45839df1cab5176e2c82c871b3be4ec1bced67ec5d +TAG: ae8d847f106e914ffadbdfe7cb57beba + +KEY: ceab57de6220b2c80e67f0c088e97b36 +NONCE: 8cf438aeb0cb29dd67506b9c +IN: ce2a7a5663449cf6e0068085e3c373c5ca6f027544e327bbc09ac00f1571268bee186d51a00bbc16da7429e4d3d5235d8d54ac96b6ecb2fb7d77a6e5b9e70d431dd4dce78ceb972e9e4b63059e350efaff841c2c42bc29c139b7fd070097556b6281b58e074d5271d9f66c6744ec6dd3b9db2f4a21aeeb7d +AD: 03e464d111ac9228d39d22a00120c6ee671fe5bbf462b1ee3fdf348b34999518998ac4e175ed48189c29b49b5527c27c43094eecbeaeacd3cdb48cd15aa82573e884a7b97bbcdad610a6955f7d8b04f6f98a13a907bc2bec4c940b77582b248f5fced1771f810977b2d0a4fa48bd4d78e4bc383bb92743fd +CT: 1fa9c379c78b92fa3c1e478443ae38d7b4b50235448ce2a88467514bc9db95844ec1baf4dbdbd1b0720e377d05d82c3b58b52af8c9c50417b39ad225e373c7ff18ac5a6ea5d182b255f1c8a2766e31e3e4e3d55dc08dfc64b818ead40a0e824b06ab24f0dc9f4f0c383db7cd4d40016b31701bb401b126dd +TAG: a9a885578467430504731d1a8f537e3c + +KEY: 585bbac0ab4508afb8b72d84167551aa +NONCE: 774c82af194277a5506e45ba +IN: d788112213d2b8b5b66b056e8b3e344a7876f6193b59a480c51fc04d3ec2e5166344c833187b14117276fd671a20937a4553181c29d3d85afe385dd86093708226f082a2ea4ec3288f372c772ca7ceae86b746ff428e8add17b0f34f8553e3db63f55224c39edf41f138a2c28be49d56aa8b4c93502b9794a16310f78b +AD: a29665261a8eb58c88803bcf623dd1a14e76af49ec5db72a267f2ebcbc479385fb6b32bafcb1239515d74a8282b228e83daf282d1ab228099b315bbed0f0e6b3427e029cc28c025460a8bf0914bd584c13e7de7830ab77fb4a9258dfdc9fdaa96ca941546477f04cea19a365a27de34e23e154e7419aefb0be0e871bbe +CT: 24f2856e4e40c0b2b8b47e43d94c1faba498884f59d2ae1cdf58c73770279c96feeee3025ec698cd8f0ae25bf0c9fbf2b350674c317e52bad50aa6ed9845e194f294eb71ff192604af50ac7192f308583a3edaf6c7aeb588990be81b801dc916ffd621dd4016e2b76e9078c89fac9da39f3a88f6548006a48b0199a732 +TAG: a5c8f9daa30b045bd3e1c1b01f438518 + +KEY: c5d727d159dd328b4160ff45a183226b +NONCE: 881c0802db519ce1595573ff +IN: 88b4be77bb8a2f37bc5e84ef9da92a4b8c3777dbcccfed13b97e93c19674c8c3f13119363ace377a14e5f36501ba9a3898fc09340886d91bf0a17ef0d028f2a92ec150071623a4a5db8e56e99e764629679943ea879ec7634fad1480e8617fe834c26210276d7db208b13f9b4c2060f2867aacb1b47c8e110830beff721dd8d120de +AD: 5f6513ad3d490f784dd68ca1df41e8c8e1ab9a240ea8e9bc22d0b1d7353da94d5d37c94f0dcd1a2dedd6d8e1c79a383e7e214cbb6ee2ccb7c6d894ffce5d01b6cf13876ae2648d36adccd88710d7d2ab6d43826d37ee0ee3b434972a2cb8f4db1c3304cee0a352bbef76f05de0e6f55a410eea5e697afb197f2483f0200d0abee224 +CT: 66bbee209eb11c675ecd3303c38cf1087b010c532e1357732c4911ca9db78c67805c95c829194cd413b635a900a08454c6eb9cfa3597ab531fc9ddfdc5b02b290be2a618df7d03b1ab465d6d03e8b87a430bf4e80d8cb9916145cf2d2342a91fc79defa151b1f3c695608e76ca2abc4c0383897f1cbb9d4bd9969b2f33813e2b5502 +TAG: 43daa08e6eac70e3238ce655adb65005 + +KEY: 16af56326046c92afca49fe173d643ad +NONCE: d32a935b4e56472d92d9f2ce +IN: c49c8e5769670384d23d9af9834026395d3f3bd32d88e61ed06b2e00e52a5ae4fe3867993c2af95203cd4006470a89677864431fb9edbed17412913bad4bb3eaff0fccaa150c9b13f83b9bf06698af844841a640d6f94d845296638ac27fb5ed87c310dbbd36415161310b284b8f84b4e025267906e0a4c822b76a682d44a70f9afde9bcf48ac2 +AD: f713886f4086026779a7e479fa646cb33574e6c977d70b8da49c8fdbb395dc7c149a59e219db8e4fff053cb00e2a1df9850fce94e52fd34661fd3d4cd8ad3ffe0b4bc7ccfbbf42eeef3e30ce13cdfd77dbd067ae9f5aebfa068f6b7ae2c17ad956dc03511dfcc38eac9fa3c0c0e9a340f5c58e39d868b77dede54fea1173216c0bb8f0a6c2990f +CT: d5d7d1ed0ae3e3481e2ccee201857ce1f427734fbb4fbe82a2b90601104008b8ad4daf74514b8ab3e42b6f6b509159ca04489b1175ce1e3fe33d36ea521e0aedff8c69fd00aa588d7a2eb9d2d551e2b8fea321f573e2a1df147535a873d540a3169d3ebc099ea6c33cefc04a2d55dc2d47237b95ad269fcdcd3c3750af426beb4edfe7837b413f +TAG: cbe0fb9509c224bb0e8e33f7ef9b49e6 + +KEY: b3df227e6dc2c846095e2a3b825d7645 +NONCE: 578bc24ca3845e23204df661 +IN: bf69be81cf0b340b006badc9f644d10376f4f9a7a78c997edb8729e3786447f21e97e4c1e0c0c74e01ef655d0a84ffc04ff7c6712ad65adc9a0da2e3078d4c9e796c9bcd71e7a9da26b987990d366b5e00a23a93652e10942e07a6aa01375af27080c9cbab5f554497abc48260937a6fe895361e79cd3d5e78c1a65c6723d4a4fbe9b3dcae3c05699cf6d3fb +AD: 00898eedad307fc017917a3296bcedabaad8a505edd34e93d92f3b61797ddccf3fc31144ef70f255be3b0c165c97eb8706f14c495f4aa9b3f15d2dafd65bf6741d67fe240967efbf0e75e610db9a8f722035e039b5e9246d258084a04c12ee8ad1668032f8caec737481fd894dba2ef702d3e6089acbb0fe0bdd6daa2a5cd47fc62603499fe3ea37365072e5 +CT: cfeb249551a695ddfec5f789e7f0a9f916abc8ee01d6233c32744c10a09b5b19ff9ed15e9f10de8f93c8ca1ae3c34e26fdbbb7f3b0f5f8b064501830d3cc982da99b294ce51bd33085c98b0ac0bfe44a8f4a5a26511afa3461aa88b770f076fe119ec90f33d8c9e7777f30b8cc95864f06e04dd8e328ad7a2c7dab83b03abfdde065bcd0c7d6dd47389108c4 +TAG: 3dedd1054f1a29286a51817264317b83 + +KEY: 58a57f04d1d5cbdd1bfbe01dd5f7e915 +NONCE: 47affabd7dbb4cce76661081 +IN: 5f82d481a6a3856c6f0be2aca54d666f16de88294a4d763134dd51ef03661bab45da94b9871d94e5b574a52214b22c92cf9690ecbffca9b108fe796abed9e608778c0b99d7bea1daec08dae89d5f7229c04fd52cc906b5f5b9fc0f0fc1e0b2272dcf4865286ee22bd9edcce1afadb579ec72cdf6038cfc75c2dbab5a1fd64b6f8e200d1ad0afcf25863293fdb7276648de +AD: 4b662822b48005fbd85bb99e6a946eaa74403909f646d914a236eecc5f4558b60b2efb1584b1f32d936b90428dda6568515801d21d24d6fb622e6463897c70be01f81fef741d6dd5c6556d163c3f048abe49f21817b41850ce79d7ec1fdfeba32935b58d898e964fa4b36f79c0f1f560b0afec3887ab325e1a025fa7662f9baf8e08a9ee714b8369621a2f1e6d2e96896a +CT: 31ab08ce0aaa883628f4b33369e5f6e5a54ee4a6596f25ecd54eeea30e81b41d357cb6c671adb6acd3d4e6654feb2ab1f3259692502efb33c5121e0852cbcb2dc5d9a4c65752debe9c4bf5e995fc909a2881621d46cc220806703795e61c0fe74c99e3c1230521b1f97bcbf4e95326e2d581f0cc879a2fc06ef88226a4413f9e9985edc913c418cc198c4df13cd46afc24 +TAG: 1e54066c6cc37f35c62b47426b609457 + +KEY: 64011470970333b7b677d4ad8ebf3ea2 +NONCE: 17031c5133a426d96de93123 +IN: 882cac1ece2d22a1db7f8339332379eb68516c8b7dcb3c089a5bfecceb49f48a169215313686eb5708135f379d89962af478cae865841e0c97ab47a57a456f634282c4e03c99abf7f7cc4e8360deb48160288f06e96cb09114877f9d91dae98828285626a1528aac87f39cfb8ad3db344fe4318aeef6f6ba14bd1edf9caab548c09f8eea091229a90dbc4b0fa34fda2bf13d300a1f9c +AD: 0394bb920cf58806b909d90c046402c745f6876af85d8a281081e22a1908f8475126594b39a0e191a070bda7c78d30dc4867e69ea522cfc962fa5f9915daea9133e998eab22f32a18957a3cf7d91c6f3d54cea94875d60be694ee841fef01e69bf5997ba4f25e846558431eb592605265f235211c2bb2d4807278f4b9c314039d0768df24e9c098c6a01c689d6a143073fb1a29f4400 +CT: dd347d6a3d4a71b2bcae0a0c690ca311f012c6ceda4f7fc054b8f9b59bad54237b64b93331b99f1305801640a68e7d50cef581a57ff2564c90995a8dbf57fa8cff046d0b946af5f68e0aa3d73262965622fe6d35c78f949a6cf9e4f62ba71accbf403b690e31f610305faa6737a19efba1e1ee97084cff2d125bd69a5a4ff99aa399df650452daa835b3e54114b295f00d94fc60e2f8 +TAG: e5e72cda6755bfb3a44377945adb5ca1 + +KEY: 4852e546fdea545d7dd12493a687e895 +NONCE: 7a3e136cd961191570c1b0b7 +IN: 30c10d7a63b614bcae1b79b07c252dc55f322554ac34ca664910fe4a0c9a33e30698e124d91cbb55cf34e931807cbe591a87667f2284c1c18dacd108163aa7a82e274ae659c4ea144191e3fc0f82d4cac929969a50b98ed9fbee52cdf465a1f0535d7d7df15a9a6eff3f4a14e254571cc47f82716d7a835dfa839213677c4da8c8623517244891993ad5956f65d318d9bba16f1eb54d2974a741ac +AD: c5ded7f545d2eaccbc2cf5cbd1b38b0ec3b6bbc054ba25a16efdd448e5a47b0085974e469c1b0df22441340170d6677f5158e4ccd71446d7ac73dcf5fcfe4ad7248c4ddcfab4c8ccab0968d74d66d9c9561650eb98c088d87766440fc9967e8463febcd12ed07f7e44fef47cabf05274002d0014c4e31f230a41171868db68bf5a83c902724397ed181dd8c6768a898e0c78f6aeb886df95442e99 +CT: f798de4998683da7fa9ca030a23dbc493f36c48bb52cd1113c3ea97ef2b67433c00195000777fa3b75a3f689a66b148159524a1fe9576587948760b279cda56164a23748564ec66ea51368ba2a900c97169eb33cf1e557f46100193575737dba670175035f0d921675d45415c6591cae079698e6b1f74e82d4b9216c20e907b148a1d514b2cf653d2e4994f7f668dcfe88dc49c29c544de96d8dd0 +TAG: 3663fb2672223154981b4c580ed3d2d9 + +KEY: a65b520a2ab67a24fb8fc669c41f2753 +NONCE: 3bd6c7e8d29242abecc4c108 +IN: 9d1559d283f7a38847088116f2156b19a8feab0731f04d0d499c6b0d21b8563a89a9c284230c1298b28a622cbdd38dbceb098ab896a7259caaabfcc7b0d9ea797178c18aaaa351c7f516342dcb9d3e91405882c8faa9a28f7c67f3db8913b31c0dcd56472d8ebbfb20cda2896a66bff2706b12ae0d9bc8c6c123c02f1f0bbaa418c1806482423eac72d718cad0dbccd208eb81663a9d9043d6ae7a52cf32b1fa +AD: 2538529cc6eec03f70df2ab085027ce015279484981422f31e58aeee31e79703d72752af2b8822dce9b385f1530f19e692e00e20ef973d333f4bd585ecf122bd4ed9b0626cef46baff0302c71411d27e372361f36c7245096faff21f0236f3dd675646760d5687b3cf1544dbcaa863f1267bce04bca976616b890c7c6ff3448d16072c3938f9b62377609950ff7818cbdd21fba2560bf1954a93517962181b18 +CT: c3194fbb5c319a94c0f61c432a730ce7611a005cfc78266ac4e5d7c95351e71d613f06f52d9d008b9d886f4d9a57bcc232d47e0c75ab755dfccc057a9c7558d7fb696a8c29843a8b9199e2406d23cd6507d35a872fa54cb95e2cb9af45405ebc6b6ee353e8a80debc393329bb9499c61c6344a6380c118f30fcd76376a9765517652e1b21ecafa63c0d19c1875658f1eda89c15ac2daf1a6f526ca72ee792a4f +TAG: fc16cd532c926ba01e2e6b15327bfb3a + +KEY: 84215d2c8f86e5b7bf93cb0620da6bb7 +NONCE: b35e99ce89dffd1ec616ed92 +IN: dfe500919f97713f6d9c4f53913175b162b8b7587d85d5b63f0cd5f51def23119e2e02c224142ecfba7f0a519aaea3c28be20b9c2a9c98eb145afd4db523b7f0b822e67dad630846b2a192bb146dcbeae00198c81b80c290d881125c24a6b01ec901b8912bad5b081ec7d97d6997b33052ec287f692489df928ce36cba1e3d6a41cf10c697a9e1f4aaf75dc5be054b98965ec3ce173be7e127c4c5387048ae6ab5a8d247f3 +AD: 6bf6222e64a46c90f83f47305554d090bc8d3838b7a856f0e5e1d92c4e7231eda6af1d9eb7ff6ce914f2256a3b0c853453b9bc75e46109cf8d7e8a9dca224e022d3d1a139d00476775622799541edf9d53eb645a40f6d98ea559e181d96e4df0141e51fe067542300581c0424f534d2c2e3b1b27153c0cd496a1c03301226beeed2b5cce0710d1f485e68b44a918b63fd8db610c7ff894514e272b6ed7ae33a38907e0698b +CT: 6c6faa54df62ba5659d45f64a5f014684138c93bf152da8a495e9d067b13a30b9fb84847f56231b2da4d87e6cd509a3e38a9ff47589c627e5b5a1196e27fc7afaa14a8432c2d10d8fbfd5d6d394e4b947c456420708a76c2aa638df7de119c160636fc8dfba32227c5de12e5ef429da933ab04e77b489f2eb761d0c753738647ad6793cad64b8942f621ac67b13bd0cab106ffeff21f24c79de69424e50ae550f2241d4029 +TAG: 202b232472d050b9bbc68b59a0c02040 + +KEY: 7c02b6bc3db61e23736c5f36faddd942 +NONCE: b958decc680d5f79ea7b8632 +IN: 7e5992ed0474f4224b8da1d038eeb78413fc2f9614fab7120043e75986a4bf1114a80703780a149fcc8dfd115b768f45917065c85176a3f00be40b427fe3765d3919a5b741708624e29bcae876d251fd46dd8d36a8ef66f671c25f984761cf7f75f4329de7093937cdabe32f130b77531ab1aa0a1bc38fbe2758c2664eded828b2589fc5c34d9a0d57a5a4463163736f419b65f0543f50207fff4cf1065a551bc00ffe9466538b673b2a +AD: 76e430fce1a7d8340104e6001f1c2048d457ac335c5453e48727244b75c3c4f04f55afbb5ce55ba6f8632dbc168ed715b83968a32e5b8e91cb24abc9efee6dcb7a8bed9394a546f0b9efc5823ecaa192df061eb41c671bd863498c2130f322074a711ee43791a1cc02b5cacccf25119ecdd99233abf3b131c83ddb8c62c93a0d653e91499e7481303adc8dbac615ec464eb8640ea138f6236b0ee31cea060f97ea9145a22d15e28eaf6b +CT: 14cfd190ae0521f94ee6b36bfcc403139782bfac3d33fe95c81f53e83c7d0c9a8fdebbddd79746b550a383ece1b5c93316b2fdf5aa36b4e97f739f78ccd2de9963ee7fb4d77b581cf676bb679b2dc4a48d977b45564f21181dc60ecee84d736f2324196c20327495d18973660ccb5dae69b79853d12e48ee0706c8ed821b7f722e46f35c8dee2b7b55ebee01dd3ea1e8ef80493cab6b27c264a67596cee06c15062e3a96b140d0d9ba38 +TAG: b6c47410e6f4a2f2b172c6a4490732f8 + +KEY: 1f58ccb33649d0dc91c50f2aedc95cbc +NONCE: b3a392b1fff0157e95f82a44 +IN: 738e04dc5a8188d775262c2cdaa04468844755dc912a4edf9db308efb3c229b8e46b2b34aee2c6330219bcd29d3493e3cead142cef5f192b043502b8a4cf0419f9b3f5e001a640541c84141e36d585b05a2f702356bd39bda518c42b461564326969983d22c3ac5a2aa214807ede803d57a61c9547505dd7e08402cc43e6ed1574a48366cf5b5573afcc7aa3c4d4721b362d20a58cbf251315f2b5f9e2c97c5ef6bff44beaa5004e5b7c7f28295df2 +AD: 93f7f5054605edc769efc30b35018ee6c929a83bc6454352c69ba9c72e4b4ea6f51c9ed06f314b5682be6a701c719087765d0a7022e5c9d495f28a9053bd435b8b834045c3670856149b08dae742b372a15a0184375d50eb09877bf94f63859e64228606791c516e76c5695a4e529b9dc5f76eff1d4641a22597e4460aea4eff107348077d4ed2d6262744b0a2d6610f25264d905133309ace10bb52f7138674c25e5d43ededbd87c13dc8fd9d3b1b +CT: a002b47b18d1febaf64842fe9011484d618a2e855c4efcccc7d08f02dc9b53d0bd4fc8013e01e21fbf2d9bc7fdda69e68be0c06d32003d045dca6bd251c0bb8c2cbe3693b252265c8694295772b767f83661ecefd57353f6f1c442f9d21ed98c55cbe1db8171ef7b54fe3e3a1a253b4dd48416b5fbc7c18d73692e9fc90dc75d4b88de1fa47c9ad33ddfa4e582d3fc61ca2a8b1eab898b9992c8e56d170730454ca50cd4f28d2759388cb8e302be10 +TAG: ac502a9a52fb3a68a7e90dc639c7ad42 + +KEY: c67510714f556ea1744af9207917eb60 +NONCE: 71b347a21653cec3d113087a +IN: 7040fde3513cf7f1886d7be9c0f371a3b75415e94c3bdfbef485081199bec4494beeee76dcea05b6601ebd4c8fe231fa16d3b0f046eb3e9c9ed8baef25bb0ff6bc85469b2eb41b929fe904735f819b241b01230c68c0b61577899426bf0dd30e085cccb4ac290244d8c1cd7514412a3ebc51aecb6bb4be1a5a4a8d2ff3fc99191f7d7d0b44fe2cc4ec34deccf901f54e3dbe19d2dfe663855fa9d93a01ab14faed7f00c14834f63e1d153441c6fabb3cf22506e8 +AD: 6d28b410c788dba025c387f5b94c0bc392c69ef646b9cdce53dc169326359de26a721703d9a7c5017631a469da13b2d9ad9115de7d06922ed6f093792ac25ae2e27993ad6be5217dc4f6c51e18f230d4eabb01a474704b71b1407d9cff921bd98e28bb60c4fc019b4d609667c747e83eef779ee62000b6800ba2666f415dccb12d43af4f585d3185d66ba2ecf0b0fcddf762445dd1b6154591dd069f03977243b45b113b6f9b110f9fdd96f0b74e2c9843a45c6a +CT: f2a2cdb4f890241f44e00b3373769542cc3dd24c3d07502ed162dfa10be9906871051b991f36b2d5c4240df483c2ad704be14b9efe79ca704e8eeb9dc250e75a92ebf5800c59fb9a6a32228fa1121d21e0b423b77e20010d36b9e6c68dbc000f69bddbd521a1f7bbc9d7e431e4e46e5094be96a928c6729293d2d805c468a3993fb7439f192b1142272a78585e3b7fcedd2f7cced52ab2bc42e2521603b89ba7633fa3b4d07d9a314d1159d7bd5b2dc5198b0c34 +TAG: 0b386c3a58ad23e9a45f00ae107d319c + +KEY: 171d25e195bae2eaf666993f3b42d690 +NONCE: fc16bde0c69d5c894642f1f3 +IN: 8775d6aa2e46ffea6ad4439000a968bcd4fce86535b7265684071a498e0bfb37646f56fad79e0fdc4d6016fd1e935dac5ad74b11c69f5261c3321efdb9cf03f9b7ec681a7f708ba8e3f66648b24c41485a5147df31385809c800155d0d4bbf41d248453302c3754eed4909b267893309ba5249588cb4a4a14b4a29496f1e799559ac9f4baba7a9b4cb5bace1c11dc0e7ef7a2ddd2596c29cdaa378b97c7d3c50db49bcadb8e1840c6b9fa12ad88c0b8152fd753efb04ead427 +AD: ebb169a863dd05cffb9deb866bdd130a1c6852046881f3f8e9013158c83bfcbaa98743957ed4b0619eb88d7ff69b3a5d06da74076c3cc2dff83dc0375236d363c0e2b1fb60c9cf10ecc0fec94757b1b719abc7066af15ff9b66788b38083f766d67005369319967995407ea20339ba27e7bf1dc263fdd54ddd8088232a500f605ba825fedfed69cccca75c207b06594d1d0070ed12a259d4f574f352d2e2ea6fa45199213b6a42d53a7c717250715e0404f2fe7b64e3ec7e89 +CT: 8694eac2bb3968303f795bf0118e43c132c9dd22ec320ecffefbe878ebe6b1e0833d19515c07ebc83f12cd9bb50d2658e6d7fe44a9fbcc2225e93ed58e1bebd78edecbe6c8b3491eedfdcc957cc8ddc95d8116d50cc50b1999ac420802605cc652134ce51a41533e00fe232344e805df146a952b40ce27a2f5c6bbba2154489ca40cbb617476ce6ceac1a6b9c0175ee33615f252377f52583e970f77795b573610baf5cbf5edc6d2837244f88bc155f71588c9c4c1c802be9c +TAG: f6725998336b3ef020b99818e0d932ac + +KEY: f7db0fd345ca6ca82ec8624950f8e672 +NONCE: 3e7ee1a209b1a191f0a00370 +IN: fa86869e14df0fd8e77eba7fe5a933fd1bc58654deab310a03aa7202a089713e323a323f4932b4b8f6b40982d6738aef48951f621aeb82a747d290d93d1eb5bdec6a62fe66774209a4aea7261acff80af9512af090e0eb0f5905ce8baf2a0ec50ed89906d8d67f370639e6f16eafbdfa982897cd5a3f88929d7f1032a8b3355223bf666be94ba9945fb5cafe655d59af69829ef92365f54ff3eebc45e01ffc439b16e23ce892ba6db7e661fc3676a175a8ede746000ca147db57a14303a1 +AD: f7b826afe62356f985e8e10ff356dc9b5b9d9df24486523c3bab7db355c84ec7e4bbdf66482b74fc6b4c6aaeccd7717fba44eb4820a40f03639076776719ea7aabd3a815c201146428bf4c6bf1e8b056b5a22ebcb214fbba64de54089a20ababda5c860ec301f36e1801fc55fe8fa189f35722a2cbf83ae921a9537be2b4f060d918af9b12f9111909d59db7cad24418896ce49762223d8a20a3a83fdf24b64703c19c78f528daecaa8689f307da7fe0befa1d6b1bef24ac8d9f5f12b6c1 +CT: acdacc648833698eff4d42a5dc0b123cdf6f2985ef05e6f2d42c9cd04663635d240648da18dce158b21cc0a3f7a2c35441799a4f1f5622e11051c874b2bcc64314bf0b94c2589d2a24d996af57d22085a64f10135322cb68428fbb951d8b14683bf6fc96b1395829a0b05ec83eeb20e54daf7a413e070ae1e0b73bde56faac630363fe215f1883cd9eef9c3b7d076bbb56f6f5ffcce0d31570f79be8864482b6b3666424dadb674f873a1b52ae6e3d8ec8984edf54186e38c71602098308 +TAG: 4dba5b1385565427a987c9d0b030f4b2 + +KEY: ca80ac4cf4057182d06d65dcdc09763a +NONCE: 63cdd8090e041baa9dca5bec +IN: 701c739ba0c146983b9e1fe0a9723850caeb818514860c3d4adef10dc5e020a8dd7f2fa282896170f9039d5b3fa629dbee3bcb81db44d0d68f9522477619269a59ec1a9ed399d4902f25271dff5c42f3747ab0f4b61c26a2c1bfe1c0fed02282fc2ef88b47825cdfb11df3ced0fe0227e8264132dd62af2d31f23d0c0e253f01c80400127c37806762eb28bc71f31807229172c78ae994b4ad800d6247ea12d3f4f902bb50b72c132902dd4faee05e67836facc7001c8f58475366668ed20d4899aec4 +AD: 0e91b38fdc70951b97e43aa9ea2c6f78d445d90ddf4faabd3e6e0ef74f528fbd5c3d4da18cc3d8bd3167b756da495cba49ea35e2db849bc37f6db8370b492d7f82f2efafa5444ac62835cb5602796cdbe85caa50084e51eec2651996d2da0dc18fe10bd6f374168d4c9ea0a36ba665148192252ce9d05cb78429c55256fbb65f1bbffb8799d63bf41701d1d706a44e3f27eb245cf720f2a329ea24fbea803c575513830fff579a1bde3daa975eecdb8d3956ddd374fe252637aac86ed3c702c4ec63e6 +CT: ca46eac0addd544bb45a97a4989d45d21599ec70f843d9db38157d186716dc39a5d1a5c0624e6c825b5b7f1fd41aa542ac846ec0edfe6bc28f727823667a33cf6cb5ba1ba6654cd023857c53ff00a63b34d2c17ebae5d46dbd073edb7b2f9e02842dbf663bbe36238f3eaeb7a23e328b0d3d50f49674253898f360c0243722af266c934f021e4f2fb8747fae728d06717b2d68cadbff762956826c910cc8ad2d4aea4518d5ac4deec978a13072fd1675a272539ebea31d736c759227f31abc911e0e76 +TAG: 9f0202c228ec48f4be6b2f876fd05a83 + +KEY: 9c2daabcfae974ae165a2ea58ecb212a +NONCE: 4b9317e4be2256a467e2831c +IN: 09169c1f5d873f03821393bef013bbcafcd82314cc986675922e2d43031417c8e65e625ce737af4621aabea6fe75030b84acf96967e791f8427b8f052051d6247a897006c6ddedd49cb7148afa5109a561e78abff7c55b97091f356e31b5667270d5653a497e2503d75e5856ac1efdcf3fb6e80b8deba8802acc064905e2b09d45e446d7d810971e5996540ee9c01fac1b4331f99ad329565a8db38eb93f2e2a8ca37d64d73cc8a7f4fe3234cc155226393f1f2ad17d0f01d5e60537ea44835dea853e027dd597f7 +AD: 1feb0ca13b3022456a4801d8f5382cad95f7a50e466a102d2208e7482dc8ba5c710d1721de7103000fe8811bb13fdf698844257dd164f1e21b0707251f228ca8bd437994526ed5684c4165c9754d1cefe7eb18f9e116a455c28db1f7c04feab74ab06af029819f51ed96f453fb6a634f73ba8c80e19dc62384e82feac70a12d42e3125c360ec2a97f4ce0a07039687ffc37c5dc1df1ed24f05a37591fcd5c34a3fc5f825c79213adbbdef65078f5e41a4062517334a67560ab215fedde53cd8129a51f27baa80f53 +CT: 8a4d4ae0842f8032d83b2e4eecfaea439f745f1d0d07808bee4b68e3b58fcb65a4c8fd9b93cba2d5b4781d28a9cc01508e9e85796551064867551f9083cce342ba1aac4d2b8f5b0b0e4e3d7c82082c441467e47aa2b0f47e167b28fd29cb8d5ee52c2298c1f87cf811061d922f056214346c1ec3d2534045c5c485ccddac7d9998d3d08a80a62eceb2ee18e1a27f97616969df52ec486015974f160745667d6be25ffc20b143d89bcc8b6eab9dff82ce3c8f95a034316a8f2f2a52674105f1246b2daa28edfd829d +TAG: 0361e65b1fdb9d967492ded32e1fe811 + +KEY: c98ed84949749efd2ee41eaeec51edba +NONCE: 7b056c9c7b393b0b04382946 +IN: 41b87fe62c82bd34cbdc70033ca8d2ec5f13eb2c14947f97fbb5d97da7323f8eb5c2eba210be11b1ab9554feaa516aa493822af4a264c8849e9c6ff41f690f44966bb49c9c1df5995de8070a2fcfa42d0b0b5115a36738102134f571988ba4fb210edc3202d3c74b5f8801a7d1e217b90caa27acb49ece590ebe6637fb6e2f5f0b849f29804efdeb8c102b3e3d2abfc4f6f2c5f71f0a6e4d5daa5cf16561914f14601edc40547d55f7d11eb4768d5c64fc621d04e8c64aa3aa1245c7192852d2ccaaabd448e06f806eae66da1b +AD: 2fdac5a70356c2c8d70def497321c6bee8ebb08a5abc8dd508d83f03bf1a09942d7f7a387d4f875a1ff16c7b5abb53d32bcc372012eab7a3b848a93f7af634eff8c5deb3269d418be698a3026f6f08f55a6e31543105cf1ccf56193cd1af802f32e10512a6bcd3101b7b54a8f3efdba03018d5f2475b51bd65e5e183a62ab11c9462450883e3e87a9640eac909f72b83da8bbd34431ed87d14c6f7e79957067c1cf2a12b5fa083496f903269a3c6c8ccd5e3f9cc287904223ee62bffc4f157f0db409e82101e3ca5e05d962378 +CT: 384ddc8e7ed6868aa722f6785fab15eb69caadf43246521b97c8d016afd976360365bbfc9f48c08b0eaf5437af8a9c23061dcbdd0d22e1d58c92951b43e013689afa6b1587f79fe9ad3104ee1f80b3c95388e35b0b9a5a3b733b32a3e62fc143e6255d0e5b1b55bc9439d3c1cbed610d36c3667378bbc1ac20d93a5a7e5563409a5b94ec799a5281213d724e46f4987588e6bc7e9e6468bbcf340d5f1a1eb1b45dc9fe9c832befff54c8a85db9c07196d7d45cc389fc9d62f4bf1f4bb82801cfa9c408498331eef4ae1ee2809e +TAG: e8cbdc1d6d51ac64f16cf08725f81370 + +KEY: 42ece9aeffc9d2e8ea02e73d1a4de834 +NONCE: b59e0770c689d60823c06c69 +IN: eccbb9a2c1241c88d17204cb0f0c069e20512bb1d31f966349add203d84cbb79d88f7add957a0a8370b9a0e04c9f17215531cd48d08c4612bbeeecf3dce68d41724166e06a331e7897e8c7c6a6affb7bf07dae1874bf3bec044d38227bef5c228f4cface9ea37255e15d6b27e154b349b16048b0e7984f17cffa03da07924b190f9b91d6222db1124c1e4e77c2b989fe2a7c338c7316a49c7df0be173d0420e8790bad669f6da96745cf34cd2eb429d18eeb61a8e80a5e03294dcf3a5886bd1865e2a55a72574db8db04a9560f969711aa7a +AD: 2aeb8ee162a7aafe5a72a8d8873ce3bc43a65fd7bbdef1f6ba71b61e5a9c3bd033e7e8eaa55e08ae381362ad0991d65bf22c99a425019c4cd7768622f108f5917a4be22b4ab65ede66c58191e402f8cdad69decf6552dd52b62e8d62268b84122b64145c97115373a26d2d5e59e69b7dca5f96c48106e9fb3f7fc7e0ab11c78a1fafc697fc73603d3f08fdfc0ee885f84572fb04fda718a21744c7e5dbace91b0e141fa82fbd4d1a7dc35edafaba7c5894778c5952ec787bb547a37e509b035c684a8f51ceac5e12ae71b165dfe957c6de15 +CT: c5874137f5e75ef02521b37f0759b5724798aaab8a1e62df81b73175690ca1d32cab6e7a9d7803a8aea420ab273fb46eab9e5f0773b7f5457d7a8c0058ed9675a6e1a7f15805c7fb695d277ba06adc3963606ead0cedb342614cb410f4197f4fad0b5df2187f8d2ebfe85ad3d5f59bbf652364c7e8c3542c5d7f15bc6e6c24eeb1d3232bcddf6588ab1c1953085bd0a1516046b76714d2b97718ce57ad23cd213507f6cda95ee9c5c23036cc7d4133c84a1d36393979f9d1bbc613350252a6de78d905607adf51368175a20106f81aa9ff9d +TAG: eab1c7790a5941270f2ae49895b3113d + +KEY: 6ace8b5fa16054558c9d0e272573a7a1 +NONCE: 358c73828e032f0e0db608fa +IN: 915466e994705239afebb8025aa965626973e41a750bd75f9e8ccc7c1078ec555fa618120b4f4b5e273fb9b262df73d39950fe5cc1c265c06a08e2318efa83c63dfc689de80966f45cab0d2dba603bf116b9ef7242bf4d9cc691a775f78148d2c75059d6049c861da5dc40d5f94848c7247a724db956d050975d613433066ab89bf91936e0fc85c61af5c2c61cd1eb414b9df0dc125a31a3805903a886b427fb78551bc696610833a9e55c7776ec1622abf839d733594864de06999be8d483f8dbc4da99f541c6f7e21d946cce229a104a57e4b823bfea +AD: e54b90d037c375238f4989910d423bc58d32ccc06ddee558dc6a0c2f9a0f13b2332883e2c4ef9cce41d72cd636516b3506f28f914dcc88311fd7c79bff0ad32770e4847362affd98ad468117cf0daa0f5747c86359615ad6087ee18e6c58453be60f3bf30f8c61c1466d107116f88499fb1b5df9a01eb762317676d5413b839c66e5c1b74121f6f2f7408825745fafa2b10ba7450f4ce207a9cc682d1e1442f972a86d5d4039c4856ccbc00c43b5b3412f5b3f87c16508ffa527c8080a556944d359f388f787f9cbc033fb3333e72127e94c455b433222 +CT: 37be446820f5635c1b5ca1d8ccc2c5ab5b393243ef5229999a2c084fbb54a330bb338963740ba470973adc86e640fcc167a88bb940e5ad1723a01089b5e804b932138efed6fa0ed99c1ac4e9c607f466c829af04407a4a2e5cba486685f693a7b973921746902ad8a0242e02075cab66204084e6b281d58430f2d62bf55ad56ad279bdab0fc8c3d570fc3371dc3280ef3aea70d686c855d40ff205c04d457adb518d904f5715fc6a9a5f30bf1cc74703b175d70a1470cc810a366cb8927fb937aecc200928db6b73873935c429e2f8d595b418c5b1bf9c +TAG: 01b05fbaa9f2257b3c23ed3cf91bcbd0 + +KEY: c5bf40aa1127073b03c114b10f3f78f2 +NONCE: b4ac4fe9920fbb4e032f6aa6 +IN: 164906110c34354a0d4cb6370e1ccc17a739350cbb11d6570f398d50efe3d9db1a97f00d031a579f56d23da2441295af18a640a4e33c29dfdc848d722786d9b73550bfb76da1676af24a7bdf5fd3301090bf342369a24ba830c7f8883db6ed77a2ced83bb85205ca31f75a16a58fbbbd163a3af5e5021bee2d2cece33c08442e89d3f4d6d2359b94a7ec6cac388208a689b584d5dd1103fcf6af10ea2c7cda4f690ea0e4c7376fe2c3e69365d982da28c5bc18d58fe384c9ad2689f4047f9575e54970961a02419d9f2bac8061ce943f132edae1b9622738593cde52 +AD: 9f05d0391cb128690cd8bd120120f21725a79e5d2d0ef9e8322c04bf775f7215a82ce1ffdcf0f6562c188e84cb520f30842b8dcbdec36436725633325020cfdda7ed1af3323d86b2bc72d1b4a326f02be2231fcf133762c4fa76c8a7d5d3ac31cd19f63411a220eba4fcbdec40b8eb01e4ef33c6620978d09a8d428ce0e74d02c140881f46f6f81c2850edd82dc46f3460b5d5fe0b54f09a3f31548dc520f1dd46ed657995e63297b6834df57525408b944badf56234eb2b9a43b1422a5c6a59bc58be683e47753803f7341cbb0075b5795228b586cc571c1bca70d5 +CT: 5c75ee10a917651c49eab6a1187ed631c7069134e492bdb5e5698f8ccd5503cea5b1902d779c2f6e6c03b0108cee3fba03f2b47803e390930060ee4ac984b1ceb9488b4cce80e329d3427851aa7da2213eca2dc5f79366caf601c49a6b7a8ab068f1a9bb899b81a23c99a9de20466fe01398bc071c724b2942640cb1a00489e0ca7052f7a06398ad42500780f194078e3e77142df5710ae88540761b902084f57d87c2b0ec57bcb7eacee6743d419d8877d61666f93a127d22ccb49b5db0b93e4f4ac0dd9393d6351780dafa412380205a90fc8daad3dfcb1b7ffaff +TAG: 8048088e7e9dadc4ef98777c0f6cb661 + +KEY: b628ee6726a4d7925734ab1db3ec4645 +NONCE: c830b0d1b4113f4c9aae46b2 +IN: cdccda3718f2b0963414d965a3c36bce0a165f8e88aa70ca9eb3de6510d02b0b49c29cda4a7f6d439c18cc8fd80b932d0a4190236a13edc9994b1c4a71dbdb694ea5dea53ef781ed398e453ce372a99c204a138739edf5b606160e38cc8444c8fb6e9cfc3aeecc1760e90d13d01692ca894572a0bcb02e13f61d8604a75bb98e96f5f36d10e70a48bbb4f73771ef97031c7da23550b3a12554c2c436115fe56713dd303d1c3d87bcebf25f61710eecc9f01c555494facac496c68ef44344aae40bbe1199de793096d4630018a725b130a27d38ab2e8c629e61d2d8d37b5974f9b7 +AD: f4d345e55ebd1ef9faf967d76736f7ef38e5eb9d659bf8a89fd3c6c3c674161bb54758f1c14856281a7dff7c9cec16cc138384f644544881d50c7692bf22513223b63274e3cb7509c8a410a389277f86cefc801d026b0049c13d85b26da1dbcc7cb387084a3d4a469788ef85b6da02ed2ba0412ba999c8cd83c9c6716cd66b65760c42d4ef3e324b470c2a5e031846fde97cadc448e87bec15164da006c10d3a846adab2b09c29ecc27ec8a9134d5fcfd2c54f17fb23f1a05dc8da46e737f317db42e927818ed00d36af8dabfef09c8641159fabfcfaed344b03a1dd6f9b883f7e +CT: 4f39b8fbd8ecbc8aaea871db2e67583a5b06cb83ed8035ff639dbc9af92c4e3f9fe57b970f4e998a0262dbf77dc024d5e208d3678ae0d90e6fa5d45e2c7f0cf90676368c8784c851d3818e221abaa87c5e54298229a2f4d3f82505ef7bf45686aaf12e8322210a727cfd57c74a5f23bb5d8222115b28503eae7a5c600ebc4765011161736a346b535e1bfcded85c198c6ce6fccfcff0fdb0c2fc480bc6e71fd5de77355932d82f8eae245091bcf5abfa0d62123302e5805ab1f5006a976bc1468e3bed0452c5844029d7d4ea6cbd4a907e905dfc796c01bbeb69c54807354a5bd8 +TAG: 2b55edb998ac9971e53ebc8973c4e8fc + +KEY: 095b26bf096971842fae34af6833c77c +NONCE: d59d30bd5384b86b19b33c13 +IN: 3be9eeac265ec4eb947dd32583ac2e595505b363d660f8b8c2ef631390bb152f016ba7c75bf7c2e5e23c980d6967772ca4535bcbf4871ac1bf70b53826a34174e5a2e6118d7ff86d4836736c9a1f9de44c80b236c5530bb5f80e5fbce9814f3b0843a088afd029f4cd2e6190dd51fa804f8216448e7acc785ddc5478287b101bab80256977494fae87d0c13054fa4470c3827b2e8172224944c8c4f78b0a33dd78ee2bff16fabff15e5909f62c49beb455dd655ee1188b8eff35bfba72f2ec5e4ebad63d7db8b6338660f9b818c6832954241860925ea9b7eb07479dd6de27489d64b1a9191b +AD: 2ff9a8d12980e63a378d6d635d319c26e8f747435aa5d797c6e21aa69fe21f653f56da7db7d67cbf54451f336f683aa9cf373ab40c16738c44efd3e664ecc6eec40d6af82df2b3e58d7abcf26b1d9ebbe6263176ce4ef8087d14b0d5ae1c16917141d2ebdc76a0834e8d83c4ef76add82e957ae376b210ce2d94d2684a045a109454799f3cb453279d89c60ba9d038a1dcb99540fac078d7216ee94f96f5cce939eca9b5f9715b1cf3c9f1e6be982897c2f25225919db3e31595713a4e281e9919bc2c5a88c46835ce05411d0757eb738ac9e45ab3f1a42ffcd6dbd09f17f656f40f1cc2c050 +CT: 4723fb7339048f811434eaaf1db24759fc232466f5f53926b84e740b67f457c8c76f902f4d70ebfd97696380de95e8e40e62434ab1089e3a5308cb066fd4cc7e862a391c2f727a63a01bfd9fdb8ceae55067fd9d6f55312f73bc2c38e4b12b3aa96edd156dd758e9175e67a64a17aedd27c9c70945a065216773d756f533b035f2ab53335a159d9ed3f97b2b7a57aef676fad95c46e3b82eb800197c03812ca4e580916c5f7cdbd4aa1308ab16096a8af5290a0a2330902966a58dcf2e72eea7ce799a8f05c986c6457b05e3eec2adfdd4ed38926a3dc07ef208c91a619848917b96a082ac27 +TAG: 3ff349a628f7fa8d3f970aff8a6302f0 + +KEY: e27171ed1baad563d3d299abc0968b75 +NONCE: 5931a4414d5a90e93d2ac47b +IN: 1d209b32a772e87c5bc593fe943d3d7a1497f390ecdccfefac50ce14595b98b682111f82957278241f291e655b3af108a9cc1523721652b6d446f34cdba2e61464a3217b29344e18ce8f47f10da88c2845a009b7491bbd1e1f36ec49997a0fb09764ee25355de29e56eae7af42a8c96aa137c02268078b7f145fb1249bdd74f2d4e4685de75be4dd7fcf29482eb26b5dfa5028accbd23c3c654bc202c1c0ae7a597ef15f4d14f7b8a14fd45698470ac6355e04fe4a14e3b2907bcade18e4152c68631f313cbef48341008482f434c017bf8e1dbd048f0d6d207446e697fea68202be7283188d1227f21ae4 +AD: af2f6abc40ca82d92901de02113cb8f7638f0a510f6a03bf056a75b02beb10157c97632320fe14fdf0610235e3a06172b6b6e80d2fe18263b11e9a5e3a07758c55131ffca0a6c9b121c37a0c85658125d5bc2edc8e4e247a636d7793a1cde364ac22bf754844607daec0a6b939d05fff5a8c44ad030181aad2361ff61f20a224f2bbf2083b2fc2a5b92f5a66bf2f9b4c49b39dcc23cd3ba66b5e7c19c5b7b74a766c3da0c2b02ac80ac22c006e8eaddf48ce6f6887f69fff1fd0aaba0a0f70ef84b54280830a62d8b0dba55ddaa5b0385c586dee60d1a05a28863a081cb9b41edbf3ee9ebff98cff983917 +CT: 673ae48b6080a3dbd08034312c36201d18508f4e1ee178ae2632a9a5ce0938687ac7e6cb238cff852ecfc736bb8b3c04b42752fe65cbf6ff897e207582e85533f7c238b0be14bb1deb4cdaff524b013661e4f2c96807bcd928e15e4e159390e1eeed036ce776b579d9f3fadcad81adfcbb99986babc9a8465def3de8de0cae19bdbf6488c12534a9b6b7d6fdaeb1d4c3be36b4adf7444a0b9fc69c69a46f7bdeced1214743f3357803d2eae24dc50933a733defc653dec56f0e0bfb8928de76699d4f7029fce9175b3b7cfb6c7ab1018f6f3eeb2b9401115c8cd382b06e4b9b43a097f42bebcc1493a49d4 +TAG: 285c1a0028fed3ab2a4d68946399d700 + +KEY: cfea8c059d7b866051aa54b8977befe3 +NONCE: e54e684ef16a2fa8e25786d9 +IN: 5a20333c4dd9b7378bfb773b7d64ab80379d16c0a56eb1f48f53c19d0fc4519d0b5f478e37f16d6e5085af31dc63488f9f2cbde3e49ba954b674b0a4e20df811098f7b8e716efaee6a4109f16afe128ddb0e54034d66bd00d13a6c69c9ef2e5a065825701f5e85634e118c69ff0fd71bfccc25030fe94e778e7f474136cd3722eb5bfd88bc99fb45dbc3060a24ac2bdadc5c82d883c5c63ccc0f7aaf5384f4c7fb07310b66a7c767d025c1a02dc9aa3d7aa921a72084906ae6039f837454493aac3e3549ad3722a735dfce4211819a2d7ec279221d43360edd9a4cb930815c8565c22b94b4849a979d5e2a57b2da8ecb +AD: 376d8e02071a93c892293902e369b8c7c44a4c9541b5050347b016243935408d0c9557b0f66c6cd493c1b8da68c8635f4c868e685674aed42f196ee9b6e56ee44510eb9b9e89108d878be917454dca0c62d207fa462a563a267270d6b1602d6795717475bc6fb5c87b747589328e39b1d4db3cb19f0fbe9791aa4232e33abd9e14b5fa3abe4705ee988c657677fa063aa349f1a05de045f3ee66da03af18b6b8b83e29b203e12bb02a4cbaf79eab3cfeb83a5a997daaf8f36fa9e12faee86c9cb351ff361351d98ee3a10af999799955a02fc46ddf56c23070319b3fe0cb42d07d811ae976f242670e618eed113b4342 +CT: 06ccc7336773919c2b1bd832e7c48ae4a569db96545363ae0b28061fede28a25ab6cc0382aae3e6b31efaa4c225073640d0148878524a7f381f53b4d21a43e39afd4c12cfdcda442d5023a8d2a8ad49f4a002ecc8354c86520524017e561fe891b6962682d168a860210e0def1cb4be1bfc6590121c1b1988254757fc5a37ef916827a5fc258ae772773a6902b084817f3641c21d3d1d1e8818b9851dd05aa49ea74e16778593f6f486957345462732ab92b1e4b06c32b5ad3270c5ef3d80b4e4bd08451e92c26acebcac1a4592e08ea434a1fbc6dfedc677151ae9471661913db19723184d9ef4bb49342606f784d98 +TAG: e7be877dad60c889d397726bf1b6ea89 + +KEY: 40d35704108a944f1e7582503018cc85 +NONCE: 26048431289e7e100481e2bb +IN: 515f9bd4935dc10e77dadd81f5a4e0b53eb858ded393979ed75330b80adb36f6b81288dcbc581e8d93b0e4705c07be3e200422397ca3648c9676952e60ea26d12198add3e33cdc589ee5a800a750d77978976344dd5dc710e56dbad462fab7fbd08c057a9f8765c4caa9418e6380038d288e09a90befeffb1e8d60e79925dcb3772cbb3258b15544f9c9554181df3483784b89b73bb6f9ca55f6d644c02fbd7e31bfbff45cc40132d2bbd08db6a27f5a302e1dce2f0afe4ef5bd4ca844c7900ba18faa1896a36896a1c80307cb37162174205665613b39cabd0a5b2dd1d5f8b6fee948006f0b2e31488c0c613c1d178b7800dddcfc +AD: 9c86692c874fa785e0d9384061bfce8d8332871ecc195621ed478706c46057bb4fff80515ed65b5fbbca3d463a62e227c228a340143bf012233b1c05a50fdb4ed04b840d983f47e00e001844a0d2ce14f6dcea58069c9b0bd8824537d2420147be7caf4a88dc9912853a7fde6d2a5cc21f85eeabca7902b94eb79d5fa143d02585acd57b93e4eb6bcdbe289a51c6631f7aea7bd9dc0f6cc2ee8426b37220216f834033fde15e3543422612fb3d972b8eacaece9614a4b759d93dcdeed026cc90ea058d7dc985c10859d4ef14ac5cb14849d4ae404badbcd98c28663eaf7274aade4bb7527c4f960875ca703ee6732c9a3720b629f2 +CT: 89a21a1d502ba947ac1921efd3c998bfdb437c2da0802e5eefff66de3af00bde934fb9109e961f179771c52de783680683f4bb752f877897882103146d030bea5bc3c03f923b477443e640450244cdf66d7d346954f6e862a3a577820d49151a82f4205340ccf2e11e4575b53f7ffeef09ec640df65a0b8c04b37f6dad7f940cf2d7446a6fc5bc2dc31854c27567b2badf6f8e94294ed5d899a458a080f38d6e72df59f13f5c8f736264fa2b302d5375d6e3f8c3abe4811f4f85cb6e302e2c12a892a1e7a78a5a33e4b555c02917330ea7a45f20cb59fa991f183d1e2a5bb1761005b73fb728124fa2082f41cdbc88bb06389eb165 +TAG: 5476c08e9561442745fd2f222d08b535 + +KEY: 2c6796d0773d12455829a3242ac7d480 +NONCE: b43c0e7842006f6a7953d598 +IN: e0f7ac13e8cdf4da6c17f1221df18b98267277e79c362ec2793dbb842bb9662b5e2fa34e43cea12f71b4eb53d9c862f176efc5d91f06b5c532d9c30206eb4355ad442127d325ae2c30ec436889e3d7a56b683ee09c7d79768d6876ebeb67b5a2cc13df02ab93646386106e0473149ed77ad0ec91dd282712d0aa26f30bfc44f93cad39504356e3472c5bfcbbf9557cd85b53e33e1a88d2f08686955a3d876e4eacfe783e5f6089b3106295899d4a73fbbdc1bd22e1408a2b93a9d89c9489cfe7a9a7cda7c92b06560a189f5ed04d1f02489685c602f8741baeef3fddf610b1a25ed26d88daf9a05aa0a476c8000dbbf798de92b0ab8779add7b7 +AD: 1048769719a44958dbafe1a59a159ddf2427c5dd8746a8454180dbf59f48ff6467d760f8e06aae8d2d2a79efefaef2dd2abf33ba1929073685d0320a583a56e8748288b50c7eac551aa859b274629f3d3cdca5fd7b2a08f0bc830e929584bcba85f80e2eb12bf83de607e4749eaf7631c3545f06ac236d55769c8a08427abce0174c52718c2c08b02afc7e418bd7aa7715de95a930eaf92f54c7dfa2f3ff3691187a21c6bb9b238d2fe2dac7266de30c94c7ee96fa60caf5ec0f5aae5cef28264933cbbc295cade787321f4c12f63ddd85185997a63fec48fc5ddb83be3b47a94e15dda3f315e7495098bc7a0b7d26802e12fdfc6a94bc6c5a76 +CT: 794ba0a7df144e66e6e7fc83ee290431818d149673d1821e1df496565aa7996f9e581fcfe9499c01d8716fd3f6d67acd6641285b70f8457108063933126c95b665e551925722af60aed5343e429e645574a65cb6fd767b204ca8fa91979c6fe49377fe4b43fb9994e619e1dd962fa49a8ae5ae0b8eb630f112c43a4e9c28ad91fee9b5bec0b27c5472e30c2699e984dcd9f984a3eb7a7b7209a165b2f4a74bca555dceb81e3495a3d39115d32609f372d8dfce820aded274ac567112d295de5b261b10c01f4939ac532d4a0591f87742d9502d7a2201178b4cb4c069b1873c44b73a901e299d4a41e57dabdefa39907dc559b44e99f2b950e09c +TAG: ae5afc2bc4096e308cffe8063277ef88 + +KEY: 092e4a78c47bcd0b169aa35343c885f6 +NONCE: adb73023c873661f02bf4ea6 +IN: 0751fac5f54602181fac252cd2fc408ea3763fe229b80149bfb4b0044f541801843c8a20ffa1ec931830bdbde31efa998e0875c09eadaba6906c870549dcc650b865665c56b5cf29b75da63de088fe4d79cce59499518a04a17dce18879e3e33ed11ad808d470b2811da4617039758109f56fe75eeee696ff51c18d5ac04fe895518fe59435ed1f073b56079dec1701999ce0e5ab45829cbb85cb1f94dc67c9ad28815728f6de85fb7ae12203eff28420393c1ae5cf644bfb5633156e9189beb02294d7199e54ca0d2012bee2dcd6322eb90f41b3c6086cf0ac6b3888b21131f3e57643f2ab60141aeb17d9d07daa213658b52503482fabc4a0ba17bbe3a1a +AD: 60fbcd82efaa99e17f3cb16a4d2a1e04659d13d84a83135a5e332366ba5e6716bb3674d27e6b2df4269180a0df25841e2235eed7d8eaba571b34178ac1a1041623138641f500a7d4ceb28efdc0ab45274cf26c0dd16174c77dcdbb79a7980e04d48b35efd3656e501e352b605bdd1b57cb7f9ceca5ca14a3953b2dc77d18fe1c4e1b859d2b02feffd3da7e259fbbf27721d330049f0d1c2729ed2f8048abfdc0e7b3609d2e6b4f5b42ece472f0fc330247880fd04768b678fbe20ba9581f3db18bf3668fa0c80751d78286e1927aa6e27ecce63fe883ee88e7a05f8ca2a387b86246f7d1a4791881b14f619a340163da62f4130b2a2c0bf39f463ef0af4120 +CT: eb0fffeb17e3309d1104c9a9c211bfbd585f9516f775793c365d36352e93af1b4db15430b454d1e7aa913f2af994191c365d76a4d49eda531fa7ce9c49b98bad4d591c868fb066a2e00a6bf4b1bf529002d403313c5df306ae34b8c62e939569bb5401eb7ba87080ba505e5c40a3856d2e177d247a5d8c727b32a13014a00a57e9f01cdeacb4d1abd16f1548256d661c45da12c2fe3ab561375875c7b6e273bbff5659749631fe26cef86e02742d0cc3f63a76ae5ece59b6556ab27da9de1a20c627da8bef3c596ebd7b246505006d1a381c2a24dda70e52b126b919471acfce274b89e07d125bc69bd94f2c65bddb82441897973566014fef625bca7e342f +TAG: 8f2dbbcc01538ccc45436e7176c2df47 + +KEY: ab1405116f454a3b1f106fd491cdfc8e +NONCE: a9e9a06e4bb83c215fc59a00 +IN: f64f0ed5ca25e118f2a2dbf069a9dc0169ab0079d91c6552d4a7e8d0314c910ce0614e1f6157b0f758ed6d3fb3fc3e2eaaa9718ef30e8d0c136c8bd6dcff97c0f5ff8a5d3808d8c23f2a9ccc35fb9427afd10dc1c298e95b335044b8d33e414ecc17d7b34901608284bc175418910116410a40b29dbb379eacf4ead521db3ab2a3d9956081af6d7438714c0631147b7d1e9ee4789751d4260b57630bb573739a3fd0b19a7ee8c301d7f1b09f86e60e31d5f2a86c7a65b244d5e4d591df3df3caab80887ea5f1dbb569516672eee351db5d5ee4d662a3d3c0e48cca108966ac6dfa6e4f9b88e5e577752826d2da05f2677dac7c31774eb64b1b0fc938580a78e4a296889c +AD: 3726f25fea1d10c2712d157e1a1bfa75d6f9e5bda448944ea2b7b85c7d4ff4ac00f68988f2a290cff3d5dfd6af33770a021b03fadd5741bffb7532924f3f2841a7f7658c49c6b915b1dc41ee4bb9ee89386c9911974979f43e71297bcb34ad6ed085177ea91300c9b42524503bbbbfcdcaea03e3f2c939d6b1dfc9c6b6e53e221568d2557bc3055752f4fd487b903a2a0bb7697a19a763fb7c615c7edd099f72e87849f57722cb0987651bfc476a0acfe13d02d6b01f761784d247301bf514a14a990cd4b59664f826649e0f389787641c1e5b87388cff42fec144d6ff3f382b85062bc21368c93019bacb56b643808a848c60bb3d804aa64e2b8fa1c128d6914663d9d3 +CT: bc1c14f1df6ca46e6b4daafb016daa235718fcccfc1ac698a061885c33479c0a7fd44e46e805869383232168940b1a9379bc652c565059ba81b4ec2ab435eb9b91de5bc03cb0a7dc11805690ed9abbadafeab2add15f9fd69b5ff4bf4ab5cdb4a6fd3164ceb7820530641d8460b83929b13860bd2e64b984407dbfd2de51e865d88c63554ea1f04305ab72bfc991fa5573bd6b41c4f8c848fff4b0c5d2398a57b4de4678ca4dfcb16a7612773a24088893444a8ea3d0916e4b460b33657f41d2b04d0c28653ed068a3653975402c31088cd74722d3bc09c50679d0ec94c1e84844886b1a56c4fc3b14614634f08c5b0868d276e9f8f992f94b2c55be5f2e408a498d27c7 +TAG: ee43dba528a9ce84a53ed8fc1fbcd871 + +KEY: 7990cd12d13fbb929fa541bdb8e3107e +NONCE: ff7b2818b62e856952aa2cac +IN: 5ba2afc1da8c18d8be3936a2e515bf9eabb93e44905a86773a38de7f959c49ca56d7f1fb43213cf7fe394b49733b031334729ce6c7ef17d843790fde814672ca982807b76475350210871ddf8309f59fb280a7d41726ba7f00ed2fd96b4a17aeb7d157130cb7e49c8a454cd08622824d20f86b4ba062bb3b3f9d4a9c1402a9d80f3324e4127ee57ad94f87d6ccfda76145363fa70df95341d483dfcc304757da7541a0f148036b2e2dc7f93697d8d275456107a016b425542a89ee33ec02289f5260257176369d990c8c89df73892d7e67227086c0c2c258e5fbfff8bf9129a230c229356fb0935738d2d6fb82992c3465ca5a9472ec06c7b5a29240b611837225c61a0e14ca2dd30f +AD: 865a9b2706eea62f3fd3164805cd8fe4740d1ba7be809cad9fb39cac26f7c57d4c449f4eac03d87f87dcf219c562b9ee07ab3ce22abd46237eef8221049fe499c9189f789948af92bc434b24aa44fff600c2d698593bdfcaea878f8780adbe8dad2cf453d253e8668631a6eb831be01db9c7f1b7b8bfedfae83bcdfef3501cf2b2ea48bcb19f40a70733f3e4c3dd90e17912d5797fa46ec852edcd49b0780bf6287679aaad13a926f750ad7d3ca1ccab577b74fc0ce4cb22e5c619d2d668292c9db4a98c5acc4c49561a77275c06f5c3fd514ed8555db3e2f50dde5c23e84a38129e7a91cec8d168bc828d09239a5c6bbb180bf69950540d8876f9fac5d1a258543a771610991b92ec +CT: 1901c8f9b5a99c46c9cbdf8ace9db03f36ac17183295544d8170fdc3a16c7194a2fda400f8f0b251a3eccf639f539cc356ed3fd09383954a8119b536290865c30a629d44e467acff5fc323d2be97f29fb9b4ef7cf2c18a63dabfefd7f75e696c574372f4a35249897a3387a2b10c1a50ae23ea74560b498c9d06bede78f4c8c9d879667c8c8e137a0a254f3f881ce8d183588546e066314bf1989d1acadbae61f7836fa633de9fd0fcc5b3f72aa03ac432be8f7a14c8e86b45bee416acfdace44b783137e3135a801342061781007ab939a52c68d686f5e3b401240bb10e764211a059fb0aa00e2f635ef214322918fffd0326ae38ee939b4045c6039df7e7def36fdad7f5b65c20dd +TAG: 3e003897b4d9411cbd449cd8dca5b58b + +KEY: 64f0a8065987a4713e35dede10afb708 +NONCE: d6ee984b82f1097331400f38 +IN: 29327f95b41119679b80c3b51fb5240490689880ebb5ff7b59a62ae5e08f7cf0993c09b13fd845ffb32a99ce18c22bb8825c137c3aa622cf3a8390042c6a1a159aa1dcb6b6b21f4e07fada584dd21620b2fe0aef64dc609aac925d8b8d26915fc101031b68a4bc89898bb92146a0a580103da265cad1946791c5735b95d85d3f0f1f39a88f47b9c52e61307627c084d68d14bd14e3572825e190bc7146080bca423099f643d53ee3989386b87fe3dd9c383f6a58fc0437fdb2087b5211df2069bfd981d8ca785384cab31545ecfc35345f38837883dbde917155e631a46ed1444ea0ea8a5441bebd54e5f6ff914fcdd66d62efd223f34e16a880370a529b2ce6ade88e907102021dc87aba9900b6 +AD: c8116196a12363785d4d6fc593b23226a5fe83b00a77ba24c69644d2e52291dc59d2af3c6ae102707439f22c33251a01c41867f54ecc552396a5aa98ffc687e3a88d8d0dcf826645bc78ff9c1a3052481933c3e8ba8e30bc249e6d095699ebdc51684696a15dcc9e28d09cac757e51336f79a0cd5ce8d070579e12956a740666d28ead49c47bae10db20fff8dfe6fb0260a87cc6f5a879cd0b2f949dbff046d90cf42c7ab51337e8908302935e50755a4503107c84fc94f7db3d3f0e8eac9c0def7435676701c9acd7f4c2349c3b7324622dfc4d6ddd8265a810c000158260aa6a7e3af973f8b178959de409792652e9c4ed1d50fce2e5e6bcf205c6889ed717db7f4b14500aa8641b8514150cab +CT: 3e04445e0ba21e8788f6f192b710b466d5d3433463f0308a3c0fbf7f1666fe01853b9d340f496bb0c2212ae3e3d34b0fa1adaf33f039201d1962f2b51031c2a4dd9aedc08f7c895682d1352e9a21225d81c98ac7fd4b4de6efe3dbe437d255e4464a1258d4497e2a1d4ef6c319869b78fdbcf4632743825112fc21acc0a1431d8cf8eb8865e695c0f3668ff5acd8e850373331ed7ae3bbe515b42c1d0ca0b9caa4df0048425fcd08850f23a86b4adc859291b5c49ed54e41778c7ee2a11da9598396aa889dda9513afb9fa0b66c0affa555bf76849d754702163004fe3e77ae5a7c46f3696bbd52cb8680583aa5cac22608c6d45b96770dbbfca14312fba61b3fd0d7041ded80d8dfbdc3f901b10 +TAG: f42a0e4e6e6a1e0654aca2ab7877350d + +KEY: 2c351f0b77cf0920873fb57c910cea15 +NONCE: 4f844d27dd26df3015608119 +IN: 227ae9330bfd5a662af4137ca7fa164f383a63e5bc33eba94726a0e7a27f666887fe484680899ad8aaf6fc5426600760f5e6ba53b0484615d0089d9b1e75f5952ce0665d16a045b272c3c50194ab7b3831b313dbd800168a24e576cab5dca4319660fc6add76bb400376fa29cbcaa25adf3cac81f3e66a6baeb0d94ed92aa37271d2cbd8219c0647f0af6a4ba8a8e169c10cf6354122054a547ba046e67cf1fb424271d3d3eee5b51e94019d450de6c1f770395316421b61c5ee9ff00c910103e58d423946c68369730a974a392c21be3fc8223cd816e7432200390fd7cc3f5160795422c9daffed23df42a7f8259e295d43fe57f75f674886c6405bc6954d17c2a36348761ba09694964646cb86c0d8c64c00 +AD: 9d7d5e5f63267154bab863a7b53e0ba159a6d8a57a8c49e084b513b463a1e812e94611116dce9c1ceab2b7e18b4d69f7dfd225d2bdf5b7750d0d9dc131f22987bc812da5b0a8ecbe9d0ca2210cf6ed8a791d95c3f72898497226f69c8971c2da342500b75367842d14983384b5985041eda7f1cd73e2b5c71bbbec6537390313583bbd53d2d563848fc93d81579d8db321d1bec973f7c4e8f34b6cab8bd7b5789a7b40f599f2f8c43f6d7f8fdf940577ca8b5159e699d449ffb00acee0940937d491a71a81ee9da0949f8fa1d780f3957908819221941f0c5d011bfb2560acf2d7386f973358d68487954e26ea9ad3068c65b797307831e03aef7d1f1bba9ddbba2f251329e85172ed8efb1a689f8026b5068c +CT: 4ef2a097a8e507143b6354ecd94d072c0068c68698fd04f2211a771bec45d616d8eb7eaf90140850c135cf468dab9e9f3dbf059b56efcf616b32992df407bdb735a8b5ac2c361973abf47029bcde46dd5b13728add772264f2faf60f3de10494b0606618c383c8929377f2390c4a104141a11711ba7e3a3c83396761d7d62a997e8782822f51ffd0eaa0e6c9e02ae4effc0686af29f2805039c1cabc8b826d1ceb75c4274e95f854a9f5be709ddf1002481272586aa021acc2fcfe3e6cb0b2a47d124bd8b83585b43bc38599a497d0de3979c30c81536ab06a1649a3cf5dc2c2a6e52bcbb05a76e35139c668dc8a3c038ffd1fde8c1b4a31de48341b5fd586c674e35bef3b104e4b84063889907c268226dc73 +TAG: 12aa2a46a9014800b3243d1020290d1b + +KEY: d94582550b2e0d42255f13a8753f8e82 +NONCE: 82f7abb31dfc28491697b347 +IN: 53ba297d691fc3abd93ea8b6f3d629584370ac045934b1b738a73c09a8236bf5f99f357b1cbb120414c68ee64d304b7751c88c563d5d16fa094602c0ad3c803a8f116f3a5071c049a4b88f19ba2d500a171565c719fa64e691bd4a9c4588077b0c2b91733a30a214e474d868ac6b301898dc85346523bdd4f6c9807ef69941a5369b4b7ff7fdfd252729d3829a7bde65427639de0b2b154b4830f57ac13894bbe705f02362f8b75367ec7962c53bd6aebbf15d72b25c08570392592b6a83d4f44d2037da8cbfea2456696cc39a3272e46a5b4fb837bc6e4bcd9606afa58d3b260e9f6f58bb5d0f07438f378b6a36c1931e9eaf923c2a3679a789e7ef5865c7e799ff4633f1b2acfb79a5a0fe9cdda9cf347b9664568def93 +AD: 2bfb6a6726c6564b31cca749bec29a8c9fd7bfa22f26af0a80db5e6b13a3b10367be6ad87325abc59252453422535466347059b7d57fd2b1eda1d6d37dcfa9da7df34746e1bbc98baeb4bae17281a537fff85c0785f9f27617e77333f11be28f9aa3704651e4ddd72502c79cb2a810c4686147cedf056b5f035566eb34d117c83ae7815e7e1e83163907020cf0736ff1862371e87269e5c8c1926e0bafbc10610a6ba6cfc273c9d9bec0922726dea04acf72b3f88a5fffc57e0af6dddd0396b4937d2e7d52feaf60d29dddc5b4cc139eb855acbb794b99d74b8a93e3731f9092b92b9bd50c846eecb6eaed2e51290cd1f98dccf3fe746c5293e0b970dde72835c44b3a445dc1f2bd67fff6b1a7e378611eaa42889fb92de1 +CT: 1afa2fec98728ce39fba26bcc769e9766993c8276f88613db574773c84c91fce6ee7dc6ba4281b8d2dfe13820723526f0d6f20cc21f305b792e9a2bb1622c742fbc05ca1f0121cb9f6e1ad6c3ba80891e2043adaac4f1bdf29260a44a182cb165f58f480be5f16b51fddfd0d264bc4a18bec589d24817f586fc8bad15df7cb4d48d788fe7fbe69f821b5558b0a664ee12ba8ddc6bbd325f9b83a024245b4e68b310f2282f4cc6005209f7b7aa6ccc025d435441e3bb990e81bcd4c8218b8360163ab266be4a1f5603059db2bb67e541e1edbe8e7762ac522a81f495f5ff8bf99948050e61c86e83134f4e1212f879c86f7fccff472fd9753e27a0601f914655a5f803061cc986431445021c907b3ae0f060fac13f3723867 +TAG: 5ef1ed1e2bf562893b094d58516c11a9 + +KEY: 31d93fd51c2d6450cf35d9edd71413f4 +NONCE: 28f6f0c288c9f92e80252e1e +IN: e78eba6c58f93cc2374932fc21e54f695f2daeda3bd1e0121a77d178e3bf5c0e824a99042e8f2522df829d014e4d35a756780e8c07f53ca8fb78db6fb76754ad461665051c4572b2514804d0a9cbae1a1a013b796565eee13a7832ab8834b8406b1185332552d38754dde2344ff4f6e4823390964ba2dc43de136f2235b1d919e0f4ad60813d30f0ac1dad35abe3bee9479337c7b430841d2c722f12aeaf931cedd8a82053f697fff8d07f0af6013da7da58a5dfcf45561943e7ccdfd8d11fbe96a68a5a27982e47346500c0284caf8e6b63c6621e80503a7365d6693dc9a249093dc45221cfd88562e25910034c2c123e44e3b09d8a8a15547285d2596b98c7a0ee9d10b2cdb032d08a6caee1212420b6854181a583c15e046aa202dd +AD: a4fdd42aad5475ffc1b122170024486406033c8640233cd9b23c286fdd40c5b69eee39cfbf965f7a10c73663f9804e6821c4f62980f8362a580bab446325b009a004b60b1dbd12566b55b42e58d8037d86c1050cd6ecaaac2fb0ef616a15bc5bcd8252fd459165795c500bbb2fb1476e5cfef9549db733be65bde391c810d099e3745a2cc7a94debe1f4ff6653b338123ef7d2f9a602bc9a4bbe757a63f932a802014f2f06c6688faf14332a355b1025f33687124399f55b6a5adb4864727ec6c5334c41d78d1463400925f6c29c0f611f35c9640045a740dad5b4f0dcb632e7f9a3478b526aa9f97cd9f8d3ad094b7922890e7b6d9c67fcc4f747d04ddcd115fba0a8f0433c6fb1bf6011a9cd153f866c76b26d427a25aebc60d10540 +CT: 8d668fb50efda82552aeb5d075ff3977c37929d73f6639289e7c6da8c89c664df80b2387e788d12398d62d3c0ed2f9f918010d41021c464d54f016c4e10e85e29ba3a45793df2ebd6cdf30045363434387bb0d20439f4986e6eb7ae9fd85fe776f7b8035025624c2413ca8491cc6e79fe901b9c40ff3a0e37a7c7e88b56de4fee65861865162821e046846d253982e4ecd17bd26214b0923a4297d4ed9423395d856940829ca5ee74488c3b4d8aa3c5ceade17d8a3f2e45d3ba91360ac1c76d6a29f8243bf49c1d75aa41ba239fa6f3b123e198ba799e3b70c674607c5371894800954eda0264b3b82606433f71371dabc5f1fb3d703232533662920a241f613c38d16b0bad24f4aa3b336af89cdcd2f371e1bed7aaa47c56d17100a01 +TAG: 594ee5c93636cfb5fde940e3d561440a + +KEY: b06d694a83b14768ae26a8f00fb78ecf +NONCE: af11369ee342454cddb8db62 +IN: c01130afd7d3f4276dcfc1ffaf4bb636a85d18e0778df6c6791b6edb92a617894b84cffef6556c834a4800b336dc295e80b699b28cf478a01c54052ab0d0d4208e1865edd6906e3a263862c05f033668d7eb5b42baf36c702d102a6a5c723974e63bec848c89d16584f0d1ec429c87686b1ccffd7626e0a83f9c471cb615541ccb02cb58d10e63ffef171f1affca492ace4d39fbf33bb5126c575963e6b6ef9fd2ee4d6efcae5afe422bbfd9c3dc22b6b47cab8dc04127ff93b016e0f92f5d8518d5bd3bc6edd45e0397440f1a4a0c7c9c2773c0a0cd3b890effb010dbcc00237dbed1177b86bf60913309bfda9376b4192da59a360afc5bcfaf8be16ea8313de97b417aaddceadc63a1c3a355693616413ed4101ad68f6e6aaa99c839dd2a9ff536 +AD: 18e3195358bae4ccf43ff8daa34902fe48f99fc1371d34060aaa442a43016a1d756f795fa5c9c4a828525554571e18c27134f46094790dd1e68471ee40c17bfa02f175b2c2f7f2aef20f00e4d71926560b58f015de19c871d808acdd341675d8fc19d1e6d4028e1e8926df500c4685c14729c6a056898cf919bf3ae429fa3ca8746495716d78c9a8f2ecde596f985b1c25ad0e73aa305a86259319176b4c4f3bb231fdaa478a856f46416ddb10a14ed23c96dcb86f5bea3114568a44d8fc6ff4bb47fd0e2538b70d964842910a682e7bc7c7263249832c21b7083a1e8b143828de0f3dea8b404cbd82efb19a11e4d60aeef13abd86621ccbc3d8f220715730eabbe04a6bf0e11a4f78cd2c4369ce2447a76f4fa48ef8d322a8a28a67039c24c4bfbf +CT: 6beeb306c71318cedabe3877ec916ce2074b2c3f1df887cc3a3e8019c10d353854b6b65c947359138d5decc62a42d50921dc8f6cf63a16062af47aa8cd50d0b2dcbc3300ba0d7d069a5e4b4fe03bbf7062c6001e276be116fdd00d15a6399d1b0db71c58f396f8bc7e51c2b1f47430d4ebd6c5d05328b29aa79bcb26927ea5a40c82715aa0e36cc83ca6d250812c1305c02ed4291a25762cd709cb3d808031b5f918ce253f622c1afcb83c43707edc493d18ec6f0dba4353a1cde7184db65654088fa13baf45f7643f0dfedf4058e6095156b791ed30827c556a7721658314356e7a3f3c62cd62fe938b008cda56ceca71442fa0ffeb78b13c5847a3ee9668bcd2a01c753bd797c240378505d1e8f2b8905428b23bf589de9af390f94f21630d1826 +TAG: df5a21a399354b2b3346a9eb6820b81f + +KEY: 06a4c6a8aa189134f5784a525d46ff10 +NONCE: 0f765d3893af99f5c3e6d9e1 +IN: 706b754094869313523493089e591d34868b708cbde9bd8b42cba8175d1fdb6a8769bb9ec156d44bcb8f9cbf2685a0dc18b5a802dcf7a12570bb9042a0aa53dfb19af8c0f13763f388d9626a480d6d435dd90fbdbb4292d9015a5633252aa0583498d6f7ec54460d8589c1d6a6d16a349d10ec6070e1cc52e5fb996f810d333675a7130e4f3db9f4db0e3fd3541d32e0b2efbd40ba70cd59295bc8d08481f0f137832b01bac1778ffd7450376e174067b3ec23d0495cbf936bdc176cabc3f42e2991947a4fa87dd8343c32fa3d7ac0e2d22660a0c128a00e1b51a8742fdb2aff44540e39e588c5920ea16293aaa522513c944d3b77f3a0e90bd9105319c170886202e336893d100b0a25aa609a49a8255f78233561f7b88256386d1c3c002c3ee68f2775585c65 +AD: 18e2ed6d500b176e49f7e1b5074c0b7dbfdefdf00a63d9fa2fea8c5e78a1c4ae00f17b23442933543ac864097629e112a099f3dce6d5beb1e3f3c8e19522c6b8f615cbe23444bc91a802edf8a08995a55125da805ebb073fd89863996ef708f7293069a744ad95db8c17cbcfedc331119e85020df8852d74b8092fd38ad424f3da41b4775beac19536ed801ac1069925b12303d8ad2c52c36ca5b4ec95e96f02ebc5725ee6cdc099e666d9055b789e39ded77a8fdca0fe2d94b8039be55b6a75209cbee4fc7864957402b50427db71bc75a0b1e3d2ed6ea20f12a980c5ee916067d0dde7d686570d075da4df7088fe5dccf0d440064a96998da6f318b603d513104c723f27484780bdad586ee358d821b480f9569e4dbdd1a45ab9056f8d8e5a879789a0d65338 +CT: 5f3627bd53f8da0bbe6f3c9246d6f96fe9abb91cdecf66ddd42f833d98f4d4634c2e1e1ad4088c84c22191bdb9d99ef227320e455dd112c4a9e9cca95724fcc9ae024ed12bf60a802d0b87b99d9bf22590786567c2962171d2b05bec9754c627608e9eba7bccc70540aa4da72e1e04b26d8f968b10230f707501c0091a8ac118f86e87aae1ac00257aee29c3345bd3839154977acd378fc1b2197f5c1fd8e12262f9c2974fb92dc481eeb51aadd44a8851f61b93a84ba57f2870df0423d289bfdcfe634f9ecb7d7c6110a95b49418a2dd6663377690275c205b3efa79a0a77c92567fb429d8ee437312a39df7516dc238f7b9414938223d7ec24d256d3fb3a5954a7c75dbd79486d49ba6bb38a7ccce0f58700260b71319adf98ab8684e34913abe2d9d97193e2 +TAG: e690e89af39ff367f5d40a1b7c7ccd4f + +KEY: 31323334353637383930313233343536 +NONCE: 31323334353637383930313233343536 +IN: 48656c6c6f2c20576f726c64 +AD: +CT: cec189d0e8419b90fb16d555 +TAG: 32893832a8d609224d77c2e56a922282 + +# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf + +KEY: 00000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: "" +CT: "" +AD: "" +TAG: 58e2fccefa7e3061367f1d57a4e7455a + +KEY: 00000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: 00000000000000000000000000000000 +CT: 0388dace60b6a392f328c2b971b2fe78 +AD: "" +TAG: ab6e47d42cec13bdf53a67b21257bddf + +KEY: feffe9928665731c6d6a8f9467308308 +NONCE: cafebabefacedbaddecaf888 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 +CT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985 +AD: "" +TAG: 4d5c2af327cd64a62cf35abd2ba6fab4 + +KEY: feffe9928665731c6d6a8f9467308308 +NONCE: cafebabefacedbaddecaf888 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091 +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 5bc94fbc3221a5db94fae95ae7121a47 + +KEY: feffe9928665731c6d6a8f9467308308 +NONCE: cafebabefacedbad +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598 +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 3612d2e79e3b0785561be14aaca2fccb + +KEY: feffe9928665731c6d6a8f9467308308 +NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5 +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 619cc5aefffe0bfa462af43c1699d050 + +# local add-ons, primarily streaming ghash tests + +# 128 bytes AD +KEY: 00000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: "" +CT: "" +AD: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad +TAG: 5fea793a2d6f974d37e68e0cb8ff9492 + +# 48 bytes plaintext +KEY: 00000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0 +AD: "" +TAG: 9dd0a376b08e40eb00c35f29f9ea61a4 + +# 80 bytes plaintext +KEY: 00000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291 +AD: "" +TAG: 98885a3a22bd4742fe7b72172193b163 + +# 128 bytes plaintext +KEY: 00000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40 +AD: "" +TAG: cac45f60e31efd3b5a43b98a22ce1aa1 + +# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF +KEY: 00000000000000000000000000000000 +NONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +CT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606 +AD: "" +TAG: 566f8ef683078bfdeeffa869d751a017 + +# 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF +KEY: 00000000000000000000000000000000 +NONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +CT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c +AD: "" +TAG: 8b307f6b33286d0ab026a9ed3fe1e85f + +# 80 bytes plaintext, submitted by Intel +KEY: 843ffcf5d2b72694d19ed01d01249412 +NONCE: dbcca32ebf9b804617c3aa9e +IN: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +AD: 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f +CT: 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5 +TAG: 3b629ccfbc1119b7319e1dce2cd6fd6d + diff --git a/Libraries/libressl/tests/aes_192_gcm_tests.txt b/Libraries/libressl/tests/aes_192_gcm_tests.txt new file mode 100644 index 000000000..cacfaaebe --- /dev/null +++ b/Libraries/libressl/tests/aes_192_gcm_tests.txt @@ -0,0 +1,44 @@ +# Test vectors from NIST: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf + +KEY: 000000000000000000000000000000000000000000000000 +NONCE: 000000000000000000000000 +AD: +TAG: cd33b28ac773f74ba00ed1f312572435 +IN: +CT: + +KEY: 000000000000000000000000000000000000000000000000 +NONCE: 000000000000000000000000 +AD: +TAG: 2ff58d80033927ab8ef4d4587514f0fb +IN: 00000000000000000000000000000000 +CT: 98e7247c07f0fe411c267e4384b0f600 + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c +NONCE: cafebabefacedbaddecaf888 +AD: +TAG: 9924a7c8587336bfb118024db8674a14 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 +CT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256 + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c +NONCE: cafebabefacedbaddecaf888 +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 2519498e80f1478f37ba55bd6d27618c +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710 + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c +NONCE: cafebabefacedbad +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 65dcc57fcf623a24094fcca40d3533f8 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7 + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c +NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: dcf566ff291c25bbb8568fc3d376a6d9 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b + diff --git a/Libraries/libressl/tests/aes_256_gcm_tests.txt b/Libraries/libressl/tests/aes_256_gcm_tests.txt new file mode 100644 index 000000000..9a30a2311 --- /dev/null +++ b/Libraries/libressl/tests/aes_256_gcm_tests.txt @@ -0,0 +1,467 @@ +# The AES-256-GCM test cases from cipher_tests.txt have been merged into this +# file. + +KEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01 +NONCE: 5bf11a0951f0bfc7ea5c9e58 +IN: +AD: +CT: +TAG: d7cba289d6d19a5af45dc13857016bac + +KEY: 73ad7bbbbc640c845a150f67d058b279849370cd2c1f3c67c4dd6c869213e13a +NONCE: a330a184fc245812f4820caa +IN: f0535fe211 +AD: e91428be04 +CT: e9b8a896da +TAG: 9115ed79f26a030c14947b3e454db9e7 + +KEY: 80e2e561886eb2a953cf923aaac1653ed2db0111ee62e09cb20d9e2652bd3476 +NONCE: 5daf201589654da8884c3c68 +IN: 96669d2d3542a4d49c7c +AD: e51e5bce7cbceb660399 +CT: 4521953e7d39497e4563 +TAG: 2083e3c0d84d663066bbe2961b08dcf7 + +KEY: 881cca012ef9d6f1241b88e4364084d8c95470c6022e59b62732a1afcc02e657 +NONCE: 172ec639be736062bba5c32f +IN: 8ed8ef4c09360ef70bb22c716554ef +AD: 98c115f2c3bbe22e3a0c562e8e67ff +CT: 06a761987a7eb0e57a31979043747d +TAG: cf07239b9d40a759e0f4f8ef088f016a + +KEY: a6efd2e2b0056d0f955e008ca88ca59fb21a8f5fc0e9aa6d730fbfc5a28b5f90 +NONCE: f6775dca7cd8674c16fdb4ee +IN: 5dc495d949f4b2c8a709092b120ac8078cdfd104 +AD: 86a597f5e2c398fff963fcfe126eae1bc13f097f +CT: 04416e23586ee364b1cf3fb75405f8ef28fddbde +TAG: e7b9d5ecb2cf30162a28c8f645f62f87 + +KEY: 8d6ed9a6d410989e3bd37874edb5a89f9ab355fa395967dcbbfa216ec9ce3f45 +NONCE: 55debbb289b9439eb47834ab +IN: 52939c7416220822a77435a46687f134cebc70a2f1a4c33d37 +AD: 7790af913d84a04c1b72d4484ea2e09fdaa802d8b1733b8470 +CT: d7bddae8929ed6bbc9ac077e2415d9fbafae4a0432f8f7eb6b +TAG: e6383b16ed9c32521dcaeef3a7b9b67f + +KEY: 525429d45a66b9d860c83860111cc65324ab91ff77938bbc30a654220bb3e526 +NONCE: 31535d82b9b46f5ad75a1629 +IN: 677eca74660499acf2e2fd6c7800fd6da2d0273a31906a691205b5765b85 +AD: 513bc218acee89848e73ab108401bfc4f9c2aa70310a4e543644c37dd2f3 +CT: f1e6032ee3ce224b2e8f17f91055c81a480398e07fd9366ad69d84dca712 +TAG: e39da5658f1d2994a529646d692c55d8 + +KEY: 630b506aa4b15c555cf279dc4a7ee9add213219d2c68163ceaeda903fb892c30 +NONCE: 79eca200a5cdf92b28be5a7a +IN: b12e6f1f8160cd65278c48f68ad53c8c82fd17c2c39bbb109f077c17fdcb8a0b3a5dbf +AD: 46cb18593b3b26ba75e4cb20a252caef31d00be31093d2369e93572a393d650c68313f +CT: 9a9ad1f78b4d411afe450d2e46347a7df98f39daa4fd478b9ab6e6b417878bcd52743a +TAG: 55453a003b021c8a247379cdc4fa6da6 + +KEY: d10bb6641e9ba0a3f1b016317831ad4232f81c2137adac0940ecd7fa36de0563 +NONCE: 99c922d37c95ebeda8e81ae8 +IN: 8b9089df5bb048cebbe709cb61e178ec768515a0031288d95b7cc4dfffeb51b836e126a237ec50cc +AD: f1cbf6c83493b2087d9f88e02121a114f45ed51817e46ffc0b66a783350eae89c6700db3f3be5f4a +CT: 8a838c51a8ef8134481e9951033295ae686624aa4df72f869d140980347a5e69a6d7cb3d7119b303 +TAG: 9152bef766579a3e9a1e36abd7ebb64c + +KEY: ca665229adcc7554f1b1c8f50e7444c6d4059c525f9c0da1406ffb35d50cae97 +NONCE: 8e2df19123ce0ad41df416d4 +IN: 12365eaac86b270e9c61b3ae7702a6f3583ef4accb80a98454c56e34e2ab97d8afa23ddee34e7e3a522497f985 +AD: bf539d8e9e3a02f3e5834970e7efd40cc7cb340a075041428d6a69ed9fa5105e4bc63720be9a7040ce5b4af6e1 +CT: 96027efdcd4433df8e7f6181c05be365cdce550b09d45cfc96fe258eab6d55976a9306a0070c9589ef08cf7a42 +TAG: ec9fb5e79cdf8ad4c8a79c900975159d + +KEY: 5033338bf7526cca0425f4a620424662ebc58364c8d985d130e525fd1f598f3f +NONCE: b40842b30758aa3eef7cda62 +IN: 69a62b8c5f9b81cebee3a9345f4e49ea089b0d9c1cc57b4ef707956d0287de83fcca6d8f5270a9393e00693075028189bda7 +AD: 3efe0ed6fbafa61070388abc59c0d06589309736b02418df5534c8c594d61a2afefbee17af8283d01634b6ca3e8e2aeadff8 +CT: d6184677a21978b6443d99d7de1fd01c6b6334cf01b7e7d58456267453f4de96708b62301172c8c87e970f91c5301e0ff61e +TAG: f8ac7aef208712845d137b8b176c89f1 + +KEY: f33c39140999a2cb69e43129cb5df18fffeb3513ec3560792e9909784daee43b +NONCE: 70608463f1dfabb1fc4451e9 +IN: e2802c4d290468177fdb031a717345753cd7c3028ed07dea428db84e7c50c3eb7b24f7381a167b4ee31bf88dcaf5251fdb90ecbb74ac2f +AD: 10a6f463dc59d4791b3c2b4c93cbe2dec579a154962cb2c4cc77664e8c2b106c574fe115fd43dad94b8b1bf2f74820e28435b4444b2b82 +CT: a27419a46037323c033d7cf2a716777fedc02a5ddd8bfbdbca82ffbdea3037bc1cc80df7c5e502b32276ae88ad6fd0f0cfe72604648812 +TAG: b1ae330d47fd399aaaa687e141e23fc7 + +KEY: 2121056225a7b2316a93c4bfeb970486fa9c586c14ba8b40be5844a31e9449c0 +NONCE: b4b7d1e8fa7d0e2334c92315 +IN: 2038e2c6cdf5282f081292448f8febbb60a1520fa3771cbfef387f48c5915a1438ab709628e8d4c81623ddbc2f6f159c3c9a8922905c4994269898b8 +AD: b07f66508a39c4932b04c16172d6462d78273cd9463e52284bb73e3b8b8e7047bdf10c5ace1f903e5a5eacbf67c9351f82c74bda140df2fe0480c80a +CT: 7b54618ae09b37ee72e51873c82cdd20b6dca37c334af89548f52f34df3a757e632cc0d453fc97270898eb50ce2f2a98c4cbd4cbb22a5b7c7564406b +TAG: de3a9e2aab2439675c4f7f0b61216d5a + +KEY: efb15235bc91771aa32d51472877b0eb364de2f88766908eebc6e6b57a702099 +NONCE: 1a510b42dc20d1d0fb34fb52 +IN: 4eff604dd4bba67f143dab0728b8597e269d4e0ecb4ce80c9850afc645d96da239d9db360605bb4268d74e1fe3431a44242ae862fa2340c076db13315f615b85f0 +AD: e8dad34f727e77444a96cf06425640f1fc80fe3b01dafd1d91476140afe8204286d01b0ebdadc0270a3d218516ff5f08a69a7ba251ac325983caccbe0d9e1de359 +CT: 989fef0145e2fe93b9f99fd90123632d83d9df8f37d8e1f80dac329dbe0c214c2191009e31232538fec63a29665f0fc1c77dc86b2f5f2050b86b3ae48e85d63116 +TAG: 6816304faeb45da4e4772f5c35730f8a + +KEY: 998c22912d5687fc3faac262a902783fcb0c738520b5c4135a8dd2cdbd7b0dfb +NONCE: eeb535c5bd6edfd696655b60 +IN: 1f6ae10d425923c882b7d2f556571acfc10333ec665b07bfad9f8948a3b8c5e5f163a4e99d4726da1a35359c657c848f327b7fd9b5f61987440ab12b9399db24715715a2d1c8 +AD: 9a3c76dbaeb69a6481a89318caeb6358267ef51a1a364a48387bf77526837c9c70afb6f105cd47d2b976dbda7d2b6bfea7b76b135810c53437472f7b80ffc8ce4dc95c7e5045 +CT: 87f4e2c80a4f15f92a8e94f468e70fe7f0e0f83c0a7799a1d465043d25210ac6f0f39a5e9765b4daca637864d1bcc090d2ef33ddfccded2d2dad61dab443b3cfcc683147c490 +TAG: 0744d928a5b5ec95f3087cc2623f0031 + +KEY: e12effa8da2c90a5d35d257c07d1b467991bd5f75fecd7129aea4e26b9e27ff1 +NONCE: 4edd0b4cc349d37eb77f5576 +IN: 21dc87984edca46a629ed95ffb04471397da8806c525a781d9a71818422e344e4af577f38e7cdbc556d4766770a9a3c95bea59ad497fe0127816ec4dcecb6b999486719b0b86cdb2c9d09e +AD: bc158e6570fb0a08d73367dba65b80a8c8e57ba6c7b99493ebdaef0424e18d8ab1f7c88670cf51c4d91b77eb9ce0f89a46ed1316141e4299ec6c3d6e712ec9e92d3db44640402aa4ac00ba +CT: 07ab8c623d683ff83030392e2864edd4b8e3d296d60579a226a8d2aff6bc5af3c4598a18cc1e8d7db4ac8eb56a082af864ac52a324851dd29af51a0945cee4bf303ea111b9b627aabf5ff8 +TAG: 53e69b7be969c39560c016c6bc1aa4e1 + +KEY: 3d9723c9235939df8647529b7e4a57b8536476d5b71b424e2c27ba4d0b82b0e8 +NONCE: 60163d2eb7822af7fad64c04 +IN: b44face0f45e4a8da19aa0c5cbe3aa960ed6b74fe3d3d9201f52523dfe7651756b2ce482e759c87bde4ec670a0e808fb4883e437c7cbcf2f6470352174327824200cb0897edc4def1736f51e229addaa +AD: a4b2b7bf36a70a5246feee52c474058100bc618fb0e3d32e8c1f76153edec47fab3045dcc7eed9ca1886bb2593703c9ffb8883c45386d2f4e3fbb0b7c722d19f2eca94767174d9127450549e8993ae33 +CT: 66fa63ded066ac67bf218af7bc21169a875f4bd695f44fbdff906f0a9b8a067be721fd260571c53a8b51661c8d49fe178dcb28c31deb3fa71b096b387f9fc8f3657d280404c05d2b6443eba7e60b562e +TAG: 59d5450872510c4bfb590d9497524331 + +KEY: 75b0a20935c4a5e2126ac7420d632bfda8d41bc947c2402bed4759b6e617ff92 +NONCE: 0c3edf0dcd1125d7e263b897 +IN: 8edc98e70030e40bea1548f6f56b4561272be0c333f3b7ae53ff3e27c35a91b1aa42d39e6305ec4811e75931e5cae2261d88a6f7d6c5b05bfb48802264e9cac782411f1de579e29d464ba56840b126a3fad07f01c4 +AD: 7e35081ef652424da6304852243ce43ff711da17f7881d5e0433b1ad7535e755a8531b93d67ce99ffe66e59fbb24f6b42655524b39f2c84daa5cdacb5e7916266c05711a118b2128930b95de83ff1a67e53337474a +CT: 858dc74dbec6fdbe4ef15a3596ff7201c8f4fcca765bf5452f678b1493a66ed9852a6fa174a73099acf951a35699f33289ec50625538c01eaa456dc658013a29e4d133b856eb969c1f221f99e11fadc98b0ee08243 +TAG: 3d8f17838c4fc69f04d7e2b76eebbc0b + +KEY: 7a3823191abcebadb7970d1b65c2a8dab8a908151737bd5400b3b6c0d59e3b08 +NONCE: e32eb00e5106097e2ef0e8ba +IN: 220db5400dce604adee4cb698cdc02d2ca61622bbdeebe347b0bfef55cc45319b940f93773a9878725c5f55485d7a26363251b9ce0d3da1f8f6e34ad5329dc9f752ec7dc12b2d259ac89a8059085996a431a56cc2dc2400a26b4 +AD: a83b6dc78931cb7500eddcf77792e810c1edbd5f4e33f85018807a8539a3cace094fb794fa9ea058e82c830d42d5a6b3e22b7785698774aec5c73edd92731c51106a23c569c0c0fef18d13da1562a9a42aa435b243c4fbc9fe42 +CT: 5ce6ec0e1d67ced5a6aa46c909b9b8907b372be03331dd0940ceb6d87e928c14a1a1e8ef9096c9b63ab4cd93242ec7be7e38b80643f9c52e7e90ffa06b8f2d238fa63dcd97af74ae37802d124623b8a272e68ca18b3432b7c017 +TAG: e21c61d604253bc5b5d58283756b9eb3 + +KEY: 53ff6dc0af3e89fc2de7370caa433f539d068609fcfed6400a5b9fda4c83e3aa +NONCE: 91a824c5e023283959858062 +IN: fc23e07b4018460279f8392e86423ecfe465b25b60382f58995ef5fa1f9ca235e4bf87112554aa0e72836831d7b5f39125df11518b8aeb1809d804419beb05ae013482213012e4ce980ddd1c58e11608b775d12b450ecace83e678c69d2c5d +AD: b3a1db2d467780480f166859e0e7aab212738b85e88237c2782496c9c503347de02f3dad6bfc671fda71a04ff1e4661767c11303daa0c36d944346d39e3e29ec63d695cdcd83b2b57181582c5ac692b13e4299ab5e86c59d09c2dc6194ebe9 +CT: 88af588ec33bdac2cc748a01ee3eec97e5bbfdf69de1d66176f42b66383bbffa8b185cdedc25b11a62237d334d68120fccfd68c2f9447b3b8e1f623f33f7f97ad8815d29bf11bc0c65641ba8fca4a087783f4694fb1d574450191825f84402 +TAG: 2c4973323e635a885f78ee106eddf19e + +KEY: ca2b4d335598f26d3d3607e62b9ef853d3543e741350f92f3050894721d3d450 +NONCE: 2431b5cee8c3ecec4caad278 +IN: 75e29e46350d1fa99403b1e5baa414e41a8e714910f313f8e850cf3076508ff650011af766b51283fbd5626166d775fd4b4cb7124d26d77b41eb17bf642bf67a34c1caf0fa9b43eec12103f864e56c5ccdc81b89c1a35e394362688d05dd94eda3d05dd2 +AD: 31c3ce532bc1bae65b5ced69449129b112019cc6078268b853dd17c41832ecae07f9c6b068ef6cba2b55f352904afd6096ff8432081aed408d9340c319fd8e2029c389b6e3a4bdc38853444c3f7be9385ff1ca27e59c43b542e99799bb4ce56b8e26d6c1 +CT: 90c13ec26d01b7b96bdd6816d3ee57df57efeabdb15ba602229ff71d71793fe8081eb1b462e8b2967bc4af96fd6dc72cee3d2b6495c7f04c9068b2ad0b073e11cd5999df541ad705c6315eefa8da49c5dbc258f7ba922908489c1ce672971c3bfb6e8482 +TAG: 3a7741a094be92b838850c32e4b06c6d + +KEY: 49fbbdb5ae21cd955be7f7603cb8563ea0b02b77a9ea14016baa5cffc55d20c9 +NONCE: c0a4463350506d2af9e35d8f +IN: f31003aaf5d8fd6261c01c5bb1e7bf6af248e0be3cf8aac67ccaeb0b7468a40d98be526a8e4f692dd23763563e601915ebcb59ecbf03bf9c665c4c5313c318939a911888fd427d5297b9b2fd91dd33eb7ed38e2f0f6ab74ec263989cdd9915811a022d4a46ed35eef0 +AD: 17e01af2386531ce67d5bc3325d8f83b53a87b38f1c305f99c0798380a7e59d3ecddf33a5ad23a82e33f0fa34eb2438b17e958451439774ab642fafd3794f80a0ee1b9bc165f32df705a6175310670ba54af3a204e446db35170ab02670086c47a475c22d1f14cbe44 +CT: bd661836d1b74244baca62d7d1cb6717e17e2fb0bcbc8d36b3265a983d557c562b0be60708499d0e7e9626825bc049db79a0ef4d2393fef6024d849089455e55693fd4da3d910eac11496492a645e4376855732765e1b3580461a2a2533cebb482736ac928cba175bb +TAG: 4596e3802109c899f27f6cfcbdceac5d + +KEY: 30d0e4f6425e38c92ac34dcaa06a815166f301289ca9cb0ed08156617d87bdf4 +NONCE: 525618ac9e317405c7d44367 +IN: 06f2204ca864dd3f7c9d0290f6fe3d0337eb9442cd5d2b586d1d5c30e58951fc2f4e99831ac7bca4356db4609a0428c482f2580b9e8cf5fd00d86d474fd88ac3b2413f44c1ff66e59e7538c090b2444396f02004ff636aca05ec40439f4e3f470a24916fa4033cb60127223addc1 +AD: 23c1a3e1083904f7226be7242027abb7af9d62f1115340cd4a57611be88303955cbcbeba44eab5488c80aed3e063c70cb7bbdd9ac289c8c8977868c3702be63d0358836838a97b31f6aee148f2b8615ad7c5dc0de7c48db7752e5f1ae8637f8c70335bbecf1313ae1b972ffb9442 +CT: afe3e71953bad46ad28113b7c8f2092fdebaeb81626bf94bd7e9dd59e000e8ba31c1ce7f728fe19dbbb42322e54aab278e3c29beb59b2d085e65cb8e54ea45d6a9fb1f561bac0bb74afe18cc8de51abf962c2fbc974c7ed54ccf2c063ff148b3e6cccdaa65cc89ab19fcd9cd0436 +TAG: e9f5edea1fdfc31cd5da693b50b72094 + +KEY: 661309741227606892db13ab553070b456c5e421cca59087144873ae6d59e590 +NONCE: 9f07692c017e1391a981e70e +IN: 40b5f8081b5dd173203e02e90a6c171fc41f804b2903ea18109edcf77c03dba687b47ca389c55389bd7b0ac59bfaefaf43b5f97065df6a5375c1fbb95d95cad589c2a45cd9e1e7960b1d13622440f7180aa565863b4f9dfe26ed336ff4318653e1a520bdb830e01db78a7e598f251834d0c9bb +AD: e8540d084f24b80414af554f470048b29a5af8adb2f9d55c9759e5ff1595ca74884af67027324587131d90c77ca72b2d15b66564549ce93df7f667d0218a6e874848563a33886c6a0c5a9d00fa435dfabaa9053243b4c8c25779a4dbf79eb4b8530a7c7bf4263ea824713a90cee92dec78c449 +CT: d543f49e6cbe26f1d8a6e058769d5b16e6f8255a28b4d73ba2cbdf664bbc5ded73f9dea12a11b86b6a6acd578f685afabc232dbe9ff8431a5318ec7f0202959a310595b147353a7ca89c9d1fc2d2b92ea610cf6d9ad2716df2dfed70f5b74d498edab114058c22c96873a2a64abc254c82af46 +TAG: 31a8441886d0e4c6bfcd6d74f6a5ee5e + +KEY: a248b0d683973d205ef2d3f86468cf5a343d6ad7c5aaac0b9b6b2a412eed3552 +NONCE: 8f62ffac4027f4dfeacf3df2 +IN: c2d7d29256832def577392acb9fe4f249eb4859025ea55cc0c4a67806caba3e1cb81bc7f5717d94e1c91ff06607b23c238daafcb0fa96905616f02205b702508970fe3bfca87270ed1102a9ab96df57ebdcfd86ef6e9c4c4242b4febd82b0220b0d6f76d8c2d0fba33ca49279907f6bcf7e8401d1419ed58 +AD: c738cdbde6dc277ab81dae20fbbb4a50d71bcf0ac1ee0ec6a39747ccd87be40b1f0f2c37f2c6b32ea99722979fcfddd0ddc2e4ff34a2e6113b591cbfda317c6f4b021ad30325276f8d8dd78f757618b53297fec091f029f9b00850b35f3863a3801c882422b318b4a1bdd89002f928371ea05c6fabcb1792 +CT: 7a837df292ad2e58f21b89da43a74de411e1746556fe47db55a136757513bd249384bf67887a5c1f605e7f7e3057596e17039701ea351e5ccaf0fd4882559e87197144632977cf07cf9e86784a959fa7399476a4fd196d7c507fe3876d759e2b37bd37edb3c12b89716f29ddc8b64974263a1ec1b6364b0e +TAG: 291098a2376a0faa5da6fb2606b4f2a4 + +KEY: 80634a8baea1c4fe5dedb664c9b5d714422dd1726d642e60d15e02364195206e +NONCE: 725ee5023ae08fece15d621a +IN: 4d1d8855b4d155e77bd1bf34b3d049ef09b2b94f4e604306406b015a2d520e8772b084ed668b868e32c7563085f2a82e7d99219da549e507aff9515e45a045c7cd5292c0e09a3a38c769acfd0a11826b27d8bf05184971670200e79c49754debbfc57d9ebc661b25f22f241c4d143bd922f7b0981a48c6a63462cb5cfd +AD: 12b3fa94a64454dc5b47433df1ce0a7dd5e8066d05b2433c6cbcb83087bb7d22d153a19c05aeb76141431c5f9801cb13531691655939c0c812611c6a30083ed3ec27e63e6868f186be559c48367a00b18085ffb8c7727638e833a7b907ff8465e3a01d654b52432767b18b855c05a9cfb5d4aabae19164f0dc2ca6346c +CT: 6b01e934916823f391cd0d2829c224a12eeddc79f18351d2484ef6cb5d492ec9ec4d8c4bd3354f01d538bbd81327f6360a7d157feee64b539489bfdd1be4d7f724d2a6dfa1af91e4108dbfffd529afa71388b07e5079236644da289ae236100b2fbeda0c17bf2a01e76cd1f88081682c2d074223fb8a41d59e70a37870 +TAG: 55762e95d897a33c4c75106449112986 + +KEY: 4f2edc967b11983f05ef5ee2a4364039ac02dbcccef3f3719913ae2719c8217c +NONCE: 255f8209b0c67a6277bdb42e +IN: f8217163bcaf77c1383089e396b271e22c517e8ccda244256cc39315fab7d0c291078d90e9b6e336992f015282caa1ec0ea858a179c9735b7a2f0d50f6f1eecaf3b9308772279ebb95f8aa53826e9dd60fb354de0c50c10001c98812b59d7c0f36daa1aecda6782ca36130fbb559363fe07704b0b91ea85be319ada027e47840c764 +AD: 1dc7065f1585384b88be47598ca484782716c78f49b3b6bf5d24a5b0d24fbd7831f18d77d80951d2c4fafb6f939d46362a69b558afadb3bb4d8aa27f7fcf3dd9624e1e075fce9bb239926d51ea9dff03619d64d5828103a414e360adcda8fd864fca55c21df86c76972c3765ab1d68ce89f708e7e5a3e06cd4de08573cf750c6f5f9 +CT: 6719849b7cea3f7f2a8e4de13d7a864d581b7c638f49fb06378a768d2034548179963c33f0ad099254c2edda9ef771daf5d299f58850033e2e449d7bc21ca3f7d3b7408429b596da615c8582886a6d8c1a9ba81fec4a41a38b7cbf1a80ee0ec8bd71451e727051fbf2a1d1e3c6ca98ee113e47650ba4fe80451e79b04abc8bb99a2a +TAG: 2ac7f962553a8007de3369c7795bc876 + +KEY: 51c5cf1f0c76ec96f4a5f9aa50a36185521f3ba259145ac6cb4da3cd12467696 +NONCE: c751e5e7e3d75874acfd2bfa +IN: fcda42cd098b7936f4bebaa37d5850cb0fdd6526966b1b5734f23d5050ee44466627576e1144957929123198e40b64eaef74476870afecd7b70f7583208603a1b5247074c6c77e10b9bbd41a3d468ff41db89895b0e9ca95be77526ddb30d4c5eb0796ba97d7d5c56d0eece344dde3ebd7de586226c00da224b04e74d9abe832686797df067c52 +AD: 343ae5e73fd1da48dce92ba7b86d21de0a203ba8587536fbaf4646bc45051a7feb343e38916f6c4c75b65f940045e830857c7b62b34a44622a36b34268b8a397892ed3e4de5df3fa7384d4ca50202b5b0833f921349c877931f4b735cec45db6b95410c8042ba49c1a39870276e0165f09c73b14bdf7f36d19084f958695c7ad2cc56f0487eae9 +CT: 04192659d6a2f1b7be472372c8f969a7de388c97d37b4a89653593e48b630947d2160b569379698e94de49b21572ef0b4dd330487a8be814a84e959a1a8e3cf33dcc9f7464fd44814d0cd7ab85e4c01c9d015f42ce3723c8ef8c311222b0c78eb83d81696c217992be725faf27701b4922c6e6099442787ddde2b7572500a5320a4d0c787b786e +TAG: 23c7a866574976dca8f401c4b5b58292 + +KEY: 1cec3efc0311d623f34b6853b3dc97e470fa728cdfd65993d9d48fdc192b28e9 +NONCE: 320fe742ef171b7b8cb615cc +IN: 722e503a97166a07974dcbf136fbaec6c03668fa52495b040383433ca59f6311103f2fc6a95ba4c925f8637167537321eff6949aa3051269fc094393a7b17d1ac8d29af052760835665b0ee89adda5dae7738656af9e8513c96e8a532a46ef34cd7430832d2be51c586a14e9aaec2458c1911bbc0f90b496737e838a12ff37d3db058bda9360d7d33e11629a +AD: fd5ccf6b6948c3eb96543aa40f107fafe94e5206c326dd8900ea510c6b61d1bcf746151a75404e31406c8e991fbf6e660db7c18e243fd2608aa22dd7ca9de88f277037661ce6dea4ff0a86809dbfe1708cd47d3061a34657cad143e6577549c9944e081f79c276300bb406378b26f349a91fa87de02a1405d712c516ae11b4bcf30ac9d56e677d03eb33e3be +CT: 363c1d6b806a6d97e2fddf53b242378e1d2b818828863fbb3f856f7737d63998a84e02d6c91e1df5f5eb6cf89f7ef53e16d10ad52f82362292d3acafaa02c23be7da7616a8b8daf8ee3ae74ee1078742c4ddc3e5a110e510417b9f43fbcbb00e17af3301b2fbcb784fb0a05b66469e771fbd78114fce3c4352c42928bf5a0ecc49228a3c930b0790bde7ad7b +TAG: 669482999be99149f9b723b60fec62d3 + +KEY: d3465cdecaecbf25943b7bbf8084ccabc15474a4228c46cbe652a99be24a861b +NONCE: 04fc836de3a1420b8e7136ca +IN: 81e0e984ce0a4074a44524f93e375eabc650a847a42393f5c524c65523368d38a7e2b677fe08502dd3bc42311775016b5689c660cc0ca8cb33a09b89f3ed3d02fa0fb75ca5bf0dc3c27c546b369ab5e7731f93bc074d37ee50d6f8366f6c8a45f73ac92b05c4aa552ecc5266041dc122a0df69a36ad625a26edb57bfff43a84e527ea0d9d3cf076f8de9eda28eb09de3ff +AD: e4adc14ac4bbf3ae7ec7d97f5c0e6090bf8127a75e8b70e9b86496a62a759dba5a4eef64a8c679c362785501260d29b58e1af647782564947950428dbf14edab8e6841c7afaf9e7949b560419c44bae30315c597f6f6e02204da7ec605a4d9a8753de1268bb0b1c84c972b4e7296da5c969781feeb35a44d2aef799ed228aa399ea04e21cf9f7d5600a2c07b047aa78388 +CT: d7995e7b610eede708526c05c584039d48b9b4356fc71b0c37ec2559309a688a7c69ac9655f94e178cd2311db58587863b0fbb990554dc9a6aa849571f945c61e5611ae7e1a96903be725a1aa75adc381b86e43fbc68a36f44e0e0cb8fe5c494caa91f758597b6ef3b80a879154cd8a7e5f570893b4f768105b24b58efb67c5f07c6db60e0f48eba9563f17d38aaf0847e +TAG: cc3fe61642c2d7fcbd579048fdfb19ec + +KEY: 1a0dfe2a6bc6a69659c68942ad0858e1df905890f47dab728ab9c73f742f469f +NONCE: f8f76b014116ba61392597de +IN: d93eead436e835a061ca061e3a53c3f9c66c6f011b21682b8a6fed098bde2018a2462aa5ab542c69bfa2805612cf6146c9150888b9720db1dcd0f359c1fa3416df4cd225dd0b0d949e917adfb3e83bf5ba2b967d48908e6b6d8aabc545335014d951a67390d7b5c7cd7dcbcf66e4e3f02aa4e5e9cccaf73e75622bad006c63433d36cb1c6aa4aa253dd1b2eacac75c548aa6648ecf9d +AD: 56ca2d5340629ca75de4e98921da352941559bd79f47ef0ab42d1d5857059352f96ee877f5458f090ca237e4eef5b08a53311c8dfd4c4582f18a93aaa8cf75080734cb2ea3389c9c74d2b04ead614eb54512ea93f0e3434e9a9366454b303a8129d6ce6cf96b1d6dd4f751311c736b517dcb50a6f6e0962c46637b4f5aaf0f34bff518cbd551a7aad3fa615708b17cf6d8fbc864f580 +CT: 8dc4d8483dc665b174ba32d6b6244da5f2a8fcc4b1865d662ec23057838b332a07ff073ecc893d413696f3fffc6dca5d107a5673f14abe8e0457a02e61138380d25e269686cbbd23cb7da3060f482f62bf80a40dcc2e711ecf5f7836ca14e456c4b73a48bef90749024393f5f8af01b73302e81bc37c4110dc26174702231d831cd14231905d2dd3f375cf2bef0425084d5b19f1039f +TAG: 825e7b7e195f65c454ce9fdd637138c1 + +KEY: 03cec87d0a947822493b5b67b918b5c6a6bbdebe45d016ec5cb6779c3ddfb35d +NONCE: eb7d261a6b56a179c88e88ad +IN: 2326102c58524326759ad399222c5b5a563cd01a29809d6aed4d49772a4723cfdf30c9f85f031063e838f543c201412d6f085a8f5435b0b2fe94659aaf70cf7bde99309239ed5b815b48342d4f81011f5aefe10ba105ac15601c64a91076c29c3cdafaa12bdd5706dd7305b48e923873cf06944b5027b210c59d79856f602bd6481980ea909152216756d77362c59d57673cedb91ee6f56a40061e +AD: 4d0fbeb69c1869d2d23198ec49b3dc23149005a84aace7025293c3afb8cb2e38c167a822e25c2fdf667d3677f4e94ed6574529c987de506d26b7ffccf3b7a36d9adac48bca76084710338eeb5bfca9df1bf6b403e33e90761a0b3152afac333071a5ef4f54010b945d03b51f123865673e8877f41ca23359e60518f076cc64232b306bd858634417e92e546ede4ac6231635c9cfcf43aab1f8fc1e +CT: 06746f993843901ce72f2fcd4af7d15e64b3102d2f9bec0fe72cdd0b97e43177a1a2238c9c1dfc3311f701196653249e767a73dbe819b660cee07a5f3bb8f25823875fb4b4d34a5a3a212d2e166311bbe11fb1d36f4e725c3b74054ed7fffb7082203ccb5e9d65873cb8a1ce28d5c6e2b6555c1a864a725e6c7d5555d37dcaf1d0884264be72d38cc4b65bc2f0d039d542c5055da56c57e084b804 +TAG: d36a4b6d2f592d4f0d347d906fc319cc + +KEY: 7f4b4bfa26719d9610c80ba3f474c43127f4aa3414fb070fc2f389e5219886e1 +NONCE: b144d4df961d4f1c25342d12 +IN: 638982b95d66ddb689b7b92e3adb683ac0ac19480148bac9db550be034cd18dbd10f2459c915e99c385cd8dc4dc6ec48b75f97e818030fc2d8fcdf66d66b80df64f0ca4af91bba83a74f3946b17af405bbbc6e216435641f5633ad3ee24c1a2ed1b39f649acce59ee56c282a3aebaee6e97f96b34cfc63d5b0482fec20d755f399dd5f61688fe55878713cc55d562c2d72236eb674a340d1a64932cdd8534a06 +AD: f2fe3d27bfc278cdcf16fffc541846d428b31534ec5cf51c30c8b6d988dc36cd6c0d41a4485a3f4469e92ea0fc7e694065bd8130c2854c95549630bd9cbaab2205f27a6efdc2c918c3be53f2d12f8f7cc8e6a81dc8be7cccd217be1fa2e6887cea7d637d2e2a390f50d2c5be10a32a9b380a400cddbdd40eac67f1fe9ba6033d4bfa88c563eaf57272c8a7052916cf4460f31ad026a0ac2588a45d082fbb5c0e +CT: 0d4de3489e09c7239972b675063579e409acbb663bea76bee8fb3f7e8785158ebe1c26db9219a9b97ea29e74762999518613249c3a87fbcd0128f651e2db8e2167f10ab532eced3464b56bcaa09780e5ece18182a6e092477ad933bd8de015c80e67c6802257a97a647fe2b1e9ab6a76c1cbf7d905deeb824aba2a34095f84b276d55ff940d6ab788c16cd63d9b16e0908d718c851a3230b0a37257751df5a38 +TAG: 9f0a882d4456847f44c7287c8ff3ba04 + +KEY: 9799ae8045d58250e4d9c3b0ccc8897a04b5b9fb164e54019dc58d7d77b65459 +NONCE: 0f20d002dbcd06528a23d5e0 +IN: 8f323018b1b636617c935791e1c8023f887da67974080af07378b533a7573424f1de9193c5d38f55e9af870f6c60ab49c80d7d1ad1f18f1a34893fd2892d49c315ee668c431f5f35e3f60ecfd534b4b09b64cc77cd16b0e1b8882872cd109a5ca377518e5b660d75052e9a4228e3935705b6bf6b4f4249346b7bf4afb891641a76621cd315cd75de391c898959be945ccca7a96073f2569f217617b08502f7d569bd2f80e0 +AD: 3f1e297bd91a276a4a4b613add617b0488414a57ede2ac75d10934e03be58ec518a418e98a4dbb39d2365889db7c5f389b2a16d8c702cf21b888a4cbf77b356df48a30298c825fb86128de45d7fa0e5f4b0b7bf82a2c4cad2470f33c231802263901fbda54a6edbf2df638716492157ec1407e7fc2eb6c663d9a215afbec3612778b8115e78a5fd68cf6ce66c12c0ca26e5c1f7ab079bc09c3bc7b673d21835671a13dd2a0 +CT: 9a5758dad7997a766db05d698b43fd491bdcec21352032cc023bcf10e136523219745a56f0360efee75a37de55da23cc7d8184a50ccebb110bcb960dcf6b25fe731e21f26290281d9c1c7715c4e6ff3dc0026cce52929163ba222f123d4f50e1d3cf67725fb4737f4010ee2b5b163ca6251c50efe05c5ab0b1ff57b97ffa24c98653f5c82690d40c791047a3d5e553a0142fa2f4346cfcd1c849a9647885c0daaac9efe222 +TAG: 5b85501a476217f100be680b2f5882cb + +KEY: a26c0e3864a7dd3b589d17a74a7c9c1f7e8f9adb4aafa0e75c083d10956b6bf6 +NONCE: b54a2a43ca3f84aef3824375 +IN: 6fd4ec60613646490791d82de30ded1a12e61fd270f1642d2221272dbb150ef63ef2604213e203b740dfc9c4bcdf722b3c85aa20abb1197949de710d7e8311956c8649524afc72a9bf5eddf0b284c7fc6d48a741b82c215a0dcd73bb8afd08d5532a6f7f99b5c6beb2ad793d6da53a81e6523b2240729924ddac996a723421f57125f928990daa7a55a5b6b53d7361d9728f66590d969659aacd9aa5c0ec627d991b55e9fd0bf9c3210f +AD: d6d8b570eca29a48a4d408d5b27ec6aec291d70cfefcd02bbfe8d8ba8aeb6db770bfd723d2c3a4859f1992767d24e7b33e3e241874292af640e2bd22a5b77e0e9e1e0d5e485041cac41d4694ac929ae1fbc08e7591e1cef689028f5db26f95fc9e0868887fb9c635579fc6335757697f63b4f2b46664ae338eafdd827988c8f2ebad80ea9787871ed8d6b302d5dbf7e8019f2e139c59036cb5964a3701ec049b839e19e33e68b83539c8 +CT: 2420e09adb24098038b2750c946551a5f6a5bdf23b126947348ddb5e938b3fcb874b33fbac6407095e05ce62df999e7234cd2b4e413009c71d855b23993cd58c1e26ba0deed891dc88f099fdf852cec0aab45f488a90edd8feb6f4c837036945bd304edbf7a2737921a2f8c1b00a1daaf9e25b908a65a8f69963fc767bc975b5b7bcc215ce37009009dc90b5c7edb1a1174a10ad28f4c1d1a2241e7ffc215edef4f847ceedf7b64f2d15 +TAG: 20521b35310385ae66557740b435d204 + +KEY: 53ef3dc7a10e435650dd20550cf3ec2b997afc8d9e79cca8f7062622afac3496 +NONCE: 257a205ed0f84016183f4613 +IN: 081e2769935f945419aa06fb5fa7d8412efd1f9b52a45863808022850836c1974d53d2b2c5c0cd420711a71e6d1a09e984366b8b677e6c61bbce8f3adf9f5a9fb5860887617a08c923171d681c4fbc6d569690f6a183d42b52a80ef0693862efd22bf83b7b4014a7008424c356b5022df1842309b3a4a2caee0fd3f4d3fc52a17d53959daccf8e0ca889578ee2905dd8c17d52e76712dc104344148e8184c82af8165ea8386f91de585b54fc8535c3 +AD: 5b73ae02bf4a70e57f5d48fbf45f85b8496ae8514c8aeb779c184f9cf823d8c1883c9e5a42b2c099d959c2298ace2d86c4479059256d6a4325e109fa4b6c4ce90f84a8228316e80aa86de9b5e111d88b2be447a29297b35ca90a8eb280d4c0fe92a1d593cb966cb0010bc06831efb0c72c1e222b031e900ef06ab8da542a5abe2870a0efbe92351d5915ab545b14900e41a27c5ca9d75d6277afafe7ae861131c2767eb314c0c3da5c264f8f2b4ac7 +CT: 20ecb6cda861b660656d692c626436227bd4ac17a9bc71f6c84a1917ef3b5a0f6ba370f00fa2e7f1bd5aa8d6c15032572090482c23e4ab7376ef1f4dfb77f79d5dc065792fe3476c9c37614e32f493e461981b519dd7d10234c2c69264ffe5be06a8e14c81022b652c8cfa24adcc7c7536a55a2fc41e9ffcd09e1c483541cba814eafd5e09e9e44477018a41b073e387c9257c07d97e40f0761fe295d015e1f2df5be65b13f34b6ef0fe1b109ad109 +TAG: c129ba4c10bc9e9c2b7d67f5f249d971 + +KEY: 15ddf0d794b1bf2e67db1af47b45b8abb0c62ff5fe09b29659f63ff943815c39 +NONCE: a6e6b4fd129bee3ab8144da1 +IN: 9c82ac83e3dd227d0cb9692703dbf41292fbaf4961e28b7407ef069e33850371ce2838b1808ec1f837511dae9899a867959183ef3d988ac20758d7a1a6859cedf687d8a42f3dd53fa4b5843e5be61422fb8774c9eb0fd22cbda5950155caa0ceaa00417f1e89a863fcc08cbf911776fbea8d7c14a6d819c070c9abe76a7f0d04598188d07fcbb822758081172e654c025703bb24c523cee2dfdc31c8d2c84534a60e7efa9f52f7e74e19c859889f9bd024f28763 +AD: 892bc04375e9ad5ad2b5c117d1aacc202a74ee4cd4125019f38ed4d716ce361b8b50463ec3255a00670f5f95d361e79349e90bfccbf084586cb5fa145b9eece8a10187c13055ba0d17c0fa526ba7985f00f3eb4a2cd53b6da488827fa8481cf47f6be58771d1e40125652732a7dd5adc49cf99ed6b085fa9fe8721c86f7241b6efb6002e65ae5f72e16ce6a09ce81365485b20f1fc2e092216024b1acd0bb4c2b4ffe28d62a9a813fcc389774688eedd76c0b041 +CT: e30465518e7dab44b9ca4ab6c86fd7b701e334b050a7889fefd08aa12c9e381acc7875ad5f8574fa44f8550bfc820b6d9a5600cfb82d1f98721a875610a91c8f47960ea64445c0e22fd3ebe94b3564e98b9b00a68e9bd941eef5382a67782c5e24ac44b928fc986c62a02fc702b145843b1c6882188dcbbb6f6b51ce1aa7784da03cbdc3efb1a01c1cfd7e90dc3332fc6e912a6a967ef1f239cfdc9752e235dfe75dab8088f8cc207a4a28994f122859aeb52d01 +TAG: 62e7455cd6b95319efa3ae0d14b88452 + +KEY: dc0cff51030582f29676482ec8dbf0490a135a4cf3e444edfb7d1ec733cdf7b9 +NONCE: 58c892d618ceb6027afbabb9 +IN: d6c4d49a9431d51bfda5bd4b07997690748fdc3df196d27d219a62480dfcb6300c5a234d675aec1239280446cc134bd4e0e0b5ebf6f10bb11b788caf949c0c3553497b62e729f08700b66c6720c35f1f434f16b15a4e404d627fd054ae1394a77d5ba728f3422aad5d99a608c2aa52b058946a76a408c5dfb210d280629ac999e86ab1f9da8f2b7b79ec07cb666105582564974180ace98c63bdb962e4580692abe58929d29f066d2f7e25c23a3824483d9e49cb6f5fc4a1b0 +AD: ee3bc8d875a4d43c278cfeefed8ced8a3da946adaef93dc356001da151010548990fe08b62edda46634db320601c7f4b50956e29868bda9ae5df186f15c3ab4a19d7cec274209cecc71602e45c37c273b7e4b2a168de5c29278042a3dd1fbea0998d7d9707d412f476ac8de7936e2e5c268a2f22646f682e664e526f88004e7c461bd42337dd21b1cb39ff678974adb67c2ea1b7055ca98697ec16c4b3bfa95b4dcbd7fb015480135634c34acb20f58549f7e7e11e20a991a1 +CT: 54eedf8ca21f31d21067af5a05dc3cb99c3dc046540d2cd1664abb32fc7714ac057d039cebdeb124e1ca9511bc71f92ddfd4c6bd3edc8a1934f2fa2511503944f2a0818e30b9bdd26bd3c51b9673f55ad3f2ee5e41de114ccc55abcdce06a5bcf63a5bd61fe71dbbfc97e1c7f3417fcb9c1462e244ad91725081c9176a0b91d3485400d273a16eecd870ec1e9e016a7f4af2fab39a0bc93576ffd1eeef9cc15b7e47feaef85b21de422666ec722cbaef26edd1941e7dc03f72 +TAG: 1cc8c395b2ccae3a685183667ee7bd34 + +KEY: 90da49f8f64e8a585697a43644a48bcbef33a8ed23c1a93c65e59a217c04a1e0 +NONCE: 0812f87792508dee6868d454 +IN: 26dac57d9f30bae5831f98ed074cbc9af9731a52b2322cdd23f1f0abbf78092c48d6d24a43c7d49edb3fa66086030f37dd9dc67847714437b11577d2bec645b3210baa8f7a540cbfc20deec5973b7489b7607eafe72e249df5d0fed95e29f03cf7f0c7a22fb2f06a0bc75214446b06d25a45ab8087270eec56af3960f53b80412a4ea7b45e54a2c374e8a3789e8eb57e656e22107503920313ee3e4025836b9e1a98541446c23bd5674cb83483642f2f3e8270bd1f77c85bcfb205a9133c +AD: f2168cef97c27a902d93cbca07b03f35c5c3ed934192d29a743c3a6c480c5a62172c088fc89cb2d8651b8979e5bd1864272ff179be8003c6dee18789c17583dc1de4e8b4fec80e5c7575838e621cac4b5b51ce5952f22e06b1c196101d2ac8d05e797323e5baacc49d1e74db97142e1bed723d46ab858d59fd36d5d08eaa63f696b610eebdc9662e504992fd3481de1264bcac8ac426b09fbc641ebc93f72c5d460088fe0b08420d88fae219b6a5a67420a5f9d1201bf8d64b2ab3e9050a +CT: 82196d89624689bb172e4ff71619046a91149c8ea99ebbaa3f2c32c77938b5ac466481575dd82a008c7f5867bc46ee44faf95fa40b6237c8c3b62474af2efcf07c771e23a63e65b48b0bd8ed26fc64dffe03e71fac6d3857b1248df63d888567d7d3618c68d6b8f1c88029bd7af8677d3b51f70ccccb4eec9e100768515637ad8a4b2e2e317902e456974ce9fe23095cc68566e85cd913e8b64119444f124640d16ef3e98136f32d618eef78f7ffbafb64227b3185bda8f541c0e7ee8405 +TAG: 71fffdbd6358f755dd22f1dbe42c4aca + +KEY: 0b1b256665284390a9193b7b7aa4e3ad15a3d2a58e79d75da8ec284c02fa3a2f +NONCE: 346ae65660de8920605fe8d1 +IN: acfa83f56f137ac39d6447d98c5f7d5e812d1d8e7c7fa7f7beea9a87c59961449683fcf5332c9ef1587135030309a1c2d95257114b790b18cc32f65f4c7d1652c0106e3331f826e9b8b0dffc50aa6723d0827076b71c668370ddc8156db3831559a72e48266b3886a6d88318e6ca646ff561ed4f71e665abb7a60089f0a115c7b7fad9cbba6c4cb0c242b9e1f17705825d98f4bc10bacd8ab2e11cf579f29b2a0b085d8c96a372434785856b483c3fc9ae909029b0c931098d7e59f233cb6450fe0b0d +AD: 64347fc132379d39cf142ca81d7e49c010f54f354ca3365d5195a7e43175c9a47603062c5ca61aaf2b381f5cd538bbf48f50d620ff2b5980c086049a378aca69570ab7c406b510a6aa6b7e8682ade6a091b1f822a97ce671fcf7c911c43c4795b78ce1c86e990e32bc5c9fa34a8a4b22a20d6f7c46722d1bafd49443b4da9634db4615f7cabc3d5bd9a8921e67de45dac261f54bcd0af2b2f845e255a16f2d2f1ffe26e88238f5dbdbe111393aab3409e08dee8b9bc85c51b385c191ee9290454236ab +CT: 9d7421330f0c2a525495bc360cd5c2273531d050d461336a254c9af8611d07c3559931cd6804fbdc6e6c9c997283cf40bc23596efd1bf116fffcc6620e45d1c738569af012a7ed0d575ace3c12662f88f3ee480af30ee015ae70db112bf4a185e220660a912f9ad840346e7cc0715e853dcd9b415ca9e865d5e4de2321e6a1b7cd8a35c760abd3f099d395576a91503147bdd51cb4bd1452c4043b42dd526de6f61bcbe819cfa3c122c6f62e0d4c38b443f5a138325a5f0ff8a9a2071c2773ce62edda +TAG: 2af508d74bcf8157ae9c55b28b5d2db9 + +KEY: c055bfc7828d9fe8fa8d9851d33f3e4888e0f7e286e1eed455e14832369f26fa +NONCE: 2804e5ec079eada8bb3946e4 +IN: a26a9b189ada0ccafab92a79711360c7c396374c6170de395bd8ed80dc5db96ef1534adc4dcd419fdf1801add1444a195367213e374eb1ab093f1f54cd82eaba5c1cde6b867e0d8fff99cdab4d96e69aee0c58a64120ce0cfd923f15cdf65076a12e06e53ab37463096d9ccb11ec654e401c24309fda7afa45ee26e5e4b8adc8febbddaff1e7cecacad1d825a6b16a115287b4b3c9f8a29b30fa6236ca6e883abda412177af38b93e0e64b012d33d7bf52ed18c4219bdf07f36151b7ea4c53091ddfe58b6c9beeca +AD: a184e4811d5565849a08d0b312f009143ac954d426ca8d563ad47550688c82dbddc1edbdea672f3a94a3c145676de66085ded7bcf356c5b7e798f5ab3bb3a11bd63c485fbcded50c3b31f914d020840cbc936c24e0b3245fead8c2f0f3e10b165d5f9c3f6be8f8d9e99b97efda5c6722051d5b81a343a7d107e30d9319c94dbc7c31c23b06a4ae948f276d0eabd050394c05781712b879317ac03eb7752462f048bcd0dccb5440f6740ad0a3a4c742c3da32a49dfda82ed1b66380a8cfd09dda73178ffa49236d20 +CT: 58dca29b5008f74bf132947df768dc85e2492a381429f151a3bad3132e63a4a977aa09f10879d206f43f27a26909495d0a2c8cb252fbcb3abd953f6e0ef0f6d5e89d89a1d9ecdb0e44686fbf5567a6fe7557a084a8a5ef5316890917bc432164266a331118c828fad4f5d1776645d163dc5444c2e12def608efb47adeb8f9928a5ffd3c46f963a749c310688e78525e34a510f529472a14bc7a5b65594338f6f5ea1d95bb5bddc6e8e1d1a449d126442accd162e4e03c10824fd48b32df763de5d7700dafc54206b +TAG: 141c80e1d044e1e9cf1c217bd881589c + +KEY: a54a347a7a388c2e0661d4ae1b5743d1c2f9116c0a7aa2d6c778a21e2bf691a9 +NONCE: bd3456b0dd0e971451627522 +IN: 3d17e3d9b5020d51295f7bd72e524027e763b94e045755af4b3cc4f86bce632a1286f71734e051dbcac95780b9817b5f1b272c419e6bc00d90c27496ac5ab8a65d63c2ea16eeeebe4b06457e66beeed20fc8d23a9b844ba2cc3eb3d87e16e1230fdb6a9134bad3e42eadccd49baed5e03e055f389a488d939c276982e4bc77f0a1c738fcdee222e2641b06fe12ed63ede2ab2fee3c54d7901d0911c32980b7c663a67d35ece23136c77f8e4536464225ab427d937e7a4260460d55bb5fdd7ea2f105604c4b0cf129dec49b81b1 +AD: c12d1ffb08acf27d51e63f5c0e311180b687438e825204074d4456d70b7c5ba9903ad0b0778a5fe36c3e12e82718c00f5d1ce585e5c73b23d6c5e41ac4a180c97c9418b07ccccbfc58c678e97882ea36395c0a05572b4cd25ddb3c32fa580c89c48a0e3066b8032e3823893a5721a4fd1e59c7d012a01b9e9afc12f3bea93e9d1a2cf5cab26e064576b36bb65606de62fe2887ace0cf399dec08da618954ce55362c8a2bcf31457a1804bbfff68a76d752f9aea81be8868bbca8f1af3375f7137941a1924b8a2b178f06a9e33f +CT: 938f8f596e17eae6920410f602c805ad9715833087e1d543eb20b1b313771266dc6a8f86f2ba033609fadec92ac38c1f1f0f728e568fe8bcecbae2ade7b9c4128fb3133c8b4107ad5c29cacbd5937f66905e18cc52d9239c14e4c8edbb2db89b26f5f4a9ff0f2045192fd212af6c65e448834580deb8787b612d6345466483dbec00b03fee4751f543a6155f2dbb745c1094e9721aea3e544a894e4a19a14645725cb8fdc21d259e086b1e411fb1bdb11293d0224ada25da2896dfe0d35095230af6894404d27d901540b0ec35 +TAG: c55c870a5eac5c0c774dd10dbadd3fec + +KEY: b262f6a609c4ad6da3710d58530b634fd7bed875956d426bf4b2412209902233 +NONCE: 0b455031d28e4e17a45b7a60 +IN: 9cff6ec8832bd0e62d9063e43821db6a1e0f3ae7947ab4d029643b0e7db8224f8bd00a2c011b246a4d5eccf9801fb314aeadc0532fa71cffe188e801d7c045e81b9dfc5cf6ae1e310b363adec4e7ca52fa754ece2540545a5161eaf9ed5748070b6e232125fa8e0fb7548fd3eed57a6be72ce0a9112f166776816a0a4ccf8151b6b93780875d03ea3d59ac57e7904c83b90b7666de85f055b25f9e342af4cb04b0c3f123ea0906c04f252f2b16b28d612e37b2a7b788d66beb8b361385efb73a825ccfb1a5ca55d60afde0349e5dad8096c7 +AD: fb99bc661b51464c0df92ba4f64c4c56d601622287bb1bf8e0a082ed3793e74db6a2f5a546391ef55dc45fd2f24878834bdc2903054d9d02ac05bd5ff122b65555d7ab1664cc36b630039e4432315445f303837e57149fdf6bf8d6856ba97abc5a18b6cd2f8f28cd3ac079355b314561c50126812861c39180fd94f9aa24edbec37bead760093d32b96ce30e389f63b2b271fc051b42952b3f5cf3950def581f7cbb2b4aa5b151a16ed3773166761232c106d3ff57851895640ea12befd69daadecc4122b4a481e85088edb093e02d5d3d8a +CT: 5341e8c7e67303d5374e3f5693c28dd9f9a5c9368efaaf82d900b4a4ab44337f7d53364544bbd822020d79443e2ab0fd2381bc73750203caa3d28858a8f9a6dba57a7c5248361ebb152a81a89c00b1bf49de9e2d08c0243b38eefe316ef89164b4907515f340468291e0b51009c9d80cf5a998d9cd8fce41d0c7405fc2d1854aae873f0e24cfad253ee07d9f4cd27080ee8ec85d787459080a06d290e6e721d23738470835f173ed815f1a15f293ffe95ad973210486372e19a9cc737c73928572cbc03f64201d1b6fd23ebb7b49d12f2eef +TAG: 5e0ac1993ceccc89d44cfa37bb319d1c + +KEY: 9b4387e01c03d2e039a44ca2991aa8557dea6179d19259d819d70ab2d5179eb0 +NONCE: 852124b4e04d7d1d63743d74 +IN: 92c6f01cd2cd959495bd8aca704f948060bee01ca61c46005b4db43e2e7655af4c0d96656cd75d904325ecc325f5fc9a5fff3eeafde6f81323b0e3b64269028cb64c9fbe866b400e76487f1759d6ab8fc66589e23df0c008974e1613bb4ec556bd1a6a0751f6dbbbaeff219874c57dffca59a955e0aae62e8fd6a904a50fa7eaacccc6dfd4a2b8c6c040505d3448ed2217b7024224bbc4335c63b2ae8172d7d3088b819edbaa17991a4729bcd5a456cad20ba20dbee99ae56f8ef669dff93c99a995c8f5dcb5d113db4178a49516206a1cba7d872682b1 +AD: 92a1d2574182f850e37aa62338b19f403fe99dbc7ddbe1e6524ac67c4092cfe296b5ee9b94eddb5c228c902c18ec1ec26e1ef0263d05c5caf1c71ed9e5ff987e9964b46f27be05a83e20867f1f2107db26b6bc7066af2b0efdcad2b65f2ebe8b31fbe2f3c30171f2e4969f1650c9642ae47c8db5bda47e57e8a9af210a6fd4894dcc2934b4ecf823cc841cdb3c93ecc779b455b8cc796d7d60437da201c3f848dcd5f45e88973e06364e7cd01afd2d49fd3032550f1c1a60c4ba48137398f4d58e5fd0093c06042b103ce0064f2cd1cfdd39b7440121d7 +CT: 28b87d324854d5c9c6ebb303fb802b12d946ed681ed5b3384dce2cd782bfbd022f213f193bcac579176440bbf2af378b019d21dde5d70e42d257722d15417a9fecc8e56430551ea3bee798a01faf74d0fb09be6dd0c14cd03feaae29c7d17581e1fda0b4bce632ef790202e98c8c4f8f842fb3e33b3fa5e8700c8644ed6d64280652bc2a5d40b3ee0e47dd5a9f3535e15b1fabb30264515afd4f9b1caa5c224574636935baebf6d1992bf1a7a3d698d457db4248a2b38a803837ac4fab7998722d52de61bfab4f98e1933a77046bfb3941bb7988acebce +TAG: 1b07d58be48b81f7007e5683b399dc28 + +KEY: 9d36155d429b90b5ff22ded128c9f0cfe77ed514d410998091bfca4dce7e3c88 +NONCE: a7b73ba1b2b0e846c3f635aa +IN: 2510210b420b12300d51ee4a7ad233c9c97d71672c0f9a7b9041d32172fdf3a6ce274aca77a0db6961d7921d1681ede2c1088a7618382481296778e7f56d2c0074c7c545ccda313495ae2a6dfd042474b07d2b59c79a0cd8c3dc16132beff1687111a48ee3d291ac556987e73c5a3807923c2deb3b9a59a135a8fa0d85d5b39016edfe0649dc13be672a639db58839d3362eaeca046767fa1182ef8a63abc104e7cdc8610b1e956aac89af76b40844a358fe6f7343d217e1838aad19587ab4b1c765d2cd7bf7018e338c0207d4c9dabdb1625af0c75749e9a20a0d8d +AD: 39e96c8d824bee306189a3bc8a8d4862df55e8016726222a528d76de169746a363e82e82e359b774d061a6e98e3c35aca8ba802a5956a2c512501fed44ae341cfa65ec9d95485763d99cbd9aea078ce551f7f82272bf54dfb6420ae7653f275ef145b2c87720c9ccfa56bd286c61cb822d0473dc2cc3fa22d50fd16bc0358e7c615aa1791b990f30b1d737f798219f4446d173e80fa62380dfdfebdb36b1284a62c2b6638f28fc370034812d09b57d27e5b7d589075bbab42fcd6a91fa2714538be6286e4c7b2657b80f045df7f8954738efa7d49a38e5a55a2af934 +CT: 8cb991b10218bfefa522e2f808dc973620ea391623947cb260b852efd28939ccca4c8b1f02d66fd6d0d7058854fac028fa0f23e8de801ed9a4361bf7e5a23e6a7086624a64a29815bedd5e5ebe4d9f9386d47e1408286971654b38ff8e5dd1fef7686d7614ef01900ad33bf97896b4ad02e7445782b1794b45af967ca3ba72a2e5cd5252a9ff0ff550ee56fdd8aa555bbb0bf8a5dd534fd65b13235fa6650761dfe2a28b2757077a2680ef88c84eaada743d1f0d25de38fdd1974ffc07dbb9c7fa67cacca309a10753c6e2561c4784470f5c7e116e12070fb3d87131 +TAG: 665fe87506f8df07d173fedcc401d18b + +KEY: bd187500219308edd6ac7340d72813ee20054d6d4b1bc2ebcde466046e96a255 +NONCE: aab93d3181e7a04cedf17031 +IN: 55b824816e045702526f8b5def71a0d023a2e42257fc1e06f9a8531ef9f7717474ba4f469e442b471d5da6e71aa635a307205c0a935a54b8a59be8856144dec435e29aa1a3568073aa6bd3439bc0f219fa1179ba0a316f7d966ea379da16be4db2f1fdac2fa6d00bef9351b78bb2773bc30ddc9d019e6e7d78dfaf38010080027afac33e751c0429ef6c70a1f2d01f103482818e9353e39a3a4b785a7dd2c7e1ba7a4c36a5f3836d5465c002bcd1ac576d90ad276952ac155dabba6873e6d92b5278280a540071b205ba99b77b7568862e70e6ddbd804906c33fa130f8b0862001 +AD: 11b35743bbcd0113d2c188f75d382df44e874a2d4b3c3148ecf8e0406479305f29197a3a71dc7bcd71b6136ab11a7cf46de80140e15046acfa18774cbcc755e9f3beb37202fc308c03b1c20470b3128f5b91d925bd6703dfb3277d65159688f656d5ccd83d2beadfd778854472b1cb8fe440bdb7efe806f4cb95249cddf69fa0013dc5a626eb8ab69a48b3ddb1a317b35f7772f711221cee1cee9469e2639c44448c5942c95324dc2fcfdc952e05aa336ddbaf57cec2d1b33981ecb8f70ccd34a279b211c50a7784906f2981a2d2ad8fb130100c4f6bdb09c95dfcf4b0eb7ac6d5 +CT: 1e99d06f82333ec8e4fa1e81014458c81325e5d69db561449b153727da35c0b540c570b60488aca6aae58f75f84792388d0160dc45e4e5bef552c49228d806fcc22259f0f94da2f786cc94a3ecf3cc15ac67719379d86abaa54ce41e868110ed2b56dbeeaad4a444eab51a96aed404a4f4b9677d22345fdb67ed0df091d23d8acd70bf6cd29f19c99910888b3281b65637590af984e493ac70011486ca88e72fd14ef1cba06a50070f138dfaed35ab12690a14b1c8ac319f597bb690cae28019d64c868acf9a58fde1d8aa18dc1ec9c3c4a0ee9c4cfff8912b1bf23c805af6df48 +TAG: 1a43147e6e097a46b61f8b05c7dbbe1b + +KEY: ce53e967bb4675a51652a9e6e87da6be36d16245c1e37ee00bae09cc30ed8528 +NONCE: 0f53ed18bfdd28918c3993d9 +IN: 3f2416477ff2ce7da3e5766f043e7a06ea2b87fdf06320d296c71cbaec4b115da356f8c7f34220f91e90c97a5cbbb7fcf0048fb89414eddeb2ec1062d08cc75a39a1f9f214fc3efd6fc8e70d78418007d7d28944b3f37fa5667ff79098d7af36a9324419b53efa76e98a311e1436ecedd977397cd02cc8d377ea8558edca35ff4c71ec31943119b76af4c78a435033eafe73c7079224bf2328b49ed58acef9b043ae3c7ff17a66b521e190d6ca2b2835ed8edc2c173f04616af237391a4440fc5306366c834f6a504e902dca6d3e9e1554088eaf5b15db7fc1fa19f0867ece90ded639ee8072 +AD: 64a596ffca0889833fcb537f58d94791f9ba9b6b7ce0c7f144f2f1a95d62ce334f7bf7f0d2ef0c6e7afa2324b069dc6a7a522f19a001c335cc0252ac4a26079c3f267cdca1e3f933069f52fe72e1a00c83d8fcbd2e76149a912c7b37663c2e7967a3a80656c87094d349af6b9d64b3873f467ed376eaa1e0abae06180c847e981c6a12d32b580acd34f779c343f8b79df1b5004d333a5c37a8be7a94c6f6400f819ffbe6d54d3c1a92824fb15c279fc8121c735b6c42248ee22e665245966d40eadc51f12904cd64110d69354cc9d9fc415b3469317d5e4643942dd4b649de0ee2fc5d200701 +CT: be462da8cc9d8cdf343f7025df0b8b41c24f7b6060cea2d3c63338b6c3e83f0797e966b8c5dd889bf1b5058fb4d694be2178fb33d9be1a351812046a6d3bd36c84ee3665d39fb98159e4d30f8a25a60064caf980f744fc519e2dc451f5fbcc0834b72920d32f0492abedc1022b0db4f2f44b91ec48c588334775fac91f174a4714b3825e96fa53cad3de94807f3b888950c8776189cc18fdf379cdc9d6054952c6ed2b3fb7f6b49beebacee7ddcb19a3eaee2b2e2b7a5d6476e5fc1f216ca443b859a9a661dcf2f7709f87361186368a62f255d78150f09ad4ab1a20e7329f3d96fa2a33cbf6 +TAG: 1cf74908f6fbfa5b2b309ebeff2f3ad1 + +KEY: 093d932ed969cfae63f07e0c04c7f9eaf1b36f656095f8d5f112517dfc430cdc +NONCE: ce36a837ae93a280d2fffc63 +IN: d9da99635f8d728843dd587cbb24e68e1df2f81b5f7abfe233a224cdbd48cd8b82da3711d2ab6c1ca722610b87f426a2cdee4456b50781e3b25da037ca636f2a5eea01f4eeea52d0feb7f1f6c2594d63d8c05c2adf339839449cb1d2aca94852d1b64b5641a572c2da02ebe299c7d1ff4da8706f44b14602f44c0ced711fc78005f87b1686106250d3d3860b67f5b38788db1891150f88d4c5276751afa0b2e37a59587cd8b718767455e65eef25bddaf787d52b88556710f740f117b02f244edd47cf0e45646d40e789671ae61ab06336e24fad8b64cd8f60b427ea1f58af443c6f55d54028edd5f40d78 +AD: 5e9c95c3449cee3f9f726be031089b2358ee92fe7b408b355739c8da6369304f3b287ca60dde4685bdc59879e1530ffd8f6589449196abf0f0dc6dcd82ba7fba481f13376cf29b32af2ecca24a161e6e57b6db70a7e02ee2154cc0bb5280b08f8dca35b1a342fa18b8025c7a805cebaed99e30b43c139de7c37adc25b0b6b5d873ed86530622ef2d0ed3ab19e9c27df98a4a15324f902c35a23adcad4598c6e990c64893355be15fa7320c1935b4ad3c069c068d6b3c8f43d6fe0588b59170bf567ac3a53a50db68e4be17964f55acfe695638cb5fdea5c40805334a385c2d35aa836637ccdf71390487d9 +CT: 40380718f069f44c88932af22a10f80513821caa71fd7a9e5c4f37e1c756c43fe491ac13f244bd1299844cc78d7812110f570b693e63614e639ec7395cf65c206eb6fc9bba86f89d03dd19e45d5ec64c7d3a308ced4ac1f59cf4e13be64e49acd9ebee209afc508c97ac817f1367629af9d59b0cd48f138d23abb61f92dac530351f46a4e7f70ac87388e44f6e9548d3e6a26884bb7611f632da7db2a12fd9174773e685df316ea9401d8b352135b6b32a374eef8661b77eeedc34fa4178d0a5731ac9bfc14bce1dfe96af095b0088371ab1a04b2062625f0c4fdf01fc0a6bbf1661cca11932e93690501a +TAG: ef7f960b146747ba4f25c705d942f8c7 + +KEY: 86875efa72ec1827f133a8935193292463ecef801bf3b461c96b0312cfcf32e1 +NONCE: 738136465c8935d77c8d4ea4 +IN: d692d3ef47a5c9d0d9a3b6a0d498e90a3ea06278134ce90cc1d69da2159d9a1f5d0a9ef4b4ce5f873e26e8f9d53ced79991491325ba5511be4d9e6563b70459b10e60d8c5da45d3b0b34dad86772b0560314f0215bef7b55c6ae53999cb2d6a14a35b50fe5a1598adb7ebeee097968ee7624bde42862824900c8cb45b12785d9c4d50ef38133d31a66a612d8638008d03edd19c4d7edb5f9b9f195c60883a7d6aa85bc3ca3b59c395b85dbe9bb30ef6896c4ebae8d72cbecfadfa451bf36631aefddd3feb36978aa8d9a45c9fa09bfa0b2c040d9a422840e68f4dcc3eb902f6be1d91b11e1749183d89715761b6cf22c +AD: 17208cfe5a96adf0ec903c7618d994492d3eb77275fe5bfce5ab1f67d27431c7746314e52934b8c44481e5760cc8f6b0e17d1fcac7fd5b476196e3152c3dc90adeb58c2c9c62cd684b4b18d4a94f8e5b4336ed3f1758b58a254f48b3aecd9cfa63cf758f2df54c52eb246d046198b6eabc90b2a0dd6c5323e915a117235174fc9089cc9bcb1a3bb49080cbcc24367e7f4e17e27a2054bdda0ad8996df1cfc6bcf43f70cd854f4d97aaa4badb5826dd86765d36a2ecc83d3daaf31594eff02999a423185356d693f26025a576037336c156543353423dd3b5da75f45e297c60dd8e091b961f60eb6786fc988f6324f9e8 +CT: 55f48dc2b6836b8603e19264382ddfc568b1bf06e678de255d355fd865ef03339f644312c4372494386589431d4ae7af2eaee5dd3c16340ecae3e87dda9220a5f9b9fe6cc3eaa226d9608385b7e8a6216e7da71997088eaf7c67b5402be01c0b182383ed3c0e72e91fc51fc99c59cc8271660dd7a59ee0e7d9626ccd4439bb9a1499c71492807f8126891ce09451d07d9c5525c5f185559ec44aa31498be3fc574389cf948640dcc37d0b122249060bb7d5d7e5194d4b7a7bb64d98d82a1155e30970a854f7c0d294fbb1a9e058f3b9f4762972c21086e0bf228768d0d879a9cdb110f9e3a172feca7417d48b3fa0b0b +TAG: e588a9849c6b7556b2f9068d5f9ead57 + +KEY: e9467b3a75dde39b0dd44e7cbf2b70ba1757ba6a2f70cc233d5258e321d5b3ad +NONCE: a9756c7b8e2e2f4e0459f1bb +IN: d6d7f6112947be12e7ec8d27ce02924503f548456d0ba407bf23e848b9ecc310e4a0c7b00c0de141777a94cb4b84a5cc34b2b05c8a37cda08b6c2dba80e80853f2a18bcc41341a719f84262b601610a93721f638a8ca651a2f6c03c3cf1070f32b92c4ab7a4982a8f5e8ae70800f7513405f3ae28ba97a9ce8241608eeb5351e6cef5560c4209790ee528b3876896846e013a0bd3a1aa89edaefe08fb4b73b3fa64c0c8b0f7ab70653ee138456319230174f0f1f7f3477f0cfc80eab8a96e29e85e20658cebb830ba216b1d8281ce499f729278dcfeb59cde3a043ef3fe2c42705f311a422e9f80fc3b58ca849dd4b99e5e66a958c +AD: ccab7afe4d320e94f77963d779ade1343e66ae80446eaa5f9ec4d3e3bb3166255e4aac5707ab407b284dfcdbb18ff515cf08790f0470cf335946040438c7de2d2a342096d7607e1920d86b519e96cec1715f4b0dfe375c5959644bd664d23d879b825dffbbdc458ea9da5ede5682ce1ad1cff33dd8820761b1c067cec638873a3cae79c7682ee8d4f97cb96a413dbbded1c242ca669d50ebb6de3c27eca3041fa8aee8974c3d17b0cf79c32c7bbfe20dcfd57303cc40334fbdc43e925df1d63fde57bf60553d7790fc56bd95e675db934dabb1125eb97cded95f397b32bfb3a2d40703e3f11c6c226633b3cb7f9da1e3367de2ba4d +CT: 47bb258ddc0945079a0b99ed5cdc0186f453f8e0393cfea258412e423dde4a00c014ac298c4dfe7c03b0d9bbd4ad189624cb6fbaf13e60ec2b4d83c5bc3294dfec30bd6c8f7125e11d7be145a966dfd78fd77af68099b855989fe077cd9f427d4381b4930abc1daae55722540e4bcbe1b560fde208ef1c2dfcaa2c51b76072e67da311c2556eaa2c25413bfc43d00dd84aa8859b296e05945683e028699d60a29227de1363c4138b9ec2db8f3b502fe09d368c5f2ffd81abe50cc1ec1ef216f27f401456d061429d1910623af00bcf500cbc6509c5aebf7de9c956e40a3f0b0d562775b03c282c204e33c0b380ce1475eb5c0441f6 +TAG: 9ea19333f5050354a7937fed68e38dd4 + +KEY: 4e323dedb68bb5cc4cf2edfe3a54a19b410f849492ed6f66fc053d8903c3d766 +NONCE: f77b876eff796db621eabe88 +IN: a7514c4111d7d8bce2d56faee25d9f5fbb527162576b444fadebf42d48d2631cfed344b0437ce8a7609bf30bf0a44aef172f8b12ea7567cfa5dccbd08bb3115efec59437ff02e7128df9d9e5193794373e30dff7b3d8ec0fcd6cd3872d755c0314f1cd9cb996e4c6ca8ee2e35f9b64a1f0bd1669369f9b333a356ba58e553ff9bf9cb6c5522599dccca2f7f57a91006e7dca4095d11955e5aabff69febb98a408aee92293c0abc12ff23482ebe9d541bf8fc7493eef2c68044dd185eb243b54a2bad9844d831d9b0766a0ef013ad3ac03627b1feeb287e5e61875bb1d0a01315761bae6323a9d678cdcd3c4a85be71b70213d081b348c63fc603 +AD: 9bd10dc97ab5e9b35e1c8c36ef37f90a11bae7dd18af436fa8b283eafe04a5bbb16bede6ce1260187299ae6474628e706cc08b3627f5243f1a9ab469455666e6d5f2ab597b6799bd60a365a9248341decc36d473fa52ac5ac469b965cb2023d43b437dded84ad49de95a6dfc6ae4bbefaf86f9b06e3a33ec90d32ea3af541fd2c43387c75dbd94d44b9582e8ea41afba5e49f1d158d48e979d04888fbd42876e12bfd6695cb99640c537f2f9223d37cf6b627207b9318bd1f4c64556b5db1101c486c53dd8dccd7405e148d6d9b38b7ac875a44bd6df75edfa4da8594a9c43b223e7a6f5b81a5cb8dd6e06e9a976ef156e45520af332e4d56035 +CT: 9885d7a11004ec546955fb7a8c77ae57588fa2e7fedcc8e9000123495b9016d1a101fec1e6724302e93eb8e01bd05efbe8502eb97b1064bafa9bba5658b1677819cec4998dbf02df1f1eef51bb3e75c19f570efdda98b0b8dc5dd9250eae8396090ca9ebecdb90f32c5e2085e86b64e57464d251af62d9f8c01d7bd6cec5f9dfa5eb7c4cd412077571bd071a4eff5098883940d63b917c08bf373916cccd7a446abff0aa5c687518703c25cd8d3c5d724f348e20be54f77fd18dbf6344d1d25c788ccb5a5747d575435829b1825e31f9e94abc33c0d2750fb62ae167a7a74fc9e39db620d43e0b8514d5f70a647e53dd5764254b7785b1519474 +TAG: 936072d637b12b0b6a4141050f4024ce + +KEY: e57e74595d230e8eae078df1dbc071c66a979a912e2252257e28447e97fc82a7 +NONCE: b613d6d5fff507e917674f2f +IN: f1ecbb2a45f04ca844616528b10ffa4d2c5d522ed4ae3366888fb371b6ee7eb4be53c8204783e43265931f58f308623f7b2733384c173540aa0bdf879fad0283c2be6c42a7b4feb2b29265fffdb518ea77d33507dbbff7d9921bd97fd27f1100402e02135f7df4b5df85f7472fa75618facca3e24d487453e831efa91242e62ee9d32880bc20f7ec016eb12edb589dc8a669f7c78375f915d7c2b03457b00ac2aceaf37c0369a85c3f6fe7c0447c022d66bb5acaee62163837a36e882cfb8579ba9182d3153a25623f339758ede5a62f67b199fc8abe235fe4b607a6804fd4d15378c76e0c26c1edf1cd637b7ea59edc66cd5ef9b8cf79b95ff89c235ab195 +AD: bf4c0737e461c1d6fc45b87175fd7833625c98a03e089c4e3d47c6b21f4bf38cb4b7666322217eb8fa022afae473df56ba3502c88cf702276bf39c6fcccf01e629925a83816a5096e612458af6380dcb7f63cfc0eae99d63475616b18b44111a1927b05503c4ce46ca48321b0f8f247a54919fc844fbabd3a2481e83bed8a5ee8086d7559db00fd1d64f4892ee9363d59829ce1e10af66696c28e86297b43190800251f346bec1b577446120529d486266a271c71011528b24ff4caf2c30f9748a2b03c788dd583541368a643075a52127c48b3b6f0c6ef413e61479c9afdbeb4bda44340ff0d81c7bc0321d3de4080cf7e108dda3fd4e480e685b202c6bfc +CT: afb2aae2dce03cb0bd3467447ef6895a132cec06b9f7764ee24d90078660dc820b8384c01375e03c20a6c688a780d7d7fbe5837d477e8f3d7ab3ab865dacb0eedb5694d3276ea914a421b03b9d4e4f586227a3af7e8d5d579bd832450f038eaa7bac57aab996df55367ddf59b338e5d370e310124e8ef43c9fe54e5d23d60023aee266054ea66c9f32170ce97998b527073fd178ed4e1752cb9c515c0b32766b363c39c513c2e9ff6d1c24807afb43af3c5a317f1536087d8576fa3be3b007d3a77ab0422303cd0b142c4ad194e1bb86471b91861235dc336dfe9666f4f2c6a32a92b8fc52b99873f9792cb359476a2aea21996d21c17ab814de4a52eeeb33 +TAG: 05906cbf531931559cf2d86c383c145e + +KEY: 847eb274561fdf0c1af8b565a92da74641f17261a0ea4cf63ba5f36ba7028192 +NONCE: a379511688390ade6f0318bb +IN: 1e588cd0636f34b656b140b591a9adafb8dc68d0abb75531942e3c6ec1d29e4f67853e3d718dbe61b733490525c7f9ce6746f8639e4d271267a95f0940b3406c67ded0aaed36374b9a4bb8c753579051c6dc3244d6126a8a97d4a912569ba139d55dd00c380e7ec450d44f6c7b9482c2594b21f61ef8d165666c830867139262be5ad3a31f44a286d7e86d4e5c9bd6118147efc8e606c522ad0e9a218aea4daa39d1653157e4c3730240fff67a42e4f34186de1c13ddcb1e44020b7a31d21ba6ba96b3f42360dd1d754a7bae75b6fdb6eb3c76412cc1fd8e900d7aacf4d897f4224f19a1d44a77e06c95eda5fe76b11c6f5088e8ca75c87e07edc64c09a6a31371552449 +AD: 331d48e814f660516f3a796b08afb1312625b3b17218819cfdbbbca4c333378b57fd93482d971992b5b15b62f0724d6e7b9beb5ddffd3c70b6f8bdd3cd826663eeb91d37734a686c987efeb4d4906b80c5378fcd07806d2dbf3eb528472a110743df8cd96b6eb67e98b13ac506c9bda167f045a412c93d78e860c9b4bbd7a2d71adbd3530f30253847b4112d4b898b520c7a14fd075e62605b05084f26fd138179c2791fd6e8d3bfbb2735002ae12d986f92d7d300fd6f1dc12c993449f8522f6f32f506a677c8a981aef9815e83019713b2f9943acc8d5b3f6f65b9e2b9a14ad2e300d636166da2d35a6a0a756a76d08709a043d65341695490124971a7574cf0b5845a +CT: fc1f0d7309e6420b42d59740c9b9d4b97075b874015251ad55483068b00f87502b18182b140db07c70a80fd884fd79b7b5fef1d307ca4db0ff046494443e1cae83478d275c31402035f1fc24e26214b78d9a4dac78d074150012f9fee810a121d87a16d8e1eec5700e9facba350029788480a259d9f30df1c2b8df7691629314391719853c0b68614134f6028865700b1fc4e7f34ff28f449c6abc3027f38d7a7f6d84b8f27f7cc5afa09478c809eec346bb58244ab42a3bef61a14ae7640d76591343983de9fe5f1b985ce56c9fcfb2e3f6220779ca6f92a6b8aa726573b38ed7663ebe4c85066ae3f488ea3309593fa41dba8efd2b8f44b9fa8f7a427823c1228093a3 +TAG: f1832022e06228c36181856325d4eb68 + +KEY: 3828b138f72f8fe793d46c55ad413bab31a51e7a9093cdd10fddb4739e28e678 +NONCE: a60413c0ab529ccf3de58468 +IN: fec017c1c51da5ce9dcd8e84cdc03a43145b31edfd039c7c85d8811a2f58efe7a2d7590149a98cf0b5af82d3e0a325223bc9d5585ceb1afc4cdd96024be6c8064c2abac14f68e65de49e25e3e967500ce5b4504d00a9cbad1e86bbdcf65c01a7a92de27583b7b92122b6a4923b7192994a1edf00b75d14a982f92559dbc2d5e427a75ad29715375d90193ddbb39b9a52c1a23d75629c539e0a6ce822c7c08fc77dcd3adc357893215df4694673a16d34513de21217ce86897c8f0575d213ce0c66eb1d1985fe73dd86da3ab5e89df4243e1be9dd95af94f878995d02929ee42a062100d6d4d3884730f54593d5ff7b7ae53e03d4f0e10f6f4c3077206499ab7d4de1e825d532d0918f +AD: e2b16ff2b6c73c9374704ffb4cdfe7bad9eeee32157f2eedf427f99c2cce80c5aa4d9145e85af0cb08e6ed477cbe79ee168ded5c0895f9f4f939c21916b3dd5c9d268b3aabdefb85d953bce9b70732fc9acf6c7b727f78d8c9aaca9e022d7cf0f95583e81744227d87fa34ae19de44d202ba01e3d03993f38c9b2fb00b54dfb677d67e6f5a15f46c29eb5597ae3d5384b37bbeca3f3d825e2b7cceaaeb36a8c1273062259608956dd0c79877cc460d0268de27355e34b9d8d1188c062ac5e10a73f2d70fd0636304b3de06cffeedd246e2db19b8b66785f9f9c62b8f0198f29d37a4ab5280f4aa0320559810f89a1618844d0ad5f3a4f5a0e834ab31e56798b7158217f834d372c36f +CT: 88ea11ef6b6ee6fb0be77bcbf227e77508922550ef0d7534bf05668ae5fcab2f4defe643747716e7e000950e36c6cb24b79987389a150382c091d39ddf841b0a5e31d763d9c59753a3ef36a23b81f38e6e715357395ce715d30c14d6ab5b7454804ecf633daa39b6107f562fae6a646efb25c1119dd17955bb9e640105a21566345408f72f2acc8f2726a0be465551f9ae566da559fc0b92c36764c5ca20a18a316c02e606030a53450e7ae1146050a48a64c600d33cb84389b0bdac7ff45d3d1f2f669a6e365ef722d76d2fe9bef2df93c58bbdd6965e18111b5de0f4a62dbb874161bf8adfa61e9cdecd97b4fff668b3efeb3e32eeb929cf58d94ad8077c0a2ca79e80877c5d9329 +TAG: 9b47afc5816b7229213cd3c9135545ed + +KEY: 91ea63dc27d9d6bbc279ec6cecdce6c45ff0b247cfb8e26b6ab15f9b63b031a4 +NONCE: 80a134fac73eca30459d5964 +IN: a848e41c77ac8c733370435b5b6a9960af36031e96260d5703ce15b003606875a7901cd11e4571bf88dda29a627c0b98065a8b4e6d382852dfa4f47d86fa08e48ad8f5a98e55c305900b83200d44029f304abd21e0264115192a3fd7b0eb69b9f8ca7865b3be93f4ba5a28468fd7bbb584c32ae867f5146efbeb1412d3ac36c30cb308c327a6f207e30f561d6efe0a535446c693e14176e9e714ffb5a5b1075812909a362a6c4bbe18322e15690c2c9cf5a18e0120c11551cb7055b5aee97e7a56d7c24fdf1214641c8eacb196d74f3d96a7fbecdd4fe52dc7b6ead9041cafd5a3fdf91fd3614e63189b488d4d7c1ea3c6351d112a2223b29d390ac3ab7f09a60bbd3df6e0d606d902aa44244334 +AD: 47940a0694183b2fcb5e760c9ef6dbe4cbff6ccf33208337a981138f9d35c03f8adbd810e94636acaebef6791b531a65e99b03fc78e7eb48036615874e97cf762fa6ca5d880bb2c2f644f1aed70c667880f98834d501caa277cb8ef1095ff882e79c3a92ea8982abebf63ea9ed7e9a24d32cb81d5d98e891974e3d636a59e165984e00f05a040d33f07b39eccb924fb24780a422a6b2b7bddb5b316beddcf6fad20e4cee7d0141c2f7c4e4f759db8691dc7b8525ccbc3ee6071a2ead63e750d6d92dde7eb1303d5b1194702b6c3e0c2e6f9649e60eeddec9c1f71cf309af0672cd2ffcf94ba7e6c3d7cee020a224a9a956274d1d36ba16030e215d90a165756666eff066a8e51bf7d4babe8b7d8d +CT: b90449af99327afb1124bb24f1c8b5cb878423b0370d5f7cd297b28cc4135ee77d6f1913a221cfeee119bafa873072bfa79e303fe377bbed05add41ce3a42ca4632b98f40a36227de1a9ba84d6176c01eca9d33d954d0ebdf4e40f136e0f6a56156fbb33b344a8a433941fd6e08774bd00075aedb0e396c2bc37d1250541248dbeb899e1b5170cdfeaf7b89995b049428bb277c501354f8cd48fb58f6f04f956dfd099c48778dbdbb4c95b7c9d6797cf6d3bcd1d00e88cea885ee4a10d94356509e148990a0e10dd89103a9d5c8434a7bdbed6c0ac1271e0709eba144abf3cf075c020e9f7835d5a98fb2439b399e377ae6e19fc5f32df9ddfb9e936190d3e9c62de99835249d1f32ca3f92ecd44 +TAG: 6ccaf7c142d86b83e4d0b4289b49c4d4 + +KEY: 1344db082889367fd48c5f06bc39f9cb9e3ad4b92fa484ccf49418dd4caa2e19 +NONCE: c04a98e7e29326b5330818d4 +IN: b0e12e3122c1ebfdcadded5a45163a6208548e9bdf95cfd18ea504e5d2e97372e58dbfe460a57b724d38f3bc0ce02a54015779bcf127343474d7d4c1402d598bee56897203b903da5b819e2218bd0d1a2af11c542544f02c46969cd2bfac683b76a8de61698ccba63361a1a0b570adf69d24e9a7e466873c8c12e25e0bcead7828386179a4d65d5bbdb800eb52fc01b67498d7b5f9864270162158a8572eccf541b07833f001848672098c57708eb479855799567c318b1aa097efa70db0d8a8d36fe0ac22ebcc2870baacac690a79e07ab286acad9f7a877939cf2989cd6200eb86dfa7a41e969a3683ceacc7c97d1cd5487f13c439a9777a67770687657d38267a347a0b6d3aa3cf64e7f31017246e4369da +AD: c96db14dbc2aa0ce3ac63794f75c7e78037dac6763282edb307821a7938de4baa3d2e35a8cfe0c8724c2a8d870d0a462ea157e15aacc69a3c881d9c819225ea8be479872d55e655c897936c95b9ab340820264567495fc5e4e3354f42b84e191b470ca9f4d8fc25d011bf9c9e73e1590e1bb919dd2f288b26935fbfb8c93e54331dc8edad5e1cc4aec103c2f3320d59870c1770319f105ee790b704ed655be423e63ab040f1153f41e7070ae3a0f34d217c4649c180c84814463902d99a9396f8c7c85a3a4c8ae2f01737649fae478a40fc72303a108822775e9c421f945cc0eea992730790a9aa0c0d014518dab371b52d30b5a560f34946a9344cfb8a19b09ee9b123bcb8f642780697508f04983b790dd2d +CT: ffda075dbde7b874995230e1324f17894689baaa7f1354e26100befb546ea23dc74807818e43a3cee00ec1bbb95c82180489ae5f3a1c482dec28f96ecaf5ca4655ff7f33c814197cb1973cf02a0b720a5c44068d8ddff0789fc1e7f20ef408c1a438133fce4f7a3e8c85d95a381b94e949ce47a85895c4be7cbfad468e52a160dee34b8ddeef2ab280eaaed4990ecec790ac16de3c74aac6fe2d5e28ea2b66a921c894a3971cee4a2158054c3567e0d941f867ded5ed1d21d8ab090848fb3eddfb1559bf11815db52b8eed871cfc117980f297da79da31da32de3f162a03d95090d3329da3662df29e6ec9b236e0f7c1d7d957cfd54d5efc99c694b9dece989912388254798513d881e5943ce830729a8e2ddf +TAG: 81c55fe9aa2de0d63efe3f74a3d8096f + +KEY: 31dbefe589b661af00a6fbad426e013f30f448c763f957bbcbaf9c09764f4a95 +NONCE: 147fe99bba0f606c57242314 +IN: 908bd801b70d85085dd480e1207a4a4b7ef179dac495a9befb16afe5adf7cb6f6d734882e6e96f587d38bfc080341dc8d5428a5fe3498b9d5faa497f60646bcb1155d2342f6b26381795daeb261d4ab1415f35c6c8ac9c8e90ea34823122df25c6ddae365cc66d92fc2fe2941f60895e00233b2e5968b01e2811c8c6f7a0a229f1c301a72715bd5c35234c1be81ef7d5cc2779e146314d3783a7aa72d87a8f107654b93cb66e3648c26fc9e4a2f0378fa178c586d096092f6a80e2e03708da72d6e4d7316c2384a522459a4ad369c82d192f6f695b0d90fcc47c6f86b8bbc6f2f4ea303aa64f5ce8b8710da62482147bcc29c8238116549256a7a011fd9c78bbb8c40e278740dc156c2cc99c3591fec2918cdeb5240fb428 +AD: 5a32d7044f003b2ffefffe5896933f4d8d64909fa03e321a1bdf063099b9f89752d72e877291d8da12340c5dd570d7d42984ffab5177824fc5483b4faf488504e6822e371dca9af541c6a97312b9cbf341b4198b0902cd2985ac10a8b5b5fe9691bb29a88344f863c980e4e871a72a8b74f92eef68c176e9d2ef037898ff567298e186af52ec62eb7429a8004ac46b945678b82859396d36d388ec3d67653aec35cf1da2684bbc6c78a5f9e3ce1b355af3b207f64e0fa73501c5d48a14638d0906c87eaa876debcf1a532c1475d80ed3d4b96458d2236eb9f67988863bc6d5c16b96b93d898683d248d7bc601b5035fc365481b89465e37a8f7dd64635e19a0282639cecde72c6b1638e0aa6e56f9c00d031cdadc59ce37e +CT: aeab9db30a579ca54195e54a9e6c787f40100c6d12ceee35643f36ae45f618cc9bb66aa4c0fae0ec2686cb4101a5b23a46877460c7e020b38b0d8d1f533ecfa99df03d346bc854a578276d7d5685ad1fb03655683a64aae4159c9efa6781f053057e0811226c7c533967a94587f4025353b28cc3a2ce5763783b4c31e7818b8ad9195bc03be8f294f9f6ceac578f9d30b22b1f5a68d647d46cf6db4a9c3a8a5c06fa97c9efb4578f501ea96db1f40942e3f24c44a7e4070a6b931c39947d9692930b67767357015de51a39e46fff94b6019e4bc1ad9d216a571ba0dc88859c49d2c487ca657384e49b4d382d86a60c8d5195320909c4e82fc077a3b22bd4eccf0f067e66ec78eed642b2d16f0f304f60f1d9ba69e205c982 +TAG: 17ca09e3084504fc22e914ee28312c8e + +KEY: 0ecc44c9036961fba57c841ace4ca3c547c51d9f126567bf41626765cfcbd53b +NONCE: aa98b6ddff7e4b2041f29d70 +IN: e49a2a5713f507bfa00c140dfbefc0c43e37bcb932e0741db03f0055da61cd837b6e2d8f99115d70750fb23685a17121b52e98a37c87204e0207729fd9219d11a48e57970d790338793cf329f7b239512a44dd4409fe9d157f92123dfc5cba24af106442644dedda87e1d9e95fd395f2f0ad8f7d27f313e6ce1a07d9845dec5ad732e6e4749b3a161527c8ce42331f5de1d700650072fb68e9c7645a0e0e529d0563d2727e3fb38ed341f74ef1ad95a0216a440e1384d0e7ef71cde38cecdc9e2b2d563f19014c40c1f92ea0af3b4f6da9146d433ae85f647153db326a28ef6ea2e0ebac0cc1aff157067c7dba7cc4317d56920ee9deab5764368e7e5b3ce8bebd0fa129f869b15897c09659c53188bf8efb7b6ac7d265c9b85fe96166 +AD: df41db4ef5350d4afcaa88b4a577b3370b96699bbd73e59aeebca6ea856cf22694a9399ae7f97a3bec226d82f5598f8949dfb92530dcfe77770f066f2af988fba5543b8ba7655bc43f8dca032981a34a1beff695c6908169d475c55b2119fe5578623f68a9dd85b653656881b0db4006d3336fdfc784d1805e48ff478fdc196601f044c9d33fca3ddde2db0102f90fff0b370f520e00e3786c2a9b0b4a9a7ea6f9d866f77d870c8ef0f3a8bedef17949a32598512af665679dfbe71e1c3efc3dee8f5d4499e20dc63281191751f67e51f201973a6675896484527d66bed94d6aaceff65fbc4192cec19452b8873f22d72bf2f4981fe656285cb24be5c58e77dafd3e096166b230f18d3f4197fe16f6ec84c060ce0793ae6848311a18b7 +CT: b15b2bc4b9e8ecc5d9c4a6359a805b7590bdb4bfaa9b3fc4d7676d721edc4b3b1ef71b18a3d78f1b31a477cf25e55b278eb3ed774805ae8e5a2a0204f7291d9587663c4d8b1b744154f3b7cef796e0b91590161f3bde82f1d8139cb8d017606ae6d0552ba144788fd8caf435ab09a43a1f4057776af49bad98fc35cefefb159cfebfed76f2e4d18b7be143677ff8b3d6e2b440fe68475b5a1193bcd19ab157d0d2257f33de8e50091ea3388648c3410aa68c830566a0413d92454e4eff433c3edc74e8f7516ec17b2c01cf57a2d7c48db97b706b8d7da0b68051f2d6a87c417f46cf217a48611980890f669d39b478c35d834ed2c79299df2381a1215d6db303cb63e2795fe517649874226e0a6dbfe2c86370b9fbdd8c5de349bfa25f +TAG: 7082c7ef72c82d23e0ba524132acd208 + +KEY: c05dc14b5def43f2e8f86c3008ef44e4dc6513768812e9218b2b216818c4cec6 +NONCE: 5cfe0dca6e599ed9aa89ba97 +IN: 8a06e2997b8e5f8040b22e07978c83c48d0f90bd2b2f8b426b43feea0b614d3b0681745ea4224cabcaa25ca45c3053a6300c47ffa4f72e838db135ae35c27939aad4cf7f75fb61daa3148d869057598e4e8b44c6fb19b0d9281e18676d8bc137489bb77a51a3a8f807a896d558f00040e8729ea9bbdc7db6102c8b99c8a1eacb0735577bc6533cd1d8147013935b6344116090a1bdef1f2e38a877a50c8fc0f394bafede31375c57476ba06d95ae734e6dae771a32e5091dff71d845c5f7385b9b9069ced12fcfea34a510880b088bb0016e94a5932c89baee038cbafbf06b3d09426afd2d5dd5e392636362e9ffa9186b5c753eb84f82f68fb1286ed06c58a5a936cad018ebc4269037b49f2ea0349373adea99f06062e5dbb0bf94f2883f5c0556 +AD: f2a3f7af8ea984bbd85953f14202c6e478f98d0bcaacd414329ec480d0c29fb4c1a052d3228c883928448f0bef12cee5b69829b4a3eb4680084131867cfc3d3af84fcc0d80c2292d3fe02405634f6cfb20b0fb90345da3a557fb30582175c32e432be66ad096f9425ff4060df54d6741fd6567a1e2fc5f6f3ed95cefc806ff64ae91ae82920b5c829ea026f83fd90d760e240da3c9ddaafe4d08507f4af1049056dc6d09657779a3dbd889d851e97d4ac60dc66df2d24979ba8947a7890a304bb301d0d42b67824e0c68fc882e90cb6deee50c2e3d9f0da59ab23c997b05635a0d56c71fc39aa0e6b19c43a7fe12d4e4145453cd7fbd8a3f33bf5451addf05052df7ef044a33513bc5f1a4cfc8b68015664bb5c8e4bf54a85efff109ee96af75d4a5 +CT: 2cf630548d6f2b449057c7861920308958199f77b123a142c6b7c89c4982f4ed0efa2fe899914ddbf4543e70865a5e683b0721d6c8443df2e697acf31e11c8809aba94196409020a7c64d396fe136826455aec973af23a6c7733cb567f5ea550e50e0b796623a97807d042855568e3c568990cfc818c31a1bf415337f43e9baed57fada2fb2ad3c3543f2b7f2777e03f84040c1c854c310ab1cc5dc7f2a5fb213af79ac068b46c7d9475bea126adf079e2100bb57904a931faf248e0f7d5832ca83ea8a283e0136979737132afb1f4ab38d307ac0774814f4d5ecdc4aad79185c05f8a706f579b78f2c1c7004cb38e6cd22c2080735b34c3f6134955ed3bc36b1ad5c8e33209c9f3c658fb07b59b6002b2526cd8d853a5c624b7108573d7df60c827 +TAG: 3dcdabcd1c82002a551cea41921570e5 + +KEY: b33f449deccc2ef0d7616f22b4a00fcd84c51a8383782f66f1696bc6405005ee +NONCE: 6afa8baf923f986b5779ac6a +IN: b0af85a6deae5fcaa94778bce015ce2da7400ab768f3e114cc1b645fb2716789e2aeb96894fda6da5bc24fcf2466124720d6ba99e5475d77e5bcf2c2f8c8e5becf5eb73ad650861bbdeb51ba5ee789c227478934200fc18f36e4fe392c99d4c3fe0b38b40d2e84f831b8ef9bce9ac1362c755943521ecf5b5cf8fbcdf08f2d47ff7cd62838597dd342695a1b037bcede69500bf70bf1edbb40a17b44695bd8ff8bc8664b3211a6bbfdcbd1bffbfb1a2ea0141cfbc6ac841c803b137be5eeb2666c46c09cc1c4fa82be43bfd56e7a2b8ceeecb6efc1933a90213a0e1bc7aca2af35f2d1dad5f0d9002561064a699f1ce76c39d9c2224ae596e88a1517e19c2115370768d50107f3f2a55051838ae5897acf2ac0814ccd864eee2f6b5d7a6728c6ac6e6a57327102 +AD: 2134f74e882a44e457c38b6580cd58ce20e81267baeb4a9d50c41ababc2a91ddf300c39963643d3c0797b628c75a5fc39c058d319e7d6deb836334dbe8e1fe3cc5704b90c712e1fb60a3c8b58d474a73d65fae886394f8b2c029e420b923f2af4d54c9de3c7fa2bccaa1e96664ccf681cacbbf9845069a4bfd6c135c4392d7d6be338eca414e3a45f50510718e2a5a3e5815eafa0c50172cf5f147510645d2269929843bbbab682deb5823d4cdf42bd250bdbd20c43e2919d7a6e48973f43a4cab73454b97cdca96721ebd83b6dbaaec7e12cf0dae678a57c431b81421657037dd47dccbee73a41f56495fd7c25c75744fe8f55cbd1eac4a174d8f7dd6f6ba57b3e53449a9ce7806517e3e07cf6546a0fa62c7b1fa244d42eee64a3182461792edb628e567b23a +CT: 0fe35823610ea698aeb5b571f3ebbaf0ac3586ecb3b24fcc7c56943d4426f7fdf4e4a53fb430751456d41551f8e5502faa0e1ac5f452b27b13c1dc63e9231c6b192f8dd2978300293298acb6293459d3204429e374881085d49ed6ad76f1d85e3f6dd5455a7a5a9d7127386a30f80658395dc8eb158e5ca052a7137feef28aa247e176cceb9c031f73fb8d48139e3bdb30e2e19627f7fc3501a6d6287e2fb89ad184cefa1774585aa663586f289c778462eee3cd88071140274770e4ed98b9b83cd4fa659fcdd2d1fde7e58333c6cf7f83fe285b97ad8f276a375fafa15f88e6167f5f2bfb95af1aefee80b0620a9bc09402ab79036e716f0c8d518ae2fa15094f6ea4c5e8b283f97cc27f2f1d0b6367b4b508c7bad16f1539325751bd785e9e08cd508bdb3b84 +TAG: 1976d7e121704ce463a8d4fe1b93d90f + +# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf + +KEY: 0000000000000000000000000000000000000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: "" +CT: "" +AD: "" +TAG: 530f8afbc74536b9a963b4f1c4cb738b + +KEY: 0000000000000000000000000000000000000000000000000000000000000000 +NONCE: 000000000000000000000000 +IN: 00000000000000000000000000000000 +CT: cea7403d4d606b6e074ec5d3baf39d18 +AD: "" +TAG: d0d1c8a799996bf0265b98b5d48ab919 + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 +NONCE: cafebabefacedbaddecaf888 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 +CT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad +AD: "" +TAG: b094dac5d93471bdec1a502270e3cc6c + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 +NONCE: cafebabefacedbaddecaf888 +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662 +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 76fc6ece0f4e1768cddf8853bb2d551b + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 +NONCE: cafebabefacedbad +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: 3a337dbf46a792c45e454913fe2ea8f2 + +KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 +NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +CT: 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f +AD: feedfacedeadbeeffeedfacedeadbeefabaddad2 +TAG: a44a8266ee1c8eb0c8b5d4cf5ae9f19a + diff --git a/Libraries/libressl/tests/aes_test.c b/Libraries/libressl/tests/aes_test.c new file mode 100644 index 000000000..37bee05ca --- /dev/null +++ b/Libraries/libressl/tests/aes_test.c @@ -0,0 +1,979 @@ +/* $OpenBSD: aes_test.c,v 1.3 2023/09/28 08:21:43 tb Exp $ */ +/* + * Copyright (c) 2022 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +struct aes_test { + const int mode; + const uint8_t key[64]; + const uint8_t iv[64]; + const int iv_len; + const uint8_t in[64]; + const int in_len; + const uint8_t out[64]; + const int out_len; + const int padding; +}; + +static const struct aes_test aes_tests[] = { + /* ECB - Test vectors from FIPS-197, Appendix C. */ + { + .mode = NID_aes_128_ecb, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + }, + .in_len = 16, + .out = { + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, + }, + .out_len = 16, + }, + { + .mode = NID_aes_192_ecb, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + }, + .in = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + }, + .in_len = 16, + .out = { + 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91, + }, + .out_len = 16, + }, + { + .mode = NID_aes_256_ecb, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + }, + .in_len = 16, + .out = { + 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89, + }, + .out_len = 16, + }, + + /* CBC - Test vectors from RFC 3602 */ + { + .mode = NID_aes_128_cbc, + .key = { + 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, + 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06, + }, + .iv = { + 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, + 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41, + }, + .iv_len = 16, + .in = { + 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6d, 0x73, 0x67, + }, + .in_len = 16, + .out = { + 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8, + 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a, + }, + .out_len = 16, + }, + { + .mode = NID_aes_128_cbc, + .key = { + 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, + 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a, + }, + .iv = { + 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, + 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, + }, + .iv_len = 16, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, + 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a, + 0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, + 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1, + }, + .out_len = 32, + }, + { + .mode = NID_aes_128_cbc, + .key = { + 0x6c, 0x3e, 0xa0, 0x47, 0x76, 0x30, 0xce, 0x21, + 0xa2, 0xce, 0x33, 0x4a, 0xa7, 0x46, 0xc2, 0xcd, + }, + .iv = { + 0xc7, 0x82, 0xdc, 0x4c, 0x09, 0x8c, 0x66, 0xcb, + 0xd9, 0xcd, 0x27, 0xd8, 0x25, 0x68, 0x2c, 0x81, + }, + .iv_len = 16, + .in = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x34, 0x38, 0x2d, 0x62, 0x79, 0x74, + 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x20, 0x28, 0x65, 0x78, 0x61, 0x63, 0x74, + 0x6c, 0x79, 0x20, 0x33, 0x20, 0x41, 0x45, 0x53, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x29, + }, + .in_len = 48, + .out = { + 0xd0, 0xa0, 0x2b, 0x38, 0x36, 0x45, 0x17, 0x53, + 0xd4, 0x93, 0x66, 0x5d, 0x33, 0xf0, 0xe8, 0x86, + 0x2d, 0xea, 0x54, 0xcd, 0xb2, 0x93, 0xab, 0xc7, + 0x50, 0x69, 0x39, 0x27, 0x67, 0x72, 0xf8, 0xd5, + 0x02, 0x1c, 0x19, 0x21, 0x6b, 0xad, 0x52, 0x5c, + 0x85, 0x79, 0x69, 0x5d, 0x83, 0xba, 0x26, 0x84, + }, + .out_len = 48, + }, + { + .mode = NID_aes_128_cbc, + .key = { + 0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74, + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49, + }, + .iv = { + 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9, + }, + .iv_len = 16, + .in = { + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + }, + .in_len = 64, + .out = { + 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e, + 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa, + 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6, + 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e, + 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf, + 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad, + 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d, + 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55, + }, + .out_len = 64, + }, + + /* CBC - Test vectors from NIST SP 800-38A */ + { + .mode = NID_aes_128_cbc, + .key = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, + 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, + 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, + 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, + 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7, + }, + .out_len = 64, + }, + { + .mode = NID_aes_192_cbc, + .key = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, + 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8, + 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, + 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a, + 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, + 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0, + 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, + 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd, + }, + .out_len = 64, + }, + { + .mode = NID_aes_256_cbc, + .key = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, + 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, + 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, + 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d, + 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, + 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61, + 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, + 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, + }, + .out_len = 64, + }, + + /* CFB128 - Test vectors from NIST SP 800-38A */ + { + .mode = NID_aes_128_cfb128, + .key = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, + 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, + 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, + 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b, + 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40, + 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf, + 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e, + 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6, + }, + .out_len = 64, + }, + { + .mode = NID_aes_192_cfb128, + .key = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, + 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, + 0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a, + 0x2e, 0x1e, 0x8a, 0x1d, 0xd5, 0x9b, 0x88, 0xb1, + 0xc8, 0xe6, 0x0f, 0xed, 0x1e, 0xfa, 0xc4, 0xc9, + 0xc0, 0x5f, 0x9f, 0x9c, 0xa9, 0x83, 0x4f, 0xa0, + 0x42, 0xae, 0x8f, 0xba, 0x58, 0x4b, 0x09, 0xff, + }, + .out_len = 64, + }, + { + .mode = NID_aes_256_cfb128, + .key = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, + 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, + 0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8, + 0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b, + 0xdf, 0x10, 0x13, 0x24, 0x15, 0xe5, 0x4b, 0x92, + 0xa1, 0x3e, 0xd0, 0xa8, 0x26, 0x7a, 0xe2, 0xf9, + 0x75, 0xa3, 0x85, 0x74, 0x1a, 0xb9, 0xce, 0xf8, + 0x20, 0x31, 0x62, 0x3d, 0x55, 0xb1, 0xe4, 0x71, + }, + .out_len = 64, + }, + + /* OFB128 - Test vectors from NIST SP 800-38A */ + { + .mode = NID_aes_128_ofb128, + .key = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, + 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, + 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, + 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, + 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, + 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, + 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, + 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e, + }, + .out_len = 64, + }, + { + .mode = NID_aes_192_ofb128, + .key = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, + 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, + 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, + 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, + 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, + 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, + 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, + 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a, + }, + .out_len = 64, + }, + { + .mode = NID_aes_256_ofb128, + .key = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, + }, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .iv_len = 16, + .in = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + }, + .in_len = 64, + .out = { + 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, + 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, + 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, + 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, + 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, + 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, + 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, + 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84, + }, + .out_len = 64, + }, +}; + +#define N_AES_TESTS (sizeof(aes_tests) / sizeof(aes_tests[0])) + +static int +aes_ecb_test(size_t test_number, const char *label, int key_bits, + const struct aes_test *at) +{ + AES_KEY key; + uint8_t out[64]; + + if (at->padding) { + /* XXX - Handle padding */ + return 1; + } + + /* Encryption */ + memset(out, 0, sizeof(out)); + AES_set_encrypt_key(at->key, key_bits, &key); + AES_ecb_encrypt(at->in, out, &key, 1); + + if (memcmp(at->out, out, at->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + label, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + AES_set_decrypt_key(at->key, key_bits, &key); + AES_ecb_encrypt(at->out, out, &key, 0); + + if (memcmp(at->in, out, at->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + label, test_number); + return 0; + } + + return 1; +} + + +static int +aes_cbc_test(size_t test_number, const char *label, int key_bits, + const struct aes_test *at) +{ + AES_KEY key; + uint8_t out[64]; + uint8_t iv[16]; + + if (at->padding) { + /* XXX - Handle padding */ + return 1; + } + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, at->iv, at->iv_len); + AES_set_encrypt_key(at->key, key_bits, &key); + AES_cbc_encrypt(at->in, out, at->in_len, &key, iv, 1); + + if (memcmp(at->out, out, at->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + label, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, at->iv, at->iv_len); + AES_set_decrypt_key(at->key, key_bits, &key); + AES_cbc_encrypt(at->out, out, at->out_len, &key, iv, 0); + + if (memcmp(at->in, out, at->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + label, test_number); + return 0; + } + + return 1; +} + +static int +aes_evp_test(size_t test_number, const struct aes_test *at, const char *label, + int key_bits, const EVP_CIPHER *cipher) +{ + EVP_CIPHER_CTX *ctx; + uint8_t out[64]; + int in_len, out_len, total_len; + int i; + int success = 0; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_new failed\n", + label, test_number); + goto failed; + } + + /* EVP encryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_EncryptInit(ctx, cipher, NULL, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_padding(ctx, at->padding)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n", + label, test_number); + goto failed; + } + + if (!EVP_EncryptInit(ctx, NULL, at->key, at->iv)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n", + label, test_number); + goto failed; + } + + for (i = 0; i < at->in_len;) { + in_len = arc4random_uniform(at->in_len / 2); + if (in_len > at->in_len - i) + in_len = at->in_len - i; + + if (!EVP_EncryptUpdate(ctx, out + total_len, &out_len, + at->in + i, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_EncryptUpdate failed\n", + label, test_number); + goto failed; + } + + i += in_len; + total_len += out_len; + } + + if (!EVP_EncryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptFinal_ex failed\n", + label, test_number); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n", + label, test_number); + goto failed; + } + + if (total_len != at->out_len) { + fprintf(stderr, + "FAIL (%s:%zu): EVP encryption length mismatch " + "(%d != %d)\n", label, test_number, total_len, at->out_len); + goto failed; + } + + if (memcmp(at->out, out, at->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP encryption mismatch\n", + label, test_number); + goto failed; + } + + /* EVP decryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_DecryptInit(ctx, cipher, NULL, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_padding(ctx, at->padding)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n", + label, test_number); + goto failed; + } + + if (!EVP_DecryptInit(ctx, NULL, at->key, at->iv)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n", + label, test_number); + goto failed; + } + + for (i = 0; i < at->out_len;) { + in_len = arc4random_uniform(at->out_len / 2); + if (in_len > at->out_len - i) + in_len = at->out_len - i; + + if (!EVP_DecryptUpdate(ctx, out + total_len, &out_len, + at->out + i, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DecryptUpdate failed\n", + label, test_number); + goto failed; + } + + i += in_len; + total_len += out_len; + } + + if (!EVP_DecryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptFinal_ex failed\n", + label, test_number); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n", + label, test_number); + goto failed; + } + + if (total_len != at->in_len) { + fprintf(stderr, + "FAIL (%s:%zu): EVP decryption length mismatch\n", + label, test_number); + goto failed; + } + + if (memcmp(at->in, out, at->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP decryption mismatch\n", + label, test_number); + goto failed; + } + + success = 1; + + failed: + EVP_CIPHER_CTX_free(ctx); + return success; +} + + +static int +aes_key_bits_from_nid(int nid) +{ + switch (nid) { + case NID_aes_128_ecb: + case NID_aes_128_cbc: + case NID_aes_128_cfb128: + case NID_aes_128_ofb128: + case NID_aes_128_gcm: + case NID_aes_128_ccm: + return 128; + case NID_aes_192_ecb: + case NID_aes_192_cbc: + case NID_aes_192_cfb128: + case NID_aes_192_ofb128: + case NID_aes_192_gcm: + case NID_aes_192_ccm: + return 192; + case NID_aes_256_ecb: + case NID_aes_256_cbc: + case NID_aes_256_cfb128: + case NID_aes_256_ofb128: + case NID_aes_256_gcm: + case NID_aes_256_ccm: + return 256; + default: + return -1; + } +} + +static int +aes_cipher_from_nid(int nid, const char **out_label, + const EVP_CIPHER **out_cipher) +{ + switch (nid) { + /* ECB */ + case NID_aes_128_ecb: + *out_label = SN_aes_128_ecb; + *out_cipher = EVP_aes_128_ecb(); + break; + case NID_aes_192_ecb: + *out_label = SN_aes_192_ecb; + *out_cipher = EVP_aes_192_ecb(); + break; + case NID_aes_256_ecb: + *out_label = SN_aes_256_ecb; + *out_cipher = EVP_aes_256_ecb(); + break; + + /* CBC */ + case NID_aes_128_cbc: + *out_label = SN_aes_128_cbc; + *out_cipher = EVP_aes_128_cbc(); + break; + case NID_aes_192_cbc: + *out_label = SN_aes_192_cbc; + *out_cipher = EVP_aes_192_cbc(); + break; + case NID_aes_256_cbc: + *out_label = SN_aes_256_cbc; + *out_cipher = EVP_aes_256_cbc(); + break; + + /* CFB128 */ + case NID_aes_128_cfb128: + *out_label = SN_aes_128_cfb128; + *out_cipher = EVP_aes_128_cfb128(); + break; + case NID_aes_192_cfb128: + *out_label = SN_aes_192_cfb128; + *out_cipher = EVP_aes_192_cfb128(); + break; + case NID_aes_256_cfb128: + *out_label = SN_aes_256_cfb128; + *out_cipher = EVP_aes_256_cfb128(); + break; + + /* OFB128 */ + case NID_aes_128_ofb128: + *out_label = SN_aes_128_ofb128; + *out_cipher = EVP_aes_128_ofb(); + break; + case NID_aes_192_ofb128: + *out_label = SN_aes_192_ofb128; + *out_cipher = EVP_aes_192_ofb(); + break; + case NID_aes_256_ofb128: + *out_label = SN_aes_256_ofb128; + *out_cipher = EVP_aes_256_ofb(); + break; + + /* GCM */ + case NID_aes_128_gcm: + *out_label = SN_aes_128_gcm; + *out_cipher = EVP_aes_128_gcm(); + break; + case NID_aes_192_gcm: + *out_label = SN_aes_192_gcm; + *out_cipher = EVP_aes_192_gcm(); + break; + case NID_aes_256_gcm: + *out_label = SN_aes_256_gcm; + *out_cipher = EVP_aes_256_gcm(); + break; + + /* CCM */ + case NID_aes_128_ccm: + *out_label = SN_aes_128_ccm; + *out_cipher = EVP_aes_128_ccm(); + break; + case NID_aes_192_ccm: + *out_label = SN_aes_192_ccm; + *out_cipher = EVP_aes_192_ccm(); + break; + case NID_aes_256_ccm: + *out_label = SN_aes_256_ccm; + *out_cipher = EVP_aes_256_ccm(); + break; + + /* Unknown */ + default: + return 0; + } + + return 1; +} + +static int +aes_test(void) +{ + const struct aes_test *at; + const char *label; + const EVP_CIPHER *cipher; + int key_bits; + size_t i; + int failed = 1; + + for (i = 0; i < N_AES_TESTS; i++) { + at = &aes_tests[i]; + key_bits = aes_key_bits_from_nid(at->mode); + if (!aes_cipher_from_nid(at->mode, &label, &cipher)) + goto failed; + + switch (at->mode) { + /* ECB */ + case NID_aes_128_ecb: + case NID_aes_192_ecb: + case NID_aes_256_ecb: + if (!aes_ecb_test(i, label, key_bits, at)) + goto failed; + break; + + /* CBC */ + case NID_aes_128_cbc: + case NID_aes_192_cbc: + case NID_aes_256_cbc: + if (!aes_cbc_test(i, label, key_bits, at)) + goto failed; + break; + + /* CFB128 */ + case NID_aes_128_cfb128: + case NID_aes_192_cfb128: + case NID_aes_256_cfb128: + /* XXX - CFB128 non-EVP tests */ + break; + + /* OFB128 */ + case NID_aes_128_ofb128: + case NID_aes_192_ofb128: + case NID_aes_256_ofb128: + /* XXX - OFB128 non-EVP tests */ + break; + + /* GCM */ + case NID_aes_128_gcm: + case NID_aes_192_gcm: + case NID_aes_256_gcm: + /* GCM is EVP-only */ + break; + + /* CCM */ + case NID_aes_128_ccm: + case NID_aes_192_ccm: + case NID_aes_256_ccm: + /* XXX - CCM non-EVP tests */ + break; + + /* Unknown */ + default: + fprintf(stderr, "FAIL: unknown mode (%d)\n", + at->mode); + goto failed; + } + + if (!aes_evp_test(i, at, label, key_bits, cipher)) + goto failed; + } + + failed = 0; + + failed: + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= aes_test(); + + return failed; +} + diff --git a/Libraries/libressl/tests/aes_wrap.c b/Libraries/libressl/tests/aes_wrap.c new file mode 100644 index 000000000..2b61ae373 --- /dev/null +++ b/Libraries/libressl/tests/aes_wrap.c @@ -0,0 +1,187 @@ +/* $OpenBSD: aes_wrap.c,v 1.5 2021/04/04 20:40:48 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +#include + +int AES_wrap_unwrap_test(const unsigned char *, int, const unsigned char *, + const unsigned char *, const unsigned char *, int); + +int +AES_wrap_unwrap_test(const unsigned char *kek, int keybits, + const unsigned char *iv, const unsigned char *eout, + const unsigned char *key, int keylen) +{ + unsigned char *otmp = NULL, *ptmp = NULL; + int r, ret = 0; + AES_KEY wctx; + + otmp = malloc(keylen + 8); + ptmp = malloc(keylen); + if (otmp == NULL || ptmp == NULL) + goto err; + if (AES_set_encrypt_key(kek, keybits, &wctx)) + goto err; + r = AES_wrap_key(&wctx, iv, otmp, key, keylen); + if (r <= 0) + goto err; + + if (eout && memcmp(eout, otmp, keylen)) + goto err; + + if (AES_set_decrypt_key(kek, keybits, &wctx)) + goto err; + r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r); + if (r <= 0) + goto err; + + if (memcmp(key, ptmp, keylen)) + goto err; + + ret = 1; + +err: + free(otmp); + free(ptmp); + + return ret; +} + +int +main(int argc, char **argv) +{ + static const unsigned char kek[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + + static const unsigned char key[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; + + static const unsigned char e1[] = { + 0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47, + 0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82, + 0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5 + }; + + static const unsigned char e2[] = { + 0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35, + 0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2, + 0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d + }; + + static const unsigned char e3[] = { + 0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2, + 0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a, + 0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7 + }; + + static const unsigned char e4[] = { + 0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32, + 0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc, + 0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93, + 0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2 + }; + + static const unsigned char e5[] = { + 0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f, + 0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4, + 0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95, + 0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1 + }; + + static const unsigned char e6[] = { + 0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4, + 0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26, + 0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26, + 0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b, + 0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21 + }; + + int ret, nfailures = 0; + ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16); + if (ret == 0) + nfailures++; + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16); + if (ret == 0) + nfailures++; + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16); + if (ret == 0) + nfailures++; + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24); + if (ret == 0) + nfailures++; + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24); + if (ret == 0) + nfailures++; + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32); + if (ret == 0) + nfailures++; + fprintf(stderr, "Key test result %d\n", ret); + + return nfailures; +} diff --git a/Libraries/libressl/tests/apitest.c b/Libraries/libressl/tests/apitest.c new file mode 100644 index 000000000..9a58de9f8 --- /dev/null +++ b/Libraries/libressl/tests/apitest.c @@ -0,0 +1,374 @@ +/* $OpenBSD: apitest.c,v 1.2 2023/04/14 12:38:30 tb Exp $ */ +/* + * Copyright (c) 2020, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +#ifndef CERTSDIR +#define CERTSDIR "." +#endif + +const char *certs_path = CERTSDIR; + +int debug = 0; + +static int +ssl_ctx_use_ca_file(SSL_CTX *ssl_ctx, const char *ca_file) +{ + char *ca_path = NULL; + int ret = 0; + + if (asprintf(&ca_path, "%s/%s", certs_path, ca_file) == -1) + goto err; + if (!SSL_CTX_load_verify_locations(ssl_ctx, ca_path, NULL)) { + fprintf(stderr, "load_verify_locations(%s) failed\n", ca_path); + goto err; + } + + ret = 1; + + err: + free(ca_path); + + return ret; +} + +static int +ssl_ctx_use_keypair(SSL_CTX *ssl_ctx, const char *chain_file, + const char *key_file) +{ + char *chain_path = NULL, *key_path = NULL; + int ret = 0; + + if (asprintf(&chain_path, "%s/%s", certs_path, chain_file) == -1) + goto err; + if (SSL_CTX_use_certificate_chain_file(ssl_ctx, chain_path) != 1) { + fprintf(stderr, "FAIL: Failed to load certificates\n"); + goto err; + } + if (asprintf(&key_path, "%s/%s", certs_path, key_file) == -1) + goto err; + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_path, + SSL_FILETYPE_PEM) != 1) { + fprintf(stderr, "FAIL: Failed to load private key\n"); + goto err; + } + + ret = 1; + + err: + free(chain_path); + free(key_path); + + return ret; +} + +static SSL * +tls_client(BIO *rbio, BIO *wbio) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) + errx(1, "client context"); + + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + + if (!ssl_ctx_use_ca_file(ssl_ctx, "ca-root-rsa.pem")) + goto failure; + if (!ssl_ctx_use_keypair(ssl_ctx, "client1-rsa-chain.pem", + "client1-rsa.pem")) + goto failure; + + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "client ssl"); + + BIO_up_ref(rbio); + BIO_up_ref(wbio); + + SSL_set_bio(ssl, rbio, wbio); + + failure: + SSL_CTX_free(ssl_ctx); + + return ssl; +} + +static SSL * +tls_server(BIO *rbio, BIO *wbio) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) + errx(1, "server context"); + + SSL_CTX_set_dh_auto(ssl_ctx, 2); + + SSL_CTX_set_verify(ssl_ctx, + SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + + if (!ssl_ctx_use_ca_file(ssl_ctx, "ca-root-rsa.pem")) + goto failure; + if (!ssl_ctx_use_keypair(ssl_ctx, "server1-rsa-chain.pem", + "server1-rsa.pem")) + goto failure; + + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "server ssl"); + + BIO_up_ref(rbio); + BIO_up_ref(wbio); + + SSL_set_bio(ssl, rbio, wbio); + + failure: + SSL_CTX_free(ssl_ctx); + + return ssl; +} + +static int +ssl_error(SSL *ssl, const char *name, const char *desc, int ssl_ret) +{ + int ssl_err; + + ssl_err = SSL_get_error(ssl, ssl_ret); + + if (ssl_err == SSL_ERROR_WANT_READ) { + return 1; + } else if (ssl_err == SSL_ERROR_WANT_WRITE) { + return 1; + } else if (ssl_err == SSL_ERROR_SYSCALL && errno == 0) { + /* Yup, this is apparently a thing... */ + } else { + fprintf(stderr, "FAIL: %s %s failed - ssl err = %d, errno = %d\n", + name, desc, ssl_err, errno); + ERR_print_errors_fp(stderr); + return 0; + } + + return 1; +} + +static int +do_connect(SSL *ssl, const char *name, int *done) +{ + int ssl_ret; + + if ((ssl_ret = SSL_connect(ssl)) == 1) { + fprintf(stderr, "INFO: %s connect done\n", name); + *done = 1; + return 1; + } + + return ssl_error(ssl, name, "connect", ssl_ret); +} + +static int +do_accept(SSL *ssl, const char *name, int *done) +{ + int ssl_ret; + + if ((ssl_ret = SSL_accept(ssl)) == 1) { + fprintf(stderr, "INFO: %s accept done\n", name); + *done = 1; + return 1; + } + + return ssl_error(ssl, name, "accept", ssl_ret); +} + +typedef int (*ssl_func)(SSL *ssl, const char *name, int *done); + +static int +do_client_server_loop(SSL *client, ssl_func client_func, SSL *server, + ssl_func server_func) +{ + int client_done = 0, server_done = 0; + int i = 0; + + do { + if (!client_done) { + if (debug) + fprintf(stderr, "DEBUG: client loop\n"); + if (!client_func(client, "client", &client_done)) + return 0; + } + if (!server_done) { + if (debug) + fprintf(stderr, "DEBUG: server loop\n"); + if (!server_func(server, "server", &server_done)) + return 0; + } + } while (i++ < 100 && (!client_done || !server_done)); + + if (!client_done || !server_done) + fprintf(stderr, "FAIL: gave up\n"); + + return client_done && server_done; +} + +static int +ssl_get_peer_cert_chain_test(uint16_t tls_version) +{ + STACK_OF(X509) *peer_chain; + X509 *peer_cert; + BIO *client_wbio = NULL, *server_wbio = NULL; + SSL *client = NULL, *server = NULL; + int failed = 1; + + if ((client_wbio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (BIO_set_mem_eof_return(client_wbio, -1) <= 0) + goto failure; + + if ((server_wbio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (BIO_set_mem_eof_return(server_wbio, -1) <= 0) + goto failure; + + if ((client = tls_client(server_wbio, client_wbio)) == NULL) + goto failure; + if (tls_version != 0) { + if (!SSL_set_min_proto_version(client, tls_version)) + goto failure; + if (!SSL_set_max_proto_version(client, tls_version)) + goto failure; + } + + if ((server = tls_server(client_wbio, server_wbio)) == NULL) + goto failure; + if (tls_version != 0) { + if (!SSL_set_min_proto_version(server, tls_version)) + goto failure; + if (!SSL_set_max_proto_version(server, tls_version)) + goto failure; + } + + if (!do_client_server_loop(client, do_connect, server, do_accept)) { + fprintf(stderr, "FAIL: client and server handshake failed\n"); + goto failure; + } + + if (tls_version != 0) { + if (SSL_version(client) != tls_version) { + fprintf(stderr, "FAIL: client got TLS version %x, " + "want %x\n", SSL_version(client), tls_version); + goto failure; + } + if (SSL_version(server) != tls_version) { + fprintf(stderr, "FAIL: server got TLS version %x, " + "want %x\n", SSL_version(server), tls_version); + goto failure; + } + } + + /* + * Due to the wonders of API inconsistency, SSL_get_peer_cert_chain() + * includes the peer's leaf certificate when called by the client, + * however it does not when called by the server. Futhermore, the + * certificate returned by SSL_get_peer_certificate() has already + * had its reference count incremented and must be freed, where as + * the certificates returned from SSL_get_peer_cert_chain() must + * not be freed... *sigh* + */ + peer_cert = SSL_get_peer_certificate(client); + peer_chain = SSL_get_peer_cert_chain(client); + X509_free(peer_cert); + + if (peer_cert == NULL) { + fprintf(stderr, "FAIL: client got no peer cert\n"); + goto failure; + } + if (sk_X509_num(peer_chain) != 2) { + fprintf(stderr, "FAIL: client got peer cert chain with %d " + "certificates, want 2\n", sk_X509_num(peer_chain)); + goto failure; + } + if (X509_cmp(peer_cert, sk_X509_value(peer_chain, 0)) != 0) { + fprintf(stderr, "FAIL: client got peer cert chain without peer " + "certificate\n"); + goto failure; + } + + peer_cert = SSL_get_peer_certificate(server); + peer_chain = SSL_get_peer_cert_chain(server); + X509_free(peer_cert); + + if (peer_cert == NULL) { + fprintf(stderr, "FAIL: server got no peer cert\n"); + goto failure; + } + if (sk_X509_num(peer_chain) != 1) { + fprintf(stderr, "FAIL: server got peer cert chain with %d " + "certificates, want 1\n", sk_X509_num(peer_chain)); + goto failure; + } + if (X509_cmp(peer_cert, sk_X509_value(peer_chain, 0)) == 0) { + fprintf(stderr, "FAIL: server got peer cert chain with peer " + "certificate\n"); + goto failure; + } + + fprintf(stderr, "INFO: Done!\n"); + + failed = 0; + + failure: + BIO_free(client_wbio); + BIO_free(server_wbio); + + SSL_free(client); + SSL_free(server); + + return failed; +} + +static int +ssl_get_peer_cert_chain_tests(void) +{ + int failed = 0; + + fprintf(stderr, "\n== Testing SSL_get_peer_cert_chain()... ==\n"); + + failed |= ssl_get_peer_cert_chain_test(0); + failed |= ssl_get_peer_cert_chain_test(TLS1_3_VERSION); + failed |= ssl_get_peer_cert_chain_test(TLS1_2_VERSION); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + if (argc > 2) { + fprintf(stderr, "usage: %s [certspath]\n", argv[0]); + exit(1); + } + if (argc == 2) + certs_path = argv[1]; + + failed |= ssl_get_peer_cert_chain_tests(); + + return failed; +} diff --git a/Libraries/libressl/tests/arc4randomforktest.c b/Libraries/libressl/tests/arc4randomforktest.c new file mode 100644 index 000000000..4bc9c634f --- /dev/null +++ b/Libraries/libressl/tests/arc4randomforktest.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2014 Google Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHECK(x) assert(x) +#define CHECK_EQ(a, b) assert((a) == (b)) +#define CHECK_NE(a, b) assert((a) != (b)) +#define CHECK_GE(a, b) assert((a) >= (b)) +#define CHECK_LE(a, b) assert((a) <= (b)) + +/* Test arc4random_buf(3) instead of arc4random(3). */ +static int flagbuf; + +/* Initialize arc4random(3) before forking. */ +static int flagprefork; + +enum { + N = 4096 +}; + +typedef struct { + uint32_t x[N]; +} Buf; + +static int +isfullbuf(const Buf *buf) +{ + size_t i; + for (i = 0; i < N; i++) + if (buf->x[i]) + return (1); + return (0); +} + +static void +fillbuf(Buf *buf) +{ + if (flagbuf) { + arc4random_buf(buf->x, sizeof(buf->x)); + } else { + size_t i; + for (i = 0; i < N; i++) + buf->x[i] = arc4random(); + } +} + +static void +usage() +{ + errx(1, "usage: arc4random-fork [-bp]"); +} + +static pid_t +safewaitpid(pid_t pid, int *status, int options) +{ + pid_t ret; + do { + ret = waitpid(pid, status, options); + } while (ret == -1 && errno == EINTR); + return (ret); +} + +int +main(int argc, char *argv[]) +{ + int opt, status; + Buf *bufparent, *bufchildone, *bufchildtwo; + pid_t pidone, pidtwo; + size_t i, countone = 0, counttwo = 0, countkids = 0; + + /* Ensure SIGCHLD isn't set to SIG_IGN. */ + const struct sigaction sa = { + .sa_handler = SIG_DFL, + }; + CHECK_EQ(0, sigaction(SIGCHLD, &sa, NULL)); + + while ((opt = getopt(argc, argv, "bp")) != -1) { + switch (opt) { + case 'b': + flagbuf = 1; + break; + case 'p': + flagprefork = 1; + break; + default: + usage(); + } + } + + if (flagprefork) + arc4random(); + + bufparent = mmap(NULL, sizeof(Buf), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0); + CHECK_NE(MAP_FAILED, bufparent); + + bufchildone = mmap(NULL, sizeof(Buf), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_SHARED, -1, 0); + CHECK_NE(MAP_FAILED, bufchildone); + + bufchildtwo = mmap(NULL, sizeof(Buf), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_SHARED, -1, 0); + CHECK_NE(MAP_FAILED, bufchildtwo); + + pidone = fork(); + CHECK_GE(pidone, 0); + if (pidone == 0) { + fillbuf(bufchildone); + _exit(0); + } + + pidtwo = fork(); + CHECK_GE(pidtwo, 0); + if (pidtwo == 0) { + fillbuf(bufchildtwo); + _exit(0); + } + + fillbuf(bufparent); + + CHECK_EQ(pidone, safewaitpid(pidone, &status, 0)); + CHECK(WIFEXITED(status)); + CHECK_EQ(0, WEXITSTATUS(status)); + + CHECK_EQ(pidtwo, safewaitpid(pidtwo, &status, 0)); + CHECK(WIFEXITED(status)); + CHECK_EQ(0, WEXITSTATUS(status)); + + CHECK(isfullbuf(bufchildone)); + CHECK(isfullbuf(bufchildtwo)); + + for (i = 0; i < N; i++) { + countone += bufparent->x[i] == bufchildone->x[i]; + counttwo += bufparent->x[i] == bufchildtwo->x[i]; + countkids += bufchildone->x[i] == bufchildtwo->x[i]; + } + + /* + * These checks are inherently probabilistic and theoretically risk + * flaking, but there's less than a 1 in 2^40 chance of more than + * one pairwise match between two vectors of 4096 32-bit integers. + */ + CHECK_LE(countone, 1); + CHECK_LE(counttwo, 1); + CHECK_LE(countkids, 1); + + return (0); +} diff --git a/Libraries/libressl/tests/arc4randomforktest.sh b/Libraries/libressl/tests/arc4randomforktest.sh new file mode 100644 index 000000000..fe0306841 --- /dev/null +++ b/Libraries/libressl/tests/arc4randomforktest.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +./arc4randomforktest +./arc4randomforktest -b +./arc4randomforktest -p +./arc4randomforktest -bp diff --git a/Libraries/libressl/tests/asn1_string_to_utf8.c b/Libraries/libressl/tests/asn1_string_to_utf8.c new file mode 100644 index 000000000..a87969d98 --- /dev/null +++ b/Libraries/libressl/tests/asn1_string_to_utf8.c @@ -0,0 +1,134 @@ +/* $OpenBSD: asn1_string_to_utf8.c,v 1.2 2022/11/23 08:51:05 tb Exp $ */ +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +struct asn1_string_to_utf8_test_case { + const char *description; + const ASN1_ITEM *item; + const uint8_t der[32]; + size_t der_len; + const uint8_t want[32]; + int want_len; +}; + +static const struct asn1_string_to_utf8_test_case tests[] = { + { + .description = "hello", + .item = &ASN1_PRINTABLESTRING_it, + .der = { + 0x13, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, + }, + .der_len = 7, + .want = { + 0x68, 0x65, 0x6c, 0x6c, 0x6f, + }, + .want_len = 5, + }, + { + .description = "face with tears of joy", + .item = &ASN1_UTF8STRING_it, + .der = { + 0x0c, 0x04, 0xF0, 0x9F, 0x98, 0x82, + }, + .der_len = 6, + .want = { + 0xF0, 0x9F, 0x98, 0x82, + }, + .want_len = 4, + }, + { + .description = "hi", + .item = &ASN1_IA5STRING_it, + .der = { + 0x16, 0x02, 0x68, 0x69, + }, + .der_len = 4, + .want = { + 0x68, 0x69, + }, + .want_len = 2, + }, +}; + +const size_t N_TESTS = sizeof(tests) / sizeof(tests[0]); + +static int +asn1_string_to_utf8_test(const struct asn1_string_to_utf8_test_case *test) +{ + ASN1_STRING *str = NULL; + const unsigned char *der; + unsigned char *out = NULL; + int ret; + int failed = 1; + + der = test->der; + if ((str = (ASN1_STRING *)ASN1_item_d2i(NULL, &der, test->der_len, + test->item)) == NULL) { + warnx("ASN1_item_d2i failed"); + goto err; + } + + if ((ret = ASN1_STRING_to_UTF8(&out, str)) < 0) { + warnx("ASN1_STRING_to_UTF8 failed: got %d, want %d", ret, + test->want_len); + goto err; + } + + if (ret != test->want_len) { + warnx("ASN1_STRING_to_UTF8: got %d, want %d", ret, + test->want_len); + goto err; + } + + if (memcmp(out, test->want, test->want_len) != 0) { + warnx("memcmp failed"); + goto err; + } + + failed = 0; + err: + ASN1_STRING_free(str); + free(out); + + return failed; +} + +static int +asn1_string_to_utf8_tests(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_TESTS; i++) + failed |= asn1_string_to_utf8_test(&tests[i]); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= asn1_string_to_utf8_tests(); + + return failed; +} diff --git a/Libraries/libressl/tests/asn1api.c b/Libraries/libressl/tests/asn1api.c new file mode 100644 index 000000000..8d016bde8 --- /dev/null +++ b/Libraries/libressl/tests/asn1api.c @@ -0,0 +1,415 @@ +/* $OpenBSD: asn1api.c,v 1.3 2022/07/09 14:47:42 tb Exp $ */ +/* + * Copyright (c) 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +const long asn1_tag2bits[] = { + [0] = 0, + [1] = 0, + [2] = 0, + [3] = B_ASN1_BIT_STRING, + [4] = B_ASN1_OCTET_STRING, + [5] = 0, + [6] = 0, + [7] = B_ASN1_UNKNOWN, + [8] = B_ASN1_UNKNOWN, + [9] = B_ASN1_UNKNOWN, + [10] = B_ASN1_UNKNOWN, + [11] = B_ASN1_UNKNOWN, + [12] = B_ASN1_UTF8STRING, + [13] = B_ASN1_UNKNOWN, + [14] = B_ASN1_UNKNOWN, + [15] = B_ASN1_UNKNOWN, + [16] = B_ASN1_SEQUENCE, + [17] = 0, + [18] = B_ASN1_NUMERICSTRING, + [19] = B_ASN1_PRINTABLESTRING, + [20] = B_ASN1_T61STRING, + [21] = B_ASN1_VIDEOTEXSTRING, + [22] = B_ASN1_IA5STRING, + [23] = B_ASN1_UTCTIME, + [24] = B_ASN1_GENERALIZEDTIME, + [25] = B_ASN1_GRAPHICSTRING, + [26] = B_ASN1_ISO64STRING, + [27] = B_ASN1_GENERALSTRING, + [28] = B_ASN1_UNIVERSALSTRING, + [29] = B_ASN1_UNKNOWN, + [30] = B_ASN1_BMPSTRING, +}; + +static int +asn1_tag2bit(void) +{ + int failed = 1; + long bit; + int i; + + for (i = -3; i <= V_ASN1_NEG + 30; i++) { + bit = ASN1_tag2bit(i); + if (i >= 0 && i <= 30) { + if (bit != asn1_tag2bits[i]) { + fprintf(stderr, "FAIL: ASN1_tag2bit(%d) = 0x%lx," + " want 0x%lx\n", i, bit, asn1_tag2bits[i]); + goto failed; + } + } else { + if (bit != 0) { + fprintf(stderr, "FAIL: ASN1_tag2bit(%d) = 0x%lx," + " want 0x0\n", i, bit); + goto failed; + } + } + } + + failed = 0; + + failed: + return failed; +} + +static int +asn1_tag2str(void) +{ + int failed = 1; + const char *s; + int i; + + for (i = -3; i <= V_ASN1_NEG + 30; i++) { + if ((s = ASN1_tag2str(i)) == NULL) { + fprintf(stderr, "FAIL: ASN1_tag2str(%d) returned " + "NULL\n", i); + goto failed; + } + if ((i >= 0 && i <= 30) || i == V_ASN1_NEG_INTEGER || + i == V_ASN1_NEG_ENUMERATED) { + if (strcmp(s, "(unknown)") == 0) { + fprintf(stderr, "FAIL: ASN1_tag2str(%d) = '%s'," + " want tag name\n", i, s); + goto failed; + } + } else { + if (strcmp(s, "(unknown)") != 0) { + fprintf(stderr, "FAIL: ASN1_tag2str(%d) = '%s'," + " want '(unknown')\n", i, s); + goto failed; + } + } + } + + failed = 0; + + failed: + return failed; +} + +struct asn1_get_object_test { + const uint8_t asn1[64]; + size_t asn1_len; + size_t asn1_hdr_len; + int want_ret; + long want_length; + int want_tag; + int want_class; + int want_error; +}; + +const struct asn1_get_object_test asn1_get_object_tests[] = { + { + /* Zero tag and zero length (EOC). */ + .asn1 = {0x00, 0x00}, + .asn1_len = 2, + .asn1_hdr_len = 2, + .want_ret = 0x00, + .want_length = 0, + .want_tag = 0, + .want_class = 0, + }, + { + /* Boolean with short form length. */ + .asn1 = {0x01, 0x01}, + .asn1_len = 3, + .asn1_hdr_len = 2, + .want_ret = 0x00, + .want_length = 1, + .want_tag = 1, + .want_class = 0, + }, + { + /* Long form tag. */ + .asn1 = {0x1f, 0x7f, 0x01}, + .asn1_len = 3 + 128, + .asn1_hdr_len = 3, + .want_ret = 0x00, + .want_length = 1, + .want_tag = 127, + .want_class = 0, + }, + { + /* Long form tag with class application. */ + .asn1 = {0x5f, 0x7f, 0x01}, + .asn1_len = 3 + 128, + .asn1_hdr_len = 3, + .want_ret = 0x00, + .want_length = 1, + .want_tag = 127, + .want_class = 1 << 6, + }, + { + /* Long form tag with class context-specific. */ + .asn1 = {0x9f, 0x7f, 0x01}, + .asn1_len = 3 + 128, + .asn1_hdr_len = 3, + .want_ret = 0x00, + .want_length = 1, + .want_tag = 127, + .want_class = 2 << 6, + }, + { + /* Long form tag with class private. */ + .asn1 = {0xdf, 0x7f, 0x01}, + .asn1_len = 3 + 128, + .asn1_hdr_len = 3, + .want_ret = 0x00, + .want_length = 1, + .want_tag = 127, + .want_class = 3 << 6, + }, + { + /* Long form tag (maximum). */ + .asn1 = {0x1f, 0x87, 0xff, 0xff, 0xff, 0x7f, 0x01}, + .asn1_len = 8, + .asn1_hdr_len = 7, + .want_ret = 0x00, + .want_length = 1, + .want_tag = 0x7fffffff, + .want_class = 0, + }, + { + /* Long form tag (maximum + 1). */ + .asn1 = {0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x01}, + .asn1_len = 8, + .asn1_hdr_len = 7, + .want_ret = 0x80, + .want_error = ASN1_R_HEADER_TOO_LONG, + }, + { + /* OctetString with long form length. */ + .asn1 = {0x04, 0x81, 0x80}, + .asn1_len = 3 + 128, + .asn1_hdr_len = 3, + .want_ret = 0x00, + .want_length = 128, + .want_tag = 4, + .want_class = 0, + }, + { + /* OctetString with long form length. */ + .asn1 = {0x04, 0x84, 0x7f, 0xff, 0xff, 0xf9}, + .asn1_len = 0x7fffffff, + .asn1_hdr_len = 6, + .want_ret = 0x00, + .want_length = 0x7ffffff9, + .want_tag = 4, + .want_class = 0, + }, + { + /* Long form tag and long form length. */ + .asn1 = {0x1f, 0x87, 0xff, 0xff, 0xff, 0x7f, 0x84, 0x7f, 0xff, 0xff, 0xf4}, + .asn1_len = 0x7fffffff, + .asn1_hdr_len = 11, + .want_ret = 0x00, + .want_length = 0x7ffffff4, + .want_tag = 0x7fffffff, + .want_class = 0, + }, + { + /* Constructed OctetString with definite length. */ + .asn1 = {0x24, 0x03}, + .asn1_len = 5, + .asn1_hdr_len = 2, + .want_ret = 0x20, + .want_length = 3, + .want_tag = 4, + .want_class = 0, + }, + { + /* Constructed OctetString with indefinite length. */ + .asn1 = {0x24, 0x80}, + .asn1_len = 5, + .asn1_hdr_len = 2, + .want_ret = 0x21, + .want_length = 0, + .want_tag = 4, + .want_class = 0, + }, + { + /* Boolean with indefinite length (invalid). */ + .asn1 = {0x01, 0x80}, + .asn1_len = 3, + .want_ret = 0x80, + .want_error = ASN1_R_HEADER_TOO_LONG, + }, + { + /* OctetString with insufficient data (only tag). */ + .asn1 = {0x04, 0x04}, + .asn1_len = 1, + .want_ret = 0x80, + .want_error = ASN1_R_HEADER_TOO_LONG, + }, + { + /* OctetString with insufficient data (missing content). */ + .asn1 = {0x04, 0x04}, + .asn1_len = 2, + .asn1_hdr_len = 2, + .want_ret = 0x80, + .want_length = 4, + .want_tag = 4, + .want_class = 0, + .want_error = ASN1_R_TOO_LONG, + }, + { + /* OctetString with insufficient data (partial content). */ + .asn1 = {0x04, 0x04}, + .asn1_len = 5, + .asn1_hdr_len = 2, + .want_ret = 0x80, + .want_length = 4, + .want_tag = 4, + .want_class = 0, + .want_error = ASN1_R_TOO_LONG, + }, + { + /* Constructed OctetString with insufficient data (only tag/len). */ + .asn1 = {0x24, 0x04}, + .asn1_len = 2, + .asn1_hdr_len = 2, + .want_ret = 0xa0, + .want_length = 4, + .want_tag = 4, + .want_class = 0, + .want_error = ASN1_R_TOO_LONG, + }, +}; + +#define N_ASN1_GET_OBJECT_TESTS \ + (sizeof(asn1_get_object_tests) / sizeof(*asn1_get_object_tests)) + +static int +asn1_get_object(void) +{ + const struct asn1_get_object_test *agot; + const uint8_t *p; + int ret, tag, tag_class; + long err, length; + size_t i; + int failed = 1; + + for (i = 0; i < N_ASN1_GET_OBJECT_TESTS; i++) { + agot = &asn1_get_object_tests[i]; + + ERR_clear_error(); + + p = agot->asn1; + ret = ASN1_get_object(&p, &length, &tag, &tag_class, agot->asn1_len); + + if (ret != agot->want_ret) { + fprintf(stderr, "FAIL: %zu - got return value %x, want %x\n", + i, ret, agot->want_ret); + goto failed; + } + if (ret & 0x80) { + err = ERR_peek_error(); + if (ERR_GET_REASON(err) != agot->want_error) { + fprintf(stderr, "FAIL: %zu - got error reason %d, " + "want %d\n", i, ERR_GET_REASON(err), + agot->want_error); + goto failed; + } + if (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG) { + if (p != agot->asn1) { + fprintf(stderr, "FAIL: %zu - got ber_in %p, " + "want %p\n", i, p, agot->asn1); + goto failed; + } + continue; + } + } + if (length != agot->want_length) { + fprintf(stderr, "FAIL: %zu - got length %ld, want %ld\n", + i, length, agot->want_length); + goto failed; + } + if (tag != agot->want_tag) { + fprintf(stderr, "FAIL: %zu - got tag %d, want %d\n", + i, tag, agot->want_tag); + goto failed; + } + if (tag_class != agot->want_class) { + fprintf(stderr, "FAIL: %zu - got class %d, want %d\n", + i, tag_class, agot->want_class); + goto failed; + } + if (p != agot->asn1 + agot->asn1_hdr_len) { + fprintf(stderr, "FAIL: %zu - got ber_in %p, want %p\n", + i, p, agot->asn1 + agot->asn1_len); + goto failed; + } + } + + failed = 0; + + failed: + return failed; +} + +static int +asn1_integer_get_null_test(void) +{ + int failed = 0; + long ret; + + if ((ret = ASN1_INTEGER_get(NULL)) != 0) { + fprintf(stderr, "FAIL: ASN1_INTEGER_get(NULL) %ld != 0\n", ret); + failed |= 1; + } + + if ((ret = ASN1_ENUMERATED_get(NULL)) != 0) { + fprintf(stderr, "FAIL: ASN1_ENUMERATED_get(NULL) %ld != 0\n", + ret); + failed |= 1; + } + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= asn1_tag2bit(); + failed |= asn1_tag2str(); + failed |= asn1_get_object(); + failed |= asn1_integer_get_null_test(); + + return (failed); +} diff --git a/Libraries/libressl/tests/asn1basic.c b/Libraries/libressl/tests/asn1basic.c new file mode 100644 index 000000000..5bcb9009a --- /dev/null +++ b/Libraries/libressl/tests/asn1basic.c @@ -0,0 +1,1137 @@ +/* $OpenBSD: asn1basic.c,v 1.15 2023/08/15 21:05:44 tb Exp $ */ +/* + * Copyright (c) 2017, 2021 Joel Sing + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +#include "asn1_local.h" + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +asn1_compare_bytes(const char *label, const unsigned char *d1, int len1, + const unsigned char *d2, int len2) +{ + if (len1 != len2) { + fprintf(stderr, "FAIL: %s - byte lengths differ " + "(%d != %d)\n", label, len1, len2); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + if (memcmp(d1, d2, len1) != 0) { + fprintf(stderr, "FAIL: %s - bytes differ\n", label); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + return 1; +} + +const uint8_t asn1_bit_string_primitive[] = { + 0x03, 0x07, + 0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0, +}; + +static int +asn1_bit_string_test(void) +{ + uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0}; + ASN1_BIT_STRING *abs; + uint8_t *p = NULL, *pp; + const uint8_t *q; + int bit, i, len; + int failed = 1; + + if ((abs = ASN1_BIT_STRING_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n"); + goto failed; + } + if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) { + fprintf(stderr, "FAIL: failed to set bit string\n"); + goto failed; + } + + if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n"); + goto failed; + } + if ((p = malloc(len)) == NULL) + errx(1, "malloc"); + memset(p, 0xbd, len); + pp = p; + if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) { + fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); + goto failed; + } + if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive, + sizeof(asn1_bit_string_primitive))) + goto failed; + if (pp != p + len) { + fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING pp = %p, want %p\n", + pp, p + len); + goto failed; + } + + /* Test primitive decoding. */ + q = p; + if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) { + fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n"); + goto failed; + } + if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length, + bs, sizeof(bs))) + goto failed; + if (q != p + len) { + fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING q = %p, want %p\n", + q, p + len); + goto failed; + } + + /* Test ASN1_BIT_STRING_get_bit(). */ + for (i = 0; i < ((int)sizeof(bs) * 8); i++) { + bit = (bs[i / 8] >> (7 - i % 8)) & 1; + + if (ASN1_BIT_STRING_get_bit(abs, i) != bit) { + fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) " + "= %d, want %d\n", i, + ASN1_BIT_STRING_get_bit(abs, i), bit); + goto failed; + } + } + + /* Test ASN1_BIT_STRING_set_bit(). */ + for (i = 0; i < ((int)sizeof(bs) * 8); i++) { + if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) { + fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n"); + goto failed; + } + } + for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) { + bit = (bs[i / 8] >> (7 - i % 8)) & 1; + if (bit == 1) + continue; + if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) { + fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n"); + goto failed; + } + } + + if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) { + fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); + goto failed; + } + + memset(p, 0xbd, len); + pp = p; + if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) { + fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); + goto failed; + } + + if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive, + sizeof(asn1_bit_string_primitive))) + goto failed; + + failed = 0; + + failed: + ASN1_BIT_STRING_free(abs); + free(p); + + return failed; +} + +const uint8_t asn1_boolean_false[] = { + 0x01, 0x01, 0x00, +}; +const uint8_t asn1_boolean_true[] = { + 0x01, 0x01, 0x01, +}; + +static int +asn1_boolean_test(void) +{ + uint8_t *p = NULL, *pp; + const uint8_t *q; + int len; + int failed = 1; + + if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n"); + goto failed; + } + if ((p = malloc(len)) == NULL) + errx(1, "calloc"); + memset(p, 0xbd, len); + pp = p; + if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) { + fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n"); + goto failed; + } + if (pp != p + len) { + fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n", + pp, p + len); + goto failed; + } + + if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false, + sizeof(asn1_boolean_false))) + goto failed; + + q = p; + if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) { + fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n"); + goto failed; + } + if (q != p + len) { + fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n", + q, p + len); + goto failed; + } + + free(p); + p = NULL; + + if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n"); + goto failed; + } + if ((p = calloc(1, len)) == NULL) + errx(1, "calloc"); + pp = p; + if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) { + fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n"); + goto failed; + } + if (pp != p + len) { + fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n", + pp, p + len); + goto failed; + } + + if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true, + sizeof(asn1_boolean_true))) + goto failed; + + q = p; + if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) { + fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n"); + goto failed; + } + if (q != p + len) { + fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n", + q, p + len); + goto failed; + } + + failed = 0; + + failed: + free(p); + + return failed; +} + +struct asn1_integer_test { + long value; + uint8_t content[64]; + size_t content_len; + int content_neg; + uint8_t der[64]; + size_t der_len; + int want_error; +}; + +struct asn1_integer_test asn1_integer_tests[] = { + { + .value = 0, + .content = {0x00}, + .content_len = 1, + .der = {0x02, 0x01, 0x00}, + .der_len = 3, + }, + { + .value = 1, + .content = {0x01}, + .content_len = 1, + .der = {0x02, 0x01, 0x01}, + .der_len = 3, + }, + { + .value = -1, + .content = {0x01}, + .content_len = 1, + .content_neg = 1, + .der = {0x02, 0x01, 0xff}, + .der_len = 3, + }, + { + .value = 127, + .content = {0x7f}, + .content_len = 1, + .der = {0x02, 0x01, 0x7f}, + .der_len = 3, + }, + { + .value = -127, + .content = {0x7f}, + .content_len = 1, + .content_neg = 1, + .der = {0x02, 0x01, 0x81}, + .der_len = 3, + }, + { + .value = 128, + .content = {0x80}, + .content_len = 1, + .der = {0x02, 0x02, 0x00, 0x80}, + .der_len = 4, + }, + { + .value = -128, + .content = {0x80}, + .content_len = 1, + .content_neg = 1, + .der = {0x02, 0x01, 0x80}, + .der_len = 3, + }, + { + /* 2^64 */ + .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .content_len = 9, + .der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .der_len = 11, + }, + { + /* -2^64 */ + .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .content_len = 9, + .content_neg = 1, + .der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .der_len = 11, + }, + { + /* Invalid length. */ + .der = {0x02, 0x00}, + .der_len = 2, + .want_error = 1, + }, + { + /* Invalid padding. */ + .der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .der_len = 11, + .want_error = 1, + }, + { + /* Invalid padding. */ + .der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .der_len = 11, + .want_error = 1, + }, + { + /* Invalid encoding (constructed with definite length). */ + .der = {0x22, 0x03, 0x02, 0x01, 0x01}, + .der_len = 5, + .want_error = 1, + }, + { + /* Invalid encoding (constructed with indefinite length). */ + .der = {0x22, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00}, + .der_len = 7, + .want_error = 1, + }, +}; + +#define N_ASN1_INTEGER_TESTS \ + (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests)) + +static int +asn1_integer_set_test(struct asn1_integer_test *ait) +{ + ASN1_INTEGER *aint = NULL; + uint8_t *p = NULL, *pp; + int len; + int failed = 1; + + if ((aint = ASN1_INTEGER_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); + goto failed; + } + if (!ASN1_INTEGER_set(aint, ait->value)) { + fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n", + ait->value); + goto failed; + } + if (ait->value != 0 && + !asn1_compare_bytes("INTEGER set", aint->data, aint->length, + ait->content, ait->content_len)) + goto failed; + if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) { + fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n"); + goto failed; + } + if (ASN1_INTEGER_get(aint) != ait->value) { + fprintf(stderr, "FAIL: ASN1_INTEGER_get() = %ld, want %ld\n", + ASN1_INTEGER_get(aint), ait->value); + goto failed; + } + if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); + goto failed; + } + if ((p = malloc(len)) == NULL) + errx(1, "malloc"); + memset(p, 0xbd, len); + pp = p; + if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); + goto failed; + } + if (!asn1_compare_bytes("INTEGER set", p, len, ait->der, + ait->der_len)) + goto failed; + + failed = 0; + + failed: + ASN1_INTEGER_free(aint); + free(p); + + return failed; +} + +static int +asn1_integer_content_test(struct asn1_integer_test *ait) +{ + ASN1_INTEGER *aint = NULL; + uint8_t *p = NULL, *pp; + int len; + int failed = 1; + + if ((aint = ASN1_INTEGER_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); + goto failed; + } + if ((aint->data = malloc(ait->content_len)) == NULL) + errx(1, "malloc"); + memcpy(aint->data, ait->content, ait->content_len); + aint->length = ait->content_len; + if (ait->content_neg) + aint->type = V_ASN1_NEG_INTEGER; + + if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); + goto failed; + } + if ((p = malloc(len)) == NULL) + errx(1, "malloc"); + memset(p, 0xbd, len); + pp = p; + if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); + goto failed; + } + if (!asn1_compare_bytes("INTEGER content", p, len, ait->der, + ait->der_len)) + goto failed; + if (pp != p + len) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER pp = %p, want %p\n", + pp, p + len); + goto failed; + } + + failed = 0; + + failed: + ASN1_INTEGER_free(aint); + free(p); + + return failed; +} + +static int +asn1_integer_decode_test(struct asn1_integer_test *ait) +{ + ASN1_INTEGER *aint = NULL; + const uint8_t *q; + int failed = 1; + + q = ait->der; + if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) { + if (ait->want_error != 0) { + fprintf(stderr, "FAIL: INTEGER decoded when it should " + "have failed\n"); + goto failed; + } + if (!asn1_compare_bytes("INTEGER content", aint->data, + aint->length, ait->content, ait->content_len)) + goto failed; + if (q != ait->der + ait->der_len) { + fprintf(stderr, "FAIL: d2i_ASN1_INTEGER q = %p, want %p\n", + q, ait->der + ait->der_len); + goto failed; + } + } else if (ait->want_error == 0) { + fprintf(stderr, "FAIL: INTEGER failed to decode\n"); + ERR_print_errors_fp(stderr); + goto failed; + } + + failed = 0; + + failed: + ASN1_INTEGER_free(aint); + + return failed; +} + +static int +asn1_integer_set_val_test(void) +{ + ASN1_INTEGER *aint = NULL; + uint64_t uval; + int64_t val; + int failed = 1; + + if ((aint = ASN1_INTEGER_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); + goto failed; + } + + if (!ASN1_INTEGER_set_uint64(aint, 0)) { + fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with " + "0\n"); + goto failed; + } + if (!ASN1_INTEGER_get_uint64(&uval, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with " + "0\n"); + goto failed; + } + if (uval != 0) { + fprintf(stderr, "FAIL: uval != 0\n"); + goto failed; + } + + if (!ASN1_INTEGER_set_uint64(aint, UINT64_MAX)) { + fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with " + "UINT64_MAX\n"); + goto failed; + } + if (!ASN1_INTEGER_get_uint64(&uval, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with " + "UINT64_MAX\n"); + goto failed; + } + if (uval != UINT64_MAX) { + fprintf(stderr, "FAIL: uval != UINT64_MAX\n"); + goto failed; + } + if (ASN1_INTEGER_get_int64(&val, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() succeeded " + "with UINT64_MAX\n"); + goto failed; + } + + if (!ASN1_INTEGER_set_int64(aint, INT64_MIN)) { + fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with " + "INT64_MIN\n"); + goto failed; + } + if (!ASN1_INTEGER_get_int64(&val, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with " + "INT64_MIN\n"); + goto failed; + } + if (val != INT64_MIN) { + fprintf(stderr, "FAIL: val != INT64_MIN\n"); + goto failed; + } + if (ASN1_INTEGER_get_uint64(&uval, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() succeeded " + "with INT64_MIN\n"); + goto failed; + } + + if (!ASN1_INTEGER_set_int64(aint, INT64_MAX)) { + fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with " + "INT64_MAX\n"); + goto failed; + } + if (!ASN1_INTEGER_get_int64(&val, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with " + "INT64_MAX\n"); + goto failed; + } + if (val != INT64_MAX) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with " + "INT64_MAX\n"); + goto failed; + } + if (!ASN1_INTEGER_get_uint64(&uval, aint)) { + fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with " + "INT64_MAX\n"); + goto failed; + } + if (uval != INT64_MAX) { + fprintf(stderr, "FAIL: uval != INT64_MAX\n"); + goto failed; + } + + failed = 0; + + failed: + ASN1_INTEGER_free(aint); + + return failed; +} + +static int +asn1_integer_cmp_test(void) +{ + ASN1_INTEGER *a = NULL, *b = NULL; + int failed = 1; + + if ((a = ASN1_INTEGER_new()) == NULL) + goto failed; + if ((b = ASN1_INTEGER_new()) == NULL) + goto failed; + + if (ASN1_INTEGER_cmp(a, b) != 0) { + fprintf(stderr, "FAIL: INTEGER 0 == 0"); + goto failed; + } + + if (!ASN1_INTEGER_set(b, 1)) { + fprintf(stderr, "FAIL: failed to set INTEGER"); + goto failed; + } + if (ASN1_INTEGER_cmp(a, b) >= 0) { + fprintf(stderr, "FAIL: INTEGER 0 < 1"); + goto failed; + } + if (ASN1_INTEGER_cmp(b, a) <= 0) { + fprintf(stderr, "FAIL: INTEGER 1 > 0"); + goto failed; + } + + if (!ASN1_INTEGER_set(b, -1)) { + fprintf(stderr, "FAIL: failed to set INTEGER"); + goto failed; + } + if (ASN1_INTEGER_cmp(a, b) <= 0) { + fprintf(stderr, "FAIL: INTEGER 0 > -1"); + goto failed; + } + if (ASN1_INTEGER_cmp(b, a) >= 0) { + fprintf(stderr, "FAIL: INTEGER -1 < 0"); + goto failed; + } + + if (!ASN1_INTEGER_set(a, 1)) { + fprintf(stderr, "FAIL: failed to set INTEGER"); + goto failed; + } + if (ASN1_INTEGER_cmp(a, b) <= 0) { + fprintf(stderr, "FAIL: INTEGER 1 > -1"); + goto failed; + } + if (ASN1_INTEGER_cmp(b, a) >= 0) { + fprintf(stderr, "FAIL: INTEGER -1 < 1"); + goto failed; + } + + if (!ASN1_INTEGER_set(b, 1)) { + fprintf(stderr, "FAIL: failed to set INTEGER"); + goto failed; + } + if (ASN1_INTEGER_cmp(a, b) != 0) { + fprintf(stderr, "FAIL: INTEGER 1 == 1"); + goto failed; + } + + failed = 0; + + failed: + ASN1_INTEGER_free(a); + ASN1_INTEGER_free(b); + + return failed; +} + +static int +asn1_integer_null_data_test(void) +{ + const uint8_t der[] = {0x02, 0x01, 0x00}; + ASN1_INTEGER *aint = NULL; + uint8_t *p = NULL, *pp; + int len; + int failed = 0; + + if ((aint = ASN1_INTEGER_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); + goto failed; + } + if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); + goto failed; + } + if ((p = calloc(1, len)) == NULL) + errx(1, "calloc"); + pp = p; + if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { + fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); + goto failed; + } + if (!asn1_compare_bytes("INTEGER NULL data", p, len, der, sizeof(der))) + goto failed; + + failed = 0; + + failed: + ASN1_INTEGER_free(aint); + free(p); + + return failed; +} + +static int +asn1_integer_test(void) +{ + struct asn1_integer_test *ait; + int failed = 0; + size_t i; + + for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) { + ait = &asn1_integer_tests[i]; + if (ait->content_len > 0 && ait->content_len <= 4) + failed |= asn1_integer_set_test(ait); + if (ait->content_len > 0) + failed |= asn1_integer_content_test(ait); + failed |= asn1_integer_decode_test(ait); + } + + failed |= asn1_integer_cmp_test(); + failed |= asn1_integer_null_data_test(); + failed |= asn1_integer_set_val_test(); + + return failed; +} + +static const struct asn1_string_new_test { + const char *name; + ASN1_STRING *(*new)(void); + void (*free)(ASN1_STRING *); + int type; + long flags; +} asn1_string_new_tests[] = { + { + .name = "ASN1_STRING", + .new = ASN1_STRING_new, + .free = ASN1_STRING_free, + .type = V_ASN1_OCTET_STRING, + }, + { + .name = "ASN1_OCTET_STRING", + .new = ASN1_OCTET_STRING_new, + .free = ASN1_OCTET_STRING_free, + .type = V_ASN1_OCTET_STRING, + }, + { + .name = "ASN1_BIT_STRING", + .new = ASN1_BIT_STRING_new, + .free = ASN1_BIT_STRING_free, + .type = V_ASN1_BIT_STRING, + }, + { + .name = "ASN1_INTEGER", + .new = ASN1_INTEGER_new, + .free = ASN1_INTEGER_free, + .type = V_ASN1_INTEGER, + }, + { + .name = "ASN1_ENUMERATED", + .new = ASN1_ENUMERATED_new, + .free = ASN1_ENUMERATED_free, + .type = V_ASN1_ENUMERATED, + }, + { + .name = "ASN1_UTF8STRING", + .new = ASN1_UTF8STRING_new, + .free = ASN1_UTF8STRING_free, + .type = V_ASN1_UTF8STRING, + }, + { + .name = "ASN1_IA5STRING", + .new = ASN1_IA5STRING_new, + .free = ASN1_IA5STRING_free, + .type = V_ASN1_IA5STRING, + }, + { + .name = "ASN1_UNIVERSALSTRING", + .new = ASN1_UNIVERSALSTRING_new, + .free = ASN1_UNIVERSALSTRING_free, + .type = V_ASN1_UNIVERSALSTRING, + }, + { + .name = "ASN1_BMPSTRING", + .new = ASN1_BMPSTRING_new, + .free = ASN1_BMPSTRING_free, + .type = V_ASN1_BMPSTRING, + }, + { + .name = "ASN1_GENERALSTRING", + .new = ASN1_GENERALSTRING_new, + .free = ASN1_GENERALSTRING_free, + .type = V_ASN1_GENERALSTRING, + }, + { + .name = "ASN1_T61STRING", + .new = ASN1_T61STRING_new, + .free = ASN1_T61STRING_free, + .type = V_ASN1_T61STRING, + }, + { + .name = "ASN1_VISIBLESTRING", + .new = ASN1_VISIBLESTRING_new, + .free = ASN1_VISIBLESTRING_free, + .type = V_ASN1_VISIBLESTRING, + }, + { + .name = "ASN1_PRINTABLESTRING", + .new = ASN1_PRINTABLESTRING_new, + .free = ASN1_PRINTABLESTRING_free, + .type = V_ASN1_PRINTABLESTRING, + }, + { + .name = "ASN1_PRINTABLE", + .new = ASN1_PRINTABLE_new, + .free = ASN1_PRINTABLE_free, + .type = V_ASN1_UNDEF, + .flags = ASN1_STRING_FLAG_MSTRING, + }, + { + .name = "DIRECTORYSTRING", + .new = DIRECTORYSTRING_new, + .free = DIRECTORYSTRING_free, + .type = V_ASN1_UNDEF, + .flags = ASN1_STRING_FLAG_MSTRING, + }, + { + .name = "DISPLAYTEXT", + .new = DISPLAYTEXT_new, + .free = DISPLAYTEXT_free, + .type = V_ASN1_UNDEF, + .flags = ASN1_STRING_FLAG_MSTRING, + }, + { + .name = "ASN1_GENERALIZEDTIME", + .new = ASN1_GENERALIZEDTIME_new, + .free = ASN1_GENERALIZEDTIME_free, + .type = V_ASN1_GENERALIZEDTIME, + }, + { + .name = "ASN1_UTCTIME", + .new = ASN1_UTCTIME_new, + .free = ASN1_UTCTIME_free, + .type = V_ASN1_UTCTIME, + }, + { + .name = "ASN1_TIME", + .new = ASN1_TIME_new, + .free = ASN1_TIME_free, + .type = V_ASN1_UNDEF, + .flags = ASN1_STRING_FLAG_MSTRING, + }, +}; + +#define N_ASN1_STRING_NEW_TESTS \ + (sizeof(asn1_string_new_tests) / sizeof(asn1_string_new_tests[0])) + +static int +asn1_string_new_test(void) +{ + size_t i; + ASN1_STRING *astr = NULL; + int failed = 1; + + for (i = 0; i < N_ASN1_STRING_NEW_TESTS; i++) { + const struct asn1_string_new_test *asnt = &asn1_string_new_tests[i]; + + if ((astr = asnt->new()) == NULL) { + fprintf(stderr, "%s_new() failed\n", asnt->name); + goto err; + } + if (ASN1_STRING_type(astr) != asnt->type) { + fprintf(stderr, "%s type: want %d, got %d\n", + asnt->name, asnt->type, ASN1_STRING_type(astr)); + goto err; + } + if (ASN1_STRING_data(astr) != NULL) { + fprintf(stderr, "%s data != NULL\n", asnt->name); + goto err; + } + if (ASN1_STRING_get0_data(astr) != NULL) { + fprintf(stderr, "%s data != NULL\n", asnt->name); + goto err; + } + if (ASN1_STRING_length(astr) != 0) { + fprintf(stderr, "%s length %d != 0\n", asnt->name, + ASN1_STRING_length(astr)); + goto err; + } + ASN1_STRING_length_set(astr, 20); + if (ASN1_STRING_length(astr) != 20) { + fprintf(stderr, "%s length %d != 20\n", asnt->name, + ASN1_STRING_length(astr)); + goto err; + } + astr->flags |= ASN1_STRING_FLAG_NDEF; + if (astr->flags != (asnt->flags | ASN1_STRING_FLAG_NDEF)) { + fprintf(stderr, "%s flags: %lx\n", asnt->name, + astr->flags); + goto err; + } + /* ASN1_STRING_set0() clears ASN1_STRING_FLAG_NDEF. */ + ASN1_STRING_set0(astr, NULL, 0); + if (astr->flags != asnt->flags) { + fprintf(stderr, "%s flags: %lx != %lx\n", asnt->name, + astr->flags, asnt->flags); + goto err; + } + asnt->free(astr); + astr = NULL; + + if ((astr = ASN1_STRING_type_new(asnt->type)) == NULL) { + fprintf(stderr, "ASN1_STRING_type_new(%s) failed\n", + asnt->name); + goto err; + } + if (ASN1_STRING_type(astr) != asnt->type) { + fprintf(stderr, "%s type: want %d, got %d\n", + asnt->name, asnt->type, ASN1_STRING_type(astr)); + goto err; + } + if (ASN1_STRING_data(astr) != NULL) { + fprintf(stderr, "%s data != NULL\n", asnt->name); + goto err; + } + /* ASN1_STRING_type_new() does not set flags. */ + if (astr->flags != 0) { + fprintf(stderr, "%s flags %lx\n", asnt->name, + astr->flags); + goto err; + } + asnt->free(astr); + astr = NULL; + + } + + failed = 0; + + err: + ASN1_STRING_free(astr); + + return failed; +} + +static char *comparison_str = "mystring"; + +static int +asn1_string_cmp_test(void) +{ + ASN1_STRING *a = NULL, *b = NULL; + int got, want; + int failed = 1; + + if ((got = ASN1_STRING_cmp(NULL, NULL)) != -1) { + fprintf(stderr, "ASN1_STRING_cmp(NULL, NULL): %d != -1\n", got); + goto err; + } + + if ((a = ASN1_STRING_new()) == NULL) { + fprintf(stderr, "a = ASN1_STRING_new() failed\n"); + goto err; + } + if ((b = ASN1_STRING_type_new(V_ASN1_UTF8STRING)) == NULL) { + fprintf(stderr, "b = ASN1_STRING_type_new() failed\n"); + goto err; + } + + if ((got = ASN1_STRING_cmp(a, NULL)) != -1) { + fprintf(stderr, "ASN1_STRING_cmp(a, NULL): %d != -1\n", got); + goto err; + } + if ((got = ASN1_STRING_cmp(NULL, a)) != -1) { + fprintf(stderr, "ASN1_STRING_cmp(NULL, a): %d != -1\n", got); + goto err; + } + + if (ASN1_STRING_cmp(a, b) >= 0) { + fprintf(stderr, "V_ASN1_OCTET_STRING >= V_ASN1_UTF8STRING\n"); + goto err; + } + want = V_ASN1_UTF8STRING - V_ASN1_OCTET_STRING; + if ((got = ASN1_STRING_cmp(b, a)) != want) { + fprintf(stderr, "comparison of octet with utf8 string:" + "want %d, got %d\n", want, got); + goto err; + } + + ASN1_STRING_set0(a, comparison_str, strlen(comparison_str)); + ASN1_STRING_set0(b, comparison_str, strlen(comparison_str)); + + /* Ensure any data set on a or b isn't freed/zeroed. */ + a->flags |= ASN1_STRING_FLAG_NDEF; + b->flags |= ASN1_STRING_FLAG_NDEF; + + if ((got = ASN1_STRING_cmp(b, a)) != want) { + fprintf(stderr, "comparison of octet with utf8 string:" + "want %d, got %d\n", want, got); + goto err; + } + + b->type = V_ASN1_OCTET_STRING; + + if ((got = ASN1_STRING_cmp(a, b)) != 0) { + fprintf(stderr, "same string on both. want 0, got %d\n", got); + goto err; + } + + if (!ASN1_STRING_set(b, "myString", -1)) { + fprintf(stderr, "ASN1_STRING_set(b) failed\n"); + goto err; + } + + if ((got = ASN1_STRING_cmp(a, b)) <= 0) { + fprintf(stderr, "capitalized letter compares larger: got %d\n", + got); + goto err; + } + if ((got = ASN1_STRING_cmp(b, a)) >= 0) { + fprintf(stderr, "capitalized letter is larger 2: %d\n", got); + goto err; + } + + ASN1_STRING_length_set(b, 2); + + want = strlen(comparison_str) - 2; + + if ((got = ASN1_STRING_cmp(a, b)) != want) { + fprintf(stderr, "comparison of a with truncated b: " + "want %d, got %d\n", want, got); + goto err; + } + + want = -want; + + if ((got = ASN1_STRING_cmp(b, a)) != want) { + fprintf(stderr, "comparison of truncated b with a: " + "want %d, got %d\n", want, got); + goto err; + } + + ASN1_STRING_length_set(a, 2); + + if ((got = ASN1_STRING_cmp(a, b)) != 0) { + fprintf(stderr, "both truncated compared to %d\n", got); + goto err; + } + + ASN1_STRING_length_set(a, strlen(comparison_str)); + + ASN1_STRING_set0(b, NULL, 0); + + want = strlen(comparison_str); + if ((got = ASN1_STRING_cmp(a, b)) != want) { + fprintf(stderr, "comparison of a with zeroed b: " + "want %d, got %d\n", want, got); + goto err; + } + + ASN1_STRING_set0(b, "", 0); + b->flags |= ASN1_STRING_FLAG_NDEF; + + if ((got = ASN1_STRING_cmp(a, b)) != want) { + fprintf(stderr, "comparison of a with zero-length b: " + "want %d, got %d\n", want, got); + goto err; + } + + ASN1_STRING_set0(a, NULL, 0); + if ((got = ASN1_STRING_cmp(a, b)) != 0) { + fprintf(stderr, "comparison of zeroed a with zero-length b: " + "want 0, got %d\n", got); + goto err; + } + if ((got = ASN1_STRING_cmp(b, a)) != 0) { + fprintf(stderr, "comparison of zero-length b with zeroed a: " + "want 0, got %d\n", got); + goto err; + } + + failed = 0; + + err: + ASN1_STRING_free(a); + ASN1_STRING_free(b); + + return failed; +} + +static int +asn1_string_test(void) +{ + int failed = 0; + + failed |= asn1_string_new_test(); + failed |= asn1_string_cmp_test(); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= asn1_bit_string_test(); + failed |= asn1_boolean_test(); + failed |= asn1_integer_test(); + failed |= asn1_string_test(); + + return (failed); +} diff --git a/Libraries/libressl/tests/asn1complex.c b/Libraries/libressl/tests/asn1complex.c new file mode 100644 index 000000000..6f34154b7 --- /dev/null +++ b/Libraries/libressl/tests/asn1complex.c @@ -0,0 +1,324 @@ +/* $OpenBSD: asn1complex.c,v 1.4 2022/09/05 21:06:31 tb Exp $ */ +/* + * Copyright (c) 2017, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +asn1_compare_bytes(const char *label, const unsigned char *d1, int len1, + const unsigned char *d2, int len2) +{ + if (len1 != len2) { + fprintf(stderr, "FAIL: %s - byte lengths differ " + "(%d != %d)\n", label, len1, len2); + return 0; + } + if (memcmp(d1, d2, len1) != 0) { + fprintf(stderr, "FAIL: %s - bytes differ\n", label); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + return 1; +} + +/* Constructed octet string with length 12. */ +const uint8_t asn1_constructed_basic_ber[] = { + 0x24, 0x0c, + 0x04, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x02, + 0x04, 0x03, 0x01, 0x02, 0x03 +}; +const uint8_t asn1_constructed_basic_content[] = { + 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, +}; + +/* Nested constructed octet string. */ +const uint8_t asn1_constructed_nested_ber[] = { + 0x24, 0x1a, + 0x04, 0x01, 0x01, + 0x24, 0x15, + 0x04, 0x02, 0x02, 0x03, + 0x24, 0x0f, + 0x24, 0x0d, + 0x04, 0x03, 0x04, 0x05, 0x06, + 0x24, 0x06, + 0x24, 0x04, + 0x04, 0x02, 0x07, 0x08, +}; +const uint8_t asn1_constructed_nested_content[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +}; + +/* Deeply nested constructed octet string. */ +const uint8_t asn1_constructed_deep_nested_ber[] = { + 0x24, 0x1b, + 0x04, 0x01, 0x01, + 0x24, 0x16, + 0x04, 0x02, 0x02, 0x03, + 0x24, 0x10, + 0x24, 0x0e, + 0x04, 0x03, 0x04, 0x05, 0x06, + 0x24, 0x07, + 0x24, 0x05, + 0x24, 0x03, + 0x04, 0x01, 0x07, +}; + +/* Constructed octet string with indefinite length. */ +const uint8_t asn1_constructed_indefinite_ber[] = { + 0x24, 0x80, + 0x04, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x02, + 0x04, 0x03, 0x01, 0x02, 0x03, + 0x00, 0x00, +}; +const uint8_t asn1_constructed_indefinite_content[] = { + 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, +}; + +struct asn1_constructed_test { + const char *name; + const uint8_t *asn1; + size_t asn1_len; + const uint8_t *want; + size_t want_len; + int want_error; + int valid; +}; + +const struct asn1_constructed_test asn1_constructed_tests[] = { + { + .name = "basic constructed", + .asn1 = asn1_constructed_basic_ber, + .asn1_len = sizeof(asn1_constructed_basic_ber), + .want = asn1_constructed_basic_content, + .want_len = sizeof(asn1_constructed_basic_content), + .valid = 1, + }, + { + .name = "nested constructed", + .asn1 = asn1_constructed_nested_ber, + .asn1_len = sizeof(asn1_constructed_nested_ber), + .want = asn1_constructed_nested_content, + .want_len = sizeof(asn1_constructed_nested_content), + .valid = 1, + }, + { + .name = "deep nested constructed", + .asn1 = asn1_constructed_deep_nested_ber, + .asn1_len = sizeof(asn1_constructed_deep_nested_ber), + .want_error = ASN1_R_NESTED_ASN1_STRING, + .valid = 0, + }, + { + .name = "indefinite length constructed", + .asn1 = asn1_constructed_indefinite_ber, + .asn1_len = sizeof(asn1_constructed_indefinite_ber), + .want = asn1_constructed_indefinite_content, + .want_len = sizeof(asn1_constructed_indefinite_content), + .valid = 1, + }, +}; + +#define N_CONSTRUCTED_TESTS \ + (sizeof(asn1_constructed_tests) / sizeof(*asn1_constructed_tests)) + +static int +do_asn1_constructed_test(const struct asn1_constructed_test *act) +{ + ASN1_OCTET_STRING *aos = NULL; + const uint8_t *p; + long err; + int failed = 1; + + ERR_clear_error(); + + p = act->asn1; + aos = d2i_ASN1_OCTET_STRING(NULL, &p, act->asn1_len); + if (!act->valid) { + if (aos != NULL) { + fprintf(stderr, "FAIL: invalid ASN.1 decoded\n"); + goto failed; + } + if (act->want_error != 0) { + err = ERR_peek_error(); + if (ERR_GET_REASON(err) != act->want_error) { + fprintf(stderr, "FAIL: got error reason %d," + "want %d", ERR_GET_REASON(err), + act->want_error); + goto failed; + } + } + goto done; + } + if (aos == NULL) { + fprintf(stderr, "FAIL: failed to decode ASN.1 constructed " + "octet string\n"); + ERR_print_errors_fp(stderr); + goto failed; + } + if (!asn1_compare_bytes(act->name, ASN1_STRING_data(aos), + ASN1_STRING_length(aos), act->want, act->want_len)) + goto failed; + + done: + failed = 0; + + failed: + ASN1_OCTET_STRING_free(aos); + + return failed; +} + +static int +do_asn1_constructed_tests(void) +{ + const struct asn1_constructed_test *act; + int failed = 0; + size_t i; + + for (i = 0; i < N_CONSTRUCTED_TESTS; i++) { + act = &asn1_constructed_tests[i]; + failed |= do_asn1_constructed_test(act); + } + + return failed; +} + +/* Sequence with length. */ +const uint8_t asn1_sequence_ber[] = { + 0x30, 0x16, + 0x04, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x02, + 0x04, 0x03, 0x01, 0x02, 0x03, + 0x30, 0x80, 0x04, 0x01, 0x01, 0x00, 0x00, + 0x04, 0x01, 0x01, + + 0x04, 0x01, 0x01, /* Trailing data. */ +}; + +const uint8_t asn1_sequence_content[] = { + 0x30, 0x16, 0x04, 0x01, 0x01, 0x04, 0x02, 0x01, + 0x02, 0x04, 0x03, 0x01, 0x02, 0x03, 0x30, 0x80, + 0x04, 0x01, 0x01, 0x00, 0x00, 0x04, 0x01, 0x01, +}; + +/* Sequence with indefinite length. */ +const uint8_t asn1_sequence_indefinite_ber[] = { + 0x30, 0x80, + 0x04, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x02, + 0x04, 0x03, 0x01, 0x02, 0x03, + 0x30, 0x80, 0x04, 0x01, 0x01, 0x00, 0x00, + 0x04, 0x01, 0x01, + 0x00, 0x00, + + 0x04, 0x01, 0x01, /* Trailing data. */ +}; + +const uint8_t asn1_sequence_indefinite_content[] = { + 0x30, 0x80, 0x04, 0x01, 0x01, 0x04, 0x02, 0x01, + 0x02, 0x04, 0x03, 0x01, 0x02, 0x03, 0x30, 0x80, + 0x04, 0x01, 0x01, 0x00, 0x00, 0x04, 0x01, 0x01, + 0x00, 0x00, +}; + +static int +do_asn1_sequence_string_tests(void) +{ + ASN1_STRING *astr = NULL; + const uint8_t *p; + long len; + int failed = 1; + + ERR_clear_error(); + + /* + * Test decoding of sequence with length and indefinite length into + * a string - in this case the ASN.1 is not decoded and is stored + * directly as the content for the string. + */ + if ((astr = ASN1_STRING_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_STRING_new() returned NULL\n"); + goto failed; + } + + p = asn1_sequence_ber; + len = sizeof(asn1_sequence_ber); + if (ASN1_item_d2i((ASN1_VALUE **)&astr, &p, len, + &ASN1_SEQUENCE_it) == NULL) { + fprintf(stderr, "FAIL: failed to decode ASN1_SEQUENCE\n"); + ERR_print_errors_fp(stderr); + goto failed; + } + + if (!asn1_compare_bytes("sequence", ASN1_STRING_data(astr), + ASN1_STRING_length(astr), asn1_sequence_content, + sizeof(asn1_sequence_content))) + goto failed; + + p = asn1_sequence_indefinite_ber; + len = sizeof(asn1_sequence_indefinite_ber); + if (ASN1_item_d2i((ASN1_VALUE **)&astr, &p, len, + &ASN1_SEQUENCE_it) == NULL) { + fprintf(stderr, "FAIL: failed to decode ASN1_SEQUENCE\n"); + ERR_print_errors_fp(stderr); + goto failed; + } + + if (!asn1_compare_bytes("sequence indefinite", ASN1_STRING_data(astr), + ASN1_STRING_length(astr), asn1_sequence_indefinite_content, + sizeof(asn1_sequence_indefinite_content))) + goto failed; + + failed = 0; + + failed: + ASN1_STRING_free(astr); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= do_asn1_constructed_tests(); + failed |= do_asn1_sequence_string_tests(); + + return (failed); +} diff --git a/Libraries/libressl/tests/asn1evp.c b/Libraries/libressl/tests/asn1evp.c new file mode 100644 index 000000000..0bf0a5fb9 --- /dev/null +++ b/Libraries/libressl/tests/asn1evp.c @@ -0,0 +1,150 @@ +/* $OpenBSD: asn1evp.c,v 1.5 2022/09/05 21:06:31 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#define TEST_NUM 0x7fffffffL + +unsigned char asn1_atios[] = { + 0x30, 0x10, 0x02, 0x04, 0x7f, 0xff, 0xff, 0xff, + 0x04, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, +}; + +unsigned char test_octetstring[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +}; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +compare_data(const char *label, const unsigned char *d1, size_t d1_len, + const unsigned char *d2, size_t d2_len) +{ + if (d1_len != d2_len) { + fprintf(stderr, "FAIL: got %s with length %zu, want %zu\n", + label, d1_len, d2_len); + return -1; + } + if (memcmp(d1, d2, d1_len) != 0) { + fprintf(stderr, "FAIL: %s differs\n", label); + fprintf(stderr, "got:\n"); + hexdump(d1, d1_len); + fprintf(stderr, "want:\n"); + hexdump(d2, d2_len); + return -1; + } + return 0; +} + +int +main(int argc, char **argv) +{ + unsigned char data[16]; + long num = TEST_NUM; + ASN1_TYPE *at = NULL; + int failed = 1; + int len; + + if ((at = ASN1_TYPE_new()) == NULL) { + fprintf(stderr, "FAIL: ASN1_TYPE_new returned NULL\n"); + goto done; + } + + if (!ASN1_TYPE_set_int_octetstring(at, num, test_octetstring, + sizeof(test_octetstring))) { + fprintf(stderr, "FAIL: ASN1_TYPE_set_int_octetstring failed\n"); + goto done; + } + if (at->type != V_ASN1_SEQUENCE) { + fprintf(stderr, "FAIL: not a V_ASN1_SEQUENCE (%d != %d)\n", + at->type, V_ASN1_SEQUENCE); + goto done; + } + if (at->value.sequence->type != V_ASN1_OCTET_STRING) { + fprintf(stderr, "FAIL: not a V_ASN1_OCTET_STRING (%d != %d)\n", + at->type, V_ASN1_OCTET_STRING); + goto done; + } + if (compare_data("sequence", at->value.sequence->data, + at->value.sequence->length, asn1_atios, sizeof(asn1_atios)) == -1) + goto done; + + memset(&data, 0, sizeof(data)); + num = 0; + + if ((len = ASN1_TYPE_get_int_octetstring(at, &num, data, + sizeof(data))) < 0) { + fprintf(stderr, "FAIL: ASN1_TYPE_get_int_octetstring failed\n"); + goto done; + } + if (num != TEST_NUM) { + fprintf(stderr, "FAIL: got num %ld, want %ld\n", num, TEST_NUM); + goto done; + } + if (compare_data("octet string", data, len, + test_octetstring, sizeof(test_octetstring)) == -1) + goto done; + if (data[len] != 0) { + fprintf(stderr, "FAIL: octet string overflowed buffer\n"); + goto done; + } + + memset(&data, 0, sizeof(data)); + num = 0; + + /* With a limit buffer, the output should be truncated... */ + if ((len = ASN1_TYPE_get_int_octetstring(at, &num, data, 4)) < 0) { + fprintf(stderr, "FAIL: ASN1_TYPE_get_int_octetstring failed\n"); + goto done; + } + if (num != TEST_NUM) { + fprintf(stderr, "FAIL: got num %ld, want %ld\n", num, TEST_NUM); + goto done; + } + if (len != sizeof(test_octetstring)) { + fprintf(stderr, "FAIL: got length mismatch (%d != %zu)\n", + len, sizeof(test_octetstring)); + goto done; + } + if (compare_data("octet string", data, 4, test_octetstring, 4) == -1) + goto done; + if (data[4] != 0) { + fprintf(stderr, "FAIL: octet string overflowed buffer\n"); + goto done; + } + + failed = 0; + + done: + ASN1_TYPE_free(at); + + return failed; +} diff --git a/Libraries/libressl/tests/asn1object.c b/Libraries/libressl/tests/asn1object.c new file mode 100644 index 000000000..539c6aa95 --- /dev/null +++ b/Libraries/libressl/tests/asn1object.c @@ -0,0 +1,495 @@ +/* $OpenBSD: asn1object.c,v 1.10 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2017, 2021, 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +#include "asn1_local.h" + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +asn1_compare_bytes(const char *label, const unsigned char *d1, int len1, + const unsigned char *d2, int len2) +{ + if (len1 != len2) { + fprintf(stderr, "FAIL: %s - byte lengths differ " + "(%d != %d)\n", label, len1, len2); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + if (memcmp(d1, d2, len1) != 0) { + fprintf(stderr, "FAIL: %s - bytes differ\n", label); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + return 1; +} + +struct asn1_object_test { + const char *oid; + const char *txt; + const uint8_t content[255]; + size_t content_len; + const uint8_t der[255]; + size_t der_len; + int want_error; +}; + +struct asn1_object_test asn1_object_tests[] = { + { + .oid = "2.5", + .txt = "directory services (X.500)", + .content = { + 0x55, + }, + .content_len = 1, + .der = { + 0x06, 0x01, 0x55, + }, + .der_len = 3, + }, + { + .oid = "2.5.4", + .txt = "X509", + .content = { + 0x55, 0x04, + }, + .content_len = 2, + .der = { + 0x06, 0x02, 0x55, 0x04, + }, + .der_len = 4, + }, + { + .oid = "2.5.4.10", + .txt = "organizationName", + .content = { + 0x55, 0x04, 0x0a, + }, + .content_len = 3, + .der = { + 0x06, 0x03, 0x55, 0x04, 0x0a, + }, + .der_len = 5, + }, + { + .oid = "2 5 4 10", + .txt = "organizationName", + .content = { + 0x55, 0x04, 0x0a, + }, + .content_len = 3, + .der = { + 0x06, 0x03, 0x55, 0x04, 0x0a, + }, + .der_len = 5, + }, + { + .oid = "2.5.0.0", + .txt = "2.5.0.0", + .content = { + 0x55, 0x00, 0x00, + }, + .content_len = 3, + .der = { + 0x06, 0x03, 0x55, 0x00, 0x00, + }, + .der_len = 5, + }, + { + .oid = "0.0.0.0", + .txt = "0.0.0.0", + .content = { + 0x00, 0x00, 0x00, + }, + .content_len = 3, + .der = { + 0x06, 0x03, 0x00, 0x00, 0x00, + }, + .der_len = 5, + }, + { + .oid = "1.3.6.1.4.1.11129.2.4.5", + .txt = "CT Certificate SCTs", + .content = { + 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, + 0x04, 0x05, + }, + .content_len = 10, + .der = { + 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, + 0x79, 0x02, 0x04, 0x05, + }, + .der_len = 12, + }, + { + .oid = "2.00005.0000000000004.10", + .want_error = ASN1_R_INVALID_NUMBER, + }, + { + .oid = "2..5.4.10", + .want_error = ASN1_R_INVALID_NUMBER, + }, + { + .oid = "2.5..4.10", + .want_error = ASN1_R_INVALID_NUMBER, + }, + { + .oid = "2.5.4..10", + .want_error = ASN1_R_INVALID_NUMBER, + }, + { + .oid = "2.5.4.10.", + .want_error = ASN1_R_INVALID_NUMBER, + }, + { + .oid = "3.5.4.10", + .want_error = ASN1_R_FIRST_NUM_TOO_LARGE, + }, + { + .oid = "0.40.4.10", + .want_error = ASN1_R_SECOND_NUMBER_TOO_LARGE, + }, + { + .oid = "1.40.4.10", + .want_error = ASN1_R_SECOND_NUMBER_TOO_LARGE, + }, + { + .oid = "2", + .want_error = ASN1_R_MISSING_SECOND_NUMBER, + }, + { + .oid = "2.5 4.10", + .want_error = ASN1_R_INVALID_SEPARATOR, + }, + { + .oid = "2,5,4,10", + .want_error = ASN1_R_INVALID_SEPARATOR, + }, + { + .oid = "2.5,4.10", + .want_error = ASN1_R_INVALID_DIGIT, + }, + { + .oid = "2a.5.4.10", + .want_error = ASN1_R_INVALID_SEPARATOR, + }, + { + .oid = "2.5a.4.10", + .want_error = ASN1_R_INVALID_DIGIT, + }, +}; + +#define N_ASN1_OBJECT_TESTS \ + (sizeof(asn1_object_tests) / sizeof(*asn1_object_tests)) + +static int +do_asn1_object_test(struct asn1_object_test *aot) +{ + ASN1_OBJECT *aobj = NULL; + uint8_t buf[1024]; + const uint8_t *p; + uint8_t *q; + int err, ret; + int failed = 1; + + ERR_clear_error(); + + ret = a2d_ASN1_OBJECT(NULL, 0, aot->oid, -1); + if (ret < 0 || (size_t)ret != aot->content_len) { + fprintf(stderr, "FAIL: a2d_ASN1_OBJECT('%s') = %d, want %zu\n", + aot->oid, ret, aot->content_len); + goto failed; + } + ret = a2d_ASN1_OBJECT(buf, sizeof(buf), aot->oid, -1); + if (ret < 0 || (size_t)ret != aot->content_len) { + fprintf(stderr, "FAIL: a2d_ASN1_OBJECT('%s') = %d, want %zu\n", + aot->oid, ret, aot->content_len); + goto failed; + } + if (aot->content_len == 0) { + err = ERR_peek_error(); + if (ERR_GET_REASON(err) != aot->want_error) { + fprintf(stderr, "FAIL: a2d_ASN1_OBJECT('%s') - got " + "error reason %d, want %d\n", aot->oid, + ERR_GET_REASON(err), aot->want_error); + goto failed; + } + goto done; + } + + if (!asn1_compare_bytes("ASN1_OBJECT content", buf, ret, aot->content, + aot->content_len)) + goto failed; + + p = aot->content; + if ((aobj = c2i_ASN1_OBJECT(NULL, &p, aot->content_len)) == NULL) { + fprintf(stderr, "FAIL: c2i_ASN1_OBJECT() failed\n"); + goto failed; + } + + q = buf; + ret = i2d_ASN1_OBJECT(aobj, &q); + if (!asn1_compare_bytes("ASN1_OBJECT DER", buf, ret, aot->der, + aot->der_len)) + goto failed; + + ASN1_OBJECT_free(aobj); + aobj = NULL; + + p = aot->der; + if ((aobj = d2i_ASN1_OBJECT(NULL, &p, aot->der_len)) == NULL) { + fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed\n"); + goto failed; + } + if (p != aot->der + aot->der_len) { + fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() p = %p, want %p\n", + p, aot->der + aot->der_len); + goto failed; + } + + if (aot->txt != NULL) { + ret = i2t_ASN1_OBJECT(buf, sizeof(buf), aobj); + if (ret <= 0 || (size_t)ret >= sizeof(buf)) { + fprintf(stderr, "FAIL: i2t_ASN1_OBJECT() failed\n"); + goto failed; + } + if (strcmp(aot->txt, buf) != 0) { + fprintf(stderr, "FAIL: i2t_ASN1_OBJECT() = '%s', " + "want '%s'\n", buf, aot->txt); + goto failed; + } + } + + done: + failed = 0; + + failed: + ASN1_OBJECT_free(aobj); + + return failed; +} + +static int +asn1_object_test(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_ASN1_OBJECT_TESTS; i++) + failed |= do_asn1_object_test(&asn1_object_tests[i]); + + return failed; +} + +const uint8_t asn1_object_bad_content1[] = { + 0x55, 0x80, 0x04, 0x0a, +}; +const uint8_t asn1_object_bad_content2[] = { + 0x55, 0x04, 0x8a, +}; + +static int +asn1_object_bad_content_test(void) +{ + ASN1_OBJECT *aobj = NULL; + const uint8_t *p; + size_t len; + int failed = 1; + + p = asn1_object_bad_content1; + len = sizeof(asn1_object_bad_content1); + if ((aobj = c2i_ASN1_OBJECT(NULL, &p, len)) != NULL) { + fprintf(stderr, "FAIL: c2i_ASN1_OBJECT() succeeded with bad " + "content 1\n"); + goto failed; + } + + p = asn1_object_bad_content2; + len = sizeof(asn1_object_bad_content2); + if ((aobj = c2i_ASN1_OBJECT(NULL, &p, len)) != NULL) { + fprintf(stderr, "FAIL: c2i_ASN1_OBJECT() succeeded with bad " + "content 2\n"); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(aobj); + + return failed; +} + +static int +asn1_object_txt_test(void) +{ + const char *obj_txt = "organizationName"; + ASN1_OBJECT *aobj = NULL; + uint8_t small_buf[2]; + const uint8_t *p; + int err, len, ret; + BIO *bio = NULL; + char *data; + long data_len; + int failed = 1; + + ERR_clear_error(); + + ret = a2d_ASN1_OBJECT(small_buf, sizeof(small_buf), "1.2.3.4", -1); + if (ret != 0) { + fprintf(stderr, "FAIL: a2d_ASN1_OBJECT() with small buffer " + "returned %d, want %d\n", ret, 0); + goto failed; + } + err = ERR_peek_error(); + if (ERR_GET_REASON(err) != ASN1_R_BUFFER_TOO_SMALL) { + fprintf(stderr, "FAIL: Got error reason %d, want %d\n", + ERR_GET_REASON(err), ASN1_R_BUFFER_TOO_SMALL); + goto failed; + } + + p = &asn1_object_tests[2].der[0]; + len = asn1_object_tests[2].der_len; + aobj = d2i_ASN1_OBJECT(NULL, &p, len); + if (aobj == NULL) { + fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed\n"); + goto failed; + } + ret = i2t_ASN1_OBJECT(small_buf, sizeof(small_buf), aobj); + if (ret < 0 || (unsigned long)ret != strlen(obj_txt)) { + fprintf(stderr, "FAIL: i2t_ASN1_OBJECT() with small buffer " + "returned %d, want %zu\n", ret, strlen(obj_txt)); + goto failed; + } + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "FAIL: BIO_new() returned NULL\n"); + goto failed; + } + ret = i2a_ASN1_OBJECT(bio, NULL); + if (ret != 4) { + fprintf(stderr, "FAIL: i2a_ASN1_OBJECT(_, NULL) returned %d, " + "want 4\n", ret); + goto failed; + } + data_len = BIO_get_mem_data(bio, &data); + if (ret != data_len || memcmp("NULL", data, data_len) != 0) { + fprintf(stderr, "FAIL: i2a_ASN1_OBJECT(_, NULL) did not return " + "'NULL'\n"); + goto failed; + } + + if ((ret = BIO_reset(bio)) <= 0) { + fprintf(stderr, "FAIL: BIO_reset failed: ret = %d\n", ret); + goto failed; + } + ret = i2a_ASN1_OBJECT(bio, aobj); + if (ret < 0 || (unsigned long)ret != strlen(obj_txt)) { + fprintf(stderr, "FAIL: i2a_ASN1_OBJECT() returned %d, " + "want %zu\n", ret, strlen(obj_txt)); + goto failed; + } + data_len = BIO_get_mem_data(bio, &data); + if (ret != data_len || memcmp(obj_txt, data, data_len) != 0) { + fprintf(stderr, "FAIL: i2a_ASN1_OBJECT() did not return " + "'%s'\n", obj_txt); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(aobj); + BIO_free(bio); + + return failed; +} + +const uint8_t asn1_large_oid_der[] = { + 0x06, 0x26, + 0x2b, 0x8f, 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, 0xff, 0xff, 0xff, 0x7f, +}; + +static int +asn1_object_large_oid_test(void) +{ + ASN1_OBJECT *aobj = NULL; + uint8_t buf[1024]; + const uint8_t *p; + uint8_t *q; + int ret; + int failed = 1; + + failed = 0; + + p = asn1_large_oid_der; + aobj = d2i_ASN1_OBJECT(NULL, &p, sizeof(asn1_large_oid_der)); + if (aobj == NULL) { + fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed with " + "large oid\n"); + goto failed; + } + + q = buf; + ret = i2d_ASN1_OBJECT(aobj, &q); + if (!asn1_compare_bytes("ASN1_OBJECT DER", buf, ret, asn1_large_oid_der, + sizeof(asn1_large_oid_der))) + goto failed; + + failed: + ASN1_OBJECT_free(aobj); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= asn1_object_test(); + failed |= asn1_object_bad_content_test(); + failed |= asn1_object_txt_test(); + failed |= asn1_object_large_oid_test(); + + return (failed); +} diff --git a/Libraries/libressl/tests/asn1oct.c b/Libraries/libressl/tests/asn1oct.c new file mode 100644 index 000000000..d989d1e6e --- /dev/null +++ b/Libraries/libressl/tests/asn1oct.c @@ -0,0 +1,280 @@ +/* $OpenBSD: asn1oct.c,v 1.4 2023/05/13 07:17:32 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#define TESTBUFFER_SIZE 20 + +static const struct i2s_asn1_octet_string_test { + const char *desc; + const uint8_t buf[TESTBUFFER_SIZE]; + long len; + const char *want; +} i2s_test[] = { + { + .desc = "Empty buffer gives empty string", + .buf = { 0x00, }, + .len = 0, + .want = "", + }, + { + .desc = "all hex digits", + .buf = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, }, + .len = 8, + .want = "01:23:45:67:89:AB:CD:EF", + }, + { + .desc = "all hex digits, scrambled", + .buf = { 0x98, 0x24, 0xbf, 0x3a, 0xc7, 0xd6, 0x01, 0x5e, }, + .len = 8, + .want = "98:24:BF:3A:C7:D6:01:5E", + }, + { + .desc = "Embedded 0 byte", + .buf = { 0x7a, 0x00, 0xbb, }, + .len = 3, + .want = "7A:00:BB", + }, + { + .desc = "All zeroes", + .buf = { 0x00, 0x00, 0x00, 0x00, 0x00, }, + .len = 4, + .want = "00:00:00:00", + }, + { + .desc = "All bits set", + .buf = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, + .len = 8, + .want = "FF:FF:FF:FF:FF:FF:FF:FF", + }, + { + .desc = "negative length", + .buf = { 0x00, }, + .len = -1, + }, +}; + +#define N_I2S_TESTS (sizeof(i2s_test) / sizeof(i2s_test[0])) + +static int +test_i2s_ASN1_OCTET_STRING(const struct i2s_asn1_octet_string_test *test) +{ + ASN1_OCTET_STRING *aos = NULL; + int should_fail = test->want == NULL; + char *got = NULL; + int failed = 0; + + if ((aos = ASN1_OCTET_STRING_new()) == NULL) + errx(1, "ASN1_OCTET_STRING_new"); + + if (!ASN1_STRING_set(aos, (void *)test->buf, test->len)) + errx(1, "ASN1_STRING_set"); + + if ((got = i2s_ASN1_OCTET_STRING(NULL, aos)) == NULL) { + if (!should_fail) + errx(1, "i2s_ASN1_OCTET_STRING"); + } + + if (!should_fail && strcmp(test->want, got) != 0) { + fprintf(stderr, "%s: \"%s\" failed: want \"%s\", got \"%s\"\n", + __func__, test->desc, test->want, got); + failed |= 1; + } + + ASN1_OCTET_STRING_free(aos); + free(got); + + return failed; +} + +static int +test_new_ASN1_OCTET_STRING(void) +{ + ASN1_OCTET_STRING *aos = NULL; + char *got; + int failed = 0; + + if ((aos = ASN1_OCTET_STRING_new()) == NULL) + errx(1, "%s: ASN1_OCTET_STRING_new", __func__); + if ((got = i2s_ASN1_OCTET_STRING(NULL, aos)) == NULL) + errx(1, "%s: i2s_ASN1_OCTET_STRING", __func__); + + if (strcmp("", got) != 0) { + fprintf(stderr, "%s failed: want \"\", got \"%s\"\n", + __func__, got); + failed |= 1; + } + + ASN1_OCTET_STRING_free(aos); + free(got); + + return failed; +} + +static int +run_i2s_ASN1_OCTET_STRING_tests(void) +{ + size_t i; + int failed = 0; + + failed |= test_new_ASN1_OCTET_STRING(); + + for (i = 0; i < N_I2S_TESTS; i++) + failed |= test_i2s_ASN1_OCTET_STRING(&i2s_test[i]); + + return failed; +} + +static const struct s2i_asn1_octet_string_test { + const char *desc; + const char *in; + const char *want; +} s2i_test[] = { + /* Tests that should succeed. */ + { + .desc = "empty string", + .in = "", + .want = "", + }, + { + .desc = "only colons", + .in = ":::::::", + .want = "", + }, + { + .desc = "a 0 octet", + .in = "00", + .want = "00", + }, + { + .desc = "a 0 octet with stupid colons", + .in = ":::00:::::", + .want = "00", + }, + { + .desc = "more stupid colons", + .in = ":::C0fF::Ee:::::", + .want = "C0:FF:EE", + }, + { + .desc = "all hex digits", + .in = "0123456789abcdef", + .want = "01:23:45:67:89:AB:CD:EF", + }, + + /* Tests that should fail. */ + { + .desc = "colons between hex digits", + .in = "A:F", + }, + { + .desc = "more colons between hex digits", + .in = "5:7", + }, + { + .desc = "one hex digit", + .in = "1", + }, + { + .desc = "three hex digits", + .in = "bad", + }, + { + .desc = "three hex digits, colon after first digit", + .in = "b:ad", + }, + { + .desc = "three hex digits, colon after second digit", + .in = "ba:d", + }, + { + .desc = "non-hex digit", + .in = "g00d", + }, + { + .desc = "non-hex digits", + .in = "d0gged", + }, + { + .desc = "trailing non-hex digit", + .in = "d00der", + }, +}; + +#define N_S2I_TESTS (sizeof(s2i_test) / sizeof(s2i_test[0])) + +static int +test_s2i_ASN1_OCTET_STRING(const struct s2i_asn1_octet_string_test *test) +{ + ASN1_OCTET_STRING *aos = NULL; + char *got = NULL; + int should_fail = test->want == NULL; + int failed = 0; + + if ((aos = s2i_ASN1_OCTET_STRING(NULL, NULL, test->in)) == NULL) { + if (!should_fail) + errx(1, "%s: s2i_ASN1_OCTET_STRING", test->desc); + goto done; + } + + if ((got = i2s_ASN1_OCTET_STRING(NULL, aos)) == NULL) + errx(1, "%s: i2s_ASN1_OCTET_STRING", test->desc); + + assert(test->want != NULL); + if (strcmp(test->want, got) != 0) { + fprintf(stderr, "%s: \"%s\" failed: want \"%s\", got \"%s\"\n", + __func__, test->desc, test->want, got); + failed |= 1; + } + + done: + ASN1_OCTET_STRING_free(aos); + free(got); + + return failed; +} + +static int +run_s2i_ASN1_OCTET_STRING_tests(void) +{ + size_t i; + int failed = 0; + + failed |= test_new_ASN1_OCTET_STRING(); + + for (i = 0; i < N_S2I_TESTS; i++) + failed |= test_s2i_ASN1_OCTET_STRING(&s2i_test[i]); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= run_i2s_ASN1_OCTET_STRING_tests(); + failed |= run_s2i_ASN1_OCTET_STRING_tests(); + + return failed; +} diff --git a/Libraries/libressl/tests/asn1string_copy.c b/Libraries/libressl/tests/asn1string_copy.c new file mode 100644 index 000000000..9c71dd08a --- /dev/null +++ b/Libraries/libressl/tests/asn1string_copy.c @@ -0,0 +1,119 @@ +/* $OpenBSD: asn1string_copy.c,v 1.1 2021/11/13 20:50:14 schwarze Exp $ */ +/* + * Copyright (c) 2021 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +int +main(void) +{ + const unsigned char *data = "hello world"; + const unsigned char *str; + ASN1_STRING *src, *dst; + int irc; + + /* Set up the source string. */ + + if ((src = ASN1_IA5STRING_new()) == NULL) + err(1, "FAIL: ASN1_IA5STRING_new() returned NULL"); + if (ASN1_STRING_set(src, data, -1) == 0) + err(1, "FAIL: ASN1_STRING_set(src) failed"); + if ((str = ASN1_STRING_get0_data(src)) == NULL) + errx(1, "FAIL: 1st ASN1_STRING_get0_data(src) returned NULL"); + if (strcmp(str, data)) + errx(1, "FAIL: 1st ASN1_STRING_get0_data(src) " + "returned wrong data: \"%s\" (expected \"%s\")", + str, data); + if ((irc = ASN1_STRING_length(src)) != (int)strlen(data)) + errx(1, "FAIL: 1st ASN1_STRING_length(src) " + "returned a wrong length: %d (expected %zu)", + irc, strlen(data)); + if ((irc = ASN1_STRING_type(src)) != V_ASN1_IA5STRING) + errx(1, "FAIL: 1st ASN1_STRING_type(src) " + "returned a wrong type: %d (expected %d)", + irc, V_ASN1_IA5STRING); + + /* Set up the destination string. */ + + if ((dst = ASN1_STRING_new()) == NULL) + err(1, "FAIL: ASN1_STRING_new() returned NULL"); + if ((str = ASN1_STRING_get0_data(dst)) != NULL) + errx(1, "FAIL: 1st ASN1_STRING_get0_data(dst) " + "returned \"%s\" (expected NULL)", str); + if ((irc = ASN1_STRING_length(dst)) != 0) + errx(1, "FAIL: 1st ASN1_STRING_length(dst) " + "returned a wrong length: %d (expected 0)", irc); + if ((irc = ASN1_STRING_type(dst)) != V_ASN1_OCTET_STRING) + errx(1, "FAIL: 1st ASN1_STRING_type(dst) " + "returned a wrong type: %d (expected %d)", + irc, V_ASN1_OCTET_STRING); + ASN1_STRING_length_set(dst, -1); + if ((str = ASN1_STRING_get0_data(dst)) != NULL) + errx(1, "FAIL: 2nd ASN1_STRING_get0_data(dst) " + "returned \"%s\" (expected NULL)", str); + if ((irc = ASN1_STRING_length(dst)) != -1) + errx(1, "FAIL: 2nd ASN1_STRING_length(dst) " + "returned a wrong length: %d (expected -1)", irc); + if ((irc = ASN1_STRING_type(dst)) != V_ASN1_OCTET_STRING) + errx(1, "FAIL: 2nd ASN1_STRING_type(dst) " + "returned a wrong type: %d (expected %d)", + irc, V_ASN1_OCTET_STRING); + + /* Attempt to copy in the wrong direction. */ + + if (ASN1_STRING_copy(src, dst) != 0) + errx(1, "FAIL: ASN1_STRING_copy unexpectedly succeeded"); + if ((str = ASN1_STRING_get0_data(src)) == NULL) + errx(1, "FAIL: 2nd ASN1_STRING_get0_data(src) returned NULL"); + if (strcmp(str, data)) + errx(1, "FAIL: 2nd ASN1_STRING_get0_data(src) " + "returned wrong data: \"%s\" (expected \"%s\")", + str, data); + if ((irc = ASN1_STRING_length(src)) != (int)strlen(data)) + errx(1, "FAIL: 2nd ASN1_STRING_length(src) " + "returned a wrong length: %d (expected %zu)", + irc, strlen(data)); + if ((irc = ASN1_STRING_type(src)) != V_ASN1_IA5STRING) + errx(1, "FAIL: 2nd ASN1_STRING_type(src) " + "returned a wrong type: %d (expected %d)", + irc, V_ASN1_IA5STRING); + + /* Copy in the right direction. */ + + if (ASN1_STRING_copy(dst, src) != 1) + err(1, "FAIL: ASN1_STRING_copy unexpectedly failed"); + if ((str = ASN1_STRING_get0_data(dst)) == NULL) + errx(1, "FAIL: 3rd ASN1_STRING_get0_data(dst) returned NULL"); + if (strcmp(str, data)) + errx(1, "FAIL: 3rd ASN1_STRING_get0_data(dst) " + "returned wrong data: \"%s\" (expected \"%s\")", + str, data); + if ((irc = ASN1_STRING_length(dst)) != (int)strlen(data)) + errx(1, "FAIL: 3rd ASN1_STRING_length(dst) " + "returned a wrong length: %d (expected %zu)", + irc, strlen(data)); + if ((irc = ASN1_STRING_type(dst)) != V_ASN1_IA5STRING) + errx(1, "FAIL: 3rd ASN1_STRING_type(dst) " + "returned a wrong type: %d (expected %d)", + irc, V_ASN1_IA5STRING); + + ASN1_STRING_free(src); + ASN1_STRING_free(dst); + return 0; +} diff --git a/Libraries/libressl/tests/asn1test.c b/Libraries/libressl/tests/asn1test.c new file mode 100644 index 000000000..6e9362b3e --- /dev/null +++ b/Libraries/libressl/tests/asn1test.c @@ -0,0 +1,478 @@ +/* $OpenBSD: asn1test.c,v 1.12 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2014, 2016 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +#include "ssl_local.h" + +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +X509 *peer_cert; + +unsigned char *peer_cert_pem = + "-----BEGIN CERTIFICATE-----\n" + "MIIBcTCCARugAwIBAgIJAPYhaZJAvUuUMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV\n" + "BAoMCVRlc3QgUGVlcjAeFw0xNjEyMjYxNDQ3NDdaFw0yNjEyMjQxNDQ3NDdaMBQx\n" + "EjAQBgNVBAoMCVRlc3QgUGVlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCyhAdJ\n" + "wojHv/uKONh8MbmR2U2+VF1HQusnLfSfHPqkJfvDzLWJ41TG7QcXkx2rIJVtAFrO\n" + "U9yNdFYJLA/hsrbjAgMBAAGjUDBOMB0GA1UdDgQWBBS3bZOw7fvaortdsdE2TPMq\n" + "IRXFRzAfBgNVHSMEGDAWgBS3bZOw7fvaortdsdE2TPMqIRXFRzAMBgNVHRMEBTAD\n" + "AQH/MA0GCSqGSIb3DQEBBQUAA0EAHsxNS+rNUZbopeDMhVIviOfUmelDjJrT56Rc\n" + "VJoFN3Gc1cV8nQAHm9aJs71uksC+MN04Pzh0WqmYX9XXrnYPcg==\n" + "-----END CERTIFICATE-----\n"; + +struct ssl_asn1_test { + SSL_SESSION session; + int peer_cert; + const unsigned char asn1[1024]; + int asn1_len; +}; + +unsigned char tlsext_tick[] = { + 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, + 0x2d, 0x30, 0x31, 0x36, 0x30, 0x3a, 0x20, 0x37, + 0x74, 0x68, 0x20, 0x41, 0x70, 0x72, 0x69, 0x6c, + 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, + 0x45, 0x2d, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x35, + 0x32, 0x39, 0x38, 0x3a, 0x20, 0x38, 0x74, 0x68, + 0x20, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32, + 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, + 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x31, 0x39, + 0x38, 0x3a, 0x20, 0x32, 0x31, 0x73, 0x74, 0x20, + 0x41, 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32, 0x30, + 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, + 0x30, 0x31, 0x34, 0x2d, 0x33, 0x34, 0x37, 0x30, + 0x3a, 0x20, 0x33, 0x30, 0x74, 0x68, 0x20, 0x4d, + 0x61, 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, + 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, + 0x2d, 0x30, 0x31, 0x39, 0x35, 0x3a, 0x20, 0x35, + 0x74, 0x68, 0x20, 0x4a, 0x75, 0x6e, 0x65, 0x20, + 0x32, 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, + 0x2d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x32, + 0x32, 0x31, 0x3a, 0x20, 0x35, 0x74, 0x68, 0x20, + 0x4a, 0x75, 0x6e, 0x65, 0x20, 0x32, 0x30, 0x31, + 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, + 0x31, 0x34, 0x2d, 0x30, 0x32, 0x32, 0x34, 0x3a, + 0x20, 0x35, 0x74, 0x68, 0x20, 0x4a, 0x75, 0x6e, + 0x65, 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, +}; + +struct ssl_asn1_test ssl_asn1_tests[] = { + { + .session = { + .cipher_id = 0x03000000L | 1, + .ssl_version = TLS1_2_VERSION, + }, + .asn1 = { + 0x30, 0x13, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03, + 0x03, 0x04, 0x02, 0x00, 0x01, 0x04, 0x00, 0x04, + 0x00, 0xa4, 0x02, 0x04, 0x00, + }, + .asn1_len = 21, + }, + { + .session = { + .cipher_id = 0x03000000L | 1, + .ssl_version = TLS1_2_VERSION, + .master_key_length = 26, + .session_id = "0123456789", + .session_id_length = 10, + .sid_ctx = "abcdefghijklmnopqrstuvwxyz", + .sid_ctx_length = 26, + }, + .asn1 = { + 0x30, 0x51, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03, + 0x03, 0x04, 0x02, 0x00, 0x01, 0x04, 0x0a, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x04, 0x1a, 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, 0xa4, 0x1c, 0x04, + 0x1a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, + }, + .asn1_len = 83, + }, + { + .session = { + .cipher_id = 0x03000000L | 1, + .ssl_version = TLS1_2_VERSION, + .master_key_length = 26, + .session_id = "0123456789", + .session_id_length = 10, + .sid_ctx = "abcdefghijklmnopqrstuvwxyz", + .sid_ctx_length = 26, + .time = 1405266069, + .timeout = 5, + .verify_result = 42, + .tlsext_hostname = "libressl.openbsd.org", + .tlsext_tick_lifetime_hint = 0x7abbccdd, + .tlsext_tick = tlsext_tick, + .tlsext_ticklen = sizeof(tlsext_tick), + }, + .peer_cert = 1, + .asn1 = { + 0x30, 0x82, 0x02, 0xd1, 0x02, 0x01, 0x01, 0x02, + 0x02, 0x03, 0x03, 0x04, 0x02, 0x00, 0x01, 0x04, + 0x0a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x04, 0x1a, 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, 0xa1, + 0x06, 0x02, 0x04, 0x53, 0xc2, 0xa8, 0x95, 0xa2, + 0x03, 0x02, 0x01, 0x05, 0xa3, 0x82, 0x01, 0x75, + 0x30, 0x82, 0x01, 0x71, 0x30, 0x82, 0x01, 0x1b, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, + 0xf6, 0x21, 0x69, 0x92, 0x40, 0xbd, 0x4b, 0x94, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, + 0x20, 0x50, 0x65, 0x65, 0x72, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x36, 0x31, 0x32, 0x32, 0x36, 0x31, + 0x34, 0x34, 0x37, 0x34, 0x37, 0x5a, 0x17, 0x0d, + 0x32, 0x36, 0x31, 0x32, 0x32, 0x34, 0x31, 0x34, + 0x34, 0x37, 0x34, 0x37, 0x5a, 0x30, 0x14, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, + 0x65, 0x65, 0x72, 0x30, 0x5c, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, + 0x48, 0x02, 0x41, 0x00, 0xb2, 0x84, 0x07, 0x49, + 0xc2, 0x88, 0xc7, 0xbf, 0xfb, 0x8a, 0x38, 0xd8, + 0x7c, 0x31, 0xb9, 0x91, 0xd9, 0x4d, 0xbe, 0x54, + 0x5d, 0x47, 0x42, 0xeb, 0x27, 0x2d, 0xf4, 0x9f, + 0x1c, 0xfa, 0xa4, 0x25, 0xfb, 0xc3, 0xcc, 0xb5, + 0x89, 0xe3, 0x54, 0xc6, 0xed, 0x07, 0x17, 0x93, + 0x1d, 0xab, 0x20, 0x95, 0x6d, 0x00, 0x5a, 0xce, + 0x53, 0xdc, 0x8d, 0x74, 0x56, 0x09, 0x2c, 0x0f, + 0xe1, 0xb2, 0xb6, 0xe3, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xb7, 0x6d, 0x93, 0xb0, 0xed, 0xfb, 0xda, 0xa2, + 0xbb, 0x5d, 0xb1, 0xd1, 0x36, 0x4c, 0xf3, 0x2a, + 0x21, 0x15, 0xc5, 0x47, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0xb7, 0x6d, 0x93, 0xb0, 0xed, 0xfb, 0xda, + 0xa2, 0xbb, 0x5d, 0xb1, 0xd1, 0x36, 0x4c, 0xf3, + 0x2a, 0x21, 0x15, 0xc5, 0x47, 0x30, 0x0c, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x03, 0x41, 0x00, 0x1e, 0xcc, 0x4d, + 0x4b, 0xea, 0xcd, 0x51, 0x96, 0xe8, 0xa5, 0xe0, + 0xcc, 0x85, 0x52, 0x2f, 0x88, 0xe7, 0xd4, 0x99, + 0xe9, 0x43, 0x8c, 0x9a, 0xd3, 0xe7, 0xa4, 0x5c, + 0x54, 0x9a, 0x05, 0x37, 0x71, 0x9c, 0xd5, 0xc5, + 0x7c, 0x9d, 0x00, 0x07, 0x9b, 0xd6, 0x89, 0xb3, + 0xbd, 0x6e, 0x92, 0xc0, 0xbe, 0x30, 0xdd, 0x38, + 0x3f, 0x38, 0x74, 0x5a, 0xa9, 0x98, 0x5f, 0xd5, + 0xd7, 0xae, 0x76, 0x0f, 0x72, 0xa4, 0x1c, 0x04, + 0x1a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0xa5, 0x03, 0x02, 0x01, 0x2a, + 0xa6, 0x16, 0x04, 0x14, 0x6c, 0x69, 0x62, 0x72, + 0x65, 0x73, 0x73, 0x6c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x62, 0x73, 0x64, 0x2e, 0x6f, 0x72, 0x67, + 0xa9, 0x06, 0x02, 0x04, 0x7a, 0xbb, 0xcc, 0xdd, + 0xaa, 0x81, 0xd2, 0x04, 0x81, 0xcf, 0x43, 0x56, + 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, + 0x31, 0x36, 0x30, 0x3a, 0x20, 0x37, 0x74, 0x68, + 0x20, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32, + 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, + 0x32, 0x30, 0x31, 0x30, 0x2d, 0x35, 0x32, 0x39, + 0x38, 0x3a, 0x20, 0x38, 0x74, 0x68, 0x20, 0x41, + 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32, 0x30, 0x31, + 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, + 0x31, 0x34, 0x2d, 0x30, 0x31, 0x39, 0x38, 0x3a, + 0x20, 0x32, 0x31, 0x73, 0x74, 0x20, 0x41, 0x70, + 0x72, 0x69, 0x6c, 0x20, 0x32, 0x30, 0x31, 0x34, + 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, + 0x34, 0x2d, 0x33, 0x34, 0x37, 0x30, 0x3a, 0x20, + 0x33, 0x30, 0x74, 0x68, 0x20, 0x4d, 0x61, 0x79, + 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, + 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, + 0x31, 0x39, 0x35, 0x3a, 0x20, 0x35, 0x74, 0x68, + 0x20, 0x4a, 0x75, 0x6e, 0x65, 0x20, 0x32, 0x30, + 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, + 0x30, 0x31, 0x34, 0x2d, 0x30, 0x32, 0x32, 0x31, + 0x3a, 0x20, 0x35, 0x74, 0x68, 0x20, 0x4a, 0x75, + 0x6e, 0x65, 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, + 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, + 0x2d, 0x30, 0x32, 0x32, 0x34, 0x3a, 0x20, 0x35, + 0x74, 0x68, 0x20, 0x4a, 0x75, 0x6e, 0x65, 0x20, + 0x32, 0x30, 0x31, 0x34, 0x0a, + }, + .asn1_len = 725, + }, + { + .session = { + .cipher_id = 0x03000000L | 1, + .ssl_version = TLS1_2_VERSION, + .timeout = -1, + }, + .asn1 = { + 0x0, + }, + .asn1_len = -1, + }, + { + .session = { + .cipher_id = 0x03000000L | 1, + .ssl_version = TLS1_2_VERSION, + .time = -1, + }, + .asn1 = { + 0x0, + }, + .asn1_len = -1, + }, +}; + +#define N_SSL_ASN1_TESTS \ + (sizeof(ssl_asn1_tests) / sizeof(*ssl_asn1_tests)) + +static int +session_strcmp(const unsigned char *o1, const unsigned char *o2, size_t len) +{ + if (o1 == NULL && o2 == NULL) + return (0); + if (o1 == NULL || o2 == NULL) + return (1); + return memcmp(o1, o2, len); +} + +static int +session_cmp(SSL_SESSION *s1, SSL_SESSION *s2) +{ + /* Compare the ASN.1 encoded values from two sessions. */ + if (s1->ssl_version != s2->ssl_version) { + fprintf(stderr, "ssl_version differs: %d != %d\n", + s1->ssl_version, s2->ssl_version); + return (1); + } + if (s1->cipher_id != s2->cipher_id) { + fprintf(stderr, "cipher_id differs: %ld != %ld\n", + s1->cipher_id, s2->cipher_id); + return (1); + } + + if (s1->master_key_length != s2->master_key_length) { + fprintf(stderr, "master_key_length differs: %zu != %zu\n", + s1->master_key_length, s2->master_key_length); + return (1); + } + if (session_strcmp(s1->master_key, s2->master_key, + s1->master_key_length) != 0) { + fprintf(stderr, "master_key differs\n"); + return (1); + } + + if (s1->session_id_length != s2->session_id_length) { + fprintf(stderr, "session_id_length differs: %zu != %zu\n", + s1->session_id_length, s2->session_id_length); + return (1); + } + if (session_strcmp(s1->session_id, s2->session_id, + s1->session_id_length) != 0) { + fprintf(stderr, "session_id differs\n"); + return (1); + } + + if (s1->sid_ctx_length != s2->sid_ctx_length) { + fprintf(stderr, "sid_ctx_length differs: %zu != %zu\n", + s1->sid_ctx_length, s2->sid_ctx_length); + return (1); + } + if (session_strcmp(s1->sid_ctx, s2->sid_ctx, + s1->sid_ctx_length) != 0) { + fprintf(stderr, "sid_ctx differs\n"); + return (1); + } + + /* d2i_SSL_SESSION uses the current time if decoding a zero value. */ + if ((s1->time != s2->time) && s1->time != 0 && s2->time != 0) { + fprintf(stderr, "time differs: %lld != %lld\n", + (long long)s1->time, (long long)s2->time); + return (1); + } + /* d2i_SSL_SESSION uses a timeout of 3 if decoding a zero value. */ + if ((s1->timeout != s2->timeout) && + s1->timeout != 3 && s2->timeout != 3) { + fprintf(stderr, "timeout differs: %ld != %ld\n", + s1->timeout, s2->timeout); + return (1); + } + + /* Ensure that a certificate is or is not present in both. */ + if ((s1->peer_cert != NULL || s2->peer_cert != NULL) && + (s1->peer_cert == NULL || s2->peer_cert == NULL || + X509_cmp(s1->peer_cert, s2->peer_cert) != 0)) { + fprintf(stderr, "peer_cert differs\n"); + return (1); + } + + if (s1->verify_result != s2->verify_result) { + fprintf(stderr, "verify_result differs: %ld != %ld\n", + s1->verify_result, s2->verify_result); + return (1); + } + + if (session_strcmp(s1->tlsext_hostname, s2->tlsext_hostname, + (s1->tlsext_hostname ? strlen(s1->tlsext_hostname) : 0)) != 0) { + fprintf(stderr, "sid_ctx differs\n"); + return (1); + } + if (s1->tlsext_tick_lifetime_hint != s2->tlsext_tick_lifetime_hint) { + fprintf(stderr, "tlsext_tick_lifetime_hint differs: " + "%u != %u\n", s1->tlsext_tick_lifetime_hint, + s2->tlsext_tick_lifetime_hint); + return (1); + } + if (s1->tlsext_ticklen != s2->tlsext_ticklen) { + fprintf(stderr, "tlsext_ticklen differs: %zu != %zu\n", + s1->tlsext_ticklen, s2->tlsext_ticklen); + return (1); + } + if (session_strcmp(s1->tlsext_tick, s2->tlsext_tick, + s1->tlsext_ticklen) != 0) { + fprintf(stderr, "tlsext_tick differs\n"); + return (1); + } + + return (0); +} + +static int +do_ssl_asn1_test(int test_no, struct ssl_asn1_test *sat) +{ + SSL_SESSION *sp = NULL; + unsigned char *ap, *asn1 = NULL; + const unsigned char *pp; + int i, len, rv = 1; + + if (sat->peer_cert) + sat->session.peer_cert = peer_cert; + + len = i2d_SSL_SESSION(&sat->session, NULL); + if (len != sat->asn1_len) { + fprintf(stderr, "FAIL: test %d returned ASN1 length %d, " + "want %d\n", test_no, len, sat->asn1_len); + goto failed; + } + + /* See if the test is expected to fail... */ + if (sat->asn1_len == -1) + return (0); + + if ((asn1 = malloc(len)) == NULL) + errx(1, "failed to allocate memory"); + + ap = asn1; + len = i2d_SSL_SESSION(&sat->session, &ap); + + /* Check the length again since the code path is different. */ + if (len != sat->asn1_len) { + fprintf(stderr, "FAIL: test %d returned ASN1 length %d, " + "want %d\n", test_no, len, sat->asn1_len); + goto failed; + } + /* ap should now point at the end of the buffer. */ + if (ap - asn1 != len) { + fprintf(stderr, "FAIL: test %d pointer increment does not " + "match length (%d != %d)\n", test_no, (int)(ap - asn1), len); + goto failed; + } + + if (memcmp(asn1, &sat->asn1, len) != 0) { + fprintf(stderr, "FAIL: test %d - encoding differs:\n", test_no); + fprintf(stderr, "encoding:\n"); + for (i = 1; i <= len; i++) { + fprintf(stderr, " 0x%02hhx,", asn1[i - 1]); + if (i % 8 == 0) + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + fprintf(stderr, "test data:\n"); + for (i = 1; i <= sat->asn1_len; i++) { + fprintf(stderr, " 0x%02hhx,", sat->asn1[i - 1]); + if (i % 8 == 0) + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + goto failed; + } + + pp = sat->asn1; + + if ((sp = d2i_SSL_SESSION(NULL, &pp, sat->asn1_len)) == NULL) { + fprintf(stderr, "FAIL: test %d - decoding failed\n", test_no); + goto failed; + } + + if (session_cmp(sp, &sat->session) != 0) { + fprintf(stderr, "FAIL: test %d - decoding differs\n", test_no); + goto failed; + } + + rv = 0; + + failed: + ERR_print_errors_fp(stderr); + SSL_SESSION_free(sp); + free(asn1); + + return (rv); +} + +int +main(int argc, char **argv) +{ + BIO *bio = NULL; + int failed = 0; + size_t i; + + SSL_library_init(); + SSL_load_error_strings(); + + bio = BIO_new_mem_buf(peer_cert_pem, -1); + if (bio == NULL) + errx(1, "failed to create bio"); + + peer_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); + if (peer_cert == NULL) + errx(1, "failed to read peer cert"); + + for (i = 0; i < N_SSL_ASN1_TESTS; i++) + failed += do_ssl_asn1_test(i, &ssl_asn1_tests[i]); + + X509_free(peer_cert); + BIO_free(bio); + + return (failed); +} diff --git a/Libraries/libressl/tests/asn1time.c b/Libraries/libressl/tests/asn1time.c new file mode 100644 index 000000000..bb58f6172 --- /dev/null +++ b/Libraries/libressl/tests/asn1time.c @@ -0,0 +1,611 @@ +/* $OpenBSD: asn1time.c,v 1.20 2023/10/02 11:14:15 tb Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +struct asn1_time_test { + const char *str; + const char *data; + const unsigned char der[32]; + time_t time; +}; + +static const struct asn1_time_test asn1_invtime_tests[] = { + { + .str = "", + }, + { + .str = "2015", + }, + { + .str = "201509", + }, + { + .str = "20150923", + }, + { + .str = "20150923032700", + }, + { + .str = "20150923032700.Z", + }, + { + .str = "20150923032700.123", + }, + { + .str = "20150923032700+1.09", + }, + { + .str = "20150923032700+1100Z", + }, + { + .str = "20150923032700-11001", + }, + { + /* UTC time cannot have fractional seconds. */ + .str = "150923032700.123Z", + }, + { + .str = "aaaaaaaaaaaaaaZ", + }, + /* utc time with omitted seconds, should fail */ + { + .str = "1609082343Z", + }, +}; + +static const struct asn1_time_test asn1_invgentime_tests[] = { + /* Generalized time with omitted seconds, should fail */ + { + .str = "201612081934Z", + }, + /* Valid UTC time, should fail as a generalized time */ + { + .str = "160908234300Z", + }, +}; + +static const struct asn1_time_test asn1_gentime_tests[] = { + { + .str = "20161208193400Z", + .data = "20161208193400Z", + .time = 1481225640, + .der = { + 0x18, 0x0f, 0x32, 0x30, 0x31, 0x36, 0x31, 0x32, + 0x30, 0x38, 0x31, 0x39, 0x33, 0x34, 0x30, 0x30, + 0x5a, + }, + }, + { + .str = "19700101000000Z", + .data = "19700101000000Z", + .time = 0, + .der = { + 0x18, 0x0f, 0x31, 0x39, 0x37, 0x30, 0x30, 0x31, + 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5a, + }, + }, + { + .str = "20150923032700Z", + .data = "20150923032700Z", + .time = 1442978820, + .der = { + 0x18, 0x0f, 0x32, 0x30, 0x31, 0x35, 0x30, 0x39, + 0x32, 0x33, 0x30, 0x33, 0x32, 0x37, 0x30, 0x30, + 0x5a, + }, + }, +}; + +static const struct asn1_time_test asn1_utctime_tests[] = { + { + .str = "700101000000Z", + .data = "700101000000Z", + .time = 0, + .der = { + 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + }, + }, + { + .str = "150923032700Z", + .data = "150923032700Z", + .time = 1442978820, + .der = { + 0x17, 0x0d, 0x31, 0x35, 0x30, 0x39, 0x32, 0x33, + 0x30, 0x33, 0x32, 0x37, 0x30, 0x30, 0x5a, + }, + }, + { + .str = "140524144512Z", + .data = "140524144512Z", + .time = 1400942712, + .der = { + 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x32, 0x34, + 0x31, 0x34, 0x34, 0x35, 0x31, 0x32, 0x5a, + }, + }, + { + .str = "240401144512Z", + .data = "240401144512Z", + .time = 1711982712, + .der = { + 0x17, 0x0d, 0x32, 0x34, 0x30, 0x34, 0x30, 0x31, + 0x31, 0x34, 0x34, 0x35, 0x31, 0x32, 0x5a + }, + }, +}; + +#define N_INVTIME_TESTS \ + (sizeof(asn1_invtime_tests) / sizeof(*asn1_invtime_tests)) +#define N_INVGENTIME_TESTS \ + (sizeof(asn1_invgentime_tests) / sizeof(*asn1_invgentime_tests)) +#define N_GENTIME_TESTS \ + (sizeof(asn1_gentime_tests) / sizeof(*asn1_gentime_tests)) +#define N_UTCTIME_TESTS \ + (sizeof(asn1_utctime_tests) / sizeof(*asn1_utctime_tests)) + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +asn1_compare_bytes(int test_no, const unsigned char *d1, + const unsigned char *d2, int len1, int len2) +{ + if (len1 != len2) { + fprintf(stderr, "FAIL: test %d - byte lengths differ " + "(%d != %d)\n", test_no, len1, len2); + return (1); + } + if (memcmp(d1, d2, len1) != 0) { + fprintf(stderr, "FAIL: test %d - bytes differ\n", test_no); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return (1); + } + return (0); +} + +static int +asn1_compare_str(int test_no, const struct asn1_string_st *asn1str, + const char *str) +{ + int length = strlen(str); + + if (asn1str->length != length) { + fprintf(stderr, "FAIL: test %d - string lengths differ " + "(%d != %d)\n", test_no, asn1str->length, length); + return (1); + } + if (strncmp(asn1str->data, str, length) != 0) { + fprintf(stderr, "FAIL: test %d - strings differ " + "('%s' != '%s')\n", test_no, asn1str->data, str); + return (1); + } + + return (0); +} + +static int +asn1_invtime_test(int test_no, const struct asn1_time_test *att, int gen) +{ + ASN1_GENERALIZEDTIME *gt = NULL; + ASN1_UTCTIME *ut = NULL; + ASN1_TIME *t = NULL; + int failure = 1; + + if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL) + goto done; + if ((ut = ASN1_UTCTIME_new()) == NULL) + goto done; + if ((t = ASN1_TIME_new()) == NULL) + goto done; + + if (ASN1_GENERALIZEDTIME_set_string(gt, att->str) != 0) { + fprintf(stderr, "FAIL: test %d - successfully set " + "GENERALIZEDTIME string '%s'\n", test_no, att->str); + goto done; + } + + if (gen) { + failure = 0; + goto done; + } + + if (ASN1_UTCTIME_set_string(ut, att->str) != 0) { + fprintf(stderr, "FAIL: test %d - successfully set UTCTIME " + "string '%s'\n", test_no, att->str); + goto done; + } + if (ASN1_TIME_set_string(t, att->str) != 0) { + fprintf(stderr, "FAIL: test %d - successfully set TIME " + "string '%s'\n", test_no, att->str); + goto done; + } + if (ASN1_TIME_set_string_X509(t, att->str) != 0) { + fprintf(stderr, "FAIL: test %d - successfully set x509 TIME " + "string '%s'\n", test_no, att->str); + goto done; + } + + failure = 0; + + done: + ASN1_GENERALIZEDTIME_free(gt); + ASN1_UTCTIME_free(ut); + ASN1_TIME_free(t); + + return (failure); +} + +static int +asn1_gentime_test(int test_no, const struct asn1_time_test *att) +{ + const unsigned char *der; + unsigned char *p = NULL; + ASN1_GENERALIZEDTIME *gt = NULL; + int failure = 1; + int len; + struct tm tm; + + if (ASN1_GENERALIZEDTIME_set_string(NULL, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + + if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL) + goto done; + + if (ASN1_GENERALIZEDTIME_set_string(gt, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + if (asn1_compare_str(test_no, gt, att->str) != 0) + goto done; + + if (ASN1_TIME_to_tm(gt, &tm) == 0) { + fprintf(stderr, "FAIL: test %d - ASN1_time_to_tm failed '%s'\n", + test_no, att->str); + goto done; + } + + if (timegm(&tm) != att->time) { + /* things with crappy time_t should die in fire */ + int64_t a = timegm(&tm); + int64_t b = att->time; + fprintf(stderr, "FAIL: test %d - times don't match, expected %lld got %lld\n", + test_no, (long long)b, (long long)a); + goto done; + } + + if ((len = i2d_ASN1_GENERALIZEDTIME(gt, &p)) <= 0) { + fprintf(stderr, "FAIL: test %d - i2d_ASN1_GENERALIZEDTIME " + "failed\n", test_no); + goto done; + } + der = att->der; + if (asn1_compare_bytes(test_no, p, der, len, strlen(der)) != 0) + goto done; + + len = strlen(att->der); + if (d2i_ASN1_GENERALIZEDTIME(>, &der, len) == NULL) { + fprintf(stderr, "FAIL: test %d - d2i_ASN1_GENERALIZEDTIME " + "failed\n", test_no); + goto done; + } + if (asn1_compare_str(test_no, gt, att->str) != 0) + goto done; + + ASN1_GENERALIZEDTIME_free(gt); + + if ((gt = ASN1_GENERALIZEDTIME_set(NULL, att->time)) == NULL) { + fprintf(stderr, "FAIL: test %d - failed to set time %lld\n", + test_no, (long long)att->time); + goto done; + } + if (asn1_compare_str(test_no, gt, att->data) != 0) + goto done; + + failure = 0; + + done: + ASN1_GENERALIZEDTIME_free(gt); + free(p); + + return (failure); +} + +static int +asn1_utctime_test(int test_no, const struct asn1_time_test *att) +{ + const unsigned char *der; + unsigned char *p = NULL; + ASN1_UTCTIME *ut = NULL; + int failure = 1; + int len; + + if (ASN1_UTCTIME_set_string(NULL, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + + if ((ut = ASN1_UTCTIME_new()) == NULL) + goto done; + + if (ASN1_UTCTIME_set_string(ut, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + if (asn1_compare_str(test_no, ut, att->str) != 0) + goto done; + + if ((len = i2d_ASN1_UTCTIME(ut, &p)) <= 0) { + fprintf(stderr, "FAIL: test %d - i2d_ASN1_UTCTIME failed\n", + test_no); + goto done; + } + der = att->der; + if (asn1_compare_bytes(test_no, p, der, len, strlen(der)) != 0) + goto done; + + len = strlen(att->der); + if (d2i_ASN1_UTCTIME(&ut, &der, len) == NULL) { + fprintf(stderr, "FAIL: test %d - d2i_ASN1_UTCTIME failed\n", + test_no); + goto done; + } + if (asn1_compare_str(test_no, ut, att->str) != 0) + goto done; + + ASN1_UTCTIME_free(ut); + + if ((ut = ASN1_UTCTIME_set(NULL, att->time)) == NULL) { + fprintf(stderr, "FAIL: test %d - failed to set time %lld\n", + test_no, (long long)att->time); + goto done; + } + if (asn1_compare_str(test_no, ut, att->data) != 0) + goto done; + + failure = 0; + + done: + ASN1_UTCTIME_free(ut); + free(p); + + return (failure); +} + +static int +asn1_time_test(int test_no, const struct asn1_time_test *att, int type) +{ + ASN1_TIME *t = NULL, *tx509 = NULL; + int failure = 1; + + if (ASN1_TIME_set_string(NULL, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + + if ((t = ASN1_TIME_new()) == NULL) + goto done; + + if ((tx509 = ASN1_TIME_new()) == NULL) + goto done; + + if (ASN1_TIME_set_string(t, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + + if (t->type != type) { + fprintf(stderr, "FAIL: test %d - got type %d, want %d\n", + test_no, t->type, type); + goto done; + } + + if (ASN1_TIME_normalize(t) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set normalize '%s'\n", + test_no, att->str); + goto done; + } + + if (ASN1_TIME_set_string_X509(tx509, t->data) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string X509 '%s'\n", + test_no, t->data); + goto done; + } + + if (t->type != tx509->type) { + fprintf(stderr, "FAIL: test %d - type %d, different from %d\n", + test_no, t->type, tx509->type); + goto done; + } + + if (ASN1_TIME_compare(t, tx509) != 0) { + fprintf(stderr, "FAIL: ASN1_TIME values differ!\n"); + goto done; + } + + + failure = 0; + + done: + + ASN1_TIME_free(t); + ASN1_TIME_free(tx509); + + return (failure); +} + +static int +time_t_cmp(time_t t1, time_t t2) +{ + if (t1 < t2) + return -1; + if (t2 < t1) + return 1; + return 0; +} + +static int +asn1_time_compare_families(const struct asn1_time_test *fam1, size_t fam1_size, + const struct asn1_time_test *fam2, size_t fam2_size) +{ + const struct asn1_time_test *att1, *att2; + ASN1_TIME *t1 = NULL, *t2 = NULL; + size_t i, j; + int asn1_cmp, time_cmp; + int comparison_failure = 0; + int failure = 1; + + if ((t1 = ASN1_TIME_new()) == NULL) + goto done; + if ((t2 = ASN1_TIME_new()) == NULL) + goto done; + + for (i = 0; i < fam1_size; i++) { + att1 = &fam1[i]; + + if (!ASN1_TIME_set_string(t1, att1->str)) + goto done; + for (j = 0; j < fam2_size; j++) { + att2 = &fam2[j]; + + if (!ASN1_TIME_set_string(t2, att2->str)) + goto done; + + time_cmp = time_t_cmp(att1->time, att2->time); + asn1_cmp = ASN1_TIME_compare(t1, t2); + + if (time_cmp != asn1_cmp) { + fprintf(stderr, "%s vs. %s: want %d, got %d\n", + att1->str, att2->str, time_cmp, asn1_cmp); + comparison_failure |= 1; + } + + time_cmp = ASN1_TIME_cmp_time_t(t1, att2->time); + if (time_cmp != asn1_cmp) { + fprintf(stderr, "%s vs. %lld: want %d, got %d\n", + att1->str, (long long)att2->time, + asn1_cmp, time_cmp); + comparison_failure |= 1; + } + + /* + * XXX - add ASN1_UTCTIME_cmp_time_t later. Don't want + * to mess with LIBRESSL_INTERNAL right before lock. + */ + } + } + + failure = comparison_failure; + + done: + ASN1_TIME_free(t1); + ASN1_TIME_free(t2); + + return failure; +} + +static int +asn1_time_compare_test(void) +{ + const struct asn1_time_test *gen = asn1_gentime_tests; + size_t gen_size = N_GENTIME_TESTS; + const struct asn1_time_test *utc = asn1_utctime_tests; + size_t utc_size = N_UTCTIME_TESTS; + int failed = 0; + + failed |= asn1_time_compare_families(gen, gen_size, gen, gen_size); + failed |= asn1_time_compare_families(gen, gen_size, utc, utc_size); + failed |= asn1_time_compare_families(utc, utc_size, gen, gen_size); + failed |= asn1_time_compare_families(utc, utc_size, utc, utc_size); + + return failed; +} + +int +main(int argc, char **argv) +{ + const struct asn1_time_test *att; + int failed = 0; + size_t i; + + fprintf(stderr, "Invalid time tests...\n"); + for (i = 0; i < N_INVTIME_TESTS; i++) { + att = &asn1_invtime_tests[i]; + failed |= asn1_invtime_test(i, att, 0); + } + + fprintf(stderr, "Invalid generalized time tests...\n"); + for (i = 0; i < N_INVGENTIME_TESTS; i++) { + att = &asn1_invgentime_tests[i]; + failed |= asn1_invtime_test(i, att, 1); + } + + fprintf(stderr, "GENERALIZEDTIME tests...\n"); + for (i = 0; i < N_GENTIME_TESTS; i++) { + att = &asn1_gentime_tests[i]; + failed |= asn1_gentime_test(i, att); + } + + fprintf(stderr, "UTCTIME tests...\n"); + for (i = 0; i < N_UTCTIME_TESTS; i++) { + att = &asn1_utctime_tests[i]; + failed |= asn1_utctime_test(i, att); + } + + fprintf(stderr, "TIME tests...\n"); + for (i = 0; i < N_UTCTIME_TESTS; i++) { + att = &asn1_utctime_tests[i]; + failed |= asn1_time_test(i, att, V_ASN1_UTCTIME); + } + for (i = 0; i < N_GENTIME_TESTS; i++) { + att = &asn1_gentime_tests[i]; + failed |= asn1_time_test(i, att, V_ASN1_GENERALIZEDTIME); + } + + fprintf(stderr, "ASN1_TIME_compare tests...\n"); + failed |= asn1_time_compare_test(); + + /* Check for a leak in ASN1_TIME_normalize(). */ + failed |= ASN1_TIME_normalize(NULL) != 0; + + return (failed); +} diff --git a/Libraries/libressl/tests/asn1x509.c b/Libraries/libressl/tests/asn1x509.c new file mode 100644 index 000000000..972b8290f --- /dev/null +++ b/Libraries/libressl/tests/asn1x509.c @@ -0,0 +1,842 @@ +/* $OpenBSD: asn1x509.c,v 1.5 2023/08/11 22:50:44 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *dsa_test_key = + "-----BEGIN DSA PRIVATE KEY-----\n" + "MIH5AgEAAkEAt+CNNryEe8t2SkjuP0azjOKjSMXsw3GzjLS5c+vFLQKs0zIuPp8F\n" + "I/z5t8vcNt/D8EyzQZWxgCfoasHqDOJvRwIVAKrJMyIMt9iJtaS31cyIJmIDVlZX\n" + "AkEAs1/Uy+x0+1C1n7V3eJxuBdO/LUalbrZM5PfcwDshf9kcQNLsRu5zTZkU0OX/\n" + "8xANz+ue2o6LON2sTAtuEfSM1QJBAIDRt0rQGGrFCRJ4O39Iqlf27yIO6Gq1ppbE\n" + "Wvsvz4YSIZsG02vlBlzVIhULftNnkpN59MFtIjx8RsbEQ4YTnSICFDXPf/UIRvdH\n" + "20NV++tnUZYUAXM+\n" + "-----END DSA PRIVATE KEY-----\n"; + +unsigned char dsa_test_asn1_pubkey[] = { + 0x30, 0x81, 0xf2, 0x30, 0x81, 0xa9, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01, 0x30, + 0x81, 0x9d, 0x02, 0x41, 0x00, 0xb7, 0xe0, 0x8d, + 0x36, 0xbc, 0x84, 0x7b, 0xcb, 0x76, 0x4a, 0x48, + 0xee, 0x3f, 0x46, 0xb3, 0x8c, 0xe2, 0xa3, 0x48, + 0xc5, 0xec, 0xc3, 0x71, 0xb3, 0x8c, 0xb4, 0xb9, + 0x73, 0xeb, 0xc5, 0x2d, 0x02, 0xac, 0xd3, 0x32, + 0x2e, 0x3e, 0x9f, 0x05, 0x23, 0xfc, 0xf9, 0xb7, + 0xcb, 0xdc, 0x36, 0xdf, 0xc3, 0xf0, 0x4c, 0xb3, + 0x41, 0x95, 0xb1, 0x80, 0x27, 0xe8, 0x6a, 0xc1, + 0xea, 0x0c, 0xe2, 0x6f, 0x47, 0x02, 0x15, 0x00, + 0xaa, 0xc9, 0x33, 0x22, 0x0c, 0xb7, 0xd8, 0x89, + 0xb5, 0xa4, 0xb7, 0xd5, 0xcc, 0x88, 0x26, 0x62, + 0x03, 0x56, 0x56, 0x57, 0x02, 0x41, 0x00, 0xb3, + 0x5f, 0xd4, 0xcb, 0xec, 0x74, 0xfb, 0x50, 0xb5, + 0x9f, 0xb5, 0x77, 0x78, 0x9c, 0x6e, 0x05, 0xd3, + 0xbf, 0x2d, 0x46, 0xa5, 0x6e, 0xb6, 0x4c, 0xe4, + 0xf7, 0xdc, 0xc0, 0x3b, 0x21, 0x7f, 0xd9, 0x1c, + 0x40, 0xd2, 0xec, 0x46, 0xee, 0x73, 0x4d, 0x99, + 0x14, 0xd0, 0xe5, 0xff, 0xf3, 0x10, 0x0d, 0xcf, + 0xeb, 0x9e, 0xda, 0x8e, 0x8b, 0x38, 0xdd, 0xac, + 0x4c, 0x0b, 0x6e, 0x11, 0xf4, 0x8c, 0xd5, 0x03, + 0x44, 0x00, 0x02, 0x41, 0x00, 0x80, 0xd1, 0xb7, + 0x4a, 0xd0, 0x18, 0x6a, 0xc5, 0x09, 0x12, 0x78, + 0x3b, 0x7f, 0x48, 0xaa, 0x57, 0xf6, 0xef, 0x22, + 0x0e, 0xe8, 0x6a, 0xb5, 0xa6, 0x96, 0xc4, 0x5a, + 0xfb, 0x2f, 0xcf, 0x86, 0x12, 0x21, 0x9b, 0x06, + 0xd3, 0x6b, 0xe5, 0x06, 0x5c, 0xd5, 0x22, 0x15, + 0x0b, 0x7e, 0xd3, 0x67, 0x92, 0x93, 0x79, 0xf4, + 0xc1, 0x6d, 0x22, 0x3c, 0x7c, 0x46, 0xc6, 0xc4, + 0x43, 0x86, 0x13, 0x9d, 0x22, +}; + +const unsigned char dsa_test_asn1_pubkey_noparams[] = { + 0x30, 0x51, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x38, 0x04, 0x01, 0x03, 0x44, 0x00, + 0x02, 0x41, 0x00, 0x80, 0xd1, 0xb7, 0x4a, 0xd0, + 0x18, 0x6a, 0xc5, 0x09, 0x12, 0x78, 0x3b, 0x7f, + 0x48, 0xaa, 0x57, 0xf6, 0xef, 0x22, 0x0e, 0xe8, + 0x6a, 0xb5, 0xa6, 0x96, 0xc4, 0x5a, 0xfb, 0x2f, + 0xcf, 0x86, 0x12, 0x21, 0x9b, 0x06, 0xd3, 0x6b, + 0xe5, 0x06, 0x5c, 0xd5, 0x22, 0x15, 0x0b, 0x7e, + 0xd3, 0x67, 0x92, 0x93, 0x79, 0xf4, 0xc1, 0x6d, + 0x22, 0x3c, 0x7c, 0x46, 0xc6, 0xc4, 0x43, 0x86, + 0x13, 0x9d, 0x22, +}; + +const char *ec_test_key = + "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEIEDkF84aPdBNu4vbPE+QV3EP9ULp4Enr1N0lz4vzuc2boAoGCCqGSM49\n" + "AwEHoUQDQgAEUQGHBjYwbfHvI3QqdDy8ftNU5UvQqh6TH6upIrtz4CVccxnWO2+s\n" + "qSMOu1z5KnGIOVf2kLQ2S2iMahyFMezr8g==\n" + "-----END EC PRIVATE KEY-----\n"; + +unsigned char ec_test_asn1_pubkey[] = { + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0x51, 0x01, 0x87, 0x06, 0x36, + 0x30, 0x6d, 0xf1, 0xef, 0x23, 0x74, 0x2a, 0x74, + 0x3c, 0xbc, 0x7e, 0xd3, 0x54, 0xe5, 0x4b, 0xd0, + 0xaa, 0x1e, 0x93, 0x1f, 0xab, 0xa9, 0x22, 0xbb, + 0x73, 0xe0, 0x25, 0x5c, 0x73, 0x19, 0xd6, 0x3b, + 0x6f, 0xac, 0xa9, 0x23, 0x0e, 0xbb, 0x5c, 0xf9, + 0x2a, 0x71, 0x88, 0x39, 0x57, 0xf6, 0x90, 0xb4, + 0x36, 0x4b, 0x68, 0x8c, 0x6a, 0x1c, 0x85, 0x31, + 0xec, 0xeb, 0xf2, +}; + +const char *rsa_test_key = + "-----BEGIN PRIVATE KEY-----\n" + "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEA4Fs6ljFFQw/ElDf5\n" + "LTghVw972PVpQuKPQvwb1cWbV3+7W5sXOcoM/RvwzO7WeppkeltVCBoKaQd+9e2Z\n" + "BHtYhwIDAQABAkEAhWv7dWIrrGvuHa8D0i51NU8R+b5IMOyHAfDnpMN1VByWcBdb\n" + "G7ZJsEYlO1Tbx1zFQOVyrDUY2hn0YttPjWys0QIhAP9+FRhHCYye/EY14zSa+lxb\n" + "ljOPjWgddMdJBcPOVNUNAiEA4M1QUtIcTnTnfvcxvEBIhbmSR8fRvZYAeT5EoTKM\n" + "puMCIQD9898X8JRHWEg9qZabVWiBoO+ddJUD5jOLWsQGKvMbiQIgBOQyxTqRJxvg\n" + "FaEnUeNMMKyzBCDS7X8gD4NNVvyUluUCIQC/lnO9xYi6S4BFMwHFEUY0jLr5vgsR\n" + "+esRU9dLkMqt+w==\n" + "-----END PRIVATE KEY-----\n"; + +unsigned char rsa_test_asn1_pubkey[] = { + 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, + 0x00, 0xe0, 0x5b, 0x3a, 0x96, 0x31, 0x45, 0x43, + 0x0f, 0xc4, 0x94, 0x37, 0xf9, 0x2d, 0x38, 0x21, + 0x57, 0x0f, 0x7b, 0xd8, 0xf5, 0x69, 0x42, 0xe2, + 0x8f, 0x42, 0xfc, 0x1b, 0xd5, 0xc5, 0x9b, 0x57, + 0x7f, 0xbb, 0x5b, 0x9b, 0x17, 0x39, 0xca, 0x0c, + 0xfd, 0x1b, 0xf0, 0xcc, 0xee, 0xd6, 0x7a, 0x9a, + 0x64, 0x7a, 0x5b, 0x55, 0x08, 0x1a, 0x0a, 0x69, + 0x07, 0x7e, 0xf5, 0xed, 0x99, 0x04, 0x7b, 0x58, + 0x87, 0x02, 0x03, 0x01, 0x00, 0x01, +}; + +const char dh_test_key[] = + "-----BEGIN PRIVATE KEY-----\n" + "MIICJgIBADCCARcGCSqGSIb3DQEDATCCAQgCggEBAIXmHiRswMxVCnVzq4GuaErl\n" + "2fBPDquOzFaxd/YSN7tVxnz3wcMNfBsHZWqtAXxTBWeyt8ydHcrIWx4EB3XTSwSi\n" + "Jqh3CEcFhDfqKdo/u7vffxG+43lEsvZZIzZHYMcYsHIpcERRoAu0xnqjHUQTkvoi\n" + "w7ukbuWr28bJrncPaxFGC8zZvLhSnUst5yzdyAsIddQvHgYBdCn2UEbz6qBx8gvJ\n" + "lb3Jv1BiVJJ0odL94vpNXRGNZ57PPm5Xlj/n8l8LHpzzxbtjc52MVYbMPpVuWzmv\n" + "2nWV0eL14708S/XG6e2AWGKb8AX8hCitdtVQ28SbEsf8Yd1dyWNo++oedFvU49sC\n" + "AQIEggEEAoIBAGywTP/vBwEeuWIgTPnBf1/jWQgfFA5no3HdRIQsHVgo2EEZHErS\n" + "X82hALavaUTEu+pHu+/yv3BLPr/8Lau6O7LOiqeXMjYX4HtSNmLZIEjugd1aCyCp\n" + "n+jZjIHQCG0fvnwWFqkKTADe4n4DUz5qxuHYmlFY4NsdMj5yARAh9mn7hqwYX+Mf\n" + "WhHLhHIHngXKNs7vKdHH/guo638uL6dv6OuTS0wbBsjLMFvQvccVlVUWlUFkH6I8\n" + "GFt8kAFLdrzz8+oMq3hHsoWIrDSp0GYq6keSu3pBj4q2mTP7ugUU8ag/dZnga5sB\n" + "Mdt2hicktiw/mQZP578plm6z2Lg0gl5yLxk=\n" + "-----END PRIVATE KEY-----\n"; + +const unsigned char dh_test_asn1_pubkey[] = { + 0x30, 0x82, 0x02, 0x24, 0x30, 0x82, 0x01, 0x17, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x08, 0x02, + 0x82, 0x01, 0x01, 0x00, 0x85, 0xe6, 0x1e, 0x24, + 0x6c, 0xc0, 0xcc, 0x55, 0x0a, 0x75, 0x73, 0xab, + 0x81, 0xae, 0x68, 0x4a, 0xe5, 0xd9, 0xf0, 0x4f, + 0x0e, 0xab, 0x8e, 0xcc, 0x56, 0xb1, 0x77, 0xf6, + 0x12, 0x37, 0xbb, 0x55, 0xc6, 0x7c, 0xf7, 0xc1, + 0xc3, 0x0d, 0x7c, 0x1b, 0x07, 0x65, 0x6a, 0xad, + 0x01, 0x7c, 0x53, 0x05, 0x67, 0xb2, 0xb7, 0xcc, + 0x9d, 0x1d, 0xca, 0xc8, 0x5b, 0x1e, 0x04, 0x07, + 0x75, 0xd3, 0x4b, 0x04, 0xa2, 0x26, 0xa8, 0x77, + 0x08, 0x47, 0x05, 0x84, 0x37, 0xea, 0x29, 0xda, + 0x3f, 0xbb, 0xbb, 0xdf, 0x7f, 0x11, 0xbe, 0xe3, + 0x79, 0x44, 0xb2, 0xf6, 0x59, 0x23, 0x36, 0x47, + 0x60, 0xc7, 0x18, 0xb0, 0x72, 0x29, 0x70, 0x44, + 0x51, 0xa0, 0x0b, 0xb4, 0xc6, 0x7a, 0xa3, 0x1d, + 0x44, 0x13, 0x92, 0xfa, 0x22, 0xc3, 0xbb, 0xa4, + 0x6e, 0xe5, 0xab, 0xdb, 0xc6, 0xc9, 0xae, 0x77, + 0x0f, 0x6b, 0x11, 0x46, 0x0b, 0xcc, 0xd9, 0xbc, + 0xb8, 0x52, 0x9d, 0x4b, 0x2d, 0xe7, 0x2c, 0xdd, + 0xc8, 0x0b, 0x08, 0x75, 0xd4, 0x2f, 0x1e, 0x06, + 0x01, 0x74, 0x29, 0xf6, 0x50, 0x46, 0xf3, 0xea, + 0xa0, 0x71, 0xf2, 0x0b, 0xc9, 0x95, 0xbd, 0xc9, + 0xbf, 0x50, 0x62, 0x54, 0x92, 0x74, 0xa1, 0xd2, + 0xfd, 0xe2, 0xfa, 0x4d, 0x5d, 0x11, 0x8d, 0x67, + 0x9e, 0xcf, 0x3e, 0x6e, 0x57, 0x96, 0x3f, 0xe7, + 0xf2, 0x5f, 0x0b, 0x1e, 0x9c, 0xf3, 0xc5, 0xbb, + 0x63, 0x73, 0x9d, 0x8c, 0x55, 0x86, 0xcc, 0x3e, + 0x95, 0x6e, 0x5b, 0x39, 0xaf, 0xda, 0x75, 0x95, + 0xd1, 0xe2, 0xf5, 0xe3, 0xbd, 0x3c, 0x4b, 0xf5, + 0xc6, 0xe9, 0xed, 0x80, 0x58, 0x62, 0x9b, 0xf0, + 0x05, 0xfc, 0x84, 0x28, 0xad, 0x76, 0xd5, 0x50, + 0xdb, 0xc4, 0x9b, 0x12, 0xc7, 0xfc, 0x61, 0xdd, + 0x5d, 0xc9, 0x63, 0x68, 0xfb, 0xea, 0x1e, 0x74, + 0x5b, 0xd4, 0xe3, 0xdb, 0x02, 0x01, 0x02, 0x03, + 0x82, 0x01, 0x05, 0x00, 0x02, 0x82, 0x01, 0x00, + 0x44, 0x30, 0x25, 0xe2, 0xeb, 0x8f, 0xd0, 0x81, + 0x96, 0x3e, 0x7d, 0x1d, 0x9b, 0x82, 0x8a, 0x2d, + 0x0f, 0xb3, 0x2d, 0x9c, 0x2b, 0xb2, 0x88, 0xda, + 0xc6, 0xef, 0x6c, 0x9d, 0x1c, 0x80, 0xf1, 0xee, + 0x9d, 0x6b, 0x31, 0xb7, 0xb1, 0x9f, 0x30, 0x0d, + 0xb7, 0x92, 0xcf, 0x56, 0xeb, 0xfc, 0x91, 0x16, + 0x35, 0x96, 0x0c, 0x7b, 0x95, 0xbc, 0x65, 0x66, + 0x10, 0x81, 0x4b, 0x46, 0x04, 0xee, 0x95, 0xca, + 0xc9, 0x0c, 0xea, 0xc1, 0xd7, 0x3b, 0x83, 0xfb, + 0xce, 0x76, 0x17, 0xb4, 0x15, 0xad, 0x03, 0xd0, + 0x00, 0xef, 0xb2, 0xee, 0x12, 0x3f, 0x75, 0xd1, + 0xb8, 0x6c, 0xfd, 0x87, 0xb5, 0x07, 0xfa, 0x1e, + 0x60, 0x9b, 0x49, 0x6f, 0x89, 0xc2, 0x75, 0x4d, + 0x7d, 0x21, 0xdb, 0xb6, 0x85, 0x78, 0xa5, 0x77, + 0xbe, 0xeb, 0x4d, 0x9e, 0x1c, 0x05, 0xbc, 0x51, + 0x97, 0x0f, 0xe9, 0x68, 0x78, 0x5a, 0xc8, 0x4e, + 0xef, 0x72, 0x8f, 0x53, 0x41, 0x0d, 0x57, 0xf2, + 0xc5, 0x29, 0x33, 0x67, 0xdd, 0x35, 0x43, 0xfc, + 0x13, 0x49, 0x92, 0x1d, 0x14, 0x92, 0x40, 0x14, + 0x38, 0x32, 0xdb, 0x14, 0x95, 0x44, 0x2a, 0x03, + 0xb7, 0x87, 0xa3, 0x5a, 0x5a, 0xe2, 0x3b, 0xc5, + 0x44, 0xa4, 0x06, 0xf6, 0x14, 0xe6, 0x08, 0x9c, + 0x51, 0x09, 0x2a, 0xc4, 0x2e, 0x72, 0xb3, 0x20, + 0x46, 0x77, 0xe2, 0xda, 0x07, 0xd8, 0x10, 0x89, + 0xcf, 0x2b, 0xef, 0x67, 0xa2, 0x48, 0xfd, 0xa3, + 0x71, 0x59, 0xf0, 0x89, 0x3a, 0x35, 0x31, 0x87, + 0xad, 0x45, 0x9e, 0x35, 0xbd, 0x64, 0xec, 0xd1, + 0xd7, 0xea, 0x92, 0xed, 0x72, 0x9c, 0x81, 0x8e, + 0x11, 0x4e, 0xa5, 0xe7, 0x12, 0xe3, 0x7c, 0x53, + 0x2b, 0x31, 0xd4, 0x3d, 0xd5, 0xd9, 0xbd, 0x44, + 0x27, 0xa3, 0x4a, 0x3f, 0x20, 0x87, 0xce, 0x73, + 0x0e, 0xa8, 0x90, 0xcd, 0xfe, 0x32, 0x69, 0x9a, +}; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +compare_data(const char *label, const unsigned char *d1, size_t d1_len, + const unsigned char *d2, size_t d2_len) +{ + if (d1_len != d2_len) { + fprintf(stderr, "FAIL: got %s with length %zu, want %zu\n", + label, d1_len, d2_len); + return -1; + } + if (memcmp(d1, d2, d1_len) != 0) { + fprintf(stderr, "FAIL: %s differs\n", label); + fprintf(stderr, "got:\n"); + hexdump(d1, d1_len); + fprintf(stderr, "want:\n"); + hexdump(d2, d2_len); + return -1; + } + return 0; +} + +static int +dh_pubkey_test(void) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY *pkey_a = NULL, *pkey_b = NULL; + unsigned char *out = NULL, *data = NULL; + DH *dh_a = NULL, *dh_b = NULL; + const unsigned char *p; + BIO *bio_mem = NULL; + int failure = 1; + int len; + + ERR_clear_error(); + + if ((bio_mem = BIO_new_mem_buf(dh_test_key, -1)) == NULL) + errx(1, "failed to create BIO"); + + if ((pkey = PEM_read_bio_PrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to decode DH key from PEM"); + } + + /* + * Test PEM_write_bio_PrivateKey(). + */ + BIO_free_all(bio_mem); + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new failed for BIO_s_mem"); + + if (!PEM_write_bio_PrivateKey(bio_mem, pkey, NULL, NULL, 0, 0, NULL)) { + fprintf(stderr, "FAIL: PEM_write_bio_PrivateKey failed\n"); + goto done; + } + + len = BIO_get_mem_data(bio_mem, &data); + if (compare_data("DH PrivateKey", data, len, + dh_test_key, sizeof(dh_test_key) - 1) == -1) + goto done; + + /* + * Test i2d_PUBKEY/d2i_PUBKEY. + */ + + if ((dh_a = EVP_PKEY_get1_DH(pkey)) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to get1 DH key from PEM"); + } + + if ((pkey_a = EVP_PKEY_new()) == NULL) + errx(1, "failed to create EVP_PKEY"); + if (!EVP_PKEY_set1_DH(pkey_a, dh_a)) + errx(1, "failed to set DH on EVP_PKEY"); + + if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_PUBKEY failed\n"); + goto done; + } + if (compare_data("DH PUBKEY", out, len, dh_test_asn1_pubkey, + sizeof(dh_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(DH_get0_pub_key(EVP_PKEY_get0_DH(pkey_a)), + DH_get0_pub_key(EVP_PKEY_get0_DH(pkey_b))) != 0) { + fprintf(stderr, "FAIL: DH public keys mismatch\n"); + goto done; + } + + failure = 0; + + done: + BIO_free_all(bio_mem); + EVP_PKEY_free(pkey); + DH_free(dh_a); + DH_free(dh_b); + EVP_PKEY_free(pkey_a); + EVP_PKEY_free(pkey_b); + free(out); + + return failure; +} + +static int +dsa_pubkey_test(void) +{ + EVP_PKEY *pkey_a = NULL, *pkey_b = NULL; + unsigned char *out = NULL, *data = NULL; + DSA *dsa_a = NULL, *dsa_b = NULL; + const unsigned char *p; + BIO *bio_mem = NULL; + int failure = 1; + int len, ret; + + ERR_clear_error(); + + if ((bio_mem = BIO_new_mem_buf((void *)dsa_test_key, -1)) == NULL) + errx(1, "failed to create BIO"); + + if ((dsa_a = PEM_read_bio_DSAPrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to decode DSA key from PEM"); + } + + /* + * Test i2d_PUBKEY/d2i_PUBKEY. + */ + if ((pkey_a = EVP_PKEY_new()) == NULL) + errx(1, "failed to create EVP_PKEY"); + if (!EVP_PKEY_set1_DSA(pkey_a, dsa_a)) + errx(1, "failed to set DSA on EVP_PKEY"); + + if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_PUBKEY failed\n"); + goto done; + } + if (compare_data("DSA PUBKEY", out, len, dsa_test_asn1_pubkey, + sizeof(dsa_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(DSA_get0_pub_key(EVP_PKEY_get0_DSA(pkey_a)), + DSA_get0_pub_key(EVP_PKEY_get0_DSA(pkey_b))) != 0) { + fprintf(stderr, "FAIL: DSA public keys mismatch\n"); + goto done; + } + + if (EVP_PKEY_missing_parameters(pkey_b)) { + fprintf(stderr, "FAIL: DSA pkey_b has missing parameters\n"); + goto done; + } + + if (!EVP_PKEY_cmp_parameters(pkey_a, pkey_b)) { + fprintf(stderr, "FAIL: DSA parameters mismatch\n"); + goto done; + } + + /* + * Check save_parameters defaults - EVP_PKEY_save_parameters() returns + * the current save_parameters; mode -1 inspects without setting. + */ + if ((ret = EVP_PKEY_save_parameters(pkey_b, 0)) != 1) { + fprintf(stderr, "FAIL: DSA save_parameters want 1, got %d\n", ret); + goto done; + } + if ((ret = EVP_PKEY_save_parameters(pkey_b, -1)) != 0) { + fprintf(stderr, "FAIL: DSA save_parameters want 0, got %d\n", ret); + goto done; + } + + free(out); + out = NULL; + + if ((len = i2d_PUBKEY(pkey_b, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_PUBKEY (no params) failed\n"); + goto done; + } + + if (compare_data("PUBKEY (no params)", dsa_test_asn1_pubkey_noparams, + sizeof(dsa_test_asn1_pubkey_noparams), out, len) == -1) + goto done; + + EVP_PKEY_free(pkey_b); + + p = out; + if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_PUBKEY (no params) failed\n"); + goto done; + } + + if (!EVP_PKEY_missing_parameters(pkey_b)) { + fprintf(stderr, "FAIL: DSA pkey_b has no missing parameters\n"); + goto done; + } + + if (BN_cmp(DSA_get0_pub_key(EVP_PKEY_get0_DSA(pkey_a)), + DSA_get0_pub_key(EVP_PKEY_get0_DSA(pkey_b))) != 0) { + fprintf(stderr, "FAIL: DSA public keys mismatch\n"); + goto done; + } + + if (EVP_PKEY_cmp_parameters(pkey_a, pkey_b)) { + fprintf(stderr, "FAIL: DSA parameters match\n"); + goto done; + } + + if (EVP_PKEY_cmp(pkey_a, pkey_b)) { + fprintf(stderr, "FAIL: DSA keys should not match\n"); + goto done; + } + + if (!EVP_PKEY_copy_parameters(pkey_b, pkey_a)) { + fprintf(stderr, "FAIL: failed to copy DSA parameters\n"); + goto done; + } + + if (!EVP_PKEY_cmp(pkey_a, pkey_b)) { + fprintf(stderr, "FAIL: DSA keys should match\n"); + goto done; + } + + free(out); + out = NULL; + + /* + * Test i2d_DSA_PUBKEY/d2i_DSA_PUBKEY. + */ + + if ((len = i2d_DSA_PUBKEY(dsa_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_DSA_PUBKEY failed\n"); + goto done; + } + if (compare_data("DSA_PUBKEY", out, len, dsa_test_asn1_pubkey, + sizeof(dsa_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((dsa_b = d2i_DSA_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_DSA_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(DSA_get0_pub_key(dsa_a), DSA_get0_pub_key(dsa_b)) != 0) { + fprintf(stderr, "FAIL: DSA public keys mismatch\n"); + goto done; + } + + p = out; + if ((dsa_a = d2i_DSA_PUBKEY(&dsa_a, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_DSA_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(DSA_get0_pub_key(dsa_a), DSA_get0_pub_key(dsa_b)) != 0) { + fprintf(stderr, "FAIL: DSA public keys mismatch\n"); + goto done; + } + + /* + * Test i2d_DSA_PUBKEY_bio/d2i_DSA_PUBKEY_bio. + */ + BIO_free_all(bio_mem); + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new failed for BIO_s_mem"); + + if ((len = i2d_DSA_PUBKEY_bio(bio_mem, dsa_a)) < 0) { + fprintf(stderr, "FAIL: i2d_DSA_PUBKEY_bio failed\n"); + goto done; + } + + len = BIO_get_mem_data(bio_mem, &data); + if (compare_data("DSA_PUBKEY", data, len, dsa_test_asn1_pubkey, + sizeof(dsa_test_asn1_pubkey)) == -1) + goto done; + + DSA_free(dsa_b); + if ((dsa_b = d2i_DSA_PUBKEY_bio(bio_mem, NULL)) == NULL) { + fprintf(stderr, "FAIL: d2i_DSA_PUBKEY_bio failed\n"); + goto done; + } + + if (BN_cmp(DSA_get0_pub_key(dsa_a), DSA_get0_pub_key(dsa_b)) != 0) { + fprintf(stderr, "FAIL: DSA public keys mismatch\n"); + goto done; + } + + failure = 0; + + done: + BIO_free_all(bio_mem); + DSA_free(dsa_a); + DSA_free(dsa_b); + EVP_PKEY_free(pkey_a); + EVP_PKEY_free(pkey_b); + free(out); + + return (failure); +} + +static int +ec_pubkey_test(void) +{ + EVP_PKEY *pkey_a = NULL, *pkey_b = NULL; + unsigned char *out = NULL, *data = NULL; + EC_KEY *ec_a = NULL, *ec_b = NULL; + const unsigned char *p; + BIO *bio_mem = NULL; + int failure = 1; + int len; + + ERR_clear_error(); + + if ((bio_mem = BIO_new_mem_buf((void *)ec_test_key, -1)) == NULL) + errx(1, "failed to create BIO"); + + if ((ec_a = PEM_read_bio_ECPrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to decode EC key from PEM"); + } + + /* + * Test i2d_PUBKEY/d2i_PUBKEY. + */ + if ((pkey_a = EVP_PKEY_new()) == NULL) + errx(1, "failed to create EVP_PKEY"); + if (!EVP_PKEY_set1_EC_KEY(pkey_a, ec_a)) + errx(1, "failed to set EC_KEY on EVP_PKEY"); + + if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_PUBKEY failed\n"); + goto done; + } + if (compare_data("EC_KEY PUBKEY", out, len, ec_test_asn1_pubkey, + sizeof(ec_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_PUBKEY failed\n"); + goto done; + } + + if (EC_GROUP_cmp(EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey_a)), + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey_b)), NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n"); + goto done; + } + if (EC_POINT_cmp(EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey_a)), + EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(pkey_a)), + EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(pkey_b)), NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n"); + goto done; + } + + free(out); + out = NULL; + + /* + * Test i2d_EC_PUBKEY/d2i_EC_PUBKEY. + */ + + if ((len = i2d_EC_PUBKEY(ec_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_EC_PUBKEY failed\n"); + goto done; + } + if (compare_data("EC_PUBKEY", out, len, ec_test_asn1_pubkey, + sizeof(ec_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((ec_b = d2i_EC_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_EC_PUBKEY failed\n"); + goto done; + } + + if (EC_GROUP_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_group(ec_b), + NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n"); + goto done; + } + if (EC_POINT_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_public_key(ec_a), + EC_KEY_get0_public_key(ec_b), NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n"); + goto done; + } + + p = out; + if ((ec_a = d2i_EC_PUBKEY(&ec_a, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_EC_PUBKEY failed\n"); + goto done; + } + + if (EC_GROUP_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_group(ec_b), + NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n"); + goto done; + } + if (EC_POINT_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_public_key(ec_a), + EC_KEY_get0_public_key(ec_b), NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n"); + goto done; + } + + /* + * Test i2d_EC_PUBKEY_bio/d2i_EC_PUBKEY_bio. + */ + BIO_free_all(bio_mem); + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new failed for BIO_s_mem"); + + if ((len = i2d_EC_PUBKEY_bio(bio_mem, ec_a)) < 0) { + fprintf(stderr, "FAIL: i2d_EC_PUBKEY_bio failed\n"); + goto done; + } + + len = BIO_get_mem_data(bio_mem, &data); + if (compare_data("EC_PUBKEY", data, len, ec_test_asn1_pubkey, + sizeof(ec_test_asn1_pubkey)) == -1) + goto done; + + EC_KEY_free(ec_b); + if ((ec_b = d2i_EC_PUBKEY_bio(bio_mem, NULL)) == NULL) { + fprintf(stderr, "FAIL: d2i_EC_PUBKEY_bio failed\n"); + goto done; + } + + if (EC_GROUP_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_group(ec_b), + NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n"); + goto done; + } + if (EC_POINT_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_public_key(ec_a), + EC_KEY_get0_public_key(ec_b), NULL) != 0) { + fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n"); + goto done; + } + + failure = 0; + + done: + BIO_free_all(bio_mem); + EC_KEY_free(ec_a); + EC_KEY_free(ec_b); + EVP_PKEY_free(pkey_a); + EVP_PKEY_free(pkey_b); + free(out); + + return (failure); +} + +static int +rsa_pubkey_test(void) +{ + EVP_PKEY *pkey_a = NULL, *pkey_b = NULL; + RSA *rsa_a = NULL, *rsa_b = NULL; + unsigned char *out = NULL, *data = NULL; + const unsigned char *p; + BIO *bio_mem = NULL; + int failure = 1; + int len; + + ERR_clear_error(); + + if ((bio_mem = BIO_new_mem_buf((void *)rsa_test_key, -1)) == NULL) + errx(1, "failed to create BIO"); + + if ((rsa_a = PEM_read_bio_RSAPrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to decode RSA key from PEM"); + } + + /* + * Test i2d_PUBKEY/d2i_PUBKEY. + */ + if ((pkey_a = EVP_PKEY_new()) == NULL) + errx(1, "failed to create EVP_PKEY"); + if (!EVP_PKEY_set1_RSA(pkey_a, rsa_a)) + errx(1, "failed to set RSA on EVP_PKEY"); + + if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_PUBKEY failed\n"); + goto done; + } + if (compare_data("RSA PUBKEY", out, len, rsa_test_asn1_pubkey, + sizeof(rsa_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(RSA_get0_n(EVP_PKEY_get0_RSA(pkey_a)), + RSA_get0_n(EVP_PKEY_get0_RSA(pkey_b))) != 0 || + BN_cmp(RSA_get0_e(EVP_PKEY_get0_RSA(pkey_a)), + RSA_get0_e(EVP_PKEY_get0_RSA(pkey_b))) != 0) { + fprintf(stderr, "FAIL: RSA public keys mismatch\n"); + goto done; + } + + free(out); + out = NULL; + + /* + * Test i2d_RSA_PUBKEY/d2i_RSA_PUBKEY. + */ + + if ((len = i2d_RSA_PUBKEY(rsa_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_RSA_PUBKEY failed\n"); + goto done; + } + if (compare_data("RSA_PUBKEY", out, len, rsa_test_asn1_pubkey, + sizeof(rsa_test_asn1_pubkey)) == -1) + goto done; + + p = out; + if ((rsa_b = d2i_RSA_PUBKEY(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_RSA_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(RSA_get0_n(rsa_a), RSA_get0_n(rsa_b)) != 0 || + BN_cmp(RSA_get0_e(rsa_a), RSA_get0_e(rsa_b)) != 0) { + fprintf(stderr, "FAIL: RSA public keys mismatch\n"); + goto done; + } + + p = out; + if ((rsa_a = d2i_RSA_PUBKEY(&rsa_a, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_RSA_PUBKEY failed\n"); + goto done; + } + + if (BN_cmp(RSA_get0_n(rsa_a), RSA_get0_n(rsa_b)) != 0 || + BN_cmp(RSA_get0_e(rsa_a), RSA_get0_e(rsa_b)) != 0) { + fprintf(stderr, "FAIL: RSA public keys mismatch\n"); + goto done; + } + + /* + * Test i2d_RSA_PUBKEY_bio/d2i_RSA_PUBKEY_bio. + */ + BIO_free_all(bio_mem); + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new failed for BIO_s_mem"); + + if ((len = i2d_RSA_PUBKEY_bio(bio_mem, rsa_a)) < 0) { + fprintf(stderr, "FAIL: i2d_RSA_PUBKEY_bio failed\n"); + goto done; + } + + len = BIO_get_mem_data(bio_mem, &data); + if (compare_data("RSA_PUBKEY", data, len, rsa_test_asn1_pubkey, + sizeof(rsa_test_asn1_pubkey)) == -1) + goto done; + + RSA_free(rsa_b); + if ((rsa_b = d2i_RSA_PUBKEY_bio(bio_mem, NULL)) == NULL) { + fprintf(stderr, "FAIL: d2i_RSA_PUBKEY_bio failed\n"); + goto done; + } + + if (BN_cmp(RSA_get0_n(rsa_a), RSA_get0_n(rsa_b)) != 0 || + BN_cmp(RSA_get0_e(rsa_a), RSA_get0_e(rsa_b)) != 0) { + fprintf(stderr, "FAIL: RSA public keys mismatch\n"); + goto done; + } + + failure = 0; + + done: + BIO_free_all(bio_mem); + RSA_free(rsa_a); + RSA_free(rsa_b); + EVP_PKEY_free(pkey_a); + EVP_PKEY_free(pkey_b); + free(out); + + return (failure); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + ERR_load_crypto_strings(); + + failed |= dh_pubkey_test(); + failed |= dsa_pubkey_test(); + failed |= ec_pubkey_test(); + failed |= rsa_pubkey_test(); + + return (failed); +} diff --git a/Libraries/libressl/tests/base64test.c b/Libraries/libressl/tests/base64test.c new file mode 100644 index 000000000..9ab2a4070 --- /dev/null +++ b/Libraries/libressl/tests/base64test.c @@ -0,0 +1,486 @@ +/* $OpenBSD: base64test.c,v 1.10 2022/09/05 21:06:31 tb Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +#define BUF_SIZE 128 + +struct base64_test { + const unsigned char in[BUF_SIZE]; + const ssize_t in_len; + const unsigned char out[BUF_SIZE]; + const ssize_t out_len; + const ssize_t valid_len; +}; + +/* + * Many of these tests are based on those found in Go's encoding/base64 tests. + */ +struct base64_test base64_tests[] = { + + /* RFC3548 examples. */ + { "\x14\xfb\x9c\x03\xd9\x7e", 6, "FPucA9l+", 8, 6, }, + { "\x14\xfb\x9c\x03\xd9", 5, "FPucA9k=", 8, 5, }, + { "\x14\xfb\x9c\x03", 4, "FPucAw==", 8, 4, }, + + /* RFC4648 examples. */ + { "", 0, "", 0, 0, }, + { "f", 1, "Zg==", 4, 1, }, + { "fo", 2, "Zm8=", 4, 2, }, + { "foo", 3, "Zm9v", 4, 3, }, + { "foob", 4, "Zm9vYg==", 8, 4, }, + { "fooba", 5, "Zm9vYmE=", 8, 5, }, + { "foobar", 6, "Zm9vYmFy", 8, 6, }, + + /* Wikipedia examples. */ + { "sure.", 5, "c3VyZS4=", 8, 5, }, + { "sure", 4, "c3VyZQ==", 8, 4, }, + { "sur", 3, "c3Vy", 4, 3, }, + { "su", 2, "c3U=", 4, 2, }, + { "leasure.", 8, "bGVhc3VyZS4=", 12, 8, }, + { "easure.", 7, "ZWFzdXJlLg==", 12, 7, }, + { "asure.", 6, "YXN1cmUu", 8, 6, }, + + { "abcd", 4, "YWJjZA==", 8, 4, }, + + { + "Twas brillig, and the slithy toves", + 34, + "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", + 48, + 34, + }, +}; + +#define N_TESTS (sizeof(base64_tests) / sizeof(*base64_tests)) + +struct base64_test base64_nl_tests[] = { + + /* Corrupt/invalid encodings. */ + { "", -1, "", 0, 0, }, + { "", -1, "!!!!", 4, 0, }, + { "", -1, "====", 4, 0, }, + { "", -1, "x===", 4, 0, }, + { "", -1, "=AAA", 4, 0, }, + { "", -1, "A=AA", 4, 0, }, + { "", -1, "AA=A", 4, 0, }, + { "", -1, "AA==A", 5, 0, }, + { "", -1, "AAA=AAAA", 8, 0, }, + { "", -1, "AAAAA", 5, 0, }, + { "", -1, "AAAAAA", 6, 0, }, + { "", -1, "A=", 2, 0, }, + { "", -1, "A==", 3, 0, }, + { "", -1, "AA=", 3, 0, }, + { "", -1, "AA==", 4, 1, }, /* XXX - output ix 0x0. */ + { "", -1, "AAA=", 4, 2, }, /* XXX - output ix 2x 0x0. */ + { "", -1, "AAAA", 4, 3, }, /* XXX - output ix 3x 0x0. */ + { "", -1, "AAAAAA=", 7, 0, }, + { "", -1, "YWJjZA=====", 11, 0, }, + + + /* Encodings with embedded CR/LF. */ + { "sure", 4, "c3VyZQ==", 8, 4, }, + { "sure", 4, "c3VyZQ==\r", 9, 4, }, + { "sure", 4, "c3VyZQ==\n", 9, 4, }, + { "sure", 4, "c3VyZQ==\r\n", 10, 4, }, + { "sure", 4, "c3VyZ\r\nQ==", 10, 4, }, + { "sure", 4, "c3V\ryZ\nQ==", 10, 4, }, + { "sure", 4, "c3V\nyZ\rQ==", 10, 4, }, + { "sure", 4, "c3VyZ\nQ==", 9, 4, }, + { "sure", 4, "c3VyZQ\n==", 9, 4, }, + { "sure", 4, "c3VyZQ=\n=", 9, 4, }, + { "sure", 4, "c3VyZQ=\r\n\r\n=", 12, 4, }, + + { + "", + -1, + "YWJjZA======================================================" + "============", + 74, + 0, + }, + + /* OpenSSL-1.1.1d test */ + /* canonical */ + { "", 0, "", 0, 0, }, + /* canonical */ + { "h", 1, "aA==\n", 5, 1, }, + /* canonical */ + { "hello", 5, "aGVsbG8=\n", 9, 5, }, + /* canonical */ + { "hello world!", 12, "aGVsbG8gd29ybGQh\n", 17, 12, }, + /* canonical */ + { "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\xa0\xb0\xc0\xd0\xe0\xf0\x00", 17, "AAECAwQFBgcICaCwwNDg8AA=\n", 25, 17, }, + /* invalid # Missing padding */ + { "", -1, "aGVsbG8", 7, 0, }, + /* invalid */ + { "", -1, "aGVsbG8\n", 8, 0, }, + /* valid # Tolerate missing newline */ + { "hello", -1, "aGVsbG8=", 8, 5, }, + /* invalid # Don't tolerate extra trailing '=' */ + { "", -1, "aGVsbG8==\n", 10, 0, }, + /* invalid */ + { "", -1, "aGVsbG8===\n", 11, 0, }, + /* invalid # Don't tolerate data after '=' */ + { "", -1, "aGV=sbG8=\n", 10, 0, }, + /* valid # Newlines are ignored */ + { "hello", -1, "aGV\nsbG8=\n", 10, 5, }, + /* canonical */ + { "hello", 5, "\x61\x47\x56\x73\x62\x47\x38\x3d\x0a", 9, 5, }, + /* invalid # Invalid characters */ + { "", -1, "\x61\x47\x56\x73\x62\x47\x38\x3d\x0a\x00", 10, 0, }, + /* invalid */ + { "", -1, "\x61\x47\x56\x00\x73\x62\x47\x38\x3d\x0a", 10, 0, }, + /* invalid */ + { "", -1, "\x61\x47\x56\x01\x73\x62\x47\x38\x3d\x0a", 10, 0, }, + /* invalid */ + { "", -1, "\x61\x47\x56\x80\x73\x62\x47\x38\x3d\x0a", 10, 0, }, + /* invalid */ + { "", -1, "\xe1\x47\x56\x73\x62\x47\x38\x3d\x0a", 9, 0, }, + /* canonical */ + { "OpenSSLOpenSSL\n", 15, "T3BlblNTTE9wZW5TU0wK\n", 21, 15, }, + /* valid */ + { "OpenSSLOpenSSL\n", -1, "T3BlblNTTE9wZW5TU0wK", 20, 15, }, + /* invalid # Truncate 1-3 chars */ + { "", -1, "T3BlblNTTE9wZW5TU0w", 19, 0, }, + /* invalid */ + { "", -1, "T3BlblNTTE9wZW5TU0", 18, 0, }, + /* invalid */ + { "", -1, "T3BlblNTTE9wZW5TU", 17, 0, }, + /* invalid */ + { "", -1, "T3BlblNTTE9wZW5TU0wK====", 24, 0, }, + /* invalid */ + { "", -1, "T3BlblNTTE9wZW5TU0wK============================================\n", 65, 0, }, + /* invalid */ + { "", -1, "YQ==YQ==YQ==\n", 13, 0, }, + /* invalid */ + { "", -1, "A", 1, 0, }, + /* invalid */ + { "", -1, "A\n", 2, 0, }, + /* invalid */ + { "", -1, "A=", 2, 0, }, + /* invalid */ + { "", -1, "A==\n", 4, 0, }, + /* invalid */ + { "", -1, "A===\n", 5, 0, }, + /* invalid */ + { "", -1, "A====\n", 6, 0, }, + /* valid */ + { "OpenSSLOpenSSL\n", -1, "T3BlblNTTE9wZW5TU0wK\n\n", 22, 15, }, + /* valid */ + { "OpenSSLOpenSSL\n", -1, "T3BlblNTTE\n9wZW5TU0wK", 21, 15, }, + /* invalid # CVE 2015-0292 */ + { "", -1, "ZW5jb2RlIG1lCg==================================================================\n", 81, 0, }, + /* canonical */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 46, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA==\n", 65, 46, }, + /* valid */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA\n==\n", 66, 46, }, + /* valid */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA=\n=\n", 66, 46, }, + /* invalid */ + { "", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA====\n", 67, 0, }, + /* canonical # Multiline output without padding */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 60, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neHh4eHh4eHh4eHh4\n", 82, 60, }, + /* canonical # Multiline output with padding */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 64, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neHh4eHh4eHh4eHh4eHh4eA==\n", 90, 64, }, + /* valid # Multiline output with line break in the middle of a b64 block is accepted */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh\n4eHh4eHh4eHh4eHh4eHh4eA==\n", 90, 64, }, + /* valid # Long lines are accepted */ + { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA==\n", 89, 64, }, + /* invalid # Multiline input with data after '='. */ + { "", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA==\neHh4eHh4eHh4eHh4eHh4eHh4\n", 90, 0, }, + /* invalid */ + { "", -1, "eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neA==eHh4eHh4eHh4eHh4eHh4\n", 90, 0, }, + /* valid # B64_EOF ('-') terminates input and trailing bytes are ignored */ + { "OpenSSLOpenSSL\n", -1, "T3BlblNTTE9wZW5TU0wK\n-abcd", 26, 15, }, + /* valid */ + { "OpenSSLOpenSSL\n", -1, "T3BlblNTTE9wZW5TU0wK-abcd", 25, 15, }, +}; + +#define N_NL_TESTS (sizeof(base64_nl_tests) / sizeof(*base64_nl_tests)) + +struct base64_test base64_no_nl_tests[] = { + + /* + * In non-newline mode, the output resulting from corrupt/invalid + * encodings is completely crazy. A number of zero bytes is returned + * rather than nothing. + */ + + /* Corrupt/invalid encodings. */ + { "", -1, "", 0, 0, }, + { "", -1, "!!!!", 4, 0, }, + { "", -1, "====", 4, 1, }, + { "", -1, "x===", 4, 1, }, + { "", -1, "=AAA", 4, 3, }, + { "", -1, "A=AA", 4, 3, }, + { "", -1, "AA=A", 4, 3, }, + { "", -1, "AA==A", 5, 1, }, + { "", -1, "AAA=AAAA", 8, 6, }, + { "", -1, "AAAAA", 5, 3, }, + { "", -1, "AAAAAA", 6, 3, }, + { "", -1, "A=", 2, 0, }, + { "", -1, "A==", 3, 0, }, + { "", -1, "AA=", 3, 0, }, + { "", -1, "AA==", 4, 1, }, + { "", -1, "AAA=", 4, 2, }, + { "", -1, "AAAA", 4, 3, }, + { "", -1, "AAAAAA=", 7, 3, }, + { "", -1, "YWJjZA=====", 11, 4, }, + + /* Encodings with embedded CR/LF. */ + { "sure", 4, "c3VyZQ==", 8, 4, }, + { "sure", 4, "c3VyZQ==\r", 9, 4, }, + { "sure", 4, "c3VyZQ==\n", 9, 4, }, + { "sure", 4, "c3VyZQ==\r\n", 10, 4, }, + { "sure", -1, "c3VyZ\r\nQ==", 10, 0, }, + { "sure", -1, "c3V\ryZ\nQ==", 10, 0, }, + { "sure", -1, "c3V\nyZ\rQ==", 10, 0, }, + { "sure", -1, "c3VyZ\nQ==", 9, 0, }, + { "sure", -1, "c3VyZQ\n==", 9, 0, }, + { "sure", -1, "c3VyZQ=\n=", 9, 0, }, + { "sure", -1, "c3VyZQ=\r\n\r\n=", 12, 0, }, + + /* + * This is invalid, yet results in 'abcd' followed by a stream of + * zero value bytes. + */ + { + "", + -1, + "YWJjZA======================================================" + "============", + 74, + 52, + }, +}; + +#define N_NO_NL_TESTS (sizeof(base64_no_nl_tests) / sizeof(*base64_no_nl_tests)) + +static int +base64_encoding_test(int test_no, struct base64_test *bt, int test_nl) +{ + BIO *bio_b64, *bio_mem; + unsigned char *buf, *out; + ssize_t i, len, b64len; + int failure = 0; + + buf = malloc(BUF_SIZE); + if (buf == NULL) + errx(1, "malloc"); + + bio_b64 = BIO_new(BIO_f_base64()); + if (bio_b64 == NULL) + errx(1, "BIO_new failed for BIO_f_base64"); + + bio_mem = BIO_new(BIO_s_mem()); + if (bio_mem == NULL) + errx(1, "BIO_new failed for BIO_s_mem"); + + bio_mem = BIO_push(bio_b64, bio_mem); + + if (!test_nl) + BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL); + + len = BIO_write(bio_mem, bt->in, bt->in_len); + if (len != bt->in_len) { + fprintf(stderr, "FAIL: test %d - only wrote %zd out of %zd " + "characters\n", test_no, len, bt->in_len); + failure = 1; + goto done; + } + if (BIO_flush(bio_mem) < 0) { + fprintf(stderr, "FAIL: test %d - flush failed\n", test_no); + failure = 1; + goto done; + } + + b64len = 0; + for (i = 0; i < bt->out_len; i++) { + if ((!test_nl || + (test_nl && (i % 64 != 0 || i == bt->out_len - 1))) && + (bt->out[i] == '\r' || bt->out[i] == '\n')) + continue; + buf[b64len++] = bt->out[i]; + } + if (test_nl) + buf[b64len++] = '\n'; + + len = BIO_get_mem_data(bio_mem, &out); + + /* An empty string with NL results in no output, rather than '\n'. */ + if (test_nl && b64len == 1 && len == 0) + goto done; + + if (len != b64len) { + fprintf(stderr, "FAIL: test %d - encoding resulted in %zd " + "characters instead of %zd\n", test_no, len, b64len); + failure = 1; + goto done; + } + + if (memcmp(buf, out, b64len) != 0) { + fprintf(stderr, "FAIL: test %d - encoding differs:\n", test_no); + fprintf(stderr, " encoding: "); + for (i = 0; i < len; i++) + fprintf(stderr, "%c", out[i]); + fprintf(stderr, "\n"); + fprintf(stderr, " test data: "); + for (i = 0; i < bt->out_len; i++) + fprintf(stderr, "%c", buf[i]); + fprintf(stderr, "\n"); + failure = 1; + } + +done: + BIO_free_all(bio_mem); + free(buf); + + return failure; +} + +static int +base64_decoding_test(int test_no, struct base64_test *bt, int test_nl) +{ + BIO *bio_b64, *bio_mem; + char *buf, *input; + ssize_t i, inlen, len; + int failure = 0; + + buf = malloc(BUF_SIZE); + if (buf == NULL) + errx(1, "malloc"); + + if ((input = malloc(BUF_SIZE)) == NULL) + errx(1, "malloc"); + + memcpy(input, bt->out, bt->out_len); + inlen = bt->out_len; + if (test_nl) { + memcpy(&input[bt->out_len], "\r\n", 2); + inlen += 2; + } + + bio_mem = BIO_new_mem_buf(input, inlen); + if (bio_mem == NULL) + errx(1, "BIO_new_mem_buf failed"); + + bio_b64 = BIO_new(BIO_f_base64()); + if (bio_b64 == NULL) + errx(1, "BIO_new failed for BIO_f_base64"); + + if (!test_nl) + BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL); + + bio_mem = BIO_push(bio_b64, bio_mem); + + /* + * If we wrote zero characters then a BIO_read will result in a return + * value of -1, hence we need to handle this case. + */ + len = BIO_read(bio_mem, buf, BUF_SIZE); + if (len != bt->valid_len && (bt->in_len != 0 || len != -1)) { + fprintf(stderr, "FAIL: test %d - decoding resulted in %zd " + "characters instead of %zd\n", test_no, len, bt->valid_len); + fprintf(stderr, " input: "); + for (i = 0; i < inlen; i++) + fprintf(stderr, "%c", input[i]); + fprintf(stderr, "\n"); + fprintf(stderr, " decoding: "); + for (i = 0; i < len; i++) + fprintf(stderr, "0x%x ", buf[i]); + fprintf(stderr, "\n"); + failure = 1; + goto done; + } + + /* See if we expect this to fail decoding. */ + if (bt->in_len == -1) + goto done; + + if (memcmp(bt->in, buf, bt->in_len) != 0) { + fprintf(stderr, "FAIL: test %d - decoding differs:\n", test_no); + fprintf(stderr, " decoding: "); + for (i = 0; i < len; i++) + fprintf(stderr, "0x%x ", buf[i]); + fprintf(stderr, "\n"); + fprintf(stderr, " test data: "); + for (i = 0; i < bt->in_len; i++) + fprintf(stderr, "0x%x ", bt->in[i]); + fprintf(stderr, "\n"); + failure = 1; + } + +done: + BIO_free_all(bio_mem); + free(buf); + free(input); + + return failure; +} + +int +main(int argc, char **argv) +{ + struct base64_test *bt; + int failed = 0; + size_t i; + + fprintf(stderr, "Starting combined tests...\n"); + + for (i = 0; i < N_TESTS; i++) { + bt = &base64_tests[i]; + if (bt->in_len != -1) + failed += base64_encoding_test(i, bt, 0); + if (bt->out_len != -1) + failed += base64_decoding_test(i, bt, 0); + if (bt->in_len != -1) + failed += base64_encoding_test(i, bt, 1); + if (bt->out_len != -1) + failed += base64_decoding_test(i, bt, 1); + } + + fprintf(stderr, "Starting NL tests...\n"); + + for (i = 0; i < N_NL_TESTS; i++) { + bt = &base64_nl_tests[i]; + + if (bt->in_len != -1) + failed += base64_encoding_test(i, bt, 1); + if (bt->out_len != -1) + failed += base64_decoding_test(i, bt, 1); + } + + fprintf(stderr, "Starting NO NL tests...\n"); + + for (i = 0; i < N_NO_NL_TESTS; i++) { + bt = &base64_no_nl_tests[i]; + + if (bt->in_len != -1) + failed += base64_encoding_test(i, bt, 0); + if (bt->out_len != -1) + failed += base64_decoding_test(i, bt, 0); + } + + return failed; +} diff --git a/Libraries/libressl/tests/bf_test.c b/Libraries/libressl/tests/bf_test.c new file mode 100644 index 000000000..153444e9d --- /dev/null +++ b/Libraries/libressl/tests/bf_test.c @@ -0,0 +1,1368 @@ +/* $OpenBSD: bf_test.c,v 1.2 2022/11/07 23:04:25 joshua Exp $ */ +/* + * Copyright (c) 2022 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +struct bf_test { + const int mode; + const uint8_t key[64]; + const int key_len; + const uint8_t iv[64]; + const int iv_len; + const uint8_t in[64]; + const int in_len; + const uint8_t out[64]; + const int out_len; + const int padding; +}; + +static const struct bf_test bf_tests[] = { + /* + * ECB - Test vectors from + * https://www.schneier.com/wp-content/uploads/2015/12/vectors-2.txt + */ + { + .mode = NID_bf_ecb, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }, + .key_len = 8, + .in = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }, + .in_len = 8, + .out = { + 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .in = { + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .in_len = 8, + .out = { + 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + }, + .key_len = 8, + .in = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + }, + .in_len = 8, + .out = { + 0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .key_len = 8, + .in = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + }, + .in_len = 8, + .out = { + 0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + }, + .key_len = 8, + .in = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .in_len = 8, + .out = { + 0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }, + .key_len = 8, + .in = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .in_len = 8, + .out = { + 0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57, + }, + .key_len = 8, + .in = { + 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42, + }, + .in_len = 8, + .out = { + 0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E, + }, + .key_len = 8, + .in = { + 0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA, + }, + .in_len = 8, + .out = { + 0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86, + }, + .key_len = 8, + .in = { + 0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72, + }, + .in_len = 8, + .out = { + 0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E, + }, + .key_len = 8, + .in = { + 0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A, + }, + .in_len = 8, + .out = { + 0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6, + }, + .key_len = 8, + .in = { + 0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2, + }, + .in_len = 8, + .out = { + 0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE, + }, + .key_len = 8, + .in = { + 0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A, + }, + .in_len = 8, + .out = { + 0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6, + }, + .key_len = 8, + .in = { + 0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2, + }, + .in_len = 8, + .out = { + 0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE, + }, + .key_len = 8, + .in = { + 0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A, + }, + .in_len = 8, + .out = { + 0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16, + }, + .key_len = 8, + .in = { + 0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02, + }, + .in_len = 8, + .out = { + 0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, + }, + .key_len = 8, + .in = { + 0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A, + }, + .in_len = 8, + .out = { + 0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46, + }, + .key_len = 8, + .in = { + 0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32, + }, + .in_len = 8, + .out = { + 0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E, + }, + .key_len = 8, + .in = { + 0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA, + }, + .in_len = 8, + .out = { + 0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, + }, + .key_len = 8, + .in = { + 0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62, + }, + .in_len = 8, + .out = { + 0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07, + }, + .key_len = 8, + .in = { + 0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2, + }, + .in_len = 8, + .out = { + 0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F, + }, + .key_len = 8, + .in = { + 0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA, + }, + .in_len = 8, + .out = { + 0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7, + }, + .key_len = 8, + .in = { + 0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92, + }, + .in_len = 8, + .out = { + 0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF, + }, + .key_len = 8, + .in = { + 0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A, + }, + .in_len = 8, + .out = { + 0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6, + }, + .key_len = 8, + .in = { + 0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2, + }, + .in_len = 8, + .out = { + 0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF, + }, + .key_len = 8, + .in = { + 0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A, + }, + .in_len = 8, + .out = { + 0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + }, + .key_len = 8, + .in = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .in_len = 8, + .out = { + 0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, + }, + .key_len = 8, + .in = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .in_len = 8, + .out = { + 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE, + }, + .key_len = 8, + .in = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .in_len = 8, + .out = { + 0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .in = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }, + .in_len = 8, + .out = { + 0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }, + .key_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + }, + .key_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A, + }, + .out_len = 8, + }, + { + .mode = NID_bf_ecb, + .key = { + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }, + .key_len = 8, + .in = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }, + .in_len = 8, + .out = { + 0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A, + }, + .out_len = 8, + }, + + /* + * CBC - Test vector from + * https://www.schneier.com/wp-content/uploads/2015/12/vectors-2.txt + */ + { + .mode = NID_bf_cbc, + .key = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + }, + .key_len = 16, + .iv = { + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }, + .iv_len = 8, + .in = { + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 32, + .out = { + 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6, + 0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93, + 0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9, + 0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC, + }, + .out_len = 32, + .padding = 0, + }, + + /* CBC (generated using https://github.com/joshuasing/libressl-test-gen) */ + { + .mode = NID_bf_cbc, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78, + 0xe1, 0xc0, 0x30, 0xe7, 0x4c, 0x14, 0xd2, 0x61, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0xb9, 0x95, 0xf2, 0x4d, 0xdf, 0xe8, 0x7b, 0xf0, + 0x05, 0x3c, 0x33, 0x39, 0x43, 0x35, 0x83, 0x62, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in_len = 16, + .out = { + 0x86, 0x6f, 0x5e, 0x72, 0xe5, 0x9a, 0x19, 0x51, + 0x56, 0xf3, 0x2f, 0x5e, 0x95, 0xfb, 0xd6, 0x52, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0xb9, 0x95, 0xf2, 0x4d, 0xdf, 0xe8, 0x7b, 0xf0, + 0x00, 0xf6, 0x2e, 0xf6, 0x6a, 0x03, 0x2d, 0x40, + 0x9c, 0xc9, 0x06, 0x31, 0x67, 0x7f, 0x6e, 0x24, + 0xeb, 0x2d, 0x3b, 0x02, 0xa3, 0x53, 0x52, 0xe9, + }, + .out_len = 32, + }, + { + .mode = NID_bf_cbc, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78, + 0xe1, 0xc0, 0x30, 0xe7, 0x4c, 0x14, 0xd2, 0x61, + 0x8b, 0xa5, 0x5d, 0x18, 0x27, 0x44, 0x9c, 0xd3, + }, + .out_len = 24, + .padding = 1, + }, + { + .mode = NID_bf_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 12, + .out = { + 0xc0, 0x1f, 0xae, 0x76, 0x86, 0x86, 0xe7, 0xb7, + 0x3b, 0x0d, 0xd9, 0x72, 0x33, 0x2b, 0x38, 0x5d, + }, + .out_len = 16, + .padding = 1, + }, + + /* CFB64 (generated using https://github.com/joshuasing/libressl-test-gen) */ + { + .mode = NID_bf_cfb64, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78, + 0xe1, 0xc0, 0x30, 0xe7, 0x4c, 0x14, 0xd2, 0x61, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0xb9, 0x95, 0xf2, 0x4d, 0xdf, 0xe8, 0x7b, 0xf0, + 0x05, 0x3c, 0x33, 0x39, 0x43, 0x35, 0x83, 0x62, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in_len = 16, + .out = { + 0xb9, 0x94, 0xf0, 0x4e, 0xdb, 0xed, 0x7d, 0xf7, + 0x0a, 0xf8, 0x96, 0xbf, 0x4d, 0x3c, 0x95, 0xdf, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0x86, 0x6e, 0x5c, 0x71, 0xe1, 0x9f, 0x1f, 0x56, + 0x1f, 0x02, 0xaa, 0x8c, 0x09, 0xe0, 0x61, 0x43, + 0x91, 0x8d, 0xd2, 0x43, 0x70, 0x5d, 0xa3, 0xf1, + 0xc7, 0x96, 0x56, 0x77, 0xfc, 0x33, 0x74, 0x9e, + }, + .out_len = 32, + }, + { + .mode = NID_bf_cfb64, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78, + 0xe1, 0xc0, 0x30, 0xe7, 0x4c, 0x14, 0xd2, 0x61, + }, + .out_len = 16, + }, + { + .mode = NID_bf_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 12, + .out = { + 0xc0, 0x1f, 0xae, 0x76, 0x86, 0x86, 0xe7, 0xb7, + 0x05, 0xbb, 0xd4, 0x5e, + }, + .out_len = 12, + }, + + /* OFB64 (generated using https://github.com/joshuasing/libressl-test-gen) */ + { + .mode = NID_bf_ofb64, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78, + 0xe1, 0xc0, 0x30, 0xe7, 0x4c, 0x14, 0xd2, 0x61, + }, + .out_len = 16, + }, + { + .mode = NID_bf_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0xb9, 0x95, 0xf2, 0x4d, 0xdf, 0xe8, 0x7b, 0xf0, + 0x05, 0x3c, 0x33, 0x39, 0x43, 0x35, 0x83, 0x62, + }, + .out_len = 16, + }, + { + .mode = NID_bf_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in_len = 16, + .out = { + 0xb9, 0x94, 0xf0, 0x4e, 0xdb, 0xed, 0x7d, 0xf7, + 0x0d, 0x35, 0x39, 0x32, 0x4f, 0x38, 0x8d, 0x6d, + }, + .out_len = 16, + }, + { + .mode = NID_bf_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0x86, 0x6e, 0x5c, 0x71, 0xe1, 0x9f, 0x1f, 0x56, + 0xbb, 0xcb, 0xd9, 0x35, 0x81, 0x57, 0xea, 0xb9, + 0xd7, 0x85, 0x28, 0x4a, 0xdc, 0xeb, 0x94, 0x99, + 0xf0, 0x87, 0x7c, 0x5a, 0x56, 0x60, 0xc7, 0x60, + }, + .out_len = 32, + }, + { + .mode = NID_bf_ofb64, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78, + 0xe1, 0xc0, 0x30, 0xe7, 0x4c, 0x14, 0xd2, 0x61, + }, + .out_len = 16, + }, + { + .mode = NID_bf_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .key_len = 8, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 12, + .out = { + 0xc0, 0x1f, 0xae, 0x76, 0x86, 0x86, 0xe7, 0xb7, + 0x05, 0xbb, 0xd4, 0x5e, + }, + .out_len = 12, + }, +}; + +#define N_BF_TESTS (sizeof(bf_tests) / sizeof(bf_tests[0])) + +static int +bf_ecb_test(size_t test_number, const struct bf_test *bt) +{ + BF_KEY key; + uint8_t out[8]; + + if (bt->padding) { + /* XXX - Handle padding */ + return 1; + } + + /* Encryption */ + memset(out, 0, sizeof(out)); + BF_set_key(&key, bt->key_len, bt->key); + BF_ecb_encrypt(bt->in, out, &key, 1); + + if (memcmp(bt->out, out, bt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_bf_ecb, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + BF_set_key(&key, bt->key_len, bt->key); + BF_ecb_encrypt(bt->out, out, &key, 0); + + if (memcmp(bt->in, out, bt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_bf_ecb, test_number); + return 0; + } + + return 1; +} + +static int +bf_cbc_test(size_t test_number, const struct bf_test *bt) +{ + BF_KEY key; + uint8_t out[512]; + uint8_t iv[64]; + + if (bt->padding) { + /* XXX - Handle padding */ + return 1; + } + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, bt->iv, bt->iv_len); + BF_set_key(&key, bt->key_len, bt->key); + BF_cbc_encrypt(bt->in, out, bt->in_len, &key, iv, 1); + + if (memcmp(bt->out, out, bt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_bf_cbc, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, bt->iv, bt->iv_len); + BF_set_key(&key, bt->key_len, bt->key); + BF_cbc_encrypt(bt->out, out, bt->out_len, &key, iv, 0); + + if (memcmp(bt->in, out, bt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_bf_cbc, test_number); + return 0; + } + + return 1; +} + +static int +bf_cfb64_test(size_t test_number, const struct bf_test *bt) +{ + BF_KEY key; + uint8_t out[512]; + uint8_t iv[64]; + int remainder = 0; + + if (bt->padding) { + /* XXX - Handle padding */ + return 1; + } + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, bt->iv, bt->iv_len); + BF_set_key(&key, bt->key_len, bt->key); + BF_cfb64_encrypt(bt->in, out, bt->in_len * 8, &key, iv, &remainder, 1); + + if (memcmp(bt->out, out, bt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_bf_cfb64, test_number); + return 0; + } + + /* Decryption */ + remainder = 0; + memset(out, 0, sizeof(out)); + memcpy(iv, bt->iv, bt->iv_len); + BF_set_key(&key, bt->key_len, bt->key); + BF_cfb64_encrypt(bt->out, out, bt->out_len, &key, iv, &remainder, 0); + + if (memcmp(bt->in, out, bt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_bf_cfb64, test_number); + return 0; + } + + return 1; +} + +static int +bf_ofb64_test(size_t test_number, const struct bf_test *bt) +{ + BF_KEY key; + uint8_t out[512]; + uint8_t iv[64]; + int remainder = 0; + + if (bt->padding) { + /* XXX - Handle padding */ + return 1; + } + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, bt->iv, bt->iv_len); + BF_set_key(&key, bt->key_len, bt->key); + BF_ofb64_encrypt(bt->in, out, bt->in_len, &key, iv, &remainder); + + if (memcmp(bt->out, out, bt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_bf_ofb64, test_number); + return 0; + } + + /* Decryption */ + remainder = 0; + memset(out, 0, sizeof(out)); + memcpy(iv, bt->iv, bt->iv_len); + BF_set_key(&key, bt->key_len, bt->key); + BF_ofb64_encrypt(bt->out, out, bt->out_len, &key, iv, &remainder); + + if (memcmp(bt->in, out, bt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_bf_ofb64, test_number); + return 0; + } + + return 1; +} + +static int +bf_evp_test(size_t test_number, const struct bf_test *bt, const char *label, + const EVP_CIPHER *cipher) +{ + EVP_CIPHER_CTX *ctx; + uint8_t out[512]; + int in_len, out_len, total_len; + int i; + int success = 0; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_new failed\n", + label, test_number); + goto failed; + } + + /* EVP encryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_EncryptInit(ctx, cipher, NULL, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_key_length(ctx, bt->key_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_key_length failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_padding(ctx, bt->padding)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n", + label, test_number); + goto failed; + } + + if (!EVP_EncryptInit(ctx, NULL, bt->key, bt->iv)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n", + label, test_number); + goto failed; + } + + for (i = 0; i < bt->in_len;) { + in_len = arc4random_uniform(bt->in_len / 2); + if (in_len > bt->in_len - i) + in_len = bt->in_len - i; + + if (!EVP_EncryptUpdate(ctx, out + total_len, &out_len, + bt->in + i, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_EncryptUpdate failed\n", + label, test_number); + goto failed; + } + + i += in_len; + total_len += out_len; + } + + if (!EVP_EncryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptFinal_ex failed\n", + label, test_number); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n", + label, test_number); + goto failed; + } + + if (total_len != bt->out_len) { + fprintf(stderr, + "FAIL (%s:%zu): EVP encryption length mismatch " + "(%d != %d)\n", label, test_number, total_len, bt->out_len); + goto failed; + } + + if (memcmp(bt->out, out, bt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP encryption mismatch\n", + label, test_number); + goto failed; + } + + /* EVP decryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_DecryptInit(ctx, cipher, NULL, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_key_length(ctx, bt->key_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_key_length failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_padding(ctx, bt->padding)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n", + label, test_number); + goto failed; + } + + if (!EVP_DecryptInit(ctx, NULL, bt->key, bt->iv)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n", + label, test_number); + goto failed; + } + + for (i = 0; i < bt->out_len;) { + in_len = arc4random_uniform(bt->out_len / 2); + if (in_len > bt->out_len - i) + in_len = bt->out_len - i; + + if (!EVP_DecryptUpdate(ctx, out + total_len, &out_len, + bt->out + i, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DecryptUpdate failed\n", + label, test_number); + goto failed; + } + + i += in_len; + total_len += out_len; + } + + if (!EVP_DecryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptFinal_ex failed\n", + label, test_number); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n", + label, test_number); + goto failed; + } + + if (total_len != bt->in_len) { + fprintf(stderr, + "FAIL (%s:%zu): EVP decryption length mismatch\n", + label, test_number); + goto failed; + } + + if (memcmp(bt->in, out, bt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP decryption mismatch\n", + label, test_number); + goto failed; + } + + success = 1; + + failed: + EVP_CIPHER_CTX_free(ctx); + return success; +} + +static int +bf_test(void) +{ + const struct bf_test *bt; + const char *label; + const EVP_CIPHER *cipher; + size_t i; + int failed = 1; + + for (i = 0; i < N_BF_TESTS; i++) { + bt = &bf_tests[i]; + switch (bt->mode) { + case NID_bf_ecb: + label = SN_bf_ecb; + cipher = EVP_bf_ecb(); + if (!bf_ecb_test(i, bt)) + goto failed; + break; + case NID_bf_cbc: + label = SN_bf_cbc; + cipher = EVP_bf_cbc(); + if (!bf_cbc_test(i, bt)) + goto failed; + break; + case NID_bf_cfb64: + label = SN_bf_cfb64; + cipher = EVP_bf_cfb64(); + if (!bf_cfb64_test(i, bt)) + goto failed; + break; + case NID_bf_ofb64: + label = SN_bf_ofb64; + cipher = EVP_bf_ofb(); + if (!bf_ofb64_test(i, bt)) + goto failed; + break; + default: + fprintf(stderr, "FAIL: unknown mode (%d)\n", + bt->mode); + goto failed; + } + + if (!bf_evp_test(i, bt, label, cipher)) + goto failed; + } + + failed = 0; + + failed: + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= bf_test(); + + return failed; +} + diff --git a/Libraries/libressl/tests/bio_asn1.c b/Libraries/libressl/tests/bio_asn1.c new file mode 100644 index 000000000..3eba1849b --- /dev/null +++ b/Libraries/libressl/tests/bio_asn1.c @@ -0,0 +1,232 @@ +/* $OpenBSD: bio_asn1.c,v 1.5 2023/07/21 20:22:47 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "asn1_local.h" + +/* + * Minimal reproducer for the BIO_new_NDEF() write after free fixed in + * bio_ndef.c r1.13. + */ + +static int +waf_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + return 0; +} + +static const ASN1_AUX WAF_aux = { + .asn1_cb = waf_cb, +}; + +static const ASN1_ITEM WAF_it = { + .funcs = &WAF_aux, +}; + +static int +test_bio_new_ndef_waf(void) +{ + BIO *out = NULL; + int failed = 1; + + if ((out = BIO_new(BIO_s_mem())) == NULL) + goto err; + + /* + * BIO_new_NDEF() pushes out onto asn_bio. The waf_cb() call fails. + * Prior to bio_ndef.c r1.13, asn_bio was freed and out->prev_bio + * still pointed to it. + */ + + if (BIO_new_NDEF(out, NULL, &WAF_it) != NULL) { + fprintf(stderr, "%s: BIO_new_NDEF succeeded\n", __func__); + goto err; + } + + /* + * If out->prev_bio != NULL, this writes to out->prev_bio->next_bio. + * After bio_ndef.c r1.13, out is an isolated BIO, so this is a noop. + */ + + BIO_pop(out); + + failed = 0; + + err: + BIO_free(out); + + return failed; +} + +/* + * test_prefix_leak() leaks before asn/bio_asn1.c r1.19. + */ + +static long +read_leak_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret) +{ + int read_return = BIO_CB_READ | BIO_CB_RETURN; + char *set_me; + + if ((cmd & read_return) != read_return) + return ret; + + set_me = BIO_get_callback_arg(bio); + *set_me = 1; + + return 0; +} + +static int +test_prefix_leak(void) +{ + BIO *bio_in = NULL, *bio_out = NULL; + PKCS7 *pkcs7 = NULL; + char set_me = 0; + int failed = 1; + + if ((bio_in = BIO_new_mem_buf("some data\n", -1)) == NULL) + goto err; + + BIO_set_callback(bio_in, read_leak_cb); + BIO_set_callback_arg(bio_in, &set_me); + + if ((pkcs7 = PKCS7_new()) == NULL) + goto err; + if (!PKCS7_set_type(pkcs7, NID_pkcs7_data)) + goto err; + + if ((bio_out = BIO_new(BIO_s_mem())) == NULL) + goto err; + + if (!i2d_PKCS7_bio_stream(bio_out, pkcs7, bio_in, + SMIME_STREAM | SMIME_BINARY)) + goto err; + + if (set_me != 1) { + fprintf(stderr, "%s: read_leak_cb didn't set set_me", __func__); + goto err; + } + + failed = 0; + + err: + BIO_free(bio_in); + BIO_free(bio_out); + PKCS7_free(pkcs7); + + return failed; +} + +/* + * test_infinite_loop() would hang before asn/bio_asn1.c r1.18. + */ + +#define SENTINEL (-57) + +static long +inf_loop_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret) +{ + int write_return = BIO_CB_WRITE | BIO_CB_RETURN; + char *set_me; + + if ((cmd & write_return) != write_return) + return ret; + + set_me = BIO_get_callback_arg(bio); + + /* First time around: ASN1_STATE_HEADER_COPY - succeed. */ + if (*set_me == 0) { + *set_me = 1; + return ret; + } + + /* Second time around: ASN1_STATE_DATA_COPY - return sentinel value. */ + if (*set_me == 1) { + *set_me = 2; + return SENTINEL; + } + + /* Everything else is unexpected: return EOF. */ + *set_me = 3; + + return 0; + +} + +static int +test_infinite_loop(void) +{ + BIO *asn_bio = NULL, *bio = NULL; + char set_me = 0; + int failed = 1; + int write_ret; + + if ((asn_bio = BIO_new(BIO_f_asn1())) == NULL) + goto err; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto err; + + BIO_set_callback(bio, inf_loop_cb); + BIO_set_callback_arg(bio, &set_me); + + if (BIO_push(asn_bio, bio) == NULL) { + BIO_free(bio); + goto err; + } + + if ((write_ret = BIO_write(asn_bio, "foo", 3)) != SENTINEL) { + fprintf(stderr, "%s: BIO_write: want %d, got %d", __func__, + SENTINEL, write_ret); + goto err; + } + + if (set_me != 2) { + fprintf(stderr, "%s: set_me: %d != 2", __func__, set_me); + goto err; + } + + failed = 0; + err: + BIO_free_all(asn_bio); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= test_bio_new_ndef_waf(); + failed |= test_prefix_leak(); + failed |= test_infinite_loop(); + + return failed; +} diff --git a/Libraries/libressl/tests/bio_chain.c b/Libraries/libressl/tests/bio_chain.c new file mode 100644 index 000000000..abf475bc4 --- /dev/null +++ b/Libraries/libressl/tests/bio_chain.c @@ -0,0 +1,515 @@ +/* $OpenBSD: bio_chain.c,v 1.16 2023/08/07 11:00:54 tb Exp $ */ +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include "bio_local.h" + +#ifndef nitems +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#endif + +#define CHAIN_POP_LEN 5 +#define LINK_CHAIN_A_LEN 8 +#define LINK_CHAIN_B_LEN 5 + +static BIO * +BIO_prev(BIO *bio) +{ + if (bio == NULL) + return NULL; + + return bio->prev_bio; +} + +static void bio_chain_destroy(BIO **, size_t); + +static int +bio_chain_create(const BIO_METHOD *meth, BIO *chain[], size_t len) +{ + BIO *prev; + size_t i; + + memset(chain, 0, len * sizeof(BIO *)); + + prev = NULL; + for (i = 0; i < len; i++) { + if ((chain[i] = BIO_new(meth)) == NULL) { + fprintf(stderr, "BIO_new failed\n"); + goto err; + } + if ((prev = BIO_push(prev, chain[i])) == NULL) { + fprintf(stderr, "BIO_push failed\n"); + goto err; + } + } + + return 1; + + err: + bio_chain_destroy(chain, len); + + return 0; +} + +static void +bio_chain_destroy(BIO *chain[], size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + BIO_free(chain[i]); + + memset(chain, 0, len * sizeof(BIO *)); +} + +static int +bio_chain_pop_test(void) +{ + BIO *bio[CHAIN_POP_LEN]; + BIO *prev, *next; + size_t i, j; + int failed = 1; + + for (i = 0; i < nitems(bio); i++) { + memset(bio, 0, sizeof(bio)); + prev = NULL; + + if (!bio_chain_create(BIO_s_null(), bio, nitems(bio))) + goto err; + + /* Check that the doubly-linked list was set up as expected. */ + if (BIO_prev(bio[0]) != NULL) { + fprintf(stderr, + "i = %zu: first BIO has predecessor\n", i); + goto err; + } + if (BIO_next(bio[nitems(bio) - 1]) != NULL) { + fprintf(stderr, "i = %zu: last BIO has successor\n", i); + goto err; + } + for (j = 0; j < nitems(bio); j++) { + if (j > 0) { + if (BIO_prev(bio[j]) != bio[j - 1]) { + fprintf(stderr, "i = %zu: " + "BIO_prev(bio[%zu]) != bio[%zu]\n", + i, j, j - 1); + goto err; + } + } + if (j < nitems(bio) - 1) { + if (BIO_next(bio[j]) != bio[j + 1]) { + fprintf(stderr, "i = %zu: " + "BIO_next(bio[%zu]) != bio[%zu]\n", + i, j, j + 1); + goto err; + } + } + } + + /* Drop the ith bio from the chain. */ + next = BIO_pop(bio[i]); + + if (BIO_prev(bio[i]) != NULL || BIO_next(bio[i]) != NULL) { + fprintf(stderr, + "BIO_pop() didn't isolate bio[%zu]\n", i); + goto err; + } + + if (i < nitems(bio) - 1) { + if (next != bio[i + 1]) { + fprintf(stderr, "BIO_pop(bio[%zu]) did not " + "return bio[%zu]\n", i, i + 1); + goto err; + } + } else { + if (next != NULL) { + fprintf(stderr, "i = %zu: " + "BIO_pop(last) != NULL\n", i); + goto err; + } + } + + /* + * Walk the remainder of the chain and see if the doubly linked + * list checks out. + */ + if (i == 0) { + prev = bio[1]; + j = 2; + } else { + prev = bio[0]; + j = 1; + } + + for (; j < nitems(bio); j++) { + if (j == i) + continue; + if (BIO_next(prev) != bio[j]) { + fprintf(stderr, "i = %zu, j = %zu: " + "BIO_next(prev) != bio[%zu]\n", i, j, j); + goto err; + } + if (BIO_prev(bio[j]) != prev) { + fprintf(stderr, "i = %zu, j = %zu: " + "BIO_prev(bio[%zu]) != prev\n", i, j, j); + goto err; + } + prev = bio[j]; + } + + if (BIO_next(prev) != NULL) { + fprintf(stderr, "i = %zu: BIO_next(prev) != NULL\n", i); + goto err; + } + + bio_chain_destroy(bio, nitems(bio)); + } + + failed = 0; + + err: + bio_chain_destroy(bio, nitems(bio)); + + return failed; +} + +static void +walk(BIO *(*step)(BIO *), BIO *start, BIO **end, size_t *len) +{ + BIO *current = NULL; + BIO *next = start; + + *len = 0; + while (next != NULL) { + current = next; + next = step(current); + (*len)++; + } + *end = current; +} + +static int +walk_report(BIO *last, BIO *expected_last, size_t len, size_t expected_len, + size_t i, size_t j, const char *fn, const char *description, + const char *direction, const char *last_name) +{ + if (last != expected_last) { + fprintf(stderr, "%s case (%zu, %zu) %s %s has unexpected %s\n", + fn, i, j, description, direction, last_name); + return 0; + } + + if (len != expected_len) { + fprintf(stderr, "%s case (%zu, %zu) %s %s want %zu, got %zu\n", + fn, i, j, description, direction, expected_len, len); + return 0; + } + + return 1; +} + +static int +walk_forward(BIO *start, BIO *expected_end, size_t expected_len, + size_t i, size_t j, const char *fn, const char *description) +{ + BIO *end; + size_t len; + + walk(BIO_next, start, &end, &len); + + return walk_report(end, expected_end, len, expected_len, + i, j, fn, description, "forward", "end"); +} + +static int +walk_backward(BIO *expected_start, BIO *end, size_t expected_len, + size_t i, size_t j, const char *fn, const char *description) +{ + BIO *start; + size_t len; + + walk(BIO_prev, end, &start, &len); + + return walk_report(start, expected_start, len, expected_len, + i, j, fn, description, "backward", "start"); +} + +static int +check_chain(BIO *start, BIO *end, size_t expected_len, size_t i, size_t j, + const char *fn, const char *description) +{ + if (!walk_forward(start, end, expected_len, i, j, fn, description)) + return 0; + + if (!walk_backward(start, end, expected_len, i, j, fn, description)) + return 0; + + return 1; +} + +/* + * Link two linear chains of BIOs A[] and B[] together using either + * BIO_push(A[i], B[j]) or BIO_set_next(A[i], B[j]). + * + * BIO_push() first walks the chain A[] to its end and then appends the tail + * of chain B[] starting at B[j]. If j > 0, we get two chains + * + * A[0] -- ... -- A[nitems(A) - 1] -- B[j] -- ... -- B[nitems(B) - 1] + * `- link created by BIO_push() + * B[0] -- ... -- B[j-1] + * |<-- oldhead -->| + * + * of lengths nitems(A) + nitems(B) - j and j, respectively. + * If j == 0, the second chain (oldhead) is empty. One quirk of BIO_push() is + * that the outcome of BIO_push(A[i], B[j]) apart from the return value is + * independent of i. + * + * Prior to bio_lib.c r1.41, BIO_push(A[i], B[j]) would fail to dissociate the + * two chains and leave B[j] with two parents for 0 < j < nitems(B). + * B[j]->prev_bio would point at A[nitems(A) - 1], while both B[j - 1] and + * A[nitems(A) - 1] would point at B[j]. In particular, BIO_free_all(A[0]) + * followed by BIO_free_all(B[0]) results in a double free of B[j]. + * + * The result for BIO_set_next() is different: three chains are created. + * + * |--- oldtail --> + * ... -- A[i-1] -- A[i] -- A[i+1] -- ... + * \ + * \ link created by BIO_set_next() + * --- oldhead -->| \ + * ... -- B[j-1] -- B[j] -- B[j+1] -- ... + * + * After creating a new link, the new chain has length i + 1 + nitems(B) - j, + * oldtail has length nitems(A) - i - 1 and oldhead has length j. + * + * Prior to bio_lib.c r1.40, BIO_set_next(A[i], B[j]) would result in both A[i] + * and B[j - 1] pointing at B[j] while B[j] would point back at A[i]. Calling + * BIO_free_all(A[0]) and BIO_free_all(B[0]) results in a double free of B[j]. + * + * XXX: Should check that the callback is called on BIO_push() as expected. + */ + +static int +link_chains_at(size_t i, size_t j, int use_bio_push) +{ + const char *fn = use_bio_push ? "BIO_push" : "BIO_set_next"; + BIO *A[LINK_CHAIN_A_LEN], *B[LINK_CHAIN_B_LEN]; + BIO *new_start, *new_end; + BIO *oldhead_start, *oldhead_end, *oldtail_start, *oldtail_end; + size_t new_len, oldhead_len, oldtail_len; + int failed = 1; + + memset(A, 0, sizeof(A)); + memset(B, 0, sizeof(B)); + + if (i >= nitems(A) || j >= nitems(B)) + goto err; + + /* Create two linear chains of BIOs. */ + if (!bio_chain_create(BIO_s_null(), A, nitems(A))) + goto err; + if (!bio_chain_create(BIO_s_null(), B, nitems(B))) + goto err; + + /* + * Set our expectations. ... it's complicated. + */ + + new_start = A[0]; + new_end = B[nitems(B) - 1]; + /* new_len depends on use_bio_push. It is set a few lines down. */ + + oldhead_start = B[0]; + oldhead_end = BIO_prev(B[j]); + oldhead_len = j; + + /* If we push B[0] or set next to B[0], the oldhead chain is empty. */ + if (j == 0) { + oldhead_start = NULL; + oldhead_end = NULL; + oldhead_len = 0; + } + + if (use_bio_push) { + new_len = nitems(A) + nitems(B) - j; + + /* oldtail doesn't exist in the BIO_push() case. */ + oldtail_start = NULL; + oldtail_end = NULL; + oldtail_len = 0; + } else { + new_len = i + 1 + nitems(B) - j; + + oldtail_start = BIO_next(A[i]); + oldtail_end = A[nitems(A) - 1]; + oldtail_len = nitems(A) - i - 1; + + /* If we set next on end of A[], the oldtail chain is empty. */ + if (i == nitems(A) - 1) { + oldtail_start = NULL; + oldtail_end = NULL; + oldtail_len = 0; + } + } + + /* The two chains A[] and B[] are split into three disjoint pieces. */ + if (nitems(A) + nitems(B) != new_len + oldtail_len + oldhead_len) { + fprintf(stderr, "%s case (%zu, %zu) inconsistent lengths: " + "%zu + %zu != %zu + %zu + %zu\n", fn, i, j, + nitems(A), nitems(B), new_len, oldtail_len, oldhead_len); + goto err; + } + + /* + * Now actually push or set next. + */ + + if (use_bio_push) { + if (BIO_push(A[i], B[j]) != A[i]) { + fprintf(stderr, "BIO_push(A[%zu], B[%zu]) != A[%zu]\n", + i, j, i); + goto err; + } + } else { + BIO_set_next(A[i], B[j]); + } + + /* + * Check that all the chains match our expectations. + */ + + if (!check_chain(new_start, new_end, new_len, i, j, fn, "new chain")) + goto err; + + if (!check_chain(oldhead_start, oldhead_end, oldhead_len, i, j, fn, + "oldhead")) + goto err; + + if (!check_chain(oldtail_start, oldtail_end, oldtail_len, i, j, fn, + "oldtail")) + goto err; + + /* + * All sanity checks passed. We can now free the chains + * with the BIO API without risk of leaks or double frees. + */ + + BIO_free_all(new_start); + BIO_free_all(oldhead_start); + BIO_free_all(oldtail_start); + + memset(A, 0, sizeof(A)); + memset(B, 0, sizeof(B)); + + failed = 0; + + err: + bio_chain_destroy(A, nitems(A)); + bio_chain_destroy(B, nitems(B)); + + return failed; +} + +static int +link_chains(int use_bio_push) +{ + size_t i, j; + int failure = 0; + + for (i = 0; i < LINK_CHAIN_A_LEN; i++) { + for (j = 0; j < LINK_CHAIN_B_LEN; j++) { + failure |= link_chains_at(i, j, use_bio_push); + } + } + + return failure; +} + +static int +bio_push_link_test(void) +{ + int use_bio_push = 1; + + return link_chains(use_bio_push); +} + +static int +bio_set_next_link_test(void) +{ + int use_bio_push = 0; + + return link_chains(use_bio_push); +} + +static long +dup_leak_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret) +{ + if (argi == BIO_CTRL_DUP) + return 0; + + return ret; +} + +static int +bio_dup_chain_leak(void) +{ + BIO *bio[CHAIN_POP_LEN]; + BIO *dup; + int failed = 1; + + if (!bio_chain_create(BIO_s_null(), bio, nitems(bio))) + goto err; + + if ((dup = BIO_dup_chain(bio[0])) == NULL) { + fprintf(stderr, "BIO_set_callback() failed\n"); + goto err; + } + + BIO_set_callback(bio[CHAIN_POP_LEN - 1], dup_leak_cb); + + BIO_free_all(dup); + if ((dup = BIO_dup_chain(bio[0])) != NULL) { + fprintf(stderr, "BIO_dup_chain() succeeded unexpectedly\n"); + BIO_free_all(dup); + goto err; + } + + failed = 0; + + err: + bio_chain_destroy(bio, nitems(bio)); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= bio_chain_pop_test(); + failed |= bio_push_link_test(); + failed |= bio_set_next_link_test(); + failed |= bio_dup_chain_leak(); + + return failed; +} diff --git a/Libraries/libressl/tests/bio_host.c b/Libraries/libressl/tests/bio_host.c new file mode 100644 index 000000000..b3a464516 --- /dev/null +++ b/Libraries/libressl/tests/bio_host.c @@ -0,0 +1,154 @@ +/* $OpenBSD: bio_host.c,v 1.1 2022/12/08 17:49:02 tb Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include + +#include + +struct bio_get_host_ip_test { + char *input; + uint32_t ip; + int ret; +}; + +struct bio_get_host_ip_test bio_get_host_ip_tests[] = { + {"", 0, 0}, + {".", 0, 0}, + {"1", 0, 0}, + {"1.2", 0, 0}, + {"1.2.3", 0, 0}, + {"1.2.3.", 0, 0}, + {"1.2.3.4", 0x01020304, 1}, + {"1.2.3.256", 0, 0}, + {"1:2:3::4", 0, 0}, + {"0.0.0.0", INADDR_ANY, 1}, + {"127.0.0.1", INADDR_LOOPBACK, 1}, + {"localhost", INADDR_LOOPBACK, 1}, + {"255.255.255.255", INADDR_BROADCAST, 1}, + {"0xff.0xff.0xff.0xff", 0, 0}, +}; + +#define N_BIO_GET_IP_TESTS \ + (sizeof(bio_get_host_ip_tests) / sizeof(*bio_get_host_ip_tests)) + +struct bio_get_port_test { + char *input; + unsigned short port; + int ret; +}; + +struct bio_get_port_test bio_get_port_tests[] = { + {NULL, 0, 0}, + {"", 0, 0}, + {"-1", 0, 0}, + {"0", 0, 1}, + {"1", 1, 1}, + {"12345", 12345, 1}, + {"65535", 65535, 1}, + {"65536", 0, 0}, + {"999999999999", 0, 0}, + {"xyzzy", 0, 0}, + {"https", 443, 1}, + {"imaps", 993, 1}, + {"telnet", 23, 1}, +}; + +#define N_BIO_GET_PORT_TESTS \ + (sizeof(bio_get_port_tests) / sizeof(*bio_get_port_tests)) + +static int +do_bio_get_host_ip_tests(void) +{ + struct bio_get_host_ip_test *bgit; + union { + unsigned char c[4]; + uint32_t i; + } ip; + int failed = 0; + size_t i; + int ret; + + for (i = 0; i < N_BIO_GET_IP_TESTS; i++) { + bgit = &bio_get_host_ip_tests[i]; + memset(&ip, 0, sizeof(ip)); + + ret = BIO_get_host_ip(bgit->input, ip.c); + if (ret != bgit->ret) { + fprintf(stderr, "FAIL: test %zd (\"%s\") %s, want %s\n", + i, bgit->input, ret ? "success" : "failure", + bgit->ret ? "success" : "failure"); + failed = 1; + continue; + } + if (ret && ntohl(ip.i) != bgit->ip) { + fprintf(stderr, "FAIL: test %zd (\"%s\") returned ip " + "%x != %x\n", i, bgit->input, + ntohl(ip.i), bgit->ip); + failed = 1; + } + } + + return failed; +} + +static int +do_bio_get_port_tests(void) +{ + struct bio_get_port_test *bgpt; + unsigned short port; + int failed = 0; + size_t i; + int ret; + + for (i = 0; i < N_BIO_GET_PORT_TESTS; i++) { + bgpt = &bio_get_port_tests[i]; + port = 0; + + ret = BIO_get_port(bgpt->input, &port); + if (ret != bgpt->ret) { + fprintf(stderr, "FAIL: test %zd (\"%s\") %s, want %s\n", + i, bgpt->input, ret ? "success" : "failure", + bgpt->ret ? "success" : "failure"); + failed = 1; + continue; + } + if (ret && port != bgpt->port) { + fprintf(stderr, "FAIL: test %zd (\"%s\") returned port " + "%u != %u\n", i, bgpt->input, port, bgpt->port); + failed = 1; + } + } + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= do_bio_get_host_ip_tests(); + failed |= do_bio_get_port_tests(); + + return failed; +} diff --git a/Libraries/libressl/tests/bio_mem.c b/Libraries/libressl/tests/bio_mem.c new file mode 100644 index 000000000..0da7ee979 --- /dev/null +++ b/Libraries/libressl/tests/bio_mem.c @@ -0,0 +1,345 @@ +/* $OpenBSD: bio_mem.c,v 1.1 2022/12/08 17:49:02 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static int +bio_mem_test(void) +{ + uint8_t *data = NULL; + size_t data_len; + uint8_t *rodata; + long rodata_len; + BUF_MEM *pbuf; + BUF_MEM *buf = NULL; + BIO *bio = NULL; + int ret; + int failed = 1; + + data_len = 4096; + if ((data = malloc(data_len)) == NULL) + err(1, "malloc"); + + memset(data, 0xdb, data_len); + data[0] = 0x01; + data[data_len - 1] = 0xff; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "FAIL: BIO_new() returned NULL\n"); + goto failure; + } + if ((ret = BIO_write(bio, data, data_len)) != (int)data_len) { + fprintf(stderr, "FAIL: BIO_write() = %d, want %zu\n", ret, + data_len); + goto failure; + } + if ((rodata_len = BIO_get_mem_data(bio, &rodata)) != (long)data_len) { + fprintf(stderr, "FAIL: BIO_get_mem_data() = %ld, want %zu\n", + rodata_len, data_len); + goto failure; + } + if (rodata[0] != 0x01) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", rodata[0], 0x01); + goto failure; + } + if (rodata[rodata_len - 1] != 0xff) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", + rodata[rodata_len - 1], 0xff); + goto failure; + } + + if (!BIO_get_mem_ptr(bio, &pbuf)) { + fprintf(stderr, "FAIL: BIO_get_mem_ptr() failed\n"); + goto failure; + } + if (pbuf->length != data_len) { + fprintf(stderr, "FAIL: Got buffer with length %zu, want %zu\n", + pbuf->length, data_len); + goto failure; + } + if (memcmp(pbuf->data, data, data_len) != 0) { + fprintf(stderr, "FAIL: Got buffer with differing data\n"); + goto failure; + } + pbuf = NULL; + + if ((buf = BUF_MEM_new()) == NULL) { + fprintf(stderr, "FAIL: BUF_MEM_new() returned NULL\n"); + goto failure; + } + if (!BIO_set_mem_buf(bio, buf, BIO_NOCLOSE)) { + fprintf(stderr, "FAIL: BUF_set_mem_buf() failed\n"); + goto failure; + } + if ((ret = BIO_puts(bio, "Hello\n")) != 6) { + fprintf(stderr, "FAIL: BUF_puts() = %d, want %d\n", ret, 6); + goto failure; + } + if ((ret = BIO_puts(bio, "World\n")) != 6) { + fprintf(stderr, "FAIL: BUF_puts() = %d, want %d\n", ret, 6); + goto failure; + } + if (buf->length != 12) { + fprintf(stderr, "FAIL: buffer has length %zu, want %d\n", + buf->length, 12); + goto failure; + } + buf->length = 11; + if ((ret = BIO_gets(bio, data, data_len)) != 6) { + fprintf(stderr, "FAIL: BUF_gets() = %d, want %d\n", ret, 6); + goto failure; + } + if (strcmp(data, "Hello\n") != 0) { + fprintf(stderr, "FAIL: BUF_gets() returned '%s', want '%s'\n", + data, "Hello\\n"); + goto failure; + } + if ((ret = BIO_gets(bio, data, data_len)) != 5) { + fprintf(stderr, "FAIL: BUF_gets() = %d, want %d\n", ret, 5); + goto failure; + } + if (strcmp(data, "World") != 0) { + fprintf(stderr, "FAIL: BUF_gets() returned '%s', want '%s'\n", + data, "World"); + goto failure; + } + + if (!BIO_eof(bio)) { + fprintf(stderr, "FAIL: BIO is not EOF\n"); + goto failure; + } + if ((ret = BIO_read(bio, data, data_len)) != -1) { + fprintf(stderr, "FAIL: BIO_read() = %d, want -1\n", ret); + goto failure; + } + if (!BIO_set_mem_eof_return(bio, -2)) { + fprintf(stderr, "FAIL: BIO_set_mem_eof_return() failed\n"); + goto failure; + } + if ((ret = BIO_read(bio, data, data_len)) != -2) { + fprintf(stderr, "FAIL: BIO_read() = %d, want -2\n", ret); + goto failure; + } + + failed = 0; + + failure: + free(data); + BUF_MEM_free(buf); + BIO_free(bio); + + return failed; +} + +static int +bio_mem_small_io_test(void) +{ + uint8_t buf[2]; + int i, j, ret; + BIO *bio; + int failed = 1; + + memset(buf, 0xdb, sizeof(buf)); + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "FAIL: BIO_new() returned NULL\n"); + goto failure; + } + + for (i = 0; i < 100; i++) { + if (!BIO_reset(bio)) { + fprintf(stderr, "FAIL: BIO_reset() failed\n"); + goto failure; + } + for (j = 0; j < 25000; j++) { + ret = BIO_write(bio, buf, sizeof(buf)); + if (ret != sizeof(buf)) { + fprintf(stderr, "FAIL: BIO_write() = %d, " + "want %zu\n", ret, sizeof(buf)); + goto failure; + } + } + for (j = 0; j < 25000; j++) { + ret = BIO_read(bio, buf, sizeof(buf)); + if (ret != sizeof(buf)) { + fprintf(stderr, "FAIL: BIO_read() = %d, " + "want %zu\n", ret, sizeof(buf)); + goto failure; + } + ret = BIO_write(bio, buf, sizeof(buf)); + if (ret != sizeof(buf)) { + fprintf(stderr, "FAIL: BIO_write() = %d, " + "want %zu\n", ret, sizeof(buf)); + goto failure; + } + } + for (j = 0; j < 25000; j++) { + ret = BIO_read(bio, buf, sizeof(buf)); + if (ret != sizeof(buf)) { + fprintf(stderr, "FAIL: BIO_read() = %d, " + "want %zu\n", ret, sizeof(buf)); + goto failure; + } + } + if (!BIO_eof(bio)) { + fprintf(stderr, "FAIL: BIO not EOF\n"); + goto failure; + } + } + + if (buf[0] != 0xdb || buf[1] != 0xdb) { + fprintf(stderr, "FAIL: buf = {0x%x, 0x%x}, want {0xdb, 0xdb}\n", + buf[0], buf[1]); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + + return failed; +} + +static int +bio_mem_readonly_test(void) +{ + uint8_t *data = NULL; + size_t data_len; + uint8_t buf[2048]; + BIO *bio = NULL; + int ret; + int failed = 1; + + data_len = 4096; + if ((data = malloc(data_len)) == NULL) + err(1, "malloc"); + + memset(data, 0xdb, data_len); + data[0] = 0x01; + data[data_len - 1] = 0xff; + + if ((bio = BIO_new_mem_buf(data, data_len)) == NULL) { + fprintf(stderr, "FAIL: BIO_new_mem_buf failed\n"); + goto failure; + } + if ((ret = BIO_read(bio, buf, 1)) != 1) { + fprintf(stderr, "FAIL: BIO_read() = %d, want %zu\n", ret, + sizeof(buf)); + goto failure; + } + if (buf[0] != 0x01) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", buf[0], 0x01); + goto failure; + } + if ((ret = BIO_read(bio, buf, sizeof(buf))) != sizeof(buf)) { + fprintf(stderr, "FAIL: BIO_read() = %d, want %zu\n", ret, + sizeof(buf)); + goto failure; + } + if (buf[0] != 0xdb) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", buf[0], 0xdb); + goto failure; + } + if ((ret = BIO_write(bio, buf, 1)) != -1) { + fprintf(stderr, "FAIL: BIO_write() = %d, want -1\n", ret); + goto failure; + } + if (BIO_eof(bio)) { + fprintf(stderr, "FAIL: BIO is EOF\n"); + goto failure; + } + if (BIO_ctrl_pending(bio) != 2047) { + fprintf(stderr, "FAIL: BIO_ctrl_pending() = %zu, want 2047\n", + BIO_ctrl_pending(bio)); + goto failure; + } + if ((ret = BIO_read(bio, buf, sizeof(buf))) != 2047) { + fprintf(stderr, "FAIL: BIO_read() = %d, want 2047\n", ret); + goto failure; + } + if (buf[2045] != 0xdb) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", buf[2045], 0xdb); + goto failure; + } + if (buf[2046] != 0xff) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", buf[2046], 0xff); + goto failure; + } + if (!BIO_eof(bio)) { + fprintf(stderr, "FAIL: BIO is not EOF\n"); + goto failure; + } + if (BIO_ctrl_pending(bio) != 0) { + fprintf(stderr, "FAIL: BIO_ctrl_pending() = %zu, want 0\n", + BIO_ctrl_pending(bio)); + goto failure; + } + + if (!BIO_reset(bio)) { + fprintf(stderr, "FAIL: failed to reset bio\n"); + goto failure; + } + if (BIO_eof(bio)) { + fprintf(stderr, "FAIL: BIO is EOF\n"); + goto failure; + } + if (BIO_ctrl_pending(bio) != 4096) { + fprintf(stderr, "FAIL: BIO_ctrl_pending() = %zu, want 4096\n", + BIO_ctrl_pending(bio)); + goto failure; + } + if ((ret = BIO_read(bio, buf, 2)) != 2) { + fprintf(stderr, "FAIL: BIO_read() = %d, want 2\n", ret); + goto failure; + } + if (buf[0] != 0x01) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", buf[0], 0x01); + goto failure; + } + if (buf[1] != 0xdb) { + fprintf(stderr, "FAIL: got 0x%x, want 0x%x\n", buf[1], 0xdb); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + free(data); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= bio_mem_test(); + failed |= bio_mem_small_io_test(); + failed |= bio_mem_readonly_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_add_sub.c b/Libraries/libressl/tests/bn_add_sub.c new file mode 100644 index 000000000..2901dcbc8 --- /dev/null +++ b/Libraries/libressl/tests/bn_add_sub.c @@ -0,0 +1,249 @@ +/* $OpenBSD: bn_add_sub.c,v 1.3 2023/01/31 05:12:16 jsing Exp $ */ +/* + * Copyright (c) 2018 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Test basic functionality of BN_add(), BN_sub(), BN_uadd() and BN_usub() */ + +#include +#include + +#include +#include + +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) + +struct hexinput_st { + const char *a_hex; + const char *b_hex; + const char *e_hex; /* expected result */ + const char ret; /* check return value */ + int compare; /* use BN_cmp() to verify results */ +}; + +int bn_op_test(int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *), + struct hexinput_st[], unsigned int, const char *); +void print_failure_case(BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, int, + const char *); + +struct hexinput_st test_bn_add[] = { + { + "F", + "F", + "1E", + 1, + 1, + }, + { + "FFFFFFFFFFFFFFFFFFF", + "1", + "10000000000000000000", + 1, + 1, + }, + { + "7878787878787878", + "1010101010101010", + "8888888888888888", + 1, + 1, + }, + { + "FFFFFFFFFFFFFFFF0000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "1FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + 1, + 1, + }, + { + "F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0", + "10101010101010101010101010101010", + "101010101010101010101010101010100", + 1, + 1, + }, +}; + +struct hexinput_st test_bn_sub[] = { + { + "10", + "1", + "F", + 1, + 1, + }, + { + "10", + "1", + "E", + 1, + 0, + }, + { + "100000000001000000000", + "11100000001", + "FFFFFFFFFEFEFFFFFFFF", + 1, + 1, + }, + { + "-FFFFFFFFFFFFFFFFFFFF", + "1", + "-100000000000000000000", + 1, + 1, + }, +}; + +struct hexinput_st test_bn_usub[] = { + { + "10", + "1", + "F", + 1, + 1, + }, + { + "10", + "1", + "E", + 1, + 0, + }, + { + "100000000001000000000", + "11100000001", + "FFFFFFFFFEFEFFFFFFFF", + 1, + 1, + }, + { + "11100000001", + "100000000001000000000", + "0", + 0, + 0, + }, + { + "100000000000000000000", + "1", + "FFFFFFFFFFFFFFFFFFFF", + 1, + 1, + }, + { + "1", + "0", + "1", + 1, + 1, + }, + { + "1", + "2", + "FFFFFFFFFFFFFFFF", + 0, + 0, + }, + { + "0", + "1", + "0", + 0, + 0, + }, +}; + +void +print_failure_case(BIGNUM *a, BIGNUM *b, BIGNUM *e, BIGNUM *r, int i, + const char *testname) +{ + fprintf(stderr, "%s #%d failed:", testname, i); + fprintf(stderr, "\na = "); + BN_print_fp(stderr, a); + fprintf(stderr, "\nb = "); + BN_print_fp(stderr, b); + fprintf(stderr, "\nexpected: e = "); + BN_print_fp(stderr, e); + fprintf(stderr, "\nobtained: r = "); + BN_print_fp(stderr, r); + fprintf(stderr, "\n"); +} + +int +bn_op_test(int (*bn_op)(BIGNUM *, const BIGNUM *, const BIGNUM *), + struct hexinput_st tests[], unsigned int ntests, const char *testname) +{ + BIGNUM *a = NULL, *b = NULL, *e = NULL, *r = NULL; + unsigned int i; + int failed = 0; + + if (((a = BN_new()) == NULL) || + ((b = BN_new()) == NULL) || + ((e = BN_new()) == NULL) || + ((r = BN_new()) == NULL)) { + failed = 1; + ERR_print_errors_fp(stderr); + goto err; + } + + for (i = 0; i < ntests; i++) { + int print = 0; + + if (!BN_hex2bn(&a, tests[i].a_hex) || + !BN_hex2bn(&b, tests[i].b_hex) || + !BN_hex2bn(&e, tests[i].e_hex)) { + print = 1; + ERR_print_errors_fp(stderr); + } + + if (tests[i].ret != bn_op(r, a, b)) + print = 1; + if (tests[i].compare == 1 && BN_cmp(e, r) != 0) + print = 1; + if (print) { + failed = 1; + print_failure_case(a, b, e, r, i, testname); + } + } + + err: + BN_free(a); + BN_free(b); + BN_free(e); + BN_free(r); + return failed; +} + +int +main(int argc, char *argv[]) +{ + int failed = 0; + + if (bn_op_test(BN_add, test_bn_add, nitems(test_bn_add), + "BN_add with test_bn_add[]")) + failed = 1; + if (bn_op_test(BN_uadd, test_bn_add, nitems(test_bn_add), + "BN_uadd with test_bn_add[]")) + failed = 1; + if (bn_op_test(BN_sub, test_bn_sub, nitems(test_bn_sub), + "BN_sub with test_bn_sub[]")) + failed = 1; + if (bn_op_test(BN_usub, test_bn_usub, nitems(test_bn_usub), + "BN_usub with test_bn_usub[]")) + failed = 1; + + return failed; +} diff --git a/Libraries/libressl/tests/bn_cmp.c b/Libraries/libressl/tests/bn_cmp.c new file mode 100644 index 000000000..047fac3ba --- /dev/null +++ b/Libraries/libressl/tests/bn_cmp.c @@ -0,0 +1,360 @@ +/* $OpenBSD: bn_cmp.c,v 1.2 2023/06/21 07:16:08 jsing Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +struct bn_cmp_test { + const char *a; + const char *b; + int cmp; + int ucmp; +}; + +struct bn_cmp_test bn_cmp_tests[] = { + { + .a = "0", + .b = "0", + .cmp = 0, + .ucmp = 0, + }, + { + .a = "-1", + .b = "0", + .cmp = -1, + .ucmp = 1, + }, + { + .a = "1ffffffffffffffff", + .b = "1ffffffffffffffff", + .cmp = 0, + .ucmp = 0, + }, + { + .a = "1fffffffffffffffe", + .b = "1ffffffffffffffff", + .cmp = -1, + .ucmp = -1, + }, + { + .a = "1ffffffffffffffff", + .b = "1fffffffffffffffe", + .cmp = 1, + .ucmp = 1, + }, + { + .a = "0", + .b = "1ffffffffffffffff", + .cmp = -1, + .ucmp = -1, + }, + { + .a = "1ffffffffffffffff", + .b = "0", + .cmp = 1, + .ucmp = 1, + }, + { + .a = "-1ffffffffffffffff", + .b = "0", + .cmp = -1, + .ucmp = 1, + }, + { + .a = "1ffffffffffffffff", + .b = "00000000000000001ffffffffffffffff", + .cmp = 0, + .ucmp = 0, + }, + { + .a = "-1ffffffffffffffff", + .b = "-00000000000000001ffffffffffffffff", + .cmp = 0, + .ucmp = 0, + }, + { + .a = "1ffffffffffffffff", + .b = "-00000000000000001ffffffffffffffff", + .cmp = 1, + .ucmp = 0, + }, + { + .a = "-1ffffffffffffffff", + .b = "00000000000000001ffffffffffffffff", + .cmp = -1, + .ucmp = 0, + }, +}; + +#define N_BN_CMP_TESTS \ + (sizeof(bn_cmp_tests) / sizeof(*bn_cmp_tests)) + +static int +test_bn_cmp(void) +{ + struct bn_cmp_test *bct; + BIGNUM *a = NULL, *b = NULL; + size_t i; + int ret; + int failed = 1; + + if ((a = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + if ((b = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + + for (i = 0; i < N_BN_CMP_TESTS; i++) { + bct = &bn_cmp_tests[i]; + + if (!BN_hex2bn(&a, bct->a)) { + fprintf(stderr, "FAIL: failed to set a from hex\n"); + goto failure; + } + if (!BN_hex2bn(&b, bct->b)) { + fprintf(stderr, "FAIL: failed to set b from hex\n"); + goto failure; + } + + if ((ret = BN_cmp(a, b)) != bct->cmp) { + fprintf(stderr, "FAIL: BN_cmp(%s, %s) = %d, want %d\n", + bct->a, bct->b, ret, bct->cmp); + goto failure; + } + if ((ret = BN_ucmp(a, b)) != bct->ucmp) { + fprintf(stderr, "FAIL: BN_ucmp(%s, %s) = %d, want %d\n", + bct->a, bct->b, ret, bct->ucmp); + goto failure; + } + } + + failed = 0; + + failure: + BN_free(a); + BN_free(b); + + return failed; +} + +static int +test_bn_cmp_null(void) +{ + BIGNUM *a = NULL; + int ret; + int failed = 1; + + if ((a = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + + /* + * Comparison to NULL. + */ + if ((ret = BN_cmp(NULL, NULL)) != 0) { + fprintf(stderr, "FAIL: BN_cmp(NULL, NULL) == %d, want 0\n", ret); + goto failure; + } + + if ((ret = BN_cmp(a, NULL)) != -1) { + fprintf(stderr, "FAIL: BN_cmp(0, NULL) == %d, want -1\n", ret); + goto failure; + } + if ((ret = BN_cmp(NULL, a)) != 1) { + fprintf(stderr, "FAIL: BN_cmp(NULL, 0) == %d, want 1\n", ret); + goto failure; + } + + if (!BN_set_word(a, 1)) { + fprintf(stderr, "FAIL: failed to set BN to 1\n"); + goto failure; + } + if ((ret = BN_cmp(a, NULL)) != -1) { + fprintf(stderr, "FAIL: BN_cmp(1, NULL) == %d, want -1\n", ret); + goto failure; + } + if ((ret = BN_cmp(NULL, a)) != 1) { + fprintf(stderr, "FAIL: BN_cmp(NULL, 1) == %d, want 1\n", ret); + goto failure; + } + + BN_set_negative(a, 1); + if ((ret = BN_cmp(a, NULL)) != -1) { + fprintf(stderr, "FAIL: BN_cmp(-1, NULL) == %d, want -1\n", ret); + goto failure; + } + if ((ret = BN_cmp(NULL, a)) != 1) { + fprintf(stderr, "FAIL: BN_cmp(NULL, -1) == %d, want 1\n", ret); + goto failure; + } + + failed = 0; + + failure: + BN_free(a); + + return failed; +} + +struct bn_cmp_word_test { + int a; + int b; + int cmp; + int ucmp; +}; + +struct bn_cmp_word_test bn_cmp_word_tests[] = { + { + .a = -1, + .b = -1, + .cmp = 0, + .ucmp = 0, + }, + { + .a = 0, + .b = 0, + .cmp = 0, + .ucmp = 0, + }, + { + .a = 1, + .b = 1, + .cmp = 0, + .ucmp = 0, + }, + { + .a = 0, + .b = 1, + .cmp = -1, + .ucmp = -1, + }, + { + .a = 1, + .b = 0, + .cmp = 1, + .ucmp = 1, + }, + { + .a = -1, + .b = 0, + .cmp = -1, + .ucmp = 1, + }, + { + .a = 0, + .b = -1, + .cmp = 1, + .ucmp = -1, + }, + { + .a = -1, + .b = 1, + .cmp = -1, + .ucmp = 0, + }, + { + .a = 1, + .b = -1, + .cmp = 1, + .ucmp = 0, + }, +}; + +#define N_BN_CMP_WORD_TESTS \ + (sizeof(bn_cmp_word_tests) / sizeof(*bn_cmp_word_tests)) + +static int +test_bn_cmp_word(void) +{ + struct bn_cmp_word_test *bcwt; + BIGNUM *a = NULL, *b = NULL; + BN_ULONG v; + size_t i; + int ret; + int failed = 1; + + if ((a = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + if ((b = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + + for (i = 0; i < N_BN_CMP_WORD_TESTS; i++) { + bcwt = &bn_cmp_word_tests[i]; + + if (bcwt->a >= 0) { + v = bcwt->a; + } else { + v = 0 - bcwt->a; + } + if (!BN_set_word(a, v)) { + fprintf(stderr, "FAIL: failed to set a\n"); + goto failure; + } + BN_set_negative(a, (bcwt->a < 0)); + + if (bcwt->b >= 0) { + v = bcwt->b; + } else { + v = 0 - bcwt->b; + } + if (!BN_set_word(b, v)) { + fprintf(stderr, "FAIL: failed to set b\n"); + goto failure; + } + BN_set_negative(b, (bcwt->b < 0)); + + if ((ret = BN_cmp(a, b)) != bcwt->cmp) { + fprintf(stderr, "FAIL: BN_cmp(%d, %d) = %d, want %d\n", + bcwt->a, bcwt->b, ret, bcwt->cmp); + goto failure; + } + if ((ret = BN_ucmp(a, b)) != bcwt->ucmp) { + fprintf(stderr, "FAIL: BN_ucmp(%d, %d) = %d, want %d\n", + bcwt->a, bcwt->b, ret, bcwt->ucmp); + goto failure; + } + } + + failed = 0; + + failure: + BN_free(a); + BN_free(b); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_bn_cmp(); + failed |= test_bn_cmp_null(); + failed |= test_bn_cmp_word(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_convert.c b/Libraries/libressl/tests/bn_convert.c new file mode 100644 index 000000000..69f7da43b --- /dev/null +++ b/Libraries/libressl/tests/bn_convert.c @@ -0,0 +1,628 @@ +/* $OpenBSD: bn_convert.c,v 1.3 2023/06/23 10:50:47 tb Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +/* + * Additional test coverage is needed for: + * + * - BN_bn2binpad() + * - BN_bn2lebinpad() + * - BN_lebin2bn() + * - BN_bn2mpi()/BN_mpi2bn() + * - BN_print()/BN_print_fp() + * + * - Invalid inputs to {asc,dec,hex,mpi}2bn + * - Zero padded inputs + */ + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +check_bin_output(size_t test_no, const char *label, const uint8_t *bin, + size_t bin_len, const BIGNUM *bn) +{ + uint8_t *out = NULL; + int out_len; + int ret; + int failed = 1; + + out_len = BN_num_bytes(bn); + if (out_len != (int)bin_len) { + fprintf(stderr, "FAIL: Test %zu %s - BN_num_bytes() = %d, " + "want %zu\n", test_no, label, out_len, bin_len); + goto failure; + } + if ((out = malloc(out_len)) == NULL) + err(1, "malloc"); + if ((ret = BN_bn2bin(bn, out)) != out_len) { + fprintf(stderr, "FAIL: Test %zu %s - BN_bn2bin() returned %d, " + "want %d\n", test_no, label, ret, out_len); + goto failure; + } + if (memcmp(out, bin, bin_len) != 0) { + fprintf(stderr, "FAIL: Test %zu %s - output from " + "BN_bn2bin() differs\n", test_no, label); + fprintf(stderr, "Got:\n"); + hexdump(out, out_len); + fprintf(stderr, "Want:\n"); + hexdump(bin, bin_len); + goto failure; + } + + failed = 0; + + failure: + free(out); + + return failed; +} + +struct bn_asc2bn_test { + const char *in; + const uint8_t bin[64]; + size_t bin_len; + int neg; + int want_error; +}; + +static const struct bn_asc2bn_test bn_asc2bn_tests[] = { + { + .in = "", + .want_error = 1, + }, + { + .in = "-", + .want_error = 1, + }, + { + .in = "0", + .bin = { 0x00, }, + .bin_len = 0, + .neg = 0, + }, + { + .in = "0x0", + .bin = { 0x00, }, + .bin_len = 0, + .neg = 0, + }, + { + .in = "-0", + .bin = { 0x00, }, + .bin_len = 0, + .neg = 0, + }, + { + .in = "-0x0", + .bin = { 0x00, }, + .bin_len = 0, + .neg = 0, + }, + { + .in = "123456789", + .bin = { 0x07, 0x5b, 0xcd, 0x15, }, + .bin_len = 4, + .neg = 0, + }, + { + .in = "0123456789", + .bin = { 0x07, 0x5b, 0xcd, 0x15, }, + .bin_len = 4, + .neg = 0, + }, + { + .in = "-123456789", + .bin = { 0x07, 0x5b, 0xcd, 0x15, }, + .bin_len = 4, + .neg = 1, + }, + { + .in = "0X123456789", + .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, }, + .bin_len = 5, + .neg = 0, + }, + { + .in = "0x123456789", + .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, }, + .bin_len = 5, + .neg = 0, + }, + { + .in = "-0x123456789", + .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, }, + .bin_len = 5, + .neg = 1, + }, + { + .in = "abcdef123456789", + .want_error = 1, + }, + { + .in = "0x000123456789abCdEf", + .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .bin_len = 8, + .neg = 0, + }, +}; + +#define N_BN_ASC2BN_TESTS \ + (sizeof(bn_asc2bn_tests) / sizeof(*bn_asc2bn_tests)) + +static int +test_bn_asc2bn(void) +{ + const struct bn_asc2bn_test *bat; + BIGNUM *bn = NULL; + size_t i; + int failed = 1; + + for (i = 0; i < N_BN_ASC2BN_TESTS; i++) { + bat = &bn_asc2bn_tests[i]; + + BN_free(bn); + bn = NULL; + + if (!BN_asc2bn(&bn, bat->in)) { + if (bat->want_error) + continue; + fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() failed\n", i); + goto failure; + } + if (bat->want_error) { + fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() succeeded " + "when it should have failed\n", i); + goto failure; + } + + if (check_bin_output(i, "BN_asc2bn()", bat->bin, bat->bin_len, + bn) != 0) + goto failure; + + if (BN_is_negative(bn) != bat->neg) { + fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() resulted " + "in negative %d, want %d", i, BN_is_negative(bn), + bat->neg); + goto failure; + } + } + + /* + * While it makes little sense to call BN_asc2bn() with a NULL bn, + * check for consistent behavior. + */ + if (!BN_asc2bn(NULL, "1") || !BN_asc2bn(NULL, "-1") || + !BN_asc2bn(NULL, "0x1") || !BN_asc2bn(NULL, "-0x1")) { + fprintf(stderr, "FAIL: BN_asc2bn() with NULL BIGNUM failed\n"); + goto failure; + } + + failed = 0; + + failure: + BN_free(bn); + + return failed; +} + +struct bn_convert_test { + const uint8_t bin[64]; + size_t bin_len; + int neg; + const char *dec; + const char *hex; +}; + +static const struct bn_convert_test bn_convert_tests[] = { + { + .bin = { 0x0, }, + .bin_len = 0, + .neg = 0, + .dec = "0", + .hex = "0", + }, + { + .bin = { 0x1, }, + .bin_len = 1, + .neg = 0, + .dec = "1", + .hex = "01", + }, + { + .bin = { 0x7f, 0xff, 0xff, }, + .bin_len = 3, + .neg = 0, + .dec = "8388607", + .hex = "7FFFFF", + }, + { + .bin = { 0x7f, 0xff, 0xff, }, + .bin_len = 3, + .neg = 1, + .dec = "-8388607", + .hex = "-7FFFFF", + }, + { + .bin = { 0xff, 0xff, 0xff, 0xff, }, + .bin_len = 4, + .neg = 0, + .dec = "4294967295", + .hex = "FFFFFFFF", + }, + { + .bin = { 0xff, 0xff, 0xff, 0xff, }, + .bin_len = 4, + .neg = 1, + .dec = "-4294967295", + .hex = "-FFFFFFFF", + }, + { + .bin = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, }, + .bin_len = 8, + .neg = 0, + .dec = "18446744069414584320", + .hex = "FFFFFFFF00000000", + }, + { + .bin = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, }, + .bin_len = 8, + .neg = 1, + .dec = "-18446744069414584320", + .hex = "-FFFFFFFF00000000", + }, + { + .bin = { 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, }, + .bin_len = 8, + .neg = 0, + .dec = "9223794255762391041", + .hex = "8001800180018001", + }, + { + .bin = { 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, }, + .bin_len = 8, + .neg = 1, + .dec = "-9223794255762391041", + .hex = "-8001800180018001", + }, + { + .bin = { 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, }, + .bin_len = 9, + .neg = 0, + .dec = "27670538329471942657", + .hex = "018001800180018001", + }, + { + .bin = { 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, }, + .bin_len = 9, + .neg = 1, + .dec = "-27670538329471942657", + .hex = "-018001800180018001", + }, + { + .bin = { + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + }, + .bin_len = 32, + .neg = 0, + .dec = "57895161181645529494837117048595051142566530671229791132691030063130991362047", + .hex = "7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF", + }, + { + .bin = { + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, + }, + .bin_len = 32, + .neg = 1, + .dec = "-57895161181645529494837117048595051142566530671229791132691030063130991362047", + .hex = "-7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF", + }, +}; + +#define N_BN_CONVERT_TESTS \ + (sizeof(bn_convert_tests) / sizeof(*bn_convert_tests)) + +static int +test_bn_convert(void) +{ + const struct bn_convert_test *bct; + char *out_str = NULL; + BIGNUM *bn = NULL; + size_t i; + int failed = 1; + + for (i = 0; i < N_BN_CONVERT_TESTS; i++) { + bct = &bn_convert_tests[i]; + + BN_free(bn); + if ((bn = BN_bin2bn(bct->bin, bct->bin_len, NULL)) == NULL) { + fprintf(stderr, "FAIL: BN_bin2bn() failed\n"); + goto failure; + } + BN_set_negative(bn, bct->neg); + + if (check_bin_output(i, "BN_bin2bn()", bct->bin, bct->bin_len, + bn) != 0) + goto failure; + + free(out_str); + if ((out_str = BN_bn2dec(bn)) == NULL) { + fprintf(stderr, "FAIL: BN_bn2dec() failed\n"); + goto failure; + } + if (strcmp(out_str, bct->dec) != 0) { + fprintf(stderr, "FAIL: Test %zu - BN_bn2dec() returned " + "'%s', want '%s'", i, out_str, bct->dec); + goto failure; + } + + free(out_str); + if ((out_str = BN_bn2hex(bn)) == NULL) { + fprintf(stderr, "FAIL: BN_bn2hex() failed\n"); + goto failure; + } + if (strcmp(out_str, bct->hex) != 0) { + fprintf(stderr, "FAIL: Test %zu - BN_bn2hex() returned " + "'%s', want '%s'", i, out_str, bct->hex); + goto failure; + } + + if (BN_dec2bn(&bn, bct->dec) != (int)strlen(bct->dec)) { + fprintf(stderr, "FAIL: BN_dec2bn() failed\n"); + goto failure; + } + if (BN_is_negative(bn) != bct->neg) { + fprintf(stderr, "FAIL: Test %zu - BN_dec2bn() resulted " + "in negative %d, want %d", i, BN_is_negative(bn), + bct->neg); + goto failure; + } + + if (check_bin_output(i, "BN_dec2bn()", bct->bin, bct->bin_len, + bn) != 0) + goto failure; + + if (BN_hex2bn(&bn, bct->hex) != (int)strlen(bct->hex)) { + fprintf(stderr, "FAIL: BN_hex2bn() failed\n"); + goto failure; + } + if (BN_is_negative(bn) != bct->neg) { + fprintf(stderr, "FAIL: Test %zu - BN_hex2bn() resulted " + "in negative %d, want %d", i, BN_is_negative(bn), + bct->neg); + goto failure; + } + + if (check_bin_output(i, "BN_hex2bn()", bct->bin, bct->bin_len, + bn) != 0) + goto failure; + } + + failed = 0; + + failure: + free(out_str); + BN_free(bn); + + return failed; +} + +static int +test_bn_dec2bn(void) +{ + BIGNUM *bn = NULL; + BN_ULONG w; + int ret; + int failed = 1; + + /* An empty string fails to parse, as does NULL. */ + if (BN_dec2bn(&bn, "") != 0) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"\") succeeded\n"); + goto failure; + } + if (bn != NULL) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"\") succeeded\n"); + goto failure; + } + if (BN_dec2bn(&bn, NULL) != 0) { + fprintf(stderr, "FAIL: BN_dec2bn(_, NULL) succeeded\n"); + goto failure; + } + if (bn != NULL) { + fprintf(stderr, "FAIL: BN_dec2bn(_, NULL) succeeded\n"); + goto failure; + } + + /* A minus sign parses as 0. */ + if (BN_dec2bn(&bn, "-") != 1) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") failed\n"); + goto failure; + } + if (bn == NULL) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") failed\n"); + goto failure; + } + if (!BN_is_zero(bn)) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") is non-zero\n"); + goto failure; + } + if (BN_is_negative(bn)) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") resulted in " + "negative zero\n"); + goto failure; + } + + /* Ensure that -0 results in 0. */ + if (BN_dec2bn(&bn, "-0") != 2) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") failed\n"); + goto failure; + } + if (!BN_is_zero(bn)) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") is non-zero\n"); + goto failure; + } + if (BN_is_negative(bn)) { + fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") resulted in " + "negative zero\n"); + goto failure; + } + + /* BN_dec2bn() is the new atoi()... */ + if ((ret = BN_dec2bn(&bn, "0123456789abcdef")) != 10) { + fprintf(stderr, "FAIL: BN_dec2bn() returned %d, want 10\n", ret); + goto failure; + } + if ((w = BN_get_word(bn)) != 0x75bcd15) { + fprintf(stderr, "FAIL: BN_dec2bn() resulted in %llx, want %llx\n", + (unsigned long long)w, 0x75bcd15ULL); + goto failure; + } + + /* And we can call BN_dec2bn() without actually converting to a BIGNUM. */ + if ((ret = BN_dec2bn(NULL, "0123456789abcdef")) != 10) { + fprintf(stderr, "FAIL: BN_dec2bn() returned %d, want 10\n", ret); + goto failure; + } + + failed = 0; + + failure: + BN_free(bn); + + return failed; +} + +static int +test_bn_hex2bn(void) +{ + BIGNUM *bn = NULL; + BN_ULONG w; + int ret; + int failed = 1; + + /* An empty string fails to parse, as does NULL. */ + if (BN_hex2bn(&bn, "") != 0) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"\") succeeded\n"); + goto failure; + } + if (bn != NULL) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"\") succeeded\n"); + goto failure; + } + if (BN_hex2bn(&bn, NULL) != 0) { + fprintf(stderr, "FAIL: BN_hex2bn(_, NULL) succeeded\n"); + goto failure; + } + if (bn != NULL) { + fprintf(stderr, "FAIL: BN_hex2bn(_, NULL) succeeded\n"); + goto failure; + } + + /* A minus sign parses as 0. */ + if (BN_hex2bn(&bn, "-") != 1) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") failed\n"); + goto failure; + } + if (bn == NULL) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") failed\n"); + goto failure; + } + if (!BN_is_zero(bn)) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") returned non-zero\n"); + goto failure; + } + if (BN_is_negative(bn)) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") returned negative zero\n"); + goto failure; + } + + /* Ensure that -0 results in 0. */ + if (BN_hex2bn(&bn, "-0") != 2) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") failed\n"); + goto failure; + } + if (!BN_is_zero(bn)) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") is non-zero\n"); + goto failure; + } + if (BN_is_negative(bn)) { + fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") resulted in " + "negative zero\n"); + goto failure; + } + + /* BN_hex2bn() is the new atoi()... */ + if ((ret = BN_hex2bn(&bn, "9abcdefz")) != 7) { + fprintf(stderr, "FAIL: BN_hex2bn() returned %d, want 7\n", ret); + goto failure; + } + if ((w = BN_get_word(bn)) != 0x9abcdef) { + fprintf(stderr, "FAIL: BN_hex2bn() resulted in %llx, want %llx\n", + (unsigned long long)w, 0x9abcdefULL); + goto failure; + } + + /* A 0x prefix fails to parse without BN_asc2bn() (instead we get 0!). */ + if (BN_hex2bn(&bn, "0x1") != 1) { + fprintf(stderr, "FAIL: BN_hex2bn() parsed a 0x prefix\n"); + goto failure; + } + + /* And we can call BN_hex2bn() without actually converting to a BIGNUM. */ + if ((ret = BN_hex2bn(NULL, "9abcdefz")) != 7) { + fprintf(stderr, "FAIL: BN_hex2bn() returned %d, want 7\n", ret); + goto failure; + } + + failed = 0; + + failure: + BN_free(bn); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_bn_asc2bn(); + failed |= test_bn_convert(); + failed |= test_bn_dec2bn(); + failed |= test_bn_hex2bn(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_gcd.c b/Libraries/libressl/tests/bn_gcd.c new file mode 100644 index 000000000..b247b9b2a --- /dev/null +++ b/Libraries/libressl/tests/bn_gcd.c @@ -0,0 +1,3670 @@ +/* $OpenBSD: bn_gcd.c,v 1.3 2023/04/07 17:09:54 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_gcd_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +static const struct gcd_test_fn { + const char *name; + int (*fn)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + int fails_on_zero; +} gcd_fn[] = { + { + .name = "BN_gcd", + .fn = BN_gcd, + }, + { + .name = "BN_gcd_ct", + .fn = BN_gcd_ct, + .fails_on_zero = 1, + }, +}; + +#define N_GCD_FN (sizeof(gcd_fn) / sizeof(gcd_fn[0])) + +static const struct gcd_test { + const char *a; + const char *b; + const char *r; +} bn_gcd_tests[] = { + { + .a = "0", + .b = "0", + .r = "0", + }, + { + .a = "1", + .b = "1", + .r = "1", + }, + { + .a = "1", + .b = "0", + .r = "1", + }, + { + .a = "0", + .b = "1", + .r = "1", + }, + { + .a = "57", + .b = "0", + .r = "57", + }, + { + .a = "0", + .b = "57", + .r = "57", + }, + + /* + * The following test cases were randomly generated. + */ + + { + .a = "255", + .b = "278d3", + .r = "3", + }, + { + .a = "6a54d", + .b = "619", + .r = "7", + }, + { + .a = "e9", + .b = "e695", + .r = "1", + }, + { + .a = "3f3a9", + .b = "41f", + .r = "5", + }, + { + .a = "643", + .b = "5bff1", + .r = "7", + }, + { + .a = "2bb", + .b = "29be3", + .r = "3", + }, + { + .a = "49e", + .b = "5770e", + .r = "6", + }, + { + .a = "f1d5", + .b = "fb", + .r = "1", + }, + { + .a = "250eb50", + .b = "206b0", + .r = "2b0", + }, + { + .a = "57ad2", + .b = "64927d6", + .r = "6a6", + }, + { + .a = "430bc", + .b = "48757a4", + .r = "564", + }, + { + .a = "7593a8c", + .b = "7161c", + .r = "7ec", + }, + { + .a = "5771161", + .b = "53d9b", + .r = "5e9", + }, + { + .a = "4132d82", + .b = "37b1e", + .r = "49e", + }, + { + .a = "72492b0", + .b = "65f90", + .r = "730", + }, + { + .a = "14bab", + .b = "163605b", + .r = "1af", + }, + { + .a = "602d952bd", + .b = "5a08833", + .r = "62ebb", + }, + { + .a = "698bf2b", + .b = "65849195f", + .r = "701db", + }, + { + .a = "37d4a5f", + .b = "402dcce6f", + .r = "488d3", + }, + { + .a = "614e922", + .b = "6644a8e72", + .r = "6cc7a", + }, + { + .a = "1eea0a75c", + .b = "1ea5c64", + .r = "21ac4", + }, + { + .a = "6136d54", + .b = "6acfd5d8c", + .r = "7e544", + }, + { + .a = "2bba7aaf2", + .b = "33894f6", + .r = "34902", + }, + { + .a = "467c1e94", + .b = "3c036c", + .r = "4d34", + }, + { + .a = "19c3fcfc5", + .b = "15f969b26a7", + .r = "1b9928b", + }, + { + .a = "145666d9a", + .b = "13bbb7f3bb6", + .r = "159a73a", + }, + { + .a = "1b0c38f9e", + .b = "18765759b3e", + .r = "1f0ce22", + }, + { + .a = "784064e87", + .b = "667b4b1bc85", + .r = "7fbc6f7", + }, + { + .a = "498054afdd3", + .b = "44d269073", + .r = "596efd7", + }, + { + .a = "198ba337af6", + .b = "1f5755eca", + .r = "214ab6a", + }, + { + .a = "5effbed2b", + .b = "6a7cdb539bd", + .r = "7b7352f", + }, + { + .a = "14388cf1265", + .b = "153338971", + .r = "174af49", + }, + { + .a = "2d4aff46122f30851a52b", + .b = "2edb8fdd14ab1b645", + .r = "332805d24fd69", + }, + { + .a = "43733ea897495e14339f9", + .b = "3e843370070058d8d", + .r = "49977f36263b5", + }, + { + .a = "58aafd7662b8de019", + .b = "5538bdda74849754e4949", + .r = "5daa7b4439b0f", + }, + { + .a = "474100872e962de8b0596", + .b = "45223dbbeaaba9e92", + .r = "580218df81b62", + }, + { + .a = "307c55bb52be32b4d", + .b = "2cc525ce8e2d2bc67aa6d", + .r = "30c17810923d9", + }, + { + .a = "4a2a6504adf43e733", + .b = "497c44b84fb6f8774f787", + .r = "5ea902856aae1", + }, + { + .a = "5b8e523f7c7b60972", + .b = "4aebe8c99000a8bd30652", + .r = "63b8fd8af9062", + }, + { + .a = "53a047f3c3f81986811d7", + .b = "53b004a9fa740fcbb", + .r = "64d12a952833b", + }, + { + .a = "6f177c61fa6afe2d209", + .b = "670a0a35553c35d52fb18f5", + .r = "74c624a8a32333b", + }, + { + .a = "5343fd2374414df3034", + .b = "507c3e327a45f92c78eeb84", + .r = "5974af2eca1fe94", + }, + { + .a = "4a07f6267329d80c7d4bdfa", + .b = "56a012dd8379b7a0e16", + .r = "59052131189608e", + }, + { + .a = "63bba164fd337e80d0c", + .b = "615a76fb66b1094efbcba2c", + .r = "735585f95d70274", + }, + { + .a = "2453ea8b7fca0284b883078", + .b = "234099d522bcad7e248", + .r = "2d69bd4f4b8d088", + }, + { + .a = "61b5dc7806b84d2b08c", + .b = "58b8dde9e5f8ecfde43cd74", + .r = "75ff164a01eaa7c", + }, + { + .a = "3816984948c1e79f882", + .b = "3b5b01106809f6bb2e2e016", + .r = "48170e737316bca", + }, + { + .a = "41b4deb320e45f566b", + .b = "4874dbcc44f53775a6a1d7", + .r = "4977a5459131df", + }, + { + .a = "364580a30652080c07c9dc48", + .b = "2e1c73c5131cbbf50628", + .r = "36825feeccb49b58", + }, + { + .a = "695d74ad760a5795570a3", + .b = "62bc190742c20aa29644c84eb", + .r = "6abcf0da95d5be6f7", + }, + { + .a = "74db3db1ab6c202baff804bcd", + .b = "6380a7b03658ba56b34a3", + .r = "756f230199f1529ab", + }, + { + .a = "4b26c75874a09700b9d512ed8", + .b = "4ca3361909906b0cf7618", + .r = "53055ca37fd154698", + }, + { + .a = "1f81faea97f44cd5c6adb457d", + .b = "22c452983db5a6ce9736f", + .r = "241a04dc3e4719c37", + }, + { + .a = "95e5584090df556539aa9fd9", + .b = "b02f19eec1f1f2d44c59", + .r = "c5c889564b7e8bab", + }, + { + .a = "4a908939e089498a7feab", + .b = "60045b573dccb74a9e2e379d5", + .r = "6116326ef394c59e7", + }, + { + .a = "39443c6a7d6bd95529a12", + .b = "409e977e693f5bd1b17b0433a", + .r = "49802f618e94d218a", + }, + { + .a = "3e6fc6cf9eaba3e94f24f03", + .b = "345aa9ded17c65a6c85dd7e6d61", + .r = "3ea3e52d4d5d024c389", + }, + { + .a = "64f62375ce39484ec7e85f4e3d", + .b = "69459ea484d6480a376e91", + .r = "748b7824736c5c39e5", + }, + { + .a = "4186cead307cad31530dd205a39", + .b = "4f5ee69f4afbb46507ccc8b", + .r = "533aef3d540410a6b2b", + }, + { + .a = "536b816e2daa705e44bae82", + .b = "4e8a14632ccec82f41941b1fd7e", + .r = "5bf87a677ef2ec1bd76", + }, + { + .a = "6518022e9b5920c69de925", + .b = "6d90bcb3174b93f44a2854f601", + .r = "7cc47ec91e90d61599", + }, + { + .a = "2f443ac559d746b4b8f87c802af", + .b = "2ef35b22f59380207cd3a09", + .r = "33f82dc6aa168711c2f", + }, + { + .a = "17418a08c177e039b1e5000", + .b = "183bf7b0342fe483457340ab000", + .r = "1da412c88f3a0c3f000", + }, + { + .a = "77685efaa0d4e6a25268eaa07", + .b = "65b89e487f7a272f6187b", + .r = "80861458bce7097f7", + }, + { + .a = "1488a0aab5415ee1ce826ecb38f7b33", + .b = "131c43cca73843a27b9feac46cd03d5de7a2f", + .r = "17b3a3001f3660377791cd8cf", + }, + { + .a = "5349d29af82e6b8fae6c25859fadec6207032", + .b = "64d277bfb253b9a22f3c0187445253a", + .r = "6573b739e39b0650a9c2c2f02", + }, + { + .a = "21df6046ab805b9f71a304d34236fe8", + .b = "1fe085864e8e75ea073efebfe6fbab133e4e8", + .r = "23e3d1525042d237154d245f8", + }, + { + .a = "56454c66089738f7074ce55236dce53b22a11", + .b = "5d5308342f5a0c2277762ba37273f07", + .r = "71fb0beacaae6adab73b8cfbb", + }, + { + .a = "25e20fcd81385c099f1db654feba9b1", + .b = "2134ea8527e2ad47f460d70b918ba69fd4c6b", + .r = "268d03475633df8adccd7eda9", + }, + { + .a = "6713eb612dab2940e2741150dfa203f632d5f", + .b = "611184b794056ec03b0aeb7c1646be9", + .r = "752472cea4fe17a0cc5881d23", + }, + { + .a = "39a3fe02e4f8cb7cfc972275862512c6e863c", + .b = "356731db8ae0f405b01423d24a00df4", + .r = "4230cc0ff4cb762463e8f45a4", + }, + { + .a = "48c66d2a5a9f354fbe6a24379b3c868", + .b = "3d52dfc550d9288335bc4ca727d0008e225d8", + .r = "4e38e92332937fe6d87b9e888", + }, + { + .a = "30de4f96ec186d1f64298c5ae4510f448", + .b = "30cbcdb08d24818e2845286f4b70760116f96e8", + .r = "32f5f8996bc47879755ea626348", + }, + { + .a = "4e3cbdc0d866680fd0cf79732b914033c", + .b = "4c0fc242dbe2f4ba5592ffc621eca68499e807c", + .r = "556fcff7e03458aba9b3229def4", + }, + { + .a = "4f902e3c221d879daae7536c66d0d1e0a", + .b = "4e2451f07d9559f3c36746cef62cb2ce95525de", + .r = "5be6e06842ff90445f2d002fdce", + }, + { + .a = "1ec50fe3ba8edcdd47cecf6b1e67d2263bee334", + .b = "20eb4fa3aabacd28aa5126fa29425be14", + .r = "244d6242059f13924023015b8bc", + }, + { + .a = "f85a29486c90172f2fcb0e8f2b9cc357235f8", + .b = "d988a3b4b5b168ed7ebe15381da5818", + .r = "fdfee673f1bde9585970c65b8", + }, + { + .a = "60ff4616bccb386ab1c8c4fd663afd554f8d8cc", + .b = "5e4e6ea5e8217e17f69c63ea07d8e93bc", + .r = "780275e6eaa0fe4bf87a78c9974", + }, + { + .a = "1ba4b71fa06394748ad36489d8a1232de12d6f0", + .b = "1da078788fa13e18814edbf15907ef930", + .r = "235f9d5de3c2a7b93122d930ad0", + }, + { + .a = "3b09f70af16cc8c40573bfffb63750b2c", + .b = "3d4c9928047325884f90888dee2d64f64dca29c", + .r = "3fc1e8665f4df4243c2062b6d0c", + }, + { + .a = "4d3079fb7639d1e7fdab98015c21c782c4c2b7878", + .b = "3dfed750b07e2be9e32d2627c31a0a1e3c8", + .r = "500cd222944614585265eb9f9e958", + }, + { + .a = "536e6614ee85be4cba997bceeacd5d87db", + .b = "48a13d2d2df5788977b9e8ecd434cba45fe3ee1b", + .r = "549a3e0100b99d244e7f85384439", + }, + { + .a = "1d83beadd7fe8d557ee9985f3d4c47b9144", + .b = "22be84a3090cce29b0b666a7cb049f9ba808cb494", + .r = "25d4b9fb71a6f79ff05eeabfbd454", + }, + { + .a = "5b5bc6dc131ab9f1f765c976c96852f5cb024d121", + .b = "4c8375dd9a13a1c7d31f2c3fc87dd070075", + .r = "5ec3c5e03869f4dd4372d274fb553", + }, + { + .a = "220220e66a4abb06681151d2a9cdf0d30a0", + .b = "26002cab182d2500064e1c19184707b9e8ba673e0", + .r = "2633ad7265ae0db8b891f4459eee0", + }, + { + .a = "1e2ff1ff6bd8bee4b18ff6fc09e2b4a82e6", + .b = "207e14815ccc0a2f5cf3903d7e2bf754356c65676", + .r = "239e193c1bc65766c6b580dcddcc2", + }, + { + .a = "26b7793830e334ac155cc8d480f2f3a6de4", + .b = "27a0ce62b6c85cd1566cdc532b5b1e322e52996cc", + .r = "297defac305c3a2f2154541ef1dc4", + }, + { + .a = "50fda952177aa819c4042847414f2d2d14e", + .b = "45255a9ae2fd394ed8b760ce3133fb71f94362a86", + .r = "56aae2037820936b47d6a9cf771fa", + }, + { + .a = "5acedf307d7016ffd7380015df422691ebbf7d97e91", + .b = "53c6266c3e6520cc40abc70370ad94e8a629d", + .r = "686ec3910fdac81085a738d1d4799d3", + }, + { + .a = "584f15ec6c7e7bfa4ba24e1780fde1511fe12", + .b = "575a78c8e8bb4f02e57efb0010d86b4a408f150fe7e", + .r = "6317a26e7ae3218b60d8ef6cfa64186", + }, + { + .a = "f617d44caf7dc67791e20feac2c1c27e655f", + .b = "11542c315141d0c46bae8863c1a945963b91b644603", + .r = "12f20af110dee02b9bbde9c9431ef47", + }, + { + .a = "54538d3df7d85581e923e44291cae3aa3a3fcd20cc5", + .b = "67eef9400e79570ce246df916892707014bbb", + .r = "6a00b7b006c767a710fdd8b7652cacd", + }, + { + .a = "1d567e0e5af1b4994bd82baf9c601d188107d", + .b = "1dae559a89e7e21212345a8148689c33da8d28f3fc9", + .r = "1f41fa99ba8e144971e741732e76cc1", + }, + { + .a = "2c3172df78361b326b2c1f83749d1b9e42672", + .b = "2ff4be223d91f31e03e07fee0c18e082f970191a41a", + .r = "3693dd9f37613c4a7de1d831f44dd26", + }, + { + .a = "32e11a127828647a88f8f7b6d48f475e8e71eda585b", + .b = "2ddf9f7e0f870347401ce5d93ff70a5a3a9cb", + .r = "3a4156da31ca81617974669400e3629", + }, + { + .a = "47f54df57b2d124be53c0c6603700e8f69829238b49", + .b = "489167e7ed18db6d541c8a94cf6a58f10836d", + .r = "5ca417bb8cb42fefd91fd832a89bdb7", + }, + { + .a = "8963a8cf862bfeda36412dea185c6984c3acf3b22204", + .b = "8035daf441d2a728b3dbded074c57e103e58ad65efaf5fe3" + "b23c", + .r = "a7cbf319f110484e28a631c8425609ed72ec", + }, + { + .a = "40f583721493abb5ead342942d9e142ce51f7251ecb6a333" + "c0888", + .b = "4cce4f3aff6019192f7e32c372c9e32385b2352d32518", + .r = "52d94814b2149c815d82619dc02750648e558", + }, + { + .a = "34a08b5c152b6bda536ab231199c5de7d8e96ad8814f3", + .b = "328d23516a0bacc130bcbb9b95965ffdd99827c49f306a6c" + "06983", + .r = "431ef899d79eb5aff9b6aa3759bca625f1317", + }, + { + .a = "4765f462b4167b25df009c3d0d710d707dc4e8a990e81", + .b = "5495c974f06f6f2cf98d285af77a76be3ef32eab77ca815b" + "a2031", + .r = "58ab78d483cc486014fb6ea972c22f7ab7b5d", + }, + { + .a = "44ad54c2afc1aeac7ec3511d847cbbee8902ec2ede784", + .b = "3cf4ddd41867fea4681efd043e079ba7788bcf66dd2694ba" + "dce1c", + .r = "495c740575ba1a56128a3a6721dc6b26fa664", + }, + { + .a = "1fa1582b89ffb94b0b97acdb1de271dbfdbc305af4513fdf" + "5b307", + .b = "27f5a44e5e13c9b5261f50a2f19f00e6a5023c0c755e5", + .r = "27f8d558c92c865c814efc3aa6a1f4d70bf73", + }, + { + .a = "591a92aedb904d763b651b2db15c965368d909b219ee607a" + "5c68c", + .b = "5b4be0a485cd99ee2d1126e62f657581da85e941e725c", + .r = "68117134ecfe0984ea313bfe818d2072186dc", + }, + { + .a = "23d0f4377e7c81b3531b876a2c277c5c60ec5db222e02", + .b = "28b7dd0cdd3dbf3d6f92099865fdda7b659264979e55a77a" + "7d9a2", + .r = "2e942c88caa87225c5a8498d87fa59dc870fa", + }, + { + .a = "44c61f3dbac478676dcbec9e9b85a1fce1822640a45c7830" + "7cca326", + .b = "4f6d3f6085a1937280761490ea12e7bfa776274e9b22dda", + .r = "58ca1394a549af73f5c95c86891f65fe0f02ce6", + }, + { + .a = "4db4b7f75bc45038ca28ac52e2f39fd546890e7b6566753f" + "65750f8", + .b = "5340542372ef34ac534d473cb2e0a5ffde3dae86c609c68", + .r = "65ac57454f6de8aa076e8754b9766f088c01598", + }, + { + .a = "5d975374b2babbc978bd336e1c3f219f1e288f2e1db9945", + .b = "4fc6275ab900f3b867af5ac9107a6605e4b7092613ae76ca" + "0caff79", + .r = "607a26e662f6a1c9bd222c7f34dab5814576bcf", + }, + { + .a = "7809cd380713c9d12f3f5700bbc69abc9a4508c400d3b6a", + .b = "7a6d99dcad253fafd6b85854588a608eb8983a6ef7f1f2cd" + "8f181a2", + .r = "7f5c9339cbbeffe9bae9e1fbcaac2b9ca73c89e", + }, + { + .a = "3d9e9943572b9a1f79ad2957b7c244a596d0ac6f1de51efc" + "9137e16", + .b = "426bbbff4bdbff38522f35096168f0edd6eb8827bdfcd92", + .r = "4aded736b377b0e75db171dbbfefdfae8d76c4a", + }, + { + .a = "37f44546e8b6837ded1179af6539491608d495d2b95d940", + .b = "39acb184673736b04fdc295ec18d4873c9e87be5291a7de0" + "66146c0", + .r = "48cd7455d2c1cfa8df085c3bbcda3db9aae91c0", + }, + { + .a = "44e3fb32ef2f76b49a2f237268b130a67a4d33fcf6b5526", + .b = "45346b4482d0967d50c829d9cd3c004ae308b257ba3e424f" + "281c142", + .r = "47ab194984b1e24a53f37d7458b0ab935bf72a6", + }, + { + .a = "583ccfde7a58547a5d4865a587f53d5bb14357ae1884ace", + .b = "672af3971a2220742816400394cf5e51d30c7e84f12c5f99" + "fc5ff6a", + .r = "73691aa5d3db4eaf50cb025db292dbf56c4655e", + }, + { + .a = "5313de0a5a6130944f256c41f1f0eb656fd0db717a910d71" + "667328c93", + .b = "523fa7f470e6662d511de7c89b98332246311c00411602c9" + "d", + .r = "63c5b2d400135796ba239bc1897c105a035cf4af1", + }, + { + .a = "6261142ad8b400e852a18dcc22ad59e799b49a441877590a" + "2b3a9c848", + .b = "540da3c401662ab7a46a45112216372f40b265bf5f29a41b" + "8", + .r = "6d6843c2bfad5aa2576615cae1dae5d89fa8dd748", + }, + { + .a = "608ca9bd26508d03ca0bd1b7298277f8f663f211a8d8f9ef" + "3", + .b = "66a32e807cd5ba8aaa27a26a6557b612410405c533e30db0" + "cd181388b", + .r = "7c082059c2fe5ec79de0cd0fdc6589bf628c34dbf", + }, + { + .a = "3c3f129b151cebc5ad541b2f055935f4b6b6d999916278d5" + "4f39de38e", + .b = "399a8dbd7959ceb3c21d040c70edc1b0b6a78979649cc87e" + "6", + .r = "3df890c79455b17a785efc18df7c4036b8d2036ce", + }, + { + .a = "a4c9bbe3961f010618e049eee287111d6ac85ed9eec95d91", + .b = "9b400dddd76cd1e856dc42e0250fa7abd9e1ca6d40406de9" + "ef6a4fdb", + .r = "ba72df9f2f039bf06d4db604f939971305056d95", + }, + { + .a = "4c877496518b9c0d55af99d7d06a06257c5a28e10f113b39" + "6bc15c3e4", + .b = "3e6fe477af388c8ac70124319f42bd92ce5544bca3ae90b2" + "c", + .r = "4edc3785759dca43fffb4143a7da85079d538bf5c", + }, + { + .a = "1a9606caa24d27f4e8886379ace27a42809d16e826628e5b" + "50b5e3672", + .b = "186dfdc633d6b265fa84e201e361465007ddc0b5ce2cdf6d" + "a", + .r = "1b58867321f49d16b1354c1788a813cc155f90c1e", + }, + { + .a = "3280c3a090a37682a1f0726730833cc826c31dc489026926" + "5", + .b = "35ae94985e20a405161cdc4901436dd36397c38fdd4a7e33" + "bae99cdef", + .r = "4192391ee1a855ec8961147e8939fe45cac80d73b", + }, + { + .a = "55cd7d3fcb430b18fafd57849074593658619b78c342a80f" + "35f", + .b = "6c002b00fbc036c3fc8e61ed14bf9dc00557be4fcd953c30" + "6220f314535", + .r = "6d6cdb2824bf090412b402523161702b44aca463751", + }, + { + .a = "5b7c45727d9663df29ccd97638ea1e5365e69737e1d2999c" + "ffe0a67e34a", + .b = "5b77539fe191d0829ebd7db19748881f4ed579662f8b3788" + "02a", + .r = "6c1d167c73f79f0a90667983c795100c81a582d7aba", + }, + { + .a = "6147dc08368c5a0de97a1935be04149805f74804c0717685" + "335", + .b = "7536275bc0c3267b7fdc41743e6419955861fc5fa9bfd466" + "0634a4fbf57", + .r = "7737a65bb5496810a9f619da5a791c8393baf33c5db", + }, + { + .a = "27828740d648ee93a505acedb32f024ac4480381a4f5b908" + "14ed67a54fe", + .b = "24e2003c3aa30c231bea1c97822dd073c29c4c530aeb2d5e" + "c66", + .r = "2a4fd1d87bc6758693cb48907b0daaab4ae3730ef9a", + }, + { + .a = "3238e873f75c5e83aab4011008be5feca52b86af433a6e72" + "68d", + .b = "2c155346f370ea6bedf6914edfd6f661c6e715fda6407b56" + "7548e0e4cb7", + .r = "3657adc3dc062f48f73ed00287b9d829a0c38eaed3b", + }, + { + .a = "639383fe0a40f99614d8e5546e51c541e303f4db310d9c88" + "657", + .b = "530a8a0bf423b328dbffa4d4576e7450ed609c096421f2a9" + "32699a2f73b", + .r = "6c8164cbaebfbfa60301953d5aa2643ba693be30469", + }, + { + .a = "6104c4f4458890e2328e437f28d4098b2a095bc350756587" + "b2a", + .b = "624a78cea710d55ed9002ee5ea2b04bf0c20e07cf07af576" + "05b0515784a", + .r = "7496a2ec992703084ce1c0612530bb24fa4fce869ca", + }, + { + .a = "21bcfd56d055ce91bf9dfeb28dbd856b8948dc6bcdf4ddad" + "c85", + .b = "21613395d1b095dbc2692e515625af73e204ca223ac29153" + "885bd953ee5", + .r = "24089f6dfee4127877db2b33b3db071fc92031cb779", + }, + { + .a = "2da7975f2ad52bd7d58b2d498890293ea0cc7e6e7194733c" + "f52ed491620782a1df1ca", + .b = "378ab3607cfa0980ee987cabdc98b365a2cafedd48860d16" + "12357d10b42", + .r = "37e537c681b6044fd268d6e53cefce7c5de4f6cf7975ab81" + "6", + }, + { + .a = "2021c9e46190f90e3c10576444aa894f248347eaaeac5b96" + "d9796824473db64d9a8f5", + .b = "1d17ba28d355234b36eb29bd3eb53caddd4e12f6144ca07e" + "54524e2a22b", + .r = "265dd940ee35b5eb0d4ab86f6cd19a4ddef731cdb8fae8b1" + "f", + }, + { + .a = "260f058e995913d6e981e740f57555e3ee86158ad4d8339f" + "06afedcad195ebda92732", + .b = "2249d97ddb467f6f63a6f76ae328cd8d34c2f3115ec4dd7c" + "01accbbe856", + .r = "2c5aca0890e94d789e13c3137a5c614284461a0081dcbe2c" + "e", + }, + { + .a = "582298f46a8c2bf26123bcb6754e71100d5c32ab6186078e" + "fd5c2490ca829be4bcd53", + .b = "6b0f201145e607d237aecf363c5758cd75261ddb034c3167" + "e3a31b38583", + .r = "6f31d80d7dcaae28f5160f13bfd6070db69a67bcbf7cf0e3" + "f", + }, + { + .a = "68d6e63cd61d4ed41693bc9e9bf5c1dfaf8a3dfeb44c8112" + "c5005c69ea94e4d5b3f0f", + .b = "69d2bc47efe097dad533f6b6700e078de4bb56bee98f3535" + "c4ba41b3f7d", + .r = "6e96f508e056eedf13eefe495a5074d9cfd51c970ac0f324" + "b", + }, + { + .a = "38f65d469da22947dfccb3fcff57132c50903f7d5f421851" + "4b4a906fa27", + .b = "35f6780af8e1935b2f26094ab97c4231cb103a7f0c1d91b5" + "2d458ac5e3ff932cf8ead", + .r = "3dc4f73d3af023d0f5cf52a1db4e0bb77fbf7d197b33c82a" + "9", + }, + { + .a = "d37bb7a5630dd5ac27a8bbe67a9e572d9adc849cba18d49a" + "46229844da5ae4915e68", + .b = "e1af2e7b007853438ec70464709355c401b6a153d3588c88" + "ad34b945b8", + .r = "10e3d1db198dc19ba1e4fe56f88772f0dd033831e6054c0a" + "8", + }, + { + .a = "cd763ea0a64c145f02c704855a79c9c3560db84138e5e3a4" + "1518be36e2acaff923e", + .b = "b866a8b952e2560bab904405b5460e7746d86f656994db40" + "072946252", + .r = "d865003bbcff5c843cb5fdeb4f5d0b20393c372fa5f4a4a", + }, + { + .a = "192d53a727cd60ffd45f517998642027212ceb1c22cf5e04" + "c86a374578e0a7ca0b025c8", + .b = "160b4e86db9e83d0b52a5419fa1507a5691ea7f53b752778" + "b98132567afd8", + .r = "1d0af6c5acad8c58a45571ee6ecdf76cf93146f4b833fa1d" + "958", + }, + { + .a = "6e72fcf18123c5fd106660b972858a9f60153e0da651e506" + "4d2dedbeb1acb", + .b = "5afe95c191b714b28933c2c4209d87c8322114863bc7633c" + "c54bb3eba70c449ab38d535", + .r = "779639703fc67cfb5b44cc447cf421864ed9297c67d3253c" + "321", + }, + { + .a = "2244b5c5cfcb3ed924dd5400e93f3ba9f3b91af3c9951350" + "947b78e2e63329e79cea9d4", + .b = "29351beb4d4d1427e1864b0c0f50a83b7ce96a99e1354fb7" + "1b1bd5a5f56fc", + .r = "293f736bb759cf96ffe993d1318f386e9825a16fef8a0ceb" + "3ec", + }, + { + .a = "5cbd24cde8f4ecc8e05edaacbfe038f7587ed23304980129" + "693ee7ba9ccb2e4c37cfe3c", + .b = "511f8aa67af7b2fbc64ba4411ce6d5cb9b5d6fc079139d29" + "2aa4b3235dff4", + .r = "5ddb2337c954a1d3f7bf64f47d6c31f31bc4aae902b91165" + "9dc", + }, + { + .a = "568e21d4ea4742f62550e06340933309c92235f91233624a" + "323ad33837e8f4df0cedeb9", + .b = "478f9166ae59494b600cb56998a6085b28c851229aeb88c3" + "43e64b4b5b78b", + .r = "5c0f58b79e8f8e5cd804cfbabb6e69d19195283d224de10d" + "aad", + }, + { + .a = "4c3188411f8916bf3bc0ae56202f7fa377f68094ff57e216" + "bf90fb61a4cd0", + .b = "3c1c9e1ab85fe9e59760317a49dd166d5bdabf5b7a17789c" + "e81ca4fea487de64c85e630", + .r = "4e3d0022f0e8936a6c364df09cfdf6114355cc757c5a1cbf" + "a50", + }, + { + .a = "11666f96a79abce41bdd2cfe3d5645340039176f66bf8f17" + "c32f76d4f57a8", + .b = "1391e654616857ab4bbf5e9bc59e6e95e1bb0466b128cfe4" + "fc56f302e9de322382266a8", + .r = "14e192315ba47c1ec563966fb4203cdce3c2198777757cfe" + "858", + }, + { + .a = "5dd52c6c3f0a8e3c69a4741c4e9e1ebe42b3491ef4748155" + "bf29001790c70aa59d114e7", + .b = "63e0213b6a9ec52cc3b17dd7bed6e0c5c65d6e309871d223" + "c692ca6adbc77", + .r = "786a2b6037ac9e417750820a5408fd854a1dd7822dfa8281" + "5c3", + }, + { + .a = "f339707d7232d30823ec944eb57f0c40994db22a6151bfdc" + "100838e0e2f15d", + .b = "e8a967992d66b599802b25c4173b71c092b9b297e4fe6f5e" + "b2be799de65ca4eda7b71b97", + .r = "f76e8c28e7c097b1151a3340e9a6f81da2736868f20106df" + "429f", + }, + { + .a = "9e768f5cbb3b3d6f7690ee66fc18b71e6e42de3e7ba7ae7d" + "1230c7ab75ae1f7035998746", + .b = "8a64e46ac9bff23d58e79f10772853bb7aadb2258642282b" + "a3faeeca2856b2", + .r = "a10ae3ba4bd787e552a47efb031d917dfe78b8a362d9b3c0" + "4236", + }, + { + .a = "6676693864c9be0b2d54f2fddb64734d49ea8608eb6c77a4" + "c95ce3d87e98a30a793bf731b", + .b = "70a9d0d8930a216d33cdd447a8f386e76b67133b657389e4" + "b94f95dfbf89d17", + .r = "742a457f57c070b0d76dc3817106351863acb689d3d8ca49" + "9e4d5", + }, + { + .a = "3d3f2333e7053685777a0a35774020f35f37c5dc10dc2f74" + "770fcf181ee58977917bfba79", + .b = "3c659ed6efa9270b17532a4da41e80e33629597b82666b9c" + "5d5f669d551378b", + .r = "433d6d9daaa8273a36fb2ec6d4c7403e2609b0ade522e44f" + "06d5b", + }, + { + .a = "26df635cda763dcb206cea154dea57bdbb0c61c207772042" + "9a0621f12a037ab1f3fc65104", + .b = "2301db7a7731c7ac7fe37451ff70e3ae589d7fd1b8e4e6ff" + "fe2300f6e8a1574", + .r = "299457348e1ae419c4d856b7208d9d3002c2179d4d36d1e9" + "52f3c", + }, + { + .a = "32e720d3ff483e0970b16a2386ae0f6853984e8c800148cf" + "e9e00454619c6b75230c1ca31", + .b = "3abaf52e682307727bcd803f699f5a74df082b8ed85cdf27" + "1498b6c144d54c3", + .r = "3d5c919f138c486f1d41adea3eecedf5e7c638a97dda3a57" + "d71d7", + }, + { + .a = "581da07e6c7da7915b98e34f3ce2df3d5038df161cbfa9a2" + "71d3c58f86dc091", + .b = "4c9ec9a853b470c8c0dd6ea8eef17135530e5e3b8802efb0" + "f8c34488f04253775bf79a29b", + .r = "588b9cebe85c4a617f1db1e85de3f7bad59ad52b99e9abca" + "25227", + }, + { + .a = "62970e919336999817be9521a615285a8db12e33160d2132" + "9eccb37bc43409d68f93799bb", + .b = "698bb6088d35165e3606663ad8bbfbc96095874aac7f1a45" + "8746b6fcd138091", + .r = "7e43151d6f44023d51e5fcb458d21118dfdb5493b4add441" + "8794f", + }, + { + .a = "4a7ecde2877df55b4a71db70a1b48d4b6b9f00148b450bd9" + "9bdcd1425dc9ac19e", + .b = "4e88b372e168f3b35abec63e3c34c6ac51c22878c6747aea" + "1605538e96415156e799576fce2", + .r = "5b47cb37e95f7ae2ee32c61c0368e5bb5902becd43fa1069" + "4b98976", + }, + { + .a = "1886913566ee6de450c1bb2df7118ae2a7a116327b6e4ead" + "bd6f9f7bb244eb0d2", + .b = "19e0bbc5cb73a10da7ec1249f1d1cecbfc0a003e55c09334" + "29293a2c93751c3ea69d8679b56", + .r = "1cc44e36e74585dcda4a6f53e39cc8b01b47928968e0d2f3" + "cf8b342", + }, + { + .a = "5f3a2c0b3c745311105cc6f6b2b460c5cc223b6111e0df12" + "9fd84b2387218b30b", + .b = "6ba00655a3417cccc7d0b64daad96efc0a5b5ea1910d280a" + "603e6af3337295a0e2315509b09", + .r = "7a836b272ddac421d45b0a25722dcee984d7cb192ddffa50" + "8b85ffd", + }, + { + .a = "63aa301030ef2eb49a2566470bccb90e1b0b7e4a7e45b149" + "4556eb47044fd13f0", + .b = "7076c5b843c90cceae07e2e5e8f08167c0f27c6226d88ede" + "0ef4a74aac509ffb109c97b76d0", + .r = "7f1726ce9ca18dde940d0da2bba31fca807fcf187d12d354" + "4780970", + }, + { + .a = "5151e338d3760bb7716028c045b7022d254d329cf2375b9e" + "c2233c6c8e6faf526", + .b = "56d9d823ecb6a7612e0a8cee927d88080b29dc95435ed411" + "0bbffa49f957e63a3586abad5aa", + .r = "67855cbdd911b1b2c5aa7aaca9a667fdf2fc2a53e71e1fc3" + "a50fa46", + }, + { + .a = "56f5e7190ab7ae84beba7746a9b27782ca7832904b330ecc" + "3954342d1be8acaf1", + .b = "5d4d9d53bbfd5a82c49c7e7c33dc0bad53dde899642bfe83" + "9056fce5260c16b1bfdeb73ba1b", + .r = "5dce8a6cc7f1100c375137bcd796e2d34f385c7aaa15267a" + "f5239c7", + }, + { + .a = "4d16c85b71f478b9cab1432b07b80db869d279923ac19638" + "b866d137fb5381fa18b6407155f", + .b = "4ef20f6226388decfc59dcaa0662c74554f170027b344c10" + "45af07d25320cca7b", + .r = "58bec748aea77048b9dfc219223c73ccaa1f32d903ac9acd" + "15e984f", + }, + { + .a = "60328dc320fdf6262a28a2cb49b8faa6fd025f60e9af3709" + "7f6d33e8d63740c9c", + .b = "5ad7495b98a54265ceb0e36c7bd1b1fbafed5d0d32790166" + "1e2b0351f88d563d1380daa3134", + .r = "6a07a2a77696240c1a4bc6626677a90fbf1210ac15b8523c" + "e058f8c", + }, + { + .a = "2ada6242bb6cc488ae781765e7946f6c7afa742fa22a10fe" + "5096a5e25d4662ca5c80f834f", + .b = "334c4a3485923bd40e7f476260a668bd2743c79c819f2328" + "18edf7e4f50da5769ecbda346329a28223341", + .r = "33f17f3a6bbcf17c181d8f7c13e74d514c98e3e628f87006" + "58cd1696e6207", + }, + { + .a = "116bcd8479b8977f3718bde35bd6fdf81812871aa2c888c7" + "9c058f423ab7d6385cd96598a", + .b = "ff4b7acaffca1ecdb159befd40177452837d1596ca45f2ad" + "fd94a4d7d24a7d8c10d52331c786fa7010e6", + .r = "150e9b0d68cf9546371739fcdfbdcfb662cd0910b65e8be9" + "743333126c866", + }, + { + .a = "31b1fff563621964f922465bbc2e6a273c65eef5aaa70692" + "fe9402ea9e34c3de978cde805", + .b = "3ce8f8d96e0dc345e2ed0268bbd0b9149eaf79be4bcdc2de" + "0ee9d4e0fbf58fb928342a69bf772fba17159", + .r = "3d74328b3406e9339af633fdb1f840d3f73ac53a333bbf4e" + "bcad4f564c1f1", + }, + { + .a = "35a452dd614fe7fee6f6cc1101b69980faac01b347a0f98e" + "d92579b0df8d9547e0dcf7a27", + .b = "3a36d5da926d5c775e4588939d740d7ffd01a37fa1157fae" + "bb43cb2e1dcda302cb0d97022865c5c43c903", + .r = "45c72930805ce0bc2f501404c897b828dd3311542d444cc9" + "aa8e4bf3f2b1f", + }, + { + .a = "54709f5da657b3cd9c53fdc481eab8a4ff55960b81032208" + "816c8ac63e83a001d84316bd0", + .b = "5547ee69224b4569a774ddff29c386e050d79f68105ce717" + "ae5554f8ae5813ef92fe4e412f746b067c830", + .r = "56ce87708173c3f347240d9188e39df8c1cbe6bad771cc84" + "abe538d73d670", + }, + { + .a = "582436c89ce1b69993d372fbb3efe56fd98ed01797075071" + "11b367bca3ed422c47731c3c754422822458d", + .b = "505f3e85baf27ffc59822432dc6be370282d2a50345d7e93" + "8295e75b01c0b8f865c74b04f", + .r = "65645b3a51e014830040c63c1bbbe4421536e910b48a3001" + "bd5f2dfb657c1", + }, + { + .a = "c21f93ac416ac68e131736c009187b9fe1066fb41c55dd0e" + "15235211ceb6124fa831099e", + .b = "c5502a7884c7dc04608aa4b3a990050517fea2c56775a128" + "be5baab5a58d05f313bbb09278918566495a", + .r = "c7c1e75e42448a1b7bfa46f18696e834e5d973e62efbd790" + "fe6d1db99dae", + }, + { + .a = "51e1ec852753ea16507229075a7e291728975425e1dad21c" + "a3ff80221fe48726d8ece58f6", + .b = "51257f27b935687b014f8140c4b59542e8fefc1bf201d11b" + "53581594c8a06f1dadd2dbf195adf798678de", + .r = "68875cab619af70abd75a89a40eecde3a1502b5430cd7938" + "aadb39c1380aa", + }, + { + .a = "5536f79100df9ae80b3fe4afdaf70b025af96430452af4da" + "547b8a620b7e1f6ddab222526d4", + .b = "6a47460921edc3de377569b670ea0a919c375314a366c652" + "bcd9abb642ae53ef3123b0db0f7b77aad66a41c", + .r = "6fcc63ea83f37c6435ecf4a205502dd4b0cf979ad62b3e9f" + "16ebaf389521f24", + }, + { + .a = "6f7df67694667235a7db91a84463615e4825e6a750704598" + "1bf8475db70d237f548326867cf", + .b = "66889dcc9881c53db1c02f741e462203dc40edb1931ca92e" + "18c29f91a36c4e50f050ba5fe4a68591feacbcd", + .r = "76fadabc9ebdaaa534887b73763f788de0bc5c2d74009bf7" + "8a59e12dc65f767", + }, + { + .a = "522c9f3d8affecc1d1a6b1f0d8dd59837d786b424811464b" + "f705accb9e371e80ff80b53efb132abcd5f7fc7", + .b = "4f2a601d7f0f802ead4383cb18fc55ddad88347cc569e73c" + "d84a7d302128e9665e903175797", + .r = "5ec7929a08be3a9c3307950b3da7a0fc91f60c574958364d" + "82718e1cbf3eb39", + }, + { + .a = "6a92d27f6ade6e00696bce4a84600e851ce06bbc5bfc51b2" + "c97b78d91d4ff7457bd4f5a002930e168ba5721", + .b = "764c31550c2fbbc8df2ff51a11116286af8613aa215fff71" + "8e30bc2f0de5daae67f61b43e19", + .r = "7810f9e35452f529dc0414cf230b4cfd9c5ef86e176cc901" + "c0f270ea79b3e4d", + }, + { + .a = "776572ff9922ee187d4e012eb4e51df04ca377b4e2362601" + "d050787b069f03053bf7fd9acc228fa1d9b1a8", + .b = "722162ef71899f03ea9c3a79f42f113c042ef1a98dd832e9" + "a09a98e7bb8a2816ca80ec2498", + .r = "7d18769900c4ee401f7e3302eb6adec095b086fbf7c14022" + "842824c8a35228", + }, + { + .a = "704a3e08400a2547bf55534a388a030ac9d578abd16d6e91" + "4afd0c206169865a938b9113fea", + .b = "705df82ca14906c33ca0274f8e1b1f298aa423c611baa0e3" + "70f3b1362803d3dc4c09546cf67b0748bf2b72a", + .r = "72f7735b6a15ba7f5be4d23a12e7408d068c5fcf2c5ce787" + "760fd3138682dee", + }, + { + .a = "3fc7a378c8cf05031a6d046377b972a1750bed9ba593570f" + "cfb8bf7f5c9d50ecf31b5eb28e4", + .b = "4db0ffa81b690182e0f3e06ef9e69026b5ce6406a896dc83" + "1889f00b84906aade207119d7652af684fa20fc", + .r = "502a09e0f389139ddf160ed6a19ac4bb710b02519a62cfa1" + "cfa55e0efb1d1f4", + }, + { + .a = "16cbb51798798f0c16a94a1fcb5e2586dd9c21af834bcbdb" + "b023b57d07834a775e20d8469f77d5f94d82bff", + .b = "1bfd911d099dab2ada4a8802cb0458c6b0595a165007f8f1" + "8e6e846358eee4b91d4ac1fbc43", + .r = "1e216f67c3a6d2621e21b8e0ca0534dbec20a1a31e2cb732" + "efca7397f9d2c6f", + }, + { + .a = "44cdb070b28fce182cb43b25333e1ccae887f4d147fa77f6" + "79c162b4b77071965b4bdccd1d74f0d33e2cbaa50", + .b = "4d9f3309128c553d5f57ec02bbba290e57c26267cdd1a5cc" + "f13fd5f03664f077ebec3bb57f810", + .r = "5b77b2a8f63255f7315f5966de10651d1715b74bb9654892" + "e5083bf49dcc611d0", + }, + { + .a = "2647edd2e11a223bca5724d6091946e25216db7931c96f06" + "177558bf7985288633e95f900b54f3fbf5ae9123f", + .b = "1fc2b218e131cad304876c1d09bf163f9612bf5afdd2bab9" + "c71be88a05be2b38f32671b5e0db7", + .r = "2759c93c8dfc827d7c2644e71ff0139650f80510807fd6ec" + "a2b1bd19e5f36ea31", + }, + { + .a = "36581909e6c39c3bf952ae81696c1419da97c9f38a3f40be" + "a497fc72a991cdc7c10343d658fe78db64340369b", + .b = "39366d8a79b046202bd9ae5472ed7e49dbfc090063844b5b" + "574d6a9b6212fd4c693dc9a59287b", + .r = "47baf308398f5c586faa74220ba8bceb406a6b29f8827fdc" + "227336b36f22e2d49", + }, + { + .a = "3417000970f156f7981b412cdac3efced457f2d0614042d0" + "c97be7cf6aad37ec2d8ce2292a467699c17b1062c", + .b = "3ff5db132200d8c379e548a6e3c934bae79fd509fc36efc9" + "3c984f71b4f2af6afe9fd94454ba4", + .r = "41f97cf95567cf25245694d8508618aca1476da358bbe1c0" + "6c543137cd864dd0c", + }, + { + .a = "6cd488c8a691a37180363f607df41cad6ff38cddbbe45cc7" + "c2f29d0267e8f05e054d01e8cb0b350679f7335d", + .b = "749e450b884827115eb77c622300f5b002c48f2257baffd5" + "c5a1060db36b7a0bf369cec39715", + .r = "89fbd91b2ced71c432be0ec4c04c9b8fe61ef9b5870e5d78" + "3a84a39d3235d481", + }, + { + .a = "2c3d1e27c27d09773ac154c62cfe94878e3218bc42d12ba3" + "572e39b33fa456442680c9ad4b1e99d189b90af20", + .b = "25d3d1bd9b2d0149e5d1811b4de4814577f0dcbdbfbffbff" + "cbd3111ac9c49995d72388f7a29e0", + .r = "2c60932e5574bef4c948b60c8b81def818ddc3efa45e4d29" + "cafc3b709aaaffae0", + }, + { + .a = "5a568e8f4c8e2ebbdf73537193b4580da661794afb37efd7" + "b25f2405956e5ce00736fbd7650f7", + .b = "4557e77035caf8429267990f443b9a7302c44e4c942721c1" + "63c90c672a42b8c1af7c0029d03f8e83a4862e843", + .r = "5a9dcffb4fcb3eb6bdb247af9f311b118eb1474aa66e4c78" + "640484b52d9a9a1fb", + }, + { + .a = "5f90593a7a231b83793a3490d425e1a1de1db8cd1fbb3a73" + "348a332138b52c2d5613efdea9dac", + .b = "5ab5021b9909a11b4e9febefbb3edfe69d4a2e0fbb4fea85" + "b57f92b2e5706d76e6b4dc1180090f6f1ce4c873c", + .r = "76b6af6e823b4ba077d790f1d01e6730d04803f4e4c62618" + "24687081619f2136c", + }, + { + .a = "f5cbf9c6e50adae62ef916b5241dff18f2dfe4704aa60d79" + "b035d2f2611d87c3e192ea93926fcf", + .b = "12cf1ce2298ba5f7c4e11873a42485a6db8a876ea27b5c3e" + "d92d8f423e67dc52158926928a5e28b7e13fc526d25", + .r = "13be9d4ad29c676ff96078bd4093ac49d512f532844d6493" + "126ad6dbba8e690b649", + }, + { + .a = "1fa5d509f556a4c587c709fb49adf1b24817fc3301652167" + "89510894bb26993f99fe800882c20dc", + .b = "1c97ce542d64bb2b0c0666783b50ad7b0ec83dd585326a2e" + "edb287ed08900414ad5a35303da5548ef7874e1b784", + .r = "219df42a796f67ba3fb54c4a95aeee52cf50e912cc90fcd5" + "7727d9bb278771ceee4", + }, + { + .a = "3f79506e9a18ecfc96ecf82ae0e88b3c61b6afc8919df51c" + "e958d3e8956f3be1d9f44cbcf53f92c", + .b = "3ffa55470d667fa61719bb07cab29e9e78748401bb248825" + "50d32d71a37def452f2ee24a5878decbbba036f5b74", + .r = "433ee870e398a7045a26803592d99e9f3f7d0bc931ee7a5f" + "7e5bd81d671899d74ec", + }, + { + .a = "1e88e5e1b5ac07c2e1868026dc8b58fd14c17338e19f0b7c" + "b42ec3af35eb01ed9a69d588beead9ee8bfad6fd702", + .b = "222adfc3c1ba3ab465a187e4861a963813657e04bdc8fcb1" + "d72419645621975d43ea7d508b0416e", + .r = "26718380c83c5b4c29dacacaea851056054770896fc8373d" + "c088e14c64224d6876a", + }, + { + .a = "6f53e0a1787a708e47bc9fe83d695a32b97d60927970a6d3" + "e0c7c7940ea7104fdad2c2b2a345fc2", + .b = "6998951fc97fa4ce0d4e038f51031bb412560291e5391204" + "3eb3cb05971620915f8e896b4b82a7209506248e60a", + .r = "759797a7335f9f0be50246d2906c3fd300c921b3ae21d133" + "c81caabdd16b41a0c56", + }, + { + .a = "404df924bab9c9eb6c43df3712bf251d44ab49dd0da0d809" + "7225ca0afde0e63ae8e3c5c9c38d168", + .b = "42d9ad894a69a138d23ad400e70876d3189f993c06c3b722" + "f0fc175cfaf2a53d11da39162822f3d0bd2deb096e8", + .r = "489d13795e291c9dd3aad13c3cbb2137c6d1cdc696128f62" + "58e41563b61c4b636a8", + }, + { + .a = "11fdc2eaf5a0227b9a6bae285f8d057036b972c5b46dc13c" + "9982982d35c608e37e6d4e6b23572beb1e0c6ca86f8", + .b = "112f78a73b732aa0e65be6a8075f531fc176986eaf4f4aaa" + "f51a1532490cdbbde1f6ff7ca1c68d8", + .r = "15f0d4c054ad88f5ee39c62f53de3efd922bf821cd0fd469" + "08d421218b6d4760758", + }, + { + .a = "48f25eb7d347227114488ff751f9fd907b80fb8370ff95a2" + "f4e20ed1f8587f0bfc6e433d1368e17", + .b = "45268786ce924277c48ccf87bcbcccaf6a9abbac4055e612" + "827d30499ba9acfd5f41f3c3e9b1831d0bf65074e83", + .r = "4d224af8f3dd16f8c916c1c871e6063cb619f0accc7aa03c" + "d6f4874857794f87ec7", + }, + { + .a = "230dde83b7195646b37ec13da3f9be4befc86492d2d65a1d" + "134245c2740f4dba0d9b22d79b0300ba00a8953", + .b = "1e00b351da3fc2d7a92a3863d606d963873e0b42e9323f53" + "76768b00d1f73c5c432e60f08a1188fe2063bb5094bc8ef3" + "4a731", + .r = "25d3f691c07a8bf2fe4ca889e6398e569210af5908aa6e09" + "3c67163703ad224522114e56d", + }, + { + .a = "589f46b0dbff1eba912f1936684b26de8014c18685e9d74f" + "30bd31eedce3538bf414ee7bce19d883e84d5a1", + .b = "5e3bf15c8c82e6e92d77c169868e8b89ecf812291c25ce7c" + "8615f1c035a1a0a6787f8c777147b6561df511da82a8e8fd" + "441a3", + .r = "68c76daa2e2a401874ebf9b82566b969132ca2fcba086df4" + "87a555e3e26d05d9cd1841a03", + }, + { + .a = "3649851b4ba0c637119aa5c53309bf937829973e54da5dad" + "11258fd1ef9deedfac65911552e50e6aa0edce2f1389f491" + "d9e29", + .b = "34723bb44b3b993ceab03d15e6c1c1fe2be151ac95d66459" + "5758768ffd10186b984604fe8f182b4bebce953", + .r = "38593265e78e78b00ab40b01c619c3a0701202e697de1097" + "c0ef93170e07e53aba19ca851", + }, + { + .a = "2940099c4bc4ff3479aa4b3545359c165edf212e215c2310" + "9b7f031ce69760df577d931600ed8737c143ba1", + .b = "307560f1adcf4265d9b3e924ac729fbe695e27162e965d8e" + "0902655a051941f9809c2087437e5ad813a828fe103d5d60" + "ba77d", + .r = "33ccad14f748edceb7c1cbdec84dbe3ae3353edcd0d61c7b" + "bd535e599d9600bfc530843f3", + }, + { + .a = "3cde94be664c6c5ca7d8739597cc53ee554247e8f5e73b3a" + "27b3b4b33ba65983e725e59924e32ed4f5f1bb4", + .b = "3d1e0b1f767fbcbd39110747bfe209deed805708b2225dd1" + "edec2db9376bea0943fe924a3ff70399c7cbac034f35befd" + "5f404", + .r = "3ef6117751b78060f043af98185626b9aebbc0f8b1d035ed" + "acffc6020ad6a172ad8f85dcc", + }, + { + .a = "2eb2d4011022e0d082870fda04ab4fd39007f0dd808a8d48" + "46a9ee2903922cfd8c35b8fcf764d4491fa40e4", + .b = "27418e94127081dbebcbb9e8a374b1421f0b9440a8977344" + "7ef4544b15d5466157800e66a9564f91a27a60c3e10163dd" + "dae3c", + .r = "30e1241abff04618884278256ae3f007bce514a250c9f2ec" + "a8276f8519afeca70d2d8e8dc", + }, + { + .a = "42c5f83c6dfcd0292baefe5061f9c4350c00bafa02959afe" + "b830f1528202b87f38a308ef95c9d2ec1a7126d", + .b = "45993bc7165341ad65abf6600542ed3a592798b31e0631ba" + "cf8fd3ee0bda613f218bb8a917fea9608b703a01b766724f" + "f697f", + .r = "58608cfcecaec3e088210fdf6c1e6f1bf7b746dcdbe47002" + "8e3fb73f7baeb2b031865ff39", + }, + { + .a = "3d900881a88aae0e937ec4ab473b40878b12ea9b3075e864" + "87ff592e4188fab6e34878c98f38c08a0891647", + .b = "3b6d97698c50aa9a1293065aaa2ede7a25cdf961a79117ce" + "177cac2aca1aaff004283dde652cd5fd84eff17dfa965e35" + "30f7b", + .r = "4ed4240327bdfef5fc636fa2bdb399e82e1d1023c501b37d" + "f5ca6e2eaaaa81232b01cf399", + }, + { + .a = "2de3dd6f988b7ad5331d43660f258a899beedb5637501149" + "6bfca53ea72a73b4751ce4dc1cca0dd7e27da7c8e3575842" + "8b08c98", + .b = "309535207f6f72e75fef6cc5701d9279aa2f23a9d9146dbe" + "871164f3dbeeffaec516366685259cf2843938ba8", + .r = "340aa5245babbe936447907ed363da1760c2ed50ec15e860" + "afd003f2207461ca4d345445948", + }, + { + .a = "378d58d4e50373da3dc5cfa9406655ddce1f30c04c8fbce2" + "4a22e827268bc301b5aff83f47bad460ee99595ef", + .b = "3b84d43deacfdf9a69a139b549a72dd330ab25b640637d89" + "02e8d41c8912c0c1a2cf8f443374daab97f2798beec8a54b" + "756b569", + .r = "436a5604f9425acffa4c56c50ac01124560a03e4431015ac" + "985ec89391c5a766a3bdbf7396b", + }, + { + .a = "2e2be92a674b64271ba77a8ceef636947c06c8e043dbbba6" + "419aa89d72b5b0c3c8fcf0e297cb1d89b48a28afbe81249a" + "ee5e45c", + .b = "324369fc279d52cf53b932597f686ce898d05e486757d6cd" + "c56db2400656450c3710a909cb6c9a244b5ccde3c", + .r = "3818db349fa3908706c1d601b7b8af9d0bcc0cb2e59bc2ae" + "160bb678c151d0d0169db45d6ec", + }, + { + .a = "3cf8d75fa4dff25e8d3ae92b8fe1268ae29d7dc6796e8edf" + "4168d084e172eb066c0672678de975dc8f266efbee1fe284" + "2eda24", + .b = "363be447b5dcd69f18a23cddb887413c538e2ca983b47dad" + "40968ac80fca6befc4659464d14a34321da9078c", + .r = "46e81c9549394650f06cb651ea66d9e343711fa23e51142d" + "e1c84b376c75a6d08bddffa234", + }, + { + .a = "5dcb41c0c32ce8b01ee1c09a48ec6c03139a109f1de3a99d" + "d5cd9c72cedef58f9d83c2a1efe2853fc991282637dece62" + "970cf26", + .b = "74f3a69b820d910ed7c0e47d0fdfb74b27990df6502e27eb" + "f7dd95368748b11012e92aca10c5b927df0e489f2", + .r = "7bdcd8ca6c2ebfb0312b400d328e77b99a5423a7447c420e" + "5b359640ed3d3a31251ea7f4b0a", + }, + { + .a = "19cd8b4aa083fbdd52c5e36278cf791308d40acacf5ad1bb" + "e362f125129d6471ce98fab1a73b8c155f76067c0", + .b = "1600d7a5562574c7b3992703e469b4d2c57f3b49dbddea56" + "c4087949baf82f3016423ff4deacdda9ddabd0b7ae65071c" + "990a540", + .r = "1d4cab55e0d93ef827953dacfbe3135ac9500f5b41d559ed" + "0cd10af09d955255e9a0ee6cdc0", + }, + { + .a = "1521d207a6110cf889bd3bf2288204e532edd789c0087e28" + "d11f1f0c2cf4281a1604c2e5c48cf0b3878047f7b", + .b = "11e2602fff3cd4b12e1df2edd9c13aacec71fa1c1258b58b" + "8f21ee736ce29d639ba63c7efe76c0043f8f8759ee9b9d40" + "c6d8293", + .r = "1696a702010efbcbe0f8428337ab4d8392cee906db9ef465" + "f860ffa079afd87a009118cf98f", + }, + { + .a = "1ba61782c3046b89565645b83fa16aafa8dfadffc1c39f99" + "bafe55ebd529b6e46cfe0bb1120b46b58e89f015a", + .b = "1bea4aa3c29b7c7266d543da0337040df47b0e97555cd08b" + "d79ec07c346b71814cfa3af0c8ab6e5d2877353657961e78" + "20c2a5e", + .r = "1e83c86d8156cd04087fcc693ea652114a035261f4298204" + "d7c6764ae538ae99edd7586fe56", + }, + { + .a = "3ecf496e4292b75f9a9670880538645345bf502e1a5bc2c8" + "9328b16944216d0a0e66c65b5192f4432c630af3bfe", + .b = "46951e3e9c58c1a91b9b75d56c33bb511da5e4872c995ef9" + "949455cca8e7af6e3f58d5319218249718aaf871de538f67" + "bbe50dcd2", + .r = "4d04a92c6bb39ee24669385a7264209b2f471f2b6b81bc4e" + "1cbf1b4cfd7f633c8e51846a4ef26", + }, + { + .a = "b37e192b94f62fbbd90ea281a2fd8fc59402b6a15b22395c" + "cf26b94089e19257750d6f0aad5ce89311dc88c6676989ef" + "c51e6b5d", + .b = "aca73bf07977f19b5ab808cdab73702ade57811031783532" + "1b4e3a5e114374004aa903360b9b8811ed1c384be5", + .r = "c561207d0c56ad8c6a62a5718d66fbeb819fd3f53b69bad7" + "6d2ce4f793a04ef167c5bf7fd743", + }, + { + .a = "5209152a97476e27655f662b192bced6a6378a399de7838f" + "8e2619ae5b5e32b627042058245ecc2968cd55a26916d9b3" + "801481ab9", + .b = "5d72f984a9382edf6aec318ce694dfb517cf9fb3594fedc9" + "8b0f817c607285a5dae2a102d2dcc1eee0bedc586fb", + .r = "62b0bad8348883fda93d1d871656e88a150078fdb6855e78" + "08cec104a068d5d478e62af058e77", + }, + { + .a = "54d02589d4c0f2d1f19e5dbe19426ce8f10c3718f20d084b" + "b2b218d30dffc03cf774d5dcb1ba3cec4c7969dc5c6", + .b = "61a0bf4ac88d4cb5f1171a705d4d7998d128e203c9c6debe" + "9e0195f0a76b095378bbef1aaa61227df204299f9218a20a" + "4478f45ea", + .r = "6ca36fa2cad2b8b0fe8f96af99809b33ccec45e9d52a1374" + "6ce61eeac0cee3b92420862f9054e", + }, + { + .a = "59fbb5e77ac4c6939f506a3d2b88561c7d857072cf0254ae" + "03f3f3b7580d79f44563f1107d32fdb316b649ae19c", + .b = "5308f555030dfe2a2d3acc43b8a0f76fcc3adf883f41e73c" + "b0d22384bf1da72d0b610f2f26ad369d3528047a6118210c" + "7564bd2fc", + .r = "5a9be472cc242465acd0fd46542ff8a8ca1a0d57215d97b9" + "d347095bb0d6b307e98c59195bcac", + }, + { + .a = "13c6df0db0cad2e785a62a999c9207722733730694a6c277" + "04f97a23dda58d54afda7e039254c1ad64c3d4e8d18b2326" + "83441fc85", + .b = "1154aaa622140d190c33b5d6c543a78e532665581bb3a3d2" + "c4629bdf86acb532ada4c5f70979dba6471dd6d4ab3", + .r = "16712b107ba923b96e99ec357f4a4b21bb9ac59b10e7af22" + "81fb523eb258972737b8a3ddda541", + }, + { + .a = "ad2ec769ec95442a5822b2ea7fb629f33e3599d319428362" + "2016ac11cacc2757b9c4f4c598fb5c460bddcef5f0f6cb0c" + "a891dbf4", + .b = "a7c23207484b51c7fd1f29115dbac4e645d5fa19dbf57d70" + "65d42e073cb2027cb63c3ffaa68c4c6e7c648a0144", + .r = "d3da58210ecd163b976b24fde2c9f082797d0d48942d35c6" + "ed6a1e964cd01e923833830678c4", + }, + { + .a = "3389e7430497fbfd7cac8430d84669cb672f888da04a0f68" + "81d74b5e15a29533670b077f2853edabe588b7fa63cb8d14" + "1416691c5", + .b = "3ba8383dfa55b8f94a8a1672dfedb3d353b4f4d589b1134e" + "bd9ae57b8eb780c5bfbcf911a04949dc498cb2082a1", + .r = "3bd105eac1dc90b428c864fc6ee986e7cd881a9461f11bd2" + "d1e89b831f9029c97d185c660e565", + }, + { + .a = "68937566f61f83d4be7315ff349e2c3db46247c7534b82ef" + "edb3ff280f01be3240a21bd043bacadc83a6e9fb34ca3941" + "bb2b643bb81", + .b = "657f9bc80e5d7a8749637a9ffae10b1378b7531779fb245c" + "92dad2253102a61408d3bb952c87774157e155b6fd9b3", + .r = "698a96710f17107988c87ba2ebb9f968dad998ff44545043" + "0e1ae0db1f35f1652ca51b174f9afad", + }, + { + .a = "806e21a6018f6902c32b5ac321abd7a9cf3871165926037b" + "b70bb13ecdb601fec01431e17341ab539f2b074468f10e4d" + "f19688267c", + .b = "973640b2656ab402878f1d7d910d1c65a4bbf0243deb0a22" + "c5e3b5c49ceebda794c2e2efbbd43f73bb264301e44c", + .r = "a191a837fb16e2706612fc2329b522d1d708e95e3e2ba43c" + "8b17a6c83987029e496582e5dc024c", + }, + { + .a = "4bfe6d14d02adbdece3c22192db04c62a7e6928590d4f4c0" + "a214c35b5c51c094fcea85ad161c0cf6ce9b641645fd4", + .b = "4f4e3b6003407e08520742559cafb7589e94fa8f2e5d22ad" + "def829a1a4313fda088baa948df6adcbbd1d9458e5fbe4ee" + "8c7f4d974f4", + .r = "5b668aa84bc05a492e9fe10afd275844a5197f828dcb50fe" + "9eadf68ec180b2ee10319fc58d4447c", + }, + { + .a = "16282008f340c333d130e2f7784183fb78546a5c0371c704" + "25387c03849b26f351843868865be89ee6820fa936285", + .b = "1606d544d1376ac311019aa10888a8c67bb518f0008e4fea" + "56fa823fcdd9489475cf1c013adb41fa5bb3e913b24cd780" + "b8f22c0b2e1", + .r = "177f836eb1cbf73e066e460bad118c201af32b042be78aa3" + "98ecbb87e0710976726bf2767a1d5c3", + }, + { + .a = "715a6da986222027f63d756ccef34905d458b4ca7ab5fc15" + "049a1aeb234874f104529c6f9a06969a27cd2f7210fff67e" + "a1ccd75f7ee", + .b = "7282278d0877ee30b1f0a0bb2654f57cd0e699fdd9cb3ff5" + "9dd5f1e5e006989c179d55b5f05d6b36729eae3b1e18e", + .r = "7c392f13a9f95cf9e2f70153c9dadf3d48394670ba5ae281" + "73bbf89c16de3234e99d33d08ffc70e", + }, + { + .a = "f1bc46ce609cdf7a7c97bd840b9b224869cec121e65a74ed" + "818a8954da8b40c694bae85a1c16111c47e7d82b0106", + .b = "fb75c11e8dee621c2ae2452251bf8d517c05d54d36e87f1f" + "5230a1c4d22a87836c1f048d5f4a334e7ddd03e4df206bf7" + "64649bdc96", + .r = "128da5ef0333c0d1efee31eb0a0c6816df7ef64565fa795e" + "c1a355d6cc4ba707787b5faa67674ce", + }, + { + .a = "5be40b81712d5af8f166e965433656616dc88505dae1c99c" + "f6251c40ffaa726cab994f3f2a6f8c9d885a48a48b45241e" + "4ec158130f6", + .b = "5017c43fe300730ec66d150aae46ac1ed96136a79fdc493b" + "9333c73a0292cac1454966ed522dd4ad175b7af495fea", + .r = "65ec987fb27319bc814c28c2f38e8d84ea0d8caa7e7bddee" + "887664442c04a6c68cd72777d68761a", + }, + { + .a = "24e090e514260628e7006fe8ef6982dcde7b6641ed26650d" + "67fe928111bb02f7e7d7894dafd79d23dcc761e1cdaf1e55" + "04c6bff620b", + .b = "222d8a56ba7bf5a83b835705d81ed5583f7066a36155b3d7" + "0cbe9e71aff38b31ed74a3cea2ea3e26129f5c7ec4d39", + .r = "27c9ee26d3cb8aa69095d665e1d14beadffd7902ffa7870e" + "025c24fe8e1a5a8d5cc68d27a3f2a8d", + }, + { + .a = "61405295402dd8b00e25700dfacf55b743e601814262c84d" + "e0798206b1802e8d491d5a02537aeb1def33efd9106918d1" + "eced5", + .b = "6626c83bcea1940abf7aece1d543b9172da120438bd315b3" + "5fce702d4cf40ceaad6c5a37b6d5831f0041f03cba63b1e9" + "aec522acec80dab7ab735", + .r = "6c40ce2b24791b71a8514e9ff5d974186a4050b08456d03a" + "58d71c1976920487b813752b193641dcac0c7", + }, + { + .a = "5e46d5de23e7c2a600290201d033e698d1d55eea4e67e465" + "f6ef83091c696554b9871fbaaf93a166c96224be5d0e79ce" + "75601d43cbe6e19f6684d", + .b = "663d6b9033445b119e8a40f2589ae93c5642726461cab0a7" + "72fea02072bdb4139a73a2b48bb1a72bb390248e6aad95ce" + "a8ad3", + .r = "78b05f955b7d0909b24486705188e732a6b3261bd0d90b45" + "968e3fa1e3316dbbed97e86e2cceb34d8742f", + }, + { + .a = "7c27f13e17b58dbdd5eaf0def441960a365cc6a92b3c2169" + "c59c15f3028f232587112c89c0464b31fc0bf61a497450f1" + "fd977", + .b = "69d9a1bbfb7804f4ecc322b26e77e14466e3d474c09022b8" + "a28c934319344858ebd6ad300737ba51feaa0f100bdb7f24" + "a06023471aaa3f095daf1", + .r = "7cc662a8353de4828ea513b11e28b093ae2dead59e1cef76" + "c99fc112980d723bac561364940efd64d4105", + }, + { + .a = "3c43ed3c6f93afdf6ebaf31befb5399d686eb0964e77494d" + "2039c68582f3cc1f8fb401217f18b60fc5119594fb0f82a7" + "c1cb38c2c35bd092737d0", + .b = "3787da5390f2c638eb5b4ac61d2885d79d087d377fb6b249" + "28d8b4f1e1b4e46f0665627422091dc0fc8205e6a445ee9a" + "c7cf0", + .r = "4611f3c04c5a9a21bcf07704efd6e217cb1d030109a7caab" + "7e51cd12927b59b0f0c00b603b0f5e30e42d0", + }, + { + .a = "26c430b726deba75855f8756fbdc3f66253d7c434a90d788" + "b73101aee9adced0fa265d906eb776337d9357eded1e31c5" + "afb61c8dbaf1235d917dd", + .b = "227295b37eaca84adb6fe12af22af018c5a70887707fa808" + "54344cd39cb0ae8d8f1b70ef8c29e6e38f2cfa637233109a" + "bfc65", + .r = "28f99f06a87e410dda5fb6f4c63d02a0009df2c8e0086fcf" + "5f0b63d24e1722964fa7ed778b93e3599c44f", + }, + { + .a = "28b7a4eeb8f949472ccbd81afbf5967c68b4404d78744a66" + "41eeb49656f0c5658fed789f3e911c5bfe40a398a8776ed6" + "a788cfdcd50e12deb8113", + .b = "2879837a5b56ba4e56812fd7b586cb43b28f279fefc3a0dd" + "d6968d9272500e44ca3abff4d2a73a843c786264b510c2e5" + "ce6d7", + .r = "2a37b7efe69d1fa03018413a39fc11da6212d5a2b312f88c" + "702a6c0fb913944ad63e2aec38fb97cab11fd", + }, + { + .a = "6ab9c198e86120643261db28c3b4bafec69938f7b4be4be1" + "dd7a4558b7b891ce8b6cdbb8efbe2574516ba730c510548d" + "8c99628efeb8a2031abeb", + .b = "6cf468976da9cf19b0ed4b90fc5648f676c62b1c29ac2095" + "0575ed8c6ebaeb2cdb3c66acf1b50a4c62097eb861defbbb" + "60cad", + .r = "75a486b9ff6c5e6d027ae67a70c3f25c01fc7e0a826aeeb8" + "d77013ac33b43e9991a0a07db6df09396eac7", + }, + { + .a = "66773cc79a73512979d0c797d5450eca79039239c0048e29" + "97f127c1a9140401eb790fa93c2459dab8c8741efe0f0b05" + "3116dbc4f19b3ea394513", + .b = "667303ba154d16bd6d221e5f2af88584c8ec971cc5d3cfe4" + "a815ebeea56d00efd0c793c21b2cf9a9b7f37ed2fa1e3926" + "7593d", + .r = "68b8c5e600e1d87cf63cc326855ed9b4263b2be793d00b31" + "2b1a0b224a04b4d354d0e27ad7a6322f267c5", + }, + { + .a = "b69c2f59854f1b7d9f48a5de97bcdd5ffb2d567345afcfc9" + "64c81abfdfccaa46d0332643487aa5bca28f4afa703886af" + "0cc3c4", + .b = "e82f0af1d64112f342bbf28a9fa9a7a8746e98d01d777b88" + "90857d23f3d68c6762478b77105ffe142be97d8a6d7975b9" + "3e95b2960916b27eebc63c", + .r = "ee9ed664275dfb3490e1c5b4212865380c1529098e615a18" + "592970a533ca75b58a5f7e99450d568cf6d56c", + }, + { + .a = "2f031d9878d58ef04fa42f3db553f38c6d13ad4f2acb5666" + "52e938cde96707fe12dab205fe2f0e7fd90eb8dc0db7ca34" + "8e1ecac", + .b = "2562b63f3618a28f06036e276a3a0b51f740c6c4ccc62358" + "0b332529e3c886a56d74dc88213afc34f2631e5a13b2fddd" + "38318ab4f5033df22d7a9dc", + .r = "3165477e4299482810038cda9e697de73399dcd3b266c5d0" + "4781c4b56bf7d6b21ca6b3c4549b47716945fbc", + }, + { + .a = "4099c54116dc69711a515cea21910dc0ade5f71bc3cbbcb8" + "722596882216ca77b1305babc60c0506e39ecabc92b4da82" + "b1c7739", + .b = "46b308f71f4e280ea802ee3235cefab5abdd7c4539943290" + "4868f866958ddefe7e7935d3a67480e7c112da217a23f827" + "c9b46d923f47e52c51d2071", + .r = "4930122b2e74cfeeaf98f311b02cb6b7d74d2c2cbb957cf7" + "194be2c3f5dd616464afd4278b18210fa862117", + }, + { + .a = "2eba58133e1905b0c3e3d1f38a050722bed713fee446e1f7" + "8a5d5b34ed3eb1dfd5890a8e9cfbe6f3431ba3ef82d593b9" + "da631d52c1f58c41f2a02f", + .b = "30d19a2230add9ef8636858843cac35ad81346e14c737468" + "de5c9235eacc9c73ae7cb19cac6c3c5e0f873b3776451623" + "dcc83b", + .r = "3a4b375620193c4b9f9ffedf3936a038b68bee38723a9591" + "671e6dc252921ab32ef4eabcbe1d5e98952609", + }, + { + .a = "62d3eeed739586b307d520aa66fdf31627b2b06dd2707a62" + "7400bd1f2db8b6e780c3ea9f26007fc632e0b2eb084f0b87" + "e5c1c0077a854d7f409ad7e", + .b = "669360d5bdd658d566543fe18895b0d7f454c8a02c394b03" + "a1d9b2b003f6ac2d2d4528297ac68608ff2f4a63cb349281" + "946e9f6", + .r = "6fd213d3646cf9a5129db36182a84778ffacfab2d66c71b3" + "f4b005ea09340d7598046deb3706b4d8d528966", + }, + { + .a = "347888d60a33f8b61f9bb2007532aa1eb744e2c2a84ecf97" + "c295c4137ea532e6e672e14287055c936325a1e7542b81f0" + "57c700f", + .b = "38cb5516f2b444d95a339f89acb2cf464868279b43e8bbee" + "bf91ae3c3c87b745756f2ad7fd8b77c20225fe52b67bd952" + "f7e6c3902d3b95673114dbb", + .r = "4510be2431127d541a3eff0dae5dcde6f1e63013ba108f9c" + "5a0692c24e34edf4dcd9620fe7a65c4a26e2ef7", + }, + { + .a = "45e85d18e8d7c1aa45704b4c2058bb1614dc1d3fb8340f69" + "806522d93702813241e6da3294f7ae7409983383382a7bea" + "65fabe0", + .b = "538d2e8074c2edf23f519974b2864cafb3eee403d6836f2c" + "b867cb5aaafd0c1347ad0eee407b681dd442d554e018d4df" + "1202bf831be7b887f1961a0", + .r = "56bcbfa2a82c68699f85d0b9045e6309274412af1bf9e93f" + "f3b911dc96038c7628bf877b6a77dee23c0a1a0", + }, + { + .a = "1288316274aacc19f984426f79563260201a93817228c304" + "7b1af465bd63bd2d28e0b0cfabbd593d18263e57c1a1d5a8" + "7fb9c7d97a8f42d7c3648", + .b = "10941ef14a7e6a5a46ed981831c20dee4d585eacf824aaab" + "98992437669dc86627a78dd1d820cc473d510525844948f1" + "c9098", + .r = "14f78f752730b6f05aee516ee5a9e8c8066752b68f1e2359" + "e188bb1f5fa30b818654385cfde2b6cdeb678", + }, + { + .a = "280357b80157b056a9f93236ea4a96b0a30180678dab7e29" + "042855b83c6900334df17b9d756c37b0862661fc311c9386" + "731c9be4be8c7c83582ff6bba", + .b = "240ea2a02538bb8d07c1c7dda2b441666ff44de744a61795" + "59c66aa4795ffbd4160d90c8bd5856f112ba55ce1b619e08" + "ee26b5f26", + .r = "2fba59e8f3c862b295846bbd2ee0faf2d8d18f0223b7cd06" + "71ffbeab03b49418e4ea97b55e4164e51ec5f8ada", + }, + { + .a = "93e0f8a84c728310c6b64841da981c57dac26291708cd338" + "bdf55a8188474b6fd791b5f26088c9ad56286523f4ba86cb" + "81bdbc2", + .b = "834da9c3dcd0642656ae7661b7c56de481e5b7ba1e78c276" + "907e2681a7c35fc4d381b429903c7315e850573f1aa03529" + "7492b0d7da203b3dd5b6076", + .r = "ac42f47f1b241a5a237960708e9ca24df3c74c7d792031c2" + "d7f0c557ad3bb8228319397c7f90457bac284da", + }, + { + .a = "9dcb088cffb10531ddf0211f9127b767bed3d7cd56db782d" + "9d99f775b0aa5a12bcdb34f9de21acd8dfdeab663ce3b113" + "834508f3529c0e4c33d94c19", + .b = "b044e928a4fbf8635c92585f0b97d2dc37b2958d1802a94e" + "1018785a5c10df530e039792f82b8c05c96552914fb0e74e" + "58f9f525", + .r = "b7c22f0b01fcf7e8b6e6231b3d9470dbbabc2d531f6ded3a" + "4d20deb5821a54a7fabdb5b16a0f793037aad2e3", + }, + { + .a = "2c73e3861c90dce2a7d933f2060f84850429d00c01c514c5" + "63505886a2b11a4c4ac2b63825f29d814ca1e6f4afa41e4c" + "cae9aa407", + .b = "288531d5b6595048d0e7b770ea6cf9c26786a3aeb7a1b5f0" + "307030acf9317edd73120816386c46a9f9b91f7c6aec1d68" + "5f72c962570187b34c40f8a53", + .r = "2ccbbbad78953dafe4777123a005bb92757bf250e00abd52" + "3724fdbd51fe3b5d14c596e281b8a0745648f2857", + }, + { + .a = "4999e088dcea64cbf4cba439295ed028c001ee0b3be03232" + "61d01e1d59570a9ec5c5611f5778a8f47c9930bfc6bd2ec1" + "5a05746d0", + .b = "487ff683437e448efae77e8a5bc621807e0a832b854bd7a6" + "68517b8d217bfa8b0996d6769a94578c09d3e27263512f27" + "5ce5ec27cce7653407e95d230", + .r = "4ab76065639776a1253bdba9ec37341444641ed9a1336a71" + "b4292d257b8436e6ae3f44967966b3bb41a4b8a50", + }, + { + .a = "53177f79018ed47528ec38153be5e8c6e90039b7cde42f7f" + "0126ce89feb93e11fe09861687dd73b537639034ca5561fa" + "454faf0cb8e80c8eca7c4ded7", + .b = "58be4ef81a47d47f6642037ee4e405f01d7c9ae87a05c493" + "64797d99c1ebfca8454e219ec7b388c9b969d14db722bf94" + "7e125132f", + .r = "5b294290e7c727163911d40aeae5d9f1fb482e4b8df31b55" + "19d77d6db35f1b79458f219c5fc87d7267d192077", + }, + { + .a = "1add9825d173a9f85180570eb176be0cc1854e34ac4396fb" + "8342b4f6da67830e9a636ba89534dbb50150bab457492bd5" + "40ba103e", + .b = "18d51b9dccc09ed1a938915e0662b23c78ba1f9dbe4f2585" + "8c7d395cd4147c0a4d229a05655b7d81f325371f10aa1b93" + "f48adbe09dbe0598fa7da896", + .r = "203fd7241aa0e48302d55a51df04c84d84330e3652e6b39e" + "9ffa7bdab9cd999e7ad1e0e454d191c8595848f6", + }, + { + .a = "547d4291bcbeb5f4a506357ffc3a962d5d0326eb39ca3e7c" + "6e3bd08384a83b53cda4ceb000f4d8001713e6111265a38a" + "3164575cb", + .b = "46b880b9775b5eac3b4af101d290d229a9495ef51f08d47d" + "643e5258bebd9400d02ae7686395066a9130e1d2b98b4a1f" + "383e8e863a108bd90f6083a07", + .r = "55ac2d896546247e799293383cbe526c07ec1132c5007de6" + "8ef8def59325b7d6aaed8b05c806bffc128ae9fa5", + }, + { + .a = "478d00c0c26851533fa5fb00e1d663f4db0d9a96c20957d6" + "1d412edff90f713f37347b4692f280c01c2b8862505d0660" + "1abc1600ef4", + .b = "4545034b956ee4aae5f482a37749aca3c85f81c4069f8e16" + "f268de62136bda95f1a3aefc7fa6919a237eba53fd86a084" + "d4b2eaf747a9c3d619a0071b25c", + .r = "50397d24f801f90f08afbc36b8a736928acb83a89fdac71b" + "5f12c6318792c2e5c9578033e1c7134f2cf2c166d24", + }, + { + .a = "31e346bb41fbc4a426d1df66e980dc34bcdece632cd64f8d" + "fe8b5e834cc7c2b786426c8a420610f2c22739601ae91dd4" + "5f138a7cee8", + .b = "3004245c6132c6a83102b859144076b36d99dc67fd58175e" + "1af03088a47c2fb72f87a4f0d70085bac3c1e6635915ddd8" + "30fa74a57448739813212522538", + .r = "32d0eb3acf9f2656ec77db54badd51ea28ca120078e69f85" + "ae2896b410a2fc0fad95077ee3cdf1efbf891c894e8", + }, + { + .a = "1ccdd16940b590eb23ff82c5f9f6d57a621f34eb3236f803" + "c095124b7da573c6e289dbbb662e93649a5dfc8d6dc98fae" + "c46e02856ebdef3b31eadca55a0", + .b = "1ae5fd16b2b322ca4b7f7b1f9a4796fb8970aad3d0fa91e0" + "8ad507ce487e3c0b8f627bff1ee11678fb3d96f9337a632d" + "7b55b2d7420", + .r = "1f287b4a3c158c597491a8cda09bf5b7b598508d14fe62ca" + "39c4bd4dcbfe60d8ab9ab1256b7dfac21a10a48a7a0", + }, + { + .a = "5fa7b4163add817d4e75cf4f577e120b240beb9a009b3930" + "e079bae2413f6676918426159eaa93318ebe2b5793abefaf" + "b5e38c02f2aed3ae66b6fdda9b8", + .b = "4a264e3d87007b75657b6280a5255bb3a516faa770d62884" + "87c26e23122f8e148544c2706cee6c87dd63146b3d760eb1" + "b09db607f48", + .r = "6164889cc4d58877517991567e772f06ee3557047736bf2b" + "3dd56a320968c9cbfcee92db6f94d4af72741363a28", + }, + { + .a = "4b280b247c4464acd4c5834dd98fa9457899ca12873fecd9" + "b87c180d0173d69ca2d152854b040b1899e2cadf29b3333e" + "87574957177", + .b = "4aa64863f4890c3f9a5c1f7e2c7064e80ffdef93f1f11b04" + "dbd64b7e0ead8f4121a915ea44101954e8e58e2bd6af14b8" + "98ed0b0c64ccda0ce2d8a5784d7", + .r = "5978246f6a19c365ea7dd01721a2378a9fee53707d4df7b0" + "d8e83f44b5fdaac20d39b79f8f39829bf93fad96765", + }, + { + .a = "2ba16f75674eb3a0dd7d19eaa93d49e7f21d32a8be164ddc" + "6e08681e4aebbc08adf959daea7928d7ddf79d1c793e219d" + "535e84fb234", + .b = "23b197ea7236d30bbdab39f6f90758cd4b69663e9e0b5444" + "7126db3ad6ef8149e4038213b761a19552dec45892d5f9a4" + "cb2d9a7ce7d900571046dd40cf4", + .r = "2e87d4fd2fd116d078cbcb0616a04cf5aa91ace4e89621b0" + "4158afa45e44b71ccf66c3046fb3738ec30663b0c2c", + }, + { + .a = "3b61d77906519c5de1be3277abae9007bf94091e4a62daee" + "7a901070b2088a96995511dfe37c42c5c2de572408b9abbe" + "29de5522aaa2ccc0739cdde8fbf", + .b = "3c25ab9e8afbf26dd1fa537b1a647c571c3f0d261b4539c9" + "cc919ac09e02e1df3b26dc3419dd70337c1480dcbd2acc19" + "d613a6cd9fb", + .r = "3cfe3abb8fd56c28ca4e2e5ba63e005f47086b208db7c28c" + "5be741c0dc4d8e47fb78051e6a33a4ec7fef86aa2ab", + }, + { + .a = "2969653d2fd900fc2e1a9522e08d762cdc7da4f86d014efc" + "dca49284133d92979943445f066fba74a829f8d81f1baab2" + "6a5732cf89a88845eb310f7ba22", + .b = "259a8f8c0e0785b581046d1b87c4ef8c4869f16aa5598c9e" + "7c8e5354c80b752e4271825b83f99666d815b229ac6e86ea" + "0bf165cb0ca", + .r = "31d8a7405d8e6721f4d4cea11bcb866886a157d3d2f7b019" + "e7b394bfef7f7cd9f708bef0d4297f4cd9585be1876", + }, + { + .a = "506f8d1906b029c816b5cd4ab1d9b59d9fc89b74336141e4" + "5eb79f17388a29246eb55331331de78dd60515a3adbf9b1c" + "323976491668d9c8556", + .b = "494be98359239745ee26f3d7aaa521e2cb276a37d47c166e" + "0369c44fbb77d7c3be7b0ca2ce85d69706e652557ff30906" + "15ca9f4e970ee9c4b4075b6ff4ebefca8a7f2", + .r = "5909113404994148bf757ae73c913969c4cdd10aefce2a7c" + "cc0deadecbaeb2eb0d9f42fa135b3aa1f57e91619b6e9c69" + "e", + }, + { + .a = "21343f9bae0a088229513be0b7b3980c8c4254084f1af6b8" + "dad25196f2c46bd19ab09a5e070cf6383147b27e2de3f59d" + "ab9e98705ed82ea5976e5594e7e54e17f9988", + .b = "21488f27cf5d5c2f8e68984c29367add5d261a07ea636743" + "6f3710787c7a684f2cd6f31aa67c4cfc7031cad9d1480085" + "305d3a55e7d2e2eb408", + .r = "23315f7125c5e9557a20a2ee85c4d2ebe6bd52e73e6a8831" + "43f032dcb8997966ec5b4e09777e4577108496e284da4de3" + "8", + }, + { + .a = "58a5d5787fc9ed20149a99828579cf06aa7fb92956fa8783" + "0c63f9d88a98d1ac89ceb3da69a1c723a97413aa4022d857" + "3c89ca9488ba1cf1c79", + .b = "5b07e7dafbfdd8ad725a7c4095fdc4a52df69702253f374f" + "e32ffa965a5ce4549f266a98590ce8de7c6e01f7a62bf429" + "9c4a4defbd38bc845104ddcf8912c1cbfacdd", + .r = "64f6bfe98925bc757c53aa7f9feeb67757f12c01992bb2e3" + "bccdd4c940303dbbcba127d73cf193d78d3c0efa78bbf442" + "1", + }, + { + .a = "d91b8fe0860e8843877df1899e65373722d4faec5b6d3acd" + "217f33733f46659a7afb4857fb368ed583fd1ceb33ae2faf" + "7ebcb71e48df0ca9ba", + .b = "10620c79f1b5119d772b87c9585dd059a198281b8563dabb" + "e62965f1798a6021024604bdad93f5908141f99ce060aa1f" + "2f691d15ff1ab0460f2d22620bb410797204a", + .r = "11d9f3439f0ee0fd907ed8a473e377bdebb29200acc7fe09" + "4637215325c5e63ebd9fdcc111c7579ac3c3c60f9688f5e5" + "6", + }, + { + .a = "8df384d9fc8aef45ef7bc545004b42473b5167c0af668748" + "e73747ff944665b1cd8af417cdb4f2cccbdb5fa260eb3e54" + "e94988fabf95776b42", + .b = "9134ead1a618378f80138ccdccc39d364151c221a8d3c6b2" + "893ed89a2199b3104dc5993ea2171e03dd3333e6f51e8628" + "9b698fa4ba0a12bafaf6d33bfdf1aa790872", + .r = "a8644df3da83254713532df1104ff7c63d56471252a1c0b2" + "ef32fa3e071c3dd61c35a0b722d7f81c70cb0881492446c2", + }, + { + .a = "4503fb24d650b931b8b9488e30c934775bb84af01d25048a" + "b4da3a829ea01fa9f2f72c251130c8f138bde24974ffa17a" + "abeea363c98282cd2ea", + .b = "437bf0cb65aabfab5125a12841d24b03191b3f5d2954af40" + "14394340b98b7e21278c0afa76e458144bafce54b3edebb7" + "9ebab9670fdcaa965181841680c093d775df2", + .r = "4b9b8468e03c458b40fc9e211b392d842f31becc6ac91e19" + "4e9937d2e1e0ca319e761529b4f17e9f241ca19267754ad4" + "2", + }, + { + .a = "51e178c447a0d68b7f63b31f380b6f11031eb470dc79eb1d" + "63286dc855d138aa61fb13c14e049f899546934f58e83df6" + "c6d1040f05f217934eaaca5066b5108e700de", + .b = "4e966d28e5a384975950696b18aa0718b53f1a0a641fa8a2" + "e9fcb89a8bac638e9bbba048d7a4e4c9d9e00255bcd27e15" + "1ed5a22faaee4ed40b2", + .r = "53828448c58e59b5686c5476e392ff03d9dae93db7b59815" + "1f96ef490d88000fd6d10c13a825b8703818397738963c8d" + "a", + }, + { + .a = "73bf0bd98904a9426b98276ef8c4db6c0d88f798af42c6cb" + "7331923b42cbe1e8b837ddc5fd64b8dac401ef638f912193" + "5650d75095d4caa642a47f90bcd149baa1495", + .b = "641c99db7076110f5f409a5e8a5cd5d95343fa00fec709b3" + "49cddd9099ce3df4d3b5f3b5c07492509704dbfdc6160bdc" + "5b4c095f434a3b4bf13", + .r = "75940862ea8c907c0a285e99a363887db2396c2af94f7bc0" + "5ce010d4f05d7e06c915dad223de4bb487c40823b425bbcf" + "d", + }, + { + .a = "64051802505f6a22a4dbe92b6941a998f2769451f226b229" + "0f9f49527ddf48e7033748fbf6a5b8aacd8e04c60bd91cd4" + "3dc3ad4b071d3de011b96829c228e8092c1561d", + .b = "5f966b3742e94b0026201eba0ad5c5df694ddc5ecca6c3ae" + "9ba7a607cb6d7cf251422130b756550124e026247fbae63b" + "4defeef4c767c3f5ecc83", + .r = "7dcb81527d60b9836352d5ec3fb149d3e84ec3ee942f6c08" + "39916f157865b53b0baa40e767a6dc8003f184966d6aeb1d" + "a6f", + }, + { + .a = "1d61c7a7e3573a91d180cac4739adf48b5b74c72f7063038" + "e9c4d1765d7e4763124ab4031b640e689e25ccc6afddb4a4" + "fecbd6fef8527ed069a84ca9d2c9667274d2da7", + .b = "212cf854e16a4cb27c31647c40475f2eb107a6088a3421c1" + "7dc6505e0174aa96a8c6b0927600088a2a528db26569563b" + "7076cb90679d4e744ad17", + .r = "22263a57f0b9e118ee0dcbfce244d886f9703057ded0c813" + "639b667a40bbcc6c025fd10f4825d775591bb1db67c9ebb4" + "373", + }, + { + .a = "446a314d814702308b15e746cc333e10b1b7993052aa8b7f" + "d2ad435b4a8ea39cfa9d15e3b6b1cb6a16f0f809a4dd0b75" + "b9009b854f2d4bf42bc23", + .b = "3fe2ef96281cc785d5f4b5e9682c08a7abc223fe9cf74dbf" + "97e7fea943970e45bee301db05528c0b82137f9b411041ca" + "90f39805b607cfa52f7b41f5e8602fc47c6bafb", + .r = "45c015f28190be09b97094a8c59bc04f34239eda90ae2ce9" + "085dd1bfd5205b26d22f1b362290ae010f19cae6a6a02462" + "723", + }, + { + .a = "ed71c4d73211323dd48ee38cad0864c8179c3b7198701fd9" + "cdcd05ae0298a47985802c387324ad277c915d050d463173" + "d702e5a873ed31527a142fdcd086cc759dcde9", + .b = "f99de4bea4fa9b029bb50dd02b77fb53d2d61403b1bf80f4" + "ed44cda0f665679f8601c385729f7d90c3216fc025c3a9df" + "9af035f5ab423c668fe5", + .r = "134afb2bc229180a005cca6cd96115a480c26218b7512cb2" + "99ae6629e77e74344ba74968a67e25cce60bd0bb7f3d1aac" + "017", + }, + { + .a = "158f69f9bf4d1cae17a2b6a85e72a62272837ac452fe147d" + "d69b096bc68a8f8e51cefe6e7f7c8d38290c918ed82073a2" + "909cfbb48669d7f21a982", + .b = "14d3d9149b52047e1ab18766533415bb6a4bc5f2f5e80285" + "c45dd1f73542089039a15d35162e37e7e258374cf9fed223" + "c1ce9c4fdc1d49985892edf4b6197bc96613ab6", + .r = "170caa7f4eb0bb1c72138de7ab78d8ec7ca40bc8c5ad2962" + "af6edf075a6af208f5a05631ed2f9531a56e2141c3e5883d" + "cca", + }, + { + .a = "1d5716fc95b5ba0fa4a0998f836ae1dab1c194480d2064d6" + "aed4349bc6d65f591d9dd4a42411bb249965a64ab979e9fc" + "f227b29095c8a2ead7f6d", + .b = "1c44c0622846ffdedea025144cc4e84aaaea8ce1dc5d1205" + "58164aa8b63aae1975fa5bbc42895bfa8f2e13dd8d1cfc5d" + "8ae30db81f9bf2d1d3ca75c9ebc6b9368dc085f", + .r = "21e1d58ab5abf752819ed5cd86894f812415170bc16fd03f" + "5360e713602f25215e2e01000a690f52ddd48e802b790625" + "ee9", + }, + { + .a = "5f95d61d5ac8dfb6237f983a975254959e16a64099f629b1" + "73d59728ba69a78b82e1d0d6ac33bcd2ce1925da02d7c34f" + "dd9ca4fb2fbf2f91a1ffc", + .b = "5250417c833f88eeb2891b033f077fd58a3d3d56afe8749f" + "688006fd5e3db3924ead2f9fcc610b86f41d570f66d0f9be" + "131d49c41f851a60a3a7cb0ab6117b469f46944", + .r = "6b8d9606cd8926ebc739c6162125b4ce0dab87354c13b6a7" + "7075cd343d8732a5af16fc330fb1c600b6b36d47f66b6607" + "43c", + }, + { + .a = "59039282401a65c164713172f1ccf9c4d97afaada58d9566" + "7e7a7533e064bd6390f59a6b7a34bc2c8f19f36fcc5fb272" + "ca6b46fa91f64c9f20af505ecf0004def24cea6", + .b = "58352c71242e461377106b457b8d778004c825641a53ccf7" + "d4697f821a074e21ec65cec7d9f8112177d76746d955e48f" + "008f4f513cf75ba3c0dba", + .r = "65da4653de3b0fdcd2e5ba6ecbfa05efbff01288526b7fcc" + "15e5332828b3e4f19945d535e4599129c4ba06c4818d673a" + "5ea", + }, + { + .a = "3684d6032ff15dd42be955e32b0fdbb85f2a1c6c8bb00384" + "1dae0e00bf12df6984067c54bc5838bd4e8fac98ff0cd678" + "0ef1cae4037d800c62ba4d1", + .b = "3411cd025265dd2da51495775758bff7813259693b9ae734" + "67b5b87febb41c27e9fd871150eb93e09fc8283c335432c6" + "3c9ad3a46cc81fed9be9e1c49d4ced031d200fe69", + .r = "42513f708f738678c4fa764fa601af6e93c152b165ffc39d" + "f97146b14f57d39fec1033b7ba6040e142716f66659ca2fa" + "d972f", + }, + { + .a = "35f5d92e10e5b20213267b3e394a9a9c389095800cee76a0" + "0ee0dcb7fbfded16bff6b4d011ab39a680421248423f6825" + "76f202c5358d69e73c253d2a507e53fda2453f075", + .b = "2d337d460643e294732a70f1970c4bab4ea720422a238027" + "1ee50e5bd897b18ce52a8820757e139dd515e187c4a24a9e" + "82aa1fc2e5a72f0f7a6eddf", + .r = "37805ddf1106510d462969dd0901ed9ac685ceb2039519a2" + "2d3e18de0d5009876dcd66d24f1303facfba475c8e14af6b" + "19fb9", + }, + { + .a = "176df0a85bd4230ba16ce860963ad6cb1b05e1feea2ea3c1" + "a3ab916f039e3e1a27db3565ac5648b82717eef5c357cc51" + "694ca181b64ea28ded069df", + .b = "15f221fbd53d4eb74ddc06ad6d768ee04e40dcf58bc1c084" + "235786fcbbdadd235181084d85938955813459912103d37e" + "964d685b4627e682d4491eb2c03bdb39e32039353", + .r = "1a62b3f8b2d3cc0657433fa37f6521c051eb5eae3ecaec7c" + "763d5095a346a60cf3470357626a1e074ec0358e382c2899" + "21dc7", + }, + { + .a = "4e6a76eba33ff0050eae889e896f01022b3e97d8d3d79bf3" + "ef4aa0a7e3c47e1d260082fdf5cc48e7a4fba332f2a1bf6b" + "2f865d5b1d22d4252ad556e", + .b = "4251261d1cfcbd60e29b0159cdbde3ef593f14855e260e1d" + "810dfa3b7965644c8294f03b39c69587808b0d5d67bf359d" + "059caf99067305486e0d9399eff72f285b5da1a02", + .r = "55daf1aecc86dbd8dc1bc1e39cfd601e24895032894b1b4e" + "aad0154972a597cb8b0d836d57c634962767c053c27576c0" + "a04ae", + }, + { + .a = "a7e3063f253529bf049b25d65650adb1585fa551103b71ad" + "bc022b3a897b7549d658795d8e6561b2222d76da2243fc2b" + "42d10dad8bab28e5265804", + .b = "ac5f34ac9bf20f064fa36b457d77769035a4bfe6702e6b42" + "edabe0a2bef03516d463a04bad0e57d6f2ae8f43050292b7" + "4d54e24c40a6fcb02c20bf699cbb4c213f4e60d4", + .r = "bab2f490dac73cb3fc7839d65ab4eeb93f5a333dae6f326b" + "c13de7cf18fb94acaccb915da4d45c0c51f7b902360eab63" + "4b94", + }, + { + .a = "4046e1893473d68e42c580d2533b7e34db79b16f9d859ac2" + "3dbab1998300ce578e0b0f0ce4e907d53d7f682e23d37dc2" + "147c451ae0b00cd68fbded75ab158fec892149847", + .b = "319d4ac19ff7a710f7e30b17f732dd5908ea93167aaf1734" + "edd540c438fbf91d41f1c65d1a46c6dc5b13eeb7dbc968d4" + "12c249f762691a511f07b15", + .r = "412458da91a0a1521fd0d1c22b7c053b814fab4df3e87ba6" + "ae21dc22d25b3bee7e475a3f48ecba135dc83868c6ddd25e" + "d58e9", + }, + { + .a = "1acc10bd504085b8432777bb6c271c9055c233cc21b8ce2d" + "6b470cdb6d1d0c74af0e1695442da2081d9492d35770cccc" + "2d1731e002cdcb45ee45921", + .b = "1b4f37bd77e0a7b314f592443f59ea10de1dbf0445bc6bed" + "128dae391f8516186ee45b516ca3475fb3ea11116a34f2ee" + "850a74e0ba20fdef9ee45588c3ca0ef127d0489af", + .r = "1d9141432a729a9b3aaa82d0503baa91568654af70cd4363" + "0355718ca82f62ee6f14770f10c6437bc42d1854c6eeccb5" + "e36ed", + }, + { + .a = "60b82f6346f5e1ff60a0176b471ce808fbf43358a16d736b" + "db3219f3f5f9a46a996122b2f2784c50121dd93596279b2d" + "6a2a07713e677ea4c9419005a6d986bcf3a9ce0bf", + .b = "74939f572534c6a8436abfddbf00ae0c33a465675989946a" + "474da3c695fba4c6490478f37b3d6e5c76e590662d87dcf0" + "14ac17b13cbe07199cd3ba5", + .r = "7e8091f648a47ce00f184882ab10932efe8967447807c941" + "0b82727bb25620adb9fb91c58bd701cb50a444af3deda2ac" + "cc4f1", + }, + { + .a = "5041a12256efd3559135a980a600dd8c71d33bc55b01475c" + "2d8516d2d606962efd8b8b4536a96f9b9a0e092f275b8652" + "c5ac60f2c8956d6fdc821e9fe480061b3b9d5e2dce4", + .b = "3f8ba54304ec5f724fe2f8161a4a15eeb203ef9b96c9c3dc" + "ad5769b15ff60240643b6b3e6dffb1f57e210e794a46d510" + "aaa4243762085a3e6d2e8ddf4", + .r = "53f22b42f1cfb21f48afc31b3ef5e63f16117906d9d5619f" + "3b9e4425d35fc00588d23493defc3b3c741b57f0e3925105" + "55a1934", + }, + { + .a = "482592525884dcfa5a3c7d1ef4ee019ee36b74efa8760e03" + "b8c9c25f73d11c2b0eefb6a4c1eb054d6cab50608dc46180" + "cffe442c5028a444591cbbe4fbd7a3a8a7e9af7aec6", + .b = "48068b5e29280df0aa9946c85ac651eb99129e56460fcb80" + "3404cf2aba590a80f27862bac4f5dfc3b53f705efc47d5b4" + "301b11b24aff938ef1b2a6dce", + .r = "54d661714aa606419e3c4a493fac4758d55a4de6d0ae8669" + "d539a1867447073a821c4f8ead9730cf1eca56bd3913143a" + "b8cacce", + }, + { + .a = "5baf6c4efe7c773afef12ce9e45f367cf462bc8677b90154" + "9df1f106ad7a59e79d3407532fd4e40792ca94ea8614a51a" + "da0f04042588aaa21f71a15ac747a583753ecee0193", + .b = "4fec301df38963b0df53ae7456fc3241d338fb0ebc719c4c" + "b6590ed2930885854f03c0bbe83ccc313ce7a40819957c71" + "1dca992576432c20528369c33", + .r = "5d49d2348ebd7e89402f54b05af16b6b25834d1d39c96f89" + "cb908d3dbd18f80edd0b2d1b11f45e3eec077694101e855d" + "49cbd11", + }, + { + .a = "2a2b63ed2a72e6759bc1cd7f47e1431dd871bfb226ed3aa8" + "8f7b1b17abcb08dbb3098d12b5e3e58d06963a6a9519bbce" + "c6528ef1a45476623662a2e11", + .b = "2c46b323b913734721878e9a9898953631956bb6c9a2b4ef" + "cedf8362065409753428aaea818f13649321f92611843a31" + "8a8a38a4840460119a08d217641560a1976b1d679c3", + .r = "2c9003a62b4e3a5e43abc538038004d390a656d238b411e5" + "db21f7bcd7f7d79f52749cfeec14ece4baaa35aa51746e41" + "2024acf", + }, + { + .a = "1cbd299d709faa872571432fbc27fe7bd54d73f083d4f64c" + "c0bb273983fc6ca835d6d520d2e469609c785aa1d5052fb5" + "1dbe4d591c5493638b2e19eb6", + .b = "1d41ded2310a8082543d3a458ab9d3a3b7673562b365d209" + "9a00f32b66a9ed87d95dcb3c9ba5a87a969d6f5b74a030c6" + "fa6faa5d03e7676a5855b91c46dee64e00f8658e75a", + .r = "24425b1ed3cd100af596e80c6fd95404e71c5b4fe9aa7add" + "518c3577da1e13a1074e60eb08c7d8e13f02475430a2e63a" + "be88cb2", + }, + { + .a = "1ca04f2c09b9596c42931ba8ee02db210ff47fb418a30b57" + "9f7efd43eef13532cbd81ab417785c1683a69980735dad72" + "c50c14231b7a97b7b8bf95e67", + .b = "1c808fde57e0c48e8ce127b7f2f1fbf45c48f1e750d05780" + "94af9ab929452340a01ff8bef56aaf980518b11b3657574c" + "9094992f00e9f865d7d20e2458bf72c7d301f84c3db", + .r = "22a0e51cd1b018a42796cbef433a38feabbb38205518b6e3" + "1e354f8d88b3b5b6c639b774804a44a0fefdd1b95a8a0e55" + "39ec419", + }, + { + .a = "52c2829183621220af8de2c0ed3dc76a8a6dec5267236f0b" + "2a22a805d4bcb70a18c8ec62e535954c6aaab0d88425c7a9" + "0a8071419efef709b1fb521d0", + .b = "44f44bcf15967aa6840213cae893971a501acda24258d714" + "8725ee3e032a422e5be1d69121a9f9ec7678b2de016ed626" + "f697ea4620534572e975ef10d3e91ce1bc9c8cb8890", + .r = "5a8dc5f968e491cf69c4addbb173d8b7ab541ea69290fbf7" + "9d4c58c8dae65a97350ae0cf2888c8bf8d2ea686f99dcf74" + "c85e790", + }, + { + .a = "3d5c521fa9d5e9b5ce987fbd317fbe82fa1a22ba4195c3b7" + "d240fb96f7f64afa63609f0938cb071c148c762b02b78eca" + "0f102b0a00d8f340bfed713df", + .b = "4486f157d285fc7fc4b3baf3d13557a20652a98199c15282" + "65c7b45f4368f968402871bf12e674f29521f75deda405f9" + "cb8f5ba0548a7fb9815c90b398fb11abf1979cab9fd", + .r = "4ded51500c9fbfa781c67ad1f645744af2c37a43d3dbd701" + "c2226db2484f0d386e5c7a4bb721eb6e1d978862914bfff5" + "cd625bb", + }, + { + .a = "9b8e2ba3744f0e2ccc6c64489f5e636e128fe0f78e5c4eb0" + "ef7edfa0e873f642478f131b5d6cc48cd6bb6c8ef878f5df" + "edeaa3fccfed4206ea3cb46f49ae74a9", + .b = "9cfb2f846b2252a87acdb0cb8f1edbc4c7f411d20dde77f0" + "a4e88be62b53b2fa3426f6a42eb8a937ab7280b1035ee3bd" + "7945fd0c7a17f8e5ae45947971d22425af6081491de906d5" + "003f", + .r = "bfa5e6375e267d9bb687e7ac7213831fb8cfc3229e4d9d56" + "99ff6827e2d0aed224e70dfcbac063d07abb5666e0c0af9b" + "41bd0111f5a7", + }, + { + .a = "2ebadfb0f01dcb25f167580ed3b4b9d59419cf269d32072d" + "1147e8fcdfe4b8cd10039a6c8465c4bd9ac22009fc6b8454" + "9adb4b1ab384a9dacfcb558dd3363b32b", + .b = "25e6acf6f10c62342188f297d83778472942056aa75d7e9f" + "6f807df6a48128a021d8da02ab76be79cb49cc238428e2a0" + "e588d8949ce6a9c02165ede046b0ca2888a4b370e656f936" + "e93ff", + .r = "309ff1985b7e18d34be1be59b8c973ee2bd8a9fad57e956b" + "88a202f470119f705cd4fd39066a4398a482a9865141a336" + "7a267a3f8b069", + }, + { + .a = "6cceed6943720a5a324197e2cdaedad687e7adda7c0d243c" + "fcab73a56f2f12dadb559e79ef3aff46c19c0d56c6c61d1d" + "22fd91fe2e624a3d41aec8a461a3f6ed6", + .b = "79a4c305491a52aa8f683102d1453741ccddcfad823e04ad" + "0420452aca76e439c065e7f4ed424e49d479148a6b3dd2b1" + "afd5d16bdedc4926156574651bfa621cd194054c92d2cee6" + "6929a", + .r = "7fc3b98762a487c12434b4913191da9e4990f0451817ac25" + "3297905f6217caeaf7861560edbb94aabf59f26cda12c830" + "7a236dced98da", + }, + { + .a = "63294e7f411ed0934592fd1ce56aa40af1f598c5eb3313c5" + "a7d72d0ca7fbd9fe0a58d0c47af5afa04a239cf98d6a0bfa" + "6ef0d145f8b3724a8e454e6cc620e431d82aaf229ba34760" + "8980a", + .b = "6fd3d8cdbb3230478da0959b4b373d71087dbe5424f610df" + "cd24f85d66a3d22f37da887118c1679676b9259ed5a8cd79" + "99bdc6342d98ffeedba5d89e6db6530d6", + .r = "720e83b9e76c2f544657365583ec7cb2f9dabb4bc64d088a" + "212405a4589a86264a22d4b81e77cceb3ae25a24a29e45dc" + "b6b0015062c22", + }, + { + .a = "dbd562f8706bd4ff1e3a3e3634de519231e6088576e60e55" + "1f10ec0abe40f95eac51dabbc571f9878e35b17d89cbca5a" + "327d0cca3600389249a460e444a72233", + .b = "ea1adae8f7712d0808c291c3d001201135640d4b182caf77" + "b9b7090ba51a4e990b1a7be13bf6a145f94082f0b80a77e9" + "85af920fddcad73de46572e5b50633bedd0f15dbfcd5977b" + "6ab9", + .r = "f728f23f3351350ede514d09827e93cef6e262d00f191535" + "0847175ba8e3e5ba34037e8ff5229194ec74a96101efff4b" + "059c0f1c08c1", + }, + { + .a = "4e62aa8b1c23927db9db64c95eebfef251ae385904f5798c" + "ce13acb401fe2e49ba9ee86342c080b63639a5deaedd9ccd" + "dd327677a0bba4da0cdba26fc68a6e95636cd47b691f4771" + "d656d", + .b = "4612daa4e7a3d3775dda8c03495ef240de334b3854747e51" + "982e4b4cc98559ad40e1b29b63586d71228a4e2f2df1f5bc" + "0ddc87c48f504f1d1fbb175017e817637", + .r = "5067e4b9a1c71f5d2ac2b6efa944791b160e131bf05a479d" + "d33823e918b27df3a775377d670d882016dfc62ccfcfa8ef" + "a186fb8cbabfd", + }, + { + .a = "5782ea018a2d729011580674ecd0fd6f2fc08775d370e387" + "fbb229df3b46c3159b02abf84f71c2acd4dccd7672700800" + "63c0d9508588d8ea2ad006c9d17fa8005b12c08f05be86f6" + "ca475", + .b = "6f1193e160ac77e6201a927a6ab19f46ebe565a1d972eeeb" + "d69352900a9ce5eeed923a15fe44ae410de225d3265bda50" + "f26956167cf7a5af19988bd90a2c905f1", + .r = "7435426ff00b17e724ef65e2a274a0a3cd920fba3719c06b" + "cad61d485da7236efad8b31592dfdaf04bc5f75765134d03" + "c793017085499", + }, + { + .a = "6359ee8249c069ec298cbeb0fd9840e579ad9c8d35064207" + "90b5b93a9c9b08a54e6dbe18168fed3cd8a17718f9a2ad38" + "cd45d617d86f21479b6164faafa80d2e4e0fbf77f3e07977" + "7468", + .b = "596ab00e4d9697fa70ec94c7e21ba6afde01e261e891ef58" + "081385ceb26ba02020cb58159670bd8f0cee21be73a53e6b" + "0a77b4e3ff40a92d7653653098009798", + .r = "64126ee141f2ea8ac8a19530379ca283fa4b0f6133e78086" + "6374a49b319d99755321c42dba02a1483bfb0b0b82eb83fa" + "33cf2fbcf518", + }, + { + .a = "af2ebc45afff617620644e4f1b5234fdb933ab59534411cd" + "f4f80081e5048874684a94cf4197ea6ab18137cff1b88954" + "365da4b4ba63a9509800040528fc93ff3e", + .b = "b4698b65c0b51cb00948d5d894fb2113333888a964d930f6" + "e477fb65c9f5880003ad205d69eea463e14a201cc31de4d9" + "c22e96730dfe9ef3bfeae662507787237ba7e0fca09e5a20" + "f7382e", + .r = "c52c16502901190a09a84fadf933fa99be94b142196fcc3e" + "f685f9b81a7596acb73f1a6ad014dd5afc1156181f6cda66" + "64db4cf33994ca", + }, + { + .a = "32bd7040cc6866c2a5de1a578d8585a0fbcd75545158acb7" + "cc07c092537c777f6470d2c81f2b653a856ac731a0bc8e64" + "3eec2c37dcc2ef374724d50ac0f6e19d273b1430d2f7abaf" + "ae89c5c", + .b = "36c361594992c8b0ad0b8ed3cbecf7aa5dba9f55b2064398" + "31081eecf83dd8e39e50020a919323994c2cf367e497787c" + "6d40ee718105088aa308955002745cc2dec", + .r = "379d7395a1f2680686876adc77c0f44ca50d271b80740af9" + "6d697e5c7686a07490ae10bb0af3baab942873862e7cb801" + "4b57100bdf3d3cc", + }, + { + .a = "6ab2c1f8e181aadae9772ea977fcbd6c0e769e9b03cfa1ae" + "f1836a1a96114172a589429f6fb2c73c7b395be503caf3ca" + "9f808ada6a10ef799a654de7c18a42c5b37", + .b = "5ed086dce77d1e41ab41f8c7236e1146a102aa2b9cf543d7" + "ce344b94fdf62a09796dffb761dec0a19c94881a26bd7c88" + "d7e9f2a41926aadd938cf8046646eb83889830bcfc588d41" + "f60a031", + .r = "6fad8f4134b6057fa6c577eb469d2a1f0493a4123156fbbf" + "18b4b87e9611a511cf285e68f5c8da5f1167f9ad927756a3" + "74fb81caa603bff", + }, + { + .a = "4222b1f9292feabe85a201d7546c7fde474b882c72c68aa0" + "831767fb7502f6710d4dda3682c594f76c3a9e95798f3e29" + "c4f208b84a43bffd66a9bfe6bef7cbf3f0f", + .b = "421306ddb3844b33b1316dc79bb75fd6e1fa0413fa3e97ae" + "e2416ee2be0677509caf92904e3f55ac4b59ecf2987a4963" + "ccdcce2aaf0934a574ee1214771a756b01109d1eb730506b" + "cb9f0a7", + .r = "4274b685f1621bdc8e6b09a293c06555ba1af6aa8aa28ba7" + "2d830fbb7325fcfec6d4554ab1be06a06fd85ecc7462c70e" + "e80ad341b770047", + }, + { + .a = "16b17d8beb25b38e18784fcf2126b1cf548ac5adb1716a52" + "58374dff36496e1bf518d6cfb071430669646f0a0c5b59cb" + "8156dffa4f6df5248a7451113f6dad2ed8dafdce8e2f6c3b" + "b5ad9df", + .b = "1b2b4e114eee4170d7ced5e894d921ac2550c00e62bda9eb" + "eedc48b5a5215f122a5aa75f04e5d4d83def46ac52476c48" + "a26963b7347aa71819f76516bb296340d51", + .r = "1dd468531f7021964214cecf79e9e73e868b887291607e4e" + "9af36c03ef8c472054f4250ba8951fb8b4d53c88bc5edf81" + "ff47ae2170cbf57", + }, + { + .a = "323c6f3e02cb806d581580e1388a4e20013e0501fe70c982" + "c3afc8d5ff04856103bdd8a57e47e3293e6ad69e19bfa94d" + "4ba469e65a2424960e2341ec60090e2d1e542f8d19fc3301" + "a0bade", + .b = "2f8677752eac018756090ab75170b4e5246c28cd6efcea6e" + "51ecf22a00530f5ce2015758419b23b0188785cffb278165" + "e92028c492e77f1d2a712f2df446bc99da", + .r = "386d1d78f1223150f0b22e01de5dc7a14a606d00cf504478" + "694b0fd9df55e8d944dd9ff94f23670788f1944bf5376066" + "4f324cdf52ddb6", + }, + { + .a = "24e663278b6b76e6e472090021b0c3fcf10851a94e225d97" + "0e93344f952e0d0142fd106d1f12056e821993bc7a66f773" + "f04584139442affd723b798f52b63d4a21c", + .b = "284b2b26790a09071efac26cfa788d9f3549ecf642064a6a" + "b1a1ed2c705c1d43c7c7690bb50a1538e0869915007676f9" + "43d4b39b24270275aa134de2b6be1012a2f7df067a794472" + "de278cc", + .r = "3013a01d87cae7273ae913ce8317e62f6183fd9d1b0733d7" + "fa3eb629bb945ef0eb31187ddcfbee739467271edefd898d" + "4fdbc26ef1bfb0c", + }, + { + .a = "545d432d036aff1691fefe5327b30f2178a8960b86aee56a" + "522dcd14e7fc04a277b9502373e8df7457b8edc63b1dbfa6" + "050abfeef758e84b8e7d21bd38e9693a459e30c8b80af40c" + "50f1743", + .b = "4c50a7e6879619d3cdc8283524d9677ae8b15654ed9b5d9e" + "adce653180782fca9d28f56717d9e27837b5309f8aec61cf" + "3ab8dd2ba67ef7143538a18b9b169a36e51", + .r = "57692da8c61de8e02aa9230ced68c3566014563552b9995c" + "8db15082638a254b2dd6056b71faa4547cac5768006975c4" + "ea77311f7cc96b3", + }, + { + .a = "1896655e0b2717301b8e7fc93b174d5092a46ae2b8e574d4" + "6a48ffed75df363b1f3079969aa13087eafe8d910212f48f" + "77e294ab538eff2d40708984966be46937847", + .b = "15f198b7de0ef20eb58877b470ce8b1595b082be9a8554cc" + "9936abae6774cec058b24270d77c6279342ce2d0584680de" + "c38e2b54fa2bb3b3c4fb840bd193dd3fafadc9447f1834d3" + "4d782c32d", + .r = "1b60531fa4b7912ffc8396d21dafb03a6ce484d925d5c281" + "62d3e5ed871175e9e83299164e9682a34ad55d940bc83d32" + "a49b40068e0c93fdd", + }, + { + .a = "43d8780b46c862cdb9baf5bde283ddaddde8ccb24aafd634" + "855de1fbdc6f0a2f1b4d8a83f711120e703c3aa46cf8147c" + "d6f37da644737bdc28e8fb3d31968b7a7c3af", + .b = "3f7167c05f5a6a976060da8bc4d8ea655cceae378978cf50" + "4cfaf93dacdd1efa1d17c1354a268f982d7eb8c52997b258" + "da5d91abd74b3d027830f99861707902df4e3dd60f7bd98f" + "5bd9526bb", + .r = "4a07551954c425e696fafffa8f2aefcce1e29ead1ec506c6" + "198d085d1dd31c2af5cef4b29ad65d8c5fd22fb5062182f8" + "96b3bd77f8497a6d5", + }, + { + .a = "67ddb1941fdd37163a493e3da23050851964f45d8d753e5c" + "60c84ffb32e8d6dac19418385f90b43dbf1af8b71421329c" + "ed35e1476952d18ed2094c1ba974c976bbfa5", + .b = "52c3fd899ea97862a0427c3b0030faeba715f30babd0c1e1" + "b0461ecfd4e4bb35622c51b507addd4c59e76467add7fabf" + "afb87c0f2f52128ec6a239195d67883cfd350e24fb4b7c13" + "7e1503815", + .r = "6b2b63676ff005d7250de5ff66d64c29c5a7a7e72736602d" + "c4a9b8a097c986899e1177df736e0aa7cc75845a460886ce" + "a568d0c4d0d101d5b", + }, + { + .a = "57e1552f1cae68e8412770607b7c6d67d5f6ef1f17c4000a" + "045667d35bf1d040c99b590f2b669af84f2d642679a95ba2" + "7a46bcd290ab6e1044fedc02b04eeedd3b75", + .b = "5cf62e9235bc95309dcbe49ba173500e7187bfc9be14044c" + "532e1aeacccfef483ac66e7e26564f8e2ce45bd7bdd391e7" + "52f17d3f5830b70edaea49ca72b98f2c37d2d508b644149f" + "a8fbebab", + .r = "5cfdcbe753eb651090213d2a783f08190d48c662bde9940e" + "239fec164c9a8a81c9dd1051c9b1f75c9aafd1b698ce0729" + "e7e37e76a06c2e5d", + }, + { + .a = "20ea9c5dcb3087f695b27c4f815f189fe882ea70a8ebcef1" + "ae3b97577f24ae2656f0c01bf9fd33aa22d4c112aff8092d" + "6794d3b0fdda4108aadc1a9fe9bb61fcf28d9404446ca5a0" + "09d88df49", + .b = "266088bdb989801f5b345876164751f85a8a564061dc2827" + "d9514c0b53776553b041ecd57151d9c55da2a89d3c7ebd36" + "b43d56723336d9beee5af50fd2230428e1213", + .r = "2b1cf5b2dd1d1cd04cabdf12f70f16028b22a281d653955b" + "4ea0436f92b4c913317bcb862d7380b774e385191f881383" + "a7d956a8afa4239e3", + }, + { + .a = "541e1f20337202fd80059713e6cc475dd33792c9d92ad34c" + "1773f1585df2da12dafd3f8d24816e2ad0093aa31cfcc8da" + "fb249a5e5930ab4b9f6cb9c5547a86bc953bf165f1abe376" + "14006361", + .b = "622f62ec0a012dec5507e76c7707206f4fb26f5020a0a2b6" + "371fe7aa171a09a4e60fb3174c8072910e826da3525dc6bf" + "af73356544b7623090d911d4b8991e29fe83", + .r = "62c57e0dc260c7ee0602c25df9828b47e89be38550145da4" + "5432dd9c9a7b96278d71a606c9f3645fbb3517626b8f32ab" + "d0afe435f4ecb433", + }, + { + .a = "2cd4051f179794ef9ef8862d26ef9dab6d182c0cb8f7ebf5" + "639c9d3496fefeb0aba58a39c9cd23ac10be381a767249d1" + "237d2ec1ee8c8ee11f8eb1bdc98369eb72997", + .b = "353fc536676f933bcc683cd1749f43c301f70c78c14061e1" + "96937152e2525308c58c0aeb1870c673d29dc587c10d85e5" + "a43f58ca37cd96c237bf47334f480d92d1548b001a773aef" + "7ce7bae6d", + .r = "36d086207bdb311c6c7f40ff336994320618686e0a8ce908" + "d26977e9366d3fbe9d0c7531b6fce290b1054c3ac6b94ef8" + "a20c196ef6fe052a3", + }, + { + .a = "44255a3fed2be652f9a34a4f4abe0eb311c2e57a0f85343d" + "2d097d970782ef3dd61260410f5607b495103b0989ba4109" + "6da388c5cbb64a497e249adf4d23c71489c7b", + .b = "4344b250abb87d531d7c6ec2665fefeb44623de4394fb82f" + "20b4af81c9b0f1f95a5e8024cbb26ec876dfeb740137d8e1" + "e22975a708e57a0bf009b09bb0855d871f9dc94dc4f2f05d" + "0a38cce7d", + .r = "593263ec0796447aac52c4687c2c795e17288b03a9e90eba" + "0d7264d0759409064c33461d6126c433f2928ebab6635f0b" + "b7622d036e16ec2b1", + }, + { + .a = "441a895ec6bb6311365e27a6bbeefe3cccd5319e2477ab4a" + "114f31b7075dbbbd2fcbfc52bf596b95566179f8e3ba1b3d" + "d5d9fe612a117174b171e6d7d8a9dfcbecae0e0cfb2c1290" + "a45b38e1dd1", + .b = "3508180db77ae987b951ad99f94eee1371709f6a9e5e1f54" + "e15af30d3305d1c03a859252fdbcc6616a362f44d2f9a107" + "54f38da41a8e01a65703de5bcb8ad1d99b34863", + .r = "45665350710b2ce8936b54b6de415eeed16612f11bf2613c" + "a7e8c8a4ee4e6103206e45bef2d696cdfaca8c25dc15f7ed" + "3baaed29ae81af3be71", + }, + { + .a = "54da6ed1f70897bc3cd66600ddda1608fb2455d09321da8b" + "c87ccaaf82291a66101c2e6e0169057bbad4531983194bb9" + "fe1a67eaaf08583ff718bb86a8aa3e5db3d23d540bc9a2a4" + "3fa939e0dcf", + .b = "595bbda1f517ee904529a9300cf6bb6baf27445355b55349" + "7c3e337b693b2ae8df63188698f84f1bb8e99b231f1541fe" + "7f1e55f471342543896860c3b4a6425cbedca2b", + .r = "5e3d812cc1c469dc551de91f369368b93c94b947c69afc31" + "67db9e82486c42774559e218e3ded0b730a52a42b0fd768c" + "86b1791b5aebd5f5d31", + }, + { + .a = "440f0ad9199fbb9071aafb23f0bffd90cfa77cf928940edb" + "cb952194ce19bc173eb4de9dff4b962399851fbde873aa8a" + "6e4286ca648c2a42c264b74d58c931c319af9e2", + .b = "5032c0da861e24e1004fff70b44b084acb03854d88f4e70e" + "f66639dd7d3a5cefdb421e4d660f903b2dd99f5ab4bb25ff" + "b7ecd3973c46d32557773f4c82095c7ca94edcfab23c3af2" + "afb486eba12", + .r = "50ccbbd6ba5993da82e631824c52f869753f03590b296be3" + "c5f0ddf8a2390e7646e7066418551aef8e5185cbf70dd335" + "75a05f94cd88f56b282", + }, + { + .a = "3c875709bfe10d50babf283029ebd6254860eb2ea5fa96a0" + "68fc3466e32d7a242fccf602fd6dff901041973b7b57d046" + "52cf6a8ffcf6d46316609a82fa58b1fbeabd4bc", + .b = "3d179ade5d386f2d58590c71984454bd7669fc25b059fdaa" + "42bf7e64075fc7f0204b7e90c0f9f70b727264a56a7bf1c3" + "27cbd33afbbba9ed1bd124d2fff205eb31a61b0487d28c9b" + "cab2df5390c", + .r = "40bbe8a212039b7f67dd515ffbb394c114d743aae1137f74" + "28f14e2056daa74ed90088b1fd0a4349faf168d3c01a3cbb" + "c793d521ecd159d183c", + }, + { + .a = "15e3afb34c242493b52d1dc6dbb65f7678297c34bf9f17ba" + "e3d4496f08a44ea971aeb7584ac66255d153584fd7a07e4f" + "3b5b0597d2ae476b02012299f71c46825911f10f2daf7319" + "d74e2df221b", + .b = "1468791ae811bf12455592f932b46f69a98e89ca3b333fcb" + "f287c8eb173c4971554753915de9f73719527343530eb6e5" + "f14409d8717b7088274efbbbf8891295a399beb", + .r = "1ad99426793db7942559aa005fea7d65827a4ee96d8754b4" + "bb94b0220b7bb008c7b2bb5511b5022cc5e23e99be347164" + "5205cfcc19360830a47", + }, + { + .a = "41cf8df652d0fedc98d1a4a6ad6a8549028ca5359eac99a0" + "aaa8465e92c4006b23c3bfbe55da176cdd1e1c23e8b442cd" + "e4e0b04a796836ddb3fe7105f7863c8de9888efdf198c764" + "f100f554db1", + .b = "4b441c2350d6c803ed1585f765774356132b84acc4d6e063" + "3767dd9f272080bee38af40fc0ccf1491caebd0d397056c0" + "1fa0a94cfa2c3ff15c8f26a8e2f88c2f5ce3547", + .r = "52f009be59e82fbab92297bbd7abe8a43b252958092adda9" + "c4ef32c24e08c752bee3e6ba574d2607dc1359382f29ae40" + "96f0171290295eb388b", + }, + { + .a = "6956040bbdab4b9bc0655df3a2cae92548495d3a31d53580" + "f7d24be5f7abe168f127e4d3833e814b381a6dfbdca18f8d" + "941afa3bfcdd6e61495f05cbfe67140edf361e97527d7630" + "c8ac3f07d56", + .b = "71c2d447d125d367b7c91f4cf019b6a0d7f9ae9637d4d75b" + "1eee393667904609a9e43bf618c25a1c6dd82fde20afec33" + "2507b73233987aa27bb7756ee0b6fc84d277d02", + .r = "7338a44552a4ecad8029aeef2a4c222b111dd5f256c623fd" + "11c39599d070eb64fdd1ef4db2078002ccbdffc8ab2a555c" + "8fa570796b45effd6f2", + }, + { + .a = "66007f6a13f6e7086df1d1eb53423db4310683351648aea0" + "bca894901744467996594837aeb9d1b0652948e5ec7fb5f5" + "6bef90232ab1450f41c3929c311d8ce595b5df86df8584ff" + "9dbf988846d", + .b = "602242d9a346d1ad7b3474efea6151eb28d899c695b05acf" + "626d984cc2646a8292b62037393907223c005b6035d5e80d" + "74a4a5ebbc1690e6c77c9b568281aa1b30a714d", + .r = "685bb934a3edaafe9df57649a9678283591c89e169aa2f96" + "86bc78711d252015f17bf6865f697b09be0dda12bda0fd3a" + "2c505c94aced0b7a277", + }, + { + .a = "a1c8515f72e0513de3e7a560a4f25406bd7df2e39666ddf9" + "0cd339d9ad4620e1fcb1063cc965e3b5f74ca5cb47905e0f" + "1d02c1f339e8a11b41d9f7ee44202a6974b9675b731810", + .b = "aa6a210674f66079f971d693322fb89c87df9c3746cc5b52" + "760a3d7d5f6591c96a29e22142cbcd4a3d4d2f56a44a3397" + "10436032b9b286d2506b217bbaf00bfb026c6bba10b0b847" + "f3903d68b7e082f949d0", + .r = "ae558be6e081e845c1b7332505e65eefd673020d06271289" + "98a2a3cf0d3d6457e58d0d504dba4b956d18059a9073530a" + "84f9aefc01b78ee7c5f2b930", + }, + { + .a = "63a2fc46309a37f6dee99d2027c20815e0ae0c73845585b2" + "32cb4ecdf4670fb5f00df6165eb48aa2c589a8439e4531c0" + "43521257245446c94e826722a04d60a711fd262271f9213", + .b = "5998b0bb3a3c937764cba78a0df0e9edb2b15f4233e2f594" + "ad195f1d76fe799d1ba7b98c4e983b78c1df913632096723" + "b18b796e296c1edbdc87fea7f543a1285e2cefbc4411c420" + "e512835e32f232de8767d", + .r = "75fb0f8b649d3b211427a2b659490fe7c9e45aab6a032310" + "2f36ddb69bf6431160297ef61824517550deaf40751a65bc" + "db3edf29d723bb44e83090247", + }, + { + .a = "5f37cd5f95c9d3a33b10ea4fa514894e4ffc15dfe73766e8" + "f3f7789fdbe9c998ff8020eb56bf47027a7dfdd28ba2d289" + "c8d3879d782342a9a6321d4a182657831dac8569986585a", + .b = "609a77e881ed16209a21be8c97ee2fb56a169827b53cbc86" + "c4902e4f97c7bcf903a1934aea4c8979120d1e9480f36890" + "a439f4686aa390654e074f821155b96623585c939030f1b7" + "185632ab71febf33a50fa", + .r = "69e8c95b10f176e970088059cefa975139f63098fd1572b7" + "ee198569f40de0c0f165e60b5f2041e6cc3f6561fc26325f" + "0c73759241cfcae05f5dfc986", + }, + { + .a = "286933c1c00f2b660e3fe32ef6e83860802f604833db3b71" + "d3dfb4159832ddb6b8c523b4dd97a638153601a00ef0277d" + "afcd4672ee18270248d330370e2b3680fa6d45e2589f9737" + "a1598116771404cc0f6fa", + .b = "236d98a863512a94fa2596fcd9f8208b3443fb57c21bdfe2" + "97057ce9d71060cc6d3d5cc8803ed478f08b96e1975e4cc7" + "8dcb4e51a0f815b758ac30f505da9d3bcec9bd95e58cc7e", + .r = "28da8edc8852c39e8ecd24e02e049bf949018e6cbf56da50" + "106cd851f68aa25eb010e5e07f3bc0890d5437bfae851246" + "69d2272c6c86d470c54b558f2", + }, + { + .a = "a1f7a323d50b847d125780718fba3e18dc0d27dedd4bd564" + "1a1e77d4f135ba301d9e35e0a64636e02beccd74dcfe7dbb" + "aa887e81d70cfb20cb29b7f01388cf03574bee3b662c06e1" + "729b24b3661baf9897c5", + .b = "b69a7319b587f4ddfbae74df4f9150d294378dcf72daad7a" + "1457f22a0d3d06f440b336e5235d01ad0d5701fb89bcd32d" + "91dc6619453ff97efec1fad9327b75d611d2f5d6e92b21", + .r = "bfbc64ece94c37370bfe82d8e6a0251d01aa25ca8a24eb7a" + "c2a46436bfb1bed25bb7461e33dbca024b5630b642566abb" + "9e9885e376ac5e2918370fbf", + }, + { + .a = "580c74733e7398fc4f93a09607019a42520d56a192197917" + "461fb30901f0d1cc51e8ad0fc811087193d99df741275886" + "5f46e78373f104531a3847bf474b28f56a5676c958768394" + "54634afe2973cc9ffbc3b", + .b = "4f616036bea3ee473e1d48729f0d8d0a1f6eff21ad44737a" + "9050b6e974fe2d83593025c34f69e95285631e3e18b50962" + "f85f2966a77975cfc0850bc2859fa595f563def7e253495", + .r = "5c5adfa84bfefd45bd3de3e20e061559bae05d2abd5fe44f" + "cc33068bf024f905f4898bef8fe95cb454d42a0bae6d7113" + "ef5cee3dcdc6918271af159ef", + }, + { + .a = "698290f68e55de40eebbeffdb5e85ee1c90b9b26bfde16b7" + "e57f6d49372d28b452b740cc0151ad03f4a4cdc620d4ecc6" + "ca4801532302aa6ad15e95f03ee47b364c51025560b3e4e", + .b = "7c154bd23d9802aaacb972cec50ee01e0cd238d99d52acdf" + "6e423fb2d25a8d43d48c190a98722bd1dc9ed362572552be" + "849525a75808ed1858301fde5ede16966aaee47b96840725" + "f0959af32aa06e9456b82", + .r = "7f9b685607df0eb284c13f737512dc08fc285924763cca08" + "010271ac23a1e3beaa6bbe99d4b0123172315084fcf38bb8" + "05d095248901f3b0aac02d4c2", + }, + { + .a = "2d0508ff787ed77aae3eec5f3b653c16a61e5c2131484a6a" + "76c8f5c55a3fb8892cc944746d88d6df8a173934a3b08e33" + "ab661013ea4cac984e7702c480121cc0a61e9a84b8cb790", + .b = "2d0d2615faa6a3270be7838e2113f003257db1301c1733b1" + "c0e7b6ecbfecd7df5025aca3ff20424029a0be85400b17a0" + "10e3d3bb2d68b869b8e3ca35e2ca578707f41ef94d1cd5f5" + "6576cc6585ed9e98f3d30", + .r = "31f493348ec0de8a0b395765ec9e0a2c53fcfeb860b7f491" + "5b97d5501a7abf7a231d8b51b0a14d403a0c33614c2bf64e" + "871540ffbed0a5c71228c9af0", + }, + { + .a = "63358d19c542aeb26102faa596947f11a4b855390eca13a0" + "5de52db574a62508f6f6ceccc465d354129670206e28ed00" + "233fbcdfcc39d33d381dd2aa085d1213b543264757e01f43" + "5", + .b = "5240f1b49d6adb2bd9e56f356ff3be942989b83a35fa88cb" + "4b1807725401d82353e90e44dcefb7d485e7c0e0e8761ddc" + "7fd082754b0c8ecb157f26efb878bf39db5afeee008bac7d" + "c04512e3d5cb1aa85edaa87", + .r = "6d728eb98af7b75867fe8171099636251252e3aebdde0ab3" + "8e61da18162d7d3f9424cd4cf5952b6fca88ea01b52118ed" + "415123848a78f861a9c5ee89675", + }, + { + .a = "4b1a96b626c403e74398c96f775cdf543313d7e5c30f3200" + "da045ddef99606fb3e06a0cf102c315bbe544684bc97e0af" + "25c63e95e96cf79d488ff0c09d3bf476871bd2e16193193b" + "cea695c9f7b5506ca32c59b", + .b = "53b13941fcaa37b2c6488181b60a22f77ff393613bd75ebf" + "9fd887e7f3a45c40b081d164f9cd694c96ef585623a75b94" + "4f9852d74b707d074d16ad35913035ecd50dbdce84def4c1" + "9", + .r = "5ac217cda9a3e134d89a18453518a3e305b32161ff87275a" + "c038066f3bdfc755cd27b5096fd0b467ad050f2fc0b621cc" + "e0a5ba13cc43066bdfcebcafee3", + }, + { + .a = "2e9c3add5fbc37e68c6ecb0d69893a6230c96097d703c6f6" + "44ac81f78853e7fe1c153e31c332515363e1fc3d116103b2" + "1edabf3f9267a2a8b859256acbdb5001bc81bec6e75817d6" + "a", + .b = "28ab95367724b0d6b25899eddf97bff39af736f56ec36b58" + "8b2c79d15d0f7b83e6c002c8ab93319a004752b9ae65edbb" + "14ec62070a24b1d7c982da5e8f278e4ab4f5ee794777a0ba" + "d3251551c42e9dec1613d96", + .r = "35bae327800c8ab846e8a3ff9e2065d49843562e1053b305" + "419c722fdfc60facd8b96b361497ea6208c1e113733f94e3" + "dfade4850b027c4e29361acf1fe", + }, + { + .a = "28d49ba94cec96bcd7c4c4b648fa02fc964253c91b3f8055" + "9bd301eb085239e0bb81d27a0930f67d31da8e0800fe00c3" + "110206ae5510c198c7ca8455e81cbbfe2da668a94275b84a" + "9a7622cae01b9218fd38665", + .b = "25fa6fb38d020d435dab152bc5f17d9ce691fe72d6c02047" + "464d2812a51728a5b021a1dccb8699c18b2a96ae7ba7905f" + "c03926debba4c1832cec97b05ecd3d1810c7249d15a82dbc" + "d", + .r = "2b4f6fe0b050b6b25d1c45cc405c1b826fae754bdf2ebdfa" + "67796176e627df6ba640e8a1b423af7bb4b398b0a90a6dbc" + "7188f88814fcab190921a455087", + }, + { + .a = "211a642e3def54b03888b99bbd5ba647232038dc9a570283" + "1018dfe3754088d6698ef224d63545c0605abf884e979f6d" + "45135895794fccae82d2cd3701059f621d9f7dad15e1f226" + "d6730f64b83b88214ae4b79", + .b = "2224220d00b674d4c20d71b7c3f3eb4c0477cb760add9e1d" + "9a142f7fbbfa6f15103365902c5b9f71cddef2f7e73a7ba3" + "6c4cf6febca1e8164c4244af2def72c61c73b7ee84d2668e" + "3", + .r = "280c8c13bfe857fa3522cbb70d5c04f0d998a1e8847dda48" + "f7de2a9387a2a2c25b731e5f4750e8337841b897c73618ac" + "e8869a75d1394fdfea8e773f2f9", + }, + { + .a = "4994b58f2a35736e189646223fe59b96081e41138a136f81" + "802d7260c251e9ef469f328dd791df126f4181a848ad08f5" + "9b0b6f6714b77387039be2e24b0a45f8b870db8a32e572e5" + "6", + .b = "53dbd859b1980b52a856a182bcad446ba31e9e38c8f38239" + "9787ade90ce668230fc79d8c9ee37ac58b4ec70d09b2d96a" + "7dd434fe13950da2d5d89260fcde8437da73896f4e3edc91" + "9e7eaf24e68fb83cb3f13a6", + .r = "5caf1894f182dbc7729b357e28a8485603bc4d4d73ca64e6" + "9dcdbb5ea37ab9534c5caed7896669fe36624011b29bc26c" + "e7fa14520e4fe6b9bf49c581b8e", + }, + { + .a = "4e9d6310d7f9107cd13932e8fd8d123529e7f1c1be039c77" + "7cebbc80fa688158c55fff8cdb7bdaaa605c234aff554b0a" + "76a93eb7aa6133a24e462260d6f407280f4e6b42978bc2b7" + "f99ee90a835fc4abaabe12a", + .b = "566140ad10242b4c8661e010188b30f6bb119f13d91ba8d7" + "80b3d7027551d50d4dad1bd8a2a941f016f9949e67f63675" + "33ccf7badf855598b792c69c18f6e78dee8d310d42716dcb" + "a", + .r = "635ebf35796abc2d75157ca5244cef21dd30f3de6d6a0b09" + "f540e25d28a4c24e8cbe0e8041015f818da03ab383ab48a3" + "f8bdd4cc724bbf01c05a076300a", + }, + { + .a = "3d5bbcf58d4674d72427fd547b4c3a04363549248d086c00" + "a6d7bbd4bcbde6d709db692514346c347096000f3819937c" + "29a251dd0f4709ea1823566ae73218ee7134bfb2dc4f4d71" + "6", + .b = "384b1ee7d2f374c44125d327983f5616a1d3a980b0451f1b" + "53bc5297b5a9110b104b7785b3ae44efc4bc1f188dec1081" + "3ae93366f10e204e9aefa65923fc08baea8c8d8c9ec6dd16" + "c25ffe541b0666ad1983832", + .r = "49b1f9b8a8be2063c6937252ad20c082a2baeffcf4495d51" + "875f49203a3c4e87df4e8f386d6ffea8f247a261be9d453d" + "be646ec243f44f3a86074a80b92", + }, + { + .a = "2f4f1d590e2344a8304c0da12ed20d320027447352a6c91f" + "be0910aa7b22176a52de2a743ee00c970af26d4d6b17ee65" + "b5733a6762c4a910a90e34b223852f1570217677e5391f3e" + "450", + .b = "3a9055f97eb776d220bda9012bb25b2fb333d692b4a64df8" + "465e2b4c4e92937e0c2da20df98aef923f2ddf775e89392d" + "626759563dba5c9b9c0bd4e72c43840873322884687d4f82" + "c17e78e8f23047c7e486436b0", + .r = "3eb0196e0434c7973e4184ed035a3dfb7b22537dffb54e7f" + "318d399e34318c098240e2b12490cc36587630abe98683d0" + "b525f6000cd29faf2311d047d7ff0", + }, + { + .a = "362e74a668ad43cc6a7b5205fcd03142a012aef0145b20a0" + "13e57019ecfc0d8dd82320991fb55114ea5a355c69220410" + "3a5ea3c17763bd095098e16c16a778b37e312bcd0542dad9" + "f944c97cabea1e4c4b8253a67", + .b = "3349ab6445ba4fbf835b4acb058afcef4c4cec07fea01935" + "dd99708e29f6929c63c7403cdd665b055f066e7a32d27cb9" + "45af3db650525bbe6cce328e48c7df688fc671f9dec68e8b" + "633", + .r = "4142e2681e3d2a70ba3651a484d2526af26d8e9945ed1ae2" + "2a6a6edb8ef6efd3623b3fb972e992ff29c8b0ed34c69259" + "c8a3973f06b667306ed2fadd6825f", + }, + { + .a = "6259d0352e249d1288eb6321e88fa4c2ff6372e6bdcd744e" + "75175953185e3d04b315c6cdea3e443bc0d07236b2b545d6" + "c02740fb1055d6cb8dcedd7fd603ef0a58204de4f717c737" + "8d71ffd215ae50c226585ef9d", + .b = "6451bf96dfda1c3624bc3face722a88fe80cdd859c9fa6bf" + "5d7aaf8017ddf75c53e1542c4c18b436abd6585bcdc20c91" + "34a227cd3d758c2d715be9762d2b310d8e302ba7802ac6bb" + "2d9", + .r = "6edc27a1e26484474f1b8989e30fb334c40fef25b5b0388b" + "8984d36d7376f0ca903572b6bbaa658c4fcb06bdef18b8bf" + "231344e15d656b79cb9af46a2637d", + }, + { + .a = "29c1dd0b414e89c92df099bcc0368148bd9da74cba13ab75" + "69926f43c155bb73c224eff597c168da1a3482c1eb5fdacb" + "3525efe8cd760e75ae4f82a9927744711ad4aedd9678207a" + "5c3", + .b = "2725f9ce0e76a58de38b514540a785b5f81b6b477cadc764" + "e451d4cfc672ffe8b45708674d8677355519b4fac1b2e205" + "2da08bb71e0302fb9b0539e5a089ec820934a7fab8a67f1a" + "cdfd284cb4d1a47a0fb6d323d", + .r = "2a112329b5a954fabcd561681a5c706baff6c5bc63409d5e" + "75f92905b8556dd9a413c066d06de375e0673881e03d2de5" + "ba0ef77162eb00b6ff38b3a3d93b3", + }, + { + .a = "6cbbcc9a66966508df9163db9047397c268dca3bb912c7d0" + "0d6f648c1d7d1e17bb401428f1f35e228ddf31a1eeafa6a9" + "ad423d8a568cf53b8295f18445d5659bdca6546b3bf486d0" + "742", + .b = "6d1caee6688280ba580c2be1f6a05e46e8adbcde74f0eb20" + "415b7e7a1d78392adb45a9568bd2d75154fed048aa63223c" + "f07dbe02b17e80ef1d849e2deb22355f564e950640dc123b" + "eca95514b77db9569a1fb8742", + .r = "7b73d174ad87c7f6929c0ff8cfdd46216ca8b52d9af14965" + "372989b353d9ece7225447637beebf9a3b4dc5c55fedb01c" + "462c9869cffda467450d5bfaa6e02", + }, + { + .a = "2ffb47c34f03a353a71fcd0407c23a0907fd8f9699e6a79d" + "4c498c7b7c21635da7dd9c6bb1b6c2ca7a1a9a9f8cccad9f" + "df7e9692298db418bdce2d0a0b2eef85b0a8bf2e669443e1" + "977", + .b = "3167566cc4a6b4394bbfa428b59bfbd481c89f0297510a00" + "06f8525bb254618d0f9fb5a7d7b6896118f084ee67e904eb" + "7e058353ccc8284802dc4e4be387aa9e51fc4f037b800de9" + "a134c5d3718d8b357cecee8f7", + .r = "34a0e93f4d59795393a404dfc5be097ef284c02b3f431e03" + "2850144f7b9f182a1968f0419b62897dfd68bc556da82d7d" + "4bee27efa7441a57f10ad3a969b7d", + }, + { + .a = "2b5b70d4b8acaa1efd052d536b2011fd6f9e4537cf137ead" + "5ea8e5a9290e1eeb798184d6a03ded2c300b1a2888fa0953" + "31c19b46ab58c131831664120d5ecdb508617499b43d2e84" + "48b239e907af8310e551fc9ca", + .b = "2e28a7ae1bb29b3c58a9958f4861eaff3ed846ac0fa1a97e" + "c413e437c8da9968de78b2c3d7e8ebedf359de341562f243" + "c4c4b2307af6f8b8783d1ea71ae86aab49b2da6c95e58aee" + "80e", + .r = "2f731e7066df73cdfafff2f0c05435593fd49aa6c57ad125" + "1927ceabf03a4a19f97102ac81607b8448d74ea340017b4f" + "e1b2b8a3428066cc7a9163fc774e2", + }, + { + .a = "1f502837bbe73b0fea089bba9cc9951db97ce193168acb55" + "c9d10465524feb504e1a07b0b084e1b43e8a638cf3072b70" + "4d134b6f3922918979651ce87aadb83d84de661569ffb63d" + "44ce00e1b0b0d2e95a917fde4", + .b = "2023c2547a2c3c4344046ef7fca206ddaf19f348747d41ff" + "7631592d81059726324e90a8bff168f5ee920f6a39dbcfe0" + "52efe5507a45ab92134124da25f3e13c7addd6ff6c18c6d7" + "a54", + .r = "286972b401a798a475640cdf1f12a08ef72faa75eb2b9560" + "db47d7c9c6ef3a7a509bf1abde076f599cee0fefc031c043" + "115427e8c030205f469879ec18ffc", + }, + { + .a = "2601371a98307e3e57ff5dce30264ff73dc3597a1c10d06e" + "7024e3a553455c77470eef23ea143a5baf1980439603d854" + "c854e0c6ab98dc517da6e52cbbde9821ab4f2669ca5cdda9" + "7c64", + .b = "293f63a8d23b4a57972134d1fd5808e7cae2e69756ad8fcc" + "c5582950e50d39f860f1c68805c07bd56be1bb3bf42c3323" + "c78547a51f5e69bd52676c0d92d7e595d1ef6fd9bf0895ac" + "588f18ef54b6befc24a7ab4014", + .r = "29986146c05bb389e166d704f15fe12df8dc9797512c5863" + "6c2a88c32dc781a1d8b2e494bf69a8fbfce90f29a7159cc6" + "fc5bddc6e867d456c8d9fdfcf3ad54", + }, + { + .a = "60d0b1fee7def86c82f63bd34fef4daf7342dc1b7a957874" + "bb74a7c2b468418a85a05bb320b87d1608ba5462d1655cde" + "b21131889a22f6f5a8bc80780af967f366c94fbb19fa2db1" + "020ee", + .b = "6d006a52efe8d29184eae98fb77a073be1410cbd17149372" + "a8a58298cf94c39062914d7d9696b20b52d256639f0c1d5c" + "bfdcd3fb61c21c2dcdac746b927ddc8cf8ff4f4c40bfeeb3" + "b797e5440aa1040781859b9cf22", + .r = "7cab7c05cbbd2434ada90d92153bcb0c2307d9cf9e97b183" + "925d0993cf15cd10c4a559f22e7a37569fdf2cbaf06a664e" + "295cb75ddceeb76aba71f5c6186c36e", + }, + { + .a = "6b65db8f217601560b67966fff62a85326a355b04362373c" + "b75b61bf72df96ccf564e776a9e260df527619eea83e2134" + "2a4aa260e21267633a335d5f1e423d57382715ed19757c55" + "6b8a6", + .b = "6de2dc6f6d0ee1e9e51bc8f32191af47b123bc6b91fdaa82" + "4b541bfbadf38d5f0f24498378aa1e1a8c8c2f58acda2ae7" + "29d85b2760326806b9075293908cee6e7a6584fb9a48cf61" + "30645512e1ee3782fdcd5b44402", + .r = "7686fcf9c12c8d09c554b47747cb85068829caa4cadf13f2" + "a6e51b1beebded15f29c3b5811c7a520d2789c8e38557d96" + "a942f083aed301fed8d55380993f01a", + }, + { + .a = "47eceb53ea1c6f9bd9710e5b441d7b8aae96074ee598100b" + "5fe1a6d1da97a34175009b0b70403a1bad9ced6a669c8989" + "43ecb37b7f1fa9b2f6961f8ba948e26b9b6348f135aad8df" + "49e24613b1d2564d0955c6d9b57", + .b = "36a85b25a3519226e79420fa52ce09ab7bc251334b47a1b2" + "b5ba8e6c57e95440f4c29ea43944b0f7021c2997a8d9c0bd" + "ee01976d43e3b17c255adb3b2ce39cbe070190e995dda8ae" + "33d17", + .r = "482139d04fb1265200bb6dac1053e701e2f380deadf3d879" + "fdb290ca71dc1be05acadc1cd92c859f5f102b2497e32821" + "4a8ade526ad3bd6f75b01dbb5221cbf", + }, + { + .a = "4e776b04968be7d5b36f76f639c69655c3ae7e6dc631dee2" + "2953a6b0ba71641ea0737f0d20d231d897efb5d6c6611607" + "d8ac4c2603c414ce2c050d7c5af793645114c239ae3e82b1" + "703314f365abfd17ebe304e3e02", + .b = "40dcfedd9e92687615ca5ebae237e2c6518e81c2bcfe5a16" + "1dc4040e8ca08da86e8b13a2c7e81830ba4194bf1da4ade2" + "6574c799c59334978b1ea0b4fcd24835b78436b20a288f7e" + "3a662", + .r = "539efa234b6ec2b3522f56fc3458eddc1f824c7ed5e69b61" + "ffef8dd721b9047b8e84dbba68c61496026b7b3225b52a37" + "7649853bf31996fe08cc1d5cc60df3e", + }, + { + .a = "6248530af91ff8a2512105605308371dd35ad4cbab53268d" + "f60a98f71b069570cea5f0d1627814906d78bcb2f0311d83" + "2da3747d865670c808d6e5561f9c57629a2a2fd0f97f9fe3" + "ef7b8", + .b = "68d82bcea9af58edf598014eb89d362ab60796fb6cebcdb7" + "c1f362791026b855d2d53ff21e200c5a6f09f8f5988b81f5" + "e5ac6eeaff8d40645c2610357cb17d7aa92b841bc0f8a62a" + "88796f971a90df96c9fd8ed9568", + .r = "71df33a8cd2b40bcc1cd88ab619f9be7ba598ee307e882d7" + "e3c3fe21006207d4027413375acde14895e4d6f531864398" + "df0700e19199e152c44a32312e1ada8", + }, + { + .a = "48a027241005fad8ad81dd613ec10404f19355fa0d70f838" + "df119556204fe6e37d2ca5691d0f6d1a46d2f60448960619" + "c542269e1cb159a8154976b01b7156ddb34644f94abfedd1" + "ecc90ce5baee6208587a79ef864", + .b = "5e06838a5e561438cecc8b5050e7b76f2c0a709ad75bbef4" + "db8a6766e7d08f4147acd0eb24f838274731070dcbdb3fae" + "f6806e06a765d32cb0ad4b9bcf938dd420e99a0c1850959e" + "068ec", + .r = "5ef23537d261c6701373d1b59b311b8d74aaab868c28c12f" + "c40c742d32f510516383527ba995526ca4ae14b1f0af8ec2" + "2f03db896320319fb5fd6f9aaad223c", + }, + { + .a = "24f02c53b3ceba7449b66b5b3fec9b0301c1ec94241f1a49" + "d6054987e8b15323f3e191b7a3bc2f58d3e5918fbfa2d6b0" + "a91a8b91f71070e42594fc4e9cb1ccbccadd0d39dd66ff6d" + "b67d7a5a0a4df91b5472bc00c2c", + .b = "2203162a0ac7281aa4801c56bd345ee940a3c56e75786cc6" + "94495214fb92e6ed32ebecb645c832f2f9414425e14f875e" + "d25d9b90512d391bda492fba97acd268fc81eb68f6b3288f" + "b3cec", + .r = "269cefdbbc38de2dfe75b1556db7819facd5afff70fe141b" + "0320907a0542e85582bcf724cd74a31dcca1f1e45158c048" + "7d15ff63cfaa19735b3fe2b794cb314", + }, + { + .a = "311daa474d338d72eba858a27a869ac50e27c00a98336ed0" + "79dc55a141ba10d4d2df9cce57c37fb623ab1acc3a908a3d" + "63bea88f2c88e9ea6291a03a983638d061ac4083990a489a" + "e8358314f98aa", + .b = "2f2dc2784c526989ce90674a073b56e1c698b72f34e86014" + "f6a5bf3ff45373192ba3ecd94b643072bbc581795d5ebfd7" + "73f685dc72cf17b744c3f4b1c183a4c9b15ad83cc835e27c" + "0253e12637e50519f4d936ae525eb84aaee1e", + .r = "359c38503bbc71801a6d09d4659fa3aee3eb9ba08aeae383" + "f283a91a563b27c075cd0b75a9eefe69ac1858f744cb0bdd" + "1275222460356f837598f3fc6db51b1b6bd56", + }, + { + .a = "4fc542ebb5dd54c2f75c4767b4693b59e46a7cddd3b1c034" + "92bd7c1ce9b99903189112669a122888ddfeba2abc2c5d84" + "0f6e6b3e652a3863265b618034cff081c55f0848082873fe" + "0860d6c458f32a5d090a56ceefc26d2f68c51", + .b = "4927608f0f371e47def5bc8602aeee09b98d8ffcc22332cc" + "755714695efff915eef1edc8f852cf1db7ad046e235d32d3" + "d5e0905e7a56d1cca7fe5996b10b65e77dcdd9c10a9a9f92" + "9ef6a40e1f899", + .r = "5c65d455c60362ee4771fa967eb6756a2c332262a0fb6edf" + "d5853b4d0422139aebbf60a87abcb1800b711dd6d3552a15" + "f657ef0f3d052a29a86c91feb98fc84c63e9f", + }, + { + .a = "420f9b7bc5385ff84114032b2fb8b6312a216fd86ea9426b" + "6b5ba622405b6bca3d38d41cc9892744d687e61bc7aa96ed" + "44cdd5f62e8f2ce900bb7bff4f3e3a3c40d19e47d7430c4f" + "b259d41806a8c", + .b = "45e49fd63db64eff1699c8c4cb518a4ddb640a4687589635" + "f9f03bae7af06e1ab608a230be3e536e7ecc236af9faa31a" + "b1bd91103b4c382144bd0c8956b32a57bc7d9cdbe996d305" + "646dae29d1c1358eff8b509f8b9d80108e2fc", + .r = "50ce5c547d5bead574e0e816d5165d55d07b9a30f9ff64e4" + "2e42333e3afc89deaef1b2f493b63877fdb17a37a6f5fec6" + "ae797d43d5ea9090b09f5bfd1ec2fe4fea8ec", + }, + { + .a = "44b8197d0642e796cd53c6bede2289a4b812c4a1b10b645e" + "819e8d079c41f6c14404f7565e2cf057a097395ecd789317" + "fdce049d6e19a4e4897df8c9af394bfadd61e2fd56b8cb34" + "04e1cbe933a63", + .b = "40e078cf89ac3fb2c4810cae1b443b669f7c5166f7537fb2" + "223ff70700df746f8d618cb9a455d5875a56e73b600ecb97" + "212611f42b255753048c6a6ef47ba91702b7709d5e72cfb8" + "b045ed808916937f1b8dc634cecc95b94812b", + .r = "4eed24653e77a9eca3fe2c1b63c3df278c0f4c0280985957" + "d6b004f66dcf6e39a9d74947d2af6ccffba2d7e3899b0076" + "ac2452b8e0270cbdfcf0649cf43a7d40b1975", + }, + { + .a = "76080bd59c509c12905beaadf568f83e5406fabaf03de198" + "0da2dbc4f7313d7d1fce50bab61e959611213fa50a348842" + "e98866853219b1aec55fecb4437418d218a9e159faa081da" + "d55340f6f4007", + .b = "653a2d3e6cd9fe2a6682652fe58df01102ea6afd799ef20b" + "5e59eb9b258fc48397f33f796a2e8d5708cd1f2f1bb78e80" + "91343bdcd8df1cd53b04b451d131933031b8670f57ef7e6c" + "79cd965edd09286e9114030f23cecb2802b03", + .r = "7625e3b21f93cac17b64759bbd6374c5b8f1794d42eb2140" + "169bcbff6f30c26727704a63f36c0af124f7c072337bd3eb" + "c1efe0deff13f498f7d52bdfd49e7d429c479", + }, + { + .a = "2165efdf206b9f3d284b1649b883fc4ebe19dd2eded07226" + "1ff33f63c76f0462fdf33151defc54c504fcc045ba6f7d8e" + "9c78e2ca866588e3260d831cb0a76f9574bb9c38b68f9f5a" + "7a8635ab69816cd357b8e9fe2a5e44aa0af72", + .b = "26990c66e29b1fc2fa5a27bf7027255c2a9269dc8564dc31" + "0e0b1897ec76be18a36c8ff535107a71d401048286d881b1" + "457e952f083ba5b6eaf21ba928523d39e7b5add8b92460cf" + "588fba4b641b2", + .r = "26f01c12ab3c84a7fd95926bbba5947df3f3a793c7bcb4d3" + "561546eb89e5204de6cf1cffd37a791bd0bc257beb0d4aad" + "2dc95704d0bbb53db71767911605798c464fa", + }, + { + .a = "4cd1da71ab1b7d0f0d2878d3d9afd4a65503f44ef1a5bb96" + "c672eee44baf3ba6dafb576338cdc58ce53dcef44adb96a6" + "916db259bbd6898e570b0cde7c104eb75bafec51d3afffb3" + "028b761e2ea3bbffc27446702564d43cac3e", + .b = "59ee8b7e46d672cba41db23f9a553be294b9576ae9eed5f7" + "ef2219814e85d92374def56b34a26840f79e475227e68e52" + "e0cb9c1d4028a5c4aba40560bc60cedc9f74f0bd9733077a" + "c51c2d9b5c26", + .r = "6051ff998a975b8d4afd44d3ff5991ea396ec2404262d25d" + "0bcbf143d4abf8e2e43a758dca2f8bf63e689429cedab262" + "1c82d299eb665aae5cffcf49887cb8ccc47a", + }, + { + .a = "3278327513e6660bf43bdd9c2f0503d1db14d1d011b20d15" + "035249dc68f402f2439f86e9f088299d6b4d72127f6710a3" + "5867445a93421a509087dbaea6cd8cdefb800116be932f54" + "838bddf1aef01", + .b = "3261ecbf9169630196e0b0edcc37c13503bbd96689be7a8c" + "fad898fdb62ba588291aeaf08c010c81ed36873d0b489037" + "1005bf531376dbdf91b8fa0a00519326103a2d231c33fe26" + "561bbbdb2d5e8cc8319fd772cea67d866fc3b", + .r = "421d0cd7cf2e36f148cab008dbe8dd131425d2e57c0c8dab" + "49446b570494e8f73508dcba47e2fd04ca795a1be21c756e" + "2eb72fcaef768ff7677b017e3bcce7af48a5f", + }, + { + .a = "3112ae572ed5c2bf9efb02d11203769de237edd54a7daeef" + "99a79f002eaf11c5f83ae6915b9b3903e7a1207d481900b1" + "cf7ef3e8bb0455a99d9ff56e2d44fe34a1b740f128aeaec5" + "7cda32fe1949c2459b0d0d8ab17886332129dfd", + .b = "2a07dae423f1f9dd41d69fc5aff306e5bd3553f08d2d088d" + "4bac224caa1c0f00525b4b7661d611cbb2a121139177a2f2" + "97ea52e7bcb4bd1670ec031da4e641b2d73dc25b80e79f4d" + "7ddd94ba401dbb5", + .r = "31da054252aff10a4cc955cacafd6a64a8a03e575c850b92" + "e7fb4eb591a887c424d59d77cfb9e7669ad27407f0d5ae53" + "5c097e281aa88744bcb5495f7614dee4f008169", + }, + { + .a = "5a99840534ed75cf3c48250eb21477027251fee776c4513f" + "162ab48f0fba91297c86e9181c55410dda0d2b9a9a88eb05" + "b1de88d5c0cebd9de8c30534c45e7a52c31b784d697b26b4" + "3d9ce287597559b", + .b = "5d00668b79b842c749fc97f756bfd23c4d93e32b1e45f33c" + "03a75ba6856e557ea44b07e6d5614833d7432304bd8a2e5a" + "d0669a9653550ce3d8fe1720c41aa5c8ef1ba841c3dec653" + "d7e627eb6f73e00d753540d8a3a716e437896ab", + .r = "76408d57c8d9ed78d6719c18ac1e5ceadbf9e440482b03a2" + "84ddcdbc2409f8c358fd1a68710632141ad8a53b6a56df02" + "ec6f344d7a329acb7183d42aa5f4908a15b03b9", + }, + { + .a = "1fff5661c3409cc5bb806df271119041576bf30437f579d3" + "febe68040124b4a8a80470c99831b91936544c540f59d1b0" + "f185d1ceb609219c05a922f30be429c30719c0bd8c332020" + "3bdb54f0da90f5cab3c2a90a341097369cd3fe3", + .b = "209b21fda82c9e7b5a9fce721e69e740a6aaed5ab49b6404" + "0ef4ef69e3b8604cc01d73c5274d5400890666a90e30a969" + "0600793f66e12ce64a63b5f330289469ba1787ddf90601ca" + "5783beb15663d4f", + .r = "20adb144f68ca15bf1b2c53e08928d98fafc2bc50a78ebd2" + "527b5311e76fc872b36b9e2b67fb3432e98b8dd02a1fab5a" + "36cf09a6c20e343ceadd377b1bc466c63439671", + }, + { + .a = "342ba5b58ce8c7bbd2e8e886bd9ded881c8974fa8ff330d5" + "370cedb0a15643f92441c822fd4ec520de49506b4a8fe3ee" + "a95e405acbf5e09421fe79e0b6808d98ea42433cc7835dbb" + "15d4a4b5813e851696d895cc37321edc016f1c4", + .b = "3db942a5261eb2554d8c07f49c9b4f63d7836374c70e1728" + "3e698093c3b35f7b8551a1d8398937e121d9072049dcf8e7" + "0ba8b689350bbff993da177cce0d98eb7561da786618aa01" + "f92d5399af1af3c", + .r = "439f3e885a5a4174c79b5f267480d8975e689bdce44724b4" + "fc035b5988e881119529a00aef3a25a46a7a8d3089b91651" + "7aded47b31ceec49fc12421e03b713436055f64", + }, + { + .a = "371e2bf2000f60628f208640c701ea4171d01828172d0c30" + "cde6c73e7751285ce32d3c7f4e3ec6898412ebb726dcc80f" + "687ca47b2e9d7a1767a6bd51c924e5a1ea5ad29b2cddec59" + "c832ab32ddae4b70a7811dd1c7800d8878ebc3d", + .b = "428146e53ba9e513544ec840520e6a3bcea1a34f598b5890" + "32302576e99cd54a8467b43a5cadde2562021b8717a730f5" + "cc7c450d64d1bb070020a65b2b9bcc9ef4dc3358cd6c6397" + "3b3662b9ad977cd", + .r = "45e7a46b06c582473292b42270e5d11cf5a4816cda22381e" + "d5adf05d8f071109f3d0aafd89da4fb012df63fb0bddf518" + "0e33d0d2d4b0f1a3ac2750c2219088e80e6fb95", + }, + { + .a = "174624f63c7f56165bd918816c6f9928e4a559e8ba011a9c" + "a3c2b3e54939622e8b54b92db303745a6e89f014f216ad7e" + "dcc6eab8c1178d1532831fb5c004a37064916b91cfa39b9e" + "5bc232b62bf369", + .b = "1902db596f7070d5dc3df09f805f3008fb680fd8eb572775" + "d2f562b4a37f6cf500e67d5d680bff68cf0aa456269c99e5" + "92a10b713eb3a2d160f2fc3ad1b66a99e60c441671ef7afc" + "fd05380181525eb53b9a86043d4698b2a65f6d", + .r = "1983b5ae26a2caf8c8e5f67ad020fbb72a97bc8c9a66c070" + "b76c857b84fa7679ac539b8478a937d0564d408f643659ca" + "5b6e3041eca6c166cd4dfe59acabd1304f2fc9", + }, + { + .a = "166ac1610f2feb02a26390da221b50c826931c98e94aa393" + "99415c85237f730e65c9c8d0b50043e96e62249e1fb39885" + "f4ab8cf2a9b77c1c8cfb95f501052da8e80450f0988967fb" + "4df550b692127ea82e10d168d3cb3715595a014", + .b = "19488565e24ac7c11eeaf77144b3d95508203e931eb9b7e8" + "0639b92f0ff337fff07ed97b4722b7f8814d071c5fa09260" + "7453069aa9708c431cc4bc2209ae30db76db8f248c5a4592" + "76f2438d9a2de0c", + .r = "1ac1ea1783caf51bf4ab0f40db6810354a0fa44e69770677" + "bf04602b02b519f64fbb150019cde0254bacfa365553afa2" + "1e1012fe4b5b4596fff33c84ff84cb9d4c047cc", + }, + { + .a = "5b75b6143a1c6cbcac489957ac2e43ceb1eaf389d6f40285" + "b167f0d6f01ef6dc680c42aa7f4b15c2b970b519cc2a748c" + "7d495d7dca200144f7b35490710d90f589c95bae6e2450b9" + "96d13d9cc1d1dac", + .b = "5e9a81924c38ae2f348d6b8d72fe1efdd831a0244801108b" + "1f9c37218a167bbcd699ad7709a3a4a6fadd10a2977161f0" + "2f4097c4614c904ab0a9cbf6b212505995cd2c369b4494b0" + "4e5ba0367b9881ccfa59645b6abeca953699734", + .r = "69d18f3862bc74145c45a988b81cf48e2cc03bfe96c34f9b" + "981012b15fd615c51d585a913340688db34ed8d52f4c52ca" + "945d58910fb63e927ca8058d88725ef986e0ec4", + }, + { + .a = "674701bcb8b7d1afcdee9861b2523a119593959acd7d16aa" + "ef2ad3509ec7e9cc60b91b833ade557d0276185244155ffc" + "9065a9341b281f6435b7d26d6caa6b39d475f919b5d8167d" + "048d1a5bb433da5bd0d4c5901b71d585c32047047", + .b = "6215d41d790981f440660c4097750c75c0b6ef765b2fc08f" + "d7caed2fc6305e84d751d806a3b469ec3ea6825e8bfc18f9" + "acb12ad29d099ad6009a0baa13a2bbb1776a567ab705788c" + "555ff3c59cd6848f7", + .r = "76a0f17a23014c2b2b4d06cd952086837c69c3da36bc8cee" + "d0d88a74e50dfefe4a8d294cc6ab52a5cee2859ee8ffb141" + "0dd1e4fe363035825401679aeab07ab247b67d431", + }, + { + .a = "2ad3d974fa2b64854fba3e82434a1df17390ffe49f984a77" + "ce7384a02e7fe7b4c77097187ba049699cfedd4d1372cd1a" + "a64f837235ca2f9bec822c822e9981ee9afc4ec4f666b37f" + "dba827c818306a34a5ec916857dfaf2b8b128d81a", + .b = "3353e8614d8b3c5c86c76006ab8fb3f1f0973a57ebe08d81" + "93a6712a7d180c6ddb91ba324239e399bb910105bf011f48" + "f13a9c6c08a11f963cde4adf41ce4bb88ce2f395b11fe2ec" + "b19ceaf98d08b19fa", + .r = "3848694f56c96a0867df3953f63d8b90a140c15b0922dc17" + "173002079a986e669a0f032ccae911a8aef52bea6abc0427" + "76d99aeb5cfa27d105bca7e2487d051f113e69782", + }, + { + .a = "5f6264c220d6716aaf0c345b02791a38ede3a0ad8a44bc08" + "6e2fcf001bfabae0028b2ffea988bf1c2328ff9b01524db1" + "659dcf2934c26be9c32205933f5334ff2220de1d7a8333b0" + "307ad05cd08b8bde423036e898e400c5e0cc887a0", + .b = "551ff6ad295ae1bce11f72540ef81f4233d1fb688708c3f8" + "2c92695e9f57be321dfb98cb7ece06cee2a191470209cb39" + "737f9465747378a2b6a2c01ae0e92b9e5e6d954576f25abe" + "957f4ad86a8d73ea0", + .r = "6b4c3708b48166f86d1701bfd9152d7455ac0b56024fe4d6" + "e947813c8c87d343a54a14459804fc951190a17134cee19a" + "1d6bcca81480ab030ff2c58f677976bbf96d2e4e0", + }, + { + .a = "29dc9a1cc77dad36cb857326121100f546dc63a624fd950a" + "5edda4361acc17af684faaf932a8a467233321a6966c3e61" + "29f490b98e2d463b9abcd4c34263042b7966953411e6ab95" + "4f3dabd1d94baf3", + .b = "32e7ae042092a898c8de2d016f3c9d9d88d534a11fb0ff37" + "dac04057e7093ee68fc6a1a9f2639fe69959d82f0109bd6d" + "f470869db5feece762683943c506ee79c7544a56a0da307b" + "9a02ffec03ae0b4b2797a5699fda4f17853a12f", + .r = "3376875790192ffc6c7981d34ce9a79e445ab96df93be276" + "a290745feef1f204cf826ab0029074ef42b7a7b207f78d40" + "fcf5c639a1fe2492cf0bdbcf69b6d0ce3bb05b3", + }, + { + .a = "1e0b1c983532babc965cdedc4aea20127d2110d1c6bf636e" + "b5384cb9a67059e3bab8ef56a28dc34630ca37fc126ed7b6" + "25fc1164f8dd06e79ac03cd6668dee32834e32abbe29e4b9" + "415c34f6b12407369", + .b = "208f4ba8619b531371a3359236423c217565ad6261992978" + "42e96a79b0ad9bc89312da9aba13acc17c7cbd12ee3fc769" + "e2473be10228f38e666afaefe868a9a960cff9e20fdc047c" + "e44b85d26e523a5acef4507da9c145f335ab3521b", + .r = "270744a30ad54fcc784ebb3ea9f8bfc50372c09ec5578eb5" + "8ff70118681efada3d75394a5ed973df0333a14573418ae2" + "42c5585b923bcfc6d10f1ee3fd1ca497553c7de6f", + }, + { + .a = "4a83938144f1565d1407f16a811c8fd217b594b210dbc259" + "459ec5fdf9769ee85878ebe617c386284285e7354898f5ed" + "2236d1f832c606e2e7598680c4d3a103730e32a700895f86" + "fa2ab0cf34af11b48", + .b = "424ee13ea5c95ff7e99889e3912b217b97975227c303f1d1" + "57c7f8147e239cbcad6a3dd28ffe8315a60b566b326b2827" + "cb21f0da1acb02a8a094415fec55f6a76ca47d7443608703" + "21e4db7cd1449892b57ecc2c26d8efd6a6bfab978", + .r = "4aaf2a59ebfbb0d69ab6e0b867762c3fe76c54757caecc33" + "3f2c4fc9d39edda28e1beb4bd7fdf35d27f8189bc8c76a7d" + "c1613c932b1b921fea1b1eaf11a8390cacc472b28", + }, + { + .a = "6c95db45eae9c3890c716013ac0e8c8093000c0030d6b7eb" + "d556e749fd6f253d31622c5b8db0ba41d1a0709e0ed5d2d3" + "1406d0cec72e7b78bb4a21c5480bdca95a648e8331a26ca8" + "5f67c442d9471860", + .b = "7de0f00b2f156e38ab5549ff5ba31e16a6cb843823a97044" + "7abd7542db53e78e812b4eb58d16df6a614a07bb590d673a" + "7208ebb98a0fc80b070c55ecfb0a6590f530daddc5ded569" + "b80aae255b9cda0b6058c2971474106319df77e0", + .r = "7e7ff05971d259d4c99403f85afb3236188d72bf350e2e2d" + "4c44be9b3a6c569ebf47e8d0dd55c6157a8846d49a1556fa" + "d3bb1e00b077bc2a01eab5a0790e0ffadffe39e0", + }, + { + .a = "4394fd57db60ab172f4c909cdb8f3ea434e2bc6adc1ba173" + "a087dda50d52ed530384197589a0a66dc3fa5c7e47fbbc77" + "bd1bf2064d70f6ae0ab33b8fab6beeb56c985baba93b6ee5" + "fe086c99c919e3986", + .b = "4940242edd9807e4ec93d363187f29ec73623961e851a5f1" + "176e62cf1de9d47e95d43fefa3e6e05a7de8ef3eef1fbe0a" + "e9ac7bf200f8d5c9dd7eb3acca2f1e5245790065e319f456" + "419bb208665aa060009300b9197ffd6000d810876", + .r = "5360c87629e74983d59adea5ec47b9a198b3c5613afc3926" + "b9ccdad58725f4e232b7b5f8963838fb1772338620ba9240" + "967ebfdb2e29aef289cfd0d50f7a7036081e42e92", + }, + { + .a = "61be17703b62e5adf51e2c388ee77758a80632adab7c3a0d" + "d56b86ce827242baeb8a2324490c3c1e1615dcf8518aa7c2" + "65983441c7542c896e71dd213fdd04be682f654308c05cec" + "3c14c8defff396874763f57687e54e32f4ce9d1434c", + .b = "522d15c2681543b7bb50d64526e6032bebf8cd452cb06f5f" + "0105616cc681eee2d522a86f683cd675082de34844ad7836" + "4555c7d2b1e960ae02826cdb4d80937bbfcdfa59d0cdbf2b" + "4c9a96dc35b5ecbfbac", + .r = "6534089f006b049c13da2253ee4057e2aac083ce0610de29" + "00b01eddd57f4ed13adda2146fbd37bbb443420a0e7a081a" + "015e82b9dc85dd6c2389ce55a139e96f6448a424e6c", + }, + { + .a = "b287e8ac4abad5500ebe7739682f6bcf324d1afb32d68b0f" + "fd0b689aecdcf61473947ab8cc84a0a8873fce752d7027d3" + "403ccc28e522aab65b993883cd781b68b7a7d20bbabbdf3e" + "93c02aab4ccc335e4fbff8135d7d55fb5fee349bc8", + .b = "abf36a5b8c6d09a3db1ed4cc037cb32072fb0812652bebb4" + "e7f0e194494017958cce507f64f1270083cf4855c9ea85ed" + "cd2f99bcb43dcfdff5e65ff2f6b18878999a646e67b10871" + "d767a014cb39c06268", + .r = "bcfa04e04d226734bb8794716a3a3424893b94724dd5e802" + "54adad60ee8cea7cf7e8d798aa1287462a43b9d337b89d2b" + "8e2dbda0efe829e8fd784d61f0e09df7cee9d9a108", + }, + { + .a = "5805113ca06a22d67bf70a022cb538560f1e48331209ec43" + "682117ee841f4b7c425f23ce05b9febfe1ceb76784f6ff8c" + "4022df8cf61625b95f02f5f8cbf9a24f885776ee0b10acfb" + "e9b6535ceaf6c592243", + .b = "5e164dba2f2ef870b086ee79a8b37b80aaf4d26c1ab53c1f" + "3de828ddc22e1820f5a7857de133684e95d9c0487270ac90" + "66bea466dc67a70a6f6f22687f35c159314eef3d5c4ee0e2" + "f18f1b8a98f270a71bd45d44de71025b1dc966618d3", + .r = "679f032203be069cd9d44729aecad54a5fd518f9582cf4be" + "a3ef0bd7e62dec0aa124369db4f68ff416700a6f052e83a1" + "aaf3dee6d31c8f34192a60eba7eb57c759686b53d3f", + }, + { + .a = "6133ca653e55b423bb47988e353d8500c668540f10efeafa" + "a08aa8b04894517b1a4ce8b0431c2a219dd6c738b878f3a3" + "ec8f55f975b24e3d56b42ac4b087200411afc3c6716402ac" + "9d05a3b5c099be9d073cea6b51264fab6b602c76efe", + .b = "52bca44f91ee3f41b18fd6286b91463c00a50f7ac5131d76" + "ac1dcc7fd60340a3f55357a364be360744b8699a83a4ac31" + "a5b7a6f9d9bd35da094e2d20a3cfb9d21aa3b573013d8301" + "cb8cbad78c811e60f5e", + .r = "61b7a3d5d104cc66dca872b821dfc45afc88f7e46010b538" + "83aff819e90d1406991b3e104c4842db52fe1bc97c8daf37" + "a0ae1aaf3faa02ab92645764cf9173160c80cde79ea", + }, + { + .a = "5ba6fdd7fbeccfe482b2f57cdac17d53d09a60bb76422fb4" + "22b4c7785ce7186c88bf33cba40afa8f74a2d66b195c7d3a" + "f49ffc436fffb2e32c4cdfb67253c1afa4898bcb5dcbe39e" + "e6288129c59cf16dc177d63d0bf02fe216c1fbeba9b", + .b = "5a1e35a1fa9ca5d66244af81b6a239d1d7b94841e38413ad" + "35b47fafb2d7509a30011e6d7a64360d4ccdb9f86d00a939" + "4721575f8fe9e23306ffe3059ef99447d09fd00f5c795d38" + "36c1dc663834da34991", + .r = "70d68f80fbeac749d6f0f718ba5a6bca7ca23dee2b7ee687" + "ba0e3be0f45941d0ee637b3e8406ea2aed4f1638bdb47f17" + "7beec21cab2e49d832d9bda5a9d3b62003d6429bcbf", + }, + { + .a = "58f54f7ea83715900bc82bd5fc183f926f0fef989159bab7" + "c3aa18fd186efd7fc79d2a58c0bbd8556c1fabb784975801" + "396089ffa82f59eff04a2557b532f99bd39e08f597e00d0c" + "c96eccf3618cc02ec57b592d4d019152b686bd84bac", + .b = "4866326c48b8226bec5aae93bc3b3b3fdac0a60319730efa" + "7d9aa373da03f59159d3ccbeb478dbb5393fd91c6daaad8c" + "28dc0187a59448847ad960648b8fdfc14f785f09e423c8cb" + "1c6cc5862b4ec95a25c", + .r = "5f4a880841ce22ffd67705b03d965c39517a79f8e8ab6669" + "482eef3966895a050c67cce16965f98cd53477aeac38a521" + "02a6274dba0f5d2f02f1d5f1dff5653db7ca109a9cc", + }, + { + .a = "6a0e2e61d2859ce130d11aff8a8a9cc0672d3cea86da2f31" + "4a6a656e13f4830826cd8a6044d1233f7a6d70cae35060ea" + "fb66ae062c7f4af5eff978da2c5c29421322ed65293dbe9e" + "1855cb2977bec2fbf20", + .b = "594a63062ee8b0b61f0143ed9237906010c17e6d03cfb2fe" + "675f13edc7f8c54770f25dbb275f3236a8fa3bddc10c4fa8" + "fe0b704e6c4c0ee29929d2d49500a4254903350cdc72b02e" + "dddf83964b5c382b4f12571fc4741fd5b3ac9c24a20", + .r = "6c4c28b2358329ee65678c92b6e9b31187d4ddd793f9af45" + "e780b723f63b82c287e2ab0fb06ccd173a9bec960667a47f" + "0ebd5a2ce8d1d0059500be32d67c8ab308e3e08fda0", + }, + { + .a = "b37bbec16572713e3cadbcbd2703c48673edde83d6ab5cc0" + "02c32dd693950f4c3965506c04cddcbd754f23245ce63f92" + "f5dcb926f40bbf08583de1a11047e0c2508b47d0896cc0cb" + "fbe031a5e9a148923e", + .b = "e8cceb9061392e35fd652346312aff143d88fb156695e0a7" + "f7b84419ca35214374733457d32517d0cb7c16c31a10f002" + "d4f2bd2fd4ee4ded122f1e221dfc989d0c8dd66deb1ac49a" + "9199290905db12c064d3376805451b969ee424a59a", + .r = "e9eb6a282f306af29a28df6d720469568183f136e58813e3" + "d61929b91f8538cf0f777fd5fb1672f0bdc4e59ccb9a4f79" + "16aabeba3101842a700fa4c08e758ec7169726d682", + }, +}; + +#define N_GCD_TESTS (sizeof(bn_gcd_tests) / sizeof(bn_gcd_tests[0])) + +static int +bn_gcd_test(const struct gcd_test *testcase) +{ + BN_CTX *ctx; + BIGNUM *a, *b, *want, *got; + size_t i; + int signs; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "a = BN_CTX_get(ctx)"); + if ((b = BN_CTX_get(ctx)) == NULL) + errx(1, "b = BN_CTX_get(ctx)"); + if ((want = BN_CTX_get(ctx)) == NULL) + errx(1, "want = BN_CTX_get(ctx)"); + if ((got = BN_CTX_get(ctx)) == NULL) + errx(1, "got = BN_CTX_get(ctx)"); + + if (!BN_hex2bn(&a, testcase->a)) + errx(1, "a = hex2bn(%s)", testcase->a); + if (!BN_hex2bn(&b, testcase->b)) + errx(1, "b = hex2bn(%s)", testcase->b); + if (!BN_hex2bn(&want, testcase->r)) + errx(1, "want = hex2bn(%s)", testcase->r); + + for (i = 0; i < N_GCD_FN; i++) { + for (signs = 0; signs < 4; signs++) { + const struct gcd_test_fn *test = &gcd_fn[i]; + + /* XXX - BN_gcd_ct(a, 0) divides by zero */ + if (test->fails_on_zero && BN_is_zero(b)) + continue; + + BN_set_negative(a, (signs >> 0) & 1); + BN_set_negative(b, (signs >> 1) & 1); + + if (!test->fn(got, a, b, ctx)) { + fprintf(stderr, "%s(%s, %s) failed\n", + test->name, testcase->a, testcase->b); + goto err; + } + + if (BN_cmp(got, want) != 0) { + fprintf(stderr, "a: %s\n", testcase->a); + fprintf(stderr, "b: %s\n", testcase->b); + fprintf(stderr, "%s, i: %zu, signs %d, want %s, got ", + test->name, i, signs, testcase->r); + BN_print_fp(stderr, got); + fprintf(stderr, "\n"); + + failed |= 1; + } + } + } + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return failed; +} + +static int +run_bn_gcd_tests(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_GCD_TESTS; i++) + failed |= bn_gcd_test(&bn_gcd_tests[i]); + + return failed; +} + +/* + * This test uses the coprime factorization 2^(2k) - 1 = (2^k - 1) * (2^k + 1). + */ + +static int +bn_binomial_gcd_test(const struct gcd_test_fn *test, int k, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + BIGNUM *gcd; + int shift, signs; + int failed = 0; + + BN_CTX_start(ctx); + + if ((gcd = BN_CTX_get(ctx)) == NULL) + errx(1, "%s: gcd = BN_CTX_get(ctx)", test->name); + + for (shift = 0; shift < 16; shift++) { + for (signs = 0; signs < 4; signs++) { + /* XXX - BN_gcd_ct(a, 0) divides by zero */ + if (test->fails_on_zero && BN_is_zero(b)) + continue; + + BN_set_negative(a, (signs >> 0) & 1); + BN_set_negative(b, (signs >> 1) & 1); + + if (!test->fn(gcd, a, b, ctx)) { + errx(1, "%s(), k: %d, shift: %d, signs %d\n", + test->name, k, shift, signs); + } + + if (BN_is_negative(gcd)) { + fprintf(stderr, "%s: negative gcd, " + "k: %d, shift: %d, signs %d\n", + test->name, k, shift, signs); + failed |= 1; + } + + if (BN_ucmp(gcd, b) != 0) { + fprintf(stderr, "%s: BN_ucmp(gcd, b) failed, " + "k: %d, shift: %d, signs %d\n", + test->name, k, shift, signs); + BN_print_fp(stderr, gcd); + fprintf(stderr, "\n"); + BN_print_fp(stderr, b); + fprintf(stderr, "\n"); + failed |= 1; + } + } + + if (!BN_lshift1(a, a)) + errx(1, "%s: BN_lshift1(a, a)", test->name); + if (!BN_lshift1(b, b)) + errx(1, "%s: BN_lshift1(b, b)", test->name); + } + + BN_CTX_end(ctx); + + return failed; +} + +static int +run_bn_binomial_gcd_tests(void) +{ + BN_CTX *ctx; + BIGNUM *a, *b; + size_t i; + int k; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "%s: BN_CTX_new()", __func__); + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "%s: a = BN_CTX_get(ctx)", __func__); + if ((b = BN_CTX_get(ctx)) == NULL) + errx(1, "%s: b = BN_CTX_get(ctx)", __func__); + + for (i = 0; i < N_GCD_FN; i++) { + const struct gcd_test_fn *test = &gcd_fn[i]; + + for (k = 0; k < 400; k++) { + BN_zero(a); + BN_zero(b); + + /* a = 2^(2k) - 1 */ + if (!BN_set_bit(a, 2 * k)) + errx(1, "%s: BN_set_bit(a, 2 * k)", test->name); + if (!BN_sub_word(a, 1)) + errx(1, "%s: BN_sub_word(a, 1)", test->name); + + /* b = 2^k - 1 */ + if (!BN_set_bit(b, k)) + errx(1, "%s: BN_set_bit(a, k)", test->name); + if (!BN_sub_word(b, 1)) + errx(1, "%s: BN_sub_word(a, 1)", test->name); + + failed |= bn_binomial_gcd_test(test, k, a, b, ctx); + + BN_zero(a); + BN_zero(b); + + /* a = 2^(2k) - 1 */ + if (!BN_set_bit(a, 2 * k)) + errx(1, "%s: BN_set_bit(a, 2 * k)", test->name); + if (!BN_sub_word(a, 1)) + errx(1, "%s: BN_sub_word(a, 1)", test->name); + + /* b = 2^k + 1 */ + if (!BN_set_bit(b, k)) + errx(1, "%s: BN_set_bit(a, k)", test->name); + if (!BN_add_word(b, 1)) + errx(1, "%s: BN_add_word(a, 1)", test->name); + + failed |= bn_binomial_gcd_test(test, k, a, b, ctx); + } + } + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= run_bn_gcd_tests(); + failed |= run_bn_binomial_gcd_tests(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_isqrt.c b/Libraries/libressl/tests/bn_isqrt.c new file mode 100644 index 000000000..d8a2d2755 --- /dev/null +++ b/Libraries/libressl/tests/bn_isqrt.c @@ -0,0 +1,330 @@ +/* $OpenBSD: bn_isqrt.c,v 1.4 2023/08/03 18:53:56 tb Exp $ */ +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "bn_local.h" + +#define N_TESTS 100 + +/* Sample squares between 2^128 and 2^4096. */ +#define LOWER_BITS 128 +#define UPPER_BITS 4096 + +extern const uint8_t is_square_mod_11[]; +extern const uint8_t is_square_mod_63[]; +extern const uint8_t is_square_mod_64[]; +extern const uint8_t is_square_mod_65[]; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +static const uint8_t * +get_table(int modulus) +{ + switch (modulus) { + case 11: + return is_square_mod_11; + case 63: + return is_square_mod_63; + case 64: + return is_square_mod_64; + case 65: + return is_square_mod_65; + default: + return NULL; + } +} + +static int +check_tables(int print) +{ + int fill[] = {11, 63, 64, 65}; + const uint8_t *table; + uint8_t q[65]; + size_t i; + int j; + int failed = 0; + + for (i = 0; i < sizeof(fill) / sizeof(fill[0]); i++) { + memset(q, 0, sizeof(q)); + + for (j = 0; j < fill[i]; j++) + q[(j * j) % fill[i]] = 1; + + if ((table = get_table(fill[i])) == NULL) { + fprintf(stderr, "failed to get table %d\n", fill[i]); + failed |= 1; + continue; + } + + if (memcmp(table, q, fill[i]) != 0) { + fprintf(stderr, "table %d does not match:\n", fill[i]); + fprintf(stderr, "want:\n"); + hexdump(table, fill[i]); + fprintf(stderr, "got:\n"); + hexdump(q, fill[i]); + failed |= 1; + continue; + } + + if (!print) + continue; + + printf("const uint8_t is_square_mod_%d[] = {\n\t", fill[i]); + for (j = 0; j < fill[i]; j++) { + const char *end = " "; + + if (j % 16 == 15) + end = "\n\t"; + if (j + 1 == fill[i]) + end = ""; + + printf("%d,%s", q[j], end); + } + printf("\n};\nCTASSERT(sizeof(is_square_mod_%d) == %d);\n\n", + fill[i], fill[i]); + } + + return failed; +} + +static int +validate_tables(void) +{ + int fill[] = {11, 63, 64, 65}; + const uint8_t *table; + size_t i; + int j, k; + int failed = 0; + + for (i = 0; i < sizeof(fill) / sizeof(fill[0]); i++) { + if ((table = get_table(fill[i])) == NULL) { + fprintf(stderr, "failed to get table %d\n", fill[i]); + failed |= 1; + continue; + } + + for (j = 0; j < fill[i]; j++) { + for (k = 0; k < fill[i]; k++) { + if (j == (k * k) % fill[i]) + break; + } + + if (table[j] == 0 && k < fill[i]) { + fprintf(stderr, "%d == %d^2 (mod %d)", j, k, + fill[i]); + failed |= 1; + } + if (table[j] == 1 && k == fill[i]) { + fprintf(stderr, "%d not a square (mod %d)", j, + fill[i]); + failed |= 1; + } + } + } + + return failed; +} + +/* + * Choose a random number n of bit length between LOWER_BITS and UPPER_BITS and + * check that n == isqrt(n^2). Random numbers n^2 <= testcase < (n + 1)^2 are + * checked to have isqrt(testcase) == n. + */ +static int +isqrt_test(void) +{ + BN_CTX *ctx; + BIGNUM *n, *n_sqr, *lower, *upper, *testcase, *isqrt; + int cmp, i, is_perfect_square; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + BN_CTX_start(ctx); + + if ((lower = BN_CTX_get(ctx)) == NULL) + errx(1, "lower = BN_CTX_get(ctx)"); + if ((upper = BN_CTX_get(ctx)) == NULL) + errx(1, "upper = BN_CTX_get(ctx)"); + if ((n = BN_CTX_get(ctx)) == NULL) + errx(1, "n = BN_CTX_get(ctx)"); + if ((n_sqr = BN_CTX_get(ctx)) == NULL) + errx(1, "n = BN_CTX_get(ctx)"); + if ((isqrt = BN_CTX_get(ctx)) == NULL) + errx(1, "result = BN_CTX_get(ctx)"); + if ((testcase = BN_CTX_get(ctx)) == NULL) + errx(1, "testcase = BN_CTX_get(ctx)"); + + /* lower = 2^LOWER_BITS, upper = 2^UPPER_BITS. */ + if (!BN_set_bit(lower, LOWER_BITS)) + errx(1, "BN_set_bit(lower, %d)", LOWER_BITS); + if (!BN_set_bit(upper, UPPER_BITS)) + errx(1, "BN_set_bit(upper, %d)", UPPER_BITS); + + if (!bn_rand_in_range(n, lower, upper)) + errx(1, "bn_rand_in_range n"); + + /* n_sqr = n^2 */ + if (!BN_sqr(n_sqr, n, ctx)) + errx(1, "BN_sqr"); + + if (!bn_isqrt(isqrt, &is_perfect_square, n_sqr, ctx)) + errx(1, "bn_isqrt n_sqr"); + + if ((cmp = BN_cmp(n, isqrt)) != 0 || !is_perfect_square) { + fprintf(stderr, "n = "); + BN_print_fp(stderr, n); + fprintf(stderr, "\nn^2 is_perfect_square: %d, cmp: %d\n", + is_perfect_square, cmp); + failed = 1; + } + + /* upper = 2 * n + 1 */ + if (!BN_lshift1(upper, n)) + errx(1, "BN_lshift1(upper, n)"); + if (!BN_add_word(upper, 1)) + errx(1, "BN_sub_word(upper, 1)"); + + /* upper = (n + 1)^2 = n^2 + upper */ + if (!BN_add(upper, n_sqr, upper)) + errx(1, "BN_add"); + + /* + * Check that isqrt((n + 1)^2) - 1 == n. + */ + + if (!bn_isqrt(isqrt, &is_perfect_square, upper, ctx)) + errx(1, "bn_isqrt(upper)"); + + if (!BN_sub_word(isqrt, 1)) + errx(1, "BN_add_word(isqrt, 1)"); + + if ((cmp = BN_cmp(n, isqrt)) != 0 || !is_perfect_square) { + fprintf(stderr, "n = "); + BN_print_fp(stderr, n); + fprintf(stderr, "\n(n + 1)^2 is_perfect_square: %d, cmp: %d\n", + is_perfect_square, cmp); + failed = 1; + } + + /* + * Test N_TESTS random numbers n^2 <= testcase < (n + 1)^2 and check + * that their isqrt is n. + */ + + for (i = 0; i < N_TESTS; i++) { + if (!bn_rand_in_range(testcase, n_sqr, upper)) + errx(1, "bn_rand_in_range testcase"); + + if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx)) + errx(1, "bn_isqrt testcase"); + + if ((cmp = BN_cmp(n, isqrt)) != 0 || + (is_perfect_square && BN_cmp(n_sqr, testcase) != 0)) { + fprintf(stderr, "n = "); + BN_print_fp(stderr, n); + fprintf(stderr, "\ntestcase = "); + BN_print_fp(stderr, testcase); + fprintf(stderr, + "\ntestcase is_perfect_square: %d, cmp: %d\n", + is_perfect_square, cmp); + failed = 1; + } + } + + /* + * Finally check that isqrt(n^2 - 1) + 1 == n. + */ + + if (!BN_sub(testcase, n_sqr, BN_value_one())) + errx(1, "BN_sub(testcase, n_sqr, 1)"); + + if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx)) + errx(1, "bn_isqrt(n_sqr - 1)"); + + if (!BN_add_word(isqrt, 1)) + errx(1, "BN_add_word(isqrt, 1)"); + + if ((cmp = BN_cmp(n, isqrt)) != 0 || is_perfect_square) { + fprintf(stderr, "n = "); + BN_print_fp(stderr, n); + fprintf(stderr, "\nn_sqr - 1 is_perfect_square: %d, cmp: %d\n", + is_perfect_square, cmp); + failed = 1; + } + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return failed; +} + +static void +usage(void) +{ + fprintf(stderr, "usage: bn_isqrt [-C]\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + size_t i; + int ch; + int failed = 0, print = 0; + + while ((ch = getopt(argc, argv, "C")) != -1) { + switch (ch) { + case 'C': + print = 1; + break; + default: + usage(); + break; + } + } + + if (print) + return check_tables(1); + + for (i = 0; i < N_TESTS; i++) + failed |= isqrt_test(); + + failed |= check_tables(0); + failed |= validate_tables(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_mod_exp.c b/Libraries/libressl/tests/bn_mod_exp.c new file mode 100644 index 000000000..14e188397 --- /dev/null +++ b/Libraries/libressl/tests/bn_mod_exp.c @@ -0,0 +1,575 @@ +/* $OpenBSD: bn_mod_exp.c,v 1.38 2023/05/09 05:39:24 tb Exp $ */ + +/* + * Copyright (c) 2022,2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#include "bn_local.h" + +#define N_MOD_EXP_TESTS 100 +#define N_MOD_EXP2_TESTS 50 + +#define INIT_MOD_EXP_FN(f) { .name = #f, .mod_exp_fn = (f), } +#define INIT_MOD_EXP_MONT_FN(f) { .name = #f, .mod_exp_mont_fn = (f), } + +static int +bn_mod_exp2_mont_first(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx) +{ + const BIGNUM *one = BN_value_one(); + + return BN_mod_exp2_mont(r, a, p, one, one, m, ctx, mctx); +} + +static int +bn_mod_exp2_mont_second(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx) +{ + const BIGNUM *one = BN_value_one(); + + return BN_mod_exp2_mont(r, one, one, a, p, m, ctx, mctx); +} + +static const struct mod_exp_test { + const char *name; + int (*mod_exp_fn)(BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*mod_exp_mont_fn)(BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *); +} mod_exp_fn[] = { + INIT_MOD_EXP_FN(BN_mod_exp), + INIT_MOD_EXP_FN(BN_mod_exp_ct), + INIT_MOD_EXP_FN(BN_mod_exp_nonct), + INIT_MOD_EXP_FN(BN_mod_exp_recp), + INIT_MOD_EXP_FN(BN_mod_exp_simple), + INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont), + INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_ct), + INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_consttime), + INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_nonct), + INIT_MOD_EXP_MONT_FN(bn_mod_exp2_mont_first), + INIT_MOD_EXP_MONT_FN(bn_mod_exp2_mont_second), +}; + +#define N_MOD_EXP_FN (sizeof(mod_exp_fn) / sizeof(mod_exp_fn[0])) + +static void +bn_print(const char *name, const BIGNUM *bn) +{ + size_t len; + int pad = 0; + + if ((len = strlen(name)) < 7) + pad = 6 - len; + + fprintf(stderr, "%s: %*s", name, pad, ""); + BN_print_fp(stderr, bn); + fprintf(stderr, "\n"); +} + +static void +print_zero_test_failure(const BIGNUM *got, const BIGNUM *a, const BIGNUM *m, + const char *name) +{ + fprintf(stderr, "%s() zero test failed:\n", name); + + bn_print("a", a); + bn_print("m", m); + bn_print("got", got); +} + +static int +bn_mod_exp_zero_test(const struct mod_exp_test *test, BN_CTX *ctx, + int neg_modulus, int random_base) +{ + BIGNUM *a, *m, *p, *got; + int mod_exp_ret; + int failed = 1; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + if ((m = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + if ((p = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + if ((got = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + + if (!BN_one(m)) + errx(1, "BN_one"); + if (neg_modulus) + BN_set_negative(m, 1); + BN_zero(a); + BN_zero(p); + + if (random_base) { + if (!BN_rand(a, 1024, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + errx(1, "BN_rand"); + } + + if (test->mod_exp_fn != NULL) { + mod_exp_ret = test->mod_exp_fn(got, a, p, m, ctx); + } else { + mod_exp_ret = test->mod_exp_mont_fn(got, a, p, m, ctx, NULL); + } + + if (!mod_exp_ret) { + fprintf(stderr, "%s failed\n", test->name); + ERR_print_errors_fp(stderr); + goto err; + } + + if (!BN_is_zero(got)) { + print_zero_test_failure(got, a, m, test->name); + goto err; + } + + failed = 0; + + err: + BN_CTX_end(ctx); + + return failed; +} + +static int +bn_mod_exp_zero_word_test(BN_CTX *ctx, int neg_modulus) +{ + const char *name = "BN_mod_exp_mont_word"; + BIGNUM *m, *p, *got; + int failed = 1; + + BN_CTX_start(ctx); + + if ((m = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + if ((p = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + if ((got = BN_CTX_get(ctx)) == NULL) + errx(1, "BN_CTX_get"); + + if (!BN_one(m)) + errx(1, "BN_one"); + if (neg_modulus) + BN_set_negative(m, neg_modulus); + BN_zero(p); + + if (!BN_mod_exp_mont_word(got, 1, p, m, ctx, NULL)) { + fprintf(stderr, "%s failed\n", name); + ERR_print_errors_fp(stderr); + goto err; + } + + if (!BN_is_zero(got)) { + print_zero_test_failure(got, p, m, name); + goto err; + } + + failed = 0; + + err: + BN_CTX_end(ctx); + + return failed; +} + +static int +test_bn_mod_exp_zero(void) +{ + BN_CTX *ctx; + size_t i, j; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + for (i = 0; i < N_MOD_EXP_FN; i++) { + for (j = 0; j < 4; j++) { + int neg_modulus = (j >> 0) & 1; + int random_base = (j >> 1) & 1; + + failed |= bn_mod_exp_zero_test(&mod_exp_fn[i], ctx, + neg_modulus, random_base); + } + } + + failed |= bn_mod_exp_zero_word_test(ctx, 0); + failed |= bn_mod_exp_zero_word_test(ctx, 1); + + BN_CTX_free(ctx); + + return failed; +} + +static int +generate_bn(BIGNUM *bn, int avg_bits, int deviate, int force_odd) +{ + int bits; + + if (bn == NULL) + return 1; + + if (avg_bits <= 0 || deviate <= 0 || deviate >= avg_bits) + return 0; + + bits = avg_bits + arc4random_uniform(deviate) - deviate; + + return BN_rand(bn, bits, 0, force_odd); +} + +static int +generate_test_quintuple(int reduce, BIGNUM *a, BIGNUM *p, BIGNUM *b, BIGNUM *q, + BIGNUM *m, BN_CTX *ctx) +{ + BIGNUM *mmodified; + BN_ULONG multiple; + int avg = 2 * BN_BITS, deviate = BN_BITS / 2; + int ret = 0; + + if (!generate_bn(a, avg, deviate, 0)) + return 0; + + if (!generate_bn(p, avg, deviate, 0)) + return 0; + + if (!generate_bn(b, avg, deviate, 0)) + return 0; + + if (!generate_bn(q, avg, deviate, 0)) + return 0; + + if (!generate_bn(m, avg, deviate, 1)) + return 0; + + if (reduce) { + if (!BN_mod(a, a, m, ctx)) + return 0; + + if (b == NULL) + return 1; + + return BN_mod(b, b, m, ctx); + } + + /* + * Add a random multiple of m to a to test unreduced exponentiation. + */ + + BN_CTX_start(ctx); + + if ((mmodified = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!bn_copy(mmodified, m)) + goto err; + + multiple = arc4random_uniform(16) + 2; + + if (!BN_mul_word(mmodified, multiple)) + goto err; + + if (!BN_add(a, a, mmodified)) + goto err; + + if (b == NULL) + goto done; + + if (!BN_add(b, b, mmodified)) + goto err; + + done: + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +static int +generate_test_triple(int reduce, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) +{ + return generate_test_quintuple(reduce, a, p, NULL, NULL, m, ctx); +} + +static void +dump_results(const BIGNUM *a, const BIGNUM *p, const BIGNUM *b, const BIGNUM *q, + const BIGNUM *m, const BIGNUM *want, const BIGNUM *got, const char *name) +{ + fprintf(stderr, "BN_mod_exp_simple() and %s() disagree:\n", name); + + bn_print("want", want); + bn_print("got", got); + + bn_print("a", a); + bn_print("p", p); + + if (b != NULL) { + bn_print("b", b); + bn_print("q", q); + } + + bn_print("m", m); + + fprintf(stderr, "\n"); +} + +static int +test_mod_exp(const BIGNUM *want, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, const struct mod_exp_test *test) +{ + BIGNUM *got; + int mod_exp_ret; + int ret = 0; + + BN_CTX_start(ctx); + + if ((got = BN_CTX_get(ctx)) == NULL) + goto err; + + if (test->mod_exp_fn != NULL) + mod_exp_ret = test->mod_exp_fn(got, a, p, m, ctx); + else + mod_exp_ret = test->mod_exp_mont_fn(got, a, p, m, ctx, NULL); + + if (!mod_exp_ret) + errx(1, "%s() failed", test->name); + + if (BN_cmp(want, got) != 0) { + dump_results(a, p, NULL, NULL, m, want, got, test->name); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} + +static int +bn_mod_exp_test(int reduce, BIGNUM *want, BIGNUM *a, BIGNUM *p, BIGNUM *m, + BN_CTX *ctx) +{ + size_t i, j; + int failed = 0; + + if (!generate_test_triple(reduce, a, p, m, ctx)) + errx(1, "generate_test_triple"); + + for (i = 0; i < 8 && !failed; i++) { + BN_set_negative(a, (i >> 0) & 1); + BN_set_negative(p, (i >> 1) & 1); + BN_set_negative(m, (i >> 2) & 1); + + if ((BN_mod_exp_simple(want, a, p, m, ctx)) <= 0) + errx(1, "BN_mod_exp_simple"); + + for (j = 0; j < N_MOD_EXP_FN; j++) { + const struct mod_exp_test *test = &mod_exp_fn[j]; + + if (!test_mod_exp(want, a, p, m, ctx, test)) + failed |= 1; + } + } + + return failed; +} + +static int +test_bn_mod_exp(void) +{ + BIGNUM *a, *p, *m, *want; + BN_CTX *ctx; + int i; + int reduce; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "a = BN_CTX_get()"); + if ((p = BN_CTX_get(ctx)) == NULL) + errx(1, "p = BN_CTX_get()"); + if ((m = BN_CTX_get(ctx)) == NULL) + errx(1, "m = BN_CTX_get()"); + if ((want = BN_CTX_get(ctx)) == NULL) + errx(1, "want = BN_CTX_get()"); + + reduce = 0; + for (i = 0; i < N_MOD_EXP_TESTS && !failed; i++) + failed |= bn_mod_exp_test(reduce, want, a, p, m, ctx); + + reduce = 1; + for (i = 0; i < N_MOD_EXP_TESTS && !failed; i++) + failed |= bn_mod_exp_test(reduce, want, a, p, m, ctx); + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return failed; +} + +static int +bn_mod_exp2_simple(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *b, const BIGNUM *q, const BIGNUM *m, BN_CTX *ctx) +{ + BIGNUM *fact1, *fact2; + int ret = 0; + + BN_CTX_start(ctx); + + if ((fact1 = BN_CTX_get(ctx)) == NULL) + goto err; + if ((fact2 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_mod_exp_simple(fact1, a, p, m, ctx)) + goto err; + if (!BN_mod_exp_simple(fact2, b, q, m, ctx)) + goto err; + if (!BN_mod_mul(out, fact1, fact2, m, ctx)) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +static int +bn_mod_exp2_test(int reduce, BIGNUM *want, BIGNUM *got, BIGNUM *a, BIGNUM *p, + BIGNUM *b, BIGNUM *q, BIGNUM *m, BN_CTX *ctx) +{ + size_t i; + int failed = 0; + + if (!generate_test_quintuple(reduce, a, p, b, q, m, ctx)) + errx(1, "generate_test_quintuple"); + + for (i = 0; i < 32 && !failed; i++) { + BN_set_negative(a, (i >> 0) & 1); + BN_set_negative(p, (i >> 1) & 1); + BN_set_negative(b, (i >> 2) & 1); + BN_set_negative(q, (i >> 3) & 1); + BN_set_negative(m, (i >> 4) & 1); + + if (!bn_mod_exp2_simple(want, a, p, b, q, m, ctx)) + errx(1, "BN_mod_exp_simple"); + + if (!BN_mod_exp2_mont(got, a, p, b, q, m, ctx, NULL)) + errx(1, "BN_mod_exp2_mont"); + + if (BN_cmp(want, got) != 0) { + dump_results(a, p, b, q, m, want, got, "BN_mod_exp2_mont"); + failed |= 1; + } + } + + return failed; +} + +static int +test_bn_mod_exp2(void) +{ + BIGNUM *a, *p, *b, *q, *m, *want, *got; + BN_CTX *ctx; + int i; + int reduce; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "a = BN_CTX_get()"); + if ((p = BN_CTX_get(ctx)) == NULL) + errx(1, "p = BN_CTX_get()"); + if ((b = BN_CTX_get(ctx)) == NULL) + errx(1, "b = BN_CTX_get()"); + if ((q = BN_CTX_get(ctx)) == NULL) + errx(1, "q = BN_CTX_get()"); + if ((m = BN_CTX_get(ctx)) == NULL) + errx(1, "m = BN_CTX_get()"); + if ((want = BN_CTX_get(ctx)) == NULL) + errx(1, "want = BN_CTX_get()"); + if ((got = BN_CTX_get(ctx)) == NULL) + errx(1, "got = BN_CTX_get()"); + + reduce = 0; + for (i = 0; i < N_MOD_EXP_TESTS && !failed; i++) + failed |= bn_mod_exp2_test(reduce, want, got, a, p, b, q, m, ctx); + + reduce = 1; + for (i = 0; i < N_MOD_EXP_TESTS && !failed; i++) + failed |= bn_mod_exp2_test(reduce, want, got, a, p, b, q, m, ctx); + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return failed; +} + +/* + * Small test for a crash reported by Guido Vranken, fixed in bn_exp2.c r1.13. + * https://github.com/openssl/openssl/issues/17648 + */ + +static int +test_bn_mod_exp2_mont_crash(void) +{ + BIGNUM *m; + int failed = 0; + + if ((m = BN_new()) == NULL) + errx(1, "BN_new"); + + if (BN_mod_exp2_mont(NULL, NULL, NULL, NULL, NULL, m, NULL, NULL)) { + fprintf(stderr, "BN_mod_exp2_mont succeeded\n"); + failed |= 1; + } + + BN_free(m); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= test_bn_mod_exp_zero(); + failed |= test_bn_mod_exp(); + failed |= test_bn_mod_exp2(); + failed |= test_bn_mod_exp2_mont_crash(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_mod_inverse.c b/Libraries/libressl/tests/bn_mod_inverse.c new file mode 100644 index 000000000..f05e78c26 --- /dev/null +++ b/Libraries/libressl/tests/bn_mod_inverse.c @@ -0,0 +1,387 @@ +/* $OpenBSD: bn_mod_inverse.c,v 1.2 2023/06/04 07:14:47 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +BIGNUM *BN_mod_inverse(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + +static const struct mod_inv_test { + const char *i; + const char *a; + const char *m; +} mod_inv_tests[] = { + { + .i = "0", + .a = "0", + .m = "1", + }, + { + .i = "0", + .a = "1", + .m = "1", + }, + { + .i = "0", + .a = "2", + .m = "1", + }, + { + .i = "0", + .a = "3", + .m = "1", + }, + { + .i = "64", + .a = "54", + .m = "e3", + }, + { + .i = "13", + .a = "2b", + .m = "30", + }, + { + .i = "2f", + .a = "30", + .m = "37", + }, + { + .i = "4", + .a = "13", + .m = "4b", + }, + { + .i = "1c47", + .a = "cd4", + .m = "6a21", + }, + { + .i = "2b97", + .a = "8e7", + .m = "49c0", + }, + { + .i = "29b9", + .a = "fcb", + .m = "3092", + }, + { + .i = "a83", + .a = "14bf", + .m = "41ae", + }, + { + .i = "18f15fe1", + .a = "11b5d53e", + .m = "322e92a1", + }, + { + .i = "32f9453b", + .a = "8af6df6", + .m = "33d45eb7", + }, + { + .i = "d696369", + .a = "c5f89dd5", + .m = "fc09c17c", + }, + { + .i = "622839d8", + .a = "60c2526", + .m = "74200493", + }, + { + .i = "fb5a8aee7bbc4ef", + .a = "24ebd835a70be4e2", + .m = "9c7256574e0c5e93", + }, + { + .i = "846bc225402419c", + .a = "23026003ab1fbdb", + .m = "1683cbe32779c59b", + }, + { + .i = "5ff84f63a78982f9", + .a = "4a2420dc733e1a0f", + .m = "a73c6bfabefa09e6", + }, + { + .i = "133e74d28ef42b43", + .a = "2e9511ae29cdd41", + .m = "15234df99f19fcda", + }, + { + .i = "46ae1fabe9521e4b99b198fc84396090" + "23aa69be2247c0d1e27c2a0ea332f9c5", + .a = "6331fec5f01014046788c919ed50dc86" + "ac7a80c085f1b6f645dd179c0f0dc9cd", + .m = "8ef409de82318259a8655a39293b1e76" + "2fa2cc7e0aeb4c59713a1e1fff6af640", + }, + { + .i = "444ccea3a7b21677dd294d34de53cc8a" + "5b51e69b37782310a00fc6bcc975709b", + .a = "679280bd880994c08322143a4ea8a082" + "5d0466fda1bb6b3eb86fc8e90747512b", + .m = "e4fecab84b365c63a0dab4244ce3f921" + "a9c87ec64d69a2031939f55782e99a2e", + }, + { + .i = "1ac7d7a03ceec5f690f567c9d61bf346" + "9c078285bcc5cf00ac944596e887ca17", + .a = "1593ef32d9c784f5091bdff952f5c5f5" + "92a3aed6ba8ea865efa6d7df87be1805", + .m = "1e276882f90c95e0c1976eb079f97af0" + "75445b1361c02018d6bd7191162e67b2", + }, + { + .i = "639108b90dfe946f498be21303058413" + "bbb0e59d0bd6a6115788705abd0666d6", + .a = "9258d6238e4923d120b2d1033573ffca" + "c691526ad0842a3b174dccdbb79887bd", + .m = "ce62909c39371d463aaba3d4b72ea6da" + "49cb9b529e39e1972ef3ccd9a66fe08f", + }, + { + .i = "aebde7654cb17833a106231c4b9e2f51" + "9140e85faee1bfb4192830f03f385e77" + "3c0f4767e93e874ffdc3b7a6b7e6a710" + "e5619901c739ee8760a26128e8c91ef8" + "cf761d0e505d8b28ae078d17e6071c37" + "2893bb7b72538e518ebc57efa70b7615" + "e406756c49729b7c6e74f84aed7a316b" + "6fa748ff4b9f143129d29dad1bff98bb", + .a = "a29dacaf5487d354280fdd2745b9ace4" + "cd50f2bde41d0ee529bf26a1913244f7" + "08085452ff32feab19a7418897990da4" + "6a0633f7c8375d583367319091bbbe06" + "9b0052c5e48a7daac9fb650db5af768c" + "d2508ec3e2cda7456d4b9ce1c3945962" + "7a8b77e038b826cd7e326d0685b0cd0c" + "b50f026f18300dae9f5fd42aa150ee8b", + .m = "d686f9b86697313251685e995c09b9f1" + "e337ddfaa050bd2df15bf4ca1dc46c55" + "65021314765299c434ea1a6ec42bf92a" + "29a7d1ffff599f4e50b79a82243fb248" + "13060580c770d4c1140aeb2ab2685007" + "e948b6f1f62e8001a0545619477d4981" + "32c907774479f6d95899e6251e7136f7" + "9ab6d3b7c82e4aca421e7d22fe7db19c", + }, + { + .i = "1ec872f4f20439e203597ca4de9d1296" + "743f95781b2fe85d5def808558bbadef" + "02a46b8955f47c83e1625f8bb40228ea" + "b09cad2a35c9ad62ab77a30e39328729" + "59c5898674162da244a0ec1f68c0ed89" + "f4b0f3572bfdc658ad15bf1b1c6e1176" + "b0784c9935bd3ff1f49bb43753eacee1" + "d8ca1c0b652d39ec727da83984fe3a0f", + .a = "2e527b0a1dc32460b2dd94ec446c6929" + "89f7b3c7451a5cbeebf69fc0ea9c4871" + "fbe78682d5dc5b66689f7ed889b52161" + "cd9830b589a93d21ab26dbede6c33959" + "f5a0f0d107169e2daaac78bac8cf2d41" + "a1eb1369cb6dc9e865e73bb2e51b886f" + "4e896082db199175e3dde0c4ed826468" + "f238a77bd894245d0918efc9ca84f945", + .m = "b13133a9ebe0645f987d170c077eea2a" + "a44e85c9ab10386d02867419a590cb18" + "2d9826a882306c212dbe75225adde23f" + "80f5b37ca75ed09df20fc277cc7fbbfa" + "c8d9ef37a50f6b68ea158f5447283618" + "e64e1426406d26ea85232afb22bf546c" + "75018c1c55cb84c374d58d9d44c0a13b" + "a88ac2e387765cb4c3269e3a983250fa", + }, + { + .i = "30ffa1876313a69de1e4e6ee132ea1d3" + "a3da32f3b56f5cfb11402b0ad517dce6" + "05cf8e91d69fa375dd887fa8507bd8a2" + "8b2d5ce745799126e86f416047709f93" + "f07fbd88918a047f13100ea71b1d48f6" + "fc6d12e5c917646df3041b302187af64" + "1eaedf4908abc36f12c204e1526a7d80" + "e96e302fb0779c28d7da607243732f26", + .a = "31157208bde6b85ebecaa63735947b3b" + "36fa351b5c47e9e1c40c947339b78bf9" + "6066e5dbe21bb42629e6fcdb81f5f88d" + "b590bfdd5f4c0a6a0c3fc6377e5c1fd8" + "235e46e291c688b6d6ecfb36604891c2" + "a7c9cbcc58c26e44b43beecb9c5044b5" + "8bb58e35de3cf1128f3c116534fe4e42" + "1a33f83603c3df1ae36ec88092f67f2a", + .m = "53408b23d6cb733e6c9bc3d1e2ea2286" + "a5c83cc4e3e7470f8af3a1d9f28727f5" + "b1f8ae348c1678f5d1105dc3edf2de64" + "e65b9c99545c47e64b770b17c8b4ef5c" + "f194b43a0538053e87a6b95ade1439ce" + "bf3d34c6aa72a11c1497f58f76011e16" + "c5be087936d88aba7a740113120e939e" + "27bd3ddcb6580c2841aa406566e33c35", + }, + { + .i = "87355002f305c81ba0dc97ca2234a2bc" + "02528cefde38b94ac5bd95efc7bf4c14" + "0899107fff47f0df9e3c6aa70017ebc9" + "0610a750f112cd4f475b9c76b204a953" + "444b4e7196ccf17e93fdaed160b7345c" + "a9b397eddf9446e8ea8ee3676102ce70" + "eaafbe9038a34639789e6f2f1e3f3526" + "38f2e8a8f5fc56aaea7ec705ee068dd5", + .a = "42a25d0bc96f71750f5ac8a51a1605a4" + "1b506cca51c9a7ecf80cad713e56f70f" + "1b4b6fa51cbb101f55fd74f318adefb3" + "af04e0c8a7e281055d5a40dd40913c0e" + "1211767c5be915972c73886106dc4932" + "5df6c2df49e9eea4536f0343a8e7d332" + "c6159e4f5bdb20d89f90e67597c4a2a6" + "32c31b2ef2534080a9ac61f52303990d", + .m = "d3d3f95d50570351528a76ab1e806bae" + "1968bd420899bdb3d87c823fac439a43" + "54c31f6c888c939784f18fe10a95e6d2" + "03b1901caa18937ba6f8be033af10c35" + "fc869cf3d16bef479f280f53b3499e64" + "5d0387554623207ca4989e5de00bfeaa" + "5e9ab56474fc60dd4967b100e0832eaa" + "f2fcb2ef82a181567057b880b3afef62", + }, + { + .i = "9b8c28a4", + .a = "135935f57", + .m = "c24242ff", + }, +}; + +#define N_MOD_INV_TESTS (sizeof(mod_inv_tests) / sizeof(mod_inv_tests[0])) + +static int +bn_mod_inverse_test(const struct mod_inv_test *test, BN_CTX *ctx, int flags) +{ + BIGNUM *i, *a, *m, *inv, *elt, *mod; + int failed_step; + int failed = 0; + + BN_CTX_start(ctx); + + if ((i = BN_CTX_get(ctx)) == NULL) + errx(1, "i = BN_CTX_get()"); + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "a = BN_CTX_get()"); + if ((m = BN_CTX_get(ctx)) == NULL) + errx(1, "m = BN_CTX_get()"); + if ((inv = BN_CTX_get(ctx)) == NULL) + errx(1, "inv = BN_CTX_get()"); + if ((elt = BN_CTX_get(ctx)) == NULL) + errx(1, "elt = BN_CTX_get()"); + if ((mod = BN_CTX_get(ctx)) == NULL) + errx(1, "mod = BN_CTX_get()"); + + BN_set_flags(i, flags); + BN_set_flags(a, flags); + BN_set_flags(m, flags); + BN_set_flags(inv, flags); + BN_set_flags(elt, flags); + BN_set_flags(mod, flags); + + if (BN_hex2bn(&i, test->i) == 0) + errx(1, "BN_hex2bn(%s)", test->i); + if (BN_hex2bn(&a, test->a) == 0) + errx(1, "BN_hex2bn(%s)", test->a); + if (BN_hex2bn(&m, test->m) == 0) + errx(1, "BN_hex2bn(%s)", test->m); + + if (BN_copy(elt, a) == NULL) + errx(1, "BN_copy(elt, a)"); + if (BN_copy(mod, m) == NULL) + errx(1, "BN_copy(mod, m)"); + + if (BN_mod_inverse(inv, elt, mod, ctx) == NULL) + errx(1, "BN_mod_inverse(inv, elt, mod)"); + + failed_step = BN_cmp(i, inv) != 0; + if (failed_step) + fprintf(stderr, "FAIL (simple), %x:\ni: %s\na: %s\nm: %s\n", + flags, test->i, test->a, test->m); + failed |= failed_step; + + if (BN_copy(elt, a) == NULL) + errx(1, "BN_copy(elt, a)"); + if (BN_copy(inv, m) == NULL) + errx(1, "BN_copy(inv, m)"); + + if (BN_mod_inverse(inv, elt, inv, ctx) == NULL) + errx(1, "BN_mod_inverse(inv, elt, inv)"); + failed_step = BN_cmp(i, inv) != 0; + if (failed_step) + fprintf(stderr, "FAIL (inv == mod), %x:\ni: %s\na: %s\nm: %s\n", + flags, test->i, test->a, test->m); + failed |= failed_step; + + if (BN_copy(inv, a) == NULL) + errx(1, "BN_copy(elt, a)"); + if (BN_copy(mod, m) == NULL) + errx(1, "BN_copy(inv, m)"); + + if (BN_mod_inverse(inv, inv, mod, ctx) == NULL) + errx(1, "BN_mod_inverse(inv, inv, mod)"); + failed_step = BN_cmp(i, inv) != 0; + if (failed_step) + fprintf(stderr, "FAIL (inv == elt), %x:\ni: %s\na: %s\nm: %s\n", + flags, test->i, test->a, test->m); + failed |= failed_step; + + BN_CTX_end(ctx); + + return failed; +} + +static int +test_bn_mod_inverse(void) +{ + BN_CTX *ctx; + size_t i; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + for (i = 0; i < N_MOD_INV_TESTS; i++) + failed |= bn_mod_inverse_test(&mod_inv_tests[i], ctx, 0); + + for (i = 0; i < N_MOD_INV_TESTS; i++) + failed |= bn_mod_inverse_test(&mod_inv_tests[i], ctx, + BN_FLG_CONSTTIME); + + BN_CTX_free(ctx); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= test_bn_mod_inverse(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_mod_sqrt.c b/Libraries/libressl/tests/bn_mod_sqrt.c new file mode 100644 index 000000000..7ab790513 --- /dev/null +++ b/Libraries/libressl/tests/bn_mod_sqrt.c @@ -0,0 +1,4533 @@ +/* $OpenBSD: bn_mod_sqrt.c,v 1.10 2023/04/11 10:10:52 tb Exp $ */ + +/* + * Copyright (c) 2022,2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +/* + * Test that .sqrt * .sqrt = .a (mod .p) where .p is a prime. If .sqrt is + * omitted, .a does not have a square root and BN_mod_sqrt() fails. + */ + +struct mod_sqrt_test { + const char *a; + const char *p; + const char *sqrt; +} mod_sqrt_test_data[] = { + { + .a = "0", + .p = "2", + .sqrt = "0", + }, + { + .a = "1", + .p = "2", + .sqrt = "1", + }, + { + .a = "23", + .p = "2", + .sqrt = "1", + }, + { + .a = "24", + .p = "2", + .sqrt = "0", + }, + { + .a = "1", + .p = "1", + }, + { + .a = "0", + .p = "17", + .sqrt = "0", + }, + { + .a = "1", + .p = "17", + .sqrt = "1", + }, + { + .a = "3", + .p = "17", + .sqrt = "7", + }, + + /* + * Test cases resulting in an infinite loop before bn_sqrt.c r1.10. + */ + + { + .a = "20a7ee", + .p = "460201", /* 460201 == 4D5 * E7D */ + }, + { + .a = "65bebdb00a96fc814ec44b81f98b59fba3c30203928fa521" + "4c51e0a97091645280c947b005847f239758482b9bfc45b0" + "66fde340d1fe32fc9c1bf02e1b2d0ed", + .p = "9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e2" + "46b41c32f71e951f", + }, + + /* + * p = 3 (mod 4) + */ + + { + .a = "c3978f75d6c2908ae3e9a714ad3d09b13031868dfc5873d7" + "bd9a9691f3b45", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "37f112813516c2563028c63a687d38b", + }, + { + .a = "1730fbcd9e78e1e786284f708aaa599ffa0d744ff223e3f7" + "ac1faac3d7d2a45e", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "4d0d44591c8c80bf1314762cf73c251f", + }, + { + .a = "1fd006456db047a16b32a48235749b8b627be66a5f9e05d7" + "d1857114baa9ff1", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "168fa1c701b579827436c8abc65bae54", + }, + { + .a = "216c1526fc9afa21788f84ff1bba10e8bccd39fc60978cdd" + "f89087d66dffdd35", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "5c7fc4b52edf59c44b0916cb134e852a", + }, + { + .a = "1cd486f29a9632ef276d10bb9754aae1b2723163a1a42552" + "4e514dd9b40e9b6e", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "55e8f564c1dd1455fea889203ae81c48", + }, + { + .a = "7272d05925151c067fcd3fb44d4d4908c9104691e3fa82a5" + "d2ed4a58479020f", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "2acad049c45fe1bf4307bd7b962dbd7d", + }, + { + .a = "6d12f19be6960d04f651867737a0e9a0b16e614cc5eb6ffe" + "cc6c911d3c9b260", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "29c68091856db1e3f6d63eaa341cbecd", + }, + { + .a = "23681522f2ab9e0e7cf34243e092dd8bada26d18dc1211fc" + "d9d49f65569cd179", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "5f349a0ac98fd5c7b575bc9ff05482cf", + }, + { + .a = "3218f7cc3f00df33b1279c2f5386f1f1837db81cf3a69052" + "d23f6220f1b43b4b", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "713f53f8fc8038dc2b8ad3adf2bb6a3a", + }, + { + .a = "1d1cd78fc48830494c54113173d636119286e7bd0bd7d627" + "21063f88256868fc", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + .sqrt = "565470af11ec50128e82606f07bd3baf", + }, + { + .a = "3a9de6e9da1e02f6e7e9b4f1556a0bcd1072d065", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + }, + { + .a = "8bdbc0195d2af794784a8b6f7b63d9fce9fe7a29", + .p = "e9f638f327f3ca2a2928f5451bb3b6ff", + }, + { + .a = "262b386d4027cc114b4bb73ea745650e6e4a22ef314e9e03" + "486f3fa7d721b15e", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "62d977c29cfede2669e617851d1db12b", + }, + { + .a = "172020616142af15b1d55675aae05601206663c1749e3753" + "f1b80696d62ece4", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "133c4f98c82d077789f01c232eca5692", + }, + { + .a = "199daf5ed7d4c07f9c22af215c32fc024cc609df92135d9e" + "360076ae2baf943b", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "50fac2c950af164b0bd7d9b5cf9600ae", + }, + { + .a = "15b01b8d11211643af99034b3e902305228c903653baea22" + "4c4896949b037800", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "4a8330fc5c8164f858e5cf5028ba69da", + }, + { + .a = "a326d1821af01d2c4251d84807980a9942b3ecab8dfe0fe9" + "9b4fd27c47de741", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "3317a2ea8c32838e0c8ac6b0838b2518", + }, + { + .a = "1213f38d2c4444e54ec1966acd28c568ad273a1d8337154e" + "3e2a137c372624fd", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "44076fb0b477e1a29315aabc95dafe43", + }, + { + .a = "399cc2207e49304d48c5ae4e32d3db8676fd16bd79ad98e6" + "dc001fb405ef6f0", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "1e5c722148e8939872584ca89e01237d", + }, + { + .a = "2faee914d3da21f1a5e82303f945593cbbb8bfc94315cb32" + "5faca3f8877b23a", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "1b9f0867a249063caf36bc28b68b5d54", + }, + { + .a = "17f6c4ba6517237a5ceaaa186400a0e5a9657db2fd863628" + "d6ac524027287880", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "4e5323a7cda4e3037d258f1436e3b964", + }, + { + .a = "1973a0acd4be1a2115b396969421d78bcd32f2cc9b31b1a7" + "3e876b0926f34142", + .p = "e36058b270896dd9380d4d693a2593eb", + .sqrt = "50b82d13351cca9addb25052c4d9bead", + }, + { + .a = "2768ea8c5bc132c003b0451a9e356ef1b9821646", + .p = "e36058b270896dd9380d4d693a2593eb", + }, + { + .a = "ae5450500ae2fdd7d07df1c46337e3de89730ec2", + .p = "e36058b270896dd9380d4d693a2593eb", + }, + { + .a = "15a78159fcd81c039d997cb2266513d677a36856756ccebd" + "7942fe063a99a42b", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "4a746881ec00b6cb8e637daf97c7f7d1", + }, + { + .a = "17ec38e2fbb20de601b699aab3a420d174a2c541938ea004" + "a65f97bc3713a273", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "4e41e59e7b80b061ae255fc98748d2d7", + }, + { + .a = "f8327d6ecd54a96d4cb2d1b5ac4be958a1073fd3c9216f18" + "4a2e1b65c80c28a", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "3f04610bae1450420bc38988dfd57fa4", + }, + { + .a = "1c8ad905faae5434f6070960507696b2879d5e7891d3073f" + "66a96bdf74c1a56c", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "557ae7ee14896190564703f963bb6516", + }, + { + .a = "21bbfe1ed600301ead629d7b87e11c5403bd16dd9c28aaca" + "03fffbf6597c1f47", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "5cee17372e523911e1a0f914db42230d", + }, + { + .a = "250de7ab5e802b1b399e8c3333b20d18dbe433ea28c333a2" + "0a9db317c5c96f2f", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "616546bc036efa2a5a30d35c1cb32ec9", + }, + { + .a = "20ae8c29c0aa7030c63efd48fb9f371f5a15fb1918859d74" + "d91a160d4533c73", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "16de015e7590bb75c7f9a0d719368285", + }, + { + .a = "a9e4dd7fea7f671c392560cc6abd8241ed88655d4adc4907" + "1b7f2151d7931f", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "d08ca78515bb8670926a12f02ae69fa", + }, + { + .a = "1a0126ea28387c8caf8a1b0b8440969407279c759673171b" + "80ba9a42281cadbc", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "5197642a69ddeb7c366b25a634a6c33b", + }, + { + .a = "52006bab38c980f87129d9d1b0d7a9559b0a8f304ddefee1" + "81b9d2874d12cbb", + .p = "c3b321a39659c8c574148821cc2f4c23", + .sqrt = "2438cea95ea42a348190d5d004ca0f6f", + }, + { + .a = "43e921a1d7d2706dc74144886815c02719a6e3c9", + .p = "c3b321a39659c8c574148821cc2f4c23", + }, + { + .a = "fe62c1aaa54f6abba02bf1add8118c2cc57ae9c", + .p = "c3b321a39659c8c574148821cc2f4c23", + }, + { + .a = "1c70683aeb6b0025b8509da40e743f4f98f74f8b81dcbd2f" + "b83c72059f45d986", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "555346fcb482ad8a501120ab9176fece", + }, + { + .a = "c30e49d25c864756e6432366defb5a7cd8cb3f18eda3cde2" + "6c88aec3a0ae004", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "37dd6d96b275bff258b4fde3321a9217", + }, + { + .a = "331e18f1f1ed03ac53c78f2d98bf9d2757127d3c25ec0cdb" + "f02882cb70595f", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "7264fcc091e4523541e8f0ee130571e", + }, + { + .a = "3c9c518aec7a7b502e49dca16acb91f9f1d57c7ca69dd199" + "d55212b710a1f", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "1f242105b1371a672211389a0b02ae5", + }, + { + .a = "a3c104e9871de2bf7e2f3e1f2e072f1d869a72935928e293" + "627f04c0fe9567", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "ccbf0901efa15d8d0d8758a57e2ab4f", + }, + { + .a = "c60bb5e0a48db72bc0cebe9455e9f94a08febd08d634591a" + "cdd1a7433eeffd9", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "384a9f1f39e3a04e3ec7e3b99cdf123b", + }, + { + .a = "22d9c628e23c14d45eaac1bb5c563cb4718556d31798e754" + "bb7f81a3c6b911d", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "179d2110991a0f85ad40927cb08a9c15", + }, + { + .a = "20354be2a9992a4f192687ab68025fe85b9724faea87f37d" + "39a43d26b71c4ee", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "16b36e6bffa91122c3615aa277cc249c", + }, + { + .a = "3ad95db7205d9413ed31b2145c4b368db365e949e54c4dbf" + "0acaef2bfb54304", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "1eaf6d6949ddfe0d9b915b2c9f472f78", + }, + { + .a = "1aa4354b3a677970dfccafe223df531fd9c753f91d802ba4" + "35362bf5ac66c11e", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + .sqrt = "5295a52e193ac5011d91f2bbeef1691e", + }, + { + .a = "f48312e68f2a47df61bff728ac986ec049c283", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + }, + { + .a = "897e77b7f767ac6a99d4be1ac2a4e52153884672", + .p = "c3c9132a60dcb07a29ea04ce12f10af7", + }, + { + .a = "105505111e51c9a73001339ccff3554c2bdd879baa46210e" + "1df8f73b70527a97", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "40a92a8fcac919aa46ee0ea2a6ccdc66", + }, + { + .a = "330b1cce03412398a36967102c7cf6e47534b630c60ceb26" + "04bf2e3842bb994", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "1c93ef2631f86d57ebc0c843e2082fe7", + }, + { + .a = "1cfe5a70784209591d7ced341bba4484e1603226449e52b0" + "a16d9afa9aa1fc0e", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "56273048848c7784c2589e3d91dbceaf", + }, + { + .a = "7baa8b5f02cdd3451df420b504bd8e16c738a07e7f9cb987" + "9944b99e1496e7d", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "2c7b6c3c5e43c0f2acd1ebfee4e234ca", + }, + { + .a = "608d55d43908ea7ea3aaf4ca05d5a8321d55cbe09b565e4c" + "163412e45c62386", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "274deb2741766cffb60a517e8f3fadbc", + }, + { + .a = "526ebff9146c9f50021f56304120d8f9b09ce515d0066346" + "8f20115421f024", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "91449230a1a386e9c1093ee0cdbba09", + }, + { + .a = "2a20b65b2a28f1b3c9e1d876d86a5f5d87d94421ddf7ef69" + "1a71f07955a09a8b", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "67d976d658fd3cbd77c1474a0906404c", + }, + { + .a = "1e083613b3a5b9f547972034d37a1f6f42733731dabbe889" + "99b5c0f50a7dca82", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "57aeb4be88de6be03a7a453a7ba5b50f", + }, + { + .a = "11d00fbce28d46f526bb51246a1cdd3c3b2d8bb83725a83a" + "564f6a67d23a0ff", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "10e1ce79ade89e839f3f0f29d72eea8a", + }, + { + .a = "3285f0c5eb6ff451af071089be87c1a7fe564e1e8de5911f" + "fe390fda34c8799e", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + .sqrt = "71ba3c5d0d93cb2da4a8242269f8f349", + }, + { + .a = "d0d1f950ec1b85862398f403e8768936ea03cf1d", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + }, + { + .a = "e5a7a57d99efdd8965c84e10b83df9d0871cc1e", + .p = "e84fd723abb1fc0208ad23dfe5986c97", + }, + { + .a = "102ce98ef5044dc2f1afa2e6600008198b5329aa0757d239" + "3f6860f7e252f5db", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "4059946cd6922b83dd0425fc4acb6651", + }, + { + .a = "132922d347e42176551bcf327fcb764380a996142bcec3a7" + "e5c55f822c53e99b", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "4609639f50503b898f97fcbce84bd069", + }, + { + .a = "1b1be4c1234332b5ac8494697d1de921f851d9c2b4557931" + "125b94f68229dbc1", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "534e5790710771e405fa386a75fddcee", + }, + { + .a = "272ac5b81ce6e27b4b5aac25ca34abfe8725d28f7f67c8d1" + "9d16d2fdbdadf2d5", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "64223ee58ff69643ec0b4cabda6fa41b", + }, + { + .a = "77a6fa94c13869d5cc265d70edc83bfed1d0e1b0ac8b89ae" + "e56580f73696b4", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "af045f74c28b50570b7d2ed8a53705c", + }, + { + .a = "207b2287539f1489a52c29d82415be4d2dbcc256c8f58f51" + "697dacc3ea2c091c", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "5b2ff6ea861f522cbe4aeda70ec954b3", + }, + { + .a = "a6322e0055de7fd226828206a28c61091a8221449c39bbd1" + "969e9cdb1cbd7b3", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "33911aaca827e264d82da9b63fe25c98", + }, + { + .a = "5c0625d646c4183b59ccea7fb137399802389d925c999c8f" + "34700cb1edd482f", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "265f251061587b79dc4bb3e2dbbddedc", + }, + { + .a = "ab2267257b8fb94428bfa7782d114a8189ad9188af7c35aa" + "2f58851104a3c3", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "d14f31646a99511d5df395ee0c6f23b", + }, + { + .a = "2ccb942f89fcd0f396e6f60dbf26faba338a9f42a08ae83a" + "8349881f4d2c9707", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + .sqrt = "6b1637561bc8e2b7c6797ff14898b78a", + }, + { + .a = "49e501a514b25ec54e97e0643fef58c2331a9e0", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + }, + { + .a = "bda6072e85a4703a58766eb147beca3a9e407324", + .p = "dfcf17789278b6e9cafdb4beaf2cfcfb", + }, + { + .a = "e505c659e3649ac1974baa7ecf478c9c46d988149506c124" + "f528a8a1da13bff", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "3c88b1ef1aa5441216ef7c2457edfb52", + }, + { + .a = "88db3bfef58b46e08c36ddcc96ff4588a8c10311ddac5620" + "682e92351245c4", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "bb2d50c0a9fc425d2f093f5e9882845", + }, + { + .a = "eccf316a16ed9aa505b82e99a9c089513f3f5465178c0595" + "5e1c8e7138da57b", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "3d8df00919e543a5f782cec0e2833eba", + }, + { + .a = "23a72d78c1d23f89f21c9aff268ada5431568d136b8980cf" + "cc72b27c7ab4e93b", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "5f89488ed8134af87ee97152df43de42", + }, + { + .a = "1863d4f3fbbcc5ad3cf555c22d5a34045e91039acfe30365" + "4fce949c31d5aba", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "13c1259e5a87acded9d3999bdd6e7cae", + }, + { + .a = "be8a91ec3aed7e990a3a01e12572b1bcf131a6dd93d46e4f" + "c6719ec22197d0", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "dcdbd473cf66c3ffb560ff8fb1411d5", + }, + { + .a = "b268924f724222d8df0d48f502c6bd33b406742efe65b153" + "3f9c34d30819ff5", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "356d87ec862cd46e67997119202dd092", + }, + { + .a = "c860b34209538b9b8efbb4bb51a70a22c1003dec12e5474d" + "2f061f29b1c1c0d", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "389f374589c29d78ffd4fddfcbc9fdad", + }, + { + .a = "857bb672df76352d6ed3259cdf20a65d941b7c3f2ea07a19" + "c513605e4b502bb", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "2e36c7760d3a9ab2d437ba376940b71c", + }, + { + .a = "248ebd6e07fabf93019b22ea1d1ab4d0fc9eba3d780d7307" + "429a57739066844b", + .p = "dfe11f28376b5562def9fbecfa68ca47", + .sqrt = "60bd96b2e42a4ba4e1c5529dbc4b31f9", + }, + { + .a = "7f0b66aca27105e059b111992986f46a71b25c9a", + .p = "dfe11f28376b5562def9fbecfa68ca47", + }, + { + .a = "a964ffcec8532b0209457c1eda9988e40fe37482", + .p = "dfe11f28376b5562def9fbecfa68ca47", + }, + { + .a = "12dc5769139571557c0af544a1eca5bec5f9b3cf70cc87d2" + "d48107c5b4d20d98", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "457c7c100eaa11609392f6af4fbdc07f", + }, + { + .a = "10d05ec3bd88a33465a1c5d9d467b587c2ea46f93a369223" + "29d1893adf131b9d", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "419b922a2d4e0fdb18d0e31a130a3b57", + }, + { + .a = "34d65ba3637b3b9d46a7d1a3558d7e3e946761ae0b8e4db5" + "1c4b9b6bdfde0492", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "744d88ffa822b5d259c4fd138e489067", + }, + { + .a = "292612ef1616fff0453f2e66580cffc763dad52f12ec5c37" + "6246c4d8f69c0062", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "66a2b919787e57087ca4fd47b6ad37cd", + }, + { + .a = "3a7ec6f19e0d9a4cca6f9bd8e2d126519c9370a88fe61879" + "a0ccef7a6d5ccb23", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "7a5f18c79265b00cbaedc8bbef8cc26d", + }, + { + .a = "b2f41bfdd2c86f5115724830a7dff681ad4f06198f7c989a" + "b8ed9912f690fe7", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "3582689e0e3d046dae757b3e395f2a09", + }, + { + .a = "12b9a1b6c4f1bd7888f206445c91c722219e1ced30bb2ee8" + "5eb1a511347c430b", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "453c6e4824654ae983a123749adf41e1", + }, + { + .a = "4a7c46417c3fefe77ee50565fe79aaee7886e1b708eebba8" + "84fd59d616e1c8", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "8a16821ca0a63ff8b03b4b1a6afc5b5", + }, + { + .a = "70b12a7a215f436eac38a7b2e9bdeae47f4e313c9622bbf0" + "ddc4ae3cdd48ef6", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "2a766d514a8eeb2518e55d56d435b5b3", + }, + { + .a = "1127295ddd79b3dc0d36759e8475e793c903136b3d779ba4" + "a4b40eaaa2510cec", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + .sqrt = "42440e1bdce37bc4099b36183270b686", + }, + { + .a = "780039d1fb613f1654993c81ebce1000256ec462", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + }, + { + .a = "55f30fcaf020db602e2db2bed4ed2cdd061683d9", + .p = "fddaa93d6ef55fe16d65f36467751ff3", + }, + { + .a = "297aa82c160b09d1551443f560c355085c075871687b98af" + "3b2028156e24fa4b", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "670bff83e4425dbc782a92735135b8c7", + }, + { + .a = "aa4b8a060fcf9f4adb09ccd99c58a0d71023319539618b60" + "8be198e4e19898", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "d0cba27ce684c00b2b22b661305ab22", + }, + { + .a = "4307405764f9c05f6b8a433fd442e97b20b6dd725a0c5488" + "fc0947daf6daecc", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "20bf92a53eeb49fc15a28fa47156c7e1", + }, + { + .a = "25e25f800892a56195c46c027eeab26ec820354e889a8057" + "a46da80343dfb960", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "627af6200712b962235b167671d6859f", + }, + { + .a = "1ee2add6b546b09bfa3acaa640feff18f0a844638a3e526e" + "a9c22ff1657802e0", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "58eb64eee715b3535a68d8d4f4c389c9", + }, + { + .a = "22c0b5472fee1bb7876e8612b63676678f0815a5a5984718" + "d44000eab1632e6", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "1794a1976ec2bb6f199e9e833c9bc7c9", + }, + { + .a = "c31233d4d15b615d95bf209890c2bc3446800af361aa69af" + "3d65390eb64b01b", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "37ddfd137bf27b3ce0f21c86c844cdf4", + }, + { + .a = "12977980fc461d4cf8f61b364e59783c589b5ff4dbb0f67d" + "5ef13413dcf58afd", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "44fd2b8b167f4c5a14cabe9344b2e337", + }, + { + .a = "3ae43a729fe988282a2a3f2e821aa58409784a661741bf05" + "237563c1025edef", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "1eb2423fde03aed73f280a8500172693", + }, + { + .a = "25988dd5cd06919bd5cb184431955d865033c58c65466597" + "fcb737ac19f27492", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + .sqrt = "621ad4ed8769873118ac6279833549c3", + }, + { + .a = "b1216cf6c24d756b71dc6cf2c88becfb95bdaf4e", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + }, + { + .a = "15ad69f58f2c2f4e820e73120f229c70e4facc3", + .p = "db9874b4d0f7b1cfcb69168102ef111f", + }, + { + .a = "aa9714b318b654674644c3daac851bbd4f39d01dfd89e3af" + "8e099d3b8903329", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "343e7b2f7e303f97e6dc9db20894ac1d", + }, + { + .a = "40597523833f21d1fee6c963939dd73397e2a2352db1b049" + "1b0f8fd50b1bdd5", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "2016557da8396370d7a7c3d9a947e666", + }, + { + .a = "10ddb7215a1e681614b6d7324b92b24fc715ed863d5038be" + "05d740824a0b3114", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "41b5964db90af860d17fbbcdd4afcc55", + }, + { + .a = "1c36ce697e95d06ec63af3b82a6c2d8e9622c2c33f3f87ea" + "ac3e75f2abef8ce", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "153f2c9007b549d8e802a903ffd2171a", + }, + { + .a = "35a13697c77f9629ef70d36fae88659d39b4048dc67828bc" + "4425d1cb41edbbc", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "1d4afd8ce507d6950e0b714c27e5e4c2", + }, + { + .a = "1886d861ea3d46d0edb942a01397780a84f5ce199e6352d7" + "42ed995a94302701", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "4f3d39e8213df646cee264182fef1f47", + }, + { + .a = "143c8b6264d12017961d3829d3aa0088ce4e8c6261a39e68" + "0ea5b276d427e465", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "47f9db1679dd06966c91bb7ee81f22c3", + }, + { + .a = "121134f6cb228fafbd45a934db668a78d27aa12fb87ab25b" + "e714ec93d05137a5", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "4402458a9a80428c77dda8334ff41f74", + }, + { + .a = "1ba2eabc24b78ce8ed873c0aba09443e5f02b98858c0a09a" + "bfdb6d4da798abc3", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "541cce775b911592fb759167755743f3", + }, + { + .a = "e58fe89a18f8200b4aa289446b6de2ae4e4b0ad911e59cf0" + "1e0a0b32b609141", + .p = "cd1f525d3eb5172c591bb299f52ba447", + .sqrt = "3c9af08f9f626f41c7ebe2f32875497a", + }, + { + .a = "b15263e714de941bb702cf71e0db12613a383de7", + .p = "cd1f525d3eb5172c591bb299f52ba447", + }, + { + .a = "5deae3520dc28e0e3bdee22fd91a66dad70b41c2", + .p = "cd1f525d3eb5172c591bb299f52ba447", + }, + + /* + * p = 5 (mod 8) + */ + + { + .a = "495114892a3986a8b4a6e05bacc0e293421716b0c4557330" + "0cf4243f784e33d", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "224004cbf31a7c967d53819764506317", + }, + { + .a = "3f7683a65a7b5ab1134a944cb831bb8a0f9d9835a45d230b" + "d3c6b8bb3902c1", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "7f7639804be2c91aed7cdb70e1af18e", + }, + { + .a = "9b044b4d448169fbb7da81261016b997ff24b3921b03dfb1" + "d6dc5b1b28de2f1", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "31cd63124ff7c306503ea3a2437bdbb0", + }, + { + .a = "128b830f7eed54c5b7cfeced129aa45ad857d6e3d9f2a70e" + "8cbf6097607ba1b0", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "44e6f601015c26b885d7cd32663bc970", + }, + { + .a = "1883fe98086c0821ff2858347227720a967a2c468a8ad9ab" + "018257dd49ec8a18", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "4f389ee648fb323847e453c77db0a364", + }, + { + .a = "23ab14a89775f60cc6d8c397711429e9aae1fa59b637d356" + "f7a8fbfe6b5379ef", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "5f8e83217d7de9d61afc3edb95912f2f", + }, + { + .a = "7c1252084891eb7e2b7d1c5ff6102949bf2b598a6ee05a0d" + "03ec0471f963fbd", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "2c8e124682ee306b16eebb31464c868f", + }, + { + .a = "824e2173788853d264c075c287c558407ab196193af02427" + "b7f7be09945bfcc", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "2da917e56d3146f4d6e496bcfb50509d", + }, + { + .a = "506661349ca4c1c1d32c030ebaec699f584e537fd561c5a5" + "40bb2339775ad6", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "8f7731dd48b0165519d0dfaf629cd81", + }, + { + .a = "d21846fcb456b5cc76e2e9e95c72cd8d10537f2f91b7817c" + "06bb2d946f9e1fd", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + .sqrt = "39fa851e5ff14e140a6f98124bcbf2bf", + }, + { + .a = "3727e2a9498ef20c8a6f0d2f8de533d664bd8f2a", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + }, + { + .a = "2eef7eeaf13b6173f9c68f71cb3a83621672810b", + .p = "c9b4dee4aa04ce668cedd3d2bb8395fd", + }, + { + .a = "7695ae6d4aa3f51985234f35cded2e378912e848d1e08bb9" + "921dce2b937aa8", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "ae3c0c05a16cb2ad83b0dde2f46d15d", + }, + { + .a = "6932c69d54861b47fe83f8531f19d3af58d3b85737e1b540" + "e2f434b05eb4ffa", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "2906c888cd5fe48ccca5c925944559bb", + }, + { + .a = "22894e6a44618c1a14c10695cf41b5083f7f6d8a34c58309" + "9334b3ec5a53a6de", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "5e07397aa72c55103caf053fd20540c1", + }, + { + .a = "d5189535263311b02c0b50f869524ae54ff3b493ccc15952" + "330792e5676feac", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "3a642808df53bce255b9d4ec52316a36", + }, + { + .a = "462df11d760ac7ba6320dce59dd012a5a13e81e93a4a23a3" + "2c2bb60314bc564", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "21825fb45eaf1c3cf86b8b6ec3f3e4a6", + }, + { + .a = "1e2fbc91cf281ba1a838e600f8a7348b03daa0d6dc5ceb82" + "788539919839184d", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "57e854eb15ea535a9210c70e2b1d0397", + }, + { + .a = "1ac89e6b45c1f3d3888411a374f291e52af2abfbd7dcf23d" + "e8024623ace61a1c", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "52ce01029221f38a79750615d89c83e2", + }, + { + .a = "408ada83c389027bb76db1c90279ead9b9855b604403ef4b" + "b2821f807a2f5dc", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "2022a3e12dff46cfd45e4b670e14f5c0", + }, + { + .a = "17157376051a1da95618c37fa6a1febd48cbc52dcc3150eb" + "c590f93be06991e8", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "4cdf79e5c4a5e9413612c09652b60588", + }, + { + .a = "c43c6a117ba38669cadfebc127dcc99a3292fe772077b322" + "d47c1f62bc8ed29", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + .sqrt = "3808a0c60e94e3bf5453c16c14b6e936", + }, + { + .a = "7899729705aaa981ccd5b22ca3b9384c957e6d8", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + }, + { + .a = "aa82a2131cf182e08daa64945131572020110835", + .p = "c7ff289dd9db4bc68a80d6d0837f5195", + }, + { + .a = "3b2c1fa25b77539a5adbc8daaaf3afb1660be07651f3f0e1" + "77331853bcd49b21", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "7b13e508e84efddeb4eeae18144046db", + }, + { + .a = "3b98fb79556ae299a2d9349f8e9544fe7c3fc9b0a7265ec4" + "00dfd31c139c1869", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "7b84e784f47a5586e6c3cb970bc98a03", + }, + { + .a = "149c120dc19610055d7f0ba9d007f458c558c68a40acd0a6" + "00bb40d2650ee1f4", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "48a2f5e66dc7919bd19d00549d177c3c", + }, + { + .a = "13c3763c5d74356dafe968f30e1d9a4f8e6c63c6101a02ea" + "ec1cec8db01798bc", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "472140c031a001ef403cb71274a91830", + }, + { + .a = "8353728f214d74a60f740e3098dc80c8bf3b3878499b71e7" + "06ded8c999a5c68", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "2dd6c9cf6caa11c9051d6823a4775155", + }, + { + .a = "5e387c6058eeb03b33b59fce405c6278d7e373083fe3ea9c" + "f1d64e8be3f58e7", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "26d3b19397db8053cf072f385f71f81e", + }, + { + .a = "22eca556be0a5ee93e1bae520342f32331727c75dfca6082" + "3aac96741594cd18", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "5e8e13ba599582dc056f0896c4cbae8a", + }, + { + .a = "308e76f45903562ae8c4a56fd9e181cf2b802586383cc133" + "7a186fe1d79c8726", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "6f7df34d1556913182384ed31aae29eb", + }, + { + .a = "9b572efdd07a8a9cc36f20d040d92f3a90fd87a4e0aa651a" + "f71361589d360bf", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "31dab1ec08d2030a50cae92533215502", + }, + { + .a = "2f720cb02294a4b8b69f41cf5f7071f7010f10038f1e603b" + "1394fdb65d388d5", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + .sqrt = "1b8d622e0887aadbf3113f7e9c923373", + }, + { + .a = "dd9e74c33015c49e90c1b54e29a123bb759e77f0", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + }, + { + .a = "da290f4e04f8dfc3c07e43dbb7121b91ee2ee29d", + .p = "fc5054f3123deeb6ca2d35c77263c08d", + }, + { + .a = "111aa51f58dcaae1d55a7f50cdb2e15da632407008ca0cc3" + "7ce53d6f53ea2a", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "422bdc54895f3fbab7fdc8e8bfe7edb", + }, + { + .a = "19381515e93479f7e5d4ce92ce1ee883ed9f50e5802d120d" + "b390d62df8736b6", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "1416624ee1b331632ede4da5a72c679f", + }, + { + .a = "605525d619104f91c7df399e6d68b960ff69d810ae481754" + "5bfa65a00d67dea", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "274279c61f21177b40e140015ac3b690", + }, + { + .a = "e59076d17860b58cf92dc7edbba52d72c3cfa5baf141c600" + "8bf897afc3a0d0e", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "3c9b0355733638764f3529906f702f46", + }, + { + .a = "1b99dda206922285a173c2e05547e366061c908b7a23af82" + "fe78a3f21c6917", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "540f073d38ac532e5382f9afc215523", + }, + { + .a = "543e02b3d7c30e8ff3a141aaf6a150f01b9874b033344ce8" + "348ddbff79aca9", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "92da8c6295ced9d22457eff8df968bb", + }, + { + .a = "2e6d5bf0b9d6ba16af020be648c01aa77b2717ce9262f23e" + "ebf2e2dfb11fd125", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "6d051e57847d8f83e8e003e833c514ca", + }, + { + .a = "179d7fc2e81864cbd54dfa14306c06fcecfc65ed159f1f4b" + "dbd4ba616ceb064e", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "4dc0b7fd597e46fdffe17ed9b8928355", + }, + { + .a = "3275ac40f4e32e5343d33881d4b3994820572bb121ece88e" + "c7995e668017ef56", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "71a7ebbb86f85e267d71b796b233b773", + }, + { + .a = "34d9fd618cd45afdbe87718ad19d8377d17619376bdaecc0" + "ddb8695e035846a", + .p = "e7616abd0448ce8b22a99105ef99f00d", + .sqrt = "1d14620b9c69abad878797bfb2fa3bd4", + }, + { + .a = "e34380a3d760ab9415cd794c58569e3687568038", + .p = "e7616abd0448ce8b22a99105ef99f00d", + }, + { + .a = "4e3af908dac0c11da23d73e9b1f2d6d3d5e94906", + .p = "e7616abd0448ce8b22a99105ef99f00d", + }, + { + .a = "6ea9d07bd5e2ce59ce999d82dde6e42cfc90ba60f0b70c17" + "e6e4cef1c8d5fa8", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "2a1422e259229156026fe1ecaecb2026", + }, + { + .a = "171dc2573d5011c8c9254adeef55f0ef572af94fa89bd329" + "d0f02d2f6fa916db", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "4ced4e16d63f14de9e77c320d7e61dba", + }, + { + .a = "5da9be4927acc2a00f8eb2bd9007b7ea51c77e6440a1e020" + "75fbc67618e9de8", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "26b63d2d91137017b1e5e0d3d15210e1", + }, + { + .a = "d32669bc65290f5b1fac5c04bcc3de52f582fb9dc22007f4" + "776a2fc05472435", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "3a1fbf4661e72f835fc36be9075f43c9", + }, + { + .a = "89cb34dafdb05e01f54169143a88b7a9a4201dd66f12b957" + "6703e52cc176861", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "2ef448e5f6e4c92d59db78cde0a066f1", + }, + { + .a = "5b8674a77fced1b08dd2376af9a96d4c4824786104ebf9f0" + "7fcc2ddd3ab0201", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "26447c86fefaa791bf1d1c15d4607fc8", + }, + { + .a = "c54d49d0b63981375c4a9129ed4647a7e8a251045a244324" + "fd58d42baa8355a", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "382f88a82f4719b32f2021eb845f7045", + }, + { + .a = "2256345a067ee92e441731a5007b08461aa7d2adef64664d" + "a92c40b7d79a9dc9", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "5dc18f24fe2dd7bcf37ae865c9b48122", + }, + { + .a = "36da4779faa88d91d59824acd9b9bd00181aa5c7cfdf8243" + "7eb2544592c91c8", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "1da00204dad7da917cb1719a9c826cd0", + }, + { + .a = "98f15c0e715dffc5a54dccee9c598314fdee262cee747268" + "2f585b7ff248ff8", + .p = "c039e7b229cc3b7792b37ed541001005", + .sqrt = "3177d023e1f4310118c00c362b422bf1", + }, + { + .a = "5bf6cf4b386b5de218728434e62fd0d802008bdf", + .p = "c039e7b229cc3b7792b37ed541001005", + }, + { + .a = "13c22cf6c3c54b75f2c07830cf50777a5add43bf", + .p = "c039e7b229cc3b7792b37ed541001005", + }, + { + .a = "8ea35eb078a0033844e5869778d9f581007c9c221338d1f6" + "4e09c528ac24747", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "2fc5c1c76763b2843384eaa1609285ce", + }, + { + .a = "274714f1060ba85737c3803bb6192cef8f1478448e0f3662" + "ad57fa2a6cbd13ff", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "6446686b34424dbb056c499ee47d6af8", + }, + { + .a = "1be91ab1e867e7c0ff4b9e039fe3a33515ade6590baba482" + "6d6ca8347f89082c", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "54875a1b0c7063fb4597f579a852bbce", + }, + { + .a = "b436cb73a7318ec101548cd18d97e350873563b145312a88" + "6c7e539ebcaa135", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "35b2914a881429245dfb9adaff55f249", + }, + { + .a = "485f18975843b575318dc7086eb45bdfdc54a8aed83b4189" + "934d2546fe231d7", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "2207504b2e026ad2c0754aadad5d322c", + }, + { + .a = "607d62025340dee0adc2de94c8dab17eb912c5cc8cc1589b" + "d227218c5ea6759", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "274aabccb65a4996273ebc7d1941981f", + }, + { + .a = "48a5421193d567325bc1d25965ac555d9384efa37843d840" + "b66b0c104f7618c", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "2217cafc385b2089617782b01c3cc88e", + }, + { + .a = "1e496e33fb89a64d8fcc3591304b05f7fddf4cfdb5a0986a" + "188e0e4e49f85e14", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "580db67fe95fbe4f965c678c3e80879d", + }, + { + .a = "ec4337ba1339cd0bf3374832526038121727b4bb78b6fd4a" + "11300ba5506612", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "f5eef0b27ded737243fe13eace325aa", + }, + { + .a = "e826c96625f199c8db32619c61d175f2255aeeefa9183a42" + "63553a1f3f0f29d", + .p = "d9c22e349011878f87754687ee523365", + .sqrt = "3cf232080315a091c876b8cfea4160d6", + }, + { + .a = "c7831203f6b08d222b1b622a7cbbee77237fc689", + .p = "d9c22e349011878f87754687ee523365", + }, + { + .a = "bb13fd167d0ceec6baf65d67537d685c82c65c8b", + .p = "d9c22e349011878f87754687ee523365", + }, + { + .a = "bd8c5e76b6e2746d4de3467b5c65169c3f62317dc4595bc6" + "dd1c6a1693e07f8", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "37121413fdc699e9e61ca1893700c75a", + }, + { + .a = "e24e97d56b8a5982465b48fd71f816623028b66ac9b2070f" + "ce474f541473e13", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "3c2c8c3d819b3b178474394684d256d6", + }, + { + .a = "eb5e5424a250f5921315b3b80e611a8bb31fe0ca502b3673" + "50dfb435d244a00", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "3d5decb13bdf112d2a7b8f7eb0499b9f", + }, + { + .a = "6974a858d34d14491e668420065eb1fb7c46a76464e66799" + "af8b6f21b43b7f8", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "29139f465027081bf12280ef60322f91", + }, + { + .a = "3534a02b5daf8f7448ba228e933b98fc0a237e3b6fa34a60" + "78e1a8788f7669", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "74b51a89bdf7e7f1bb04c8cc07d506b", + }, + { + .a = "279ffd9d740d5de93484de00ca0b02f876c2f8a49548fa4e" + "a16bb9b5a764f63f", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "64b7a63b5b33224381ee8dc1e0bed0da", + }, + { + .a = "19ff5b6b054acc5ca156cb335fbb57a949d3b495609625f0" + "b1b1ea0e19c1e669", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "5194934308057d3c8ecdcccb8a1f8801", + }, + { + .a = "286c1adb06c8e0d91743543c715d66581e0f1404952f2cf1" + "9a92168097e4bce", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "196e70cf9b236e13078af721e59d4642", + }, + { + .a = "2fb921c1706f29159470f5080f009b7af73a2b4b59319e89" + "44313f674843c790", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "6e87f87aae63457cd4a4a6ea532641c6", + }, + { + .a = "1e9be1645bc61e1814adf8ca7809fe2f024723b319556971" + "114b2a184e9121f6", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + .sqrt = "5885400cb80c63bae4914308b2cdf9ea", + }, + { + .a = "9ca8cf6730dbca96d208b79b0fd52535e792b304", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + }, + { + .a = "73f219324f36e0aae1f6e8d95b89d0468ab1922b", + .p = "e3fe457cf7ae0d453157fac07cbaa725", + }, + { + .a = "124b02b0fd0ff677573e733d6bc3bea9a6be60d6e84ef86a" + "6e67b740c7112749", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "446eb9f9ac09ff7ac2b358dd78ebb4c1", + }, + { + .a = "d0d034bfbdcca69049d17eead78572c66b5f5a9e230fa1b7" + "d41e7b623a83153", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "39cd2ece90ca23d6c2693178c5fcf193", + }, + { + .a = "25f55f4ea11fd8adef2d8f9781363006366f6caa0b0337a5" + "e0184795f3fad", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "18a4e931a05b8416bf5b991bc02cf1a", + }, + { + .a = "25337b83d2f3e5853dd52b7052496b7a5e6380e941685db6" + "b4693edeaa62e106", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "61969ce7afde7fada420c587b0241dbf", + }, + { + .a = "50eaeefcd5f5a1b5b0926caed2ec08c92c561f00275694d4" + "68c7bba52ae7b", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "23fb513f8e77985606921ec8e1f49b5", + }, + { + .a = "609baed1c2d4d52f1c91a9ed2f3c68ffe87641b5f00464d2" + "128086a4c1e981e", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "2750d6a4effd2c9ba5f71f80c2f58cce", + }, + { + .a = "2d9514eff20d87bf3afcbd25bc681c134780dec20d01b97d" + "3b29cc911a1d90c", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "1b01816bc1b20bfaee478233e5f22911", + }, + { + .a = "28d32b18c9082ae7ea28f0be3cd7aa8efad600561d4347a8" + "53b467758443b1a8", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "663b1fed3e5cfed7167cce2dbae810b1", + }, + { + .a = "fd38ba6f44adf4ce8d06344d0c3e5e4a44a34aaf93497b25" + "3f1e9b1009c6b0", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "fe9b64d7af41c5ce81ff18a391165af", + }, + { + .a = "590d9ed0431461071609075d93270c323533800822a360e1" + "60210e2d5c438be", + .p = "d258b10a93a427f65fcdf8cbc655b845", + .sqrt = "25bf48a476372ef10dc669ed3f7d4896", + }, + { + .a = "5b0f78a90cee80f72695c3b14d340e7a38567f11", + .p = "d258b10a93a427f65fcdf8cbc655b845", + }, + { + .a = "afad58d4e0c0c06fb40a77131871575bc72369a7", + .p = "d258b10a93a427f65fcdf8cbc655b845", + }, + { + .a = "1e19fd22e601573225586b66084a4df65158ef45ad0fe8f0" + "a68faa4ad447cf65", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "57c8a49ae8a34fc47bf236674b817723", + }, + { + .a = "5c15b5ef617d5cf85e4c9276478d9278e04a30527a2bcb66" + "a6adeb05ccb671e", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "2662638f71038b2b0b9e4a06e46bb361", + }, + { + .a = "f1243406b9dbcaa1f252e7dd8c22daa9345c9151f6fa6e54" + "df6ac088c81ceb2", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "3e1d6b16acc35ee99a3cf9b58f385d65", + }, + { + .a = "a951e30e28201b632da15521f791e8101ae9fdf7a107e6c5" + "6c35e4f7ce52d46", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "340c978f9204064fc549747774070f41", + }, + { + .a = "2d0cda470ec77db7e748640e1c82131141b262df8cc2cea7" + "43915d3ce85533e1", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "6b64207016d908d10e20b8d8098fe79b", + }, + { + .a = "47ee4bb1de2238c9ffb9ab96eef909b14b165c8cd9bc2049" + "0837e26d76134cf", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "21ecc111c02eac8f8693cd21c980dea7", + }, + { + .a = "d6d0e077785db6f2246475088ce5104e6bda7921c1fb12ac" + "1149bb3c9b7eea", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "ea816f0e6b06c0d446fa0a00e79103c", + }, + { + .a = "3f0fa323e5d12f4aa296f2024f86b51cad3a0339d978bb2f" + "c4a5ce4fc83a29a4", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "7f0ebfc9efebd5de70d24955fa75393a", + }, + { + .a = "247680753d5599c95aab84d1b1fa516d41e092622574f295" + "ebf9b51e3825bb74", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "609d7f6a4769d94e1a3ffc6916c02b50", + }, + { + .a = "5f1e3012e6d330b09e72cfbae64d71ecc314161a43045cc1" + "39c06f35a9842a5", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + .sqrt = "2702e8eea69442b4e6172a2a604727b3", + }, + { + .a = "37f3b0d8b439d1154897e5570a0c3848df6bbd0", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + }, + { + .a = "7eaf05eecb0d43ecf2512817192528adf0889694", + .p = "ffd67dcb5d329a4a2bb7dd5714883bc5", + }, + { + .a = "105c1fa13632480e2b74fb6cf6bc328cc3942f9d8e53b98f" + "1cdbe90f20cbd421", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "40b738fd5e8a939cff33399ccf94500f", + }, + { + .a = "13a3407966b0d6d73397a45fa9be2b11acaecc6e80df03fa" + "ed2e048b044bdbd5", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "46e7329b7c7e48e6fa2a369589706b6b", + }, + { + .a = "22147b448cd5a73ec3034e900e5e35e2c7449ddea0217f7b" + "65fc368cb7fc571", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "1759ea6c3c8c4564b5978c40efdc030a", + }, + { + .a = "e10c85d3fcfda9437b148bd660ad5a7ebca4d80c8c68c524" + "6ceb0939273b4dc", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "3c01ab6ba6cbdb7e8516e22542b2b18d", + }, + { + .a = "28f0530dbfaae27d8c0d6681d32a5d550cd335c110b789ef" + "2988c39b6c4d3294", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "665f9acaaa3c55e7088bb93dc88fb6a3", + }, + { + .a = "4962eae6c1079bb2a5ee60600f9b9c9db0715a9779c20a5a" + "8415b20c4b3d85", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "8910bc8cbf206a16968ee9607017bb3", + }, + { + .a = "15d05b2c3428db47461d4b90e8146dd4b4ad5f86465abb8a" + "7bb252ca423ff7de", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "4aba823c04a7ec0d08070999f7ab5965", + }, + { + .a = "37c0957199baff074190dae6fde2420a56748d522ba89182" + "13bdda91a171085", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "1dddf264310f08e6d212b7809744b075", + }, + { + .a = "1170b6f4f5c7d90fc1127a987baf05d47c1f91b62ba0dd01" + "e2ffc3e61e26544", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "10b462a39a4ea25517c916ca1267d4ee", + }, + { + .a = "dc67e90034f4b1c96158d66c61ef94f6322bf30540767194" + "289d50a0e64a34", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + .sqrt = "ed8984640b9032ff7d5dc6164ea1f40", + }, + { + .a = "6412bbff1fbbca4e25a7f59fc99722dd655b1941", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + }, + { + .a = "a98c16965781b8b6fb49a1fdfbefbd00ade3dc92", + .p = "ce66d97f3c1ed87b6103b64014e37bb5", + }, + + /* + * p = 1 (mod 8), short initial segment of quadratic residues + */ + + { + .a = "b0b43e2686e8bf81e07908ee0315393cde48656e98e2c432" + "3bd5133a07a1c76", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "352c0a67702fab872833b758680a99fb", + }, + { + .a = "c95dc97c4405b42ccc6bec830850684245262d383756c231" + "8dd79378a9f8669", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "38c2ee16f6e355ea53e346fd9078f655", + }, + { + .a = "35379a66ef1ef5a281091c35966a31d312095cb7ac0959a0" + "0f99997ecb69f251", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "74b85e7a7766ca98047ce8a702c9ebd5", + }, + { + .a = "4ccc534c7ac3ac9526407a4aae616151c8e5a38984f59a9d" + "b5e75f03c296", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "8c371cbd5d69a8d82889263b56773d", + }, + { + .a = "e30807499ebe6f6c89322fd3c4b428f11ba4952f6fbae497" + "c90edc5297bdf3b", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "3c452e6bd40178ab4cf09f121a9a89ef", + }, + { + .a = "24dc33460e63ad6ae3d5e659bcfcf7208f083c804501a5e9" + "1b12f0478c6f5f2f", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "6123de04bebd162ffb002e0500ab8359", + }, + { + .a = "26c2a761b5d95bc3847ff7a58825f249738d9c1eb8a003ba" + "53be67dd6a4b92d", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "18e73380a4810e17bb114f3e1f38bb14", + }, + { + .a = "362b43adb6aa4f3f7041ee86d42ee37897495fbcd2a52a47" + "9e1a80493f1fbc7e", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "75c264b8c82dfb64c9cfee3e0c64c699", + }, + { + .a = "7364cfd413f046b4bb886cda3d7dcda21f619ebb715a5bd0" + "6cc3833be5d4107", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "2af7f6495da83f2f27d947cb982cec03", + }, + { + .a = "3e7559de589e876d2fe6efd091a0a91511b7334576eef8f0" + "ecacb298b61838a", + .p = "eec87e1e532b9f1a091122c4cff81d01", + .sqrt = "1f9cbc8282c070ed616cc1a97fac79a9", + }, + { + .a = "25ba186abff6724df832e524fd872f6306adefbd", + .p = "eec87e1e532b9f1a091122c4cff81d01", + }, + { + .a = "59193d6469d246596bc69cc0030b2e0a0ff2296a", + .p = "eec87e1e532b9f1a091122c4cff81d01", + }, + { + .a = "1f14cb634a8e3f4f262998e8e661b91b424ec91b48e245b2" + "0c7b79d21bfc9307", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "59336bf333f7dab3f26b6e5b3d580ae4", + }, + { + .a = "6b1b8ea97893defaaaa262bbedec178071cd0de9fb5b1bf6" + "35148c2880bbcac", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "2965aa4725e333b86683bf030fd5828d", + }, + { + .a = "12996d48b6f9cc889c9173399f5f4db773f29a964a192980" + "2183f3939b94ab8d", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "4500cab9ab7aec1150b1223ee9cd7049", + }, + { + .a = "3dae5dd26b2373500194c86816b27350a53aae4b5dd31531" + "01d5f6e5a9d3df4", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "1f6a38ef49cc8bd1eef8883f1491227f", + }, + { + .a = "9e2de20f229e667f8e79d43f9f31b890f8b9b58aba382037" + "ae889c6fc807bf2", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "324ec7636c3dff4fa3253fbc81af6dab", + }, + { + .a = "80d25f2f19978918bca80dab98de01d82ae3b169ba0f6e89" + "03d21cb4fc27329", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "2d665de92ba36cd16eafa053f5dc4ef5", + }, + { + .a = "70410faf098a2039617c43dd4768c4366f3583a543d74d00" + "7781d5fae6308ec", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "2a61492be8dbba6a845ebf0d132e2698", + }, + { + .a = "5a35e960ebdb0461f1867c55fd8e4f1e626a7facab744924" + "2c92e8fe724c17b", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "25fde03b1a02c096f8383c840443c2d3", + }, + { + .a = "a1d2ed930145ab18b174126582c20cc189d64844227bcbd4" + "6437cd12564cee5", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "32e24ed1bc281819156635ca43ef4a4c", + }, + { + .a = "7054c96a5e8841dcc19561c1324d5ad01c31e853eb73f983" + "f4d3b86a199cbb6", + .p = "c6f187c92de82671e10480e2f38454f1", + .sqrt = "2a65023c989bb86d8ea28dce73589cd5", + }, + { + .a = "be49695b8e19d4480f861204bc929de31e6cc630", + .p = "c6f187c92de82671e10480e2f38454f1", + }, + { + .a = "3a0c60b78ae72dfe52da83947fa263ceb2db906b", + .p = "c6f187c92de82671e10480e2f38454f1", + }, + { + .a = "165cf974fe4ed624e4f37336c62619b3e7e810c12efaa571" + "5edddc9fecd73a43", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "4ba9df1fcfeeb2d1c8ee0ac376216ef2", + }, + { + .a = "4678e362dc4e15b9398f7ccc8fa691b6a05ba26089a0ee9b" + "b6b538a62e96043", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "21943f77370cefaa2abbd82ec27bbe25", + }, + { + .a = "7eff91bde1563cc1919ae3a81fa35182a6a44454164c9ba4" + "9e3f3cf689d23a1", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "2d13d1477e40f4bcf7df8323b1f2c103", + }, + { + .a = "1de4798791513fe1babddcef80e6a15c996d15f5b70f584b" + "9ece3ca9ab76d2cf", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "577a7a0479f552028216368fb7a36ecb", + }, + { + .a = "82732b80ab0df57861ffec20a3c75c270bc5e134eebb264f" + "99d8f3ebbd53ab4", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "2daf94bf89a6d4b92d99f6ec2be281b1", + }, + { + .a = "27eb19d9f5b57e8b8eb038da5358a95908dcbeaf7910a9d2" + "7b063d6f00850fc4", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "6516ee003d56d1d4eac285a97de1af3a", + }, + { + .a = "12f3ebcf10e154bd69406ed2df0fe0ffd2f613ac45e69c4b" + "bec2c33247a28df", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "1169f787334a104e5da71364960bb4b3", + }, + { + .a = "81de8f01e74ce3a1b254c9f2a18817c806e50a3c95903392" + "943ea1b8ec0d2ac", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "2d9587643969929cfb837f76ca325d5d", + }, + { + .a = "148c6cdf92945f7111d9ad5ad4a206a349cc46be1a89781c" + "1b09780f40cebafd", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "48875ebd5c183cc3ae177c2506c27249", + }, + { + .a = "fe6ef7838aa594f982ac528e59641752e0a4873ef72d900d" + "703462f5f18c20b", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + .sqrt = "3fcdcb3f24ebb63257de3e9acd379046", + }, + { + .a = "704e6918f3a0a47b167296642e1f6c064b5fed6", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + }, + { + .a = "e10a7f7f045c58adf44a12fcc6cec87bd63b75b", + .p = "debc88c58dfc9ad8e61d69f61fc52d49", + }, + { + .a = "b9656d002c98fa8c120ac1db4a05775df1c3319de5bfb690" + "1c0d264f372014", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "d9db3f403b9e424045df0a09e6cd899", + }, + { + .a = "1974d77a065c76035af3290bb7dd8e1cddfc19c59facb248" + "1639bd8eee190b", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "50ba19e7001bcb74ee9d6df6933e18b", + }, + { + .a = "94751c7af51c0786c679e31948c0489d12fabf16c8814bad" + "906b3b41e6b229b", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "30bcbc5bf9b4bde195aba7aeefa44bfc", + }, + { + .a = "3dc05f7bd4aabe0a68e366abcc0487f1a10c4c179cb665b7" + "ccf4f39ce6063bb0", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "7dbb39e9a61cdbcf7e83b21483d922f6", + }, + { + .a = "208977daf6a72daa5c5d4e14fbe2e28fa533753867d08329" + "5af878df4c7e377e", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "5b4413582ab1a3ff47f447cc08c0d0ed", + }, + { + .a = "3de30458947b12443eb955b8895c7b45db79e53805a82933" + "3b93dee77f4528e", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "1f779e770a66ab59075023137a0f55fd", + }, + { + .a = "18f5f5e27aec608f1fd5520a17983aba52d6a1d0ac3d88ec" + "0243fb82a649ec4c", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "4fefee3399d14feca488bbafcbd9b10e", + }, + { + .a = "155a7cab9f3549ddc09cd71691144e147b6471e3e9ecfef2" + "6db13e9fa385108d", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "49ef89b4f7a44d54bba946b799fee7b0", + }, + { + .a = "567ec8920ee7fc5d5a66fd5fb6714a449dd86220a424d4ad" + "86f0a6b31b7a3c4", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "25337d299557bb92261fd1fd30cc7236", + }, + { + .a = "1d3a6ca959af4a5d1cb68a950f244400259e87f51c6f29bd" + "ac8905767b7e6342", + .p = "fbde582b5fbe2da75cae71930eb93f21", + .sqrt = "568042169dc73549d6345470ee1eabb2", + }, + { + .a = "ecc06a093a4b1438a644026f9daba3dbfee04846", + .p = "fbde582b5fbe2da75cae71930eb93f21", + }, + { + .a = "4b770b922a4704dd5dcfb1b44bccc4bc79d75dd6", + .p = "fbde582b5fbe2da75cae71930eb93f21", + }, + { + .a = "142f20f570f05d4fe64988f56be3ab87aa855d4f8b145dda" + "7176d7b51c93e765", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "47e1fb727135a208cc2c7ea7b0c379fe", + }, + { + .a = "979a2fbdbf6fe322c4b7a96d1b8dcf98aa337ee09989d42b" + "2846137dd294a18", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "314031569a866f17741995c94339eff3", + }, + { + .a = "1125db5aba454aced382b162c403d256b4b74f15a8da2bd9" + "8c7df618069b5a00", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "424188e0d7180cc52c9cade1410166be", + }, + { + .a = "5c15ec51bdca83353cda8dae1258b75eda7320fb2b5f61fd" + "9c2dd4ef047184", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "9989bb94715481c52520a8f18b5d16a", + }, + { + .a = "a14e2920e9a3d3c9dcb2b2625570c2799d1ec9bf13eef681" + "6a2493e0bb67abf", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "32cd6adb81261c417dd10a2583a2d1de", + }, + { + .a = "4f7e44dd885cfcc183c4c6a81bbc54029b5ec16a57c18d2a" + "dcb85ddb1f674a", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "8ea784baad105cace13c408e30333c4", + }, + { + .a = "1ca8323e809c9adda0190816e6083aecf2d7249f111b80af" + "e243f3ec95b07909", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "55a6cf22f6779438a874c1790ee79b01", + }, + { + .a = "241ffcdf08f03805c6ba3bd1fe664a031aed20225e841269" + "8df05607921bb7ae", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "602a9d0981fbdf7429190008e771bf43", + }, + { + .a = "2005bcee577a5a69d7d38a7c33c0f32a5d4d092cb961369b" + "8ce8718596581c5", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "16a2a5a7aed60909e10cdde80133b3d1", + }, + { + .a = "24e5fd362ef16d84a64f25481f99daea591b537726220bcf" + "59ecc270559a1e21", + .p = "c579568a7fda58a3116a02bde4c395b1", + .sqrt = "6130c332ad0069454b0e327e635ad978", + }, + { + .a = "aa65d05d557cf6a73d04668ac5c474cf738d20a0", + .p = "c579568a7fda58a3116a02bde4c395b1", + }, + { + .a = "b0e60e655eef70c827476d6706b8ebc040392f78", + .p = "c579568a7fda58a3116a02bde4c395b1", + }, + { + .a = "2e2f92d2457763400965223456e5fb40f67df2022e1b397a" + "f37ca2135582db4", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "1b2f1ed46b49eb6a0529b395c74f44bf", + }, + { + .a = "c4fab9bdefce241989dc61671de4c86d7d7644c02c0be973" + "54a9f6d865b8128", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "3823c5f72e6d52d7022b4cb12a312f00", + }, + { + .a = "13d0f37f258adc9fbfbde054fb0a9560eacdc5cd8ccd7cdc" + "928730d1b7e1ff4a", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "473982d7a7015f122afc0a97e94bf72b", + }, + { + .a = "e7593a8c8cca00d2996f301e0b2246f12609bcdff086020c" + "8e78ad216665e", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "3cd73095a2a43b2dc019896d5f51fab", + }, + { + .a = "1fb9fe423f25e1546d266fee359a6b65cbbf4fa49822f597" + "76a67f989057af2", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "1687d08343e40b4750c9592bac920dbc", + }, + { + .a = "dbb601ad3da8e497e34eb2f541fcd576dafefa41751a18bd" + "435ceefbef0c44a", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "3b4a64d9bf6ebdd2bd243432c0d532a6", + }, + { + .a = "6d71e7136f775c460d920b0796c8df487e7dc97d22ea5d92" + "e8bce3470504a13", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "29d8abe2fb649295530753aaf1327711", + }, + { + .a = "5609c11c6911640ff282bd04ce8400a1221c097df2ef63ed" + "4ac8b4e999d51a5", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "251a49ed949d8ddcc69aa3d6dda2dbdb", + }, + { + .a = "2df199e2eba7bd3163719afb875e1f64bb5327a51c2e9fe6" + "c56ef8592a9598a", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "1b1cdbcd9320d9443ac170ff59d6c27c", + }, + { + .a = "2c91906b42c1a3c210516de02bc028f1f2916992158e13b6" + "03565a950e1b863", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + .sqrt = "1ab432280a0b62a6784abdb8ff2d863c", + }, + { + .a = "ac93b16f0e514f2d4ea5270fede89adea8bf3205", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + }, + { + .a = "74a3c88c833d3c186c8ddfc0ae0cd9134503c933", + .p = "d1bd970108af0ab47a7ccff9c1f7b6d1", + }, + { + .a = "164e6a030c238052514d8152aed4f20009275ea0555e7f14" + "f2789eff29e27be0", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "4b913964a95efc1abff3727531e6d1be", + }, + { + .a = "121a1159c2305a9bc5b85cd1ae1cda94cee7dbfa471e99f3" + "5d5471c7bffe918d", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "4412f0d87aa6931d475a536af11974aa", + }, + { + .a = "205b1ab436bfcb8c64aca2a495d47c16703746de53edfcbe" + "71762c73f73cd7f4", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "5b02f5b0766eb62563120a97d3da7016", + }, + { + .a = "1a84a5e3bf3784e752c2734c536659b1daf6acd4423c7ad9" + "c89c56fc2959b6df", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "5264ac2cedc3afd4ed552aeead50c87e", + }, + { + .a = "a008aa6563a2233120e31e75f2bf91c4c32ddfbe4ce80e22" + "c10f16efe9ed7f5", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "329a0f3350dba44da9c0fa3fb3001460", + }, + { + .a = "3454b1dba0a1eb696492911db8d36c58fd1f283802533765" + "984e3f5c3ce0dee", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "1cef9f32af8abe01ee1fb856df4a9619", + }, + { + .a = "24cc035dd244bca942b1144f4533548fa36faef24f838deb" + "371870df172474a3", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "610e8750278f896c548f5b8f6c08d896", + }, + { + .a = "24308e5a0df6a24c4c01726759757ee155ef2f107b4d69d7" + "90e1c66b47beb33", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "18102a01dea52cf26ec7bcd9ce7bcf1e", + }, + { + .a = "2656e62c6b0cc284f0cb348094467a51d89eec529b8ffcfe" + "f34805a2211fdfa1", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "6311f6d63ed3fdd25ea3b0b44444fcb8", + }, + { + .a = "227ea04bc695cf6afc9ae8414776f4a4a09b7baa3755eb93" + "569e1c6e979a09f", + .p = "cc0bd352a591f8665ea869e19947a909", + .sqrt = "177e2b9aa023b58ab846307b1e948d16", + }, + { + .a = "2b40088613eb00bcaa1fa590a18924b12876e414", + .p = "cc0bd352a591f8665ea869e19947a909", + }, + { + .a = "2ef7c6d7541f87a19fa4f788bc213b2e4807eedc", + .p = "cc0bd352a591f8665ea869e19947a909", + }, + { + .a = "22edc2d92411cc04ef7ad3119a87a5e12073d9e09c74539b" + "be76677cbe145ab2", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "5e8f9636712aecc1a01b915baeda4f76", + }, + { + .a = "29fea5f62359b09c8dbb54de10637f04295258dbe34e91a8" + "3dbb0f81447c0f", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "67af71fc655003a5abf936a9ac002b8", + }, + { + .a = "8f66c7428f3d42ff8c1d5ee690d8378457d6f2398d7031ef" + "74663b895758689", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "2fe66fbc713a5304afed6b054570859b", + }, + { + .a = "fd9a8bfabaf8bae3776af4c4863dd94751de970d9d27a8ee" + "12ff19fa805f721", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "3fb32357d34705010c2c57f5f01d142d", + }, + { + .a = "2fc61df839a0b92ddeb05d69df8f5830b13faa5325cbe198" + "e9731e1892c347c", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "1ba5c042e81e591307e09615209ed8a4", + }, + { + .a = "5721f5f2c40a81655246041e141a8399cabc43e19c866568" + "568d5383337dfba", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "255683ec2efe5057dea7391c5912ae9c", + }, + { + .a = "2c7a60d81f0a2ee7e1ff17f0271be4af740fe7001e6f9602" + "07766cffd9dd583e", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "6ab4fc3f4f0c7674d9443ffbddf70d99", + }, + { + .a = "3a167990a328fae6c924e193fd37eb420eb5761dffbf6269" + "b7f1696b6598ee", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "79f1ce74a61de8d2da7f4fff2421e30", + }, + { + .a = "13ca314b6be0b28ade1f8d3581eb137f8196a74f8f3f801b" + "7410bc0d12d49cd", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "11cb571a0d7832a5131c3bd9e2b2175b", + }, + { + .a = "2ac0f52b513f3d5dc1aad96129f2d68f3512b1a83a9ed1a9" + "8ae07407527c1", + .p = "e2fd3d48b3845be5df89591787fd68e1", + .sqrt = "1a278fccb0eafab3c74cdb5a1e0660a", + }, + { + .a = "b3b7c12e0c3c394e7b41748f46bb5a71422f44fe", + .p = "e2fd3d48b3845be5df89591787fd68e1", + }, + { + .a = "c339daf5e328d836ca0274464ead34c8d4e8b3df", + .p = "e2fd3d48b3845be5df89591787fd68e1", + }, + { + .a = "1cad67a0472e3d78ce2f4db0079bf3d3efef4c16bb8b1295" + "df85c8790aae9586", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "55ae976c8da057f164602c832173e3bd", + }, + { + .a = "1f2aa0fa2d7aaf972d75e84280b1c193bbd4de6de474a1b1" + "daa929b44805eaa4", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "5952bb50076a5002d4fd98ee1b234bee", + }, + { + .a = "18b96cb4952e56620973262602bb7c65b81b7155e0561c0f" + "c27e611cdaca4ebe", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "4f8ec4312a94b37af9d2677320b55d88", + }, + { + .a = "19c0b132a768d471e98aec9b3d06620894d3909bae11fc3c" + "3ecb9f33c7cdac28", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "5132056926467b9ebc503517eae731b4", + }, + { + .a = "2e91ee9e3f29a743a7ed896237b1cdc4ff7045391128a3fe" + "1fe43b7eb33b88c8", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "6d3006960c9822d8e3e20277297f2b4d", + }, + { + .a = "a89e2e2f33c155e357ace3a22721d0acd7b7c754698e6f46" + "b75c5b8507315d9", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "33f0f13b9bfbccfc3af5ebcf2932234f", + }, + { + .a = "bafc09132b129b127efb13fca3e56fd94d70f5e60664d93d" + "6e56bcfd43f138", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "dac9a361004882677076847427fc17a", + }, + { + .a = "2ca6dca28ad4a0c1b16ddbb1d9439cdfce6f8220ddd77af8" + "192d157f0cc18a", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "6aea4b1e58873c72cf789c7e1b38c67", + }, + { + .a = "aacc0a85bd836d8b31aafaa15b5b30198cfe32943796490a" + "2f66829fea31ead", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "344696a190e09e2fcc7c162be811ea3a", + }, + { + .a = "145df6843833e76a7d4f7b9ee3df29ed2a604663887296de" + "844739e5f2c59086", + .p = "dd371a07847d0e0ba15fe277859db621", + .sqrt = "483530d37ec99f64af73f91ff39c2071", + }, + { + .a = "b73e95675c9ae0eeb18640fb9e9363ec44c83275", + .p = "dd371a07847d0e0ba15fe277859db621", + }, + { + .a = "86545503f6b37446d95dfab5af4536927ef7c949", + .p = "dd371a07847d0e0ba15fe277859db621", + }, + { + .a = "1a0ca94f23fb2ff2f05ee6edf6c5288ee6632c9bb78b1f27" + "a1418ea74cefec90", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "51a970741b5119c5d0f3ef99ee70c620", + }, + { + .a = "40941999acd5ecaf4819064d829274799f81c557c872b94f" + "9c55f90669bbbce", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "2024f113a8ff4531638916f5ce8ce437", + }, + { + .a = "1d2b395e6e74c7a9c89df6b709b809747ad27b2f39e2c84c" + "c6bfe6c88c591a48", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "5669c103c43a3e71eff5067f1c64689e", + }, + { + .a = "256567c23e2f5efcae74a5ee4390c2a53371f70cc6a391e4" + "6cb41df3ac32d795", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "61d801f9493c8dd4df81bdec46b11044", + }, + { + .a = "1cf702151efb378046c6e1ff7c4fdea64dab11de545b18cc" + "4635faff50bb2023", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "561c45e4d90fbc3d67e257d464522362", + }, + { + .a = "2a76050e09a73aeec0b232bd0c58141f1240c51fd0e1c802" + "d2c6cf88090cbeb9", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "6842672d2370bdef87261e322caefacc", + }, + { + .a = "3a947f3f87fdac9374669cbd3f426629b2b4b0813a72679c" + "91bf1536b4bdf95", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "1e9d73ae67b54e8c1b37638ff2c5e17f", + }, + { + .a = "a2e97855accfaca7225f22b1956b639f40dff10ee0767b7e" + "34e8daf8af129d3", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "330e06e86764464282b30f49d39e279b", + }, + { + .a = "233a0d4f8e8b10457cee27d567331ada6c3bb189737efd83" + "6461a7c3b00e0e40", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "5ef6a2fd26778224d90f8d922c064306", + }, + { + .a = "22e5d6d527c72836c1120fb64094f939bf0bf7739cd999f0" + "7e04c68e3223c074", + .p = "d8708392da9cc40e2cc47ad468621c99", + .sqrt = "5e84dc6e6d114b48d36564b1d9881eac", + }, + { + .a = "766cf945129c9768cabe5c8bc206ee011a133fb3", + .p = "d8708392da9cc40e2cc47ad468621c99", + }, + { + .a = "8b8061d0214fb275eb3edf0ac4efc12983c5188a", + .p = "d8708392da9cc40e2cc47ad468621c99", + }, + + /* + * p = 1 (mod 8), long initial segment of quadratic residues + */ + + { + .a = "121a50ac860d84f7632ea520155e45108edbf726ef400312" + "af265d6d6b542aa", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "1104d9fa5277ffd941b2ca504033f3c1", + }, + { + .a = "12bba14492ac49da4e944ac02ac9ded3a2d449cadbba048f" + "9d30d2a96f6b9e1", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "115007fab662b063f1c1a85a986d9574", + }, + { + .a = "13d8ac7d33c3ea1bcb184abc660fe5ff6ac0b3eace1f6ac0" + "76425b4a70b6bf0a", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "474762679be31397e717f008a6d94c44", + }, + { + .a = "331f552bbda4b1d992dd79a7dac65fc714d6123502efd1ca" + "131eca10e1f832cd", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "72665e9479b1cae103882e27b3896e4e", + }, + { + .a = "d39f0377067e6d7814a3b54b74d5fc877e6a150a842dee80" + "2a5b35f434e94ef", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "3a3056445c077b79b88dd4feac16ee6f", + }, + { + .a = "59ffa4f211e11e9e28bf06313768d9e6f30539ce99a64803" + "3b147f97992630b", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "25f271261880530813283b393df6d638", + }, + { + .a = "196e733b9783263e5097a258d393314e518d78908dbbd0d9" + "8e835ea8811ded62", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "50aff6d9df607c2aab6c09da72abe272", + }, + { + .a = "1ad74de96a84df153ed96f4f3305965c688ce85c8e8285b1" + "16551b86fbf46c41", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "52e4b15907eafab6fab028f7ff777318", + }, + { + .a = "d559fae722d3d02118faf185537d3b9872888085c08f0e33" + "2f79667588a85", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "3a6d1d1324934f1c6ab27f4340030b2", + }, + { + .a = "1fda911e045e686c13d0ed29ef87858456bfe08a6dcc64c5" + "044dfa62c2c48755", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + .sqrt = "5a4d79d775b65857a6a3eae7e6c65fd7", + }, + { + .a = "c2072a78c83712d1f17d1f4d5146a0b14068e152", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + }, + { + .a = "4a46c4c627d798c4a3d26f415e869f18e2b8cd60", + .p = "ee690b3287cc4bef7173d1ae8c38af11", + }, + { + .a = "33a4da7f8fab68215f235b974676bb5f530284c9c4346bd2" + "9c0904947b9893a", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "1cbed89a3a6add32a2caedd7aa666d4a", + }, + { + .a = "12454eb2f4fb16b606b45cdd2f1964bcae0c638cd67eebbd" + "6e3c12cb58303d0", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "11190392b941d3c89014057d43c2b933", + }, + { + .a = "1be7aad902860399a59a3a4ab60355a96233a1095785d78f" + "7ef1fad6cbfd499f", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "54852d0df6fc249853261a64a8bfc356", + }, + { + .a = "171d95cc535784789996b38108bf0570f7bf822c848bdad4" + "017dbd03006159e5", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "4ced03f935a5b8e00177ac488ceda8ed", + }, + { + .a = "13bc64edf2aa045dff33a834f301b9ae53f21b0507a52a6b" + "9bb9f70ec9fa95e0", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "471487b8b79cd2cc1562319251cfd065", + }, + { + .a = "575eaa57283b6ca36106e03ac951f1eb514aef0871563f17" + "85b83ae61972cc", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "958e0d5480ae5eb29c7a2031e5e4747", + }, + { + .a = "1497fcf0a83b6d52e15c77e5ee46c84843e2d405f8551c16" + "961fb7ff05f0df47", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "489bc3d8bc5b72090a498a3e932cbccf", + }, + { + .a = "8156269059697cbe658d596ee7316dc56e2da0f3c9c6bc94" + "2e318b4f92b3a", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "2d7d908fba94f97f14510009d92f58f", + }, + { + .a = "52d9cdd76ed355c0b91964303075ed7ed5b6bf574c78166e" + "bb57797cc5988d", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "91a2c7ccc1fa93a8353d40cd3567b0a", + }, + { + .a = "241675d474e36edda5c3b52592f3ca2778b80e3cc9d7ccfc" + "ff9acea456fad162", + .p = "c94395af7aa282d79adc16e955ceba59", + .sqrt = "601dedc64c2739d55eade2b81bf9f8c3", + }, + { + .a = "1c1209a5d14e9c5fd860b4095128e11d30727138", + .p = "c94395af7aa282d79adc16e955ceba59", + }, + { + .a = "56962f61002646287cb6213cf007e2b812757b3d", + .p = "c94395af7aa282d79adc16e955ceba59", + }, + { + .a = "53277a6735ee7f2b1e6a1ecbaf7697da5d13467f57c2696a" + "7ae29f809cc2bc", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "91e6fc750eae4d47389d23991722161", + }, + { + .a = "fb3df21f43f9d6b0454ae88e536fbe2562b90e242e9d4813" + "859f853e37086e", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "fd9c1dcee2d6f1e72864100bf2250f5", + }, + { + .a = "1fe8895b0f43e7c7cf435a9708d90fa6af7e102cd797f1c1" + "06d28f270ff6ef0", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "16985135456ec55e3725b2649e85f1ce", + }, + { + .a = "8c18527907be48bfe6bba3f269b16accf36cd895650d6b9d" + "e1f131f3fd6b2d", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "bd60f7b30295f53e4b330e67945b6b7", + }, + { + .a = "27ceb721ee3cd6332803e248b636270c224fbad700346d2e" + "a5568d415f99ded7", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "64f2f6748b0c7dd09ad91e9987e57627", + }, + { + .a = "22c6e133d12d207d07d9a0884092c502e77d38c260f6b23f" + "7d95611ffc98be4", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "1796b981cb621d743e84f701e0026dd9", + }, + { + .a = "25893abcc46a5a2aa1a62ebd893decf99a5d9f5d6d6a094b" + "876f3ff330720c4", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "1881b51449505ca0bdb7eb4f6c7ca0bb", + }, + { + .a = "bc4082a238d1575921b5eaab6627422cb203184fb28f0e08" + "6060e840dc1899c", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "36e1c98a1360f6c88e4d7e949a6796c9", + }, + { + .a = "11cd69e093fb539abe544337e8a572a6d90f9d5c64535b9c" + "c6ea45b5fb873b17", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "438234d3d5d8a32f5c0fdf0b08364d15", + }, + { + .a = "23c0c8b1387989e141f57cf845d006452579c911f9f524e8" + "6ca76ce6e15cffae", + .p = "e01ad2e26513df5d8863c0407b51c089", + .sqrt = "5fab91205cecc253a5ef159f1279f7ce", + }, + { + .a = "16506dcf1e424dff4ff0163ff326011f2db4baf3", + .p = "e01ad2e26513df5d8863c0407b51c089", + }, + { + .a = "7c735c98cb5e13142fb42696c52dea4f86c35f27", + .p = "e01ad2e26513df5d8863c0407b51c089", + }, + { + .a = "1546a26d92c7a1b90e846b8def8a95dcc5fd8d098681485c" + "f9f40454c2e56a44", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "49cd2327060e71f193255ab50227b50c", + }, + { + .a = "40d7e51170443f269b12256b03b7f78916639a565bb91683" + "7afae2c07bccc81", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "2035cc0bddddef9ab1a6044f713e0e2f", + }, + { + .a = "12b4099bd0acc2e80398c544809f6ea261d6cfc6753ff181" + "7e19ee7cd5cfebb9", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "453215e8591db1b9a53f077b3e388bd2", + }, + { + .a = "7e978b624e693fda3c0f159fade85c07690c840dec951b49" + "571b7563f4f55", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "2d01575650de55dc3553c480bd5d61e", + }, + { + .a = "1851ce97073e83d6e3c76ece920c5d91460ab827eeec431b" + "94adef9c506c80d0", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "4ee75e54c41de8a702b6ce0cb35c7911", + }, + { + .a = "1eeeb89f9c697a2a08bff8da8dc6d7fd6e71f43b6922a7cf" + "8e89087734e24eb2", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "58fcb8ed1d1adcd40427574beb6b6b98", + }, + { + .a = "82ea9d2e6ce9f8a7e70d20bb3a00eb0951f0aa9602c98202" + "a33cf05cbc3f473", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "2dc47a644bfbcd83d67f001ec9f37ec3", + }, + { + .a = "7ee5b35c2a7284cce7fc26e681f824c7ef88b92ad6a956e3" + "04d32ea49935656", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "2d0f39c1415aa6ecdb216eba95e8d130", + }, + { + .a = "16691aa76616aa66ba8cb19138b2de30f3e19b4a5f1cc57a" + "cc7812c0344a0ca6", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "4bbe61678ace7fad9e1f61aac5fc4248", + }, + { + .a = "22a64631a16464b2b41f91a716213bc7f5289bd1b8ef5dfe" + "5de03fa85e43bf49", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + .sqrt = "5e2ea04651665b0764861ce7cd63a2c1", + }, + { + .a = "7904a8e905770d9c71da1bf00c1246d5365070b2", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + }, + { + .a = "7941e180046e485ad69df661a9353c369bffa269", + .p = "d9adedeb8bc5d4d1a4bbd07dc62a48d1", + }, + { + .a = "22c8e6edc37789d7738ec6dcefebbd607d1fdaaa7c584cad" + "61d1526800c92018", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "5e5da4530248bd7ab1a3fbd08f69f1c5", + }, + { + .a = "1ca92a917bec25c99039774b1246aa9f2fb5a2c9ba9f4f27" + "fa2b893cb3f559b9", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "55a84239f80708583d3f9a76ff73958e", + }, + { + .a = "1159fd297bb177aa585fdaa7bd4bd97ba5fec4770aaf40c9" + "277496ea0743f4fd", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "42a5f38ec5af19489aeb45e7bfcce9de", + }, + { + .a = "26f55dd518994145017f5fd0dc182be72ab0dcef72ead33b" + "2a69a803f6b19161", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "63dde2ed42f80e076e0481dbaf0cbf02", + }, + { + .a = "2d1189aaeea16c966889adada17bcb26232c86006015164a" + "30742831511eff6", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "1ada6d768160903b16fe877dd9aa113f", + }, + { + .a = "28acf490426026147635bdc6b062d6d04b635c9b99a198cd" + "86b47dc47b96e5f", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "1982cf14b64995642cd5dbd245c27afb", + }, + { + .a = "2fc7aefd1b206bcfb2644576a4c8cca7fe9a72a7b2e4dcc8" + "ed127ffb685fd14", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "1ba6344ba57e08173d21a98328b71684", + }, + { + .a = "f035046ddb03b1e343cc2e5dc24a91fe807dbd7906b2f16f" + "02480db9c8627e5", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "3dfe9533519e67d651b4c524b737dd99", + }, + { + .a = "3609bf3e9b32879a3add17aa6d1542c2f549030d23bf4cb0" + "4d65a353f11230f", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "1d677c1e06055bd8d77565b6e97b18f4", + }, + { + .a = "103a6d3816aa8b314402c12ffb54a111bfc100f599aa5f78" + "ff9574c3523e0121", + .p = "e26c6cd64976b9391f43981671002d69", + .sqrt = "40747083db7013669a8050e31542a781", + }, + { + .a = "4ce4c0d22add35bbe43784924de6dbc0906e533d", + .p = "e26c6cd64976b9391f43981671002d69", + }, + { + .a = "c5c1e597f6dd8751825916133738c2f42c04114", + .p = "e26c6cd64976b9391f43981671002d69", + }, + { + .a = "beeeb4fc61586d0d2d7149410c8bfaa7129f65cd12accd00" + "ae821bac17ba37", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "dd15d5ca7cdce13ab7e98c88fc88f19", + }, + { + .a = "2a0b5b4376ec8b0bbb8f0a283a0a317fd09589bdc8e693f0" + "031c2bc1a1ae087b", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "67bf2103f485c73c075cbb5f8243bad9", + }, + { + .a = "26c4d966b33befb307a16c8a87acab27a12f94b7921af11e" + "430adeacac82a62d", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "639fa027439489f0eef60d704e8cef98", + }, + { + .a = "29eadb8e533f3a9e325bf9bbbc9db41291f5c93281e02a70" + "3e7153c744a817e6", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "6797009adb6ae5b392734d13664e56b2", + }, + { + .a = "e4aa928dd30d75d78f5074e8931d697b45c4a65b6ba31109" + "86e9bd08fa3cb8e", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "3c7ca3274282f6fbf175d681fe84526d", + }, + { + .a = "32f1d70f5fadfb94c555b61651de9eea025b7150feefddda" + "6d5319eb6bdfbe37", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "72336c9bfae5183830819108df6061da", + }, + { + .a = "1c941c73a20169cb3bf4f4c3c37690d041402787e7d12156" + "6269ccbbc4990a46", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "5588c5d715f5f9e0c90823d91b6c7cc7", + }, + { + .a = "1579253f887c3a8185c70f385203a19b867d8bf51657e531" + "78ac6d665c7ba070", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "4a248a6f3b66c3dbcf633d86248b6bbf", + }, + { + .a = "1a12783318c06b7477ea1f2c7323bf1bade4969a5c2b2d1c" + "d5de12ca124bc7b5", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "51b28a8e6affa359cb3d437785560a6d", + }, + { + .a = "b42d6aedb666a8102825bcb9af19b001b37c1902cc3a5751" + "9775caa627d0c69", + .p = "e74a67bb1628c7b1d923808f320470a9", + .sqrt = "35b12ba2fc934dbfb1f447ea5063f20e", + }, + { + .a = "bf7b664d321a2d4a31c0d798f674c0e25a885ec1", + .p = "e74a67bb1628c7b1d923808f320470a9", + }, + { + .a = "2a324cfa40e3117fc1da8357e67be94c39365a56", + .p = "e74a67bb1628c7b1d923808f320470a9", + }, + { + .a = "82e929f47c509779ae81f2eb12dcac84c1288827cd7909ae" + "43dbb8bdef71eef", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "2dc43980830b15b0c83573d07afe6999", + }, + { + .a = "4589649eb9b85e1be15abcc1f48f2eb4c58b197ebac83abc" + "8d809024e40803e", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "215affc621edf6c85922903ab48ea658", + }, + { + .a = "1c868a42c164513eaf724725ca5994f241c16b2e68f303e1" + "b5d57b57c1183304", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "55747461ff8137d4e05eeaf2c29aa0a8", + }, + { + .a = "518e36afe548286568e99c20afef30074ecac2b1c25ac73d" + "9556855fda6e2c", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "907e3233f20c0db9a659d896a9c2512", + }, + { + .a = "4c41116acdaf952fadd8643ad7db01266cbbd3f3dc86242c" + "7b255fa17f7bedf", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "22edf0b170fabd22b9cd2919e45ebc77", + }, + { + .a = "1deb14e6e04d5c3da1bde36ed62b5c98b30d9637ce70d467" + "1553062f135fb743", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "578424546feb87643c07224b5ac59802", + }, + { + .a = "19b9585337d4bf6c126db6f56929140ceff37c6072503ff1" + "cdf661c36471bf", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "51266f7e4ea87ca3749d508ed010664", + }, + { + .a = "e79ca7697fb17fca33dc2be93bc1408b890da7861b685f4f" + "432d87a3f0f152f", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "3ce00d970ebd09af262bca93d838fa1f", + }, + { + .a = "2ad3e70e0575ddcb8a6b150eb98caba70854861249aefd23" + "d517198827f406f6", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "68b56a7414fae89868d5bf8352d273fa", + }, + { + .a = "13120bbe4f9aa9295e79f6e1d14c6e4ad6857a9cb781542c" + "d803927706a35b26", + .p = "d64bb8768a638d7f5d3825337ace2de9", + .sqrt = "45df23b41b892c677376741d846897ec", + }, + { + .a = "39c6f0ca17b31cdd576136a42afacc1951195d46", + .p = "d64bb8768a638d7f5d3825337ace2de9", + }, + { + .a = "364f883be424ee5552e3e2964066cf720981ef15", + .p = "d64bb8768a638d7f5d3825337ace2de9", + }, + { + .a = "2a482b02a0fa79c96ef9d00287b3b5eb306bd82d29cbcee0" + "d4698e0d6cad30fa", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "680a0d10bec5fd5a019917ee00f61184", + }, + { + .a = "dace96b6e89e3d170e76b81a9f023d9f364a80e9ff40cdd3" + "338e2b538177cce", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "3b2b230a1222cd9af8aa60978608e5b1", + }, + { + .a = "1350c9c08466500847eb0573aa711123b77d86a12d52184e" + "584496ebb278e1f8", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "4651b6413d019c9b27af8be350b9efbd", + }, + { + .a = "309971a3c9a159c454fe42fcbabe744b8ad1b8aa8ba475b5" + "8466da45a84de", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "1be2a35bf675130b7362bd13d1bd119", + }, + { + .a = "e88515de6431e1ac3259fc16bc996b369e621113c8505c34" + "ba18d7a77239e80", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "3cfe918a2d7deaec83f14014593287dd", + }, + { + .a = "dd42d98bed06e1eee7825a3df6ee9a9406b501801e35fd43" + "54538ed582c38b1", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "3b7fd868d0022fc7f467d06f3a673aef", + }, + { + .a = "e47b2f19b59423aeddf737a59b95433d6c335de8380113c4" + "cdb781e9851d2fd", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "3c765e522c77141a85a7f5be88e6dce9", + }, + { + .a = "1317abf2c6630cecee00a0b2c3619269c6abc56b19d52521" + "afdeed13e8181498", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "45e9714caf9599488f7b5f50663a6f47", + }, + { + .a = "fb4a9ec53f4b5b8337db3b52729f92660c540a57ba26f6a3" + "1132c3df8e7fbcc", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "3f68a0d5d9b6773b6462d520fc15a592", + }, + { + .a = "17bde3718d8c79dea7bf8177b429b9fbbe2ec377ee056318" + "8b1723601dfe97f4", + .p = "d3b5db60b30e3077d3bc605643d0a579", + .sqrt = "4df5f7e0af55aa287adf15f97d58a39f", + }, + { + .a = "9d6a2d424236cef8719d331a7352de39ecf44983", + .p = "d3b5db60b30e3077d3bc605643d0a579", + }, + { + .a = "c09b3647eca9c87b3a542b0c1e734bf52ce314df", + .p = "d3b5db60b30e3077d3bc605643d0a579", + }, + { + .a = "1d8903ab585dc5b9992ba2f4295e058111c46c3620554d27" + "5e46107e55d7a2c", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "15bd0fdd249f3c6a8c2f548736905f23", + }, + { + .a = "f85fac41fc1b4425c176f56f6e9d62e1e76e1b2211ef4fb4" + "59c33ae66b796c", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "fc2874c1abda2571ab8a869d1808175", + }, + { + .a = "e42771a0f23fd6acdfb6aa40aca83b16c58759815f4dc6a3" + "8fd3eef95cee3ea", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "3c6b48d5885c257eca850ffce85e46be", + }, + { + .a = "195fc0fe25e90c6173a995e481fee9e7e256409fe143fea6" + "1826da3486c3e297", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "5098a32cc135bdea68430ed532ea0005", + }, + { + .a = "b9ba371e8df3cd27092a0acc00e0fb452607e13a8cd3a003" + "515de9e1d7bda62", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "368342b57f60ae446e6effdf172b074b", + }, + { + .a = "110fccbd58d822da1cf00b2ebf75e8479fba35602ae212f8" + "7abe5470aa0a8dc", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "1085b79c4bb04aeb47ee70702a56c09e", + }, + { + .a = "770192a443c51e1652e7057f01317a4daa394f698c7e8552" + "a2708ce9a171da8", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "2ba2cf3f71977f2ab422dc333af01aed", + }, + { + .a = "d64e10830c62eca1dac4bc5f1fa566f9504bb15ca82c63a3" + "efa32cef3b1c5b0", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "3a8e7f5e1cb03581dc78638cf4860450", + }, + { + .a = "1e44103d73e7744ed150aea64c9781bb286d0c8896086aad" + "a0d01ec4018edd9e", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "5805e8e0c4c53dfa1e3ea9e4ef6659db", + }, + { + .a = "2602d83a0b822bf52b8a02e7a5df83d06bf6f75f52658484" + "03a60c25c70d2fb", + .p = "d221951118210ae00de11d059add5179", + .sqrt = "18a9486523c9cbdcc1d9d812345978a3", + }, + { + .a = "7575749b1df9decda4eeb931f3e077a35ab17cb4", + .p = "d221951118210ae00de11d059add5179", + }, + { + .a = "1ab8eec9aa32cd78e7fccc74bea5bc666224eae5", + .p = "d221951118210ae00de11d059add5179", + }, + { + .a = "1fcb7176f1300935e5f662830115c7330fe0a336e27f1ded" + "642f51a97f71f6c", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "168e01d97eb477d70cd284571dfff3ec", + }, + { + .a = "a856d9e3eb0073dc8acf9736094df283bfaa8ecf94d633d3" + "0c21fd34154c3df", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "33e5f39cdd6b39931e1295525323eced", + }, + { + .a = "23ca9267d09a2a9697887b8d71794f91e7ad6ee2282a6247" + "5d37273ea49cfb24", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "5fb8a8b3082f117d9c32ba395772f1f9", + }, + { + .a = "2e5adfa8b2e4baf9a120ad13afc13d420ea82b7b6552ef49" + "b93d827edd782420", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "6cef6806482bb27a8f431c2be11da15d", + }, + { + .a = "1856d952cfe49f088152e15c8a35a6e02e9e6471ef8ba7c2" + "a8085d01f197911c", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "4eef8bc5cbe83339d5363dd75fcb906c", + }, + { + .a = "809153ea20aab3373a44470d4a92e5415293c42084757301" + "4ecef756ebe3b6e", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "2d5ae64f52b011c2b47b196d3257815a", + }, + { + .a = "d8f2c65347eba4148fed9f5420a50727915e41417b090095" + "d011f2dd85d13a1", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "3aeaaa8f5a07973ffdc5c96e28c6b6a0", + }, + { + .a = "2fc2023299021c3bbd160fdc96f3f235105bec74eedd0bc5" + "ba2c6ba3aea5845", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "1ba48fe5d1a5c1b26b142965ce0dd426", + }, + { + .a = "7c57bc6f695242e8c31ea7ea07ccb856fd80291ab481aab2" + "66980264ffa3b64", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "2c9a8745a0f72ec9dbb8d2ad4e86e6cf", + }, + { + .a = "194e31d9e40a273b975b87cf5b4956b892b0b810e9c56d63" + "9731eb011f3b5bba", + .p = "e9103af488d3bc5209fe348dcf043dc1", + .sqrt = "507cbb530412e9a988aeecda15a9c9e1", + }, + { + .a = "d26fa79e1156dd232b5886efaf8b5b7a08dc5740", + .p = "e9103af488d3bc5209fe348dcf043dc1", + }, + { + .a = "cceefd8c7bc0a4b82b8eacbbcb786f9b21f6ff31", + .p = "e9103af488d3bc5209fe348dcf043dc1", + }, +}; + +const size_t N_TESTS = sizeof(mod_sqrt_test_data) / sizeof(*mod_sqrt_test_data); + +static int +mod_sqrt_test(struct mod_sqrt_test *test, BN_CTX *ctx) +{ + BIGNUM *a, *p, *want, *got, *diff; + int failed = 1; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "a = BN_CTX_get()"); + if ((p = BN_CTX_get(ctx)) == NULL) + errx(1, "p = BN_CTX_get()"); + if ((want = BN_CTX_get(ctx)) == NULL) + errx(1, "want = BN_CTX_get()"); + if ((got = BN_CTX_get(ctx)) == NULL) + errx(1, "got = BN_CTX_get()"); + if ((diff = BN_CTX_get(ctx)) == NULL) + errx(1, "diff = BN_CTX_get()"); + + if (!BN_hex2bn(&a, test->a)) + errx(1, "BN_hex2bn(%s)", test->a); + if (!BN_hex2bn(&p, test->p)) + errx(1, "BN_hex2bn(%s)", test->p); + + if (BN_mod_sqrt(got, a, p, ctx) == NULL) { + failed = test->sqrt != NULL; + if (failed) + fprintf(stderr, "BN_mod_sqrt(%s, %s) failed\n", + test->a, test->p); + goto out; + } + + if (!BN_hex2bn(&want, test->sqrt)) + errx(1, "BN_hex2bn(%s)", test->sqrt); + if (!BN_mod_sub(diff, want, got, p, ctx)) + errx(1, "BN_mod_sub() failed\n"); + + if (!BN_is_zero(diff)) { + fprintf(stderr, "a: %s\n", test->a); + fprintf(stderr, "p: %s\n", test->p); + fprintf(stderr, "want: %s\n", test->sqrt); + fprintf(stderr, "got: "); + BN_print_fp(stderr, got); + fprintf(stderr, "\n\n"); + + goto out; + } + + failed = 0; + + out: + BN_CTX_end(ctx); + + return failed; +} + +static int +bn_mod_sqrt_test(void) +{ + BN_CTX *ctx; + size_t i; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new()"); + + for (i = 0; i < N_TESTS; i++) + failed |= mod_sqrt_test(&mod_sqrt_test_data[i], ctx); + + BN_CTX_free(ctx); + + return failed; +} + +/* + * A list of primes p = 1 (mod 8) with long initial segments of quadratic + * residues. These exercise the non-deterministic path of Tonelli-Shanks. + */ + +#define N_SMALL_SQUARE_TESTS 100 + +static const struct p_is_1_mod_8_tests { + const char *p; + int first_non_square; + const char *sqrt[N_SMALL_SQUARE_TESTS]; +} p_is_1_mod_8_tests[] = { + { + .p = "d7a6133d89b7a840ec0d80d2ee197849", + .first_non_square = 101, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "127b07d9558aa7382fda337e674b0020", + [3] = "2b0756607c913be85534cec59846e6f8", + [4] = "2", + [5] = "1ac3bfe91dd86f91be44b30936b6bcff", + [6] = "3a03fcd8bc70d0a08444356250a316c9", + [7] = "22c3c29b3cf04300495e694db5a1fb11", + [8] = "24f60fb2ab154e705fb466fcce960040", + [9] = "3", + [10] = "46dce6880d735d143a40b99097f87f9e", + [11] = "3eab85485728056c43cd2681a96976ba", + [12] = "560eacc0f92277d0aa699d8b308dcdf0", + [13] = "19bf2319a32e92a6c2d80d364a19229d", + [14] = "51554e1d7adc5173841a9525b4a2ff7d", + [15] = "3d9a295185f27dc096b33184e4edd834", + [16] = "4", + [17] = "407d75edc1fba51c637aeddcb35abc1e", + [18] = "3771178c009ff5a88f8e9a7b35e10060", + [19] = "9e48ccec873561b315a0980c409c291", + [20] = "35877fd23bb0df237c8966126d6d79fe", + [21] = "2f4a3220291ac0440f3a2cb35d8e8f4c", + [22] = "218f85684d6378bf6a90d02b0f94dc11", + [23] = "432f4d621cc773b7945a024a076048d4", + [24] = "639e198c10d606ffe385160e4cd34ab7", + [25] = "5", + [26] = "8478976383e49d4fbda384883343e1", + [27] = "5690101c1403f487ec6f14822544c361", + [28] = "4587853679e0860092bcd29b6b43f622", + [29] = "47804840abaf4bc53e37c87291f55527", + [30] = "48925009cc14fbef1dee0b4a2f920890", + [31] = "228ef1765a5448f6a4600026dfb14830", + [32] = "49ec1f65562a9ce0bf68cdf99d2c0080", + [33] = "a41fb079bc22c9d1e5658a86db0e6bb", + [34] = "675b3a95cddf5b210dde6d3e7dd4cfa3", + [35] = "5b727e9bccd4da204cac92594babe837", + [36] = "6", + [37] = "64ba7d11b9d672e6d31a9b5971e60d2f", + [38] = "24afa6855c01017537555a58a70da6f9", + [39] = "3bb009b3541796452327d8e6fd8323ba", + [40] = "49ec462d6ed0ee18778c0db1be28790d", + [41] = "545f0385bd365fa7862502739a781f69", + [42] = "2b0b17173a32035911223d142ab00a4e", + [43] = "67109cc9a742fc0305d031cc20e7fd1f", + [44] = "5a4f08acdb679d68647333cf9b468ad5", + [45] = "504b3fbb59894eb53ace191ba42436fd", + [46] = "38e6358e14aa1cd9778b09cbf05deb48", + [47] = "319d132fc72dff9b631b3c2ca0c2f49f", + [48] = "2b88b9bb9772b89f973a45bc8cfddc69", + [49] = "7", + [50] = "5c67273eabb54418ef430178047700a0", + [51] = "3558bf08253c3d5afd58bd1c3c0498e3", + [52] = "337e4633465d254d85b01a6c9432453a", + [53] = "1845657cc9012fafd8a266bf41b2ce66", + [54] = "299a1cb35465365f5f40e0abfc3033ee", + [55] = "582fca95baf4c0b18befc9aa5b09aff4", + [56] = "34fb770293ff0559e3d8568784d3794f", + [57] = "62e847fb9f593dbe7d2f1a5c74594670", + [58] = "1c85e173426916ea88c889b950bd5d96", + [59] = "13e4d1ad2ef6d69c758826e554d3fce7", + [60] = "5c71c09a7dd2acbfbea71dc9243dc7e1", + [61] = "5bd4d7bf50d72c7642321ac648a41207", + [62] = "4d543e0b7cb7a087f6c6820871402203", + [63] = "684b47d1b6d0c900dc1b3be920e5f133", + [64] = "8", + [65] = "4720271c07130a09c11989006d5b65b7", + [66] = "27c5c5d3ef4be7d25b799ea455ff933", + [67] = "563c042e90bd60de622c83b96aad46f3", + [68] = "56ab276205c05e082517a5198764000d", + [69] = "40aabad2f12469f355cbd0e524021817", + [70] = "69f41210ae2c64ebbbfb9cc4436b121b", + [71] = "2495fdd3e3ee43c51d78a037f2af961", + [72] = "68c3e4258877bcefccf04bdc82577789", + [73] = "a54afbfe8d22b43dba10c45c3e1945a", + [74] = "387797174f3bf5d6281fe71ea18676e1", + [75] = "81635b1ae17cb7420576f6f4b6f571", + [76] = "13c9199d90e6ac3662b4130188138522", + [77] = "2095521a5b009be0acd08b5ee47fa519", + [78] = "2bdce5c6e97146d22fd25f4abb3bfa49", + [79] = "15d3c2c27cdc4411498596c20ef7d174", + [80] = "6b0effa47761be46f912cc24dadaf3fc", + [81] = "9", + [82] = "12af1ddc568bab9c8609a1069ad98974", + [83] = "4ba992f528674a24e7d11121eb88af39", + [84] = "5e946440523580881e745966bb1d1e98", + [85] = "1a0d8dbdac9222fddfacbae62f73dc50", + [86] = "4040b1fc21cc440034ac36b0e9eb9c90", + [87] = "1203e4b669c80a95eb2a5134436217aa", + [88] = "431f0ad09ac6f17ed521a0561f29b822", + [89] = "62aa36cb4434c129d65d92ff25a9c3c4", + [90] = "30f5fa5615d91043d4b5421262ff96f", + [91] = "2b64e196026445e615b7c019aafc52c4", + [92] = "514778795028c0d1c3597c3edf58e6a1", + [93] = "25eb81b5dcc44f0a8bcf7fb909690c50", + [94] = "48e96bc3845c7d38eb06fdf2d9274207", + [95] = "18ae0da0ae22f6cdee901b535977cfe", + [96] = "1069e025680b9a41250354b65472e2db", + [97] = "6bc184c777e6c859c4ce144eb68d6bef", + [98] = "5648dc4c32ed15b79d16185e1b0c7769", + [99] = "1ba38364843f97fc20a60d4df1dd141b", + }, + }, + { + .p = "ed2ca93a2b8b7053b5cbfbfc164284d9", + .first_non_square = 83, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "3a3c6e5ea115faa8be69eac1c177f698", + [3] = "2748dedd33f6c6a09f84973f2f862922", + [4] = "2", + [5] = "d7607decaa9bfe5ec031537ce343ed0", + [6] = "401d83de7c83456c0bee28fd25829dd5", + [7] = "21f72780e6f6789259086212c3e9538c", + [8] = "7478dcbd422bf5517cd3d58382efed30", + [9] = "3", + [10] = "28f8f6227299e5883b1a59e07b4cdec", + [11] = "4b557ee20b98bd00344c14563ca8f839", + [12] = "4e91bdba67ed8d413f092e7e5f0c5244", + [13] = "10242586b3f9e2ca74409066950b0dc", + [14] = "a4bfde50f20b288cf44d40af83abd84", + [15] = "43fffde1b3477313dd57b9cd7261cdc3", + [16] = "4", + [17] = "524907a08de4e5c0c153c544c87bf9ce", + [18] = "3e775e1e484980597a8e3bb6d1daa111", + [19] = "427441618f7df01a97f7435904162b4d", + [20] = "1aec0fbd95537fcbd8062a6f9c687da0", + [21] = "6cb69f443aa14ed65113febd0cfbdf66", + [22] = "7311499cc97a3d0f4a9c0597b2c761ec", + [23] = "2e4c8606309b68cd815085fb51529a9c", + [24] = "6cf1a17d3284e57b9defaa01cb3d492f", + [25] = "5", + [26] = "3565c3eaf0daac1e3a2c028657569676", + [27] = "75da9c979be453e1de8dc5bd8e927b66", + [28] = "43ee4f01cdecf124b210c42587d2a718", + [29] = "35864fac94ecba016620c63c0ccc5f56", + [30] = "3c85a120dba23570cc87f22b973f1654", + [31] = "6838d8565fcbbc5dbf597fb37a1f5406", + [32] = "43aefbfa73385b0bc2450f51062aa79", + [33] = "45bc0d05b45e92a9ec86fdb68d4d8b6d", + [34] = "617de3651efcd26b6524a971fc68398c", + [35] = "4101878d7ace3b9fb358dad9ace0a5c8", + [36] = "6", + [37] = "673a3026784b7a41328bac018550b86f", + [38] = "2b23c1a47cab7f8fcd0105546e230715", + [39] = "4e915dc6234ac56a095df35c40ea4907", + [40] = "51f1ec44e533cb107634b3c0f699bd8", + [41] = "3360c9282c4fdef670b93037989ff143", + [42] = "35e69c414ce1d44b024bcd9a7225a5c1", + [43] = "2e48de0b4bd10c05fbfb2f9719b20e69", + [44] = "5681ab761459f6534d33d34f9cf09467", + [45] = "2862179c5ffd3fb1c4093fa76a9cbc70", + [46] = "643d5c5c9b5af336e504f41726dfc0d3", + [47] = "3e98383357bcacf462c70cc9351a91a0", + [48] = "50092dc55bb055d137b99eff5829e051", + [49] = "7", + [50] = "36017e9ef9e274f8024599ccb1154c1f", + [51] = "5bf023ca007e263e4b5a030838af810c", + [52] = "20484b0d67f3c594e88120cd2a161b8", + [53] = "2b9e8a3b3ed1ed9329bede411f92778c", + [54] = "2cd41d9eb601a00f92018104a5baab5a", + [55] = "5bec2e51e71bb1f1a852e3e56d43a184", + [56] = "1497fbca1e4165119e89a815f0757b08", + [57] = "63423607948c915df58134dba2f29d07", + [58] = "18d9afef351887618e7bb9e3cfb0211", + [59] = "3ea4eee3e48e677c53aa0f392d896490", + [60] = "652cad76c4fc8a2bfb1c8861317ee953", + [61] = "66fbaa07b40873c3ac00b38cb100f017", + [62] = "6a018a4798e4a471a9ff4fb9dac762f", + [63] = "65e57682b4e369b70b1926384bbbfaa4", + [64] = "8", + [65] = "6188263fe8ff27e6249f9fb45efc8a9", + [66] = "3cff332519838822fd763253838bf932", + [67] = "4c83bbd2d19d60743a698d36db22c917", + [68] = "489a99f90fc1a4d233247172854a913d", + [69] = "38607b0f81008cc1a1dd707a16fc4d28", + [70] = "4eecbfcfce6b4da4c456d606983c3ef4", + [71] = "303995f9d14e1722b14e98314f7064ca", + [72] = "703decfd9af86fa0c0af848e728d42b7", + [73] = "17b2676a1150040ad999fbcd06f41d3a", + [74] = "1a7989bf779d64cf9a301debf4fec091", + [75] = "28c04ee827b98f30983507c028a3b72f", + [76] = "684426770c8f901e85dd754a0e162e3f", + [77] = "2b5c61ea91f69b1c7c7ebaeefb3240c5", + [78] = "568763066059e114d011688b51121883", + [79] = "a43ac4b02b98857c9d659c953154885", + [80] = "35d81f7b2aa6ff97b00c54df38d0fb40", + [81] = "9", + [82] = "d688cbf38d1530c3d11285f8a829bc3", + [84] = "13bf6ab1b648d2a713a3fe81fc4ac60d", + [85] = "4760657d9d6c47c60833c08573e79b80", + [86] = "3532206ae6f0f9a9721be80adf3b3df4", + [87] = "755e6970bfe25e6ac8bf805cf22b7343", + [88] = "70a16009896f6352093f0ccb0b3c101", + [90] = "7aeae26757cdb098b14f0da171e69c4", + [91] = "2bbeb474b349124e3ef6c222b62ad7b3", + [92] = "5c990c0c6136d19b02a10bf6a2a53538", + [93] = "46e5aa500f60629978168938a0c01682", + [94] = "228459bf06f9dfb15baf8ac31efe34c1", + [95] = "69e2c2104da63c9b919341b9013db3b7", + [96] = "1349663fc681a55c79eca7f87fc7f27b", + [97] = "39c6a22fb3f9d6c91f40fc217241c45e", + [98] = "42b24dddef7d060a36b28cabe23d4b8a", + [99] = "b2c2c9408c1395318e7bef960479c2e", + }, + }, + { + .p = "f9df802d991ea5ebaed8d3b9a42cf101", + .first_non_square = 59, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "9b87b93bb96389be7801b89dc1652d8", + [3] = "59e13489928842f26ae2886d9310b8f3", + [4] = "2", + [5] = "4c5c3af3b9fab5886e65b82402dad66f", + [6] = "69e583a41fd4c41fad8dfafe1d64ce80", + [7] = "2226e4abbf4dabfbc798cafda99b0c40", + [8] = "1370f727772c7137cf003713b82ca5b0", + [9] = "3", + [10] = "56069730d91a5cc07e2a98a6a68b7202", + [11] = "3f7c0d6dd412594787118d6095384c3a", + [12] = "461d171a740e2006d913c2de7e0b7f1b", + [13] = "40b3ccbea21d3d72c74263ab6879d65f", + [14] = "119ec14e3683163583a5553d2a0e9311", + [15] = "2aa84242c307fd827f2ab90abc5e7d0e", + [16] = "4", + [17] = "79b4a0e036f6d7ac8945c382d3135b5d", + [18] = "1d2972bb32c2a9d3b680529d9442f888", + [19] = "4fc091a564105b66fd19904959dd1c2b", + [20] = "61270a4625293adad20d63719e774423", + [21] = "5a0e8b4c8c5c042b55235a9cb7adaf60", + [22] = "35a1aa98a855b5d2c77f916145f41758", + [23] = "72a841aa741cb731c7986c8eee1af3b", + [24] = "261478e559751dac53bcddbd69635401", + [25] = "5", + [26] = "47e09b3873557e6bc1ceadd3969fbe88", + [27] = "13c41d6f1e7a22eb91cec58f150539d8", + [28] = "444dc9577e9b57f78f3195fb53361880", + [29] = "57798532e4e9404df4b67adf52c37099", + [30] = "3590327cc41d87a9e09fd8d9619c06c6", + [31] = "e15fec88e2da65f950f0a29275df452", + [32] = "26e1ee4eee58e26f9e006e2770594b60", + [33] = "614bdf992ff880c1f9092b13cdc354f2", + [34] = "16f4ebd0bea0a507679dfed7c67cfa36", + [35] = "84b3b3b80ffec8c1d8269511ac835ac", + [36] = "6", + [37] = "7533be777b68bc56c672a6970f2021d4", + [38] = "66d2c23bdb3236d9d65c761f5cd0b606", + [39] = "68bdd47cfdfa7a81e2550461aae74818", + [40] = "4dd251cbe6e9ec6ab283a26c57160cfd", + [41] = "38d5408abd422d8fcf19e8cf070d342d", + [42] = "358408a1b5fa21b4ad7eaeab5970dd7d", + [43] = "395a8a9786765fcc10641a5932985fac", + [44] = "7ae76551f0f9f35ca0b5b8f879bc588d", + [45] = "14cacf526b2e855263a7ab4d9b9c6db4", + [46] = "fefca61affd696e5b8c9179dc6ea1b5", + [47] = "70c9d4ca66eb1683ef376ed8e27f78de", + [48] = "6da551f8b10265ddfcb14dfca815f2cb", + [49] = "7", + [50] = "309a69e2a9ef1b0b858089b14c6f9e38", + [51] = "2f7c7a1a80c51f68ca01ad786d31730a", + [52] = "7877e6b054e42b0620540c62d3394443", + [53] = "10cd478dce3a9dc19548ee40ca0c2b0", + [54] = "43d10abec65fa67359d11d40b4017a7f", + [55] = "528ec8c6e928f443382d5537ef5e4844", + [56] = "233d829c6d062c6b074aaa7a541d2622", + [57] = "72bd2260fffce41b2fceb568f468cd5f", + [58] = "7159169c936f53e5d9e62a97f2c7fcaa", + [60] = "55508485860ffb04fe55721578bcfa1c", + [62] = "549a3f9a716d2b96a14ac143160611cc", + [63] = "6674ae033de903f356ca60f8fcd124c0", + [64] = "8", + [65] = "645b10018a4ad21e827fe92a1e59f098", + [66] = "bdb26c2d680b416a65bbcdbccc495f0", + [68] = "6763e6d2b30f6929c4d4cb3fe063a47", + [69] = "5b40ed33d02f5dc35137a11e753e982b", + [70] = "30c34c8e71a415dbbb1f090970f44828", + [71] = "13e6bbfca6921f5a4856c934c5d6e3c5", + [72] = "3a52e576658553a76d00a53b2885f110", + [74] = "3c65617b9a3fcb1c3f7296ea850efa7", + [75] = "3258f9ab5593fd1b4744fd4f69064543", + [76] = "5a5e5ce2d0fdef1db4a5b326f072b8ab", + [77] = "3552f699dfaa4c271b0eeda26ed29d78", + [78] = "58976ff498c84c33a271944f973ae216", + [80] = "37916ba14ecc30360abe0cd6673e68bb", + [81] = "9", + [82] = "5a9d0c87e518c6cb13a811c0ebbca59c", + [83] = "5ef2cb8d6cb52a4627e5c105c143c922", + [84] = "45c2699480669d9504921e8034d19241", + [85] = "4bba44a6872d99a6cd89235b86fd6796", + [86] = "5632d46186d2d1e32be4c3055231edaf", + [87] = "531f902b8fb73220ef988a46ca801f16", + [88] = "6b43553150ab6ba58eff22c28be82eb0", + [90] = "8344564f2307055cba6f63a4f756505", + [91] = "76240705743b992bad77b0ecb5569616", + [92] = "e5508354e8396e638f30d91ddc35e76", + [93] = "154d0dac17c4a150f8fc0c8c1ae2021e", + [94] = "6713d7b3635f41a9a0bee026abfdddb0", + [95] = "64321552a81000b462142ecd1287bc36", + [96] = "4c28f1cab2ea3b58a779bb7ad2c6a802", + [98] = "440b610a211b8c435480c0c5049c43e8", + [99] = "3b6b57e41ce79a1519a42b97e4840c53", + }, + }, + { + .p = "e74738af4ed4cdd4b646d73096a2ccc1", + .first_non_square = 73, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "6ac4647c98cf7af7efe36371c9840eaf", + [3] = "21f4d6a5034093c1707e59226887fd48", + [4] = "2", + [5] = "548a6d10aee79ac83c925efab62b6a1b", + [6] = "67066dfb891738c460a2e75221d367c5", + [7] = "1953c6191d849b93d1aab79fa4cda95", + [8] = "11be6fb61d35d7e4d680104d039aaf63", + [9] = "3", + [10] = "180026ae5dbe974e7eb06b324927eaf0", + [11] = "1f9a4dff72cd9019164b73b04505333c", + [12] = "43e9ad4a06812782e0fcb244d10ffa90", + [13] = "643262a816c65c4721ec5f69b3669844", + [14] = "233636554b325c46cbad926a62d900d6", + [15] = "2b886afec0a6d18648114e84a91330c4", + [16] = "4", + [17] = "25046e4d32a4c22cb9f8afba3f3ceffb", + [18] = "5905f4c67b99a31319635324c5e95f4c", + [19] = "369e8c7fda6cf7c0d54f91eff4932e14", + [20] = "3e325e8df10598443d22193b2a4bf88b", + [21] = "70a98d624f107a23b9291ed17c65e708", + [22] = "48e20c07cccf03cc10d026cd8f1ef8d8", + [23] = "39ac71be3dfc7f2469a7df772ca4a372", + [24] = "193a5cb83ca65c4bf501088c52fbfd37", + [25] = "5", + [26] = "8c353e6ed18c48d8d54754f51d9522", + [27] = "65de83ef09c1bb44517b0b673997f7d8", + [28] = "32a78c323b093727a3556f3f499b52a", + [29] = "4ec6fa6a98995394f71e0b2207f371a9", + [30] = "13107997fc19873b1902a2a615da9376", + [31] = "51dc60db382d37d1cd141b86b4154757", + [32] = "237cdf6c3a6bafc9ad00209a07355ec6", + [33] = "25640e49e12fb784a6ac33b6d27d6e77", + [34] = "25f4ab6cd383cb4026bffd362b15d7f", + [35] = "411f7f296f7fac0ef30960fd99f42d43", + [36] = "6", + [37] = "2feabe9655a9641a8fa1f87f22531049", + [38] = "720bb70b21823e069d150e3e64d26b7b", + [39] = "177beb203ec9b72d675ca269eab76fd5", + [40] = "30004d5cbb7d2e9cfd60d664924fd5e0", + [41] = "382967f0e5f5feb1984360723a0c4f82", + [42] = "22468c3c9efc7faffb5d3e8dd251fc40", + [43] = "2de84badd9bff0944b460f3b8d0458e", + [44] = "3f349bfee59b20322c96e7608a0a6678", + [45] = "16580e82bde20283ff7045bf8bdf7190", + [46] = "456c8f05a1da32e653cc5b839fa9b9e3", + [47] = "1092ae6dfcff9bf2b3292f357aca1c05", + [48] = "5f73de1b41d27ecef44d72a6f482d7a1", + [49] = "7", + [50] = "474785105e63cb2e42e342d7c24eafe9", + [51] = "4b16b51a17a20de39e3f2a36fc8c9abd", + [52] = "1ee2735f21481546726e185d2fd59c39", + [53] = "2be013c5a5285182d8f04af39b1d6fef", + [54] = "4dcc11434c70dc786ba1dec5ced76a8e", + [55] = "542fb8ff09b332e95786de3e3ec8a568", + [56] = "466c6caa9664b88d975b24d4c5b201ac", + [57] = "5a3d33318760312855953f24bffd9ced", + [58] = "469159fcdc46912a4e3fcab24a5ef2ac", + [59] = "25635a436530a1238a7f4b2f0025e32b", + [60] = "5710d5fd814da30c90229d0952266188", + [61] = "3deb808b5ad9f2cb409d268e094918af", + [62] = "2dbc7a4f609cc9466560d9177a45bfbb", + [63] = "4bfb524b588dd2bb750026deee68fbf", + [64] = "8", + [65] = "235c214fd9dc61623c9955f87db2b12", + [66] = "463c486bc87316cf7424a483bf537d38", + [67] = "41be254c0da85d290b883c6b08421178", + [68] = "4a08dc9a6549845973f15f747e79dff6", + [69] = "1632bc546d2fa40a63b66c9c0b10399", + [70] = "1de0640a5afe477f5b35616ff7a4cf41", + [71] = "52b9f4585f7d01646e479ec08cff289e", + [72] = "353b4f2257a187ae838030e70ad00e29", + [74] = "233e33da1bb170db78a61f5463dea41c", + [75] = "3d7f07763e91eb0d83cf19848bfada59", + [76] = "6d3d18ffb4d9ef81aa9f23dfe9265c28", + [77] = "a8291ed9a50df270c807f51fd931ec", + [78] = "10d7025482f44ccf3b15f625e68fa814", + [80] = "6ae27b936cc99d4c3c02a4ba420adbab", + [81] = "9", + [82] = "10a7130308b2012359b349defd48bb7c", + [84] = "5f41deab0b3d98d43f4998d9dd6feb1", + [85] = "593575a6c6f3d3defc4139e083a23789", + [86] = "14bb748ced6ace4ce9ba942b124e9978", + [87] = "54085d04c4746201ca5df23ce9c207b8", + [88] = "5583209fb536c63c94a689957864db11", + [90] = "4800740b193bc5eb7c114196db77c0d0", + [91] = "3ccce2be9baf4d2f5575efc5d8bcaf5d", + [92] = "7358e37c7bf8fe48d34fbeee594946e4", + [93] = "5f7b21557f767e363b43f867baf4921c", + [94] = "25f9463099ba6747ef039591b8a24142", + [95] = "618ad1c02988e0f3f4ecc2dff670aac2", + [96] = "3274b970794cb897ea021118a5f7fa6e", + [98] = "3589155a412df3496c63328abeb40086", + [99] = "5ecee9fe5868b04b42e25b10cf0f99b4", + }, + }, + { + .p = "d3a1b64e241479381932df4745621009", + .first_non_square = 53, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "3256df5d0e4054ee1c708a8c2a94ce21", + [3] = "1aceb5e620540ea3c8e28ff09e65a03e", + [4] = "2", + [5] = "4a920722c3d286a0acf498eb88a17407", + [6] = "59c0e022516ddfc6f750aed84fc5ae70", + [7] = "123de903d6dc595ff3db324dee5f1a27", + [8] = "64adbeba1c80a9dc38e1151855299c42", + [9] = "3", + [10] = "10fb193db4a2e4fb1183cb7aa4488898", + [11] = "f4ee6591467dcf7223ee39a1828d8a6", + [12] = "359d6bcc40a81d4791c51fe13ccb407c", + [13] = "3259920bf856147b6d524ea42d74cd0d", + [14] = "5a72ba66b8b0b50d7dfc78997218456f", + [15] = "41028b2be43eda537b3de57589b190bf", + [16] = "4", + [17] = "62de61e0af734f1d89f10bc4ac9ae273", + [18] = "3c9d1836f9537a6dc3e13fa2c5a3a5a6", + [19] = "4eacea5adabc97af905b65f1f32a67d6", + [20] = "3e7da8089c6f6bf6bf49ad70341f27fb", + [21] = "665de344f793cfcf0d8851eeaa979209", + [22] = "4ab0fe70c9af2e359407cfb7a9284d2e", + [23] = "55a3bad41617c6c316d63b172d065de3", + [24] = "201ff6098138b9aa2a918196a5d6b329", + [25] = "5", + [26] = "13519dc6a212b6970dbdfa5c48317dde", + [27] = "506c21b260fc2beb5aa7afd1db30e0ba", + [28] = "247bd207adb8b2bfe7b6649bdcbe344e", + [29] = "a108bd629d894d7d4ae6b94fc533244", + [30] = "25de096124247dca639e5b4bdb451969", + [31] = "3d7f485499372a399679f8a3ad2cb393", + [32] = "a4638d9eb13257fa770b5169b0ed785", + [33] = "63142ce93321793c61bc51c04ef70535", + [34] = "ddef86ef8e2539ebeca14b526f44b5", + [35] = "4ce13194f399e69fa318bb4bb8f7ea7b", + [36] = "6", + [37] = "9228193d6c0e38073c07cdf448de5ee", + [38] = "11c081d52a1f27b9dafd424384c59554", + [39] = "5006ac3ae7fc06103b81937bc75a2b33", + [40] = "21f6327b6945c9f6230796f548911130", + [41] = "3f455b8cd2f901c587b0598a682b583f", + [42] = "1df60d29d9e20a850f71ff40123437c1", + [43] = "2382b8ce194e6c36c92a0b3faadaaa52", + [44] = "1e9dccb228cfb9ee447dc7343051b14c", + [45] = "c145f1a27631aa9edaaeb7b54824c0c", + [46] = "671467f745d92daf13ebb67ecf24fca3", + [47] = "264506f56045c3502ef62170be528551", + [48] = "6866deb5a2c43ea8f5a89f84cbcb8f11", + [49] = "7", + [50] = "2810a683232d2f6e74ffd5758f85f69c", + [51] = "1ebedbfc86ece8fe5b90062a149969f8", + [52] = "64b32417f0ac28f6daa49d485ae99a1a", + [54] = "39a0ea18d035261cccbf2d41a9eefb47", + [55] = "694639a2f3d08884ecb2affda5ee61e3", + [56] = "1ebc4180b2b30f1d1d39ee146131852b", + [57] = "5d2cec4ee0c2ce79bf81a15df81ceb4f", + [58] = "2ce9fcc748ecf7848e9dcf2211e67206", + [60] = "519c9ff65b96c49122b7145c31feee8b", + [62] = "12685eaa555f8cb49a90178a0a6015fc", + [63] = "36b9bb0b84950c1fdb9196e9cb1d4e75", + [64] = "8", + [65] = "4de278e7a145b79c2419db6e07e791f", + [66] = "379ddde1c4ac6a9e5ca97ef7aba7a6c", + [67] = "37c6a10abcd0fe2aa60f330f989550ca", + [68] = "de4f28cc52ddafd0550c7bdec2c4b23", + [69] = "2769cef201b1aac7821d582d2d2e8780", + [70] = "639e469a7c754f5cd697dab32f90d07", + [71] = "2c68191bf87dfe5cef79f5f62b726623", + [72] = "5a6785e0316d845c91706001ba1ac4bd", + [73] = "3a6fe5f9d81eb2fe4353d17adde7346f", + [74] = "1576149deacfc14d26864a3cc3e17600", + [75] = "4d9828cf827030052cc60f942d65eed3", + [76] = "3647e1986e9b49d8f87c13635f0d405d", + [77] = "630c6e7117790a971af1517d57363f28", + [78] = "6856e68603816f2c27fdc4c7d5016934", + [80] = "56a6663ceb35a14a9a9f8466dd23c013", + [81] = "9", + [82] = "59830bfb04b7677115c088282226682f", + [84] = "6e5efc434ecd999fe223b69f032ebf7", + [85] = "59925907902ef6ef57cd520278a260c5", + [86] = "632a92f87db0fc76ab82a2d352768c19", + [87] = "16d7959610ea9badc85fb36603a94879", + [88] = "3e3fb96c90b61cccf1233fd7f31175ad", + [89] = "13088ca71d4342c41581472612636828", + [90] = "32f14bb91de8aef1348b626fecd999c8", + [91] = "5c0a55b7b9d58943b809015a4aa020ff", + [92] = "285a40a5f7e4ebb1eb866918eb555443", + [93] = "1592a85e0341d9c9825096e1976e192b", + [94] = "2fb36c59090a20bbaa092c8aa8992ac2", + [95] = "2e74a563b5f9c6a6b01d52288f9c0d6b", + [96] = "403fec13027173545523032d4bad6652", + [98] = "46e35110e4669fed6b51f4b960b27d2b", + [99] = "2decb30b3d3796e566bcaace487a89f2", + }, + }, + { + .p = "d7da4ea4510511593950179f8f711349", + .first_non_square = 59, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "959d1dbbc442f0c03fab00d7b74bc39", + [3] = "54011c029cc999cc59490b7ee97eeab5", + [4] = "2", + [5] = "27a5f203b507150a1470c9475067a7a9", + [6] = "5b106a2f61672bff1fc84537031bb8bf", + [7] = "c1c26a4d8728d54300851fec2a6c397", + [8] = "12b3a3b778885e1807f5601af6e97872", + [9] = "3", + [10] = "5454e217bab81e821a0b173196678210", + [11] = "1682f9cf7225b6fd06af37171fe3fde1", + [12] = "2fd8169f1771ddc086be00a1bc733ddf", + [13] = "217f7c4618539196631e3abcf5fe454d", + [14] = "46176a55e55c6e8920b06a348e37c612", + [15] = "43fc3e63a8bbe3e9e702986f4f1ed133", + [16] = "4", + [17] = "19453763a8648666e6d09e4de90b0333", + [18] = "1c0d759334cc8d240bf01028725e34ab", + [19] = "119bcbb7bff3e1badada7f4d83e36e67", + [20] = "4f4be4076a0e2a1428e1928ea0cf4f52", + [21] = "1d5498842ef5c553b8ef2d356bcc6eab", + [22] = "15b78a01b3f6097e3cf9b453f141e9ed", + [23] = "980e6f8411b4639e84cd6c712a9cba1", + [24] = "21b97a458e36b95af9bf8d318939a1cb", + [25] = "5", + [26] = "20dcca93e1306a7f700b99170fbce6c7", + [27] = "242905638557bc0bd28b0add2d0bacd6", + [28] = "18384d49b0e51aa86010a3fd854d872e", + [29] = "5a6e09373884c6bfa72122a486a177b3", + [30] = "12e5df3ef102359d598724a0811ba203", + [31] = "5c85b8dbe7a3ff15fcc9eb57067b82bc", + [32] = "2567476ef110bc300feac035edd2f0e4", + [33] = "6b8e76260fca9eefcef94f3f2d12200f", + [34] = "3b36f3d67d8463ece78ac1e3396d148e", + [35] = "394b72ee77c8734547637275946556da", + [36] = "6", + [37] = "4b64318604f4ae445368e8876704e136", + [38] = "c3a81ce44aaa2db666a3d16b0201d09", + [39] = "1e45b92f0be82f1042ad3fe274ff0c88", + [40] = "2f308a74db94d4550539e93c62a20f29", + [41] = "3e9c285ed90c12fe79cf4ba4128f6185", + [42] = "2025ee1dd9e72c7313b99e9f1c90d856", + [43] = "3a3dbbf0e96a1a3ce316b144b7826682", + [44] = "2d05f39ee44b6dfa0d5e6e2e3fc7fbc2", + [45] = "60e8789931efd23afbfdbbc99e3a1c4e", + [46] = "fee50de01be07f792ac6f5b9b5de4b7", + [47] = "8b0f0ef7048f8d3e4c9ba6d4ef80f6f", + [48] = "5fb02d3e2ee3bb810d7c014378e67bbe", + [49] = "7", + [50] = "2ec1194aad54eb3c13e570436947ad1d", + [51] = "17e29b58202c9cefddc75b5fafc7e372", + [52] = "42fef88c30a7232cc63c7579ebfc8a9a", + [53] = "3a0c58a5ec20f119c262f12ae5183157", + [54] = "3956efe9d33072a42608b80579e216f4", + [55] = "2be21c25e83850a25db71abbc4a48100", + [56] = "4bab79f8864c3446f7ef433673018725", + [57] = "5386749f14c9429c39b8d9d424f075b5", + [58] = "360395662a2d98180968961c84e61588", + [60] = "4fe1d1dcff8d49856b4ae6c0f13370e3", + [61] = "4238404aca0d8514e461aa1b212a5af6", + [62] = "629800208ccbf1d82b7b1b43ec19118c", + [63] = "245473ee8957a7fc9018f5fc47f44ac5", + [64] = "8", + [65] = "6b2bef42c7770064af9022b31d103d5c", + [66] = "20454e81a6a03a241dbc136180e8c664", + [68] = "328a6ec750c90ccdcda13c9bd2160666", + [69] = "160e654845d6518f69ca871d43a32123", + [70] = "1bb310d630d1bc146d36acc51d7abf11", + [72] = "381aeb2669991a4817e02050e4bc6956", + [73] = "472e264b5e0edc8ec4a88d77a050dc04", + [74] = "49a4a35f203f4e4d29034e654752f75", + [75] = "baf113b921a21b4b432f5c48f679109", + [76] = "2337976f7fe7c375b5b4fe9b07c6dcce", + [77] = "28caa6a79c150442aa8ad26a6a293d6b", + [78] = "1ea04d76bcb64865c84cbabc0eef714b", + [80] = "394286957ce8bd30e78cf2824dd274a5", + [81] = "9", + [82] = "f4596207cde9bd65f928c1c6ad96fe", + [83] = "56f024a084a7418b7fbb56a3398cdf40", + [84] = "3aa931085deb8aa771de5a6ad798dd56", + [85] = "5f4260a2d155f008378db93f90204793", + [86] = "140253b4201d75301a986809baed51d8", + [87] = "f5d00583106340970471bc36ca2d0d7", + [88] = "2b6f140367ec12fc79f368a7e283d3da", + [89] = "6adb209ecb5bcd002bef5b6bee7f253a", + [90] = "252457a2df234a2d14d12df533c572e7", + [91] = "1c21f090707344b4d211c183e4e5bd60", + [92] = "1301cdf082368c73d099ad8e25539742", + [93] = "4c8047a783cda4682655dc2f757b35bb", + [94] = "6eaa3447c9e7a4f0b0afe99836c88ee", + [95] = "69c7233d4237d40d65ac836ac27e305a", + [96] = "4372f48b1c6d72b5f37f1a6312734396", + [98] = "4174bd0225dd49541bdad05e6031258f", + [99] = "4388ed6e567124f7140da5455fabf9a3", + }, + }, + { + .p = "e4ad8bf1a7b946d591595a7347b15f71", + .first_non_square = 53, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "4c49d878822cfbe76fb4b402caaed4fd", + [3] = "3c37757e7487b01dfbc37216d844db99", + [4] = "2", + [5] = "5aeece5c7ed9ca8c1ed52da45babc777", + [6] = "40713762535e9a0c57f602473ff52998", + [7] = "3ecda635990f5dea2acb9b1a9fdefbf5", + [8] = "4c19db00a35f4f06b1eff26db253b577", + [9] = "3", + [10] = "91ce7bde461ea19843dc9847de90e4", + [11] = "125b241be577156bc1797be7208ee62b", + [12] = "6c3ea0f4bea9e69999d276459727a83f", + [13] = "425700a36490fb859641b2b08a7eae0a", + [14] = "10f1f9d70043a045d55a6d116c2a6f31", + [15] = "469981b6614fca719735f3d6d9dcb656", + [16] = "4", + [17] = "72796d6db8598786ae34c9df885233b", + [18] = "2ffd77decdace0bdc4c195185b1f86", + [19] = "1dcf29a92bb5b16be3ff967d956e78c1", + [20] = "2ecfef38aa05b1bd53aeff2a9059d083", + [21] = "417e0eec0ee9eab8893e2c6432f1410f", + [22] = "65551d126459325ddff4e27e0e154850", + [23] = "3394ef48c3876261e519f07c5cc22838", + [24] = "63cb1d2d00fc12bce16d55e4c7c70c41", + [25] = "5", + [26] = "10772742d4d9fbe450d15ef5ffc3fe71", + [27] = "30072b764a22367b9e0f042ebee2cca6", + [28] = "67123f86759a8b013bc2243e07f36787", + [29] = "5cc3d6327e652a41154770644a38b969", + [30] = "4ad60c254ddec972fae777b256a7c5d5", + [31] = "2e00a145ed5a04009a8355499ce70919", + [32] = "4c79d5f060faa8c82d797597e309f483", + [33] = "5cf3346d66af0589ba6cc2ca64333c79", + [34] = "4a3aaa0b4b8c6ede15bc17190bdada64", + [35] = "71363966ddc55278fda04d8b9c1ae94b", + [36] = "6", + [37] = "1b3a4a911ed3a3c94924fa36bb0b2ee9", + [38] = "28e73aa747bd0f9c9a9bc913df016115", + [39] = "6f8a1ed7db16005ca5df3eddb25eacbb", + [40] = "1239cf7bc8c3d433087b9308fbd21c8", + [41] = "6a7533c0bc1acd73a3b48be478dd13a2", + [42] = "9e55812741e9524ca166ce7bff9be9e", + [43] = "6244c591bd3277fca7ec50e93b69221c", + [44] = "24b64837caee2ad782f2f7ce411dcc56", + [45] = "2c1edf23d4d418cecb262e79cb51f6f4", + [46] = "e3c5e20bd259295570a71eec9ecd768", + [47] = "4cf99eaa49470e4938c90a22bc4ccb88", + [48] = "c304a082a6579a25db46de819620ef3", + [49] = "7", + [50] = "4be9dd88c491a225f42b30d899f895f1", + [51] = "3467e2afaf03823c26a922d43928cc08", + [52] = "5fff8aaade974fca64d5f51232b4035d", + [54] = "2359e5caad9d78b08977539d87d1e2a9", + [55] = "bd103977e456b841e966a74aad0e057", + [56] = "21e3f3ae0087408baab4da22d854de62", + [57] = "2c4fbdbb74128aab91bd39e1913a3f27", + [58] = "3371407d6491e3ec1977f1b775823de2", + [60] = "577a8884e519b1f262ed72c593f7f2c5", + [61] = "3ee45bf8835e5badafeb6df43185f5bc", + [62] = "56cb5291a6e682ffcaf3ff8b4150c72e", + [63] = "28449950dc8b2d1710f6892368146b92", + [64] = "8", + [65] = "143912b856d247f8c39d24c1c062491", + [66] = "3c15ad8b379ebaff4763bab01a9bcda9", + [68] = "e4f2dadb70b30f0d5c6993bf10a4676", + [69] = "635cd56cb6cb00cf27fa36b7aedfbc53", + [70] = "43c04f20e4e9ac170210fc23ab9c2dc2", + [72] = "5ffaefbd9b59c17b89832a30b63f0c", + [74] = "bfdaba577a3472dd49bfd77fd19918f", + [75] = "4867bf869eed29c05977dffef1a6ea8c", + [76] = "3b9e5352576b62d7c7ff2cfb2adcf182", + [77] = "2006ed422b0a69dc4d57d750f38d34ab", + [78] = "4b050d62afd87d0f33db026adbb1c115", + [80] = "5d9fde71540b637aa75dfe5520b3a106", + [81] = "9", + [82] = "b0dc8230270044d0edf3ab1ad97b16d", + [84] = "61b16e1989e571647edd01aae1cedd53", + [85] = "46e0143233ee83c76c0b13168f19a07a", + [86] = "52a1b3caadecf3720ef1d80d467e74bc", + [87] = "14589812286e6d6f123be7173952a95c", + [88] = "1a0351ccdf06e219d16f95772b86ced1", + [89] = "539cf0fd123cf0a349f1fa6ffdfc4a68", + [90] = "1b56b739ad25be4c8cb95c8d79bb2ac", + [91] = "5662acc7560be428cb14e9cc5a4e2128", + [92] = "6729de91870ec4c3ca33e0f8b9845070", + [93] = "5cb5d378c21458c2912dd06deb1a7735", + [94] = "552aec748d185891ca356d1379aed772", + [95] = "4fc9e390534febdb6c6ec3fea343b79c", + [96] = "1d175197a5c1215bce7eaea9b82346ef", + [98] = "4ca9d3683fc855a8eb3e372cfb651409", + [99] = "37116c53b0654043446c73b561acb281", + }, + }, + { + .p = "cbcabb1f226a0c65460ae623608b1ad9", + .first_non_square = 59, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "20aa56375597d8cdab6a03b709d4a278", + [3] = "49d44e3b109e23292d3d13445b9b8eea", + [4] = "2", + [5] = "1e0e210eb335cae047c35d767f674637", + [6] = "625c5c0f38eca85e2ecb80174fa4a95e", + [7] = "3745673b54e841a6a4fb1a8a3759b8bf", + [8] = "4154ac6eab2fb19b56d4076e13a944f0", + [9] = "3", + [10] = "4f0396e7b9df52bac992b43575c33c35", + [11] = "4d679981c0acbe4a8e305ca2cc963ef9", + [12] = "38221ea9012dc612eb90bf9aa953fd05", + [13] = "6596f0c8f4a91c4a17e751f02c81a82f", + [14] = "20d6292a2fdef5fadd66420ecd85cbd3", + [15] = "266647395842faa57f249c38db0f1eb1", + [16] = "4", + [17] = "3cba2f5354d5ba2192012e780019d728", + [18] = "61ff02a600c78a69023e0b251d7de768", + [19] = "577f304041afec01a5c075ab05175217", + [20] = "3c1c421d666b95c08f86baecfece8c6e", + [21] = "28429bbbd4c6513ad4f08b5ea351f8a", + [22] = "29cf35616a805dd926e7cdcbe6d63680", + [23] = "55d452f7467ccbaa62afc2985787cf17", + [24] = "7120300b090bba8e873e5f4c141c81d", + [25] = "5", + [26] = "29e4c4e321eced80ec26e6133bf20af6", + [27] = "11b22f920f705d1641ac53a9b24791e5", + [28] = "5d3feca878998917fc14b10ef1d7a95b", + [29] = "5b4b3eed097bd01db9cd0c7a288b56c3", + [30] = "3575cde15467aaaae6e0187e24d6d2ee", + [31] = "5840337f0dc69197ea45a3a340700304", + [32] = "49216241cc0aa92e9862d747393890f9", + [33] = "54002bd7d536884838b4eeda47283774", + [34] = "4951e9a1bd020bb682f868df70b4bfbc", + [35] = "376b66fcc1a223932d2b34a06781ff17", + [36] = "6", + [37] = "3f93f4d11e213ad8cdab598763039e7b", + [38] = "324d3ab2b47ec5393ef6070e5374bb34", + [39] = "261e82ec98f3c07d5dc28a1484db4146", + [40] = "2dc38d4faeab66efb2e57db87504a26f", + [41] = "1976a2ea6012d0647da3523808d36740", + [42] = "42de54dbb74f15f8e3186afc44a48501", + [43] = "4f751abc9fe3a2f84f1ccb3fd63bd3f6", + [44] = "30fb881ba1108fd029aa2cddc75e9ce7", + [45] = "5a2a632c19a160a0d74a18637e35d2a5", + [46] = "494db3f0b07d25c8a30faeec07f9b5e8", + [47] = "182d2c235507872a1e99c776b83ccfbe", + [48] = "5b867dcd200e803f6ee966ee0de320cf", + [49] = "7", + [50] = "28770c0a7672d060ecf8d3902f63ee81", + [51] = "d05c776625315a66187a12849c70f79", + [52] = "9cd98d3917d3d1163c42430787ca7b", + [53] = "286f9d986059b7f9938b43ead8c8d654", + [54] = "5b4a590e885becb546579a228e62e141", + [55] = "51aa04d6a5d11b6edc1a6fe2233eee6b", + [56] = "41ac52545fbdebf5bacc841d9b0b97a6", + [57] = "5aa5e71f1dfc8b3cc0e026612f7e1fb6", + [58] = "35533f553747e464072c4440bac52a0e", + [60] = "4ccc8e72b085f54afe493871b61e3d62", + [61] = "24551bf46096d057148ef425467a9ba9", + [62] = "3e52033154f120b235978178d647c143", + [63] = "25fa856d23b1477157199684ba7df09c", + [64] = "8", + [65] = "563a6e8eb33b076dbe065396eb315574", + [66] = "5e864cca82f747ea276994780ac8a19d", + [68] = "52565c7878be98222208893360576c89", + [69] = "5ce922cd0c1b446c1e4ca6c4e0f24df8", + [70] = "11f934d12f2ffcc38b0a891a84025b50", + [72] = "7ccb5d320daf793418ecfd9258f4c09", + [73] = "52a7a870244bba2a55519bf744ebed05", + [74] = "ad23956ae428025f0a0257bf2dda72f", + [75] = "266fef16f1bd68fca9e46bf0f70c6b20", + [76] = "1ccc5a9e9f0a3461fa89facd565c76ab", + [77] = "14072fe6875f3477f254a09d386e4654", + [78] = "38f4c4a6b86698a0480425b350bdbebe", + [80] = "539236e45592e0e426fd704962ee01fd", + [81] = "9", + [82] = "3f7b778244278ec4835d885d4839b2b4", + [84] = "50853777a98ca275a9e116bd46a3f14", + [85] = "22d770096f8b019cc1dbe271c8d798b8", + [86] = "50718b1afe946781b22c7ce102fd4243", + [87] = "50259cceac8c1f8b42544d960fee46fb", + [88] = "539e6ac2d500bbb24dcf9b97cdac6d00", + [90] = "214009980b33ebcb16ad367d00be99c6", + [91] = "2df48de5831087e5fa6d5f4b545beb59", + [92] = "202215309570751080ab60f2b17b7cab", + [93] = "384da52f8b0dd624357002ef2753ab23", + [94] = "2d9c483316aab53053292ffc1364a199", + [95] = "17d3a3a478758dcb2d715b6a6c291770", + [96] = "e24060161217751d0e7cbe98283903a", + [98] = "18dda06434bce13a69db33dde445566f", + [99] = "1c6c11661f9c2e7a64862fc50537a212", + }, + }, + { + .p = "fe4140ab1703f4636f45c48bfb0068a1", + .first_non_square = 53, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "7ba6780b0fed766515a7f52780bc9293", + [3] = "6149de094ae83131a239de5a6df50f3d", + [4] = "2", + [5] = "8e08f47c68cea90d366ed88b052dc0d", + [6] = "712eb140f38d2eda5c637e54d10bef43", + [7] = "647ecb433b6c7bac3b1d2f9d6054d0ba", + [8] = "6f45094f729079943f5da3cf987437b", + [9] = "3", + [10] = "329e80ca3b64fa4f1155f9c270b8f4ce", + [11] = "24c5b58cbd45b14e27fb39d98513e861", + [12] = "3bad8498813392002ad207d71f164a27", + [13] = "30b405638cc9503430b6aa41495bb61", + [14] = "2f1bc9fc42ecee2906bb9cb2c4b48844", + [15] = "1060959a729316d3567679f61abc49af", + [16] = "4", + [17] = "2743cff56b8c8f8ee97f7446ae99739e", + [18] = "74b2277618c46ecbd1b21aea87354f18", + [19] = "3fbbfcdfd2487c9b851129505f179076", + [20] = "11c11e8f8d19d521a6cddb1160a5b81a", + [21] = "6fc009527f629afe432b1f4f1e4b1fea", + [22] = "3f01ff2d6c6d833d28056e6072b25e60", + [23] = "506f5b0f98fa595bed0cbc10ab7c5ee5", + [24] = "1be3de292fe996aeb67ec7e258e88a1b", + [25] = "5", + [26] = "10be4164d8254ac55662322c7ddcf6fe", + [27] = "259c5970c9b49f317767d6834edec516", + [28] = "3543aa24a02afd0af90b65513a56c72d", + [29] = "5e4f3f1a728ca81e0562ea16d3b3cffd", + [30] = "5f7adf9503c5bf6b2ed871ee578d7f7f", + [31] = "5a732eeb6c03d753dce4cbca35427431", + [32] = "de8a129ee520f3287ebb479f30e86f6", + [33] = "515718e3cde407eb2f1f134140cb21fe", + [34] = "58f96aeb670e2022511ae47d9ecba760", + [35] = "7b8229e2856880ab02cd93d5da144228", + [36] = "6", + [37] = "6b81b8e27b6cf32c0457ca6fdadea755", + [38] = "b8e8b04539168fe235d3def1490dad8", + [39] = "15bf17346ca8088e3cce95dfb9c418f7", + [40] = "653d019476c9f49e22abf384e171e99c", + [41] = "70c50f028034d998186c4fa9b24ec776", + [42] = "4025367c12a3595db005c840e28fca2f", + [43] = "10bd851db1dbc8acea1e2f5c9a539027", + [44] = "498b6b197a8b629c4ff673b30a27d0c2", + [45] = "1aa1add753a6bfb27a34c89a10f89427", + [46] = "2f0c4d81e381d9b019bf8094b3eecee6", + [47] = "15534147c6ebf56b2ecc5c10e0770e14", + [48] = "775b09310267240055a40fae3e2c944e", + [49] = "7", + [50] = "6dbdd6e1219b67328dbc40ad8dae0b9d", + [51] = "70e70926d41fd03e102a5a44ce1229f9", + [52] = "61680ac71992a068616d548292b76c2", + [54] = "554ad317c3a3982ba5e4b67278236528", + [55] = "1459f9f6ec22944520f4871412088d85", + [56] = "5e3793f885d9dc520d77396589691088", + [57] = "341ef10187760d3c36d527145b4ad817", + [58] = "529922ce1cc858cb8a2b30f4684aa9fd", + [59] = "37be2dfe9028978862327c01c89586e2", + [60] = "20c12b34e5262da6acecf3ec3578935e", + [62] = "6ecd16e975917832f0959b6c9542da42", + [63] = "2f3b211e9b417ea14211ca4c25fe098d", + [64] = "8", + [65] = "7345a2c482c5a9588f299989ac40ecad", + [66] = "18770759a8b2f26d1a24dba6c2d52a07", + [68] = "4e879fead7191f1dd2fee88d5d32e73c", + [69] = "3a0988799c07916f61906d56b5afe5ec", + [70] = "1d94b3814a59d9cd691f356c42e05881", + [72] = "14dcf1bee57b16cbcbe18eb6ec95ca71", + [74] = "1d13c613cdf866cb5b13e4a51dc7ebe3", + [75] = "16112b27b77ef2ceb36a3153d0378511", + [76] = "7ec946eb7272fb2c652371eb3cd147b5", + [77] = "3ea093d7619691c048b296bdc0d37662", + [78] = "3af49044c061c8aad58fc0604c081c2c", + [80] = "23823d1f1a33aa434d9bb622c14b7034", + [81] = "9", + [82] = "21662760541dd24c3115bfa4f0b2f76d", + [84] = "1ec12e06183ebe66e8ef85edbe6a28cd", + [85] = "34b4035b5edce75b16326453cc7b7c59", + [86] = "67f099b3ac6c1e2285f800c1169f3e74", + [87] = "28d2792fa43528197df02a2ab64f10b4", + [88] = "7e03fe5ad8db067a500adcc0e564bcc0", + [89] = "131cea5295f0f890d408cd55292baa9a", + [90] = "6665be4c64d505763b43d744a8d58a37", + [91] = "6166d2bbeaabb0fc8f2a7f54155dba4c", + [92] = "5d628a8be50f41ab952c4c6aa407aad7", + [93] = "5d9415660fcce03cc4807ceb85b729c0", + [94] = "63b43ba1ab89508e123048325aa02be5", + [95] = "453ec81c6776384522e1ecda1b6ddee5", + [96] = "37c7bc525fd32d5d6cfd8fc4b1d11436", + [98] = "66c9864c2a725f9949c666709426c822", + [99] = "6e5120a637d113ea77f1ad8c8f3bb923", + }, + }, + { + .p = "c952099317697fbee819206f51261769", + .first_non_square = 61, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "1030ca5f555429e4df1a0364d52ed574", + [3] = "1c008a94d898f5934cc6768dc4aa9e7", + [4] = "2", + [5] = "6453a0cada2df423a5cadbfdb1f7a43a", + [6] = "4ead969961f9970cc0957f4c1997a2eb", + [7] = "9516aa771b15128eb5879ba5cbbcb6c", + [8] = "206194beaaa853c9be3406c9aa5daae8", + [9] = "3", + [10] = "218b5770aff5df5ee5dea41f84d956f8", + [11] = "2e5ad00f8babb3bf597470ccdefa6904", + [12] = "38011529b131eb26998ced1b89553ce", + [13] = "5b7093eeeaabe2273d89ed1269e95a8d", + [14] = "150e9ff34aebd4279f3f194d0b008b9a", + [15] = "52f554395146f4e92284fd0195f3da81", + [16] = "4", + [17] = "e87f72fca45eea33de5b19bdc8598a6", + [18] = "30925f1dfffc7dae9d4e0a2e7f8c805c", + [19] = "dbbf4eb69d3d3d80113b9c179dbdf14", + [20] = "aac7fd630d97779c836873ed36cef5", + [21] = "343a4efea6c533ef26fbc9c0455bba4b", + [22] = "561d91e30353cd92dad551df29b34330", + [23] = "1c46770900025779e503a37fbf3652f", + [24] = "2bf6dc60537651a566ee21d71df6d193", + [25] = "5", + [26] = "d8061aede379d718c4477b0c72eeb0b", + [27] = "54019fbe89cae0b9e65363a94dffdb5", + [28] = "12a2d54ee362a251d6b0f374b97796d8", + [29] = "1a00dd8133c4574015541507f34fa2a2", + [30] = "354823c12c93d938a6150ca543c49001", + [31] = "2c50d713847df4e0e6c8092bbb7ff748", + [32] = "40c3297d5550a7937c680d9354bb55d0", + [33] = "1dadd4e7aed55d1dee86fa9fbec2b5f9", + [34] = "495c10a814ec41ca882fd0a3db20dae0", + [35] = "e02ae2c2ae827bcbcb8d5cee71ce245", + [36] = "6", + [37] = "48666c8d4ae91cdb3baa3faaf209f863", + [38] = "1348689ee8394ec3c373f58427071294", + [39] = "22ebc3a88ac979c4cb232cb96ef56c3d", + [40] = "4316aee15febbebdcbbd483f09b2adf0", + [41] = "5d6e17005c737be1d08b4c361e7c38aa", + [42] = "63bdca4c2bc7704338cb6b9040f977bc", + [43] = "bbcd28418772487d60fa0e99ee30f4e", + [44] = "5cb5a01f1757677eb2e8e199bdf4d208", + [45] = "63a8d8cd77205cac09477389c4c0d545", + [46] = "27626a82bfa70599fc17246961bdadd0", + [47] = "e64fa81b1411430a01be20a26516d3", + [48] = "70022a536263d64d3319da3712aa79c", + [49] = "7", + [50] = "50f3f3dcaaa4d1785b8210f829ea2b44", + [51] = "4573f3634cf8d8277095b591bba6eb32", + [52] = "1270e1b54211bb706d05464a7d53624f", + [53] = "4b910f3075773d693fc6320490320417", + [54] = "22b6ba390e83456759a75d74fba0d158", + [55] = "43d64c3a87c506ed9f669fb02a34490f", + [56] = "2a1d3fe695d7a84f3e7e329a16011734", + [57] = "f9eab4f7d57e3626e924cb0a2ed38d1", + [58] = "2c268106581c388b69a240d04f41ddb3", + [59] = "5468c6518f3cc44a8b95e3bebafe1160", + [60] = "2367612074db95eca30f266c253e6267", + [62] = "45bc5f2b116bb2147e21226906d83f5e", + [63] = "1bf43ff65513f37ac2096d2f16336244", + [64] = "8", + [65] = "3a05b5275ba2635e914620a14673f977", + [66] = "1a17a7a83581669f72accc1078c3b313", + [68] = "1d0fee5f948bdd467bcb6337b90b314c", + [69] = "212575df2c4a30476197bbdee2f94cc7", + [70] = "a3f6dea37e9f80dc82f120598fd4bf", + [71] = "f488a226be605e99163987425d9d390", + [72] = "6124be3bfff8fb5d3a9c145cff1900b8", + [74] = "13d134042559929d1edc56f26b66f3b", + [75] = "8c02b4e83afccbe07fe050c4d755183", + [76] = "1b77e9d6d3a7a7b002277382f3b7be28", + [77] = "173a062e52c9d7f72af37a962c86bc64", + [78] = "564a72f1159c013f5c9bad4a81a1e2e2", + [79] = "4398a271233b37edbd0ff6c5bc3dba1", + [80] = "1558ffac61b2eef3906d0e7da6d9dea", + [81] = "9", + [82] = "360ac3f246c2a2011620260c69e306ee", + [84] = "60dd6b95c9df17e09a218ceec66ea2d3", + [85] = "1042e7ab08c6e4551896de0fc918b9a7", + [86] = "bf0a7212c4ed469c981a78d7c6c7e86", + [87] = "4e6d3d71bd2dca40b63270d75cb33802", + [88] = "1d16e5cd10c1e499326e7cb0fdbf9109", + [90] = "64a206520fe19e1cb19bec5e8e8c04e8", + [91] = "53cbd73f05e4d2cdd9ea452367ba48a3", + [92] = "388cee120004aef3ca0746ff7e6ca5e", + [93] = "5068af97e0ba758c38264b3fb6aaba9c", + [94] = "3d7f4045e3fa05122e1616448e2b059f", + [95] = "2b0448ad5e65cf7b24cc311cd17c2e1e", + [96] = "57edb8c0a6eca34acddc43ae3beda326", + [97] = "49893d9e5a5a5c7bb1c62e154d45677a", + [98] = "57fc80f7c21c5a7cce6308ad7cde413d", + [99] = "3e41996474666480dbbbce08b436dc5d", + }, + }, + { + .p = "c4ed76cc85621982d0467c08b185a479", + .first_non_square = 53, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "3f8cc442a5387175ec9f6de0eb3fcfe6", + [3] = "5904ffdcb4ae08d74f449e78de9eab94", + [4] = "2", + [5] = "259e201e5d0138c02f3566bfd710b661", + [6] = "32b732707de2692db32c7ea095415db8", + [7] = "65daac5f051d65191914b053e23ef41", + [8] = "45d3ee473af13696f707a046db0604ad", + [9] = "3", + [10] = "40b664afaf338d62876013bbf2850e05", + [11] = "4939a174028adff8511dd38caf5f62fa", + [12] = "12e377131c0607d431bd3f16f4484d51", + [13] = "4ed277339c1cddb3c56b926ece26e9b3", + [14] = "52db8f0f6f42d7552ccd23ca9d43c858", + [15] = "5da61b91394552f37eea84e6e9b9e447", + [16] = "4", + [17] = "3263fc1c526565e2ffed7234ab9ede85", + [18] = "6472a0495b8c5210a683265efc634c7", + [19] = "20ffb9b29d785211f5fb2761e31d1051", + [20] = "4b3c403cba0271805e6acd7fae216cc2", + [21] = "4e785976b5b051b1b2e78ffcc9067f4e", + [22] = "2e284efd9784af8211500f8c36f5a70e", + [23] = "594077cd6306cf9a454adc544da4d3d6", + [24] = "5f7f11eb899d472769ed7ec78702e909", + [25] = "5", + [26] = "2e2ba3ff7ddf95e9b6def6042acaea23", + [27] = "462188c998a801031d875f61ea565e43", + [28] = "cbb558be0a3aca32322960a7c47de82", + [29] = "3fdb558ea0ae7f05f9623ff54ff6c31", + [30] = "399eecae8ad427718879430013cbaead", + [31] = "1cc235d349911eb835346be57f23afd4", + [32] = "39459a3e0f7fac54e2373b7afb799b1f", + [33] = "3ee92e429c7167e910ad8d9e907ce9e6", + [34] = "9a58bf423affc176de6871c6946427f", + [35] = "217de1bb8bb1ab729df5ceb28cc237", + [36] = "6", + [37] = "4a7d3127acb1d9d63fbb12d1998acbcd", + [38] = "37a1b1cc5ce5955e6927b8a0be607672", + [39] = "67dc5debbe41df6e4f625aa1282f90d", + [40] = "4380ad6d26fafebdc1865490cc7b886f", + [41] = "59027e0c78b977e07824ad3f13d8fb83", + [42] = "37abc1ab524a3fa6426e7699e79ed055", + [43] = "1f5889733073ba0dbc15699a91e9ce77", + [44] = "327a33e4804c59922e0ad4ef52c6de85", + [45] = "541316716e5e6f4242a647c92c538156", + [46] = "1045c1a86d83c28384cc59075121c424", + [47] = "4e57a3fbf4a57fb46047b4ab5a9d9e13", + [48] = "25c6ee26380c0fa8637a7e2de8909aa2", + [49] = "7", + [50] = "4c1b184bd0a9fbb8016fd2accacc3974", + [51] = "5f3dc1f5436670ae7db2a3697e96fc1", + [52] = "274888654d285e1b456f572b1537d113", + [54] = "2cc7df7b0bbaddf9b6c10026f1c18b51", + [55] = "5f18346aeb83dd5f3d12ba08d2626129", + [56] = "1f3658ada6dc6ad876ac347376fe13c9", + [57] = "1322a9c3b403434ff5f0844599617ca7", + [58] = "35387bde818eb63ada2200a8961719d1", + [59] = "f15241a33b0cfb446f6b396297ffbf3", + [60] = "9a13faa12d7739bd271723ade11dbeb", + [62] = "45c11c41de0139f08cc806b248eeea7d", + [63] = "13190051d0f582f4b4b3e10fba6bcdc3", + [64] = "8", + [65] = "2f44ee31ef11f1e041c5dc4734a05708", + [66] = "4acbc94b0fd58ca158900d5ce645bec", + [68] = "60257e93e0974dbcd06b979f5a47e76f", + [69] = "4cdf1a7305f09d090eaeda3aeae4a635", + [70] = "4ae10ea94a44e9be9451a847e77a3936", + [72] = "c8e54092b718a4214d064cbdf8c698e", + [74] = "3444a9a3dc80764eb53f9202edb24a12", + [75] = "333e11b67ca1f92eebca204af60e10f2", + [76] = "41ff73653af0a423ebf64ec3c63a20a2", + [77] = "33f489c7462d8f1ae74f1c038423686", + [78] = "1770c4abd4023f184ba032ba66c8ade3", + [79] = "3c4c81760ef85c7b571b4f891649e64f", + [80] = "2e74f653115d36821370e1095542caf5", + [81] = "9", + [82] = "55eb50263e7b6e913814c68ba433a0b3", + [84] = "27fcc3df1a01761f6a775c0f1f78a5dd", + [85] = "444699a6ec75af134e8304bf932e79db", + [86] = "2a80de463669824da6b3253c088d97e5", + [87] = "51bb41a01003857029b5fb4020e9c1d7", + [88] = "5c509dfb2f095f0422a01f186deb4e1c", + [89] = "1923d478504b67b59ec8ae1a154654ff", + [90] = "2ca48bd77c7715b3a2640d4d9f67a6a", + [91] = "ca61e8231f3b59f1a97cedd8768fbc6", + [92] = "126c8731bf547a4e45b0c360163bfccd", + [93] = "479c97732d6fac4a0c4ad8964b95adf7", + [94] = "356870d65524375c5802aac1ff4c506a", + [95] = "63840baecb9ce0a51a270159bc79796", + [96] = "5ef52f572278b33fc6b7e79a37fd267", + [97] = "3610283097aedf2a259556d93489ea97", + [98] = "32fe703979c6e733d7cf09150bb36658", + [99] = "16bf6d8f823e86662312fe9d5c988475", + }, + }, + { + .p = "edf5623aef85b0b731e8f3e4c9e8d089", + .first_non_square = 53, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "16fcdbe33357a001d4fc47a63b82b779", + [3] = "1ecf4968a0192536a7749d06021eb42d", + [4] = "2", + [5] = "20a67fac9adbaf3e3780a6234ab6822e", + [6] = "2af9620e1f106e9a9051afc7aad33623", + [7] = "6ca9e7acb8e5b669c9b88ca94e76fdb", + [8] = "2df9b7c666af4003a9f88f4c77056ef2", + [9] = "3", + [10] = "4b00db7c853c5b4f00c6644aad3be157", + [11] = "2d736e49f3108641e7452d9978126b30", + [12] = "3d9e92d140324a6d4ee93a0c043d685a", + [13] = "43cac0cde7a35ba38264df5cbcbb4cd5", + [14] = "41a304d2883c6a82d4fb6b2c3079e110", + [15] = "67b91838119086d8078fd5be1bc8080c", + [16] = "4", + [17] = "5bd9ce3ab9d83d23da97a992ad7057d5", + [18] = "44f693a99a06e0057ef4d6f2b288266b", + [19] = "6bf0939c5e1638d3f76312968f659bd3", + [20] = "414cff5935b75e7c6f014c46956d045c", + [21] = "597b55effbb87b39e16b6d017bf7b30e", + [22] = "2c06cac16e38fca86d4478f9c87c625d", + [23] = "3c68a5b1ddb3dde1e92ccd7ec30a0b59", + [24] = "55f2c41c3e20dd3520a35f8f55a66c46", + [25] = "5", + [26] = "15af5f9e777e5614e2b9c15efe617ffa", + [27] = "5c6ddc39e04b6fa3f65dd712065c1c87", + [28] = "d953cf5971cb6cd3937119529cedfb6", + [29] = "2715ddb62536c46c4eea2bc625137fcd", + [30] = "212c5620fd99f5f09808644e22c79c32", + [31] = "6b577ba061d38d163ed349282302a120", + [32] = "5bf36f8ccd5e800753f11e98ee0adde4", + [33] = "13aa3aa2e45a174e92d9731e834dd329", + [34] = "5f856c5a327c79f10ea1e2a8d7703c3c", + [35] = "2dc1e3e916a6334eb3477947df87b8ae", + [36] = "6", + [37] = "2ce03f825cbb1e23600f9aa78fd89284", + [38] = "f0756eb9a9c43ad60272f73d2f20934", + [39] = "312aa19e77e6fef0afd8ad15ba1059ba", + [40] = "57f3ab41e50cfa19305c2b4f6f710ddb", + [41] = "56fb9e4458d3ec5aa118b9631c581c61", + [42] = "6a4cd4bfebe6ce666facf556c29ab9e", + [43] = "36c0e5bef8ace24e6a9b6a35dc24b702", + [44] = "5ae6dc93e6210c83ce8a5b32f024d660", + [45] = "61f37f05d0930dbaa681f269e023868a", + [46] = "35dab1813560b2e575205b9c85ba76ce", + [47] = "5037067f108024661ae1aa2c5c3228cd", + [48] = "72b83c986f211bdc94167fccc16dffd5", + [49] = "7", + [50] = "72f04b7000b6200928ed663f298d955d", + [51] = "f5a4507c2325355cdb0dadb2b2bce2c", + [52] = "665fe09f203ef9702d1f352b507236df", + [54] = "6d093c10925464e780f3e48dc96f2e20", + [55] = "3eca2d8e6904692c541d73928b4b8451", + [56] = "6aaf5895df0cdbb187f21d8c68f50e69", + [57] = "27423a9ff36f3d4ef62ac239f3ac9262", + [58] = "4d1eab01cec65f80ea32b0606b44490", + [60] = "1e8331cacc64a30722c948689258c071", + [61] = "274990b8bb86788b18d8567d7cf13f7f", + [62] = "2012553a6ccaec6d59c20d078ad45a53", + [63] = "145fdb7062ab1233d5d29a5fbeb64f91", + [64] = "8", + [65] = "2323facf1d23fd1dca99c58dcf9f51d1", + [66] = "abb680a9971a272a8ea46b2364fc14a", + [68] = "3641c5c57bd5366f7cb9a0bf6f0820df", + [69] = "6fe190bed95ca359eb6734e670f50c4a", + [70] = "15c4010e04617c35f94feed5c2417719", + [72] = "64083ae7bb77f0ac33ff45ff64d883b3", + [73] = "6bee761e1205d462392ce8e9c95c7da8", + [74] = "596eca3cd2371ce3ec9ffca3b68bc077", + [75] = "53e8f32fcf07f6a5eca1e2c6bf4f4ba8", + [76] = "16143b0233593f0f4322ceb7ab1d98e3", + [77] = "71702a65ae7de31ccb0de3444caf69af", + [78] = "114dfd1ba42d0cdda59bb8d4845e6f6d", + [80] = "6b5b63888416f3be53e65b579f0ec7d1", + [81] = "9", + [82] = "2ca2b887752daa4e112076a9f94ee2a4", + [84] = "3afeb65af814ba436f1219e1d1f96a6d", + [85] = "584290bf297fad6e90ca21b3a654a2ea", + [86] = "579d6f1c2105e88017132be6c7046179", + [87] = "272af66060f7c2226c9cf2d1b97a9396", + [88] = "580d9582dc71f950da88f1f390f8c4ba", + [90] = "cf2cfc55fd09eca2f95c704c2352c84", + [91] = "305a0b4b9244b27f0fac4d3f66cb1493", + [92] = "752416d7341df4f35f8f58e743d4b9d7", + [93] = "14764518d2fa770b40d7b124c1028271", + [94] = "12413e5231c1fbf54bf1ae472e0be00e", + [95] = "73033d976e08cf57e754d4502cee064f", + [96] = "420fda027343f64cf0a234c61e9bf7fd", + [98] = "4d0b5f04882050aa5f02fe592955cc3a", + [99] = "659b175d16541df17c196b1861b18ef9", + }, + }, + { + .p = "f216567317bd6168b283b35efdeb6e01", + .first_non_square = 61, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "480d3cc58db85c317fd3ca162a7ef31", + [3] = "751e72f645812eae49b9e8f43808b53c", + [4] = "2", + [5] = "66a75882537b0fd3e89cfaf5a83e5caf", + [6] = "47664935d814e997186d42dfa98dd547", + [7] = "4da889482696f681bdbef67c7ac1796e", + [8] = "901a798b1b70b862ffa7942c54fde62", + [9] = "3", + [10] = "57d17116e7de4d7c7380b35d174c50fe", + [11] = "692649e1555a93b8fa42eafb084cf8a1", + [12] = "7d970868cbb040c1f0fe1768dda0389", + [13] = "3209b67f7292b1ffb4371dc03ba01083", + [14] = "148d5a6790f3e04b3568bf944c02fe61", + [15] = "5520d9f992eb5c8c8881685999651f93", + [16] = "4", + [17] = "57d481f0380db09125d31dc6dfd1d9c9", + [18] = "d827b650a92914947f7b5e427f7cd93", + [19] = "69962be7fbbdd6eb3f9293403a845b10", + [20] = "24c7a56e70c741c0e149bd73ad6eb4a3", + [21] = "4ce832377d3bc8b2e4d6a23d6f5dd99f", + [22] = "331c2415f14f2d68991cf9c2e2fc696a", + [23] = "52c3351f96e116c602e2ca5e4298e8a7", + [24] = "6349c40767938e3a81a92d9faacfc373", + [25] = "5", + [26] = "14d036065850428ccb1ba5e425fa304f", + [27] = "6d45026fb8c62aa22aaa077daa2eb1b3", + [28] = "56c543e2ca8f74653705c66608687b25", + [29] = "29f9490f6684ea66db901d68cce1cdb1", + [30] = "576da7973e26fea493d4f7b7d53fb53", + [31] = "192cd4b66179a4082118574bfc148b27", + [32] = "12034f31636e170c5ff4f2858a9fbcc4", + [33] = "23224092a600150201ba52b3424456d7", + [34] = "5f9b7eb636b189b226aac177355abc25", + [35] = "733b83f9abd4bc87d247385c96040338", + [36] = "6", + [37] = "3d5cdd23a2a5a3f9d4d323b3f874ca9b", + [38] = "657de6d78704b86d6df714f94c9596b7", + [39] = "25a875a44f870578858989b880e1d053", + [40] = "427374454800c66fcb824ca4cf52cc05", + [41] = "5bed9dc9cb362674bda905c0aac4335", + [42] = "f12748e2759fd3766c92ead058963ce", + [43] = "9ccd7e40b4b4dbe60c0e14bbe7f12cc", + [44] = "1fc9c2b06d0839f6bdfddd68ed517cbf", + [45] = "41dfb313e2b3ce1307533d81facfa80c", + [46] = "4cc8c3b03683a8d1853c9e55ec8d52e8", + [47] = "3f765db35fcf6e1a387d4ecc26efd1e5", + [48] = "fb2e10d197608183e1fc2ed1bb40712", + [49] = "7", + [50] = "168422fdbc499ccf77f22f26ed47abf5", + [51] = "2e3b00d48ee6701ed7f985e0698e7e1e", + [52] = "64136cfee52563ff686e3b8077402106", + [53] = "6f4feac060b10c8f42797ff7f442ea12", + [54] = "1be37ad18f7ea4a3693beac00141ee2c", + [55] = "769f25532938ca79dd2823b747b11e1e", + [56] = "291ab4cf21e7c0966ad17f289805fcc2", + [57] = "3a8c4047c4ddf27d1e5e917d9185a6b", + [58] = "69a0f3549b38d0265f39e4d632238958", + [59] = "16b4266e9fcb5601a88ba6a1eee156b1", + [60] = "47d4a27ff1e6a84fa180e2abcb212edb", + [62] = "158d6e26917f81791039a0a8358c9866", + [63] = "91cba9aa3f87de37946cfe98da701b7", + [64] = "8", + [65] = "cbe13f6bfadaee035d56a39bf98bfad", + [66] = "6604d1e998f3793831782f4d99b1bd84", + [68] = "426d5292a7a2004666dd77d13e47ba6f", + [69] = "1b280a5d865f3099592b6d469a6f3ac", + [70] = "167dd1d604c01acd4591c8a2c13e301f", + [71] = "271e22c50a6918cd603a20c2872a8b59", + [72] = "1b04f6ca152522928fef6bc84fef9b26", + [73] = "11a5924dfa463201c0cc2c515c1f0bf1", + [74] = "60091028fb4a74808bad9094366d9379", + [75] = "656b91e92c0b26960b9a26071c54ae2a", + [76] = "1ee9fea32041b392335e8cde88e2b7e1", + [77] = "2bdf95db0fa53563fe363c057dd8bd33", + [78] = "3df809dc85028674ec0781daa86cdc8c", + [79] = "2b5c1a1ba7726ca49bdb8ffb265cebc7", + [80] = "498f4adce18e8381c2937ae75add6946", + [81] = "9", + [82] = "4fbde7f74ad09eca78d83d64e54c9a30", + [83] = "26e0943fdb9849c21d9f0cccdee7b474", + [84] = "5845f2041d45d002e8d66ee41f2fbac3", + [85] = "1742e5ddddcdc922680c7ccb36f25999", + [86] = "3db8bbcd65fc815230dc101898dd51f9", + [87] = "77f93b086452981199e093f1112ac36", + [88] = "6638482be29e5ad13239f385c5f8d2d4", + [90] = "155dfcd19fdd870ca7fe66b847f984f9", + [91] = "8bf6d293b0a33d416f2d8765850281a", + [92] = "4c8fec33e9fb33dcacbe1ea278b99cb3", + [93] = "16b76f5c478034b02d3a2455278766b0", + [94] = "54aada5a9d62cf663caa710a4fa9265", + [95] = "564288cd696118b6fb7a77938d8329f6", + [96] = "2b82ce64489644f3af31581fa84be71b", + [98] = "1f85ca966e00a855a7eca869b2978a57", + [99] = "495c8730e85259c23c450d921afb7be2", + }, + }, + { + .p = "d5b3e02a00ec37238b8739f3ab1bed99", + .first_non_square = 67, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "45029faf1a073c8cb536f5eda7fd1560", + [3] = "f768c37c2f57a1a9c226ff461c562b", + [4] = "2", + [5] = "65b4689cf2d75db16dcd3105953ce3c6", + [6] = "5684c6ba43a113848a8969d2fb6ca23a", + [7] = "1ff8e09fcaf051326e5c632e0cd4f823", + [8] = "4baea0cbccddbe0a21194e185b21c2d9", + [9] = "3", + [10] = "4285c184615d84354cf9a87345e9d1bb", + [11] = "e970057e6c9a32e07738b0ab78d90ba", + [12] = "1eed186f85eaf4353844dfe8c38ac56", + [13] = "67cc0965e6dd98513e4d39d0b090df81", + [14] = "1ab1e5e513662050b68d92f8f531b05d", + [15] = "281851578e9af5ae568a5b6f1c9147fd", + [16] = "4", + [17] = "1889951f21b30e2095ab76c87fcf9ba5", + [18] = "6ac011cb2d6817d6be2582ab324ad79", + [19] = "5eb623f1739f6fdc336ee0e74b3511ca", + [20] = "a4b0ef01b3d7bc0afecd7e880a2260d", + [21] = "5df17f78bd0ed66c6837513486b31cc5", + [22] = "606ae7b931bdba98f04c5fe37af4ff6b", + [23] = "148d44e0e884ce444c99b6cd437c575e", + [24] = "28aa52b579aa101a7674664db442a925", + [25] = "5", + [26] = "325e9911c86ae631a6bc1f5b699c7e31", + [27] = "2e63a4a748e06e4fd4674fdd2550281", + [28] = "3ff1c13f95e0a264dcb8c65c19a9f046", + [29] = "38fcfd8cec4b90a0de1c4c38cedc15b9", + [30] = "2f6ec8019c1949b8d7f7ce76ff9fa69b", + [31] = "e6ca869dfb345ffd59ace43b3792685", + [32] = "3e569e926730bb0f49549dc2f4d867e7", + [33] = "579bee988ae90b7ccc3e68e0c54d9e2f", + [34] = "569b25c035de96b42221456fa925c7f5", + [35] = "1f830a9c274bf0424f04e1dc96fba083", + [36] = "6", + [37] = "56a04e969e561d11e819e3f0999b2ec3", + [38] = "1399392aaee18717002eebf72a4f2714", + [39] = "184fa0b19872dbc03cc003fb7ef0a647", + [40] = "50a85d213e312eb8f193e90d1f484a23", + [41] = "32edb4d05e11465009b98a6710278c1", + [42] = "1a8d7edc19c5bfc9ffd61781bccc9691", + [43] = "22c80c569d45bb4a9f05877846f790f3", + [44] = "1d2e00afcd93465c0ee716156f1b2174", + [45] = "5b6959acd799e1f0bde0591d149abdb9", + [46] = "21456a4847a1103ea0c239e574779197", + [47] = "47bfe557af21dc9c64152430cf6cf25c", + [48] = "3dda30df0bd5e86a7089bfd187158ac", + [49] = "7", + [50] = "525aa1e87fb43f878cfba6430e467052", + [51] = "68bd2ad79d20ea7312ed693d62c8d008", + [52] = "61bcd5e333106810eecc65249fa2e97", + [53] = "81bd0dba2601145e75e1d77f1d04844", + [54] = "2dda7404c9f7036a141503854729f915", + [55] = "68e4b71490938a9f48933bde86807125", + [56] = "3563cbca26cc40a16d1b25f1ea6360ba", + [57] = "4f2d5569b091a5a79ab7e16a6ba25362", + [58] = "55c448979b854e6bb106146571f68426", + [59] = "302a3d80209e0026e0fecb63e2ce75dd", + [60] = "5030a2af1d35eb5cad14b6de39228ffa", + [61] = "2b92f6a2d393e7a4259eb1cb017f2b00", + [62] = "5a261ada71bcb91ccb1a04c49d16c6e9", + [63] = "5feaa1df60d0f3974b15298a267ee869", + [64] = "8", + [65] = "6181cb54bab42602fb979953302dbe36", + [66] = "610168cbd024ca65f82099abc21d6efd", + [68] = "31132a3e43661c412b56ed90ff9f374a", + [69] = "4835741318cf28d4227c2137b4c5613c", + [70] = "209bda2b3602ef01ac5d0be10bfad042", + [71] = "40ba51b46a55058308aec51c587fc6fe", + [72] = "d58023965ad02fad7c4b05566495af2", + [74] = "d230d76484819d75b87a4216ee67233", + [75] = "4d50bd16cecb62850cac2fc5e8daed7", + [76] = "1847984719ad576b24a9782514b1ca05", + [77] = "3c0c6536905353924fb4f8abc19e281b", + [78] = "3d0dff19927ac726586098881fb096ea", + [80] = "14961de0367af7815fd9afd101444c1a", + [81] = "9", + [82] = "1bccdc1adcd9e6f574bab3fd655d69df", + [83] = "18d4bce73268207ac84da046587f3c06", + [84] = "19d0e13886ce8a4abb18978a9db5b40f", + [85] = "4b9978cf3d8230ed3cadc49a74d5368", + [86] = "128b08847198de2b1645ac717643a123", + [87] = "63caad9c66c7cf88bcaf13f4ec88588a", + [88] = "14de10b79d70c1f1aaee7a2cb531eec3", + [90] = "e229b9cdcd3aa83a49a4099d95e7868", + [91] = "636ffea27582b5e892f407d04f9dfc9", + [92] = "291a89c1d1099c8899336d9a86f8aebc", + [93] = "26be0f04da5bbe43fd72738163315128", + [94] = "2978cccfee4c80269a3463e3bebb5dc8", + [95] = "36c57b7d41260e361126830cb6b5c75f", + [96] = "5154a56af3542034ece8cc9b6885524a", + [98] = "37aa9d75b45a3991dd72459841b3ba6e", + [99] = "2bc50107b45ce98a165aa12026a8b22e", + }, + }, + { + .p = "ebad0be3a536493da57f0fe644b4e021", + .first_non_square = 61, + .sqrt = { + [0] = "0", + [1] = "1", + [2] = "123db297cea699fb0344c1a1a1f186f3", + [3] = "bf6436b702b833d17678ccfe261262f", + [4] = "2", + [5] = "70f8ee4ff65e26fb5773b23de20012cf", + [6] = "5dee45725830feb3edd2b0e1513d9316", + [7] = "66a976a6da314fb8c0e2017aa49b4aaa", + [8] = "247b652f9d4d33f60689834343e30de6", + [9] = "3", + [10] = "3b0561b1c9001e576bf37ae3e029d215", + [11] = "2a4ac9391e3061d7182f14f088c62564", + [12] = "17ec86d6e057067a2ecf199fc4c24c5e", + [13] = "3648df5a9ba7ba504370d498d59fd9a1", + [14] = "6481962d0448c2db2aa4e42a481786f3", + [15] = "1af1cbdc9ef10ecc8382347a181e34cc", + [16] = "4", + [17] = "3f172b01dabd178cca0bc966f1fdf6f3", + [18] = "36b917c76bf3cdf109ce44e4e5d494d9", + [19] = "65ef4e2e99d2781eb82b88fe04e6f1f5", + [20] = "9bb2f43b879fb46f697ab6a80b4ba83", + [21] = "18e1abe04941114658e9e6f21f47dd08", + [22] = "5f978475f36f4e4ce77c522191208b3", + [23] = "357fa88c030974a0bc36f851f0795e64", + [24] = "2fd080fef4d44bd5c9d9ae23a239b9f5", + [25] = "5", + [26] = "408935d3281810e0ce90b4f2985fcf5e", + [27] = "23e2ca42508289b74636a66fa723728d", + [28] = "1e5a1e95f0d3a9cc23bb0cf0fb7e4acd", + [29] = "5f2c0d7368f0b6b1d2a16643a705a279", + [30] = "17549d7da5e5b8bd89b2849403020df0", + [31] = "7210f7c02ab70af02f0c665461b42f9c", + [32] = "48f6ca5f3a9a67ec0d13068687c61bcc", + [33] = "4951d8bebbe35c3f19483f7c871c8ee2", + [34] = "5a7a0a5f2d5f90c936cee2e1f1448983", + [35] = "2d5cc3d220d762d0bafed021e3b701f7", + [36] = "6", + [37] = "4eb91be8674d073b7cad4f89d9b90fd9", + [38] = "223270fd99acd27c3e6ca67c60efee95", + [39] = "2c8220ca14a994690d2737863449596e", + [40] = "75a2488013360c8ecd981a1e84613bf7", + [41] = "67b2177c12aabd92026438a46ab4cb61", + [42] = "5d34f549c9252d13b2e417b1dda2793d", + [43] = "4710ac452532ca6122daeacc47ada339", + [44] = "549592723c60c3ae305e29e1118c4ac8", + [45] = "673dbf0c3de42bb460dc06d3614b584c", + [46] = "600d79740b8a279419d8716358bdcff8", + [47] = "6bb1a8ff33f37594bad6958999635634", + [48] = "2fd90dadc0ae0cf45d9e333f898498bc", + [49] = "7", + [50] = "5b347cf7094101e71057c82829b7a2bf", + [51] = "fb13b5a54b5f9a85079f05cd8dbc210", + [52] = "6c91beb5374f74a086e1a931ab3fb342", + [53] = "5c04393e2792c7f52e5ea35e49daf887", + [54] = "2e1dc473635cb2de23f902bdaf03d921", + [55] = "59c9e5d019f3c45d7bd67877148f7b0b", + [56] = "22a9df899ca4c38750354791b485d23b", + [57] = "1cbf6261b5e6f70d8b62240aca1404c0", + [58] = "6df943332998c675130fe1ea5965661", + [59] = "3931526869d8069ffab62e14f7463ebc", + [60] = "35e397b93de21d99070468f4303c6998", + [62] = "71287677776721bbb63d7a47e3d3271f", + [63] = "484f5810e95da5ec9d26f489a91cffdd", + [64] = "8", + [65] = "24f66f45952f7b1a8a788adf0b988dd8", + [66] = "55358e335092c9ad35db80f42dbda41a", + [67] = "541c13cfadd2c6e4a3e57237c33e2b6e", + [68] = "6d7eb5dfefbc1a2411677d1860b8f23b", + [69] = "5bd017f4178d6d06fb91e3dd0daee5de", + [70] = "bce4858fe7d92a437b916d8525a45b0", + [71] = "2f318248a0091aa2094717d79179c32f", + [72] = "6d722f8ed7e79be2139c89c9cba929b2", + [74] = "5979aa2335b2e6800722423a6dce7cc8", + [75] = "3bcf511930d990317505c00f6be5beeb", + [76] = "1fce6f86719159003527fdea3ae6fc37", + [77] = "3548cedb5a44367e61e396e1b9fbccd7", + [78] = "3820cfa14dd428ff95f92b750c0af8fa", + [79] = "1b610761a0faff110434c44da3056ad", + [80] = "13765e8770f3f68ded2f56d501697506", + [81] = "9", + [82] = "4f0934854d6129caf0f3268c2b6b9ba1", + [84] = "31c357c09282228cb1d3cde43e8fba10", + [85] = "6528c8fcf5a00c45c1a742a924dc6105", + [86] = "40948b6c8dacf9307d00643172b10021", + [87] = "58f0cbf88142db86d306e56d7ca053ab", + [88] = "bf2f08ebe6de9c99cef8a4432241166", + [90] = "3a9ce6ce4a35ee3761a49f3aa43769e2", + [91] = "61e94c9be16d9115fcf3d10de819b796", + [92] = "6aff51180612e941786df0a3e0f2bcc8", + [93] = "70e2effd74ee8238a346798baf98f88", + [94] = "27630a3037b0748d160c9f0d0b6446ae", + [95] = "3ab1e5b6243a976461a7c25ebc9b6933", + [96] = "5fa101fde9a897ab93b35c47447373ea", + [98] = "6bfd29bcfea813608e9dc47ad71a2f7c", + [99] = "6cccb0384aa523b85cf1d114aa626ff5", + }, + }, +}; + +#define N_P_IS_1_MOD_8_TESTS \ + (sizeof(p_is_1_mod_8_tests) / sizeof(p_is_1_mod_8_tests[0])) + +static int +bn_mod_sqrt_p_is_1_mod_8_test(const struct p_is_1_mod_8_tests *test, + BN_CTX *ctx) +{ + BIGNUM *a, *p, *want, *got, *diff; + const char *const *sqrts = test->sqrt; + int i; + int failed = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + errx(1, "a = BN_CTX_get()"); + if ((p = BN_CTX_get(ctx)) == NULL) + errx(1, "p = BN_CTX_get()"); + if ((want = BN_CTX_get(ctx)) == NULL) + errx(1, "want = BN_CTX_get()"); + if ((got = BN_CTX_get(ctx)) == NULL) + errx(1, "got = BN_CTX_get()"); + if ((diff = BN_CTX_get(ctx)) == NULL) + errx(1, "diff = BN_CTX_get()"); + + if (!BN_hex2bn(&p, test->p)) + errx(1, "BN_hex2bn"); + + for (i = 0; i < N_SMALL_SQUARE_TESTS; i++) { + if (!BN_set_word(a, i)) + errx(1, "BN_set_word"); + + if (BN_mod_sqrt(got, a, p, ctx) == NULL) { + if (i < test->first_non_square || sqrts[i] != NULL) { + fprintf(stderr, "no sqrt(%d) (mod %s)?\n", + i, test->p); + failed |= 1; + } + continue; + } + + if (sqrts[i] == NULL) { + fprintf(stderr, "sqrt(%d) (mod %s): ", i, test->p); + BN_print_fp(stderr, got); + fprintf(stderr, "?\n"); + failed |= 1; + continue; + } + + if (!BN_hex2bn(&want, sqrts[i])) + errx(1, "BN_hex2bn"); + + if (!BN_mod_sub(diff, want, got, p, ctx)) + errx(1, "BN_mod_sub() failed\n"); + + if (!BN_is_zero(diff)) { + fprintf(stderr, "a: %d\n", i); + fprintf(stderr, "p: %s\n", test->p); + fprintf(stderr, "want: %s\n", sqrts[i]); + fprintf(stderr, "got: "); + BN_print_fp(stderr, got); + fprintf(stderr, "\n\n"); + + failed |= 1; + continue; + } + } + + BN_CTX_end(ctx); + + return failed; +} + +static int +bn_mod_sqrt_p_is_1_mod_8(void) +{ + BN_CTX *ctx; + size_t i; + int failed = 0; + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + for (i = 0; i < N_P_IS_1_MOD_8_TESTS; i++) { + const struct p_is_1_mod_8_tests *test = &p_is_1_mod_8_tests[i]; + + failed |= bn_mod_sqrt_p_is_1_mod_8_test(test, ctx); + } + + BN_CTX_free(ctx); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= bn_mod_sqrt_test(); + failed |= bn_mod_sqrt_p_is_1_mod_8(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_mont.c b/Libraries/libressl/tests/bn_mont.c new file mode 100644 index 000000000..4bcc79d18 --- /dev/null +++ b/Libraries/libressl/tests/bn_mont.c @@ -0,0 +1,83 @@ +/* $OpenBSD: bn_mont.c,v 1.2 2022/12/06 18:23:29 tb Exp $ */ + +/* + * Copyright (c) 2014 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +/* + * Test for proper bn_mul_mont behaviour when operands are of vastly different + * sizes. + */ + +int +main(int argc, char *argv[]) +{ + DH *dh = NULL; + BIGNUM *priv_key = NULL; + unsigned char *key = NULL; + unsigned char r[32 + 16 * 8]; + size_t privsz; + + arc4random_buf(r, sizeof(r)); + + for (privsz = 32; privsz <= sizeof(r); privsz += 8) { + dh = DH_new(); + if (dh == NULL) + goto err; + if (DH_generate_parameters_ex(dh, 32, DH_GENERATOR_2, + NULL) == 0) + goto err; + + /* force private key to be much larger than public one */ + priv_key = BN_bin2bn(r, privsz, NULL); + if (priv_key == NULL) + goto err; + + if (!DH_set0_key(dh, NULL, priv_key)) + goto err; + priv_key = NULL; + + if (DH_generate_key(dh) == 0) + goto err; + key = malloc(DH_size(dh)); + if (key == NULL) + err(1, "malloc"); + if (DH_compute_key(key, DH_get0_pub_key(dh), dh) == -1) + goto err; + + free(key); + key = NULL; + DH_free(dh); + dh = NULL; + } + + return 0; + + err: + ERR_print_errors_fp(stderr); + free(key); + BN_free(priv_key); + DH_free(dh); + return 1; +} diff --git a/Libraries/libressl/tests/bn_primes.c b/Libraries/libressl/tests/bn_primes.c new file mode 100644 index 000000000..8180b0d78 --- /dev/null +++ b/Libraries/libressl/tests/bn_primes.c @@ -0,0 +1,148 @@ +/* $OpenBSD: bn_primes.c,v 1.3 2023/04/25 15:30:03 tb Exp $ */ +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include "bn_prime.h" + +static int +test_bn_is_prime_fasttest(int do_trial_division) +{ + BIGNUM *n = NULL; + char *descr = NULL; + uint16_t i, j, max; + int is_prime, ret; + int failed = 1; + + if (asprintf(&descr, "with%s trial divisions", + do_trial_division ? "" : "out") == -1) { + descr = NULL; + fprintf(stderr, "asprintf failed\n"); + goto err; + } + + if ((n = BN_new()) == NULL) { + fprintf(stderr, "BN_new failed\n"); + goto err; + } + + max = primes[NUMPRIMES - 1] + 1; + + failed = 0; + for (i = 1, j = 0; i < max && j < NUMPRIMES; i++) { + if (!BN_set_word(n, i)) { + fprintf(stderr, "BN_set_word(%d) failed", i); + failed = 1; + goto err; + } + + is_prime = i == primes[j]; + if (is_prime) + j++; + + ret = BN_is_prime_fasttest_ex(n, BN_prime_checks, NULL, + do_trial_division, NULL); + if (ret != is_prime) { + fprintf(stderr, + "BN_is_prime_fasttest_ex(%d) %s: want %d, got %d\n", + i, descr, is_prime, ret); + failed = 1; + } + } + + if (i < max || j < NUMPRIMES) { + fprintf(stderr, "%s: %d < %d or %d < %d\n", descr, i, max, j, + NUMPRIMES); + failed = 1; + } + + err: + BN_free(n); + free(descr); + return failed; +} + +#define BN_PRIME_FN_INIT(a) { .fn = a, .name = #a } + +static const struct test_dynamic_api { + BIGNUM *(*fn)(BIGNUM *); + const char *name; +} dynamic_api_data[] = { + BN_PRIME_FN_INIT(BN_get_rfc2409_prime_1024), + BN_PRIME_FN_INIT(BN_get_rfc2409_prime_768), + BN_PRIME_FN_INIT(BN_get_rfc3526_prime_1536), + BN_PRIME_FN_INIT(BN_get_rfc3526_prime_2048), + BN_PRIME_FN_INIT(BN_get_rfc3526_prime_3072), + BN_PRIME_FN_INIT(BN_get_rfc3526_prime_4096), + BN_PRIME_FN_INIT(BN_get_rfc3526_prime_6144), + BN_PRIME_FN_INIT(BN_get_rfc3526_prime_8192), +}; + +#define N_DYNAMIC_TESTS (sizeof(dynamic_api_data) / sizeof(dynamic_api_data[0])) + +static int +test_prime_dynamic_api(const struct test_dynamic_api *tc) +{ + BIGNUM *prime; + int ret; + int failed = 1; + + if ((prime = tc->fn(NULL)) == NULL) { + fprintf(stderr, "%s failed\n", tc->name); + goto err; + } + + if ((ret = BN_is_prime_fasttest_ex(prime, 1, NULL, 1, NULL)) != 1) { + fprintf(stderr, "%s: %s want 1, got %d\n", tc->name, + "BN_is_prime_fasttest_ex", ret); + goto err; + } + + failed = 0; + + err: + BN_free(prime); + return failed; +} + +static int +test_prime_constants(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_DYNAMIC_TESTS; i++) + failed |= test_prime_dynamic_api(&dynamic_api_data[i]); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= test_bn_is_prime_fasttest(0); + failed |= test_bn_is_prime_fasttest(1); + failed |= test_prime_constants(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_print.c b/Libraries/libressl/tests/bn_print.c new file mode 100644 index 000000000..a3118869f --- /dev/null +++ b/Libraries/libressl/tests/bn_print.c @@ -0,0 +1,305 @@ +/* $OpenBSD: bn_print.c,v 1.5 2023/07/27 06:41:39 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +#include "bn_local.h" + +#define BATIHDIDIDI "mana mana" +#define BUF_MEM_LEN 1024 + +static const char *pk = "040d305e1b159d03d0a17935b73a3c927aca151ccd62f39c" + "265c073de554faa3d6cc12eaf4145fe88e19ab2f2e48e6ac" + "184378acd037c3bdb2cd2ce647e21ae663b83d2e2f78c44f" + "dbf40fa4684c55726b951d4e18429578cc373c91e29b652b" + "29"; + +const struct print_test { + const char *desc; + const char *want; +} bn_print_tests[] = { + { + .desc = "zero", + .want = " mana mana 0\n", + }, + { + .desc = "minus one", + .want = " mana mana 1 (0x1)\n", + }, + { + .desc = "minus one", + .want = " mana mana -1 (-0x1)\n", + }, +#ifdef _LP64 + { + .desc = "largest word", + .want = " mana mana 18446744073709551615 " + "(0xffffffffffffffff)\n", + }, + { + .desc = "smallest word", + .want = " mana mana -18446744073709551615 " + "(-0xffffffffffffffff)\n", + }, + { + .desc = "largest negative non-word", + .want = " mana mana (Negative)\n" + " 01:00:00:00:00:00:00:00:00\n", + }, + { + .desc = "smallest positive non-word", + .want = " mana mana\n" + " 01:00:00:00:00:00:00:00:00\n", + }, +#else + { + .desc = "largest word", + .want = " mana mana 4294967295 (0xffffffff)\n", + }, + { + .desc = "smallest word", + .want = " mana mana -4294967295 (-0xffffffff)\n", + }, + { + .desc = "largest negative non-word", + .want = " mana mana (Negative)\n" + " 01:00:00:00:00\n", + }, + { + .desc = "smallest positive non-word", + .want = " mana mana\n" + " 01:00:00:00:00\n", + }, +#endif + { + .desc = "some pubkey", + .want = " mana mana\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n" + " 3c:91:e2:9b:65:2b:29\n", + }, + { + .desc = "negated pubkey", + .want = " mana mana (Negative)\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n" + " 3c:91:e2:9b:65:2b:29\n", + }, + { + .desc = "shifted negated pubkey", + .want = " mana mana (Negative)\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n", + }, + { + .desc = "shifted pubkey", + .want = " mana mana\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n", + }, + { + .desc = "high bit of first nibble is set", + .want = " mana mana\n" + " 00:80:00:00:00:00:00:00:00:00\n", + }, + { + /* XXX - this is incorrect and should be fixed. */ + .desc = "high bit of first nibble is set for negative number", + .want = " mana mana (Negative)\n" + " 00:80:00:00:00:00:00:00:00:00\n", + }, +}; + +#define N_TESTCASES (sizeof(bn_print_tests) / sizeof(bn_print_tests[0])) + +static int +bn_print_testcase(const BIGNUM *bn, const struct print_test *test) +{ + BIO *bio; + char *got; + size_t want_len; + long got_len; + int failed = 1; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new"); + + if (!bn_printf(bio, bn, 4, "%s", BATIHDIDIDI)) + errx(1, "bn_printf"); + + if ((got_len = BIO_get_mem_data(bio, &got)) < 0) + errx(1, "BIO_get_mem_data"); + + if ((want_len = strlen(test->want)) != (size_t)got_len) { + fprintf(stderr, "%s: want: %zu, got %ld\n", + test->desc, want_len, got_len); + goto err; + } + + if (strncmp(got, test->want, want_len) != 0) { + fprintf(stderr, "%s: strings differ\n", test->desc); + fprintf(stderr, "want: \"%s\"\ngot : \"%*s\"\n", + test->want, (int)got_len, got); + goto err; + } + + failed = 0; + err: + BIO_free(bio); + + return failed; +} + +int +main(void) +{ + const struct print_test *test; + size_t testcase = 0; + BIGNUM *bn; + int failed = 0; + + /* zero */ + if ((bn = BN_new()) == NULL) + errx(1, "BN_new"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* one */ + if (!BN_set_word(bn, 1)) + errx(1, "BIO_set_word"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* minus one */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* largest word */ + if (!BN_set_word(bn, ~0)) + errx(1, "BN_set_word"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* smallest word */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* largest negative non-word */ + if (!BN_sub_word(bn, 1)) + errx(1, "ASN1_bn_print"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* smallest positive non-word */ + BN_set_negative(bn, 0); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* some pubkey */ + if (BN_hex2bn(&bn, pk) == 0) + errx(1, "BN_hex2bn"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* negated pubkey */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* shifted negated pubkey */ + if (!BN_rshift(bn, bn, 7 * 8)) + errx(1, "BN_rshift"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* shifted pubkey */ + BN_set_negative(bn, 0); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* high bit of first nibble is set. */ + BN_zero(bn); + if (!BN_set_bit(bn, 71)) + errx(1, "BN_set_bit"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* high bit of first nibble is set for negative number. */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + if (testcase != N_TESTCASES) { + warnx("Not all tests run"); + failed |= 1; + } + + BN_free(bn); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_shift.c b/Libraries/libressl/tests/bn_shift.c new file mode 100644 index 000000000..95a61975b --- /dev/null +++ b/Libraries/libressl/tests/bn_shift.c @@ -0,0 +1,659 @@ +/* $OpenBSD: bn_shift.c,v 1.9 2023/03/11 14:02:26 jsing Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +static const char *bn_shift_want_hex = \ + "02AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8"; + +static int +check_shift_result(BIGNUM *bn1) +{ + BIGNUM *bn2 = NULL; + char *s = NULL; + int ret = 0; + + if (!BN_hex2bn(&bn2, bn_shift_want_hex)) { + fprintf(stderr, "FAIL: BN_hex2bn() failed\n"); + goto failure; + } + if (BN_cmp(bn1, bn2) != 0) { + fprintf(stderr, "FAIL: shifted result differs\n"); + if ((s = BN_bn2hex(bn1)) == NULL) { + fprintf(stderr, "FAIL: BN_bn2hex()\n"); + goto failure; + } + fprintf(stderr, "Got: %s\n", s); + free(s); + if ((s = BN_bn2hex(bn2)) == NULL) { + fprintf(stderr, "FAIL: BN_bn2hex()\n"); + goto failure; + } + fprintf(stderr, "Want: %s\n", s); + } + + ret = 1; + + failure: + BN_free(bn2); + free(s); + + return ret; +} + +static int +test_bn_shift1(void) +{ + BIGNUM *bn1 = NULL, *bn2 = NULL; + int i; + int failed = 1; + + if ((bn1 = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + if ((bn2 = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN\n"); + goto failure; + } + + for (i = 1; i <= 256; i++) { + if (!BN_set_bit(bn1, 1)) { + fprintf(stderr, "FAIL: failed to set bit\n"); + goto failure; + } + if (!BN_lshift1(bn1, bn1)) { + fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); + goto failure; + } + if (!BN_lshift1(bn1, bn1)) { + fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); + goto failure; + } + if (!BN_rshift1(bn1, bn1)) { + fprintf(stderr, "FAIL: failed to BN_rshift1()\n"); + goto failure; + } + if (!BN_lshift1(bn1, bn1)) { + fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); + goto failure; + } + } + + if (!check_shift_result(bn1)) + goto failure; + + /* + * Shift result into a different BN. + */ + if (!BN_lshift1(bn1, bn1)) { + fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); + goto failure; + } + if (!BN_rshift1(bn2, bn1)) { + fprintf(stderr, "FAIL: failed to BN_rshift1()\n"); + goto failure; + } + + if (!check_shift_result(bn2)) + goto failure; + + if (!BN_rshift1(bn2, bn2)) { + fprintf(stderr, "FAIL: failed to BN_rshift1()\n"); + goto failure; + } + if (!BN_lshift1(bn1, bn2)) { + fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); + goto failure; + } + + if (!check_shift_result(bn1)) + goto failure; + + failed = 0; + + failure: + BN_free(bn1); + BN_free(bn2); + + return failed; +} + +static int +test_bn_shift(void) +{ + BIGNUM *bn1 = NULL, *bn2 = NULL; + int i; + int failed = 1; + + if ((bn1 = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN 1\n"); + goto failure; + } + if ((bn2 = BN_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create BN 2\n"); + goto failure; + } + + for (i = 1; i <= 256; i++) { + if (!BN_set_bit(bn1, 1)) { + fprintf(stderr, "FAIL: failed to set bit\n"); + goto failure; + } + if (!BN_lshift(bn1, bn1, i + 1)) { + fprintf(stderr, "FAIL: failed to BN_lshift()\n"); + goto failure; + } + if (!BN_rshift(bn1, bn1, i - 1)) { + fprintf(stderr, "FAIL: failed to BN_rshift()\n"); + goto failure; + } + } + + if (!check_shift_result(bn1)) + goto failure; + + for (i = 0; i <= 256; i++) { + if (!BN_lshift(bn1, bn1, i)) { + fprintf(stderr, "FAIL: failed to BN_lshift()\n"); + goto failure; + } + if (i > 1) { + if (!BN_set_bit(bn1, 1)) { + fprintf(stderr, "FAIL: failed to set bit\n"); + goto failure; + } + } + } + + if (BN_num_bytes(bn1) != 4177) { + fprintf(stderr, "FAIL: BN has %d bytes, want 4177\n", + BN_num_bytes(bn1)); + goto failure; + } + + for (i = 0; i <= 256; i++) { + if (!BN_rshift(bn1, bn1, i)) { + fprintf(stderr, "FAIL: failed to BN_rshift()\n"); + goto failure; + } + } + + if (!check_shift_result(bn1)) + goto failure; + + /* + * Shift result into a different BN. + */ + if (!BN_lshift(bn1, bn1, BN_BITS2 + 1)) { + fprintf(stderr, "FAIL: failed to BN_lshift()\n"); + goto failure; + } + if (!BN_rshift(bn2, bn1, BN_BITS2 + 1)) { + fprintf(stderr, "FAIL: failed to BN_rshift()\n"); + goto failure; + } + + if (!check_shift_result(bn2)) + goto failure; + + if (!BN_rshift(bn2, bn2, 3)) { + fprintf(stderr, "FAIL: failed to BN_rshift()\n"); + goto failure; + } + if (!BN_lshift(bn1, bn2, 3)) { + fprintf(stderr, "FAIL: failed to BN_lshift()\n"); + goto failure; + } + + if (!check_shift_result(bn1)) + goto failure; + + /* + * Shift of zero (equivalent to a copy). + */ + BN_zero(bn2); + if (!BN_lshift(bn2, bn1, 0)) { + fprintf(stderr, "FAIL: failed to BN_lshift()\n"); + goto failure; + } + + if (!check_shift_result(bn2)) + goto failure; + + if (!BN_lshift(bn2, bn2, 0)) { + fprintf(stderr, "FAIL: failed to BN_lshift()\n"); + goto failure; + } + + if (!check_shift_result(bn2)) + goto failure; + + BN_zero(bn2); + if (!BN_rshift(bn2, bn1, 0)) { + fprintf(stderr, "FAIL: failed to BN_rshift()\n"); + goto failure; + } + + if (!check_shift_result(bn2)) + goto failure; + + if (!BN_rshift(bn2, bn2, 0)) { + fprintf(stderr, "FAIL: failed to BN_rshift()\n"); + goto failure; + } + + if (!check_shift_result(bn2)) + goto failure; + + failed = 0; + + failure: + BN_free(bn1); + BN_free(bn2); + + return failed; +} + +static int +test_bn_rshift_to_zero(void) +{ + BIGNUM *bn1 = NULL, *bn2 = NULL; + int failed = 1; + + if (!BN_hex2bn(&bn1, "ffff")) { + fprintf(stderr, "FAIL: BN_hex2bn() failed\n"); + goto failure; + } + if (!BN_lshift(bn1, bn1, BN_BITS2)) { + fprintf(stderr, "FAIL: BN_lshift() failed\n"); + goto failure; + } + + if ((bn2 = BN_new()) == NULL) { + fprintf(stderr, "FAIL: BN_new() failed\n"); + goto failure; + } + + /* Shift all words. */ + if (!BN_rshift(bn2, bn1, BN_BITS2 * 2)) { + fprintf(stderr, "FAIL: BN_rshift() failed\n"); + goto failure; + } + if (BN_is_zero(bn1)) { + fprintf(stderr, "FAIL: BN is zero\n"); + goto failure; + } + if (!BN_is_zero(bn2)) { + fprintf(stderr, "FAIL: BN is not zero\n"); + goto failure; + } + + /* Shift to zero, with partial shift for top most word. */ + if (!BN_rshift(bn2, bn1, BN_BITS2 + 16)) { + fprintf(stderr, "FAIL: BN_rshift() failed\n"); + goto failure; + } + if (BN_is_zero(bn1)) { + fprintf(stderr, "FAIL: BN is zero\n"); + goto failure; + } + if (!BN_is_zero(bn2)) { + fprintf(stderr, "FAIL: BN is not zero\n"); + goto failure; + } + + /* Shift to zero of negative value. */ + if (!BN_one(bn1)) { + fprintf(stderr, "FAIL: BN_one() failed\n"); + goto failure; + } + BN_set_negative(bn1, 1); + if (!BN_rshift(bn1, bn1, 1)) { + fprintf(stderr, "FAIL: BN_rshift() failed\n"); + goto failure; + } + if (!BN_is_zero(bn1)) { + fprintf(stderr, "FAIL: BN is not zero\n"); + goto failure; + } + if (BN_is_negative(bn1)) { + fprintf(stderr, "FAIL: BN is negative zero\n"); + goto failure; + } + + failed = 0; + + failure: + BN_free(bn1); + BN_free(bn2); + + return failed; +} + +#if 0 + +static void +benchmark_bn_lshift1(BIGNUM *bn) +{ + int i; + + if (!BN_set_bit(bn, 8192)) + errx(1, "BN_set_bit"); + + if (!BN_one(bn)) + errx(1, "BN_one"); + + for (i = 0; i < 8192; i++) { + if (!BN_lshift1(bn, bn)) + errx(1, "BN_lshift1"); + } +} + +static void +benchmark_bn_lshift(BIGNUM *bn, int n) +{ + int i; + + if (!BN_set_bit(bn, 8192 * n)) + errx(1, "BN_set_bit"); + + if (!BN_one(bn)) + errx(1, "BN_one"); + + for (i = 0; i < 8192; i++) { + if (!BN_lshift(bn, bn, n)) + errx(1, "BN_lshift"); + } +} + +static void +benchmark_bn_lshift_1(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 1); +} + +static void +benchmark_bn_lshift_16(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 16); +} + +static void +benchmark_bn_lshift_32(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 32); +} + +static void +benchmark_bn_lshift_64(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 64); +} + +static void +benchmark_bn_lshift_65(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 65); +} + +static void +benchmark_bn_lshift_80(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 80); +} + +static void +benchmark_bn_lshift_127(BIGNUM *bn) +{ + benchmark_bn_lshift(bn, 127); +} + +static void +benchmark_bn_rshift1(BIGNUM *bn) +{ + int i; + + if (!BN_one(bn)) + errx(1, "BN_one"); + + if (!BN_set_bit(bn, 8192)) + errx(1, "BN_set_bit"); + + for (i = 0; i < 8192; i++) { + if (!BN_rshift1(bn, bn)) + errx(1, "BN_rshift1"); + } +} + +static void +benchmark_bn_rshift(BIGNUM *bn, int n) +{ + int i; + + if (!BN_one(bn)) + errx(1, "BN_one"); + + if (!BN_set_bit(bn, 8192 * n)) + errx(1, "BN_set_bit"); + + for (i = 0; i < 8192; i++) { + if (!BN_rshift(bn, bn, n)) + errx(1, "BN_rshift"); + } +} + +static void +benchmark_bn_rshift_1(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 1); +} + +static void +benchmark_bn_rshift_16(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 16); +} + +static void +benchmark_bn_rshift_32(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 32); +} + +static void +benchmark_bn_rshift_64(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 64); +} + +static void +benchmark_bn_rshift_65(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 65); +} + +static void +benchmark_bn_rshift_80(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 80); +} + +static void +benchmark_bn_rshift_127(BIGNUM *bn) +{ + benchmark_bn_rshift(bn, 127); +} + +struct benchmark { + const char *desc; + void (*func)(BIGNUM *); +}; + +static const struct benchmark benchmarks[] = { + { + .desc = "BN_lshift1()", + .func = benchmark_bn_lshift1, + }, + { + .desc = "BN_lshift(_, _, 1)", + .func = benchmark_bn_lshift_1, + }, + { + .desc = "BN_lshift(_, _, 16)", + .func = benchmark_bn_lshift_16, + }, + { + .desc = "BN_lshift(_, _, 32)", + .func = benchmark_bn_lshift_32, + }, + { + .desc = "BN_lshift(_, _, 64)", + .func = benchmark_bn_lshift_64, + }, + { + .desc = "BN_lshift(_, _, 65)", + .func = benchmark_bn_lshift_65, + }, + { + .desc = "BN_lshift(_, _, 80)", + .func = benchmark_bn_lshift_80, + }, + { + .desc = "BN_lshift(_, _, 127)", + .func = benchmark_bn_lshift_127, + }, + { + .desc = "BN_rshift1()", + .func = benchmark_bn_rshift1, + }, + { + .desc = "BN_rshift(_, _, 1)", + .func = benchmark_bn_rshift_1, + }, + { + .desc = "BN_rshift(_, _, 16)", + .func = benchmark_bn_rshift_16, + }, + { + .desc = "BN_rshift(_, _, 32)", + .func = benchmark_bn_rshift_32, + }, + { + .desc = "BN_rshift(_, _, 64)", + .func = benchmark_bn_rshift_64, + }, + { + .desc = "BN_rshift(_, _, 65)", + .func = benchmark_bn_rshift_65, + }, + { + .desc = "BN_rshift(_, _, 80)", + .func = benchmark_bn_rshift_80, + }, + { + .desc = "BN_rshift(_, _, 127)", + .func = benchmark_bn_rshift_127, + }, +}; + +#define N_BENCHMARKS (sizeof(benchmarks) / sizeof(benchmarks[0])) + +static volatile sig_atomic_t benchmark_stop; + +static void +benchmark_sig_alarm(int sig) +{ + benchmark_stop = 1; +} + +static void +benchmark_run(const struct benchmark *bm, int seconds) +{ + struct timespec start, end, duration; + BIGNUM *bn; + int i; + + signal(SIGALRM, benchmark_sig_alarm); + + if ((bn = BN_new()) == NULL) + errx(1, "BN_new"); + + benchmark_stop = 0; + i = 0; + alarm(seconds); + + clock_gettime(CLOCK_MONOTONIC, &start); + + fprintf(stderr, "Benchmarking %s for %ds: ", bm->desc, seconds); + while (!benchmark_stop) { + bm->func(bn); + i++; + } + clock_gettime(CLOCK_MONOTONIC, &end); + timespecsub(&end, &start, &duration); + fprintf(stderr, "%d iterations in %f seconds\n", i, + duration.tv_sec + duration.tv_nsec / 1000000000.0); + + BN_free(bn); +} + +#endif + +static void +benchmark_bn_shift(void) +{ +#if 0 + const struct benchmark *bm; + size_t i; + + for (i = 0; i < N_BENCHMARKS; i++) { + bm = &benchmarks[i]; + benchmark_run(bm, 5); + } +#else + return; +#endif +} + +int +main(int argc, char **argv) +{ + int benchmark = 0, failed = 0; + + if (argc == 2 && strcmp(argv[1], "--benchmark") == 0) + benchmark = 1; + + failed |= test_bn_shift1(); + failed |= test_bn_shift(); + failed |= test_bn_rshift_to_zero(); + + if (benchmark && !failed) + benchmark_bn_shift(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_test.c b/Libraries/libressl/tests/bn_test.c new file mode 100644 index 000000000..f73799b3a --- /dev/null +++ b/Libraries/libressl/tests/bn_test.c @@ -0,0 +1,1916 @@ +/* $OpenBSD: bn_test.c,v 1.19 2023/04/25 17:17:21 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include +#include + +#include +#include +#include + +#include "bn_local.h" + +const int num0 = 100; /* number of tests */ +const int num1 = 50; /* additional tests for some functions */ +const int num2 = 5; /* number of tests for slow functions */ + +int test_add(BIO *bp, BN_CTX *ctx); +int test_sub(BIO *bp, BN_CTX *ctx); +int test_lshift1(BIO *bp, BN_CTX *ctx); +int test_lshift(BIO *bp, BN_CTX *ctx, int use_lst); +int test_rshift1(BIO *bp, BN_CTX *ctx); +int test_rshift(BIO *bp, BN_CTX *ctx); +int test_div(BIO *bp, BN_CTX *ctx); +int test_div_word(BIO *bp, BN_CTX *ctx); +int test_div_recp(BIO *bp, BN_CTX *ctx); +int test_mul(BIO *bp, BN_CTX *ctx); +int test_sqr(BIO *bp, BN_CTX *ctx); +int test_mont(BIO *bp, BN_CTX *ctx); +int test_mod(BIO *bp, BN_CTX *ctx); +int test_mod_mul(BIO *bp, BN_CTX *ctx); +int test_mod_exp(BIO *bp, BN_CTX *ctx); +int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx); +int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx); +int test_mod_exp_sizes(BIO *bp, BN_CTX *ctx); +int test_exp(BIO *bp, BN_CTX *ctx); +int test_kron(BIO *bp, BN_CTX *ctx); +int test_sqrt(BIO *bp, BN_CTX *ctx); +int rand_neg(void); +static int results = 0; + +#define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__, \ + __LINE__) + +#define CHECK_GOTO(a) do { \ + if (!(a)) { \ + PRINT_ERROR; \ + goto err; \ + } \ +} while (0) + +static void +message(BIO *out, char *m) +{ + ERR_print_errors_fp(stderr); + ERR_clear_error(); + + fprintf(stderr, "test %s\n", m); + BIO_puts(out, "print \"test "); + BIO_puts(out, m); + BIO_puts(out, "\\n\"\n"); +} + +int +main(int argc, char *argv[]) +{ + BN_CTX *ctx; + BIO *out; + char *outfile = NULL; + + results = 0; + + argc--; + argv++; + while (argc >= 1) { + if (strcmp(*argv, "-results") == 0) + results = 1; + else if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + break; + outfile= *(++argv); + } + argc--; + argv++; + } + + if ((ctx = BN_CTX_new()) == NULL) + exit(1); + + if ((out = BIO_new(BIO_s_file())) == NULL) + exit(1); + if (outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (!BIO_write_filename(out, outfile)) { + perror(outfile); + exit(1); + } + } + + if (!results) + BIO_puts(out, "obase=16\nibase=16\n"); + + message(out, "BN_add"); + if (!test_add(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_sub"); + if (!test_sub(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_lshift1"); + if (!test_lshift1(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_lshift (fixed)"); + if (!test_lshift(out, ctx, 0)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_lshift"); + if (!test_lshift(out, ctx, 1)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_rshift1"); + if (!test_rshift1(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_rshift"); + if (!test_rshift(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_sqr"); + if (!test_sqr(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mul"); + if (!test_mul(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_div"); + if (!test_div(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_div_word"); + if (!test_div_word(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_div_recp"); + if (!test_div_recp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod"); + if (!test_mod(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_mul"); + if (!test_mod_mul(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mont"); + if (!test_mont(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_exp"); + if (!test_mod_exp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_exp_mont_consttime"); + if (!test_mod_exp_mont_consttime(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_exp_mont5"); + if (!test_mod_exp_mont5(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_exp"); + if (!test_exp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_kronecker"); + if (!test_kron(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_sqrt"); + if (!test_sqrt(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "Modexp with different sizes"); + if (!test_mod_exp_sizes(out, ctx)) + goto err; + (void)BIO_flush(out); + + BN_CTX_free(ctx); + BIO_free(out); + + exit(0); + err: + BIO_puts(out, "1\n"); /* make sure the Perl script fed by bc notices + * the failure, see test_bn in test/Makefile.ssl*/ + + (void)BIO_flush(out); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); + exit(1); +} + +int +test_add(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0)); + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_bntest_rand(b, 450 + i, 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + CHECK_GOTO(BN_add(c, a, b)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " + "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + BN_set_negative(a, !BN_is_negative(a)); + BN_set_negative(b, !BN_is_negative(b)); + CHECK_GOTO(BN_add(c, c, b)); + CHECK_GOTO(BN_add(c, c, a)); + if (!BN_is_zero(c)) { + fprintf(stderr, "Add test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_sub(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + + for (i = 0; i < num0 + num1; i++) { + if (i < num1) { + CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0)); + CHECK_GOTO(bn_copy(b, a)); + if (BN_set_bit(a, i) == 0) + goto err; + CHECK_GOTO(BN_add_word(b, i)); + } else { + CHECK_GOTO(BN_bntest_rand(b, 400 + i - num1, 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + } + CHECK_GOTO(BN_sub(c, a, b)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " - "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_add(c, c, b)); + CHECK_GOTO(BN_sub(c, c, a)); + if (!BN_is_zero(c)) { + fprintf(stderr, "Subtract test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_div(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_one(a)); + BN_zero(b); + + if (BN_div(d, c, a, b, ctx)) { + fprintf(stderr, "Division by zero succeeded!\n"); + goto err; + } + ERR_clear_error(); + + for (i = 0; i < num0 + num1; i++) { + if (i < num1) { + CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0)); + CHECK_GOTO(bn_copy(b, a)); + CHECK_GOTO(BN_lshift(a, a, i)); + CHECK_GOTO(BN_add_word(a, i)); + } else + CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + CHECK_GOTO(BN_div(d, c, a, b, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " / "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul(e, d, b, ctx)); + CHECK_GOTO(BN_add(d, e, c)); + CHECK_GOTO(BN_sub(d, d, a)); + if (!BN_is_zero(d)) { + fprintf(stderr, "Division test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +static void +print_word(BIO *bp, BN_ULONG w) +{ +#ifdef SIXTY_FOUR_BIT + if (sizeof(w) > sizeof(unsigned long)) { + unsigned long h = (unsigned long)(w >> 32), l = (unsigned long)(w); + + if (h) + BIO_printf(bp, "%lX%08lX", h, l); + else + BIO_printf(bp, "%lX", l); + return; + } +#endif + BIO_printf(bp, BN_HEX_FMT1, w); +} + +int +test_div_word(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b; + BN_ULONG r, rmod, s = 0; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + + for (i = 0; i < num0; i++) { + do { + if (!BN_bntest_rand(a, 512, -1, 0) || + !BN_bntest_rand(b, BN_BITS2, -1, 0)) + goto err; + s = BN_get_word(b); + } while (!s); + + if (!bn_copy(b, a)) + goto err; + + rmod = BN_mod_word(b, s); + r = BN_div_word(b, s); + + if (r == (BN_ULONG)-1 || rmod == (BN_ULONG)-1) + goto err; + + if (rmod != r) { + fprintf(stderr, "Mod (word) test failed!\n"); + goto err; + } + + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " / "); + print_word(bp, s); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, "\n"); + + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " % "); + print_word(bp, s); + BIO_puts(bp, " - "); + } + print_word(bp, r); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul_word(b, s)); + CHECK_GOTO(BN_add_word(b, r)); + CHECK_GOTO(BN_sub(b, a, b)); + if (!BN_is_zero(b)) { + fprintf(stderr, "Division (word) test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_div_recp(BIO *bp, BN_CTX *ctx) +{ + BN_RECP_CTX *recp = NULL; + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((recp = BN_RECP_CTX_new()) == NULL) + goto err; + + for (i = 0; i < num0 + num1; i++) { + if (i < num1) { + CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0)); + CHECK_GOTO(bn_copy(b, a)); + CHECK_GOTO(BN_lshift(a, a, i)); + CHECK_GOTO(BN_add_word(a, i)); + } else + CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + CHECK_GOTO(BN_RECP_CTX_set(recp, b, ctx)); + CHECK_GOTO(BN_div_recp(d, c, a, recp, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " / "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul(e, d, b, ctx)); + CHECK_GOTO(BN_add(d, e, c)); + CHECK_GOTO(BN_sub(d, d, a)); + if (!BN_is_zero(d)) { + fprintf(stderr, "Reciprocal division test failed!\n"); + fprintf(stderr, "a="); + CHECK_GOTO(BN_print_fp(stderr, a)); + fprintf(stderr, "\nb="); + CHECK_GOTO(BN_print_fp(stderr, b)); + fprintf(stderr, "\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(recp); + + return ret; +} + +int +test_mul(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + for (i = 0; i < num0 + num1; i++) { + if (i <= num1) { + CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0)); + } else + CHECK_GOTO(BN_bntest_rand(b, i - num1, 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + CHECK_GOTO(BN_mul(c, a, b, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_div(d, e, c, a, ctx)); + CHECK_GOTO(BN_sub(d, d, b)); + if (!BN_is_zero(d) || !BN_is_zero(e)) { + fprintf(stderr, "Multiplication test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_sqr(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_bntest_rand(a, 40 + i * 10, 0, 0)); + BN_set_negative(a, rand_neg()); + CHECK_GOTO(BN_sqr(c, a, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_div(d, e, c, a, ctx)); + CHECK_GOTO(BN_sub(d, d, a)); + if (!BN_is_zero(d) || !BN_is_zero(e)) { + fprintf(stderr, "Square test failed!\n"); + goto err; + } + } + + /* Regression test for a BN_sqr overflow bug. */ + if (!BN_hex2bn(&a, "80000000000000008000000000000001" + "FFFFFFFFFFFFFFFE0000000000000000")) { + fprintf(stderr, "BN_hex2bn failed\n"); + goto err; + } + CHECK_GOTO(BN_sqr(c, a, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul(d, a, a, ctx)); + if (BN_cmp(c, d)) { + fprintf(stderr, + "Square test failed: BN_sqr and BN_mul produce " + "different results!\n"); + goto err; + } + + /* Regression test for a BN_sqr overflow bug. */ + if (!BN_hex2bn(&a, "80000000000000000000000080000001" + "FFFFFFFE000000000000000000000000")) { + fprintf(stderr, "BN_hex2bn failed\n"); + goto err; + } + CHECK_GOTO(BN_sqr(c, a, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul(d, a, a, ctx)); + if (BN_cmp(c, d)) { + fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce " + "different results!\n"); + goto err; + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_mont(BIO *bp, BN_CTX *ctx) +{ + BN_MONT_CTX *mont = NULL; + BIGNUM *a, *b, *c, *d, *A, *B, *n; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((A = BN_CTX_get(ctx)) == NULL) + goto err; + if ((B = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + + BN_zero(n); + if (BN_MONT_CTX_set(mont, n, ctx)) { + fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n"); + goto err; + } + ERR_clear_error(); + + CHECK_GOTO(BN_set_word(n, 16)); + if (BN_MONT_CTX_set(mont, n, ctx)) { + fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n"); + goto err; + } + ERR_clear_error(); + + CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0)); + for (i = 0; i < num2; i++) { + int bits = (200 * (i + 1)) / num2; + + if (bits == 0) + continue; + CHECK_GOTO(BN_bntest_rand(n, bits, 0, 1)); + CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx)); + + CHECK_GOTO(BN_nnmod(a, a, n, ctx)); + CHECK_GOTO(BN_nnmod(b, b, n, ctx)); + + CHECK_GOTO(BN_to_montgomery(A, a, mont, ctx)); + CHECK_GOTO(BN_to_montgomery(B, b, mont, ctx)); + + CHECK_GOTO(BN_mod_mul_montgomery(c, A, B, mont, ctx)); + CHECK_GOTO(BN_from_montgomery(A, c, mont, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " % "); + /* n == &mont->N */ + CHECK_GOTO(BN_print(bp, n)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, A)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mod_mul(d, a, b, n, ctx)); + CHECK_GOTO(BN_sub(d, d, A)); + if (!BN_is_zero(d)) { + fprintf(stderr, "Montgomery multiplication test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + BN_MONT_CTX_free(mont); + + return ret; +} + +int +test_mod(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0)); + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_bntest_rand(b, 450 + i * 10, 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + CHECK_GOTO(BN_mod(c, a, b, ctx)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_div(d, e, a, b, ctx)); + CHECK_GOTO(BN_sub(e, e, c)); + if (!BN_is_zero(e)) { + fprintf(stderr, "Modulo test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_mod_mul(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i, j; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_one(a)); + CHECK_GOTO(BN_one(b)); + BN_zero(c); + if (BN_mod_mul(e, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n"); + goto err; + } + ERR_clear_error(); + + for (j = 0; j < 3; j++) { + CHECK_GOTO(BN_bntest_rand(c, 1024, 0, 0)); + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_bntest_rand(a, 475 + i * 10, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 425 + i * 11, 0, 0)); + BN_set_negative(a, rand_neg()); + BN_set_negative(b, rand_neg()); + if (!BN_mod_mul(e, a, b, c, ctx)) { + unsigned long l; + + while ((l = ERR_get_error())) + fprintf(stderr, "ERROR:%s\n", + ERR_error_string(l, NULL)); + exit(1); + } + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, c)); + if ((BN_is_negative(a) ^ BN_is_negative(b)) && + !BN_is_zero(e)) { + /* If (a*b) % c is negative, c must be added + * in order to obtain the normalized remainder + * (new with OpenSSL 0.9.7, previous versions of + * BN_mod_mul could generate negative results) + */ + BIO_puts(bp, " + "); + CHECK_GOTO(BN_print(bp, c)); + } + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, e)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul(d, a, b, ctx)); + CHECK_GOTO(BN_sub(d, d, e)); + CHECK_GOTO(BN_div(a, b, d, c, ctx)); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo multiply test failed!\n"); + ERR_print_errors_fp(stderr); + goto err; + } + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_mod_exp(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_one(a)); + CHECK_GOTO(BN_one(b)); + BN_zero(c); + if (BN_mod_exp(d, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n"); + goto err; + } + ERR_clear_error(); + if (BN_mod_exp_ct(d, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_exp_ct with zero modulus succeeded!\n"); + goto err; + } + ERR_clear_error(); + if (BN_mod_exp_nonct(d, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_exp_nonct with zero modulus succeeded!\n"); + goto err; + } + ERR_clear_error(); + + CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */ + for (i = 0; i < num2; i++) { + CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0)); + + if (!BN_mod_exp(d, a, b, c, ctx)) + goto err; + + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " ^ "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_exp(e, a, b, ctx)); + CHECK_GOTO(BN_sub(e, e, d)); + CHECK_GOTO(BN_div(a, b, e, c, ctx)); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo exponentiation test failed!\n"); + goto err; + } + } + + CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */ + for (i = 0; i < num2; i++) { + CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0)); + + if (!BN_mod_exp_ct(d, a, b, c, ctx)) + goto err; + + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " ^ "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_exp(e, a, b, ctx)); + CHECK_GOTO(BN_sub(e, e, d)); + CHECK_GOTO(BN_div(a, b, e, c, ctx)); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo exponentiation test failed!\n"); + goto err; + } + } + + CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */ + for (i = 0; i < num2; i++) { + CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0)); + + if (!BN_mod_exp_nonct(d, a, b, c, ctx)) + goto err; + + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " ^ "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_exp(e, a, b, ctx)); + CHECK_GOTO(BN_sub(e, e, d)); + CHECK_GOTO(BN_div(a, b, e, c, ctx)); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo exponentiation test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_one(a)); + CHECK_GOTO(BN_one(b)); + BN_zero(c); + if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) { + fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus " + "succeeded\n"); + goto err; + } + ERR_clear_error(); + + CHECK_GOTO(BN_set_word(c, 16)); + if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) { + fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus " + "succeeded\n"); + goto err; + } + ERR_clear_error(); + + CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */ + for (i = 0; i < num2; i++) { + CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0)); + + if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) + goto err; + + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " ^ "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " % "); + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_exp(e, a, b, ctx)); + CHECK_GOTO(BN_sub(e, e, d)); + CHECK_GOTO(BN_div(a, b, e, c, ctx)); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo exponentiation test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +/* + * Test constant-time modular exponentiation with 1024-bit inputs, which on + * x86_64 cause a different code branch to be taken. + */ +int +test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *p, *m, *d, *e; + BIGNUM *b, *n, *c; + BN_MONT_CTX *mont = NULL; + int len; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((m = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((n = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(mont = BN_MONT_CTX_new()); + + CHECK_GOTO(BN_bntest_rand(m, 1024, 0, 1)); /* must be odd for montgomery */ + /* Zero exponent */ + CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0)); + BN_zero(p); + if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) + goto err; + if (!BN_is_one(d)) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + goto err; + } + /* Regression test for carry bug in mulx4x_mont */ + len = BN_hex2bn(&a, + "7878787878787878787878787878787878787878787878787878787878787878" + "7878787878787878787878787878787878787878787878787878787878787878" + "7878787878787878787878787878787878787878787878787878787878787878" + "7878787878787878787878787878787878787878787878787878787878787878"); + CHECK_GOTO(len); + len = BN_hex2bn(&b, + "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744" + "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593" + "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03" + "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81"); + CHECK_GOTO(len); + len = BN_hex2bn(&n, + "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B" + "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5" + "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4" + "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF"); + CHECK_GOTO(len); + CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx)); + CHECK_GOTO(BN_mod_mul_montgomery(c, a, b, mont, ctx)); + CHECK_GOTO(BN_mod_mul_montgomery(d, b, a, mont, ctx)); + if (BN_cmp(c, d)) { + fprintf(stderr, "Montgomery multiplication test failed:" + " a*b != b*a.\n"); + goto err; + } + /* Regression test for carry bug in sqr[x]8x_mont */ + len = BN_hex2bn(&n, + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF00" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF"); + CHECK_GOTO(len); + len = BN_hex2bn(&a, + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF0000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000FFFFFFFFFFFFFF00000000"); + CHECK_GOTO(len); + CHECK_GOTO(bn_copy(b, a)); + CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx)); + CHECK_GOTO(BN_mod_mul_montgomery(c, a, a, mont, ctx)); + CHECK_GOTO(BN_mod_mul_montgomery(d, a, b, mont, ctx)); + if (BN_cmp(c, d)) { + fprintf(stderr, "Montgomery multiplication test failed:" + " a**2 != a*a.\n"); + goto err; + } + /* Zero input */ + CHECK_GOTO(BN_bntest_rand(p, 1024, 0, 0)); + BN_zero(a); + if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) + goto err; + if (!BN_is_zero(d)) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + goto err; + } + /* + * Craft an input whose Montgomery representation is 1, i.e., shorter + * than the modulus m, in order to test the const time precomputation + * scattering/gathering. + */ + CHECK_GOTO(BN_one(a)); + CHECK_GOTO(BN_MONT_CTX_set(mont, m, ctx)); + if (!BN_from_montgomery(e, a, mont, ctx)) + goto err; + if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) + goto err; + if (!BN_mod_exp_simple(a, e, p, m, ctx)) + goto err; + if (BN_cmp(a, d) != 0) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + goto err; + } + /* Finally, some regular test vectors. */ + CHECK_GOTO(BN_bntest_rand(e, 1024, 0, 0)); + if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) + goto err; + if (!BN_mod_exp_simple(a, e, p, m, ctx)) + goto err; + if (BN_cmp(a, d) != 0) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + goto err; + } + + ret = 1; + err: + BN_CTX_end(ctx); + BN_MONT_CTX_free(mont); + + return ret; +} + +int +test_exp(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + for (i = 0; i < num2; i++) { + CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0)); + CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0)); + + if (BN_exp(d, a, b, ctx) <= 0) + goto err; + + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " ^ "); + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, d)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_one(e)); + for (; !BN_is_zero(b); BN_sub_word(b, 1)) + CHECK_GOTO(BN_mul(e, e, a, ctx)); + CHECK_GOTO(BN_sub(e, e, d)); + if (!BN_is_zero(e)) { + fprintf(stderr, "Exponentiation test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +static int +genprime_cb(int p, int n, BN_GENCB *arg) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + putc(c, stderr); + return 1; +} + +int +test_kron(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *r, *t; + BN_GENCB *cb = NULL; + int i; + int legendre, kronecker; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r = BN_CTX_get(ctx)) == NULL) + goto err; + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((cb = BN_GENCB_new()) == NULL) + goto err; + + BN_GENCB_set(cb, genprime_cb, NULL); + + /* + * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In + * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is + * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we + * generate a random prime b and compare these values for a number of + * random a's. (That is, we run the Solovay-Strassen primality test to + * confirm that b is prime, except that we don't want to test whether b + * is prime but whether BN_kronecker works.) + */ + + if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, cb)) + goto err; + BN_set_negative(b, rand_neg()); + putc('\n', stderr); + + for (i = 0; i < num0; i++) { + if (!BN_bntest_rand(a, 512, 0, 0)) + goto err; + BN_set_negative(a, rand_neg()); + + /* t := (|b|-1)/2 (note that b is odd) */ + if (!bn_copy(t, b)) + goto err; + BN_set_negative(t, 0); + if (!BN_sub_word(t, 1)) + goto err; + if (!BN_rshift1(t, t)) + goto err; + /* r := a^t mod b */ + BN_set_negative(b, 0); + + if (!BN_mod_exp_recp(r, a, t, b, ctx)) + goto err; + BN_set_negative(b, 1); + + if (BN_is_word(r, 1)) + legendre = 1; + else if (BN_is_zero(r)) + legendre = 0; + else { + if (!BN_add_word(r, 1)) + goto err; + if (0 != BN_ucmp(r, b)) { + fprintf(stderr, "Legendre symbol computation failed\n"); + goto err; + } + legendre = -1; + } + + kronecker = BN_kronecker(a, b, ctx); + if (kronecker < -1) + goto err; + /* we actually need BN_kronecker(a, |b|) */ + if (BN_is_negative(a) && BN_is_negative(b)) + kronecker = -kronecker; + + if (legendre != kronecker) { + fprintf(stderr, "legendre != kronecker; a = "); + CHECK_GOTO(BN_print_fp(stderr, a)); + fprintf(stderr, ", b = "); + CHECK_GOTO(BN_print_fp(stderr, b)); + fprintf(stderr, "\n"); + goto err; + } + + putc('.', stderr); + } + + putc('\n', stderr); + + ret = 1; + err: + BN_GENCB_free(cb); + BN_CTX_end(ctx); + + return ret; +} + +int +test_sqrt(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *p, *r; + BN_GENCB *cb = NULL; + int i, j; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((p = BN_CTX_get(ctx)) == NULL) + goto err; + if ((r = BN_CTX_get(ctx)) == NULL) + goto err; + + if ((cb = BN_GENCB_new()) == NULL) + goto err; + + BN_GENCB_set(cb, genprime_cb, NULL); + + for (i = 0; i < 16; i++) { + if (i < 8) { + unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 }; + + if (!BN_set_word(p, primes[i])) + goto err; + } else { + if (!BN_set_word(a, 32)) + goto err; + if (!BN_set_word(r, 2 * i + 1)) + goto err; + + if (!BN_generate_prime_ex(p, 256, 0, a, r, cb)) + goto err; + putc('\n', stderr); + } + BN_set_negative(p, rand_neg()); + + for (j = 0; j < num2; j++) { + /* + * construct 'a' such that it is a square modulo p, but in + * general not a proper square and not reduced modulo p + */ + if (!BN_bntest_rand(r, 256, 0, 3)) + goto err; + if (!BN_nnmod(r, r, p, ctx)) + goto err; + if (!BN_mod_sqr(r, r, p, ctx)) + goto err; + if (!BN_bntest_rand(a, 256, 0, 3)) + goto err; + if (!BN_nnmod(a, a, p, ctx)) + goto err; + if (!BN_mod_sqr(a, a, p, ctx)) + goto err; + if (!BN_mul(a, a, r, ctx)) + goto err; + if (rand_neg()) + if (!BN_sub(a, a, p)) + goto err; + + if (!BN_mod_sqrt(r, a, p, ctx)) + goto err; + if (!BN_mod_sqr(r, r, p, ctx)) + goto err; + + if (!BN_nnmod(a, a, p, ctx)) + goto err; + + if (BN_cmp(a, r) != 0) { + fprintf(stderr, "BN_mod_sqrt failed: a = "); + CHECK_GOTO(BN_print_fp(stderr, a)); + fprintf(stderr, ", r = "); + CHECK_GOTO(BN_print_fp(stderr, r)); + fprintf(stderr, ", p = "); + CHECK_GOTO(BN_print_fp(stderr, p)); + fprintf(stderr, "\n"); + goto err; + } + + putc('.', stderr); + } + + putc('\n', stderr); + } + + ret = 1; + err: + BN_GENCB_free(cb); + BN_CTX_end(ctx); + + return ret; +} + +int +test_lshift(BIO *bp, BN_CTX *ctx, int use_lst) +{ + BIGNUM *a, *b, *c, *d; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + CHECK_GOTO(BN_one(c)); + + if (use_lst) { + if (!BN_hex2bn(&a, "C64F43042AEACA6E5836805BE8C99B04" + "5D4836C2FD16C964F0")) + goto err; + } else { + CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0)); + BN_set_negative(a, rand_neg()); + } + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_lshift(b, a, i + 1)); + CHECK_GOTO(BN_add(c, c, c)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * "); + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_mul(d, a, c, ctx)); + CHECK_GOTO(BN_sub(d, d, b)); + if (!BN_is_zero(d)) { + fprintf(stderr, "Left shift test failed!\n"); + fprintf(stderr, "a="); + CHECK_GOTO(BN_print_fp(stderr, a)); + fprintf(stderr, "\nb="); + CHECK_GOTO(BN_print_fp(stderr, b)); + fprintf(stderr, "\nc="); + CHECK_GOTO(BN_print_fp(stderr, c)); + fprintf(stderr, "\nd="); + CHECK_GOTO(BN_print_fp(stderr, d)); + fprintf(stderr, "\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_lshift1(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0)); + BN_set_negative(a, rand_neg()); + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_lshift1(b, a)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " * 2"); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_add(c, a, a)); + CHECK_GOTO(BN_sub(a, b, c)); + if (!BN_is_zero(a)) { + fprintf(stderr, "Left shift one test failed!\n"); + goto err; + } + + CHECK_GOTO(bn_copy(a, b)); + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_rshift(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((d = BN_CTX_get(ctx)) == NULL) + goto err; + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + CHECK_GOTO(BN_one(c)); + + CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0)); + BN_set_negative(a, rand_neg()); + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_rshift(b, a, i + 1)); + CHECK_GOTO(BN_add(c, c, c)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " / "); + CHECK_GOTO(BN_print(bp, c)); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_div(d, e, a, c, ctx)); + CHECK_GOTO(BN_sub(d, d, b)); + if (!BN_is_zero(d)) { + fprintf(stderr, "Right shift test failed!\n"); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +test_rshift1(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c; + int i; + int ret = 0; + + BN_CTX_start(ctx); + + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + + CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0)); + BN_set_negative(a, rand_neg()); + for (i = 0; i < num0; i++) { + CHECK_GOTO(BN_rshift1(b, a)); + if (bp != NULL) { + if (!results) { + CHECK_GOTO(BN_print(bp, a)); + BIO_puts(bp, " / 2"); + BIO_puts(bp, " - "); + } + CHECK_GOTO(BN_print(bp, b)); + BIO_puts(bp, "\n"); + } + CHECK_GOTO(BN_sub(c, a, b)); + CHECK_GOTO(BN_sub(c, c, b)); + if (!BN_is_zero(c) && !BN_abs_is_word(c, 1)) { + fprintf(stderr, "Right shift one test failed!\n"); + goto err; + } + CHECK_GOTO(bn_copy(a, b)); + } + + ret = 1; + err: + BN_CTX_end(ctx); + + return ret; +} + +int +rand_neg(void) +{ + static unsigned int neg = 0; + static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 }; + + return sign[neg++ % 8]; +} + +int +test_mod_exp_sizes(BIO *bp, BN_CTX *ctx) +{ + BN_MONT_CTX *mont_ctx = NULL; + BIGNUM *p, *x, *y, *r, *r2; + int size; + int ret = 0; + + BN_CTX_start(ctx); + CHECK_GOTO(p = BN_CTX_get(ctx)); + CHECK_GOTO(x = BN_CTX_get(ctx)); + CHECK_GOTO(y = BN_CTX_get(ctx)); + CHECK_GOTO(r = BN_CTX_get(ctx)); + CHECK_GOTO(r2 = BN_CTX_get(ctx)); + mont_ctx = BN_MONT_CTX_new(); + + if (r2 == NULL || mont_ctx == NULL) + goto err; + + if (!BN_generate_prime_ex(p, 32, 0, NULL, NULL, NULL) || + !BN_MONT_CTX_set(mont_ctx, p, ctx)) + goto err; + + for (size = 32; size < 1024; size += 8) { + if (!BN_rand(x, size, -1, 0) || + !BN_rand(y, size, -1, 0) || + !BN_mod_exp_mont_consttime(r, x, y, p, ctx, mont_ctx) || + !BN_mod_exp(r2, x, y, p, ctx)) + goto err; + + if (BN_cmp(r, r2) != 0) { + char *r_str = NULL; + char *r2_str = NULL; + CHECK_GOTO(r_str = BN_bn2hex(r)); + CHECK_GOTO(r2_str = BN_bn2hex(r2)); + + printf("Incorrect answer at size %d: %s vs %s\n", + size, r_str, r2_str); + free(r_str); + free(r2_str); + goto err; + } + } + + ret = 1; + err: + BN_CTX_end(ctx); + BN_MONT_CTX_free(mont_ctx); + + return ret; +} diff --git a/Libraries/libressl/tests/bn_to_string.c b/Libraries/libressl/tests/bn_to_string.c new file mode 100644 index 000000000..93945b873 --- /dev/null +++ b/Libraries/libressl/tests/bn_to_string.c @@ -0,0 +1,252 @@ +/* $OpenBSD: bn_to_string.c,v 1.5 2023/04/10 21:00:16 tb Exp $ */ +/* + * Copyright (c) 2019 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +struct bn_to_string_tests { + const char *input; + const char *want; +} testcases[] = { + { + .input = "0x0", + .want = "0", + }, + { + .input = "-0x0", + .want = "0", + }, + { + .input = "0x7", + .want = "7", + }, + { + .input = "-0x7", + .want = "-7", + }, + { + .input = "0x8", + .want = "8", + }, + { + .input = "-0x8", + .want = "-8", + }, + { + .input = "0xF", + .want = "15", + }, + { + .input = "-0xF", + .want = "-15", + }, + { + .input = "0x10", + .want = "16", + }, + { + .input = "-0x10", + .want = "-16", + }, + { + .input = "0x7F", + .want = "127", + }, + { + .input = "-0x7F", + .want = "-127", + }, + { + .input = "0x80", + .want = "128", + }, + { + .input = "-0x80", + .want = "-128", + }, + { + .input = "0xFF", + .want = "255", + }, + { + .input = "-0xFF", + .want = "-255", + }, + { + .input = "0x100", + .want = "256", + }, + { + .input = "0x7FFF", + .want = "32767", + }, + { + .input = "-0x7FFF", + .want = "-32767", + }, + { + .input = "0x8000", + .want = "32768", + }, + { + .input = "-0x8000", + .want = "-32768", + }, + { + .input = "0xFFFF", + .want = "65535", + }, + { + .input = "-0xFFFF", + .want = "-65535", + }, + { + .input = "0x10000", + .want = "65536", + }, + { + .input = "-0x10000", + .want = "-65536", + }, + { + .input = "0x7FFFFFFF", + .want = "2147483647", + }, + { + .input = "-0x7FFFFFFF", + .want = "-2147483647", + }, + { + .input = "0x80000000", + .want = "2147483648", + }, + { + .input = "-0x80000000", + .want = "-2147483648", + }, + { + .input = "0xFFFFFFFF", + .want = "4294967295", + }, + { + .input = "-0xFFFFFFFF", + .want = "-4294967295", + }, + { + .input = "0x100000000", + .want = "4294967296", + }, + { + .input = "-0x100000000", + .want = "-4294967296", + }, + { + .input = "0x7FFFFFFFFFFFFFFF", + .want = "9223372036854775807", + }, + { + .input = "-0x7FFFFFFFFFFFFFFF", + .want = "-9223372036854775807", + }, + { + .input = "0x8000000000000000", + .want = "9223372036854775808", + }, + { + .input = "-0x8000000000000000", + .want = "-9223372036854775808", + }, + { + .input = "0xFFFFFFFFFFFFFFFF", + .want = "18446744073709551615", + }, + { + .input = "-0xFFFFFFFFFFFFFFFF", + .want = "-18446744073709551615", + }, + { + .input = "0x10000000000000000", + .want = "18446744073709551616", + }, + { + .input = "-0x10000000000000000", + .want = "-18446744073709551616", + }, + { + .input = "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + .want = "170141183460469231731687303715884105727", + }, + { + .input = "-0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + .want = "-170141183460469231731687303715884105727", + }, + { + .input = "0x80000000000000000000000000000000", + .want = "0x80000000000000000000000000000000", + }, + { + .input = "-0x80000000000000000000000000000000", + .want = "-0x80000000000000000000000000000000", + }, + { + .input = "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + .want = "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + }, + { + .input = "-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + .want = "-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + }, + { + .input = "0x100000000000000000000000000000000", + .want = "0x0100000000000000000000000000000000", + }, + { + .input = "-0x100000000000000000000000000000000", + .want = "-0x0100000000000000000000000000000000", + }, + { + .input = NULL, + }, +}; + +int +main(void) +{ + struct bn_to_string_tests *test; + ASN1_INTEGER *aint; + char *got; + int failed = 0; + + for (test = testcases; test->input != NULL; test++) { + if ((aint = s2i_ASN1_INTEGER(NULL, test->input)) == NULL) + errx(1, "s2i_ASN1_INTEGER(%s)", test->input); + if ((got = i2s_ASN1_INTEGER(NULL, aint)) == NULL) + errx(1, "i2s_ASN1_INTEGER(%s)", test->input); + if (strcmp(got, test->want) != 0) { + warnx("want: %s, got: %s", test->want, got); + failed |= 1; + } + ASN1_INTEGER_free(aint); + free(got); + } + + return failed; +} diff --git a/Libraries/libressl/tests/bn_unit.c b/Libraries/libressl/tests/bn_unit.c new file mode 100644 index 000000000..3a88bfca6 --- /dev/null +++ b/Libraries/libressl/tests/bn_unit.c @@ -0,0 +1,307 @@ +/* $OpenBSD: bn_unit.c,v 1.7 2023/06/21 07:15:38 jsing Exp $ */ + +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include + +static int +test_bn_print_wrapper(char *a, size_t size, const char *descr, + int (*to_bn)(BIGNUM **, const char *)) +{ + int ret; + + ret = to_bn(NULL, a); + if (ret != 0 && (ret < 0 || (size_t)ret != size - 1)) { + fprintf(stderr, "unexpected %s() return" + "want 0 or %zu, got %d\n", descr, size - 1, ret); + return 1; + } + + return 0; +} + +static int +test_bn_print_null_derefs(void) +{ + size_t size = INT_MAX / 4 + 4; + size_t datalimit = (size + 500 * 1024) / 1024; + char *a; + char digit; + int failed = 0; + + if ((a = malloc(size)) == NULL) { + warn("malloc(%zu) failed (make sure data limit is >= %zu KiB)", + size, datalimit); + return 0; + } + + /* Fill with a random digit since coverity doesn't like us using '0'. */ + digit = '0' + arc4random_uniform(10); + + memset(a, digit, size - 1); + a[size - 1] = '\0'; + + failed |= test_bn_print_wrapper(a, size, "BN_dec2bn", BN_dec2bn); + failed |= test_bn_print_wrapper(a, size, "BN_hex2bn", BN_hex2bn); + + free(a); + + return failed; +} + +static int +test_bn_num_bits(void) +{ + BIGNUM *bn; + int i, num_bits; + int failed = 0; + + if ((bn = BN_new()) == NULL) + errx(1, "BN_new"); + + if ((num_bits = BN_num_bits(bn)) != 0) { + warnx("BN_num_bits(0): got %d, want 0", num_bits); + failed |= 1; + } + + if (!BN_set_word(bn, 1)) + errx(1, "BN_set_word"); + + for (i = 0; i <= 5 * BN_BITS2; i++) { + if ((num_bits = BN_num_bits(bn)) != i + 1) { + warnx("BN_num_bits(1 << %d): got %d, want %d", + i, num_bits, i + 1); + failed |= 1; + } + if (!BN_lshift1(bn, bn)) + errx(1, "BN_lshift1"); + } + + if (BN_hex2bn(&bn, "0000000000000000010000000000000000") != 34) + errx(1, "BN_hex2bn"); + + if ((num_bits = BN_num_bits(bn)) != 65) { + warnx("BN_num_bits(1 << 64) padded: got %d, want %d", + num_bits, 65); + failed |= 1; + } + + BN_free(bn); + + return failed; +} + +static int +test_bn_num_bits_word(void) +{ + BN_ULONG w = 1; + int i, num_bits; + int failed = 0; + + if ((num_bits = BN_num_bits_word(0)) != 0) { + warnx("BN_num_bits_word(0): want 0, got %d", num_bits); + failed |= 1; + } + + for (i = 0; i < BN_BITS2; i++) { + if ((num_bits = BN_num_bits_word(w << i)) != i + 1) { + warnx("BN_num_bits_word(0x%llx): want %d, got %d", + (unsigned long long)(w << i), i + 1, num_bits); + failed |= 1; + } + } + + return failed; +} + +#define BN_FLG_ALL_KNOWN \ + (BN_FLG_STATIC_DATA | BN_FLG_CONSTTIME | BN_FLG_MALLOCED) + +static int +bn_check_expected_flags(const BIGNUM *bn, int expected, const char *fn, + const char *descr) +{ + int flags, got; + int ret = 1; + + flags = BN_get_flags(bn, BN_FLG_ALL_KNOWN); + + if ((got = flags & expected) != expected) { + fprintf(stderr, "%s: %s: expected flags: want %x, got %x\n", + fn, descr, expected, got); + ret = 0; + } + + if ((got = flags & ~expected) != 0) { + fprintf(stderr, "%s: %s: unexpected flags: want %x, got %x\n", + fn, descr, 0, got); + ret = 0; + } + + return ret; +} + +static int +test_bn_copy_copies_flags(void) +{ + BIGNUM *dst, *src; + int failed = 0; + + if ((dst = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after BN_new")) + failed |= 1; + + if (BN_copy(dst, BN_value_one()) == NULL) + errx(1, "%s: bn_copy()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after bn_copy")) + failed |= 1; + + if ((src = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + BN_set_flags(src, BN_FLG_CONSTTIME); + + if (!bn_check_expected_flags(src, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "src after BN_set_flags")) + failed |= 1; + + if (!BN_set_word(src, 57)) + errx(1, "%s: BN_set_word(src, 57)", __func__); + + if (BN_copy(dst, src) == NULL) + errx(1, "%s: BN_copy(dst, src)", __func__); + + if (BN_cmp(src, dst) != 0) { + fprintf(stderr, "copy not equal to original\n"); + failed |= 1; + } + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "dst after BN_copy(dst, src)")) + failed |= 1; + + BN_free(dst); + BN_free(src); + + return failed; +} + +static int +test_bn_copy_consttime_is_sticky(void) +{ + BIGNUM *src, *dst; + int failed = 0; + + if ((src = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + if (!bn_check_expected_flags(src, BN_FLG_MALLOCED, + __func__, "src after BN_new")) + failed |= 1; + + if ((dst = BN_new()) == NULL) + errx(1, "%s: dst = BN_new()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after BN_new")) + failed |= 1; + + BN_set_flags(dst, BN_FLG_CONSTTIME); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "src after BN_new")) + failed |= 1; + + if (BN_copy(dst, BN_value_one()) == NULL) + errx(1, "%s: bn_copy()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "dst after bn_copy")) + failed |= 1; + + BN_free(dst); + BN_free(src); + + return failed; +} + +static int +test_bn_dup_consttime_is_sticky(void) +{ + BIGNUM *src, *dst; + int failed = 0; + + if (!bn_check_expected_flags(BN_value_one(), BN_FLG_STATIC_DATA, + __func__, "flags on BN_value_one()")) + failed |= 1; + + if ((dst = BN_dup(BN_value_one())) == NULL) + errx(1, "%s: dst = BN_dup(BN_value_one())", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after BN_dup(BN_value_one())")) + failed |= 1; + + BN_free(dst); + + if ((src = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + BN_set_flags(src, BN_FLG_CONSTTIME); + + if (!bn_check_expected_flags(src, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "src after BN_new")) + failed |= 1; + + if ((dst = BN_dup(src)) == NULL) + errx(1, "%s: dst = BN_dup(src)", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "dst after bn_copy")) + failed |= 1; + + BN_free(dst); + BN_free(src); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= test_bn_print_null_derefs(); + failed |= test_bn_num_bits(); + failed |= test_bn_num_bits_word(); + failed |= test_bn_copy_copies_flags(); + failed |= test_bn_copy_consttime_is_sticky(); + failed |= test_bn_dup_consttime_is_sticky(); + + return failed; +} diff --git a/Libraries/libressl/tests/bn_word.c b/Libraries/libressl/tests/bn_word.c new file mode 100644 index 000000000..0a543add9 --- /dev/null +++ b/Libraries/libressl/tests/bn_word.c @@ -0,0 +1,617 @@ +/* $OpenBSD: bn_word.c,v 1.1 2023/03/11 14:04:21 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +struct bn_word_test { + const char *in_hex; + BN_ULONG in_word; + BN_ULONG mod_word; + BN_ULONG out_word; + const char *out_hex; + int out_is_negative; +}; + +static int +check_bn_word_test(const char *op_name, const BIGNUM *bn, + const struct bn_word_test *bwt) +{ + char *out_hex = NULL; + BN_ULONG out_word; + int failed = 1; + + if ((out_word = BN_get_word(bn)) != bwt->out_word) { + fprintf(stderr, "FAIL %s: Got word %lx, want %lx\n", + op_name, (unsigned long)out_word, + (unsigned long)bwt->out_word); + goto failure; + } + + if (BN_is_negative(bn) != bwt->out_is_negative) { + fprintf(stderr, "FAIL %s: Got is negative %d, want %d\n", + op_name, BN_is_negative(bn), bwt->out_is_negative); + goto failure; + } + + if ((out_hex = BN_bn2hex(bn)) == NULL) + errx(1, "BN_bn2hex() failed\n"); + + if (strcmp(out_hex, bwt->out_hex) != 0) { + fprintf(stderr, "FAIL %s: Got hex %s, want %s\n", + op_name, out_hex, bwt->out_hex); + goto failure; + } + + if (BN_is_zero(bn) && BN_is_negative(bn) != 0) { + fprintf(stderr, "FAIL %s: Got negative zero\n", op_name); + goto failure; + } + + failed = 0; + + failure: + free(out_hex); + + return failed; +} + +static int +test_bn_word(int (*bn_word_op)(BIGNUM *, BN_ULONG), const char *op_name, + const struct bn_word_test *bwts, size_t num_tests) +{ + const struct bn_word_test *bwt; + BIGNUM *bn; + size_t i; + int failed = 0; + + if ((bn = BN_new()) == NULL) + errx(1, "BN_new() failed\n"); + + for (i = 0; i < num_tests; i++) { + bwt = &bwts[i]; + + if (!BN_hex2bn(&bn, bwt->in_hex)) { + fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n", + bwt->in_hex); + failed = 1; + continue; + } + + if (!bn_word_op(bn, bwt->in_word)) { + fprintf(stderr, "FAIL: %s(%lx) failed\n", op_name, + (unsigned long)bwt->in_word); + failed = 1; + continue; + } + + failed |= check_bn_word_test(op_name, bn, bwt); + } + + BN_free(bn); + + return failed; +} + +static const struct bn_word_test bn_add_word_tests[] = { + { + .in_hex = "1", + .in_word = 0, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "0", + .in_word = 1, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "1", + .in_word = 1, + .out_word = 2, + .out_hex = "02", + }, + { + .in_hex = "-1", + .in_word = 2, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "-1", + .in_word = 1, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "-3", + .in_word = 2, + .out_word = 1, + .out_hex = "-01", + .out_is_negative = 1, + }, + { + .in_hex = "1", + .in_word = 0xfffffffeUL, + .out_word = 0xffffffffUL, + .out_hex = "FFFFFFFF", + }, + { + .in_hex = "FFFFFFFFFFFFFFFF", + .in_word = 1, + .out_word = BN_MASK2, + .out_hex = "010000000000000000", + }, +}; + +#define N_BN_ADD_WORD_TESTS \ + (sizeof(bn_add_word_tests) / sizeof(bn_add_word_tests[0])) + +static int +test_bn_add_word(void) +{ + return test_bn_word(BN_add_word, "BN_add_word", bn_add_word_tests, + N_BN_ADD_WORD_TESTS); +} + +static const struct bn_word_test bn_sub_word_tests[] = { + { + .in_hex = "1", + .in_word = 0, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "0", + .in_word = 1, + .out_word = 1, + .out_hex = "-01", + .out_is_negative = 1, + }, + { + .in_hex = "1", + .in_word = 1, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "2", + .in_word = 1, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "-1", + .in_word = 2, + .out_word = 3, + .out_hex = "-03", + .out_is_negative = 1, + }, + { + .in_hex = "1", + .in_word = 1, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "3", + .in_word = 2, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "-3", + .in_word = 2, + .out_word = 5, + .out_hex = "-05", + .out_is_negative = 1, + }, + { + .in_hex = "-1", + .in_word = 0xfffffffeUL, + .out_word = 0xffffffffUL, + .out_hex = "-FFFFFFFF", + .out_is_negative = 1, + }, + { + .in_hex = "010000000000000000", + .in_word = 1, + .out_word = BN_MASK2, + .out_hex = "FFFFFFFFFFFFFFFF", + }, +}; + +#define N_BN_SUB_WORD_TESTS \ + (sizeof(bn_sub_word_tests) / sizeof(bn_sub_word_tests[0])) + +static int +test_bn_sub_word(void) +{ + return test_bn_word(BN_sub_word, "BN_sub_word", bn_sub_word_tests, + N_BN_SUB_WORD_TESTS); +} + +static const struct bn_word_test bn_mul_word_tests[] = { + { + .in_hex = "1", + .in_word = 0, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "0", + .in_word = 1, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "1", + .in_word = 1, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "-1", + .in_word = 0, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "-1", + .in_word = 1, + .out_word = 1, + .out_hex = "-01", + .out_is_negative = 1, + }, + { + .in_hex = "-3", + .in_word = 2, + .out_word = 6, + .out_hex = "-06", + .out_is_negative = 1, + }, + { + .in_hex = "1", + .in_word = 0xfffffffeUL, + .out_word = 0xfffffffeUL, + .out_hex = "FFFFFFFE", + }, + { + .in_hex = "010000000000000000", + .in_word = 2, + .out_word = BN_MASK2, + .out_hex = "020000000000000000", + }, +}; + +#define N_BN_MUL_WORD_TESTS \ + (sizeof(bn_mul_word_tests) / sizeof(bn_mul_word_tests[0])) + +static int +test_bn_mul_word(void) +{ + return test_bn_word(BN_mul_word, "BN_mul_word", bn_mul_word_tests, + N_BN_MUL_WORD_TESTS); +} + +static const struct bn_word_test bn_div_word_tests[] = { + { + .in_hex = "1", + .in_word = 0, + .mod_word = BN_MASK2, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "0", + .in_word = 1, + .mod_word = 0, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "4", + .in_word = 2, + .mod_word = 0, + .out_word = 2, + .out_hex = "02", + }, + { + .in_hex = "7", + .in_word = 3, + .mod_word = 1, + .out_word = 2, + .out_hex = "02", + }, + { + .in_hex = "1", + .in_word = 1, + .mod_word = 0, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "-2", + .in_word = 1, + .mod_word = 0, + .out_word = 2, + .out_hex = "-02", + .out_is_negative = 1, + }, + { + .in_hex = "-1", + .in_word = 2, + .mod_word = 1, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "-3", + .in_word = 2, + .mod_word = 1, + .out_word = 1, + .out_hex = "-01", + .out_is_negative = 1, + }, + { + .in_hex = "1", + .in_word = 0xffffffffUL, + .mod_word = 1, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "FFFFFFFF", + .in_word = 1, + .mod_word = 0, + .out_word = 0xffffffffUL, + .out_hex = "FFFFFFFF", + }, + { + .in_hex = "FFFFFFFE", + .in_word = 0xffffffffUL, + .mod_word = 0xfffffffeUL, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "FFFFFFFFFFFFFFFF", + .in_word = 1, + .mod_word = 0, + .out_word = BN_MASK2, + .out_hex = "FFFFFFFFFFFFFFFF", + }, + { + .in_hex = "FFFFFFFF", + .in_word = 0xff, + .mod_word = 0, + .out_word = 0x1010101UL, + .out_hex = "01010101", + }, + { + .in_hex = "FFFFFFFF", + .in_word = 0x10, + .mod_word = 0xf, + .out_word = 0xfffffffUL, + .out_hex = "0FFFFFFF", + }, +}; + +#define N_BN_DIV_WORD_TESTS \ + (sizeof(bn_div_word_tests) / sizeof(bn_div_word_tests[0])) + +static int +test_bn_div_word(void) +{ + const char *op_name = "BN_div_word"; + const struct bn_word_test *bwt; + BN_ULONG mod_word; + BIGNUM *bn; + size_t i; + int failed = 0; + + if ((bn = BN_new()) == NULL) + errx(1, "BN_new() failed\n"); + + for (i = 0; i < N_BN_DIV_WORD_TESTS; i++) { + bwt = &bn_div_word_tests[i]; + + if (!BN_hex2bn(&bn, bwt->in_hex)) { + fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n", + bwt->in_hex); + failed = 1; + continue; + } + + if ((mod_word = BN_div_word(bn, bwt->in_word)) != bwt->mod_word) { + fprintf(stderr, "FAIL %s: Got mod word %lx, want %lx\n", + op_name, (unsigned long)mod_word, + (unsigned long)bwt->mod_word); + failed = 1; + continue; + } + + failed |= check_bn_word_test(op_name, bn, bwt); + } + + BN_free(bn); + + return failed; +} + +static const struct bn_word_test bn_mod_word_tests[] = { + { + .in_hex = "1", + .in_word = 0, + .mod_word = BN_MASK2, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "0", + .in_word = 1, + .mod_word = 0, + .out_word = 0, + .out_hex = "0", + }, + { + .in_hex = "4", + .in_word = 2, + .mod_word = 0, + .out_word = 4, + .out_hex = "04", + }, + { + .in_hex = "7", + .in_word = 3, + .mod_word = 1, + .out_word = 7, + .out_hex = "07", + }, + { + .in_hex = "1", + .in_word = 1, + .mod_word = 0, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "-2", + .in_word = 1, + .mod_word = 0, + .out_word = 2, + .out_hex = "-02", + .out_is_negative = 1, + }, + { + .in_hex = "-1", + .in_word = 2, + .mod_word = 1, + .out_word = 1, + .out_hex = "-01", + .out_is_negative = 1, + }, + { + .in_hex = "-3", + .in_word = 2, + .mod_word = 1, + .out_word = 3, + .out_hex = "-03", + .out_is_negative = 1, + }, + { + .in_hex = "1", + .in_word = 0xffffffffUL, + .mod_word = 1, + .out_word = 1, + .out_hex = "01", + }, + { + .in_hex = "FFFFFFFF", + .in_word = 1, + .mod_word = 0, + .out_word = 0xffffffffUL, + .out_hex = "FFFFFFFF", + }, + { + .in_hex = "FFFFFFFE", + .in_word = 0xffffffffUL, + .mod_word = 0xfffffffeUL, + .out_word = 0xfffffffeUL, + .out_hex = "FFFFFFFE", + }, + { + .in_hex = "FFFFFFFFFFFFFFFF", + .in_word = 1, + .mod_word = 0, + .out_word = BN_MASK2, + .out_hex = "FFFFFFFFFFFFFFFF", + }, + { + .in_hex = "FFFFFFFF", + .in_word = 0xff, + .mod_word = 0, + .out_word = 0xffffffff, + .out_hex = "FFFFFFFF", + }, + { + .in_hex = "FFFFFFFF", + .in_word = 0x10, + .mod_word = 0xf, + .out_word = 0xffffffffUL, + .out_hex = "FFFFFFFF", + }, +}; + +#define N_BN_MOD_WORD_TESTS \ + (sizeof(bn_mod_word_tests) / sizeof(bn_mod_word_tests[0])) + +static int +test_bn_mod_word(void) +{ + const char *op_name = "BN_mod_word"; + const struct bn_word_test *bwt; + BN_ULONG mod_word; + BIGNUM *bn; + size_t i; + int failed = 0; + + if ((bn = BN_new()) == NULL) + errx(1, "BN_new() failed\n"); + + for (i = 0; i < N_BN_MOD_WORD_TESTS; i++) { + bwt = &bn_mod_word_tests[i]; + + if (!BN_hex2bn(&bn, bwt->in_hex)) { + fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n", + bwt->in_hex); + failed = 1; + continue; + } + + if ((mod_word = BN_mod_word(bn, bwt->in_word)) != bwt->mod_word) { + fprintf(stderr, "FAIL %s: Got mod word %lx, want %lx\n", + op_name, (unsigned long)mod_word, + (unsigned long)bwt->mod_word); + failed = 1; + continue; + } + + failed |= check_bn_word_test(op_name, bn, bwt); + } + + BN_free(bn); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_bn_add_word(); + failed |= test_bn_sub_word(); + failed |= test_bn_mul_word(); + failed |= test_bn_div_word(); + failed |= test_bn_mod_word(); + + return failed; +} diff --git a/Libraries/libressl/tests/buffertest.c b/Libraries/libressl/tests/buffertest.c new file mode 100644 index 000000000..3dfad7c44 --- /dev/null +++ b/Libraries/libressl/tests/buffertest.c @@ -0,0 +1,364 @@ +/* $OpenBSD: buffertest.c,v 1.6 2022/07/22 19:34:55 jsing Exp $ */ +/* + * Copyright (c) 2019, 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include "tls_internal.h" + +uint8_t testdata[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +struct read_state { + uint8_t *buf; + size_t len; + size_t offset; +}; + +static ssize_t +read_cb(void *buf, size_t buflen, void *cb_arg) +{ + struct read_state *rs = cb_arg; + ssize_t n; + + if (rs->offset > rs->len) + return TLS_IO_EOF; + + if ((size_t)(n = buflen) > (rs->len - rs->offset)) + n = rs->len - rs->offset; + + if (n == 0) + return TLS_IO_WANT_POLLIN; + + memcpy(buf, &rs->buf[rs->offset], n); + rs->offset += n; + + return n; +} + +struct extend_test { + size_t extend_len; + size_t read_len; + ssize_t want_ret; +}; + +const struct extend_test extend_tests[] = { + { + .extend_len = 4, + .read_len = 0, + .want_ret = TLS_IO_WANT_POLLIN, + }, + { + .extend_len = 4, + .read_len = 8, + .want_ret = 4, + }, + { + .extend_len = 12, + .read_len = 8, + .want_ret = TLS_IO_WANT_POLLIN, + }, + { + .extend_len = 12, + .read_len = 10, + .want_ret = TLS_IO_WANT_POLLIN, + }, + { + .extend_len = 12, + .read_len = 12, + .want_ret = 12, + }, + { + .extend_len = 16, + .read_len = 16, + .want_ret = 16, + }, + { + .extend_len = 20, + .read_len = 1, + .want_ret = TLS_IO_EOF, + }, +}; + +#define N_EXTEND_TESTS (sizeof(extend_tests) / sizeof(extend_tests[0])) + +static int +tls_buffer_extend_test(void) +{ + const struct extend_test *et; + struct tls_buffer *buf; + struct read_state rs; + uint8_t *data = NULL; + size_t i, data_len; + ssize_t ret; + CBS cbs; + int failed = 1; + + rs.buf = testdata; + rs.offset = 0; + + if ((buf = tls_buffer_new(0)) == NULL) + errx(1, "tls_buffer_new"); + + for (i = 0; i < N_EXTEND_TESTS; i++) { + et = &extend_tests[i]; + rs.len = et->read_len; + + ret = tls_buffer_extend(buf, et->extend_len, read_cb, &rs); + if (ret != extend_tests[i].want_ret) { + fprintf(stderr, "FAIL: Test %zd - extend returned %zd, " + "want %zd\n", i, ret, et->want_ret); + goto failed; + } + + if (!tls_buffer_data(buf, &cbs)) { + fprintf(stderr, "FAIL: Test %zd - failed to get data\n", + i); + goto failed; + } + + if (!CBS_mem_equal(&cbs, testdata, CBS_len(&cbs))) { + fprintf(stderr, "FAIL: Test %zd - extend buffer " + "mismatch", i); + goto failed; + } + } + + if (!tls_buffer_finish(buf, &data, &data_len)) { + fprintf(stderr, "FAIL: failed to finish\n"); + goto failed; + } + + tls_buffer_free(buf); + buf = NULL; + + if (data_len != sizeof(testdata)) { + fprintf(stderr, "FAIL: got data length %zu, want %zu\n", + data_len, sizeof(testdata)); + goto failed; + } + if (memcmp(data, testdata, data_len) != 0) { + fprintf(stderr, "FAIL: data mismatch\n"); + goto failed; + } + + failed = 0; + + failed: + tls_buffer_free(buf); + free(data); + + return failed; +} + +struct read_write_test { + uint8_t pattern; + size_t read; + size_t write; + size_t append; + ssize_t want; +}; + +const struct read_write_test read_write_tests[] = { + { + .read = 2048, + .want = TLS_IO_WANT_POLLIN, + }, + { + .pattern = 0xdb, + .write = 2048, + .want = 2048, + }, + { + .pattern = 0xbd, + .append = 2048, + .want = 1, + }, + { + .pattern = 0xdb, + .read = 2048, + .want = 2048, + }, + { + .pattern = 0xfe, + .append = 1024, + .want = 1, + }, + { + .pattern = 0xbd, + .read = 1000, + .want = 1000, + }, + { + .pattern = 0xbd, + .read = 1048, + .want = 1048, + }, + { + .pattern = 0xdb, + .write = 2048, + .want = 2048, + }, + { + .pattern = 0xbd, + .append = 1024, + .want = 1, + }, + { + .pattern = 0xee, + .append = 4096, + .want = 1, + }, + { + .pattern = 0xfe, + .append = 1, + .want = 0, + }, + { + .pattern = 0xfe, + .write = 1, + .want = TLS_IO_FAILURE, + }, + { + .pattern = 0xfe, + .read = 1024, + .want = 1024, + }, + { + .pattern = 0xdb, + .read = 2048, + .want = 2048, + }, + { + .pattern = 0xbd, + .read = 1024, + .want = 1024, + }, + { + .pattern = 0xee, + .read = 1024, + .want = 1024, + }, + { + .pattern = 0xee, + .read = 4096, + .want = 3072, + }, + { + .read = 2048, + .want = TLS_IO_WANT_POLLIN, + }, +}; + +#define N_READ_WRITE_TESTS (sizeof(read_write_tests) / sizeof(read_write_tests[0])) + +static int +tls_buffer_read_write_test(void) +{ + const struct read_write_test *rwt; + struct tls_buffer *buf = NULL; + uint8_t *rbuf = NULL, *wbuf = NULL; + ssize_t n; + size_t i; + int ret; + int failed = 1; + + if ((buf = tls_buffer_new(0)) == NULL) + errx(1, "tls_buffer_new"); + + tls_buffer_set_capacity_limit(buf, 8192); + + for (i = 0; i < N_READ_WRITE_TESTS; i++) { + rwt = &read_write_tests[i]; + + if (rwt->append > 0) { + free(wbuf); + if ((wbuf = malloc(rwt->append)) == NULL) + errx(1, "malloc"); + memset(wbuf, rwt->pattern, rwt->append); + if ((ret = tls_buffer_append(buf, wbuf, rwt->append)) != + rwt->want) { + fprintf(stderr, "FAIL: test %zu - " + "tls_buffer_append() = %d, want %zu\n", + i, ret, rwt->want); + goto failed; + } + } + + if (rwt->write > 0) { + free(wbuf); + if ((wbuf = malloc(rwt->write)) == NULL) + errx(1, "malloc"); + memset(wbuf, rwt->pattern, rwt->write); + if ((n = tls_buffer_write(buf, wbuf, rwt->write)) != + rwt->want) { + fprintf(stderr, "FAIL: test %zu - " + "tls_buffer_write() = %zi, want %zu\n", + i, n, rwt->want); + goto failed; + } + } + + if (rwt->read > 0) { + free(rbuf); + if ((rbuf = calloc(1, rwt->read)) == NULL) + errx(1, "malloc"); + if ((n = tls_buffer_read(buf, rbuf, rwt->read)) != + rwt->want) { + fprintf(stderr, "FAIL: test %zu - " + "tls_buffer_read() = %zi, want %zu\n", + i, n, rwt->want); + goto failed; + } + if (rwt->want > 0) { + free(wbuf); + if ((wbuf = malloc(rwt->want)) == NULL) + errx(1, "malloc"); + memset(wbuf, rwt->pattern, rwt->want); + if (memcmp(rbuf, wbuf, rwt->want) != 0) { + fprintf(stderr, "FAIL: test %zu - " + "read byte mismatch\n", i); + goto failed; + } + } + } + } + + failed = 0; + + failed: + tls_buffer_free(buf); + free(rbuf); + free(wbuf); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= tls_buffer_extend_test(); + failed |= tls_buffer_read_write_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/bytestringtest.c b/Libraries/libressl/tests/bytestringtest.c new file mode 100644 index 000000000..36f45c4bd --- /dev/null +++ b/Libraries/libressl/tests/bytestringtest.c @@ -0,0 +1,968 @@ +/* $OpenBSD: bytestringtest.c,v 1.17 2023/01/01 17:43:04 miod Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include + +#include "bytestring.h" + +/* This is from in boringssl */ +#define OPENSSL_U64(x) x##ULL + +#define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__, \ + __LINE__) + +#define CHECK(a) do { \ + if (!(a)) { \ + PRINT_ERROR; \ + return 0; \ + } \ +} while (0) + +#define CHECK_GOTO(a) do { \ + if (!(a)) { \ + PRINT_ERROR; \ + goto err; \ + } \ +} while (0) + +static int +test_skip(void) +{ + static const uint8_t kData[] = {1, 2, 3}; + CBS data; + + CBS_init(&data, kData, sizeof(kData)); + + CHECK(CBS_len(&data) == 3); + CHECK(CBS_skip(&data, 1)); + CHECK(CBS_len(&data) == 2); + CHECK(CBS_skip(&data, 2)); + CHECK(CBS_len(&data) == 0); + CHECK(!CBS_skip(&data, 1)); + + return 1; +} + +static int +test_get_u(void) +{ + static const uint8_t kData[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + }; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + CBS data; + + CBS_init(&data, kData, sizeof(kData)); + + CHECK(CBS_get_u8(&data, &u8)); + CHECK(u8 == 1); + CHECK(CBS_get_u16(&data, &u16)); + CHECK(u16 == 0x203); + CHECK(CBS_get_u24(&data, &u32)); + CHECK(u32 == 0x40506); + CHECK(CBS_get_u32(&data, &u32)); + CHECK(u32 == 0x708090a); + CHECK(CBS_get_u64(&data, &u64)); + CHECK(u64 == 0x0b0c0d0e0f101112ULL); + CHECK(CBS_get_last_u8(&data, &u8)); + CHECK(u8 == 20); + CHECK(CBS_get_last_u8(&data, &u8)); + CHECK(u8 == 19); + CHECK(!CBS_get_u8(&data, &u8)); + CHECK(!CBS_get_last_u8(&data, &u8)); + + return 1; +} + +static int +test_get_prefixed(void) +{ + static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1}; + uint8_t u8; + uint16_t u16; + uint32_t u32; + CBS data, prefixed; + + CBS_init(&data, kData, sizeof(kData)); + + CHECK(CBS_get_u8_length_prefixed(&data, &prefixed)); + CHECK(CBS_len(&prefixed) == 1); + CHECK(CBS_get_u8(&prefixed, &u8)); + CHECK(u8 == 2); + CHECK(CBS_get_u16_length_prefixed(&data, &prefixed)); + CHECK(CBS_len(&prefixed) == 2); + CHECK(CBS_get_u16(&prefixed, &u16)); + CHECK(u16 == 0x304); + CHECK(CBS_get_u24_length_prefixed(&data, &prefixed)); + CHECK(CBS_len(&prefixed) == 3); + CHECK(CBS_get_u24(&prefixed, &u32)); + CHECK(u32 == 0x30201); + + return 1; +} + +static int +test_get_prefixed_bad(void) +{ + static const uint8_t kData1[] = {2, 1}; + static const uint8_t kData2[] = {0, 2, 1}; + static const uint8_t kData3[] = {0, 0, 2, 1}; + CBS data, prefixed; + + CBS_init(&data, kData1, sizeof(kData1)); + CHECK(!CBS_get_u8_length_prefixed(&data, &prefixed)); + + CBS_init(&data, kData2, sizeof(kData2)); + CHECK(!CBS_get_u16_length_prefixed(&data, &prefixed)); + + CBS_init(&data, kData3, sizeof(kData3)); + CHECK(!CBS_get_u24_length_prefixed(&data, &prefixed)); + + return 1; +} + +static int +test_peek_u(void) +{ + static const uint8_t kData[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, + }; + uint8_t u8; + uint16_t u16; + uint32_t u32; + CBS data; + + CBS_init(&data, kData, sizeof(kData)); + + CHECK(CBS_peek_u8(&data, &u8)); + CHECK(u8 == 1); + CHECK(CBS_peek_u16(&data, &u16)); + CHECK(u16 == 0x102); + CHECK(CBS_peek_u24(&data, &u32)); + CHECK(u32 == 0x10203); + CHECK(CBS_peek_u32(&data, &u32)); + CHECK(u32 == 0x1020304); + CHECK(CBS_get_u32(&data, &u32)); + CHECK(u32 == 0x1020304); + CHECK(CBS_peek_last_u8(&data, &u8)); + CHECK(u8 == 9); + CHECK(CBS_peek_u32(&data, &u32)); + CHECK(u32 == 0x5060708); + CHECK(CBS_get_u32(&data, &u32)); + CHECK(u32 == 0x5060708); + CHECK(CBS_get_u8(&data, &u8)); + CHECK(u8 == 9); + CHECK(!CBS_get_u8(&data, &u8)); + + return 1; +} + +static int +test_get_asn1(void) +{ + static const uint8_t kData1[] = {0x30, 2, 1, 2}; + static const uint8_t kData2[] = {0x30, 3, 1, 2}; + static const uint8_t kData3[] = {0x30, 0x80}; + static const uint8_t kData4[] = {0x30, 0x81, 1, 1}; + static const uint8_t kData5[4 + 0x80] = {0x30, 0x82, 0, 0x80}; + static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1}; + static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1}; + static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1}; + static const uint8_t kData9[] = {0xa1, 3, 0x2, 1, 0xff}; + + CBS data, contents; + int present; + uint64_t value; + + CBS_init(&data, kData1, sizeof(kData1)); + + CHECK(!CBS_peek_asn1_tag(&data, 0x1)); + CHECK(CBS_peek_asn1_tag(&data, 0x30)); + + CHECK(CBS_get_asn1(&data, &contents, 0x30)); + CHECK(CBS_len(&contents) == 2); + CHECK(memcmp(CBS_data(&contents), "\x01\x02", 2) == 0); + + CBS_init(&data, kData2, sizeof(kData2)); + /* data is truncated */ + CHECK(!CBS_get_asn1(&data, &contents, 0x30)); + + CBS_init(&data, kData3, sizeof(kData3)); + /* zero byte length of length */ + CHECK(!CBS_get_asn1(&data, &contents, 0x30)); + + CBS_init(&data, kData4, sizeof(kData4)); + /* long form mistakenly used. */ + CHECK(!CBS_get_asn1(&data, &contents, 0x30)); + + CBS_init(&data, kData5, sizeof(kData5)); + /* length takes too many bytes. */ + CHECK(!CBS_get_asn1(&data, &contents, 0x30)); + + CBS_init(&data, kData1, sizeof(kData1)); + /* wrong tag. */ + CHECK(!CBS_get_asn1(&data, &contents, 0x31)); + + CBS_init(&data, NULL, 0); + /* peek at empty data. */ + CHECK(!CBS_peek_asn1_tag(&data, 0x30)); + + CBS_init(&data, NULL, 0); + /* optional elements at empty data. */ + CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa0)); + CHECK(!present); + CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present, + 0xa0)); + CHECK(!present); + CHECK(CBS_len(&contents) == 0); + CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0)); + CHECK(CBS_len(&contents) == 0); + CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42)); + CHECK(value == 42); + + CBS_init(&data, kData6, sizeof(kData6)); + /* optional element. */ + CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa0)); + CHECK(!present); + CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa1)); + CHECK(present); + CHECK(CBS_len(&contents) == 3); + CHECK(memcmp(CBS_data(&contents), "\x04\x01\x01", 3) == 0); + + CBS_init(&data, kData6, sizeof(kData6)); + /* optional octet string. */ + CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present, + 0xa0)); + CHECK(!present); + CHECK(CBS_len(&contents) == 0); + CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present, + 0xa1)); + CHECK(present); + CHECK(CBS_len(&contents) == 1); + CHECK(CBS_data(&contents)[0] == 1); + + CBS_init(&data, kData7, sizeof(kData7)); + /* invalid optional octet string. */ + CHECK(!CBS_get_optional_asn1_octet_string(&data, &contents, &present, + 0xa1)); + + CBS_init(&data, kData8, sizeof(kData8)); + /* optional octet string. */ + CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42)); + CHECK(value == 42); + CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)); + CHECK(value == 1); + + CBS_init(&data, kData9, sizeof(kData9)); + /* invalid optional integer. */ + CHECK(!CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)); + + return 1; +} + +static int +test_get_optional_asn1_bool(void) +{ + CBS data; + int val; + + static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff}; + static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00}; + static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01}; + + CBS_init(&data, NULL, 0); + val = 2; + CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0)); + CHECK(val == 0); + + CBS_init(&data, kTrue, sizeof(kTrue)); + val = 2; + CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0)); + CHECK(val == 1); + + CBS_init(&data, kFalse, sizeof(kFalse)); + val = 2; + CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)); + CHECK(val == 0); + + CBS_init(&data, kInvalid, sizeof(kInvalid)); + CHECK(!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)); + + return 1; +} + +static int +test_cbb_basic(void) +{ + static const uint8_t kExpected[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + }; + uint8_t *buf = NULL; + size_t buf_len; + int ret = 0; + CBB cbb; + + CHECK(CBB_init(&cbb, 100)); + + CBB_cleanup(&cbb); + + CHECK(CBB_init(&cbb, 0)); + CHECK_GOTO(CBB_add_u8(&cbb, 1)); + CHECK_GOTO(CBB_add_u16(&cbb, 0x203)); + CHECK_GOTO(CBB_add_u24(&cbb, 0x40506)); + CHECK_GOTO(CBB_add_u32(&cbb, 0x708090a)); + CHECK_GOTO(CBB_add_bytes(&cbb, (const uint8_t*) "\x0b\x0c", 2)); + CHECK_GOTO(CBB_add_u64(&cbb, 0xd0e0f1011121314LL)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + + ret = (buf_len == sizeof(kExpected) + && memcmp(buf, kExpected, buf_len) == 0); + + if (0) { +err: + CBB_cleanup(&cbb); + } + free(buf); + return ret; +} + +static int +test_cbb_add_space(void) +{ + static const uint8_t kExpected[] = {1, 2, 0, 0, 0, 0, 7, 8}; + uint8_t *buf = NULL; + size_t buf_len; + uint8_t *data; + int ret = 0; + CBB cbb; + + CHECK(CBB_init(&cbb, 100)); + + CHECK_GOTO(CBB_add_u16(&cbb, 0x102)); + CHECK_GOTO(CBB_add_space(&cbb, &data, 4)); + CHECK_GOTO(CBB_add_u16(&cbb, 0x708)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + + ret |= (buf_len == sizeof(kExpected) + && memcmp(buf, kExpected, buf_len) == 0); + + memset(buf, 0xa5, buf_len); + CHECK(CBB_init_fixed(&cbb, buf, buf_len)); + + CHECK_GOTO(CBB_add_u16(&cbb, 0x102)); + CHECK_GOTO(CBB_add_space(&cbb, &data, 4)); + CHECK_GOTO(CBB_add_u16(&cbb, 0x708)); + CHECK_GOTO(CBB_finish(&cbb, NULL, NULL)); + + ret |= (buf_len == sizeof(kExpected) + && memcmp(buf, kExpected, buf_len) == 0); + + if (0) { +err: + CBB_cleanup(&cbb); + } + free(buf); + return ret; +} + +static int +test_cbb_fixed(void) +{ + CBB cbb; + uint8_t buf[1]; + uint8_t *out_buf = NULL; + size_t out_size; + int ret = 0; + + CHECK(CBB_init_fixed(&cbb, NULL, 0)); + CHECK_GOTO(!CBB_add_u8(&cbb, 1)); + CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); + CHECK(out_buf == NULL && out_size == 0); + + CHECK(CBB_init_fixed(&cbb, buf, 1)); + CHECK_GOTO(CBB_add_u8(&cbb, 1)); + CHECK_GOTO(!CBB_add_u8(&cbb, 2)); + CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); + + ret = (out_buf == buf && out_size == 1 && buf[0] == 1); + + if (0) { +err: + CBB_cleanup(&cbb); + } + + return ret; +} + +static int +test_cbb_finish_child(void) +{ + CBB cbb, child; + uint8_t *out_buf = NULL; + size_t out_size; + int ret = 0; + + CHECK(CBB_init(&cbb, 16)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); + CHECK_GOTO(!CBB_finish(&child, &out_buf, &out_size)); + CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); + + ret = (out_size == 1 && out_buf[0] == 0); + +err: + free(out_buf); + return ret; +} + +static int +test_cbb_prefixed(void) +{ + static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3, + 4, 5, 6, 5, 4, 1, 0, 1, 2}; + CBB cbb, contents, inner_contents, inner_inner_contents; + uint8_t *buf = NULL; + size_t buf_len; + int ret = 0; + + CHECK(CBB_init(&cbb, 0)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u8(&contents, 1)); + CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u16(&contents, 0x203)); + CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u24(&contents, 0x40506)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents)); + CHECK_GOTO(CBB_add_u8(&inner_contents, 1)); + CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents, + &inner_inner_contents)); + CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 2)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + + ret = (buf_len == sizeof(kExpected) + && memcmp(buf, kExpected, buf_len) == 0); + + if (0) { +err: + CBB_cleanup(&cbb); + } + free(buf); + return ret; +} + +static int +test_cbb_discard_child(void) +{ + static const uint8_t kExpected[] = { + 0xaa, + 0, + 1, 0xbb, + 0, 2, 0xcc, 0xcc, + 0, 0, 3, 0xdd, 0xdd, 0xdd, + 1, 0xff, + }; + CBB cbb, contents, inner_contents, inner_inner_contents; + uint8_t *buf = NULL; + size_t buf_len; + int ret = 0; + + CHECK(CBB_init(&cbb, 0)); + CHECK_GOTO(CBB_add_u8(&cbb, 0xaa)); + + // Discarding |cbb|'s children preserves the byte written. + CBB_discard_child(&cbb); + + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u8(&contents, 0xbb)); + CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u16(&contents, 0xcccc)); + CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u24(&contents, 0xdddddd)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); + CHECK_GOTO(CBB_add_u8(&contents, 0xff)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents)); + CHECK_GOTO(CBB_add_u8(&inner_contents, 0x42)); + CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents, + &inner_inner_contents)); + CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 0x99)); + + // Discard everything from |inner_contents| down. + CBB_discard_child(&contents); + + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + + ret = (buf_len == sizeof(kExpected) + && memcmp(buf, kExpected, buf_len) == 0); + + if (0) { +err: + CBB_cleanup(&cbb); + } + free(buf); + return ret; +} + +static int +test_cbb_misuse(void) +{ + CBB cbb, child, contents; + uint8_t *buf = NULL; + size_t buf_len; + int ret = 0; + + CHECK(CBB_init(&cbb, 0)); + CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); + CHECK_GOTO(CBB_add_u8(&child, 1)); + CHECK_GOTO(CBB_add_u8(&cbb, 2)); + + /* + * Since we wrote to |cbb|, |child| is now invalid and attempts to write + * to it should fail. + */ + CHECK_GOTO(!CBB_add_u8(&child, 1)); + CHECK_GOTO(!CBB_add_u16(&child, 1)); + CHECK_GOTO(!CBB_add_u24(&child, 1)); + CHECK_GOTO(!CBB_add_u8_length_prefixed(&child, &contents)); + CHECK_GOTO(!CBB_add_u16_length_prefixed(&child, &contents)); + CHECK_GOTO(!CBB_add_asn1(&child, &contents, 1)); + CHECK_GOTO(!CBB_add_bytes(&child, (const uint8_t*) "a", 1)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + + ret = (buf_len == 3 && memcmp(buf, "\x01\x01\x02", 3) == 0); + + if (0) { +err: + CBB_cleanup(&cbb); + } + free(buf); + return ret; +} + +static int +test_cbb_asn1(void) +{ + static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3}; + uint8_t *buf = NULL, *test_data = NULL; + size_t buf_len; + CBB cbb, contents, inner_contents; + int ret = 0; + int alloc = 0; + + CHECK_GOTO(CBB_init(&cbb, 0)); + alloc = 1; + CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); + CHECK_GOTO(CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", + 3)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + alloc = 0; + + CHECK_GOTO(buf_len == sizeof(kExpected)); + CHECK_GOTO(memcmp(buf, kExpected, buf_len) == 0); + + free(buf); + buf = NULL; + + CHECK_GOTO(((test_data = malloc(100000)) != NULL)); + memset(test_data, 0x42, 100000); + + CHECK_GOTO(CBB_init(&cbb, 0)); + alloc = 1; + CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); + CHECK_GOTO(CBB_add_bytes(&contents, test_data, 130)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + alloc = 0; + + CHECK_GOTO(buf_len == 3 + 130); + CHECK_GOTO(memcmp(buf, "\x30\x81\x82", 3) == 0); + CHECK_GOTO(memcmp(buf + 3, test_data, 130) == 0); + + free(buf); + buf = NULL; + + CHECK_GOTO(CBB_init(&cbb, 0)); + alloc = 1; + CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); + CHECK_GOTO(CBB_add_bytes(&contents, test_data, 1000)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + alloc = 0; + + CHECK_GOTO(buf_len == 4 + 1000); + CHECK_GOTO(memcmp(buf, "\x30\x82\x03\xe8", 4) == 0); + CHECK_GOTO(!memcmp(buf + 4, test_data, 1000)); + + free(buf); + buf = NULL; + + CHECK_GOTO(CBB_init(&cbb, 0)); + alloc = 1; + CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); + CHECK_GOTO(CBB_add_asn1(&contents, &inner_contents, 0x30)); + CHECK_GOTO(CBB_add_bytes(&inner_contents, test_data, 100000)); + CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); + alloc = 0; + + CHECK_GOTO(buf_len == 5 + 5 + 100000); + CHECK_GOTO(memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) + == 0); + CHECK_GOTO(!memcmp(buf + 10, test_data, 100000)); + + ret = 1; + + if (0) { +err: + if (alloc) + CBB_cleanup(&cbb); + } + free(buf); + free(test_data); + return ret; +} + +static int +do_indefinite_convert(const char *name, const uint8_t *definite_expected, + size_t definite_len, const uint8_t *indefinite, size_t indefinite_len) +{ + CBS in; + uint8_t *out = NULL; + size_t out_len; + int ret = 0; + + CBS_init(&in, indefinite, indefinite_len); + + CHECK_GOTO(CBS_asn1_indefinite_to_definite(&in, &out, &out_len)); + + if (out == NULL) { + + if (indefinite_len != definite_len || + memcmp(definite_expected, indefinite, indefinite_len) != 0) { + PRINT_ERROR; + goto err; + } + + return 1; + } + + if (out_len != definite_len || + memcmp(out, definite_expected, definite_len) != 0) { + PRINT_ERROR; + goto err; + } + + ret = 1; +err: + free(out); + return ret; +} + +static int +test_indefinite_convert(void) +{ + static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; + + /* kIndefBER contains a SEQUENCE with an indefinite length. */ + static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, + 0x00}; + static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; + + /* + * kOctetStringBER contains an indefinite length OCTETSTRING with two + * parts. These parts need to be concatenated in DER form. + */ + static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, + 1, 0x04, 0x02, 2, 3, 0x00, 0x00}; + static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; + + /* + * kNSSBER is part of a PKCS#12 message generated by NSS that uses + * indefinite length elements extensively. + */ + static const uint8_t kNSSBER[] = { + 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, + 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, + 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, + 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, + 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44, + 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b, + 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, + }; + + static const uint8_t kNSSDER[] = { + 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, + 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, + 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, + 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, + 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, + 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, + }; + + CHECK(do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), + kSimpleBER, sizeof(kSimpleBER))); + CHECK(do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), + kIndefBER, sizeof(kIndefBER))); + CHECK(do_indefinite_convert("kOctetStringBER", kOctetStringDER, + sizeof(kOctetStringDER), kOctetStringBER, + sizeof(kOctetStringBER))); + CHECK(do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, + sizeof(kNSSBER))); + + return 1; +} + +typedef struct { + uint64_t value; + const char *encoding; + size_t encoding_len; +} ASN1_UINT64_TEST; + +static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { + {0, "\x02\x01\x00", 3}, + {1, "\x02\x01\x01", 3}, + {127, "\x02\x01\x7f", 3}, + {128, "\x02\x02\x00\x80", 4}, + {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, + {OPENSSL_U64(0x0102030405060708), + "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, + {OPENSSL_U64(0xffffffffffffffff), + "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, +}; + +typedef struct { + const char *encoding; + size_t encoding_len; +} ASN1_INVALID_UINT64_TEST; + +static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { + /* Bad tag. */ + {"\x03\x01\x00", 3}, + /* Empty contents. */ + {"\x02\x00", 2}, + /* Negative number. */ + {"\x02\x01\x80", 3}, + /* Overflow. */ + {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, + /* Leading zeros. */ + {"\x02\x02\x00\x01", 4}, +}; + +static int +test_asn1_uint64(void) +{ + CBB cbb; + uint8_t *out = NULL; + size_t i; + int ret = 0; + int alloc = 0; + + for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); + i++) { + const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; + CBS cbs; + uint64_t value; + size_t len; + + CBS_init(&cbs, (const uint8_t *)test->encoding, + test->encoding_len); + + CHECK(CBS_get_asn1_uint64(&cbs, &value)); + CHECK(CBS_len(&cbs) == 0); + CHECK(value == test->value); + + CHECK(CBB_init(&cbb, 0)); + alloc = 1; + CHECK_GOTO(CBB_add_asn1_uint64(&cbb, test->value)); + CHECK_GOTO(CBB_finish(&cbb, &out, &len)); + alloc = 0; + + CHECK_GOTO(len == test->encoding_len); + CHECK_GOTO(memcmp(out, test->encoding, len) == 0); + free(out); + out = NULL; + } + + for (i = 0; i < sizeof(kAsn1InvalidUint64Tests) + / sizeof(kAsn1InvalidUint64Tests[0]); i++) { + const ASN1_INVALID_UINT64_TEST *test = + &kAsn1InvalidUint64Tests[i]; + CBS cbs; + uint64_t value; + + CBS_init(&cbs, (const uint8_t *)test->encoding, + test->encoding_len); + CHECK(!CBS_get_asn1_uint64(&cbs, &value)); + } + + ret = 1; + + if (0) { +err: + if (alloc) + CBB_cleanup(&cbb); + } + free(out); + + return ret; +} + +static int +test_offset(void) +{ + uint8_t v; + static const uint8_t input[] = {1, 2, 3, 4, 5}; + CBS data; + + CBS_init(&data, input, sizeof(input)); + CHECK(sizeof(input) == 5); + CHECK(CBS_len(&data) == 5); + CHECK(CBS_offset(&data) == 0); + CHECK(CBS_get_u8(&data, &v)); + CHECK(v == 1); + CHECK(CBS_len(&data) == 4); + CHECK(CBS_offset(&data) == 1); + CHECK(CBS_skip(&data, 2)); + CHECK(CBS_len(&data) == 2); + CHECK(CBS_offset(&data) == 3); + CHECK(CBS_get_u8(&data, &v)); + CHECK(v == 4); + CHECK(CBS_get_u8(&data, &v)); + CHECK(v == 5); + CHECK(CBS_len(&data) == 0); + CHECK(CBS_offset(&data) == 5); + CHECK(!CBS_skip(&data, 1)); + + CBS_init(&data, input, sizeof(input)); + CHECK(CBS_skip(&data, 2)); + CHECK(CBS_len(&data) == 3); + CHECK(CBS_offset(&data) == 2); + CHECK(CBS_skip(&data, 3)); + CHECK(CBS_len(&data) == 0); + CHECK(CBS_offset(&data) == 5); + CHECK(!CBS_get_u8(&data, &v)); + + return 1; +} + +static int +test_write_bytes(void) +{ + int ret = 0; + uint8_t v; + size_t len; + static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; + CBS data; + uint8_t *tmp = NULL; + + CHECK_GOTO((tmp = malloc(sizeof(input))) != NULL); + memset(tmp, 100, sizeof(input)); + + CBS_init(&data, input, sizeof(input)); + CHECK_GOTO(CBS_len(&data) == 6); + CHECK_GOTO(CBS_offset(&data) == 0); + CHECK_GOTO(CBS_get_u8(&data, &v)); + CHECK_GOTO(v == 102 /* f */); + CHECK_GOTO(CBS_skip(&data, 1)); + CHECK_GOTO(!CBS_skip(&data, 15)); + CHECK_GOTO(CBS_write_bytes(&data, tmp, sizeof(input), &len)); + CHECK_GOTO(len == 4); + CHECK_GOTO(memcmp(input + 2, tmp, len) == 0); + CHECK_GOTO(tmp[4] == 100 && tmp[5] == 100); + + ret = 1; + +err: + free(tmp); + return ret; +} + +static int +test_cbs_dup(void) +{ + CBS data, check; + static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; + + CBS_init(&data, input, sizeof(input)); + CHECK(CBS_len(&data) == 6); + CBS_dup(&data, &check); + CHECK(CBS_len(&check) == 6); + CHECK(CBS_data(&data) == CBS_data(&check)); + CHECK(CBS_skip(&data, 1)); + CHECK(CBS_len(&data) == 5); + CHECK(CBS_len(&check) == 6); + CHECK(CBS_data(&data) == CBS_data(&check) + 1); + CHECK(CBS_skip(&check, 1)); + CHECK(CBS_len(&data) == 5); + CHECK(CBS_len(&check) == 5); + CHECK(CBS_data(&data) == CBS_data(&check)); + CHECK(CBS_offset(&data) == 1); + CHECK(CBS_offset(&check) == 1); + + CBS_init(&data, input, sizeof(input)); + CHECK(CBS_skip(&data, 5)); + CBS_dup(&data, &check); + CHECK(CBS_len(&data) == 1); + CHECK(CBS_len(&check) == 1); + CHECK(CBS_data(&data) == input + 5); + CHECK(CBS_data(&data) == CBS_data(&check)); + CHECK(CBS_offset(&data) == 5); + CHECK(CBS_offset(&check) == 5); + + return 1; +} + +int +main(void) +{ + int failed = 0; + + failed |= !test_skip(); + failed |= !test_get_u(); + failed |= !test_get_prefixed(); + failed |= !test_get_prefixed_bad(); + failed |= !test_peek_u(); + failed |= !test_get_asn1(); + failed |= !test_cbb_basic(); + failed |= !test_cbb_add_space(); + failed |= !test_cbb_fixed(); + failed |= !test_cbb_finish_child(); + failed |= !test_cbb_discard_child(); + failed |= !test_cbb_misuse(); + failed |= !test_cbb_prefixed(); + failed |= !test_cbb_asn1(); + failed |= !test_indefinite_convert(); + failed |= !test_asn1_uint64(); + failed |= !test_get_optional_asn1_bool(); + failed |= !test_offset(); + failed |= !test_write_bytes(); + failed |= !test_cbs_dup(); + + if (!failed) + printf("PASS\n"); + return failed; +} diff --git a/Libraries/libressl/tests/ca-int-ecdsa.crl b/Libraries/libressl/tests/ca-int-ecdsa.crl new file mode 100644 index 000000000..b904de3ef --- /dev/null +++ b/Libraries/libressl/tests/ca-int-ecdsa.crl @@ -0,0 +1,8 @@ +-----BEGIN X509 CRL----- +MIHuMIGUMAoGCCqGSM49BAMCMC4xLDAqBgNVBAMMI0xpYnJlU1NMIFRlc3QgSW50 +ZXJtZWRpYXRlIENBIEVDRFNBFw0yMTEyMjcxNDQwNDBaFw0yMjAxMjYxNDQwNDBa +MDgwGgIJAOVssaaTYoH5Fw0yMTEyMjcxNDQwNDBaMBoCCQDlbLGmk2KB+xcNMjEx +MjI3MTQ0MDQwWjAKBggqhkjOPQQDAgNJADBGAiEA9FWkenCgh+6Rz0/nuS7DaiUR +J5imCs0Wx6TiG3YUL3oCIQDfTT+54eKAEFXeYN2oToZtHbTHh5YUici5GA/PDmOG +Ig== +-----END X509 CRL----- diff --git a/Libraries/libressl/tests/ca-int-ecdsa.pem b/Libraries/libressl/tests/ca-int-ecdsa.pem new file mode 100644 index 000000000..fa1db8638 --- /dev/null +++ b/Libraries/libressl/tests/ca-int-ecdsa.pem @@ -0,0 +1,13 @@ +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/ca-int-rsa.crl b/Libraries/libressl/tests/ca-int-rsa.crl new file mode 100644 index 000000000..481886ae5 --- /dev/null +++ b/Libraries/libressl/tests/ca-int-rsa.crl @@ -0,0 +1,11 @@ +-----BEGIN X509 CRL----- +MIIBrDCBlTANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0 +IEludGVybWVkaWF0ZSBDQSBSU0EXDTIxMTIyNzE0NDAzOFoXDTIyMDEyNjE0NDAz +OFowODAaAgkA5WyxppNigfQXDTIxMTIyNzE0NDAzN1owGgIJAOVssaaTYoH2Fw0y +MTEyMjcxNDQwMzhaMA0GCSqGSIb3DQEBCwUAA4IBAQCGMtlhTlaOK7fK2OHXgoAf +lDr1FQfqfNo5ZNE2+VqOvjYfgwdOgfxIsIuUoNp9/NhzO3e4KNe6P/33axwIsy7o +RofbGYFSlHIYPEf1LyvH8z5mT2L2LAQAi+p+QMFizH6KNc74Oftygyi1bcJlN3CJ +dP9LyvACdJSna7dEh7Snu2hy8tEDAO/RxUrryOZca0+5I4aaD8QCdFwdicDQ8U1s +gTJ5w1gxkEWKv/J/AjCjRAVoAjE2/sUC1PPOJnZy7b0sS2Fv7zV7UAWSzO0KEYv+ +vav3UekGIgw0A5PDdWmUqCxE7aK71iy4EmlzMyVNULVcF1qX6qBQT5OpXr0Eo6WR +-----END X509 CRL----- diff --git a/Libraries/libressl/tests/ca-int-rsa.pem b/Libraries/libressl/tests/ca-int-rsa.pem new file mode 100644 index 000000000..b457ad6f9 --- /dev/null +++ b/Libraries/libressl/tests/ca-int-rsa.pem @@ -0,0 +1,22 @@ +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/ca-root-ecdsa.pem b/Libraries/libressl/tests/ca-root-ecdsa.pem new file mode 100644 index 000000000..c7862da58 --- /dev/null +++ b/Libraries/libressl/tests/ca-root-ecdsa.pem @@ -0,0 +1,13 @@ +subject= CN = LibreSSL Test Root CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIJALqTupYRbYuwMAoGCCqGSM49BAMCMCYxJDAiBgNVBAMM +G0xpYnJlU1NMIFRlc3QgUm9vdCBDQSBFQ0RTQTAeFw0yMTEyMjcxNDQwNDBaFw0z +MTEyMjUxNDQwNDBaMCYxJDAiBgNVBAMMG0xpYnJlU1NMIFRlc3QgUm9vdCBDQSBF +Q0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIxQjA3Gp+4irgwEumPY1/EG +lVy6/olnAc+4elWkj0SqqdjfWanQqO8wHFY0qICKq8lHKhcyw2v9oyOsNVXZj8Kj +YzBhMB0GA1UdDgQWBBS2+Rq3hR1xQSKm3ov88GAQVgfoDDAfBgNVHSMEGDAWgBS2 ++Rq3hR1xQSKm3ov88GAQVgfoDDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAKBggqhkjOPQQDAgNIADBFAiAqAN8RFQOAIXeJcxCHUCN1n3sUBuYF/XkS +VnTsAEU/kwIhANNk/xjGq9O2YeLEFT1InoltVlwM5P8oa7krPnPbFnwY +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/ca-root-rsa.pem b/Libraries/libressl/tests/ca-root-rsa.pem new file mode 100644 index 000000000..daf3407a9 --- /dev/null +++ b/Libraries/libressl/tests/ca-root-rsa.pem @@ -0,0 +1,22 @@ +subject= CN = LibreSSL Test Root CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIJAIuM+uV8F+LtMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAkMSIwIAYDVQQDDBlMaWJyZVNTTCBUZXN0IFJvb3QgQ0Eg +UlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnvrj8h5JmJ+7V33R +wloqhM0nLvmidkmk1sqJaOi0GNXoMLnaut90+2TnRiFDbsblzAjTijQC6PEfaJTB +AEFBgNSQKdhVruYTL5HHhw/XHTjxqftizvJj1FsZh2n6gkTG/QOgbaDMCx+yFF88 +wro7Br32TZF+BuDuyzVcSPJUajYT+C9bWSq9jX8Fhvl5M3IOG7olg3gAMmU+E8SY +TaKhoJ7KGLHDEQP9NJknJusV8T72lY/TzacVDDOxEUxpuYtJ1Kayytflhs1065Ua +PkiIReoFnhK/tRAgyxz3bc6HDDmTz4FpyGPcAsSRtEbn1n1417hzH4Neq5eioVmx +hX1HTwIDAQABo2MwYTAdBgNVHQ4EFgQUPkv8e/SsNCqlESgB8ojoXY//FdEwHwYD +VR0jBBgwFoAUPkv8e/SsNCqlESgB8ojoXY//FdEwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAEYi6O+l7SS14myiZydm +eP0hS8+ABWz/xqzu81W5Uxo7XD3sNfz5hkhA3S2FrBg5xpDScAzsM9Og6VRuQA7/ +StWLc2gLvLI6cZNdOCOH/O4K6IYRGR0kXG7WA4MpBiDrPXZKXI3WcUNyTHM36Un4 +ZATRkO+xMLKFpnxHCkY5U9kp8xX5boNxtQsGkWfuG+fm7GVBaQapnvN+WRY4QXKQ +jF10CFUcIUNGG81XTEhQwpcP0b0ruZK6JBah4VG7lUHbJ6/WoYiGYXCToK09ohIX +PuWiVTiT9LH90U58No3NfinQPbE55mJju+YNNqLU4Wk3ub5rYpp0WFmo6T9kXL/z +fO8= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/ca.pem b/Libraries/libressl/tests/ca.pem new file mode 100644 index 000000000..07f9b3fdd --- /dev/null +++ b/Libraries/libressl/tests/ca.pem @@ -0,0 +1,45 @@ +-----BEGIN CERTIFICATE----- +MIIDtjCCAp6gAwIBAgIJAJz/hGfwYXLrMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT +VElORyBQVVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBD +QTAeFw0xNDA1MjQxNDQ1MTFaFw0yNDA1MjExNDQ1MTFaMGgxCzAJBgNVBAYTAlVL +MRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVTVElORyBQ +VVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBDQTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMaarigKGOra5Mc/LrhOkcmHzDs +vkYL7dfaaht8fLBKRTYwzSBvO9x54koTWjq7HkbaxkYAg3HnDTkNCyzkGKNdM89H +q/PtGIFFlceQIOat3Kjd05Iw3PtLEWTDjT6FMA9Mkjk/XbpmycqRIwNKtgICoFsG +juIpc4P31kxK7i3ri+JnlyvVmRZjJxrheJB0qHGXilrOVDPOliDn//jXbcyzXemu +R8KgAeQM4IIs9jYHJOgHrTItIpwa9wNTEp9KCGkO6xr20NkKyDp6XRyd+hmnUB7r +77WTptvKPFFTjTDFqEtcif9U2kVkCfn2mSRO8noCbVH++fuR8LMWlD99gt8CAwEA +AaNjMGEwHQYDVR0OBBYEFIwZD9dCMXcFBuHTsZ/rOft4cTpFMB8GA1UdIwQYMBaA +FIwZD9dCMXcFBuHTsZ/rOft4cTpFMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCPfqm4KbYtXEB8aP1RdUH2BkPSjyau +WQLMGfKNF/zkUQue0REgdJ4wVR06NTTlOCsfHC6b68vgz2QFC1mM8ZANgDiyr4M1 +6gjvP0eZQVxokJ3EMzjDMFRHIiFrZZAFr7aGq8dxoruuehovqyehuJRakAe0oNUb +4ZTKrGuTKh9Mwti9721XNFByjeTFL2dlH6ulz7qyfI+lrTi+pNsUchuVYE8a1TP3 +OEiG6whsyPU1YoTlemC1mvW0ixtj8Tcem0KyotCUyOmJlwyWj0bA43sCI6z/OVqJ +tVvwgfqrOeVNk9nN2JslCsttnwstwqUfDoEXFoScej2CT0QezFGPTN21 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDvjCCAqagAwIBAgIJAPrXr2k7uM/OMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT +VElORyBQVVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBD +QTAeFw0xNDA1MjQxNDQ1MTFaFw0yNDA1MDExNDQ1MTFaMHAxCzAJBgNVBAYTAlVL +MRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVTVElORyBQ +VVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJtZWRpYXRl +IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsErw75CmLYD6pkrG +W/YhAl/K8L5wJYxDjqu2FghxjD8K308W3EHq4uBxEwR1OHXaM1+6ZZw7/r2I37VL +IdurBEAIEUdbzx0so74FPawgz5EW2CTqoJnK8F71/vo5Kj1VPwW46CxwxUR3cfvJ +GNXND2ip0TcyTSPLROXOyQakcVfIGJmdSa1wHKi+c2gMA4emADudZUOYLrg80gr2 +ldePm07ynbVsKKzCcStw8MdmoW9Qt3fLnPJn2TFUUBNWj+4kvL+88edWCVQXKNds +ysD/CDrH4W/hjyPDStVsM6XpiNU0+L2ZY6fcj3OP8d0goOx45xotMn9m8hNkCGsr +VXx9IwIDAQABo2MwYTAdBgNVHQ4EFgQUNsNsiOeV/rC97M4+PYarIYGH2towHwYD +VR0jBBgwFoAUjBkP10IxdwUG4dOxn+s5+3hxOkUwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAAIwwR8jyFN6qYGIRAKi +ahyeHd26hNPC4RiCvjz6dytuvDUqfMTUZcjBy6Ez1Wsfs1/PC8u3IDpOTwZSz72K +ACQzPpmXREWkO5nx8I+W+94yJsbklhsTxDlZj3X2oJCQ7qO4hdIpYESWfMchYra9 +5e55SMBXeGDp+uRILt+6UfOXCGaXaoYqyrzQROJAiGy1x96A/5sU6ZU3KdKN1JLM +XTZ268ihubCMRVScHnpYUjRDoGrhnQM7007ybVfRUGNXDs+ENqjGfyxc5ScR+Un4 +UQtOd4zD2g9wrdXvlDiqxci6W7IOEPVP6qHG2GIh+T2zpO3GOAuZCe5cjLiCDATs +hNw= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/casttest.c b/Libraries/libressl/tests/casttest.c new file mode 100644 index 000000000..df72cafa4 --- /dev/null +++ b/Libraries/libressl/tests/casttest.c @@ -0,0 +1,197 @@ +/* $OpenBSD: casttest.c,v 1.7 2023/08/20 22:35:52 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +static const unsigned char k[16] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A, +}; + +static const unsigned char in[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, +}; + +static int k_len[3] = {16, 10, 5}; +static const unsigned char c[3][8] = { + {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}, + {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, + {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}, +}; +static unsigned char out[80]; + +static const unsigned char in_a[16] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A, +}; +static const unsigned char in_b[16] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A, +}; + +static const unsigned char c_a[16] = { + 0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6, + 0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92, +}; +static const unsigned char c_b[16] = { + 0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71, + 0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E, +}; + +int +main(int argc, char *argv[]) +{ + long l; + CAST_KEY key_b; + int i, z, err = 0; + CAST_KEY key; + + for (z = 0; z < 3; z++) { + CAST_set_key(&key, k_len[z], k); + + CAST_ecb_encrypt(in, out, &key, CAST_ENCRYPT); + if (memcmp(out, &(c[z][0]), 8) != 0) { + printf("ecb cast error encrypting for keysize %d\n", + k_len[z]*8); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", c[z][i]); + err = 20; + printf("\n"); + } + + CAST_ecb_encrypt(out, out, &key, CAST_DECRYPT); + if (memcmp(out, in, 8) != 0) { + printf("ecb cast error decrypting for keysize %d\n", + k_len[z]*8); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", in[i]); + printf("\n"); + err = 3; + } + } + if (err == 0) + printf("ecb cast5 ok\n"); + + { + unsigned char out_a[16], out_b[16]; + static char *hex = "0123456789ABCDEF"; + + printf("This test will take some time...."); + fflush(stdout); + memcpy(out_a, in_a, sizeof(in_a)); + memcpy(out_b, in_b, sizeof(in_b)); + i = 1; + + for (l = 0; l < 1000000L; l++) { + CAST_set_key(&key_b, 16, out_b); + CAST_ecb_encrypt(&(out_a[0]), &(out_a[0]), &key_b, + CAST_ENCRYPT); + CAST_ecb_encrypt(&(out_a[8]), &(out_a[8]), &key_b, + CAST_ENCRYPT); + CAST_set_key(&key, 16, out_a); + CAST_ecb_encrypt(&(out_b[0]), &(out_b[0]), &key, + CAST_ENCRYPT); + CAST_ecb_encrypt(&(out_b[8]), &(out_b[8]), &key, + CAST_ENCRYPT); + if ((l & 0xffff) == 0xffff) { + printf("%c", hex[i & 0x0f]); + fflush(stdout); + i++; + } + } + + if ((memcmp(out_a, c_a, sizeof(c_a)) != 0) || + (memcmp(out_b, c_b, sizeof(c_b)) != 0)) { + printf("\n"); + printf("Error\n"); + + printf("A out ="); + for (i = 0; i < 16; i++) + printf("%02X ", out_a[i]); + printf("\nactual="); + for (i = 0; i < 16; i++) + printf("%02X ", c_a[i]); + printf("\n"); + + printf("B out ="); + for (i = 0; i < 16; i++) + printf("%02X ", out_b[i]); + printf("\nactual="); + for (i = 0; i < 16; i++) + printf("%02X ", c_b[i]); + printf("\n"); + } else + printf(" ok\n"); + } + + exit(err); +} diff --git a/Libraries/libressl/tests/chacha20_poly1305_tests.txt b/Libraries/libressl/tests/chacha20_poly1305_tests.txt new file mode 100644 index 000000000..7656247d4 --- /dev/null +++ b/Libraries/libressl/tests/chacha20_poly1305_tests.txt @@ -0,0 +1,576 @@ +# Test vector from RFC 8439 Section 2.8.1. + +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." +AD: 50515253c0c1c2c3c4c5c6c7 +CT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116 +TAG: 1ae10b594f09e26a7e902ecbd0600691 + +# Test padding AD with 15 zeros in the tag calculation. +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: "123456789abcdef0" +AD: "1" +CT: ae49da6934cb77822c83ed9852e46c9e +TAG: dac9c841c168379dcf8f2bb8e22d6da2 + +# Test padding IN with 15 zeros in the tag calculation. +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: "1" +AD: "123456789abcdef0" +CT: ae +TAG: 3ed2f824f901a8994052f852127c196a + +# Test padding AD with 1 zero in the tag calculation. +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: "123456789abcdef0" +AD: "123456789abcdef" +CT: ae49da6934cb77822c83ed9852e46c9e +TAG: 2e9c9b1689adb5ec444002eb920efb66 + +# Test padding IN with 1 zero in the tag calculation. +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: "123456789abcdef" +AD: "123456789abcdef0" +CT: ae49da6934cb77822c83ed9852e46c +TAG: 05b2937f8bbc64fed21f0fb74cd7147c + +# Test maximal nonce value. +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: ffffffffffffffffffffffff +IN: "123456789abcdef0" +AD: "123456789abcdef0" +CT: e275aeb341e1fc9a70c4fd4496fc7cdb +TAG: 41acd0560ea6843d3e5d4e5babf6e946 + +KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6 +NONCE: 000000003de9c0da2bd7f91e +IN: "" +AD: "" +CT: "" +TAG: 5a6e21f4ba6dbee57380e79e79c30def + +KEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5 +NONCE: 000000001e8b4c510f5ca083 +IN: 8c8419bc27 +AD: 34ab88c265 +CT: 1a7c2f33f5 +TAG: 2a63876a887f4f080c9df418813fc1fd + +KEY: 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007 +NONCE: 00000000cd7cf67be39c794a +IN: 86d09974840bded2a5ca +AD: 87e229d4500845a079c0 +CT: e3e446f7ede9a19b62a4 +TAG: 356d9eda66d08016b853d87c08b5c1b3 + +KEY: 422a5355b56dcf2b436aa8152858106a88d9ba23cdfe087b5e74e817a52388b3 +NONCE: 000000001d12d6d91848f2ea +IN: 537a645387f22d6f6dbbea568d3feb +AD: bef267c99aec8af56bc238612bfea6 +CT: 281a366705c5a24b94e56146681e44 +TAG: 59143dab187449060a3ec2a1681613cc + +KEY: ec7b864a078c3d05d970b6ea3ba6d33d6bb73dfa64c622a4727a96ede876f685 +NONCE: 000000002bca0e59e39508d3 +IN: b76733895c871edd728a45ed1a21f15a9597d49d +AD: cc1243ea54272db602fb0853c8e7027c56338b6c +CT: 1fb9b2958fce47a5cada9d895fbb0c00d3569858 +TAG: 219b4252deb16a43b292165aabc5d5ce + +KEY: 2c4c0fdb611df2d4d5e7898c6af0022795364adb8749155e2c68776a090e7d5c +NONCE: 0000000013ce7382734c4a71 +IN: 0dc6ff21a346e1337dd0db81d8f7d9f6fd1864418b98aadcdb +AD: 0115edcb176ab8bfa947d1f7c3a86a845d310bf6706c59a8f9 +CT: dad65e4244a1a17ce59d88b00af4f7434bd7830ffdd4c5558f +TAG: 7ae32f186cf9ec59b41b764b34307d4f + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648a5919a + +KEY: a8b9766f404dea8cf7d7dfaf5822f53df9ccd092e332a57f007b301b507d5e14 +NONCE: 00000000c7f2f7a233104a2d +IN: 4d6faeaee39179a7c892faae3719656cc614c7e6ecd8fcb570a3b82c4dace969090338 +AD: c6d83b6a56408a356e68d0494d4eff150530b09551d008373d6dee2b8d6b5619d67fdb +CT: a15443f083316eef627a371f4c9ac654d0dd75255d8a303125e9f51af4233ff4ceb7fe +TAG: 63c2b4e0973096299488b0a66ffa54c1 + +KEY: 5e8d0e5f1467f7a750c55144d0c670f7d91075f386795b230c9bf1c04ba250bc +NONCE: 0000000088049f44ba61b88f +IN: 51a1eebcc348e0582196a0bce16ed1f8ac2e91c3e8a690e04a9f4b5cf63313d7ad08d1efbff85c89 +AD: 5d09bf0be90026f9fc51f73418d6d864b6d197ea030b3de072bd2c2f5cab5860a342abbd29dba9dc +CT: 35aa4bd4537aa611fd7578fc227df50ebcb00c692a1cf6f02e50ed9270bd93af3bc68f4c75b96638 +TAG: 4461139c4055333106cf7f7556fd4171 + +KEY: 21a9f07ec891d488805e9b92bb1b2286f3f0410c323b07fee1dc6f7379e22e48 +NONCE: 00000000066215be6567377a +IN: c1b0affaf2b8d7ef51cca9aacf7969f92f928c2e3cc7db2e15f47ee1f65023910d09f209d007b7436ee898133d +AD: dfdfdf4d3a68b47ad0d48828dc17b2585da9c81c3a8d71d826b5fa8020fee002397e91fc9658e9d61d728b93eb +CT: 8ff4ceb600e7d45696d02467f8e30df0d33864a040a41ffb9e4c2da09b92e88b6f6b850e9f7258d827b9aaf346 +TAG: b2ad07b86aca1b3ab34033c12d6a08cc + +KEY: 54c93db9aa0e00d10b45041c7a7e41ee9f90ab78ae4c1bba18d673c3b370abde +NONCE: 000000003f2d44e7b352360f +IN: 1241e7d6fbe5eef5d8af9c2fb8b516e0f1dd49aa4ebe5491205194fe5aea3704efaf30d392f44cc99e0925b84460d4873344 +AD: f1d1b08dd6fe96c46578c1d1ad38881840b10cb5eae41e5f05fe5287223fa72242aea48cb374a80be937b541f9381efa66bb +CT: 027b86865b80b4c4da823a7d3dbcf5845bf57d58ee334eb357e82369cc628979e2947830d9d4817efd3d0bc4779f0b388943 +TAG: 6de01091d749f189c4e25aa315b31495 + +KEY: 808e0e73e9bcd274d4c6f65df2fe957822a602f039d4752616ba29a28926ef4a +NONCE: 000000001b9cd73d2fc3cb8e +IN: 3436c7b5be2394af7e88320c82326a6db37887ff9de41961c7d654dd22dd1f7d40444d48f5c663b86ff41f3e15b5c8ca1337f97635858f +AD: d57cfbe5f2538044282e53b2f0bb4e86ea2233041fb36adb8338ded092148f8c2e894ef8766a7ec2dd02c6ac5dbab0c3703c5e9119e37c +CT: 9b950b3caf7d25eaf5fca6fa3fe12ed077d80dcd5579851233c766bb8bb613ec91d925a939bb52fb88d5eda803cfe2a8cda2e055b962fd +TAG: 0887ec7d5e1a4e532746ec247a30825a + +KEY: 4adfe1a26c5636536cd7cb72aa5bded0b1aa64487ad0e4078f311e8782768e97 +NONCE: 00000000d69e54badec11560 +IN: 19b3f9411ce875fcb684cbdc07938c4c1347e164f9640d37b22f975b4b9a373c4302ae0e7dfdeba1e0d00ced446e338f4c5bc01b4becef5115825276 +AD: bda1b0f6c2f4eb8121dcbd2eebd91a03ae1d6e0523b9b6f34b6f16ceca0d086654fb0552bfd5c8e1887730e1449ea02d7f647ae835bc2dab4bbc65b9 +CT: ea765a829d961e08bacaed801237ef4067df38ad3737b7c6de4db587a102a86fc4abbaabea0ee97c95ca7f571c7bab6f38cbae60cd6e6a4ce3c7a320 +TAG: a27f18846f5a4f7fcc724656c91cf4f3 + +KEY: eb3db86c14b7cc2e494345d0dfb4841bbd3aa1e2bc640cca0c6c405520685639 +NONCE: 0000000088b54b28d6da8c81 +IN: f75c0a357271430b1ecff07a307b6c29325c6e66935046704a19845e629f87a9e3b8aa6c1df55dd426a487d533bb333e46f0d3418464ac1bef059231f8e87e6284 +AD: 34b08bb0df821c573dcb56f5b8b4a9920465067f3b5bf3e3254ea1da1a7fc9847fd38bdfe6b30927945263a91fa288c7cf1bee0fddb0fadf5948c5d83eb4623575 +CT: 146ec84f5dc1c9fe9de3307a9182dbaa75965bf85f5e64563e68d039a5b659aa8863b89228edb93ff3d8c3323ab0d03300476aa4aca206d4626a6b269b2078912d +TAG: 854cbb42bade86a09597482c8604681a + +KEY: dd5b49b5953e04d926d664da3b65ebcffbbf06abbe93a3819dfc1abbecbaab13 +NONCE: 00000000c5c8009459b9e31a +IN: f21f6706a4dc33a361362c214defd56d353bcb29811e5819ab3c5c2c13950c7aa0000b9d1fe69bb46454514dcce88a4a5eda097c281b81e51d6a4dba47c80326ba6cea8e2bab +AD: fe6f4cbb00794adea59e9de8b03c7fdf482e46f6c47a35f96997669c735ed5e729a49416b42468777e6a8d7aa173c18b8177418ded600124a98cbb65489f9c24a04f1e7127ce +CT: 911ead61b2aa81d00c5eff53aeea3ab713709ed571765890d558fb59d3993b45f598a39e5eff4be844c4d4bd1ef9622e60412b21140007d54dcf31b2c0e3e98cf33a00fd27f0 +TAG: 2865d2a26f413cc92416340f9491e1be + +KEY: 3b319e40148a67dc0bb19271d9272b327bc5eee087173d3d134ad56c8c7dc020 +NONCE: 00000000ce5cf6fef84d0010 +IN: 27b5627b17a2de31ad00fc2ecb347da0a399bb75cc6eadd4d6ee02de8fbd6a2168d4763ba9368ba982e97a2db8126df0343cdad06d2bc7d7e12eec731d130f8b8745c1954bfd1d717b4ea2 +AD: a026b6638f2939ec9cc28d935fb7113157f3b5b7e26c12f8f25b36412b0cd560b7f11b62788a76bd171342e2ae858bcecb8266ff8482bbaed593afe818b9829e05e8e2b281ae7799580142 +CT: 368fb69892447b75778f1c5236e1e9d5d89255c3d68d565a5bba4f524d6ad27de13087f301e2ef4c08f5e2c6128b1d3e26de845c4ac4869e4c8bd8858ad0d26dec3b5d61a9e3666a3911ba +TAG: 1414f1b91966340417c38226ccca9d3d + +KEY: 43bf97407a82d0f684bb85342380d66b85fcc81c3e22f1c0d972cd5bfdf407f4 +NONCE: 000000008b6ba494c540fba4 +IN: 4b4c7e292a357f56fdf567c32fc0f33608110d7ce5c69112987d7b5a0bd46d8627a721b0aed070b54ea9726084188c518cba829f3920365afc9382c6a5eb0dd332b84612366735be2479b63c9efc7ff5 +AD: 1e0acf4070e8d6758b60d81b6d289a4ecdc30e3de4f9090c13691d5b93d5bbcef984f90956de53c5cf44be6c70440661fa58e65dec2734ff51d6d03f57bddda1f47807247e3194e2f7ddd5f3cafd250f +CT: d0076c88ad4bc12d77eb8ae8d9b5bf3a2c5888a8d4c15297b38ece5d64f673191dc81547240a0cbe066c9c563f5c3424809971b5a07dcc70b107305561ce85aecb0b0ea0e8b4ff4d1e4f84836955a945 +TAG: c5ca34599c6a8b357c6723ee12b24da8 + +KEY: 12fc0bc94104ed8150bde1e56856ce3c57cd1cf633954d22552140e1f4e7c65d +NONCE: 00000000d3875d1b6c808353 +IN: 24592082d6e73eb65c409b26ceae032e57f6877514947fc45eb007b8a6034494dde5563ac586ea081dc12fa6cda32266be858e4748be40bb20f71320711bf84c3f0e2783a63ad6e25a63b44c373a99af845cdf452c +AD: b8be08463e84a909d071f5ff87213391b7da889dc56fd2f1e3cf86a0a03e2c8eaa2f539bf73f90f5298c26f27ef4a673a12784833acb4d0861562142c974ee37b09ae7708a19f14d1ad8c402bd1ecf5ea280fab280 +CT: 9d9ae6328711fb897a88462d20b8aa1b278134cdf7b23e1f1c809fa408b68a7bfc2be61a790008edaa98823381f45ae65f71042689d88acfa5f63332f0fba737c4772c972eba266640056452903d6522cefd3f264e +TAG: e84211b6cfd43543f8b1b4db07a494d1 + +KEY: 7b6300f7dc21c9fddeaa71f439d53b553a7bf3e69ff515b5cb6495d652a0f99c +NONCE: 0000000040b32e3fdc646453 +IN: 572f60d98c8becc8ba80dd6b8d2d0f7b7bbfd7e4abc235f374abd44d9035c7650a79d1dd545fa2f6fb0b5eba271779913e5c5eb450528e4128909a96d11a652bf3f7ae9d0d17adbf612ec9ca32e73ef6e87d7f4e21fe3412ce14 +AD: 9ff377545a35cf1bfb77c734ad900c703aee6c3174fdb3736664863036a3a9d09163c2992f093e2408911b8751f001e493decc41e4eeeed04f698b6daed48452a7e1a74ec3b4f3dcf2151ca249fa568aa084c8428a41f20be5fd +CT: 229da76844426639e2fd3ef253a195e0a93f08452ba37219b6773f103134f3f87b1345f9b4bf8cfc11277c311780a2b6e19a363b6ac2efe6c4cc54a39b144e29c94b9ebbde6fd094c30f59d1b770ebf9fcad2a5c695dc003bf51 +TAG: 55e025a1eb87bc84d4be00c775c92ad2 + +KEY: 4aeb62f024e187606ee7cc9f5865c391c43df1963f459c87ba00e44bb163a866 +NONCE: 000000009559bd08718b75af +IN: c5d586ceece6f41812c969bcf1e727fe6ff8d1ae8c8c52367c612caa7cdf50e0662f5dffc5ea7d3cc39400dfe3dc1897905f6490fd7747b5f5f9842739c67d07ce7c339a5b3997a7fb4cd0d8e4817ff8916b251c11ef919167f858e41504b9 +AD: 51f5b503b73a5de8b96534c2a3f2d859ece0bd063ea6dfa486a7eec99f6c020983f7148cccb86202cf9685cc1cc266930f04e536ad8bc26094252baa4606d883bd2aeed6b430152202e9b6cc797ff24fc365315ed67391374c1357c9a845f2 +CT: 252ea42b6e5740306816974a4fe67b66e793ebe0914778ef485d55288eb6c9c45fa34ac853dc7a39252520514c3cb34c72b973b14b32bc257687d398f36f64cc2a668faffa7305ab240171343b5f9f49b6c2197e4fbe187b10540d7cdcfa37 +TAG: ab1d8a5a1f3eda9b5609c0028737477f + +KEY: 9a19e72f005cae1ae78b8e350d7aabe59fc8845999e8c52fad545b942c225eaf +NONCE: 00000000d9dae2ea8d2ffc31 +IN: 2110378d856ded07eb2be8e8f43308e0c75bc8a3fcc7b1773b0725b7de49f6a166c4528e64120bdf7c9776615d3ce6feeb03de964a7b919206a77392f80437faceb6745845cafc166e1c13b68e70ca2a1d00c71737b8fcbbbd50902565c32159e05fcd23 +AD: 1cd73b72c4e103afbefd7c777e0480f3f5e68c60b85bd2e71ef5caebb175d7fc6535d39f38f92c24f2eb0fe97d878ed3d5967c0bb4394a5d41f7d34cda6e1523d3848f049cde554a7d31e1afeab5d3e6150f85858335cbd28c8a7f87d528058df50eea06 +CT: 5f009fbce4ec8e4ca9d8d42258b1a3e4e920b2fbad33d5e9f07557d9595e841025193b521ba440110dd83958e8ee30219d952b418e98a6c624894aa248aedc0678f2d263e7bfaf54ca379fef6c5d2f7ac422ea4b4369408b82d6225a7a2cf9a9f46fd4ef +TAG: 1c6bdff7d8b9554dc7bf40e50b37d352 + +KEY: ba1d0b3329ecc009f1da0fab4c854b00ad944870fdca561838e38bad364da507 +NONCE: 000000008a81c92b37221f2f +IN: 6289944ffa3ccea4bf25cd601b271f64e6deb0eba77d65efb4d69ca93e01996e4727168b6f74f3ccf17bd44715f23ceb8fc030c0e035e77f53263db025021fd2d04b87a1b54b12229c5e860481452a80a125cb0693a2ba1b47e28ee7cbaf9e683c178232c7f6d34f97 +AD: e57883961b8d041d9b9eeaddcfd61fa9f59213f66571fadffffdd1498b9b014f1ef2e7e56c3044d7f9fa7a1403a1169e86430a2a782137093f5456e142aad03a5f7a66d38009dd01b7fc02c9cf61642dedaf7cc8d46066c281ee17780674c3a36eae66c58d2d765075 +CT: 9c44d9135db0dbf81c862c1f69bec55a279794cdd29a58e61909aa29ec4c120c9c5a508d856b9e56138095714a4bb58402a1ad06774cf4ecdf2273839c0007cb88b5444b25c76f6d2424281101d043fc6369ebb3b2ff63cdb0f11a6ea1b8a7dafc80cdaef2813fa661 +TAG: 689a141bc11159d306dad7a4ecf6ad9d + +KEY: 0cf8c73a6cffc1b8b2f5d320da1d859d314374e4a9468db7fd42c8d270b7613a +NONCE: 000000003c4c6f0281841aff +IN: 4434728d234603c916e2faa06b25d83bad3348990ecde2344368d1a7af1309bd04251bb2e0b72044948f8dea33cce2618283b6af742073a9586b26c1089335fe735141e099785a1235810a3a67ff309e2f0ce68220ba0077ad1a5dc1a4aef898a3b9ff8f5ad7fe60149bd0bd6d83 +AD: a38d09a4f1c9241623c639b7688d8d35345ea5824080c9d74e4352919db63c74d318f19e1cbb9b14eebd7c74b0ad0119247651911f3551583e749ea50ff648858dcaaa789b7419d9e93a5bf6c8167188dbac2f36804380db325201982b8b06597efeb7684546b272642941591e92 +CT: bdfbfea261b1f4c134445321db9e6e40476e2dd2f4e4dbe86e31d6a116d25830762e065b07b11a3799aab93a94b4f98c31c0faeb77ec52c02048e9579257e67f5a6bae9bc65210c25b37fc16ee93bda88fd5f30a533e470b6188c6ce5739fa3e90f77120b490fc1027964f277f40 +TAG: 780cc54bb6f1c9b78545c1562cd9d550 + +KEY: 69f4e5788d486a75adf9207df1bd262dd2fe3dd3a0236420390d16e2a3040466 +NONCE: 000000006255bf5c71bb27d1 +IN: c15048ca2941ef9600e767a5045aa98ac615225b805a9fbda3ac6301cd5a66aef611400fa3bc04838ead9924d382bef8251a47f1e487d2f3ca4bccd3476a6ca7f13e94fd639a259ef23cc2f8b8d248a471d30ac9219631c3e6985100dc45e0b59b8fc62046309165ddb6f092da3a4f067c8a44 +AD: 0c83039504c8464b49d63b7f944802f0d39c85e9f3745e250f10119fa2c960490f75ae4dced8503b156d072a69f20400e9494ab2fa58446c255d82ff0be4b7e43046580bc1cf34060c6f076c72ea455c3687381a3b908e152b10c95c7b94155b0b4b303b7764a8a27d1db0a885f1040d5dbcc3 +CT: f0bb2b73d94f2a7cef70fe77e054f206998eacf2b86c05c4fa3f40f2b8cebf034fe17bcbee4dea821f51c18c0aa85b160f8508bd1dc455cc7f49668b1fb25557cdae147bf2399e07fcacaca18eccded741e026ef25365a6b0f44a6b3dd975ee6bb580f5fccd040b73c18b0fbf8f63199ba10fe +TAG: 2ecccea4607d14dbb2d2475792aeb468 + +KEY: ad7b9409147a896648a2a2fe2128f79022a70d96dc482730cd85c70db492b638 +NONCE: 00000000a28a6dedf3f2b01a +IN: 791d293ff0a3b8510b4d494b30f50b38a01638bf130e58c7601904f12cb8900871e8cf3d50abd4d34fda122c76dfee5b7f82cd6e8590647535c915ae08714e427da52f80aef09f40040036034ca52718ea68313c534e7a045cd51745ec52f2e1b59463db07de7ca401c6f6453841d247f370341b2dbc1212 +AD: 9a6defddb9b8d5c24a26dd8096f5b8c3af7a89e1f7d886f560fabbe64f14db838d6eb9d6879f4f0b769fe1f9eebf67fcd47b6f9ceb4840b2dba7587e98dc5cae186ef2a0f8601060e8058d9dda812d91387c583da701d2ba3347f285c5d44385a2b0bf07150cbc95e7fcfa8ae07132849a023c98817c03d2 +CT: c2f109d6d94f77a7289c8a2ab33bc6a98d976554721b0c726cbf4121069473e62ba36e7090e02414f3edc25c5d83ac80b49ad528cda1e3ad815b5a8c8ae9ad0753de725319df236983abd3f69ab4465d9b806c075b1896d40bdba72d73ba84c4a530896eb94ffccf5fb67eb59119e66a1861872218f928cf +TAG: 17ec6cf2b172f01e3c456ad047196805 + +KEY: 48470da98228c9b53f58747673504f74ca1737d7d4bb6dbf7c0cba6ca42f80b9 +NONCE: 0000000056fb4923a97e9320 +IN: bc6626d651e2b237f22ee51608ddcffeba5f31c26df72f443f701f2b085d6f34f806e29673584cb21522179edb62a82427d946acabce065b88b2878e9eb87ed1004e55ef58f51ec46375ac542c5782725ff013136cb506fcf99496e13fcd224b8a74a971cc8ddb8b393ccc6ac910bd1906ea9f2ed8a5d066dc639c20cd +AD: df8ab634d3dca14e2e091b15ecc78f91e229a1a13cba5edd6526d182525ec575aa45bc70fb6193ffcd59bad3c347159099c4f139c323c30a230753d070018786b2e59b758dd4a97d1a88e8f672092bef780b451fd66ba7431cbb5660ea7816cdf26e19a6ebb9aadc3088e6923f29f53f877a6758068f79a6f2a182b4bf +CT: a62e313ecf258cc9087cbb94fcc12643eb722d255c3f98c39f130e10058a375f0809662442c7b18044feb1602d89be40facae8e89ca967015f0b7f8c2e4e4a3855dbb46a066e49abf9cef67e6036400c8ff46b241fc99ba1974ba3ba6ea20dc52ec6753f6fc7697adbccd02b0bbea1df8352629b03b43cc3d632576787 +TAG: d29a8968067aeb457ffc114c3a9efb95 + +KEY: b62fb85c1decd0faf242ce662140ad1b82975e99a3fa01666cac2385ab91da54 +NONCE: 000000002f4a5ca096a4faf8 +IN: 03b14f13c0065e4a4421de62ab1d842bffb80f3da30bf47d115c09857f5bdd5756fd7c9ac3d9af1c9fb94f2640f7f4386cfba74db468e5288dbe4dd78bfe4f69e41480ca6138e8beacc6eaa3374157c713cfa900c07dd836eaecc8827fa3e70e052ae09e8473e2ae1a10b1bb669ef60a8dd957f6553daa8114918e17371f2ac327bd +AD: cfe3b7ab7550b0e8e2e8235fa0dcef95647ce6814abd3dc3f5a3bd7d6d282504660c34ad8341e4d11402c7d46c83a494d7ddb105e1002979023e0e3dc2978c9ae53e10eb8567e7a02b60e51e945c7040d832ca900d132b4205a35034fed939a1b7965183c25654931a9b744401c4649c945710b0d9733b87451348b32ba81de30ea7 +CT: 8965db3d3ae4fb483208f147276e7d81b71a86e7202ffc9b1eaade009bc016838dc09ca4bcf30887b2f4243fbd652cd90ebed1ceef8151ff17ea70518d03b0f2a24960aa7de9b30fa65c2e2d57360061aae6d9376e984e9fcd5e5dd0911a4bc8deca832ffb76f252bd7da523076593ba6b174f7d9fb0377e066ecbb6638036241e86 +TAG: 28a5284696ed82714eaa94c9ebe6e815 + +KEY: de9c657258774d4ebc09d109a0fc79d66493ae578797cac4eb8830a6a4b547e0 +NONCE: 00000000b5e35fe3398efa34 +IN: 4d68fb683aa4f4c7a16ba1114fc0b1b8d8898610fa2763e435ded8771b3651078bef73d4dfd14e76a34cd5eb9ef4db4ead4da9e83f4ce50fe059977b2d17d687c29335a04d87389d211f8215449749969f7652dc1935a0f9a94538dc81dc9a39af63446a6517609076987920547d0098a9c6766cf5e704883ea32feaea1889b1554b5eb0ce5ecc +AD: 436ea5a5fee8293b93e4e8488116c94d3269c19f1d5050def23d280515457b931bbed64a542b317cc5023d648330a4b7adca14dd6f3783207b94f86ccaa0a0ac39b7db00ac87a99e3cd8a764ed9c75da8454479636ab2b29e770b166a5b75cacc425c919bf1ce9ac34afe6b4425c3d9fd2e48bc81e7d15516d60e592bfcc2ebefb660f0995f2b5 +CT: 97a97b8f0f5420845ae8d57567f9bba693d30e6db916fad0b971f553ad7d993f806f27ab8b458d8046062ced4778c004b4f958a4436141637c6039963308dea2f54008b7feab79650295ed41bf9e65e1a2d75ab1c7b2a70ebb9e9f38d07a9a672d3e95ea78afe9ac02f2566b48b0251aef6eeeca8bd15bd8d43b559426aa9d15d960ee35cb3edf +TAG: 4ef49e8a0c2ef85826d7f03e81c577f2 + +KEY: 6885bd333c336c7672db8ebdf24c1a1b605c5a4ae279f0f698162f47e6c73401 +NONCE: 00000000f0c4a213a6168aab +IN: fa905a2bfa5b5bad767239fb070a7bc0b303d1503ecd2b429418cc8feba843e5444ed89022fdb379c3b155a0f9ceab2979000a0f60292a631771f2fde4ef065aa746426609082969530a9c70ad145308c30ba389ea122fd766081511a031ce3a0bd9f9f583c7000b333b79ac004fbde6ec3eb2d905977ff95dcff77858e3c424fe8932a6a12139e6ec8d5e98 +AD: 8ded368f919efb522bb6a9ad009e02ffbc6a16536e34d95cdb34f1153d7cb7b0f3c2b13dd05cedae27cfe68ec3aca8047e0930a29c9d0770c1b83c234dcb0385deae7ae85da73a5f8de3dfb28612a001f4e552c4f67ae0e2ec53853289b7017a58591fd6f70b0e954876bb2f7ec33001e298856a64bb16181017ba924648c09fc63c62eff262c80d614679bd +CT: 0cb3d6c31e0f4029eca5524f951244df042fc637c4162511fea512a52d3f7581af097eb642e79e48666cb1086edbd38c4777c535a20945fabc23e7c9277e2b960aac46865f1026eb6da82759108b9baece5da930ccfc1052b1656b0eadaa120ed0c45ad04b24ae8cdb22ceab76c5f180b46a392ab45b1b99c612546e6b947f4d5c06ad5abee92ff96345ad43 +TAG: fad7d5a5193dfb121c68529ba8c0c35d + +KEY: fbc978abb1240a6937ccc16735b8d6ed5411cdbc1897214165a174e16f4e699b +NONCE: 000000007968379a8ce88117 +IN: 1a8196cd4a1389ec916ef8b7da5078a2afa8e9f1081223fa72f6524ac0a1a8019e44a09563a953615587429295052cc904b89f778ef446ed341430d7d8f747cf2db4308478524639f44457253ae5a4451c7efca8ae0b6c5c051aaa781e9c505489b381a6dcba87b157edc7f820a8fbaf2a52e484dc121f33d9d8b9ac59d4901d6ed8996ed4f62d9d4d82274c449cd74efa +AD: 3913cd01299b8a4e507f067d887d7e9a6ded16dd9f9bb3115c5779aa14239fd33ee9f25756d45262dc3011069356425b5c81a4729594e17c9747119f81463e85625d5603d05e00f568b0c800bb181eb717be8d7a93166a504ce1bc817e15530c5bd2b3df1d4222245ea78a38bc10f66c5cf68d661503131f11af885c8a910b6dce70bc3a7448dfae00595beb707fe054d3 +CT: d152bcb4c24c3711b0fad28548dc4db605bbc89237cdbea7dbf956b8855d1161a0781f27bd56d798141e2ace339955efb98fe05d9b44cd011e645106bf47726183958cb6df34ce5766695f60bc70b6fe0fabb9afa009a8ef043dbf75f861881368fa07726625448fe608d578cdc48277f2dc53eaaf1bdc075269a42f9302a57cad387a82c6969608acacda20e1cac4596c +TAG: 96ae06cd7c72456e5568a42317046158 + +KEY: 77d1a857fbadfe01aba7974eea2dfb3dc7bf41de73686aece403993e5016c714 +NONCE: 00000000fdd913a321c40eb0 +IN: db8915bfe651e2ecb3ce0b27d99a6bfa7a7c507cfcb2987293018636c365a459c6a138b4428be538413db15bda69e697cbb92b154b7f4d2cbb07965225aa6865d7dcd1ba2c17c484b00b1986fed63e889f25a4966dc3ed4273f1577768f665362d7d3e824484f0dded7f82b8be8797ad951719719365e45abbf76324bc7d657799d4d4f4bb1dba67d96ab1c88519a5bee704f7214814 +AD: 3cb2c06c20cb0832bbacebfc205d77393ca1816346ea2681de4d3ab1fadb774ad273e4713290454496f5281ebc65e04cfe84ed37cd0aedc4bbe3decbd8d79d04a4e434876650e0d64309e336bfb10e924066a64acb92260b2dbd96735d03af03909aa6a80a6e89fda81037257aec21fe9be7e91a64e88e0a58fa38ecba4c4c4cffb61958f3c486cbb0b1d0b0014a2d1d3df248eec1ca +CT: acb825e6023b44b03b2efc265603e887954e8612b2ee134bdcb61501cfb9492952bf67be597c3a005b09af74d9e421a576d2c65e98104780feab838d8cb1bd135452ea39dc8907a4c1a6a9161805e4fa3e16989e6a418a7eea2582bf895da967028eab7c95d846a6de4b9980785814cf00484baa2f6de609912fff689bce6e854261ffe866bd8e63274605c7c5ad677bd7897ade543e +TAG: bcf523a9bcf772e157941753c6d7401e + +KEY: b7e9b90dc02b5cd6df5df7283ef293ed4dc07513d9e67331b606f4d42dec7d29 +NONCE: 00000000a6c191f6d1818f8e +IN: 2ada0e3c7ca6db1f780ce8c79472af4e8e951ddc828e0d6e8a67df520638ff5f14a2f95a5e5931749ae2c4e9946ae4d5eb5de42fb5b77d2236e2e2bd817df51be40b1b8a6c21015a7c79fe06dba4a08b34013dfa02747b5f03930268404c455dc54a74d9c6e35485e10026da573cb41cd50b64cfafe4cfcdf3c9684ef877e45d84e22bd5e15fa6c8fd5be921366ff0dc6fe2df45f7252972c9b303 +AD: 0f4269ed5ef0bfff7be39946a4e86e8bf79f84b70cd0b14fecb7be3c071316ce86de3d99d6871e0ba5667d9d7bba7dcaba10cb2a36668b6c3e2fb6c102938b75008bb9c213ebf9b85b5e91a802df0d31d7f11d764b2289f6225212694ab6b7c0e3ff36e84245d9f4f43fc5f98e654dea7ba9bd918658879c5bb4a1642af0d83113e3cf935d3c0d5208318f66f654eb17d8c28a602543e77ad3e815 +CT: 22586fe7338e99cdaad9f85bd724ba4cfe6249b8a71399f9a3707b5c4323b8d96679568dfc8d230aefb453df596e13eb3e8a439249bd64bc93a58f95089a62b94f6562b821c83d91f56c55147381e9de4beb4ae81bd6fe7caef7e7e9a2078f2fba8f3e70d4910da9accc92b8e81a61b0fefbece4bd89443e66e8ddda8e47a66a62f17fd0e7d0a4852ce1a4d43d72a0b5e8914bbec698f060f2b092 +TAG: bd05336ed6426de412aac37661953052 + +KEY: 6b2cb2678d1102f2fbbd028794a79f14585c223d405e1ae904c0361e9b241e99 +NONCE: 000000007b3ae31f8f938251 +IN: b3cb745930e05f3ab8c926c0a343a6eb14809fd21b8390a6fcc58adb5579e5432021765b2d249a0ecf6ba678634c4f53f71495865f031ee97aa159f9ead3a3fcb823ee5238bdf12706a9c6137d236e2e7110ce650c321e41daf0afd62bab2a8fe55d7018de49a14efe6d83a15b2f256d595e998d25309f23633360f5745c50c4e5af8ccc9a8a2cb47064105a023e919c7795d2dc331d3f2afb8c42e5c0bcc26d +AD: 1c32fd3df22b3e440e2a3c7a7624990194cb16a5f74af36f87fd6ca7d410ce9064316a2d091945deef7d9b35ceec8396069307caced2b80afd7d53ec479c35cedf2dfd4c95c3dd8400f71ad34028c6e4f8681d93d0774064ba38f3fb9b0c1dfa1f5f0c7d20676a5911d999fb6a1d41367a8e99d852bf3d3b7b3f4c233249ed1ca135389a674ff48232ded3f6800a97b6d409c40e6cd70d09bf9d2ad25d9b9485 +CT: ef70c7de98ab1d4ad817024a970be463443640eb0cd7ff234bdd00e653074a77a1d5749e698bd526dc709f82df06f4c0e64046b3dc5f3c7044aef53aebb807d32239d0652dd990362c44ec25bf5aeae641e27bf716e0c4a1c9fbd37bbf602bb0d0c35b0638be20dd5d5891d446137e842f92c0ee075c68225e4dbacb63cc6fb32442b4bcda5e62cb500a4df2741a4059034d2ccb71b0b8b0112bf1c4ca6eec74 +TAG: d48657033095db3f873c33445fec8d35 + +KEY: 4dbc80a402c9fceaa755e1105dc49ef6489016776883e06fcf3aed93bf7f6af7 +NONCE: 000000002358ae0ce3fb8e9f +IN: 197c06403eb896d2fa6465e4d64426d24cc7476aa1ae4127cd2bd8a48ce2c99c16b1cbf3064856e84073b6cf12e7406698ef3dd1240c026cbd1ab04ee603e1e6e735c9b7551fd0d355202b4f64b482dd4a7c7d82c4fe2eb494d0d5e17788982d704c1356c41a94655530deda23118cba281d0f717e149fbeb2c59b22d0c0574c1a2e640afad1a6ceb92e1bf1dde71752a1c991e9a5517fe98688a16b073dbf6884cfde61ac +AD: cf6ce7b899fb700a90d2a5466d54d31358ecf0562e02b330a27ba0138006b342b7ed6349d73c4c5c6d29bde75a25089b11dac5b27adea7e7640ca1a7ceb050e3aae84a47e11640a6e485bd54ae9fdb547edc7313d24a0328429fcffd8b18f39880edd616447344ebeec9eadb2dcb1fa7e67179e7f913c194ebd8f5a58aea73b0c5d1133561245b6d9c5cfd8bb0c25b38ffb37db5e2de5cdded6b57355e9d215cb095b8731f +CT: aa87f9a83048b6919c8f2b050315db4e2adae4a9c2ca0109b81961b520e63299dcb028cec0b9d3249a945ee67dd029b40f361245c740f004f8cf0d2214fcfa65e6124a3e74b78aa94345c46fdc158d34823ed249ee550431eaae9218367321cdd6e6a477650469bb3cc137a8f48d9cf27934b16703608b383d2145659922fb83bb2e7ee2ef938a90f2ff846a4a949129b1fb74dde55c5ae013c2f285de84f7dac7d1662f23 +TAG: 298f84c8312029a7b1f38c5ea6021f57 + +KEY: 9e4a62016dae4b3223fed1d01d0787e31d30694f79e8142224fe4c4735248a83 +NONCE: 00000000263a2fc06a2872e7 +IN: 5a46946601f93a0cee5993c69575e599cc24f51aafa2d7c28d816a5b9b4decda2e59c111075fb60a903d701ad2680bb14aeda14af2ae9c07a759d8388b30446f28b85f0a05cd150050bd2e715ff550ebbd24da3ebb1eac15aba23d448659de34be962ab3ab31cb1758db76c468b5bb8ce44b06c4e4db9bd2f0615b1e727f053f6b4ffb6358d248f022bcad6ca973044bed23d3920906a89a9a9c5d8024ec67d7f061f64529a955ce16b3 +AD: 4cd65f68f9f88c0516231f2a425c8f8a287de47d409d5ecde3ad151e906b3839fb01bb91a456f20ea9d394d4b06604ab1f9009ef29019af7968d965d1643161ab33a5354cda2fdc9f1d21ec9cb71c325c65964a14f9b26eb16560beb9792075a1597394000fd5f331bd8b7d20d88e5f89cf8d0b33e4e78e4904bb59c9c8d5d31ac86b893e4a0667af1be85fdb77f7ec3e2594a68048d20c2fb9422f5879078772ee26a1c560cbcbb2113 +CT: e944bb2ab06d138ad633c16ce82706ecf0ef5d119be1f3460c9ce101d9c4e04ef1677707fca40d1f8ca181e07273707b06624d6d7063c3b7b0bb0151b757b3e5237fb8004c161233d8bc7e5f28ea1c18da1874b3d54c5ad6ff0835eed35c8853704585cf83996e5e7cec68180af414e04f08134d3b0384ebdf0393c9310b55d8698fe10cb362defc0995e9a13b48b42cff61ffd9fe4c3c8c6dab355713b88f6e98a02e7231a0c6644ec4 +TAG: 6234e81e089b779d0d509d14e566b5d7 + +KEY: 18ca3ea3e8baeed1b341189297d33cef7f4e0a2fab40ec3b6bb67385d0969cfe +NONCE: 00000000b6aef34c75818e7c +IN: ef6d1bb4094782f602fcf41561cba4970679661c63befe35ff2ca7ad1a280bf6b1e7f153fa848edfeffe25153f540b71253e8baba9aeb719a02752cda60ea5938aab339eead5aabf81b19b0fc5c1ed556be6ad8970ea43c303d3046205b12c419dea71c4245cfedd0a31b0f4150b5a9fe80052790188529ab32f5e61d8ccde5973ed30bdf290cbfbd5f073c0c6a020eac0332fced17a9a08cef6f9217bd6bef68c1505d6eed40953e15508d87f08fc +AD: f40f03beaa023db6311bad9b4d5d0d66a58d978e0bcbbf78acebde1f4eb9a284095628955a0b15afc454152f962ec3ea2b9a3b089b99658e68ede4dee5acd56672025eb7323bcbc6ba5d91c94310f18c918e3914bbbf869e1b8721476f9def31b9d32c471a54132481aa89f6c735ab193369496d8dbeb49b130d85fbff3f9cb7dccea4c1da7a2846eef5e6929d9009a9149e39c6c8ec150c9ab49a09c18c4749a0a9fcba77057cdea6efd4d142256c +CT: c531633c0c98230dcf059c1081d1d69c96bab71c3143ae60f9fc2b9cd18762314496ab6e90bf6796252cb9f667a1f08da47fc2b0eecda813228cae00d4c0d71f5e01b6ce762fa636efffe55d0e89fdc89ba42521cc019ab9d408fcd79c14914e8bbf0ea44d8a1d35743ad628327e432fdcfeb0b6679ddca8c92b998473732abd55dba54eefff83c78488eee5f92b145a74b6866531476fc46279d4fde24d049c1ce2b42358ff3ab2ba3a8866e547af +TAG: e3b4192f6e50528c4f4f70267f094c56 + +KEY: 95fdd2d3d4296069055b6b79e5d1387628254a7be647baafdf99dd8af354d817 +NONCE: 00000000cd7ed9e70f608613 +IN: 0248284acffa4b2c46636bdf8cc70028dd151a6d8e7a5a5bc2d39acc1020e736885031b252bfe9f96490921f41d1e174bf1ac03707bc2ae5088a1208a7c664583835e8bb93c787b96dea9fc4b884930c57799e7b7a6649c61340376d042b9f5faee8956c70a63cf1cff4fc2c7cb8535c10214e73cec6b79669d824f23ff8c8a2ca1c05974dd6189cfee484d0906df487b6bd85671ce2b23825052e44b84803e2839a96391abc25945cb867b527cdd9b373fbfb83 +AD: 24a45a3a0076a5bcfd5afe1c54f7b77496117d29f4c0909f1e6940b81dde3abacb71ec71f0f4db8a7e540bd4c2c60faee21dd3ce72963855be1b0ce54fb20ad82dbc45be20cd6c171e2bebb79e65e7d01567ad0eeb869883e4e814c93688607a12b3b732c1703b09566c308d29ce676a5c762a85700639b70d82aaef408cf98821a372c6a0614a73ba9918a7951ea8b2bb77cd9896d26988086d8586d72edc92af2042ff5e5f1429a22f61065e03cfcd7edc2a93 +CT: 40c6318d9e383e107cdd3e1c8951562193c3ef64ee442432a63e2edefc78f32ab07772aeac172cb67ecf4d21f8b448423527bbeb9d8ddd0b46bdb27f74096ceb24e41963b4cdca176676a75bdbe3abc270b349ac0c6cbd9c3a5cd5bce20202fc5cc0c1bdd4fd25e121e0a24bd7bbeb9b19b1912467bf5338ee2ce88aa383c082b42cc399c9654ca325f35523e81438beb3f8926be79c378822d7c8f785614408a5f7cac49e4543188725643e6c1a70b46d0ec400 +TAG: 874875c9a0ba3060a0680291c3dc85a2 + +KEY: 6ae1102f84ed4dc114bb9d63f4dc78d7dbb1ab63f1659dd95f47940a7b7a811f +NONCE: 00000000c965d578ba91d227 +IN: b82a8a9209618f1f5be9c2c32aba3dc45b4947007b14c851cd694456b303ad59a465662803006705673d6c3e29f1d3510dfc0405463c03414e0e07e359f1f1816c68b2434a19d3eee0464873e23c43f3ab60a3f606a0e5be81e3ab4aa27fb7707a57b949f00d6cd3a11ae4827d4889dd455a0b6d39e99012fd40db23fb50e79e11f8a6451669beb2fbd913effd49ad1b43926311f6e13a6e7a09cf4bebb1c0bf63ce59cd5a08e4b8d8dbf9d002e8a3d9e80c7995bb0b485280 +AD: dfd4ac3e80b2904623ff79ea8ee87862268939decf5306c07a175b6b9da0eb13ac209b4d164755929e03240a0fe26599f136fb2afdffd12bb20354aa1d20e5799839abb68ae46d50c8974e13e361d87ef550fe6d82e8b5b172cf5cd08482efdef793ede3530d24667faf3a1e96348867c2942641f4c036981b83f50236b8e8a10b83ebf6909aad0076302f1083f72de4cf4a1a3183fe6ec6bfe2e73e2af8e1e8c9d85079083fd179ccc2ee9ff002f213dbd7333053a46c5e43 +CT: a9aeb8f0a2b3ca141ac71a808dcc0c9798ac117c5d2bd09b3cfe622693a9f8ca62e841b58bddb2042f888e3099b53638b88dfc930b7a6ee4272d77e4b1d7e442bab6afbde96ab0b432f0092d9ca50eef42f63c60c09e7b8de019b32ebe4030c37b8183cc1e3b913b0ce4ee4d744398fa03f9af1c070bed8cdafd65b3a84140cb4deadc70184de757332ce3780af84353f540755227e886a8d7ad980f3dd6fd68263d82e93f883381dec888bc9f4f48349aa2b4c342cb9f48c6 +TAG: f6dcad5412b95994f5e4d6829c2eba98 + +KEY: 405bb7b94715b875df068655f00513cb1ae23ffaac977ce273e57d3f83b43663 +NONCE: 000000005c6da1259451119a +IN: f9f143c0c52c94b4ba7b0608b144156a49e7b5d27c97315743d171911e3645ab7957c80924e3c6b9c22ab7a1cac4b7e9c0de84e49fd5e4a2d1ab51d764fc5670318688ec942f7ab34c331dce8f90fea6972e07f0dadec29d8eb3b7b6521ddd678a6527a962f4d8af78c077e27f7a0b2ef7eabd19e92b7f8c1e8fb166d4763ce9c40c888cf49aa9cdfc3e997c8fe1cce3fe802441bbd698de269ff316f31c196e62d12c6bb5cd93fb3c79ca6369f8c1ac9102daf818975ea7f513bb38576a +AD: 6fe6446505677bf08b385e2f6d83ef70e1547712208d9cebc010cba8c16ea4ece058d73c72273eed650afdc9f954f35aa1bdf90f1118b1173368acbc8d38d93ebf85bd30d6dc6d1b90913790c3efa55f34d31531f70c958759b2ba6f956c6fcdd289b58cb4c26e9515bf550f0fd71ab8527f062c9505cbb16e8e037d34de1756bef02a133dbf4a9c00ac03befc3fb7f137af04e12595ce9560f98b612480fcdba3b8be01db56ebec40f9deae532c3b0370b5c23a2a6b02a4de69efa8900c +CT: 1a4b073881922c6366680cc9c2a127b26f264148651b29abb0c388cf6c9b1865dba5a991e1f8309efbdb91bce44b278772c58fd41273526c33fec84beb53d1689b9da8483f71be6db73a73417069bb4cd3f195236e8d0a00d124eed3a6b6f89415b19a27fbe35774f6a1a6ee4bd4350b252b975f0db2d2eea82f4836350850d6290901e726e8af13644e2d98bc1d569c20800521e6affe976bd407049a2e6d9dd23f88d52e651391ecd2fc45b864310824aaadfa203762a77c1d64562dae +TAG: 90fcc2544880250f1c3abe8a3761ba08 + +KEY: 8c602bd94c630cd00c7a9c508067a5a9f133d12f06d9f6fe2a7b68dce4786d8a +NONCE: 00000000760de0f7b7cb67e2 +IN: c3ff559cf1d6ba6c0cc793ca09a0ba573a28359386a6ec93e1bacd8e630209e0b477a20aedec3c9cbf513ee6a1e3887112218d6155b9875f7e6c4bbba2c31972e905d19f529f4f0f9502996199f94f8728ba8d6424bb15f87fcacd88bb42c63fcc513759712bd0172b1e87c9da122f1993ffb7efd3a5c34b240dd3db89dddea36dbeb2836d9f8648f8e7cd428c0f948097af753b35f9876059e7702027bb00dc69071206e785f48fcbf81b39cc0343974ac70784a2e60c0df93b40379bea4ad8cac625 +AD: 9e14907c3a8e96c2636db1f3d78eb1f673d6ef043cbbb349467f1fe29bf60f23d5d5d1c3b133a8ad72065d822347541c13d1574baf737eb3cc3382fb479e6d5193b9c8e7d2444c66971ef099dc7f37f6cd97b9f7959d46e2cf25e8a5b3111b4d9e2ef906d905f0ee2d17587f7082d7c8e9a51509bde03d3d64338e1838d71700f1b4fcb100b5e0402969da462f26f974b4f9e766121f8fd54be99fc10beb9a606e13fbb1f960062815d19e67f80093360324013095719273c65542b0e31b1a2a3d928f +CT: 2794e6e133f6892f23837fff60cf7c28ee9942f8982ef8089db117903d0143293fdf12ea1cc014bcd8806fb83c19570eed7af522db0de489bbc87133a13434518bcfb9cda4d9f6d832a69209657a447abf8afd816ae15f313c7ea95ec4bc694efc2386cdd8d915dc475e8fadf3421fbb0319a3c0b3b6dfa80ca3bb22c7aab07fe14a3fea5f0aee17ab1302338eeac010a04e505e20096a95f3347dc2b4510f62d6a4c1fae6b36939503a6ac22780a62d72f2fc3849d4ef21267fffdef23196d88fbb9b +TAG: 7fa630c9bcb455e89f13d7a99d5e8dbe + +KEY: bd68ff5eb296c71cfe6bc903c14907f7726bcb1331f0c75f7801cd1b7948f3a1 +NONCE: 0000000065a748004b352ba6 +IN: 52bf78c00f6e5dca2fc60e2e9a52e827df97808e9cf727773860cafc89f4b64178a19b30b46ed813fe00c8f09b25a6a1b6e350d5b005122934a59bfbd5e6e0c635c84a5226c3f2f7dcf951560f18ac220453d583015fdb2e446c69c6e6fdecf2e595e04fab1b0c506e3c6bd5e4414a35f15021e97f447aa334f54a8f1ef942dec6273511b5668b696fca97188ff15ed84b2f46145cce031c1a7f00bd88bb83d90797edc46161b3fda7a2299173496d73b812139556e8b4eb318078b9eb2ae5046e83b79dd3d45950 +AD: 5557b08a5010cbc9f46bb140c2505f68684eb24889324bff44b27234fd7a95a99cfb4ff90a8f9982085b725f78ac42eca6ce7f3314e457dc41f404008681a9d29ba765660de2e05bb679d65b81f5e797d8417b94eb9aabbd0576b5c57f86eae25f6050a7918e4c8021a85b47f7a83b4c8446898441c5cc4e0229776ef3e809cb085d71f3c75ec03378730cb066150f07e60f96aec983c0e7e72bf6bf87ae42228dfda195f97855fcdf4e6d1c4479d978abcfa276d16ed60ecbfbfc664041335ce65a40a2ca3424df +CT: a5c8cf42287d4760fca755e2111817b981c47e85b0047de270ec301ca5f7b3679f4749210892b6ea6568f3a6a4344734a0efc0120ffedecf212d55cbcbb67815ac964875af45f735b70092a8f8435f52fc01b981ae971d486026fb69a9c3927acfe1f2eab0340ae95f8dbee41b2548e400805ece191db5fd1f0804053f1dbfaf7f8d6fded3874cb92d99a2729d3faaa60522060cf0b8101b463b3eb35b380fcddb6406c027d73fe701a5090c8dd531c203ce979e26b9ced3431e2b726a7244a20d9377bd62951bf5 +TAG: 82c6194de4d27aac4c54b023b9831634 + +KEY: 934fd043c32d16a88fad01c3506469b077cb79d258b5664fa55ad8521afdcaa2 +NONCE: 00000000c7091f6afbbeb360 +IN: 2bdd1fc4f011ef97ea52ec643819941c7e0fb39023c2f3c7683804a0ddee14a5d1784a5246966d533b3538edc7d8742d27061c3cab88df0318ab242102de3a54d03632eeb871b72c7e8f8065b49f4a91e95e15f3f46b29fd76b8fcea0d23570c5530e3bbb8a6aafa9ae32c1b3eac653c5ed5fdb2da5a986075808f6385870c85b1913e26042a9d8e78f5bc2ea6de5a64f8aeafa22adcffc7f6932d543c29bb3a04614783f948680e433a71573568d2ce984d249fb4fc06a9f358c76aa3e64a357f4eae924c1356bd5baccf7e0f +AD: f737dd85638eb324dd3891219c5eef7c2dd053cfd055d447a411eba304a4b27dce981d112c4540590933c153d603022c91ebd2b4a58069d27e6ca17a462ef822ca41bffa80b43a68b1b564644cb3c5a7f0fddf7a13a30ff24437fddd8ef93c6f6f205d054f81890d982bd4d4ece0b1563677e843fe48c1f54e9a57ed4da66061482712e710a401073be5080d5b8b96525bffa67de5af31d50385fbbf1a87c21bf0e0a1fdff69ec32c7b7103e0b8ee6c844245e0fc84b9f89fcce62966cea68e2871d3b82e8df424c76309fc88d +CT: dd13fbf22c8d18354d774bcd18f7eb814e9b528e9e424abc4e3f2463195e8018576565d16ab48845d11c9277f2865ebb4dc412fd5b27078f8325eadf971e6944c66542e34d9dda971e2aba70dbd3e94a1e638d521477a027776b52acf90520ca229ebc760b73128879475d1cbe1f70fc598b549cd92d8a9ac6833e500c138c56474db84cb3d70b7aa4f293a4c2b4d818b0ff9fd85918dc590a12a8c0e375c4d98b7fc87596547eb960676aad5559834588f00f251a9d53f95c47af4df3c4299175d5211779c148cfc988a5e9d9 +TAG: aeb0a4eb29886f0a7a12ec0516bd4af5 + +KEY: f9f6eb9ad736a8f66e7459fef5ec2890188dc26baf34a95f6f0384e79f5c6559 +NONCE: 000000007858dfc084fe4b0f +IN: a644ca6e7cc076e87eb2929fd257693fce0f6fb64fd632f7f07c648ebd03696c8e262e6a810d7b7c4e5eef8c65b5323c99dbba50a70b4a9e5c2a9e7315973cd67f35d8052ce9a85a206416dd3031929f4f929b13d0a5fb10cb73c65f6c0ace019da146b51c5274a099f44e3669d26add6f2ff081e886f3cf952fe0dbbe6b0534c23e307574bd35fbd657f5fcbd5dc19fb382a1dc0a2dc8285a0350f71554e4c601497749e35567dd4a273cddc9a48ce53a5f1d297fd8baf8d1b9feb35d9151114345abada4d90db947bb9a743c175f5653d1 +AD: 2048d1c2ddfb5ec385b201832c7a993f229ba72ec16d6ebf723ef0c5032b9966209a9e8a63151b40412e96b82f86728ea6588c7e8e11ac71cc8eabab8c4b54de866658d9c5011def61fb3dbe4e630158a45ea41a2ed55ebd1efb1abeda7637de6fa5fd2f151c6d2f385bf6cd002ca8b4a2896e0d65944ee913e3c784669dd201b1985ef3577f7f123a5f9bcffa176c8f557c4f729133cac518642f27d9b22ca9b97faaafe5b669a10b79ace4a7d5727df146c77ce681357d69f9c2d65b4401bd73cd113387e3b3a05d897adad7a24c485e7b +CT: 4146faffd7313f5d9f625370d20413cc62ab65f4acfa3c7ee1125b937dd7a39f638fc46c8ed004fb525698de5d8620ec153435571817c3de257b0d0e648ebb92940c86a98262d54e764f28cbdd4f7d9bea970291f2110414f62064d7229c6332236c507b3dac742e651d85a2a22fb243c0cc7cc2d016e5bea38f33f9a9ce048944a5fe8b078d71d23168e12dfe5a0f0b829771edc7073fb96032b7be471337a37aca0cf7c0cdd543eed686cd34934717fd79a3f18492eef72f9f450b880aa7e2e1b65e3b04c22e72301338b43aa32ceec2e6 +TAG: 61c6d4d6918b04fc1b72a7a0e9a3b799 + +KEY: 29b19636cdd32507fd98ec4ee26caab1a917646fb8f05b0dc01728a9f4a127f0 +NONCE: 0000000006699d245916686d +IN: 5fdf913aceab1d6dbaf7d9a29352fa8a3eb22718043a79cffa2fe8c35c820aec7c07644b8785dcf7a433b4189abb257fb12b06fae0662641011a069873c3e3c5ccc78e7358184a62c2005c44b8a92254958eb5ff460d73cd80284d6daba22c3faba046c5426fe8b7cacec64b235a8f8d3e2641e5bc378830594bcfb27c177aea745951ee5780a63705727ef42c4ad3abf556d88e3830f3db6b09e93edd09485cbf907f79de61f8dc5cb5fb7665ffa0ef53cb48702f6a81d8ad421cef20c1dbdf402b8fafed56a5361b2f93f914a2380fdd0557faf1f4de +AD: 39116c49cc13adb065b92cb7635f73d5f6bf6b5ccbf72a3f65a5df6bd4a661105015358d9e69f42e98aed795e8161282bc113058b7ef3b9e23fcd8eeab34a392e03f4d6329c112cb968385ec52a7afc98bb8695785af6b27b700973cc952630b7247ce226b4fbb99b8a486370bf6345d4516c52c64e33f407c4f2d1ba90545c88732d98bbd97972ac5e94c694624a9b3782b0099824651cb7567914d25b3e13181a791dbcd40e76e836b3350d310a52151bf835d3c357c9871482c2928e8404c6e533406d4d6fa8f63366f2c4ed828141f1ff00f01a536 +CT: 01e237220b619054a1f3670928fe67d40484b5af40fbd04d032500aac5acaa3b4584dd99a58c390627636a50de5d744f76a56a33205f9e3b00e16162eb47ff3333e1e208ca200f1a5338a86e17bd92dd2d16af8bb022a7dc05b923d019e05247f1a0d0b4bfcfce58dd6d83830705707676d55739abee89fcd5cb94b8fde006a5da02df64b00a467f45970b5ca440f22319b9735a55d454b9fba0588fef0c59d3d83823eba6e0601a96e10233826c5adeea6b2a51d386a07a9e047ad405b23d4c3d89f30c31e3199f0c8f927bfac43ceea1f969de0a8c0f +TAG: b9fec6da464c7b85b2a4726694562fe9 + +KEY: bae06b9b5456707551c7b0e207aae02a19b4848ad8ca4ce40705bf8c856a6e52 +NONCE: 000000009c27065c3ef2d522 +IN: 50cdd88137ff428a88e87b5845be4924f6387537bb5c0b654c80107ab5698db75b2e131848e7aec156d31aed0766d31c379fece4095d38264c6d5945974d25f729c3b0ba11ea853e9cebdb6f03bb670fce08adff74d0a8f02d633fb34e0fb7337a8e66e1c12084d914fb6173b8105684db822752c6751a372bb16690284d661b8b8bc6a6dfbddf45ebc2219596f9f2f878c118df69030de38b4d99dde43b9b9e20a3dab691645dd518342f49b06a0fe0a397adf261e99f07af5b0b3798b1022ba0939c42a54d3b93641cffa3c2e174bce9ab7ad7e7c7924308d1a77a +AD: 5d5590db1bd316eb7a0e30e4c7a6dfdbef9d3287fdb8d824389599c3c2ee262b2192eb5b9708e66e22dbc7eca83fa1a995da3ce64c86fe5aa08b826d476dc439497e2d12e2702c63c8d27aa7f09fedee816dc8bffe1351d53271a34d4292b613b7efcedb7e3cf3e6ad389eef12471e9e20e38e7ae22a323abbadfe8f2e84271bffb1819feb4f77b82843cb8757cfae293631bc6d39669107e7015c85d7343ffa6fc1bbe6f5ab4de30cd752a281e03061ea89de2a3f5e90e20da22fd6e8525c100738667f42212b2cf45fcb23bbb54b21c117484b22c6e514685314df +CT: 66b7f69ac49fab4e5975aeb6fa9287d8eac02ac312c4de78f77f59da16cbcf87274e66801c4b862c33ea79cdc76528862bb2956c06db8b8acfac4794ebf39e35ac03cc73a4351a4ff762f681a48d6f25cad36e2814c9b5c40b9ae92509e58429106847789454d376836936bebc7a80e6c66e7aa52936d6b361378a41f849ad4e48f9ee2d3e92217a908fa8eb35736ac8ada7d32ae05391f2d807be3512543c36138a5fe660dd4cd4cd184bb43b6ba6bc0bae634e2fa9669304cd510ed5103f630068ff76d3375738de60a381842b421477e25a490cdd6894b2704125 +TAG: 94118ccc68de1921d480aab43d1ef0d1 + +KEY: 2cb374cb048c168f2e43597f028d9e73cade1b458284ffc260d4fc6b9011c414 +NONCE: 000000009fb909169bc9f4e9 +IN: 39eb929482784b463546f5d84f80510f2019923d465b99d194246d68c7ae343f91971d8f7059cebb86aa5dd099289aa648248b8c5ca04e66ac5e9bf06776e3883495397618a0227f035666806e636836b47d3d2d255a49db79866cf00d9ddabda259c4f968a1e01e651c7811cebbee2ee71803ea1d9d23487eb221f2d9555756800aba5e6abbefd6fb72b3151cc99ced599cd86df2a9b1ce94f89f347eeb124d9e7f0d9cc48d3dedd819e6d3dbac57ecee199547b266116a2035c9acc4c8ca3271ac74952372897c4a5f2cb84e2d81817fec9d6774f6d8a5b2021684132db4fca3 +AD: 0c7bd4f3a30ee944ccf9489181e6911684dcffad4593a9b65a67dfc80718c69b35897d01281016b7731e12c15cad8482e79458e08a755622e3f3f22a23ef6c8487a36ad1771ba06c641f06f85de0db3776cc6df06ad8fe3b4d60d58508de943083f17cbb9dc0d390ac94d8429e8c6fcfe063f424fbde0f62f6a7f91a626d195dc498a6e69bd93109c4e9ba13e7330aba456d710a4b0cc279d4045660406e26d61dff70d4a33c4f1052869f9248024e7a0f85f1effb32f6f7ccb1f860f3ef04e8f7b29096e6bcf9d4b3e0ce703e9bf228fdf515c2ff9cbabd16987be0f9babd3d8a +CT: 91ddadb86b7ebef798ddaa59da51d71316fcf6c9678143178227d778750dc9827fc6cc21e605c505023e6db25849df7fb6fc1ca4d223aa215f8c85b724643c83bf8218815a9f9e2952384e0ca6a80a3760b39daf91a3c6154c4728c2371fd181fa3764753d0b0c23808a82cd8f0497246e3a0f17f8906a07c725d2891ce968a9d432c2b102d85c05510b28e715bb60d0403a77490e7f18be81218bc4f39287b9bb09f50227dd2f55e4fb70c4438da8ba3c8ffbced87d90155913faa9979fc57e6cbeddfaba3d3ab4163c0eebc7d94279c27d3ed56338893dba542eaefba30f8c3b +TAG: 8980e8e4fe796428b733f4f8e1954a45 + +KEY: f0f16b6f12b3840bbd1c4a6a0811eef237f1521b45de9986daec9f28fca6485c +NONCE: 000000007ac93e754e290323 +IN: 0530556424d823f90a7f1c524c4baa706aad2807e289e9479301e3e7a71f2a5e14e6232ea785f339c669af2e6d25f1d5a261096a548d23864945c3a589b67b09b0304a784d61b42b2419139485242e0d51fcbe9e8fed996d214de8717e6a71f8987ccad65eb92e66707034a5ae38e6486e26eb4374c565aad5df949dab209f7f7bcd8eb6fc52761a26cfe5d01fd349e59f4042e6dbe6b232f9301b971dee121d8aa1e62d40f043a42f3aa859d867eb809b1ced5ae1ec62cacf94a69fafd0631a8b5dfd66d855900fb295eec90ae5fcbf77beae267a79d24081bb322d8c4e0630fed252541b36 +AD: 13bfcc17b810099cda31ca53a1323db9b07633ceb2088a42263a4cbd6a4d47978776005c9a20203319c3a3ae434e9a26fb541047dc9df38dc36c095267272e203d0b24d119a70a7e96041b6d82b7c4d5570e1e4a1cf2f6e44ae63fe005a1f5b900778c482f7bd89e2e02305e35b8f61b7bb2c78a13aebfce0145d1c5aa0bf1d10d23616d5a3a446de550302f56f81dc56fe4f3700f14242688d9b92d8a427979b403c8de8c493a2cde510eaf6b285e6675b173aa0314a386b635c7577d5aff0d868a0cb3f73c8d2005f8c7c9dab5a060ef80102c9d4a4af988838afe87aff04c0689e8c3c7f9 +CT: 2c14c3931e98e84507c4c165c2ed47ad4a178f0e216cd7ac2453bbbf9f85dd06bd8ef54a9ff1fd3dd8e0cafb635d8f2de861a0db5b14d03f17aaea8c89b3010797c71c13a0e666899d7ff6e53c4f08be8ddb3e37688b5afa088079b6c7519b833e16560073e699530302028a3496e05edddec01a23a4c7983956250e8d9e616f7b940856955cde81c1efabf6b7b92f153d03f4cd17e7f7d2907670cfc84d45c1d7936775a3fce47968504278ffaecacea0871b227f250e2979516f6fa310fec0d8df1af7872e5a534e82870aa05f43ef0a455846b93ce938064fa33e92de262e4156dae56775 +TAG: 16c972829819b8fb030b2c5f40dab717 + +KEY: 3792943c0396f1840496917ce8ad89608385007e796febeea3805f3f4cbeccf7 +NONCE: 0000000023b2f9068b2c4c85 +IN: be6b67eb943ee7b5c785cd882f653e73a8f75b4a41a2a7c56ae5a10f729caf39948fe48ad0e51240e2e7aa43193c7ec6ce7f4909fc94c9f99e38e6a0ad7e98eb29c5c2e61c99e9cbe890f154185cec213a74725d23c1a4e4d0cb9b1a36b78c87e5eee20d2aa29aae80d4759eb0c51c5dc3a95bdbbf7e14eb434419a6c88a954ac03d0c98739f4211b8732acd71c297f578b8cb64ccac45f7235ddc7f2a3f5f997525c1ed39dc550126cdf9cedaf55425489085e91b170be6205a5a395f2dd4084a3e8dbc4fd8b13252f7effae067b571cb94a1e54aba45b1b9841308db0cc75b03cfce4ddafe89ce20f2d1 +AD: 7eb6d7b7bbaaa3c202a4f0f1de2263767169eb4a64853240d48c0f8d5d31b08d5baf42977614a57aad99426cde76d242cb37d2956d8c77dc4fd62a3abf30e8ac6cd58c8ef35e67497022960138c57787818892460f3bfc16e37ff388b1edc6ce2bc53c22717edc7a03d4c78b0dbbe9121c7fd8a3e3993b87a4fe389bff13bdae3b349de0b6db561602c53f746022aeb4483c723b67825042f4af20b7dd1e6031cf54215266295c524ac8e1370424c5c5e607fb3e23e97c8eebe64656775edf616422a8b974e1acf13ab45c9a367a7dd9b2d62f48bbc05819b65eccb813ca813f57b22ee4c280dbb5a9d8d5 +CT: 0b316ab2bcf5359900fa4082d5d253b49ad94b70e3fab544f98bd111cbcef6766cf953deec08cae1f489fe12f7acc0032db8a6b0c0eee0c206ea5fb973feaebf90f690e840094db5e13fdd7157ba127368c995b426529435a1bcdd1f14ce9125b8a0e4c96b6ec09e3c36a180adf81941c002d19c19d53c2009be803b987504606b7d43bdee5e0b32ff23c466b6cccfcd0d4e88fd1332e73712b5ab725c1a383e584f34f80daff29d285ae5e43cf1d0cc7a828e75c25daced3a581a93d7a50f313b33f38dddfaa23cd5b9914797db820ee2400d52bf5fa982277fe9b5881ac42981633b3957b0e935051828 +TAG: c549aa944d6d97e52e0793ed572682c0 + +KEY: fe4be6054773f634356ac328591fbc6f833b0d1beeb38dd5b6feb7481b4489d4 +NONCE: 000000000b3f16f898a5a7d5 +IN: 76ced1ade6d1ef4069afddb32e7432d4ff2fd06685121f7b16464e7a72d365744f547d2ccf53486310e38b42d8bacaf711e54c5458d2d68c4dbcc8de31ab6732f4430e88a64565f5b287640775aaa2af1cc461d3e415bb275c6246b1b58517aa72667eae291a2982eda175d1b22c5a58e6fec2b3743d55712f201ca24ba5c0ae8c25724871b2ec2fb914a8da5a52670ab9b43a83b8568ce74db5c634061cb80530c8070c38b8f48c33ba136cb9f2158ee7eda8b65f2192fc94d1291f182f101795b7190c74b319d2d3e02a97c824d9c9471a83797e4936310b207e3a1e0bcf75f7c3e3ee48a747641cdc4377f2d55082 +AD: 834cd775cbefe4b33a3ca53a00c06a3c4a666983e4115a029f15729460daa45d1505e95172d3695625a186b28b8be173a925af04665f209267b3c5123e8be13da447ee1ae856bb0925f35aaa76e04a7bca8460f76c2024de2149f38a8cfba81694b854885d72568105571b6b213a0bc188a44cc7fe13153cbf261401b238cf12a95e23cb56f240114f16e2f1e3a514615aab4449c0c49e4d900b0e17d1a8dabb53d43dca32fa052d576b73dd9b40856b515d6d7efc2a5c17e0ebcb17bd59dc86f22ce909301a2652f134e82ef0e4519487ed12d51536024f2ae8f75d937c42d003076e5dea8de0c684cda1f34253d8fc +CT: f8defb6fe95dfec499b909996a1f75a198a90e4d6c6464d00a357a555311c42fe92dbbc4b79c935e4f0b1a95e44fdbc1380bebabca28db4dd0d2870daaafc38ef27908c3509e945714801cc51f1a07b2430c74fa64f2a7c2f7fd1551d258c9c3be020873fc1bf19f33ab6c660911dcf2317195d0efee82d20ec26d22611f9cf86c51a64e28b3a1f344500018e0855c88dae3c07acaeaa10b60388484dce93e16e6e1a6e69e899806648a92568c8780e9f4baacd98cbb353ac2f908e775d92303cfab843f15be0e0c322a958802fb1a60fcc7631f151f4c2b8cb965d2d296acef250275a2fecc0cea803ce7c058b12dd2 +TAG: baf9a51180f172e5c0cc2c946ce55055 + +KEY: a288b11ce5382ec724ce4ab2d7efa8e777e91ebd04367935e15f9dac483e9596 +NONCE: 00000000874144dbf648b325 +IN: 4c9195280a79a509919af4947e9e07231695fd7c5088539f23936ce88770ce07d9ad3ae4a463b3a57d0634d3a77ceaadf347a334682b04be8e58b8e86fb94a1f93255132b8cdb0df86f5bea354eea4e8315fea83e3fdf6e58aa9f26e93caa08e5e2551a94bd916a51fed29ec16f66800cda6a0aa24ec308bf5fb885afba272685de27c1edcdd3668048ef07b06e90d464a8aa28664903cac45e154e8e1e39c257e1ff506b9d95cef4f300bb73b899e7828602c3c1d290b8cf55ee5fd72ecce9e6efc9293aebf674a70e2a7673e75629c12950622dff71d3ec0992e57776c788c6927d30b4e24b749191c3ce8017f0ada6276e43720 +AD: 04abe8588c8c8c39a182092e5e7840442bd1c1149da102c4ee412bd8b82baa5087ef7291b5cd077c177c42770b0023e0e462b06e7553f191bcb0315a34918dcdbffe2b99c3e011b4220cc1775debcc0db55fa60df9b52234f3d3fa9606508badc26f30b47cdb4f1c0f4708d417b6853e66c2f1f67f6200daf760ceb64ffc43db27f057ad3ee973e31d7e5d5deb050315c1c687980c0c148ee1a492d47acfcd6132334176c11258c89b19ba02e6acc55d852f87b6a2169ed34a6147caa60906ac8c0813c0f05522af7b7f0faddb4bc297405e28ecf5a0f6aac6258422d29cfe250d61402840f3c27d0ce39b3e2d5f1e520541d2965e +CT: 0afce770a12f15d67ac104ba0640aab95922390607473cbda71321156a5559906be933fb0980da56f27e89796eaa1054f5aacf1668d9f273cc69071b9e8e22af6a205a6a88f7ad918e22f616bddbb07c78913c7e056e769e6fcf91c7600c2740212e3a176e4110cac9e361a59a773457064d2dc652dd115d04f1c3756c0e1d39f6737a16b4508663e310934c49c58058b3c7b9af7bb2334c8a163608c42499658986927cda365e2aead3ac29de16e47e954383ea566f8fb245a4e5a934c767bb3bf7e0eb8a477fd0e1f61bcb238462a0d19c5cea9293ca58ade76829413216a7882cd2846323046694f78cd8b0347792ebb75abdc1 +TAG: eb9b2ee43e9a3ae1e33561800169d868 + +KEY: 65b63ed53750c88c508c44881ae59e6fff69c66288f3c14cfec503391262cafc +NONCE: 000000007f5e560a1de434ba +IN: 845ef27b6615fb699d37971db6b597930a7ef1e6f90054791eb04ddfe7252b5f88fd60eba5af469bc09661c0987a496fa540621afeec51bebda786826800943d977039dee76235248112ff8b743f25ed5f3cb0d3307f5e118d84fdbb9c3f5531bc177fb84549c994ea4496c65e5249da987dd755d46dc1788f582410266a10f291c1474f732183a2a39afe603771bb9c423fe3e8906f2be44a0c9a7c3f0ceb09d1d0f92d942383a875c0567c7869f045e56dd1a4d6e90c58d44fe0c5760bb4fd01de55439db52b56831e5a26a47de14249453a4f8e7da3cb3282c6622916197ebfaad85dd65c61e7d2d3ba626276366746f396394c1bf75f51ce +AD: 51a3588398808e1d6a98505c6e5601ae2a2766f1f28f8f69d1ccbcad18038c157b41525be58ae4527a073748b7a04809e52a5df0c7988417607738e63d7ead47db795a346b04e740186e73ccad79f725b58ee22dc6e30d1f0a218eda1791e2229b253d4ab2b963a43e12318c8b0785c20fca3abcf220c08745d9f9602f0ece544a05736d76b12d249699c9e3e99f3f13cf4e5dc13a04125c949a5b30d034b23cb364c8781964bc6c30e5e5ca9673d517ef5f35965d8a8cf1be017e343df97b6bee37b30638b154286d1f36d2f9a0eaa23cc484eac5a05b15d9efc537d989dbc8b3106c0dc1a56e97e6aec2eff54a82cf7ae9df2af46b4c860f83 +CT: 027b14197b4012256b133b78ddc94e72fb4d724fefa4ae329f5a5fa3fa784fe6d7e1e805e3f7a75557de64de506d38237b467fa577efb59e7cfe2356bed6655c5aa4e238dcfeb75c16549a0917268768a96acb5e20546a1fb7e3a7cff887f49f2cd7a135f72a98a779150f3207bf733e88861fd79eadbf77fa3bfe97bfe8b6a991cb3bcc2cde8287f7e89384846561934b0f3e05e0646e0e1907770df67a7594161a4d0763faa6fa844080932159999d528ee0558710058ce16f97d13ac9fd9bf5044191188bbfb598d0fafbdf790b61ce0781ecc04218a30ded45efd498cc9ba03562ed2b4a993ee98876b3ab7a9bc07829f1c4ca6ead98c06b +TAG: e0bf9b6837428843f5a233ee5ddb8a1e + +KEY: 4986fd62d6cb86b2eaf219174bec681bebcdef86c8be291f27d3e5dc69e2feba +NONCE: 00000000d08d486620ed2e84 +IN: 3a22ad5de387db4fdd5d62a1b728c23a8dddc50b1e89f54f6198b90499f9da3122ebeb38ebf5fdfe30309734f79aff01e3de1e196b35bffa33bae451f31f74b8aec03763f9e0861a34fe5db0b40c76e57c7fc582bfa19c94ee25b5e168270f379bf9f8a0a18bed05de256f8f0dd7c23ba2ff1c7f721409462f04cc611ad9bd4c3c9acf30742acfb9518a6375cbb15d65a1bc6993ea434894f93d4f6e05996ebc1bd56579296309a2c6b8fde95072168b5fd31927c4c0abaa056bcd16221d5f220be47591f43255013a262dce439817f534830ba82155347e5fe3101f8011b89365a6568214ed0661914e8cb3431d6c8f2347dfc1209a3eca4aaf0a111f47fe +AD: 7dd3f656a03c001b45ca0680bc3ac9d68c6e96b591d3c69eb8c65e489009d845cb331c98b82e627e06d5bf01e74c573df268c2386f12628c019951d42f55991ff20d72a7b2c45f41d0be7af428c92f324aaab8df70d900301cdf09a3d93eb711c919d34a86fff9cb078322ee2e0ad48dbdf3b7884f0f2dc5c36262c59bcfd75ac6200f59c6fcd0ce10ff5005fef5df8f0432377dfbfc1db8f559e27e1aeef3380ea3864867d36a25a18654779a751586cad3b8a46b90864ee697b08605673b8d2123433c020a21c4db243dde2420c12fd4d54a2704a0c8c376454a1b5e80fd6db89aabd56d9b421f29649e474824dfa56cb5c673c504d10be52b53751709fe +CT: c40180afd53001663ff4834110f56e6b0f178cd3c0e7f7de5d0089ee41d8403ffb98e84922706544a344d7e2625b12cf66b9c966f9f57d7b94e3e4b34e6f0aaed1763ce012782e2f5e1682e6c343fc7961fedddd0919d0b910e9923c17e36406979b256b85aec24ee352f03b48c1302eab419c83dccc5372cc059e9de596224fa70098eb32fc9579e97917b923914fa2efc30ab29b457bf14e45583b3771486bdc0876f3ea6e1a646746c4f8c5cb2641a1557c8473e6ea67d4811a67485ae9a678ff3a2408ca845c3b51957e189eef47dfc1d46bde4b9d754d7df13f828ddadb06e4ebddb5f0dafbdb28de4c5e6078926f20cdf9e97ecd58e309e640f74f06 +TAG: 2e8eb9ff4467c0f61c2abf6ca10893ef + +KEY: 7d28a60810e43d3dfa32e97c07957ec069fc80cc6a50061830aa29b3aa777dfc +NONCE: 0000000047738ac8f10f2c3a +IN: b50278ae0f0fa2f918bb9a5ed3a0797c328e452974d33cbf26a1e213aa20c03d0d89490869754abf84dbbe231d7bccdced77d53fd4527356d8e02b681fc89a535ae87308bf7fbc26197a5ea85bdb3aa033b8da5cd197ea6d72f96f63b03f4ecc7adedf399a5043776cdb32c08f30b77f34df85f8adb8e02649a04b020b03e17d445ca63e4ed73ae432c481392e031eba2f9d2f7f981d1e50917822bd6ff71c239d33444ada3523a59dfbce5457eadec1ab926c9e6c5299c7521e3f204b96901a712504fcc782e8cea80ba12a7f7e71cec3d0871899b6ca059061da037715f7d13fed01c9cade1e687b4fbb1f4ac4b040db3b43800f112fb900e4f772d61b921cbce4da6f +AD: 324292813b7df15bc070cc5d8a4bf74ead036430be63abc43304cf653959a24a91c7de5a671c50fa8a87e21bb82b069999aadfb6895d8bda4c3083d17b8ca55b9ab1511ed8c4b39d8c28c11a22ef90c08a983e3fe2d988df9e02b16a20b24f39ddb28429625f511db08298c4dc321f6c268fc836a6191df6232f51c463a397a8d8b33374abe94e62c0f5c322387e1fc4a1c1980a04a1a3c2c31b32f183a11c3268c6dca521149dc16af120a78be6627210e8ddbc44472bc24d66ce3681c7579b3d9a425212a704a4f5105cb80f0d18ee860953d10b59c114826779bbc368d7a0eece9f223e47cd8e5fd453607d101d9d9c2bd9a658d6520b87d7b4263f6d845a524a36e4 +CT: 2c217e969c04740a1acfa30117eb5b32dc573df3354f4cc3bf8f696ff905f1e640f3b2c250473b376622e0c9bda13b94640521be1ef0fc660b4c10dbe2bfc093030753e04f6aaecf813b43b61f960455974b8bb8a9b461d1e8fd3802315e863c00448f24dd38deb90e135493274eb14ccbde15c50dcad734ed815a806be6622492a84cd062e3ba567b909a205a1d0d2bedd40169697d261c7b6c2e0b1f069853fd470e8f364a142c386c439a6dbe192ded5a3d0fbf73799f588c59e58c60249d980ddcf0d9693631cd9b3f972509c3a77123d38d9e267ecad06e1208e3f1c0a69fbca7c3bb1a48fda19493d0f8f48398820057b94120f3ef97d87e9e8a1b301a2534c68f +TAG: ce507bdb0c71f8e89f5078495f7995b8 + +KEY: a76e9b916f5a67b78a5949651c8c3a9741a1bc3c41cdf85fd2c8f3e9a0616098 +NONCE: 000000000808da8292dc14e0 +IN: 9c149eeb09345c3c22462b03e49eb4dba6bc98b269b1086d752bcd8eea53b8977b238a04a994baf915591686baab90b79a3bf7d9adb2c6c2e31acd3e72f0813fb745aa5fb2e3da408f78001c9c09bd26a1a2646011b6120aaa2bbacc4a16c39fb5257b9b2ea2ad8bf70bcc9855cf11841116c2767310cf3cd49d1aa44cd505f079761e064d5bc7cea4a7173b086882a77d3fc179efc86fc4db8a373491d2ed81eabc63c950e832db17d09f474d4ec46bde47830caf26fabaa0372b81fccc449c0e19ccd630caf693a7b43bb1c408a54e03f50c44280a05ad89fb6e8f01d8ac278edf556e5d86ceb4b614fb2ef133819c6e1ff6abb86c54a135256204b5cd400b93624d3932e7c2b046 +AD: 6aeb7031e4a2e23eea93f05fdc562aa2bf43b8998bea7344377aaddc60fbdb7bcb1491d379ed0cb613ee757cfb66490db61bb431d2fad34b38ddd55bc5b22aa6c4773b9992f34b878c5663f6e8cdb5f80a17f4d312bf342492e48d1ce4c6d754076a634fece61500acf8168d47381af4faf980c6cac2bfd5da8c09b6edb0f543bf0fe02643e38d73fa37d8ae87fb66193f22e57faf4393c007d48c8631a685d520578f8f89db684fb371ea02f3a58b1e2168f0216321139472e0d03b6d90ba8aab65402e1c1ac4f9172a60e27e3d997b9b05e2f672120d6c87bcafa6d4c9b4cf8ba8a82932d92840368fc53dc5b48526103dcab5f1531038aabe89171327ac559b98a3cf4ea70bf051 +CT: 9c3faab9261a63cea9477b3269007283995b06ba77ef83d9e693f7e4ee9855550eef94855be39a7a435b6a3584b202973777c7b2482376ba47b49311947a64983b60236756ee4455d4cfada8c36af8eb06b06ba2f6b79ffb1185c89f2b2a831cfaa3855fc1841d8910908be5078352011168a67d36372d851a3217cabf593ea462dcd325cf9a4f67e85418fd5c924e9b92ab026cbee4e7ab1067066cb5949dfc699a68fe539e1abb13cec33904e5207e6963d24f5a0b770613b8b00014e791bfff88f9c25ca126127a2f8d1d1e9794efd28dce98b53e228073faae8d5047530d502184fc341321c3f55fcbf41187fc31262c325b97f519959b6a29b36c71f76f60196bb1457b77c8bb +TAG: 73b00b1705602479aab944dcc1b282a2 + +KEY: 98cd2477a7a072c69f375b88d09ed9d7b9c3df3f87e36ce621726f76e3b41a1d +NONCE: 0000000077d185aaf715aa48 +IN: 42b31eefdacab0f03ef6060156000c8195adb0976cabbe1a42bfcc09f85659c60b98638401f2d2e2facfb9a97a62926bb0cecaf3af0180a01bfb6e576babf7fc43331937a92abd30cddfa3e450f895e9dd914dea3fafd759c136d685310ebce28ac0613ccdbf30115946c9634b67510b77d0e37f07714b2ddac9d7095b8d4bd887c132c4a9127eb01c8dedb4c39c87b98a741316656f9a8d5a5b0c0ac84789aa2347a5f99ca5ad55cd1bcf98f703eb4b00badb8a8555f38b3b368db8ba7ceea94e8b219f51edce75d84166b5602156ed5962a93a51db73c59d87e906179d7a74a2a2a69d8ad99f323225c87e475d3f771b4a203a2e2b03b458401044649fa6536dfab24d7037807dcbf6518e6578 +AD: f5bb1496052a4361dddf72a288e36953a3d815d6876c013f1d6ba839e127f721b052b1f7d8ca20c7dc0386a7d459ebd7eb9fc8cb08941e6ca9ddb980f3115f65bc1928a414d441ae71dcb879d5bfe0cde0562bc37f8fde0d5291ad405c92fcbb860c43b55ac0fe663b54b3d0616aca13a5c82b7b5d34125a05c2acb5530141030e6f2aa0c8322b2c8fa307e7518918e550e9f48921c6168f094d8758e16b9f815fd0458095c4143f0922adb1840d0e685636825a9c90ee90ee537f4b8dceecbc4287c82dc9a00d7e51671e37ea284ee3ca501b1b2596459d3f592f70186f41125739e342c9f6be9241973b1414dfe5fb8cba1af82e679278cfcf95420df0c5364af4d7e72ad57d5c871fcbc35462 +CT: 7a3bf3e3ad5ae3ab71fb1f7121c3d8fb511099484b50af7ca128ee0337ed4b828dc4cde0b88dc1e8089101fa82c9beb3eb48fdcf0f5b16da441f5a3fce9a590022af95a94aed6a3e71e505f60f303c78c356f274ea85a55354078530664ecda32c80e77dc20974b3b38f4825b8fbee8c3970769a2f42c5181608a8d7d76ef4d093961b665ee42b9708fcafe2c82d3a307173e2a25ad2528c3bf83352b9265e45b70722d7cf8c9b80826d21335234ee3db69d0d37871c83222365900c96c17a7e9f5742d0bfe383be24d0d44590d4b0f29f7abe0c65daaffb968b3f2657b1eb300534eacb52ec7a6b6f9f57a50a91b1799f491361cf613c934b7f520dc4eeeb40ffc45e10be0a95e76f366d4eac14 +TAG: 69302888812eea030d621b640e7bcf7c + +KEY: 2f0f4631ab1c1bcf8f3ad0559c818d50e0af7d8cd63faa357f2069f30881d9cb +NONCE: 000000007d0ced2fdb1c9173 +IN: 6516ba1d29357144eebfa486d21decf223da3aa76ec29bbfcbe7f1eeaf4a847710e5080177f7e5a7c8b4752c219b1cc70aef4db861ba67d0fa6222d9f4a1dc756a0ba44e62906f9374a960c16198866d867854d88f528a60e212eb91645787e75685b2e215c0a41990abc344a77236ec0186ba63a664592938cc5a8ac1d3eb99c95ce00e19fbe249263083d85b052d48bfdffc01585dc57bb2a2c6c4a819604c1ec0548c6f0f78dc05e4418b36277dc07233c7532f9c289d6aed0cc6bc7df4fd0a536c497b982e2dad2c30d2db1c6545a845c5dfa83a4ac49ef06fc9c919079d3e299e31b5c3be370814ae5022ae469d3ee55246a41bd0dc4e64351cc38c3c09af0a1aee3b388a6892deff0df3f93cd92d722b +AD: 1ccfa1ececc8de1e200d0ecc19dcf67b7c96bea3a282c2bccba61035db5c14776387b8b8f58e5757deb0129d4e5e315f64df354a5985d2e47ebbbeafe0c914f7cf1d63dd0311ace19e69a8b6ff0ab25cc8df0408d22132205e89e5eb679268d82b2913e64e3f885bbf4a6d379b760b94590e3140dd7275ab4713cb56d0b716e2718f11316640cb394802862d39e77a46d0c065af3caf7dec14e887039d8aa8c3d3a8ac1ee06026f49d00b2f59d971b54735e95a51f199389a93a4fc24ebaba1f7a2eef7412f61febf79084fbf481afc6fb6b204084e5ef5df71f30506459dea074f11fc055cd2a8c0fc922c4811a849984352a56a15659b7d07a4cc90b88623638ea00c4c8bc13884df2237b359f2877aa41d6 +CT: e580093789ba17ffb46672dc326f09278aca08598d3e5458eaa53e6ed45d5c71a396e35b5ea3fe7b7c0496a734d24f1c75420694be2ff095d5172fd3407794e4b99fd7c374fbe8d1564a048614d3f355bfb5866de1a53e1a51f9f5e8312253cfd82f36efaa1898c850ca0d975ad1e8b0d9597a5a9e6516fe2a3c92efb7495557a8afc3da15b0d3e2ba58f612519836946cf2d15b898320d16a026c8c00a1be2e35f0ebe68f28d91c6c45d24c3f3c157cb132fa659b7794df883d90741fa2d2afcc4f27858e13ecd41b154a35d24947ae7361170060c107d8ecacb393ea67104b60457278a392fdf1794bab97d3b02b71a4eb015eaa38a4b4c944c2bc7cd5e329da4a1ab2937a6af81a6caa5fce752331fdefd4 +TAG: 19bbacfac768bb0ce71e39c5d4d3e9a0 + +KEY: a48b9b6df475e566aba7671fbd76772cb0eff0b12499967978ce3e25fac92feb +NONCE: 000000002ccbf0d6c40cb302 +IN: 09da1cacd001dce4f7573a065a4406fe0da04ab367a2d87780a2762e168957a88d3fa78f0a4b6978d449026e5a801d32884b6e14fdaaaf864214f928ebc03dead081fee96683ebb032362d5088c4c2a3b1e242f055f2604919f4dd551db777a258cf9da6d95a2bde249247812b9efc7985cf08707620808524d6dd3079b0b63bf0f71ea5de834ccb8b7c6a97125fd6ca49148e866d3134bbf1d8a6b714e9a80fe549c8bfefe342f41be2ba2300e0028f78cefab65274632dfdbe70bf7d655ec4036df561f2d4fc4d56a482bbe2f9f2ae279b3aa216b39afee75e53602de319484db89a51e844f38c361634e474f8f1f01c340f3f3594860d671346449c6d08ee38de22d246309bc7e4a252a29c86aa6d94b5b4fa58904c70 +AD: 1c2503d5aa1aad193f0da12874074ea0432bb76a61cd43a3017061514da0759846a0f3ae3a49fdb0b6d29f713de665beacb6568f2694112ca380d13f3c1698316866a7a7f87f1d7503a92176ab84fc08977b46ba664508a858e7525753c45511b3d2f407d5e993c6ede77f13d12975707e5195704970a89f71fc30828049f92f944f3aa93d6a5297e678e08952919beb7eac5919df1919cab3c3da6aa696a1eeab6371f310f7e81143e7d240b0213ae554524b52000306160dd4877bf13ba0f13bbe867da7c7d707f31335eef4cd942938ac890a0829ec66bd30ae01a2188a6e5ea0f17cd7dc875e17f03c0ab5dd18e36db8a1fc1f72859ee046b62368f168b3bea2234e0432c07b7d8e1b9277f21e692c513b9e816e6860 +CT: 7d35cfe4be56bd6e0e09dedcd01735b915bc1891a4d1f6a541abc4bcd0ebe89dcb8e365e5813742e8ec65777b6159422fada747da99394252baf8a046fc1b60ad79755f545f4448627b7acaf403000894f5641e78d3f946dfca29ec617f0660dcd6e8d8827e67e1022a245c595d86e60fbd176bf721b171bbe5ecaf4ae671b9f3dd3920146e6ad431bd8fc431820e19454b6ca209723d80fdbee187fca9c937c979206ae97be55f6ba7366a5608770a11d537396485eb0a66586385f4d4cf3905d1fc90831c3e136d5d513fa22be285193142994a3ed477145bacdcbdd791e8b3b88b0d4f1d18b27382550a818c4fd8884bf36f677c6c3ff5677406e510911e696af75e5b3f859bef699bdd16e6215fdb98d874025eada50 +TAG: 0fa4cb2bab84336409aa4349ab99a8bd + +KEY: 923d4b086b9e43b986f7b65e4cea6113a3d8aabefa89323c5e4d5b6f158bb7e0 +NONCE: 00000000a0f73297b87f5deb +IN: 21435e8d5c8edf0684f58c2cba4070c10b4801adf46b6c4d322eb3990a38a9ad338ad704b9df6597f3e68d66cd5b56290c8466db2231e56d6bcb9c44e1bd081f42ca2a894dad369df2bd0d2c63d6c881732d6ea22bb22b5bc9a62eaffa1b094d0845f6b966d2cb095e7b3b8bcbc15e707449d35c8df4aea30c3b7243e977fffd59c80f1c5c9af4bb5a54b9c786fbbe8d21b2b906a87a786caed841a34a3e0cc0ac3209d83c58afba19edd63622dd261532d2cfb0b49d527d8eaa0887a087f5129d897f665264b229f860363d71a88b7d49c8dc6360182b357b0662391bb41337f46010ac32b9fada2d60a2efcb99365d3b27b7ac396900d1c821d0df8b86cc9cc1f2673259a33efea610bf8e1d00d7e9db2afea21da8f58c55f799999d +AD: c853a8b39c0dc597d562f123cd221e4104b65423a062a4f4ba890ba344feb84290f61817e23330c365f58c3583ce08360d3c1171982ead5496d525ac878f23a57480a6ee39d4e65afd6268245bb982a2545fa1195427cdbbcd404cdad5198f55cce2a5a028fae435f71b15921d066e8d43766c32b2f2c3f57c0674e129607dcd3703eca529414adaee79d81fed432153cceb6f3fc53404810d8ec878f7d94be5d379d0e0e1aa9bc404b4b5d396038a9d76a5ce53c9f3759b8e50fb331858ca58cee81bfc3ee58baef5d19c402a3dc8b36370ec1ace5a4aa2527fb94b4f933a4ab8ccaaf6a5af5a779eae5667c2a24ab027e781c8d4f30c377aa5885a2fdaf6507d18cd824a847c35368b4ea984d2c3c3824a5b8ba3042e1852504a21a3 +CT: f2e21052eebbb86a4f5e803360855d8632aa727dca6f5e79dd74d7aff106e442001928d113005b030f8446f8eff2ee951db663978abe43090dd5ad2c51ba97a0ecf988c607d95e486d02524f690fa3c28d5c48c1f75c1f555e7b43fe7e46f2ca2b9fdb408ec4ba18b6cdde2af673183cb7b1a3c23ae77eddd4cac75e1ea14743fc571f8d31ce2e96787524cd48aadaa474181c096a032184574ddc25a6e0ac8441c212bc36298708e33c963ae931e6c6241d1affeef7b6ef759495df44b6ab647447693cf703569e69aa72f1def9a342b8978c1edea9703a421ca75b92cac4de14b88c693200022b8a2ed22b1c4678b99f4d695e080dd1196d7168e14f0d0f8ff880d742e97b9f6d00af1f7118e10b77c5ef3ea6c52f84a20fd6ea46dc +TAG: 9bd8b7743c056bb2334833afd6143e18 + +KEY: df73adab2768559ea983cce85453fe81d79be3b3c57f202b31b94d6635cf2e4b +NONCE: 00000000e7a87e6bf6b5a354 +IN: 0032a37abf661faa18c587fd2aa88885c061deeba81105dd221969bed5d59c7204b09b1a8c4c8de3b9f748c7fc70626ebeaca060233a57b102221b1bf0f3d9fdaaad3d2b1439c24d08f9c67f49f3c47128f92ee530abf4c4f4573bc60ae4b38109f55bca3ca9e1ba9f9fd6e34ba0d174892977a53356e1f5c88c614fe3ff3b3dd0818e7a2285412e3b37444bbe8a80942efcfd03958809a6966cda9430b2f0c9e552f4bced6e19eb3e85fc5758bd7b588297ccbed37ed94c3adc8c08ea8b058462aac9d57a939ec711bc4ecfec944d2b653b7cfc7b02a65d7057c9fdadd51b9da8cc4a3c68dae9da8b9c5319c1a2baa3d6c891c5ac4a39461484b5a01abc64df447ada24c04a4363e605eaccf339a9aa515e724206206da6d22bbd2f52e64cd7c895 +AD: f833e5ab4f8bc89167f80f576b1d6b22cdd0e30721f5f735799746cf645b6eff531d4c7b03584f3dfcb73cbd35ac42736216dc7f0de098a4f42c61ceb4b227ee288e47d697a0a76afc762f084e8fdbf9351c28340c324771c109a469341ab10ca10483ed2af5e878d7d3dc2bced2f72da3d1a25852b103ee9878e8158eb4309c1ce528f3a178ace153b6d3ae0af0d577cb3cb1540489e80427f792217ad8a09b84f027fca7ceb651b4264e98e94b4cb8a37b133390897233e8ba9103628d05b9609e8552c4a4b11e3f2fa8d56af36957390e88cba44656be3edace798cf8cdf7771bac338a256bc3cba6df97728f222f423ca7c6d149c9372d66163a98f79a234b00d4b75fb2ec860dcc2d1998105e4b9c01d68f079f3e0aa21cc534047fc7b858f8 +CT: b842eadfdf431c135bd6581d3eccae54e2267d8890036aa33dfe2d2d9715c44625441210a3a0d666d708d30588fe851ec36e10d8fa3584ed77b095149494b7c54379d62c8935e1d2b9a8f47e4759ad0b3437fdf2cc2fb6c5ea25ad10e0bdc9dc5b0517fc237eb783cc461c46665e2b1d1a5b8008dbf409ea2a63fea0276de23a32c99d92a498807a0f95e208fc6262321a78aafaf0cc3f833fff37bd4efa66f6023a25cdc6702cee3912799563d908a5183c9956a06aa71085d855dc7c809ed6e2889592b361ab3ab39060f8e419152187a794a19c2a1128882201900ea2cd597860674bf78d9720643df8701676718fd201baed4935a88e50558daf86edd08a9ab227ac7afae55c974b68de8dacad4a4d79b13ed6dfe74017a4cb9148e033436fb6 +TAG: ee1ec36804e1d5cdbddb52608c711fd8 + +KEY: 55a4be2448b464c2ea52a2f2664ed6aba865c14ea1fea77f4689331fd105c8d4 +NONCE: 00000000db37c0a405b4626d +IN: d266e66272e5d3462081b004cb42429c8b9741e9f678153754d726f6f9aa513464763c5e793b482fe512fece97585f1426120d4cefb3d0a8cc0a8db4bde93fc72c78f44d4fecca14650c660d3e285b327e7cdd813063e7e867b8a2d059a41bab70432b7f857199894da90dca3fe5272bae1ec694a1a07b60b05df275784d4975637e4673109f3ba846dfd1a048b202ed8e89973be608b91ee4743b1e759900f1443038951fe6189e806638985f3c16338c3c60695df58e621154d79bb973859c4558e9dca90470f77c73f004443ad5db0717abbe43266f90e57397b83ac34d1fef2e897e2483d5bcdcb627abd64b0d1aef525835f25e76d6e9158232cdde6dce970b59f58de8a98e653be32fb58edabbcefa5065d73afdf1c9c4fbf50c1022bd22bfcb98e4b422 +AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813bf5c501ad31e5d791c4b5b3a0a71b63fdddcc8de4b056064ef467989ecccc5d0160d403bf3a025d4892b3b1de3e062bc3581d4410f273338311eb4637529e4a680a6e4a5e26e308630a5b6d49ead6d543f8f2bf9050aa94ce091318721e1d8b96e279f34b9759b65037bec4bf6ccda6929705aeeeebe49e327e4d7a916620c9faf3765120658af34c53fbb97ec07657b3f088fcbdc401aa7949ddeda34d885018c2c23f4f0bb8218bf0d4fc90643658b4d8834f4a8c08e590c2a790995baa9e77627c342d283e454f84fcc05be15e9627a2d9be340c9d72f222bbdfc47905f56616cd9f936d49e4732f319f020513340fb8b22828db251b102b6b137c9533936d6 +CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f +TAG: 296a397d280d026fc3627f4718971be9 + +# Tag truncation tests. + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c2 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f3 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f37465 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a8413 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a841386 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648a5 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648a591 + diff --git a/Libraries/libressl/tests/chachatest.c b/Libraries/libressl/tests/chachatest.c new file mode 100644 index 000000000..4e1597461 --- /dev/null +++ b/Libraries/libressl/tests/chachatest.c @@ -0,0 +1,509 @@ +/* $OpenBSD: chachatest.c,v 1.6 2019/01/22 00:59:21 dlg Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +struct chacha_tv { + const char *desc; + const unsigned char key[32]; + const unsigned char iv[8]; + const size_t len; + const unsigned char out[512]; +}; + +/* + * Test vectors from: + * http://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01 + */ +struct chacha_tv chacha_test_vectors[] = { + { + "TC1: All zero key and IV", + { + 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, 0x00, + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + 64, + { + 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, + 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, + 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, + 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, + 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, + 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, + 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, + 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86, + }, + }, + { + "TC2: Single bit in key set, all zero IV", + { + 0x01, 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, + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + 64, + { + 0xc5, 0xd3, 0x0a, 0x7c, 0xe1, 0xec, 0x11, 0x93, + 0x78, 0xc8, 0x4f, 0x48, 0x7d, 0x77, 0x5a, 0x85, + 0x42, 0xf1, 0x3e, 0xce, 0x23, 0x8a, 0x94, 0x55, + 0xe8, 0x22, 0x9e, 0x88, 0x8d, 0xe8, 0x5b, 0xbd, + 0x29, 0xeb, 0x63, 0xd0, 0xa1, 0x7a, 0x5b, 0x99, + 0x9b, 0x52, 0xda, 0x22, 0xbe, 0x40, 0x23, 0xeb, + 0x07, 0x62, 0x0a, 0x54, 0xf6, 0xfa, 0x6a, 0xd8, + 0x73, 0x7b, 0x71, 0xeb, 0x04, 0x64, 0xda, 0xc0, + }, + }, + { + "TC3: Single bit in IV set, all zero key", + { + 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, 0x00, + }, + { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + 64, + { + 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb, + 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80, + 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac, + 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32, + 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c, + 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54, + 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d, + 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b + }, + }, + { + "TC4: All bits in key and IV are set", + { + 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, + }, + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + 64, + { + 0xd9, 0xbf, 0x3f, 0x6b, 0xce, 0x6e, 0xd0, 0xb5, + 0x42, 0x54, 0x55, 0x77, 0x67, 0xfb, 0x57, 0x44, + 0x3d, 0xd4, 0x77, 0x89, 0x11, 0xb6, 0x06, 0x05, + 0x5c, 0x39, 0xcc, 0x25, 0xe6, 0x74, 0xb8, 0x36, + 0x3f, 0xea, 0xbc, 0x57, 0xfd, 0xe5, 0x4f, 0x79, + 0x0c, 0x52, 0xc8, 0xae, 0x43, 0x24, 0x0b, 0x79, + 0xd4, 0x90, 0x42, 0xb7, 0x77, 0xbf, 0xd6, 0xcb, + 0x80, 0xe9, 0x31, 0x27, 0x0b, 0x7f, 0x50, 0xeb, + }, + }, + { + "TC5: Every even bit set in key and IV", + { + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + }, + { + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + }, + 64, + { + 0xbe, 0xa9, 0x41, 0x1a, 0xa4, 0x53, 0xc5, 0x43, + 0x4a, 0x5a, 0xe8, 0xc9, 0x28, 0x62, 0xf5, 0x64, + 0x39, 0x68, 0x55, 0xa9, 0xea, 0x6e, 0x22, 0xd6, + 0xd3, 0xb5, 0x0a, 0xe1, 0xb3, 0x66, 0x33, 0x11, + 0xa4, 0xa3, 0x60, 0x6c, 0x67, 0x1d, 0x60, 0x5c, + 0xe1, 0x6c, 0x3a, 0xec, 0xe8, 0xe6, 0x1e, 0xa1, + 0x45, 0xc5, 0x97, 0x75, 0x01, 0x7b, 0xee, 0x2f, + 0xa6, 0xf8, 0x8a, 0xfc, 0x75, 0x80, 0x69, 0xf7, + }, + }, + { + "TC6: Every odd bit set in key and IV", + { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + }, + { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + }, + 64, + { + 0x9a, 0xa2, 0xa9, 0xf6, 0x56, 0xef, 0xde, 0x5a, + 0xa7, 0x59, 0x1c, 0x5f, 0xed, 0x4b, 0x35, 0xae, + 0xa2, 0x89, 0x5d, 0xec, 0x7c, 0xb4, 0x54, 0x3b, + 0x9e, 0x9f, 0x21, 0xf5, 0xe7, 0xbc, 0xbc, 0xf3, + 0xc4, 0x3c, 0x74, 0x8a, 0x97, 0x08, 0x88, 0xf8, + 0x24, 0x83, 0x93, 0xa0, 0x9d, 0x43, 0xe0, 0xb7, + 0xe1, 0x64, 0xbc, 0x4d, 0x0b, 0x0f, 0xb2, 0x40, + 0xa2, 0xd7, 0x21, 0x15, 0xc4, 0x80, 0x89, 0x06, + }, + }, + { + "TC7: Sequence patterns in key and IV", + { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, + }, + { + 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, + }, + 64, + { + 0x9f, 0xad, 0xf4, 0x09, 0xc0, 0x08, 0x11, 0xd0, + 0x04, 0x31, 0xd6, 0x7e, 0xfb, 0xd8, 0x8f, 0xba, + 0x59, 0x21, 0x8d, 0x5d, 0x67, 0x08, 0xb1, 0xd6, + 0x85, 0x86, 0x3f, 0xab, 0xbb, 0x0e, 0x96, 0x1e, + 0xea, 0x48, 0x0f, 0xd6, 0xfb, 0x53, 0x2b, 0xfd, + 0x49, 0x4b, 0x21, 0x51, 0x01, 0x50, 0x57, 0x42, + 0x3a, 0xb6, 0x0a, 0x63, 0xfe, 0x4f, 0x55, 0xf7, + 0xa2, 0x12, 0xe2, 0x16, 0x7c, 0xca, 0xb9, 0x31, + }, + }, + { + "TC8: key: 'All your base are belong to us!, IV: 'IETF2013'", + { + 0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78, + 0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35, + 0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb, + 0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d, + }, + { + 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21, + }, + 64, + { + 0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9, + 0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06, + 0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00, + 0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf, + 0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd, + 0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f, + 0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f, + 0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92, + }, + }, +}; + +#define N_VECTORS (sizeof(chacha_test_vectors) / sizeof(*chacha_test_vectors)) + +/* Single-shot ChaCha20 using CRYPTO_chacha_20 interface. */ +static void +crypto_chacha_20_test(struct chacha_tv *tv, unsigned char *out, + unsigned char *in) +{ + CRYPTO_chacha_20(out, in, tv->len, tv->key, tv->iv, 0); +} + +/* Single-shot ChaCha20 using the ChaCha interface. */ +static void +chacha_ctx_full_test(struct chacha_tv *tv, unsigned char *out, + unsigned char *in) +{ + ChaCha_ctx ctx; + + ChaCha_set_key(&ctx, tv->key, 256); + ChaCha_set_iv(&ctx, tv->iv, NULL); + ChaCha(&ctx, out, in, tv->len); +} + +/* ChaCha20 with partial writes using the Chacha interface. */ +static void +chacha_ctx_partial_test(struct chacha_tv *tv, unsigned char *out, + unsigned char *in) +{ + ChaCha_ctx ctx; + int len, size = 0; + + ChaCha_set_key(&ctx, tv->key, 256); + ChaCha_set_iv(&ctx, tv->iv, NULL); + len = tv->len - 1; + while (len > 1) { + size = len / 2; + ChaCha(&ctx, out, in, size); + in += size; + out += size; + len -= size; + } + ChaCha(&ctx, out, in, len + 1); +} + +/* ChaCha20 with single byte writes using the Chacha interface. */ +static void +chacha_ctx_single_test(struct chacha_tv *tv, unsigned char *out, + unsigned char *in) +{ + ChaCha_ctx ctx; + size_t i; + + ChaCha_set_key(&ctx, tv->key, 256); + ChaCha_set_iv(&ctx, tv->iv, NULL); + for (i = 0; i < tv->len; i++) + ChaCha(&ctx, out + i, in + i, 1); +} + +struct chacha_test_function { + char *name; + void (*func)(struct chacha_tv *, unsigned char *, unsigned char *); +}; + +struct chacha_test_function chacha_test_functions[] = { + {"crypto_chacha_20_test", crypto_chacha_20_test}, + {"chacha_ctx_full_test", chacha_ctx_full_test}, + {"chacha_ctx_partial_test", chacha_ctx_partial_test}, + {"chacha_ctx_single_test", chacha_ctx_single_test}, +}; + +#define N_FUNCS (sizeof(chacha_test_functions) / sizeof(*chacha_test_functions)) + +/* draft-arciszewski-xchacha-02 test vectors */ +static int +crypto_hchacha_20_test(void) +{ + static const unsigned char key[32] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + static const unsigned char nonce[16] = { + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x41, 0x59, 0x27, + }; + static const unsigned char result[32] = { + 0x82, 0x41, 0x3b, 0x42, 0x27, 0xb2, 0x7b, 0xfe, + 0xd3, 0x0e, 0x42, 0x50, 0x8a, 0x87, 0x7d, 0x73, + 0xa0, 0xf9, 0xe4, 0xd5, 0x8a, 0x74, 0xa8, 0x53, + 0xc1, 0x2e, 0xc4, 0x13, 0x26, 0xd3, 0xec, 0xdc, + }; + unsigned char out[32]; + int failed = 0; + size_t k; + + CRYPTO_hchacha_20(out, key, nonce); + + if (memcmp(out, result, sizeof(out)) != 0) { + printf("HChaCha20 failed!\n"); + + printf("Got:\t"); + for (k = 0; k < sizeof(out); k++) + printf("%2.2x", out[k]); + printf("\n"); + + printf("Want:\t"); + for (k = 0; k < sizeof(result); k++) + printf("%2.2x", result[k]); + printf("\n"); + + failed = 1; + } + + return (failed); +} + +static int +crypto_xchacha_20_test(void) +{ + static const unsigned char key[32] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + }; + static const unsigned char iv[24] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x58 + }; + static const unsigned char plain[] = { + 0x54, 0x68, 0x65, 0x20, 0x64, 0x68, 0x6f, 0x6c, + 0x65, 0x20, 0x28, 0x70, 0x72, 0x6f, 0x6e, 0x6f, + 0x75, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x22, 0x64, + 0x6f, 0x6c, 0x65, 0x22, 0x29, 0x20, 0x69, 0x73, + 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x41, 0x73, 0x69, 0x61, 0x74, + 0x69, 0x63, 0x20, 0x77, 0x69, 0x6c, 0x64, 0x20, + 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x72, 0x65, 0x64, + 0x20, 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x77, 0x68, 0x69, 0x73, 0x74, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x67, 0x2e, + 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, + 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x61, 0x20, 0x47, 0x65, 0x72, 0x6d, 0x61, + 0x6e, 0x20, 0x73, 0x68, 0x65, 0x70, 0x68, 0x65, + 0x72, 0x64, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6c, + 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6d, 0x6f, 0x72, + 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x61, + 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x6c, 0x65, + 0x67, 0x67, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x78, + 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x68, + 0x69, 0x67, 0x68, 0x6c, 0x79, 0x20, 0x65, 0x6c, + 0x75, 0x73, 0x69, 0x76, 0x65, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, + 0x64, 0x20, 0x6a, 0x75, 0x6d, 0x70, 0x65, 0x72, + 0x20, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x77, 0x6f, 0x6c, 0x76, + 0x65, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x79, 0x6f, + 0x74, 0x65, 0x73, 0x2c, 0x20, 0x6a, 0x61, 0x63, + 0x6b, 0x61, 0x6c, 0x73, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x66, 0x6f, 0x78, 0x65, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x61, 0x78, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, + 0x20, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, + 0x43, 0x61, 0x6e, 0x69, 0x64, 0x61, 0x65, 0x2e, + }; + static const unsigned char cipher[] = { + 0x45, 0x59, 0xab, 0xba, 0x4e, 0x48, 0xc1, 0x61, + 0x02, 0xe8, 0xbb, 0x2c, 0x05, 0xe6, 0x94, 0x7f, + 0x50, 0xa7, 0x86, 0xde, 0x16, 0x2f, 0x9b, 0x0b, + 0x7e, 0x59, 0x2a, 0x9b, 0x53, 0xd0, 0xd4, 0xe9, + 0x8d, 0x8d, 0x64, 0x10, 0xd5, 0x40, 0xa1, 0xa6, + 0x37, 0x5b, 0x26, 0xd8, 0x0d, 0xac, 0xe4, 0xfa, + 0xb5, 0x23, 0x84, 0xc7, 0x31, 0xac, 0xbf, 0x16, + 0xa5, 0x92, 0x3c, 0x0c, 0x48, 0xd3, 0x57, 0x5d, + 0x4d, 0x0d, 0x2c, 0x67, 0x3b, 0x66, 0x6f, 0xaa, + 0x73, 0x10, 0x61, 0x27, 0x77, 0x01, 0x09, 0x3a, + 0x6b, 0xf7, 0xa1, 0x58, 0xa8, 0x86, 0x42, 0x92, + 0xa4, 0x1c, 0x48, 0xe3, 0xa9, 0xb4, 0xc0, 0xda, + 0xec, 0xe0, 0xf8, 0xd9, 0x8d, 0x0d, 0x7e, 0x05, + 0xb3, 0x7a, 0x30, 0x7b, 0xbb, 0x66, 0x33, 0x31, + 0x64, 0xec, 0x9e, 0x1b, 0x24, 0xea, 0x0d, 0x6c, + 0x3f, 0xfd, 0xdc, 0xec, 0x4f, 0x68, 0xe7, 0x44, + 0x30, 0x56, 0x19, 0x3a, 0x03, 0xc8, 0x10, 0xe1, + 0x13, 0x44, 0xca, 0x06, 0xd8, 0xed, 0x8a, 0x2b, + 0xfb, 0x1e, 0x8d, 0x48, 0xcf, 0xa6, 0xbc, 0x0e, + 0xb4, 0xe2, 0x46, 0x4b, 0x74, 0x81, 0x42, 0x40, + 0x7c, 0x9f, 0x43, 0x1a, 0xee, 0x76, 0x99, 0x60, + 0xe1, 0x5b, 0xa8, 0xb9, 0x68, 0x90, 0x46, 0x6e, + 0xf2, 0x45, 0x75, 0x99, 0x85, 0x23, 0x85, 0xc6, + 0x61, 0xf7, 0x52, 0xce, 0x20, 0xf9, 0xda, 0x0c, + 0x09, 0xab, 0x6b, 0x19, 0xdf, 0x74, 0xe7, 0x6a, + 0x95, 0x96, 0x74, 0x46, 0xf8, 0xd0, 0xfd, 0x41, + 0x5e, 0x7b, 0xee, 0x2a, 0x12, 0xa1, 0x14, 0xc2, + 0x0e, 0xb5, 0x29, 0x2a, 0xe7, 0xa3, 0x49, 0xae, + 0x57, 0x78, 0x20, 0xd5, 0x52, 0x0a, 0x1f, 0x3f, + 0xb6, 0x2a, 0x17, 0xce, 0x6a, 0x7e, 0x68, 0xfa, + 0x7c, 0x79, 0x11, 0x1d, 0x88, 0x60, 0x92, 0x0b, + 0xc0, 0x48, 0xef, 0x43, 0xfe, 0x84, 0x48, 0x6c, + 0xcb, 0x87, 0xc2, 0x5f, 0x0a, 0xe0, 0x45, 0xf0, + 0xcc, 0xe1, 0xe7, 0x98, 0x9a, 0x9a, 0xa2, 0x20, + 0xa2, 0x8b, 0xdd, 0x48, 0x27, 0xe7, 0x51, 0xa2, + 0x4a, 0x6d, 0x5c, 0x62, 0xd7, 0x90, 0xa6, 0x63, + 0x93, 0xb9, 0x31, 0x11, 0xc1, 0xa5, 0x5d, 0xd7, + 0x42, 0x1a, 0x10, 0x18, 0x49, 0x74, 0xc7, 0xc5, + }; + unsigned char out[sizeof(cipher)]; + int failed = 0; + size_t k; + + CRYPTO_xchacha_20(out, plain, sizeof(out), key, iv); + + if (memcmp(out, cipher, sizeof(out)) != 0) { + printf("XChaCha20 failed!\n"); + + printf("Got:\t"); + for (k = 0; k < sizeof(out); k++) + printf("%2.2x", out[k]); + printf("\n"); + + printf("Want:\t"); + for (k = 0; k < sizeof(cipher); k++) + printf("%2.2x", cipher[k]); + printf("\n"); + + failed = 1; + } + + return (failed); +} + +int +main(int argc, char **argv) +{ + struct chacha_tv *tv; + unsigned char *in, *out; + size_t i, j, k; + int failed = 0; + + for (i = 0; i < N_VECTORS; i++) { + tv = &chacha_test_vectors[i]; + + for (j = 0; j < N_FUNCS; j++) { + in = calloc(1, tv->len); + if (in == NULL) + errx(1, "calloc in"); + out = calloc(1, tv->len); + if (out == NULL) + errx(1, "calloc out"); + + chacha_test_functions[j].func(tv, out, in); + + if (memcmp(out, tv->out, tv->len) != 0) { + printf("ChaCha %s failed for \"%s\"!\n", + chacha_test_functions[j].name, tv->desc); + + printf("Got:\t"); + for (k = 0; k < tv->len; k++) + printf("%2.2x", out[k]); + printf("\n"); + + printf("Want:\t"); + for (k = 0; k < tv->len; k++) + printf("%2.2x", tv->out[k]); + printf("\n"); + + failed = 1; + } + + free(in); + free(out); + } + } + + if (crypto_hchacha_20_test() != 0) + failed = 1; + + if (crypto_xchacha_20_test() != 0) + failed = 1; + + return failed; +} diff --git a/Libraries/libressl/tests/cipher_list.c b/Libraries/libressl/tests/cipher_list.c new file mode 100644 index 000000000..c715f60e0 --- /dev/null +++ b/Libraries/libressl/tests/cipher_list.c @@ -0,0 +1,231 @@ +/* $OpenBSD: cipher_list.c,v 1.14 2022/12/17 16:05:28 jsing Exp $ */ +/* + * Copyright (c) 2015 Doug Hogan + * Copyright (c) 2015 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Test TLS ssl bytes (aka cipher suites) to cipher list and back. + * + * TLSv1.0 - RFC 2246 section 7.4.1.2 (ClientHello struct) + * TLSv1.1 - RFC 4346 section 7.4.1.2 (ClientHello struct) + * TLSv1.2 - RFC 5246 section 7.4.1.2 (ClientHello struct) + * + * In all of these standards, the relevant structures are: + * + * uint8 CipherSuite[2]; + * + * struct { + * ... + * CipherSuite cipher_suites<2..2^16-2> + * ... + * } ClientHello; + */ + +#include + +#include +#include + +#include "ssl_local.h" + +#include "tests.h" + +static uint8_t cipher_bytes[] = { + 0xcc, 0xa8, /* ECDHE-ECDSA-CHACHA20-POLY1305 */ + 0xcc, 0xa9, /* ECDHE-RSA-CHACHA20-POLY1305 */ + 0xcc, 0xaa, /* DHE-RSA-CHACHA20-POLY1305 */ + 0x00, 0x9c, /* AES128-GCM-SHA256 */ + 0x00, 0x3d, /* AES256-SHA256 */ +}; + +static uint8_t cipher_bytes_seclevel3[] = { + 0xcc, 0xa8, /* ECDHE-ECDSA-CHACHA20-POLY1305 */ + 0xcc, 0xa9, /* ECDHE-RSA-CHACHA20-POLY1305 */ + 0xcc, 0xaa, /* DHE-RSA-CHACHA20-POLY1305 */ +}; + +static uint16_t cipher_values[] = { + 0xcca8, /* ECDHE-ECDSA-CHACHA20-POLY1305 */ + 0xcca9, /* ECDHE-RSA-CHACHA20-POLY1305 */ + 0xccaa, /* DHE-RSA-CHACHA20-POLY1305 */ + 0x009c, /* AES128-GCM-SHA256 */ + 0x003d, /* AES256-SHA256 */ +}; + +#define N_CIPHERS (sizeof(cipher_bytes) / 2) + +static int +ssl_bytes_to_list_alloc(SSL *s, STACK_OF(SSL_CIPHER) **ciphers) +{ + SSL_CIPHER *cipher; + uint16_t value; + CBS cbs; + int i; + + CBS_init(&cbs, cipher_bytes, sizeof(cipher_bytes)); + + *ciphers = ssl_bytes_to_cipher_list(s, &cbs); + CHECK(*ciphers != NULL); + CHECK(sk_SSL_CIPHER_num(*ciphers) == N_CIPHERS); + for (i = 0; i < sk_SSL_CIPHER_num(*ciphers); i++) { + cipher = sk_SSL_CIPHER_value(*ciphers, i); + CHECK(cipher != NULL); + value = SSL_CIPHER_get_value(cipher); + CHECK(value == cipher_values[i]); + } + + return 1; +} + +static int +ssl_list_to_bytes_scsv(SSL *s, STACK_OF(SSL_CIPHER) **ciphers, + const uint8_t *cb, size_t cb_len) +{ + CBB cbb; + unsigned char *buf = NULL; + size_t buflen, outlen; + int ret = 0; + + /* Space for cipher bytes, plus reneg SCSV and two spare bytes. */ + CHECK(sk_SSL_CIPHER_num(*ciphers) == N_CIPHERS); + buflen = cb_len + 2 + 2; + CHECK((buf = calloc(1, buflen)) != NULL); + + /* Clear renegotiate so it adds SCSV */ + s->renegotiate = 0; + + CHECK_GOTO(CBB_init_fixed(&cbb, buf, buflen)); + CHECK_GOTO(ssl_cipher_list_to_bytes(s, *ciphers, &cbb)); + CHECK_GOTO(CBB_finish(&cbb, NULL, &outlen)); + + CHECK_GOTO(outlen > 0 && outlen == cb_len + 2); + CHECK_GOTO(memcmp(buf, cb, cb_len) == 0); + CHECK_GOTO(buf[buflen - 4] == 0x00 && buf[buflen - 3] == 0xff); + CHECK_GOTO(buf[buflen - 2] == 0x00 && buf[buflen - 1] == 0x00); + + ret = 1; + + err: + free(buf); + return ret; +} + +static int +ssl_list_to_bytes_no_scsv(SSL *s, STACK_OF(SSL_CIPHER) **ciphers, + const uint8_t *cb, size_t cb_len) +{ + CBB cbb; + unsigned char *buf = NULL; + size_t buflen, outlen; + int ret = 0; + + /* Space for cipher bytes and two spare bytes */ + CHECK(sk_SSL_CIPHER_num(*ciphers) == N_CIPHERS); + buflen = cb_len + 2; + CHECK((buf = calloc(1, buflen)) != NULL); + buf[buflen - 2] = 0xfe; + buf[buflen - 1] = 0xab; + + /* Set renegotiate so it doesn't add SCSV */ + s->renegotiate = 1; + + CHECK_GOTO(CBB_init_fixed(&cbb, buf, buflen)); + CHECK_GOTO(ssl_cipher_list_to_bytes(s, *ciphers, &cbb)); + CHECK_GOTO(CBB_finish(&cbb, NULL, &outlen)); + + CHECK_GOTO(outlen > 0 && outlen == cb_len); + CHECK_GOTO(memcmp(buf, cb, cb_len) == 0); + CHECK_GOTO(buf[buflen - 2] == 0xfe && buf[buflen - 1] == 0xab); + + ret = 1; + + err: + free(buf); + return ret; +} + +static int +ssl_bytes_to_list_invalid(SSL *s, STACK_OF(SSL_CIPHER) **ciphers) +{ + uint8_t empty_cipher_bytes[] = {0}; + CBS cbs; + + sk_SSL_CIPHER_free(*ciphers); + + /* Invalid length: CipherSuite is 2 bytes so it must be even */ + CBS_init(&cbs, cipher_bytes, sizeof(cipher_bytes) - 1); + *ciphers = ssl_bytes_to_cipher_list(s, &cbs); + CHECK(*ciphers == NULL); + + /* Invalid length: cipher_suites must be at least 2 */ + CBS_init(&cbs, empty_cipher_bytes, sizeof(empty_cipher_bytes)); + *ciphers = ssl_bytes_to_cipher_list(s, &cbs); + CHECK(*ciphers == NULL); + + return 1; +} + +int +main(void) +{ + STACK_OF(SSL_CIPHER) *ciphers = NULL; + SSL_CTX *ctx = NULL; + SSL *s = NULL; + int rv = 1; + + SSL_library_init(); + + /* Use TLSv1.2 client to get all ciphers. */ + CHECK_GOTO((ctx = SSL_CTX_new(TLSv1_2_client_method())) != NULL); + CHECK_GOTO((s = SSL_new(ctx)) != NULL); + SSL_set_security_level(s, 2); + + if (!ssl_bytes_to_list_alloc(s, &ciphers)) + goto err; + if (!ssl_list_to_bytes_scsv(s, &ciphers, cipher_bytes, + sizeof(cipher_bytes))) + goto err; + if (!ssl_list_to_bytes_no_scsv(s, &ciphers, cipher_bytes, + sizeof(cipher_bytes))) + goto err; + if (!ssl_bytes_to_list_invalid(s, &ciphers)) + goto err; + + sk_SSL_CIPHER_free(ciphers); + ciphers = NULL; + + SSL_set_security_level(s, 3); + if (!ssl_bytes_to_list_alloc(s, &ciphers)) + goto err; + if (!ssl_list_to_bytes_scsv(s, &ciphers, cipher_bytes_seclevel3, + sizeof(cipher_bytes_seclevel3))) + goto err; + if (!ssl_list_to_bytes_no_scsv(s, &ciphers, cipher_bytes_seclevel3, + sizeof(cipher_bytes_seclevel3))) + goto err; + + rv = 0; + + err: + sk_SSL_CIPHER_free(ciphers); + SSL_CTX_free(ctx); + SSL_free(s); + + if (!rv) + printf("PASS %s\n", __FILE__); + + return rv; +} diff --git a/Libraries/libressl/tests/cipherstest.c b/Libraries/libressl/tests/cipherstest.c new file mode 100644 index 000000000..c43939d4d --- /dev/null +++ b/Libraries/libressl/tests/cipherstest.c @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2015, 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +int ssl3_num_ciphers(void); +const SSL_CIPHER *ssl3_get_cipher(unsigned int u); + +int ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str); + +static inline int +ssl_aes_is_accelerated(void) +{ +#if defined(__i386__) || defined(__x86_64__) + return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); +#else + return (0); +#endif +} + +static int +check_cipher_order(void) +{ + unsigned long id, prev_id = 0; + const SSL_CIPHER *cipher; + int num_ciphers; + int i; + + num_ciphers = ssl3_num_ciphers(); + + for (i = 1; i <= num_ciphers; i++) { + /* + * For some reason, ssl3_get_cipher() returns ciphers in + * reverse order. + */ + if ((cipher = ssl3_get_cipher(num_ciphers - i)) == NULL) { + fprintf(stderr, "FAIL: ssl3_get_cipher(%d) returned " + "NULL\n", i); + return 1; + } + if ((id = SSL_CIPHER_get_id(cipher)) <= prev_id) { + fprintf(stderr, "FAIL: ssl3_ciphers is not sorted by " + "id - cipher %d (%lx) <= cipher %d (%lx)\n", + i, id, i - 1, prev_id); + return 1; + } + prev_id = id; + } + + return 0; +} + +static int +cipher_find_test(void) +{ + STACK_OF(SSL_CIPHER) *ciphers; + const SSL_CIPHER *cipher; + unsigned char buf[2]; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int ret = 1; + int i; + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + goto failure; + } + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + goto failure; + } + if (!SSL_set_cipher_list(ssl, "ALL")) { + fprintf(stderr, "SSL_set_cipher_list failed\n"); + goto failure; + } + + if ((ciphers = SSL_get_ciphers(ssl)) == NULL) { + fprintf(stderr, "no ciphers\n"); + goto failure; + } + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + uint16_t cipher_value; + + cipher = sk_SSL_CIPHER_value(ciphers, i); + cipher_value = SSL_CIPHER_get_value(cipher); + + buf[0] = cipher_value >> 8; + buf[1] = cipher_value & 0xff; + + if ((cipher = SSL_CIPHER_find(ssl, buf)) == NULL) { + fprintf(stderr, + "SSL_CIPHER_find() returned NULL for %s\n", + SSL_CIPHER_get_name(cipher)); + goto failure; + } + + if (SSL_CIPHER_get_value(cipher) != cipher_value) { + fprintf(stderr, + "got cipher with value 0x%x, want 0x%x\n", + SSL_CIPHER_get_value(cipher), cipher_value); + goto failure; + } + } + + ret = 0; + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return (ret); +} + +static int +cipher_get_by_value_tests(void) +{ + STACK_OF(SSL_CIPHER) *ciphers; + const SSL_CIPHER *cipher; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + unsigned long id; + uint16_t value; + int ret = 1; + int i; + + if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + goto failure; + } + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + goto failure; + } + + if ((ciphers = SSL_get_ciphers(ssl)) == NULL) { + fprintf(stderr, "no ciphers\n"); + goto failure; + } + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + cipher = sk_SSL_CIPHER_value(ciphers, i); + + id = SSL_CIPHER_get_id(cipher); + if (SSL_CIPHER_get_by_id(id) == NULL) { + fprintf(stderr, "SSL_CIPHER_get_by_id() failed " + "for %s (0x%lx)\n", SSL_CIPHER_get_name(cipher), + id); + goto failure; + } + + value = SSL_CIPHER_get_value(cipher); + if (SSL_CIPHER_get_by_value(value) == NULL) { + fprintf(stderr, "SSL_CIPHER_get_by_value() failed " + "for %s (0x%04hx)\n", SSL_CIPHER_get_name(cipher), + value); + goto failure; + } + } + + ret = 0; + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return (ret); +} + +struct parse_ciphersuites_test { + const char *str; + const int want; + const unsigned long cids[32]; +}; + +struct parse_ciphersuites_test parse_ciphersuites_tests[] = { + { + /* LibreSSL names. */ + .str = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256:AEAD-AES128-GCM-SHA256", + .want = 1, + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_3_CK_AES_128_GCM_SHA256, + }, + }, + { + /* OpenSSL names. */ + .str = "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256", + .want = 1, + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_3_CK_AES_128_GCM_SHA256, + }, + }, + { + /* Different priority order. */ + .str = "AEAD-AES128-GCM-SHA256:AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .want = 1, + .cids = { + TLS1_3_CK_AES_128_GCM_SHA256, + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + }, + }, + { + /* Known but unsupported names. */ + .str = "AEAD-AES256-GCM-SHA384:AEAD-AES128-CCM-SHA256:AEAD-AES128-CCM-8-SHA256", + .want = 1, + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + }, + }, + { + /* Empty string means no TLSv1.3 ciphersuites. */ + .str = "", + .want = 1, + .cids = { 0 }, + }, + { + .str = "TLS_CHACHA20_POLY1305_SHA256:TLS_NOT_A_CIPHERSUITE", + .want = 0, + }, + { + .str = "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256,TLS_AES_128_GCM_SHA256", + .want = 0, + }, +}; + +#define N_PARSE_CIPHERSUITES_TESTS \ + (sizeof(parse_ciphersuites_tests) / sizeof(*parse_ciphersuites_tests)) + +static int +parse_ciphersuites_test(void) +{ + struct parse_ciphersuites_test *pct; + STACK_OF(SSL_CIPHER) *ciphers = NULL; + SSL_CIPHER *cipher; + int failed = 1; + int j, ret; + size_t i; + + for (i = 0; i < N_PARSE_CIPHERSUITES_TESTS; i++) { + pct = &parse_ciphersuites_tests[i]; + + ret = ssl_parse_ciphersuites(&ciphers, pct->str); + if (ret != pct->want) { + fprintf(stderr, "FAIL: test %zu - " + "ssl_parse_ciphersuites returned %d, want %d\n", + i, ret, pct->want); + goto failed; + } + if (ret == 0) + continue; + + for (j = 0; j < sk_SSL_CIPHER_num(ciphers); j++) { + cipher = sk_SSL_CIPHER_value(ciphers, j); + if (SSL_CIPHER_get_id(cipher) == pct->cids[j]) + continue; + fprintf(stderr, "FAIL: test %zu - got cipher %d with " + "id %lx, want %lx\n", i, j, + SSL_CIPHER_get_id(cipher), pct->cids[j]); + goto failed; + } + if (pct->cids[j] != 0) { + fprintf(stderr, "FAIL: test %zu - got %d ciphers, " + "expected more", i, sk_SSL_CIPHER_num(ciphers)); + goto failed; + } + } + + failed = 0; + + failed: + sk_SSL_CIPHER_free(ciphers); + + return failed; +} + +struct cipher_set_test { + int ctx_ciphersuites_first; + const char *ctx_ciphersuites; + const char *ctx_rulestr; + int ssl_ciphersuites_first; + const char *ssl_ciphersuites; + const char *ssl_rulestr; + int cids_aes_accel_fixup; + unsigned long cids[32]; +}; + +struct cipher_set_test cipher_set_tests[] = { + { + .ctx_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids_aes_accel_fixup = 1, + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_3_CK_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ssl_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids_aes_accel_fixup = 1, + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_3_CK_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ctx_ciphersuites_first = 1, + .ctx_ciphersuites = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .ctx_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ssl_ciphersuites_first = 1, + .ssl_ciphersuites = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .ssl_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ctx_ciphersuites_first = 0, + .ctx_ciphersuites = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .ctx_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ssl_ciphersuites_first = 0, + .ssl_ciphersuites = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .ssl_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ssl_ciphersuites_first = 1, + .ssl_ciphersuites = "", + .ssl_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ssl_ciphersuites_first = 0, + .ssl_ciphersuites = "", + .ssl_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ctx_ciphersuites = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .ssl_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + { + .ctx_rulestr = "TLSv1.2+ECDHE+AEAD+AES", + .ssl_ciphersuites = "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256", + .cids = { + TLS1_3_CK_AES_256_GCM_SHA384, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, +}; + +#define N_CIPHER_SET_TESTS \ + (sizeof(cipher_set_tests) / sizeof(*cipher_set_tests)) + +static int +cipher_set_test(void) +{ + struct cipher_set_test *cst; + STACK_OF(SSL_CIPHER) *ciphers = NULL; + SSL_CIPHER *cipher; + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + int failed = 0; + size_t i; + int j; + + for (i = 0; i < N_CIPHER_SET_TESTS; i++) { + cst = &cipher_set_tests[i]; + + if (!ssl_aes_is_accelerated() && cst->cids_aes_accel_fixup) { + cst->cids[0] = TLS1_3_CK_CHACHA20_POLY1305_SHA256; + cst->cids[1] = TLS1_3_CK_AES_256_GCM_SHA384; + } + + if ((ctx = SSL_CTX_new(TLS_method())) == NULL) + errx(1, "SSL_CTX_new"); + + if (cst->ctx_ciphersuites_first && cst->ctx_ciphersuites != NULL) { + if (!SSL_CTX_set_ciphersuites(ctx, cst->ctx_ciphersuites)) + errx(1, "SSL_CTX_set_ciphersuites"); + } + if (cst->ctx_rulestr != NULL) { + if (!SSL_CTX_set_cipher_list(ctx, cst->ctx_rulestr)) + errx(1, "SSL_CTX_set_cipher_list"); + } + if (!cst->ctx_ciphersuites_first && cst->ctx_ciphersuites != NULL) { + if (!SSL_CTX_set_ciphersuites(ctx, cst->ctx_ciphersuites)) + errx(1, "SSL_CTX_set_ciphersuites"); + } + + /* XXX - check SSL_CTX_get_ciphers(ctx) */ + + if ((ssl = SSL_new(ctx)) == NULL) + errx(1, "SSL_new"); + + if (cst->ssl_ciphersuites_first && cst->ssl_ciphersuites != NULL) { + if (!SSL_set_ciphersuites(ssl, cst->ssl_ciphersuites)) + errx(1, "SSL_set_ciphersuites"); + } + if (cst->ssl_rulestr != NULL) { + if (!SSL_set_cipher_list(ssl, cst->ssl_rulestr)) + errx(1, "SSL_set_cipher_list"); + } + if (!cst->ssl_ciphersuites_first && cst->ssl_ciphersuites != NULL) { + if (!SSL_set_ciphersuites(ssl, cst->ssl_ciphersuites)) + errx(1, "SSL_set_ciphersuites"); + } + + ciphers = SSL_get_ciphers(ssl); + + for (j = 0; j < sk_SSL_CIPHER_num(ciphers); j++) { + cipher = sk_SSL_CIPHER_value(ciphers, j); + if (SSL_CIPHER_get_id(cipher) == cst->cids[j]) + continue; + fprintf(stderr, "FAIL: test %zu - got cipher %d with " + "id %lx, want %lx\n", i, j, + SSL_CIPHER_get_id(cipher), cst->cids[j]); + failed |= 1; + } + if (cst->cids[j] != 0) { + fprintf(stderr, "FAIL: test %zu - got %d ciphers, " + "expected more", i, sk_SSL_CIPHER_num(ciphers)); + failed |= 1; + } + + SSL_CTX_free(ctx); + SSL_free(ssl); + } + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= check_cipher_order(); + + failed |= cipher_find_test(); + failed |= cipher_get_by_value_tests(); + + failed |= parse_ciphersuites_test(); + failed |= cipher_set_test(); + + return (failed); +} diff --git a/Libraries/libressl/tests/client.pem b/Libraries/libressl/tests/client.pem new file mode 100644 index 000000000..ce4bf49ce --- /dev/null +++ b/Libraries/libressl/tests/client.pem @@ -0,0 +1,51 @@ +subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Client Cert +issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA +-----BEGIN CERTIFICATE----- +MIIDpTCCAo2gAwIBAgIJAPYm3GvOr5eTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt +ZWRpYXRlIENBMB4XDTE0MDUyNDE0NDUxMVoXDTI0MDQwMTE0NDUxMVowZDELMAkG +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU +RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY ++yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs +lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D +nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2 +x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2 +bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9 +AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG ++EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B +AQUFAAOCAQEAJzA4KTjkjXGSC4He63yX9Br0DneGBzjAwc1H6f72uqnCs8m7jgkE +PQJFdTzQUKh97QPUuayZ2gl8XHagg+iWGy60Kw37gQ0+lumCN2sllvifhHU9R03H +bWtS4kue+yQjMbrzf3zWygMDgwvFOUAIgBpH9qGc+CdNu97INTYd0Mvz51vLlxRn +sC5aBYCWaZFnw3lWYxf9eVFRy9U+DkYFqX0LpmbDtcKP7AZGE6ZwSzaim+Cnoz1u +Cgn+QmpFXgJKMFIZ82iSZISn+JkCCGxctZX1lMvai4Wi8Y0HxW9FTFZ6KBNwwE4B +zjbN/ehBkgLlW/DWfi44DvwUHmuU6QP3cw== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAtK2p2x0S3C1ajftAc3GaWPsji6scw1k9Sw/XltbLQuDc11/f +wwrUiFcje2CB3Ri6yD6+uCA3V12jEc4GdqzirJZhwgIhaTv42vfYBgiUcR9McEGr +agFC3yVR3lIbOzhBjmXNp1on46irxnzU4pT+w58IuvYqUBavaEtfRZocFR5NsIOy +mRhyNag8htOFK3wmTEYrb0vflFYT6SD47ogYtsd/xWSKS+YFyb7xSusR2Ot6Ktmr +MswQE57QYJz+KiRVlnL0cduMBdT52Wm8blaC9mz50PyrzjQ68NyHapCoWDU7pe4x +HLtzpXGSDMPuw4miiSwMym/2wReYJv6cFugLPQIDAQABAoIBAAZOyc9MhIwLSU4L +p4RgQvM4UVVe8/Id+3XTZ8NsXExJbWxXfIhiqGjaIfL8u4vsgRjcl+v1s/jo2/iT +KMab4o4D8gXD7UavQVDjtjb/ta79WL3SjRl2Uc9YjjMkyq6WmDNQeo2NKDdafCTB +1uzSJtLNipB8Z53ELPuHJhxX9QMHrMnuha49riQgXZ7buP9iQrHJFhImBjSzbxJx +L+TI6rkyLSf9Wi0Pd3L27Ob3QWNfNRYNSeTE+08eSRChkur5W0RuXAcuAICdQlCl +LBvWO/LmmvbzCqiDcgy/TliSb6CGGwgiNG7LJZmlkYNj8laGwalNlYZs3UrVv6NO +Br2loAECgYEA2kvCvPGj0Dg/6g7WhXDvAkEbcaL1tSeCxBbNH+6HS2UWMWvyTtCn +/bbD519QIdkvayy1QjEf32GV/UjUVmlULMLBcDy0DGjtL3+XpIhLKWDNxN1v1/ai +1oz23ZJCOgnk6K4qtFtlRS1XtynjA+rBetvYvLP9SKeFrnpzCgaA2r0CgYEA0+KX +1ACXDTNH5ySX3kMjSS9xdINf+OOw4CvPHFwbtc9aqk2HePlEsBTz5I/W3rKwXva3 +NqZ/bRqVVeZB/hHKFywgdUQk2Uc5z/S7Lw70/w1HubNTXGU06Ngb6zOFAo/o/TwZ +zTP1BMIKSOB6PAZPS3l+aLO4FRIRotfFhgRHOoECgYEAmiZbqt8cJaJDB/5YYDzC +mp3tSk6gIb936Q6M5VqkMYp9pIKsxhk0N8aDCnTU+kIK6SzWBpr3/d9Ecmqmfyq7 +5SvWO3KyVf0WWK9KH0abhOm2BKm2HBQvI0DB5u8sUx2/hsvOnjPYDISbZ11t0MtK +u35Zy89yMYcSsIYJjG/ROCUCgYEAgI2P9G5PNxEP5OtMwOsW84Y3Xat/hPAQFlI+ +HES+AzbFGWJkeT8zL2nm95tVkFP1sggZ7Kxjz3w7cpx7GX0NkbWSE9O+T51pNASV +tN1sQ3p5M+/a+cnlqgfEGJVvc7iAcXQPa3LEi5h2yPR49QYXAgG6cifn3dDSpmwn +SUI7PQECgYEApGCIIpSRPLAEHTGmP87RBL1smurhwmy2s/pghkvUkWehtxg0sGHh +kuaqDWcskogv+QC0sVdytiLSz8G0DwcEcsHK1Fkyb8A+ayiw6jWJDo2m9+IF4Fww +1Te6jFPYDESnbhq7+TLGgHGhtwcu5cnb4vSuYXGXKupZGzoLOBbv1Zw= +-----END RSA PRIVATE KEY----- diff --git a/Libraries/libressl/tests/client1-ecdsa-chain.pem b/Libraries/libressl/tests/client1-ecdsa-chain.pem new file mode 100644 index 000000000..7a6883db9 --- /dev/null +++ b/Libraries/libressl/tests/client1-ecdsa-chain.pem @@ -0,0 +1,27 @@ +subject= CN = LibreSSL Test Client 1 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrTCCAVKgAwIBAgIJAOVssaaTYoH6MAoGCCqGSM49BAMCMC4xLDAqBgNVBAMM +I0xpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTIxMTIyNzE0 +NDA0MFoXDTMxMTIyNTE0NDA0MFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBD +bGllbnQgMSBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMnRxZ9SVIjF +eygaoub4qyo/tQlHXpQ2U66mhwKhchXD02w3viqOW0qklPSRhwV4nFKsdkVTogCg +Y8AJokxKDU6jYDBeMB0GA1UdDgQWBBTikUU9S7ASdWw7fhaYVdDqUAyH+DAfBgNV +HSMEGDAWgBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1Ud +DwEB/wQEAwIHgDAKBggqhkjOPQQDAgNJADBGAiEA+Aal+cjgT+pknsmAPbivSHY+ +9clFV0Ree1c+nPbBz8cCIQCZDS2G/X8QthK7hZwV2mYhwvd6M/8kwet4u39qJYx8 +eA== +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/client1-ecdsa.pem b/Libraries/libressl/tests/client1-ecdsa.pem new file mode 100644 index 000000000..7d1b2cfc0 --- /dev/null +++ b/Libraries/libressl/tests/client1-ecdsa.pem @@ -0,0 +1,19 @@ +subject= CN = LibreSSL Test Client 1 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrTCCAVKgAwIBAgIJAOVssaaTYoH6MAoGCCqGSM49BAMCMC4xLDAqBgNVBAMM +I0xpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTIxMTIyNzE0 +NDA0MFoXDTMxMTIyNTE0NDA0MFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBD +bGllbnQgMSBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMnRxZ9SVIjF +eygaoub4qyo/tQlHXpQ2U66mhwKhchXD02w3viqOW0qklPSRhwV4nFKsdkVTogCg +Y8AJokxKDU6jYDBeMB0GA1UdDgQWBBTikUU9S7ASdWw7fhaYVdDqUAyH+DAfBgNV +HSMEGDAWgBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1Ud +DwEB/wQEAwIHgDAKBggqhkjOPQQDAgNJADBGAiEA+Aal+cjgT+pknsmAPbivSHY+ +9clFV0Ree1c+nPbBz8cCIQCZDS2G/X8QthK7hZwV2mYhwvd6M/8kwet4u39qJYx8 +eA== +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghOgzNmZV/rLf5+I5 +pnOXJ3N6W8QE5biANh/RVNNmNImhRANCAATJ0cWfUlSIxXsoGqLm+KsqP7UJR16U +NlOupocCoXIVw9NsN74qjltKpJT0kYcFeJxSrHZFU6IAoGPACaJMSg1O +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/client1-rsa-chain.pem b/Libraries/libressl/tests/client1-rsa-chain.pem new file mode 100644 index 000000000..e5267eb34 --- /dev/null +++ b/Libraries/libressl/tests/client1-rsa-chain.pem @@ -0,0 +1,44 @@ +subject= CN = LibreSSL Test Client 1 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoH1MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzhaFw0zMTEyMjUxNDQwMzhaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +Q2xpZW50IDEgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyct5 +l3L4GIzbFPszUioY0/+W9IGnQqOlBtFJQSzJtM96/UcJ/9MEkz08UUaf07CTYWy/ +Qbwl3DizPV9yymiae64oe9RBc2Hh/Z88473Q6UZvPrdoexoVb159tTdvF8IDfIER +HEB2VAtssFvszERa04ndpDqS8tHfBcLGUCu2kZQ0FSCKbNSDLLwoQmyNgnWo8PDY +XshJGdABaTmnhpkrhJq2zeYiUResoWo8z08iVn7vLgjRNTi9mtXr5eC4L0DfEuZB +exaC8frQXH2rXKvojFrFwJ67QLwCOiUKbGlUQBeKS6iahgDL/dRprHqbNZFI7in4 +QiokqixjfzYSmALFqwIDAQABo2AwXjAdBgNVHQ4EFgQUNRNEZs+zkqBu6va5XyGv +UfzSKZQwHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBACmIu0ppKw1T +hzGAoyjxK0y1ffbIDvObcwAMtXSHprMNhkdk7jyQBiXpx4ngEg1LhalUUDkp9Yt1 +qUVjyM4cphJL7ni3N/SyoUtuYWY4s8mqIhloT5adaUJ24kHJ2eFzNBLDuno5wen4 +dXKevTZPNqkkNohbVHrrFewsqS8CYw+rfiNerOJYZzSMbueWK5Pck0od05STZlAE +/B2zesXgd3ZmRKM8jrlZS6gan1FaJOzwErccP7jWnrOeW9uLysRg0ww26/H8Q9xS +dm0L8IXjzmE/yodk/nrt9G72mJnUITt4uHW/1ibMi4+iUR0Ff4oeqrBHQAbRawMK +XKRzXhtI9sI= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/client1-rsa.pem b/Libraries/libressl/tests/client1-rsa.pem new file mode 100644 index 000000000..7e0c47cc4 --- /dev/null +++ b/Libraries/libressl/tests/client1-rsa.pem @@ -0,0 +1,50 @@ +subject= CN = LibreSSL Test Client 1 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoH1MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzhaFw0zMTEyMjUxNDQwMzhaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +Q2xpZW50IDEgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyct5 +l3L4GIzbFPszUioY0/+W9IGnQqOlBtFJQSzJtM96/UcJ/9MEkz08UUaf07CTYWy/ +Qbwl3DizPV9yymiae64oe9RBc2Hh/Z88473Q6UZvPrdoexoVb159tTdvF8IDfIER +HEB2VAtssFvszERa04ndpDqS8tHfBcLGUCu2kZQ0FSCKbNSDLLwoQmyNgnWo8PDY +XshJGdABaTmnhpkrhJq2zeYiUResoWo8z08iVn7vLgjRNTi9mtXr5eC4L0DfEuZB +exaC8frQXH2rXKvojFrFwJ67QLwCOiUKbGlUQBeKS6iahgDL/dRprHqbNZFI7in4 +QiokqixjfzYSmALFqwIDAQABo2AwXjAdBgNVHQ4EFgQUNRNEZs+zkqBu6va5XyGv +UfzSKZQwHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBACmIu0ppKw1T +hzGAoyjxK0y1ffbIDvObcwAMtXSHprMNhkdk7jyQBiXpx4ngEg1LhalUUDkp9Yt1 +qUVjyM4cphJL7ni3N/SyoUtuYWY4s8mqIhloT5adaUJ24kHJ2eFzNBLDuno5wen4 +dXKevTZPNqkkNohbVHrrFewsqS8CYw+rfiNerOJYZzSMbueWK5Pck0od05STZlAE +/B2zesXgd3ZmRKM8jrlZS6gan1FaJOzwErccP7jWnrOeW9uLysRg0ww26/H8Q9xS +dm0L8IXjzmE/yodk/nrt9G72mJnUITt4uHW/1ibMi4+iUR0Ff4oeqrBHQAbRawMK +XKRzXhtI9sI= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDJy3mXcvgYjNsU ++zNSKhjT/5b0gadCo6UG0UlBLMm0z3r9Rwn/0wSTPTxRRp/TsJNhbL9BvCXcOLM9 +X3LKaJp7rih71EFzYeH9nzzjvdDpRm8+t2h7GhVvXn21N28XwgN8gREcQHZUC2yw +W+zMRFrTid2kOpLy0d8FwsZQK7aRlDQVIIps1IMsvChCbI2Cdajw8NheyEkZ0AFp +OaeGmSuEmrbN5iJRF6yhajzPTyJWfu8uCNE1OL2a1evl4LgvQN8S5kF7FoLx+tBc +fatcq+iMWsXAnrtAvAI6JQpsaVRAF4pLqJqGAMv91Gmseps1kUjuKfhCKiSqLGN/ +NhKYAsWrAgMBAAECggEAahMtnXDv/We9mi/Z8Gz0lCwcm/azh5IiI41MJph2hzcx +fYYkOXghRYzA8jBfv5VoQ6Q4fUN722Fqxu4vlzqZSj5oRX9z0EU52GomRcj30kgW +Hi+nGl7BucM/7Uxwd1qjHoVyCxnPmapPvfz0YwPjgqNMARJRQJcV1x9lw6rW03rW +qvoQKwnQ5vZRYldFnvYXRM0VUu8GdruaidWJ2Ra6FUFbEH+I77oIIoyWgXniq9jq +h0VJNRVCLwV4rFzmMkOAz1yxvJ+4UG9/wHYsZVhJDkyos1FVf0klKipKTS7Z87Em +aFlZ01JrM//kS/qdgohllCU8Xt1uVtvsYmJY9T6IEQKBgQD1IJzdopCI+BL7PfWf +qSpyUOgp+8J50CnIJ42ZdBWDhPZSbBqWmqbgBlnXEyPwkKVOhHde6td9DtxRVOiE +Zfy0gpUp4xWUxFdMKyW0+JmsmXiUJKIck6LxqfYDZUTzD2wp1/AhLGJ2M/J5e4IP +umr6IQ4BbDfKGp2NiHEQElCmdwKBgQDSvtOy71EhewJQ9slazR+10skSBbc5Ks9W +cy1fZKcnNB/dPenak5i8Gr04nPhhNvgAwmtDGb9hH1mwjHCUz/TaoPsbTKvtTN2N +MxFzQEsE9F803ULOvFOppe5YEy/M2OaDLHVil1bMwbrg3pGKD4TUfy5cE2NfCDi3 +JwlKk6uDbQKBgQCLAQ9zb7hes66v4pbjD18OrGq7RBUoVq8a3bMijf2VM1UrsDnz +pYd0CqXvnN8IkD3tpJi8rpe8Ry0QwgGI8vy2sEY+FpQqZJzMiLs9QKyEgBMsjwmP +Avmn6SWlD0xmORyxLc7yQOUk+phJ44wBt0jqxsvWarPIXAd0NydGYdxySQKBgAWo +B4iS8cuDQLGpngfo34QCz1DDhIJtSrlYSAx6aB4eQQiwI7mxInVSBmghlm0Ni6SB +k11usHtL2x1o95CW8Ex566N08FxjJsMmbr54KEtOv8tscOGZnmk8QeRtR2gpHi7B +H7lwtGy0em6UqrVY60jEzRq9jno7f0IzMwWkZwMVAoGAL9mQ8xVIaDNyhK477NvD +ZF2AWrHHLXDeTfwdI+HTCUdeDC208kgTx4Z/AX1cN7KQtWZfKIW0bWtCDnKsIwbK +zheDR2AjuDEbT9HWLtYgQvx5/fEc/yxJqtQk+n4CTrDY+rNeow51kziBKWFnu8Je +m38SJSK7uNLz5ZWNgj3XIUE= +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/client2-ecdsa-chain.pem b/Libraries/libressl/tests/client2-ecdsa-chain.pem new file mode 100644 index 000000000..0cba867b7 --- /dev/null +++ b/Libraries/libressl/tests/client2-ecdsa-chain.pem @@ -0,0 +1,26 @@ +subject= CN = LibreSSL Test Client 2 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIDEAACMAoGCCqGSM49BAMCMC4xLDAqBgNVBAMMI0xpYnJl +U1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTEwMDEwMTAwMDAwMFoX +DTIwMDEwMTAwMDAwMFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBDbGllbnQg +MiBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL7oVxdDfyspO7ozwbv+ +2QKCXR8Z1+JWKj6lLmAkN6GY/gXPYcCAtXOWRoVt5yg4YrH0eOJalah7yGjAeHLq +EHijYDBeMB0GA1UdDgQWBBRO8eCtJ/+3xfn+3qY31gP3Ch5JvDAfBgNVHSMEGDAW +gBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQE +AwIHgDAKBggqhkjOPQQDAgNIADBFAiEA10kcAL7I/Y0KVNryJGrfVa1er0uiUXxS +2GmnKWFCQKECID9PY+LK4+DNvxyn4ld47AGJZjdolx6mwLFHK8RvtLo9 +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/client2-ecdsa.pem b/Libraries/libressl/tests/client2-ecdsa.pem new file mode 100644 index 000000000..f0576e6eb --- /dev/null +++ b/Libraries/libressl/tests/client2-ecdsa.pem @@ -0,0 +1,18 @@ +subject= CN = LibreSSL Test Client 2 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIDEAACMAoGCCqGSM49BAMCMC4xLDAqBgNVBAMMI0xpYnJl +U1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTEwMDEwMTAwMDAwMFoX +DTIwMDEwMTAwMDAwMFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBDbGllbnQg +MiBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL7oVxdDfyspO7ozwbv+ +2QKCXR8Z1+JWKj6lLmAkN6GY/gXPYcCAtXOWRoVt5yg4YrH0eOJalah7yGjAeHLq +EHijYDBeMB0GA1UdDgQWBBRO8eCtJ/+3xfn+3qY31gP3Ch5JvDAfBgNVHSMEGDAW +gBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQE +AwIHgDAKBggqhkjOPQQDAgNIADBFAiEA10kcAL7I/Y0KVNryJGrfVa1er0uiUXxS +2GmnKWFCQKECID9PY+LK4+DNvxyn4ld47AGJZjdolx6mwLFHK8RvtLo9 +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGJcFF0AYtzYr190f +tXnGfakMTr5zk0UO1nAfVSLMW2OhRANCAAS+6FcXQ38rKTu6M8G7/tkCgl0fGdfi +Vio+pS5gJDehmP4Fz2HAgLVzlkaFbecoOGKx9HjiWpWoe8howHhy6hB4 +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/client2-rsa-chain.pem b/Libraries/libressl/tests/client2-rsa-chain.pem new file mode 100644 index 000000000..bc09c2e05 --- /dev/null +++ b/Libraries/libressl/tests/client2-rsa-chain.pem @@ -0,0 +1,44 @@ +subject= CN = LibreSSL Test Client 2 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIDEAACMA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNVBAMMIUxp +YnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0xMDAxMDEwMDAwMDBa +Fw0yMDAxMDEwMDAwMDBaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3QgQ2xpZW50 +IDIgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6TPjTtVn4l/2 +3g+XVWUMpxZWu1G3GJ1TY14loqG2lLcyFwHfbxPgjdeUYUXgKw2v3LKdK1xlwohi +7adKmf8ZsqgWYd+SWtvzyoEEEvWQVj5bbs2+EI9CTP4L96lqsiBYZoHxCI+TG3pY +6JOZQT2wmJEL0zeK9cmUXoaV6fQOcEtSmp6m8XWLEEyUZvVHG3OX+7FtcV0snDfz +XrnvpRpu4zolbCC6jysufU46VoJNrrKdPlDu4PbF8PKrJl7jOSULaYHqugIeniMV +V9enkg9t0Bb8bW5sW8/c4vwS52dlRNLHXkwGE7u9+XEVOGDJ+a01eRjVOxQwqptn +qrWTF++D0QIDAQABo2AwXjAdBgNVHQ4EFgQUmUxF57QtRFh9JBPTMx5rUvRjj+4w +HwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/BAIwADAO +BgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAMAvLchG7tWtNXPK3+Ie +u+htMMPhgJCsHhEC0ssZezD3BfYHaJh7ayQwI1KWKrQOwu9z+oOGWQjoVmhBzoi2 +hmvH9vT4GFVnM5agf68USNLxQvlQiShfnqPZiy3EduwY0q+uNvvNYlHeLTp/Au7F +SesJqWoaMr3130n8QqiO8myNjUj3GVrmBBpFogU5qxQAHkcy2AbpkATjRtfG4Jn2 +DWXR9Yd56KuvmkpdVkw+DScOXbIgXmHyutJ7qDbm6lwXLD3U5ulvbSxXW/MhJpb9 +72UjtpQbhMzcyQwCvNrKnST+QqKMisAdkOOhCdEYTj8flpCbMA5bqwBRX+t+AMeD +4lY= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/client2-rsa.pem b/Libraries/libressl/tests/client2-rsa.pem new file mode 100644 index 000000000..b4431ce67 --- /dev/null +++ b/Libraries/libressl/tests/client2-rsa.pem @@ -0,0 +1,50 @@ +subject= CN = LibreSSL Test Client 2 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIDEAACMA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNVBAMMIUxp +YnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0xMDAxMDEwMDAwMDBa +Fw0yMDAxMDEwMDAwMDBaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3QgQ2xpZW50 +IDIgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6TPjTtVn4l/2 +3g+XVWUMpxZWu1G3GJ1TY14loqG2lLcyFwHfbxPgjdeUYUXgKw2v3LKdK1xlwohi +7adKmf8ZsqgWYd+SWtvzyoEEEvWQVj5bbs2+EI9CTP4L96lqsiBYZoHxCI+TG3pY +6JOZQT2wmJEL0zeK9cmUXoaV6fQOcEtSmp6m8XWLEEyUZvVHG3OX+7FtcV0snDfz +XrnvpRpu4zolbCC6jysufU46VoJNrrKdPlDu4PbF8PKrJl7jOSULaYHqugIeniMV +V9enkg9t0Bb8bW5sW8/c4vwS52dlRNLHXkwGE7u9+XEVOGDJ+a01eRjVOxQwqptn +qrWTF++D0QIDAQABo2AwXjAdBgNVHQ4EFgQUmUxF57QtRFh9JBPTMx5rUvRjj+4w +HwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/BAIwADAO +BgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAMAvLchG7tWtNXPK3+Ie +u+htMMPhgJCsHhEC0ssZezD3BfYHaJh7ayQwI1KWKrQOwu9z+oOGWQjoVmhBzoi2 +hmvH9vT4GFVnM5agf68USNLxQvlQiShfnqPZiy3EduwY0q+uNvvNYlHeLTp/Au7F +SesJqWoaMr3130n8QqiO8myNjUj3GVrmBBpFogU5qxQAHkcy2AbpkATjRtfG4Jn2 +DWXR9Yd56KuvmkpdVkw+DScOXbIgXmHyutJ7qDbm6lwXLD3U5ulvbSxXW/MhJpb9 +72UjtpQbhMzcyQwCvNrKnST+QqKMisAdkOOhCdEYTj8flpCbMA5bqwBRX+t+AMeD +4lY= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDpM+NO1WfiX/be +D5dVZQynFla7UbcYnVNjXiWiobaUtzIXAd9vE+CN15RhReArDa/csp0rXGXCiGLt +p0qZ/xmyqBZh35Ja2/PKgQQS9ZBWPltuzb4Qj0JM/gv3qWqyIFhmgfEIj5Mbeljo +k5lBPbCYkQvTN4r1yZRehpXp9A5wS1KanqbxdYsQTJRm9Ucbc5f7sW1xXSycN/Ne +ue+lGm7jOiVsILqPKy59TjpWgk2usp0+UO7g9sXw8qsmXuM5JQtpgeq6Ah6eIxVX +16eSD23QFvxtbmxbz9zi/BLnZ2VE0sdeTAYTu735cRU4YMn5rTV5GNU7FDCqm2eq +tZMX74PRAgMBAAECggEAGghk06QXGLpFwLxU1H+XTf+8ZuTUX7cQXANiiCktTKS2 +vsLCwo+hfbQXKFS4lZXNkAGQcgq6gWDgSk9mkJJduAfzl7FxkRsEuBJ29fbbygTk +CBaHpSmY6SdjBp6u/nuF4suWsLH2ZhbeXfg8H4BXenCWtVl59b4vBe5YRemswvQv +DJzV9gVKDf7HnvcjUMBXNKNWk0cLlodKX6bRhpPbq/WNPAubA3z4Z0JZqnW9uuWa +wTd7QPeKxVbQmz5Y5hifKMI4ML5i1+Fo6Xvcdt1TwfeHYy+iPNtB8fEu1VdH25DN +iN5iiMOr7go8MOc4LxCZGsXqIDd6WYOg/DmCEsSiEQKBgQD78UT9ezhI7TLVmUdC +eQd8+oi1qXykHXpMvobCJUrEulF6/iZSICcVVdH/DcvGRPv7A+90QZWGcY2Bzhtz +8C2XFLqLvSyHegSA4P57PbHjBOqowFAWntLTn/gSOb+nYKSM5XzOQq7RQctYX3EO +jZb4GKhPOUwzy2Ugd9zNhqD8gwKBgQDs9VtAYvM2i3ylRLH/UdAu/E+oA05ydxT1 +dt4tK6R54KSZk+E/LM/k8D3p70tyiRbfky6DtGrGZSpyecCPdkNF0FJTRER1eDsb +Au2uH6zP0nn2FUnQnL5fcIkVlclukf8pMox5fbFcoZjIWti9TURIdMTkaQVX9LKf +Gme84UX2GwKBgQCqsJZuKbpDZjinkDZAKeFR4icW9KIWSkZekkKYbE2QpS6o5mEu +CMyR3tfsNfuV84zITq0/lWNpd6tIg0wEK3enwQp1vA/cJWXBry2ab30CcoVNGSXp +fWcWq22VY3yeOJKjRqNc1r671RigYeEl2/WpVoNJUWd4O9fivHJi6FBPYwKBgQDI +3B5y0K27gbex3C5J8A7ZlTTshYj8zGZuwEkK3yC30y2TpV/dDl5XgTHqV9aLixth +f0CBkfCkpeK6UOxib2wNBM6UGJ0zOixX9D6HSABT1eVeLKN6ezOAcUMykdrCqG0z +fc7HuT0b+TsqMp/gr1t/U8QGneNSsHCtH1PqLscAGwKBgFdecOiUhKezd6mReDYc +cBKBN/2EBPNCSKlzuskSGoU/mC0H+2Mj1XX4fx5Wjvjp3hqKEVgs/L8Eth1KYfgF +CaQzGAkavihH03L73to1Wj/K4XineBAKZLtXkdzWdB+kM8zkYJqmagh6h6BlXFun +TJvYJYIK9U3kvhZtsD6w1slZ +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/client3-ecdsa-chain.pem b/Libraries/libressl/tests/client3-ecdsa-chain.pem new file mode 100644 index 000000000..a389943ee --- /dev/null +++ b/Libraries/libressl/tests/client3-ecdsa-chain.pem @@ -0,0 +1,26 @@ +subject= CN = LibreSSL Test Client 3 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBqjCCAVGgAwIBAgIJAOVssaaTYoH7MAkGByqGSM49BAEwLjEsMCoGA1UEAwwj +TGlicmVTU0wgVGVzdCBJbnRlcm1lZGlhdGUgQ0EgRUNEU0EwHhcNMjExMjI3MTQ0 +MDQwWhcNMzExMjI1MTQ0MDQwWjAnMSUwIwYDVQQDDBxMaWJyZVNTTCBUZXN0IENs +aWVudCAzIEVDRFNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqlNqEjPuPpw3 +HaWxXbWql6f9g2HPei7RGZRfEAeNrnWT+Y4okVoqcxjeLNBA6dNl3uALWbSmDu6a +kmBSU1aY9KNgMF4wHQYDVR0OBBYEFKxGR7LhwxXUGYyxjqBrxi5RKHamMB8GA1Ud +IwQYMBaAFBdWPW/8SlcSOULKAnKBq1AN5MIIMAwGA1UdEwEB/wQCMAAwDgYDVR0P +AQH/BAQDAgeAMAkGByqGSM49BAEDSAAwRQIhAMFzwaCpvWiXD+zEZ/mUBdbMQq2W +JLELD9Mv11NiBhi6AiAN/QNQjluNEUTkxCH6p9bQiOYCQ3DOnPTxrSly/RQOSQ== +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/client3-ecdsa.pem b/Libraries/libressl/tests/client3-ecdsa.pem new file mode 100644 index 000000000..f42528bfa --- /dev/null +++ b/Libraries/libressl/tests/client3-ecdsa.pem @@ -0,0 +1,18 @@ +subject= CN = LibreSSL Test Client 3 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBqjCCAVGgAwIBAgIJAOVssaaTYoH7MAkGByqGSM49BAEwLjEsMCoGA1UEAwwj +TGlicmVTU0wgVGVzdCBJbnRlcm1lZGlhdGUgQ0EgRUNEU0EwHhcNMjExMjI3MTQ0 +MDQwWhcNMzExMjI1MTQ0MDQwWjAnMSUwIwYDVQQDDBxMaWJyZVNTTCBUZXN0IENs +aWVudCAzIEVDRFNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqlNqEjPuPpw3 +HaWxXbWql6f9g2HPei7RGZRfEAeNrnWT+Y4okVoqcxjeLNBA6dNl3uALWbSmDu6a +kmBSU1aY9KNgMF4wHQYDVR0OBBYEFKxGR7LhwxXUGYyxjqBrxi5RKHamMB8GA1Ud +IwQYMBaAFBdWPW/8SlcSOULKAnKBq1AN5MIIMAwGA1UdEwEB/wQCMAAwDgYDVR0P +AQH/BAQDAgeAMAkGByqGSM49BAEDSAAwRQIhAMFzwaCpvWiXD+zEZ/mUBdbMQq2W +JLELD9Mv11NiBhi6AiAN/QNQjluNEUTkxCH6p9bQiOYCQ3DOnPTxrSly/RQOSQ== +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgfaMOzQZ+d1yL3ToI +VPcHtdkIVhqatu/rDcJLuJcNnQehRANCAASqU2oSM+4+nDcdpbFdtaqXp/2DYc96 +LtEZlF8QB42udZP5jiiRWipzGN4s0EDp02Xe4AtZtKYO7pqSYFJTVpj0 +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/client3-rsa-chain.pem b/Libraries/libressl/tests/client3-rsa-chain.pem new file mode 100644 index 000000000..251344f93 --- /dev/null +++ b/Libraries/libressl/tests/client3-rsa-chain.pem @@ -0,0 +1,44 @@ +subject= CN = LibreSSL Test Client 3 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoH2MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzhaFw0zMTEyMjUxNDQwMzhaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +Q2xpZW50IDMgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1vW +q3L63zPi8RJaJ07LsR05gCBYJ7FrnprqKbo7swLra3HE5WQFTxxOPkzBBnCUEaa2 +tqPtov34mrOmnYTQDBxpljx5u6AzjgMfwJZfh7CtGf893nbbP7T2f3pXAFBR0A32 +xmEvso5afyLNRvmxCsrdr2u73bETmBqFQFgGrhtBpTeGqsixgOegZzKHVF67ZjJi +e+faM24GAtkOiPB7PfVgZFyTfe8HQsqqcMRVtjd7JxuN33k8cFIWqv5i8oqVLBME +mLFM2WFIYNTsMtQ38eA7xieuuK6OPTp+cJKQY6jA3wUJOTRt9UE7pEjxOTumckfM +u/ZE1+AODHkH97FptwIDAQABo2AwXjAdBgNVHQ4EFgQUz44RRa+P1oRBVI6lla3o +VsVQq7swHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFgL5955qwHN +vFGnAKoHhoszX3qf2h8zc5HvFfnbvZbBbsuRFW1/QGfQPGWDq8YUlb6wu8NjLjSM +qTSYd1CvWXO1s91kr3LM5k7+9x+whOgbzWjGiprloS9pXcZ+ljTunW4o7jE7pPjZ +opk7W2WmD7/dEDg10x0yDZnKbzea5PMpp6kLqNjtENW4SETtcnwBdi/MZ09ApuUC +E+XWK/uKmxbIJ7Rt/Vi5H3BE74w7souq7fMwGGk7NL8Fmha78VQApKvZV/Rsfrio +D0vVU8djTlEJyXCeqFYU2eKWhc0bfiONIFJ6Wtg/1cR6Jn12+6X36J+wW1G3ibMu +ey+V9oVpM2U= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/client3-rsa.pem b/Libraries/libressl/tests/client3-rsa.pem new file mode 100644 index 000000000..b825391c5 --- /dev/null +++ b/Libraries/libressl/tests/client3-rsa.pem @@ -0,0 +1,50 @@ +subject= CN = LibreSSL Test Client 3 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoH2MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzhaFw0zMTEyMjUxNDQwMzhaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +Q2xpZW50IDMgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1vW +q3L63zPi8RJaJ07LsR05gCBYJ7FrnprqKbo7swLra3HE5WQFTxxOPkzBBnCUEaa2 +tqPtov34mrOmnYTQDBxpljx5u6AzjgMfwJZfh7CtGf893nbbP7T2f3pXAFBR0A32 +xmEvso5afyLNRvmxCsrdr2u73bETmBqFQFgGrhtBpTeGqsixgOegZzKHVF67ZjJi +e+faM24GAtkOiPB7PfVgZFyTfe8HQsqqcMRVtjd7JxuN33k8cFIWqv5i8oqVLBME +mLFM2WFIYNTsMtQ38eA7xieuuK6OPTp+cJKQY6jA3wUJOTRt9UE7pEjxOTumckfM +u/ZE1+AODHkH97FptwIDAQABo2AwXjAdBgNVHQ4EFgQUz44RRa+P1oRBVI6lla3o +VsVQq7swHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFgL5955qwHN +vFGnAKoHhoszX3qf2h8zc5HvFfnbvZbBbsuRFW1/QGfQPGWDq8YUlb6wu8NjLjSM +qTSYd1CvWXO1s91kr3LM5k7+9x+whOgbzWjGiprloS9pXcZ+ljTunW4o7jE7pPjZ +opk7W2WmD7/dEDg10x0yDZnKbzea5PMpp6kLqNjtENW4SETtcnwBdi/MZ09ApuUC +E+XWK/uKmxbIJ7Rt/Vi5H3BE74w7souq7fMwGGk7NL8Fmha78VQApKvZV/Rsfrio +D0vVU8djTlEJyXCeqFYU2eKWhc0bfiONIFJ6Wtg/1cR6Jn12+6X36J+wW1G3ibMu +ey+V9oVpM2U= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCnW9arcvrfM+Lx +ElonTsuxHTmAIFgnsWuemuopujuzAutrccTlZAVPHE4+TMEGcJQRpra2o+2i/fia +s6adhNAMHGmWPHm7oDOOAx/All+HsK0Z/z3edts/tPZ/elcAUFHQDfbGYS+yjlp/ +Is1G+bEKyt2va7vdsROYGoVAWAauG0GlN4aqyLGA56BnModUXrtmMmJ759ozbgYC +2Q6I8Hs99WBkXJN97wdCyqpwxFW2N3snG43feTxwUhaq/mLyipUsEwSYsUzZYUhg +1Owy1Dfx4DvGJ664ro49On5wkpBjqMDfBQk5NG31QTukSPE5O6ZyR8y79kTX4A4M +eQf3sWm3AgMBAAECggEBAJV3HddtDsR8sHegbkegxaXeddYKDPEWMQkrTWoK2vpa +5ynEJ5a+p0cp/m8BWXqI3JSPEas36CmjLH3taCZR0QSf82SrigSZZLG19IupQJQM +o+wN2pFuEQ1qbqMW/dBX61kmv3gYn+KV5BibWj3DDeyXlTjvvI6XcOps9QisFPs0 +BqPC7U4B3DaILeK+cLS9ONjXv4WgGi1LB8dpSR3HgT+qKs/bceCWGCcjfi3PQVJw +8Ahv8wce71rwIWxhnh6hcHq8iiGUj2CAtOA9E4qtxgQ5VkhR049pPQ0CkcrFBRT8 +wTDF5ffzSAbU9QRp/cL7k/eeEAiNQg0aL2GUHhmO/KECgYEA1PxATAFTzX6K4nM/ +yRU769vegTiblYjzUB5JL7baMUgSGgXrZ4UomtQQiYZSDhho8bDSEKM7cNzddMTo +BFyKTvV4Won6LtF2R/JiFbUfDxhGS1+uoLXGciAFdB+NABLrmTQ0jp0N3y53UBmr +jwMDz9BqXq+6QoM3lLUsL4V2j08CgYEAySiax4D3pkr3T6iTuEaLqW9vTV58vWUY +sDstNA2YONYTPHUtFMpVfPgMmrraWHl3yNC2LB9W3SjJ+05oRYObUBI1oAg68u9z +T2+jcxM3fN8HFwyFMm5gd3tygawdwGsvCjLPMJaHdtwlbg8lYfHyEl1hJRA+cnKg +Y5hrfWtpJRkCgYEApWeBR4WAX4Z2tYZrcu5aqsEF+7TKn0bMLtxWWgfXS459AFi4 +iJyQ/CzU6vi1oNy0I37+pI0gDHZ6RcTlqv1zK/7WiPm+ob1p7lX+dn1CsaZYcRDN +vWFtzBOyKIyYJAaNkV1Js7eknj6nyj0lTts4ipuBACfYru7Yq1RIDF/Jw2ECgYA9 +qTWwu+at0cL3ZwxI6076VA9BHxqLj8a+lpUnpJcprO1eleiIu/DyirKKZ4ZwomNG +aju9UKn2xv8LCqDJ1iqwo7ROZtdzClVFX0oyBwz2OQNaXFsj91OYrH2QJCtGhVR5 +AtQh57KEi7zpfLkPyfNTD86sZstNl7d0cA9a9abYWQKBgQCPESj1LojjkEvGKtiD +9w+ZMaDf+mYK+RYQnjEthUMpAPI+mhm9cAl8mMJu3FaNgviOX9oB1/1XGl1Pj5od +KWej9CF1ltoW/PcjsSTeeRFye5jvXn9BLr3w6iUl9pwyo4sVyLHgMzZpiQvGoRNy +u80tjy6bVP3dGa5VHm36pENC4Q== +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/clienttest.c b/Libraries/libressl/tests/clienttest.c new file mode 100644 index 000000000..8fb5a1da7 --- /dev/null +++ b/Libraries/libressl/tests/clienttest.c @@ -0,0 +1,754 @@ +/* $OpenBSD: clienttest.c,v 1.42 2023/07/11 17:03:44 tb Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include +#include +#include + +#define DTLS_HM_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH) +#define DTLS_RANDOM_OFFSET (DTLS_HM_OFFSET + 2) +#define DTLS_CIPHER_OFFSET (DTLS_HM_OFFSET + 38) + +#define SSL3_HM_OFFSET (SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH) +#define SSL3_RANDOM_OFFSET (SSL3_HM_OFFSET + 2) +#define SSL3_CIPHER_OFFSET (SSL3_HM_OFFSET + 37) + +#define TLS13_HM_OFFSET (SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH) +#define TLS13_RANDOM_OFFSET (TLS13_HM_OFFSET + 2) +#define TLS13_SESSION_OFFSET (TLS13_HM_OFFSET + 34) +#define TLS13_CIPHER_OFFSET (TLS13_HM_OFFSET + 69) +#define TLS13_KEY_SHARE_OFFSET (TLS13_HM_OFFSET + 188) +#define TLS13_ONLY_KEY_SHARE_OFFSET (TLS13_HM_OFFSET + 98) + +#define TLS1_3_VERSION_ONLY (TLS1_3_VERSION | 0x10000) + +int tlsext_linearize_build_order(SSL *); + +static const uint8_t cipher_list_dtls1[] = { + 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, + 0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, + 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, + 0x00, 0x2f, 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, + 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, +}; + +static const uint8_t client_hello_dtls1[] = { + 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xfe, 0xff, 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, 0x00, 0x00, 0x00, 0x00, 0x26, 0xc0, + 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, + 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, + 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, + 0x2f, 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, 0x00, + 0x16, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00, 0x00, + 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, + 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x23, 0x00, + 0x00, +}; + +static const uint8_t cipher_list_dtls12_aes[] = { + 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, + 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x39, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, + 0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, + 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, + 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, + 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, + 0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, + 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, + 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, + 0x00, 0x0a, 0x00, 0xff +}; + +static const uint8_t cipher_list_dtls12_chacha[] = { + 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, + 0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, + 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, + 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, + 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, + 0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, + 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, + 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, + 0x00, 0x0a, 0x00, 0xff, +}; + +static const uint8_t client_hello_dtls12[] = { + 0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x00, 0x00, + 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb2, 0xfe, 0xfd, 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, 0x00, 0x00, 0x00, 0x00, 0x54, 0xc0, + 0x30, 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, + 0x14, 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, + 0x39, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xff, + 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, + 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, + 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, + 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, + 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, + 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, + 0x41, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, + 0x0a, 0x00, 0xff, 0x01, 0x00, 0x00, 0x34, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, + 0x01, 0x06, 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, + 0x03, 0x08, 0x04, 0x04, 0x01, 0x04, 0x03, 0x02, + 0x01, 0x02, 0x03, +}; + +static const uint8_t cipher_list_tls10[] = { + 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, + 0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, + 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, + 0x00, 0x2f, 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, + 0x00, 0x05, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, + 0x00, 0x0a, 0x00, 0xff, +}; + +static const uint8_t client_hello_tls10[] = { + 0x16, 0x03, 0x01, 0x00, 0x71, 0x01, 0x00, 0x00, + 0x6d, 0x03, 0x01, 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, 0x00, 0x00, 0x00, 0x2c, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 0x88, + 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 0x2f, + 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, + 0x00, 0xff, 0x01, 0x00, 0x00, 0x18, 0x00, 0x0b, + 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, + 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, + 0x00, 0x19, 0x00, 0x23, 0x00, 0x00, +}; + +static const uint8_t cipher_list_tls11[] = { + 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, + 0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, + 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, + 0x00, 0x2f, 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, + 0x00, 0x05, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, + 0x00, 0x0a, 0x00, 0xff, +}; + +static const uint8_t client_hello_tls11[] = { + 0x16, 0x03, 0x01, 0x00, 0x71, 0x01, 0x00, 0x00, + 0x6d, 0x03, 0x02, 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, 0x00, 0x00, 0x00, 0x2c, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 0x88, + 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 0x2f, + 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, + 0x00, 0xff, 0x01, 0x00, 0x00, 0x18, 0x00, 0x0b, + 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, + 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, + 0x00, 0x19, 0x00, 0x23, 0x00, 0x00, +}; + +static const uint8_t cipher_list_tls12_aes[] = { + 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, + 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x39, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, + 0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, + 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, + 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, + 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, + 0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, + 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, + 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, + 0x00, 0xff, +}; + +static const uint8_t cipher_list_tls12_chacha[] = { + 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, + 0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, + 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, + 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, + 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, + 0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, + 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, + 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, + 0x00, 0xff, +}; + +static const uint8_t client_hello_tls12[] = { + 0x16, 0x03, 0x03, 0x00, 0xbb, 0x01, 0x00, 0x00, + 0xb7, 0x03, 0x03, 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, 0x00, 0x00, 0x00, 0x5a, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, + 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xff, 0x85, + 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, + 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, + 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, + 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, + 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, + 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0xc0, 0x12, + 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, + 0x01, 0x00, 0x00, 0x34, 0x00, 0x0b, 0x00, 0x02, + 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, + 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, + 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x18, + 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03, + 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, + 0x04, 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, +}; + +static const uint8_t cipher_list_tls13_aes[] = { + 0x13, 0x02, 0x13, 0x03, 0x13, 0x01, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, + 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xff, 0x85, + 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, + 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, + 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, + 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, + 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, + 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0xc0, 0x12, + 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, +}; + +static const uint8_t cipher_list_tls13_chacha[] = { + 0x13, 0x03, 0x13, 0x02, 0x13, 0x01, 0xcc, 0xa9, + 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30, 0xc0, 0x2c, + 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a, + 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, 0xff, 0x85, + 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, + 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, + 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, + 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, + 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, + 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0xc0, 0x12, + 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, +}; + +static const uint8_t client_hello_tls13[] = { + 0x16, 0x03, 0x03, 0x01, 0x14, 0x01, 0x00, 0x01, + 0x10, 0x03, 0x03, 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, 0x00, 0x20, 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, 0x00, 0x00, 0x60, 0x13, 0x03, + 0x13, 0x02, 0x13, 0x01, 0xcc, 0xa9, 0xcc, 0xa8, + 0xcc, 0xaa, 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28, + 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f, + 0x00, 0x6b, 0x00, 0x39, 0xff, 0x85, 0x00, 0xc4, + 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, 0x00, 0x3d, + 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f, + 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, 0x00, 0x33, + 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, 0x00, 0x3c, + 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, 0xc0, 0x11, + 0xc0, 0x07, 0x00, 0x05, 0xc0, 0x12, 0xc0, 0x08, + 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00, + 0x00, 0x67, 0x00, 0x2b, 0x00, 0x05, 0x04, 0x03, + 0x04, 0x03, 0x03, 0x00, 0x33, 0x00, 0x26, 0x00, + 0x24, 0x00, 0x1d, 0x00, 0x20, 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, 0x00, 0x00, 0x0b, 0x00, + 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06, + 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, + 0x04, 0x04, 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, + 0x03, +}; + +static const uint8_t cipher_list_tls13_only_aes[] = { + 0x13, 0x02, 0x13, 0x03, 0x13, 0x01, +}; + +static const uint8_t cipher_list_tls13_only_chacha[] = { + 0x13, 0x03, 0x13, 0x02, 0x13, 0x01, +}; + +static const uint8_t client_hello_tls13_only[] = { + 0x16, 0x03, 0x03, 0x00, 0xb6, 0x01, 0x00, 0x00, + 0xb2, 0x03, 0x03, 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, 0x00, 0x20, 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, 0x00, 0x00, 0x08, 0x13, 0x03, + 0x13, 0x02, 0x13, 0x01, 0x00, 0xff, 0x01, 0x00, + 0x00, 0x61, 0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, + 0x04, 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, + 0x1d, 0x00, 0x20, 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, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, + 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, + 0x12, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03, 0x08, + 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, + 0x01, 0x04, 0x03, +}; + +struct client_hello_test { + const char *desc; + const int protocol; + const size_t random_start; + const size_t session_start; + const size_t key_share_start; + const SSL_METHOD *(*ssl_method)(void); + const long ssl_options; + int connect_fails; +}; + +static const struct client_hello_test client_hello_tests[] = { + { + .desc = "DTLSv1 client method", + .protocol = DTLS1_VERSION, + .random_start = DTLS_RANDOM_OFFSET, + .ssl_method = DTLSv1_client_method, + .connect_fails = 1, + }, + { + .desc = "DTLSv1.2 client method", + .protocol = DTLS1_2_VERSION, + .random_start = DTLS_RANDOM_OFFSET, + .ssl_method = DTLSv1_2_client_method, + }, + { + .desc = "DTLS client method", + .protocol = DTLS1_2_VERSION, + .random_start = DTLS_RANDOM_OFFSET, + .ssl_method = DTLS_client_method, + }, + { + .desc = "DTLS client method (no DTLSv1.2)", + .protocol = DTLS1_VERSION, + .random_start = DTLS_RANDOM_OFFSET, + .ssl_method = DTLS_client_method, + .ssl_options = SSL_OP_NO_DTLSv1_2, + .connect_fails = 1, + }, + { + .desc = "DTLS client method (no DTLSv1.0)", + .protocol = DTLS1_2_VERSION, + .random_start = DTLS_RANDOM_OFFSET, + .ssl_method = DTLS_client_method, + .ssl_options = SSL_OP_NO_DTLSv1, + }, + { + .desc = "TLSv1 client method", + .protocol = TLS1_VERSION, + .random_start = SSL3_RANDOM_OFFSET, + .ssl_method = TLSv1_client_method, + .connect_fails = 1, + }, + { + .desc = "TLSv1_1 client method", + .protocol = TLS1_1_VERSION, + .random_start = SSL3_RANDOM_OFFSET, + .ssl_method = TLSv1_1_client_method, + .connect_fails = 1, + }, + { + .desc = "TLSv1_2 client method", + .protocol = TLS1_2_VERSION, + .random_start = SSL3_RANDOM_OFFSET, + .ssl_method = TLSv1_2_client_method, + }, + { + .desc = "SSLv23 default", + .protocol = TLS1_3_VERSION, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_KEY_SHARE_OFFSET, + .ssl_method = SSLv23_client_method, + .ssl_options = 0, + }, + { + .desc = "SSLv23 default (no TLSv1.3)", + .protocol = TLS1_2_VERSION, + .random_start = SSL3_RANDOM_OFFSET, + .ssl_method = SSLv23_client_method, + .ssl_options = SSL_OP_NO_TLSv1_3, + }, + { + .desc = "SSLv23 (no TLSv1.2)", + .protocol = TLS1_3_VERSION_ONLY, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_ONLY_KEY_SHARE_OFFSET, + .ssl_method = SSLv23_client_method, + .ssl_options = SSL_OP_NO_TLSv1_2, + }, + { + .desc = "SSLv23 (no TLSv1.1)", + .protocol = TLS1_3_VERSION, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_KEY_SHARE_OFFSET, + .ssl_method = SSLv23_client_method, + .ssl_options = SSL_OP_NO_TLSv1_1, + }, + { + .desc = "TLS default", + .protocol = TLS1_3_VERSION, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_KEY_SHARE_OFFSET, + .ssl_method = TLS_client_method, + .ssl_options = 0, + }, + { + .desc = "TLS (no TLSv1.3)", + .protocol = TLS1_2_VERSION, + .random_start = SSL3_RANDOM_OFFSET, + .ssl_method = TLS_client_method, + .ssl_options = SSL_OP_NO_TLSv1_3, + }, + { + .desc = "TLS (no TLSv1.2)", + .protocol = TLS1_3_VERSION_ONLY, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_ONLY_KEY_SHARE_OFFSET, + .ssl_method = TLS_client_method, + .ssl_options = SSL_OP_NO_TLSv1_2, + }, + { + .desc = "TLS (no TLSv1.1)", + .protocol = TLS1_3_VERSION, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_KEY_SHARE_OFFSET, + .ssl_method = TLS_client_method, + .ssl_options = SSL_OP_NO_TLSv1_1, + }, +#if 0 + /* XXX - build client hello with explicit versions extension. */ + { + .desc = "TLS (no TLSv1.0, no TLSv1.1)", + .protocol = TLS1_3_VERSION, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_KEY_SHARE_OFFSET, + .ssl_method = TLS_client_method, + .ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, + }, +#endif + { + .desc = "TLS (no TLSv1.0, no TLSv1.1, no TLSv1.2)", + .protocol = TLS1_3_VERSION_ONLY, + .random_start = TLS13_RANDOM_OFFSET, + .session_start = TLS13_SESSION_OFFSET, + .key_share_start = TLS13_ONLY_KEY_SHARE_OFFSET, + .ssl_method = TLS_client_method, + .ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2, + }, +}; + +#define N_CLIENT_HELLO_TESTS \ + (sizeof(client_hello_tests) / sizeof(*client_hello_tests)) + +static void +hexdump(const uint8_t *buf, size_t len, const uint8_t *compare) +{ + const char *mark = ""; + size_t i; + + for (i = 1; i <= len; i++) { + if (compare != NULL) + mark = (buf[i - 1] != compare[i - 1]) ? "*" : " "; + fprintf(stderr, " %s0x%02hhx,%s", mark, buf[i - 1], + i % 8 && i != len ? "" : "\n"); + } + fprintf(stderr, "\n"); +} + +static inline int +ssl_aes_is_accelerated(void) +{ +#if defined(__i386__) || defined(__x86_64__) + return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); +#else + return (0); +#endif +} + +static int +make_client_hello(int protocol, char **out, size_t *outlen) +{ + size_t client_hello_len, cipher_list_len, cipher_list_offset; + const uint8_t *client_hello, *cipher_list; + char *p; + + *out = NULL; + *outlen = 0; + + switch (protocol) { + case DTLS1_VERSION: + client_hello = client_hello_dtls1; + client_hello_len = sizeof(client_hello_dtls1); + cipher_list = cipher_list_dtls1; + cipher_list_len = sizeof(cipher_list_dtls1); + cipher_list_offset = DTLS_CIPHER_OFFSET; + break; + + case DTLS1_2_VERSION: + client_hello = client_hello_dtls12; + client_hello_len = sizeof(client_hello_dtls12); + cipher_list = cipher_list_dtls12_chacha; + cipher_list_len = sizeof(cipher_list_dtls12_chacha); + if (ssl_aes_is_accelerated()) { + cipher_list = cipher_list_dtls12_aes; + cipher_list_len = sizeof(cipher_list_dtls12_aes); + } + cipher_list_offset = DTLS_CIPHER_OFFSET; + break; + + case TLS1_VERSION: + client_hello = client_hello_tls10; + client_hello_len = sizeof(client_hello_tls10); + cipher_list = cipher_list_tls10; + cipher_list_len = sizeof(cipher_list_tls10); + cipher_list_offset = SSL3_CIPHER_OFFSET; + break; + + case TLS1_1_VERSION: + client_hello = client_hello_tls11; + client_hello_len = sizeof(client_hello_tls11); + cipher_list = cipher_list_tls11; + cipher_list_len = sizeof(cipher_list_tls11); + cipher_list_offset = SSL3_CIPHER_OFFSET; + break; + + case TLS1_2_VERSION: + client_hello = client_hello_tls12; + client_hello_len = sizeof(client_hello_tls12); + cipher_list = cipher_list_tls12_chacha; + cipher_list_len = sizeof(cipher_list_tls12_chacha); + if (ssl_aes_is_accelerated()) { + cipher_list = cipher_list_tls12_aes; + cipher_list_len = sizeof(cipher_list_tls12_aes); + } + cipher_list_offset = SSL3_CIPHER_OFFSET; + break; + + case TLS1_3_VERSION: + client_hello = client_hello_tls13; + client_hello_len = sizeof(client_hello_tls13); + cipher_list = cipher_list_tls13_chacha; + cipher_list_len = sizeof(cipher_list_tls13_chacha); + if (ssl_aes_is_accelerated()) { + cipher_list = cipher_list_tls13_aes; + cipher_list_len = sizeof(cipher_list_tls13_aes); + } + cipher_list_offset = TLS13_CIPHER_OFFSET; + break; + + case TLS1_3_VERSION_ONLY: + client_hello = client_hello_tls13_only; + client_hello_len = sizeof(client_hello_tls13_only); + cipher_list = cipher_list_tls13_only_chacha; + cipher_list_len = sizeof(cipher_list_tls13_only_chacha); + if (ssl_aes_is_accelerated()) { + cipher_list = cipher_list_tls13_only_aes; + cipher_list_len = sizeof(cipher_list_tls13_only_aes); + } + cipher_list_offset = TLS13_CIPHER_OFFSET; + break; + + default: + return (-1); + } + + if ((p = malloc(client_hello_len)) == NULL) + return (-1); + + memcpy(p, client_hello, client_hello_len); + memcpy(p + cipher_list_offset, cipher_list, cipher_list_len); + + *out = p; + *outlen = client_hello_len; + + return (0); +} + +static int +client_hello_test(int testno, const struct client_hello_test *cht) +{ + BIO *rbio = NULL, *wbio = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + char *client_hello = NULL; + size_t client_hello_len; + size_t session_len; + char *wbuf, rbuf[1]; + int ret = 1; + long len; + + fprintf(stderr, "Test %d - %s\n", testno, cht->desc); + + /* Providing a small buf causes *_get_server_hello() to return. */ + if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) { + fprintf(stderr, "Failed to setup rbio\n"); + goto failure; + } + if ((wbio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "Failed to setup wbio\n"); + goto failure; + } + + if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + goto failure; + } + + SSL_CTX_set_options(ssl_ctx, cht->ssl_options); + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + goto failure; + } + + if (!tlsext_linearize_build_order(ssl)) { + fprintf(stderr, "failed to linearize build order"); + goto failure; + } + + BIO_up_ref(rbio); + BIO_up_ref(wbio); + SSL_set_bio(ssl, rbio, wbio); + + if (SSL_connect(ssl) != 0) { + if (cht->connect_fails) + goto done; + fprintf(stderr, "SSL_connect() returned non-zero\n"); + goto failure; + } + + len = BIO_get_mem_data(wbio, &wbuf); + + if (make_client_hello(cht->protocol, &client_hello, + &client_hello_len) != 0) + errx(1, "failed to make client hello"); + + if ((size_t)len != client_hello_len) { + fprintf(stderr, "FAIL: test returned ClientHello length %ld, " + "want %zu\n", len, client_hello_len); + fprintf(stderr, "received:\n"); + hexdump(wbuf, len, NULL); + fprintf(stderr, "test data:\n"); + hexdump(client_hello, client_hello_len, NULL); + fprintf(stderr, "\n"); + goto failure; + } + + /* We expect the client random to differ. */ + if (memcmp(&client_hello[cht->random_start], &wbuf[cht->random_start], + SSL3_RANDOM_SIZE) == 0) { + fprintf(stderr, "FAIL: ClientHello has zeroed random\n"); + goto failure; + } + + memset(&wbuf[cht->random_start], 0, SSL3_RANDOM_SIZE); + + if (cht->session_start > 0) { + session_len = wbuf[cht->session_start]; + if (session_len > 0) + memset(&wbuf[cht->session_start + 1], 0, session_len); + } + if (cht->key_share_start > 0) + memset(&wbuf[cht->key_share_start], 0, 32); + + if (memcmp(client_hello, wbuf, client_hello_len) != 0) { + fprintf(stderr, "FAIL: ClientHello differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(wbuf, len, client_hello); + fprintf(stderr, "test data:\n"); + hexdump(client_hello, client_hello_len, wbuf); + fprintf(stderr, "\n"); + goto failure; + } + + done: + ret = 0; + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + BIO_free(rbio); + BIO_free(wbio); + + free(client_hello); + + return (ret); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + SSL_library_init(); + + for (i = 0; i < N_CLIENT_HELLO_TESTS; i++) + failed |= client_hello_test(i, &client_hello_tests[i]); + + return (failed); +} diff --git a/Libraries/libressl/tests/cmstest.c b/Libraries/libressl/tests/cmstest.c new file mode 100644 index 000000000..c207b9ebd --- /dev/null +++ b/Libraries/libressl/tests/cmstest.c @@ -0,0 +1,326 @@ +/* $OpenBSD: cmstest.c,v 1.7 2023/03/02 21:08:14 tb Exp $ */ +/* + * Copyright (c) 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +#include + +static int verbose = 0; + +static const char cms_msg[] = "Hello CMS!\r\n"; + +static const char cms_ca_1[] = + "-----BEGIN CERTIFICATE-----\n" + "MIICqDCCAZACCQD8ebR8e4kdvjANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtU\n" + "ZXN0IENNUyBDQTAeFw0xOTA1MTExNTUzNTNaFw0yOTA1MDgxNTUzNTNaMBYxFDAS\n" + "BgNVBAMMC1Rlc3QgQ01TIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" + "AQEAoIiW3POGYfhY0BEgG8mIwouOI917M72jsuUE57ccjEXLWseItLb7r9vkiwW/\n" + "FYbz0UYkJW1JgpZmWaTGOgZGxj+WTzxh1aq7OHyJb6Pxwp9wGrGJu+BEqOZN/bi/\n" + "aQ1l8x7DxVJkFeI1+4QKDfmGYfWoVzQLgamO3u0vxz3Vi/XzX01ZomcZUYYx0lIq\n" + "hxAO665HoPUmecqYdLPquJNxdfiy37ieLJOmIsKZJtMcCZAxqhcCwE7I0196Ng3P\n" + "fK9Sl7BCyTBszb2YC2qOleuI2Wjg/7o1+hugopUkjxz0RGFu5s3K9PhCLwpqylXg\n" + "IXe9Vwi38gKawD3yjtDBRDNmIwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAvsvtc\n" + "cO0Eo0F6MvB0bjBIMHBkKyWcmD2c5gVFhbHyRD+XBVXNdn5CcBba2amm0VgShBpM\n" + "4e1rOtIH/Hf6nB3c/EjZvd16ryoTCTvzayac7sD2Y8IxF1JIAKvjFbu+LmzM/F5f\n" + "x3/WdY1qs5W7lO46i8xmSUAP88gohWP4cyVUAITNrh/RSOFaWUd5i1/vZ+iEexLI\n" + "rQWsweJleOxvA8SrXm2gAkqRWEncsxOrsX/MsPl7iJoebLhWbS3cOHhutWrfhdlC\n" + "2uT6K7SA9rn6qqmvI6mLkHJQpqq++Py2UTDo1u8VKa3ieYNUN070kgxpYiVBGs3L\n" + "aaACIcEs48gnTRWc\n" + "-----END CERTIFICATE-----\n"; + +static const char cms_cert_1[] = + "-----BEGIN CERTIFICATE-----\n" + "MIICpDCCAYwCAQMwDQYJKoZIhvcNAQEFBQAwFjEUMBIGA1UEAwwLVGVzdCBDTVMg\n" + "Q0EwHhcNMTkwNTExMTU1MzU0WhcNMjkwNTA4MTU1MzU0WjAaMRgwFgYDVQQDDA9U\n" + "ZXN0IENNUyBDZXJ0IDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD\n" + "MLSuy+tc0AwfrlszgHJ3z7UEpJSn5mcKxquFnEC5DtchgQJ+cj5VFvB9A9G98ykQ\n" + "0IrHXNUTbS2yvf8ac1PlocuA8ggeDK4gPHCe097j0nUphhT0VzhwwFfP6Uo6VaR8\n" + "B7Qb3zFTz64bN66V89etZ5NQJKMdrh4oOh5nfxLKvCcTK+9U4ZrgeGVdVXmL6HJp\n" + "3m9CPobCBsC8DgI+zF/tg4GjDoVCJd6Tv5MRAmKiBrzTGglVeknkgiyIZ9C7gXU/\n" + "7NMUihmLlt+80zr+nL0P+MA924WV4fZJi1wtf6Eioalq6n/9i93nBRCeu8bEOBrT\n" + "pAre2oBEoULIJu7Ubx79AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBADnLc6ZzApHq\n" + "Z8l4zrFKAG/O/oULPMRTA8/zXNQ60BMV10hVtTCxVNq59d48wEljuUOGLfM91rhj\n" + "gId8AOlsQbfRZE94DxlcaaAXaEjbkVSke56yfdLd4NqkIWrXGrFlbepj4b4ORAHh\n" + "85kPwDEDnpMgQ63LqNX3gru3xf2AGIa1Fck2ISkVafqW5TH0Y6dCeGGFTtnH/QUT\n" + "ofTm8uQ2vG9ERn+C1ooqJ2dyAckXFdmCcpor26vO/ZssMEKSee38ZNWR/01LEkOG\n" + "G0+AL7E1mJdlVOtp3DDFN0hoNY7PbVuuzT+mrAwGLhCp2jnf68iNdrIuDdIE6yvi\n" + "6WWvmmz+rC0=\n" + "-----END CERTIFICATE-----\n"; + +static const char cms_key_1[] = + "-----BEGIN PRIVATE KEY-----\n" + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDMLSuy+tc0Awf\n" + "rlszgHJ3z7UEpJSn5mcKxquFnEC5DtchgQJ+cj5VFvB9A9G98ykQ0IrHXNUTbS2y\n" + "vf8ac1PlocuA8ggeDK4gPHCe097j0nUphhT0VzhwwFfP6Uo6VaR8B7Qb3zFTz64b\n" + "N66V89etZ5NQJKMdrh4oOh5nfxLKvCcTK+9U4ZrgeGVdVXmL6HJp3m9CPobCBsC8\n" + "DgI+zF/tg4GjDoVCJd6Tv5MRAmKiBrzTGglVeknkgiyIZ9C7gXU/7NMUihmLlt+8\n" + "0zr+nL0P+MA924WV4fZJi1wtf6Eioalq6n/9i93nBRCeu8bEOBrTpAre2oBEoULI\n" + "Ju7Ubx79AgMBAAECggEAD4XkGLKm+S6iiDJ5llL0x4qBPulH2UJ9l2HNakbO7ui7\n" + "OzLjW+MCCgpU/dw75ftcnLW5E7nSSEU6iSiLDTN2zKBdatfUxW8EuhOUcU0wQLYQ\n" + "E0lSiUwWdQEW+rX27US6XBLQxBav+ZZeplN7UvmdgXDnSkxfnJCoXVKh8GEuwWip\n" + "sM/Lwg8MSZK0o5qFVXtPp7kreB8CWlVyPYW5rDYy3k02R1t9k6WSdO2foPXe9rdZ\n" + "iiThkALcHdBcFF0NHrIkAgMdtcAxkDIwO2kOnGJQKDXu+txbzPYodMU0Z6eVnlIu\n" + "jh9ZjnZKBJgX6YVLVPRBwQXHXeGAnvMNm2WXH7SCAQKBgQDmMxvspc3K6HOqMoik\n" + "59Rq1gXIuaGH0uSMSiUMTkr4laJbh9WgZ6JTAfIPuhj1xKGfDK7LF9VjPQ104SgL\n" + "dCA1pV6nsuGS3j3vBnaMfmO7yr3yON+p/WDpKOgqC51Z3/pT8reJtMnyowQuDeYe\n" + "UVRVyeXA11nve0SSc97US4AtXQKBgQDZERtgs6ejiUJQXuflu9HDczEZ/pHfPI1y\n" + "+RU0tvI4860OTjerVJA2YBeOBLa9Y3hblvNpOU0SoVeMAGQLblEznJAl1nbaWqVY\n" + "kPgvtQcTOL/awEB90JklvSRqR82WJchMOHMG5SeqrpUx3Dg+cPH6nId0e8UCt3/U\n" + "W/u/5hP+IQKBgQDfReEmxaZ10MIm6P6p24Wm3dEcYBfxEjbEb0HBzspek1u3JWep\n" + "PfsuQavTXy/IaKBOENIUgBhjOZssqxnZChgXkD7frtulRNOTW5RuLkRzp3BWWJ1v\n" + "VifB3gBYj41d16UH+VnVQbnCEiUCuk5hR4bh8oJaaUV8xvW6ipItHNHErQKBgGoe\n" + "2uuj6UkiSbFRNL4z3JFZN6AlvNsOl3imHZ/v8Ou29dwQkVbJuNdckydzVoOwpZ7h\n" + "ZY8D3JJHHq3rYv3TqQ86c56MAv8tYbiy5yMrtZHIJMOlSeI4oSa6GZt8Dx5gylO5\n" + "JUMxtPrU70u5BiZAwYxsCi0AdYimfXAsqB9hNFUBAoGBAJPT7Xsr7NIkrbv+aYXj\n" + "rVVJ1qokUEKT6H1GmFXO3Fkw3kjPKS8VZloKOB7OiBC+AwMEQIflArCZ+PJdnVNO\n" + "48ntHnaeaZk8rKXsYdJsqMKgIxZYZuCIazZz9WHeYxn5vkH76Q3DrfqrneJ3HSU/\n" + "pFtLoXoGoVXRjAtpNvX7fh/G\n" + "-----END PRIVATE KEY-----\n"; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\n"); + if (len % 8 != 0) + fprintf(stderr, "\n"); +} + +static int +test_cms_encrypt_decrypt(void) +{ + STACK_OF(X509) *certs = NULL; + CMS_ContentInfo *ci = NULL; + EVP_PKEY *pkey = NULL; + BIO *bio_mem = NULL; + BIO *bio_out = NULL; + X509 *cert = NULL; + size_t len; + long mem_len; + char *p; + int failed = 1; + + if ((bio_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL) + errx(1, "failed to create BIO"); + + if ((certs = sk_X509_new_null()) == NULL) + errx(1, "failed to create certs"); + if ((bio_mem = BIO_new_mem_buf(cms_cert_1, -1)) == NULL) + errx(1, "failed to create BIO for cert"); + if ((cert = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL)) == NULL) + errx(1, "failed to read cert"); + if (!sk_X509_push(certs, cert)) + errx(1, "failed to push cert"); + + BIO_free(bio_mem); + if ((bio_mem = BIO_new_mem_buf(cms_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) + errx(1, "failed to read key"); + + BIO_free(bio_mem); + if ((bio_mem = BIO_new_mem_buf(cms_msg, -1)) == NULL) + errx(1, "failed to create BIO for message"); + + if ((ci = CMS_encrypt(certs, bio_mem, EVP_aes_256_cbc(), 0)) == NULL) { + fprintf(stderr, "FAIL: CMS_encrypt returned NULL\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (verbose) { + if (!CMS_ContentInfo_print_ctx(bio_out, ci, 0, NULL)) + errx(1, "failed to print CMS ContentInfo"); + if (!PEM_write_bio_CMS(bio_out, ci)) + errx(1, "failed to print CMS PEM"); + } + + BIO_free(bio_mem); + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "failed to create BIO for message"); + + if (!CMS_decrypt(ci, pkey, cert, NULL, bio_mem, 0)) { + fprintf(stderr, "FAIL: CMS_decrypt failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if ((mem_len = BIO_get_mem_data(bio_mem, &p)) <= 0) { + fprintf(stderr, "FAIL: BIO_get_mem_data returned %ld\n", + mem_len); + goto failure; + } + if ((len = strlen(cms_msg)) != (size_t)mem_len) { + fprintf(stderr, "FAIL: CMS decrypt returned %ld bytes, " + "want %zu bytes\n", mem_len, len); + fprintf(stderr, "Got CMS data:\n"); + hexdump(p, mem_len); + fprintf(stderr, "Want CMS data:\n"); + hexdump(cms_msg, len); + goto failure; + } + if (memcmp(p, cms_msg, len) != 0) { + fprintf(stderr, "FAIL: CMS decrypt message differs"); + fprintf(stderr, "Got CMS data:\n"); + hexdump(p, mem_len); + fprintf(stderr, "Want CMS data:\n"); + hexdump(cms_msg, len); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio_mem); + BIO_free(bio_out); + CMS_ContentInfo_free(ci); + EVP_PKEY_free(pkey); + sk_X509_free(certs); + X509_free(cert); + + return failed; +} + +static int +test_cms_sign_verify(void) +{ + STACK_OF(X509) *certs = NULL; + CMS_ContentInfo *ci = NULL; + X509_STORE *store = NULL; + EVP_PKEY *pkey = NULL; + BIO *bio_mem = NULL; + BIO *bio_out = NULL; + X509 *cert = NULL; + X509 *ca = NULL; + size_t len; + long mem_len; + char *p; + int failed = 1; + + if ((bio_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL) + errx(1, "failed to create BIO"); + + if ((certs = sk_X509_new_null()) == NULL) + errx(1, "failed to create certs"); + if ((bio_mem = BIO_new_mem_buf(cms_cert_1, -1)) == NULL) + errx(1, "failed to create BIO for cert"); + if ((cert = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL)) == NULL) + errx(1, "failed to read cert"); + if (!sk_X509_push(certs, cert)) + errx(1, "failed to push cert"); + + BIO_free(bio_mem); + if ((bio_mem = BIO_new_mem_buf(cms_ca_1, -1)) == NULL) + errx(1, "failed to create BIO for cert"); + if ((ca = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL)) == NULL) + errx(1, "failed to read cert"); + if ((store = X509_STORE_new()) == NULL) + errx(1, "failed to create X509 store"); + if (!X509_STORE_add_cert(store, ca)) + errx(1, "failed to add cert to store"); + + BIO_free(bio_mem); + if ((bio_mem = BIO_new_mem_buf(cms_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) + errx(1, "failed to read key"); + + BIO_free(bio_mem); + if ((bio_mem = BIO_new_mem_buf(cms_msg, -1)) == NULL) + errx(1, "failed to create BIO for message"); + + if ((ci = CMS_sign(cert, pkey, NULL, bio_mem, 0)) == NULL) { + fprintf(stderr, "FAIL: CMS sign failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (verbose) { + if (!CMS_ContentInfo_print_ctx(bio_out, ci, 0, NULL)) + errx(1, "failed to print CMS ContentInfo"); + if (!PEM_write_bio_CMS(bio_out, ci)) + errx(1, "failed to print CMS PEM"); + } + + BIO_free(bio_mem); + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "failed to create BIO for message"); + + if (!CMS_verify(ci, certs, store, NULL, bio_mem, 0)) { + fprintf(stderr, "FAIL: CMS_verify failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if ((mem_len = BIO_get_mem_data(bio_mem, &p)) <= 0) { + fprintf(stderr, "FAIL: BIO_get_mem_data returned %ld\n", + mem_len); + goto failure; + } + if ((len = strlen(cms_msg)) != (size_t)mem_len) { + fprintf(stderr, "FAIL: CMS verify returned %ld bytes, " + "want %zu bytes\n", mem_len, len); + fprintf(stderr, "Got CMS data:\n"); + hexdump(p, mem_len); + fprintf(stderr, "Want CMS data:\n"); + hexdump(cms_msg, len); + goto failure; + } + if (memcmp(p, cms_msg, len) != 0) { + fprintf(stderr, "FAIL: CMS verify message differs"); + fprintf(stderr, "Got CMS data:\n"); + hexdump(p, mem_len); + fprintf(stderr, "Want CMS data:\n"); + hexdump(cms_msg, len); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio_mem); + BIO_free(bio_out); + CMS_ContentInfo_free(ci); + EVP_PKEY_free(pkey); + sk_X509_free(certs); + X509_free(cert); + X509_STORE_free(store); + X509_free(ca); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + ERR_load_crypto_strings(); + + failed |= test_cms_encrypt_decrypt(); + failed |= test_cms_sign_verify(); + + return failed; +} diff --git a/Libraries/libressl/tests/compat/memmem.c b/Libraries/libressl/tests/compat/memmem.c new file mode 100644 index 000000000..9b11960de --- /dev/null +++ b/Libraries/libressl/tests/compat/memmem.c @@ -0,0 +1,183 @@ +/* $OpenBSD: memmem.c,v 1.5 2020/04/16 12:39:28 claudio Exp $ */ + +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +static char * +twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1]; + for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++) + if (hw == nw) return (char *)h-2; + return hw == nw ? (char *)h-2 : 0; +} + +static char * +threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8; + uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8; + for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8) + if (hw == nw) return (char *)h-3; + return hw == nw ? (char *)h-3 : 0; +} + +static char * +fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3]; + uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3]; + for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++) + if (hw == nw) return (char *)h-4; + return hw == nw ? (char *)h-4 : 0; +} + +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) + +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) + +/* + * Maxime Crochemore and Dominique Perrin, Two-way string-matching, + * Journal of the ACM, 38(3):651-675, July 1991. + */ +static char * +twoway_memmem(const unsigned char *h, const unsigned char *z, + const unsigned char *n, size_t l) +{ + size_t i, ip, jp, k, p, ms, p0, mem, mem0; + size_t byteset[32 / sizeof(size_t)] = { 0 }; + size_t shift[256]; + + /* Computing length of needle and fill shift table */ + for (i=0; i n[jp+k]) { + jp += k; + k = 1; + p = jp - ip; + } else { + ip = jp++; + k = p = 1; + } + } + ms = ip; + p0 = p; + + /* And with the opposite comparison */ + ip = -1; jp = 0; k = p = 1; + while (jp+k ms+1) ms = ip; + else p = p0; + + /* Periodic needle? */ + if (memcmp(n, n+p, ms+1)) { + mem0 = 0; + p = MAX(ms, l-ms-1) + 1; + } else mem0 = l-p; + mem = 0; + + /* Search loop */ + for (;;) { + /* If remainder of haystack is shorter than needle, done */ + if (z-h < l) return 0; + + /* Check last byte first; advance by shift on mismatch */ + if (BITOP(byteset, h[l-1], &)) { + k = l-shift[h[l-1]]; + if (k) { + if (k < mem) k = mem; + h += k; + mem = 0; + continue; + } + } else { + h += l; + mem = 0; + continue; + } + + /* Compare right half */ + for (k=MAX(ms+1,mem); kmem && n[k-1] == h[k-1]; k--); + if (k <= mem) return (char *)h; + h += p; + mem = mem0; + } +} + +void * +memmem(const void *h0, size_t k, const void *n0, size_t l) +{ + const unsigned char *h = h0, *n = n0; + + /* Return immediately on empty needle */ + if (!l) return (void *)h; + + /* Return immediately when needle is longer than haystack */ + if (k + */ + +#include +#include +#include +#include + +#undef socketpair + +#ifdef _WIN32 + +static int setfd(int fd, int flag) +{ + int rc = -1; + if (flag & FD_CLOEXEC) { + HANDLE h = (HANDLE)_get_osfhandle(fd); + if (h != NULL) + rc = SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0) == 0 ? -1 : 0; + } + return rc; +} + +static int setfl(int fd, int flag) +{ + int rc = -1; + if (flag & O_NONBLOCK) { + long mode = 1; + rc = ioctlsocket(fd, FIONBIO, &mode); + } + return rc; +} + +int socketpair(int domain, int type, int protocol, int socket_vector[2]) +{ + if (domain != AF_UNIX || !(type & SOCK_STREAM) || protocol != PF_UNSPEC) + return -1; + + socket_vector[0] = -1; + socket_vector[1] = -1; + + int listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listener == -1) { + return -1; + } + + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + .sin_port = 0, + }; + + int yes = 1, e; + if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, + (void *)&yes, sizeof yes) == -1) + goto err; + + if (bind(listener, (struct sockaddr *)&addr, sizeof addr) != 0) + goto err; + + memset(&addr, 0, sizeof addr); + socklen_t addrlen = sizeof addr; + if (getsockname(listener, (struct sockaddr *)&addr, &addrlen) != 0) + goto err; + + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_family = AF_INET; + + if (listen(listener, 1) != 0) + goto err; + + socket_vector[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); + if (socket_vector[0] == -1) + goto err; + + if (connect(socket_vector[0], (struct sockaddr *)&addr, sizeof addr) != 0) + goto err; + + socket_vector[1] = accept(listener, NULL, NULL); + if (socket_vector[1] == -1) + goto err; + + closesocket(listener); + return 0; + +err: + e = WSAGetLastError(); + closesocket(listener); + closesocket(socket_vector[0]); + closesocket(socket_vector[1]); + WSASetLastError(e); + socket_vector[0] = -1; + socket_vector[1] = -1; + return -1; +} + +int pipe(int fildes[2]) +{ + return socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, fildes); +} + +#else + +static int setfd(int fd, int flag) +{ + int flags = fcntl(fd, F_GETFD); + flags |= flag; + return fcntl(fd, F_SETFD, flags); +} + +static int setfl(int fd, int flag) +{ + int flags = fcntl(fd, F_GETFL); + flags |= flag; + return fcntl(fd, F_SETFL, flags); +} +#endif + +int pipe2(int fildes[2], int flags) +{ + int rc = pipe(fildes); + if (rc == 0) { + if (flags & O_NONBLOCK) { + rc |= setfl(fildes[0], O_NONBLOCK); + rc |= setfl(fildes[1], O_NONBLOCK); + } + if (flags & O_CLOEXEC) { + rc |= setfd(fildes[0], FD_CLOEXEC); + rc |= setfd(fildes[1], FD_CLOEXEC); + } + if (rc != 0) { + int e = errno; + close(fildes[0]); + close(fildes[1]); + errno = e; + } + } + return rc; +} + +int bsd_socketpair(int domain, int type, int protocol, int socket_vector[2]) +{ + int flags = type & ~0xf; + type &= 0xf; + int rc = socketpair(domain, type, protocol, socket_vector); + if (rc == 0) { + if (flags & SOCK_NONBLOCK) { + rc |= setfl(socket_vector[0], O_NONBLOCK); + rc |= setfl(socket_vector[1], O_NONBLOCK); + } + if (flags & SOCK_CLOEXEC) { + rc |= setfd(socket_vector[0], FD_CLOEXEC); + rc |= setfd(socket_vector[1], FD_CLOEXEC); + } + if (rc != 0) { + int e = errno; + close(socket_vector[0]); + close(socket_vector[1]); + errno = e; + } + } + return rc; +} diff --git a/Libraries/libressl/tests/configtest.c b/Libraries/libressl/tests/configtest.c new file mode 100644 index 000000000..5af5b56ff --- /dev/null +++ b/Libraries/libressl/tests/configtest.c @@ -0,0 +1,173 @@ +/* $OpenBSD: configtest.c,v 1.3 2023/07/02 06:37:27 beck Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +struct parse_protocols_test { + const char *protostr; + int want_return; + uint32_t want_protocols; +}; + +struct parse_protocols_test parse_protocols_tests[] = { + { + .protostr = NULL, + .want_return = 0, + .want_protocols = TLS_PROTOCOLS_DEFAULT, + }, + { + .protostr = "default", + .want_return = 0, + .want_protocols = TLS_PROTOCOLS_DEFAULT, + }, + { + .protostr = "secure", + .want_return = 0, + .want_protocols = TLS_PROTOCOLS_DEFAULT, + }, + { + .protostr = "all", + .want_return = 0, + .want_protocols = TLS_PROTOCOLS_ALL, + }, + { + .protostr = "tlsv1", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1, + }, + { + .protostr = "tlsv1.2", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_2, + }, + { + .protostr = "tlsv1.3", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_3, + }, + { + .protostr = "", + .want_return = -1, + .want_protocols = 0, + }, + { + .protostr = "tlsv1.0:tlsv1.1:tlsv1.2:tlsv1.3", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3, + }, + { + .protostr = "tlsv1.0,tlsv1.1,tlsv1.2,tlsv1.3", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3, + }, + { + .protostr = "tlsv1.1,tlsv1.2,tlsv1.0", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_2, + }, + { + .protostr = "tlsv1.1,tlsv1.2,tlsv1.1", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_2, + }, + { + .protostr = "tlsv1.1,tlsv1.2,!tlsv1.1", + .want_return = 0, + .want_protocols = 0, + }, + { + .protostr = "unknown", + .want_return = -1, + .want_protocols = 0, + }, + { + .protostr = "all,!unknown", + .want_return = -1, + .want_protocols = 0, + }, + { + .protostr = "sslv3,tlsv1.0,tlsv1.1,tlsv1.2", + .want_return = -1, + .want_protocols = 0, + }, + { + .protostr = "all,!tlsv1.0", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_3, + }, + { + .protostr = "!tlsv1.0", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_3, + }, + { + .protostr = "!tlsv1.0,!tlsv1.1,!tlsv1.3", + .want_return = 0, + .want_protocols = 0, + }, + { + .protostr = "!tlsv1.0,!tlsv1.1,tlsv1.2,!tlsv1.3", + .want_return = 0, + .want_protocols = TLS_PROTOCOL_TLSv1_2, + }, +}; + +#define N_PARSE_PROTOCOLS_TESTS \ + (sizeof(parse_protocols_tests) / sizeof(*parse_protocols_tests)) + +static int +do_parse_protocols_test(int test_no, struct parse_protocols_test *ppt) +{ + uint32_t protocols = 0; + int failed = 1; + int rv; + + rv = tls_config_parse_protocols(&protocols, ppt->protostr); + if (rv != ppt->want_return) { + fprintf(stderr, "FAIL: test %i - tls_config_parse_protocols() " + "returned %i, want %i\n", test_no, rv, ppt->want_return); + goto done; + } + if (protocols != ppt->want_protocols) { + fprintf(stderr, "FAIL: test %i - got protocols 0x%x, " + "want 0x%x\n", test_no, protocols, ppt->want_protocols); + goto done; + } + + failed = 0; + + done: + return (failed); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + tls_init(); + + for (i = 0; i < N_PARSE_PROTOCOLS_TESTS; i++) + failed += do_parse_protocols_test(i, &parse_protocols_tests[i]); + + return (failed); +} diff --git a/Libraries/libressl/tests/constraints.c b/Libraries/libressl/tests/constraints.c new file mode 100644 index 000000000..6677b58c1 --- /dev/null +++ b/Libraries/libressl/tests/constraints.c @@ -0,0 +1,584 @@ +/* $OpenBSD: constraints.c,v 1.17 2023/10/01 04:48:39 tb Exp $ */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include "x509_internal.h" + +#define FAIL(msg, ...) \ +do { \ + fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ + fprintf(stderr, msg, ##__VA_ARGS__); \ +} while(0) + +unsigned char *valid_hostnames[] = { + "openbsd.org", + "op3nbsd.org", + "org", + "3openbsd.com", + "3-0penb-d.c-m", + "a", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "open_bsd.org", /* because this is liberal */ + NULL, +}; + +unsigned char *valid_sandns_names[] = { + "*.ca", + "*.op3nbsd.org", + "c*.openbsd.org", + "foo.*.d*.c*.openbsd.org", + NULL, +}; + +unsigned char *valid_domain_constraints[] = { + "", + ".ca", + ".op3nbsd.org", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "www.openbsd.org", + NULL, +}; + +unsigned char *valid_mbox_names[] = { + "\"!#$%&\\\"*+-/=?\002^_`{|}~.\"@openbsd.org", + "beck@openbsd.org", + "beck@openbsd.org", + "beck@op3nbsd.org", + "beck@org", + "beck@3openbsd.com", + "beck@3-0penb-d.c-m", + "bec@a", + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "beck@open_bsd.org", /* because this is liberal */ + NULL, +}; + +unsigned char *invalid_hostnames[] = { + "openbsd.org.", + "openbsd..org", + "openbsd.org-", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + "-p3nbsd.org", + "openbs-.org", + "openbsd\n.org", + "open\178bsd.org", + "open\255bsd.org", + "*.openbsd.org", + NULL, +}; + +unsigned char *invalid_sandns_names[] = { + "", + ".", + "*.a", + "*.", + "*.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + "*.-p3nbsd.org", + "*.*..openbsd.org", + "*..openbsd.org", + ".openbsd.org", + "c*c.openbsd.org", + NULL, +}; + +unsigned char *invalid_mbox_names[] = { + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + "beck@.-openbsd.org", + "beck@.openbsd.org.", + "beck@.a", + "beck@.", + "beck@", + "beck@.ca", + "@openbsd.org", + NULL, +}; + +unsigned char *invalid_domain_constraints[] = { + ".", + ".a", + "..", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + ".-p3nbsd.org", + "..openbsd.org", + NULL, +}; + +unsigned char *invaliduri[] = { + "https://-www.openbsd.org", + "https://.www.openbsd.org/", + "https://www.ope|nbsd.org%", + "https://www.openbsd.org.#", + "https://192.168.1.1./", + "https://192.168.1.1|/", + "https://.192.168.1.1/", + "https://192.168..1.1/", + "https://.2001:0DB8:AC10:FE01::/", + "https://.2001:0DB8:AC10:FE01::|/", + "///", + "//", + "/", + "", + NULL, +}; + +unsigned char *validuri[] = { + "https://www.openbsd.org/meep/meep/meep/", + "https://192.168.1.1/", + "https://2001:0DB8:AC10:FE01::/", + "https://192.168.1/", /* Not an IP, but valid component */ + "https://999.999.999.999/", /* Not an IP, but valid component */ + NULL, +}; + +static int +test_valid_hostnames(void) +{ + int i, failure = 0; + + for (i = 0; valid_hostnames[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, valid_hostnames[i], strlen(valid_hostnames[i])); + if (!x509_constraints_valid_host(&cbs, 0)) { + FAIL("Valid hostname '%s' rejected\n", + valid_hostnames[i]); + failure = 1; + goto done; + } + CBS_init(&cbs, valid_hostnames[i], strlen(valid_hostnames[i])); + if (!x509_constraints_valid_sandns(&cbs)) { + FAIL("Valid sandns '%s' rejected\n", + valid_hostnames[i]); + failure = 1; + goto done; + } + } + + done: + return failure; +} + +static int +test_valid_sandns_names(void) +{ + int i, failure = 0; + for (i = 0; valid_sandns_names[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, valid_sandns_names[i], + strlen(valid_sandns_names[i])); + if (!x509_constraints_valid_sandns(&cbs)) { + FAIL("Valid dnsname '%s' rejected\n", + valid_sandns_names[i]); + failure = 1; + goto done; + } + } + + done: + return failure; +} + +static int +test_valid_domain_constraints(void) +{ + int i, failure = 0; + for (i = 0; valid_domain_constraints[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, valid_domain_constraints[i], + strlen(valid_domain_constraints[i])); + if (!x509_constraints_valid_domain_constraint(&cbs)) { + FAIL("Valid dnsname '%s' rejected\n", + valid_domain_constraints[i]); + failure = 1; + goto done; + } + } + + done: + return failure; +} + +static int +test_valid_mbox_names(void) +{ + struct x509_constraints_name name = {0}; + int i, failure = 0; + for (i = 0; valid_mbox_names[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, valid_mbox_names[i], + strlen(valid_mbox_names[i])); + if (!x509_constraints_parse_mailbox(&cbs, &name)) { + FAIL("Valid mailbox name '%s' rejected\n", + valid_mbox_names[i]); + failure = 1; + goto done; + } + free(name.name); + name.name = NULL; + free(name.local); + name.local = NULL; + } + + done: + return failure; +} + +static int +test_invalid_hostnames(void) +{ + int i, failure = 0; + char *nulhost = "www.openbsd.org\0"; + CBS cbs; + + for (i = 0; invalid_hostnames[i] != NULL; i++) { + CBS_init(&cbs, invalid_hostnames[i], + strlen(invalid_hostnames[i])); + if (x509_constraints_valid_host(&cbs, 0)) { + FAIL("Invalid hostname '%s' accepted\n", + invalid_hostnames[i]); + failure = 1; + goto done; + } + } + CBS_init(&cbs, nulhost, strlen(nulhost) + 1); + if (x509_constraints_valid_host(&cbs, 0)) { + FAIL("hostname with NUL byte accepted\n"); + failure = 1; + goto done; + } + CBS_init(&cbs, nulhost, strlen(nulhost) + 1); + if (x509_constraints_valid_sandns(&cbs)) { + FAIL("sandns with NUL byte accepted\n"); + failure = 1; + goto done; + } + + done: + return failure; +} + +static int +test_invalid_sandns_names(void) +{ + int i, failure = 0; + for (i = 0; invalid_sandns_names[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, invalid_sandns_names[i], + strlen(invalid_sandns_names[i])); + if (x509_constraints_valid_sandns(&cbs)) { + FAIL("Valid dnsname '%s' rejected\n", + invalid_sandns_names[i]); + failure = 1; + goto done; + } + } + + done: + return failure; +} + +static int +test_invalid_mbox_names(void) +{ + int i, failure = 0; + struct x509_constraints_name name = {0}; + for (i = 0; invalid_mbox_names[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, invalid_mbox_names[i], + strlen(invalid_mbox_names[i])); + if (x509_constraints_parse_mailbox(&cbs, &name)) { + FAIL("invalid mailbox name '%s' accepted\n", + invalid_mbox_names[i]); + failure = 1; + goto done; + } + free(name.name); + name.name = NULL; + free(name.local); + name.local = NULL; + } + + done: + return failure; +} + +static int +test_invalid_domain_constraints(void) +{ + int i, failure = 0; + for (i = 0; invalid_domain_constraints[i] != NULL; i++) { + CBS cbs; + CBS_init(&cbs, invalid_domain_constraints[i], + strlen(invalid_domain_constraints[i])); + if (x509_constraints_valid_domain_constraint(&cbs)) { + FAIL("invalid dnsname '%s' accepted\n", + invalid_domain_constraints[i]); + failure = 1; + goto done; + } + } + + done: + return failure; +} + +static int +test_invalid_uri(void) +{ + int j, failure = 0; + char *hostpart = NULL; + + for (j = 0; invaliduri[j] != NULL; j++) { + if (x509_constraints_uri_host(invaliduri[j], + strlen(invaliduri[j]), &hostpart) != 0) { + FAIL("invalid URI '%s' accepted\n", + invaliduri[j]); + failure = 1; + goto done; + } + free(hostpart); + hostpart = NULL; + } + + done: + return failure; +} + +static int +test_valid_uri(void) +{ + int j, failure = 0; + char *hostpart = NULL; + + for (j = 0; validuri[j] != NULL; j++) { + if (x509_constraints_uri_host(validuri[j], + strlen(invaliduri[j]), &hostpart) == 0) { + FAIL("Valid URI '%s' NOT accepted\n", + validuri[j]); + failure = 1; + goto done; + } + free(hostpart); + hostpart = NULL; + } + + done: + return failure; +} + +static int +test_constraints1(void) +{ + char *c; + size_t cl; + char *d; + size_t dl; + int failure = 0; + int error = 0; + int i, j; + unsigned char *constraints[] = { + ".org", + ".openbsd.org", + "www.openbsd.org", + NULL, + }; + unsigned char *failing[] = { + ".ca", + "openbsd.ca", + "org", + NULL, + }; + unsigned char *matching[] = { + "www.openbsd.org", + NULL, + }; + unsigned char *matchinguri[] = { + "https://www.openbsd.org", + "https://www.openbsd.org/", + "https://www.openbsd.org?", + "https://www.openbsd.org#", + "herp://beck@www.openbsd.org:", + "spiffe://beck@www.openbsd.org/this/is/so/spiffe/", + NULL, + }; + unsigned char *failinguri[] = { + "https://www.openbsd.ca", + "https://www.freebsd.com/", + "https://www.openbsd.net?", + "https://org#", + "herp://beck@org:", + "///", + "//", + "/", + "", + NULL, + }; + unsigned char *noauthority[] = { + "urn:open62541.server.application", + NULL, + }; + for (i = 0; constraints[i] != NULL; i++) { + char *constraint = constraints[i]; + size_t clen = strlen(constraints[i]); + for (j = 0; matching[j] != NULL; j++) { + if (!x509_constraints_domain(matching[j], + strlen(matching[j]), constraint, clen)) { + FAIL("constraint '%s' should have matched" + " '%s'\n", + constraint, matching[j]); + failure = 1; + goto done; + } + } + for (j = 0; matchinguri[j] != NULL; j++) { + error = 0; + if (!x509_constraints_uri(matchinguri[j], + strlen(matchinguri[j]), constraint, clen, &error)) { + FAIL("constraint '%s' should have matched URI" + " '%s' (error %d)\n", + constraint, matchinguri[j], error); + failure = 1; + goto done; + } + } + for (j = 0; failing[j] != NULL; j++) { + if (x509_constraints_domain(failing[j], + strlen(failing[j]), constraint, clen)) { + FAIL("constraint '%s' should not have matched" + " '%s'\n", + constraint, failing[j]); + failure = 1; + goto done; + } + } + for (j = 0; failinguri[j] != NULL; j++) { + error = 0; + if (x509_constraints_uri(failinguri[j], + strlen(failinguri[j]), constraint, clen, &error)) { + FAIL("constraint '%s' should not have matched URI" + " '%s' (error %d)\n", + constraint, failinguri[j], error); + failure = 1; + goto done; + } + } + for (j = 0; noauthority[j] != NULL; j++) { + char *hostpart = NULL; + error = 0; + if (!x509_constraints_uri_host(noauthority[j], + strlen(noauthority[j]), NULL) || + !x509_constraints_uri_host(noauthority[j], + strlen(noauthority[j]), &hostpart)) { + FAIL("name '%s' should parse as a URI", + noauthority[j]); + failure = 1; + free(hostpart); + goto done; + } + free(hostpart); + + if (x509_constraints_uri(noauthority[j], + strlen(noauthority[j]), constraint, clen, &error)) { + FAIL("constraint '%s' should not have matched URI" + " '%s' (error %d)\n", + constraint, failinguri[j], error); + failure = 1; + goto done; + } + } + } + c = ".openbsd.org"; + cl = strlen(".openbsd.org"); + d = "*.openbsd.org"; + dl = strlen("*.openbsd.org"); + if (!x509_constraints_domain(d, dl, c, cl)) { + FAIL("constraint '%s' should have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + c = "www.openbsd.org"; + cl = strlen("www.openbsd.org"); + if (x509_constraints_domain(d, dl, c, cl)) { + FAIL("constraint '%s' should not have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + c = ""; + cl = 0; + if (!x509_constraints_domain(d, dl, c, cl)) { + FAIL("constraint '%s' should have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + + done: + return failure; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_valid_hostnames(); + failed |= test_invalid_hostnames(); + failed |= test_valid_sandns_names(); + failed |= test_invalid_sandns_names(); + failed |= test_valid_mbox_names(); + failed |= test_invalid_mbox_names(); + failed |= test_valid_domain_constraints(); + failed |= test_invalid_domain_constraints(); + failed |= test_invalid_uri(); + failed |= test_valid_uri(); + failed |= test_constraints1(); + + return (failed); +} diff --git a/Libraries/libressl/tests/ctlog.conf b/Libraries/libressl/tests/ctlog.conf new file mode 100644 index 000000000..83a01f63c --- /dev/null +++ b/Libraries/libressl/tests/ctlog.conf @@ -0,0 +1,5 @@ +enabled_logs = argon2022 + +[argon2022] +description = Google Argon 2022 +key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeIPc6fGmuBg6AJkv/z7NFckmHvf/OqmjchZJ6wm2qN200keRDg352dWpi7CHnSV51BpQYAj1CQY5JuRAwrrDwg== diff --git a/Libraries/libressl/tests/cttest.c b/Libraries/libressl/tests/cttest.c new file mode 100644 index 000000000..9e0a99b61 --- /dev/null +++ b/Libraries/libressl/tests/cttest.c @@ -0,0 +1,491 @@ +/* $OpenBSD: cttest.c,v 1.8 2023/04/14 14:36:13 tb Exp $ */ +/* + * Copyright (c) 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +#ifndef CTPATH +#define CTPATH "." +#endif + +char *test_ctlog_conf_file; +char *test_cert_file; +char *test_issuer_file; + +const int debug = 0; + +const uint8_t scts_asn1[] = { + 0x04, 0x81, 0xf2, 0x00, 0xf0, 0x00, 0x77, 0x00, + 0x29, 0x79, 0xbe, 0xf0, 0x9e, 0x39, 0x39, 0x21, + 0xf0, 0x56, 0x73, 0x9f, 0x63, 0xa5, 0x77, 0xe5, + 0xbe, 0x57, 0x7d, 0x9c, 0x60, 0x0a, 0xf8, 0xf9, + 0x4d, 0x5d, 0x26, 0x5c, 0x25, 0x5d, 0xc7, 0x84, + 0x00, 0x00, 0x01, 0x7d, 0x39, 0x51, 0x1f, 0x6f, + 0x00, 0x00, 0x04, 0x03, 0x00, 0x48, 0x30, 0x46, + 0x02, 0x21, 0x00, 0x93, 0xed, 0x3a, 0x65, 0x98, + 0x9a, 0x85, 0xf0, 0x3b, 0x3c, 0x26, 0xf7, 0x52, + 0x94, 0xd7, 0x92, 0x48, 0xc2, 0xc0, 0x64, 0xcb, + 0x01, 0xf5, 0xec, 0xf7, 0x6d, 0x41, 0xe0, 0xbd, + 0x28, 0x56, 0xad, 0x02, 0x21, 0x00, 0xc2, 0x4f, + 0x92, 0xfb, 0xa0, 0xbb, 0xef, 0x55, 0x67, 0x80, + 0x06, 0x10, 0x07, 0xe7, 0xb9, 0xb1, 0x96, 0xa7, + 0xa9, 0x8b, 0xb2, 0xcb, 0xd3, 0x9c, 0x4e, 0x02, + 0xe8, 0xdb, 0x24, 0x65, 0x1e, 0xc8, 0x00, 0x75, + 0x00, 0x6f, 0x53, 0x76, 0xac, 0x31, 0xf0, 0x31, + 0x19, 0xd8, 0x99, 0x00, 0xa4, 0x51, 0x15, 0xff, + 0x77, 0x15, 0x1c, 0x11, 0xd9, 0x02, 0xc1, 0x00, + 0x29, 0x06, 0x8d, 0xb2, 0x08, 0x9a, 0x37, 0xd9, + 0x13, 0x00, 0x00, 0x01, 0x7d, 0x39, 0x51, 0x20, + 0x3b, 0x00, 0x00, 0x04, 0x03, 0x00, 0x46, 0x30, + 0x44, 0x02, 0x20, 0x26, 0xc9, 0x12, 0x28, 0x70, + 0x2d, 0x15, 0x05, 0xa7, 0xa2, 0xea, 0x12, 0x1a, + 0xff, 0x39, 0x36, 0x5f, 0x93, 0xdf, 0x83, 0x36, + 0x5f, 0xed, 0x07, 0x38, 0xb8, 0x0a, 0x40, 0xe1, + 0x8d, 0xb9, 0xfa, 0x02, 0x20, 0x61, 0xae, 0x2b, + 0x86, 0xbd, 0x8e, 0x86, 0x65, 0x2b, 0xfb, 0x63, + 0xe1, 0xda, 0x77, 0xb3, 0xf3, 0xc5, 0x2a, 0x32, + 0xb8, 0x23, 0x1e, 0x7e, 0xfa, 0x7d, 0x83, 0xa5, + 0x49, 0x00, 0xc4, 0x57, 0xb8, +}; + +const char *sct_log_id1_base64 = "KXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4Q="; + +const uint8_t sct_signature1[] = { + 0x30, 0x46, 0x02, 0x21, 0x00, 0x93, 0xed, 0x3a, + 0x65, 0x98, 0x9a, 0x85, 0xf0, 0x3b, 0x3c, 0x26, + 0xf7, 0x52, 0x94, 0xd7, 0x92, 0x48, 0xc2, 0xc0, + 0x64, 0xcb, 0x01, 0xf5, 0xec, 0xf7, 0x6d, 0x41, + 0xe0, 0xbd, 0x28, 0x56, 0xad, 0x02, 0x21, 0x00, + 0xc2, 0x4f, 0x92, 0xfb, 0xa0, 0xbb, 0xef, 0x55, + 0x67, 0x80, 0x06, 0x10, 0x07, 0xe7, 0xb9, 0xb1, + 0x96, 0xa7, 0xa9, 0x8b, 0xb2, 0xcb, 0xd3, 0x9c, + 0x4e, 0x02, 0xe8, 0xdb, 0x24, 0x65, 0x1e, 0xc8 +}; + +const char *sct_signature1_base64 = + "BAMASDBGAiEAk+06ZZiahfA7PCb3UpTXkkjCwGTLAfXs921B4L0oVq0CIQDCT5L7oLvvVWeABh" + "AH57mxlqepi7LL05xOAujbJGUeyA=="; + +const char *sct_log_id2_base64 = "b1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RM="; + +const uint8_t sct_signature2[] = { + 0x30, 0x44, 0x02, 0x20, 0x26, 0xc9, 0x12, 0x28, + 0x70, 0x2d, 0x15, 0x05, 0xa7, 0xa2, 0xea, 0x12, + 0x1a, 0xff, 0x39, 0x36, 0x5f, 0x93, 0xdf, 0x83, + 0x36, 0x5f, 0xed, 0x07, 0x38, 0xb8, 0x0a, 0x40, + 0xe1, 0x8d, 0xb9, 0xfa, 0x02, 0x20, 0x61, 0xae, + 0x2b, 0x86, 0xbd, 0x8e, 0x86, 0x65, 0x2b, 0xfb, + 0x63, 0xe1, 0xda, 0x77, 0xb3, 0xf3, 0xc5, 0x2a, + 0x32, 0xb8, 0x23, 0x1e, 0x7e, 0xfa, 0x7d, 0x83, + 0xa5, 0x49, 0x00, 0xc4, 0x57, 0xb8 +}; + +const char *sct_signature2_base64 = + "BAMARjBEAiAmyRIocC0VBaei6hIa/zk2X5PfgzZf7Qc4uApA4Y25+gIgYa4rhr2OhmUr+2Ph2n" + "ez88UqMrgjHn76fYOlSQDEV7g="; + +struct sct_data { + uint8_t version; + uint8_t log_id[32]; + uint64_t timestamp; + size_t extensions_len; + int signature_nid; + const uint8_t *signature; + size_t signature_len; +}; + +const struct sct_data sct_test_data[] = { + { + .version = 0, + .log_id = { + 0x29, 0x79, 0xbe, 0xf0, 0x9e, 0x39, 0x39, 0x21, + 0xf0, 0x56, 0x73, 0x9f, 0x63, 0xa5, 0x77, 0xe5, + 0xbe, 0x57, 0x7d, 0x9c, 0x60, 0x0a, 0xf8, 0xf9, + 0x4d, 0x5d, 0x26, 0x5c, 0x25, 0x5d, 0xc7, 0x84, + }, + .timestamp = 1637344157551LL, + .extensions_len = 0, + .signature_nid = NID_ecdsa_with_SHA256, + .signature = sct_signature1, + .signature_len = sizeof(sct_signature1), + }, + { + .version = 0, + .log_id = { + 0x6f, 0x53, 0x76, 0xac, 0x31, 0xf0, 0x31, 0x19, + 0xd8, 0x99, 0x00, 0xa4, 0x51, 0x15, 0xff, 0x77, + 0x15, 0x1c, 0x11, 0xd9, 0x02, 0xc1, 0x00, 0x29, + 0x06, 0x8d, 0xb2, 0x08, 0x9a, 0x37, 0xd9, 0x13 + }, + .timestamp = 1637344157755LL, + .extensions_len = 0, + .signature_nid = NID_ecdsa_with_SHA256, + .signature = sct_signature2, + .signature_len = sizeof(sct_signature2), + }, +}; + +#define N_SCT_TEST_DATA (sizeof(sct_test_data) / sizeof(*sct_test_data)) + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +static void +cert_from_file(const char *filename, X509 **cert) +{ + BIO *bio = NULL; + X509 *x; + + if ((bio = BIO_new_file(filename, "r")) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to create bio"); + } + if ((x = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) + errx(1, "failed to read PEM"); + + *cert = x; + + BIO_free(bio); +} + +static int +ct_compare_test_scts(STACK_OF(SCT) *scts) +{ + const struct sct_data *sdt; + BIO *bio_err = NULL; + SCT *sct; + uint8_t *data; + size_t len; + int i; + int ret = 0; + + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + if (sk_SCT_num(scts) != N_SCT_TEST_DATA) { + fprintf(stderr, "FAIL: got %d SCTS, want %zu\n", + sk_SCT_num(scts), N_SCT_TEST_DATA); + goto failure; + } + + for (i = 0; i < sk_SCT_num(scts); i++) { + sct = sk_SCT_value(scts, i); + sdt = &sct_test_data[i]; + + if (debug > 0) { + SCT_print(sct, bio_err, 0, NULL); + BIO_printf(bio_err, "\n"); + } + + if (SCT_get_version(sct) != sdt->version) { + fprintf(stderr, "FAIL: SCT %d - got version %u, " + "want %u\n", i, SCT_get_version(sct), sdt->version); + goto failure; + } + len = SCT_get0_log_id(sct, &data); + if (len != sizeof(sdt->log_id)) { + fprintf(stderr, "FAIL: SCT %d - got version %u, " + "want %u\n", i, SCT_get_version(sct), sdt->version); + goto failure; + } + if (memcmp(data, sdt->log_id, len) != 0) { + fprintf(stderr, "FAIL: SCT %d - log ID differs\n", i); + fprintf(stderr, "Got:\n"); + hexdump(data, len); + fprintf(stderr, "Want:\n"); + hexdump(sdt->log_id, sizeof(sdt->log_id)); + goto failure; + } + if (SCT_get_timestamp(sct) != sdt->timestamp) { + fprintf(stderr, "FAIL: SCT %d - got timestamp %llu, " + "want %llu\n", i, + (unsigned long long)SCT_get_timestamp(sct), + (unsigned long long)sdt->timestamp); + goto failure; + } + if (SCT_get_signature_nid(sct) != sdt->signature_nid) { + fprintf(stderr, "FAIL: SCT %d - got signature_nid %d, " + "want %d\n", i, SCT_get_signature_nid(sct), + sdt->signature_nid); + goto failure; + } + len = SCT_get0_extensions(sct, &data); + if (len != sdt->extensions_len) { + fprintf(stderr, "FAIL: SCT %d - got extensions with " + "length %zu, want %zu\n", i, len, + sdt->extensions_len); + goto failure; + } + len = SCT_get0_signature(sct, &data); + if (len != sdt->signature_len) { + fprintf(stderr, "FAIL: SCT %d - got signature with " + "length %zu, want %zu\n", i, len, + sdt->signature_len); + goto failure; + } + if (memcmp(data, sdt->signature, len) != 0) { + fprintf(stderr, "FAIL: SCT %d - signature differs\n", + i); + fprintf(stderr, "Got:\n"); + hexdump(data, len); + fprintf(stderr, "Want:\n"); + hexdump(sdt->signature, sdt->signature_len); + goto failure; + } + } + + ret = 1; + + failure: + BIO_free(bio_err); + + return ret; +} + +static int +ct_cert_test(void) +{ + X509 *cert = NULL; + X509_EXTENSION *ext; + STACK_OF(SCT) *scts = NULL; + int idx; + int failed = 1; + + cert_from_file(test_cert_file, &cert); + + if ((idx = X509_get_ext_by_NID(cert, NID_ct_precert_scts, -1)) == -1) { + fprintf(stderr, "FAIL: failed to find SCTs\n"); + goto failure; + } + if ((ext = X509_get_ext(cert, idx)) == NULL) { + fprintf(stderr, "FAIL: failed to get SCT extension\n"); + goto failure; + } + if ((scts = X509V3_EXT_d2i(ext)) == NULL) { + fprintf(stderr, "FAIL: failed to decode SCTs\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (!ct_compare_test_scts(scts)) + goto failure; + + failed = 0; + + failure: + SCT_LIST_free(scts); + X509_free(cert); + + return failed; +} + +static int +ct_sct_test(void) +{ + STACK_OF(SCT) *scts = NULL; + const uint8_t *p; + uint8_t *data = NULL; + int len; + int failed = 1; + + p = scts_asn1; + if ((scts = d2i_SCT_LIST(NULL, &p, sizeof(scts_asn1))) == NULL) { + fprintf(stderr, "FAIL: failed to decode SCTS from ASN.1\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (!ct_compare_test_scts(scts)) + goto failure; + + data = NULL; + if ((len = i2d_SCT_LIST(scts, &data)) <= 0) { + fprintf(stderr, "FAIL: failed to encode SCTS to ASN.1\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + if (len != sizeof(scts_asn1)) { + fprintf(stderr, "FAIL: ASN.1 length differs - got %d, want " + "%zu\n", len, sizeof(scts_asn1)); + goto failure; + } + if (memcmp(data, scts_asn1, len) != 0) { + fprintf(stderr, "FAIL: ASN.1 for SCTS differs\n"); + fprintf(stderr, "Got:\n"); + hexdump(data, len); + fprintf(stderr, "Want:\n"); + hexdump(scts_asn1, sizeof(scts_asn1)); + goto failure; + } + + failed = 0; + + failure: + SCT_LIST_free(scts); + free(data); + + return failed; +} + +static int +ct_sct_base64_test(void) +{ + SCT *sct1 = NULL, *sct2 = NULL; + STACK_OF(SCT) *scts = NULL; + int failed = 1; + + if ((sct1 = SCT_new_from_base64(SCT_VERSION_V1, sct_log_id1_base64, + CT_LOG_ENTRY_TYPE_X509, 1637344157551LL, "", + sct_signature1_base64)) == NULL) { + fprintf(stderr, "FAIL: SCT_new_from_base64() failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + if ((sct2 = SCT_new_from_base64(SCT_VERSION_V1, sct_log_id2_base64, + CT_LOG_ENTRY_TYPE_X509, 1637344157755LL, "", + sct_signature2_base64)) == NULL) { + fprintf(stderr, "FAIL: SCT_new_from_base64() failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + if ((scts = sk_SCT_new_null()) == NULL) + goto failure; + if (!sk_SCT_push(scts, sct1)) + goto failure; + sct1 = NULL; + if (!sk_SCT_push(scts, sct2)) + goto failure; + sct2 = NULL; + + if (!ct_compare_test_scts(scts)) + goto failure; + + failed = 0; + + failure: + SCT_LIST_free(scts); + SCT_free(sct1); + SCT_free(sct2); + + return failed; +} + +static int +ct_sct_verify_test(void) +{ + STACK_OF(SCT) *scts = NULL; + CT_POLICY_EVAL_CTX *ct_policy = NULL; + CTLOG_STORE *ctlog_store = NULL; + X509 *cert = NULL, *issuer = NULL; + const uint8_t *p; + SCT *sct; + int failed = 1; + + cert_from_file(test_cert_file, &cert); + cert_from_file(test_issuer_file, &issuer); + + if ((ctlog_store = CTLOG_STORE_new()) == NULL) + goto failure; + if (!CTLOG_STORE_load_file(ctlog_store, test_ctlog_conf_file)) + goto failure; + + if ((ct_policy = CT_POLICY_EVAL_CTX_new()) == NULL) + goto failure; + + CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ct_policy, ctlog_store); + CT_POLICY_EVAL_CTX_set_time(ct_policy, 1641393117000LL); + + if (!CT_POLICY_EVAL_CTX_set1_cert(ct_policy, cert)) + goto failure; + if (!CT_POLICY_EVAL_CTX_set1_issuer(ct_policy, issuer)) + goto failure; + + p = scts_asn1; + if ((scts = d2i_SCT_LIST(NULL, &p, sizeof(scts_asn1))) == NULL) { + fprintf(stderr, "FAIL: failed to decode SCTS from ASN.1\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + sct = sk_SCT_value(scts, 0); + + if (!SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT)) + goto failure; + if (!SCT_validate(sct, ct_policy)) { + fprintf(stderr, "FAIL: SCT_validate failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + failed = 0; + + failure: + CT_POLICY_EVAL_CTX_free(ct_policy); + CTLOG_STORE_free(ctlog_store); + X509_free(cert); + X509_free(issuer); + SCT_LIST_free(scts); + + return failed; +} + +int +main(int argc, char **argv) +{ + const char *ctpath = CTPATH; + int failed = 0; + + if (argc > 2) { + fprintf(stderr, "usage %s [ctpath]\n", argv[0]); + exit(1); + } + if (argc == 2) + ctpath = argv[1]; + + if (asprintf(&test_cert_file, "%s/%s", ctpath, + "libressl.org.crt") == -1) + errx(1, "asprintf test_cert_file"); + if (asprintf(&test_issuer_file, "%s/%s", ctpath, + "letsencrypt-r3.crt") == -1) + errx(1, "asprintf test_issuer_file"); + if (asprintf(&test_ctlog_conf_file, "%s/%s", ctpath, + "ctlog.conf") == -1) + errx(1, "asprintf test_ctlog_conf_file"); + + failed |= ct_cert_test(); + failed |= ct_sct_test(); + failed |= ct_sct_base64_test(); + failed |= ct_sct_verify_test(); + + free(test_cert_file); + free(test_issuer_file); + free(test_ctlog_conf_file); + + return (failed); +} diff --git a/Libraries/libressl/tests/destest.c b/Libraries/libressl/tests/destest.c new file mode 100644 index 000000000..ebc67f310 --- /dev/null +++ b/Libraries/libressl/tests/destest.c @@ -0,0 +1,884 @@ +/* $OpenBSD: destest.c,v 1.4 2018/07/17 17:06:49 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include + +#include + +#define crypt(c,s) (DES_crypt((c),(s))) + +/* tisk tisk - the test keys don't all have odd parity :-( */ +/* test data */ +#define NUM_TESTS 34 +static unsigned char key_data[NUM_TESTS][8]={ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, + {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, + {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, + {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, + {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, + {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, + {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, + {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, + {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, + {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, + {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, + {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, + {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, + {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, + {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, + {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, + {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, + {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, + {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, + {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, + {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, + {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; + +static unsigned char plain_data[NUM_TESTS][8]={ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, + {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, + {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, + {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, + {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, + {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, + {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, + {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, + {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, + {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, + {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, + {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, + {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, + {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, + {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, + {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, + {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, + {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, + {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; + +static unsigned char cipher_data[NUM_TESTS][8]={ + {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, + {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, + {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, + {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, + {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, + {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, + {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, + {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, + {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, + {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, + {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, + {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, + {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, + {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, + {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, + {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, + {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, + {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, + {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, + {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, + {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, + {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, + {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, + {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, + {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, + {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, + {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, + {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, + {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, + {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, + {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, + {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, + {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, + {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; + +static unsigned char cipher_ecb2[NUM_TESTS-1][8]={ + {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E}, + {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16}, + {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27}, + {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6}, + {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25}, + {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A}, + {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74}, + {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6}, + {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67}, + {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10}, + {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85}, + {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA}, + {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3}, + {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3}, + {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A}, + {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69}, + {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1}, + {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7}, + {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F}, + {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87}, + {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A}, + {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE}, + {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3}, + {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD}, + {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84}, + {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85}, + {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC}, + {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89}, + {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E}, + {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89}, + {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7}, + {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8}, + {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}}; + +static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cbc2_key[8]={0xf1,0xe0,0xd3,0xc2,0xb5,0xa4,0x97,0x86}; +static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +/* Changed the following text constant to binary so it will work on ebcdic + * machines :-) */ +/* static char cbc_data[40]="7654321 Now is the time for \0001"; */ +static unsigned char cbc_data[40]={ + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x20, + 0x4E,0x6F,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6D,0x65,0x20, + 0x66,0x6F,0x72,0x20,0x00,0x31,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + +static unsigned char cbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, + 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, + 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +#ifdef SCREW_THE_PARITY +#error "SCREW_THE_PARITY is not ment to be defined." +#error "Original vectors are preserved for reference only." +static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; +static unsigned char xcbc_ok[32]={ + 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48, + 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD, + 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76, + 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2, + }; +#else +static unsigned char xcbc_ok[32]={ + 0x84,0x6B,0x29,0x14,0x85,0x1E,0x9A,0x29, + 0x54,0x73,0x2F,0x8A,0xA0,0xA6,0x11,0xC1, + 0x15,0xCD,0xC2,0xD7,0x95,0x1B,0x10,0x53, + 0xA6,0x3C,0x5E,0x03,0xB2,0x1A,0xA3,0xC4, + }; +#endif + +static unsigned char cbc3_ok[32]={ + 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0, + 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC, + 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4, + 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75}; + +static unsigned char pcbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, + 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, + 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; + +static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; +static unsigned char plain[24]= + { + 0x4e,0x6f,0x77,0x20,0x69,0x73, + 0x20,0x74,0x68,0x65,0x20,0x74, + 0x69,0x6d,0x65,0x20,0x66,0x6f, + 0x72,0x20,0x61,0x6c,0x6c,0x20 + }; +static unsigned char cfb_cipher8[24]= { + 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, + 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 }; +static unsigned char cfb_cipher16[24]={ + 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70, + 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B }; +static unsigned char cfb_cipher32[24]={ + 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD, + 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 }; +static unsigned char cfb_cipher48[24]={ + 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85, + 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F }; +static unsigned char cfb_cipher64[24]={ + 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B, + 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 }; + +static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; +static unsigned char ofb_cipher[24]= + { + 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, + 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, + 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 + }; + +#if 0 +static DES_LONG cbc_cksum_ret=0xB462FEF7L; +#else +static DES_LONG cbc_cksum_ret=0xF7FE62B4L; +#endif +static unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +static char *pt(unsigned char *p); +static int cfb_test(int bits, unsigned char *cfb_cipher); +static int cfb64_test(unsigned char *cfb_cipher); +static int ede_cfb64_test(unsigned char *cfb_cipher); +int main(int argc, char *argv[]) + { + int j,err=0; + unsigned int i; + DES_cblock in,out,outin,iv3,iv2; + DES_key_schedule ks,ks2,ks3; + unsigned char cbc_in[40]; + unsigned char cbc_out[40]; + DES_LONG cs; + unsigned char cret[8]; + DES_LONG lqret[4]; + int num; + char *str; + +#ifndef OPENSSL_NO_DESCBCM + printf("Doing cbcm\n"); + if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0) + { + printf("Key error %d\n",j); + err=1; + } + if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0) + { + printf("Key error %d\n",j); + err=1; + } + if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0) + { + printf("Key error %d\n",j); + err=1; + } + memset(cbc_out,0,40); + memset(cbc_in,0,40); + i=strlen((char *)cbc_data)+1; + /* i=((i+7)/8)*8; */ + memcpy(iv3,cbc_iv,sizeof(cbc_iv)); + memset(iv2,'\0',sizeof iv2); + + DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2, + DES_ENCRYPT); + DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3, + &iv3,&iv2,DES_ENCRYPT); + /* if (memcmp(cbc_out,cbc3_ok, + (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0) + { + printf("des_ede3_cbc_encrypt encrypt error\n"); + err=1; + } + */ + memcpy(iv3,cbc_iv,sizeof(cbc_iv)); + memset(iv2,'\0',sizeof iv2); + DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT); + if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0) + { + unsigned int n; + + printf("des_ede3_cbcm_encrypt decrypt error\n"); + for(n=0 ; n < i ; ++n) + printf(" %02x",cbc_data[n]); + printf("\n"); + for(n=0 ; n < i ; ++n) + printf(" %02x",cbc_in[n]); + printf("\n"); + err=1; + } +#endif + + printf("Doing ecb\n"); + for (i=0; i>4)&0xf]; + ret[i*2+1]=f[p[i]&0xf]; + } + ret[16]='\0'; + return(ret); + } + +static int cfb_test(int bits, unsigned char *cfb_cipher) + { + DES_key_schedule ks; + int i,err=0; + + DES_set_key_checked(&cfb_key,&ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + DES_cfb_encrypt(plain,cfb_buf1,bits,sizeof(plain),&ks,&cfb_tmp, + DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + DES_cfb_encrypt(cfb_buf1,cfb_buf2,bits,sizeof(plain),&ks,&cfb_tmp, + DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + return(err); + } + +static int cfb64_test(unsigned char *cfb_cipher) + { + DES_key_schedule ks; + int err=0,i,n; + + DES_set_key_checked(&cfb_key,&ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + DES_cfb64_encrypt(plain,cfb_buf1,12,&ks,&cfb_tmp,&n,DES_ENCRYPT); + DES_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),sizeof(plain)-12,&ks, + &cfb_tmp,&n,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + DES_cfb64_encrypt(cfb_buf1,cfb_buf2,17,&ks,&cfb_tmp,&n,DES_DECRYPT); + DES_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), + sizeof(plain)-17,&ks,&cfb_tmp,&n,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf2[i]))); + } + return(err); + } + +static int ede_cfb64_test(unsigned char *cfb_cipher) + { + DES_key_schedule ks; + int err=0,i,n; + + DES_set_key_checked(&cfb_key,&ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + DES_ede3_cfb64_encrypt(plain,cfb_buf1,12,&ks,&ks,&ks,&cfb_tmp,&n, + DES_ENCRYPT); + DES_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), + sizeof(plain)-12,&ks,&ks,&ks, + &cfb_tmp,&n,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("ede_cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + DES_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&ks,&ks,&ks, + &cfb_tmp,&n,DES_DECRYPT); + DES_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), + sizeof(plain)-17,&ks,&ks,&ks, + &cfb_tmp,&n,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("ede_cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf2[i]))); + } + return(err); + } diff --git a/Libraries/libressl/tests/dhtest.c b/Libraries/libressl/tests/dhtest.c new file mode 100644 index 000000000..0df54273e --- /dev/null +++ b/Libraries/libressl/tests/dhtest.c @@ -0,0 +1,170 @@ +/* $OpenBSD: dhtest.c,v 1.14 2023/08/20 22:21:00 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static int +cb(int p, int n, BN_GENCB *arg) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + printf("%c", c); + fflush(stdout); + return 1; +} + +int +main(int argc, char *argv[]) +{ + BN_GENCB *_cb; + DH *dh = NULL; + unsigned char *buf = NULL; + int flags, buf_len, secret_len; + int i; + int ret = 1; + + if ((_cb = BN_GENCB_new()) == NULL) + err(1, "BN_GENCB_new"); + + BN_GENCB_set(_cb, &cb, NULL); + if ((dh = DH_new()) == NULL) + goto err; + +#ifdef OPENSSL_NO_ENGINE + if (DH_get0_engine(dh) != NULL) { + fprintf(stderr, "ENGINE was not NULL\n"); + goto err; + } +#endif + + if (!DH_generate_parameters_ex(dh, 64, DH_GENERATOR_5, _cb)) + goto err; + + if (!DH_check(dh, &flags)) + goto err; + if (flags & DH_CHECK_P_NOT_PRIME) + printf("p value is not prime\n"); + if (flags & DH_CHECK_P_NOT_SAFE_PRIME) + printf("p value is not a safe prime\n"); + if (flags & DH_UNABLE_TO_CHECK_GENERATOR) + printf("unable to check the generator value\n"); + if (flags & DH_NOT_SUITABLE_GENERATOR) + printf("the g value is not a generator\n"); + + printf("\np = "); + if (!BN_print_fp(stdout, DH_get0_p(dh))) + goto err; + printf("\ng = "); + if (!BN_print_fp(stdout, DH_get0_g(dh))) + goto err; + printf("\n"); + + if (!DH_generate_key(dh)) + goto err; + printf("pri1 = "); + if (!BN_print_fp(stdout, DH_get0_priv_key(dh))) + goto err; + printf("\npub1 = "); + if (!BN_print_fp(stdout, DH_get0_pub_key(dh))) + goto err; + printf("\n"); + + buf_len = DH_size(dh); + if ((buf = malloc(buf_len)) == NULL) + err(1, "malloc"); + secret_len = DH_compute_key(buf, DH_get0_pub_key(dh), dh); + + printf("key1 = "); + for (i = 0; i < secret_len; i++) { + printf("%02X", buf[i]); + } + printf("\n"); + + if (secret_len < 4) { + fprintf(stderr, "Error in DH routines\n"); + goto err; + } + + ret = 0; +err: + ERR_print_errors_fp(stderr); + + free(buf); + DH_free(dh); + BN_GENCB_free(_cb); + + return (ret); +} diff --git a/Libraries/libressl/tests/dsatest.c b/Libraries/libressl/tests/dsatest.c new file mode 100644 index 000000000..62343455f --- /dev/null +++ b/Libraries/libressl/tests/dsatest.c @@ -0,0 +1,235 @@ +/* $OpenBSD: dsatest.c,v 1.9 2023/08/20 22:22:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static int dsa_cb(int p, int n, BN_GENCB *arg); + +/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to + * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */ +static unsigned char seed[20] = { + 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40, + 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3, +}; + +static unsigned char out_p[] = { + 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, + 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb, + 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7, + 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, + 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, + 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac, + 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2, + 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91, +}; + +static unsigned char out_q[] = { + 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, + 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e, + 0xda, 0xce, 0x91, 0x5f, +}; + +static unsigned char out_g[] = { + 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, + 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00, + 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb, + 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, + 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, + 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c, + 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c, + 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02, +}; + +static const unsigned char str1[] = "12345678901234567890"; + +static BIO *bio_err = NULL; + +int +main(int argc, char **argv) +{ + BN_GENCB *cb; + DSA *dsa = NULL; + int counter, i, j; + unsigned char buf[256]; + unsigned long h; + unsigned char sig[256]; + unsigned int siglen; + int ret = 0; + + if (bio_err == NULL) + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + ERR_load_crypto_strings(); + + BIO_printf(bio_err, "test generation of DSA parameters\n"); + + if ((cb = BN_GENCB_new()) == NULL) + goto end; + + BN_GENCB_set(cb, dsa_cb, bio_err); + if ((dsa = DSA_new()) == NULL) + goto end; + +#ifdef OPENSSL_NO_ENGINE + if (DSA_get0_engine(dsa) != NULL) { + BIO_printf(bio_err, "ENGINE was not NULL\n"); + goto end; + } +#endif + + if (!DSA_generate_parameters_ex(dsa, 512, seed, 20, &counter, &h, cb)) + goto end; + + BIO_printf(bio_err, "seed\n"); + for (i = 0; i < 20; i += 4) { + BIO_printf(bio_err, "%02X%02X%02X%02X ", + seed[i], seed[i + 1], seed[i + 2], seed[i + 3]); + } + BIO_printf(bio_err, "\ncounter=%d h=%ld\n", counter, h); + + DSA_print(bio_err, dsa, 0); + if (counter != 105) { + BIO_printf(bio_err, "counter should be 105\n"); + goto end; + } + if (h != 2) { + BIO_printf(bio_err, "h should be 2\n"); + goto end; + } + + i = BN_bn2bin(DSA_get0_q(dsa), buf); + j = sizeof(out_q); + if ((i != j) || (memcmp(buf, out_q, i) != 0)) { + BIO_printf(bio_err, "q value is wrong\n"); + goto end; + } + + i = BN_bn2bin(DSA_get0_p(dsa), buf); + j = sizeof(out_p); + if ((i != j) || (memcmp(buf, out_p, i) != 0)) { + BIO_printf(bio_err, "p value is wrong\n"); + goto end; + } + + i = BN_bn2bin(DSA_get0_g(dsa), buf); + j = sizeof(out_g); + if ((i != j) || (memcmp(buf, out_g, i) != 0)) { + BIO_printf(bio_err, "g value is wrong\n"); + goto end; + } + + DSA_generate_key(dsa); + DSA_sign(0, str1, 20, sig, &siglen, dsa); + if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1) + ret = 1; + +end: + BN_GENCB_free(cb); + if (!ret) + ERR_print_errors(bio_err); + DSA_free(dsa); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(bio_err); + BIO_free(bio_err); + bio_err = NULL; + + return !ret; +} + +static int +dsa_cb(int p, int n, BN_GENCB *arg) +{ + char c = '*'; + static int ok = 0, num = 0; + + if (p == 0) { + c = '.'; + num++; + } + if (p == 1) + c = '+'; + if (p == 2) { + c = '*'; + ok++; + } + + if (p == 3) + c = '\n'; + BIO_write(BN_GENCB_get_arg(arg), &c, 1); + (void)BIO_flush(BN_GENCB_get_arg(arg)); + + if (!ok && (p == 0) && (num > 1)) { + BIO_printf((BIO *)arg, "error in dsatest\n"); + return 0; + } + return 1; +} diff --git a/Libraries/libressl/tests/ec_asn1_test.c b/Libraries/libressl/tests/ec_asn1_test.c new file mode 100644 index 000000000..512f5c525 --- /dev/null +++ b/Libraries/libressl/tests/ec_asn1_test.c @@ -0,0 +1,206 @@ +/* $OpenBSD: ec_asn1_test.c,v 1.2 2021/12/04 17:03:43 tb Exp $ */ +/* + * Copyright (c) 2017, 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +const uint8_t ec_secp256r1_pkparameters_named_curve[] = { + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, + 0x01, 0x07, +}; + +const uint8_t ec_secp256r1_pkparameters_parameters[] = { + 0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c, + 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, + 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, + 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, + 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, + 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, + 0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36, + 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78, + 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, + 0x90, 0x04, 0x41, 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, 0x02, 0x21, 0x00, 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, 0x02, + 0x01, 0x01, +}; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +compare_data(const char *label, const unsigned char *d1, size_t d1_len, + const unsigned char *d2, size_t d2_len) +{ + if (d1_len != d2_len) { + fprintf(stderr, "FAIL: got %s with length %zu, want %zu\n", + label, d1_len, d2_len); + return -1; + } + if (memcmp(d1, d2, d1_len) != 0) { + fprintf(stderr, "FAIL: %sdiffer\n", label); + fprintf(stderr, "got:\n"); + hexdump(d1, d1_len); + fprintf(stderr, "want:\n"); + hexdump(d2, d2_len); + return -1; + } + return 0; +} + +static int +ec_group_pkparameters_test(const char *label, int asn1_flag, + const uint8_t *test_data, size_t test_data_len) +{ + EC_GROUP *group_a = NULL, *group_b = NULL; + unsigned char *out = NULL, *data = NULL; + const unsigned char *p; + BIO *bio_mem = NULL; + int failure = 1; + int len; + + /* + * Test i2d_ECPKParameters/d2i_ECPKParameters. + */ + if ((group_a = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL) + errx(1, "failed to create EC_GROUP"); + + EC_GROUP_set_asn1_flag(group_a, asn1_flag); + + if ((len = i2d_ECPKParameters(group_a, &out)) < 0) { + fprintf(stderr, "FAIL: i2d_ECPKParameters failed\n"); + goto done; + } + if (compare_data(label, out, len, test_data, test_data_len) == -1) + goto done; + + p = out; + if ((group_b = d2i_ECPKParameters(NULL, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_ECPKParameters failed\n"); + goto done; + } + + if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { + fprintf(stderr, "FAIL: EC_GROUPs do not match!\n"); + goto done; + } + + p = out; + if ((group_a = d2i_ECPKParameters(&group_a, &p, len)) == NULL) { + fprintf(stderr, "FAIL: d2i_ECPKParameters failed\n"); + goto done; + } + + if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { + fprintf(stderr, "FAIL: EC_GROUPs do not match!\n"); + goto done; + } + + /* + * Test i2d_ECPKParameters_bio/d2i_ECPKParameters_bio. + */ + if ((bio_mem = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new failed for BIO_s_mem"); + + if ((len = i2d_ECPKParameters_bio(bio_mem, group_a)) < 0) { + fprintf(stderr, "FAIL: i2d_ECPKParameters_bio failed\n"); + goto done; + } + + len = BIO_get_mem_data(bio_mem, &data); + if (compare_data(label, out, len, test_data, test_data_len) == -1) + goto done; + + EC_GROUP_free(group_b); + if ((group_b = d2i_ECPKParameters_bio(bio_mem, NULL)) == NULL) { + fprintf(stderr, "FAIL: d2i_ECPKParameters_bio failed\n"); + goto done; + } + + if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { + fprintf(stderr, "FAIL: EC_GROUPs do not match!\n"); + goto done; + } + + failure = 0; + + done: + BIO_free_all(bio_mem); + EC_GROUP_free(group_a); + EC_GROUP_free(group_b); + free(out); + + return (failure); +} + +static int +ec_group_pkparameters_named_curve_test(void) +{ + return ec_group_pkparameters_test("ECPKPARAMETERS named curve", + OPENSSL_EC_NAMED_CURVE, ec_secp256r1_pkparameters_named_curve, + sizeof(ec_secp256r1_pkparameters_named_curve)); +} + +static int +ec_group_pkparameters_parameters_test(void) +{ + return ec_group_pkparameters_test("ECPKPARAMETERS parameters", + OPENSSL_EC_EXPLICIT_CURVE, ec_secp256r1_pkparameters_parameters, + sizeof(ec_secp256r1_pkparameters_parameters)); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= ec_group_pkparameters_named_curve_test(); + failed |= ec_group_pkparameters_parameters_test(); + + return (failed); +} diff --git a/Libraries/libressl/tests/ec_point_conversion.c b/Libraries/libressl/tests/ec_point_conversion.c new file mode 100644 index 000000000..001e8a032 --- /dev/null +++ b/Libraries/libressl/tests/ec_point_conversion.c @@ -0,0 +1,545 @@ +/* $OpenBSD: ec_point_conversion.c,v 1.14 2023/08/01 17:19:49 tb Exp $ */ +/* + * Copyright (c) 2021 Theo Buehler + * Copyright (c) 2021 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +int forms[] = { + POINT_CONVERSION_COMPRESSED, + POINT_CONVERSION_UNCOMPRESSED, + POINT_CONVERSION_HYBRID, +}; + +static const size_t N_FORMS = sizeof(forms) / sizeof(forms[0]); +#define N_RANDOM_POINTS 10 + +static const char * +form2str(int form) +{ + switch (form) { + case POINT_CONVERSION_COMPRESSED: + return "compressed form"; + case POINT_CONVERSION_UNCOMPRESSED: + return "uncompressed form"; + case POINT_CONVERSION_HYBRID: + return "hybrid form"; + default: + return "unknown form"; + } +} + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +static int +roundtrip(EC_GROUP *group, EC_POINT *point, int form, BIGNUM *x, BIGNUM *y) +{ + BIGNUM *x_out = NULL, *y_out = NULL; + size_t len; + uint8_t *buf = NULL; + int failed = 1; + + if ((len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL)) == 0) + errx(1, "point2oct"); + if ((buf = malloc(len)) == NULL) + errx(1, "malloc"); + if (EC_POINT_point2oct(group, point, form, buf, len, NULL) != len) + errx(1, "point2oct"); + + if (!EC_POINT_oct2point(group, point, buf, len, NULL)) + errx(1, "%s oct2point", form2str(form)); + + if ((x_out = BN_new()) == NULL) + errx(1, "new x_out"); + if ((y_out = BN_new()) == NULL) + errx(1, "new y_out"); + + if (!EC_POINT_get_affine_coordinates(group, point, x_out, y_out, NULL)) + errx(1, "get affine"); + + if (BN_cmp(x, x_out) != 0) { + warnx("%s: x", form2str(form)); + goto err; + } + if (BN_cmp(y, y_out) != 0) { + warnx("%s: y", form2str(form)); + goto err; + } + + failed = 0; + + err: + if (failed) + hexdump(buf, len); + + free(buf); + BN_free(x_out); + BN_free(y_out); + + return failed; +} + +/* XXX This only tests multiples of the generator for now... */ +static int +test_random_points_on_curve(EC_builtin_curve *curve) +{ + EC_GROUP *group; + BIGNUM *order = NULL; + BIGNUM *random; + BIGNUM *x, *y; + size_t i, j; + int failed = 0; + + if ((group = EC_GROUP_new_by_curve_name(curve->nid)) == NULL) + errx(1, "EC_GROUP_new_by_curve_name(%s)", + OBJ_nid2sn(curve->nid)); + + if ((order = BN_new()) == NULL) + errx(1, "BN_new order"); + if ((random = BN_new()) == NULL) + errx(1, "BN_new random"); + if ((x = BN_new()) == NULL) + errx(1, "BN_new x"); + if ((y = BN_new()) == NULL) + errx(1, "BN_new y"); + + if (!EC_GROUP_get_order(group, order, NULL)) + errx(1, "EC_group_get_order"); + + for (i = 0; i < N_RANDOM_POINTS; i++) { + EC_POINT *random_point; + + do { + if (!BN_rand_range(random, order)) + errx(1, "BN_rand_range"); + } while (BN_is_zero(random)); + + if ((random_point = EC_POINT_new(group)) == NULL) + errx(1, "EC_POINT_new"); + + if (!EC_POINT_mul(group, random_point, random, NULL, NULL, NULL)) + errx(1, "EC_POINT_mul"); + + if (EC_POINT_is_at_infinity(group, random_point)) { + EC_POINT_free(random_point); + + warnx("info: got infinity"); + fprintf(stderr, "random = "); + BN_print_fp(stderr, random); + fprintf(stderr, "\n"); + + continue; + } + + if (!EC_POINT_get_affine_coordinates(group, random_point, + x, y, NULL)) + errx(1, "EC_POINT_get_affine_coordinates"); + + for (j = 0; j < N_FORMS; j++) + failed |= roundtrip(group, random_point, forms[j], x, y); + + EC_POINT_free(random_point); + } + + BN_free(order); + BN_free(random); + BN_free(x); + BN_free(y); + EC_GROUP_free(group); + + return failed; +} + +static int +test_random_points(void) +{ + EC_builtin_curve *all_curves = NULL; + size_t ncurves = 0; + size_t curve_id; + int failed = 0; + + ncurves = EC_get_builtin_curves(NULL, 0); + if ((all_curves = calloc(ncurves, sizeof(EC_builtin_curve))) == NULL) + err(1, "calloc builtin curves"); + EC_get_builtin_curves(all_curves, ncurves); + + for (curve_id = 0; curve_id < ncurves; curve_id++) + failed |= test_random_points_on_curve(&all_curves[curve_id]); + + fprintf(stderr, "%s %s\n", __func__, failed ? ": FAILED" : ""); + + free(all_curves); + return failed; +} + +static const struct point_conversion { + const char *description; + int nid; + uint8_t octets[256]; + uint8_t octets_len; + int valid; +} point_conversions[] = { + /* XXX - now that sect571 is no longer tested, add another test? */ + { + .description = "point at infinity on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { 0x00 }, + .octets_len = 1, + .valid = 1, + }, + { + .description = "point at infinity on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { 0x01 }, + .octets_len = 1, + .valid = 0, + }, + { + .description = "zero x compressed point on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x02, 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, + 0x00, + }, + .octets_len = 33, + .valid = 1, + }, + { + .description = + "zero x compressed point on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x03, 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, + 0x00, + }, + .octets_len = 33, + .valid = 1, + }, + { + .description = "generic compressed point on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x03, 0xa3, 0x96, 0xa0, 0x42, 0x73, 0x1a, 0x8b, + 0x90, 0xd8, 0xcb, 0xae, 0xda, 0x1b, 0x23, 0x11, + 0x77, 0x5f, 0x6a, 0x4c, 0xb4, 0x57, 0xbf, 0xe0, + 0x65, 0xd4, 0x09, 0x11, 0x5f, 0x54, 0xe4, 0xee, + 0xdd, + }, + .octets_len = 33, + .valid = 1, + }, + { + .description = + "generic compressed point on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x02, 0xa3, 0x96, 0xa0, 0x42, 0x73, 0x1a, 0x8b, + 0x90, 0xd8, 0xcb, 0xae, 0xda, 0x1b, 0x23, 0x11, + 0x77, 0x5f, 0x6a, 0x4c, 0xb4, 0x57, 0xbf, 0xe0, + 0x65, 0xd4, 0x09, 0x11, 0x5f, 0x54, 0xe4, 0xee, + 0xdd, + }, + .octets_len = 33, + .valid = 1, + }, + { + .description = "zero x uncompressed point #1 on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x04, 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, + 0x00, 0x66, 0x48, 0x5c, 0x78, 0x0e, 0x2f, 0x83, + 0xd7, 0x24, 0x33, 0xbd, 0x5d, 0x84, 0xa0, 0x6b, + 0xb6, 0x54, 0x1c, 0x2a, 0xf3, 0x1d, 0xae, 0x87, + 0x17, 0x28, 0xbf, 0x85, 0x6a, 0x17, 0x4f, 0x93, + 0xf4, + }, + .octets_len = 65, + .valid = 1, + }, + { + .description = + "zero x uncompressed point #1 on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x05, 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, + 0x00, 0x66, 0x48, 0x5c, 0x78, 0x0e, 0x2f, 0x83, + 0xd7, 0x24, 0x33, 0xbd, 0x5d, 0x84, 0xa0, 0x6b, + 0xb6, 0x54, 0x1c, 0x2a, 0xf3, 0x1d, 0xae, 0x87, + 0x17, 0x28, 0xbf, 0x85, 0x6a, 0x17, 0x4f, 0x93, + 0xf4, + }, + .octets_len = 65, + .valid = 0, + }, + { + .description = "zero x uncompressed point #2 on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x04, 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, + 0x00, 0x99, 0xb7, 0xa3, 0x86, 0xf1, 0xd0, 0x7c, + 0x29, 0xdb, 0xcc, 0x42, 0xa2, 0x7b, 0x5f, 0x94, + 0x49, 0xab, 0xe3, 0xd5, 0x0d, 0xe2, 0x51, 0x78, + 0xe8, 0xd7, 0x40, 0x7a, 0x95, 0xe8, 0xb0, 0x6c, + 0x0b, + }, + .octets_len = 65, + .valid = 1, + }, + { + .description = + "zero x uncompressed point #2 on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x05, 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, + 0x00, 0x99, 0xb7, 0xa3, 0x86, 0xf1, 0xd0, 0x7c, + 0x29, 0xdb, 0xcc, 0x42, 0xa2, 0x7b, 0x5f, 0x94, + 0x49, 0xab, 0xe3, 0xd5, 0x0d, 0xe2, 0x51, 0x78, + 0xe8, 0xd7, 0x40, 0x7a, 0x95, 0xe8, 0xb0, 0x6c, + 0x0b, + }, + .octets_len = 65, + .valid = 0, + }, + { + .description = "generic uncompressed point on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x04, 0x23, 0xe5, 0x85, 0xa5, 0x4b, 0xda, 0x34, + 0x7e, 0xe5, 0x65, 0x53, 0x7f, 0x3b, 0xce, 0xe4, + 0x54, 0xd8, 0xa4, 0x5a, 0x53, 0x4b, 0xb0, 0x4c, + 0xb9, 0x31, 0x09, 0x29, 0xa2, 0x03, 0x4c, 0x73, + 0x20, 0xd2, 0xc6, 0x17, 0xca, 0xe3, 0xcf, 0xc2, + 0xd8, 0x31, 0xfe, 0xf1, 0x7c, 0x6f, 0x9d, 0x7a, + 0x01, 0x7c, 0x34, 0x65, 0x42, 0x05, 0xaf, 0xcc, + 0x04, 0xa3, 0x2f, 0x44, 0x14, 0xbe, 0xd8, 0xc2, + 0x03, + }, + .octets_len = 65, + .valid = 1, + }, + { + .description = + "generic uncompressed point on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x05, 0x23, 0xe5, 0x85, 0xa5, 0x4b, 0xda, 0x34, + 0x7e, 0xe5, 0x65, 0x53, 0x7f, 0x3b, 0xce, 0xe4, + 0x54, 0xd8, 0xa4, 0x5a, 0x53, 0x4b, 0xb0, 0x4c, + 0xb9, 0x31, 0x09, 0x29, 0xa2, 0x03, 0x4c, 0x73, + 0x20, 0xd2, 0xc6, 0x17, 0xca, 0xe3, 0xcf, 0xc2, + 0xd8, 0x31, 0xfe, 0xf1, 0x7c, 0x6f, 0x9d, 0x7a, + 0x01, 0x7c, 0x34, 0x65, 0x42, 0x05, 0xaf, 0xcc, + 0x04, 0xa3, 0x2f, 0x44, 0x14, 0xbe, 0xd8, 0xc2, + 0x03, + }, + .octets_len = 65, + .valid = 0, + }, + { + .description = "zero x hybrid point #1 on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x06, 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, + 0x00, 0x66, 0x48, 0x5c, 0x78, 0x0e, 0x2f, 0x83, + 0xd7, 0x24, 0x33, 0xbd, 0x5d, 0x84, 0xa0, 0x6b, + 0xb6, 0x54, 0x1c, 0x2a, 0xf3, 0x1d, 0xae, 0x87, + 0x17, 0x28, 0xbf, 0x85, 0x6a, 0x17, 0x4f, 0x93, + 0xf4, + }, + .octets_len = 65, + .valid = 1, + }, + { + .description = + "zero x hybrid point #1 on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x07, 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, + 0x00, 0x66, 0x48, 0x5c, 0x78, 0x0e, 0x2f, 0x83, + 0xd7, 0x24, 0x33, 0xbd, 0x5d, 0x84, 0xa0, 0x6b, + 0xb6, 0x54, 0x1c, 0x2a, 0xf3, 0x1d, 0xae, 0x87, + 0x17, 0x28, 0xbf, 0x85, 0x6a, 0x17, 0x4f, 0x93, + 0xf4, + }, + .octets_len = 65, + .valid = 0, + }, + { + .description = "zero x hybrid point #2 on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x07, 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, + 0x00, 0x99, 0xb7, 0xa3, 0x86, 0xf1, 0xd0, 0x7c, + 0x29, 0xdb, 0xcc, 0x42, 0xa2, 0x7b, 0x5f, 0x94, + 0x49, 0xab, 0xe3, 0xd5, 0x0d, 0xe2, 0x51, 0x78, + 0xe8, 0xd7, 0x40, 0x7a, 0x95, 0xe8, 0xb0, 0x6c, + 0x0b, + }, + .octets_len = 65, + .valid = 1, + }, + { + .description = + "zero x hybrid point #2 on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x06, 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, + 0x00, 0x99, 0xb7, 0xa3, 0x86, 0xf1, 0xd0, 0x7c, + 0x29, 0xdb, 0xcc, 0x42, 0xa2, 0x7b, 0x5f, 0x94, + 0x49, 0xab, 0xe3, 0xd5, 0x0d, 0xe2, 0x51, 0x78, + 0xe8, 0xd7, 0x40, 0x7a, 0x95, 0xe8, 0xb0, 0x6c, + 0x0b, + }, + .octets_len = 65, + .valid = 0, + }, + { + .description = "generic hybrid point on secp256r1", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x07, 0x38, 0xb2, 0x98, 0x38, 0x21, 0x6b, 0xec, + 0x87, 0xcf, 0x50, 0xbb, 0x65, 0x11, 0x96, 0x63, + 0xf3, 0x90, 0x64, 0xc3, 0x5c, 0x59, 0xa5, 0x6f, + 0xaf, 0x56, 0x2a, 0x0c, 0xc0, 0x3a, 0x9b, 0x92, + 0x85, 0x95, 0x54, 0xf3, 0x08, 0x0f, 0x78, 0x59, + 0xa2, 0x44, 0x2f, 0x19, 0x5d, 0xd5, 0xcd, 0xf6, + 0xa5, 0xbe, 0x2f, 0x83, 0x70, 0x94, 0xf5, 0xcd, + 0x8c, 0x40, 0x7f, 0xd8, 0x97, 0x92, 0x14, 0xf7, + 0xc5, + }, + .octets_len = 65, + .valid = 1, + }, + { + .description = + "generic hybrid point on secp256r1 (flipped y_bit)", + .nid = NID_X9_62_prime256v1, + .octets = { + 0x06, 0x38, 0xb2, 0x98, 0x38, 0x21, 0x6b, 0xec, + 0x87, 0xcf, 0x50, 0xbb, 0x65, 0x11, 0x96, 0x63, + 0xf3, 0x90, 0x64, 0xc3, 0x5c, 0x59, 0xa5, 0x6f, + 0xaf, 0x56, 0x2a, 0x0c, 0xc0, 0x3a, 0x9b, 0x92, + 0x85, 0x95, 0x54, 0xf3, 0x08, 0x0f, 0x78, 0x59, + 0xa2, 0x44, 0x2f, 0x19, 0x5d, 0xd5, 0xcd, 0xf6, + 0xa5, 0xbe, 0x2f, 0x83, 0x70, 0x94, 0xf5, 0xcd, + 0x8c, 0x40, 0x7f, 0xd8, 0x97, 0x92, 0x14, 0xf7, + 0xc5, + }, + .octets_len = 65, + .valid = 0, + }, +}; + +static const size_t N_POINT_CONVERSIONS = + sizeof(point_conversions) / sizeof(point_conversions[0]); + +static int +point_conversion_form_y_bit(const struct point_conversion *test) +{ + EC_GROUP *group = NULL; + EC_POINT *point = NULL; + int ret; + int failed = 0; + + if ((group = EC_GROUP_new_by_curve_name(test->nid)) == NULL) + errx(1, "group"); + if ((point = EC_POINT_new(group)) == NULL) + errx(1, "point"); + + ret = EC_POINT_oct2point(group, point, test->octets, test->octets_len, + NULL); + if (ret != test->valid) { + fprintf(stderr, "%s want %d got %d\n", test->description, + test->valid, ret); + failed |= 1; + } + + EC_GROUP_free(group); + EC_POINT_free(point); + + return failed; +} + +static int +test_point_conversions(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_POINT_CONVERSIONS; i++) + failed |= point_conversion_form_y_bit(&point_conversions[i]); + + fprintf(stderr, "%s %s\n", __func__, failed ? ": FAILED" : ""); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_random_points(); + failed |= test_point_conversions(); + + return failed; +} diff --git a/Libraries/libressl/tests/ecc_cdh.c b/Libraries/libressl/tests/ecc_cdh.c new file mode 100644 index 000000000..0333cf1e8 --- /dev/null +++ b/Libraries/libressl/tests/ecc_cdh.c @@ -0,0 +1,2506 @@ +/* $OpenBSD: ecc_cdh.c,v 1.2 2023/07/16 08:25:41 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ECC-CDH test vectors extracted from version 14.1 of Component-Testing#ECCCDH + * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static const struct ecc_cdh_test { + int nid; + const char *peer_x; + const char *peer_y; + const char *priv; + const char *pub_x; + const char *pub_y; + const char *want; +} ecc_cdh_tests[] = { + { + .nid = NID_X9_62_prime192v1, + .peer_x = "42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0", + .peer_y = "dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523", + .priv = "f17d3fea367b74d340851ca4270dcb24c271f445bed9d527", + .pub_x = "b15053401f57285637ec324c1cd2139e3a67de3739234b37", + .pub_y = "f269c158637482aad644cd692dd1d3ef2c8a7c49e389f7f6", + .want = "803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7", + .peer_y = "7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125", + .priv = "56e853349d96fe4c442448dacb7cf92bb7a95dcf574a9bd5", + .pub_x = "c00d435716ffea53fd8c162792414c37665187e582716539", + .pub_y = "ab711c62aa71a5a18e8a3c48f89dc6fa52fac0108e52a8a0", + .want = "c208847568b98835d7312cef1f97f7aa298283152313c29d", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "4edaa8efc5a0f40f843663ec5815e7762dddc008e663c20f", + .peer_y = "0a9f8dc67a3e60ef6d64b522185d03df1fc0adfd42478279", + .priv = "c6ef61fe12e80bf56f2d3f7d0bb757394519906d55500949", + .pub_x = "e184bc182482f3403c8787b83842477467fcd011db0f6c64", + .pub_y = "f9d1c14142f40de8639db97d51a63d2cce1007ccf773cdcb", + .want = "87229107047a3b611920d6e3b2c0c89bea4f49412260b8dd", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "8887c276edeed3e9e866b46d58d895c73fbd80b63e382e88", + .peer_y = "04c5097ba6645e16206cfb70f7052655947dd44a17f1f9d5", + .priv = "e6747b9c23ba7044f38ff7e62c35e4038920f5a0163d3cda", + .pub_x = "2b838dbe73735f37a39a78d3195783d26991e86ff4d92d1a", + .pub_y = "60d344942274489f98903b2e7f93f8d197fc9ae60a0ed53a", + .want = "eec0bed8fc55e1feddc82158fd6dc0d48a4d796aaf47d46c", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "0d045f30254adc1fcefa8a5b1f31bf4e739dd327cd18d594", + .peer_y = "542c314e41427c08278a08ce8d7305f3b5b849c72d8aff73", + .priv = "beabedd0154a1afcfc85d52181c10f5eb47adc51f655047d", + .pub_x = "1f65cf6e8978e1c1bc10bb61a7db311de310088c8cf9768b", + .pub_y = "f7d438168e7f42ab14b16af53a7a2f646ff40b53d74cbcc7", + .want = "716e743b1b37a2cd8479f0a3d5a74c10ba2599be18d7e2f4", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "fb35ca20d2e96665c51b98e8f6eb3d79113508d8bccd4516", + .peer_y = "368eec0d5bfb847721df6aaff0e5d48c444f74bf9cd8a5a7", + .priv = "cf70354226667321d6e2baf40999e2fd74c7a0f793fa8699", + .pub_x = "5f4844ffcce61005d24f737db98675e92f7b6543aeb6106c", + .pub_y = "5424f598139215d389b6b12b86d58014857f2ddadb540f51", + .want = "f67053b934459985a315cb017bf0302891798d45d0e19508", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "824752960c1307e5f13a83da21c7998ca8b5b00b9549f6d0", + .peer_y = "bc52d91e234363bc32ee0b6778f25cd8c1847510f4348b94", + .priv = "fe942515237fffdd7b4eb5c64909eee4856a076cdf12bae2", + .pub_x = "e6369df79b207b8b8679f7c869cfc264859d1ab55aa401e8", + .pub_y = "1f99c71f801a30b52f74da6e5e6dbb62ee4c5da1090cc020", + .want = "75822971193edd472bf30151a782619c55ad0b279c9303dd", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "10bb57020291141981f833b4749e5611034b308e84011d21", + .peer_y = "e1cacd6b7bd17ed8ddb50b6aee0654c35f2d0eddc1cffcf6", + .priv = "33fed10492afa5bea0333c0af12cac940c4d222455bcd0fe", + .pub_x = "ef0b28afc41637d737f42e4c8aaceadc84ba2e0b849ca18c", + .pub_y = "57797942e552173bba17f73278e029f42335068bd770ddf2", + .want = "67cba2cbb69ee78bf1abafb0e6fbe33fa2094c128d59652d", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "5192fce4185a7758ea1bc56e0e4f4e8b2dce32348d0dced1", + .peer_y = "20989981beaaf0006d88a96e7971a2fa3a33ba46047fc7ba", + .priv = "f3557c5d70b4c7954960c33568776adbe8e43619abe26b13", + .pub_x = "d70112c5f0f0844386494ac1ad99dce2214134176ebfb9af", + .pub_y = "d3c187a038510ab31d459e2b7af1a380dd7576af06267548", + .want = "cf99a2770a386ca0137d1eca0a226e484297ac3c513f3631", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "26d019dbe279ead01eed143a91601ada26e2f42225b1c62b", + .peer_y = "6ca653f08272e0386fc9421fbd580093d7ae6301bca94476", + .priv = "586cfba1c6e81766ed52828f177b1be14ebbc5b83348c311", + .pub_x = "58b3c63e56bec9d696bf9a88df2873738391f76368aa2b49", + .pub_y = "5776773b261faf7ba2fdc4fe43b92c0b1c7a2fd054a43650", + .want = "576331e2b4fb38a112810e1529834de8307fb0a0d2756877", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "539bc40fe20a0fb267888b647b03eaaf6ec20c02a1e1f8c8", + .peer_y = "69095e5bb7b4d44c3278a7ee6beca397c45246da9a34c8be", + .priv = "cad8100603a4f65be08d8fc8a1b7e884c5ff65deb3c96d99", + .pub_x = "b7fcc0f52c7a411edbed39e10bf02b6ae0f26614c6b325a2", + .pub_y = "47483b26eb67776de2b93ab7119d5447573739e3d55e72fb", + .want = "902f4501916a0dd945554c3a37b3d780d375a6da713197c4", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "5d343ddb96318fb4794d10f6c573f99fee5d0d57b996250f", + .peer_y = "99fbdf9d97dd88ad410235dac36e5b92ce2824b8e587a82c", + .priv = "1edd879cc5c79619cae6c73a691bd5a0395c0ef3b356fcd2", + .pub_x = "6ce6adb2c30808f590048c33dffad4524ebf7a5fd39b747b", + .pub_y = "4966bd2f3d00569b4d4c0409fbd7a2db752f6d09bca8c25f", + .want = "46e4de335054d429863218ae33636fc9b89c628b64b506c7", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "8d3db9bdce137ffbfb891388c37df6c0cbc90aa5e5376220", + .peer_y = "135d30b5cb660eef8764ffc744f15c1b5d6dc06ba4416d37", + .priv = "460e452273fe1827602187ad3bebee65cb84423bb4f47537", + .pub_x = "d1bd3a3efabf4767fe6380bdf0dbf49d52d4cf0cbb89404c", + .pub_y = "c150c2b4c8b3aa35f765f847e4f7f8fd8704d241a181ee99", + .want = "1bfe9e5a20ac7a38d8f605b425bb9030be31ef97c101c76c", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "9e0a6949519c7f5be68c0433c5fdf13064aa13fb29483dc3", + .peer_y = "e1c8ba63e1f471db23185f50d9c871edea21255b3a63b4b7", + .priv = "b970365008456f8758ecc5a3b33cf3ae6a8d568107a52167", + .pub_x = "c1b8610c8c63f8d4abda093b9a11a566044bf65c6faa8999", + .pub_y = "a5bc4b3ca095382e9738aee95fe9479b17879b3ad5295559", + .want = "0e8c493a4adc445dc9288a3b9b272599224054592d7265b3", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "be088238902e9939b3d054eeeb8492daf4bdcf09a2ab77f1", + .peer_y = "58d6749a3a923dc80440f2661fd35b651617e65294b46375", + .priv = "59c15b8a2464e41dfe4371c7f7dadf470ae425544f8113bd", + .pub_x = "1fe776f73567b6ac0b0d6764164de6c5be751ba8d1ff455e", + .pub_y = "4c160bf38afb2b71f684261664115ce874553e8b059432d2", + .want = "0f1991086b455ded6a1c4146f7bf59fe9b495de566ebc6bf", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "bf5ae05025e1be617e666d87a4168363873d5761b376b503", + .peer_y = "e1e6e38b372b6bee0ff5b3502d83735e3b2c26825e4f0fcc", + .priv = "a6e9b885c66b959d1fc2708d591b6d3228e49eb98f726d61", + .pub_x = "632bb7651dbf49dde9dd125d13fb234e06617723beed3d1b", + .pub_y = "f4ad5209638488397c5f44f994dd7479807e79f4887d2e71", + .want = "b30f2127c34df35aaa91dbf0bbe15798e799a03ed11698c1", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "6cc4feed84c7ab0d09005d660ed34de6955a9461c4138d11", + .peer_y = "31225f33864ed48da06fa45a913b46cf42557742e35085e6", + .priv = "bdb754096ffbfbd8b0f3cb046ccb7ca149c4e7192067a3ee", + .pub_x = "d9c098d421d741f6faab116f3e4731d28c5558e19fe112a1", + .pub_y = "38d4dc48ccdb1d3ed8d31fd06784a4f87a68aec1cbd5b08f", + .want = "64a5c246599d3e8177a2402a1110eb81e6c456ab4edb5127", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "36157315bee7afedded58c4e8ba14d3421c401e51135bcc9", + .peer_y = "37c297ca703f77c52bb062d8ce971db84097ba0c753a418f", + .priv = "d5bcf2534dafc3d99964c7bd63ab7bd15999fe56dd969c42", + .pub_x = "fda1d5d28d6fe0e7909d6a8bafa7824db5572ab92ffe7de6", + .pub_y = "134a297c1d9c8bbab249abacd951ed11e5a99f92e7991572", + .want = "017b8ca53c82fab163da2ab783966a39e061b32c8cfa334d", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "98464d47f0256f8292e027e8c92582ea77cf9051f5ce8e5d", + .peer_y = "449552ef7578be96236fe5ed9d0643c0bb6c5a9134b0108d", + .priv = "43d4b9df1053be5b4268104c02244d3bf9594b010b46a8b2", + .pub_x = "c3020b7091463d788f1f1d76f7cfeec82ecdb3b7d99c345c", + .pub_y = "9a7710d5179591d8f3df0aa122301768ae7db7eee2d7f583", + .want = "340ef3db3dbebdd91c62c3d4e1a3da2c7c52a3338b865259", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "563eb66c334cf6f123bf04c7803b48a3110214237e983bf5", + .peer_y = "0f351104819199ef07c9a6051d20758f3af79027ea66a53f", + .priv = "94cac2c2ca714746401670d94edbf3f677867b5a03bee7ad", + .pub_x = "b18554a2e743ef0aa2f040987c4c451004e096df3d80ddae", + .pub_y = "6e3e2c618f896e36ba620077684b70a05ffb79bf5e6c7640", + .want = "2162144921df5103d0e6a650fb13fd246f4738d0896ce92f", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "86828c4ac92b5507618aec7873a1d4fc6543c5be33cf3078", + .peer_y = "b22ca72437545e10d6d4f052422eb898b737a4b8543ee550", + .priv = "2a3a9e33c8cc3107a9f9265c3bdea1206570e86f92ac7014", + .pub_x = "a7ba38be1bc669dd23ccfcee0645b1f0db8cf942deafaeb6", + .pub_y = "b82db79d80cd0e37f28d4163adc389dee8fc7797b5c9831b", + .want = "4c69e7feed4b11159adfc16a6047a92572ea44e0740b23af", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "6700a102437781a9581da2bc25ced5abf419da91d3c803df", + .peer_y = "71396c9cf08bcd91854e3e6e42d8c657ce0f27ab77a9dc4b", + .priv = "4a6b78a98ac98fa8e99a8ece08ec0251125f85c6fd0e289b", + .pub_x = "e769dbbcd5ce2d83514b768d3d2d5aa0bcd8f66af15f5500", + .pub_y = "2fc6d0b039e0f28f74fbeffe9e883d4dd72296e4e95cae71", + .want = "46072acefd67bff50de355ca7a31fa6be59f26e467587259", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "a82f354cf97bee5d22dc6c079f2902ead44d96a8f614f178", + .peer_y = "a654a9aa8a1a0802f2ce0ee8a0f4ebe96dee1b37464b1ff2", + .priv = "c5a6491d78844d6617ef33be6b8bd54da221450885d5950f", + .pub_x = "db1b24f7466bc154e9d7d2c3ca52dcfe0bfc9563c5fdb6f3", + .pub_y = "1c74fbbf5bd99921f1a9a744f8e1cf770bd6a76a772b3003", + .want = "ec5580eabca9f3389d2b427ddf6e49e26d629afd03fa766e", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "3cec21b28668a12a2cf78e1a8e55d0efe065152fffc34718", + .peer_y = "1029557beba4ff1992bd21c23cb4825f6dae70e3318fd1ca", + .priv = "2ba2703c5e23f6463c5b88dc37292fabd3399b5e1fb67c05", + .pub_x = "7543148906cef9b37a71a7c08363cdd3bba50142d65241aa", + .pub_y = "8b3a6973de8dc271e27c1ead1e962fdaae3710c724daac38", + .want = "7f3929dd3cbf7673bc30d859d90b880307475f800660ea32", + }, + { + .nid = NID_X9_62_prime192v1, + .peer_x = "7082644715b8b731f8228b5118e7270d34d181f361a221fc", + .peer_y = "464649d6c88ca89614488a1cc7b8442bb42f9fb3020a3d76", + .priv = "836118c6248f882e9147976f764826c1a28755a6102977d5", + .pub_x = "fcd345a976c720caaa97de6697226825615e1287a9eff67e", + .pub_y = "58ea42edbeeafca9ff44cfd7f29abd2cbde7626d79e422c9", + .want = "72e88f3ea67d46d46dbf83926e7e2a6b85b54536741e6d2c", + }, + + { + .nid = NID_secp224r1, + .peer_x = + "af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280", + .peer_y = + "882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7", + .priv = + "8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd", + .pub_x = + "8de2e26adf72c582d6568ef638c4fd59b18da171bdf501f1d929e048", + .pub_y = + "4a68a1c2b0fb22930d120555c1ece50ea98dea8407f71be36efac0de", + .want = + "7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8", + }, + { + .nid = NID_secp224r1, + .peer_x = + "13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46", + .peer_y = + "eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4", + .priv = + "043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d", + .pub_x = + "2f90f5c8eac9c7decdbb97b6c2f715ab725e4fe40fe6d746efbf4e1b", + .pub_y = + "66897351454f927a309b269c5a6d31338be4c19a5acfc32cf656f45c", + .want = + "ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09", + }, + { + .nid = NID_secp224r1, + .peer_x = + "756dd806b9d9c34d899691ecb45b771af468ec004486a0fdd283411e", + .peer_y = + "4d02c2ca617bb2c5d9613f25dd72413d229fd2901513aa29504eeefb", + .priv = + "5ad0dd6dbabb4f3c2ea5fe32e561b2ca55081486df2c7c15c9622b08", + .pub_x = + "005bca45d793e7fe99a843704ed838315ab14a5f6277507e9bc37531", + .pub_y = + "43e9d421e1486ae5893bfd23c210e5c140d7c6b1ada59d842c9a98de", + .want = + "3fcc01e34d4449da2a974b23fc36f9566754259d39149790cfa1ebd3", + }, + { + .nid = NID_secp224r1, + .peer_x = + "0f537bf1c1122c55656d25e8aa8417e0b44b1526ae0523144f9921c4", + .peer_y = + "f79b26d30e491a773696cc2c79b4f0596bc5b9eebaf394d162fb8684", + .priv = + "0aa6ff55a5d820efcb4e7d10b845ea3c9f9bc5dff86106db85318e22", + .pub_x = + "2f96754131e0968198aa78fbe8c201dc5f3581c792de487340d32448", + .pub_y = + "61e8a5cd79615203b6d89e9496f9e236fe3b6be8731e743d615519c6", + .want = + "49129628b23afcef48139a3f6f59ff5e9811aa746aa4ff33c24bb940", + }, + { + .nid = NID_secp224r1, + .peer_x = + "2b3631d2b06179b3174a100f7f57131eeea8947be0786c3dc64b2239", + .peer_y = + "83de29ae3dad31adc0236c6de7f14561ca2ea083c5270c78a2e6cbc0", + .priv = + "efe6e6e25affaf54c98d002abbc6328da159405a1b752e32dc23950a", + .pub_x = + "355e962920bde043695f6bffb4b355c63da6f5de665ed46f2ec817e2", + .pub_y = + "748e095368f62e1d364edd461719793b404adbdaacbcadd88922ff37", + .want = + "fcdc69a40501d308a6839653a8f04309ec00233949522902ffa5eac6", + }, + { + .nid = NID_secp224r1, + .peer_x = + "4511403de29059f69a475c5a6a5f6cabed5d9f014436a8cb70a02338", + .peer_y = + "7d2d1b62aa046df9340f9c37a087a06b32cf7f08a223f992812a828b", + .priv = + "61cb2932524001e5e9eeed6df7d9c8935ee3322029edd7aa8acbfd51", + .pub_x = + "d50e4adabfd989d7dbc7cf4052546cc7c447a97630436997ad4b9536", + .pub_y = + "5bea503473c5eaef9552d42c40b1f2f7ca292733b255b9bbe1b12337", + .want = + "827e9025cb62e0e837c596063f3b9b5a0f7afd8d8783200086d61ec1", + }, + { + .nid = NID_secp224r1, + .peer_x = + "314a0b26dd31c248845d7cc17b61cad4608259bed85a58d1f1ffd378", + .peer_y = + "66e4b350352e119eecada382907f3619fd748ea73ae4899dfd496302", + .priv = + "8c7ace347171f92def98d845475fc82e1d1496da81ee58f505b985fa", + .pub_x = + "b1a8dcac89aca2799320b451df1c7ff4d97567abb68141c0d95fc2aa", + .pub_y = + "3524950902b1510bdc987d860afc27ad871ceaea66935abd3c0a99a8", + .want = + "335ba51228d94acbed851ca7821c801d5cb1c7975d7aa90a7159f8fa", + }, + { + .nid = NID_secp224r1, + .peer_x = + "abe6843beec2fd9e5fb64730d0be4d165438ce922ed75dd80b4603e5", + .peer_y = + "6afe8673a96c4ba9900ad85995e631e436c6cc88a2c2b47b7c4886b8", + .priv = + "382feb9b9ba10f189d99e71a89cdfe44cb554cec13a212840977fb68", + .pub_x = + "abb6f1e3773ff8fc73aea2a0b107809ce70adcefed6e41fc5cb43045", + .pub_y = + "a963897ae906c10a055eeadb97ffdd6f748d3e5621e5fff304e48ba7", + .want = + "8c2e627594206b34f7356d3426eb3d79f518ef843fbe94014cceace3", + }, + { + .nid = NID_secp224r1, + .peer_x = + "13cf9d6d2c9aae8274c27d446afd0c888ffdd52ae299a35984d4f527", + .peer_y = + "dcbee75b515751f8ee2ae355e8afd5de21c62a939a6507b538cbc4af", + .priv = + "e0d62035101ef487c485c60fb4500eebe6a32ec64dbe97dbe0232c46", + .pub_x = + "88537735e9b23e3e0e076f135a82d33f9bffb465f3abce8322a62a62", + .pub_y = + "b4c8c123673197875c0bd14ed097606d330fba2b9200ef65a44764d3", + .want = + "632abb662728dbc994508873d5c527ca5ef923c0d31fa6c47ef4c825", + }, + { + .nid = NID_secp224r1, + .peer_x = + "965b637c0dfbc0cf954035686d70f7ec30929e664e521dbaa2280659", + .peer_y = + "82a58ff61bc90019bbcbb5875d3863db0bc2a1fa34b0ad4de1a83f99", + .priv = + "b96ade5b73ba72aa8b6e4d74d7bf9c58e962ff78eb542287c7b44ba2", + .pub_x = + "37682926a54f70a4c1748f54d50d5b00138a055f924f2c65e5b0bbe4", + .pub_y = + "596afefcdd640d29635015b89bdddd1f8c2723686d332e7a06ca8799", + .want = + "34641141aab05ef58bd376d609345901fb8f63477c6be9097f037f1f", + }, + { + .nid = NID_secp224r1, + .peer_x = + "73cc645372ca2e71637cda943d8148f3382ab6dd0f2e1a49da94e134", + .peer_y = + "df5c355c23e6e232ebc3bee2ab1873ee0d83e3382f8e6fe613f6343c", + .priv = + "a40d7e12049c71e6522c7ff2384224061c3a457058b310557655b854", + .pub_x = + "399801243bfe0c2da9b0a53c8ca57f2eee87aaa94a8e4d5e029f42ca", + .pub_y = + "aa49e6d4b47cee7a5c4ab71d5a67da84e0b9b425ce3e70da68c889e7", + .want = + "4f74ac8507501a32bfc5a78d8271c200e835966e187e8d00011a8c75", + }, + { + .nid = NID_secp224r1, + .peer_x = + "546578216250354e449e21546dd11cd1c5174236739acad9ce0f4512", + .peer_y = + "d2a22fcd66d1abedc767668327c5cb9c599043276239cf3c8516af24", + .priv = + "ad2519bc724d484e02a69f05149bb047714bf0f5986fac2e222cd946", + .pub_x = + "df9c1e0ef15e53b9f626e2be1cbe893639c06f3e0439ee95d7d4b1e3", + .pub_y = + "7a52a7386adda243efdf8941085c84e31239cab92b8017336748965e", + .want = + "ad09c9ae4d2324ea81bb555b200d3c003e22a6870ee03b52df49e4de", + }, + { + .nid = NID_secp224r1, + .peer_x = + "1d46b1dc3a28123cb51346e67baec56404868678faf7d0e8b2afa22a", + .peer_y = + "0ec9e65ec97e218373e7fc115c2274d5b829a60d93f71e01d58136c3", + .priv = + "3d312a9b9d8ed09140900bbac1e095527ebc9e3c6493bcf3666e3a29", + .pub_x = + "b4a0198dc8810e884425b750928b0c960c31f7a99663400b01a179df", + .pub_y = + "812b601bfc0738242c6f86f830f27acd632ca618a0b5280c9d5769f7", + .want = + "ef029c28c68064b8abd2965a38c404fb5e944ace57e8638daba9d3cd", + }, + { + .nid = NID_secp224r1, + .peer_x = + "266d038cc7a4fe21f6c976318e827b82bb5b8f7443a55298136506e0", + .peer_y = + "df123d98a7a20bbdf3943df2e3563422f8c0cf74d53aaabdd7c973ba", + .priv = + "8ce0822dc24c153995755ac350737ef506641c7d752b4f9300c612ed", + .pub_x = + "00dfc7ec137690cd6d12fdb2fd0b8c5314582108769c2b722ffb3958", + .pub_y = + "5eef3da4ba458127346bb64023868bddb7558a2ecfc813645f4ce9fe", + .want = + "f83c16661dfcbad021cc3b5a5af51d9a18db4653866b3ff90787ce3e", + }, + { + .nid = NID_secp224r1, + .peer_x = + "eb0a09f7a1c236a61f595809ec5670efd92e4598d5e613e092cdfdca", + .peer_y = + "50787ae2f2f15b88bc10f7b5f0aee1418373f16153aebd1fba54288d", + .priv = + "0ff9b485325ab77f29e7bc379fed74bfac859482da0dee7528c19db2", + .pub_x = + "7e603e6976db83c36011508fa695d1b515249e2e54b48fcbcfb90247", + .pub_y = + "0179a600ce86adfca9b1b931fa5173d618da09e841803d19b0264286", + .want = + "f51258c63f232e55a66aa25ebd597b2018d1052c02eeb63866758005", + }, + { + .nid = NID_secp224r1, + .peer_x = + "6b2f6b18a587f562ffc61bd9b0047322286986a78f1fd139b84f7c24", + .peer_y = + "7096908e4615266be59a53cd655515056ff92370a6271a5d3823d704", + .priv = + "19cf5ff6306467f28b9fe0675a43c0582552c8c12e59ce7c38f292b1", + .pub_x = + "fc20e906e609c112cfc2e0fea6303882c5db94e87e022373ab2c082a", + .pub_y = + "aecdf1daa71782bc5a26bbbd8d7e8a76490e26abc17dffc774bd7341", + .want = + "7fdc969a186ff18429f2a276dac43beea21182d82ce2e5a0876552b1", + }, + { + .nid = NID_secp224r1, + .peer_x = + "328101ba826acd75ff9f34d5574ce0dbc92f709bad8d7a33c47940c1", + .peer_y = + "df39f1ea88488c55d5538160878b9ced18a887ea261dd712d14024ff", + .priv = + "90a15368e3532c0b1e51e55d139447c2c89bc160719d697291ea7c14", + .pub_x = + "c6837d506e976da7db3ad1267c359dff2ea6fb0b7f7f8e77024c59e9", + .pub_y = + "67eb491d2fc8a530c46525d2a8b2d7c1df5fba1ae740a4649c683ee6", + .want = + "3d60ab6db2b3ffe2d29ccff46d056e54230cf34982e241556ed2920c", + }, + { + .nid = NID_secp224r1, + .peer_x = + "0081e34270871e2ebbd94183f617b4ae15f0416dd634fe6e934cf3c0", + .peer_y = + "3a1e9f38a7b90b7317d26b9f6311063ab58b268cf489b2e50386d5d6", + .priv = + "8e0838e05e1721491067e1cabc2e8051b290e2616eec427b7121897d", + .pub_x = + "e9150f770075626019e18f95473b71e6828041791d3f08d3faeeaa2b", + .pub_y = + "475f70735eaae52308a3b763dc88efe18ab590ebafa035f6e08b001c", + .want = + "9116d72786f4db5df7a8b43078c6ab9160d423513d35ea5e2559306d", + }, + { + .nid = NID_secp224r1, + .peer_x = + "2623632fdf0bd856805a69aa186d4133ef5904e1f655a972d66cce07", + .peer_y = + "2cef9728dd06fb8b50150f529b695076d4507983912585c89bd0682e", + .priv = + "38106e93f16a381adb1d72cee3da66ae462ad4bbfea9ecdf35d0814e", + .pub_x = + "7be6c4c917829ab657dd79e8637d7aefd2f81f0de7654d957e97658d", + .pub_y = + "430d22d9e8438310f61e0d43f25fa3e34585f432baad27db3021bf0d", + .want = + "207c53dcefac789aaa0276d9200b3a940ce5f2296f4cb2e81a185d3d", + }, + { + .nid = NID_secp224r1, + .peer_x = + "8ee4d1dcc31dee4bf6fe21ca8a587721d910acfb122c16c2a77a8152", + .peer_y = + "4ebf323fff04eb477069a0ac68b345f6b1ae134efc31940e513cb99f", + .priv = + "e5d1718431cf50f6cbd1bc8019fa16762dfa12c989e5999977fb4ea2", + .pub_x = + "2ea4966e7f92ed7f5cc61fde792045f63b731d6e7d0de2577f2d8ece", + .pub_y = + "1c4a7b1ede6f839162292df424be78e8176fb6f942a3c02391700f31", + .want = + "10e467da34f48ad7072005bccd6da1b2ba3f71eafa1c393842f91d74", + }, + { + .nid = NID_secp224r1, + .peer_x = + "97dcbe6d28335882a6d193cc54a1063dd0775dc328565300bb99e691", + .peer_y = + "dad11dd5ece8cfd9f97c9a526e4a1506e6355969ee87826fc38bcd24", + .priv = + "3d635691b62a9a927c633951c9369c8862bd2119d30970c2644727d6", + .pub_x = + "438bbb980517afb20be1d674e3ac2b31cef07a9b23fb8f6e38e0d6c0", + .pub_y = + "0be5f1c47d58d21b6ed28423b32f5a94750da47edcef33ea79942afd", + .want = + "82fd2f9c60c4f999ac00bbe64bfc11da8ff8cda2e499fced65230bb1", + }, + { + .nid = NID_secp224r1, + .peer_x = + "ce9126dd53972dea1de1d11efef900de34b661859c4648c5c0e534f7", + .peer_y = + "e113b6f2c1659d07f2716e64a83c18bbce344dd2121fe85168eae085", + .priv = + "acf3c85bbdc379f02f5ea36e7f0f53095a9e7046a28685a8659bf798", + .pub_x = + "ff7511215c71d796bd646e8474be4416b91684ce0d269ef6f422013b", + .pub_y = + "b7bf5e79b5a9393bb9ea42c0bdb2d3c2dc806e1a7306aa58e4fdbea5", + .want = + "530f7e7fc932613b29c981f261cb036cba3f1df3864e0e1cba2685a2", + }, + { + .nid = NID_secp224r1, + .peer_x = + "84419967d6cfad41e75a02b6da605a97949a183a97c306c4b46e66a5", + .peer_y = + "5cc9b259718b1bc8b144fde633a894616ffd59a3a6d5d8e942c7cbb7", + .priv = + "cffd62cb00a0e3163fbf2c397fadc9618210f86b4f54a675287305f0", + .pub_x = + "04bf4d948f4430d18b4ed6c96dbaf981fa11a403ed16887f06754981", + .pub_y = + "7c1326a9cef51f79d4e78303d6064b459f612584ac2fdf593d7d5d84", + .want = + "49f6fd0139248ef4df2db05d1319bd5b1489e249827a45a8a5f12427", + }, + { + .nid = NID_secp224r1, + .peer_x = + "7c9cac35768063c2827f60a7f51388f2a8f4b7f8cd736bd6bc337477", + .peer_y = + "29ee6b849c6025d577dbcc55fbd17018f4edbc2ef105b004d6257bcd", + .priv = + "85f903e43943d13c68932e710e80de52cbc0b8f1a1418ea4da079299", + .pub_x = + "970a4a7e01d4188497ceb46955eb1b842d9085819a9b925c84529d3d", + .pub_y = + "dfa2526480f833ea0edbd204e4e365fef3472888fe7d9691c3ebc09f", + .want = + "8f7e34e597ae8093b98270a74a8dfcdbed457f42f43df487c5487161", + }, + { + .nid = NID_secp224r1, + .peer_x = + "085a7642ad8e59b1a3e8726a7547afbecffdac1dab7e57230c6a9df4", + .peer_y = + "f91c36d881fe9b8047a3530713554a1af4c25c5a8e654dcdcf689f2e", + .priv = + "cce64891a3d0129fee0d4a96cfbe7ac470b85e967529057cfa31a1d9", + .pub_x = + "a6b29632db94da2125dc1cf80e03702687b2acc1122022fa2174765a", + .pub_y = + "61723edd73e10daed73775278f1958ba56f1fc9d085ebc2b64c84fe5", + .want = + "71954e2261e8510be1a060733671d2e9d0a2d012eb4e09556d697d2a", + }, + + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "700c48f77f56584c5cc632ca65640db9" + "1b6bacce3a4df6b42ce7cc838833d287", + .peer_y = + "db71e509e3fd9b060ddb20ba5c51dcc5" + "948d46fbf640dfe0441782cab85fa4ac", + .priv = + "7d7dc5f71eb29ddaf80d6214632eeae0" + "3d9058af1fb6d22ed80badb62bc1a534", + .pub_x = + "ead218590119e8876b29146ff89ca617" + "70c4edbbf97d38ce385ed281d8a6b230", + .pub_y = + "28af61281fd35e2fa7002523acc85a42" + "9cb06ee6648325389f59edfce1405141", + .want = + "46fc62106420ff012e54a434fbdd2d25" + "ccc5852060561e68040dd7778997bd7b", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "809f04289c64348c01515eb03d5ce7ac" + "1a8cb9498f5caa50197e58d43a86a7ae", + .peer_y = + "b29d84e811197f25eba8f5194092cb6f" + "f440e26d4421011372461f579271cda3", + .priv = + "38f65d6dce47676044d58ce5139582d5" + "68f64bb16098d179dbab07741dd5caf5", + .pub_x = + "119f2f047902782ab0c9e27a54aff5eb" + "9b964829ca99c06b02ddba95b0a3f6d0", + .pub_y = + "8f52b726664cac366fc98ac7a012b268" + "2cbd962e5acb544671d41b9445704d1d", + .want = + "057d636096cb80b67a8c038c890e887d" + "1adfa4195e9b3ce241c8a778c59cda67", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "a2339c12d4a03c33546de533268b4ad6" + "67debf458b464d77443636440ee7fec3", + .peer_y = + "ef48a3ab26e20220bcda2c1851076839" + "dae88eae962869a497bf73cb66faf536", + .priv = + "1accfaf1b97712b85a6f54b148985a1b" + "dc4c9bec0bd258cad4b3d603f49f32c8", + .pub_x = + "d9f2b79c172845bfdb560bbb01447ca5" + "ecc0470a09513b6126902c6b4f8d1051", + .pub_y = + "f815ef5ec32128d3487834764678702e" + "64e164ff7315185e23aff5facd96d7bc", + .want = + "2d457b78b4614132477618a5b077965e" + "c90730a8c81a1c75d6d4ec68005d67ec", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "df3989b9fa55495719b3cf46dccd28b5" + "153f7808191dd518eff0c3cff2b705ed", + .peer_y = + "422294ff46003429d739a33206c87525" + "52c8ba54a270defc06e221e0feaf6ac4", + .priv = + "207c43a79bfee03db6f4b944f53d2fb7" + "6cc49ef1c9c4d34d51b6c65c4db6932d", + .pub_x = + "24277c33f450462dcb3d4801d57b9ced" + "05188f16c28eda873258048cd1607e0d", + .pub_y = + "c4789753e2b1f63b32ff014ec42cd6a6" + "9fac81dfe6d0d6fd4af372ae27c46f88", + .want = + "96441259534b80f6aee3d287a6bb17b5" + "094dd4277d9e294f8fe73e48bf2a0024", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "41192d2813e79561e6a1d6f53c8bc1a4" + "33a199c835e141b05a74a97b0faeb922", + .peer_y = + "1af98cc45e98a7e041b01cf35f462b75" + "62281351c8ebf3ffa02e33a0722a1328", + .priv = + "59137e38152350b195c9718d39673d51" + "9838055ad908dd4757152fd8255c09bf", + .pub_x = + "a8c5fdce8b62c5ada598f141adb3b26c" + "f254c280b2857a63d2ad783a73115f6b", + .pub_y = + "806e1aafec4af80a0d786b3de45375b5" + "17a7e5b51ffb2c356537c9e6ef227d4a", + .want = + "19d44c8d63e8e8dd12c22a87b8cd4ece" + "27acdde04dbf47f7f27537a6999a8e62", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "33e82092a0f1fb38f5649d5867fba28b" + "503172b7035574bf8e5b7100a3052792", + .peer_y = + "f2cf6b601e0a05945e335550bf648d78" + "2f46186c772c0f20d3cd0d6b8ca14b2f", + .priv = + "f5f8e0174610a661277979b58ce5c90f" + "ee6c9b3bb346a90a7196255e40b132ef", + .pub_x = + "7b861dcd2844a5a8363f6b8ef8d49364" + "0f55879217189d80326aad9480dfc149", + .pub_y = + "c4675b45eeb306405f6c33c38bc69eb2" + "bdec9b75ad5af4706aab84543b9cc63a", + .want = + "664e45d5bba4ac931cd65d52017e4be9" + "b19a515f669bea4703542a2c525cd3d3", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "6a9e0c3f916e4e315c91147be571686d" + "90464e8bf981d34a90b6353bca6eeba7", + .peer_y = + "40f9bead39c2f2bcc2602f75b8a73ec7" + "bdffcbcead159d0174c6c4d3c5357f05", + .priv = + "3b589af7db03459c23068b64f63f28d3" + "c3c6bc25b5bf76ac05f35482888b5190", + .pub_x = + "9fb38e2d58ea1baf7622e96720101cae" + "3cde4ba6c1e9fa26d9b1de0899102863", + .pub_y = + "d5561b900406edf50802dd7d73e89395" + "f8aed72fba0e1d1b61fe1d22302260f0", + .want = + "ca342daa50dc09d61be7c196c85e60a8" + "0c5cb04931746820be548cdde055679d", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "a9c0acade55c2a73ead1a86fb0a97132" + "23c82475791cd0e210b046412ce224bb", + .peer_y = + "f6de0afa20e93e078467c053d241903e" + "dad734c6b403ba758c2b5ff04c9d4229", + .priv = + "d8bf929a20ea7436b2461b541a11c80e" + "61d826c0a4c9d322b31dd54e7f58b9c8", + .pub_x = + "20f07631e4a6512a89ad487c4e9d6303" + "9e579cb0d7a556cb9e661cd59c1e7fa4", + .pub_y = + "6de91846b3eee8a5ec09c2ab1f41e21b" + "d83620ccdd1bdce3ab7ea6e02dd274f5", + .want = + "35aa9b52536a461bfde4e85fc756be92" + "8c7de97923f0416c7a3ac8f88b3d4489", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "94e94f16a98255fff2b9ac0c9598aac3" + "5487b3232d3231bd93b7db7df36f9eb9", + .peer_y = + "d8049a43579cfa90b8093a94416cbefb" + "f93386f15b3f6e190b6e3455fedfe69a", + .priv = + "0f9883ba0ef32ee75ded0d8bda39a514" + "6a29f1f2507b3bd458dbea0b2bb05b4d", + .pub_x = + "abb61b423be5d6c26e21c605832c9142" + "dc1dfe5a5fff28726737936e6fbf516d", + .pub_y = + "733d2513ef58beab202090586fac91bf" + "0fee31e80ab33473ab23a2d89e58fad6", + .want = + "605c16178a9bc875dcbff54d63fe00df" + "699c03e8a888e9e94dfbab90b25f39b4", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "e099bf2a4d557460b5544430bbf6da11" + "004d127cb5d67f64ab07c94fcdf5274f", + .peer_y = + "d9c50dbe70d714edb5e221f4e020610e" + "eb6270517e688ca64fb0e98c7ef8c1c5", + .priv = + "2beedb04b05c6988f6a67500bb813faf" + "2cae0d580c9253b6339e4a3337bb6c08", + .pub_x = + "3d63e429cb5fa895a9247129bf4e48e8" + "9f35d7b11de8158efeb3e106a2a87395", + .pub_y = + "0cae9e477ef41e7c8c1064379bb7b554" + "ddcbcae79f9814281f1e50f0403c61f3", + .want = + "f96e40a1b72840854bb62bc13c40cc27" + "95e373d4e715980b261476835a092e0b", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "f75a5fe56bda34f3c1396296626ef012" + "dc07e4825838778a645c8248cff01658", + .peer_y = + "33bbdf1b1772d8059df568b061f3f112" + "2f28a8d819167c97be448e3dc3fb0c3c", + .priv = + "77c15dcf44610e41696bab758943eff1" + "409333e4d5a11bbe72c8f6c395e9f848", + .pub_x = + "ad5d13c3db508ddcd38457e5991434a2" + "51bed49cf5ddcb59cdee73865f138c9f", + .pub_y = + "62cec1e70588aa4fdfc7b9a09daa6780" + "81c04e1208b9d662b8a2214bf8e81a21", + .want = + "8388fa79c4babdca02a8e8a34f9e4355" + "4976e420a4ad273c81b26e4228e9d3a3", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "2db4540d50230756158abf61d9835712" + "b6486c74312183ccefcaef2797b7674d", + .peer_y = + "62f57f314e3f3495dc4e099012f5e0ba" + "71770f9660a1eada54104cdfde77243e", + .priv = + "42a83b985011d12303db1a800f2610f7" + "4aa71cdf19c67d54ce6c9ed951e9093e", + .pub_x = + "ab48caa61ea35f13f8ed07ffa6a13e8d" + "b224dfecfae1a7df8b1bb6ebaf0cb97d", + .pub_y = + "1274530ca2c385a3218bddfbcbf0b402" + "4c9badd5243bff834ebff24a8618dccb", + .want = + "72877cea33ccc4715038d4bcbdfe0e43" + "f42a9e2c0c3b017fc2370f4b9acbda4a", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "cd94fc9497e8990750309e9a8534fd11" + "4b0a6e54da89c4796101897041d14ecb", + .peer_y = + "c3def4b5fe04faee0a11932229fff563" + "637bfdee0e79c6deeaf449f85401c5c4", + .priv = + "ceed35507b5c93ead5989119b9ba342c" + "fe38e6e638ba6eea343a55475de2800b", + .pub_x = + "9a8cd9bd72e71752df91440f77c54750" + "9a84df98114e7de4f26cdb39234a625d", + .pub_y = + "d07cfc84c8e144fab2839f5189bb1d7c" + "88631d579bbc58012ed9a2327da52f62", + .want = + "e4e7408d85ff0e0e9c838003f28cdbd5" + "247cdce31f32f62494b70e5f1bc36307", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "15b9e467af4d290c417402e040426fe4" + "cf236bae72baa392ed89780dfccdb471", + .peer_y = + "cdf4e9170fb904302b8fd93a820ba8cc" + "7ed4efd3a6f2d6b05b80b2ff2aee4e77", + .priv = + "43e0e9d95af4dc36483cdd1968d2b7ee" + "b8611fcce77f3a4e7d059ae43e509604", + .pub_x = + "f989cf8ee956a82e7ebd9881cdbfb2fd" + "946189b08db53559bc8cfdd48071eb14", + .pub_y = + "5eff28f1a18a616b04b7d337868679f6" + "dd84f9a7b3d7b6f8af276c19611a541d", + .want = + "ed56bcf695b734142c24ecb1fc1bb64d" + "08f175eb243a31f37b3d9bb4407f3b96", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "49c503ba6c4fa605182e186b5e81113f" + "075bc11dcfd51c932fb21e951eee2fa1", + .peer_y = + "8af706ff0922d87b3f0c5e4e31d8b259" + "aeb260a9269643ed520a13bb25da5924", + .priv = + "b2f3600df3368ef8a0bb85ab22f41fc0" + "e5f4fdd54be8167a5c3cd4b08db04903", + .pub_x = + "69c627625b36a429c398b45c38677cb3" + "5d8beb1cf78a571e40e99fe4eac1cd4e", + .pub_y = + "81690112b0a88f20f7136b28d7d47e5f" + "bc2ada3c8edd87589bc19ec9590637bd", + .want = + "bc5c7055089fc9d6c89f83c1ea1ada87" + "9d9934b2ea28fcf4e4a7e984b28ad2cf", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "19b38de39fdd2f70f7091631a4f75d19" + "93740ba9429162c2a45312401636b29c", + .peer_y = + "09aed7232b28e060941741b6828bcdfa" + "2bc49cc844f3773611504f82a390a5ae", + .priv = + "4002534307f8b62a9bf67ff641ddc60f" + "ef593b17c3341239e95bdb3e579bfdc8", + .pub_x = + "5fe964671315a18aa68a2a6e3dd1fde7" + "e23b8ce7181471cfac43c99e1ae80262", + .pub_y = + "d5827be282e62c84de531b963884ba83" + "2db5d6b2c3a256f0e604fe7e6b8a7f72", + .want = + "9a4e8e657f6b0e097f47954a63c75d74" + "fcba71a30d83651e3e5a91aa7ccd8343", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "2c91c61f33adfe9311c942fdbff6ba47" + "020feff416b7bb63cec13faf9b099954", + .peer_y = + "6cab31b06419e5221fca014fb84ec870" + "622a1b12bab5ae43682aa7ea73ea08d0", + .priv = + "4dfa12defc60319021b681b3ff84a10a" + "511958c850939ed45635934ba4979147", + .pub_x = + "c9b2b8496f1440bd4a2d1e52752fd372" + "835b364885e154a7dac49295f281ec7c", + .pub_y = + "fbe6b926a8a4de26ccc83b802b121240" + "0754be25d9f3eeaf008b09870ae76321", + .want = + "3ca1fc7ad858fb1a6aba232542f3e2a7" + "49ffc7203a2374a3f3d3267f1fc97b78", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "a28a2edf58025668f724aaf83a50956b" + "7ac1cfbbff79b08c3bf87dfd2828d767", + .peer_y = + "dfa7bfffd4c766b86abeaf5c99b6e50c" + "b9ccc9d9d00b7ffc7804b0491b67bc03", + .priv = + "1331f6d874a4ed3bc4a2c6e9c74331d3" + "039796314beee3b7152fcdba5556304e", + .pub_x = + "59e1e101521046ad9cf1d082e9d2ec7d" + "d22530cce064991f1e55c5bcf5fcb591", + .pub_y = + "482f4f673176c8fdaa0bb6e59b15a3e4" + "7454e3a04297d3863c9338d98add1f37", + .want = + "1aaabe7ee6e4a6fa732291202433a237" + "df1b49bc53866bfbe00db96a0f58224f", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "a2ef857a081f9d6eb206a81c4cf78a80" + "2bdf598ae380c8886ecd85fdc1ed7644", + .peer_y = + "563c4c20419f07bc17d0539fade1855e" + "34839515b892c0f5d26561f97fa04d1a", + .priv = + "dd5e9f70ae740073ca0204df60763fb6" + "036c45709bf4a7bb4e671412fad65da3", + .pub_x = + "30b9db2e2e977bcdc98cb87dd736cbd8" + "e78552121925cf16e1933657c2fb2314", + .pub_y = + "6a45028800b81291bce5c2e1fed7ded6" + "50620ebbe6050c6f3a7f0dfb4673ab5c", + .want = + "430e6a4fba4449d700d2733e557f66a3" + "bf3d50517c1271b1ddae1161b7ac798c", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "ccd8a2d86bc92f2e01bce4d6922cf7fe" + "1626aed044685e95e2eebd464505f01f", + .peer_y = + "e9ddd583a9635a667777d5b8a8f31b0f" + "79eba12c75023410b54b8567dddc0f38", + .priv = + "5ae026cfc060d55600717e55b8a12e11" + "6d1d0df34af831979057607c2d9c2f76", + .pub_x = + "46c9ebd1a4a3c8c0b6d572b5dcfba124" + "67603208a9cb5d2acfbb733c40cf6391", + .pub_y = + "46c913a27d044185d38b467ace011e04" + "d4d9bbbb8cb9ae25fa92aaf15a595e86", + .want = + "1ce9e6740529499f98d1f1d71329147a" + "33df1d05e4765b539b11cf615d6974d3", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "c188ffc8947f7301fb7b53e36746097c" + "2134bf9cc981ba74b4e9c4361f595e4e", + .peer_y = + "bf7d2f2056e72421ef393f0c0f2b0e00" + "130e3cac4abbcc00286168e85ec55051", + .priv = + "b601ac425d5dbf9e1735c5e2d5bdb79c" + "a98b3d5be4a2cfd6f2273f150e064d9d", + .pub_x = + "7c9e950841d26c8dde8994398b8f5d47" + "5a022bc63de7773fcf8d552e01f1ba0a", + .pub_y = + "cc42b9885c9b3bee0f8d8c57d3a8f635" + "5016c019c4062fa22cff2f209b5cc2e1", + .want = + "4690e3743c07d643f1bc183636ab2a9c" + "b936a60a802113c49bb1b3f2d0661660", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "317e1020ff53fccef18bf47bb7f2dd77" + "07fb7b7a7578e04f35b3beed222a0eb6", + .peer_y = + "09420ce5a19d77c6fe1ee587e6a49fba" + "f8f280e8df033d75403302e5a27db2ae", + .priv = + "fefb1dda1845312b5fce6b81b2be205a" + "f2f3a274f5a212f66c0d9fc33d7ae535", + .pub_x = + "38b54db85500cb20c61056edd3d88b6a" + "9dc26780a047f213a6e1b900f76596eb", + .pub_y = + "6387e4e5781571e4eb8ae62991a33b5d" + "c33301c5bc7e125d53794a39160d8fd0", + .want = + "30c2261bd0004e61feda2c16aa5e21ff" + "a8d7e7f7dbf6ec379a43b48e4b36aeb0", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "45fb02b2ceb9d7c79d9c2fa93e9c7967" + "c2fa4df5789f9640b24264b1e524fcb1", + .peer_y = + "5c6e8ecf1f7d3023893b7b1ca1e4d178" + "972ee2a230757ddc564ffe37f5c5a321", + .priv = + "334ae0c4693d23935a7e8e043ebbde21" + "e168a7cba3fa507c9be41d7681e049ce", + .pub_x = + "3f2bf1589abf3047bf3e54ac9a95379b" + "ff95f8f55405f64eca36a7eebe8ffca7", + .pub_y = + "5212a94e66c5ae9a8991872f66a72723" + "d80ec5b2e925745c456f5371943b3a06", + .want = + "2adae4a138a239dcd93c243a3803c3e4" + "cf96e37fe14e6a9b717be9599959b11c", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "a19ef7bff98ada781842fbfc51a47aff" + "39b5935a1c7d9625c8d323d511c92de6", + .peer_y = + "e9c184df75c955e02e02e400ffe45f78" + "f339e1afe6d056fb3245f4700ce606ef", + .priv = + "2c4bde40214fcc3bfc47d4cf434b629a" + "cbe9157f8fd0282540331de7942cf09d", + .pub_x = + "29c0807f10cbc42fb45c9989da50681e" + "ead716daa7b9e91fd32e062f5eb92ca0", + .pub_y = + "ff1d6d1955d7376b2da24fe1163a2716" + "59136341bc2eb1195fc706dc62e7f34d", + .want = + "2e277ec30f5ea07d6ce513149b9479b9" + "6e07f4b6913b1b5c11305c1444a1bc0b", + }, + { + .nid = NID_X9_62_prime256v1, + .peer_x = + "356c5a444c049a52fee0adeb7e5d82ae" + "5aa83030bfff31bbf8ce2096cf161c4b", + .peer_y = + "57d128de8b2a57a094d1a001e572173f" + "96e8866ae352bf29cddaf92fc85b2f92", + .priv = + "85a268f9d7772f990c36b42b0a331adc" + "92b5941de0b862d5d89a347cbf8faab0", + .pub_x = + "9cf4b98581ca1779453cc816ff28b410" + "0af56cf1bf2e5bc312d83b6b1b21d333", + .pub_y = + "7a5504fcac5231a0d12d658218284868" + "229c844a04a3450d6c7381abe080bf3b", + .want = + "1e51373bd2c6044c129c436e742a55be" + "2a668a85ae08441b6756445df5493857", + }, + + { + .nid = NID_secp384r1, + .peer_x = + "a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e76459" + "2efda27fe7513272734466b400091adbf2d68c58e0c50066", + .peer_y = + "ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b66" + "1efedf243451915ed0905a32b060992b468c64766fc8437a", + .priv = + "3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b1" + "5618b6818a661774ad463b205da88cf699ab4d43c9cf98a1", + .pub_x = + "9803807f2f6d2fd966cdd0290bd410c0190352fbec7ff624" + "7de1302df86f25d34fe4a97bef60cff548355c015dbb3e5f", + .pub_y = + "ba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2" + "af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99", + .want = + "5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f4" + "0ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1", + }, + { + .nid = NID_secp384r1, + .peer_x = + "30f43fcf2b6b00de53f624f1543090681839717d53c7c955" + "d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0", + .peer_y = + "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c" + "860857a68153ab62e525ec0530d81b5aa15897981e858757", + .priv = + "92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8" + "b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783", + .pub_x = + "ea4018f5a307c379180bf6a62fd2ceceebeeb7d4df063a66" + "fb838aa35243419791f7e2c9d4803c9319aa0eb03c416b66", + .pub_y = + "68835a91484f05ef028284df6436fb88ffebabcdd69ab013" + "3e6735a1bcfb37203d10d340a8328a7b68770ca75878a1a6", + .want = + "a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd50" + "1a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff", + }, + { + .nid = NID_secp384r1, + .peer_x = + "1aefbfa2c6c8c855a1a216774550b79a24cda37607bb1f7c" + "c906650ee4b3816d68f6a9c75da6e4242cebfb6652f65180", + .peer_y = + "419d28b723ebadb7658fcebb9ad9b7adea674f1da3dc6b63" + "97b55da0f61a3eddacb4acdb14441cb214b04a0844c02fa3", + .priv = + "12cf6a223a72352543830f3f18530d5cb37f26880a0b2944" + "82c8a8ef8afad09aa78b7dc2f2789a78c66af5d1cc553853", + .pub_x = + "fcfcea085e8cf74d0dced1620ba8423694f903a219bbf901" + "b0b59d6ac81baad316a242ba32bde85cb248119b852fab66", + .pub_y = + "972e3c68c7ab402c5836f2a16ed451a33120a7750a6039f3" + "ff15388ee622b7065f7122bf6d51aefbc29b37b03404581b", + .want = + "3d2e640f350805eed1ff43b40a72b2abed0a518bcebe8f2d" + "15b111b6773223da3c3489121db173d414b5bd5ad7153435", + }, + { + .nid = NID_secp384r1, + .peer_x = + "8bc089326ec55b9cf59b34f0eb754d93596ca290fcb3444c" + "83d4de3a5607037ec397683f8cef07eab2fe357eae36c449", + .peer_y = + "d9d16ce8ac85b3f1e94568521aae534e67139e310ec72693" + "526aa2e927b5b322c95a1a033c229cb6770c957cd3148dd7", + .priv = + "8dd48063a3a058c334b5cc7a4ce07d02e5ee6d8f1f3c51a1" + "600962cbab462690ae3cd974fb39e40b0e843daa0fd32de1", + .pub_x = + "e38c9846248123c3421861ea4d32669a7b5c3c08376ad281" + "04399494c84ff5efa3894adb2c6cbe8c3c913ef2eec5bd3c", + .pub_y = + "9fa84024a1028796df84021f7b6c9d02f0f4bd1a612a03cb" + "f75a0beea43fef8ae84b48c60172aadf09c1ad016d0bf3ce", + .want = + "6a42cfc392aba0bfd3d17b7ccf062b91fc09bbf3417612d0" + "2a90bdde62ae40c54bb2e56e167d6b70db670097eb8db854", + }, + { + .nid = NID_secp384r1, + .peer_x = + "eb952e2d9ac0c20c6cc48fb225c2ad154f53c8750b003fd3" + "b4ed8ed1dc0defac61bcdde02a2bcfee7067d75d342ed2b0", + .peer_y = + "f1828205baece82d1b267d0d7ff2f9c9e15b69a72df47058" + "a97f3891005d1fb38858f5603de840e591dfa4f6e7d489e1", + .priv = + "84ece6cc3429309bd5b23e959793ed2b111ec5cb43b6c180" + "85fcaea9efa0685d98a6262ee0d330ee250bc8a67d0e733f", + .pub_x = + "3222063a2997b302ee60ee1961108ff4c7acf1c0ef1d5fb0" + "d164b84bce71c431705cb9aea9a45f5d73806655a058bee3", + .pub_y = + "e61fa9e7fbe7cd43abf99596a3d3a039e99fa9dc93b0bdd9" + "cad81966d17eeaf557068afa7c78466bb5b22032d1100fa6", + .want = + "ce7ba454d4412729a32bb833a2d1fd2ae612d4667c3a900e" + "069214818613447df8c611de66da200db7c375cf913e4405", + }, + { + .nid = NID_secp384r1, + .peer_x = + "441d029e244eb7168d647d4df50db5f4e4974ab3fdaf022a" + "ff058b3695d0b8c814cc88da6285dc6df1ac55c553885003", + .peer_y = + "e8025ac23a41d4b1ea2aa46c50c6e479946b59b6d76497cd" + "9249977e0bfe4a6262622f13d42a3c43d66bdbb30403c345", + .priv = + "68fce2121dc3a1e37b10f1dde309f9e2e18fac47cd177095" + "1451c3484cdb77cb136d00e731260597cc2859601c01a25b", + .pub_x = + "868be0e694841830e424d913d8e7d86b84ee1021d82b0ecf" + "523f09fe89a76c0c95c49f2dfbcf829c1e39709d55efbb3b", + .pub_y = + "9195eb183675b40fd92f51f37713317e4a9b4f715c8ab22e" + "0773b1bc71d3a219f05b8116074658ee86b52e36f3897116", + .want = + "ba69f0acdf3e1ca95caaac4ecaf475bbe51b54777efce01c" + "a381f45370e486fe87f9f419b150c61e329a286d1aa265ec", + }, + { + .nid = NID_secp384r1, + .peer_x = + "3d4e6bf08a73404accc1629873468e4269e82d90d832e58a" + "d72142639b5a056ad8d35c66c60e8149fac0c797bceb7c2f", + .peer_y = + "9b0308dc7f0e6d29f8c277acbc65a21e5adb83d11e6873bc" + "0a07fda0997f482504602f59e10bc5cb476b83d0a4f75e71", + .priv = + "b1764c54897e7aae6de9e7751f2f37de849291f88f0f9109" + "3155b858d1cc32a3a87980f706b86cc83f927bdfdbeae0bd", + .pub_x = + "c371222feaa6770c6f3ea3e0dac9740def4fcf821378b7f9" + "1ff937c21e0470f70f3a31d5c6b2912195f10926942b48ae", + .pub_y = + "047d6b4d765123563f81116bc665b7b8cc6207830d805fd8" + "4da7cb805a65baa7c12fd592d1b5b5e3e65d9672a9ef7662", + .want = + "1a6688ee1d6e59865d8e3ada37781d36bb0c2717eef92e61" + "964d3927cb765c2965ea80f7f63e58c322ba0397faeaf62b", + }, + { + .nid = NID_secp384r1, + .peer_x = + "f5f6bef1d110da03be0017eac760cc34b24d092f736f237b" + "c7054b3865312a813bcb62d297fb10a4f7abf54708fe2d3d", + .peer_y = + "06fdf8d7dc032f4e10010bf19cbf6159321252ff415fb919" + "20d438f24e67e60c2eb0463204679fa356af44cea9c9ebf5", + .priv = + "f0f7a96e70d98fd5a30ad6406cf56eb5b72a510e9f192f50" + "e1f84524dbf3d2439f7287bb36f5aa912a79deaab4adea82", + .pub_x = + "99c8c41cb1ab5e0854a346e4b08a537c1706a61553387c8d" + "94943ab15196d40dbaa55b8210a77a5d00915f2c4ea69eab", + .pub_y = + "5531065bdcf17bfb3cb55a02e41a57c7f694c383ad289f90" + "0fbd656c2233a93c92e933e7a26f54cbb56f0ad875c51bb0", + .want = + "d06a568bf2336b90cbac325161be7695eacb2295f599500d" + "787f072612aca313ee5d874f807ddef6c1f023fe2b6e7cd0", + }, + { + .nid = NID_secp384r1, + .peer_x = + "7cdec77e0737ea37c67b89b7137fe38818010f4464438ee4" + "d1d35a0c488cad3fde2f37d00885d36d3b795b9f93d23a67", + .peer_y = + "28c42ee8d6027c56cf979ba4c229fdb01d234944f8ac4336" + "50112c3cf0f02844e888a3569dfef7828a8a884589aa055e", + .priv = + "9efb87ddc61d43c482ba66e1b143aef678fbd0d1bebc2000" + "941fabe677fe5b706bf78fce36d100b17cc787ead74bbca2", + .pub_x = + "4c34efee8f0c95565d2065d1bbac2a2dd25ae964320eb6bc" + "cedc5f3a9b42a881a1afca1bb6b880584fa27b01c193cd92", + .pub_y = + "d8fb01dbf7cd0a3868c26b951f393c3c56c2858cee901f77" + "93ff5d271925d13a41f8e52409f4eba1990f33acb0bac669", + .want = + "bb3b1eda9c6560d82ff5bee403339f1e80342338a9913448" + "53b56b24f109a4d94b92f654f0425edd4c205903d7586104", + }, + { + .nid = NID_secp384r1, + .peer_x = + "8eeea3a319c8df99fbc29cb55f243a720d95509515ee5cc5" + "87a5c5ae22fbbd009e626db3e911def0b99a4f7ae304b1ba", + .peer_y = + "73877dc94db9adddc0d9a4b24e8976c22d73c844370e1ee8" + "57f8d1b129a3bd5f63f40caf3bd0533e38a5f5777074ff9e", + .priv = + "d787a57fde22ec656a0a525cf3c738b30d73af61e743ea90" + "893ecb2d7b622add2f94ee25c2171467afb093f3f84d0018", + .pub_x = + "171546923b87b2cbbad664f01ce932bf09d6a61181686784" + "46bfa9f0938608cb4667a98f4ec8ac1462285c2508f74862", + .pub_y = + "fa41cb4db68ae71f1f8a3e8939dc52c2dec61a83c983beb2" + "a02baf29ec49278088882ed0cf56c74b5c173b552ccf63cf", + .want = + "1e97b60add7cb35c7403dd884c0a75795b7683fff8b49f9d" + "8672a8206bfdcf0a106b8768f983258c74167422e44e4d14", + }, + { + .nid = NID_secp384r1, + .peer_x = + "a721f6a2d4527411834b13d4d3a33c29beb83ab7682465c6" + "cbaf6624aca6ea58c30eb0f29dd842886695400d7254f20f", + .peer_y = + "14ba6e26355109ad35129366d5e3a640ae798505a7fa55a9" + "6a36b5dad33de00474f6670f522214dd7952140ab0a7eb68", + .priv = + "83d70f7b164d9f4c227c767046b20eb34dfc778f5387e32e" + "834b1e6daec20edb8ca5bb4192093f543b68e6aeb7ce788b", + .pub_x = + "57cd770f3bbcbe0c78c770eab0b169bc45e139f86378ffae" + "1c2b16966727c2f2eb724572b8f3eb228d130db4ff862c63", + .pub_y = + "7ec5c8813b685558d83e924f14bc719f6eb7ae0cbb2c4742" + "27c5bda88637a4f26c64817929af999592da6f787490332f", + .want = + "1023478840e54775bfc69293a3cf97f5bc914726455c6653" + "8eb5623e218feef7df4befa23e09d77145ad577db32b41f9", + }, + { + .nid = NID_secp384r1, + .peer_x = + "d882a8505c2d5cb9b8851fc676677bb0087681ad53faceba" + "1738286b45827561e7da37b880276c656cfc38b32ade847e", + .peer_y = + "34b314bdc134575654573cffaf40445da2e6aaf987f7e913" + "cd4c3091523058984a25d8f21da8326192456c6a0fa5f60c", + .priv = + "8f558e05818b88ed383d5fca962e53413db1a0e4637eda19" + "4f761944cbea114ab9d5da175a7d57882550b0e432f395a9", + .pub_x = + "9a2f57f4867ce753d72b0d95195df6f96c1fae934f602efd" + "7b6a54582f556cfa539d89005ca2edac08ad9b72dd1f60ba", + .pub_y = + "d9b94ee82da9cc601f346044998ba387aee56404dc6ecc8a" + "b2b590443319d0b2b6176f9d0eac2d44678ed561607d09a9", + .want = + "6ad6b9dc8a6cf0d3691c501cbb967867f6e4bbb764b60dbf" + "f8fcff3ed42dbba39d63cf325b4b4078858495ddee75f954", + }, + { + .nid = NID_secp384r1, + .peer_x = + "815c9d773dbf5fb6a1b86799966247f4006a23c92e68c55e" + "9eaa998b17d8832dd4d84d927d831d4f68dac67c6488219f", + .peer_y = + "e79269948b2611484560fd490feec887cb55ef99a4b52488" + "0fa7499d6a07283aae2afa33feab97deca40bc606c4d8764", + .priv = + "0f5dee0affa7bbf239d5dff32987ebb7cf84fcceed643e1d" + "3c62d0b3352aec23b6e5ac7fa4105c8cb26126ad2d1892cb", + .pub_x = + "23346bdfbc9d7c7c736e02bdf607671ff6082fdd27334a8b" + "c75f3b23681ebe614d0597dd614fae58677c835a9f0b273b", + .pub_y = + "82ba36290d2f94db41479eb45ab4eaf67928a2315138d59e" + "ecc9b5285dfddd6714f77557216ea44cc6fc119d8243efaf", + .want = + "cc9e063566d46b357b3fcae21827377331e5e290a36e60cd" + "7c39102b828ae0b918dc5a02216b07fe6f1958d834e42437", + }, + { + .nid = NID_secp384r1, + .peer_x = + "1c0eeda7a2be000c5bdcda0478aed4db733d2a9e34122437" + "9123ad847030f29e3b168fa18e89a3c0fba2a6ce1c28fc3b", + .peer_y = + "ec8c1c83c118c4dbea94271869f2d868eb65e8b44e21e6f1" + "4b0f4d9b38c068daefa27114255b9a41d084cc4a1ad85456", + .priv = + "037b633b5b8ba857c0fc85656868232e2febf59578718391" + "b81da8541a00bfe53c30ae04151847f27499f8d7abad8cf4", + .pub_x = + "8878ac8a947f7d5cb2b47aad24fbb8210d86126585399a28" + "71f84aa9c5fde3074ae540c6bf82275ca822d0feb862bc74", + .pub_y = + "632f5cd2f900c2711c32f8930728eb647d31edd8d650f965" + "4e7d33e5ed1b475489d08daa30d8cbcba6bfc3b60d9b5a37", + .want = + "deff7f03bd09865baf945e73edff6d5122c03fb561db87de" + "c8662e09bed4340b28a9efe118337bb7d3d4f7f568635ff9", + }, + { + .nid = NID_secp384r1, + .peer_x = + "c95c185e256bf997f30b311548ae7f768a38dee43eeeef43" + "083f3077be70e2bf39ac1d4daf360c514c8c6be623443d1a", + .peer_y = + "3e63a663eaf75d8a765ab2b9a35513d7933fa5e26420a524" + "4550ec6c3b6f033b96db2aca3d6ac6aab052ce929595aea5", + .priv = + "e3d07106bedcc096e7d91630ffd3094df2c7859db8d7edbb" + "2e37b4ac47f429a637d06a67d2fba33838764ef203464991", + .pub_x = + "e74a1a2b85f1cbf8dbbdf050cf1aff8acb02fda2fb6591f9" + "d3cfe4e79d0ae938a9c1483e7b75f8db24505d65065cdb18", + .pub_y = + "1773ee591822f7abaa856a1a60bc0a5203548dbd1cb50254" + "66eff8481bd07614eaa04a16c3db76905913e972a5b6b59d", + .want = + "c8b1038f735ad3bb3e4637c3e47eab487637911a6b7950a4" + "e461948329d3923b969e5db663675623611a457fcda35a71", + }, + { + .nid = NID_secp384r1, + .peer_x = + "3497238a7e6ad166df2dac039aa4dac8d17aa925e7c7631e" + "b3b56e3aaa1c545fcd54d2e5985807910fb202b1fc191d2a", + .peer_y = + "a49e5c487dcc7aa40a8f234c979446040d9174e3ad357d40" + "4d7765183195aed3f913641b90c81a306ebf0d8913861316", + .priv = + "f3f9b0c65a49a506632c8a45b10f66b5316f9eeb06fae218" + "f2da62333f99905117b141c760e8974efc4af10570635791", + .pub_x = + "a4ad77aa7d86e5361118a6b921710c820721210712f4c347" + "985fdee58aa4effa1e28be80a17b120b139f96300f89b49b", + .pub_y = + "1ddf22e07e03f1560d8f45a480094560dba9fae7f9531130" + "c1b57ebb95982496524f31d3797793396fa823f22bdb4328", + .want = + "d337eaa32b9f716b8747b005b97a553c59dab0c51df41a2d" + "49039cdae705aa75c7b9e7bc0b6a0e8c578c902bc4fff23e", + }, + { + .nid = NID_secp384r1, + .peer_x = + "90a34737d45b1aa65f74e0bd0659bc118f8e4b774b761944" + "ffa6573c6df4f41dec0d11b697abd934d390871d4b453240", + .peer_y = + "9b590719bb3307c149a7817be355d684893a307764b512ee" + "ffe07cb699edb5a6ffbf8d6032e6c79d5e93e94212c2aa4e", + .priv = + "59fce7fad7de28bac0230690c95710c720e528f9a4e54d3a" + "6a8cd5fc5c5f21637031ce1c5b4e3d39647d8dcb9b794664", + .pub_x = + "9c43bf971edf09402876ee742095381f78b1bd3aa39b5132" + "af75dbfe7e98bd78bde10fe2e903c2b6379e1deee175a1b0", + .pub_y = + "a6c58ecea5a477bb01bd543b339f1cc49f1371a2cda4d46e" + "b4e53e250597942351a99665a122ffea9bde0636c375daf2", + .want = + "32d292b695a4488e42a7b7922e1ae537d76a3d21a0b2e368" + "75f60e9f6d3e8779c2afb3a413b9dd79ae18e70b47d337c1", + }, + { + .nid = NID_secp384r1, + .peer_x = + "dda546acfc8f903d11e2e3920669636d44b2068aeb66ff07" + "aa266f0030e1535b0ed0203cb8a460ac990f1394faf22f1d", + .peer_y = + "15bbb2597913035faadf413476f4c70f7279769a40c986f4" + "70c427b4ee4962abdf8173bbad81874772925fd32f0b159f", + .priv = + "3e49fbf950a424c5d80228dc4bc35e9f6c6c0c1d04440998" + "da0a609a877575dbe437d6a5cedaa2ddd2a1a17fd112aded", + .pub_x = + "5a949594228b1a3d6f599eb3db0d06070fbc551c657b5823" + "4ba164ce3fe415fa5f3eb823c08dc29b8c341219c77b6b3d", + .pub_y = + "2baad447c8c290cfed25edd9031c41d0b76921457327f42d" + "b31122b81f337bbf0b1039ec830ce9061a3761953c75e4a8", + .want = + "1220e7e6cad7b25df98e5bbdcc6c0b65ca6c2a50c5ff6c41" + "dca71e475646fd489615979ca92fb4389aeadefde79a24f1", + }, + { + .nid = NID_secp384r1, + .peer_x = + "788be2336c52f4454d63ee944b1e49bfb619a08371048e6d" + "a92e584eae70bde1f171c4df378bd1f3c0ab03048a237802", + .peer_y = + "4673ebd8db604eaf41711748bab2968a23ca4476ce144e72" + "8247f08af752929157b5830f1e26067466bdfa8b65145a33", + .priv = + "50ccc1f7076e92f4638e85f2db98e0b483e6e2204c92bdd4" + "40a6deea04e37a07c6e72791c190ad4e4e86e01efba84269", + .pub_x = + "756c07df0ce32c839dac9fb4733c9c28b70113a676a7057c" + "38d223f22a3a9095a8d564653af528e04c7e1824be4a6512", + .pub_y = + "17c2ce6962cbd2a2e066297b39d57dd9bb4680f0191d390f" + "70b4e461419b2972ce68ad46127fdda6c39195774ea86df3", + .want = + "793bb9cd22a93cf468faf804a38d12b78cb12189ec679ddd" + "2e9aa21fa9a5a0b049ab16a23574fe04c1c3c02343b91beb", + }, + { + .nid = NID_secp384r1, + .peer_x = + "d09bb822eb99e38060954747c82bb3278cf96bbf36fece34" + "00f4c873838a40c135eb3babb9293bd1001bf3ecdee7bf26", + .peer_y = + "d416db6e1b87bbb7427788a3b6c7a7ab2c165b1e366f9608" + "df512037584f213a648d47f16ac326e19aae972f63fd76c9", + .priv = + "06f132b71f74d87bf99857e1e4350a594e5fe35533b88855" + "2ceccbc0d8923c902e36141d7691e28631b8bc9bafe5e064", + .pub_x = + "2a3cc6b8ff5cde926e7e3a189a1bd029c9b586351af8838f" + "4f201cb8f4b70ef3b0da06d352c80fc26baf8f42b784459e", + .pub_y = + "bf9985960176da6d23c7452a2954ffcbbcb24249b43019a2" + "a023e0b3dabd461f19ad3e775c364f3f11ad49f3099400d3", + .want = + "012d191cf7404a523678c6fc075de8285b243720a9030477" + "08bb33e501e0dbee5bcc40d7c3ef6c6da39ea24d830da1e8", + }, + { + .nid = NID_secp384r1, + .peer_x = + "13741262ede5861dad71063dfd204b91ea1d3b7c631df68e" + "b949969527d79a1dc59295ef7d2bca6743e8cd77b04d1b58", + .peer_y = + "0baaeadc7e19d74a8a04451a135f1be1b02fe299f9dc00bf" + "df201e83d995c6950bcc1cb89d6f7b30bf54656b9a4da586", + .priv = + "12048ebb4331ec19a1e23f1a2c773b664ccfe90a28bfb846" + "fc12f81dff44b7443c77647164bf1e9e67fd2c07a6766241", + .pub_x = + "bc18836bc7a9fdf54b5352f37d7528ab8fa8ec544a8c6180" + "511cbfdd49cce377c39e34c031b5240dc9980503ed2f262c", + .pub_y = + "8086cbe338191080f0b7a16c7afc4c7b0326f9ac66f58552" + "ef4bb9d24de3429ed5d3277ed58fcf48f2b5f61326bec6c6", + .want = + "ad0fd3ddffe8884b9263f3c15fe1f07f2a5a22ffdc7e9670" + "85eea45f0cd959f20f18f522763e28bcc925e496a52dda98", + }, + { + .nid = NID_secp384r1, + .peer_x = + "9e22cbc18657f516a864b37b783348b66f1aa9626cd631f4" + "fa1bd32ad88cf11db52057c660860d39d11fbf024fabd444", + .peer_y = + "6b0d53c79681c28116df71e9cee74fd56c8b7f04b39f1198" + "cc72284e98be9562e35926fb4f48a9fbecafe729309e8b6f", + .priv = + "34d61a699ca576169fcdc0cc7e44e4e1221db0fe63d16850" + "c8104029f7d48449714b9884328cae189978754ab460b486", + .pub_x = + "867f81104ccd6b163a7902b670ef406042cb0cce7dcdc63d" + "1dfc91b2c40e3cdf7595834bf9eceb79849f1636fc8462fc", + .pub_y = + "9d4bde8e875ec49697d258d1d59465f8431c6f5531e1c59e" + "9f9ebe3cf164a8d9ce10a12f1979283a959bad244dd83863", + .want = + "dc4ca392dc15e20185f2c6a8ea5ec31dfc96f56153a47394" + "b3072b13d0015f5d4ae13beb3bed54d65848f9b8383e6c95", + }, + { + .nid = NID_secp384r1, + .peer_x = + "2db5da5f940eaa884f4db5ec2139b0469f38e4e6fbbcc52d" + "f15c0f7cf7fcb1808c749764b6be85d2fdc5b16f58ad5dc0", + .peer_y = + "22e8b02dcf33e1b5a083849545f84ad5e43f77cb71546dbb" + "ac0d11bdb2ee202e9d3872e8d028c08990746c5e1dde9989", + .priv = + "dc60fa8736d702135ff16aab992bb88eac397f5972456c72" + "ec447374d0d8ce61153831bfc86ad5a6eb5b60bfb96a862c", + .pub_x = + "b69beede85d0f829fec1b893ccb9c3e052ff692e13b97453" + "7bc5b0f9feaf7b22e84f03231629b24866bdb4b8cf908914", + .pub_y = + "66f85e2bfcaba2843285b0e14ebc07ef7dafff8b424416fe" + "e647b59897b619f20eed95a632e6a4206bf7da429c04c560", + .want = + "d765b208112d2b9ed5ad10c4046e2e3b0dbf57c469329519" + "e239ac28b25c7d852bf757d5de0ee271cadd021d86cfd347", + }, + { + .nid = NID_secp384r1, + .peer_x = + "329647baa354224eb4414829c5368c82d7893b39804e08cb" + "b2180f459befc4b347a389a70c91a23bd9d30c83be5295d3", + .peer_y = + "cc8f61923fad2aa8e505d6cfa126b9fabd5af9dce290b756" + "60ef06d1caa73681d06089c33bc4246b3aa30dbcd2435b12", + .priv = + "6fa6a1c704730987aa634b0516a826aba8c6d6411d3a4c89" + "772d7a62610256a2e2f289f5c3440b0ec1e70fa339e251ce", + .pub_x = + "53de1fc1328e8de14aecab29ad8a40d6b13768f86f7d2984" + "33d20fec791f86f8bc73f358098b256a298bb488de257bf4", + .pub_y = + "ac28944fd27f17b82946c04c66c41f0053d3692f275da55c" + "d8739a95bd8cd3af2f96e4de959ea8344d8945375905858b", + .want = + "d3778850aeb58804fbe9dfe6f38b9fa8e20c2ca4e0dec335" + "aafceca0333e3f2490b53c0c1a14a831ba37c4b9d74be0f2", + }, + { + .nid = NID_secp384r1, + .peer_x = + "29d8a36d22200a75b7aea1bb47cdfcb1b7fd66de96704143" + "4728ab5d533a060df732130600fe6f75852a871fb2938e39", + .peer_y = + "e19b53db528395de897a45108967715eb8cb55c3fcbf2337" + "9372c0873a058d57544b102ecce722b2ccabb1a603774fd5", + .priv = + "74ad8386c1cb2ca0fcdeb31e0869bb3f48c036afe2ef110c" + "a302bc8b910f621c9fcc54cec32bb89ec7caa84c7b8e54a8", + .pub_x = + "27a3e83cfb9d5122e73129d801615857da7cc089cccc9c54" + "ab3032a19e0a0a9f677346e37f08a0b3ed8da6e5dd691063", + .pub_y = + "8d60e44aa5e0fd30c918456796af37f0e41957901645e5c5" + "96c6d989f5859b03a0bd7d1f4e77936fff3c74d204e5388e", + .want = + "81e1e71575bb4505498de097350186430a6242fa6c57b85a" + "5f984a23371123d2d1424eefbf804258392bc723e4ef1e35", + }, + + { + .nid = NID_secp521r1, + .peer_x = + "000000685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5d" + "a4f4370f3a9490340854334b1e1b87fa395464c60626124a" + "4e70d0f785601d37c09870ebf176666877a2046d", + .peer_y = + "000001ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05" + "400697942e80b739884a83bde99e0f6716939e632bc8986f" + "a18dccd443a348b6c3e522497955a4f3c302f676", + .priv = + "0000017eecc07ab4b329068fba65e56a1f8890aa935e5713" + "4ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefe" + "e5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47", + .pub_x = + "000000602f9d0cf9e526b29e22381c203c48a886c2b06730" + "33366314f1ffbcba240ba42f4ef38a76174635f91e6b4ed3" + "4275eb01c8467d05ca80315bf1a7bbd945f550a5", + .pub_y = + "000001b7c85f26f5d4b2d7355cf6b02117659943762b6d1d" + "b5ab4f1dbc44ce7b2946eb6c7de342962893fd387d1b73d7" + "a8672d1f236961170b7eb3579953ee5cdc88cd2d", + .want = + "005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc" + "5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0" + "ad9759436a4d3c5bf6e74b9578fac148c831", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001df277c152108349bc34d539ee0cf06b24f5d350067" + "7b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51" + "b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a", + .peer_y = + "0000013d52f33a9f3c14384d1587fa8abe7aed74bc33749a" + "d9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990" + "ae7f700e5b4a6640229112deafa0cd8bb0d089b0", + .priv = + "000000816f19c1fb10ef94d4a1d81c156ec3d1de08b66761" + "f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14" + "d74cc872f95d05d07ad50f621ceb620cd905cfb8", + .pub_x = + "000000d45615ed5d37fde699610a62cd43ba76bedd8f85ed" + "31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9" + "f4671105309ec9b6879d0551d930dac8ba45d255", + .pub_y = + "000001425332844e592b440c0027972ad1526431c06732df" + "19cd46a242172d4dd67c2c8c99dfc22e49949a56cf90c647" + "3635ce82f25b33682fb19bc33bd910ed8ce3a7fa", + .want = + "000b3920ac830ade812c8f96805da2236e002acbbf13596a" + "9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032" + "c26d42189273ca4efa4c3db6bd12a6853759", + }, + { + .nid = NID_secp521r1, + .peer_x = + "00000092db3142564d27a5f0006f819908fba1b85038a5bc" + "2509906a497daac67fd7aee0fc2daba4e4334eeaef0e0019" + "204b471cd88024f82115d8149cc0cf4f7ce1a4d5", + .peer_y = + "0000016bad0623f517b158d9881841d2571efbad63f85cbe" + "2e581960c5d670601a6760272675a548996217e4ab2b8ebc" + "e31d71fca63fcc3c08e91c1d8edd91cf6fe845f8", + .priv = + "0000012f2e0c6d9e9d117ceb9723bced02eb3d4eebf5feea" + "f8ee0113ccd8057b13ddd416e0b74280c2d0ba8ed291c443" + "bc1b141caf8afb3a71f97f57c225c03e1e4d42b0", + .pub_x = + "000000717fcb3d4a40d103871ede044dc803db508aaa4ae7" + "4b70b9fb8d8dfd84bfecfad17871879698c292d2fd5e17b4" + "f9343636c531a4fac68a35a93665546b9a878679", + .pub_y = + "000000f3d96a8637036993ab5d244500fff9d2772112826f" + "6436603d3eb234a44d5c4e5c577234679c4f9df725ee5b91" + "18f23d8a58d0cc01096daf70e8dfec0128bdc2e8", + .want = + "006b380a6e95679277cfee4e8353bf96ef2a1ebdd060749f" + "2f046fe571053740bbcc9a0b55790bc9ab56c3208aa05ddf" + "746a10a3ad694daae00d980d944aabc6a08f", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000000fdd40d9e9d974027cb3bae682162eac1328ad61bc4" + "353c45bf5afe76bf607d2894c8cce23695d920f2464fda47" + "73d4693be4b3773584691bdb0329b7f4c86cc299", + .peer_y = + "00000034ceac6a3fef1c3e1c494bfe8d872b183832219a7e" + "14da414d4e3474573671ec19b033be831b915435905925b4" + "4947c592959945b4eb7c951c3b9c8cf52530ba23", + .priv = + "000000e548a79d8b05f923b9825d11b656f222e8cb98b0f8" + "9de1d317184dc5a698f7c71161ee7dc11cd31f4f4f8ae3a9" + "81e1a3e78bdebb97d7c204b9261b4ef92e0918e0", + .pub_x = + "0000000ce800217ed243dd10a79ad73df578aa8a3f9194af" + "528cd1094bbfee27a3b5481ad5862c8876c0c3f91294c0ab" + "3aa806d9020cbaa2ed72b7fecdc5a09a6dad6f32", + .pub_y = + "000001543c9ab45b12469232918e21d5a351f9a4b9cbf9ef" + "b2afcc402fa9b31650bec2d641a05c440d35331c0893d11f" + "b13151335988b303341301a73dc5f61d574e67d9", + .want = + "00fbbcd0b8d05331fef6086f22a6cce4d35724ab7a2f49dd" + "8458d0bfd57a0b8b70f246c17c4468c076874b0dff7a0336" + "823b19e98bf1cec05e4beffb0591f97713c6", + }, + { + .nid = NID_secp521r1, + .peer_x = + "00000098d99dee0816550e84dbfced7e88137fddcf581a72" + "5a455021115fe49f8dc3cf233cd9ea0e6f039dc7919da973" + "cdceaca205da39e0bd98c8062536c47f258f44b5", + .peer_y = + "000000cd225c8797371be0c4297d2b457740100c774141d8" + "f214c23b61aa2b6cd4806b9b70722aa4965fb622f42b7391" + "e27e5ec21c5679c5b06b59127372997d421adc1e", + .priv = + "000001c8aae94bb10b8ca4f7be577b4fb32bb2381032c494" + "2c24fc2d753e7cc5e47b483389d9f3b956d20ee9001b1eef" + "9f23545f72c5602140046839e963313c3decc864", + .pub_x = + "00000106a14e2ee8ff970aa8ab0c79b97a33bba2958e070b" + "75b94736b77bbe3f777324fa52872771aa88a63a9e8490c3" + "378df4dc760cd14d62be700779dd1a4377943656", + .pub_y = + "0000002366ce3941e0b284b1aa81215d0d3b9778fce23c8c" + "d1e4ed6fa0abf62156c91d4b3eb55999c3471bed275e9e60" + "e5aa9d690d310bfb15c9c5bbd6f5e9eb39682b74", + .want = + "0145cfa38f25943516c96a5fd4bfebb2f645d10520117aa5" + "1971eff442808a23b4e23c187e639ff928c3725fbd1c0c2a" + "d0d4aeb207bc1a6fb6cb6d467888dc044b3c", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000007ae115adaaf041691ab6b7fb8c921f99d8ed32d283" + "d67084e80b9ad9c40c56cd98389fb0a849d9ecf7268c297b" + "6f93406119f40e32b5773ed25a28a9a85c4a7588", + .peer_y = + "000001a28e004e37eeaefe1f4dbb71f1878696141af3a10a" + "9691c4ed93487214643b761fa4b0fbeeb247cf6d3fba7a60" + "697536ad03f49b80a9d1cb079673654977c5fa94", + .priv = + "0000009b0af137c9696c75b7e6df7b73156bb2d45f482e5a" + "4217324f478b10ceb76af09724cf86afa316e7f89918d31d" + "54824a5c33107a483c15c15b96edc661340b1c0e", + .pub_x = + "000000748cdbb875d35f4bccb62abe20e82d32e4c14dc2fe" + "b5b87da2d0ccb11c9b6d4b7737b6c46f0dfb4d896e2db92f" + "cf53cdbbae2a404c0babd564ad7adeac6273efa3", + .pub_y = + "000001984acab8d8f173323de0bb60274b228871609373bb" + "22a17287e9dec7495873abc09a8915b54c8455c8e02f654f" + "602e23a2bbd7a9ebb74f3009bd65ecc650814cc0", + .want = + "005c5721e96c273319fd60ecc46b5962f698e974b429f28f" + "e6962f4ac656be2eb8674c4aafc037eab48ece612953b1e8" + "d861016b6ad0c79805784c67f73ada96f351", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000012588115e6f7f7bdcfdf57f03b169b479758baafdaf" + "569d04135987b2ce6164c02a57685eb5276b5dae6295d3fe" + "90620f38b5535c6d2260c173e61eb888ca920203", + .peer_y = + "000001542c169cf97c2596fe2ddd848a222e367c5f7e6267" + "ebc1bcd9ab5dcf49158f1a48e4af29a897b7e6a82091c2db" + "874d8e7abf0f58064691344154f396dbaed188b6", + .priv = + "000001e48faacee6dec83ffcde944cf6bdf4ce4bae727478" + "88ebafee455b1e91584971efb49127976a52f4142952f7c2" + "07ec0265f2b718cf3ead96ea4f62c752e4f7acd3", + .pub_x = + "0000010eb1b4d9172bcc23f4f20cc9560fc54928c3f34ea6" + "1c00391dc766c76ed9fa608449377d1e4fadd12360254173" + "30b4b91086704ace3e4e6484c606e2a943478c86", + .pub_y = + "00000149413864069825ee1d0828da9f4a97713005e9bd1a" + "dbc3b38c5b946900721a960fe96ad2c1b3a44fe3de915613" + "6d44cb17cbc2415729bb782e16bfe2deb3069e43", + .want = + "01736d9717429b4f412e903febe2f9e0fffd81355d6ce2c0" + "6ff3f66a3be15ceec6e65e308347593f00d7f33591da4043" + "c30763d72749f72cdceebe825e4b34ecd570", + }, + { + .nid = NID_secp521r1, + .peer_x = + "00000169491d55bd09049fdf4c2a53a660480fee4c03a053" + "8675d1cd09b5bba78dac48543ef118a1173b3fbf8b20e39c" + "e0e6b890a163c50f9645b3d21d1cbb3b60a6fff4", + .peer_y = + "00000083494b2eba76910fed33c761804515011fab50e3b3" + "77abd8a8a045d886d2238d2c268ac1b6ec88bd71b7ba78e2" + "c33c152e4bf7da5d565e4acbecf5e92c7ad662bb", + .priv = + "000000c29aa223ea8d64b4a1eda27f39d3bc98ea0148dd98" + "c1cbe595f8fd2bfbde119c9e017a50f5d1fc121c08c1cef3" + "1b758859556eb3e0e042d8dd6aaac57a05ca61e3", + .pub_x = + "0000001511c848ef60d5419a98d10204db0fe58224124370" + "061bcfa4e9249d50618c56bf3722471b259f38263bb7b280" + "d23caf2a1ee8737f9371cdb2732cdc958369930c", + .pub_y = + "000001d461681ae6d8c49b4c5f4d6016143fb1bd7491573e" + "3ed0e6c48b82e821644f87f82f0e5f08fd16f1f98fa17586" + "200ab02ed8c627b35c3f27617ec5fd92f456203f", + .want = + "018f2ae9476c771726a77780208dedfefa205488996b18fe" + "cc50bfd4c132753f5766b2cd744afa9918606de2e016effc" + "63622e9029e76dc6e3f0c69f7aeced565c2c", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000008415f5bbd0eee387d6c09d0ef8acaf29c66db45d6b" + "a101860ae45d3c60e1e0e3f7247a4626a60fdd404965c356" + "6c79f6449e856ce0bf94619f97da8da24bd2cfb6", + .peer_y = + "000000fdd7c59c58c361bc50a7a5d0d36f723b17c4f2ad2b" + "03c24d42dc50f74a8c465a0afc4683f10fab84652dfe9e92" + "8c2626b5456453e1573ff60be1507467d431fbb2", + .priv = + "00000028692be2bf5c4b48939846fb3d5bce74654bb2646e" + "15f8389e23708a1afadf561511ea0d9957d0b53453819d60" + "fba8f65a18f7b29df021b1bb01cd163293acc3cc", + .pub_x = + "000001cfdc10c799f5c79cb6930a65fba351748e07567993" + "e5e410ef4cacc4cd8a25784991eb4674e41050f930c7190a" + "c812b9245f48a7973b658daf408822fe5b85f668", + .pub_y = + "00000180d9ddfc9af77b9c4a6f02a834db15e535e0b3845b" + "2cce30388301b51cecbe3276307ef439b5c9e6a72dc2d94d" + "879bc395052dbb4a5787d06efb280210fb8be037", + .want = + "0105a346988b92ed8c7a25ce4d79d21bc86cfcc7f99c6cd1" + "9dbb4a39f48ab943b79e4f0647348da0b80bd864b85c6b8d" + "92536d6aa544dc7537a00c858f8b66319e25", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001c721eea805a5cba29f34ba5758775be0cf6160e6c0" + "8723f5ab17bf96a1ff2bd9427961a4f34b07fc0b14ca4b2b" + "f6845debd5a869f124ebfa7aa72fe565050b7f18", + .peer_y = + "000000b6e89eb0e1dcf181236f7c548fd1a8c16b258b52c1" + "a9bfd3fe8f22841b26763265f074c4ccf2d634ae97b70195" + "6f67a11006c52d97197d92f585f5748bc2672eeb", + .priv = + "000001194d1ee613f5366cbc44b504d21a0cf6715e209cd3" + "58f2dd5f3e71cc0d67d0e964168c42a084ebda746f9863a8" + "6bacffc819f1edf1b8c727ccfb3047240a57c435", + .pub_x = + "0000016bd15c8a58d366f7f2b2f298cc87b7485e9ee70d11" + "d12448b8377c0a82c7626f67aff7f97be7a3546bf417eeed" + "df75a93c130191c84108042ea2fca17fd3f80d14", + .pub_y = + "000001560502d04b74fce1743aab477a9d1eac93e5226981" + "fdb97a7478ce4ce566ff7243931284fad850b0c2bcae0ddd" + "2d97790160c1a2e77c3ed6c95ecc44b89e2637fc", + .want = + "004531b3d2c6cd12f21604c8610e6723dbf4daf80b5a459d" + "6ba5814397d1c1f7a21d7c114be964e27376aaebe3a7bc3d" + "6af7a7f8c7befb611afe487ff032921f750f", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001c35823e440a9363ab98d9fc7a7bc0c0532dc7977a7" + "9165599bf1a9cc64c00fb387b42cca365286e8430360bfad" + "3643bc31354eda50dc936c329ecdb60905c40fcb", + .peer_y = + "000000d9e7f433531e44df4f6d514201cbaabb06badd6783" + "e01111726d815531d233c5cdb722893ffbb2027259d594de" + "77438809738120c6f783934f926c3fb69b40c409", + .priv = + "000001fd90e3e416e98aa3f2b6afa7f3bf368e451ad9ca5b" + "d54b5b14aee2ed6723dde5181f5085b68169b09fbec72137" + "2ccf6b284713f9a6356b8d560a8ff78ca3737c88", + .pub_x = + "000001ebea1b10d3e3b971b7efb69fc878de11c7f472e4e4" + "d384c31b8d6288d8071517acade9b39796c7af5163bcf71a" + "eda777533f382c6cf0a4d9bbb938c85f44b78037", + .pub_y = + "0000016b0e3e19c2996b2cbd1ff64730e7ca90edca1984f9" + "b2951333535e5748baa34a99f61ff4d5f812079e0f01e877" + "89f34efdad8098015ee74a4f846dd190d16dc6e1", + .want = + "0100c8935969077bae0ba89ef0df8161d975ec5870ac811a" + "e7e65ca5394efba4f0633d41bf79ea5e5b9496bbd7aae000" + "b0594baa82ef8f244e6984ae87ae1ed124b7", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000000093057fb862f2ad2e82e581baeb3324e7b32946f2b" + "a845a9beeed87d6995f54918ec6619b9931955d5a89d4d74" + "adf1046bb362192f2ef6bd3e3d2d04dd1f87054a", + .peer_y = + "000000aa3fb2448335f694e3cda4ae0cc71b1b2f2a206fa8" + "02d7262f19983c44674fe15327acaac1fa40424c395a6556" + "cb8167312527fae5865ecffc14bbdc17da78cdcf", + .priv = + "0000009012ecfdadc85ced630afea534cdc8e9d1ab8be5f3" + "753dcf5f2b09b40eda66fc6858549bc36e6f8df55998cfa9" + "a0703aecf6c42799c245011064f530c09db98369", + .pub_x = + "000000234e32be0a907131d2d128a6477e0caceb86f02479" + "745e0fe245cb332de631c078871160482eeef584e274df7f" + "a412cea3e1e91f71ecba8781d9205d48386341ad", + .pub_y = + "000001cf86455b09b1c005cffba8d76289a3759628c874be" + "ea462f51f30bd581e3803134307dedbb771b3334ee15be2e" + "242cd79c3407d2f58935456c6941dd9b6d155a46", + .want = + "017f36af19303841d13a389d95ec0b801c7f9a679a823146" + "c75c17bc44256e9ad422a4f8b31f14647b2c7d317b933f7c" + "2946c4b8abd1d56d620fab1b5ff1a3adc71f", + }, + { + .nid = NID_secp521r1, + .peer_x = + "00000083192ed0b1cb31f75817794937f66ad91cf74552cd" + "510cedb9fd641310422af5d09f221cad249ee814d16dd7ac" + "84ded9eacdc28340fcfc9c0c06abe30a2fc28cd8", + .peer_y = + "0000002212ed868c9ba0fb2c91e2c39ba93996a3e4ebf45f" + "2852d0928c48930e875cc7b428d0e7f3f4d503e5d60c68cb" + "49b13c2480cd486bed9200caddaddfe4ff8e3562", + .priv = + "000001b5ff847f8eff20b88cfad42c06e58c3742f2f8f1fd" + "fd64b539ba48c25926926bd5e332b45649c0b184f77255e9" + "d58fe8afa1a6d968e2cb1d4637777120c765c128", + .pub_x = + "000001de3dc9263bc8c4969dc684be0eec54befd9a9f3dba" + "194d8658a789341bf0d78d84da6735227cafaf0935195169" + "1197573c8c360a11e5285712b8bbdf5ac91b977c", + .pub_y = + "000000812de58cd095ec2e5a9b247eb3ed41d8bef6aeace1" + "94a7a05b65aa5d289fbc9b1770ec84bb6be0c2c64cc37c1d" + "54a7f5d71377a9adbe20f26f6f2b544a821ea831", + .want = + "00062f9fc29ae1a68b2ee0dcf956cbd38c88ae5f645eaa54" + "6b00ebe87a7260bf724be20d34b9d02076655c933d056b21" + "e304c24ddb1dedf1dd76de611fc4a2340336", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001a89b636a93e5d2ba6c2292bf23033a84f06a3ac122" + "0ea71e806afbe097a804cc67e9baa514cfb6c12c9194be30" + "212bf7aae7fdf6d376c212f0554e656463ffab7e", + .peer_y = + "00000182efcaf70fc412d336602e014da47256a0b606f2ad" + "dcce8053bf817ac8656bb4e42f14c8cbf2a68f488ab35dcd" + "f64056271dee1f606a440ba4bd4e5a11b8b8e54f", + .priv = + "0000011a6347d4e801c91923488354cc533e7e35fddf81ff" + "0fb7f56bb0726e0c29ee5dcdc5f394ba54cf57269048aab6" + "e055895c8da24b8b0639a742314390cc04190ed6", + .pub_x = + "000000fe30267f33ba5cdefc25cbb3c9320dad9ccb1d7d37" + "6644620ca4fadee5626a3cede25ad254624def727a7048f7" + "145f76162aa98042f9b123b2076f8e8cf59b3fdf", + .pub_y = + "0000001145dc6631953b6e2945e94301d6cbb098fe4b04f7" + "ee9b09411df104dc82d7d79ec46a01ed0f2d3e7db6eb6806" + "94bdeb107c1078aec6cabd9ebee3d342fe7e54df", + .want = + "0128ab09bfec5406799e610f772ba17e892249fa8e0e7b18" + "a04b9197034b250b48294f1867fb9641518f92766066a07a" + "8b917b0e76879e1011e51ccbd9f540c54d4f", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000017200b3f16a68cbaed2bf78ba8cddfb6cffac262bba" + "00fbc25f9dc72a07ce59372904899f364c44cb264c097b64" + "7d4412bee3e519892d534d9129f8a28f7500fee7", + .peer_y = + "000000baba8d672a4f4a3b63de48b96f56e18df5d68f7d70" + "d5109833f43770d6732e06b39ad60d93e5b43db8789f1ec0" + "aba47286a39ea584235acea757dbf13d53b58364", + .priv = + "00000022b6d2a22d71dfaa811d2d9f9f31fbed27f2e1f3d2" + "39538ddf3e4cc8c39a330266db25b7bc0a9704f17bde7f35" + "92bf5f1f2d4b56013aacc3d8d1bc02f00d3146cc", + .pub_x = + "000000ba38cfbf9fd2518a3f61d43549e7a6a6d28b2be57f" + "fd3e0faceb636b34ed17e044a9f249dae8fc132e937e2d93" + "49cd2ed77bb1049ceb692a2ec5b17ad61502a64c", + .pub_y = + "0000001ec91d3058573fa6c0564a02a1a010160c313bc7c7" + "3510dc983e5461682b5be00dbce7e2c682ad73f29ca822cd" + "c111f68fabe33a7b384a648342c3cdb9f050bcdb", + .want = + "0101e462e9d9159968f6440e956f11dcf2227ae4aea81667" + "122b6af9239a291eb5d6cf5a4087f358525fcacfa46bb2db" + "01a75af1ba519b2d31da33eda87a9d565748", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000004efd5dbd2f979e3831ce98f82355d6ca14a5757842" + "875882990ab85ab9b7352dd6b9b2f4ea9a1e95c3880d65d1" + "f3602f9ca653dc346fac858658d75626f4d4fb08", + .peer_y = + "00000061cf15dbdaa7f31589c98400373da284506d70c89f" + "074ed262a9e28140796b7236c2eef99016085e71552ff488" + "c72b7339fefb7915c38459cb20ab85aec4e45052", + .priv = + "0000005bacfff268acf6553c3c583b464ea36a1d35e2b257" + "a5d49eb3419d5a095087c2fb4d15cf5bf5af816d0f3ff758" + "6490ccd3ddc1a98b39ce63749c6288ce0dbdac7d", + .pub_x = + "00000036e488da7581472a9d8e628c58d6ad727311b7e6a3" + "f6ae33a8544f34b09280249020be7196916fafd90e2ec54b" + "66b5468d2361b99b56fa00d7ac37abb8c6f16653", + .pub_y = + "0000011edb9fb8adb6a43f4f5f5fdc1421c9fe04fc8ba46c" + "9b66334e3af927c8befb4307104f299acec4e30f812d9345" + "c9720d19869dbfffd4ca3e7d2713eb5fc3f42615", + .want = + "0141d6a4b719ab67eaf04a92c0a41e2dda78f4354fb90bdc" + "35202cc7699b9b04d49616f82255debf7bbec045ae58f982" + "a66905fcfae69d689785e38c868eb4a27e7b", + }, + { + .nid = NID_secp521r1, + .peer_x = + "00000129891de0cf3cf82e8c2cf1bf90bb296fe00ab08ca4" + "5bb7892e0e227a504fdd05d2381a4448b68adff9c4153c87" + "eacb78330d8bd52515f9f9a0b58e85f446bb4e10", + .peer_y = + "0000009edd679696d3d1d0ef327f200383253f6413683d9e" + "4fcc87bb35f112c2f110098d15e5701d7ceee416291ff5fe" + "d85e687f727388b9afe26a4f6feed560b218e6bb", + .priv = + "0000008e2c93c5423876223a637cad367c8589da69a2d0fc" + "68612f31923ae50219df2452e7cc92615b67f17b57ffd2f5" + "2b19154bb40d7715336420fde2e89fee244f59dc", + .pub_x = + "000000fa3b35118d6c422570f724a26f90b2833b19239174" + "cea081c53133f64db60d6940ea1261299c04c1f4587cdb0c" + "4c39616479c1bb0c146799a118032dcf98f899c0", + .pub_y = + "00000069f040229006151fa32b51f679c8816f7c17506b40" + "3809dc77cd58a2aec430d94d13b6c916de99f355aa45fcfb" + "c6853d686c71be496a067d24bfaea4818fc51f75", + .want = + "00345e26e0abb1aac12b75f3a9cf41efe1c336396dffa4a0" + "67a4c2cfeb878c68b2b045faa4e5b4e6fa4678f5b603c351" + "903b14bf9a6a70c439257199a640890b61d1", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001a3c20240e59f5b7a3e17c275d2314ba1741210ad58" + "b71036f8c83cc1f6b0f409dfdd9113e94b67ec39c3291426" + "c23ffcc447054670d2908ff8fe67dc2306034c5c", + .peer_y = + "000001d2825bfd3af8b1e13205780c137fe938f84fde4018" + "8e61ea02cead81badfdb425c29f7d7fb0324debadc10bbb9" + "3de68f62c35069268283f5265865db57a79f7bf7", + .priv = + "00000004d49d39d40d8111bf16d28c5936554326b197353e" + "ebbcf47545393bc8d3aaf98f14f5be7074bfb38e6cc97b98" + "9754074daddb3045f4e4ce745669fdb3ec0d5fa8", + .pub_x = + "0000012ec226d050ce07c79b3df4d0f0891f9f7adf462e8c" + "98dbc1a2a14f5e53a3f5ad894433587cc429a8be9ea1d84f" + "a33b1803690dae04da7218d30026157fc995cf52", + .pub_y = + "0000004837dfbf3426f57b5c793269130abb9a38f6185322" + "11931154db4eeb9aede88e57290f842ea0f2ea9a5f74c620" + "3a3920fe4e305f6118f676b154e1d75b9cb5eb88", + .want = + "006fe9de6fb8e672e7fd150fdc5e617fabb0d43906354ccf" + "d224757c7276f7a1010091b17ed072074f8d10a5ec971eb3" + "5a5cb7076603b7bc38d432cbc059f80f9488", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000007e2d138f2832e345ae8ff65957e40e5ec7163f016b" + "df6d24a2243daa631d878a4a16783990c722382130f9e51f" + "0c1bd6ff5ac96780e48b68f5dec95f42e6144bb5", + .peer_y = + "000000b0de5c896791f52886b0f09913e26e78dd0b69798f" + "c4df6d95e3ca708ecbcbcce1c1895f5561bbabaae372e9e6" + "7e6e1a3be60e19b470cdf673ec1fc393d3426e20", + .priv = + "0000011a5d1cc79cd2bf73ea106f0e60a5ace220813b53e2" + "7b739864334a07c03367efda7a4619fa6eef3a9746492283" + "b3c445610a023a9cc49bf4591140384fca5c8bb5", + .pub_x = + "000000eb07c7332eedb7d3036059d35f7d2288d4377d5f42" + "337ad3964079fb120ccd4c8bd384b585621055217023acd9" + "a94fcb3b965bfb394675e788ade41a1de73e620c", + .pub_y = + "000000491a835de2e6e7deb7e090f4a11f2c460c0b1f3d5e" + "94ee8d751014dc720784fd3b54500c86ebaef18429f09e8e" + "876d5d1538968a030d7715dde99f0d8f06e29d59", + .want = + "01e4e759ecedce1013baf73e6fcc0b92451d03bdd50489b7" + "8871c333114990c9ba6a9b2fc7b1a2d9a1794c1b60d9279a" + "f6f146f0bbfb0683140403bfa4ccdb524a29", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000000118c36022209b1af8ebad1a12b566fc48744576e11" + "99fe80de1cdf851cdf03e5b9091a8f7e079e83b7f827259b" + "691d0c22ee29d6bdf73ec7bbfd746f2cd97a357d", + .peer_y = + "000000da5ff4904548a342e2e7ba6a1f4ee5f840411a96cf" + "63e6fe622f22c13e614e0a847c11a1ab3f1d12cc850c32e0" + "95614ca8f7e2721477b486e9ff40372977c3f65c", + .priv = + "0000010c908caf1be74c616b625fc8c1f514446a6aec83b5" + "937141d6afbb0a8c7666a7746fa1f7a6664a2123e8cdf6cd" + "8bf836c56d3c0ebdcc980e43a186f938f3a78ae7", + .pub_x = + "00000031890f4c7abec3f723362285d77d2636f876817db3" + "bbc88b01e773597b969ff6f013ea470c854ab4a7739004eb" + "8cbea69b82ddf36acadd406871798ecb2ac3aa7f", + .pub_y = + "000000d8b429ae3250266b9643c0c765a60dc10155bc2531" + "cf8627296f4978b6640a9e600e19d0037d58503fa8079954" + "6a814d7478a550aa90e5ebeb052527faaeae5d08", + .want = + "0163c9191d651039a5fe985a0eea1eba018a40ab1937fcd2" + "b61220820ee8f2302e9799f6edfc3f5174f369d672d377ea" + "8954a8d0c8b851e81a56fda95212a6578f0e", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001780edff1ca1c03cfbe593edc6c049bcb2860294a92" + "c355489d9afb2e702075ade1c953895a456230a0cde905de" + "4a3f38573dbfcccd67ad6e7e93f0b5581e926a5d", + .peer_y = + "000000a5481962c9162962e7f0ebdec936935d0eaa813e82" + "26d40d7f6119bfd940602380c86721e61db1830f51e139f2" + "10000bcec0d8edd39e54d73a9a129f95cd5fa979", + .priv = + "000001b37d6b7288de671360425d3e5ac1ccb21815079d8d" + "73431e9b74a6f0e7ae004a357575b11ad66642ce8b775593" + "eba9d98bf25c75ef0b4d3a2098bbc641f59a2b77", + .pub_x = + "000000189a5ee34de7e35aefeaeef9220c18071b4c29a4c3" + "bd9d954458bd3e82a7a34da34cff5579b8101c065b1f2f52" + "7cf4581501e28ef5671873e65267733d003520af", + .pub_y = + "000001eb4bc50a7b4d4599d7e3fa773ddb9eb252c9b34228" + "72e544bdf75c7bf60f5166ddc11eb08fa7c30822dabaee37" + "3ab468eb2d922e484e2a527fff2ebb804b7d9a37", + .want = + "015d613e267a36342e0d125cdad643d80d97ed0600afb9e6" + "b9545c9e64a98cc6da7c5aaa3a8da0bdd9dd3b97e9788218" + "a80abafc106ef065c8f1c4e1119ef58d298b", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000016dacffa183e5303083a334f765de724ec5ec940202" + "6d4797884a9828a0d321a8cfac74ab737fe20a7d6befcfc7" + "3b6a35c1c7b01d373e31abc192d48a4241a35803", + .peer_y = + "0000011e5327cac22d305e7156e559176e19bee7e4f2f59e" + "86f1a9d0b6603b6a7df1069bde6387feb71587b8ffce5b26" + "6e1bae86de29378a34e5c74b6724c4d40a719923", + .priv = + "000000f2661ac762f60c5fff23be5d969ccd4ec6f98e4e72" + "618d12bdcdb9b4102162333788c0bae59f91cdfc172c7a16" + "81ee44d96ab2135a6e5f3415ebbcd55165b1afb0", + .pub_x = + "000000a8e25a6902d687b4787cdc94c364ac7cecc5c49548" + "3ed363dc0aa95ee2bd739c4c4d46b17006c728b076350d7d" + "7e54c6822f52f47162a25109aaaba690cab696ec", + .pub_y = + "00000168d2f08fe19e4dc9ee7a195b03c9f7fe6676f9f520" + "b6270557504e72ca4394a2c6918625e15ac0c51b8f95cd56" + "0123653fb8e8ee6db961e2c4c62cc54e92e2a2a9", + .want = + "014d6082a3b5ced1ab8ca265a8106f302146c4acb8c30bb1" + "4a4c991e3c82a9731288bdb91e0e85bda313912d06384fc4" + "4f2153fb13506fa9cf43c9aab5750988c943", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000000a091421d3703e3b341e9f1e7d58f8cf7bdbd1798d0" + "01967b801d1cec27e605c580b2387c1cb464f55ce7ac8033" + "4102ab03cfb86d88af76c9f4129c01bedd3bbfc4", + .peer_y = + "0000008c9c577a8e6fc446815e9d40baa66025f15dae285f" + "19eb668ee60ae9c98e7ecdbf2b2a68e22928059f67db1880" + "07161d3ecf397e0883f0c4eb7eaf7827a62205cc", + .priv = + "000000f430ca1261f09681a9282e9e970a9234227b1d5e58" + "d558c3cc6eff44d1bdf53de16ad5ee2b18b92d62fc795861" + "16b0efc15f79340fb7eaf5ce6c44341dcf8dde27", + .pub_x = + "0000006c1d9b5eca87de1fb871a0a32f807c725adccde9b3" + "967453a71347d608f0c030cd09e338cdecbf4a02015bc8a6" + "e8d3e2595fe773ffc2fc4e4a55d0b1a2cc00323b", + .pub_y = + "000001141b2109e7f4981c952aa818a2b9f6f5c41feccdb7" + "a7a45b9b4b672937771b008cae5f934dfe3fed10d383ab1f" + "38769c92ce88d9be5414817ecb073a31ab368ccb", + .want = + "0020c00747cb8d492fd497e0fec54644bf027d418ab68638" + "1f109712a99cabe328b9743d2225836f9ad66e5d7fed1de2" + "47e0da92f60d5b31f9e47672e57f710598f4", + }, + { + .nid = NID_secp521r1, + .peer_x = + "0000004f38816681771289ce0cb83a5e29a1ab06fc91f786" + "994b23708ff08a08a0f675b809ae99e9f9967eb1a49f1960" + "57d69e50d6dedb4dd2d9a81c02bdcc8f7f518460", + .peer_y = + "0000009efb244c8b91087de1eed766500f0e81530752d469" + "256ef79f6b965d8a2232a0c2dbc4e8e1d09214bab38485be" + "6e357c4200d073b52f04e4a16fc6f5247187aecb", + .priv = + "0000005dc33aeda03c2eb233014ee468dff753b72f73b009" + "91043ea353828ae69d4cd0fadeda7bb278b535d7c57406ff" + "2e6e473a5a4ff98e90f90d6dadd25100e8d85666", + .pub_x = + "000000c825ba307373cec8dd2498eef82e21fd9862168dbf" + "eb83593980ca9f82875333899fe94f137daf1c4189eb5029" + "37c3a367ea7951ed8b0f3377fcdf2922021d46a5", + .pub_y = + "0000016b8a2540d5e65493888bc337249e67c0a68774f3e8" + "d81e3b4574a0125165f0bd58b8af9de74b35832539f95c3c" + "d9f1b759408560aa6851ae3ac7555347b0d3b13b", + .want = + "00c2bfafcd7fbd3e2fd1c750fdea61e70bd4787a7e68468c" + "574ee99ebc47eedef064e8944a73bcb7913dbab5d93dca66" + "0d216c553622362794f7a2acc71022bdb16f", + }, + { + .nid = NID_secp521r1, + .peer_x = + "000001a32099b02c0bd85371f60b0dd20890e6c7af048c81" + "79890fda308b359dbbc2b7a832bb8c6526c4af99a7ea3f0b" + "3cb96ae1eb7684132795c478ad6f962e4a6f446d", + .peer_y = + "0000017627357b39e9d7632a1370b3e93c1afb5c851b910e" + "b4ead0c9d387df67cde85003e0e427552f1cd09059aad026" + "2e235cce5fba8cedc4fdc1463da76dcd4b6d1a46", + .priv = + "000000df14b1f1432a7b0fb053965fd8643afee26b2451ec" + "b6a8a53a655d5fbe16e4c64ce8647225eb11e7fdcb236274" + "71dffc5c2523bd2ae89957cba3a57a23933e5a78", + .pub_x = + "0000004e8583bbbb2ecd93f0714c332dff5ab3bc6396e62f" + "3c560229664329baa5138c3bb1c36428abd4e23d17fcb7a2" + "cfcc224b2e734c8941f6f121722d7b6b94154576", + .pub_y = + "000001cf0874f204b0363f020864672fadbf87c8811eb147" + "758b254b74b14fae742159f0f671a018212bbf25b8519e12" + "6d4cad778cfff50d288fd39ceb0cac635b175ec0", + .want = + "01aaf24e5d47e4080c18c55ea35581cd8da30f1a07956504" + "5d2008d51b12d0abb4411cda7a0785b15d149ed301a36970" + "62f42da237aa7f07e0af3fd00eb1800d9c41", + }, +}; + +#define N_ECC_CDH_TESTS (sizeof(ecc_cdh_tests) / sizeof(ecc_cdh_tests[0])) + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +static int +run_ecc_cdh_test(const struct ecc_cdh_test *test) +{ + static int last_nid; + static size_t count; + EC_KEY *key = NULL; + const EC_GROUP *group; + EC_POINT *peer_pub = NULL; + BN_CTX *ctx = NULL; + BIGNUM *peer_x, *peer_y, *priv, *pub_x, *pub_y, *shared; + uint8_t *out, *want; + int out_len; + int failed = 1; + + if (test->nid != last_nid) { + last_nid = test->nid; + count = 0; + } + + if ((ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + BN_CTX_start(ctx); + + if ((peer_x = BN_CTX_get(ctx)) == NULL) + errx(1, "peer_x = BN_CTX_get()"); + if ((peer_y = BN_CTX_get(ctx)) == NULL) + errx(1, "peer_y = BN_CTX_get()"); + if ((priv = BN_CTX_get(ctx)) == NULL) + errx(1, "priv = BN_CTX_get()"); + if ((pub_x = BN_CTX_get(ctx)) == NULL) + errx(1, "pub_x = BN_CTX_get()"); + if ((pub_y = BN_CTX_get(ctx)) == NULL) + errx(1, "pub_y = BN_CTX_get()"); + if ((shared = BN_CTX_get(ctx)) == NULL) + errx(1, "want = BN_CTX_get()"); + + if ((key = EC_KEY_new_by_curve_name(test->nid)) == NULL) + errx(1, "EC_KEY_new_by_curve_name(%d)", test->nid); + + if (!BN_hex2bn(&peer_x, test->peer_x)) + errx(1, "peer_x = BN_hex2bn()"); + if (!BN_hex2bn(&peer_y, test->peer_y)) + errx(1, "peer_y = BN_hex2bn()"); + + if ((group = EC_KEY_get0_group(key)) == NULL) + errx(1, "EC_KEY_get0_group"); + + if ((peer_pub = EC_POINT_new(group)) == NULL) + errx(1, "EC_POINT_new"); + + if (!EC_POINT_set_affine_coordinates(group, peer_pub, peer_x, peer_y, ctx)) + errx(1, "EC_POINT_set_affine_coordinates"); + + if (!BN_hex2bn(&priv, test->priv)) + errx(1, "priv = BN_hex2bn()"); + if (!BN_hex2bn(&pub_x, test->pub_x)) + errx(1, "pub_x = BN_hex2bn()"); + if (!BN_hex2bn(&pub_y, test->pub_y)) + errx(1, "pub_y = BN_hex2bn()"); + + if (!EC_KEY_set_private_key(key, priv)) + errx(1, "EC_KEY_set_private_key"); + if (!EC_KEY_set_public_key_affine_coordinates(key, pub_x, pub_y)) + errx(1, "EC_KEY_set_public_key_affine_coordinates"); + + EC_KEY_set_flags(key, EC_FLAG_COFACTOR_ECDH); + + out_len = ECDH_size(key); + if ((out = calloc(1, out_len)) == NULL) + errx(1, NULL); + + if (ECDH_compute_key(out, out_len, peer_pub, key, NULL) != out_len) + errx(1, "ECDH_compute_key"); + + if (!BN_hex2bn(&shared, test->want)) + errx(1, "shared = BN_hex2bn()"); + + if ((want = calloc(1, out_len)) == NULL) + errx(1, NULL); + + if (BN_bn2binpad(shared, want, out_len) != out_len) + errx(1, "BN_bn2binpad"); + + if (memcmp(out, want, out_len) != 0) { + fprintf(stderr, "%s test %zu failed:\nwant:\n", + OBJ_nid2sn(test->nid), count); + hexdump(want, out_len); + fprintf(stderr, "got:\n"); + hexdump(out, out_len); + goto failed; + } + + failed = 0; + + failed: + count++; + + EC_KEY_free(key); + EC_POINT_free(peer_pub); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + freezero(out, out_len); + freezero(want, out_len); + + return failed; +} + +int +main(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_ECC_CDH_TESTS; i++) + failed |= run_ecc_cdh_test(&ecc_cdh_tests[i]); + + return failed; +} diff --git a/Libraries/libressl/tests/ecdhtest.c b/Libraries/libressl/tests/ecdhtest.c new file mode 100644 index 000000000..7d7bbf546 --- /dev/null +++ b/Libraries/libressl/tests/ecdhtest.c @@ -0,0 +1,418 @@ +/* $OpenBSD: ecdhtest.c,v 1.20 2023/07/16 07:34:07 tb Exp $ */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stdout, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stdout, "\n"); +} + +static void * +KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) +{ +#ifdef OPENSSL_NO_SHA + return NULL; +#else + if (*outlen < SHA_DIGEST_LENGTH) + return NULL; + *outlen = SHA_DIGEST_LENGTH; + return SHA1(in, inlen, out); +#endif +} + +static int +ecdh_keygen_test(int nid) +{ + EC_KEY *keya = NULL, *keyb = NULL; + const EC_POINT *puba, *pubb; + unsigned char *abuf = NULL, *bbuf = NULL; + int len = SHA_DIGEST_LENGTH; + int failed = 1; + + if ((keya = EC_KEY_new_by_curve_name(nid)) == NULL) + goto err; + if (!EC_KEY_generate_key(keya)) + goto err; + if ((puba = EC_KEY_get0_public_key(keya)) == NULL) + goto err; + + if ((keyb = EC_KEY_new_by_curve_name(nid)) == NULL) + goto err; + if (!EC_KEY_generate_key(keyb)) + goto err; + if ((pubb = EC_KEY_get0_public_key(keyb)) == NULL) + goto err; + + if ((abuf = calloc(1, len)) == NULL) + goto err; + if ((bbuf = calloc(1, len)) == NULL) + goto err; + + if (ECDH_compute_key(abuf, len, pubb, keya, KDF1_SHA1) != len) + goto err; + if (ECDH_compute_key(bbuf, len, puba, keyb, KDF1_SHA1) != len) + goto err; + + if (memcmp(abuf, bbuf, len) != 0) { + printf("key generation with %s failed\n", OBJ_nid2sn(nid)); + + EC_KEY_print_fp(stdout, keya, 1); + printf(" shared secret:\n"); + hexdump(abuf, len); + + EC_KEY_print_fp(stdout, keyb, 1); + printf(" shared secret:\n"); + hexdump(bbuf, len); + + fprintf(stderr, "Error in ECDH routines\n"); + + goto err; + } + + failed = 0; + + err: + ERR_print_errors_fp(stderr); + + EC_KEY_free(keya); + EC_KEY_free(keyb); + freezero(abuf, len); + freezero(bbuf, len); + + return failed; +} + +static const struct ecdh_kat_test { + const int nid; + const char *keya; + const char *keyb; + const char *want; +} ecdh_kat_tests[] = { + /* Keys and shared secrets from RFC 5114 */ + { + .nid = NID_X9_62_prime192v1, + .keya = "323fa3169d8e9c6593f59476bc142000ab5be0e249c43426", + .keyb = "631f95bb4a67632c9c476eee9ab695ab240a0499307fcf62", + .want = "ad420182633f8526bfe954acda376f05e5ff4f837f54febe", + }, + { + .nid = NID_secp224r1, + .keya = "b558eb6c288da707bbb4f8fbae2ab9e9cb62e3bc5c7573e2" + "2e26d37f", + .keyb = "ac3b1add3d9770e6f6a708ee9f3b8e0ab3b480e9f27f85c8" + "8b5e6d18", + .want = "52272f50f46f4edc9151569092f46df2d96ecc3b6dc1714a" + "4ea949fa", + }, + { + .nid = NID_X9_62_prime256v1, + .keya = "814264145f2f56f2e96a8e337a1284993faf432a5abce59e" + "867b7291d507a3af", + .keyb = "2ce1788ec197e096db95a200cc0ab26a19ce6bccad562b8e" + "ee1b593761cf7f41", + .want = "dd0f5396219d1ea393310412d19a08f1f5811e9dc8ec8eea" + "7f80d21c820c2788", + }, + { + .nid = NID_secp384r1, + .keya = "d27335ea71664af244dd14e9fd1260715dfd8a7965571c48" + "d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1", + .keyb = "52d1791fdb4b70f89c0f00d456c2f7023b6125262c36a7df" + "1f80231121cce3d39be52e00c194a4132c4a6c768bcd94d2", + .want = "5ea1fc4af7256d2055981b110575e0a8cae53160137d904c" + "59d926eb1b8456e427aa8a4540884c37de159a58028abc0e", + }, + { + .nid = NID_secp521r1, + .keya = "0113f82da825735e3d97276683b2b74277bad27335ea7166" + "4af2430cc4f33459b9669ee78b3ffb9b8683015d344dcbfe" + "f6fb9af4c6c470be254516cd3c1a1fb47362", + .keyb = "00cee3480d8645a17d249f2776d28bae616952d1791fdb4b" + "70f7c3378732aa1b22928448bcd1dc2496d435b01048066e" + "be4f72903c361b1a9dc1193dc2c9d0891b96", + .want = "00cdea89621cfa46b132f9e4cfe2261cde2d4368eb565663" + "4c7cc98c7a00cde54ed1866a0dd3e6126c9d2f845daff82c" + "eb1da08f5d87521bb0ebeca77911169c20cc", + }, + /* Keys and shared secrets from RFC 5903 */ + { + .nid = NID_X9_62_prime256v1, + .keya = "c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049" + "c62a9c57862d1433", + .keyb = "c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0" + "b283ab46476bee53", + .want = "d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03" + "812464d04b9442de", + }, + { + .nid = NID_secp384r1, + .keya = "099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f16" + "0647b67414dce655e35b538041e649ee3faef896783ab194", + .keyb = "41cb0779b4bdb85d47846725fbec3c9430fab46cc8dc5060" + "855cc9bda0aa2942e0308312916b8ed2960e4bd55a7448fc", + .want = "11187331c279962d93d604243fd592cb9d0a926f422e4718" + "7521287e7156c5c4d603135569b9e9d09cf5d4a270f59746", + }, + { + .nid = NID_secp521r1, + .keya = "0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5" + "393dce47608172a095aa85a30fe1c2952c6771d937ba9777" + "f5957b2639bab072462f68c27a57382d" + "4a52", + .keyb = "0145ba99a847af43793fdd0e872e7cdfa16be30fdc780f97" + "bccc3f078380201e9c677d600b343757a3bdbf2a3163e4c2" + "f869cca7458aa4a4effc311f5cb151685eb9", + .want = "01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f9" + "7894e5e6b2d79b04d1427e73ca4baa240a34786859810c06" + "b3c715a3a8cc3151f2bee417996d19f3ddea", + }, + /* Keys and shared secrets from RFC 7027 */ + { + .nid = NID_brainpoolP256r1, + .keya = "81db1ee100150ff2ea338d708271be38300cb54241d79950" + "f77b063039804f1d", + .keyb = "55e40bc41e37e3e2ad25c3c6654511ffa8474a91a0032087" + "593852d3e7d76bd3", + .want = "89afc39d41d3b327814b80940b042590f96556ec91e6ae79" + "39bce31f3a18bf2b", + }, + { + .nid = NID_brainpoolP384r1, + .keya = "1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d" + "57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042", + .keyb = "032640bc6003c59260f7250c3db58ce647f98e1260acce4a" + "cda3dd869f74e01f8ba5e0324309db6a9831497abac96670", + .want = "0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc" + "51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42", + }, + { + .nid = NID_brainpoolP512r1, + .keya = "16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a" + "56850a38bd87bd59b09e80279609ff333eb9d4c061231fb2" + "6f92eeb04982a5f1d1764cad57665422", + .keyb = "230e18e1bcc88a362fa54e4ea3902009292f7f8033624fd4" + "71b5d8ace49d12cfabbc19963dab8e2f1eba00bffb29e4d7" + "2d13f2224562f405cb80503666b25429", + .want = "a7927098655f1f9976fa50a9d566865dc530331846381c87" + "256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d" + "24f11a9b5c0bef679fe1454b21c4cd1f", + }, +}; + +#define N_KATS (sizeof(ecdh_kat_tests) / sizeof(ecdh_kat_tests[0])) + +/* Given private value and NID, create EC_KEY structure */ + +static EC_KEY * +mk_eckey(int nid, const char *priv_str) +{ + EC_KEY *key = NULL; + BIGNUM *priv = NULL; + EC_POINT *pub = NULL; + const EC_GROUP *group; + EC_KEY *ret = NULL; + + if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) + goto err; + if (!BN_hex2bn(&priv, priv_str)) + goto err; + if (!EC_KEY_set_private_key(key, priv)) + goto err; + if ((group = EC_KEY_get0_group(key)) == NULL) + goto err; + if ((pub = EC_POINT_new(group)) == NULL) + goto err; + if (!EC_POINT_mul(group, pub, priv, NULL, NULL, NULL)) + goto err; + if (!EC_KEY_set_public_key(key, pub)) + goto err; + + ret = key; + key = NULL; + + err: + EC_KEY_free(key); + BN_free(priv); + EC_POINT_free(pub); + + return ret; +} + +/* + * Known answer test: compute shared secret and check it matches expected value. + */ +static int +ecdh_kat(const struct ecdh_kat_test *kat) +{ + EC_KEY *keya = NULL, *keyb = NULL; + const EC_POINT *puba, *pubb; + BIGNUM *z = NULL; + unsigned char *want = NULL, *got = NULL; + int len = 0; + int failed = 1; + + if ((keya = mk_eckey(kat->nid, kat->keya)) == NULL) + goto err; + if ((puba = EC_KEY_get0_public_key(keya)) == NULL) + goto err; + if ((keyb = mk_eckey(kat->nid, kat->keyb)) == NULL) + goto err; + if ((pubb = EC_KEY_get0_public_key(keyb)) == NULL) + goto err; + + if ((len = ECDH_size(keya)) != ECDH_size(keyb)) + goto err; + + if ((want = calloc(1, len)) == NULL) + goto err; + if ((got = calloc(1, len)) == NULL) + goto err; + + if (!BN_hex2bn(&z, kat->want)) + goto err; + if (BN_num_bytes(z) > len) + goto err; + if (BN_bn2binpad(z, want, len) != len) + goto err; + + if (ECDH_compute_key(got, len, pubb, keya, NULL) != len) + goto err; + if (memcmp(got, want, len) != 0) + goto err; + + memset(got, 0, len); + + if (ECDH_compute_key(got, len, puba, keyb, NULL) != len) + goto err; + if (memcmp(got, want, len) != 0) + goto err; + + failed = 0; + + err: + if (failed) { + printf("shared secret with %s failed", OBJ_nid2sn(kat->nid)); + + fprintf(stderr, "Error in ECDH routines\n"); + ERR_print_errors_fp(stderr); + } + + EC_KEY_free(keya); + EC_KEY_free(keyb); + BN_free(z); + freezero(want, len); + freezero(got, len); + + return failed; +} + +int +main(void) +{ + EC_builtin_curve *curves = NULL; + size_t i, n_curves; + int failed = 0; + + if ((n_curves = EC_get_builtin_curves(NULL, 0)) == 0) + errx(1, "EC_get_builtin_curves failed"); + if ((curves = calloc(n_curves, sizeof(*curves))) == NULL) + errx(1, NULL); + if (EC_get_builtin_curves(curves, n_curves) != n_curves) + errx(1, "EC_get_builtin_curves failed"); + + for (i = 0; i < n_curves; i++) + failed |= ecdh_keygen_test(curves[i].nid); + + for (i = 0; i < N_KATS; i++) + failed |= ecdh_kat(&ecdh_kat_tests[i]); + + free(curves); + ERR_print_errors_fp(stderr); + + return failed; +} diff --git a/Libraries/libressl/tests/ecdsatest.c b/Libraries/libressl/tests/ecdsatest.c new file mode 100644 index 000000000..b0b9bd006 --- /dev/null +++ b/Libraries/libressl/tests/ecdsatest.c @@ -0,0 +1,348 @@ +/* $OpenBSD: ecdsatest.c,v 1.17 2023/05/04 13:50:14 tb Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include + +int test_builtin(void); + +int +test_builtin(void) +{ + unsigned char digest[20], wrong_digest[20]; + EC_builtin_curve *curves = NULL; + size_t num_curves = 0, n = 0; + EC_KEY *eckey = NULL, *wrong_eckey = NULL; + EC_GROUP *group; + ECDSA_SIG *ecdsa_sig = NULL; + BIGNUM *r = NULL, *s = NULL; + unsigned char *signature = NULL; + const unsigned char *sig_ptr; + unsigned char *sig_ptr2; + unsigned char *raw_buf = NULL; + unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; + int nid; + int failed = 1; + + /* fill digest values with some random data */ + arc4random_buf(digest, 20); + arc4random_buf(wrong_digest, 20); + + /* create and verify a ecdsa signature with every available curve */ + printf("\ntesting ECDSA_sign() and ECDSA_verify() " + "with some internal curves:\n"); + + /* get a list of all internal curves */ + num_curves = EC_get_builtin_curves(NULL, 0); + + curves = reallocarray(NULL, sizeof(EC_builtin_curve), num_curves); + if (curves == NULL) { + printf("reallocarray error\n"); + goto err; + } + + if (!EC_get_builtin_curves(curves, num_curves)) { + printf("unable to get internal curves\n"); + goto err; + } + + /* now create and verify a signature for every curve */ + for (n = 0; n < num_curves; n++) { + unsigned char dirt, offset; + + nid = curves[n].nid; + if (nid == NID_ipsec4) + continue; + + if ((eckey = EC_KEY_new()) == NULL) + goto err; + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) + goto err; + if (EC_KEY_set_group(eckey, group) == 0) + goto err; + degree = EC_GROUP_get_degree(group); + EC_GROUP_free(group); + if (degree < 160) { + /* drop the curve */ + EC_KEY_free(eckey); + eckey = NULL; + continue; + } + printf("%s: ", OBJ_nid2sn(nid)); + + if (!EC_KEY_generate_key(eckey)) { + goto err; + } + + /* Exercise ECParameters_dup() and let ASAN test for leaks. */ + if ((wrong_eckey = ECParameters_dup(eckey)) == NULL) + goto err; + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) + goto err; + if (EC_KEY_set_group(wrong_eckey, group) == 0) + goto err; + EC_GROUP_free(group); + if (!EC_KEY_generate_key(wrong_eckey)) + goto err; + + printf("."); + fflush(stdout); + + if (!EC_KEY_check_key(eckey)) + goto err; + + printf("."); + fflush(stdout); + + if ((sig_len = ECDSA_size(eckey)) == 0) + goto err; + if ((signature = malloc(sig_len)) == NULL) + goto err; + if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) + goto err; + + printf("."); + fflush(stdout); + + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) + goto err; + + printf("."); + fflush(stdout); + + /* verify signature with the wrong key */ + if (ECDSA_verify(0, digest, 20, signature, sig_len, + wrong_eckey) == 1) + goto err; + + printf("."); + fflush(stdout); + + if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, + eckey) == 1) + goto err; + + printf("."); + fflush(stdout); + + if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, + eckey) == 1) + goto err; + + printf("."); + fflush(stdout); + + /* + * Modify a single byte of the signature: to ensure we don't + * garble the ASN1 structure, we read the raw signature and + * modify a byte in one of the bignums directly. + */ + sig_ptr = signature; + if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, + sig_len)) == NULL) + goto err; + + /* Store the two BIGNUMs in raw_buf. */ + r_len = BN_num_bytes(ECDSA_SIG_get0_r(ecdsa_sig)); + s_len = BN_num_bytes(ECDSA_SIG_get0_s(ecdsa_sig)); + bn_len = (degree + 7) / 8; + if ((r_len > bn_len) || (s_len > bn_len)) + goto err; + + buf_len = 2 * bn_len; + if ((raw_buf = calloc(1, buf_len)) == NULL) + goto err; + BN_bn2bin(ECDSA_SIG_get0_r(ecdsa_sig), + raw_buf + bn_len - r_len); + BN_bn2bin(ECDSA_SIG_get0_s(ecdsa_sig), + raw_buf + buf_len - s_len); + + /* Modify a single byte in the buffer. */ + offset = raw_buf[10] % buf_len; + dirt = raw_buf[11] ? raw_buf[11] : 1; + raw_buf[offset] ^= dirt; + /* Now read the BIGNUMs back in from raw_buf. */ + if ((r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL || + (s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL) + goto err; + if (!ECDSA_SIG_set0(ecdsa_sig, r, s)) + goto err; + r = NULL; + s = NULL; + + if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL)) <= 0) + goto err; + free(signature); + if ((signature = calloc(1, sig_len)) == NULL) + goto err; + + sig_ptr2 = signature; + if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2)) <= 0) + goto err; + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) + goto err; + + /* Sanity check: undo the modification and verify signature. */ + raw_buf[offset] ^= dirt; + if ((r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL || + (s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL) + goto err; + if (!ECDSA_SIG_set0(ecdsa_sig, r, s)) + goto err; + r = NULL; + s = NULL; + + if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL)) <= 0) + goto err; + free(signature); + if ((signature = calloc(1, sig_len)) == NULL) + goto err; + + sig_ptr2 = signature; + if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2)) <= 0) + goto err; + if (ECDSA_verify(0, digest, 20, signature, sig_len, + eckey) != 1) + goto err; + + printf("."); + fflush(stdout); + + printf(" ok\n"); + + ERR_clear_error(); + free(signature); + signature = NULL; + EC_KEY_free(eckey); + eckey = NULL; + EC_KEY_free(wrong_eckey); + wrong_eckey = NULL; + ECDSA_SIG_free(ecdsa_sig); + ecdsa_sig = NULL; + free(raw_buf); + raw_buf = NULL; + } + + failed = 0; + + err: + if (failed) + printf(" failed\n"); + + BN_free(r); + BN_free(s); + EC_KEY_free(eckey); + EC_KEY_free(wrong_eckey); + ECDSA_SIG_free(ecdsa_sig); + free(signature); + free(raw_buf); + free(curves); + + return failed; +} + +int +main(void) +{ + int failed = 1; + + /* the tests */ + if (test_builtin()) + goto err; + + printf("\nECDSA test passed\n"); + failed = 0; + + err: + if (failed) { + printf("\nECDSA test failed\n"); + ERR_print_errors_fp(stdout); + } + + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + + return failed; +} diff --git a/Libraries/libressl/tests/ectest.c b/Libraries/libressl/tests/ectest.c new file mode 100644 index 000000000..f0b1028f4 --- /dev/null +++ b/Libraries/libressl/tests/ectest.c @@ -0,0 +1,781 @@ +/* $OpenBSD: ectest.c,v 1.21 2023/07/26 22:46:06 tb Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include +#include +#include + +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include +#include +#include +#include + +#define ABORT do { \ + fflush(stdout); \ + fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ + ERR_print_errors_fp(stderr); \ + exit(1); \ +} while (0) + +#define TIMING_BASE_PT 0 +#define TIMING_RAND_PT 1 +#define TIMING_SIMUL 2 + +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); + +/* test multiplication with group order, long and negative scalars */ +static void +group_order_tests(EC_GROUP *group) +{ + BIGNUM *n1, *n2, *order; + EC_POINT *P = EC_POINT_new(group); + EC_POINT *Q = EC_POINT_new(group); + BN_CTX *ctx; + + if ((ctx = BN_CTX_new()) == NULL) + ABORT; + + if ((n1 = BN_new()) == NULL) + ABORT; + if ((n2 = BN_new()) == NULL) + ABORT; + if ((order = BN_new()) == NULL) + ABORT; + fprintf(stdout, "verify group order ..."); + fflush(stdout); + if (!EC_GROUP_get_order(group, order, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + fprintf(stdout, "."); + fflush(stdout); + if (!EC_GROUP_precompute_mult(group, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + fprintf(stdout, " ok\n"); + fprintf(stdout, "long/negative scalar tests ... "); + /* XXX - switch back to BN_one() after next bump. */ + if (!BN_set_word(n1, 1)) + ABORT; + /* n1 = 1 - order */ + if (!BN_sub(n1, n1, order)) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + /* n2 = 1 + order */ + if (!BN_add(n2, order, BN_value_one())) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + /* n2 = (1 - order) * (1 + order) */ + if (!BN_mul(n2, n1, n2, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + fprintf(stdout, "ok\n"); + EC_POINT_free(P); + EC_POINT_free(Q); + BN_free(n1); + BN_free(n2); + BN_free(order); + BN_CTX_free(ctx); +} + +static void +prime_field_tests(void) +{ + BN_CTX *ctx = NULL; + BIGNUM *p, *a, *b; + EC_GROUP *group; + EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL; + EC_POINT *P, *Q, *R; + BIGNUM *x, *y, *z; + unsigned char buf[100]; + size_t i, len; + int k; + + ctx = BN_CTX_new(); + if (!ctx) + ABORT; + + p = BN_new(); + a = BN_new(); + b = BN_new(); + if (!p || !a || !b) + ABORT; + + if (!BN_hex2bn(&p, "17")) + ABORT; + if (!BN_hex2bn(&a, "1")) + ABORT; + if (!BN_hex2bn(&b, "1")) + ABORT; + + group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp + * so that the library gets to choose the EC_METHOD */ + if (!group) + ABORT; + + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + { + EC_GROUP *tmp; + tmp = EC_GROUP_new(EC_GROUP_method_of(group)); + if (!tmp) + ABORT; + if (!EC_GROUP_copy(tmp, group)) + ABORT; + EC_GROUP_free(group); + group = tmp; + } + + if (!EC_GROUP_get_curve(group, p, a, b, ctx)) + ABORT; + + fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x"); + BN_print_fp(stdout, p); + fprintf(stdout, ")\n a = 0x"); + BN_print_fp(stdout, a); + fprintf(stdout, "\n b = 0x"); + BN_print_fp(stdout, b); + fprintf(stdout, "\n"); + + P = EC_POINT_new(group); + Q = EC_POINT_new(group); + R = EC_POINT_new(group); + if (!P || !Q || !R) + ABORT; + + if (!EC_POINT_set_to_infinity(group, P)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + buf[0] = 0; + if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) + ABORT; + + if (!EC_POINT_add(group, P, P, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + x = BN_new(); + y = BN_new(); + z = BN_new(); + if (!x || !y || !z) + ABORT; + + if (!BN_hex2bn(&x, "D")) + ABORT; + if (!EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { + if (!EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)) + ABORT; + fprintf(stderr, "Point is not on curve: x = 0x"); + BN_print_fp(stderr, x); + fprintf(stderr, ", y = 0x"); + BN_print_fp(stderr, y); + fprintf(stderr, "\n"); + ABORT; + } + + fprintf(stdout, "A cyclic subgroup:\n"); + k = 100; + do { + if (k-- == 0) + ABORT; + + if (EC_POINT_is_at_infinity(group, P)) + fprintf(stdout, " point at infinity\n"); + else { + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + + fprintf(stdout, " x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, ", y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + } + + if (!EC_POINT_copy(R, P)) + ABORT; + if (!EC_POINT_add(group, P, P, Q, ctx)) + ABORT; + } while (!EC_POINT_is_at_infinity(group, P)); + + if (!EC_POINT_add(group, P, Q, R, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "Generator as octet string, compressed form:\n "); + for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); + + len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); + for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); + + len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); + for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); + + if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) + ABORT; + fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, ", Y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, ", Z = 0x"); + BN_print_fp(stdout, z); + fprintf(stdout, "\n"); + + if (!EC_POINT_invert(group, P, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, R, ctx)) + ABORT; + + + /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000) + * -- not a NIST curve, but commonly used */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) + ABORT; + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) + ABORT; + if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) + ABORT; + if (!EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 160) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_160, group)) + ABORT; + + + /* Curve P-192 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) + ABORT; + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) + ABORT; + if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 192) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_192, group)) + ABORT; + + + /* Curve P-224 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) + ABORT; + if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) + ABORT; + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) + ABORT; + if (!EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 224) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_224, group)) + ABORT; + + + /* Curve P-256 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) + ABORT; + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) + ABORT; + if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" + "84F3B9CAC2FC632551")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 256) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_256, group)) + ABORT; + + + /* Curve P-384 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT; + if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" + "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT; + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" + "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT; + if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" + "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 384) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_384, group)) + ABORT; + + + /* Curve P-521 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT; + if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" + "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" + "DF883D2C34F1EF451FD46B503F00")) ABORT; + if (!EC_GROUP_set_curve(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" + "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" + "3C1856A429BF97E7E31C2E5BD66")) ABORT; + if (!EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" + "C9B8899C47AEBB6FB71E91386409")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" + "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" + "7086A272C24088BE94769FD16650")) ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 521) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_521, group)) + ABORT; + + + /* more tests using the last curve */ + fprintf(stdout, "infinity tests ..."); + fflush(stdout); + if (!EC_POINT_copy(Q, P)) + ABORT; + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + /* P := 2P */ + if (!EC_POINT_dbl(group, P, P, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + /* Q := -P */ + if (!EC_POINT_invert(group, Q, ctx)) + ABORT; + /* R := 2P - P = P */ + if (!EC_POINT_add(group, R, P, Q, ctx)) + ABORT; + /* R := R + Q = P - P = infty */ + if (!EC_POINT_add(group, R, R, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, R)) + ABORT; + fprintf(stdout, " ok\n\n"); + + if (ctx) + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + EC_GROUP_free(group); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(R); + BN_free(x); + BN_free(y); + BN_free(z); + + if (P_160) + EC_GROUP_free(P_160); + if (P_192) + EC_GROUP_free(P_192); + if (P_224) + EC_GROUP_free(P_224); + if (P_256) + EC_GROUP_free(P_256); + if (P_384) + EC_GROUP_free(P_384); + if (P_521) + EC_GROUP_free(P_521); + +} + +static void +internal_curve_test(void) +{ + EC_builtin_curve *curves = NULL; + size_t crv_len = 0, n = 0; + int ok = 1; + + crv_len = EC_get_builtin_curves(NULL, 0); + + curves = reallocarray(NULL, sizeof(EC_builtin_curve), crv_len); + + if (curves == NULL) + return; + + if (!EC_get_builtin_curves(curves, crv_len)) { + free(curves); + return; + } + + fprintf(stdout, "testing internal curves: "); + + for (n = 0; n < crv_len; n++) { + EC_GROUP *group = NULL; + int nid = curves[n].nid; + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { + ok = 0; + fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" + " curve %s\n", OBJ_nid2sn(nid)); + /* try next curve */ + continue; + } + if (!EC_GROUP_check(group, NULL)) { + ok = 0; + fprintf(stdout, "\nEC_GROUP_check() failed with" + " curve %s\n", OBJ_nid2sn(nid)); + EC_GROUP_free(group); + /* try the next curve */ + continue; + } + fprintf(stdout, "."); + fflush(stdout); + EC_GROUP_free(group); + } + if (ok) + fprintf(stdout, " ok\n\n"); + else { + fprintf(stdout, " failed\n\n"); + ABORT; + } + free(curves); + return; +} + +int +main(int argc, char *argv[]) +{ + ERR_load_crypto_strings(); + + prime_field_tests(); + puts(""); + /* test the internal curves */ + internal_curve_test(); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks_fp(stderr); + + return 0; +} diff --git a/Libraries/libressl/tests/ed25519test.c b/Libraries/libressl/tests/ed25519test.c new file mode 100644 index 000000000..78ed85c06 --- /dev/null +++ b/Libraries/libressl/tests/ed25519test.c @@ -0,0 +1,474 @@ +/* $OpenBSD: ed25519test.c,v 1.10 2022/12/01 13:55:22 tb Exp $ */ +/* + * Copyright (c) 2019, 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +struct testvector { + const uint8_t sec_key[ED25519_PRIVATE_KEY_LENGTH]; + const uint8_t pub_key[ED25519_PUBLIC_KEY_LENGTH]; + const uint8_t signature[ED25519_SIGNATURE_LENGTH]; + const uint8_t message[1024]; + size_t message_len; +}; + +/* + * Test vectors from https://tools.ietf.org/html/rfc8032#section-7.1. + */ +static const struct testvector testvectors[] = { + { + .sec_key = { + 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, + 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, + 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19, + 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60, + }, + .pub_key = { + 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, + 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, + 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, + 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a, + }, + .message = { + 0x0, /* Windows has stupid compilers... */ + }, + .message_len = 0, + .signature = { + 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, + 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a, + 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74, + 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55, + 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac, + 0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, + 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, + 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b, + }, + }, + { + .sec_key = { + 0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda, + 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f, + 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24, + 0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb, + }, + .pub_key = { + 0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a, + 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc, + 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c, + 0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c, + }, + .message = { + 0x72, + }, + .message_len = 1, + .signature = { + 0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8, + 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40, + 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f, + 0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda, + 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e, + 0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, + 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, + 0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00, + }, + }, + { + .sec_key = { + 0xc5, 0xaa, 0x8d, 0xf4, 0x3f, 0x9f, 0x83, 0x7b, + 0xed, 0xb7, 0x44, 0x2f, 0x31, 0xdc, 0xb7, 0xb1, + 0x66, 0xd3, 0x85, 0x35, 0x07, 0x6f, 0x09, 0x4b, + 0x85, 0xce, 0x3a, 0x2e, 0x0b, 0x44, 0x58, 0xf7, + }, + .pub_key = { + 0xfc, 0x51, 0xcd, 0x8e, 0x62, 0x18, 0xa1, 0xa3, + 0x8d, 0xa4, 0x7e, 0xd0, 0x02, 0x30, 0xf0, 0x58, + 0x08, 0x16, 0xed, 0x13, 0xba, 0x33, 0x03, 0xac, + 0x5d, 0xeb, 0x91, 0x15, 0x48, 0x90, 0x80, 0x25, + }, + .message = { + 0xaf, 0x82, + }, + .message_len = 2, + .signature = { + 0x62, 0x91, 0xd6, 0x57, 0xde, 0xec, 0x24, 0x02, + 0x48, 0x27, 0xe6, 0x9c, 0x3a, 0xbe, 0x01, 0xa3, + 0x0c, 0xe5, 0x48, 0xa2, 0x84, 0x74, 0x3a, 0x44, + 0x5e, 0x36, 0x80, 0xd7, 0xdb, 0x5a, 0xc3, 0xac, + 0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90, + 0xae, 0x67, 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59, + 0x4a, 0x7c, 0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d, + 0xc0, 0x27, 0xbe, 0xce, 0xea, 0x1e, 0xc4, 0x0a, + }, + }, + { + .sec_key = { + 0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95, + 0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c, + 0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74, + 0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5, + }, + .pub_key = { + 0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34, + 0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86, + 0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5, + 0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e, + }, + .message = { + 0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43, + 0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08, + 0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91, + 0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98, + 0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12, + 0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1, + 0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f, + 0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8, + 0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96, + 0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57, + 0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37, + 0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d, + 0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0, + 0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c, + 0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b, + 0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc, + 0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3, + 0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a, + 0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e, + 0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe, + 0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82, + 0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b, + 0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6, + 0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e, + 0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8, + 0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9, + 0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28, + 0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef, + 0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68, + 0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10, + 0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1, + 0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7, + 0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04, + 0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4, + 0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53, + 0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1, + 0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44, + 0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9, + 0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5, + 0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2, + 0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59, + 0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d, + 0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce, + 0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24, + 0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6, + 0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd, + 0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf, + 0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70, + 0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59, + 0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53, + 0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78, + 0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc, + 0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9, + 0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b, + 0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2, + 0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07, + 0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75, + 0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a, + 0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d, + 0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba, + 0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31, + 0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b, + 0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22, + 0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a, + 0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78, + 0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b, + 0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88, + 0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e, + 0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9, + 0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8, + 0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4, + 0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7, + 0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55, + 0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1, + 0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01, + 0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c, + 0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb, + 0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d, + 0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c, + 0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8, + 0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb, + 0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8, + 0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14, + 0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf, + 0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9, + 0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27, + 0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b, + 0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08, + 0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a, + 0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7, + 0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67, + 0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49, + 0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f, + 0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57, + 0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a, + 0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4, + 0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5, + 0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1, + 0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d, + 0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3, + 0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e, + 0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09, + 0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79, + 0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e, + 0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4, + 0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2, + 0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66, + 0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f, + 0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98, + 0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41, + 0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c, + 0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5, + 0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3, + 0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61, + 0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9, + 0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1, + 0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45, + 0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34, + 0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd, + 0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d, + 0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85, + 0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e, + 0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47, + 0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c, + 0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef, + 0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca, + 0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08, + 0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0, + }, + .message_len = 1023, + .signature = { + 0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2, + 0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a, + 0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb, + 0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50, + 0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45, + 0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b, + 0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6, + 0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03, + }, + }, + { + .sec_key = { + 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, + 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e, + 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, + 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42, + }, + .pub_key = { + 0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b, + 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34, + 0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64, + 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf, + }, + .message = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f, + }, + .message_len = 64, + .signature = { + 0xdc, 0x2a, 0x44, 0x59, 0xe7, 0x36, 0x96, 0x33, + 0xa5, 0x2b, 0x1b, 0xf2, 0x77, 0x83, 0x9a, 0x00, + 0x20, 0x10, 0x09, 0xa3, 0xef, 0xbf, 0x3e, 0xcb, + 0x69, 0xbe, 0xa2, 0x18, 0x6c, 0x26, 0xb5, 0x89, + 0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec, + 0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30, + 0x3d, 0xca, 0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a, + 0xd9, 0xbe, 0xf1, 0x17, 0x73, 0x31, 0xa7, 0x04, + }, + }, +}; + +const size_t num_testvectors = sizeof(testvectors) / sizeof(testvectors[0]); + +static int +test_ED25519_verify(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < num_testvectors; i++) { + const struct testvector *tc = &testvectors[i]; + + if (!ED25519_verify(tc->message, tc->message_len, tc->signature, + tc->pub_key)) { + warnx("failed verification in test case %zu", i); + failed = 1; + } + } + + return failed; +} + +static int +test_ED25519_sign(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < num_testvectors; i++) { + const struct testvector *tc = &testvectors[i]; + uint8_t signature[64]; + + if (!ED25519_sign(signature, tc->message, tc->message_len, + tc->pub_key, tc->sec_key)) { + warnx("failed signature in test case %zu", i); + failed = 1; + } + + if (memcmp(tc->signature, signature, sizeof signature) != 0) { + warnx("signature mismatch in test case %zu", i); + failed = 1; + } + } + + return failed; +} + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +static void +dump_info(const uint8_t *message, size_t message_len, const uint8_t *public_key, + const uint8_t *private_key, const uint8_t *signature) +{ + + fprintf(stderr, "message:\n"); + hexdump(message, message_len); + + fprintf(stderr, "public key:\n"); + hexdump(public_key, ED25519_PUBLIC_KEY_LENGTH); + fprintf(stderr, "private key:\n"); + hexdump(private_key, ED25519_PRIVATE_KEY_LENGTH); + + if (signature != NULL) { + fprintf(stderr, "signature:\n"); + hexdump(signature, ED25519_SIGNATURE_LENGTH); + } +} + +/* + * Little-endian representation of the order of edwards25519, + * see https://www.rfc-editor.org/rfc/rfc7748#section-4.1 + */ +static const uint8_t order[] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +}; + +/* + * Modify signature by adding the group order to the upper half of the + * signature. This is caught by the check added in curve25519.c r1.14. + */ +static void +modify_signature(uint8_t *signature) +{ + uint16_t sum; + uint8_t *upper_half = &signature[32]; + uint16_t carry = 0; + size_t i; + + for (i = 0; i < sizeof(order); i++) { + sum = carry + order[i] + upper_half[i]; + carry = (sum > 0xff); + upper_half[i] = sum & 0xff; + } + + /* carry == 0 since 0 <= upper_half < order and 2 * order < 2^256. */ +} + +static int +test_ED25519_signature_malleability(void) +{ + uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]; + uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]; + uint8_t message[32]; + uint8_t signature[ED25519_SIGNATURE_LENGTH]; + int failed = 1; + + ED25519_keypair(public_key, private_key); + arc4random_buf(message, sizeof(message)); + + if (!ED25519_sign(signature, message, sizeof(message), + public_key, private_key)) { + fprintf(stderr, "Failed to sign random message\n"); + dump_info(message, sizeof(message), public_key, private_key, + NULL); + goto err; + } + + if (!ED25519_verify(message, sizeof(message), signature, public_key)) { + fprintf(stderr, "Failed to verify random message\n"); + dump_info(message, sizeof(message), public_key, private_key, + signature); + goto err; + } + + modify_signature(signature); + + if (ED25519_verify(message, sizeof(message), signature, public_key)) { + fprintf(stderr, "Verified with modified signature\n"); + dump_info(message, sizeof(message), public_key, private_key, + signature); + goto err; + } + + failed = 0; + + err: + return failed; +} + +int +main(int argc, char *argv[]) +{ + int failed = 0; + + failed |= test_ED25519_verify(); + failed |= test_ED25519_sign(); + failed |= test_ED25519_signature_malleability(); + + return failed; +} diff --git a/Libraries/libressl/tests/empty.c b/Libraries/libressl/tests/empty.c new file mode 100644 index 000000000..e69de29bb diff --git a/Libraries/libressl/tests/enginetest.c b/Libraries/libressl/tests/enginetest.c new file mode 100644 index 000000000..9afae3919 --- /dev/null +++ b/Libraries/libressl/tests/enginetest.c @@ -0,0 +1,253 @@ +/* $OpenBSD: enginetest.c,v 1.10 2023/06/19 18:52:29 tb Exp $ */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#include + +static void display_engine_list(void) +{ + ENGINE *h; + int loop; + + h = ENGINE_get_first(); + loop = 0; + printf("listing available engine types\n"); + while (h) { + printf("engine %d, id = \"%s\", name = \"%s\"\n", + loop++, ENGINE_get_id(h), ENGINE_get_name(h)); + h = ENGINE_get_next(h); + } + + printf("end of list\n"); + /* + * ENGINE_get_first() increases the struct_ref counter, so we must call + * ENGINE_free() to decrease it again + */ + ENGINE_free(h); +} + +int main(int argc, char *argv[]) +{ + ENGINE *block[512]; + char *id, *name; + ENGINE *ptr; + int loop; + int to_return = 1; + ENGINE *new_h1 = NULL; + ENGINE *new_h2 = NULL; + ENGINE *new_h3 = NULL; + ENGINE *new_h4 = NULL; + + ERR_load_crypto_strings(); + + memset(block, 0, 512 * sizeof(ENGINE *)); + if (((new_h1 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h1, "test_id0") || + !ENGINE_set_name(new_h1, "First test item") || + ((new_h2 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h2, "test_id1") || + !ENGINE_set_name(new_h2, "Second test item") || + ((new_h3 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h3, "test_id2") || + !ENGINE_set_name(new_h3, "Third test item") || + ((new_h4 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h4, "test_id3") || + !ENGINE_set_name(new_h4, "Fourth test item")) { + printf("Couldn't set up test ENGINE structures\n"); + goto end; + } + + printf("\nenginetest beginning\n\n"); + display_engine_list(); + if (!ENGINE_add(new_h1)) { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + ptr = ENGINE_get_first(); + if (!ENGINE_remove(ptr)) { + printf("Remove failed!\n"); + goto end; + } + ENGINE_free(ptr); + display_engine_list(); + if (!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + if (!ENGINE_remove(new_h2)) { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if (!ENGINE_add(new_h4)) { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + if (ENGINE_add(new_h3)) { + printf("Add *should* have failed but didn't!\n"); + goto end; + } else + printf("Add that should fail did.\n"); + ERR_clear_error(); + if (ENGINE_remove(new_h2)) { + printf("Remove *should* have failed but didn't!\n"); + goto end; + } else + printf("Remove that should fail did.\n"); + ERR_clear_error(); + if (!ENGINE_remove(new_h3)) { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if (!ENGINE_remove(new_h4)) { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + /* + * Depending on whether there's any hardware support compiled + * in, this remove may be destined to fail. + */ + ptr = ENGINE_get_first(); + if (ptr) + if (!ENGINE_remove(ptr)) + printf("Remove failed!i - probably no hardware " + "support present.\n"); + ENGINE_free(ptr); + display_engine_list(); + + if (!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) { + printf("Couldn't add and remove to an empty list!\n"); + goto end; + } else + printf("Successfully added and removed to an empty list!\n"); + + printf("About to beef up the engine-type list\n"); + for (loop = 0; loop < 512; loop++) { + if (asprintf(&id, "id%d", loop) == -1) + goto end; + if (asprintf(&name, "Fake engine type %d", loop) == -1) + goto end; + + if (((block[loop] = ENGINE_new()) == NULL) || + !id || !ENGINE_set_id(block[loop], id) || + !name || !ENGINE_set_name(block[loop], name)) { + printf("Couldn't create block of ENGINE structures.\n"); + goto end; + } + } + + for (loop = 0; loop < 512; loop++) { + if (!ENGINE_add(block[loop])) { + printf("\nAdding stopped at %d, (%s,%s)\n", + loop, ENGINE_get_id(block[loop]), + ENGINE_get_name(block[loop])); + break; + } + printf("."); + fflush(stdout); + } + printf("\nAbout to empty the engine-type list\n"); + while ((ptr = ENGINE_get_first()) != NULL) { + if (!ENGINE_remove(ptr)) { + printf("\nRemove failed!\n"); + goto end; + } + ENGINE_free(ptr); + printf("."); fflush(stdout); + } + for (loop = 0; loop < 512; loop++) { + free((void *)ENGINE_get_id(block[loop])); + free((void *)ENGINE_get_name(block[loop])); + } + printf("\nTests completed happily\n"); + to_return = 0; +end: + if (to_return) + ERR_print_errors_fp(stderr); + ENGINE_free(new_h1); + ENGINE_free(new_h2); + ENGINE_free(new_h3); + ENGINE_free(new_h4); + for (loop = 0; loop < 512; loop++) + ENGINE_free(block[loop]); + ENGINE_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks_fp(stderr); + return to_return; +} +#else +int +main(void) +{ + printf("ENGINE support is disabled\n"); + return 0; +} +#endif diff --git a/Libraries/libressl/tests/evp_ecx_test.c b/Libraries/libressl/tests/evp_ecx_test.c new file mode 100644 index 000000000..b28378b9b --- /dev/null +++ b/Libraries/libressl/tests/evp_ecx_test.c @@ -0,0 +1,831 @@ +/* $OpenBSD: evp_ecx_test.c,v 1.5 2023/03/02 20:04:42 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +#include "curve25519_internal.h" + +static const uint8_t ed25519_priv_key_1[] = + "-----BEGIN PRIVATE KEY-----\n" + "MC4CAQAwBQYDK2VwBCIEIIkDg89yB70IpUXsAZieCcCDE2ig9nin9JJWpDQoCup8\n" + "-----END PRIVATE KEY-----\n"; + +const uint8_t ed25519_raw_priv_key_1[] = { + 0x89, 0x03, 0x83, 0xcf, 0x72, 0x07, 0xbd, 0x08, + 0xa5, 0x45, 0xec, 0x01, 0x98, 0x9e, 0x09, 0xc0, + 0x83, 0x13, 0x68, 0xa0, 0xf6, 0x78, 0xa7, 0xf4, + 0x92, 0x56, 0xa4, 0x34, 0x28, 0x0a, 0xea, 0x7c, +}; + +static const uint8_t ed25519_pub_key_1[] = + "-----BEGIN PUBLIC KEY-----\n" + "MCowBQYDK2VwAyEA1vxPpbnoC7G8vFmRjYVXUU2aln3hUZEgfW1atlTHF/o=\n" + "-----END PUBLIC KEY-----\n"; + +const uint8_t ed25519_raw_pub_key_1[] = { + 0xd6, 0xfc, 0x4f, 0xa5, 0xb9, 0xe8, 0x0b, 0xb1, + 0xbc, 0xbc, 0x59, 0x91, 0x8d, 0x85, 0x57, 0x51, + 0x4d, 0x9a, 0x96, 0x7d, 0xe1, 0x51, 0x91, 0x20, + 0x7d, 0x6d, 0x5a, 0xb6, 0x54, 0xc7, 0x17, 0xfa, +}; + +static const uint8_t message_1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +static const uint8_t signature_1[] = { + 0x1c, 0xba, 0x71, 0x5a, 0xbc, 0x7f, 0x3b, 0x6b, + 0xc1, 0x61, 0x04, 0x02, 0xb6, 0x37, 0x9e, 0xe1, + 0xa6, 0x7c, 0xfe, 0xcd, 0xdd, 0x68, 0x59, 0xb5, + 0xc8, 0x09, 0xa5, 0x36, 0x66, 0xfb, 0xad, 0xc5, + 0x68, 0x31, 0xd1, 0x7a, 0x48, 0x44, 0xaa, 0xa9, + 0x9c, 0xf1, 0x1a, 0xbb, 0xd5, 0x49, 0xd5, 0xe8, + 0x63, 0xe2, 0x94, 0x77, 0x16, 0x1a, 0x52, 0xfa, + 0x33, 0x6b, 0xf3, 0x57, 0x93, 0xd4, 0xc1, 0x07, +}; + +static const uint8_t x25519_priv_key_1[] = + "-----BEGIN PRIVATE KEY-----\n" + "MC4CAQAwBQYDK2VuBCIEICi6rzFFJb02mi6sopELeshEi2vr68ul4bzEHPOz+K1o\n" + "-----END PRIVATE KEY-----\n"; + +const uint8_t x25519_raw_priv_key_1[] = { + 0x28, 0xba, 0xaf, 0x31, 0x45, 0x25, 0xbd, 0x36, + 0x9a, 0x2e, 0xac, 0xa2, 0x91, 0x0b, 0x7a, 0xc8, + 0x44, 0x8b, 0x6b, 0xeb, 0xeb, 0xcb, 0xa5, 0xe1, + 0xbc, 0xc4, 0x1c, 0xf3, 0xb3, 0xf8, 0xad, 0x68, +}; + +static const uint8_t x25519_pub_key_1[] = + "-----BEGIN PUBLIC KEY-----\n" + "MCowBQYDK2VuAyEAu4WHXnAQL2YfonJhuoEO9PM2WwXjveApPmCXSiDnf1M=\n" + "-----END PUBLIC KEY-----\n"; + +static const uint8_t x25519_raw_pub_key_1[] = { + 0xbb, 0x85, 0x87, 0x5e, 0x70, 0x10, 0x2f, 0x66, + 0x1f, 0xa2, 0x72, 0x61, 0xba, 0x81, 0x0e, 0xf4, + 0xf3, 0x36, 0x5b, 0x05, 0xe3, 0xbd, 0xe0, 0x29, + 0x3e, 0x60, 0x97, 0x4a, 0x20, 0xe7, 0x7f, 0x53, +}; + +static const uint8_t x25519_priv_key_2[] = + "-----BEGIN PRIVATE KEY-----\n" + "MC4CAQAwBQYDK2VuBCIEIAg9Jbp/Ma0TO4r179WGGiv+VnGxGNRh4VNrHUij7Ql/\n" + "-----END PRIVATE KEY-----\n"; + +static const uint8_t x25519_raw_priv_key_2[] = { + 0x08, 0x3d, 0x25, 0xba, 0x7f, 0x31, 0xad, 0x13, + 0x3b, 0x8a, 0xf5, 0xef, 0xd5, 0x86, 0x1a, 0x2b, + 0xfe, 0x56, 0x71, 0xb1, 0x18, 0xd4, 0x61, 0xe1, + 0x53, 0x6b, 0x1d, 0x48, 0xa3, 0xed, 0x09, 0x7f, +}; + +static const uint8_t x25519_pub_key_2[] = + "-----BEGIN PUBLIC KEY-----\n" + "MCowBQYDK2VuAyEABvksGQRgsUXEK5CaniVZ59pPvDoABgBSdAM+EF0Q9Cw=\n" + "-----END PUBLIC KEY-----\n"; + +static const uint8_t x25519_raw_pub_key_2[] = { + 0x06, 0xf9, 0x2c, 0x19, 0x04, 0x60, 0xb1, 0x45, + 0xc4, 0x2b, 0x90, 0x9a, 0x9e, 0x25, 0x59, 0xe7, + 0xda, 0x4f, 0xbc, 0x3a, 0x00, 0x06, 0x00, 0x52, + 0x74, 0x03, 0x3e, 0x10, 0x5d, 0x10, 0xf4, 0x2c, +}; + +static const uint8_t shared_key_1[] = { + 0xa2, 0x61, 0xf5, 0x91, 0x2e, 0x82, 0xbc, 0x98, + 0x6c, 0x85, 0xb6, 0x51, 0x1f, 0x69, 0xdb, 0xfa, + 0x88, 0x6c, 0x4b, 0x9e, 0x3b, 0xb0, 0x71, 0xd1, + 0xf3, 0xea, 0x2a, 0xd0, 0xef, 0xf6, 0xa5, 0x5a, +}; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +ecx_ed25519_keygen_test(void) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pkey = NULL; + BIO *bio = NULL; + int failed = 1; + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to create ED25519 context\n"); + goto failure; + } + + if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { + fprintf(stderr, "FAIL: failed to init keygen for ED25519\n"); + goto failure; + } + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) { + fprintf(stderr, "FAIL: failed to generate ED25519 key\n"); + goto failure; + } + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) { + fprintf(stderr, "FAIL: failed to write ED25519 to PEM\n"); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey); + + return failed; +} + +static int +ecx_ed25519_raw_key_test(void) +{ + EVP_PKEY *pkey = NULL; + uint8_t *priv_key = NULL; + size_t priv_key_len = 0; + uint8_t *pub_key = NULL; + size_t pub_key_len = 0; + const uint8_t *pp; + BIO *bio = NULL; + int failed = 1; + + /* + * Decode private key from PEM and check raw private and raw public. + */ + + if ((bio = BIO_new_mem_buf(ed25519_priv_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read private key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &priv_key_len)) { + fprintf(stderr, "FAIL: failed to get raw private key len\n"); + goto failure; + } + if (priv_key_len != sizeof(ed25519_raw_priv_key_1)) { + fprintf(stderr, "FAIL: raw private key length differs " + "(%zu != %zu)\n", priv_key_len, + sizeof(ed25519_raw_priv_key_1)); + goto failure; + } + if ((priv_key = malloc(priv_key_len)) == NULL) + errx(1, "failed to malloc priv key"); + if (!EVP_PKEY_get_raw_private_key(pkey, priv_key, &priv_key_len)) { + fprintf(stderr, "FAIL: failed to get raw private key len\n"); + goto failure; + } + if (memcmp(priv_key, ed25519_raw_priv_key_1, priv_key_len) != 0) { + fprintf(stderr, "FAIL: get raw private key failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(priv_key, priv_key_len); + fprintf(stderr, "Want:\n"); + hexdump(ed25519_raw_priv_key_1, sizeof(ed25519_raw_priv_key_1)); + goto failure; + } + + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (pub_key_len != sizeof(ed25519_raw_pub_key_1)) { + fprintf(stderr, "FAIL: raw public key length differs " + "(%zu != %zu)\n", pub_key_len, + sizeof(ed25519_raw_pub_key_1)); + goto failure; + } + if ((pub_key = malloc(pub_key_len)) == NULL) + errx(1, "failed to malloc private key"); + if (!EVP_PKEY_get_raw_public_key(pkey, pub_key, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (memcmp(pub_key, ed25519_raw_pub_key_1, pub_key_len) != 0) { + fprintf(stderr, "FAIL: get raw public key failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(pub_key, pub_key_len); + fprintf(stderr, "Want:\n"); + hexdump(ed25519_raw_pub_key_1, sizeof(ed25519_raw_pub_key_1)); + goto failure; + } + + BIO_free(bio); + bio = NULL; + + EVP_PKEY_free(pkey); + pkey = NULL; + + freezero(priv_key, priv_key_len); + priv_key = NULL; + priv_key_len = 0; + + freezero(pub_key, pub_key_len); + pub_key = NULL; + pub_key_len = 0; + + /* + * Decode public key from PEM and check raw private and raw public. + */ + + if ((bio = BIO_new_mem_buf(ed25519_pub_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read public key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + /* + * Yet another astounding API design - we cannot tell if the private key + * is not present, or if some other failure occurred. + */ + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &priv_key_len)) { + fprintf(stderr, "FAIL: failed to get raw priv key len\n"); + goto failure; + } + if ((priv_key = malloc(priv_key_len)) == NULL) + errx(1, "failed to malloc priv key"); + if (EVP_PKEY_get_raw_private_key(pkey, priv_key, &priv_key_len)) { + fprintf(stderr, "FAIL: got raw private key, should fail\n"); + goto failure; + } + + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (pub_key_len != sizeof(ed25519_raw_pub_key_1)) { + fprintf(stderr, "FAIL: raw public key length differs " + "(%zu != %zu)\n", pub_key_len, + sizeof(ed25519_raw_pub_key_1)); + goto failure; + } + if ((pub_key = malloc(pub_key_len)) == NULL) + errx(1, "failed to malloc private key"); + if (!EVP_PKEY_get_raw_public_key(pkey, pub_key, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (memcmp(pub_key, ed25519_raw_pub_key_1, pub_key_len) != 0) { + fprintf(stderr, "FAIL: get raw public key failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(pub_key, pub_key_len); + fprintf(stderr, "Want:\n"); + hexdump(ed25519_raw_pub_key_1, sizeof(ed25519_raw_pub_key_1)); + goto failure; + } + + BIO_free(bio); + bio = NULL; + + EVP_PKEY_free(pkey); + pkey = NULL; + + /* + * Create PKEY from raw private, check PEM encoded private and public. + */ + if ((pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, + ed25519_raw_priv_key_1, sizeof(ed25519_raw_priv_key_1))) == NULL) { + fprintf(stderr, "FAIL: PKEY from raw private key failed"); + goto failure; + } + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) { + fprintf(stderr, "FAIL: failed to write ED25519 private to PEM\n"); + goto failure; + } + BIO_get_mem_data(bio, &pp); + if (strcmp(ed25519_priv_key_1, pp) != 0) { + fprintf(stderr, "FAIL: resulting private key PEM differs\n"); + goto failure; + } + + (void)BIO_reset(bio); + if (!PEM_write_bio_PUBKEY(bio, pkey)) { + fprintf(stderr, "FAIL: failed to write ED25519 public to PEM\n"); + goto failure; + } + BIO_get_mem_data(bio, &pp); + if (strcmp(ed25519_pub_key_1, pp) != 0) { + fprintf(stderr, "FAIL: resulting public key PEM differs\n"); + fprintf(stderr, "%s\n", ed25519_pub_key_1); + fprintf(stderr, "%s\n", pp); + //goto failure; + } + + EVP_PKEY_free(pkey); + pkey = NULL; + + /* + * Create PKEY from raw public, check public key PEM. + */ + if ((pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, + ed25519_raw_pub_key_1, sizeof(ed25519_raw_pub_key_1))) == NULL) { + fprintf(stderr, "FAIL: PKEY from raw public key failed"); + goto failure; + } + (void)BIO_reset(bio); + if (!PEM_write_bio_PUBKEY(bio, pkey)) { + fprintf(stderr, "FAIL: failed to write ED25519 public to PEM\n"); + goto failure; + } + BIO_get_mem_data(bio, &pp); + if (strcmp(ed25519_pub_key_1, pp) != 0) { + fprintf(stderr, "FAIL: resulting public key PEM differs\n"); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_PKEY_free(pkey); + freezero(priv_key, priv_key_len); + freezero(pub_key, pub_key_len); + + return failed; +} + +static int +ecx_ed25519_sign_test(void) +{ + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY *pkey = NULL; + uint8_t *signature = NULL; + size_t signature_len = 0; + BIO *bio = NULL; + int failed = 1; + + if ((bio = BIO_new_mem_buf(ed25519_priv_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read private key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + errx(1, "failed to create MD_CTX"); + + if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey)) { + fprintf(stderr, "FAIL: failed to init digest sign\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + if (!EVP_DigestSign(md_ctx, NULL, &signature_len, NULL, 0)) { + fprintf(stderr, "FAIL: failed to digest sign update\n"); + goto failure; + } + if ((signature = calloc(1, signature_len)) == NULL) + errx(1, "failed to allocate signature"); + if (!EVP_DigestSign(md_ctx, signature, &signature_len, message_1, + sizeof(message_1))) { + fprintf(stderr, "FAIL: failed to digest sign update\n"); + goto failure; + } + + if (signature_len != sizeof(signature_1)) { + fprintf(stderr, "FAIL: signature length differs (%zu != %zu)\n", + signature_len, sizeof(signature_1)); + goto failure; + } + + if (memcmp(signature, signature_1, signature_len) != 0) { + fprintf(stderr, "FAIL: Ed25519 sign failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(signature, signature_len); + fprintf(stderr, "Want:\n"); + hexdump(signature_1, sizeof(signature_1)); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_MD_CTX_free(md_ctx); + EVP_PKEY_free(pkey); + free(signature); + + return failed; +} + +static int +ecx_ed25519_verify_test(void) +{ + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY *pkey = NULL; + BIO *bio = NULL; + int failed = 1; + + if ((bio = BIO_new_mem_buf(ed25519_pub_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read public key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + errx(1, "failed to create MD_CTX"); + + if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey)) { + fprintf(stderr, "FAIL: failed to init digest verify\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + if (!EVP_DigestVerify(md_ctx, signature_1, sizeof(signature_1), + message_1, sizeof(message_1))) { + fprintf(stderr, "FAIL: failed to digest verify update\n"); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_MD_CTX_free(md_ctx); + EVP_PKEY_free(pkey); + + return failed; +} + +static int +ecx_x25519_keygen_test(void) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pkey = NULL; + BIO *bio = NULL; + int failed = 1; + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to create X25519 context\n"); + goto failure; + } + + if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { + fprintf(stderr, "FAIL: failed to init keygen for X25519\n"); + goto failure; + } + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) { + fprintf(stderr, "FAIL: failed to generate X25519 key\n"); + goto failure; + } + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) { + fprintf(stderr, "FAIL: failed to write X25519 to PEM\n"); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey); + + return failed; +} + +static int +ecx_x25519_derive_test(void) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pkey = NULL, *pkey_peer = NULL; + uint8_t *shared_key = NULL; + size_t shared_key_len = 0; + BIO *bio = NULL; + int failed = 1; + + if ((bio = BIO_new_mem_buf(x25519_priv_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read private key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + BIO_free(bio); + if ((bio = BIO_new_mem_buf(x25519_pub_key_2, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey_peer = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read peer public key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to create X25519 context\n"); + goto failure; + } + if (EVP_PKEY_derive_init(pkey_ctx) <= 0) { + fprintf(stderr, "FAIL: failed to init derive for X25519\n"); + goto failure; + } + if (EVP_PKEY_derive_set_peer(pkey_ctx, pkey_peer) <= 0) { + fprintf(stderr, "FAIL: failed to set peer key for X25519\n"); + goto failure; + } + if (EVP_PKEY_derive(pkey_ctx, NULL, &shared_key_len) <= 0) { + fprintf(stderr, "FAIL: failed to derive X25519 key length\n"); + goto failure; + } + if ((shared_key = malloc(shared_key_len)) == NULL) + errx(1, "failed to malloc shared key"); + if (EVP_PKEY_derive(pkey_ctx, shared_key, &shared_key_len) <= 0) { + fprintf(stderr, "FAIL: failed to derive X25519 key\n"); + goto failure; + } + + if (shared_key_len != sizeof(shared_key_1)) { + fprintf(stderr, "FAIL: shared key length differs (%zu != %zu)\n", + shared_key_len, sizeof(shared_key_1)); + goto failure; + } + + if (memcmp(shared_key, shared_key_1, shared_key_len) != 0) { + fprintf(stderr, "FAIL: X25519 derive failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(shared_key, shared_key_len); + fprintf(stderr, "Want:\n"); + hexdump(shared_key_1, sizeof(shared_key_1)); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey_peer); + EVP_PKEY_free(pkey); + freezero(shared_key, shared_key_len); + + return failed; +} + +static int +ecx_x25519_raw_key_test(void) +{ + EVP_PKEY *pkey = NULL; + uint8_t *priv_key = NULL; + size_t priv_key_len = 0; + uint8_t *pub_key = NULL; + size_t pub_key_len = 0; + const uint8_t *pp; + BIO *bio = NULL; + int failed = 1; + + /* + * Decode private key from PEM and check raw private and raw public. + */ + + if ((bio = BIO_new_mem_buf(x25519_priv_key_2, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read private key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &priv_key_len)) { + fprintf(stderr, "FAIL: failed to get raw private key len\n"); + goto failure; + } + if (priv_key_len != sizeof(x25519_raw_priv_key_2)) { + fprintf(stderr, "FAIL: raw private key length differs " + "(%zu != %zu)\n", priv_key_len, + sizeof(x25519_raw_priv_key_2)); + goto failure; + } + if ((priv_key = malloc(priv_key_len)) == NULL) + errx(1, "failed to malloc priv key"); + if (!EVP_PKEY_get_raw_private_key(pkey, priv_key, &priv_key_len)) { + fprintf(stderr, "FAIL: failed to get raw private key len\n"); + goto failure; + } + if (memcmp(priv_key, x25519_raw_priv_key_2, priv_key_len) != 0) { + fprintf(stderr, "FAIL: get raw private key failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(priv_key, priv_key_len); + fprintf(stderr, "Want:\n"); + hexdump(x25519_raw_priv_key_2, sizeof(x25519_raw_priv_key_2)); + goto failure; + } + + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (pub_key_len != sizeof(x25519_raw_pub_key_2)) { + fprintf(stderr, "FAIL: raw public key length differs " + "(%zu != %zu)\n", pub_key_len, + sizeof(x25519_raw_pub_key_2)); + goto failure; + } + if ((pub_key = malloc(pub_key_len)) == NULL) + errx(1, "failed to malloc private key"); + if (!EVP_PKEY_get_raw_public_key(pkey, pub_key, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (memcmp(pub_key, x25519_raw_pub_key_2, pub_key_len) != 0) { + fprintf(stderr, "FAIL: get raw public key failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(pub_key, pub_key_len); + fprintf(stderr, "Want:\n"); + hexdump(x25519_raw_pub_key_2, sizeof(x25519_raw_pub_key_2)); + goto failure; + } + + BIO_free(bio); + bio = NULL; + + EVP_PKEY_free(pkey); + pkey = NULL; + + freezero(priv_key, priv_key_len); + priv_key = NULL; + priv_key_len = 0; + + freezero(pub_key, pub_key_len); + pub_key = NULL; + pub_key_len = 0; + + /* + * Decode public key from PEM and check raw private and raw public. + */ + + if ((bio = BIO_new_mem_buf(x25519_pub_key_1, -1)) == NULL) + errx(1, "failed to create BIO for key"); + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to read public key\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + /* + * Yet another astounding API design - we cannot tell if the private key + * is not present, or if some other failure occurred. + */ + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &priv_key_len)) { + fprintf(stderr, "FAIL: failed to get raw priv key len\n"); + goto failure; + } + if ((priv_key = malloc(priv_key_len)) == NULL) + errx(1, "failed to malloc priv key"); + if (EVP_PKEY_get_raw_private_key(pkey, priv_key, &priv_key_len)) { + fprintf(stderr, "FAIL: got raw private key, should fail\n"); + goto failure; + } + + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (pub_key_len != sizeof(x25519_raw_pub_key_1)) { + fprintf(stderr, "FAIL: raw public key length differs " + "(%zu != %zu)\n", pub_key_len, + sizeof(x25519_raw_pub_key_1)); + goto failure; + } + if ((pub_key = malloc(pub_key_len)) == NULL) + errx(1, "failed to malloc private key"); + if (!EVP_PKEY_get_raw_public_key(pkey, pub_key, &pub_key_len)) { + fprintf(stderr, "FAIL: failed to get raw pub key len\n"); + goto failure; + } + if (memcmp(pub_key, x25519_raw_pub_key_1, pub_key_len) != 0) { + fprintf(stderr, "FAIL: get raw public key failed\n"); + fprintf(stderr, "Got:\n"); + hexdump(pub_key, pub_key_len); + fprintf(stderr, "Want:\n"); + hexdump(x25519_raw_pub_key_1, sizeof(x25519_raw_pub_key_1)); + goto failure; + } + + BIO_free(bio); + bio = NULL; + + EVP_PKEY_free(pkey); + pkey = NULL; + + /* + * Create PKEY from raw private, check PEM encoded private and public. + */ + if ((pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, + x25519_raw_priv_key_2, sizeof(x25519_raw_priv_key_2))) == NULL) { + fprintf(stderr, "FAIL: PKEY from raw private key failed"); + goto failure; + } + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) { + fprintf(stderr, "FAIL: failed to write X25519 private to PEM\n"); + goto failure; + } + BIO_get_mem_data(bio, &pp); + if (strcmp(x25519_priv_key_2, pp) != 0) { + fprintf(stderr, "FAIL: resulting private key PEM differs\n"); + goto failure; + } + + (void)BIO_reset(bio); + if (!PEM_write_bio_PUBKEY(bio, pkey)) { + fprintf(stderr, "FAIL: failed to write X25519 public to PEM\n"); + goto failure; + } + BIO_get_mem_data(bio, &pp); + if (strcmp(x25519_pub_key_2, pp) != 0) { + fprintf(stderr, "FAIL: resulting public key PEM differs\n"); + goto failure; + } + + EVP_PKEY_free(pkey); + pkey = NULL; + + /* + * Create PKEY from raw public, check public key PEM. + */ + if ((pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL, + x25519_raw_pub_key_1, sizeof(x25519_raw_pub_key_1))) == NULL) { + fprintf(stderr, "FAIL: PKEY from raw public key failed"); + goto failure; + } + (void)BIO_reset(bio); + if (!PEM_write_bio_PUBKEY(bio, pkey)) { + fprintf(stderr, "FAIL: failed to write X25519 public to PEM\n"); + goto failure; + } + BIO_get_mem_data(bio, &pp); + if (strcmp(x25519_pub_key_1, pp) != 0) { + fprintf(stderr, "FAIL: resulting public key PEM differs\n"); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EVP_PKEY_free(pkey); + freezero(priv_key, priv_key_len); + freezero(pub_key, pub_key_len); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= ecx_ed25519_raw_key_test(); + failed |= ecx_ed25519_keygen_test(); + failed |= ecx_ed25519_sign_test(); + failed |= ecx_ed25519_verify_test(); + + failed |= ecx_x25519_keygen_test(); + failed |= ecx_x25519_derive_test(); + failed |= ecx_x25519_raw_key_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/evp_pkey_check.c b/Libraries/libressl/tests/evp_pkey_check.c new file mode 100644 index 000000000..7b73316b9 --- /dev/null +++ b/Libraries/libressl/tests/evp_pkey_check.c @@ -0,0 +1,397 @@ +/* $OpenBSD: evp_pkey_check.c,v 1.4 2023/03/02 20:18:40 tb Exp $ */ +/* + * Copyright (c) 2021-2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#define EVP_TEST_RSA_BITS 2048 + +static int +evp_pkey_check_rsa(void) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + BIGNUM *rsa_d; + int ret; + int fail_soft = 0; + int failed = 1; + + /* + * Generate a run-off-the-mill RSA key. + */ + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { + fprintf(stderr, "%s: EVP_PKEY_CTX_new_id()\n", __func__); + goto err; + } + if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_keygen_init\n", __func__); + goto err; + } + if (!EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, EVP_TEST_RSA_BITS)) { + fprintf(stderr, "%s: EVP_PKEY_CTX_set_rsa_keygen_bits\n", + __func__); + goto err; + } + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_keygen\n", __func__); + goto err; + } + + /* At this point, no pkey is set on pkey_ctx, we should fail with 0. */ + if (EVP_PKEY_check(pkey_ctx) != 0) { + fprintf(stderr, "%s: EVP_PKEY_check() succeeded without pkey\n", + __func__); + ERR_print_errors_fp(stderr); + fail_soft = 1; + } + + ERR_clear_error(); + + /* + * Create a new EVP_PKEY_CTX with pkey set. + */ + + EVP_PKEY_CTX_free(pkey_ctx); + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + fprintf(stderr, "%s: EVP_PKEY_CTX_new\n", __func__); + goto err; + } + + /* The freshly generated pkey is set on pkey_ctx. We should succeed. */ + if ((ret = EVP_PKEY_check(pkey_ctx)) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_check(), generated pkey: %d\n", + __func__, ret); + ERR_print_errors_fp(stderr); + ERR_clear_error(); + fail_soft = 1; + } + + /* Public key checking for RSA is not supported. */ + if (EVP_PKEY_public_check(pkey_ctx) != -2) { + fprintf(stderr, + "%s: EVP_PKEY_public_check() supported for RSA?\n", + __func__); + goto err; + } + ERR_clear_error(); + + /* Parameter checking for RSA is not supported. */ + if (EVP_PKEY_param_check(pkey_ctx) != -2) { + fprintf(stderr, + "%s: EVP_PKEY_param_check() supported for RSA?\n", + __func__); + goto err; + } + ERR_clear_error(); + + /* + * Now modify the RSA key a bit. The check should then fail. + */ + + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { + fprintf(stderr, "%s: EVP_PKEY_get0_RSA\n", __func__); + goto err; + } + /* We're lazy and modify rsa->d directly, hence the ugly cast. */ + if ((rsa_d = (BIGNUM *)RSA_get0_d(rsa)) == NULL) { + fprintf(stderr, "%s: RSA_get0_d()\n", __func__); + goto err; + } + if (!BN_add_word(rsa_d, 2)) { + fprintf(stderr, "%s: BN_add_word\n", __func__); + goto err; + } + + /* Since (d+2) * e != 1 mod (p-1)*(q-1), we should fail */ + if (EVP_PKEY_check(pkey_ctx) == 1) { + fprintf(stderr, "%s: EVP_PKEY_check success with modified d\n", + __func__); + fail_soft = 1; + } + + if (ERR_peek_error() == 0) { + fprintf(stderr, "%s: expected some RSA errors\n", __func__); + fail_soft = 1; + } + ERR_clear_error(); + + failed = 0; + + err: + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey); + + return failed | fail_soft; +} + +static int +evp_pkey_check_ec(void) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pkey = NULL; + EC_KEY *eckey = NULL; + BIGNUM *private_key = NULL; + EC_GROUP *group; + const EC_POINT *generator; + BIGNUM *cofactor = NULL, *order = NULL; + int ret; + int fail_soft = 0; + int failed = 1; + + /* + * Generate an elliptic curve key on secp384r1 + */ + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { + fprintf(stderr, "%s: EVP_PKEY_CTX_new_id\n", __func__); + goto err; + } + if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_keygen_init\n", __func__); + goto err; + } + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkey_ctx, + NID_secp384r1) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_CTX_set_ec_paramgen_curve_nid\n", + __func__); + goto err; + } + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_keygen\n", __func__); + goto err; + } + + /* At this point, no pkey is set on pkey_ctx, we should fail with 0. */ + if (EVP_PKEY_check(pkey_ctx) != 0) { + fprintf(stderr, "%s: EVP_PKEY_check() succeeded without pkey\n", + __func__); + ERR_print_errors_fp(stderr); + fail_soft = 1; + } + + ERR_clear_error(); + + /* + * Create a new EVP_PKEY_CTX with pkey set. + */ + + EVP_PKEY_CTX_free(pkey_ctx); + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + fprintf(stderr, "%s: EVP_PKEY_CTX_new\n", __func__); + goto err; + } + + /* The freshly generated pkey is set on pkey_ctx. We should succeed. */ + if ((ret = EVP_PKEY_check(pkey_ctx)) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_check(), generated pkey: %d\n", + __func__, ret); + ERR_print_errors_fp(stderr); + ERR_clear_error(); + fail_soft = 1; + } + + /* We should also succeed the public check. */ + if ((ret = EVP_PKEY_public_check(pkey_ctx)) <= 0) { + fprintf(stderr, + "%s: EVP_PKEY_public_check(), generated pkey: %d\n", + __func__, ret); + ERR_print_errors_fp(stderr); + ERR_clear_error(); + fail_soft = 1; + } + + /* We should also succeed the parameter check. */ + if ((ret = EVP_PKEY_param_check(pkey_ctx)) <= 0) { + fprintf(stderr, + "%s: EVP_PKEY_param_check(), generated pkey: %d\n", + __func__, ret); + ERR_print_errors_fp(stderr); + ERR_clear_error(); + fail_soft = 1; + } + + /* + * Modify the private key slightly. + */ + + if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { + fprintf(stderr, "%s: EVP_PKEY_get0_EC_KEY\n", __func__); + goto err; + } + + /* We're lazy and modify the private key directly. */ + if ((private_key = (BIGNUM *)EC_KEY_get0_private_key(eckey)) == NULL) { + fprintf(stderr, "%s: EC_KEY_get0_private_key\n", __func__); + goto err; + } + + /* + * The private key is a random number in [1, order). Preserve this + * property by adding 1 if it is equal to 1 and subtracting 1 otherwise. + */ + if (BN_cmp(private_key, BN_value_one()) == 0) { + if (!BN_add_word(private_key, 1)) { + fprintf(stderr, "%s: BN_add_word\n", __func__); + goto err; + } + } else { + if (!BN_sub_word(private_key, 1)) { + fprintf(stderr, "%s: BN_sub_word\n", __func__); + goto err; + } + } + + /* Generator times private key will no longer be equal to public key. */ + if (EVP_PKEY_check(pkey_ctx) == 1) { + fprintf(stderr, "%s: EVP_PKEY_check succeeded unexpectedly\n", + __func__); + fail_soft = 1; + } + + if (ERR_peek_error() == 0) { + fprintf(stderr, "%s: expected a private key error\n", __func__); + fail_soft = 1; + } + ERR_clear_error(); + + /* EVP_PKEY_public_check checks the private key (sigh), so we fail. */ + if (EVP_PKEY_public_check(pkey_ctx) == 1) { + fprintf(stderr, + "%s: EVP_PKEY_public_check succeeded unexpectedly\n", + __func__); + fail_soft = 1; + } + + /* We should still succeed the parameter check. */ + if ((ret = EVP_PKEY_param_check(pkey_ctx)) <= 0) { + fprintf(stderr, + "%s: EVP_PKEY_param_check(), modified privkey pkey: %d\n", + __func__, ret); + ERR_print_errors_fp(stderr); + ERR_clear_error(); + fail_soft = 1; + } + + /* Now set the private key to NULL. The API will think malloc failed. */ + if (EC_KEY_set_private_key(eckey, NULL) != 0) { + fprintf(stderr, "%s: EC_KEY_set_private_key succeeded?!", + __func__); + goto err; + } + + /* + * EVP_PKEY_public_check now only checks that the public key is on the + * curve. We should succeed again. + */ + + if ((ret = EVP_PKEY_public_check(pkey_ctx)) <= 0) { + fprintf(stderr, "%s: EVP_PKEY_check(), generated pkey: %d\n", + __func__, ret); + fail_soft = 1; + } + + ERR_clear_error(); + + /* + * Now let's modify the group to trip the parameter check. + */ + + if ((group = (EC_GROUP *)EC_KEY_get0_group(eckey)) == NULL) { + fprintf(stderr, "%s: EC_KEY_get0_group() failed\n", __func__); + goto err; + } + + if ((generator = EC_GROUP_get0_generator(group)) == NULL) { + fprintf(stderr, "%s: EC_GROUP_get0_generator() failed\n", + __func__); + goto err; + } + + if ((order = BN_new()) == NULL) { + fprintf(stderr, "%s: order = BN_new() failed\n", __func__); + goto err; + } + if ((cofactor = BN_new()) == NULL) { + fprintf(stderr, "%s: cofactor = BN_new() failed\n", __func__); + goto err; + } + + if (!EC_GROUP_get_order(group, order, NULL)) { + fprintf(stderr, "%s: EC_GROUP_get_order() failed\n", __func__); + goto err; + } + if (!EC_GROUP_get_cofactor(group, cofactor, NULL)) { + fprintf(stderr, "%s: EC_GROUP_get_cofactor() failed\n", + __func__); + goto err; + } + + /* Decrement order so order * generator != (point at infinity). */ + if (!BN_sub_word(order, 1)) { + fprintf(stderr, "%s: BN_sub_word() failed\n", __func__); + goto err; + } + + /* Now set this nonsense on the group. */ + if (!EC_GROUP_set_generator(group, generator, order, cofactor)) { + fprintf(stderr, "%s: EC_GROUP_set_generator() failed\n", + __func__); + goto err; + } + + /* We should now fail the parameter check. */ + if (EVP_PKEY_param_check(pkey_ctx) == 1) { + fprintf(stderr, + "%s: EVP_PKEY_param_check(), succeeded unexpectedly\n", + __func__); + fail_soft = 1; + } + + if (ERR_peek_error() == 0) { + fprintf(stderr, "%s: expected a group order error\n", __func__); + fail_soft = 1; + } + ERR_clear_error(); + + failed = 0; + + err: + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey); + BN_free(order); + BN_free(cofactor); + + return failed | fail_soft; +} + +int +main(void) +{ + int failed = 0; + + failed |= evp_pkey_check_rsa(); + failed |= evp_pkey_check_ec(); + + return failed; +} diff --git a/Libraries/libressl/tests/evp_pkey_cleanup.c b/Libraries/libressl/tests/evp_pkey_cleanup.c new file mode 100644 index 000000000..fd922efb0 --- /dev/null +++ b/Libraries/libressl/tests/evp_pkey_cleanup.c @@ -0,0 +1,83 @@ +/* $OpenBSD: evp_pkey_cleanup.c,v 1.3 2022/12/01 13:49:12 tb Exp $ */ + +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "evp_local.h" + +struct pkey_cleanup_test { + const char *name; + int nid; + void (*free)(void); +}; + +int pkey_ids[] = { + EVP_PKEY_CMAC, + EVP_PKEY_DH, + EVP_PKEY_DSA, + EVP_PKEY_EC, + EVP_PKEY_GOSTIMIT, + EVP_PKEY_GOSTR01, + EVP_PKEY_HMAC, + EVP_PKEY_RSA, + EVP_PKEY_RSA_PSS, +}; + +static const size_t N_PKEY_IDS = sizeof(pkey_ids) / sizeof(pkey_ids[0]); + +static int +test_evp_pkey_ctx_cleanup(int nid) +{ + EVP_PKEY_CTX *pkey_ctx = NULL; + void *data; + int failed = 1; + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(nid, NULL)) == NULL) { + fprintf(stderr, "EVP_PKEY_CTX_new_id(%d, NULL) failed\n", nid); + goto err; + } + + data = EVP_PKEY_CTX_get_data(pkey_ctx); + + EVP_PKEY_CTX_set_data(pkey_ctx, NULL); + if (pkey_ctx->pmeth->cleanup != NULL) + pkey_ctx->pmeth->cleanup(pkey_ctx); + + EVP_PKEY_CTX_set_data(pkey_ctx, data); + + failed = 0; + + err: + EVP_PKEY_CTX_free(pkey_ctx); + + return failed; +} + +int +main(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_PKEY_IDS; i++) + failed |= test_evp_pkey_ctx_cleanup(pkey_ids[i]); + + return failed; +} diff --git a/Libraries/libressl/tests/evp_test.c b/Libraries/libressl/tests/evp_test.c new file mode 100644 index 000000000..eff071fa5 --- /dev/null +++ b/Libraries/libressl/tests/evp_test.c @@ -0,0 +1,419 @@ +/* $OpenBSD: evp_test.c,v 1.7 2023/09/29 06:53:05 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "evp_local.h" + +static int +evp_asn1_method_test(void) +{ + const EVP_PKEY_ASN1_METHOD *method; + int count, pkey_id, i; + int failed = 1; + + if ((count = EVP_PKEY_asn1_get_count()) < 1) { + fprintf(stderr, "FAIL: failed to get pkey asn1 method count\n"); + goto failure; + } + for (i = 0; i < count; i++) { + if ((method = EVP_PKEY_asn1_get0(i)) == NULL) { + fprintf(stderr, "FAIL: failed to get pkey %d\n", i); + goto failure; + } + } + + if ((method = EVP_PKEY_asn1_find(NULL, EVP_PKEY_RSA)) == NULL) { + fprintf(stderr, "FAIL: failed to find RSA method\n"); + goto failure; + } + if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { + fprintf(stderr, "FAIL: failed to get RSA method info\n"); + goto failure; + } + if (pkey_id != EVP_PKEY_RSA) { + fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", + pkey_id, EVP_PKEY_RSA); + goto failure; + } + + if ((method = EVP_PKEY_asn1_find(NULL, EVP_PKEY_RSA_PSS)) == NULL) { + fprintf(stderr, "FAIL: failed to find RSA-PSS method\n"); + goto failure; + } + if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { + fprintf(stderr, "FAIL: failed to get RSA-PSS method info\n"); + goto failure; + } + if (pkey_id != EVP_PKEY_RSA_PSS) { + fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", + pkey_id, EVP_PKEY_RSA_PSS); + goto failure; + } + + if ((method = EVP_PKEY_asn1_find_str(NULL, "RSA", -1)) == NULL) { + fprintf(stderr, "FAIL: failed to find RSA method by str\n"); + goto failure; + } + if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { + fprintf(stderr, "FAIL: failed to get RSA method info\n"); + goto failure; + } + if (pkey_id != EVP_PKEY_RSA) { + fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", + pkey_id, EVP_PKEY_RSA); + goto failure; + } + + if ((method = EVP_PKEY_asn1_find_str(NULL, "RSA-PSS", -1)) == NULL) { + fprintf(stderr, "FAIL: failed to find RSA-PSS method\n"); + goto failure; + } + if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) { + fprintf(stderr, "FAIL: failed to get RSA-PSS method info\n"); + goto failure; + } + if (pkey_id != EVP_PKEY_RSA_PSS) { + fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", + pkey_id, EVP_PKEY_RSA_PSS); + goto failure; + } + + failed = 0; + + failure: + + return failed; +} + +static int +evp_pkey_method_test(void) +{ + const EVP_PKEY_METHOD *method; + int pkey_id; + int failed = 1; + + if ((method = EVP_PKEY_meth_find(EVP_PKEY_RSA)) == NULL) { + fprintf(stderr, "FAIL: failed to find RSA method\n"); + goto failure; + } + EVP_PKEY_meth_get0_info(&pkey_id, NULL, method); + if (pkey_id != EVP_PKEY_RSA) { + fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", + pkey_id, EVP_PKEY_RSA); + goto failure; + } + + if ((method = EVP_PKEY_meth_find(EVP_PKEY_RSA_PSS)) == NULL) { + fprintf(stderr, "FAIL: failed to find RSA-PSS method\n"); + goto failure; + } + EVP_PKEY_meth_get0_info(&pkey_id, NULL, method); + if (pkey_id != EVP_PKEY_RSA_PSS) { + fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n", + pkey_id, EVP_PKEY_RSA_PSS); + goto failure; + } + + failed = 0; + + failure: + + return failed; +} + +static const struct evp_iv_len_test { + const EVP_CIPHER *(*cipher)(void); + int iv_len; + int setlen; + int expect; +} evp_iv_len_tests[] = { + { + .cipher = EVP_aes_128_ccm, + .iv_len = 7, + .setlen = 11, + .expect = 1, + }, + { + .cipher = EVP_aes_128_ccm, + .iv_len = 7, + .setlen = 6, + .expect = 0, + }, + { + .cipher = EVP_aes_128_ccm, + .iv_len = 7, + .setlen = 13, + .expect = 1, + }, + { + .cipher = EVP_aes_128_ccm, + .iv_len = 7, + .setlen = 14, + .expect = 0, + }, + + { + .cipher = EVP_aes_192_ccm, + .iv_len = 7, + .setlen = 11, + .expect = 1, + }, + { + .cipher = EVP_aes_192_ccm, + .iv_len = 7, + .setlen = 6, + .expect = 0, + }, + { + .cipher = EVP_aes_192_ccm, + .iv_len = 7, + .setlen = 13, + .expect = 1, + }, + { + .cipher = EVP_aes_192_ccm, + .iv_len = 7, + .setlen = 14, + .expect = 0, + }, + + { + .cipher = EVP_aes_256_ccm, + .iv_len = 7, + .setlen = 11, + .expect = 1, + }, + { + .cipher = EVP_aes_256_ccm, + .iv_len = 7, + .setlen = 6, + .expect = 0, + }, + { + .cipher = EVP_aes_256_ccm, + .iv_len = 7, + .setlen = 13, + .expect = 1, + }, + { + .cipher = EVP_aes_256_ccm, + .iv_len = 7, + .setlen = 14, + .expect = 0, + }, + + { + .cipher = EVP_aes_128_gcm, + .iv_len = 12, + .setlen = 16, + .expect = 1, + }, + { + .cipher = EVP_aes_128_gcm, + .iv_len = 12, + .setlen = 0, + .expect = 0, + }, + { + .cipher = EVP_aes_128_gcm, + .iv_len = 12, + .setlen = 1, + .expect = 1, + }, + /* XXX - GCM IV length isn't capped... */ + { + .cipher = EVP_aes_128_gcm, + .iv_len = 12, + .setlen = 1024 * 1024, + .expect = 1, + }, + + { + .cipher = EVP_aes_192_gcm, + .iv_len = 12, + .setlen = 16, + .expect = 1, + }, + { + .cipher = EVP_aes_192_gcm, + .iv_len = 12, + .setlen = 0, + .expect = 0, + }, + { + .cipher = EVP_aes_192_gcm, + .iv_len = 12, + .setlen = 1, + .expect = 1, + }, + /* XXX - GCM IV length isn't capped... */ + { + .cipher = EVP_aes_128_gcm, + .iv_len = 12, + .setlen = 1024 * 1024, + .expect = 1, + }, + + { + .cipher = EVP_aes_256_gcm, + .iv_len = 12, + .setlen = 16, + .expect = 1, + }, + { + .cipher = EVP_aes_256_gcm, + .iv_len = 12, + .setlen = 0, + .expect = 0, + }, + { + .cipher = EVP_aes_256_gcm, + .iv_len = 12, + .setlen = 1, + .expect = 1, + }, + /* XXX - GCM IV length isn't capped... */ + { + .cipher = EVP_aes_128_gcm, + .iv_len = 12, + .setlen = 1024 * 1024, + .expect = 1, + }, + + { + .cipher = EVP_aes_128_ecb, + .iv_len = 0, + .setlen = 11, + .expect = 0, + }, + + { + .cipher = EVP_chacha20_poly1305, + .iv_len = 12, + .setlen = 11, + .expect = 1, + }, + { + .cipher = EVP_chacha20_poly1305, + .iv_len = 12, + .setlen = 12, + .expect = 1, + }, + { + .cipher = EVP_chacha20_poly1305, + .iv_len = 12, + .setlen = 13, + .expect = 0, + }, + { + .cipher = EVP_chacha20_poly1305, + .iv_len = 12, + .setlen = 1, + .expect = 1, + }, + { + .cipher = EVP_chacha20_poly1305, + .iv_len = 12, + .setlen = 0, + .expect = 0, + }, +}; + +#define N_EVP_IV_LEN_TESTS \ + (sizeof(evp_iv_len_tests) / sizeof(evp_iv_len_tests[0])) + +static int +evp_pkey_iv_len_testcase(const struct evp_iv_len_test *test) +{ + const EVP_CIPHER *cipher = test->cipher(); + const char *name; + EVP_CIPHER_CTX *ctx; + int ret; + int failure = 1; + + assert(cipher != NULL); + name = OBJ_nid2ln(EVP_CIPHER_nid(cipher)); + assert(name != NULL); + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: %s: EVP_CIPHER_CTX_new()\n", name); + goto failure; + } + + if ((ret = EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL)) <= 0) { + fprintf(stderr, "FAIL: %s: EVP_EncryptInit_ex:" + " want %d, got %d\n", name, 1, ret); + goto failure; + } + if ((ret = EVP_CIPHER_CTX_iv_length(ctx)) != test->iv_len) { + fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_iv_length (before set)" + " want %d, got %d\n", name, test->iv_len, ret); + goto failure; + } + if ((ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + test->setlen, NULL)) != test->expect) { + fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_ctrl" + " want %d, got %d\n", name, test->expect, ret); + goto failure; + } + if (test->expect == 0) + goto done; + if ((ret = EVP_CIPHER_CTX_iv_length(ctx)) != test->setlen) { + fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_iv_length (after set)" + " want %d, got %d\n", name, test->setlen, ret); + goto failure; + } + + done: + failure = 0; + + failure: + EVP_CIPHER_CTX_free(ctx); + + return failure; +} + +static int +evp_pkey_iv_len_test(void) +{ + size_t i; + int failure = 0; + + for (i = 0; i < N_EVP_IV_LEN_TESTS; i++) + failure |= evp_pkey_iv_len_testcase(&evp_iv_len_tests[i]); + + return failure; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= evp_asn1_method_test(); + failed |= evp_pkey_method_test(); + failed |= evp_pkey_iv_len_test(); + + OPENSSL_cleanup(); + + return failed; +} diff --git a/Libraries/libressl/tests/evptest.c b/Libraries/libressl/tests/evptest.c new file mode 100644 index 000000000..6f677dd95 --- /dev/null +++ b/Libraries/libressl/tests/evptest.c @@ -0,0 +1,470 @@ +/* $OpenBSD: evptest.c,v 1.12 2023/03/02 20:24:51 tb Exp $ */ +/* Written by Ben Laurie, 2001 */ +/* + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include + +int verbose; + +static void +hexdump(FILE *f, const char *title, const unsigned char *s, int l) +{ + int n = 0; + + fprintf(f, "%s",title); + for (; n < l; ++n) { + if ((n % 16) == 0) + fprintf(f, "\n%04x",n); + fprintf(f, " %02x",s[n]); + } + fprintf(f, "\n"); +} + +static int +convert(unsigned char *s) +{ + unsigned char *d; + + for (d = s; *s; s += 2,++d) { + unsigned int n; + + if (!s[1]) { + fprintf(stderr, "Odd number of hex digits!\n"); + exit(4); + } + if (sscanf((char *)s, "%2x", &n) != 1) { + fprintf(stderr, "Invalid hex value at %s\n", s); + exit(4); + } + + *d = (unsigned char)n; + } + return s - d; +} + +static char * +sstrsep(char **string, const char *delim) +{ + char isdelim[256]; + char *token = *string; + + if (**string == 0) + return NULL; + + memset(isdelim, 0, 256); + isdelim[0] = 1; + + while (*delim) { + isdelim[(unsigned char)(*delim)] = 1; + delim++; + } + + while (!isdelim[(unsigned char)(**string)]) { + (*string)++; + } + + if (**string) { + **string = 0; + (*string)++; + } + + return token; +} + +static unsigned char * +ustrsep(char **p, const char *sep) +{ + return (unsigned char *)sstrsep(p, sep); +} + +static int +test1_exit(int ec) +{ + exit(ec); + return(0); /* To keep some compilers quiet */ +} + +static void +test1(const EVP_CIPHER *c, const unsigned char *key, int kn, + const unsigned char *iv, int in, const unsigned char *plaintext, int pn, + const unsigned char *ciphertext, int cn, int encdec) +{ + EVP_CIPHER_CTX *ctx; + unsigned char out[4096]; + const unsigned char *eiv; + int outl, outl2; + + if (verbose) { + printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), + (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); + hexdump(stdout, "Key",key,kn); + if (in) + hexdump(stdout, "IV",iv,in); + hexdump(stdout, "Plaintext",plaintext,pn); + hexdump(stdout, "Ciphertext",ciphertext,cn); + } + + if (kn != EVP_CIPHER_key_length(c)) { + fprintf(stderr, "Key length doesn't match, got %d expected %lu\n",kn, + (unsigned long)EVP_CIPHER_key_length(c)); + test1_exit(5); + } + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "EVP_CIPHER_CTX_new failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(12); + } + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (encdec != 0) { + eiv = iv; + if (EVP_CIPHER_mode(c) == EVP_CIPH_WRAP_MODE && in == 0) + eiv = NULL; + if (!EVP_EncryptInit_ex(ctx, c, NULL, key, eiv)) { + fprintf(stderr, "EncryptInit failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(10); + } + EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_EncryptUpdate(ctx, out, &outl, plaintext, pn)) { + fprintf(stderr, "Encrypt failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(6); + } + if (!EVP_EncryptFinal_ex(ctx, out + outl, &outl2)) { + fprintf(stderr, "EncryptFinal failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(7); + } + + if (outl + outl2 != cn) { + fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", + outl + outl2, cn); + test1_exit(8); + } + + if (memcmp(out, ciphertext, cn)) { + fprintf(stderr, "Ciphertext mismatch\n"); + hexdump(stderr, "Got",out,cn); + hexdump(stderr, "Expected",ciphertext,cn); + test1_exit(9); + } + } + + if (encdec <= 0) { + eiv = iv; + if (EVP_CIPHER_mode(c) == EVP_CIPH_WRAP_MODE && in == 0) + eiv = NULL; + if (!EVP_DecryptInit_ex(ctx, c,NULL, key, eiv)) { + fprintf(stderr, "DecryptInit failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(11); + } + EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_DecryptUpdate(ctx, out, &outl, ciphertext, cn)) { + fprintf(stderr, "Decrypt failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(6); + } + if (!EVP_DecryptFinal_ex(ctx, out + outl, &outl2)) { + fprintf(stderr, "DecryptFinal failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(7); + } + + if (outl + outl2 != pn) { + fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", + outl + outl2, pn); + test1_exit(8); + } + + if (memcmp(out, plaintext, pn)) { + fprintf(stderr, "Plaintext mismatch\n"); + hexdump(stderr, "Got",out,pn); + hexdump(stderr, "Expected",plaintext,pn); + test1_exit(9); + } + } + + EVP_CIPHER_CTX_free(ctx); + + if (verbose) + printf("\n"); +} + +static int +test_cipher(const char *cipher, const unsigned char *key, int kn, + const unsigned char *iv, int in, const unsigned char *plaintext, int pn, + const unsigned char *ciphertext, int cn, int encdec) +{ + const EVP_CIPHER *c; + + c = EVP_get_cipherbyname(cipher); + if (!c) + return 0; + + test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec); + + return 1; +} + +static int +test_digest(const char *digest, const unsigned char *plaintext, int pn, + const unsigned char *ciphertext, unsigned int cn) +{ + const EVP_MD *d; + EVP_MD_CTX *ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdn; + + d = EVP_get_digestbyname(digest); + if (!d) + return 0; + + if (verbose) { + printf("Testing digest %s\n",EVP_MD_name(d)); + hexdump(stdout, "Plaintext",plaintext,pn); + hexdump(stdout, "Digest",ciphertext,cn); + } + + if ((ctx = EVP_MD_CTX_new()) == NULL) { + fprintf(stderr, "EVP_CIPHER_CTX_new failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(104); + } + if (!EVP_DigestInit_ex(ctx, d, NULL)) { + fprintf(stderr, "DigestInit failed\n"); + ERR_print_errors_fp(stderr); + exit(100); + } + if (!EVP_DigestUpdate(ctx, plaintext, pn)) { + fprintf(stderr, "DigestUpdate failed\n"); + ERR_print_errors_fp(stderr); + exit(101); + } + if (!EVP_DigestFinal_ex(ctx, md, &mdn)) { + fprintf(stderr, "DigestFinal failed\n"); + ERR_print_errors_fp(stderr); + exit(101); + } + EVP_MD_CTX_free(ctx); + ctx = NULL; + + if (mdn != cn) { + fprintf(stderr, "Digest length mismatch, got %d expected %d\n",mdn,cn); + exit(102); + } + + if (memcmp(md, ciphertext, cn)) { + fprintf(stderr, "Digest mismatch\n"); + hexdump(stderr, "Got",md,cn); + hexdump(stderr, "Expected",ciphertext,cn); + exit(103); + } + if (verbose) + printf("\n"); + + return 1; +} + +int +main(int argc, char **argv) +{ + const char *szTestFile; + FILE *f; + + if (argc != 2 && argc != 3) { + fprintf(stderr, "%s \n",argv[0]); + exit(1); + } + if (argc == 3 && strcmp(argv[1], "-v") == 0) { + verbose = 1; + argv++; + argc--; + } + + szTestFile = argv[1]; + + f=fopen(szTestFile, "r"); + if (!f) { + perror(szTestFile); + exit(2); + } + + /* Load up the software EVP_CIPHER and EVP_MD definitions */ + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +#ifndef OPENSSL_NO_ENGINE + /* Load all compiled-in ENGINEs */ + ENGINE_load_builtin_engines(); +#endif +#if 0 + OPENSSL_config(); +#endif +#ifndef OPENSSL_NO_ENGINE + /* Register all available ENGINE implementations of ciphers and digests. + * This could perhaps be changed to "ENGINE_register_all_complete()"? */ + ENGINE_register_all_ciphers(); + ENGINE_register_all_digests(); + /* If we add command-line options, this statement should be switchable. + * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if + * they weren't already initialised. */ + /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ +#endif + + for (;;) { + char line[8 * 1024]; + char *p; + char *cipher; + unsigned char *iv, *key, *plaintext, *ciphertext; + int encdec; + int kn, in, pn, cn; + + if (!fgets((char *)line, sizeof line, f)) + break; + if (line[0] == '#' || line[0] == '\n') + continue; + p = line; + cipher=sstrsep(&p, ":"); + key=ustrsep(&p, ":"); + iv=ustrsep(&p, ":"); + plaintext=ustrsep(&p, ":"); + ciphertext=ustrsep(&p, ":"); + if (p[-1] == '\n') { + p[-1] = '\0'; + encdec = -1; + } else { + encdec = atoi(sstrsep(&p, "\n")); + } + + + kn = convert(key); + in = convert(iv); + pn = convert(plaintext); + cn = convert(ciphertext); + + if (!test_cipher(cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec) && + !test_digest(cipher, plaintext, pn, ciphertext, cn)) { +#ifdef OPENSSL_NO_AES + if (strstr(cipher, "AES") == cipher && verbose) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_DES + if (strstr(cipher, "DES") == cipher && verbose) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_RC4 + if (strstr(cipher, "RC4") == cipher && verbose) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_CAMELLIA + if (strstr(cipher, "CAMELLIA") == cipher && verbose) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_SEED + if (strstr(cipher, "SEED") == cipher) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_CHACHA + if (strstr(cipher, "ChaCha") == cipher) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_GOST + if (strstr(cipher, "md_gost") == cipher || + strstr(cipher, "streebog") == cipher) { + if (verbose) + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif + fprintf(stderr, "Can't find %s\n",cipher); + exit(3); + } + } + fclose(f); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks_fp(stderr); + + return 0; +} diff --git a/Libraries/libressl/tests/evptest.sh b/Libraries/libressl/tests/evptest.sh new file mode 100644 index 000000000..ba44d7515 --- /dev/null +++ b/Libraries/libressl/tests/evptest.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e +TEST=./evptest +if [ -e ./evptest.exe ]; then + TEST=./evptest.exe +fi +$TEST $srcdir/evptests.txt diff --git a/Libraries/libressl/tests/evptests.txt b/Libraries/libressl/tests/evptests.txt new file mode 100644 index 000000000..2a5806526 --- /dev/null +++ b/Libraries/libressl/tests/evptests.txt @@ -0,0 +1,384 @@ +# $OpenBSD: evptests.txt,v 1.9 2020/01/26 03:31:40 tb Exp $ +#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt) +#digest:::input:output + +# SHA(1) tests (from shatest.c) +SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d + +# MD5 tests (from md5test.c) +MD5::::d41d8cd98f00b204e9800998ecf8427e +MD5:::61:0cc175b9c0f1b6a831c399e269772661 +MD5:::616263:900150983cd24fb0d6963f7d28e17f72 +MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0 +MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b +MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f +MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a + +# MD5+SHA1 tests +MD5-SHA1:::616263:900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d + +# GOST R 34.11 tests +md_gost94::::981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0 +streebog512::::8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a +streebog256::::3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb +streebog512:::303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132:1b54d01a4af5b9d5cc3d86d68d285462b19abc2475222f35c085122be4ba1ffa00ad30f8767b3a82384c6574f024c311e2a481332b08ef7f41797891c1646f48 +streebog256:::303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132:9d151eefd8590b89daa6ba6cb74af9275dd051026bb149a452fd84e5e57b5500 +streebog512:::d1e520e2e5f2f0e82c20d1f2f0e8e1eee6e820e2edf3f6e82c20e2e5fef2fa20f120eceef0ff20f1f2f0e5ebe0ece820ede020f5f0e0e1f0fbff20efebfaeafb20c8e3eef0e5e2fb:1e88e62226bfca6f9994f1f2d51569e0daf8475a3b0fe61a5300eee46d961376035fe83549ada2b8620fcd7c496ce5b33f0cb9dddc2b6460143b03dabac9fb28 +streebog256:::d1e520e2e5f2f0e82c20d1f2f0e8e1eee6e820e2edf3f6e82c20e2e5fef2fa20f120eceef0ff20f1f2f0e5ebe0ece820ede020f5f0e0e1f0fbff20efebfaeafb20c8e3eef0e5e2fb:9dd2fe4e90409e5da87f53976d7405b0c0cac628fc669a741d50063c557e8f50 +streebog512:::000000000000000000000000000000000000000000000000000000000000000021ffffffffffffff7fffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000b1cd42dd2900f900:efd5fec76e1e7929baebb85007ec80c9d565ac8fa5cb4f100749091afb943499ab5d408d11091f6eb278fa7d06e18cae63370a5570f041ecd14bb36eb262c82a + +# AES 128 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1 + +# AES 192 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1 + +# AES 256 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1 + +# AES 128 ECB tests (from NIST test vectors, encrypt) + +#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1 + +# AES 128 ECB tests (from NIST test vectors, decrypt) + +#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0 + +# AES 192 ECB tests (from NIST test vectors, decrypt) + +#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0 + +# AES 256 ECB tests (from NIST test vectors, decrypt) + +#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0 + +# AES 128 CBC tests (from NIST test vectors, encrypt) + +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1 + +# AES 192 CBC tests (from NIST test vectors, encrypt) + +#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1 + +# AES 256 CBC tests (from NIST test vectors, encrypt) + +#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1 + +# AES 128 CBC tests (from NIST test vectors, decrypt) + +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0 + +# AES tests from NIST document SP800-38A +# For all ECB encrypts and decrypts, the transformed sequence is +# AES-bits-ECB:key::plaintext:ciphertext:encdec +# ECB-AES128.Encrypt and ECB-AES128.Decrypt +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97 +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688 +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4 +# ECB-AES192.Encrypt and ECB-AES192.Decrypt +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E +# ECB-AES256.Encrypt and ECB-AES256.Decrypt +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8 +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870 +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7 +# For all CBC encrypts and decrypts, the transformed sequence is +# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec +# CBC-AES128.Encrypt and CBC-AES128.Decrypt +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2 +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516 +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7 +# CBC-AES192.Encrypt and CBC-AES192.Decrypt +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8 +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0 +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD +# CBC-AES256.Encrypt and CBC-AES256.Decrypt +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6 +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461 +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B +# We don't support CFB{1,8}-AESxxx.{En,De}crypt +# For all CFB128 encrypts and decrypts, the transformed sequence is +# AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec +# CFB128-AES128.Encrypt +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1 +# CFB128-AES128.Decrypt +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0 +# CFB128-AES192.Encrypt +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1 +# CFB128-AES192.Decrypt +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0 +# CFB128-AES256.Encrypt +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1 +# CFB128-AES256.Decrypt +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0 +# For all OFB encrypts and decrypts, the transformed sequence is +# AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec +# OFB-AES128.Encrypt +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 +# OFB-AES128.Decrypt +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0 +# OFB-AES192.Encrypt +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 +# OFB-AES192.Decrypt +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 +# OFB-AES256.Encrypt +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1 +# OFB-AES256.Decrypt +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0 + +# AES Counter test vectors from RFC3686 +aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1 +aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1 +aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1 + +aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1 +aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1 +aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1 + +aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1 +aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1 +aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1 + +# AES wrap tests from RFC3394 +id-aes128-wrap:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5 +id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D +id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7 +id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF0001020304050607:031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2 +id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF0001020304050607:A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1 +id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F:28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21 +# DES ECB tests (from destest) + +DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7 +DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58 +DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B +DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533 +DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D +DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD +DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4 + +# DESX-CBC tests (from destest) +DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4 + +# DES EDE3 CBC tests (from destest) +DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675 + +# RC4 tests (from rc4test) +RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596 +RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879 +RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a +RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858 +RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf +RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61 + + +# Camellia tests from RFC3713 +# For all ECB encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec +CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43 +CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9 +CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509 + +# ECB-CAMELLIA128.Encrypt +CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1 +CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1 +CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1 + +# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96 +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636 +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A + +# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3 +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366 +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26 + +# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28 +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B + +# For all CBC encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec +# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887 +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54 +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980 + +# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08 + +# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50 +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83 +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F + +# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt +# For all CFB128 encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec +# CFB128-CAMELLIA128.Encrypt +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1 + +# CFB128-CAMELLIA128.Decrypt +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0 + +# CFB128-CAMELLIA192.Encrypt +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1 + +# CFB128-CAMELLIA192.Decrypt +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0 + +# CFB128-CAMELLIA256.Encrypt +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1 + +# CFB128-CAMELLIA256.Decrypt +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0 + +# For all OFB encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec +# OFB-CAMELLIA128.Encrypt +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1 + +# OFB-CAMELLIA128.Decrypt +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0 + +# OFB-CAMELLIA192.Encrypt +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1 + +# OFB-CAMELLIA192.Decrypt +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0 + +# OFB-CAMELLIA256.Encrypt +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1 + +# OFB-CAMELLIA256.Decrypt +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0 + +# SEED test vectors from RFC4269 +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0 +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0 +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0 +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0 +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1 +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1 +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1 +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1 + +# ChaCha test vectors +ChaCha:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586:1 +ChaCha:0000000000000000000000000000000000000000000000000000000000000000:01000000000000000000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f:1 +ChaCha:0000000000000000000000000000000000000000000000000000000000000001:01000000000000000000000000000002:416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f:a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85ad00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6ccc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0bc39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e698ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221:1 +ChaCha:1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0:2a000000000000000000000000000002:2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e:62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1:1 +ChaCha:0000000000000000000000000000000000000000000000000000000000000001:00000000000000000000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:4540f05a9f1fb296d7736e7b208e3c96eb4fe1834688d2604f450952ed432d41bbe2a0b6ea7566d2a5d1e7e20d42af2c53d792b1c43fea817e9ad275ae546963:1 +ChaCha:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000001:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:de9cba7bf3d69ef5e786dc63973f653a0b49e015adbff7134fcb7df137821031e85a050278a7084527214f73efc7fa5b5277062eb7a0433e445f41e31afab757:1 +ChaCha:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000100000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:ef3fdfd6c61578fbf5cf35bd3dd33b8009631634d21e42ac33960bd138e50d32111e4caf237ee53ca8ad6426194a88545ddc497a0b466e7d6bbdb0041b2f586b:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c730:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444a:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE5D493C19E38A77939E7A058D713E9CCCCA58045F436B434B1C80D365472406E392951987DB6905C80D431DA18451135BE7E82BCAB358CB3971E61405B2FF1798:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE5D493C19E38A77939E7A058D713E9CCCCA58045F436B434B1C80D365472406E392951987DB6905C80D431DA18451135BE7E82BCAB358CB3971E61405B2FF17980D6E7E67E861E28201C1EE30B441040FD06878D65042C95582A4318207BFC700BE0CE32889AEC2FFE5085E8967910D879FA0E8C0FF85FDC510B9FF2FBF87CFCB:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE5D493C19E38A77939E7A058D713E9CCCCA58045F436B434B1C80D365472406E392951987DB6905C80D431DA18451135BE7E82BCAB358CB3971E61405B2FF17980D6E7E67E861E28201C1EE30B441040FD06878D65042C95582A4318207BFC700BE0CE32889AEC2FFE5085E8967910D879FA0E8C0FF85FDC510B9FF2FBF87CFCB29577D68099E04FFA05F752A73D377C70D3A8BC2DA80E6E780EC057182C33AD1DE387252258A1E18E6FAD910327CE7F42FD1E1E0515F9586E2F2EFCB9F472B1D:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE5D493C19E38A77939E7A058D713E9CCCCA58045F436B434B1C80D365472406E392951987DB6905C80D431DA18451135BE7E82BCAB358CB3971E61405B2FF17980D6E7E67E861E28201C1EE30B441040FD06878D65042C95582A4318207BFC700BE0CE32889AEC2FFE5085E8967910D879FA0E8C0FF85FDC510B9FF2FBF87CFCB29577D68099E04FFA05F752A73D377C70D3A8BC2DA80E6E780EC057182C33AD1DE387252258A1E18E6FAD910327CE7F42FD1E1E0515F9586E2F2EFCB9F472B1DBDBAC354A4162151E9D92C79FB08BB4DDC56F19448C0175A46E2E6C491FEC71419AA43A349BEA768A92C75DE68FD9591E68067F3197094D3FB87ED81785EA075:1 +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE5D493C19E38A77939E7A058D713E9CCCCA58045F436B434B1C80D365472406E392951987DB6905C80D431DA18451135BE7E82BCAB358CB3971E61405B2FF17980D6E7E67E861E28201C1EE30B441040FD06878D65042C95582A4318207BFC700BE0CE32889AEC2FFE5085E8967910D879FA0E8C0FF85FDC510B9FF2FBF87CFCB29577D68099E04FFA05F752A73D377C70D3A8BC2DA80E6E780EC057182C33AD1DE387252258A1E18E6FAD910327CE7F42FD1E1E0515F9586E2F2EFCB9F472B1DBDBAC354A4162151E9D92C79FB08BB4DDC56F19448C0175A46E2E6C491FEC71419AA43A349BEA768A92C75DE68FD9591E68067F3197094D3FB87ED81785EA075E4B65E3E4C78F81DA9B751C5EFE024152301C48E63245B556C4C67AFF857E5EA15A908D83A1D9704F8E55E7352B20B694BF9970298E6B5AAD33EA2155D105D4E:1 + +ChaCha:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:00000000000000000001020304050607:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c94213668bbbd394c5de93b853178addd6b97f9fa1ec3e56c00c9ddff0a44a204241175a4cab0f961ba53ede9bdf960b94f9829b1f3414726429b362c5b538e391520f489b7ed8d20ae3fd49e9e259e44397514d618c96c4846be3c680bdc11c71dcbbe29ccf80d62a0938fa549391e6ea57ecbe2606790ec15d2224ae307c144226b7c4e8c2f97d2a1d67852d29beba110edd445197012062a393a9c92803ad3b4f31d7bc6033ccf7932cfed3f019044d25905916777286f82f9a4cc1ffe430ffd1dcfc27deed327b9f9630d2fa969fb6f0603cd19dd9a9519e673bcfcd9014125291a44669ef7285e74ed3729b677f801c3cdf058c50963168b496043716c7307cd9e0cdd137fccb0f05b47cdbb95c5f54831622c3652a32b2531fe326bcd6e2bbf56a194fa196fbd1a54952110f51c73433865f7664b836685e3664b3d8444aF89A242805E18C975F1146324996FDE17007CF3E6E8F4E764022533EDBFE07D4733E48BB372D75B0EF48EC983EB78532161CC529E5ABB89837DFCCA6261DBB37C7C5E6A87478BF41EE85A518C0F4EFA9BDE828C5A71B8E46597B634AFD204D3C501334239C3414285ED72D3A9169EABBD4DC25D52BB7516D3BA712D75AD8C0AE5D493C19E38A77939E7A058D713E9CCCCA58045F436B434B1C80D365472406E392951987DB6905C80D431DA18451135BE7E82BCAB358CB3971E61405B2FF17980D6E7E67E861E28201C1EE30B441040FD06878D65042C95582A4318207BFC700BE0CE32889AEC2FFE5085E8967910D879FA0E8C0FF85FDC510B9FF2FBF87CFCB29577D68099E04FFA05F752A73D377C70D3A8BC2DA80E6E780EC057182C33AD1DE387252258A1E18E6FAD910327CE7F42FD1E1E0515F9586E2F2EFCB9F472B1DBDBAC354A4162151E9D92C79FB08BB4DDC56F19448C0175A46E2E6C491FEC71419AA43A349BEA768A92C75DE68FD9591E68067F3197094D3FB87ED81785EA075E4B65E3E4C78F81DA9B751C5EFE024152301C48E63245B556C4C67AFF857E5EA15A908D83A1D9704F8E55E7352B20B694BF9970298E6B5AAD33EA2155D105D4E637D1E87C40A8E5F4E8C5A16A4B8F3DC27B31721D77A65FD1ED6F86BE25FB95DB29B1988493770A7C60E451FF97DD241A236851FC425691979FE30226559AD95:1 +ChaCha:0100000000000000000000000000000000000000000000000000000000000000:000000000000000000000000000000000000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:c5d30a7ce1ec119378c84f487d775a8542f13ece238a9455e8229e888de85bbd29eb63d0a17a5b999b52da22be4023eb07620a54f6fa6ad8737b71eb0464dac0:1 +ChaCha:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:0000000000000000ffffffffffffffff0000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:d9bf3f6bce6ed0b54254557767fb57443dd4778911b606055c39cc25e674b8363feabc57fde54f790c52c8ae43240b79d49042b777bfd6cb80e931270b7f50eb:1 +ChaCha:5555555555555555555555555555555555555555555555555555555555555555:0000000000000000aaaaaaaaaaaaaaaa0000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:aff7418293f3a553894b1e7484bd1e8ede196eced5a1d6814de37091e07e076e34bbba8107a686c982850f0a7353940d40db1ab0b5765b78b4cf473d9485a3dd:1 +ChaCha:5555555555555555555555555555555555555555555555555555555555555555:000000000000000055555555555555550000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:bea9411aa453c5434a5ae8c92862f564396855a9ea6e22d6d3b50ae1b3663311a4a3606c671d605ce16c3aece8e61ea145c59775017bee2fa6f88afc758069f7:1 +ChaCha:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:0000000000000000aaaaaaaaaaaaaaaa0000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9aa2a9f656efde5aa7591c5fed4b35aea2895dec7cb4543b9e9f21f5e7bcbcf3c43c748a970888f8248393a09d43e0b7e164bc4d0b0fb240a2d72115c4808906:1 +ChaCha:00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100:00000000000000000f1e2d3c4b5a69780000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9fadf409c00811d00431d67efbd88fba59218d5d6708b1d685863fabbb0e961eea480fd6fb532bfd494b2151015057423ab60a63fe4f55f7a212e2167ccab931:1 +ChaCha:c46ec1b18ce8a878725a37e780dfb7351f68ed2e194c79fbc6aebee1a667975d:00000000000000001ada31d5cf6882210000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f63a89b75c2271f9368816542ba52f06ed49241792302b00b5e8f80ae9a473afc25b218f519af0fdd406362e8d69de7f54c604a6e00f353f110f771bdca8ab92:1 diff --git a/Libraries/libressl/tests/explicit_bzero.c b/Libraries/libressl/tests/explicit_bzero.c new file mode 100644 index 000000000..496bafb20 --- /dev/null +++ b/Libraries/libressl/tests/explicit_bzero.c @@ -0,0 +1,225 @@ +/* $OpenBSD: explicit_bzero.c,v 1.9 2022/02/10 08:39:32 tb Exp $ */ +/* + * Copyright (c) 2014 Google Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#define ASSERT_EQ(a, b) assert((a) == (b)) +#define ASSERT_NE(a, b) assert((a) != (b)) +#define ASSERT_GE(a, b) assert((a) >= (b)) + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define __SANITIZE_ADDRESS__ +#endif +#endif +#ifdef __SANITIZE_ADDRESS__ +#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) +#else +#define ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif + +/* 128 bits of random data. */ +static const char secret[16] = { + 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c, + 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96, +}; + +enum { + SECRETCOUNT = 64, + SECRETBYTES = SECRETCOUNT * sizeof(secret) +}; + +/* + * As of glibc 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is no longer + * constant on Linux. SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ). + */ +static char *altstack; +#define ALTSTACK_SIZE (SIGSTKSZ + SECRETBYTES) + +static void +setup_stack(void) +{ + altstack = calloc(1, ALTSTACK_SIZE); + ASSERT_NE(NULL, altstack); + + const stack_t sigstk = { + .ss_sp = altstack, + .ss_size = ALTSTACK_SIZE + }; + + ASSERT_EQ(0, sigaltstack(&sigstk, NULL)); +} + +static void +cleanup_stack(void) +{ + free(altstack); +} + +static void +assert_on_stack(void) +{ + stack_t cursigstk; + ASSERT_EQ(0, sigaltstack(NULL, &cursigstk)); + ASSERT_EQ(SS_ONSTACK, cursigstk.ss_flags & (SS_DISABLE|SS_ONSTACK)); +} + +static void +call_on_stack(void (*fn)(int)) +{ + /* + * This is a bit more complicated than strictly necessary, but + * it ensures we don't have any flaky test failures due to + * inherited signal masks/actions/etc. + * + * On systems where SA_ONSTACK is not supported, this could + * alternatively be implemented using makecontext() or + * pthread_attr_setstack(). + */ + + const struct sigaction sigact = { + .sa_handler = fn, + .sa_flags = SA_ONSTACK, + }; + struct sigaction oldsigact; + sigset_t sigset, oldsigset; + + /* First, block all signals. */ + ASSERT_EQ(0, sigemptyset(&sigset)); + ASSERT_EQ(0, sigfillset(&sigset)); + ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigset, &oldsigset)); + + /* Next setup the signal handler for SIGUSR1. */ + ASSERT_EQ(0, sigaction(SIGUSR1, &sigact, &oldsigact)); + + /* Raise SIGUSR1 and momentarily unblock it to run the handler. */ + ASSERT_EQ(0, raise(SIGUSR1)); + ASSERT_EQ(0, sigdelset(&sigset, SIGUSR1)); + ASSERT_EQ(-1, sigsuspend(&sigset)); + ASSERT_EQ(EINTR, errno); + + /* Restore the original signal action, stack, and mask. */ + ASSERT_EQ(0, sigaction(SIGUSR1, &oldsigact, NULL)); + ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &oldsigset, NULL)); +} + +static void +populate_secret(char *buf, size_t len) +{ + int i, fds[2]; + ASSERT_EQ(0, pipe(fds)); + + for (i = 0; i < SECRETCOUNT; i++) + ASSERT_EQ(sizeof(secret), write(fds[1], secret, sizeof(secret))); + ASSERT_EQ(0, close(fds[1])); + + ASSERT_EQ(len, read(fds[0], buf, len)); + ASSERT_EQ(0, close(fds[0])); +} + +static int +count_secrets(const char *buf) +{ + int res = 0; + size_t i; + for (i = 0; i < SECRETCOUNT; i++) { + if (memcmp(buf + i * sizeof(secret), secret, + sizeof(secret)) == 0) + res += 1; + } + return (res); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static char * +test_without_bzero(void) +{ + char buf[SECRETBYTES]; + assert_on_stack(); + populate_secret(buf, sizeof(buf)); + char *res = memmem(altstack, ALTSTACK_SIZE, buf, sizeof(buf)); + ASSERT_NE(NULL, res); + return (res); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static char * +test_with_bzero(void) +{ + char buf[SECRETBYTES]; + assert_on_stack(); + populate_secret(buf, sizeof(buf)); + char *res = memmem(altstack, ALTSTACK_SIZE, buf, sizeof(buf)); + ASSERT_NE(NULL, res); + explicit_bzero(buf, sizeof(buf)); + return (res); +} + +static void +do_test_without_bzero(int signo) +{ + char *buf = test_without_bzero(); + ASSERT_GE(count_secrets(buf), 1); +} + +static void +do_test_with_bzero(int signo) +{ + char *buf = test_with_bzero(); + ASSERT_EQ(count_secrets(buf), 0); +} + +int +main(void) +{ + setup_stack(); + + /* + * Solaris and OS X clobber the signal stack after returning to the + * normal stack, so we need to inspect altstack while we're still + * running on it. Unfortunately, this means we risk clobbering the + * buffer ourselves. + * + * To minimize this risk, test_with{,out}_bzero() are responsible for + * locating the offset of their buf variable within altstack, and + * and returning that address. Then we can simply memcmp() repeatedly + * to count how many instances of secret we found. + */ + + /* + * First, test that if we *don't* call explicit_bzero, that we + * *are* able to find at least one instance of the secret data still + * on the stack. This sanity checks that call_on_stack() and + * populate_secret() work as intended. + */ + memset(altstack, 0, ALTSTACK_SIZE); + call_on_stack(do_test_without_bzero); + + /* + * Now test with a call to explicit_bzero() and check that we + * *don't* find any instances of the secret data. + */ + memset(altstack, 0, ALTSTACK_SIZE); + call_on_stack(do_test_with_bzero); + + cleanup_stack(); + + return (0); +} diff --git a/Libraries/libressl/tests/exportertest.c b/Libraries/libressl/tests/exportertest.c new file mode 100644 index 000000000..252fcb062 --- /dev/null +++ b/Libraries/libressl/tests/exportertest.c @@ -0,0 +1,664 @@ +/* $OpenBSD: exportertest.c,v 1.3 2023/04/14 14:23:05 tb Exp $ */ +/* + * Copyright (c) 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +#include "ssl_local.h" + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +struct exporter_test { + uint16_t tls_version; + unsigned int cipher_id; + const uint8_t *label; + size_t label_len; + const uint8_t context_value[64]; + size_t context_value_len; + int use_context; + const uint8_t client_random[SSL3_RANDOM_SIZE]; + const uint8_t server_random[SSL3_RANDOM_SIZE]; + const uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH]; + const uint8_t shared_key[64]; + size_t shared_key_len; + const uint8_t export[64]; + size_t export_len; + int want_error; +}; + +static const struct exporter_test exporter_tests[] = { + { + /* Valid export, no context - 32 bytes. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .use_context = 0, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export = { + 0x14, 0x08, 0x00, 0x9e, 0x6a, 0x67, 0x75, 0x4c, + 0xc4, 0xf3, 0x51, 0x57, 0x2f, 0x75, 0x0b, 0xf8, + 0x16, 0xfa, 0x61, 0x74, 0xd2, 0x12, 0x8f, 0x78, + 0x77, 0xf9, 0x8a, 0x3e, 0x58, 0x70, 0xf3, 0xd8, + }, + .export_len = 32, + }, + { + /* Valid export, no context - 32 bytes. */ + .tls_version = TLS1_3_VERSION, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .use_context = 0, + .shared_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .shared_key_len = 32, + .export = { + 0x69, 0xf4, 0xac, 0xec, 0x80, 0x67, 0xac, 0x5c, + 0xa6, 0x24, 0x47, 0xb1, 0x0f, 0xc8, 0xa1, 0x13, + 0x3b, 0x91, 0x33, 0x82, 0x97, 0x0a, 0xc0, 0xbf, + 0xac, 0x6d, 0x6b, 0x34, 0x20, 0xd3, 0x3a, 0x02, + }, + .export_len = 32, + }, + { + /* Valid export, no context - 64 bytes. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .use_context = 0, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export = { + 0x14, 0x08, 0x00, 0x9e, 0x6a, 0x67, 0x75, 0x4c, + 0xc4, 0xf3, 0x51, 0x57, 0x2f, 0x75, 0x0b, 0xf8, + 0x16, 0xfa, 0x61, 0x74, 0xd2, 0x12, 0x8f, 0x78, + 0x77, 0xf9, 0x8a, 0x3e, 0x58, 0x70, 0xf3, 0xd8, + 0xe8, 0xd2, 0xb7, 0xcd, 0xbc, 0x37, 0xdf, 0x16, + 0x12, 0xf1, 0xe8, 0xb2, 0x62, 0x79, 0x91, 0x45, + 0x77, 0xe0, 0x68, 0x6d, 0xd5, 0x31, 0x54, 0x55, + 0x22, 0x63, 0xc0, 0x36, 0x31, 0x07, 0xda, 0x33, + }, + .export_len = 64, + }, + { + /* Valid export, no context - 64 bytes. */ + .tls_version = TLS1_3_VERSION, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .use_context = 0, + .shared_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .shared_key_len = 32, + .export = { + 0x77, 0x15, 0xe2, 0x07, 0x65, 0x64, 0x3b, 0x14, + 0x38, 0xcb, 0x73, 0x93, 0xda, 0x70, 0xfa, 0x86, + 0x2c, 0x34, 0xcc, 0x94, 0x52, 0xc2, 0xd3, 0xb4, + 0x59, 0x2c, 0xc8, 0x05, 0x70, 0xfe, 0x48, 0x61, + 0xd3, 0xea, 0x57, 0x66, 0xa9, 0x66, 0x2f, 0x4a, + 0x35, 0xc9, 0x88, 0x86, 0x28, 0x52, 0xe3, 0x64, + 0x5e, 0xf9, 0x28, 0x53, 0x8a, 0x3a, 0x92, 0x92, + 0x40, 0x8c, 0x89, 0x17, 0x59, 0xd0, 0xd0, 0x82, + }, + .export_len = 64, + }, + { + /* Valid export, zero length context - 32 bytes. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .context_value_len = 0, + .use_context = 1, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export = { + 0xdb, 0xc9, 0xdf, 0x7c, 0x04, 0x39, 0xdd, 0x23, + 0xc3, 0x68, 0xdc, 0xf3, 0x04, 0xcf, 0x4c, 0x4d, + 0x86, 0x5b, 0xe6, 0x48, 0xc5, 0x6d, 0xe5, 0x1e, + 0xea, 0xc5, 0xe4, 0x00, 0x27, 0x72, 0xda, 0xb6, + }, + .export_len = 32, + }, + { + /* Valid export, zero length context - 32 bytes. */ + .tls_version = TLS1_3_VERSION, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .context_value_len = 0, + .use_context = 1, + .shared_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .shared_key_len = 32, + .export = { + 0x69, 0xf4, 0xac, 0xec, 0x80, 0x67, 0xac, 0x5c, + 0xa6, 0x24, 0x47, 0xb1, 0x0f, 0xc8, 0xa1, 0x13, + 0x3b, 0x91, 0x33, 0x82, 0x97, 0x0a, 0xc0, 0xbf, + 0xac, 0x6d, 0x6b, 0x34, 0x20, 0xd3, 0x3a, 0x02, + }, + .export_len = 32, + }, + { + /* Valid export, with context value - 32 bytes. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .context_value = { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + }, + .context_value_len = 16, + .use_context = 1, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export = { + 0x0e, 0xb4, 0xd1, 0x3a, 0x0e, 0x24, 0xab, 0x0d, + 0x4c, 0x48, 0x35, 0x25, 0xf6, 0x4d, 0xa2, 0x9b, + 0xaa, 0x1d, 0xbc, 0x54, 0x7e, 0xb0, 0x3c, 0x4b, + 0x07, 0x04, 0x9c, 0x7c, 0x06, 0xa7, 0xea, 0x70, + }, + .export_len = 32, + }, + { + /* Valid export, with context value - 32 bytes. */ + .tls_version = TLS1_3_VERSION, + .label = "EXPERIMENTAL testing", + .label_len = 20, + .context_value = { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + }, + .context_value_len = 16, + .use_context = 1, + .shared_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .shared_key_len = 32, + .export = { + 0x34, 0xb8, 0x00, 0x6a, 0xb2, 0x62, 0xab, 0xea, + 0xc7, 0x2b, 0x15, 0xa0, 0x85, 0xda, 0xaa, 0xa5, + 0x12, 0x85, 0xbf, 0x4a, 0xa4, 0x71, 0x42, 0xc8, + 0xd4, 0xa6, 0x66, 0x18, 0xc6, 0xc9, 0x26, 0x6f, + }, + .export_len = 32, + }, + { + /* Valid export, with different label - 32 bytes. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = "EXPERIMENTAL more testing", + .label_len = 20, + .context_value = { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + }, + .context_value_len = 16, + .use_context = 1, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export = { + 0xb0, 0xb6, 0x45, 0xdd, 0x30, 0x76, 0xf0, 0x57, + 0x22, 0x31, 0xbb, 0x8d, 0xe1, 0xf9, 0xe3, 0xed, + 0xae, 0x74, 0x6f, 0x40, 0x94, 0xf6, 0xc2, 0xfc, + 0x21, 0xff, 0xf7, 0x00, 0x86, 0x54, 0xb6, 0x06, + }, + .export_len = 32, + }, + { + /* Valid export, with different label - 32 bytes. */ + .tls_version = TLS1_3_VERSION, + .label = "EXPERIMENTAL more testing", + .label_len = 20, + .context_value = { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + }, + .context_value_len = 16, + .use_context = 1, + .shared_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .shared_key_len = 32, + .export = { + 0x18, 0x4e, 0x65, 0x3c, 0x91, 0x5d, 0x6a, 0xc3, + 0x25, 0x38, 0xbe, 0x6e, 0xca, 0x12, 0x54, 0x76, + 0x5a, 0x84, 0xf7, 0x19, 0x44, 0x78, 0xec, 0xc0, + 0x83, 0xf6, 0x22, 0xb8, 0x86, 0x31, 0xe9, 0x2e, + }, + .export_len = 32, + }, + { + /* Invalid - illegal label. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = TLS_MD_CLIENT_FINISH_CONST, + .label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, + .use_context = 0, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export_len = 32, + .want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL, + }, + { + /* Invalid - illegal label. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = TLS_MD_SERVER_FINISH_CONST, + .label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, + .use_context = 0, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export_len = 32, + .want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL, + }, + { + /* Invalid - illegal label. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = TLS_MD_KEY_EXPANSION_CONST, + .label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE, + .use_context = 0, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export_len = 32, + .want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL, + }, + { + /* Invalid - illegal label. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = TLS_MD_MASTER_SECRET_CONST, + .label_len = TLS_MD_MASTER_SECRET_CONST_SIZE, + .use_context = 0, + .client_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export_len = 32, + .want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL, + }, + { + /* Invalid - illegal label, split over label and seed. */ + .tls_version = TLS1_2_VERSION, + .cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .label = "master ", + .label_len = 7, + .use_context = 0, + .client_random = { + 's', 'e', 'c', 'r', 'e', 't', 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .server_random = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .master_key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }, + .export = { + 0x40, 0x70, 0xba, 0xfa, 0xba, 0x44, 0x74, 0x93, + 0xa2, 0x43, 0x18, 0x07, 0xa4, 0x4f, 0x3f, 0xda, + 0x88, 0x7b, 0x0e, 0x79, 0x70, 0xcf, 0xdb, 0x91, + 0xfc, 0x3f, 0x96, 0x78, 0x6b, 0x50, 0xe3, 0xa6, + }, + .export_len = 32, + .want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL, + }, +}; + +#define N_EXPORTER_TESTS (sizeof(exporter_tests) / sizeof(exporter_tests[0])) + +static int +exporter_test(size_t test_no, const struct exporter_test *et) +{ + struct tls13_secret tls13_context = { .data = "", .len = 0 }; + struct tls13_ctx *tls13_ctx; + struct tls13_secrets *tls13_secrets; + SSL_SESSION *ssl_session = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + uint8_t export[256]; + int err, ret; + int failed = 1; + + memset(export, 0, sizeof(export)); + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) { + fprintf(stderr, "FAIL: SSL_CTX_new\n"); + goto failure; + } + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "FAIL: SSL_new\n"); + goto failure; + } + if ((ssl_session = SSL_SESSION_new()) == NULL) { + fprintf(stderr, "FAIL: SSL_SESSION_new\n"); + goto failure; + } + + ssl_session->ssl_version = et->tls_version; + + if (!SSL_set_session(ssl, ssl_session)) { + fprintf(stderr, "FAIL: SSL_set_session\n"); + goto failure; + } + + memcpy(ssl_session->master_key, et->master_key, + sizeof(ssl_session->master_key)); + memcpy(ssl->s3->client_random, et->client_random, + sizeof(ssl->s3->client_random)); + memcpy(ssl->s3->server_random, et->server_random, + sizeof(ssl->s3->server_random)); + + if (et->tls_version >= TLS1_3_VERSION) { + if ((tls13_ctx = tls13_ctx_new(TLS13_HS_CLIENT, ssl)) == NULL) { + fprintf(stderr, "FAIL: tls13_ctx_new\n"); + goto failure; + } + ssl->tls13 = tls13_ctx; + + if ((tls13_secrets = tls13_secrets_create(EVP_sha384(), + 0)) == NULL) { + fprintf(stderr, "FAIL: tls13_secrets_create\n"); + goto failure; + } + ssl->s3->hs.tls13.secrets = tls13_secrets; + + if (!tls13_derive_early_secrets(tls13_secrets, + tls13_secrets->zeros.data, tls13_secrets->zeros.len, + &tls13_context)) { + fprintf(stderr, "FAIL: tls13_derive_early_secrets\n"); + goto failure; + } + if (!tls13_derive_handshake_secrets(tls13_secrets, et->shared_key, + et->shared_key_len, &tls13_context)) { + fprintf(stderr, "FAIL: tls13_derive_handshake_secrets\n"); + goto failure; + } + if (!tls13_derive_application_secrets(tls13_secrets, + &tls13_context)) { + fprintf(stderr, "FAIL: tls13_derive_early_secrets\n"); + goto failure; + } + + tls13_ctx->handshake_completed = 1; + } + + ssl->s3->hs.state = SSL_ST_OK; + ssl->s3->hs.negotiated_tls_version = et->tls_version; + ssl->s3->hs.cipher = SSL_CIPHER_get_by_id(et->cipher_id); + + ret = SSL_export_keying_material(ssl, export, et->export_len, et->label, + et->label_len, et->context_value, et->context_value_len, + et->use_context); + + if (et->want_error != 0) { + if (ret) { + fprintf(stderr, "FAIL: test %zu - " + "SSL_export_keying_material() succeeded, want " + "error\n", test_no); + goto failure; + } + + err = ERR_peek_error(); + if (ERR_GET_REASON(err) != et->want_error) { + fprintf(stderr, "FAIL: %zu - got error reason %d, " + "want %d\n", test_no, ERR_GET_REASON(err), + et->want_error); + goto failure; + } + } else { + if (!ret) { + fprintf(stderr, "FAIL: test %zu - " + "SSL_export_keying_material() failed\n", test_no); + ERR_print_errors_fp(stderr); + goto failure; + } + + if (memcmp(et->export, export, et->export_len) != 0) { + fprintf(stderr, "FAIL: test %zu\n", test_no); + fprintf(stderr, "Got export:\n"); + hexdump(export, et->export_len); + fprintf(stderr, "Want export:\n"); + hexdump(et->export, et->export_len); + goto failure; + } + } + + failed = 0; + + failure: + SSL_SESSION_free(ssl_session); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_EXPORTER_TESTS; i++) + failed |= exporter_test(i, &exporter_tests[i]); + + return (failed); +} diff --git a/Libraries/libressl/tests/freenull.c b/Libraries/libressl/tests/freenull.c new file mode 100644 index 000000000..75c755350 --- /dev/null +++ b/Libraries/libressl/tests/freenull.c @@ -0,0 +1,239 @@ +/* $OpenBSD: freenull.c.head,v 1.6 2023/07/28 17:13:56 tb Exp $ */ + +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int +main(int argc, char **argv) +{ + ACCESS_DESCRIPTION_free(NULL); + ASIdOrRange_free(NULL); + ASIdentifierChoice_free(NULL); + ASIdentifiers_free(NULL); + ASN1_BIT_STRING_free(NULL); + ASN1_BMPSTRING_free(NULL); + ASN1_ENUMERATED_free(NULL); + ASN1_GENERALIZEDTIME_free(NULL); + ASN1_GENERALSTRING_free(NULL); + ASN1_IA5STRING_free(NULL); + ASN1_INTEGER_free(NULL); + ASN1_NULL_free(NULL); + ASN1_OBJECT_free(NULL); + ASN1_OCTET_STRING_free(NULL); + ASN1_PCTX_free(NULL); + ASN1_PRINTABLESTRING_free(NULL); + ASN1_PRINTABLE_free(NULL); + ASN1_STRING_free(NULL); + ASN1_T61STRING_free(NULL); + ASN1_TIME_free(NULL); + ASN1_TYPE_free(NULL); + ASN1_UNIVERSALSTRING_free(NULL); + ASN1_UTCTIME_free(NULL); + ASN1_UTF8STRING_free(NULL); + ASN1_VISIBLESTRING_free(NULL); + ASRange_free(NULL); + AUTHORITY_INFO_ACCESS_free(NULL); + AUTHORITY_KEYID_free(NULL); + BASIC_CONSTRAINTS_free(NULL); + BIO_free(NULL); + BIO_meth_free(NULL); + BN_CTX_free(NULL); + BN_GENCB_free(NULL); + BN_MONT_CTX_free(NULL); + BN_clear_free(NULL); + BN_free(NULL); + BUF_MEM_free(NULL); + CERTIFICATEPOLICIES_free(NULL); + CMAC_CTX_free(NULL); + CMS_ContentInfo_free(NULL); + CMS_ReceiptRequest_free(NULL); + CONF_free(NULL); + CRL_DIST_POINTS_free(NULL); + CTLOG_STORE_free(NULL); + CTLOG_free(NULL); + CT_POLICY_EVAL_CTX_free(NULL); + DH_free(NULL); + DIRECTORYSTRING_free(NULL); + DISPLAYTEXT_free(NULL); + DIST_POINT_NAME_free(NULL); + DIST_POINT_free(NULL); + DSA_SIG_free(NULL); + DSA_free(NULL); + DSA_meth_free(NULL); + ECDSA_SIG_free(NULL); + EC_GROUP_clear_free(NULL); + EC_GROUP_free(NULL); + EC_KEY_METHOD_free(NULL); + EC_KEY_free(NULL); + EC_POINT_clear_free(NULL); + EC_POINT_free(NULL); + EDIPARTYNAME_free(NULL); +#ifndef OPENSSL_NO_ENGINE + ENGINE_free(NULL); +#endif + ESS_CERT_ID_free(NULL); + ESS_ISSUER_SERIAL_free(NULL); + ESS_SIGNING_CERT_free(NULL); + EVP_AEAD_CTX_free(NULL); + EVP_CIPHER_CTX_free(NULL); + EVP_CIPHER_meth_free(NULL); + EVP_ENCODE_CTX_free(NULL); + EVP_MD_CTX_free(NULL); + EVP_MD_meth_free(NULL); + EVP_PKEY_CTX_free(NULL); + EVP_PKEY_asn1_free(NULL); + EVP_PKEY_free(NULL); + EVP_PKEY_meth_free(NULL); + EXTENDED_KEY_USAGE_free(NULL); + GENERAL_NAMES_free(NULL); + GENERAL_NAME_free(NULL); + GENERAL_SUBTREE_free(NULL); + GOST_CIPHER_PARAMS_free(NULL); + GOST_KEY_free(NULL); + HMAC_CTX_free(NULL); + IPAddressChoice_free(NULL); + IPAddressFamily_free(NULL); + IPAddressOrRange_free(NULL); + IPAddressRange_free(NULL); + ISSUING_DIST_POINT_free(NULL); + NAME_CONSTRAINTS_free(NULL); + NCONF_free(NULL); + NETSCAPE_SPKAC_free(NULL); + NETSCAPE_SPKI_free(NULL); + NOTICEREF_free(NULL); + OCSP_BASICRESP_free(NULL); + OCSP_CERTID_free(NULL); + OCSP_CERTSTATUS_free(NULL); + OCSP_CRLID_free(NULL); + OCSP_ONEREQ_free(NULL); + OCSP_REQINFO_free(NULL); + OCSP_REQUEST_free(NULL); + OCSP_REQ_CTX_free(NULL); + OCSP_RESPBYTES_free(NULL); + OCSP_RESPDATA_free(NULL); + OCSP_RESPID_free(NULL); + OCSP_RESPONSE_free(NULL); + OCSP_REVOKEDINFO_free(NULL); + OCSP_SERVICELOC_free(NULL); + OCSP_SIGNATURE_free(NULL); + OCSP_SINGLERESP_free(NULL); + OTHERNAME_free(NULL); + PBE2PARAM_free(NULL); + PBEPARAM_free(NULL); + PBKDF2PARAM_free(NULL); + PKCS12_BAGS_free(NULL); + PKCS12_MAC_DATA_free(NULL); + PKCS12_SAFEBAG_free(NULL); + PKCS12_free(NULL); + PKCS7_DIGEST_free(NULL); + PKCS7_ENCRYPT_free(NULL); + PKCS7_ENC_CONTENT_free(NULL); + PKCS7_ENVELOPE_free(NULL); + PKCS7_ISSUER_AND_SERIAL_free(NULL); + PKCS7_RECIP_INFO_free(NULL); + PKCS7_SIGNED_free(NULL); + PKCS7_SIGNER_INFO_free(NULL); + PKCS7_SIGN_ENVELOPE_free(NULL); + PKCS7_free(NULL); + PKCS8_PRIV_KEY_INFO_free(NULL); + PKEY_USAGE_PERIOD_free(NULL); + POLICYINFO_free(NULL); + POLICYQUALINFO_free(NULL); + POLICY_CONSTRAINTS_free(NULL); + POLICY_MAPPING_free(NULL); + RSA_OAEP_PARAMS_free(NULL); + RSA_PSS_PARAMS_free(NULL); + RSA_free(NULL); + RSA_meth_free(NULL); + SCT_LIST_free(NULL); + SCT_free(NULL); + TS_ACCURACY_free(NULL); + TS_MSG_IMPRINT_free(NULL); + TS_REQ_ext_free(NULL); + TS_REQ_free(NULL); + TS_RESP_CTX_free(NULL); + TS_RESP_free(NULL); + TS_STATUS_INFO_free(NULL); + TS_TST_INFO_ext_free(NULL); + TS_TST_INFO_free(NULL); + TS_VERIFY_CTX_free(NULL); + TXT_DB_free(NULL); + UI_free(NULL); + USERNOTICE_free(NULL); + X509V3_conf_free(NULL); + X509_ALGOR_free(NULL); + X509_ATTRIBUTE_free(NULL); + X509_CERT_AUX_free(NULL); + X509_CINF_free(NULL); + X509_CRL_INFO_free(NULL); + X509_CRL_METHOD_free(NULL); + X509_CRL_free(NULL); + X509_EXTENSION_free(NULL); + X509_INFO_free(NULL); + X509_LOOKUP_free(NULL); + X509_NAME_ENTRY_free(NULL); + X509_NAME_free(NULL); + X509_OBJECT_free(NULL); + X509_PKEY_free(NULL); + X509_PUBKEY_free(NULL); + X509_REQ_INFO_free(NULL); + X509_REQ_free(NULL); + X509_REVOKED_free(NULL); + X509_SIG_free(NULL); + X509_STORE_CTX_free(NULL); + X509_STORE_free(NULL); + X509_VAL_free(NULL); + X509_VERIFY_PARAM_free(NULL); + X509_email_free(NULL); + X509_free(NULL); + lh_free(NULL); + sk_free(NULL); +/* $OpenBSD: freenull.c.tail,v 1.2 2018/07/10 20:55:57 tb Exp $ */ + + BIO_free_all(NULL); + NCONF_free_data(NULL); + _CONF_free_data(NULL); + + lh_FUNCTION_free(NULL); + + sk_ASN1_OBJECT_pop_free(NULL, NULL); + sk_CONF_VALUE_pop_free(NULL, NULL); + sk_GENERAL_NAME_pop_free(NULL, NULL); + sk_OCSP_CERTID_free(NULL); + sk_OPENSSL_STRING_free(NULL); + sk_PKCS12_SAFEBAG_pop_free(NULL, NULL); + sk_PKCS7_pop_free(NULL, NULL); + sk_X509_ATTRIBUTE_free(NULL); + sk_X509_CRL_pop_free(NULL, NULL); + sk_X509_EXTENSION_pop_free(NULL, NULL); + sk_X509_INFO_free(NULL); + sk_X509_INFO_pop_free(NULL, NULL); + sk_X509_NAME_ENTRY_pop_free(NULL, NULL); + sk_X509_free(NULL); + sk_X509_pop_free(NULL, NULL); + + printf("PASS\n"); + + return 0; +} diff --git a/Libraries/libressl/tests/gcm128test.c b/Libraries/libressl/tests/gcm128test.c new file mode 100644 index 000000000..def7653c7 --- /dev/null +++ b/Libraries/libressl/tests/gcm128test.c @@ -0,0 +1,926 @@ +/* $OpenBSD: gcm128test.c,v 1.7 2022/09/05 21:06:31 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include + +#include +#include + +/* XXX - something like this should be in the public headers. */ +struct gcm128_context { + uint64_t opaque[64]; +}; + +struct gcm128_test { + const uint8_t K[128]; + size_t K_len; + const uint8_t IV[128]; + size_t IV_len; + const uint8_t P[512]; + size_t P_len; + const uint8_t A[128]; + size_t A_len; + const uint8_t C[512]; + size_t C_len; + const uint8_t T[16]; +}; + +struct gcm128_test gcm128_tests[] = { + { + /* Test Case 1. */ + .K = {0}, + .K_len = 16, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 0, + .A = {0}, + .A_len = 0, + .C = {0}, + .C_len = 0, + .T = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a, + }, + }, + { + /* Test Case 2. */ + .K = {0}, + .K_len = 16, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 16, + .A = {0}, + .A_len = 0, + .C = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78, + }, + .C_len = 16, + .T = { + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf, + }, + }, + { + /* Test Case 3. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 16, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, + }, + .IV_len = 12, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + }, + .P_len = 64, + .A = {0}, + .A_len = 0, + .C = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, + }, + .C_len = 64, + .T = { + 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, + } + }, + { + /* Test Case 4. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 16, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, + }, + .IV_len = 12, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, + }, + .C_len = 60, + .T = { + 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, + }, + }, + { + /* Test Case 5. */ + /* K, P, A are the same as TC4. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 16, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + }, + .IV_len = 8, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98, + }, + .C_len = 60, + .T = { + 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, + }, + }, + { + /* Test Case 6. */ + /* K, P, A are the same as TC4. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 16, + .IV = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, + }, + .IV_len = 60, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5, + }, + .C_len = 60, + .T = { + 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, + }, + }, + { + /* Test Case 7. */ + .K = {0}, + .K_len = 24, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 0, + .A = {0}, + .A_len = 0, + .C = {0}, + .C_len = 0, + .T = { + 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35, + }, + }, + { + /* Test Case 8. */ + .K = {0}, + .K_len = 24, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 16, + .A = {0}, + .A_len = 0, + .C = { + 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00, + }, + .C_len = 16, + .T = { + 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb, + }, + }, + { + /* Test Case 9. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + }, + .K_len = 24, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, + }, + .IV_len = 12, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + }, + .P_len = 64, + .A = {0}, + .A_len = 0, + .C = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56, + }, + .C_len = 64, + .T = { + 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14, + }, + }, + { + /* Test Case 10. */ + /* K and IV are the same as TC9. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + }, + .K_len = 24, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, + }, + .IV_len = 12, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, + }, + .C_len = 60, + .T = { + 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c, + }, + }, + { + /* Test Case 11. */ + /* K is the same as TC9, P and A are the same as TC10. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + }, + .K_len = 24, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + }, + .IV_len = 8, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 + }, + .C_len = 60, + .T = { + 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8, + }, + }, + { + /* Test Case 12. */ + /* K is the same as TC9, P and A are the same as TC10. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + }, + .K_len = 24, + .IV = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, + }, + .IV_len = 60, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b, + }, + .C_len = 60, + .T = { + 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9, + }, + }, + { + /* Test Case 13. */ + .K = {0}, + .K_len = 32, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 0, + .A = {0}, + .A_len = 0, + .C = {0}, + .C_len = 0, + .T = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b, + }, + }, + { + /* Test Case 14. */ + .K = {0}, + .K_len = 32, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 16, + .A = {0}, + .A_len = 0, + .C = { + 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, + }, + .C_len = 16, + .T = { + 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19, + }, + }, + { + /* Test Case 15. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 32, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, + }, + .IV_len = 12, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + }, + .P_len = 64, + .A = {0}, + .A_len = 0, + .C = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad, + }, + .C_len = 64, + .T = { + 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c, + }, + }, + { + /* Test Case 16. */ + /* K and IV are the same as TC15. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 32, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, + }, + .IV_len = 12, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, + }, + .C_len = 60, + .T = { + 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b, + }, + }, + { + /* Test Case 17. */ + /* K is the same as TC15, P and A are the same as TC 16. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 32, + .IV = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + }, + .IV_len = 8, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f, + }, + .C_len = 60, + .T = { + 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2, + }, + }, + { + /* Test Case 18. */ + /* K is the same as TC15, P and A are the same as TC 16. */ + .K = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + }, + .K_len = 32, + .IV = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, + }, + .IV_len = 60, + .P = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, + }, + .P_len = 60, + .A = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, + }, + .A_len = 20, + .C = { + 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f, + }, + .C_len = 60, + .T = { + 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a, + }, + }, + { + /* Test Case 19. */ + .K = {0}, + .K_len = 16, + .IV = {0}, + .IV_len = 12, + .P = {0}, + .P_len = 0, + .A = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad, + }, + .A_len = 128, + .C = {0}, + .C_len = 0, + .T = { + 0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d, + 0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92, + }, + }, + { + /* Test Case 20. */ + .K = {0}, + .K_len = 16, + .IV = { + /* This results in 0xff in counter LSB. */ + 0xff, 0xff, 0xff, 0xff, 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, 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, + }, + .IV_len = 64, + .P = {0}, + .P_len = 288, + .A = {0}, + .A_len = 0, + .C = { + 0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a, + 0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14, + 0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce, + 0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f, + 0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70, + 0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18, + 0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf, + 0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49, + 0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab, + 0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c, + 0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c, + 0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29, + 0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1, + 0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76, + 0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2, + 0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce, + 0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f, + 0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86, + 0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb, + 0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18, + 0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65, + 0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42, + 0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b, + 0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06, + 0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24, + 0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c, + 0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4, + 0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64, + 0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03, + 0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6, + 0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90, + 0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74, + 0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67, + 0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46, + 0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78, + 0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c, + }, + .C_len = 288, + .T = { + 0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a, + 0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f, + }, + }, +}; + +#define N_TESTS (sizeof(gcm128_tests) / sizeof(*gcm128_tests)) + +static int +do_gcm128_test(int test_no, struct gcm128_test *tv) +{ + GCM128_CONTEXT ctx; + AES_KEY key; + uint8_t *out = NULL; + size_t out_len; + int ret = 1; + + out_len = tv->P_len; + if (out_len != 0) { + out = malloc(out_len); + if (out == NULL) + err(1, "malloc"); + } + + AES_set_encrypt_key(tv->K, tv->K_len * 8, &key); + + if (out_len != 0) + memset(out, 0, out_len); + CRYPTO_gcm128_init(&ctx, &key, (block128_f)AES_encrypt); + CRYPTO_gcm128_setiv(&ctx, tv->IV, tv->IV_len); + if (tv->A_len > 0) + CRYPTO_gcm128_aad(&ctx, tv->A, tv->A_len); + if (tv->P_len > 0) + CRYPTO_gcm128_encrypt(&ctx, tv->P, out, out_len); + if (CRYPTO_gcm128_finish(&ctx, tv->T, 16)) { + fprintf(stderr, "TEST %d: CRYPTO_gcm128_finish failed\n", + test_no); + goto fail; + } + if (tv->C_len > 0 && memcmp(out, tv->C, out_len)) { + fprintf(stderr, "TEST %d: encrypt failed\n", test_no); + goto fail; + } + + if (out_len != 0) + memset(out, 0, out_len); + CRYPTO_gcm128_setiv(&ctx, tv->IV, tv->IV_len); + if (tv->A_len > 0) + CRYPTO_gcm128_aad(&ctx, tv->A, tv->A_len); + if (tv->C_len > 0) + CRYPTO_gcm128_decrypt(&ctx, tv->C, out, out_len); + if (CRYPTO_gcm128_finish(&ctx, tv->T, 16)) { + fprintf(stderr, "TEST %d: CRYPTO_gcm128_finish failed\n", + test_no); + goto fail; + } + if (tv->P_len > 0 && memcmp(out, tv->P, out_len)) { + fprintf(stderr, "TEST %d: decrypt failed\n", test_no); + goto fail; + } + + ret = 0; + +fail: + free(out); + return (ret); +} + +int +main(int argc, char **argv) +{ + int ret = 0; + size_t i; + + for (i = 0; i < N_TESTS; i++) + ret |= do_gcm128_test(i + 1, &gcm128_tests[i]); + + return ret; +} diff --git a/Libraries/libressl/tests/gost2814789t.c b/Libraries/libressl/tests/gost2814789t.c new file mode 100644 index 000000000..5e439a7e3 --- /dev/null +++ b/Libraries/libressl/tests/gost2814789t.c @@ -0,0 +1,1491 @@ +/* $OpenBSD: gost2814789t.c,v 1.9 2023/06/19 18:51:47 tb Exp $ */ +/* vim: set fileencoding=ascii : Charset: ASCII */ +/* test/gostr2814789t.c */ +/* ==================================================================== + * Copyright (c) 2012 Crypto-Pro, Ltd., Serguei E. Leontiev, + * lse@cryptopro.ru + * + * This file is distributed under the same license as OpenSSL + * ==================================================================== + */ +#include + +#if defined(OPENSSL_NO_GOST) +int main(int argc, char *argv[]) +{ + printf("No GOST 28147-89 support\n"); + return 0; +} +#else + +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include +#include +#include + +#define G89_MAX_TC_LEN (2048) +#define G89_BLOCK_LEN (8) + +#undef U64 +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +#define U64(C) C##UI64 +#elif defined(_LP64) || defined(__arch64__) +#define U64(C) C##UL +#else +#define U64(C) C##ULL +#endif + +typedef enum g89_mode_ { + G89_ECB, + G89_CFB, + G89_CNT, + G89_IMIT +} g89_mode; + +typedef struct g89_tc_ { + uint64_t ullLen; /* ullLen > G89_MAX_TC_LEN */ + /* Clear text ullLen */ + /* of zero unsigned chars */ + const unsigned char bIn[G89_MAX_TC_LEN]; /* Clear text, when */ + /* ullLen <= G89_MAX_TC_LEN */ + const char *szParamSet; /* S-Box ID */ + const char *szDerive; /* String for derive bRawKey */ + const unsigned char bRawKey[EVP_MAX_KEY_LENGTH]; + g89_mode gMode; /* Mode of encryption or MAC */ + const unsigned char bIV[EVP_MAX_IV_LENGTH]; /* IV for CFB or CNT mode */ + const unsigned char bOut[G89_MAX_TC_LEN]; /* Cipher text for ECB/CFB/CNT */ + /* mode, when ullLen <= G89_MAX_TC_LEN; + * Last 16 unsigned char of cipher text for + * ECB/CFB/CNT, when ullLen > + * G89_MAX_TC_LEN; + * 4 unsigned char MAC for imitovstavka */ +} g89_tc; + +const g89_tc tcs[] = { + /* + * GOST R 34.11-94 Test cases + */ + { /* see p. A.3.1 [GOSTR341194], p. 7.3.1 [ENG-GOSTR341194] */ + /* */ + /* Iteration 1, K[1], see Errata for RFC 5831 */ + 8, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + "id-GostR3411-94-TestParamSet", + NULL, + { + 0x54, 0x6d, 0x20, 0x33, 0x68, 0x65, 0x6c, 0x32, + 0x69, 0x73, 0x65, 0x20, 0x73, 0x73, 0x6e, 0x62, + 0x20, 0x61, 0x67, 0x79, 0x69, 0x67, 0x74, 0x74, + 0x73, 0x65, 0x68, 0x65, 0x20, 0x2c, 0x3d, 0x73 + }, + G89_ECB, + { 0 }, + { + 0x1b, 0x0b, 0xbc, 0x32, 0xce, 0xbc, 0xab, 0x42 + } + }, + { /* see p. A.3.1 [GOSTR341194], p. 7.3.1 [ENG-GOSTR341194] */ + /* */ + /* Iteration 1, K[4] */ + 8, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + "id-GostR3411-94-TestParamSet", + NULL, + { + 0xec, 0x0a, 0x8b, 0xa1, 0x5e, 0xc0, 0x04, 0xa8, + 0xba, 0xc5, 0x0c, 0xac, 0x0c, 0x62, 0x1d, 0xee, + 0xe1, 0xc7, 0xb8, 0xe7, 0x00, 0x7a, 0xe2, 0xec, + 0xf2, 0x73, 0x1b, 0xff, 0x4e, 0x80, 0xe2, 0xa0 + }, + G89_ECB, + { 0 }, + { + 0x2d, 0x56, 0x2a, 0x0d, 0x19, 0x04, 0x86, 0xe7 + } + }, + { /* see p. A.3.1 [GOSTR341194], p. 7.3.1 [ENG-GOSTR341194] */ + /* */ + /* Iteration 2, K[1] */ + 8, + { + 0x34, 0xc0, 0x15, 0x33, 0xe3, 0x7d, 0x1c, 0x56 + }, + "id-GostR3411-94-TestParamSet", + NULL, + { + 0x34, 0x87, 0x24, 0xa4, 0xc1, 0xa6, 0x76, 0x67, + 0x15, 0x3d, 0xde, 0x59, 0x33, 0x88, 0x42, 0x50, + 0xe3, 0x24, 0x8c, 0x65, 0x7d, 0x41, 0x3b, 0x8c, + 0x1c, 0x9c, 0xa0, 0x9a, 0x56, 0xd9, 0x68, 0xcf + }, + G89_ECB, + { 0 }, + { + 0x86, 0x3e, 0x78, 0xdd, 0x2d, 0x60, 0xd1, 0x3c + } + }, + /* + * id-Gost28147-89-CryptoPro-A-ParamSet (1.2.643.2.2.31.1) + * Test cases + */ + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 16, + { + 0x74, 0x3d, 0x76, 0xf9, 0x1b, 0xee, 0x35, 0x3c, + 0xa2, 0x5c, 0x3b, 0x10, 0xeb, 0x64, 0xcf, 0xf5 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testecb1", + { + 0xbb, 0xf1, 0xed, 0xd3, 0x20, 0xaf, 0x8a, 0x62, + 0x8e, 0x11, 0xc8, 0xa9, 0x51, 0xcc, 0xbe, 0x81, + 0x47, 0x7b, 0x41, 0xa1, 0x6a, 0xf6, 0x7f, 0x05, + 0xe8, 0x51, 0x2f, 0x9e, 0x01, 0xf8, 0xcf, 0x49 + }, + G89_ECB, + { 0 }, + { + 0xc3, 0x73, 0x90, 0x95, 0x35, 0x58, 0x08, 0x63, + 0xcb, 0x68, 0x85, 0x96, 0x77, 0xe8, 0xfb, 0xa9 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 16, + { + 0xd2, 0xfd, 0xf8, 0x3a, 0xc1, 0xb4, 0x39, 0x23, + 0x2e, 0xaa, 0xcc, 0x98, 0x0a, 0x02, 0xda, 0x33 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testcfb1", + { + 0x8d, 0x5a, 0x2c, 0x83, 0xa7, 0xc7, 0x0a, 0x61, + 0xd6, 0x1b, 0x34, 0xb5, 0x1f, 0xdf, 0x42, 0x68, + 0x66, 0x71, 0xa3, 0x5d, 0x87, 0x4c, 0xfd, 0x84, + 0x99, 0x36, 0x63, 0xb6, 0x1e, 0xd6, 0x0d, 0xad + }, + G89_CFB, + { + 0x46, 0x60, 0x6f, 0x0d, 0x88, 0x34, 0x23, 0x5a + }, + { + 0x88, 0xb7, 0x75, 0x16, 0x74, 0xa5, 0xee, 0x2d, + 0x14, 0xfe, 0x91, 0x67, 0xd0, 0x5c, 0xcc, 0x40 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 16, + { + 0x90, 0xa2, 0x39, 0x66, 0xae, 0x01, 0xb9, 0xa3, + 0x52, 0x4e, 0xc8, 0xed, 0x6c, 0xdd, 0x88, 0x30 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testcnt1", + { + 0x59, 0x9f, 0x84, 0xba, 0xc3, 0xf3, 0xd2, 0xf1, + 0x60, 0xe1, 0xe3, 0xf2, 0x6a, 0x96, 0x1a, 0xf9, + 0x9c, 0x48, 0xb2, 0x4e, 0xbc, 0xbb, 0xbf, 0x7c, + 0xd8, 0xf3, 0xac, 0xcd, 0x96, 0x8d, 0x28, 0x6a + }, + G89_CNT, + { + 0x8d, 0xaf, 0xa8, 0xd1, 0x58, 0xed, 0x05, 0x8d + }, + { + 0x6e, 0x72, 0x62, 0xcc, 0xe3, 0x59, 0x36, 0x90, + 0x83, 0x3a, 0xfe, 0xa9, 0x1b, 0xc9, 0xbe, 0xce + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 16, + { + 0xb5, 0xa1, 0xf0, 0xe3, 0xce, 0x2f, 0x02, 0x1d, + 0x67, 0x61, 0x94, 0x34, 0x5c, 0x41, 0xe3, 0x6e + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testimit1", + { + 0x9d, 0x05, 0xb7, 0x9e, 0x90, 0xca, 0xd0, 0x0a, + 0x2c, 0xda, 0xd2, 0x2e, 0xf4, 0xe8, 0x6f, 0x5c, + 0xf5, 0xdc, 0x37, 0x68, 0x19, 0x85, 0xb3, 0xbf, + 0xaa, 0x18, 0xc1, 0xc3, 0x05, 0x0a, 0x91, 0xa2 + }, + G89_IMIT, + { 0 }, + { + 0xf8, 0x1f, 0x08, 0xa3 + } + }, + /* + * Other paramsets and key meshing test cases. + */ + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 1039, + { + 0x8c, 0x9c, 0x44, 0x35, 0xfb, 0xe9, 0xa5, 0xa3, + 0xa0, 0xae, 0x28, 0x56, 0x91, 0x10, 0x8e, 0x1e , + 0xd2, 0xbb, 0x18, 0x53, 0x81, 0x27, 0x0d, 0xa6, + 0x68, 0x59, 0x36, 0xc5, 0x81, 0x62, 0x9a, 0x8e, + 0x7d, 0x50, 0xf1, 0x6f, 0x97, 0x62, 0x29, 0xec, + 0x80, 0x51, 0xe3, 0x7d, 0x6c, 0xc4, 0x07, 0x95, + 0x28, 0x63, 0xdc, 0xb4, 0xb9, 0x2d, 0xb8, 0x13, + 0xb1, 0x05, 0xb5, 0xf9, 0xeb, 0x75, 0x37, 0x4e, + 0xf7, 0xbf, 0x51, 0xf1, 0x98, 0x86, 0x43, 0xc4, + 0xe4, 0x3d, 0x3e, 0xa7, 0x62, 0xec, 0x41, 0x59, + 0xe0, 0xbd, 0xfb, 0xb6, 0xfd, 0xec, 0xe0, 0x77, + 0x13, 0xd2, 0x59, 0x90, 0xa1, 0xb8, 0x97, 0x6b, + 0x3d, 0x8b, 0x7d, 0xfc, 0x9d, 0xca, 0x82, 0x73, + 0x32, 0x70, 0x0a, 0x74, 0x03, 0xc6, 0x0c, 0x26, + 0x7f, 0x56, 0xf0, 0x9d, 0xb2, 0xeb, 0x71, 0x40, + 0xd7, 0xc3, 0xb1, 0xa7, 0xc5, 0x1e, 0x20, 0x17, + 0xb3, 0x50, 0x1d, 0x8a, 0x6e, 0x19, 0xcb, 0xbe, + 0x20, 0x86, 0x2b, 0xd6, 0x1c, 0xfd, 0xb4, 0xb7, + 0x5d, 0x9a, 0xb3, 0xe3, 0x7d, 0x15, 0x7a, 0x35, + 0x01, 0x9f, 0x5d, 0x65, 0x89, 0x4b, 0x34, 0xc6, + 0xf4, 0x81, 0x3f, 0x78, 0x30, 0xcf, 0xe9, 0x15, + 0x90, 0x9a, 0xf9, 0xde, 0xba, 0x63, 0xd0, 0x19, + 0x14, 0x66, 0x3c, 0xb9, 0xa4, 0xb2, 0x84, 0x94, + 0x02, 0xcf, 0xce, 0x20, 0xcf, 0x76, 0xe7, 0xc5, + 0x48, 0xf7, 0x69, 0x3a, 0x5d, 0xec, 0xaf, 0x41, + 0xa7, 0x12, 0x64, 0x83, 0xf5, 0x99, 0x1e, 0x9e, + 0xb2, 0xab, 0x86, 0x16, 0x00, 0x23, 0x8e, 0xe6, + 0xd9, 0x80, 0x0b, 0x6d, 0xc5, 0x93, 0xe2, 0x5c, + 0x8c, 0xd8, 0x5e, 0x5a, 0xae, 0x4a, 0x85, 0xfd, + 0x76, 0x01, 0xea, 0x30, 0xf3, 0x78, 0x34, 0x10, + 0x72, 0x51, 0xbc, 0x9f, 0x76, 0xce, 0x1f, 0xd4, + 0x8f, 0x33, 0x50, 0x34, 0xc7, 0x4d, 0x7b, 0xcf, + 0x91, 0x63, 0x7d, 0x82, 0x9e, 0xa1, 0x23, 0x45, + 0xf5, 0x45, 0xac, 0x98, 0x7a, 0x48, 0xff, 0x64, + 0xd5, 0x59, 0x47, 0xde, 0x2b, 0x3f, 0xfa, 0xec, + 0x50, 0xe0, 0x81, 0x60, 0x8b, 0xc3, 0xfc, 0x80, + 0x98, 0x17, 0xc7, 0xa3, 0xc2, 0x57, 0x3d, 0xab, + 0x91, 0x67, 0xf5, 0xc4, 0xab, 0x92, 0xc8, 0xd6, + 0x3b, 0x6b, 0x3f, 0xff, 0x15, 0x6b, 0xcf, 0x53, + 0x65, 0x02, 0xf1, 0x74, 0xca, 0xa9, 0xbe, 0x24, + 0xd2, 0xf0, 0xb7, 0x26, 0xa8, 0xd7, 0x6d, 0xed, + 0x90, 0x36, 0x7b, 0x3e, 0x41, 0xa9, 0x7f, 0xa3, + 0x1b, 0xf4, 0x43, 0xc5, 0x51, 0xbe, 0x28, 0x59, + 0xe9, 0x45, 0x26, 0x49, 0x38, 0x32, 0xf8, 0xf3, + 0x92, 0x6e, 0x30, 0xcc, 0xb0, 0xa0, 0xf9, 0x01, + 0x14, 0xc8, 0xba, 0xd9, 0xf0, 0x2a, 0x29, 0xe2, + 0x52, 0x9a, 0x76, 0x95, 0x3a, 0x16, 0x32, 0xec, + 0xf4, 0x10, 0xec, 0xee, 0x47, 0x00, 0x70, 0x19, + 0xe4, 0x72, 0x35, 0x66, 0x44, 0x53, 0x2d, 0xa2, + 0xf3, 0xaa, 0x7e, 0x8a, 0x33, 0x13, 0xcd, 0xc8, + 0xbf, 0x0e, 0x40, 0x90, 0x00, 0xe4, 0x42, 0xc3, + 0x09, 0x84, 0xe1, 0x66, 0x17, 0xa2, 0xaf, 0x03, + 0xab, 0x6b, 0xa1, 0xec, 0xfb, 0x17, 0x72, 0x81, + 0xfe, 0x9a, 0x9f, 0xf4, 0xb2, 0x33, 0x1f, 0xae, + 0x0c, 0xd1, 0x6a, 0xae, 0x19, 0xb8, 0xaf, 0xec, + 0xe3, 0xea, 0x00, 0xf8, 0xac, 0x87, 0x07, 0x5f, + 0x6d, 0xb0, 0xac, 0x6b, 0x22, 0x48, 0x36, 0xbf, + 0x22, 0x18, 0xb0, 0x03, 0x9f, 0x6c, 0x70, 0x45, + 0x36, 0xf0, 0x6b, 0xc6, 0xc2, 0xa5, 0x72, 0x2c, + 0xd8, 0xe0, 0x27, 0x3d, 0xec, 0x56, 0x07, 0x05, + 0x7d, 0x83, 0xa1, 0x65, 0x7d, 0x41, 0x5b, 0xcd, + 0x77, 0x24, 0xe5, 0xaa, 0x76, 0x47, 0xd0, 0x50, + 0xf6, 0xe7, 0xb5, 0x59, 0x75, 0x31, 0x27, 0xef, + 0xd8, 0xa6, 0x4e, 0x7f, 0xb8, 0x40, 0xb1, 0xdf, + 0x53, 0x14, 0xed, 0xf1, 0x68, 0x5f, 0xfc, 0x3f, + 0x02, 0xdb, 0x05, 0xeb, 0x31, 0xe4, 0x2c, 0x7f, + 0x32, 0xb5, 0x70, 0x8e, 0x75, 0x85, 0xa4, 0x5c, + 0x16, 0x23, 0x37, 0xf2, 0x10, 0x79, 0xcb, 0xdc, + 0xf8, 0x1c, 0x25, 0xc2, 0xa1, 0x3d, 0x9c, 0x33, + 0x6c, 0xed, 0xc3, 0xe7, 0xf3, 0x02, 0x87, 0x82, + 0x4e, 0xfb, 0xac, 0xb3, 0x2d, 0xfc, 0xf8, 0x0d, + 0x1d, 0x4a, 0x39, 0xd4, 0xb3, 0x09, 0xbb, 0xe9, + 0x25, 0xc7, 0xec, 0x6a, 0x87, 0x72, 0x84, 0xed, + 0x12, 0x60, 0x19, 0x64, 0xeb, 0x16, 0x2a, 0x5b, + 0x10, 0x76, 0x27, 0xff, 0x7b, 0xe4, 0xae, 0xe5, + 0xa4, 0x04, 0x02, 0x7f, 0xbb, 0x0a, 0xb5, 0xf4, + 0x05, 0xa5, 0x56, 0x1c, 0x53, 0x31, 0x7a, 0x93, + 0xba, 0x16, 0x15, 0xab, 0x62, 0x60, 0xfc, 0xde, + 0x72, 0x36, 0x6e, 0x28, 0xaf, 0x98, 0x0d, 0xe6, + 0xf4, 0xde, 0x60, 0xa7, 0x7e, 0x06, 0x07, 0x86, + 0xf3, 0x94, 0xb6, 0x6d, 0x0d, 0x93, 0xa6, 0xbc, + 0x60, 0x70, 0x33, 0xac, 0x3f, 0xa1, 0xa8, 0x4a, + 0x20, 0x61, 0xb6, 0xb5, 0x43, 0xa3, 0x15, 0x5a, + 0x00, 0xbe, 0x76, 0x98, 0x57, 0x72, 0xab, 0x7a, + 0x0e, 0x18, 0x93, 0x82, 0x3a, 0x18, 0x78, 0x6e, + 0x71, 0x7b, 0x78, 0x4f, 0x7e, 0x8c, 0xde, 0x7a, + 0x62, 0xb5, 0x0a, 0x7c, 0x45, 0x1d, 0x16, 0xd5, + 0xc3, 0x8c, 0x9b, 0x25, 0xb4, 0x50, 0x90, 0xcd, + 0x96, 0x93, 0xad, 0x0f, 0xd4, 0x43, 0xcb, 0x49, + 0x0f, 0xfc, 0x5a, 0x31, 0xf4, 0x19, 0xb7, 0xd4, + 0xeb, 0x4d, 0x40, 0x58, 0xd0, 0x3b, 0xc8, 0xe0, + 0x4a, 0x54, 0x2f, 0xdb, 0x22, 0xc3, 0x29, 0x7b, + 0x40, 0x90, 0x61, 0x43, 0xd3, 0x7e, 0xe2, 0x30, + 0x2b, 0x48, 0x3c, 0xce, 0x90, 0x93, 0xb1, 0x8b, + 0x31, 0x96, 0x65, 0x6d, 0x57, 0x8b, 0x9d, 0x4d, + 0x53, 0xf0, 0x83, 0x1c, 0xe5, 0xa1, 0x9d, 0x55, + 0xe3, 0xbf, 0x7e, 0xca, 0x1a, 0x74, 0x66, 0x14, + 0xcc, 0x47, 0x43, 0xd9, 0xbb, 0xef, 0x97, 0x7d, + 0xb7, 0x6e, 0xff, 0xf1, 0x22, 0xf8, 0x10, 0x2d, + 0x3f, 0xcd, 0x49, 0x96, 0xd9, 0x09, 0x11, 0xb8, + 0x33, 0xd0, 0x23, 0x9a, 0xfa, 0x16, 0xcb, 0x50, + 0x26, 0x57, 0x24, 0x5c, 0x0e, 0xba, 0xf0, 0x3f, + 0x37, 0x2f, 0xa3, 0xf7, 0x18, 0x57, 0x48, 0x48, + 0x95, 0xcf, 0xef, 0x87, 0x67, 0x2a, 0xe9, 0xb6, + 0x8a, 0x21, 0x36, 0x7f, 0xff, 0x48, 0x6c, 0x46, + 0x35, 0x57, 0xf2, 0xbc, 0x48, 0x67, 0x8f, 0x63, + 0x23, 0x78, 0x11, 0x2b, 0xc2, 0x08, 0xde, 0x51, + 0xe8, 0x8b, 0x92, 0x29, 0xf9, 0x9a, 0x9e, 0xad, + 0xed, 0x0f, 0xeb, 0xa2, 0xd2, 0x40, 0x92, 0xd4, + 0xde, 0x62, 0x95, 0x76, 0xfd, 0x6e, 0x3c, 0xbf, + 0xc0, 0xd7, 0x0d, 0xe5, 0x1b, 0xa4, 0xc7, 0x18, + 0xe1, 0x58, 0xa4, 0x56, 0xef, 0x2e, 0x17, 0x1b, + 0x75, 0xcb, 0xbc, 0xf9, 0x2a, 0x95, 0x71, 0xa7, + 0x1d, 0x7f, 0xe7, 0x73, 0x63, 0x05, 0x6b, 0x19, + 0x4c, 0xf4, 0x22, 0x14, 0xc4, 0x59, 0x88, 0x66, + 0x92, 0x86, 0x61, 0x5c, 0x6a, 0xae, 0xec, 0x58, + 0xff, 0xc9, 0xf2, 0x44, 0xd4, 0xa2, 0xf5, 0x98, + 0xeb, 0x5f, 0x09, 0xbc, 0x8a, 0xbf, 0x3c, 0xb4, + 0x3e, 0xb1, 0x20, 0x05, 0x44, 0x96, 0x79, 0x0a, + 0x40, 0x92, 0x7f, 0x9d, 0xd1, 0xaf, 0xbc, 0x90, + 0x95, 0x0a, 0x81, 0xd4, 0xa7, 0xc6, 0xb8, 0xe0, + 0xe4, 0x39, 0x30, 0x1d, 0x79, 0xc0, 0xe5, 0xfa, + 0xb4, 0xe9, 0x63, 0xb4, 0x09, 0x72, 0x3b, 0x3e, + 0xd9, 0xf6, 0xd9, 0x10, 0x21, 0x18, 0x7e, 0xe5, + 0xad, 0x81, 0xd7, 0xd5, 0x82, 0xd0, 0x8c, 0x3b, + 0x38, 0x95, 0xf8, 0x92, 0x01, 0xa9, 0x92, 0x00, + 0x70, 0xd1, 0xa7, 0x88, 0x77, 0x1f, 0x3a, 0xeb, + 0xb5, 0xe4, 0xf5, 0x9d, 0xc7, 0x37, 0x86, 0xb2, + 0x12, 0x46, 0x34, 0x19, 0x72, 0x8c, 0xf5, 0x8c, + 0xf6, 0x78, 0x98, 0xe0, 0x7c, 0xd3, 0xf4 + }, + "id-Gost28147-89-CryptoPro-B-ParamSet", + "testcfb2", + { + 0x48, 0x0c, 0x74, 0x1b, 0x02, 0x6b, 0x55, 0xd5, + 0xb6, 0x6d, 0xd7, 0x1d, 0x40, 0x48, 0x05, 0x6b, + 0x6d, 0xeb, 0x3c, 0x29, 0x0f, 0x84, 0x80, 0x23, + 0xee, 0x0d, 0x47, 0x77, 0xe3, 0xfe, 0x61, 0xc9 + }, + G89_CFB, + { + 0x1f, 0x3f, 0x82, 0x1e, 0x0d, 0xd8, 0x1e, 0x22 + }, + { + 0x23, 0xc6, 0x7f, 0x20, 0xa1, 0x23, 0x58, 0xbc, + 0x7b, 0x05, 0xdb, 0x21, 0x15, 0xcf, 0x96, 0x41, + 0xc7, 0x88, 0xef, 0x76, 0x5c, 0x49, 0xdb, 0x42, + 0xbf, 0xf3, 0xc0, 0xf5, 0xbd, 0x5d, 0xd9, 0x8e, + 0xaf, 0x3d, 0xf4, 0xe4, 0xda, 0x88, 0xbd, 0xbc, + 0x47, 0x5d, 0x76, 0x07, 0xc9, 0x5f, 0x54, 0x1d, + 0x1d, 0x6a, 0xa1, 0x2e, 0x18, 0xd6, 0x60, 0x84, + 0x02, 0x18, 0x37, 0x92, 0x92, 0x15, 0xab, 0x21, + 0xee, 0x21, 0xcc, 0x71, 0x6e, 0x51, 0xd9, 0x2b, + 0xcc, 0x81, 0x97, 0x3f, 0xeb, 0x45, 0x99, 0xb8, + 0x1b, 0xda, 0xff, 0x90, 0xd3, 0x41, 0x06, 0x9c, + 0x3f, 0xfb, 0xe4, 0xb2, 0xdc, 0xc9, 0x03, 0x0d, + 0xa7, 0xae, 0xd7, 0x7d, 0x02, 0xb8, 0x32, 0xab, + 0xf3, 0x65, 0xa3, 0x65, 0x6c, 0x4e, 0xe4, 0xa2, + 0x5e, 0x9e, 0xee, 0xcd, 0xde, 0x79, 0x36, 0x6b, + 0x1b, 0xe1, 0x3c, 0xdf, 0x10, 0xad, 0x4f, 0x02, + 0xe1, 0x14, 0xaa, 0x09, 0xb4, 0x0b, 0x76, 0xeb, + 0x69, 0x38, 0x20, 0x02, 0xcb, 0x8e, 0xc0, 0xdf, + 0xca, 0x48, 0x74, 0xc3, 0x31, 0xad, 0x42, 0x2c, + 0x51, 0x9b, 0xd0, 0x6a, 0xc1, 0x36, 0xd7, 0x21, + 0xdf, 0xb0, 0x45, 0xba, 0xca, 0x7f, 0x35, 0x20, + 0x28, 0xbb, 0xc1, 0x76, 0xfd, 0x43, 0x5d, 0x23, + 0x7d, 0x31, 0x84, 0x1a, 0x97, 0x4d, 0x83, 0xaa, + 0x7e, 0xf1, 0xc4, 0xe6, 0x83, 0xac, 0x0d, 0xef, + 0xef, 0x3c, 0xa4, 0x7c, 0x48, 0xe4, 0xc8, 0xca, + 0x0d, 0x7d, 0xea, 0x7c, 0x45, 0xd7, 0x73, 0x50, + 0x25, 0x1d, 0x01, 0xc4, 0x02, 0x1a, 0xcd, 0xe0, + 0x38, 0x5b, 0xa8, 0x5a, 0x16, 0x9a, 0x10, 0x59, + 0x74, 0xd7, 0x19, 0xc6, 0xf3, 0xb5, 0x17, 0xf6, + 0x59, 0x8d, 0x62, 0xaf, 0x44, 0xe8, 0xdc, 0xe9, + 0xc1, 0x76, 0xf1, 0xd0, 0xbd, 0x29, 0xd7, 0xec, + 0x1d, 0xac, 0x57, 0xdb, 0x1a, 0x3f, 0xd8, 0xf6, + 0x6e, 0xb6, 0xe6, 0xdf, 0x36, 0xe7, 0x89, 0xce, + 0x56, 0x35, 0x43, 0x1c, 0x7d, 0x57, 0x79, 0x0e, + 0xd8, 0xf4, 0xd7, 0xa7, 0x0d, 0xc6, 0x8f, 0x91, + 0x66, 0x67, 0x82, 0x0f, 0x49, 0xc9, 0xc5, 0x65, + 0x81, 0xa1, 0x39, 0x5a, 0x53, 0x9f, 0x02, 0xa5, + 0xd5, 0x36, 0x22, 0xa8, 0xa8, 0x1c, 0x37, 0x0e, + 0x76, 0x46, 0xdf, 0xbd, 0x6a, 0xdb, 0xfc, 0x1b, + 0xbd, 0x10, 0xb8, 0xb1, 0xbc, 0x72, 0x4c, 0x58, + 0x4a, 0xda, 0x6d, 0x66, 0x00, 0xda, 0x7a, 0x66, + 0xa0, 0xe7, 0x3b, 0x39, 0xa3, 0xf7, 0x05, 0x07, + 0xfa, 0x21, 0x4b, 0xc7, 0x94, 0xc0, 0xd3, 0x7b, + 0x19, 0x02, 0x5d, 0x4a, 0x10, 0xf1, 0xc2, 0x0f, + 0x19, 0x68, 0x27, 0xc7, 0x7d, 0xbf, 0x55, 0x03, + 0x57, 0x7d, 0xaf, 0x77, 0xae, 0x80, 0x2f, 0x7a, + 0xe6, 0x1f, 0x4b, 0xdc, 0x15, 0x18, 0xc0, 0x62, + 0xa1, 0xe8, 0xd9, 0x1c, 0x9e, 0x8c, 0x96, 0x39, + 0xc1, 0xc4, 0x88, 0xf7, 0x0c, 0xe1, 0x04, 0x84, + 0x68, 0x51, 0xce, 0xf1, 0x90, 0xda, 0x7f, 0x76, + 0xc8, 0xc0, 0x88, 0xef, 0x8e, 0x15, 0x25, 0x3e, + 0x7b, 0xe4, 0x79, 0xb5, 0x66, 0x2d, 0x9c, 0xd1, + 0x13, 0xda, 0xd0, 0xd5, 0x46, 0xd5, 0x8d, 0x46, + 0x18, 0x07, 0xee, 0xd8, 0xc9, 0x64, 0xe3, 0xbe, + 0x0e, 0x68, 0x27, 0x09, 0x96, 0x26, 0xf6, 0xe2, + 0x19, 0x61, 0x3f, 0xf4, 0x58, 0x27, 0x0a, 0xeb, + 0xce, 0x7c, 0xb6, 0x68, 0x92, 0xe7, 0x12, 0x3b, + 0x31, 0xd4, 0x48, 0xdf, 0x35, 0x8d, 0xf4, 0x86, + 0x42, 0x2a, 0x15, 0x4b, 0xe8, 0x19, 0x1f, 0x26, + 0x65, 0x9b, 0xa8, 0xda, 0x4b, 0x79, 0x1f, 0x8e, + 0xe6, 0x13, 0x7e, 0x49, 0x8f, 0xc1, 0xce, 0xdc, + 0x5e, 0x64, 0x74, 0xce, 0x02, 0x78, 0xe0, 0xcf, + 0xa0, 0xed, 0x5e, 0x31, 0x74, 0xd1, 0xd0, 0xb4, + 0xee, 0x70, 0x19, 0x14, 0x3c, 0x8f, 0x16, 0xa6, + 0xcf, 0x12, 0x93, 0x15, 0x88, 0xeb, 0x91, 0x65, + 0x76, 0x98, 0xfd, 0xa1, 0x94, 0x30, 0xba, 0x43, + 0x62, 0x65, 0x40, 0x04, 0x77, 0x9e, 0xd6, 0xab, + 0x8b, 0x0d, 0x93, 0x80, 0x50, 0x5f, 0xa2, 0x76, + 0x20, 0xa7, 0xd6, 0x9c, 0x27, 0x15, 0x27, 0xbc, + 0xa5, 0x5a, 0xbf, 0xe9, 0x92, 0x82, 0x05, 0xa8, + 0x41, 0xe9, 0xb5, 0x60, 0xd5, 0xc0, 0xd7, 0x4b, + 0xad, 0x38, 0xb2, 0xe9, 0xd1, 0xe5, 0x51, 0x5f, + 0x24, 0x78, 0x24, 0x9a, 0x23, 0xd2, 0xc2, 0x48, + 0xbd, 0x0e, 0xf1, 0x37, 0x72, 0x91, 0x87, 0xb0, + 0x4e, 0xbd, 0x99, 0x6b, 0x2c, 0x01, 0xb6, 0x79, + 0x69, 0xec, 0x0c, 0xed, 0xe5, 0x3f, 0x50, 0x64, + 0x7c, 0xb9, 0xdd, 0xe1, 0x92, 0x81, 0xb5, 0xd0, + 0xcb, 0x17, 0x83, 0x86, 0x8b, 0xea, 0x4f, 0x93, + 0x08, 0xbc, 0x22, 0x0c, 0xef, 0xe8, 0x0d, 0xf5, + 0x9e, 0x23, 0xe1, 0xf9, 0xb7, 0x6b, 0x45, 0x0b, + 0xcb, 0xa9, 0xb6, 0x4d, 0x28, 0x25, 0xba, 0x3e, + 0x86, 0xf2, 0x75, 0x47, 0x5d, 0x9d, 0x6b, 0xf6, + 0x8a, 0x05, 0x58, 0x73, 0x3d, 0x00, 0xde, 0xfd, + 0x69, 0xb1, 0x61, 0x16, 0xf5, 0x2e, 0xb0, 0x9f, + 0x31, 0x6a, 0x00, 0xb9, 0xef, 0x71, 0x63, 0x47, + 0xa3, 0xca, 0xe0, 0x40, 0xa8, 0x7e, 0x02, 0x04, + 0xfe, 0xe5, 0xce, 0x48, 0x73, 0xe3, 0x94, 0xcf, + 0xe2, 0xff, 0x29, 0x7e, 0xf6, 0x32, 0xbb, 0xb7, + 0x55, 0x12, 0x21, 0x7a, 0x9c, 0x75, 0x04, 0x0c, + 0xb4, 0x7c, 0xb0, 0x3d, 0x40, 0xb3, 0x11, 0x9a, + 0x7a, 0x9a, 0x13, 0xfb, 0x77, 0xa7, 0x51, 0x68, + 0xf7, 0x05, 0x47, 0x3b, 0x0f, 0x52, 0x5c, 0xe6, + 0xc2, 0x99, 0x3a, 0x37, 0x54, 0x5c, 0x4f, 0x2b, + 0xa7, 0x01, 0x08, 0x74, 0xbc, 0x91, 0xe3, 0xe2, + 0xfe, 0x65, 0x94, 0xfd, 0x3d, 0x18, 0xe0, 0xf0, + 0x62, 0xed, 0xc2, 0x10, 0x82, 0x9c, 0x58, 0x7f, + 0xb2, 0xa3, 0x87, 0x8a, 0x74, 0xd9, 0xc1, 0xfb, + 0x84, 0x28, 0x17, 0xc7, 0x2b, 0xcb, 0x53, 0x1f, + 0x4e, 0x8a, 0x82, 0xfc, 0xb4, 0x3f, 0xc1, 0x47, + 0x25, 0xf3, 0x21, 0xdc, 0x4c, 0x2d, 0x08, 0xfa, + 0xe7, 0x0f, 0x03, 0xa9, 0x68, 0xde, 0x6b, 0x41, + 0xa0, 0xf9, 0x41, 0x6c, 0x57, 0x4d, 0x3a, 0x0e, + 0xea, 0x51, 0xca, 0x9f, 0x97, 0x11, 0x7d, 0xf6, + 0x8e, 0x88, 0x63, 0x67, 0xc9, 0x65, 0x13, 0xca, + 0x38, 0xed, 0x35, 0xbe, 0xf4, 0x27, 0xa9, 0xfc, + 0xa9, 0xe6, 0xc3, 0x40, 0x86, 0x08, 0x39, 0x72, + 0x37, 0xee, 0xb2, 0x87, 0x09, 0x96, 0xb7, 0x40, + 0x87, 0x36, 0x92, 0xc1, 0x5d, 0x6a, 0x2c, 0x43, + 0xca, 0x25, 0xc8, 0x35, 0x37, 0x2d, 0xb5, 0xa9, + 0x27, 0x44, 0x50, 0xf2, 0x6d, 0x22, 0x75, 0x41, + 0x77, 0x2a, 0xdb, 0xb1, 0x8c, 0x6d, 0x05, 0xe8, + 0xc9, 0x99, 0xc7, 0x08, 0xf9, 0x14, 0x8f, 0x78, + 0xa9, 0x8f, 0xc2, 0x5a, 0x7a, 0x65, 0xc5, 0xd8, + 0x86, 0xbb, 0x72, 0x69, 0x6b, 0x6b, 0x45, 0x83, + 0x5b, 0xb1, 0xf7, 0xcd, 0x16, 0x73, 0xee, 0xe9, + 0x80, 0x85, 0xfe, 0x8e, 0xe1, 0xae, 0x53, 0x8f, + 0xde, 0xbe, 0x48, 0x8b, 0x59, 0xef, 0xf6, 0x7e, + 0xd8, 0xb5, 0xa8, 0x47, 0xc0, 0x4e, 0x15, 0x58, + 0xca, 0xd3, 0x2f, 0xf8, 0x6c, 0xa6, 0x3d, 0x78, + 0x4d, 0x7a, 0x54, 0xd6, 0x10, 0xe5, 0xcc, 0x05, + 0xe2, 0x29, 0xb5, 0x86, 0x07, 0x39, 0x7d, 0x78, + 0x8e, 0x5a, 0x8f, 0x83, 0x4c, 0xe7, 0x3d, 0x68, + 0x3e, 0xe5, 0x02, 0xe6, 0x64, 0x4f, 0x5e, 0xb4, + 0x49, 0x77, 0xf0, 0xc0, 0xfa, 0x6f, 0xc8, 0xfb, + 0x9f, 0x84, 0x6f, 0x55, 0xfb, 0x30, 0x5e, 0x89, + 0x93, 0xa9, 0xf3, 0xa6, 0xa3, 0xd7, 0x26, 0xbb, + 0xd8, 0xa8, 0xd9, 0x95, 0x1d, 0xfe, 0xfc, 0xd7, + 0xa8, 0x93, 0x66, 0x2f, 0x04, 0x53, 0x06, 0x64, + 0x7f, 0x31, 0x29, 0xae, 0xb7, 0x9f, 0xba, 0xc4, + 0x6d, 0x68, 0xd1, 0x24, 0x32, 0xf4, 0x11 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 4, + { + 0x07, 0x9c, 0x91, 0xbe + }, + "id-Gost28147-89-CryptoPro-C-ParamSet", + "testcfb3", + { + 0x77, 0xc3, 0x45, 0x8e, 0xf6, 0x42, 0xe7, 0x04, + 0x8e, 0xfc, 0x08, 0xe4, 0x70, 0x96, 0xd6, 0x05, + 0x93, 0x59, 0x02, 0x6d, 0x6f, 0x97, 0xca, 0xe9, + 0xcf, 0x89, 0x44, 0x4b, 0xde, 0x6c, 0x22, 0x1d + }, + G89_CFB, + { + 0x43, 0x7c, 0x3e, 0x8e, 0x2f, 0x2a, 0x00, 0x98 + }, + { + 0x19, 0x35, 0x81, 0x34 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 9, + { + 0x2f, 0x31, 0xd8, 0x83, 0xb4, 0x20, 0xe8, 0x6e, + 0xda + }, + "id-Gost28147-89-CryptoPro-D-ParamSet", + "testcfb4", + { + 0x38, 0x9f, 0xe8, 0x37, 0xff, 0x9c, 0x5d, 0x29, + 0xfc, 0x48, 0x55, 0xa0, 0x87, 0xea, 0xe8, 0x40, + 0x20, 0x87, 0x5b, 0xb2, 0x01, 0x15, 0x55, 0xa7, + 0xe3, 0x2d, 0xcb, 0x3d, 0xd6, 0x59, 0x04, 0x73 + }, + G89_CFB, + { + 0xc5, 0xa2, 0xd2, 0x1f, 0x2f, 0xdf, 0xb8, 0xeb + }, + { + 0x6d, 0xa4, 0xed, 0x40, 0x08, 0x88, 0x71, 0xad, + 0x16 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 5242880+8, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test5Mcfb", + { + 0x61, 0x58, 0x44, 0x5a, 0x41, 0xf6, 0xc7, 0x0f, + 0x6b, 0xdb, 0x51, 0x91, 0x6a, 0xf6, 0x81, 0x30, + 0x8c, 0xa7, 0x98, 0xdd, 0x38, 0x35, 0x8a, 0x60, + 0x85, 0xb4, 0xf0, 0xf9, 0x43, 0xa2, 0x7d, 0x9a + }, + G89_CFB, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0x1c, 0x16, 0xa0, 0xe9, 0x63, 0x94, 0xfe, 0x38, + 0x37, 0xa7, 0x9b, 0x70, 0x25, 0x2e, 0xd6, 0x00 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + U64(4294967296)+16, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test4Gcfb", + { + 0xae, 0x57, 0xa2, 0xdd, 0xa4, 0xef, 0x4f, 0x96, + 0xb8, 0x94, 0xa5, 0xd1, 0x1b, 0xc8, 0x9b, 0x42, + 0xa5, 0x24, 0xcc, 0x89, 0x5c, 0xb8, 0x92, 0x52, + 0xc1, 0x12, 0x6a, 0xb0, 0x9a, 0x26, 0xe8, 0x06 + }, + G89_CFB, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0x2e, 0x62, 0xb0, 0x2e, 0xc7, 0x87, 0x4b, 0x29, + 0x33, 0x16, 0x6b, 0xb4, 0xd6, 0x61, 0x66, 0xd9 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 1037, + { + 0x3d, 0x0b, 0x69, 0xf7, 0xa8, 0xe4, 0xfc, 0x99, + 0x22, 0x2e, 0xee, 0xd1, 0x63, 0x12, 0xfe, 0xa8, + 0x9d, 0xcb, 0x6c, 0x4d, 0x48, 0x8c, 0xe8, 0xbd, + 0x8b, 0x60, 0xf1, 0xbf, 0x7b, 0xe3, 0x79, 0xd5, + 0x2b, 0x25, 0x97, 0x13, 0xef, 0x35, 0xda, 0xf4, + 0xbc, 0x77, 0xce, 0xea, 0xe9, 0x3f, 0xa4, 0xb6, + 0x01, 0xd5, 0x73, 0x29, 0x58, 0xda, 0xd7, 0x67, + 0x17, 0xac, 0xe4, 0x75, 0x2f, 0x57, 0x23, 0xac, + 0x96, 0x21, 0xc7, 0x62, 0x2d, 0xf7, 0x32, 0xb5, + 0x44, 0x5f, 0x72, 0xb1, 0x5f, 0xba, 0x1b, 0x1e, + 0xdb, 0x4a, 0x09, 0x8c, 0x92, 0x61, 0xa2, 0xb0, + 0x49, 0x68, 0xe5, 0xb3, 0xa2, 0x8f, 0x13, 0x4b, + 0xf5, 0x4d, 0x84, 0xda, 0xab, 0xa0, 0xb6, 0xd1, + 0x5a, 0x63, 0x19, 0xe8, 0xa2, 0x09, 0xf6, 0x76, + 0x6f, 0x9b, 0x48, 0x0a, 0x15, 0x5d, 0xb7, 0x20, + 0x21, 0x9a, 0x2e, 0xb9, 0x6d, 0xfa, 0x1e, 0xc2, + 0x0e, 0xef, 0x15, 0xab, 0x59, 0x01, 0xfe, 0x43, + 0x90, 0xf2, 0x62, 0xca, 0x4a, 0x9a, 0x48, 0x38, + 0xab, 0x6f, 0x9d, 0x21, 0xb3, 0xad, 0xa7, 0x60, + 0x46, 0xe3, 0xef, 0xd0, 0xe3, 0x1d, 0xc5, 0xe1, + 0xb8, 0xa1, 0xe2, 0x99, 0x20, 0xc5, 0x76, 0xcc, + 0xaa, 0x8a, 0xa9, 0x45, 0x55, 0xa0, 0x78, 0x00, + 0x64, 0xde, 0xcf, 0x5b, 0xdf, 0x26, 0x48, 0xcd, + 0xba, 0x8a, 0xb5, 0xfb, 0xfd, 0x4a, 0xd5, 0xc4, + 0xe0, 0x43, 0xa6, 0x71, 0x90, 0xa4, 0x8b, 0xca, + 0x2e, 0x88, 0x7b, 0xac, 0xb2, 0xdc, 0xf2, 0x01, + 0xcb, 0xda, 0x6e, 0x91, 0x27, 0x28, 0x44, 0x88, + 0x9a, 0xd2, 0x12, 0xf1, 0xa6, 0xf5, 0xb7, 0x61, + 0xce, 0x79, 0x62, 0x52, 0x3c, 0xe6, 0x14, 0x73, + 0xd1, 0x41, 0x92, 0x50, 0xbd, 0xdc, 0x3b, 0xd0, + 0xa7, 0x11, 0x8c, 0x3a, 0xe4, 0x2d, 0xf2, 0x52, + 0xd3, 0x2f, 0x7c, 0x8e, 0x54, 0x90, 0x4e, 0x23, + 0xae, 0xb3, 0xa0, 0xf3, 0x25, 0x7e, 0x66, 0xaa, + 0x0f, 0x6f, 0x81, 0x72, 0x77, 0xbb, 0xd3, 0x47, + 0xe8, 0x05, 0xff, 0xe1, 0x5b, 0xc9, 0x37, 0x50, + 0x33, 0x49, 0x17, 0xaf, 0xab, 0x1d, 0xe1, 0x15, + 0xf2, 0xe5, 0x98, 0x5e, 0x2d, 0x05, 0x1f, 0x0d, + 0x55, 0x97, 0xed, 0xff, 0x5e, 0xe0, 0x0f, 0xc3, + 0x9c, 0xbd, 0x82, 0xc2, 0x06, 0xbe, 0x45, 0x66, + 0xae, 0x33, 0xbe, 0x28, 0x48, 0xe9, 0x2d, 0x1a, + 0xe6, 0x65, 0x8e, 0xdf, 0x76, 0x03, 0x73, 0x4b, + 0xc0, 0x80, 0x71, 0xf9, 0xac, 0xba, 0xa0, 0xb0, + 0x19, 0x1a, 0x0a, 0xd4, 0x35, 0x12, 0x88, 0x76, + 0x05, 0x75, 0x8f, 0x7c, 0xb5, 0xf0, 0x19, 0x75, + 0x6d, 0x05, 0xcb, 0x0d, 0xbc, 0x8d, 0xe9, 0xf0, + 0xd4, 0xdb, 0x3c, 0x3c, 0x29, 0x8e, 0x2c, 0x32, + 0x1d, 0xf7, 0xb6, 0x49, 0xcf, 0xdb, 0x63, 0xee, + 0x3c, 0xfa, 0x33, 0x73, 0x6f, 0xe4, 0x97, 0x4e, + 0x2f, 0xc9, 0x4c, 0x5c, 0x65, 0xfe, 0xea, 0xfb, + 0xc6, 0xdd, 0xc1, 0x1c, 0x47, 0x3f, 0xf4, 0x50, + 0x2f, 0xde, 0x1b, 0x5b, 0x0b, 0x16, 0xca, 0xb6, + 0x46, 0x44, 0xf2, 0xc1, 0x0d, 0xa1, 0x1d, 0xa6, + 0xdb, 0xf0, 0x3d, 0xb1, 0x6c, 0x05, 0x31, 0x85, + 0x8e, 0x74, 0xae, 0xf2, 0x39, 0x26, 0xf7, 0xc1, + 0xe7, 0x4c, 0xdd, 0x9d, 0x40, 0xb8, 0xf3, 0xc5, + 0xc2, 0x16, 0x64, 0x6b, 0xaa, 0xdb, 0x4b, 0x82, + 0x5c, 0xd3, 0x02, 0xd3, 0x8f, 0x26, 0x79, 0x8d, + 0xb0, 0x78, 0x70, 0x19, 0x58, 0x0c, 0xb4, 0x31, + 0x88, 0x44, 0x1c, 0x91, 0x6f, 0xf4, 0x52, 0x39, + 0xa8, 0xf5, 0xc0, 0x1b, 0xfe, 0xf2, 0x0e, 0x4b, + 0xac, 0x0a, 0xc2, 0x7e, 0x9c, 0x9b, 0xeb, 0x5d, + 0x4e, 0x4f, 0x42, 0xd8, 0x71, 0x0a, 0x97, 0x27, + 0x03, 0x14, 0x96, 0xa6, 0x3d, 0x04, 0xea, 0x9f, + 0x14, 0x14, 0x27, 0x4c, 0xd9, 0xa2, 0x89, 0x5f, + 0x65, 0x4a, 0xe1, 0x9d, 0x2c, 0xb8, 0xf8, 0xd4, + 0x8f, 0x2a, 0x57, 0x36, 0xcc, 0x06, 0x9c, 0x2c, + 0xc5, 0x13, 0x16, 0xdf, 0xfc, 0xae, 0x22, 0x16, + 0xa8, 0x2b, 0x71, 0x6f, 0x1d, 0xb3, 0x47, 0x54, + 0x3f, 0x2d, 0x0a, 0x68, 0x9f, 0x2e, 0xf6, 0x90, + 0xd8, 0xa1, 0x21, 0x09, 0xd4, 0x97, 0xb9, 0x7b, + 0x7f, 0x9b, 0x6a, 0xed, 0xd1, 0xf0, 0xe3, 0xb6, + 0x28, 0xc7, 0x62, 0x82, 0x00, 0xc9, 0x38, 0xa1, + 0x82, 0x78, 0xce, 0x87, 0xc8, 0x53, 0xac, 0x4f, + 0x2e, 0x31, 0xb9, 0x50, 0x7f, 0x36, 0x00, 0x4a, + 0x32, 0xe6, 0xd8, 0xbb, 0x59, 0x45, 0x0e, 0x91, + 0x1b, 0x38, 0xa9, 0xbc, 0xb9, 0x5e, 0x6c, 0x6a, + 0x9c, 0x03, 0x01, 0x1c, 0xde, 0xe8, 0x1f, 0x1e, + 0xe3, 0xde, 0x25, 0xa2, 0x56, 0x79, 0xe1, 0xbd, + 0x58, 0xc4, 0x93, 0xe6, 0xd0, 0x8a, 0x4d, 0x08, + 0xab, 0xf7, 0xaa, 0xc3, 0x7d, 0xc1, 0xee, 0x68, + 0x37, 0xbc, 0x78, 0x0b, 0x19, 0x68, 0x2b, 0x2b, + 0x2e, 0x6d, 0xc4, 0x6f, 0xaa, 0x3b, 0xc6, 0x19, + 0xcb, 0xf1, 0x58, 0xb9, 0x60, 0x85, 0x45, 0xae, + 0x52, 0x97, 0xba, 0x24, 0x32, 0x13, 0x72, 0x16, + 0x6e, 0x7b, 0xc1, 0x98, 0xac, 0xb1, 0xed, 0xb4, + 0xcc, 0x6c, 0xcf, 0x45, 0xfc, 0x50, 0x89, 0x80, + 0x8e, 0x7a, 0xa4, 0xd3, 0x64, 0x50, 0x63, 0x37, + 0xc9, 0x6c, 0xf1, 0xc4, 0x3d, 0xfb, 0xde, 0x5a, + 0x5c, 0xa8, 0x21, 0x35, 0xe6, 0x2e, 0x8c, 0x2a, + 0x3c, 0x12, 0x17, 0x79, 0x9a, 0x0d, 0x2e, 0x79, + 0xeb, 0x67, 0x1f, 0x2b, 0xf8, 0x6e, 0xca, 0xc1, + 0xfa, 0x45, 0x18, 0x9e, 0xdf, 0x6a, 0xe6, 0xcb, + 0xe9, 0x5c, 0xc3, 0x09, 0xaf, 0x93, 0x58, 0x13, + 0xbf, 0x90, 0x84, 0x87, 0x75, 0xd6, 0x82, 0x28, + 0x8d, 0xe7, 0x2f, 0xa3, 0xfb, 0x97, 0x74, 0x2a, + 0x73, 0x04, 0x82, 0x06, 0x76, 0x69, 0xb1, 0x0b, + 0x19, 0xfc, 0xae, 0xb3, 0xdd, 0x2a, 0xe5, 0xc1, + 0x05, 0xd8, 0x80, 0x95, 0x22, 0x90, 0x71, 0xfc, + 0xc2, 0x92, 0x42, 0xfd, 0xf1, 0x70, 0xb4, 0x68, + 0x88, 0xa4, 0x9e, 0x0a, 0x24, 0x40, 0x13, 0xc8, + 0xa2, 0x56, 0x4f, 0x39, 0xe6, 0x06, 0xf1, 0xdc, + 0xf5, 0x13, 0x0e, 0xad, 0x9c, 0x8b, 0xaf, 0xe9, + 0xe3, 0x88, 0x72, 0xff, 0xa0, 0x6d, 0xda, 0x08, + 0x70, 0xb9, 0x2e, 0x83, 0xc5, 0xbb, 0x32, 0xa5, + 0x74, 0xc7, 0xfb, 0x7b, 0x76, 0xaf, 0x02, 0xbb, + 0x2b, 0xb8, 0x5e, 0x65, 0x02, 0xfe, 0x0e, 0xa0, + 0x99, 0xce, 0x01, 0x3b, 0x35, 0xe1, 0xb0, 0x22, + 0xe5, 0x94, 0xbd, 0xdd, 0x8e, 0xbb, 0xf6, 0x75, + 0xbf, 0xbf, 0xee, 0x7a, 0xb1, 0x58, 0xb4, 0x81, + 0xb8, 0x39, 0x3e, 0xb6, 0x1e, 0xde, 0xda, 0x1b, + 0xd5, 0xf7, 0xdd, 0x7d, 0x65, 0x9c, 0xaa, 0x56, + 0x93, 0xb8, 0xaf, 0x48, 0x53, 0xc7, 0x22, 0xe4, + 0x1c, 0xdf, 0xe9, 0x79, 0xb4, 0x20, 0x89, 0xcc, + 0x2a, 0x79, 0x2c, 0x09, 0xbe, 0x78, 0xcf, 0xcc, + 0xf2, 0x90, 0xd6, 0x65, 0xc5, 0x29, 0xfc, 0xda, + 0x69, 0xfc, 0xc0, 0xd6, 0x70, 0x99, 0x61, 0x3f, + 0x60, 0x02, 0xd8, 0x12, 0x22, 0xc8, 0x34, 0xc6, + 0x3b, 0xb3, 0xc2, 0x33, 0xa1, 0x5c, 0x8f, 0x4c, + 0xd1, 0x52, 0x72, 0xf2, 0x42, 0x05, 0x8e, 0x18, + 0x1f, 0x16, 0xda, 0xb8, 0x53, 0xa1, 0x5f, 0x01, + 0x32, 0x1b, 0x90, 0xb3, 0x53, 0x9b, 0xd0, 0x85, + 0x61, 0x2d, 0x17, 0xed, 0x0a, 0xa4, 0xa5, 0x27, + 0x09, 0x75, 0x7c, 0xbc, 0x30, 0xf7, 0x5e, 0x59, + 0x9a, 0x07, 0x96, 0x84, 0x28, 0x86, 0x4b, 0xa7, + 0x22, 0x35, 0x28, 0xc7, 0xed, 0x0d, 0xc3, 0xce, + 0x98, 0xcc, 0x2d, 0xec, 0xd4, 0x98, 0x09, 0x8e, + 0x52, 0x5f, 0x2b, 0x9a, 0x13, 0xbe, 0x99, 0x16, + 0x73, 0xd1, 0x1f, 0x81, 0xe5, 0xa2, 0x08, 0x78, + 0xcb, 0x0c, 0x20, 0xd4, 0xa5, 0xea, 0x4b, 0x5b, + 0x95, 0x5a, 0x92, 0x9a, 0x52 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testcnt2", + { + 0x1b, 0x5d, 0xdb, 0x77, 0xcf, 0xf9, 0xec, 0x95, + 0x5e, 0xcc, 0x67, 0x9f, 0x5d, 0x28, 0xad, 0x4a, + 0x27, 0xf4, 0x32, 0xc6, 0xb2, 0xcb, 0xb1, 0x45, + 0x6a, 0x88, 0x14, 0x0c, 0x9b, 0x9b, 0x5f, 0x48 + }, + G89_CNT, + { + 0x71, 0x58, 0x8c, 0xe1, 0x55, 0xf4, 0xf6, 0xb3 + }, + { + 0x8e, 0xcd, 0x8f, 0xc8, 0xac, 0xe1, 0x15, 0x48, + 0x2d, 0xae, 0x24, 0x8a, 0xc7, 0xfb, 0xba, 0x0f, + 0x1d, 0x8a, 0x95, 0xa2, 0x43, 0xef, 0xcb, 0xdc, + 0x59, 0x57, 0xa7, 0xc7, 0x0e, 0xe3, 0xe2, 0xb9, + 0x0d, 0x86, 0x29, 0x62, 0xcb, 0x83, 0x4d, 0x07, + 0x0c, 0x40, 0xd4, 0x7b, 0x2e, 0xca, 0xba, 0xbf, + 0x4a, 0x60, 0x3b, 0x31, 0x98, 0xc8, 0x88, 0x47, + 0xd9, 0x82, 0xab, 0xfc, 0x8f, 0x48, 0xe2, 0x46, + 0xab, 0xd3, 0xa1, 0xab, 0x8a, 0x05, 0x22, 0x8c, + 0xf4, 0xec, 0x9a, 0x1e, 0x76, 0xab, 0x1a, 0x60, + 0xd9, 0x25, 0x6b, 0xb8, 0x56, 0xe5, 0xb2, 0xea, + 0x10, 0xf3, 0x62, 0x04, 0x32, 0x5e, 0xaa, 0x3b, + 0x7b, 0x57, 0xbc, 0x3b, 0x8b, 0x43, 0x47, 0xf2, + 0xd5, 0x03, 0x7e, 0x51, 0x01, 0xff, 0x77, 0x28, + 0xca, 0x90, 0xa3, 0xfe, 0x7e, 0x2e, 0x70, 0x16, + 0x75, 0x18, 0x44, 0xf0, 0x1b, 0x85, 0x05, 0xea, + 0xe3, 0x21, 0xf7, 0x26, 0x86, 0x76, 0x3c, 0x67, + 0x9d, 0xfc, 0xbc, 0x10, 0x7f, 0x77, 0xe4, 0xed, + 0xd3, 0x12, 0xf8, 0x83, 0x00, 0x1f, 0x4b, 0x92, + 0x95, 0x92, 0x5c, 0xf3, 0x5a, 0xf3, 0xb7, 0xd0, + 0xa9, 0x5f, 0xf2, 0x18, 0xc4, 0x66, 0x62, 0xc1, + 0x84, 0x0e, 0x66, 0xe8, 0x80, 0x7d, 0x1f, 0xf0, + 0xba, 0x01, 0x9b, 0x71, 0xae, 0x93, 0xcc, 0x27, + 0x54, 0x34, 0x9a, 0xbd, 0xca, 0xee, 0x52, 0x09, + 0x92, 0x9d, 0xb0, 0xd5, 0xd9, 0xba, 0x2f, 0xb9, + 0x96, 0xdc, 0xfa, 0xbd, 0xce, 0xea, 0x1a, 0x7b, + 0x9a, 0x1d, 0x13, 0xa7, 0x11, 0xe2, 0x9a, 0x64, + 0xf6, 0xd3, 0xee, 0xc6, 0x33, 0xb7, 0x6e, 0xef, + 0x25, 0x9e, 0x1e, 0x7c, 0xe3, 0x1f, 0x2c, 0x6e, + 0xa9, 0xc0, 0xf8, 0xc1, 0xbf, 0x3b, 0xf8, 0x34, + 0x03, 0x9b, 0xa1, 0x40, 0x5b, 0x0c, 0x3c, 0x09, + 0x66, 0x9d, 0x63, 0xe2, 0xe2, 0x04, 0x8f, 0x06, + 0x84, 0x74, 0x68, 0xb2, 0x5c, 0x3b, 0x4c, 0xad, + 0x0b, 0x3f, 0x03, 0xb3, 0x07, 0x8a, 0x64, 0xa7, + 0x36, 0x56, 0x26, 0x39, 0x66, 0xda, 0xe9, 0x6d, + 0x1b, 0xd5, 0x88, 0xe8, 0x5c, 0xaf, 0x5a, 0x4c, + 0x49, 0xf7, 0xf5, 0xb7, 0x78, 0xf0, 0xde, 0xec, + 0xcd, 0x16, 0x23, 0x9e, 0x8c, 0x13, 0xbe, 0x6b, + 0x6f, 0x9b, 0x07, 0xe5, 0xbb, 0xcc, 0x3a, 0x1b, + 0x6f, 0x43, 0xdf, 0xff, 0x46, 0x2a, 0xae, 0x47, + 0x19, 0x18, 0x9a, 0x25, 0x09, 0xc9, 0x24, 0x40, + 0x0c, 0x4b, 0xa7, 0xda, 0x5e, 0x0d, 0xee, 0xfa, + 0x62, 0x45, 0x8e, 0xcc, 0x2f, 0x23, 0x08, 0x1d, + 0x92, 0xf0, 0xfe, 0x82, 0x0f, 0xd7, 0x11, 0x60, + 0x7e, 0x0b, 0x0b, 0x75, 0xf4, 0xf5, 0x3b, 0xc0, + 0xa4, 0xe8, 0x72, 0xa5, 0xb6, 0xfa, 0x5a, 0xad, + 0x5a, 0x4f, 0x39, 0xb5, 0xa2, 0x12, 0x96, 0x0a, + 0x32, 0x84, 0xb2, 0xa1, 0x06, 0x68, 0x56, 0x57, + 0x97, 0xa3, 0x7b, 0x22, 0x61, 0x76, 0x5d, 0x30, + 0x1a, 0x31, 0xab, 0x99, 0x06, 0xc5, 0x1a, 0x96, + 0xcf, 0xcf, 0x14, 0xff, 0xb2, 0xc4, 0xcc, 0x2b, + 0xbf, 0x0c, 0x9d, 0x91, 0x8f, 0x79, 0x5b, 0xbc, + 0xa9, 0x6b, 0x91, 0x6a, 0xb4, 0x93, 0x5c, 0x7b, + 0x5d, 0xc2, 0x8a, 0x75, 0xc0, 0xc1, 0x08, 0xfa, + 0x99, 0xf9, 0x4d, 0x5e, 0x0c, 0x06, 0x64, 0x60, + 0xa9, 0x01, 0x4a, 0x34, 0x0f, 0x33, 0x84, 0x95, + 0x69, 0x30, 0xc1, 0x1c, 0x36, 0xf8, 0xfc, 0x30, + 0x23, 0xb2, 0x71, 0xe5, 0x52, 0x4d, 0x12, 0x1a, + 0xc9, 0xbe, 0xee, 0xc9, 0xcb, 0x01, 0x85, 0xf3, + 0xdb, 0x30, 0xf9, 0x41, 0xa9, 0x40, 0xb0, 0x06, + 0x29, 0x77, 0xcd, 0xc5, 0xec, 0x58, 0x02, 0x48, + 0x83, 0x53, 0x44, 0x6a, 0xd2, 0xca, 0x05, 0xd8, + 0x5a, 0x08, 0xeb, 0xa9, 0xf4, 0xe6, 0xc7, 0x9d, + 0xd5, 0x7b, 0x74, 0x0b, 0x31, 0xb7, 0xa5, 0x57, + 0x7c, 0x7a, 0xfd, 0x1a, 0x0e, 0xd7, 0x97, 0x41, + 0xbf, 0xdd, 0xc6, 0x19, 0x6c, 0x77, 0x8c, 0x18, + 0x52, 0x57, 0x83, 0xba, 0x71, 0x25, 0xee, 0x39, + 0xbb, 0xe2, 0x43, 0xa0, 0x14, 0xdc, 0x0e, 0x84, + 0xb4, 0x2b, 0xde, 0x3e, 0xe5, 0x36, 0xb7, 0xa2, + 0x92, 0x98, 0x05, 0xb8, 0x96, 0xe5, 0xd0, 0x8c, + 0x08, 0x93, 0x35, 0xc2, 0x81, 0xe0, 0xfc, 0x59, + 0x71, 0xe2, 0x44, 0x49, 0x5d, 0xda, 0xfb, 0x9c, + 0xaa, 0x70, 0x9f, 0x43, 0xa8, 0xa5, 0xd9, 0x67, + 0xd9, 0x8f, 0xa3, 0x1e, 0xbe, 0x0e, 0xec, 0xdf, + 0x12, 0x2b, 0x6a, 0xe7, 0x1c, 0x12, 0x17, 0xe7, + 0xc4, 0x6d, 0x50, 0xc9, 0x52, 0x7a, 0xd5, 0xe8, + 0x7f, 0xbc, 0x07, 0x15, 0xac, 0xdb, 0x93, 0x66, + 0xb1, 0xf0, 0xa7, 0x7b, 0x2f, 0xe9, 0xec, 0xd0, + 0x47, 0x69, 0x59, 0x87, 0xf1, 0x4c, 0x3e, 0x4b, + 0x9b, 0x11, 0x79, 0x13, 0xe4, 0x96, 0xf6, 0x56, + 0x04, 0x6e, 0x0b, 0x33, 0xfc, 0x40, 0xf6, 0xc7, + 0xc1, 0x43, 0xb1, 0xbf, 0x0e, 0xb3, 0x87, 0xfd, + 0x0b, 0x1c, 0x63, 0x46, 0x3a, 0xd3, 0xa0, 0x17, + 0x59, 0x25, 0x94, 0x6c, 0x9c, 0x3d, 0x0c, 0x81, + 0xce, 0x82, 0x72, 0x42, 0x28, 0xf9, 0x37, 0x6a, + 0x6d, 0xe4, 0x12, 0xf4, 0x21, 0xaa, 0xf7, 0xfe, + 0x27, 0x55, 0x40, 0x1a, 0x14, 0xc3, 0x39, 0x5b, + 0xbf, 0x63, 0xc2, 0x5f, 0x10, 0x1f, 0x14, 0x25, + 0xd0, 0xce, 0xf3, 0x14, 0x48, 0x13, 0xa5, 0x0b, + 0x4d, 0x38, 0xcf, 0x0d, 0x34, 0xc0, 0x0a, 0x11, + 0xb4, 0xb5, 0x72, 0xc8, 0x4b, 0xc2, 0x6f, 0xe7, + 0x9d, 0x93, 0xf7, 0xdf, 0xb8, 0x43, 0x72, 0x7e, + 0xda, 0x3e, 0x20, 0x1f, 0xbc, 0x21, 0x2a, 0xce, + 0x00, 0xfa, 0x96, 0x9f, 0x3d, 0xe5, 0x88, 0x96, + 0xef, 0x29, 0x84, 0xdf, 0x6c, 0x1c, 0x96, 0xd8, + 0x58, 0x47, 0xaa, 0x92, 0xf3, 0x07, 0xe5, 0xfb, + 0xaf, 0xea, 0x95, 0x7e, 0x0b, 0x71, 0xcd, 0x81, + 0x0f, 0xb7, 0x0a, 0x59, 0x8f, 0x31, 0x4d, 0xd1, + 0xc3, 0xf3, 0x2f, 0x70, 0x5c, 0x59, 0x18, 0x97, + 0xaf, 0x77, 0x95, 0x5e, 0xaf, 0x40, 0x06, 0x12, + 0x81, 0x61, 0x86, 0x08, 0x4e, 0xbc, 0x89, 0x46, + 0x07, 0x2e, 0x5b, 0x10, 0xaa, 0x12, 0xf0, 0xa7, + 0x84, 0xe2, 0x9a, 0x08, 0xf1, 0xde, 0x59, 0xe3, + 0x0e, 0x47, 0x4b, 0xff, 0xc3, 0xc9, 0x18, 0xaf, + 0x95, 0x9c, 0x67, 0x2a, 0xde, 0x8a, 0x7a, 0x99, + 0x04, 0xc4, 0xb8, 0x97, 0x4c, 0x04, 0x29, 0x71, + 0x05, 0xda, 0xb3, 0xd6, 0xdb, 0x6c, 0x71, 0xe6, + 0xe8, 0x03, 0xbf, 0x94, 0x7d, 0xde, 0x3d, 0xc8, + 0x44, 0xfa, 0x7d, 0x62, 0xb4, 0x36, 0x03, 0xee, + 0x36, 0x52, 0x64, 0xb4, 0x85, 0x6d, 0xd5, 0x78, + 0xf0, 0x6f, 0x67, 0x2d, 0x0e, 0xe0, 0x2c, 0x88, + 0x9b, 0x55, 0x19, 0x29, 0x40, 0xf6, 0x8c, 0x12, + 0xbb, 0x2c, 0x83, 0x96, 0x40, 0xc0, 0x36, 0xf5, + 0x77, 0xff, 0x70, 0x8c, 0x75, 0x92, 0x0b, 0xad, + 0x05, 0x9b, 0x7e, 0xa2, 0xfc, 0xa9, 0xd1, 0x64, + 0x76, 0x82, 0x13, 0xba, 0x22, 0x5e, 0x33, 0x0e, + 0x26, 0x70, 0xa9, 0xbe, 0x74, 0x28, 0xf5, 0xe2, + 0xc4, 0x96, 0xee, 0x3a, 0xbc, 0x97, 0xa6, 0x2c, + 0x2a, 0xe0, 0x64, 0x8d, 0x35, 0xc6, 0x1a, 0xca, + 0xf4, 0x92, 0xfa, 0xc3, 0xf1, 0x1f, 0x98, 0xe4, + 0x43, 0x88, 0x69, 0x3a, 0x09, 0xbf, 0x63, 0xe5, + 0x96, 0x29, 0x0b, 0x9b, 0x62, 0x23, 0x14, 0x8a, + 0x95, 0xe4, 0x1c, 0x5c, 0x0a, 0xa9, 0xc5, 0xb9, + 0x6f, 0x4f, 0x2b, 0x25, 0x6f, 0x74, 0x1e, 0x18, + 0xd5, 0xfe, 0x27, 0x7d, 0x3f, 0x6e, 0x55, 0x2c, + 0x67, 0xe6, 0xde, 0xb5, 0xcc, 0xc0, 0x2d, 0xff, + 0xc4, 0xe4, 0x06, 0x21, 0xa5, 0xc8, 0xd3, 0xd6, + 0x6c, 0xa1, 0xc3, 0xfb, 0x88, 0x92, 0xb1, 0x1d, + 0x90, 0xe1, 0x35, 0x05, 0x9b, 0x29, 0x6d, 0xba, + 0xf1, 0xf4, 0x1e, 0x23, 0x2e + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 5242880+8, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test5Mcnt", + { + 0x07, 0x52, 0x65, 0xe7, 0xca, 0xa3, 0xca, 0x45, + 0xcf, 0x3a, 0x05, 0x1d, 0x38, 0x03, 0x53, 0x0c, + 0x22, 0x31, 0xba, 0x99, 0x4f, 0x9b, 0x6a, 0x1b, + 0x7e, 0x09, 0x9d, 0x4e, 0xb5, 0xc9, 0x84, 0x2e + }, + G89_CNT, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0x3d, 0x05, 0x07, 0x57, 0xc0, 0x75, 0x89, 0x97, + 0xd6, 0x94, 0x49, 0x11, 0x1d, 0xd0, 0x91, 0xee + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + U64(4294967296)+16, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test4Gcnt", + { + 0x75, 0xa3, 0x3c, 0xae, 0x03, 0x6b, 0x10, 0xdb, + 0xc1, 0x56, 0x50, 0x89, 0x03, 0xd2, 0x9f, 0x91, + 0xee, 0xe8, 0x64, 0x1d, 0x43, 0xf2, 0x4e, 0xf8, + 0xf2, 0x6c, 0xed, 0xda, 0x8f, 0xe4, 0x88, 0xe9 + }, + G89_CNT, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0xfa, 0x6c, 0x96, 0x78, 0xe2, 0xf8, 0xdd, 0xaa, + 0x67, 0x5a, 0xc9, 0x5d, 0x57, 0xf1, 0xbd, 0x99 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 1035, + { + 0xd6, 0xcf, 0x31, 0x96, 0x9c, 0xa1, 0xfb, 0xd6, + 0x8d, 0xa3, 0xdd, 0x01, 0xd9, 0x88, 0xc0, 0x2f, + 0xbc, 0x46, 0xc7, 0x3a, 0xe4, 0x21, 0x86, 0x96, + 0x8d, 0xe2, 0xca, 0xb6, 0x37, 0xa2, 0xe1, 0xa8, + 0x7e, 0xa7, 0x79, 0x2e, 0xa4, 0x56, 0x75, 0x7f, + 0x3e, 0x55, 0x8b, 0x43, 0xae, 0x65, 0xdf, 0xaa, + 0x42, 0xb6, 0x00, 0xa6, 0x61, 0x03, 0x0d, 0xd3, + 0x41, 0x02, 0x27, 0x23, 0x95, 0x79, 0x9b, 0x34, + 0x81, 0xa9, 0x86, 0xb5, 0xa7, 0x90, 0xe2, 0xae, + 0xc4, 0x2f, 0xc3, 0x8e, 0x32, 0x56, 0x13, 0xfa, + 0x4d, 0x4e, 0x9f, 0x15, 0x75, 0x7e, 0x74, 0xdc, + 0x32, 0x2d, 0xee, 0x4d, 0x67, 0x70, 0x9f, 0x62, + 0xb9, 0xc4, 0xdb, 0x24, 0x84, 0xcc, 0x16, 0x7b, + 0xda, 0x22, 0xf7, 0xc5, 0xf3, 0x93, 0x35, 0x73, + 0xc6, 0x03, 0x1c, 0x77, 0xa5, 0xf2, 0x76, 0x56, + 0xb4, 0x95, 0xd4, 0x7e, 0x0d, 0x20, 0xc6, 0x6e, + 0xee, 0x8f, 0x25, 0x48, 0xff, 0x7e, 0x01, 0x3a, + 0xb4, 0x1f, 0xaa, 0x35, 0xc0, 0x33, 0x58, 0x9c, + 0xb5, 0xba, 0x65, 0x4b, 0xd3, 0x51, 0x14, 0xec, + 0x61, 0xce, 0xe4, 0xba, 0x49, 0xba, 0x39, 0x32, + 0xab, 0xce, 0x81, 0x72, 0xce, 0xab, 0xed, 0xd4, + 0xd2, 0x19, 0x87, 0x85, 0x92, 0xfa, 0x64, 0x34, + 0xd8, 0x86, 0xf4, 0x8a, 0x08, 0x3c, 0xde, 0xee, + 0x97, 0x92, 0x92, 0x69, 0xba, 0x9b, 0x5f, 0x7a, + 0x03, 0xc1, 0x5d, 0x43, 0x02, 0x8c, 0xbe, 0xd2, + 0x46, 0x72, 0x81, 0x40, 0x7d, 0x68, 0x98, 0x45, + 0x0b, 0x54, 0x27, 0x1c, 0xaf, 0x80, 0x42, 0xe4, + 0xd5, 0xd4, 0xe4, 0xa2, 0x98, 0x07, 0x8f, 0x03, + 0xf5, 0x2c, 0x8c, 0x88, 0xca, 0x5a, 0xde, 0xe4, + 0x9f, 0xb1, 0x5f, 0x82, 0xff, 0x20, 0x67, 0x52, + 0x85, 0x84, 0x4f, 0xc8, 0xfe, 0xa7, 0x9e, 0xae, + 0x1c, 0xfa, 0xb8, 0x75, 0xd3, 0xf7, 0x9f, 0x0d, + 0xda, 0x2d, 0xe6, 0xcc, 0x86, 0x6b, 0xa4, 0x14, + 0x65, 0xc3, 0xf9, 0x15, 0xbc, 0x87, 0xf5, 0xae, + 0x8c, 0x10, 0xd4, 0xce, 0x5b, 0x9c, 0xe2, 0xdd, + 0x42, 0x03, 0x09, 0x87, 0x47, 0xed, 0x5d, 0xd0, + 0x7a, 0x69, 0x4c, 0xfa, 0x43, 0x7d, 0xbf, 0x07, + 0x85, 0x6a, 0xee, 0x68, 0xe6, 0x7a, 0x57, 0xb2, + 0x20, 0x8d, 0x80, 0xf2, 0x91, 0x6f, 0x5c, 0x07, + 0x8c, 0xe4, 0x6a, 0x49, 0x90, 0x85, 0x8b, 0x77, + 0x29, 0x56, 0x1c, 0x5e, 0xa9, 0x3f, 0xab, 0x8b, + 0x79, 0xa3, 0x6f, 0x6b, 0x34, 0xcb, 0x61, 0xf6, + 0xe6, 0x92, 0xd1, 0x48, 0x9e, 0x11, 0xa2, 0x82, + 0xc0, 0x4e, 0x23, 0xd2, 0x15, 0x0d, 0x8d, 0xff, + 0xfa, 0x17, 0x9d, 0x81, 0xb8, 0xbc, 0xd7, 0x5b, + 0x08, 0x81, 0x20, 0x40, 0xc0, 0x3c, 0x06, 0x8b, + 0x1a, 0x88, 0x0b, 0x4b, 0x7b, 0x31, 0xf5, 0xd4, + 0x4e, 0x09, 0xd1, 0x4d, 0x0d, 0x7f, 0x45, 0xd1, + 0x09, 0x35, 0xba, 0xce, 0x65, 0xdd, 0xf2, 0xb8, + 0xfb, 0x7a, 0xbc, 0xc4, 0x4b, 0xc8, 0x75, 0xda, + 0x6b, 0xce, 0x3d, 0xe8, 0x94, 0xcc, 0x23, 0x6f, + 0xb0, 0x3b, 0x4f, 0x7d, 0x07, 0xb9, 0x0f, 0x62, + 0x92, 0x7e, 0xda, 0x70, 0x50, 0xce, 0xd3, 0x28, + 0x12, 0x11, 0x00, 0xeb, 0x8d, 0x63, 0x70, 0x78, + 0xa8, 0x7b, 0x76, 0xab, 0xc6, 0x40, 0xc0, 0x4e, + 0x80, 0xdd, 0xf0, 0xfe, 0x83, 0x72, 0x56, 0x4c, + 0x09, 0x4c, 0xf1, 0x72, 0x72, 0x86, 0x26, 0x31, + 0xc3, 0xc2, 0xdc, 0x8e, 0xc7, 0xf4, 0x35, 0xec, + 0x17, 0x06, 0x63, 0x47, 0x49, 0x88, 0x47, 0xaf, + 0xb3, 0x38, 0x4f, 0x7e, 0x44, 0x95, 0xb5, 0xbb, + 0x1d, 0xbd, 0x5a, 0x91, 0x5b, 0xd0, 0x1a, 0xdf, + 0x0d, 0x0b, 0x50, 0xd8, 0xe2, 0x0e, 0xc5, 0x00, + 0x2d, 0x5b, 0x29, 0x19, 0xaa, 0x2b, 0x64, 0xc5, + 0x40, 0x31, 0x48, 0x11, 0xbc, 0x04, 0xd1, 0xcf, + 0x6d, 0xf9, 0xa5, 0x2f, 0x4a, 0xc9, 0x82, 0xfa, + 0x59, 0xe1, 0xfc, 0xab, 0x1c, 0x33, 0x26, 0x0a, + 0x5f, 0xef, 0xf2, 0x06, 0xd8, 0xd3, 0x7e, 0x16, + 0x58, 0x16, 0x78, 0x73, 0xae, 0xba, 0xeb, 0xe5, + 0x3d, 0xb2, 0x0a, 0xb3, 0x32, 0x2d, 0x14, 0xa4, + 0xfa, 0x3f, 0x1f, 0x43, 0xf9, 0x7b, 0xa9, 0x43, + 0x98, 0x18, 0x94, 0x07, 0x07, 0xe5, 0x19, 0x34, + 0xa8, 0x16, 0x5f, 0x71, 0x67, 0xaa, 0x29, 0xe5, + 0xfa, 0xf0, 0x83, 0x06, 0x1d, 0x9d, 0xfc, 0xfe, + 0xfe, 0x8c, 0xb5, 0xb2, 0xa9, 0xe7, 0xa0, 0x40, + 0x60, 0xb6, 0x71, 0x9e, 0xab, 0x5b, 0x83, 0xb9, + 0x0c, 0x2b, 0x58, 0x23, 0x80, 0x09, 0x9e, 0x5d, + 0x94, 0x7d, 0x40, 0x76, 0xa9, 0x16, 0x96, 0x9e, + 0x83, 0xe0, 0x0d, 0xec, 0xa0, 0xec, 0x76, 0x2a, + 0xb7, 0xa0, 0xff, 0xb8, 0x50, 0x4c, 0x5b, 0xc6, + 0x8b, 0x0a, 0x65, 0x2e, 0xfe, 0xb4, 0x40, 0x9a, + 0x01, 0xd8, 0xc6, 0xa3, 0xab, 0x99, 0xa2, 0xc5, + 0x0c, 0x08, 0xc4, 0xb7, 0xee, 0x4d, 0x1d, 0xc4, + 0x08, 0x15, 0xd0, 0xdb, 0xaa, 0x63, 0x4f, 0x31, + 0xeb, 0x14, 0x97, 0x43, 0xbd, 0xc1, 0x94, 0x08, + 0xe6, 0xde, 0x43, 0x9f, 0x95, 0x0b, 0x96, 0x7e, + 0x7f, 0x3c, 0x68, 0xba, 0x6f, 0xc4, 0xc9, 0x35, + 0x2b, 0xc4, 0x0e, 0xda, 0x1f, 0x91, 0x68, 0x64, + 0x63, 0x34, 0x73, 0xbe, 0x57, 0x75, 0xb9, 0xed, + 0xf7, 0x2d, 0x3b, 0x05, 0x21, 0x93, 0x28, 0x48, + 0x96, 0x95, 0x97, 0xa0, 0xd2, 0x7d, 0x78, 0xbb, + 0x6a, 0x49, 0x8f, 0x76, 0x55, 0x74, 0x63, 0xb9, + 0xc5, 0x36, 0x12, 0x25, 0xbf, 0x03, 0x82, 0x8f, + 0xf0, 0xf6, 0x80, 0xbb, 0x33, 0xb4, 0xf4, 0x17, + 0x27, 0x1c, 0xf3, 0x4c, 0x10, 0xa3, 0xe4, 0xd1, + 0x55, 0xd9, 0x68, 0x21, 0x4e, 0x5a, 0x83, 0x67, + 0xbf, 0xf8, 0x3c, 0x7d, 0x4e, 0x62, 0xd3, 0x28, + 0xa7, 0x26, 0x6f, 0xe9, 0xee, 0xc2, 0x0b, 0x2d, + 0x03, 0x84, 0xb1, 0xff, 0xd6, 0x68, 0x1f, 0xb6, + 0xf2, 0xe4, 0x0f, 0xda, 0x2d, 0xee, 0x5f, 0x6e, + 0x21, 0xc8, 0xe1, 0xfc, 0xad, 0x6b, 0x0e, 0x04, + 0x7d, 0xaf, 0xc2, 0x3b, 0xa5, 0x68, 0x9b, 0x0c, + 0xf3, 0x56, 0xf3, 0xda, 0x8d, 0xc8, 0x7d, 0x39, + 0xdc, 0xd5, 0x99, 0xc6, 0x01, 0x10, 0xce, 0x42, + 0x1b, 0xac, 0x48, 0xdc, 0x97, 0x78, 0x0a, 0xec, + 0xb3, 0x8f, 0x47, 0x35, 0xa3, 0x6a, 0x64, 0xb2, + 0x8e, 0x63, 0x69, 0x22, 0x66, 0xae, 0x2e, 0xe0, + 0x88, 0xf9, 0x40, 0x3c, 0xc9, 0xa2, 0x57, 0x61, + 0xf6, 0xad, 0xf0, 0xdc, 0x90, 0x56, 0x3f, 0x06, + 0x9b, 0x7d, 0xbd, 0xc2, 0x81, 0x02, 0xab, 0xb8, + 0x15, 0x09, 0x88, 0x4a, 0xff, 0x2f, 0x31, 0xbf, + 0x5e, 0xfa, 0x6a, 0x7e, 0xf6, 0xc5, 0xa7, 0xf7, + 0xd5, 0xab, 0x55, 0xac, 0xae, 0x0d, 0x8c, 0x8d, + 0x7f, 0x4b, 0x25, 0xbb, 0x32, 0xff, 0x11, 0x33, + 0x2e, 0x37, 0x37, 0x69, 0x96, 0x15, 0x17, 0xb1, + 0x17, 0x49, 0xe0, 0x9a, 0x9c, 0xd9, 0x5b, 0x8d, + 0x58, 0xa3, 0x1d, 0x92, 0x87, 0xf8, 0x80, 0xb9, + 0xbd, 0x5a, 0xec, 0x40, 0xe1, 0x00, 0x33, 0x60, + 0xe4, 0x86, 0x16, 0x6d, 0x61, 0x81, 0xf2, 0x28, + 0x6a, 0xa7, 0xce, 0x3f, 0x95, 0xae, 0x43, 0xca, + 0xe1, 0x3f, 0x81, 0x74, 0x7e, 0x1c, 0x47, 0x17, + 0x95, 0xc6, 0x60, 0xda, 0x74, 0x77, 0xd9, 0x9f, + 0xfa, 0x92, 0xb4, 0xbe, 0xe1, 0x23, 0x98, 0x18, + 0x95, 0x63, 0x03, 0x13, 0x4c, 0x1a, 0x2d, 0x41, + 0xcd, 0xe4, 0x84, 0xf7, 0xe6, 0x38, 0xef, 0xff, + 0x95, 0xb2, 0xe8, 0x7c, 0x8f, 0x58, 0xb5, 0xb5, + 0xed, 0x27, 0x7f, 0x3c, 0x18, 0xab, 0xbe, 0x7f, + 0x4f, 0xe2, 0x35, 0x15, 0x71, 0xb7, 0x6f, 0x85, + 0x38, 0x9b, 0x88, 0xf6, 0x9c, 0x8d, 0x43, 0xb5, + 0x58, 0x9e, 0xf2, 0xd1, 0x96, 0xbe, 0xb7, 0xad, + 0x1a, 0xa0, 0x98 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testimit2", + { + 0x80, 0xd9, 0xa0, 0xdc, 0x21, 0xf9, 0x30, 0x40, + 0x75, 0xfe, 0x49, 0x1b, 0x9e, 0x71, 0x90, 0x91, + 0x78, 0x88, 0x21, 0x60, 0x39, 0xe7, 0xc9, 0x2b, + 0xfb, 0x55, 0x1d, 0xf4, 0xdd, 0x2b, 0x0a, 0x01 + }, + G89_IMIT, + { 0 }, + { + 0x90, 0xf2, 0x11, 0x9a + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 10, + { + 0x1d, 0xeb, 0xe6, 0x79, 0x0a, 0x59, 0x00, 0xe6, + 0x8e, 0x5c + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testimit3", + { + 0xa9, 0xb6, 0x37, 0xcc, 0x6d, 0x9b, 0x2f, 0x25, + 0xb0, 0xdf, 0x47, 0x04, 0x50, 0x68, 0xb0, 0x27, + 0x41, 0x27, 0x58, 0x6a, 0xbd, 0x0a, 0x6e, 0x50, + 0x2f, 0xc6, 0xfc, 0xc0, 0x3e, 0x29, 0x42, 0xa5 + }, + G89_IMIT, + { 0 }, + { + 0x31, 0x7c, 0x16, 0xe4 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 6, + { + 0xef, 0x06, 0x8f, 0x14, 0xc9, 0x04 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testimit4", + { + 0xb0, 0x6c, 0x48, 0x23, 0x0a, 0x6e, 0xf4, 0xec, + 0x27, 0x98, 0x01, 0x23, 0xa7, 0xd8, 0xbf, 0x60, + 0x89, 0xef, 0xad, 0xe8, 0x8f, 0x79, 0x14, 0x8c, + 0x18, 0x5c, 0x9a, 0xda, 0xef, 0x0b, 0xdd, 0xa0 + }, + G89_IMIT, + { 0 }, + { + 0xe9, 0x72, 0xae, 0xbf + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 16, + { + 0x02, 0xf8, 0xec, 0x2b, 0x4d, 0x1f, 0xbc, 0x7c, + 0x6e, 0x47, 0xe3, 0x87, 0x22, 0x75, 0x41, 0xa7 + }, + "id-Gost28147-89-CryptoPro-B-ParamSet", + "testimit5", + { + 0x33, 0xd3, 0xef, 0x01, 0x19, 0x95, 0x0e, 0x15, + 0xa1, 0x69, 0x75, 0xae, 0x56, 0x27, 0x17, 0x79, + 0x63, 0x47, 0xab, 0x62, 0x9d, 0x4a, 0xf0, 0x34, + 0xd3, 0x1e, 0x69, 0x74, 0xec, 0x31, 0x48, 0xfc + }, + G89_IMIT, + { 0 }, + { + 0xf5, 0x55, 0x1f, 0x28 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 8, + { + 0xf3, 0xb2, 0x29, 0xd2, 0x7a, 0x37, 0x03, 0x12 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testimit6", + { + 0x42, 0x35, 0x81, 0x91, 0x0b, 0xa9, 0x99, 0xff, + 0xd9, 0x43, 0xf8, 0xc6, 0x19, 0x55, 0x1f, 0x2f, + 0x2d, 0x45, 0x40, 0x20, 0x1e, 0x1d, 0x32, 0x7a, + 0xb1, 0x07, 0x6b, 0x4f, 0x45, 0x90, 0xd9, 0x80 + }, + G89_IMIT, + { 0 }, + { + 0x6e, 0x15, 0xfa, 0xe8 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 0, + { + 0 + }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "testimit7", + { + 0x26, 0xcb, 0xb9, 0xf0, 0x0c, 0x62, 0x9f, 0xaa, + 0x4a, 0x1d, 0xb6, 0x30, 0x09, 0x01, 0x56, 0x89, + 0x66, 0xd4, 0xe4, 0x0e, 0xfe, 0xf6, 0x10, 0x6b, + 0x6c, 0xe8, 0x04, 0x3a, 0xe3, 0x61, 0x4b, 0x19 + }, + G89_IMIT, + { 0 }, + { + 0x00, 0x00, 0x00, 0x00 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 5242880, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test5Mimit", + { + 0xaa, 0x85, 0x84, 0xcd, 0x65, 0x28, 0xe1, 0xdb, + 0xb8, 0x20, 0x19, 0x43, 0xe0, 0x36, 0x35, 0x10, + 0x19, 0xc3, 0x70, 0x5b, 0x27, 0xc1, 0x9d, 0x84, + 0x75, 0xa3, 0xc6, 0x49, 0x46, 0x8f, 0x7c, 0x4e + }, + G89_IMIT, + { 0 }, + { + 0x2a, 0xe6, 0x23, 0xc6 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + 3221225472U + 16, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test3Gimit1", + { + 0xd5, 0xda, 0xfe, 0x06, 0x60, 0xdc, 0xf0, 0xb3, + 0x49, 0x5a, 0x02, 0x59, 0xc8, 0x2e, 0x4a, 0x2b, + 0xcc, 0x9b, 0x98, 0x04, 0xb7, 0xf2, 0x78, 0xb7, + 0xce, 0xa3, 0xf2, 0xdb, 0x9e, 0xa8, 0x49, 0x1d + }, + G89_IMIT, + { 0 }, + { + 0xcc, 0x46, 0x67, 0xe4 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + U64(4)*1024*1024*1024, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test4Gimit3", + { + 0x0d, 0xf1, 0xa8, 0x7f, 0x57, 0x03, 0x44, 0xcc, + 0xdb, 0x20, 0xde, 0xed, 0x85, 0x50, 0x38, 0xda, + 0xc9, 0x44, 0xec, 0x2c, 0x0d, 0x66, 0xb7, 0xdc, + 0x17, 0x14, 0x55, 0x95, 0x33, 0x6e, 0x43, 0x3e + }, + G89_IMIT, + { 0 }, + { + 0xb7, 0x21, 0x2e, 0x48 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + U64(4)*1024*1024*1024+4, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test4Gimit1", + { + 0x0c, 0xf3, 0xe9, 0xb0, 0x28, 0x3b, 0x9f, 0x8b, + 0xe3, 0x82, 0xb9, 0xa2, 0xa6, 0xbd, 0x80, 0xd2, + 0xcd, 0xfa, 0x3f, 0xf7, 0x90, 0xa7, 0x55, 0x06, + 0x9b, 0x7a, 0x58, 0xee, 0xe7, 0xf1, 0x9d, 0xbe + }, + G89_IMIT, + { 0 }, + { + 0xda, 0x15, 0x10, 0x73 + } + }, + { /* Calculated by libcapi10, CryptoPro CSP 3.6R2, Mac OSX */ + U64(4)*1024*1024*1024+10, + { 0 }, + "id-Gost28147-89-CryptoPro-A-ParamSet", + "test4Gimit2", + { + 0x97, 0x1a, 0x42, 0x22, 0xfa, 0x07, 0xb2, 0xca, + 0xf9, 0xd2, 0x34, 0x5a, 0x92, 0xb1, 0x1f, 0x6b, + 0x53, 0xf8, 0xaf, 0xed, 0x9a, 0x73, 0xc4, 0x38, + 0xd7, 0x7d, 0x25, 0x81, 0x00, 0x0d, 0xd4, 0x29 + }, + G89_IMIT, + { 0 }, + { + 0x52, 0xaa, 0x22, 0xb4 + } + } +}; + +/* const */ unsigned char bZB[40*1024*1024]; +unsigned char bTS[40*1024*1024]; + +int main(int argc, char *argv[]) +{ + unsigned int t; + uint64_t ullMaxLen = 6*1000*1000; + int ignore = 0; + EVP_MD_CTX *mctx = NULL; + EVP_CIPHER_CTX *ectx = NULL; + EVP_PKEY *mac_key; + unsigned char bDerive[EVP_MAX_KEY_LENGTH]; + unsigned char bTest[G89_MAX_TC_LEN]; + unsigned char bTest1[G89_MAX_TC_LEN]; + uint64_t ullLeft; + unsigned int mdl = 0; + int enlu = 0; + int enlf = 0; + size_t siglen; + size_t l = 0; + BIO *bio_err; + const EVP_MD *md_gost94 = NULL; + const EVP_CIPHER *cp_g89ecb = NULL; + const EVP_CIPHER *cp_g89cfb = NULL; + const EVP_CIPHER *cp_g89cnt = NULL; + const EVP_CIPHER *ctype = NULL; + const EVP_MD *md_g89imit = NULL; + int ret = 0; + + printf("Testing GOST 28147-89 "); + + if(1 < argc) { + if(1 != sscanf(argv[1], "%" SCNu64, &ullMaxLen) || + ( 2 < argc ? + 1 != sscanf(argv[2], "%d", &ignore) : 0)) { + fflush(NULL); + fprintf(stderr, "Usage: %s [maxlen [ignore-error]]\n", + argv[0]); + ret = 1; + goto out; + } + } + + ERR_load_crypto_strings(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); +#endif + OPENSSL_load_builtin_modules(); + OpenSSL_add_all_algorithms(); + + memset(bZB, 0, sizeof bZB); + memset(bTS, 0, sizeof bTS); + + /* Test load engine */ + if(NULL == (md_gost94 = EVP_get_digestbyname(SN_id_GostR3411_94))) { + fflush(NULL); + fprintf(stderr, "\"" SN_id_GostR3411_94 "\" - not found\n"); + if(!ignore) { + ret = 7; + goto out; + } + } + if(NULL == (cp_g89cfb = EVP_get_cipherbyname(SN_id_Gost28147_89))) { + fflush(NULL); + fprintf(stderr, "\"" SN_id_Gost28147_89 "\" - not found\n"); + if(!ignore) { + ret = 8; + goto out; + } + } + if(NULL == (cp_g89cnt = EVP_get_cipherbyname(SN_gost89_cnt))) { + fflush(NULL); + fprintf(stderr, "\"" SN_gost89_cnt "\" - not found\n"); + if(!ignore) { + ret = 9; + goto out; + } + } + if(NULL == (cp_g89ecb = EVP_get_cipherbyname(SN_gost89_ecb))) { + fflush(NULL); + fprintf(stderr, "\"" SN_gost89_ecb "\" - not found\n"); + if(!ignore) { + ret = 8; + goto out; + } + } + if(NULL == (md_g89imit = EVP_get_digestbyname(SN_id_Gost28147_89_MAC))) { + fflush(NULL); + fprintf(stderr, "\"" SN_id_Gost28147_89_MAC "\" - not found\n"); + if(!ignore) { + ret = 10; + goto out; + } + } + + /* Test cases */ + for(t = 0; t < sizeof(tcs)/sizeof(tcs[0]); t++) { + if(NULL != tcs[t].szDerive) { + memset(bDerive, 0x3c, sizeof(bDerive)); + mdl = sizeof(bDerive); + if (!EVP_Digest(tcs[t].szDerive, strlen(tcs[t].szDerive), bDerive, + &mdl, md_gost94, NULL)) + goto out; + if(0 != memcmp(tcs[t].bRawKey, bDerive, mdl)) { + fflush(NULL); + fprintf(stderr, "Engine test t=%d " + "derive key error.\n", t); + if(!ignore) { + ret = 12; + goto out; + } + } + } + if(ullMaxLen < tcs[t].ullLen) { + printf("@"); + continue; + } + memset(bTest, 0xa5, sizeof(bTest)); + memset(bTest1, 0x5a, sizeof(bTest1)); + + switch(tcs[t].gMode) { + case G89_ECB: + ctype = cp_g89ecb; + goto engine_cipher_check; + case G89_CFB: + ctype = cp_g89cfb; + goto engine_cipher_check; + case G89_CNT: + ctype = cp_g89cnt; +engine_cipher_check: + if ((ectx = EVP_CIPHER_CTX_new()) == NULL) + goto imit_fail; + if (!EVP_EncryptInit_ex(ectx, ctype, NULL, tcs[t].bRawKey, + tcs[t].bIV)) + goto imit_fail; + if (!EVP_CIPHER_CTX_ctrl(ectx, EVP_CTRL_GOST_SET_SBOX, + OBJ_txt2nid(tcs[t].szParamSet), 0)) + goto imit_fail; + if(G89_MAX_TC_LEN >= tcs[t].ullLen) { + enlu = sizeof(bTest); + if (!EVP_EncryptUpdate(ectx, bTest, &enlu, tcs[t].bIn, + (int)tcs[t].ullLen)) + goto imit_fail; + l = (size_t)tcs[t].ullLen; + } else { + for(ullLeft = tcs[t].ullLen; + ullLeft >= sizeof(bZB); + ullLeft -= sizeof(bZB)) { + printf("B"); + fflush(NULL); + enlu = sizeof(bTS); + if (!EVP_EncryptUpdate(ectx, bTS, &enlu, bZB, + sizeof(bZB))) + goto imit_fail; + } + printf("b%" PRIu64 "/%" PRIu64, ullLeft, tcs[t].ullLen); + fflush(NULL); + if (!EVP_EncryptUpdate(ectx, bTS, &enlu, bZB, (int)ullLeft)) + goto imit_fail; + memcpy(bTest, &bTS[enlu-16], 16); + enlu = (int)tcs[t].ullLen; + l = 16; + } + enlf = sizeof(bTest1); + if (tcs[t].gMode == G89_ECB) + enlf = 0; + else { + if (!EVP_EncryptFinal_ex(ectx, bTest1, &enlf)) + goto imit_fail; + } + EVP_CIPHER_CTX_free(ectx); + ectx = NULL; + break; + case G89_IMIT: + if ((mctx = EVP_MD_CTX_new()) == NULL) + goto imit_fail; + mac_key = EVP_PKEY_new_mac_key( + NID_id_Gost28147_89_MAC, NULL, + bDerive, mdl); + if (mac_key == NULL) + goto imit_fail; + if (!EVP_DigestSignInit(mctx, NULL, md_g89imit, NULL, mac_key)) + goto imit_fail; + if (!EVP_MD_CTX_ctrl(mctx, EVP_MD_CTRL_GOST_SET_SBOX, + OBJ_txt2nid(tcs[t].szParamSet), 0)) + goto imit_fail; + if(G89_MAX_TC_LEN >= tcs[t].ullLen) { + if (!EVP_DigestSignUpdate(mctx, tcs[t].bIn, + (unsigned int)tcs[t].ullLen)) + goto imit_fail; + } else { + for(ullLeft = tcs[t].ullLen; + ullLeft >= sizeof(bZB); + ullLeft -= sizeof(bZB)) { + printf("B"); + fflush(NULL); + if (!EVP_DigestSignUpdate(mctx, bZB, sizeof(bZB))) + goto imit_fail; + } + printf("b%" PRIu64 "/%" PRIu64, ullLeft, tcs[t].ullLen); + fflush(NULL); + if (!EVP_DigestSignUpdate(mctx, bZB, (unsigned int)ullLeft)) + goto imit_fail; + } + siglen = 4; + OPENSSL_assert(EVP_DigestSignFinal(mctx, bTest, &siglen)); + EVP_MD_CTX_free(mctx); + mctx = NULL; + EVP_PKEY_free(mac_key); + enlu = (int)tcs[t].ullLen; + enlf = 0; + l = siglen; + break; + } + if((int)tcs[t].ullLen != enlu || 0 != enlf || + 0 != memcmp(tcs[t].bOut, bTest, l)) { +imit_fail: + fflush(NULL); + fprintf(stderr, "\nEngine test t=%d len=%" PRIu64 + " mode=%d failed.\n", t, tcs[t].ullLen, tcs[t].gMode); + if(!ignore) { + ret = 13; + goto out; + } + } else { + printf("."); + fflush(NULL); + } + } + + printf(" passed\n"); + fflush(NULL); + + out: + + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + ERR_print_errors(bio_err); + (void)BIO_flush(bio_err); + BIO_free(bio_err); + EVP_CIPHER_CTX_free(ectx); + EVP_MD_CTX_free(mctx); + return ret; +} +#endif diff --git a/Libraries/libressl/tests/handshake_table.c b/Libraries/libressl/tests/handshake_table.c new file mode 100644 index 000000000..8ebed9a73 --- /dev/null +++ b/Libraries/libressl/tests/handshake_table.c @@ -0,0 +1,550 @@ +/* $OpenBSD: handshake_table.c,v 1.18 2022/12/01 13:49:12 tb Exp $ */ +/* + * Copyright (c) 2019 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "tls13_handshake.h" + +#define MAX_FLAGS (UINT8_MAX + 1) + +/* + * From RFC 8446: + * + * Appendix A. State Machine + * + * This appendix provides a summary of the legal state transitions for + * the client and server handshakes. State names (in all capitals, + * e.g., START) have no formal meaning but are provided for ease of + * comprehension. Actions which are taken only in certain circumstances + * are indicated in []. The notation "K_{send,recv} = foo" means "set + * the send/recv key to the given key". + * + * A.1. Client + * + * START <----+ + * Send ClientHello | | Recv HelloRetryRequest + * [K_send = early data] | | + * v | + * / WAIT_SH ----+ + * | | Recv ServerHello + * | | K_recv = handshake + * Can | V + * send | WAIT_EE + * early | | Recv EncryptedExtensions + * data | +--------+--------+ + * | Using | | Using certificate + * | PSK | v + * | | WAIT_CERT_CR + * | | Recv | | Recv CertificateRequest + * | | Certificate | v + * | | | WAIT_CERT + * | | | | Recv Certificate + * | | v v + * | | WAIT_CV + * | | | Recv CertificateVerify + * | +> WAIT_FINISHED <+ + * | | Recv Finished + * \ | [Send EndOfEarlyData] + * | K_send = handshake + * | [Send Certificate [+ CertificateVerify]] + * Can send | Send Finished + * app data --> | K_send = K_recv = application + * after here v + * CONNECTED + * + * Note that with the transitions as shown above, clients may send + * alerts that derive from post-ServerHello messages in the clear or + * with the early data keys. If clients need to send such alerts, they + * SHOULD first rekey to the handshake keys if possible. + * + */ + +struct child { + enum tls13_message_type mt; + uint8_t flag; + uint8_t forced; + uint8_t illegal; +}; + +static struct child stateinfo[][TLS13_NUM_MESSAGE_TYPES] = { + [CLIENT_HELLO] = { + { + .mt = SERVER_HELLO_RETRY_REQUEST, + }, + { + .mt = SERVER_HELLO, + .flag = WITHOUT_HRR, + }, + }, + [SERVER_HELLO_RETRY_REQUEST] = { + { + .mt = CLIENT_HELLO_RETRY, + }, + }, + [CLIENT_HELLO_RETRY] = { + { + .mt = SERVER_HELLO, + }, + }, + [SERVER_HELLO] = { + { + .mt = SERVER_ENCRYPTED_EXTENSIONS, + }, + }, + [SERVER_ENCRYPTED_EXTENSIONS] = { + { + .mt = SERVER_CERTIFICATE_REQUEST, + }, + { .mt = SERVER_CERTIFICATE, + .flag = WITHOUT_CR, + }, + { + .mt = SERVER_FINISHED, + .flag = WITH_PSK, + }, + }, + [SERVER_CERTIFICATE_REQUEST] = { + { + .mt = SERVER_CERTIFICATE, + }, + }, + [SERVER_CERTIFICATE] = { + { + .mt = SERVER_CERTIFICATE_VERIFY, + }, + }, + [SERVER_CERTIFICATE_VERIFY] = { + { + .mt = SERVER_FINISHED, + }, + }, + [SERVER_FINISHED] = { + { + .mt = CLIENT_FINISHED, + .forced = WITHOUT_CR | WITH_PSK, + }, + { + .mt = CLIENT_CERTIFICATE, + .illegal = WITHOUT_CR | WITH_PSK, + }, + }, + [CLIENT_CERTIFICATE] = { + { + .mt = CLIENT_FINISHED, + }, + { + .mt = CLIENT_CERTIFICATE_VERIFY, + .flag = WITH_CCV, + }, + }, + [CLIENT_CERTIFICATE_VERIFY] = { + { + .mt = CLIENT_FINISHED, + }, + }, + [CLIENT_FINISHED] = { + { + .mt = APPLICATION_DATA, + }, + }, + [APPLICATION_DATA] = { + { + .mt = 0, + }, + }, +}; + +const size_t stateinfo_count = sizeof(stateinfo) / sizeof(stateinfo[0]); + +void build_table(enum tls13_message_type + table[MAX_FLAGS][TLS13_NUM_MESSAGE_TYPES], + struct child current, struct child end, + struct child path[], uint8_t flags, unsigned int depth); +size_t count_handshakes(void); +void edge(enum tls13_message_type start, + enum tls13_message_type end, uint8_t flag); +const char *flag2str(uint8_t flag); +void flag_label(uint8_t flag); +void forced_edges(enum tls13_message_type start, + enum tls13_message_type end, uint8_t forced); +int generate_graphics(void); +void fprint_entry(FILE *stream, + enum tls13_message_type path[TLS13_NUM_MESSAGE_TYPES], + uint8_t flags); +void fprint_flags(FILE *stream, uint8_t flags); +const char *mt2str(enum tls13_message_type mt); +void usage(void); +int verify_table(enum tls13_message_type + table[MAX_FLAGS][TLS13_NUM_MESSAGE_TYPES], int print); + +const char * +flag2str(uint8_t flag) +{ + const char *ret; + + if (flag & (flag - 1)) + errx(1, "more than one bit is set"); + + switch (flag) { + case INITIAL: + ret = "INITIAL"; + break; + case NEGOTIATED: + ret = "NEGOTIATED"; + break; + case WITHOUT_CR: + ret = "WITHOUT_CR"; + break; + case WITHOUT_HRR: + ret = "WITHOUT_HRR"; + break; + case WITH_PSK: + ret = "WITH_PSK"; + break; + case WITH_CCV: + ret = "WITH_CCV"; + break; + case WITH_0RTT: + ret = "WITH_0RTT"; + break; + default: + ret = "UNKNOWN"; + } + + return ret; +} + +const char * +mt2str(enum tls13_message_type mt) +{ + const char *ret; + + switch (mt) { + case INVALID: + ret = "INVALID"; + break; + case CLIENT_HELLO: + ret = "CLIENT_HELLO"; + break; + case CLIENT_HELLO_RETRY: + ret = "CLIENT_HELLO_RETRY"; + break; + case CLIENT_END_OF_EARLY_DATA: + ret = "CLIENT_END_OF_EARLY_DATA"; + break; + case CLIENT_CERTIFICATE: + ret = "CLIENT_CERTIFICATE"; + break; + case CLIENT_CERTIFICATE_VERIFY: + ret = "CLIENT_CERTIFICATE_VERIFY"; + break; + case CLIENT_FINISHED: + ret = "CLIENT_FINISHED"; + break; + case SERVER_HELLO: + ret = "SERVER_HELLO"; + break; + case SERVER_HELLO_RETRY_REQUEST: + ret = "SERVER_HELLO_RETRY_REQUEST"; + break; + case SERVER_ENCRYPTED_EXTENSIONS: + ret = "SERVER_ENCRYPTED_EXTENSIONS"; + break; + case SERVER_CERTIFICATE: + ret = "SERVER_CERTIFICATE"; + break; + case SERVER_CERTIFICATE_VERIFY: + ret = "SERVER_CERTIFICATE_VERIFY"; + break; + case SERVER_CERTIFICATE_REQUEST: + ret = "SERVER_CERTIFICATE_REQUEST"; + break; + case SERVER_FINISHED: + ret = "SERVER_FINISHED"; + break; + case APPLICATION_DATA: + ret = "APPLICATION_DATA"; + break; + case TLS13_NUM_MESSAGE_TYPES: + ret = "TLS13_NUM_MESSAGE_TYPES"; + break; + default: + ret = "UNKNOWN"; + break; + } + + return ret; +} + +void +fprint_flags(FILE *stream, uint8_t flags) +{ + int first = 1, i; + + if (flags == 0) { + fprintf(stream, "%s", flag2str(flags)); + return; + } + + for (i = 0; i < 8; i++) { + uint8_t set = flags & (1U << i); + + if (set) { + fprintf(stream, "%s%s", first ? "" : " | ", + flag2str(set)); + first = 0; + } + } +} + +void +fprint_entry(FILE *stream, + enum tls13_message_type path[TLS13_NUM_MESSAGE_TYPES], uint8_t flags) +{ + int i; + + fprintf(stream, "\t["); + fprint_flags(stream, flags); + fprintf(stream, "] = {\n"); + + for (i = 0; i < TLS13_NUM_MESSAGE_TYPES; i++) { + if (path[i] == 0) + break; + fprintf(stream, "\t\t%s,\n", mt2str(path[i])); + } + fprintf(stream, "\t},\n"); +} + +void +edge(enum tls13_message_type start, enum tls13_message_type end, + uint8_t flag) +{ + printf("\t%s -> %s", mt2str(start), mt2str(end)); + flag_label(flag); + printf(";\n"); +} + +void +flag_label(uint8_t flag) +{ + if (flag) + printf(" [label=\"%s\"]", flag2str(flag)); +} + +void +forced_edges(enum tls13_message_type start, enum tls13_message_type end, + uint8_t forced) +{ + uint8_t forced_flag, i; + + if (forced == 0) + return; + + for (i = 0; i < 8; i++) { + forced_flag = forced & (1U << i); + if (forced_flag) + edge(start, end, forced_flag); + } +} + +int +generate_graphics(void) +{ + enum tls13_message_type start, end; + unsigned int child; + uint8_t flag; + uint8_t forced; + + printf("digraph G {\n"); + printf("\t%s [shape=box];\n", mt2str(CLIENT_HELLO)); + printf("\t%s [shape=box];\n", mt2str(APPLICATION_DATA)); + + for (start = CLIENT_HELLO; start < APPLICATION_DATA; start++) { + for (child = 0; stateinfo[start][child].mt != 0; child++) { + end = stateinfo[start][child].mt; + flag = stateinfo[start][child].flag; + forced = stateinfo[start][child].forced; + + if (forced == 0) + edge(start, end, flag); + else + forced_edges(start, end, forced); + } + } + + printf("}\n"); + return 0; +} + +extern enum tls13_message_type handshakes[][TLS13_NUM_MESSAGE_TYPES]; +extern size_t handshake_count; + +size_t +count_handshakes(void) +{ + size_t ret = 0, i; + + for (i = 0; i < handshake_count; i++) { + if (handshakes[i][0] != INVALID) + ret++; + } + + return ret; +} + +void +build_table(enum tls13_message_type table[MAX_FLAGS][TLS13_NUM_MESSAGE_TYPES], + struct child current, struct child end, struct child path[], uint8_t flags, + unsigned int depth) +{ + unsigned int i; + + if (depth >= TLS13_NUM_MESSAGE_TYPES - 1) + errx(1, "recursed too deeply"); + + /* Record current node. */ + path[depth++] = current; + flags |= current.flag; + + /* If we haven't reached the end, recurse over the children. */ + if (current.mt != end.mt) { + for (i = 0; stateinfo[current.mt][i].mt != 0; i++) { + struct child child = stateinfo[current.mt][i]; + int forced = stateinfo[current.mt][i].forced; + int illegal = stateinfo[current.mt][i].illegal; + + if ((forced == 0 || (forced & flags)) && + (illegal == 0 || !(illegal & flags))) + build_table(table, child, end, path, flags, + depth); + } + return; + } + + if (flags == 0) + errx(1, "path does not set flags"); + + if (table[flags][0] != 0) + errx(1, "path traversed twice"); + + for (i = 0; i < depth; i++) + table[flags][i] = path[i].mt; +} + +int +verify_table(enum tls13_message_type table[MAX_FLAGS][TLS13_NUM_MESSAGE_TYPES], + int print) +{ + int success = 1, i; + size_t num_valid, num_found = 0; + uint8_t flags = 0; + + do { + if (table[flags][0] == 0) + continue; + + num_found++; + + for (i = 0; i < TLS13_NUM_MESSAGE_TYPES; i++) { + if (table[flags][i] != handshakes[flags][i]) { + fprintf(stderr, + "incorrect entry %d of handshake ", i); + fprint_flags(stderr, flags); + fprintf(stderr, "\n"); + success = 0; + } + } + + if (print) + fprint_entry(stdout, table[flags], flags); + } while(++flags != 0); + + num_valid = count_handshakes(); + if (num_valid != num_found) { + fprintf(stderr, + "incorrect number of handshakes: want %zu, got %zu.\n", + num_valid, num_found); + success = 0; + } + + return success; +} + +void +usage(void) +{ + fprintf(stderr, "usage: handshake_table [-C | -g]\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + static enum tls13_message_type + hs_table[MAX_FLAGS][TLS13_NUM_MESSAGE_TYPES] = { + [INITIAL] = { + CLIENT_HELLO, + SERVER_HELLO_RETRY_REQUEST, + CLIENT_HELLO_RETRY, + SERVER_HELLO, + }, + }; + struct child start = { + .mt = CLIENT_HELLO, + }; + struct child end = { + .mt = APPLICATION_DATA, + }; + struct child path[TLS13_NUM_MESSAGE_TYPES] = {{0}}; + uint8_t flags = NEGOTIATED; + unsigned int depth = 0; + int ch, graphviz = 0, print = 0; + + while ((ch = getopt(argc, argv, "Cg")) != -1) { + switch (ch) { + case 'C': + print = 1; + break; + case 'g': + graphviz = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc != 0) + usage(); + + if (graphviz && print) + usage(); + + if (graphviz) + return generate_graphics(); + + build_table(hs_table, start, end, path, flags, depth); + if (!verify_table(hs_table, print)) + return 1; + + return 0; +} diff --git a/Libraries/libressl/tests/hkdf_test.c b/Libraries/libressl/tests/hkdf_test.c new file mode 100644 index 000000000..5e89f3384 --- /dev/null +++ b/Libraries/libressl/tests/hkdf_test.c @@ -0,0 +1,300 @@ +/* $OpenBSD: hkdf_test.c,v 1.2 2018/07/17 17:06:49 tb Exp $ */ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include + +#include +#include +#include +#include + +#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +typedef struct HKDFTestVector_st { + const EVP_MD *(*md_func)(void); + const uint8_t ikm[80]; + const size_t ikm_len; + const uint8_t salt[80]; + const size_t salt_len; + const uint8_t info[80]; + const size_t info_len; + const uint8_t prk[EVP_MAX_MD_SIZE]; + const size_t prk_len; + const size_t out_len; + const uint8_t out[82]; +} HKDFTestVector; + +/* These test vectors are from RFC 5869. */ +static const HKDFTestVector kTests[] = { + { + EVP_sha256, + { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + }, 22, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, + }, 13, + { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + }, 10, + { + 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d, + 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31, + 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5, + }, 32, + 42, { + 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, + 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, + 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, + 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 + } + }, + { + EVP_sha256, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f + }, 80, + { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf + }, 80, + { + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, 80, + { + 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a, 0x06, 0x10, 0x4c, 0x9c, + 0xeb, 0x35, 0xb4, 0x5c, 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01, + 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44, + }, 32, + 82, { + 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c, + 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, + 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99, + 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09, + 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9, + 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, + 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87 + } + }, + { + EVP_sha256, + { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + }, 22, + { + 0, + }, 0, + { + 0, + }, 0, + { + 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d, + 0x6f, 0x64, 0x8b, 0xdf, 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77, + 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04 + }, 32, + 42, { + 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a, + 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, + 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, 0x20, 0x13, 0x95, + 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8 + } + }, + { + EVP_sha1, + { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + }, 11, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, + }, 13, + { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + }, 10, + { + 0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f, 0x0e, 0x71, 0xc8, 0xeb, + 0x88, 0xf4, 0xb3, 0x0b, 0xaa, 0x2b, 0xa2, 0x43 + }, 20, + 42, { + 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, 0x56, + 0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15, + 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, 0xc2, 0x2e, 0x42, 0x24, + 0x78, 0xd3, 0x05, 0xf3, 0xf8, 0x96 + } + }, + { + EVP_sha1, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f + }, 80, + { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf + }, 80, + { + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, 80, + { + 0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59, 0x47, 0x8d, 0x30, 0x9b, + 0x26, 0xc4, 0x11, 0x5a, 0x22, 0x4c, 0xfa, 0xf6, + }, 20, + 82, { + 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5, + 0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19, + 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3, 0xf1, 0xa4, + 0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c, + 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c, 0x7f, 0x9d, + 0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43, + 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4 + } + }, + { + EVP_sha1, + { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + }, 22, + { + 0, + }, 0, + { + 0, + }, 0, + { + 0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28, 0x8e, 0xc6, 0xf5, 0xe7, + 0xc2, 0x97, 0x78, 0x6a, 0xa0, 0xd3, 0x2d, 0x01, + }, 20, + 42, { + 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, 0x98, + 0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06, + 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, 0xea, 0x00, 0x03, 0x3d, + 0xe0, 0x39, 0x84, 0xd3, 0x49, 0x18 + } + }, + { + EVP_sha1, + { + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + }, 22, + { + 0, + }, 0, + { + 0, + }, 0, + { + 0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c, 0x20, 0x77, 0xad, 0x2e, + 0xb1, 0x9d, 0x3f, 0x3e, 0x73, 0x13, 0x85, 0xdd, + }, 20, + 42, { + 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, 0x6a, + 0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23, + 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, 0x67, 0x3a, 0x08, 0x1d, + 0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48 + } + }, +}; + +int main(void) { + size_t i; + OPENSSL_add_all_algorithms_noconf(); + + for (i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) { + const HKDFTestVector *test = &kTests[i]; + uint8_t prk[EVP_MAX_MD_SIZE]; + uint8_t buf[82]; + size_t prk_len; + if (!HKDF_extract(prk, &prk_len, test->md_func(), test->ikm, + test->ikm_len, test->salt, test->salt_len)) { + fprintf(stderr, "Call to HKDF_extract failed\n"); + ERR_print_errors_fp(stderr); + return 1; + } + if (prk_len != test->prk_len || + memcmp(prk, test->prk, test->prk_len) != 0) { + fprintf(stderr, "%zu: Resulting PRK does not match" + "test vector\n", i); + return 1; + } + if (!HKDF_expand(buf, test->out_len, test->md_func(), prk, prk_len, + test->info, test->info_len)) { + fprintf(stderr, "Call to HKDF_expand failed\n"); + ERR_print_errors_fp(stderr); + return 1; + } + if (memcmp(buf, test->out, test->out_len) != 0) { + fprintf(stderr, + "%zu: Resulting key material does not match test" + "vector\n", i); + return 1; + } + + if (!HKDF(buf, test->out_len, test->md_func(), test->ikm, + test->ikm_len, test->salt, test->salt_len, test->info, + test->info_len)) { + fprintf(stderr, "Call to HKDF failed\n"); + ERR_print_errors_fp(stderr); + return 1; + } + if (memcmp(buf, test->out, test->out_len) != 0) { + fprintf(stderr, + "%zu: Resulting key material does not match test" + "vector\n", i); + return 1; + } + } + + printf("PASS\n"); + return 0; +} diff --git a/Libraries/libressl/tests/hmactest.c b/Libraries/libressl/tests/hmactest.c new file mode 100644 index 000000000..f61a177e1 --- /dev/null +++ b/Libraries/libressl/tests/hmactest.c @@ -0,0 +1,335 @@ +/* $OpenBSD: hmactest.c,v 1.7 2021/11/18 20:11:55 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#ifndef OPENSSL_NO_MD5 +#include +#endif + +#ifndef OPENSSL_NO_MD5 +static struct test_st { + unsigned char key[16]; + int key_len; + unsigned char data[64]; + int data_len; + unsigned char *digest; +} test[8] = { + { "", + 0, + "More text test vectors to stuff up EBCDIC machines :-)", + 54, + (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86", + }, + { {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b, + 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,}, + 16, + "Hi There", + 8, + (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d", + }, + { "Jefe", + 4, + "what do ya want for nothing?", + 28, + (unsigned char *)"750c783e6ab0b503eaa86e310a5db738", + }, + { {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,}, + 16, + {0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, + 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, + 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, + 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, + 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, + 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, + 0xdd,0xdd}, + 50, + (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6", + }, + { "", + 0, + "My test data", + 12, + (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc" + }, + { "", + 0, + "My test data", + 12, + (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776" + }, + { "123456", + 6, + "My test data", + 12, + (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd" + }, + { "12345", + 5, + "My test data again", + 12, + (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb" + } +}; +#endif + +static char *pt(unsigned char *md, unsigned int len); + +int +main(int argc, char *argv[]) +{ +#ifndef OPENSSL_NO_MD5 + int i; + char *p; +#endif + int err = 0; + HMAC_CTX *ctx = NULL, *ctx2 = NULL; + unsigned char buf[EVP_MAX_MD_SIZE]; + unsigned int len; + +#ifdef OPENSSL_NO_MD5 + printf("test skipped: MD5 disabled\n"); +#else + + for (i = 0; i < 4; i++) { + p = pt(HMAC(EVP_md5(), + test[i].key, test[i].key_len, + test[i].data, test[i].data_len, NULL, NULL), + MD5_DIGEST_LENGTH); + + if (strcmp(p, (char *)test[i].digest) != 0) { + printf("error calculating HMAC on %d entry'\n", i); + printf("got %s instead of %s\n", p, test[i].digest); + err++; + } else + printf("test %d ok\n", i); + } +#endif /* OPENSSL_NO_MD5 */ + +/* test4 */ + if ((ctx = HMAC_CTX_new()) == NULL) { + printf("HMAC_CTX_init failed (test 4)\n"); + exit(1); + } + if (HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) { + printf("Should fail to initialise HMAC with empty MD and key (test 4)\n"); + err++; + goto test5; + } + if (HMAC_Update(ctx, test[4].data, test[4].data_len)) { + printf("Should fail HMAC_Update with ctx not set up (test 4)\n"); + err++; + goto test5; + } + if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) { + printf("Should fail to initialise HMAC with empty key (test 4)\n"); + err++; + goto test5; + } + if (HMAC_Update(ctx, test[4].data, test[4].data_len)) { + printf("Should fail HMAC_Update with ctx not set up (test 4)\n"); + err++; + goto test5; + } + printf("test 4 ok\n"); + test5: + HMAC_CTX_reset(ctx); + if (HMAC_Init_ex(ctx, test[4].key, test[4].key_len, NULL, NULL)) { + printf("Should fail to initialise HMAC with empty MD (test 5)\n"); + err++; + goto test6; + } + if (HMAC_Update(ctx, test[4].data, test[4].data_len)) { + printf("Should fail HMAC_Update with ctx not set up (test 5)\n"); + err++; + goto test6; + } + if (HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL)) { + printf("Should fail to initialise HMAC with invalid key len(test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) { + printf("Failed to initialise HMAC (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Update(ctx, test[4].data, test[4].data_len)) { + printf("Error updating HMAC with data (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Final(ctx, buf, &len)) { + printf("Error finalising data (test 5)\n"); + err++; + goto test6; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[4].digest) != 0) { + printf("Error calculating interim HMAC on test 5\n"); + printf("got %s instead of %s\n", p, test[4].digest); + err++; + goto test6; + } + if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) { + printf("Should disallow changing MD without a new key (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) { + printf("Failed to reinitialise HMAC (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Update(ctx, test[5].data, test[5].data_len)) { + printf("Error updating HMAC with data (sha256) (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Final(ctx, buf, &len)) { + printf("Error finalising data (sha256) (test 5)\n"); + err++; + goto test6; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[5].digest) != 0) { + printf("Error calculating 2nd interim HMAC on test 5\n"); + printf("got %s instead of %s\n", p, test[5].digest); + err++; + goto test6; + } + if (!HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) { + printf("Failed to reinitialise HMAC with key (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Update(ctx, test[6].data, test[6].data_len)) { + printf("Error updating HMAC with data (new key) (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Final(ctx, buf, &len)) { + printf("Error finalising data (new key) (test 5)\n"); + err++; + goto test6; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[6].digest) != 0) { + printf("error calculating HMAC on test 5\n"); + printf("got %s instead of %s\n", p, test[6].digest); + err++; + } else { + printf("test 5 ok\n"); + } + test6: + HMAC_CTX_reset(ctx); + if (!HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) { + printf("Failed to initialise HMAC (test 6)\n"); + err++; + goto end; + } + if (!HMAC_Update(ctx, test[7].data, test[7].data_len)) { + printf("Error updating HMAC with data (test 6)\n"); + err++; + goto end; + } + if ((ctx2 = HMAC_CTX_new()) == NULL) { + printf("HMAC_CTX_new failed (test 6)\n"); + exit(1); + } + if (!HMAC_CTX_copy(ctx2, ctx)) { + printf("Failed to copy HMAC_CTX (test 6)\n"); + err++; + goto end; + } + if (!HMAC_Final(ctx2, buf, &len)) { + printf("Error finalising data (test 6)\n"); + err++; + goto end; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[7].digest) != 0) { + printf("Error calculating HMAC on test 6\n"); + printf("got %s instead of %s\n", p, test[7].digest); + err++; + } else { + printf("test 6 ok\n"); + } +end: + HMAC_CTX_free(ctx); + HMAC_CTX_free(ctx2); + exit(err); + return(0); +} + +#ifndef OPENSSL_NO_MD5 +static char * +pt(unsigned char *md, unsigned int len) +{ + unsigned int i; + static char buf[80]; + + for (i = 0; i < len; i++) + snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x", md[i]); + return(buf); +} +#endif diff --git a/Libraries/libressl/tests/ideatest.c b/Libraries/libressl/tests/ideatest.c new file mode 100644 index 000000000..b33b824ae --- /dev/null +++ b/Libraries/libressl/tests/ideatest.c @@ -0,0 +1,221 @@ +/* $OpenBSD: ideatest.c,v 1.2 2018/07/17 17:06:49 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +unsigned char k[16]={ + 0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04, + 0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08}; + +unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03}; +unsigned char c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5}; +unsigned char out[80]; + +char *text="Hello to all people out there"; + +static unsigned char cfb_key[16]={ + 0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96, + 0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e, + }; +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd}; +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; +#define CFB_TEST_SIZE 24 +static unsigned char plain[CFB_TEST_SIZE]= + { + 0x4e,0x6f,0x77,0x20,0x69,0x73, + 0x20,0x74,0x68,0x65,0x20,0x74, + 0x69,0x6d,0x65,0x20,0x66,0x6f, + 0x72,0x20,0x61,0x6c,0x6c,0x20 + }; +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={ + 0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F, + 0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A, + 0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45 + +/* 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38, + 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9, + 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/ + }; + +static int cfb64_test(unsigned char *cfb_cipher); +static char *pt(unsigned char *p); +int main(int argc, char *argv[]) + { + int i,err=0; + IDEA_KEY_SCHEDULE key,dkey; + unsigned char iv[8]; + + idea_set_encrypt_key(k,&key); + idea_ecb_encrypt(in,out,&key); + if (memcmp(out,c,8) != 0) + { + printf("ecb idea error encrypting\n"); + printf("got :"); + for (i=0; i<8; i++) + printf("%02X ",out[i]); + printf("\n"); + printf("expected:"); + for (i=0; i<8; i++) + printf("%02X ",c[i]); + err=20; + printf("\n"); + } + + idea_set_decrypt_key(&key,&dkey); + idea_ecb_encrypt(c,out,&dkey); + if (memcmp(out,in,8) != 0) + { + printf("ecb idea error decrypting\n"); + printf("got :"); + for (i=0; i<8; i++) + printf("%02X ",out[i]); + printf("\n"); + printf("expected:"); + for (i=0; i<8; i++) + printf("%02X ",in[i]); + printf("\n"); + err=3; + } + + if (err == 0) printf("ecb idea ok\n"); + + memcpy(iv,k,8); + idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1); + memcpy(iv,k,8); + idea_cbc_encrypt(out,out,8,&dkey,iv,0); + idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0); + if (memcmp(text,out,strlen(text)+1) != 0) + { + printf("cbc idea bad\n"); + err=4; + } + else + printf("cbc idea ok\n"); + + printf("cfb64 idea "); + if (cfb64_test(cfb_cipher64)) + { + printf("bad\n"); + err=5; + } + else + printf("ok\n"); + + exit(err); + } + +static int cfb64_test(unsigned char *cfb_cipher) + { + IDEA_KEY_SCHEDULE eks,dks; + int err=0,i,n; + + idea_set_encrypt_key(cfb_key,&eks); + idea_set_decrypt_key(&eks,&dks); + memcpy(cfb_tmp,cfb_iv,8); + n=0; + idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks, + cfb_tmp,&n,IDEA_ENCRYPT); + idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), + (long)CFB_TEST_SIZE-12,&eks, + cfb_tmp,&n,IDEA_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0) + { + err=1; + printf("idea_cfb64_encrypt encrypt error\n"); + for (i=0; i>4)&0xf]; + ret[i*2+1]=f[p[i]&0xf]; + } + ret[16]='\0'; + return(ret); + } diff --git a/Libraries/libressl/tests/igetest.c b/Libraries/libressl/tests/igetest.c new file mode 100644 index 000000000..2191af85b --- /dev/null +++ b/Libraries/libressl/tests/igetest.c @@ -0,0 +1,370 @@ +/* $OpenBSD: igetest.c,v 1.4 2018/07/17 17:06:49 tb Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include + +#include + +#define TEST_SIZE 128 +#define BIG_TEST_SIZE 10240 + +static void hexdump(FILE *f,const char *title,const unsigned char *s,int l) + { + int n=0; + + fprintf(f,"%s",title); + for( ; n < l ; ++n) + { + if((n%16) == 0) + fprintf(f,"\n%04x",n); + fprintf(f," %02x",s[n]); + } + fprintf(f,"\n"); + } + +#define MAX_VECTOR_SIZE 64 + +struct ige_test + { + const unsigned char key[16]; + const unsigned char iv[32]; + const unsigned char in[MAX_VECTOR_SIZE]; + const unsigned char out[MAX_VECTOR_SIZE]; + const size_t length; + const int encrypt; + }; + +static struct ige_test const ige_test_vectors[] = { +{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* iv */ + { 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, 0x00 }, /* in */ + { 0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52, + 0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45, + 0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3, + 0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb }, /* out */ + 32, AES_ENCRYPT }, /* test vector 0 */ + +{ { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65 }, /* key */ + { 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45, + 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53 }, /* iv */ + { 0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73, + 0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65, + 0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74, + 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a }, /* in */ + { 0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13, + 0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a, + 0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34, + 0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b }, /* out */ + 32, AES_DECRYPT }, /* test vector 1 */ +}; + +static int run_test_vectors(void) + { + unsigned int n; + int errs = 0; + + for(n=0 ; n < sizeof(ige_test_vectors)/sizeof(ige_test_vectors[0]) ; ++n) + { + const struct ige_test * const v = &ige_test_vectors[n]; + AES_KEY key; + unsigned char buf[MAX_VECTOR_SIZE]; + unsigned char iv[AES_BLOCK_SIZE*2]; + + assert(v->length <= MAX_VECTOR_SIZE); + + if(v->encrypt == AES_ENCRYPT) + AES_set_encrypt_key(v->key, 8*sizeof v->key, &key); + else + AES_set_decrypt_key(v->key, 8*sizeof v->key, &key); + memcpy(iv, v->iv, sizeof iv); + AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt); + + if(memcmp(v->out, buf, v->length)) + { + printf("IGE test vector %d failed\n", n); + hexdump(stdout, "key", v->key, sizeof v->key); + hexdump(stdout, "iv", v->iv, sizeof v->iv); + hexdump(stdout, "in", v->in, v->length); + hexdump(stdout, "expected", v->out, v->length); + hexdump(stdout, "got", buf, v->length); + + ++errs; + } + + /* try with in == out */ + memcpy(iv, v->iv, sizeof iv); + memcpy(buf, v->in, v->length); + AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt); + + if(memcmp(v->out, buf, v->length)) + { + printf("IGE test vector %d failed (with in == out)\n", n); + hexdump(stdout, "key", v->key, sizeof v->key); + hexdump(stdout, "iv", v->iv, sizeof v->iv); + hexdump(stdout, "in", v->in, v->length); + hexdump(stdout, "expected", v->out, v->length); + hexdump(stdout, "got", buf, v->length); + + ++errs; + } + } + + return errs; + } + +int main(int argc, char **argv) + { + unsigned char rkey[16]; + unsigned char rkey2[16]; + AES_KEY key; + AES_KEY key2; + unsigned char plaintext[BIG_TEST_SIZE]; + unsigned char ciphertext[BIG_TEST_SIZE]; + unsigned char checktext[BIG_TEST_SIZE]; + unsigned char iv[AES_BLOCK_SIZE*4]; + unsigned char saved_iv[AES_BLOCK_SIZE*4]; + int err = 0; + unsigned int n; + unsigned matches; + + assert(BIG_TEST_SIZE >= TEST_SIZE); + + arc4random_buf(rkey, sizeof(rkey)); + arc4random_buf(plaintext, sizeof(plaintext)); + arc4random_buf(iv, sizeof(iv)); + memcpy(saved_iv, iv, sizeof(saved_iv)); + + /* Forward IGE only... */ + + /* Straight encrypt/decrypt */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, + AES_ENCRYPT); + + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, + AES_DECRYPT); + + if(memcmp(checktext, plaintext, TEST_SIZE)) + { + printf("Encrypt+decrypt doesn't match\n"); + hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); + hexdump(stdout, "Checktext", checktext, TEST_SIZE); + ++err; + } + + /* Now check encrypt chaining works */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv, + AES_ENCRYPT); + AES_ige_encrypt(plaintext+TEST_SIZE/2, + ciphertext+TEST_SIZE/2, TEST_SIZE/2, + &key, iv, AES_ENCRYPT); + + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, + AES_DECRYPT); + + if(memcmp(checktext, plaintext, TEST_SIZE)) + { + printf("Chained encrypt+decrypt doesn't match\n"); + hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); + hexdump(stdout, "Checktext", checktext, TEST_SIZE); + ++err; + } + + /* And check decrypt chaining */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv, + AES_ENCRYPT); + AES_ige_encrypt(plaintext+TEST_SIZE/2, + ciphertext+TEST_SIZE/2, TEST_SIZE/2, + &key, iv, AES_ENCRYPT); + + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(ciphertext, checktext, TEST_SIZE/2, &key, iv, + AES_DECRYPT); + AES_ige_encrypt(ciphertext+TEST_SIZE/2, + checktext+TEST_SIZE/2, TEST_SIZE/2, &key, iv, + AES_DECRYPT); + + if(memcmp(checktext, plaintext, TEST_SIZE)) + { + printf("Chained encrypt+chained decrypt doesn't match\n"); + hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); + hexdump(stdout, "Checktext", checktext, TEST_SIZE); + ++err; + } + + /* make sure garble extends forwards only */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv, + AES_ENCRYPT); + + /* corrupt halfway through */ + ++ciphertext[sizeof ciphertext/2]; + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + memcpy(iv, saved_iv, sizeof iv); + AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv, + AES_DECRYPT); + + matches=0; + for(n=0 ; n < sizeof checktext ; ++n) + if(checktext[n] == plaintext[n]) + ++matches; + + if(matches > sizeof checktext/2+sizeof checktext/100) + { + printf("More than 51%% matches after garbling\n"); + ++err; + } + + if(matches < sizeof checktext/2) + { + printf("Garble extends backwards!\n"); + ++err; + } + + /* make sure garble extends both ways */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2); + AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv, + AES_ENCRYPT); + + /* corrupt halfway through */ + ++ciphertext[sizeof ciphertext/2]; + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2); + AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv, + AES_DECRYPT); + + matches=0; + for(n=0 ; n < sizeof checktext ; ++n) + if(checktext[n] == plaintext[n]) + ++matches; + + if(matches > sizeof checktext/100) + { + printf("More than 1%% matches after bidirectional garbling\n"); + ++err; + } + + /* make sure garble extends both ways (2) */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2); + AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv, + AES_ENCRYPT); + + /* corrupt right at the end */ + ++ciphertext[sizeof ciphertext-1]; + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2); + AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv, + AES_DECRYPT); + + matches=0; + for(n=0 ; n < sizeof checktext ; ++n) + if(checktext[n] == plaintext[n]) + ++matches; + + if(matches > sizeof checktext/100) + { + printf("More than 1%% matches after bidirectional garbling (2)\n"); + ++err; + } + + /* make sure garble extends both ways (3) */ + AES_set_encrypt_key(rkey, 8*sizeof rkey, &key); + AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2); + AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv, + AES_ENCRYPT); + + /* corrupt right at the start */ + ++ciphertext[0]; + AES_set_decrypt_key(rkey, 8*sizeof rkey, &key); + AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2); + AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv, + AES_DECRYPT); + + matches=0; + for(n=0 ; n < sizeof checktext ; ++n) + if(checktext[n] == plaintext[n]) + ++matches; + + if(matches > sizeof checktext/100) + { + printf("More than 1%% matches after bidirectional garbling (3)\n"); + ++err; + } + + err += run_test_vectors(); + + return err; + } diff --git a/Libraries/libressl/tests/key_schedule.c b/Libraries/libressl/tests/key_schedule.c new file mode 100644 index 000000000..f937d042c --- /dev/null +++ b/Libraries/libressl/tests/key_schedule.c @@ -0,0 +1,317 @@ +/* $OpenBSD: key_schedule.c,v 1.10 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2018-2019 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" + +#include "bytestring.h" +#include "ssl_tlsext.h" +#include "tls13_internal.h" + +static int failures = 0; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static void +compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, + size_t expect_len) +{ + fprintf(stderr, "received:\n"); + hexdump(recv, recv_len); + + fprintf(stderr, "test data:\n"); + hexdump(expect, expect_len); +} + +#define FAIL(msg, ...) \ +do { \ + fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ + fprintf(stderr, msg, ##__VA_ARGS__); \ + failures++; \ +} while(0) + +/* Hashes and secrets from test vector */ + +uint8_t chello[] = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 +}; +const struct tls13_secret chello_hash = { + .data = chello, + .len = 32, +}; + +uint8_t cshello [] = { + 0x86, 0x0c, 0x06, 0xed, 0xc0, 0x78, 0x58, 0xee, + 0x8e, 0x78, 0xf0, 0xe7, 0x42, 0x8c, 0x58, 0xed, + 0xd6, 0xb4, 0x3f, 0x2c, 0xa3, 0xe6, 0xe9, 0x5f, + 0x02, 0xed, 0x06, 0x3c, 0xf0, 0xe1, 0xca, 0xd8 +}; + +const struct tls13_secret cshello_hash = { + .data = cshello, + .len = 32, +}; + +const uint8_t ecdhe [] = { + 0x8b, 0xd4, 0x05, 0x4f, 0xb5, 0x5b, 0x9d, 0x63, + 0xfd, 0xfb, 0xac, 0xf9, 0xf0, 0x4b, 0x9f, 0x0d, + 0x35, 0xe6, 0xd6, 0x3f, 0x53, 0x75, 0x63, 0xef, + 0xd4, 0x62, 0x72, 0x90, 0x0f, 0x89, 0x49, 0x2d +}; + +uint8_t csfhello [] = { + 0x96, 0x08, 0x10, 0x2a, 0x0f, 0x1c, 0xcc, 0x6d, + 0xb6, 0x25, 0x0b, 0x7b, 0x7e, 0x41, 0x7b, 0x1a, + 0x00, 0x0e, 0xaa, 0xda, 0x3d, 0xaa, 0xe4, 0x77, + 0x7a, 0x76, 0x86, 0xc9, 0xff, 0x83, 0xdf, 0x13 +}; + +const struct tls13_secret csfhello_hash = { + .data = csfhello, + .len = 32, +}; + + +/* Expected Values */ + +uint8_t expected_extracted_early[] = { + 0x33, 0xad, 0x0a, 0x1c, 0x60, 0x7e, 0xc0, 0x3b, + 0x09, 0xe6, 0xcd, 0x98, 0x93, 0x68, 0x0c, 0xe2, + 0x10, 0xad, 0xf3, 0x00, 0xaa, 0x1f, 0x26, 0x60, + 0xe1, 0xb2, 0x2e, 0x10, 0xf1, 0x70, 0xf9, 0x2a +}; +uint8_t expected_derived_early[] = { + 0x6f, 0x26, 0x15, 0xa1, 0x08, 0xc7, 0x02, 0xc5, + 0x67, 0x8f, 0x54, 0xfc, 0x9d, 0xba, 0xb6, 0x97, + 0x16, 0xc0, 0x76, 0x18, 0x9c, 0x48, 0x25, 0x0c, + 0xeb, 0xea, 0xc3, 0x57, 0x6c, 0x36, 0x11, 0xba +}; +uint8_t expected_extracted_handshake[] = { + 0x1d, 0xc8, 0x26, 0xe9, 0x36, 0x06, 0xaa, 0x6f, + 0xdc, 0x0a, 0xad, 0xc1, 0x2f, 0x74, 0x1b, 0x01, + 0x04, 0x6a, 0xa6, 0xb9, 0x9f, 0x69, 0x1e, 0xd2, + 0x21, 0xa9, 0xf0, 0xca, 0x04, 0x3f, 0xbe, 0xac +}; +uint8_t expected_client_handshake_traffic[] = { + 0xb3, 0xed, 0xdb, 0x12, 0x6e, 0x06, 0x7f, 0x35, + 0xa7, 0x80, 0xb3, 0xab, 0xf4, 0x5e, 0x2d, 0x8f, + 0x3b, 0x1a, 0x95, 0x07, 0x38, 0xf5, 0x2e, 0x96, + 0x00, 0x74, 0x6a, 0x0e, 0x27, 0xa5, 0x5a, 0x21 +}; + +uint8_t expected_server_handshake_traffic[] = { + 0xb6, 0x7b, 0x7d, 0x69, 0x0c, 0xc1, 0x6c, 0x4e, + 0x75, 0xe5, 0x42, 0x13, 0xcb, 0x2d, 0x37, 0xb4, + 0xe9, 0xc9, 0x12, 0xbc, 0xde, 0xd9, 0x10, 0x5d, + 0x42, 0xbe, 0xfd, 0x59, 0xd3, 0x91, 0xad, 0x38 +}; + +uint8_t expected_derived_handshake[] = { + 0x43, 0xde, 0x77, 0xe0, 0xc7, 0x77, 0x13, 0x85, + 0x9a, 0x94, 0x4d, 0xb9, 0xdb, 0x25, 0x90, 0xb5, + 0x31, 0x90, 0xa6, 0x5b, 0x3e, 0xe2, 0xe4, 0xf1, + 0x2d, 0xd7, 0xa0, 0xbb, 0x7c, 0xe2, 0x54, 0xb4 +}; + +uint8_t expected_extracted_master[] = { + 0x18, 0xdf, 0x06, 0x84, 0x3d, 0x13, 0xa0, 0x8b, + 0xf2, 0xa4, 0x49, 0x84, 0x4c, 0x5f, 0x8a, 0x47, + 0x80, 0x01, 0xbc, 0x4d, 0x4c, 0x62, 0x79, 0x84, + 0xd5, 0xa4, 0x1d, 0xa8, 0xd0, 0x40, 0x29, 0x19 +}; + +uint8_t expected_server_application_traffic[] = { + 0xa1, 0x1a, 0xf9, 0xf0, 0x55, 0x31, 0xf8, 0x56, + 0xad, 0x47, 0x11, 0x6b, 0x45, 0xa9, 0x50, 0x32, + 0x82, 0x04, 0xb4, 0xf4, 0x4b, 0xfb, 0x6b, 0x3a, + 0x4b, 0x4f, 0x1f, 0x3f, 0xcb, 0x63, 0x16, 0x43 +}; + +uint8_t expected_server_application_traffic_updated[] = { + 0x51, 0x92, 0x1b, 0x8a, 0xa3, 0x00, 0x19, 0x76, + 0xeb, 0x40, 0x1d, 0x0a, 0x43, 0x19, 0xa8, 0x51, + 0x64, 0x16, 0xa6, 0xc5, 0x60, 0x01, 0xa3, 0x57, + 0xe5, 0xd1, 0x62, 0x03, 0x1e, 0x84, 0xf9, 0x16, +}; + +uint8_t expected_client_application_traffic[] = { + 0x9e, 0x40, 0x64, 0x6c, 0xe7, 0x9a, 0x7f, 0x9d, + 0xc0, 0x5a, 0xf8, 0x88, 0x9b, 0xce, 0x65, 0x52, + 0x87, 0x5a, 0xfa, 0x0b, 0x06, 0xdf, 0x00, 0x87, + 0xf7, 0x92, 0xeb, 0xb7, 0xc1, 0x75, 0x04, 0xa5, +}; + +uint8_t expected_client_application_traffic_updated[] = { + 0xfc, 0xdf, 0xcc, 0x72, 0x72, 0x5a, 0xae, 0xe4, + 0x8b, 0xf6, 0x4e, 0x4f, 0xd8, 0xb7, 0x49, 0xcd, + 0xbd, 0xba, 0xb3, 0x9d, 0x90, 0xda, 0x0b, 0x26, + 0xe2, 0x24, 0x5c, 0xa6, 0xea, 0x16, 0x72, 0x07, +}; + +uint8_t expected_exporter_master[] = { + 0xfe, 0x22, 0xf8, 0x81, 0x17, 0x6e, 0xda, 0x18, + 0xeb, 0x8f, 0x44, 0x52, 0x9e, 0x67, 0x92, 0xc5, + 0x0c, 0x9a, 0x3f, 0x89, 0x45, 0x2f, 0x68, 0xd8, + 0xae, 0x31, 0x1b, 0x43, 0x09, 0xd3, 0xcf, 0x50 +}; + +int +main (int argc, char **argv) +{ + struct tls13_secrets *secrets; + + if ((secrets = tls13_secrets_create(EVP_sha256(), 0)) == NULL) + errx(1,"failed to create secrets\n"); + + secrets->insecure = 1; /* don't explicit_bzero when done */ + + if (tls13_derive_handshake_secrets(secrets, ecdhe, 32, &cshello_hash)) + FAIL("derive_handshake_secrets worked when it shouldn't\n"); + if (tls13_derive_application_secrets(secrets, + &chello_hash)) + FAIL("derive_application_secrets worked when it shouldn't\n"); + + if (!tls13_derive_early_secrets(secrets, + secrets->zeros.data, secrets->zeros.len, &chello_hash)) + FAIL("derive_early_secrets failed\n"); + if (tls13_derive_early_secrets(secrets, + secrets->zeros.data, secrets->zeros.len, &chello_hash)) + FAIL("derive_early_secrets worked when it shouldn't(2)\n"); + + if (!tls13_derive_handshake_secrets(secrets, ecdhe, 32, &cshello_hash)) + FAIL("derive_handshake_secrets failed\n"); + if (tls13_derive_handshake_secrets(secrets, ecdhe, 32, &cshello_hash)) + FAIL("derive_handshake_secrets worked when it shouldn't(2)\n"); + + /* XXX fix hash here once test vector sorted */ + if (!tls13_derive_application_secrets(secrets, &csfhello_hash)) + FAIL("derive_application_secrets failed\n"); + if (tls13_derive_application_secrets(secrets, &csfhello_hash)) + FAIL("derive_application_secrets worked when it " + "shouldn't(2)\n"); + + fprintf(stderr, "extracted_early:\n"); + compare_data(secrets->extracted_early.data, 32, + expected_extracted_early, 32); + if (memcmp(secrets->extracted_early.data, + expected_extracted_early, 32) != 0) + FAIL("extracted_early does not match\n"); + + fprintf(stderr, "derived_early:\n"); + compare_data(secrets->derived_early.data, 32, + expected_derived_early, 32); + if (memcmp(secrets->derived_early.data, + expected_derived_early, 32) != 0) + FAIL("derived_early does not match\n"); + + fprintf(stderr, "extracted_handshake:\n"); + compare_data(secrets->extracted_handshake.data, 32, + expected_extracted_handshake, 32); + if (memcmp(secrets->extracted_handshake.data, + expected_extracted_handshake, 32) != 0) + FAIL("extracted_handshake does not match\n"); + + fprintf(stderr, "client_handshake_traffic:\n"); + compare_data(secrets->client_handshake_traffic.data, 32, + expected_client_handshake_traffic, 32); + if (memcmp(secrets->client_handshake_traffic.data, + expected_client_handshake_traffic, 32) != 0) + FAIL("client_handshake_traffic does not match\n"); + + fprintf(stderr, "server_handshake_traffic:\n"); + compare_data(secrets->server_handshake_traffic.data, 32, + expected_server_handshake_traffic, 32); + if (memcmp(secrets->server_handshake_traffic.data, + expected_server_handshake_traffic, 32) != 0) + FAIL("server_handshake_traffic does not match\n"); + + fprintf(stderr, "derived_early:\n"); + compare_data(secrets->derived_early.data, 32, + expected_derived_early, 32); + if (memcmp(secrets->derived_early.data, + expected_derived_early, 32) != 0) + FAIL("derived_early does not match\n"); + + fprintf(stderr, "derived_handshake:\n"); + compare_data(secrets->derived_handshake.data, 32, + expected_derived_handshake, 32); + if (memcmp(secrets->derived_handshake.data, + expected_derived_handshake, 32) != 0) + FAIL("derived_handshake does not match\n"); + + fprintf(stderr, "extracted_master:\n"); + compare_data(secrets->extracted_master.data, 32, + expected_extracted_master, 32); + if (memcmp(secrets->extracted_master.data, + expected_extracted_master, 32) != 0) + FAIL("extracted_master does not match\n"); + + fprintf(stderr, "server_application_traffic:\n"); + compare_data(secrets->server_application_traffic.data, 32, + expected_server_application_traffic, 32); + if (memcmp(secrets->server_application_traffic.data, + expected_server_application_traffic, 32) != 0) + FAIL("server_application_traffic does not match\n"); + + fprintf(stderr, "client_application_traffic:\n"); + compare_data(secrets->client_application_traffic.data, 32, + expected_client_application_traffic, 32); + if (memcmp(secrets->client_application_traffic.data, + expected_client_application_traffic, 32) != 0) + FAIL("server_application_traffic does not match\n"); + + fprintf(stderr, "exporter_master:\n"); + compare_data(secrets->exporter_master.data, 32, + expected_exporter_master, 32); + if (memcmp(secrets->exporter_master.data, + expected_exporter_master, 32) != 0) + FAIL("exporter_master does not match\n"); + + tls13_update_server_traffic_secret(secrets); + fprintf(stderr, "server_application_traffic after update:\n"); + compare_data(secrets->server_application_traffic.data, 32, + expected_server_application_traffic_updated, 32); + if (memcmp(secrets->server_application_traffic.data, + expected_server_application_traffic_updated, 32) != 0) + FAIL("server_application_traffic does not match after update\n"); + + + tls13_update_client_traffic_secret(secrets); + fprintf(stderr, "client_application_traffic after update:\n"); + compare_data(secrets->client_application_traffic.data, 32, + expected_client_application_traffic_updated, 32); + if (memcmp(secrets->client_application_traffic.data, + expected_client_application_traffic_updated, 32) != 0) + FAIL("client_application_traffic does not match after update\n"); + + tls13_secrets_destroy(secrets); + + return failures; +} diff --git a/Libraries/libressl/tests/keypairtest.c b/Libraries/libressl/tests/keypairtest.c new file mode 100644 index 000000000..31bf7d6a5 --- /dev/null +++ b/Libraries/libressl/tests/keypairtest.c @@ -0,0 +1,211 @@ +/* $OpenBSD: keypairtest.c,v 1.6 2022/02/08 18:05:57 tb Exp $ */ +/* + * Copyright (c) 2018 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define PUBKEY_HASH \ + "SHA256:858d0f94beb0a08eb4f13871ba57bf0a2e081287d0efbaeb3bbac59dd8f1a8e5" + +char *cert_file, *key_file, *ocsp_staple_file; + +static void +load_file(const char *filename, const uint8_t **data, size_t *data_len) +{ + struct stat sb; + uint8_t *buf; + size_t len; + ssize_t n; + int fd; + + if ((fd = open(filename, O_RDONLY)) == -1) + err(1, "failed to open '%s'", filename); + if ((fstat(fd, &sb)) == -1) + err(1, "failed to stat '%s'", filename); + if (sb.st_size < 0) + err(1, "file size invalid for '%s'", filename); + len = (size_t)sb.st_size; + if ((buf = malloc(len)) == NULL) + err(1, "out of memory"); + n = read(fd, buf, len); + if (n < 0 || (size_t)n != len) + err(1, "failed to read '%s'", filename); + close(fd); + + *data = buf; + *data_len = len; +} + +static int +compare_mem(char *label, const uint8_t *data1, size_t data1_len, + const uint8_t *data2, size_t data2_len) +{ + if (data1_len != data2_len) { + fprintf(stderr, "FAIL: %s length mismatch (%zu != %zu)\n", + label, data1_len, data2_len); + return -1; + } + if (data1 == data2) { + fprintf(stderr, "FAIL: %s comparing same memory (%p == %p)\n", + label, data1, data2); + return -1; + } + if (memcmp(data1, data2, data1_len) != 0) { + fprintf(stderr, "FAIL: %s data mismatch\n", label); + return -1; + } + return 0; +} + +static int +do_keypair_tests(void) +{ + size_t cert_len, key_len, ocsp_staple_len; + const uint8_t *cert, *key, *ocsp_staple; + X509 *x509_cert = NULL; + struct tls_keypair *kp; + struct tls_error err; + int failed = 1; + + load_file(cert_file, &cert, &cert_len); + load_file(key_file, &key, &key_len); + load_file(ocsp_staple_file, &ocsp_staple, &ocsp_staple_len); + + if ((kp = tls_keypair_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create keypair\n"); + goto done; + } + + if (tls_keypair_set_cert_file(kp, &err, cert_file) == -1) { + fprintf(stderr, "FAIL: failed to load cert file: %s\n", + err.msg); + goto done; + } + if (tls_keypair_set_key_file(kp, &err, key_file) == -1) { + fprintf(stderr, "FAIL: failed to load key file: %s\n", err.msg); + goto done; + } + if (tls_keypair_set_ocsp_staple_file(kp, &err, ocsp_staple_file) == -1) { + fprintf(stderr, "FAIL: failed to load ocsp staple file: %s\n", + err.msg); + goto done; + } + + if (compare_mem("certificate", cert, cert_len, kp->cert_mem, + kp->cert_len) == -1) + goto done; + if (compare_mem("key", key, key_len, kp->key_mem, kp->cert_len) == -1) + goto done; + if (compare_mem("ocsp staple", ocsp_staple, ocsp_staple_len, + kp->ocsp_staple, kp->ocsp_staple_len) == -1) + goto done; + if (strcmp(kp->pubkey_hash, PUBKEY_HASH) != 0) { + fprintf(stderr, "FAIL: got pubkey hash '%s', want '%s'", + kp->pubkey_hash, PUBKEY_HASH); + goto done; + } + + tls_keypair_clear_key(kp); + + if (kp->key_mem != NULL || kp->key_len != 0) { + fprintf(stderr, "FAIL: key not cleared (mem %p, len %zu)", + kp->key_mem, kp->key_len); + goto done; + } + + if (tls_keypair_set_cert_mem(kp, &err, cert, cert_len) == -1) { + fprintf(stderr, "FAIL: failed to load cert: %s\n", err.msg); + goto done; + } + if (tls_keypair_set_key_mem(kp, &err, key, key_len) == -1) { + fprintf(stderr, "FAIL: failed to load key: %s\n", err.msg); + goto done; + } + if (tls_keypair_set_ocsp_staple_mem(kp, &err, ocsp_staple, + ocsp_staple_len) == -1) { + fprintf(stderr, "FAIL: failed to load ocsp staple: %s\n", err.msg); + goto done; + } + if (compare_mem("certificate", cert, cert_len, kp->cert_mem, + kp->cert_len) == -1) + goto done; + if (compare_mem("key", key, key_len, kp->key_mem, kp->cert_len) == -1) + goto done; + if (compare_mem("ocsp staple", ocsp_staple, ocsp_staple_len, + kp->ocsp_staple, kp->ocsp_staple_len) == -1) + goto done; + if (strcmp(kp->pubkey_hash, PUBKEY_HASH) != 0) { + fprintf(stderr, "FAIL: got pubkey hash '%s', want '%s'", + kp->pubkey_hash, PUBKEY_HASH); + goto done; + } + + if (tls_keypair_load_cert(kp, &err, &x509_cert) == -1) { + fprintf(stderr, "FAIL: failed to load X509 certificate: %s\n", + err.msg); + goto done; + } + + tls_keypair_clear_key(kp); + + if (kp->key_mem != NULL || kp->key_len != 0) { + fprintf(stderr, "FAIL: key not cleared (mem %p, len %zu)", + kp->key_mem, kp->key_len); + goto done; + } + + failed = 0; + + done: + tls_keypair_free(kp); + X509_free(x509_cert); + free((uint8_t *)cert); + free((uint8_t *)key); + free((uint8_t *)ocsp_staple); + + return (failed); +} + +int +main(int argc, char **argv) +{ + int failure = 0; + + if (argc != 4) { + fprintf(stderr, "usage: %s ocspstaplefile certfile keyfile\n", + argv[0]); + return (1); + } + + ocsp_staple_file = argv[1]; + cert_file = argv[2]; + key_file = argv[3]; + + failure |= do_keypair_tests(); + + return (failure); +} diff --git a/Libraries/libressl/tests/keypairtest.sh b/Libraries/libressl/tests/keypairtest.sh new file mode 100644 index 000000000..3c24869b4 --- /dev/null +++ b/Libraries/libressl/tests/keypairtest.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e +TEST=./keypairtest +if [ -e ./keypairtest.exe ]; then + TEST=./keypairtest.exe +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +$TEST $srcdir/ca.pem $srcdir/server.pem $srcdir/server.pem diff --git a/Libraries/libressl/tests/letsencrypt-r3.crt b/Libraries/libressl/tests/letsencrypt-r3.crt new file mode 100644 index 000000000..43b222a60 --- /dev/null +++ b/Libraries/libressl/tests/letsencrypt-r3.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw +WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP +R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx +sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm +NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg +Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG +/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB +Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA +FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw +Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB +gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W +PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl +ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz +CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm +lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 +avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 +yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O +yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids +hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ +HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv +MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX +nLRbwHOoq7hHwg== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/libressl.org.crt b/Libraries/libressl/tests/libressl.org.crt new file mode 100644 index 000000000..425954879 --- /dev/null +++ b/Libraries/libressl/tests/libressl.org.crt @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +MIIG3DCCBcSgAwIBAgISA7cdK3Ainj5sW/nVzBz0QTKzMA0GCSqGSIb3DQEBCwUA +MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD +EwJSMzAeFw0yMTExMTkxNjQ5MTdaFw0yMjAyMTcxNjQ5MTZaMBoxGDAWBgNVBAMT +D3d3dy5vcGVuYnNkLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AONf/xu/gf0QoQT8nqjEpfUQaaygDkhPBw5mswqAU0fOMg9ZaZT7Nx8g9qAH0mgi +6GNd/y7I2fMM7vvkFk/NQn8pu51EMLJ7aNKv6o4ThJYzyvPikdZW+RcdIdt185wJ +ws7MNq2kaZ0gJRXsIE8haE0iDB9nPRtJ8HAbhxOeCRczrALjvJBI6blg/9TBI+sd +zvA8yEOelGRox6AikFSP6JDmSmzoBgVSTXq9riKKQeK1j+Wa6vBYmsN2LFmbWPYN +1TbJk1C37E7Q3CTCkHt+CZNcAqBFIovClb9jmR+0QU3NQnTSqeXnyKyOe2RtYHOx +3oRs9A8bsRPybvh6zYf33Od2QbFwCGOS1H9sRux1LJEeZlCFDuccRpU3X9f7IO1X +n5cYr9eIUFIniTAfiksGvL7do2nYNmX/ujdraX7ttPmJZMVVDBjct9g4KGC7aMvB +CSc695JcLA7RJuJ8qKXcKxINavIpSHsFPobLDPwl43xxihCMQpMfb8Eg3fi5CQcu +FjdljawMkFeAiVv4iI1rbpWhpZeOGQTKxxjagWd9UNJW9PQxqh+x63I2zO47+W6r +jSbk2SicUrYTK7F1W+4HRPbA4e5U+hFk881nngnG0mB0D3sinqzxWIyM5DWTDuVp +ePBJQq3odt2/ityGRY0FcO35mlYkuB26/7Dfq/KmI4olAgMBAAGjggMCMIIC/jAO +BgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwG +A1UdEwEB/wQCMAAwHQYDVR0OBBYEFIQBXV9xwD2xyW1oHNhKs8qxdQFtMB8GA1Ud +IwQYMBaAFBQusxe3WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggr +BgEFBQcwAYYVaHR0cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRw +Oi8vcjMuaS5sZW5jci5vcmcvMIHRBgNVHREEgckwgcaCD2Z0cC5vcGVuYnNkLm9y +Z4IMbGlicmVzc2wub3JnggtvcGVuYnNkLm9yZ4IMb3BlbmlrZWQub3JnggtvcGVu +c3NoLmNvbYIPcnBraS1jbGllbnQub3JnghB3d3cubGlicmVzc2wub3Jngg93d3cu +b3BlbmJzZC5vcmeCEHd3dy5vcGVuaWtlZC5vcmeCEXd3dy5vcGVucnN5bmMub3Jn +gg93d3cub3BlbnNzaC5jb22CE3d3dy5ycGtpLWNsaWVudC5vcmcwTAYDVR0gBEUw +QzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDov +L2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdwAp +eb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZcJV3HhAAAAX05UR9vAAAEAwBIMEYC +IQCT7TplmJqF8Ds8JvdSlNeSSMLAZMsB9ez3bUHgvShWrQIhAMJPkvugu+9VZ4AG +EAfnubGWp6mLssvTnE4C6NskZR7IAHUAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQAp +Bo2yCJo32RMAAAF9OVEgOwAABAMARjBEAiAmyRIocC0VBaei6hIa/zk2X5PfgzZf +7Qc4uApA4Y25+gIgYa4rhr2OhmUr+2Ph2nez88UqMrgjHn76fYOlSQDEV7gwDQYJ +KoZIhvcNAQELBQADggEBADMSIRTpbJOdHjy/ju4TPXmc9H7mhyXwXH382FKnkC+T +VaqPsJL7Mve7Lgr96tzRGVU8hLF3oRXpZVv6qSNmV3ULyCDVG8JoYDZbJV/v7ziU +RITnWsraI8BYtxgDx6YU8ISbWU0Kh8REdi+mQ49FWmmPaJO9XyvkvG2BD2e+t1Zh +8O78YFFhtQLuwTtOYa4WKOzWVXD8t2vZBGecJ+APnhcPGS6NQ9qqpKdDwmm0qYG7 +gafHxcWd2k2phmqbp7R3qqY/VP21VyUXCXoGAp+IaqJRunyEmTBAUyB6LkFBfQpc +y0LH4LFzj5ouo5HtlZQRR5z3MN9WmwAej1gNpC/j688= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/md_test.c b/Libraries/libressl/tests/md_test.c new file mode 100644 index 000000000..f2b4eca33 --- /dev/null +++ b/Libraries/libressl/tests/md_test.c @@ -0,0 +1,301 @@ +/* $OpenBSD: md_test.c,v 1.1.1.1 2022/09/02 13:34:48 tb Exp $ */ +/* + * Copyright (c) 2022 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +struct md_test { + const int algorithm; + const uint8_t in[128]; + const size_t in_len; + const uint8_t out[EVP_MAX_MD_SIZE]; +}; + +static const struct md_test md_tests[] = { + /* MD4 (RFC 1320 test vectors) */ + { + .algorithm = NID_md4, + .in = "", + .in_len = 0, + .out = { + 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0, + } + }, + { + .algorithm = NID_md4, + .in = "a", + .in_len = 1, + .out = { + 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24, + } + }, + { + .algorithm = NID_md4, + .in = "abc", + .in_len = 3, + .out = { + 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d, + } + }, + { + .algorithm = NID_md4, + .in = "message digest", + .in_len = 14, + .out = { + 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b, + } + }, + { + .algorithm = NID_md4, + .in = "abcdefghijklmnopqrstuvwxyz", + .in_len = 26, + .out = { + 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9, + } + }, + { + .algorithm = NID_md4, + .in = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" + "wxyz0123456789", + .in_len = 62, + .out = { + 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4, + } + }, + { + .algorithm = NID_md4, + .in = + "123456789012345678901234567890123456789012345678" + "90123456789012345678901234567890", + .in_len = 80, + .out = { + 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36, + } + }, + + /* MD5 (RFC 1321 test vectors) */ + { + .algorithm = NID_md5, + .in = "", + .in_len = 0, + .out = { + 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, + } + }, + { + .algorithm = NID_md5, + .in = "a", + .in_len = 1, + .out = { + 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61, + } + }, + { + .algorithm = NID_md5, + .in = "abc", + .in_len = 3, + .out = { + 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72, + } + }, + { + .algorithm = NID_md5, + .in = "message digest", + .in_len = 14, + .out = { + 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0, + } + }, + { + .algorithm = NID_md5, + .in = "abcdefghijklmnopqrstuvwxyz", + .in_len = 26, + .out = { + 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b, + } + }, + { + .algorithm = NID_md5, + .in = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" + "wxyz0123456789", + .in_len = 62, + .out = { + 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f, + } + }, + { + .algorithm = NID_md5, + .in = + "123456789012345678901234567890123456789012345678" + "90123456789012345678901234567890", + .in_len = 80, + .out = { + 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a, + } + }, +}; + +#define N_MD_TESTS (sizeof(md_tests) / sizeof(md_tests[0])) + +typedef unsigned char *(*md_hash_func)(const unsigned char *, size_t, + unsigned char *); + +static int +md_hash_from_algorithm(int algorithm, const char **out_label, + md_hash_func *out_func, const EVP_MD **out_md, size_t *out_len) +{ + switch (algorithm) { + case NID_md4: + *out_label = SN_md4; + *out_func = MD4; + *out_md = EVP_md4(); + *out_len = MD4_DIGEST_LENGTH; + break; + case NID_md5: + *out_label = SN_md5; + *out_func = MD5; + *out_md = EVP_md5(); + *out_len = MD5_DIGEST_LENGTH; + break; + default: + fprintf(stderr, "FAIL: unknown algorithm (%d)\n", + algorithm); + return 0; + } + + return 1; +} + +static int +md_test(void) +{ + unsigned char *(*md_func)(const unsigned char *, size_t, unsigned char *); + const struct md_test *st; + EVP_MD_CTX *hash = NULL; + const EVP_MD *md; + uint8_t out[EVP_MAX_MD_SIZE]; + size_t in_len, out_len; + size_t i; + const char *label; + int failed = 1; + + if ((hash = EVP_MD_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n"); + goto failed; + } + + for (i = 0; i < N_MD_TESTS; i++) { + st = &md_tests[i]; + if (!md_hash_from_algorithm(st->algorithm, &label, &md_func, + &md, &out_len)) + goto failed; + + /* Digest */ + memset(out, 0, sizeof(out)); + md_func(st->in, st->in_len, out); + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, "FAIL (%s): mismatch\n", label); + goto failed; + } + + /* EVP single-shot digest */ + memset(out, 0, sizeof(out)); + if (!EVP_Digest(st->in, st->in_len, out, NULL, md, NULL)) { + fprintf(stderr, "FAIL (%s): EVP_Digest failed\n", + label); + goto failed; + } + + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, "FAIL (%s): EVP single-shot mismatch\n", + label); + goto failed; + } + + /* EVP digest */ + memset(out, 0, sizeof(out)); + if (!EVP_DigestInit_ex(hash, md, NULL)) { + fprintf(stderr, "FAIL (%s): EVP_DigestInit_ex failed\n", + label); + goto failed; + } + + in_len = st->in_len / 2; + if (!EVP_DigestUpdate(hash, st->in, in_len)) { + fprintf(stderr, + "FAIL (%s): EVP_DigestUpdate first half failed\n", + label); + goto failed; + } + + if (!EVP_DigestUpdate(hash, st->in + in_len, + st->in_len - in_len)) { + fprintf(stderr, + "FAIL (%s): EVP_DigestUpdate second half failed\n", + label); + goto failed; + } + + if (!EVP_DigestFinal_ex(hash, out, NULL)) { + fprintf(stderr, + "FAIL (%s): EVP_DigestFinal_ex failed\n", + label); + goto failed; + } + + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, "FAIL (%s): EVP mismatch\n", label); + goto failed; + } + } + + failed = 0; + + failed: + EVP_MD_CTX_free(hash); + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= md_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/objectstest.c b/Libraries/libressl/tests/objectstest.c new file mode 100644 index 000000000..5be26d48e --- /dev/null +++ b/Libraries/libressl/tests/objectstest.c @@ -0,0 +1,588 @@ +/* $OpenBSD: objectstest.c,v 1.8 2023/05/23 11:06:52 tb Exp $ */ +/* + * Copyright (c) 2017, 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +obj_compare_bytes(const char *label, const unsigned char *d1, int len1, + const unsigned char *d2, int len2) +{ + if (len1 != len2) { + fprintf(stderr, "FAIL: %s - byte lengths differ " + "(%d != %d)\n", label, len1, len2); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + if (memcmp(d1, d2, len1) != 0) { + fprintf(stderr, "FAIL: %s - bytes differ\n", label); + fprintf(stderr, "Got:\n"); + hexdump(d1, len1); + fprintf(stderr, "Want:\n"); + hexdump(d2, len2); + return 0; + } + return 1; +} + +struct obj_test { + const char *oid; + const char *sn; + const char *ln; + int nid; + uint8_t data[255]; + size_t data_len; +}; + +struct obj_test obj_tests[] = { + { + .oid = NULL, + .sn = "UNDEF", + .ln = "undefined", + .nid = NID_undef, + }, + { + .oid = "2.5.4.10", + .sn = "O", + .ln = "organizationName", + .nid = NID_organizationName, + .data = { + 0x55, 0x04, 0x0a, + }, + .data_len = 3, + }, + { + .oid = "2.5.4.8", + .sn = "ST", + .ln = "stateOrProvinceName", + .nid = NID_stateOrProvinceName, + .data = { + 0x55, 0x04, 0x08, + }, + .data_len = 3, + }, + { + .oid = "2.23.43.1", + .sn = "wap-wsg", + .nid = NID_wap_wsg, + .data = { + 0x67, 0x2b, 0x01, + }, + .data_len = 3, + }, + { + .oid = "1.3.6.1.4.1.11129.2.4.5", + .sn = "ct_cert_scts", + .ln = "CT Certificate SCTs", + .nid = NID_ct_cert_scts, + .data = { + 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, + 0x04, 0x05, + }, + .data_len = 10, + }, + { + .oid = "1.3.6.1.4.1", + .sn = "enterprises", + .ln = "Enterprises", + .nid = NID_Enterprises, + .data = { + 0x2b, 0x06, 0x01, 0x04, 0x01, + }, + .data_len = 5, + }, + { + .oid = "1.3.6.1.4.1.5454.1.70.6.11.2", + .nid = NID_undef, + .data = { + 0x2b, 0x06, 0x01, 0x04, 0x01, 0xaa, 0x4e, 0x01, + 0x46, 0x06, 0x0b, 0x02, + }, + .data_len = 12, + }, + { + .oid = "1.3.6.1.4.1.890.1.5.8.60.102.2", + .nid = NID_undef, + .data = { + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x86, 0x7a, 0x01, + 0x05, 0x08, 0x3c, 0x66, 0x02, + }, + .data_len = 13, + }, + { + .oid = "1.3.6.1.4.1.173.7.3.4.1.1.26", + .nid = NID_undef, + .data = { + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x2d, 0x07, + 0x03, 0x04, 0x01, 0x01, 0x1a, + }, + .data_len = 13, + }, +}; + +#define N_OBJ_TESTS (sizeof(obj_tests) / sizeof(*obj_tests)) + +static int +obj_name_test(struct obj_test *ot) +{ + const char *ln, *sn; + int nid; + int failed = 1; + + if (ot->ln != NULL) { + if ((nid = OBJ_ln2nid(ot->ln)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_ln2nid() for '%s' = %d, " + "want %d\n", ot->ln, nid, ot->nid); + goto failed; + } + if ((ln = OBJ_nid2ln(ot->nid)) == NULL) { + fprintf(stderr, "FAIL: OBJ_nid2ln() for '%s' returned " + "NULL\n", ot->oid); + goto failed; + } + if (strcmp(ln, ot->ln) != 0) { + fprintf(stderr, "FAIL: OBJ_nid2ln() for '%s' = '%s', " + "want '%s'\n", ot->oid, ln, ot->ln); + goto failed; + } + } + if (ot->sn != NULL) { + if ((nid = OBJ_sn2nid(ot->sn)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_sn2nid() for '%s' = %d, " + "want %d\n", ot->sn, nid, ot->nid); + goto failed; + } + if ((sn = OBJ_nid2sn(ot->nid)) == NULL) { + fprintf(stderr, "FAIL: OBJ_nid2sn() for '%s' returned " + "NULL\n", ot->oid); + goto failed; + } + if (strcmp(sn, ot->sn) != 0) { + fprintf(stderr, "FAIL: OBJ_nid2sn() for '%s' = '%s', " + "want '%s'\n", ot->oid, sn, ot->sn); + goto failed; + } + } + + failed = 0; + + failed: + return failed; +} + +static int +obj_name_tests(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_OBJ_TESTS; i++) + failed |= obj_name_test(&obj_tests[i]); + + return failed; +} + +static int +obj_nid_test(struct obj_test *ot) +{ + ASN1_OBJECT *obj = NULL; + int nid; + int failed = 1; + + if (ot->nid == NID_undef && ot->oid != NULL) + return 0; + + if ((obj = OBJ_nid2obj(ot->nid)) == NULL) { + fprintf(stderr, "FAIL: OBJ_nid2obj() failed for '%s' (NID %d)\n", + ot->oid, ot->nid); + goto failed; + } + if ((nid = OBJ_obj2nid(obj)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_obj2nid() failed for '%s' - got %d, " + "want %d\n", ot->oid ? ot->oid : "undef", nid, ot->nid); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(obj); + + return failed; +} + +static int +obj_nid_tests(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_OBJ_TESTS; i++) + failed |= obj_nid_test(&obj_tests[i]); + + return failed; +} + +static int +obj_oid_test(struct obj_test *ot) +{ + ASN1_OBJECT *obj = NULL; + char buf[1024]; + int len, nid; + int failed = 1; + + if (ot->oid == NULL) + return 0; + + if ((obj = OBJ_txt2obj(ot->oid, 0)) == NULL) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n", ot->oid); + goto failed; + } + if ((nid = OBJ_txt2nid(ot->oid)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_txt2nid() failed for '%s', got %d " + "want %d\n", ot->oid, nid, ot->nid); + goto failed; + } + + if (!obj_compare_bytes("object data", OBJ_get0_data(obj), OBJ_length(obj), + ot->data, ot->data_len)) + goto failed; + + len = OBJ_obj2txt(buf, sizeof(buf), obj, 1); + if (len <= 0 || (size_t)len >= sizeof(buf)) { + fprintf(stderr, "FAIL: OBJ_obj2txt() failed for '%s'\n", ot->oid); + goto failed; + } + if (strcmp(buf, ot->oid) != 0) { + fprintf(stderr, "FAIL: OBJ_obj2txt() returned '%s', want '%s'\n", + buf, ot->oid); + goto failed; + } + + if ((OBJ_obj2txt(NULL, 0, obj, 1) != len)) { + fprintf(stderr, "FAIL: OBJ_obj2txt() with NULL buffer != %d\n", + len); + goto failed; + } + if ((OBJ_obj2txt(buf, 3, obj, 1) != len)) { + fprintf(stderr, "FAIL: OBJ_obj2txt() with short buffer != %d\n", + len); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(obj); + + return failed; +} + +static int +obj_oid_tests(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_OBJ_TESTS; i++) + failed |= obj_oid_test(&obj_tests[i]); + + return failed; +} + +static int +obj_txt_test(struct obj_test *ot) +{ + ASN1_OBJECT *obj = NULL; + const char *want; + char buf[1024]; + int len, nid; + int failed = 1; + + if (ot->oid == NULL) + return 0; + + if (ot->sn != NULL) { + if ((obj = OBJ_txt2obj(ot->sn, 0)) == NULL) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n", + ot->sn); + goto failed; + } + if ((nid = OBJ_obj2nid(obj)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s', " + "got nid %d want %d\n", ot->sn, nid, ot->nid); + goto failed; + } + ASN1_OBJECT_free(obj); + obj = NULL; + } + if (ot->ln != NULL) { + if ((obj = OBJ_txt2obj(ot->ln, 0)) == NULL) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n", + ot->ln); + goto failed; + } + if ((nid = OBJ_obj2nid(obj)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s', " + "got nid %d want %d\n", ot->ln, nid, ot->nid); + goto failed; + } + ASN1_OBJECT_free(obj); + obj = NULL; + } + + if ((obj = OBJ_txt2obj(ot->oid, 0)) == NULL) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n", ot->oid); + goto failed; + } + if ((nid = OBJ_obj2nid(obj)) != ot->nid) { + fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s', " + "got nid %d want %d\n", ot->oid, nid, ot->nid); + goto failed; + } + + len = OBJ_obj2txt(buf, sizeof(buf), obj, 0); + if (len <= 0 || (size_t)len >= sizeof(buf)) { + fprintf(stderr, "FAIL: OBJ_obj2txt() failed for '%s'\n", ot->oid); + goto failed; + } + want = ot->ln; + if (want == NULL) + want = ot->sn; + if (want == NULL) + want = ot->oid; + if (strcmp(buf, want) != 0) { + fprintf(stderr, "FAIL: OBJ_obj2txt() returned '%s', want '%s'\n", + buf, want); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(obj); + + return failed; +} + +static int +obj_txt_early_nul_test(void) +{ + ASN1_OBJECT *obj = NULL; + char buf[2]; + int failed = 1; + + buf[0] = 'x'; + buf[1] = '\0'; + + if (OBJ_obj2txt(buf, sizeof(buf), NULL, 1) != 0) { + fprintf(stderr, "FAIL: OBJ_obj2txt(NULL) succeded\n"); + goto failed; + } + if (buf[0] != '\0') { + fprintf(stderr, "FAIL: OBJ_obj2txt(NULL) did not NUL terminate\n"); + goto failed; + } + + if ((obj = ASN1_OBJECT_new()) == NULL) + errx(1, "ASN1_OBJECT_new"); + + buf[0] = 'x'; + buf[1] = '\0'; + + if (OBJ_obj2txt(buf, sizeof(buf), obj, 1) != 0) { + fprintf(stderr, "FAIL: OBJ_obj2txt(obj) succeeded\n"); + goto failed; + } + if (buf[0] != '\0') { + fprintf(stderr, "FAIL: OBJ_obj2txt(obj) did not NUL terminate\n"); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(obj); + + return failed; +} + +static int +obj_txt_tests(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_OBJ_TESTS; i++) + failed |= obj_txt_test(&obj_tests[i]); + + failed |= obj_txt_early_nul_test(); + + return failed; +} + +/* OID 1.3.18446744073709551615 (64 bits). */ +const uint8_t asn1_large_oid1[] = { + 0x06, 0x0b, + 0x2b, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, +}; + +/* OID 1.3.18446744073709551616 (65 bits). */ +const uint8_t asn1_large_oid2[] = { + 0x06, 0x0b, + 0x2b, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x00, +}; + +/* OID 1.3.340282366920938463463374607431768211455 (128 bits). */ +const uint8_t asn1_large_oid3[] = { + 0x06, 0x14, + 0x2b, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, +}; + +/* OID 1.3.115792089237316195423570985008687907853269984665640564039457584007913129639935 (256 bits). */ +const uint8_t asn1_large_oid4[] = { + 0x06, 0x26, + 0x2b, 0x8f, 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, 0xff, 0xff, 0xff, 0x7f, +}; + +struct oid_large_test { + const char *oid; + const uint8_t *asn1_der; + size_t asn1_der_len; + int obj2txt; +}; + +struct oid_large_test oid_large_tests[] = { + { + .oid = "1.3.18446744073709551615", + .asn1_der = asn1_large_oid1, + .asn1_der_len = sizeof(asn1_large_oid1), + .obj2txt = 1, + }, + { + .oid = "1.3.18446744073709551616", + .asn1_der = asn1_large_oid2, + .asn1_der_len = sizeof(asn1_large_oid2), + .obj2txt = 0, + }, + { + .oid = "1.3.340282366920938463463374607431768211455", + .asn1_der = asn1_large_oid3, + .asn1_der_len = sizeof(asn1_large_oid3), + .obj2txt = 0, + }, + { + .oid = "1.3.115792089237316195423570985008687907853269984665640" + "564039457584007913129639935", + .asn1_der = asn1_large_oid4, + .asn1_der_len = sizeof(asn1_large_oid4), + .obj2txt = 0, + }, +}; + +#define N_OID_LARGE_TESTS (sizeof(oid_large_tests) / sizeof(*oid_large_tests)) + +static int +obj_oid_large_test(size_t test_no, struct oid_large_test *olt) +{ + ASN1_OBJECT *obj = NULL; + const uint8_t *p; + char buf[1024]; + int len; + int failed = 1; + + p = olt->asn1_der; + if ((obj = d2i_ASN1_OBJECT(NULL, &p, olt->asn1_der_len)) == NULL) { + fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed for large " + "oid %zu\n", test_no); + goto failed; + } + len = OBJ_obj2txt(buf, sizeof(buf), obj, 1); + if (len < 0 || (size_t)len >= sizeof(buf)) { + fprintf(stderr, "FAIL: OBJ_obj2txt() failed for large " + "oid %zu\n", test_no); + goto failed; + } + if ((len != 0) != olt->obj2txt) { + fprintf(stderr, "FAIL: OBJ_obj2txt() failed for large " + "oid %zu\n", test_no); + goto failed; + } + if (len != 0 && strcmp(buf, olt->oid) != 0) { + fprintf(stderr, "FAIL: OBJ_obj2txt() returned '%s', want '%s'\n", + buf, olt->oid); + goto failed; + } + + failed = 0; + + failed: + ASN1_OBJECT_free(obj); + + return failed; +} + +static int +obj_oid_large_tests(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_OID_LARGE_TESTS; i++) + failed |= obj_oid_large_test(i, &oid_large_tests[i]); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= obj_name_tests(); + failed |= obj_nid_tests(); + failed |= obj_oid_tests(); + failed |= obj_txt_tests(); + failed |= obj_oid_large_tests(); + + return (failed); +} diff --git a/Libraries/libressl/tests/ocsp_test.c b/Libraries/libressl/tests/ocsp_test.c new file mode 100644 index 000000000..a38d28135 --- /dev/null +++ b/Libraries/libressl/tests/ocsp_test.c @@ -0,0 +1,159 @@ +/* $OpenBSD: ocsp_test.c,v 1.7 2023/07/07 19:54:36 bcook Exp $ */ +/* + * Copyright (c) 2016 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static int +tcp_connect(char *host, char *port) +{ + int error, sd = -1; + struct addrinfo hints, *res, *r; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + if (BIO_sock_init() != 1) { + perror("BIO_sock_init()"); + exit(-1); + } + + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + perror("getaddrinfo()"); + exit(-1); + } + + for (r = res; r != NULL; r = r->ai_next) { + sd = socket(r->ai_family, r->ai_socktype, r->ai_protocol); + if (sd == -1) + continue; + + if (connect(sd, r->ai_addr, r->ai_addrlen) == 0) + break; + + close(sd); + } + + freeaddrinfo(res); + + return sd; +} + +int +main(int argc, char *argv[]) +{ + int sd, ocsp_status; + const unsigned char *p; + long len; + OCSP_RESPONSE *rsp = NULL; + OCSP_BASICRESP *br = NULL; + X509_STORE *st = NULL; + STACK_OF(X509) *ch = NULL; + char *host, *port; +#ifdef _PATH_SSL_CA_FILE + char *cafile = _PATH_SSL_CA_FILE; +#else + char *cafile = "/etc/ssl/cert.pem"; +#endif + + SSL *ssl; + SSL_CTX *ctx; + + SSL_library_init(); + SSL_load_error_strings(); + + ctx = SSL_CTX_new(SSLv23_client_method()); + + if (!SSL_CTX_load_verify_locations(ctx, cafile, NULL)) { + printf("failed to load %s\n", cafile); + exit(-1); + } + + if (argc != 3) + errx(-1, "need a host and port to connect to"); + else { + host = argv[1]; + port = argv[2]; + } + + sd = tcp_connect(host, port); + + ssl = SSL_new(ctx); + + SSL_set_fd(ssl, (int) sd); + SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp); + + if (SSL_connect(ssl) <= 0) { + printf("SSL connect error\n"); + exit(-1); + } + + if (SSL_get_verify_result(ssl) != X509_V_OK) { + printf("Certificate doesn't verify from host %s port %s\n", host, port); + exit(-1); + } + + /* ==== VERIFY OCSP RESPONSE ==== */ + + + len = SSL_get_tlsext_status_ocsp_resp(ssl, &p); + + if (!p) { + printf("No OCSP response received for %s port %s\n", host, port); + exit(-1); + } + + rsp = d2i_OCSP_RESPONSE(NULL, &p, len); + if (!rsp) { + puts("Invalid OCSP response"); + exit(-1); + } + + ocsp_status = OCSP_response_status(rsp); + if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + printf("Invalid OCSP response status: %s (%d)", + OCSP_response_status_str(ocsp_status), ocsp_status); + exit(-1); + } + + br = OCSP_response_get1_basic(rsp); + if (!br) { + puts("Invalid OCSP response"); + exit(-1); + } + + ch = SSL_get_peer_cert_chain(ssl); + st = SSL_CTX_get_cert_store(ctx); + + if (OCSP_basic_verify(br, ch, st, 0) <= 0) { + puts("OCSP response verification failed"); + exit(-1); + } + + printf("OCSP validated from %s %s\n", host, port); + + return 0; +} diff --git a/Libraries/libressl/tests/ocsptest.bat b/Libraries/libressl/tests/ocsptest.bat new file mode 100644 index 000000000..058aeaf9d --- /dev/null +++ b/Libraries/libressl/tests/ocsptest.bat @@ -0,0 +1,12 @@ +@echo off +setlocal enabledelayedexpansion +REM ocspocsp_test_bin.bat + +set ocsp_test_bin=%1 +set ocsp_test_bin=%ocsp_test_bin:/=\% +if not exist %ocsp_test_bin% exit /b 1 + +%ocsp_test_bin% www.amazon.com 443 & if !errorlevel! neq 0 exit /b 1 +%ocsp_test_bin% cloudflare.com 443 & if !errorlevel! neq 0 exit /b 1 + +endlocal diff --git a/Libraries/libressl/tests/ocsptest.sh b/Libraries/libressl/tests/ocsptest.sh new file mode 100644 index 000000000..a1c266de8 --- /dev/null +++ b/Libraries/libressl/tests/ocsptest.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e +TEST=./ocsp_test +if [ -e ./ocsp_test.exe ]; then + TEST=./ocsp_test.exe +fi +$TEST www.amazon.com 443 +$TEST cloudflare.com 443 diff --git a/Libraries/libressl/tests/openssl.cnf b/Libraries/libressl/tests/openssl.cnf new file mode 100644 index 000000000..8e1eeb7f1 --- /dev/null +++ b/Libraries/libressl/tests/openssl.cnf @@ -0,0 +1,29 @@ +# $OpenBSD: openssl.cnf,v 1.1 2014/08/26 17:50:07 jsing Exp $ + +# +# SSLeay example configuration file. +# This is mostly being used for generation of certificate requests. +# +# hacked by iang to do DSA certs - Server + +RANDFILE = ./.rnd + +#################################################################### +[ req ] +distinguished_name = req_distinguished_name +encrypt_rsa_key = no + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = CA +countryName_value = CA + +organizationName = Organization Name (eg, company) +organizationName_value = Shake it Vera + +0.commonName = Common Name (eg, YOUR name) +0.commonName_value = Wastelandus + +1.commonName = Common Name (eg, YOUR name) +1.commonName_value = Maximus + diff --git a/Libraries/libressl/tests/optionstest.c b/Libraries/libressl/tests/optionstest.c new file mode 100644 index 000000000..af9dc1ef7 --- /dev/null +++ b/Libraries/libressl/tests/optionstest.c @@ -0,0 +1,381 @@ +/* $OpenBSD: optionstest.c,v 1.8 2015/01/22 05:48:00 doug Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#include +#include + +/* Needed to keep apps.c happy... */ +BIO *bio_err; +CONF *config; + +static int argfunc(char *arg); +static int defaultarg(int argc, char **argv, int *argsused); +static int multiarg(int argc, char **argv, int *argsused); + +static struct { + char *arg; + int flag; +} test_config; + +static struct option test_options[] = { + { + .name = "arg", + .argname = "argname", + .type = OPTION_ARG, + .opt.arg = &test_config.arg, + }, + { + .name = "argfunc", + .argname = "argname", + .type = OPTION_ARG_FUNC, + .opt.argfunc = argfunc, + }, + { + .name = "flag", + .type = OPTION_FLAG, + .opt.flag = &test_config.flag, + }, + { + .name = "multiarg", + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = multiarg, + }, + { + .name = NULL, + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = defaultarg, + }, + { NULL }, +}; + +char *args1[] = { "opts" }; +char *args2[] = { "opts", "-arg", "arg", "-flag" }; +char *args3[] = { "opts", "-arg", "arg", "-flag", "unnamed" }; +char *args4[] = { "opts", "-arg", "arg", "unnamed", "-flag" }; +char *args5[] = { "opts", "unnamed1", "-arg", "arg", "-flag", "unnamed2" }; +char *args6[] = { "opts", "-argfunc", "arg", "-flag" }; +char *args7[] = { "opts", "-arg", "arg", "-flag", "-", "-unnamed" }; +char *args8[] = { "opts", "-arg", "arg", "-flag", "file1", "file2", "file3" }; +char *args9[] = { "opts", "-arg", "arg", "-flag", "file1", "-file2", "file3" }; +char *args10[] = { "opts", "-arg", "arg", "-flag", "-", "file1", "file2" }; +char *args11[] = { "opts", "-arg", "arg", "-flag", "-", "-file1", "-file2" }; +char *args12[] = { "opts", "-multiarg", "arg1", "arg2", "-flag", "unnamed" }; +char *args13[] = { "opts", "-multiargz", "arg1", "arg2", "-flagz", "unnamed" }; + +struct options_test { + int argc; + char **argv; + enum { + OPTIONS_TEST_NONE, + OPTIONS_TEST_UNNAMED, + OPTIONS_TEST_ARGSUSED, + } type; + char *unnamed; + int used; + int want; + char *wantarg; + int wantflag; +}; + +struct options_test options_tests[] = { + { + /* Test 1 - No arguments (only program name). */ + .argc = 1, + .argv = args1, + .type = OPTIONS_TEST_NONE, + .want = 0, + .wantarg = NULL, + .wantflag = 0, + }, + { + /* Test 2 - Named arguments (unnamed not permitted). */ + .argc = 4, + .argv = args2, + .type = OPTIONS_TEST_NONE, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 3 - Named arguments (unnamed permitted). */ + .argc = 4, + .argv = args2, + .type = OPTIONS_TEST_UNNAMED, + .unnamed = NULL, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 4 - Named and single unnamed (unnamed not permitted). */ + .argc = 5, + .argv = args3, + .type = OPTIONS_TEST_NONE, + .want = 1, + }, + { + /* Test 5 - Named and single unnamed (unnamed permitted). */ + .argc = 5, + .argv = args3, + .type = OPTIONS_TEST_UNNAMED, + .unnamed = "unnamed", + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 6 - Named and single unnamed (different sequence). */ + .argc = 5, + .argv = args4, + .type = OPTIONS_TEST_UNNAMED, + .unnamed = "unnamed", + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 7 - Multiple unnamed arguments (should fail). */ + .argc = 6, + .argv = args5, + .type = OPTIONS_TEST_UNNAMED, + .want = 1, + }, + { + /* Test 8 - Function. */ + .argc = 4, + .argv = args6, + .type = OPTIONS_TEST_NONE, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 9 - Named and single unnamed (hyphen separated). */ + .argc = 6, + .argv = args7, + .type = OPTIONS_TEST_UNNAMED, + .unnamed = "-unnamed", + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 10 - Named and multiple unnamed. */ + .argc = 7, + .argv = args8, + .used = 4, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 11 - Named and multiple unnamed. */ + .argc = 7, + .argv = args9, + .used = 4, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 12 - Named and multiple unnamed. */ + .argc = 7, + .argv = args10, + .used = 5, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 13 - Named and multiple unnamed. */ + .argc = 7, + .argv = args11, + .used = 5, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 14 - Named only. */ + .argc = 4, + .argv = args2, + .used = 4, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = "arg", + .wantflag = 1, + }, + { + /* Test 15 - Multiple argument callback. */ + .argc = 6, + .argv = args12, + .unnamed = "unnamed", + .type = OPTIONS_TEST_UNNAMED, + .want = 0, + .wantarg = NULL, + .wantflag = 1, + }, + { + /* Test 16 - Multiple argument callback. */ + .argc = 6, + .argv = args12, + .used = 5, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = NULL, + .wantflag = 1, + }, + { + /* Test 17 - Default callback. */ + .argc = 6, + .argv = args13, + .unnamed = "unnamed", + .type = OPTIONS_TEST_UNNAMED, + .want = 0, + .wantarg = NULL, + .wantflag = 1, + }, + { + /* Test 18 - Default callback. */ + .argc = 6, + .argv = args13, + .used = 5, + .type = OPTIONS_TEST_ARGSUSED, + .want = 0, + .wantarg = NULL, + .wantflag = 1, + }, +}; + +#define N_OPTIONS_TESTS \ + (sizeof(options_tests) / sizeof(*options_tests)) + +static int +argfunc(char *arg) +{ + test_config.arg = arg; + return (0); +} + +static int +defaultarg(int argc, char **argv, int *argsused) +{ + if (argc < 1) + return (1); + + if (strcmp(argv[0], "-multiargz") == 0) { + if (argc < 3) + return (1); + *argsused = 3; + return (0); + } else if (strcmp(argv[0], "-flagz") == 0) { + test_config.flag = 1; + *argsused = 1; + return (0); + } + + return (1); +} + +static int +multiarg(int argc, char **argv, int *argsused) +{ + if (argc < 3) + return (1); + + *argsused = 3; + return (0); +} + +static int +do_options_test(int test_no, struct options_test *ot) +{ + int *argsused = NULL; + char *unnamed = NULL; + char **arg = NULL; + int used = 0; + int ret; + + if (ot->type == OPTIONS_TEST_UNNAMED) + arg = &unnamed; + else if (ot->type == OPTIONS_TEST_ARGSUSED) + argsused = &used; + + memset(&test_config, 0, sizeof(test_config)); + ret = options_parse(ot->argc, ot->argv, test_options, arg, argsused); + if (ret != ot->want) { + fprintf(stderr, "FAIL: test %i options_parse() returned %i, " + "want %i\n", test_no, ret, ot->want); + return (1); + } + if (ret != 0) + return (0); + + if ((test_config.arg != NULL || ot->wantarg != NULL) && + (test_config.arg == NULL || ot->wantarg == NULL || + strcmp(test_config.arg, ot->wantarg) != 0)) { + fprintf(stderr, "FAIL: test %i got arg '%s', want '%s'\n", + test_no, test_config.arg, ot->wantarg); + return (1); + } + if (test_config.flag != ot->wantflag) { + fprintf(stderr, "FAIL: test %i got flag %i, want %i\n", + test_no, test_config.flag, ot->wantflag); + return (1); + } + if (ot->type == OPTIONS_TEST_UNNAMED && + (unnamed != NULL || ot->unnamed != NULL) && + (unnamed == NULL || ot->unnamed == NULL || + strcmp(unnamed, ot->unnamed) != 0)) { + fprintf(stderr, "FAIL: test %i got unnamed '%s', want '%s'\n", + test_no, unnamed, ot->unnamed); + return (1); + } + if (ot->type == OPTIONS_TEST_ARGSUSED && used != ot->used) { + fprintf(stderr, "FAIL: test %i got used %i, want %i\n", + test_no, used, ot->used); + return (1); + } + + return (0); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_OPTIONS_TESTS; i++) { + printf("Test %d%s\n", (int)(i + 1), options_tests[i].want == 0 ? + "" : " is expected to complain"); + failed += do_options_test(i + 1, &options_tests[i]); + } + + return (failed); +} diff --git a/Libraries/libressl/tests/pbkdf2.c b/Libraries/libressl/tests/pbkdf2.c new file mode 100644 index 000000000..9cbc03182 --- /dev/null +++ b/Libraries/libressl/tests/pbkdf2.c @@ -0,0 +1,214 @@ +/* $OpenBSD: pbkdf2.c,v 1.2 2018/07/17 17:06:49 tb Exp $ */ +/* Written by Christian Heimes, 2013 */ +/* + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include + +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include + +typedef struct { + const char *pass; + int passlen; + const char *salt; + int saltlen; + int iter; +} testdata; + +static const testdata test_cases[] = { + {"password", 8, "salt", 4, 1}, + {"password", 8, "salt", 4, 2}, + {"password", 8, "salt", 4, 4096}, + {"passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096}, + {"pass\0word", 9, "sa\0lt", 5, 4096}, + {NULL}, +}; + +static const char *sha1_results[] = { + "0c60c80f961f0e71f3a9b524af6012062fe037a6", + "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", + "4b007901b765489abead49d926f721d065a429c1", + "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", + "56fa6aa75548099dcc37d7f03425e0c3", +}; + +static const char *sha256_results[] = { + "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b", + "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43", + "c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a", + "348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c63551" + "8c7dac47e9", + "89b69d0516f829893c696226650a8687", +}; + +static const char *sha512_results[] = { + "867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d47" + "0a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce", + "e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab" + "2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e", + "d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30" + "602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5", + "8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59" + "f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8", + "9d9e9c4cd21fe4be24d5b8244c759665", +}; + +static void +hexdump(FILE *f, const char *title, const unsigned char *s, size_t len) +{ + fprintf(f, "%s", title); + for (; len != 0; len--) + fprintf(f, " 0x%02x", *(s++)); + fprintf(f, "\n"); +} + +static int +convert(unsigned char *dst, const unsigned char *src, size_t len) +{ + unsigned int n; + + for (; len != 0; src += 2, len--) { + if (sscanf((char *)src, "%2x", &n) != 1) + return EINVAL; + *dst++ = (unsigned char)n; + } + return 0; +} + +static void +test_p5_pbkdf2(unsigned int n, const char *digestname, const testdata *test, + const char *hex) +{ + const EVP_MD *digest; + unsigned char *out; + unsigned char *expected; + size_t keylen; + int r; + + digest = EVP_get_digestbyname(digestname); + if (digest == NULL) { + fprintf(stderr, "unknown digest %s\n", digestname); + exit(5); + } + + keylen = strlen(hex); + if ((keylen % 2) != 0) { + fprintf(stderr, "odd hex string %s, digest %u\n", digestname, n); + exit(5); + } + keylen /= 2; + expected = malloc(keylen); + out = malloc(keylen); + if (expected == NULL || out == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(5); + } + if (convert(expected, (const unsigned char *)hex, keylen) != 0) { + fprintf(stderr, "invalid hex string %s, digest %u\n", hex, n); + exit(5); + } + + r = PKCS5_PBKDF2_HMAC(test->pass, test->passlen, + (const unsigned char *)test->salt, test->saltlen, + test->iter, digest, keylen, out); + + if (r == 0) { + fprintf(stderr, "PKCS5_PBKDF2_HMAC(%s) failure test %u\n", + digestname, n); + exit(3); + } + if (memcmp(expected, out, keylen) != 0) { + fprintf(stderr, + "Wrong result for PKCS5_PBKDF2_HMAC(%s) test %u\n", + digestname, n); + hexdump(stderr, "expected: ", expected, keylen); + hexdump(stderr, "result: ", out, keylen); + exit(2); + } + free(expected); + free(out); +} + +int +main(int argc,char **argv) +{ + unsigned int n; + const testdata *test = test_cases; + + OpenSSL_add_all_digests(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); + ENGINE_register_all_digests(); +#endif + + for (n = 0; test->pass != NULL; n++, test++) { + test_p5_pbkdf2(n, "sha1", test, sha1_results[n]); + test_p5_pbkdf2(n, "sha256", test, sha256_results[n]); + test_p5_pbkdf2(n, "sha512", test, sha512_results[n]); + } + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + return 0; +} diff --git a/Libraries/libressl/tests/pidwraptest.c b/Libraries/libressl/tests/pidwraptest.c new file mode 100644 index 000000000..5dbcef7bd --- /dev/null +++ b/Libraries/libressl/tests/pidwraptest.c @@ -0,0 +1,85 @@ +/* + * Checks if LibreSSL's PRNG is fork-safe. + * From https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux + * This code is in the public domain. + * + * Original source: https://gist.github.com/AGWA/eb84e55ca25a7da1deb0 + */ + +#undef LIBRESSL_INTERNAL +#include +#include +#include +#include +#include + +static void random_bytes (unsigned char* p, size_t len) +{ + if (RAND_bytes(p, len) != 1) { + fprintf(stderr, "RAND_bytes failed\n"); + abort(); + } +} + +static void random_stir (void) +{ + if (RAND_poll() != 1) { + fprintf(stderr, "RAND_poll failed\n"); + abort(); + } +} + +static void print_buffer (unsigned char* p, size_t len) +{ + while (len--) { + printf("%02x", (unsigned int)*p++); + } +} + +int main () +{ + char c = 0; + int pipefd[2]; + pipe(pipefd); + setbuf(stdout, NULL); + + if (fork() == 0) { + unsigned char buffer[32]; + pid_t grandparent_pid = getpid(); + + random_bytes(buffer, sizeof(buffer)); + + if (fork() == 0) { + random_stir(); + setsid(); + while (1) { + pid_t grandchild_pid = fork(); + if (grandchild_pid == 0) { + random_stir(); + if (getpid() == grandparent_pid) { + random_bytes(buffer, sizeof(buffer)); + print_buffer(buffer, sizeof(buffer)); + printf("\n"); + } + _exit(0); + } + wait(NULL); + if (grandchild_pid == grandparent_pid) { + break; + } + } + write(pipefd[1], &c, 1); + _exit(0); + } + + random_bytes(buffer, sizeof(buffer)); + print_buffer(buffer, sizeof(buffer)); + printf(" "); + _exit(0); + } + wait(NULL); + close(pipefd[1]); + read(pipefd[0], &c, 1); + return 0; +} + diff --git a/Libraries/libressl/tests/pidwraptest.sh b/Libraries/libressl/tests/pidwraptest.sh new file mode 100644 index 000000000..04fb5c45b --- /dev/null +++ b/Libraries/libressl/tests/pidwraptest.sh @@ -0,0 +1,11 @@ +#!/bin/sh +./pidwraptest > pidwraptest.txt +while read a b; +do + if [ "$a" = "$b" ]; then + echo "FAIL: $a = $b" + return 2 + else + echo "PASS: $a != $b" + fi +done < pidwraptest.txt diff --git a/Libraries/libressl/tests/pkcs7test.c b/Libraries/libressl/tests/pkcs7test.c new file mode 100644 index 000000000..28e0f67ae --- /dev/null +++ b/Libraries/libressl/tests/pkcs7test.c @@ -0,0 +1,301 @@ +/* $OpenBSD: pkcs7test.c,v 1.5 2021/04/07 17:21:40 tb Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +const char certificate[] = "\ +-----BEGIN CERTIFICATE----- \n\ +MIIDpTCCAo2gAwIBAgIJAPYm3GvOr5eTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV \n\ +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT \n\ +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt \n\ +ZWRpYXRlIENBMB4XDTE0MDUyNDE0NDUxMVoXDTI0MDQwMTE0NDUxMVowZDELMAkG \n\ +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU \n\ +RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw \n\ +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY \n\ ++yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs \n\ +lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D \n\ +nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2 \n\ +x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2 \n\ +bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9 \n\ +AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG \n\ ++EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B \n\ +AQUFAAOCAQEAJzA4KTjkjXGSC4He63yX9Br0DneGBzjAwc1H6f72uqnCs8m7jgkE \n\ +PQJFdTzQUKh97QPUuayZ2gl8XHagg+iWGy60Kw37gQ0+lumCN2sllvifhHU9R03H \n\ +bWtS4kue+yQjMbrzf3zWygMDgwvFOUAIgBpH9qGc+CdNu97INTYd0Mvz51vLlxRn \n\ +sC5aBYCWaZFnw3lWYxf9eVFRy9U+DkYFqX0LpmbDtcKP7AZGE6ZwSzaim+Cnoz1u \n\ +Cgn+QmpFXgJKMFIZ82iSZISn+JkCCGxctZX1lMvai4Wi8Y0HxW9FTFZ6KBNwwE4B \n\ +zjbN/ehBkgLlW/DWfi44DvwUHmuU6QP3cw== \n\ +-----END CERTIFICATE----- \n\ +"; + +const char private_key[] = "\ +-----BEGIN RSA PRIVATE KEY----- \n\ +MIIEpQIBAAKCAQEAtK2p2x0S3C1ajftAc3GaWPsji6scw1k9Sw/XltbLQuDc11/f \n\ +wwrUiFcje2CB3Ri6yD6+uCA3V12jEc4GdqzirJZhwgIhaTv42vfYBgiUcR9McEGr \n\ +agFC3yVR3lIbOzhBjmXNp1on46irxnzU4pT+w58IuvYqUBavaEtfRZocFR5NsIOy \n\ +mRhyNag8htOFK3wmTEYrb0vflFYT6SD47ogYtsd/xWSKS+YFyb7xSusR2Ot6Ktmr \n\ +MswQE57QYJz+KiRVlnL0cduMBdT52Wm8blaC9mz50PyrzjQ68NyHapCoWDU7pe4x \n\ +HLtzpXGSDMPuw4miiSwMym/2wReYJv6cFugLPQIDAQABAoIBAAZOyc9MhIwLSU4L \n\ +p4RgQvM4UVVe8/Id+3XTZ8NsXExJbWxXfIhiqGjaIfL8u4vsgRjcl+v1s/jo2/iT \n\ +KMab4o4D8gXD7UavQVDjtjb/ta79WL3SjRl2Uc9YjjMkyq6WmDNQeo2NKDdafCTB \n\ +1uzSJtLNipB8Z53ELPuHJhxX9QMHrMnuha49riQgXZ7buP9iQrHJFhImBjSzbxJx \n\ +L+TI6rkyLSf9Wi0Pd3L27Ob3QWNfNRYNSeTE+08eSRChkur5W0RuXAcuAICdQlCl \n\ +LBvWO/LmmvbzCqiDcgy/TliSb6CGGwgiNG7LJZmlkYNj8laGwalNlYZs3UrVv6NO \n\ +Br2loAECgYEA2kvCvPGj0Dg/6g7WhXDvAkEbcaL1tSeCxBbNH+6HS2UWMWvyTtCn \n\ +/bbD519QIdkvayy1QjEf32GV/UjUVmlULMLBcDy0DGjtL3+XpIhLKWDNxN1v1/ai \n\ +1oz23ZJCOgnk6K4qtFtlRS1XtynjA+rBetvYvLP9SKeFrnpzCgaA2r0CgYEA0+KX \n\ +1ACXDTNH5ySX3kMjSS9xdINf+OOw4CvPHFwbtc9aqk2HePlEsBTz5I/W3rKwXva3 \n\ +NqZ/bRqVVeZB/hHKFywgdUQk2Uc5z/S7Lw70/w1HubNTXGU06Ngb6zOFAo/o/TwZ \n\ +zTP1BMIKSOB6PAZPS3l+aLO4FRIRotfFhgRHOoECgYEAmiZbqt8cJaJDB/5YYDzC \n\ +mp3tSk6gIb936Q6M5VqkMYp9pIKsxhk0N8aDCnTU+kIK6SzWBpr3/d9Ecmqmfyq7 \n\ +5SvWO3KyVf0WWK9KH0abhOm2BKm2HBQvI0DB5u8sUx2/hsvOnjPYDISbZ11t0MtK \n\ +u35Zy89yMYcSsIYJjG/ROCUCgYEAgI2P9G5PNxEP5OtMwOsW84Y3Xat/hPAQFlI+ \n\ +HES+AzbFGWJkeT8zL2nm95tVkFP1sggZ7Kxjz3w7cpx7GX0NkbWSE9O+T51pNASV \n\ +tN1sQ3p5M+/a+cnlqgfEGJVvc7iAcXQPa3LEi5h2yPR49QYXAgG6cifn3dDSpmwn \n\ +SUI7PQECgYEApGCIIpSRPLAEHTGmP87RBL1smurhwmy2s/pghkvUkWehtxg0sGHh \n\ +kuaqDWcskogv+QC0sVdytiLSz8G0DwcEcsHK1Fkyb8A+ayiw6jWJDo2m9+IF4Fww \n\ +1Te6jFPYDESnbhq7+TLGgHGhtwcu5cnb4vSuYXGXKupZGzoLOBbv1Zw= \n\ +-----END RSA PRIVATE KEY----- \n\ +"; + +const char message[] = "\ +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do \r\n\ +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut \r\n\ +enim ad minim veniam, quis nostrud exercitation ullamco laboris \r\n\ +nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor \r\n\ +in reprehenderit in voluptate velit esse cillum dolore eu fugiat \r\n\ +nulla pariatur. Excepteur sint occaecat cupidatat non proident, \r\n\ +sunt in culpa qui officia deserunt mollit anim id est laborum. \r\n\ +"; + +static int +x509_store_callback(int ok, X509_STORE_CTX *ctx) +{ + /* Pretend the certificate issuer is valid... */ + return 1; +} + +static void +fatal(const char *msg) +{ + warnx("%s", msg); + ERR_print_errors_fp(stderr); + exit(1); +} + +static void +message_compare(const char *out, size_t len) +{ + if (len != sizeof(message)) { + fprintf(stderr, "FAILURE: length mismatch (%zu != %zu)\n", + len, sizeof(message)); + exit(1); + } + if (memcmp(out, message, len) != 0) { + fprintf(stderr, "FAILURE: message mismatch\n"); + fprintf(stderr, "Got:\n%s\n", out); + fprintf(stderr, "Want:\n%s\n", message); + exit(1); + } +} + +int +main(int argc, char **argv) +{ + BIO *bio_in, *bio_content, *bio_out, *bio_cert, *bio_pkey; + STACK_OF(X509) *certs; + const EVP_CIPHER *cipher; + EVP_PKEY *pkey; + X509_STORE *store; + X509 *cert; + PKCS7 *p7; + size_t len; + char *out; + int flags; + + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + + /* + * A bunch of setup... + */ + cipher = EVP_aes_256_cbc(); + if (cipher == NULL) + fatal("cipher"); + + certs = sk_X509_new_null(); + if (certs == NULL) + fatal("sk_X509_new_null"); + + bio_cert = BIO_new_mem_buf((char *)certificate, sizeof(certificate)); + if (bio_cert == NULL) + fatal("BIO_new_mem_buf certificate"); + + cert = PEM_read_bio_X509_AUX(bio_cert, NULL, NULL, NULL); + if (cert == NULL) + fatal("PEM_read_bio_X509_AUX"); + sk_X509_push(certs, cert); + + store = X509_STORE_new(); + if (store == NULL) + fatal("X509_STORE_new"); + X509_STORE_set_verify_cb(store, x509_store_callback); + + bio_pkey = BIO_new_mem_buf((char *)private_key, sizeof(private_key)); + if (bio_pkey == NULL) + fatal("BIO_new_mem_buf private_key"); + + pkey = PEM_read_bio_PrivateKey(bio_pkey, NULL, NULL, NULL); + if (pkey == NULL) + fatal("PEM_read_bio_PrivateKey"); + + bio_content = BIO_new_mem_buf((char *)message, sizeof(message)); + if (bio_content == NULL) + fatal("BIO_new_mem_buf message"); + + /* + * Encrypt and then decrypt. + */ + if (BIO_reset(bio_content) != 1) + fatal("BIO_reset"); + bio_out = BIO_new(BIO_s_mem()); + if (bio_out == NULL) + fatal("BIO_new"); + + p7 = PKCS7_encrypt(certs, bio_content, cipher, 0); + if (p7 == NULL) + fatal("PKCS7_encrypt"); + if (PEM_write_bio_PKCS7(bio_out, p7) != 1) + fatal("PEM_write_bio_PKCS7"); + PKCS7_free(p7); + + bio_in = bio_out; + bio_out = BIO_new(BIO_s_mem()); + if (bio_out == NULL) + fatal("BIO_new"); + + p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); + if (p7 == NULL) + fatal("PEM_read_bio_PKCS7"); + if (PKCS7_decrypt(p7, pkey, cert, bio_out, 0) != 1) + fatal("PKCS7_decrypt"); + PKCS7_free(p7); + + len = BIO_get_mem_data(bio_out, &out); + message_compare(out, len); + + BIO_free(bio_in); + BIO_free(bio_out); + + /* + * Sign and then verify. + */ + if (BIO_reset(bio_content) != 1) + fatal("BIO_reset"); + bio_out = BIO_new(BIO_s_mem()); + if (bio_out == NULL) + fatal("BIO_new"); + + p7 = PKCS7_sign(cert, pkey, certs, bio_content, 0); + if (p7 == NULL) + fatal("PKCS7_sign"); + if (PEM_write_bio_PKCS7(bio_out, p7) != 1) + fatal("PEM_write_bio_PKCS7"); + PKCS7_free(p7); + + bio_in = bio_out; + bio_out = BIO_new(BIO_s_mem()); + if (bio_out == NULL) + fatal("BIO_new"); + + p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); + if (p7 == NULL) + fatal("PEM_read_bio_PKCS7"); + if (PKCS7_verify(p7, certs, store, NULL, bio_out, 0) != 1) + fatal("PKCS7_verify"); + PKCS7_free(p7); + + len = BIO_get_mem_data(bio_out, &out); + message_compare(out, len); + + BIO_free(bio_in); + BIO_free(bio_out); + + /* + * Sign and then verify with a detached signature. + */ + if (BIO_reset(bio_content) != 1) + fatal("BIO_reset"); + bio_out = BIO_new(BIO_s_mem()); + if (bio_out == NULL) + fatal("BIO_new"); + + flags = PKCS7_DETACHED|PKCS7_PARTIAL; + p7 = PKCS7_sign(NULL, NULL, NULL, bio_content, flags); + if (p7 == NULL) + fatal("PKCS7_sign"); + if (PKCS7_sign_add_signer(p7, cert, pkey, NULL, flags) == NULL) + fatal("PKCS7_sign_add_signer"); + if (PKCS7_final(p7, bio_content, flags) != 1) + fatal("PKCS7_final"); + if (PEM_write_bio_PKCS7(bio_out, p7) != 1) + fatal("PEM_write_bio_PKCS7"); + PKCS7_free(p7); + + /* bio_out contains only the detached signature. */ + bio_in = bio_out; + if (BIO_reset(bio_content) != 1) + fatal("BIO_reset"); + + bio_out = BIO_new(BIO_s_mem()); + if (bio_out == NULL) + fatal("BIO_new"); + + p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); + if (p7 == NULL) + fatal("PEM_read_bio_PKCS7"); + if (PKCS7_verify(p7, certs, store, bio_content, bio_out, flags) != 1) + fatal("PKCS7_verify"); + PKCS7_free(p7); + + len = BIO_get_mem_data(bio_out, &out); + message_compare(out, len); + + BIO_free(bio_in); + BIO_free(bio_out); + BIO_free(bio_content); + BIO_free(bio_cert); + BIO_free(bio_pkey); + + EVP_PKEY_free(pkey); + + X509_free(cert); + X509_STORE_free(store); + sk_X509_free(certs); + + return 0; +} diff --git a/Libraries/libressl/tests/policy.c b/Libraries/libressl/tests/policy.c new file mode 100644 index 000000000..f5c9700b2 --- /dev/null +++ b/Libraries/libressl/tests/policy.c @@ -0,0 +1,667 @@ +/* $OpenBSD: policy.c,v 1.12 2023/06/02 08:35:10 tb Exp $ */ +/* + * Copyright (c) 2020 Joel Sing + * Copyright (c) 2020-2023 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "x509_verify.h" + +#define MODE_MODERN_VFY 0 +#define MODE_MODERN_VFY_DIR 1 +#define MODE_LEGACY_VFY 2 + +static int verbose = 1; + +#define OID1 "1.2.840.113554.4.1.72585.2.1" +#define OID2 "1.2.840.113554.4.1.72585.2.2" +#define OID3 "1.2.840.113554.4.1.72585.2.3" +#define OID4 "1.2.840.113554.4.1.72585.2.4" +#define OID5 "1.2.840.113554.4.1.72585.2.5" + +#ifndef CERTSDIR +#define CERTSDIR "." +#endif + +static int +passwd_cb(char *buf, int size, int rwflag, void *u) +{ + memset(buf, 0, size); + return (0); +} + +static int +certs_from_file(const char *filename, STACK_OF(X509) **certs) +{ + STACK_OF(X509_INFO) *xis = NULL; + STACK_OF(X509) *xs = NULL; + BIO *bio = NULL; + X509 *x; + int i; + + if (*certs == NULL) { + if ((xs = sk_X509_new_null()) == NULL) + errx(1, "failed to create X509 stack"); + } else { + xs = *certs; + } + if ((bio = BIO_new_file(filename, "r")) == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to create bio"); + } + if ((xis = PEM_X509_INFO_read_bio(bio, NULL, passwd_cb, NULL)) == NULL) + errx(1, "failed to read PEM"); + + for (i = 0; i < sk_X509_INFO_num(xis); i++) { + if ((x = sk_X509_INFO_value(xis, i)->x509) == NULL) + continue; + if (!sk_X509_push(xs, x)) + errx(1, "failed to push X509"); + X509_up_ref(x); + } + + *certs = xs; + xs = NULL; + + sk_X509_INFO_pop_free(xis, X509_INFO_free); + sk_X509_pop_free(xs, X509_free); + BIO_free(bio); + + return 1; +} + +static int +verify_cert_cb(int ok, X509_STORE_CTX *xsc) +{ + X509 *current_cert; + int verify_err; + + current_cert = X509_STORE_CTX_get_current_cert(xsc); + if (current_cert != NULL) { + X509_NAME_print_ex_fp(stderr, + X509_get_subject_name(current_cert), 0, + XN_FLAG_ONELINE); + fprintf(stderr, "\n"); + } + + verify_err = X509_STORE_CTX_get_error(xsc); + if (verify_err != X509_V_OK) { + fprintf(stderr, "verify error at depth %d: %s\n", + X509_STORE_CTX_get_error_depth(xsc), + X509_verify_cert_error_string(verify_err)); + } + + return ok; +} + +static void +verify_cert(const char *roots_file, const char *intermediate_file, + const char *leaf_file, int *chains, int *error, int *error_depth, + int mode, ASN1_OBJECT *policy_oid, ASN1_OBJECT *policy_oid2, + int verify_flags) +{ + STACK_OF(X509) *roots = NULL, *bundle = NULL; + X509_STORE_CTX *xsc = NULL; + X509_STORE *store = NULL; + X509 *leaf = NULL; + int flags, ret; + + *chains = 0; + *error = 0; + *error_depth = 0; + + if (!certs_from_file(roots_file, &roots)) + errx(1, "failed to load roots from '%s'", roots_file); + if (!certs_from_file(leaf_file, &bundle)) + errx(1, "failed to load leaf from '%s'", leaf_file); + if (intermediate_file != NULL && !certs_from_file(intermediate_file, + &bundle)) + errx(1, "failed to load intermediate from '%s'", + intermediate_file); + if (sk_X509_num(bundle) < 1) + errx(1, "not enough certs in bundle"); + leaf = sk_X509_shift(bundle); + + if ((xsc = X509_STORE_CTX_new()) == NULL) + errx(1, "X509_STORE_CTX"); + if (!X509_STORE_CTX_init(xsc, store, leaf, bundle)) { + ERR_print_errors_fp(stderr); + errx(1, "failed to init store context"); + } + + flags = X509_V_FLAG_POLICY_CHECK; + flags |= verify_flags; + if (mode == MODE_LEGACY_VFY) + flags |= X509_V_FLAG_LEGACY_VERIFY; + X509_STORE_CTX_set_flags(xsc, flags); + + if (verbose) + X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); + X509_STORE_CTX_set0_trusted_stack(xsc, roots); + + if (policy_oid != NULL) { + X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(xsc); + ASN1_OBJECT *copy = OBJ_dup(policy_oid); + X509_VERIFY_PARAM_add0_policy(param, copy); + } + if (policy_oid2 != NULL) { + X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(xsc); + ASN1_OBJECT *copy = OBJ_dup(policy_oid2); + X509_VERIFY_PARAM_add0_policy(param, copy); + } + + ret = X509_verify_cert(xsc); + + *error = X509_STORE_CTX_get_error(xsc); + *error_depth = X509_STORE_CTX_get_error_depth(xsc); + + if (ret == 1) { + *chains = 1; /* XXX */ + goto done; + } + + if (*error == 0) + errx(1, "Error unset on failure!\n"); + + fprintf(stderr, "failed to verify at %d: %s\n", + *error_depth, X509_verify_cert_error_string(*error)); + + done: + sk_X509_pop_free(roots, X509_free); + sk_X509_pop_free(bundle, X509_free); + X509_STORE_free(store); + X509_STORE_CTX_free(xsc); + X509_free(leaf); +} + +struct verify_cert_test { + const char *id; + const char *root_file; + const char *intermediate_file; + const char *leaf_file; + const char *policy_oid_to_check; + const char *policy_oid_to_check2; + int want_chains; + int want_error; + int want_error_depth; + int want_legacy_error; + int want_legacy_error_depth; + int failing; + int verify_flags; +}; + +struct verify_cert_test verify_cert_tests[] = { + /* + * Comments here are from boringssl/crypto/x509/x509_test.cc + * certs were generated by + * boringssl/crypto/x509/test/make_policy_certs.go + */ + + /* The chain is good for |oid1| and |oid2|, but not |oid3|. */ + { + .id = "nothing in 1 and 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .want_chains = 1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + }, + { + .id = "1, in 1 and 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID1, + .want_chains = 1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + }, + { + .id = "2, in 1 and 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID2, + .want_chains = 1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + }, + { + .id = "3, in 1 and 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + { + .id = "1 and 2, in 1 and 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID1, + .policy_oid_to_check2 = OID2, + .want_chains = 1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + }, + { + .id = "1 and 3, in 1 and 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID1, + .policy_oid_to_check2 = OID3, + .want_chains = 1, + }, + /* The policy extension cannot be parsed. */ + { + .id = "1 in invalid intermediate policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_invalid.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID1, + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + { + .id = "invalid intermediate", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_invalid.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + { + .id = "1 in invalid policy in leaf", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem", + .policy_oid_to_check = OID1, + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + { + .id = "invalid leaf", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem", + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + { + .id = "invalid leaf without explicit policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem", + .want_chains = 0, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + /* There is a duplicate policy in the leaf policy extension. */ + { + .id = "1 in duplicate policy extension in leaf", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_duplicate.pem", + .policy_oid_to_check = OID1, + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + /* There is a duplicate policy in the intermediate policy extension. */ + { + .id = "1 in duplicate policy extension in intermediate", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_duplicate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID1, + .want_chains = 0, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + /* + * Without |X509_V_FLAG_EXPLICIT_POLICY|, the policy tree is built and + * intersected with user-specified policies, but it is not required to result + * in any valid policies. + */ + { + .id = "nothing with explicit_policy unset", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .want_chains = 1, + }, + { + .id = "oid3 with explicit_policy unset", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .want_chains = 1, + }, + /* However, a CA with policy constraints can require an explicit policy. */ + { + .id = "oid1 with explicit_policy unset, intermediate requiring policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID1, + .want_chains = 1, + }, + { + .id = "oid3 with explicit_policy unset, intermediate requiring policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + /* + * requireExplicitPolicy applies even if the application does not configure a + * user-initial-policy-set. If the validation results in no policies, the + * chain is invalid. + */ + { + .id = "nothing explict_policy unset, with intermediate requiring policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_none.pem", + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + /* A leaf can also set requireExplicitPolicy but should work with none */ + { + .id = "nothing explicit_policy unset, with leaf requiring policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_require.pem", + .want_chains = 1, + }, + /* A leaf can also set requireExplicitPolicy but should fail with policy */ + { + .id = "oid3, explicit policy unset, with leaf requiring policy", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_require.pem", + .policy_oid_to_check = OID3, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + /* + * requireExplicitPolicy is a count of certificates to skip. If the value is + * not zero by the end of the chain, it doesn't count. + */ + { + .id = "oid3, with intermediate requiring explicit depth 1", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require1.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + { + .id = "oid3, with intermediate requiring explicit depth 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require2.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .want_chains = 1, + }, + { + .id = "oid3, with leaf requiring explicit depth 1", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_require1.pem", + .policy_oid_to_check = OID3, + .want_chains = 1, + }, + /* + * If multiple certificates specify the constraint, the more constrained value + * wins. + */ + { + .id = "oid3, with leaf and intermediate requiring explicit depth 1", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require1.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_require1.pem", + .policy_oid_to_check = OID3, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + { + .id = "oid3, with leaf requiring explicit depth 1 and intermediate depth 2", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require2.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_require.pem", + .policy_oid_to_check = OID3, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + /* + * An intermediate that requires an explicit policy, but then specifies no + * policies should fail verification as a result. + */ + { + .id = "oid1 with explicit_policy unset, intermediate requiring policy but specifying none", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require_no_policies.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + /* + * A constrained intermediate's policy extension has a duplicate policy, which + * is invalid. Historically this, and the above case, leaked memory. + */ + { + .id = "oid1 with explicit_policy unset, intermediate requiring policy but has duplicate", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_require_duplicate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf.pem", + .policy_oid_to_check = OID3, + .want_chains = 0, + .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, + .want_legacy_error_depth = 0, + }, + /* + * The leaf asserts anyPolicy, but the intermediate does not. The resulting + * valid policies are the intersection.(and vice versa) + */ + { + .id = "oid1, with explicit_policy set, with leaf asserting any", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_any.pem", + .policy_oid_to_check = OID1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 1, + }, + { + .id = "oid3, with explicit_policy set, with leaf asserting any", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_any.pem", + .policy_oid_to_check = OID3, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 0, + .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_error_depth = 0, + .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, + .want_legacy_error_depth = 0, + }, + /* Both assert anyPolicy. All policies are valid. */ + { + .id = "oid1, with explicit_policy set, with leaf and intermediate asserting any", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_any.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_any.pem", + .policy_oid_to_check = OID1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 1, + }, + { + .id = "oid3, with explicit_policy set, with leaf and intermediate asserting any", + .root_file = CERTSDIR "/" "policy_root.pem", + .intermediate_file = CERTSDIR "/" "policy_intermediate_any.pem", + .leaf_file = CERTSDIR "/" "policy_leaf_any.pem", + .policy_oid_to_check = OID1, + .verify_flags = X509_V_FLAG_EXPLICIT_POLICY, + .want_chains = 1, + }, + /* + * BoringSSL tests just a trust anchor but behaves differently in this corner case. + * than libressl for reasons that have nothing to do with policy (because parital + * chains and legacy verifier horror) + */ +}; + +#define N_VERIFY_CERT_TESTS \ + (sizeof(verify_cert_tests) / sizeof(*verify_cert_tests)) + +static int +verify_cert_test(int mode) +{ + ASN1_OBJECT *policy_oid, *policy_oid2; + struct verify_cert_test *vct; + int chains, error, error_depth; + int failed = 0; + size_t i; + + for (i = 0; i < N_VERIFY_CERT_TESTS; i++) { + vct = &verify_cert_tests[i]; + policy_oid = vct->policy_oid_to_check ? + OBJ_txt2obj(vct->policy_oid_to_check, 1) : NULL; + policy_oid2 = vct->policy_oid_to_check2 ? + OBJ_txt2obj(vct->policy_oid_to_check2, 1) : NULL; + + error = 0; + error_depth = 0; + + fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); + verify_cert(vct->root_file, vct->intermediate_file, + vct->leaf_file, &chains, &error, &error_depth, + mode, policy_oid, policy_oid2, vct->verify_flags); + + if ((chains == 0 && vct->want_chains == 0) || + (chains == 1 && vct->want_chains > 0)) { + fprintf(stderr, "INFO: Succeeded with %d chains%s\n", + chains, vct->failing ? " (legacy failure)" : ""); + if (mode == MODE_LEGACY_VFY && vct->failing) + failed |= 1; + } else { + fprintf(stderr, "FAIL: Failed with %d chains%s\n", + chains, vct->failing ? " (legacy failure)" : ""); + if (!vct->failing) + failed |= 1; + } + + if (mode == MODE_LEGACY_VFY) { + if (error != vct->want_legacy_error) { + fprintf(stderr, "FAIL: Got legacy error %d, " + "want %d\n", error, vct->want_legacy_error); + failed |= 1; + } + if (error_depth != vct->want_legacy_error_depth) { + fprintf(stderr, "FAIL: Got legacy error depth " + "%d, want %d\n", error_depth, + vct->want_legacy_error_depth); + failed |= 1; + } + } + fprintf(stderr, "\n"); + ASN1_OBJECT_free(policy_oid); + ASN1_OBJECT_free(policy_oid2); + } + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + fprintf(stderr, "\n\nTesting legacy x509_vfy\n"); + failed |= verify_cert_test(MODE_LEGACY_VFY); + fprintf(stderr, "\n\nTesting modern x509_vfy\n"); + failed |= verify_cert_test(MODE_MODERN_VFY); + /* New verifier does not do policy goop at the moment */ + + return (failed); +} diff --git a/Libraries/libressl/tests/policy_intermediate.pem b/Libraries/libressl/tests/policy_intermediate.pem new file mode 100644 index 000000000..759deb4c4 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBqjCCAVGgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgYUwgYIwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAoGCCqGSM49BAMCA0cAMEQCIFN2ZtknXQ9vz23qD1ecprC9iIo7 +j/SI42Ub64qZQaraAiA+CRCWJz/l+NQ1+TPWYDDWY6Wh2L9Wbddh1Nj5KJEkhQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_any.pem b/Libraries/libressl/tests/policy_intermediate_any.pem new file mode 100644 index 000000000..0931964f5 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_any.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBkDCCATWgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjajBoMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE +YcLF6z1QWoBtrjARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZIzj0EAwIDSQAwRgIh +AJbyXshUwjsFCiqrJkg91GzJdhZZ+3WXOekCJgi8uEESAiEAhv4sEE0wRRqgHDjl +vIt26IELfFE2Z/FBF3ihGmi6NoI= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_duplicate.pem b/Libraries/libressl/tests/policy_intermediate_duplicate.pem new file mode 100644 index 000000000..0eafe8d86 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_duplicate.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBvDCCAWKgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZYwgZMwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMDwGA1UdIAQ1MDMwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMA8GDSqGSIb3EgQBhLcJAgIwCgYIKoZIzj0EAwIDSAAwRQIgUpG6 +FUeWrC62BtTPHiSlWBdnLWUYH0llS6uYUkpJFJECIQCWfhoZYXvHdMhgBDSI/vzY +Sw4uNdcMxrC2kP6lIioUSw== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_invalid.pem b/Libraries/libressl/tests/policy_intermediate_invalid.pem new file mode 100644 index 000000000..11c95afce --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_invalid.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjDCCATKgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjZzBlMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE +YcLF6z1QWoBtrjAOBgNVHSAEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgS2uK +cYlZ1bxeqgMy3X0Sfi0arAnqpePsAqAeEf+HJHQCIQDwfCnXrWyHET9lM/gJSkfN +j/JRJvJELDrAMVewCxZWKA== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_mapped.pem b/Libraries/libressl/tests/policy_intermediate_mapped.pem new file mode 100644 index 000000000..fa45e604b --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_mapped.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAlSgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjggGHMIIBgzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u +qGsIhGHCxes9UFqAba4wXgYDVR0gBFcwVTAPBg0qhkiG9xIEAYS3CQIBMA8GDSqG +SIb3EgQBhLcJAgIwDwYNKoZIhvcSBAGEtwkCAzAPBg0qhkiG9xIEAYS3CQIEMA8G +DSqGSIb3EgQBhLcJAgUwgcsGA1UdIQSBwzCBwDAeBg0qhkiG9xIEAYS3CQIDBg0q +hkiG9xIEAYS3CQIBMB4GDSqGSIb3EgQBhLcJAgMGDSqGSIb3EgQBhLcJAgIwHgYN +KoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBDAeBg0qhkiG9xIEAYS3CQIEBg0q +hkiG9xIEAYS3CQIFMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3EgQBhLcJAgQwHgYN +KoZIhvcSBAGEtwkCBQYNKoZIhvcSBAGEtwkCBTAKBggqhkjOPQQDAgNIADBFAiAe +Ah2vJMZsW/RV35mM7b7/NjsjScjPEIxfDJu49inNXQIhANmGBqyWUogh/gXyVB0/ +IfDro27pANW3R02A+zH34q5k +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_mapped_any.pem b/Libraries/libressl/tests/policy_intermediate_mapped_any.pem new file mode 100644 index 000000000..ae47bf45c --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_mapped_any.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYjCCAgegAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjggE6MIIBNjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u +qGsIhGHCxes9UFqAba4wEQYDVR0gBAowCDAGBgRVHSAAMIHLBgNVHSEEgcMwgcAw +HgYNKoZIhvcSBAGEtwkCAwYNKoZIhvcSBAGEtwkCATAeBg0qhkiG9xIEAYS3CQID +Bg0qhkiG9xIEAYS3CQICMB4GDSqGSIb3EgQBhLcJAgQGDSqGSIb3EgQBhLcJAgQw +HgYNKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBTAeBg0qhkiG9xIEAYS3CQIF +Bg0qhkiG9xIEAYS3CQIEMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3EgQBhLcJAgUw +CgYIKoZIzj0EAwIDSQAwRgIhAIOx3GL5xlldQGdTLIvTTAvczm8wiYHzZDAif2yj +wAjEAiEAg4K02kTYX9x7PC/u1PYdwvo+LVbnGbO6AN6U3K2d7gs= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_mapped_oid3.pem b/Libraries/libressl/tests/policy_intermediate_mapped_oid3.pem new file mode 100644 index 000000000..c04a38a48 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_mapped_oid3.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICajCCAhCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjggFDMIIBPzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u +qGsIhGHCxes9UFqAba4wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIDMIHLBgNV +HSEEgcMwgcAwHgYNKoZIhvcSBAGEtwkCAwYNKoZIhvcSBAGEtwkCATAeBg0qhkiG +9xIEAYS3CQIDBg0qhkiG9xIEAYS3CQICMB4GDSqGSIb3EgQBhLcJAgQGDSqGSIb3 +EgQBhLcJAgQwHgYNKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBTAeBg0qhkiG +9xIEAYS3CQIFBg0qhkiG9xIEAYS3CQIEMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3 +EgQBhLcJAgUwCgYIKoZIzj0EAwIDSAAwRQIhAK0bRaGgd5qQlX+zTw3IUynFHxfk +zRbZagnTzjYtkNNmAiBJ2kOnvRdW930eHAwZPGpc1Hn5hMSOQdUhNZ3XZDASkQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_require.pem b/Libraries/libressl/tests/policy_intermediate_require.pem new file mode 100644 index 000000000..5cf5d5bfe --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_require.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuDCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAwGA1UdJAQFMAOAAQAwCgYIKoZIzj0EAwIDRwAwRAIgbPUZ9ezH +SgTqom7VLPOvrQQXwy3b/ijSobs7+SOouKMCIDaqcb9143BG005etqeTvlgUyOGF +GQDWhiW8bizH+KEl +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_require1.pem b/Libraries/libressl/tests/policy_intermediate_require1.pem new file mode 100644 index 000000000..7087404b3 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_require1.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBujCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAwGA1UdJAQFMAOAAQEwCgYIKoZIzj0EAwIDSQAwRgIhAIAwvhHB +GQDN5YXlidd+n3OT/SqoeXfp7RiEonBnCkW4AiEA+iFc47EOBchHb+Gy0gg8F9Po +RnlpoulWDfbDwx9r4lc= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_require2.pem b/Libraries/libressl/tests/policy_intermediate_require2.pem new file mode 100644 index 000000000..350f41919 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_require2.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuTCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAwGA1UdJAQFMAOAAQIwCgYIKoZIzj0EAwIDSAAwRQIgOpliSKKA ++wy/auQnKKl+wwtn/hGw6eZXgIOtFgDmyMYCIQC84zoJL87AE64gsrdX4XSHq6lb +WhZQp9ZnDaNu88SQLQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_require_duplicate.pem b/Libraries/libressl/tests/policy_intermediate_require_duplicate.pem new file mode 100644 index 000000000..733087af9 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_require_duplicate.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByjCCAXCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgaQwgaEwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMDwGA1UdIAQ1MDMwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMA8GDSqGSIb3EgQBhLcJAgIwDAYDVR0kBAUwA4ABADAKBggqhkjO +PQQDAgNIADBFAiA2GxzMRYYo7NNq8u/ZvffXkCj/phqXQ8I64tEDd0X8pgIhAOJJ +e+dzzf4vbWfMlYkOQ4kf6ei5Zf+J2PL6VrqVrHQa +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_intermediate_require_no_policies.pem b/Libraries/libressl/tests/policy_intermediate_require_no_policies.pem new file mode 100644 index 000000000..1e81e0c11 --- /dev/null +++ b/Libraries/libressl/tests/policy_intermediate_require_no_policies.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBizCCATCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjZTBjMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE +YcLF6z1QWoBtrjAMBgNVHSQEBTADgAEAMAoGCCqGSM49BAMCA0kAMEYCIQDJYPgf +50fFDVho5TFeqkNVONx0ArVNgULPB27yPDHLrwIhAN+eua6oM4Q/O0jUESQ4VAKt +ts7ZCquTZbvgRgyqtjuT +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf.pem b/Libraries/libressl/tests/policy_leaf.pem new file mode 100644 index 000000000..fb70306c8 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBpzCCAU2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo34wfDAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wKwYDVR0gBCQwIjAPBg0qhkiG9xIEAYS3CQIBMA8GDSqGSIb3EgQB +hLcJAgIwCgYIKoZIzj0EAwIDSAAwRQIgBEOriD1N3/cqoAofxEtf73M7Wi4UfjFK +jiU9nQhwnnoCIQD1v/XDp2BkWNHxNq7TaPnil3xXTvMX97yUbkUg8IRo0w== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_any.pem b/Libraries/libressl/tests/policy_leaf_any.pem new file mode 100644 index 000000000..d2c1b9e95 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_any.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjTCCATOgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2QwYjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wEQYDVR0gBAowCDAGBgRVHSAAMAoGCCqGSM49BAMCA0gAMEUCIQC4 +UwAf1R4HefSzyO8lyQ3fmMjkptVEhFBee0a7N12IvwIgJMYZgQ52VTbqXyXqraJ8 +V+y+o7eHds7NewqnyuLbc78= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_duplicate.pem b/Libraries/libressl/tests/policy_leaf_duplicate.pem new file mode 100644 index 000000000..bdeb13cbd --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_duplicate.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBsTCCAVigAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE +AxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkSrY +vFVtkZJmvirfY0JDDYrZQrNJecPLt0ksJux2URL5nAQiQY1SERGnEaiNLpoc0dle +TS8wQT/cjw/wPgoeV6OBkDCBjTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5j +b20wPAYDVR0gBDUwMzAPBg0qhkiG9xIEAYS3CQIBMA8GDSqGSIb3EgQBhLcJAgIw +DwYNKoZIhvcSBAGEtwkCAjAKBggqhkjOPQQDAgNHADBEAiBjYDwsWcs35hU/wPqa +5gf0QUMvV/8z5LPX14fB2y4RGQIgMw0ekrt9K5UcgkvFupV/XXIjLRFQvc8URA3C +/+w+2/4= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_invalid.pem b/Libraries/libressl/tests/policy_leaf_invalid.pem new file mode 100644 index 000000000..de7a5e9b2 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_invalid.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBgjCCASigAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE +AxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkSrY +vFVtkZJmvirfY0JDDYrZQrNJecPLt0ksJux2URL5nAQiQY1SERGnEaiNLpoc0dle +TS8wQT/cjw/wPgoeV6NhMF8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMAwGA1UdEwEB/wQCMAAwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t +MA4GA1UdIAQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiAgfcDIeqmV+u5YtUe4 +aBnj13tZAJAQh6ttum1xZ+xHEgIhAJqvGX5c0/d1qYelBlm/jE3UuivijdEjVsLX +GVH+X1VA +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_none.pem b/Libraries/libressl/tests/policy_leaf_none.pem new file mode 100644 index 000000000..13ad7cec0 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_none.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBezCCASCgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo1EwTzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wCgYIKoZIzj0EAwIDSQAwRgIhAIDFeeYJ8nmYo09OnJFpNS3A6fYO +ZliHkAqOsg193DTnAiEA3OSHLCczcvRjMG+qd/FI61u2sKU1hhHh7uHtD/YO/dA= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_oid1.pem b/Libraries/libressl/tests/policy_leaf_oid1.pem new file mode 100644 index 000000000..94cd1a77b --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_oid1.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlTCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIBMAoGCCqGSM49BAMC +A0cAMEQCIHh4Bo8l/HVJhLMWcYusPOE0arqoDrJ5E0M6nEi3nRhgAiAArK8bBohG +fZ3DmVMq/2BJtQZwRRj+50VKWuf9mBSflQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_oid2.pem b/Libraries/libressl/tests/policy_leaf_oid2.pem new file mode 100644 index 000000000..10adf86c5 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_oid2.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQICMAoGCCqGSM49BAMC +A0kAMEYCIQDvW7rdL6MSW/0BPNET4hEeECO6LWmZZHKCHIu6o33dsAIhAPwgm6lD +KV2hMOxkE6rBDQzlCr+zAkQrxSzQZqJp5p+W +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_oid3.pem b/Libraries/libressl/tests/policy_leaf_oid3.pem new file mode 100644 index 000000000..e5c103151 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_oid3.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIDMAoGCCqGSM49BAMC +A0kAMEYCIQDBPnPpRsOH20ncg8TKUdlONfbO62WafQj9SKgyi/nGBQIhAMhT8J7f +fTEou6jlAilaIQwlAgZzVKRqgghIHezFY86T +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_oid4.pem b/Libraries/libressl/tests/policy_leaf_oid4.pem new file mode 100644 index 000000000..7dd7a547a --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_oid4.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIEMAoGCCqGSM49BAMC +A0kAMEYCIQD2gnpCTMxUalCtEV52eXzqeJgsKMYvEpJTuU/VqH5KwQIhAPEavAkt +cSJsgMgJcJnbBzAdSrbOgHXF2etDHmFbg0hz +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_oid5.pem b/Libraries/libressl/tests/policy_leaf_oid5.pem new file mode 100644 index 000000000..2a9aee73b --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_oid5.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIFMAoGCCqGSM49BAMC +A0kAMEYCIQDDFVjhlQ1Wu0KITcRX8kELpVDeYSKSlvEbZc3rn1QjkQIhAMPthqBi +I0acz8DPQcdFmHXV0xR2xyC1yuen0gES5WLR +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_require.pem b/Libraries/libressl/tests/policy_leaf_require.pem new file mode 100644 index 000000000..169b84441 --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_require.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuDCCAV2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GNMIGKMA4GA1UdDwEB/wQEAwICBDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5l +eGFtcGxlLmNvbTArBgNVHSAEJDAiMA8GDSqGSIb3EgQBhLcJAgEwDwYNKoZIhvcS +BAGEtwkCAjAMBgNVHSQEBTADgAEAMAoGCCqGSM49BAMCA0kAMEYCIQDrNQPi/mdK +l7Nd/YmMXWYTHJBWWin1zA64Ohkd7z4jGgIhAJpw/umk5MxS1MwSi+YTkkcSQKpl +YROQH6+T53DauoW6 +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_leaf_require1.pem b/Libraries/libressl/tests/policy_leaf_require1.pem new file mode 100644 index 000000000..261ef954f --- /dev/null +++ b/Libraries/libressl/tests/policy_leaf_require1.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuDCCAV2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GNMIGKMA4GA1UdDwEB/wQEAwICBDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5l +eGFtcGxlLmNvbTArBgNVHSAEJDAiMA8GDSqGSIb3EgQBhLcJAgEwDwYNKoZIhvcS +BAGEtwkCAjAMBgNVHSQEBTADgAEBMAoGCCqGSM49BAMCA0kAMEYCIQCtXENGJrKv +IOeLHO/3Nu/SMRXc69Vb3q+4b/uHBFbuqwIhAK22Wfh/ZIHKu3FwbjL+sN0Z39pf +Dsak6fp1y4tqNuvK +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_root.pem b/Libraries/libressl/tests/policy_root.pem new file mode 100644 index 000000000..595f8a132 --- /dev/null +++ b/Libraries/libressl/tests/policy_root.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBdTCCARqgAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE +AxMLUG9saWN5IFJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQmdqXYl1Gv +Y7y3jcTTK6MVXIQr44TqChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAP +EPSJwPndjolto1cwVTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU0GnnoB+yeN63WMthnh6Uh1HH +dRIwCgYIKoZIzj0EAwIDSQAwRgIhAKVxVAaJnmvt+q4SqegGS23QSzKPM9Yakw9e +bOUU9+52AiEAjXPRBdd90YDey4VFu4f/78yVe0cxMK30lll7lLl7TTA= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_root2.pem b/Libraries/libressl/tests/policy_root2.pem new file mode 100644 index 000000000..1350035fd --- /dev/null +++ b/Libraries/libressl/tests/policy_root2.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBeDCCAR6gAwIBAgIBATAKBggqhkjOPQQDAjAYMRYwFAYDVQQDEw1Qb2xpY3kg +Um9vdCAyMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAYMRYwFAYD +VQQDEw1Qb2xpY3kgUm9vdCAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJnal +2JdRr2O8t43E0yujFVyEK+OE6goUWCOiHlfbSAeoyLDmPkKJdW5PMf+wORRjp1Fh +VSxADxD0icD53Y6JbaNXMFUwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNBp56Afsnjet1jLYZ4e +lIdRx3USMAoGCCqGSM49BAMCA0gAMEUCIQDm9rw9ODVtJUPBn2lWoK8s7ElbyY4/ +Gc2thHR50UUzbgIgKRenEDhKiBR6cGC77RaIiaaafW8b7HMd7obuZdDU/58= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/policy_root_cross_inhibit_mapping.pem b/Libraries/libressl/tests/policy_root_cross_inhibit_mapping.pem new file mode 100644 index 000000000..9273a5308 --- /dev/null +++ b/Libraries/libressl/tests/policy_root_cross_inhibit_mapping.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBljCCAT2gAwIBAgIBATAKBggqhkjOPQQDAjAYMRYwFAYDVQQDEw1Qb2xpY3kg +Um9vdCAyMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAWMRQwEgYD +VQQDEwtQb2xpY3kgUm9vdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCZ2pdiX +Ua9jvLeNxNMroxVchCvjhOoKFFgjoh5X20gHqMiw5j5CiXVuTzH/sDkUY6dRYVUs +QA8Q9InA+d2OiW2jeDB2MA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF +BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTQaeegH7J43rdYy2GeHpSH +Ucd1EjARBgNVHSAECjAIMAYGBFUdIAAwDAYDVR0kBAUwA4EBADAKBggqhkjOPQQD +AgNHADBEAiBzR3JGEf9PITYuiXTx+vx9gXji5idGsVog9wRUbY98wwIgVVeYNQQb +x+RN2wYp3kmm8iswUOrqiI6J4PSzT8CYP8Q= +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/poly1305test.c b/Libraries/libressl/tests/poly1305test.c new file mode 100644 index 000000000..3f9af0db0 --- /dev/null +++ b/Libraries/libressl/tests/poly1305test.c @@ -0,0 +1,169 @@ +/* $OpenBSD: poly1305test.c,v 1.3 2018/07/17 17:06:49 tb Exp $ */ +/* + * Public Domain poly1305 from Andrew Moon + * Based on poly1305-donna.c from: + * https://github.com/floodyberry/poly1305-donna + */ + +#include + +#include + +void poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, + const unsigned char key[32]); + +int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]); +int poly1305_power_on_self_test(void); + +void +poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, +const unsigned char key[32]) { + poly1305_context ctx; + CRYPTO_poly1305_init(&ctx, key); + CRYPTO_poly1305_update(&ctx, m, bytes); + CRYPTO_poly1305_finish(&ctx, mac); +} + +int +poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]) +{ + size_t i; + unsigned int dif = 0; + for (i = 0; i < 16; i++) + dif |= (mac1[i] ^ mac2[i]); + dif = (dif - 1) >> ((sizeof(unsigned int) * 8) - 1); + return (dif & 1); +} + +/* test a few basic operations */ +int +poly1305_power_on_self_test(void) +{ + /* example from nacl */ + static const unsigned char nacl_key[32] = { + 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91, + 0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25, + 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65, + 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80, + }; + + static const unsigned char nacl_msg[131] = { + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, + 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, + 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, + 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, + 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, + 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, + 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, + 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, + 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, + 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, + 0xe3, 0x55, 0xa5 + }; + + static const unsigned char nacl_mac[16] = { + 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9 + }; + + /* generates a final value of (2^130 - 2) == 3 */ + static const unsigned char wrap_key[32] = { + 0x02, 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 wrap_msg[16] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + static const unsigned char wrap_mac[16] = { + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + /* + mac of the macs of messages of length 0 to 256, where the key and messages + have all their values set to the length + */ + static const unsigned char total_key[32] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + static const unsigned char total_mac[16] = { + 0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd, + 0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39 + }; + + poly1305_context ctx; + poly1305_context total_ctx; + unsigned char all_key[32]; + unsigned char all_msg[256]; + unsigned char mac[16]; + size_t i, j; + int result = 1; + + for (i = 0; i < sizeof(mac); i++) + mac[i] = 0; + poly1305_auth(mac, nacl_msg, sizeof(nacl_msg), nacl_key); + result &= poly1305_verify(nacl_mac, mac); + + for (i = 0; i < sizeof(mac); i++) + mac[i] = 0; + CRYPTO_poly1305_init(&ctx, nacl_key); + CRYPTO_poly1305_update(&ctx, nacl_msg + 0, 32); + CRYPTO_poly1305_update(&ctx, nacl_msg + 32, 64); + CRYPTO_poly1305_update(&ctx, nacl_msg + 96, 16); + CRYPTO_poly1305_update(&ctx, nacl_msg + 112, 8); + CRYPTO_poly1305_update(&ctx, nacl_msg + 120, 4); + CRYPTO_poly1305_update(&ctx, nacl_msg + 124, 2); + CRYPTO_poly1305_update(&ctx, nacl_msg + 126, 1); + CRYPTO_poly1305_update(&ctx, nacl_msg + 127, 1); + CRYPTO_poly1305_update(&ctx, nacl_msg + 128, 1); + CRYPTO_poly1305_update(&ctx, nacl_msg + 129, 1); + CRYPTO_poly1305_update(&ctx, nacl_msg + 130, 1); + CRYPTO_poly1305_finish(&ctx, mac); + result &= poly1305_verify(nacl_mac, mac); + + for (i = 0; i < sizeof(mac); i++) + mac[i] = 0; + poly1305_auth(mac, wrap_msg, sizeof(wrap_msg), wrap_key); + result &= poly1305_verify(wrap_mac, mac); + + CRYPTO_poly1305_init(&total_ctx, total_key); + for (i = 0; i < 256; i++) { + /* set key and message to 'i,i,i..' */ + for (j = 0; j < sizeof(all_key); j++) + all_key[j] = i; + for (j = 0; j < i; j++) + all_msg[j] = i; + poly1305_auth(mac, all_msg, i, all_key); + CRYPTO_poly1305_update(&total_ctx, mac, 16); + } + CRYPTO_poly1305_finish(&total_ctx, mac); + result &= poly1305_verify(total_mac, mac); + + return result; +} + +int +main(int argc, char **argv) +{ + if (!poly1305_power_on_self_test()) { + fprintf(stderr, "One or more self tests failed!\n"); + return 1; + } + + return 0; +} diff --git a/Libraries/libressl/tests/pq_expected.txt b/Libraries/libressl/tests/pq_expected.txt new file mode 100644 index 000000000..c59d6cd83 --- /dev/null +++ b/Libraries/libressl/tests/pq_expected.txt @@ -0,0 +1,3 @@ +item 6966726167696c69 +item 7374696365787069 +item 737570657263616c diff --git a/Libraries/libressl/tests/pq_test.bat b/Libraries/libressl/tests/pq_test.bat new file mode 100644 index 000000000..15e0c51e9 --- /dev/null +++ b/Libraries/libressl/tests/pq_test.bat @@ -0,0 +1,15 @@ +@echo off +setlocal enabledelayedexpansion +REM pq_test.bat + +set pq_test_bin=%1 +set pq_test_bin=%pq_test_bin:/=\% +if not exist %pq_test_bin% exit /b 1 + +set pq_output=pq_output.txt +if exist %pq_output% del %pq_output% + +%pq_test_bin% > %pq_output% +fc /b %pq_output% %srcdir%\pq_expected.txt + +endlocal diff --git a/Libraries/libressl/tests/pq_test.c b/Libraries/libressl/tests/pq_test.c new file mode 100644 index 000000000..a078ba536 --- /dev/null +++ b/Libraries/libressl/tests/pq_test.c @@ -0,0 +1,118 @@ +/* crypto/pqueue/pq_test.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include +#include "pqueue.h" + +/* remember to change expected.txt if you change these values */ +unsigned char prio1[8] = "supercal"; +unsigned char prio2[8] = "ifragili"; +unsigned char prio3[8] = "sticexpi"; + +static void +pqueue_print(pqueue pq) +{ + pitem *iter, *item; + + iter = pqueue_iterator(pq); + for (item = pqueue_next(&iter); item != NULL; + item = pqueue_next(&iter)) { + printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n", + item->priority[0], item->priority[1], + item->priority[2], item->priority[3], + item->priority[4], item->priority[5], + item->priority[6], item->priority[7]); + } +} + +int +main(void) +{ + pitem *item; + pqueue pq; + + pq = pqueue_new(); + + item = pitem_new(prio3, NULL); + pqueue_insert(pq, item); + + item = pitem_new(prio1, NULL); + pqueue_insert(pq, item); + + item = pitem_new(prio2, NULL); + pqueue_insert(pq, item); + + item = pqueue_find(pq, prio1); + fprintf(stderr, "found %p\n", item->priority); + + item = pqueue_find(pq, prio2); + fprintf(stderr, "found %p\n", item->priority); + + item = pqueue_find(pq, prio3); + fprintf(stderr, "found %p\n", item ? item->priority: 0); + + pqueue_print(pq); + + for (item = pqueue_pop(pq); item != NULL; item = pqueue_pop(pq)) + pitem_free(item); + + pqueue_free(pq); + return 0; +} diff --git a/Libraries/libressl/tests/pq_test.sh b/Libraries/libressl/tests/pq_test.sh new file mode 100644 index 000000000..ab87bc7f1 --- /dev/null +++ b/Libraries/libressl/tests/pq_test.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e +TEST=./pq_test +if [ -e ./pq_test.exe ]; then + TEST=./pq_test.exe +fi +$TEST | diff -b $srcdir/pq_expected.txt - diff --git a/Libraries/libressl/tests/quictest.bat b/Libraries/libressl/tests/quictest.bat new file mode 100644 index 000000000..1d48884c2 --- /dev/null +++ b/Libraries/libressl/tests/quictest.bat @@ -0,0 +1,14 @@ +@echo off +setlocal enabledelayedexpansion +REM quictest.bat + +set quictest_bin=%1 +set quictest_bin=%quictest_bin:/=\% +if not exist %quictest_bin% exit /b 1 + +%quictest_bin% %srcdir%\server.pem %srcdir%\server.pem %srcdir%\ca.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + +endlocal diff --git a/Libraries/libressl/tests/quictest.c b/Libraries/libressl/tests/quictest.c new file mode 100644 index 000000000..cdd4b2387 --- /dev/null +++ b/Libraries/libressl/tests/quictest.c @@ -0,0 +1,339 @@ +/* $OpenBSD: quictest.c,v 1.1 2022/08/27 09:16:29 jsing Exp $ */ +/* + * Copyright (c) 2020, 2021, 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +const char *server_ca_file; +const char *server_cert_file; +const char *server_key_file; + +int debug = 0; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +struct quic_data { + enum ssl_encryption_level_t rlevel; + enum ssl_encryption_level_t wlevel; + BIO *rbio; + BIO *wbio; +}; + +static int +quic_set_read_secret(SSL *ssl, enum ssl_encryption_level_t level, + const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len) +{ + struct quic_data *qd = SSL_get_app_data(ssl); + + qd->rlevel = level; + + return 1; +} + +static int +quic_set_write_secret(SSL *ssl, enum ssl_encryption_level_t level, + const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len) +{ + struct quic_data *qd = SSL_get_app_data(ssl); + + qd->wlevel = level; + + return 1; +} + +static int +quic_read_handshake_data(SSL *ssl) +{ + struct quic_data *qd = SSL_get_app_data(ssl); + uint8_t buf[2048]; + int ret; + + if ((ret = BIO_read(qd->rbio, buf, sizeof(buf))) > 0) { + if (debug > 1) { + fprintf(stderr, "== quic_read_handshake_data ==\n"); + hexdump(buf, ret); + } + if (!SSL_provide_quic_data(ssl, qd->rlevel, buf, ret)) + return -1; + } + + return 1; +} + +static int +quic_add_handshake_data(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *data, size_t len) +{ + struct quic_data *qd = SSL_get_app_data(ssl); + int ret; + + if (debug > 1) { + fprintf(stderr, "== quic_add_handshake_data\n"); + hexdump(data, len); + } + + if ((ret = BIO_write(qd->wbio, data, len)) <= 0) + return 0; + + return (size_t)ret == len; +} + +static int +quic_flush_flight(SSL *ssl) +{ + return 1; +} + +static int +quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert) +{ + return 1; +} + +const SSL_QUIC_METHOD quic_method = { + .set_read_secret = quic_set_read_secret, + .set_write_secret = quic_set_write_secret, + .add_handshake_data = quic_add_handshake_data, + .flush_flight = quic_flush_flight, + .send_alert = quic_send_alert, +}; + +static SSL * +quic_client(struct quic_data *data) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) + errx(1, "client context"); + + if (!SSL_CTX_set_quic_method(ssl_ctx, &quic_method)) { + fprintf(stderr, "FAIL: Failed to set QUIC method\n"); + goto failure; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "client ssl"); + + SSL_set_connect_state(ssl); + SSL_set_app_data(ssl, data); + + failure: + SSL_CTX_free(ssl_ctx); + + return ssl; +} + +static SSL * +quic_server(struct quic_data *data) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) + errx(1, "server context"); + + SSL_CTX_set_dh_auto(ssl_ctx, 2); + + if (SSL_CTX_use_certificate_file(ssl_ctx, server_cert_file, + SSL_FILETYPE_PEM) != 1) { + fprintf(stderr, "FAIL: Failed to load server certificate\n"); + goto failure; + } + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key_file, + SSL_FILETYPE_PEM) != 1) { + fprintf(stderr, "FAIL: Failed to load server private key\n"); + goto failure; + } + + if (!SSL_CTX_set_quic_method(ssl_ctx, &quic_method)) { + fprintf(stderr, "FAIL: Failed to set QUIC method\n"); + goto failure; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "server ssl"); + + SSL_set_accept_state(ssl); + SSL_set_app_data(ssl, data); + + failure: + SSL_CTX_free(ssl_ctx); + + return ssl; +} + +static int +ssl_error(SSL *ssl, const char *name, const char *desc, int ssl_ret) +{ + int ssl_err; + + ssl_err = SSL_get_error(ssl, ssl_ret); + + if (ssl_err == SSL_ERROR_WANT_READ) { + if (quic_read_handshake_data(ssl) < 0) + return 0; + return 1; + } else if (ssl_err == SSL_ERROR_WANT_WRITE) { + return 1; + } else if (ssl_err == SSL_ERROR_SYSCALL && errno == 0) { + /* Yup, this is apparently a thing... */ + } else { + fprintf(stderr, "FAIL: %s %s failed - ssl err = %d, errno = %d\n", + name, desc, ssl_err, errno); + ERR_print_errors_fp(stderr); + return 0; + } + + return 1; +} + +static int +do_handshake(SSL *ssl, const char *name, int *done) +{ + int ssl_ret; + + if ((ssl_ret = SSL_do_handshake(ssl)) == 1) { + fprintf(stderr, "INFO: %s handshake done\n", name); + *done = 1; + return 1; + } + + return ssl_error(ssl, name, "handshake", ssl_ret); +} + +typedef int (*ssl_func)(SSL *ssl, const char *name, int *done); + +static int +do_client_server_loop(SSL *client, ssl_func client_func, SSL *server, + ssl_func server_func) +{ + int client_done = 0, server_done = 0; + int i = 0; + + do { + if (!client_done) { + if (debug) + fprintf(stderr, "DEBUG: client loop\n"); + if (!client_func(client, "client", &client_done)) + return 0; + } + if (!server_done) { + if (debug) + fprintf(stderr, "DEBUG: server loop\n"); + if (!server_func(server, "server", &server_done)) + return 0; + } + } while (i++ < 100 && (!client_done || !server_done)); + + if (!client_done || !server_done) + fprintf(stderr, "FAIL: gave up\n"); + + return client_done && server_done; +} + +static int +quictest(void) +{ + struct quic_data *client_data = NULL, *server_data = NULL; + BIO *client_wbio = NULL, *server_wbio = NULL; + SSL *client = NULL, *server = NULL; + int failed = 1; + + if ((client_wbio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (BIO_set_mem_eof_return(client_wbio, -1) <= 0) + goto failure; + + if ((server_wbio = BIO_new(BIO_s_mem())) == NULL) + goto failure; + if (BIO_set_mem_eof_return(server_wbio, -1) <= 0) + goto failure; + + if ((client_data = calloc(1, sizeof(*client_data))) == NULL) + goto failure; + + client_data->rbio = server_wbio; + client_data->wbio = client_wbio; + + if ((client = quic_client(client_data)) == NULL) + goto failure; + + if ((server_data = calloc(1, sizeof(*server_data))) == NULL) + goto failure; + + server_data->rbio = client_wbio; + server_data->wbio = server_wbio; + + if ((server = quic_server(server_data)) == NULL) + goto failure; + + if (!do_client_server_loop(client, do_handshake, server, do_handshake)) { + fprintf(stderr, "FAIL: client and server handshake failed\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + fprintf(stderr, "INFO: Done!\n"); + + failed = 0; + + failure: + BIO_free(client_wbio); + BIO_free(server_wbio); + + free(client_data); + free(server_data); + + SSL_free(client); + SSL_free(server); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + if (argc != 4) { + fprintf(stderr, "usage: %s keyfile certfile cafile\n", + argv[0]); + exit(1); + } + + server_key_file = argv[1]; + server_cert_file = argv[2]; + server_ca_file = argv[3]; + + failed |= quictest(); + + return failed; +} diff --git a/Libraries/libressl/tests/quictest.sh b/Libraries/libressl/tests/quictest.sh new file mode 100644 index 000000000..cc1982f64 --- /dev/null +++ b/Libraries/libressl/tests/quictest.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +quictest_bin=./quictest +if [ -e ./quictest.exe ]; then + quictest_bin=./quictest.exe +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +$quictest_bin $srcdir/server.pem $srcdir/server.pem $srcdir/ca.pem diff --git a/Libraries/libressl/tests/randtest.c b/Libraries/libressl/tests/randtest.c new file mode 100644 index 000000000..d0f02ad22 --- /dev/null +++ b/Libraries/libressl/tests/randtest.c @@ -0,0 +1,204 @@ +/* $OpenBSD: randtest.c,v 1.3 2018/07/17 17:06:49 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#undef LIBRESSL_INTERNAL /* Needed to get RAND_pseudo_bytes(). */ +#include + +/* some FIPS 140-1 random number test */ +/* some simple tests */ + +int main(int argc,char **argv) + { + unsigned char buf[2500]; + int i,j,k,s,sign,nsign,err=0; + unsigned long n1; + unsigned long n2[16]; + unsigned long runs[2][34]; + /*double d; */ + long d; + + i = RAND_pseudo_bytes(buf,2500); + if (i < 0) + { + printf ("init failed, the rand method is not properly installed\n"); + err++; + goto err; + } + + n1=0; + for (i=0; i<16; i++) n2[i]=0; + for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0; + + /* test 1 and 2 */ + sign=0; + nsign=0; + for (i=0; i<2500; i++) + { + j=buf[i]; + + n2[j&0x0f]++; + n2[(j>>4)&0x0f]++; + + for (k=0; k<8; k++) + { + s=(j&0x01); + if (s == sign) + nsign++; + else + { + if (nsign > 34) nsign=34; + if (nsign != 0) + { + runs[sign][nsign-1]++; + if (nsign > 6) + runs[sign][5]++; + } + sign=s; + nsign=1; + } + + if (s) n1++; + j>>=1; + } + } + if (nsign > 34) nsign=34; + if (nsign != 0) runs[sign][nsign-1]++; + + /* test 1 */ + if (!((9654 < n1) && (n1 < 10346))) + { + printf("test 1 failed, X=%lu\n",n1); + err++; + } + printf("test 1 done\n"); + + /* test 2 */ + d=0; + for (i=0; i<16; i++) + d+=n2[i]*n2[i]; + d=(d*8)/25-500000; + if (!((103 < d) && (d < 5740))) + { + printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L); + err++; + } + printf("test 2 done\n"); + + /* test 3 */ + for (i=0; i<2; i++) + { + if (!((2267 < runs[i][0]) && (runs[i][0] < 2733))) + { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i,1,runs[i][0]); + err++; + } + if (!((1079 < runs[i][1]) && (runs[i][1] < 1421))) + { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i,2,runs[i][1]); + err++; + } + if (!(( 502 < runs[i][2]) && (runs[i][2] < 748))) + { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i,3,runs[i][2]); + err++; + } + if (!(( 223 < runs[i][3]) && (runs[i][3] < 402))) + { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i,4,runs[i][3]); + err++; + } + if (!(( 90 < runs[i][4]) && (runs[i][4] < 223))) + { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i,5,runs[i][4]); + err++; + } + if (!(( 90 < runs[i][5]) && (runs[i][5] < 223))) + { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i,6,runs[i][5]); + err++; + } + } + printf("test 3 done\n"); + + /* test 4 */ + if (runs[0][33] != 0) + { + printf("test 4 failed, bit=%d run=%d num=%lu\n", + 0,34,runs[0][33]); + err++; + } + if (runs[1][33] != 0) + { + printf("test 4 failed, bit=%d run=%d num=%lu\n", + 1,34,runs[1][33]); + err++; + } + printf("test 4 done\n"); + err: + err=((err)?1:0); + exit(err); + } diff --git a/Libraries/libressl/tests/rc2_test.c b/Libraries/libressl/tests/rc2_test.c new file mode 100644 index 000000000..2e503c5c8 --- /dev/null +++ b/Libraries/libressl/tests/rc2_test.c @@ -0,0 +1,917 @@ +/* $OpenBSD: rc2_test.c,v 1.6 2022/11/09 12:13:08 joshua Exp $ */ +/* + * Copyright (c) 2022 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +struct rc2_test { + const int mode; + const uint8_t key[64]; + const int key_len; + const int key_bits; + const uint8_t iv[64]; + const int iv_len; + const uint8_t in[64]; + const int in_len; + const uint8_t out[64]; + const int out_len; + const int padding; +}; + +static const struct rc2_test rc2_tests[] = { + /* ECB (Test vectors from RFC 2268) */ + { + .mode = NID_rc2_ecb, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .key_bits = 63, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .key_len = 8, + .key_bits = 64, + .in = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .in_len = 8, + .out = { + 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .key_bits = 64, + .in = { + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .in_len = 8, + .out = { + 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x88, + }, + .key_len = 1, + .key_bits = 64, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, + }, + .key_len = 7, + .key_bits = 64, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2, + }, + .key_len = 16, + .key_bits = 64, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2, + }, + .key_len = 16, + .key_bits = 128, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2, + 0x16, 0xf8, 0x0a, 0x6f, 0x85, 0x92, 0x05, 0x84, + 0xc4, 0x2f, 0xce, 0xb0, 0xbe, 0x25, 0x5d, 0xaf, + 0x1e, + }, + .key_len = 33, + .key_bits = 129, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x5b, 0x78, 0xd3, 0xa4, 0x3d, 0xff, 0xf1, 0xf1, + }, + .out_len = 8, + }, + + /* ECB (Test vectors from http://websites.umich.edu/~x509/ssleay/rrc2.html) */ + { + .mode = NID_rc2_ecb, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 16, + .key_bits = 1024, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x1c, 0x19, 0x8a, 0x83, 0x8d, 0xf0, 0x28, 0xb7, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .key_len = 16, + .key_bits = 1024, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 16, + .key_bits = 1024, + .in = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .in_len = 8, + .out = { + 0x13, 0xdb, 0x35, 0x17, 0xd3, 0x21, 0x86, 0x9e, + }, + .out_len = 8, + }, + { + .mode = NID_rc2_ecb, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 1024, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 8, + .out = { + 0x50, 0xdc, 0x01, 0x62, 0xbd, 0x75, 0x7f, 0x31, + }, + .out_len = 8, + }, + + /* CBC (generated using https://github.com/joshuasing/libressl-test-gen) */ + { + .mode = NID_rc2_cbc, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .key_bits = 64, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff, + 0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b, + 0x52, 0x8f, 0xc8, 0x47, 0x2b, 0x66, 0xf9, 0x70, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in_len = 16, + .out = { + 0x8b, 0x11, 0x08, 0x1c, 0xf0, 0xa0, 0x86, 0xe9, + 0x60, 0x57, 0x69, 0x5d, 0xdd, 0x42, 0x38, 0xe3, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_cbc, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b, + 0x29, 0xf1, 0x7a, 0xd2, 0x16, 0xa0, 0xb2, 0xc6, + 0xd1, 0xa2, 0x31, 0xbe, 0xa3, 0x94, 0xc6, 0xb0, + 0x81, 0x22, 0x27, 0x17, 0x5b, 0xd4, 0x6d, 0x29, + }, + .out_len = 32, + }, + + /* CFB64 (generated using https://github.com/joshuasing/libressl-test-gen) */ + { + .mode = NID_rc2_cfb64, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .key_bits = 64, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff, + 0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b, + 0x52, 0x8f, 0xc8, 0x47, 0x2b, 0x66, 0xf9, 0x70, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in_len = 16, + .out = { + 0x9c, 0x4a, 0xfc, 0x6e, 0xfa, 0x76, 0x9a, 0x2c, + 0xeb, 0xdf, 0x25, 0xb0, 0x15, 0x8b, 0x6a, 0x2a, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_cfb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0x8b, 0x10, 0x0a, 0x1f, 0xf4, 0xa5, 0x80, 0xee, + 0x94, 0x4d, 0xc3, 0xcd, 0x26, 0x79, 0x81, 0xc0, + 0xe9, 0x3e, 0x20, 0x85, 0x11, 0x71, 0x61, 0x2a, + 0x1d, 0x4c, 0x8a, 0xe2, 0xb7, 0x0a, 0xa8, 0xcf, + }, + .out_len = 32, + }, + + /* OFB64 (generated using https://github.com/joshuasing/libressl-test-gen) */ + { + .mode = NID_rc2_ofb64, + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .key_bits = 64, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff, + 0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .in_len = 16, + .out = { + 0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b, + 0x52, 0x8f, 0xc8, 0x47, 0x2b, 0x66, 0xf9, 0x70, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .in_len = 16, + .out = { + 0x9c, 0x4a, 0xfc, 0x6e, 0xfa, 0x76, 0x9a, 0x2c, + 0x5a, 0x86, 0xc2, 0x4c, 0x27, 0x6b, 0xf7, 0x7f, + }, + .out_len = 16, + }, + { + .mode = NID_rc2_ofb64, + .key = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }, + .key_len = 16, + .key_bits = 128, + .iv = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .iv_len = 8, + .in = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + .in_len = 32, + .out = { + 0x8b, 0x10, 0x0a, 0x1f, 0xf4, 0xa5, 0x80, 0xee, + 0xfa, 0x1d, 0x1a, 0x7c, 0xb2, 0x93, 0x00, 0x9d, + 0x36, 0xa1, 0xff, 0x3a, 0x77, 0x1d, 0x00, 0x9b, + 0x20, 0xde, 0x5f, 0x93, 0xcc, 0x3e, 0x51, 0xaa, + }, + .out_len = 32, + }, +}; + +#define N_RC2_TESTS (sizeof(rc2_tests) / sizeof(rc2_tests[0])) + +static int +rc2_ecb_test(size_t test_number, const struct rc2_test *rt) +{ + RC2_KEY key; + uint8_t out[8]; + + /* Encryption */ + memset(out, 0, sizeof(out)); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_ecb_encrypt(rt->in, out, &key, 1); + + if (memcmp(rt->out, out, rt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_rc2_ecb, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_ecb_encrypt(rt->out, out, &key, 0); + + if (memcmp(rt->in, out, rt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_rc2_ecb, test_number); + return 0; + } + + return 1; +} + +static int +rc2_cbc_test(size_t test_number, const struct rc2_test *rt) +{ + RC2_KEY key; + uint8_t out[512]; + uint8_t iv[64]; + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, rt->iv, rt->iv_len); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_cbc_encrypt(rt->in, out, rt->in_len, &key, iv, 1); + + if (memcmp(rt->out, out, rt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_rc2_cbc, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, rt->iv, rt->iv_len); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_cbc_encrypt(rt->out, out, rt->out_len, &key, iv, 0); + + if (memcmp(rt->in, out, rt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_rc2_cbc, test_number); + return 0; + } + + return 1; +} + +static int +rc2_cfb64_test(size_t test_number, const struct rc2_test *rt) +{ + RC2_KEY key; + uint8_t out[512]; + uint8_t iv[64]; + int remainder = 0; + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, rt->iv, rt->iv_len); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_cfb64_encrypt(rt->in, out, rt->in_len * 8, &key, iv, &remainder, 1); + + if (memcmp(rt->out, out, rt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_rc2_cbc, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, rt->iv, rt->iv_len); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_cfb64_encrypt(rt->out, out, rt->out_len, &key, iv, &remainder, 0); + + if (memcmp(rt->in, out, rt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_rc2_cbc, test_number); + return 0; + } + + return 1; +} + +static int +rc2_ofb64_test(size_t test_number, const struct rc2_test *rt) +{ + RC2_KEY key; + uint8_t out[512]; + uint8_t iv[64]; + int remainder = 0; + + /* Encryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, rt->iv, rt->iv_len); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_ofb64_encrypt(rt->in, out, rt->in_len, &key, iv, &remainder); + + if (memcmp(rt->out, out, rt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", + SN_rc2_cbc, test_number); + return 0; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + memcpy(iv, rt->iv, rt->iv_len); + RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); + RC2_ofb64_encrypt(rt->out, out, rt->out_len, &key, iv, &remainder); + + if (memcmp(rt->in, out, rt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", + SN_rc2_cbc, test_number); + return 0; + } + + return 1; +} + +static int +rc2_evp_test(size_t test_number, const struct rc2_test *rt, const char *label, + const EVP_CIPHER *cipher) +{ + EVP_CIPHER_CTX *ctx; + uint8_t out[512]; + int in_len, out_len, total_len; + int i; + int success = 0; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_new failed\n", + label, test_number); + goto failed; + } + + /* EVP encryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_EncryptInit(ctx, cipher, NULL, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n", + label, test_number); + goto failed; + } + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, + rt->key_bits, NULL) <= 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_ctrl failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_key_length(ctx, rt->key_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_key_length failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_padding(ctx, rt->padding)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n", + label, test_number); + goto failed; + } + + if (!EVP_EncryptInit(ctx, NULL, rt->key, rt->iv)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n", + label, test_number); + goto failed; + } + + for (i = 0; i < rt->in_len;) { + in_len = arc4random_uniform(rt->in_len / 2); + if (in_len > rt->in_len - i) + in_len = rt->in_len - i; + + if (!EVP_EncryptUpdate(ctx, out + total_len, &out_len, + rt->in + i, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_EncryptUpdate failed\n", + label, test_number); + goto failed; + } + + i += in_len; + total_len += out_len; + } + + if (!EVP_EncryptFinal_ex(ctx, out + out_len, &out_len)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptFinal_ex failed\n", + label, test_number); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n", + label, test_number); + goto failed; + } + + if (total_len != rt->out_len) { + fprintf(stderr, + "FAIL (%s:%zu): EVP encryption length mismatch\n", + label, test_number); + goto failed; + } + + if (memcmp(rt->out, out, rt->out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP encryption mismatch\n", + label, test_number); + goto failed; + } + + /* EVP decryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_DecryptInit(ctx, cipher, NULL, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n", + label, test_number); + goto failed; + } + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, + rt->key_bits, NULL) <= 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_ctrl failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_key_length(ctx, rt->key_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_key_length failed\n", + label, test_number); + goto failed; + } + + if (!EVP_CIPHER_CTX_set_padding(ctx, rt->padding)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n", + label, test_number); + goto failed; + } + + if (!EVP_DecryptInit(ctx, NULL, rt->key, rt->iv)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n", + label, test_number); + goto failed; + } + + for (i = 0; i < rt->out_len;) { + in_len = arc4random_uniform(rt->out_len / 2); + if (in_len > rt->out_len - i) + in_len = rt->out_len - i; + + if (!EVP_DecryptUpdate(ctx, out + total_len, &out_len, + rt->out + i, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DecryptUpdate failed\n", + label, test_number); + goto failed; + } + + i += in_len; + total_len += out_len; + } + + if (!EVP_DecryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptFinal_ex failed\n", + label, test_number); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n", + label, test_number); + goto failed; + } + + if (total_len != rt->in_len) { + fprintf(stderr, + "FAIL (%s:%zu): EVP decryption length mismatch\n", + label, test_number); + goto failed; + } + + if (memcmp(rt->in, out, rt->in_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP decryption mismatch\n", + label, test_number); + goto failed; + } + + success = 1; + + failed: + EVP_CIPHER_CTX_free(ctx); + return success; +} + +static int +rc2_test(void) +{ + const struct rc2_test *rt; + const char *label; + const EVP_CIPHER *cipher; + size_t i; + int failed = 1; + + for (i = 0; i < N_RC2_TESTS; i++) { + rt = &rc2_tests[i]; + switch (rt->mode) { + case NID_rc2_ecb: + label = SN_rc2_ecb; + cipher = EVP_rc2_ecb(); + if (!rc2_ecb_test(i, rt)) + goto failed; + break; + case NID_rc2_cbc: + label = SN_rc2_cbc; + cipher = EVP_rc2_cbc(); + if (!rc2_cbc_test(i, rt)) + goto failed; + break; + case NID_rc2_cfb64: + label = SN_rc2_cfb64; + cipher = EVP_rc2_cfb64(); + if (!rc2_cfb64_test(i, rt)) + goto failed; + break; + case NID_rc2_ofb64: + label = SN_rc2_ofb64; + cipher = EVP_rc2_ofb(); + if (!rc2_ofb64_test(i, rt)) + goto failed; + break; + default: + fprintf(stderr, "FAIL: unknown mode (%d)\n", + rt->mode); + goto failed; + } + + if (!rc2_evp_test(i, rt, label, cipher)) + goto failed; + } + + failed = 0; + + failed: + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= rc2_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/rc4_test.c b/Libraries/libressl/tests/rc4_test.c new file mode 100644 index 000000000..fc4c65ff2 --- /dev/null +++ b/Libraries/libressl/tests/rc4_test.c @@ -0,0 +1,479 @@ +/* $OpenBSD: rc4_test.c,v 1.6 2022/11/09 12:10:17 joshua Exp $ */ +/* + * Copyright (c) 2022 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +struct rc4_test { + const uint8_t key[32]; + const int key_len; + const int len; + const uint8_t in[512]; + const uint8_t out[512]; +}; + +static const struct rc4_test rc4_tests[] = { + /* + * Test vectors from RFC 6229, with 40 and 128-bit keys. + * Note that this only uses the first 32 bytes of each test vector due + * to stream offsets. + */ + { + .key = { + 0x01, 0x02, 0x03, 0x04, 0x05, + }, + .key_len = 5, + .len = 32, + .in = { + 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, 0x00, + }, + .out = { + 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27, + 0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8, + 0x69, 0x82, 0x94, 0x4f, 0x18, 0xfc, 0x82, 0xd5, + 0x89, 0xc4, 0x03, 0xa4, 0x7a, 0x0d, 0x09, 0x19, + }, + }, + { + .key = { + 0x83, 0x32, 0x22, 0x77, 0x2a, + }, + .key_len = 5, + .len = 32, + .in = { + 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, 0x00, + }, + .out = { + 0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a, + 0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda, + 0x20, 0xf0, 0x60, 0xc2, 0xf2, 0xe5, 0x12, 0x65, + 0x01, 0xd3, 0xd4, 0xfe, 0xa1, 0x0d, 0x5f, 0xc0, + }, + }, + { + .key = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + }, + .key_len = 16, + .len = 32, + .in = { + 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, 0x00, + }, + .out = { + 0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7, + 0xb2, 0x93, 0x28, 0x99, 0xcd, 0xe4, 0x1b, 0x97, + 0x52, 0x48, 0xc4, 0x95, 0x90, 0x14, 0x12, 0x6a, + 0x6e, 0x8a, 0x84, 0xf1, 0x1d, 0x1a, 0x9e, 0x1c, + }, + }, + { + .key = { + 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37, + 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a, + }, + .key_len = 16, + .len = 32, + .in = { + 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, 0x00, + }, + .out = { + 0x72, 0x0c, 0x94, 0xb6, 0x3e, 0xdf, 0x44, 0xe1, + 0x31, 0xd9, 0x50, 0xca, 0x21, 0x1a, 0x5a, 0x30, + 0xc3, 0x66, 0xfd, 0xea, 0xcf, 0x9c, 0xa8, 0x04, + 0x36, 0xbe, 0x7c, 0x35, 0x84, 0x24, 0xd2, 0x0b, + }, + }, + + /* + * Test vectors from the original cypherpunk posting of ARC4: + * https://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0?pli=1 + */ + { + .key = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }, + .key_len = 8, + .len = 8, + .in = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }, + .out = { + 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96, + }, + }, + { + .key = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }, + .key_len = 8, + .len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .out = { + 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79, + }, + }, + { + .key = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .key_len = 8, + .len = 8, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .out = { + 0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a, + }, + }, + { + .key = { + 0xef, 0x01, 0x23, 0x45, + }, + .key_len = 4, + .len = 10, + .in = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + }, + .out = { + 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, + 0xbd, 0x61, + }, + }, + { + .key = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }, + .key_len = 8, + .len = 512, + .in = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + }, + .out = { + 0x75, 0x95, 0xc3, 0xe6, 0x11, 0x4a, 0x09, 0x78, + 0x0c, 0x4a, 0xd4, 0x52, 0x33, 0x8e, 0x1f, 0xfd, + 0x9a, 0x1b, 0xe9, 0x49, 0x8f, 0x81, 0x3d, 0x76, + 0x53, 0x34, 0x49, 0xb6, 0x77, 0x8d, 0xca, 0xd8, + 0xc7, 0x8a, 0x8d, 0x2b, 0xa9, 0xac, 0x66, 0x08, + 0x5d, 0x0e, 0x53, 0xd5, 0x9c, 0x26, 0xc2, 0xd1, + 0xc4, 0x90, 0xc1, 0xeb, 0xbe, 0x0c, 0xe6, 0x6d, + 0x1b, 0x6b, 0x1b, 0x13, 0xb6, 0xb9, 0x19, 0xb8, + 0x47, 0xc2, 0x5a, 0x91, 0x44, 0x7a, 0x95, 0xe7, + 0x5e, 0x4e, 0xf1, 0x67, 0x79, 0xcd, 0xe8, 0xbf, + 0x0a, 0x95, 0x85, 0x0e, 0x32, 0xaf, 0x96, 0x89, + 0x44, 0x4f, 0xd3, 0x77, 0x10, 0x8f, 0x98, 0xfd, + 0xcb, 0xd4, 0xe7, 0x26, 0x56, 0x75, 0x00, 0x99, + 0x0b, 0xcc, 0x7e, 0x0c, 0xa3, 0xc4, 0xaa, 0xa3, + 0x04, 0xa3, 0x87, 0xd2, 0x0f, 0x3b, 0x8f, 0xbb, + 0xcd, 0x42, 0xa1, 0xbd, 0x31, 0x1d, 0x7a, 0x43, + 0x03, 0xdd, 0xa5, 0xab, 0x07, 0x88, 0x96, 0xae, + 0x80, 0xc1, 0x8b, 0x0a, 0xf6, 0x6d, 0xff, 0x31, + 0x96, 0x16, 0xeb, 0x78, 0x4e, 0x49, 0x5a, 0xd2, + 0xce, 0x90, 0xd7, 0xf7, 0x72, 0xa8, 0x17, 0x47, + 0xb6, 0x5f, 0x62, 0x09, 0x3b, 0x1e, 0x0d, 0xb9, + 0xe5, 0xba, 0x53, 0x2f, 0xaf, 0xec, 0x47, 0x50, + 0x83, 0x23, 0xe6, 0x71, 0x32, 0x7d, 0xf9, 0x44, + 0x44, 0x32, 0xcb, 0x73, 0x67, 0xce, 0xc8, 0x2f, + 0x5d, 0x44, 0xc0, 0xd0, 0x0b, 0x67, 0xd6, 0x50, + 0xa0, 0x75, 0xcd, 0x4b, 0x70, 0xde, 0xdd, 0x77, + 0xeb, 0x9b, 0x10, 0x23, 0x1b, 0x6b, 0x5b, 0x74, + 0x13, 0x47, 0x39, 0x6d, 0x62, 0x89, 0x74, 0x21, + 0xd4, 0x3d, 0xf9, 0xb4, 0x2e, 0x44, 0x6e, 0x35, + 0x8e, 0x9c, 0x11, 0xa9, 0xb2, 0x18, 0x4e, 0xcb, + 0xef, 0x0c, 0xd8, 0xe7, 0xa8, 0x77, 0xef, 0x96, + 0x8f, 0x13, 0x90, 0xec, 0x9b, 0x3d, 0x35, 0xa5, + 0x58, 0x5c, 0xb0, 0x09, 0x29, 0x0e, 0x2f, 0xcd, + 0xe7, 0xb5, 0xec, 0x66, 0xd9, 0x08, 0x4b, 0xe4, + 0x40, 0x55, 0xa6, 0x19, 0xd9, 0xdd, 0x7f, 0xc3, + 0x16, 0x6f, 0x94, 0x87, 0xf7, 0xcb, 0x27, 0x29, + 0x12, 0x42, 0x64, 0x45, 0x99, 0x85, 0x14, 0xc1, + 0x5d, 0x53, 0xa1, 0x8c, 0x86, 0x4c, 0xe3, 0xa2, + 0xb7, 0x55, 0x57, 0x93, 0x98, 0x81, 0x26, 0x52, + 0x0e, 0xac, 0xf2, 0xe3, 0x06, 0x6e, 0x23, 0x0c, + 0x91, 0xbe, 0xe4, 0xdd, 0x53, 0x04, 0xf5, 0xfd, + 0x04, 0x05, 0xb3, 0x5b, 0xd9, 0x9c, 0x73, 0x13, + 0x5d, 0x3d, 0x9b, 0xc3, 0x35, 0xee, 0x04, 0x9e, + 0xf6, 0x9b, 0x38, 0x67, 0xbf, 0x2d, 0x7b, 0xd1, + 0xea, 0xa5, 0x95, 0xd8, 0xbf, 0xc0, 0x06, 0x6f, + 0xf8, 0xd3, 0x15, 0x09, 0xeb, 0x0c, 0x6c, 0xaa, + 0x00, 0x6c, 0x80, 0x7a, 0x62, 0x3e, 0xf8, 0x4c, + 0x3d, 0x33, 0xc1, 0x95, 0xd2, 0x3e, 0xe3, 0x20, + 0xc4, 0x0d, 0xe0, 0x55, 0x81, 0x57, 0xc8, 0x22, + 0xd4, 0xb8, 0xc5, 0x69, 0xd8, 0x49, 0xae, 0xd5, + 0x9d, 0x4e, 0x0f, 0xd7, 0xf3, 0x79, 0x58, 0x6b, + 0x4b, 0x7f, 0xf6, 0x84, 0xed, 0x6a, 0x18, 0x9f, + 0x74, 0x86, 0xd4, 0x9b, 0x9c, 0x4b, 0xad, 0x9b, + 0xa2, 0x4b, 0x96, 0xab, 0xf9, 0x24, 0x37, 0x2c, + 0x8a, 0x8f, 0xff, 0xb1, 0x0d, 0x55, 0x35, 0x49, + 0x00, 0xa7, 0x7a, 0x3d, 0xb5, 0xf2, 0x05, 0xe1, + 0xb9, 0x9f, 0xcd, 0x86, 0x60, 0x86, 0x3a, 0x15, + 0x9a, 0xd4, 0xab, 0xe4, 0x0f, 0xa4, 0x89, 0x34, + 0x16, 0x3d, 0xdd, 0xe5, 0x42, 0xa6, 0x58, 0x55, + 0x40, 0xfd, 0x68, 0x3c, 0xbf, 0xd8, 0xc0, 0x0f, + 0x12, 0x12, 0x9a, 0x28, 0x4d, 0xea, 0xcc, 0x4c, + 0xde, 0xfe, 0x58, 0xbe, 0x71, 0x37, 0x54, 0x1c, + 0x04, 0x71, 0x26, 0xc8, 0xd4, 0x9e, 0x27, 0x55, + 0xab, 0x18, 0x1a, 0xb7, 0xe9, 0x40, 0xb0, 0xc0, + }, + }, +}; + +#define N_RC4_TESTS (sizeof(rc4_tests) / sizeof(rc4_tests[0])) + +static int +rc4_test(void) +{ + const struct rc4_test *rt; + RC4_KEY key; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher; + uint8_t out[512]; + int in_len, out_len, total_len; + size_t i; + int j; + int failed = 1; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_CIPHER_CTX_new() failed\n"); + goto failed; + } + + for (i = 0; i < N_RC4_TESTS; i++) { + rt = &rc4_tests[i]; + + /* Encryption */ + memset(out, 0, sizeof(out)); + RC4_set_key(&key, rt->key_len, rt->key); + RC4(&key, rt->len, rt->in, out); + + if (memcmp(rt->out, out, rt->len) != 0) { + fprintf(stderr, "FAIL: encryption mismatch\n"); + goto failed; + } + + /* Decryption */ + memset(out, 0, sizeof(out)); + RC4_set_key(&key, rt->key_len, rt->key); + RC4(&key, rt->len, rt->out, out); + + if (memcmp(rt->in, out, rt->len) != 0) { + fprintf(stderr, "FAIL: decryption mismatch\n"); + goto failed; + } + + /* + * EVP tests + */ + if (rt->key_len == 5) { + cipher = EVP_rc4_40(); + } else if (rt->key_len == 16) { + cipher = EVP_rc4(); + } else { + /* EVP does not support this key length */ + continue; + } + + /* EVP encryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_EncryptInit(ctx, cipher, rt->key, NULL)) { + fprintf(stderr, "FAIL: EVP_EncryptInit failed\n"); + goto failed; + } + + for (j = 0; j < rt->len;) { + in_len = arc4random_uniform(rt->len / 2); + if (in_len > rt->len - j) + in_len = rt->len - j; + + if (!EVP_EncryptUpdate(ctx, out + total_len, &out_len, + rt->in + j, in_len)) { + fprintf(stderr, + "FAIL: EVP_EncryptUpdate failed\n"); + goto failed; + } + + j += in_len; + total_len += out_len; + } + + if (!EVP_EncryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL: EVP_EncryptFinal_ex failed\n"); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, "FAIL: EVP_CIPHER_CTX_reset failed\n"); + goto failed; + } + + if (total_len != rt->len) { + fprintf(stderr, + "FAIL: EVP encryption length mismatch\n"); + goto failed; + } + + if (memcmp(rt->out, out, rt->len) != 0) { + fprintf(stderr, "FAIL: EVP encryption mismatch\n"); + goto failed; + } + + /* EVP decryption */ + total_len = 0; + memset(out, 0, sizeof(out)); + if (!EVP_DecryptInit(ctx, cipher, rt->key, NULL)) { + fprintf(stderr, "FAIL: EVP_DecryptInit failed\n"); + goto failed; + } + + for (j = 0; j < rt->len;) { + in_len = arc4random_uniform(rt->len / 2); + if (in_len > rt->len - j) + in_len = rt->len - j; + + if (!EVP_DecryptUpdate(ctx, out + total_len, &out_len, + rt->in + j, in_len)) { + fprintf(stderr, + "FAIL: EVP_DecryptUpdate failed\n"); + goto failed; + } + + j += in_len; + total_len += out_len; + } + + if (!EVP_DecryptFinal_ex(ctx, out + total_len, &out_len)) { + fprintf(stderr, "FAIL: EVP_DecryptFinal_ex failed\n"); + goto failed; + } + total_len += out_len; + + if (!EVP_CIPHER_CTX_reset(ctx)) { + fprintf(stderr, "FAIL: EVP_CIPHER_CTX_reset failed\n"); + goto failed; + } + + if (total_len != rt->len) { + fprintf(stderr, + "FAIL: EVP decryption length mismatch\n"); + goto failed; + } + + if (memcmp(rt->out, out, rt->len) != 0) { + fprintf(stderr, "FAIL: EVP decryption mismatch\n"); + goto failed; + } + } + + failed = 0; + + failed: + EVP_CIPHER_CTX_free(ctx); + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= rc4_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/record_layer_test.c b/Libraries/libressl/tests/record_layer_test.c new file mode 100644 index 000000000..2db0c10f8 --- /dev/null +++ b/Libraries/libressl/tests/record_layer_test.c @@ -0,0 +1,306 @@ +/* $OpenBSD: record_layer_test.c,v 1.6 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2019, 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "ssl_local.h" +#include "tls13_internal.h" +#include "tls13_record.h" + +int tls12_record_layer_inc_seq_num(struct tls12_record_layer *rl, + uint8_t *seq_num); +int tls13_record_layer_inc_seq_num(uint8_t *seq_num); + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\n"); + if (len % 8 != 0) + fprintf(stderr, "\n"); +} + +struct seq_num_test { + uint8_t seq_num[TLS13_RECORD_SEQ_NUM_LEN]; + uint8_t want_num[TLS13_RECORD_SEQ_NUM_LEN]; + int want; +}; + +struct seq_num_test seq_num_dtls_tests[] = { + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}, + .want = 1, + }, + { + .seq_num = {0xab, 0xcd, 0xef, 0x00, 0xfe, 0xff, 0xff, 0xff}, + .want_num = {0xab, 0xcd, 0xef, 0x00, 0xff, 0x00, 0x00, 0x00}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 0, + }, + { + .seq_num = {0x01, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want = 1, + }, + { + .seq_num = {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + .want_num = {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 1, + }, + { + .seq_num = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want_num = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + .want = 1, + }, + { + .seq_num = {0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 0, + }, + { + .seq_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + .want_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 1, + }, + { + .seq_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 0, + }, +}; + +#define N_SEQ_NUM_DTLS_TESTS \ + (sizeof(seq_num_dtls_tests) / sizeof(seq_num_dtls_tests[0])) + +struct seq_num_test seq_num_tls_tests[] = { + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff}, + .want_num = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}, + .want = 1, + }, + { + .seq_num = {0xab, 0xcd, 0xef, 0x00, 0xfe, 0xff, 0xff, 0xff}, + .want_num = {0xab, 0xcd, 0xef, 0x00, 0xff, 0x00, 0x00, 0x00}, + .want = 1, + }, + { + .seq_num = {0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want = 1, + }, + { + .seq_num = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want = 1, + }, + { + .seq_num = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want_num = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + .want = 1, + }, + { + .seq_num = {0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .want = 1, + }, + { + .seq_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + .want_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 1, + }, + { + .seq_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want_num = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .want = 0, + }, +}; + +#define N_SEQ_NUM_TLS_TESTS \ + (sizeof(seq_num_tls_tests) / sizeof(seq_num_tls_tests[0])) + +#ifndef TLS12_RECORD_SEQ_NUM_LEN +#define TLS12_RECORD_SEQ_NUM_LEN 8 +#endif + +static int +do_seq_num_test_tls12(size_t test_no, int dtls, struct seq_num_test *snt) +{ + uint8_t seq_num[TLS12_RECORD_SEQ_NUM_LEN]; + struct tls12_record_layer *rl; + int failed = 1; + int ret; + + if ((rl = tls12_record_layer_new()) == NULL) + errx(1, "tls12_record_layer_new"); + + if (dtls) + tls12_record_layer_set_version(rl, DTLS1_2_VERSION); + + memcpy(seq_num, snt->seq_num, sizeof(seq_num)); + + if ((ret = tls12_record_layer_inc_seq_num(rl, seq_num)) != snt->want) { + fprintf(stderr, "FAIL: Test %zu - got return %d, want %d\n", + test_no, ret, snt->want); + goto failure; + } + + if (memcmp(seq_num, snt->want_num, sizeof(seq_num)) != 0) { + fprintf(stderr, "FAIL: Test %zu - got sequence number:\n", + test_no); + hexdump(seq_num, sizeof(seq_num)); + fprintf(stderr, "want:\n"); + hexdump(snt->want_num, sizeof(snt->want_num)); + goto failure; + } + + failed = 0; + + failure: + tls12_record_layer_free(rl); + + return failed; +} + +static int +test_seq_num_tls12(void) +{ + int failed = 0; + size_t i; + + fprintf(stderr, "Running TLSv1.2 sequence number tests...\n"); + for (i = 0; i < N_SEQ_NUM_TLS_TESTS; i++) + failed |= do_seq_num_test_tls12(i, 0, &seq_num_tls_tests[i]); + + fprintf(stderr, "Running DTLSv1.2 sequence number tests...\n"); + for (i = 0; i < N_SEQ_NUM_DTLS_TESTS; i++) + failed |= do_seq_num_test_tls12(i, 1, &seq_num_dtls_tests[i]); + + return failed; +} + +static int +do_seq_num_test_tls13(size_t test_no, struct seq_num_test *snt) +{ + uint8_t seq_num[TLS13_RECORD_SEQ_NUM_LEN]; + int failed = 1; + int ret; + + memcpy(seq_num, snt->seq_num, sizeof(seq_num)); + + if ((ret = tls13_record_layer_inc_seq_num(seq_num)) != snt->want) { + fprintf(stderr, "FAIL: Test %zu - got return %d, want %d\n", + test_no, ret, snt->want); + goto failure; + } + + if (memcmp(seq_num, snt->want_num, sizeof(seq_num)) != 0) { + fprintf(stderr, "FAIL: Test %zu - got sequence number:\n", + test_no); + hexdump(seq_num, sizeof(seq_num)); + fprintf(stderr, "want:\n"); + hexdump(snt->want_num, sizeof(snt->want_num)); + goto failure; + } + + failed = 0; + + failure: + return failed; +} + +static int +test_seq_num_tls13(void) +{ + int failed = 0; + size_t i; + + fprintf(stderr, "Running TLSv1.3 sequence number tests...\n"); + + for (i = 0; i < N_SEQ_NUM_TLS_TESTS; i++) + failed |= do_seq_num_test_tls13(i, &seq_num_tls_tests[i]); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_seq_num_tls12(); + failed |= test_seq_num_tls13(); + + return failed; +} diff --git a/Libraries/libressl/tests/recordtest.c b/Libraries/libressl/tests/recordtest.c new file mode 100644 index 000000000..de9bfd693 --- /dev/null +++ b/Libraries/libressl/tests/recordtest.c @@ -0,0 +1,555 @@ +/* $OpenBSD: recordtest.c,v 1.5 2022/06/10 22:00:15 tb Exp $ */ +/* + * Copyright (c) 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +#include "tls13_internal.h" +#include "tls13_record.h" + +/* Valid record. */ +static uint8_t test_record_1[] = { + 0x16, 0x03, 0x03, 0x00, 0x7a, 0x02, 0x00, 0x00, + 0x76, 0x03, 0x03, 0x14, 0xae, 0x2b, 0x6d, 0x58, + 0xe9, 0x79, 0x9d, 0xd4, 0x90, 0x52, 0x90, 0x13, + 0x1c, 0x08, 0xaa, 0x3f, 0x5b, 0xfb, 0x64, 0xfe, + 0x9a, 0xca, 0x73, 0x6d, 0x87, 0x8d, 0x8b, 0x3b, + 0x70, 0x14, 0xa3, 0x20, 0xd7, 0x50, 0xa4, 0xe5, + 0x17, 0x42, 0x5d, 0xce, 0xe6, 0xfe, 0x1b, 0x59, + 0x27, 0x6b, 0xff, 0xc8, 0x40, 0xc7, 0xac, 0x16, + 0x32, 0xe6, 0x5b, 0xd2, 0xd9, 0xd4, 0xb5, 0x3f, + 0x8f, 0x74, 0x6e, 0x7d, 0x13, 0x02, 0x00, 0x00, + 0x2e, 0x00, 0x33, 0x00, 0x24, 0x00, 0x1d, 0x00, + 0x20, 0x72, 0xb0, 0xaf, 0x7f, 0xf5, 0x89, 0x0f, + 0xcd, 0x6e, 0x45, 0xb1, 0x51, 0xa0, 0xbd, 0x1e, + 0xee, 0x7e, 0xf1, 0xa5, 0xc5, 0xc6, 0x7e, 0x5f, + 0x6a, 0xca, 0xc9, 0xe4, 0xae, 0xb9, 0x50, 0x76, + 0x0a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, +}; + +/* Truncated record. */ +static uint8_t test_record_2[] = { + 0x17, 0x03, 0x03, 0x41, 0x00, 0x02, 0x00, 0x00, +}; + +/* Oversized and truncated record. */ +static uint8_t test_record_3[] = { + 0x17, 0x03, 0x03, 0x41, 0x01, 0x02, 0x00, 0x00, +}; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\n"); + if (len % 8 != 0) + fprintf(stderr, "\n"); +} + +struct rw_state { + uint8_t *buf; + size_t len; + size_t offset; + uint8_t eof; +}; + +static ssize_t +read_cb(void *buf, size_t buflen, void *cb_arg) +{ + struct rw_state *rs = cb_arg; + ssize_t n; + + if (rs->eof) + return TLS13_IO_EOF; + + if ((size_t)(n = buflen) > (rs->len - rs->offset)) + n = rs->len - rs->offset; + + if (n == 0) + return TLS13_IO_WANT_POLLIN; + + memcpy(buf, &rs->buf[rs->offset], n); + rs->offset += n; + + return n; +} + +static ssize_t +write_cb(const void *buf, size_t buflen, void *cb_arg) +{ + struct rw_state *ws = cb_arg; + ssize_t n; + + if (ws->eof) + return TLS13_IO_EOF; + + if ((size_t)(n = buflen) > (ws->len - ws->offset)) + n = ws->len - ws->offset; + + if (n == 0) + return TLS13_IO_WANT_POLLOUT; + + memcpy(&ws->buf[ws->offset], buf, n); + ws->offset += n; + + return n; +} + +struct record_test { + size_t rw_len; + int eof; + ssize_t want_ret; +}; + +struct record_recv_test { + uint8_t *read_buf; + struct record_test rt[10]; + uint8_t want_content_type; + uint8_t *want_data; + size_t want_len; +}; + +struct record_recv_test record_recv_tests[] = { + { + .read_buf = test_record_1, + .rt = { + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_content_type = SSL3_RT_HANDSHAKE, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .read_buf = test_record_1, + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_content_type = SSL3_RT_HANDSHAKE, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .read_buf = test_record_1, + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .rw_len = 5, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_content_type = SSL3_RT_HANDSHAKE, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .read_buf = test_record_1, + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .rw_len = 2, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .rw_len = 6, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_content_type = SSL3_RT_HANDSHAKE, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .read_buf = test_record_1, + .rt = { + { + .rw_len = 4, + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .eof = 1, + .want_ret = TLS13_IO_EOF, + }, + }, + }, + { + .read_buf = test_record_1, + .rt = { + { + .eof = 1, + .want_ret = TLS13_IO_EOF, + }, + }, + }, + { + .read_buf = test_record_2, + .rt = { + { + .rw_len = sizeof(test_record_2), + .want_ret = TLS13_IO_WANT_POLLIN, + }, + { + .eof = 1, + .want_ret = TLS13_IO_EOF, + }, + }, + .want_content_type = SSL3_RT_APPLICATION_DATA, + }, + { + .read_buf = test_record_3, + .rt = { + { + .rw_len = sizeof(test_record_3), + .want_ret = TLS13_IO_RECORD_OVERFLOW, + }, + }, + }, +}; + +#define N_RECORD_RECV_TESTS (sizeof(record_recv_tests) / sizeof(record_recv_tests[0])) + +struct record_send_test { + uint8_t *data; + size_t data_len; + struct record_test rt[10]; + uint8_t *want_data; + size_t want_len; +}; + +struct record_send_test record_send_tests[] = { + { + .data = test_record_1, + .data_len = sizeof(test_record_1), + .rt = { + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .data = test_record_1, + .data_len = sizeof(test_record_1), + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .data = test_record_1, + .data_len = sizeof(test_record_1), + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .rw_len = 5, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .data = test_record_1, + .data_len = sizeof(test_record_1), + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .rw_len = 2, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .rw_len = 6, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .rw_len = sizeof(test_record_1), + .want_ret = sizeof(test_record_1), + }, + }, + .want_data = test_record_1, + .want_len = sizeof(test_record_1), + }, + { + .data = test_record_1, + .data_len = sizeof(test_record_1), + .rt = { + { + .rw_len = 4, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .eof = 1, + .want_ret = TLS13_IO_EOF, + }, + }, + .want_data = test_record_1, + .want_len = 4, + }, + { + .data = test_record_1, + .data_len = sizeof(test_record_1), + .rt = { + { + .rw_len = 0, + .want_ret = TLS13_IO_WANT_POLLOUT, + }, + { + .eof = 1, + .want_ret = TLS13_IO_EOF, + }, + }, + .want_data = NULL, + .want_len = 0, + }, +}; + +#define N_RECORD_SEND_TESTS (sizeof(record_send_tests) / sizeof(record_send_tests[0])) + +static int +test_record_recv(size_t test_no, struct record_recv_test *rrt) +{ + struct tls13_record *rec; + struct rw_state rs; + int failed = 1; + ssize_t ret; + size_t i; + CBS cbs; + + rs.buf = rrt->read_buf; + rs.offset = 0; + + if ((rec = tls13_record_new()) == NULL) + errx(1, "tls13_record_new"); + + for (i = 0; rrt->rt[i].rw_len != 0 || rrt->rt[i].want_ret != 0; i++) { + rs.eof = rrt->rt[i].eof; + rs.len = rrt->rt[i].rw_len; + + ret = tls13_record_recv(rec, read_cb, &rs); + if (ret != rrt->rt[i].want_ret) { + fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_recv " + "returned %zd, want %zd\n", test_no, i, ret, + rrt->rt[i].want_ret); + goto failure; + } + } + + if (tls13_record_content_type(rec) != rrt->want_content_type) { + fprintf(stderr, "FAIL: Test %zu - got content type %u, " + "want %u\n", test_no, tls13_record_content_type(rec), + rrt->want_content_type); + goto failure; + } + + tls13_record_data(rec, &cbs); + if (rrt->want_data == NULL) { + if (CBS_data(&cbs) != NULL || CBS_len(&cbs) != 0) { + fprintf(stderr, "FAIL: Test %zu - got CBS with data, " + "want NULL\n", test_no); + goto failure; + } + goto done; + } + if (!CBS_mem_equal(&cbs, rrt->want_data, rrt->want_len)) { + fprintf(stderr, "FAIL: Test %zu - data mismatch\n", test_no); + fprintf(stderr, "Got record data:\n"); + hexdump(CBS_data(&cbs), CBS_len(&cbs)); + fprintf(stderr, "Want record data:\n"); + hexdump(rrt->want_data, rrt->want_len); + goto failure; + } + + if (!tls13_record_header(rec, &cbs)) { + fprintf(stderr, "FAIL: Test %zu - fail to get record " + "header", test_no); + goto failure; + } + if (!CBS_mem_equal(&cbs, rrt->want_data, TLS13_RECORD_HEADER_LEN)) { + fprintf(stderr, "FAIL: Test %zu - header mismatch\n", test_no); + fprintf(stderr, "Got record header:\n"); + hexdump(CBS_data(&cbs), CBS_len(&cbs)); + fprintf(stderr, "Want record header:\n"); + hexdump(rrt->want_data, rrt->want_len); + goto failure; + } + + if (!tls13_record_content(rec, &cbs)) { + fprintf(stderr, "FAIL: Test %zu - fail to get record " + "content", test_no); + goto failure; + } + if (!CBS_mem_equal(&cbs, rrt->want_data + TLS13_RECORD_HEADER_LEN, + rrt->want_len - TLS13_RECORD_HEADER_LEN)) { + fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no); + fprintf(stderr, "Got record content:\n"); + hexdump(CBS_data(&cbs), CBS_len(&cbs)); + fprintf(stderr, "Want record content:\n"); + hexdump(rrt->want_data, rrt->want_len); + goto failure; + } + + done: + failed = 0; + + failure: + tls13_record_free(rec); + + return failed; +} + +static int +test_record_send(size_t test_no, struct record_send_test *rst) +{ + uint8_t *data = NULL; + struct tls13_record *rec; + struct rw_state ws; + int failed = 1; + ssize_t ret; + size_t i; + + if ((ws.buf = malloc(TLS13_RECORD_MAX_LEN)) == NULL) + errx(1, "malloc"); + + ws.offset = 0; + + if ((rec = tls13_record_new()) == NULL) + errx(1, "tls13_record_new"); + + if ((data = malloc(rst->data_len)) == NULL) + errx(1, "malloc"); + memcpy(data, rst->data, rst->data_len); + + if (!tls13_record_set_data(rec, data, rst->data_len)) { + fprintf(stderr, "FAIL: Test %zu - failed to set record data\n", + test_no); + goto failure; + } + data = NULL; + + for (i = 0; rst->rt[i].rw_len != 0 || rst->rt[i].want_ret != 0; i++) { + ws.eof = rst->rt[i].eof; + ws.len = rst->rt[i].rw_len; + + ret = tls13_record_send(rec, write_cb, &ws); + if (ret != rst->rt[i].want_ret) { + fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_send " + "returned %zd, want %zd\n", test_no, i, ret, + rst->rt[i].want_ret); + goto failure; + } + } + + if (rst->want_data != NULL && + memcmp(ws.buf, rst->want_data, rst->want_len) != 0) { + fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no); + fprintf(stderr, "Got record data:\n"); + hexdump(rst->data, rst->data_len); + fprintf(stderr, "Want record data:\n"); + hexdump(rst->want_data, rst->want_len); + goto failure; + } + + failed = 0; + + failure: + tls13_record_free(rec); + free(ws.buf); + + return failed; +} + +static int +test_recv_records(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_RECORD_RECV_TESTS; i++) + failed |= test_record_recv(i, &record_recv_tests[i]); + + return failed; +} + +static int +test_send_records(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_RECORD_SEND_TESTS; i++) + failed |= test_record_send(i, &record_send_tests[i]); + + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_recv_records(); + failed |= test_send_records(); + + return failed; +} diff --git a/Libraries/libressl/tests/rfc3779.c b/Libraries/libressl/tests/rfc3779.c new file mode 100644 index 000000000..33808d43e --- /dev/null +++ b/Libraries/libressl/tests/rfc3779.c @@ -0,0 +1,1965 @@ +/* $OpenBSD: rfc3779.c,v 1.9 2023/04/20 07:39:17 tb Exp $ */ +/* + * Copyright (c) 2021 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +#define RAW_ADDRESS_SIZE 16 + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stderr, "\n"); +} + +static void +report_hexdump(const char *func, const char *description, const char *msg, + const unsigned char *want, size_t want_len, + const unsigned char *got, size_t got_len) +{ + fprintf(stderr, "%s: \"%s\" %s\nwant:\n", func, description, msg); + hexdump(want, want_len); + fprintf(stderr, "got:\n"); + hexdump(got, got_len); +} + +static int +afi_size(int afi) +{ + switch (afi) { + case IANA_AFI_IPV4: + return 4; + case IANA_AFI_IPV6: + return 16; + } + return 0; +} + +struct IPAddressOrRange_test { + const char *description; + const uint8_t der[32]; + size_t der_len; + unsigned afi; + const uint8_t min[RAW_ADDRESS_SIZE]; + const uint8_t max[RAW_ADDRESS_SIZE]; +}; + +const struct IPAddressOrRange_test IPAddressOrRange_test_data[] = { + /* Examples from RFC 3779, section 2.1.1 */ + { + .description = "address 10.5.0.4", + .der = { + 0x03, 0x05, 0x00, 0x0a, 0x05, 0x00, 0x04, + }, + .der_len = 7, + .afi = IANA_AFI_IPV4, + .min = { + 0x0a, 0x05, 0x00, 0x04, + }, + .max = { + 0x0a, 0x05, 0x00, 0x04, + } + }, + { + .description = "prefix 10.5.0/23", + .der = { + 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00, + }, + .der_len = 6, + .afi = IANA_AFI_IPV4, + .min = { + 0x0a, 0x05, 0x00, 0x00, + }, + .max = { + 0x0a, 0x05, 0x01, 0xff, + } + }, + { + .description = "address 2001:0:200:3::1", + .der = { + 0x03, 0x11, 0x00, 0x20, 0x01, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + }, + .der_len = 19, + .afi = IANA_AFI_IPV6, + .min = { + 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + .max = { + 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + }, + { + .description = "prefix 2001:0:200/39", + .der = { + 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02, + }, + .der_len = 8, + .afi = IANA_AFI_IPV6, + .min = { + 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .max = { + 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + }, + + /* Examples from RFC 3779, Section 2.1.2 */ + { + .description = "prefix 10.5.0/23 as a range", + .der = { + /* Sequence */ + 0x30, 0x0b, + /* 10.5.0.0 */ + 0x03, 0x03, 0x00, 0x0a, 0x05, + /* 10.5.1.255 */ + 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00, + }, + .der_len = 13, + .afi = IANA_AFI_IPV4, + .min = { + 0x0a, 0x05, 0x00, 0x00, + }, + .max = { + 0x0a, 0x05, 0x01, 0xff, + } + }, + { + .description = "prefix 2001:0:200/39 as a range", + .der = { + /* Sequence */ + 0x30, 0x10, + /* 2001:0:200:: */ + 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02, + /* 2001:0:3ff:ffff:ffff:ffff:ffff:ffff */ + 0x03, 0x06, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00, + }, + .der_len = 18, + .afi = IANA_AFI_IPV6, + .min = { + 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .max = { + 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + } + }, + { + .description = "prefix 0/0", + .der = { + 0x03, 0x01, 0x00, + }, + .der_len = 3, + .afi = IANA_AFI_IPV4, + .min = { + 0x00, 0x00, 0x00, 0x00, + }, + .max = { + 0xff, 0xff, 0xff, 0xff, + } + }, + { + .description = "prefix 10.64/12", + .der = { + 0x03, 0x03, 0x04, 0x0a, 0x40, + }, + .der_len = 5, + .afi = IANA_AFI_IPV4, + .min = { + 0x0a, 0x40, 0x00, 0x00, + }, + .max = { + 0x0a, 0x4f, 0xff, 0xff, + }, + }, + { + .description = "prefix 10.64/20", + .der = { + 0x03, 0x04, 0x04, 0x0a, 0x40, 0x00, + }, + .der_len = 6, + .afi = IANA_AFI_IPV4, + .min = { + 0x0a, 0x40, 0x00, 0x00, + }, + .max = { + 0x0a, 0x40, 0x0f, 0xff, + }, + }, +}; + +const size_t N_IPADDRESSORRANGE_TESTS = + sizeof(IPAddressOrRange_test_data) / sizeof(IPAddressOrRange_test_data[0]); + +static int +test_IPAddressOrRange(const struct IPAddressOrRange_test *test) +{ + IPAddressOrRange *aor; + const unsigned char *p; + unsigned char min[RAW_ADDRESS_SIZE] = {0}, max[RAW_ADDRESS_SIZE] = {0}; + unsigned char *out = NULL; + int out_len; + int afi_len; + int memcmp_failed = 0; + int failed = 1; + + /* + * First, decode DER from the test case. + */ + + p = &test->der[0]; + if ((aor = d2i_IPAddressOrRange(NULL, &p, test->der_len)) == NULL) { + fprintf(stderr, "%s: \"%s\" d2i_IPAddressOrRange failed\n", + __func__, test->description); + goto err; + } + + /* + * Now extract minimum and maximum from the parsed range. + */ + + afi_len = afi_size(test->afi); + + if (X509v3_addr_get_range(aor, test->afi, min, max, sizeof min) != + afi_len) { + fprintf(stderr, "%s: \"%s\" X509v3_addr_get_range failed\n", + __func__, test->description); + goto err; + } + + /* + * Check that min and max match expectations. + */ + + if (memcmp(min, test->min, afi_len) != 0) { + memcmp_failed |= 1; + report_hexdump(__func__, test->description, "memcmp min failed", + test->min, afi_len, min, afi_len); + } + if (memcmp(max, test->max, afi_len) != 0) { + memcmp_failed |= 1; + report_hexdump(__func__, test->description, "memcmp max failed", + test->max, afi_len, max, afi_len); + } + if (memcmp_failed) + goto err; + + /* + * Now turn the parsed IPAddressOrRange back into DER and check that + * it matches the DER in the test case. + */ + + out = NULL; + if ((out_len = i2d_IPAddressOrRange(aor, &out)) <= 0) { + fprintf(stderr, "%s: \"%s\" i2d_IPAddressOrRange failed\n", + __func__, test->description); + goto err; + } + + memcmp_failed = (size_t)out_len != test->der_len; + if (!memcmp_failed) + memcmp_failed = memcmp(test->der, out, out_len); + + if (memcmp_failed) { + report_hexdump(__func__, test->description, "memcmp DER failed", + test->der, test->der_len, out, out_len); + goto err; + } + + failed = 0; + err: + IPAddressOrRange_free(aor); + free(out); + + return failed; +} + +static int +run_IPAddressOrRange_tests(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_IPADDRESSORRANGE_TESTS; i++) + failed |= + test_IPAddressOrRange(&IPAddressOrRange_test_data[i]); + + return failed; +} + +/* + * XXX: These should really be part of the public API... + */ +static IPAddrBlocks *IPAddrBlocks_new(void); +static void IPAddrBlocks_free(IPAddrBlocks *addr); +static IPAddrBlocks *d2i_IPAddrBlocks(IPAddrBlocks **addrs, + const unsigned char **in, long len); +static int i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out); + +static IPAddrBlocks * +IPAddrBlocks_new(void) +{ + IPAddrBlocks *addrs; + + /* + * XXX The comparison function IPAddressFamily_cmp() isn't public. + * Start with the default and exploit a side effect of the lovely API + * which helpfully sets the correct function in a few places. Let's + * use the cheapest and easiest to reach one. + */ + if ((addrs = sk_IPAddressFamily_new_null()) == NULL) + return NULL; + if (!X509v3_addr_canonize(addrs)) { + IPAddrBlocks_free(addrs); + return NULL; + } + + return addrs; +} + +static void +IPAddrBlocks_free(IPAddrBlocks *addr) +{ + sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); +} + +/* + * We want {d2i,i2d}_IPAddrBlocks() to play with the DER of the extension. + * These don't exist, so we have to implement them ourselves. IPAddrBlocks_it + * isn't public, so we need to fetch it from the library. We cache it in a + * static variable to avoid the cost of a binary search through all supported + * extensions on each call. + */ + +static const ASN1_ITEM_EXP * +get_IPAddrBlocks_it(void) +{ + static const ASN1_ITEM_EXP *my_IPAddrBlocks_it; + const X509V3_EXT_METHOD *v3_addr; + + if (my_IPAddrBlocks_it != NULL) + return my_IPAddrBlocks_it; + + if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) { + fprintf(stderr, "could not get v3_addr\n"); + return NULL; + } + + my_IPAddrBlocks_it = v3_addr->it; + + return my_IPAddrBlocks_it; +} + +static IPAddrBlocks * +d2i_IPAddrBlocks(IPAddrBlocks **addrs, const unsigned char **in, long len) +{ + const ASN1_ITEM_EXP *my_IPAddrBlocks_it; + + if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL) + return NULL; + + return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrs, in, len, + my_IPAddrBlocks_it); +} + +static int +i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out) +{ + const ASN1_ITEM_EXP *my_IPAddrBlocks_it; + + if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL) + return -1; + + return ASN1_item_i2d((ASN1_VALUE *)addrs, out, my_IPAddrBlocks_it); +} + +struct ipv4_prefix { + unsigned char addr[4]; + size_t addr_len; + size_t prefix_len; +}; + +struct ipv4_range { + unsigned char min[4]; + unsigned char max[4]; +}; + +union ipv4_choice { + struct ipv4_prefix prefix; + struct ipv4_range range; +}; + +struct ipv6_prefix { + unsigned char addr[16]; + size_t addr_len; + size_t prefix_len; +}; + +struct ipv6_range { + unsigned char min[16]; + unsigned char max[16]; +}; + +union ipv6_choice { + struct ipv6_prefix prefix; + struct ipv6_range range; +}; + +enum choice_type { + choice_prefix, + choice_range, + choice_inherit, + choice_last, +}; + +union ip { + union ipv4_choice ipv4; + union ipv6_choice ipv6; +}; + +enum safi { + safi_none, + safi_unicast, + safi_multicast, +}; + +struct ip_addr_block { + unsigned int afi; + enum safi safi; + enum choice_type type; + union ip addr; +}; + +struct build_addr_block_test_data { + char *description; + struct ip_addr_block addrs[16]; + char der[128]; + size_t der_len; + int is_canonical; + int inherits; + unsigned int afis[4]; + int afi_len; +}; + +const struct build_addr_block_test_data build_addr_block_tests[] = { + { + .description = "RFC 3779, Appendix B, example 1", + .addrs = { + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 0, 32, + }, + .addr_len = 3, + .prefix_len = 20, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 0, 64, + }, + .addr_len = 3, + .prefix_len = 24, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 1, + }, + .addr_len = 2, + .prefix_len = 16, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 2, 48, + }, + .addr_len = 3, + .prefix_len = 20, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 2, 64, + }, + .addr_len = 3, + .prefix_len = 24, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 3, + }, + .addr_len = 2, + .prefix_len = 16, + }, + }, + { + .afi = IANA_AFI_IPV6, + .safi = safi_none, + .type = choice_inherit, + }, + { + .type = choice_last, + }, + }, + .der = { + 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01, + 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00, + 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03, + 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04, + 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a, + 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30, + 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00, + }, + .der_len = 55, + .is_canonical = 0, + .inherits = 1, + .afis = { + IANA_AFI_IPV4, IANA_AFI_IPV6, + }, + .afi_len = 2, + }, + { + .description = "RFC 3779, Appendix B, example 1 canonical", + .addrs = { + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 0, 32, + }, + .addr_len = 3, + .prefix_len = 20, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 0, 64, + }, + .addr_len = 3, + .prefix_len = 24, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 1, + }, + .addr_len = 2, + .prefix_len = 16, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_range, + .addr.ipv4.range = { + .min = { + 10, 2, 48, 00, + }, + .max = { + 10, 2, 64, 255, + }, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, 3, + }, + .addr_len = 2, + .prefix_len = 16, + }, + }, + { + .afi = IANA_AFI_IPV6, + .safi = safi_none, + .type = choice_inherit, + }, + { + .type = choice_last, + }, + }, + .der = { + 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01, + 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00, + 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03, + 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04, + 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a, + 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30, + 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00, + }, + .der_len = 55, + .is_canonical = 1, + .inherits = 1, + .afis = { + IANA_AFI_IPV4, IANA_AFI_IPV6, + }, + .afi_len = 2, + }, + { + .description = "RFC 3779, Appendix B, example 2", + .addrs = { + { + .afi = IANA_AFI_IPV6, + .safi = safi_none, + .type = choice_prefix, + .addr.ipv6.prefix = { + .addr = { + 0x20, 0x01, 0x00, 0x00, + 0x00, 0x02, + }, + .addr_len = 6, + .prefix_len = 48, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 10, + }, + .addr_len = 1, + .prefix_len = 8, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_unicast, + .type = choice_prefix, + .addr.ipv4.prefix = { + .addr = { + 172, 16, + }, + .addr_len = 2, + .prefix_len = 12, + }, + }, + { + .afi = IANA_AFI_IPV4, + .safi = safi_multicast, + .type = choice_inherit, + }, + { + .type = choice_last, + }, + }, + .der = { + 0x30, 0x2c, 0x30, 0x10, 0x04, 0x03, 0x00, 0x01, + 0x01, 0x30, 0x09, 0x03, 0x02, 0x00, 0x0a, 0x03, + 0x03, 0x04, 0xac, 0x10, 0x30, 0x07, 0x04, 0x03, + 0x00, 0x01, 0x02, 0x05, 0x00, 0x30, 0x0f, 0x04, + 0x02, 0x00, 0x02, 0x30, 0x09, 0x03, 0x07, 0x00, + 0x20, 0x01, 0x00, 0x00, 0x00, 0x02, + }, + .der_len = 46, + .is_canonical = 0, + .inherits = 1, + .afis = { + IANA_AFI_IPV4, IANA_AFI_IPV4, + }, + .afi_len = 2, + }, + { + .description = "Range should be prefix 127/8", + .addrs = { + { + .afi = IANA_AFI_IPV4, + .safi = safi_none, + .type = choice_range, + .addr.ipv4.range = { + .min = { + 127, 0, 0, 0, + }, + .max = { + 127, 255, 255, 255, + }, + }, + }, + { + .type = choice_last, + }, + }, + .der = { + 0x30, 0x0c, 0x30, 0x0a, 0x04, 0x02, 0x00, 0x01, + 0x30, 0x04, 0x03, 0x02, 0x00, 0x7f, + }, + .der_len = 14, + .is_canonical = 1, + .inherits = 0, + .afis = { + IANA_AFI_IPV4, + }, + .afi_len = 1, + }, +}; + +const size_t N_BUILD_ADDR_BLOCK_TESTS = + sizeof(build_addr_block_tests) / sizeof(build_addr_block_tests[0]); + +static unsigned int * +addr_block_get_safi(const struct ip_addr_block *addr) +{ + static unsigned int safi; + + switch (addr->safi) { + case safi_none: + return NULL; + case safi_unicast: + safi = 1; + break; + case safi_multicast: + safi = 2; + break; + } + + return &safi; +} + +static int +addr_block_add_ipv4_addr(IPAddrBlocks *block, enum choice_type type, + const union ipv4_choice *ipv4, unsigned int *safi) +{ + unsigned char addr[RAW_ADDRESS_SIZE] = {0}; + unsigned char min[RAW_ADDRESS_SIZE]; + unsigned char max[RAW_ADDRESS_SIZE]; + + switch (type) { + case choice_prefix: + memcpy(addr, ipv4->prefix.addr, ipv4->prefix.addr_len); + return X509v3_addr_add_prefix(block, IANA_AFI_IPV4, safi, + addr, ipv4->prefix.prefix_len); + case choice_range: + memcpy(min, ipv4->range.min, sizeof(ipv4->range.min)); + memcpy(max, ipv4->range.max, sizeof(ipv4->range.max)); + return X509v3_addr_add_range(block, IANA_AFI_IPV4, safi, + min, max); + case choice_inherit: + return X509v3_addr_add_inherit(block, IANA_AFI_IPV4, safi); + case choice_last: + default: + return 0; + } +} + +static int +addr_block_add_ipv6_addr(IPAddrBlocks *block, enum choice_type type, + const union ipv6_choice *ipv6, unsigned int *safi) +{ + unsigned char addr[RAW_ADDRESS_SIZE] = {0}; + unsigned char min[RAW_ADDRESS_SIZE]; + unsigned char max[RAW_ADDRESS_SIZE]; + + switch (type) { + case choice_prefix: + memcpy(addr, ipv6->prefix.addr, ipv6->prefix.addr_len); + return X509v3_addr_add_prefix(block, IANA_AFI_IPV6, safi, + addr, ipv6->prefix.prefix_len); + case choice_range: + memcpy(min, ipv6->range.min, sizeof(ipv6->range.min)); + memcpy(max, ipv6->range.max, sizeof(ipv6->range.max)); + return X509v3_addr_add_range(block, IANA_AFI_IPV6, safi, + min, max); + case choice_inherit: + return X509v3_addr_add_inherit(block, IANA_AFI_IPV6, safi); + case choice_last: + default: + return 0; + } +} + +static int +addr_block_add_addrs(IPAddrBlocks *block, const struct ip_addr_block addrs[]) +{ + const struct ip_addr_block *addr; + unsigned int *safi; + + for (addr = &addrs[0]; addr->type != choice_last; addr++) { + safi = addr_block_get_safi(addr); + switch (addr->afi) { + case IANA_AFI_IPV4: + if (!addr_block_add_ipv4_addr(block, addr->type, + &addr->addr.ipv4, safi)) + return 0; + break; + case IANA_AFI_IPV6: + if (!addr_block_add_ipv6_addr(block, addr->type, + &addr->addr.ipv6, safi)) + return 0; + break; + default: + fprintf(stderr, "%s: corrupt test data", __func__); + exit(1); + } + } + + return 1; +} + +static int +build_addr_block_test(const struct build_addr_block_test_data *test) +{ + IPAddrBlocks *addrs = NULL, *parsed = NULL; + const unsigned char *p; + unsigned char *out = NULL; + int out_len; + int i; + int memcmp_failed = 1; + int failed = 1; + + if ((addrs = IPAddrBlocks_new()) == NULL) + goto err; + + if (!addr_block_add_addrs(addrs, test->addrs)) + goto err; + + if (X509v3_addr_is_canonical(addrs) != test->is_canonical) { + fprintf(stderr, "%s: \"%s\" X509v3_addr_is_canonical not %d\n", + __func__, test->description, test->is_canonical); + goto err; + } + + if (!X509v3_addr_canonize(addrs)) { + fprintf(stderr, "%s: \"%s\" failed to canonize\n", + __func__, test->description); + goto err; + } + + if (!X509v3_addr_is_canonical(addrs)) { + fprintf(stderr, "%s: \"%s\" canonization wasn't canonical\n", + __func__, test->description); + goto err; + } + + if ((out_len = i2d_IPAddrBlocks(addrs, &out)) <= 0) { + fprintf(stderr, "%s: \"%s\" i2d_IPAddrBlocks failed\n", + __func__, test->description); + goto err; + } + + memcmp_failed = (size_t)out_len != test->der_len; + if (!memcmp_failed) + memcmp_failed = memcmp(out, test->der, test->der_len); + if (memcmp_failed) { + report_hexdump(__func__, test->description, "memcmp DER failed", + test->der, test->der_len, out, out_len); + goto err; + } + + if (X509v3_addr_inherits(addrs) != test->inherits) { + fprintf(stderr, "%s: \"%s\" X509v3_addr_inherits not %d\n", + __func__, test->description, test->inherits); + goto err; + } + + for (i = 0; i < sk_IPAddressFamily_num(addrs) && i < test->afi_len; i++) { + IPAddressFamily *family; + unsigned int afi; + + family = sk_IPAddressFamily_value(addrs, i); + + if ((afi = X509v3_addr_get_afi(family)) == 0) { + fprintf(stderr, "%s: \"%s\" X509v3_addr_get_afi" + " failed\n", __func__, test->description); + goto err; + } + if (test->afis[i] != afi){ + fprintf(stderr, "%s: \"%s\" afi[%d] mismatch. " + "want: %u, got: %u\n", __func__, + test->description, i, test->afis[i], afi); + goto err; + } + } + if (i != test->afi_len) { + fprintf(stderr, "%s: \"%s\" checked %d afis, expected %d\n", + __func__, test->description, i, test->afi_len); + goto err; + } + + p = test->der; + if ((parsed = d2i_IPAddrBlocks(NULL, &p, test->der_len)) == NULL) { + fprintf(stderr, "%s: \"%s\" d2i_IPAddrBlocks failed\n", + __func__, test->description); + goto err; + } + if (!X509v3_addr_is_canonical(parsed)) { + fprintf(stderr, "%s: \"%s\" parsed AddrBlocks isn't canonical\n", + __func__, test->description); + goto err; + } + /* Can't compare IPAddrBlocks with inheritance. */ + if (!X509v3_addr_inherits(addrs) && !X509v3_addr_inherits(parsed)) { + if (!X509v3_addr_subset(addrs, parsed)) { + fprintf(stderr, "%s: \"%s\" addrs not subset of parsed\n", + __func__, test->description); + } + if (!X509v3_addr_subset(parsed, addrs)) { + fprintf(stderr, "%s: \"%s\" parsed not subset of addrs\n", + __func__, test->description); + } + } + + failed = 0; + + err: + IPAddrBlocks_free(addrs); + IPAddrBlocks_free(parsed); + free(out); + + return failed; +} + +static int +run_IPAddrBlock_tests(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_BUILD_ADDR_BLOCK_TESTS; i++) + failed |= build_addr_block_test(&build_addr_block_tests[i]); + + return failed; +} + +struct asid_or_range { + int type; + int inherit; + const unsigned char *min; + const unsigned char *max; +}; + +struct ASIdentifiers_build_test { + const char *description; + int should_build; + int inherits; + int canonical; + int should_canonize; + struct asid_or_range delegations[8]; + const unsigned char der[128]; + size_t der_len; +}; + +/* Sentinel value used for marking the end of the delegations table. */ +#define V3_ASID_END -1 + +const struct ASIdentifiers_build_test ASIdentifiers_build_data[] = { + { + .description = "RFC 3779, Appendix C", + .should_build = 1, + .inherits = 1, + .canonical = 1, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "135", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3000", + .max = "3999", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "5001", + .max = NULL, + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + .min = NULL, + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .der = { + 0x30, 0x1a, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02, + 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, + 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, + 0xa1, 0x02, 0x05, 0x00, + }, + .der_len = 28, + }, + { + .description = "RFC 3779, Appendix C without rdi", + .should_build = 1, + .inherits = 0, + .canonical = 1, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "135", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3000", + .max = "3999", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "5001", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .der = { + 0x30, 0x16, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02, + 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, + 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, + }, + .der_len = 24, + }, + { + .description = "RFC 3779, Appendix C variant", + .should_build = 1, + .inherits = 0, + .canonical = 1, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "135", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3000", + .max = "3999", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "5001", + .max = NULL, + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "135", + .max = NULL, + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "3000", + .max = "3999", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "5001", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .der = { + 0x30, 0x2c, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02, + 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, + 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, + 0xa1, 0x14, 0x30, 0x12, 0x02, 0x02, 0x00, 0x87, + 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 0x02, 0x02, + 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, + }, + .der_len = 46, + }, + { + .description = "inherit only", + .should_build = 1, + .inherits = 1, + .canonical = 1, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 1, + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + .der = { + 0x30, 0x08, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x02, + 0x05, 0x00, + }, + .der_len = 10, + }, + { + .description = "adjacent unsorted ranges are merged", + .should_build = 1, + .inherits = 0, + .canonical = 0, + .should_canonize = 1, + .delegations = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "27", + .max = NULL, + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "28", + .max = "57", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "66", + .max = "68", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "58", + .max = "63", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "64", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .der = { + 0x30, 0x14, 0xa1, 0x12, 0x30, 0x10, 0x30, 0x06, + 0x02, 0x01, 0x1b, 0x02, 0x01, 0x40, 0x30, 0x06, + 0x02, 0x01, 0x42, 0x02, 0x01, 0x44, + }, + .der_len = 22, + }, + { + .description = "range of length 0", + .should_build = 1, + .inherits = 1, + .canonical = 1, + .should_canonize = 1, + .delegations = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "27", + .max = "27", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + .der = { + 0x30, 0x10, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x0a, + 0x30, 0x08, 0x30, 0x06, 0x02, 0x01, 0x1b, 0x02, + 0x01, 0x1b, + }, + .der_len = 18, + }, + { + .description = "reversed range doesn't canonize", + .should_build = 1, + .inherits = 0, + .canonical = 0, + .should_canonize = 0, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "57", + .max = "42", + }, + { + .type = V3_ASID_END, + }, + }, + }, + { + .description = "overlapping ranges don't canonize", + .should_build = 1, + .inherits = 0, + .canonical = 0, + .should_canonize = 0, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "42", + .max = "57", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "57", + .max = "60", + }, + { + .type = V3_ASID_END, + }, + }, + }, + { + .description = "reversed interior range doesn't canonize", + .should_build = 1, + .inherits = 0, + .canonical = 0, + .should_canonize = 0, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "2", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "57", + .max = "42", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "65523", + .max = "65535", + }, + { + .type = V3_ASID_END, + }, + }, + }, + { + .description = "can't inherit and add AS ids", + .should_build = 0, + .inherits = 0, + .canonical = 0, + .should_canonize = 0, + .delegations = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "2", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + }, + { + .description = "can't inherit and add rdis", + .should_build = 0, + .inherits = 0, + .canonical = 0, + .should_canonize = 0, + .delegations = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "2", + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + }, +}; + +const size_t N_ASIDENTIFIERS_BUILD_TESTS = + sizeof(ASIdentifiers_build_data) / sizeof(ASIdentifiers_build_data[0]); + +static int +add_as_delegation(ASIdentifiers *asid, const struct asid_or_range *delegation) +{ + ASN1_INTEGER *min = NULL, *max = NULL; + int ret = 0; + + if (delegation->inherit) + return X509v3_asid_add_inherit(asid, delegation->type); + + if ((min = s2i_ASN1_INTEGER(NULL, delegation->min)) == NULL) + goto err; + + if (delegation->max != NULL) { + if ((max = s2i_ASN1_INTEGER(NULL, delegation->max)) == NULL) + goto err; + } + + if (!X509v3_asid_add_id_or_range(asid, delegation->type, min, max)) + goto err; + min = NULL; + max = NULL; + + ret = 1; + + err: + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); + + return ret; +} + +static ASIdentifiers * +build_asid(const struct asid_or_range delegations[]) +{ + ASIdentifiers *asid = NULL; + const struct asid_or_range *delegation; + + if ((asid = ASIdentifiers_new()) == NULL) + goto err; + + for (delegation = &delegations[0]; delegation->type != V3_ASID_END; + delegation++) { + if (!add_as_delegation(asid, delegation)) + goto err; + } + + return asid; + + err: + ASIdentifiers_free(asid); + return NULL; +} + +static int +build_asid_test(const struct ASIdentifiers_build_test *test) +{ + ASIdentifiers *asid = NULL; + unsigned char *out = NULL; + int out_len; + int memcmp_failed = 1; + int failed = 1; + + if ((asid = build_asid(test->delegations)) == NULL) { + if (!test->should_build) { + failed = 0; + return failed; + } + fprintf(stderr, "%s: \"%s\" failed to build\n", __func__, + test->description); + return failed; + } + + if (!test->canonical) { + if (X509v3_asid_is_canonical(asid)) { + fprintf(stderr, "%s: \"%s\" shouldn't be canonical\n", + __func__, test->description); + goto err; + } + if (X509v3_asid_canonize(asid) != test->should_canonize) { + fprintf(stderr, "%s: \"%s\" failed to canonize\n", + __func__, test->description); + goto err; + } + if (!test->should_canonize) { + failed = 0; + goto err; + } + } + + /* + * Verify that asid is in canonical form before converting it to DER. + */ + if (!X509v3_asid_is_canonical(asid)) { + fprintf(stderr, "%s: asid is not canonical\n", __func__); + goto err; + } + + /* + * Convert asid to DER and check that it matches expectations + */ + out = NULL; + if ((out_len = i2d_ASIdentifiers(asid, &out)) <= 0) { + fprintf(stderr, "%s: \"%s\" i2d_ASIdentifiers failed\n", + __func__, test->description); + goto err; + } + + + memcmp_failed = (size_t)out_len != test->der_len; + if (!memcmp_failed) + memcmp_failed = memcmp(out, test->der, test->der_len); + if (memcmp_failed) { + report_hexdump(__func__, test->description, "memcmp DER failed", + test->der, test->der_len, out, out_len); + goto err; + } + + /* + * Verify that asid inherits as expected + */ + if (X509v3_asid_inherits(asid) != test->inherits) { + fprintf(stderr, "%s: \"%s\" unexpected asid inherit %d\n", + __func__, test->description, test->inherits); + goto err; + } + + failed = 0; + + err: + free(out); + ASIdentifiers_free(asid); + + return failed; +} + +static int +run_ASIdentifiers_build_test(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_ASIDENTIFIERS_BUILD_TESTS; i++) + failed |= build_asid_test(&ASIdentifiers_build_data[i]); + + return failed; +} + +struct ASIdentifiers_subset_test { + const char *description; + struct asid_or_range delegationsA[8]; + struct asid_or_range delegationsB[8]; + int is_subset; + int is_subset_if_canonized; +}; + +const struct ASIdentifiers_subset_test ASIdentifiers_subset_data[] = { + { + .description = "simple subset relation", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = "4", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 1, + .is_subset_if_canonized = 1, + }, + { + .description = "only asnums", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = "4", + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 1, + .is_subset_if_canonized = 1, + }, + { + .description = "only rdis", + .delegationsA = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 1, + .is_subset_if_canonized = 1, + }, + { + .description = "child only has asnums, parent only has rdis", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = "4", + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 0, + .is_subset_if_canonized = 0, + }, + { + .description = "child only has rdis, parent only has asnums", + .delegationsA = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "2", + .max = "4", + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 0, + .is_subset_if_canonized = 0, + }, + { + .description = "child only has rdis, parent has both", + .delegationsA = { + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "2", + .max = "4", + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 1, + .is_subset_if_canonized = 1, + }, + { + .description = "subset relation only after canonization", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3", + .max = "4", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "3", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "4", + .max = "5", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 0, + .is_subset_if_canonized = 1, + }, + { + .description = "no subset if A inherits", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3", + .max = "4", + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "3", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "4", + .max = "5", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "1", + .max = "5", + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 0, + .is_subset_if_canonized = 0, + }, + { + .description = "no subset if B inherits", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3", + .max = "4", + }, + { + .type = V3_ASID_RDI, + .inherit = 0, + .min = "5", + .max = NULL, + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "3", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "4", + .max = "5", + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 0, + .is_subset_if_canonized = 0, + }, + { + .description = "no subset if both inherit", + .delegationsA = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "2", + .max = NULL, + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "3", + .max = "4", + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + .delegationsB = { + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "1", + .max = "3", + }, + { + .type = V3_ASID_ASNUM, + .inherit = 0, + .min = "4", + .max = "5", + }, + { + .type = V3_ASID_RDI, + .inherit = 1, + }, + { + .type = V3_ASID_END, + }, + }, + .is_subset = 0, + .is_subset_if_canonized = 0, + }, +}; + +const size_t N_ASIDENTIFIERS_SUBSET_TESTS = + sizeof(ASIdentifiers_subset_data) / sizeof(ASIdentifiers_subset_data[0]); + +static int +asid_subset_test(const struct ASIdentifiers_subset_test *test) +{ + ASIdentifiers *asidA = NULL, *asidB = NULL; + int failed = 0; + + if ((asidA = build_asid(test->delegationsA)) == NULL) + goto err; + if ((asidB = build_asid(test->delegationsB)) == NULL) + goto err; + + if (X509v3_asid_subset(asidA, asidB) != test->is_subset) { + fprintf(stderr, "%s: \"%s\" X509v3_asid_subset failed\n", + __func__, test->description); + failed = 1; + } + + if (!test->is_subset) { + if (!X509v3_asid_canonize(asidA)) + goto err; + if (!X509v3_asid_canonize(asidB)) + goto err; + if (X509v3_asid_subset(asidA, asidB) != + test->is_subset_if_canonized) { + fprintf(stderr, "%s: \"%s\" canonized subset failed\n", + __func__, test->description); + failed = 1; + } + } + + err: + ASIdentifiers_free(asidA); + ASIdentifiers_free(asidB); + + return failed; +} + +static int +run_ASIdentifiers_subset_test(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_ASIDENTIFIERS_SUBSET_TESTS; i++) + failed |= asid_subset_test(&ASIdentifiers_subset_data[i]); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= run_IPAddressOrRange_tests(); + failed |= run_IPAddrBlock_tests(); + failed |= run_ASIdentifiers_build_test(); + failed |= run_ASIdentifiers_subset_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/rfc5280time.c b/Libraries/libressl/tests/rfc5280time.c new file mode 100644 index 000000000..dfffb3571 --- /dev/null +++ b/Libraries/libressl/tests/rfc5280time.c @@ -0,0 +1,390 @@ +/* $OpenBSD: rfc5280time.c,v 1.7 2022/09/05 21:12:08 tb Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * Copyright (c) 2015 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +struct rfc5280_time_test { + const char *str; + const char *data; + time_t time; +}; + +struct rfc5280_time_test rfc5280_invtime_tests[] = { + { + .str = "", + }, + { + .str = "2015", + }, + { + .str = "201509", + }, + { + .str = "20150923", + }, + { + .str = "20150923032700", + }, + { + /* UTC time must have seconds */ + .str = "7001010000Z", + }, + { + .str = "201509230327Z", + }, + { + .str = "20150923032700.Z", + }, + { + .str = "20150923032700.123", + }, + { + .str = "20150923032700+1100Z", + }, + { + .str = "20150923032700-11001", + }, + { + /* UTC time cannot have fractional seconds. */ + .str = "150923032700.123Z", + }, + { + /* Gen time cannot have +- TZ. */ + .str = "20150923032712+1115", + }, + { + /* Gen time cannot have fractional seconds */ + .str = "20150923032712.123Z", + }, + { + .str = "aaaaaaaaaaaaaaZ", + }, + { + /* Must be a UTC time per RFC 5280 */ + .str = "19700101000000Z", + .data = "19700101000000Z", + .time = 0, + }, + { + /* (times before 2050 must be UTCTIME) Per RFC 5280 4.1.2.5 */ + .str = "20150923032700Z", + .data = "20150923032700Z", + .time = 1442978820, + }, +#if SIZEOF_TIME_T == 8 + { + /* (times before 2050 must be UTCTIME) Per RFC 5280 4.1.2.5 */ + .str = "00000101000000Z", + .data = "00000101000000Z", + .time = -62167219200LL, + }, + { + /* (times before 2050 must be UTCTIME) Per RFC 5280 4.1.2.5 */ + .str = "20491231235959Z", + .data = "20491231235959Z", + .time = 2524607999LL, + }, +#endif + { + /* (times before 2050 must be UTCTIME) Per RFC 5280 4.1.2.5 */ + .str = "19500101000000Z", + .data = "19500101000000Z", + .time = -631152000LL, + }, +}; + +struct rfc5280_time_test rfc5280_gentime_tests[] = { +#if SIZEOF_TIME_T == 8 + { + /* Biggest RFC 5280 time */ + .str = "99991231235959Z", + .data = "99991231235959Z", + .time = 253402300799LL, + }, + { + .str = "21600218104000Z", + .data = "21600218104000Z", + .time = 6000000000LL, + }, + { + /* Smallest RFC 5280 gen time */ + .str = "20500101000000Z", + .data = "20500101000000Z", + .time = 2524608000LL, + }, +#endif +}; +struct rfc5280_time_test rfc5280_utctime_tests[] = { + { + .str = "500101000000Z", + .data = "500101000000Z", + .time = -631152000, + }, + { + .str = "540226230640Z", + .data = "540226230640Z", + .time = -500000000, + }, +#if SIZEOF_TIME_T == 8 + { + .str = "491231235959Z", + .data = "491231235959Z", + .time = 2524607999LL, + }, +#endif + { + .str = "700101000000Z", + .data = "700101000000Z", + .time = 0, + }, + { + .str = "150923032700Z", + .data = "150923032700Z", + .time = 1442978820, + }, + { + .str = "150923102700Z", + .data = "150923102700Z", + .time = 1443004020, + }, + { + .str = "150922162712Z", + .data = "150922162712Z", + .time = 1442939232, + }, + { + .str = "140524144512Z", + .data = "140524144512Z", + .time = 1400942712, + }, + { + .str = "240401144512Z", + .data = "240401144512Z", + .time = 1711982712, + }, +}; + +#define N_INVTIME_TESTS \ + (sizeof(rfc5280_invtime_tests) / sizeof(*rfc5280_invtime_tests)) +#define N_GENTIME_TESTS \ + (sizeof(rfc5280_gentime_tests) / sizeof(*rfc5280_gentime_tests)) +#define N_UTCTIME_TESTS \ + (sizeof(rfc5280_utctime_tests) / sizeof(*rfc5280_utctime_tests)) + +static int +asn1_compare_str(int test_no, struct asn1_string_st *asn1str, const char *str) +{ + int length = strlen(str); + + if (asn1str->length != length) { + fprintf(stderr, "FAIL: test %d - string lengths differ " + "(%d != %d)\n", test_no, asn1str->length, length); + return (1); + } + if (strncmp(asn1str->data, str, length) != 0) { + fprintf(stderr, "FAIL: test %d - strings differ " + "('%s' != '%s')\n", test_no, asn1str->data, str); + return (1); + } + + return (0); +} + +static int +rfc5280_invtime_test(int test_no, struct rfc5280_time_test *att) +{ + ASN1_GENERALIZEDTIME *gt = NULL; + ASN1_UTCTIME *ut = NULL; + ASN1_TIME *t = NULL; + int failure = 1; + time_t now = time(NULL); + + if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL) + goto done; + if ((ut = ASN1_UTCTIME_new()) == NULL) + goto done; + if ((t = ASN1_TIME_new()) == NULL) + goto done; + + if (ASN1_GENERALIZEDTIME_set_string(gt, att->str) != 0) { + if (X509_cmp_time(gt, &now) != 0) { + fprintf(stderr, "FAIL: test %d - successfully parsed as GENTIME " + "string '%s'\n", test_no, att->str); + goto done; + } + } + if (ASN1_UTCTIME_set_string(ut, att->str) != 0) { + if (X509_cmp_time(ut, &now) != 0) { + fprintf(stderr, "FAIL: test %d - successfully parsed as UTCTIME " + "string '%s'\n", test_no, att->str); + goto done; + } + } + if (ASN1_TIME_set_string(t, att->str) != 0) { + if (X509_cmp_time(t, &now) != 0) { + fprintf(stderr, "FAIL: test %d - successfully parsed as UTCTIME " + "string '%s'\n", test_no, att->str); + goto done; + } + } + + failure = 0; + + done: + ASN1_GENERALIZEDTIME_free(gt); + ASN1_UTCTIME_free(ut); + ASN1_TIME_free(t); + + return (failure); +} + +static int +rfc5280_gentime_test(int test_no, struct rfc5280_time_test *att) +{ + unsigned char *p = NULL; + ASN1_GENERALIZEDTIME *gt; + int failure = 1; + int i; + + if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL) + goto done; + + if (ASN1_GENERALIZEDTIME_set_string(gt, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + if (asn1_compare_str(test_no, gt, att->str) != 0) + goto done; + + if ((i = X509_cmp_time(gt, &att->time)) != -1) { + fprintf(stderr, "FAIL: test %d - X509_cmp_time failed - returned %d compared to %lld\n", + test_no, i, (long long)att->time); + goto done; + } + + att->time--; + if ((i = X509_cmp_time(gt, &att->time)) != 1) { + fprintf(stderr, "FAIL: test %d - X509_cmp_time failed - returned %d compared to %lld\n", + test_no, i, (long long)att->time); + goto done; + } + att->time++; + + ASN1_GENERALIZEDTIME_free(gt); + + if ((gt = ASN1_GENERALIZEDTIME_set(NULL, att->time)) == NULL) { + fprintf(stderr, "FAIL: test %d - failed to set time %lld\n", + test_no, (long long)att->time); + goto done; + } + if (asn1_compare_str(test_no, gt, att->data) != 0) + goto done; + + failure = 0; + + done: + ASN1_GENERALIZEDTIME_free(gt); + free(p); + + return (failure); +} + +static int +rfc5280_utctime_test(int test_no, struct rfc5280_time_test *att) +{ + unsigned char *p = NULL; + ASN1_UTCTIME *ut; + int failure = 1; + int i; + + if ((ut = ASN1_UTCTIME_new()) == NULL) + goto done; + + if (ASN1_UTCTIME_set_string(ut, att->str) != 1) { + fprintf(stderr, "FAIL: test %d - failed to set string '%s'\n", + test_no, att->str); + goto done; + } + if (asn1_compare_str(test_no, ut, att->str) != 0) + goto done; + + if ((i = X509_cmp_time(ut, &att->time)) != -1) { + fprintf(stderr, "FAIL: test %d - X509_cmp_time failed - returned %d compared to %lld\n", + test_no, i, (long long)att->time); + goto done; + } + + att->time--; + if ((i = X509_cmp_time(ut, &att->time)) != 1) { + fprintf(stderr, "FAIL: test %d - X509_cmp_time failed - returned %d compared to %lld\n", + test_no, i, (long long)att->time); + goto done; + } + att->time++; + + ASN1_UTCTIME_free(ut); + + if ((ut = ASN1_UTCTIME_set(NULL, att->time)) == NULL) { + fprintf(stderr, "FAIL: test %d - failed to set time %lld\n", + test_no, (long long)att->time); + goto done; + } + if (asn1_compare_str(test_no, ut, att->data) != 0) + goto done; + + failure = 0; + + done: + ASN1_UTCTIME_free(ut); + free(p); + + return (failure); +} + +int +main(int argc, char **argv) +{ + struct rfc5280_time_test *att; + int failed = 0; + size_t i; + + fprintf(stderr, "RFC5280 Invalid time tests...\n"); + for (i = 0; i < N_INVTIME_TESTS; i++) { + att = &rfc5280_invtime_tests[i]; + failed |= rfc5280_invtime_test(i, att); + } + + fprintf(stderr, "RFC5280 GENERALIZEDTIME tests...\n"); + for (i = 0; i < N_GENTIME_TESTS; i++) { + att = &rfc5280_gentime_tests[i]; + failed |= rfc5280_gentime_test(i, att); + } + + fprintf(stderr, "RFC5280 UTCTIME tests...\n"); + for (i = 0; i < N_UTCTIME_TESTS; i++) { + att = &rfc5280_utctime_tests[i]; + failed |= rfc5280_utctime_test(i, att); + } + return (failed); +} diff --git a/Libraries/libressl/tests/rfc5280time_small.test b/Libraries/libressl/tests/rfc5280time_small.test new file mode 100644 index 000000000..373059786 --- /dev/null +++ b/Libraries/libressl/tests/rfc5280time_small.test @@ -0,0 +1,10 @@ +#!/bin/sh +set -e +echo 1..2 +TEST=./rfc5280time +if [ -e ./rfc5280time.exe ]; then + TEST=./rfc5280time.exe +fi +$TEST +echo "ok 1" +echo "ok 2 - rfc5280time_64-bit # SKIP this system is unable to represent times past 2038" diff --git a/Libraries/libressl/tests/rmd_test.c b/Libraries/libressl/tests/rmd_test.c new file mode 100644 index 000000000..0a88a9bbb --- /dev/null +++ b/Libraries/libressl/tests/rmd_test.c @@ -0,0 +1,201 @@ +/* $OpenBSD: rmd_test.c,v 1.1 2022/09/02 15:45:52 tb Exp $ */ +/* + * Copyright (c) 2022 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +struct rmd_test { + const uint8_t in[128]; + const size_t in_len; + const uint8_t out[EVP_MAX_MD_SIZE]; +}; + +static const struct rmd_test rmd_tests[] = { + /* + * RIPEMD-160 - Test vectors from + * https://homes.esat.kuleuven.be/~bosselae/ripemd160.html + */ + { + .in = "", + .in_len = 0, + .out = { + 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, + 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, + 0xb2, 0x25, 0x8d, 0x31, + }, + }, + { + .in = "a", + .in_len = 1, + .out = { + 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, + 0xda, 0xae, 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, + 0x5a, 0x46, 0x7f, 0xfe, + }, + }, + { + .in = "abc", + .in_len = 3, + .out = { + 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, + 0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, + 0xf1, 0x5a, 0x0b, 0xfc, + }, + }, + { + .in = "message digest", + .in_len = 14, + .out = { + 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, + 0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, + 0x21, 0x59, 0x5f, 0x36, + }, + }, + { + .in = "abcdefghijklmnopqrstuvwxyz", + .in_len = 26, + .out = { + 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, + 0x56, 0xbb, 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, + 0xb3, 0x70, 0x8d, 0xbc, + }, + }, + { + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .in_len = 56, + .out = { + 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, + 0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, + 0xda, 0x62, 0xeb, 0x2b, + }, + }, + { + .in = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" + "wxyz0123456789", + .in_len = 62, + .out = { + 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, + 0x86, 0xed, 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, + 0xb2, 0x1f, 0x51, 0x89, + }, + }, + { + .in = + "123456789012345678901234567890123456789012345678" + "90123456789012345678901234567890", + .in_len = 80, + .out = { + 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, + 0xf4, 0xdb, 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, + 0x63, 0x32, 0x6b, 0xfb, + }, + }, +}; + +#define N_RMD_TESTS (sizeof(rmd_tests) / sizeof(rmd_tests[0])) + +static int +rmd_test(void) +{ + const struct rmd_test *rt; + EVP_MD_CTX *hash = NULL; + uint8_t out[EVP_MAX_MD_SIZE]; + size_t in_len; + size_t i; + int failed = 1; + + if ((hash = EVP_MD_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n"); + goto failed; + } + + for (i = 0; i < N_RMD_TESTS; i++) { + rt = &rmd_tests[i]; + + /* Digest */ + memset(out, 0, sizeof(out)); + RIPEMD160(rt->in, rt->in_len, out); + if (memcmp(rt->out, out, RIPEMD160_DIGEST_LENGTH) != 0) { + fprintf(stderr, "FAIL: mismatch\n"); + goto failed; + } + + /* EVP single-shot digest */ + memset(out, 0, sizeof(out)); + if (!EVP_Digest(rt->in, rt->in_len, out, NULL, EVP_ripemd160(), NULL)) { + fprintf(stderr, "FAIL: EVP_Digest failed\n"); + goto failed; + } + + if (memcmp(rt->out, out, RIPEMD160_DIGEST_LENGTH) != 0) { + fprintf(stderr, "FAIL: EVP single-shot mismatch\n"); + goto failed; + } + + /* EVP digest */ + memset(out, 0, sizeof(out)); + if (!EVP_DigestInit_ex(hash, EVP_ripemd160(), NULL)) { + fprintf(stderr, "FAIL: EVP_DigestInit_ex failed\n"); + goto failed; + } + + in_len = rt->in_len / 2; + if (!EVP_DigestUpdate(hash, rt->in, in_len)) { + fprintf(stderr, + "FAIL: EVP_DigestUpdate first half failed\n"); + goto failed; + } + + if (!EVP_DigestUpdate(hash, rt->in + in_len, + rt->in_len - in_len)) { + fprintf(stderr, + "FAIL: EVP_DigestUpdate second half failed\n"); + goto failed; + } + + if (!EVP_DigestFinal_ex(hash, out, NULL)) { + fprintf(stderr, "FAIL: EVP_DigestFinal_ex failed\n"); + goto failed; + } + + if (memcmp(rt->out, out, RIPEMD160_DIGEST_LENGTH) != 0) { + fprintf(stderr, "FAIL: EVP mismatch\n"); + goto failed; + } + } + + failed = 0; + + failed: + EVP_MD_CTX_free(hash); + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= rmd_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/rsa_test.c b/Libraries/libressl/tests/rsa_test.c new file mode 100644 index 000000000..6fd0ddc79 --- /dev/null +++ b/Libraries/libressl/tests/rsa_test.c @@ -0,0 +1,472 @@ +/* $OpenBSD: rsa_test.c,v 1.4 2021/11/25 16:51:31 tb Exp $ */ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* test vectors from p1ovect1.txt */ + +#include +#include + +#include +#include +#include +#include + +#ifdef OPENSSL_NO_RSA +int main(int argc, char *argv[]) +{ + printf("No RSA support\n"); + return (0); +} +#else +# include + +static int +key1(RSA *key, unsigned char *c) +{ + static unsigned char n[] = + "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F" + "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5" + "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93" + "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1" + "\xF5"; + + static unsigned char e[] = "\x11"; + + static unsigned char d[] = + "\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44" + "\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64" + "\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9" + "\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51"; + + static unsigned char p[] = + "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" + "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12" + "\x0D"; + + static unsigned char q[] = + "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" + "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" + "\x89"; + + static unsigned char dmp1[] = + "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF" + "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05"; + + static unsigned char dmq1[] = + "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99" + "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D" + "\x51"; + + static unsigned char iqmp[] = + "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8" + "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26"; + + static unsigned char ctext_ex[] = + "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89" + "\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52" + "\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44" + "\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2"; + + BIGNUM *bn_n = NULL, *bn_e = NULL, *bn_d = NULL; + BIGNUM *bn_p = NULL, *bn_q = NULL; + BIGNUM *bn_dmp1 = NULL, *bn_dmq1 = NULL, *bn_iqmp = NULL; + + bn_n = BN_bin2bn(n, sizeof(n) - 1, NULL); + bn_e = BN_bin2bn(e, sizeof(e) - 1, NULL); + bn_d = BN_bin2bn(d, sizeof(d) - 1, NULL); + if (bn_n == NULL || bn_e == NULL || bn_d == NULL) + goto err; + if (!RSA_set0_key(key, bn_n, bn_e, bn_d)) + goto err; + bn_n = NULL; + bn_e = NULL; + bn_d = NULL; + + bn_p = BN_bin2bn(p, sizeof(p) - 1, NULL); + bn_q = BN_bin2bn(q, sizeof(q) - 1, NULL); + if (bn_p == NULL || bn_q == NULL) + goto err; + if (!RSA_set0_factors(key, bn_p, bn_q)) + goto err; + bn_p = NULL; + bn_q = NULL; + + bn_dmp1 = BN_bin2bn(dmp1, sizeof(dmp1) - 1, NULL); + bn_dmq1 = BN_bin2bn(dmq1, sizeof(dmq1) - 1, NULL); + bn_iqmp = BN_bin2bn(iqmp, sizeof(iqmp) - 1, NULL); + if (bn_dmp1 == NULL || bn_dmq1 == NULL || bn_iqmp == NULL) + goto err; + if (!RSA_set0_crt_params(key, bn_dmp1, bn_dmq1, bn_iqmp)) + goto err; + bn_dmp1 = NULL; + bn_dmq1 = NULL; + bn_iqmp = NULL; + + memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); + return sizeof(ctext_ex) - 1; + + err: + BN_free(bn_n); + BN_free(bn_e); + BN_free(bn_d); + BN_free(bn_p); + BN_free(bn_q); + BN_free(bn_dmp1); + BN_free(bn_dmq1); + BN_free(bn_iqmp); + + return -1; +} + +static int +key2(RSA *key, unsigned char *c) +{ + static unsigned char n[] = + "\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8" + "\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26" + "\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8" + "\x34\x77\xCF"; + + static unsigned char e[] = "\x3"; + + static unsigned char d[] = + "\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2" + "\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41" + "\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21" + "\xE5\xEB"; + + static unsigned char p[] = + "\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92" + "\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91"; + + static unsigned char q[] = + "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" + "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F"; + + static unsigned char dmp1[] = + "\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61" + "\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B"; + + static unsigned char dmq1[] = + "\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90" + "\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F"; + + static unsigned char iqmp[] = + "\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13" + "\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D"; + + static unsigned char ctext_ex[] = + "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" + "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" + "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" + "\x62\x51"; + + BIGNUM *bn_n = NULL, *bn_e = NULL, *bn_d = NULL; + BIGNUM *bn_p = NULL, *bn_q = NULL; + BIGNUM *bn_dmp1 = NULL, *bn_dmq1 = NULL, *bn_iqmp = NULL; + + bn_n = BN_bin2bn(n, sizeof(n) - 1, NULL); + bn_e = BN_bin2bn(e, sizeof(e) - 1, NULL); + bn_d = BN_bin2bn(d, sizeof(d) - 1, NULL); + if (bn_n == NULL || bn_e == NULL || bn_d == NULL) + goto err; + if (!RSA_set0_key(key, bn_n, bn_e, bn_d)) + goto err; + bn_n = NULL; + bn_e = NULL; + bn_d = NULL; + + bn_p = BN_bin2bn(p, sizeof(p) - 1, NULL); + bn_q = BN_bin2bn(q, sizeof(q) - 1, NULL); + if (bn_p == NULL || bn_q == NULL) + goto err; + if (!RSA_set0_factors(key, bn_p, bn_q)) + goto err; + bn_p = NULL; + bn_q = NULL; + + bn_dmp1 = BN_bin2bn(dmp1, sizeof(dmp1) - 1, NULL); + bn_dmq1 = BN_bin2bn(dmq1, sizeof(dmq1) - 1, NULL); + bn_iqmp = BN_bin2bn(iqmp, sizeof(iqmp) - 1, NULL); + if (bn_dmp1 == NULL || bn_dmq1 == NULL || bn_iqmp == NULL) + goto err; + if (!RSA_set0_crt_params(key, bn_dmp1, bn_dmq1, bn_iqmp)) + goto err; + bn_dmp1 = NULL; + bn_dmq1 = NULL; + bn_iqmp = NULL; + + memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); + return sizeof(ctext_ex) - 1; + + err: + BN_free(bn_n); + BN_free(bn_e); + BN_free(bn_d); + BN_free(bn_p); + BN_free(bn_q); + BN_free(bn_dmp1); + BN_free(bn_dmq1); + BN_free(bn_iqmp); + + return -1; +} + +static int +key3(RSA *key, unsigned char *c) +{ + static unsigned char n[] = + "\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" + "\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" + "\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD" + "\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80" + "\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25" + "\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39" + "\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68" + "\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" + "\xCB"; + + static unsigned char e[] = "\x11"; + + static unsigned char d[] = + "\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD" + "\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41" + "\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69" + "\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA" + "\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94" + "\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A" + "\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" + "\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" + "\xC1"; + + static unsigned char p[] = + "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" + "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" + "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" + "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" + "\x99"; + + static unsigned char q[] = + "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" + "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" + "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" + "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" + "\x03"; + + static unsigned char dmp1[] = + "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" + "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" + "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" + "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"; + + static unsigned char dmq1[] = + "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" + "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" + "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" + "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"; + + static unsigned char iqmp[] = + "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" + "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" + "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" + "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" + "\xF7"; + + static unsigned char ctext_ex[] = + "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7" + "\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce" + "\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3" + "\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06" + "\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86" + "\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4" + "\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a" + "\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1"; + + BIGNUM *bn_n = NULL, *bn_e = NULL, *bn_d = NULL; + BIGNUM *bn_p = NULL, *bn_q = NULL; + BIGNUM *bn_dmp1 = NULL, *bn_dmq1 = NULL, *bn_iqmp = NULL; + + bn_n = BN_bin2bn(n, sizeof(n) - 1, NULL); + bn_e = BN_bin2bn(e, sizeof(e) - 1, NULL); + bn_d = BN_bin2bn(d, sizeof(d) - 1, NULL); + if (bn_n == NULL || bn_e == NULL || bn_d == NULL) + goto err; + if (!RSA_set0_key(key, bn_n, bn_e, bn_d)) + goto err; + bn_n = NULL; + bn_e = NULL; + bn_d = NULL; + + bn_p = BN_bin2bn(p, sizeof(p) - 1, NULL); + bn_q = BN_bin2bn(q, sizeof(q) - 1, NULL); + if (bn_p == NULL || bn_q == NULL) + goto err; + if (!RSA_set0_factors(key, bn_p, bn_q)) + goto err; + bn_p = NULL; + bn_q = NULL; + + bn_dmp1 = BN_bin2bn(dmp1, sizeof(dmp1) - 1, NULL); + bn_dmq1 = BN_bin2bn(dmq1, sizeof(dmq1) - 1, NULL); + bn_iqmp = BN_bin2bn(iqmp, sizeof(iqmp) - 1, NULL); + if (bn_dmp1 == NULL || bn_dmq1 == NULL || bn_iqmp == NULL) + goto err; + if (!RSA_set0_crt_params(key, bn_dmp1, bn_dmq1, bn_iqmp)) + goto err; + bn_dmp1 = NULL; + bn_dmq1 = NULL; + bn_iqmp = NULL; + + memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); + + return sizeof(ctext_ex) - 1; + + err: + BN_free(bn_n); + BN_free(bn_e); + BN_free(bn_d); + BN_free(bn_p); + BN_free(bn_q); + BN_free(bn_dmp1); + BN_free(bn_dmq1); + BN_free(bn_iqmp); + + return -1; +} + +static int +pad_unknown(void) +{ + unsigned long l; + while ((l = ERR_get_error()) != 0) + if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE) + return (1); + return (0); +} + +int +main(int argc, char *argv[]) +{ + int err = 0; + int v; + RSA *key; + unsigned char ptext[256]; + unsigned char ctext[256]; + static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; + unsigned char ctext_ex[256]; + int plen; + int clen = 0; + int num; + int n; + + plen = sizeof(ptext_ex) - 1; + + for (v = 0; v < 3; v++) { + key = RSA_new(); + switch (v) { + case 0: + clen = key1(key, ctext_ex); + break; + case 1: + clen = key2(key, ctext_ex); + break; + case 2: + clen = key3(key, ctext_ex); + break; + } + + if (clen <= 0) { + printf("failed to generate key%d\n", v); + err = 1; + goto next; + } + + num = RSA_public_encrypt(plen, ptext_ex, ctext, key, + RSA_PKCS1_PADDING); + if (num != clen) { + printf("PKCS#1 v1.5 encryption failed!\n"); + err = 1; + goto oaep; + } + + num = RSA_private_decrypt(num, ctext, ptext, key, + RSA_PKCS1_PADDING); + if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { + printf("PKCS#1 v1.5 decryption failed!\n"); + err = 1; + } else + printf("PKCS #1 v1.5 encryption/decryption ok\n"); + + oaep: + ERR_clear_error(); + num = RSA_public_encrypt(plen, ptext_ex, ctext, key, + RSA_PKCS1_OAEP_PADDING); + if (num == -1 && pad_unknown()) { + printf("No OAEP support\n"); + goto next; + } + if (num != clen) { + printf("OAEP encryption failed!\n"); + err = 1; + goto next; + } + + num = RSA_private_decrypt(num, ctext, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { + printf("OAEP decryption (encrypted data) failed!\n"); + err = 1; + } else if (memcmp(ctext, ctext_ex, num) == 0) + printf("OAEP test vector %d passed!\n", v); + + /* + * Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT). + * Try decrypting ctext_ex + */ + + num = RSA_private_decrypt(clen, ctext_ex, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { + printf("OAEP decryption (test vector data) failed!\n"); + err = 1; + } else + printf("OAEP encryption/decryption ok\n"); + + /* Try decrypting corrupted ciphertexts. */ + for (n = 0; n < clen; ++n) { + ctext[n] ^= 1; + num = RSA_private_decrypt(clen, ctext, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num > 0) { + printf("Corrupt data decrypted!\n"); + err = 1; + break; + } + ctext[n] ^= 1; + } + + /* Test truncated ciphertexts, as well as negative length. */ + for (n = -1; n < clen; ++n) { + num = RSA_private_decrypt(n, ctext, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num > 0) { + printf("Truncated data decrypted!\n"); + err = 1; + break; + } + } + + next: + RSA_free(key); + } + + return err; +} +#endif diff --git a/Libraries/libressl/tests/server.pem b/Libraries/libressl/tests/server.pem new file mode 100644 index 000000000..7412490f5 --- /dev/null +++ b/Libraries/libressl/tests/server.pem @@ -0,0 +1,51 @@ +subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert +issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA +-----BEGIN CERTIFICATE----- +MIIDpTCCAo2gAwIBAgIJAPYm3GvOr5eUMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt +ZWRpYXRlIENBMB4XDTE0MDUyNDE0NDUxMloXDTI0MDQwMTE0NDUxMlowZDELMAkG +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU +RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJ +KCLTuf7g3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfi +R7bfSdI/+qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMv +vPQGuI+OEAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7 +TVcGVSEiJdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU +41NEWAsu/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8R +AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG ++EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B +AQUFAAOCAQEADfy8VrY5er5ebYLyiC1il5kVOuJHSf8aN5SciJz/VcifA1+Hl2Bu +CfuizhP/kUdB9PTSj8ep9sL+5PBFl7CZJDO6Sxs5+qJe15XvLBP8UEdvc779plL6 +StUMJT0aU/MaqUZZCldC3G4CcbwzOzKSD5YzvxxIGspxBWRduZKKMOju/4aqK76p +dwA/VGCve9mjft3LIrb0gSaPi5KmdGtpAjzW3H1+63DSqxCYb1oiPtUZBs4STwjh +WPRmAEVR4RPCETM3Sth4C+bE0QMCGY12ctcbzhj7Xgo7LcSpqviq6JD8SPuU7ISL +hy4NcnBBHJr9OV9WTLpmS9V9Vg6QmOpxQw== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv +h4VZS2axxfV6hV3CD9MuKVg2zEhroqK1Js5n4ke230nSP/qiELfCl0R+hzRtbfKL +tFUr1iHeU0uQ6v3q+Tg1K/Tmmg72uxKrhyHDL7z0BriPjhAHJ5XlQsvR1RCMkqzu +D9wjSInJxpMMIgLndOclAKv4D1wQtYU7ZpTw+01XBlUhIiXb86qpYL9NqnnRq5JI +uhmOEuxo2ca63+xaHNhD/udSyc8C0Md/yX6wlONTRFgLLv0pdLUGm1xEjfsydaQ6 +qGd7hzIKUI3hohNKJa/mHLElv7SZolPTogK/EQIDAQABAoIBAADq9FwNtuE5IRQn +zGtO4q7Y5uCzZ8GDNYr9RKp+P2cbuWDbvVAecYq2NV9QoIiWJOAYZKklOvekIju3 +r0UZLA0PRiIrTg6NrESx3JrjWDK8QNlUO7CPTZ39/K+FrmMkV9lem9yxjJjyC34D +AQB+YRTx+l14HppjdxNwHjAVQpIx/uO2F5xAMuk32+3K+pq9CZUtrofe1q4Agj9R +5s8mSy9pbRo9kW9wl5xdEotz1LivFOEiqPUJTUq5J5PeMKao3vdK726XI4Z455Nm +W2/MA0YV0ug2FYinHcZdvKM6dimH8GLfa3X8xKRfzjGjTiMSwsdjgMa4awY3tEHH +674jhAECgYEA/zqMrc0zsbNk83sjgaYIug5kzEpN4ic020rSZsmQxSCerJTgNhmg +utKSCt0Re09Jt3LqG48msahX8ycqDsHNvlEGPQSbMu9IYeO3Wr3fAm75GEtFWePY +BhM73I7gkRt4s8bUiUepMG/wY45c5tRF23xi8foReHFFe9MDzh8fJFECgYEA9EFX +4qAik1pOJGNei9BMwmx0I0gfVEIgu0tzeVqT45vcxbxr7RkTEaDoAG6PlbWP6D9a +WQNLp4gsgRM90ZXOJ4up5DsAWDluvaF4/omabMA+MJJ5kGZ0gCj5rbZbKqUws7x8 +bp+6iBfUPJUbcqNqFmi/08Yt7vrDnMnyMw2A/sECgYEAiiuRMxnuzVm34hQcsbhH +6ymVqf7j0PW2qK0F4H1ocT9qhzWFd+RB3kHWrCjnqODQoI6GbGr/4JepHUpre1ex +4UEN5oSS3G0ru0rC3U4C59dZ5KwDHFm7ffZ1pr52ljfQDUsrjjIMRtuiwNK2OoRa +WSsqiaL+SDzSB+nBmpnAizECgYBdt/y6rerWUx4MhDwwtTnel7JwHyo2MDFS6/5g +n8qC2Lj6/fMDRE22w+CA2esp7EJNQJGv+b27iFpbJEDh+/Lf5YzIT4MwVskQ5bYB +JFcmRxUVmf4e09D7o705U/DjCgMH09iCsbLmqQ38ONIRSHZaJtMDtNTHD1yi+jF+ +OT43gQKBgQC/2OHZoko6iRlNOAQ/tMVFNq7fL81GivoQ9F1U0Qr+DH3ZfaH8eIkX +xT0ToMPJUzWAn8pZv0snA0um6SIgvkCuxO84OkANCVbttzXImIsL7pFzfcwV/ERK +UM6j0ZuSMFOCr/lGPAoOQU0fskidGEHi1/kW+suSr28TqsyYZpwBDQ== +-----END RSA PRIVATE KEY----- diff --git a/Libraries/libressl/tests/server1-ecdsa-chain.pem b/Libraries/libressl/tests/server1-ecdsa-chain.pem new file mode 100644 index 000000000..46add4d11 --- /dev/null +++ b/Libraries/libressl/tests/server1-ecdsa-chain.pem @@ -0,0 +1,26 @@ +subject= CN = LibreSSL Test Server 1 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBqzCCAVKgAwIBAgIJAOVssaaTYoH4MAoGCCqGSM49BAMCMC4xLDAqBgNVBAMM +I0xpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTIxMTIyNzE0 +NDA0MFoXDTMxMTIyNTE0NDA0MFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBT +ZXJ2ZXIgMSBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLCfzrwjvJ6V +m2Jog48gtuDNYupHd8TKOCVb6J7f1/U3Owwy2//ZVTvM+9uoIC8xxUJAmN0PC+9a ++5TkRWiD1KWjYDBeMB0GA1UdDgQWBBTo776/p89eGJwMmJRNk4k+xGVRPTAfBgNV +HSMEGDAWgBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1Ud +DwEB/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAhHPaADQMcGea7iBRbKZWSHUAf +fZSNIWF/nYASNBvKLgIgQXLiuWxt6/a7vxaZwgYXkhP1YfDSC5Kpktxr/3jHcAU= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/server1-ecdsa.pem b/Libraries/libressl/tests/server1-ecdsa.pem new file mode 100644 index 000000000..541fed6ef --- /dev/null +++ b/Libraries/libressl/tests/server1-ecdsa.pem @@ -0,0 +1,18 @@ +subject= CN = LibreSSL Test Server 1 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBqzCCAVKgAwIBAgIJAOVssaaTYoH4MAoGCCqGSM49BAMCMC4xLDAqBgNVBAMM +I0xpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTIxMTIyNzE0 +NDA0MFoXDTMxMTIyNTE0NDA0MFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBT +ZXJ2ZXIgMSBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLCfzrwjvJ6V +m2Jog48gtuDNYupHd8TKOCVb6J7f1/U3Owwy2//ZVTvM+9uoIC8xxUJAmN0PC+9a ++5TkRWiD1KWjYDBeMB0GA1UdDgQWBBTo776/p89eGJwMmJRNk4k+xGVRPTAfBgNV +HSMEGDAWgBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1Ud +DwEB/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAhHPaADQMcGea7iBRbKZWSHUAf +fZSNIWF/nYASNBvKLgIgQXLiuWxt6/a7vxaZwgYXkhP1YfDSC5Kpktxr/3jHcAU= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgvh2q0Zzqn18tPux2 +csqpbWDtHGialpwtx/r/0ENHeKOhRANCAASwn868I7yelZtiaIOPILbgzWLqR3fE +yjglW+ie39f1NzsMMtv/2VU7zPvbqCAvMcVCQJjdDwvvWvuU5EVog9Sl +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/server1-rsa-chain.pem b/Libraries/libressl/tests/server1-rsa-chain.pem new file mode 100644 index 000000000..57dec7b5b --- /dev/null +++ b/Libraries/libressl/tests/server1-rsa-chain.pem @@ -0,0 +1,44 @@ +subject= CN = LibreSSL Test Server 1 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoHzMA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzdaFw0zMTEyMjUxNDQwMzdaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +U2VydmVyIDEgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnvyt +i0uA2qaFltVb8+PElYk84AnjY0WZDcGtKSMCAYTD857fO2V4S/wpJ9ZMt8kBKQ29 +D2Glkkhc/HPpb7wJcAUT++aZ/PbOtuzOHzdxheOolfZ6aw+qCSiVlcflKfMp7VPL +swimqKpm6atl2aSqldKfmGzjhAAPiTXbzUjh9pbTfO8ykdn/6AqP7ju3+4sseMPL +seNq1wstWRdiHm0P/BoJn4lwDe7QTSp1AxMqDTz5BiO+UjCW2oTsOFfo/hhslQf5 +qv7uPLrz/VWiEojQP5RzfcnVwplUgTvtaOkXxZeOH7VkKS1v8W506/h3RIKj0X8Y +JDLuIPqSAPNLWGyH4wIDAQABo2AwXjAdBgNVHQ4EFgQUFJPGTfe+ULC/anJ4fCVz +DXA0JI4wHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAGP5hYyAYzlj +YCV24ApNPb+mNEMHu1SL1MgDXJOTWZMFOvuYcibtmcVIfwpM4+UpC7cRqPRjBEqm +NdLbJi4jGzQDNOcI7OZCCx6oKvAhjMofpb42Iq4bDuBqlhHRXvYnO30y0yRbSGXt +GvKvkNKOSXUnY1UtcBAN5szcyFk30xQK+f/2VqJguvjsTquFV+piqFyq91ICyIeQ +1gjTn1N2/SkmYpwZdyf0HqSjyqJ0FG4xiW6T0HmX1QI651Kux49vLel7ySxzGY+6 +axnPilTYx/7pkciGk5ckLdujpXsDPhC+E2hdoee494c5NvX/uibYhigLU/gHK/ZP +YisY8ihnPl8= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/server1-rsa.pem b/Libraries/libressl/tests/server1-rsa.pem new file mode 100644 index 000000000..12e9ac9ec --- /dev/null +++ b/Libraries/libressl/tests/server1-rsa.pem @@ -0,0 +1,50 @@ +subject= CN = LibreSSL Test Server 1 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoHzMA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzdaFw0zMTEyMjUxNDQwMzdaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +U2VydmVyIDEgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnvyt +i0uA2qaFltVb8+PElYk84AnjY0WZDcGtKSMCAYTD857fO2V4S/wpJ9ZMt8kBKQ29 +D2Glkkhc/HPpb7wJcAUT++aZ/PbOtuzOHzdxheOolfZ6aw+qCSiVlcflKfMp7VPL +swimqKpm6atl2aSqldKfmGzjhAAPiTXbzUjh9pbTfO8ykdn/6AqP7ju3+4sseMPL +seNq1wstWRdiHm0P/BoJn4lwDe7QTSp1AxMqDTz5BiO+UjCW2oTsOFfo/hhslQf5 +qv7uPLrz/VWiEojQP5RzfcnVwplUgTvtaOkXxZeOH7VkKS1v8W506/h3RIKj0X8Y +JDLuIPqSAPNLWGyH4wIDAQABo2AwXjAdBgNVHQ4EFgQUFJPGTfe+ULC/anJ4fCVz +DXA0JI4wHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAGP5hYyAYzlj +YCV24ApNPb+mNEMHu1SL1MgDXJOTWZMFOvuYcibtmcVIfwpM4+UpC7cRqPRjBEqm +NdLbJi4jGzQDNOcI7OZCCx6oKvAhjMofpb42Iq4bDuBqlhHRXvYnO30y0yRbSGXt +GvKvkNKOSXUnY1UtcBAN5szcyFk30xQK+f/2VqJguvjsTquFV+piqFyq91ICyIeQ +1gjTn1N2/SkmYpwZdyf0HqSjyqJ0FG4xiW6T0HmX1QI651Kux49vLel7ySxzGY+6 +axnPilTYx/7pkciGk5ckLdujpXsDPhC+E2hdoee494c5NvX/uibYhigLU/gHK/ZP +YisY8ihnPl8= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCe/K2LS4DapoWW +1Vvz48SViTzgCeNjRZkNwa0pIwIBhMPznt87ZXhL/Ckn1ky3yQEpDb0PYaWSSFz8 +c+lvvAlwBRP75pn89s627M4fN3GF46iV9nprD6oJKJWVx+Up8yntU8uzCKaoqmbp +q2XZpKqV0p+YbOOEAA+JNdvNSOH2ltN87zKR2f/oCo/uO7f7iyx4w8ux42rXCy1Z +F2IebQ/8GgmfiXAN7tBNKnUDEyoNPPkGI75SMJbahOw4V+j+GGyVB/mq/u48uvP9 +VaISiNA/lHN9ydXCmVSBO+1o6RfFl44ftWQpLW/xbnTr+HdEgqPRfxgkMu4g+pIA +80tYbIfjAgMBAAECggEBAJDm9PkW6KrfyLPPZA5mUl6EBWKgQInS/gsmsT7j9EkU +C1A4RXcqJTkD6zKuw59h6NfU+LJTKgeoQm+o6WJ3/BYH2s3kwAZpn7/jFn4nFyWT +d6yuR6baUPwl7CfmV3wjbtwqWmajhNoG7OMd3yc9SGhi3iibXcWKFJ7W4q04NxJ5 +txswRddLYMFUeJxPBdImlyibyUIWaYFid4O2kozTQWpyJld5SP4+YQObb6sBJuvN +wR53eaRGb0OaUGppglGlWTahIADBjbhf0zd9YiUjvums/cjx2goHzQqt4rIj1Pid +I3duu/kw7AsuRlvmhk02Cu4Ixr8hljbeo2L7UAP+4BkCgYEAzVq8Fqi/5IVdjl0H +FwvS9NX3HFFzdixtI2p/jCQ721Kxpf73zvRpMG/YZL3vBt4sXT7WpJZZsKrYogL7 +8s/dG7p/GpzSnvJKQfT6Ko+jnv24MEIoqMx+Smd+nJJJ0KzZRvrqzcF+wsicmKnN +y/4t8T1DqSm4WxDyuy/uDozqCP0CgYEAxjJ9GJha40sHlY4sOTaJqapN6va/t70/ +iRj+Mt9Bm1O41PBgu+SMADGukrjL5DYp53QRGhyqb2PWmZsGYvftPZNq5b3pzKPo +8jiP9AxYDt/GLO3x/GppiywOxHD8CV19BDVqWcBkV1ATu2kkmokDbq+g94xnMBzN +nURtfL5Hml8CgYAMeJIrnhvpOOAxoRypHaK2E7hqE9g7OP93wyPz0s9/xknbltxd +ySIKOwCdPZuigyOWlhZa8HaJ8BYv4JaEbHM1F+JYL2XrGTPBRatbolWBdk8VPy9Q +8PpKcnaR86Bf999KHDreO/4CvkQkUUuaM9l+aQYO4+W6QhE7pPGEGLKt0QKBgCL2 +exzgm3/nF3JpfyGknkpA0bf2SUG3b8LWltkQizlEXqGpudbLbWsHWJ1nXghnCaNb +1Tx+/A3kVdIJB+pjhAVNwRjAFMNV0t0P300U9F/DV+lLHFoDx5SWdBBxQfTA+jHI +3nbwuoKwjJqN5LgiHWnkL4gby4QwQJFSpeHQiz8PAoGBAJaur4aFaSlgGAiKJX4/ +Om4AedImBgFsVKf44xx5pDwEcqLeEwRBxa0r5Sftqsrz+Ck60hR/MWCwJEBll5PV +MJtOHBb2bINFhLOqV1WoSkSoKEhtMvFnLbWGBi5gYHC4+lYuyQqD/vu3sxe5IT9C +PKgUgKV32Z7KBpDuFGtGmiDb +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/server2-ecdsa-chain.pem b/Libraries/libressl/tests/server2-ecdsa-chain.pem new file mode 100644 index 000000000..494d2ea20 --- /dev/null +++ b/Libraries/libressl/tests/server2-ecdsa-chain.pem @@ -0,0 +1,26 @@ +subject= CN = LibreSSL Test Server 2 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIDEAABMAoGCCqGSM49BAMCMC4xLDAqBgNVBAMMI0xpYnJl +U1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTEwMDEwMTAwMDAwMFoX +DTIwMDEwMTAwMDAwMFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBTZXJ2ZXIg +MiBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJOTftmDhBMSS23a+sRO +3Zr43RUwtdJvNfKhpHKRbBLIttBkbI1wWCgufMLCJXhL6pSpCeT/C9ioFks2JMg7 +CPCjYDBeMB0GA1UdDgQWBBSCtBk04EXYNjiFaaTcJumL0BFylTAfBgNVHSMEGDAW +gBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQE +AwIHgDAKBggqhkjOPQQDAgNIADBFAiEAqnQ+TRgMZRys3z3olZysrnP0d6XIdfgv +XvlXRaM0s/QCIHdrTx/IPfJSvo0rDN08CJfbO0NBOc9PFsnDRUKsxJd4 +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/server2-ecdsa.pem b/Libraries/libressl/tests/server2-ecdsa.pem new file mode 100644 index 000000000..2f49df993 --- /dev/null +++ b/Libraries/libressl/tests/server2-ecdsa.pem @@ -0,0 +1,18 @@ +subject= CN = LibreSSL Test Server 2 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIDEAABMAoGCCqGSM49BAMCMC4xLDAqBgNVBAMMI0xpYnJl +U1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIEVDRFNBMB4XDTEwMDEwMTAwMDAwMFoX +DTIwMDEwMTAwMDAwMFowJzElMCMGA1UEAwwcTGlicmVTU0wgVGVzdCBTZXJ2ZXIg +MiBFQ0RTQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJOTftmDhBMSS23a+sRO +3Zr43RUwtdJvNfKhpHKRbBLIttBkbI1wWCgufMLCJXhL6pSpCeT/C9ioFks2JMg7 +CPCjYDBeMB0GA1UdDgQWBBSCtBk04EXYNjiFaaTcJumL0BFylTAfBgNVHSMEGDAW +gBQXVj1v/EpXEjlCygJygatQDeTCCDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQE +AwIHgDAKBggqhkjOPQQDAgNIADBFAiEAqnQ+TRgMZRys3z3olZysrnP0d6XIdfgv +XvlXRaM0s/QCIHdrTx/IPfJSvo0rDN08CJfbO0NBOc9PFsnDRUKsxJd4 +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgxkOt2jb6kQC1ZaUa +MLSz0lyS0YQtqChoyAvJ7yQf3FahRANCAASTk37Zg4QTEktt2vrETt2a+N0VMLXS +bzXyoaRykWwSyLbQZGyNcFgoLnzCwiV4S+qUqQnk/wvYqBZLNiTIOwjw +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/server2-rsa-chain.pem b/Libraries/libressl/tests/server2-rsa-chain.pem new file mode 100644 index 000000000..5bb660f45 --- /dev/null +++ b/Libraries/libressl/tests/server2-rsa-chain.pem @@ -0,0 +1,44 @@ +subject= CN = LibreSSL Test Server 2 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIDEAABMA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNVBAMMIUxp +YnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0xMDAxMDEwMDAwMDBa +Fw0yMDAxMDEwMDAwMDBaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3QgU2VydmVy +IDIgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu08owc3HqHu2 ++92bKDs/VCVjkGMZSVOrdAXYEKf9WQ6cGxiowjJy391szSd5bW/Yf7hbNhctr29G +8oIj0wsMfz3lxuHDYISt8uAjbjqFiZTNfBeg7PVE9aDWXqaophcq4DT2ygv9O190 +09RxTJD6PdclUtQNYZHr3c7kP2AdeBWWVPAmKISDSEkjXqc0x9LEtm7UA/0WAtKM +NUXUb/ZNBu90j7gRpjN6VyfaqJMdoDR31s7QXivL5hr4x0M0Y1ihN1/cHA5Qjb0s +6t8w6H2b0xtvJgO5N3ZUAVclAO3MsVRqr04aAyxcJ47qOkWPbh9OqaFyZFdl7L2r +UTLloQNkcwIDAQABo2AwXjAdBgNVHQ4EFgQUrDgWmmX6bVZt4Z7SvCSXEfJMoZQw +HwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/BAIwADAO +BgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBANbQG/fAGsV+J+cmEIlg +9i5c44hpr3BAXn5QYMbV9OQ8M9Rq8cZx/EkwNlCfPnQph2PqN2tZNstBnlL90rNq +pOj1Ee+ppemeJrHKFuEncytGHbgqjRLgi9n0vR5RF1I7dJvRlPugpf/FxeMC/7f2 +qDDfdMsvmu/+qWBMb+U5yPLXlibGr7nf7B3t9ZBtku5flP3OOmipIjFpLOmvu06Z +9fac0JHDRvBQCemvIbSIa8Sz6UVJ1hKTjaN+lqc7e5tgbovNqjgFiLx0lQrfBmg9 +tnNhoaEuwwyPNIVLUK3J1Q4lv/m9fX7BVmL5C56AexwtD/jupdXe2utjFx6YXrKG +nxU= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/server2-rsa.pem b/Libraries/libressl/tests/server2-rsa.pem new file mode 100644 index 000000000..ed7389a43 --- /dev/null +++ b/Libraries/libressl/tests/server2-rsa.pem @@ -0,0 +1,50 @@ +subject= CN = LibreSSL Test Server 2 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIDEAABMA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNVBAMMIUxp +YnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0xMDAxMDEwMDAwMDBa +Fw0yMDAxMDEwMDAwMDBaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3QgU2VydmVy +IDIgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu08owc3HqHu2 ++92bKDs/VCVjkGMZSVOrdAXYEKf9WQ6cGxiowjJy391szSd5bW/Yf7hbNhctr29G +8oIj0wsMfz3lxuHDYISt8uAjbjqFiZTNfBeg7PVE9aDWXqaophcq4DT2ygv9O190 +09RxTJD6PdclUtQNYZHr3c7kP2AdeBWWVPAmKISDSEkjXqc0x9LEtm7UA/0WAtKM +NUXUb/ZNBu90j7gRpjN6VyfaqJMdoDR31s7QXivL5hr4x0M0Y1ihN1/cHA5Qjb0s +6t8w6H2b0xtvJgO5N3ZUAVclAO3MsVRqr04aAyxcJ47qOkWPbh9OqaFyZFdl7L2r +UTLloQNkcwIDAQABo2AwXjAdBgNVHQ4EFgQUrDgWmmX6bVZt4Z7SvCSXEfJMoZQw +HwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/BAIwADAO +BgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBANbQG/fAGsV+J+cmEIlg +9i5c44hpr3BAXn5QYMbV9OQ8M9Rq8cZx/EkwNlCfPnQph2PqN2tZNstBnlL90rNq +pOj1Ee+ppemeJrHKFuEncytGHbgqjRLgi9n0vR5RF1I7dJvRlPugpf/FxeMC/7f2 +qDDfdMsvmu/+qWBMb+U5yPLXlibGr7nf7B3t9ZBtku5flP3OOmipIjFpLOmvu06Z +9fac0JHDRvBQCemvIbSIa8Sz6UVJ1hKTjaN+lqc7e5tgbovNqjgFiLx0lQrfBmg9 +tnNhoaEuwwyPNIVLUK3J1Q4lv/m9fX7BVmL5C56AexwtD/jupdXe2utjFx6YXrKG +nxU= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7TyjBzceoe7b7 +3ZsoOz9UJWOQYxlJU6t0BdgQp/1ZDpwbGKjCMnLf3WzNJ3ltb9h/uFs2Fy2vb0by +giPTCwx/PeXG4cNghK3y4CNuOoWJlM18F6Ds9UT1oNZepqimFyrgNPbKC/07X3TT +1HFMkPo91yVS1A1hkevdzuQ/YB14FZZU8CYohINISSNepzTH0sS2btQD/RYC0ow1 +RdRv9k0G73SPuBGmM3pXJ9qokx2gNHfWztBeK8vmGvjHQzRjWKE3X9wcDlCNvSzq +3zDofZvTG28mA7k3dlQBVyUA7cyxVGqvThoDLFwnjuo6RY9uH06poXJkV2XsvatR +MuWhA2RzAgMBAAECggEAc5ApQzkkv+xkPwzAl5fGQLI4tXKOvVDj7VdVsSEUDAgZ +hBY4uGfLvBau8/wwzLY+yr4BeGPgieaLzT9BvwmIElEsHQJZOolhkQF8mpt8nB+0 +j6U8YjYI78rlt8v3LVIJ3/6NbKbs+96vA6qEpIql+dVtb6bpApO3BEiLRhaU1+ra +pi5YbF56S3XlUFL6H46hpNTUxOqbb6toZ/2rr1nscu4jkQhL8u/KS5Uz1Y7RW3zd +A3U4rbxXnM8SVZrRuWsN1DRL5CpAOdGGiVhew46vAxZU8iX6rODrRaRCp+Gbnoll +x/ubMMrBrE4WpCY5orb41FPb4U6raY9ZZzTGPuC9YQKBgQDs0LrDy8kh3V7wsIwn +6vMT9MD2Olpl6zwSyQJ0C04u+hGNur3L6intg78TSRqZ7ZKK7CspPy9JCGTYztTG +vFbXy2vahCFlI2G3lfZj2nS2D+UNSmo2pdpBtuk/iKj67pFAlaa8C3OQ8MXjldQn +3QPANsCo276t0E9SmFcbJYJVCwKBgQDKe7sfdg0tQr9xsBeDuSxRJQOrtWeTmXm6 +zcPKRX8avWr5Ag6w4/BX/RxGZkD4brV5LaK6Qsbwl8v8aNe8Hv4yBQFdW0IMP8mB +v4kVaNEGxoJE4fnKk1wS22TQvX5fxWPGZhOWQ1sgIqp3Dzvky0nalK7Ru0gRA4gS +Jl0a4Sp/OQKBgQCHwuW/B53n5yPdcij3XW87Go5g2nUmhqPq1QeuBSkuLzhO+yaB +t12QB35MDRXN9u+S6u+XdtyhzskZrgE3aZOTpM/Q9vy6IX2MpNEaz4snMJeMdgPM +DmrAT58KSEsviAMHdoOevCXlitK3tRZqP/89e2YZp9h5hrlizWjqbCd6nwKBgQCS +XFWqLB7iNHlFqE+W+2a5UNQSbhHscue2y71WnF1/6qNEUuRjoJ++OksR6B/Wc8/h +Q8d4c4RxrIfab75hUNXVOiD+ZlSbng/+JYDlZNqS1zKar+1rLJFFYCjDafXLLFcu +teI6n31jASvO28gjXX6I7ShgmctB4ReeZvSt1UxuoQKBgHQ/0fA3owx9kDRA41Hu +a+npibal0F2JOxn0xiwgW3JcH/EkcSIvUELm8Kjl3GBxf0y9Osu0uf3cSqW9K9+z +CRpwZmFq+q3HFN6FYHYI6oVvPKIljDhmkvw9HyexXFLRKNs1z2b7Noz2H7ysE0cb +1sAZitEjace2/eAx/wWr2dq0 +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/server3-ecdsa-chain.pem b/Libraries/libressl/tests/server3-ecdsa-chain.pem new file mode 100644 index 000000000..03f3373d3 --- /dev/null +++ b/Libraries/libressl/tests/server3-ecdsa-chain.pem @@ -0,0 +1,26 @@ +subject= CN = LibreSSL Test Server 3 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBqjCCAVGgAwIBAgIJAOVssaaTYoH5MAkGByqGSM49BAEwLjEsMCoGA1UEAwwj +TGlicmVTU0wgVGVzdCBJbnRlcm1lZGlhdGUgQ0EgRUNEU0EwHhcNMjExMjI3MTQ0 +MDQwWhcNMzExMjI1MTQ0MDQwWjAnMSUwIwYDVQQDDBxMaWJyZVNTTCBUZXN0IFNl +cnZlciAzIEVDRFNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0pRqRW+PDenx +cp+5za1pFDdECxXPXZY7LUPoXxens1lPSM2diexVMdLw1kEbVkOZ50s1X32vQnTa +TVpovmwna6NgMF4wHQYDVR0OBBYEFCXbw+Fdv+OWDOU163ujSYbdJZx3MB8GA1Ud +IwQYMBaAFBdWPW/8SlcSOULKAnKBq1AN5MIIMAwGA1UdEwEB/wQCMAAwDgYDVR0P +AQH/BAQDAgeAMAkGByqGSM49BAEDSAAwRQIhAMt01G90LOiCVRIcodKP1nsOg3oY +kX8VHUPk9myD52KZAiBu32mh/fgaWsR/lbo2dyGJQHKkmHNt9Wy8hOQ9eGO91A== +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA ECDSA +issuer= CN = LibreSSL Test Root CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBrDCCAVOgAwIBAgIJAOVssaaTYoH3MAkGByqGSM49BAEwJjEkMCIGA1UEAwwb +TGlicmVTU0wgVGVzdCBSb290IENBIEVDRFNBMB4XDTIxMTIyNzE0NDA0MFoXDTMx +MTIyNTE0NDA0MFowLjEsMCoGA1UEAwwjTGlicmVTU0wgVGVzdCBJbnRlcm1lZGlh +dGUgQ0EgRUNEU0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWRQbJh4aHPzHq +LOAmosW/o83bTpm3Sj1VxM44StmG7c1nnFM/+gS8rp2bVSgjWZQzRtZqGVGJgzbk +7/M1m3x3o2MwYTAdBgNVHQ4EFgQUF1Y9b/xKVxI5QsoCcoGrUA3kwggwHwYDVR0j +BBgwFoAUtvkat4UdcUEipt6L/PBgEFYH6AwwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwCQYHKoZIzj0EAQNIADBFAiBE4NiOdv/XRN3WWMnkE5QccvC6 +VThoIQRyBf4I97cRPQIhAK18dvwrLuOOfbhWMdkpNCddMkWZHxS7traw/8+s7OUU +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/server3-ecdsa.pem b/Libraries/libressl/tests/server3-ecdsa.pem new file mode 100644 index 000000000..98950aabb --- /dev/null +++ b/Libraries/libressl/tests/server3-ecdsa.pem @@ -0,0 +1,18 @@ +subject= CN = LibreSSL Test Server 3 ECDSA +issuer= CN = LibreSSL Test Intermediate CA ECDSA +-----BEGIN CERTIFICATE----- +MIIBqjCCAVGgAwIBAgIJAOVssaaTYoH5MAkGByqGSM49BAEwLjEsMCoGA1UEAwwj +TGlicmVTU0wgVGVzdCBJbnRlcm1lZGlhdGUgQ0EgRUNEU0EwHhcNMjExMjI3MTQ0 +MDQwWhcNMzExMjI1MTQ0MDQwWjAnMSUwIwYDVQQDDBxMaWJyZVNTTCBUZXN0IFNl +cnZlciAzIEVDRFNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0pRqRW+PDenx +cp+5za1pFDdECxXPXZY7LUPoXxens1lPSM2diexVMdLw1kEbVkOZ50s1X32vQnTa +TVpovmwna6NgMF4wHQYDVR0OBBYEFCXbw+Fdv+OWDOU163ujSYbdJZx3MB8GA1Ud +IwQYMBaAFBdWPW/8SlcSOULKAnKBq1AN5MIIMAwGA1UdEwEB/wQCMAAwDgYDVR0P +AQH/BAQDAgeAMAkGByqGSM49BAEDSAAwRQIhAMt01G90LOiCVRIcodKP1nsOg3oY +kX8VHUPk9myD52KZAiBu32mh/fgaWsR/lbo2dyGJQHKkmHNt9Wy8hOQ9eGO91A== +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTWRMClyUOn11mX5s +hTTIQT+3BeauAjrTvKMy5RryWtyhRANCAATSlGpFb48N6fFyn7nNrWkUN0QLFc9d +ljstQ+hfF6ezWU9IzZ2J7FUx0vDWQRtWQ5nnSzVffa9CdNpNWmi+bCdr +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/server3-rsa-chain.pem b/Libraries/libressl/tests/server3-rsa-chain.pem new file mode 100644 index 000000000..e40c98289 --- /dev/null +++ b/Libraries/libressl/tests/server3-rsa-chain.pem @@ -0,0 +1,44 @@ +subject= CN = LibreSSL Test Server 3 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoH0MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzdaFw0zMTEyMjUxNDQwMzdaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +U2VydmVyIDMgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyqw4 +GSS7/WAR0VYbqFTltj9Cv17m+RuztM1jiJq+MU0Gscbx59NFPt8UFevNsMzWNmAK +qkioEMVJxXzSUDBjXjLesDt/+VTjR46z16fje3MhGmWa8lDt7hpuHwDF80dg3rZa +kVEcgKvd6LODTucgE7l07DzMb8qAdRp1SDXIFECO0wLJewkf2CihmNukTxQhI0d+ +XPZTYe3cyMelj8KpCXCXOVXKnXI+BWnYMHC1Op4S9z90xiVBNgQ+Vmg2K9NFifzT +ZyKIWsERq80rp1s+JmxmzA/vBRlsbj/Ec0h2kF4IavGtHwvAvdvIPV7AG/dIxwlT +VnHZkPDuLK0H396wmwIDAQABo2AwXjAdBgNVHQ4EFgQUSuP+QN+526Pxw/LGBTqP +WJpWGvwwHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFBJ0mO7dpSN +euxoh2DJghVfqQB4ladEroDZJkJEDuDkY3SjC+WB/lJowBVPC2QkzjTZt/J4B0Om +6irtKUC8jQ7aqMBfESu/s//GEU4kwlvlJN/Z0nLOh1YEeCwbkavFDy/X62iZ9XvJ +gjLVVzaXKWGrgdJedHx9Di04rU9jME5qfpXZI50u8grZccpUuTTqpZBiGjFRda2j +nJhgPBrn9/ityYaOrif8taR+QM6AETvEpJWo+I/iQ7vATmxHuq6y+0Sza5j9wGH/ +begJs9H890AiwO2bbUi1ehNj7NHZHySWNJlzBerwOQv7Zo8j+kHBop82ABsb/Xet +kgn7bdkfKoI= +-----END CERTIFICATE----- +subject= CN = LibreSSL Test Intermediate CA RSA +issuer= CN = LibreSSL Test Root CA RSA +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIJAOVssaaTYoHyMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV +BAMMGUxpYnJlU1NMIFRlc3QgUm9vdCBDQSBSU0EwHhcNMjExMjI3MTQ0MDM3WhcN +MzExMjI1MTQ0MDM3WjAsMSowKAYDVQQDDCFMaWJyZVNTTCBUZXN0IEludGVybWVk +aWF0ZSBDQSBSU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD151AI +I+W9MrEP3dO0PEjg6L9E1R6+CG6u0LT3Jobc/rG2RXqKLasEaXoBWYiJoTImVxFT +wtrY+IDDTaEV4/4RGII1fY8Js7v5NpwoEh15jCoJ6/qDjKd4y1s1M48PlWYNNRmv +OBKRIu3Fz7scUa1RSBCp1bZeHbq/V5SzG419nDq2xpyuUrwmfBhDZTH+kUwBNGn8 +XVRFCRJQVP3qEAH02Zai2emSVj13KrhEWMtNyA8fa34GIuV23Q40RKW3jUgGBF+D +5jPNN8EZCj34nvvbjCCBs7cxZvD4F/MzGbatKpNmNOKXKibeg/xCq8B/F1uzHcl3 +IzJuViNtQ3RjQ/1pAgMBAAGjYzBhMB0GA1UdDgQWBBQ2oaFa//6a3ZNBNV0NlN3n +A9jiZjAfBgNVHSMEGDAWgBQ+S/x79Kw0KqURKAHyiOhdj/8V0TAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAcok2oSct +BOkm75qA8+4eUilGxTaqFPCqY8fk8MKNRKNNzaqirPaLJW62mZaxRHOn1Bw9uzL3 +jgz2PaTwA7n5GpKs3r5JLk8BdtRyeqMLmqJVJKKuu4GtJLCA8jhQm+XNA1Z324hg +kVeBHLPpLKvQxb+0lmbRBORq/OtMirq2yK8OlF2USrfQx0jmhSvvLpWyA0hhAXRS +gg1ds9aL57dELvk6gR7Unob+J0O2Xq3FRwz2O1k9fF86a0qrWUkxcnAjobC2BczC +7Fe5B194LgrX2U4IIrzwgJ19kmtrb1Qol2okECxomTYsbQY36sBs+LOKxSuiagu6 +ZgJtfcNeVMglYQ== +-----END CERTIFICATE----- diff --git a/Libraries/libressl/tests/server3-rsa.pem b/Libraries/libressl/tests/server3-rsa.pem new file mode 100644 index 000000000..256528ae3 --- /dev/null +++ b/Libraries/libressl/tests/server3-rsa.pem @@ -0,0 +1,50 @@ +subject= CN = LibreSSL Test Server 3 RSA +issuer= CN = LibreSSL Test Intermediate CA RSA +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIJAOVssaaTYoH0MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV +BAMMIUxpYnJlU1NMIFRlc3QgSW50ZXJtZWRpYXRlIENBIFJTQTAeFw0yMTEyMjcx +NDQwMzdaFw0zMTEyMjUxNDQwMzdaMCUxIzAhBgNVBAMMGkxpYnJlU1NMIFRlc3Qg +U2VydmVyIDMgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyqw4 +GSS7/WAR0VYbqFTltj9Cv17m+RuztM1jiJq+MU0Gscbx59NFPt8UFevNsMzWNmAK +qkioEMVJxXzSUDBjXjLesDt/+VTjR46z16fje3MhGmWa8lDt7hpuHwDF80dg3rZa +kVEcgKvd6LODTucgE7l07DzMb8qAdRp1SDXIFECO0wLJewkf2CihmNukTxQhI0d+ +XPZTYe3cyMelj8KpCXCXOVXKnXI+BWnYMHC1Op4S9z90xiVBNgQ+Vmg2K9NFifzT +ZyKIWsERq80rp1s+JmxmzA/vBRlsbj/Ec0h2kF4IavGtHwvAvdvIPV7AG/dIxwlT +VnHZkPDuLK0H396wmwIDAQABo2AwXjAdBgNVHQ4EFgQUSuP+QN+526Pxw/LGBTqP +WJpWGvwwHwYDVR0jBBgwFoAUNqGhWv/+mt2TQTVdDZTd5wPY4mYwDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFBJ0mO7dpSN +euxoh2DJghVfqQB4ladEroDZJkJEDuDkY3SjC+WB/lJowBVPC2QkzjTZt/J4B0Om +6irtKUC8jQ7aqMBfESu/s//GEU4kwlvlJN/Z0nLOh1YEeCwbkavFDy/X62iZ9XvJ +gjLVVzaXKWGrgdJedHx9Di04rU9jME5qfpXZI50u8grZccpUuTTqpZBiGjFRda2j +nJhgPBrn9/ityYaOrif8taR+QM6AETvEpJWo+I/iQ7vATmxHuq6y+0Sza5j9wGH/ +begJs9H890AiwO2bbUi1ehNj7NHZHySWNJlzBerwOQv7Zo8j+kHBop82ABsb/Xet +kgn7bdkfKoI= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDKrDgZJLv9YBHR +VhuoVOW2P0K/Xub5G7O0zWOImr4xTQaxxvHn00U+3xQV682wzNY2YAqqSKgQxUnF +fNJQMGNeMt6wO3/5VONHjrPXp+N7cyEaZZryUO3uGm4fAMXzR2DetlqRURyAq93o +s4NO5yATuXTsPMxvyoB1GnVINcgUQI7TAsl7CR/YKKGY26RPFCEjR35c9lNh7dzI +x6WPwqkJcJc5Vcqdcj4FadgwcLU6nhL3P3TGJUE2BD5WaDYr00WJ/NNnIohawRGr +zSunWz4mbGbMD+8FGWxuP8RzSHaQXghq8a0fC8C928g9XsAb90jHCVNWcdmQ8O4s +rQff3rCbAgMBAAECggEAAoOiaoVvI5SGhA9KZosvElS0kkUuHlb+oraNjotE4r2u +4JO0Ooj/aelAiYkUUyYnXiNQ3o3qL9MSuDV1MnN3OBrvckY6rzAjZabaiklV5Bko +hvhNtMXWPcbsKMxMqFjxVbHza6wS63G2XgWkEl2Bo10Am1Ghw51CfLFoVQ39vmqM +8xKqZBZRwRUNk/2ccNhG5crUOX9+wQJSVjZCTgevjCJVVsFX9NLsHsx7G1wtE580 +AuFb9JEe66QNrtpTbKQP61W8YiRKQHT5uAAL0X9o88d2rpjGAcpJ8214aGH5P1HH +oUjL7mZceYuVeWvAMwLFFmPbPZuj3Ricgo1OIkKyyQKBgQDtNNXod5GzJyHOUrFR +rijyHhS81sOeDOhTbc1Cx8eFNH/svGATAU01HqgFRZpeJPHsAVYwVizfyqp/CESk +EFKTkMqRTat8Pkk+BtAGZD5fEBejl1fwRiBF9bTnk+u6q1WvBsQ0Bngf3v1CYGuq +rvb57AvhkCsEMjWs1YplBLwdVwKBgQDauvNslanbFstrWVBJqxV1iEaWmN1Lr//C +fwCFU8rH8VEvp+JJCICu7sE5Te+1TF/ASEs/bCrsW51YXjH30z3De1oFrjFVjwOU +XFMqcaTCX5Fjxv739LmgGuO2MCrItmveQHYkpTzCl6/p/pI4I1QJN0S5a/FaBNcW +x5tV2Ks4XQKBgHCCiBdsZ1pPbFR9moeAkQFOTU3InB5iRuwTf7F2Kue+oBK8wuEg +0+snMFDX08Flyq3DcIsaxMwdR8NbO5uJ9nDx03MaIQWcUYcvGgp+D6ttaZj5lwdr +a7FjOrxAyCXRUKHlFrkKfH25eey66TabKKAgWv5RMGYcHqNs4ejKVyOfAoGALqUf +tFBWYLqDtujdDljFwsLFCuieiL2HtVqQKd6sp+b2gUs0Ho8JokSYQDg2nlsjMEY6 +hdPzc2Q2Mdoknc0WptFvaTa0nqJZCRKHSc3ibPEkeDq/tPEjhNk3JmsvNI5ygnsM +ttPmGTlv8l6vn/kouq5moYQ7fA78L4dxwOTr3qECgYBNuIf4vQq8WEkt0uSTJXom +UQVZglJu61NVGzR//lyukQB7/HrdEMB+JYJfev0o1GxLx1RV8rTVaeDJkUJjwn/h +qpqiLjJKF328oOuQdP3dH6AavH9r7gUOByOuxXgzZNbhtyNCrStAGOfX2xUxRZyZ +l0+QtrqbPtB4VSfZ0j+imw== +-----END PRIVATE KEY----- diff --git a/Libraries/libressl/tests/servertest.bat b/Libraries/libressl/tests/servertest.bat new file mode 100644 index 000000000..815fbb0b3 --- /dev/null +++ b/Libraries/libressl/tests/servertest.bat @@ -0,0 +1,14 @@ +@echo off +setlocal enabledelayedexpansion +REM servertest.bat + +set servertest_bin=%1 +set servertest_bin=%servertest_bin:/=\% +if not exist %servertest_bin% exit /b 1 + +%servertest_bin% %srcdir%\server.pem %srcdir%\server.pem %srcdir%\ca.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + +endlocal diff --git a/Libraries/libressl/tests/servertest.c b/Libraries/libressl/tests/servertest.c new file mode 100644 index 000000000..d572d1452 --- /dev/null +++ b/Libraries/libressl/tests/servertest.c @@ -0,0 +1,209 @@ +/* $OpenBSD: servertest.c,v 1.9 2023/07/11 11:52:35 tb Exp $ */ +/* + * Copyright (c) 2015, 2016, 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +#include +#include +#include + +const SSL_METHOD *tls_legacy_method(void); + +char *server_ca_file; +char *server_cert_file; +char *server_key_file; + +static unsigned char sslv2_client_hello_tls10[] = { + 0x80, 0x6a, 0x01, 0x03, 0x01, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x39, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x35, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x33, + 0x00, 0x00, 0x32, 0x00, 0x00, 0x2f, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x66, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x63, 0x00, 0x00, 0x62, + 0x00, 0x00, 0x61, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x09, 0x00, 0x00, 0x65, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x60, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x03, 0xdd, 0xb6, 0x59, 0x26, + 0x46, 0xe6, 0x79, 0x77, 0xf4, 0xec, 0x42, 0x76, + 0xc8, 0x73, 0xad, 0x9c, +}; + +static unsigned char sslv2_client_hello_tls12[] = { + 0x80, 0xcb, 0x01, 0x03, 0x03, 0x00, 0xa2, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0xa5, 0x00, 0x00, + 0xa3, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x9f, 0x00, + 0x00, 0x6b, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x69, + 0x00, 0x00, 0x68, 0x00, 0x00, 0x39, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x37, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x88, 0x00, 0x00, 0x87, 0x00, 0x00, 0x86, + 0x00, 0x00, 0x85, 0x00, 0x00, 0x9d, 0x00, 0x00, + 0x3d, 0x00, 0x00, 0x35, 0x00, 0x00, 0x84, 0x00, + 0x00, 0xa4, 0x00, 0x00, 0xa2, 0x00, 0x00, 0xa0, + 0x00, 0x00, 0x9e, 0x00, 0x00, 0x67, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x33, 0x00, 0x00, 0x32, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x9a, 0x00, 0x00, + 0x99, 0x00, 0x00, 0x98, 0x00, 0x00, 0x97, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x44, 0x00, 0x00, 0x43, + 0x00, 0x00, 0x42, 0x00, 0x00, 0x9c, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x96, 0x00, + 0x00, 0x41, 0x00, 0x00, 0x07, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x16, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0xff, 0x1d, 0xfd, 0x90, + 0x03, 0x61, 0x3c, 0x5a, 0x22, 0x83, 0xed, 0x11, + 0x85, 0xf4, 0xea, 0x36, 0x59, 0xd9, 0x1b, 0x27, + 0x22, 0x01, 0x14, 0x07, 0x66, 0xb2, 0x24, 0xf5, + 0x4e, 0x7d, 0x9d, 0x9c, 0x52, +}; + +struct server_hello_test { + const unsigned char *desc; + unsigned char *client_hello; + const size_t client_hello_len; + const SSL_METHOD *(*ssl_method)(void); + const long ssl_clear_options; + const long ssl_set_options; + int accept_fails; +}; + +static struct server_hello_test server_hello_tests[] = { + { + .desc = "TLSv1.0 in SSLv2 record", + .client_hello = sslv2_client_hello_tls10, + .client_hello_len = sizeof(sslv2_client_hello_tls10), + .ssl_method = tls_legacy_method, + .ssl_clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, + .ssl_set_options = 0, + .accept_fails = 1, + }, + { + .desc = "TLSv1.2 in SSLv2 record", + .client_hello = sslv2_client_hello_tls12, + .client_hello_len = sizeof(sslv2_client_hello_tls12), + .ssl_method = tls_legacy_method, + .ssl_clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, + .ssl_set_options = 0, + .accept_fails = 1, + }, +}; + +#define N_SERVER_HELLO_TESTS \ + (sizeof(server_hello_tests) / sizeof(*server_hello_tests)) + +static int +server_hello_test(int testno, struct server_hello_test *sht) +{ + BIO *rbio = NULL, *wbio = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int ret = 1; + + fprintf(stderr, "Test %d - %s\n", testno, sht->desc); + + if ((rbio = BIO_new_mem_buf(sht->client_hello, + sht->client_hello_len)) == NULL) { + fprintf(stderr, "Failed to setup rbio\n"); + goto failure; + } + if ((wbio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "Failed to setup wbio\n"); + goto failure; + } + + if ((ssl_ctx = SSL_CTX_new(sht->ssl_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + goto failure; + } + + if (SSL_CTX_use_certificate_file(ssl_ctx, server_cert_file, + SSL_FILETYPE_PEM) != 1) { + fprintf(stderr, "Failed to load server certificate"); + goto failure; + } + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key_file, + SSL_FILETYPE_PEM) != 1) { + fprintf(stderr, "Failed to load server private key"); + goto failure; + } + + SSL_CTX_set_dh_auto(ssl_ctx, 1); + SSL_CTX_set_ecdh_auto(ssl_ctx, 1); + + SSL_CTX_clear_options(ssl_ctx, sht->ssl_clear_options); + SSL_CTX_set_options(ssl_ctx, sht->ssl_set_options); + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + goto failure; + } + + BIO_up_ref(rbio); + BIO_up_ref(wbio); + SSL_set_bio(ssl, rbio, wbio); + + if (SSL_accept(ssl) != 0) { + if (sht->accept_fails) + goto done; + fprintf(stderr, "SSL_accept() returned non-zero\n"); + ERR_print_errors_fp(stderr); + goto failure; + } + + done: + ret = 0; + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + BIO_free(rbio); + BIO_free(wbio); + + return (ret); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + if (argc != 4) { + fprintf(stderr, "usage: %s keyfile certfile cafile\n", + argv[0]); + exit(1); + } + + server_key_file = argv[1]; + server_cert_file = argv[2]; + server_ca_file = argv[3]; + + SSL_library_init(); + SSL_load_error_strings(); + + for (i = 0; i < N_SERVER_HELLO_TESTS; i++) + failed |= server_hello_test(i, &server_hello_tests[i]); + + return (failed); +} diff --git a/Libraries/libressl/tests/servertest.sh b/Libraries/libressl/tests/servertest.sh new file mode 100644 index 000000000..f1efeb058 --- /dev/null +++ b/Libraries/libressl/tests/servertest.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +servertest_bin=./servertest +if [ -e ./servertest.exe ]; then + servertest_bin=./servertest.exe +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +$servertest_bin $srcdir/server.pem $srcdir/server.pem $srcdir/ca.pem diff --git a/Libraries/libressl/tests/sha_test.c b/Libraries/libressl/tests/sha_test.c new file mode 100644 index 000000000..82a0c4cce --- /dev/null +++ b/Libraries/libressl/tests/sha_test.c @@ -0,0 +1,936 @@ +/* $OpenBSD: sha_test.c,v 1.6 2023/07/19 15:11:42 joshua Exp $ */ +/* + * Copyright (c) 2022, 2023 Joshua Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +struct sha_test { + const int algorithm; + const uint8_t in[128]; + const size_t in_len; + const uint8_t out[EVP_MAX_MD_SIZE]; +}; + +static const struct sha_test sha_tests[] = { + /* SHA-1 */ + { + .algorithm = NID_sha1, + .in = "abc", + .in_len = 3, + .out = { + 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d, + }, + }, + { + .algorithm = NID_sha1, + .in = "", + .in_len = 0, + .out = { + 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, + 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, + 0xaf, 0xd8, 0x07, 0x09, + }, + }, + { + .algorithm = NID_sha1, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, + 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, + 0xe5, 0x46, 0x70, 0xf1, + }, + }, + { + .algorithm = NID_sha1, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0xa4, 0x9b, 0x24, 0x46, 0xa0, 0x2c, 0x64, 0x5b, + 0xf4, 0x19, 0xf9, 0x95, 0xb6, 0x70, 0x91, 0x25, + 0x3a, 0x04, 0xa2, 0x59, + }, + }, + + /* SHA-224 */ + { + .algorithm = NID_sha224, + .in = "abc", + .in_len = 3, + .out = { + 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22, + 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3, + 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7, + 0xe3, 0x6c, 0x9d, 0xa7, + }, + }, + { + .algorithm = NID_sha224, + .in = "", + .in_len = 0, + .out = { + 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, + 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4, + 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a, + 0xc5, 0xb3, 0xe4, 0x2f, + }, + }, + { + .algorithm = NID_sha224, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc, + 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50, + 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19, + 0x52, 0x52, 0x25, 0x25, + }, + }, + { + .algorithm = NID_sha224, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0xc9, 0x7c, 0xa9, 0xa5, 0x59, 0x85, 0x0c, 0xe9, + 0x7a, 0x04, 0xa9, 0x6d, 0xef, 0x6d, 0x99, 0xa9, + 0xe0, 0xe0, 0xe2, 0xab, 0x14, 0xe6, 0xb8, 0xdf, + 0x26, 0x5f, 0xc0, 0xb3, + }, + }, + + /* SHA-256 */ + { + .algorithm = NID_sha256, + .in = "abc", + .in_len = 3, + .out = { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad, + }, + }, + { + .algorithm = NID_sha256, + .in = "", + .in_len = 0, + .out = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, + }, + }, + { + .algorithm = NID_sha256, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1, + }, + }, + { + .algorithm = NID_sha256, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80, + 0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37, + 0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51, + 0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1, + }, + }, + + /* SHA-384 */ + { + .algorithm = NID_sha384, + .in = "abc", + .in_len = 3, + .out = { + 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7, + }, + }, + { + .algorithm = NID_sha384, + .in = "", + .in_len = 0, + .out = { + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, + 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, + 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, + 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, + 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, + 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b, + }, + }, + { + .algorithm = NID_sha384, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, + 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39, + 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab, + 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, + 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, + 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b, + }, + }, + { + .algorithm = NID_sha384, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39, + }, + }, + + /* SHA-512 */ + { + .algorithm = NID_sha512, + .in = "abc", + .in_len = 3, + .out = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f, + }, + }, + { + .algorithm = NID_sha512, + .in = "", + .in_len = 0, + .out = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, + 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, + 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, + 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, + 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, + 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, + 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, + 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e, + }, + }, + { + .algorithm = NID_sha512, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, + 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16, + 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8, + 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, + 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, + 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0, + 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03, + 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45, + }, + }, + { + .algorithm = NID_sha512, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09, + }, + }, + + /* SHA3-224 */ + { + .algorithm = NID_sha3_224, + .in = "abc", + .in_len = 3, + .out = { + 0xe6, 0x42, 0x82, 0x4c, 0x3f, 0x8c, 0xf2, 0x4a, + 0xd0, 0x92, 0x34, 0xee, 0x7d, 0x3c, 0x76, 0x6f, + 0xc9, 0xa3, 0xa5, 0x16, 0x8d, 0x0c, 0x94, 0xad, + 0x73, 0xb4, 0x6f, 0xdf, + }, + }, + { + .algorithm = NID_sha3_224, + .in = "", + .in_len = 0, + .out = { + 0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7, + 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab, + 0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f, + 0x5b, 0x5a, 0x6b, 0xc7, + }, + }, + { + .algorithm = NID_sha3_224, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x8a, 0x24, 0x10, 0x8b, 0x15, 0x4a, 0xda, 0x21, + 0xc9, 0xfd, 0x55, 0x74, 0x49, 0x44, 0x79, 0xba, + 0x5c, 0x7e, 0x7a, 0xb7, 0x6e, 0xf2, 0x64, 0xea, + 0xd0, 0xfc, 0xce, 0x33, + }, + }, + { + .algorithm = NID_sha3_224, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0x54, 0x3e, 0x68, 0x68, 0xe1, 0x66, 0x6c, 0x1a, + 0x64, 0x36, 0x30, 0xdf, 0x77, 0x36, 0x7a, 0xe5, + 0xa6, 0x2a, 0x85, 0x07, 0x0a, 0x51, 0xc1, 0x4c, + 0xbf, 0x66, 0x5c, 0xbc, + }, + }, + + /* SHA3-256 */ + { + .algorithm = NID_sha3_256, + .in = "abc", + .in_len = 3, + .out = { + 0x3a, 0x98, 0x5d, 0xa7, 0x4f, 0xe2, 0x25, 0xb2, + 0x04, 0x5c, 0x17, 0x2d, 0x6b, 0xd3, 0x90, 0xbd, + 0x85, 0x5f, 0x08, 0x6e, 0x3e, 0x9d, 0x52, 0x5b, + 0x46, 0xbf, 0xe2, 0x45, 0x11, 0x43, 0x15, 0x32, + }, + }, + { + .algorithm = NID_sha3_256, + .in = "", + .in_len = 0, + .out = { + 0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, + 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, + 0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa, + 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a, + }, + }, + { + .algorithm = NID_sha3_256, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x41, 0xc0, 0xdb, 0xa2, 0xa9, 0xd6, 0x24, 0x08, + 0x49, 0x10, 0x03, 0x76, 0xa8, 0x23, 0x5e, 0x2c, + 0x82, 0xe1, 0xb9, 0x99, 0x8a, 0x99, 0x9e, 0x21, + 0xdb, 0x32, 0xdd, 0x97, 0x49, 0x6d, 0x33, 0x76, + }, + }, + { + .algorithm = NID_sha3_256, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0x91, 0x6f, 0x60, 0x61, 0xfe, 0x87, 0x97, 0x41, + 0xca, 0x64, 0x69, 0xb4, 0x39, 0x71, 0xdf, 0xdb, + 0x28, 0xb1, 0xa3, 0x2d, 0xc3, 0x6c, 0xb3, 0x25, + 0x4e, 0x81, 0x2b, 0xe2, 0x7a, 0xad, 0x1d, 0x18, + }, + }, + + /* SHA3-384 */ + { + .algorithm = NID_sha3_384, + .in = "abc", + .in_len = 3, + .out = { + 0xec, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6f, 0xc9, + 0x26, 0x45, 0x9f, 0x58, 0xe2, 0xc6, 0xad, 0x8d, + 0xf9, 0xb4, 0x73, 0xcb, 0x0f, 0xc0, 0x8c, 0x25, + 0x96, 0xda, 0x7c, 0xf0, 0xe4, 0x9b, 0xe4, 0xb2, + 0x98, 0xd8, 0x8c, 0xea, 0x92, 0x7a, 0xc7, 0xf5, + 0x39, 0xf1, 0xed, 0xf2, 0x28, 0x37, 0x6d, 0x25, + }, + }, + { + .algorithm = NID_sha3_384, + .in = "", + .in_len = 0, + .out = { + 0x0c, 0x63, 0xa7, 0x5b, 0x84, 0x5e, 0x4f, 0x7d, + 0x01, 0x10, 0x7d, 0x85, 0x2e, 0x4c, 0x24, 0x85, + 0xc5, 0x1a, 0x50, 0xaa, 0xaa, 0x94, 0xfc, 0x61, + 0x99, 0x5e, 0x71, 0xbb, 0xee, 0x98, 0x3a, 0x2a, + 0xc3, 0x71, 0x38, 0x31, 0x26, 0x4a, 0xdb, 0x47, + 0xfb, 0x6b, 0xd1, 0xe0, 0x58, 0xd5, 0xf0, 0x04, + }, + }, + { + .algorithm = NID_sha3_384, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x99, 0x1c, 0x66, 0x57, 0x55, 0xeb, 0x3a, 0x4b, + 0x6b, 0xbd, 0xfb, 0x75, 0xc7, 0x8a, 0x49, 0x2e, + 0x8c, 0x56, 0xa2, 0x2c, 0x5c, 0x4d, 0x7e, 0x42, + 0x9b, 0xfd, 0xbc, 0x32, 0xb9, 0xd4, 0xad, 0x5a, + 0xa0, 0x4a, 0x1f, 0x07, 0x6e, 0x62, 0xfe, 0xa1, + 0x9e, 0xef, 0x51, 0xac, 0xd0, 0x65, 0x7c, 0x22, + }, + }, + { + .algorithm = NID_sha3_384, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0x79, 0x40, 0x7d, 0x3b, 0x59, 0x16, 0xb5, 0x9c, + 0x3e, 0x30, 0xb0, 0x98, 0x22, 0x97, 0x47, 0x91, + 0xc3, 0x13, 0xfb, 0x9e, 0xcc, 0x84, 0x9e, 0x40, + 0x6f, 0x23, 0x59, 0x2d, 0x04, 0xf6, 0x25, 0xdc, + 0x8c, 0x70, 0x9b, 0x98, 0xb4, 0x3b, 0x38, 0x52, + 0xb3, 0x37, 0x21, 0x61, 0x79, 0xaa, 0x7f, 0xc7, + }, + }, + + /* SHA3-512 */ + { + .algorithm = NID_sha3_512, + .in = "abc", + .in_len = 3, + .out = { + 0xb7, 0x51, 0x85, 0x0b, 0x1a, 0x57, 0x16, 0x8a, + 0x56, 0x93, 0xcd, 0x92, 0x4b, 0x6b, 0x09, 0x6e, + 0x08, 0xf6, 0x21, 0x82, 0x74, 0x44, 0xf7, 0x0d, + 0x88, 0x4f, 0x5d, 0x02, 0x40, 0xd2, 0x71, 0x2e, + 0x10, 0xe1, 0x16, 0xe9, 0x19, 0x2a, 0xf3, 0xc9, + 0x1a, 0x7e, 0xc5, 0x76, 0x47, 0xe3, 0x93, 0x40, + 0x57, 0x34, 0x0b, 0x4c, 0xf4, 0x08, 0xd5, 0xa5, + 0x65, 0x92, 0xf8, 0x27, 0x4e, 0xec, 0x53, 0xf0, + }, + }, + { + .algorithm = NID_sha3_512, + .in = "", + .in_len = 0, + .out = { + 0xa6, 0x9f, 0x73, 0xcc, 0xa2, 0x3a, 0x9a, 0xc5, + 0xc8, 0xb5, 0x67, 0xdc, 0x18, 0x5a, 0x75, 0x6e, + 0x97, 0xc9, 0x82, 0x16, 0x4f, 0xe2, 0x58, 0x59, + 0xe0, 0xd1, 0xdc, 0xc1, 0x47, 0x5c, 0x80, 0xa6, + 0x15, 0xb2, 0x12, 0x3a, 0xf1, 0xf5, 0xf9, 0x4c, + 0x11, 0xe3, 0xe9, 0x40, 0x2c, 0x3a, 0xc5, 0x58, + 0xf5, 0x00, 0x19, 0x9d, 0x95, 0xb6, 0xd3, 0xe3, + 0x01, 0x75, 0x85, 0x86, 0x28, 0x1d, 0xcd, 0x26, + }, + }, + { + .algorithm = NID_sha3_512, + .in = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno" + "mnopnopq", + .in_len = 56, + .out = { + 0x04, 0xa3, 0x71, 0xe8, 0x4e, 0xcf, 0xb5, 0xb8, + 0xb7, 0x7c, 0xb4, 0x86, 0x10, 0xfc, 0xa8, 0x18, + 0x2d, 0xd4, 0x57, 0xce, 0x6f, 0x32, 0x6a, 0x0f, + 0xd3, 0xd7, 0xec, 0x2f, 0x1e, 0x91, 0x63, 0x6d, + 0xee, 0x69, 0x1f, 0xbe, 0x0c, 0x98, 0x53, 0x02, + 0xba, 0x1b, 0x0d, 0x8d, 0xc7, 0x8c, 0x08, 0x63, + 0x46, 0xb5, 0x33, 0xb4, 0x9c, 0x03, 0x0d, 0x99, + 0xa2, 0x7d, 0xaf, 0x11, 0x39, 0xd6, 0xe7, 0x5e, + }, + }, + { + .algorithm = NID_sha3_512, + .in = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklm" + "ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs" + "mnopqrstnopqrstu", + .in_len = 112, + .out = { + 0xaf, 0xeb, 0xb2, 0xef, 0x54, 0x2e, 0x65, 0x79, + 0xc5, 0x0c, 0xad, 0x06, 0xd2, 0xe5, 0x78, 0xf9, + 0xf8, 0xdd, 0x68, 0x81, 0xd7, 0xdc, 0x82, 0x4d, + 0x26, 0x36, 0x0f, 0xee, 0xbf, 0x18, 0xa4, 0xfa, + 0x73, 0xe3, 0x26, 0x11, 0x22, 0x94, 0x8e, 0xfc, + 0xfd, 0x49, 0x2e, 0x74, 0xe8, 0x2e, 0x21, 0x89, + 0xed, 0x0f, 0xb4, 0x40, 0xd1, 0x87, 0xf3, 0x82, + 0x27, 0x0c, 0xb4, 0x55, 0xf2, 0x1d, 0xd1, 0x85, + }, + }, +}; + +struct sha_repetition_test { + const int algorithm; + const uint8_t in; + const size_t in_repetitions; + const uint8_t out[EVP_MAX_MD_SIZE]; +}; + +static const struct sha_repetition_test sha_repetition_tests[] = { + /* SHA-1 */ + { + .algorithm = NID_sha1, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4, + 0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31, + 0x65, 0x34, 0x01, 0x6f, + }, + }, + + /* SHA-224 */ + { + .algorithm = NID_sha224, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0x20, 0x79, 0x46, 0x55, 0x98, 0x0c, 0x91, 0xd8, + 0xbb, 0xb4, 0xc1, 0xea, 0x97, 0x61, 0x8a, 0x4b, + 0xf0, 0x3f, 0x42, 0x58, 0x19, 0x48, 0xb2, 0xee, + 0x4e, 0xe7, 0xad, 0x67, + }, + }, + + /* SHA-256 */ + { + .algorithm = NID_sha256, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, + 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, + 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, + 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0, + }, + }, + + /* SHA-384 */ + { + .algorithm = NID_sha384, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb, + 0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c, + 0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52, + 0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b, + 0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb, + 0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85, + }, + }, + + /* SHA-512 */ + { + .algorithm = NID_sha512, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64, + 0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63, + 0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb, + 0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a, + 0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b, + 0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e, + 0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b, + }, + }, + + /* SHA3-224 */ + { + .algorithm = NID_sha3_224, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0xd6, 0x93, 0x35, 0xb9, 0x33, 0x25, 0x19, 0x2e, + 0x51, 0x6a, 0x91, 0x2e, 0x6d, 0x19, 0xa1, 0x5c, + 0xb5, 0x1c, 0x6e, 0xd5, 0xc1, 0x52, 0x43, 0xe7, + 0xa7, 0xfd, 0x65, 0x3c, + }, + }, + + /* SHA3-256 */ + { + .algorithm = NID_sha3_256, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0x5c, 0x88, 0x75, 0xae, 0x47, 0x4a, 0x36, 0x34, + 0xba, 0x4f, 0xd5, 0x5e, 0xc8, 0x5b, 0xff, 0xd6, + 0x61, 0xf3, 0x2a, 0xca, 0x75, 0xc6, 0xd6, 0x99, + 0xd0, 0xcd, 0xcb, 0x6c, 0x11, 0x58, 0x91, 0xc1, + }, + }, + + /* SHA3-384 */ + { + .algorithm = NID_sha3_384, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0xee, 0xe9, 0xe2, 0x4d, 0x78, 0xc1, 0x85, 0x53, + 0x37, 0x98, 0x34, 0x51, 0xdf, 0x97, 0xc8, 0xad, + 0x9e, 0xed, 0xf2, 0x56, 0xc6, 0x33, 0x4f, 0x8e, + 0x94, 0x8d, 0x25, 0x2d, 0x5e, 0x0e, 0x76, 0x84, + 0x7a, 0xa0, 0x77, 0x4d, 0xdb, 0x90, 0xa8, 0x42, + 0x19, 0x0d, 0x2c, 0x55, 0x8b, 0x4b, 0x83, 0x40, + }, + }, + + /* SHA3-512 */ + { + .algorithm = NID_sha3_512, + .in = 'a', + .in_repetitions = 1000000, + .out = { + 0x3c, 0x3a, 0x87, 0x6d, 0xa1, 0x40, 0x34, 0xab, + 0x60, 0x62, 0x7c, 0x07, 0x7b, 0xb9, 0x8f, 0x7e, + 0x12, 0x0a, 0x2a, 0x53, 0x70, 0x21, 0x2d, 0xff, + 0xb3, 0x38, 0x5a, 0x18, 0xd4, 0xf3, 0x88, 0x59, + 0xed, 0x31, 0x1d, 0x0a, 0x9d, 0x51, 0x41, 0xce, + 0x9c, 0xc5, 0xc6, 0x6e, 0xe6, 0x89, 0xb2, 0x66, + 0xa8, 0xaa, 0x18, 0xac, 0xe8, 0x28, 0x2a, 0x0e, + 0x0d, 0xb5, 0x96, 0xc9, 0x0b, 0x0a, 0x7b, 0x87, + }, + }, +}; + +#define N_SHA_TESTS (sizeof(sha_tests) / sizeof(sha_tests[0])) +#define N_SHA_REPETITION_TESTS (sizeof(sha_repetition_tests) / sizeof(sha_repetition_tests[0])) + +typedef unsigned char *(*sha_hash_func)(const unsigned char *, size_t, + unsigned char *); + +static int +sha_hash_from_algorithm(int algorithm, const char **out_label, + sha_hash_func *out_func, const EVP_MD **out_md, size_t *out_len) +{ + const char *label; + sha_hash_func sha_func; + const EVP_MD *md; + size_t len; + + switch (algorithm) { + case NID_sha1: + label = SN_sha1; + sha_func = SHA1; + md = EVP_sha1(); + len = SHA_DIGEST_LENGTH; + break; + case NID_sha224: + label = SN_sha224; + sha_func = SHA224; + md = EVP_sha224(); + len = SHA224_DIGEST_LENGTH; + break; + case NID_sha256: + label = SN_sha256; + sha_func = SHA256; + md = EVP_sha256(); + len = SHA256_DIGEST_LENGTH; + break; + case NID_sha384: + label = SN_sha384; + sha_func = SHA384; + md = EVP_sha384(); + len = SHA384_DIGEST_LENGTH; + break; + case NID_sha512: + label = SN_sha512; + sha_func = SHA512; + md = EVP_sha512(); + len = SHA512_DIGEST_LENGTH; + break; + case NID_sha3_224: + label = SN_sha3_224; + sha_func = NULL; + md = EVP_sha3_224(); + len = 224 / 8; + break; + case NID_sha3_256: + label = SN_sha3_256; + sha_func = NULL; + md = EVP_sha3_256(); + len = 256 / 8; + break; + case NID_sha3_384: + label = SN_sha3_384; + sha_func = NULL; + md = EVP_sha3_384(); + len = 384 / 8; + break; + case NID_sha3_512: + label = SN_sha3_512; + sha_func = NULL; + md = EVP_sha3_512(); + len = 512 / 8; + break; + default: + fprintf(stderr, "FAIL: unknown algorithm (%d)\n", + algorithm); + return 0; + } + + if (out_label != NULL) + *out_label = label; + if (out_func != NULL) + *out_func = sha_func; + if (out_md != NULL) + *out_md = md; + if (out_len != NULL) + *out_len = len; + + return 1; +} + +static int +sha_test(void) +{ + sha_hash_func sha_func; + const struct sha_test *st; + EVP_MD_CTX *hash = NULL; + const EVP_MD *md; + uint8_t out[EVP_MAX_MD_SIZE]; + size_t in_len, out_len; + size_t i; + const char *label; + int failed = 1; + + if ((hash = EVP_MD_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n"); + goto failed; + } + + for (i = 0; i < N_SHA_TESTS; i++) { + st = &sha_tests[i]; + if (!sha_hash_from_algorithm(st->algorithm, &label, &sha_func, + &md, &out_len)) + goto failed; + + /* Digest */ + if (sha_func != NULL) { + memset(out, 0, sizeof(out)); + sha_func(st->in, st->in_len, out); + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): mismatch\n", + label, i); + goto failed; + } + } + + /* EVP single-shot digest */ + memset(out, 0, sizeof(out)); + if (!EVP_Digest(st->in, st->in_len, out, NULL, md, NULL)) { + fprintf(stderr, "FAIL (%s:%zu): EVP_Digest failed\n", + label, i); + goto failed; + } + + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, + "FAIL (%s:%zu): EVP single-shot mismatch\n", + label, i); + goto failed; + } + + /* EVP digest */ + memset(out, 0, sizeof(out)); + if (!EVP_DigestInit_ex(hash, md, NULL)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestInit_ex failed\n", + label, i); + goto failed; + } + + in_len = st->in_len / 2; + if (!EVP_DigestUpdate(hash, st->in, in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestUpdate first half " + "failed\n", label, i); + goto failed; + } + + if (!EVP_DigestUpdate(hash, st->in + in_len, + st->in_len - in_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestUpdate second half " + "failed\n", label, i); + goto failed; + } + + if (!EVP_DigestFinal_ex(hash, out, NULL)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestFinal_ex failed\n", + label, i); + goto failed; + } + + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP mismatch\n", + label, i); + goto failed; + } + } + + failed = 0; + + failed: + EVP_MD_CTX_free(hash); + return failed; +} + +static int +sha_repetition_test(void) +{ + const struct sha_repetition_test *st; + EVP_MD_CTX *hash = NULL; + const EVP_MD *md; + uint8_t buf[1024]; + uint8_t out[EVP_MAX_MD_SIZE]; + size_t out_len, part_len; + size_t i, j; + const char *label; + int failed = 1; + + if ((hash = EVP_MD_CTX_new()) == NULL) { + fprintf(stderr, "FAIL: EVP_MD_CTX_new() failed\n"); + goto failed; + } + + for (i = 0; i < N_SHA_REPETITION_TESTS; i++) { + st = &sha_repetition_tests[i]; + if (!sha_hash_from_algorithm(st->algorithm, &label, NULL, &md, + &out_len)) + goto failed; + + /* EVP digest */ + if (!EVP_DigestInit_ex(hash, md, NULL)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestInit_ex failed\n", + label, i); + goto failed; + } + + memset(buf, st->in, sizeof(buf)); + + for (j = 0; j < st->in_repetitions;) { + part_len = arc4random_uniform(sizeof(buf)); + if (part_len > st->in_repetitions - j) + part_len = st->in_repetitions - j; + + if (!EVP_DigestUpdate(hash, buf, part_len)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestUpdate failed\n", + label, i); + goto failed; + } + + j += part_len; + } + + if (!EVP_DigestFinal_ex(hash, out, NULL)) { + fprintf(stderr, + "FAIL (%s:%zu): EVP_DigestFinal_ex failed\n", + label, i); + goto failed; + } + + if (memcmp(st->out, out, out_len) != 0) { + fprintf(stderr, "FAIL (%s:%zu): EVP mismatch\n", + label, i); + goto failed; + } + } + + failed = 0; + + failed: + EVP_MD_CTX_free(hash); + return failed; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= sha_test(); + failed |= sha_repetition_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/signertest.c b/Libraries/libressl/tests/signertest.c new file mode 100644 index 000000000..f0523d34b --- /dev/null +++ b/Libraries/libressl/tests/signertest.c @@ -0,0 +1,471 @@ +/* $OpenBSD: signertest.c,v 1.6 2023/04/14 12:41:26 tb Exp $ */ +/* + * Copyright (c) 2017, 2018, 2022 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "tls_internal.h" + +#ifndef CERTSDIR +#define CERTSDIR "." +#endif + +const char *cert_path = CERTSDIR; +int sign_cb_count; + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static void +load_file(const char *filename, const uint8_t **data, size_t *data_len) +{ + char *filepath; + struct stat sb; + uint8_t *buf; + size_t len; + ssize_t n; + int fd; + + if (asprintf(&filepath, "%s/%s", cert_path, filename) == -1) + err(1, "asprintf"); + if ((fd = open(filepath, O_RDONLY)) == -1) + err(1, "failed to open '%s'", filepath); + if ((fstat(fd, &sb)) == -1) + err(1, "failed to stat '%s'", filepath); + if (sb.st_size < 0) + err(1, "file size invalid for '%s'", filepath); + len = (size_t)sb.st_size; + if ((buf = malloc(len)) == NULL) + err(1, "out of memory"); + n = read(fd, buf, len); + if (n < 0 || (size_t)n != len) + err(1, "failed to read '%s'", filepath); + close(fd); + + *data = buf; + *data_len = len; + + free(filepath); +} + +static int +compare_mem(char *label, const uint8_t *data1, size_t data1_len, + const uint8_t *data2, size_t data2_len) +{ + if (data1_len != data2_len) { + fprintf(stderr, "FAIL: %s length mismatch (%zu != %zu)\n", + label, data1_len, data2_len); + fprintf(stderr, "Got:\n"); + hexdump(data1, data1_len); + fprintf(stderr, "Want:\n"); + hexdump(data2, data2_len); + return -1; + } + if (data1 == data2) { + fprintf(stderr, "FAIL: %s comparing same memory (%p == %p)\n", + label, data1, data2); + return -1; + } + if (memcmp(data1, data2, data1_len) != 0) { + fprintf(stderr, "FAIL: %s data mismatch\n", label); + fprintf(stderr, "Got:\n"); + hexdump(data1, data1_len); + fprintf(stderr, "Want:\n"); + hexdump(data2, data2_len); + return -1; + } + return 0; +} + +const char *server_ecdsa_pubkey_hash = \ + "SHA256:cef2616ece9a57a76d072013b0faad2232511487c67c45bf00fbcecc070e2f5b"; +const char *server_rsa_pubkey_hash = \ + "SHA256:f03c535d374614e7356c0a4e6fd37fe94297b60ed86212adcba40e8e0b07bc9f"; +const char *server_unknown_pubkey_hash = \ + "SHA256:f03c535d374614e7356c0a4e6fd37fe94297b60ed86212adcba40e8e0b07bc9e"; + +const uint8_t test_digest[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, +}; + +const uint8_t test_rsa_signature[] = { + 0x77, 0xfb, 0xdd, 0x41, 0x45, 0x40, 0x25, 0xd6, + 0x01, 0xe0, 0x59, 0x04, 0x65, 0xae, 0xa1, 0x59, + 0xae, 0xa2, 0x44, 0x08, 0xf7, 0x02, 0x3d, 0xe4, + 0xc6, 0x0d, 0x4d, 0x9a, 0x3a, 0xce, 0x34, 0xbe, + 0x2e, 0xc0, 0xfc, 0xbd, 0x5b, 0x21, 0xe4, 0xbb, + 0xce, 0x02, 0xfd, 0xc3, 0xfc, 0x3d, 0x25, 0xe7, + 0xd1, 0x9a, 0x13, 0x60, 0xcb, 0x07, 0xda, 0x23, + 0xf7, 0xa3, 0xf0, 0xaf, 0x16, 0x1b, 0x28, 0x54, + 0x0a, 0x3c, 0xc1, 0x31, 0x08, 0x0f, 0x2f, 0xce, + 0x6d, 0x09, 0x45, 0x48, 0xee, 0x37, 0xa8, 0xc3, + 0x91, 0xcb, 0xde, 0xad, 0xc6, 0xcf, 0x18, 0x19, + 0xeb, 0xad, 0x08, 0x66, 0x2f, 0xce, 0x1d, 0x07, + 0xe3, 0x03, 0x84, 0x00, 0xca, 0x0f, 0x1d, 0x0f, + 0x0e, 0x6e, 0x54, 0xc1, 0x39, 0x3f, 0x2a, 0x78, + 0xc8, 0xa3, 0x6d, 0x52, 0xb9, 0x26, 0x8e, 0x7e, + 0x7a, 0x18, 0x3c, 0x8a, 0x50, 0xa3, 0xad, 0xab, + 0xd0, 0x03, 0xc5, 0x3e, 0xa5, 0x46, 0x87, 0xb0, + 0x03, 0xde, 0xd9, 0xe5, 0x4d, 0x73, 0x95, 0xcf, + 0xe1, 0x59, 0x8e, 0x2e, 0x50, 0x69, 0xe6, 0x20, + 0xaf, 0x21, 0x4f, 0xe6, 0xc4, 0x86, 0x11, 0x36, + 0x79, 0x68, 0x83, 0xde, 0x0e, 0x81, 0xde, 0x2e, + 0xd0, 0x19, 0x3f, 0x4b, 0xad, 0x3e, 0xbf, 0xdd, + 0x14, 0x4d, 0x66, 0xf3, 0x7f, 0x7d, 0xca, 0xed, + 0x99, 0x62, 0xdc, 0x7c, 0xb2, 0x8b, 0x57, 0xcb, + 0xdf, 0xed, 0x16, 0x13, 0x86, 0xd8, 0xd8, 0xb4, + 0x44, 0x6e, 0xd5, 0x54, 0xbc, 0xdf, 0xe7, 0x34, + 0x10, 0xa4, 0x17, 0x5f, 0xb7, 0xe1, 0x33, 0x2c, + 0xc1, 0x70, 0x5b, 0x87, 0x0d, 0x39, 0xee, 0xe8, + 0xec, 0x18, 0x92, 0xe8, 0x95, 0xa8, 0x93, 0x26, + 0xdf, 0x26, 0x93, 0x96, 0xfd, 0xad, 0x81, 0xb6, + 0xeb, 0x72, 0x9c, 0xd4, 0xcc, 0xf6, 0x9f, 0xb0, + 0xbb, 0xbd, 0xbd, 0x44, 0x1c, 0x99, 0x07, 0x6d, +}; + +static int +do_signer_tests(void) +{ + char *server_rsa_filepath = NULL; + const uint8_t *server_ecdsa = NULL; + size_t server_ecdsa_len; + struct tls_signer *signer = NULL; + uint8_t *signature = NULL; + size_t signature_len; + EC_KEY *ec_key = NULL; + X509 *x509 = NULL; + BIO *bio = NULL; + int failed = 1; + + load_file("server1-ecdsa.pem", &server_ecdsa, &server_ecdsa_len); + + if (asprintf(&server_rsa_filepath, "%s/%s", cert_path, + "server1-rsa.pem") == -1) { + fprintf(stderr, "FAIL: failed to build rsa file path\n"); + goto failure; + } + + /* Load the ECDSA public key - we'll need it later. */ + if ((bio = BIO_new_mem_buf(server_ecdsa, server_ecdsa_len)) == NULL) { + fprintf(stderr, "FAIL: failed to create bio\n"); + goto failure; + } + if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) { + fprintf(stderr, "FAIL: failed to load certificate\n"); + goto failure; + } + if ((ec_key = EVP_PKEY_get1_EC_KEY(X509_get0_pubkey(x509))) == NULL) { + fprintf(stderr, "FAIL: failed to get EC public key\n"); + goto failure; + } + + /* Create signer and add key pairs (one ECDSA, one RSA). */ + if ((signer = tls_signer_new()) == NULL) { + fprintf(stderr, "FAIL: failed to create tls signer\n"); + goto failure; + } + if (tls_signer_add_keypair_mem(signer, server_ecdsa, server_ecdsa_len, + server_ecdsa, server_ecdsa_len) == -1) { + fprintf(stderr, "FAIL: failed to add ECDSA keypair to tls " + "signer: %s\n", tls_signer_error(signer)); + goto failure; + } + if (tls_signer_add_keypair_file(signer, server_rsa_filepath, + server_rsa_filepath) == -1) { + fprintf(stderr, "FAIL: failed to add RSA keypair to tls " + "signer: %s\n", tls_signer_error(signer)); + goto failure; + } + + /* Sign with RSA. */ + if (tls_signer_sign(signer, server_rsa_pubkey_hash, test_digest, + sizeof(test_digest), TLS_PADDING_RSA_PKCS1, &signature, + &signature_len) == -1) { + fprintf(stderr, "FAIL: failed to sign with RSA key: %s\n", + tls_signer_error(signer)); + goto failure; + } + if (compare_mem("rsa signature", signature, signature_len, + test_rsa_signature, sizeof(test_rsa_signature)) == -1) + goto failure; + + free(signature); + signature = NULL; + + /* + * Sign with ECDSA - ECDSA signatures are non-deterministic so we cannot + * check against a known value, rather we can only verify the signature. + */ + if (tls_signer_sign(signer, server_ecdsa_pubkey_hash, test_digest, + sizeof(test_digest), TLS_PADDING_NONE, &signature, + &signature_len) == -1) { + fprintf(stderr, "FAIL: failed to sign with ECDSA key: %s\n", + tls_signer_error(signer)); + goto failure; + } + if (ECDSA_verify(0, test_digest, sizeof(test_digest), signature, + signature_len, ec_key) != 1) { + fprintf(stderr, "FAIL: failed to verify ECDSA signature\n"); + goto failure; + } + + free(signature); + signature = NULL; + + /* Attempt to sign with an unknown cert pubkey hash. */ + if (tls_signer_sign(signer, server_unknown_pubkey_hash, test_digest, + sizeof(test_digest), TLS_PADDING_NONE, &signature, + &signature_len) != -1) { + fprintf(stderr, "FAIL: signing succeeded with unknown key\n"); + goto failure; + } + if (strcmp(tls_signer_error(signer), "key not found") != 0) { + fprintf(stderr, "FAIL: got tls signer error '%s', want " + "'key not found'\n", tls_signer_error(signer)); + goto failure; + } + + failed = 0; + + failure: + BIO_free(bio); + EC_KEY_free(ec_key); + X509_free(x509); + tls_signer_free(signer); + free((uint8_t *)server_ecdsa); + free(server_rsa_filepath); + free(signature); + + return failed; +} + +static int +do_tls_handshake(char *name, struct tls *ctx) +{ + int rv; + + rv = tls_handshake(ctx); + if (rv == 0) + return (1); + if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT) + return (0); + + errx(1, "%s handshake failed: %s", name, tls_error(ctx)); +} + +static int +do_client_server_handshake(char *desc, struct tls *client, + struct tls *server_cctx) +{ + int i, client_done, server_done; + + i = client_done = server_done = 0; + do { + if (client_done == 0) + client_done = do_tls_handshake("client", client); + if (server_done == 0) + server_done = do_tls_handshake("server", server_cctx); + } while (i++ < 100 && (client_done == 0 || server_done == 0)); + + if (client_done == 0 || server_done == 0) { + printf("FAIL: %s TLS handshake did not complete\n", desc); + return (1); + } + + return (0); +} + +static int +test_tls_handshake_socket(struct tls *client, struct tls *server) +{ + struct tls *server_cctx; + int failure; + int sv[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, + sv) == -1) + err(1, "failed to create socketpair"); + + if (tls_accept_socket(server, &server_cctx, sv[0]) == -1) + errx(1, "failed to accept: %s", tls_error(server)); + + if (tls_connect_socket(client, sv[1], "test") == -1) + errx(1, "failed to connect: %s", tls_error(client)); + + failure = do_client_server_handshake("socket", client, server_cctx); + + tls_free(server_cctx); + + close(sv[0]); + close(sv[1]); + + return (failure); +} + +static int +test_signer_tls_sign(void *cb_arg, const char *pubkey_hash, + const uint8_t *input, size_t input_len, int padding_type, + uint8_t **out_signature, size_t *out_signature_len) +{ + struct tls_signer *signer = cb_arg; + + sign_cb_count++; + + return tls_signer_sign(signer, pubkey_hash, input, input_len, + padding_type, out_signature, out_signature_len); +} + +static int +test_signer_tls(char *certfile, char *keyfile, char *cafile) +{ + struct tls_config *client_cfg, *server_cfg; + struct tls_signer *signer; + struct tls *client, *server; + int failure = 0; + + if ((signer = tls_signer_new()) == NULL) + errx(1, "failed to create tls signer"); + if (tls_signer_add_keypair_file(signer, certfile, keyfile)) + errx(1, "failed to add keypair to signer"); + + if ((client = tls_client()) == NULL) + errx(1, "failed to create tls client"); + if ((client_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls client config"); + tls_config_insecure_noverifyname(client_cfg); + if (tls_config_set_ca_file(client_cfg, cafile) == -1) + errx(1, "failed to set ca: %s", tls_config_error(client_cfg)); + + if ((server = tls_server()) == NULL) + errx(1, "failed to create tls server"); + if ((server_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls server config"); + if (tls_config_set_sign_cb(server_cfg, test_signer_tls_sign, + signer) == -1) + errx(1, "failed to set server signer callback: %s", + tls_config_error(server_cfg)); + if (tls_config_set_cert_file(server_cfg, certfile) == -1) + errx(1, "failed to set server certificate: %s", + tls_config_error(server_cfg)); + + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + tls_config_free(client_cfg); + tls_config_free(server_cfg); + + failure |= test_tls_handshake_socket(client, server); + + tls_signer_free(signer); + tls_free(client); + tls_free(server); + + return (failure); +} + +static int +do_signer_tls_tests(void) +{ + char *server_ecdsa_cert = NULL, *server_ecdsa_key = NULL; + char *server_rsa_cert = NULL, *server_rsa_key = NULL; + char *ca_root_ecdsa = NULL, *ca_root_rsa = NULL; + int failure = 0; + + if (asprintf(&ca_root_ecdsa, "%s/%s", cert_path, + "ca-root-ecdsa.pem") == -1) + err(1, "ca ecdsa root"); + if (asprintf(&ca_root_rsa, "%s/%s", cert_path, + "ca-root-rsa.pem") == -1) + err(1, "ca rsa root"); + if (asprintf(&server_ecdsa_cert, "%s/%s", cert_path, + "server1-ecdsa-chain.pem") == -1) + err(1, "server ecdsa chain"); + if (asprintf(&server_ecdsa_key, "%s/%s", cert_path, + "server1-ecdsa.pem") == -1) + err(1, "server ecdsa key"); + if (asprintf(&server_rsa_cert, "%s/%s", cert_path, + "server1-rsa-chain.pem") == -1) + err(1, "server rsa chain"); + if (asprintf(&server_rsa_key, "%s/%s", cert_path, + "server1-rsa.pem") == -1) + err(1, "server rsa key"); + + failure |= test_signer_tls(server_ecdsa_cert, server_ecdsa_key, + ca_root_ecdsa); + failure |= test_signer_tls(server_rsa_cert, server_rsa_key, + ca_root_rsa); + + if (sign_cb_count != 2) { + fprintf(stderr, "FAIL: sign callback was called %d times, " + "want 2\n", sign_cb_count); + failure |= 1; + } + + free(ca_root_ecdsa); + free(ca_root_rsa); + free(server_ecdsa_cert); + free(server_ecdsa_key); + free(server_rsa_cert); + free(server_rsa_key); + + return (failure); +} + +int +main(int argc, char **argv) +{ + int failure = 0; + + if (argc > 2) { + fprintf(stderr, "usage: %s [certpath]\n", argv[0]); + return (1); + } + if (argc == 2) + cert_path = argv[1]; + + failure |= do_signer_tests(); + failure |= do_signer_tls_tests(); + + return (failure); +} diff --git a/Libraries/libressl/tests/sm3test.c b/Libraries/libressl/tests/sm3test.c new file mode 100644 index 000000000..f02ce3a66 --- /dev/null +++ b/Libraries/libressl/tests/sm3test.c @@ -0,0 +1,99 @@ +/* $OpenBSD: sm3test.c,v 1.3 2021/04/06 15:00:19 tb Exp $ */ +/* + * Copyright (c) 2018 Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#define SM3_TESTS 3 + +const char *sm3_input[SM3_TESTS] = { + "", + "abc", + "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", +}; + +const uint8_t sm3_expected[SM3_TESTS][32] = { + { + 0x1a, 0xb2, 0x1d, 0x83, 0x55, 0xcf, 0xa1, 0x7f, + 0x8e, 0x61, 0x19, 0x48, 0x31, 0xe8, 0x1a, 0x8f, + 0x22, 0xbe, 0xc8, 0xc7, 0x28, 0xfe, 0xfb, 0x74, + 0x7e, 0xd0, 0x35, 0xeb, 0x50, 0x82, 0xaa, 0x2b, + }, + { + 0x66, 0xc7, 0xf0, 0xf4, 0x62, 0xee, 0xed, 0xd9, + 0xd1, 0xf2, 0xd4, 0x6b, 0xdc, 0x10, 0xe4, 0xe2, + 0x41, 0x67, 0xc4, 0x87, 0x5c, 0xf2, 0xf7, 0xa2, + 0x29, 0x7d, 0xa0, 0x2b, 0x8f, 0x4b, 0xa8, 0xe0, + }, + { + 0xde, 0xbe, 0x9f, 0xf9, 0x22, 0x75, 0xb8, 0xa1, + 0x38, 0x60, 0x48, 0x89, 0xc1, 0x8e, 0x5a, 0x4d, + 0x6f, 0xdb, 0x70, 0xe5, 0x38, 0x7e, 0x57, 0x65, + 0x29, 0x3d, 0xcb, 0xa3, 0x9c, 0x0c, 0x57, 0x32, + }, +}; + +/* Tweaked version of libssl/key_schedule/key_schedule.c. */ +static void +hexdump(const uint8_t *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02x,%s", buf[i - 1], (i % 8) ? "" : "\n"); + + if (i % 8 != 1) + fprintf(stderr, "\n"); +} + +int +main(int argc, char *argv[]) +{ + EVP_MD_CTX *ctx; + uint8_t digest[32]; + int i; + int numerrors = 0; + + if ((ctx = EVP_MD_CTX_new()) == NULL) + err(1, NULL); + + for (i = 0; i < SM3_TESTS; i++) { + if (!EVP_DigestInit(ctx, EVP_sm3())) + errx(1, "EVP_DigestInit() failed"); + if (!EVP_DigestUpdate(ctx, sm3_input[i], strlen(sm3_input[i]))) + errx(1, "EVP_DigestInit() failed"); + if (!EVP_DigestFinal(ctx, digest, NULL)) + errx(1, "EVP_DigestFinal() failed"); + + if (memcmp(digest, sm3_expected[i], sizeof(digest)) != 0) { + fprintf(stderr, "TEST %d failed\n", i); + fprintf(stderr, "Produced:\n"); + hexdump(digest, sizeof(digest)); + fprintf(stderr, "Expected:\n"); + hexdump(sm3_expected[i], sizeof(sm3_expected[i])); + numerrors++; + } else + fprintf(stderr, "SM3 test %d ok\n", i); + } + + EVP_MD_CTX_free(ctx); + + return (numerrors > 0) ? 1 : 0; +} diff --git a/Libraries/libressl/tests/sm4test.c b/Libraries/libressl/tests/sm4test.c new file mode 100644 index 000000000..1bfdbb631 --- /dev/null +++ b/Libraries/libressl/tests/sm4test.c @@ -0,0 +1,108 @@ +/* $OpenBSD: sm4test.c,v 1.1 2019/03/17 17:48:31 tb Exp $ */ +/* + * Copyright (c) 2017, 2019 Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +static void +hexdump(FILE *fp, const char *title, const uint8_t *buf, size_t len) +{ + size_t i; + + fprintf(fp, "%s:\n", title); + for (i = 1; i <= len; i++) + fprintf(fp, " 0x%02x,%s", buf[i - 1], (i % 8) ? "" : "\n"); + + if (i % 8 != 1) + fprintf(fp, "\n"); +} + +int +main(int argc, char *argv[]) +{ + int i; + SM4_KEY key; + uint8_t block[SM4_BLOCK_SIZE]; + + static const uint8_t k[SM4_BLOCK_SIZE] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + + static const uint8_t input[SM4_BLOCK_SIZE] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + + /* + * This test vector comes from Example 1 of GB/T 32907-2016, + * and described in Internet Draft draft-ribose-cfrg-sm4-02. + */ + static const uint8_t expected[SM4_BLOCK_SIZE] = { + 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, + 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46 + }; + + /* + * This test vector comes from Example 2 from GB/T 32907-2016, + * and described in Internet Draft draft-ribose-cfrg-sm4-02. + * After 1,000,000 iterations. + */ + static const uint8_t expected_iter[SM4_BLOCK_SIZE] = { + 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, + 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 0x3f, 0x66 + }; + + if (!SM4_set_key(k, &key)) + errx(1, "SM4_set_key() failed"); + + memcpy(block, input, SM4_BLOCK_SIZE); + + SM4_encrypt(block, block, &key); + + if (memcmp(block, expected, SM4_BLOCK_SIZE) != 0) { + fprintf(stderr, "FAIL: Encryption failed\n"); + hexdump(stderr, "Got", block, SM4_BLOCK_SIZE); + hexdump(stderr, "Expected", expected, SM4_BLOCK_SIZE); + return 1; + } + + for (i = 0; i < 999999; i++) + SM4_encrypt(block, block, &key); + + if (memcmp(block, expected_iter, SM4_BLOCK_SIZE) != 0) { + fprintf(stderr, "FAIL: Multi-iteration encryption failed\n"); + hexdump(stderr, "Got", block, SM4_BLOCK_SIZE); + hexdump(stderr, "Expected", expected_iter, SM4_BLOCK_SIZE); + return 1; + } + + for (i = 0; i < 1000000; i++) + SM4_decrypt(block, block, &key); + + if (memcmp(block, input, SM4_BLOCK_SIZE) != 0) { + fprintf(stderr, "FAIL: Decrypted data does not match input\n"); + hexdump(stderr, "Got", block, SM4_BLOCK_SIZE); + hexdump(stderr, "Expected", input, SM4_BLOCK_SIZE); + return 1; + } + + return 0; +} diff --git a/Libraries/libressl/tests/ssl_get_shared_ciphers.c b/Libraries/libressl/tests/ssl_get_shared_ciphers.c new file mode 100644 index 000000000..33efc15f1 --- /dev/null +++ b/Libraries/libressl/tests/ssl_get_shared_ciphers.c @@ -0,0 +1,482 @@ +/* $OpenBSD: ssl_get_shared_ciphers.c,v 1.11 2022/02/05 18:19:39 tb Exp $ */ +/* + * Copyright (c) 2021 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct peer_config { + const char *name; + int server; + uint16_t max_version; + uint16_t min_version; + const char *ciphers; +}; + +struct ssl_shared_ciphers_test_data { + const char *description; + struct peer_config client_config; + struct peer_config server_config; + const char *shared_ciphers; + const char *shared_ciphers_without_aesni; +}; + +char *server_cert; +char *server_key; + +static const struct ssl_shared_ciphers_test_data ssl_shared_ciphers_tests[] = { + { + .description = "TLSv1.3 defaults", + .client_config = { + .name = "client", + .server = 0, + .max_version = TLS1_3_VERSION, + .min_version = TLS1_3_VERSION, + .ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256", + }, + .server_config = { + .name = "server", + .server = 1, + .max_version = TLS1_3_VERSION, + .min_version = TLS1_3_VERSION, + .ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256", + }, + .shared_ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256", + }, + + { + .description = "TLSv1.3, client without ChaCha", + .client_config = { + .name = "client", + .server = 0, + .max_version = TLS1_3_VERSION, + .min_version = TLS1_3_VERSION, + .ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_AES_128_GCM_SHA256", + }, + .server_config = { + .name = "server", + .server = 1, + .max_version = TLS1_3_VERSION, + .min_version = TLS1_3_VERSION, + .ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256", + }, + .shared_ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_AES_128_GCM_SHA256", + }, + + { + .description = "TLSv1.2", + .client_config = { + .name = "client", + .server = 0, + .max_version = TLS1_2_VERSION, + .min_version = TLS1_2_VERSION, + .ciphers = + "ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-SHA384:" + "ECDHE-ECDSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA:" + "ECDHE-ECDSA-AES256-SHA", + }, + .server_config = { + .name = "server", + .server = 1, + .max_version = TLS1_2_VERSION, + .min_version = TLS1_2_VERSION, + .ciphers = + "ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-SHA384:" + "ECDHE-ECDSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA:" + "ECDHE-ECDSA-AES256-SHA", + }, + .shared_ciphers = + "ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-SHA384:" + "ECDHE-ECDSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA:" + "ECDHE-ECDSA-AES256-SHA", + }, + + { + .description = "TLSv1.2, server without ECDSA", + .client_config = { + .name = "client", + .server = 0, + .max_version = TLS1_2_VERSION, + .min_version = TLS1_2_VERSION, + .ciphers = + "ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-SHA384:" + "ECDHE-ECDSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA:" + "ECDHE-ECDSA-AES256-SHA", + }, + .server_config = { + .name = "server", + .server = 1, + .max_version = TLS1_2_VERSION, + .min_version = TLS1_2_VERSION, + .ciphers = + "ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA", + }, + .shared_ciphers = + "ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA", + }, + + { + .description = "TLSv1.3 ciphers are prepended", + .client_config = { + .name = "client", + .server = 0, + .max_version = TLS1_3_VERSION, + .min_version = TLS1_2_VERSION, + .ciphers = + "ECDHE-RSA-AES256-GCM-SHA384", + }, + .server_config = { + .name = "server", + .server = 1, + .max_version = TLS1_3_VERSION, + .min_version = TLS1_2_VERSION, + .ciphers = + "ECDHE-RSA-AES256-GCM-SHA384", + }, + .shared_ciphers = + "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256:" + "ECDHE-RSA-AES256-GCM-SHA384", + .shared_ciphers_without_aesni = + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_256_GCM_SHA384:" + "TLS_AES_128_GCM_SHA256:" + "ECDHE-RSA-AES256-GCM-SHA384", + }, +}; + +static const size_t N_SHARED_CIPHERS_TESTS = + sizeof(ssl_shared_ciphers_tests) / sizeof(ssl_shared_ciphers_tests[0]); + +static SSL_CTX * +peer_config_to_ssl_ctx(const struct peer_config *config) +{ + SSL_CTX *ctx; + + if ((ctx = SSL_CTX_new(TLS_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new(%s) failed\n", config->name); + goto err; + } + if (!SSL_CTX_set_max_proto_version(ctx, config->max_version)) { + fprintf(stderr, "max_proto_version(%s) failed\n", config->name); + goto err; + } + if (!SSL_CTX_set_min_proto_version(ctx, config->min_version)) { + fprintf(stderr, "min_proto_version(%s) failed\n", config->name); + goto err; + } + if (!SSL_CTX_set_cipher_list(ctx, config->ciphers)) { + fprintf(stderr, "set_cipher_list(%s) failed\n", config->name); + goto err; + } + + if (config->server) { + if (!SSL_CTX_use_certificate_file(ctx, server_cert, + SSL_FILETYPE_PEM)) { + fprintf(stderr, "use_certificate_file(%s) failed\n", + config->name); + goto err; + } + if (!SSL_CTX_use_PrivateKey_file(ctx, server_key, + SSL_FILETYPE_PEM)) { + fprintf(stderr, "use_PrivateKey_file(%s) failed\n", + config->name); + goto err; + } + } + + return ctx; + + err: + SSL_CTX_free(ctx); + return NULL; +} + +/* Connect client and server via a pair of "nonblocking" memory BIOs. */ +static int +connect_peers(SSL *client_ssl, SSL *server_ssl, const char *description) +{ + BIO *client_wbio = NULL, *server_wbio = NULL; + int ret = 0; + + if ((client_wbio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "%s: failed to create client BIO\n", + description); + goto err; + } + if ((server_wbio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "%s: failed to create server BIO\n", + description); + goto err; + } + if (BIO_set_mem_eof_return(client_wbio, -1) <= 0) { + fprintf(stderr, "%s: failed to set client eof return\n", + description); + goto err; + } + if (BIO_set_mem_eof_return(server_wbio, -1) <= 0) { + fprintf(stderr, "%s: failed to set server eof return\n", + description); + goto err; + } + + /* Avoid double free. SSL_set_bio() takes ownership of the BIOs. */ + BIO_up_ref(client_wbio); + BIO_up_ref(server_wbio); + + SSL_set_bio(client_ssl, server_wbio, client_wbio); + SSL_set_bio(server_ssl, client_wbio, server_wbio); + client_wbio = NULL; + server_wbio = NULL; + + ret = 1; + + err: + BIO_free(client_wbio); + BIO_free(server_wbio); + + return ret; +} + +static int +push_data_to_peer(SSL *ssl, int *ret, int (*func)(SSL *), const char *func_name, + const char *description) +{ + int ssl_err = 0; + + if (*ret == 1) + return 1; + + /* + * Do SSL_connect/SSL_accept/SSL_shutdown once and loop while hitting + * WANT_WRITE. If done or on WANT_READ hand off to peer. + */ + + do { + if ((*ret = func(ssl)) <= 0) + ssl_err = SSL_get_error(ssl, *ret); + } while (*ret <= 0 && ssl_err == SSL_ERROR_WANT_WRITE); + + /* Ignore erroneous error - see SSL_shutdown(3)... */ + if (func == SSL_shutdown && ssl_err == SSL_ERROR_SYSCALL) + return 1; + + if (*ret <= 0 && ssl_err != SSL_ERROR_WANT_READ) { + fprintf(stderr, "%s: %s failed\n", description, func_name); + ERR_print_errors_fp(stderr); + return 0; + } + + return 1; +} + +/* + * Alternate between loops of SSL_connect() and SSL_accept() as long as only + * WANT_READ and WANT_WRITE situations are encountered. A function is repeated + * until WANT_READ is returned or it succeeds, then it's the other function's + * turn to make progress. Succeeds if SSL_connect() and SSL_accept() return 1. + */ +static int +handshake(SSL *client_ssl, SSL *server_ssl, const char *description) +{ + int loops = 0, client_ret = 0, server_ret = 0; + + while (loops++ < 10 && (client_ret <= 0 || server_ret <= 0)) { + if (!push_data_to_peer(client_ssl, &client_ret, SSL_connect, + "SSL_connect", description)) + return 0; + + if (!push_data_to_peer(server_ssl, &server_ret, SSL_accept, + "SSL_accept", description)) + return 0; + } + + if (client_ret != 1 || server_ret != 1) { + fprintf(stderr, "%s: failed\n", __func__); + return 0; + } + + return 1; +} + +static int +shutdown_peers(SSL *client_ssl, SSL *server_ssl, const char *description) +{ + int loops = 0, client_ret = 0, server_ret = 0; + + while (loops++ < 10 && (client_ret <= 0 || server_ret <= 0)) { + if (!push_data_to_peer(client_ssl, &client_ret, SSL_shutdown, + "client shutdown", description)) + return 0; + + if (!push_data_to_peer(server_ssl, &server_ret, SSL_shutdown, + "server shutdown", description)) + return 0; + } + + if (client_ret != 1 || server_ret != 1) { + fprintf(stderr, "%s: failed\n", __func__); + return 0; + } + + return 1; +} + +/* from ssl_ciph.c */ +static inline int +ssl_aes_is_accelerated(void) +{ +#if defined(__i386__) || defined(__x86_64__) + return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); +#else + return (0); +#endif +} + +static int +check_shared_ciphers(const struct ssl_shared_ciphers_test_data *test, + const char *got) +{ + const char *want = test->shared_ciphers; + int failed; + + if (!ssl_aes_is_accelerated() && + test->shared_ciphers_without_aesni != NULL) + want = test->shared_ciphers_without_aesni; + + failed = strcmp(want, got); + + if (failed) + fprintf(stderr, "%s: want \"%s\", got \"%s\"\n", + test->description, want, got); + + return failed; +} + +static int +test_get_shared_ciphers(const struct ssl_shared_ciphers_test_data *test) +{ + SSL_CTX *client_ctx = NULL, *server_ctx = NULL; + SSL *client_ssl = NULL, *server_ssl = NULL; + char buf[4096]; + int failed = 1; + + if ((client_ctx = peer_config_to_ssl_ctx(&test->client_config)) == NULL) + goto err; + if ((server_ctx = peer_config_to_ssl_ctx(&test->server_config)) == NULL) + goto err; + + if ((client_ssl = SSL_new(client_ctx)) == NULL) { + fprintf(stderr, "%s: failed to create client SSL\n", + test->description); + goto err; + } + if ((server_ssl = SSL_new(server_ctx)) == NULL) { + fprintf(stderr, "%s: failed to create server SSL\n", + test->description); + goto err; + } + + if (!connect_peers(client_ssl, server_ssl, test->description)) + goto err; + + if (!handshake(client_ssl, server_ssl, test->description)) + goto err; + + if (SSL_get_shared_ciphers(server_ssl, buf, sizeof(buf)) == NULL) { + fprintf(stderr, "%s: failed to get shared ciphers\n", + test->description); + goto err; + } + + if (!shutdown_peers(client_ssl, server_ssl, test->description)) + goto err; + + failed = check_shared_ciphers(test, buf); + + err: + SSL_CTX_free(client_ctx); + SSL_CTX_free(server_ctx); + SSL_free(client_ssl); + SSL_free(server_ssl); + + return failed; +} + +int +main(int argc, char **argv) +{ + size_t i; + int failed = 0; + + if (asprintf(&server_cert, "%s/server.pem", CERTSDIR) == -1) { + fprintf(stderr, "asprintf server_cert failed\n"); + failed = 1; + goto err; + } + server_key = server_cert; + + for (i = 0; i < N_SHARED_CIPHERS_TESTS; i++) + failed |= test_get_shared_ciphers(&ssl_shared_ciphers_tests[i]); + + if (failed == 0) + printf("PASS %s\n", __FILE__); + + err: + free(server_cert); + + return failed; +} diff --git a/Libraries/libressl/tests/ssl_methods.c b/Libraries/libressl/tests/ssl_methods.c new file mode 100644 index 000000000..0fc33a406 --- /dev/null +++ b/Libraries/libressl/tests/ssl_methods.c @@ -0,0 +1,267 @@ +/* $OpenBSD: ssl_methods.c,v 1.4 2021/04/04 20:21:43 tb Exp $ */ +/* + * Copyright (c) 2020 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +struct ssl_method_test_data { + const SSL_METHOD *(*method)(void); + const char *name; + int server; + int dtls; +}; + +struct ssl_method_test_data ssl_method_tests[] = { + { + .method = SSLv23_method, + .name = "SSLv23_method", + .server = 1, + .dtls = 0, + }, + { + .method = SSLv23_server_method, + .name = "SSLv23_server_method", + .server = 1, + .dtls = 0, + }, + { + .method = SSLv23_client_method, + .name = "SSLv23_client_method", + .server = 0, + .dtls = 0, + }, + + { + .method = TLSv1_method, + .name = "TLSv1_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLSv1_server_method, + .name = "TLSv1_server_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLSv1_client_method, + .name = "TLSv1_client_method", + .server = 0, + .dtls = 0, + }, + + { + .method = TLSv1_1_method, + .name = "TLSv1_1_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLSv1_1_server_method, + .name = "TLSv1_1_server_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLSv1_1_client_method, + .name = "TLSv1_1_client_method", + .server = 0, + .dtls = 0, + }, + + { + .method = TLSv1_2_method, + .name = "TLSv1_2_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLSv1_2_server_method, + .name = "TLSv1_2_server_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLSv1_2_client_method, + .name = "TLSv1_2_client_method", + .server = 0, + .dtls = 0, + }, + + { + .method = TLS_method, + .name = "TLS_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLS_server_method, + .name = "TLS_server_method", + .server = 1, + .dtls = 0, + }, + { + .method = TLS_client_method, + .name = "TLS_client_method", + .server = 0, + .dtls = 0, + }, + + { + .method = DTLSv1_method, + .name = "DTLSv1_method", + .server = 1, + .dtls = 1, + }, + { + .method = DTLSv1_server_method, + .name = "DTLSv1_server_method", + .server = 1, + .dtls = 1, + }, + { + .method = DTLSv1_client_method, + .name = "DTLSv1_client_method", + .server = 0, + .dtls = 1, + }, + + { + .method = DTLSv1_2_method, + .name = "DTLSv1_2_method", + .server = 1, + .dtls = 1, + }, + { + .method = DTLSv1_2_server_method, + .name = "DTLSv1_2_server_method", + .server = 1, + .dtls = 1, + }, + { + .method = DTLSv1_2_client_method, + .name = "DTLSv1_2_client_method", + .server = 0, + .dtls = 1, + }, + + { + .method = DTLS_method, + .name = "DTLS_method", + .server = 1, + .dtls = 1, + }, + { + .method = DTLS_server_method, + .name = "DTLS_server_method", + .server = 1, + .dtls = 1, + }, + { + .method = DTLS_client_method, + .name = "DTLS_client_method", + .server = 0, + .dtls = 1, + }, +}; + +#define N_METHOD_TESTS (sizeof(ssl_method_tests) / sizeof(ssl_method_tests[0])) + +int test_client_or_server_method(struct ssl_method_test_data *); +int test_dtls_method(struct ssl_method_test_data *); + +int +test_client_or_server_method(struct ssl_method_test_data *testcase) +{ + SSL_CTX *ssl_ctx; + SSL *ssl = NULL; + int failed = 1; + + if ((ssl_ctx = SSL_CTX_new(testcase->method())) == NULL) { + fprintf(stderr, "SSL_CTX_new returned NULL\n"); + goto err; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new returned NULL\n"); + goto err; + } + + if (SSL_is_server(ssl) != testcase->server) { + fprintf(stderr, "%s: SSL_is_server: want %d, got %d\n", + testcase->name, testcase->server, SSL_is_server(ssl)); + goto err; + } + + failed = 0; + + err: + SSL_free(ssl); + SSL_CTX_free(ssl_ctx); + + return failed; +} + +int +test_dtls_method(struct ssl_method_test_data *testcase) +{ + SSL_CTX *ssl_ctx; + SSL *ssl = NULL; + int failed = 1; + + if ((ssl_ctx = SSL_CTX_new(testcase->method())) == NULL) { + fprintf(stderr, "SSL_CTX_new returned NULL\n"); + goto err; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new returned NULL\n"); + goto err; + } + + if (SSL_is_dtls(ssl) != testcase->dtls) { + fprintf(stderr, "%s: SSL_is_dtls: want %d, got %d\n", + testcase->name, testcase->dtls, SSL_is_dtls(ssl)); + goto err; + } + + failed = 0; + + err: + SSL_free(ssl); + SSL_CTX_free(ssl_ctx); + + return failed; +} + +int +main(int argc, char **argv) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_METHOD_TESTS; i++) { + failed |= test_client_or_server_method(&ssl_method_tests[i]); + failed |= test_dtls_method(&ssl_method_tests[i]); + } + + if (failed == 0) + printf("PASS %s\n", __FILE__); + + return failed; +} diff --git a/Libraries/libressl/tests/ssl_set_alpn_protos.c b/Libraries/libressl/tests/ssl_set_alpn_protos.c new file mode 100644 index 000000000..87dd4d9e5 --- /dev/null +++ b/Libraries/libressl/tests/ssl_set_alpn_protos.c @@ -0,0 +1,204 @@ +/* $OpenBSD: ssl_set_alpn_protos.c,v 1.2 2022/07/21 03:59:04 tb Exp $ */ +/* + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +struct alpn_test { + const char *description; + const uint8_t protocols[24]; + size_t protocols_len; + int ret; +}; + +static const struct alpn_test alpn_tests[] = { + { + .description = "valid protocol list", + .protocols = { + 6, 's', 'p', 'd', 'y', '/', '1', + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + }, + .protocols_len = 16, + .ret = 0, + }, + { + .description = "zero length protocol", + .protocols = { + 0, + }, + .protocols_len = 1, + .ret = 1, + }, + { + .description = "zero length protocol at start", + .protocols = { + 0, + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + 6, 's', 'p', 'd', 'y', '/', '1', + }, + .protocols_len = 17, + .ret = 1, + }, + { + .description = "zero length protocol embedded", + .protocols = { + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + 0, + 6, 's', 'p', 'd', 'y', '/', '1', + }, + .protocols_len = 17, + .ret = 1, + }, + { + .description = "zero length protocol at end", + .protocols = { + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + 6, 's', 'p', 'd', 'y', '/', '1', + 0, + }, + .protocols_len = 17, + .ret = 1, + }, + { + .description = "protocol length too short", + .protocols = { + 6, 'h', 't', 't', 'p', '/', '1', '.', '1', + }, + .protocols_len = 9, + .ret = 1, + }, + { + .description = "protocol length too long", + .protocols = { + 8, 's', 'p', 'd', 'y', '/', '1', + }, + .protocols_len = 7, + .ret = 1, + }, +}; + +static const size_t N_ALPN_TESTS = sizeof(alpn_tests) / sizeof(alpn_tests[0]); + +static int +test_ssl_set_alpn_protos(const struct alpn_test *tc) +{ + SSL_CTX *ctx; + SSL *ssl; + int ret; + int failed = 0; + + if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "SSL_CTX_new"); + + ret = SSL_CTX_set_alpn_protos(ctx, tc->protocols, tc->protocols_len); + if (ret != tc->ret) { + warnx("%s: setting on SSL_CTX: want %d, got %d", + tc->description, tc->ret, ret); + failed = 1; + } + + if ((ssl = SSL_new(ctx)) == NULL) + errx(1, "SSL_new"); + + ret = SSL_set_alpn_protos(ssl, tc->protocols, tc->protocols_len); + if (ret != tc->ret) { + warnx("%s: setting on SSL: want %d, got %d", + tc->description, tc->ret, ret); + failed = 1; + } + + SSL_CTX_free(ctx); + SSL_free(ssl); + + return failed; +} + +static int +test_ssl_set_alpn_protos_edge_cases(void) +{ + SSL_CTX *ctx; + SSL *ssl; + const uint8_t valid[] = { + 6, 's', 'p', 'd', 'y', '/', '3', + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + }; + int failed = 0; + + if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "SSL_CTX_new"); + + if (SSL_CTX_set_alpn_protos(ctx, valid, sizeof(valid)) != 0) { + warnx("setting valid protocols on SSL_CTX failed"); + failed = 1; + } + if (SSL_CTX_set_alpn_protos(ctx, NULL, 0) != 0) { + warnx("setting 'NULL, 0' on SSL_CTX failed"); + failed = 1; + } + if (SSL_CTX_set_alpn_protos(ctx, valid, 0) != 0) { + warnx("setting 'valid, 0' on SSL_CTX failed"); + failed = 1; + } + if (SSL_CTX_set_alpn_protos(ctx, NULL, 43) != 0) { + warnx("setting 'NULL, 43' on SSL_CTX failed"); + failed = 1; + } + + if ((ssl = SSL_new(ctx)) == NULL) + errx(1, "SSL_new"); + + if (SSL_set_alpn_protos(ssl, valid, sizeof(valid)) != 0) { + warnx("setting valid protocols on SSL failed"); + failed = 1; + } + if (SSL_set_alpn_protos(ssl, NULL, 0) != 0) { + warnx("setting 'NULL, 0' on SSL failed"); + failed = 1; + } + if (SSL_set_alpn_protos(ssl, valid, 0) != 0) { + warnx("setting 'valid, 0' on SSL failed"); + failed = 1; + } + if (SSL_set_alpn_protos(ssl, NULL, 43) != 0) { + warnx("setting 'NULL, 43' on SSL failed"); + failed = 1; + } + + SSL_CTX_free(ctx); + SSL_free(ssl); + + return failed; +} + +int +main(void) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_ALPN_TESTS; i++) + failed |= test_ssl_set_alpn_protos(&alpn_tests[i]); + + failed |= test_ssl_set_alpn_protos_edge_cases(); + + if (!failed) + printf("PASS %s\n", __FILE__); + + return failed; +} diff --git a/Libraries/libressl/tests/ssl_verify_param.c b/Libraries/libressl/tests/ssl_verify_param.c new file mode 100644 index 000000000..cdb52c56a --- /dev/null +++ b/Libraries/libressl/tests/ssl_verify_param.c @@ -0,0 +1,99 @@ +/* $OpenBSD: ssl_verify_param.c,v 1.1 2023/05/24 08:54:59 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +unsigned int X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param); + +static int +ssl_verify_param_flags_inherited(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + X509_VERIFY_PARAM *param; + unsigned int defaultflags = 0; + unsigned int newflags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; + unsigned int flags; + int failed = 1; + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) + errx(1, "SSL_CTX_new"); + + if ((param = SSL_CTX_get0_param(ssl_ctx)) == NULL) { + fprintf(stderr, "FAIL: no verify param on ssl_ctx\n"); + goto failure; + } + + if ((flags = X509_VERIFY_PARAM_get_hostflags(param)) != defaultflags) { + fprintf(stderr, "FAIL: SSL_CTX default hostflags, " + "want: %x, got: %x\n", defaultflags, flags); + goto failure; + } + + X509_VERIFY_PARAM_set_hostflags(param, newflags); + + if ((flags = X509_VERIFY_PARAM_get_hostflags(param)) != newflags) { + fprintf(stderr, "FAIL: SSL_CTX new hostflags, " + "want: %x, got: %x\n", newflags, flags); + goto failure; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "SSL_new"); + + if ((param = SSL_get0_param(ssl)) == NULL) { + fprintf(stderr, "FAIL: no verify param on ssl\n"); + goto failure; + } + + if ((flags = X509_VERIFY_PARAM_get_hostflags(param)) != newflags) { + fprintf(stderr, "FAIL: SSL inherited hostflags, " + "want: %x, got: %x\n", newflags, flags); + goto failure; + } + + SSL_set_hostflags(ssl, defaultflags); + + if ((flags = X509_VERIFY_PARAM_get_hostflags(param)) != defaultflags) { + fprintf(stderr, "FAIL: SSL set hostflags, " + "want: %x, got: %x\n", defaultflags, flags); + goto failure; + } + + failed = 0; + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= ssl_verify_param_flags_inherited(); + + return failed; +} diff --git a/Libraries/libressl/tests/ssl_versions.c b/Libraries/libressl/tests/ssl_versions.c new file mode 100644 index 000000000..ebfe8d2c2 --- /dev/null +++ b/Libraries/libressl/tests/ssl_versions.c @@ -0,0 +1,922 @@ +/* $OpenBSD: ssl_versions.c,v 1.20 2023/07/02 17:21:33 beck Exp $ */ +/* + * Copyright (c) 2016, 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" + +struct version_range_test { + const long options; + const uint16_t minver; + const uint16_t maxver; + const uint16_t want_minver; + const uint16_t want_maxver; +}; + +static struct version_range_test version_range_tests[] = { + { + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_3_VERSION, + }, + { + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = SSL_OP_NO_TLSv1, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = SSL_OP_NO_TLSv1_3, + .minver = TLS1_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, + { + .options = SSL_OP_NO_TLSv1_1, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, + { + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, + { + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | + SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, + { + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | + SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_3_VERSION, + .want_maxver = TLS1_3_VERSION, + }, + { + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | + SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3, + .minver = TLS1_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, + { + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = 0, + .minver = TLS1_2_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_3_VERSION, + }, + { + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_3_VERSION, + }, + { + .options = 0, + .minver = TLS1_2_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = TLS1_3_VERSION, + }, + { + .options = 0, + .minver = TLS1_3_VERSION, + .maxver = TLS1_3_VERSION, + .want_minver = TLS1_3_VERSION, + .want_maxver = TLS1_3_VERSION, + }, + { + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_1_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, + { + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_VERSION, + .want_minver = 0, + .want_maxver = 0, + }, +}; + +#define N_VERSION_RANGE_TESTS \ + (sizeof(version_range_tests) / sizeof(*version_range_tests)) + +static int +test_ssl_enabled_version_range(void) +{ + struct version_range_test *vrt; + uint16_t minver, maxver; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failed = 1; + size_t i; + + fprintf(stderr, "INFO: starting enabled version range tests...\n"); + + if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + goto failure; + } + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + goto failure; + } + + failed = 0; + + for (i = 0; i < N_VERSION_RANGE_TESTS; i++) { + vrt = &version_range_tests[i]; + + SSL_clear_options(ssl, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | + SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3); + SSL_set_options(ssl, vrt->options); + + minver = maxver = 0xffff; + ssl->min_tls_version = vrt->minver; + ssl->max_tls_version = vrt->maxver; + + if (ssl_enabled_tls_version_range(ssl, &minver, &maxver) != 1) { + if (vrt->want_minver != 0 || vrt->want_maxver != 0) { + fprintf(stderr, "FAIL: test %zu - failed but " + "wanted non-zero versions\n", i); + failed++; + } + continue; + } + if (minver != vrt->want_minver) { + fprintf(stderr, "FAIL: test %zu - got minver %x, " + "want %x\n", i, minver, vrt->want_minver); + failed++; + } + if (maxver != vrt->want_maxver) { + fprintf(stderr, "FAIL: test %zu - got maxver %x, " + "want %x\n", i, maxver, vrt->want_maxver); + failed++; + } + } + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return (failed); +} + +struct shared_version_test { + const SSL_METHOD *(*ssl_method)(void); + const long options; + const uint16_t minver; + const uint16_t maxver; + const uint16_t peerver; + const uint16_t want_maxver; +}; + +static struct shared_version_test shared_version_tests[] = { + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = SSL2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = SSL3_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_3_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = 0x7f12, + .want_maxver = TLS1_2_VERSION, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = SSL_OP_NO_TLSv1, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_1_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLSv1_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLSv1_method, + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLSv1_1_method, + .options = 0, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = TLS1_1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLS_method, + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = DTLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLS_method, + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = DTLS1_2_VERSION, + .want_maxver = DTLS1_2_VERSION, + }, + { + .ssl_method = DTLS_method, + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = 0xfefc, /* DTLSv1.3, probably. */ + .want_maxver = DTLS1_2_VERSION, + }, + { + .ssl_method = DTLSv1_method, + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_1_VERSION, + .peerver = DTLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLSv1_2_method, + .options = 0, + .minver = TLS1_2_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = DTLS1_2_VERSION, + .want_maxver = DTLS1_2_VERSION, + }, + { + .ssl_method = DTLSv1_method, + .options = 0, + .minver = TLS1_1_VERSION, + .maxver = TLS1_1_VERSION, + .peerver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLS_method, + .options = SSL_OP_NO_DTLSv1, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = DTLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLS_method, + .options = SSL_OP_NO_DTLSv1, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = DTLS1_2_VERSION, + .want_maxver = DTLS1_2_VERSION, + }, + { + .ssl_method = DTLS_method, + .options = SSL_OP_NO_DTLSv1_2, + .minver = TLS1_1_VERSION, + .maxver = TLS1_2_VERSION, + .peerver = DTLS1_2_VERSION, + .want_maxver = 0, + }, +}; + +#define N_SHARED_VERSION_TESTS \ + (sizeof(shared_version_tests) / sizeof(*shared_version_tests)) + +static int +test_ssl_max_shared_version(void) +{ + struct shared_version_test *svt; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + uint16_t maxver; + int failed = 0; + size_t i; + + failed = 0; + + fprintf(stderr, "INFO: starting max shared version tests...\n"); + + for (i = 0; i < N_SHARED_VERSION_TESTS; i++) { + svt = &shared_version_tests[i]; + + if ((ssl_ctx = SSL_CTX_new(svt->ssl_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + failed++; + goto err; + } + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + failed++; + goto err; + } + + SSL_clear_options(ssl, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | + SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3); + SSL_set_options(ssl, svt->options); + + maxver = 0; + ssl->min_tls_version = svt->minver; + ssl->max_tls_version = svt->maxver; + + if (!ssl_max_shared_version(ssl, svt->peerver, &maxver)) { + if (svt->want_maxver != 0) { + fprintf(stderr, "FAIL: test %zu - failed but " + "wanted non-zero shared version (peer %x)\n", + i, svt->peerver); + failed++; + } + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + ssl_ctx = NULL; + ssl = NULL; + continue; + } + if (maxver != svt->want_maxver) { + fprintf(stderr, "FAIL: test %zu - got shared " + "version %x, want %x\n", i, maxver, + svt->want_maxver); + failed++; + } + + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + ssl_ctx = NULL; + ssl = NULL; + } + + err: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return (failed); +} + +struct min_max_version_test { + const SSL_METHOD *(*ssl_method)(void); + const uint16_t minver; + const uint16_t maxver; + const uint16_t want_minver; + const uint16_t want_maxver; + const int want_min_fail; + const int want_max_fail; +}; + +static struct min_max_version_test min_max_version_tests[] = { + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = 0, + .want_minver = 0, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .minver = TLS1_VERSION, + .maxver = 0, + .want_minver = TLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = TLS1_2_VERSION, + .want_minver = 0, + .want_maxver = TLS1_2_VERSION, + }, + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = TLS1_3_VERSION, + .want_minver = 0, + .want_maxver = TLS1_3_VERSION, + }, + { + .ssl_method = TLS_method, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_VERSION, + .want_maxver = TLS1_2_VERSION, + }, + { + .ssl_method = TLS_method, + .minver = TLS1_1_VERSION, + .maxver = 0, + .want_minver = TLS1_1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .minver = TLS1_2_VERSION, + .maxver = 0, + .want_minver = TLS1_2_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .minver = 0x0300, + .maxver = 0, + .want_minver = TLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = TLS_method, + .minver = 0x0305, + .maxver = 0, + .want_min_fail = 1, + }, + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = 0x0305, + .want_minver = 0, + .want_maxver = TLS1_3_VERSION, + }, + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = TLS1_1_VERSION, + .want_minver = 0, + .want_maxver = TLS1_1_VERSION, + }, + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = TLS1_VERSION, + .want_minver = 0, + .want_maxver = TLS1_VERSION, + }, + { + .ssl_method = TLS_method, + .minver = 0, + .maxver = 0x0300, + .want_max_fail = 1, + }, + { + .ssl_method = TLS_method, + .minver = TLS1_2_VERSION, + .maxver = TLS1_1_VERSION, + .want_minver = TLS1_2_VERSION, + .want_maxver = 0, + .want_max_fail = 1, + }, + { + .ssl_method = TLSv1_1_method, + .minver = 0, + .maxver = 0, + .want_minver = 0, + .want_maxver = 0, + }, + { + .ssl_method = TLSv1_1_method, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = TLS1_1_VERSION, + .want_maxver = TLS1_1_VERSION, + }, + { + .ssl_method = TLSv1_1_method, + .minver = TLS1_2_VERSION, + .maxver = 0, + .want_minver = 0, + .want_maxver = 0, + .want_min_fail = 1, + }, + { + .ssl_method = TLSv1_1_method, + .minver = 0, + .maxver = TLS1_VERSION, + .want_minver = 0, + .want_maxver = 0, + .want_max_fail = 1, + }, + { + .ssl_method = DTLS_method, + .minver = 0, + .maxver = 0, + .want_minver = 0, + .want_maxver = 0, + }, + { + .ssl_method = DTLS_method, + .minver = 0, + .maxver = DTLS1_VERSION, + .want_minver = 0, + .want_maxver = DTLS1_VERSION, + }, + { + .ssl_method = DTLS_method, + .minver = DTLS1_VERSION, + .maxver = 0, + .want_minver = DTLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLS_method, + .minver = DTLS1_VERSION, + .maxver = DTLS1_2_VERSION, + .want_minver = DTLS1_VERSION, + .want_maxver = DTLS1_2_VERSION, + }, + { + .ssl_method = DTLSv1_method, + .minver = 0, + .maxver = 0, + .want_minver = 0, + .want_maxver = 0, + }, + { + .ssl_method = DTLSv1_method, + .minver = DTLS1_VERSION, + .maxver = 0, + .want_minver = DTLS1_VERSION, + .want_maxver = 0, + }, + { + .ssl_method = DTLSv1_method, + .minver = 0, + .maxver = DTLS1_VERSION, + .want_minver = 0, + .want_maxver = DTLS1_VERSION, + }, + { + .ssl_method = DTLSv1_method, + .minver = 0, + .maxver = DTLS1_2_VERSION, + .want_minver = 0, + .want_maxver = DTLS1_VERSION, + }, + { + .ssl_method = DTLSv1_method, + .minver = TLS1_VERSION, + .maxver = TLS1_2_VERSION, + .want_minver = 0, + .want_maxver = 0, + .want_min_fail = 1, + .want_max_fail = 1, + }, +}; + +#define N_MIN_MAX_VERSION_TESTS \ + (sizeof(min_max_version_tests) / sizeof(*min_max_version_tests)) + +static int +test_ssl_min_max_version(void) +{ + struct min_max_version_test *mmvt; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failed = 0; + size_t i; + + failed = 0; + + fprintf(stderr, "INFO: starting min max version tests...\n"); + + for (i = 0; i < N_MIN_MAX_VERSION_TESTS; i++) { + mmvt = &min_max_version_tests[i]; + + if ((ssl_ctx = SSL_CTX_new(mmvt->ssl_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + return 1; + } + + if (!SSL_CTX_set_min_proto_version(ssl_ctx, mmvt->minver)) { + if (!mmvt->want_min_fail) { + fprintf(stderr, "FAIL: test %zu - failed to set " + "SSL_CTX min version\n", i); + failed++; + } + goto next; + } + if (!SSL_CTX_set_max_proto_version(ssl_ctx, mmvt->maxver)) { + if (!mmvt->want_max_fail) { + fprintf(stderr, "FAIL: test %zu - failed to set " + "SSL_CTX min version\n", i); + failed++; + } + goto next; + } + + if (mmvt->want_min_fail) { + fprintf(stderr, "FAIL: test %zu - successfully set " + "SSL_CTX min version, should have failed\n", i); + failed++; + goto next; + } + if (mmvt->want_max_fail) { + fprintf(stderr, "FAIL: test %zu - successfully set " + "SSL_CTX max version, should have failed\n", i); + failed++; + goto next; + } + + if (SSL_CTX_get_min_proto_version(ssl_ctx) != mmvt->want_minver) { + fprintf(stderr, "FAIL: test %zu - got SSL_CTX min " + "version 0x%x, want 0x%x\n", i, + SSL_CTX_get_min_proto_version(ssl_ctx), mmvt->want_minver); + failed++; + goto next; + } + if (SSL_CTX_get_max_proto_version(ssl_ctx) != mmvt->want_maxver) { + fprintf(stderr, "FAIL: test %zu - got SSL_CTX max " + "version 0x%x, want 0x%x\n", i, + SSL_CTX_get_max_proto_version(ssl_ctx), mmvt->want_maxver); + failed++; + goto next; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + return 1; + } + + if (SSL_get_min_proto_version(ssl) != mmvt->want_minver) { + fprintf(stderr, "FAIL: test %zu - initial SSL min " + "version 0x%x, want 0x%x\n", i, + SSL_get_min_proto_version(ssl), mmvt->want_minver); + failed++; + goto next; + } + if (SSL_get_max_proto_version(ssl) != mmvt->want_maxver) { + fprintf(stderr, "FAIL: test %zu - initial SSL max " + "version 0x%x, want 0x%x\n", i, + SSL_get_max_proto_version(ssl), mmvt->want_maxver); + failed++; + goto next; + } + + if (!SSL_set_min_proto_version(ssl, mmvt->minver)) { + if (mmvt->want_min_fail) { + fprintf(stderr, "FAIL: test %zu - failed to set " + "SSL min version\n", i); + failed++; + } + goto next; + } + if (!SSL_set_max_proto_version(ssl, mmvt->maxver)) { + if (mmvt->want_max_fail) { + fprintf(stderr, "FAIL: test %zu - failed to set " + "SSL min version\n", i); + failed++; + } + goto next; + } + + if (mmvt->want_min_fail) { + fprintf(stderr, "FAIL: test %zu - successfully set SSL " + "min version, should have failed\n", i); + failed++; + goto next; + } + if (mmvt->want_max_fail) { + fprintf(stderr, "FAIL: test %zu - successfully set SSL " + "max version, should have failed\n", i); + failed++; + goto next; + } + + if (SSL_get_min_proto_version(ssl) != mmvt->want_minver) { + fprintf(stderr, "FAIL: test %zu - got SSL min " + "version 0x%x, want 0x%x\n", i, + SSL_get_min_proto_version(ssl), mmvt->want_minver); + failed++; + goto next; + } + if (SSL_get_max_proto_version(ssl) != mmvt->want_maxver) { + fprintf(stderr, "FAIL: test %zu - got SSL max " + "version 0x%x, want 0x%x\n", i, + SSL_get_max_proto_version(ssl), mmvt->want_maxver); + failed++; + goto next; + } + + next: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + ssl_ctx = NULL; + ssl = NULL; + } + + return (failed); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + SSL_library_init(); + + /* XXX - Test ssl_supported_version_range() */ + + failed |= test_ssl_enabled_version_range(); + failed |= test_ssl_max_shared_version(); + failed |= test_ssl_min_max_version(); + + if (failed == 0) + printf("PASS %s\n", __FILE__); + + return (failed); +} diff --git a/Libraries/libressl/tests/ssltest.bat b/Libraries/libressl/tests/ssltest.bat new file mode 100644 index 000000000..fe138a571 --- /dev/null +++ b/Libraries/libressl/tests/ssltest.bat @@ -0,0 +1,19 @@ +@echo off +setlocal enabledelayedexpansion +REM ssltest.bat + +set ssltest_bin=%1 +set ssltest_bin=%ssltest_bin:/=\% +if not exist %ssltest_bin% exit /b 1 + +set openssl_bin=%2 +set openssl_bin=%openssl_bin:/=\% +if not exist %openssl_bin% exit /b 1 + +%srcdir%\testssl.bat %srcdir%\server1-rsa.pem %srcdir%\server1-rsa-chain.pem ^ + %srcdir%\ca-root-rsa.pem %ssltest_bin% %openssl_bin% +if !errorlevel! neq 0 ( + exit /b 1 +) + +endlocal diff --git a/Libraries/libressl/tests/ssltest.c b/Libraries/libressl/tests/ssltest.c new file mode 100644 index 000000000..f95ea44a9 --- /dev/null +++ b/Libraries/libressl/tests/ssltest.c @@ -0,0 +1,1535 @@ +/* $OpenBSD: ssltest.c,v 1.43 2023/08/15 11:20:57 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +/* XXX - USE_BIOPAIR code needs updating for BIO_n{read,write}{,0} removal. */ +/* #define USE_BIOPAIR */ + +#define _BSD_SOURCE 1 /* Or gethostname won't be declared properly + on Linux and GNU platforms. */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "ssl_local.h" + +#define TEST_SERVER_CERT "../apps/server.pem" +#define TEST_CLIENT_CERT "../apps/client.pem" + +static int verify_callback(int ok, X509_STORE_CTX *ctx); +static int app_verify_callback(X509_STORE_CTX *ctx, void *arg); + +static DH *get_dh1024(void); +static DH *get_dh1024dsa(void); + +static BIO *bio_err = NULL; +static BIO *bio_stdout = NULL; + +static const char *alpn_client; +static const char *alpn_server; +static const char *alpn_expected; +static unsigned char *alpn_selected; + +/* + * next_protos_parse parses a comma separated list of strings into a string + * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. + * outlen: (output) set to the length of the resulting buffer on success. + * err: (maybe NULL) on failure, an error message line is written to this BIO. + * in: a NUL terminated string like "abc,def,ghi" + * + * returns: a malloced buffer or NULL on failure. + */ +static unsigned char * +next_protos_parse(unsigned short *outlen, const char *in) +{ + size_t i, len, start = 0; + unsigned char *out; + + len = strlen(in); + if (len >= 65535) + return (NULL); + + if ((out = malloc(strlen(in) + 1)) == NULL) + return (NULL); + + for (i = 0; i <= len; ++i) { + if (i == len || in[i] == ',') { + if (i - start > 255) { + free(out); + return (NULL); + } + out[start] = i - start; + start = i + 1; + } else + out[i+1] = in[i]; + } + *outlen = len + 1; + return (out); +} + +static int +cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg) +{ + unsigned char *protos; + unsigned short protos_len; + + if ((protos = next_protos_parse(&protos_len, alpn_server)) == NULL) { + fprintf(stderr, + "failed to parser ALPN server protocol string: %s\n", + alpn_server); + abort(); + } + + if (SSL_select_next_proto((unsigned char **)out, outlen, protos, + protos_len, in, inlen) != OPENSSL_NPN_NEGOTIATED) { + free(protos); + return (SSL_TLSEXT_ERR_NOACK); + } + + /* + * Make a copy of the selected protocol which will be freed in + * verify_alpn. + */ + free(alpn_selected); + if ((alpn_selected = malloc(*outlen)) == NULL) { + fprintf(stderr, "malloc failed\n"); + abort(); + } + memcpy(alpn_selected, *out, *outlen); + *out = alpn_selected; + free(protos); + + return (SSL_TLSEXT_ERR_OK); +} + +static int +verify_alpn(SSL *client, SSL *server) +{ + const unsigned char *client_proto, *server_proto; + unsigned int client_proto_len = 0, server_proto_len = 0; + + SSL_get0_alpn_selected(client, &client_proto, &client_proto_len); + SSL_get0_alpn_selected(server, &server_proto, &server_proto_len); + + free(alpn_selected); + alpn_selected = NULL; + + if (client_proto_len != server_proto_len || (client_proto_len > 0 && + memcmp(client_proto, server_proto, client_proto_len) != 0)) { + BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); + goto err; + } + + if (client_proto_len > 0 && alpn_expected == NULL) { + BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n"); + goto err; + } + + if (alpn_expected != NULL && + (client_proto_len != strlen(alpn_expected) || + memcmp(client_proto, alpn_expected, client_proto_len) != 0)) { + BIO_printf(bio_stdout, "ALPN selected protocols not equal to " + "expected protocol: %s\n", alpn_expected); + goto err; + } + + return (0); + +err: + BIO_printf(bio_stdout, "ALPN results: client: '"); + BIO_write(bio_stdout, client_proto, client_proto_len); + BIO_printf(bio_stdout, "', server: '"); + BIO_write(bio_stdout, server_proto, server_proto_len); + BIO_printf(bio_stdout, "'\n"); + BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", + alpn_client, alpn_server); + + return (-1); +} + +static char *cipher = NULL; +static int verbose = 0; +static int debug = 0; + +int doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time, + clock_t *c_time); +int doit(SSL *s_ssl, SSL *c_ssl, long bytes); + +static void +sv_usage(void) +{ + fprintf(stderr, "usage: ssltest [args ...]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -server_auth - check server certificate\n"); + fprintf(stderr, " -client_auth - do client authentication\n"); + fprintf(stderr, " -proxy - allow proxy certificates\n"); + fprintf(stderr, " -proxy_auth - set proxy policy rights\n"); + fprintf(stderr, " -proxy_cond - experssion to test proxy policy rights\n"); + fprintf(stderr, " -v - more output\n"); + fprintf(stderr, " -d - debug output\n"); + fprintf(stderr, " -reuse - use session-id reuse\n"); + fprintf(stderr, " -num - number of connections to perform\n"); + fprintf(stderr, " -bytes - number of bytes to swap between client/server\n"); + fprintf(stderr, " -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); + fprintf(stderr, " -no_dhe - disable DHE\n"); + fprintf(stderr, " -no_ecdhe - disable ECDHE\n"); + fprintf(stderr, " -dtls1_2 - use DTLSv1.2\n"); + fprintf(stderr, " -tls1 - use TLSv1\n"); + fprintf(stderr, " -tls1_2 - use TLSv1.2\n"); + fprintf(stderr, " -CApath arg - PEM format directory of CA's\n"); + fprintf(stderr, " -CAfile arg - PEM format file of CA's\n"); + fprintf(stderr, " -cert arg - Server certificate file\n"); + fprintf(stderr, " -key arg - Server key file (default: same as -cert)\n"); + fprintf(stderr, " -c_cert arg - Client certificate file\n"); + fprintf(stderr, " -c_key arg - Client key file (default: same as -c_cert)\n"); + fprintf(stderr, " -cipher arg - The cipher list\n"); + fprintf(stderr, " -bio_pair - Use BIO pairs\n"); + fprintf(stderr, " -f - Test even cases that can't work\n"); + fprintf(stderr, " -time - measure processor time used by client and server\n"); + fprintf(stderr, " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ + " Use \"openssl ecparam -list_curves\" for all names\n" \ + " (default is sect163r2).\n"); + fprintf(stderr, " -alpn_client - have client side offer ALPN\n"); + fprintf(stderr, " -alpn_server - have server side offer ALPN\n"); + fprintf(stderr, " -alpn_expected - the ALPN protocol that should be negotiated\n"); +} + +static void +print_details(SSL *c_ssl, const char *prefix) +{ + const SSL_CIPHER *ciph; + X509 *cert = NULL; + EVP_PKEY *pkey; + + ciph = SSL_get_current_cipher(c_ssl); + BIO_printf(bio_stdout, "%s%s, cipher %s %s", + prefix, SSL_get_version(c_ssl), SSL_CIPHER_get_version(ciph), + SSL_CIPHER_get_name(ciph)); + + if ((cert = SSL_get_peer_certificate(c_ssl)) == NULL) + goto out; + if ((pkey = X509_get0_pubkey(cert)) == NULL) + goto out; + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + RSA *rsa; + + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) + goto out; + + BIO_printf(bio_stdout, ", %d bit RSA", RSA_bits(rsa)); + } else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) { + DSA *dsa; + const BIGNUM *p; + + if ((dsa = EVP_PKEY_get0_DSA(pkey)) == NULL) + goto out; + + DSA_get0_pqg(dsa, &p, NULL, NULL); + + BIO_printf(bio_stdout, ", %d bit DSA", BN_num_bits(p)); + } + + out: + /* + * The SSL API does not allow us to look at temporary RSA/DH keys, + * otherwise we should print their lengths too + */ + BIO_printf(bio_stdout, "\n"); + + X509_free(cert); +} + +int +main(int argc, char *argv[]) +{ + char *CApath = NULL, *CAfile = NULL; + int badop = 0; + int bio_pair = 0; + int force = 0; + int tls1 = 0, tls1_2 = 0, dtls1_2 = 0, ret = 1; + int client_auth = 0; + int server_auth = 0, i; + char *app_verify_arg = "Test Callback Argument"; + char *server_cert = TEST_SERVER_CERT; + char *server_key = NULL; + char *client_cert = TEST_CLIENT_CERT; + char *client_key = NULL; + char *named_curve = NULL; + SSL_CTX *s_ctx = NULL; + SSL_CTX *c_ctx = NULL; + const SSL_METHOD *meth = NULL; + SSL *c_ssl, *s_ssl; + int number = 1, reuse = 0; + int seclevel = 0; + long bytes = 256L; + DH *dh; + int dhe1024dsa = 0; + EC_KEY *ecdh = NULL; + int no_dhe = 0; + int no_ecdhe = 0; + int print_time = 0; + clock_t s_time = 0, c_time = 0; + + verbose = 0; + debug = 0; + cipher = 0; + + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE|BIO_FP_TEXT); + + bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE|BIO_FP_TEXT); + + argc--; + argv++; + + while (argc >= 1) { + if (!strcmp(*argv, "-F")) { + fprintf(stderr, "not compiled with FIPS support, so exiting without running.\n"); + exit(0); + } else if (strcmp(*argv, "-server_auth") == 0) + server_auth = 1; + else if (strcmp(*argv, "-client_auth") == 0) + client_auth = 1; + else if (strcmp(*argv, "-v") == 0) + verbose = 1; + else if (strcmp(*argv, "-d") == 0) + debug = 1; + else if (strcmp(*argv, "-reuse") == 0) + reuse = 1; + else if (strcmp(*argv, "-dhe1024dsa") == 0) { + dhe1024dsa = 1; + } else if (strcmp(*argv, "-no_dhe") == 0) + no_dhe = 1; + else if (strcmp(*argv, "-no_ecdhe") == 0) + no_ecdhe = 1; + else if (strcmp(*argv, "-dtls1_2") == 0) + dtls1_2 = 1; + else if (strcmp(*argv, "-tls1") == 0) + tls1 = 1; + else if (strcmp(*argv, "-tls1_2") == 0) + tls1_2 = 1; + else if (strncmp(*argv, "-num", 4) == 0) { + if (--argc < 1) + goto bad; + number = atoi(*(++argv)); + if (number == 0) + number = 1; + } else if (strncmp(*argv, "-seclevel", 9) == 0) { + if (--argc < 1) + goto bad; + seclevel = atoi(*(++argv)); + } else if (strcmp(*argv, "-bytes") == 0) { + if (--argc < 1) + goto bad; + bytes = atol(*(++argv)); + if (bytes == 0L) + bytes = 1L; + i = strlen(argv[0]); + if (argv[0][i - 1] == 'k') + bytes*=1024L; + if (argv[0][i - 1] == 'm') + bytes*=1024L*1024L; + } else if (strcmp(*argv, "-cert") == 0) { + if (--argc < 1) + goto bad; + server_cert= *(++argv); + } else if (strcmp(*argv, "-s_cert") == 0) { + if (--argc < 1) + goto bad; + server_cert= *(++argv); + } else if (strcmp(*argv, "-key") == 0) { + if (--argc < 1) + goto bad; + server_key= *(++argv); + } else if (strcmp(*argv, "-s_key") == 0) { + if (--argc < 1) + goto bad; + server_key= *(++argv); + } else if (strcmp(*argv, "-c_cert") == 0) { + if (--argc < 1) + goto bad; + client_cert= *(++argv); + } else if (strcmp(*argv, "-c_key") == 0) { + if (--argc < 1) + goto bad; + client_key= *(++argv); + } else if (strcmp(*argv, "-cipher") == 0) { + if (--argc < 1) + goto bad; + cipher= *(++argv); + } else if (strcmp(*argv, "-CApath") == 0) { + if (--argc < 1) + goto bad; + CApath= *(++argv); + } else if (strcmp(*argv, "-CAfile") == 0) { + if (--argc < 1) + goto bad; + CAfile= *(++argv); + } else if (strcmp(*argv, "-bio_pair") == 0) { + bio_pair = 1; + } else if (strcmp(*argv, "-f") == 0) { + force = 1; + } else if (strcmp(*argv, "-time") == 0) { + print_time = 1; + } else if (strcmp(*argv, "-named_curve") == 0) { + if (--argc < 1) + goto bad; + named_curve = *(++argv); + } else if (strcmp(*argv, "-app_verify") == 0) { + ; + } else if (strcmp(*argv, "-alpn_client") == 0) { + if (--argc < 1) + goto bad; + alpn_client = *(++argv); + } else if (strcmp(*argv, "-alpn_server") == 0) { + if (--argc < 1) + goto bad; + alpn_server = *(++argv); + } else if (strcmp(*argv, "-alpn_expected") == 0) { + if (--argc < 1) + goto bad; + alpn_expected = *(++argv); + } else { + fprintf(stderr, "unknown option %s\n", *argv); + badop = 1; + break; + } + argc--; + argv++; + } + if (badop) { +bad: + sv_usage(); + goto end; + } + + if (!dtls1_2 && !tls1 && !tls1_2 && number > 1 && !reuse && !force) { + fprintf(stderr, + "This case cannot work. Use -f to perform " + "the test anyway (and\n-d to see what happens), " + "or add one of -dtls1, -tls1, -tls1_2, -reuse\n" + "to avoid protocol mismatch.\n"); + exit(1); + } + + if (print_time) { + if (!bio_pair) { + fprintf(stderr, "Using BIO pair (-bio_pair)\n"); + bio_pair = 1; + } + if (number < 50 && !force) + fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n"); + } + +/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */ + + SSL_library_init(); + SSL_load_error_strings(); + + if (dtls1_2) + meth = DTLSv1_2_method(); + else if (tls1) + meth = TLSv1_method(); + else if (tls1_2) + meth = TLSv1_2_method(); + else + meth = TLS_method(); + + c_ctx = SSL_CTX_new(meth); + s_ctx = SSL_CTX_new(meth); + if ((c_ctx == NULL) || (s_ctx == NULL)) { + ERR_print_errors(bio_err); + goto end; + } + + SSL_CTX_set_security_level(c_ctx, seclevel); + SSL_CTX_set_security_level(s_ctx, seclevel); + + if (cipher != NULL) { + SSL_CTX_set_cipher_list(c_ctx, cipher); + SSL_CTX_set_cipher_list(s_ctx, cipher); + } + + if (!no_dhe) { + if (dhe1024dsa) { + /* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */ + SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); + dh = get_dh1024dsa(); + } else + dh = get_dh1024(); + SSL_CTX_set_tmp_dh(s_ctx, dh); + DH_free(dh); + } + + if (!no_ecdhe) { + int nid; + + if (named_curve != NULL) { + nid = OBJ_sn2nid(named_curve); + if (nid == 0) { + BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); + goto end; + } + } else + nid = NID_X9_62_prime256v1; + + ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) { + BIO_printf(bio_err, "unable to create curve\n"); + goto end; + } + + SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); + SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); + EC_KEY_free(ecdh); + } + + if (!SSL_CTX_use_certificate_chain_file(s_ctx, server_cert)) { + ERR_print_errors(bio_err); + } else if (!SSL_CTX_use_PrivateKey_file(s_ctx, + (server_key ? server_key : server_cert), SSL_FILETYPE_PEM)) { + ERR_print_errors(bio_err); + goto end; + } + + if (client_auth) { + SSL_CTX_use_certificate_chain_file(c_ctx, client_cert); + SSL_CTX_use_PrivateKey_file(c_ctx, + (client_key ? client_key : client_cert), + SSL_FILETYPE_PEM); + } + + if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(s_ctx)) || + (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(c_ctx))) { + /* fprintf(stderr,"SSL_load_verify_locations\n"); */ + ERR_print_errors(bio_err); + /* goto end; */ + } + + if (client_auth) { + BIO_printf(bio_err, "client authentication\n"); + SSL_CTX_set_verify(s_ctx, + SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); + SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, + app_verify_arg); + } + if (server_auth) { + BIO_printf(bio_err, "server authentication\n"); + SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, + verify_callback); + SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, + app_verify_arg); + } + + { + int session_id_context = 0; + SSL_CTX_set_session_id_context(s_ctx, + (void *)&session_id_context, sizeof(session_id_context)); + } + + if (alpn_server != NULL) + SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); + + if (alpn_client != NULL) { + unsigned short alpn_len; + unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); + + if (alpn == NULL) { + BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); + goto end; + } + SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len); + free(alpn); + } + + c_ssl = SSL_new(c_ctx); + s_ssl = SSL_new(s_ctx); + + for (i = 0; i < number; i++) { + if (!reuse) + SSL_set_session(c_ssl, NULL); +#ifdef USE_BIOPAIR + if (bio_pair) + ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, + &c_time); + else +#endif + ret = doit(s_ssl, c_ssl, bytes); + } + + if (!verbose) { + print_details(c_ssl, ""); + } + if ((number > 1) || (bytes > 1L)) + BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", + number, bytes); + if (print_time) { +#ifdef CLOCKS_PER_SEC + /* "To determine the time in seconds, the value returned + * by the clock function should be divided by the value + * of the macro CLOCKS_PER_SEC." + * -- ISO/IEC 9899 */ + BIO_printf(bio_stdout, + "Approximate total server time: %6.2f s\n" + "Approximate total client time: %6.2f s\n", + (double)s_time/CLOCKS_PER_SEC, + (double)c_time/CLOCKS_PER_SEC); +#else + /* "`CLOCKS_PER_SEC' undeclared (first use this function)" + * -- cc on NeXTstep/OpenStep */ + BIO_printf(bio_stdout, + "Approximate total server time: %6.2f units\n" + "Approximate total client time: %6.2f units\n", + (double)s_time, + (double)c_time); +#endif + } + + SSL_free(s_ssl); + SSL_free(c_ssl); + +end: + SSL_CTX_free(s_ctx); + SSL_CTX_free(c_ctx); + BIO_free(bio_stdout); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_thread_state(NULL); + EVP_cleanup(); + CRYPTO_mem_leaks(bio_err); + BIO_free(bio_err); + + exit(ret); + return ret; +} + +#if USE_BIOPAIR +int +doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time, + clock_t *c_time) +{ + long cw_num = count, cr_num = count, sw_num = count, sr_num = count; + BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; + BIO *server = NULL, *server_io = NULL; + BIO *client = NULL, *client_io = NULL; + int ret = 1; + + size_t bufsiz = 256; /* small buffer for testing */ + + if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz)) + goto err; + if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz)) + goto err; + + s_ssl_bio = BIO_new(BIO_f_ssl()); + if (!s_ssl_bio) + goto err; + + c_ssl_bio = BIO_new(BIO_f_ssl()); + if (!c_ssl_bio) + goto err; + + SSL_set_connect_state(c_ssl); + SSL_set_bio(c_ssl, client, client); + (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE); + + SSL_set_accept_state(s_ssl); + SSL_set_bio(s_ssl, server, server); + (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE); + + do { + /* c_ssl_bio: SSL filter BIO + * + * client: pseudo-I/O for SSL library + * + * client_io: client's SSL communication; usually to be + * relayed over some I/O facility, but in this + * test program, we're the server, too: + * + * server_io: server's SSL communication + * + * server: pseudo-I/O for SSL library + * + * s_ssl_bio: SSL filter BIO + * + * The client and the server each employ a "BIO pair": + * client + client_io, server + server_io. + * BIO pairs are symmetric. A BIO pair behaves similar + * to a non-blocking socketpair (but both endpoints must + * be handled by the same thread). + * [Here we could connect client and server to the ends + * of a single BIO pair, but then this code would be less + * suitable as an example for BIO pairs in general.] + * + * Useful functions for querying the state of BIO pair endpoints: + * + * BIO_ctrl_pending(bio) number of bytes we can read now + * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil + * other side's read attempt + * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now + * + * ..._read_request is never more than ..._write_guarantee; + * it depends on the application which one you should use. + */ + + /* We have non-blocking behaviour throughout this test program, but + * can be sure that there is *some* progress in each iteration; so + * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE + * -- we just try everything in each iteration + */ + + { + /* CLIENT */ + + char cbuf[1024*8]; + int i, r; + clock_t c_clock = clock(); + + memset(cbuf, 0, sizeof(cbuf)); + + if (debug) + if (SSL_in_init(c_ssl)) + printf("client waiting in SSL_connect - %s\n", + SSL_state_string_long(c_ssl)); + + if (cw_num > 0) { + /* Write to server. */ + + if (cw_num > (long)sizeof cbuf) + i = sizeof cbuf; + else + i = (int)cw_num; + r = BIO_write(c_ssl_bio, cbuf, i); + if (r < 0) { + if (!BIO_should_retry(c_ssl_bio)) { + fprintf(stderr, "ERROR in CLIENT\n"); + goto err; + } + /* BIO_should_retry(...) can just be ignored here. + * The library expects us to call BIO_write with + * the same arguments again, and that's what we will + * do in the next iteration. */ + } else if (r == 0) { + fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); + goto err; + } else { + if (debug) + printf("client wrote %d\n", r); + cw_num -= r; + + } + } + + if (cr_num > 0) { + /* Read from server. */ + + r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf)); + if (r < 0) { + if (!BIO_should_retry(c_ssl_bio)) { + fprintf(stderr, "ERROR in CLIENT\n"); + goto err; + } + /* Again, "BIO_should_retry" can be ignored. */ + } else if (r == 0) { + fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); + goto err; + } else { + if (debug) + printf("client read %d\n", r); + cr_num -= r; + } + } + + /* c_time and s_time increments will typically be very small + * (depending on machine speed and clock tick intervals), + * but sampling over a large number of connections should + * result in fairly accurate figures. We cannot guarantee + * a lot, however -- if each connection lasts for exactly + * one clock tick, it will be counted only for the client + * or only for the server or even not at all. + */ + *c_time += (clock() - c_clock); + } + + { + /* SERVER */ + + char sbuf[1024*8]; + int i, r; + clock_t s_clock = clock(); + + memset(sbuf, 0, sizeof(sbuf)); + + if (debug) + if (SSL_in_init(s_ssl)) + printf("server waiting in SSL_accept - %s\n", + SSL_state_string_long(s_ssl)); + + if (sw_num > 0) { + /* Write to client. */ + + if (sw_num > (long)sizeof sbuf) + i = sizeof sbuf; + else + i = (int)sw_num; + r = BIO_write(s_ssl_bio, sbuf, i); + if (r < 0) { + if (!BIO_should_retry(s_ssl_bio)) { + fprintf(stderr, "ERROR in SERVER\n"); + goto err; + } + /* Ignore "BIO_should_retry". */ + } else if (r == 0) { + fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); + goto err; + } else { + if (debug) + printf("server wrote %d\n", r); + sw_num -= r; + + } + } + + if (sr_num > 0) { + /* Read from client. */ + + r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf)); + if (r < 0) { + if (!BIO_should_retry(s_ssl_bio)) { + fprintf(stderr, "ERROR in SERVER\n"); + goto err; + } + /* blah, blah */ + } else if (r == 0) { + fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); + goto err; + } else { + if (debug) + printf("server read %d\n", r); + sr_num -= r; + } + } + + *s_time += (clock() - s_clock); + } + + { + /* "I/O" BETWEEN CLIENT AND SERVER. */ + + size_t r1, r2; + BIO *io1 = server_io, *io2 = client_io; + /* we use the non-copying interface for io1 + * and the standard BIO_write/BIO_read interface for io2 + */ + + static int prev_progress = 1; + int progress = 0; + + /* io1 to io2 */ + do { + size_t num; + int r; + + r1 = BIO_ctrl_pending(io1); + r2 = BIO_ctrl_get_write_guarantee(io2); + + num = r1; + if (r2 < num) + num = r2; + if (num) { + char *dataptr; + + if (INT_MAX < num) /* yeah, right */ + num = INT_MAX; + + r = BIO_nread(io1, &dataptr, (int)num); + assert(r > 0); + assert(r <= (int)num); + /* possibly r < num (non-contiguous data) */ + num = r; + r = BIO_write(io2, dataptr, (int)num); + if (r != (int)num) /* can't happen */ + { + fprintf(stderr, "ERROR: BIO_write could not write " + "BIO_ctrl_get_write_guarantee() bytes"); + goto err; + } + progress = 1; + + if (debug) + printf((io1 == client_io) ? + "C->S relaying: %d bytes\n" : + "S->C relaying: %d bytes\n", + (int)num); + } + } while (r1 && r2); + + /* io2 to io1 */ + { + size_t num; + int r; + + r1 = BIO_ctrl_pending(io2); + r2 = BIO_ctrl_get_read_request(io1); + /* here we could use ..._get_write_guarantee instead of + * ..._get_read_request, but by using the latter + * we test restartability of the SSL implementation + * more thoroughly */ + num = r1; + if (r2 < num) + num = r2; + if (num) { + char *dataptr; + + if (INT_MAX < num) + num = INT_MAX; + + if (num > 1) + --num; /* test restartability even more thoroughly */ + + r = BIO_nwrite0(io1, &dataptr); + assert(r > 0); + if (r < (int)num) + num = r; + r = BIO_read(io2, dataptr, (int)num); + if (r != (int)num) /* can't happen */ + { + fprintf(stderr, "ERROR: BIO_read could not read " + "BIO_ctrl_pending() bytes"); + goto err; + } + progress = 1; + r = BIO_nwrite(io1, &dataptr, (int)num); + if (r != (int)num) /* can't happen */ + { + fprintf(stderr, "ERROR: BIO_nwrite() did not accept " + "BIO_nwrite0() bytes"); + goto err; + } + + if (debug) + printf((io2 == client_io) ? + "C->S relaying: %d bytes\n" : + "S->C relaying: %d bytes\n", + (int)num); + } + } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */ + + if (!progress && !prev_progress) { + if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) { + fprintf(stderr, "ERROR: got stuck\n"); + goto err; + } + } + prev_progress = progress; + } + } while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); + + if (verbose) + print_details(c_ssl, "DONE via BIO pair: "); + + if (verify_alpn(c_ssl, s_ssl) < 0) { + ret = 1; + goto err; + } + + ret = 0; + +err: + ERR_print_errors(bio_err); + + BIO_free(server); + BIO_free(server_io); + BIO_free(client); + BIO_free(client_io); + BIO_free(s_ssl_bio); + BIO_free(c_ssl_bio); + + return ret; +} +#endif + + +#define W_READ 1 +#define W_WRITE 2 +#define C_DONE 1 +#define S_DONE 2 + +int +doit(SSL *s_ssl, SSL *c_ssl, long count) +{ + char cbuf[1024*8], sbuf[1024*8]; + long cw_num = count, cr_num = count; + long sw_num = count, sr_num = count; + int ret = 1; + BIO *c_to_s = NULL; + BIO *s_to_c = NULL; + BIO *c_bio = NULL; + BIO *s_bio = NULL; + int c_r, c_w, s_r, s_w; + int i, j; + int done = 0; + int c_write, s_write; + int do_server = 0, do_client = 0; + + memset(cbuf, 0, sizeof(cbuf)); + memset(sbuf, 0, sizeof(sbuf)); + + c_to_s = BIO_new(BIO_s_mem()); + s_to_c = BIO_new(BIO_s_mem()); + if ((s_to_c == NULL) || (c_to_s == NULL)) { + ERR_print_errors(bio_err); + goto err; + } + + c_bio = BIO_new(BIO_f_ssl()); + s_bio = BIO_new(BIO_f_ssl()); + if ((c_bio == NULL) || (s_bio == NULL)) { + ERR_print_errors(bio_err); + goto err; + } + + SSL_set_connect_state(c_ssl); + SSL_set_bio(c_ssl, s_to_c, c_to_s); + BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE); + + SSL_set_accept_state(s_ssl); + SSL_set_bio(s_ssl, c_to_s, s_to_c); + BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE); + + c_r = 0; + s_r = 1; + c_w = 1; + s_w = 0; + c_write = 1, s_write = 0; + + /* We can always do writes */ + for (;;) { + do_server = 0; + do_client = 0; + + i = (int)BIO_pending(s_bio); + if ((i && s_r) || s_w) + do_server = 1; + + i = (int)BIO_pending(c_bio); + if ((i && c_r) || c_w) + do_client = 1; + + if (do_server && debug) { + if (SSL_in_init(s_ssl)) + printf("server waiting in SSL_accept - %s\n", + SSL_state_string_long(s_ssl)); + } + + if (do_client && debug) { + if (SSL_in_init(c_ssl)) + printf("client waiting in SSL_connect - %s\n", + SSL_state_string_long(c_ssl)); + } + + if (!do_client && !do_server) { + fprintf(stdout, "ERROR in STARTUP\n"); + ERR_print_errors(bio_err); + goto err; + } + + if (do_client && !(done & C_DONE)) { + if (c_write) { + j = (cw_num > (long)sizeof(cbuf)) ? + (int)sizeof(cbuf) : (int)cw_num; + i = BIO_write(c_bio, cbuf, j); + if (i < 0) { + c_r = 0; + c_w = 0; + if (BIO_should_retry(c_bio)) { + if (BIO_should_read(c_bio)) + c_r = 1; + if (BIO_should_write(c_bio)) + c_w = 1; + } else { + fprintf(stderr, "ERROR in CLIENT\n"); + ERR_print_errors(bio_err); + goto err; + } + } else if (i == 0) { + fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); + goto err; + } else { + if (debug) + printf("client wrote %d\n", i); + /* ok */ + s_r = 1; + c_write = 0; + cw_num -= i; + } + } else { + i = BIO_read(c_bio, cbuf, sizeof(cbuf)); + if (i < 0) { + c_r = 0; + c_w = 0; + if (BIO_should_retry(c_bio)) { + if (BIO_should_read(c_bio)) + c_r = 1; + if (BIO_should_write(c_bio)) + c_w = 1; + } else { + fprintf(stderr, "ERROR in CLIENT\n"); + ERR_print_errors(bio_err); + goto err; + } + } else if (i == 0) { + fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); + goto err; + } else { + if (debug) + printf("client read %d\n", i); + cr_num -= i; + if (sw_num > 0) { + s_write = 1; + s_w = 1; + } + if (cr_num <= 0) { + s_write = 1; + s_w = 1; + done = S_DONE|C_DONE; + } + } + } + } + + if (do_server && !(done & S_DONE)) { + if (!s_write) { + i = BIO_read(s_bio, sbuf, sizeof(cbuf)); + if (i < 0) { + s_r = 0; + s_w = 0; + if (BIO_should_retry(s_bio)) { + if (BIO_should_read(s_bio)) + s_r = 1; + if (BIO_should_write(s_bio)) + s_w = 1; + } else { + fprintf(stderr, "ERROR in SERVER\n"); + ERR_print_errors(bio_err); + goto err; + } + } else if (i == 0) { + ERR_print_errors(bio_err); + fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_read\n"); + goto err; + } else { + if (debug) + printf("server read %d\n", i); + sr_num -= i; + if (cw_num > 0) { + c_write = 1; + c_w = 1; + } + if (sr_num <= 0) { + s_write = 1; + s_w = 1; + c_write = 0; + } + } + } else { + j = (sw_num > (long)sizeof(sbuf)) ? + (int)sizeof(sbuf) : (int)sw_num; + i = BIO_write(s_bio, sbuf, j); + if (i < 0) { + s_r = 0; + s_w = 0; + if (BIO_should_retry(s_bio)) { + if (BIO_should_read(s_bio)) + s_r = 1; + if (BIO_should_write(s_bio)) + s_w = 1; + } else { + fprintf(stderr, "ERROR in SERVER\n"); + ERR_print_errors(bio_err); + goto err; + } + } else if (i == 0) { + ERR_print_errors(bio_err); + fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_write\n"); + goto err; + } else { + if (debug) + printf("server wrote %d\n", i); + sw_num -= i; + s_write = 0; + c_r = 1; + if (sw_num <= 0) + done |= S_DONE; + } + } + } + + if ((done & S_DONE) && (done & C_DONE)) + break; + } + + if (verbose) + print_details(c_ssl, "DONE: "); + + if (verify_alpn(c_ssl, s_ssl) < 0) { + ret = 1; + goto err; + } + + ret = 0; +err: + /* We have to set the BIO's to NULL otherwise they will be + * free()ed twice. Once when th s_ssl is SSL_free()ed and + * again when c_ssl is SSL_free()ed. + * This is a hack required because s_ssl and c_ssl are sharing the same + * BIO structure and SSL_set_bio() and SSL_free() automatically + * BIO_free non NULL entries. + * You should not normally do this or be required to do this */ + if (s_ssl != NULL) { + s_ssl->rbio = NULL; + s_ssl->wbio = NULL; + } + if (c_ssl != NULL) { + c_ssl->rbio = NULL; + c_ssl->wbio = NULL; + } + + BIO_free(c_to_s); + BIO_free(s_to_c); + BIO_free_all(c_bio); + BIO_free_all(s_bio); + + return (ret); +} + +static int +verify_callback(int ok, X509_STORE_CTX *ctx) +{ + X509 *xs; + char *s, buf[256]; + int error, error_depth; + + xs = X509_STORE_CTX_get_current_cert(ctx); + s = X509_NAME_oneline(X509_get_subject_name(xs), buf, sizeof buf); + error = X509_STORE_CTX_get_error(ctx); + error_depth = X509_STORE_CTX_get_error_depth(ctx); + if (s != NULL) { + if (ok) + fprintf(stderr, "depth=%d %s\n", error_depth, buf); + else { + fprintf(stderr, "depth=%d error=%d %s\n", error_depth, + error, buf); + } + } + + if (ok == 0) { + fprintf(stderr, "Error string: %s\n", + X509_verify_cert_error_string(error)); + switch (error) { + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + fprintf(stderr, " ... ignored.\n"); + ok = 1; + } + } + + return (ok); +} + +static int +app_verify_callback(X509_STORE_CTX *ctx, void *arg) +{ + X509 *xs; + char *s = NULL, buf[256]; + const char *cb_arg = arg; + + xs = X509_STORE_CTX_get0_cert(ctx); + fprintf(stderr, "In app_verify_callback, allowing cert. "); + fprintf(stderr, "Arg is: %s\n", cb_arg); + fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n", + (void *)ctx, (void *)xs); + if (xs) + s = X509_NAME_oneline(X509_get_subject_name(xs), buf, 256); + if (s != NULL) { + fprintf(stderr, "cert depth=%d %s\n", + X509_STORE_CTX_get_error_depth(ctx), buf); + } + + return 1; +} + +/* These DH parameters have been generated as follows: + * $ openssl dhparam -C -noout 1024 + * $ openssl dhparam -C -noout -dsaparam 1024 + * (The second function has been renamed to avoid name conflicts.) + */ +static DH * +get_dh1024(void) +{ + static unsigned char dh1024_p[] = { + 0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 0x3A, + 0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 0xA2, + 0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 0xB0, + 0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 0xC2, + 0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 0x8C, + 0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 0xB8, + 0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 0x52, + 0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 0xC1, + 0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 0xB1, + 0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 0xAB, + 0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53, + }; + static unsigned char dh1024_g[] = { + 0x02, + }; + DH *dh; + BIGNUM *dh_p = NULL, *dh_g = NULL; + + if ((dh = DH_new()) == NULL) + return NULL; + + dh_p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); + dh_g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); + if (dh_p == NULL || dh_g == NULL) + goto err; + + if (!DH_set0_pqg(dh, dh_p, NULL, dh_g)) + goto err; + + return dh; + + err: + BN_free(dh_p); + BN_free(dh_g); + DH_free(dh); + return NULL; +} + +static DH * +get_dh1024dsa(void) +{ + static unsigned char dh1024_p[] = { + 0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 0x00, + 0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 0x19, + 0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 0xD2, + 0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 0x55, + 0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 0xFC, + 0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 0x97, + 0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 0x8D, + 0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 0xBB, + 0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 0xF6, + 0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 0x9E, + 0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39, + }; + static unsigned char dh1024_g[] = { + 0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 0x05, + 0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 0xF3, + 0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 0xE9, + 0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 0x3C, + 0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 0x65, + 0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 0x60, + 0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 0xF6, + 0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 0xA7, + 0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 0xA1, + 0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 0x60, + 0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2, + }; + DH *dh; + BIGNUM *dh_p = NULL, *dh_g = NULL; + + if ((dh = DH_new()) == NULL) + return NULL; + + dh_p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); + dh_g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); + if (dh_p == NULL || dh_g == NULL) + goto err; + + if (!DH_set0_pqg(dh, dh_p, NULL, dh_g)) + goto err; + + DH_set_length(dh, 160); + + return dh; + + err: + BN_free(dh_p); + BN_free(dh_g); + DH_free(dh); + return NULL; +} diff --git a/Libraries/libressl/tests/ssltest.sh b/Libraries/libressl/tests/ssltest.sh new file mode 100644 index 000000000..22a893667 --- /dev/null +++ b/Libraries/libressl/tests/ssltest.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +ssltest_bin=./ssltest +if [ -e ./ssltest.exe ]; then + ssltest_bin=./ssltest.exe +fi + +if [ -d ../apps/openssl ]; then + openssl_bin=../apps/openssl/openssl + if [ -e ../apps/openssl/openssl.exe ]; then + openssl_bin=../apps/openssl/openssl.exe + fi +else + openssl_bin=../apps/openssl + if [ -e ../apps/openssl.exe ]; then + openssl_bin=../apps/openssl.exe + fi +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +$srcdir/testssl $srcdir/server1-rsa.pem $srcdir/server1-rsa-chain.pem \ + $srcdir/ca-root-rsa.pem \ + $ssltest_bin $openssl_bin diff --git a/Libraries/libressl/tests/string_table.c b/Libraries/libressl/tests/string_table.c new file mode 100644 index 000000000..e80cf0f20 --- /dev/null +++ b/Libraries/libressl/tests/string_table.c @@ -0,0 +1,128 @@ +/* $OpenBSD: string_table.c,v 1.1 2021/12/11 22:58:48 schwarze Exp $ */ +/* + * Copyright (c) 2021 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +static int errcount; + +static void +report(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); + + errcount++; +} + +static void +stable_check(const char *testname, ASN1_STRING_TABLE *have, + ASN1_STRING_TABLE *want, unsigned long want_flags) +{ + if (have == NULL) { + report("%s returned NULL", testname); + return; + } + if (have->nid != want->nid) + report("%s nid %d, expected %d", testname, + have->nid, want->nid); + if (have->minsize != want->minsize) + report("%s minsize %ld, expected %ld", testname, + have->minsize, want->minsize); + if (have->maxsize != want->maxsize) + report("%s maxsize %ld, expected %ld", testname, + have->maxsize, want->maxsize); + if (have->mask != want->mask) + report("%s mask %lu, expected %lu", testname, + have->mask, want->mask); + if (have->flags != want_flags) + report("%s flags %lu, expected %lu", testname, + have->flags, want_flags); +} + +int +main(void) +{ + ASN1_STRING_TABLE orig, mine, *have; + int irc; + + orig.nid = NID_name; + orig.minsize = 1; + orig.maxsize = ub_name; + orig.mask = DIRSTRING_TYPE; + orig.flags = 0; + + mine.nid = NID_name; + mine.minsize = 4; + mine.maxsize = 64; + mine.mask = B_ASN1_PRINTABLESTRING; + mine.flags = STABLE_NO_MASK; + + /* Original entry. */ + + have = ASN1_STRING_TABLE_get(orig.nid); + stable_check("orig", have, &orig, 0); + + /* Copy, but don't really change. */ + + irc = ASN1_STRING_TABLE_add(orig.nid, -1, -1, 0, 0); + if (irc != 1) + report("set noop returned %d, expected 1", irc); + have = ASN1_STRING_TABLE_get(orig.nid); + stable_check("noop", have, &orig, STABLE_FLAGS_MALLOC); + + /* Change entry. */ + + irc = ASN1_STRING_TABLE_add(mine.nid, mine.minsize, mine.maxsize, + mine.mask, mine.flags); + if (irc != 1) + report("set returned %d, expected 1", irc); + have = ASN1_STRING_TABLE_get(mine.nid); + stable_check("set", have, &mine, STABLE_FLAGS_MALLOC | STABLE_NO_MASK); + + /* New entry. */ + + mine.nid = NID_title; + irc = ASN1_STRING_TABLE_add(mine.nid, mine.minsize, mine.maxsize, + mine.mask, mine.flags); + if (irc != 1) + report("new returned %d, expected 1", irc); + have = ASN1_STRING_TABLE_get(mine.nid); + stable_check("new", have, &mine, STABLE_FLAGS_MALLOC | STABLE_NO_MASK); + + /* Back to the initial state. */ + + ASN1_STRING_TABLE_cleanup(); + have = ASN1_STRING_TABLE_get(orig.nid); + stable_check("back", have, &orig, 0); + if (ASN1_STRING_TABLE_get(mine.nid) != NULL) + report("deleted entry is not NULL"); + + switch (errcount) { + case 0: + return 0; + case 1: + errx(1, "one error"); + default: + errx(1, "%d errors", errcount); + } +} diff --git a/Libraries/libressl/tests/testdsa.bat b/Libraries/libressl/tests/testdsa.bat new file mode 100644 index 000000000..ed2ff93fe --- /dev/null +++ b/Libraries/libressl/tests/testdsa.bat @@ -0,0 +1,35 @@ +@echo off +setlocal enabledelayedexpansion +REM testdsa.bat + + +REM # Test DSA certificate generation of openssl + +set openssl_bin=%1 +set openssl_bin=%openssl_bin:/=\% +if not exist %openssl_bin% exit /b 1 + +REM # Generate DSA paramter set +%openssl_bin% dsaparam 512 -out dsa512.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + + +REM # Generate a DSA certificate +%openssl_bin% req -config %srcdir%\openssl.cnf -x509 -newkey dsa:dsa512.pem -out testdsa.pem -keyout testdsa.key +if !errorlevel! neq 0 ( + exit /b 1 +) + + +REM # Now check the certificate +%openssl_bin% x509 -text -in testdsa.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + +del testdsa.key dsa512.pem testdsa.pem + +exit /b 0 +endlocal diff --git a/Libraries/libressl/tests/testdsa.sh b/Libraries/libressl/tests/testdsa.sh new file mode 100644 index 000000000..7ecb8efb4 --- /dev/null +++ b/Libraries/libressl/tests/testdsa.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# $OpenBSD: testdsa.sh,v 1.1 2014/08/26 17:50:07 jsing Exp $ + + +#Test DSA certificate generation of openssl + +if [ -d ../apps/openssl ]; then + cmd=../apps/openssl/openssl + if [ -e ../apps/openssl/openssl.exe ]; then + cmd=../apps/openssl/openssl.exe + fi +else + cmd=../apps/openssl + if [ -e ../apps/openssl.exe ]; then + cmd=../apps/openssl.exe + fi +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +# Generate DSA paramter set +$cmd dsaparam 512 -out dsa512.pem +if [ $? != 0 ]; then + exit 1; +fi + + +# Denerate a DSA certificate +$cmd req -config $srcdir/openssl.cnf -x509 -newkey dsa:dsa512.pem -out testdsa.pem -keyout testdsa.key +if [ $? != 0 ]; then + exit 1; +fi + + +# Now check the certificate +$cmd x509 -text -in testdsa.pem +if [ $? != 0 ]; then + exit 1; +fi + +rm testdsa.key dsa512.pem testdsa.pem + +exit 0 diff --git a/Libraries/libressl/tests/testenc.bat b/Libraries/libressl/tests/testenc.bat new file mode 100644 index 000000000..cca78d3fe --- /dev/null +++ b/Libraries/libressl/tests/testenc.bat @@ -0,0 +1,69 @@ +@echo off +setlocal enabledelayedexpansion +REM testenc.bat + +set test=p + +set openssl_bin=%1 +set openssl_bin=%openssl_bin:/=\% +if not exist %openssl_bin% exit /b 1 + +copy %srcdir%\openssl.cnf %test% + +echo cat +%openssl_bin% enc -in %test% -out %test%.cipher +%openssl_bin% enc -in %test%.cipher -out %test%.clear +fc /b %test% %test%.clear +if !errorlevel! neq 0 ( + exit /b 1 +) else ( + del %test%.cipher %test%.clear +) + +echo base64 +%openssl_bin% enc -a -e -in %test% -out %test%.cipher +%openssl_bin% enc -a -d -in %test%.cipher -out %test%.clear +fc /b %test% %test%.clear +if !errorlevel! neq 0 ( + exit /b 1 +) else ( + del %test%.cipher %test%.clear +) + +for %%i in ( + aes-128-cbc aes-128-cfb aes-128-cfb1 aes-128-cfb8 + aes-128-ecb aes-128-ofb aes-192-cbc aes-192-cfb + aes-192-cfb1 aes-192-cfb8 aes-192-ecb aes-192-ofb + aes-256-cbc aes-256-cfb aes-256-cfb1 aes-256-cfb8 + aes-256-ecb aes-256-ofb + bf-cbc bf-cfb bf-ecb bf-ofb + cast-cbc cast5-cbc cast5-cfb cast5-ecb cast5-ofb + des-cbc des-cfb des-cfb8 des-ecb des-ede + des-ede-cbc des-ede-cfb des-ede-ofb des-ede3 + des-ede3-cbc des-ede3-cfb des-ede3-ofb des-ofb desx-cbc + rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb + rc4 rc4-40 +) do ( + echo %%i + %openssl_bin% %%i -e -k test -in %test% -out %test%.%%i.cipher + %openssl_bin% %%i -d -k test -in %test%.%%i.cipher -out %test%.%%i.clear + fc /b %test% %test%.%%i.clear + if !errorlevel! neq 0 ( + exit /b 1 + ) else ( + del %test%.%%i.cipher %test%.%%i.clear + ) + + echo %%i base64 + %openssl_bin% %%i -a -e -k test -in %test% -out %test%.%%i.cipher + %openssl_bin% %%i -a -d -k test -in %test%.%%i.cipher -out %test%.%%i.clear + fc /b %test% %test%.%%i.clear + if !errorlevel! neq 0 ( + exit /b 1 + ) else ( + del %test%.%%i.cipher %test%.%%i.clear + ) +) + +del %test% +endlocal diff --git a/Libraries/libressl/tests/testenc.sh b/Libraries/libressl/tests/testenc.sh new file mode 100644 index 000000000..63bce34de --- /dev/null +++ b/Libraries/libressl/tests/testenc.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# $OpenBSD: testenc.sh,v 1.1 2014/08/26 17:50:07 jsing Exp $ + +test=p +if [ -d ../apps/openssl ]; then + cmd=../apps/openssl/openssl + if [ -e ../apps/openssl/openssl.exe ]; then + cmd=../apps/openssl/openssl.exe + fi +else + cmd=../apps/openssl + if [ -e ../apps/openssl.exe ]; then + cmd=../apps/openssl.exe + fi +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +cat $srcdir/openssl.cnf >$test; + +echo cat +$cmd enc < $test > $test.cipher +$cmd enc < $test.cipher >$test.clear +cmp $test $test.clear +if [ $? != 0 ] +then + exit 1 +else + /bin/rm $test.cipher $test.clear +fi +echo base64 +$cmd enc -a -e < $test > $test.cipher +$cmd enc -a -d < $test.cipher >$test.clear +cmp $test $test.clear +if [ $? != 0 ] +then + exit 1 +else + /bin/rm $test.cipher $test.clear +fi + +for i in \ + aes-128-cbc aes-128-cfb aes-128-cfb1 aes-128-cfb8 \ + aes-128-ecb aes-128-ofb aes-192-cbc aes-192-cfb \ + aes-192-cfb1 aes-192-cfb8 aes-192-ecb aes-192-ofb \ + aes-256-cbc aes-256-cfb aes-256-cfb1 aes-256-cfb8 \ + aes-256-ecb aes-256-ofb \ + bf-cbc bf-cfb bf-ecb bf-ofb \ + cast-cbc cast5-cbc cast5-cfb cast5-ecb cast5-ofb \ + des-cbc des-cfb des-cfb8 des-ecb des-ede \ + des-ede-cbc des-ede-cfb des-ede-ofb des-ede3 \ + des-ede3-cbc des-ede3-cfb des-ede3-ofb des-ofb desx-cbc \ + rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb \ + rc4 rc4-40 +do + echo $i + $cmd $i -e -k test < $test > $test.$i.cipher + $cmd $i -d -k test < $test.$i.cipher >$test.$i.clear + cmp $test $test.$i.clear + if [ $? != 0 ] + then + exit 1 + else + /bin/rm $test.$i.cipher $test.$i.clear + fi + + echo $i base64 + $cmd $i -a -e -k test < $test > $test.$i.cipher + $cmd $i -a -d -k test < $test.$i.cipher >$test.$i.clear + cmp $test $test.$i.clear + if [ $? != 0 ] + then + exit 1 + else + /bin/rm $test.$i.cipher $test.$i.clear + fi +done +rm -f $test diff --git a/Libraries/libressl/tests/testrsa.bat b/Libraries/libressl/tests/testrsa.bat new file mode 100644 index 000000000..4947a3031 --- /dev/null +++ b/Libraries/libressl/tests/testrsa.bat @@ -0,0 +1,35 @@ +@echo off +setlocal enabledelayedexpansion +REM testrsa.bat + + +REM # Test RSA certificate generation of openssl + +set openssl_bin=%1 +set openssl_bin=%openssl_bin:/=\% +if not exist %openssl_bin% exit /b 1 + +REM # Generate RSA private key +%openssl_bin% genrsa -out rsakey.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + + +REM # Generate an RSA certificate +%openssl_bin% req -config %srcdir%\openssl.cnf -key rsakey.pem -new -x509 -days 365 -out rsacert.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + + +REM # Now check the certificate +%openssl_bin% x509 -text -in rsacert.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + +del rsacert.pem rsakey.pem + +exit /b 0 +endlocal diff --git a/Libraries/libressl/tests/testrsa.sh b/Libraries/libressl/tests/testrsa.sh new file mode 100644 index 000000000..e64499935 --- /dev/null +++ b/Libraries/libressl/tests/testrsa.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# $OpenBSD: testrsa.sh,v 1.1 2014/08/26 17:50:07 jsing Exp $ + + +#Test RSA certificate generation of openssl + +if [ -d ../apps/openssl ]; then + cmd=../apps/openssl/openssl + if [ -e ../apps/openssl/openssl.exe ]; then + cmd=../apps/openssl/openssl.exe + fi +else + cmd=../apps/openssl + if [ -e ../apps/openssl.exe ]; then + cmd=../apps/openssl.exe + fi +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +# Generate RSA private key +$cmd genrsa -out rsakey.pem +if [ $? != 0 ]; then + exit 1; +fi + + +# Generate an RSA certificate +$cmd req -config $srcdir/openssl.cnf -key rsakey.pem -new -x509 -days 365 -out rsacert.pem +if [ $? != 0 ]; then + exit 1; +fi + + +# Now check the certificate +$cmd x509 -text -in rsacert.pem +if [ $? != 0 ]; then + exit 1; +fi + +rm -f rsacert.pem rsakey.pem + +exit 0 diff --git a/Libraries/libressl/tests/tests.h b/Libraries/libressl/tests/tests.h new file mode 100644 index 000000000..287816946 --- /dev/null +++ b/Libraries/libressl/tests/tests.h @@ -0,0 +1,44 @@ +/* $OpenBSD: tests.h,v 1.1 2015/06/27 23:35:52 doug Exp $ */ +/* + * Copyright (c) 2015 Doug Hogan + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIBRESSL_REGRESS_TESTS_H__ +#define LIBRESSL_REGRESS_TESTS_H__ 1 + +/* Ugly macros that are useful for regression tests. */ + +#define SKIP(a) do { \ + printf("Skipping test in %s [%s:%d]\n", __func__, __FILE__, \ + __LINE__); \ +} while (0) + +#define CHECK(a) do { \ + if (!(a)) { \ + printf("Error in %s [%s:%d]\n", __func__, __FILE__, \ + __LINE__); \ + return 0; \ + } \ +} while (0) + +#define CHECK_GOTO(a) do { \ + if (!(a)) { \ + printf("Error in %s [%s:%d]\n", __func__, __FILE__, \ + __LINE__); \ + goto err; \ + } \ +} while (0) + +#endif /* LIBRESSL_REGRESS_TESTS_H__ */ diff --git a/Libraries/libressl/tests/testssl b/Libraries/libressl/tests/testssl new file mode 100644 index 000000000..70db1752b --- /dev/null +++ b/Libraries/libressl/tests/testssl @@ -0,0 +1,162 @@ +#!/bin/sh + +key="$1" +cert="$2" +CA="-CAfile $3" +ssltest="${4-./ssltest} -key $key -cert $cert -c_key $key -c_cert $cert" +openssl=${5-openssl} +extra="$6" + +$openssl version || exit 1 + +if $openssl x509 -in $cert -text -noout | fgrep 'DSA Public Key' >/dev/null; then + dsa_cert=YES +else + dsa_cert=NO +fi + +############################################################################# + +echo test sslv2/sslv3 +$ssltest $extra || exit 1 + +echo test sslv2/sslv3 with server authentication +$ssltest -server_auth $CA $extra || exit 1 + +echo test sslv2/sslv3 with client authentication +$ssltest -client_auth $CA $extra || exit 1 + +echo test sslv2/sslv3 with both client and server authentication +$ssltest -server_auth -client_auth $CA $extra || exit 1 + +echo test sslv2/sslv3 via BIO pair +$ssltest $extra || exit 1 + +if [ $dsa_cert = NO ]; then + echo 'test sslv2/sslv3 w/o (EC)DHE via BIO pair' + $ssltest -bio_pair -no_dhe -no_ecdhe $extra || exit 1 +fi + +echo test sslv2/sslv3 with 1024bit DHE via BIO pair +$ssltest -bio_pair -dhe1024dsa -v $extra || exit 1 + +echo test sslv2/sslv3 with server authentication +$ssltest -bio_pair -server_auth $CA $extra || exit 1 + +echo test sslv2/sslv3 with client authentication via BIO pair +$ssltest -bio_pair -client_auth $CA $extra || exit 1 + +echo test sslv2/sslv3 with both client and server authentication via BIO pair +$ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1 + +echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify +$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1 + +echo "Testing ciphersuites" +for protocol in SSLv3 TLSv1.2; do + echo "Testing ciphersuites for $protocol" + for cipher in `$openssl ciphers -v "$protocol+aRSA" | + awk "/ $protocol / { print \\$1 }"`; do + echo "Testing $cipher" + $ssltest -cipher $cipher -tls1_2 + if [ $? -ne 0 ] ; then + echo "Failed $cipher" + exit 1 + fi + done +done +for protocol in TLSv1.3; do + echo "Testing ciphersuites for $protocol at security level 2" + for cipher in `$openssl ciphers -v "$protocol" | + awk "/ $protocol / { print \\$1 }"`; do + echo "Testing $cipher" + $ssltest -cipher $cipher -seclevel 2 + if [ $? -ne 0 ] ; then + echo "Failed $cipher" + exit 1 + fi + done +done +for protocol in TLSv1.3; do + echo "Testing ciphersuites for $protocol at security level 3" + for cipher in `$openssl ciphers -v "$protocol" | + awk "/ $protocol / { print \\$1 }"`; do + echo "Testing $cipher" + $ssltest -cipher $cipher -seclevel 3 + if [ $? -eq 0 ] ; then + echo "Failed $cipher should not have succeeded" + exit 1 + fi + done +done + +############################################################################# + +if $openssl no-dh; then + echo skipping anonymous DH tests +else + echo skipping tls1 tests. +fi + +#if $openssl no-rsa; then +# echo skipping RSA tests +#else +# echo 'test tls1 with 1024bit RSA, no (EC)DHE, multiple handshakes' +# ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -no_ecdhe -num 10 -f -time $extra || exit 1 +# +# if $openssl no-dh; then +# echo skipping RSA+DHE tests +# else +# echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes +# ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1 +# fi +#fi + +# +# DTLS tests +# + +$ssltest -dtls1_2 $extra || exit 1 + +echo test dtlsv1_2 with server authentication +$ssltest -dtls1_2 -server_auth $CA $extra || exit 1 + +echo test dtlsv1_2 with client authentication +$ssltest -dtls1_2 -client_auth $CA $extra || exit 1 + +echo test dtlsv1_2 with both client and server authentication +$ssltest -dtls1_2 -server_auth -client_auth $CA $extra || exit 1 + +echo "Testing DTLS ciphersuites" +for protocol in SSLv3; do + echo "Testing ciphersuites for $protocol" + for cipher in `$openssl ciphers -v "RSA+$protocol" | + awk "/ $protocol / { print \\$1 }" | + grep -v RC4`; do + echo "Testing $cipher" + $ssltest -cipher $cipher -dtls1_2 + if [ $? -ne 0 ] ; then + echo "Failed $cipher" + exit 1 + fi + done +done + +# +# ALPN tests +# +echo "Testing ALPN..." +$ssltest -bio_pair -alpn_client foo -alpn_server bar || exit 1 +$ssltest -bio_pair -alpn_client foo -alpn_server foo \ + -alpn_expected foo || exit 1 +$ssltest -bio_pair -alpn_client foo,bar -alpn_server foo \ + -alpn_expected foo || exit 1 +$ssltest -bio_pair -alpn_client bar,foo -alpn_server foo \ + -alpn_expected foo || exit 1 +$ssltest -bio_pair -alpn_client bar,foo -alpn_server foo,bar \ + -alpn_expected foo || exit 1 +$ssltest -bio_pair -alpn_client bar,foo -alpn_server bar,foo \ + -alpn_expected bar || exit 1 +$ssltest -bio_pair -alpn_client foo,bar -alpn_server bar,foo \ + -alpn_expected bar || exit 1 +$ssltest -bio_pair -alpn_client baz -alpn_server bar,foo || exit 1 diff --git a/Libraries/libressl/tests/testssl.bat b/Libraries/libressl/tests/testssl.bat new file mode 100644 index 000000000..4d382440c --- /dev/null +++ b/Libraries/libressl/tests/testssl.bat @@ -0,0 +1,158 @@ +@echo on +setlocal enabledelayedexpansion +REM testssl.bat + +set key=%1 +set cert=%2 +set CA=-CAfile %3 +set ssltest=%4 -key %key% -cert %cert% -c_key %key% -c_cert %cert% +set openssl=%5 +set extra=%6 + +%openssl% version & if !errorlevel! neq 0 exit /b 1 + +set lines=0 +for /f "usebackq" %%s in (`%openssl% x509 -in %cert% -text -noout ^| find "DSA Public Key"`) do ( + set /a lines=%lines%+1 +) +if %lines% gtr 0 ( + set dsa_cert=YES +) else ( + set dsa_cert=NO +) + +REM ######################################################################### + +echo test sslv2/sslv3 +%ssltest% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with server authentication +%ssltest% -server_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with client authentication +%ssltest% -client_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with both client and server authentication +%ssltest% -server_auth -client_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 via BIO pair +%ssltest% %extra% & if !errorlevel! neq 0 exit /b 1 + +if %dsa_cert%==NO ( + echo "test sslv2/sslv3 w/o (EC)DHE via BIO pair" + %ssltest% -bio_pair -no_dhe -no_ecdhe %extra% & if !errorlevel! neq 0 exit /b 1 +) + +echo test sslv2/sslv3 with 1024bit DHE via BIO pair +%ssltest% -bio_pair -dhe1024dsa -v %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with server authentication +%ssltest% -bio_pair -server_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with client authentication via BIO pair +%ssltest% -bio_pair -client_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with both client and server authentication via BIO pair +%ssltest% -bio_pair -server_auth -client_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify +%ssltest% -bio_pair -server_auth -client_auth -app_verify %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo "Testing ciphersuites" +for %%p in ( SSLv3,TLSv1.2 ) do ( + echo "Testing ciphersuites for %%p" + for /f "usebackq" %%c in (`%openssl% ciphers -v "%%p+aRSA" ^| find "%%p"`) do ( + echo "Testing %%c" + %ssltest% -cipher %%c -tls1_2 + if !errorlevel! neq 0 ( + echo "Failed %%c" + exit /b 1 + ) + ) +) +for %%p in ( TLSv1.3 ) do ( + echo "Testing ciphersuites for %%p" + for /f "usebackq" %%c in (`%openssl% ciphers -v "%%p" ^| find "%%p"`) do ( + echo "Testing %%c" + %ssltest% -cipher %%c + if !errorlevel! neq 0 ( + echo "Failed %%c" + exit /b 1 + ) + ) +) + +REM ########################################################################## + +for /f "usebackq" %%s in (`%openssl% no-dh`) do set nodh=%%s +if %nodh%==no-dh ( + echo skipping anonymous DH tests +) else ( + echo skipping tls1 tests. +) + +REM #for /f "usebackq" %%s in (`%openssl% no-rsa`) do set norsa=%%s +REM #if %norsa%==no-rsa ( +REM # echo skipping RSA tests +REM #) else ( +REM # echo "test tls1 with 1024bit RSA, no (EC)DHE, multiple handshakes" +REM # %ssltest% -v -bio_pair -tls1 -cert ..\apps\server2.pem -no_dhe -no_ecdhe -num 10 -f -time %extra% & if !errorlevel! neq 0 exit /b 1 +REM # +REM # for /f "usebackq" %%s in (`%openssl% no-dh`) do set nodh=%%s +REM # if %nodh%==no-dh ( +REM # echo skipping RSA+DHE tests +REM # ) else ( +REM # echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes +REM # %ssltest% -v -bio_pair -tls1 -cert ..\apps\server2.pem -dhe1024dsa -num 10 -f -time %extra% & if !errorlevel! neq 0 exit /b 1 +REM # ) +REM #) + +REM # +REM # DTLS tests +REM # + +echo test dtlsv1_2 +%ssltest% -dtls1_2 %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test dtlsv1_2 with server authentication +%ssltest% -dtls1_2 -server_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test dtlsv1_2 with client authentication +%ssltest% -dtls1_2 -client_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo test dtlsv1_2 with both client and server authentication +%ssltest% -dtls1_2 -server_auth -client_auth %CA% %extra% & if !errorlevel! neq 0 exit /b 1 + +echo "Testing DTLS ciphersuites" +for %%p in ( SSLv3 ) do ( + echo "Testing ciphersuites for %%p" + for /f "usebackq" %%c in (`%openssl% ciphers -v "RSA+%%p:-RC4" ^| find "%%p"`) do ( + echo "Testing %%c" + %ssltest% -cipher %%c -dtls1_2 + if !errorlevel! neq 0 ( + echo "Failed %%c" + exit /b 1 + ) + ) +) + +REM # +REM # ALPN tests +REM # +echo "Testing ALPN..." +%ssltest% -bio_pair -alpn_client foo -alpn_server bar & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client foo -alpn_server foo ^ + -alpn_expected foo & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client foo,bar -alpn_server foo ^ + -alpn_expected foo & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client bar,foo -alpn_server foo ^ + -alpn_expected foo & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client bar,foo -alpn_server foo,bar ^ + -alpn_expected foo & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client bar,foo -alpn_server bar,foo ^ + -alpn_expected bar & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client foo,bar -alpn_server bar,foo ^ + -alpn_expected bar & if !errorlevel! neq 0 exit /b 1 +%ssltest% -bio_pair -alpn_client baz -alpn_server bar,foo & if !errorlevel! neq 0 exit /b 1 + +endlocal diff --git a/Libraries/libressl/tests/timingsafe.c b/Libraries/libressl/tests/timingsafe.c new file mode 100644 index 000000000..f6605f869 --- /dev/null +++ b/Libraries/libressl/tests/timingsafe.c @@ -0,0 +1,68 @@ +/* $OpenBSD: timingsafe.c,v 1.3 2014/06/21 22:57:15 tedu Exp $ */ +/* + * Copyright (c) 2014 Google Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#define ASSERT_EQ(a, b) assert((a) == (b)) + +enum { + N = 8 +}; + +static unsigned char bufone[N], buftwo[N]; + +void +check() +{ + int cmp = memcmp(bufone, buftwo, N); + + /* Check for reflexivity. */ + ASSERT_EQ(0, timingsafe_bcmp(bufone, bufone, N)); + ASSERT_EQ(0, timingsafe_bcmp(buftwo, buftwo, N)); + ASSERT_EQ(0, timingsafe_memcmp(bufone, bufone, N)); + ASSERT_EQ(0, timingsafe_memcmp(buftwo, buftwo, N)); + + /* Check that timingsafe_bcmp returns 0 iff memcmp returns 0. */ + ASSERT_EQ(cmp == 0, timingsafe_bcmp(bufone, buftwo, N) == 0); + + /* Check that timingsafe_memcmp returns cmp... */ + ASSERT_EQ(cmp < 0, timingsafe_memcmp(bufone, buftwo, N) < 0); + + /* ... or -cmp if the argument order is swapped. */ + ASSERT_EQ(-cmp < 0, timingsafe_memcmp(buftwo, bufone, N) < 0); +} + +int +main() +{ + int i, j; + + for (i = 0; i < 10000; i++) { + arc4random_buf(bufone, N); + arc4random_buf(buftwo, N); + + check(); + for (j = 0; j < N; j++) { + buftwo[j] = bufone[j]; + check(); + } + } + + return (0); +} diff --git a/Libraries/libressl/tests/tls_ext_alpn.c b/Libraries/libressl/tests/tls_ext_alpn.c new file mode 100644 index 000000000..d00f3efb5 --- /dev/null +++ b/Libraries/libressl/tests/tls_ext_alpn.c @@ -0,0 +1,442 @@ +/* $OpenBSD: tls_ext_alpn.c,v 1.9 2022/11/26 16:08:57 tb Exp $ */ +/* + * Copyright (c) 2015 Doug Hogan + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Test TLS extension Application-Layer Protocol Negotiation (RFC 7301). + */ +#include +#include + +#include "ssl_local.h" +#include "ssl_tlsext.h" + +#include "tests.h" + +/* + * In the ProtocolNameList, ProtocolNames must not include empty strings and + * byte strings must not be truncated. + * + * This uses some of the IANA approved protocol names from: + * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml + */ + +/* Valid for client and server since it only has one name. */ +static uint8_t proto_single[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0f, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x0b, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x09, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 +}; + +/* Valid for client, but NOT server. Server must have exactly one name. */ +static uint8_t proto_multiple1[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x19, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x15, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x13, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ + 0x09, /* len */ + 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e +}; + +/* Valid for client, but NOT server. Server must have exactly one name. */ +static uint8_t proto_multiple2[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x1c, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x18, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x16, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + /* opaque ProtocolName<1..2^8-1> -- 'h2' */ + 0x02, /* len */ + 0x68, 0x32, + /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ + 0x09, /* len */ + 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e +}; + +/* Valid for client, but NOT server. Server must have exactly one name. */ +static uint8_t proto_multiple3[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x20, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x1c, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x1a, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + /* opaque ProtocolName<1..2^8-1> -- 'h2' */ + 0x02, /* len */ + 0x68, 0x32, + /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ + 0x09, /* len */ + 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e, + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; + +static uint8_t proto_empty[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions. */ + 0x00, 0x00, /* none present. */ +}; + +/* Invalid for both client and server. Length is wrong. */ +static uint8_t proto_invalid_len1[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x04, /* XXX len too large */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len2[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x02, /* XXX len too small */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len3[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x03, /* XXX len too small */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len4[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x06, /* XXX len too large */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len5[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x01, 0x08, /* XXX len too large */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len6[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x05, /* XXX len too small */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len7[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x06, /* XXX len too small */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; +static uint8_t proto_invalid_len8[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0b, /* XXX len too large */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + 0x03, /* len */ + 0x68, 0x32, 0x63 +}; + +/* Invalid for client and server since it is missing data. */ +static uint8_t proto_invalid_missing1[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x06, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x04, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ + /* XXX missing */ +}; +static uint8_t proto_invalid_missing2[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x00, /* XXX missing name list */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ +}; +static uint8_t proto_invalid_missing3[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x02, /* XXX size is sufficient but missing data for name list */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ +}; +static uint8_t proto_invalid_missing4[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x0a, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + /* XXX missing */ +}; +static uint8_t proto_invalid_missing5[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x1c, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x18, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x16, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + /* opaque ProtocolName<1..2^8-1> -- 'h2' */ + 0x02, /* len */ + 0x68, 0x32, + /* XXX missing name */ +}; +static uint8_t proto_invalid_missing6[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x07, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x03, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x01, /* XXX len must be at least 2 */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x00, /* XXX len cannot be 0 */ +}; +static uint8_t proto_invalid_missing7[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x07, /* len */ + /* ExtensionType extension_type */ + 0x00, 0x10, /* ALPN */ + /* opaque extension_data<0..2^16-1> */ + 0x00, 0x03, /* len */ + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x02, /* XXX len is at least 2 but not correct. */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x00, /* XXX len cannot be 0 */ +}; +static uint8_t proto_invalid_missing8[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x00, 0x01, /* len */ + /* ExtensionType extension_type */ + 0x00, /* XXX need a 2 byte type */ +}; +static uint8_t proto_invalid_missing9[] = { + /* Extension extensions<0..2^16-1> -- All TLS extensions */ + 0x0a, /* XXX need a 2 byte len */ +}; + + +#define CHECK_BOTH(c_val, s_val, proto) do { \ + { \ + CBS cbs; \ + int al; \ + \ + CBS_init(&cbs, proto, sizeof(proto)); \ + CHECK(c_val == tlsext_server_parse(s, SSL_TLSEXT_MSG_CH, &cbs, &al)); \ + CBS_init(&cbs, proto, sizeof(proto)); \ + CHECK(s_val == tlsext_client_parse(s, SSL_TLSEXT_MSG_SH, &cbs, &al)); \ + } \ +} while (0) + +static int dummy_alpn_cb(SSL *ssl, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, unsigned int inlen, + void *arg); + +static int +check_valid_alpn(SSL *s) +{ + const uint8_t str[] = { + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* http/1.1 */ + }; + + /* Setup in order to test ALPN. */ + CHECK(! SSL_set_alpn_protos(s, str, 9)); + SSL_CTX_set_alpn_select_cb(s->ctx, dummy_alpn_cb, NULL); + + /* Prerequisites to test these. */ + CHECK(s->alpn_client_proto_list != NULL); + CHECK(s->ctx->alpn_select_cb != NULL); + //CHECK(s->s3->tmp.finish_md_len == 0); + + CHECK_BOTH(1, 1, proto_single); + CHECK_BOTH(1, 1, proto_empty); + + /* Multiple protocol names are only valid for client */ + CHECK_BOTH(1, 0, proto_multiple1); + CHECK_BOTH(1, 0, proto_multiple2); + CHECK_BOTH(1, 0, proto_multiple3); + + return 1; +} + +/* + * Some of the IANA approved IDs from: + * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml + */ +static int +check_invalid_alpn(SSL *s) +{ + const uint8_t str[] = { + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* http/1.1 */ + }; + + /* Setup in order to test ALPN. */ + CHECK(! SSL_set_alpn_protos(s, str, 9)); + SSL_CTX_set_alpn_select_cb(s->ctx, dummy_alpn_cb, NULL); + + /* Prerequisites to test these. */ + CHECK(s->alpn_client_proto_list != NULL); + CHECK(s->ctx->alpn_select_cb != NULL); + //CHECK(s->s3->tmp.finish_md_len == 0); + + /* None of these are valid for client or server */ + CHECK_BOTH(0, 0, proto_invalid_len1); + CHECK_BOTH(0, 0, proto_invalid_len2); + CHECK_BOTH(0, 0, proto_invalid_len3); + CHECK_BOTH(0, 0, proto_invalid_len4); + CHECK_BOTH(0, 0, proto_invalid_len5); + CHECK_BOTH(0, 0, proto_invalid_len6); + CHECK_BOTH(0, 0, proto_invalid_len7); + CHECK_BOTH(0, 0, proto_invalid_len8); + CHECK_BOTH(0, 0, proto_invalid_missing1); + CHECK_BOTH(0, 0, proto_invalid_missing2); + CHECK_BOTH(0, 0, proto_invalid_missing3); + CHECK_BOTH(0, 0, proto_invalid_missing4); + CHECK_BOTH(0, 0, proto_invalid_missing5); + CHECK_BOTH(0, 0, proto_invalid_missing6); + CHECK_BOTH(0, 0, proto_invalid_missing7); + CHECK_BOTH(0, 0, proto_invalid_missing8); + CHECK_BOTH(0, 0, proto_invalid_missing9); + + return 1; +} + +int +dummy_alpn_cb(SSL *ssl __attribute__((unused)), const unsigned char **out, + unsigned char *outlen, const unsigned char *in, unsigned int inlen, + void *arg __attribute__((unused))) +{ + *out = in; + *outlen = (unsigned char)inlen; + + return 0; +} + +int +main(void) +{ + SSL_CTX *ctx = NULL; + SSL *s = NULL; + int rv = 1; + + SSL_library_init(); + + CHECK_GOTO((ctx = SSL_CTX_new(TLSv1_2_client_method())) != NULL); + CHECK_GOTO((s = SSL_new(ctx)) != NULL); + + if (!check_valid_alpn(s)) + goto err; + if (!check_invalid_alpn(s)) + goto err; + + rv = 0; + +err: + SSL_CTX_free(ctx); + SSL_free(s); + + if (!rv) + printf("PASS %s\n", __FILE__); + return rv; +} diff --git a/Libraries/libressl/tests/tls_prf.c b/Libraries/libressl/tests/tls_prf.c new file mode 100644 index 000000000..a22d0e70d --- /dev/null +++ b/Libraries/libressl/tests/tls_prf.c @@ -0,0 +1,251 @@ +/* $OpenBSD: tls_prf.c,v 1.8 2022/11/26 16:08:57 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "ssl_local.h" + +int tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len, + const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len, + const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len, + const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len); + +#define TLS_PRF_OUT_LEN 128 + +struct tls_prf_test { + const unsigned char *desc; + const SSL_METHOD *(*ssl_method)(void); + const uint16_t cipher_value; + const unsigned char out[TLS_PRF_OUT_LEN]; +}; + +static struct tls_prf_test tls_prf_tests[] = { + { + .desc = "MD5+SHA1", + .ssl_method = TLSv1_method, + .cipher_value = 0x0033, + .out = { + 0x03, 0xa1, 0xc1, 0x7d, 0x2c, 0xa5, 0x3d, 0xe8, + 0x9d, 0x59, 0x5e, 0x30, 0xf5, 0x71, 0xbb, 0x96, + 0xde, 0x5c, 0x8e, 0xdc, 0x25, 0x8a, 0x7c, 0x05, + 0x9f, 0x7d, 0x35, 0x29, 0x45, 0xae, 0x56, 0xad, + 0x9f, 0x57, 0x15, 0x5c, 0xdb, 0x83, 0x3a, 0xac, + 0x19, 0xa8, 0x2b, 0x40, 0x72, 0x38, 0x1e, 0xed, + 0xf3, 0x25, 0xde, 0x84, 0x84, 0xd8, 0xd1, 0xfc, + 0x31, 0x85, 0x81, 0x12, 0x55, 0x4d, 0x12, 0xb5, + 0xed, 0x78, 0x5e, 0xba, 0xc8, 0xec, 0x8d, 0x28, + 0xa1, 0x21, 0x1e, 0x6e, 0x07, 0xf1, 0xfc, 0xf5, + 0xbf, 0xe4, 0x8e, 0x8e, 0x97, 0x15, 0x93, 0x85, + 0x75, 0xdd, 0x87, 0x09, 0xd0, 0x4e, 0xe5, 0xd5, + 0x9e, 0x1f, 0xd6, 0x1c, 0x3b, 0xe9, 0xad, 0xba, + 0xe0, 0x16, 0x56, 0x62, 0x90, 0xd6, 0x82, 0x84, + 0xec, 0x8a, 0x22, 0xbe, 0xdc, 0x6a, 0x5e, 0x05, + 0x12, 0x44, 0xec, 0x60, 0x61, 0xd1, 0x8a, 0x66, + }, + }, + { + .desc = "GOST94", + .ssl_method = TLSv1_2_method, + .cipher_value = 0x0081, + .out = { + 0xcc, 0xd4, 0x89, 0x5f, 0x52, 0x08, 0x9b, 0xc7, + 0xf9, 0xb5, 0x83, 0x58, 0xe8, 0xc7, 0x71, 0x49, + 0x39, 0x99, 0x1f, 0x14, 0x8f, 0x85, 0xbe, 0x64, + 0xee, 0x40, 0x5c, 0xe7, 0x5f, 0x68, 0xaf, 0xf2, + 0xcd, 0x3a, 0x94, 0x52, 0x33, 0x53, 0x46, 0x7d, + 0xb6, 0xc5, 0xe1, 0xb8, 0xa4, 0x04, 0x69, 0x91, + 0x0a, 0x9c, 0x88, 0x86, 0xd9, 0x60, 0x63, 0xdd, + 0xd8, 0xe7, 0x2e, 0xee, 0xce, 0xe2, 0x20, 0xd8, + 0x9a, 0xfa, 0x9c, 0x63, 0x0c, 0x9c, 0xa1, 0x76, + 0xed, 0x78, 0x9a, 0x84, 0x70, 0xb4, 0xd1, 0x51, + 0x1f, 0xde, 0x44, 0xe8, 0x90, 0x21, 0x3f, 0xeb, + 0x05, 0xf4, 0x77, 0x59, 0xf3, 0xad, 0xdd, 0x34, + 0x3d, 0x3a, 0x7c, 0xd0, 0x59, 0x40, 0xe1, 0x3f, + 0x04, 0x4b, 0x8b, 0xd6, 0x95, 0x46, 0xb4, 0x9e, + 0x4c, 0x2d, 0xf7, 0xee, 0xbd, 0xbc, 0xcb, 0x5c, + 0x3a, 0x36, 0x0c, 0xd0, 0x27, 0xcb, 0x45, 0x06, + }, + }, + { + .desc = "SHA256 (via TLSv1.2)", + .ssl_method = TLSv1_2_method, + .cipher_value = 0x0033, + .out = { + 0x37, 0xa7, 0x06, 0x71, 0x6e, 0x19, 0x19, 0xda, + 0x23, 0x8c, 0xcc, 0xb4, 0x2f, 0x31, 0x64, 0x9d, + 0x05, 0x29, 0x1c, 0x33, 0x7e, 0x09, 0x1b, 0x0c, + 0x0e, 0x23, 0xc1, 0xb0, 0x40, 0xcc, 0x31, 0xf7, + 0x55, 0x66, 0x68, 0xd9, 0xa8, 0xae, 0x74, 0x75, + 0xf3, 0x46, 0xe9, 0x3a, 0x54, 0x9d, 0xe0, 0x8b, + 0x7e, 0x6c, 0x63, 0x1c, 0xfa, 0x2f, 0xfd, 0xc9, + 0xd3, 0xf1, 0xd3, 0xfe, 0x7b, 0x9e, 0x14, 0x95, + 0xb5, 0xd0, 0xad, 0x9b, 0xee, 0x78, 0x8c, 0x83, + 0x18, 0x58, 0x7e, 0xa2, 0x23, 0xc1, 0x8b, 0x62, + 0x94, 0x12, 0xcb, 0xb6, 0x60, 0x69, 0x32, 0xfe, + 0x98, 0x0e, 0x93, 0xb0, 0x8e, 0x5c, 0xfb, 0x6e, + 0xdb, 0x9a, 0xc2, 0x9f, 0x8c, 0x5c, 0x43, 0x19, + 0xeb, 0x4a, 0x52, 0xad, 0x62, 0x2b, 0xdd, 0x9f, + 0xa3, 0x74, 0xa6, 0x96, 0x61, 0x4d, 0x98, 0x40, + 0x63, 0xa6, 0xd4, 0xbb, 0x17, 0x11, 0x75, 0xed, + }, + }, + { + .desc = "SHA384", + .ssl_method = TLSv1_2_method, + .cipher_value = 0x009d, + .out = { + 0x00, 0x93, 0xc3, 0xfd, 0xa7, 0xbb, 0xdc, 0x5b, + 0x13, 0x3a, 0xe6, 0x8b, 0x1b, 0xac, 0xf3, 0xfb, + 0x3c, 0x9a, 0x78, 0xf6, 0x19, 0xf0, 0x13, 0x0f, + 0x0d, 0x01, 0x9d, 0xdf, 0x0a, 0x28, 0x38, 0xce, + 0x1a, 0x9b, 0x43, 0xbe, 0x56, 0x12, 0xa7, 0x16, + 0x58, 0xe1, 0x8a, 0xe4, 0xc5, 0xbb, 0x10, 0x4c, + 0x3a, 0xf3, 0x7f, 0xd3, 0xdb, 0xe4, 0xe0, 0x3d, + 0xcc, 0x83, 0xca, 0xf0, 0xf9, 0x69, 0xcc, 0x70, + 0x83, 0x32, 0xf6, 0xfc, 0x81, 0x80, 0x02, 0xe8, + 0x31, 0x1e, 0x7c, 0x3b, 0x34, 0xf7, 0x34, 0xd1, + 0xcf, 0x2a, 0xc4, 0x36, 0x2f, 0xe9, 0xaa, 0x7f, + 0x6d, 0x1f, 0x5e, 0x0e, 0x39, 0x05, 0x15, 0xe1, + 0xa2, 0x9a, 0x4d, 0x97, 0x8c, 0x62, 0x46, 0xf1, + 0x87, 0x65, 0xd8, 0xe9, 0x14, 0x11, 0xa6, 0x48, + 0xd7, 0x0e, 0x6e, 0x70, 0xad, 0xfb, 0x3f, 0x36, + 0x05, 0x76, 0x4b, 0xe4, 0x28, 0x50, 0x4a, 0xf2, + }, + }, + { + .desc = "STREEBOG256", + .ssl_method = TLSv1_2_method, + .cipher_value = 0xff87, + .out = { + 0x3e, 0x13, 0xb9, 0xeb, 0x85, 0x8c, 0xb4, 0x21, + 0x23, 0x40, 0x9b, 0x73, 0x04, 0x56, 0xe2, 0xff, + 0xce, 0x52, 0x1f, 0x82, 0x7f, 0x17, 0x5b, 0x80, + 0x23, 0x71, 0xca, 0x30, 0xdf, 0xfc, 0xdc, 0x2d, + 0xc0, 0xfc, 0x5d, 0x23, 0x5a, 0x54, 0x7f, 0xae, + 0xf5, 0x7d, 0x52, 0x1e, 0x86, 0x95, 0xe1, 0x2d, + 0x28, 0xe7, 0xbe, 0xd7, 0xd0, 0xbf, 0xa9, 0x96, + 0x13, 0xd0, 0x9c, 0x0c, 0x1c, 0x16, 0x05, 0xbb, + 0x26, 0xd7, 0x30, 0x39, 0xb9, 0x53, 0x28, 0x98, + 0x4f, 0x1b, 0x83, 0xc3, 0xce, 0x1c, 0x7c, 0x34, + 0xa2, 0xc4, 0x7a, 0x54, 0x16, 0xc6, 0xa7, 0x9e, + 0xed, 0x4b, 0x7b, 0x83, 0xa6, 0xae, 0xe2, 0x5b, + 0x96, 0xf5, 0x6c, 0xad, 0x1f, 0xa3, 0x83, 0xb2, + 0x84, 0x32, 0xed, 0xe3, 0x2c, 0xf6, 0xd4, 0x73, + 0x30, 0xef, 0x9d, 0xbe, 0xe7, 0x23, 0x9a, 0xbf, + 0x4d, 0x1c, 0xe7, 0xef, 0x3d, 0xea, 0x46, 0xe2, + }, + }, +}; + +#define N_TLS_PRF_TESTS \ + (sizeof(tls_prf_tests) / sizeof(*tls_prf_tests)) + +#define TLS_PRF_SEED1 "tls prf seed 1" +#define TLS_PRF_SEED2 "tls prf seed 2" +#define TLS_PRF_SEED3 "tls prf seed 3" +#define TLS_PRF_SEED4 "tls prf seed 4" +#define TLS_PRF_SEED5 "tls prf seed 5" +#define TLS_PRF_SECRET "tls prf secretz" + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static int +do_tls_prf_test(int test_no, struct tls_prf_test *tpt) +{ + unsigned char *out = NULL; + const SSL_CIPHER *cipher; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failure = 1; + int len; + + fprintf(stderr, "Test %d - %s\n", test_no, tpt->desc); + + if ((out = malloc(TLS_PRF_OUT_LEN)) == NULL) + errx(1, "failed to allocate out"); + + if ((ssl_ctx = SSL_CTX_new(tpt->ssl_method())) == NULL) + errx(1, "failed to create SSL context"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL context"); + + if ((cipher = ssl3_get_cipher_by_value(tpt->cipher_value)) == NULL) { + fprintf(stderr, "FAIL: no cipher %hx\n", tpt->cipher_value); + goto failure; + } + + ssl->s3->hs.cipher = cipher; + + for (len = 1; len <= TLS_PRF_OUT_LEN; len++) { + memset(out, 'A', TLS_PRF_OUT_LEN); + + if (tls1_PRF(ssl, TLS_PRF_SECRET, sizeof(TLS_PRF_SECRET), + TLS_PRF_SEED1, sizeof(TLS_PRF_SEED1), TLS_PRF_SEED2, + sizeof(TLS_PRF_SEED2), TLS_PRF_SEED3, sizeof(TLS_PRF_SEED3), + TLS_PRF_SEED4, sizeof(TLS_PRF_SEED4), TLS_PRF_SEED5, + sizeof(TLS_PRF_SEED5), out, len) != 1) { + fprintf(stderr, "FAIL: tls_PRF failed for len %d\n", + len); + goto failure; + } + + if (memcmp(out, tpt->out, len) != 0) { + fprintf(stderr, "FAIL: tls_PRF output differs for " + "len %d\n", len); + fprintf(stderr, "output:\n"); + hexdump(out, TLS_PRF_OUT_LEN); + fprintf(stderr, "test data:\n"); + hexdump(tpt->out, TLS_PRF_OUT_LEN); + fprintf(stderr, "\n"); + goto failure; + } + } + + failure = 0; + + failure: + SSL_free(ssl); + SSL_CTX_free(ssl_ctx); + + free(out); + + return failure; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + SSL_library_init(); + SSL_load_error_strings(); + + for (i = 0; i < N_TLS_PRF_TESTS; i++) + failed |= do_tls_prf_test(i, &tls_prf_tests[i]); + + return failed; +} diff --git a/Libraries/libressl/tests/tlsexttest.c b/Libraries/libressl/tests/tlsexttest.c new file mode 100644 index 000000000..e4da328c6 --- /dev/null +++ b/Libraries/libressl/tests/tlsexttest.c @@ -0,0 +1,4613 @@ +/* $OpenBSD: tlsexttest.c,v 1.82 2023/07/05 17:30:14 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * Copyright (c) 2017 Doug Hogan + * Copyright (c) 2019 Bob Beck + * Copyright (c) 2022 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "ssl_local.h" + +#include "bytestring.h" +#include "ssl_tlsext.h" + +struct tls_extension_funcs { + int (*needs)(SSL *s, uint16_t msg_type); + int (*build)(SSL *s, uint16_t msg_type, CBB *cbb); + int (*parse)(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); +}; + +uint16_t tls_extension_type(const struct tls_extension *); +const struct tls_extension *tls_extension_find(uint16_t, size_t *); +const struct tls_extension_funcs *tlsext_funcs(const struct tls_extension *, + int); +int tlsext_linearize_build_order(SSL *); + +static int +tls_extension_funcs(int type, const struct tls_extension_funcs **client_funcs, + const struct tls_extension_funcs **server_funcs) +{ + const struct tls_extension *ext; + size_t idx; + + if ((ext = tls_extension_find(type, &idx)) == NULL) + return 0; + + if ((*client_funcs = tlsext_funcs(ext, 0)) == NULL) + return 0; + + if ((*server_funcs = tlsext_funcs(ext, 1)) == NULL) + return 0; + + return 1; +} + +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static void +hexdump2(const uint16_t *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len / 2; i++) + fprintf(stderr, " 0x%04hx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + fprintf(stderr, "\n"); +} + +static void +compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, + size_t expect_len) +{ + fprintf(stderr, "received:\n"); + hexdump(recv, recv_len); + + fprintf(stderr, "test data:\n"); + hexdump(expect, expect_len); +} + +static void +compare_data2(const uint16_t *recv, size_t recv_len, const uint16_t *expect, + size_t expect_len) +{ + fprintf(stderr, "received:\n"); + hexdump2(recv, recv_len); + + fprintf(stderr, "test data:\n"); + hexdump2(expect, expect_len); +} + +#define FAIL(msg, ...) \ +do { \ + fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ + fprintf(stderr, msg, ##__VA_ARGS__); \ +} while(0) + +/* + * Supported Application-Layer Protocol Negotiation - RFC 7301 + * + * There are already extensive unit tests for this so this just + * tests the state info. + */ + +const uint8_t tlsext_alpn_multiple_protos_val[] = { + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ + 0x09, /* len */ + 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e +}; + +const uint8_t tlsext_alpn_multiple_protos[] = { + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x13, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ + 0x09, /* len */ + 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e +}; + +const uint8_t tlsext_alpn_single_proto_val[] = { + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 +}; + +const uint8_t tlsext_alpn_single_proto_name[] = { + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* 'http/1.1' */ +}; + +const uint8_t tlsext_alpn_single_proto[] = { + /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ + 0x00, 0x09, /* len of all names */ + /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ + 0x08, /* len */ + 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 +}; + +#define TLSEXT_TYPE_alpn TLSEXT_TYPE_application_layer_protocol_negotiation + +static int +test_tlsext_alpn_client(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + uint8_t *data = NULL; + CBB cbb; + CBS cbs; + int failure, alert; + size_t dlen; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_alpn, &client_funcs, &server_funcs)) + errx(1, "failed to fetch ALPN funcs"); + + /* By default, we don't need this */ + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need ALPN by default\n"); + goto err; + } + + /* + * Prereqs: + * 1) Set s->alpn_client_proto_list + * - Using SSL_set_alpn_protos() + * 2) We have not finished or renegotiated. + * - s->s3->tmp.finish_md_len == 0 + */ + if (SSL_set_alpn_protos(ssl, tlsext_alpn_single_proto_val, + sizeof(tlsext_alpn_single_proto_val)) != 0) { + FAIL("should be able to set ALPN to http/1.1\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need ALPN by default\n"); + goto err; + } + + /* Make sure we can build the client with a single proto. */ + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build ALPN\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_alpn_single_proto)) { + FAIL("got client ALPN with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_alpn_single_proto)); + compare_data(data, dlen, tlsext_alpn_single_proto, + sizeof(tlsext_alpn_single_proto)); + goto err; + } + if (memcmp(data, tlsext_alpn_single_proto, dlen) != 0) { + FAIL("client ALPN differs:\n"); + compare_data(data, dlen, tlsext_alpn_single_proto, + sizeof(tlsext_alpn_single_proto)); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* Make sure we can parse the single proto. */ + + CBS_init(&cbs, tlsext_alpn_single_proto, + sizeof(tlsext_alpn_single_proto)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse ALPN\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->alpn_client_proto_list_len != + sizeof(tlsext_alpn_single_proto_val)) { + FAIL("got client ALPN with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_alpn_single_proto_val)); + compare_data(ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len, + tlsext_alpn_single_proto_val, + sizeof(tlsext_alpn_single_proto_val)); + goto err; + } + if (memcmp(ssl->alpn_client_proto_list, + tlsext_alpn_single_proto_val, + sizeof(tlsext_alpn_single_proto_val)) != 0) { + FAIL("client ALPN differs:\n"); + compare_data(data, dlen, tlsext_alpn_single_proto_val, + sizeof(tlsext_alpn_single_proto_val)); + goto err; + } + + /* Make sure we can build the clienthello with multiple entries. */ + + if (SSL_set_alpn_protos(ssl, tlsext_alpn_multiple_protos_val, + sizeof(tlsext_alpn_multiple_protos_val)) != 0) { + FAIL("should be able to set ALPN to http/1.1\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need ALPN by now\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build ALPN\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_alpn_multiple_protos)) { + FAIL("got client ALPN with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_alpn_multiple_protos)); + compare_data(data, dlen, tlsext_alpn_multiple_protos, + sizeof(tlsext_alpn_multiple_protos)); + goto err; + } + if (memcmp(data, tlsext_alpn_multiple_protos, dlen) != 0) { + FAIL("client ALPN differs:\n"); + compare_data(data, dlen, tlsext_alpn_multiple_protos, + sizeof(tlsext_alpn_multiple_protos)); + goto err; + } + + /* Make sure we can parse multiple protos */ + + CBS_init(&cbs, tlsext_alpn_multiple_protos, + sizeof(tlsext_alpn_multiple_protos)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse ALPN\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->alpn_client_proto_list_len != + sizeof(tlsext_alpn_multiple_protos_val)) { + FAIL("got client ALPN with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_alpn_multiple_protos_val)); + compare_data(ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len, + tlsext_alpn_multiple_protos_val, + sizeof(tlsext_alpn_multiple_protos_val)); + goto err; + } + if (memcmp(ssl->alpn_client_proto_list, + tlsext_alpn_multiple_protos_val, + sizeof(tlsext_alpn_multiple_protos_val)) != 0) { + FAIL("client ALPN differs:\n"); + compare_data(data, dlen, tlsext_alpn_multiple_protos_val, + sizeof(tlsext_alpn_multiple_protos_val)); + goto err; + } + + /* Make sure we can remove the list and avoid ALPN */ + + free(ssl->alpn_client_proto_list); + ssl->alpn_client_proto_list = NULL; + ssl->alpn_client_proto_list_len = 0; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need ALPN by default\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_alpn_server(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + uint8_t *data = NULL; + CBB cbb; + CBS cbs; + int failure, alert; + size_t dlen; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_alpn, &client_funcs, &server_funcs)) + errx(1, "failed to fetch ALPN funcs"); + + /* By default, ALPN isn't needed. */ + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need ALPN by default\n"); + goto err; + } + + /* + * The server has a single ALPN selection which is set by + * SSL_CTX_set_alpn_select_cb() and calls SSL_select_next_proto(). + * + * This will be a plain name and separate length. + */ + if ((ssl->s3->alpn_selected = malloc(sizeof(tlsext_alpn_single_proto_name))) == NULL) { + errx(1, "failed to malloc"); + } + memcpy(ssl->s3->alpn_selected, tlsext_alpn_single_proto_name, + sizeof(tlsext_alpn_single_proto_name)); + ssl->s3->alpn_selected_len = sizeof(tlsext_alpn_single_proto_name); + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need ALPN after a protocol is selected\n"); + goto err; + } + + /* Make sure we can build a server with one protocol */ + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server should be able to build a response\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_alpn_single_proto)) { + FAIL("got client ALPN with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_alpn_single_proto)); + compare_data(data, dlen, tlsext_alpn_single_proto, + sizeof(tlsext_alpn_single_proto)); + goto err; + } + if (memcmp(data, tlsext_alpn_single_proto, dlen) != 0) { + FAIL("client ALPN differs:\n"); + compare_data(data, dlen, tlsext_alpn_single_proto, + sizeof(tlsext_alpn_single_proto)); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* Make sure we can parse the single proto. */ + + CBS_init(&cbs, tlsext_alpn_single_proto, + sizeof(tlsext_alpn_single_proto)); + + /* Shouldn't be able to parse without requesting */ + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("Should only parse server if we requested it\n"); + goto err; + } + + /* Should be able to parse once requested. */ + if (SSL_set_alpn_protos(ssl, tlsext_alpn_single_proto_val, + sizeof(tlsext_alpn_single_proto_val)) != 0) { + FAIL("should be able to set ALPN to http/1.1\n"); + goto err; + } + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("Should be able to parse server when we request it\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->s3->alpn_selected_len != + sizeof(tlsext_alpn_single_proto_name)) { + FAIL("got server ALPN with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_alpn_single_proto_name)); + compare_data(ssl->s3->alpn_selected, + ssl->s3->alpn_selected_len, + tlsext_alpn_single_proto_name, + sizeof(tlsext_alpn_single_proto_name)); + goto err; + } + if (memcmp(ssl->s3->alpn_selected, + tlsext_alpn_single_proto_name, + sizeof(tlsext_alpn_single_proto_name)) != 0) { + FAIL("server ALPN differs:\n"); + compare_data(ssl->s3->alpn_selected, + ssl->s3->alpn_selected_len, + tlsext_alpn_single_proto_name, + sizeof(tlsext_alpn_single_proto_name)); + goto err; + } + + /* + * We should NOT be able to build a server with multiple + * protocol names. However, the existing code did not check for this + * case because it is passed in as an encoded value. + */ + + /* Make sure we can remove the list and avoid ALPN */ + + free(ssl->s3->alpn_selected); + ssl->s3->alpn_selected = NULL; + ssl->s3->alpn_selected_len = 0; + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need ALPN by default\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); + +} + +/* + * Supported Elliptic Curves - RFC 4492 section 5.1.1. + * + * This extension is only used by the client. + */ + +static const uint8_t tlsext_supportedgroups_client_default[] = { + 0x00, 0x08, + 0x00, 0x1d, /* X25519 (29) */ + 0x00, 0x17, /* secp256r1 (23) */ + 0x00, 0x18, /* secp384r1 (24) */ + 0x00, 0x19, /* secp521r1 (25) */ +}; + +static const uint16_t tlsext_supportedgroups_client_secp384r1_val[] = { + 0x0018 /* tls1_ec_nid2group_id(NID_secp384r1) */ +}; +static const uint8_t tlsext_supportedgroups_client_secp384r1[] = { + 0x00, 0x02, + 0x00, 0x18 /* secp384r1 (24) */ +}; + +/* Example from RFC 4492 section 5.1.1 */ +static const uint16_t tlsext_supportedgroups_client_nistp192and224_val[] = { + 0x0013, /* tls1_ec_nid2group_id(NID_X9_62_prime192v1) */ + 0x0015 /* tls1_ec_nid2group_id(NID_secp224r1) */ +}; +static const uint8_t tlsext_supportedgroups_client_nistp192and224[] = { + 0x00, 0x04, + 0x00, 0x13, /* secp192r1 aka NIST P-192 */ + 0x00, 0x15 /* secp224r1 aka NIST P-224 */ +}; + +static int +test_tlsext_supportedgroups_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + size_t dlen; + int failure, alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_supported_groups, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch supported groups funcs"); + + /* + * Default ciphers include EC so we need it by default. + */ + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need Ellipticcurves for default " + "ciphers\n"); + goto err; + } + + /* + * Exclude cipher suites so we can test not including it. + */ + if (!SSL_set_cipher_list(ssl, "TLSv1.2:!ECDHE:!ECDSA")) { + FAIL("client should be able to set cipher list\n"); + goto err; + } + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need Ellipticcurves\n"); + goto err; + } + + /* + * Use libtls default for the rest of the testing + */ + if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { + FAIL("client should be able to set cipher list\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need Ellipticcurves\n"); + goto err; + } + + /* + * Test with a session secp384r1. The default is used instead. + */ + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if ((ssl->session->tlsext_supportedgroups = malloc(sizeof(uint16_t))) + == NULL) { + FAIL("client could not malloc\n"); + goto err; + } + if (!tls1_ec_nid2group_id(NID_secp384r1, + &ssl->session->tlsext_supportedgroups[0])) + goto err; + ssl->session->tlsext_supportedgroups_length = 1; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need Ellipticcurves\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build Ellipticcurves\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_supportedgroups_client_default)) { + FAIL("got client Ellipticcurves with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_supportedgroups_client_default)); + compare_data(data, dlen, tlsext_supportedgroups_client_default, + sizeof(tlsext_supportedgroups_client_default)); + goto err; + } + + if (memcmp(data, tlsext_supportedgroups_client_default, dlen) != 0) { + FAIL("client Ellipticcurves differs:\n"); + compare_data(data, dlen, tlsext_supportedgroups_client_default, + sizeof(tlsext_supportedgroups_client_default)); + goto err; + } + + /* + * Test parsing secp384r1 + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + CBS_init(&cbs, tlsext_supportedgroups_client_secp384r1, + sizeof(tlsext_supportedgroups_client_secp384r1)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client Ellipticcurves\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_supportedgroups_length != + sizeof(tlsext_supportedgroups_client_secp384r1_val) / sizeof(uint16_t)) { + FAIL("no tlsext_ellipticcurves from client " + "Ellipticcurves\n"); + goto err; + } + + if (memcmp(ssl->session->tlsext_supportedgroups, + tlsext_supportedgroups_client_secp384r1_val, + sizeof(tlsext_supportedgroups_client_secp384r1_val)) != 0) { + FAIL("client had an incorrect Ellipticcurves " + "entry\n"); + compare_data2(ssl->session->tlsext_supportedgroups, + ssl->session->tlsext_supportedgroups_length * 2, + tlsext_supportedgroups_client_secp384r1_val, + sizeof(tlsext_supportedgroups_client_secp384r1_val)); + goto err; + } + + /* + * Use a custom order. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if ((ssl->tlsext_supportedgroups = malloc(sizeof(uint16_t) * 2)) == NULL) { + FAIL("client could not malloc\n"); + goto err; + } + if (!tls1_ec_nid2group_id(NID_X9_62_prime192v1, + &ssl->tlsext_supportedgroups[0])) + goto err; + if (!tls1_ec_nid2group_id(NID_secp224r1, + &ssl->tlsext_supportedgroups[1])) + goto err; + ssl->tlsext_supportedgroups_length = 2; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need Ellipticcurves\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build Ellipticcurves\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_supportedgroups_client_nistp192and224)) { + FAIL("got client Ellipticcurves with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_supportedgroups_client_nistp192and224)); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_supportedgroups_client_nistp192and224, + sizeof(tlsext_supportedgroups_client_nistp192and224)); + goto err; + } + + if (memcmp(data, tlsext_supportedgroups_client_nistp192and224, dlen) != 0) { + FAIL("client Ellipticcurves differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_supportedgroups_client_nistp192and224, + sizeof(tlsext_supportedgroups_client_nistp192and224)); + goto err; + } + + /* + * Parse non-default curves to session. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + /* Reset back to the default list. */ + free(ssl->tlsext_supportedgroups); + ssl->tlsext_supportedgroups = NULL; + ssl->tlsext_supportedgroups_length = 0; + + CBS_init(&cbs, tlsext_supportedgroups_client_nistp192and224, + sizeof(tlsext_supportedgroups_client_nistp192and224)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client Ellipticcurves\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_supportedgroups_length != + sizeof(tlsext_supportedgroups_client_nistp192and224_val) / sizeof(uint16_t)) { + FAIL("no tlsext_ellipticcurves from client Ellipticcurves\n"); + goto err; + } + + if (memcmp(ssl->session->tlsext_supportedgroups, + tlsext_supportedgroups_client_nistp192and224_val, + sizeof(tlsext_supportedgroups_client_nistp192and224_val)) != 0) { + FAIL("client had an incorrect Ellipticcurves entry\n"); + compare_data2(ssl->session->tlsext_supportedgroups, + ssl->session->tlsext_supportedgroups_length * 2, + tlsext_supportedgroups_client_nistp192and224_val, + sizeof(tlsext_supportedgroups_client_nistp192and224_val)); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + + +/* elliptic_curves is only used by the client so this doesn't test much. */ +static int +test_tlsext_supportedgroups_server(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + + failure = 1; + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_supported_groups, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch supported groups funcs"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need elliptic_curves\n"); + goto err; + } + + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need elliptic_curves\n"); + goto err; + } + + failure = 0; + + err: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return (failure); + +} + +/* + * Supported Point Formats - RFC 4492 section 5.1.2. + * + * Examples are from the RFC. Both client and server have the same build and + * parse but the needs differ. + */ + +static const uint8_t tlsext_ecpf_hello_uncompressed_val[] = { + TLSEXT_ECPOINTFORMAT_uncompressed +}; +static const uint8_t tlsext_ecpf_hello_uncompressed[] = { + 0x01, + 0x00 /* TLSEXT_ECPOINTFORMAT_uncompressed */ +}; + +static const uint8_t tlsext_ecpf_hello_prime[] = { + 0x01, + 0x01 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ +}; + +static const uint8_t tlsext_ecpf_hello_prefer_order_val[] = { + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, + TLSEXT_ECPOINTFORMAT_uncompressed, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 +}; +static const uint8_t tlsext_ecpf_hello_prefer_order[] = { + 0x03, + 0x01, /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ + 0x00, /* TLSEXT_ECPOINTFORMAT_uncompressed */ + 0x02 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 */ +}; + +static int +test_tlsext_ecpf_client(void) +{ + uint8_t *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + size_t dlen; + int failure, alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_ec_point_formats, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch ecpf funcs"); + + /* + * Default ciphers include EC so we need it by default. + */ + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need ECPointFormats for default " + "ciphers\n"); + goto err; + } + + /* + * Exclude EC cipher suites so we can test not including it. + */ + if (!SSL_set_cipher_list(ssl, "ALL:!ECDHE:!ECDH")) { + FAIL("client should be able to set cipher list\n"); + goto err; + } + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need ECPointFormats\n"); + goto err; + } + + /* + * Use libtls default for the rest of the testing + */ + if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { + FAIL("client should be able to set cipher list\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need ECPointFormats\n"); + goto err; + } + + /* + * The default ECPointFormats should only have uncompressed + */ + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build ECPointFormats\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ecpf_hello_uncompressed)) { + FAIL("got client ECPointFormats with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_ecpf_hello_uncompressed)); + compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, + sizeof(tlsext_ecpf_hello_uncompressed)); + goto err; + } + + if (memcmp(data, tlsext_ecpf_hello_uncompressed, dlen) != 0) { + FAIL("client ECPointFormats differs:\n"); + compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, + sizeof(tlsext_ecpf_hello_uncompressed)); + goto err; + } + + /* + * Make sure we can parse the default. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + CBS_init(&cbs, tlsext_ecpf_hello_uncompressed, + sizeof(tlsext_ecpf_hello_uncompressed)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client ECPointFormats\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_ecpointformatlist_length != + sizeof(tlsext_ecpf_hello_uncompressed_val)) { + FAIL("no tlsext_ecpointformats from client " + "ECPointFormats\n"); + goto err; + } + + if (memcmp(ssl->session->tlsext_ecpointformatlist, + tlsext_ecpf_hello_uncompressed_val, + sizeof(tlsext_ecpf_hello_uncompressed_val)) != 0) { + FAIL("client had an incorrect ECPointFormats entry\n"); + goto err; + } + + /* + * Test with a custom order. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if ((ssl->tlsext_ecpointformatlist = malloc(sizeof(uint8_t) * 3)) == NULL) { + FAIL("client could not malloc\n"); + goto err; + } + ssl->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + ssl->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_uncompressed; + ssl->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + ssl->tlsext_ecpointformatlist_length = 3; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need ECPointFormats with a custom " + "format\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build ECPointFormats\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ecpf_hello_prefer_order)) { + FAIL("got client ECPointFormats with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_ecpf_hello_prefer_order)); + compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, + sizeof(tlsext_ecpf_hello_prefer_order)); + goto err; + } + + if (memcmp(data, tlsext_ecpf_hello_prefer_order, dlen) != 0) { + FAIL("client ECPointFormats differs:\n"); + compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, + sizeof(tlsext_ecpf_hello_prefer_order)); + goto err; + } + + /* + * Make sure that we can parse this custom order. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + /* Reset the custom list so we go back to the default uncompressed. */ + free(ssl->tlsext_ecpointformatlist); + ssl->tlsext_ecpointformatlist = NULL; + ssl->tlsext_ecpointformatlist_length = 0; + + CBS_init(&cbs, tlsext_ecpf_hello_prefer_order, + sizeof(tlsext_ecpf_hello_prefer_order)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client ECPointFormats\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_ecpointformatlist_length != + sizeof(tlsext_ecpf_hello_prefer_order_val)) { + FAIL("no tlsext_ecpointformats from client " + "ECPointFormats\n"); + goto err; + } + + if (memcmp(ssl->session->tlsext_ecpointformatlist, + tlsext_ecpf_hello_prefer_order_val, + sizeof(tlsext_ecpf_hello_prefer_order_val)) != 0) { + FAIL("client had an incorrect ECPointFormats entry\n"); + goto err; + } + + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_ecpf_server(void) +{ + uint8_t *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + size_t dlen; + int failure, alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_ec_point_formats, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch ecpf funcs"); + + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + /* Setup the state so we can call needs. */ + if ((ssl->s3->hs.cipher = + ssl3_get_cipher_by_id(TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305)) + == NULL) { + FAIL("server cannot find cipher\n"); + goto err; + } + if ((ssl->session->tlsext_ecpointformatlist = malloc(sizeof(uint8_t))) + == NULL) { + FAIL("server could not malloc\n"); + goto err; + } + ssl->session->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + ssl->session->tlsext_ecpointformatlist_length = 1; + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need ECPointFormats now\n"); + goto err; + } + + /* + * The server will ignore the session list and use either a custom + * list or the default (uncompressed). + */ + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server failed to build ECPointFormats\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ecpf_hello_uncompressed)) { + FAIL("got server ECPointFormats with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_ecpf_hello_uncompressed)); + compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, + sizeof(tlsext_ecpf_hello_uncompressed)); + goto err; + } + + if (memcmp(data, tlsext_ecpf_hello_uncompressed, dlen) != 0) { + FAIL("server ECPointFormats differs:\n"); + compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, + sizeof(tlsext_ecpf_hello_uncompressed)); + goto err; + } + + /* + * Cannot parse a non-default list without at least uncompressed. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + CBS_init(&cbs, tlsext_ecpf_hello_prime, + sizeof(tlsext_ecpf_hello_prime)); + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("must include uncompressed in server ECPointFormats\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + /* + * Test with a custom order that replaces the default uncompressed. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + /* Add a session list even though it will be ignored. */ + if ((ssl->session->tlsext_ecpointformatlist = malloc(sizeof(uint8_t))) + == NULL) { + FAIL("server could not malloc\n"); + goto err; + } + ssl->session->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + ssl->session->tlsext_ecpointformatlist_length = 1; + + /* Replace the default list with a custom one. */ + if ((ssl->tlsext_ecpointformatlist = malloc(sizeof(uint8_t) * 3)) == NULL) { + FAIL("server could not malloc\n"); + goto err; + } + ssl->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + ssl->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_uncompressed; + ssl->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + ssl->tlsext_ecpointformatlist_length = 3; + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need ECPointFormats\n"); + goto err; + } + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server failed to build ECPointFormats\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ecpf_hello_prefer_order)) { + FAIL("got server ECPointFormats with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_ecpf_hello_prefer_order)); + compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, + sizeof(tlsext_ecpf_hello_prefer_order)); + goto err; + } + + if (memcmp(data, tlsext_ecpf_hello_prefer_order, dlen) != 0) { + FAIL("server ECPointFormats differs:\n"); + compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, + sizeof(tlsext_ecpf_hello_prefer_order)); + goto err; + } + + /* + * Should be able to parse the custom list into a session list. + */ + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + /* Reset back to the default (uncompressed) */ + free(ssl->tlsext_ecpointformatlist); + ssl->tlsext_ecpointformatlist = NULL; + ssl->tlsext_ecpointformatlist_length = 0; + + CBS_init(&cbs, tlsext_ecpf_hello_prefer_order, + sizeof(tlsext_ecpf_hello_prefer_order)); + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse server ECPointFormats\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_ecpointformatlist_length != + sizeof(tlsext_ecpf_hello_prefer_order_val)) { + FAIL("no tlsext_ecpointformats from server " + "ECPointFormats\n"); + goto err; + } + + if (memcmp(ssl->session->tlsext_ecpointformatlist, + tlsext_ecpf_hello_prefer_order_val, + sizeof(tlsext_ecpf_hello_prefer_order_val)) != 0) { + FAIL("server had an incorrect ECPointFormats entry\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +/* + * Renegotiation Indication - RFC 5746. + */ + +static const unsigned char tlsext_ri_prev_client[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +}; + +static const unsigned char tlsext_ri_prev_server[] = { + 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, +}; + +static const unsigned char tlsext_ri_client[] = { + 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +}; + +static const unsigned char tlsext_ri_server[] = { + 0x20, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, +}; + +static int +test_tlsext_ri_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLSv1_2_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_renegotiate, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch ri funcs"); + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need RI\n"); + goto err; + } + + if (!SSL_renegotiate(ssl)) { + FAIL("client failed to set renegotiate\n"); + goto err; + } + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need RI\n"); + goto err; + } + + memcpy(ssl->s3->previous_client_finished, tlsext_ri_prev_client, + sizeof(tlsext_ri_prev_client)); + ssl->s3->previous_client_finished_len = sizeof(tlsext_ri_prev_client); + + ssl->s3->renegotiate_seen = 0; + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build RI\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ri_client)) { + FAIL("got client RI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_ri_client)); + goto err; + } + + if (memcmp(data, tlsext_ri_client, dlen) != 0) { + FAIL("client RI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_ri_client, sizeof(tlsext_ri_client)); + goto err; + } + + CBS_init(&cbs, tlsext_ri_client, sizeof(tlsext_ri_client)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client RI\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->s3->renegotiate_seen != 1) { + FAIL("renegotiate seen not set\n"); + goto err; + } + if (ssl->s3->send_connection_binding != 1) { + FAIL("send connection binding not set\n"); + goto err; + } + + memset(ssl->s3->previous_client_finished, 0, + sizeof(ssl->s3->previous_client_finished)); + + ssl->s3->renegotiate_seen = 0; + + CBS_init(&cbs, tlsext_ri_client, sizeof(tlsext_ri_client)); + if (server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("parsed invalid client RI\n"); + goto err; + } + + if (ssl->s3->renegotiate_seen == 1) { + FAIL("renegotiate seen set\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_ri_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_renegotiate, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch ri funcs"); + + ssl->version = TLS1_2_VERSION; + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need RI\n"); + goto err; + } + + ssl->s3->send_connection_binding = 1; + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need RI\n"); + goto err; + } + + memcpy(ssl->s3->previous_client_finished, tlsext_ri_prev_client, + sizeof(tlsext_ri_prev_client)); + ssl->s3->previous_client_finished_len = sizeof(tlsext_ri_prev_client); + + memcpy(ssl->s3->previous_server_finished, tlsext_ri_prev_server, + sizeof(tlsext_ri_prev_server)); + ssl->s3->previous_server_finished_len = sizeof(tlsext_ri_prev_server); + + ssl->s3->renegotiate_seen = 0; + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server failed to build RI\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ri_server)) { + FAIL("got server RI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_ri_server)); + goto err; + } + + if (memcmp(data, tlsext_ri_server, dlen) != 0) { + FAIL("server RI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_ri_server, sizeof(tlsext_ri_server)); + goto err; + } + + CBS_init(&cbs, tlsext_ri_server, sizeof(tlsext_ri_server)); + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse server RI\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->s3->renegotiate_seen != 1) { + FAIL("renegotiate seen not set\n"); + goto err; + } + if (ssl->s3->send_connection_binding != 1) { + FAIL("send connection binding not set\n"); + goto err; + } + + memset(ssl->s3->previous_client_finished, 0, + sizeof(ssl->s3->previous_client_finished)); + memset(ssl->s3->previous_server_finished, 0, + sizeof(ssl->s3->previous_server_finished)); + + ssl->s3->renegotiate_seen = 0; + + CBS_init(&cbs, tlsext_ri_server, sizeof(tlsext_ri_server)); + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("parsed invalid server RI\n"); + goto err; + } + + if (ssl->s3->renegotiate_seen == 1) { + FAIL("renegotiate seen set\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +/* + * Signature Algorithms - RFC 5246 section 7.4.1.4.1. + */ + +static const unsigned char tlsext_sigalgs_client[] = { + 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03, + 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, + 0x04, 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, +}; + +static int +test_tlsext_sigalgs_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_signature_algorithms, + &client_funcs, &server_funcs)) + errx(1, "failed to fetch sigalgs funcs"); + + ssl->s3->hs.our_max_tls_version = TLS1_1_VERSION; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need sigalgs\n"); + goto done; + } + + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need sigalgs\n"); + goto done; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build sigalgs\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_sigalgs_client)) { + FAIL("got client sigalgs length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_sigalgs_client)); + goto done; + } + + if (memcmp(data, tlsext_sigalgs_client, dlen) != 0) { + FAIL("client SNI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_sigalgs_client, sizeof(tlsext_sigalgs_client)); + goto done; + } + + CBS_init(&cbs, tlsext_sigalgs_client, sizeof(tlsext_sigalgs_client)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client SNI\n"); + goto done; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +#if 0 +static int +test_tlsext_sigalgs_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_server_name, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch sigalgs funcs"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need sigalgs\n"); + goto done; + } + + if (server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server should not build sigalgs\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + CBS_init(&cbs, tlsext_sigalgs_client, sizeof(tlsext_sigalgs_client)); + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("server should not parse sigalgs\n"); + goto done; + } + + failure = 0; + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} +#endif + +/* + * Server Name Indication - RFC 6066 section 3. + */ + +#define TEST_SNI_SERVERNAME "www.libressl.org" + +static const unsigned char tlsext_sni_client[] = { + 0x00, 0x13, 0x00, 0x00, 0x10, 0x77, 0x77, 0x77, + 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, +}; + +/* An empty array is an incomplete type and sizeof() is undefined. */ +static const unsigned char tlsext_sni_server[] = { + 0x00, +}; +static size_t tlsext_sni_server_len = 0; + +static int +test_tlsext_sni_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_server_name, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch sni funcs"); + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need SNI\n"); + goto err; + } + + if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { + FAIL("client failed to set server name\n"); + goto err; + } + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need SNI\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build SNI\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB"); + goto err; + } + + if (dlen != sizeof(tlsext_sni_client)) { + FAIL("got client SNI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_sni_client)); + goto err; + } + + if (memcmp(data, tlsext_sni_client, dlen) != 0) { + FAIL("client SNI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_sni_client, sizeof(tlsext_sni_client)); + goto err; + } + + /* + * SSL_set_tlsext_host_name() may be called with a NULL host name to + * disable SNI. + */ + if (!SSL_set_tlsext_host_name(ssl, NULL)) { + FAIL("cannot set host name to NULL"); + goto err; + } + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need SNI\n"); + goto err; + } + + if ((ssl->session = SSL_SESSION_new()) == NULL) { + FAIL("failed to create session"); + goto err; + } + + ssl->hit = 0; + + CBS_init(&cbs, tlsext_sni_client, sizeof(tlsext_sni_client)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client SNI\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_hostname == NULL) { + FAIL("no tlsext_hostname from client SNI\n"); + goto err; + } + + if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || + strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, + strlen(TEST_SNI_SERVERNAME)) != 0) { + FAIL("got tlsext_hostname `%s', want `%s'\n", + ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); + goto err; + } + + ssl->hit = 1; + + free(ssl->session->tlsext_hostname); + if ((ssl->session->tlsext_hostname = strdup("notthesame.libressl.org")) == + NULL) { + FAIL("failed to strdup tlsext_hostname"); + goto err; + } + + CBS_init(&cbs, tlsext_sni_client, sizeof(tlsext_sni_client)); + if (server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("parsed client with mismatched SNI\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_sni_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_server_name, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch sni funcs"); + + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need SNI\n"); + goto err; + } + + if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { + FAIL("client failed to set server name\n"); + goto err; + } + + if ((ssl->session->tlsext_hostname = strdup(TEST_SNI_SERVERNAME)) == + NULL) + errx(1, "failed to strdup tlsext_hostname"); + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need SNI\n"); + goto err; + } + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server failed to build SNI\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != tlsext_sni_server_len) { + FAIL("got server SNI with length %zu, " + "want length %zu\n", dlen, tlsext_sni_server_len); + goto err; + } + + if (memcmp(data, tlsext_sni_server, dlen) != 0) { + FAIL("server SNI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_sni_server, tlsext_sni_server_len); + goto err; + } + + free(ssl->session->tlsext_hostname); + ssl->session->tlsext_hostname = NULL; + + CBS_init(&cbs, tlsext_sni_server, tlsext_sni_server_len); + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse server SNI\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->session->tlsext_hostname == NULL) { + FAIL("no tlsext_hostname after server SNI\n"); + goto err; + } + + if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || + strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, + strlen(TEST_SNI_SERVERNAME)) != 0) { + FAIL("got tlsext_hostname `%s', want `%s'\n", + ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + + +/* + * QUIC transport parameters extension - RFC 90210 :) + */ + +static const unsigned char tlsext_quic_transport_data[] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, +}; + +static int +test_tlsext_quic_transport_parameters_client(void) +{ + const SSL_QUIC_METHOD quic_method; + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + CBB cbb; + CBS cbs; + int alert; + const uint8_t *out_bytes; + size_t out_bytes_len; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_quic_transport_parameters, + &client_funcs, &server_funcs)) + errx(1, "failed to fetch quic transport parameter funcs"); + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need QUIC\n"); + goto err; + } + + if (!SSL_set_quic_transport_params(ssl, + tlsext_quic_transport_data, sizeof(tlsext_quic_transport_data))) { + FAIL("client failed to set QUIC parametes\n"); + goto err; + } + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need QUIC\n"); + goto err; + } + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + ssl->s3->hs.negotiated_tls_version = TLS1_3_VERSION; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need QUIC\n"); + goto err; + } + + ssl->quic_method = &quic_method; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need QUIC\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build QUIC\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB"); + goto err; + } + + if (dlen != sizeof(tlsext_quic_transport_data)) { + FAIL("got client QUIC with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + if (memcmp(data, tlsext_quic_transport_data, dlen) != 0) { + FAIL("client QUIC differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_quic_transport_data, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + CBS_init(&cbs, tlsext_quic_transport_data, + sizeof(tlsext_quic_transport_data)); + + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("server_parse of QUIC from server failed\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + SSL_get_peer_quic_transport_params(ssl, &out_bytes, &out_bytes_len); + + if (out_bytes_len != sizeof(tlsext_quic_transport_data)) { + FAIL("server_parse QUIC length differs, got %zu want %zu\n", + out_bytes_len, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + if (memcmp(out_bytes, tlsext_quic_transport_data, + out_bytes_len) != 0) { + FAIL("server_parse QUIC differs from sent:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_quic_transport_data, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_quic_transport_parameters_server(void) +{ + const SSL_QUIC_METHOD quic_method; + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + const uint8_t *out_bytes; + size_t out_bytes_len; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_quic_transport_parameters, + &client_funcs, &server_funcs)) + errx(1, "failed to fetch quic transport parameter funcs"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need QUIC\n"); + goto err; + } + + if (!SSL_set_quic_transport_params(ssl, + tlsext_quic_transport_data, sizeof(tlsext_quic_transport_data))) { + FAIL("server failed to set QUIC parametes\n"); + goto err; + } + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_EE)) { + FAIL("server should not need QUIC\n"); + goto err; + } + + ssl->quic_method = &quic_method; + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_EE)) { + FAIL("server should need QUIC\n"); + goto err; + } + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_EE, &cbb)) { + FAIL("server failed to build QUIC\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_quic_transport_data)) { + FAIL("got server QUIC with length %zu, want length %zu\n", + dlen, sizeof(tlsext_quic_transport_data)); + goto err; + } + + if (memcmp(data, tlsext_quic_transport_data, dlen) != 0) { + FAIL("saved server QUIC differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_quic_transport_data, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + CBS_init(&cbs, tlsext_quic_transport_data, + sizeof(tlsext_quic_transport_data)); + + ssl->quic_method = NULL; + + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_EE, &cbs, &alert)) { + FAIL("QUIC parse should have failed!\n"); + goto err; + } + + ssl->quic_method = &quic_method; + + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("client_parse of QUIC from server failed\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + SSL_get_peer_quic_transport_params(ssl, &out_bytes, &out_bytes_len); + + if (out_bytes_len != sizeof(tlsext_quic_transport_data)) { + FAIL("client QUIC length differs, got %zu want %zu\n", + out_bytes_len, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + if (memcmp(out_bytes, tlsext_quic_transport_data, out_bytes_len) != 0) { + FAIL("client QUIC differs from sent:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_quic_transport_data, + sizeof(tlsext_quic_transport_data)); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static const unsigned char tls_ocsp_client_default[] = { + 0x01, 0x00, 0x00, 0x00, 0x00 +}; + +static int +test_tlsext_ocsp_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + size_t dlen; + int failure; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_status_request, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch ocsp funcs"); + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need TLSEXT_TYPE_status_request\n"); + goto err; + } + SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp); + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need TLSEXT_TYPE_status_request\n"); + goto err; + } + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build SNI\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tls_ocsp_client_default)) { + FAIL("got TLSEXT_TYPE_status_request client with length %zu, " + "want length %zu\n", dlen, + sizeof(tls_ocsp_client_default)); + goto err; + } + if (memcmp(data, tls_ocsp_client_default, dlen) != 0) { + FAIL("TLSEXT_TYPE_status_request client differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tls_ocsp_client_default, + sizeof(tls_ocsp_client_default)); + goto err; + } + CBS_init(&cbs, tls_ocsp_client_default, + sizeof(tls_ocsp_client_default)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse TLSEXT_TYPE_status_request client\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_ocsp_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + size_t dlen; + int failure; + CBB cbb; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_status_request, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch ocsp funcs"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need TLSEXT_TYPE_status_request\n"); + goto err; + } + + ssl->tlsext_status_expected = 1; + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need TLSEXT_TYPE_status_request\n"); + goto err; + } + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server failed to build TLSEXT_TYPE_status_request\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +/* + * Session ticket - RFC 5077 since no known implementations use 4507. + * + * Session tickets can be length 0 (special case) to 2^16-1. + * + * The state is encrypted by the server so it is opaque to the client. + */ +static uint8_t tlsext_sessionticket_hello_min[1]; +static uint8_t tlsext_sessionticket_hello_max[65535]; + +static int +test_tlsext_sessionticket_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + CBB cbb; + size_t dlen; + uint8_t dummy[1234]; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + /* Create fake session tickets with random data. */ + arc4random_buf(tlsext_sessionticket_hello_min, + sizeof(tlsext_sessionticket_hello_min)); + arc4random_buf(tlsext_sessionticket_hello_max, + sizeof(tlsext_sessionticket_hello_max)); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_session_ticket, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch session ticket funcs"); + + /* Should need a ticket by default. */ + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need Sessionticket for default " + "ciphers\n"); + goto err; + } + + /* Test disabling tickets. */ + if ((SSL_set_options(ssl, SSL_OP_NO_TICKET) & SSL_OP_NO_TICKET) == 0) { + FAIL("Cannot disable tickets in the TLS connection\n"); + goto err; + } + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need SessionTicket if it was disabled\n"); + goto err; + } + + /* Test re-enabling tickets. */ + if ((SSL_clear_options(ssl, SSL_OP_NO_TICKET) & SSL_OP_NO_TICKET) != 0) { + FAIL("Cannot re-enable tickets in the TLS connection\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need SessionTicket if it was disabled\n"); + goto err; + } + + /* Since we don't have a session, we should build an empty ticket. */ + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("Cannot build a ticket\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("Cannot finish CBB\n"); + goto err; + } + if (dlen != 0) { + FAIL("Expected 0 length but found %zu\n", dlen); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* With a new session (but no ticket), we should still have 0 length */ + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("Should still want a session ticket with a new session\n"); + goto err; + } + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("Cannot build a ticket\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("Cannot finish CBB\n"); + goto err; + } + if (dlen != 0) { + FAIL("Expected 0 length but found %zu\n", dlen); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* With a new session (and ticket), we should use that ticket */ + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + arc4random_buf(&dummy, sizeof(dummy)); + if ((ssl->session->tlsext_tick = malloc(sizeof(dummy))) == NULL) { + errx(1, "failed to malloc"); + } + memcpy(ssl->session->tlsext_tick, dummy, sizeof(dummy)); + ssl->session->tlsext_ticklen = sizeof(dummy); + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("Should still want a session ticket with a new session\n"); + goto err; + } + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("Cannot build a ticket\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("Cannot finish CBB\n"); + goto err; + } + if (dlen != sizeof(dummy)) { + FAIL("Expected %zu length but found %zu\n", sizeof(dummy), dlen); + goto err; + } + if (memcmp(data, dummy, dlen) != 0) { + FAIL("server SNI differs:\n"); + compare_data(data, dlen, + dummy, sizeof(dummy)); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + free(ssl->session->tlsext_tick); + ssl->session->tlsext_tick = NULL; + ssl->session->tlsext_ticklen = 0; + + /* + * Send in NULL to disable session tickets at runtime without going + * through SSL_set_options(). + */ + if (!SSL_set_session_ticket_ext(ssl, NULL, 0)) { + FAIL("Could not set a NULL custom ticket\n"); + goto err; + } + /* Should not need a ticket in this case */ + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("Should not want to use session tickets with a NULL custom\n"); + goto err; + } + + /* + * If you want to remove the tlsext_session_ticket behavior, you have + * to do it manually. + */ + free(ssl->tlsext_session_ticket); + ssl->tlsext_session_ticket = NULL; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("Should need a session ticket again when the custom one is removed\n"); + goto err; + } + + /* Test a custom session ticket (not recommended in practice) */ + if (!SSL_set_session_ticket_ext(ssl, tlsext_sessionticket_hello_max, + sizeof(tlsext_sessionticket_hello_max))) { + FAIL("Should be able to set a custom ticket\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("Should need a session ticket again when the custom one is not empty\n"); + goto err; + } + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("Cannot build a ticket with a max length random payload\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("Cannot finish CBB\n"); + goto err; + } + if (dlen != sizeof(tlsext_sessionticket_hello_max)) { + FAIL("Expected %zu length but found %zu\n", + sizeof(tlsext_sessionticket_hello_max), dlen); + goto err; + } + if (memcmp(data, tlsext_sessionticket_hello_max, + sizeof(tlsext_sessionticket_hello_max)) != 0) { + FAIL("Expected to get what we passed in\n"); + compare_data(data, dlen, + tlsext_sessionticket_hello_max, + sizeof(tlsext_sessionticket_hello_max)); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + + +static int +test_tlsext_sessionticket_server(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + uint8_t *data = NULL; + size_t dlen; + CBB cbb; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_session_ticket, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch session ticket funcs"); + + /* + * By default, should not need a session ticket since the ticket + * is not yet expected. + */ + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need SessionTicket by default\n"); + goto err; + } + + /* Test disabling tickets. */ + if ((SSL_set_options(ssl, SSL_OP_NO_TICKET) & SSL_OP_NO_TICKET) == 0) { + FAIL("Cannot disable tickets in the TLS connection\n"); + goto err; + } + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need SessionTicket if it was disabled\n"); + goto err; + } + + /* Test re-enabling tickets. */ + if ((SSL_clear_options(ssl, SSL_OP_NO_TICKET) & SSL_OP_NO_TICKET) != 0) { + FAIL("Cannot re-enable tickets in the TLS connection\n"); + goto err; + } + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need SessionTicket yet\n"); + goto err; + } + + /* Set expected to require it. */ + ssl->tlsext_ticket_expected = 1; + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should now be required for SessionTicket\n"); + goto err; + } + + /* server hello's session ticket should always be 0 length payload. */ + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("Cannot build a ticket with a max length random payload\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("Cannot finish CBB\n"); + goto err; + } + if (dlen != 0) { + FAIL("Expected 0 length but found %zu\n", dlen); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +#ifndef OPENSSL_NO_SRTP +/* + * Supported Secure Real-time Transport Protocol (RFC 5764 section 4.1.1) + */ + +/* Colon separated string values */ +const char *tlsext_srtp_single_profile = "SRTP_AES128_CM_SHA1_80"; +const char *tlsext_srtp_multiple_profiles = "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"; + +const char *tlsext_srtp_aes128cmsha80 = "SRTP_AES128_CM_SHA1_80"; +const char *tlsext_srtp_aes128cmsha32 = "SRTP_AES128_CM_SHA1_32"; + +const uint8_t tlsext_srtp_single[] = { + /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ + 0x00, 0x02, /* len */ + 0x00, 0x01, /* SRTP_AES128_CM_SHA1_80 */ + 0x00 /* opaque srtp_mki<0..255> */ +}; + +const uint8_t tlsext_srtp_multiple[] = { + /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ + 0x00, 0x04, /* len */ + 0x00, 0x01, /* SRTP_AES128_CM_SHA1_80 */ + 0x00, 0x02, /* SRTP_AES128_CM_SHA1_32 */ + 0x00 /* opaque srtp_mki<0..255> */ +}; + +const uint8_t tlsext_srtp_multiple_invalid[] = { + /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ + 0x00, 0x04, /* len */ + 0x00, 0x08, /* arbitrary value not found in known profiles */ + 0x00, 0x09, /* arbitrary value not found in known profiles */ + 0x00 /* opaque srtp_mki<0..255> */ +}; + +const uint8_t tlsext_srtp_single_invalid[] = { + /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ + 0x00, 0x02, /* len */ + 0x00, 0x08, /* arbitrary value not found in known profiles */ + 0x00 /* opaque srtp_mki<0..255> */ +}; + +const uint8_t tlsext_srtp_multiple_one_valid[] = { + /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ + 0x00, 0x04, /* len */ + 0x00, 0x08, /* arbitrary value not found in known profiles */ + 0x00, 0x02, /* SRTP_AES128_CM_SHA1_32 */ + 0x00 /* opaque srtp_mki<0..255> */ +}; + +static int +test_tlsext_srtp_client(void) +{ + SRTP_PROTECTION_PROFILE *prof; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + uint8_t *data = NULL; + CBB cbb; + CBS cbs; + int failure, alert; + size_t dlen; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + /* SRTP is for DTLS */ + if ((ssl_ctx = SSL_CTX_new(DTLSv1_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_use_srtp, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch srtp funcs"); + + /* By default, we don't need this */ + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need SRTP by default\n"); + goto err; + } + + if (SSL_set_tlsext_use_srtp(ssl, tlsext_srtp_single_profile) != 0) { + FAIL("should be able to set a single SRTP\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need SRTP\n"); + goto err; + } + + /* Make sure we can build the client with a single profile. */ + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build SRTP\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_srtp_single)) { + FAIL("got client SRTP with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_srtp_single)); + compare_data(data, dlen, tlsext_srtp_single, + sizeof(tlsext_srtp_single)); + goto err; + } + if (memcmp(data, tlsext_srtp_single, dlen) != 0) { + FAIL("client SRTP differs:\n"); + compare_data(data, dlen, tlsext_srtp_single, + sizeof(tlsext_srtp_single)); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* Make sure we can parse the single profile. */ + + if (SSL_get_selected_srtp_profile(ssl) != NULL) { + FAIL("SRTP profile should not be set yet\n"); + goto err; + } + + CBS_init(&cbs, tlsext_srtp_single, sizeof(tlsext_srtp_single)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse SRTP\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { + FAIL("SRTP profile should be set now\n"); + goto err; + } + if (strcmp(prof->name, tlsext_srtp_aes128cmsha80) != 0) { + FAIL("SRTP profile was not set properly\n"); + goto err; + } + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("should send server extension when profile selected\n"); + goto err; + } + + /* Make sure we can build the clienthello with multiple entries. */ + + if (SSL_set_tlsext_use_srtp(ssl, tlsext_srtp_multiple_profiles) != 0) { + FAIL("should be able to set SRTP to multiple profiles\n"); + goto err; + } + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need SRTP by now\n"); + goto err; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build SRTP\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_srtp_multiple)) { + FAIL("got client SRTP with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_srtp_multiple)); + compare_data(data, dlen, tlsext_srtp_multiple, + sizeof(tlsext_srtp_multiple)); + goto err; + } + if (memcmp(data, tlsext_srtp_multiple, dlen) != 0) { + FAIL("client SRTP differs:\n"); + compare_data(data, dlen, tlsext_srtp_multiple, + sizeof(tlsext_srtp_multiple)); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* Make sure we can parse multiple profiles (selects server preferred) */ + + ssl->srtp_profile = NULL; + + CBS_init(&cbs, tlsext_srtp_multiple, + sizeof(tlsext_srtp_multiple)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse SRTP\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { + FAIL("SRTP profile should be set now\n"); + goto err; + } + if (strcmp(prof->name, tlsext_srtp_aes128cmsha80) != 0) { + FAIL("SRTP profile was not set properly\n"); + goto err; + } + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("should send server extension when profile selected\n"); + goto err; + } + + /* + * Make sure we can parse the clienthello with multiple entries + * where one is unknown. + */ + ssl->srtp_profile = NULL; + + CBS_init(&cbs, tlsext_srtp_multiple_one_valid, + sizeof(tlsext_srtp_multiple_one_valid)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse SRTP\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { + FAIL("SRTP profile should be set now\n"); + goto err; + } + if (strcmp(prof->name, tlsext_srtp_aes128cmsha32) != 0) { + FAIL("SRTP profile was not set properly\n"); + goto err; + } + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("should send server extension when profile selected\n"); + goto err; + } + + /* Make sure we fall back to negotiated when none work. */ + + ssl->srtp_profile = NULL; + + CBS_init(&cbs, tlsext_srtp_multiple_invalid, + sizeof(tlsext_srtp_multiple_invalid)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("should be able to fall back to negotiated\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + /* If we fallback, the server should NOT send the extension. */ + if (SSL_get_selected_srtp_profile(ssl) != NULL) { + FAIL("should not have selected a profile when none found\n"); + goto err; + } + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("should not send server tlsext when no profile found\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_srtp_server(void) +{ + const SRTP_PROTECTION_PROFILE *prof; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + uint8_t *data = NULL; + CBB cbb; + CBS cbs; + int failure, alert; + size_t dlen; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + /* SRTP is for DTLS */ + if ((ssl_ctx = SSL_CTX_new(DTLSv1_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_use_srtp, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch srtp funcs"); + + /* By default, we don't need this */ + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need SRTP by default\n"); + goto err; + } + + if (srtp_find_profile_by_name(tlsext_srtp_aes128cmsha80, &prof, + strlen(tlsext_srtp_aes128cmsha80))) { + FAIL("should be able to find the given profile\n"); + goto err; + } + ssl->srtp_profile = prof; + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need SRTP by now\n"); + goto err; + } + + /* Make sure we can build the server with a single profile. */ + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server failed to build SRTP\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_srtp_single)) { + FAIL("got server SRTP with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_srtp_single)); + compare_data(data, dlen, tlsext_srtp_single, + sizeof(tlsext_srtp_single)); + goto err; + } + if (memcmp(data, tlsext_srtp_single, dlen) != 0) { + FAIL("server SRTP differs:\n"); + compare_data(data, dlen, tlsext_srtp_single, + sizeof(tlsext_srtp_single)); + goto err; + } + + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + free(data); + data = NULL; + + /* Make sure we can parse the single profile. */ + ssl->srtp_profile = NULL; + + if (SSL_get_selected_srtp_profile(ssl) != NULL) { + FAIL("SRTP profile should not be set yet\n"); + goto err; + } + + /* Setup the environment as if a client sent a list of profiles. */ + if (SSL_set_tlsext_use_srtp(ssl, tlsext_srtp_multiple_profiles) != 0) { + FAIL("should be able to set multiple profiles in SRTP\n"); + goto err; + } + + CBS_init(&cbs, tlsext_srtp_single, sizeof(tlsext_srtp_single)); + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse SRTP\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { + FAIL("SRTP profile should be set now\n"); + goto err; + } + if (strcmp(prof->name, tlsext_srtp_aes128cmsha80) != 0) { + FAIL("SRTP profile was not set properly\n"); + goto err; + } + + /* Make sure we cannot parse multiple profiles */ + ssl->srtp_profile = NULL; + + CBS_init(&cbs, tlsext_srtp_multiple, + sizeof(tlsext_srtp_multiple)); + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("should not find multiple entries from the server\n"); + goto err; + } + + /* Make sure we cannot parse a server with unknown profile */ + ssl->srtp_profile = NULL; + + CBS_init(&cbs, tlsext_srtp_single_invalid, + sizeof(tlsext_srtp_single_invalid)); + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("should not be able to parse this\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} +#endif /* OPENSSL_NO_SRTP */ + +static const unsigned char tlsext_clienthello_default[] = { + 0x00, 0x34, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, + 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, + 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, + 0x08, 0x06, 0x06, 0x01, 0x06, 0x03, 0x08, 0x05, + 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, + 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, +}; + +/* An empty array is an incomplete type and sizeof() is undefined. */ +static const unsigned char tlsext_clienthello_disabled[] = { + 0x00, +}; +static size_t tlsext_clienthello_disabled_len = 0; + +static int +test_tlsext_clienthello_build(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + size_t dlen; + int failure; + CBB cbb; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) { + FAIL("failed to create SSL_CTX"); + goto err; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + FAIL("failed to create SSL"); + goto err; + } + + if (!tlsext_linearize_build_order(ssl)) { + FAIL("failed to linearize build order"); + goto err; + } + + if (!tls_extension_funcs(TLSEXT_TYPE_supported_versions, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch supported versions funcs"); + + ssl->s3->hs.our_min_tls_version = TLS1_VERSION; + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + + if (!tlsext_client_build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("failed to build clienthello extensions\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB"); + goto err; + } + + if (dlen != sizeof(tlsext_clienthello_default)) { + FAIL("got clienthello extensions with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_clienthello_default)); + compare_data(data, dlen, tlsext_clienthello_default, + sizeof(tlsext_clienthello_default)); + goto err; + } + if (memcmp(data, tlsext_clienthello_default, dlen) != 0) { + FAIL("clienthello extensions differs:\n"); + compare_data(data, dlen, tlsext_clienthello_default, + sizeof(tlsext_clienthello_default)); + goto err; + } + + free(data); + data = NULL; + CBB_cleanup(&cbb); + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + /* Switch to TLSv1.1, disable EC ciphers and session tickets. */ + ssl->s3->hs.our_max_tls_version = TLS1_1_VERSION; + if (!SSL_set_cipher_list(ssl, "TLSv1.2:!ECDHE:!ECDSA")) { + FAIL("failed to set cipher list\n"); + goto err; + } + if ((SSL_set_options(ssl, SSL_OP_NO_TICKET) & SSL_OP_NO_TICKET) == 0) { + FAIL("failed to disable session tickets\n"); + goto err; + } + + if (!tlsext_client_build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("failed to build clienthello extensions\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB"); + goto err; + } + + if (dlen != tlsext_clienthello_disabled_len) { + FAIL("got clienthello extensions with length %zu, " + "want length %zu\n", dlen, + tlsext_clienthello_disabled_len); + compare_data(data, dlen, tlsext_clienthello_disabled, + tlsext_clienthello_disabled_len); + goto err; + } + if (memcmp(data, tlsext_clienthello_disabled, dlen) != 0) { + FAIL("clienthello extensions differs:\n"); + compare_data(data, dlen, tlsext_clienthello_disabled, + tlsext_clienthello_disabled_len); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +unsigned char tlsext_serverhello_default[] = { + 0x00, 0x06, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, +}; + +unsigned char tlsext_serverhello_enabled[] = { + 0x00, 0x10, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, + 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, + 0x00, 0x00, +}; + +static int +test_tlsext_serverhello_build(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + size_t dlen; + int failure; + CBB cbb; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) { + FAIL("failed to create SSL_CTX"); + goto err; + } + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + FAIL("failed to create SSL"); + goto err; + } + if (!tlsext_linearize_build_order(ssl)) { + FAIL("failed to linearize build order"); + goto err; + } + if ((ssl->session = SSL_SESSION_new()) == NULL) { + FAIL("failed to create session"); + goto err; + } + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + ssl->s3->hs.negotiated_tls_version = TLS1_3_VERSION; + ssl->s3->hs.cipher = + ssl3_get_cipher_by_id(TLS1_CK_RSA_WITH_AES_128_SHA256); + + if (!tlsext_server_build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("failed to build serverhello extensions\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB"); + goto err; + } + + if (dlen != sizeof(tlsext_serverhello_default)) { + FAIL("got serverhello extensions with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_serverhello_default)); + compare_data(data, dlen, tlsext_serverhello_default, + sizeof(tlsext_serverhello_default)); + goto err; + } + if (memcmp(data, tlsext_serverhello_default, dlen) != 0) { + FAIL("serverhello extensions differs:\n"); + compare_data(data, dlen, tlsext_serverhello_default, + sizeof(tlsext_serverhello_default)); + goto err; + } + + CBB_cleanup(&cbb); + free(data); + data = NULL; + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + /* Turn a few things on so we get extensions... */ + ssl->s3->send_connection_binding = 1; + ssl->s3->hs.cipher = + ssl3_get_cipher_by_id(TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256); + ssl->tlsext_status_expected = 1; + ssl->tlsext_ticket_expected = 1; + if ((ssl->session->tlsext_ecpointformatlist = malloc(1)) == NULL) { + FAIL("malloc failed"); + goto err; + } + ssl->session->tlsext_ecpointformatlist_length = 1; + ssl->session->tlsext_ecpointformatlist[0] = + TLSEXT_ECPOINTFORMAT_uncompressed; + + if (!tlsext_server_build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("failed to build serverhello extensions\n"); + goto err; + } + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB"); + goto err; + } + + if (dlen != sizeof(tlsext_serverhello_enabled)) { + FAIL("got serverhello extensions with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_serverhello_enabled)); + compare_data(data, dlen, tlsext_serverhello_enabled, + sizeof(tlsext_serverhello_enabled)); + goto err; + } + if (memcmp(data, tlsext_serverhello_enabled, dlen) != 0) { + FAIL("serverhello extensions differs:\n"); + compare_data(data, dlen, tlsext_serverhello_enabled, + sizeof(tlsext_serverhello_enabled)); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +const unsigned char tlsext_versions_client[] = { + 0x08, 0x03, 0x04, 0x03, 0x03, 0x03, + 0x02, 0x03, 0x01, +}; + +const unsigned char tlsext_versions_server[] = { + 0x03, 0x04, +}; + +static int +test_tlsext_versions_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_supported_versions, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch supported versions funcs"); + + ssl->s3->hs.our_max_tls_version = TLS1_1_VERSION; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need versions\n"); + goto done; + } + + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need versions\n"); + goto done; + } + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need versions\n"); + goto done; + } + + ssl->s3->hs.our_min_tls_version = TLS1_VERSION; + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client should have built versions\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB\n"); + goto done; + } + + if (dlen != sizeof(tlsext_versions_client)) { + FAIL("got versions with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_versions_client)); + goto done; + } + + CBS_init(&cbs, data, dlen); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client versions\n"); + goto done; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_versions_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_supported_versions, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch supported versions funcs"); + + ssl->s3->hs.negotiated_tls_version = TLS1_2_VERSION; + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need versions\n"); + goto done; + } + + ssl->s3->hs.negotiated_tls_version = TLS1_3_VERSION; + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need versions\n"); + goto done; + } + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server should have built versions\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB\n"); + goto done; + } + + if (dlen != sizeof(tlsext_versions_server)) { + FAIL("got versions with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_versions_server)); + goto done; + } + + CBS_init(&cbs, data, dlen); + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse client versions\n"); + goto done; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +const unsigned char tlsext_keyshare_client[] = { + 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0xba, 0x83, + 0x2e, 0x4a, 0x18, 0xbe, 0x96, 0xd2, 0x71, 0x70, + 0x18, 0x04, 0xf9, 0x9d, 0x76, 0x98, 0xef, 0xe8, + 0x4f, 0x8b, 0x85, 0x41, 0xa4, 0xd9, 0x61, 0x57, + 0xad, 0x5b, 0xa4, 0xe9, 0x8b, 0x6b, +}; + +const unsigned char tlsext_keyshare_server[] = { + 0x00, 0x1d, 0x00, 0x20, 0xe5, 0xe8, 0x5a, 0xb9, + 0x7e, 0x12, 0x62, 0xe3, 0xd8, 0x7f, 0x6e, 0x3c, + 0xec, 0xa6, 0x8b, 0x99, 0x45, 0x77, 0x8e, 0x11, + 0xb3, 0xb9, 0x12, 0xb6, 0xbe, 0x35, 0xca, 0x51, + 0x76, 0x1e, 0xe8, 0x22 +}; + +static int +test_tlsext_keyshare_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_key_share, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch keyshare funcs"); + + if ((ssl->s3->hs.key_share = + tls_key_share_new_nid(NID_X25519)) == NULL) + errx(1, "failed to create key share"); + if (!tls_key_share_generate(ssl->s3->hs.key_share)) + errx(1, "failed to generate key share"); + + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need keyshare\n"); + goto done; + } + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need keyshare\n"); + goto done; + } + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client should have built keyshare\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB\n"); + goto done; + } + + if (dlen != sizeof(tlsext_keyshare_client)) { + FAIL("got client keyshare with length %zu, " + "want length %zu\n", dlen, (size_t) sizeof(tlsext_keyshare_client)); + goto done; + } + + (ssl)->version = TLS1_3_VERSION; + CBS_init(&cbs, data, dlen); + + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client keyshare\n"); + goto done; + } + + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static const uint8_t bogokey[] = { + 0xe5, 0xe8, 0x5a, 0xb9, 0x7e, 0x12, 0x62, 0xe3, + 0xd8, 0x7f, 0x6e, 0x3c, 0xec, 0xa6, 0x8b, 0x99, + 0x45, 0x77, 0x8e, 0x11, 0xb3, 0xb9, 0x12, 0xb6, + 0xbe, 0x35, 0xca, 0x51, 0x76, 0x1e, 0xe8, 0x22, +}; + +static int +test_tlsext_keyshare_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int decode_error; + int failure; + size_t dlen, idx; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_key_share, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch keyshare funcs"); + + ssl->s3->hs.negotiated_tls_version = TLS1_2_VERSION; + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need keyshare\n"); + goto done; + } + + ssl->s3->hs.negotiated_tls_version = TLS1_3_VERSION; + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("client should not need keyshare\n"); + goto done; + } + + if (tls_extension_find(TLSEXT_TYPE_key_share, &idx) == NULL) { + FAIL("failed to find keyshare extension\n"); + goto done; + } + ssl->s3->hs.extensions_seen |= (1 << idx); + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should need keyshare\n"); + goto done; + } + + if (server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server should not have built a keyshare response\n"); + goto done; + } + + if ((ssl->s3->hs.key_share = + tls_key_share_new_nid(NID_X25519)) == NULL) { + FAIL("failed to create key share"); + goto done; + } + + if (!tls_key_share_generate(ssl->s3->hs.key_share)) { + FAIL("failed to generate key share"); + goto done; + } + + CBS_init(&cbs, bogokey, sizeof(bogokey)); + + if (!tls_key_share_peer_public(ssl->s3->hs.key_share, &cbs, + &decode_error, NULL)) { + FAIL("failed to load peer public key\n"); + goto done; + } + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_SH, &cbb)) { + FAIL("server should be able to build a keyshare response\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB\n"); + goto done; + } + + if (dlen != sizeof(tlsext_keyshare_server)) { + FAIL("got server keyshare with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_keyshare_server)); + goto done; + } + + tls_key_share_free(ssl->s3->hs.key_share); + + if ((ssl->s3->hs.key_share = + tls_key_share_new_nid(NID_X25519)) == NULL) { + FAIL("failed to create key share"); + goto done; + } + if (!tls_key_share_generate(ssl->s3->hs.key_share)) { + FAIL("failed to generate key share"); + goto done; + } + + CBS_init(&cbs, data, dlen); + + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse server keyshare\n"); + goto done; + } + + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + +done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +/* One day I hope to be the only Muppet in this codebase */ +const uint8_t cookie[] = "\n" + " (o)(o) \n" + " m' 'm \n" + " M -****- M \n" + " 'm m' \n" + " m''''''''''m \n" + " M M BB \n"; + +static int +test_tlsext_cookie_client(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_cookie, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch cookie funcs"); + + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need cookie\n"); + goto done; + } + + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need cookie\n"); + goto done; + } + + /* Normally would be set by receiving a server cookie in an HRR */ + ssl->s3->hs.tls13.cookie = strdup(cookie); + ssl->s3->hs.tls13.cookie_len = strlen(cookie); + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need cookie\n"); + goto done; + } + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client should have built a cookie response\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB\n"); + goto done; + } + + if (dlen != strlen(cookie) + sizeof(uint16_t)) { + FAIL("got cookie with length %zu, " + "want length %zu\n", dlen, strlen(cookie) + + sizeof(uint16_t)); + goto done; + } + + CBS_init(&cbs, data, dlen); + + /* Checks cookie against what's in the hs.tls13 */ + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse client cookie\n"); + goto done; + } + + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +static int +test_tlsext_cookie_server(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_cookie, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch cookie funcs"); + + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need cookie\n"); + goto done; + } + + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need cookie\n"); + goto done; + } + + /* Normally would be set by server before sending HRR */ + ssl->s3->hs.tls13.cookie = strdup(cookie); + ssl->s3->hs.tls13.cookie_len = strlen(cookie); + + if (!server_funcs->needs(ssl, SSL_TLSEXT_MSG_HRR)) { + FAIL("server should need cookie\n"); + goto done; + } + + if (!server_funcs->build(ssl, SSL_TLSEXT_MSG_HRR, &cbb)) { + FAIL("server should have built a cookie response\n"); + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) { + FAIL("failed to finish CBB\n"); + goto done; + } + + if (dlen != strlen(cookie) + sizeof(uint16_t)) { + FAIL("got cookie with length %zu, " + "want length %zu\n", dlen, strlen(cookie) + + sizeof(uint16_t)); + goto done; + } + + CBS_init(&cbs, data, dlen); + + if (client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("client should not have parsed server cookie\n"); + goto done; + } + + freezero(ssl->s3->hs.tls13.cookie, ssl->s3->hs.tls13.cookie_len); + ssl->s3->hs.tls13.cookie = NULL; + ssl->s3->hs.tls13.cookie_len = 0; + + if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) { + FAIL("failed to parse server cookie\n"); + goto done; + } + + if (memcmp(cookie, ssl->s3->hs.tls13.cookie, + ssl->s3->hs.tls13.cookie_len) != 0) { + FAIL("parsed server cookie does not match sent cookie\n"); + goto done; + } + + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto done; + } + + failure = 0; + +done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +const uint8_t tlsext_default_psk_modes[] = { + 0x01, 0x01, +}; + +const uint8_t tlsext_psk_only_mode[] = { + 0x01, 0x00, +}; + +const uint8_t tlsext_psk_both_modes[] = { + 0x02, 0x00, 0x01, +}; + +static int +test_tlsext_psk_modes_client(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + uint8_t *data = NULL; + size_t dlen; + CBB cbb; + CBS cbs; + int alert; + + failure = 1; + + if (!CBB_init(&cbb, 0)) + errx(1, "Failed to create CBB"); + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_psk_kex_modes, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch psk funcs"); + + /* Disabled by default. */ + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need psk kex modes by default\n"); + goto err; + } + + /* + * Prerequisites: use_psk_dhe_ke flag is set and + * our_max_tls_version >= TLSv1.3. + */ + + ssl->s3->hs.tls13.use_psk_dhe_ke = 1; + ssl->s3->hs.our_max_tls_version = TLS1_2_VERSION; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need psk kex modes with TLSv1.2\n"); + goto err; + } + + ssl->s3->hs.tls13.use_psk_dhe_ke = 0; + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + + if (client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should not need psk kex modes without " + "use_psk_dhe_ke\n"); + goto err; + } + + ssl->s3->hs.tls13.use_psk_dhe_ke = 1; + ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION; + + if (!client_funcs->needs(ssl, SSL_TLSEXT_MSG_CH)) { + FAIL("client should need psk kex modes with TLSv1.3\n"); + goto err; + } + + /* Make sure we can build psk modes with DHE key establishment. */ + + if (!client_funcs->build(ssl, SSL_TLSEXT_MSG_CH, &cbb)) { + FAIL("client failed to build psk kex modes\n"); + goto err; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish psk kex CBB"); + + if (dlen != sizeof(tlsext_default_psk_modes)) { + FAIL("got client psk kex modes with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_default_psk_modes)); + compare_data(data, dlen, tlsext_default_psk_modes, + sizeof(tlsext_default_psk_modes)); + goto err; + } + if (memcmp(data, tlsext_default_psk_modes, dlen) != 0) { + FAIL("client psk kex modes differ:\n"); + compare_data(data, dlen, tlsext_default_psk_modes, + sizeof(tlsext_default_psk_modes)); + goto err; + } + + CBB_cleanup(&cbb); + free(data); + data = NULL; + + /* + * Make sure we can parse the default psk modes and that use_psk_dhe_ke + * is set after parsing. + */ + + ssl->s3->hs.tls13.use_psk_dhe_ke = 0; + + CBS_init(&cbs, tlsext_default_psk_modes, + sizeof(tlsext_default_psk_modes)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse psk kex modes\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->s3->hs.tls13.use_psk_dhe_ke != 1) { + FAIL("should have set use_psk_dhe_ke\n"); + goto err; + } + + /* + * Make sure we can parse the psk-only mode and that use_psk_dhe_ke + * is still not set after parsing. + */ + + ssl->s3->hs.tls13.use_psk_dhe_ke = 0; + + CBS_init(&cbs, tlsext_psk_only_mode, sizeof(tlsext_psk_only_mode)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse psk kex modes\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->s3->hs.tls13.use_psk_dhe_ke != 0) { + FAIL("should not have set use_psk_dhe_ke\n"); + goto err; + } + + /* + * Make sure we can parse the extension indicating both modes and that + * use_psk_dhe_ke is set after parsing. + */ + + ssl->s3->hs.tls13.use_psk_dhe_ke = 0; + + CBS_init(&cbs, tlsext_psk_both_modes, sizeof(tlsext_psk_both_modes)); + if (!server_funcs->parse(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { + FAIL("failed to parse psk kex modes\n"); + goto err; + } + if (CBS_len(&cbs) != 0) { + FAIL("extension data remaining\n"); + goto err; + } + + if (ssl->s3->hs.tls13.use_psk_dhe_ke != 1) { + FAIL("should have set use_psk_dhe_ke\n"); + goto err; + } + + failure = 0; + + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return failure; +} + +static int +test_tlsext_psk_modes_server(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + const struct tls_extension_funcs *client_funcs; + const struct tls_extension_funcs *server_funcs; + int failure; + + failure = 1; + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (!tls_extension_funcs(TLSEXT_TYPE_psk_kex_modes, &client_funcs, + &server_funcs)) + errx(1, "failed to fetch psk funcs"); + + if (server_funcs->needs(ssl, SSL_TLSEXT_MSG_SH)) { + FAIL("server should not need psk kex modes\n"); + goto err; + } + + failure = 0; + + err: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return failure; +} + +struct tls_sni_test { + const char *hostname; + int is_ip; + int valid; +}; + +static const struct tls_sni_test tls_sni_tests[] = { + { + .hostname = "openbsd.org", + .valid = 1, + }, + { + .hostname = "op3nbsd.org", + .valid = 1, + }, + { + .hostname = "org", + .valid = 1, + }, + { + .hostname = "3openbsd.com", + .valid = 1, + }, + { + .hostname = "3-0penb-d.c-m", + .valid = 1, + }, + { + .hostname = "a", + .valid = 1, + }, + { + .hostname = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + .valid = 1, + }, + { + .hostname = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + .valid = 1, + }, + { + .hostname = "openbsd.org.", + .valid = 0, + }, + { + .hostname = "openbsd..org", + .valid = 0, + }, + { + .hostname = "openbsd.org-", + .valid = 0, + }, + { + .hostname = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + .valid = 0, + }, + { + .hostname = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + .valid = 0, + }, + { + .hostname = "-p3nbsd.org", + .valid = 0, + }, + { + .hostname = "openbs-.org", + .valid = 0, + }, + { + .hostname = "openbsd\n.org", + .valid = 0, + }, + { + .hostname = "open_bsd.org", + .valid = 0, + }, + { + .hostname = "open\178bsd.org", + .valid = 0, + }, + { + .hostname = "open\255bsd.org", + .valid = 0, + }, + { + .hostname = "dead::beef", + .is_ip = 1, + .valid = 0, + }, + { + .hostname = "192.168.0.1", + .is_ip = 1, + .valid = 0, + }, +}; + +#define N_TLS_SNI_TESTS (sizeof(tls_sni_tests) / sizeof(*tls_sni_tests)) + +static int +test_tlsext_is_valid_hostname(const struct tls_sni_test *tst) +{ + int failure; + int is_ip; + CBS cbs; + + failure = 1; + + CBS_init(&cbs, tst->hostname, strlen(tst->hostname)); + if (tlsext_sni_is_valid_hostname(&cbs, &is_ip) != tst->valid) { + if (tst->valid) { + FAIL("Valid hostname '%s' rejected\n", + tst->hostname); + } else { + FAIL("Invalid hostname '%s' accepted\n", + tst->hostname); + } + goto done; + } + if (tst->is_ip != is_ip) { + if (tst->is_ip) { + FAIL("Hostname '%s' is an IP literal but not " + "identified as one\n", tst->hostname); + } else { + FAIL("Hostname '%s' is not an IP literal but is " + "identified as one\n", tst->hostname); + } + goto done; + } + + if (tst->valid) { + CBS_init(&cbs, tst->hostname, + strlen(tst->hostname) + 1); + if (tlsext_sni_is_valid_hostname(&cbs, &is_ip)) { + FAIL("hostname with NUL byte accepted\n"); + goto done; + } + } + + failure = 0; + + done: + + return failure; +} + +static int +test_tlsext_valid_hostnames(void) +{ + const struct tls_sni_test *tst; + int failure = 0; + size_t i; + + for (i = 0; i < N_TLS_SNI_TESTS; i++) { + tst = &tls_sni_tests[i]; + failure |= test_tlsext_is_valid_hostname(tst); + } + + return failure; +} + +#define N_TLSEXT_RANDOMIZATION_TESTS 1000 + +static int +test_tlsext_check_extension_order(SSL *ssl) +{ + const struct tls_extension *ext; + uint16_t type; + size_t alpn_idx, sni_idx; + size_t i; + + if (ssl->tlsext_build_order_len == 0) { + FAIL("Unexpected zero build order length"); + return 1; + } + + ext = ssl->tlsext_build_order[ssl->tlsext_build_order_len - 1]; + if ((type = tls_extension_type(ext)) != TLSEXT_TYPE_psk) { + FAIL("last extension is %u, want %u\n", type, TLSEXT_TYPE_psk); + return 1; + } + + if (ssl->server) + return 0; + + alpn_idx = sni_idx = ssl->tlsext_build_order_len; + for (i = 0; i < ssl->tlsext_build_order_len; i++) { + ext = ssl->tlsext_build_order[i]; + if (tls_extension_type(ext) == TLSEXT_TYPE_alpn) + alpn_idx = i; + if (tls_extension_type(ext) == TLSEXT_TYPE_server_name) + sni_idx = i; + } + + if (alpn_idx == ssl->tlsext_build_order_len) { + FAIL("could not find alpn extension\n"); + return 1; + } + + if (sni_idx == ssl->tlsext_build_order_len) { + FAIL("could not find alpn extension\n"); + return 1; + } + + if (sni_idx >= alpn_idx) { + FAIL("sni does not precede alpn: %zu >= %zu\n", + sni_idx, alpn_idx); + return 1; + } + + return 0; +} + +static int +test_tlsext_randomized_extensions(SSL *ssl) +{ + size_t i; + int failed = 0; + + for (i = 0; i < N_TLSEXT_RANDOMIZATION_TESTS; i++) { + if (!tlsext_randomize_build_order(ssl)) + errx(1, "failed to randomize extensions"); + failed |= test_tlsext_check_extension_order(ssl); + } + + return failed; +} + +static int +test_tlsext_extension_order(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failure; + + failure = 0; + + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + failure |= test_tlsext_randomized_extensions(ssl); + + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + failure |= test_tlsext_randomized_extensions(ssl); + + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return failure; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + SSL_library_init(); + SSL_load_error_strings(); + + failed |= test_tlsext_alpn_client(); + failed |= test_tlsext_alpn_server(); + + failed |= test_tlsext_supportedgroups_client(); + failed |= test_tlsext_supportedgroups_server(); + + failed |= test_tlsext_ecpf_client(); + failed |= test_tlsext_ecpf_server(); + + failed |= test_tlsext_ri_client(); + failed |= test_tlsext_ri_server(); + + failed |= test_tlsext_sigalgs_client(); + + failed |= test_tlsext_sni_client(); + failed |= test_tlsext_sni_server(); + + failed |= test_tlsext_ocsp_client(); + failed |= test_tlsext_ocsp_server(); + + failed |= test_tlsext_sessionticket_client(); + failed |= test_tlsext_sessionticket_server(); + + failed |= test_tlsext_versions_client(); + failed |= test_tlsext_versions_server(); + + failed |= test_tlsext_keyshare_client(); + failed |= test_tlsext_keyshare_server(); + + failed |= test_tlsext_cookie_client(); + failed |= test_tlsext_cookie_server(); + +#ifndef OPENSSL_NO_SRTP + failed |= test_tlsext_srtp_client(); + failed |= test_tlsext_srtp_server(); +#else + fprintf(stderr, "Skipping SRTP tests due to OPENSSL_NO_SRTP\n"); +#endif + + failed |= test_tlsext_psk_modes_client(); + failed |= test_tlsext_psk_modes_server(); + + failed |= test_tlsext_clienthello_build(); + failed |= test_tlsext_serverhello_build(); + + failed |= test_tlsext_valid_hostnames(); + + failed |= test_tlsext_quic_transport_parameters_client(); + failed |= test_tlsext_quic_transport_parameters_server(); + + failed |= test_tlsext_extension_order(); + + return (failed); +} diff --git a/Libraries/libressl/tests/tlslegacytest.c b/Libraries/libressl/tests/tlslegacytest.c new file mode 100644 index 000000000..59429d716 --- /dev/null +++ b/Libraries/libressl/tests/tlslegacytest.c @@ -0,0 +1,625 @@ +/* $OpenBSD: tlslegacytest.c,v 1.7 2022/10/02 16:39:39 jsing Exp $ */ +/* + * Copyright (c) 2015, 2016, 2017, 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +/* openssl.org:443 */ +static uint8_t tls12_server_response[] = { + 0x16, 0x03, 0x03, 0x00, 0x3d, 0x02, 0x00, 0x00, + 0x39, 0x03, 0x03, 0x62, 0x0c, 0x8a, 0x7e, 0x29, + 0x60, 0xcb, 0x08, 0xd1, 0xb4, 0x95, 0x68, 0x76, + 0xea, 0x4e, 0x0c, 0x94, 0xf2, 0x42, 0x3d, 0xd1, + 0x7a, 0xc2, 0xfe, 0x6c, 0xb3, 0xe6, 0x12, 0x8a, + 0x33, 0x02, 0x92, 0x00, 0xc0, 0x30, 0x00, 0x00, + 0x11, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0b, + 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x23, + 0x00, 0x00, +}; + +/* + * outlook.office365.com:587 with starttls - this server response includes + * multiple handshake messages contained in a single TLS record. + */ +static uint8_t tls12_server_response_with_cert[] = { + 0x16, 0x03, 0x03, 0x0f, 0x2b, 0x02, 0x00, 0x00, + 0x4d, 0x03, 0x03, 0x5f, 0x7c, 0x69, 0x42, 0xe1, + 0x19, 0xf0, 0x22, 0xfb, 0x71, 0x9a, 0xf1, 0x63, + 0x34, 0xbb, 0x61, 0x46, 0xea, 0x5f, 0x0b, 0x5e, + 0xb1, 0x4e, 0x37, 0x96, 0x67, 0xff, 0x83, 0xea, + 0x0e, 0x16, 0x85, 0x20, 0x3a, 0x1b, 0x00, 0x00, + 0x17, 0xe9, 0xac, 0xca, 0x19, 0x61, 0xaf, 0x70, + 0x28, 0x3b, 0x18, 0xaa, 0x6c, 0xa0, 0x0f, 0x78, + 0xd0, 0x83, 0xfc, 0x5d, 0x78, 0xf9, 0x6d, 0xdb, + 0x16, 0x21, 0x15, 0xa2, 0xc0, 0x30, 0x00, 0x00, + 0x05, 0xff, 0x01, 0x00, 0x01, 0x00, 0x0b, 0x00, + 0x0d, 0x47, 0x00, 0x0d, 0x44, 0x00, 0x08, 0xaf, + 0x30, 0x82, 0x08, 0xab, 0x30, 0x82, 0x07, 0x93, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0c, 0x6d, + 0xea, 0x0b, 0xe1, 0x97, 0x27, 0x60, 0xa1, 0x59, + 0xb1, 0x85, 0x60, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, + 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, + 0x76, 0x2d, 0x73, 0x61, 0x31, 0x3c, 0x30, 0x3a, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x33, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, + 0x6e, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x53, + 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, + 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x30, + 0x30, 0x38, 0x31, 0x33, 0x32, 0x33, 0x31, 0x38, + 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, + 0x38, 0x31, 0x34, 0x32, 0x33, 0x31, 0x38, 0x34, + 0x39, 0x5a, 0x30, 0x6a, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, + 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, + 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, + 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, + 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, + 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x0b, 0x6f, 0x75, 0x74, 0x6c, 0x6f, + 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc9, + 0x20, 0x3f, 0x57, 0xb9, 0xf9, 0x71, 0xaa, 0x3c, + 0x6a, 0x0a, 0x5d, 0x3f, 0xc9, 0x8d, 0x99, 0xa5, + 0x50, 0x26, 0x25, 0x4e, 0xdc, 0x69, 0x52, 0xb3, + 0x33, 0x70, 0xe7, 0x72, 0xa2, 0x83, 0x92, 0x54, + 0xd1, 0xd4, 0x86, 0x15, 0xf2, 0xc4, 0x65, 0xf8, + 0xbc, 0xe5, 0xd2, 0x1e, 0x12, 0x25, 0x9e, 0x75, + 0x8e, 0x77, 0xd2, 0x8e, 0x94, 0xca, 0x03, 0x4b, + 0xf4, 0xc8, 0xca, 0xe3, 0xe3, 0x9b, 0x66, 0xa3, + 0xa1, 0x37, 0x74, 0xcc, 0xfe, 0xc4, 0x1e, 0x64, + 0xdc, 0xe3, 0x18, 0xba, 0xc1, 0x7b, 0x39, 0x5b, + 0xb1, 0x47, 0xe9, 0x11, 0x92, 0xef, 0xee, 0xe6, + 0x08, 0xcd, 0x93, 0x7b, 0x09, 0xc7, 0x39, 0xfe, + 0xe5, 0xe2, 0x47, 0x3f, 0x68, 0x78, 0xa4, 0x17, + 0x78, 0x13, 0xcb, 0x12, 0x38, 0x9d, 0x89, 0x2b, + 0x1f, 0x75, 0x9b, 0x87, 0x5d, 0x53, 0xfc, 0xb0, + 0x2a, 0xaf, 0x2d, 0x86, 0x8a, 0x76, 0x3b, 0xce, + 0x5e, 0xae, 0x43, 0x74, 0x68, 0xc3, 0x28, 0xbf, + 0x10, 0x2f, 0xdd, 0xd9, 0x43, 0x4b, 0x2d, 0xa6, + 0xdc, 0x1f, 0x6d, 0x90, 0xd0, 0xce, 0x14, 0x1e, + 0x6c, 0xdc, 0x7b, 0x06, 0xe4, 0x7b, 0xa9, 0x81, + 0x40, 0xed, 0xde, 0x18, 0xb7, 0xdf, 0x53, 0x61, + 0xbc, 0x18, 0x83, 0x11, 0xc7, 0xb4, 0x1b, 0x99, + 0xef, 0x14, 0xe4, 0x63, 0x39, 0xe3, 0x5c, 0x2f, + 0xe7, 0x89, 0x58, 0x5b, 0xda, 0x03, 0x3a, 0x39, + 0x96, 0x8a, 0xca, 0x4f, 0xd8, 0xe3, 0x6c, 0x7f, + 0x6e, 0xd3, 0xe7, 0x30, 0x34, 0x9c, 0xdb, 0x8b, + 0xe8, 0x6a, 0xa6, 0x08, 0x77, 0x1d, 0x63, 0xd6, + 0x57, 0x9d, 0xcd, 0xa7, 0x47, 0x05, 0x39, 0x96, + 0x7b, 0xfd, 0x9a, 0x09, 0x99, 0xef, 0x49, 0xb1, + 0x89, 0x02, 0xbe, 0x4f, 0xb8, 0xef, 0xa0, 0x04, + 0x29, 0x74, 0xfb, 0x9a, 0x7e, 0x9d, 0xa8, 0x10, + 0xfb, 0x7e, 0xb0, 0x6c, 0x60, 0x4f, 0x57, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x05, 0x53, + 0x30, 0x82, 0x05, 0x4f, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x05, 0xa0, 0x30, 0x81, 0x9e, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, + 0x01, 0x04, 0x81, 0x91, 0x30, 0x81, 0x8e, 0x30, + 0x4b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x02, 0x86, 0x3f, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, + 0x2f, 0x67, 0x73, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, + 0x61, 0x6c, 0x73, 0x68, 0x61, 0x32, 0x67, 0x33, + 0x2e, 0x63, 0x72, 0x74, 0x30, 0x3f, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x32, 0x2e, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x73, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x61, 0x6c, 0x73, + 0x68, 0x61, 0x32, 0x67, 0x33, 0x30, 0x56, 0x06, + 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4f, 0x30, 0x4d, + 0x30, 0x41, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0xa0, 0x32, 0x01, 0x14, 0x30, 0x34, 0x30, + 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, + 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x2f, 0x30, 0x08, 0x06, 0x06, 0x67, + 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, + 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, + 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0xa0, 0x39, 0xa0, + 0x37, 0x86, 0x35, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x73, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x76, 0x61, 0x6c, 0x73, 0x68, + 0x61, 0x32, 0x67, 0x33, 0x2e, 0x63, 0x72, 0x6c, + 0x30, 0x82, 0x02, 0x10, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x82, 0x02, 0x07, 0x30, 0x82, 0x02, + 0x03, 0x82, 0x0b, 0x6f, 0x75, 0x74, 0x6c, 0x6f, + 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x16, + 0x2a, 0x2e, 0x63, 0x6c, 0x6f, 0x2e, 0x66, 0x6f, + 0x6f, 0x74, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x64, + 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x0d, + 0x2a, 0x2e, 0x68, 0x6f, 0x74, 0x6d, 0x61, 0x69, + 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x16, 0x2a, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, + 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x0a, 0x2a, + 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x82, 0x16, 0x2a, 0x2e, 0x6e, 0x72, 0x62, + 0x2e, 0x66, 0x6f, 0x6f, 0x74, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x64, 0x6e, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x82, 0x0c, 0x2a, 0x2e, 0x6f, 0x66, 0x66, + 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x82, + 0x0f, 0x2a, 0x2e, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x33, 0x36, 0x35, 0x2e, 0x63, 0x6f, 0x6d, + 0x82, 0x0d, 0x2a, 0x2e, 0x6f, 0x75, 0x74, 0x6c, + 0x6f, 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x82, + 0x17, 0x2a, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, + 0x6f, 0x6b, 0x2e, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x33, 0x36, 0x35, 0x2e, 0x63, 0x6f, 0x6d, + 0x82, 0x1b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x75, 0x74, + 0x6c, 0x6f, 0x6f, 0x6b, 0x2e, 0x6c, 0x69, 0x76, + 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x82, 0x1d, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, + 0x6b, 0x2e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, + 0x2e, 0x6e, 0x65, 0x74, 0x82, 0x20, 0x61, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, + 0x2e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x70, + 0x70, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x82, 0x16, + 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6f, 0x66, 0x66, 0x69, + 0x63, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x82, 0x1a, + 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2d, 0x73, 0x64, 0x66, 0x2e, + 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x2e, 0x6e, + 0x65, 0x74, 0x82, 0x1d, 0x63, 0x63, 0x73, 0x2e, + 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x6d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x6f, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x82, 0x21, 0x63, 0x63, 0x73, 0x2d, 0x73, + 0x64, 0x66, 0x2e, 0x6c, 0x6f, 0x67, 0x69, 0x6e, + 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x0b, 0x68, 0x6f, + 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, + 0x6d, 0x82, 0x16, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x82, 0x0d, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x33, 0x36, 0x35, 0x2e, 0x63, 0x6f, 0x6d, + 0x82, 0x12, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, + 0x6b, 0x2e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x14, 0x73, 0x75, + 0x62, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x2e, + 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x82, 0x18, 0x73, 0x75, 0x62, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x73, 0x64, + 0x66, 0x2e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, + 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x03, 0x02, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0x68, 0x86, 0xb8, 0x7d, 0x7a, 0xd9, 0x6d, 0x49, + 0x6b, 0x87, 0x2f, 0x18, 0x8b, 0x15, 0x34, 0x6c, + 0xd7, 0xb4, 0x7a, 0x0e, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x8a, + 0x7c, 0x73, 0x44, 0x70, 0xa8, 0x4d, 0x83, 0x25, + 0x6f, 0xa6, 0x53, 0xda, 0x42, 0x52, 0x96, 0xc9, + 0x15, 0x71, 0x21, 0x30, 0x82, 0x01, 0x7c, 0x06, + 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, + 0x02, 0x04, 0x02, 0x04, 0x82, 0x01, 0x6c, 0x04, + 0x82, 0x01, 0x68, 0x01, 0x66, 0x00, 0x76, 0x00, + 0x22, 0x45, 0x45, 0x07, 0x59, 0x55, 0x24, 0x56, + 0x96, 0x3f, 0xa1, 0x2f, 0xf1, 0xf7, 0x6d, 0x86, + 0xe0, 0x23, 0x26, 0x63, 0xad, 0xc0, 0x4b, 0x7f, + 0x5d, 0xc6, 0x83, 0x5c, 0x6e, 0xe2, 0x0f, 0x02, + 0x00, 0x00, 0x01, 0x73, 0xea, 0x1e, 0x7d, 0x2f, + 0x00, 0x00, 0x04, 0x03, 0x00, 0x47, 0x30, 0x45, + 0x02, 0x21, 0x00, 0xf4, 0x50, 0x8f, 0xe7, 0x38, + 0xc9, 0x7a, 0xd1, 0xf7, 0xf7, 0x69, 0xc5, 0x05, + 0xea, 0x8e, 0x03, 0x80, 0x2c, 0x87, 0x06, 0x03, + 0xb6, 0x9b, 0xe6, 0xa5, 0x83, 0x2f, 0xb9, 0xaf, + 0x7b, 0xb4, 0xac, 0x02, 0x20, 0x51, 0xa6, 0x8f, + 0xe8, 0xe5, 0x6c, 0xa7, 0xff, 0x16, 0x01, 0x7e, + 0x15, 0x42, 0x11, 0x31, 0xdc, 0xdc, 0xc7, 0x37, + 0x7c, 0x64, 0x2c, 0xac, 0xdd, 0x42, 0xbb, 0x3c, + 0x79, 0x31, 0x74, 0xcc, 0x9d, 0x00, 0x75, 0x00, + 0x29, 0x79, 0xbe, 0xf0, 0x9e, 0x39, 0x39, 0x21, + 0xf0, 0x56, 0x73, 0x9f, 0x63, 0xa5, 0x77, 0xe5, + 0xbe, 0x57, 0x7d, 0x9c, 0x60, 0x0a, 0xf8, 0xf9, + 0x4d, 0x5d, 0x26, 0x5c, 0x25, 0x5d, 0xc7, 0x84, + 0x00, 0x00, 0x01, 0x73, 0xea, 0x1e, 0x7a, 0xa7, + 0x00, 0x00, 0x04, 0x03, 0x00, 0x46, 0x30, 0x44, + 0x02, 0x20, 0x03, 0xf1, 0x19, 0xd7, 0x0f, 0x2f, + 0xc4, 0xa9, 0x84, 0xa0, 0x33, 0xd4, 0x76, 0xa6, + 0xee, 0xf1, 0xae, 0xe0, 0x03, 0xe7, 0xae, 0x98, + 0x43, 0x17, 0xb0, 0x0f, 0xfb, 0x12, 0xbb, 0x13, + 0xda, 0x34, 0x02, 0x20, 0x10, 0xe6, 0xa9, 0x1d, + 0x8b, 0x1c, 0x64, 0xd4, 0xc9, 0xf7, 0xc0, 0x3d, + 0x3c, 0x77, 0x49, 0xb1, 0x08, 0x3d, 0x1d, 0x5e, + 0x34, 0xf9, 0xd9, 0x10, 0x7c, 0x74, 0x6b, 0x18, + 0xc6, 0x5e, 0x6d, 0x07, 0x00, 0x75, 0x00, 0x55, + 0x81, 0xd4, 0xc2, 0x16, 0x90, 0x36, 0x01, 0x4a, + 0xea, 0x0b, 0x9b, 0x57, 0x3c, 0x53, 0xf0, 0xc0, + 0xe4, 0x38, 0x78, 0x70, 0x25, 0x08, 0x17, 0x2f, + 0xa3, 0xaa, 0x1d, 0x07, 0x13, 0xd3, 0x0c, 0x00, + 0x00, 0x01, 0x73, 0xea, 0x1e, 0x7d, 0xae, 0x00, + 0x00, 0x04, 0x03, 0x00, 0x46, 0x30, 0x44, 0x02, + 0x20, 0x26, 0x21, 0x64, 0xdb, 0xa6, 0xe2, 0x3d, + 0x32, 0x7d, 0x9f, 0xa8, 0xae, 0xb7, 0x29, 0xb7, + 0x42, 0x9b, 0x49, 0xaa, 0xf5, 0xa5, 0xc0, 0x12, + 0x01, 0xa1, 0xb6, 0xe7, 0xf2, 0x01, 0xd4, 0x2f, + 0x45, 0x02, 0x20, 0x4e, 0x19, 0xba, 0x47, 0x75, + 0x8b, 0x49, 0xd7, 0x4b, 0xba, 0x04, 0x62, 0xdd, + 0xa2, 0xb7, 0x6b, 0x05, 0xd0, 0x01, 0x1f, 0x7c, + 0x36, 0x17, 0x27, 0x29, 0xb2, 0x17, 0x1c, 0x7f, + 0x10, 0x81, 0x8a, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x26, + 0xf4, 0xa3, 0x77, 0x1d, 0xdc, 0x9e, 0xc4, 0x1a, + 0x88, 0x23, 0x30, 0x8c, 0xe1, 0x14, 0xf9, 0x62, + 0x0e, 0xbf, 0xad, 0x24, 0xc9, 0xab, 0xab, 0xd0, + 0x68, 0x8b, 0xbc, 0xf1, 0xec, 0x1c, 0xd0, 0x96, + 0xad, 0xf9, 0x5f, 0xdd, 0xe0, 0xee, 0xa8, 0xe0, + 0x2c, 0x3a, 0x19, 0xa5, 0x68, 0x0c, 0x6e, 0xfe, + 0xe6, 0x80, 0xce, 0xa3, 0x3b, 0x6c, 0x00, 0x88, + 0x5c, 0xbf, 0x3c, 0xd8, 0x68, 0x08, 0x36, 0xb9, + 0x9e, 0x84, 0x9b, 0x5f, 0x97, 0xfb, 0x77, 0xea, + 0x72, 0xfb, 0x73, 0x47, 0x00, 0xb0, 0xa8, 0x7c, + 0x64, 0x38, 0xf1, 0xcc, 0xc0, 0x29, 0x71, 0x67, + 0x65, 0x76, 0x4c, 0x80, 0x58, 0x97, 0xc8, 0x62, + 0x63, 0x3e, 0xf1, 0x3e, 0xc0, 0x0e, 0x48, 0x5f, + 0x55, 0x21, 0x8f, 0x96, 0x68, 0xbd, 0x41, 0x14, + 0x7a, 0x0b, 0x8c, 0x31, 0x5b, 0x39, 0xac, 0xa3, + 0xa0, 0x99, 0x58, 0x24, 0xfa, 0xd9, 0x19, 0x32, + 0x1c, 0x9f, 0x2d, 0xa9, 0xed, 0xb9, 0x97, 0xa4, + 0x66, 0x30, 0x29, 0xd8, 0x82, 0xa2, 0xf5, 0xfc, + 0x6d, 0x10, 0xf1, 0xac, 0x1d, 0x3f, 0xfb, 0xde, + 0xa1, 0x0e, 0xb6, 0x84, 0x90, 0xd4, 0x55, 0x5c, + 0x21, 0x1b, 0x1f, 0x21, 0x45, 0x92, 0xc5, 0x9a, + 0x47, 0x05, 0x0f, 0xb8, 0x1c, 0x78, 0x6e, 0xb9, + 0x6b, 0xa3, 0xa9, 0x8d, 0xb1, 0x59, 0xff, 0xf4, + 0xe6, 0x71, 0x77, 0x38, 0x12, 0xfe, 0x41, 0x8f, + 0x04, 0x92, 0x08, 0x3f, 0x32, 0x2a, 0x92, 0x5e, + 0x0a, 0x7b, 0x7e, 0x04, 0xee, 0x24, 0x10, 0x39, + 0xf3, 0xac, 0x5e, 0x04, 0x93, 0x91, 0xa2, 0x8f, + 0x90, 0x04, 0x33, 0x5c, 0x5c, 0x94, 0xb3, 0x80, + 0x2b, 0x43, 0xbf, 0xe3, 0x74, 0x64, 0x20, 0xf4, + 0x00, 0xb2, 0x6c, 0x7b, 0xa8, 0x77, 0xfb, 0x74, + 0x35, 0xce, 0xdd, 0xb6, 0x5f, 0x83, 0x18, 0xc4, + 0xe7, 0x31, 0x1a, 0x8d, 0x30, 0x0d, 0xc4, 0x00, + 0x04, 0x8f, 0x30, 0x82, 0x04, 0x8b, 0x30, 0x82, + 0x03, 0x73, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x0e, 0x47, 0x07, 0xb1, 0x01, 0x9a, 0x0c, 0x57, + 0xad, 0x39, 0xb3, 0xe1, 0x7d, 0xa9, 0xf9, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, + 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, + 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x39, 0x30, + 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x32, 0x35, 0x30, 0x39, 0x30, 0x34, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, + 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, + 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, + 0x61, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x33, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, + 0x41, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xc9, 0x86, 0xa2, 0x05, 0x3e, 0xec, 0x77, 0x4d, + 0x79, 0x42, 0x81, 0xf2, 0xc5, 0x46, 0xa9, 0xc2, + 0x9b, 0xf9, 0x57, 0xa9, 0x48, 0xdd, 0x3c, 0x3b, + 0xe2, 0x16, 0x47, 0x83, 0x15, 0x0c, 0x36, 0x88, + 0x61, 0xb3, 0xc8, 0xb9, 0xd5, 0x20, 0x97, 0xb6, + 0xfe, 0x07, 0x30, 0x01, 0x9e, 0x01, 0x3a, 0xf9, + 0x50, 0x87, 0xa0, 0x4f, 0x60, 0xcc, 0x90, 0xf6, + 0xdd, 0x1f, 0xa6, 0xc7, 0x55, 0x00, 0x6c, 0x54, + 0x31, 0x5f, 0x02, 0x9a, 0xf7, 0x7f, 0x07, 0x9a, + 0xd2, 0x22, 0x53, 0x05, 0xcd, 0x9f, 0xc7, 0xbb, + 0x7b, 0x59, 0x3b, 0x8a, 0xb2, 0x93, 0x78, 0x0d, + 0x43, 0x02, 0x92, 0x76, 0xa5, 0x29, 0xf8, 0x7c, + 0x9d, 0x5c, 0x3a, 0xa2, 0xf8, 0x52, 0x72, 0x22, + 0x45, 0x91, 0xfd, 0x90, 0x12, 0x28, 0x4d, 0x75, + 0xe4, 0xdd, 0xaa, 0x79, 0x58, 0x68, 0x6f, 0x2a, + 0x7e, 0x7b, 0xef, 0xd1, 0x9e, 0x7f, 0x52, 0xdc, + 0xcb, 0x1c, 0x48, 0xe2, 0x3e, 0x4d, 0x5c, 0x47, + 0x7a, 0xb4, 0xf1, 0xce, 0xff, 0xd9, 0x60, 0x2b, + 0x77, 0xd1, 0x62, 0x22, 0x2d, 0xa9, 0x5a, 0x06, + 0x16, 0xee, 0x37, 0x6a, 0x51, 0xcf, 0x8e, 0xa5, + 0xd1, 0x6e, 0x70, 0x4a, 0xf0, 0xd8, 0x63, 0x60, + 0x6a, 0x72, 0x55, 0xd7, 0xf1, 0x99, 0x38, 0x86, + 0x44, 0x67, 0x18, 0xe0, 0x71, 0x8e, 0xc1, 0x40, + 0x6d, 0x85, 0xda, 0x4b, 0xdd, 0x31, 0x73, 0xbc, + 0x32, 0xcc, 0x6f, 0x8e, 0x7b, 0xb9, 0x8d, 0x4b, + 0x80, 0xda, 0xb9, 0xc7, 0xc6, 0x24, 0x83, 0x5e, + 0x32, 0xfb, 0x87, 0xe9, 0x8b, 0x61, 0x67, 0xa2, + 0x99, 0x76, 0xdb, 0xa5, 0xaa, 0xb4, 0xe8, 0x6c, + 0x41, 0x9f, 0x5f, 0x2a, 0xb3, 0xd5, 0x7d, 0xd7, + 0x92, 0xc8, 0x27, 0x4b, 0xec, 0x1f, 0xda, 0x05, + 0x6d, 0x88, 0x73, 0x8f, 0x06, 0xb2, 0x38, 0x3d, + 0x03, 0xa2, 0xe1, 0x87, 0x86, 0x3c, 0xc6, 0xa1, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x44, 0x30, 0x82, 0x01, 0x40, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x02, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x68, 0x86, 0xb8, 0x7d, 0x7a, + 0xd9, 0x6d, 0x49, 0x6b, 0x87, 0x2f, 0x18, 0x8b, + 0x15, 0x34, 0x6c, 0xd7, 0xb4, 0x7a, 0x0e, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, + 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, + 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, + 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, + 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, + 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, + 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, + 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, + 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, + 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x47, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, 0x3e, 0x30, + 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, + 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, + 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x9a, 0xb9, 0x82, 0x1c, 0xdd, 0x83, 0x83, + 0x8b, 0x92, 0xc0, 0xc4, 0xed, 0x01, 0xad, 0x84, + 0xfc, 0x4e, 0xee, 0x6d, 0x9c, 0x1d, 0x01, 0xfa, + 0x52, 0x14, 0xdb, 0xd8, 0xc2, 0x10, 0x63, 0x9f, + 0x6b, 0x39, 0x9a, 0xc7, 0x1c, 0x3c, 0xa0, 0xaa, + 0xe3, 0x19, 0x3a, 0xfc, 0x64, 0x46, 0x2a, 0xef, + 0x35, 0x26, 0x03, 0xf6, 0x05, 0x67, 0xfa, 0x6e, + 0x74, 0xe1, 0x46, 0xfb, 0x40, 0xd8, 0x6f, 0xae, + 0x2d, 0x39, 0x21, 0x74, 0x86, 0x9f, 0x00, 0x05, + 0x1a, 0x3f, 0x2f, 0x93, 0x5b, 0xd4, 0xa4, 0x45, + 0xbc, 0x3d, 0x0c, 0x29, 0x17, 0x5a, 0xd3, 0xfb, + 0x68, 0xa6, 0x0f, 0xe0, 0x00, 0x68, 0x79, 0xb0, + 0x4c, 0xb1, 0x45, 0x8b, 0xc8, 0x85, 0x8c, 0x67, + 0x0e, 0x8c, 0x7d, 0x54, 0xf8, 0xb0, 0x75, 0xce, + 0x0a, 0xac, 0x1d, 0xd7, 0x6b, 0x44, 0xac, 0xfe, + 0x1b, 0xd4, 0xa6, 0x98, 0x21, 0x09, 0x3e, 0xa2, + 0x4b, 0x33, 0xba, 0xba, 0x4b, 0x12, 0xa8, 0x6b, + 0x57, 0x27, 0x9d, 0xfa, 0x94, 0x80, 0xb4, 0x68, + 0x4c, 0x77, 0x60, 0xff, 0xd7, 0x29, 0x5a, 0x38, + 0x3d, 0xce, 0x2d, 0x4b, 0x08, 0x56, 0x9f, 0x69, + 0xcb, 0x7b, 0xd8, 0xe2, 0x36, 0xf9, 0x37, 0x69, + 0xc5, 0xce, 0x36, 0x97, 0x1c, 0xba, 0x0d, 0x3f, + 0x15, 0xb3, 0x65, 0xa0, 0xec, 0x74, 0x12, 0xbd, + 0xb3, 0xad, 0xe8, 0xde, 0x9e, 0xa1, 0xec, 0xd3, + 0xbf, 0xa9, 0xe0, 0xa5, 0x91, 0x6d, 0x83, 0x59, + 0x12, 0x56, 0x2f, 0x13, 0xa6, 0x7e, 0x79, 0x73, + 0xa1, 0xa3, 0x89, 0xd5, 0xe1, 0xa5, 0x8c, 0xce, + 0x2d, 0xac, 0x8a, 0xcf, 0x62, 0x16, 0x65, 0xcd, + 0xd9, 0xee, 0xa8, 0xb6, 0x40, 0x08, 0xb5, 0x7c, + 0x50, 0xf9, 0x37, 0x82, 0x7a, 0xa4, 0x0b, 0x34, + 0x66, 0xec, 0xe9, 0x97, 0x57, 0x1f, 0x8a, 0x67, + 0x3e, 0x81, 0xbc, 0x3b, 0x35, 0xd3, 0x2a, 0x48, + 0x0c, 0x0c, 0x00, 0x01, 0x69, 0x03, 0x00, 0x18, + 0x61, 0x04, 0xb7, 0xa9, 0xbd, 0x74, 0x71, 0xd5, + 0x68, 0xbf, 0xd8, 0xa6, 0x84, 0x12, 0xaf, 0x8f, + 0xd4, 0x2c, 0xcf, 0xf9, 0x72, 0x2b, 0x8c, 0x6c, + 0x73, 0xa3, 0x13, 0x74, 0xdb, 0x83, 0x3e, 0xa6, + 0xf4, 0x1b, 0xee, 0xa9, 0x34, 0xe5, 0x65, 0xa7, + 0xaf, 0xef, 0xf2, 0xac, 0xfb, 0x87, 0xb4, 0xdb, + 0x8b, 0x05, 0x4f, 0xe8, 0x25, 0x3d, 0x32, 0x65, + 0xda, 0x47, 0xd8, 0xd2, 0x86, 0xad, 0x9b, 0x37, + 0xbc, 0x45, 0xef, 0xb6, 0x91, 0xa2, 0x71, 0x2f, + 0x13, 0x68, 0xfa, 0xa7, 0x20, 0xe4, 0x8a, 0xa8, + 0x9b, 0xbe, 0xf6, 0x7c, 0xc8, 0x16, 0xd4, 0x50, + 0x9d, 0x63, 0xb3, 0xf4, 0x6e, 0xd3, 0x8f, 0x32, + 0x68, 0x66, 0x04, 0x01, 0x01, 0x00, 0xaa, 0xcb, + 0x90, 0xbd, 0x94, 0x10, 0xab, 0xfc, 0x30, 0x1d, + 0x68, 0x1c, 0xb4, 0x21, 0xcf, 0x73, 0xa5, 0x4b, + 0x20, 0x94, 0xde, 0x66, 0x99, 0x54, 0x3f, 0xba, + 0x40, 0x58, 0x50, 0xe3, 0x64, 0x53, 0x90, 0x9e, + 0xf8, 0x67, 0xcc, 0x85, 0x4a, 0xdc, 0xd8, 0xd7, + 0xc8, 0xb5, 0xe0, 0x92, 0x02, 0x6b, 0xa8, 0x76, + 0x67, 0xc5, 0xae, 0x12, 0x56, 0xff, 0xd1, 0xda, + 0xc0, 0x48, 0x17, 0x99, 0xc9, 0xbe, 0x02, 0xc6, + 0x9e, 0x5c, 0xd9, 0x44, 0x3f, 0x06, 0xbd, 0x98, + 0xe3, 0x4d, 0x46, 0x10, 0xe8, 0x20, 0xed, 0x7b, + 0xcd, 0x73, 0xed, 0x03, 0x6a, 0x4c, 0x49, 0xaf, + 0xbe, 0xa3, 0xe0, 0xab, 0x9a, 0xb8, 0xf8, 0x06, + 0x25, 0x31, 0x8d, 0x32, 0x44, 0xfd, 0xd6, 0xb0, + 0xd4, 0x6c, 0x9a, 0x2a, 0x0f, 0xab, 0xe2, 0x13, + 0x10, 0x6d, 0x41, 0x0b, 0x97, 0x74, 0xa0, 0x04, + 0x16, 0x60, 0xf1, 0x8e, 0x74, 0xf3, 0x91, 0x75, + 0x2b, 0x92, 0x2b, 0xc7, 0x5b, 0x6f, 0x1d, 0x70, + 0xe2, 0xc6, 0x9a, 0x7d, 0x66, 0x55, 0x98, 0x01, + 0x71, 0xb8, 0xdd, 0xf4, 0x70, 0xc9, 0x74, 0x56, + 0xcc, 0xa5, 0x2c, 0x51, 0x70, 0x72, 0xc2, 0x44, + 0xb9, 0x59, 0xc3, 0xc3, 0xf8, 0x29, 0x4e, 0x79, + 0x40, 0x9b, 0x30, 0x35, 0x66, 0xb2, 0xd8, 0x7d, + 0xfe, 0x65, 0x6b, 0xf0, 0x17, 0xa3, 0x13, 0xc7, + 0xc7, 0xc6, 0x48, 0xb2, 0xae, 0x4f, 0x26, 0x0b, + 0x8a, 0x40, 0xaa, 0x06, 0x65, 0x8a, 0x95, 0x00, + 0xc4, 0xc9, 0xfd, 0x69, 0x0a, 0xa9, 0x0a, 0x18, + 0xff, 0x95, 0x40, 0xab, 0x84, 0x75, 0xfe, 0x11, + 0xb1, 0x6f, 0xca, 0x5e, 0xf7, 0xe4, 0x1d, 0x8d, + 0x08, 0x1c, 0xd3, 0x95, 0xf4, 0x9b, 0x17, 0x41, + 0xa8, 0x8f, 0x6e, 0xfa, 0x6c, 0x43, 0x60, 0x39, + 0x0a, 0xa2, 0x7e, 0xdf, 0x3e, 0x74, 0xc2, 0xbf, + 0xaf, 0x96, 0x96, 0xbd, 0x21, 0x4b, 0x0d, 0x00, + 0x00, 0x1a, 0x03, 0x01, 0x02, 0x40, 0x00, 0x12, + 0x04, 0x01, 0x05, 0x01, 0x02, 0x01, 0x04, 0x03, + 0x05, 0x03, 0x02, 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, +}; + +struct tlslegacy_client_test { + const unsigned char *desc; + unsigned char *server_response; + const size_t server_response_len; + const SSL_METHOD *(*ssl_method)(void); + int want_state; +}; + +static struct tlslegacy_client_test tlslegacy_client_tests[] = { + { + .desc = "TLSv1.2 legacy fallback", + .server_response = tls12_server_response, + .server_response_len = sizeof(tls12_server_response), + .ssl_method = TLS_client_method, + .want_state = SSL3_ST_CR_CERT_A, + }, + { + .desc = "TLSv1.2 legacy fallback with server cert", + .server_response = tls12_server_response_with_cert, + .server_response_len = sizeof(tls12_server_response_with_cert), + .ssl_method = TLS_client_method, + .want_state = SSL3_ST_CR_KEY_EXCH_B, + }, +}; + +#define N_TLSLEGACY_CLIENT_TESTS \ + (sizeof(tlslegacy_client_tests) / sizeof(*tlslegacy_client_tests)) + +static int +tlslegacy_client_test(int testno, struct tlslegacy_client_test *tct) +{ + BIO *rbio = NULL, *wbio = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int ret = 1; + + fprintf(stderr, "Test %d - %s\n", testno, tct->desc); + + if ((rbio = BIO_new_mem_buf(tct->server_response, + tct->server_response_len)) == NULL) { + fprintf(stderr, "Failed to setup rbio\n"); + goto failure; + } + if ((wbio = BIO_new(BIO_s_mem())) == NULL) { + fprintf(stderr, "Failed to setup wbio\n"); + goto failure; + } + + if ((ssl_ctx = SSL_CTX_new(tct->ssl_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new() returned NULL\n"); + goto failure; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + fprintf(stderr, "SSL_new() returned NULL\n"); + goto failure; + } + + BIO_up_ref(rbio); + BIO_up_ref(wbio); + SSL_set_bio(ssl, rbio, wbio); + + if (SSL_connect(ssl) == 1) { + fprintf(stderr, "SSL_connect() succeeded\n"); + goto failure; + } + + if (SSL_state(ssl) != tct->want_state) { + fprintf(stderr, "FAIL: Got SSL state %x, want %x", + SSL_state(ssl), tct->want_state); + goto failure; + } + + ret = 0; + + failure: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + BIO_free(rbio); + BIO_free(wbio); + + return (ret); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + for (i = 0; i < N_TLSLEGACY_CLIENT_TESTS; i++) + failed |= tlslegacy_client_test(i, &tlslegacy_client_tests[i]); + + return (failed); +} diff --git a/Libraries/libressl/tests/tlstest.bat b/Libraries/libressl/tests/tlstest.bat new file mode 100644 index 000000000..4b4fad1be --- /dev/null +++ b/Libraries/libressl/tests/tlstest.bat @@ -0,0 +1,14 @@ +@echo off +setlocal enabledelayedexpansion +REM tlstest.bat + +set tlstest_bin=%1 +set tlstest_bin=%tlstest_bin:/=\% +if not exist %tlstest_bin% exit /b 1 + +%tlstest_bin% %srcdir%\ca.pem %srcdir%\server.pem %srcdir%\server.pem +if !errorlevel! neq 0 ( + exit /b 1 +) + +endlocal diff --git a/Libraries/libressl/tests/tlstest.c b/Libraries/libressl/tests/tlstest.c new file mode 100644 index 000000000..fb6649e83 --- /dev/null +++ b/Libraries/libressl/tests/tlstest.c @@ -0,0 +1,555 @@ +/* $OpenBSD: tlstest.c,v 1.15 2022/07/16 07:46:08 tb Exp $ */ +/* + * Copyright (c) 2017 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#define CIRCULAR_BUFFER_SIZE 512 + +unsigned char client_buffer[CIRCULAR_BUFFER_SIZE]; +unsigned char *client_readptr, *client_writeptr; + +unsigned char server_buffer[CIRCULAR_BUFFER_SIZE]; +unsigned char *server_readptr, *server_writeptr; + +char *cafile, *certfile, *keyfile; + +int debug = 0; + +static void +circular_init(void) +{ + client_readptr = client_writeptr = client_buffer; + server_readptr = server_writeptr = server_buffer; +} + +static ssize_t +circular_read(char *name, unsigned char *buf, size_t bufsize, + unsigned char **readptr, unsigned char *writeptr, + unsigned char *outbuf, size_t outlen) +{ + unsigned char *nextptr = *readptr; + size_t n = 0; + + while (n < outlen) { + if (nextptr == writeptr) + break; + *outbuf++ = *nextptr++; + if ((size_t)(nextptr - buf) >= bufsize) + nextptr = buf; + *readptr = nextptr; + n++; + } + + if (debug && n > 0) + fprintf(stderr, "%s buffer: read %zi bytes\n", name, n); + + return (n > 0 ? (ssize_t)n : TLS_WANT_POLLIN); +} + +static ssize_t +circular_write(char *name, unsigned char *buf, size_t bufsize, + unsigned char *readptr, unsigned char **writeptr, + const unsigned char *inbuf, size_t inlen) +{ + unsigned char *nextptr = *writeptr; + unsigned char *prevptr; + size_t n = 0; + + while (n < inlen) { + prevptr = nextptr++; + if ((size_t)(nextptr - buf) >= bufsize) + nextptr = buf; + if (nextptr == readptr) + break; + *prevptr = *inbuf++; + *writeptr = nextptr; + n++; + } + + if (debug && n > 0) + fprintf(stderr, "%s buffer: wrote %zi bytes\n", name, n); + + return (n > 0 ? (ssize_t)n : TLS_WANT_POLLOUT); +} + +static ssize_t +client_read(struct tls *ctx, void *buf, size_t buflen, void *cb_arg) +{ + return circular_read("client", client_buffer, sizeof(client_buffer), + &client_readptr, client_writeptr, buf, buflen); +} + +static ssize_t +client_write(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg) +{ + return circular_write("server", server_buffer, sizeof(server_buffer), + server_readptr, &server_writeptr, buf, buflen); +} + +static ssize_t +server_read(struct tls *ctx, void *buf, size_t buflen, void *cb_arg) +{ + return circular_read("server", server_buffer, sizeof(server_buffer), + &server_readptr, server_writeptr, buf, buflen); +} + +static ssize_t +server_write(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg) +{ + return circular_write("client", client_buffer, sizeof(client_buffer), + client_readptr, &client_writeptr, buf, buflen); +} + +static int +do_tls_handshake(char *name, struct tls *ctx) +{ + int rv; + + rv = tls_handshake(ctx); + if (rv == 0) + return (1); + if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT) + return (0); + + errx(1, "%s handshake failed: %s", name, tls_error(ctx)); +} + +static int +do_tls_close(char *name, struct tls *ctx) +{ + int rv; + + rv = tls_close(ctx); + if (rv == 0) + return (1); + if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT) + return (0); + + errx(1, "%s close failed: %s", name, tls_error(ctx)); +} + +static int +do_client_server_handshake(char *desc, struct tls *client, + struct tls *server_cctx) +{ + int i, client_done, server_done; + + i = client_done = server_done = 0; + do { + if (client_done == 0) + client_done = do_tls_handshake("client", client); + if (server_done == 0) + server_done = do_tls_handshake("server", server_cctx); + } while (i++ < 100 && (client_done == 0 || server_done == 0)); + + if (client_done == 0 || server_done == 0) { + printf("FAIL: %s TLS handshake did not complete\n", desc); + return (1); + } + + return (0); +} + +static int +do_client_server_close(char *desc, struct tls *client, struct tls *server_cctx) +{ + int i, client_done, server_done; + + i = client_done = server_done = 0; + do { + if (client_done == 0) + client_done = do_tls_close("client", client); + if (server_done == 0) + server_done = do_tls_close("server", server_cctx); + } while (i++ < 100 && (client_done == 0 || server_done == 0)); + + if (client_done == 0 || server_done == 0) { + printf("FAIL: %s TLS close did not complete\n", desc); + return (1); + } + + return (0); +} + +static int +do_client_server_test(char *desc, struct tls *client, struct tls *server_cctx) +{ + if (do_client_server_handshake(desc, client, server_cctx) != 0) + return (1); + + printf("INFO: %s TLS handshake completed successfully\n", desc); + + /* XXX - Do some reads and writes... */ + + if (do_client_server_close(desc, client, server_cctx) != 0) + return (1); + + printf("INFO: %s TLS close completed successfully\n", desc); + + return (0); +} + +static int +test_tls_cbs(struct tls *client, struct tls *server) +{ + struct tls *server_cctx; + int failure; + + circular_init(); + + if (tls_accept_cbs(server, &server_cctx, server_read, server_write, + NULL) == -1) + errx(1, "failed to accept: %s", tls_error(server)); + + if (tls_connect_cbs(client, client_read, client_write, NULL, + "test") == -1) + errx(1, "failed to connect: %s", tls_error(client)); + + failure = do_client_server_test("callback", client, server_cctx); + + tls_free(server_cctx); + + return (failure); +} + +static int +test_tls_fds(struct tls *client, struct tls *server) +{ + struct tls *server_cctx; + int cfds[2], sfds[2]; + int failure; + + if (pipe2(cfds, O_NONBLOCK) == -1) + err(1, "failed to create pipe"); + if (pipe2(sfds, O_NONBLOCK) == -1) + err(1, "failed to create pipe"); + + if (tls_accept_fds(server, &server_cctx, sfds[0], cfds[1]) == -1) + errx(1, "failed to accept: %s", tls_error(server)); + + if (tls_connect_fds(client, cfds[0], sfds[1], "test") == -1) + errx(1, "failed to connect: %s", tls_error(client)); + + failure = do_client_server_test("file descriptor", client, server_cctx); + + tls_free(server_cctx); + + close(cfds[0]); + close(cfds[1]); + close(sfds[0]); + close(sfds[1]); + + return (failure); +} + +static int +test_tls_socket(struct tls *client, struct tls *server) +{ + struct tls *server_cctx; + int failure; + int sv[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, + sv) == -1) + err(1, "failed to create socketpair"); + + if (tls_accept_socket(server, &server_cctx, sv[0]) == -1) + errx(1, "failed to accept: %s", tls_error(server)); + + if (tls_connect_socket(client, sv[1], "test") == -1) + errx(1, "failed to connect: %s", tls_error(client)); + + failure = do_client_server_test("socket", client, server_cctx); + + tls_free(server_cctx); + + close(sv[0]); + close(sv[1]); + + return (failure); +} + +static int +test_tls(char *client_protocols, char *server_protocols, char *ciphers) +{ + struct tls_config *client_cfg, *server_cfg; + struct tls *client, *server; + uint32_t protocols; + int failure = 0; + + if ((client = tls_client()) == NULL) + errx(1, "failed to create tls client"); + if ((client_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls client config"); + tls_config_insecure_noverifyname(client_cfg); + if (tls_config_parse_protocols(&protocols, client_protocols) == -1) + errx(1, "failed to parse protocols: %s", tls_config_error(client_cfg)); + if (tls_config_set_protocols(client_cfg, protocols) == -1) + errx(1, "failed to set protocols: %s", tls_config_error(client_cfg)); + if (tls_config_set_ciphers(client_cfg, ciphers) == -1) + errx(1, "failed to set ciphers: %s", tls_config_error(client_cfg)); + if (tls_config_set_ca_file(client_cfg, cafile) == -1) + errx(1, "failed to set ca: %s", tls_config_error(client_cfg)); + + if ((server = tls_server()) == NULL) + errx(1, "failed to create tls server"); + if ((server_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls server config"); + if (tls_config_parse_protocols(&protocols, server_protocols) == -1) + errx(1, "failed to parse protocols: %s", tls_config_error(server_cfg)); + if (tls_config_set_protocols(server_cfg, protocols) == -1) + errx(1, "failed to set protocols: %s", tls_config_error(server_cfg)); + if (tls_config_set_ciphers(server_cfg, ciphers) == -1) + errx(1, "failed to set ciphers: %s", tls_config_error(server_cfg)); + if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1) + errx(1, "failed to set keypair: %s", + tls_config_error(server_cfg)); + + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + tls_reset(server); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + tls_config_free(client_cfg); + tls_config_free(server_cfg); + + failure |= test_tls_cbs(client, server); + + tls_free(client); + tls_free(server); + + return (failure); +} + +static int +do_tls_tests(void) +{ + struct tls_config *client_cfg, *server_cfg; + struct tls *client, *server; + int failure = 0; + + printf("== TLS tests ==\n"); + + if ((client = tls_client()) == NULL) + errx(1, "failed to create tls client"); + if ((client_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls client config"); + tls_config_insecure_noverifyname(client_cfg); + if (tls_config_set_ca_file(client_cfg, cafile) == -1) + errx(1, "failed to set ca: %s", tls_config_error(client_cfg)); + + if ((server = tls_server()) == NULL) + errx(1, "failed to create tls server"); + if ((server_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls server config"); + if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1) + errx(1, "failed to set keypair: %s", + tls_config_error(server_cfg)); + + tls_reset(client); + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + tls_reset(server); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + failure |= test_tls_cbs(client, server); + + tls_reset(client); + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + tls_reset(server); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + failure |= test_tls_fds(client, server); + + tls_reset(client); + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + tls_reset(server); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + tls_config_free(client_cfg); + tls_config_free(server_cfg); + + failure |= test_tls_socket(client, server); + + tls_free(client); + tls_free(server); + + printf("\n"); + + return (failure); +} + +static int +do_tls_ordering_tests(void) +{ + struct tls *client = NULL, *server = NULL, *server_cctx = NULL; + struct tls_config *client_cfg, *server_cfg; + int failure = 0; + + printf("== TLS ordering tests ==\n"); + + if ((client = tls_client()) == NULL) + errx(1, "failed to create tls client"); + if ((client_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls client config"); + tls_config_insecure_noverifyname(client_cfg); + if (tls_config_set_ca_file(client_cfg, cafile) == -1) + errx(1, "failed to set ca: %s", tls_config_error(client_cfg)); + + if ((server = tls_server()) == NULL) + errx(1, "failed to create tls server"); + if ((server_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls server config"); + if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1) + errx(1, "failed to set keypair: %s", + tls_config_error(server_cfg)); + + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + tls_config_free(client_cfg); + tls_config_free(server_cfg); + + if (tls_handshake(client) != -1) { + printf("FAIL: TLS handshake succeeded on unconnnected " + "client context\n"); + failure = 1; + goto done; + } + + circular_init(); + + if (tls_accept_cbs(server, &server_cctx, server_read, server_write, + NULL) == -1) + errx(1, "failed to accept: %s", tls_error(server)); + + if (tls_connect_cbs(client, client_read, client_write, NULL, + "test") == -1) + errx(1, "failed to connect: %s", tls_error(client)); + + if (do_client_server_handshake("ordering", client, server_cctx) != 0) { + failure = 1; + goto done; + } + + if (tls_handshake(client) != -1) { + printf("FAIL: TLS handshake succeeded twice\n"); + failure = 1; + goto done; + } + + if (tls_handshake(server_cctx) != -1) { + printf("FAIL: TLS handshake succeeded twice\n"); + failure = 1; + goto done; + } + + if (do_client_server_close("ordering", client, server_cctx) != 0) { + failure = 1; + goto done; + } + + done: + tls_free(client); + tls_free(server); + tls_free(server_cctx); + + printf("\n"); + + return (failure); +} + +struct test_versions { + char *client; + char *server; +}; + +static struct test_versions tls_test_versions[] = { + {"tlsv1.3", "all"}, + {"tlsv1.2", "all"}, + {"tlsv1.1", "all"}, + {"tlsv1.0", "all"}, + {"all", "tlsv1.3"}, + {"all", "tlsv1.2"}, + {"all", "tlsv1.1"}, + {"all", "tlsv1.0"}, + {"tlsv1.3", "tlsv1.3"}, + {"tlsv1.2", "tlsv1.2"}, + {"tlsv1.1", "tlsv1.1"}, + {"tlsv1.0", "tlsv1.0"}, +}; + +#define N_TLS_VERSION_TESTS \ + (sizeof(tls_test_versions) / sizeof(*tls_test_versions)) + +static int +do_tls_version_tests(void) +{ + struct test_versions *tv; + int failure = 0; + size_t i; + + printf("== TLS version tests ==\n"); + + for (i = 0; i < N_TLS_VERSION_TESTS; i++) { + tv = &tls_test_versions[i]; + printf("INFO: version test %zu - client versions '%s' " + "and server versions '%s'\n", i, tv->client, tv->server); + failure |= test_tls(tv->client, tv->server, "legacy"); + printf("\n"); + } + + return failure; +} + +int +main(int argc, char **argv) +{ + int failure = 0; + + if (argc != 4) { + fprintf(stderr, "usage: %s cafile certfile keyfile\n", + argv[0]); + return (1); + } + + cafile = argv[1]; + certfile = argv[2]; + keyfile = argv[3]; + + failure |= do_tls_tests(); + failure |= do_tls_ordering_tests(); + failure |= do_tls_version_tests(); + + return (failure); +} diff --git a/Libraries/libressl/tests/tlstest.sh b/Libraries/libressl/tests/tlstest.sh new file mode 100644 index 000000000..25f8647b7 --- /dev/null +++ b/Libraries/libressl/tests/tlstest.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +tlstest_bin=./tlstest +if [ -e ./tlstest.exe ]; then + tlstest_bin=./tlstest.exe +fi + +if [ -z $srcdir ]; then + srcdir=. +fi + +$tlstest_bin $srcdir/ca.pem $srcdir/server.pem $srcdir/server.pem diff --git a/Libraries/libressl/tests/utf8test.c b/Libraries/libressl/tests/utf8test.c new file mode 100644 index 000000000..26477e882 --- /dev/null +++ b/Libraries/libressl/tests/utf8test.c @@ -0,0 +1,319 @@ +/* $OpenBSD: utf8test.c,v 1.5 2022/11/26 16:08:56 tb Exp $ */ +/* + * Copyright (c) 2014 Philip Guenther + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * A mostly exhaustive test of UTF-8 decoder and encoder + */ + +#include +#include +#include + +#include +#include "asn1_local.h" /* peek into the internals */ + +#define UNCHANGED 0xfedcba98 + +#define ASSERT(x) \ + do { \ + if (!(x)) \ + errx(1, "test failed at line %d: %s", \ + __LINE__, #x); \ + } while (0) + +int +main(void) +{ + unsigned char testbuf[] = "012345"; + const unsigned char zerobuf[sizeof testbuf] = { 0 }; + unsigned long value; + unsigned int i, j, k, l; + int ret; + + /* + * First, verify UTF8_getc() + */ + value = UNCHANGED; + ret = UTF8_getc(testbuf, 0, &value); + ASSERT(ret == 0); + ASSERT(value == UNCHANGED); + + /* check all valid single-byte chars */ + for (i = 0; i < 0x80; i++) { + testbuf[0] = i; + ret = UTF8_getc(testbuf, 1, &value); + ASSERT(ret == 1); + ASSERT(value == i); + + ret = UTF8_getc(testbuf, 2, &value); + ASSERT(ret == 1); + ASSERT(value == i); + } + + /* + * Verify failure on all invalid initial bytes: + * 0x80 - 0xBF following bytes only + * 0xC0 - 0xC1 used to be in non-shortest forms + * 0xF5 - 0xFD used to be initial for 5 and 6 byte sequences + * 0xFE - 0xFF have never been valid in utf-8 + */ + for (i = 0x80; i < 0xC2; i++) { + value = UNCHANGED; + testbuf[0] = i; + ret = UTF8_getc(testbuf, 1, &value); + ASSERT(ret == -2); + ASSERT(value == UNCHANGED); + } + for (i = 0xF5; i < 0x100; i++) { + value = UNCHANGED; + testbuf[0] = i; + ret = UTF8_getc(testbuf, 1, &value); + ASSERT(ret == -2); + ASSERT(value == UNCHANGED); + } + + /* + * Verify handling of all two-byte sequences + */ + for (i = 0xC2; i < 0xE0; i++) { + testbuf[0] = i; + + for (j = 0; j < 0x100; j++) { + testbuf[1] = j; + + value = UNCHANGED; + ret = UTF8_getc(testbuf, 1, &value); + ASSERT(ret == -1); + ASSERT(value == UNCHANGED); + + ret = UTF8_getc(testbuf, 2, &value); + + /* outside range of trailing bytes */ + if (j < 0x80 || j > 0xBF) { + ASSERT(ret == -3); + ASSERT(value == UNCHANGED); + continue; + } + + /* valid */ + ASSERT(ret == 2); + ASSERT((value & 0x3F) == (j & 0x3F)); + ASSERT(value >> 6 == (i & 0x1F)); + } + } + + /* + * Verify handling of all three-byte sequences + */ + for (i = 0xE0; i < 0xF0; i++) { + testbuf[0] = i; + + for (j = 0; j < 0x100; j++) { + testbuf[1] = j; + + for (k = 0; k < 0x100; k++) { + testbuf[2] = k; + + value = UNCHANGED; + ret = UTF8_getc(testbuf, 2, &value); + ASSERT(ret == -1); + ASSERT(value == UNCHANGED); + + ret = UTF8_getc(testbuf, 3, &value); + + /* outside range of trailing bytes */ + if (j < 0x80 || j > 0xBF || + k < 0x80 || k > 0xBF) { + ASSERT(ret == -3); + ASSERT(value == UNCHANGED); + continue; + } + + /* non-shortest form */ + if (i == 0xE0 && j < 0xA0) { + ASSERT(ret == -4); + ASSERT(value == UNCHANGED); + continue; + } + + /* surrogate pair code point */ + if (i == 0xED && j > 0x9F) { + ASSERT(ret == -2); + ASSERT(value == UNCHANGED); + continue; + } + + ASSERT(ret == 3); + ASSERT((value & 0x3F) == (k & 0x3F)); + ASSERT(((value >> 6) & 0x3F) == (j & 0x3F)); + ASSERT(value >> 12 == (i & 0x0F)); + } + } + } + + /* + * Verify handling of all four-byte sequences + */ + for (i = 0xF0; i < 0xF5; i++) { + testbuf[0] = i; + + for (j = 0; j < 0x100; j++) { + testbuf[1] = j; + + for (k = 0; k < 0x100; k++) { + testbuf[2] = k; + + for (l = 0; l < 0x100; l++) { + testbuf[3] = l; + + value = UNCHANGED; + ret = UTF8_getc(testbuf, 3, &value); + ASSERT(ret == -1); + ASSERT(value == UNCHANGED); + + ret = UTF8_getc(testbuf, 4, &value); + + /* outside range of trailing bytes */ + if (j < 0x80 || j > 0xBF || + k < 0x80 || k > 0xBF || + l < 0x80 || l > 0xBF) { + ASSERT(ret == -3); + ASSERT(value == UNCHANGED); + continue; + } + + /* non-shortest form */ + if (i == 0xF0 && j < 0x90) { + ASSERT(ret == -4); + ASSERT(value == UNCHANGED); + continue; + } + + /* beyond end of UCS range */ + if (i == 0xF4 && j > 0x8F) { + ASSERT(ret == -2); + ASSERT(value == UNCHANGED); + continue; + } + + ASSERT(ret == 4); + ASSERT((value & 0x3F) == (l & 0x3F)); + ASSERT(((value >> 6) & 0x3F) == + (k & 0x3F)); + ASSERT(((value >> 12) & 0x3F) == + (j & 0x3F)); + ASSERT(value >> 18 == (i & 0x07)); + } + } + } + } + + + /* + * Next, verify UTF8_putc() + */ + memset(testbuf, 0, sizeof testbuf); + + /* single-byte sequences */ + for (i = 0; i < 0x80; i++) { + ret = UTF8_putc(NULL, 0, i); + ASSERT(ret == 1); + + testbuf[0] = 0; + ret = UTF8_putc(testbuf, 0, i); + ASSERT(ret == -1); + ASSERT(memcmp(testbuf, zerobuf, sizeof testbuf) == 0); + + ret = UTF8_putc(testbuf, 1, i); + ASSERT(ret == 1); + ASSERT(testbuf[0] == i); + ASSERT(memcmp(testbuf+1, zerobuf, sizeof(testbuf)-1) == 0); + } + + /* two-byte sequences */ + for (i = 0x80; i < 0x800; i++) { + ret = UTF8_putc(NULL, 0, i); + ASSERT(ret == 2); + + testbuf[0] = testbuf[1] = 0; + ret = UTF8_putc(testbuf, 1, i); + ASSERT(ret == -1); + ASSERT(memcmp(testbuf, zerobuf, sizeof testbuf) == 0); + + ret = UTF8_putc(testbuf, 2, i); + ASSERT(ret == 2); + ASSERT(memcmp(testbuf+2, zerobuf, sizeof(testbuf)-2) == 0); + ret = UTF8_getc(testbuf, 2, &value); + ASSERT(ret == 2); + ASSERT(value == i); + } + + /* three-byte sequences */ + for (i = 0x800; i < 0x10000; i++) { + if (i >= 0xD800 && i < 0xE000) { + /* surrogates aren't valid */ + ret = UTF8_putc(NULL, 0, i); + ASSERT(ret == -2); + continue; + } + + ret = UTF8_putc(NULL, 0, i); + ASSERT(ret == 3); + + testbuf[0] = testbuf[1] = testbuf[2] = 0; + ret = UTF8_putc(testbuf, 2, i); + ASSERT(ret == -1); + ASSERT(memcmp(testbuf, zerobuf, sizeof testbuf) == 0); + + ret = UTF8_putc(testbuf, 3, i); + ASSERT(ret == 3); + ASSERT(memcmp(testbuf+3, zerobuf, sizeof(testbuf)-3) == 0); + ret = UTF8_getc(testbuf, 3, &value); + ASSERT(ret == 3); + ASSERT(value == i); + } + + /* four-byte sequences */ + for (i = 0x10000; i < 0x110000; i++) { + ret = UTF8_putc(NULL, 0, i); + ASSERT(ret == 4); + + testbuf[0] = testbuf[1] = testbuf[2] = testbuf[3] = 0; + ret = UTF8_putc(testbuf, 3, i); + ASSERT(ret == -1); + ASSERT(memcmp(testbuf, zerobuf, sizeof testbuf) == 0); + + ret = UTF8_putc(testbuf, 4, i); + ASSERT(ret == 4); + ASSERT(memcmp(testbuf+4, zerobuf, sizeof(testbuf)-4) == 0); + ret = UTF8_getc(testbuf, 4, &value); + ASSERT(ret == 4); + ASSERT(value == i); + } + + /* spot check some larger values to confirm error return */ + for (i = 0x110000; i < 0x110100; i++) { + ret = UTF8_putc(NULL, 0, i); + ASSERT(ret == -2); + } + for (value = (unsigned long)-1; value > (unsigned long)-256; value--) { + ret = UTF8_putc(NULL, 0, value); + ASSERT(ret == -2); + } + + return 0; +} diff --git a/Libraries/libressl/tests/valid_handshakes_terminate.c b/Libraries/libressl/tests/valid_handshakes_terminate.c new file mode 100644 index 000000000..286b860a7 --- /dev/null +++ b/Libraries/libressl/tests/valid_handshakes_terminate.c @@ -0,0 +1,54 @@ +/* $OpenBSD: valid_handshakes_terminate.c,v 1.4 2022/12/01 13:49:12 tb Exp $ */ +/* + * Copyright (c) 2019 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "tls13_handshake.c" + +int +main(int argc, char *argv[]) +{ + size_t i, j; + int terminates; + int fail = 0; + + for (i = 1; i < handshake_count; i++) { + enum tls13_message_type mt = handshakes[i][0]; + + if (mt == INVALID) + continue; + + terminates = 0; + + for (j = 0; j < TLS13_NUM_MESSAGE_TYPES; j++) { + mt = handshakes[i][j]; + if (state_machine[mt].handshake_complete) { + terminates = 1; + break; + } + } + + if (!terminates) { + fail = 1; + printf("FAIL: handshake_complete never true in " + "handshake %zu\n", i); + } + } + + return fail; +} diff --git a/Libraries/libressl/tests/verifytest.c b/Libraries/libressl/tests/verifytest.c new file mode 100644 index 000000000..57aa99214 --- /dev/null +++ b/Libraries/libressl/tests/verifytest.c @@ -0,0 +1,526 @@ +/* $OpenBSD: verifytest.c,v 1.8 2023/05/28 09:02:01 beck Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +extern int tls_check_name(struct tls *ctx, X509 *cert, const char *name, + int *match); + +struct alt_name { + const char name[128]; + int name_len; + int name_type; +}; + +struct verify_test { + const char common_name[128]; + int common_name_len; + struct alt_name alt_name1; + struct alt_name alt_name2; + struct alt_name alt_name3; + const char name[128]; + int want_return; + int want_match; + int name_type; +}; + +struct verify_test verify_tests[] = { + { + /* CN without SANs - matching. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* Zero length name - non-matching. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .name = "", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - matching. */ + .common_name = "*.openbsd.org", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* CN without SANs - non-matching. */ + .common_name = "www.openbsdfoundation.org", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid CN wildcard. */ + .common_name = "w*.openbsd.org", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid CN wildcard. */ + .common_name = "www.*.org", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid CN wildcard. */ + .common_name = "www.openbsd.*", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid CN wildcard. */ + .common_name = "*", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid CN wildcard. */ + .common_name = "*.org", + .common_name_len = -1, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid CN wildcard. */ + .common_name = "*.org", + .common_name_len = -1, + .name = "openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN IPv4 without SANs - matching. */ + .common_name = "1.2.3.4", + .common_name_len = -1, + .name = "1.2.3.4", + .want_return = 0, + .want_match = 1, + }, + { + /* CN IPv4 wildcard without SANS - invalid IP wildcard. */ + .common_name = "*.2.3.4", + .common_name_len = -1, + .name = "1.2.3.4", + .want_return = 0, + .want_match = 0, + }, + { + /* CN IPv6 without SANs - matching. */ + .common_name = "cafe::beef", + .common_name_len = -1, + .name = "cafe::beef", + .want_return = 0, + .want_match = 1, + }, + { + /* CN without SANs - error due to embedded NUL in CN. */ + .common_name = { + 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x62, 0x73, 0x64, 0x2e, 0x6f, 0x72, 0x67, 0x00, + 0x6e, 0x61, 0x73, 0x74, 0x79, 0x2e, 0x6f, 0x72, + 0x67, + }, + .common_name_len = 25, + .name = "www.openbsd.org", + .want_return = -1, + .want_match = 0, + }, + { + /* CN wildcard without SANs - invalid non-matching name. */ + .common_name = "*.openbsd.org", + .common_name_len = -1, + .name = ".openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN with SANs - matching on first SAN. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "ftp.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* SANs only - matching on first SAN. */ + .common_name_len = 0, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "ftp.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* SANs only - matching on second SAN. */ + .common_name_len = 0, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "ftp.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "ftp.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* SANs only - non-matching. */ + .common_name_len = 0, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "ftp.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "mail.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN with SANs - matching on second SAN. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "ftp.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "ftp.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* CN with SANs - matching on wildcard second SAN. */ + .common_name = "www.openbsdfoundation.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsdfoundation.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "*.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 1, + }, + { + /* CN with SANs - non-matching invalid wildcard. */ + .common_name = "www.openbsdfoundation.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsdfoundation.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "*.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN with SANs - non-matching IPv4 due to GEN_DNS SAN. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = "1.2.3.4", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "1.2.3.4", + .want_return = 0, + .want_match = 0, + }, + { + /* CN with SANs - matching IPv4 on GEN_IPADD SAN. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = {0x01, 0x02, 0x03, 0x04}, + .name_len = 4, + .name_type = GEN_IPADD, + }, + .name = "1.2.3.4", + .want_return = 0, + .want_match = 1, + }, + { + /* CN with SANs - matching IPv6 on GEN_IPADD SAN. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = { + 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xef, + }, + .name_len = 16, + .name_type = GEN_IPADD, + }, + .name = "cafe::beef", + .want_return = 0, + .want_match = 1, + }, + { + /* CN with SANs - error due to embedded NUL in GEN_DNS. */ + .common_name = "www.openbsd.org.nasty.org", + .common_name_len = -1, + .alt_name1 = { + .name = "www.openbsd.org.nasty.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .alt_name2 = { + .name = { + 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x62, 0x73, 0x64, 0x2e, 0x6f, 0x72, 0x67, 0x00, + 0x6e, 0x61, 0x73, 0x74, 0x79, 0x2e, 0x6f, 0x72, + 0x67, + }, + .name_len = 25, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = -1, + .want_match = 0, + }, + { + /* CN with SAN - non-matching due to non-matching SAN. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = "ftp.openbsd.org", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = 0, + .want_match = 0, + }, + { + /* CN with SAN - error due to illegal dNSName. */ + .common_name = "www.openbsd.org", + .common_name_len = -1, + .alt_name1 = { + .name = " ", + .name_len = -1, + .name_type = GEN_DNS, + }, + .name = "www.openbsd.org", + .want_return = -1, + .want_match = 0, + }, +}; + +#define N_VERIFY_TESTS \ + (sizeof(verify_tests) / sizeof(*verify_tests)) + +static void +alt_names_add(STACK_OF(GENERAL_NAME) *alt_name_stack, struct alt_name *alt) +{ + ASN1_STRING *alt_name_str; + GENERAL_NAME *alt_name; + + if ((alt_name = GENERAL_NAME_new()) == NULL) + errx(1, "failed to malloc GENERAL_NAME"); + alt_name->type = alt->name_type; + + if ((alt_name_str = ASN1_STRING_new()) == NULL) + errx(1, "failed to malloc alt name"); + if (ASN1_STRING_set(alt_name_str, alt->name, alt->name_len) == 0) + errx(1, "failed to set alt name"); + + switch (alt_name->type) { + case GEN_DNS: + alt_name->d.dNSName = alt_name_str; + break; + case GEN_IPADD: + alt_name->d.iPAddress = alt_name_str; + break; + default: + errx(1, "unknown alt name type (%i)", alt_name->type); + } + + if (sk_GENERAL_NAME_push(alt_name_stack, alt_name) == 0) + errx(1, "failed to push alt_name"); +} + +static void +cert_add_alt_names(X509 *cert, struct verify_test *vt) +{ + STACK_OF(GENERAL_NAME) *alt_name_stack = NULL; + + if (vt->alt_name1.name_type == 0) + return; + + if ((alt_name_stack = sk_GENERAL_NAME_new_null()) == NULL) + errx(1, "failed to malloc sk_GENERAL_NAME"); + + if (vt->alt_name1.name_type != 0) + alt_names_add(alt_name_stack, &vt->alt_name1); + if (vt->alt_name2.name_type != 0) + alt_names_add(alt_name_stack, &vt->alt_name2); + if (vt->alt_name3.name_type != 0) + alt_names_add(alt_name_stack, &vt->alt_name3); + + if (X509_add1_ext_i2d(cert, NID_subject_alt_name, + alt_name_stack, 0, 0) == 0) + errx(1, "failed to set subject alt name"); + + sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free); +} + +static int +do_verify_test(int test_no, struct verify_test *vt) +{ + struct tls *tls; + X509_NAME *name; + X509 *cert; + int failed = 1; + int match; + + /* Build certificate structure. */ + if ((cert = X509_new()) == NULL) + errx(1, "failed to malloc X509"); + + if (vt->common_name_len != 0) { + if ((name = X509_NAME_new()) == NULL) + errx(1, "failed to malloc X509_NAME"); + if (X509_NAME_add_entry_by_NID(name, NID_commonName, + vt->name_type ? vt->name_type : MBSTRING_ASC, + (unsigned char *)vt->common_name, + vt->common_name_len, -1, 0) == 0) + errx(1, "failed to add name entry"); + if (X509_set_subject_name(cert, name) == 0) + errx(1, "failed to set subject name"); + X509_NAME_free(name); + } + + if ((tls = tls_client()) == NULL) + errx(1, "failed to malloc tls_client"); + + cert_add_alt_names(cert, vt); + + match = 1; + + if (tls_check_name(tls, cert, vt->name, &match) != vt->want_return) { + fprintf(stderr, "FAIL: test %i failed for check name '%s': " + "%s\n", test_no, vt->name, tls_error(tls)); + goto done; + } + if (match != vt->want_match) { + fprintf(stderr, "FAIL: test %i failed to match name '%s'\n", + test_no, vt->name); + goto done; + } + + failed = 0; + + done: + X509_free(cert); + tls_free(tls); + + return (failed); +} + +int +main(int argc, char **argv) +{ + int failed = 0; + size_t i; + + tls_init(); + + for (i = 0; i < N_VERIFY_TESTS; i++) + failed += do_verify_test(i, &verify_tests[i]); + + return (failed); +} diff --git a/Libraries/libressl/tests/x25519test.c b/Libraries/libressl/tests/x25519test.c new file mode 100644 index 000000000..321aac4d7 --- /dev/null +++ b/Libraries/libressl/tests/x25519test.c @@ -0,0 +1,141 @@ +/* $OpenBSD: x25519test.c,v 1.3 2022/12/01 13:55:22 tb Exp $ */ +/* + * Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +static int +x25519_test(void) +{ + /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */ + static const uint8_t kScalar1[32] = { + 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, + 0x3b, 0x16, 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd, + 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, 0x5a, 0x18, + 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4, + }; + static const uint8_t kPoint1[32] = { + 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, + 0x35, 0x94, 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, + 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 0x35, 0x3b, + 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c, + }; + static const uint8_t kExpected1[32] = { + 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, + 0x8e, 0x94, 0xea, 0x4d, 0xf2, 0x8d, 0x08, 0x4f, + 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c, 0x71, 0xf7, + 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52, + }; + static const uint8_t kScalar2[32] = { + 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, + 0x5a, 0xd2, 0x26, 0x91, 0x95, 0x7d, 0x6a, 0xf5, + 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea, 0x01, 0xd4, + 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d, + }; + static const uint8_t kPoint2[32] = { + 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, + 0xf4, 0xb7, 0x95, 0x9d, 0x05, 0x38, 0xae, 0x2c, + 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, 0x3c, 0x3e, + 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93, + }; + static const uint8_t kExpected2[32] = { + 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, + 0x7a, 0xad, 0xe4, 0x5c, 0xb4, 0xb8, 0x73, 0xf8, + 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f, 0xa1, 0x52, + 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57, + }; + + uint8_t out[32]; + + X25519(out, kScalar1, kPoint1); + if (memcmp(kExpected1, out, sizeof(out)) != 0) { + fprintf(stderr, "X25519 test one failed.\n"); + return 1; + } + + X25519(out, kScalar2, kPoint2); + if (memcmp(kExpected2, out, sizeof(out)) != 0) { + fprintf(stderr, "X25519 test two failed.\n"); + return 1; + } + + return 0; +} + +static int +x25519_iterated_test(void) +{ + /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */ + static const uint8_t kExpected[32] = { + 0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, + 0x28, 0x00, 0xef, 0x56, 0x6f, 0x2f, 0x4d, 0x3c, + 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, 0xe3, 0x87, + 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51, + }; + + uint8_t scalar[32] = {9}, point[32] = {9}, out[32]; + unsigned i; + + for (i = 0; i < 1000; i++) { + X25519(out, scalar, point); + memcpy(point, scalar, sizeof(point)); + memcpy(scalar, out, sizeof(scalar)); + } + + if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) { + fprintf(stderr, "Iterated X25519 test failed\n"); + return 1; + } + + return 0; +} + +static int +x25519_small_order_test(void) +{ + static const uint8_t kSmallOrderPoint[32] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, + 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, + 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, + 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00, + }; + + uint8_t out[32], private_key[32]; + + memset(private_key, 0x11, sizeof(private_key)); + if (X25519(out, private_key, kSmallOrderPoint)) { + fprintf(stderr, "X25519 returned success with a small-order input.\n"); + return 1; + } + + return 0; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= x25519_test(); + failed |= x25519_iterated_test(); + failed |= x25519_small_order_test(); + + return failed; +} diff --git a/Libraries/libressl/tests/x509_asn1.c b/Libraries/libressl/tests/x509_asn1.c new file mode 100644 index 000000000..c7753623f --- /dev/null +++ b/Libraries/libressl/tests/x509_asn1.c @@ -0,0 +1,601 @@ +/* $OpenBSD: x509_asn1.c,v 1.20 2023/06/05 18:32:06 job Exp $ */ +/* + * Copyright (c) 2023 Job Snijders + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This program tests whether the presence of "->enc.modified = 1;" + * in select X509 setter functions properly triggers invalidation of cached + * DER. + */ + +#include +#include +#include + +#include +#include +#include + +static const struct fnnames { + char *name; + void (*fn); +} fnnames[] = { + { "X509_set_version", X509_set_version }, + { "X509_set_serialNumber", X509_set_serialNumber }, + { "X509_set_issuer_name", X509_set_issuer_name }, + { "X509_set_subject_name", X509_set_subject_name }, + { "X509_set_notBefore", X509_set_notBefore }, + { "X509_set_notAfter", X509_set_notAfter }, + { "X509_set_pubkey", X509_set_pubkey }, + { "X509_CRL_set_version", X509_CRL_set_version }, + { "X509_CRL_set_issuer_name", X509_CRL_set_issuer_name }, + { "X509_CRL_set_lastUpdate", X509_CRL_set_lastUpdate }, + { "X509_CRL_set_nextUpdate", X509_CRL_set_nextUpdate }, + { "X509_REQ_add_extensions", X509_REQ_add_extensions }, + { "X509_REQ_add1_attr", X509_REQ_add1_attr }, + { NULL, NULL } +}; + +static void +lookup_and_err(void (*fn)) +{ + int i; + + for (i = 0; fnnames[i].name; i++) { + if (fnnames[i].fn == fn) + errx(1, "%s failed", fnnames[i].name); + } +} + +static void +x509_setup(unsigned char **der, unsigned char **der2, X509 **x, + long dersz, long *der2sz) +{ + const unsigned char *cpder; + + cpder = *der; + if ((*x = d2i_X509(NULL, &cpder, dersz)) == NULL) + errx(1, "d2i_X509"); + if ((*der2sz = i2d_X509(*x, der2)) <= 0) + errx(1, "i2d_X509"); +} + +static void +x509_cleanup(X509 **x, unsigned char **der) +{ + X509_free(*x); + *x = NULL; + free(*der); + *der = NULL; +} + +static void +x509_set_integer(int (*f)(X509 *, ASN1_INTEGER *), X509 **x, int i) +{ + ASN1_INTEGER *ai; + + if ((ai = ASN1_INTEGER_new()) == NULL) + err(1, NULL); + if (!ASN1_INTEGER_set(ai, i)) + errx(1, "ASN1_INTEGER_set"); + if (!f(*x, ai)) + lookup_and_err(f); + + ASN1_INTEGER_free(ai); +} + +static void +x509_set_name(int (*f)(X509 *, X509_NAME *), X509 **x, + const unsigned char *n) +{ + X509_NAME *xn; + + if ((xn = X509_NAME_new()) == NULL) + err(1, NULL); + if (!X509_NAME_add_entry_by_txt(xn, "C", MBSTRING_ASC, n, -1, -1, 0)) + errx(1, "X509_NAME_add_entry_by_txt"); + if (!f(*x, xn)) + lookup_and_err(f); + + X509_NAME_free(xn); +} + +static void +x509_set_time(int (*f)(X509 *, const ASN1_TIME *), X509 **x, int t) +{ + ASN1_TIME *at; + + if ((at = X509_gmtime_adj(NULL, t)) == NULL) + errx(1, "X509_gmtime_adj"); + if (!f(*x, at)) + lookup_and_err(f); + + ASN1_TIME_free(at); +} + +static int +x509_compare(char *f, X509 *a, const unsigned char *der, long dersz) +{ + unsigned char *der_test = NULL; + long der_testsz; + int rc = 0; + + if ((der_testsz = i2d_X509(a, &der_test)) <= 0) + errx(1, "i2d_X509"); + + if (dersz == der_testsz) { + if (memcmp(der, der_test, dersz) == 0) { + warnx("%s() stale version of encoding after i2d", f); + rc = 1; + } else + warnx("%s() OK", f); + } else + warnx("%s() OK", f); + + free(der_test); + return rc; +} + +static void +x509_crl_setup(unsigned char **der, unsigned char **der2, X509_CRL **xc, + long dersz, long *der2sz) +{ + const unsigned char *cpder; + + cpder = *der; + if ((*xc = d2i_X509_CRL(NULL, &cpder, dersz)) == NULL) + errx(1, "d2i_X509"); + if ((*der2sz = i2d_X509_CRL(*xc, der2)) <= 0) + errx(1, "i2d_X509"); +} + +static void +x509_crl_cleanup(X509_CRL **xc, unsigned char **der) +{ + X509_CRL_free(*xc); + *xc = NULL; + free(*der); + *der = NULL; +} + +static void +x509_crl_set_name(int (*f)(X509_CRL *, X509_NAME *), X509_CRL **xc, + const unsigned char *n) +{ + X509_NAME *xn; + + if ((xn = X509_NAME_new()) == NULL) + err(1, NULL); + if (!X509_NAME_add_entry_by_txt(xn, "C", MBSTRING_ASC, n, -1, -1, 0)) + errx(1, "X509_NAME_add_entry_by_txt"); + if (!f(*xc, xn)) + lookup_and_err(f); + + X509_NAME_free(xn); +} + +static void +x509_crl_set_time(int (*f)(X509_CRL *, const ASN1_TIME *), X509_CRL **xc, int t) +{ + ASN1_TIME *at; + + if ((at = X509_gmtime_adj(NULL, t)) == NULL) + errx(1, "X509_gmtime_adj"); + if (!f(*xc, at)) + lookup_and_err(f); + + ASN1_TIME_free(at); +} + +static int +x509_crl_compare(char *f, X509_CRL *ac, const unsigned char *der, long dersz) +{ + unsigned char *der_test = NULL; + long der_testsz; + int rc = 0; + + if ((der_testsz = i2d_X509_CRL(ac, &der_test)) <= 0) + errx(1, "i2d_X509_CRL"); + + if (dersz == der_testsz) { + if (memcmp(der, der_test, dersz) == 0) { + warnx("%s() stale version of encoding after i2d", f); + rc = 1; + } else + warnx("%s() OK", f); + } else + warnx("%s() OK", f); + + free(der_test); + return rc; +} + +static int +test_x509_setters(void) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + X509 *a, *x; + unsigned char *der = NULL, *der2 = NULL; + long dersz, der2sz; + int failed = 0; + + if ((x = X509_new()) == NULL) + err(1, NULL); + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) + errx(1, "EVP_PKEY_CTX_new_id"); + if (EVP_PKEY_keygen_init(pkey_ctx) != 1) + errx(1, "EVP_PKEY_keygen_init"); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, 2048) <= 0) + errx(1, "EVP_PKEY_CTX_set_rsa_keygen_bits"); + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) + errx(1, "EVP_PKEY_keygen"); + if (X509_set_pubkey(x, pkey) != 1) + errx(1, "X509_set_pubkey"); + + x509_set_integer(X509_set_serialNumber, &x, 1); + x509_set_time(X509_set_notBefore, &x, 0); + x509_set_time(X509_set_notAfter, &x, 60); + x509_set_name(X509_set_issuer_name, &x, "NL"); + x509_set_name(X509_set_subject_name, &x, "BE"); + + /* one time creation of the original DER */ + if (!X509_sign(x, pkey, EVP_sha256())) + errx(1, "X509_sign"); + if ((dersz = i2d_X509(x, &der)) <= 0) + errx(1, "i2d_X509"); + + /* test X509_set_version */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + if (!X509_set_version(a, 2)) + errx(1, "X509_set_version"); + failed |= x509_compare("X509_set_version", a, der2, der2sz); + x509_cleanup(&a, &der2); + + /* test X509_set_serialNumber */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + x509_set_integer(X509_set_serialNumber, &a, 2); + failed |= x509_compare("X509_set_serialNumber", a, der2, der2sz); + x509_cleanup(&a, &der2); + + /* test X509_set_issuer_name */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + x509_set_name(X509_set_issuer_name, &a, "DE"); + failed |= x509_compare("X509_set_issuer_name", a, der2, der2sz); + x509_cleanup(&a, &der2); + + /* test X509_set_subject_name */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + x509_set_name(X509_set_subject_name, &a, "FR"); + failed |= x509_compare("X509_set_subject_name", a, der2, der2sz); + x509_cleanup(&a, &der2); + + /* test X509_set_notBefore */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + x509_set_time(X509_set_notBefore, &a, 120); + failed |= x509_compare("X509_set_notBefore", a, der2, der2sz); + x509_cleanup(&a, &der2); + + /* test X509_set_notAfter */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + x509_set_time(X509_set_notAfter, &a, 180); + failed |= x509_compare("X509_set_notAfter", a, der2, der2sz); + x509_cleanup(&a, &der2); + + /* test X509_set_pubkey */ + x509_setup(&der, &der2, &a, dersz, &der2sz); + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) + errx(1, "EVP_PKEY_keygen"); + if (X509_set_pubkey(a, pkey) != 1) + errx(1, "X509_set_pubkey"); + failed |= x509_compare("X509_set_pubkey", a, der2, der2sz); + x509_cleanup(&a, &der2); + + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey); + X509_free(x); + free(der); + + return failed; +} + +static int +test_x509_crl_setters(void) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + X509_CRL *ac, *xc; + unsigned char *der = NULL, *der2 = NULL; + long dersz, der2sz; + int failed = 0; + + if ((xc = X509_CRL_new()) == NULL) + err(1, NULL); + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) + errx(1, "EVP_PKEY_CTX_new_id"); + if (EVP_PKEY_keygen_init(pkey_ctx) != 1) + errx(1, "EVP_PKEY_keygen_init"); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, 2048) <= 0) + errx(1, "EVP_PKEY_CTX_set_rsa_keygen_bits"); + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) + errx(1, "EVP_PKEY_keygen"); + + x509_crl_set_time(X509_CRL_set_lastUpdate, &xc, 0); + x509_crl_set_time(X509_CRL_set_nextUpdate, &xc, 60); + x509_crl_set_name(X509_CRL_set_issuer_name, &xc, "NL"); + + /* one time creation of the original DER */ + if (!X509_CRL_sign(xc, pkey, EVP_sha256())) + errx(1, "X509_CRL_sign"); + if ((dersz = i2d_X509_CRL(xc, &der)) <= 0) + errx(1, "i2d_X509_CRL"); + + /* test X509_CRL_set_version */ + x509_crl_setup(&der, &der2, &ac, dersz, &der2sz); + if (!X509_CRL_set_version(ac, 1)) + errx(1, "X509_CRL_set_version"); + failed |= x509_crl_compare("X509_CRL_set_version", ac, der2, der2sz); + x509_crl_cleanup(&ac, &der2); + + /* test X509_CRL_set_issuer_name */ + x509_crl_setup(&der, &der2, &ac, dersz, &der2sz); + x509_crl_set_name(X509_CRL_set_issuer_name, &ac, "DE"); + failed |= x509_crl_compare("X509_CRL_set_issuer_name", ac, der2, + der2sz); + x509_crl_cleanup(&ac, &der2); + + /* test X509_CRL_set_lastUpdate */ + x509_crl_setup(&der, &der2, &ac, dersz, &der2sz); + x509_crl_set_time(X509_CRL_set_lastUpdate, &ac, 120); + failed |= x509_crl_compare("X509_CRL_set_lastUpdate", ac, der2, der2sz); + x509_crl_cleanup(&ac, &der2); + + /* test X509_CRL_set_nextUpdate */ + x509_crl_setup(&der, &der2, &ac, dersz, &der2sz); + x509_crl_set_time(X509_CRL_set_nextUpdate, &ac, 180); + failed |= x509_crl_compare("X509_CRL_set_nextUpdate", ac, der2, der2sz); + x509_crl_cleanup(&ac, &der2); + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(pkey_ctx); + X509_CRL_free(xc); + free(der); + + return failed; +} + +static void +x509_req_setup(unsigned char **der, unsigned char **der2, X509_REQ **xr, + long dersz, long *der2sz) +{ + const unsigned char *cpder; + + cpder = *der; + if ((*xr = d2i_X509_REQ(NULL, &cpder, dersz)) == NULL) + errx(1, "d2i_X509"); + if ((*der2sz = i2d_X509_REQ(*xr, der2)) <= 0) + errx(1, "i2d_X509"); +} + +static int +x509_req_compare(char *f, X509_REQ *xr, const unsigned char *der, long dersz) +{ + unsigned char *der_test = NULL; + long der_testsz; + int rc = 0; + + if ((der_testsz = i2d_X509_REQ(xr, &der_test)) <= 0) + errx(1, "i2d_X509_REQ"); + + if (dersz == der_testsz) { + if (memcmp(der, der_test, dersz) == 0) { + warnx("%s() stale version of encoding after i2d", f); + rc = 1; + } else + warnx("%s() OK", f); + } else + warnx("%s() OK", f); + + free(der_test); + return rc; +} + +static void +x509_req_cleanup(X509_REQ **xr, unsigned char **der) +{ + X509_REQ_free(*xr); + *xr = NULL; + free(*der); + *der = NULL; +} + +static int +test_x509_req_setters(void) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + X509_REQ *ar = NULL, *xr = NULL; + unsigned char *der = NULL, *der2 = NULL; + X509_NAME *xn; + ASN1_OCTET_STRING *aos; + X509_EXTENSION *xe; + STACK_OF(X509_EXTENSION) *exts = NULL; + ASN1_OBJECT *coid; + X509_ATTRIBUTE *xa; + long dersz, der2sz; + int failed = 0; + + if ((xr = X509_REQ_new()) == NULL) + err(1, NULL); + + if (!X509_REQ_set_version(xr, 0)) + errx(1, "X509_REQ_set_version"); + + if ((xn = X509_NAME_new()) == NULL) + err(1, NULL); + if (!X509_NAME_add_entry_by_txt(xn, "C", MBSTRING_ASC, "NL", -1, -1, 0)) + errx(1, "X509_NAME_add_entry_by_txt"); + if (!X509_REQ_set_subject_name(xr, xn)) + errx(1, "X509_REQ_set_subject_name"); + + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) + errx(1, "EVP_PKEY_CTX_new_id"); + if (EVP_PKEY_keygen_init(pkey_ctx) != 1) + errx(1, "EVP_PKEY_keygen_init"); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, 2048) <= 0) + errx(1, "EVP_PKEY_CTX_set_rsa_keygen_bits"); + if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) + errx(1, "EVP_PKEY_keygen"); + if (!X509_REQ_set_pubkey(xr, pkey)) + errx(1, "X509_REQ_set_pubkey"); + + if (!X509_REQ_sign(xr, pkey, EVP_sha256())) + errx(1, "X509_REQ_sign"); + if ((dersz = i2d_X509_REQ(xr, &der)) <= 0) + errx(1, "i2d_X509_REQ"); + + /* test X509_REQ_add_extensions */ + x509_req_setup(&der, &der2, &ar, dersz, &der2sz); + if ((aos = ASN1_OCTET_STRING_new()) == NULL) + err(1, NULL); + ASN1_OCTET_STRING_set(aos, (unsigned char *)"DNS: test.nl", + strlen("DNS: test.nl")); + if ((xe = X509_EXTENSION_new()) == NULL) + err(1, NULL); + if (!X509_EXTENSION_create_by_NID(&xe, NID_subject_alt_name, 0, aos)) + errx(1, "X509_EXTENSION_create_by_NID"); + if ((exts = sk_X509_EXTENSION_new_null()) == NULL) + errx(1, "sk_X509_EXTENSION_new_null"); + sk_X509_EXTENSION_push(exts, xe); + if (!X509_REQ_add_extensions(ar, exts)) + errx(1, "X509_REQ_add_extensions"); + failed |= x509_req_compare("X509_REQ_add_extensions", ar, der2, der2sz); + x509_req_cleanup(&ar, &der2); + + /* test X509_REQ_add1_attr */ + x509_req_setup(&der, &der2, &ar, dersz, &der2sz); + if ((coid = OBJ_nid2obj(NID_pkcs7_data)) == NULL) + errx(1, "OBJ_nid2obj"); + if ((xa = X509_ATTRIBUTE_create(NID_pkcs9_contentType, V_ASN1_OBJECT, + coid)) == NULL) + errx(1, "X509_ATTRIBUTE_create"); + if (!X509_REQ_add1_attr(ar, xa)) + errx(1, "X509_REQ_add1_attr"); + failed |= x509_req_compare("X509_REQ_add1_attr", ar, der2, der2sz); + x509_req_cleanup(&ar, &der2); + + ASN1_OBJECT_free(coid); + X509_NAME_free(xn); + ASN1_OCTET_STRING_free(aos); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + X509_ATTRIBUTE_free(xa); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(pkey_ctx); + X509_REQ_free(xr); + free(der); + + return failed; +} + +static const struct testcase { + char *data; + int len; + int len_to_pass; + int encode_type; + int expected_result; + char *expected_string; +} testCases[] = { + /* should work */ + {"fozzie", 6, 80, MBSTRING_ASC, 6, "fozzie"}, + /* should work */ + {"fozzie", 6, -1, MBSTRING_ASC, 6, ""}, + /* should fail, truncation */ + {"muppet", 6, 5, MBSTRING_ASC, -1, ""}, + /* should fail, contains 0 byte */ + {"g\0nzo", 5, 80, MBSTRING_ASC, -1, ""}, + /* should fail, can't encode as utf-8 */ + {"\x30\x00", 2, 80, V_ASN1_SEQUENCE, -1, ""}, +}; + +#define NUM_TEST_CASES (sizeof(testCases) / sizeof(testCases[0])) + +static int +test_x509_name_get(void) +{ + int failed = 0; + size_t i; + + for (i = 0; i < NUM_TEST_CASES; i++) { + const struct testcase *test = testCases + i; + X509_NAME_ENTRY *entry = NULL; + X509_NAME *name = NULL; + char textbuf[80]; + int result; + + textbuf[0] = '\0'; + if ((name = X509_NAME_new()) == NULL) + err(1, "X509_NAME_new"); + if ((entry = X509_NAME_ENTRY_new()) == NULL) + err(1, "X509_NAME_ENTRY_new"); + if (!X509_NAME_ENTRY_set_object(entry, + OBJ_nid2obj(NID_commonName))) + err(1, "X509_NAME_ENTRY_set_object"); + if (!X509_NAME_ENTRY_set_data(entry, test->encode_type, + test->data, test->len)) + err(1, "X509_NAME_ENTRY_set_data"); + if (!X509_NAME_add_entry(name, entry, -1, 0)) + err(1, "X509_NAME_add_entry"); + if (test->len_to_pass == -1) + result = X509_NAME_get_text_by_NID(name, NID_commonName, + NULL, 0); + else + result = X509_NAME_get_text_by_NID(name, NID_commonName, + textbuf, test->len_to_pass); + if (result != test->expected_result) { + fprintf(stderr, + "Test %zu X509_GET_text_by_NID returned %d," + "expected %d\n", i, result, test->expected_result); + failed++; + } + if (result != -1 && + strcmp(test->expected_string, textbuf) != 0) { + fprintf(stderr, + "Test %zu, X509_GET_text_by_NID returned bytes do" + "not match \n", i); + failed++; + } + X509_NAME_ENTRY_free(entry); + X509_NAME_free(name); + } + return failed; +} + +int +main(void) +{ + int failed = 0; + + failed |= test_x509_setters(); + /* failed |= */ test_x509_crl_setters(); + /* failed |= */ test_x509_req_setters(); + failed |= test_x509_name_get(); + + OPENSSL_cleanup(); + + return failed; +} diff --git a/Libraries/libressl/tests/x509_info.c b/Libraries/libressl/tests/x509_info.c new file mode 100644 index 000000000..8e223e207 --- /dev/null +++ b/Libraries/libressl/tests/x509_info.c @@ -0,0 +1,184 @@ +/* $OpenBSD: x509_info.c,v 1.2 2020/09/18 14:41:04 tb Exp $ */ +/* + * Copyright (c) 2020 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +static const char *const bogus_pem = "\ +-----BEGIN BOGUS----- \n\ +-----END BOGUS----- \n\ +"; + +static const char *const cert_pem = "\ +-----BEGIN CERTIFICATE----- \n\ +MIIDpTCCAo2gAwIBAgIJAPYm3GvOr5eTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV \n\ +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT \n\ +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt \n\ +ZWRpYXRlIENBMB4XDTE0MDUyNDE0NDUxMVoXDTI0MDQwMTE0NDUxMVowZDELMAkG \n\ +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU \n\ +RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw \n\ +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY \n\ ++yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs \n\ +lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D \n\ +nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2 \n\ +x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2 \n\ +bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9 \n\ +AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG \n\ ++EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B \n\ +AQUFAAOCAQEAJzA4KTjkjXGSC4He63yX9Br0DneGBzjAwc1H6f72uqnCs8m7jgkE \n\ +PQJFdTzQUKh97QPUuayZ2gl8XHagg+iWGy60Kw37gQ0+lumCN2sllvifhHU9R03H \n\ +bWtS4kue+yQjMbrzf3zWygMDgwvFOUAIgBpH9qGc+CdNu97INTYd0Mvz51vLlxRn \n\ +sC5aBYCWaZFnw3lWYxf9eVFRy9U+DkYFqX0LpmbDtcKP7AZGE6ZwSzaim+Cnoz1u \n\ +Cgn+QmpFXgJKMFIZ82iSZISn+JkCCGxctZX1lMvai4Wi8Y0HxW9FTFZ6KBNwwE4B \n\ +zjbN/ehBkgLlW/DWfi44DvwUHmuU6QP3cw== \n\ +-----END CERTIFICATE----- \n\ +"; + +int +main(void) +{ + BIO *bp; + STACK_OF(X509_INFO) *skin, *skout; + X509_INFO *info0, *info1; + const char *errdata; + unsigned long errcode; + int errcount, errflags, num; + + errcount = 0; + if ((skin = sk_X509_INFO_new_null()) == NULL) + err(1, "sk_X509_INFO_new_null"); + + /* Test with empty input. */ + + if ((bp = BIO_new_mem_buf("", 0)) == NULL) + err(1, "BIO_new_mem_buf(empty)"); + if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) == NULL) + err(1, "empty input: %s", + ERR_error_string(ERR_get_error(), NULL)); + if (skout != skin) + errx(1, "empty input did not return the same stack"); + skout = NULL; + if ((num = sk_X509_INFO_num(skin)) != 0) + errx(1, "empty input created %d X509_INFO objects", num); + BIO_free(bp); + + /* Test with bogus input. */ + + if ((bp = BIO_new_mem_buf(bogus_pem, strlen(bogus_pem))) == NULL) + err(1, "BIO_new_mem_buf(bogus_pem)"); + if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL) + errx(1, "success with bogus input on first try"); + if ((num = sk_X509_INFO_num(skin)) != 0) + errx(1, "bogus input created %d X509_INFO objects", num); + if (BIO_reset(bp) != 1) + errx(1, "BIO_reset"); + + /* Populate stack and test again with bogus input. */ + + if ((info0 = X509_INFO_new()) == NULL) + err(1, "X509_INFO_new"); + info0->references = 2; /* X509_INFO_up_ref(3) doesn't exist. */ + if (sk_X509_INFO_push(skin, info0) != 1) + err(1, "sk_X509_INFO_push"); + if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL) + errx(1, "success with bogus input on second try"); + if ((num = sk_X509_INFO_num(skin)) != 1) + errx(1, "bogus input changed stack size from 1 to %d", num); + if (sk_X509_INFO_value(skin, 0) != info0) + errx(1, "bogus input changed stack content"); + if (info0->references != 2) { + warnx("bogus input changed ref count from 2 to %d", + info0->references); + info0->references = 2; + errcount++; + } + BIO_free(bp); + + /* Use a real certificate object. */ + + if ((bp = BIO_new_mem_buf(cert_pem, strlen(cert_pem))) == NULL) + err(1, "BIO_new_mem_buf(cert_pem)"); + if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) == NULL) { + errdata = NULL; + errflags = 0; + while ((errcode = ERR_get_error_line_data(NULL, NULL, + &errdata, &errflags)) != 0) + if (errdata != NULL && (errflags & ERR_TXT_STRING)) + warnx("%s --- %s", + ERR_error_string(errcode, NULL), + errdata); + else + warnx("%s", ERR_error_string(errcode, NULL)); + err(1, "real input: parsing failed"); + } + if (skout != skin) + errx(1, "real input did not return the same stack"); + skout = NULL; + if ((num = sk_X509_INFO_num(skin)) != 2) + errx(1, "real input changed stack size from 1 to %d", num); + if (sk_X509_INFO_value(skin, 0) != info0) + errx(1, "real input changed stack content"); + if (info0->references != 2) + errx(1, "real input changed ref count from 2 to %d", + info0->references); + info1 = sk_X509_INFO_pop(skin); + if (info1->x509 == NULL) + errx(1, "real input did not create a certificate"); + X509_INFO_free(info1); + info1 = NULL; + BIO_free(bp); + + /* Two real certificates followed by bogus input. */ + + if ((bp = BIO_new(BIO_s_mem())) == NULL) + err(1, "BIO_new"); + if (BIO_puts(bp, cert_pem) != strlen(cert_pem)) + err(1, "BIO_puts(cert_pem) first copy"); + if (BIO_puts(bp, cert_pem) != strlen(cert_pem)) + err(1, "BIO_puts(cert_pem) second copy"); + if (BIO_puts(bp, bogus_pem) != strlen(bogus_pem)) + err(1, "BIO_puts(bogus_pem)"); + if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL) + errx(1, "success with real + bogus input"); + if ((num = sk_X509_INFO_num(skin)) != 1) { + warnx("real + bogus input changed stack size from 1 to %d", + num); + while (sk_X509_INFO_num(skin) > 1) + (void)sk_X509_INFO_pop(skin); + errcount++; + } + if (sk_X509_INFO_value(skin, 0) != info0) + errx(1, "real + bogus input changed stack content"); + if (info0->references != 2) { + warnx("real + bogus input changed ref count from 2 to %d", + info0->references); + errcount++; + } + BIO_free(bp); + info0->references = 1; + X509_INFO_free(info0); + sk_X509_INFO_free(skin); + + if (errcount > 0) + errx(1, "%d errors detected", errcount); + return 0; +} diff --git a/Libraries/libressl/tests/x509attribute.c b/Libraries/libressl/tests/x509attribute.c new file mode 100644 index 000000000..908935cb6 --- /dev/null +++ b/Libraries/libressl/tests/x509attribute.c @@ -0,0 +1,105 @@ +/* $OpenBSD: x509attribute.c,v 1.3 2021/11/01 08:28:31 tb Exp $ */ +/* + * Copyright (c) 2020 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +void fail_head(const char *); +void fail_tail(void); +void fail_str(const char *, const char *); +void fail_int(const char *, int); + +static const char *testname; +static int errcount; + +void +fail_head(const char *stepname) +{ + fprintf(stderr, "failure#%d testname=%s stepname=%s ", + ++errcount, testname, stepname); +} + +void +fail_tail(void) +{ + unsigned long errnum; + + if ((errnum = ERR_get_error())) + fprintf(stderr, "OpenSSL says: %s\n", + ERR_error_string(errnum, NULL)); + if (errno) + fprintf(stderr, "libc says: %s\n", strerror(errno)); +} + +void +fail_str(const char *stepname, const char *result) +{ + fail_head(stepname); + fprintf(stderr, "wrong result=%s\n", result); + fail_tail(); +} + +void +fail_int(const char *stepname, int result) +{ + fail_head(stepname); + fprintf(stderr, "wrong result=%d\n", result); + fail_tail(); +} + +int +main(void) +{ + X509_ATTRIBUTE *attrib; + ASN1_TYPE *any; + ASN1_OBJECT *coid; + int num; + + testname = "preparation"; + if ((coid = OBJ_nid2obj(NID_pkcs7_data)) == NULL) { + fail_str("OBJ_nid2obj", "NULL"); + return 1; + } + + testname = "valid_args"; + if ((attrib = X509_ATTRIBUTE_create(NID_pkcs9_contentType, + V_ASN1_OBJECT, coid)) == NULL) + fail_str("X509_ATTRIBUTE_create", "NULL"); + else if (X509_ATTRIBUTE_get0_object(attrib) == NULL) + fail_str("X509_ATTRIBUTE_get0_object", "NULL"); + else if ((num = X509_ATTRIBUTE_count(attrib)) != 1) + fail_int("X509_ATTRIBUTE_count", num); + else if ((any = X509_ATTRIBUTE_get0_type(attrib, 0)) == NULL) + fail_str("X509_ATTRIBUTE_get0_type", "NULL"); + else if (any->type != V_ASN1_OBJECT) + fail_int("any->type", any->type); + else if (any->value.object != coid) + fail_str("value", "wrong pointer"); + X509_ATTRIBUTE_free(attrib); + + testname = "bad_nid"; + if ((attrib = X509_ATTRIBUTE_create(-1, + V_ASN1_OBJECT, coid)) != NULL) + fail_str("X509_ATTRIBUTE_create", "not NULL"); + X509_ATTRIBUTE_free(attrib); + + return errcount != 0; +} diff --git a/Libraries/libressl/tests/x509name.c b/Libraries/libressl/tests/x509name.c new file mode 100644 index 000000000..9deeeb298 --- /dev/null +++ b/Libraries/libressl/tests/x509name.c @@ -0,0 +1,62 @@ +/* $OpenBSD: x509name.c,v 1.3 2021/10/31 08:27:15 tb Exp $ */ +/* + * Copyright (c) 2018 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +static void debug_print(X509_NAME *); + +static void +debug_print(X509_NAME *name) +{ + int loc; + + for (loc = 0; loc < X509_NAME_entry_count(name); loc++) + printf("%d:", + X509_NAME_ENTRY_set(X509_NAME_get_entry(name, loc))); + putchar(' '); + X509_NAME_print_ex_fp(stdout, name, 0, XN_FLAG_SEP_CPLUS_SPC); + putchar('\n'); +} + +int +main(void) +{ + X509_NAME *name; + + if ((name = X509_NAME_new()) == NULL) + err(1, NULL); + X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_ASC, + "BaWue", -1, -1, 0); + X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, + "KIT", -1, -1, 0); + debug_print(name); + + X509_NAME_add_entry_by_txt(name, "L", MBSTRING_ASC, + "Karlsruhe", -1, 1, 0); + debug_print(name); + + X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, + "DE", -1, 0, 1); + debug_print(name); + + X509_NAME_free(name); + + return 0; +} diff --git a/Libraries/libressl/tests/x509req_ext.c b/Libraries/libressl/tests/x509req_ext.c new file mode 100644 index 000000000..b91a41360 --- /dev/null +++ b/Libraries/libressl/tests/x509req_ext.c @@ -0,0 +1,161 @@ +/* $OpenBSD: x509req_ext.c,v 1.1 2021/11/03 13:08:57 schwarze Exp $ */ +/* + * Copyright (c) 2020, 2021 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +void fail_head(const char *); +void fail_tail(void); +void fail_str(const char *, const char *); +void fail_int(const char *, int); +void fail_ptr(const char *, const void *); + +static const char *testname; +static int errcount; + +void +fail_head(const char *stepname) +{ + fprintf(stderr, "failure#%d testname=%s stepname=%s ", + ++errcount, testname, stepname); +} + +void +fail_tail(void) +{ + unsigned long errnum; + + if ((errnum = ERR_get_error())) + fprintf(stderr, "OpenSSL says: %s\n", + ERR_error_string(errnum, NULL)); + if (errno) + fprintf(stderr, "libc says: %s\n", strerror(errno)); +} + +void +fail_str(const char *stepname, const char *result) +{ + fail_head(stepname); + fprintf(stderr, "wrong result=%s\n", result); + fail_tail(); +} + +void +fail_int(const char *stepname, int result) +{ + fail_head(stepname); + fprintf(stderr, "wrong result=%d\n", result); + fail_tail(); +} + +void +fail_ptr(const char *stepname, const void *result) +{ + fail_head(stepname); + fprintf(stderr, "wrong result=%p\n", result); + fail_tail(); +} + +int +main(void) +{ + X509_REQ *req; + X509_EXTENSIONS *exts; + X509_ATTRIBUTE *attr; + ASN1_TYPE *aval; + int irc; + + testname = "exts=NULL"; + if ((req = X509_REQ_new()) == NULL) { + fail_str("X509_REQ_new", "NULL"); + return 1; + } + if ((irc = X509_REQ_add_extensions(req, NULL)) != 0) + fail_int("X509_REQ_add_extensions", irc); + if ((irc = X509_REQ_get_attr_count(req)) != 0) + fail_int("X509_REQ_get_attr_count", irc); + if ((attr = X509_REQ_get_attr(req, 0)) != NULL) + fail_ptr("X509_REQ_get_attr", attr); + X509_REQ_free(req); + + testname = "nid=-1"; + if ((req = X509_REQ_new()) == NULL) { + fail_str("X509_REQ_new", "NULL"); + return 1; + } + if ((exts = sk_X509_EXTENSION_new_null()) == NULL) { + fail_str("sk_X509_EXTENSION_new_null", "NULL"); + return 1; + } + if ((irc = X509_REQ_add_extensions_nid(req, exts, -1)) != 0) + fail_int("X509_REQ_add_extensions", irc); + if ((irc = X509_REQ_get_attr_count(req)) != 0) + fail_int("X509_REQ_get_attr_count", irc); + if ((attr = X509_REQ_get_attr(req, 0)) != NULL) + fail_ptr("X509_REQ_get_attr", attr); + X509_REQ_free(req); + + testname = "valid"; + if ((req = X509_REQ_new()) == NULL) { + fail_str("X509_REQ_new", "NULL"); + return 1; + } + if ((irc = X509_REQ_add_extensions(req, exts)) != 1) + fail_int("X509_REQ_add_extensions", irc); + sk_X509_EXTENSION_free(exts); + if ((irc = X509_REQ_get_attr_count(req)) != 1) + fail_int("X509_REQ_get_attr_count", irc); + if ((attr = X509_REQ_get_attr(req, 0)) == NULL) { + fail_str("X509_REQ_get_attr", "NULL"); + goto end_valid; + } + if ((irc = X509_ATTRIBUTE_count(attr)) != 1) + fail_int("X509_ATTRIBUTE_count", irc); + if ((aval = X509_ATTRIBUTE_get0_type(attr, 0)) == NULL) { + fail_str("X509_ATTRIBUTE_get0_type", "NULL"); + goto end_valid; + } + if ((irc = ASN1_TYPE_get(aval)) != V_ASN1_SEQUENCE) + fail_int("ASN1_TYPE_get", irc); + exts = ASN1_item_unpack(aval->value.sequence, &X509_EXTENSIONS_it); + if (exts == NULL) { + fail_str("ASN1_item_unpack", "NULL"); + goto end_valid; + } + if ((irc = sk_X509_EXTENSION_num(exts)) != 0) + fail_int("sk_X509_EXTENSION_num", irc); + sk_X509_EXTENSION_free(exts); + +end_valid: + testname = "getext"; + if ((exts = X509_REQ_get_extensions(req)) == NULL) { + fail_str("X509_REQ_get_extensions", "NULL"); + goto end_getext; + } + if ((irc = sk_X509_EXTENSION_num(exts)) != 0) + fail_int("sk_X509_EXTENSION_num", irc); + sk_X509_EXTENSION_free(exts); + +end_getext: + X509_REQ_free(req); + return errcount != 0; +} diff --git a/Libraries/libressl/tests/xchacha20_poly1305_tests.txt b/Libraries/libressl/tests/xchacha20_poly1305_tests.txt new file mode 100644 index 000000000..d3eb39bbe --- /dev/null +++ b/Libraries/libressl/tests/xchacha20_poly1305_tests.txt @@ -0,0 +1,366 @@ +# Test vectors generated from libsodium + +KEY: 1f4774fbe6324700d62dd6a104e7b3ca7160cfd958413f2afdb96695475f007e +NONCE: 029174e5102710975a8a4a936075eb3e0f470d436884d250 +IN: +AD: +CT: +TAG: f55cf0949af356f977479f1f187d7291 + +KEY: eb27969c7abf9aff79348e1e77f1fcba7508ceb29a7471961b017aef9ceaf1c2 +NONCE: 990009311eab3459c1bee84b5b860bb5bdf93c7bec8767e2 +IN: e7ec3d4b9f +AD: +CT: 66bd484861 +TAG: 07e31b4dd0f51f0819a0641c86380f32 + +KEY: 4b6d89dbd7d019c0e1683d4c2a497305c778e2089ddb0f383f2c7fa2a5a52153 +NONCE: 97525eb02a8d347fcf38c81b1be5c3ba59406241cf251ba6 +IN: 074db54ef9fbc680b41a +AD: +CT: 1221898afd6f516f770f +TAG: 75e7182e7d715f5a32ee6733fd324539 + +KEY: 766997b1dc6c3c73b1f50e8c28c0fcb90f206258e685aff320f2d4884506c8f4 +NONCE: 30e7a9454892ef304776b6dc3d2c2f767ed97041b331c173 +IN: b8250c93ac6cf28902137b4522cc67 +AD: +CT: e2a13eeff8831a35d9336cb3b5c5d9 +TAG: 62fdf67735cad0172f9b88603b5f3c13 + +KEY: 6585031b5649fcabd9d4971d4ac5646fc7dca22f991dfa7dac39647001004e20 +NONCE: 705ee25d03fec430e24c9c6ccaa633f5b86dd43682778278 +IN: 9a4ca0633886a742e0241f132e8f90794c34dfd4 +AD: +CT: 0a8e6fd4cd1640be77c4c87dde4ae6222c887ed7 +TAG: edc4fbc91dfa07021e74ae0d9d1c98dc + +KEY: dfc6f7c86a10a319ebcb6362997e585f55b67f3434f47dc4039c2d67973e3077 +NONCE: 6097f30fd75229d928454c7d59a2d2c58bfddcb14c16438e +IN: 74c946a7f0733377e852a23087506a28dccef86e101a4359c0 +AD: +CT: 6e8ea0bb4c2f1323841d8e236816c61c3295866b75cefb5c25 +TAG: f16c0e9487ca7de5e7cb2a1b8bb370fc + +KEY: 59b8d488773767c4804d918709cfec6c69a193371145bb94f183899851aaadac +NONCE: ad5bdf8f190ca2d2cc02a75bb62aa22274cb3c98fe2d25f2 +IN: 066b9ed10f16d3dc132b409aae02d8cac209dd9b4fb789c4d34725ab2a1f +AD: +CT: 2bbd4542489006df66ad1462a932524642b139ddcbf86b6b480e9e6d976c +TAG: ca4835419ba029bc57010a8cc8bca80c + +KEY: 8c0cb4633cf8dc6b4b9552d1035f85517cb1ba4c36bcbc43338a8c6c7d15ce20 +NONCE: 8418b9655a0376fadefa3cdf8805815c4f7b56f467a74a95 +IN: 50c205a9c5d4088ba8e59a96fcd837f5170669854547678288199f1078ff2a81f0b19a +AD: +CT: 8b55a12df1a85dd3fb19c34ab047a85849d15a30225bb5360bad1f0a8f5f2bd49f5898 +TAG: bce13201df6e4a7e6d896262e45d969d + +KEY: b45386a75a5772e34bd193e1946f69ebfb90c37ae4581d39c9669d75e4584f50 +NONCE: 9fb763d0926585b5f726af9b8e3babdb331e9aa97f8d99ed +IN: 64df0e341145d9e4a0d090153591a74893bc36cb9dae1e9570d8fee62e907cf004f9d8a360343483 +AD: +CT: 3146d8a5c898edd832ec9d126e93b3a433ec97dc47dce0e1985bda88c88c6aeca46fc7d9a68e30ab +TAG: 44fdb0d69abd8068442cb2ea6df8b2f2 + +KEY: f2efbd358dd353639a162be39a957d27c0175d5ab72aeba4a266aeda434e4a58 +NONCE: 65a6f7ebe48de78beb183b518589a0afacf71b40a949fa59 +IN: f7473947996e6682a3b9c720f03cfaf26bbcdaf76c83342d2ad922435e227a5d1eacbd9bd6ea1727ec19fb0e42 +AD: +CT: 778a0fb701b9d671ccfaf1454e8928158ede9bb4395119356a8133036840c1bcbb8fe5e19922fbbcf8b18596e7 +TAG: 9d195a89fdd29ca271405d3330f996f9 + +KEY: 9dd674fb4a30a7bb85fc78050479ab0e2c3cc9f9f5b8689a7a67413aca304b21 +NONCE: ad9e8fe15940694725f232e88f79cda7c82fe1b8aae58ba4 +IN: 7272bb6609cbd1399a0b89f6ea255165f99330aeb170ac88fccdd8e226df0952407e35718fb5edc9e987faabb271cc69f7e7 +AD: +CT: 846901650cb38974463a18c367676e1579ebdaf3e96b57224e842f5d5f678f3270b9a15f01241795662befb3db0768800e25 +TAG: 900004db3613acbeb33d65d74dd437d7 + +KEY: 280cbe7380a0d8bb4d8dd4476012f2eeb388a37b8b71067969abb99f6a888007 +NONCE: 2e1854617c67002599e6b077a812c326deb22fe29d093cbb +IN: d0901ec3d31ece2832685ff577f383bdff26c31341ea254acee7c5929a5df74fea2aa964524dc680b2f55fbd4fea900e956c304cc4ac3c +AD: +CT: 546370726cc63068d3520d67f4f57f65d03b9ecec21c2a8c7b1133089ad28b07025a7181bddeb4a49f514fac1a44f64ee3af33d778fb98 +TAG: 39084e33e42a1b05f58da65ba487d138 + +KEY: 887564f75afa78f595cdadcea7340d20f5c5a2df169d0ad14b15fe32ce337004 +NONCE: 54c11df13d1f444da80b0964caeb59474b17b23a650a33f5 +IN: f0f008eece79ecb24b715dff8a3456dfe253924b99f98f2f1b18564cced50925fca860d1c2d4785bdf4a964c76c3079efa6b37c4ba2cacc534fb590c +AD: +CT: 32bb077268568d569b39e8ccdeeeb447ef424eaa2ffab565209a19b16a25952f897e5405bb0d67d8c9005d1c0b32687164d17fa4d0f412b80414c025 +TAG: 0bac7c0f8dce12917fbd4ed1738ac0cc + +KEY: 21c6aa88eb1a320d251f71a4b312ca75347040990d869a1dd2a1982c30fda2c7 +NONCE: 7dead2f1a3d9d45a9124a40efe8994300976991a4417ef4d +IN: +AD: e1bf7de4 +CT: +TAG: 341e9d0687006f981bced2f985f953e6 + +KEY: 0c97b9a65ffcd80b8f7c20c3904d0d6dd8809a7f97d7f46d39a12c198a85da5d +NONCE: 1f2c1dbc5f52fc9c8f9ca7695515d01d15904b86f703fba3 +IN: ecaf65b66d +AD: bd8a6f18 +CT: 8d1b2b0e38 +TAG: 27a7c7ac8bda627085414f0f31206a07 + +KEY: 4ab5e3595f39c4379a924e5f8ebcf3279075c08d18daff01d9ddfa40e03faf12 +NONCE: 94e6ddc294f5f1531924ec018823343ebcc220a88ea5ee33 +IN: c91b73abe5316c3effc6 +AD: c576f6ea +CT: abe960fbc64b339c53b1 +TAG: 7ebae48a2ff10117069324f04619ad6f + +KEY: a1e6146c71c2ea22300e9063455f621e15bd5bf1a3762e17f845e1aba5dd5a9c +NONCE: 82ddb6929abff8a9ad03dfb86c0bb3e7c092d45ebfa60a1b +IN: f011f32ccc2955158c117f53cf7b12 +AD: 5d14bc05 +CT: 44592321c665f51e9ffea052df1fea +TAG: d556798b97f9b647729801419424affc + +KEY: 7a1af30362c27fd55b8c24b7fca324d350decee1d1f8fae56b66253a9dd127dd +NONCE: 61201d6247992002e24e1a893180d4f0c19a3ae4cc74bf0c +IN: 5c7150b6a4daa362e62f82f676fdc4c4b558df64 +AD: 00c49210 +CT: 27d9e2730b6809c08efbd4b0d24639c7b67486f3 +TAG: 5889fdee25379960038778e36b2cedb2 + +KEY: 0b3fd9073e545ac44a7967263ead139c9547f7a54f06228fd3c8609fa2620784 +NONCE: 6450e1097d6f9ea76eb42e8e65972d501041c3a58baf8770 +IN: d679ae442b0351e5bff9906b099d45aab4f6aea5306a7a794f +AD: 318d292b +CT: a3f9ee45316d7b0f948a26145ee4fd0552bc6dc25e577e777a +TAG: 0068a401a194b8417ec0e198baa81830 + +KEY: 047c7d378fe80c02ee48df6f679a859253aed534fdcdd87023eb3d2f93fcafe3 +NONCE: ed240b0ff6f8ac585b3ea1ab2dab8080fc2f6401b010c5d0 +IN: 7288afb4e0fa5c58602090a75c10d84b5f5f1c0e03498519afe457251aa7 +AD: e4310302 +CT: 87906b14ca3e32ab01523b31ae0bb74590ce9e1df0811e743a2c7a93415a +TAG: 3a0abeab93792b1ffe768d316da74741 + +KEY: 1ad4e42acc5dfd07eb0a2456e9103cd0e150a36c667eb2f2b73c0d1ac1089ce3 +NONCE: 48efb52387284c5d38b4940c75f0c39a3f81f60bfebb48cb +IN: da7edb5b3193b4484f09efa85fcf85600968ecdc537d3829a469c866ee67b0df677866 +AD: 446be8e3 +CT: b76457ca99e95b6539b12f1d6bdac55a6d5c6469b1ff274459363ec05241f7e6e5d3ce +TAG: 06880ee508ce929da5a81f8b9de0031c + +KEY: 702a554c1b703d4dd69ad51234293ab787a01e15bdb3ce88bf89e18c01a67164 +NONCE: ea535d9c371241b9850b8b4a596b63db79eea60bd2cd9fbb +IN: a97156e9b39d05c00b811552d22088d7ee090a117a7f08adac574820d592021f16207720d49fb5fd +AD: ba5790e3 +CT: 8d0b2b04479c33287096f0c6276a73f6c037edc1a2b28f8d3b2b8e6d4c5f9dc5113309dd3ecb15e6 +TAG: 3cf303305e12924d29c223976699fb73 + +KEY: 1bb7303fefa4d8d344bb9a215901b2314324bf1f3aeb9df5d1c1532c3a55ebf1 +NONCE: a304551e5f0dc98995ddfee6215a9995023a3696debfd302 +IN: 6cf6819ce3e7ed9d4f85f4a5699701dbcaf3161adc210c0b7825ddfd83d6d7c685db62f68b3801ccc8a786066d +AD: 901c5feb +CT: bc5ef09c111f76e54f897e6fce4aee1d25b6ed934f641ed5262d0c5eed45f610a6aea3b58b7771e34256d43a16 +TAG: b83f73f7995ba1b243dbf48ddfeb8e3a + +KEY: 24b294f6cbac10d87158d1c6aca83b337d596132afac7633f69a3b3e58823f11 +NONCE: 805772ff619cc6fcc5ec0e9965435d6f74a2290c055ec754 +IN: 65e8581286868caabcec1a9814db00b805edc660b94ee3babc6ce19a3ca868bd322105484d59b4ce02ced4071bc16642a1f2 +AD: 7ae1c561 +CT: fe1d463b1466e8e411f0b0700f90760472ee5141f3e5afef43fd729f1623dca75cd4d00576765b335f8b2b77b00527599cb3 +TAG: 111d8540fd5ec04b9ba16ed810133026 + +KEY: 38e63e8b6402ac3f6d1641a1e3b74d2074be0fe41129975a3ff62b74ca52af05 +NONCE: 228d671b036710cbdaa72e9bf1d9ed6982b0bb3428a69fd6 +IN: 20a8d18878924d09aac32853c10e73dbd741134b7050ae6999839f2dbc727cb0052b5497c4bbd2a89e716278f15c81b871953614a49693 +AD: e9e6ac73 +CT: 80e0fe8eb26e5df229c6d939c944d440a37aa3cabf76eab5b9a420095513021ea4241ab367f6f44a20817b14631549ae6c96aa963970e1 +TAG: 1e80fbafcc7168e0494fce4cd76d692c + +KEY: 4325dd8406fdb8431a81f1b5db3603995256de36121019724cca2190c87a6e83 +NONCE: dcbf3077b36d5d678d668fd2d0c99284c780b55c4658ea75 +IN: 4f599ad04f79be9add10fdc649b8be53e1062ea5e9c2bed22265dc6fb30d5ab4fd4425b38ff14d8e68013405bec1eff8c9ef3069902e492aac73dcd9 +AD: 6fa0d757 +CT: 7decbdc7043495c59ecc64e720436bb0708b586a46f8745f74391477f5a2520905dfcebc3765a330999013d309dfaa997bf70bab6a0b8f4f2a2a3cdf +TAG: 051ec4ecce208d9be0cd17f434e13be3 + +KEY: 2d3d9ed4bc9eb9668733bafbb73e88be2cd17021c3a23be69b981d9f0df71df1 +NONCE: 84cae69639240c82b58895997511f145e474ebe1b008f391 +IN: +AD: 64db597c26a4c3da +CT: +TAG: 2a22c4a962d46a719014ab7b0ffaf6d3 + +KEY: 09ec4e79a02db53b19b54dd2d3592afc92c74ef57d1e0f51f3726a6631b1b73f +NONCE: 2907ced16e0777fedb1e2de30df11b3fd712af41dd714a4b +IN: b6e50cd4ea +AD: b5488e9b7f339b7b +CT: 0163e75330 +TAG: e29401c6d756adcc516580ae656852aa + +KEY: 9d5ac25a417b8a57b85332979e8a7cbad23617bb27772bbccc2acb0acae7b755 +NONCE: ff152421688dd6af7fef87817b508493a32d97a06fbda4f3 +IN: 92f4b9bc809be77e6a0d +AD: 892b793f7a6e0727 +CT: bcc594f59de8ee8c22c6 +TAG: 1a8275816c0d32a1b6cfd41fa3889558 + +KEY: eccf80c5f744d2ecc932f95ade0d9fe9327e19795023db1846d68d04720a2401 +NONCE: abc050fad8876589633b222d6a0f2e0bf709f73610aa23ee +IN: 45a380e438405314510c166bac6840 +AD: c32c9a1ce6852046 +CT: 9fa452dc9ca04c16ff7bde9925e246 +TAG: 3d5e826162fa78de3fc043af26044a08 + +KEY: b1912d6bc3cff47f0c3beccff85d7cd915b70ab88d0d3a8a59e994e1b0da8ac8 +NONCE: d8756090a42eea14ff25be890e66bfe4949fad498776ea20 +IN: e2f85df2ebcfa6045bd521abfe8af37fc88a0be1 +AD: 4576bb59b78032c8 +CT: 5eb6324aa48e0a4f72f5cb0a4917faf93af4209c +TAG: 774f8077f039588495045fee07950e14 + +KEY: 85162b111c9f3163f57c2cbc311a1e9aeed9dd6136b5784bc9c0b5052f8bffbd +NONCE: 23cdb8b546bb8a5a746b24446f0ab4199f0543d915ff51f1 +IN: dc81000077d5743beef09ac91663885d984212bbccf3dbe6f3 +AD: 3084f3e9c4d0a15f +CT: 692d17ae0b524ec6edc0cf49b69ac90c99bed44691f7ae63b7 +TAG: efe72ff84b3bccb4d83a27ddc574bc21 + +KEY: b05ca358d8ca79f51283d83e2673bfb741c379ba271a773b8dd9c6a108e758d3 +NONCE: 9a53ad79f535c6e9da011463063c896f2ec7645e6e3548fc +IN: 44e793742c774020e7349c996418042dc0dc30ee2bfd2654008c8929a436 +AD: 71ab5948c5e0f4c6 +CT: c5eddb7aeaa175b5f3dab68cf746f2acaf56fc62b29804629e25e2d63879 +TAG: bec3b7a8b8dad22ff3d14d26273294d2 + +KEY: abb5136a01354c765a96e832df58bec3b088bd19dc4d6bd6674f2f02007ebdaa +NONCE: 71267ac9f4fe5caa1d52cd85948a170a778f0141d54dbffe +IN: afb526fe41c4e2a767ce77c4145b9d054268f5f3b279237dec97f8bc46f9d158868b86 +AD: 047baa2b04748b62 +CT: 0032d4c1e65da2266539464c5d3c2b1618454a6af0e7f1e3cfc87845c75f2f4ae8b03f +TAG: b526a95a33f17ab61f2cdfc1e2dd486a + +KEY: bb826ed38008a0d7fb34c0c1a1a1149d2cad16b691d5129cc83f5eff2b3e5748 +NONCE: 4e02fe0915d81e9d5a62e5b3551b9db882e3873c0aaa230d +IN: 20270d291a8d9791b0f5e35a64387bb4237bad61169841d7e1667c994ad49869c7d5580ffa752a2d +AD: db852a275081e29b +CT: d740012efb7e1bb986ce2c535134a45f658b92163c109bdecf1ce5b836879fe9e006a56be1fac8d7 +TAG: 21e931042e7df80695262198a06286c9 + +KEY: 938d2c59f6f3e2e7316726537932372e05e8c1b5577aae0ee870bf712ff001ab +NONCE: fb4d71cf7eb2f70df9759a64c76a36b75203f88bf64f4edb +IN: 8910415d674a93c54c8f5e4aa88e59648d9a0a5039a66837d58ab14f0665a5f6d9af9b839f9033d0fe8bc58f19 +AD: a3fca278a63bf944 +CT: 1905c6987a702980b7f87f1ed2d3ae073abe1401b23434f3db43b5c37c979c2068ce9a92afedcdc218003848ea +TAG: 1bd712f64777381f68be5ccc73f364a3 + +KEY: dd0521842f498d23236692a22db0eb2f0f14fef57577e5fb194503e206b0973d +NONCE: 519e0eee8f86c75c7a364e0905a5d10d82073e11b91083a5 +IN: 61ff13acb99c5a7fd1921ec787c8de23c1a712ff002b08cecc644a78c47341eab78e7680380c93c7d53d5e56ef050d6ff192 +AD: bb5c4e5ae8f7e461 +CT: 9bfdb0fd195fa5d37da3416b3b1e8f67bd2a456eb0317c02aabf9aac9d833a19bda299e6388e7b7119be235761477a34d49e +TAG: 0f0c03b8423583cb8305a74f622fa1f9 + +KEY: 189bd84be3fb02723539b29cf76d41507c8b85b7217777ee1fb8f84a24aa7fee +NONCE: ef1bf39f22ba2edf86853505c24fafdf62c1a067963c63ba +IN: d5f96e240b5dd77b9fb2bf11c154fcbff312a791c3eb0717684e4fd84bf943e788050b47e76c427f42f3e5344b2636091603ba3b1d7a91 +AD: 93368a8e0900c7b6 +CT: c55a8b7f587bee4f97514582c5115582abffd6312914d76c2568be6836f62ba098789ed897c9a7508a5dc214bf8c218664f29941ccdfd6 +TAG: 78f87352dcb1143038c95dc6e7352cfd + +KEY: 23a2dbfcd02d265805169fa86e6927c7d49c9a24d2707884e18955e32dafc542 +NONCE: 305c7851f46f23ea8d832d5ed09d266714fd14f82ba0f69c +IN: 224de94a938d49cad46144e657e548bd86690a1b57b81558095eace59df1c552600dea389aaa609304fbc1eadf2241f2118c8bdf04522e1898efe1d4 +AD: 0075b20502bd29b2 +CT: 8e10c59369bbb0d72958100b05788498f59588795e075b8bce21d92d320206348b04010ced9b8cd3d651e825488915ce4a6e4f1af2f4d2f77b955376 +TAG: c39f0595ae8112dea6ef96df1c12458b + +KEY: 264e3c3f47bdf795cdde57d9a30be5a4da8b18463c0e3e05df28b7bf4e56410b +NONCE: 3ee09b6e205c261bf48ac53a9ba0afa460a5d5c0f2d80be8 +IN: +AD: 8eeec09d8972cb8ab0069554 +CT: +TAG: 245a034d84edab9fa6f0decb6b984766 + +KEY: d8ba98a272b5f91797b04b114311c3b92b7f2e3bb72edb7f78ed311b9f8ea2ad +NONCE: 481de9a06eee76a501e3c2b9d7423d90596193ad9d8a6564 +IN: 9ee1a3134d +AD: 928653701f6d6c8429b08c0d +CT: 459a07898f +TAG: 9188ec8d8e3bd91dcfda48fcc76773f7 + +KEY: ac9afd627a745df682bb003517056f07876eb94d2f8c610c61b6ac0d34ec4ec0 +NONCE: eaae7b8704530db1e8c3dcc968a00604a333c7c27ba51b16 +IN: f7c3f6ee2e9c03394dc8 +AD: 796620b367d5f041821baf69 +CT: d4a69005790cc91d8d34 +TAG: e4c83def113afcf83a1ea8cb204a0eae + +KEY: ea1a07c1fd60a5421f1fb6c43b4318090e290c97aa3bfa037e6fc5ee00fd47d4 +NONCE: 37327805cce92b38a669affbca1de92e068727fcf6fbb09a +IN: 7002ca765b91913ee719e7521ef5ac +AD: 64e7c48fc3041eac0734737f +CT: 9d8857a8c52a9ab3bf44b024b191b6 +TAG: d072c31714a7d0fe1596fd443a96e715 + +KEY: b3beb34fe0229fc8f49b354e941025bde6a788f25017a60e8a49591ed5d7e7da +NONCE: dd0e9fec76de1f6efb022b12164f7e9248b8e8c01d14ac02 +IN: acf360d7529a42be1f132f74745a940da9e823f2 +AD: 1489ca8d852f0a8547dbe8bc +CT: 2e8718372d6e8167213cf112dc41c80377244f5a +TAG: e4f31e8f84b9356999dc60989009e698 + +KEY: 9357cecd10bab8d2e42ed88c0386204827c3b76e9e51150d09fd4e3b4e0e1e6f +NONCE: 81f2106a5379e0ed861cf76b3cf95afb17515478b5cbcae9 +IN: ee51a0f25d091288b5e2b91ad11d491329e48b35a18a3a8685 +AD: b80cb677f4b409cd1537363b +CT: f681f19fa8de1fdea3538001a46f30fa6333b76d6439337e68 +TAG: afad5e6d282d9df6d8119c32237b3e60 + +KEY: 9f868600fbf81e40398b7dfb201fcae35d34bba10908860b0b2bf8b942b4e8fa +NONCE: 2ddcc13c97185614095d437900b8c0a9170e0a4a50e46ba5 +IN: 133fa3ac176fee6df67472752e41c6834f13300c0064ff5b190f903b7ac7 +AD: 0d61321fbee8bb1f3f5cb454 +CT: b93abb311ec0bf018dc300c7d511b42ade72780373186e231820b44f22f0 +TAG: f8bd2f649a337783ff911e37966037bd + +KEY: 05affcdfce0a28539924370db8d80a78b835254778ec41acbff52bfab092fa33 +NONCE: 3edaeb185f7273b1a7cccba54f84c5f7d6583433b49d3694 +IN: 7657581faad266cc1037962a380c8aa5306f88000427d0a05397696b503790ad2643c6 +AD: d7c213e9e6f4a40f3e5b662c +CT: 5eb19080aadc89f2329da4f5c41dc60568651c424c1b05d827f2bfb8dbff42c5a08224 +TAG: 2da20087b5674f0b967d1baa664bbd82 + +KEY: 645ed60ec74ddfe1f02694792db4436c262d20405d8645cd9755d64876219799 +NONCE: d83665b44c1fdf567299f2b8501e9c0e7ae2dda0bb8f2c82 +IN: ceee69d32ad4667a00909964d9611bf34fd98be41ad7f0feaaaff8169060d64cf310c13bcb9394cf +AD: 57379f8f44191ec9cf3b1a07 +CT: 4496a0666f0f895ebce224b448a04502f2ae7b354d868b7c54295bf051162e82c530c767d1ffd2cc +TAG: 1ffc56da4fb961ffdfabe66d82ec8f29 + +KEY: 06624c9a75bb7dbe224a3f23791281f53c40b407a14161a3f82f34924623dc02 +NONCE: e647b8b4739bf542a81d72d695e1cd6ba348fa593987ac47 +IN: 2658763f8d70e8c3303582d66ba3d736ce9d407e9507f6c6627e382d0144da157d73d0aee10ef034083cdd9013 +AD: 75536443a6c2189a57d553bb +CT: 305cab5c2f9a6edccac307d6965febe3c86f2a1e31ac8c74e88924a10c2a29106bce980c803b7886985bba8ec5 +TAG: 8c12bb58c84175b9f601b704d0f8a25c + +KEY: 63aeb46083100bbcc430f4f09bcc34410df9cfd5883d629e4af8645ffabb89c2 +NONCE: b09830874dc549195a5d6da93b9dcc12aa1ec8af201c96bd +IN: 1b3c9050e0a062f5a5cff7bec8706864cf8648142ec5cb1f9867ace384e9b2bba33aab8dc83e83b2d2fac70cd5189f2b5ab5 +AD: 7dcc05b0940198bd5c68cdf1 +CT: d8b22e5d381de08a50b163c00dbbca6c07d61c80199cebd52234c7bd4f7ed0a90d47ef05617cdb8e3f782875ae629c0f0ad6 +TAG: 194077f0e6d415bf7307d171e8484a9c + +KEY: 4826c1bf8b48088fece4008922173c500ff45790f945b1027f36110da4fecc92 +NONCE: 3a78fc7397944d762303b0a75974ac92a60e250bf112600a +IN: d26e3a2b92120ff8056bb992660cc8a2364792589c16a518b8d232b8184aed05ba8d4fd0b2ad2b928cd873e11905a21ffece5f1e63c974 +AD: 904d2cd3e50f7bfb9352f142 +CT: 21f4cf679662fad36f57945fc0c0753c3791261eb58d643278dfe1f14bfb585c5a01370ba96f18dc3f6b6945a2c6997330b24f12f5219a +TAG: 95397c54428f9d069c511b5c82e0151c + +KEY: ec526c03d8a08e8a63751112428a76399c399e8b83d98c9247c73164805ac8fe +NONCE: 2cc1a6ae89c2a091415fa2964b44a0e5da629d40d77b77f1 +IN: 567377f5b6df5442e70bc9a31bc450bd4febfcf89d7ca611353c7e612d8b7e36e859f6365ec7e5e99e9e0e882532666dd7203d06f6e25439ed871237 +AD: 35575b56716868b66cd21e24 +CT: 6b738274fe974438f1f5fca8ef1ee7df664f1e72bc54ccd3fb58c4a3df67ef9a73261df41ffe9c52aeafc8be4f6524baf9efb1558d4a57defec7bee3 +TAG: 92599d4b14a795e8c375ec2a8960b4dc + diff --git a/Libraries/libressl/tls/CMakeLists.txt b/Libraries/libressl/tls/CMakeLists.txt new file mode 100644 index 000000000..4beef36ea --- /dev/null +++ b/Libraries/libressl/tls/CMakeLists.txt @@ -0,0 +1,108 @@ +set( + TLS_SRC + tls.c + tls_bio_cb.c + tls_client.c + tls_config.c + tls_conninfo.c + tls_keypair.c + tls_server.c + tls_signer.c + tls_ocsp.c + tls_peer.c + tls_util.c + tls_verify.c +) + +if(WIN32) + set( + TLS_SRC + ${TLS_SRC} + compat/ftruncate.c + compat/pread.c + compat/pwrite.c + ) + + set(LIBTLS_EXTRA_EXPORT ${LIBTLS_EXTRA_EXPORT} ftruncate) +endif() + +if(NOT "${OPENSSLDIR}" STREQUAL "") + add_definitions(-DTLS_DEFAULT_CA_FILE=\"${OPENSSLDIR}/cert.pem\") +else() + add_definitions(-DTLS_DEFAULT_CA_FILE=\"${CMAKE_INSTALL_PREFIX}/etc/ssl/cert.pem\") +endif() + +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/tls.sym DESTINATION + ${CMAKE_CURRENT_BINARY_DIR}) +if(LIBTLS_EXTRA_EXPORT) + list(SORT LIBTLS_EXTRA_EXPORT) + foreach(SYM IN LISTS LIBTLS_EXTRA_EXPORT) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/tls.sym "${SYM}\n") + endforeach() +endif() + +add_library(tls_obj OBJECT ${TLS_SRC}) +target_include_directories(tls_obj + PRIVATE + . + ../include/compat + PUBLIC + ../include + ${CMAKE_BINARY_DIR}/include) + +add_library(tls $ $ + $ empty.c) + +export_symbol(tls ${CMAKE_CURRENT_BINARY_DIR}/tls.sym) +target_link_libraries(tls ${PLATFORM_LIBS}) +if (WIN32) + set(TLS_POSTFIX -${TLS_MAJOR_VERSION} PARENT_SCOPE) +endif() +set_target_properties(tls PROPERTIES + OUTPUT_NAME tls${TLS_POSTFIX} + ARCHIVE_OUTPUT_NAME tls${TLS_POSTFIX} + EXPORT_NAME TLS + VERSION ${TLS_VERSION} + SOVERSION ${TLS_MAJOR_VERSION} +) + +target_include_directories( + tls + PUBLIC + $ + $ +) + +install( + TARGETS tls + EXPORT TLS-target +) + +export( + EXPORT TLS-target + FILE "${LibreSSL_BINARY_DIR}/LibreSSL-TLS.cmake" + NAMESPACE LibreSSL:: +) + +if(ENABLE_LIBRESSL_INSTALL) + install( + TARGETS tls + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + install( + EXPORT TLS-target + FILE "LibreSSL-TLS.cmake" + NAMESPACE LibreSSL:: + DESTINATION "${LIBRESSL_INSTALL_CMAKEDIR}" + ) +endif(ENABLE_LIBRESSL_INSTALL) + +# build static library for regression test +if(BUILD_SHARED_LIBS) + add_library(tls-static STATIC $ + $ $) + target_link_libraries(tls-static ${PLATFORM_LIBS}) +endif() + diff --git a/Libraries/libressl/tls/Makefile.am b/Libraries/libressl/tls/Makefile.am new file mode 100644 index 000000000..22f3222a7 --- /dev/null +++ b/Libraries/libressl/tls/Makefile.am @@ -0,0 +1,61 @@ +include $(top_srcdir)/Makefile.am.common + +-include $(abs_top_builddir)/crypto/libcrypto_la_objects.mk +-include $(abs_top_builddir)/ssl/libssl_la_objects.mk + +lib_LTLIBRARIES = libtls.la + +EXTRA_DIST = VERSION +EXTRA_DIST += CMakeLists.txt +EXTRA_DIST += tls.sym +EXTRA_DIST += empty.c + +CLEANFILES = libtls_la_objects.mk + +EXTRA_libtls_la_DEPENDENCIES = libtls_la_objects.mk + +libtls_la_objects.mk: Makefile + @echo "libtls_la_objects= $(libtls_la_OBJECTS)" \ + | sed -e 's/ *$$//' -e 's/ */ $$\(abs_top_builddir\)\/tls\//g' \ + > libtls_la_objects.mk + +libtls_la_LDFLAGS = -version-info @LIBTLS_VERSION@ -no-undefined -export-symbols $(top_srcdir)/tls/tls.sym + +if ENABLE_LIBTLS_ONLY +libtls_la_LIBADD = $(libcrypto_la_objects) +libtls_la_LIBADD += $(libssl_la_objects) +else +libtls_la_LIBADD = $(abs_top_builddir)/crypto/libcrypto.la +libtls_la_LIBADD += $(abs_top_builddir)/ssl/libssl.la +endif + +libtls_la_LIBADD += $(libcompat_la_objects) +libtls_la_LIBADD += $(libcompatnoopt_la_objects) +libtls_la_LIBADD += $(PLATFORM_LDADD) + +libtls_la_CPPFLAGS = $(AM_CPPFLAGS) +if OPENSSLDIR_DEFINED +libtls_la_CPPFLAGS += -DTLS_DEFAULT_CA_FILE=\"@OPENSSLDIR@/cert.pem\" +else +libtls_la_CPPFLAGS += -DTLS_DEFAULT_CA_FILE=\"$(sysconfdir)/ssl/cert.pem\" +endif + +libtls_la_SOURCES = tls.c +libtls_la_SOURCES += tls_client.c +libtls_la_SOURCES += tls_bio_cb.c +libtls_la_SOURCES += tls_config.c +libtls_la_SOURCES += tls_conninfo.c +libtls_la_SOURCES += tls_keypair.c +libtls_la_SOURCES += tls_server.c +libtls_la_SOURCES += tls_signer.c +libtls_la_SOURCES += tls_ocsp.c +libtls_la_SOURCES += tls_peer.c +libtls_la_SOURCES += tls_util.c +libtls_la_SOURCES += tls_verify.c +noinst_HEADERS = tls_internal.h + +if HOST_WIN +libtls_la_SOURCES += compat/ftruncate.c +libtls_la_SOURCES += compat/pread.c +libtls_la_SOURCES += compat/pwrite.c +endif diff --git a/Libraries/libressl/tls/Makefile.in b/Libraries/libressl/tls/Makefile.in new file mode 100644 index 000000000..8f049e4fa --- /dev/null +++ b/Libraries/libressl/tls/Makefile.in @@ -0,0 +1,901 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@OPENSSLDIR_DEFINED_TRUE@am__append_1 = -DTLS_DEFAULT_CA_FILE=\"@OPENSSLDIR@/cert.pem\" +@OPENSSLDIR_DEFINED_FALSE@am__append_2 = -DTLS_DEFAULT_CA_FILE=\"$(sysconfdir)/ssl/cert.pem\" +@HOST_WIN_TRUE@am__append_3 = compat/ftruncate.c compat/pread.c \ +@HOST_WIN_TRUE@ compat/pwrite.c +subdir = tls +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_add_fortify_source.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/check-hardening-options.m4 \ + $(top_srcdir)/m4/check-libc.m4 \ + $(top_srcdir)/m4/check-os-options.m4 \ + $(top_srcdir)/m4/disable-compiler-warnings.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +@ENABLE_LIBTLS_ONLY_FALSE@libtls_la_DEPENDENCIES = $(abs_top_builddir)/crypto/libcrypto.la \ +@ENABLE_LIBTLS_ONLY_FALSE@ $(abs_top_builddir)/ssl/libssl.la \ +@ENABLE_LIBTLS_ONLY_FALSE@ $(am__DEPENDENCIES_1) +@ENABLE_LIBTLS_ONLY_TRUE@libtls_la_DEPENDENCIES = \ +@ENABLE_LIBTLS_ONLY_TRUE@ $(am__DEPENDENCIES_1) +am__libtls_la_SOURCES_DIST = tls.c tls_client.c tls_bio_cb.c \ + tls_config.c tls_conninfo.c tls_keypair.c tls_server.c \ + tls_signer.c tls_ocsp.c tls_peer.c tls_util.c tls_verify.c \ + compat/ftruncate.c compat/pread.c compat/pwrite.c +am__dirstamp = $(am__leading_dot)dirstamp +@HOST_WIN_TRUE@am__objects_1 = compat/libtls_la-ftruncate.lo \ +@HOST_WIN_TRUE@ compat/libtls_la-pread.lo \ +@HOST_WIN_TRUE@ compat/libtls_la-pwrite.lo +am_libtls_la_OBJECTS = libtls_la-tls.lo libtls_la-tls_client.lo \ + libtls_la-tls_bio_cb.lo libtls_la-tls_config.lo \ + libtls_la-tls_conninfo.lo libtls_la-tls_keypair.lo \ + libtls_la-tls_server.lo libtls_la-tls_signer.lo \ + libtls_la-tls_ocsp.lo libtls_la-tls_peer.lo \ + libtls_la-tls_util.lo libtls_la-tls_verify.lo $(am__objects_1) +libtls_la_OBJECTS = $(am_libtls_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libtls_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libtls_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libtls_la-tls.Plo \ + ./$(DEPDIR)/libtls_la-tls_bio_cb.Plo \ + ./$(DEPDIR)/libtls_la-tls_client.Plo \ + ./$(DEPDIR)/libtls_la-tls_config.Plo \ + ./$(DEPDIR)/libtls_la-tls_conninfo.Plo \ + ./$(DEPDIR)/libtls_la-tls_keypair.Plo \ + ./$(DEPDIR)/libtls_la-tls_ocsp.Plo \ + ./$(DEPDIR)/libtls_la-tls_peer.Plo \ + ./$(DEPDIR)/libtls_la-tls_server.Plo \ + ./$(DEPDIR)/libtls_la-tls_signer.Plo \ + ./$(DEPDIR)/libtls_la-tls_util.Plo \ + ./$(DEPDIR)/libtls_la-tls_verify.Plo \ + compat/$(DEPDIR)/libtls_la-ftruncate.Plo \ + compat/$(DEPDIR)/libtls_la-pread.Plo \ + compat/$(DEPDIR)/libtls_la-pwrite.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtls_la_SOURCES) +DIST_SOURCES = $(am__libtls_la_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.common $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTO_VERSION = @LIBCRYPTO_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSL_VERSION = @LIBSSL_VERSION@ +LIBTLS_VERSION = @LIBTLS_VERSION@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSLDIR = @OPENSSLDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_LDADD = @PLATFORM_LDADD@ +PROG_LDADD = @PROG_LDADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(abs_top_builddir)/include \ + -I$(top_srcdir)/include/compat -DLIBRESSL_INTERNAL \ + -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= +lib_LTLIBRARIES = libtls.la +EXTRA_DIST = VERSION CMakeLists.txt tls.sym empty.c +CLEANFILES = libtls_la_objects.mk +EXTRA_libtls_la_DEPENDENCIES = libtls_la_objects.mk +libtls_la_LDFLAGS = -version-info @LIBTLS_VERSION@ -no-undefined -export-symbols $(top_srcdir)/tls/tls.sym +@ENABLE_LIBTLS_ONLY_FALSE@libtls_la_LIBADD = $(abs_top_builddir)/crypto/libcrypto.la \ +@ENABLE_LIBTLS_ONLY_FALSE@ $(abs_top_builddir)/ssl/libssl.la \ +@ENABLE_LIBTLS_ONLY_FALSE@ $(libcompat_la_objects) \ +@ENABLE_LIBTLS_ONLY_FALSE@ $(libcompatnoopt_la_objects) \ +@ENABLE_LIBTLS_ONLY_FALSE@ $(PLATFORM_LDADD) +@ENABLE_LIBTLS_ONLY_TRUE@libtls_la_LIBADD = $(libcrypto_la_objects) \ +@ENABLE_LIBTLS_ONLY_TRUE@ $(libssl_la_objects) \ +@ENABLE_LIBTLS_ONLY_TRUE@ $(libcompat_la_objects) \ +@ENABLE_LIBTLS_ONLY_TRUE@ $(libcompatnoopt_la_objects) \ +@ENABLE_LIBTLS_ONLY_TRUE@ $(PLATFORM_LDADD) +libtls_la_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_1) $(am__append_2) +libtls_la_SOURCES = tls.c tls_client.c tls_bio_cb.c tls_config.c \ + tls_conninfo.c tls_keypair.c tls_server.c tls_signer.c \ + tls_ocsp.c tls_peer.c tls_util.c tls_verify.c $(am__append_3) +noinst_HEADERS = tls_internal.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tls/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tls/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.am.common $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +compat/$(am__dirstamp): + @$(MKDIR_P) compat + @: > compat/$(am__dirstamp) +compat/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) compat/$(DEPDIR) + @: > compat/$(DEPDIR)/$(am__dirstamp) +compat/libtls_la-ftruncate.lo: compat/$(am__dirstamp) \ + compat/$(DEPDIR)/$(am__dirstamp) +compat/libtls_la-pread.lo: compat/$(am__dirstamp) \ + compat/$(DEPDIR)/$(am__dirstamp) +compat/libtls_la-pwrite.lo: compat/$(am__dirstamp) \ + compat/$(DEPDIR)/$(am__dirstamp) + +libtls.la: $(libtls_la_OBJECTS) $(libtls_la_DEPENDENCIES) $(EXTRA_libtls_la_DEPENDENCIES) + $(AM_V_CCLD)$(libtls_la_LINK) -rpath $(libdir) $(libtls_la_OBJECTS) $(libtls_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f compat/*.$(OBJEXT) + -rm -f compat/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_bio_cb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_client.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_conninfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_keypair.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_ocsp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_peer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_server.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_signer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtls_la-tls_verify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@compat/$(DEPDIR)/libtls_la-ftruncate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@compat/$(DEPDIR)/libtls_la-pread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@compat/$(DEPDIR)/libtls_la-pwrite.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libtls_la-tls.lo: tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls.Tpo -c -o libtls_la-tls.lo `test -f 'tls.c' || echo '$(srcdir)/'`tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls.Tpo $(DEPDIR)/libtls_la-tls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='libtls_la-tls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls.lo `test -f 'tls.c' || echo '$(srcdir)/'`tls.c + +libtls_la-tls_client.lo: tls_client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_client.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_client.Tpo -c -o libtls_la-tls_client.lo `test -f 'tls_client.c' || echo '$(srcdir)/'`tls_client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_client.Tpo $(DEPDIR)/libtls_la-tls_client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_client.c' object='libtls_la-tls_client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_client.lo `test -f 'tls_client.c' || echo '$(srcdir)/'`tls_client.c + +libtls_la-tls_bio_cb.lo: tls_bio_cb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_bio_cb.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_bio_cb.Tpo -c -o libtls_la-tls_bio_cb.lo `test -f 'tls_bio_cb.c' || echo '$(srcdir)/'`tls_bio_cb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_bio_cb.Tpo $(DEPDIR)/libtls_la-tls_bio_cb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_bio_cb.c' object='libtls_la-tls_bio_cb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_bio_cb.lo `test -f 'tls_bio_cb.c' || echo '$(srcdir)/'`tls_bio_cb.c + +libtls_la-tls_config.lo: tls_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_config.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_config.Tpo -c -o libtls_la-tls_config.lo `test -f 'tls_config.c' || echo '$(srcdir)/'`tls_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_config.Tpo $(DEPDIR)/libtls_la-tls_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_config.c' object='libtls_la-tls_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_config.lo `test -f 'tls_config.c' || echo '$(srcdir)/'`tls_config.c + +libtls_la-tls_conninfo.lo: tls_conninfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_conninfo.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_conninfo.Tpo -c -o libtls_la-tls_conninfo.lo `test -f 'tls_conninfo.c' || echo '$(srcdir)/'`tls_conninfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_conninfo.Tpo $(DEPDIR)/libtls_la-tls_conninfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_conninfo.c' object='libtls_la-tls_conninfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_conninfo.lo `test -f 'tls_conninfo.c' || echo '$(srcdir)/'`tls_conninfo.c + +libtls_la-tls_keypair.lo: tls_keypair.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_keypair.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_keypair.Tpo -c -o libtls_la-tls_keypair.lo `test -f 'tls_keypair.c' || echo '$(srcdir)/'`tls_keypair.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_keypair.Tpo $(DEPDIR)/libtls_la-tls_keypair.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_keypair.c' object='libtls_la-tls_keypair.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_keypair.lo `test -f 'tls_keypair.c' || echo '$(srcdir)/'`tls_keypair.c + +libtls_la-tls_server.lo: tls_server.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_server.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_server.Tpo -c -o libtls_la-tls_server.lo `test -f 'tls_server.c' || echo '$(srcdir)/'`tls_server.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_server.Tpo $(DEPDIR)/libtls_la-tls_server.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_server.c' object='libtls_la-tls_server.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_server.lo `test -f 'tls_server.c' || echo '$(srcdir)/'`tls_server.c + +libtls_la-tls_signer.lo: tls_signer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_signer.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_signer.Tpo -c -o libtls_la-tls_signer.lo `test -f 'tls_signer.c' || echo '$(srcdir)/'`tls_signer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_signer.Tpo $(DEPDIR)/libtls_la-tls_signer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_signer.c' object='libtls_la-tls_signer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_signer.lo `test -f 'tls_signer.c' || echo '$(srcdir)/'`tls_signer.c + +libtls_la-tls_ocsp.lo: tls_ocsp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_ocsp.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_ocsp.Tpo -c -o libtls_la-tls_ocsp.lo `test -f 'tls_ocsp.c' || echo '$(srcdir)/'`tls_ocsp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_ocsp.Tpo $(DEPDIR)/libtls_la-tls_ocsp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_ocsp.c' object='libtls_la-tls_ocsp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_ocsp.lo `test -f 'tls_ocsp.c' || echo '$(srcdir)/'`tls_ocsp.c + +libtls_la-tls_peer.lo: tls_peer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_peer.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_peer.Tpo -c -o libtls_la-tls_peer.lo `test -f 'tls_peer.c' || echo '$(srcdir)/'`tls_peer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_peer.Tpo $(DEPDIR)/libtls_la-tls_peer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_peer.c' object='libtls_la-tls_peer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_peer.lo `test -f 'tls_peer.c' || echo '$(srcdir)/'`tls_peer.c + +libtls_la-tls_util.lo: tls_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_util.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_util.Tpo -c -o libtls_la-tls_util.lo `test -f 'tls_util.c' || echo '$(srcdir)/'`tls_util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_util.Tpo $(DEPDIR)/libtls_la-tls_util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_util.c' object='libtls_la-tls_util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_util.lo `test -f 'tls_util.c' || echo '$(srcdir)/'`tls_util.c + +libtls_la-tls_verify.lo: tls_verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtls_la-tls_verify.lo -MD -MP -MF $(DEPDIR)/libtls_la-tls_verify.Tpo -c -o libtls_la-tls_verify.lo `test -f 'tls_verify.c' || echo '$(srcdir)/'`tls_verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtls_la-tls_verify.Tpo $(DEPDIR)/libtls_la-tls_verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_verify.c' object='libtls_la-tls_verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtls_la-tls_verify.lo `test -f 'tls_verify.c' || echo '$(srcdir)/'`tls_verify.c + +compat/libtls_la-ftruncate.lo: compat/ftruncate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat/libtls_la-ftruncate.lo -MD -MP -MF compat/$(DEPDIR)/libtls_la-ftruncate.Tpo -c -o compat/libtls_la-ftruncate.lo `test -f 'compat/ftruncate.c' || echo '$(srcdir)/'`compat/ftruncate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) compat/$(DEPDIR)/libtls_la-ftruncate.Tpo compat/$(DEPDIR)/libtls_la-ftruncate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat/ftruncate.c' object='compat/libtls_la-ftruncate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat/libtls_la-ftruncate.lo `test -f 'compat/ftruncate.c' || echo '$(srcdir)/'`compat/ftruncate.c + +compat/libtls_la-pread.lo: compat/pread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat/libtls_la-pread.lo -MD -MP -MF compat/$(DEPDIR)/libtls_la-pread.Tpo -c -o compat/libtls_la-pread.lo `test -f 'compat/pread.c' || echo '$(srcdir)/'`compat/pread.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) compat/$(DEPDIR)/libtls_la-pread.Tpo compat/$(DEPDIR)/libtls_la-pread.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat/pread.c' object='compat/libtls_la-pread.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat/libtls_la-pread.lo `test -f 'compat/pread.c' || echo '$(srcdir)/'`compat/pread.c + +compat/libtls_la-pwrite.lo: compat/pwrite.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat/libtls_la-pwrite.lo -MD -MP -MF compat/$(DEPDIR)/libtls_la-pwrite.Tpo -c -o compat/libtls_la-pwrite.lo `test -f 'compat/pwrite.c' || echo '$(srcdir)/'`compat/pwrite.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) compat/$(DEPDIR)/libtls_la-pwrite.Tpo compat/$(DEPDIR)/libtls_la-pwrite.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat/pwrite.c' object='compat/libtls_la-pwrite.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat/libtls_la-pwrite.lo `test -f 'compat/pwrite.c' || echo '$(srcdir)/'`compat/pwrite.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf compat/.libs compat/_libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f compat/$(DEPDIR)/$(am__dirstamp) + -rm -f compat/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libtls_la-tls.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_bio_cb.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_client.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_config.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_conninfo.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_keypair.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_ocsp.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_peer.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_server.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_signer.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_util.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_verify.Plo + -rm -f compat/$(DEPDIR)/libtls_la-ftruncate.Plo + -rm -f compat/$(DEPDIR)/libtls_la-pread.Plo + -rm -f compat/$(DEPDIR)/libtls_la-pwrite.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libtls_la-tls.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_bio_cb.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_client.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_config.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_conninfo.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_keypair.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_ocsp.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_peer.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_server.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_signer.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_util.Plo + -rm -f ./$(DEPDIR)/libtls_la-tls_verify.Plo + -rm -f compat/$(DEPDIR)/libtls_la-ftruncate.Plo + -rm -f compat/$(DEPDIR)/libtls_la-pread.Plo + -rm -f compat/$(DEPDIR)/libtls_la-pwrite.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +-include $(abs_top_builddir)/crypto/libcrypto_la_objects.mk +-include $(abs_top_builddir)/ssl/libssl_la_objects.mk + +libtls_la_objects.mk: Makefile + @echo "libtls_la_objects= $(libtls_la_OBJECTS)" \ + | sed -e 's/ *$$//' -e 's/ */ $$\(abs_top_builddir\)\/tls\//g' \ + > libtls_la_objects.mk + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Libraries/libressl/tls/VERSION b/Libraries/libressl/tls/VERSION new file mode 100644 index 000000000..fd02cce9d --- /dev/null +++ b/Libraries/libressl/tls/VERSION @@ -0,0 +1 @@ +28:0:0 diff --git a/Libraries/libressl/tls/compat/ftruncate.c b/Libraries/libressl/tls/compat/ftruncate.c new file mode 100644 index 000000000..e825e5045 --- /dev/null +++ b/Libraries/libressl/tls/compat/ftruncate.c @@ -0,0 +1,17 @@ +/* + * Public domain + * + * Kinichiro Inoguchi + */ + +#ifdef _WIN32 + +#include + +int +ftruncate(int fd, off_t length) +{ + return _chsize(fd, length); +} + +#endif diff --git a/Libraries/libressl/tls/compat/pread.c b/Libraries/libressl/tls/compat/pread.c new file mode 100644 index 000000000..b9d6b097a --- /dev/null +++ b/Libraries/libressl/tls/compat/pread.c @@ -0,0 +1,29 @@ +/* + * Public domain + * + * Kinichiro Inoguchi + */ + +#ifdef _WIN32 + +#define NO_REDEF_POSIX_FUNCTIONS + +#include + +ssize_t +pread(int d, void *buf, size_t nbytes, off_t offset) +{ + off_t cpos, opos, rpos; + ssize_t bytes; + if((cpos = lseek(d, 0, SEEK_CUR)) == -1) + return -1; + if((opos = lseek(d, offset, SEEK_SET)) == -1) + return -1; + if((bytes = read(d, buf, nbytes)) == -1) + return -1; + if((rpos = lseek(d, cpos, SEEK_SET)) == -1) + return -1; + return bytes; +} + +#endif diff --git a/Libraries/libressl/tls/compat/pwrite.c b/Libraries/libressl/tls/compat/pwrite.c new file mode 100644 index 000000000..82f5f555b --- /dev/null +++ b/Libraries/libressl/tls/compat/pwrite.c @@ -0,0 +1,29 @@ +/* + * Public domain + * + * Kinichiro Inoguchi + */ + +#ifdef _WIN32 + +#define NO_REDEF_POSIX_FUNCTIONS + +#include + +ssize_t +pwrite(int d, const void *buf, size_t nbytes, off_t offset) +{ + off_t cpos, opos, rpos; + ssize_t bytes; + if((cpos = lseek(d, 0, SEEK_CUR)) == -1) + return -1; + if((opos = lseek(d, offset, SEEK_SET)) == -1) + return -1; + if((bytes = write(d, buf, nbytes)) == -1) + return -1; + if((rpos = lseek(d, cpos, SEEK_SET)) == -1) + return -1; + return bytes; +} + +#endif diff --git a/Libraries/libressl/tls/empty.c b/Libraries/libressl/tls/empty.c new file mode 100644 index 000000000..e69de29bb diff --git a/Libraries/libressl/tls/tls.c b/Libraries/libressl/tls/tls.c new file mode 100644 index 000000000..fdb994d73 --- /dev/null +++ b/Libraries/libressl/tls/tls.c @@ -0,0 +1,931 @@ +/* $OpenBSD: tls.c,v 1.98 2023/07/02 06:37:27 beck Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "tls_internal.h" + +static struct tls_config *tls_config_default; + +static int tls_init_rv = -1; + +static void +tls_do_init(void) +{ + OPENSSL_init_ssl(OPENSSL_INIT_NO_LOAD_CONFIG, NULL); + + if (BIO_sock_init() != 1) + return; + + if ((tls_config_default = tls_config_new_internal()) == NULL) + return; + + tls_config_default->refcount++; + + tls_init_rv = 0; +} + +int +tls_init(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + if (pthread_once(&once, tls_do_init) != 0) + return -1; + + return tls_init_rv; +} + +const char * +tls_error(struct tls *ctx) +{ + return ctx->error.msg; +} + +void +tls_error_clear(struct tls_error *error) +{ + free(error->msg); + error->msg = NULL; + error->num = 0; + error->tls = 0; +} + +static int +tls_error_vset(struct tls_error *error, int errnum, const char *fmt, va_list ap) +{ + char *errmsg = NULL; + int rv = -1; + + tls_error_clear(error); + + error->num = errnum; + error->tls = 1; + + if (vasprintf(&errmsg, fmt, ap) == -1) { + errmsg = NULL; + goto err; + } + + if (errnum == -1) { + error->msg = errmsg; + return (0); + } + + if (asprintf(&error->msg, "%s: %s", errmsg, strerror(errnum)) == -1) { + error->msg = NULL; + goto err; + } + rv = 0; + + err: + free(errmsg); + + return (rv); +} + +int +tls_error_set(struct tls_error *error, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls_error_vset(error, errnum, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_error_setx(struct tls_error *error, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls_error_vset(error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_config_set_error(struct tls_config *config, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls_error_vset(&config->error, errnum, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_config_set_errorx(struct tls_config *config, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls_error_vset(&config->error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_set_error(struct tls *ctx, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls_error_vset(&ctx->error, errnum, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_set_errorx(struct tls *ctx, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls_error_vset(&ctx->error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...) +{ + va_list ap; + int rv; + + /* Only set an error if a more specific one does not already exist. */ + if (ctx->error.tls != 0) + return (0); + + va_start(ap, fmt); + rv = tls_error_vset(&ctx->error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +struct tls_sni_ctx * +tls_sni_ctx_new(void) +{ + return (calloc(1, sizeof(struct tls_sni_ctx))); +} + +void +tls_sni_ctx_free(struct tls_sni_ctx *sni_ctx) +{ + if (sni_ctx == NULL) + return; + + SSL_CTX_free(sni_ctx->ssl_ctx); + X509_free(sni_ctx->ssl_cert); + + free(sni_ctx); +} + +struct tls * +tls_new(void) +{ + struct tls *ctx; + + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) + return (NULL); + + tls_reset(ctx); + + if (tls_configure(ctx, tls_config_default) == -1) { + free(ctx); + return NULL; + } + + return (ctx); +} + +int +tls_configure(struct tls *ctx, struct tls_config *config) +{ + if (config == NULL) + config = tls_config_default; + + pthread_mutex_lock(&config->mutex); + config->refcount++; + pthread_mutex_unlock(&config->mutex); + + tls_config_free(ctx->config); + + ctx->config = config; + ctx->keypair = config->keypair; + + if ((ctx->flags & TLS_SERVER) != 0) + return (tls_configure_server(ctx)); + + return (0); +} + +int +tls_cert_hash(X509 *cert, char **hash) +{ + char d[EVP_MAX_MD_SIZE], *dhex = NULL; + int dlen, rv = -1; + + free(*hash); + *hash = NULL; + + if (X509_digest(cert, EVP_sha256(), d, &dlen) != 1) + goto err; + + if (tls_hex_string(d, dlen, &dhex, NULL) != 0) + goto err; + + if (asprintf(hash, "SHA256:%s", dhex) == -1) { + *hash = NULL; + goto err; + } + + rv = 0; + err: + free(dhex); + + return (rv); +} + +int +tls_cert_pubkey_hash(X509 *cert, char **hash) +{ + char d[EVP_MAX_MD_SIZE], *dhex = NULL; + int dlen, rv = -1; + + free(*hash); + *hash = NULL; + + if (X509_pubkey_digest(cert, EVP_sha256(), d, &dlen) != 1) + goto err; + + if (tls_hex_string(d, dlen, &dhex, NULL) != 0) + goto err; + + if (asprintf(hash, "SHA256:%s", dhex) == -1) { + *hash = NULL; + goto err; + } + + rv = 0; + + err: + free(dhex); + + return (rv); +} + +static int +tls_keypair_to_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY **pkey) +{ + BIO *bio = NULL; + X509 *x509 = NULL; + char *mem; + size_t len; + int ret = -1; + + *pkey = NULL; + + if (ctx->config->use_fake_private_key) { + mem = keypair->cert_mem; + len = keypair->cert_len; + } else { + mem = keypair->key_mem; + len = keypair->key_len; + } + + if (mem == NULL) + return (0); + + if (len > INT_MAX) { + tls_set_errorx(ctx, ctx->config->use_fake_private_key ? + "cert too long" : "key too long"); + goto err; + } + + if ((bio = BIO_new_mem_buf(mem, len)) == NULL) { + tls_set_errorx(ctx, "failed to create buffer"); + goto err; + } + + if (ctx->config->use_fake_private_key) { + if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb, + NULL)) == NULL) { + tls_set_errorx(ctx, "failed to read X509 certificate"); + goto err; + } + if ((*pkey = X509_get_pubkey(x509)) == NULL) { + tls_set_errorx(ctx, "failed to retrieve pubkey"); + goto err; + } + } else { + if ((*pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb, + NULL)) == NULL) { + tls_set_errorx(ctx, "failed to read private key"); + goto err; + } + } + + ret = 0; + err: + BIO_free(bio); + X509_free(x509); + return (ret); +} + +static int +tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *pkey) +{ + RSA_METHOD *rsa_method; + EC_KEY_METHOD *ecdsa_method; + RSA *rsa = NULL; + EC_KEY *eckey = NULL; + int ret = -1; + + /* Only install the pubkey hash if fake private keys are used. */ + if (!ctx->config->skip_private_key_check) + return (0); + + if (keypair->pubkey_hash == NULL) { + tls_set_errorx(ctx, "public key hash not set"); + goto err; + } + + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_RSA: + if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL || + RSA_set_ex_data(rsa, 0, keypair->pubkey_hash) == 0) { + tls_set_errorx(ctx, "RSA key setup failure"); + goto err; + } + if (ctx->config->sign_cb != NULL) { + rsa_method = tls_signer_rsa_method(); + if (rsa_method == NULL || + RSA_set_ex_data(rsa, 1, ctx->config) == 0 || + RSA_set_method(rsa, rsa_method) == 0) { + tls_set_errorx(ctx, "failed to setup RSA key"); + goto err; + } + } + /* Reset the key to work around caching in OpenSSL 3. */ + if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) { + tls_set_errorx(ctx, "failed to set RSA key"); + goto err; + } + break; + case EVP_PKEY_EC: + if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL || + EC_KEY_set_ex_data(eckey, 0, keypair->pubkey_hash) == 0) { + tls_set_errorx(ctx, "EC key setup failure"); + goto err; + } + if (ctx->config->sign_cb != NULL) { + ecdsa_method = tls_signer_ecdsa_method(); + if (ecdsa_method == NULL || + EC_KEY_set_ex_data(eckey, 1, ctx->config) == 0 || + EC_KEY_set_method(eckey, ecdsa_method) == 0) { + tls_set_errorx(ctx, "failed to setup EC key"); + goto err; + } + } + /* Reset the key to work around caching in OpenSSL 3. */ + if (EVP_PKEY_set1_EC_KEY(pkey, eckey) == 0) { + tls_set_errorx(ctx, "failed to set EC key"); + goto err; + } + break; + default: + tls_set_errorx(ctx, "incorrect key type"); + goto err; + } + + ret = 0; + + err: + RSA_free(rsa); + EC_KEY_free(eckey); + return (ret); +} + +int +tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, + struct tls_keypair *keypair, int required) +{ + EVP_PKEY *pkey = NULL; + + if (!required && + keypair->cert_mem == NULL && + keypair->key_mem == NULL) + return(0); + + if (keypair->cert_mem != NULL) { + if (keypair->cert_len > INT_MAX) { + tls_set_errorx(ctx, "certificate too long"); + goto err; + } + + if (SSL_CTX_use_certificate_chain_mem(ssl_ctx, + keypair->cert_mem, keypair->cert_len) != 1) { + tls_set_errorx(ctx, "failed to load certificate"); + goto err; + } + } + + if (tls_keypair_to_pkey(ctx, keypair, &pkey) == -1) + goto err; + if (pkey != NULL) { + if (tls_keypair_setup_pkey(ctx, keypair, pkey) == -1) + goto err; + if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { + tls_set_errorx(ctx, "failed to load private key"); + goto err; + } + EVP_PKEY_free(pkey); + pkey = NULL; + } + + if (!ctx->config->skip_private_key_check && + SSL_CTX_check_private_key(ssl_ctx) != 1) { + tls_set_errorx(ctx, "private/public key mismatch"); + goto err; + } + + return (0); + + err: + EVP_PKEY_free(pkey); + + return (-1); +} + +int +tls_configure_ssl(struct tls *ctx, SSL_CTX *ssl_ctx) +{ + SSL_CTX_clear_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); + + SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2); + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv3); + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1); + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1); + + SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TLSv1_2); + SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TLSv1_3); + + if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_2) == 0) + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2); + if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_3) == 0) + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3); + + if (ctx->config->alpn != NULL) { + if (SSL_CTX_set_alpn_protos(ssl_ctx, ctx->config->alpn, + ctx->config->alpn_len) != 0) { + tls_set_errorx(ctx, "failed to set alpn"); + goto err; + } + } + + if (ctx->config->ciphers != NULL) { + if (SSL_CTX_set_cipher_list(ssl_ctx, + ctx->config->ciphers) != 1) { + tls_set_errorx(ctx, "failed to set ciphers"); + goto err; + } + } + + if (ctx->config->verify_time == 0) { + X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(ssl_ctx), + X509_V_FLAG_NO_CHECK_TIME); + } + + /* Disable any form of session caching by default */ + SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_OFF); + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET); + + return (0); + + err: + return (-1); +} + +static int +tls_ssl_cert_verify_cb(X509_STORE_CTX *x509_ctx, void *arg) +{ + struct tls *ctx = arg; + int x509_err; + + if (ctx->config->verify_cert == 0) + return (1); + + if ((X509_verify_cert(x509_ctx)) < 0) { + tls_set_errorx(ctx, "X509 verify cert failed"); + return (0); + } + + x509_err = X509_STORE_CTX_get_error(x509_ctx); + if (x509_err == X509_V_OK) + return (1); + + tls_set_errorx(ctx, "certificate verification failed: %s", + X509_verify_cert_error_string(x509_err)); + + return (0); +} + +int +tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify) +{ + size_t ca_len = ctx->config->ca_len; + char *ca_mem = ctx->config->ca_mem; + char *crl_mem = ctx->config->crl_mem; + size_t crl_len = ctx->config->crl_len; + char *ca_free = NULL; + STACK_OF(X509_INFO) *xis = NULL; + X509_STORE *store; + X509_INFO *xi; + BIO *bio = NULL; + int rv = -1; + int i; + + SSL_CTX_set_verify(ssl_ctx, verify, NULL); + SSL_CTX_set_cert_verify_callback(ssl_ctx, tls_ssl_cert_verify_cb, ctx); + + if (ctx->config->verify_depth >= 0) + SSL_CTX_set_verify_depth(ssl_ctx, ctx->config->verify_depth); + + if (ctx->config->verify_cert == 0) + goto done; + + /* If no CA has been specified, attempt to load the default. */ + if (ctx->config->ca_mem == NULL && ctx->config->ca_path == NULL) { + if (tls_config_load_file(&ctx->error, "CA", tls_default_ca_cert_file(), + &ca_mem, &ca_len) != 0) + goto err; + ca_free = ca_mem; + } + + if (ca_mem != NULL) { + if (ca_len > INT_MAX) { + tls_set_errorx(ctx, "ca too long"); + goto err; + } + if (SSL_CTX_load_verify_mem(ssl_ctx, ca_mem, ca_len) != 1) { + tls_set_errorx(ctx, "ssl verify memory setup failure"); + goto err; + } + } else if (SSL_CTX_load_verify_locations(ssl_ctx, NULL, + ctx->config->ca_path) != 1) { + tls_set_errorx(ctx, "ssl verify locations failure"); + goto err; + } + + if (crl_mem != NULL) { + if (crl_len > INT_MAX) { + tls_set_errorx(ctx, "crl too long"); + goto err; + } + if ((bio = BIO_new_mem_buf(crl_mem, crl_len)) == NULL) { + tls_set_errorx(ctx, "failed to create buffer"); + goto err; + } + if ((xis = PEM_X509_INFO_read_bio(bio, NULL, tls_password_cb, + NULL)) == NULL) { + tls_set_errorx(ctx, "failed to parse crl"); + goto err; + } + store = SSL_CTX_get_cert_store(ssl_ctx); + for (i = 0; i < sk_X509_INFO_num(xis); i++) { + xi = sk_X509_INFO_value(xis, i); + if (xi->crl == NULL) + continue; + if (!X509_STORE_add_crl(store, xi->crl)) { + tls_set_error(ctx, "failed to add crl"); + goto err; + } + } + X509_STORE_set_flags(store, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + } + + done: + rv = 0; + + err: + sk_X509_INFO_pop_free(xis, X509_INFO_free); + BIO_free(bio); + free(ca_free); + + return (rv); +} + +void +tls_free(struct tls *ctx) +{ + if (ctx == NULL) + return; + + tls_reset(ctx); + + free(ctx); +} + +void +tls_reset(struct tls *ctx) +{ + struct tls_sni_ctx *sni, *nsni; + + tls_config_free(ctx->config); + ctx->config = NULL; + + SSL_CTX_free(ctx->ssl_ctx); + SSL_free(ctx->ssl_conn); + X509_free(ctx->ssl_peer_cert); + + ctx->ssl_conn = NULL; + ctx->ssl_ctx = NULL; + ctx->ssl_peer_cert = NULL; + /* X509 objects in chain are freed with the SSL */ + ctx->ssl_peer_chain = NULL; + + ctx->socket = -1; + ctx->state = 0; + + free(ctx->servername); + ctx->servername = NULL; + + free(ctx->error.msg); + ctx->error.msg = NULL; + ctx->error.num = -1; + + tls_conninfo_free(ctx->conninfo); + ctx->conninfo = NULL; + + tls_ocsp_free(ctx->ocsp); + ctx->ocsp = NULL; + + for (sni = ctx->sni_ctx; sni != NULL; sni = nsni) { + nsni = sni->next; + tls_sni_ctx_free(sni); + } + ctx->sni_ctx = NULL; + + ctx->read_cb = NULL; + ctx->write_cb = NULL; + ctx->cb_arg = NULL; +} + +int +tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix) +{ + const char *errstr = "unknown error"; + unsigned long err; + int ssl_err; + + ssl_err = SSL_get_error(ssl_conn, ssl_ret); + switch (ssl_err) { + case SSL_ERROR_NONE: + case SSL_ERROR_ZERO_RETURN: + return (0); + + case SSL_ERROR_WANT_READ: + return (TLS_WANT_POLLIN); + + case SSL_ERROR_WANT_WRITE: + return (TLS_WANT_POLLOUT); + + case SSL_ERROR_SYSCALL: + if ((err = ERR_peek_error()) != 0) { + errstr = ERR_error_string(err, NULL); + } else if (ssl_ret == 0) { + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) != 0) { + ctx->state |= TLS_EOF_NO_CLOSE_NOTIFY; + return (0); + } + errstr = "unexpected EOF"; + } else if (ssl_ret == -1) { + errstr = strerror(errno); + } + tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr); + return (-1); + + case SSL_ERROR_SSL: + if ((err = ERR_peek_error()) != 0) { + errstr = ERR_error_string(err, NULL); + } + tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr); + return (-1); + + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_WANT_ACCEPT: + case SSL_ERROR_WANT_X509_LOOKUP: + default: + tls_set_ssl_errorx(ctx, "%s failed (%d)", prefix, ssl_err); + return (-1); + } +} + +int +tls_handshake(struct tls *ctx) +{ + int rv = -1; + + tls_error_clear(&ctx->error); + + if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { + tls_set_errorx(ctx, "invalid operation for context"); + goto out; + } + + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) != 0) { + tls_set_errorx(ctx, "handshake already completed"); + goto out; + } + + if ((ctx->flags & TLS_CLIENT) != 0) + rv = tls_handshake_client(ctx); + else if ((ctx->flags & TLS_SERVER_CONN) != 0) + rv = tls_handshake_server(ctx); + + if (rv == 0) { + ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn); + ctx->ssl_peer_chain = SSL_get_peer_cert_chain(ctx->ssl_conn); + if (tls_conninfo_populate(ctx) == -1) + rv = -1; + if (ctx->ocsp == NULL) + ctx->ocsp = tls_ocsp_setup_from_peer(ctx); + } + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} + +ssize_t +tls_read(struct tls *ctx, void *buf, size_t buflen) +{ + ssize_t rv = -1; + int ssl_ret; + + tls_error_clear(&ctx->error); + + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { + if ((rv = tls_handshake(ctx)) != 0) + goto out; + } + + if (buflen > INT_MAX) { + tls_set_errorx(ctx, "buflen too long"); + goto out; + } + + ERR_clear_error(); + if ((ssl_ret = SSL_read(ctx->ssl_conn, buf, buflen)) > 0) { + rv = (ssize_t)ssl_ret; + goto out; + } + rv = (ssize_t)tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "read"); + + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} + +ssize_t +tls_write(struct tls *ctx, const void *buf, size_t buflen) +{ + ssize_t rv = -1; + int ssl_ret; + + tls_error_clear(&ctx->error); + + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { + if ((rv = tls_handshake(ctx)) != 0) + goto out; + } + + if (buflen > INT_MAX) { + tls_set_errorx(ctx, "buflen too long"); + goto out; + } + + ERR_clear_error(); + if ((ssl_ret = SSL_write(ctx->ssl_conn, buf, buflen)) > 0) { + rv = (ssize_t)ssl_ret; + goto out; + } + rv = (ssize_t)tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "write"); + + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} + +int +tls_close(struct tls *ctx) +{ + int ssl_ret; + int rv = 0; + + tls_error_clear(&ctx->error); + + if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { + tls_set_errorx(ctx, "invalid operation for context"); + rv = -1; + goto out; + } + + if (ctx->state & TLS_SSL_NEEDS_SHUTDOWN) { + ERR_clear_error(); + ssl_ret = SSL_shutdown(ctx->ssl_conn); + if (ssl_ret < 0) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, + "shutdown"); + if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT) + goto out; + } + ctx->state &= ~TLS_SSL_NEEDS_SHUTDOWN; + } + + if (ctx->socket != -1) { + if (shutdown(ctx->socket, SHUT_RDWR) != 0) { + if (rv == 0 && + errno != ENOTCONN && errno != ECONNRESET) { + tls_set_error(ctx, "shutdown"); + rv = -1; + } + } + if (close(ctx->socket) != 0) { + if (rv == 0) { + tls_set_error(ctx, "close"); + rv = -1; + } + } + ctx->socket = -1; + } + + if ((ctx->state & TLS_EOF_NO_CLOSE_NOTIFY) != 0) { + tls_set_errorx(ctx, "EOF without close notify"); + rv = -1; + } + + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} diff --git a/Libraries/libressl/tls/tls.sym b/Libraries/libressl/tls/tls.sym new file mode 100644 index 000000000..42c039d29 --- /dev/null +++ b/Libraries/libressl/tls/tls.sym @@ -0,0 +1,91 @@ +tls_accept_cbs +tls_accept_fds +tls_accept_socket +tls_client +tls_close +tls_config_add_keypair_file +tls_config_add_keypair_mem +tls_config_add_keypair_ocsp_file +tls_config_add_keypair_ocsp_mem +tls_config_add_ticket_key +tls_config_clear_keys +tls_config_error +tls_config_free +tls_config_insecure_noverifycert +tls_config_insecure_noverifyname +tls_config_insecure_noverifytime +tls_config_new +tls_config_ocsp_require_stapling +tls_config_parse_protocols +tls_config_prefer_ciphers_client +tls_config_prefer_ciphers_server +tls_config_set_alpn +tls_config_set_ca_file +tls_config_set_ca_mem +tls_config_set_ca_path +tls_config_set_cert_file +tls_config_set_cert_mem +tls_config_set_ciphers +tls_config_set_crl_file +tls_config_set_crl_mem +tls_config_set_dheparams +tls_config_set_ecdhecurve +tls_config_set_ecdhecurves +tls_config_set_key_file +tls_config_set_key_mem +tls_config_set_keypair_file +tls_config_set_keypair_mem +tls_config_set_keypair_ocsp_file +tls_config_set_keypair_ocsp_mem +tls_config_set_ocsp_staple_mem +tls_config_set_ocsp_staple_file +tls_config_set_protocols +tls_config_set_session_id +tls_config_set_session_lifetime +tls_config_set_session_fd +tls_config_set_verify_depth +tls_config_skip_private_key_check +tls_config_use_fake_private_key +tls_config_verify +tls_config_verify_client +tls_config_verify_client_optional +tls_configure +tls_conn_alpn_selected +tls_conn_cipher +tls_conn_cipher_strength +tls_conn_servername +tls_conn_session_resumed +tls_conn_version +tls_connect +tls_connect_cbs +tls_connect_fds +tls_connect_servername +tls_connect_socket +tls_default_ca_cert_file +tls_error +tls_free +tls_handshake +tls_init +tls_load_file +tls_ocsp_process_response +tls_peer_cert_chain_pem +tls_peer_cert_contains_name +tls_peer_cert_hash +tls_peer_cert_issuer +tls_peer_cert_notafter +tls_peer_cert_notbefore +tls_peer_cert_provided +tls_peer_cert_subject +tls_peer_ocsp_cert_status +tls_peer_ocsp_crl_reason +tls_peer_ocsp_next_update +tls_peer_ocsp_response_status +tls_peer_ocsp_result +tls_peer_ocsp_revocation_time +tls_peer_ocsp_this_update +tls_peer_ocsp_url +tls_read +tls_reset +tls_server +tls_unload_file +tls_write diff --git a/Libraries/libressl/tls/tls_bio_cb.c b/Libraries/libressl/tls/tls_bio_cb.c new file mode 100644 index 000000000..8a1edfd5e --- /dev/null +++ b/Libraries/libressl/tls/tls_bio_cb.c @@ -0,0 +1,171 @@ +/* $OpenBSD: tls_bio_cb.c,v 1.21 2023/05/14 07:26:25 op Exp $ */ +/* + * Copyright (c) 2016 Tobias Pape + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +#include +#include "tls_internal.h" + +static int bio_cb_write(BIO *bio, const char *buf, int num); +static int bio_cb_read(BIO *bio, char *buf, int size); +static int bio_cb_puts(BIO *bio, const char *str); +static long bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr); + +static BIO_METHOD *bio_cb_method; + +static pthread_mutex_t bio_cb_method_lock = PTHREAD_MUTEX_INITIALIZER; + +static void +bio_cb_method_init(void) +{ + BIO_METHOD *bio_method; + + if (bio_cb_method != NULL) + return; + + bio_method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks"); + if (bio_method == NULL) + return; + + BIO_meth_set_write(bio_method, bio_cb_write); + BIO_meth_set_read(bio_method, bio_cb_read); + BIO_meth_set_puts(bio_method, bio_cb_puts); + BIO_meth_set_ctrl(bio_method, bio_cb_ctrl); + + bio_cb_method = bio_method; +} + +static BIO_METHOD * +bio_s_cb(void) +{ + if (bio_cb_method != NULL) + return (bio_cb_method); + + pthread_mutex_lock(&bio_cb_method_lock); + bio_cb_method_init(); + pthread_mutex_unlock(&bio_cb_method_lock); + + return (bio_cb_method); +} + +static int +bio_cb_puts(BIO *bio, const char *str) +{ + return (bio_cb_write(bio, str, strlen(str))); +} + +static long +bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) { + case BIO_CTRL_GET_CLOSE: + ret = (long)BIO_get_shutdown(bio); + break; + case BIO_CTRL_SET_CLOSE: + BIO_set_shutdown(bio, (int)num); + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + break; + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_SET: + default: + ret = BIO_ctrl(BIO_next(bio), cmd, num, ptr); + } + + return (ret); +} + +static int +bio_cb_write(BIO *bio, const char *buf, int num) +{ + struct tls *ctx = BIO_get_data(bio); + int rv; + + BIO_clear_retry_flags(bio); + rv = (ctx->write_cb)(ctx, buf, num, ctx->cb_arg); + if (rv == TLS_WANT_POLLIN) { + BIO_set_retry_read(bio); + rv = -1; + } else if (rv == TLS_WANT_POLLOUT) { + BIO_set_retry_write(bio); + rv = -1; + } + return (rv); +} + +static int +bio_cb_read(BIO *bio, char *buf, int size) +{ + struct tls *ctx = BIO_get_data(bio); + int rv; + + BIO_clear_retry_flags(bio); + rv = (ctx->read_cb)(ctx, buf, size, ctx->cb_arg); + if (rv == TLS_WANT_POLLIN) { + BIO_set_retry_read(bio); + rv = -1; + } else if (rv == TLS_WANT_POLLOUT) { + BIO_set_retry_write(bio); + rv = -1; + } + return (rv); +} + +int +tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb, + void *cb_arg) +{ + const BIO_METHOD *bio_cb; + BIO *bio; + int rv = -1; + + if (read_cb == NULL || write_cb == NULL) { + tls_set_errorx(ctx, "no callbacks provided"); + goto err; + } + + ctx->read_cb = read_cb; + ctx->write_cb = write_cb; + ctx->cb_arg = cb_arg; + + if ((bio_cb = bio_s_cb()) == NULL) { + tls_set_errorx(ctx, "failed to create callback method"); + goto err; + } + if ((bio = BIO_new(bio_cb)) == NULL) { + tls_set_errorx(ctx, "failed to create callback i/o"); + goto err; + } + BIO_set_data(bio, ctx); + BIO_set_init(bio, 1); + + SSL_set_bio(ctx->ssl_conn, bio, bio); + + rv = 0; + + err: + return (rv); +} diff --git a/Libraries/libressl/tls/tls_client.c b/Libraries/libressl/tls/tls_client.c new file mode 100644 index 000000000..deb24ebc2 --- /dev/null +++ b/Libraries/libressl/tls/tls_client.c @@ -0,0 +1,485 @@ +/* $OpenBSD: tls_client.c,v 1.49 2023/05/14 07:26:25 op Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include "tls_internal.h" + +struct tls * +tls_client(void) +{ + struct tls *ctx; + + if (tls_init() == -1) + return (NULL); + + if ((ctx = tls_new()) == NULL) + return (NULL); + + ctx->flags |= TLS_CLIENT; + + return (ctx); +} + +int +tls_connect(struct tls *ctx, const char *host, const char *port) +{ + return tls_connect_servername(ctx, host, port, NULL); +} + +int +tls_connect_servername(struct tls *ctx, const char *host, const char *port, + const char *servername) +{ + struct addrinfo hints, *res, *res0; + const char *h = NULL, *p = NULL; + char *hs = NULL, *ps = NULL; + int rv = -1, s = -1, ret; + + if ((ctx->flags & TLS_CLIENT) == 0) { + tls_set_errorx(ctx, "not a client context"); + goto err; + } + + if (host == NULL) { + tls_set_errorx(ctx, "host not specified"); + goto err; + } + + /* If port is NULL, try to extract a port from the specified host. */ + if (port == NULL) { + ret = tls_host_port(host, &hs, &ps); + if (ret == -1) { + tls_set_errorx(ctx, "memory allocation failure"); + goto err; + } + if (ret != 0) { + tls_set_errorx(ctx, "no port provided"); + goto err; + } + } + + h = (hs != NULL) ? hs : host; + p = (ps != NULL) ? ps : port; + + /* + * First check if the host is specified as a numeric IP address, + * either IPv4 or IPv6, before trying to resolve the host. + * The AI_ADDRCONFIG resolver option will not return IPv4 or IPv6 + * records if it is not configured on an interface; not considering + * loopback addresses. Checking the numeric addresses first makes + * sure that connection attempts to numeric addresses and especially + * 127.0.0.1 or ::1 loopback addresses are always possible. + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + + /* try as an IPv4 literal */ + hints.ai_family = AF_INET; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(h, p, &hints, &res0) != 0) { + /* try again as an IPv6 literal */ + hints.ai_family = AF_INET6; + if (getaddrinfo(h, p, &hints, &res0) != 0) { + /* last try, with name resolution and save the error */ + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_ADDRCONFIG; + if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) { + tls_set_error(ctx, "%s", gai_strerror(s)); + goto err; + } + } + } + + /* It was resolved somehow; now try connecting to what we got */ + s = -1; + for (res = res0; res; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) { + tls_set_error(ctx, "socket"); + continue; + } + if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { + tls_set_error(ctx, "connect"); + close(s); + s = -1; + continue; + } + + break; /* Connected. */ + } + freeaddrinfo(res0); + + if (s == -1) + goto err; + + if (servername == NULL) + servername = h; + + if (tls_connect_socket(ctx, s, servername) != 0) { + close(s); + goto err; + } + + ctx->socket = s; + + rv = 0; + + err: + free(hs); + free(ps); + + return (rv); +} + +static int +tls_client_read_session(struct tls *ctx) +{ + int sfd = ctx->config->session_fd; + uint8_t *session = NULL; + size_t session_len = 0; + SSL_SESSION *ss = NULL; + BIO *bio = NULL; + struct stat sb; + ssize_t n; + int rv = -1; + + if (fstat(sfd, &sb) == -1) { + tls_set_error(ctx, "failed to stat session file"); + goto err; + } + if (sb.st_size < 0 || sb.st_size > INT_MAX) { + tls_set_errorx(ctx, "invalid session file size"); + goto err; + } + session_len = (size_t)sb.st_size; + + /* A zero size file means that we do not yet have a valid session. */ + if (session_len == 0) + goto done; + + if ((session = malloc(session_len)) == NULL) + goto err; + + n = pread(sfd, session, session_len, 0); + if (n < 0 || (size_t)n != session_len) { + tls_set_error(ctx, "failed to read session file"); + goto err; + } + if ((bio = BIO_new_mem_buf(session, session_len)) == NULL) + goto err; + if ((ss = PEM_read_bio_SSL_SESSION(bio, NULL, tls_password_cb, + NULL)) == NULL) { + tls_set_errorx(ctx, "failed to parse session"); + goto err; + } + + if (SSL_set_session(ctx->ssl_conn, ss) != 1) { + tls_set_errorx(ctx, "failed to set session"); + goto err; + } + + done: + rv = 0; + + err: + freezero(session, session_len); + SSL_SESSION_free(ss); + BIO_free(bio); + + return rv; +} + +static int +tls_client_write_session(struct tls *ctx) +{ + int sfd = ctx->config->session_fd; + SSL_SESSION *ss = NULL; + BIO *bio = NULL; + long data_len; + char *data; + off_t offset; + size_t len; + ssize_t n; + int rv = -1; + + if ((ss = SSL_get1_session(ctx->ssl_conn)) == NULL) { + if (ftruncate(sfd, 0) == -1) { + tls_set_error(ctx, "failed to truncate session file"); + goto err; + } + goto done; + } + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto err; + if (PEM_write_bio_SSL_SESSION(bio, ss) == 0) + goto err; + if ((data_len = BIO_get_mem_data(bio, &data)) <= 0) + goto err; + + len = (size_t)data_len; + offset = 0; + + if (ftruncate(sfd, len) == -1) { + tls_set_error(ctx, "failed to truncate session file"); + goto err; + } + while (len > 0) { + if ((n = pwrite(sfd, data + offset, len, offset)) == -1) { + tls_set_error(ctx, "failed to write session file"); + goto err; + } + offset += n; + len -= n; + } + + done: + rv = 0; + + err: + SSL_SESSION_free(ss); + BIO_free_all(bio); + + return (rv); +} + +static int +tls_connect_common(struct tls *ctx, const char *servername) +{ + union tls_addr addrbuf; + size_t servername_len; + int rv = -1; + + if ((ctx->flags & TLS_CLIENT) == 0) { + tls_set_errorx(ctx, "not a client context"); + goto err; + } + + if (servername != NULL) { + if ((ctx->servername = strdup(servername)) == NULL) { + tls_set_errorx(ctx, "out of memory"); + goto err; + } + + /* + * If there's a trailing dot, remove it. While an FQDN includes + * the terminating dot representing the zero-length label of + * the root (RFC 8499, section 2), the SNI explicitly does not + * include it (RFC 6066, section 3). + */ + servername_len = strlen(ctx->servername); + if (servername_len > 0 && + ctx->servername[servername_len - 1] == '.') + ctx->servername[servername_len - 1] = '\0'; + } + + if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { + tls_set_errorx(ctx, "ssl context failure"); + goto err; + } + + if (tls_configure_ssl(ctx, ctx->ssl_ctx) != 0) + goto err; + + if (tls_configure_ssl_keypair(ctx, ctx->ssl_ctx, + ctx->config->keypair, 0) != 0) + goto err; + + if (ctx->config->verify_name) { + if (ctx->servername == NULL) { + tls_set_errorx(ctx, "server name not specified"); + goto err; + } + } + + if (tls_configure_ssl_verify(ctx, ctx->ssl_ctx, SSL_VERIFY_PEER) == -1) + goto err; + + if (ctx->config->ecdhecurves != NULL) { + if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves, + ctx->config->ecdhecurves_len) != 1) { + tls_set_errorx(ctx, "failed to set ecdhe curves"); + goto err; + } + } + + if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) { + tls_set_errorx(ctx, "ssl OCSP verification setup failure"); + goto err; + } + + if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { + tls_set_errorx(ctx, "ssl connection failure"); + goto err; + } + + if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) { + tls_set_errorx(ctx, "ssl application data failure"); + goto err; + } + + if (ctx->config->session_fd != -1) { + SSL_clear_options(ctx->ssl_conn, SSL_OP_NO_TICKET); + if (tls_client_read_session(ctx) == -1) + goto err; + } + + if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) { + tls_set_errorx(ctx, "ssl OCSP extension setup failure"); + goto err; + } + + /* + * RFC 6066 (SNI): Literal IPv4 and IPv6 addresses are not + * permitted in "HostName". + */ + if (ctx->servername != NULL && + inet_pton(AF_INET, ctx->servername, &addrbuf) != 1 && + inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) { + if (SSL_set_tlsext_host_name(ctx->ssl_conn, + ctx->servername) == 0) { + tls_set_errorx(ctx, "server name indication failure"); + goto err; + } + } + + ctx->state |= TLS_CONNECTED; + rv = 0; + + err: + return (rv); +} + +int +tls_connect_socket(struct tls *ctx, int s, const char *servername) +{ + return tls_connect_fds(ctx, s, s, servername); +} + +int +tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, + const char *servername) +{ + int rv = -1; + + if (fd_read < 0 || fd_write < 0) { + tls_set_errorx(ctx, "invalid file descriptors"); + goto err; + } + + if (tls_connect_common(ctx, servername) != 0) + goto err; + + if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 || + SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) { + tls_set_errorx(ctx, "ssl file descriptor failure"); + goto err; + } + + rv = 0; + err: + return (rv); +} + +int +tls_connect_cbs(struct tls *ctx, tls_read_cb read_cb, + tls_write_cb write_cb, void *cb_arg, const char *servername) +{ + int rv = -1; + + if (tls_connect_common(ctx, servername) != 0) + goto err; + + if (tls_set_cbs(ctx, read_cb, write_cb, cb_arg) != 0) + goto err; + + rv = 0; + + err: + return (rv); +} + +int +tls_handshake_client(struct tls *ctx) +{ + X509 *cert = NULL; + int match, ssl_ret; + int rv = -1; + + if ((ctx->flags & TLS_CLIENT) == 0) { + tls_set_errorx(ctx, "not a client context"); + goto err; + } + + if ((ctx->state & TLS_CONNECTED) == 0) { + tls_set_errorx(ctx, "context not connected"); + goto err; + } + + ctx->state |= TLS_SSL_NEEDS_SHUTDOWN; + + ERR_clear_error(); + if ((ssl_ret = SSL_connect(ctx->ssl_conn)) != 1) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); + goto err; + } + + if (ctx->config->verify_name) { + cert = SSL_get_peer_certificate(ctx->ssl_conn); + if (cert == NULL) { + tls_set_errorx(ctx, "no server certificate"); + goto err; + } + if (tls_check_name(ctx, cert, ctx->servername, &match) == -1) + goto err; + if (!match) { + tls_set_errorx(ctx, "name `%s' not present in" + " server certificate", ctx->servername); + goto err; + } + } + + ctx->state |= TLS_HANDSHAKE_COMPLETE; + + if (ctx->config->session_fd != -1) { + if (tls_client_write_session(ctx) == -1) + goto err; + } + + rv = 0; + + err: + X509_free(cert); + + return (rv); +} diff --git a/Libraries/libressl/tls/tls_config.c b/Libraries/libressl/tls/tls_config.c new file mode 100644 index 000000000..5eb5b69ac --- /dev/null +++ b/Libraries/libressl/tls/tls_config.c @@ -0,0 +1,930 @@ +/* $OpenBSD: tls_config.c,v 1.67 2023/07/02 06:37:27 beck Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "tls_internal.h" + +static const char default_ca_file[] = TLS_DEFAULT_CA_FILE; + +const char * +tls_default_ca_cert_file(void) +{ + return default_ca_file; +} + +int +tls_config_load_file(struct tls_error *error, const char *filetype, + const char *filename, char **buf, size_t *len) +{ + struct stat st; + int fd = -1; + ssize_t n; + + free(*buf); + *buf = NULL; + *len = 0; + + if ((fd = open(filename, O_RDONLY)) == -1) { + tls_error_set(error, "failed to open %s file '%s'", + filetype, filename); + goto err; + } + if (fstat(fd, &st) != 0) { + tls_error_set(error, "failed to stat %s file '%s'", + filetype, filename); + goto err; + } + if (st.st_size < 0) + goto err; + *len = (size_t)st.st_size; + if ((*buf = malloc(*len)) == NULL) { + tls_error_set(error, "failed to allocate buffer for " + "%s file", filetype); + goto err; + } + n = read(fd, *buf, *len); + if (n < 0 || (size_t)n != *len) { + tls_error_set(error, "failed to read %s file '%s'", + filetype, filename); + goto err; + } + close(fd); + return 0; + + err: + if (fd != -1) + close(fd); + freezero(*buf, *len); + *buf = NULL; + *len = 0; + + return -1; +} + +struct tls_config * +tls_config_new_internal(void) +{ + struct tls_config *config; + unsigned char sid[TLS_MAX_SESSION_ID_LENGTH]; + + if ((config = calloc(1, sizeof(*config))) == NULL) + return (NULL); + + if (pthread_mutex_init(&config->mutex, NULL) != 0) + goto err; + + config->refcount = 1; + config->session_fd = -1; + + if ((config->keypair = tls_keypair_new()) == NULL) + goto err; + + /* + * Default configuration. + */ + if (tls_config_set_dheparams(config, "none") != 0) + goto err; + if (tls_config_set_ecdhecurves(config, "default") != 0) + goto err; + if (tls_config_set_ciphers(config, "secure") != 0) + goto err; + + if (tls_config_set_protocols(config, TLS_PROTOCOLS_DEFAULT) != 0) + goto err; + if (tls_config_set_verify_depth(config, 6) != 0) + goto err; + + /* + * Set session ID context to a random value. For the simple case + * of a single process server this is good enough. For multiprocess + * servers the session ID needs to be set by the caller. + */ + arc4random_buf(sid, sizeof(sid)); + if (tls_config_set_session_id(config, sid, sizeof(sid)) != 0) + goto err; + config->ticket_keyrev = arc4random(); + config->ticket_autorekey = 1; + + tls_config_prefer_ciphers_server(config); + + tls_config_verify(config); + + return (config); + + err: + tls_config_free(config); + return (NULL); +} + +struct tls_config * +tls_config_new(void) +{ + if (tls_init() == -1) + return (NULL); + + return tls_config_new_internal(); +} + +void +tls_config_free(struct tls_config *config) +{ + struct tls_keypair *kp, *nkp; + int refcount; + + if (config == NULL) + return; + + pthread_mutex_lock(&config->mutex); + refcount = --config->refcount; + pthread_mutex_unlock(&config->mutex); + + if (refcount > 0) + return; + + for (kp = config->keypair; kp != NULL; kp = nkp) { + nkp = kp->next; + tls_keypair_free(kp); + } + + free(config->error.msg); + + free(config->alpn); + free((char *)config->ca_mem); + free((char *)config->ca_path); + free((char *)config->ciphers); + free((char *)config->crl_mem); + free(config->ecdhecurves); + + pthread_mutex_destroy(&config->mutex); + + free(config); +} + +static void +tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair) +{ + struct tls_keypair *kp; + + kp = config->keypair; + while (kp->next != NULL) + kp = kp->next; + + kp->next = keypair; +} + +const char * +tls_config_error(struct tls_config *config) +{ + return config->error.msg; +} + +void +tls_config_clear_keys(struct tls_config *config) +{ + struct tls_keypair *kp; + + for (kp = config->keypair; kp != NULL; kp = kp->next) + tls_keypair_clear_key(kp); +} + +int +tls_config_parse_protocols(uint32_t *protocols, const char *protostr) +{ + uint32_t proto, protos = 0; + char *s, *p, *q; + int negate; + + if (protostr == NULL) { + *protocols = TLS_PROTOCOLS_DEFAULT; + return (0); + } + + if ((s = strdup(protostr)) == NULL) + return (-1); + + q = s; + while ((p = strsep(&q, ",:")) != NULL) { + while (*p == ' ' || *p == '\t') + p++; + + negate = 0; + if (*p == '!') { + negate = 1; + p++; + } + + if (negate && protos == 0) + protos = TLS_PROTOCOLS_ALL; + + proto = 0; + if (strcasecmp(p, "all") == 0 || + strcasecmp(p, "legacy") == 0) + proto = TLS_PROTOCOLS_ALL; + else if (strcasecmp(p, "default") == 0 || + strcasecmp(p, "secure") == 0) + proto = TLS_PROTOCOLS_DEFAULT; + if (strcasecmp(p, "tlsv1") == 0) + proto = TLS_PROTOCOL_TLSv1; + else if (strcasecmp(p, "tlsv1.0") == 0) + proto = TLS_PROTOCOL_TLSv1_2; + else if (strcasecmp(p, "tlsv1.1") == 0) + proto = TLS_PROTOCOL_TLSv1_2; + else if (strcasecmp(p, "tlsv1.2") == 0) + proto = TLS_PROTOCOL_TLSv1_2; + else if (strcasecmp(p, "tlsv1.3") == 0) + proto = TLS_PROTOCOL_TLSv1_3; + + if (proto == 0) { + free(s); + return (-1); + } + + if (negate) + protos &= ~proto; + else + protos |= proto; + } + + *protocols = protos; + + free(s); + + return (0); +} + +static int +tls_config_parse_alpn(struct tls_config *config, const char *alpn, + char **alpn_data, size_t *alpn_len) +{ + size_t buf_len, i, len; + char *buf = NULL; + char *s = NULL; + char *p, *q; + + free(*alpn_data); + *alpn_data = NULL; + *alpn_len = 0; + + if ((buf_len = strlen(alpn) + 1) > 65535) { + tls_config_set_errorx(config, "alpn too large"); + goto err; + } + + if ((buf = malloc(buf_len)) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + + if ((s = strdup(alpn)) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + + i = 0; + q = s; + while ((p = strsep(&q, ",")) != NULL) { + if ((len = strlen(p)) == 0) { + tls_config_set_errorx(config, + "alpn protocol with zero length"); + goto err; + } + if (len > 255) { + tls_config_set_errorx(config, + "alpn protocol too long"); + goto err; + } + buf[i++] = len & 0xff; + memcpy(&buf[i], p, len); + i += len; + } + + free(s); + + *alpn_data = buf; + *alpn_len = buf_len; + + return (0); + + err: + free(buf); + free(s); + + return (-1); +} + +int +tls_config_set_alpn(struct tls_config *config, const char *alpn) +{ + return tls_config_parse_alpn(config, alpn, &config->alpn, + &config->alpn_len); +} + +static int +tls_config_add_keypair_file_internal(struct tls_config *config, + const char *cert_file, const char *key_file, const char *ocsp_file) +{ + struct tls_keypair *keypair; + + if ((keypair = tls_keypair_new()) == NULL) + return (-1); + if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0) + goto err; + if (key_file != NULL && + tls_keypair_set_key_file(keypair, &config->error, key_file) != 0) + goto err; + if (ocsp_file != NULL && + tls_keypair_set_ocsp_staple_file(keypair, &config->error, + ocsp_file) != 0) + goto err; + + tls_config_keypair_add(config, keypair); + + return (0); + + err: + tls_keypair_free(keypair); + return (-1); +} + +static int +tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len, + const uint8_t *staple, size_t staple_len) +{ + struct tls_keypair *keypair; + + if ((keypair = tls_keypair_new()) == NULL) + return (-1); + if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0) + goto err; + if (key != NULL && + tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0) + goto err; + if (staple != NULL && + tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple, + staple_len) != 0) + goto err; + + tls_config_keypair_add(config, keypair); + + return (0); + + err: + tls_keypair_free(keypair); + return (-1); +} + +int +tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len) +{ + return tls_config_add_keypair_mem_internal(config, cert, cert_len, key, + key_len, NULL, 0); +} + +int +tls_config_add_keypair_file(struct tls_config *config, + const char *cert_file, const char *key_file) +{ + return tls_config_add_keypair_file_internal(config, cert_file, + key_file, NULL); +} + +int +tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple, + size_t staple_len) +{ + return tls_config_add_keypair_mem_internal(config, cert, cert_len, key, + key_len, staple, staple_len); +} + +int +tls_config_add_keypair_ocsp_file(struct tls_config *config, + const char *cert_file, const char *key_file, const char *ocsp_file) +{ + return tls_config_add_keypair_file_internal(config, cert_file, + key_file, ocsp_file); +} + +int +tls_config_set_ca_file(struct tls_config *config, const char *ca_file) +{ + return tls_config_load_file(&config->error, "CA", ca_file, + &config->ca_mem, &config->ca_len); +} + +int +tls_config_set_ca_path(struct tls_config *config, const char *ca_path) +{ + return tls_set_string(&config->ca_path, ca_path); +} + +int +tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len) +{ + return tls_set_mem(&config->ca_mem, &config->ca_len, ca, len); +} + +int +tls_config_set_cert_file(struct tls_config *config, const char *cert_file) +{ + return tls_keypair_set_cert_file(config->keypair, &config->error, + cert_file); +} + +int +tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert, + size_t len) +{ + return tls_keypair_set_cert_mem(config->keypair, &config->error, + cert, len); +} + +int +tls_config_set_ciphers(struct tls_config *config, const char *ciphers) +{ + SSL_CTX *ssl_ctx = NULL; + + if (ciphers == NULL || + strcasecmp(ciphers, "default") == 0 || + strcasecmp(ciphers, "secure") == 0) + ciphers = TLS_CIPHERS_DEFAULT; + else if (strcasecmp(ciphers, "compat") == 0) + ciphers = TLS_CIPHERS_COMPAT; + else if (strcasecmp(ciphers, "legacy") == 0) + ciphers = TLS_CIPHERS_LEGACY; + else if (strcasecmp(ciphers, "all") == 0 || + strcasecmp(ciphers, "insecure") == 0) + ciphers = TLS_CIPHERS_ALL; + + if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) { + tls_config_set_errorx(config, "no ciphers for '%s'", ciphers); + goto err; + } + + SSL_CTX_free(ssl_ctx); + return tls_set_string(&config->ciphers, ciphers); + + err: + SSL_CTX_free(ssl_ctx); + return -1; +} + +int +tls_config_set_crl_file(struct tls_config *config, const char *crl_file) +{ + return tls_config_load_file(&config->error, "CRL", crl_file, + &config->crl_mem, &config->crl_len); +} + +int +tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl, + size_t len) +{ + return tls_set_mem(&config->crl_mem, &config->crl_len, crl, len); +} + +int +tls_config_set_dheparams(struct tls_config *config, const char *params) +{ + int keylen; + + if (params == NULL || strcasecmp(params, "none") == 0) + keylen = 0; + else if (strcasecmp(params, "auto") == 0) + keylen = -1; + else if (strcasecmp(params, "legacy") == 0) + keylen = 1024; + else { + tls_config_set_errorx(config, "invalid dhe param '%s'", params); + return (-1); + } + + config->dheparams = keylen; + + return (0); +} + +int +tls_config_set_ecdhecurve(struct tls_config *config, const char *curve) +{ + if (curve == NULL || + strcasecmp(curve, "none") == 0 || + strcasecmp(curve, "auto") == 0) { + curve = TLS_ECDHE_CURVES; + } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) { + tls_config_set_errorx(config, "invalid ecdhe curve '%s'", + curve); + return (-1); + } + + return tls_config_set_ecdhecurves(config, curve); +} + +int +tls_config_set_ecdhecurves(struct tls_config *config, const char *curves) +{ + int *curves_list = NULL, *curves_new; + size_t curves_num = 0; + char *cs = NULL; + char *p, *q; + int rv = -1; + int nid; + + free(config->ecdhecurves); + config->ecdhecurves = NULL; + config->ecdhecurves_len = 0; + + if (curves == NULL || strcasecmp(curves, "default") == 0) + curves = TLS_ECDHE_CURVES; + + if ((cs = strdup(curves)) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + + q = cs; + while ((p = strsep(&q, ",:")) != NULL) { + while (*p == ' ' || *p == '\t') + p++; + + nid = OBJ_sn2nid(p); + if (nid == NID_undef) + nid = OBJ_ln2nid(p); + if (nid == NID_undef) + nid = EC_curve_nist2nid(p); + if (nid == NID_undef) { + tls_config_set_errorx(config, + "invalid ecdhe curve '%s'", p); + goto err; + } + + if ((curves_new = reallocarray(curves_list, curves_num + 1, + sizeof(int))) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + curves_list = curves_new; + curves_list[curves_num] = nid; + curves_num++; + } + + config->ecdhecurves = curves_list; + config->ecdhecurves_len = curves_num; + curves_list = NULL; + + rv = 0; + + err: + free(cs); + free(curves_list); + + return (rv); +} + +int +tls_config_set_key_file(struct tls_config *config, const char *key_file) +{ + return tls_keypair_set_key_file(config->keypair, &config->error, + key_file); +} + +int +tls_config_set_key_mem(struct tls_config *config, const uint8_t *key, + size_t len) +{ + return tls_keypair_set_key_mem(config->keypair, &config->error, + key, len); +} + +static int +tls_config_set_keypair_file_internal(struct tls_config *config, + const char *cert_file, const char *key_file, const char *ocsp_file) +{ + if (tls_config_set_cert_file(config, cert_file) != 0) + return (-1); + if (tls_config_set_key_file(config, key_file) != 0) + return (-1); + if (ocsp_file != NULL && + tls_config_set_ocsp_staple_file(config, ocsp_file) != 0) + return (-1); + + return (0); +} + +static int +tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len, + const uint8_t *staple, size_t staple_len) +{ + if (tls_config_set_cert_mem(config, cert, cert_len) != 0) + return (-1); + if (tls_config_set_key_mem(config, key, key_len) != 0) + return (-1); + if ((staple != NULL) && + (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0)) + return (-1); + + return (0); +} + +int +tls_config_set_keypair_file(struct tls_config *config, + const char *cert_file, const char *key_file) +{ + return tls_config_set_keypair_file_internal(config, cert_file, key_file, + NULL); +} + +int +tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len) +{ + return tls_config_set_keypair_mem_internal(config, cert, cert_len, + key, key_len, NULL, 0); +} + +int +tls_config_set_keypair_ocsp_file(struct tls_config *config, + const char *cert_file, const char *key_file, const char *ocsp_file) +{ + return tls_config_set_keypair_file_internal(config, cert_file, key_file, + ocsp_file); +} + +int +tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len, + const uint8_t *staple, size_t staple_len) +{ + return tls_config_set_keypair_mem_internal(config, cert, cert_len, + key, key_len, staple, staple_len); +} + + +int +tls_config_set_protocols(struct tls_config *config, uint32_t protocols) +{ + config->protocols = protocols; + + return (0); +} + +int +tls_config_set_session_fd(struct tls_config *config, int session_fd) +{ + struct stat sb; + mode_t mugo; + + if (session_fd == -1) { + config->session_fd = session_fd; + return (0); + } + + if (fstat(session_fd, &sb) == -1) { + tls_config_set_error(config, "failed to stat session file"); + return (-1); + } + if (!S_ISREG(sb.st_mode)) { + tls_config_set_errorx(config, + "session file is not a regular file"); + return (-1); + } + + if (sb.st_uid != getuid()) { + tls_config_set_errorx(config, "session file has incorrect " + "owner (uid %u != %u)", sb.st_uid, getuid()); + return (-1); + } + mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO); + if (mugo != (S_IRUSR|S_IWUSR)) { + tls_config_set_errorx(config, "session file has incorrect " + "permissions (%o != 600)", mugo); + return (-1); + } + + config->session_fd = session_fd; + + return (0); +} + +int +tls_config_set_sign_cb(struct tls_config *config, tls_sign_cb cb, void *cb_arg) +{ + config->use_fake_private_key = 1; + config->skip_private_key_check = 1; + config->sign_cb = cb; + config->sign_cb_arg = cb_arg; + + return (0); +} + +int +tls_config_set_verify_depth(struct tls_config *config, int verify_depth) +{ + config->verify_depth = verify_depth; + + return (0); +} + +void +tls_config_prefer_ciphers_client(struct tls_config *config) +{ + config->ciphers_server = 0; +} + +void +tls_config_prefer_ciphers_server(struct tls_config *config) +{ + config->ciphers_server = 1; +} + +void +tls_config_insecure_noverifycert(struct tls_config *config) +{ + config->verify_cert = 0; +} + +void +tls_config_insecure_noverifyname(struct tls_config *config) +{ + config->verify_name = 0; +} + +void +tls_config_insecure_noverifytime(struct tls_config *config) +{ + config->verify_time = 0; +} + +void +tls_config_verify(struct tls_config *config) +{ + config->verify_cert = 1; + config->verify_name = 1; + config->verify_time = 1; +} + +void +tls_config_ocsp_require_stapling(struct tls_config *config) +{ + config->ocsp_require_stapling = 1; +} + +void +tls_config_verify_client(struct tls_config *config) +{ + config->verify_client = 1; +} + +void +tls_config_verify_client_optional(struct tls_config *config) +{ + config->verify_client = 2; +} + +void +tls_config_skip_private_key_check(struct tls_config *config) +{ + config->skip_private_key_check = 1; +} + +void +tls_config_use_fake_private_key(struct tls_config *config) +{ + config->use_fake_private_key = 1; + config->skip_private_key_check = 1; +} + +int +tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) +{ + return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error, + staple_file); +} + +int +tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple, + size_t len) +{ + return tls_keypair_set_ocsp_staple_mem(config->keypair, &config->error, + staple, len); +} + +int +tls_config_set_session_id(struct tls_config *config, + const unsigned char *session_id, size_t len) +{ + if (len > TLS_MAX_SESSION_ID_LENGTH) { + tls_config_set_errorx(config, "session ID too large"); + return (-1); + } + memset(config->session_id, 0, sizeof(config->session_id)); + memcpy(config->session_id, session_id, len); + return (0); +} + +int +tls_config_set_session_lifetime(struct tls_config *config, int lifetime) +{ + if (lifetime > TLS_MAX_SESSION_TIMEOUT) { + tls_config_set_errorx(config, "session lifetime too large"); + return (-1); + } + if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) { + tls_config_set_errorx(config, "session lifetime too small"); + return (-1); + } + + config->session_lifetime = lifetime; + return (0); +} + +int +tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev, + unsigned char *key, size_t keylen) +{ + struct tls_ticket_key newkey; + int i; + + if (TLS_TICKET_KEY_SIZE != keylen || + sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) { + tls_config_set_errorx(config, + "wrong amount of ticket key data"); + return (-1); + } + + keyrev = htonl(keyrev); + memset(&newkey, 0, sizeof(newkey)); + memcpy(newkey.key_name, &keyrev, sizeof(keyrev)); + memcpy(newkey.aes_key, key, sizeof(newkey.aes_key)); + memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key), + sizeof(newkey.hmac_key)); + newkey.time = time(NULL); + + for (i = 0; i < TLS_NUM_TICKETS; i++) { + struct tls_ticket_key *tk = &config->ticket_keys[i]; + if (memcmp(newkey.key_name, tk->key_name, + sizeof(tk->key_name)) != 0) + continue; + + /* allow re-entry of most recent key */ + if (i == 0 && memcmp(newkey.aes_key, tk->aes_key, + sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key, + tk->hmac_key, sizeof(tk->hmac_key)) == 0) + return (0); + tls_config_set_errorx(config, "ticket key already present"); + return (-1); + } + + memmove(&config->ticket_keys[1], &config->ticket_keys[0], + sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0])); + config->ticket_keys[0] = newkey; + + config->ticket_autorekey = 0; + + return (0); +} + +int +tls_config_ticket_autorekey(struct tls_config *config) +{ + unsigned char key[TLS_TICKET_KEY_SIZE]; + int rv; + + arc4random_buf(key, sizeof(key)); + rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key, + sizeof(key)); + config->ticket_autorekey = 1; + return (rv); +} diff --git a/Libraries/libressl/tls/tls_conninfo.c b/Libraries/libressl/tls/tls_conninfo.c new file mode 100644 index 000000000..b2aadab08 --- /dev/null +++ b/Libraries/libressl/tls/tls_conninfo.c @@ -0,0 +1,344 @@ +/* $OpenBSD: tls_conninfo.c,v 1.23 2023/05/14 07:26:25 op Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * Copyright (c) 2015 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +#include +#include "tls_internal.h" + +int ASN1_time_tm_clamp_notafter(struct tm *tm); + +int +tls_hex_string(const unsigned char *in, size_t inlen, char **out, + size_t *outlen) +{ + static const char hex[] = "0123456789abcdef"; + size_t i, len; + char *p; + + if (outlen != NULL) + *outlen = 0; + + if (inlen >= SIZE_MAX) + return (-1); + if ((*out = reallocarray(NULL, inlen + 1, 2)) == NULL) + return (-1); + + p = *out; + len = 0; + for (i = 0; i < inlen; i++) { + p[len++] = hex[(in[i] >> 4) & 0x0f]; + p[len++] = hex[in[i] & 0x0f]; + } + p[len++] = 0; + + if (outlen != NULL) + *outlen = len; + + return (0); +} + +static int +tls_get_peer_cert_hash(struct tls *ctx, char **hash) +{ + *hash = NULL; + if (ctx->ssl_peer_cert == NULL) + return (0); + + if (tls_cert_hash(ctx->ssl_peer_cert, hash) == -1) { + tls_set_errorx(ctx, "unable to compute peer certificate hash - out of memory"); + *hash = NULL; + return -1; + } + return 0; +} + +static int +tls_get_peer_cert_issuer(struct tls *ctx, char **issuer) +{ + X509_NAME *name = NULL; + + *issuer = NULL; + if (ctx->ssl_peer_cert == NULL) + return (-1); + if ((name = X509_get_issuer_name(ctx->ssl_peer_cert)) == NULL) + return (-1); + *issuer = X509_NAME_oneline(name, 0, 0); + if (*issuer == NULL) + return (-1); + return (0); +} + +static int +tls_get_peer_cert_subject(struct tls *ctx, char **subject) +{ + X509_NAME *name = NULL; + + *subject = NULL; + if (ctx->ssl_peer_cert == NULL) + return (-1); + if ((name = X509_get_subject_name(ctx->ssl_peer_cert)) == NULL) + return (-1); + *subject = X509_NAME_oneline(name, 0, 0); + if (*subject == NULL) + return (-1); + return (0); +} + +static int +tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, + time_t *notafter) +{ + struct tm before_tm, after_tm; + ASN1_TIME *before, *after; + + if (ctx->ssl_peer_cert == NULL) + return (-1); + + if ((before = X509_get_notBefore(ctx->ssl_peer_cert)) == NULL) + goto err; + if ((after = X509_get_notAfter(ctx->ssl_peer_cert)) == NULL) + goto err; + if (ASN1_time_parse(before->data, before->length, &before_tm, 0) == -1) + goto err; + if (ASN1_time_parse(after->data, after->length, &after_tm, 0) == -1) + goto err; + if (!ASN1_time_tm_clamp_notafter(&after_tm)) + goto err; + if ((*notbefore = timegm(&before_tm)) == -1) + goto err; + if ((*notafter = timegm(&after_tm)) == -1) + goto err; + + return (0); + + err: + return (-1); +} + +static int +tls_get_peer_cert_info(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (0); + + if (tls_get_peer_cert_hash(ctx, &ctx->conninfo->hash) == -1) + goto err; + if (tls_get_peer_cert_subject(ctx, &ctx->conninfo->subject) == -1) + goto err; + if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1) + goto err; + if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, + &ctx->conninfo->notafter) == -1) + goto err; + + return (0); + + err: + return (-1); +} + +static int +tls_conninfo_alpn_proto(struct tls *ctx) +{ + const unsigned char *p; + unsigned int len; + + free(ctx->conninfo->alpn); + ctx->conninfo->alpn = NULL; + + SSL_get0_alpn_selected(ctx->ssl_conn, &p, &len); + if (len > 0) { + if ((ctx->conninfo->alpn = malloc(len + 1)) == NULL) + return (-1); + memcpy(ctx->conninfo->alpn, p, len); + ctx->conninfo->alpn[len] = '\0'; + } + + return (0); +} + +static int +tls_conninfo_cert_pem(struct tls *ctx) +{ + int i, rv = -1; + BIO *membio = NULL; + BUF_MEM *bptr = NULL; + + if (ctx->ssl_peer_cert == NULL) + return 0; + if ((membio = BIO_new(BIO_s_mem()))== NULL) + goto err; + + /* + * We have to write the peer cert out separately, because + * the certificate chain may or may not contain it. + */ + if (!PEM_write_bio_X509(membio, ctx->ssl_peer_cert)) + goto err; + for (i = 0; i < sk_X509_num(ctx->ssl_peer_chain); i++) { + X509 *chaincert = sk_X509_value(ctx->ssl_peer_chain, i); + if (chaincert != ctx->ssl_peer_cert && + !PEM_write_bio_X509(membio, chaincert)) + goto err; + } + + BIO_get_mem_ptr(membio, &bptr); + free(ctx->conninfo->peer_cert); + ctx->conninfo->peer_cert_len = 0; + if ((ctx->conninfo->peer_cert = malloc(bptr->length)) == NULL) + goto err; + ctx->conninfo->peer_cert_len = bptr->length; + memcpy(ctx->conninfo->peer_cert, bptr->data, + ctx->conninfo->peer_cert_len); + + /* BIO_free() will kill BUF_MEM - because we have not set BIO_NOCLOSE */ + rv = 0; + err: + BIO_free(membio); + return rv; +} + +static int +tls_conninfo_session(struct tls *ctx) +{ + ctx->conninfo->session_resumed = SSL_session_reused(ctx->ssl_conn); + + return 0; +} + +int +tls_conninfo_populate(struct tls *ctx) +{ + const char *tmp; + + tls_conninfo_free(ctx->conninfo); + + if ((ctx->conninfo = calloc(1, sizeof(struct tls_conninfo))) == NULL) { + tls_set_errorx(ctx, "out of memory"); + goto err; + } + + if (tls_conninfo_alpn_proto(ctx) == -1) + goto err; + + if ((tmp = SSL_get_cipher(ctx->ssl_conn)) == NULL) + goto err; + if ((ctx->conninfo->cipher = strdup(tmp)) == NULL) + goto err; + ctx->conninfo->cipher_strength = SSL_get_cipher_bits(ctx->ssl_conn, NULL); + + if (ctx->servername != NULL) { + if ((ctx->conninfo->servername = + strdup(ctx->servername)) == NULL) + goto err; + } + + if ((tmp = SSL_get_version(ctx->ssl_conn)) == NULL) + goto err; + if ((ctx->conninfo->version = strdup(tmp)) == NULL) + goto err; + + if (tls_get_peer_cert_info(ctx) == -1) + goto err; + + if (tls_conninfo_cert_pem(ctx) == -1) + goto err; + + if (tls_conninfo_session(ctx) == -1) + goto err; + + return (0); + + err: + tls_conninfo_free(ctx->conninfo); + ctx->conninfo = NULL; + + return (-1); +} + +void +tls_conninfo_free(struct tls_conninfo *conninfo) +{ + if (conninfo == NULL) + return; + + free(conninfo->alpn); + free(conninfo->cipher); + free(conninfo->servername); + free(conninfo->version); + + free(conninfo->hash); + free(conninfo->issuer); + free(conninfo->subject); + + free(conninfo->peer_cert); + + free(conninfo); +} + +const char * +tls_conn_alpn_selected(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->alpn); +} + +const char * +tls_conn_cipher(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->cipher); +} + +int +tls_conn_cipher_strength(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (0); + return (ctx->conninfo->cipher_strength); +} + +const char * +tls_conn_servername(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->servername); +} + +int +tls_conn_session_resumed(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (0); + return (ctx->conninfo->session_resumed); +} + +const char * +tls_conn_version(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->version); +} diff --git a/Libraries/libressl/tls/tls_internal.h b/Libraries/libressl/tls/tls_internal.h new file mode 100644 index 000000000..5cac88199 --- /dev/null +++ b/Libraries/libressl/tls/tls_internal.h @@ -0,0 +1,326 @@ +/* $OpenBSD: tls_internal.h,v 1.83 2023/06/27 18:19:59 tb Exp $ */ +/* + * Copyright (c) 2014 Jeremie Courreges-Anglas + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS_INTERNAL_H +#define HEADER_TLS_INTERNAL_H + +#include + +#include +#include + +#include + +__BEGIN_HIDDEN_DECLS + +#ifndef TLS_DEFAULT_CA_FILE +#define TLS_DEFAULT_CA_FILE "/etc/ssl/cert.pem" +#endif + +#define TLS_CIPHERS_DEFAULT "TLSv1.3:TLSv1.2+AEAD+ECDHE:TLSv1.2+AEAD+DHE" +#define TLS_CIPHERS_COMPAT "HIGH:!aNULL" +#define TLS_CIPHERS_LEGACY "HIGH:MEDIUM:!aNULL" +#define TLS_CIPHERS_ALL "ALL:!aNULL:!eNULL" + +#define TLS_ECDHE_CURVES "X25519,P-256,P-384" + +union tls_addr { + struct in_addr ip4; + struct in6_addr ip6; +}; + +struct tls_error { + char *msg; + int num; + int tls; +}; + +struct tls_keypair { + struct tls_keypair *next; + + char *cert_mem; + size_t cert_len; + char *key_mem; + size_t key_len; + char *ocsp_staple; + size_t ocsp_staple_len; + char *pubkey_hash; +}; + +#define TLS_MIN_SESSION_TIMEOUT (4) +#define TLS_MAX_SESSION_TIMEOUT (24 * 60 * 60) + +#define TLS_NUM_TICKETS 4 +#define TLS_TICKET_NAME_SIZE 16 +#define TLS_TICKET_AES_SIZE 32 +#define TLS_TICKET_HMAC_SIZE 16 + +struct tls_ticket_key { + /* The key_name must be 16 bytes according to -lssl */ + unsigned char key_name[TLS_TICKET_NAME_SIZE]; + unsigned char aes_key[TLS_TICKET_AES_SIZE]; + unsigned char hmac_key[TLS_TICKET_HMAC_SIZE]; + time_t time; +}; + +typedef int (*tls_sign_cb)(void *_cb_arg, const char *_pubkey_hash, + const uint8_t *_input, size_t _input_len, int _padding_type, + uint8_t **_out_signature, size_t *_out_signature_len); + +struct tls_config { + struct tls_error error; + + pthread_mutex_t mutex; + int refcount; + + char *alpn; + size_t alpn_len; + const char *ca_path; + char *ca_mem; + size_t ca_len; + const char *ciphers; + int ciphers_server; + char *crl_mem; + size_t crl_len; + int dheparams; + int *ecdhecurves; + size_t ecdhecurves_len; + struct tls_keypair *keypair; + int ocsp_require_stapling; + uint32_t protocols; + unsigned char session_id[TLS_MAX_SESSION_ID_LENGTH]; + int session_fd; + int session_lifetime; + struct tls_ticket_key ticket_keys[TLS_NUM_TICKETS]; + uint32_t ticket_keyrev; + int ticket_autorekey; + int verify_cert; + int verify_client; + int verify_depth; + int verify_name; + int verify_time; + int skip_private_key_check; + int use_fake_private_key; + tls_sign_cb sign_cb; + void *sign_cb_arg; +}; + +struct tls_conninfo { + char *alpn; + char *cipher; + int cipher_strength; + char *servername; + int session_resumed; + char *version; + + char *hash; + char *issuer; + char *subject; + + uint8_t *peer_cert; + size_t peer_cert_len; + + time_t notbefore; + time_t notafter; +}; + +#define TLS_CLIENT (1 << 0) +#define TLS_SERVER (1 << 1) +#define TLS_SERVER_CONN (1 << 2) + +#define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0) +#define TLS_CONNECTED (1 << 1) +#define TLS_HANDSHAKE_COMPLETE (1 << 2) +#define TLS_SSL_NEEDS_SHUTDOWN (1 << 3) + +struct tls_ocsp_result { + const char *result_msg; + int response_status; + int cert_status; + int crl_reason; + time_t this_update; + time_t next_update; + time_t revocation_time; +}; + +struct tls_ocsp { + /* responder location */ + char *ocsp_url; + + /* cert data, this struct does not own these */ + X509 *main_cert; + STACK_OF(X509) *extra_certs; + + struct tls_ocsp_result *ocsp_result; +}; + +struct tls_sni_ctx { + struct tls_sni_ctx *next; + + struct tls_keypair *keypair; + + SSL_CTX *ssl_ctx; + X509 *ssl_cert; +}; + +struct tls { + struct tls_config *config; + struct tls_keypair *keypair; + + struct tls_error error; + + uint32_t flags; + uint32_t state; + + char *servername; + int socket; + + SSL *ssl_conn; + SSL_CTX *ssl_ctx; + + struct tls_sni_ctx *sni_ctx; + + X509 *ssl_peer_cert; + STACK_OF(X509) *ssl_peer_chain; + + struct tls_conninfo *conninfo; + + struct tls_ocsp *ocsp; + + tls_read_cb read_cb; + tls_write_cb write_cb; + void *cb_arg; +}; + +int tls_set_mem(char **_dest, size_t *_destlen, const void *_src, + size_t _srclen); +int tls_set_string(const char **_dest, const char *_src); + +struct tls_keypair *tls_keypair_new(void); +void tls_keypair_clear_key(struct tls_keypair *_keypair); +void tls_keypair_free(struct tls_keypair *_keypair); +int tls_keypair_set_cert_file(struct tls_keypair *_keypair, + struct tls_error *_error, const char *_cert_file); +int tls_keypair_set_cert_mem(struct tls_keypair *_keypair, + struct tls_error *_error, const uint8_t *_cert, size_t _len); +int tls_keypair_set_key_file(struct tls_keypair *_keypair, + struct tls_error *_error, const char *_key_file); +int tls_keypair_set_key_mem(struct tls_keypair *_keypair, + struct tls_error *_error, const uint8_t *_key, size_t _len); +int tls_keypair_set_ocsp_staple_file(struct tls_keypair *_keypair, + struct tls_error *_error, const char *_ocsp_file); +int tls_keypair_set_ocsp_staple_mem(struct tls_keypair *_keypair, + struct tls_error *_error, const uint8_t *_staple, size_t _len); +int tls_keypair_load_cert(struct tls_keypair *_keypair, + struct tls_error *_error, X509 **_cert); + +struct tls_sni_ctx *tls_sni_ctx_new(void); +void tls_sni_ctx_free(struct tls_sni_ctx *sni_ctx); + +struct tls_config *tls_config_new_internal(void); + +struct tls *tls_new(void); +struct tls *tls_server_conn(struct tls *ctx); + +int tls_check_name(struct tls *ctx, X509 *cert, const char *servername, + int *match); +int tls_configure_server(struct tls *ctx); + +int tls_configure_ssl(struct tls *ctx, SSL_CTX *ssl_ctx); +int tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, + struct tls_keypair *keypair, int required); +int tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify); + +int tls_handshake_client(struct tls *ctx); +int tls_handshake_server(struct tls *ctx); + +int tls_config_load_file(struct tls_error *error, const char *filetype, + const char *filename, char **buf, size_t *len); +int tls_config_ticket_autorekey(struct tls_config *config); +int tls_host_port(const char *hostport, char **host, char **port); + +int tls_set_cbs(struct tls *ctx, + tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg); + +void tls_error_clear(struct tls_error *error); +int tls_error_set(struct tls_error *error, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_error_setx(struct tls_error *error, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_config_set_error(struct tls_config *cfg, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_config_set_errorx(struct tls_config *cfg, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_set_error(struct tls *ctx, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_set_errorx(struct tls *ctx, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); + +int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, + const char *prefix); + +int tls_conninfo_populate(struct tls *ctx); +void tls_conninfo_free(struct tls_conninfo *conninfo); + +int tls_ocsp_verify_cb(SSL *ssl, void *arg); +int tls_ocsp_stapling_cb(SSL *ssl, void *arg); +void tls_ocsp_free(struct tls_ocsp *ctx); +struct tls_ocsp *tls_ocsp_setup_from_peer(struct tls *ctx); +int tls_hex_string(const unsigned char *_in, size_t _inlen, char **_out, + size_t *_outlen); +int tls_cert_hash(X509 *_cert, char **_hash); +int tls_cert_pubkey_hash(X509 *_cert, char **_hash); + +int tls_password_cb(char *_buf, int _size, int _rwflag, void *_u); + +RSA_METHOD *tls_signer_rsa_method(void); +EC_KEY_METHOD *tls_signer_ecdsa_method(void); + +#define TLS_PADDING_NONE 0 +#define TLS_PADDING_RSA_PKCS1 1 + +int tls_config_set_sign_cb(struct tls_config *_config, tls_sign_cb _cb, + void *_cb_arg); + +struct tls_signer* tls_signer_new(void); +void tls_signer_free(struct tls_signer * _signer); +const char *tls_signer_error(struct tls_signer * _signer); +int tls_signer_add_keypair_file(struct tls_signer *_signer, + const char *_cert_file, const char *_key_file); +int tls_signer_add_keypair_mem(struct tls_signer *_signer, const uint8_t *_cert, + size_t _cert_len, const uint8_t *_key, size_t _key_len); +int tls_signer_sign(struct tls_signer *_signer, const char *_pubkey_hash, + const uint8_t *_input, size_t _input_len, int _padding_type, + uint8_t **_out_signature, size_t *_out_signature_len); + +__END_HIDDEN_DECLS + +/* XXX this function is not fully hidden so relayd can use it */ +void tls_config_skip_private_key_check(struct tls_config *config); +void tls_config_use_fake_private_key(struct tls_config *config); + +#endif /* HEADER_TLS_INTERNAL_H */ diff --git a/Libraries/libressl/tls/tls_keypair.c b/Libraries/libressl/tls/tls_keypair.c new file mode 100644 index 000000000..a12d21d0d --- /dev/null +++ b/Libraries/libressl/tls/tls_keypair.c @@ -0,0 +1,169 @@ +/* $OpenBSD: tls_keypair.c,v 1.8 2021/01/05 17:37:12 jsing Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include "tls_internal.h" + +struct tls_keypair * +tls_keypair_new(void) +{ + return calloc(1, sizeof(struct tls_keypair)); +} + +static int +tls_keypair_pubkey_hash(struct tls_keypair *keypair, struct tls_error *error) +{ + X509 *cert = NULL; + int rv = -1; + + free(keypair->pubkey_hash); + keypair->pubkey_hash = NULL; + + if (keypair->cert_mem == NULL) { + rv = 0; + goto done; + } + + if (tls_keypair_load_cert(keypair, error, &cert) == -1) + goto err; + if (tls_cert_pubkey_hash(cert, &keypair->pubkey_hash) == -1) + goto err; + + rv = 0; + + err: + X509_free(cert); + done: + return (rv); +} + +void +tls_keypair_clear_key(struct tls_keypair *keypair) +{ + freezero(keypair->key_mem, keypair->key_len); + keypair->key_mem = NULL; + keypair->key_len = 0; +} + +int +tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error, + const char *cert_file) +{ + if (tls_config_load_file(error, "certificate", cert_file, + &keypair->cert_mem, &keypair->cert_len) == -1) + return -1; + return tls_keypair_pubkey_hash(keypair, error); +} + +int +tls_keypair_set_cert_mem(struct tls_keypair *keypair, struct tls_error *error, + const uint8_t *cert, size_t len) +{ + if (tls_set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len) == -1) + return -1; + return tls_keypair_pubkey_hash(keypair, error); +} + +int +tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error, + const char *key_file) +{ + tls_keypair_clear_key(keypair); + return tls_config_load_file(error, "key", key_file, + &keypair->key_mem, &keypair->key_len); +} + +int +tls_keypair_set_key_mem(struct tls_keypair *keypair, struct tls_error *error, + const uint8_t *key, size_t len) +{ + tls_keypair_clear_key(keypair); + return tls_set_mem(&keypair->key_mem, &keypair->key_len, key, len); +} + +int +tls_keypair_set_ocsp_staple_file(struct tls_keypair *keypair, + struct tls_error *error, const char *ocsp_file) +{ + return tls_config_load_file(error, "ocsp", ocsp_file, + &keypair->ocsp_staple, &keypair->ocsp_staple_len); +} + +int +tls_keypair_set_ocsp_staple_mem(struct tls_keypair *keypair, + struct tls_error *error, const uint8_t *staple, size_t len) +{ + return tls_set_mem(&keypair->ocsp_staple, &keypair->ocsp_staple_len, + staple, len); +} + +void +tls_keypair_free(struct tls_keypair *keypair) +{ + if (keypair == NULL) + return; + + tls_keypair_clear_key(keypair); + + free(keypair->cert_mem); + free(keypair->ocsp_staple); + free(keypair->pubkey_hash); + + free(keypair); +} + +int +tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error, + X509 **cert) +{ + char *errstr = "unknown"; + BIO *cert_bio = NULL; + unsigned long ssl_err; + int rv = -1; + + X509_free(*cert); + *cert = NULL; + + if (keypair->cert_mem == NULL) { + tls_error_set(error, "keypair has no certificate"); + goto err; + } + if ((cert_bio = BIO_new_mem_buf(keypair->cert_mem, + keypair->cert_len)) == NULL) { + tls_error_set(error, "failed to create certificate bio"); + goto err; + } + if ((*cert = PEM_read_bio_X509(cert_bio, NULL, tls_password_cb, + NULL)) == NULL) { + if ((ssl_err = ERR_peek_error()) != 0) + errstr = ERR_error_string(ssl_err, NULL); + tls_error_set(error, "failed to load certificate: %s", errstr); + goto err; + } + + rv = 0; + + err: + BIO_free(cert_bio); + + return (rv); +} diff --git a/Libraries/libressl/tls/tls_ocsp.c b/Libraries/libressl/tls/tls_ocsp.c new file mode 100644 index 000000000..acf6935a5 --- /dev/null +++ b/Libraries/libressl/tls/tls_ocsp.c @@ -0,0 +1,463 @@ +/* $OpenBSD: tls_ocsp.c,v 1.23 2023/05/14 07:26:25 op Exp $ */ +/* + * Copyright (c) 2015 Marko Kreen + * Copyright (c) 2016 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include "tls_internal.h" + +#define MAXAGE_SEC (14*24*60*60) +#define JITTER_SEC (60) + +/* + * State for request. + */ + +static struct tls_ocsp * +tls_ocsp_new(void) +{ + return (calloc(1, sizeof(struct tls_ocsp))); +} + +void +tls_ocsp_free(struct tls_ocsp *ocsp) +{ + if (ocsp == NULL) + return; + + X509_free(ocsp->main_cert); + free(ocsp->ocsp_result); + free(ocsp->ocsp_url); + + free(ocsp); +} + +static int +tls_ocsp_asn1_parse_time(struct tls *ctx, ASN1_GENERALIZEDTIME *gt, time_t *gt_time) +{ + struct tm tm; + + if (gt == NULL) + return -1; + /* RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME */ + if (ASN1_time_parse(gt->data, gt->length, &tm, + V_ASN1_GENERALIZEDTIME) == -1) + return -1; + if ((*gt_time = timegm(&tm)) == -1) + return -1; + return 0; +} + +static int +tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status, + int crl_reason, ASN1_GENERALIZEDTIME *revtime, + ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd) +{ + struct tls_ocsp_result *info = NULL; + + free(ctx->ocsp->ocsp_result); + ctx->ocsp->ocsp_result = NULL; + + if ((info = calloc(1, sizeof (struct tls_ocsp_result))) == NULL) { + tls_set_error(ctx, "calloc"); + return -1; + } + info->response_status = response_status; + info->cert_status = cert_status; + info->crl_reason = crl_reason; + if (info->response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + info->result_msg = + OCSP_response_status_str(info->response_status); + } else if (info->cert_status != V_OCSP_CERTSTATUS_REVOKED) { + info->result_msg = OCSP_cert_status_str(info->cert_status); + } else { + info->result_msg = OCSP_crl_reason_str(info->crl_reason); + } + info->revocation_time = info->this_update = info->next_update = -1; + if (revtime != NULL && + tls_ocsp_asn1_parse_time(ctx, revtime, &info->revocation_time) != 0) { + tls_set_error(ctx, + "unable to parse revocation time in OCSP reply"); + goto err; + } + if (thisupd != NULL && + tls_ocsp_asn1_parse_time(ctx, thisupd, &info->this_update) != 0) { + tls_set_error(ctx, + "unable to parse this update time in OCSP reply"); + goto err; + } + if (nextupd != NULL && + tls_ocsp_asn1_parse_time(ctx, nextupd, &info->next_update) != 0) { + tls_set_error(ctx, + "unable to parse next update time in OCSP reply"); + goto err; + } + ctx->ocsp->ocsp_result = info; + return 0; + + err: + free(info); + return -1; +} + +static OCSP_CERTID * +tls_ocsp_get_certid(X509 *main_cert, STACK_OF(X509) *extra_certs, + SSL_CTX *ssl_ctx) +{ + X509_NAME *issuer_name; + X509 *issuer; + X509_STORE_CTX *storectx = NULL; + X509_OBJECT *obj = NULL; + OCSP_CERTID *cid = NULL; + X509_STORE *store; + + if ((issuer_name = X509_get_issuer_name(main_cert)) == NULL) + goto out; + + if (extra_certs != NULL) { + issuer = X509_find_by_subject(extra_certs, issuer_name); + if (issuer != NULL) { + cid = OCSP_cert_to_id(NULL, main_cert, issuer); + goto out; + } + } + + if ((store = SSL_CTX_get_cert_store(ssl_ctx)) == NULL) + goto out; + if ((storectx = X509_STORE_CTX_new()) == NULL) + goto out; + if (X509_STORE_CTX_init(storectx, store, main_cert, extra_certs) != 1) + goto out; + if ((obj = X509_STORE_CTX_get_obj_by_subject(storectx, X509_LU_X509, + issuer_name)) == NULL) + goto out; + + cid = OCSP_cert_to_id(NULL, main_cert, X509_OBJECT_get0_X509(obj)); + + out: + X509_STORE_CTX_free(storectx); + X509_OBJECT_free(obj); + + return cid; +} + +struct tls_ocsp * +tls_ocsp_setup_from_peer(struct tls *ctx) +{ + struct tls_ocsp *ocsp = NULL; + STACK_OF(OPENSSL_STRING) *ocsp_urls = NULL; + + if ((ocsp = tls_ocsp_new()) == NULL) + goto err; + + /* steal state from ctx struct */ + ocsp->main_cert = SSL_get_peer_certificate(ctx->ssl_conn); + ocsp->extra_certs = SSL_get_peer_cert_chain(ctx->ssl_conn); + if (ocsp->main_cert == NULL) { + tls_set_errorx(ctx, "no peer certificate for OCSP"); + goto err; + } + + ocsp_urls = X509_get1_ocsp(ocsp->main_cert); + if (ocsp_urls == NULL) { + tls_set_errorx(ctx, "no OCSP URLs in peer certificate"); + goto err; + } + + ocsp->ocsp_url = strdup(sk_OPENSSL_STRING_value(ocsp_urls, 0)); + if (ocsp->ocsp_url == NULL) { + tls_set_errorx(ctx, "out of memory"); + goto err; + } + + X509_email_free(ocsp_urls); + return ocsp; + + err: + tls_ocsp_free(ocsp); + X509_email_free(ocsp_urls); + return NULL; +} + +static int +tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp) +{ + OCSP_BASICRESP *br = NULL; + ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL; + OCSP_CERTID *cid = NULL; + STACK_OF(X509) *combined = NULL; + int response_status=0, cert_status=0, crl_reason=0; + int ret = -1; + unsigned long flags; + + if ((br = OCSP_response_get1_basic(resp)) == NULL) { + tls_set_errorx(ctx, "cannot load ocsp reply"); + goto err; + } + + /* + * Skip validation of 'extra_certs' as this should be done + * already as part of main handshake. + */ + flags = OCSP_TRUSTOTHER; + + /* now verify */ + if (OCSP_basic_verify(br, ctx->ocsp->extra_certs, + SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) { + tls_set_errorx(ctx, "ocsp verify failed"); + goto err; + } + + /* signature OK, look inside */ + response_status = OCSP_response_status(resp); + if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + tls_set_errorx(ctx, "ocsp verify failed: response - %s", + OCSP_response_status_str(response_status)); + goto err; + } + + cid = tls_ocsp_get_certid(ctx->ocsp->main_cert, + ctx->ocsp->extra_certs, ctx->ssl_ctx); + if (cid == NULL) { + tls_set_errorx(ctx, "ocsp verify failed: no issuer cert"); + goto err; + } + + if (OCSP_resp_find_status(br, cid, &cert_status, &crl_reason, + &revtime, &thisupd, &nextupd) != 1) { + tls_set_errorx(ctx, "ocsp verify failed: no result for cert"); + goto err; + } + + if (OCSP_check_validity(thisupd, nextupd, JITTER_SEC, + MAXAGE_SEC) != 1) { + tls_set_errorx(ctx, + "ocsp verify failed: ocsp response not current"); + goto err; + } + + if (tls_ocsp_fill_info(ctx, response_status, cert_status, + crl_reason, revtime, thisupd, nextupd) != 0) + goto err; + + /* finally can look at status */ + if (cert_status != V_OCSP_CERTSTATUS_GOOD && cert_status != + V_OCSP_CERTSTATUS_UNKNOWN) { + tls_set_errorx(ctx, "ocsp verify failed: revoked cert - %s", + OCSP_crl_reason_str(crl_reason)); + goto err; + } + ret = 0; + + err: + sk_X509_free(combined); + OCSP_CERTID_free(cid); + OCSP_BASICRESP_free(br); + return ret; +} + +/* + * Process a raw OCSP response from an OCSP server request. + * OCSP details can then be retrieved with tls_peer_ocsp_* functions. + * returns 0 if certificate ok, -1 otherwise. + */ +static int +tls_ocsp_process_response_internal(struct tls *ctx, const unsigned char *response, + size_t size) +{ + int ret; + OCSP_RESPONSE *resp; + + resp = d2i_OCSP_RESPONSE(NULL, &response, size); + if (resp == NULL) { + tls_ocsp_free(ctx->ocsp); + ctx->ocsp = NULL; + tls_set_error(ctx, "unable to parse OCSP response"); + return -1; + } + ret = tls_ocsp_verify_response(ctx, resp); + OCSP_RESPONSE_free(resp); + return ret; +} + +/* TLS handshake verification callback for stapled requests */ +int +tls_ocsp_verify_cb(SSL *ssl, void *arg) +{ + const unsigned char *raw = NULL; + int size, res = -1; + struct tls *ctx; + + if ((ctx = SSL_get_app_data(ssl)) == NULL) + return -1; + + size = SSL_get_tlsext_status_ocsp_resp(ssl, &raw); + if (size <= 0) { + if (ctx->config->ocsp_require_stapling) { + tls_set_errorx(ctx, "no stapled OCSP response provided"); + return 0; + } + return 1; + } + + tls_ocsp_free(ctx->ocsp); + if ((ctx->ocsp = tls_ocsp_setup_from_peer(ctx)) == NULL) + return 0; + + if (ctx->config->verify_cert == 0 || ctx->config->verify_time == 0) + return 1; + + res = tls_ocsp_process_response_internal(ctx, raw, size); + + return (res == 0) ? 1 : 0; +} + + +/* Staple the OCSP information in ctx->ocsp to the server handshake. */ +int +tls_ocsp_stapling_cb(SSL *ssl, void *arg) +{ + int ret = SSL_TLSEXT_ERR_ALERT_FATAL; + unsigned char *ocsp_staple = NULL; + struct tls *ctx; + + if ((ctx = SSL_get_app_data(ssl)) == NULL) + goto err; + + if (ctx->keypair == NULL || ctx->keypair->ocsp_staple == NULL || + ctx->keypair->ocsp_staple_len == 0) + return SSL_TLSEXT_ERR_NOACK; + + if ((ocsp_staple = malloc(ctx->keypair->ocsp_staple_len)) == NULL) + goto err; + + memcpy(ocsp_staple, ctx->keypair->ocsp_staple, + ctx->keypair->ocsp_staple_len); + + if (SSL_set_tlsext_status_ocsp_resp(ctx->ssl_conn, ocsp_staple, + ctx->keypair->ocsp_staple_len) != 1) + goto err; + + ret = SSL_TLSEXT_ERR_OK; + err: + if (ret != SSL_TLSEXT_ERR_OK) + free(ocsp_staple); + + return ret; +} + +/* + * Public API + */ + +/* Retrieve OCSP URL from peer certificate, if present. */ +const char * +tls_peer_ocsp_url(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return NULL; + return ctx->ocsp->ocsp_url; +} + +const char * +tls_peer_ocsp_result(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return NULL; + if (ctx->ocsp->ocsp_result == NULL) + return NULL; + return ctx->ocsp->ocsp_result->result_msg; +} + +int +tls_peer_ocsp_response_status(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return -1; + if (ctx->ocsp->ocsp_result == NULL) + return -1; + return ctx->ocsp->ocsp_result->response_status; +} + +int +tls_peer_ocsp_cert_status(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return -1; + if (ctx->ocsp->ocsp_result == NULL) + return -1; + return ctx->ocsp->ocsp_result->cert_status; +} + +int +tls_peer_ocsp_crl_reason(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return -1; + if (ctx->ocsp->ocsp_result == NULL) + return -1; + return ctx->ocsp->ocsp_result->crl_reason; +} + +time_t +tls_peer_ocsp_this_update(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return -1; + if (ctx->ocsp->ocsp_result == NULL) + return -1; + return ctx->ocsp->ocsp_result->this_update; +} + +time_t +tls_peer_ocsp_next_update(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return -1; + if (ctx->ocsp->ocsp_result == NULL) + return -1; + return ctx->ocsp->ocsp_result->next_update; +} + +time_t +tls_peer_ocsp_revocation_time(struct tls *ctx) +{ + if (ctx->ocsp == NULL) + return -1; + if (ctx->ocsp->ocsp_result == NULL) + return -1; + return ctx->ocsp->ocsp_result->revocation_time; +} + +int +tls_ocsp_process_response(struct tls *ctx, const unsigned char *response, + size_t size) +{ + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) + return -1; + return tls_ocsp_process_response_internal(ctx, response, size); +} diff --git a/Libraries/libressl/tls/tls_peer.c b/Libraries/libressl/tls/tls_peer.c new file mode 100644 index 000000000..ec97a3083 --- /dev/null +++ b/Libraries/libressl/tls/tls_peer.c @@ -0,0 +1,99 @@ +/* $OpenBSD: tls_peer.c,v 1.8 2017/04/10 17:11:13 jsing Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * Copyright (c) 2015 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include "tls_internal.h" + +const char * +tls_peer_cert_hash(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->hash); +} +const char * +tls_peer_cert_issuer(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->issuer); +} + +const char * +tls_peer_cert_subject(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->subject); +} + +int +tls_peer_cert_provided(struct tls *ctx) +{ + return (ctx->ssl_peer_cert != NULL); +} + +int +tls_peer_cert_contains_name(struct tls *ctx, const char *name) +{ + int match; + + if (ctx->ssl_peer_cert == NULL) + return (0); + + if (tls_check_name(ctx, ctx->ssl_peer_cert, name, &match) == -1) + return (0); + + return (match); +} + +time_t +tls_peer_cert_notbefore(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (-1); + if (ctx->conninfo == NULL) + return (-1); + return (ctx->conninfo->notbefore); +} + +time_t +tls_peer_cert_notafter(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (-1); + if (ctx->conninfo == NULL) + return (-1); + return (ctx->conninfo->notafter); +} + +const uint8_t * +tls_peer_cert_chain_pem(struct tls *ctx, size_t *size) +{ + if (ctx->ssl_peer_cert == NULL) + return (NULL); + if (ctx->conninfo == NULL) + return (NULL); + *size = ctx->conninfo->peer_cert_len; + return (ctx->conninfo->peer_cert); +} + diff --git a/Libraries/libressl/tls/tls_server.c b/Libraries/libressl/tls/tls_server.c new file mode 100644 index 000000000..5f93c7a03 --- /dev/null +++ b/Libraries/libressl/tls/tls_server.c @@ -0,0 +1,468 @@ +/* $OpenBSD: tls_server.c,v 1.49 2023/05/14 07:26:25 op Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include + +#include +#include +#include + +#include +#include "tls_internal.h" + +struct tls * +tls_server(void) +{ + struct tls *ctx; + + if (tls_init() == -1) + return (NULL); + + if ((ctx = tls_new()) == NULL) + return (NULL); + + ctx->flags |= TLS_SERVER; + + return (ctx); +} + +struct tls * +tls_server_conn(struct tls *ctx) +{ + struct tls *conn_ctx; + + if ((conn_ctx = tls_new()) == NULL) + return (NULL); + + conn_ctx->flags |= TLS_SERVER_CONN; + + pthread_mutex_lock(&ctx->config->mutex); + ctx->config->refcount++; + pthread_mutex_unlock(&ctx->config->mutex); + + conn_ctx->config = ctx->config; + conn_ctx->keypair = ctx->config->keypair; + + return (conn_ctx); +} + +static int +tls_server_alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg) +{ + struct tls *ctx = arg; + + if (SSL_select_next_proto((unsigned char**)out, outlen, + ctx->config->alpn, ctx->config->alpn_len, in, inlen) == + OPENSSL_NPN_NEGOTIATED) + return (SSL_TLSEXT_ERR_OK); + + return (SSL_TLSEXT_ERR_NOACK); +} + +static int +tls_servername_cb(SSL *ssl, int *al, void *arg) +{ + struct tls *ctx = (struct tls *)arg; + struct tls_sni_ctx *sni_ctx; + union tls_addr addrbuf; + struct tls *conn_ctx; + const char *name; + int match; + + if ((conn_ctx = SSL_get_app_data(ssl)) == NULL) + goto err; + + if ((name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) == + NULL) { + /* + * The servername callback gets called even when there is no + * TLS servername extension provided by the client. Sigh! + */ + return (SSL_TLSEXT_ERR_NOACK); + } + + /* + * Per RFC 6066 section 3: ensure that name is not an IP literal. + * + * While we should treat this as an error, a number of clients + * (Python, Ruby and Safari) are not RFC compliant. To avoid handshake + * failures, pretend that we did not receive the extension. + */ + if (inet_pton(AF_INET, name, &addrbuf) == 1 || + inet_pton(AF_INET6, name, &addrbuf) == 1) + return (SSL_TLSEXT_ERR_NOACK); + + free(conn_ctx->servername); + if ((conn_ctx->servername = strdup(name)) == NULL) + goto err; + + /* Find appropriate SSL context for requested servername. */ + for (sni_ctx = ctx->sni_ctx; sni_ctx != NULL; sni_ctx = sni_ctx->next) { + if (tls_check_name(ctx, sni_ctx->ssl_cert, name, + &match) == -1) + goto err; + if (match) { + conn_ctx->keypair = sni_ctx->keypair; + SSL_set_SSL_CTX(conn_ctx->ssl_conn, sni_ctx->ssl_ctx); + return (SSL_TLSEXT_ERR_OK); + } + } + + /* No match, use the existing context/certificate. */ + return (SSL_TLSEXT_ERR_OK); + + err: + /* + * There is no way to tell libssl that an internal failure occurred. + * The only option we have is to return a fatal alert. + */ + *al = SSL_AD_INTERNAL_ERROR; + return (SSL_TLSEXT_ERR_ALERT_FATAL); +} + +static struct tls_ticket_key * +tls_server_ticket_key(struct tls_config *config, unsigned char *keyname) +{ + struct tls_ticket_key *key = NULL; + time_t now; + int i; + + now = time(NULL); + if (config->ticket_autorekey == 1) { + if (now - 3 * (config->session_lifetime / 4) > + config->ticket_keys[0].time) { + if (tls_config_ticket_autorekey(config) == -1) + return (NULL); + } + } + for (i = 0; i < TLS_NUM_TICKETS; i++) { + struct tls_ticket_key *tk = &config->ticket_keys[i]; + if (now - config->session_lifetime > tk->time) + continue; + if (keyname == NULL || timingsafe_memcmp(keyname, + tk->key_name, sizeof(tk->key_name)) == 0) { + key = tk; + break; + } + } + return (key); +} + +static int +tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int mode) +{ + struct tls_ticket_key *key; + struct tls *tls_ctx; + + if ((tls_ctx = SSL_get_app_data(ssl)) == NULL) + return (-1); + + if (mode == 1) { + /* create new session */ + key = tls_server_ticket_key(tls_ctx->config, NULL); + if (key == NULL) { + tls_set_errorx(tls_ctx, "no valid ticket key found"); + return (-1); + } + + memcpy(keyname, key->key_name, sizeof(key->key_name)); + arc4random_buf(iv, EVP_MAX_IV_LENGTH); + if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, + key->aes_key, iv)) { + tls_set_errorx(tls_ctx, "failed to init encrypt"); + return (-1); + } + if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key), + EVP_sha256(), NULL)) { + tls_set_errorx(tls_ctx, "failed to init hmac"); + return (-1); + } + return (0); + } else { + /* get key by name */ + key = tls_server_ticket_key(tls_ctx->config, keyname); + if (key == NULL) + return (0); + + if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, + key->aes_key, iv)) { + tls_set_errorx(tls_ctx, "failed to init decrypt"); + return (-1); + } + if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key), + EVP_sha256(), NULL)) { + tls_set_errorx(tls_ctx, "failed to init hmac"); + return (-1); + } + + /* time to renew the ticket? is it the primary key? */ + if (key != &tls_ctx->config->ticket_keys[0]) + return (2); + return (1); + } +} + +static int +tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, + struct tls_keypair *keypair) +{ + SSL_CTX_free(*ssl_ctx); + + if ((*ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) { + tls_set_errorx(ctx, "ssl context failure"); + goto err; + } + + SSL_CTX_set_options(*ssl_ctx, SSL_OP_NO_CLIENT_RENEGOTIATION); + + if (SSL_CTX_set_tlsext_servername_callback(*ssl_ctx, + tls_servername_cb) != 1) { + tls_set_error(ctx, "failed to set servername callback"); + goto err; + } + if (SSL_CTX_set_tlsext_servername_arg(*ssl_ctx, ctx) != 1) { + tls_set_error(ctx, "failed to set servername callback arg"); + goto err; + } + + if (tls_configure_ssl(ctx, *ssl_ctx) != 0) + goto err; + if (tls_configure_ssl_keypair(ctx, *ssl_ctx, keypair, 1) != 0) + goto err; + if (ctx->config->verify_client != 0) { + int verify = SSL_VERIFY_PEER; + if (ctx->config->verify_client == 1) + verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + if (tls_configure_ssl_verify(ctx, *ssl_ctx, verify) == -1) + goto err; + } + + if (ctx->config->alpn != NULL) + SSL_CTX_set_alpn_select_cb(*ssl_ctx, tls_server_alpn_cb, + ctx); + + if (ctx->config->dheparams == -1) + SSL_CTX_set_dh_auto(*ssl_ctx, 1); + else if (ctx->config->dheparams == 1024) + SSL_CTX_set_dh_auto(*ssl_ctx, 2); + + if (ctx->config->ecdhecurves != NULL) { + SSL_CTX_set_ecdh_auto(*ssl_ctx, 1); + if (SSL_CTX_set1_groups(*ssl_ctx, ctx->config->ecdhecurves, + ctx->config->ecdhecurves_len) != 1) { + tls_set_errorx(ctx, "failed to set ecdhe curves"); + goto err; + } + } + + if (ctx->config->ciphers_server == 1) + SSL_CTX_set_options(*ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + + if (SSL_CTX_set_tlsext_status_cb(*ssl_ctx, tls_ocsp_stapling_cb) != 1) { + tls_set_errorx(ctx, "failed to add OCSP stapling callback"); + goto err; + } + + if (ctx->config->session_lifetime > 0) { + /* set the session lifetime and enable tickets */ + SSL_CTX_set_timeout(*ssl_ctx, ctx->config->session_lifetime); + SSL_CTX_clear_options(*ssl_ctx, SSL_OP_NO_TICKET); + if (!SSL_CTX_set_tlsext_ticket_key_cb(*ssl_ctx, + tls_server_ticket_cb)) { + tls_set_error(ctx, + "failed to set the TLS ticket callback"); + goto err; + } + } + + if (SSL_CTX_set_session_id_context(*ssl_ctx, ctx->config->session_id, + sizeof(ctx->config->session_id)) != 1) { + tls_set_error(ctx, "failed to set session id context"); + goto err; + } + + return (0); + + err: + SSL_CTX_free(*ssl_ctx); + *ssl_ctx = NULL; + + return (-1); +} + +static int +tls_configure_server_sni(struct tls *ctx) +{ + struct tls_sni_ctx **sni_ctx; + struct tls_keypair *kp; + + if (ctx->config->keypair->next == NULL) + return (0); + + /* Set up additional SSL contexts for SNI. */ + sni_ctx = &ctx->sni_ctx; + for (kp = ctx->config->keypair->next; kp != NULL; kp = kp->next) { + if ((*sni_ctx = tls_sni_ctx_new()) == NULL) { + tls_set_errorx(ctx, "out of memory"); + goto err; + } + (*sni_ctx)->keypair = kp; + if (tls_configure_server_ssl(ctx, &(*sni_ctx)->ssl_ctx, kp) == -1) + goto err; + if (tls_keypair_load_cert(kp, &ctx->error, + &(*sni_ctx)->ssl_cert) == -1) + goto err; + sni_ctx = &(*sni_ctx)->next; + } + + return (0); + + err: + return (-1); +} + +int +tls_configure_server(struct tls *ctx) +{ + if (tls_configure_server_ssl(ctx, &ctx->ssl_ctx, + ctx->config->keypair) == -1) + goto err; + if (tls_configure_server_sni(ctx) == -1) + goto err; + + return (0); + + err: + return (-1); +} + +static struct tls * +tls_accept_common(struct tls *ctx) +{ + struct tls *conn_ctx = NULL; + + if ((ctx->flags & TLS_SERVER) == 0) { + tls_set_errorx(ctx, "not a server context"); + goto err; + } + + if ((conn_ctx = tls_server_conn(ctx)) == NULL) { + tls_set_errorx(ctx, "connection context failure"); + goto err; + } + + if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { + tls_set_errorx(ctx, "ssl failure"); + goto err; + } + + if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) { + tls_set_errorx(ctx, "ssl application data failure"); + goto err; + } + + return conn_ctx; + + err: + tls_free(conn_ctx); + + return (NULL); +} + +int +tls_accept_socket(struct tls *ctx, struct tls **cctx, int s) +{ + return (tls_accept_fds(ctx, cctx, s, s)); +} + +int +tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write) +{ + struct tls *conn_ctx; + + if ((conn_ctx = tls_accept_common(ctx)) == NULL) + goto err; + + if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || + SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { + tls_set_errorx(ctx, "ssl file descriptor failure"); + goto err; + } + + *cctx = conn_ctx; + + return (0); + err: + tls_free(conn_ctx); + *cctx = NULL; + + return (-1); +} + +int +tls_accept_cbs(struct tls *ctx, struct tls **cctx, + tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg) +{ + struct tls *conn_ctx; + + if ((conn_ctx = tls_accept_common(ctx)) == NULL) + goto err; + + if (tls_set_cbs(conn_ctx, read_cb, write_cb, cb_arg) != 0) + goto err; + + *cctx = conn_ctx; + + return (0); + err: + tls_free(conn_ctx); + *cctx = NULL; + + return (-1); +} + +int +tls_handshake_server(struct tls *ctx) +{ + int ssl_ret; + int rv = -1; + + if ((ctx->flags & TLS_SERVER_CONN) == 0) { + tls_set_errorx(ctx, "not a server connection context"); + goto err; + } + + ctx->state |= TLS_SSL_NEEDS_SHUTDOWN; + + ERR_clear_error(); + if ((ssl_ret = SSL_accept(ctx->ssl_conn)) != 1) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); + goto err; + } + + ctx->state |= TLS_HANDSHAKE_COMPLETE; + rv = 0; + + err: + return (rv); +} diff --git a/Libraries/libressl/tls/tls_signer.c b/Libraries/libressl/tls/tls_signer.c new file mode 100644 index 000000000..177c9d07a --- /dev/null +++ b/Libraries/libressl/tls/tls_signer.c @@ -0,0 +1,451 @@ +/* $OpenBSD: tls_signer.c,v 1.9 2023/06/18 19:12:58 tb Exp $ */ +/* + * Copyright (c) 2021 Eric Faurot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +#include "tls.h" +#include "tls_internal.h" + +struct tls_signer_key { + char *hash; + RSA *rsa; + EC_KEY *ecdsa; + struct tls_signer_key *next; +}; + +struct tls_signer { + struct tls_error error; + struct tls_signer_key *keys; +}; + +static pthread_mutex_t signer_method_lock = PTHREAD_MUTEX_INITIALIZER; + +struct tls_signer * +tls_signer_new(void) +{ + struct tls_signer *signer; + + if ((signer = calloc(1, sizeof(*signer))) == NULL) + return (NULL); + + return (signer); +} + +void +tls_signer_free(struct tls_signer *signer) +{ + struct tls_signer_key *skey; + + if (signer == NULL) + return; + + tls_error_clear(&signer->error); + + while (signer->keys) { + skey = signer->keys; + signer->keys = skey->next; + RSA_free(skey->rsa); + EC_KEY_free(skey->ecdsa); + free(skey->hash); + free(skey); + } + + free(signer); +} + +const char * +tls_signer_error(struct tls_signer *signer) +{ + return (signer->error.msg); +} + +int +tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len) +{ + struct tls_signer_key *skey = NULL; + char *errstr = "unknown"; + int ssl_err; + EVP_PKEY *pkey = NULL; + X509 *x509 = NULL; + BIO *bio = NULL; + char *hash = NULL; + + /* Compute certificate hash */ + if ((bio = BIO_new_mem_buf(cert, cert_len)) == NULL) { + tls_error_setx(&signer->error, + "failed to create certificate bio"); + goto err; + } + if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb, + NULL)) == NULL) { + if ((ssl_err = ERR_peek_error()) != 0) + errstr = ERR_error_string(ssl_err, NULL); + tls_error_setx(&signer->error, "failed to load certificate: %s", + errstr); + goto err; + } + if (tls_cert_pubkey_hash(x509, &hash) == -1) { + tls_error_setx(&signer->error, + "failed to get certificate hash"); + goto err; + } + + X509_free(x509); + x509 = NULL; + BIO_free(bio); + bio = NULL; + + /* Read private key */ + if ((bio = BIO_new_mem_buf(key, key_len)) == NULL) { + tls_error_setx(&signer->error, "failed to create key bio"); + goto err; + } + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb, + NULL)) == NULL) { + tls_error_setx(&signer->error, "failed to read private key"); + goto err; + } + + if ((skey = calloc(1, sizeof(*skey))) == NULL) { + tls_error_set(&signer->error, "failed to create key entry"); + goto err; + } + skey->hash = hash; + if ((skey->rsa = EVP_PKEY_get1_RSA(pkey)) == NULL && + (skey->ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) { + tls_error_setx(&signer->error, "unknown key type"); + goto err; + } + + skey->next = signer->keys; + signer->keys = skey; + EVP_PKEY_free(pkey); + BIO_free(bio); + + return (0); + + err: + EVP_PKEY_free(pkey); + X509_free(x509); + BIO_free(bio); + free(hash); + free(skey); + + return (-1); +} + +int +tls_signer_add_keypair_file(struct tls_signer *signer, const char *cert_file, + const char *key_file) +{ + char *cert = NULL, *key = NULL; + size_t cert_len, key_len; + int rv = -1; + + if (tls_config_load_file(&signer->error, "certificate", cert_file, + &cert, &cert_len) == -1) + goto err; + + if (tls_config_load_file(&signer->error, "key", key_file, &key, + &key_len) == -1) + goto err; + + rv = tls_signer_add_keypair_mem(signer, cert, cert_len, key, key_len); + + err: + free(cert); + free(key); + + return (rv); +} + +static int +tls_sign_rsa(struct tls_signer *signer, struct tls_signer_key *skey, + const uint8_t *input, size_t input_len, int padding_type, + uint8_t **out_signature, size_t *out_signature_len) +{ + int rsa_padding, rsa_size, signature_len; + char *signature = NULL; + + *out_signature = NULL; + *out_signature_len = 0; + + if (padding_type == TLS_PADDING_NONE) { + rsa_padding = RSA_NO_PADDING; + } else if (padding_type == TLS_PADDING_RSA_PKCS1) { + rsa_padding = RSA_PKCS1_PADDING; + } else { + tls_error_setx(&signer->error, "invalid RSA padding type (%d)", + padding_type); + return (-1); + } + + if (input_len > INT_MAX) { + tls_error_setx(&signer->error, "input too large"); + return (-1); + } + if ((rsa_size = RSA_size(skey->rsa)) <= 0) { + tls_error_setx(&signer->error, "invalid RSA size: %d", + rsa_size); + return (-1); + } + if ((signature = calloc(1, rsa_size)) == NULL) { + tls_error_set(&signer->error, "RSA signature"); + return (-1); + } + + if ((signature_len = RSA_private_encrypt((int)input_len, input, + signature, skey->rsa, rsa_padding)) <= 0) { + /* XXX - include further details from libcrypto. */ + tls_error_setx(&signer->error, "RSA signing failed"); + free(signature); + return (-1); + } + + *out_signature = signature; + *out_signature_len = (size_t)signature_len; + + return (0); +} + +static int +tls_sign_ecdsa(struct tls_signer *signer, struct tls_signer_key *skey, + const uint8_t *input, size_t input_len, int padding_type, + uint8_t **out_signature, size_t *out_signature_len) +{ + unsigned char *signature; + int signature_len; + + *out_signature = NULL; + *out_signature_len = 0; + + if (padding_type != TLS_PADDING_NONE) { + tls_error_setx(&signer->error, "invalid ECDSA padding"); + return (-1); + } + + if (input_len > INT_MAX) { + tls_error_setx(&signer->error, "digest too large"); + return (-1); + } + if ((signature_len = ECDSA_size(skey->ecdsa)) <= 0) { + tls_error_setx(&signer->error, "invalid ECDSA size: %d", + signature_len); + return (-1); + } + if ((signature = calloc(1, signature_len)) == NULL) { + tls_error_set(&signer->error, "ECDSA signature"); + return (-1); + } + + if (!ECDSA_sign(0, input, input_len, signature, &signature_len, + skey->ecdsa)) { + /* XXX - include further details from libcrypto. */ + tls_error_setx(&signer->error, "ECDSA signing failed"); + free(signature); + return (-1); + } + + *out_signature = signature; + *out_signature_len = signature_len; + + return (0); +} + +int +tls_signer_sign(struct tls_signer *signer, const char *pubkey_hash, + const uint8_t *input, size_t input_len, int padding_type, + uint8_t **out_signature, size_t *out_signature_len) +{ + struct tls_signer_key *skey; + + *out_signature = NULL; + *out_signature_len = 0; + + for (skey = signer->keys; skey; skey = skey->next) + if (!strcmp(pubkey_hash, skey->hash)) + break; + + if (skey == NULL) { + tls_error_setx(&signer->error, "key not found"); + return (-1); + } + + if (skey->rsa != NULL) + return tls_sign_rsa(signer, skey, input, input_len, + padding_type, out_signature, out_signature_len); + + if (skey->ecdsa != NULL) + return tls_sign_ecdsa(signer, skey, input, input_len, + padding_type, out_signature, out_signature_len); + + tls_error_setx(&signer->error, "unknown key type"); + + return (-1); +} + +static int +tls_rsa_priv_enc(int from_len, const unsigned char *from, unsigned char *to, + RSA *rsa, int rsa_padding) +{ + struct tls_config *config; + uint8_t *signature = NULL; + size_t signature_len = 0; + const char *pubkey_hash; + int padding_type; + + /* + * This function is called via RSA_private_encrypt() and has to conform + * to its calling convention/signature. The caller is required to + * provide a 'to' buffer of at least RSA_size() bytes. + */ + + pubkey_hash = RSA_get_ex_data(rsa, 0); + config = RSA_get_ex_data(rsa, 1); + + if (pubkey_hash == NULL || config == NULL) + goto err; + + if (rsa_padding == RSA_NO_PADDING) { + padding_type = TLS_PADDING_NONE; + } else if (rsa_padding == RSA_PKCS1_PADDING) { + padding_type = TLS_PADDING_RSA_PKCS1; + } else { + goto err; + } + + if (from_len < 0) + goto err; + + if (config->sign_cb(config->sign_cb_arg, pubkey_hash, from, from_len, + padding_type, &signature, &signature_len) == -1) + goto err; + + if (signature_len > INT_MAX || (int)signature_len > RSA_size(rsa)) + goto err; + + memcpy(to, signature, signature_len); + free(signature); + + return ((int)signature_len); + + err: + free(signature); + + return (-1); +} + +RSA_METHOD * +tls_signer_rsa_method(void) +{ + static RSA_METHOD *rsa_method = NULL; + + pthread_mutex_lock(&signer_method_lock); + + if (rsa_method != NULL) + goto out; + + rsa_method = RSA_meth_new("libtls RSA method", 0); + if (rsa_method == NULL) + goto out; + + RSA_meth_set_priv_enc(rsa_method, tls_rsa_priv_enc); + + out: + pthread_mutex_unlock(&signer_method_lock); + + return (rsa_method); +} + +static ECDSA_SIG * +tls_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, + const BIGNUM *rp, EC_KEY *eckey) +{ + struct tls_config *config; + ECDSA_SIG *ecdsa_sig = NULL; + uint8_t *signature = NULL; + size_t signature_len = 0; + const unsigned char *p; + const char *pubkey_hash; + + /* + * This function is called via ECDSA_do_sign_ex() and has to conform + * to its calling convention/signature. + */ + + pubkey_hash = EC_KEY_get_ex_data(eckey, 0); + config = EC_KEY_get_ex_data(eckey, 1); + + if (pubkey_hash == NULL || config == NULL) + goto err; + + if (dgst_len < 0) + goto err; + + if (config->sign_cb(config->sign_cb_arg, pubkey_hash, dgst, dgst_len, + TLS_PADDING_NONE, &signature, &signature_len) == -1) + goto err; + + p = signature; + if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &p, signature_len)) == NULL) + goto err; + + free(signature); + + return (ecdsa_sig); + + err: + free(signature); + + return (NULL); +} + +EC_KEY_METHOD * +tls_signer_ecdsa_method(void) +{ + static EC_KEY_METHOD *ecdsa_method = NULL; + const EC_KEY_METHOD *default_method; + int (*sign)(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey); + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp); + + pthread_mutex_lock(&signer_method_lock); + + if (ecdsa_method != NULL) + goto out; + + default_method = EC_KEY_get_default_method(); + ecdsa_method = EC_KEY_METHOD_new(default_method); + if (ecdsa_method == NULL) + goto out; + + EC_KEY_METHOD_get_sign(default_method, &sign, &sign_setup, NULL); + EC_KEY_METHOD_set_sign(ecdsa_method, sign, sign_setup, + tls_ecdsa_do_sign); + + out: + pthread_mutex_unlock(&signer_method_lock); + + return (ecdsa_method); +} diff --git a/Libraries/libressl/tls/tls_util.c b/Libraries/libressl/tls/tls_util.c new file mode 100644 index 000000000..b276d2cfa --- /dev/null +++ b/Libraries/libressl/tls/tls_util.c @@ -0,0 +1,226 @@ +/* $OpenBSD: tls_util.c,v 1.16 2023/05/14 07:26:25 op Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * Copyright (c) 2014 Ted Unangst + * Copyright (c) 2015 Reyk Floeter + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include + +#include "tls.h" +#include "tls_internal.h" + +static void * +memdup(const void *in, size_t len) +{ + void *out; + + if ((out = malloc(len)) == NULL) + return NULL; + memcpy(out, in, len); + return out; +} + +int +tls_set_mem(char **dest, size_t *destlen, const void *src, size_t srclen) +{ + free(*dest); + *dest = NULL; + *destlen = 0; + if (src != NULL) { + if ((*dest = memdup(src, srclen)) == NULL) + return -1; + *destlen = srclen; + } + return 0; +} + +int +tls_set_string(const char **dest, const char *src) +{ + free((char *)*dest); + *dest = NULL; + if (src != NULL) + if ((*dest = strdup(src)) == NULL) + return -1; + return 0; +} + +/* + * Extract the host and port from a colon separated value. For a literal IPv6 + * address the address must be contained with square braces. If a host and + * port are successfully extracted, the function will return 0 and the + * caller is responsible for freeing the host and port. If no port is found + * then the function will return 1, with both host and port being NULL. + * On memory allocation failure -1 will be returned. + */ +int +tls_host_port(const char *hostport, char **host, char **port) +{ + char *h, *p, *s; + int rv = 1; + + *host = NULL; + *port = NULL; + + if ((s = strdup(hostport)) == NULL) + goto err; + + h = p = s; + + /* See if this is an IPv6 literal with square braces. */ + if (p[0] == '[') { + h++; + if ((p = strchr(s, ']')) == NULL) + goto done; + *p++ = '\0'; + } + + /* Find the port separator. */ + if ((p = strchr(p, ':')) == NULL) + goto done; + + /* If there is another separator then we have issues. */ + if (strchr(p + 1, ':') != NULL) + goto done; + + *p++ = '\0'; + + if (asprintf(host, "%s", h) == -1) { + *host = NULL; + goto err; + } + if (asprintf(port, "%s", p) == -1) { + *port = NULL; + goto err; + } + + rv = 0; + goto done; + + err: + free(*host); + *host = NULL; + free(*port); + *port = NULL; + rv = -1; + + done: + free(s); + + return (rv); +} + +int +tls_password_cb(char *buf, int size, int rwflag, void *u) +{ + size_t len; + + if (size < 0) + return (0); + + if (u == NULL) { + memset(buf, 0, size); + return (0); + } + + if ((len = strlcpy(buf, u, size)) >= (size_t)size) + return (0); + + return (len); +} + +uint8_t * +tls_load_file(const char *name, size_t *len, char *password) +{ + FILE *fp; + EVP_PKEY *key = NULL; + BIO *bio = NULL; + char *data; + uint8_t *buf = NULL; + struct stat st; + size_t size = 0; + int fd = -1; + ssize_t n; + + *len = 0; + + if ((fd = open(name, O_RDONLY)) == -1) + return (NULL); + + /* Just load the file into memory without decryption */ + if (password == NULL) { + if (fstat(fd, &st) != 0) + goto err; + if (st.st_size < 0) + goto err; + size = (size_t)st.st_size; + if ((buf = malloc(size)) == NULL) + goto err; + n = read(fd, buf, size); + if (n < 0 || (size_t)n != size) + goto err; + close(fd); + goto done; + } + + /* Or read the (possibly) encrypted key from file */ + if ((fp = fdopen(fd, "r")) == NULL) + goto err; + fd = -1; + + key = PEM_read_PrivateKey(fp, NULL, tls_password_cb, password); + fclose(fp); + if (key == NULL) + goto err; + + /* Write unencrypted key to memory buffer */ + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto err; + if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) + goto err; + if ((size = BIO_get_mem_data(bio, &data)) <= 0) + goto err; + if ((buf = malloc(size)) == NULL) + goto err; + memcpy(buf, data, size); + + BIO_free_all(bio); + EVP_PKEY_free(key); + + done: + *len = size; + return (buf); + + err: + if (fd != -1) + close(fd); + freezero(buf, size); + BIO_free_all(bio); + EVP_PKEY_free(key); + + return (NULL); +} + +void +tls_unload_file(uint8_t *buf, size_t len) +{ + freezero(buf, len); +} diff --git a/Libraries/libressl/tls/tls_verify.c b/Libraries/libressl/tls/tls_verify.c new file mode 100644 index 000000000..c588f027c --- /dev/null +++ b/Libraries/libressl/tls/tls_verify.c @@ -0,0 +1,331 @@ +/* $OpenBSD: tls_verify.c,v 1.28 2023/06/01 07:32:25 tb Exp $ */ +/* + * Copyright (c) 2014 Jeremie Courreges-Anglas + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include + +#include + +#include +#include "tls_internal.h" + +static int +tls_match_name(const char *cert_name, const char *name) +{ + const char *cert_domain, *domain, *next_dot; + + if (strcasecmp(cert_name, name) == 0) + return 0; + + /* Wildcard match? */ + if (cert_name[0] == '*') { + /* + * Valid wildcards: + * - "*.domain.tld" + * - "*.sub.domain.tld" + * - etc. + * Reject "*.tld". + * No attempt to prevent the use of eg. "*.co.uk". + */ + cert_domain = &cert_name[1]; + /* Disallow "*" */ + if (cert_domain[0] == '\0') + return -1; + /* Disallow "*foo" */ + if (cert_domain[0] != '.') + return -1; + /* Disallow "*.." */ + if (cert_domain[1] == '.') + return -1; + next_dot = strchr(&cert_domain[1], '.'); + /* Disallow "*.bar" */ + if (next_dot == NULL) + return -1; + /* Disallow "*.bar.." */ + if (next_dot[1] == '.') + return -1; + + domain = strchr(name, '.'); + + /* No wildcard match against a name with no host part. */ + if (name[0] == '.') + return -1; + /* No wildcard match against a name with no domain part. */ + if (domain == NULL || strlen(domain) == 1) + return -1; + + if (strcasecmp(cert_domain, domain) == 0) + return 0; + } + + return -1; +} + +/* + * See RFC 5280 section 4.2.1.6 for SubjectAltName details. + * alt_match is set to 1 if a matching alternate name is found. + * alt_exists is set to 1 if any known alternate name exists in the certificate. + */ +static int +tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name, + int *alt_match, int *alt_exists) +{ + STACK_OF(GENERAL_NAME) *altname_stack = NULL; + union tls_addr addrbuf; + int addrlen, type; + int count, i; + int critical = 0; + int rv = -1; + + *alt_match = 0; + *alt_exists = 0; + + altname_stack = X509_get_ext_d2i(cert, NID_subject_alt_name, &critical, + NULL); + if (altname_stack == NULL) { + if (critical != -1) { + tls_set_errorx(ctx, "error decoding subjectAltName"); + goto err; + } + goto done; + } + + if (inet_pton(AF_INET, name, &addrbuf) == 1) { + type = GEN_IPADD; + addrlen = 4; + } else if (inet_pton(AF_INET6, name, &addrbuf) == 1) { + type = GEN_IPADD; + addrlen = 16; + } else { + type = GEN_DNS; + addrlen = 0; + } + + count = sk_GENERAL_NAME_num(altname_stack); + for (i = 0; i < count; i++) { + GENERAL_NAME *altname; + + altname = sk_GENERAL_NAME_value(altname_stack, i); + + if (altname->type == GEN_DNS || altname->type == GEN_IPADD) + *alt_exists = 1; + + if (altname->type != type) + continue; + + if (type == GEN_DNS) { + const unsigned char *data; + int format, len; + + format = ASN1_STRING_type(altname->d.dNSName); + if (format == V_ASN1_IA5STRING) { + data = ASN1_STRING_get0_data(altname->d.dNSName); + len = ASN1_STRING_length(altname->d.dNSName); + + if (len < 0 || (size_t)len != strlen(data)) { + tls_set_errorx(ctx, + "error verifying name '%s': " + "NUL byte in subjectAltName, " + "probably a malicious certificate", + name); + goto err; + } + + /* + * Per RFC 5280 section 4.2.1.6: + * " " is a legal domain name, but that + * dNSName must be rejected. + */ + if (strcmp(data, " ") == 0) { + tls_set_errorx(ctx, + "error verifying name '%s': " + "a dNSName of \" \" must not be " + "used", name); + goto err; + } + + if (tls_match_name(data, name) == 0) { + *alt_match = 1; + goto done; + } + } else { +#ifdef DEBUG + fprintf(stdout, "%s: unhandled subjectAltName " + "dNSName encoding (%d)\n", getprogname(), + format); +#endif + } + + } else if (type == GEN_IPADD) { + const unsigned char *data; + int datalen; + + datalen = ASN1_STRING_length(altname->d.iPAddress); + data = ASN1_STRING_get0_data(altname->d.iPAddress); + + if (datalen < 0) { + tls_set_errorx(ctx, + "Unexpected negative length for an " + "IP address: %d", datalen); + goto err; + } + + /* + * Per RFC 5280 section 4.2.1.6: + * IPv4 must use 4 octets and IPv6 must use 16 octets. + */ + if (datalen == addrlen && + memcmp(data, &addrbuf, addrlen) == 0) { + *alt_match = 1; + goto done; + } + } + } + + done: + rv = 0; + + err: + sk_GENERAL_NAME_pop_free(altname_stack, GENERAL_NAME_free); + return rv; +} + +static int +tls_check_common_name(struct tls *ctx, X509 *cert, const char *name, + int *cn_match) +{ + unsigned char *utf8_bytes = NULL; + X509_NAME *subject_name; + char *common_name = NULL; + union tls_addr addrbuf; + int common_name_len; + ASN1_STRING *data; + int lastpos = -1; + int rv = -1; + + *cn_match = 0; + + subject_name = X509_get_subject_name(cert); + if (subject_name == NULL) + goto done; + + lastpos = X509_NAME_get_index_by_NID(subject_name, + NID_commonName, lastpos); + if (lastpos == -1) + goto done; + if (lastpos < 0) + goto err; + if (X509_NAME_get_index_by_NID(subject_name, NID_commonName, lastpos) + != -1) { + /* + * Having multiple CN's is possible, and even happened back in + * the glory days of mullets and Hammer pants. In anything like + * a modern TLS cert, CN is as close to deprecated as it gets, + * and having more than one is bad. We therefore fail if we have + * more than one CN fed to us in the subject, treating the + * certificate as hostile. + */ + tls_set_errorx(ctx, "error verifying name '%s': " + "Certificate subject contains mutiple Common Name fields, " + "probably a malicious or malformed certificate", name); + goto err; + } + + data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, + lastpos)); + /* + * Fail if we cannot encode the CN bytes as UTF-8. + */ + if ((common_name_len = ASN1_STRING_to_UTF8(&utf8_bytes, data)) < 0) { + tls_set_errorx(ctx, "error verifying name '%s': " + "Common Name field cannot be encoded as a UTF-8 string, " + "probably a malicious certificate", name); + goto err; + } + /* + * Fail if the CN is of invalid length. RFC 5280 specifies that a CN + * must be between 1 and 64 bytes long. + */ + if (common_name_len < 1 || common_name_len > 64) { + tls_set_errorx(ctx, "error verifying name '%s': " + "Common Name field has invalid length, " + "probably a malicious certificate", name); + goto err; + } + /* + * Fail if the resulting text contains a NUL byte. + */ + if (memchr(utf8_bytes, 0, common_name_len) != NULL) { + tls_set_errorx(ctx, "error verifying name '%s': " + "NUL byte in Common Name field, " + "probably a malicious certificate", name); + goto err; + } + + common_name = strndup(utf8_bytes, common_name_len); + if (common_name == NULL) { + tls_set_error(ctx, "out of memory"); + goto err; + } + + /* + * We don't want to attempt wildcard matching against IP addresses, + * so perform a simple comparison here. + */ + if (inet_pton(AF_INET, name, &addrbuf) == 1 || + inet_pton(AF_INET6, name, &addrbuf) == 1) { + if (strcmp(common_name, name) == 0) + *cn_match = 1; + goto done; + } + + if (tls_match_name(common_name, name) == 0) + *cn_match = 1; + + done: + rv = 0; + + err: + free(utf8_bytes); + free(common_name); + return rv; +} + +int +tls_check_name(struct tls *ctx, X509 *cert, const char *name, int *match) +{ + int alt_exists; + + *match = 0; + + if (tls_check_subject_altname(ctx, cert, name, match, + &alt_exists) == -1) + return -1; + + /* + * As per RFC 6125 section 6.4.4, if any known alternate name existed + * in the certificate, we do not attempt to match on the CN. + */ + if (*match || alt_exists) + return 0; + + return tls_check_common_name(ctx, cert, name, match); +} diff --git a/Libraries/libressl/x509v3.cnf b/Libraries/libressl/x509v3.cnf new file mode 100644 index 000000000..d12d73285 --- /dev/null +++ b/Libraries/libressl/x509v3.cnf @@ -0,0 +1,29 @@ +# default settings +CERTPATHLEN = 1 +CERTUSAGE = digitalSignature,keyCertSign,cRLSign +EXTCERTUSAGE = serverAuth,clientAuth +CERTIP = 0.0.0.0 +CERTFQDN = nohost.nodomain + +# This section should be referenced when building an x509v3 CA +# Certificate. +# The default path length and the key usage can be overridden +# modified by setting the CERTPATHLEN and CERTUSAGE environment +# variables. +[x509v3_CA] +basicConstraints=critical,CA:true,pathlen:$ENV::CERTPATHLEN +keyUsage=$ENV::CERTUSAGE + +# This section should be referenced to add an IP Address +# as an alternate subject name, needed by isakmpd +# The address must be provided in the CERTIP environment variable +[x509v3_IPAddr] +subjectAltName=IP:$ENV::CERTIP +extendedKeyUsage=$ENV::EXTCERTUSAGE + +# This section should be referenced to add a FQDN hostname +# as an alternate subject name, needed by isakmpd +# The address must be provided in the CERTFQDN environment variable +[x509v3_FQDN] +subjectAltName=DNS:$ENV::CERTFQDN +extendedKeyUsage=$ENV::EXTCERTUSAGE diff --git a/README.md b/README.md index 7400f3adb..6d0ff66c9 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,4 @@ lib3mf is released under the [BSD license](LICENSE). The library contains code o 3. cpp-base64 2.rc.08, https://github.com/ReneNyffenegger/cpp-base64/blob/master/LICENSE 4. fast-float v6.0.0, https://github.com/fastfloat/fast_float/tree/v6.0.0?tab=License-3-ov-file -In addition, the automated tests of lib3mf make use of LibReSSL 3.0.2, [License](Tests/libressl/COPYING). +In addition, the automated tests of lib3mf make uses of LibReSSL 3.8.2, [License](https://github.com/libressl/openbsd/blob/master/src/lib/libssl/LICENSE) and googletest 1.14.0 [License](https://github.com/google/googletest/blob/main/LICENSE). diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 066a72c92..e4352882a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -3,11 +3,16 @@ enable_testing() if (USE_INCLUDED_SSL) SET(LIBRESSL_APPS OFF CACHE BOOL "" FORCE) SET(LIBRESSL_TESTS OFF CACHE BOOL "" FORCE) - ADD_SUBDIRECTORY (libressl EXCLUDE_FROM_ALL) - SET_TARGET_PROPERTIES (ssl PROPERTIES FOLDER LibreSSL) - SET_TARGET_PROPERTIES (crypto PROPERTIES FOLDER LibreSSL) + SET(ENABLE_ASM OFF CACHE BOOL "" FORCE) + SET(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "" FORCE) + ADD_SUBDIRECTORY(./../Libraries/libressl ${CMAKE_CURRENT_BINARY_DIR}/libressl EXCLUDE_FROM_ALL) + SET_TARGET_PROPERTIES(ssl PROPERTIES FOLDER LibreSSL) + SET_TARGET_PROPERTIES(crypto PROPERTIES FOLDER LibreSSL) + SET_TARGET_PROPERTIES(ssl_obj PROPERTIES FOLDER LibreSSL) + SET_TARGET_PROPERTIES(crypto_obj PROPERTIES FOLDER LibreSSL) endif() + add_definitions( -DTESTFILESPATH="${CMAKE_CURRENT_SOURCE_DIR}/TestFiles/") add_definitions( -DLTESTFILESPATH=L"${CMAKE_CURRENT_SOURCE_DIR}/TestFiles/") add_definitions( -DLOUTFILESPATH=L"${CMAKE_BINARY_DIR}/") diff --git a/Tests/CPP_Bindings/CMakeLists.txt b/Tests/CPP_Bindings/CMakeLists.txt index 97f74286d..89aa33ae8 100644 --- a/Tests/CPP_Bindings/CMakeLists.txt +++ b/Tests/CPP_Bindings/CMakeLists.txt @@ -44,32 +44,24 @@ add_executable(${TESTNAME} ${SRCS_UNITTEST} ${GTEST_SRC_FILES}) set(STARTUPPROJECT ${TESTNAME}) -if (WIN32) - target_compile_options(${TESTNAME} PUBLIC "$<$:/Od;/Ob0;/sdl;/W3;/WX;/FC;/MDd;/wd4996>") - target_compile_options(${TESTNAME} PUBLIC "$<$:/O2;/sdl;/WX;/Oi;/Gy;/FC;/MD;/wd4996>") -endif() - -add_dependencies(${TESTNAME} ssl) -add_dependencies(${TESTNAME} crypto) - target_include_directories(${TESTNAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include ${CMAKE_SOURCE_DIR}/Libraries/googletest/Include - ${CMAKE_CURRENT_SOURCE_DIR}/../libressl/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../Libraries/libressl/include ${CMAKE_CURRENT_SOURCE_DIR_AUTOGENERATED}/Bindings/Cpp ) # pthreads Needed for googletest if (LINUX) - set(THREADS_PREFER_PTHREAD_FLAG ON) - find_package(Threads REQUIRED) - target_link_libraries(${TESTNAME} PRIVATE Threads::Threads) +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(${TESTNAME} PRIVATE Threads::Threads) endif() target_link_libraries(${TESTNAME} PRIVATE ${PROJECT_NAME} ssl crypto) if (WIN32) - target_link_libraries(${TESTNAME} PRIVATE ws2_32) +target_link_libraries(${TESTNAME} PRIVATE ws2_32) endif() diff --git a/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp b/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp index 1ac8db3be..45a5f7458 100644 --- a/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp +++ b/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp @@ -288,7 +288,8 @@ void EncryptionCallbacks::keyDecryptClientCallback( || Lib3MF::eDigestMethod::SHA1 != ar.GetDigestMethod()) *status = 0; else if (nullptr == plainBuffer || 0 == plainSize) { - *plainNeeded = 32; + // plainNeeded should be bigger than the plain text size for padding cases to avoid mem leak. + *plainNeeded = RsaMethods::getSize(context->key) - 42; *status = 32; } else { diff --git a/Tests/libressl b/Tests/libressl deleted file mode 160000 index c80f8ed8f..000000000 --- a/Tests/libressl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c80f8ed8f1ce203f7cd86fa0324bfef952c21661 diff --git a/submodules/README.md b/submodules/README.md index 56511dda5..8906a1eb6 100644 --- a/submodules/README.md +++ b/submodules/README.md @@ -4,16 +4,18 @@ There is a bash/batch script that updates the libraries and copies the header an - Bash shell/ Powershell environment - Git installed +- cmake ## Usage To run the script, execute the following command: -.\update_libs.bat +.\update_libs.bat [library_name] or -bash update_libs.sh +bash update_libs.sh [library_name] +- library_name is optional argument. - If no library name is provided, all libraries will be updated. - If a library name is provided, only that library will be updated. @@ -21,3 +23,6 @@ bash update_libs.sh - Libzip - In copying header and source files script, a cmake script is called to generate zip_err_str.c and while configuring CMake of Lib3MF, Libzip needs to be configured as well to generate platfrom specific header files config.h and zipconf.h. +- LibreSSL is not added as a submodule, instead downloaded from https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ and copied to Libraries manually. LibreSSL source and header files integration is complex, hence used cmake to add_subdirectory. + +- AutomaticComponentToolkit is updated using update_act.bat scirpt. \ No newline at end of file From e77162cc1ee6b9be0783a3fc34d08f3ff20a628e Mon Sep 17 00:00:00 2001 From: gangatp Date: Tue, 9 Jan 2024 12:56:41 +0530 Subject: [PATCH 20/54] catching exception for base64decode --- CMakeLists.txt | 1 - Include/Common/NMR_ErrorConst.h | 3 ++ Source/Common/NMR_Exception.cpp | 1 + .../NMR_ModelReaderNode_KeyStoreCEKParams.cpp | 1 + ...MR_ModelReaderNode_KeyStoreCipherValue.cpp | 1 + Tests/CPP_Bindings/Source/SecureContent.cpp | 29 ++++++++++++++++--- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ab053490..10a011314 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,6 @@ set(CMAKE_INSTALL_INCLUDEDIR include/lib3mf CACHE PATH "directory for installing option(USE_INCLUDED_ZLIB "Use included zlib" ON) option(USE_INCLUDED_LIBZIP "Use included libzip" ON) -option(USE_INCLUDED_GTEST "Used included gtest" ON) option(USE_INCLUDED_SSL "Use included libressl" ON) option(BUILD_FOR_CODECOVERAGE "Build for code coverage analysis" OFF) option(STRIP_BINARIES "Strip binaries (on non-apple)" ON) diff --git a/Include/Common/NMR_ErrorConst.h b/Include/Common/NMR_ErrorConst.h index 0d461286a..aaaf60fb8 100644 --- a/Include/Common/NMR_ErrorConst.h +++ b/Include/Common/NMR_ErrorConst.h @@ -1228,6 +1228,9 @@ Model error codes (0x8XXX) // A component resource is invalid #define NMR_ERROR_INVALIDCOMPONENTRESOURCE 0x810D +// A keystore element is not base64 encoded +#define NMR_ERROR_KEYSTOREINVALIDENCODING 0x810E + /*------------------------------------------------------------------- XML Parser Error Constants (0x9XXX) -------------------------------------------------------------------*/ diff --git a/Source/Common/NMR_Exception.cpp b/Source/Common/NMR_Exception.cpp index 0edd80259..6f5187159 100644 --- a/Source/Common/NMR_Exception.cpp +++ b/Source/Common/NMR_Exception.cpp @@ -418,6 +418,7 @@ namespace NMR { case NMR_ERROR_KEYSTOREDUPLICATEACCESSRIGHT: return "An AccessRight already exists for this consumer in a ResourceDataGroup"; case NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAGROUP: return "A resource data group already exist for this keyuuid"; case NMR_ERROR_KEYSTOREINVALIDALGORITHM: return "The algorithm attribute is invalid"; + case NMR_ERROR_KEYSTOREINVALIDENCODING: return "The keystore element value is not base64 encoded."; case NMR_ERROR_KEYSTOREINVALIDCOMPRESSION: return "The KeyStore ResourceData compression is invalid"; case NMR_ERROR_KEYSTOREINVALIDCIPHERVALUE: return "Invalid CipherValue elment value"; case NMR_ERROR_KEYSTOREINVALIDMGF: return "The mfgalgorithm attribute has invalid value"; diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp index 378f4aed7..70552a1b8 100644 --- a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp @@ -131,6 +131,7 @@ namespace NMR { } catch (...) { // base64_decode throws an exception if the input is not valid base64 + m_pWarnings->addException(CNMRException(NMR_ERROR_KEYSTOREINVALIDENCODING), mrwInvalidOptionalValue); } } } diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp index e7a61218d..5b9dcc55e 100644 --- a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp @@ -77,6 +77,7 @@ namespace NMR { } catch (...) { // base64_decode throws an exception if the input is not valid base64 + m_pWarnings->addException(CNMRException(NMR_ERROR_KEYSTOREINVALIDENCODING), NMR::eModelWarningLevel::mrwInvalidMandatoryValue); } } } diff --git a/Tests/CPP_Bindings/Source/SecureContent.cpp b/Tests/CPP_Bindings/Source/SecureContent.cpp index 9d4fe82f4..021db7328 100644 --- a/Tests/CPP_Bindings/Source/SecureContent.cpp +++ b/Tests/CPP_Bindings/Source/SecureContent.cpp @@ -395,7 +395,7 @@ namespace Lib3MF { TEST_F(SecureContentT, ModelReaderKeyStoreNoAttributesWarnings) { PReader reader3MF = readKeyStore(NEGATIVEUNENCRYPTEDKEYSTOREMISSINGATTRIBUTES); - CheckReaderWarnings(reader3MF, 6); + CheckReaderWarnings(reader3MF, 8); Lib3MF_uint32 iWarning = 0; // NMR_ERROR_KEYSTOREMISSINGCONSUMERID @@ -418,21 +418,32 @@ namespace Lib3MF { reader3MF->GetWarning(3, iWarning); ASSERT_EQ(0x8105, iWarning); + // NMR_ERROR_KEYSTOREINVALIDENCODING + // invalid key store element value in ResourceData + reader3MF->GetWarning(4, iWarning); + ASSERT_EQ(0x810E, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDENCODING + // invalid key store element value in ResourceData + reader3MF->GetWarning(5, iWarning); + ASSERT_EQ(0x810E, iWarning); + + // NMR_ERROR_KEYSTOREMISSINGALGORTHM // missing encryptionalgorithm on cekparams - reader3MF->GetWarning(4, iWarning); + reader3MF->GetWarning(6, iWarning); ASSERT_EQ(0x810A, iWarning); // NMR_ERROR_MISSINGUUID //missing guid on keystore - reader3MF->GetWarning(5, iWarning); + reader3MF->GetWarning(7, iWarning); ASSERT_EQ(0x80B0, iWarning); } TEST_F(SecureContentT, ModelReaderKeyStoreInvalidAttributesWarnings) { PReader reader3MF = readKeyStore(NEGATIVEUNENCRYPTEDKEYSTOREINVALIDATTRIBUTES); - CheckReaderWarnings(reader3MF, 8); + CheckReaderWarnings(reader3MF, 10); Lib3MF_uint32 iWarning = 0; // NMR_ERROR_KEYSTOREDUPLICATECONSUMERID @@ -474,6 +485,16 @@ namespace Lib3MF { // invalid compression attribute in ResourceData reader3MF->GetWarning(7, iWarning); ASSERT_EQ(0x80F8, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDENCODING + // invalid key store element value in ResourceData + reader3MF->GetWarning(8, iWarning); + ASSERT_EQ(0x810E, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDENCODING + // invalid key store element value in ResourceData + reader3MF->GetWarning(9, iWarning); + ASSERT_EQ(0x810E, iWarning); } TEST_F(SecureContentT, CheckKeyStoreConsumers) { From e5014c564c0cef17dd8aa56139393952a4fe2b52 Mon Sep 17 00:00:00 2001 From: gangatp <145573667+gangatp@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:10:49 +0530 Subject: [PATCH 21/54] Linux build using ubi8 and gcc12 (#338) * adding docker file * adding dockerfile * giving permissions to cmake file * build ubi8 image * adding destination in artifact * using zip instead of tar * ignoring parent folder while zipping * replacing ubuntu with ubi8 binaries * replacing ubuntu with ubi8 binaries * creating artifacts from ubi8 * fixing lib3mf linux export --- .github/workflows/build.yml | 51 +++++++++++++++++++++----- CI/Dockerfile | 72 +++++++++++++++++++++++++++++++++++-- CI/Dockerfile.ubuntu | 18 ++++++++++ CI/script.sh | 7 ---- 4 files changed, 129 insertions(+), 19 deletions(-) create mode 100644 CI/Dockerfile.ubuntu delete mode 100644 CI/script.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ccfd7a37f..96a237c83 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ on: [push, pull_request] name: Build jobs: - build-linux: + build-linux-memtest: runs-on: ubuntu-20.04 steps: - run: sudo apt update @@ -12,19 +12,53 @@ jobs: - run: sh cmake/GenerateMake.sh - run: cmake --build . --target lib3mf_memcheck working-directory: ./build - - run: ctest -V - working-directory: ./build - - name: Archive Linux binary - uses: actions/upload-artifact@v2 + + build-linux-ubi8-gcc12: + runs-on: ubuntu-20.04 + steps: + - run: sudo apt update + - run: sudo apt install -y uuid-dev + - uses: actions/checkout@v2 with: - name: lib3mf.so - path: build/lib3mf.so.2 + submodules: true + - run: mkdir -p build - run: zip -r build/bindings.zip Autogenerated/Bindings + - name: Archive bindings uses: actions/upload-artifact@v2 with: name: bindings.zip path: build/bindings.zip + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Docker Build + uses: docker/build-push-action@v5 + with: + context: . + file: ./CI/Dockerfile + platforms: linux/amd64 + tags: lib3mf_ubi8:latest + load: true + - + name: Docker Extract + uses: shrink/actions-docker-extract@v3.0.0 + id: extract + with: + image: lib3mf_ubi8:latest + path: out.zip + destination: dist + + - run: unzip out.zip + working-directory: ./dist + - + name: Upload Artifact + uses: actions/upload-artifact@v2 + with: + name: lib3mf.so + path: dist/lib3mf.so.2 + build-macos: runs-on: macos-latest steps: @@ -41,7 +75,6 @@ jobs: with: name: lib3mf.dylib path: build/lib3mf.dylib - codecoverage-macos: runs-on: macos-latest steps: @@ -141,7 +174,7 @@ jobs: working-directory: ./build assemble-sdk: runs-on: ubuntu-20.04 - needs: [build-windows-release, build-linux, build-macos] + needs: [build-windows-release, build-macos, build-linux-ubi8-gcc12] steps: - run: sudo apt install -y zip unzip - run: mkdir build diff --git a/CI/Dockerfile b/CI/Dockerfile index 3f5d7d56a..846332f66 100644 --- a/CI/Dockerfile +++ b/CI/Dockerfile @@ -1,4 +1,70 @@ -FROM martinweismann/lib3mf_ppcbuilds:latest +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest + +LABEL maintainer="pradeep.gangatharan@autodesk.com" + +ENV GCCTOOLSET=gcc-toolset-12 + +RUN \ + microdnf update -y && \ + microdnf -y install --nodocs \ + wget \ + which \ + libuuid-devel \ + glibc-langpack-en \ + tar \ + gzip \ + zip \ + ${GCCTOOLSET} \ + && microdnf clean all + +ENV LD_LIBRARY_PATH=/opt/rh/${GCCTOOLSET}/root/usr/lib64:/opt/rh/${GCCTOOLSET}/root/usr/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +ENV PKG_CONFIG_PATH=/opt/rh/${GCCTOOLSET}/root/usr/lib64/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}} +ENV PATH=/opt/rh/${GCCTOOLSET}/root/usr/bin${PATH:+:${PATH}} + +# CMake +ARG CMAKE_VERSION=3.28.1 +ADD "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz" /usr/tmp/ +RUN tar xzf /usr/tmp/cmake-$CMAKE_VERSION-linux-x86_64.tar.gz -C /opt && rm /usr/tmp/cmake-$CMAKE_VERSION-linux-x86_64.tar.gz +ENV PATH /opt/cmake-$CMAKE_VERSION-linux-x86_64/bin:${PATH} + + +RUN ln -s /opt/cmake-$CMAKE_VERSION-linux-x86_64/bin/cmake /usr/bin/cmake3 +RUN ln -s /opt/cmake-$CMAKE_VERSION-linux-x86_64/bin/cpack /usr/bin/cpack3 +RUN ln -s /opt/cmake-$CMAKE_VERSION-linux-x86_64/bin/ctest /usr/bin/ctest3 + + +RUN ldd --version +RUN cmake --version +RUN cmake3 --version +RUN gcc --version + + ADD . lib3mf-repo -ADD CI/script.sh script.sh -ENTRYPOINT ["sh", "script.sh"] + +WORKDIR "/lib3mf-repo" + +RUN chmod +x cmake/GenerateMake.sh + +RUN cmake/GenerateMake.sh + +WORKDIR "/lib3mf-repo/build" + +RUN cmake --build . + +RUN ctest -V . + +WORKDIR "/../../" + +RUN mkdir -p out + +RUN cp ./lib3mf-repo/build/lib3mf.so.2 ./out/ + +RUN cd out && zip -r ../out.zip . + + + + + + + + diff --git a/CI/Dockerfile.ubuntu b/CI/Dockerfile.ubuntu new file mode 100644 index 000000000..94dec0242 --- /dev/null +++ b/CI/Dockerfile.ubuntu @@ -0,0 +1,18 @@ +# Copy this to root folder of lib3mf then build and run this image. +FROM ubuntu:20.04 + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install build-essential uuid-dev wget + +RUN wget -qO- "https://cmake.org/files/v3.28/cmake-3.28.1-linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local + +ADD . lib3mf-repo + +WORKDIR "/lib3mf-repo" + +RUN cmake/GenerateMake.sh + +WORKDIR "/lib3mf-repo/build" + +RUN cmake --build . + +RUN ctest -V . diff --git a/CI/script.sh b/CI/script.sh deleted file mode 100644 index 389ab6362..000000000 --- a/CI/script.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -cd lib3mf-repo -sh cmake/GenerateMakeFast.sh -cd build -make -j1 -ctest -V . From 8ceec9c12d7bff04202dd5df3c4c82267d4e5a45 Mon Sep 17 00:00:00 2001 From: gangatp <145573667+gangatp@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:13:12 +0530 Subject: [PATCH 22/54] fixing fast float stod conversion according to ST_Number schema specification (#339) * fixing stod conversion according to schema * spaces to tabs * adding test case * adding test case for leading plus sign double conversion * refactoring --- CMakeLists.txt | 3 +++ Source/Common/NMR_StringUtils.cpp | 8 +++++++- Tests/CPP_Bindings/Source/Reader.cpp | 17 +++++++++++++++++ Tests/TestFiles/Reader/N_XXX_0422_01.3mf | Bin 0 -> 1308 bytes Tests/TestFiles/Reader/P_XXM_0519_01.3mf | Bin 0 -> 427940 bytes 5 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Tests/TestFiles/Reader/N_XXX_0422_01.3mf create mode 100644 Tests/TestFiles/Reader/P_XXM_0519_01.3mf diff --git a/CMakeLists.txt b/CMakeLists.txt index 10a011314..fe8004a5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,9 @@ file(GLOB list(FILTER LIBS_INCLUDE EXCLUDE REGEX "zlib|libzip|libressl") target_include_directories(${PROJECT_NAME} PRIVATE ${LIBS_INCLUDE}) +# allow FASTFLOAT_ALLOWS_LEADING_PLUS +add_definitions(-DFASTFLOAT_ALLOWS_LEADING_PLUS=1) + target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR_AUTOGENERATED}/Source) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include/API) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include) diff --git a/Source/Common/NMR_StringUtils.cpp b/Source/Common/NMR_StringUtils.cpp index 63166d6e8..7c663e492 100644 --- a/Source/Common/NMR_StringUtils.cpp +++ b/Source/Common/NMR_StringUtils.cpp @@ -161,7 +161,13 @@ namespace NMR { { throw CNMRException(NMR_ERROR_EMPTYSTRINGTODOUBLECONVERSION); } - + else if (answer.ptr) // Invalidate comma as decimal separator + { + if (answer.ptr[0] == ',') + { + throw CNMRException(NMR_ERROR_INVALIDSTRINGTODOUBLECONVERSION); + } + } if ((dResult == HUGE_VAL) || (dResult == -HUGE_VAL)) throw CNMRException(NMR_ERROR_STRINGTODOUBLECONVERSIONOUTOFRANGE); diff --git a/Tests/CPP_Bindings/Source/Reader.cpp b/Tests/CPP_Bindings/Source/Reader.cpp index fa2c81b89..03e4b4698 100644 --- a/Tests/CPP_Bindings/Source/Reader.cpp +++ b/Tests/CPP_Bindings/Source/Reader.cpp @@ -149,4 +149,21 @@ namespace Lib3MF auto reader = model->QueryReader("3mf"); ASSERT_SPECIFIC_THROW(reader->ReadFromFile(sTestFilesPath + "/Reader/" + "GEN-M-ADA-ITEM-TRANSFORM-0.3mf"), ELib3MFException); } + + + TEST_F(Reader, ReadVerticesCommaSeparatedValue) { + // This file N_XXX_0422_01.3mf contains vertices with comma-separated values. + // The 3MFReader should throw an error at NMR_StringUtils::fnStringToDouble when reading this file because + // comma-separated values are not allowed in 3MF files. + auto reader = model->QueryReader("3mf"); + ASSERT_SPECIFIC_THROW(reader->ReadFromFile(sTestFilesPath + "/Reader/" + "N_XXX_0422_01.3mf"), ELib3MFException); + } + + TEST_F(Reader, ReadVerticesWithLeadingPLUSSign) { + // This file P_XXM_0519_01.3mf contains vertices with leading + sign e.g +1E+2. + // The 3MFReader allows leading = sign at NMR_StringUtils::fnStringToDouble when reading this file. + auto reader = model->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/Reader/" + "P_XXM_0519_01.3mf"); + CheckReaderWarnings(Reader::reader3MF, 0); + } } diff --git a/Tests/TestFiles/Reader/N_XXX_0422_01.3mf b/Tests/TestFiles/Reader/N_XXX_0422_01.3mf new file mode 100644 index 0000000000000000000000000000000000000000..b10793a279d7d7408d1de47e6868fd465146bc25 GIT binary patch literal 1308 zcmWIWW@Zs#;Nak3Seqc~%YX#9f$aFA)SO~{JrJ4Nf7^@2kf-fE>-~jK?w#ymR@zjW z?{XtLQeI)pOlH5ym&(Lzt2Z}2NYZ1ntgZid_n&d@yE9AIY00&%V?Qorvd*Zw!hYX9 z+osjMDwmcWl5$*+7`;7hz`)6xJm1f0W zDA}oC=__(;703hH#^6>L$9?C0X-(i$iNVQ)9V626~-?5 z#woe^DXBSnU~=u$(|NZI1YEzf{^Dm|7o}jPsogc%p-8~u#k#v&s+*@BGvv05nPl{) zuGW3pTsKcy509;iuCLDQRcT-RCokP3=OX*loP(1#CNyj-nYyW;b@k({lCugfnc6Go z9&L&|{w_`4{>ib>6^#kfT-*8zi%(Z-T+c|6kPfX9zoXUXon8?onfZFEPV!q#E&aLf zc7mSAjSYtv+6wvU#~)jg~z#XPon|uiR%m5B*$`W!zT1_TdLl1$oB5Vyg?!`756H zuu0I^d&}k1sWjgs@)AmCQXM1?HZ#9gy6|qr)qkZLL4{lO4Q1H*n)7}NpXOMlC6Vi) zJ*j7(`pHFWrtkPswx7c->+C#3_xQxWNpB4NmP>|)KfY@7F2TL%krRj2$G`XAy>II5 z?y0H~_-D6ES?|}w_lwU*$glZ(|G~W3W*-g|{c|&Va#4F%;IEoxbL<*&owRti37_)G zx}+9-e%IT8Oz+ObE2-W~53g9`9LslkSJuik>ZMnME+<~uviR$<&hiyYoWI6~Un`u! zSFF(%IN2}nOR0v{Yp-)DA9m{GuF77{@NCc8CCige$A{gniPVm@RS$7t)-Bc9f6-ey z?3}dGl^6rYNAbS>J2m&-yR*dLtlp$&wxaFdGN)SF-&{D=q(1o7Uq(<;((BHC&CA5V z(9e!9DG39UQnYh^UP)?RNqk6UL27ZVUPW$B>jcNF!=TjEde1Q%DCB=Akj#4l`n z4=D8K24<=(DfGynKQUN?#jDKt^Z!5W`|V?z!qd+jb(Q+E?(LVv|9`I3|5efPGSO;| zn{m0_@Ti`|f-Q!MokmAx8dA@0_DtBH==S+m>HA}DNh*0e(lR`QSJ^*gS)Km1Qt;)m zQ!l#1j?dotiH%pYGQH8&JYDL&$65WQQ_r6b7Mp&mTVjjR|0E}wi}nv%_P^O~$goy8 zB5w2IofG%6*(_3-^*H_>$?I|&p42;jzyH97*kS=m5}n1OHykoIE%@c?=h B4DtW~ literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Reader/P_XXM_0519_01.3mf b/Tests/TestFiles/Reader/P_XXM_0519_01.3mf new file mode 100644 index 0000000000000000000000000000000000000000..cf19de339131f1762e6dd4a9c27a219f8e87d4fd GIT binary patch literal 427940 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

`s;2#mZ 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

4veY@hheGg7(?aPRAUyumok8@tF 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

eD5bT`MR^zgRPh0K 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


t7Y=2rNhefG2Mr)#2Vdu$I=<+IaUN<2mP(>0A{f zXU){^r#&oux#E2`9hjAx$G*xiTppO+szf+nt~AE{G%?!{*~vR7xDbI(nOl&+_S?O zz(y=VBo{hey``)~0uJ9YPtA$NV_y$CQcmYp3{+}ILrxj24w|M-KT&vG zg#|W5g!+&^WB8xKtxu@hN1+WS*4|-mUnSxPd*pOn@Hy+$nl$ST3M)x2-ezm57w3|B z426AgqlNrDrlGu%MmIBz4{gJMJ(nlkS0^KstdY>FX{$2-0O1+bF0M`G z(?h4(+x2Uif7SEC`jhMiX|h~fNpmHXHn2>S0G@P=c+YS$c9yGG{cbn`pt*beo+L{o|38M(z8yTdaM0r*>(JowBPe;uu$;IX}y-PH%2*$`*BlCwm*FO~>0z0!CpwgyBQZu4DvV{Eu^1JPB$rPkWl}9}a7$*51FX;% z$jY{G7oNW7=~=S|wwNuQ(p&}@8^IfYD)&ntg3v%m_K1>H+{Q-91cCQedt{!zfYj^o zi_9VP{RG|4s7QcFutT^UjzBEK*C(}XlZyAYFrB3R)5C2o^~vOoOe)3OWMh)sxiBWhC!>Zejq)70LMH z#u_}9j{?OnpBVr)!_T&BmZTRlk*r&K7?Su}(KNGSLY2Y69N_xb2Q{vvp=u<-xn48! zwm$Im_pZOfzA6_?EH7IOe&HuMtzBnEw!DbAQIYcljG8Laarc(YQI@u5Z-zb~SVDfy zty>ij!C}xJPhHI*YvM0z6v#UhUcM287fZF)gMi1u}(+!j+!H7ZW=AvIP}FOOSx}+J3#ocUHbT`*JM)b*21c0FSurJx)Dq&8dN_2kxGw zJX|KVI-MH!HH~G`wN2^H5<~MZqOk4ttsBJDZ$aBS7^EM+i};v&WBS(vdwHhMA-mCS zXS29ri33T!4O`OnJLa7>vqvZyVL8gT(AOnOb57DaVL0xM*)(WvR7(ZivRb|v#LbBz zZ%m%w&bBn0A2`P;x@J&74jZ@kSXNqJ*$*;1%Re@D#tOd-zUQY}p4#_Vw{r;7uq5Uu z1mv%#M+Ui^ntGe1baz)1=(=sH+G_hs70R?Hfu4gL)@JL$JBMv?p|9&!(Y3#mDwh~% z+H!qBBd6g}+jz@Q@Xeu>;GXAD0JqFOR5j<<>Q_<^l^vt`NylzE zt}j!Q$DSgaI+UW>Bp5r~C{TSs6|^ZmU}UPi_$bbM);fEO=OKGJ5n>uvXAbl9X|@$(>yFR`}pFwf$uM6{{WWK0km=aAoQ-U zOVd+Jzc*J`4>iG6A2%fR`@W0xttwVfjj1o0F^0bJd&7PdD6rk!Br5jgG#1-KDiP40 z#lE%GY8t$9Y!m5s2_pXh9ApfiP_>m7y<-BbWVI3}mG7h70=EeBLP3mwKe|FzU>(0a>%^B@nD};2d&#)+Cp5Be7W| z=O+qBQ&}rFsy6AM{X@jM^~9{kc|5HAsEVp{?~2Bj?rHNS#O))TXL&4sf{WX!qmO@< zNjbpuKDCt6$VN-xka+8g>8A^$IY_xA@$&DG7oz6?epTn5J=SHNmrsgcl=9(vS5bK+ zfq!kZgJ&DBd1t3%%Heo8lFvhcfyZ^ z9xeFU;~Q@Xcuw7dZdSd#Vf(8{bIgoR0q=p_)|bNn0EAlq0L4!f!QkHu#}o_xy7u-} zK24kh??~iz^aHCL0bihg4AOoR{>}axweXd??76rh<%p5?yV(f;09`x(01Emj;0`{$ z^RGJcP@}v2Kd71+!v|mA4yJ7cx%ER4*Wp|pL>4sUEJ6YI&mzUkV?RABp$=3r&{oN%zYl{v}^4c(+x$ys`5WciF-FI0uupR{-E1 z_3hsez6^Xc(H(9k)BN2+1y_~t4nZV;-#?d5_3UR>@YS>lX9RZegN2Pi3a$X>Xz$0M z;;CHOXqQOWkwm^o`Low=xXl%)RiFFDtFqJn9FMN1xoIv{6mnUgTExvtySupscTboR3)1taM)tO9j58s6_r@3Fb*I=VC~}$?7Y9+fvc>RT0?f z!s#Anh6zw(%8@#5&p>m*>0UG8)rwt3yiuwFCEc_U#_>+8-IDn> zk$KRZG&d@6LGC>>o}Dr(wza0*rM>j_IxMi=U0aKM#UNE2ADH8|PftoNwXITVEj1f7 zF+n*Cakvb}&pE4~Zq%)ASuQW*XdLd0V+U{buS@E5?BfS#wu{TU{{TB2YNV69Jc94R zSGT5ZCi2b&jwV23WXi~_er3tY0Gyor*F~fJFVjEa6SdQHoB1@`$e@}D+7%&2=?ki; zJYfm>f7#-@yPIe=34YleaWsj>Tk!O%cNV(58k`J^5Vs@DY@F^n#xOmNa$z#}hEA19 zd#&l~-|o=qsg0dfxpZjx$Hd7wj=AF|qtpCZ@teT6 zaaeep!>@T_(S~Q37u&~0kaZtg`kvw`o*7_{O`E|Z&>U6=_HF!)2)UXmRR+h6mnwaK zop#1piV;wR(~oIJ>+svw!0|Az{AefW?9Ut1ej@l6#pt#=rJ8A%@&XkuF@k-Zcly?^ z{31GDp=Bkqg^03kWN+R_AUz2OsI4Cv{2$P7rCmbWz*}4^5&NO?5_)8I=DgQa)qG*# z&1TxxZ9Y*5B0a$Fj#%^RdJ&qRYeuBGYD1B~Js+SdT+zK5U&)?#@ssv*(Y!&WzMplc z3le4yFCl}^i)ZmELPi4)`N%yh^Y7!o?3v<5#<`@MZL zU$3@4G12vDpG(vn+uf)NVv%qh9^m)-S26J$;fII3NoenT14PG_xwl@8+j9DSE1s?j zt{z^}i~j&8`hG@{#Hx$g*GJ&Ai7Zah%B+ruYby*8M^HsGCcf7A`THYY>Nl6#r-vho zEnYWbs;3cNW2)qIlN^sx?_U~fnqB^le?FP1+R1NqZsjG8L4u@LMGQ=9d%H`q!-&I5 zgTC?ZRG@XDis?Cy>)|hjwO<_giZ2ORNBg^(7Fp%T`lMgHbM8Nted~2`ru-H7aUPqc zLCbSAy+Z;s=R0 zNqGW@ppBagzZu$t&}3xSNvdhyBk}i$Ui0n5ETqPPc`6Cu55k=4`&Z9b;QU{k^8C%A z1s`@VUa#~;i<_?!__tDrsB zXqSA>c;g*$f%s;lg3n9%DdDufV09gKcz}-2s09B25gygz&}n`=_`%{W`lY?pQ%xxb zMBXAu^Tt%37qFD=%#e0%YBu_O39!uIm% zdRp$C;<5Ea@_&FXgm~NXsESsU3N*YxrmI zN5lRPwzqqoIy<}MQH!>H_-u2u9+m1a*?^geMq=uqV?O@IqIjyc?HI0Dt&-FJ8}l-h z>C#q)t)6w^?}9!M(ItDR)>&Fnhup&jx@3;$u|4ahPXOq4Z6jIOp!1gvz&RtK{41em zTV@R`v7#_lAo`P!!mxF}6X<$Oa@^kdg2p6`8P0AOa8>GX4srNaZw%`@*|+m%O1$>D zmjtm}-tCsrSZ@2OfE;)2`d3EQnpMPNV_=&I?tl?o5Bw)S5ti8Mh~EOW8!67Cqh6U(6Xtnu#y}l0-oAoQ73r4Ov001Q&BTZq z5D;2H-+|kuN3RdIV7ix6*bXaZr-xqax8xM-%KrAJ%l`lkej)ge!@9iQAJ=0uTEeXD z4adwt3!XF5sr*pzmX+eoHT-ShbwaA!?x0>?FR1kCUghIohI$`~H20K89i{T2RJa@# zVmJr$uK@7zA?5AyWj=M$k$!w-D|5hC7T3?Wa;Tqs+9Q<|#_ezq8cjY%guK zIV^M?LS2!_Rn^;%E&Jox*NFT{jWq8ZUg?1f#W6A?b}gU&v9Edfr>5!F`pvJ3{5iF> z>$!Rku*y22A5&fz@p+}WXtiZ4zS2P)t&V{54R_1;u+?gCHOnmyLi`!+-p?QcdXG;^ z=2t_9V=E9?Hc2O?ZRnTjex_vvg#}5^PfB`P!#m0eBXQ4OGCH5ixMY!{xy5T%b3{uJ zp%i0^=h<0F%7dH{k@{x3?-1CH%vM}u_<90=m2-}`LJDqf!!?suDKe;yif4o)?&BCA zg;!w87#?%L&-1MohlTV#su?4VBnmdDBz<}7{HYe1NWiQ{)3gQQv78@Dr9G2I!HWhQ z*36Kg8ASx+)B02^9?(``SxLuCf00VaH!)fy8Cf{n{6M$mf_)IWQli37w$VBei?m5 zd{yC_1-$VEg`+MSNs)cJ^u>OH_$J!w$4axgx42Y;M}>bCLH~BzO0%O&%Ri=GrOlNLF}kCZ>yo|emV=BedUa#W zwKsK77U@Xnvuk%TBV~dOJToZA{PbLbRpZueW`Ua0ON+9Ek>u)wcdsaR{z9RG%T2tI z_FLS_(J?2yGu@ zcxS>_H!mI3h!|%Zx9;2cFyQ-eYnjujDRRjUt|k;f99-#A%=DW*%dq?oiy4>s6*3e0kl100j2>vBrypC&x__^^m&%xV#E#bSEueFd5 zn{o(bvr;(U>i&!Q*Nh9dx^sJZsl3w2#oB9!%#8lT{(x~_tHMJCZ)xT=lL#U3%*D{iMP`Ohjbc%CPIxs3Y>LPpm13ESX|gzd!-w2iuy?wj&a) zB~ktC+7xL^M+NsH)yKz=5a>F@sp5+_)U2OlEXjp%oruRDUwZXxJzK-xKJf4MzlZNu zK#7(Fjp*3>tUFiC-XSY-Awv5?6SN-c-!S~StiK9)%TxG&tXpcDY>sW)G2KEK?3q=% z5$m*!A8PZyy*SpjT~qtcj7C#VtuA~&yCwHC-LGJMH)K~zRk65`eS6kj=AmX_Wr9Lg zw*nn;&#?6W01DXgUaMi^pA6dgpGde3Z!#+(&piF$eF*7ZcP^pluaN_FVgciWk4iCA zBO6XSrgPvi5}I+I=;1tBGLd&1FxpkdJ9A$g>iRXrH#6qrbSWbh8OaNi#eG-fYt@F% zdBORJ+I=!B<$Z0gKG8GDAlmJb^ya>gAd8G9pL4+Csj1GJU7zT4mrz8+s*%$@Duv~! zfzU@O+`yawC)P$Uw7Il(#S6t~2@9tLO`-O4e_udBR4Fnf$;??#~$QTwaB3Xs9HP0dT=c!Qc)# z`MX!4_*&BP-4$nrE!QUm5s$%-^sXqr=S4|a-ikOSx`NI(Rxa5C%iED&$u!ze!+!u= zc&AdcN0QbiXkD|tT#u9kp60lX2F5wAVGHE8NL=!9?kkA>tUPOTq^6JHh%cO_#6s%o zFu|1VI81&u?qw7y)WmyA>hOYcera_1?0GnzYR)uZ?BwnGzrgSvV)Mk_B-gG0H9*S0 zb^DuXOt;gS8ece#x$VaSy$8Y(Yt{?ryfZjZ2JbkP$Kzgjn%1XtBK@8stB!Z>Ap7kvz7*8(>lnJ#uT$#9}I9>&q2g-O1hm0A5F|;}|7Q3dv|}uCsfn-p64r zjCTe?6_lW3kEQ|qje0$&!(R^C>FcR#?zV^%e2F2zOnQUQ)q46>j{)gkAJAkTB-h2c z^1fv(yK=yFM;@$*MxSkPUfK(lAwkABbH;m$j$dthlhO-C-Lsv^se3wG z^?eajPt+$D(8uB1CDRuLlIGwbm^?oE-vKSn)=&rf8pN)9lt+B49Jg%AWWgN40v` zd?h=i+Dq>Icl>@wB}F&3=VSi>2@htc9N5;vmw%{1p zoE8`$jz>L573i97p#CAZw$!bzL1$E%GTA4LpQ-Co{;yI}P}Q}gcl-iWs#8i$>Eu*< z9}9T$7_{FIX_D!>#BuWk+&TXMX&7KQ=&pdhH+n)z%Qo6?PX*7-HwlGF((*7hz z750Mq#l@pba{?B$o+UBK3umY!oOQ1~vG|WCiZqw-cZ+`9W!8auwv#M!z=LY6nPn&Zb6-JtcgIrrsT#&$o7Fck z1C74b^1h|voBMrWwZAdB+#4Jy{43Oc8r|K?cWt_2j}j8jI-GHe@jb0vEqJ;+H>y3k zdkXX%rnOy8_s5!kEFqTMD2ge3;KM7=)O6>+(z>4s_^~anEN{1YmXpM*IYLMXc**|& zb+h;y!Mz7mx02T7jF$3(2GfE^f7Y?|^FN0!mrY5GmU5|-MprDIv-BpuqP#6qGfPWZ z`D=9k^TBqNJ9WL!NcfkcL446&*@YXp+&hZ#&l6kRL_W_eN41=xDsn&_{j1jeHF;~| z9SY-27Yxs7!v;KrJqP8HUQOc7I?l&fHu!Ds#FM;ZW_SnQxN{6AJRMfGS{-?AA;J4Q zoUW$g>7fur#D)SjZ{c3~`~`U@i{jLOwI{oR=@lMEGAReAOaoo7i*GM9ZFlVnbRmfY zd0#QXbH`8f*0_u7%bh`HylD5R0KR$Wxi#XnsMCISJ-Tn&%<@l(+7oMDAH0Z1^Q2|e zo(|#9@~@U;XH3LN20V;+&TH*`OYHX+@`o8s+gJhAcLKgh@!pC3jjrEYsxro9F1a7V zdRMcN*5{0=zf-`^X!6vJL{;$hy2)~`Uj+a-$2IAiEw#D1HZ3f_zy0B0KpcBll<3!K z5p^IRm-9WVwA1xHPF0IjhEWQFBLPP^`quckH!GOo=V&AM`pQ`CBKtZH+nDDhpRHZ6 zC}i^-j+y4X>eE}*^c_My2UZAC+i#o*7(S0(a@-;zb(3*#ezn@-m8!+wFJ^fyH2EIp z)R&57QIJ7={sO3KH#ZWzNf8)l%MRpLYic4Db}TdZ5Ov3?s`_@PCH3XWMPVE`O~;`< zz^;CE%%Z(b6ndMt7v4(Xaz+3Gs9fKVG!=e$8SD*Lzm;QB?I}M`TF8p>I2`YBESb*U zxb!BvDaW1aXD@eSt615fz+9KEe_7K(jfW+aa02HQqo-@8R6cBYBLHXkjY+8p0a!jrK3lc8OjdvH`By7 zSFEw>SCY#aKXA4e@*GvCA=pb5>);Lvt8seRlHe6yikS*NzNg-~(RVjO`3JAPYiJr~t>PQ>vC-`s zNmzhL`>UQgJ*zKZp!u283`(f%jja+!v~c$~N|wd{0C?nQV8>stu&(PwxA6evKpVd& ziCHwy0r+}ViQ5L`!{$pNJx)3J%-Q%f!vNytti%4_kR0aw?SU>diFdM;n(c(@dEEl zx3s*1=mMCLuH5C1UK65^*1fk+_!4wWRFlOzt-MgG4eiG@t$nX*J{p!b)2;4O zNx0nZ*~#yMPd}A&8jpxIuqD>yTdhLzm~Dj7F9@MdfjEN91&U+9!uc7a} z3*lWJ=g-sa^$V-{5AP4WEuH!(-;Tw&3&C| zYvA2d;TG;_p5?w)Rp5i~ijP;&G_5{kYX^tmHlvVPn6cxiJ?lEOQ))F~xtwJF%$|qm z&xwCzt9P+&M^3$t*o=~~62N^yMjO?=je zr_ZtiILAGy!%Nb21;yr{1ckowDbGIj75paM z)xU~PLH4HGU9w6D$rkr7+-K)Om8*@IJ zbbRY+QKFFYyl`uu*0fk4LwRiDZ&qJH?OC_hS6Y0{1&rA2!l38CF zP(D%gKi0cF6ZR_9HPZ-fa(g>9`JIGirkC*OgY&O#@K@|d;F~K&8kp4eEDR5{-LPM9 z6-{{2cxkJua=)Ut;?e0!bB>N^@~?;b9nX!l#gb;zS)xW0+B^RMAMgUhpyMQSn$$lD zHOswz^2s%wE9{cR5rPD_Bu5t;iEsf{VZbAv{9?YD@JH{O~;w?bMs_STzJ9&>FLee&R?I(=qx%{j2v&26FwC!dP zw^~Flu{QO}a;LEs!FZGQd$hl`Yiq483y8qL4;fY-z=8bhf~{!Ar|%(kydLjyJmdvke*nc;XuHz zeE6yRA>3(gHm#vgs9JS*icn;T{TOm9;$2(fFNicB5MJ3mtWw7WtrCI=I0qej*F6>W z>Bjvu@T-3sAH(fd`EpNLZFYdH$46BO+j%D zv~Z}7L%qQy=OlVpEo25R@w!5*subCNvFX9J$J>#r1eV$yjelT}6|jwBcZw-t}o zD#v)c`Wq}&H>#2}t}Rkcj$MlS9{$x;&7?69HY;|({{SYr`_G6zA970G#>%}p&16aA ztsLAmsXyN64^P9=x@lnRHLO{ju~hmqqqtmyC(P#<`@B+V+ExC$t6KPfNVI#+O8!-b z-rh0Qo2S#%p1@ZfdE?}gO^}vs@B)nF_5!}l{hz)a!|+eS5d2{Hhou|87HiQ3@b;32 zGFwF8;hcYcvI!jFa5|HY$YCl)r7bW0T**~cWy=j&>)#GMJK^8izrq$i4boz@)x2x0 zI!kiJep5Se9z)I%Gqo4$dXrwEqI@Gy3`ze03HOa)O>bSf+|fsI7U1^|M%DxP5k^2> zr>_+^?D6o=NW4jYDtO*$A5dp$6>d}ltT_aBIQ=VcQTUy&_}=>J$HDq$`%62PjVB3_ zkOw8Y9=Z3e@#=&y{E}%!?R|N?{Qm$VsY;}3I8xnwPiuK1zLD_aeO_6$pB7$83$&(5 zAq}{N<7$q`0MF-Jej>5bZS=vXXx7l$2Sc_b=4qd{Gs|*$&UmPFpABlZN~w9P$#HTd zGhD=2;pAb0bJctF&*4n4({yboR=V*%w>;OE#^D4q$}#0BQ;6ap!lT=gc_zGSG$RLGw&u*Df|@CkDAb(2lTvTLf6;n}G-SP}GG1N1JjkT@VdA|<$JR^YOX+{I zBfDG3FYRR!+*!toLtAXXM~Z#GHhyj^*>wqSG|e@k(X{n*2M!Bka&$eqj=xGg5uh%Y z;rnSkN#Y4Lg(zlPdL`RE8`7r)voPqmN=yVl^kRobDwU%g=u^pztpsA z`<*jVyjf%OL`}axDd(p?yna>Hcyb|krXq=_FkB&Fx>nqzo>$uy=J&c6_71gnH1l%* z0K5{sW=3LEp4mS2Goe=lUKMHGty5M@PTR7fRyc}sqdP9gzYFV08f_+JRY}yk9Q7lv zDK9iu7VusyuEHD-nCIm+$68+ATxs?<%)VUq%f0Z~E(b&Sj@7k&<0qR>n%dUdMUq(f zX}(p-9gTey5}bLW?frHwS_%bWxFRa*CqW&L>xsU^)~{{Y%GHnEBS z0JJjsE1ub^p>_Ltn=V{uIR_%BU-{P>UEAsVvXXg;u>I^F)qw|!b@*avr;}?ZMkAbh z)>41pvo?%m_DPwt(?VTYau?A0)<&~or)qez)HL;EZ=Wong+8@kL-E?i1Ui&k ziQq_sHMK6cX>|Vpy|!Y65xB2vQl_T8>om;mC_S1ylgA$kf3+G}{4a1}x`38g$-r(i z@}ElM{14-;TTj%kd@tje9tN`s33-4UqfF103Doi?t4qXep0)D8ONdeSDg6c zz$e6aQyaaa>&YHW;YTNq&w8ZnTt>RDh*4^Y^Tw|W%zU8&nb^ibW-5n!e zSsusCL{fPWZy{#^7pXAP0MboUH^;5>@V09m5j^u*ubAt0OFLcH7Ywd4R~&(!yznci)qG{*KZrgcSZ(YBS;YQS5uLe2 z2aFE>_0<_iT9WuzLMI08N;`FC+&Z4O@fXC2JXW_pT<@7AaxjQ7&-3EGi16lzrfHUu z+grqmg&AZYd;I!WE#U1Y!^65&y{p9=O*RX@FiRf5S7x)pXJq%+62}}6sdr*=v;mX) zRW~d|`Q)|oII7f3+=j^2iG{FmBnuGd40>X@9arL|3MD+uo&J5A)Wd2lH2mg?jV z%lX$O1;Q)>nhH3#-|_)2m3wclx_|TLDK=(~oRb zPNKuKx0m((UvE*uig9zE#B!8$Z|7Rc%L$nAo(icWDST%J!O>sk8tziFagEEd+0OFEFO@PH9X=o}xr&whri zT6nL^92V-M_=qPz=e;_zl&RineD(Xge3JAEY4ct;x83;`2f|%LPGJs>Bvui~ zF*USc6p;bl-#^99E0#}!o+Y>OADeX6^IFWsi9@%Zp@*URag2)V?{$wDOd*~1YkWhE z`wl$6PJ8`6qPd-a#eP15*G7oj)Qt#q>ei zB$2QNaxt}uz##B?*Q$71;v?$%a@*?~d->|(8CWNL9I^Bj&U{1oU!r){*5dm^kS*W@ zl*lSn0rF$t6;7<^C+yOi{C!ZP7}T<@r7MF+E79TB zyw^+siz00Rx7{D(U3BE(%Q&2}R&5_L_;*ybm&6zT71ao9OS3K(UJP^R2tfTlmE=DV zCYCX**h;xV?E&-~d;WFmzqBuhiRg5ZWm9Bq+$*OmNBzk+z|uW|C~in1{u z#7;Ml(!GdO=3L$X07IHl>Dcq13fnch%0iJFGPZHoBNeBt>K58sY$HBk;{&ff>YP{6 z+uU7Q#;TFP>IXiRjpAKVbxD>O6m3u99nZCLEjI^y*r%#$-*0jV0|$)OP*0mVB(Wre z-lh=9j8v-j>T^v2#{`f^OmwWI?ow72b_K@3ed@EKv-*yJVyy$Y1_{VKiW=RvZVT3s z%0(15FituOM^a9C>58x;3`&;C`cn)?b9NZ(Kq8Z)p#ez)82M@mw~(V57{K-a0P703 zDR}->UIS zp+Vm%$v*!8rF>`@zDD8v8H9Ajzi0yMhn{2F6Z5rF_nAlf*0b{ZFvS z(v}&oKhYkkVd4nFu}jEu=Rdl)+%ulNDYtsTxJHIMyPTHJ78v6V{&=oqOn)qSOwJWZ z!+$!OOS>rVQZqi^Fr9$5e?eSy+K$Jj>FRD;&vR;xB7Lm3FmXQ6KP9KwYMQ)LnY8x2 zM`AK!xjwz{Kb>P;Ts&$}#!ETdk`52PGgtJ8jF%Bc3Pv2N^c-~Q&1&n)D$!Y_Nc2#}D#2Xq^O9m6gSKjP2ExxO4|k$8VX^5^jupoL<5hWk8S<#2l7bnlwj zwi-8sbPYqqy3VGC#>E+#h})bFG4(jFi?zLe`^1{{--vZd8SZsEg8P{B8fWA|&j1Vx z_b?Iqy(f*TuJ($1H{JJ3cjsjEXU|n}##i=B;ab1)`I^t-T}sePs238+Bbg+3<>io{ znVUS4O=X`K!>r1%Tw6(LBV!W4*j~NR@JG`Ip}kcKEpM3}hCzNv8Kr`F= zD`S!Vd)BjDHM{|soxtFC=kTv9@Ghe9c(%Ej@{&&Apzr_{{ZAy zeJjqFBj|WD<)w&nk6q6>_>q3Lx+AR5hup-Dp0)GNr+H^1`CE&fxftfXN8>KF9oU&7 zVTnjl&u;bN#vnLeqrH7jS5Mi~yWII4_P4dJquCX80IuI6oCBVn>XeZ_eC~1v2?S)1 zdyt_&s3C2ChuTRkN)`vmx?m{)BbO4lWjPyP8UqxxUg|4V%n^P+t z%y90F5k?;!E9RdBU5i~!jGJ@V0gh|mJQdXvTkrac`J?uQ)Yo44$9~V{M3zv)1S${i)NI_ulkQD@5AfRRJ3S?D<(5faW!z)Q zDeu>(y?mkZjjgBnwXd0?m_%*^!xNvnN`uq5^sieDS}@D;2|Zeh{{YF8{SI0Xe_V@w z6aN4&)PqUYAcE|9Fs`97Tn0aJewpIEtKpoFX?JOFEEZ6~DE;fAl0iTHYWeoo?o^X> z_XxlcQ9;_Hp7{P%>HZYfp!;>KHy&h;NKqV3h3C}u{AUF40Y+xJj*C!T$AUX|hWyuLBa z$}McJ2biW;XOR%{epTu{vtAA0siW}zwRE%G!E$Y|k-UrYhB(Q=`t`1p#6J=*t+6(r zAh%@7x}m~IJwo@Zr0U*LmW#W)ZT!NjjZb-R_#Vx#X)xQ#H2MayZK%Q{AL#Q&_VR|u z%%3@BVd!!*TwFTu*`k)-Ij7U^EeMiG@~ZF+-kyi@HOKgG;tl4b6I)HZ2?-_klfXSe ztzQ^k!!p=-gyG*zIFd;IUGTO;Dd6$Y`D#M{hU{a69P{KDy4upO^tBn1YwQD=u z&0ag{vo)UCP!I_mVB$=E>3WBz|U-SuR0Xy!V{@2;`H_3 zTl88Mr7viq(XD^r9-pS_@!#4i+t1Jp7ffXOk7HUFNv5O&P`?WES&XWYgCOcgeKTC# z1?*r~yup<40C0BWpvU#Dd*UX!sjiVOnWsp;e5rwnxg?1b%s|zY}~(Yh`OK^s{15Gcj^AAsv6E zc$bE?8GJqByK8wE58rumh8Y+=PI2vBFT}4G>Dr#7<-u_q#|YaVdD`Q>dDF!#RZ8<~ z+-~W4Z58-xb*d_jSSW96U(n|~L*mQrZ!%7%DL}+(JCF0)v$PKy9TxISYl~5JZ*q+s zpr|`{4iD#5?q#xpOv@;FSaHwmT=YwBF4{|mVH+Hl2c}JY%}TBOk9HK&MxM6cXJu4E zBYcoC$0ED~bleIwIz6^ zQbgY~Hr{_e)y`>JrS6%n$)?}jv9?pT*`&r;d!B$-VwcM_7*$o5Jf6Sg*D>Os4gUaY zLFPt4l?HR3bJvQP)>wI7UklN%*VP>9dsWNVp|5dy6j8|W6(JWT{rj5C@YXFYoQWmm5_?DAV<(B5{&C@AqT1+7I6x((UAwz|1X}taXz3wv{9vKWE<4TrE(9k=svaKUm0|_ z)GY69{Ic=Q845}7US2vr&T6c8TAjFN+Hrd`^Ugq3ijjf|6yCL^uGqDPsc~+@8(iRi zHJn!+Yv`dRD5)dJoLpqn5`Z&HgV(oe^k0QP2{lh1>Xwt;!8|%ll8D2i6D8B<9$ZQ} zVow}WsZunf%_dbUQmrmXEkyW1@IS`i81yy*5Lm3USOnJx~7tTE9)d zXK&c2M(|yozNvXuS<-whaCA=!-mJHB3`=rKs2JaB6n9SO7QAf_|f|cEX#( zK}zoH)VA*Ij$1(R_$rU6&wn#1{{WWme7ySL@@vraKM85t_CB3Kf2&^{bv9 z&~9}LoIR;{V%+Xj9I_5KeKX#@Uq|q@ifPL=ww%HE-0`2EW^tLRfkDyn=djr{Ld`AxB&qf!R?=6 z_}8N8*4`7bf#sjXEYmv(-rZeeVt=|+^j2dP!rsfx6P2A2Wn;vin|%X=b*lH!x)k zNc9-+Rjxb@H;paY`rlTK95F0N-@)xvbQjb7Hzmi0yjK(LVtlF4WD)K?YMYHq!ZG*O zwzli7ucyd}!ZBR;zkec*qa~)brz~@LLf%QI0bHOlhx{wSelPqJ(5~&8T_`+rws8dG z4-v+24{_=1UhSy(-E4%~G;Q|XJ@*KtZv3&rcI*H<~TZ_)8TyL&`&82|^qp2q8~E8CCMrP~=xb~)BicSmd`RHL;oU!a zJ2LgP*olIGN3lFs&Ah>vIl=UXX5V~cz)VQWg)FB+Aa?n4*uORKR-(6t16V0-Hjs{PebO9*}L{I@t?*0Lf>2Q zEv))ah1G*Jq-~budPWH8{?&et{4)KWJP+{CM2|`EwvHo2%RG{{_GUfFuTao53tcYO zD@Y)YB#ZzRR{#uf02R_$T8Sr2De{zHj+r&VQZA$BsP6v&54-g`AteQ9EeyRA!q$=7 z?PO%*oDP-N>6#=lVSw6*FbL{>K9zpX!Z4vqgODqr{>(?S@`GVmbB;e++MFz}V=2wt z&C~Q~hAxCaD}XVONv-Jg`*1K3aA|Gqk|<+}AO-*fp2DXn@r*D45sti?*+MZ^GIDHW zc5$pbLEH(>O;&wA-bN$I2M4Aq`u_lQE&~4mDv}6H%63G|TaFGf>r*Ommf})q=Cv;k zS0ZV(5 z0mW3hgrp6OyL7wi}tVo0D^k>C*p;Kz9sl?We$hpP^}@3Gz)Kb-EctR3H2NkSW?I1 zGRsF6{jEReOWt4NOGz&{r2L-eQ>TZ<=>^F?-(~#zeDw4`9&t(d*H7cW0Qi^T?})Da zFXFv2YYjrmLmaV4xWOKk&#kkRG7+>6Ij^LpTAgSrl-hB6rn;lcsX}z5;U#8>Ljy*A zGgFIDTLJ!GTvnxqj}`o0L<)EHGP4X0IpVJB*Cj>uI`4uW82;1oR30e5iCanV^zmHJ zy>ca&Kf8zyc9{6dkc)IC6D|olW5i=OKT3ZdoSw(^sa6rQm=sS~NDSQF= zZ>j0>_*=quSGN1$xsO}bVKD~ti;g2=eFnk#*V?i}u4(pC+{Z8WUDDwrw~v^mA$U7_ zf^vUK`KtMZ9a%cJ_I_Sn{G0PWlMg}AqN58bzW#ratMOOjUYB8~!|>|jcDH$>SWJ+N z1XjlE9D&>q#d;A@5O*M+>l3>a=~Vjg=kK3Z16+`+mNjC0?$eEF%axZ1?ln#dF1 zOyQniv-!&GMpXkG70AXp^{-v{U7|(f1&-p^RF_M(2_>}Frc7mr%atF8Uvpk28xuUk z80xKC(Ob8t=6B*KM+=5fZ%yB8o{iuwOH1*6_1)K*D@PDiSmYjAi1Jtra!K#_S6yvm z;r1VHy0VJm2yz7T4XBtt{eKE{UL5dsg{7{VWR3=eW--4E=ecA2Ra3+;&w3IIuae1s z)y*0C7=LtuUu}oMLX|b`q3=EX{Xeg~`O1~mNxx?%kg4OZ4MTROFE7iC?O9nus6K#p z{&lq_=9%K#LKYMafroFD`+L_Yz7FvBk@nv($tnzjj5>REAB9}g8rB&6%OWtJDFc91 z`uqO?QC-o5X1QHE7)`-@(35PnVWZl}vfEwiMWTjRB|`-$PYgYJRb5-a-W|4SB$inv zki;g2PcfK0W3D;D$ET%X__kQQKQ-rw->coRbKoy@<*k3R?AMZu#yPi z5nRH*I*tPnG8lUi%}?T6O(|uy)y2Ab(nc3}10;jc{XwpF*6pK+-7cA^WJY0Z09is3 zrz@XRinTq4yQ=BmXNSVt+xbLnZzv3$3}fd1063_r8YwP$FPmTHOl4A1y1Bmv&8*fW zNShCoQ>Hj0j-Ohup;*azr?1)MC1Y)y7zPJ|2*Iv!U)@{9_B-t(TGQPbK{s|%0queT z9ldLFOurVk_WuCc(rrV4Z0=c^o?#dS_CCIy>sIqhv(@eK zBq4IR4yXFoEcTjyq=Mlv#lScm_ceq600}0s;Y3q*8SRVh$^H?J^qP#ncRd)R?>=Zf zO3(2%KW`**zpCb z%&}ZdW5GK{NWmF7_Y_m3Z6r-uIrI%!UFjO@8(-Z;D{sj>H>j;^*=8{$%^I@p+6Qix zj@~QNb$M3GP#s)@6oZkUe@fX~n^9`fvxnFZezi`VVpAs6 zEs@HR)E@oKc@CN4w(wjsT3yY%$R~7ibyYnv>J59vrOur?+*?T?4pV|gG6(S2o%rYB z<(9jqwzH?8H!)<82P}j7*F3LD^CiFab9!wx$uq-$X+MR!H^yIvx0+nBqKl9&>?Q*y z8G42u#AF|(etvu;_;GpQO+#1Iyh6q)t)r4MF~TAqTk*wyr0JLTms)&&7u2IzWn_5m z#yW-MW8a>h#=cnipYZ0w4;WqBT%(9JNMusL;Z(3WKhKKgt45?In%Z02xzkQilC+kq zZ$spN4n*45i^Ios*uIpg8?m??KG_Mca+rslik$_GH z4XUqB(r9!LB6QKXglEFb5>#8Q>n3-guMZMX!Z)NwsOM!`%JY zB18VM+l9`3{{WG%9PpN{FN*btywok`XrPg#n8eBhxg?f9Qc10G4tRQ3gVpKhZ|kXs z6-H9#n$aGS@T0@QBEQ!BQv@hdUi;=Jn&gE#il^|fRGhwBuwq?yC?5)&M9HhXS#_ZztkC2@Ti;=5Syygw3J+io&5TsAYGeoy6F!xo^q z9_!}+0L+(7zkM0!!jL41{*`efrT{G=Bd!7Z;-S9qR-s{SGE^y-CHLN4pK#L z?{@rat8EiiwYGG*SS6Y?+TUlFaB-aQNdEvitUY!=9oyQMYiqgX4Itgx8P#>(teoyn`59jxVX^U5tbY-FCnuFXoIuQ}g791hQmlTT z$kO~N@%5LE^h0@RdeYxOc3dGR7VrF7_u&2&!oIkge~2|JD|^2;L-7PANDCf085s8* z56Zc}fZF2N>Aoklw2nk()tJbGjE;bx$k%;XMiN}Rf50)-rjG0Oj=8gw!a`D}PqNG$ zw^RO2eC6W3O3L>{(q)ZyLj;a6$DjazTK6A{_i@eOT}h=?mRF4J9fAIp^3K1j`MO@6 zqFcybUp1O+43X0V@vg3Q8h7Z76fY|nxA)Q;o5qQT$)9!`lU32ADhlrThi~OtzwnM~ zI)%f^Vn`zdD(~t?8ToqGPp14h)MU#gh0W&Q;9rq{$N5*CJi?7Q-f~FnrIz9=KXNAu ziIO=iIT-6xNo9GlWEK;JV0N*Muzs9Zuf^e?8tEY1Tli|nL|D*;GTI~^%7EZ<7% zJTKu7iXJPLDCO}39;H0#0)+z^+Mr-|uRgYUN|bq%jlF-#9*r!9q}`=;^8WxfeEDmj z>sO;~mXmusb^Y87-_oql;cpY!s5e>$r592ITR7v_rG0bZAAwfhE0X6)Ux=E7dhMCa z*3lIkRQC#SSZ9tuO5BI`Yu9bH1k!K(WvsD~aVnDN$uE)t>s3^;gG5QMMU9%+Cc;yV;tAr{wDpIylEAv)O7C`-Cm-w zK$m(#NK+>pnUkHqr?1w$d&i#!{B`i+^j!GY;f;o+VDay3yKwSbxE_)w8Z(Z5U^>>c zc#@Rm$uyJgfAdT8GM+@O%}!75{{Sa{!1cmFxPCg}xo? z?$;JGY8nKRfMd3GH!y>aRa@^5#-X(M1>((m&+YyQz0$SvgECp$+^lzTj>pP!3lDY8 zdQr`A_Ps{q>aFGTOw>1JZ> zy#_%iKhC;o(u#VVIF~L~R{fy-X7}D1(|kD39A@%SG^rEdVlkX@Ipm7)$*ff-iS8nK zQ{b(?F8aT5tcgMlGp04MRUR}oV3 zjV_5V$5V$3N-(9()wljfQxuWg>R8lmnh<#NGXDS|Ju&EddwSH`UCoU4cMYn@;@$;j zLec!{SoFuQPAihN*YD@Lh3+q&R<{8V85LDr)GZ`tv(_|YGfTL~G$gEu=N-r19WnUVW2byR)-`CMx|VpX zZH#<4oD(-_(CGUa_tG6o$^Sut%5 zgSP~B>70Aln`#=&_g7^Kv`NbCJRD=aYkV6bQRv|Ke7J+?GLLwMjwXSq)8{; zl32DV&vIKB{A<@)rUM5bXI8XRT{)G{nXQAx;->1VZqLb{8RZj|J;yn!ml2Gz78nbR zcduyizwEQ|GfB#TwjFD+$E@jNV;$FUXH zLomYPKZQ~)`89vIv#9J_5 zETIkrfc3^dt$L@0wKj@icaj?m_*W)j4|z=;_&IyFJ+s62FwXXCb8Q$gE*Pr<4`4Ct z#d@uluWjTB_b-;ogOkR3aqIl6!gQ@h8Lkx1brew~KQGOUX1+GZrOsPdIZ z$b;06GuQJ{Z$HR}2NF(;H;VoS!MZeSxn>2PG)h z!@sp1JyTEgXyTf5>cX#`zVpKEg|poy?c=&a2`W03Aayn9ei_%SU~5b1V<&Mx?J@Qr zQC?SfcMYa)CVWPDAo2k0DYhEr(U+FYq1hqze@K zo|wyZXwpB;@{E=D1Y~|S=2|z1u60}HxsKjV@wd+lAG${v&TG+})ZrShqEYp?{13?E zqwe09tNYJDwbZ4tmhJCMW^9QV9P=A51P`wjzoFmhnyrkNP+ZtYHM{Q-+zhOXjF3MX z;0TJRo_UYiXA(udUyS3Y>MIMw zR$uUq>Bdb;FZh{En?@UmPI+AS&s@|VBiG=(v6DxFXOAHkBB0_*0h$J?8qI#F^6%vk%wPi zy=#E8@U`WhZf_dlZHWEZ5|;_bxAHa7T=>G?+8FJwqjg~hQevS{k;h+JSZTOdZ)Eo> zQRjlNe#~Wu#9c#9jyaW{1M=G!xJ@Px6`3vC| zui~vg#X7FJq*zE~lW1a)`I|DwgZ?$wc;m(Ty}A>wTg^4Yu^|~YpJ+*Y@Wyjc`l%yzM{lHbh_zB8S~_3PIk&bjStU4vD*#5U7x4Z}0z zw@eD(5luqw`dH?rCn+R{>9_X=G!v2sZ~nbrzSUAtmf=@&E)*yn^W2WL7LTE89wC`+ zEOg0tE_V<(100j+J?l>Y0KzxAa;jM($#Wh-nKIZugB);c=A~YgYH~KNd(`OElx~)V zDYT2NRieJt41r_+09P6zF2H&(^)-R2*u!xsSiBzv)2o7wddDNvBO{M$*txa4u)2zU zb@e8Y06fnz$Wi%>S8w5;6zVqd?zYrzZ>_<>hf%aksDM3=;k|yjr&|#!X-@b1*W_Gi z^J!y%(*7U(P}DbF=(ZYen5A}u4Xj8$o7fy2dXbvegW*TStGT01d&IhugM%bOVvZNN z1Axo!xfSd7w|)`1kTvCm{tCaJ3YXejJJ?(g_TxDV&-1SS&%>I=i)jGyMwM%*X_MjY z@2$y_DSa4i!A8e%_=@vtW9ui&8!tq^H+T1%Dm3kRFOz@LKB(g zPD`@VB9a_oMtgTAu=lOveVjQ>xFmG{0QJ?Qsr{A%ZEtSM6+$zge#73sLy}U9x%s-f zYR3iR53uRFv{JRwT1BWzAep)sZ1J}p`&O@qd_XR>7KSTZmA1ADizI-BmCvSr@Ey-e zK941xrM1DfR)IftfsS3t&PF-` zT=*zC-jZosqkSIM>D^fLrkvoXYySYi{{Vn}cWEq=hMYUdp3C|Qlgf9IZzNX97!i}e z1Gk{BHSn*+e-HSUD|^+~Vzson7`2K+~h;i(bcusmDIedGl76}_?}xA#SH z-XW1=NgbnS&Q1V5K*GP(9Z#lfqr8&G!xsce>ca)o#XK2HcXqWC^>s_zLo$i8fHZn=0Udzc=Gv zpQ+#FR_$Z*+F)>SK2;vM=Dg>|7YQ_3QMgJ=ZpCreT=22e4IR<>+3`zDlHbM`%M?ww z%s9aJt}w!%>%@@5kisqcZYd>zc=UFyywGS8Pxn$soQCqRAzg-*+g)} zIV{Bbb;nXqps!N{E8*hrqDK}jC0VYl+W1%S(*FSB9=sq3@#&U@UiM`l!_-E;tlyyK zzd`>1XI}!?cx>7Dtu(7$GRsT`IBstg%OS_`TSd@gyoWsW&sydF5_~q(JO$yS;rL$K z%-Jb>+v!s;B&Y8X2UFLNKsr~UUh0}O+G?hOs9i+`vWsJLK785oIT1!WWd0}VUT4=T zR>i5)S5e!ytMWa(J`xye7M_k<{{WHGc-!`XvDK#*8fwcl#FX=H5P5d-58~&7PC5@! zRkST%RPlw~t0tFmXQafS%JT(Qo&DGkyY0nr_Zn0y6dIsKiE<9rI`#o>d{tLh0$@-->*Dl}J$n^xW zgz3R;t)+@R#y!ZO433~4=9y(>Wv4PVouGn3`FW-pZ*m87_2RF1PT8Z=Ak)E>17YSY z#enBH1oR!a`qX|Rk51HeSghr|iX~6I9ykQ>0sJec*~&9hQ8{B#E5iC7f#B~LX|@rR zk^oe&W{|lh*mJq_%O6g|uoc-48F+f$)J>%7NBc%bCER0TgV!t5fyM{tUPKmKYd4Au zTQ^8k<`N7@ex8}*C)3ih40HL!+``sQe&R4V=lHUE5ArLm*QGbg)t{67I{rs9!>N18 z=ykp()egC-NM=~(B!c&Qb~yu}3(-eCFiG{RT7JEu$g8KwjSG>q+%e?i`Bxu3_1(S` zTTePPTt(#(^8HBT`qmxZsSL~lAPPD#JRf6DG~s0wuDrDSyM4oHz1iPuwwex*iFI|W zK?=y=Bg-hvjCv~Pl24$l3(aEg8{>Heu!V2qjN8n7 zqqye}&>x|!pAzYImcSbcjAN3qs&J>c&2u)_(P{S29C6QaGm@ui`B$C^$4pm1%X6ve z@Ld5RI|{HqzO|&O(|^2r&>{{qbBuG21mwTJB!~PikhCR)k>Zp&fIRSk0)yQiR@(Y29^3@aFe#W|@(! zS>8f|YuB3NPQOwkm<_>L{nC90t$fq*@4*&Vk)1-)7}HX;Ov&XRmSpV19r0gGcw1k4 z-wkRSJfZPzY|RN~-Scz!0i0sEtE~h660Is*V`i-(x7-*n0sg;SisZ#nbgDT;-EHetn#bOYjMn-e3|p6q;BLm{KQKJvteK-}jGuH4i|Jh##6JsNcyn5CZOm&SByo+r z^fkzd8HUvy^sf3fqgD!WJZjWkDY!FvF3fRmj!+2XiiT}|SXG#?7|u;ar|Gv>MNt)- z2hz0e`~#?K`i`05s}~~YRGngSzrdYckI-b*&aW!Dl8N5_%>Mukb&rewDNhvZ5HfgU zOPdIcIK7=tLi?hgPvAXk^ixLC;kUMq(%nLQpbUQxwQzq1{12u0H^JI|i>2ELE$tvw z3P1#b)sMM6=ia?8);AKxwoQQNAP%Fq(!9FW9a(C1!YT^L*s-$YGj|+{=ydBimNKLe zPt3xz?HH^<%5#obp7nAqN;o4~C!Ikj8*$YAYcFLc_6}rkMzO?#Mmtw`Vad-*+_wP6 zykjG!bDDMRGe&}0)p+OAHL(rsDhXEyj0|_JX~Icsu@Y&TQ2-f;CyXc*;@)iFI~*@T zj-K^OOVboV+ldJIN2NO6?}51d$CJ%zyj&KX^0N!M()EM>ZwS6&bV9xJu%j~ zr$sX3CXbVUYroke!QUJFGk2(_n-m@>wu!&9?@)y<;AK)zPg_ui&o` zUHDsD(&n<%H1{!26zQ~v2h;l3^gpWr^FR#0*`uinjOq?qN%res5`NwvvbX#!j}E_& zyeVLd;tehnB*_|ccM6PsZ^FKIGXBM^vR0ou9yU4KBhxSGQINWF)K4Kks^<$t_7cCU=Z(7kz6r!6nF z?e|>zEInC!K6yu9zeAnW{7-$NUma3w2Gj+#f(OYxq{<#Z17&d$&NkfT3)9ZHXG*sXhweoqch{{RT>-OB13Wy<0S2PChd$8O%B z*B_>M+Q#M!DG7TWR>YEu>$OlQJHCGF?t4<*_?qX%f#1TGSVd4~yxWM?iN+%&V4qX@ zSLrP{MO3M6ceD3jX1CYPek)VuT62?vO)tpQi%}jNxOlEE<++Y>THekyEiZoEzNdZR^(9dOS705@Kw=bYlY&3gAj z)S*diCxAI{vp4}*mLJQeYm*a-sZJi!n!4Kkf6My4&8gFjrOPG$L|zQ=zuGM)zSehL zwak7|X`goCj&}MEdJjtK^ea6xO4Ev6Y4BJ)1jQGYpX*R`_x$P)2up2sqr(NX;!CSF z#DKPbW6nplQog>wlIvyb5hN@LTwpTitzwd!RVt-+mizpPl5Mz0V^TYvGUDvXZ~l)W zoy0I0Z(NS~tM+~*y|%(xe75%PF}Q+uXDSHm!N|{{u6I|K8`WnKJYHgL^AWiO)^spO zW2?v}x;|4PMxk@do`jRw{{V$du`ZP37{`B_8lf2`+3G`Fy1RhR(FR!o=zV=YhZr@^ zUwA)3)SNulo>Z}@+R-sWaqEt?Lc;P}c_e~6h6vGR0q8JBe@ee+cfL|Lk^$$Qm8ZEW zb1fg1kMJ|)boM!2W5C+QtcHCjRP*9saTVv!w2pu{!vXcpaC*(dLjzmt#%&>^c1b2w zGQw0G=WrZ)@+;dVxbn%jEsz_JO3s^4f@r3S=H4IPExvlTVorS>OX>?H#!ORlBVnCsDUz@3Gby2yTRNTvT%X zg&$Bv%<=*eayciiYL|(1c_PwoZb2&Uiv(ynEKgEBM_^JUOCj zHv-!38>|`S+*z3Ic!ADGq59Wnb$xLKwaAw|0-&kngMpgiY_O4R*k5Z%EHg^-=tJ%=CTU1pi$fSO$Ibs`CRd%#Ay1%#agt48oZJn89RR9oq#yvserSR6NX8tK?t7?sKA&On7T#%c=1CEV2bTW;9)t6* zs3Gx&?K(K3Sm6OkRV4HE^ry=gCv6UT+}x<(elqx)?%nh~9_Hdtv@1yAPBvr9J6L;) z>bwDJx^ICk^)$Hxc|c-FP@t2?*1UuEhSW79d7)}j$!+#yx(8Ut?+I*RnIve-PJf4<`20so z=~gO9?vt6ggD%HDZy7AS4)z~KiZbm!`LuA@lOpH_w)Lt4IV zvYq114+^Almd$W;I5z34%ewxyMvl_AKf~BdZ9+(6k2fp0A(5je=3Ygy$( zYaF6US8#6G2N}&tsd!G?`#$RLOVnjcrB-#0LKraq==#@?OXE4>OPhJ&k{i2e3QUYJ zco_tGf(Rn2oqF(Jya!H{^?_$y(xK9I*4N{Z#U0YB+$e9A)Q}EGW*u|sT*t(XMhLW< z%@G{8+F>ck=nrvOekJ&fr%k#KB%APlQoRl_w3GEG>s4Du)pe*e>E|WZJ6OZHCy-Qf zYr6+pRAYI3h{Q!yX`UhH%ctp!FfR>%81U3jKZEx9hQBrpQQc0Y%B2XAr#BEEOhJQpfo&v6g> zV@3&<_16fvJd_8PKj#(IUlgGQId8x9>Rk*wuRBL$v+);-WAT=i{gSdxr`XJL&PHXF zf3m**w3;Ww_iK2g(QNE2BPv}@!5(ygVUveLXYqBom=rrphSqdstTb=$W) zj?yw5f>hpN>!1fx5)^!~_UPUW= zZ4`257gP6vlwgnky>K25@Yjg^G4TXjG*fB!7b_vWivA{Kk_1Lz%20Ahjez&BXz<>( zq3OC+wceu%f?Lj$C#knzKt)ZN7Rn zZH`aDTGxo~?(b~8PvYB4%TNkI6!xtQg%4fQF942%k4lmJAFX(k!`>nAU9X8%Z>)n{ zXga>1aFWd&BxJ)n9vmskkU`3@Jw-ryC<*a7h>^q2j51 zYMYe#-#2Tfw(Yj|OVsI-rBYG%RhnHrdj9~yJl5Y`_?7UQTg?N-1N&b>x4Ziup`_p4 zdC|?^AtcKvBjyY-^{op5@Pl4vheG>rg{PgGSmPFrJV;JBAscfpdB_Be_Z6e@gICe~ zUwa0jHhlQ4mvnO|=KyeI>Ur(yn#1uHgW*>2ri-XqSYGM(j(oSCIND2TMotR1Vl(%0 z4mwwLE=tZ5sGMf{uP@A(8PSXOdalIU#*KZThK}!1w7Rrc^49Xr_rkBAyDE%4P3+)S z11rySxiABYo&Dk29Hwch~xtt4voi?o48;2MH^V`z8+nrLz z@)*27tU!GD)CeZHK$9Tt9K7QrA1e&0#yBYe6RMZY}PufdWT`zGzvLFb<~#WO5ELdlOh1 z4~VX`JJ{MMD%-Z5+3Y_L9>VAOW*U#{3K2Ztgw$@>j+tgR7UZ1p|JbN$7 z-=XGGlTcB84&P0`jy5HbGM~MIIP|WoL%WLq08!K~E=xPX8a#0}e6zsD?#C79npMrk z-0Kyr0on6}2PX&ARr|M_&w}#mS#9mYtaB)0qX3*Y^sZTZ}=8AbuX;7Jxce**V=9O zn%9NcZD7iH>&VBgdGCm3j`zklqRr2jbs?K#jNzN8{Q0hbQ1O_&oOx~n4BfEc~`}chF&qY*KRJf?*m_HT5362E^nA5VY{|i zj4#yJ(K_GliSX;do)rH8geo5o*y>uPi9hNUq={We$eY{dDxlzPJqJA3&vR-203ZJV zYaMZ}??VkPIX`xUn5}Ko=y=XOa%!iP$0@-&`Gr{1a_H{l-(?ilpRM%SHhHwO3fSC3 z`n(%Ut?d-Odj1}59QTI&QSh(8c9U7^n)Tkfd{-}Pqr?jC^fNvaziid5KjUt(Jgffz z2tUE?2Ge7FmpYQZp+DCIga`1iTGM}KkAa^H{F|?femJ#h$1}kV!YGRvC3f=U;PHW7 z1^)o;75f@^Qa|kf00;Ow?^PDSW^}SRIQ}fT1pZaShM`{>7VvmCC~wbI*?gk(`{Q$I z;%LHFt68~rr+q)|L!a!pr$VQ%PC%}jbIq{-0K3D&oP47w$MTQpOsU}Jxu;4`&BaOo0GaZB zhx=H5*8UTe%VF^*^Hqv7^FyfG#d3~44pcYfYtXcR_$a4~uAo~_i=P0zFXBk@sPo$= zks;6fGApk<`d87qb^ieDKk*A&ipmRpKTEmSQxl>w&G9m5C|i;Kt)YTmFhlBZW=OPYBFDXN=8j#VXZkhKb(IjZ@lnm zz94_WKmIeu)?PaJXLH~kLQ*k2wv7yG$G4pUDhK<>1xK#`0Kq+U9b(V^5^ve_;-!YW zr-j`V7Za?5AKep1ah!4UDEFoDf9%DqTV1Dzd{N>1s|Y4>_G^fiH?!O@MkNH1oDt42 zeR@|V;tve!e+s-}(EKj(_0EAUl!VAFuNqFnhLKfPNX~fNnH+=2&1X*mMzXdQIN4qD zyTy5OyXs8qPMcoRSH9QPzna#^n)v78$Haeyx4uV?d?k6O#)KqJ@os`bI&F|;Nc?I~ z4Qo?L07+bhKkHku_8;f9eO2)D_Q15c)9(Bi`$6b-+Lff6A&TnS(Pc@L@WNClY2%!M z&1rax_E7k5mFO@w|?7OjN_+T#-%((3wuc2cVDXh zy$uyuNol9#c#niepQdV2>UTIu5k#T706)BIw!D{3@vf71X{RfVKJXNGnaImy94~5H zZ-m|>)GeOgO$O@PeJpO(Eehr1IN_N(`CtwhWFK0~SA7BEwP-OD5)gyNI}`3|u$8@? zMOHiaGQ>xnazBu3hc&OLL}+*i|| z68s@$<7N?O|I8UFx)G4wyqzFEH0H4QfEZ94wb?Dv-Pv2QS8zMo3(s~EdZ z8$Zm>oSRmb=cjmc#4%_q6!FYicQ49&XRqN);KtOL^Yo*kainX1|j+eSL?LHta@J%;m#Mh+k48JgZjxrB_f30o! zYTD~g)e}?Hk|8R9=^UBNZRv{PuDngA=+~jNi%7AINP!0cbZn3F(A0N75iVRjrvCtC z!=Ya?KpYd>(5d&K&Qg4`(Hdyg(djz>0K^GwWhN=qzWwbU+<>^`diAbb#~&4KG}r`i zT+Jc5MQ<=f0%Y~VoTn6cX7B2ATy#}sNyep@GrhX}-v0n1B`8X#G#8c5+D&fK2rU3BcFFUUj31PLw0*JZ zS$f}zV_4)DS3!LL0GVNmQGf?RPkP}jd|j$u-!v;Rp6S%{7g_*u;(O#$~bIfbM0P~+85e)Tu2s0mn60aC#N+p68)<7P1~w_3D1@`p6AT)Y3t>P zCxomn3bGJ(o;^EPY4F>`J|OT)$d(TJpNFzq?@5sPv4s96j31d;XFPG&>s^IabB{c3h`2ojU2O;)9R0) zZLj4&>epsl3UiZ>TAuFqLc-S3RFm@-B=A4IpIX4Pk!OleIqagw>0faq&+uA<)L`rz8{H4(7aH;opU2w($P7 zp|*o>s799zEUn%pe9NDioqOZ1dT=Y;^>&9&wwB5n-eWO4nRAjloSwtEHS<=R@sCyb zS>ugv#@|djhMjjfDKS1;MstjpBRfx}aZ!wG*QrWUNzOf2RVBBcuHQ4$f|O|UQ&;7Z z`;UC^@4!UY?ezU?#+s7JaclEKZD|mQ#goQgoN?)1+ovs_i(w9*XsC$_?MTpIFZuPa z8t@0i?OR!yW4w+TO!;IMWtmiZ7HnthUZZVkbAG$-Bq)S(6!aC_PMk2y_gdfZ{{Ssc zI@76D+N;>wwbbrz3o5zT-+A-G`vLuGc`l>1g#DRtk&Ka_ynRh`clyHVQ8>4^-4rX( zuo?9vp4A+BrPimXwDVdUWpGMHWEo}t^AXS=O1V^vi)reNl_r{f3itYqTDn{dm=)t? zD#v%;AKf40UTY3|Jh`fA}s5t}J4&Pel zwQHEP$mO{a?2SQ9k*;{`1$pwM`T5?8+MST7lzCCjYcj2@I~mk$U7IoaSD5(L?AyYn zfyoEu_WD+|o+rE2^{bn5BSekJ2X;uu=qsM_h2l+W&z-v$f=^6U%_kminrb2ZnFZV;W@tt?!QQAaY!p!Yv?AFW~hV$-htO?9W} zmI@@fytHU)>6d0 zHUYvL$+hz9`I^zgs<@?6TSYIwq0!pu{vOl38Gmxt9tujbUA zTbO5*F(-6`AhF;84^Tgusms)Gs&c6xiFNWj>+@ng#NLebUkvy{{{Y1rvdyH)4c3)z zxmd(ImCBrjE&N2DO?R{ScJD^Gx4G9MNn~aWV2OZO$mzh~W7OxRT<`_XvwfvSructN zdwXpz)FjikBg>w+1F0t`@vFL)k^YPxYk~xMBpI>JFn+bOqNvN-sdHKFZ9Z>Hn5vS$ zvy!s>f8ZKc{wLLBwIfH0+&YY+NZ>QEI30RbTb*XxLk8zmyN-L;Pu_WPmPBL5?DxlS zTH_?WNiQ1QA1%XRPR)gmB0uyj{(`H%iK^K_70mjp-P-SI2`45~&md>!9fxj}tn)gY z%1>`k)KS7yS~JpY^@wJXXSbZPHqv*DbB?(5scto?q<2Fz%NsuKPUdDk{~3;=8Z zySN9?)>>#f*}9KpqErJVHuwI6itRLQGHqsLxv*03?#oJ}<^6velKaQr74ZD?*!Xi# zZGTy|8J!|!SZzVh9(j-M;$NvGBcd;Drs6Lik8uD?b)D# z`o>Nd0QEI)>cnbOnXfgZazGm(Lg$V%o}B$?(c?ZVmS()x?`|wh7Z$PGGQk@Va2va4 z48R`4Bxk1GmW88VBi?Cx^_`X|(PESCq-yXC}5h<-ynqFI9y|3tH$kV&i`tvbj zv9{A9@*=S>yyO|@RRi3G1pXDPXCzkkv0C{tv_rIe@I86PPvu(X(@tqt3!o!Z&+kwI z8{84vvTiP|>~4*$Go-3lBOD#1_4cg(u`ZF{@dpU?X0@DF8k~y^Pz8|yV1>xeJw0jn zZDR=gEyOZ{Tb;;1K08({R}x1e&uB<7w&gkGA4=-AC}Hsylx}Ut+lasqj-dYlfvI(+ z%g<}BtE%%s$rRFicQG&YOJ~z$wDbJPm~K)}IVZhx)_xzBCBM^V1!B8RtH;PjF>*!slO*?9r;CS`E zhW;0^)ZS>p0!PM2-yC3Pu+KE_3EP=8Lvd({8#+k1>z%B7_dJ^Ed~>8~3#7>eYNak* z6m7hP$UN6Ia&KVKt!-8#1k8@W4g&oLZ(1qMN;13GMfe&{T^d zpTSpu+qSkbPV!|)Z2YyB7PM$q_A}Xw6Ghgg?IXH94*vjL(R?MOokC_v$xMunbNy?- z{ghVY$NJURjc%;UT3b1{wC?SLmTyl%#e6s74;O2`E4%Zx8^&e(vBakczQ9-MFYJ%u z8}AN$I?=5BsN!dZWssBAo8~`_dKKiAHsk1dRMT=t)jC}1Z)&k^%HV$wUqMn__{Q4C zN7L+py}w=>DA*q)chl3!{ zw4-ZdY@y~RYl(||(#Xt9u{~Ld>VKtqRjaB?mMh-;j>yBTjV&eoL8&9jscNm4auO&$ zL{%gE-+2C&rDfo&Ym12FyDuX~a14&lKT}%zHkzzUg(Z}ABR_>~#T>BUFb9#_6~^k- zsJ-dGzTfZ%&Z7O*V?Niwk&TM8POlWgWovm_K1V=sdHz+iXQyjc_X2xeN$w(xIf7Lg zZ++c(tsOo|5m{pSl$-)hT>{o98CWt(;|#;zl`m~g-ZOtUf5GYZSaPe(z2s0D(J~nB zB6wUJ5aXxg(AD+4SYi_ZNN)N4YWLR z1?YYHR#m*kM&0;ga(iRit~-PQRkFwP$9mPu##SvwHt9}sLj0rL_p4Hz$C5Fee7=>H z0sA`=q~Xr&9^S&84yMyc$iYOQrNtXai#8(PmA zu0h7{;}yQjKGVFaB*L7Vzt?aC< zOz||(=XNe>-Z4TTO&zh&GKK0}pM}mAk@Z#XRcpRGEXm%>g+%uu_Ny1@~%qL!@eT2w___u3tgxzJl(~6k^0xB4RT#iOS(&F8b@|! zR`lnJ;dMPX#CnC$y&h${Wh2foG1TWjg>qwX*00W`@oi(f4O#m>Mv}L42TGI0pWB~f zO&;FjIGI`6GqOS(AOY%o{W0rali|#uR}gnA{1 zhAnKg_{?@TaH+-)>|-R6-Hmt`hWr+s?jPw9{ch9wP`lh#ia~+0)utY_$2#*LGgAC(# zIX!<$Bi1}wr_L-j^XJ>T?v3KhW-@w)^!7fL<4&)&cbvWNEt%M<${z~T@jXMsZ$F1- ziQo>X>~hRL@a#UBuCrLUhgq{-Mj)Z!1&(@vIXSO9()?WpnV~vO4A)b@cfvvWHW9!l zpy+eySP}eU(lv|QTMH|p3SAuBFWxG1fWIzl-K8|>C3WSlrjGO>4aCrJxSaq1LF22Jq!edfS2P5&XZx7E>lxk@1uXWV(YdFHA zjjU~^q9=g}ZS8_iDWd4Mq^b8um5?+3eQPEucEYkDCN;U@R+S<&>*&9n^ui^gy)~c4S(k3Zd==0m1Ci_BZrJhHhPsf}h1NWAR zv|tbKFH!5#vfkcXy-MFwy<}S`)JbZf30EUf;^V*Xlg2#OCl9=`aflW}d!M2#u?=|U!p_@*npcuBc@$8e)K zBVhIXYq;@*Ro8BO?~hE?gxgK=lYzqKUu zXrC3HWRRG$4iDXI@(w+#&b5tB<+Xi3#Bn+Dok46K>TrJ=^q<=X81H;lZG51WXrn5? z;QilG^{*4rF6F*`MkY1)3Vq1xVDUX9NhvD?pXhQ2@Wz1(-&JlX}!sxBf8Exzudhf!X!@JHfsXyowj zvoJ=FK3F8=^NeG?9?4IA%<4H>=-U0I^mwg2JE!XKTt>0j-1%XgfW$sW9H{H$#F~|7Vw0Orz)BIzje`8-lt88#uM~J_gh@Se@<-$DMN1=Mu+~hddng#dYy(cKTPu zi)pnBlvr+T*dbH%D`aN_rZHX*;ZGA>J*v!*v@$Z{SsT;TdU0KK)$Nw8Yi%@FttP9d zmU~wx3fai{y+IsvSXF}My{=qk?`qGZE-!Rz?Hf=wx1vUgQR9_JW|cw92EgY4Q?zd# z+Rqes7W3g6Gr6;ngs&WW3|G#Yf5k7dTqJSbMHKO_*=_Ul1|6~7XSlAO$HpE8iC*ga zPL(bn1^l~)Rgj*nS2g2Q=jV1`iP;#&+Mc@?jP=N5oHf$VZMz9Nf(aP@mE=Ar@dehc z@h4SPo-eRRrCW(v1{v-*Fy#7e#bNwF`0r_^>8)wu{XESuOe8R$x;@Wt#=QRD#)kD? zm9KIQ5Cv7QOQ9?q>3xfGkPR$^hzluXoY>Nug*u zRi(s!DATQG)AZ*_;g&Hh)0oL$F`;k*r%nrJBxBpW_^sl98f)$1J$B*?tAuxx%~%#K+kgRnQS%%qCp>lTPJPThI&{~yuKgEZ z{Uxh+yYxAnWmnxxL(sfs{2&9|KCu?!{N6c^sARJbAguWPB zYm%gM_=`qwG1;SvTZv%@ugI*!ZhHgmUQOn{r*|f&b9r$h8xKzscM!^x0(gc#=3w2vs#mo-znrW5%+zDI~w$# z1Y2reGmifN!gsd+0Bh8&mMfha_HnvE1b8dF@=ijWlgK1jL-5+y;oD7ruG?FEt+iWV zmnjxmVY^l+>;2L}Qhu1Lm!2x{?v<+Pw-)!hb)WWfNfQ^DUEVx=r(|T1aqH<=QOjzz z%~HxY)pg%=w=l1mbGHaZ-=o|5>~NkP@Xw7rJ>sh`5$T>*nLep+b763iT7w8w1+p@F z6Sy8Y;+<)sc=~N}<5GvjS9Wk;S>|H0B9hTLU8CHq=eBcQMz!%n!SY*MYj&O^Fh{0L z8_%$`X&NEZ_ku!jt&$1G4P@K+zu~5}YKt$A_1G?=%YC3CB(k01fgx9e!1g2SU9{*b zH`UA0dUrYJI@Mk5lk>mmncjFl)8dzl{vn-8aUJfNr`biPTwJQGeruS#sLNx8+(9Lm z_=zVQt5Vxiw9sH^rP4M10^7s7M3#5*MQI${8@fpwoJkb1u^X|JkOR}2;B7oX;hRLc zkHcRdwOa@;5q@46nG+#Nz!(@j`rub@q4>5Y*6cNVgJtmw6&ZM70ts&ql4C02_al*> zhX)-G0==45aNNqZUx~X~QRPW{se8%t>&mX)iC@s*sfVv_O*w7S_v_M8ORKiMj$>W% z71x9Hy#`ok*I>~vK65S5*zj90Mvh4U;PKAjeF62aRrr0R{6f_HL8--fZ9GHa3Hf z#(Lttvq2!z{L`2n7Ug$^c1m%8`tzz&%H`c2%KWO;L3z@;f%+ zB~m_dO>-|-eKy?Zl++-vO{wa=?H`lrsmyq*{t<0A#X1&;sR^UgJX3DLrBMn`42>ek zhAyn72?_{rmy?WS=BBmqyTEoj#om>oSqs}mX+(=HvTu&z7cb?pKQw#eJEIu@gNm`^ zYYjWaS2mhvzjm|D7Ke9aFC$>GK{LmgpB!gwp>ygFHOP4P#ojK}ymda2;U5q&e-B>U z$s$W^jb#zJRd*$TG6Jrx=I1!-GBa390fm$&QgBO^X(xMZuC3j+t$labLh041DMk^N z_qzG$?{D%jz9Re*kHmUa>sk12874?t;@alYU-^h6`yT0K^K8M$_9M^2CO9+*EQM?|lb+>e6p$gZ8^p``+ z^iLApUBYa2NfuOeF-X7O9<}8@I`CcQfpsnQlzwiW?UZEaU_Fg`55%to>wgSu!Un4f7g@7)Msi_Kec->}jf9D7(B6#y;~g$IINB>a4X* zU&S}pz8LT#Tz!~Ksva^!TuGn2ao8S}#@K0^kBoJ@e+qbd)<+EC94}Vwjw|T<-xzpf z_Ga*`UK;RqwXUJ#>*#{ZbO3d-R_Y3ojpN#}_LY6Nvcp9>jb88JgnG(fqTTF_rOQ%0 z^)JiOE#&(z)$EPPybtiB_J6Up*M2YRL&P2`oOz3&Lc&6z@}1noi7{|>Z>BpsW-Uj$F;;$Y}aq%1C7OeJKV@PGY)o)zkf#(2q zIqi-sqW=JekKum{-u;W=H-jRWLP`x!Qc)|+Iufz;1ECe2B}z42d>nnXNa*WM*1uI7 z-AB?Xwbh}?IezOED=+!?9hYnO^_H)(&iF^*XT`sXm)~oTPnlNYK(k%nPq(P!EXOCk zcQby-C&OgV<1dIB1)PyL?;-Pi#@p&UV>JoX{xV0a)A zpHp1cmHQ_6w#99mP_r>yKtmaXqhlfMjP>WQUIlO6d=B`7qr}>^o}G0oM;;=Y0l3Bi z$snox_^&lm!qu0%UTJsH{%Xf_tB8t8a<~0?7CsKLg6m3@ifj}qD1$F1Dyll_k4`#LEnx4k|{h%ot^t~Qc!k6K8ij#1mx~+Fs+5Z5U^%sS_ckt@> z`y;`gE1ONzEB%4j#ZR`JpmZ654_OyPaSBo&)_H1wYa0VD0Fv%IIf~xe5@J4SwJJzSak-x zvtRg^tavBI15eT$#F|xwjFH?XpLuXnOG(NFm4M|=aC&e?IIgHr!D3TQxJugDtGjg7 zt=m^=NodYrWnM1ucfWN10I$60ekJ?}e+$hW!q}IJ?%Y9p8?tP9P?6`r*x(Vg;QYYu zAdc=Lz(+6x8)b{`$)Ng9Md4f~K>b8DMV<-V)bdkNW<$F>?0O_LkK7cH>jJveYA0y-^Y{ z!N4KMaao@bJO!fo?PI*t=Syu#$L`pkNXI+9NAj&NiXRO%{{Vx&Hg5&^p5V`Gar^xz zP*vL<)Fj{^_E;Vndmefk;zx-!9Wz@cnM%esjOQeOPHQz&k!!Q)ZmIL@9nTr@M}{?z z58q23ucylxjO|$y=0@kSA4=z;yYh3oRv?j+oDQ}1jfLKetysezqiqb9*HRXmIq*-= zXT4!+U$d`;JVdikpj^pkAsdQ}GUWRnpPfu!GHophm%8kH`)#P(x;d3w%s49Qc>Jo| z8n}lTn`u4!dkXD!KiS*Fx>SsiYSz+ueC=lB`c@tP0Kq>Qd8op86&;7lCC<~HIH*#l z-v0oDAH0k!-C3SAFC%V@ZC1(S&{lEPZzXks?Rf(nFJoStp!^5dWS`5w)Iuo0ZL5*j z9r&+N@W;Z>0{C(`?zITsd$c%VE(p)JG~+o`mnAse{ok1~YAW)7sp7sA@D{nQ&kTBm zGuzn6cPp~?_9vS4IlLtXfuyCH;o?Gbv~qdpKK1CA-XQSoO19Bi?uCE>c7Q?t^5^+i z3F3R?x%nWFTp?@)E#=4$vFK~2cp9{=R&r0tbTf@*QF7YH4X%wH#ED}q$~aMo8}$1OO#K+P}#dZNAwR%3aT<%`h`v zN=RXVsh;%>xoV4zmWNAk1WR<5;RJ#{9|tPLbv5dGKa6iYC8G;1HYEFIpnr7_AR=`0 zG5o8{v@>ZGVntGkyeJY37jDQ0^RG?Ov}QwXeQ~Kk*H0jMn_=MxMF*}ranih;ZZGuGYLfS!tokW(#VAEt zA%jSV`#ude*6w7E)sK}7tIT;hBc9pjx*rVNUEAtX-0INDJI)M$X|ZjDAsm9fzo8Y4 z4d$sEg}Ic=5(BsGQSKyn1of_$!}_#xA)D-y#1YDV?<{lb0qVb<6)IKbweE~mR9?qr zqpPC>Z#qt>G4kikL+-srdN+r!^$m#|0P(o{ufZQf-np+2=vrR3kli8#xfls0yOm(x zg?iS_zldzSKY1pD;%!3S2Vh^lz z2N@@!kO9=FJx}{R>wx%`@Ub-e@Bz2Dg6Ih&n$-M_k;IBRsXf&6Iqg>NekN(w(5>8B zMD7U!7J^YYyJPE_?UJ|KB9+bBAP z+)xE3TU%DgnUC)g&$WD?@e^3kwT~5P);gA(a}-7iJi9#NNf>g4k6=m9t$khN`|X+} z_d8jXDP5_?N4fO+SIJV^Ug};X)U_E%is9r~VY_|=Svh6{z6LQ~GHK%U-D~Ia`_E?% znxXg~Mt;xtHy1iII;8gALO05ac==RdeQVo)weF=>wzQrhF4MJ1=O01*>*c?M{sGm8 zh+X9Pg{<9LKtsoG5CLURa&v*tKr>%LXc`0>OmbV=X4uOon=9m&kdvR8i6s3i-jv}u zuV;HT+Q*erpCsMdH!ZZdZf;^tPB`ZwL+s>&-mRXs(mmy+oF~eOS&ul+8Ln=9Qr^Td z-Z!e?lBXnn1yuglit-TqUNq-ozus?hJ5#4l30tY0+@-HV%W9X8b2p#9KuFAljDMeM z^Y4gy>`=iYtLy|78@v4lZtFfEw~8YaEOU%;(S7~?mE}G(*FcI{e8Dv7!bA_<$9DAV z-m%1_q3;?|Zc@y|wSum1pAx!)M-=^d`YAOS}sIV9E+XqU<2 zYo8NqdW_O;UADI6kChla?<1yqU}CU*PpSQ(oxIm0rzbr3=D4LK>8l;K_ljN)v5!;n z%IeommC|D~rs15-{{SlfLpAiLhxONQ1L~sQRgO^GfROyCsySx$B;NXsM(b9v>#A55+|W9mum?Oa%^O{zESzWq-} z3l3N*+g<+Smb1H__Vw?kSscwKRbotS0OP6T=hxo7>*3eKeQU%~Hlc53U_@PpS2ewSYPvswZtv#5hfji3^CFB4FkXOrl0f6$ zy-M_9^=73jS!t%d4tG+1(KszzH?&^~$Kf3=O*#!hLlYx$;*OK@b!`FsLUs}+Av)(8BMEZo20J5q3 zqa^XqwN>%Q#9c?nH%GyGCCs1Mnq}Vmsin#+lBnPu@_OJ7+4VeoSZq^<9Y$*I`gXUf z=(?lM#M4!4dzvn%rs@9x5v1|e>F{rdqg_8mxn;Lmcll=rJK9Fi0|4ao0ZuYc9T$dl z%?s=nHr^q=g7(T4ki~5peU2p{kcg-U&h3Cpuq+39^X(2BOK%|sm6W#;!m-VAk}7WN z!Yc5p1_wDO*1L%;t!;GJZsfMV7p6Sh?Q8~P{6&ri4spe2DxX+<)nm^y zglQ{9**(2|PiLFN9vt{-;rM2{)9$UB`HO=XS)wvB5w;_okOvv-&(^%d;xCKzTZ?Nw zPs93cg2W??T-jU1#%>s#ynqCV4CH_bVtFRHd#@R4WwgyF#6oE__+N3igb>^l@&`O9 zIp+ehB#6Q<+f15EOB?L8md>XGKi%EQ0C(?LSE=u}g^Id<>s#4$l5M?xdTw4GiiWjY z*M83Zi(l}yuY6B5+D*ejr$S&QL@_kd%D~_$VZsa&S&tl7CE>4#`d)#5GV4F-X>PJ4 zQWnC79Wnjkp5~&|QZEAl+dw40-`i?h2B{U?7x+MqgM8{vHU;%2q`3Hh;r((4oY_eU zkhItmW-DT&CL#ykeCMwMrk*Pjx+^{MGz4)JxriLD8O z(qAz~ST;Iif;}syvhf(vwKxW&awCfHm{bNBbBv6BV!W%vH&!|?gJ;sMY}zpuz8-ANMz?ooW31Z<cJ^ z=0zVc9;bjm3h6#0Xto#n>bZtFS5SpwaLbU`Ib8h?D;8NV?=2oH&=&JekfS>FG2`VV z`-)Vn%Mndfnzcy3dH(=6M(y7F`k78Kr#r*peLG+DJcGq&XNoUA*%%Q=r?%0IsW=%p z_2#}s{i6INKj9b}j73>wh|9;Wf5N`L@hf@Py4~|KNgvqRQ?bT-epTS#7W5%?;MfL9 z6I(ot4?uC!yxe=_jB52({M$VYD(AdA>G&hz&jaZVt$4pm((nkD?E?eo4o~v0)qjVV zYoh1~f>e*}aVs_yU=6;V_^-|nfjSyo{9v=UxfokFmQoKKsN%l+(-2t}^fJgOA6mHXKD&j4F9T(-A=7!%&AxX9&G_*D9we>(LW1p6Ax zy;SdA$@26bmBM&kc3VV}ug$c1drt!coYtxFH`=exmuVp12-_rt9f`+JbB@BigzfPf zPA*#=m4>4fY!s+M`6nKguWdcEG2I~8eR-}1^TXQp?YhgSYi1mr3`PjXKgSilYoThE z5L?GBz_==)$NTpy!61S2fYw+skbG5+VQxJPML&V-J-ekTYC{ zpQ?tH;*HMu{_rQIY1`i67?#fC&2;-G6Q7%*xdicDAh(goJ#Yu5Pc@yeh{Wm`IKWou zbM>q!E><=Z5^+~oQDL@5D$Lm6p4Ft6GPBr8*_@88q<>^;q60B|Tce1}9E5)Bp5xND zw1tMw0Te)m2XnI=mM5ORwRcz3?RCpDZvbRE~vkK#MjZv8I`dh|?c8eH8WPPkrWSB82 zxU1uc&N}`^uV_~)En$jAVs;Xxy0{%FDf?F9fyKpKx2oHTp$Z#oE?8~;9CZFw=AJ9E zwX?dDP`QrXAi9JJWnkOPnZ#+F<8LPe9eVb!OPcC8M_l~QKQC(XkBgUgRyrKl_EJS0 z_TV%xBJNdef>`z#P~7&<9M%;%V=K%0=yXuKc1IhbT8M8NKebG#8Jhs@1P;}+tXx?I zipChiD*+}+$!5>^SDZuREBpJFO)afrv~7Ypg9h`mGT6sB6>ld|x{RCIM1Tyt9x?1I zvX3NUqV;D?;VC|6q25|cX0jDCD=8aUNC%Gf^XHFzLv^owb6qma$ePE)@g=kiCK@q2 z5YlneJxAeQs*@c#-fy-=JaH?_CgJyXjGxd~%^n!kt}d*m)uar!nx*8|&mlcayA{Wv z#YSg{jTlBSTkrn>1iTd?OxRLiNsbE#>n_5*aYi*6a&{_j1pTlZcwhQdhY z{>(^H-V+a$>+`DmhWd4`6XDm4HBC>$GTq%@sWwwAc$Gm9{oY4!@UE(Tdeca70&$Z<_imTPS^F||!@T{Bv@@jbke!4rP+LeLYr zPh!4=3~}D2o8l&iadUNNq>r|U&y?{89$H9A`Ek_aoZ`8Eh_@fxy1t*`YZ=-}Az;@R z5NFF+@;0Mmrg$gY>s|N5Z-p8*m#0U6J*BH%q>dVR#zQE;Q@61H0PEK_7L%LyagF-= zY*r?$V--0&9Vdl!Y4v?7;@;xb=C{0U&SXH5qLl+`CtP*wTK*gOTcv1{o6XB5#7Vid#dSH$|r@ESk?U4Tz?Qfeg6Ooryq!+I-D0SWZK|w z50F6zBl=f)Be=GvP_5=Ig)zwC6 z=_I{X%;z4cp8LeCeA%qyl*n8}kBkp<`t_>I;><-an*sCH#BPV8W|J^;nc~w zu!qC&TiL=(b&=Q}OMCvcnRRkCi=?%6C(HSnw)7vmT+efJQ++jU;L}vZ9ukZ;@C)&Q{(UPy$M?E* zu7h)jJCfIcGlf8L*VLNKySoxPqe=wwzSaxe_s7t2T>k*Z{c7IFz_&3&CMJ~xYNP5g z`s4Dhye&A!YRf~KyKXz5B7W3dn`qSbsloH=iWQpUz$s8OCnKf5UpY^cZ z93M1JUgrM*#QqDIY5LR>J-TIKx{XPWPTbaxmE+GKA(7fh!33TCN&f%}>YK$HezR<1 zpX~BNK^q?o0Pbs=xbRT7duFv>IY}|kuHKam)Q7~bRp9)MYu^)iM_E<5)GZ^H zXw<5iKk+??hRX;z*<}aS5FX5h?v5Z87CFZ-}q}x zj&^gY&nhbNH|-n0{Z-9Ulqaf#Mv$GhmCIVkjp2qFVX#P1a6=G47(H@3*Dr74L3JsQ z?F=D2ousJ8;oBaSR$VsE+F88BO}!%|?>PKw6}E|_3#Y}ng=RPy#~zgm5su2mUzqD| zwVQ2f8xd`9v_!1N=*gCl5&#Y9v;&W=Xjw&RG)R|o%uH%lAsG2^JLL5hhv7{!*3|@a zvSu;!20Ul_n(6Frbo5Uy*h?+IaIpZn81KjQu1rQD$@0eMuZ6?%q~B7`qI4Cp3vO>( zQZ}ND1>Aa{r%JDHrRy?Xn{TpV$lN25ag@hWeXwhwvD0omQFRCwsj}8hhB%JNSdVXf zSFqe^x?YE4q+V(_7HNMIfU9tuRK!;d(t3f&$8(Q*@@wNNQi_c=bJm3_Pu`Kw_yge1 zu_Nhs3l{lrr;JAd1x&da1KCd_cK~D>?`G2A@DGV^bo*=VPgUlnRm zh@+i-fG9wt+jl&4X?@^v8O|u<+gFUMP;zE34e;vd43$76Gm7 z;C3$~sQceHE0xdijCHLP6d==AYwmjO=cWGuBbiCfx6Py9`t|hCZlC)r4O_+Y>i!bg zmr}~te`dIhC98r7R{-OU-9Q8oI#&LN`#bpaL%O-SpH$PWE?)f_`Lwrb1ZcpYFd{A& zjxsQK>0Yz1>XJ{Vq437F6wq2j6oT><*v>&a_70$X9{H%Od`yX`NZM`v+=5GZt|f|Y zR#qIck};k^AbMuKidkkIH|^%sx3!g*&8zjcKN+}(LXWmxxN9q5DPhOSc-aPnk zccg1k>iRqls6{+;sfnEJ2V#w<9N_K9^u=|5WP3R}v}V`&K8{JN{npgVIhVFvl_Hj% zKg(jCpW=8f^=Yg%OM57Pn4&y7wR7m2=B3)z(C9Sw7S5!LLpZAVeG@okO3)2EUUvXWfH1cg+FCqFMw zrYoTFUW0GpNswt*vETSwNysy!w6f`wNSWTrl6<^_xko^9D~_c~)aK!eg_3vXTQ_Sf z_O_d8{l0!~XySrHof~TnOjMtv0!>Aa6&lQ-x^?EL>wZ4){{V@fO>6s5F5c=ZNsA!@M94eI9S9>F@;;S|rCDEIooee=w|i^t zJ}j(pC|DWG{{X7zk@Dwg1f1istgRDA)MV5eYkR%0OkzJW^C|}1I`ADo1CA;u3RLON zO%Aa1xt$gY6 zgWwR-yeB`4{4J@rp<}1APb%-7hQI^woNN z#a5)H7M!nRE9DAH2(kuc+ouFQr!d=7plOtp&M_JCVHF_6#WOGuO#@J@XN&i z01o_Jspw|XTbL|Y&+`y�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

|I2vE@h#I&2*<$2&Q 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%0D>K3~}ay`kE zq6AWZzYU6uKl|mtx*PT*vRFFylhcFn685v=8?XKpZNmG%aEDTkG z(4dXI`v=ka_>X z-x{Xi*#-r`DlK8Z^k zahy9duNm6KT1$6@#IiVKX&`8BaspXlqC_xQz1l+E;js}II0>?OG)6W`nloeqBaK~1 zI)n5i98xkG)JMDrhs(i)KvsXe0S-yd`oup}2&=BuQP$a!42`XpIY0yRqbJwDG;xytjlAQFqbK0oj_z zMBwhJOfN~E9f5kn=iek#mZly7O5Cu=tSJYBnFVdKRB?W2Q6{(e%sTvki3du8?1axu z93#ZqN4&Ax;uX)=%=wL2UkJfucOZ~jfzzMXaw2IfCL0YCqewk7Y;LzU#t^@MXPDPE zn8F^Q)TYd|IGvagEZ66JxOQO+X`cyZETY0W=N1x6=g7o3v3gw18)Y&^aTl$rPyR6naJ}Bth8q&Ik;WX7KO|kN-GPXv zZR{U%QczYM=4w2zE;i0?X(#1?&rb$o#QmLpO%qw(JcIRXpT>le&ge?0wX(_XL$)Bz zKqT%XRxb$!66sSo6pL!BnanLtus0%KZYt}@)_R=qL^t^Zi<6+Yh)yG?#pba{2;Heg z6Gc6?(`3v0yBYP#l5Ba&2fKIsw#J-noWujlcuB8lwOU&8BRiqD?;Vi6^|%;>;c`1v zLKX`Z>c-ZoVmu!9B)8+?Y))6ZkVLy{oC(=~N zNeS;dwF(kjW$7tNDLkB+VDuz#^PPQ+n>pC|e$p+do;v`@Fo*3LjMI)Z6oAPW#aQgA zDJ`YTxj1>u#R5n;Wdi{?tcgEZ2hBUTPXqd?dj7?l^TV*w_6DFlegp>%fvWvHQGM&P6*H(0QtJECB>kGi? z7H@A3ATuQ(na=*3ci<=Ow^MK?Uhpj%+qRQ0n%K5&^NVdK6Wew&v8{=1TNB%Ma)1AG z-tMiskLT&^$5masx_kB7tG7?~j-CX?b;!@y89!uJ8BkF|#oo8F4q{ge7=zK->87$_RY!abzQzA(zZJx|+ot zsF}|5E>ch;+Xw_BeqEvDn}!1$hLU7X`G362-M(DgA7t-*!`s!g?y{J;um?f=ppg)h zqPUT>_m=XOpiYPy1K^{b6zWlA^ue7axqtEBzk@?SbRHMUdl6CvyYityEr{DNE$T}} zR!FBicrb;$ZUx!DeRSJ55`sZdzTJ&8KR-VwIK;5Q3pwYTpv|>;If+PEHIjB+L-+o?@K!&!QxwB zkh8|t)Zn0zd~*l-Q?VFHuVEU^eR2{qhyBD)27R&;Ii7mGf1$>OqEM+E63X}Q>W;Ma ze#6OhIwbJ3FUi`mG?^~ZTd^i9chAyPyXW^hIpXW9^>NmAbn@xe(=LlqB}zx zltuH*xUGWM&xDsO(vL7GBc(Bhipmol)Go@Xlwj)err(~t1rX8vkR-=7IKry=#-kt* ztS^5-(JLim6d|FLgh~n?DV}@Y+wyaY@F3>mzCj5w--J}r)igA%A}_o7~-iE(P?BDCp+x;y;zN5zIlC|a~i ziYrq8E`HqLgnAF4L***Rah9~b44aRCbmu%5_>=*!>q1%$X_p0gv;WpvTy}ty6=d|? zS0raGM#&DEC2moG(W0`k&c64m_BUJkYU6e{_l5+;)w+J?H)_~Og*}Chxn5%gv@ zoPd`)>{aiam0MF+y@&Q&-rkRF&-+V0%6MhE{mZ!DE0NNo>NKMXpQPjNwU`g(ZKZes zmiP-GF3}p-80)4_#wHgyt9B-^OHG+rxFF;l0>wW~IYD62;E~bqgM3rS%D3JB`AvG!v4mxypFKM3XAbTbq~HNmc~OyM ziqL4Ou^q(9Cf~%rd-|p4|Lmpk3GP~D=E*0}Y@T8rmN${;$tO}kVDvFVD6gG?R$Rhd zd+Geo`v!_Ze@!HBcLk*v5Lfjjr_o=$dQqiZbU6k^W?b_i7rGrGS@bt}rHBvTofi*1 zg)1Rts2wJ)J5Xy|YDtRac@%EV#CDC;@vV!YILMzuS`%XJW1&YbDuvr_Msk|#XNZbS zHk+w4I4C`%Is2Z03H7k#^ZZ#EG{FA?1Q}jF$X$0)2uKw}wLi?>&!hdAIgEpy0dkCe zyu2vT=#S{&e_%%2!#DaH!yP>&MnUYr=Jcfl#~to=WMRx4?o=Ilyc{Z`c*bbR;`p9% z|8_=HAfF%jHub&?z6O(~!b$sW6)A?|VkL;Dhq8lcC^CEgJ;wZNyM%(ZN5AF=dOC2_ z3QGGe?ZzHaVmzoVc*t4GX-(I^{po(5HMqt;@Ly zxHEechGDB0s~@CZ=Hp^`Ei%$JSi_0J&h5n&BV$GqhQ$EwK#1pfnuGV07U4!!D?&k5 z8E1Oo)O+R$pCi=BF`Kg&NxV~r6;DMP-00ZAEZVqtJFtPA37(2+f;fd_wvsdZKGQ`x zpIrtvO#~W%aA%(>8`g@;luV0eWN1Bx@2fRrI+`CJvhEJ9hw@* zf|MD(6{7@nQWLY>P;hB_eI+BM08lzJSf4FR6laV;K_N;fi4k|sLjl7f`jn8RYe3GVlE+>AD-~4X1R+fszhf}GT+z-l=9lNgRk-Ju zJ61Trt>u_mF4kJFji|+#8+DH4eQIBL&Un9A)~WHiIWU|HAErv%FgJYLsGpb9kQ@cC zzCEQhgvB};;Vv8vYo98Dv7`u2sgw631xPi~-Y7#^WGp1DJ%7#5-Z=FW-OU)Ac*#@8 z+tRD~VW2O2GfB^%6I~VYCm*zjpRH95KRf_gJh@Vi-k-dRmrS^)KG&gNS*P^oE zO|g7jrjRSdho!RGq{mQ&_yR(?&j$Lq48Ugc`5v6$ALR8zXbEP~S!WN5RbPLRx>$@* zQ7LX5#`rLAlq?FitqrN$89&IaVR@!QeCpJLC}eH&pDH_$N>CnIz-1}d*6VE#_P;_Z z#kMed5LYHO8XG`?Q7j~Lvj7#O+0Ia@r{t2uG7}}i5=zb=Wwuo!darM2h&&2GhfNob zyi#)ZbK;OYmbq>H@anGq?+5KinAmMc@o}d7z%m3k&70J z`@`{h!?Gu7yXWjEFEQ#=h7Olv$@#LsO{=z4d^il+(3j0+kBGg&?5hRat5h6@(zJ|T zhR#&icD6&(=?`W$I81=DXd@*4mtT2>GH_53SQXjUOR^ame#0Z~&sDU;lAk?8BBhej zrHO?K#iwcc%I7mcWI3G-pr9?#iBywQsoW!lGC?1=EBl;+6)%>C2Itx4*2gv?bjxyi z(w9(_c~qvU23Q8+-wpuJAzS0=a#H79O;$B!Aj|uWtzo>d5HbBxk%+i4XqCZ1NJtZb zSq9q^k1M#2B|);MgCv`)^v;G7aAG-LJfLgc^-+ zm`Q0%@Ld8Ct5fqyc;aJiXL{h8OqXySW=LIKm@&~lPFYobaI!^7xbKUDEk3MgINZB6 z^!i;ihMcr#_2vqgrI!cr+bZMh1{V_wal^nVOSBcuKg>LVuVEC-Z(hR}?U_iM+Q+i3 zN|Hi0mh{3& zU5Udb5T{;M5+G4$cmMNAY+Ce(D2DU*{FflmjYL-hb26K%{AdKVoIis9*^S zY=l<_SlS7kqCireXTgg_@)HvL{8kt!u)>c1A0OvH+Ugc$M+JEEVqW zub2Q=Qp|j zx-LTrpAWX9OLfwg6iTG^R`oCxIHqhn_Dy3bFBvKIwLSbYEi1wdx483xX*W8po_6xC znsR0)+>S(vE}38XcTDR!iR<))+@MNLs&Ib7^La>zisdT&w&6PAc;tH(LOxhi);f_w zJv-|Fq@Bf3Mt=xb94H)Zu`;lm5A`-)Ow{+7xWEC3g3sD%;8wyjlC zD~abB!-msW^UZ1(?pq(QuQztAfgb&mF18TfYH%txwVr?K)nk1RN-3sEZMVi-&KZ|k zI~$`+d&x1m*xcMZ|CVNQ>L>VY$44yPa>u5ePQm#xsxx(wRdF8Ty->3?FLe%6>ttgi z2#Dg{^p;a5j5eMXU|;to?mxmQDJf(-L2M8~`Q2fGJEx_7%zRIK#(U6k^c3T}Vr0*& zIR*!gJ^sm_DfMj|#dIZhdML@!mwF$EsP~M7-pR z-&{}TuS}&qiu0``+QAmWRy=6gz;f0*sKOJRG>x{kctTKP;C%(6+_b3IkdN4ou3Dn4 z{49xEs%hiBWOd&$u*1GXH`3rw)@lM?P^sZP87O@X!hM*=52itv5THW2u{m6c*YA5IJqN*HM5+uSIA{Y6+x`<5VAltCC zFl9Ii)eVR;)$#?8EQ~)K(5%uqcy1S{_3yLtQ_J{8q#3Og8>t=vG~0w~Y44nTIf5gr zk`gm3y$nwn9w!L{ui-~IVjap(#^TqO33w>2^}`mD|4t;piz9z~7Z_UQnpXCkZ*QNf zEAMa>y4VUG=yxd=8GOCIXl6}W$7Ms|lNhrZrd?>%@kKuSEZM3#M%HaHGbQIenP$3J z&k%%B9?Cv3TCSD{yy8WNZd&Q8%r}9Vn4lVZb51z9&B*yDRnd4Q#VcJe@$8N@!d>~k z!sSZre4k;%Jv)O}xM<|Je+>BRrsD7(u9!1nYKye28FbK%58=-kKe@hzj0CPPJO4YI z{5EwU42OynZN)T&nVa{?=aXCT)MXB!hVfvbp7lm&0Q7&V-7-3kpJ8JC6R6UhKGCKY=Q`Uw-L2=wF*y84^x!TRk)~RQss6h_c`uy;6 zxh?F0&nJBI;N%=j0iA?73sq%Jk=BJ-RV-KN=)%k^mx--C3uY8pRArSe8Yk0mYN-&v zs@iU2Ju}=~ENh|*d&oj9Cq*KZ$;3v3y%{EyD1iT70WLjilh?t!2~ygnV|P#nbG2ZG z?s~}4nv@Sga&+%ba|9{9sZXP*ccdK!<{>F!IYl-`J8US=ea|IsrpYT0U0C&)!t3A0 z!TnGU7%xAr1SY^#Qk)%do3f*H>%_6_Ky}krm<<={&0la~ULZpjBCnLPDMzQh*l>uz zH>hx3L7lNlpDm;V0!NA~tSNz^Z(k)wcx!O9+C&!u z>esf!E!ADyHYFKvGBGh$;i!QS38tiSJkV0zH=l?D;#L5dPAdU&3xFbXi@vh%%S}}L zN`3O{$393-djR@dNzl%^^}rgL{yOY?1GP-4h6tJo#r;Ud^wpUCg|E|6IQSMNjs}NU zZiQwKCGoa|nsxdTYmF3|H~0@)#)-2=swyo~Hn|>88_P-p12hZ-Z6*C|M>j8Y^GciM zXZ!vFHrZi{c2+c7Ao`uc-P9l&oN`}uwGI>>d%Hc~jEri0KGa8m8eT!nX(Mo9^ z9vaW)J$NMQp7puBf^L_0bUbtN%+8Ar<2kfm#L4B6qn{r^PqV@Hb!Ozq^vZVFte#Q| zpaOXwFU_qE^PCs4>gysIYoHn<;0MPasP}N8p9~1IID7rF|9t!Wy?Pvh=CF!K@TOjU zmCur5P{tc&5Zu&v9Yu@!{Rn7f;zN)#ZIpXdSOy{&H;G!s+faaP%-?V^?1&^PsV zIobJ<+%DYE$c}*`gZuSf1%#E#JYFGmQc0g6erQs;Tu6WoS9?54LtAxHcXN;DGvUt( zmS%w&^>y9I?d?Lq2w6Z%v@QX*ce?+Yo7RXfDXW@x#4?IwHNLBj~uCY`n|`ud8i^K%+rMo0km@b^6sh zFF?L}LJzK@77~vF##&D|Gq$7zs8}pm{r3DHhK?^O0@h*k@7Loa8q&2_l0qtO^X;z;PtRs6i0qF>3>X^d7$XQZAoO}!d@T}c>O5|>HW!!lE~ z+;%gUVVS)}4M~F~GJYv2=_gm^G55BHYZFbY(@VpHE}OIvY$v`1Y39xirLOp-sf0vJ z0Y+hel%2Jy7>|ll{#W>Sx!slfAIc=rcTKVE!1dkVLkZ1fGi z^8pLdzF^=c2tYjFTkrjlfVD@dT4y2DU*!WIlFnv_4NxfMZ|Te$D1~s1w8qN>5Z1MM zcwR(gGn8Ldu&7YvCf@VBpCjRW)!owHY^Vra5Mz?4a0>B{&4c_b0jh>demhV-oqZr` z>C{Ut?ODAIwMkZKZ+MP3D=Jen(5c`Vat_Hf0WSqs0D-F8O0@#%jFgpP^C;|Q;XMYt zEJ;W}=ZL3499Z0T%RuGaoFXlk$F#3aHKt%@L01LgJ%)@U^kg`JN!=J04pUt$0+aR& z*##bII#SyZRNNN#_>v4FjT(7Y)Oi`Gk7XXp`!chQ5iL4v``WGewDHa9PL)q=9XLoA zwp8&u7 z%Q-u?z=6}1o(^1w`rOhS*)c(tO9_L_OXF?%XpL$%Wm;B)@OhT;M-cVlq@)U5@ zV9!UdvqWO-OH9$b~%@QUmG?H_DESWQmdT(F&je?s<|h4{Xw z<}Syllm8Y25sO;c9s*?D_fyxoDe->q@uI#p*Mu$N!@j}?_yGZ&!J?Ho5`u`#A+8Z)eYRvG;el^q)-5-@q=S^~@+u`;}tMUj}H71}UHYc(yP3#Jsn-g+cesrR0CVSEEE7^^rKd zSLfxgd%F*c%$1rI69C0eQWZ_U21kL|SwwZGCe?KF76Vl2NLKe_6f{?ts7rE5XMH_< z!?&TnTwnGg6((=f+d^5GWiRPQAQ27ZWP$E{&{o9u+y3o?Z?~HGpm#2fu6T@KN0yPt zx3XPua*%J(%>yto6`$6TKX7+I_mORbz-oSkHo#25`9Ys`;U9 zo;#JvK>t=TAC4p*Vy^ZglG5?HY{&Yx$QZ#MI(;-jbCAKGtt$4L(DcN8pu2?#blJ@Z z&`+D|)RfwL0y^Tl%xRDhZ#OGiK!d5}#aogH4mB_iqG>3iuq?0|NVNU33*__|x4wMj`qjtXghbwqIyxmr;zK_f5?W&abap#Y z*td8iE@0#jp{MyVm9n4=Y&_}(s8!1}dy6IF;=~o?UVVAL`R56v&voqEBoJUTKpN-e z_@e*nLXgM|ww|2tC2jE+v4tswK!q|Y)m6$YBkf`%lU$Xm{Sd!ymdZnI!voj zRQP0^`E;!HWxR6;7fajp?Mu#xXK-;JY`%3k@t!Q^q+`lKXooZAlJidvQ24Q=evC=< zrN;@PK~KX?mN#}80W*gt30NY~a%S$d%}8kl z2?CPID5qOczw&M!ebNP-l_jTwX#G};qaQ}_91kby4Vf}^W4&YR$^355fBpgavpGmY zN=O2)t#g7GJ3s1TqGe7R@mvfhFaISn>cF$LB6$>0;@Mog=2~EVEJ^z4N50ZhbT!W( zRW!0Eq`b=`bmRS( z7Tpaj5+~{MFm>;;9;#ExDyN&Ny$&R7R4Scv&KiJ^BGCZReio8Y7 z_;5Wd7UampElC?+5vXkB5MNK)@^IPN>Ju9pZn9f%aXG9Q#)2h8YH3yS#-?MOV1iUB zOhBy%gM}8#Pip7QSV@M2Hxi9Mc91?cN1;3DP&WUzO$f^4W3NzzcMbW9OJ`Yc9lNa* z);IiTUyT3O;Zm2zs2xZ9uzhT%6qlQ%v3)!ju!_BI2`pD*wn;EkLA8?)woc&JukxUBu+fFIMaIlJAsv9{;Tmsz zluZ|*>LJpX%>Z}G20C~rg(?Ntw0Sc+Zw*>ai5u^P(OJWNl>=E@v)S+Ts;{#pg=K{N zlO4G~xK!?&CVMR2V(^&Y-9pscJ?bmOD4c<|WEcv&Rs7wa_G_2Unm`D zeDGJ}R}z8j3xmnUYrwr5z@>U3(E!ulPaJl3>IzA2Dd}MQ%TAL1p`M2h)<^$YL|Ryr|J1ahqdmv;Feq_ zj_E!65f+ZQDxd(slYX?**~@m=2fr3Vb>FZ8T{>y zXxk^q{Rp1|VVOk?W9i?#fw%L%SVGV-)fS7~3r)|_T38!^8X)Yqin_}6%aG8w#y zv2j@=)iqDsu{IXYWQVo$`(bKQlKdNT6}>qAT%_J2mpsxC;+=@1waF<~P&!N=x$gvN zoRBIdF1hQqD8gaXEtH8WLBUEb8~C5zjsW$&k_fF$t<5=C6xX=@k!d$6mPbkj)fHD*xaqaH-_2K1n3W_2otAfjd+hQU7Gyy`5& z78)?l*-0q=0j;kt>ppuDd7WR{2nUD(%|8ka@RzBa0&JvV=z8U%Y-i~9z~n<1F!ReW zUQFm@ZXHjc7l&G~mDS(Q2;C-byxNb7<=nH~IUIp*?^DCmrM{5RA>#Nj2+q1}e$A`LhAlhui#-H$3oW#%;jS?S#QxBW7Ugj{= zXFS+PtR+S$EMwc5#hiu2uVEc=Gu;hDKuuJCH+B&c_&|MinHWp<9{1{n1~Vsva(I3o zF0QnZB9PKCX|XCRxwoE$p|8_uyW z4Xv6>D*}d>WT?2-#KrvxHaLoP_@{R3t=<#I!7(g1B@8$p25D?er0}2|c=T`(Pem=H z_+=lm|C`Dr+8bG-LU>i*dh%Y2yWo_RP?XWD53wquY{EQp+{KymPyn(ZeT%`+juera$z$7h(r}4E^Rq>B)Bo!%XH%7|hJn-o=@g8i_2+A4R z?YucRm=E9LFCK`ACe*MObbX3MbnBYZbc5=72+`gxg{8J2fB+c=zSP`pG!uoX9htp> zwdIv~W98@kku>cyNVx?MvXA*SbPGwuGgMXf!dDuoLIK?NkD~zmDe5fg7CqNm6*>?81wgImGroOyJJ+dqg^K=IhTL=I@_Uw?KxhWY1L0g-h`-nO;BBLKHYgG z8RA2u|9TU9smm_GHzCJQ;}T6%Q8>MO@;svwr0{sKOT{HK5SN*Tp`T@k3xC4eXMEa*5dwN$HFv%seR6>{%X zBYNaoy|X%Hd5ai&2%3s|VP0{KQP|~M>;X;z_n_F*4#Mw?jA+r3B1(XavZ3Zm3GB?O zlbISMc=zF*G2x6>Q{`Fin~tB3YIP5CJH^I)A$KRt1rQmV3ab@Zk|cn$UY2hGLv_Yj z8()C|C{~mM%{nzi7WXGew(2MmIKIHQXpV61gj_Sw1R≀4yT4?jV9!$M5Ot8W7cO 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 b$VBg8_Y(>@#D4=IexA6W&wqvd_w>I24bUam literal 0 HcmV?d00001 From d3efbd0996a988005426fe9582bf399bfdeff1a5 Mon Sep 17 00:00:00 2001 From: gangatp Date: Wed, 31 Jan 2024 15:56:35 +0530 Subject: [PATCH 23/54] lib3mf 2.3.0-alpha version --- Autogenerated/Bindings/C/lib3mf.h | 6 +++--- Autogenerated/Bindings/C/lib3mf_types.h | 2 +- .../Bindings/CDynamic/lib3mf_dynamic.h | 6 +++--- Autogenerated/Bindings/CDynamic/lib3mf_types.h | 2 +- Autogenerated/Bindings/Cpp/lib3mf_abi.hpp | 6 +++--- Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp | 6 +++--- Autogenerated/Bindings/Cpp/lib3mf_types.hpp | 2 +- .../Bindings/CppDynamic/lib3mf_dynamic.h | 6 +++--- .../Bindings/CppDynamic/lib3mf_dynamic.hpp | 6 +++--- .../Bindings/CppDynamic/lib3mf_types.hpp | 2 +- Autogenerated/Bindings/Go/lib3mf.go | 6 +++--- Autogenerated/Bindings/Go/lib3mf_dynamic.h | 6 +++--- Autogenerated/Bindings/Go/lib3mf_types.h | 2 +- Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h | 6 +++--- Autogenerated/Bindings/NodeJS/lib3mf_types.h | 2 +- Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas | 8 ++++---- Autogenerated/Bindings/Python/Lib3MF.py | 2 +- Autogenerated/Source/lib3mf_abi.hpp | 6 +++--- .../Source/lib3mf_interfacejournal.cpp | 2 +- Autogenerated/Source/lib3mf_interfaces.hpp | 6 +++--- Autogenerated/Source/lib3mf_types.hpp | 2 +- AutomaticComponentToolkit/lib3mf.xml | 2 +- AutomaticComponentToolkit/patch_python.bat | 17 +++++++++++++++++ AutomaticComponentToolkit/patch_python.sh | 17 +++++++++++++++++ CMakeLists.txt | 2 +- Documentation/conf.py | 2 +- Documentation/index.rst | 6 +++--- README.md | 4 ++-- SDK/Examples/CSharp/Lib3MF_Example.cs | 2 +- SDK/Examples/Pascal/Lib3MF_Example.lpr | 2 +- SDK/Examples/Python/Lib3MF_Example.py | 2 +- SDK/Readme.md | 2 +- Source/API/lib3mf.cpp | 2 +- 33 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 AutomaticComponentToolkit/patch_python.bat create mode 100644 AutomaticComponentToolkit/patch_python.sh diff --git a/Autogenerated/Bindings/C/lib3mf.h b/Autogenerated/Bindings/C/lib3mf.h index b287ecd36..257f9afa3 100644 --- a/Autogenerated/Bindings/C/lib3mf.h +++ b/Autogenerated/Bindings/C/lib3mf.h @@ -2047,7 +2047,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_setrelationshiptype(Lib3MF_Attach LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetofile(Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2056,7 +2056,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetofile(Lib3MF_Attachment pAt LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_readfromfile(Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2088,7 +2088,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_getstreamsize(Lib3MF_Attachment p LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetobuffer(Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Bindings/C/lib3mf_types.h b/Autogenerated/Bindings/C/lib3mf_types.h index b4059ad3f..46de0f1ff 100644 --- a/Autogenerated/Bindings/C/lib3mf_types.h +++ b/Autogenerated/Bindings/C/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h index c92306d14..3feee8514 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h @@ -2034,7 +2034,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_SetRelationShipTypePtr) (Lib3MF_Attachm typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2043,7 +2043,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAtt typedef Lib3MFResult (*PLib3MFAttachment_ReadFromFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2075,7 +2075,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_GetStreamSizePtr) (Lib3MF_Attachment pA typedef Lib3MFResult (*PLib3MFAttachment_WriteToBufferPtr) (Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_types.h b/Autogenerated/Bindings/CDynamic/lib3mf_types.h index b4059ad3f..46de0f1ff 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_types.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp index 455bd3225..a81f5f197 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp @@ -2047,7 +2047,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_setrelationshiptype(Lib3MF_Attach LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetofile(Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2056,7 +2056,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetofile(Lib3MF_Attachment pAt LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_readfromfile(Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2088,7 +2088,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_getstreamsize(Lib3MF_Attachment p LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetobuffer(Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp index dcd87726d..09ab8281e 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp @@ -4396,7 +4396,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) } /** - * CAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. + * CAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * @param[in] sFileName - file to read from. */ void CAttachment::ReadFromFile(const std::string & sFileName) @@ -4405,7 +4405,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) } /** - * CAttachment::ReadFromCallback - Reads a model and from the data provided by a callback function + * CAttachment::ReadFromCallback - Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * @param[in] pTheReadCallback - Callback to call for reading a data chunk * @param[in] nStreamSize - number of bytes the callback returns * @param[in] pTheSeekCallback - Callback to call for seeking in the stream. @@ -4442,7 +4442,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) } /** - * CAttachment::ReadFromBuffer - Reads an attachment from a memory buffer + * CAttachment::ReadFromBuffer - Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * @param[in] BufferBuffer - Buffer to read from */ void CAttachment::ReadFromBuffer(const CInputVector & BufferBuffer) diff --git a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp index e9c0bdad5..01e157f05 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h index 016b3c496..9c1289868 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h @@ -2034,7 +2034,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_SetRelationShipTypePtr) (Lib3MF_Attachm typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2043,7 +2043,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAtt typedef Lib3MFResult (*PLib3MFAttachment_ReadFromFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2075,7 +2075,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_GetStreamSizePtr) (Lib3MF_Attachment pA typedef Lib3MFResult (*PLib3MFAttachment_WriteToBufferPtr) (Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp index d3da42c55..a1ab0ab33 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp @@ -9522,7 +9522,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) } /** - * CAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. + * CAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * @param[in] sFileName - file to read from. */ void CAttachment::ReadFromFile(const std::string & sFileName) @@ -9531,7 +9531,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) } /** - * CAttachment::ReadFromCallback - Reads a model and from the data provided by a callback function + * CAttachment::ReadFromCallback - Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * @param[in] pTheReadCallback - Callback to call for reading a data chunk * @param[in] nStreamSize - number of bytes the callback returns * @param[in] pTheSeekCallback - Callback to call for seeking in the stream. @@ -9568,7 +9568,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) } /** - * CAttachment::ReadFromBuffer - Reads an attachment from a memory buffer + * CAttachment::ReadFromBuffer - Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * @param[in] BufferBuffer - Buffer to read from */ void CAttachment::ReadFromBuffer(const CInputVector & BufferBuffer) diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp index e9c0bdad5..01e157f05 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/Go/lib3mf.go b/Autogenerated/Bindings/Go/lib3mf.go index aeac95c81..c55f4507f 100644 --- a/Autogenerated/Bindings/Go/lib3mf.go +++ b/Autogenerated/Bindings/Go/lib3mf.go @@ -6230,7 +6230,7 @@ func (inst Attachment) WriteToFile(fileName string) error { return nil } -// ReadFromFile reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +// ReadFromFile reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. func (inst Attachment) ReadFromFile(fileName string) error { ret := C.CCall_lib3mf_attachment_readfromfile(inst.wrapperRef.LibraryHandle, inst.Ref, (*C.char)(unsafe.Pointer(&[]byte(fileName)[0]))) if ret != 0 { @@ -6239,7 +6239,7 @@ func (inst Attachment) ReadFromFile(fileName string) error { return nil } -// ReadFromCallback reads a model and from the data provided by a callback function. +// ReadFromCallback reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. func (inst Attachment) ReadFromCallback(theReadCallback ReadCallbackFunc, streamSize uint64, theSeekCallback SeekCallbackFunc, userData uintptr) error { ret := C.CCall_lib3mf_attachment_readfromcallback(inst.wrapperRef.LibraryHandle, inst.Ref, (C.Lib3MFReadCallback)(unsafe.Pointer(C.Lib3MFReadCallback_cgo)), C.uint64_t(streamSize), (C.Lib3MFSeekCallback)(unsafe.Pointer(C.Lib3MFSeekCallback_cgo)), (C.Lib3MF_pvoid)(userData)) if ret != 0 { @@ -6277,7 +6277,7 @@ func (inst Attachment) WriteToBuffer(buffer []uint8) ([]uint8, error) { return buffer[:int(neededforbuffer)], nil } -// ReadFromBuffer reads an attachment from a memory buffer. +// ReadFromBuffer reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). func (inst Attachment) ReadFromBuffer(buffer []uint8) error { ret := C.CCall_lib3mf_attachment_readfrombuffer(inst.wrapperRef.LibraryHandle, inst.Ref, C.uint64_t(len(buffer)), (*C.uint8_t)(unsafe.Pointer(&buffer[0]))) if ret != 0 { diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.h b/Autogenerated/Bindings/Go/lib3mf_dynamic.h index c92306d14..3feee8514 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.h @@ -2034,7 +2034,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_SetRelationShipTypePtr) (Lib3MF_Attachm typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2043,7 +2043,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAtt typedef Lib3MFResult (*PLib3MFAttachment_ReadFromFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2075,7 +2075,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_GetStreamSizePtr) (Lib3MF_Attachment pA typedef Lib3MFResult (*PLib3MFAttachment_WriteToBufferPtr) (Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Bindings/Go/lib3mf_types.h b/Autogenerated/Bindings/Go/lib3mf_types.h index b4059ad3f..46de0f1ff 100644 --- a/Autogenerated/Bindings/Go/lib3mf_types.h +++ b/Autogenerated/Bindings/Go/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h index c92306d14..3feee8514 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h @@ -2034,7 +2034,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_SetRelationShipTypePtr) (Lib3MF_Attachm typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2043,7 +2043,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_WriteToFilePtr) (Lib3MF_Attachment pAtt typedef Lib3MFResult (*PLib3MFAttachment_ReadFromFilePtr) (Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2075,7 +2075,7 @@ typedef Lib3MFResult (*PLib3MFAttachment_GetStreamSizePtr) (Lib3MF_Attachment pA typedef Lib3MFResult (*PLib3MFAttachment_WriteToBufferPtr) (Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_types.h b/Autogenerated/Bindings/NodeJS/lib3mf_types.h index b4059ad3f..46de0f1ff 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_types.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas index 7f51715d0..9a8f92186 100644 --- a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas +++ b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas @@ -56,7 +56,7 @@ interface LIB3MF_VERSION_MAJOR = 2; LIB3MF_VERSION_MINOR = 3; LIB3MF_VERSION_MICRO = 0; - LIB3MF_VERSION_PRERELEASEINFO = 'develop'; + LIB3MF_VERSION_PRERELEASEINFO = 'alpha'; LIB3MF_VERSION_BUILDINFO = ''; @@ -2435,7 +2435,7 @@ TLib3MFModel = class; TLib3MFAttachment_WriteToFileFunc = function(pAttachment: TLib3MFHandle; const pFileName: PAnsiChar): TLib3MFResult; cdecl; (** - * Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. + * Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2444,7 +2444,7 @@ TLib3MFModel = class; TLib3MFAttachment_ReadFromFileFunc = function(pAttachment: TLib3MFHandle; const pFileName: PAnsiChar): TLib3MFResult; cdecl; (** - * Reads a model and from the data provided by a callback function + * Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2476,7 +2476,7 @@ TLib3MFModel = class; TLib3MFAttachment_WriteToBufferFunc = function(pAttachment: TLib3MFHandle; const nBufferCount: QWord; out pBufferNeededCount: QWord; pBufferBuffer: PByte): TLib3MFResult; cdecl; (** - * Reads an attachment from a memory buffer + * Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferCount - Number of elements in buffer diff --git a/Autogenerated/Bindings/Python/Lib3MF.py b/Autogenerated/Bindings/Python/Lib3MF.py index 0268092b3..94e42a975 100644 --- a/Autogenerated/Bindings/Python/Lib3MF.py +++ b/Autogenerated/Bindings/Python/Lib3MF.py @@ -544,7 +544,7 @@ class BeamLatticeClipMode(CTypesEnum): '''Definition of BeamLatticeBallMode ''' class BeamLatticeBallMode(CTypesEnum): - None = 0 + BeamLatticeBallModeNone = 0 Mixed = 1 All = 2 '''Definition of ProgressIdentifier diff --git a/Autogenerated/Source/lib3mf_abi.hpp b/Autogenerated/Source/lib3mf_abi.hpp index 455bd3225..a81f5f197 100644 --- a/Autogenerated/Source/lib3mf_abi.hpp +++ b/Autogenerated/Source/lib3mf_abi.hpp @@ -2047,7 +2047,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_setrelationshiptype(Lib3MF_Attach LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetofile(Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. +* Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pFileName - file to read from. @@ -2056,7 +2056,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetofile(Lib3MF_Attachment pAt LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_readfromfile(Lib3MF_Attachment pAttachment, const char * pFileName); /** -* Reads a model and from the data provided by a callback function +* Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * * @param[in] pAttachment - Attachment instance. * @param[in] pTheReadCallback - Callback to call for reading a data chunk @@ -2088,7 +2088,7 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_getstreamsize(Lib3MF_Attachment p LIB3MF_DECLSPEC Lib3MFResult lib3mf_attachment_writetobuffer(Lib3MF_Attachment pAttachment, const Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer); /** -* Reads an attachment from a memory buffer +* Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * * @param[in] pAttachment - Attachment instance. * @param[in] nBufferBufferSize - Number of elements in buffer diff --git a/Autogenerated/Source/lib3mf_interfacejournal.cpp b/Autogenerated/Source/lib3mf_interfacejournal.cpp index 643eec73d..3a06266db 100644 --- a/Autogenerated/Source/lib3mf_interfacejournal.cpp +++ b/Autogenerated/Source/lib3mf_interfacejournal.cpp @@ -286,7 +286,7 @@ CLib3MFInterfaceJournal::CLib3MFInterfaceJournal (const std::string & sFileName) m_StartTime = std::chrono::high_resolution_clock::now(); m_Stream.open (sFileName, std::ios::out); m_Stream << "\n"; - m_Stream << "\n"; + m_Stream << "\n"; m_Stream << "\n"; } diff --git a/Autogenerated/Source/lib3mf_interfaces.hpp b/Autogenerated/Source/lib3mf_interfaces.hpp index 8bc997a12..f042bcd1d 100644 --- a/Autogenerated/Source/lib3mf_interfaces.hpp +++ b/Autogenerated/Source/lib3mf_interfaces.hpp @@ -2132,13 +2132,13 @@ class IAttachment : public virtual IBase { virtual void WriteToFile(const std::string & sFileName) = 0; /** - * IAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF packege, or via the WriteToFile or WriteToBuffer-methods. + * IAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * @param[in] sFileName - file to read from. */ virtual void ReadFromFile(const std::string & sFileName) = 0; /** - * IAttachment::ReadFromCallback - Reads a model and from the data provided by a callback function + * IAttachment::ReadFromCallback - Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer-methods. * @param[in] pTheReadCallback - callback function * @param[in] nStreamSize - number of bytes the callback returns * @param[in] pTheSeekCallback - callback function @@ -2161,7 +2161,7 @@ class IAttachment : public virtual IBase { virtual void WriteToBuffer(Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer) = 0; /** - * IAttachment::ReadFromBuffer - Reads an attachment from a memory buffer + * IAttachment::ReadFromBuffer - Reads an attachment from a memory buffer. This buffer is immediatly read (in contrast to the ReadFromCallback and ReadFromFile-methods). * @param[in] nBufferBufferSize - Number of elements in buffer * @param[in] pBufferBuffer - Buffer to read from */ diff --git a/Autogenerated/Source/lib3mf_types.hpp b/Autogenerated/Source/lib3mf_types.hpp index e9c0bdad5..01e157f05 100644 --- a/Autogenerated/Source/lib3mf_types.hpp +++ b/Autogenerated/Source/lib3mf_types.hpp @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "develop" +#define LIB3MF_VERSION_PRERELEASEINFO "alpha" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 26b0c171e..f6f29d8da 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -1,5 +1,5 @@ - + diff --git a/AutomaticComponentToolkit/patch_python.bat b/AutomaticComponentToolkit/patch_python.bat new file mode 100644 index 000000000..a19c08d1f --- /dev/null +++ b/AutomaticComponentToolkit/patch_python.bat @@ -0,0 +1,17 @@ +@echo off + +REM This script is to patch python binding which is using None keyword for enum. Apply this patch until ACT is fixed + +set "current_dir=%~dp0" + +REM Specify the python binding file path +set "file_path=%current_dir%\..\Autogenerated\Bindings\Python\Lib3MF.py" + +REM None is a python keyword which has to be replaced +set "search_line= None = 0" + +REM Replace None with BeamLatticeBallModeNone +set "new_line= BeamLatticeBallModeNone = 0" + +REM Use PowerShell to find and replace the line +powershell -Command "(Get-Content '%file_path%') -replace '%search_line%', '%new_line%' | Set-Content '%file_path%'" \ No newline at end of file diff --git a/AutomaticComponentToolkit/patch_python.sh b/AutomaticComponentToolkit/patch_python.sh new file mode 100644 index 000000000..ebf8b909b --- /dev/null +++ b/AutomaticComponentToolkit/patch_python.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# This script is to patch python binding which is using None keyword for enum. Apply this patch until ACT is fixed + +current_dir=`dirname "$0"` + +# Specify the python binding file path +file_path="$current_dir/../Autogenerated/Bindings/Python/Lib3MF.py" + +# None is python keyword which has to be replaced +search_line="\tNone = 0" + +# Replace None with BeamLatticeBallModeNone +new_line="\tBeamLatticeBallModeNone = 0" + +# Use sed to find and replace the line +sed -i "s|$search_line|$new_line|" "$file_path" \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fe8004a5f..ea7f2f685 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(GNUInstallDirs) set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API set(LIB3MF_VERSION_MINOR 3) # increase on every backward compatible change of the API set(LIB3MF_VERSION_MICRO 0) # increase on on every change that does not alter the API -set(LIB3MF_VERSION_PRERELEASE "develop") # denotes pre-release information of a version of lib3mf +set(LIB3MF_VERSION_PRERELEASE "alpha") # denotes pre-release information of a version of lib3mf project(lib3mf VERSION ${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO} diff --git a/Documentation/conf.py b/Documentation/conf.py index bd02a2981..bd45df012 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -22,7 +22,7 @@ author = '3MF Consortium' # The full version, including alpha/beta/rc tags -release = 'v2.3.0-develop' +release = 'v2.3.0-alpha' master_doc = 'index' diff --git a/Documentation/index.rst b/Documentation/index.rst index f47f78da9..76f108078 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -1,7 +1,7 @@ .. lib3mf documentation master file ********************************************* -lib3mf v2.3.0-develop documentation +lib3mf v2.3.0-alpha documentation ********************************************* .. image:: https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=master @@ -12,7 +12,7 @@ lib3mf v2.3.0-develop documentation :target: https://readthedocs.org/projects/lib3mf/ :alt: Documentation Status -.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-develop&color=green +.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-alpha&color=green :alt: Version .. image:: https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey @@ -27,7 +27,7 @@ lib3mf v2.3.0-develop documentation :language: bash -Welcome! This is the documentation for lib3mf v2.3.0-develop. +Welcome! This is the documentation for lib3mf v2.3.0-alpha. lib3mf is an implementation of the 3D Manufacturing Format file standard. diff --git a/README.md b/README.md index 6d0ff66c9..118dcd77d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # lib3mf -![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=develop) +![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0-alpha) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) -[![Version 2.3.0-develop](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-develop&color=green)]() +[![Version 2.3.0-alpha](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-alpha&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() [![Simplified BSD License](https://img.shields.io/static/v1.svg?label=license&message=BSD&color=green)](LICENSE) [![codecov](https://codecov.io/gh/3MFConsortium/lib3mf/branch/develop/graph/badge.svg?token=3ARnBye33c)](https://codecov.io/gh/3MFConsortium/lib3mf) diff --git a/SDK/Examples/CSharp/Lib3MF_Example.cs b/SDK/Examples/CSharp/Lib3MF_Example.cs index 1b5008c6d..a46e08ea4 100644 --- a/SDK/Examples/CSharp/Lib3MF_Example.cs +++ b/SDK/Examples/CSharp/Lib3MF_Example.cs @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CSharp application that demonstrates the usage of the CSharp bindings of the 3MF Library -Interface version: 2.2.0 +Interface version: 2.3.0 */ diff --git a/SDK/Examples/Pascal/Lib3MF_Example.lpr b/SDK/Examples/Pascal/Lib3MF_Example.lpr index 75aa62f11..4c90d59a4 100644 --- a/SDK/Examples/Pascal/Lib3MF_Example.lpr +++ b/SDK/Examples/Pascal/Lib3MF_Example.lpr @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Pascal application that demonstrates the usage of the Pascal bindings of the 3MF Library -Interface version: 2.2.0 +Interface version: 2.3.0 *) diff --git a/SDK/Examples/Python/Lib3MF_Example.py b/SDK/Examples/Python/Lib3MF_Example.py index 4c3d2a864..5a1ccff7a 100644 --- a/SDK/Examples/Python/Lib3MF_Example.py +++ b/SDK/Examples/Python/Lib3MF_Example.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python application that demonstrates the usage of the Python bindings of the 3MF Library -Interface version: 2.2.0 +Interface version: 2.3.0 ''' diff --git a/SDK/Readme.md b/SDK/Readme.md index 06b1d9739..7deb78b2c 100644 --- a/SDK/Readme.md +++ b/SDK/Readme.md @@ -18,4 +18,4 @@ The specification can be downloaded at ## Documentation -lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.0-develop.pdf](Documentation/lib3mf_v2.3.0-develop.pdf). +lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.0-alpha.pdf](Documentation/lib3mf_v2.3.0-alpha.pdf). diff --git a/Source/API/lib3mf.cpp b/Source/API/lib3mf.cpp index 101a1c066..ba7212770 100644 --- a/Source/API/lib3mf.cpp +++ b/Source/API/lib3mf.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It needs to be generated only once. -Interface version: 2.2.0 +Interface version: 2.3.0 */ From 9ab96e6b6547d98248d6ee808f298e37c3239d0e Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 1 Feb 2024 18:51:38 +0530 Subject: [PATCH 24/54] update credits --- SDK/Credits.txt | 138 ++++++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 56 deletions(-) diff --git a/SDK/Credits.txt b/SDK/Credits.txt index 1476d7aa9..313ef1e49 100644 --- a/SDK/Credits.txt +++ b/SDK/Credits.txt @@ -3,70 +3,65 @@ Version information of libraries compiled into lib3mf: ----------------------------------------- -libzip 1.7.3 +libzip v1.10.1 https://libzip.org/license/ -Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - -The authors can be contacted at - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -zlib 1.2.11 +Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +zlib 1.3.0 http://www.zlib.net/zlib_license.html -Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler +Copyright notice: -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. + (C) 1995-2024 Jean-loup Gailly and Mark Adler -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. -The data format used by the zlib library is described by RFCs (Request for -Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 -(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu -cpp-base64 1.01.00 +cpp-base64 v2.rc.08 https://github.com/ReneNyffenegger/cpp-base64/blob/master/LICENSE Copyright © 2004-2017 by René Nyffenegger @@ -86,4 +81,35 @@ freely, subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original source code. -3. This notice may not be removed or altered from any source distribution. \ No newline at end of file +3. This notice may not be removed or altered from any source distribution. + + +fast_float v6.0.0 +https://github.com/fastfloat/fast_float/blob/main/LICENSE-MIT +MIT License + +Copyright (c) 2021 The fast_float authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file From e242855f6671bd4dbf784bd60a66e66c8f6204e4 Mon Sep 17 00:00:00 2001 From: gangatp Date: Tue, 5 Mar 2024 19:32:36 +0530 Subject: [PATCH 25/54] renaming version from 2.3.0-alpha to 2.3.0 --- Autogenerated/Bindings/C/lib3mf_types.h | 2 +- Autogenerated/Bindings/CDynamic/lib3mf_types.h | 2 +- Autogenerated/Bindings/Cpp/lib3mf_types.hpp | 2 +- Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp | 2 +- Autogenerated/Bindings/Go/lib3mf_types.h | 2 +- Autogenerated/Bindings/NodeJS/lib3mf_types.h | 2 +- Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas | 2 +- Autogenerated/Source/lib3mf_interfacejournal.cpp | 2 +- Autogenerated/Source/lib3mf_types.hpp | 2 +- AutomaticComponentToolkit/lib3mf.xml | 2 +- Documentation/conf.py | 2 +- Documentation/index.rst | 6 +++--- SDK/Readme.md | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Autogenerated/Bindings/C/lib3mf_types.h b/Autogenerated/Bindings/C/lib3mf_types.h index 46de0f1ff..85f2a0a12 100644 --- a/Autogenerated/Bindings/C/lib3mf_types.h +++ b/Autogenerated/Bindings/C/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_types.h b/Autogenerated/Bindings/CDynamic/lib3mf_types.h index 46de0f1ff..85f2a0a12 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_types.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp index 01e157f05..62176df53 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp index 01e157f05..62176df53 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/Go/lib3mf_types.h b/Autogenerated/Bindings/Go/lib3mf_types.h index 46de0f1ff..85f2a0a12 100644 --- a/Autogenerated/Bindings/Go/lib3mf_types.h +++ b/Autogenerated/Bindings/Go/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_types.h b/Autogenerated/Bindings/NodeJS/lib3mf_types.h index 46de0f1ff..85f2a0a12 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_types.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_types.h @@ -86,7 +86,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas index 9a8f92186..074540d11 100644 --- a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas +++ b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas @@ -56,7 +56,7 @@ interface LIB3MF_VERSION_MAJOR = 2; LIB3MF_VERSION_MINOR = 3; LIB3MF_VERSION_MICRO = 0; - LIB3MF_VERSION_PRERELEASEINFO = 'alpha'; + LIB3MF_VERSION_PRERELEASEINFO = ''; LIB3MF_VERSION_BUILDINFO = ''; diff --git a/Autogenerated/Source/lib3mf_interfacejournal.cpp b/Autogenerated/Source/lib3mf_interfacejournal.cpp index 3a06266db..8ebbe5e01 100644 --- a/Autogenerated/Source/lib3mf_interfacejournal.cpp +++ b/Autogenerated/Source/lib3mf_interfacejournal.cpp @@ -286,7 +286,7 @@ CLib3MFInterfaceJournal::CLib3MFInterfaceJournal (const std::string & sFileName) m_StartTime = std::chrono::high_resolution_clock::now(); m_Stream.open (sFileName, std::ios::out); m_Stream << "\n"; - m_Stream << "\n"; + m_Stream << "\n"; m_Stream << "\n"; } diff --git a/Autogenerated/Source/lib3mf_types.hpp b/Autogenerated/Source/lib3mf_types.hpp index 01e157f05..62176df53 100644 --- a/Autogenerated/Source/lib3mf_types.hpp +++ b/Autogenerated/Source/lib3mf_types.hpp @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 #define LIB3MF_VERSION_MICRO 0 -#define LIB3MF_VERSION_PRERELEASEINFO "alpha" +#define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" /************************************************************************************************************************* diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index f6f29d8da..90e22e66e 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -1,5 +1,5 @@ - + diff --git a/Documentation/conf.py b/Documentation/conf.py index bd45df012..3c28edb92 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -22,7 +22,7 @@ author = '3MF Consortium' # The full version, including alpha/beta/rc tags -release = 'v2.3.0-alpha' +release = 'v2.3.0' master_doc = 'index' diff --git a/Documentation/index.rst b/Documentation/index.rst index 76f108078..8d5b57f87 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -1,7 +1,7 @@ .. lib3mf documentation master file ********************************************* -lib3mf v2.3.0-alpha documentation +lib3mf v2.3.0 documentation ********************************************* .. image:: https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=master @@ -12,7 +12,7 @@ lib3mf v2.3.0-alpha documentation :target: https://readthedocs.org/projects/lib3mf/ :alt: Documentation Status -.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-alpha&color=green +.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0&color=green :alt: Version .. image:: https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey @@ -27,7 +27,7 @@ lib3mf v2.3.0-alpha documentation :language: bash -Welcome! This is the documentation for lib3mf v2.3.0-alpha. +Welcome! This is the documentation for lib3mf v2.3.0. lib3mf is an implementation of the 3D Manufacturing Format file standard. diff --git a/SDK/Readme.md b/SDK/Readme.md index 7deb78b2c..0e3c835c1 100644 --- a/SDK/Readme.md +++ b/SDK/Readme.md @@ -18,4 +18,4 @@ The specification can be downloaded at ## Documentation -lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.0-alpha.pdf](Documentation/lib3mf_v2.3.0-alpha.pdf). +lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.0.pdf](Documentation/lib3mf_v2.3.0.pdf). From 08feef223ef958f0c8ac00f17e59b076c5e7c222 Mon Sep 17 00:00:00 2001 From: gangatp <145573667+gangatp@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:18:09 +0530 Subject: [PATCH 26/54] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 118dcd77d..572b32ec9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # lib3mf -![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0-alpha) +![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) [![Version 2.3.0-alpha](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-alpha&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() From eb799bc1bdf9a08231bb94e2cf750c941821d403 Mon Sep 17 00:00:00 2001 From: gangatp <145573667+gangatp@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:20:03 +0530 Subject: [PATCH 27/54] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 118dcd77d..572b32ec9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # lib3mf -![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0-alpha) +![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) [![Version 2.3.0-alpha](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-alpha&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() From a77059c488cc81d87ee4d72a73350ae77204204f Mon Sep 17 00:00:00 2001 From: gangatp Date: Wed, 13 Mar 2024 15:54:46 +0530 Subject: [PATCH 28/54] removing alpha --- CMakeLists.txt | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea7f2f685..469f77ec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(GNUInstallDirs) set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API set(LIB3MF_VERSION_MINOR 3) # increase on every backward compatible change of the API set(LIB3MF_VERSION_MICRO 0) # increase on on every change that does not alter the API -set(LIB3MF_VERSION_PRERELEASE "alpha") # denotes pre-release information of a version of lib3mf +set(LIB3MF_VERSION_PRERELEASE "") # denotes pre-release information of a version of lib3mf project(lib3mf VERSION ${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO} diff --git a/README.md b/README.md index 118dcd77d..0b3345627 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # lib3mf -![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0-alpha) +![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) -[![Version 2.3.0-alpha](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0-alpha&color=green)]() +[![Version 2.3.0](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() [![Simplified BSD License](https://img.shields.io/static/v1.svg?label=license&message=BSD&color=green)](LICENSE) [![codecov](https://codecov.io/gh/3MFConsortium/lib3mf/branch/develop/graph/badge.svg?token=3ARnBye33c)](https://codecov.io/gh/3MFConsortium/lib3mf) From 0f842544c535eaed1cb1ec10266444794f27bf7f Mon Sep 17 00:00:00 2001 From: gangatp Date: Wed, 13 Mar 2024 21:19:22 +0530 Subject: [PATCH 29/54] replacing 2.3.0 to 2.3.1 --- Autogenerated/Bindings/C/lib3mf.h | 2 +- Autogenerated/Bindings/C/lib3mf_types.h | 4 +- .../Bindings/CDynamic/lib3mf_dynamic.cc | 2 +- .../Bindings/CDynamic/lib3mf_dynamic.h | 2 +- .../Bindings/CDynamic/lib3mf_types.h | 4 +- Autogenerated/Bindings/CSharp/Lib3MF.cs | 2 +- Autogenerated/Bindings/Cpp/lib3mf_abi.hpp | 2 +- .../Bindings/Cpp/lib3mf_implicit.hpp | 2 +- Autogenerated/Bindings/Cpp/lib3mf_types.hpp | 4 +- .../Bindings/CppDynamic/lib3mf_abi.hpp | 2 +- .../Bindings/CppDynamic/lib3mf_dynamic.h | 2 +- .../Bindings/CppDynamic/lib3mf_dynamic.hpp | 2 +- .../Bindings/CppDynamic/lib3mf_types.hpp | 4 +- Autogenerated/Bindings/Go/cfunc.go | 2 +- Autogenerated/Bindings/Go/lib3mf.go | 2 +- Autogenerated/Bindings/Go/lib3mf_dynamic.cc | 2 +- Autogenerated/Bindings/Go/lib3mf_dynamic.h | 2 +- Autogenerated/Bindings/Go/lib3mf_impl.go | 5843 +++++++++-------- Autogenerated/Bindings/Go/lib3mf_types.h | 4 +- .../Bindings/NodeJS/lib3mf_dynamic.cc | 2 +- .../Bindings/NodeJS/lib3mf_dynamic.h | 2 +- .../Bindings/NodeJS/lib3mf_nodeaddon.cc | 2 +- .../Bindings/NodeJS/lib3mf_nodewrapper.cc | 2 +- .../Bindings/NodeJS/lib3mf_nodewrapper.h | 2 +- Autogenerated/Bindings/NodeJS/lib3mf_types.h | 4 +- Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas | 4 +- Autogenerated/Bindings/Python/Lib3MF.py | 4 +- Autogenerated/Source/lib3mf_abi.hpp | 2 +- .../Source/lib3mf_interfaceexception.cpp | 2 +- .../Source/lib3mf_interfaceexception.hpp | 2 +- .../Source/lib3mf_interfacejournal.cpp | 4 +- .../Source/lib3mf_interfacejournal.hpp | 2 +- Autogenerated/Source/lib3mf_interfaces.hpp | 2 +- .../Source/lib3mf_interfacewrapper.cpp | 2 +- Autogenerated/Source/lib3mf_types.hpp | 4 +- AutomaticComponentToolkit/lib3mf.xml | 2 +- CMakeLists.txt | 2 +- Documentation/conf.py | 2 +- Documentation/index.rst | 6 +- SDK/Examples/CSharp/Lib3MF_Example.cs | 2 +- SDK/Examples/Pascal/Lib3MF_Example.lpr | 2 +- SDK/Examples/Python/Lib3MF_Example.py | 2 +- SDK/Readme.md | 2 +- Source/API/lib3mf.cpp | 2 +- 44 files changed, 3001 insertions(+), 2952 deletions(-) diff --git a/Autogenerated/Bindings/C/lib3mf.h b/Autogenerated/Bindings/C/lib3mf.h index 257f9afa3..d22a9aac1 100644 --- a/Autogenerated/Bindings/C/lib3mf.h +++ b/Autogenerated/Bindings/C/lib3mf.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/C/lib3mf_types.h b/Autogenerated/Bindings/C/lib3mf_types.h index 85f2a0a12..a0c6149a6 100644 --- a/Autogenerated/Bindings/C/lib3mf_types.h +++ b/Autogenerated/Bindings/C/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc index 967ef1f16..937582f41 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h index 3feee8514..c524c7583 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_types.h b/Autogenerated/Bindings/CDynamic/lib3mf_types.h index 85f2a0a12..a0c6149a6 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_types.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/CSharp/Lib3MF.cs b/Autogenerated/Bindings/CSharp/Lib3MF.cs index 1addacc92..fab65add3 100644 --- a/Autogenerated/Bindings/CSharp/Lib3MF.cs +++ b/Autogenerated/Bindings/CSharp/Lib3MF.cs @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CSharp file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp index a81f5f197..864f8704d 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp index 09ab8281e..c5718c58f 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp index 62176df53..bc584e7b5 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -84,7 +84,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp index ee6ae7bba..255061d89 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h index 9c1289868..5aef62409 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp index a1ab0ab33..3411be9e3 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp index 62176df53..bc584e7b5 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -84,7 +84,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/Go/cfunc.go b/Autogenerated/Bindings/Go/cfunc.go index dbb8966e6..66d256455 100644 --- a/Autogenerated/Bindings/Go/cfunc.go +++ b/Autogenerated/Bindings/Go/cfunc.go @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go wrapper file in order to allow an easy use of the 3MF Library. -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Go/lib3mf.go b/Autogenerated/Bindings/Go/lib3mf.go index c55f4507f..c454d5b63 100644 --- a/Autogenerated/Bindings/Go/lib3mf.go +++ b/Autogenerated/Bindings/Go/lib3mf.go @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go wrapper file in order to allow an easy use of the 3MF Library. -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.cc b/Autogenerated/Bindings/Go/lib3mf_dynamic.cc index 967ef1f16..937582f41 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.h b/Autogenerated/Bindings/Go/lib3mf_dynamic.h index 3feee8514..c524c7583 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_impl.go b/Autogenerated/Bindings/Go/lib3mf_impl.go index 8ef411b33..8fc4c8d1c 100644 --- a/Autogenerated/Bindings/Go/lib3mf_impl.go +++ b/Autogenerated/Bindings/Go/lib3mf_impl.go @@ -29,490 +29,489 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go implementation file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ - package lib3mf // #include import "C" import ( - "fmt" - "errors" - "syscall" - "unsafe" + "errors" + "fmt" + "syscall" + "unsafe" ) type Lib3MFImplementation struct { - Initialized bool - DLLHandle syscall.Handle - Lib3MF_writer_writetofile uintptr - Lib3MF_writer_getstreamsize uintptr - Lib3MF_writer_writetobuffer uintptr - Lib3MF_writer_writetocallback uintptr - Lib3MF_writer_setprogresscallback uintptr - Lib3MF_writer_getdecimalprecision uintptr - Lib3MF_writer_setdecimalprecision uintptr - Lib3MF_writer_setstrictmodeactive uintptr - Lib3MF_writer_getstrictmodeactive uintptr - Lib3MF_writer_getwarning uintptr - Lib3MF_writer_getwarningcount uintptr - Lib3MF_writer_addkeywrappingcallback uintptr - Lib3MF_writer_setcontentencryptioncallback uintptr - Lib3MF_reader_readfromfile uintptr - Lib3MF_reader_readfrombuffer uintptr - Lib3MF_reader_readfromcallback uintptr - Lib3MF_reader_setprogresscallback uintptr - Lib3MF_reader_addrelationtoread uintptr - Lib3MF_reader_removerelationtoread uintptr - Lib3MF_reader_setstrictmodeactive uintptr - Lib3MF_reader_getstrictmodeactive uintptr - Lib3MF_reader_getwarning uintptr - Lib3MF_reader_getwarningcount uintptr - Lib3MF_reader_addkeywrappingcallback uintptr - Lib3MF_reader_setcontentencryptioncallback uintptr - Lib3MF_packagepart_getpath uintptr - Lib3MF_packagepart_setpath uintptr - Lib3MF_resource_getresourceid uintptr - Lib3MF_resource_getuniqueresourceid uintptr - Lib3MF_resource_packagepart uintptr - Lib3MF_resource_setpackagepart uintptr - Lib3MF_resource_getmodelresourceid uintptr - Lib3MF_resourceiterator_movenext uintptr - Lib3MF_resourceiterator_moveprevious uintptr - Lib3MF_resourceiterator_getcurrent uintptr - Lib3MF_resourceiterator_clone uintptr - Lib3MF_resourceiterator_count uintptr - Lib3MF_slicestackiterator_getcurrentslicestack uintptr - Lib3MF_objectiterator_getcurrentobject uintptr - Lib3MF_meshobjectiterator_getcurrentmeshobject uintptr - Lib3MF_componentsobjectiterator_getcurrentcomponentsobject uintptr - Lib3MF_texture2diterator_getcurrenttexture2d uintptr - Lib3MF_basematerialgroupiterator_getcurrentbasematerialgroup uintptr - Lib3MF_colorgroupiterator_getcurrentcolorgroup uintptr - Lib3MF_texture2dgroupiterator_getcurrenttexture2dgroup uintptr + Initialized bool + DLLHandle syscall.Handle + Lib3MF_writer_writetofile uintptr + Lib3MF_writer_getstreamsize uintptr + Lib3MF_writer_writetobuffer uintptr + Lib3MF_writer_writetocallback uintptr + Lib3MF_writer_setprogresscallback uintptr + Lib3MF_writer_getdecimalprecision uintptr + Lib3MF_writer_setdecimalprecision uintptr + Lib3MF_writer_setstrictmodeactive uintptr + Lib3MF_writer_getstrictmodeactive uintptr + Lib3MF_writer_getwarning uintptr + Lib3MF_writer_getwarningcount uintptr + Lib3MF_writer_addkeywrappingcallback uintptr + Lib3MF_writer_setcontentencryptioncallback uintptr + Lib3MF_reader_readfromfile uintptr + Lib3MF_reader_readfrombuffer uintptr + Lib3MF_reader_readfromcallback uintptr + Lib3MF_reader_setprogresscallback uintptr + Lib3MF_reader_addrelationtoread uintptr + Lib3MF_reader_removerelationtoread uintptr + Lib3MF_reader_setstrictmodeactive uintptr + Lib3MF_reader_getstrictmodeactive uintptr + Lib3MF_reader_getwarning uintptr + Lib3MF_reader_getwarningcount uintptr + Lib3MF_reader_addkeywrappingcallback uintptr + Lib3MF_reader_setcontentencryptioncallback uintptr + Lib3MF_packagepart_getpath uintptr + Lib3MF_packagepart_setpath uintptr + Lib3MF_resource_getresourceid uintptr + Lib3MF_resource_getuniqueresourceid uintptr + Lib3MF_resource_packagepart uintptr + Lib3MF_resource_setpackagepart uintptr + Lib3MF_resource_getmodelresourceid uintptr + Lib3MF_resourceiterator_movenext uintptr + Lib3MF_resourceiterator_moveprevious uintptr + Lib3MF_resourceiterator_getcurrent uintptr + Lib3MF_resourceiterator_clone uintptr + Lib3MF_resourceiterator_count uintptr + Lib3MF_slicestackiterator_getcurrentslicestack uintptr + Lib3MF_objectiterator_getcurrentobject uintptr + Lib3MF_meshobjectiterator_getcurrentmeshobject uintptr + Lib3MF_componentsobjectiterator_getcurrentcomponentsobject uintptr + Lib3MF_texture2diterator_getcurrenttexture2d uintptr + Lib3MF_basematerialgroupiterator_getcurrentbasematerialgroup uintptr + Lib3MF_colorgroupiterator_getcurrentcolorgroup uintptr + Lib3MF_texture2dgroupiterator_getcurrenttexture2dgroup uintptr Lib3MF_compositematerialsiterator_getcurrentcompositematerials uintptr Lib3MF_multipropertygroupiterator_getcurrentmultipropertygroup uintptr - Lib3MF_metadata_getnamespace uintptr - Lib3MF_metadata_setnamespace uintptr - Lib3MF_metadata_getname uintptr - Lib3MF_metadata_setname uintptr - Lib3MF_metadata_getkey uintptr - Lib3MF_metadata_getmustpreserve uintptr - Lib3MF_metadata_setmustpreserve uintptr - Lib3MF_metadata_gettype uintptr - Lib3MF_metadata_settype uintptr - Lib3MF_metadata_getvalue uintptr - Lib3MF_metadata_setvalue uintptr - Lib3MF_metadatagroup_getmetadatacount uintptr - Lib3MF_metadatagroup_getmetadata uintptr - Lib3MF_metadatagroup_getmetadatabykey uintptr - Lib3MF_metadatagroup_removemetadatabyindex uintptr - Lib3MF_metadatagroup_removemetadata uintptr - Lib3MF_metadatagroup_addmetadata uintptr - Lib3MF_object_gettype uintptr - Lib3MF_object_settype uintptr - Lib3MF_object_getname uintptr - Lib3MF_object_setname uintptr - Lib3MF_object_getpartnumber uintptr - Lib3MF_object_setpartnumber uintptr - Lib3MF_object_ismeshobject uintptr - Lib3MF_object_iscomponentsobject uintptr - Lib3MF_object_isvalid uintptr - Lib3MF_object_setattachmentasthumbnail uintptr - Lib3MF_object_getthumbnailattachment uintptr - Lib3MF_object_clearthumbnailattachment uintptr - Lib3MF_object_getoutbox uintptr - Lib3MF_object_getuuid uintptr - Lib3MF_object_setuuid uintptr - Lib3MF_object_getmetadatagroup uintptr - Lib3MF_object_setslicesmeshresolution uintptr - Lib3MF_object_getslicesmeshresolution uintptr - Lib3MF_object_hasslices uintptr - Lib3MF_object_clearslicestack uintptr - Lib3MF_object_getslicestack uintptr - Lib3MF_object_assignslicestack uintptr - Lib3MF_meshobject_getvertexcount uintptr - Lib3MF_meshobject_gettrianglecount uintptr - Lib3MF_meshobject_getvertex uintptr - Lib3MF_meshobject_setvertex uintptr - Lib3MF_meshobject_addvertex uintptr - Lib3MF_meshobject_getvertices uintptr - Lib3MF_meshobject_gettriangle uintptr - Lib3MF_meshobject_settriangle uintptr - Lib3MF_meshobject_addtriangle uintptr - Lib3MF_meshobject_gettriangleindices uintptr - Lib3MF_meshobject_setobjectlevelproperty uintptr - Lib3MF_meshobject_getobjectlevelproperty uintptr - Lib3MF_meshobject_settriangleproperties uintptr - Lib3MF_meshobject_gettriangleproperties uintptr - Lib3MF_meshobject_setalltriangleproperties uintptr - Lib3MF_meshobject_getalltriangleproperties uintptr - Lib3MF_meshobject_clearallproperties uintptr - Lib3MF_meshobject_setgeometry uintptr - Lib3MF_meshobject_ismanifoldandoriented uintptr - Lib3MF_meshobject_beamlattice uintptr - Lib3MF_beamlattice_getminlength uintptr - Lib3MF_beamlattice_setminlength uintptr - Lib3MF_beamlattice_getclipping uintptr - Lib3MF_beamlattice_setclipping uintptr - Lib3MF_beamlattice_getrepresentation uintptr - Lib3MF_beamlattice_setrepresentation uintptr - Lib3MF_beamlattice_getballoptions uintptr - Lib3MF_beamlattice_setballoptions uintptr - Lib3MF_beamlattice_getbeamcount uintptr - Lib3MF_beamlattice_getbeam uintptr - Lib3MF_beamlattice_addbeam uintptr - Lib3MF_beamlattice_setbeam uintptr - Lib3MF_beamlattice_setbeams uintptr - Lib3MF_beamlattice_getbeams uintptr - Lib3MF_beamlattice_getballcount uintptr - Lib3MF_beamlattice_getball uintptr - Lib3MF_beamlattice_addball uintptr - Lib3MF_beamlattice_setball uintptr - Lib3MF_beamlattice_setballs uintptr - Lib3MF_beamlattice_getballs uintptr - Lib3MF_beamlattice_getbeamsetcount uintptr - Lib3MF_beamlattice_addbeamset uintptr - Lib3MF_beamlattice_getbeamset uintptr - Lib3MF_component_getobjectresource uintptr - Lib3MF_component_getobjectresourceid uintptr - Lib3MF_component_getuuid uintptr - Lib3MF_component_setuuid uintptr - Lib3MF_component_hastransform uintptr - Lib3MF_component_gettransform uintptr - Lib3MF_component_settransform uintptr - Lib3MF_componentsobject_addcomponent uintptr - Lib3MF_componentsobject_getcomponent uintptr - Lib3MF_componentsobject_getcomponentcount uintptr - Lib3MF_beamset_setname uintptr - Lib3MF_beamset_getname uintptr - Lib3MF_beamset_setidentifier uintptr - Lib3MF_beamset_getidentifier uintptr - Lib3MF_beamset_getreferencecount uintptr - Lib3MF_beamset_setreferences uintptr - Lib3MF_beamset_getreferences uintptr - Lib3MF_beamset_getballreferencecount uintptr - Lib3MF_beamset_setballreferences uintptr - Lib3MF_beamset_getballreferences uintptr - Lib3MF_basematerialgroup_getcount uintptr - Lib3MF_basematerialgroup_getallpropertyids uintptr - Lib3MF_basematerialgroup_addmaterial uintptr - Lib3MF_basematerialgroup_removematerial uintptr - Lib3MF_basematerialgroup_getname uintptr - Lib3MF_basematerialgroup_setname uintptr - Lib3MF_basematerialgroup_setdisplaycolor uintptr - Lib3MF_basematerialgroup_getdisplaycolor uintptr - Lib3MF_colorgroup_getcount uintptr - Lib3MF_colorgroup_getallpropertyids uintptr - Lib3MF_colorgroup_addcolor uintptr - Lib3MF_colorgroup_removecolor uintptr - Lib3MF_colorgroup_setcolor uintptr - Lib3MF_colorgroup_getcolor uintptr - Lib3MF_texture2dgroup_getcount uintptr - Lib3MF_texture2dgroup_getallpropertyids uintptr - Lib3MF_texture2dgroup_addtex2coord uintptr - Lib3MF_texture2dgroup_gettex2coord uintptr - Lib3MF_texture2dgroup_removetex2coord uintptr - Lib3MF_texture2dgroup_gettexture2d uintptr - Lib3MF_compositematerials_getcount uintptr - Lib3MF_compositematerials_getallpropertyids uintptr - Lib3MF_compositematerials_getbasematerialgroup uintptr - Lib3MF_compositematerials_addcomposite uintptr - Lib3MF_compositematerials_removecomposite uintptr - Lib3MF_compositematerials_getcomposite uintptr - Lib3MF_multipropertygroup_getcount uintptr - Lib3MF_multipropertygroup_getallpropertyids uintptr - Lib3MF_multipropertygroup_addmultiproperty uintptr - Lib3MF_multipropertygroup_setmultiproperty uintptr - Lib3MF_multipropertygroup_getmultiproperty uintptr - Lib3MF_multipropertygroup_removemultiproperty uintptr - Lib3MF_multipropertygroup_getlayercount uintptr - Lib3MF_multipropertygroup_addlayer uintptr - Lib3MF_multipropertygroup_getlayer uintptr - Lib3MF_multipropertygroup_removelayer uintptr - Lib3MF_attachment_getpath uintptr - Lib3MF_attachment_setpath uintptr - Lib3MF_attachment_packagepart uintptr - Lib3MF_attachment_getrelationshiptype uintptr - Lib3MF_attachment_setrelationshiptype uintptr - Lib3MF_attachment_writetofile uintptr - Lib3MF_attachment_readfromfile uintptr - Lib3MF_attachment_readfromcallback uintptr - Lib3MF_attachment_getstreamsize uintptr - Lib3MF_attachment_writetobuffer uintptr - Lib3MF_attachment_readfrombuffer uintptr - Lib3MF_texture2d_getattachment uintptr - Lib3MF_texture2d_setattachment uintptr - Lib3MF_texture2d_getcontenttype uintptr - Lib3MF_texture2d_setcontenttype uintptr - Lib3MF_texture2d_gettilestyleuv uintptr - Lib3MF_texture2d_settilestyleuv uintptr - Lib3MF_texture2d_getfilter uintptr - Lib3MF_texture2d_setfilter uintptr - Lib3MF_builditem_getobjectresource uintptr - Lib3MF_builditem_getuuid uintptr - Lib3MF_builditem_setuuid uintptr - Lib3MF_builditem_getobjectresourceid uintptr - Lib3MF_builditem_hasobjecttransform uintptr - Lib3MF_builditem_getobjecttransform uintptr - Lib3MF_builditem_setobjecttransform uintptr - Lib3MF_builditem_getpartnumber uintptr - Lib3MF_builditem_setpartnumber uintptr - Lib3MF_builditem_getmetadatagroup uintptr - Lib3MF_builditem_getoutbox uintptr - Lib3MF_builditemiterator_movenext uintptr - Lib3MF_builditemiterator_moveprevious uintptr - Lib3MF_builditemiterator_getcurrent uintptr - Lib3MF_builditemiterator_clone uintptr - Lib3MF_builditemiterator_count uintptr - Lib3MF_slice_setvertices uintptr - Lib3MF_slice_getvertices uintptr - Lib3MF_slice_getvertexcount uintptr - Lib3MF_slice_addpolygon uintptr - Lib3MF_slice_getpolygoncount uintptr - Lib3MF_slice_setpolygonindices uintptr - Lib3MF_slice_getpolygonindices uintptr - Lib3MF_slice_getpolygonindexcount uintptr - Lib3MF_slice_getztop uintptr - Lib3MF_slicestack_getbottomz uintptr - Lib3MF_slicestack_getslicecount uintptr - Lib3MF_slicestack_getslice uintptr - Lib3MF_slicestack_addslice uintptr - Lib3MF_slicestack_getslicerefcount uintptr - Lib3MF_slicestack_addslicestackreference uintptr - Lib3MF_slicestack_getslicestackreference uintptr - Lib3MF_slicestack_collapseslicereferences uintptr - Lib3MF_slicestack_setownpath uintptr - Lib3MF_slicestack_getownpath uintptr - Lib3MF_consumer_getconsumerid uintptr - Lib3MF_consumer_getkeyid uintptr - Lib3MF_consumer_getkeyvalue uintptr - Lib3MF_accessright_getconsumer uintptr - Lib3MF_accessright_getwrappingalgorithm uintptr - Lib3MF_accessright_getmgfalgorithm uintptr - Lib3MF_accessright_getdigestmethod uintptr - Lib3MF_contentencryptionparams_getencryptionalgorithm uintptr - Lib3MF_contentencryptionparams_getkey uintptr - Lib3MF_contentencryptionparams_getinitializationvector uintptr - Lib3MF_contentencryptionparams_getauthenticationtag uintptr - Lib3MF_contentencryptionparams_setauthenticationtag uintptr + Lib3MF_metadata_getnamespace uintptr + Lib3MF_metadata_setnamespace uintptr + Lib3MF_metadata_getname uintptr + Lib3MF_metadata_setname uintptr + Lib3MF_metadata_getkey uintptr + Lib3MF_metadata_getmustpreserve uintptr + Lib3MF_metadata_setmustpreserve uintptr + Lib3MF_metadata_gettype uintptr + Lib3MF_metadata_settype uintptr + Lib3MF_metadata_getvalue uintptr + Lib3MF_metadata_setvalue uintptr + Lib3MF_metadatagroup_getmetadatacount uintptr + Lib3MF_metadatagroup_getmetadata uintptr + Lib3MF_metadatagroup_getmetadatabykey uintptr + Lib3MF_metadatagroup_removemetadatabyindex uintptr + Lib3MF_metadatagroup_removemetadata uintptr + Lib3MF_metadatagroup_addmetadata uintptr + Lib3MF_object_gettype uintptr + Lib3MF_object_settype uintptr + Lib3MF_object_getname uintptr + Lib3MF_object_setname uintptr + Lib3MF_object_getpartnumber uintptr + Lib3MF_object_setpartnumber uintptr + Lib3MF_object_ismeshobject uintptr + Lib3MF_object_iscomponentsobject uintptr + Lib3MF_object_isvalid uintptr + Lib3MF_object_setattachmentasthumbnail uintptr + Lib3MF_object_getthumbnailattachment uintptr + Lib3MF_object_clearthumbnailattachment uintptr + Lib3MF_object_getoutbox uintptr + Lib3MF_object_getuuid uintptr + Lib3MF_object_setuuid uintptr + Lib3MF_object_getmetadatagroup uintptr + Lib3MF_object_setslicesmeshresolution uintptr + Lib3MF_object_getslicesmeshresolution uintptr + Lib3MF_object_hasslices uintptr + Lib3MF_object_clearslicestack uintptr + Lib3MF_object_getslicestack uintptr + Lib3MF_object_assignslicestack uintptr + Lib3MF_meshobject_getvertexcount uintptr + Lib3MF_meshobject_gettrianglecount uintptr + Lib3MF_meshobject_getvertex uintptr + Lib3MF_meshobject_setvertex uintptr + Lib3MF_meshobject_addvertex uintptr + Lib3MF_meshobject_getvertices uintptr + Lib3MF_meshobject_gettriangle uintptr + Lib3MF_meshobject_settriangle uintptr + Lib3MF_meshobject_addtriangle uintptr + Lib3MF_meshobject_gettriangleindices uintptr + Lib3MF_meshobject_setobjectlevelproperty uintptr + Lib3MF_meshobject_getobjectlevelproperty uintptr + Lib3MF_meshobject_settriangleproperties uintptr + Lib3MF_meshobject_gettriangleproperties uintptr + Lib3MF_meshobject_setalltriangleproperties uintptr + Lib3MF_meshobject_getalltriangleproperties uintptr + Lib3MF_meshobject_clearallproperties uintptr + Lib3MF_meshobject_setgeometry uintptr + Lib3MF_meshobject_ismanifoldandoriented uintptr + Lib3MF_meshobject_beamlattice uintptr + Lib3MF_beamlattice_getminlength uintptr + Lib3MF_beamlattice_setminlength uintptr + Lib3MF_beamlattice_getclipping uintptr + Lib3MF_beamlattice_setclipping uintptr + Lib3MF_beamlattice_getrepresentation uintptr + Lib3MF_beamlattice_setrepresentation uintptr + Lib3MF_beamlattice_getballoptions uintptr + Lib3MF_beamlattice_setballoptions uintptr + Lib3MF_beamlattice_getbeamcount uintptr + Lib3MF_beamlattice_getbeam uintptr + Lib3MF_beamlattice_addbeam uintptr + Lib3MF_beamlattice_setbeam uintptr + Lib3MF_beamlattice_setbeams uintptr + Lib3MF_beamlattice_getbeams uintptr + Lib3MF_beamlattice_getballcount uintptr + Lib3MF_beamlattice_getball uintptr + Lib3MF_beamlattice_addball uintptr + Lib3MF_beamlattice_setball uintptr + Lib3MF_beamlattice_setballs uintptr + Lib3MF_beamlattice_getballs uintptr + Lib3MF_beamlattice_getbeamsetcount uintptr + Lib3MF_beamlattice_addbeamset uintptr + Lib3MF_beamlattice_getbeamset uintptr + Lib3MF_component_getobjectresource uintptr + Lib3MF_component_getobjectresourceid uintptr + Lib3MF_component_getuuid uintptr + Lib3MF_component_setuuid uintptr + Lib3MF_component_hastransform uintptr + Lib3MF_component_gettransform uintptr + Lib3MF_component_settransform uintptr + Lib3MF_componentsobject_addcomponent uintptr + Lib3MF_componentsobject_getcomponent uintptr + Lib3MF_componentsobject_getcomponentcount uintptr + Lib3MF_beamset_setname uintptr + Lib3MF_beamset_getname uintptr + Lib3MF_beamset_setidentifier uintptr + Lib3MF_beamset_getidentifier uintptr + Lib3MF_beamset_getreferencecount uintptr + Lib3MF_beamset_setreferences uintptr + Lib3MF_beamset_getreferences uintptr + Lib3MF_beamset_getballreferencecount uintptr + Lib3MF_beamset_setballreferences uintptr + Lib3MF_beamset_getballreferences uintptr + Lib3MF_basematerialgroup_getcount uintptr + Lib3MF_basematerialgroup_getallpropertyids uintptr + Lib3MF_basematerialgroup_addmaterial uintptr + Lib3MF_basematerialgroup_removematerial uintptr + Lib3MF_basematerialgroup_getname uintptr + Lib3MF_basematerialgroup_setname uintptr + Lib3MF_basematerialgroup_setdisplaycolor uintptr + Lib3MF_basematerialgroup_getdisplaycolor uintptr + Lib3MF_colorgroup_getcount uintptr + Lib3MF_colorgroup_getallpropertyids uintptr + Lib3MF_colorgroup_addcolor uintptr + Lib3MF_colorgroup_removecolor uintptr + Lib3MF_colorgroup_setcolor uintptr + Lib3MF_colorgroup_getcolor uintptr + Lib3MF_texture2dgroup_getcount uintptr + Lib3MF_texture2dgroup_getallpropertyids uintptr + Lib3MF_texture2dgroup_addtex2coord uintptr + Lib3MF_texture2dgroup_gettex2coord uintptr + Lib3MF_texture2dgroup_removetex2coord uintptr + Lib3MF_texture2dgroup_gettexture2d uintptr + Lib3MF_compositematerials_getcount uintptr + Lib3MF_compositematerials_getallpropertyids uintptr + Lib3MF_compositematerials_getbasematerialgroup uintptr + Lib3MF_compositematerials_addcomposite uintptr + Lib3MF_compositematerials_removecomposite uintptr + Lib3MF_compositematerials_getcomposite uintptr + Lib3MF_multipropertygroup_getcount uintptr + Lib3MF_multipropertygroup_getallpropertyids uintptr + Lib3MF_multipropertygroup_addmultiproperty uintptr + Lib3MF_multipropertygroup_setmultiproperty uintptr + Lib3MF_multipropertygroup_getmultiproperty uintptr + Lib3MF_multipropertygroup_removemultiproperty uintptr + Lib3MF_multipropertygroup_getlayercount uintptr + Lib3MF_multipropertygroup_addlayer uintptr + Lib3MF_multipropertygroup_getlayer uintptr + Lib3MF_multipropertygroup_removelayer uintptr + Lib3MF_attachment_getpath uintptr + Lib3MF_attachment_setpath uintptr + Lib3MF_attachment_packagepart uintptr + Lib3MF_attachment_getrelationshiptype uintptr + Lib3MF_attachment_setrelationshiptype uintptr + Lib3MF_attachment_writetofile uintptr + Lib3MF_attachment_readfromfile uintptr + Lib3MF_attachment_readfromcallback uintptr + Lib3MF_attachment_getstreamsize uintptr + Lib3MF_attachment_writetobuffer uintptr + Lib3MF_attachment_readfrombuffer uintptr + Lib3MF_texture2d_getattachment uintptr + Lib3MF_texture2d_setattachment uintptr + Lib3MF_texture2d_getcontenttype uintptr + Lib3MF_texture2d_setcontenttype uintptr + Lib3MF_texture2d_gettilestyleuv uintptr + Lib3MF_texture2d_settilestyleuv uintptr + Lib3MF_texture2d_getfilter uintptr + Lib3MF_texture2d_setfilter uintptr + Lib3MF_builditem_getobjectresource uintptr + Lib3MF_builditem_getuuid uintptr + Lib3MF_builditem_setuuid uintptr + Lib3MF_builditem_getobjectresourceid uintptr + Lib3MF_builditem_hasobjecttransform uintptr + Lib3MF_builditem_getobjecttransform uintptr + Lib3MF_builditem_setobjecttransform uintptr + Lib3MF_builditem_getpartnumber uintptr + Lib3MF_builditem_setpartnumber uintptr + Lib3MF_builditem_getmetadatagroup uintptr + Lib3MF_builditem_getoutbox uintptr + Lib3MF_builditemiterator_movenext uintptr + Lib3MF_builditemiterator_moveprevious uintptr + Lib3MF_builditemiterator_getcurrent uintptr + Lib3MF_builditemiterator_clone uintptr + Lib3MF_builditemiterator_count uintptr + Lib3MF_slice_setvertices uintptr + Lib3MF_slice_getvertices uintptr + Lib3MF_slice_getvertexcount uintptr + Lib3MF_slice_addpolygon uintptr + Lib3MF_slice_getpolygoncount uintptr + Lib3MF_slice_setpolygonindices uintptr + Lib3MF_slice_getpolygonindices uintptr + Lib3MF_slice_getpolygonindexcount uintptr + Lib3MF_slice_getztop uintptr + Lib3MF_slicestack_getbottomz uintptr + Lib3MF_slicestack_getslicecount uintptr + Lib3MF_slicestack_getslice uintptr + Lib3MF_slicestack_addslice uintptr + Lib3MF_slicestack_getslicerefcount uintptr + Lib3MF_slicestack_addslicestackreference uintptr + Lib3MF_slicestack_getslicestackreference uintptr + Lib3MF_slicestack_collapseslicereferences uintptr + Lib3MF_slicestack_setownpath uintptr + Lib3MF_slicestack_getownpath uintptr + Lib3MF_consumer_getconsumerid uintptr + Lib3MF_consumer_getkeyid uintptr + Lib3MF_consumer_getkeyvalue uintptr + Lib3MF_accessright_getconsumer uintptr + Lib3MF_accessright_getwrappingalgorithm uintptr + Lib3MF_accessright_getmgfalgorithm uintptr + Lib3MF_accessright_getdigestmethod uintptr + Lib3MF_contentencryptionparams_getencryptionalgorithm uintptr + Lib3MF_contentencryptionparams_getkey uintptr + Lib3MF_contentencryptionparams_getinitializationvector uintptr + Lib3MF_contentencryptionparams_getauthenticationtag uintptr + Lib3MF_contentencryptionparams_setauthenticationtag uintptr Lib3MF_contentencryptionparams_getadditionalauthenticationdata uintptr - Lib3MF_contentencryptionparams_getdescriptor uintptr - Lib3MF_contentencryptionparams_getkeyuuid uintptr - Lib3MF_resourcedata_getpath uintptr - Lib3MF_resourcedata_getencryptionalgorithm uintptr - Lib3MF_resourcedata_getcompression uintptr - Lib3MF_resourcedata_getadditionalauthenticationdata uintptr - Lib3MF_resourcedatagroup_getkeyuuid uintptr - Lib3MF_resourcedatagroup_addaccessright uintptr - Lib3MF_resourcedatagroup_findaccessrightbyconsumer uintptr - Lib3MF_resourcedatagroup_removeaccessright uintptr - Lib3MF_keystore_addconsumer uintptr - Lib3MF_keystore_getconsumercount uintptr - Lib3MF_keystore_getconsumer uintptr - Lib3MF_keystore_removeconsumer uintptr - Lib3MF_keystore_findconsumer uintptr - Lib3MF_keystore_getresourcedatagroupcount uintptr - Lib3MF_keystore_addresourcedatagroup uintptr - Lib3MF_keystore_getresourcedatagroup uintptr - Lib3MF_keystore_removeresourcedatagroup uintptr - Lib3MF_keystore_findresourcedatagroup uintptr - Lib3MF_keystore_addresourcedata uintptr - Lib3MF_keystore_removeresourcedata uintptr - Lib3MF_keystore_findresourcedata uintptr - Lib3MF_keystore_getresourcedatacount uintptr - Lib3MF_keystore_getresourcedata uintptr - Lib3MF_keystore_getuuid uintptr - Lib3MF_keystore_setuuid uintptr - Lib3MF_model_rootmodelpart uintptr - Lib3MF_model_findorcreatepackagepart uintptr - Lib3MF_model_setunit uintptr - Lib3MF_model_getunit uintptr - Lib3MF_model_getlanguage uintptr - Lib3MF_model_setlanguage uintptr - Lib3MF_model_querywriter uintptr - Lib3MF_model_queryreader uintptr - Lib3MF_model_gettexture2dbyid uintptr - Lib3MF_model_getpropertytypebyid uintptr - Lib3MF_model_getbasematerialgroupbyid uintptr - Lib3MF_model_gettexture2dgroupbyid uintptr - Lib3MF_model_getcompositematerialsbyid uintptr - Lib3MF_model_getmultipropertygroupbyid uintptr - Lib3MF_model_getmeshobjectbyid uintptr - Lib3MF_model_getcomponentsobjectbyid uintptr - Lib3MF_model_getcolorgroupbyid uintptr - Lib3MF_model_getslicestackbyid uintptr - Lib3MF_model_getbuilduuid uintptr - Lib3MF_model_setbuilduuid uintptr - Lib3MF_model_getbuilditems uintptr - Lib3MF_model_getoutbox uintptr - Lib3MF_model_getresources uintptr - Lib3MF_model_getobjects uintptr - Lib3MF_model_getmeshobjects uintptr - Lib3MF_model_getcomponentsobjects uintptr - Lib3MF_model_gettexture2ds uintptr - Lib3MF_model_getbasematerialgroups uintptr - Lib3MF_model_getcolorgroups uintptr - Lib3MF_model_gettexture2dgroups uintptr - Lib3MF_model_getcompositematerials uintptr - Lib3MF_model_getmultipropertygroups uintptr - Lib3MF_model_getslicestacks uintptr - Lib3MF_model_mergetomodel uintptr - Lib3MF_model_addmeshobject uintptr - Lib3MF_model_addcomponentsobject uintptr - Lib3MF_model_addslicestack uintptr - Lib3MF_model_addtexture2dfromattachment uintptr - Lib3MF_model_addbasematerialgroup uintptr - Lib3MF_model_addcolorgroup uintptr - Lib3MF_model_addtexture2dgroup uintptr - Lib3MF_model_addcompositematerials uintptr - Lib3MF_model_addmultipropertygroup uintptr - Lib3MF_model_addbuilditem uintptr - Lib3MF_model_removebuilditem uintptr - Lib3MF_model_getmetadatagroup uintptr - Lib3MF_model_addattachment uintptr - Lib3MF_model_removeattachment uintptr - Lib3MF_model_getattachment uintptr - Lib3MF_model_findattachment uintptr - Lib3MF_model_getattachmentcount uintptr - Lib3MF_model_haspackagethumbnailattachment uintptr - Lib3MF_model_createpackagethumbnailattachment uintptr - Lib3MF_model_getpackagethumbnailattachment uintptr - Lib3MF_model_removepackagethumbnailattachment uintptr - Lib3MF_model_addcustomcontenttype uintptr - Lib3MF_model_removecustomcontenttype uintptr - Lib3MF_model_setrandomnumbercallback uintptr - Lib3MF_model_getkeystore uintptr - Lib3MF_getlibraryversion uintptr - Lib3MF_getprereleaseinformation uintptr - Lib3MF_getbuildinformation uintptr - Lib3MF_getspecificationversion uintptr - Lib3MF_createmodel uintptr - Lib3MF_release uintptr - Lib3MF_acquire uintptr - Lib3MF_setjournal uintptr - Lib3MF_getlasterror uintptr - Lib3MF_getsymbollookupmethod uintptr - Lib3MF_retrieveprogressmessage uintptr - Lib3MF_rgbatocolor uintptr - Lib3MF_floatrgbatocolor uintptr - Lib3MF_colortorgba uintptr - Lib3MF_colortofloatrgba uintptr - Lib3MF_getidentitytransform uintptr - Lib3MF_getuniformscaletransform uintptr - Lib3MF_getscaletransform uintptr - Lib3MF_gettranslationtransform uintptr + Lib3MF_contentencryptionparams_getdescriptor uintptr + Lib3MF_contentencryptionparams_getkeyuuid uintptr + Lib3MF_resourcedata_getpath uintptr + Lib3MF_resourcedata_getencryptionalgorithm uintptr + Lib3MF_resourcedata_getcompression uintptr + Lib3MF_resourcedata_getadditionalauthenticationdata uintptr + Lib3MF_resourcedatagroup_getkeyuuid uintptr + Lib3MF_resourcedatagroup_addaccessright uintptr + Lib3MF_resourcedatagroup_findaccessrightbyconsumer uintptr + Lib3MF_resourcedatagroup_removeaccessright uintptr + Lib3MF_keystore_addconsumer uintptr + Lib3MF_keystore_getconsumercount uintptr + Lib3MF_keystore_getconsumer uintptr + Lib3MF_keystore_removeconsumer uintptr + Lib3MF_keystore_findconsumer uintptr + Lib3MF_keystore_getresourcedatagroupcount uintptr + Lib3MF_keystore_addresourcedatagroup uintptr + Lib3MF_keystore_getresourcedatagroup uintptr + Lib3MF_keystore_removeresourcedatagroup uintptr + Lib3MF_keystore_findresourcedatagroup uintptr + Lib3MF_keystore_addresourcedata uintptr + Lib3MF_keystore_removeresourcedata uintptr + Lib3MF_keystore_findresourcedata uintptr + Lib3MF_keystore_getresourcedatacount uintptr + Lib3MF_keystore_getresourcedata uintptr + Lib3MF_keystore_getuuid uintptr + Lib3MF_keystore_setuuid uintptr + Lib3MF_model_rootmodelpart uintptr + Lib3MF_model_findorcreatepackagepart uintptr + Lib3MF_model_setunit uintptr + Lib3MF_model_getunit uintptr + Lib3MF_model_getlanguage uintptr + Lib3MF_model_setlanguage uintptr + Lib3MF_model_querywriter uintptr + Lib3MF_model_queryreader uintptr + Lib3MF_model_gettexture2dbyid uintptr + Lib3MF_model_getpropertytypebyid uintptr + Lib3MF_model_getbasematerialgroupbyid uintptr + Lib3MF_model_gettexture2dgroupbyid uintptr + Lib3MF_model_getcompositematerialsbyid uintptr + Lib3MF_model_getmultipropertygroupbyid uintptr + Lib3MF_model_getmeshobjectbyid uintptr + Lib3MF_model_getcomponentsobjectbyid uintptr + Lib3MF_model_getcolorgroupbyid uintptr + Lib3MF_model_getslicestackbyid uintptr + Lib3MF_model_getbuilduuid uintptr + Lib3MF_model_setbuilduuid uintptr + Lib3MF_model_getbuilditems uintptr + Lib3MF_model_getoutbox uintptr + Lib3MF_model_getresources uintptr + Lib3MF_model_getobjects uintptr + Lib3MF_model_getmeshobjects uintptr + Lib3MF_model_getcomponentsobjects uintptr + Lib3MF_model_gettexture2ds uintptr + Lib3MF_model_getbasematerialgroups uintptr + Lib3MF_model_getcolorgroups uintptr + Lib3MF_model_gettexture2dgroups uintptr + Lib3MF_model_getcompositematerials uintptr + Lib3MF_model_getmultipropertygroups uintptr + Lib3MF_model_getslicestacks uintptr + Lib3MF_model_mergetomodel uintptr + Lib3MF_model_addmeshobject uintptr + Lib3MF_model_addcomponentsobject uintptr + Lib3MF_model_addslicestack uintptr + Lib3MF_model_addtexture2dfromattachment uintptr + Lib3MF_model_addbasematerialgroup uintptr + Lib3MF_model_addcolorgroup uintptr + Lib3MF_model_addtexture2dgroup uintptr + Lib3MF_model_addcompositematerials uintptr + Lib3MF_model_addmultipropertygroup uintptr + Lib3MF_model_addbuilditem uintptr + Lib3MF_model_removebuilditem uintptr + Lib3MF_model_getmetadatagroup uintptr + Lib3MF_model_addattachment uintptr + Lib3MF_model_removeattachment uintptr + Lib3MF_model_getattachment uintptr + Lib3MF_model_findattachment uintptr + Lib3MF_model_getattachmentcount uintptr + Lib3MF_model_haspackagethumbnailattachment uintptr + Lib3MF_model_createpackagethumbnailattachment uintptr + Lib3MF_model_getpackagethumbnailattachment uintptr + Lib3MF_model_removepackagethumbnailattachment uintptr + Lib3MF_model_addcustomcontenttype uintptr + Lib3MF_model_removecustomcontenttype uintptr + Lib3MF_model_setrandomnumbercallback uintptr + Lib3MF_model_getkeystore uintptr + Lib3MF_getlibraryversion uintptr + Lib3MF_getprereleaseinformation uintptr + Lib3MF_getbuildinformation uintptr + Lib3MF_getspecificationversion uintptr + Lib3MF_createmodel uintptr + Lib3MF_release uintptr + Lib3MF_acquire uintptr + Lib3MF_setjournal uintptr + Lib3MF_getlasterror uintptr + Lib3MF_getsymbollookupmethod uintptr + Lib3MF_retrieveprogressmessage uintptr + Lib3MF_rgbatocolor uintptr + Lib3MF_floatrgbatocolor uintptr + Lib3MF_colortorgba uintptr + Lib3MF_colortofloatrgba uintptr + Lib3MF_getidentitytransform uintptr + Lib3MF_getuniformscaletransform uintptr + Lib3MF_getscaletransform uintptr + Lib3MF_gettranslationtransform uintptr } type Lib3MFImplementationHandle interface { Lib3MFHandle - GetDLLInHandle() (uintptr) - GetDLLOutHandle() (uintptr) - GetWrapper() (*Lib3MFImplementation) + GetDLLInHandle() uintptr + GetDLLOutHandle() uintptr + GetWrapper() *Lib3MFImplementation } type Lib3MFImplementationHandleStruct struct { - Implementation * Lib3MFImplementation - DLLhandle uintptr + Implementation *Lib3MFImplementation + DLLhandle uintptr } -func (handle *Lib3MFImplementationHandleStruct) Close() (error) { - if (handle.DLLhandle != 0) { - if (handle.Implementation == nil) { +func (handle *Lib3MFImplementationHandleStruct) Close() error { + if handle.DLLhandle != 0 { + if handle.Implementation == nil { return errors.New("Uninitialized DLL Implementation Handle") } - + dllhandle := handle.DLLhandle - handle.DLLhandle = 0; - + handle.DLLhandle = 0 + return handle.Implementation.CallFunction(handle.Implementation.Lib3MF_release, dllhandle) } - + return nil } -func (handle *Lib3MFImplementationHandleStruct) IsValid() (bool) { +func (handle *Lib3MFImplementationHandleStruct) IsValid() bool { return (handle.DLLhandle != 0) } -func (handle *Lib3MFImplementationHandleStruct) GetDLLInHandle() (uintptr) { - return handle.DLLhandle; +func (handle *Lib3MFImplementationHandleStruct) GetDLLInHandle() uintptr { + return handle.DLLhandle } -func (handle *Lib3MFImplementationHandleStruct) GetDLLOutHandle() (uintptr) { - return uintptr(unsafe.Pointer(&handle.DLLhandle)); +func (handle *Lib3MFImplementationHandleStruct) GetDLLOutHandle() uintptr { + return uintptr(unsafe.Pointer(&handle.DLLhandle)) } -func (handle *Lib3MFImplementationHandleStruct) GetWrapper() (*Lib3MFImplementation) { - return handle.Implementation; +func (handle *Lib3MFImplementationHandleStruct) GetWrapper() *Lib3MFImplementation { + return handle.Implementation } -func Int8OutValue(reference * int8) uintptr { +func Int8OutValue(reference *int8) uintptr { return uintptr(unsafe.Pointer(reference)) } func Int8InValue(value int8) uintptr { return uintptr(value) } -func Int16OutValue(reference * int16) uintptr { +func Int16OutValue(reference *int16) uintptr { return uintptr(unsafe.Pointer(reference)) } func Int16InValue(value int16) uintptr { return uintptr(value) } -func Int32OutValue(reference * int32) uintptr { +func Int32OutValue(reference *int32) uintptr { return uintptr(unsafe.Pointer(reference)) } func Int32InValue(value int32) uintptr { return uintptr(value) } -func Int64OutValue(reference * int64) uintptr { +func Int64OutValue(reference *int64) uintptr { return uintptr(unsafe.Pointer(reference)) } func Int64InValue(value int64) uintptr { return uintptr(value) } -func UInt8OutValue(reference * uint8) uintptr { +func UInt8OutValue(reference *uint8) uintptr { return uintptr(unsafe.Pointer(reference)) } func UInt8InValue(value uint8) uintptr { return uintptr(value) } -func UInt16OutValue(reference * uint16) uintptr { +func UInt16OutValue(reference *uint16) uintptr { return uintptr(unsafe.Pointer(reference)) } func UInt16InValue(value uint16) uintptr { return uintptr(value) } -func UInt32OutValue(reference * uint32) uintptr { +func UInt32OutValue(reference *uint32) uintptr { return uintptr(unsafe.Pointer(reference)) } func UInt32InValue(value uint32) uintptr { return uintptr(value) } -func UInt64OutValue(reference * uint64) uintptr { +func UInt64OutValue(reference *uint64) uintptr { return uintptr(unsafe.Pointer(reference)) } func UInt64InValue(value uint64) uintptr { return uintptr(value) } -func Float32OutValue(reference * float32) uintptr { +func Float32OutValue(reference *float32) uintptr { return uintptr(unsafe.Pointer(reference)) } func Float32InValue(value float32) uintptr { return uintptr(value) } -func Float64OutValue(reference * float64) uintptr { +func Float64OutValue(reference *float64) uintptr { return uintptr(unsafe.Pointer(reference)) } func Float64InValue(value float64) uintptr { return uintptr(value) } -func StringInValue (value string) uintptr { +func StringInValue(value string) uintptr { bytePtr, err := syscall.BytePtrFromString(value) if err != nil { return 0 @@ -520,69 +519,108 @@ func StringInValue (value string) uintptr { return uintptr(unsafe.Pointer(bytePtr)) } -func PtrOutValue(ptr * uintptr) uintptr { - return uintptr(unsafe.Pointer(ptr)) -} - -func BytesOutValue(bytePtr * []byte) uintptr { - return uintptr(unsafe.Pointer(bytePtr)) -} - - -func GetLib3MFErrorMessage(errorcode uint32) (string) { - switch (errorcode) { - case 1: return "NOTIMPLEMENTED"; - case 2: return "INVALIDPARAM"; - case 3: return "INVALIDCAST"; - case 4: return "BUFFERTOOSMALL"; - case 5: return "GENERICEXCEPTION"; - case 6: return "COULDNOTLOADLIBRARY"; - case 7: return "COULDNOTFINDLIBRARYEXPORT"; - case 8: return "INCOMPATIBLEBINARYVERSION"; - case 10: return "CALCULATIONABORTED"; - case 11: return "SHOULDNOTBECALLED"; - case 100: return "READERCLASSUNKNOWN"; - case 101: return "WRITERCLASSUNKNOWN"; - case 102: return "ITERATORINVALIDINDEX"; - case 103: return "INVALIDMODELRESOURCE"; - case 104: return "RESOURCENOTFOUND"; - case 105: return "INVALIDMODEL"; - case 106: return "INVALIDOBJECT"; - case 107: return "INVALIDMESHOBJECT"; - case 108: return "INVALIDCOMPONENTSOBJECT"; - case 109: return "INVALIDCOMPONENT"; - case 110: return "INVALIDBUILDITEM"; - case 111: return "INVALIDBASEMATERIALGROUP"; - case 112: return "INVALIDSLICESTACKRESOURCE"; - case 113: return "INVALIDTEXTURERESOURCE"; - case 114: return "INVALIDCOLORGROUP"; - case 115: return "INVALIDTEXTURE2DGROUP"; - case 116: return "INVALIDCOMPOSITEMATERIALS"; - case 117: return "INVALIDMULTIPROPERTYGROUP"; - case 120: return "INVALIDRESOURCEINDEX"; - case 121: return "ATTACHMENTNOTFOUND"; - case 130: return "FORBIDDENCYCLICREFERENCE"; - case 131: return "INVALIDATTACHMENTSTREAM"; - case 132: return "INVALIDPROPERTYCOUNT"; - case 140: return "UNKOWNPROGRESSIDENTIFIER"; - case 141: return "ELEMENTCOUNTEXCEEDSLIMIT"; - case 2000: return "BEAMLATTICE_INVALID_OBJECTTYPE"; - case 3000: return "INVALIDKEYSTORE"; - case 3001: return "INVALIDKEYSTORECONSUMER"; - case 3002: return "KEYSTORECONSUMERNOTFOUND"; - case 3003: return "KEYSTORERESOURCEDATANOTFOUND"; - case 3004: return "SECURECONTEXTNOTREGISTERED"; +func PtrOutValue(ptr *uintptr) uintptr { + return uintptr(unsafe.Pointer(ptr)) +} + +func BytesOutValue(bytePtr *[]byte) uintptr { + return uintptr(unsafe.Pointer(bytePtr)) +} + +func GetLib3MFErrorMessage(errorcode uint32) string { + switch errorcode { + case 1: + return "NOTIMPLEMENTED" + case 2: + return "INVALIDPARAM" + case 3: + return "INVALIDCAST" + case 4: + return "BUFFERTOOSMALL" + case 5: + return "GENERICEXCEPTION" + case 6: + return "COULDNOTLOADLIBRARY" + case 7: + return "COULDNOTFINDLIBRARYEXPORT" + case 8: + return "INCOMPATIBLEBINARYVERSION" + case 10: + return "CALCULATIONABORTED" + case 11: + return "SHOULDNOTBECALLED" + case 100: + return "READERCLASSUNKNOWN" + case 101: + return "WRITERCLASSUNKNOWN" + case 102: + return "ITERATORINVALIDINDEX" + case 103: + return "INVALIDMODELRESOURCE" + case 104: + return "RESOURCENOTFOUND" + case 105: + return "INVALIDMODEL" + case 106: + return "INVALIDOBJECT" + case 107: + return "INVALIDMESHOBJECT" + case 108: + return "INVALIDCOMPONENTSOBJECT" + case 109: + return "INVALIDCOMPONENT" + case 110: + return "INVALIDBUILDITEM" + case 111: + return "INVALIDBASEMATERIALGROUP" + case 112: + return "INVALIDSLICESTACKRESOURCE" + case 113: + return "INVALIDTEXTURERESOURCE" + case 114: + return "INVALIDCOLORGROUP" + case 115: + return "INVALIDTEXTURE2DGROUP" + case 116: + return "INVALIDCOMPOSITEMATERIALS" + case 117: + return "INVALIDMULTIPROPERTYGROUP" + case 120: + return "INVALIDRESOURCEINDEX" + case 121: + return "ATTACHMENTNOTFOUND" + case 130: + return "FORBIDDENCYCLICREFERENCE" + case 131: + return "INVALIDATTACHMENTSTREAM" + case 132: + return "INVALIDPROPERTYCOUNT" + case 140: + return "UNKOWNPROGRESSIDENTIFIER" + case 141: + return "ELEMENTCOUNTEXCEEDSLIMIT" + case 2000: + return "BEAMLATTICE_INVALID_OBJECTTYPE" + case 3000: + return "INVALIDKEYSTORE" + case 3001: + return "INVALIDKEYSTORECONSUMER" + case 3002: + return "KEYSTORECONSUMERNOTFOUND" + case 3003: + return "KEYSTORERESOURCEDATANOTFOUND" + case 3004: + return "SECURECONTEXTNOTREGISTERED" default: - return "unknown"; + return "unknown" } } - func (implementation *Lib3MFImplementation) GetWrapperHandle(handle Lib3MFHandle) (Lib3MFImplementationHandle, error) { implementation_handle, ok := handle.(Lib3MFImplementationHandle) if ok { handle_implementation := implementation_handle.GetWrapper() - if (handle_implementation == implementation) { + if handle_implementation == implementation { return implementation_handle, nil } return nil, errors.New("Invalid Implementation for DLL handle.") @@ -591,1873 +629,1885 @@ func (implementation *Lib3MFImplementation) GetWrapperHandle(handle Lib3MFHandle } func (implementation *Lib3MFImplementation) Initialize(DLLFileName string) error { - implementation.Initialized = false; - implementation.DLLHandle = 0; + implementation.Initialized = false + implementation.DLLHandle = 0 - dllHandle, err := syscall.LoadLibrary(DLLFileName); - if (err != nil) { - return err; + dllHandle, err := syscall.LoadLibrary(DLLFileName) + if err != nil { + return err } implementation.Lib3MF_writer_writetofile, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_writetofile") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_writetofile: " + err.Error()) } - + implementation.Lib3MF_writer_getstreamsize, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_getstreamsize") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_getstreamsize: " + err.Error()) } - + implementation.Lib3MF_writer_writetobuffer, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_writetobuffer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_writetobuffer: " + err.Error()) } - + implementation.Lib3MF_writer_writetocallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_writetocallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_writetocallback: " + err.Error()) } - + implementation.Lib3MF_writer_setprogresscallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_setprogresscallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_setprogresscallback: " + err.Error()) } - + implementation.Lib3MF_writer_getdecimalprecision, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_getdecimalprecision") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_getdecimalprecision: " + err.Error()) } - + implementation.Lib3MF_writer_setdecimalprecision, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_setdecimalprecision") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_setdecimalprecision: " + err.Error()) } - + implementation.Lib3MF_writer_setstrictmodeactive, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_setstrictmodeactive") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_setstrictmodeactive: " + err.Error()) } - + implementation.Lib3MF_writer_getstrictmodeactive, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_getstrictmodeactive") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_getstrictmodeactive: " + err.Error()) } - + implementation.Lib3MF_writer_getwarning, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_getwarning") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_getwarning: " + err.Error()) } - + implementation.Lib3MF_writer_getwarningcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_getwarningcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_getwarningcount: " + err.Error()) } - + implementation.Lib3MF_writer_addkeywrappingcallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_addkeywrappingcallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_addkeywrappingcallback: " + err.Error()) } - + implementation.Lib3MF_writer_setcontentencryptioncallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_writer_setcontentencryptioncallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_writer_setcontentencryptioncallback: " + err.Error()) } - + implementation.Lib3MF_reader_readfromfile, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_readfromfile") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_readfromfile: " + err.Error()) } - + implementation.Lib3MF_reader_readfrombuffer, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_readfrombuffer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_readfrombuffer: " + err.Error()) } - + implementation.Lib3MF_reader_readfromcallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_readfromcallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_readfromcallback: " + err.Error()) } - + implementation.Lib3MF_reader_setprogresscallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_setprogresscallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_setprogresscallback: " + err.Error()) } - + implementation.Lib3MF_reader_addrelationtoread, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_addrelationtoread") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_addrelationtoread: " + err.Error()) } - + implementation.Lib3MF_reader_removerelationtoread, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_removerelationtoread") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_removerelationtoread: " + err.Error()) } - + implementation.Lib3MF_reader_setstrictmodeactive, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_setstrictmodeactive") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_setstrictmodeactive: " + err.Error()) } - + implementation.Lib3MF_reader_getstrictmodeactive, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_getstrictmodeactive") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_getstrictmodeactive: " + err.Error()) } - + implementation.Lib3MF_reader_getwarning, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_getwarning") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_getwarning: " + err.Error()) } - + implementation.Lib3MF_reader_getwarningcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_getwarningcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_getwarningcount: " + err.Error()) } - + implementation.Lib3MF_reader_addkeywrappingcallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_addkeywrappingcallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_addkeywrappingcallback: " + err.Error()) } - + implementation.Lib3MF_reader_setcontentencryptioncallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_reader_setcontentencryptioncallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_reader_setcontentencryptioncallback: " + err.Error()) } - + implementation.Lib3MF_packagepart_getpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_packagepart_getpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_packagepart_getpath: " + err.Error()) } - + implementation.Lib3MF_packagepart_setpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_packagepart_setpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_packagepart_setpath: " + err.Error()) } - + implementation.Lib3MF_resource_getresourceid, err = syscall.GetProcAddress(dllHandle, "lib3mf_resource_getresourceid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resource_getresourceid: " + err.Error()) } - + implementation.Lib3MF_resource_getuniqueresourceid, err = syscall.GetProcAddress(dllHandle, "lib3mf_resource_getuniqueresourceid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resource_getuniqueresourceid: " + err.Error()) } - + implementation.Lib3MF_resource_packagepart, err = syscall.GetProcAddress(dllHandle, "lib3mf_resource_packagepart") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resource_packagepart: " + err.Error()) } - + implementation.Lib3MF_resource_setpackagepart, err = syscall.GetProcAddress(dllHandle, "lib3mf_resource_setpackagepart") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resource_setpackagepart: " + err.Error()) } - + implementation.Lib3MF_resource_getmodelresourceid, err = syscall.GetProcAddress(dllHandle, "lib3mf_resource_getmodelresourceid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resource_getmodelresourceid: " + err.Error()) } - + implementation.Lib3MF_resourceiterator_movenext, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourceiterator_movenext") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourceiterator_movenext: " + err.Error()) } - + implementation.Lib3MF_resourceiterator_moveprevious, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourceiterator_moveprevious") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourceiterator_moveprevious: " + err.Error()) } - + implementation.Lib3MF_resourceiterator_getcurrent, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourceiterator_getcurrent") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourceiterator_getcurrent: " + err.Error()) } - + implementation.Lib3MF_resourceiterator_clone, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourceiterator_clone") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourceiterator_clone: " + err.Error()) } - + implementation.Lib3MF_resourceiterator_count, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourceiterator_count") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourceiterator_count: " + err.Error()) } - + implementation.Lib3MF_slicestackiterator_getcurrentslicestack, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestackiterator_getcurrentslicestack") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestackiterator_getcurrentslicestack: " + err.Error()) } - + implementation.Lib3MF_objectiterator_getcurrentobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_objectiterator_getcurrentobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_objectiterator_getcurrentobject: " + err.Error()) } - + implementation.Lib3MF_meshobjectiterator_getcurrentmeshobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobjectiterator_getcurrentmeshobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobjectiterator_getcurrentmeshobject: " + err.Error()) } - + implementation.Lib3MF_componentsobjectiterator_getcurrentcomponentsobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_componentsobjectiterator_getcurrentcomponentsobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_componentsobjectiterator_getcurrentcomponentsobject: " + err.Error()) } - + implementation.Lib3MF_texture2diterator_getcurrenttexture2d, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2diterator_getcurrenttexture2d") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2diterator_getcurrenttexture2d: " + err.Error()) } - + implementation.Lib3MF_basematerialgroupiterator_getcurrentbasematerialgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroupiterator_getcurrentbasematerialgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroupiterator_getcurrentbasematerialgroup: " + err.Error()) } - + implementation.Lib3MF_colorgroupiterator_getcurrentcolorgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroupiterator_getcurrentcolorgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroupiterator_getcurrentcolorgroup: " + err.Error()) } - + implementation.Lib3MF_texture2dgroupiterator_getcurrenttexture2dgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroupiterator_getcurrenttexture2dgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroupiterator_getcurrenttexture2dgroup: " + err.Error()) } - + implementation.Lib3MF_compositematerialsiterator_getcurrentcompositematerials, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerialsiterator_getcurrentcompositematerials") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerialsiterator_getcurrentcompositematerials: " + err.Error()) } - + implementation.Lib3MF_multipropertygroupiterator_getcurrentmultipropertygroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroupiterator_getcurrentmultipropertygroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroupiterator_getcurrentmultipropertygroup: " + err.Error()) } - + implementation.Lib3MF_metadata_getnamespace, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_getnamespace") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_getnamespace: " + err.Error()) } - + implementation.Lib3MF_metadata_setnamespace, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_setnamespace") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_setnamespace: " + err.Error()) } - + implementation.Lib3MF_metadata_getname, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_getname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_getname: " + err.Error()) } - + implementation.Lib3MF_metadata_setname, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_setname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_setname: " + err.Error()) } - + implementation.Lib3MF_metadata_getkey, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_getkey") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_getkey: " + err.Error()) } - + implementation.Lib3MF_metadata_getmustpreserve, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_getmustpreserve") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_getmustpreserve: " + err.Error()) } - + implementation.Lib3MF_metadata_setmustpreserve, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_setmustpreserve") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_setmustpreserve: " + err.Error()) } - + implementation.Lib3MF_metadata_gettype, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_gettype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_gettype: " + err.Error()) } - + implementation.Lib3MF_metadata_settype, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_settype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_settype: " + err.Error()) } - + implementation.Lib3MF_metadata_getvalue, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_getvalue") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_getvalue: " + err.Error()) } - + implementation.Lib3MF_metadata_setvalue, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadata_setvalue") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadata_setvalue: " + err.Error()) } - + implementation.Lib3MF_metadatagroup_getmetadatacount, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadatagroup_getmetadatacount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadatagroup_getmetadatacount: " + err.Error()) } - + implementation.Lib3MF_metadatagroup_getmetadata, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadatagroup_getmetadata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadatagroup_getmetadata: " + err.Error()) } - + implementation.Lib3MF_metadatagroup_getmetadatabykey, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadatagroup_getmetadatabykey") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadatagroup_getmetadatabykey: " + err.Error()) } - + implementation.Lib3MF_metadatagroup_removemetadatabyindex, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadatagroup_removemetadatabyindex") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadatagroup_removemetadatabyindex: " + err.Error()) } - + implementation.Lib3MF_metadatagroup_removemetadata, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadatagroup_removemetadata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadatagroup_removemetadata: " + err.Error()) } - + implementation.Lib3MF_metadatagroup_addmetadata, err = syscall.GetProcAddress(dllHandle, "lib3mf_metadatagroup_addmetadata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_metadatagroup_addmetadata: " + err.Error()) } - + implementation.Lib3MF_object_gettype, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_gettype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_gettype: " + err.Error()) } - + implementation.Lib3MF_object_settype, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_settype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_settype: " + err.Error()) } - + implementation.Lib3MF_object_getname, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getname: " + err.Error()) } - + implementation.Lib3MF_object_setname, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_setname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_setname: " + err.Error()) } - + implementation.Lib3MF_object_getpartnumber, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getpartnumber") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getpartnumber: " + err.Error()) } - + implementation.Lib3MF_object_setpartnumber, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_setpartnumber") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_setpartnumber: " + err.Error()) } - + implementation.Lib3MF_object_ismeshobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_ismeshobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_ismeshobject: " + err.Error()) } - + implementation.Lib3MF_object_iscomponentsobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_iscomponentsobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_iscomponentsobject: " + err.Error()) } - + implementation.Lib3MF_object_isvalid, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_isvalid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_isvalid: " + err.Error()) } - + implementation.Lib3MF_object_setattachmentasthumbnail, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_setattachmentasthumbnail") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_setattachmentasthumbnail: " + err.Error()) } - + implementation.Lib3MF_object_getthumbnailattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getthumbnailattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getthumbnailattachment: " + err.Error()) } - + implementation.Lib3MF_object_clearthumbnailattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_clearthumbnailattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_clearthumbnailattachment: " + err.Error()) } - + implementation.Lib3MF_object_getoutbox, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getoutbox") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getoutbox: " + err.Error()) } - + implementation.Lib3MF_object_getuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getuuid: " + err.Error()) } - + implementation.Lib3MF_object_setuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_setuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_setuuid: " + err.Error()) } - + implementation.Lib3MF_object_getmetadatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getmetadatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getmetadatagroup: " + err.Error()) } - + implementation.Lib3MF_object_setslicesmeshresolution, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_setslicesmeshresolution") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_setslicesmeshresolution: " + err.Error()) } - + implementation.Lib3MF_object_getslicesmeshresolution, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getslicesmeshresolution") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getslicesmeshresolution: " + err.Error()) } - + implementation.Lib3MF_object_hasslices, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_hasslices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_hasslices: " + err.Error()) } - + implementation.Lib3MF_object_clearslicestack, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_clearslicestack") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_clearslicestack: " + err.Error()) } - + implementation.Lib3MF_object_getslicestack, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_getslicestack") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_getslicestack: " + err.Error()) } - + implementation.Lib3MF_object_assignslicestack, err = syscall.GetProcAddress(dllHandle, "lib3mf_object_assignslicestack") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_object_assignslicestack: " + err.Error()) } - + implementation.Lib3MF_meshobject_getvertexcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_getvertexcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_getvertexcount: " + err.Error()) } - + implementation.Lib3MF_meshobject_gettrianglecount, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_gettrianglecount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_gettrianglecount: " + err.Error()) } - + implementation.Lib3MF_meshobject_getvertex, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_getvertex") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_getvertex: " + err.Error()) } - + implementation.Lib3MF_meshobject_setvertex, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_setvertex") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_setvertex: " + err.Error()) } - + implementation.Lib3MF_meshobject_addvertex, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_addvertex") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_addvertex: " + err.Error()) } - + implementation.Lib3MF_meshobject_getvertices, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_getvertices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_getvertices: " + err.Error()) } - + implementation.Lib3MF_meshobject_gettriangle, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_gettriangle") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_gettriangle: " + err.Error()) } - + implementation.Lib3MF_meshobject_settriangle, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_settriangle") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_settriangle: " + err.Error()) } - + implementation.Lib3MF_meshobject_addtriangle, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_addtriangle") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_addtriangle: " + err.Error()) } - + implementation.Lib3MF_meshobject_gettriangleindices, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_gettriangleindices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_gettriangleindices: " + err.Error()) } - + implementation.Lib3MF_meshobject_setobjectlevelproperty, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_setobjectlevelproperty") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_setobjectlevelproperty: " + err.Error()) } - + implementation.Lib3MF_meshobject_getobjectlevelproperty, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_getobjectlevelproperty") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_getobjectlevelproperty: " + err.Error()) } - + implementation.Lib3MF_meshobject_settriangleproperties, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_settriangleproperties") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_settriangleproperties: " + err.Error()) } - + implementation.Lib3MF_meshobject_gettriangleproperties, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_gettriangleproperties") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_gettriangleproperties: " + err.Error()) } - + implementation.Lib3MF_meshobject_setalltriangleproperties, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_setalltriangleproperties") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_setalltriangleproperties: " + err.Error()) } - + implementation.Lib3MF_meshobject_getalltriangleproperties, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_getalltriangleproperties") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_getalltriangleproperties: " + err.Error()) } - + implementation.Lib3MF_meshobject_clearallproperties, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_clearallproperties") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_clearallproperties: " + err.Error()) } - + implementation.Lib3MF_meshobject_setgeometry, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_setgeometry") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_setgeometry: " + err.Error()) } - + implementation.Lib3MF_meshobject_ismanifoldandoriented, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_ismanifoldandoriented") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_ismanifoldandoriented: " + err.Error()) } - + implementation.Lib3MF_meshobject_beamlattice, err = syscall.GetProcAddress(dllHandle, "lib3mf_meshobject_beamlattice") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_meshobject_beamlattice: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getminlength, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getminlength") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getminlength: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setminlength, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setminlength") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setminlength: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getclipping, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getclipping") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getclipping: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setclipping, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setclipping") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setclipping: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getrepresentation, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getrepresentation") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getrepresentation: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setrepresentation, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setrepresentation") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setrepresentation: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getballoptions, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getballoptions") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getballoptions: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setballoptions, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setballoptions") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setballoptions: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getbeamcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getbeamcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getbeamcount: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getbeam, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getbeam") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getbeam: " + err.Error()) } - + implementation.Lib3MF_beamlattice_addbeam, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_addbeam") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_addbeam: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setbeam, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setbeam") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setbeam: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setbeams, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setbeams") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setbeams: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getbeams, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getbeams") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getbeams: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getballcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getballcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getballcount: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getball, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getball") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getball: " + err.Error()) } - + implementation.Lib3MF_beamlattice_addball, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_addball") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_addball: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setball, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setball") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setball: " + err.Error()) } - + implementation.Lib3MF_beamlattice_setballs, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_setballs") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_setballs: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getballs, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getballs") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getballs: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getbeamsetcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getbeamsetcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getbeamsetcount: " + err.Error()) } - + implementation.Lib3MF_beamlattice_addbeamset, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_addbeamset") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_addbeamset: " + err.Error()) } - + implementation.Lib3MF_beamlattice_getbeamset, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamlattice_getbeamset") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamlattice_getbeamset: " + err.Error()) } - + implementation.Lib3MF_component_getobjectresource, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_getobjectresource") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_getobjectresource: " + err.Error()) } - + implementation.Lib3MF_component_getobjectresourceid, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_getobjectresourceid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_getobjectresourceid: " + err.Error()) } - + implementation.Lib3MF_component_getuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_getuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_getuuid: " + err.Error()) } - + implementation.Lib3MF_component_setuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_setuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_setuuid: " + err.Error()) } - + implementation.Lib3MF_component_hastransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_hastransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_hastransform: " + err.Error()) } - + implementation.Lib3MF_component_gettransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_gettransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_gettransform: " + err.Error()) } - + implementation.Lib3MF_component_settransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_component_settransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_component_settransform: " + err.Error()) } - + implementation.Lib3MF_componentsobject_addcomponent, err = syscall.GetProcAddress(dllHandle, "lib3mf_componentsobject_addcomponent") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_componentsobject_addcomponent: " + err.Error()) } - + implementation.Lib3MF_componentsobject_getcomponent, err = syscall.GetProcAddress(dllHandle, "lib3mf_componentsobject_getcomponent") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_componentsobject_getcomponent: " + err.Error()) } - + implementation.Lib3MF_componentsobject_getcomponentcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_componentsobject_getcomponentcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_componentsobject_getcomponentcount: " + err.Error()) } - + implementation.Lib3MF_beamset_setname, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_setname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_setname: " + err.Error()) } - + implementation.Lib3MF_beamset_getname, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_getname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_getname: " + err.Error()) } - + implementation.Lib3MF_beamset_setidentifier, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_setidentifier") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_setidentifier: " + err.Error()) } - + implementation.Lib3MF_beamset_getidentifier, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_getidentifier") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_getidentifier: " + err.Error()) } - + implementation.Lib3MF_beamset_getreferencecount, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_getreferencecount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_getreferencecount: " + err.Error()) } - + implementation.Lib3MF_beamset_setreferences, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_setreferences") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_setreferences: " + err.Error()) } - + implementation.Lib3MF_beamset_getreferences, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_getreferences") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_getreferences: " + err.Error()) } - + implementation.Lib3MF_beamset_getballreferencecount, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_getballreferencecount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_getballreferencecount: " + err.Error()) } - + implementation.Lib3MF_beamset_setballreferences, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_setballreferences") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_setballreferences: " + err.Error()) } - + implementation.Lib3MF_beamset_getballreferences, err = syscall.GetProcAddress(dllHandle, "lib3mf_beamset_getballreferences") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_beamset_getballreferences: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_getcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_getcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_getcount: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_getallpropertyids, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_getallpropertyids") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_getallpropertyids: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_addmaterial, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_addmaterial") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_addmaterial: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_removematerial, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_removematerial") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_removematerial: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_getname, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_getname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_getname: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_setname, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_setname") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_setname: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_setdisplaycolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_setdisplaycolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_setdisplaycolor: " + err.Error()) } - + implementation.Lib3MF_basematerialgroup_getdisplaycolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_basematerialgroup_getdisplaycolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_basematerialgroup_getdisplaycolor: " + err.Error()) } - + implementation.Lib3MF_colorgroup_getcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroup_getcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroup_getcount: " + err.Error()) } - + implementation.Lib3MF_colorgroup_getallpropertyids, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroup_getallpropertyids") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroup_getallpropertyids: " + err.Error()) } - + implementation.Lib3MF_colorgroup_addcolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroup_addcolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroup_addcolor: " + err.Error()) } - + implementation.Lib3MF_colorgroup_removecolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroup_removecolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroup_removecolor: " + err.Error()) } - + implementation.Lib3MF_colorgroup_setcolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroup_setcolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroup_setcolor: " + err.Error()) } - + implementation.Lib3MF_colorgroup_getcolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_colorgroup_getcolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colorgroup_getcolor: " + err.Error()) } - + implementation.Lib3MF_texture2dgroup_getcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroup_getcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroup_getcount: " + err.Error()) } - + implementation.Lib3MF_texture2dgroup_getallpropertyids, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroup_getallpropertyids") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroup_getallpropertyids: " + err.Error()) } - + implementation.Lib3MF_texture2dgroup_addtex2coord, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroup_addtex2coord") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroup_addtex2coord: " + err.Error()) } - + implementation.Lib3MF_texture2dgroup_gettex2coord, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroup_gettex2coord") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroup_gettex2coord: " + err.Error()) } - + implementation.Lib3MF_texture2dgroup_removetex2coord, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroup_removetex2coord") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroup_removetex2coord: " + err.Error()) } - + implementation.Lib3MF_texture2dgroup_gettexture2d, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2dgroup_gettexture2d") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2dgroup_gettexture2d: " + err.Error()) } - + implementation.Lib3MF_compositematerials_getcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerials_getcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerials_getcount: " + err.Error()) } - + implementation.Lib3MF_compositematerials_getallpropertyids, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerials_getallpropertyids") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerials_getallpropertyids: " + err.Error()) } - + implementation.Lib3MF_compositematerials_getbasematerialgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerials_getbasematerialgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerials_getbasematerialgroup: " + err.Error()) } - + implementation.Lib3MF_compositematerials_addcomposite, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerials_addcomposite") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerials_addcomposite: " + err.Error()) } - + implementation.Lib3MF_compositematerials_removecomposite, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerials_removecomposite") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerials_removecomposite: " + err.Error()) } - + implementation.Lib3MF_compositematerials_getcomposite, err = syscall.GetProcAddress(dllHandle, "lib3mf_compositematerials_getcomposite") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_compositematerials_getcomposite: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_getcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_getcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_getcount: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_getallpropertyids, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_getallpropertyids") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_getallpropertyids: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_addmultiproperty, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_addmultiproperty") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_addmultiproperty: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_setmultiproperty, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_setmultiproperty") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_setmultiproperty: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_getmultiproperty, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_getmultiproperty") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_getmultiproperty: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_removemultiproperty, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_removemultiproperty") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_removemultiproperty: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_getlayercount, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_getlayercount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_getlayercount: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_addlayer, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_addlayer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_addlayer: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_getlayer, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_getlayer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_getlayer: " + err.Error()) } - + implementation.Lib3MF_multipropertygroup_removelayer, err = syscall.GetProcAddress(dllHandle, "lib3mf_multipropertygroup_removelayer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_multipropertygroup_removelayer: " + err.Error()) } - + implementation.Lib3MF_attachment_getpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_getpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_getpath: " + err.Error()) } - + implementation.Lib3MF_attachment_setpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_setpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_setpath: " + err.Error()) } - + implementation.Lib3MF_attachment_packagepart, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_packagepart") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_packagepart: " + err.Error()) } - + implementation.Lib3MF_attachment_getrelationshiptype, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_getrelationshiptype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_getrelationshiptype: " + err.Error()) } - + implementation.Lib3MF_attachment_setrelationshiptype, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_setrelationshiptype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_setrelationshiptype: " + err.Error()) } - + implementation.Lib3MF_attachment_writetofile, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_writetofile") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_writetofile: " + err.Error()) } - + implementation.Lib3MF_attachment_readfromfile, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_readfromfile") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_readfromfile: " + err.Error()) } - + implementation.Lib3MF_attachment_readfromcallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_readfromcallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_readfromcallback: " + err.Error()) } - + implementation.Lib3MF_attachment_getstreamsize, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_getstreamsize") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_getstreamsize: " + err.Error()) } - + implementation.Lib3MF_attachment_writetobuffer, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_writetobuffer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_writetobuffer: " + err.Error()) } - + implementation.Lib3MF_attachment_readfrombuffer, err = syscall.GetProcAddress(dllHandle, "lib3mf_attachment_readfrombuffer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_attachment_readfrombuffer: " + err.Error()) } - + implementation.Lib3MF_texture2d_getattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_getattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_getattachment: " + err.Error()) } - + implementation.Lib3MF_texture2d_setattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_setattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_setattachment: " + err.Error()) } - + implementation.Lib3MF_texture2d_getcontenttype, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_getcontenttype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_getcontenttype: " + err.Error()) } - + implementation.Lib3MF_texture2d_setcontenttype, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_setcontenttype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_setcontenttype: " + err.Error()) } - + implementation.Lib3MF_texture2d_gettilestyleuv, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_gettilestyleuv") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_gettilestyleuv: " + err.Error()) } - + implementation.Lib3MF_texture2d_settilestyleuv, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_settilestyleuv") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_settilestyleuv: " + err.Error()) } - + implementation.Lib3MF_texture2d_getfilter, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_getfilter") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_getfilter: " + err.Error()) } - + implementation.Lib3MF_texture2d_setfilter, err = syscall.GetProcAddress(dllHandle, "lib3mf_texture2d_setfilter") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_texture2d_setfilter: " + err.Error()) } - + implementation.Lib3MF_builditem_getobjectresource, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getobjectresource") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getobjectresource: " + err.Error()) } - + implementation.Lib3MF_builditem_getuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getuuid: " + err.Error()) } - + implementation.Lib3MF_builditem_setuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_setuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_setuuid: " + err.Error()) } - + implementation.Lib3MF_builditem_getobjectresourceid, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getobjectresourceid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getobjectresourceid: " + err.Error()) } - + implementation.Lib3MF_builditem_hasobjecttransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_hasobjecttransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_hasobjecttransform: " + err.Error()) } - + implementation.Lib3MF_builditem_getobjecttransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getobjecttransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getobjecttransform: " + err.Error()) } - + implementation.Lib3MF_builditem_setobjecttransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_setobjecttransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_setobjecttransform: " + err.Error()) } - + implementation.Lib3MF_builditem_getpartnumber, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getpartnumber") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getpartnumber: " + err.Error()) } - + implementation.Lib3MF_builditem_setpartnumber, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_setpartnumber") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_setpartnumber: " + err.Error()) } - + implementation.Lib3MF_builditem_getmetadatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getmetadatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getmetadatagroup: " + err.Error()) } - + implementation.Lib3MF_builditem_getoutbox, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditem_getoutbox") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditem_getoutbox: " + err.Error()) } - + implementation.Lib3MF_builditemiterator_movenext, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditemiterator_movenext") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditemiterator_movenext: " + err.Error()) } - + implementation.Lib3MF_builditemiterator_moveprevious, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditemiterator_moveprevious") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditemiterator_moveprevious: " + err.Error()) } - + implementation.Lib3MF_builditemiterator_getcurrent, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditemiterator_getcurrent") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditemiterator_getcurrent: " + err.Error()) } - + implementation.Lib3MF_builditemiterator_clone, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditemiterator_clone") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditemiterator_clone: " + err.Error()) } - + implementation.Lib3MF_builditemiterator_count, err = syscall.GetProcAddress(dllHandle, "lib3mf_builditemiterator_count") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_builditemiterator_count: " + err.Error()) } - + implementation.Lib3MF_slice_setvertices, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_setvertices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_setvertices: " + err.Error()) } - + implementation.Lib3MF_slice_getvertices, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_getvertices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_getvertices: " + err.Error()) } - + implementation.Lib3MF_slice_getvertexcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_getvertexcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_getvertexcount: " + err.Error()) } - + implementation.Lib3MF_slice_addpolygon, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_addpolygon") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_addpolygon: " + err.Error()) } - + implementation.Lib3MF_slice_getpolygoncount, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_getpolygoncount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_getpolygoncount: " + err.Error()) } - + implementation.Lib3MF_slice_setpolygonindices, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_setpolygonindices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_setpolygonindices: " + err.Error()) } - + implementation.Lib3MF_slice_getpolygonindices, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_getpolygonindices") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_getpolygonindices: " + err.Error()) } - + implementation.Lib3MF_slice_getpolygonindexcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_getpolygonindexcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_getpolygonindexcount: " + err.Error()) } - + implementation.Lib3MF_slice_getztop, err = syscall.GetProcAddress(dllHandle, "lib3mf_slice_getztop") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slice_getztop: " + err.Error()) } - + implementation.Lib3MF_slicestack_getbottomz, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_getbottomz") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_getbottomz: " + err.Error()) } - + implementation.Lib3MF_slicestack_getslicecount, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_getslicecount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_getslicecount: " + err.Error()) } - + implementation.Lib3MF_slicestack_getslice, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_getslice") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_getslice: " + err.Error()) } - + implementation.Lib3MF_slicestack_addslice, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_addslice") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_addslice: " + err.Error()) } - + implementation.Lib3MF_slicestack_getslicerefcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_getslicerefcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_getslicerefcount: " + err.Error()) } - + implementation.Lib3MF_slicestack_addslicestackreference, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_addslicestackreference") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_addslicestackreference: " + err.Error()) } - + implementation.Lib3MF_slicestack_getslicestackreference, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_getslicestackreference") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_getslicestackreference: " + err.Error()) } - + implementation.Lib3MF_slicestack_collapseslicereferences, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_collapseslicereferences") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_collapseslicereferences: " + err.Error()) } - + implementation.Lib3MF_slicestack_setownpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_setownpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_setownpath: " + err.Error()) } - + implementation.Lib3MF_slicestack_getownpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_slicestack_getownpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_slicestack_getownpath: " + err.Error()) } - + implementation.Lib3MF_consumer_getconsumerid, err = syscall.GetProcAddress(dllHandle, "lib3mf_consumer_getconsumerid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_consumer_getconsumerid: " + err.Error()) } - + implementation.Lib3MF_consumer_getkeyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_consumer_getkeyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_consumer_getkeyid: " + err.Error()) } - + implementation.Lib3MF_consumer_getkeyvalue, err = syscall.GetProcAddress(dllHandle, "lib3mf_consumer_getkeyvalue") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_consumer_getkeyvalue: " + err.Error()) } - + implementation.Lib3MF_accessright_getconsumer, err = syscall.GetProcAddress(dllHandle, "lib3mf_accessright_getconsumer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_accessright_getconsumer: " + err.Error()) } - + implementation.Lib3MF_accessright_getwrappingalgorithm, err = syscall.GetProcAddress(dllHandle, "lib3mf_accessright_getwrappingalgorithm") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_accessright_getwrappingalgorithm: " + err.Error()) } - + implementation.Lib3MF_accessright_getmgfalgorithm, err = syscall.GetProcAddress(dllHandle, "lib3mf_accessright_getmgfalgorithm") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_accessright_getmgfalgorithm: " + err.Error()) } - + implementation.Lib3MF_accessright_getdigestmethod, err = syscall.GetProcAddress(dllHandle, "lib3mf_accessright_getdigestmethod") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_accessright_getdigestmethod: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getencryptionalgorithm, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getencryptionalgorithm") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getencryptionalgorithm: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getkey, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getkey") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getkey: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getinitializationvector, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getinitializationvector") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getinitializationvector: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getauthenticationtag, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getauthenticationtag") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getauthenticationtag: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_setauthenticationtag, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_setauthenticationtag") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_setauthenticationtag: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getadditionalauthenticationdata, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getadditionalauthenticationdata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getadditionalauthenticationdata: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getdescriptor, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getdescriptor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getdescriptor: " + err.Error()) } - + implementation.Lib3MF_contentencryptionparams_getkeyuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_contentencryptionparams_getkeyuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_contentencryptionparams_getkeyuuid: " + err.Error()) } - + implementation.Lib3MF_resourcedata_getpath, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedata_getpath") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedata_getpath: " + err.Error()) } - + implementation.Lib3MF_resourcedata_getencryptionalgorithm, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedata_getencryptionalgorithm") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedata_getencryptionalgorithm: " + err.Error()) } - + implementation.Lib3MF_resourcedata_getcompression, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedata_getcompression") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedata_getcompression: " + err.Error()) } - + implementation.Lib3MF_resourcedata_getadditionalauthenticationdata, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedata_getadditionalauthenticationdata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedata_getadditionalauthenticationdata: " + err.Error()) } - + implementation.Lib3MF_resourcedatagroup_getkeyuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedatagroup_getkeyuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedatagroup_getkeyuuid: " + err.Error()) } - + implementation.Lib3MF_resourcedatagroup_addaccessright, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedatagroup_addaccessright") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedatagroup_addaccessright: " + err.Error()) } - + implementation.Lib3MF_resourcedatagroup_findaccessrightbyconsumer, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedatagroup_findaccessrightbyconsumer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedatagroup_findaccessrightbyconsumer: " + err.Error()) } - + implementation.Lib3MF_resourcedatagroup_removeaccessright, err = syscall.GetProcAddress(dllHandle, "lib3mf_resourcedatagroup_removeaccessright") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_resourcedatagroup_removeaccessright: " + err.Error()) } - + implementation.Lib3MF_keystore_addconsumer, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_addconsumer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_addconsumer: " + err.Error()) } - + implementation.Lib3MF_keystore_getconsumercount, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getconsumercount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getconsumercount: " + err.Error()) } - + implementation.Lib3MF_keystore_getconsumer, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getconsumer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getconsumer: " + err.Error()) } - + implementation.Lib3MF_keystore_removeconsumer, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_removeconsumer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_removeconsumer: " + err.Error()) } - + implementation.Lib3MF_keystore_findconsumer, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_findconsumer") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_findconsumer: " + err.Error()) } - + implementation.Lib3MF_keystore_getresourcedatagroupcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getresourcedatagroupcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getresourcedatagroupcount: " + err.Error()) } - + implementation.Lib3MF_keystore_addresourcedatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_addresourcedatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_addresourcedatagroup: " + err.Error()) } - + implementation.Lib3MF_keystore_getresourcedatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getresourcedatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getresourcedatagroup: " + err.Error()) } - + implementation.Lib3MF_keystore_removeresourcedatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_removeresourcedatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_removeresourcedatagroup: " + err.Error()) } - + implementation.Lib3MF_keystore_findresourcedatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_findresourcedatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_findresourcedatagroup: " + err.Error()) } - + implementation.Lib3MF_keystore_addresourcedata, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_addresourcedata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_addresourcedata: " + err.Error()) } - + implementation.Lib3MF_keystore_removeresourcedata, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_removeresourcedata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_removeresourcedata: " + err.Error()) } - + implementation.Lib3MF_keystore_findresourcedata, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_findresourcedata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_findresourcedata: " + err.Error()) } - + implementation.Lib3MF_keystore_getresourcedatacount, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getresourcedatacount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getresourcedatacount: " + err.Error()) } - + implementation.Lib3MF_keystore_getresourcedata, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getresourcedata") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getresourcedata: " + err.Error()) } - + implementation.Lib3MF_keystore_getuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_getuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_getuuid: " + err.Error()) } - + implementation.Lib3MF_keystore_setuuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_keystore_setuuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_keystore_setuuid: " + err.Error()) } - + implementation.Lib3MF_model_rootmodelpart, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_rootmodelpart") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_rootmodelpart: " + err.Error()) } - + implementation.Lib3MF_model_findorcreatepackagepart, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_findorcreatepackagepart") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_findorcreatepackagepart: " + err.Error()) } - + implementation.Lib3MF_model_setunit, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_setunit") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_setunit: " + err.Error()) } - + implementation.Lib3MF_model_getunit, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getunit") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getunit: " + err.Error()) } - + implementation.Lib3MF_model_getlanguage, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getlanguage") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getlanguage: " + err.Error()) } - + implementation.Lib3MF_model_setlanguage, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_setlanguage") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_setlanguage: " + err.Error()) } - + implementation.Lib3MF_model_querywriter, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_querywriter") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_querywriter: " + err.Error()) } - + implementation.Lib3MF_model_queryreader, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_queryreader") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_queryreader: " + err.Error()) } - + implementation.Lib3MF_model_gettexture2dbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_gettexture2dbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_gettexture2dbyid: " + err.Error()) } - + implementation.Lib3MF_model_getpropertytypebyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getpropertytypebyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getpropertytypebyid: " + err.Error()) } - + implementation.Lib3MF_model_getbasematerialgroupbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getbasematerialgroupbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getbasematerialgroupbyid: " + err.Error()) } - + implementation.Lib3MF_model_gettexture2dgroupbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_gettexture2dgroupbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_gettexture2dgroupbyid: " + err.Error()) } - + implementation.Lib3MF_model_getcompositematerialsbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getcompositematerialsbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getcompositematerialsbyid: " + err.Error()) } - + implementation.Lib3MF_model_getmultipropertygroupbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getmultipropertygroupbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getmultipropertygroupbyid: " + err.Error()) } - + implementation.Lib3MF_model_getmeshobjectbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getmeshobjectbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getmeshobjectbyid: " + err.Error()) } - + implementation.Lib3MF_model_getcomponentsobjectbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getcomponentsobjectbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getcomponentsobjectbyid: " + err.Error()) } - + implementation.Lib3MF_model_getcolorgroupbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getcolorgroupbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getcolorgroupbyid: " + err.Error()) } - + implementation.Lib3MF_model_getslicestackbyid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getslicestackbyid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getslicestackbyid: " + err.Error()) } - + implementation.Lib3MF_model_getbuilduuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getbuilduuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getbuilduuid: " + err.Error()) } - + implementation.Lib3MF_model_setbuilduuid, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_setbuilduuid") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_setbuilduuid: " + err.Error()) } - + implementation.Lib3MF_model_getbuilditems, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getbuilditems") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getbuilditems: " + err.Error()) } - + implementation.Lib3MF_model_getoutbox, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getoutbox") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getoutbox: " + err.Error()) } - + implementation.Lib3MF_model_getresources, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getresources") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getresources: " + err.Error()) } - + implementation.Lib3MF_model_getobjects, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getobjects") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getobjects: " + err.Error()) } - + implementation.Lib3MF_model_getmeshobjects, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getmeshobjects") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getmeshobjects: " + err.Error()) } - + implementation.Lib3MF_model_getcomponentsobjects, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getcomponentsobjects") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getcomponentsobjects: " + err.Error()) } - + implementation.Lib3MF_model_gettexture2ds, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_gettexture2ds") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_gettexture2ds: " + err.Error()) } - + implementation.Lib3MF_model_getbasematerialgroups, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getbasematerialgroups") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getbasematerialgroups: " + err.Error()) } - + implementation.Lib3MF_model_getcolorgroups, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getcolorgroups") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getcolorgroups: " + err.Error()) } - + implementation.Lib3MF_model_gettexture2dgroups, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_gettexture2dgroups") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_gettexture2dgroups: " + err.Error()) } - + implementation.Lib3MF_model_getcompositematerials, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getcompositematerials") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getcompositematerials: " + err.Error()) } - + implementation.Lib3MF_model_getmultipropertygroups, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getmultipropertygroups") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getmultipropertygroups: " + err.Error()) } - + implementation.Lib3MF_model_getslicestacks, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getslicestacks") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getslicestacks: " + err.Error()) } - + implementation.Lib3MF_model_mergetomodel, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_mergetomodel") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_mergetomodel: " + err.Error()) } - + implementation.Lib3MF_model_addmeshobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addmeshobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addmeshobject: " + err.Error()) } - + implementation.Lib3MF_model_addcomponentsobject, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addcomponentsobject") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addcomponentsobject: " + err.Error()) } - + implementation.Lib3MF_model_addslicestack, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addslicestack") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addslicestack: " + err.Error()) } - + implementation.Lib3MF_model_addtexture2dfromattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addtexture2dfromattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addtexture2dfromattachment: " + err.Error()) } - + implementation.Lib3MF_model_addbasematerialgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addbasematerialgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addbasematerialgroup: " + err.Error()) } - + implementation.Lib3MF_model_addcolorgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addcolorgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addcolorgroup: " + err.Error()) } - + implementation.Lib3MF_model_addtexture2dgroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addtexture2dgroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addtexture2dgroup: " + err.Error()) } - + implementation.Lib3MF_model_addcompositematerials, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addcompositematerials") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addcompositematerials: " + err.Error()) } - + implementation.Lib3MF_model_addmultipropertygroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addmultipropertygroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addmultipropertygroup: " + err.Error()) } - + implementation.Lib3MF_model_addbuilditem, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addbuilditem") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addbuilditem: " + err.Error()) } - + implementation.Lib3MF_model_removebuilditem, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_removebuilditem") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_removebuilditem: " + err.Error()) } - + implementation.Lib3MF_model_getmetadatagroup, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getmetadatagroup") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getmetadatagroup: " + err.Error()) } - + implementation.Lib3MF_model_addattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addattachment: " + err.Error()) } - + implementation.Lib3MF_model_removeattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_removeattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_removeattachment: " + err.Error()) } - + implementation.Lib3MF_model_getattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getattachment: " + err.Error()) } - + implementation.Lib3MF_model_findattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_findattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_findattachment: " + err.Error()) } - + implementation.Lib3MF_model_getattachmentcount, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getattachmentcount") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getattachmentcount: " + err.Error()) } - + implementation.Lib3MF_model_haspackagethumbnailattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_haspackagethumbnailattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_haspackagethumbnailattachment: " + err.Error()) } - + implementation.Lib3MF_model_createpackagethumbnailattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_createpackagethumbnailattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_createpackagethumbnailattachment: " + err.Error()) } - + implementation.Lib3MF_model_getpackagethumbnailattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getpackagethumbnailattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getpackagethumbnailattachment: " + err.Error()) } - + implementation.Lib3MF_model_removepackagethumbnailattachment, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_removepackagethumbnailattachment") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_removepackagethumbnailattachment: " + err.Error()) } - + implementation.Lib3MF_model_addcustomcontenttype, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_addcustomcontenttype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_addcustomcontenttype: " + err.Error()) } - + implementation.Lib3MF_model_removecustomcontenttype, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_removecustomcontenttype") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_removecustomcontenttype: " + err.Error()) } - + implementation.Lib3MF_model_setrandomnumbercallback, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_setrandomnumbercallback") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_setrandomnumbercallback: " + err.Error()) } - + implementation.Lib3MF_model_getkeystore, err = syscall.GetProcAddress(dllHandle, "lib3mf_model_getkeystore") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_model_getkeystore: " + err.Error()) } - + implementation.Lib3MF_getlibraryversion, err = syscall.GetProcAddress(dllHandle, "lib3mf_getlibraryversion") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getlibraryversion: " + err.Error()) } - + implementation.Lib3MF_getprereleaseinformation, err = syscall.GetProcAddress(dllHandle, "lib3mf_getprereleaseinformation") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getprereleaseinformation: " + err.Error()) } - + implementation.Lib3MF_getbuildinformation, err = syscall.GetProcAddress(dllHandle, "lib3mf_getbuildinformation") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getbuildinformation: " + err.Error()) } - + implementation.Lib3MF_getspecificationversion, err = syscall.GetProcAddress(dllHandle, "lib3mf_getspecificationversion") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getspecificationversion: " + err.Error()) } - + implementation.Lib3MF_createmodel, err = syscall.GetProcAddress(dllHandle, "lib3mf_createmodel") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_createmodel: " + err.Error()) } - + implementation.Lib3MF_release, err = syscall.GetProcAddress(dllHandle, "lib3mf_release") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_release: " + err.Error()) } - + implementation.Lib3MF_acquire, err = syscall.GetProcAddress(dllHandle, "lib3mf_acquire") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_acquire: " + err.Error()) } - + implementation.Lib3MF_setjournal, err = syscall.GetProcAddress(dllHandle, "lib3mf_setjournal") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_setjournal: " + err.Error()) } - + implementation.Lib3MF_getlasterror, err = syscall.GetProcAddress(dllHandle, "lib3mf_getlasterror") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getlasterror: " + err.Error()) } - + implementation.Lib3MF_getsymbollookupmethod, err = syscall.GetProcAddress(dllHandle, "lib3mf_getsymbollookupmethod") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getsymbollookupmethod: " + err.Error()) } - + implementation.Lib3MF_retrieveprogressmessage, err = syscall.GetProcAddress(dllHandle, "lib3mf_retrieveprogressmessage") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_retrieveprogressmessage: " + err.Error()) } - + implementation.Lib3MF_rgbatocolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_rgbatocolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_rgbatocolor: " + err.Error()) } - + implementation.Lib3MF_floatrgbatocolor, err = syscall.GetProcAddress(dllHandle, "lib3mf_floatrgbatocolor") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_floatrgbatocolor: " + err.Error()) } - + implementation.Lib3MF_colortorgba, err = syscall.GetProcAddress(dllHandle, "lib3mf_colortorgba") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colortorgba: " + err.Error()) } - + implementation.Lib3MF_colortofloatrgba, err = syscall.GetProcAddress(dllHandle, "lib3mf_colortofloatrgba") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_colortofloatrgba: " + err.Error()) } - + implementation.Lib3MF_getidentitytransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_getidentitytransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getidentitytransform: " + err.Error()) } - + implementation.Lib3MF_getuniformscaletransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_getuniformscaletransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getuniformscaletransform: " + err.Error()) } - + implementation.Lib3MF_getscaletransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_getscaletransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_getscaletransform: " + err.Error()) } - + implementation.Lib3MF_gettranslationtransform, err = syscall.GetProcAddress(dllHandle, "lib3mf_gettranslationtransform") - if (err != nil) { + if err != nil { return errors.New("Could not get function lib3mf_gettranslationtransform: " + err.Error()) } - - implementation.DLLHandle = dllHandle + + implementation.DLLHandle = dllHandle implementation.Initialized = true return nil } -func (implementation *Lib3MFImplementation) NewHandle() (Lib3MFImplementationHandle) { - handle := new (Lib3MFImplementationHandleStruct) +func (implementation *Lib3MFImplementation) NewHandle() Lib3MFImplementationHandle { + handle := new(Lib3MFImplementationHandleStruct) handle.Implementation = implementation handle.DLLhandle = 0 return handle } -func (implementation *Lib3MFImplementation) CallFunction(funcptr uintptr, parameters ... uintptr) (error) { - var ret uintptr; - if (!implementation.Initialized) { +func (implementation *Lib3MFImplementation) CallFunction(funcptr uintptr, parameters ...uintptr) error { + var ret uintptr + if !implementation.Initialized { return errors.New("Lib3MF Implementation has not been initialized!") } - - switch len(parameters) { - case 0: ret, _, _ = syscall.Syscall(funcptr, 0, 0, 0, 0) - case 1: ret, _, _ = syscall.Syscall(funcptr, 1, uintptr(parameters[0]), 0, 0) - case 2: ret, _, _ = syscall.Syscall(funcptr, 2, uintptr(parameters[0]), uintptr(parameters[1]), 0) - case 3: ret, _, _ = syscall.Syscall(funcptr, 3, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2])) - case 4: ret, _, _ = syscall.Syscall6(funcptr, 4, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), 0, 0) - case 5: ret, _, _ = syscall.Syscall6(funcptr, 5, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), 0) - case 6: ret, _, _ = syscall.Syscall6(funcptr, 6, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5])) - case 7: ret, _, _ = syscall.Syscall9(funcptr, 7, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), 0, 0) - case 8: ret, _, _ = syscall.Syscall9(funcptr, 8, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), 0) - case 9: ret, _, _ = syscall.Syscall9(funcptr, 9, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8])) - case 10: ret, _, _ = syscall.Syscall12(funcptr, 10, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8]), uintptr(parameters[9]), 0, 0) - case 11: ret, _, _ = syscall.Syscall12(funcptr, 11, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8]), uintptr(parameters[9]), uintptr(parameters[10]), 0) - case 12: ret, _, _ = syscall.Syscall12(funcptr, 12, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8]), uintptr(parameters[9]), uintptr(parameters[10]), uintptr(parameters[11])) - default: - return errors.New("Invalid DLL function parameter count!"); - } - - if (int(ret) != 0) { + + switch len(parameters) { + case 0: + ret, _, _ = syscall.Syscall(funcptr, 0, 0, 0, 0) + case 1: + ret, _, _ = syscall.Syscall(funcptr, 1, uintptr(parameters[0]), 0, 0) + case 2: + ret, _, _ = syscall.Syscall(funcptr, 2, uintptr(parameters[0]), uintptr(parameters[1]), 0) + case 3: + ret, _, _ = syscall.Syscall(funcptr, 3, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2])) + case 4: + ret, _, _ = syscall.Syscall6(funcptr, 4, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), 0, 0) + case 5: + ret, _, _ = syscall.Syscall6(funcptr, 5, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), 0) + case 6: + ret, _, _ = syscall.Syscall6(funcptr, 6, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5])) + case 7: + ret, _, _ = syscall.Syscall9(funcptr, 7, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), 0, 0) + case 8: + ret, _, _ = syscall.Syscall9(funcptr, 8, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), 0) + case 9: + ret, _, _ = syscall.Syscall9(funcptr, 9, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8])) + case 10: + ret, _, _ = syscall.Syscall12(funcptr, 10, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8]), uintptr(parameters[9]), 0, 0) + case 11: + ret, _, _ = syscall.Syscall12(funcptr, 11, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8]), uintptr(parameters[9]), uintptr(parameters[10]), 0) + case 12: + ret, _, _ = syscall.Syscall12(funcptr, 12, uintptr(parameters[0]), uintptr(parameters[1]), uintptr(parameters[2]), uintptr(parameters[3]), uintptr(parameters[4]), uintptr(parameters[5]), uintptr(parameters[6]), uintptr(parameters[7]), uintptr(parameters[8]), uintptr(parameters[9]), uintptr(parameters[10]), uintptr(parameters[11])) + default: + return errors.New("Invalid DLL function parameter count!") + } + + if int(ret) != 0 { return errors.New(fmt.Sprintf("Lib3MF Error: %.04x (%s)", int(ret), GetLib3MFErrorMessage(uint32(ret)))) } - + return nil } - -func (implementation *Lib3MFImplementation) Writer_WriteToFile(Writer Lib3MFHandle, sFilename string) (error) { +func (implementation *Lib3MFImplementation) Writer_WriteToFile(Writer Lib3MFHandle, sFilename string) error { var err error = nil - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_writetofile, implementation_writer.GetDLLInHandle(), StringInValue(sFilename)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Writer_GetStreamSize(Writer Lib3MFHandle) (uint64, error) { var err error = nil var nStreamSize uint64 = 0 - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_writer_getstreamsize, implementation_writer.GetDLLInHandle(), UInt64OutValue(&nStreamSize)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nStreamSize), err } @@ -2466,126 +2516,125 @@ func (implementation *Lib3MFImplementation) Writer_WriteToBuffer(Writer Lib3MFHa var neededforBuffer int64 = 0 var filledinBuffer int64 = 0 bufferBuffer := make([]uint8, 0) - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_writer_writetobuffer, implementation_writer.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforBuffer), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeBuffer := neededforBuffer bufferBuffer = make([]uint8, bufferSizeBuffer) err = implementation.CallFunction(implementation.Lib3MF_writer_writetobuffer, implementation_writer.GetDLLInHandle(), Int64InValue(bufferSizeBuffer), Int64OutValue(&filledinBuffer), uintptr(unsafe.Pointer(&bufferBuffer[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferBuffer, err } -func (implementation *Lib3MFImplementation) Writer_WriteToCallback(Writer Lib3MFHandle, pTheWriteCallback int64, pTheSeekCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Writer_WriteToCallback(Writer Lib3MFHandle, pTheWriteCallback int64, pTheSeekCallback int64, nUserData uint64) error { var err error = nil - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_writetocallback, implementation_writer.GetDLLInHandle(), 0, 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Writer_SetProgressCallback(Writer Lib3MFHandle, pProgressCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Writer_SetProgressCallback(Writer Lib3MFHandle, pProgressCallback int64, nUserData uint64) error { var err error = nil - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_setprogresscallback, implementation_writer.GetDLLInHandle(), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Writer_GetDecimalPrecision(Writer Lib3MFHandle) (uint32, error) { var err error = nil var nDecimalPrecision uint32 = 0 - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_writer_getdecimalprecision, implementation_writer.GetDLLInHandle(), UInt32OutValue(&nDecimalPrecision)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nDecimalPrecision), err } -func (implementation *Lib3MFImplementation) Writer_SetDecimalPrecision(Writer Lib3MFHandle, nDecimalPrecision uint32) (error) { +func (implementation *Lib3MFImplementation) Writer_SetDecimalPrecision(Writer Lib3MFHandle, nDecimalPrecision uint32) error { var err error = nil - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_setdecimalprecision, implementation_writer.GetDLLInHandle(), UInt32InValue(nDecimalPrecision)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Writer_SetStrictModeActive(Writer Lib3MFHandle, bStrictModeActive bool) (error) { +func (implementation *Lib3MFImplementation) Writer_SetStrictModeActive(Writer Lib3MFHandle, bStrictModeActive bool) error { var err error = nil var nStrictModeActive uint8 = 0 - if (bStrictModeActive) { + if bStrictModeActive { nStrictModeActive = 1 } - - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_setstrictmodeactive, implementation_writer.GetDLLInHandle(), UInt8InValue(nStrictModeActive)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Writer_GetStrictModeActive(Writer Lib3MFHandle) (bool, error) { var err error = nil var bStrictModeActive int64 = 0 - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_writer_getstrictmodeactive, implementation_writer.GetDLLInHandle(), Int64OutValue(&bStrictModeActive)) - if (err != nil) { + if err != nil { return false, err } - + return (bStrictModeActive != 0), err } @@ -2594,206 +2643,205 @@ func (implementation *Lib3MFImplementation) Writer_GetWarning(Writer Lib3MFHandl var nErrorCode uint32 = 0 var neededforWarning int64 = 0 var filledinWarning int64 = 0 - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return 0, "", err } err = implementation.CallFunction(implementation.Lib3MF_writer_getwarning, implementation_writer.GetDLLInHandle(), UInt32InValue(nIndex), UInt32OutValue(&nErrorCode), Int64InValue(0), Int64OutValue(&neededforWarning), Int64InValue(0)) - if (err != nil) { + if err != nil { return 0, "", err } bufferSizeWarning := neededforWarning bufferWarning := make([]byte, bufferSizeWarning) err = implementation.CallFunction(implementation.Lib3MF_writer_getwarning, implementation_writer.GetDLLInHandle(), UInt32InValue(nIndex), UInt32OutValue(&nErrorCode), Int64InValue(bufferSizeWarning), Int64OutValue(&filledinWarning), uintptr(unsafe.Pointer(&bufferWarning[0]))) - if (err != nil) { + if err != nil { return 0, "", err } - - return uint32(nErrorCode), string(bufferWarning[:(filledinWarning-1)]), err + + return uint32(nErrorCode), string(bufferWarning[:(filledinWarning - 1)]), err } func (implementation *Lib3MFImplementation) Writer_GetWarningCount(Writer Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_writer_getwarningcount, implementation_writer.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } -func (implementation *Lib3MFImplementation) Writer_AddKeyWrappingCallback(Writer Lib3MFHandle, sConsumerID string, pTheCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Writer_AddKeyWrappingCallback(Writer Lib3MFHandle, sConsumerID string, pTheCallback int64, nUserData uint64) error { var err error = nil - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_addkeywrappingcallback, implementation_writer.GetDLLInHandle(), StringInValue(sConsumerID), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Writer_SetContentEncryptionCallback(Writer Lib3MFHandle, pTheCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Writer_SetContentEncryptionCallback(Writer Lib3MFHandle, pTheCallback int64, nUserData uint64) error { var err error = nil - + implementation_writer, err := implementation.GetWrapperHandle(Writer) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_writer_setcontentencryptioncallback, implementation_writer.GetDLLInHandle(), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_ReadFromFile(Reader Lib3MFHandle, sFilename string) (error) { +func (implementation *Lib3MFImplementation) Reader_ReadFromFile(Reader Lib3MFHandle, sFilename string) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_readfromfile, implementation_reader.GetDLLInHandle(), StringInValue(sFilename)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_ReadFromBuffer(Reader Lib3MFHandle, Buffer []uint8) (error) { +func (implementation *Lib3MFImplementation) Reader_ReadFromBuffer(Reader Lib3MFHandle, Buffer []uint8) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_readfrombuffer, implementation_reader.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_ReadFromCallback(Reader Lib3MFHandle, pTheReadCallback int64, nStreamSize uint64, pTheSeekCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Reader_ReadFromCallback(Reader Lib3MFHandle, pTheReadCallback int64, nStreamSize uint64, pTheSeekCallback int64, nUserData uint64) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_readfromcallback, implementation_reader.GetDLLInHandle(), 0, UInt64InValue(nStreamSize), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_SetProgressCallback(Reader Lib3MFHandle, pProgressCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Reader_SetProgressCallback(Reader Lib3MFHandle, pProgressCallback int64, nUserData uint64) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_setprogresscallback, implementation_reader.GetDLLInHandle(), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_AddRelationToRead(Reader Lib3MFHandle, sRelationShipType string) (error) { +func (implementation *Lib3MFImplementation) Reader_AddRelationToRead(Reader Lib3MFHandle, sRelationShipType string) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_addrelationtoread, implementation_reader.GetDLLInHandle(), StringInValue(sRelationShipType)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_RemoveRelationToRead(Reader Lib3MFHandle, sRelationShipType string) (error) { +func (implementation *Lib3MFImplementation) Reader_RemoveRelationToRead(Reader Lib3MFHandle, sRelationShipType string) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_removerelationtoread, implementation_reader.GetDLLInHandle(), StringInValue(sRelationShipType)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_SetStrictModeActive(Reader Lib3MFHandle, bStrictModeActive bool) (error) { +func (implementation *Lib3MFImplementation) Reader_SetStrictModeActive(Reader Lib3MFHandle, bStrictModeActive bool) error { var err error = nil var nStrictModeActive uint8 = 0 - if (bStrictModeActive) { + if bStrictModeActive { nStrictModeActive = 1 } - - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_setstrictmodeactive, implementation_reader.GetDLLInHandle(), UInt8InValue(nStrictModeActive)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Reader_GetStrictModeActive(Reader Lib3MFHandle) (bool, error) { var err error = nil var bStrictModeActive int64 = 0 - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_reader_getstrictmodeactive, implementation_reader.GetDLLInHandle(), Int64OutValue(&bStrictModeActive)) - if (err != nil) { + if err != nil { return false, err } - + return (bStrictModeActive != 0), err } @@ -2802,72 +2850,72 @@ func (implementation *Lib3MFImplementation) Reader_GetWarning(Reader Lib3MFHandl var nErrorCode uint32 = 0 var neededforWarning int64 = 0 var filledinWarning int64 = 0 - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return 0, "", err } err = implementation.CallFunction(implementation.Lib3MF_reader_getwarning, implementation_reader.GetDLLInHandle(), UInt32InValue(nIndex), UInt32OutValue(&nErrorCode), Int64InValue(0), Int64OutValue(&neededforWarning), Int64InValue(0)) - if (err != nil) { + if err != nil { return 0, "", err } bufferSizeWarning := neededforWarning bufferWarning := make([]byte, bufferSizeWarning) err = implementation.CallFunction(implementation.Lib3MF_reader_getwarning, implementation_reader.GetDLLInHandle(), UInt32InValue(nIndex), UInt32OutValue(&nErrorCode), Int64InValue(bufferSizeWarning), Int64OutValue(&filledinWarning), uintptr(unsafe.Pointer(&bufferWarning[0]))) - if (err != nil) { + if err != nil { return 0, "", err } - - return uint32(nErrorCode), string(bufferWarning[:(filledinWarning-1)]), err + + return uint32(nErrorCode), string(bufferWarning[:(filledinWarning - 1)]), err } func (implementation *Lib3MFImplementation) Reader_GetWarningCount(Reader Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_reader_getwarningcount, implementation_reader.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } -func (implementation *Lib3MFImplementation) Reader_AddKeyWrappingCallback(Reader Lib3MFHandle, sConsumerID string, pTheCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Reader_AddKeyWrappingCallback(Reader Lib3MFHandle, sConsumerID string, pTheCallback int64, nUserData uint64) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_addkeywrappingcallback, implementation_reader.GetDLLInHandle(), StringInValue(sConsumerID), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Reader_SetContentEncryptionCallback(Reader Lib3MFHandle, pTheCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Reader_SetContentEncryptionCallback(Reader Lib3MFHandle, pTheCallback int64, nUserData uint64) error { var err error = nil - + implementation_reader, err := implementation.GetWrapperHandle(Reader) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_reader_setcontentencryptioncallback, implementation_reader.GetDLLInHandle(), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -2875,388 +2923,388 @@ func (implementation *Lib3MFImplementation) PackagePart_GetPath(PackagePart Lib3 var err error = nil var neededforPath int64 = 0 var filledinPath int64 = 0 - + implementation_packagepart, err := implementation.GetWrapperHandle(PackagePart) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_packagepart_getpath, implementation_packagepart.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPath), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizePath := neededforPath bufferPath := make([]byte, bufferSizePath) err = implementation.CallFunction(implementation.Lib3MF_packagepart_getpath, implementation_packagepart.GetDLLInHandle(), Int64InValue(bufferSizePath), Int64OutValue(&filledinPath), uintptr(unsafe.Pointer(&bufferPath[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferPath[:(filledinPath-1)]), err + + return string(bufferPath[:(filledinPath - 1)]), err } -func (implementation *Lib3MFImplementation) PackagePart_SetPath(PackagePart Lib3MFHandle, sPath string) (error) { +func (implementation *Lib3MFImplementation) PackagePart_SetPath(PackagePart Lib3MFHandle, sPath string) error { var err error = nil - + implementation_packagepart, err := implementation.GetWrapperHandle(PackagePart) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_packagepart_setpath, implementation_packagepart.GetDLLInHandle(), StringInValue(sPath)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Resource_GetResourceID(Resource Lib3MFHandle) (uint32, error) { var err error = nil var nUniqueResourceID uint32 = 0 - + implementation_resource, err := implementation.GetWrapperHandle(Resource) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_resource_getresourceid, implementation_resource.GetDLLInHandle(), UInt32OutValue(&nUniqueResourceID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nUniqueResourceID), err } func (implementation *Lib3MFImplementation) Resource_GetUniqueResourceID(Resource Lib3MFHandle) (uint32, error) { var err error = nil var nUniqueResourceID uint32 = 0 - + implementation_resource, err := implementation.GetWrapperHandle(Resource) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_resource_getuniqueresourceid, implementation_resource.GetDLLInHandle(), UInt32OutValue(&nUniqueResourceID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nUniqueResourceID), err } func (implementation *Lib3MFImplementation) Resource_PackagePart(Resource Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hPackagePart := implementation.NewHandle() - + implementation_resource, err := implementation.GetWrapperHandle(Resource) - if (err != nil) { + if err != nil { return hPackagePart, err } err = implementation.CallFunction(implementation.Lib3MF_resource_packagepart, implementation_resource.GetDLLInHandle(), hPackagePart.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hPackagePart, err } - + return hPackagePart, err } -func (implementation *Lib3MFImplementation) Resource_SetPackagePart(Resource Lib3MFHandle, PackagePart Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Resource_SetPackagePart(Resource Lib3MFHandle, PackagePart Lib3MFHandle) error { var err error = nil - + implementation_resource, err := implementation.GetWrapperHandle(Resource) - if (err != nil) { + if err != nil { return err } implementation_packagepart, err := implementation.GetWrapperHandle(PackagePart) - if (err != nil) { + if err != nil { return err } - + PackagePartDLLHandle := implementation_packagepart.GetDLLInHandle() - if (PackagePartDLLHandle == 0) { + if PackagePartDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_resource_setpackagepart, implementation_resource.GetDLLInHandle(), PackagePartDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Resource_GetModelResourceID(Resource Lib3MFHandle) (uint32, error) { var err error = nil var nModelResourceId uint32 = 0 - + implementation_resource, err := implementation.GetWrapperHandle(Resource) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_resource_getmodelresourceid, implementation_resource.GetDLLInHandle(), UInt32OutValue(&nModelResourceId)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nModelResourceId), err } func (implementation *Lib3MFImplementation) ResourceIterator_MoveNext(ResourceIterator Lib3MFHandle) (bool, error) { var err error = nil var bHasNext int64 = 0 - + implementation_resourceiterator, err := implementation.GetWrapperHandle(ResourceIterator) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_resourceiterator_movenext, implementation_resourceiterator.GetDLLInHandle(), Int64OutValue(&bHasNext)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasNext != 0), err } func (implementation *Lib3MFImplementation) ResourceIterator_MovePrevious(ResourceIterator Lib3MFHandle) (bool, error) { var err error = nil var bHasPrevious int64 = 0 - + implementation_resourceiterator, err := implementation.GetWrapperHandle(ResourceIterator) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_resourceiterator_moveprevious, implementation_resourceiterator.GetDLLInHandle(), Int64OutValue(&bHasPrevious)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasPrevious != 0), err } func (implementation *Lib3MFImplementation) ResourceIterator_GetCurrent(ResourceIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_resourceiterator, err := implementation.GetWrapperHandle(ResourceIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_resourceiterator_getcurrent, implementation_resourceiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) ResourceIterator_Clone(ResourceIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hOutResourceIterator := implementation.NewHandle() - + implementation_resourceiterator, err := implementation.GetWrapperHandle(ResourceIterator) - if (err != nil) { + if err != nil { return hOutResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_resourceiterator_clone, implementation_resourceiterator.GetDLLInHandle(), hOutResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hOutResourceIterator, err } - + return hOutResourceIterator, err } func (implementation *Lib3MFImplementation) ResourceIterator_Count(ResourceIterator Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_resourceiterator, err := implementation.GetWrapperHandle(ResourceIterator) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_resourceiterator_count, implementation_resourceiterator.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) SliceStackIterator_GetCurrentSliceStack(SliceStackIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_slicestackiterator, err := implementation.GetWrapperHandle(SliceStackIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_slicestackiterator_getcurrentslicestack, implementation_slicestackiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) ObjectIterator_GetCurrentObject(ObjectIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_objectiterator, err := implementation.GetWrapperHandle(ObjectIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_objectiterator_getcurrentobject, implementation_objectiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) MeshObjectIterator_GetCurrentMeshObject(MeshObjectIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_meshobjectiterator, err := implementation.GetWrapperHandle(MeshObjectIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_meshobjectiterator_getcurrentmeshobject, implementation_meshobjectiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) ComponentsObjectIterator_GetCurrentComponentsObject(ComponentsObjectIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_componentsobjectiterator, err := implementation.GetWrapperHandle(ComponentsObjectIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_componentsobjectiterator_getcurrentcomponentsobject, implementation_componentsobjectiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) Texture2DIterator_GetCurrentTexture2D(Texture2DIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_texture2diterator, err := implementation.GetWrapperHandle(Texture2DIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_texture2diterator_getcurrenttexture2d, implementation_texture2diterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) BaseMaterialGroupIterator_GetCurrentBaseMaterialGroup(BaseMaterialGroupIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_basematerialgroupiterator, err := implementation.GetWrapperHandle(BaseMaterialGroupIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroupiterator_getcurrentbasematerialgroup, implementation_basematerialgroupiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) ColorGroupIterator_GetCurrentColorGroup(ColorGroupIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_colorgroupiterator, err := implementation.GetWrapperHandle(ColorGroupIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_colorgroupiterator_getcurrentcolorgroup, implementation_colorgroupiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) Texture2DGroupIterator_GetCurrentTexture2DGroup(Texture2DGroupIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_texture2dgroupiterator, err := implementation.GetWrapperHandle(Texture2DGroupIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroupiterator_getcurrenttexture2dgroup, implementation_texture2dgroupiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) CompositeMaterialsIterator_GetCurrentCompositeMaterials(CompositeMaterialsIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_compositematerialsiterator, err := implementation.GetWrapperHandle(CompositeMaterialsIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_compositematerialsiterator_getcurrentcompositematerials, implementation_compositematerialsiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } func (implementation *Lib3MFImplementation) MultiPropertyGroupIterator_GetCurrentMultiPropertyGroup(MultiPropertyGroupIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResource := implementation.NewHandle() - + implementation_multipropertygroupiterator, err := implementation.GetWrapperHandle(MultiPropertyGroupIterator) - if (err != nil) { + if err != nil { return hResource, err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroupiterator_getcurrentmultipropertygroup, implementation_multipropertygroupiterator.GetDLLInHandle(), hResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResource, err } - + return hResource, err } @@ -3264,39 +3312,39 @@ func (implementation *Lib3MFImplementation) MetaData_GetNameSpace(MetaData Lib3M var err error = nil var neededforNameSpace int64 = 0 var filledinNameSpace int64 = 0 - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_metadata_getnamespace, implementation_metadata.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforNameSpace), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeNameSpace := neededforNameSpace bufferNameSpace := make([]byte, bufferSizeNameSpace) err = implementation.CallFunction(implementation.Lib3MF_metadata_getnamespace, implementation_metadata.GetDLLInHandle(), Int64InValue(bufferSizeNameSpace), Int64OutValue(&filledinNameSpace), uintptr(unsafe.Pointer(&bufferNameSpace[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferNameSpace[:(filledinNameSpace-1)]), err + + return string(bufferNameSpace[:(filledinNameSpace - 1)]), err } -func (implementation *Lib3MFImplementation) MetaData_SetNameSpace(MetaData Lib3MFHandle, sNameSpace string) (error) { +func (implementation *Lib3MFImplementation) MetaData_SetNameSpace(MetaData Lib3MFHandle, sNameSpace string) error { var err error = nil - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_metadata_setnamespace, implementation_metadata.GetDLLInHandle(), StringInValue(sNameSpace)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -3304,39 +3352,39 @@ func (implementation *Lib3MFImplementation) MetaData_GetName(MetaData Lib3MFHand var err error = nil var neededforName int64 = 0 var filledinName int64 = 0 - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_metadata_getname, implementation_metadata.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforName), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeName := neededforName bufferName := make([]byte, bufferSizeName) err = implementation.CallFunction(implementation.Lib3MF_metadata_getname, implementation_metadata.GetDLLInHandle(), Int64InValue(bufferSizeName), Int64OutValue(&filledinName), uintptr(unsafe.Pointer(&bufferName[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferName[:(filledinName-1)]), err + + return string(bufferName[:(filledinName - 1)]), err } -func (implementation *Lib3MFImplementation) MetaData_SetName(MetaData Lib3MFHandle, sName string) (error) { +func (implementation *Lib3MFImplementation) MetaData_SetName(MetaData Lib3MFHandle, sName string) error { var err error = nil - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_metadata_setname, implementation_metadata.GetDLLInHandle(), StringInValue(sName)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -3344,61 +3392,60 @@ func (implementation *Lib3MFImplementation) MetaData_GetKey(MetaData Lib3MFHandl var err error = nil var neededforKey int64 = 0 var filledinKey int64 = 0 - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_metadata_getkey, implementation_metadata.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforKey), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeKey := neededforKey bufferKey := make([]byte, bufferSizeKey) err = implementation.CallFunction(implementation.Lib3MF_metadata_getkey, implementation_metadata.GetDLLInHandle(), Int64InValue(bufferSizeKey), Int64OutValue(&filledinKey), uintptr(unsafe.Pointer(&bufferKey[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferKey[:(filledinKey-1)]), err + + return string(bufferKey[:(filledinKey - 1)]), err } func (implementation *Lib3MFImplementation) MetaData_GetMustPreserve(MetaData Lib3MFHandle) (bool, error) { var err error = nil var bMustPreserve int64 = 0 - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_metadata_getmustpreserve, implementation_metadata.GetDLLInHandle(), Int64OutValue(&bMustPreserve)) - if (err != nil) { + if err != nil { return false, err } - + return (bMustPreserve != 0), err } -func (implementation *Lib3MFImplementation) MetaData_SetMustPreserve(MetaData Lib3MFHandle, bMustPreserve bool) (error) { +func (implementation *Lib3MFImplementation) MetaData_SetMustPreserve(MetaData Lib3MFHandle, bMustPreserve bool) error { var err error = nil var nMustPreserve uint8 = 0 - if (bMustPreserve) { + if bMustPreserve { nMustPreserve = 1 } - - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_metadata_setmustpreserve, implementation_metadata.GetDLLInHandle(), UInt8InValue(nMustPreserve)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -3406,39 +3453,39 @@ func (implementation *Lib3MFImplementation) MetaData_GetType(MetaData Lib3MFHand var err error = nil var neededforType int64 = 0 var filledinType int64 = 0 - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_metadata_gettype, implementation_metadata.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforType), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeType := neededforType bufferType := make([]byte, bufferSizeType) err = implementation.CallFunction(implementation.Lib3MF_metadata_gettype, implementation_metadata.GetDLLInHandle(), Int64InValue(bufferSizeType), Int64OutValue(&filledinType), uintptr(unsafe.Pointer(&bufferType[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferType[:(filledinType-1)]), err + + return string(bufferType[:(filledinType - 1)]), err } -func (implementation *Lib3MFImplementation) MetaData_SetType(MetaData Lib3MFHandle, sType string) (error) { +func (implementation *Lib3MFImplementation) MetaData_SetType(MetaData Lib3MFHandle, sType string) error { var err error = nil - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_metadata_settype, implementation_metadata.GetDLLInHandle(), StringInValue(sType)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -3446,187 +3493,187 @@ func (implementation *Lib3MFImplementation) MetaData_GetValue(MetaData Lib3MFHan var err error = nil var neededforValue int64 = 0 var filledinValue int64 = 0 - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_metadata_getvalue, implementation_metadata.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforValue), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeValue := neededforValue bufferValue := make([]byte, bufferSizeValue) err = implementation.CallFunction(implementation.Lib3MF_metadata_getvalue, implementation_metadata.GetDLLInHandle(), Int64InValue(bufferSizeValue), Int64OutValue(&filledinValue), uintptr(unsafe.Pointer(&bufferValue[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferValue[:(filledinValue-1)]), err + + return string(bufferValue[:(filledinValue - 1)]), err } -func (implementation *Lib3MFImplementation) MetaData_SetValue(MetaData Lib3MFHandle, sValue string) (error) { +func (implementation *Lib3MFImplementation) MetaData_SetValue(MetaData Lib3MFHandle, sValue string) error { var err error = nil - + implementation_metadata, err := implementation.GetWrapperHandle(MetaData) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_metadata_setvalue, implementation_metadata.GetDLLInHandle(), StringInValue(sValue)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MetaDataGroup_GetMetaDataCount(MetaDataGroup Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_metadatagroup, err := implementation.GetWrapperHandle(MetaDataGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_metadatagroup_getmetadatacount, implementation_metadatagroup.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } func (implementation *Lib3MFImplementation) MetaDataGroup_GetMetaData(MetaDataGroup Lib3MFHandle, nIndex uint32) (Lib3MFHandle, error) { var err error = nil hMetaData := implementation.NewHandle() - + implementation_metadatagroup, err := implementation.GetWrapperHandle(MetaDataGroup) - if (err != nil) { + if err != nil { return hMetaData, err } err = implementation.CallFunction(implementation.Lib3MF_metadatagroup_getmetadata, implementation_metadatagroup.GetDLLInHandle(), UInt32InValue(nIndex), hMetaData.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMetaData, err } - + return hMetaData, err } func (implementation *Lib3MFImplementation) MetaDataGroup_GetMetaDataByKey(MetaDataGroup Lib3MFHandle, sNameSpace string, sName string) (Lib3MFHandle, error) { var err error = nil hMetaData := implementation.NewHandle() - + implementation_metadatagroup, err := implementation.GetWrapperHandle(MetaDataGroup) - if (err != nil) { + if err != nil { return hMetaData, err } err = implementation.CallFunction(implementation.Lib3MF_metadatagroup_getmetadatabykey, implementation_metadatagroup.GetDLLInHandle(), StringInValue(sNameSpace), StringInValue(sName), hMetaData.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMetaData, err } - + return hMetaData, err } -func (implementation *Lib3MFImplementation) MetaDataGroup_RemoveMetaDataByIndex(MetaDataGroup Lib3MFHandle, nIndex uint32) (error) { +func (implementation *Lib3MFImplementation) MetaDataGroup_RemoveMetaDataByIndex(MetaDataGroup Lib3MFHandle, nIndex uint32) error { var err error = nil - + implementation_metadatagroup, err := implementation.GetWrapperHandle(MetaDataGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_metadatagroup_removemetadatabyindex, implementation_metadatagroup.GetDLLInHandle(), UInt32InValue(nIndex)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) MetaDataGroup_RemoveMetaData(MetaDataGroup Lib3MFHandle, TheMetaData Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) MetaDataGroup_RemoveMetaData(MetaDataGroup Lib3MFHandle, TheMetaData Lib3MFHandle) error { var err error = nil - + implementation_metadatagroup, err := implementation.GetWrapperHandle(MetaDataGroup) - if (err != nil) { + if err != nil { return err } implementation_themetadata, err := implementation.GetWrapperHandle(TheMetaData) - if (err != nil) { + if err != nil { return err } - + TheMetaDataDLLHandle := implementation_themetadata.GetDLLInHandle() - if (TheMetaDataDLLHandle == 0) { + if TheMetaDataDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_metadatagroup_removemetadata, implementation_metadatagroup.GetDLLInHandle(), TheMetaDataDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MetaDataGroup_AddMetaData(MetaDataGroup Lib3MFHandle, sNameSpace string, sName string, sValue string, sType string, bMustPreserve bool) (Lib3MFHandle, error) { var err error = nil var nMustPreserve uint8 = 0 - if (bMustPreserve) { + if bMustPreserve { nMustPreserve = 1 } - + hMetaData := implementation.NewHandle() - + implementation_metadatagroup, err := implementation.GetWrapperHandle(MetaDataGroup) - if (err != nil) { + if err != nil { return hMetaData, err } err = implementation.CallFunction(implementation.Lib3MF_metadatagroup_addmetadata, implementation_metadatagroup.GetDLLInHandle(), StringInValue(sNameSpace), StringInValue(sName), StringInValue(sValue), StringInValue(sType), UInt8InValue(nMustPreserve), hMetaData.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMetaData, err } - + return hMetaData, err } func (implementation *Lib3MFImplementation) Object_GetType(Object Lib3MFHandle) (ELib3MFObjectType, error) { var err error = nil var eObjectType uint64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_object_gettype, implementation_object.GetDLLInHandle(), UInt64OutValue(&eObjectType)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFObjectType (eObjectType), err + + return ELib3MFObjectType(eObjectType), err } -func (implementation *Lib3MFImplementation) Object_SetType(Object Lib3MFHandle, eObjectType ELib3MFObjectType) (error) { +func (implementation *Lib3MFImplementation) Object_SetType(Object Lib3MFHandle, eObjectType ELib3MFObjectType) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_settype, implementation_object.GetDLLInHandle(), uintptr(eObjectType)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -3634,39 +3681,39 @@ func (implementation *Lib3MFImplementation) Object_GetName(Object Lib3MFHandle) var err error = nil var neededforName int64 = 0 var filledinName int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_object_getname, implementation_object.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforName), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeName := neededforName bufferName := make([]byte, bufferSizeName) err = implementation.CallFunction(implementation.Lib3MF_object_getname, implementation_object.GetDLLInHandle(), Int64InValue(bufferSizeName), Int64OutValue(&filledinName), uintptr(unsafe.Pointer(&bufferName[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferName[:(filledinName-1)]), err + + return string(bufferName[:(filledinName - 1)]), err } -func (implementation *Lib3MFImplementation) Object_SetName(Object Lib3MFHandle, sName string) (error) { +func (implementation *Lib3MFImplementation) Object_SetName(Object Lib3MFHandle, sName string) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_setname, implementation_object.GetDLLInHandle(), StringInValue(sName)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -3674,166 +3721,166 @@ func (implementation *Lib3MFImplementation) Object_GetPartNumber(Object Lib3MFHa var err error = nil var neededforPartNumber int64 = 0 var filledinPartNumber int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_object_getpartnumber, implementation_object.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPartNumber), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizePartNumber := neededforPartNumber bufferPartNumber := make([]byte, bufferSizePartNumber) err = implementation.CallFunction(implementation.Lib3MF_object_getpartnumber, implementation_object.GetDLLInHandle(), Int64InValue(bufferSizePartNumber), Int64OutValue(&filledinPartNumber), uintptr(unsafe.Pointer(&bufferPartNumber[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferPartNumber[:(filledinPartNumber-1)]), err + + return string(bufferPartNumber[:(filledinPartNumber - 1)]), err } -func (implementation *Lib3MFImplementation) Object_SetPartNumber(Object Lib3MFHandle, sPartNumber string) (error) { +func (implementation *Lib3MFImplementation) Object_SetPartNumber(Object Lib3MFHandle, sPartNumber string) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_setpartnumber, implementation_object.GetDLLInHandle(), StringInValue(sPartNumber)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Object_IsMeshObject(Object Lib3MFHandle) (bool, error) { var err error = nil var bIsMeshObject int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_object_ismeshobject, implementation_object.GetDLLInHandle(), Int64OutValue(&bIsMeshObject)) - if (err != nil) { + if err != nil { return false, err } - + return (bIsMeshObject != 0), err } func (implementation *Lib3MFImplementation) Object_IsComponentsObject(Object Lib3MFHandle) (bool, error) { var err error = nil var bIsComponentsObject int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_object_iscomponentsobject, implementation_object.GetDLLInHandle(), Int64OutValue(&bIsComponentsObject)) - if (err != nil) { + if err != nil { return false, err } - + return (bIsComponentsObject != 0), err } func (implementation *Lib3MFImplementation) Object_IsValid(Object Lib3MFHandle) (bool, error) { var err error = nil var bIsValid int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_object_isvalid, implementation_object.GetDLLInHandle(), Int64OutValue(&bIsValid)) - if (err != nil) { + if err != nil { return false, err } - + return (bIsValid != 0), err } -func (implementation *Lib3MFImplementation) Object_SetAttachmentAsThumbnail(Object Lib3MFHandle, Attachment Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Object_SetAttachmentAsThumbnail(Object Lib3MFHandle, Attachment Lib3MFHandle) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } - + AttachmentDLLHandle := implementation_attachment.GetDLLInHandle() - if (AttachmentDLLHandle == 0) { + if AttachmentDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_object_setattachmentasthumbnail, implementation_object.GetDLLInHandle(), AttachmentDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Object_GetThumbnailAttachment(Object Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hAttachment := implementation.NewHandle() - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return hAttachment, err } err = implementation.CallFunction(implementation.Lib3MF_object_getthumbnailattachment, implementation_object.GetDLLInHandle(), hAttachment.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachment, err } - + return hAttachment, err } -func (implementation *Lib3MFImplementation) Object_ClearThumbnailAttachment(Object Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Object_ClearThumbnailAttachment(Object Lib3MFHandle) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_clearthumbnailattachment, implementation_object.GetDLLInHandle()) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Object_GetOutbox(Object Lib3MFHandle) (sLib3MFBox, error) { var err error = nil var sOutbox sLib3MFBox - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return sOutbox, err } err = implementation.CallFunction(implementation.Lib3MF_object_getoutbox, implementation_object.GetDLLInHandle(), 0) - if (err != nil) { + if err != nil { return sOutbox, err } - + return sOutbox, err } @@ -3842,362 +3889,362 @@ func (implementation *Lib3MFImplementation) Object_GetUUID(Object Lib3MFHandle) var bHasUUID int64 = 0 var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return false, "", err } err = implementation.CallFunction(implementation.Lib3MF_object_getuuid, implementation_object.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_object_getuuid, implementation_object.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasUUID != 0), string(bufferUUID[:(filledinUUID-1)]), err + + return (bHasUUID != 0), string(bufferUUID[:(filledinUUID - 1)]), err } -func (implementation *Lib3MFImplementation) Object_SetUUID(Object Lib3MFHandle, sUUID string) (error) { +func (implementation *Lib3MFImplementation) Object_SetUUID(Object Lib3MFHandle, sUUID string) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_setuuid, implementation_object.GetDLLInHandle(), StringInValue(sUUID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Object_GetMetaDataGroup(Object Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hMetaDataGroup := implementation.NewHandle() - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return hMetaDataGroup, err } err = implementation.CallFunction(implementation.Lib3MF_object_getmetadatagroup, implementation_object.GetDLLInHandle(), hMetaDataGroup.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMetaDataGroup, err } - + return hMetaDataGroup, err } -func (implementation *Lib3MFImplementation) Object_SetSlicesMeshResolution(Object Lib3MFHandle, eMeshResolution ELib3MFSlicesMeshResolution) (error) { +func (implementation *Lib3MFImplementation) Object_SetSlicesMeshResolution(Object Lib3MFHandle, eMeshResolution ELib3MFSlicesMeshResolution) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_setslicesmeshresolution, implementation_object.GetDLLInHandle(), uintptr(eMeshResolution)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Object_GetSlicesMeshResolution(Object Lib3MFHandle) (ELib3MFSlicesMeshResolution, error) { var err error = nil var eMeshResolution uint64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_object_getslicesmeshresolution, implementation_object.GetDLLInHandle(), UInt64OutValue(&eMeshResolution)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFSlicesMeshResolution (eMeshResolution), err + + return ELib3MFSlicesMeshResolution(eMeshResolution), err } func (implementation *Lib3MFImplementation) Object_HasSlices(Object Lib3MFHandle, bRecursive bool) (bool, error) { var err error = nil var nRecursive uint8 = 0 - if (bRecursive) { + if bRecursive { nRecursive = 1 } - + var bHasSlices int64 = 0 - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_object_hasslices, implementation_object.GetDLLInHandle(), UInt8InValue(nRecursive), Int64OutValue(&bHasSlices)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasSlices != 0), err } -func (implementation *Lib3MFImplementation) Object_ClearSliceStack(Object Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Object_ClearSliceStack(Object Lib3MFHandle) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_object_clearslicestack, implementation_object.GetDLLInHandle()) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Object_GetSliceStack(Object Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hSliceStackInstance := implementation.NewHandle() - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return hSliceStackInstance, err } err = implementation.CallFunction(implementation.Lib3MF_object_getslicestack, implementation_object.GetDLLInHandle(), hSliceStackInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hSliceStackInstance, err } - + return hSliceStackInstance, err } -func (implementation *Lib3MFImplementation) Object_AssignSliceStack(Object Lib3MFHandle, SliceStackInstance Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Object_AssignSliceStack(Object Lib3MFHandle, SliceStackInstance Lib3MFHandle) error { var err error = nil - + implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return err } implementation_slicestackinstance, err := implementation.GetWrapperHandle(SliceStackInstance) - if (err != nil) { + if err != nil { return err } - + SliceStackInstanceDLLHandle := implementation_slicestackinstance.GetDLLInHandle() - if (SliceStackInstanceDLLHandle == 0) { + if SliceStackInstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_object_assignslicestack, implementation_object.GetDLLInHandle(), SliceStackInstanceDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MeshObject_GetVertexCount(MeshObject Lib3MFHandle) (uint32, error) { var err error = nil var nVertexCount uint32 = 0 - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getvertexcount, implementation_meshobject.GetDLLInHandle(), UInt32OutValue(&nVertexCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nVertexCount), err } func (implementation *Lib3MFImplementation) MeshObject_GetTriangleCount(MeshObject Lib3MFHandle) (uint32, error) { var err error = nil var nVertexCount uint32 = 0 - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_gettrianglecount, implementation_meshobject.GetDLLInHandle(), UInt32OutValue(&nVertexCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nVertexCount), err } func (implementation *Lib3MFImplementation) MeshObject_GetVertex(MeshObject Lib3MFHandle, nIndex uint32) (sLib3MFPosition, error) { var err error = nil var sCoordinates sLib3MFPosition - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return sCoordinates, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getvertex, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nIndex), 0) - if (err != nil) { + if err != nil { return sCoordinates, err } - + return sCoordinates, err } -func (implementation *Lib3MFImplementation) MeshObject_SetVertex(MeshObject Lib3MFHandle, nIndex uint32, sCoordinates sLib3MFPosition) (error) { +func (implementation *Lib3MFImplementation) MeshObject_SetVertex(MeshObject Lib3MFHandle, nIndex uint32, sCoordinates sLib3MFPosition) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_setvertex, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nIndex), uintptr(unsafe.Pointer(&sCoordinates))) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MeshObject_AddVertex(MeshObject Lib3MFHandle, sCoordinates sLib3MFPosition) (uint32, error) { var err error = nil var nNewIndex uint32 = 0 - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_addvertex, implementation_meshobject.GetDLLInHandle(), uintptr(unsafe.Pointer(&sCoordinates)), UInt32OutValue(&nNewIndex)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nNewIndex), err } func (implementation *Lib3MFImplementation) MeshObject_GetVertices(MeshObject Lib3MFHandle) ([]sLib3MFPosition, error) { var err error = nil arrayVertices := make([]sLib3MFPosition, 0) - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return make([]sLib3MFPosition, 0), err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getvertices, implementation_meshobject.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFPosition, 0), err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getvertices, implementation_meshobject.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFPosition, 0), err } - + return arrayVertices, err } func (implementation *Lib3MFImplementation) MeshObject_GetTriangle(MeshObject Lib3MFHandle, nIndex uint32) (sLib3MFTriangle, error) { var err error = nil var sIndices sLib3MFTriangle - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return sIndices, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_gettriangle, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nIndex), 0) - if (err != nil) { + if err != nil { return sIndices, err } - + return sIndices, err } -func (implementation *Lib3MFImplementation) MeshObject_SetTriangle(MeshObject Lib3MFHandle, nIndex uint32, sIndices sLib3MFTriangle) (error) { +func (implementation *Lib3MFImplementation) MeshObject_SetTriangle(MeshObject Lib3MFHandle, nIndex uint32, sIndices sLib3MFTriangle) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_settriangle, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nIndex), uintptr(unsafe.Pointer(&sIndices))) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MeshObject_AddTriangle(MeshObject Lib3MFHandle, sIndices sLib3MFTriangle) (uint32, error) { var err error = nil var nNewIndex uint32 = 0 - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_addtriangle, implementation_meshobject.GetDLLInHandle(), uintptr(unsafe.Pointer(&sIndices)), UInt32OutValue(&nNewIndex)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nNewIndex), err } func (implementation *Lib3MFImplementation) MeshObject_GetTriangleIndices(MeshObject Lib3MFHandle) ([]sLib3MFTriangle, error) { var err error = nil arrayIndices := make([]sLib3MFTriangle, 0) - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return make([]sLib3MFTriangle, 0), err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_gettriangleindices, implementation_meshobject.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFTriangle, 0), err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_gettriangleindices, implementation_meshobject.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFTriangle, 0), err } - + return arrayIndices, err } -func (implementation *Lib3MFImplementation) MeshObject_SetObjectLevelProperty(MeshObject Lib3MFHandle, nUniqueResourceID uint32, nPropertyID uint32) (error) { +func (implementation *Lib3MFImplementation) MeshObject_SetObjectLevelProperty(MeshObject Lib3MFHandle, nUniqueResourceID uint32, nPropertyID uint32) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_setobjectlevelproperty, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), UInt32InValue(nPropertyID)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -4206,186 +4253,186 @@ func (implementation *Lib3MFImplementation) MeshObject_GetObjectLevelProperty(Me var nUniqueResourceID uint32 = 0 var nPropertyID uint32 = 0 var bHasObjectLevelProperty int64 = 0 - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return 0, 0, false, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getobjectlevelproperty, implementation_meshobject.GetDLLInHandle(), UInt32OutValue(&nUniqueResourceID), UInt32OutValue(&nPropertyID), Int64OutValue(&bHasObjectLevelProperty)) - if (err != nil) { + if err != nil { return 0, 0, false, err } - + return uint32(nUniqueResourceID), uint32(nPropertyID), (bHasObjectLevelProperty != 0), err } -func (implementation *Lib3MFImplementation) MeshObject_SetTriangleProperties(MeshObject Lib3MFHandle, nIndex uint32, sProperties sLib3MFTriangleProperties) (error) { +func (implementation *Lib3MFImplementation) MeshObject_SetTriangleProperties(MeshObject Lib3MFHandle, nIndex uint32, sProperties sLib3MFTriangleProperties) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_settriangleproperties, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nIndex), uintptr(unsafe.Pointer(&sProperties))) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MeshObject_GetTriangleProperties(MeshObject Lib3MFHandle, nIndex uint32) (sLib3MFTriangleProperties, error) { var err error = nil var sProperty sLib3MFTriangleProperties - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return sProperty, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_gettriangleproperties, implementation_meshobject.GetDLLInHandle(), UInt32InValue(nIndex), 0) - if (err != nil) { + if err != nil { return sProperty, err } - + return sProperty, err } -func (implementation *Lib3MFImplementation) MeshObject_SetAllTriangleProperties(MeshObject Lib3MFHandle, PropertiesArray []sLib3MFTriangleProperties) (error) { +func (implementation *Lib3MFImplementation) MeshObject_SetAllTriangleProperties(MeshObject Lib3MFHandle, PropertiesArray []sLib3MFTriangleProperties) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_setalltriangleproperties, implementation_meshobject.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MeshObject_GetAllTriangleProperties(MeshObject Lib3MFHandle) ([]sLib3MFTriangleProperties, error) { var err error = nil arrayPropertiesArray := make([]sLib3MFTriangleProperties, 0) - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return make([]sLib3MFTriangleProperties, 0), err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getalltriangleproperties, implementation_meshobject.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFTriangleProperties, 0), err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_getalltriangleproperties, implementation_meshobject.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFTriangleProperties, 0), err } - + return arrayPropertiesArray, err } -func (implementation *Lib3MFImplementation) MeshObject_ClearAllProperties(MeshObject Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) MeshObject_ClearAllProperties(MeshObject Lib3MFHandle) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_clearallproperties, implementation_meshobject.GetDLLInHandle()) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) MeshObject_SetGeometry(MeshObject Lib3MFHandle, Vertices []sLib3MFPosition, Indices []sLib3MFTriangle) (error) { +func (implementation *Lib3MFImplementation) MeshObject_SetGeometry(MeshObject Lib3MFHandle, Vertices []sLib3MFPosition, Indices []sLib3MFTriangle) error { var err error = nil - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_setgeometry, implementation_meshobject.GetDLLInHandle(), 0, 0, 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MeshObject_IsManifoldAndOriented(MeshObject Lib3MFHandle) (bool, error) { var err error = nil var bIsManifoldAndOriented int64 = 0 - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_ismanifoldandoriented, implementation_meshobject.GetDLLInHandle(), Int64OutValue(&bIsManifoldAndOriented)) - if (err != nil) { + if err != nil { return false, err } - + return (bIsManifoldAndOriented != 0), err } func (implementation *Lib3MFImplementation) MeshObject_BeamLattice(MeshObject Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hTheBeamLattice := implementation.NewHandle() - + implementation_meshobject, err := implementation.GetWrapperHandle(MeshObject) - if (err != nil) { + if err != nil { return hTheBeamLattice, err } err = implementation.CallFunction(implementation.Lib3MF_meshobject_beamlattice, implementation_meshobject.GetDLLInHandle(), hTheBeamLattice.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheBeamLattice, err } - + return hTheBeamLattice, err } func (implementation *Lib3MFImplementation) BeamLattice_GetMinLength(BeamLattice Lib3MFHandle) (float64, error) { var err error = nil var dMinLength float64 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getminlength, implementation_beamlattice.GetDLLInHandle(), Float64OutValue(&dMinLength)) - if (err != nil) { + if err != nil { return 0, err } - + return dMinLength, err } -func (implementation *Lib3MFImplementation) BeamLattice_SetMinLength(BeamLattice Lib3MFHandle, dMinLength float64) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetMinLength(BeamLattice Lib3MFHandle, dMinLength float64) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setminlength, implementation_beamlattice.GetDLLInHandle(), Float64InValue(dMinLength)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -4393,33 +4440,33 @@ func (implementation *Lib3MFImplementation) BeamLattice_GetClipping(BeamLattice var err error = nil var eClipMode uint64 = 0 var nUniqueResourceID uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getclipping, implementation_beamlattice.GetDLLInHandle(), UInt64OutValue(&eClipMode), UInt32OutValue(&nUniqueResourceID)) - if (err != nil) { + if err != nil { return 0, 0, err } - - return ELib3MFBeamLatticeClipMode (eClipMode), uint32(nUniqueResourceID), err + + return ELib3MFBeamLatticeClipMode(eClipMode), uint32(nUniqueResourceID), err } -func (implementation *Lib3MFImplementation) BeamLattice_SetClipping(BeamLattice Lib3MFHandle, eClipMode ELib3MFBeamLatticeClipMode, nUniqueResourceID uint32) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetClipping(BeamLattice Lib3MFHandle, eClipMode ELib3MFBeamLatticeClipMode, nUniqueResourceID uint32) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setclipping, implementation_beamlattice.GetDLLInHandle(), uintptr(eClipMode), UInt32InValue(nUniqueResourceID)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -4427,33 +4474,33 @@ func (implementation *Lib3MFImplementation) BeamLattice_GetRepresentation(BeamLa var err error = nil var bHasRepresentation int64 = 0 var nUniqueResourceID uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return false, 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getrepresentation, implementation_beamlattice.GetDLLInHandle(), Int64OutValue(&bHasRepresentation), UInt32OutValue(&nUniqueResourceID)) - if (err != nil) { + if err != nil { return false, 0, err } - + return (bHasRepresentation != 0), uint32(nUniqueResourceID), err } -func (implementation *Lib3MFImplementation) BeamLattice_SetRepresentation(BeamLattice Lib3MFHandle, nUniqueResourceID uint32) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetRepresentation(BeamLattice Lib3MFHandle, nUniqueResourceID uint32) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setrepresentation, implementation_beamlattice.GetDLLInHandle(), UInt32InValue(nUniqueResourceID)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -4461,326 +4508,326 @@ func (implementation *Lib3MFImplementation) BeamLattice_GetBallOptions(BeamLatti var err error = nil var eBallMode uint64 = 0 var dBallRadius float64 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getballoptions, implementation_beamlattice.GetDLLInHandle(), UInt64OutValue(&eBallMode), Float64OutValue(&dBallRadius)) - if (err != nil) { + if err != nil { return 0, 0, err } - - return ELib3MFBeamLatticeBallMode (eBallMode), dBallRadius, err + + return ELib3MFBeamLatticeBallMode(eBallMode), dBallRadius, err } -func (implementation *Lib3MFImplementation) BeamLattice_SetBallOptions(BeamLattice Lib3MFHandle, eBallMode ELib3MFBeamLatticeBallMode, dBallRadius float64) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetBallOptions(BeamLattice Lib3MFHandle, eBallMode ELib3MFBeamLatticeBallMode, dBallRadius float64) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setballoptions, implementation_beamlattice.GetDLLInHandle(), uintptr(eBallMode), Float64InValue(dBallRadius)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BeamLattice_GetBeamCount(BeamLattice Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getbeamcount, implementation_beamlattice.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } func (implementation *Lib3MFImplementation) BeamLattice_GetBeam(BeamLattice Lib3MFHandle, nIndex uint32) (sLib3MFBeam, error) { var err error = nil var sBeamInfo sLib3MFBeam - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return sBeamInfo, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getbeam, implementation_beamlattice.GetDLLInHandle(), UInt32InValue(nIndex), 0) - if (err != nil) { + if err != nil { return sBeamInfo, err } - + return sBeamInfo, err } func (implementation *Lib3MFImplementation) BeamLattice_AddBeam(BeamLattice Lib3MFHandle, sBeamInfo sLib3MFBeam) (uint32, error) { var err error = nil var nIndex uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_addbeam, implementation_beamlattice.GetDLLInHandle(), uintptr(unsafe.Pointer(&sBeamInfo)), UInt32OutValue(&nIndex)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nIndex), err } -func (implementation *Lib3MFImplementation) BeamLattice_SetBeam(BeamLattice Lib3MFHandle, nIndex uint32, sBeamInfo sLib3MFBeam) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetBeam(BeamLattice Lib3MFHandle, nIndex uint32, sBeamInfo sLib3MFBeam) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setbeam, implementation_beamlattice.GetDLLInHandle(), UInt32InValue(nIndex), uintptr(unsafe.Pointer(&sBeamInfo))) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) BeamLattice_SetBeams(BeamLattice Lib3MFHandle, BeamInfo []sLib3MFBeam) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetBeams(BeamLattice Lib3MFHandle, BeamInfo []sLib3MFBeam) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setbeams, implementation_beamlattice.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BeamLattice_GetBeams(BeamLattice Lib3MFHandle) ([]sLib3MFBeam, error) { var err error = nil arrayBeamInfo := make([]sLib3MFBeam, 0) - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return make([]sLib3MFBeam, 0), err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getbeams, implementation_beamlattice.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFBeam, 0), err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getbeams, implementation_beamlattice.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFBeam, 0), err } - + return arrayBeamInfo, err } func (implementation *Lib3MFImplementation) BeamLattice_GetBallCount(BeamLattice Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getballcount, implementation_beamlattice.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } func (implementation *Lib3MFImplementation) BeamLattice_GetBall(BeamLattice Lib3MFHandle, nIndex uint32) (sLib3MFBall, error) { var err error = nil var sBallInfo sLib3MFBall - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return sBallInfo, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getball, implementation_beamlattice.GetDLLInHandle(), UInt32InValue(nIndex), 0) - if (err != nil) { + if err != nil { return sBallInfo, err } - + return sBallInfo, err } func (implementation *Lib3MFImplementation) BeamLattice_AddBall(BeamLattice Lib3MFHandle, sBallInfo sLib3MFBall) (uint32, error) { var err error = nil var nIndex uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_addball, implementation_beamlattice.GetDLLInHandle(), uintptr(unsafe.Pointer(&sBallInfo)), UInt32OutValue(&nIndex)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nIndex), err } -func (implementation *Lib3MFImplementation) BeamLattice_SetBall(BeamLattice Lib3MFHandle, nIndex uint32, sBallInfo sLib3MFBall) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetBall(BeamLattice Lib3MFHandle, nIndex uint32, sBallInfo sLib3MFBall) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setball, implementation_beamlattice.GetDLLInHandle(), UInt32InValue(nIndex), uintptr(unsafe.Pointer(&sBallInfo))) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) BeamLattice_SetBalls(BeamLattice Lib3MFHandle, BallInfo []sLib3MFBall) (error) { +func (implementation *Lib3MFImplementation) BeamLattice_SetBalls(BeamLattice Lib3MFHandle, BallInfo []sLib3MFBall) error { var err error = nil - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_setballs, implementation_beamlattice.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BeamLattice_GetBalls(BeamLattice Lib3MFHandle) ([]sLib3MFBall, error) { var err error = nil arrayBallInfo := make([]sLib3MFBall, 0) - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return make([]sLib3MFBall, 0), err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getballs, implementation_beamlattice.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFBall, 0), err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getballs, implementation_beamlattice.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFBall, 0), err } - + return arrayBallInfo, err } func (implementation *Lib3MFImplementation) BeamLattice_GetBeamSetCount(BeamLattice Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getbeamsetcount, implementation_beamlattice.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } func (implementation *Lib3MFImplementation) BeamLattice_AddBeamSet(BeamLattice Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hBeamSet := implementation.NewHandle() - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return hBeamSet, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_addbeamset, implementation_beamlattice.GetDLLInHandle(), hBeamSet.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBeamSet, err } - + return hBeamSet, err } func (implementation *Lib3MFImplementation) BeamLattice_GetBeamSet(BeamLattice Lib3MFHandle, nIndex uint32) (Lib3MFHandle, error) { var err error = nil hBeamSet := implementation.NewHandle() - + implementation_beamlattice, err := implementation.GetWrapperHandle(BeamLattice) - if (err != nil) { + if err != nil { return hBeamSet, err } err = implementation.CallFunction(implementation.Lib3MF_beamlattice_getbeamset, implementation_beamlattice.GetDLLInHandle(), UInt32InValue(nIndex), hBeamSet.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBeamSet, err } - + return hBeamSet, err } func (implementation *Lib3MFImplementation) Component_GetObjectResource(Component Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hObjectResource := implementation.NewHandle() - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return hObjectResource, err } err = implementation.CallFunction(implementation.Lib3MF_component_getobjectresource, implementation_component.GetDLLInHandle(), hObjectResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hObjectResource, err } - + return hObjectResource, err } func (implementation *Lib3MFImplementation) Component_GetObjectResourceID(Component Lib3MFHandle) (uint32, error) { var err error = nil var nUniqueResourceID uint32 = 0 - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_component_getobjectresourceid, implementation_component.GetDLLInHandle(), UInt32OutValue(&nUniqueResourceID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nUniqueResourceID), err } @@ -4789,166 +4836,166 @@ func (implementation *Lib3MFImplementation) Component_GetUUID(Component Lib3MFHa var bHasUUID int64 = 0 var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return false, "", err } err = implementation.CallFunction(implementation.Lib3MF_component_getuuid, implementation_component.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_component_getuuid, implementation_component.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasUUID != 0), string(bufferUUID[:(filledinUUID-1)]), err + + return (bHasUUID != 0), string(bufferUUID[:(filledinUUID - 1)]), err } -func (implementation *Lib3MFImplementation) Component_SetUUID(Component Lib3MFHandle, sUUID string) (error) { +func (implementation *Lib3MFImplementation) Component_SetUUID(Component Lib3MFHandle, sUUID string) error { var err error = nil - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_component_setuuid, implementation_component.GetDLLInHandle(), StringInValue(sUUID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Component_HasTransform(Component Lib3MFHandle) (bool, error) { var err error = nil var bHasTransform int64 = 0 - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_component_hastransform, implementation_component.GetDLLInHandle(), Int64OutValue(&bHasTransform)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasTransform != 0), err } func (implementation *Lib3MFImplementation) Component_GetTransform(Component Lib3MFHandle) (sLib3MFTransform, error) { var err error = nil var sTransform sLib3MFTransform - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return sTransform, err } err = implementation.CallFunction(implementation.Lib3MF_component_gettransform, implementation_component.GetDLLInHandle(), 0) - if (err != nil) { + if err != nil { return sTransform, err } - + return sTransform, err } -func (implementation *Lib3MFImplementation) Component_SetTransform(Component Lib3MFHandle, sTransform sLib3MFTransform) (error) { +func (implementation *Lib3MFImplementation) Component_SetTransform(Component Lib3MFHandle, sTransform sLib3MFTransform) error { var err error = nil - + implementation_component, err := implementation.GetWrapperHandle(Component) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_component_settransform, implementation_component.GetDLLInHandle(), uintptr(unsafe.Pointer(&sTransform))) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) ComponentsObject_AddComponent(ComponentsObject Lib3MFHandle, ObjectResource Lib3MFHandle, sTransform sLib3MFTransform) (Lib3MFHandle, error) { var err error = nil hComponentInstance := implementation.NewHandle() - + implementation_componentsobject, err := implementation.GetWrapperHandle(ComponentsObject) - if (err != nil) { + if err != nil { return hComponentInstance, err } implementation_objectresource, err := implementation.GetWrapperHandle(ObjectResource) - if (err != nil) { + if err != nil { return hComponentInstance, err } - + ObjectResourceDLLHandle := implementation_objectresource.GetDLLInHandle() - if (ObjectResourceDLLHandle == 0) { + if ObjectResourceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hComponentInstance, err } err = implementation.CallFunction(implementation.Lib3MF_componentsobject_addcomponent, implementation_componentsobject.GetDLLInHandle(), ObjectResourceDLLHandle, uintptr(unsafe.Pointer(&sTransform)), hComponentInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hComponentInstance, err } - + return hComponentInstance, err } func (implementation *Lib3MFImplementation) ComponentsObject_GetComponent(ComponentsObject Lib3MFHandle, nIndex uint32) (Lib3MFHandle, error) { var err error = nil hComponentInstance := implementation.NewHandle() - + implementation_componentsobject, err := implementation.GetWrapperHandle(ComponentsObject) - if (err != nil) { + if err != nil { return hComponentInstance, err } err = implementation.CallFunction(implementation.Lib3MF_componentsobject_getcomponent, implementation_componentsobject.GetDLLInHandle(), UInt32InValue(nIndex), hComponentInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hComponentInstance, err } - + return hComponentInstance, err } func (implementation *Lib3MFImplementation) ComponentsObject_GetComponentCount(ComponentsObject Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_componentsobject, err := implementation.GetWrapperHandle(ComponentsObject) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_componentsobject_getcomponentcount, implementation_componentsobject.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } -func (implementation *Lib3MFImplementation) BeamSet_SetName(BeamSet Lib3MFHandle, sName string) (error) { +func (implementation *Lib3MFImplementation) BeamSet_SetName(BeamSet Lib3MFHandle, sName string) error { var err error = nil - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamset_setname, implementation_beamset.GetDLLInHandle(), StringInValue(sName)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -4956,39 +5003,39 @@ func (implementation *Lib3MFImplementation) BeamSet_GetName(BeamSet Lib3MFHandle var err error = nil var neededforName int64 = 0 var filledinName int64 = 0 - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_beamset_getname, implementation_beamset.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforName), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeName := neededforName bufferName := make([]byte, bufferSizeName) err = implementation.CallFunction(implementation.Lib3MF_beamset_getname, implementation_beamset.GetDLLInHandle(), Int64InValue(bufferSizeName), Int64OutValue(&filledinName), uintptr(unsafe.Pointer(&bufferName[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferName[:(filledinName-1)]), err + + return string(bufferName[:(filledinName - 1)]), err } -func (implementation *Lib3MFImplementation) BeamSet_SetIdentifier(BeamSet Lib3MFHandle, sIdentifier string) (error) { +func (implementation *Lib3MFImplementation) BeamSet_SetIdentifier(BeamSet Lib3MFHandle, sIdentifier string) error { var err error = nil - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamset_setidentifier, implementation_beamset.GetDLLInHandle(), StringInValue(sIdentifier)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -4996,56 +5043,56 @@ func (implementation *Lib3MFImplementation) BeamSet_GetIdentifier(BeamSet Lib3MF var err error = nil var neededforIdentifier int64 = 0 var filledinIdentifier int64 = 0 - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_beamset_getidentifier, implementation_beamset.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforIdentifier), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeIdentifier := neededforIdentifier bufferIdentifier := make([]byte, bufferSizeIdentifier) err = implementation.CallFunction(implementation.Lib3MF_beamset_getidentifier, implementation_beamset.GetDLLInHandle(), Int64InValue(bufferSizeIdentifier), Int64OutValue(&filledinIdentifier), uintptr(unsafe.Pointer(&bufferIdentifier[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferIdentifier[:(filledinIdentifier-1)]), err + + return string(bufferIdentifier[:(filledinIdentifier - 1)]), err } func (implementation *Lib3MFImplementation) BeamSet_GetReferenceCount(BeamSet Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamset_getreferencecount, implementation_beamset.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } -func (implementation *Lib3MFImplementation) BeamSet_SetReferences(BeamSet Lib3MFHandle, References []uint32) (error) { +func (implementation *Lib3MFImplementation) BeamSet_SetReferences(BeamSet Lib3MFHandle, References []uint32) error { var err error = nil - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamset_setreferences, implementation_beamset.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } @@ -5054,56 +5101,56 @@ func (implementation *Lib3MFImplementation) BeamSet_GetReferences(BeamSet Lib3MF var neededforReferences int64 = 0 var filledinReferences int64 = 0 bufferReferences := make([]uint32, 0) - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_beamset_getreferences, implementation_beamset.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforReferences), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizeReferences := neededforReferences bufferReferences = make([]uint32, bufferSizeReferences) err = implementation.CallFunction(implementation.Lib3MF_beamset_getreferences, implementation_beamset.GetDLLInHandle(), Int64InValue(bufferSizeReferences), Int64OutValue(&filledinReferences), uintptr(unsafe.Pointer(&bufferReferences[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferReferences, err } func (implementation *Lib3MFImplementation) BeamSet_GetBallReferenceCount(BeamSet Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_beamset_getballreferencecount, implementation_beamset.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } -func (implementation *Lib3MFImplementation) BeamSet_SetBallReferences(BeamSet Lib3MFHandle, BallReferences []uint32) (error) { +func (implementation *Lib3MFImplementation) BeamSet_SetBallReferences(BeamSet Lib3MFHandle, BallReferences []uint32) error { var err error = nil - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_beamset_setballreferences, implementation_beamset.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } @@ -5112,40 +5159,40 @@ func (implementation *Lib3MFImplementation) BeamSet_GetBallReferences(BeamSet Li var neededforBallReferences int64 = 0 var filledinBallReferences int64 = 0 bufferBallReferences := make([]uint32, 0) - + implementation_beamset, err := implementation.GetWrapperHandle(BeamSet) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_beamset_getballreferences, implementation_beamset.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforBallReferences), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizeBallReferences := neededforBallReferences bufferBallReferences = make([]uint32, bufferSizeBallReferences) err = implementation.CallFunction(implementation.Lib3MF_beamset_getballreferences, implementation_beamset.GetDLLInHandle(), Int64InValue(bufferSizeBallReferences), Int64OutValue(&filledinBallReferences), uintptr(unsafe.Pointer(&bufferBallReferences[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferBallReferences, err } func (implementation *Lib3MFImplementation) BaseMaterialGroup_GetCount(BaseMaterialGroup Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_getcount, implementation_basematerialgroup.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } @@ -5154,56 +5201,56 @@ func (implementation *Lib3MFImplementation) BaseMaterialGroup_GetAllPropertyIDs( var neededforPropertyIDs int64 = 0 var filledinPropertyIDs int64 = 0 bufferPropertyIDs := make([]uint32, 0) - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_getallpropertyids, implementation_basematerialgroup.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPropertyIDs), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizePropertyIDs := neededforPropertyIDs bufferPropertyIDs = make([]uint32, bufferSizePropertyIDs) err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_getallpropertyids, implementation_basematerialgroup.GetDLLInHandle(), Int64InValue(bufferSizePropertyIDs), Int64OutValue(&filledinPropertyIDs), uintptr(unsafe.Pointer(&bufferPropertyIDs[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferPropertyIDs, err } func (implementation *Lib3MFImplementation) BaseMaterialGroup_AddMaterial(BaseMaterialGroup Lib3MFHandle, sName string, sDisplayColor sLib3MFColor) (uint32, error) { var err error = nil var nPropertyID uint32 = 0 - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_addmaterial, implementation_basematerialgroup.GetDLLInHandle(), StringInValue(sName), uintptr(unsafe.Pointer(&sDisplayColor)), UInt32OutValue(&nPropertyID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nPropertyID), err } -func (implementation *Lib3MFImplementation) BaseMaterialGroup_RemoveMaterial(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32) (error) { +func (implementation *Lib3MFImplementation) BaseMaterialGroup_RemoveMaterial(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32) error { var err error = nil - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_removematerial, implementation_basematerialgroup.GetDLLInHandle(), UInt32InValue(nPropertyID)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -5211,89 +5258,89 @@ func (implementation *Lib3MFImplementation) BaseMaterialGroup_GetName(BaseMateri var err error = nil var neededforName int64 = 0 var filledinName int64 = 0 - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_getname, implementation_basematerialgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), Int64InValue(0), Int64OutValue(&neededforName), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeName := neededforName bufferName := make([]byte, bufferSizeName) err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_getname, implementation_basematerialgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), Int64InValue(bufferSizeName), Int64OutValue(&filledinName), uintptr(unsafe.Pointer(&bufferName[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferName[:(filledinName-1)]), err + + return string(bufferName[:(filledinName - 1)]), err } -func (implementation *Lib3MFImplementation) BaseMaterialGroup_SetName(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32, sName string) (error) { +func (implementation *Lib3MFImplementation) BaseMaterialGroup_SetName(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32, sName string) error { var err error = nil - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_setname, implementation_basematerialgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), StringInValue(sName)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) BaseMaterialGroup_SetDisplayColor(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32, sTheColor sLib3MFColor) (error) { +func (implementation *Lib3MFImplementation) BaseMaterialGroup_SetDisplayColor(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32, sTheColor sLib3MFColor) error { var err error = nil - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_setdisplaycolor, implementation_basematerialgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), uintptr(unsafe.Pointer(&sTheColor))) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BaseMaterialGroup_GetDisplayColor(BaseMaterialGroup Lib3MFHandle, nPropertyID uint32) (sLib3MFColor, error) { var err error = nil var sTheColor sLib3MFColor - + implementation_basematerialgroup, err := implementation.GetWrapperHandle(BaseMaterialGroup) - if (err != nil) { + if err != nil { return sTheColor, err } err = implementation.CallFunction(implementation.Lib3MF_basematerialgroup_getdisplaycolor, implementation_basematerialgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), 0) - if (err != nil) { + if err != nil { return sTheColor, err } - + return sTheColor, err } func (implementation *Lib3MFImplementation) ColorGroup_GetCount(ColorGroup Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_colorgroup, err := implementation.GetWrapperHandle(ColorGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_colorgroup_getcount, implementation_colorgroup.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } @@ -5302,106 +5349,106 @@ func (implementation *Lib3MFImplementation) ColorGroup_GetAllPropertyIDs(ColorGr var neededforPropertyIDs int64 = 0 var filledinPropertyIDs int64 = 0 bufferPropertyIDs := make([]uint32, 0) - + implementation_colorgroup, err := implementation.GetWrapperHandle(ColorGroup) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_colorgroup_getallpropertyids, implementation_colorgroup.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPropertyIDs), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizePropertyIDs := neededforPropertyIDs bufferPropertyIDs = make([]uint32, bufferSizePropertyIDs) err = implementation.CallFunction(implementation.Lib3MF_colorgroup_getallpropertyids, implementation_colorgroup.GetDLLInHandle(), Int64InValue(bufferSizePropertyIDs), Int64OutValue(&filledinPropertyIDs), uintptr(unsafe.Pointer(&bufferPropertyIDs[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferPropertyIDs, err } func (implementation *Lib3MFImplementation) ColorGroup_AddColor(ColorGroup Lib3MFHandle, sTheColor sLib3MFColor) (uint32, error) { var err error = nil var nPropertyID uint32 = 0 - + implementation_colorgroup, err := implementation.GetWrapperHandle(ColorGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_colorgroup_addcolor, implementation_colorgroup.GetDLLInHandle(), uintptr(unsafe.Pointer(&sTheColor)), UInt32OutValue(&nPropertyID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nPropertyID), err } -func (implementation *Lib3MFImplementation) ColorGroup_RemoveColor(ColorGroup Lib3MFHandle, nPropertyID uint32) (error) { +func (implementation *Lib3MFImplementation) ColorGroup_RemoveColor(ColorGroup Lib3MFHandle, nPropertyID uint32) error { var err error = nil - + implementation_colorgroup, err := implementation.GetWrapperHandle(ColorGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_colorgroup_removecolor, implementation_colorgroup.GetDLLInHandle(), UInt32InValue(nPropertyID)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) ColorGroup_SetColor(ColorGroup Lib3MFHandle, nPropertyID uint32, sTheColor sLib3MFColor) (error) { +func (implementation *Lib3MFImplementation) ColorGroup_SetColor(ColorGroup Lib3MFHandle, nPropertyID uint32, sTheColor sLib3MFColor) error { var err error = nil - + implementation_colorgroup, err := implementation.GetWrapperHandle(ColorGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_colorgroup_setcolor, implementation_colorgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), uintptr(unsafe.Pointer(&sTheColor))) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) ColorGroup_GetColor(ColorGroup Lib3MFHandle, nPropertyID uint32) (sLib3MFColor, error) { var err error = nil var sTheColor sLib3MFColor - + implementation_colorgroup, err := implementation.GetWrapperHandle(ColorGroup) - if (err != nil) { + if err != nil { return sTheColor, err } err = implementation.CallFunction(implementation.Lib3MF_colorgroup_getcolor, implementation_colorgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), 0) - if (err != nil) { + if err != nil { return sTheColor, err } - + return sTheColor, err } func (implementation *Lib3MFImplementation) Texture2DGroup_GetCount(Texture2DGroup Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_texture2dgroup, err := implementation.GetWrapperHandle(Texture2DGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_getcount, implementation_texture2dgroup.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } @@ -5410,107 +5457,107 @@ func (implementation *Lib3MFImplementation) Texture2DGroup_GetAllPropertyIDs(Tex var neededforPropertyIDs int64 = 0 var filledinPropertyIDs int64 = 0 bufferPropertyIDs := make([]uint32, 0) - + implementation_texture2dgroup, err := implementation.GetWrapperHandle(Texture2DGroup) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_getallpropertyids, implementation_texture2dgroup.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPropertyIDs), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizePropertyIDs := neededforPropertyIDs bufferPropertyIDs = make([]uint32, bufferSizePropertyIDs) err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_getallpropertyids, implementation_texture2dgroup.GetDLLInHandle(), Int64InValue(bufferSizePropertyIDs), Int64OutValue(&filledinPropertyIDs), uintptr(unsafe.Pointer(&bufferPropertyIDs[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferPropertyIDs, err } func (implementation *Lib3MFImplementation) Texture2DGroup_AddTex2Coord(Texture2DGroup Lib3MFHandle, sUVCoordinate sLib3MFTex2Coord) (uint32, error) { var err error = nil var nPropertyID uint32 = 0 - + implementation_texture2dgroup, err := implementation.GetWrapperHandle(Texture2DGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_addtex2coord, implementation_texture2dgroup.GetDLLInHandle(), uintptr(unsafe.Pointer(&sUVCoordinate)), UInt32OutValue(&nPropertyID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nPropertyID), err } func (implementation *Lib3MFImplementation) Texture2DGroup_GetTex2Coord(Texture2DGroup Lib3MFHandle, nPropertyID uint32) (sLib3MFTex2Coord, error) { var err error = nil var sUVCoordinate sLib3MFTex2Coord - + implementation_texture2dgroup, err := implementation.GetWrapperHandle(Texture2DGroup) - if (err != nil) { + if err != nil { return sUVCoordinate, err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_gettex2coord, implementation_texture2dgroup.GetDLLInHandle(), UInt32InValue(nPropertyID), 0) - if (err != nil) { + if err != nil { return sUVCoordinate, err } - + return sUVCoordinate, err } -func (implementation *Lib3MFImplementation) Texture2DGroup_RemoveTex2Coord(Texture2DGroup Lib3MFHandle, nPropertyID uint32) (error) { +func (implementation *Lib3MFImplementation) Texture2DGroup_RemoveTex2Coord(Texture2DGroup Lib3MFHandle, nPropertyID uint32) error { var err error = nil - + implementation_texture2dgroup, err := implementation.GetWrapperHandle(Texture2DGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_removetex2coord, implementation_texture2dgroup.GetDLLInHandle(), UInt32InValue(nPropertyID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Texture2DGroup_GetTexture2D(Texture2DGroup Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hTexture2DInstance := implementation.NewHandle() - + implementation_texture2dgroup, err := implementation.GetWrapperHandle(Texture2DGroup) - if (err != nil) { + if err != nil { return hTexture2DInstance, err } err = implementation.CallFunction(implementation.Lib3MF_texture2dgroup_gettexture2d, implementation_texture2dgroup.GetDLLInHandle(), hTexture2DInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTexture2DInstance, err } - + return hTexture2DInstance, err } func (implementation *Lib3MFImplementation) CompositeMaterials_GetCount(CompositeMaterials Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_compositematerials, err := implementation.GetWrapperHandle(CompositeMaterials) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_getcount, implementation_compositematerials.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } @@ -5519,111 +5566,111 @@ func (implementation *Lib3MFImplementation) CompositeMaterials_GetAllPropertyIDs var neededforPropertyIDs int64 = 0 var filledinPropertyIDs int64 = 0 bufferPropertyIDs := make([]uint32, 0) - + implementation_compositematerials, err := implementation.GetWrapperHandle(CompositeMaterials) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_getallpropertyids, implementation_compositematerials.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPropertyIDs), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizePropertyIDs := neededforPropertyIDs bufferPropertyIDs = make([]uint32, bufferSizePropertyIDs) err = implementation.CallFunction(implementation.Lib3MF_compositematerials_getallpropertyids, implementation_compositematerials.GetDLLInHandle(), Int64InValue(bufferSizePropertyIDs), Int64OutValue(&filledinPropertyIDs), uintptr(unsafe.Pointer(&bufferPropertyIDs[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferPropertyIDs, err } func (implementation *Lib3MFImplementation) CompositeMaterials_GetBaseMaterialGroup(CompositeMaterials Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hBaseMaterialGroupInstance := implementation.NewHandle() - + implementation_compositematerials, err := implementation.GetWrapperHandle(CompositeMaterials) - if (err != nil) { + if err != nil { return hBaseMaterialGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_getbasematerialgroup, implementation_compositematerials.GetDLLInHandle(), hBaseMaterialGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBaseMaterialGroupInstance, err } - + return hBaseMaterialGroupInstance, err } func (implementation *Lib3MFImplementation) CompositeMaterials_AddComposite(CompositeMaterials Lib3MFHandle, Composite []sLib3MFCompositeConstituent) (uint32, error) { var err error = nil var nPropertyID uint32 = 0 - + implementation_compositematerials, err := implementation.GetWrapperHandle(CompositeMaterials) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_addcomposite, implementation_compositematerials.GetDLLInHandle(), 0, 0, UInt32OutValue(&nPropertyID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nPropertyID), err } -func (implementation *Lib3MFImplementation) CompositeMaterials_RemoveComposite(CompositeMaterials Lib3MFHandle, nPropertyID uint32) (error) { +func (implementation *Lib3MFImplementation) CompositeMaterials_RemoveComposite(CompositeMaterials Lib3MFHandle, nPropertyID uint32) error { var err error = nil - + implementation_compositematerials, err := implementation.GetWrapperHandle(CompositeMaterials) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_removecomposite, implementation_compositematerials.GetDLLInHandle(), UInt32InValue(nPropertyID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) CompositeMaterials_GetComposite(CompositeMaterials Lib3MFHandle, nPropertyID uint32) ([]sLib3MFCompositeConstituent, error) { var err error = nil arrayComposite := make([]sLib3MFCompositeConstituent, 0) - + implementation_compositematerials, err := implementation.GetWrapperHandle(CompositeMaterials) - if (err != nil) { + if err != nil { return make([]sLib3MFCompositeConstituent, 0), err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_getcomposite, implementation_compositematerials.GetDLLInHandle(), UInt32InValue(nPropertyID), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFCompositeConstituent, 0), err } err = implementation.CallFunction(implementation.Lib3MF_compositematerials_getcomposite, implementation_compositematerials.GetDLLInHandle(), UInt32InValue(nPropertyID), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFCompositeConstituent, 0), err } - + return arrayComposite, err } func (implementation *Lib3MFImplementation) MultiPropertyGroup_GetCount(MultiPropertyGroup Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getcount, implementation_multipropertygroup.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } @@ -5632,56 +5679,56 @@ func (implementation *Lib3MFImplementation) MultiPropertyGroup_GetAllPropertyIDs var neededforPropertyIDs int64 = 0 var filledinPropertyIDs int64 = 0 bufferPropertyIDs := make([]uint32, 0) - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getallpropertyids, implementation_multipropertygroup.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPropertyIDs), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizePropertyIDs := neededforPropertyIDs bufferPropertyIDs = make([]uint32, bufferSizePropertyIDs) err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getallpropertyids, implementation_multipropertygroup.GetDLLInHandle(), Int64InValue(bufferSizePropertyIDs), Int64OutValue(&filledinPropertyIDs), uintptr(unsafe.Pointer(&bufferPropertyIDs[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferPropertyIDs, err } func (implementation *Lib3MFImplementation) MultiPropertyGroup_AddMultiProperty(MultiPropertyGroup Lib3MFHandle, PropertyIDs []uint32) (uint32, error) { var err error = nil var nPropertyID uint32 = 0 - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_addmultiproperty, implementation_multipropertygroup.GetDLLInHandle(), 0, 0, UInt32OutValue(&nPropertyID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nPropertyID), err } -func (implementation *Lib3MFImplementation) MultiPropertyGroup_SetMultiProperty(MultiPropertyGroup Lib3MFHandle, nPropertyID uint32, PropertyIDs []uint32) (error) { +func (implementation *Lib3MFImplementation) MultiPropertyGroup_SetMultiProperty(MultiPropertyGroup Lib3MFHandle, nPropertyID uint32, PropertyIDs []uint32) error { var err error = nil - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_setmultiproperty, implementation_multipropertygroup.GetDLLInHandle(), UInt32InValue(nPropertyID), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } @@ -5690,106 +5737,106 @@ func (implementation *Lib3MFImplementation) MultiPropertyGroup_GetMultiProperty( var neededforPropertyIDs int64 = 0 var filledinPropertyIDs int64 = 0 bufferPropertyIDs := make([]uint32, 0) - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getmultiproperty, implementation_multipropertygroup.GetDLLInHandle(), UInt32InValue(nPropertyID), Int64InValue(0), Int64OutValue(&neededforPropertyIDs), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizePropertyIDs := neededforPropertyIDs bufferPropertyIDs = make([]uint32, bufferSizePropertyIDs) err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getmultiproperty, implementation_multipropertygroup.GetDLLInHandle(), UInt32InValue(nPropertyID), Int64InValue(bufferSizePropertyIDs), Int64OutValue(&filledinPropertyIDs), uintptr(unsafe.Pointer(&bufferPropertyIDs[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferPropertyIDs, err } -func (implementation *Lib3MFImplementation) MultiPropertyGroup_RemoveMultiProperty(MultiPropertyGroup Lib3MFHandle, nPropertyID uint32) (error) { +func (implementation *Lib3MFImplementation) MultiPropertyGroup_RemoveMultiProperty(MultiPropertyGroup Lib3MFHandle, nPropertyID uint32) error { var err error = nil - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_removemultiproperty, implementation_multipropertygroup.GetDLLInHandle(), UInt32InValue(nPropertyID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) MultiPropertyGroup_GetLayerCount(MultiPropertyGroup Lib3MFHandle) (uint32, error) { var err error = nil var nCount uint32 = 0 - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getlayercount, implementation_multipropertygroup.GetDLLInHandle(), UInt32OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nCount), err } func (implementation *Lib3MFImplementation) MultiPropertyGroup_AddLayer(MultiPropertyGroup Lib3MFHandle, sTheLayer sLib3MFMultiPropertyLayer) (uint32, error) { var err error = nil var nLayerIndex uint32 = 0 - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_addlayer, implementation_multipropertygroup.GetDLLInHandle(), uintptr(unsafe.Pointer(&sTheLayer)), UInt32OutValue(&nLayerIndex)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nLayerIndex), err } func (implementation *Lib3MFImplementation) MultiPropertyGroup_GetLayer(MultiPropertyGroup Lib3MFHandle, nLayerIndex uint32) (sLib3MFMultiPropertyLayer, error) { var err error = nil var sTheLayer sLib3MFMultiPropertyLayer - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return sTheLayer, err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_getlayer, implementation_multipropertygroup.GetDLLInHandle(), UInt32InValue(nLayerIndex), 0) - if (err != nil) { + if err != nil { return sTheLayer, err } - + return sTheLayer, err } -func (implementation *Lib3MFImplementation) MultiPropertyGroup_RemoveLayer(MultiPropertyGroup Lib3MFHandle, nLayerIndex uint32) (error) { +func (implementation *Lib3MFImplementation) MultiPropertyGroup_RemoveLayer(MultiPropertyGroup Lib3MFHandle, nLayerIndex uint32) error { var err error = nil - + implementation_multipropertygroup, err := implementation.GetWrapperHandle(MultiPropertyGroup) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_multipropertygroup_removelayer, implementation_multipropertygroup.GetDLLInHandle(), UInt32InValue(nLayerIndex)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -5797,56 +5844,56 @@ func (implementation *Lib3MFImplementation) Attachment_GetPath(Attachment Lib3MF var err error = nil var neededforPath int64 = 0 var filledinPath int64 = 0 - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_attachment_getpath, implementation_attachment.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPath), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizePath := neededforPath bufferPath := make([]byte, bufferSizePath) err = implementation.CallFunction(implementation.Lib3MF_attachment_getpath, implementation_attachment.GetDLLInHandle(), Int64InValue(bufferSizePath), Int64OutValue(&filledinPath), uintptr(unsafe.Pointer(&bufferPath[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferPath[:(filledinPath-1)]), err + + return string(bufferPath[:(filledinPath - 1)]), err } -func (implementation *Lib3MFImplementation) Attachment_SetPath(Attachment Lib3MFHandle, sPath string) (error) { +func (implementation *Lib3MFImplementation) Attachment_SetPath(Attachment Lib3MFHandle, sPath string) error { var err error = nil - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_attachment_setpath, implementation_attachment.GetDLLInHandle(), StringInValue(sPath)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Attachment_PackagePart(Attachment Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hPackagePart := implementation.NewHandle() - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return hPackagePart, err } err = implementation.CallFunction(implementation.Lib3MF_attachment_packagepart, implementation_attachment.GetDLLInHandle(), hPackagePart.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hPackagePart, err } - + return hPackagePart, err } @@ -5854,104 +5901,104 @@ func (implementation *Lib3MFImplementation) Attachment_GetRelationShipType(Attac var err error = nil var neededforPath int64 = 0 var filledinPath int64 = 0 - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_attachment_getrelationshiptype, implementation_attachment.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPath), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizePath := neededforPath bufferPath := make([]byte, bufferSizePath) err = implementation.CallFunction(implementation.Lib3MF_attachment_getrelationshiptype, implementation_attachment.GetDLLInHandle(), Int64InValue(bufferSizePath), Int64OutValue(&filledinPath), uintptr(unsafe.Pointer(&bufferPath[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferPath[:(filledinPath-1)]), err + + return string(bufferPath[:(filledinPath - 1)]), err } -func (implementation *Lib3MFImplementation) Attachment_SetRelationShipType(Attachment Lib3MFHandle, sPath string) (error) { +func (implementation *Lib3MFImplementation) Attachment_SetRelationShipType(Attachment Lib3MFHandle, sPath string) error { var err error = nil - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_attachment_setrelationshiptype, implementation_attachment.GetDLLInHandle(), StringInValue(sPath)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Attachment_WriteToFile(Attachment Lib3MFHandle, sFileName string) (error) { +func (implementation *Lib3MFImplementation) Attachment_WriteToFile(Attachment Lib3MFHandle, sFileName string) error { var err error = nil - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_attachment_writetofile, implementation_attachment.GetDLLInHandle(), StringInValue(sFileName)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Attachment_ReadFromFile(Attachment Lib3MFHandle, sFileName string) (error) { +func (implementation *Lib3MFImplementation) Attachment_ReadFromFile(Attachment Lib3MFHandle, sFileName string) error { var err error = nil - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_attachment_readfromfile, implementation_attachment.GetDLLInHandle(), StringInValue(sFileName)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Attachment_ReadFromCallback(Attachment Lib3MFHandle, pTheReadCallback int64, nStreamSize uint64, pTheSeekCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Attachment_ReadFromCallback(Attachment Lib3MFHandle, pTheReadCallback int64, nStreamSize uint64, pTheSeekCallback int64, nUserData uint64) error { var err error = nil - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_attachment_readfromcallback, implementation_attachment.GetDLLInHandle(), 0, UInt64InValue(nStreamSize), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Attachment_GetStreamSize(Attachment Lib3MFHandle) (uint64, error) { var err error = nil var nStreamSize uint64 = 0 - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_attachment_getstreamsize, implementation_attachment.GetDLLInHandle(), UInt64OutValue(&nStreamSize)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nStreamSize), err } @@ -5960,115 +6007,115 @@ func (implementation *Lib3MFImplementation) Attachment_WriteToBuffer(Attachment var neededforBuffer int64 = 0 var filledinBuffer int64 = 0 bufferBuffer := make([]uint8, 0) - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_attachment_writetobuffer, implementation_attachment.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforBuffer), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeBuffer := neededforBuffer bufferBuffer = make([]uint8, bufferSizeBuffer) err = implementation.CallFunction(implementation.Lib3MF_attachment_writetobuffer, implementation_attachment.GetDLLInHandle(), Int64InValue(bufferSizeBuffer), Int64OutValue(&filledinBuffer), uintptr(unsafe.Pointer(&bufferBuffer[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferBuffer, err } -func (implementation *Lib3MFImplementation) Attachment_ReadFromBuffer(Attachment Lib3MFHandle, Buffer []uint8) (error) { +func (implementation *Lib3MFImplementation) Attachment_ReadFromBuffer(Attachment Lib3MFHandle, Buffer []uint8) error { var err error = nil - + implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_attachment_readfrombuffer, implementation_attachment.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Texture2D_GetAttachment(Texture2D Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hAttachment := implementation.NewHandle() - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return hAttachment, err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_getattachment, implementation_texture2d.GetDLLInHandle(), hAttachment.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachment, err } - + return hAttachment, err } -func (implementation *Lib3MFImplementation) Texture2D_SetAttachment(Texture2D Lib3MFHandle, Attachment Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Texture2D_SetAttachment(Texture2D Lib3MFHandle, Attachment Lib3MFHandle) error { var err error = nil - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return err } implementation_attachment, err := implementation.GetWrapperHandle(Attachment) - if (err != nil) { + if err != nil { return err } - + AttachmentDLLHandle := implementation_attachment.GetDLLInHandle() - if (AttachmentDLLHandle == 0) { + if AttachmentDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_setattachment, implementation_texture2d.GetDLLInHandle(), AttachmentDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Texture2D_GetContentType(Texture2D Lib3MFHandle) (ELib3MFTextureType, error) { var err error = nil var eContentType uint64 = 0 - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_getcontenttype, implementation_texture2d.GetDLLInHandle(), UInt64OutValue(&eContentType)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFTextureType (eContentType), err + + return ELib3MFTextureType(eContentType), err } -func (implementation *Lib3MFImplementation) Texture2D_SetContentType(Texture2D Lib3MFHandle, eContentType ELib3MFTextureType) (error) { +func (implementation *Lib3MFImplementation) Texture2D_SetContentType(Texture2D Lib3MFHandle, eContentType ELib3MFTextureType) error { var err error = nil - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_setcontenttype, implementation_texture2d.GetDLLInHandle(), uintptr(eContentType)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -6076,83 +6123,83 @@ func (implementation *Lib3MFImplementation) Texture2D_GetTileStyleUV(Texture2D L var err error = nil var eTileStyleU uint64 = 0 var eTileStyleV uint64 = 0 - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return 0, 0, err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_gettilestyleuv, implementation_texture2d.GetDLLInHandle(), UInt64OutValue(&eTileStyleU), UInt64OutValue(&eTileStyleV)) - if (err != nil) { + if err != nil { return 0, 0, err } - - return ELib3MFTextureTileStyle (eTileStyleU), ELib3MFTextureTileStyle (eTileStyleV), err + + return ELib3MFTextureTileStyle(eTileStyleU), ELib3MFTextureTileStyle(eTileStyleV), err } -func (implementation *Lib3MFImplementation) Texture2D_SetTileStyleUV(Texture2D Lib3MFHandle, eTileStyleU ELib3MFTextureTileStyle, eTileStyleV ELib3MFTextureTileStyle) (error) { +func (implementation *Lib3MFImplementation) Texture2D_SetTileStyleUV(Texture2D Lib3MFHandle, eTileStyleU ELib3MFTextureTileStyle, eTileStyleV ELib3MFTextureTileStyle) error { var err error = nil - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_settilestyleuv, implementation_texture2d.GetDLLInHandle(), uintptr(eTileStyleU), uintptr(eTileStyleV)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Texture2D_GetFilter(Texture2D Lib3MFHandle) (ELib3MFTextureFilter, error) { var err error = nil var eFilter uint64 = 0 - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_getfilter, implementation_texture2d.GetDLLInHandle(), UInt64OutValue(&eFilter)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFTextureFilter (eFilter), err + + return ELib3MFTextureFilter(eFilter), err } -func (implementation *Lib3MFImplementation) Texture2D_SetFilter(Texture2D Lib3MFHandle, eFilter ELib3MFTextureFilter) (error) { +func (implementation *Lib3MFImplementation) Texture2D_SetFilter(Texture2D Lib3MFHandle, eFilter ELib3MFTextureFilter) error { var err error = nil - + implementation_texture2d, err := implementation.GetWrapperHandle(Texture2D) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_texture2d_setfilter, implementation_texture2d.GetDLLInHandle(), uintptr(eFilter)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BuildItem_GetObjectResource(BuildItem Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hObjectResource := implementation.NewHandle() - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return hObjectResource, err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getobjectresource, implementation_builditem.GetDLLInHandle(), hObjectResource.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hObjectResource, err } - + return hObjectResource, err } @@ -6161,106 +6208,106 @@ func (implementation *Lib3MFImplementation) BuildItem_GetUUID(BuildItem Lib3MFHa var bHasUUID int64 = 0 var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return false, "", err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getuuid, implementation_builditem.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_builditem_getuuid, implementation_builditem.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasUUID != 0), string(bufferUUID[:(filledinUUID-1)]), err + + return (bHasUUID != 0), string(bufferUUID[:(filledinUUID - 1)]), err } -func (implementation *Lib3MFImplementation) BuildItem_SetUUID(BuildItem Lib3MFHandle, sUUID string) (error) { +func (implementation *Lib3MFImplementation) BuildItem_SetUUID(BuildItem Lib3MFHandle, sUUID string) error { var err error = nil - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_builditem_setuuid, implementation_builditem.GetDLLInHandle(), StringInValue(sUUID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BuildItem_GetObjectResourceID(BuildItem Lib3MFHandle) (uint32, error) { var err error = nil var nUniqueResourceID uint32 = 0 - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getobjectresourceid, implementation_builditem.GetDLLInHandle(), UInt32OutValue(&nUniqueResourceID)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nUniqueResourceID), err } func (implementation *Lib3MFImplementation) BuildItem_HasObjectTransform(BuildItem Lib3MFHandle) (bool, error) { var err error = nil var bHasTransform int64 = 0 - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_builditem_hasobjecttransform, implementation_builditem.GetDLLInHandle(), Int64OutValue(&bHasTransform)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasTransform != 0), err } func (implementation *Lib3MFImplementation) BuildItem_GetObjectTransform(BuildItem Lib3MFHandle) (sLib3MFTransform, error) { var err error = nil var sTransform sLib3MFTransform - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return sTransform, err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getobjecttransform, implementation_builditem.GetDLLInHandle(), 0) - if (err != nil) { + if err != nil { return sTransform, err } - + return sTransform, err } -func (implementation *Lib3MFImplementation) BuildItem_SetObjectTransform(BuildItem Lib3MFHandle, sTransform sLib3MFTransform) (error) { +func (implementation *Lib3MFImplementation) BuildItem_SetObjectTransform(BuildItem Lib3MFHandle, sTransform sLib3MFTransform) error { var err error = nil - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_builditem_setobjecttransform, implementation_builditem.GetDLLInHandle(), uintptr(unsafe.Pointer(&sTransform))) - if (err != nil) { + if err != nil { return err } - + return err } @@ -6268,262 +6315,262 @@ func (implementation *Lib3MFImplementation) BuildItem_GetPartNumber(BuildItem Li var err error = nil var neededforPartNumber int64 = 0 var filledinPartNumber int64 = 0 - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getpartnumber, implementation_builditem.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPartNumber), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizePartNumber := neededforPartNumber bufferPartNumber := make([]byte, bufferSizePartNumber) err = implementation.CallFunction(implementation.Lib3MF_builditem_getpartnumber, implementation_builditem.GetDLLInHandle(), Int64InValue(bufferSizePartNumber), Int64OutValue(&filledinPartNumber), uintptr(unsafe.Pointer(&bufferPartNumber[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferPartNumber[:(filledinPartNumber-1)]), err + + return string(bufferPartNumber[:(filledinPartNumber - 1)]), err } -func (implementation *Lib3MFImplementation) BuildItem_SetPartNumber(BuildItem Lib3MFHandle, sSetPartnumber string) (error) { +func (implementation *Lib3MFImplementation) BuildItem_SetPartNumber(BuildItem Lib3MFHandle, sSetPartnumber string) error { var err error = nil - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_builditem_setpartnumber, implementation_builditem.GetDLLInHandle(), StringInValue(sSetPartnumber)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) BuildItem_GetMetaDataGroup(BuildItem Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hMetaDataGroup := implementation.NewHandle() - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return hMetaDataGroup, err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getmetadatagroup, implementation_builditem.GetDLLInHandle(), hMetaDataGroup.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMetaDataGroup, err } - + return hMetaDataGroup, err } func (implementation *Lib3MFImplementation) BuildItem_GetOutbox(BuildItem Lib3MFHandle) (sLib3MFBox, error) { var err error = nil var sOutbox sLib3MFBox - + implementation_builditem, err := implementation.GetWrapperHandle(BuildItem) - if (err != nil) { + if err != nil { return sOutbox, err } err = implementation.CallFunction(implementation.Lib3MF_builditem_getoutbox, implementation_builditem.GetDLLInHandle(), 0) - if (err != nil) { + if err != nil { return sOutbox, err } - + return sOutbox, err } func (implementation *Lib3MFImplementation) BuildItemIterator_MoveNext(BuildItemIterator Lib3MFHandle) (bool, error) { var err error = nil var bHasNext int64 = 0 - + implementation_builditemiterator, err := implementation.GetWrapperHandle(BuildItemIterator) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_builditemiterator_movenext, implementation_builditemiterator.GetDLLInHandle(), Int64OutValue(&bHasNext)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasNext != 0), err } func (implementation *Lib3MFImplementation) BuildItemIterator_MovePrevious(BuildItemIterator Lib3MFHandle) (bool, error) { var err error = nil var bHasPrevious int64 = 0 - + implementation_builditemiterator, err := implementation.GetWrapperHandle(BuildItemIterator) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_builditemiterator_moveprevious, implementation_builditemiterator.GetDLLInHandle(), Int64OutValue(&bHasPrevious)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasPrevious != 0), err } func (implementation *Lib3MFImplementation) BuildItemIterator_GetCurrent(BuildItemIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hBuildItem := implementation.NewHandle() - + implementation_builditemiterator, err := implementation.GetWrapperHandle(BuildItemIterator) - if (err != nil) { + if err != nil { return hBuildItem, err } err = implementation.CallFunction(implementation.Lib3MF_builditemiterator_getcurrent, implementation_builditemiterator.GetDLLInHandle(), hBuildItem.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBuildItem, err } - + return hBuildItem, err } func (implementation *Lib3MFImplementation) BuildItemIterator_Clone(BuildItemIterator Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hOutBuildItemIterator := implementation.NewHandle() - + implementation_builditemiterator, err := implementation.GetWrapperHandle(BuildItemIterator) - if (err != nil) { + if err != nil { return hOutBuildItemIterator, err } err = implementation.CallFunction(implementation.Lib3MF_builditemiterator_clone, implementation_builditemiterator.GetDLLInHandle(), hOutBuildItemIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hOutBuildItemIterator, err } - + return hOutBuildItemIterator, err } func (implementation *Lib3MFImplementation) BuildItemIterator_Count(BuildItemIterator Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_builditemiterator, err := implementation.GetWrapperHandle(BuildItemIterator) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_builditemiterator_count, implementation_builditemiterator.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } -func (implementation *Lib3MFImplementation) Slice_SetVertices(Slice Lib3MFHandle, Vertices []sLib3MFPosition2D) (error) { +func (implementation *Lib3MFImplementation) Slice_SetVertices(Slice Lib3MFHandle, Vertices []sLib3MFPosition2D) error { var err error = nil - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_slice_setvertices, implementation_slice.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Slice_GetVertices(Slice Lib3MFHandle) ([]sLib3MFPosition2D, error) { var err error = nil arrayVertices := make([]sLib3MFPosition2D, 0) - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return make([]sLib3MFPosition2D, 0), err } err = implementation.CallFunction(implementation.Lib3MF_slice_getvertices, implementation_slice.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFPosition2D, 0), err } err = implementation.CallFunction(implementation.Lib3MF_slice_getvertices, implementation_slice.GetDLLInHandle(), 0, 0, 0) - if (err != nil) { + if err != nil { return make([]sLib3MFPosition2D, 0), err } - + return arrayVertices, err } func (implementation *Lib3MFImplementation) Slice_GetVertexCount(Slice Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slice_getvertexcount, implementation_slice.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) Slice_AddPolygon(Slice Lib3MFHandle, Indices []uint32) (uint64, error) { var err error = nil var nIndex uint64 = 0 - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slice_addpolygon, implementation_slice.GetDLLInHandle(), 0, 0, UInt64OutValue(&nIndex)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nIndex), err } func (implementation *Lib3MFImplementation) Slice_GetPolygonCount(Slice Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slice_getpolygoncount, implementation_slice.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } -func (implementation *Lib3MFImplementation) Slice_SetPolygonIndices(Slice Lib3MFHandle, nIndex uint64, Indices []uint32) (error) { +func (implementation *Lib3MFImplementation) Slice_SetPolygonIndices(Slice Lib3MFHandle, nIndex uint64, Indices []uint32) error { var err error = nil - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_slice_setpolygonindices, implementation_slice.GetDLLInHandle(), UInt64InValue(nIndex), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } @@ -6532,217 +6579,217 @@ func (implementation *Lib3MFImplementation) Slice_GetPolygonIndices(Slice Lib3MF var neededforIndices int64 = 0 var filledinIndices int64 = 0 bufferIndices := make([]uint32, 0) - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } err = implementation.CallFunction(implementation.Lib3MF_slice_getpolygonindices, implementation_slice.GetDLLInHandle(), UInt64InValue(nIndex), Int64InValue(0), Int64OutValue(&neededforIndices), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } bufferSizeIndices := neededforIndices bufferIndices = make([]uint32, bufferSizeIndices) err = implementation.CallFunction(implementation.Lib3MF_slice_getpolygonindices, implementation_slice.GetDLLInHandle(), UInt64InValue(nIndex), Int64InValue(bufferSizeIndices), Int64OutValue(&filledinIndices), uintptr(unsafe.Pointer(&bufferIndices[0]))) - if (err != nil) { + if err != nil { return make([]uint32, 0), err } - + return bufferIndices, err } func (implementation *Lib3MFImplementation) Slice_GetPolygonIndexCount(Slice Lib3MFHandle, nIndex uint64) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slice_getpolygonindexcount, implementation_slice.GetDLLInHandle(), UInt64InValue(nIndex), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) Slice_GetZTop(Slice Lib3MFHandle) (float64, error) { var err error = nil var dZTop float64 = 0 - + implementation_slice, err := implementation.GetWrapperHandle(Slice) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slice_getztop, implementation_slice.GetDLLInHandle(), Float64OutValue(&dZTop)) - if (err != nil) { + if err != nil { return 0, err } - + return dZTop, err } func (implementation *Lib3MFImplementation) SliceStack_GetBottomZ(SliceStack Lib3MFHandle) (float64, error) { var err error = nil var dZBottom float64 = 0 - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_getbottomz, implementation_slicestack.GetDLLInHandle(), Float64OutValue(&dZBottom)) - if (err != nil) { + if err != nil { return 0, err } - + return dZBottom, err } func (implementation *Lib3MFImplementation) SliceStack_GetSliceCount(SliceStack Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_getslicecount, implementation_slicestack.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) SliceStack_GetSlice(SliceStack Lib3MFHandle, nSliceIndex uint64) (Lib3MFHandle, error) { var err error = nil hTheSlice := implementation.NewHandle() - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return hTheSlice, err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_getslice, implementation_slicestack.GetDLLInHandle(), UInt64InValue(nSliceIndex), hTheSlice.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheSlice, err } - + return hTheSlice, err } func (implementation *Lib3MFImplementation) SliceStack_AddSlice(SliceStack Lib3MFHandle, dZTop float64) (Lib3MFHandle, error) { var err error = nil hTheSlice := implementation.NewHandle() - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return hTheSlice, err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_addslice, implementation_slicestack.GetDLLInHandle(), Float64InValue(dZTop), hTheSlice.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheSlice, err } - + return hTheSlice, err } func (implementation *Lib3MFImplementation) SliceStack_GetSliceRefCount(SliceStack Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_getslicerefcount, implementation_slicestack.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } -func (implementation *Lib3MFImplementation) SliceStack_AddSliceStackReference(SliceStack Lib3MFHandle, TheSliceStack Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) SliceStack_AddSliceStackReference(SliceStack Lib3MFHandle, TheSliceStack Lib3MFHandle) error { var err error = nil - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return err } implementation_theslicestack, err := implementation.GetWrapperHandle(TheSliceStack) - if (err != nil) { + if err != nil { return err } - + TheSliceStackDLLHandle := implementation_theslicestack.GetDLLInHandle() - if (TheSliceStackDLLHandle == 0) { + if TheSliceStackDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_addslicestackreference, implementation_slicestack.GetDLLInHandle(), TheSliceStackDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) SliceStack_GetSliceStackReference(SliceStack Lib3MFHandle, nSliceRefIndex uint64) (Lib3MFHandle, error) { var err error = nil hTheSliceStack := implementation.NewHandle() - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return hTheSliceStack, err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_getslicestackreference, implementation_slicestack.GetDLLInHandle(), UInt64InValue(nSliceRefIndex), hTheSliceStack.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheSliceStack, err } - + return hTheSliceStack, err } -func (implementation *Lib3MFImplementation) SliceStack_CollapseSliceReferences(SliceStack Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) SliceStack_CollapseSliceReferences(SliceStack Lib3MFHandle) error { var err error = nil - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_collapseslicereferences, implementation_slicestack.GetDLLInHandle()) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) SliceStack_SetOwnPath(SliceStack Lib3MFHandle, sPath string) (error) { +func (implementation *Lib3MFImplementation) SliceStack_SetOwnPath(SliceStack Lib3MFHandle, sPath string) error { var err error = nil - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_setownpath, implementation_slicestack.GetDLLInHandle(), StringInValue(sPath)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -6750,181 +6797,181 @@ func (implementation *Lib3MFImplementation) SliceStack_GetOwnPath(SliceStack Lib var err error = nil var neededforPath int64 = 0 var filledinPath int64 = 0 - + implementation_slicestack, err := implementation.GetWrapperHandle(SliceStack) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_slicestack_getownpath, implementation_slicestack.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforPath), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizePath := neededforPath bufferPath := make([]byte, bufferSizePath) err = implementation.CallFunction(implementation.Lib3MF_slicestack_getownpath, implementation_slicestack.GetDLLInHandle(), Int64InValue(bufferSizePath), Int64OutValue(&filledinPath), uintptr(unsafe.Pointer(&bufferPath[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferPath[:(filledinPath-1)]), err + + return string(bufferPath[:(filledinPath - 1)]), err } func (implementation *Lib3MFImplementation) Consumer_GetConsumerID(Consumer Lib3MFHandle) (string, error) { var err error = nil var neededforConsumerID int64 = 0 var filledinConsumerID int64 = 0 - + implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_consumer_getconsumerid, implementation_consumer.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforConsumerID), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeConsumerID := neededforConsumerID bufferConsumerID := make([]byte, bufferSizeConsumerID) err = implementation.CallFunction(implementation.Lib3MF_consumer_getconsumerid, implementation_consumer.GetDLLInHandle(), Int64InValue(bufferSizeConsumerID), Int64OutValue(&filledinConsumerID), uintptr(unsafe.Pointer(&bufferConsumerID[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferConsumerID[:(filledinConsumerID-1)]), err + + return string(bufferConsumerID[:(filledinConsumerID - 1)]), err } func (implementation *Lib3MFImplementation) Consumer_GetKeyID(Consumer Lib3MFHandle) (string, error) { var err error = nil var neededforKeyID int64 = 0 var filledinKeyID int64 = 0 - + implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_consumer_getkeyid, implementation_consumer.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforKeyID), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeKeyID := neededforKeyID bufferKeyID := make([]byte, bufferSizeKeyID) err = implementation.CallFunction(implementation.Lib3MF_consumer_getkeyid, implementation_consumer.GetDLLInHandle(), Int64InValue(bufferSizeKeyID), Int64OutValue(&filledinKeyID), uintptr(unsafe.Pointer(&bufferKeyID[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferKeyID[:(filledinKeyID-1)]), err + + return string(bufferKeyID[:(filledinKeyID - 1)]), err } func (implementation *Lib3MFImplementation) Consumer_GetKeyValue(Consumer Lib3MFHandle) (string, error) { var err error = nil var neededforKeyValue int64 = 0 var filledinKeyValue int64 = 0 - + implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_consumer_getkeyvalue, implementation_consumer.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforKeyValue), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeKeyValue := neededforKeyValue bufferKeyValue := make([]byte, bufferSizeKeyValue) err = implementation.CallFunction(implementation.Lib3MF_consumer_getkeyvalue, implementation_consumer.GetDLLInHandle(), Int64InValue(bufferSizeKeyValue), Int64OutValue(&filledinKeyValue), uintptr(unsafe.Pointer(&bufferKeyValue[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferKeyValue[:(filledinKeyValue-1)]), err + + return string(bufferKeyValue[:(filledinKeyValue - 1)]), err } func (implementation *Lib3MFImplementation) AccessRight_GetConsumer(AccessRight Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hConsumer := implementation.NewHandle() - + implementation_accessright, err := implementation.GetWrapperHandle(AccessRight) - if (err != nil) { + if err != nil { return hConsumer, err } err = implementation.CallFunction(implementation.Lib3MF_accessright_getconsumer, implementation_accessright.GetDLLInHandle(), hConsumer.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hConsumer, err } - + return hConsumer, err } func (implementation *Lib3MFImplementation) AccessRight_GetWrappingAlgorithm(AccessRight Lib3MFHandle) (ELib3MFWrappingAlgorithm, error) { var err error = nil var eAlgorithm uint64 = 0 - + implementation_accessright, err := implementation.GetWrapperHandle(AccessRight) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_accessright_getwrappingalgorithm, implementation_accessright.GetDLLInHandle(), UInt64OutValue(&eAlgorithm)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFWrappingAlgorithm (eAlgorithm), err + + return ELib3MFWrappingAlgorithm(eAlgorithm), err } func (implementation *Lib3MFImplementation) AccessRight_GetMgfAlgorithm(AccessRight Lib3MFHandle) (ELib3MFMgfAlgorithm, error) { var err error = nil var eAlgorithm uint64 = 0 - + implementation_accessright, err := implementation.GetWrapperHandle(AccessRight) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_accessright_getmgfalgorithm, implementation_accessright.GetDLLInHandle(), UInt64OutValue(&eAlgorithm)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFMgfAlgorithm (eAlgorithm), err + + return ELib3MFMgfAlgorithm(eAlgorithm), err } func (implementation *Lib3MFImplementation) AccessRight_GetDigestMethod(AccessRight Lib3MFHandle) (ELib3MFDigestMethod, error) { var err error = nil var eAlgorithm uint64 = 0 - + implementation_accessright, err := implementation.GetWrapperHandle(AccessRight) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_accessright_getdigestmethod, implementation_accessright.GetDLLInHandle(), UInt64OutValue(&eAlgorithm)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFDigestMethod (eAlgorithm), err + + return ELib3MFDigestMethod(eAlgorithm), err } func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetEncryptionAlgorithm(ContentEncryptionParams Lib3MFHandle) (ELib3MFEncryptionAlgorithm, error) { var err error = nil var eAlgorithm uint64 = 0 - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getencryptionalgorithm, implementation_contentencryptionparams.GetDLLInHandle(), UInt64OutValue(&eAlgorithm)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFEncryptionAlgorithm (eAlgorithm), err + + return ELib3MFEncryptionAlgorithm(eAlgorithm), err } func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetKey(ContentEncryptionParams Lib3MFHandle) ([]uint8, error) { @@ -6932,23 +6979,23 @@ func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetKey(Conte var neededforByteData int64 = 0 var filledinByteData int64 = 0 bufferByteData := make([]uint8, 0) - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getkey, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforByteData), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeByteData := neededforByteData bufferByteData = make([]uint8, bufferSizeByteData) err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getkey, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(bufferSizeByteData), Int64OutValue(&filledinByteData), uintptr(unsafe.Pointer(&bufferByteData[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferByteData, err } @@ -6957,23 +7004,23 @@ func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetInitializ var neededforByteData int64 = 0 var filledinByteData int64 = 0 bufferByteData := make([]uint8, 0) - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getinitializationvector, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforByteData), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeByteData := neededforByteData bufferByteData = make([]uint8, bufferSizeByteData) err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getinitializationvector, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(bufferSizeByteData), Int64OutValue(&filledinByteData), uintptr(unsafe.Pointer(&bufferByteData[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferByteData, err } @@ -6982,39 +7029,39 @@ func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetAuthentic var neededforByteData int64 = 0 var filledinByteData int64 = 0 bufferByteData := make([]uint8, 0) - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getauthenticationtag, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforByteData), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeByteData := neededforByteData bufferByteData = make([]uint8, bufferSizeByteData) err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getauthenticationtag, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(bufferSizeByteData), Int64OutValue(&filledinByteData), uintptr(unsafe.Pointer(&bufferByteData[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferByteData, err } -func (implementation *Lib3MFImplementation) ContentEncryptionParams_SetAuthenticationTag(ContentEncryptionParams Lib3MFHandle, ByteData []uint8) (error) { +func (implementation *Lib3MFImplementation) ContentEncryptionParams_SetAuthenticationTag(ContentEncryptionParams Lib3MFHandle, ByteData []uint8) error { var err error = nil - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_setauthenticationtag, implementation_contentencryptionparams.GetDLLInHandle(), 0, 0) - if (err != nil) { + if err != nil { return err } - + return err } @@ -7023,40 +7070,40 @@ func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetAdditiona var neededforByteData int64 = 0 var filledinByteData int64 = 0 bufferByteData := make([]uint8, 0) - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getadditionalauthenticationdata, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforByteData), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeByteData := neededforByteData bufferByteData = make([]uint8, bufferSizeByteData) err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getadditionalauthenticationdata, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(bufferSizeByteData), Int64OutValue(&filledinByteData), uintptr(unsafe.Pointer(&bufferByteData[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferByteData, err } func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetDescriptor(ContentEncryptionParams Lib3MFHandle) (uint64, error) { var err error = nil var nDescriptor uint64 = 0 - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getdescriptor, implementation_contentencryptionparams.GetDLLInHandle(), UInt64OutValue(&nDescriptor)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nDescriptor), err } @@ -7064,75 +7111,75 @@ func (implementation *Lib3MFImplementation) ContentEncryptionParams_GetKeyUUID(C var err error = nil var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_contentencryptionparams, err := implementation.GetWrapperHandle(ContentEncryptionParams) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getkeyuuid, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_contentencryptionparams_getkeyuuid, implementation_contentencryptionparams.GetDLLInHandle(), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferUUID[:(filledinUUID-1)]), err + + return string(bufferUUID[:(filledinUUID - 1)]), err } func (implementation *Lib3MFImplementation) ResourceData_GetPath(ResourceData Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hPath := implementation.NewHandle() - + implementation_resourcedata, err := implementation.GetWrapperHandle(ResourceData) - if (err != nil) { + if err != nil { return hPath, err } err = implementation.CallFunction(implementation.Lib3MF_resourcedata_getpath, implementation_resourcedata.GetDLLInHandle(), hPath.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hPath, err } - + return hPath, err } func (implementation *Lib3MFImplementation) ResourceData_GetEncryptionAlgorithm(ResourceData Lib3MFHandle) (ELib3MFEncryptionAlgorithm, error) { var err error = nil var eEncryptionAlgorithm uint64 = 0 - + implementation_resourcedata, err := implementation.GetWrapperHandle(ResourceData) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_resourcedata_getencryptionalgorithm, implementation_resourcedata.GetDLLInHandle(), UInt64OutValue(&eEncryptionAlgorithm)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFEncryptionAlgorithm (eEncryptionAlgorithm), err + + return ELib3MFEncryptionAlgorithm(eEncryptionAlgorithm), err } func (implementation *Lib3MFImplementation) ResourceData_GetCompression(ResourceData Lib3MFHandle) (ELib3MFCompression, error) { var err error = nil var eCompression uint64 = 0 - + implementation_resourcedata, err := implementation.GetWrapperHandle(ResourceData) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_resourcedata_getcompression, implementation_resourcedata.GetDLLInHandle(), UInt64OutValue(&eCompression)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFCompression (eCompression), err + + return ELib3MFCompression(eCompression), err } func (implementation *Lib3MFImplementation) ResourceData_GetAdditionalAuthenticationData(ResourceData Lib3MFHandle) ([]uint8, error) { @@ -7140,23 +7187,23 @@ func (implementation *Lib3MFImplementation) ResourceData_GetAdditionalAuthentica var neededforByteData int64 = 0 var filledinByteData int64 = 0 bufferByteData := make([]uint8, 0) - + implementation_resourcedata, err := implementation.GetWrapperHandle(ResourceData) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } err = implementation.CallFunction(implementation.Lib3MF_resourcedata_getadditionalauthenticationdata, implementation_resourcedata.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforByteData), Int64InValue(0)) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } bufferSizeByteData := neededforByteData bufferByteData = make([]uint8, bufferSizeByteData) err = implementation.CallFunction(implementation.Lib3MF_resourcedata_getadditionalauthenticationdata, implementation_resourcedata.GetDLLInHandle(), Int64InValue(bufferSizeByteData), Int64OutValue(&filledinByteData), uintptr(unsafe.Pointer(&bufferByteData[0]))) - if (err != nil) { + if err != nil { return make([]uint8, 0), err } - + return bufferByteData, err } @@ -7164,425 +7211,425 @@ func (implementation *Lib3MFImplementation) ResourceDataGroup_GetKeyUUID(Resourc var err error = nil var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_resourcedatagroup, err := implementation.GetWrapperHandle(ResourceDataGroup) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_resourcedatagroup_getkeyuuid, implementation_resourcedatagroup.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_resourcedatagroup_getkeyuuid, implementation_resourcedatagroup.GetDLLInHandle(), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferUUID[:(filledinUUID-1)]), err + + return string(bufferUUID[:(filledinUUID - 1)]), err } func (implementation *Lib3MFImplementation) ResourceDataGroup_AddAccessRight(ResourceDataGroup Lib3MFHandle, Consumer Lib3MFHandle, eWrappingAlgorithm ELib3MFWrappingAlgorithm, eMgfAlgorithm ELib3MFMgfAlgorithm, eDigestMethod ELib3MFDigestMethod) (Lib3MFHandle, error) { var err error = nil hTheAccessRight := implementation.NewHandle() - + implementation_resourcedatagroup, err := implementation.GetWrapperHandle(ResourceDataGroup) - if (err != nil) { + if err != nil { return hTheAccessRight, err } implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return hTheAccessRight, err } - + ConsumerDLLHandle := implementation_consumer.GetDLLInHandle() - if (ConsumerDLLHandle == 0) { + if ConsumerDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hTheAccessRight, err } err = implementation.CallFunction(implementation.Lib3MF_resourcedatagroup_addaccessright, implementation_resourcedatagroup.GetDLLInHandle(), ConsumerDLLHandle, uintptr(eWrappingAlgorithm), uintptr(eMgfAlgorithm), uintptr(eDigestMethod), hTheAccessRight.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheAccessRight, err } - + return hTheAccessRight, err } func (implementation *Lib3MFImplementation) ResourceDataGroup_FindAccessRightByConsumer(ResourceDataGroup Lib3MFHandle, Consumer Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hTheAccessRight := implementation.NewHandle() - + implementation_resourcedatagroup, err := implementation.GetWrapperHandle(ResourceDataGroup) - if (err != nil) { + if err != nil { return hTheAccessRight, err } implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return hTheAccessRight, err } - + ConsumerDLLHandle := implementation_consumer.GetDLLInHandle() - if (ConsumerDLLHandle == 0) { + if ConsumerDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hTheAccessRight, err } err = implementation.CallFunction(implementation.Lib3MF_resourcedatagroup_findaccessrightbyconsumer, implementation_resourcedatagroup.GetDLLInHandle(), ConsumerDLLHandle, hTheAccessRight.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheAccessRight, err } - + return hTheAccessRight, err } -func (implementation *Lib3MFImplementation) ResourceDataGroup_RemoveAccessRight(ResourceDataGroup Lib3MFHandle, Consumer Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) ResourceDataGroup_RemoveAccessRight(ResourceDataGroup Lib3MFHandle, Consumer Lib3MFHandle) error { var err error = nil - + implementation_resourcedatagroup, err := implementation.GetWrapperHandle(ResourceDataGroup) - if (err != nil) { + if err != nil { return err } implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return err } - + ConsumerDLLHandle := implementation_consumer.GetDLLInHandle() - if (ConsumerDLLHandle == 0) { + if ConsumerDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_resourcedatagroup_removeaccessright, implementation_resourcedatagroup.GetDLLInHandle(), ConsumerDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) KeyStore_AddConsumer(KeyStore Lib3MFHandle, sConsumerID string, sKeyID string, sKeyValue string) (Lib3MFHandle, error) { var err error = nil hConsumer := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hConsumer, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_addconsumer, implementation_keystore.GetDLLInHandle(), StringInValue(sConsumerID), StringInValue(sKeyID), StringInValue(sKeyValue), hConsumer.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hConsumer, err } - + return hConsumer, err } func (implementation *Lib3MFImplementation) KeyStore_GetConsumerCount(KeyStore Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getconsumercount, implementation_keystore.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) KeyStore_GetConsumer(KeyStore Lib3MFHandle, nConsumerIndex uint64) (Lib3MFHandle, error) { var err error = nil hConsumer := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hConsumer, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getconsumer, implementation_keystore.GetDLLInHandle(), UInt64InValue(nConsumerIndex), hConsumer.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hConsumer, err } - + return hConsumer, err } -func (implementation *Lib3MFImplementation) KeyStore_RemoveConsumer(KeyStore Lib3MFHandle, Consumer Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) KeyStore_RemoveConsumer(KeyStore Lib3MFHandle, Consumer Lib3MFHandle) error { var err error = nil - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return err } implementation_consumer, err := implementation.GetWrapperHandle(Consumer) - if (err != nil) { + if err != nil { return err } - + ConsumerDLLHandle := implementation_consumer.GetDLLInHandle() - if (ConsumerDLLHandle == 0) { + if ConsumerDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_keystore_removeconsumer, implementation_keystore.GetDLLInHandle(), ConsumerDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) KeyStore_FindConsumer(KeyStore Lib3MFHandle, sConsumerID string) (Lib3MFHandle, error) { var err error = nil hConsumer := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hConsumer, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_findconsumer, implementation_keystore.GetDLLInHandle(), StringInValue(sConsumerID), hConsumer.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hConsumer, err } - + return hConsumer, err } func (implementation *Lib3MFImplementation) KeyStore_GetResourceDataGroupCount(KeyStore Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getresourcedatagroupcount, implementation_keystore.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) KeyStore_AddResourceDataGroup(KeyStore Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceDataGroup := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_addresourcedatagroup, implementation_keystore.GetDLLInHandle(), hResourceDataGroup.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } - + return hResourceDataGroup, err } func (implementation *Lib3MFImplementation) KeyStore_GetResourceDataGroup(KeyStore Lib3MFHandle, nResourceDataIndex uint64) (Lib3MFHandle, error) { var err error = nil hResourceDataGroup := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getresourcedatagroup, implementation_keystore.GetDLLInHandle(), UInt64InValue(nResourceDataIndex), hResourceDataGroup.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } - + return hResourceDataGroup, err } -func (implementation *Lib3MFImplementation) KeyStore_RemoveResourceDataGroup(KeyStore Lib3MFHandle, ResourceDataGroup Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) KeyStore_RemoveResourceDataGroup(KeyStore Lib3MFHandle, ResourceDataGroup Lib3MFHandle) error { var err error = nil - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return err } implementation_resourcedatagroup, err := implementation.GetWrapperHandle(ResourceDataGroup) - if (err != nil) { + if err != nil { return err } - + ResourceDataGroupDLLHandle := implementation_resourcedatagroup.GetDLLInHandle() - if (ResourceDataGroupDLLHandle == 0) { + if ResourceDataGroupDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_keystore_removeresourcedatagroup, implementation_keystore.GetDLLInHandle(), ResourceDataGroupDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) KeyStore_FindResourceDataGroup(KeyStore Lib3MFHandle, PartPath Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceDataGroup := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } implementation_partpath, err := implementation.GetWrapperHandle(PartPath) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } - + PartPathDLLHandle := implementation_partpath.GetDLLInHandle() - if (PartPathDLLHandle == 0) { + if PartPathDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hResourceDataGroup, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_findresourcedatagroup, implementation_keystore.GetDLLInHandle(), PartPathDLLHandle, hResourceDataGroup.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceDataGroup, err } - + return hResourceDataGroup, err } func (implementation *Lib3MFImplementation) KeyStore_AddResourceData(KeyStore Lib3MFHandle, ResourceDataGroup Lib3MFHandle, PartPath Lib3MFHandle, eAlgorithm ELib3MFEncryptionAlgorithm, eCompression ELib3MFCompression, AdditionalAuthenticationData []uint8) (Lib3MFHandle, error) { var err error = nil hResourceData := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hResourceData, err } implementation_resourcedatagroup, err := implementation.GetWrapperHandle(ResourceDataGroup) - if (err != nil) { + if err != nil { return hResourceData, err } - + ResourceDataGroupDLLHandle := implementation_resourcedatagroup.GetDLLInHandle() - if (ResourceDataGroupDLLHandle == 0) { + if ResourceDataGroupDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hResourceData, err } implementation_partpath, err := implementation.GetWrapperHandle(PartPath) - if (err != nil) { + if err != nil { return hResourceData, err } - + PartPathDLLHandle := implementation_partpath.GetDLLInHandle() - if (PartPathDLLHandle == 0) { + if PartPathDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hResourceData, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_addresourcedata, implementation_keystore.GetDLLInHandle(), ResourceDataGroupDLLHandle, PartPathDLLHandle, uintptr(eAlgorithm), uintptr(eCompression), 0, 0, hResourceData.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceData, err } - + return hResourceData, err } -func (implementation *Lib3MFImplementation) KeyStore_RemoveResourceData(KeyStore Lib3MFHandle, ResourceData Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) KeyStore_RemoveResourceData(KeyStore Lib3MFHandle, ResourceData Lib3MFHandle) error { var err error = nil - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return err } implementation_resourcedata, err := implementation.GetWrapperHandle(ResourceData) - if (err != nil) { + if err != nil { return err } - + ResourceDataDLLHandle := implementation_resourcedata.GetDLLInHandle() - if (ResourceDataDLLHandle == 0) { + if ResourceDataDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_keystore_removeresourcedata, implementation_keystore.GetDLLInHandle(), ResourceDataDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) KeyStore_FindResourceData(KeyStore Lib3MFHandle, ResourcePath Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceData := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hResourceData, err } implementation_resourcepath, err := implementation.GetWrapperHandle(ResourcePath) - if (err != nil) { + if err != nil { return hResourceData, err } - + ResourcePathDLLHandle := implementation_resourcepath.GetDLLInHandle() - if (ResourcePathDLLHandle == 0) { + if ResourcePathDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hResourceData, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_findresourcedata, implementation_keystore.GetDLLInHandle(), ResourcePathDLLHandle, hResourceData.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceData, err } - + return hResourceData, err } func (implementation *Lib3MFImplementation) KeyStore_GetResourceDataCount(KeyStore Lib3MFHandle) (uint64, error) { var err error = nil var nCount uint64 = 0 - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getresourcedatacount, implementation_keystore.GetDLLInHandle(), UInt64OutValue(&nCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint64(nCount), err } func (implementation *Lib3MFImplementation) KeyStore_GetResourceData(KeyStore Lib3MFHandle, nResourceDataIndex uint64) (Lib3MFHandle, error) { var err error = nil hResourceData := implementation.NewHandle() - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return hResourceData, err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getresourcedata, implementation_keystore.GetDLLInHandle(), UInt64InValue(nResourceDataIndex), hResourceData.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceData, err } - + return hResourceData, err } @@ -7591,350 +7638,350 @@ func (implementation *Lib3MFImplementation) KeyStore_GetUUID(KeyStore Lib3MFHand var bHasUUID int64 = 0 var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return false, "", err } err = implementation.CallFunction(implementation.Lib3MF_keystore_getuuid, implementation_keystore.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_keystore_getuuid, implementation_keystore.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasUUID != 0), string(bufferUUID[:(filledinUUID-1)]), err + + return (bHasUUID != 0), string(bufferUUID[:(filledinUUID - 1)]), err } -func (implementation *Lib3MFImplementation) KeyStore_SetUUID(KeyStore Lib3MFHandle, sUUID string) (error) { +func (implementation *Lib3MFImplementation) KeyStore_SetUUID(KeyStore Lib3MFHandle, sUUID string) error { var err error = nil - + implementation_keystore, err := implementation.GetWrapperHandle(KeyStore) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_keystore_setuuid, implementation_keystore.GetDLLInHandle(), StringInValue(sUUID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_RootModelPart(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hRootModelPart := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hRootModelPart, err } err = implementation.CallFunction(implementation.Lib3MF_model_rootmodelpart, implementation_model.GetDLLInHandle(), hRootModelPart.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hRootModelPart, err } - + return hRootModelPart, err } func (implementation *Lib3MFImplementation) Model_FindOrCreatePackagePart(Model Lib3MFHandle, sAbsolutePath string) (Lib3MFHandle, error) { var err error = nil hModelPart := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hModelPart, err } err = implementation.CallFunction(implementation.Lib3MF_model_findorcreatepackagepart, implementation_model.GetDLLInHandle(), StringInValue(sAbsolutePath), hModelPart.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hModelPart, err } - + return hModelPart, err } -func (implementation *Lib3MFImplementation) Model_SetUnit(Model Lib3MFHandle, eUnit ELib3MFModelUnit) (error) { +func (implementation *Lib3MFImplementation) Model_SetUnit(Model Lib3MFHandle, eUnit ELib3MFModelUnit) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_setunit, implementation_model.GetDLLInHandle(), uintptr(eUnit)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_GetUnit(Model Lib3MFHandle) (ELib3MFModelUnit, error) { var err error = nil var eUnit uint64 = 0 - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_model_getunit, implementation_model.GetDLLInHandle(), UInt64OutValue(&eUnit)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFModelUnit (eUnit), err + + return ELib3MFModelUnit(eUnit), err } func (implementation *Lib3MFImplementation) Model_GetLanguage(Model Lib3MFHandle) (string, error) { var err error = nil var neededforLanguage int64 = 0 var filledinLanguage int64 = 0 - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return "", err } err = implementation.CallFunction(implementation.Lib3MF_model_getlanguage, implementation_model.GetDLLInHandle(), Int64InValue(0), Int64OutValue(&neededforLanguage), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeLanguage := neededforLanguage bufferLanguage := make([]byte, bufferSizeLanguage) err = implementation.CallFunction(implementation.Lib3MF_model_getlanguage, implementation_model.GetDLLInHandle(), Int64InValue(bufferSizeLanguage), Int64OutValue(&filledinLanguage), uintptr(unsafe.Pointer(&bufferLanguage[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferLanguage[:(filledinLanguage-1)]), err + + return string(bufferLanguage[:(filledinLanguage - 1)]), err } -func (implementation *Lib3MFImplementation) Model_SetLanguage(Model Lib3MFHandle, sLanguage string) (error) { +func (implementation *Lib3MFImplementation) Model_SetLanguage(Model Lib3MFHandle, sLanguage string) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_setlanguage, implementation_model.GetDLLInHandle(), StringInValue(sLanguage)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_QueryWriter(Model Lib3MFHandle, sWriterClass string) (Lib3MFHandle, error) { var err error = nil hWriterInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hWriterInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_querywriter, implementation_model.GetDLLInHandle(), StringInValue(sWriterClass), hWriterInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hWriterInstance, err } - + return hWriterInstance, err } func (implementation *Lib3MFImplementation) Model_QueryReader(Model Lib3MFHandle, sReaderClass string) (Lib3MFHandle, error) { var err error = nil hReaderInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hReaderInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_queryreader, implementation_model.GetDLLInHandle(), StringInValue(sReaderClass), hReaderInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hReaderInstance, err } - + return hReaderInstance, err } func (implementation *Lib3MFImplementation) Model_GetTexture2DByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hTextureInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hTextureInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_gettexture2dbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hTextureInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTextureInstance, err } - + return hTextureInstance, err } func (implementation *Lib3MFImplementation) Model_GetPropertyTypeByID(Model Lib3MFHandle, nUniqueResourceID uint32) (ELib3MFPropertyType, error) { var err error = nil var eThePropertyType uint64 = 0 - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_model_getpropertytypebyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), UInt64OutValue(&eThePropertyType)) - if (err != nil) { + if err != nil { return 0, err } - - return ELib3MFPropertyType (eThePropertyType), err + + return ELib3MFPropertyType(eThePropertyType), err } func (implementation *Lib3MFImplementation) Model_GetBaseMaterialGroupByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hBaseMaterialGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hBaseMaterialGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getbasematerialgroupbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hBaseMaterialGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBaseMaterialGroupInstance, err } - + return hBaseMaterialGroupInstance, err } func (implementation *Lib3MFImplementation) Model_GetTexture2DGroupByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hTexture2DGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hTexture2DGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_gettexture2dgroupbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hTexture2DGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTexture2DGroupInstance, err } - + return hTexture2DGroupInstance, err } func (implementation *Lib3MFImplementation) Model_GetCompositeMaterialsByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hCompositeMaterialsInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hCompositeMaterialsInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getcompositematerialsbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hCompositeMaterialsInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hCompositeMaterialsInstance, err } - + return hCompositeMaterialsInstance, err } func (implementation *Lib3MFImplementation) Model_GetMultiPropertyGroupByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hMultiPropertyGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hMultiPropertyGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getmultipropertygroupbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hMultiPropertyGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMultiPropertyGroupInstance, err } - + return hMultiPropertyGroupInstance, err } func (implementation *Lib3MFImplementation) Model_GetMeshObjectByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hMeshObjectInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hMeshObjectInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getmeshobjectbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hMeshObjectInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMeshObjectInstance, err } - + return hMeshObjectInstance, err } func (implementation *Lib3MFImplementation) Model_GetComponentsObjectByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hComponentsObjectInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hComponentsObjectInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getcomponentsobjectbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hComponentsObjectInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hComponentsObjectInstance, err } - + return hComponentsObjectInstance, err } func (implementation *Lib3MFImplementation) Model_GetColorGroupByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hColorGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hColorGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getcolorgroupbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hColorGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hColorGroupInstance, err } - + return hColorGroupInstance, err } func (implementation *Lib3MFImplementation) Model_GetSliceStackByID(Model Lib3MFHandle, nUniqueResourceID uint32) (Lib3MFHandle, error) { var err error = nil hSliceStacInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hSliceStacInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getslicestackbyid, implementation_model.GetDLLInHandle(), UInt32InValue(nUniqueResourceID), hSliceStacInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hSliceStacInstance, err } - + return hSliceStacInstance, err } @@ -7943,766 +7990,770 @@ func (implementation *Lib3MFImplementation) Model_GetBuildUUID(Model Lib3MFHandl var bHasUUID int64 = 0 var neededforUUID int64 = 0 var filledinUUID int64 = 0 - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return false, "", err } err = implementation.CallFunction(implementation.Lib3MF_model_getbuilduuid, implementation_model.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(0), Int64OutValue(&neededforUUID), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizeUUID := neededforUUID bufferUUID := make([]byte, bufferSizeUUID) err = implementation.CallFunction(implementation.Lib3MF_model_getbuilduuid, implementation_model.GetDLLInHandle(), Int64OutValue(&bHasUUID), Int64InValue(bufferSizeUUID), Int64OutValue(&filledinUUID), uintptr(unsafe.Pointer(&bufferUUID[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasUUID != 0), string(bufferUUID[:(filledinUUID-1)]), err + + return (bHasUUID != 0), string(bufferUUID[:(filledinUUID - 1)]), err } -func (implementation *Lib3MFImplementation) Model_SetBuildUUID(Model Lib3MFHandle, sUUID string) (error) { +func (implementation *Lib3MFImplementation) Model_SetBuildUUID(Model Lib3MFHandle, sUUID string) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_setbuilduuid, implementation_model.GetDLLInHandle(), StringInValue(sUUID)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_GetBuildItems(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hBuildItemIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hBuildItemIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getbuilditems, implementation_model.GetDLLInHandle(), hBuildItemIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBuildItemIterator, err } - + return hBuildItemIterator, err } func (implementation *Lib3MFImplementation) Model_GetOutbox(Model Lib3MFHandle) (sLib3MFBox, error) { var err error = nil var sOutbox sLib3MFBox - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return sOutbox, err } err = implementation.CallFunction(implementation.Lib3MF_model_getoutbox, implementation_model.GetDLLInHandle(), 0) - if (err != nil) { + if err != nil { return sOutbox, err } - + return sOutbox, err } func (implementation *Lib3MFImplementation) Model_GetResources(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getresources, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetObjects(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getobjects, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetMeshObjects(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getmeshobjects, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetComponentsObjects(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getcomponentsobjects, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetTexture2Ds(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_gettexture2ds, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetBaseMaterialGroups(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getbasematerialgroups, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetColorGroups(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getcolorgroups, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetTexture2DGroups(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_gettexture2dgroups, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetCompositeMaterials(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getcompositematerials, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetMultiPropertyGroups(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getmultipropertygroups, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_GetSliceStacks(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hResourceIterator := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hResourceIterator, err } err = implementation.CallFunction(implementation.Lib3MF_model_getslicestacks, implementation_model.GetDLLInHandle(), hResourceIterator.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hResourceIterator, err } - + return hResourceIterator, err } func (implementation *Lib3MFImplementation) Model_MergeToModel(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hMergedModelInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hMergedModelInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_mergetomodel, implementation_model.GetDLLInHandle(), hMergedModelInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMergedModelInstance, err } - + return hMergedModelInstance, err } func (implementation *Lib3MFImplementation) Model_AddMeshObject(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hMeshObjectInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hMeshObjectInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addmeshobject, implementation_model.GetDLLInHandle(), hMeshObjectInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMeshObjectInstance, err } - + return hMeshObjectInstance, err } func (implementation *Lib3MFImplementation) Model_AddComponentsObject(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hComponentsObjectInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hComponentsObjectInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addcomponentsobject, implementation_model.GetDLLInHandle(), hComponentsObjectInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hComponentsObjectInstance, err } - + return hComponentsObjectInstance, err } func (implementation *Lib3MFImplementation) Model_AddSliceStack(Model Lib3MFHandle, dZBottom float64) (Lib3MFHandle, error) { var err error = nil hSliceStackInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hSliceStackInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addslicestack, implementation_model.GetDLLInHandle(), Float64InValue(dZBottom), hSliceStackInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hSliceStackInstance, err } - + return hSliceStackInstance, err } func (implementation *Lib3MFImplementation) Model_AddTexture2DFromAttachment(Model Lib3MFHandle, TextureAttachment Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hTexture2DInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hTexture2DInstance, err } implementation_textureattachment, err := implementation.GetWrapperHandle(TextureAttachment) - if (err != nil) { + if err != nil { return hTexture2DInstance, err } - + TextureAttachmentDLLHandle := implementation_textureattachment.GetDLLInHandle() - if (TextureAttachmentDLLHandle == 0) { + if TextureAttachmentDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hTexture2DInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addtexture2dfromattachment, implementation_model.GetDLLInHandle(), TextureAttachmentDLLHandle, hTexture2DInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTexture2DInstance, err } - + return hTexture2DInstance, err } func (implementation *Lib3MFImplementation) Model_AddBaseMaterialGroup(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hBaseMaterialGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hBaseMaterialGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addbasematerialgroup, implementation_model.GetDLLInHandle(), hBaseMaterialGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBaseMaterialGroupInstance, err } - + return hBaseMaterialGroupInstance, err } func (implementation *Lib3MFImplementation) Model_AddColorGroup(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hColorGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hColorGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addcolorgroup, implementation_model.GetDLLInHandle(), hColorGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hColorGroupInstance, err } - + return hColorGroupInstance, err } func (implementation *Lib3MFImplementation) Model_AddTexture2DGroup(Model Lib3MFHandle, Texture2DInstance Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hTexture2DGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hTexture2DGroupInstance, err } implementation_texture2dinstance, err := implementation.GetWrapperHandle(Texture2DInstance) - if (err != nil) { + if err != nil { return hTexture2DGroupInstance, err } - + Texture2DInstanceDLLHandle := implementation_texture2dinstance.GetDLLInHandle() - if (Texture2DInstanceDLLHandle == 0) { + if Texture2DInstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hTexture2DGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addtexture2dgroup, implementation_model.GetDLLInHandle(), Texture2DInstanceDLLHandle, hTexture2DGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTexture2DGroupInstance, err } - + return hTexture2DGroupInstance, err } func (implementation *Lib3MFImplementation) Model_AddCompositeMaterials(Model Lib3MFHandle, BaseMaterialGroupInstance Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hCompositeMaterialsInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hCompositeMaterialsInstance, err } implementation_basematerialgroupinstance, err := implementation.GetWrapperHandle(BaseMaterialGroupInstance) - if (err != nil) { + if err != nil { return hCompositeMaterialsInstance, err } - + BaseMaterialGroupInstanceDLLHandle := implementation_basematerialgroupinstance.GetDLLInHandle() - if (BaseMaterialGroupInstanceDLLHandle == 0) { + if BaseMaterialGroupInstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hCompositeMaterialsInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addcompositematerials, implementation_model.GetDLLInHandle(), BaseMaterialGroupInstanceDLLHandle, hCompositeMaterialsInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hCompositeMaterialsInstance, err } - + return hCompositeMaterialsInstance, err } func (implementation *Lib3MFImplementation) Model_AddMultiPropertyGroup(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hMultiPropertyGroupInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hMultiPropertyGroupInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addmultipropertygroup, implementation_model.GetDLLInHandle(), hMultiPropertyGroupInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hMultiPropertyGroupInstance, err } - + return hMultiPropertyGroupInstance, err } func (implementation *Lib3MFImplementation) Model_AddBuildItem(Model Lib3MFHandle, Object Lib3MFHandle, sTransform sLib3MFTransform) (Lib3MFHandle, error) { var err error = nil hBuildItemInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hBuildItemInstance, err } implementation_object, err := implementation.GetWrapperHandle(Object) - if (err != nil) { + if err != nil { return hBuildItemInstance, err } - + ObjectDLLHandle := implementation_object.GetDLLInHandle() - if (ObjectDLLHandle == 0) { + if ObjectDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return hBuildItemInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addbuilditem, implementation_model.GetDLLInHandle(), ObjectDLLHandle, uintptr(unsafe.Pointer(&sTransform)), hBuildItemInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hBuildItemInstance, err } - + return hBuildItemInstance, err } -func (implementation *Lib3MFImplementation) Model_RemoveBuildItem(Model Lib3MFHandle, BuildItemInstance Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Model_RemoveBuildItem(Model Lib3MFHandle, BuildItemInstance Lib3MFHandle) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } implementation_builditeminstance, err := implementation.GetWrapperHandle(BuildItemInstance) - if (err != nil) { + if err != nil { return err } - + BuildItemInstanceDLLHandle := implementation_builditeminstance.GetDLLInHandle() - if (BuildItemInstanceDLLHandle == 0) { + if BuildItemInstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_model_removebuilditem, implementation_model.GetDLLInHandle(), BuildItemInstanceDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_GetMetaDataGroup(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hTheMetaDataGroup := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hTheMetaDataGroup, err } err = implementation.CallFunction(implementation.Lib3MF_model_getmetadatagroup, implementation_model.GetDLLInHandle(), hTheMetaDataGroup.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hTheMetaDataGroup, err } - + return hTheMetaDataGroup, err } func (implementation *Lib3MFImplementation) Model_AddAttachment(Model Lib3MFHandle, sURI string, sRelationShipType string) (Lib3MFHandle, error) { var err error = nil hAttachmentInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hAttachmentInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_addattachment, implementation_model.GetDLLInHandle(), StringInValue(sURI), StringInValue(sRelationShipType), hAttachmentInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachmentInstance, err } - + return hAttachmentInstance, err } -func (implementation *Lib3MFImplementation) Model_RemoveAttachment(Model Lib3MFHandle, AttachmentInstance Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Model_RemoveAttachment(Model Lib3MFHandle, AttachmentInstance Lib3MFHandle) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } implementation_attachmentinstance, err := implementation.GetWrapperHandle(AttachmentInstance) - if (err != nil) { + if err != nil { return err } - + AttachmentInstanceDLLHandle := implementation_attachmentinstance.GetDLLInHandle() - if (AttachmentInstanceDLLHandle == 0) { + if AttachmentInstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_model_removeattachment, implementation_model.GetDLLInHandle(), AttachmentInstanceDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_GetAttachment(Model Lib3MFHandle, nIndex uint32) (Lib3MFHandle, error) { var err error = nil hAttachmentInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hAttachmentInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_getattachment, implementation_model.GetDLLInHandle(), UInt32InValue(nIndex), hAttachmentInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachmentInstance, err } - + return hAttachmentInstance, err } func (implementation *Lib3MFImplementation) Model_FindAttachment(Model Lib3MFHandle, sURI string) (Lib3MFHandle, error) { var err error = nil hAttachmentInstance := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hAttachmentInstance, err } err = implementation.CallFunction(implementation.Lib3MF_model_findattachment, implementation_model.GetDLLInHandle(), StringInValue(sURI), hAttachmentInstance.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachmentInstance, err } - + return hAttachmentInstance, err } func (implementation *Lib3MFImplementation) Model_GetAttachmentCount(Model Lib3MFHandle) (uint32, error) { var err error = nil var nAttachmentCount uint32 = 0 - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return 0, err } err = implementation.CallFunction(implementation.Lib3MF_model_getattachmentcount, implementation_model.GetDLLInHandle(), UInt32OutValue(&nAttachmentCount)) - if (err != nil) { + if err != nil { return 0, err } - + return uint32(nAttachmentCount), err } func (implementation *Lib3MFImplementation) Model_HasPackageThumbnailAttachment(Model Lib3MFHandle) (bool, error) { var err error = nil var bHasThumbnail int64 = 0 - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return false, err } err = implementation.CallFunction(implementation.Lib3MF_model_haspackagethumbnailattachment, implementation_model.GetDLLInHandle(), Int64OutValue(&bHasThumbnail)) - if (err != nil) { + if err != nil { return false, err } - + return (bHasThumbnail != 0), err } func (implementation *Lib3MFImplementation) Model_CreatePackageThumbnailAttachment(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hAttachment := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hAttachment, err } err = implementation.CallFunction(implementation.Lib3MF_model_createpackagethumbnailattachment, implementation_model.GetDLLInHandle(), hAttachment.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachment, err } - + return hAttachment, err } func (implementation *Lib3MFImplementation) Model_GetPackageThumbnailAttachment(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hAttachment := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hAttachment, err } err = implementation.CallFunction(implementation.Lib3MF_model_getpackagethumbnailattachment, implementation_model.GetDLLInHandle(), hAttachment.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hAttachment, err } - + return hAttachment, err } -func (implementation *Lib3MFImplementation) Model_RemovePackageThumbnailAttachment(Model Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Model_RemovePackageThumbnailAttachment(Model Lib3MFHandle) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_removepackagethumbnailattachment, implementation_model.GetDLLInHandle()) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Model_AddCustomContentType(Model Lib3MFHandle, sExtension string, sContentType string) (error) { +func (implementation *Lib3MFImplementation) Model_AddCustomContentType(Model Lib3MFHandle, sExtension string, sContentType string) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_addcustomcontenttype, implementation_model.GetDLLInHandle(), StringInValue(sExtension), StringInValue(sContentType)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Model_RemoveCustomContentType(Model Lib3MFHandle, sExtension string) (error) { +func (implementation *Lib3MFImplementation) Model_RemoveCustomContentType(Model Lib3MFHandle, sExtension string) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_removecustomcontenttype, implementation_model.GetDLLInHandle(), StringInValue(sExtension)) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Model_SetRandomNumberCallback(Model Lib3MFHandle, pTheCallback int64, nUserData uint64) (error) { +func (implementation *Lib3MFImplementation) Model_SetRandomNumberCallback(Model Lib3MFHandle, pTheCallback int64, nUserData uint64) error { var err error = nil - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return err } err = implementation.CallFunction(implementation.Lib3MF_model_setrandomnumbercallback, implementation_model.GetDLLInHandle(), 0, UInt64InValue(nUserData)) - if (err != nil) { + if err != nil { return err } - + return err } func (implementation *Lib3MFImplementation) Model_GetKeyStore(Model Lib3MFHandle) (Lib3MFHandle, error) { var err error = nil hKeyStore := implementation.NewHandle() - + implementation_model, err := implementation.GetWrapperHandle(Model) - if (err != nil) { + if err != nil { return hKeyStore, err } err = implementation.CallFunction(implementation.Lib3MF_model_getkeystore, implementation_model.GetDLLInHandle(), hKeyStore.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hKeyStore, err } - + return hKeyStore, err } +/* +************************************************************************************************************************ -/************************************************************************************************************************* Class definition Lib3MFWrapper -**************************************************************************************************************************/ + +************************************************************************************************************************* +*/ type Lib3MFWrapper struct { Interface Lib3MFGoInterface } + func (implementation *Lib3MFImplementation) GetLibraryVersion() (uint32, uint32, uint32, error) { var err error = nil var nMajor uint32 = 0 @@ -8710,10 +8761,10 @@ func (implementation *Lib3MFImplementation) GetLibraryVersion() (uint32, uint32, var nMicro uint32 = 0 err = implementation.CallFunction(implementation.Lib3MF_getlibraryversion, UInt32OutValue(&nMajor), UInt32OutValue(&nMinor), UInt32OutValue(&nMicro)) - if (err != nil) { + if err != nil { return 0, 0, 0, err } - + return uint32(nMajor), uint32(nMinor), uint32(nMicro), err } @@ -8724,17 +8775,17 @@ func (implementation *Lib3MFImplementation) GetPrereleaseInformation() (bool, st var filledinPrereleaseInfo int64 = 0 err = implementation.CallFunction(implementation.Lib3MF_getprereleaseinformation, Int64OutValue(&bHasPrereleaseInfo), Int64InValue(0), Int64OutValue(&neededforPrereleaseInfo), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizePrereleaseInfo := neededforPrereleaseInfo bufferPrereleaseInfo := make([]byte, bufferSizePrereleaseInfo) err = implementation.CallFunction(implementation.Lib3MF_getprereleaseinformation, Int64OutValue(&bHasPrereleaseInfo), Int64InValue(bufferSizePrereleaseInfo), Int64OutValue(&filledinPrereleaseInfo), uintptr(unsafe.Pointer(&bufferPrereleaseInfo[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasPrereleaseInfo != 0), string(bufferPrereleaseInfo[:(filledinPrereleaseInfo-1)]), err + + return (bHasPrereleaseInfo != 0), string(bufferPrereleaseInfo[:(filledinPrereleaseInfo - 1)]), err } func (implementation *Lib3MFImplementation) GetBuildInformation() (bool, string, error) { @@ -8744,17 +8795,17 @@ func (implementation *Lib3MFImplementation) GetBuildInformation() (bool, string, var filledinBuildInformation int64 = 0 err = implementation.CallFunction(implementation.Lib3MF_getbuildinformation, Int64OutValue(&bHasBuildInfo), Int64InValue(0), Int64OutValue(&neededforBuildInformation), Int64InValue(0)) - if (err != nil) { + if err != nil { return false, "", err } bufferSizeBuildInformation := neededforBuildInformation bufferBuildInformation := make([]byte, bufferSizeBuildInformation) err = implementation.CallFunction(implementation.Lib3MF_getbuildinformation, Int64OutValue(&bHasBuildInfo), Int64InValue(bufferSizeBuildInformation), Int64OutValue(&filledinBuildInformation), uintptr(unsafe.Pointer(&bufferBuildInformation[0]))) - if (err != nil) { + if err != nil { return false, "", err } - - return (bHasBuildInfo != 0), string(bufferBuildInformation[:(filledinBuildInformation-1)]), err + + return (bHasBuildInfo != 0), string(bufferBuildInformation[:(filledinBuildInformation - 1)]), err } func (implementation *Lib3MFImplementation) GetSpecificationVersion(sSpecificationURL string) (bool, uint32, uint32, uint32, error) { @@ -8765,10 +8816,10 @@ func (implementation *Lib3MFImplementation) GetSpecificationVersion(sSpecificati var nMicro uint32 = 0 err = implementation.CallFunction(implementation.Lib3MF_getspecificationversion, StringInValue(sSpecificationURL), Int64OutValue(&bIsSupported), UInt32OutValue(&nMajor), UInt32OutValue(&nMinor), UInt32OutValue(&nMicro)) - if (err != nil) { + if err != nil { return false, 0, 0, 0, err } - + return (bIsSupported != 0), uint32(nMajor), uint32(nMinor), uint32(nMicro), err } @@ -8777,63 +8828,63 @@ func (implementation *Lib3MFImplementation) CreateModel() (Lib3MFHandle, error) hModel := implementation.NewHandle() err = implementation.CallFunction(implementation.Lib3MF_createmodel, hModel.GetDLLOutHandle()) - if (err != nil) { + if err != nil { return hModel, err } - + return hModel, err } -func (implementation *Lib3MFImplementation) Release(Instance Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Release(Instance Lib3MFHandle) error { var err error = nil implementation_instance, err := implementation.GetWrapperHandle(Instance) - if (err != nil) { + if err != nil { return err } - + InstanceDLLHandle := implementation_instance.GetDLLInHandle() - if (InstanceDLLHandle == 0) { + if InstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_release, InstanceDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) Acquire(Instance Lib3MFHandle) (error) { +func (implementation *Lib3MFImplementation) Acquire(Instance Lib3MFHandle) error { var err error = nil implementation_instance, err := implementation.GetWrapperHandle(Instance) - if (err != nil) { + if err != nil { return err } - + InstanceDLLHandle := implementation_instance.GetDLLInHandle() - if (InstanceDLLHandle == 0) { + if InstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return err } err = implementation.CallFunction(implementation.Lib3MF_acquire, InstanceDLLHandle) - if (err != nil) { + if err != nil { return err } - + return err } -func (implementation *Lib3MFImplementation) SetJournal(sJournalPath string) (error) { +func (implementation *Lib3MFImplementation) SetJournal(sJournalPath string) error { var err error = nil err = implementation.CallFunction(implementation.Lib3MF_setjournal, StringInValue(sJournalPath)) - if (err != nil) { + if err != nil { return err } - + return err } @@ -8843,28 +8894,28 @@ func (implementation *Lib3MFImplementation) GetLastError(Instance Lib3MFHandle) var filledinLastErrorString int64 = 0 var bHasLastError int64 = 0 implementation_instance, err := implementation.GetWrapperHandle(Instance) - if (err != nil) { + if err != nil { return "", false, err } - + InstanceDLLHandle := implementation_instance.GetDLLInHandle() - if (InstanceDLLHandle == 0) { + if InstanceDLLHandle == 0 { err := fmt.Errorf("Handle must not be 0.") return "", false, err } err = implementation.CallFunction(implementation.Lib3MF_getlasterror, InstanceDLLHandle, Int64InValue(0), Int64OutValue(&neededforLastErrorString), Int64InValue(0), Int64OutValue(&bHasLastError)) - if (err != nil) { + if err != nil { return "", false, err } bufferSizeLastErrorString := neededforLastErrorString bufferLastErrorString := make([]byte, bufferSizeLastErrorString) err = implementation.CallFunction(implementation.Lib3MF_getlasterror, InstanceDLLHandle, Int64InValue(bufferSizeLastErrorString), Int64OutValue(&filledinLastErrorString), uintptr(unsafe.Pointer(&bufferLastErrorString[0])), Int64OutValue(&bHasLastError)) - if (err != nil) { + if err != nil { return "", false, err } - - return string(bufferLastErrorString[:(filledinLastErrorString-1)]), (bHasLastError != 0), err + + return string(bufferLastErrorString[:(filledinLastErrorString - 1)]), (bHasLastError != 0), err } func (implementation *Lib3MFImplementation) GetSymbolLookupMethod() (uint64, error) { @@ -8872,10 +8923,10 @@ func (implementation *Lib3MFImplementation) GetSymbolLookupMethod() (uint64, err var nSymbolLookupMethod uint64 = 0 err = implementation.CallFunction(implementation.Lib3MF_getsymbollookupmethod, UInt64OutValue(&nSymbolLookupMethod)) - if (err != nil) { + if err != nil { return 0, err } - + return nSymbolLookupMethod, err } @@ -8885,17 +8936,17 @@ func (implementation *Lib3MFImplementation) RetrieveProgressMessage(eTheProgress var filledinProgressMessage int64 = 0 err = implementation.CallFunction(implementation.Lib3MF_retrieveprogressmessage, uintptr(eTheProgressIdentifier), Int64InValue(0), Int64OutValue(&neededforProgressMessage), Int64InValue(0)) - if (err != nil) { + if err != nil { return "", err } bufferSizeProgressMessage := neededforProgressMessage bufferProgressMessage := make([]byte, bufferSizeProgressMessage) err = implementation.CallFunction(implementation.Lib3MF_retrieveprogressmessage, uintptr(eTheProgressIdentifier), Int64InValue(bufferSizeProgressMessage), Int64OutValue(&filledinProgressMessage), uintptr(unsafe.Pointer(&bufferProgressMessage[0]))) - if (err != nil) { + if err != nil { return "", err } - - return string(bufferProgressMessage[:(filledinProgressMessage-1)]), err + + return string(bufferProgressMessage[:(filledinProgressMessage - 1)]), err } func (implementation *Lib3MFImplementation) RGBAToColor(nRed uint8, nGreen uint8, nBlue uint8, nAlpha uint8) (sLib3MFColor, error) { @@ -8903,10 +8954,10 @@ func (implementation *Lib3MFImplementation) RGBAToColor(nRed uint8, nGreen uint8 var sTheColor sLib3MFColor err = implementation.CallFunction(implementation.Lib3MF_rgbatocolor, UInt8InValue(nRed), UInt8InValue(nGreen), UInt8InValue(nBlue), UInt8InValue(nAlpha), 0) - if (err != nil) { + if err != nil { return sTheColor, err } - + return sTheColor, err } @@ -8915,10 +8966,10 @@ func (implementation *Lib3MFImplementation) FloatRGBAToColor(fRed float32, fGree var sTheColor sLib3MFColor err = implementation.CallFunction(implementation.Lib3MF_floatrgbatocolor, Float32InValue(fRed), Float32InValue(fGreen), Float32InValue(fBlue), Float32InValue(fAlpha), 0) - if (err != nil) { + if err != nil { return sTheColor, err } - + return sTheColor, err } @@ -8930,10 +8981,10 @@ func (implementation *Lib3MFImplementation) ColorToRGBA(sTheColor sLib3MFColor) var nAlpha uint8 = 0 err = implementation.CallFunction(implementation.Lib3MF_colortorgba, uintptr(unsafe.Pointer(&sTheColor)), UInt8OutValue(&nRed), UInt8OutValue(&nGreen), UInt8OutValue(&nBlue), UInt8OutValue(&nAlpha)) - if (err != nil) { + if err != nil { return 0, 0, 0, 0, err } - + return uint8(nRed), uint8(nGreen), uint8(nBlue), uint8(nAlpha), err } @@ -8945,10 +8996,10 @@ func (implementation *Lib3MFImplementation) ColorToFloatRGBA(sTheColor sLib3MFCo var fAlpha float32 = 0 err = implementation.CallFunction(implementation.Lib3MF_colortofloatrgba, uintptr(unsafe.Pointer(&sTheColor)), Float32OutValue(&fRed), Float32OutValue(&fGreen), Float32OutValue(&fBlue), Float32OutValue(&fAlpha)) - if (err != nil) { + if err != nil { return 0, 0, 0, 0, err } - + return fRed, fGreen, fBlue, fAlpha, err } @@ -8957,10 +9008,10 @@ func (implementation *Lib3MFImplementation) GetIdentityTransform() (sLib3MFTrans var sTransform sLib3MFTransform err = implementation.CallFunction(implementation.Lib3MF_getidentitytransform, 0) - if (err != nil) { + if err != nil { return sTransform, err } - + return sTransform, err } @@ -8969,10 +9020,10 @@ func (implementation *Lib3MFImplementation) GetUniformScaleTransform(fFactor flo var sTransform sLib3MFTransform err = implementation.CallFunction(implementation.Lib3MF_getuniformscaletransform, Float32InValue(fFactor), 0) - if (err != nil) { + if err != nil { return sTransform, err } - + return sTransform, err } @@ -8981,10 +9032,10 @@ func (implementation *Lib3MFImplementation) GetScaleTransform(fFactorX float32, var sTransform sLib3MFTransform err = implementation.CallFunction(implementation.Lib3MF_getscaletransform, Float32InValue(fFactorX), Float32InValue(fFactorY), Float32InValue(fFactorZ), 0) - if (err != nil) { + if err != nil { return sTransform, err } - + return sTransform, err } @@ -8993,41 +9044,39 @@ func (implementation *Lib3MFImplementation) GetTranslationTransform(fVectorX flo var sTransform sLib3MFTransform err = implementation.CallFunction(implementation.Lib3MF_gettranslationtransform, Float32InValue(fVectorX), Float32InValue(fVectorY), Float32InValue(fVectorZ), 0) - if (err != nil) { + if err != nil { return sTransform, err } - + return sTransform, err } - -func (implementation *Lib3MFImplementation) checkBinaryVersion() (error) { - var nBindingMajor uint32 = 2; - var nBindingMinor uint32 = 3; +func (implementation *Lib3MFImplementation) checkBinaryVersion() error { + var nBindingMajor uint32 = 2 + var nBindingMinor uint32 = 3 nMajor, nMinor, _, err := implementation.GetLibraryVersion() - if (err != nil) { - return err; + if err != nil { + return err } - if ( (nMajor != nBindingMajor) || (nMinor < nBindingMinor) ) { - return fmt.Errorf("Lib3MF Error: 25 (%s)", int(0), GetLib3MFErrorMessage(uint32(0))); + if (nMajor != nBindingMajor) || (nMinor < nBindingMinor) { + return fmt.Errorf("Lib3MF Error: 25 (%s)", int(0), GetLib3MFErrorMessage(uint32(0))) } return nil } func Lib3MFLoadWrapper(DllFileName string) (Lib3MFWrapper, error) { - var Wrapper Lib3MFWrapper; - var Instance Lib3MFImplementation; - - err := Instance.Initialize(DllFileName); - if (err != nil) { - return Wrapper, err; + var Wrapper Lib3MFWrapper + var Instance Lib3MFImplementation + + err := Instance.Initialize(DllFileName) + if err != nil { + return Wrapper, err } err = Instance.checkBinaryVersion() - if (err != nil) { - return Wrapper, err; + if err != nil { + return Wrapper, err } - Wrapper.Interface = &Instance; - - return Wrapper, nil; -} + Wrapper.Interface = &Instance + return Wrapper, nil +} diff --git a/Autogenerated/Bindings/Go/lib3mf_types.h b/Autogenerated/Bindings/Go/lib3mf_types.h index 85f2a0a12..a0c6149a6 100644 --- a/Autogenerated/Bindings/Go/lib3mf_types.h +++ b/Autogenerated/Bindings/Go/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc index 967ef1f16..937582f41 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h index 3feee8514..c524c7583 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc b/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc index 723898b55..983c79636 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file for the Node addon class of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc index 75fbffa47..c4bedb2a2 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file for the Node wrapper class of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h index 4f9389864..66c489824 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Header file for the Node wrapper class of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_types.h b/Autogenerated/Bindings/NodeJS/lib3mf_types.h index 85f2a0a12..a0c6149a6 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_types.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas index 074540d11..6b5ff029d 100644 --- a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas +++ b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas @@ -30,7 +30,7 @@ Abstract: This is an autogenerated Pascal Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 *) @@ -55,7 +55,7 @@ interface const LIB3MF_VERSION_MAJOR = 2; LIB3MF_VERSION_MINOR = 3; - LIB3MF_VERSION_MICRO = 0; + LIB3MF_VERSION_MICRO = 1; LIB3MF_VERSION_PRERELEASEINFO = ''; LIB3MF_VERSION_BUILDINFO = ''; diff --git a/Autogenerated/Bindings/Python/Lib3MF.py b/Autogenerated/Bindings/Python/Lib3MF.py index 94e42a975..54e233c8d 100644 --- a/Autogenerated/Bindings/Python/Lib3MF.py +++ b/Autogenerated/Bindings/Python/Lib3MF.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 ''' @@ -58,7 +58,7 @@ def __str__(self): class BindingVersion(enum.IntEnum): MAJOR = 2 MINOR = 3 - MICRO = 0 + MICRO = 1 '''Definition Error Codes ''' diff --git a/Autogenerated/Source/lib3mf_abi.hpp b/Autogenerated/Source/lib3mf_abi.hpp index a81f5f197..864f8704d 100644 --- a/Autogenerated/Source/lib3mf_abi.hpp +++ b/Autogenerated/Source/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Source/lib3mf_interfaceexception.cpp b/Autogenerated/Source/lib3mf_interfaceexception.cpp index 4504a7b7d..b484bd6a8 100644 --- a/Autogenerated/Source/lib3mf_interfaceexception.cpp +++ b/Autogenerated/Source/lib3mf_interfaceexception.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file with the basic internal exception type in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Source/lib3mf_interfaceexception.hpp b/Autogenerated/Source/lib3mf_interfaceexception.hpp index ad0405d44..1df317ec2 100644 --- a/Autogenerated/Source/lib3mf_interfaceexception.hpp +++ b/Autogenerated/Source/lib3mf_interfaceexception.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Header file with the basic internal exception type in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Source/lib3mf_interfacejournal.cpp b/Autogenerated/Source/lib3mf_interfacejournal.cpp index 8ebbe5e01..106908b7f 100644 --- a/Autogenerated/Source/lib3mf_interfacejournal.cpp +++ b/Autogenerated/Source/lib3mf_interfacejournal.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It provides an automatic Journaling mechanism for the library implementation. -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -286,7 +286,7 @@ CLib3MFInterfaceJournal::CLib3MFInterfaceJournal (const std::string & sFileName) m_StartTime = std::chrono::high_resolution_clock::now(); m_Stream.open (sFileName, std::ios::out); m_Stream << "\n"; - m_Stream << "\n"; + m_Stream << "\n"; m_Stream << "\n"; } diff --git a/Autogenerated/Source/lib3mf_interfacejournal.hpp b/Autogenerated/Source/lib3mf_interfacejournal.hpp index cdfb1f798..f12f333d1 100644 --- a/Autogenerated/Source/lib3mf_interfacejournal.hpp +++ b/Autogenerated/Source/lib3mf_interfacejournal.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ header file in order to allow easy development of the 3MF Library. It provides an automatic Journaling mechanism for the library implementation. -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Source/lib3mf_interfaces.hpp b/Autogenerated/Source/lib3mf_interfaces.hpp index f042bcd1d..9a479767f 100644 --- a/Autogenerated/Source/lib3mf_interfaces.hpp +++ b/Autogenerated/Source/lib3mf_interfaces.hpp @@ -30,7 +30,7 @@ Abstract: This is an autogenerated C++ header file in order to allow easy development of the 3MF Library. The implementer of the 3MF Library needs to derive concrete classes from the abstract classes in this header. -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Source/lib3mf_interfacewrapper.cpp b/Autogenerated/Source/lib3mf_interfacewrapper.cpp index 8b3d7d174..8eddf9ce8 100644 --- a/Autogenerated/Source/lib3mf_interfacewrapper.cpp +++ b/Autogenerated/Source/lib3mf_interfacewrapper.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. The functions in this file need to be implemented. It needs to be generated only once. -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/Autogenerated/Source/lib3mf_types.hpp b/Autogenerated/Source/lib3mf_types.hpp index 62176df53..bc584e7b5 100644 --- a/Autogenerated/Source/lib3mf_types.hpp +++ b/Autogenerated/Source/lib3mf_types.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ @@ -84,7 +84,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 0 +#define LIB3MF_VERSION_MICRO 1 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 90e22e66e..273d1792f 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -1,5 +1,5 @@ - + diff --git a/CMakeLists.txt b/CMakeLists.txt index 469f77ec2..30a31120a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ include(GNUInstallDirs) # Define Version set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API set(LIB3MF_VERSION_MINOR 3) # increase on every backward compatible change of the API -set(LIB3MF_VERSION_MICRO 0) # increase on on every change that does not alter the API +set(LIB3MF_VERSION_MICRO 1) # increase on on every change that does not alter the API set(LIB3MF_VERSION_PRERELEASE "") # denotes pre-release information of a version of lib3mf project(lib3mf diff --git a/Documentation/conf.py b/Documentation/conf.py index 3c28edb92..3b05e0b61 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -22,7 +22,7 @@ author = '3MF Consortium' # The full version, including alpha/beta/rc tags -release = 'v2.3.0' +release = 'v2.3.1' master_doc = 'index' diff --git a/Documentation/index.rst b/Documentation/index.rst index 8d5b57f87..ad31b3b56 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -1,7 +1,7 @@ .. lib3mf documentation master file ********************************************* -lib3mf v2.3.0 documentation +lib3mf v2.3.1 documentation ********************************************* .. image:: https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=master @@ -12,7 +12,7 @@ lib3mf v2.3.0 documentation :target: https://readthedocs.org/projects/lib3mf/ :alt: Documentation Status -.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0&color=green +.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.1&color=green :alt: Version .. image:: https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey @@ -27,7 +27,7 @@ lib3mf v2.3.0 documentation :language: bash -Welcome! This is the documentation for lib3mf v2.3.0. +Welcome! This is the documentation for lib3mf v2.3.1. lib3mf is an implementation of the 3D Manufacturing Format file standard. diff --git a/SDK/Examples/CSharp/Lib3MF_Example.cs b/SDK/Examples/CSharp/Lib3MF_Example.cs index a46e08ea4..53c85dff8 100644 --- a/SDK/Examples/CSharp/Lib3MF_Example.cs +++ b/SDK/Examples/CSharp/Lib3MF_Example.cs @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CSharp application that demonstrates the usage of the CSharp bindings of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 */ diff --git a/SDK/Examples/Pascal/Lib3MF_Example.lpr b/SDK/Examples/Pascal/Lib3MF_Example.lpr index 4c90d59a4..6a564d7dd 100644 --- a/SDK/Examples/Pascal/Lib3MF_Example.lpr +++ b/SDK/Examples/Pascal/Lib3MF_Example.lpr @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Pascal application that demonstrates the usage of the Pascal bindings of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 *) diff --git a/SDK/Examples/Python/Lib3MF_Example.py b/SDK/Examples/Python/Lib3MF_Example.py index 5a1ccff7a..22220afd2 100644 --- a/SDK/Examples/Python/Lib3MF_Example.py +++ b/SDK/Examples/Python/Lib3MF_Example.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python application that demonstrates the usage of the Python bindings of the 3MF Library -Interface version: 2.3.0 +Interface version: 2.3.1 ''' diff --git a/SDK/Readme.md b/SDK/Readme.md index 0e3c835c1..fa392dda7 100644 --- a/SDK/Readme.md +++ b/SDK/Readme.md @@ -18,4 +18,4 @@ The specification can be downloaded at ## Documentation -lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.0.pdf](Documentation/lib3mf_v2.3.0.pdf). +lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.1.pdf](Documentation/lib3mf_v2.3.1.pdf). diff --git a/Source/API/lib3mf.cpp b/Source/API/lib3mf.cpp index ba7212770..79d207aab 100644 --- a/Source/API/lib3mf.cpp +++ b/Source/API/lib3mf.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It needs to be generated only once. -Interface version: 2.3.0 +Interface version: 2.3.1 */ From d7aa426fa69af144350d2fcbc6a322116f3283c2 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 14 Mar 2024 08:53:27 +0530 Subject: [PATCH 30/54] changing readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b3345627..8c5d8384c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # lib3mf -![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.0) +![Build Status](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.1) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) -[![Version 2.3.0](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.0&color=green)]() +[![Version 2.3.1](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.1&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() [![Simplified BSD License](https://img.shields.io/static/v1.svg?label=license&message=BSD&color=green)](LICENSE) [![codecov](https://codecov.io/gh/3MFConsortium/lib3mf/branch/develop/graph/badge.svg?token=3ARnBye33c)](https://codecov.io/gh/3MFConsortium/lib3mf) From 8eca08f25b4925eeb22c8462248ad94fc1150b26 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 14 Mar 2024 09:21:37 +0530 Subject: [PATCH 31/54] adding debug artifacts --- .github/workflows/build.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96a237c83..2260343e7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,6 +75,24 @@ jobs: with: name: lib3mf.dylib path: build/lib3mf.dylib + + build-macos-debug: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - run: sh cmake/GenerateMake.sh "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64 -DCMAKE_BUILD_TYPE=Debug" + - run: cmake --build . + working-directory: ./build + - run: ctest -V + working-directory: ./build + - name: Archive Mac binary + uses: actions/upload-artifact@v2 + with: + name: lib3mf.debug.dylib + path: build/lib3mf.dylib + codecoverage-macos: runs-on: macos-latest steps: @@ -139,6 +157,14 @@ jobs: with: name: lib3mf.debug.dll path: build/Debug/lib3mf.dll + - uses: actions/upload-artifact@v2 + with: + name: lib3mf.pdb + path: build/Debug/lib3mf.pdb + - uses: actions/upload-artifact@v2 + with: + name: lib3mf.debug.lib + path: build/Debug/lib3mf.lib build-windows-32bit: runs-on: windows-2019 steps: From 264d9edd0e47c5309959f441d1f33f5ae9fffb96 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 14 Mar 2024 10:57:57 +0530 Subject: [PATCH 32/54] updating readthedocs config file --- .readthedocs.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index c321dfcbd..10b02b916 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,6 +5,12 @@ # Required version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.7" + # Build documentation in the docs/ directory with Sphinx sphinx: configuration: Documentation/conf.py From 52a3f2636f6ba80be835de097ea77de38d937eb9 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 14 Mar 2024 11:09:16 +0530 Subject: [PATCH 33/54] updating readthedocs config file --- .readthedocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 10b02b916..0054d1cfc 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -22,6 +22,5 @@ formats: - htmlzip python: - version: 3.7 install: - requirements: Documentation/requirements.txt From d4fab5ecf2fb12330e1f6058c4cbd0ffd03cee77 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 14 Mar 2024 11:52:49 +0530 Subject: [PATCH 34/54] updating readthedocs config file --- Documentation/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/requirements.txt b/Documentation/requirements.txt index 89db71b74..fc4abed0a 100644 --- a/Documentation/requirements.txt +++ b/Documentation/requirements.txt @@ -1,2 +1,3 @@ sphinx>=2.0.0 sphinx-tabs +sphinx-rtd-theme \ No newline at end of file From 3a32a3e36d27833ecab158c8a60a8ad6cba59d73 Mon Sep 17 00:00:00 2001 From: gangatp Date: Mon, 15 Apr 2024 23:06:04 +0530 Subject: [PATCH 35/54] skipping leading whitespaces --- Source/Common/NMR_StringUtils.cpp | 3 +++ Tests/CPP_Bindings/Source/Reader.cpp | 10 +++++++++- Tests/TestFiles/Reader/cam_51476_test.3mf | Bin 0 -> 2332813 bytes 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Tests/TestFiles/Reader/cam_51476_test.3mf diff --git a/Source/Common/NMR_StringUtils.cpp b/Source/Common/NMR_StringUtils.cpp index 7c663e492..81dad377b 100644 --- a/Source/Common/NMR_StringUtils.cpp +++ b/Source/Common/NMR_StringUtils.cpp @@ -153,6 +153,9 @@ namespace NMR { __NMRASSERT(pwszValue); nfDouble dResult = 0.0; + //skip leading whitespaces + for (; *pszValue && *pszValue == ' '; pszValue++); + // Convert to double and make a input and range check! auto answer = fast_float::from_chars(pszValue, pszValue + strlen(pszValue), dResult); diff --git a/Tests/CPP_Bindings/Source/Reader.cpp b/Tests/CPP_Bindings/Source/Reader.cpp index 03e4b4698..27f911e31 100644 --- a/Tests/CPP_Bindings/Source/Reader.cpp +++ b/Tests/CPP_Bindings/Source/Reader.cpp @@ -161,9 +161,17 @@ namespace Lib3MF TEST_F(Reader, ReadVerticesWithLeadingPLUSSign) { // This file P_XXM_0519_01.3mf contains vertices with leading + sign e.g +1E+2. - // The 3MFReader allows leading = sign at NMR_StringUtils::fnStringToDouble when reading this file. + // The 3MFReader allows leading + sign at NMR_StringUtils::fnStringToDouble when reading this file. auto reader = model->QueryReader("3mf"); reader->ReadFromFile(sTestFilesPath + "/Reader/" + "P_XXM_0519_01.3mf"); CheckReaderWarnings(Reader::reader3MF, 0); } + + TEST_F(Reader, ReadVerticesValueWithLeadingTrialingSpaces) { + // This file cam-51476-test.3mf contains vertices with leading whitespaces. + // The 3MFReader allows leading/trialing whitespaces at NMR_StringUtils::fnStringToDouble when reading this file. + auto reader = model->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/Reader/" + "cam_51476_test.3mf"); + CheckReaderWarnings(Reader::reader3MF, 0); + } } diff --git a/Tests/TestFiles/Reader/cam_51476_test.3mf b/Tests/TestFiles/Reader/cam_51476_test.3mf new file mode 100644 index 0000000000000000000000000000000000000000..97d858084702a42fcba9aa4025a6d95df741d73e GIT binary patch literal 2332813 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

    d3U&#ba_uVBdDKJ>>zA#p3)^ zK;DC{E*Ebn4Xyw$jmN6cb`$1bL{v?CxVpggu02}$;ngzRlS>~Y-}X7y>VS+jy%7zd zVm-STi^g}s6F3(R?2ZY4-Ke}@{*x5OS3Kamqr+Ctx>#4l$T`10k@^C)?+`Xu=Uu-@ z=)Ip!<$e$M8DIK9a3WUjUSA`>NO`JSOG2&W2*Q6Ec9A)r_XSxSr_sB(Yv$~C`c%oL ztu&X9j>PHH<9U;-b>vl-sqykt{f{5<;aeQ3KX`>e-O}X`lM^gMvW6TgB%-)msBikY zx6FD_dUJdYWpKTLup54Dk@#s-Ruofotu&(_Sqfr761JyoSE8yP5#BU&Z5KIkN^{cA zJ^~U^cGGpS;8WlaH!u)mpv?F2Tq(alo?2X!ZeJ|EP4Z#EELoJhUkQWcD9OxhuD1BH zgDP!1y%Sva<1%IsvQo7n#g)S_A7urcbD&>^j9;SUPSiMILQ33`92?Sx0jP}wqStAq z8>Dw-RvT;u+e2_B6Q7sWqh-^^Ew)>mLx&z!H&;D5W)6gV4{hH9s@p=v;3U@&+)!D* z^^*p5QwOwpb#1@r>+O)RuMKezj7GIilB>!`vN%n9Sl8%Z=BVr^t~iq;1&n>#KKk^& z(BwCCRH++b`&2dFJK1%~T==Q^nF9aExH09e9~&5aTB$}sb29(%vK+Z3)*18qQuazjn5y~8hn3p_)$d+()&Wc zT-{?eZ%$6b`C=QotZQqgsi(#VTe__>1n_w(y?Xay20D{4ONLz{IBjdBrfV}uXifR^ z^*#$!dgXI{eyncS4SL;?8Niu(%x#yMk6^hne|@@^sW_FmBrgysRbT=&(GC?k{2gkc zgzHC}*29x~;)PC|sLxKaE`~?l_C;^uUnD+`wtr5e)JvGNqj1z4wJEU?vieU2FSgw2Mx63D$^}NZxJ@k`xsZq!oo3Lm2_LZ}O zSD(z@W%-&Fb{hIlj%(b634!Civ24+AgZ-#1h5M;Jn#7GR}M zpB*N9oP*6LSvL70&eeLE2u@nvUoqh9^@v=cCx31uG8{;@(GexKBkp9N5>yW(BXfmu zJgcnXd1!6bH9`K}DFoiFigY8?RaZ_3hCJ-P&yOs+68{kqC4Fmd29;XDwO;ilkk)@t@yV$W%%A zpq8&h`ss%5-Qe5{YCnySKACAdl8;Hb!tA6Rhmi58PSoa zn91X$kHf09M9O&5OLi62+1Y2b`F&3b(Z9E70e68&G zwK0ZK%kvl@eoFRLHOz>U2iT-&+CCm#B&}_aojVtrVN2 zM6PI7OndWK>*03Fl>_LV% z+Vkfgb=lhasunh~z)3gMizhr0)J-=Ip zy24g&JA%f^zNnMWXz9&@z6c#Xws2Y$ue`CYjm zn(Ju)MpYD#xc-oHXNrRhXIrROcOo=#<5_}PqP}p$63EoH8=2MNTSwT~NJw-wHH=7J z%-2JkR)yCai-zp+TWe8kAY>RD{vi+P)PqK6^@K4>Z~OFjlHU#;=Mk|!3(~Z{*RPNt z(1QqHsy|5;JAI-ehKgPG3SFnNUme=5AdX39WNT^9nw2q_PxVEbs6DHIrU1e!dd6#GakFs|k5M|Z7oC>h zxik0I;e9d3Qy|wdZLSwiIjR5Kp!aQUT*Q5)|EDBfk(T;kCn#Pdx_*;>PjzANmZ!Qb zXZv{0zT~dIS&{Sk1@@nJw2JQ7ljmp#Q??K6UGzcAYIue^@be9RhqkOhJ4ZH%CnE{G ze)*4^FG@BeLHQwEkudZJi%hW1+HnVXvY%`dQfxk>bRU0And(AH>b>0LczfG7w02%4 zN+h#-N~ZB*6+z8UfbbK7Vo2laQ_5=#MGJa04J(=3v)!w7g^$CmZjt1wyjqt-Pa(&z zYs${sku?zkRpDd)Muqi~*`rAH(IEQ^ulG=b=*(R!AflhP(wOdulmD>1Y=yuxMi9P5 z?B<5-`1QdV3=hHi+BKG`;C2I?mj3$-6z6`k=C%yTXo*?^&q4f|={Ma4a}xf($iZ7? z1w(|7`_UCo768S2AYmdi;pa!;w>LF( zzZ^Yz9)rp}GPD81`t1E>bEUy}YJo=~a#u-Tj0kHN-W#!07}pGq1vDcO{$_1+hy@td zzI8r-jf8Zh_HU??3k2srnH#lgeE1#IAhIW|0KE(ZbgQ?EM1%l)OR@C)9%7y8>$P}~ zBrNlMPV#L@9Cyyk(Y{dSk*0Nd(aKSVsp~|tP~A=pE+l>Ldi<6Wi1|tiL%9*}vUOPK z5v2!t;J(T$l(H4*KSX#VcbnfpH)gJo^7`DQ_)QM*`c1y~@uA6P2O`&ulbbLFrxRp- z-`25a6vqqe!!kTQ+7G)y*%(K9-w7T0?P*#q<}7W|jV+8gb=8W{=W_Ty{{2i*BM(S# z14HehC@hp0|_H`KXQ^HPJ!sFfhrobF$|v7=_M**H@C0Fdeu zxuxj=8O~j9j62`v#m!;QQaI`a;JoMQsRNjR?h|`Zv<0w-^{pASR(HSUX5ve!pYDiL zUlV-pOZ!gX=8=LNACe<}q^O$|&r-Gk3&g)yQ_{!Ohvit5A^5IkF!Q$dMzNl{u83>@ zt9HYBIK}9m{GcIhTLMHD9>L@kG+WdLFM)J5g#hVOvg&rGkpj7V7DB0CG5sd}Cn!1* z+yIFer35@&BzkTWV>Tg{=JHf`s=^mu{p(>M3iC^S5;%5Bm@UYrZv@FACQyCR5jk$U0=#(Z0nsvK%ssVkpU-+fqRb91qU7uZ_&*y!3 zzFrrTvv<>45Vr$1TW-9-dZ@K1I@%dj=7Y>b{Yv1U6PpWNSJ53omvymkWty1-S7$~% z4?bY*1&<=U1%9j}ZB)MN%apOiU5@DXkIz6ifz@jlZH}S(ZBzX(LMHf8eeFKz2qYt4 zu5rYi!!7Ex#Do2QFz<7PRpFc=O|-r*AEnij8h|!U38rLMi{W$K34PfY_MRAbUZ;TAReB5CI%Es;7*fGM60=I-xg*zKE4!R|08xq~~uWznTwq1n|yK+409^ZfD5Af6xUz9kFOlcAm)@Q zawUFY^ptwr^%Mqc;NVH<_#&W-gQ1gv1R7f5&|>*XM~X&dGzIzUi+EdVhmhIu7$CS> zT>0nY6#U#jMVda}7U3Vv?bZ)GVOt@-c9Z#curaQD96@_{55o+`+_hlb_0!vQt}`3{d93L2!Q6L}aZY2A2j@4*BK zETi0R3^q}%zrY~g)nzY`72*z({mPJ8;BV4c;|&b82ivu~2`43DJp?sA-#5+7Yv}D?lLKE5;_y`9To$M(c2#C1i> zh?5DQx_xWUcgv}iiXq)EZNRw8Om{0r@#>tAuxVt;idf*68NrZ@)Op zFC5yc4DUM$N$B1?wSg)ir_q|(g8PKAO9D!=(532K<~qF9xSfu?RbJbxs-^55Jx@M8zU{&oiGGqgC}3LP z51xW1kU7dW>?EG)xxy7pr@DGnm5n(6)?^AY-*kr*Bf6hSqIDn3<^t{Q`oH+Nzh5$k z4)!^k+C^2#>QNvmYsPN$6YG7(NC4}7en1~T1ImGi==Vc)tI@r@8b00OL1 z6C$0xs_jo@-(GnddmZDF_j#Fy!bV5yH8%hVUgOkY+_H-5;a+Eh_E#6>;U-=m@Z;QX z6-Mn2|&V4#7nb?%j3dXq$ZcUY4 zGM+eELn(+N`_3+-N)_!lJYf^YyK082U>i#SG|xxYfkuwrzVyHExxzv6)jAn-;Qmfu z*eB#P9HGs?3Xr{6Kg7U+s%2&3dxZDzBkn0Y!w+bBw@qaA=hV%}q#AZrq3b+d^zu(Jh(&rj=t?a{fQ^gu?PJOKs z8>b%&#H61!C|;`}W+KdDCRkRzo%OcI!c2DYGnK0mTJsM#sDeDm0exPuCT`5D7q`&n z_>>cN!vm>5eiN(lu@(wJMlPVaa zSF;X=vg2RbpENxuuE9f|6n^7fs-@g&;6G2jy-K6F(C~);&@5{7dkF4d1 zg{&5Q?#R(0c6y#EMHZA$J3wfy{DfG_eD62cy^Ehr6r-%PweVHuT%BM1tl{)h$QmK( zxeb5$)X#?sVrVWV<^mJnm0p}+PF|y$`oP$ljrIwHc>RF>n~qCo2YoPSU6ko(evM*!fl;irqT%0w*Wm^_m2l0{s?pX zBDj(61Ss0Vvk*Plqrc^(r{lFPDkD21x1)ZArL>@YpI9L2T{Jb2cG-czPWHtPq@}+m zTIOI#=EN7Fr4jF~OA!qcN9r%jiPAF~pL3j|v+$EwPIBLkLxli`&`=MH!(xdpcP@9R z8||z0vYovII0kZhsBBoTKJJUWG*g=#;24@4%E=}1V_Wb=vdYRvYNTpTMRDfpFw7IFrS9Tz ziZQeB-=;2&;fW?2<}{hCO~3LT>;jWh-8Y!yZMPb8T+(Ya{>z)}l)$2)lHEVB2eX+E z8P=~Zas5C?i~)=gKj7p%YPF;le7e9wTAZWS*$8d$Llj3$(XkwGi)1~!kAL6;e`uj> zvEfCXy80LGyfB%!#JZZ^zZ%G`1E7zQPxIBB%KzMpGpIn0b_Nohuafq=!3CE+V8ZU> zM;Xv;!*e7#pQlQeL~AR8y;ed{v!!k?QAzE4rc#(+J>Bm*Y+3aS>P?-UiE=-_d%{p4 z{T7^QY)F}bk9;V>Wb7unpND^6oV-M_Yg}xdV=~WCS1N? zw|%L<>WJMha=8hEF+Q+ES3^4DSwFN+tVKGWDDAIrE?Pdz*ua6z4k`RSNJm@E6h-%l zU_a`4Y0a4{kZ%I+(*l*TO<}lSeiQ<9XiDenYB`J==%m*kaF2?o3gDORgSDA%S^yeq zWt1#R(eN|-kDK5(--HYd*LuRO<*}v_m7PkrsMfGLbm|hG4u2wXJVZ|p1K%HDFQq9| zV}=->?zKrYH*5}vMeSmMWCS$jk@SFWX9K|sQ0JHKGhKYj^WJ&iWkt``qKK1FaEeg2 zcQG`M*e^C@V}-e)rkU4@W#EcxVogSj=7jCV_o_+ZoNkv_pfGvRfVxY)VD_h(&Uxz5 z8W?p3-vb$R+GobvTEqcQbQFRoitIcP!$izuPSQeE0@p2J##T>3GcBYDU{ipybK6Wu z_fxMw5OOV~W~)KMpJT^u)R4w$=TOsJx(ITYU;H>u=J-C-UTLF#X#oh@<%1p!%oB#z z_?;4_n=j@tGNA6;a5ZYpP6@>){Gy}`M#_=cD3~q3c5qTtBOpVXDMd!6_&OK$`4-$u zHW74BpTJETR(##ScYf;n60;jmnm)~ykl^1I2+2ct;Fj#Ag76`QZOiUOo-x`WTo9pUv zn0um>Sp0U6xw2n@td*1GoWs~76M_n0sx0qJ;c3gJ$bOgxnV;s9-9Z1K!e#^A=h;{N zN+8SZO!KiFlTpHtCT^M%tZhOb%dXM&YDH(DKLXaBq%!JUku#qWpNj=M$8)RLdnTYI z!WA=(k2QZFKdx1LW@=Wiq5dhI()X91Ei@5P;Xg1J+M0q(O_J{ zqz(x&$2r|=Cd67pqi7+y>a1brhWk^{RsnRv7u0JweoJ*7fkCS*G?A;X|^$0BtoW5^WhUL%z)Yozt_F@kz((F5%Zq z37duGYtWe}j??6lG>gh)d>Hy9MtE=x=yweg7omQ;cK5vq5S%E2sM=00rGEBmDHb%@ zE*pP%2A{_)`%9g2-;Rt3&xoOWvs?0t1^hG8N?C++Yi)pZcERwkA`XHvtuGnj z+P)&0X4Zq-ZlcQ>P;ZK(h2h`)bEdXr(^84|qVW}duVS=ckF@f_VR*J~!wr?Ds~RY) z`(g9232W3ry{yj#yFiL{f=B-1sh<>|_7cN=eAnTs94e4cv9fGNuaYB*UonK_^OkVHG0mQ|!AFHtbTC+3uHo|xv`XIS# zqsD0tU84|^^GCV{*}G6?!T?A)TUMi4 zbB488iiIiChJ)#J0 z{7))0c65>}O5-uKvMBy@mxqCmF^botk@hVC6{$Bq7_mv)|3`nXn{W6b%r{hQ&si*+ zE@@1r>r!J&w*vB0BA~B{ z)6RCKMQ3rYJxx0d8!EflB-Hp4KE+)bGyJW}7K*20(yhlmlQq&hagA|x_+H&==x^R} zONy~{Z4WgkirzM6S|lXTxms?`ElGik4}^*`afWr9n9cwbBWMxx2W_PU+jeiDskGUAC>rPz985Q z4PHsIlw~PwIME5E*BDOBi<~~XNPWZfUdu;R3|Dq6CY`IgR;c1T+>-|IX(M7w;*0loD-@oG zr30TmXs>gEGb!y;F7-*TdDFWn!~maTbv z={%cPDVMw+6eGXojN>g2YB!sj?R?J#1LSNu?F420z z5#B$=xXze&p?|*=<}_zl9O{}cEe_|u-pf(03A7n3S|-`h#JmlAkkTK&i~S3=^@!>s zXfj@WV2#)y005!)?JmWbL+%O>mNE0+??4V9OzUpjz!r5>CL4Tq#v)YNbe{~tda|4DG#Mu+;lk3X2SG5#nQ$AQ ztI9bI-Mi7G>U4?hY7EpD`DLrg3nvv#Q7fhjqNIDB4!SkjeZFdXap1hz&5zRpzL}xB z{>6H8KjeJ05w9eCab)}ipZw%1DzcPev4b^;H$*x@vQong}0ht{E)k<9YUpS2$tz++xVJ zoWsm_mNL{jP)i5Vs(&N;#MDpMoBS!T5Z2sB%KE40DmMG+4B)Rqq3>n>kl0TIpdtrU z!u$+wWLekp4hHLx%UR?34C!7Pq>~;?(x)#Ke3{+q!6|tIb+q_qdY|>zOALA4yZxHG zq+dBH@k*aWdFZvE|MXazN{d2KrzKhk3j93z1EA>rW>*klJjW>!?YOTAe+caJnyv_& zQB{ty*QyIqmMCyAZd9y5rk8~;Nr)oeC*9^RB+WB8Wh>7b1|Bv1B%WHRb%yO-sC>g= z{)gP&DY&^|=>tr;>FwxM)Il9o=tPYevf2b^Z*>0%geE1(f?IqWaBt#v-xY&f6`L%D zDEy}2H}x4S$9mec0Kn18xWx^xoS{?};0R91L!!gZ~HjoIlQ0eOklcM{U(5xl)`q6(+^tx}GP zVDN*G&>_7qaGfp!%VA%Dlr#lCMafEujN+CX(1&V=cO%kayO+IBX+^Ms@A(H_P zLcMLI7V^ZLGsHl2YNMuS6?P{p0JE!+7+5)9@$e3rbeuVPv{!3nU0F9<`WoGZ_Mp;` zrAs8S_|Ld)bXA)(diku=d(DrL5ATB`;EXUzT}g>Bx3ZNvl>Iym?X_1FzP+k>^Qhpp zsuU3W(=>kEtm@q(+0zuu+FLsNx~mH(cinb!0R>Wc{d3n*Jg4rS5n_XvH)eGq=dykP~)UheXuE5x6Ti83ao zkN+tL^}bMg)l#lG?Hn>XI^|kw{;022uq<2RoO1&v1UOi+>7y5!rmBiPuoAwew-TL- zqi{w&Yrk-oj#PQ$SoH;EKP78H-QoGA=|Zx%rxY5V8S=_U(2AIFYPv^49|O|y>#K)V z??0@c@NorTyX%(n)M@W-Hl~%<1B(U;F@EynOF$y?)7VVpm;U;M7VFNwYnA&cjRD;x zcGbv`p)E34NN^VR0GiXsF0Gi1?9xrsKyLH+^ga-_=daF|g7ws2y>J1p>6b>ot-hA9 z@jNer&#~>>oTRk*hWS`dS&ID_S9$7=ULT`7&$epjk2SI)j(l{HXzo~;`u~yt)1!JC zN6d+gsp>u*Fnrt9oaj04aL-e62-}x6Y*zpGyIO#oR2H6EtGDkuNCuze&T6qN~(EP zTq~#FFeP9p4NV(`1}DHYhP?x#?F3V|o|=V9HQN)^D(L{q9sgTXY~&vt_H-wY!R@2K z(`i49mFoCU)EL!(?q!NX%Z{lx^$S45o+H^>)sSw+eTbx4A`UYA=`MTn*~p?C#bfe7 zve~!#Aw`^GSJ!n)A*SF|YtW+>Gg{L+RogV|nG(B8z)Ts@S7xA|@EW~@`PS(Dq~`2R z`^o=B@GB|vn)*J=DBemdK9)|4HYjaoT(}pWoOO>^*-V;ms=SNTeHVvkQCn5e?nv z3iOo}!|T1A0YDhzP{8J6ikx58Uo*bj3Ef~JyT)3!dU%sEBDgjCChQB1bZ0{ouUKa9 zAnw}$4yr`0gW$omrSgBW@kb0^zuT5Uf437JN!RwZ30WU__@}WJ(zjQTbB$~;HX8pD z=>B}dECbczgG=KV&sw2a$6T3?^oiw5eW_Y2>47g))K3cz#!7sE^-5U}P^iKWckU7X zA+lEK1b1qPRZIXOaz6(bHM2MJpK9(+8VaJ=6Duc^v-SH2#+tl>Wj7P+EC8!KjS%24 zH7m2g+Z$A?`1xL8jj9C(jvxG8FZ!S%k|TekKkF#S5zpm@+<(0i`B-vjk=*0Zia<;P#Axl>l<)i9i=&&Yh*}w zOcvdeF=XeSI;mrR_5lte-xmY^n9KNq+&>Hhkz2GMFkjPdvJ1y^dn^DkRITFWr={G7 z(nE8oms}Wgfq*DD6ViR= z4lG4jPrCkdF30_mI5pc+<57u7A`&3e3w33dSTX00bN|G{L>92x$}>eG*Tc1_mM zj$_xsh$qsze3~nQaBQng2dk;P-&;W*bo&V zPX7*%dHO{A6~pEdC|9SKC}&atIMdiPl~rmd=j7ZpzPkik4VHt@_>)|Ol_3~%{juWA zIdX3B*R0;+)#JBCQDOyi_QTqwfb!xz&yKF^XqRQd$AP!M2Vg1IJ-I97ZA|U4 zhnOa0B-w71_DOrJ59^2-u~cLjF1bnp75o&3*Vh`9Ioe|vP4kI|Fz>{j-H^!; z(|v8rD)ERS*v5>E6haSI|>@KS9=gL;Drxq^EE8sZ_3Z) zt~I)N4AqQt|~GBVrC2|)c_}3CH<~F7Rt#Y z4=OSoxjqHrGtA(qIK%_(Unp{J1boD(_W$44Y&MIB+t2ArMxL0-jxsDo3s#R;CL4AX z!@EUpVRX;5{f0NRs5)ZXQ_b%J^gbf|2QzhD>0EM@|2?f)8Bju;0WNtt#Hp2I+E311 z3YaMxFsB5e5LY~Vt;Q+zh;nAJ966#rmcy@?&LyYjvBNKm-C_tEF@XB0pMl2aU{%s5 zU)WAkqEo%)xYu_@#(t9RY%cJMk~=HJfa#p2e25K3XtWAqDmJllPXcu%xYb@o9fOmP7thS`1Foohm7JAoSB-Mu;62Yee_rwp>0aYJ1 zU;KEctbpy*TE9~4QpnT&N6!5uDCP@+0e@~N8`7|k3$|(?W-Vq+@tL!xpUO2&E2P?E z56VQ!zq<>Pe5prEan)dz_E>sKX79)aYW#M(A`@4wqsx4Q5pYD9{#m%T!kmw zHCcpHeOh%ief8-`3wQDd0dy8s#a=NZV@gnSm|gRUD=QF7R7@UjzNR&+Dc6$0^$EL4 zIe23~BBS2rwf0!6W&6k`Josg{rSt*wfpDH|bkXQl1%5@hI29MGxO4@!c;q&UY}W!x z24)m}fv^jkCw@Gf!O3Ae)#>o$kd;s)aCv`0>tyo(zn|a=YY{Ny3uY}*;c z(8JneM-Uqua{o7N^1L3+x&uSkIh?zPHVE7l-c;`-sLr1(TsrRe9oQVjE9IwOlSckG zinCcLvanv3by8ronRLr0sep-yNEaJ#0Y_&CFz?03Tdd{O5p4^N=cIq3J*I+kWtv7s z28nv6Z{n+rxaJ3>oSy=a*=6=kP~gYn`h)Htr@yaJlj@CCzsm_!@W^?)PLxvhWE=}T zDyxkA*Y07f3D8nS|7VvyVEp?yR3^G%`_c{QkKuqMXYW;jFcw{h?!GIGk)7&Z(O-U+ z(keYxMdcw^jt|YG-()wYum$7NV5(p}_yzDvLD{UvsRiqcB-ep1xHo2mFU4YYJ=l-@ zOR++2#<~&IMsyTDL&TUbefxgGj{oG{7aC^C57izz;0WWcc_{26GEv0eZN!6|V&mjp zSwm@S4B^eGm$?_-Uhm`}{Fj0P&`Ch&K~t!nTs!_?pDs`4S&F6_WO9f5tU#AYQ4=mv;S!}+Mrt9MxI`Q=%Zk(v?Zo60o_lsjL&0>>Bj<<_fxT5{=t z_M|nkXSD(s3|Xfj@2a}#)?-^0XJA8=fe`m_^0VueJAXjai9bHVE2^+dY2~2=qNaM^UJs$xGZA=0@95f55S=5apy>P4Y<&n zbj=??BfuS#33YD4cU-4G805I3i>bInx_7iJ01GiTd7s3JWWk@$(rmyjK9VJRKNh$P zlCE7g3rhoBs7BTrjR1Ne6kN4mBzi^stkk6vB=qq(0SCi|D=0~Wp`c^+V&ets-UA(1Kd7@gi22- zZTv>`V_@#U8C;tca{OWtn}M?RF#gY?ZDzYocgX;N9z^IU`&r?rP7CRYB9-C;k5q99 z{im>On6;acLY#YhA=~&a0Skkd__~9@NPK9@-oL8w%UY@B%`yGa984Jer!!{x$TFskx)q$Rg40%xJnV%Xbz*Ix z5}H9|4tkWpcxwG?q@HlQHelHEHsA?d(54F&qh)8zBg>vHRN@=Vr6KO>2lE3B{~NZJkk+)q%BS+w4CaIHie-0)(XrNY+{HMFb2QU!yz^^;D*MF zs%S@OBj4qv^_MkDUaxGSfl{f+q!Kd>6-*7y#3;o!KmYq6G1!kc=dp0^%Wt!Lt7tz#tgYHkmEAK(@q*}GIe zcO6aMT3AsoG;Xd>RN4+(?$t4$Aug9MkVXW181kALlsSmxZw_Dub3>({^@wv0z5NTY zkv0~l(^i!)Q2E`pi0pNR?4WOKwSvypTVz;|MkR|!a=ateBSP3zjGcsYfSdN$aXVz> zAk9I39x%jH;dDF>PtcDpFRw|Vl%g(so?{) z{U)Of-04}Lg;-#^QsB5qNK-srCniz*(67DRjFGU~-U z8~9h;i&eFg8uC|Dz@*<3gLTY_eQ&7S<>7N^h64YsoG9`21p==S_uD2)h?@?Ss>=wF z)Sv5KMH5oXs{HwwXPlbF|6X7w;Y*J;2=OGsWSbc8I~0Rs?K7=4uct{*Vr|l2HN_3j zsTkyZx(oS+@E8tw2|jW}*A_z&SCf3~(MX^@cg&$H1ZKP(P5C$yMqPKvmaFrxx2;M{ zJ<)QU0iM~tK*&tVWFzX9A;tLH3y8p?xlrG+yvgNru59Rj3Z6cIvHEV=?7d9ge7Bx7 zUfNFCLw}7hq*+bjsdoGprh9T}pKQMVb^fOoW4MclfTF0@O7rEn>I%T9eT2~~$jT3N zhh65;q~PQhCz;>M%Qp@XSM5jKl(Xi$CX^uVoD7Nv-)GWh6QAN*3Z`Xe-hJdG4}(ng z2Q|fH$UwpiUy#n$d^#x>$$rnG8=hD_lYu2gO~u!rm1BM40#5p*Xm#r)YF^C^i-l8!K~ zvN)li)|+^EcAp_Q-*ooV1I%6FvWu)Es+_)p807dvXb4+&v9OvHxT$Nc*0Y9XRg?Dz z^qzs}O>#Ybmf4%BzRa^;scSbgro5_O4XU7?HmBTQz~u^dy~ma1?j+O(MHx4J`S_bK zz2VdsckwXctxG~0ND@u)L#+05f49&mc-e$Zv=fH+d-ffE+= zhkVHM$LBanJGrB8ooeE>wQopa663Y;5`Gbf^C6mes^vJSXz=dR8NmlUd>8kKG5L{; zt$RB(S2RGS%u-Xt*T=V@r|b3NnB1P2SFcR=&3vvw0z`dp1oX0EBQp{nV<_D`2GXaF zQ}R=zjb;vy+yUz?Pr$Wq|F?Lx?`#6(7BzePF+m3y=o8p(Ilo?O2Um`lZ5Fv@PgK0t z`M2T@{m#&ldlML>NvY3IYh*X=7OPH=`oc9gMeLq*@f=zF8=9w3|0Du()V0s5uF#$j zbEQp!Kv$jlZu&>|T`_T+oA#87Ku~|WAT+uzJ>#VMQU5FZ0l_{pef(n7@!x1ZQkj&0H*nl6 zxVF(PEEmZKiQV}~NB*|!;!73a%~v!D~_jLI>z zgD?&@XgvvWFc)BTp8nEO&c#a}h?V#zae%{b$WMHs1>Nqx)t|7d!IL4u)vP*k>m$iL z(^)Aj;J!cb5W|=)rw3E!mN@Hj&mU6qlk}-nb`!E=ue%t{ILn-CJg|6xQr{;lUG>1K zrDPex`TmU(6mFpD{U8>`5^aR-hqc`ZR65`(Tp`5_Kl%gee`Jq)*cRrUYaeO79sivOS+2OQ68I?S4g$Tg>6tlLDVwHwlw}YMy_1qqE&Z zZLM3RbxVw(TQsYtsH4W>9hJ|h=xW%;_GN}1OxgUdSfld0e%VrKj&VVPiDIsu|Fz@? z2c_N7c9%Nrk@T#E@s_rVjd-?rGliNrxver3se&c97c0s-4=;z`8t|H zu+(-w$^77;OgH3o?&kxgEW9SjecY!>(@N;64TatNFx)h z1RbD0kuE-d=^ADwOy+XX*!t%q4o`*Ci^4jlVQ%PgacxF7ph<0;(NpK!*9@{QOnODf zQ<#8di#f^XdK>I#O9+Mw@fRi04&MN^6X;$J)9-Q7iUdT`zD0+H7e{ZI;KiH^jHr|z z$eIy276fZxo`c`hwk0qt`$7iI4ZAKTa4Kcg1})K%QPyI7n=5F0ui7M;TeZ;S_0*z> zFEmI3h7xayt+NuAf5so-hD*|%XGMFXoVsYbbpm>7$M zE1j9Unflw2ySAm)FVr$u8jn4`;g2wZ*DRUwsgymL^7B=Sug{Z4q^UGTWb|dKDBfF> zMy;5vP+_mZx+8D#()1zqmE7DxLMU~I=>!+Q#@L!6u9ij<8zxKVYl?4+krA*NuXpM( zT;!Ei_Gb*Krdq=0NZ*dNFu|UW1De4oFT>HVZt8_NmO!ikJ#N1RZ`&4-nUdKgnrS=p z9vYEGqRMl(kZPS~1V45^U^H@m-{B(f<9B1)PsZAPi@B#+QO&zGalXJXQW*$)Aedb| zYeRe9vILvJo^f0F6B4`(u2BaTfXm`e@3!3Fd66yr)cSv;M zUVVp`>FCe;(~cbH<{ze*`=6F$w5n=SXjK4f5efQf@47Q$C*9{-@$ zNW!*`h$LcGEBU7ZHIh=!!ND#;g0Z0cU_$d~i4NsxZQyhw~1?k~Uh zAIqgJ3yW`1o$E);b6=Lq^Bu9ZRIhftF#C(u_2SrnlHC4d1bJVR#QHunZ_Ml?cfMapeV!vVO`F+E94z-ge6mT2x{Zf$C3DGHr;nJH7#8D< z%Lo087flK4=|6E4KYfxqZSZv>W%YxZ7dJ7VttQTUKD#TX`I|?Yx~`be3|F}YgjLv& zy}sO(?>0AHZRba;kSVUiKIghFL%e;&TOlin4jOf;%3TF|eYl#uRpN2|UHU%88?aK- zMYT^C(qn|pcO>q4dRH9*2*SgRAZeyQbNZoXsQo|6p1}b{$XeRSD_D${8F?6)TW>|1 zwRsV=Q5Q!V$l#v$>GEfd<-Ss{aCYxsg(X}4<_rx88}E8aPn@1%wCnqROt)|c@pGsz z1)M^!)<}Q7bOBe4>9(CXI+-&0M3e7#e6P&&S_dUHg#U^f~FfFgxP>#~2BVct73){b~^cGpzObbI*g*%s*` z?GCe7&-DvE&%@F~jFf^TkjQp21);EkRAsnf-i$P_7mUvFkDzYR^uW#7FGv)uJ$0RA zF6I5N0AFOw5j?+IdSaa7=gx57Z!D;m^*qH1g#xaRW&vVECU?=kJMs$mJ6_U86psF9^a=T3vphbEu(PvpFZ__{d@ zs1fD(p1(Wi&N$H6udGsyh=$L)fkgBcVEqAn^+S@L&tH-cS|*n zWBlR5de7o4Z}J)U)@K-v&tpUU+{e-}WWFF6xe(upcxv1`Ol_093Uc;v6g)q8pY)9; zQ10BJnlq=#4CK5l2Xp1pjQBvvcMWSNJ&f{W-Rw#^<_Kw#(;%|xvieUY>L<-hlqTw| z*R*NpvJ;NT-bRueH1YDnkVW!qp9oo}2$VIR2bw~TZ;C`b(ew>emUTcT*?TtuPu{}F zCZ5mu3~rT*FTktM3?R;uIlGha)W2qVg{AvRfnO^{<^LhRVC)kp4dd1s-o`5@-tl@H zG87+=vzEynR3()1=|GgWUbsMxC_FwJSHao00i2#V`^)MW>Z@>r1lilSg&V}qr%~#h zN|kTbiQ%*QXfNz>&_ScO)Gp)=Z$~+#MZnm0k?b&7(v++|bk}YmC5m%@eS+3>)+$*z zMsN(G#I>ukh7S@~9Ucecn+vy)%pE3D1oIxrjrzzA$!qEhT9r1{5_Qp=@ebO+79d3-e6AZ_Z$>9Sh&ejv28Gn!aI~{@i6u^ zP}X7(cH~mVn(e~HoEqUWd4SDtD~ofj}S!4ZTmCQ%f=s) z3m%BK3uRYahdrZaS93d>(KE97Y+npafP0#b7(*w(a2YbAOdvK#X1CMWsB z7e=c9Gstw_0QeGXz!{1|^7_vk)wy4@Wy71(hCzdy07FF4_tCKvLJ~g%w1O}2ah}!b z(h{fKXV2|tf0KR@gtZ)0U})>#4bnnXH9sJ?zGPDJCqVm8+vVYM!{N|)t-B3$0t(kL zT<8lGtTVqLD#>&!RaZ|5{~$Q@{}YTFC*JSts@_$Ao0n%pw_8el?}ri0XC1FcydU$SwG= zFMm4F$D`_X29c4*-D#=kmTw=AiQaiJGj~@k#p%;#8El@E>27G)Pn{<@DPX4%_+Dwu zeG-tqJy(S)7JcGSFpHGyzn1JMr<&pC3a;LudfSN=)nSsHU(myApSp2?2|QUkvm;_M zS8Doqs6*9rcXrcLmpt$vRMZ4hrZATYpJ?!fr5hw(v3T(EMEE>OEb%S^+EsQ(?PHj0 z^jb+R+97z53{7Yk;~$ZCyh|DL(9UsVPwnT>M$8S1DTxR12R{OZXjyG(8Rb}5H1(-a*)W&w z%J~wjxIJDe)#2vpUsi3AM%)#u#IKMfNs^4`CfcUGb3mH8)#wpIUGVpw43bfDEL&T1e73SgN{*!hhM~{J=}vzp<9xxYDj##b09F5|*bCV|w<%lDi%~se=;{}u81CFNnKEwvh$K|3; zC*2j!VAv+p$3;&2fF&lZ*jUa}xB0G@7z~d_|IO zVN|_r7;`igQGedJBtqzGXh*#IN7Chqju|$0w3%hy_*nzHX0+eLVgg2b9nv1b;i@*( zX9nsE?L?OL3K(2V7l|?x6Iy(HnbWVdB^OzBhI9GHQW;@7UaTg3&|H7hb+GSRU_SH< zqgi#4d2fW4l1M1Ah}Wcc_?#X-DMWXD72s8wIjx_TT8-VEs(noJJb|sR-NoEP-#2~`f!hEE157v zt$89U-3XRNUHU(Y&OV;0_l@H{kf*dne50(AB-JWPYAmUQ3JIaCQc-o!4vU+~>UR`@Zha^|{_xh>eCg`(3Ht z*dNydhgo;tZ|X_0)Y75t!dMF~^aAJuyI8ZMMPE|mmc(MRE=G5u^R}W|1nrf@M81!m zczH)&JXnFYpOY(mh=~3v`9rmcLtyV-S3TL7>s95x^|Y`7jqG1rCQEU6N7T;_h4MiN zUysCX$&-~Px9}ZKI6TI=tdZ$&AWB7>sd}UL#~c>GrxI67X7bF3T0ot07-jRK*1_m4 z?NeW;AfTfE{-SLp&Mp>rx+wfJZH(X28ecx)_7{W>uJ$SEaPjDgvFc`T$Hknaz1vKW znh`I$ThVDRY)(_}&pP`^kVh!q$304ac}>wROLhaZZJ{fqBf)Ftm;$@}tE|w@q8{XB zr@o?ML~Zs*&;RFT6vsa{x-XBuBaE44;}=XS*(Dtu23P`LapDvRlPm`VipVe(^47A<_w~Wj+(Vk*&?t(wni)51x-WDVQ9> zEjmq+k8Xc0I@gmEm5>Q{-umy1{fT-FLB@rt;D_ri0ouf@#V}|BxniI4hJ(u1jp{bh zX3|8JZEnWAFB(0B-KGZ-xrD2_7{219d`*+$WvSP~o17-QLEq?F-zBT8>P(-ba!WDt zp@SkTGr(M^a};}f>ba0OV7StNw_V^a!@Gzer(xp1^kg2cy$BUHp~W1UdQA_s+rT%R zO+*)q2^HhF8zX_U5wK)gfGDF(@N7^Lva-$jEYE!}>dc_@mMRZ23E%FkB z+JSmIIfUgfY#x{kF1!W%vis#9;(~)l1z-^6iSNj`bv~61gQBBKzZ`Q&n$45); zPpPTqOK+7>mLnd8#z@T)wD`-^9xSg}`1~9G!Rr99iLrng3!>C1wqx=xV6g8ybmFk{ zHD&hR{AIv;e;r3!pTWYj%%dy_Nl?W2?Qwzvz&BpW<4%-3lG(s*%^_y47g4~ z5G?sA=6l2f%%|NI)QsKvg=!yaI%+A;j)@{VkLO{`2dd{n)A>6c7Ve;?=mWe=l!?7i z0bVW~Bf#xU1;?(1Bnd6wbaU3)%L(`v(~16@iOWbDH4B+93Q}2TRflQWtkBW8<%(!Sofs zYz{voKqJ_`#{PR5UDW(aaeAv`M~=<^SX1ku88g{ph>3@s?m9C8YCq~$)T#FDNjRiM=un+%kfAs1k%n^}$D z+R`w5Gm6;#6KEZXi}H(&mt@HGy^-@7&Whup;WmwJ;;W$sP)`>#{Es9H9IZq^ILzEQ zn&B(#FIETB^bN;q!xKxULJycqO)`n71;jkOc%kFt1x3t$GyBs0MM@U-2#}1AdykPm zwM&x0ww_D-B(mi^TeOA3oS&GpO*C$nEPOq;BZDG&tcDbCxQ^=5s*}y$Hc(gP=ytZq z5Je6Z1MQIJv-6ehPD{i%{I2{R??OB_^xCTkPyRuU<*m-4i=-=>(h*G!16@`Qp9X0P~OicW3P1~|59%Ejv91gJ0AJXQE+b*wN{8a{Kl2vVRD^AhteQMl`D#!`|qxiC2k-J-pqr1 zT>6ChShR^%nFhWGH&LE$5Dg#w^QA+CZ_#IM>L41k!=VpS{Bb@bO75_gO^$BuAW~&( zX5=Aj@+51HZyrTK%S`Sua9PEm87Y$F+lu~`6PUPl_#)%RHony66}r|ooes9LB4) zZISsH2cCMN2ySqv$(=wWY@BPg+$2%HNB8{3Jnr6vdg3(guToc48Tnt#x9Vbb%4tF5 zAL^4HCda-F`5-np#CMf!@Fw0w~}By&|Z!wfvZ_fW=JM8oHVb2Ee0kRFRo1>vI-vz28D5L!jvEK zFDjiHIY=66#b9)!6hE43zw_!EV3lNty7Gs1IqD$Lw9UbP^$+iX7VQ4!)`;ARzYkHL z(~p1~=igc>3{7`-QMTBm_C%5^nOQ9+fdvHeYgb4R`5pY0pr&{02h)f1h;bQy1YCo4 zq}d9VE^(i#EQ#C;oOT(;j9qG4Bh1~5MB(COoU@c3?Z4SQzP-J2fngo<4l)-f_b<-) z%Aa4P%AoEQX8iE>k6z=h#7LMA#S7i3Wo38vfX)sQTKlxr=aerUopwBUs zI`%C5s4{D=CZQ#2|3CBz1=>f3-`>;5Rt}VIeQ8U{o6^cHB283wXQ2iLci1B)=6;$_ z(a6hGWcj^e#6h=wf^{llJ@%gJar$eJCfg#yV2gvNxQJd{U!MfO83_Ps<5@`-v(Bd; zsm@=^sjT^t159EaYgVq3^J-)}eKHH-EQUNS0GhW2>phz;6V1 z9ntYo^{9W6BtIWo2;=*k7n^XKiV+TN)&@9;z8e{A|9qMUBFO0mdJpxomqiYMiEkr|x;)=D=UDl$Z|3d6$X-1L`FtUg- zm4Ueg-cFg)7CXBS)4f|Rf=foV7QYxJS8g?y{c*68eN6Gs2jjL`4Y5B=Sw>!5-58*p zZ-sL$wQ!Dlq@;}Wd1vfvaz{ghSsV9KS}!KhTTHJTt>9b zRB+ATpb@C?v+u;MO&{fvWZUp)#!s4i+ISpDc}&~0bvpaV zn@oAdo|M9|F#P>;!d_mwBuFjl)wUxGimRL>sPnPG_5m!}RZaph^VvIvc2E>c7C@wl zwEOg-v`!L)2899p zc?JM(g}`#u<~>gTgoA;+9;;lD5JoW{7d<5I-vdXEdpDuO#U#0O@G@vHswJ*+{Nq{NA1pyyP3peXS;S#6i0nop0aIDn;yDgu0@b{-$LW zl9%$U&Zu;GDR<43ntG*G=3}^{uihx2K8zz0vAi%JSrq8$wILXnEcgA%K8l_4WaIRC z^GuU-zRN*oI04{d3?;_`_O_`W6}?%YCl?4aauzy8M1a*8g&E)@dT$?(x{~N@ zpT{^aqnVhUx~v#PO|KHlmB<+X(4VXmVG6O4-MA&f=444O_^K(lGa5M8o+aNoEb}DX z631&T*2aXfCM;i!6G!0haqvX8c+5Lq%pHLz@QN$F;InZSzcbcP`S#&D3n=5c)xhep zxALmHH9n1;*TAkMPR117P{P`bH2G@HeE-zf_>U29s7GPP>Q}>;`Dk<29ihfk(K~60 zXRYPF_MfSV2`w`Fb$OE4FFaXJ``pA3s(Q>`Ca!R5gJ{(}apOLS{rKI`U*eUs|rnjxj3T ziO1IouJu&Z$zmfruVu+M1X~ZlL{n#^j2+g@OP`8^HIbW`T7Di;fhYGnwqWpNO5$l@%}rcnpDO+0COrcUX#DN0{RPIpU${9-t%*32) znNZ%WEVzlb0sk-9my-mMFp>ufQxOIvn_T_?*m$g6J4Sh)!|Z^REbey85z&J?MR$=Q z#l#rwalU)Yq->}xk{2*5dU1~(9g?dd7_sj`f8Ei+K88JnTGtq}hOz!8?5=;GYVS2V z;px2mP>hsPkGn#EUws7okhB)E__)YcOlADL7*R$zJN<%fghUz%6Yh|t^4+ACrKB~b z$*rK_RI3Fr%&ge08e_)^r#316kvJjVSHpP2$KK&K@P6DSNh3=j0LDR4WEOV?|3(UN z+o@KlRZYl!E#8OS?!(tE0p*>BGf+Aa;%-~yHxS_JrQJ%_D|h?HzKV~(jhcs4|L~x$ zfdoO9jB(;BttsOOa5^@4MCHsk;i*NJ8PmzpCp!ecFN3zVL&wH068sxX>J-$Lr;e)c zcY%!wY()izS4I8iw00?i=bpM;SJ*`EXrl9Lmo_Wz?=_W+SrKPf!%tlzpz5JJ&9Ggt z!|2&P=W@AD6P)Gy;D3x#mffYbB^rpH_(lfaed!wYLg&qrHraN8mwadfmp0+TMU0}p z-n4Olj`jHId=&e$h44HhN$O#Iqb0S5CO6Sz+};d{ZktHcS%PZi;z3T4c)vRJu_j%X zG1VSHsRp{-AhTo5dcKcb{nytQpOl{hIxkWS-pDMgO@FAV432#~jF9z(V}EIAF4_?v zVy?X5cXtljqkCvA*7gx3+ph@EdW=Z@En(f*7`&DCAGTh}%3%(j8B?UJjbj=vd{j`L ziH#I}J>qtbK!E&Cx`{{~8;a~KZW-5@C`3ERhvubWK;SnG{3#OrXw<^IyG-_5StW8? z&n+kr@V-$mI+T8cpxl@7TkD68<-j=3Df+C)Bt$nG!!NC^{NuKpK8Z+?M^vXnvdkjt zxX4rsvls2w=w9DRz0HXW0E!gjE)qqJ+FCSMj;0G-e}?_kk9Q10?8> ziDLRwDPI#~F=iRKn!lZMsrKsBP4q%{wMJ*1#~>aWc1k6HifwzbbNR zE>m>KgGKK%Safs20{#GVq1q82O2mvzv}?jPzjOrBp0+6L)}@IiiN4~ev65}I6<3;N z_V+Di@S0sDrnB$GF2GyeAwd(S`UyJJ>d%Jj2>)2&il&sS8R&h8`g z_P#F)|Jcej>?P{yXehG~k;C@Cr6qm48rE0Q=N_}Za6y>~x5vCxPe#4;a8HKb10mTN zY*G)7VQrc@E9{H@xD+^Tn_R#-D|x{;a768<1GUVxlB&%}MQ*n|Mz!O0M(Uv!oxjE6 zhcLoJn`vX%;*qFs4`bwbC7x#gg4PZW=!>8O?-O8f^xP&o9y%#F8G^N^p z6C-*)k+~YmRAC_w)q#2CzPMcVJ4PmKnB)n-TGYSP7eC-N;e=bPlTsJnM@>OYa*NU< zKZ^7kPUJo4K_;NKP*9)#1Sq$w^sXxjG_A$$wGFE`a+cmQTt22S?}U1N)q-?m^!3>cWvcg|Os_0K6`_Ee( zwR{4`e0BIlSHnJqDmUF4v$F)BYe=GX_R2R|;^i0oUc=gn`VkFo#m*?7Bw^N%%kCQx znV4A{_mxO<_@M?V$qRLiRq%|r|N5zPm0O!&)qn;6=f+X%o*C<zwU_Z$9S9yW^IWMWFJ&^BqtheTnTed3)F3dJKLle^xsD8WZL@>m0{T0X zJs%iG&5NnEJcp)o5y#=b0fHw$QhrK-x{)lV9GxV(VdDf%J1bq3-uvSad+Ud`?0Q6c z|HSqjtsAzB&);EiZXa?%b$4Ac@WtO!ET2kpmCk{YIO!&Ic&x^nU{>`~2Iyd%zXF^J z+5kGt8TDOmt8th+y+N?^QIOSB#99Ze__H4^`1$!xoCT{XPI>vcgBp0MxH9Hu@>tQ$;JPiWMkh*?~VvIIdlmFrXeZkTBN#QaWi8) zGU?@xHlyJGTdq^;k4k5YU$aM}V@!3X;g6V}QyR@vn(|O6(F{7&BVA%E4@EmPht}a- z-E3%OFD*ssnskLzzEpcuOKJb^$~Wy12luP|^@Ir)F8>A4E-^^kxywy1wC-fu!J6 zH|!t7sSVX`nU7_{)iW`A48uz+S<9c~R9gGjs+P?M9;AoXr`3?y#vMU&Fsw14RN5R3 zj1(@V9W!~xg7o%gPkkxf9N6badjqMEz~1_XVjFQrAr|TW_&wdj-Rl5iDZ|iScL6XC zWJetnweOe_>&-apF}7ZMrzlFWby4lCY>Uz#r!S` z0qE9?O-65ZcW$KZk0sP}$0)op7Alazd_S4J3|SGi(5+kok$B&&8i;VDi50|F4Vm!k9)8L2;+Kd*kfXj;AUE&QJ% z2NIdIpDsV~3qpzGWIXiqS?`%+T|{mE{)mnO$ZEO&sN0kxQn85_bkKCL+B2CQMU?lo zNp)sMHYO!X#%z!?Y{25He31ej%PU4a28ngWbjPk6{*q3TLaCiHkek4EiD!24xMiySYLJK1kM zc2ZH??dO^CI7Pgy6M7{4R{6VeZx&_&`)a^qreFzCFxMM`-y6u5`g;tiiO|{gky^ZO zrv9VMp|hRsLqPnPu&SKw;jq;DtPqtp--d%!hlT)Hf4{VS8IriF2!4Oa6BH z{ynWGxb>s@xN^1ZP#muDo<*v>1wR-gtLkA+bBWSpBh>{_<%LGpUZYI0y*428CG>Bj zw_~5IaAj3`^Usy)+SfZ$8)KzVSE;s-UqHP;w(P^u$6RI@2k+o|P<5LeY&;C}4Yo|j zELdG-a4V-zA9|B<)qa#+>Qo3E#pXn7D!zW;6&-n&CTOzSV`}W2E;#Q8ALvO~u=C~( zUc1o;du@M^9qE+>&CHk+_JVaq*ceU{XpVo-Y+aAjK6>vQ>ch1|{4RI1N!yM4PAK!3 z&Mk_W0l1pwz$xGk%Rp$9anlfoSq3kO#|+a367sFd+h$-gxsDJ-Ue=u_LM$`o--?>M zQ0feRxODGZh|8#S4F*DNSWu~O#=PQ%;MNzB^}~U6ADA zn|z!)3rdCVbzUr8Nn&C`YK=%4{N2Ag6;qo7Epg~0_g+s_O8bI$(K+vvS%9bNudHh4 zTjridCuO=oV>46*+J(dgfyDg~IGjjDLd0wQmRlSt}BdG&l|?fj}#)A`4%A74Z-L&h937-nCXf{Ve6(WBj%bmC6P zr81dZWx6{c9pNK+5xj2^z2f%hsKc6>$Zh6b%6D&G$*(u}UXQE`eMATf2v)%r8A==b z3yKUwVMG5t1_s9XF7B1gc}^?dT8a89OG6{t&I^E@KZ(`-TOG_MRk6zT9(Kp0j-4g0 zk#4}F-Vr()K?Z2PH=<>NduxSa`*u^dyZtf~M_P!NglvX%>!Yjcy%uxtDyaqQrp8`= zn1mi$oNmo|HiaFA5A0ZgJ-J-^-=tzvBGY7oG4CgX0{#*(swg{JfRDa#>QRgIV0#B< z#Xw{oDkMod7&T7NF@RQCr6yfm*@Y{FyhH^Auf80I3tQwJ*r{QRBi_G$d4$bSh8J

    Am_~^X`Zi<#BDQ@hR~o79U_g>zV93pC3S*^;rE)z zD|y8@^(H1SR(c(}J^~NDH}8HgI%m>iInu3ZFFXDVE)0VsR|n}$ojQ4yV2oW4_p^|{ zo9L!^xKQgy!K@sZ-grr?f?f?cJ@pM9k35LNJ1f5^AFK796yx|OI#Bb`)G7Ief%s9C zw4_OzQNE3~-)nCZGc!x}SJ!$sh-0K@Yf1U3-+_kaX^3Zk%j@T$s1W|0Eci+nY+sDr zLZVwK>-Nyxxvt8K=V}qJZs;y(oN9$XhoTYMqy_raG5F{v)Vj$E$SI(Bvr(!m!QL<$ zCw5l>w?2MR!yXE(8S~?T-Au@}rfM-z||hVFP0e zhB3LGcq=m(6Ufi;jJ_NxE`6*F)5GK+rUfTAkY|s#8q z_^k3#<+Z-j%^m2@6Y%0nN9F2qv(~^prYs{YBd{r8Jz4IUIFsS^Ox%)#ZI0Mmh<^MP z&9i8^sIseaS|_v)!CHN1Zs$ZyM4qb4?y#^we%XQfiFyRNUx_Fe|0|5o?+u8Tu`Pdi5SuFSpb%jG!_e# zLonWR5#^c#r&k{BB|&dSh9CX})wcB!sh|ss*5*3RlaZTt7g@36 z_{GI16?P`>e(2rk6?mh0R9QT2{;~=xFU$U--Crej;mtSk)+aIH-$d$UR=SX=#eZemrVI0^~jQ2kj%sanmu)$}<_!G>jADF0``J0@c{^9}E^A^>E) zKwh|qTs5I3f-zwO7LFwg9TD#)5yHez=dH-K`$k9kjNnQj>1hYOSi|pPVA{Haa{FmMLy?RiDvo zK|`@J_<79dn)vNTLoqu#G)5I+__x+@#_!m{Hn|zWlgT_Oc&fy2c?-v1Wg&Kjl#CLD zvJ?hmG3YKK3eKDN*ir+@7r=CLq%iE5VRq@_`%A=G%ARX)k2gztsdQ z8wcVdXIH}(N%9Q=8MEk|41a%JMeklU>a~`Do3NR6rMD^6dFi>bat$th8BnRa3H8PG z9f8nd1ws6q0@XR$A2mb|_ovIv{K;|$8~1mmMCpDoB@NFvvstTZ<9{auKI1?te=7%g zKCoQb_;0M@cr05Se=O>l3!iK);4CFByy+@28h3-#ubA%d4!X!qG!FJW_X$Z?Ab)N? zb^SPYYK0a*R?%PHCO9I3Jp6Hk1Sqc^ej75?-c-Y;b?UI9)8#$(maLDjVpwxSxBtFW z=+48Blt7~?y-)^R-HYxQ!glfEU)2J}W9wEPfvlpB(6w}fzg(TngH@_N#KkeBGd6VB z49ttaLm!=on)ieK<~yGm&w?fq(+?(DYC7nIM;)(4c$n&yw?}?{h>m=Jns2Dc_y7qR zXmzY7Fw%QZ9F7D66J;tJN*l;XcEV4)+$KR$odVXq_Xr#MD>IQ6L3La1LC3R*Xm zB{^ib#*ck)PeqO%x&nQ^N?ZC=6BGIdcsl6S$nB*LMH79!m@?x*>{s*7VD?L6sYcMM zxA0!N4#)O!N<7$W7aRFC4zsBYkvGUmKJBgOZR6XG=QfJ-<1^~T-AU5?YoSceM^zs> z=-mz|i8Y1=E`LiGPZSl8%(|sO9-n_j58l_8mcKfND@|Gm`Zh&dj#L|I-Fv$O7JeNeB%C9R3_}p_ukzS$|y#M9mf{C-Pl)FkTb2v z+dknqks{sPYrv{If~26zfz6D|4&~!dp3U|@4EdHqBNx->u`lhEKVe#n_fgwWXS-S( zrJY%^(scDB$oh6j2#MOtL~sI%gD>>>Gw0Sa&_x%c)-d2r9}Cf^e-LHcT~&4eye3b| zwlm1+I|-_PEonaGLu@W5fHr(9O4&Yy&uUf0oTa?M=9)R~8cPMO%*FaJvu3FS`rG43 zU7J;BXd$lNSxjb-YpgF(N(5x3StDs7VnwsIB;U2d40RUB;x>PxT@Yu`m_4WQ;}q%l z7YgRb8!`yvagJ5`V`FYkF;Sk_ey*|LmB+o+>JbrnVZ?bW~0*?kCf&YH+Y>zkfewV?W+6qvb# zx3w7J#6+APw`RVS%w~MJpVgz_i}WkhqxvC1e4AsjuK2nv+y2n<&?7N`D_GmiUydeE((u=b3-VPS^OyN zdDzT#QJcip&x?e%C2e5lt*O>y2wpGe9miTYkJv`&pnOgTCdr$i%phB#?&=MrSnPQBD=4l0AN+~iD1+|Z>$^?(jhg-pu^cZFOOK;=G(#2Agx4siHS1jFIRwg&8QMf- z73Nn0_(E_?w04il+i}N zU8AHS?xHY1#9W^fbb(Ul{7asy?%)joG19$?54u9Z-5QQ(6&%hR>4=)SpN`&O;>(qH zAL1ONA1tK(LyzWW+@;jXGAb4iGwE}W9@-|ceZ&14ZD&ns!kVgeY-Qt_BDBG2P7Qel z_8#0W(5z+yl3T+xl((}nQuA7{wu&Jw0zvgfJBY>cE*WClWxN`glt*|1nPgg=Pp+KM zQOhXpE({#wSczrQ<_WQ_f0qiWhG!>ibtJ(~VOEx@7}C(l+2 zGQ1{aH?Fgh4@TNj+i&xgXj0{=@sE{uZ5L2bQJO=^nIC#+v~%(|H_ilj%vxUMkRClR z)|#WR@K3_jaVlFWqT3-7`5V8b2nvJNCpv^H|EE!d*t(~VsY|O=Zoi7> z)m*}-lbt4`aOW}pZo#1YwXPKCkL5CZn=6UV9O^};31 zHGZ%jv=DE)%r}gDRH_*RHdm-hwN-nDx^bEElHquZkODO_CA$)-d#4!{?ELcAdiYO6u#fq^e^9CxJ4qqev$?FiC$Yg0!=0Y zxvgF319O&7&te0O;>N8=DjRFstu+!pwA{X{mni`d! zFBAFU-?_Po5xH;}S?SL^GOhg?~OvynlQG!nv`5LPZmzr!FE4KA3)dgb5 z!$(Ktw<@BY&eFrfZ~PUy?+L<@$&X%b`t@-RRj=$y6!I5pu98%DxF0;JUeSSybWszS zUmlqH4L<)H3=|Fg`ytvvJ~L7dGom2cIGS#n@R0u zlrXZY>C7_wU*0anzyP#=?_=d#10HP&_cko5k()+6agm1Ng2)MI6ix54=<7LNvSWTs z)5K(|?InD))wH}8ck4SX0trMHS885O8$}}W;nwHKChUi(7XCbVUS43seLXI&oENl8 zuGd<`Bs4i=eJonw8$Z8OywZr8c0i;D1QugnM42ns=)&B_l&@dG%6d2b$ME;&4vx9qNKwQeP>NERrwPH zONv^8MoDy@g=E5PN|haSHKDSM8cn;kYZ(1}YkobQqt~#HNPCf@@J>OJQ!8sM{-j`k0oVxN`-n zX!JcHxSb>L$mn!?kkP(Ob+{{npqkDG1MGjG43LU++2E^v5I2Ok=zbmGuc?=xFGPHC z;eR;Pf2&K}?WHF{F0?1wj}yJzH(;xV1$w5&WmGr+Tk6Bp zc>a(~t^79^*BbSzO$A0<+5OBA+J#?1&tq3a?n^*Dc)7X0TJA(OV1=&udj7kEBk{vY zD1(Cv?EthXhiI;qO*omvY)tkEYnQ8=zSz*Ij9v#D+%BEK0Fwpu#7!ohMi~{RL;(^a zU35C3AcKP9C2z&nHQdF~(6c;y<*zhQSJRk5WBO*a=&3r7LRG>yp!~>c9Si@1HoW2pEz1Wa0E$>u5LCB`y|8d-wp^{X7uQ0L z2V_;P`*p$!-0ePY?%3McU2Nq$7rdI()v>Mub@BCeCEQNR$km<8ndNtCe)bSDxj z7kVW5E0)FL*jH+9@kE~Xe#0=zcBRAJt%S96;Ge=5vhMKdBspi8V zUZQy91^lyjzIRmbqfxKruOoSQsrNmQFMB?rPU)+qWiZIJC{_ldM4jIebwz-8S0)Nj;*=h_4=L6Ta|q2?8?bDbl59^=|X= zfz5A94N!j-;dmFb*PQSIzun|Pw26(09%*xda|n&eieNL>q~N|yujv22mgqmOZ_C$8QDD^%>$mqy9&?^cS>X%CvDy{Ls7 z@opBMj0%#3tN>`YG(|gc+UpU;6{O7*j^2+1X}8XP(*_X_6i zNA`umK=ltQ7&6J6ARfhvMUQSErv{gAntC?)!$T$VKz8XI)n74~7Lesi3wn$Fx@GdE zCIXdqH-iw6GG~faI-e$VQ>{)#Q0(gIIKD1#O0@}K|{M}U3)2x_Zok|H?U zJ~JZAs~d%R!xAjIY0Ac4j=GO`|AyZvApKBKur{5v$%??Y4hVvAU+!K(JBA{cMSZlP zlLQ|{ik~piJrzR{W(kaTiD7IkZ#XU$EAQ$ZO~ z?#7LnP@i{EO(!1{V1y`!^Zc8aIjEEM4Y{9boM2=bV(yb_>AtA(!3MWm>oLC`u;UwY zJ%Q?Ku_yj`WFXSNHr_WAzCj*6$R2hZBfK)`*T@I&lv=l8(l=6Z_g7q4@V#HAdYo-h z<||+@WApDgEY1-XtDzkN%w@jq(!lDByWCTKTHBa$by$9g@5Lg=Do*k!bDc({0N1ms zkwlgvufLk0{<3~iI!DAs2kMXKlA!(nuJ94QwVtw+&?dUB!|qpub`joTxS=rIg=00p zBU~}?oK+x}2y0Av-_lhzw6o*%fdOByxqHg85EABO#jq$;kO?u2j%RS3>50BgQX@qw zY*54e^bcTDQrqHo;uak3h3Em!dI0j9-D6`~+^bBP{!kj~i~)EBuwe=CF5c_u*=zB9 z(rSzyDj-AW!X>kax1?EAzPJ+R>4Bn)ap(NAMC;1~ zAg%JIbuH$@{v{_T2U)abNo`PCy)M--F~mQ39cGLOY&h z&F20(T@yGOxy4*~$XHPHexJplFUYtN0Rb_Oi_#~v8*%C(|51lNdLHaYFkKpHV_CJn z&?T`mHw|=|2Irh7lMQi(n7t6Ggd?J(ps z|0_7H#79_f>RUc+W&yE$(PLoBfbZQ~H&rv^^1{K$Qp9YS5rfEhF7}ONXdgt9N`JnX zP;aT`mR4U&5_<8R-wAdg5rJ#P?vI^f*kHP7&L{W>eNSV%h?F(YUzvwl9{nPeCF}UG z3|<%zMv7RhtOX~){-b~&x;CDj!6-8NP7kNjb)^00t}8XS%-TsD)Q~Gr-Jya>jem6! zI-qz8U@5&IMx402*+8aJgm|D(N=+JSw$wuf8rKk7IM%$uSq5!Ik=qB2oNepJ%*~a* zp2>b`7alu6dVtJVQLULh#yb}*<`}dmkgF|T3Qg;l7b2-ZnaTp0m8TL|P#U2jSGUvo zN+N??PQ!}okd1z1AMzl)WHoxriP=A-Z%Tt{j0jIsEz$DoLR@@M>07Nun&G$7b;Q<_ z1R~IFTq|2#tLg7)Dil^Dgmrb0-*mra7tOL zWXN}}`OjZMc^&l+^r6`8+L`;ZRQDF62=D{r;>f4}Mrkq7^LfroDAD*!h`2d4x;VHd zaEsg)8AR~;qE8Yn3By~O{B7Z%DI)FoM29EI;~C1IMDpN@erRF2=-|eWtWv?CIKyN{ zInXS78oJ|^`%=aQOb4p}s9=l4tPin$Tzcj=^&x6U6ogMhmR|;m^@1C4>eeeJut47QdD5zgKE>n1ardsZ|^k?EtqiNe6=yQ`A-Av}V!oT&IKpg%zcxt?y zYV#cplUg|-B1fRo-}8ymPoF~wfL|AUhvjI@e~B#c#XyGFJKXr~4_A~Ira?$)N)$~r zi7r_R@e((4`)l{{iEIQkBH;Xa<_r>e20Z7&ny6P^`C6GC=%s+o`ict^vSt1!oT34; zxFL5B99Mo^u`n(;(z&Uu;Dt>6oBe9Zi_mK|Q~TD4!k=+r9eZYJed`$*Z4xbt%9L%U zA|inR9)+;2L8Qf|A7C(n$zE`SWoFCbovl9rZdAwt<3`l9e9v63;EYeL>U^ZB&v|mo z$3E3#CsQW7Et1p+e}p=M3*XGpW|@fHBtm)FPk5XCqD35d>ybm+p|E}a=o*g6Xn{g` zLr17-gG5~~j<{*|JUE>_XU-#Aux-y$I;5Q&`r`PH7i!EuIA2PGg6nADh3FYm_0ye? z{Gz=O+Vx}=49tb4V7)Vyaxf3UKvz!h6{jO||U*5RI%6Dz6dXPe3$?v#({g_Rv6WTQNB~ydTj zdyK?EM{MF{sSgL$RJ9}WjqppCl!wnju1|*GR2-|MQ6&ASJ!6e_DnVU<=cP?4-U5mS zku+Cb*?dsCLj)f7OPYgo*3PlLh41v)+!2$_K!mi}`xy5?ZF}oBhySpyG{0P2HJo}x zw2l_?-v#b%AA z2Im{f2w_|%dwTbON2D}ly-bM9EZHT9QC<(D1!m`=pNLB2$ktaKw3pEz98nxxCS@14 zAM22lY``yiU(I-Si4rfn#Tk!U!qSKn{i;*+vB)PU1my``@I#z&-V zsEmdqn~^$Ql^etD*Ws$x)BfHcEO5e^PR0ioJ+@|?nb8R^Cj>1MZ=SHvE4QT_Mnw6U z6YL@M>iYGFUgT+)xyfv~qy5!8;H~~}68HjPxEQpXdE!y@+JVqGk*H3Dt@NENEs{2p zmQzi}F+F_$9N&4wrvK2>k(@l`g)MtSOg%@4uPg&=H*Kb_tTOesL(ej9cVXVXVfVDs znD9&Y0@JxWHKeoYJ}JzuS;tOC0`BU#oVn;)$c?UDJBdD?0=%5HJQ7B#L=V%;CZ^>w z)_A1u`R!0qECa6pEtZ@iuks zs!Ls3N$*Psh+@&N?`Xeiqn|dgZ*QK!z~$eU4a3f?n6@kARIHO~OiV--s)Nf;xE}|d zA_$+rkn^gLo%1j+nY!}(GL`(B%OyNoLJ(X*Mi@s;(KMxUgzsn#I>%G-p2RM7=hT?? zFOU9!$C%ob1G{?*`1RS>qll=xSGeZUe?J{gpz`c~G8C-fB_EGJEiWG^k;Gv{`?_d|le{ z*Ua6YEV#JN3$W!yQ6$&~yAKFqG>FXg$`BbL4<`uIxYFHuGexK!1(a=sA?c4pC@1-i zU(o^RuZLmhTP-$w)1&IIzgEoMp!QCjhg^GUvbV|(P>}^c%*wzN9g})JA~%=1brQ{r z;5D>p2a}?xf$W`z91EskPGTu&eSUrls=EDFcW{u6*fc6gAsLmDMA3WMsz&f9#G6$m zuIhHDC&Dj$Lf9x4D+DX?7e3Iw=Ae8O3`K7+VN1ZyF1Hu6j;_P*g4>ORkkX3>rE;v> z3{V=cE$DnBFJ&Me!3RRaM7wFoe`VzUwA2s5|KsS}!M=zomJkoN-?wT6%j&nNGLXPtYk^0vIBA`VdP9U=Q+>pe0XiYeSiCF*Y&!# z-S>U%e%{af`FtGkeN|q9NLom$1__+*aFma7y+>9wyc<)Nr$XvJG#35$HXm7*@Qt!%X)$0!BPYbvxPe&Y~Bk>A=)kgHp zfq^qZC*b8{{`tzws^xU=jS0i>j}aVu7c2Wx`)BE7RfO79N|Ug;HS{C0snNg9YcFMg zk~*)YUXT#pYp{dJwc?=4*G>Or3!bWR}q-y zJw_aeeH2{AwJ2w*Wx3hapQjwXX4N^*qI)za*Z%-BSJ)u-idO`?`o6IRcwx4W`I#C7 zXwn@w(5jH53yhU#{!bN4HU!KhEVq-2UwT~t16fza9cv3tXgBX;M=ZJjSI)wl_@{+@_$}rYcFAfcU7SPkuTYQ~co1>`q3u7>&E?gke2s zOQ$ZzaJKe17zt~A83B)LHtRDS^w;;QQMt~c* zS|ZQ-5NF3+|0$xi^7KD5LzcNRPK|Z3M6B$rVLM6fA5gzV6PmiCF={5&hlNo5!|ocy zPKe#;ZG@E^HVozP%SNvC9O7l3^A}LVm2F_>PW3g*L0_F7pW?#hr$zi1JNh!SA4>=7 zaX*ZFF+fo)HpRM+7F7;%;a!9V zVdiuKWF7x|3xMjd0yh~S&5QTljEOd`JzwTNoOu||hDv-(qU}pju*c(>Y6(h46FTK> zo-B3Z%86`_BKR(dWiM*eFXKO)SWe6R!<8Nkie(VbbAI(M zr+(7F%cUn1^9-iJJ)GqCp>9-|DirXjX!EB z8ceGq={jnKZ-(CVl@N^b##P9Dqy=AWacj{dH}0yQz;?G6+zMk5 z%O>jhJi<>)Rm3gtIPo^QQhi4q!)@PX*+X79-R>oPmpZ#X2x0Z- zke zw;hWZF+yUPD0i)@$ZKVcF;*d>zuc)pBaOe*gI}y)buFOpJKx{f@ z6H5ksz9Uj(y0Z~y)eALT;`4r`(Ee38O(V&6rI7lffKXUohJMfnH4A@SfJL5=spYQ1 z)g`;71h0Mw2$vPAXPiLI?t;IN8(YX#jy)jtD2AKa<;x|mg&ZS6xCPpf+|e>LduiPaXVc&E zC3*E=r#4spa-lNl4CbOzq?`i<^GRc4f|bDez*|2c8J6D`?H3*JaWdzr3>=9jCmpIF!9<-Y2?n8 zx|l7{+a)7E2xecGrz%g}MSkKdTu&<&*sx~9ckG~Be}R|uC&s`Gl$u>E#-3Uu8{8L} z@$WEOdp05sc=T>mWlLYpgA-x=bIFQ*i|!xbdq$_LjV&85IjGX?x{boAK(8vd;3Q*H znrts5f5J57Ekt0{TFQDq;k9(b<|n!<9m@a3d9aK!z76PZdW}1S3KK)_SGj`ehu%QP zxv{v7Cxu;X63E`nG4PrX$9D#-Y;adUn(A03tKv8(P-nd*=3$|5G+AU<+wITGbZ9; zGnvkaA;YHDzzhk3~awr za1)qMJS86#hcTEPHxFZ7cVCWTeL0E#Tbw=#14YAPt=Cta5%e{q=sNSYQ*Y#2I49V2 zRj=SS{@dA$`v z$y{~c{z$vp1mV6a<7vJrckT4a0no~uVxzGPe{`@S`l@_L*?_s0 z!@mV{EJEzx186j^kWi^d_j5T!F7cNv#};`_)ipNzlqB(za6%shnOM5%sHhKYQO`04b}7yq!N7 zk2L9gHiAl{iJMW~8b2fSu34jdFd-9qXA-kYB924%amnU%F_>13}u`ObdF zr7@VJB|#0Zcoj_eG4_6fSbU7X7+R|9l*v~eU&K@gQ1sl7IJXm-`c3y{%T ze_}sRwk14L-OZEWW$x#M({8NN!Y<<#>-Z1w0#Xp3U%Bv+cRMfoeYX?btPWVYC$;(lc*cOFwjI$lW-c5S6> z1*<!Gj0!%P>J^kk{JhT5=DVc zV^VO*{G50m91^Y=W_%zp7jBuVu06cOs&R>Iu2N-!TSHFbgvO?=s}5MfV%PRxTX+w5T0irY~>f`krMgErs^d z*P#Mx9d&#rL4Nc8xs1{5Ju#S7h&65G_bqI$=MhH#c}K);bm26c7sG8WxHD-N4tt}; zjAWuWO17${J}-Pt%3R0Sfs9Op1+wT)eI?*r-WSw@Tf2Dr3jH+BX{2DPh7yfwZ7l)aQa<5~tB4d?4 zjA0DxxvUa3>o1|~;JcfhI)gX|z3x-W?pO?zMEq9Es6?>3Jt#jR5uR7MQQ>Srxw)t_B!?^9{5bkwQ1sMwE+{$uzayB9@swpAnrIw3|T&H|(Yp zZyAjKR=Tbc%!8U3)7EMlI*~v2#OLu1d^DbywSCzBcQE1yomo<^<>vv>1_~N-TMl zOB&Y~!4R-b>nZu8(@v4Qh7yl=IRGgAM-%_TOujN>vB)o?l8osPJf4L6JIHt$4nmBI zPA#y{e7;AxA*?pe7~8i1Mc=8Ef@|^-dR``gO{U(2ea}~p{fBjJl#COH$idg}{rAm* zD`>35v1W;RuO|DHn+gRW|V9_yQG zIC7Q3`WjyDKN0cnd60l+IU6$P`??yV!SS6!e@vAs7hN7qdXc!dFEGi2hCP+F&|l=- zV8pF`2Y}8UT<(8ruNneyRW;}JY2gqHbhKZ+t}`OLgw)EXPT!%lGiyZK$ox(iwVKw{ zk%w6c+lOVz9YspZh9C^!Og~!tqeFY)cPYH`yPvN!?BD+29F9NCub!`NlRQD_|8-{; z{(Xqg<-3HWvgAruIVKX2!k1i(`yb0A8Us$M8d-uHKrDt$cgv?!i1X99J9UYO>;f6u zLFg}%N4`9&1VQPYb}B9Eac*yBu^(!q!?4yJkF28{E}b!-cyI(%v&|TY53rV|$F9AV zs0U+1!s~d;!tf--5p3ar_{sZmwGF^(b>I?<&mowm?OgTrJ0h~fK@{Xd7De5FRNTeO zJ6=oT1*~r2zDWq*TG?ga$8pe+X3i}faH6R6u0*EH=CX~vOyJHgkX`chZ!G!EMSmp= z*OAD3&ats>WhWRViJ;(-y^O{-0Tm0SG@fn>k6$9!$ni8 z+PFl~`cjGzD-XpZjqU!&N(=uzAmF)j|6GNL?Jv`jdm}I9QGtyOTHvjt@tIQhGlXA` zoF5IlSLS5SiS%TqX3DwRdQ7R!t*hLLZ*X|y?o`I0JK-x785YaM+L}Df zd%jYbKdZ={&+aiAEg)8i4@FEFxkp@cUo&g+@i8(FOnp2IyIB;ix;0WeCTq2lByOG1 z7_U6md3dgBr^NL5!7=6a!H1*7uS>1}aK60;eoR&~&>?i!MfAq-jgZ@Zl#0p7(>_}k z+^YbH?6BjuL6?98#+w%fj*Iz)C_ox0tnNm?g+?`p0*8byNcOM*$Ze-L{ta{3;cE}<7d zEsF3E15H1bMG2O_npToHvv+SEMi+bbpkwTeA5B*q%$cI=b%Y`x7zxxH(QyhZvENPT zcRD@tm5^@`aVs$;n`S-*qZ4j0#}5mV?_C?soiY~~#%T$7*MY83xNN|)Fu3<|zq*e- z7nC6NzU@P0G~<$yO_C)0trpUfW*pjmUVg2!gHfCld?og;{h%O9R+-DGbj&S7w7s>t z#*yYwIP=%A`c z^lx_@=pE@bM`$T<{0gD{W*nJ`beoH2m|dHLEljUIZmg}4`faCJy$L=k2`YCGsMc?w zOu3}OOt-_6BhM{@rP25Y!4nOPfJJc1rJt>D0&UAZm&NRMhjR=qD$jcWAK+HJa4SXZ z!HXd7L0wn%(KTgy#w`>gh zp2YLZSwCku^;R-@B-ASov>7$>1h#ZSnqg@|9Odmo}|a&P_k-gLT(KWtIDsiqd>|_MuxJqGXn>Czq^ z(z=^H1=F4h6gr}UH3giFp26bxIl{*iXPdD3C#?oDiOtn6N;m6vVuNAEU*d@v$>46j zHsAS{jTy>3m*<6hvlh~vbzN!{k;9F%Sx@I62iygmw_Tjma~7Gj*=1)LW_|AP=Q){2 zXAIr+mnK?^YcOMFhX`}7lvNmA^C-tNP!r|BOLXIY6XBd`3P$0#bf{H-yX4YCec;!W zC&5Q&BT-CD0Z%WD-0`pGc*Q%CleJ$Z z&T1*!ZcvOPn78Ro{Ipj?sDr2g%Du+w{n&WuEZ>|L>z+0_Lim&*Uq@}GJC2=dCAY63DI z;hrYektf@jG)_h?RM8|qWZ9d~I#rnY8cdSQy*y^L)<>KRGR4>z>EX}6QSHXA;Js=& zcadYBGvWLov}1VJw^4nW;1YC;Vr*Z!Y{8A+x=xw1K1EC~9jC2Z zG{sq0(5tUrS9uB_SG`wUPn6Z65Q7ZbCH2u#TA?W3QJ?PhzL4Yuc>(#iJ+yS+N#FlO z@P1S*6m`s{7fj_R&HJ6TEh=&}seq=ZumnNaClTyz_NoDz0<<{efS9=@yb8qJA zf%WU;PT5yy&NUtB-c;_SH5pwS+G^LO0c9-tKUUS0lIbzBQ;i0 z?5E$=i;aKU#YmpLPEs)Sn3bUCT$NrdhE*uc`2-iFGVZy6lae%%=)GnhKlmUT*!^*oxv-3{bGuWARqVpa<)TTC0y7G(=xqnU^XOq09c0Gz zREx@yxwJQn@RUb%^l<7dT~11>aeZi=o0QV%G|hs&yr4SyTPdYw{*-Y6HL*L z?J@G%#nl)R-%J`fK-k+-!Xtjb1x-*fhg|AI?xg-gTmtZKJP?yF48B3n{$$t&UXjA#I4 z)uE;}P|aC8gzs!}`5Eeg(AcFda6<{dXuGiON>$)BwKZUa&Cucqd`}wMKE0j5`%bL6=heU>k)BS$W#cg}58Ov$M78e~6apM+h zXKY`A2aP{h?Nm7ftXD8n*23o71i$4cVsTLxf}vdGWsK?PoO$~=&Sl|o4cP7Hm=~}w zgee3KKkmwQ5_6LNad%rhYgZ5$gDJ3CPvtyg`OLsFz@PMt7^H>p@c_Z`>^E-HMTyn? zU!Z$x-yCBz^*yVE^UWErz^4ezFAE4tpz4Vb;aRxV7sy8OK@a638jvMr(Uyti;#b+^f`xCwFYjO z(F<d)o9MN^q&M4;WPD6L`-vZ7OtfLr|JAel z+3E~zTM|Z7r1wdbI-7jmwgfr}RrMdayrPcaD?)jV7R0G#Ys$ibQYoDE${) z6_0g!ei@|j{vXQY_jcod%*9sX_V_;@<`YxmX&JGYNAl1b^6lf5YC>z5ooh5CaKKD5 zAEw2WJdAA!^qvl0LiQ6cG0mqfY|rA}k%S0eix^Bc%&JIjr{r)1tUGt=BOwsJ_zT&3 z265$hC2n&o(p>s*9~X3i%B=+`?e#+WRoN<@Au|;I8R9DcGZ?W42hCR&G#zKL{j4Jq z8rc7{^_0I7pDzs;wXro&Rux#rwsDBV4g1MTw-@BB;zy{DC{FcT>FU9yMK&D1qML%&2)7Dh>_U@$F_ULyYKn2PPXcEGJtp)+Z~ z?>X?zZIqoA=rosLEb2V}%14lI(&e6Q=0;7;xOlvWq9Z#8)qqy64nW|~zK-Juno>E+ zRF65$YY0WDiSpdcYGTk=D4}aN{aWHv&}5EqJYN;?CX0Jz>1~QUfBbRQ&YK5Nn<=Nq zGZGKB7=BQXpWup=^3^&v?{`aa!W9RbS9Ec`HLovS%n^^ZHUEytU;0F1+h2(tp3Uxf zrfAqc{AS?v;mCnqYZ6gN&siS*5Xcpd{fUM>)EPv4W>#kecDi|feYYrtH_20O*0i<9g@$sAC!ISR zEZAs#YQxMv99ToX5!SuHq_>f~*mM`i=BW%F<>zwYsx5s0_QK|9E!ZMwR*UWjD3=*y3;oc1LjR zR0z%dHD#YVD3s;V+Qs54yug8eVE4I4^2zz@Z&Yw?(acmm^p(YLDC2P1Kk|`HlCRLH zdRQ_k+Sh3hymORAH?}MFU;5tWoSkw{sQ{?3<%8_7My<2%Yvh0+ zyD!qLe#Km=p6X_SGV>jKXqu{#B$gB$SqNIg!5~9Y=hRoy{zmdebZdfSL#01%@ZVwQ z*i$Fi>NxJhtxI>9?9B&SKbdSGTGh!Xb8|+NZNYvEVaU4E_4nF+SJYO1a@{5>`b4OD zGc>(#6usHC2L18PB~|V41==M#v8B}?e%=*tTmN(ETMT$NK#f(5KBn^oxCoDpd`3`<73M?LuunjFvre zT-;*y2RQgFR5kEfFojA?A9>|n#JE}~Yka6Pt+W!Fr3$^W%nQzg zYlVaLBa3|x?15>$m!fPdvW+;Hp^&fJV| z!gv+X3=7RP<=WFVT3@_kFt2J!%X(1ncY@D0(LEP-s<2)h!hP0E{P3Rr8(>BgIpneT z&(=b2bq$d#7dJM2L!?{0je=*-@3nJm+&(-#h}(mL_ryrY@NOokYi?<%VB*dQps8D> z*r+<}*i8}>4h7^;5L0wqgXL_Q<6 z0~gQf_jt8oB5wIevkZ8z&TYT;^y4O`!vxXIj zl8)Iz)~AV3#h)?vEbdfq@`PMllA!iT2KKepOAMAw|GTU?9y*^e`g@fy;MrU(rj_;) z*J3iIGD36yvt;2c$GE@3^vv2E6IEU;t9$;f&AKX5t#Dc40V-YGjU!tC@-K=eosF)}~f<6swp^MnD>p#1m+Oa)K@ zeG`V9yLE|fB2{199D7I9i9Ur-<35DAB-W94M&Wd#9ufX(AD}X}dp5)6X8T-n88cP(NQIeXl zyLyz1;}4LGiOseAwB^$!EHxp$Vd`2Md1E-P=QBb2m)L&+rB<#guA4DpV(z$6t^jg} zB@JnC*wQ9S_7canzzpF&0bxNB$ujrCIDth7IQQS)OBf_XouqVO5UYlqJ! z_=jP3ym_jk4{0?kwv-qQJ&fmNcWv)Lty8rRJ(TDZed_^pN!%8if$*4Em8!@jG*+D{ z-`lSWgpV;npv-vGU)e*v!Emz0Lll}x+-k&&o^Z1Kv$UfIXIaVGNH4gLRNSZ`d`;)s z0k5n7sX!%NII@HCT%FpT`9PlK>njEH>>EeGng^CIeRuw}HuNqdJds?QVz&@T? z^AwRTE?=9fbWfOU67eG!${qBXiKUcdyei>ded>!OjO|H<4Hh_d04R_7pkRb5en@{P z)7Ho;N_k#r%_ya||0sq~(oVU*jrH03UcCGMlQ%f>OK)vN_IFKc1;0WSxHn(UAo`Bf z%Jb`)>dA{5V5=|5HoaR5S)Y9M-)Adb)$n$k6EC*W>7~H#L<$;kIeYcu(b% zs`6Uwim_)@cTZ*FtI<9c4xT$nk;0CE$B$6+s?&LKQWrPMMOEYBvCfgV=N(6joC&|~ zzurxCSOzt#|3_HtMii)ohda+IV-GkZB(8*^y3j#3(O&w{K}XW?oWbPJZU8P5F3@ei zsTLrik{$OEqhTa|ui$XSFa!G!NRWD12--NX&kp_gF@+9Cy#=7zjLHc#d9?UU9E7+IpK>2wH|gIfiCDir0RO9hu_<1KRe zmB-k*NP`*cm&Z)HRL9@kgmwg#Z6jn|&{W@JOEL^-k1&pH52XLm!wmlCJFx#|lQm6L zpe=M-&r6zH8{62H_n;zkh!%^bsnDfN?}ILmHS)35_knajRKRh*GsuJ=X(JzI ze#%VZ*{ZZtnaAFsaX$0%2~#pJlNPF7j>-yBg0Br@FwEOi$&CKZsanfv-4j}T?hh99 z#3Z+|8Ki@~f{9qda2@xC*}hK-j;oms#;oykmScZ31ao1BBsj4KqXPHKg{dL~)D68uc8G zFlwA<0)vOf)E(%dI0EB8{cq^yG|h}POU)NjzVe2$L~$(u%Juf`mstwj8nG)nr94L?CmjmK#P~T7LxbuYBi*QP zH@tBwT?{vpfpvR3AnUNj3u(&y3O}g@l@m35FVgDRc7F0xr>(0*fqdczaj7=w?cSj1 z8{DqI(65uyg@d!fyRc84BwMg!%$CrP>cSOuV0n#fQ|Gwj|K-JI${veO)pJE;YML#t#9?sbN2b{qgSO}zw#xh zUJ9Y8XrF?8h335T2GDgPi&pf1GsL4bCRP42@4k~!h>q;*O8;0SuJ}GnWXhE|WC9)^ z5Z}Qjf=)ye>|q6yb5R`6!<>G1@sIrp}xVe3d{ zSRKkh7B%QMWq7-hpdEvVVhwn<7-pHKi>H?7BFflipbO}iCO7GLmo6Z}4k_86q05zC z@AYOcfu=3&T>_Vo^kGC~rpE@I?Lcf6Z751DRA;o)aJ z83w_c^4WkX?!TRO0lP`jJilyYsm_=aDIFrNvIeoeegaNbs|JTT<-H8jziwj-u~dgk zIf|}`=8-=1`o0tNoNmCJ)tRo8e|hp63@~lDjZ5#do?}+by2~&;h5ma7HAK!Ei_Ue)Sk?A6;*bv)puo#LV96gF7+@tHw zf{wrn7GIy*HR}OOdJ6g@?sTQ4 zj^fgOw&gIHbtYnncma7+VH2>?Y0>_sB7*P_iJ@oIRlT~hK!d8q<>)FRRK!5#Oy;o< z+q-=IvBqN|F|2PaZYyZBUT*V@qzUZF1U_#=79NL;e%_%H5p=pA*MaAu=cqfq(qQEU zWO;a}{F24(CNWa*Bn48pz`cxRKsN)4>-!*Khz-CI<=3H$dBM!V0N;~CH+-j)N`^U_ zqVTJKVBLeiEWu|wv_Ab&{4c>avWf6O75EHdx(b+!50%XUUn+;X_d zH?*OX34AP^{L4D8muAouywreLF7bAw=t@_g2c{zd9_BRMlBZkNRLt+5Iw76Q3l8Nl zTO_!0V)GD5_a-6|>vAidT7{7Yjipe>gMqnAMfws5Ysy7e zy-JG=YQ6<8(5SojBH*GsHiy7hLO(krRwt8!f8^7DON>TRKjGm(7NSd!e5u1=iFOQe zshOPlKnG*<09>-WIqCz`QC{ectASpk)J&59LtUS`AgVjdSdP8DfC)9E?dlIo@f{nn zt>N!9*^v*}7IEes!hr-gZn82>jGKu)+C3ws_xshXdd+E=){%LwHsE+oe>)w%z-{3e zT~{TMesr6{52gpcTe(<<_EXN84g>dGJZn}#OfKST34^0@>F*1R9BlF4;6|*8O1lf4 ze1?h9ZPOKb?biE}%h95RI=zNyMob*H-_Nde)OK)jg!g;xk3ul34)g}KJ^@K-t@~?a z4zx=8b(d^l>k2XjjGDmXqv- z!PkLx{mL~+oVI*c=V%fm)Tt!=Z4ItGSYHA92jlK$=Gr|Ba2gXbW!JmDMCd5geBg*4SiG1*Xz-|21-O3pLW&anArAA&6_$TDM}+f{GSN4l7ffPTqiS`WA`{S<@i?d)s6QsVjwv zy7c9y^Psk|KqI2vLai3DCm+X?>dNC9XPWw;$(!?)L2Cn4hc0`y0ufba9H(Z>}E1^N}X)j6$1xR zb|-7#OFJ~9au|dcCFS$_@+vOIK9lgUC*08bhN^h0@1(QuG<5gRh&!6|_7vZMxomA| z2y4F3AhK8&6L(#A86g+YVB1rmrxY+vaK7@{@p1kH*HId`Qsld*coWS^Vt?c))u`!= ztJHRMV>E8h{R8Yh);vfo$s#9CSC~(ib73lHe}$e+ zzM}HlHqiqIxk0ZVhM7F=45l}OHR7My*ZK1oc*MZ2rq;BpO1Zv9M9mTzG{pc{{KwVa z$Q&PM96N_J?t3)yceb1IKYBDF!@q|AS40T!jX3s{fxnE;K9SghctD~ggbAwT?jDX4 zQJG;&7AxxwbN@w-D0Gy4U3-B0JzI%t&RG(`cyd|k>|4r?^m&!1%7_BbB;EWJoI_em zp6&xe@G%XBZA+{#X@U^DhSZ<_23wjVZpMdi9C!v>Z1-Icn!A7#mt}U?#P!jEDMp8Y zrz&&vMfRZ-(@J96N9Y%vgjC|h7A;j-^IO-*$68og6^0tvkevgWHg@u*Kc9%oH7zBZ zLYb5xWtx@XN0ES9yMBfV*1;V9te~#0G+drQd1fWxd;+)e?ihI~N~HgCot}G+205%b z;@eJfL^=yN1L}sf)9cray)A*H&w1d;g8u}4kIL^lH^OhJaz3p940&;GhceO`v3S%Z zI#VxPQCx&x7t3((&GQD1Z595)j6{+JnHrMo#itG-N7yAf6y!=ZLL9vcRI9NG?wNh)L!^#itpJGmO&l!;X4pXtel8`oW(O zIwLu#%Obd}_r+S%C379+8N=MwzAu~ool$%x!3?=)v&?i|gzvPC-wl~@?(}j zGAj_15aukq1cEMjc^q6UNs%O7tu+1LuA1vS;9i4w_RONO1 zWW=^UMj89rd;AXGIag$?x*#>%VLEHk&(Q-DI`;G(BOF7>xvdWt@)%|A5H{be@A0gq zsnpxd*ou}Ja;ub)bVOwTqS6TiG}BT06Y2vs@mIF4(O2b3w;day1b2ncr-X})z0JvY z*UG88LG!)lbRn*JK{UZakNyc~N{zxh9*But;m}(+on)&|CYc%M^{oo;P{QU+eYl3A z6EBy|qh6@aH%$dAM(u@m#I8rlthF;$H)vko>u1c}rw#wqFY`4y{T_Lv!+#NHGzl@G zO$*KVe_@jsoO}jZs0^fWQNAj6lF0eXlz8MIxQq|Iv)_H)N(1=>L7A}@6E&S#B24G^ z{+VQco6-Tdyj^k1i&G?4+@z@w@J0KhSoNX(cd2(W@Wy9L>D}0$hG8T_TBWi{%71n^ z91DzQT88adRB@pyUYuaA z2%8Ixtg$AH4b53)n~XFzbylSPj&$#q-Ua7OA3^2>8r10BtA=fOvT3~^-&6u4scnU7 z@O5~3<{acynki7+@##UiR>2Yrz8o}9MsC$-tr*@@e2^0WbkV6-hjW;_U<9j;ccTUB=s%WU6)Ji31jmMsHMvm73fSFJ6z}lLOwiL%%%nWUl(d zZ&d4*z1&=^R%j_&1+uC8k{%$jUdN`Ya*ZZeQ7hQj*Rete*UF4dXvoKph}q=#LlD91 zX#338_$G{PGWzolfnoFhfKJ~KTfBFLq3yVeR$+Kuf39F%^b_W3Pio3hALVx+o~j)c zc*S7!bH`-9RQ2DNXtn3suVaEV@i3gsI4rBUtNI%Jaut{!ymtDtx*DCkRd#_#xqwNk zlW%bASlmkUIhrDln#lB%|9y2>NAY>JkIVaWB09hBVTqV=09^XRvF=LmHD2S=i3V=UoaOfY}z9#wGiW!2aA~= zBIP0M%>~}3Ru;fvW@oX@`sHZQWd-Q6FK5h&J9?t>5n!_ujA1wUhp8RUX{tAXy;zrr z|HT5_VWvPDO|?t4?J#2G`*$kA1GfJUy6n932yrT7^=z<6>44rV-Bn&EIvUJ^`@=``XLH4!>DoBxF}30d3;qCZ@F~Cb?z$g{Q+827g9Xd@oB*n z2qRCS{O7=M!S;H@-bj@<;R1P(;5Y~R@`aw8%hZP=`Vs-=H_AjJLjKCB11;4+~fuV%XYTV0b(!IM(;SFP7e$9(}H#{VP0D7wE ze>^|+@?|piZ$o*iKiM%T4}B|A8et3CnEy9!UBRonkt%<%Cij2jemQq);yageoy*7% z45z}nS%3?r&>IT$$vLtr^+a~~o{m(lp`EY7C8}53lJ;>V11X}*eGwH}nFhml>Sutj zMU9#%4gV+}D$xZ4fm(7Rrx*K93n)GXyZ}&D*uEx0p{#>|;Y2-BuIcP8l&=!1K_8bH zH-3>N#f+=ub_DVhnV8?$f4%)bWsWFgw7~z*9@Qq^H@7WWD2~&*7@S!nDkP$s(VD)b zNj=|2?mamtlRzYoC2uklS*Z_*&?Sxb4boxl62CNN@5%3lwwXfRhyhPMzfP0?|Z-d z^Zotjw1?gI?(4cbTuQ-JsCd;8CQmA0x2I z^Zn!IZV`+XoVJ~#u|OE&Adl)XnP0Y3Ca&fc3+L5APzV_}FcHG^#ar1>cm}V-eI2gI zKT7Q%?bddk$AzgDSASCQr-IX+i~3oUp^QDZ=k=zeMe57YI_5w6JX#oo`W%l z#=9NQnVr~0THj}5|C;}9nU?XtP;dv7#(YTLZ zVmT#BQ53LTz-_7x)R$bCPGB0AFt7fY(_1y;bb#jecq{6$(;>2zMm_Dpywa1@A%q>a z-iHj0nk`SKoK4XO|IG33%fbXIpWCtBlf|Ryl`)Ygev^+x1B@1(|Nds8J~2TfU&Ly$ z%@cgrpwgYVm$m<%t*Un(hJ`#dCk~U0)F9cLN)}_!5h*2%AF47vko(grjLSlKC~4l- zlxeQ^>_idU5_SzYx=J&PhVw8EQK95=EC!lq^cHip(a#SHN%owH%U0u!I8Hr3tSG;S zcJ=GXgQiJi@K8wt*zsm+o0@3=$G(30WPNK7w=-8=+aob{X)he%6#F z?SsvR-mh<7-NDk}J>rtR)E&>PEtUGX4hfOsh5LD6%P-6<%|Peq5%zZtg(Ao$?_rR; zT)uNv(0kVccW0u4kM3c}eXKB0xE>e6wrxG$7gJso1E)Cjq(cBq6ys<9pXy$V%ho@sCDy!S??n;A~aX(s&-SyX|HJzAW*DuYCCDAurJ2ob+ zC$2sKn>t*C8V6F&u=Zvzisir#H|MAwF&lTWykVjiM;!8DF;`dlqQ`^{*`D%}2*<87 z^8cb-UJCij7$pD4s4HeAbkdna$$*j$)vp!AIf2{;468@wD54ZP$_SVp=H;YkIKWQM z!rqTvC=3jb2v=O@C(osk7S7t<0`riIW z&_KP@|ASWoMhm0o!lM*sm)Ntj#~5l?RTROFM>++bufBuICNW3JQ#y8<9pKeBWg(2f zj$zJYryJswckb9qx}2b%`*$Vzsp6g5{yArR<_i7^%YmRY%}7j4XOH^Q zH8fikO+*x7Wov;qKkP+vS>6g#p%K{>%jO=IR@2U>Y6AO zw?Rp}@NN3omwxZR5>Vw_Px}FV%VqOp+j)yY17B8p*m2Z7OA^_?w%~E(+9uTdq%65n z7ba`*n$5@*<#*Hsc?w}cvYcuH{Y&Ceo0hsfk0&fP7149)Oi1SD)S>+T=RN5!VrH)8 ziOibBF0~x#IS?pD|4tToURzjPV z-USbqo+&*=KVUs#7Oe!ca(4T3exF87QM;4-S%5<1t>kQPO4L8gI$_A$4nJ5z{M6q%xAc_ z;4++^FMzJ+AFUaVVLGoI;95g7;bBcgi3Bik)&=nlqCjpk?LJB#a2NxA%4=U7ijJ*l z03WDRRuxHJC1IVaeWnsAVFwaRq% zBo_P${i|_Igu3aZ?VQc0b?4p0w4o*OntEPnY+{QJstGN}mNH_jJJ2>D%rB z?re^Ew=+dO0muzV*=;BSX&vZVNNo;wM<(z5;!J6oG$#$ydj1DrA;s!eeYbXGJZ^V+ zzqwmFY8u7|E?c2qzke)u2^Z|8c-L27!)YA5*u3y#L*>vfCVy)YsrKCpRm5Ev-{?S@Kwu++!l5 zUAF5x>!6X32-L(~_M52s>cInn^(x$1%%a&ytj!H;%(}5}{}4ifl438qKlDoT2z49W z0g5jEs_Qw6o&C7bGo$>1WhU;Gp*7Rt=k>oO>SD{5@RYN7RCBJ=v0bvW=-1QWGvf;e zwSm<~wq-m^ecfY>-&UIG73-e-M=S$m{516DWUz$0J5)00NO zVYO4XL+<0fEjOUk_t|LVsr;8H3<}YpMR?PB!)26A6UR$U*OK}hgYvSNCR3rK&$UHf zQ5Roo^u%4<2ZE~Eug~rzbA=JZv~oRV+?9jNW+$-3O~UYB51ck|l85eUtIO&AYllC` z4=>`D_1;$)1$+?@#FSD}e^guHGfW)GX8irQxRyD2kg0TMoSi=V%Jzf;;Z=_xmvo~8 z-~De6jmimZJW@goMQ&;LQATKy?tK-29-KRbU*_@gxf9?5W7^C$w0Hh#9+@Z79;^Bj z0S#Ihit6j<;UjLmxdVkCA|eA>9MRu5GH8-aw42*&c4RFy9DsLu zDFKI`iJG>R?K5_6LfG_qVhN@rA3)2+3fb+{<8{ktZD-srhP!Si;ofSDs!7~cT5cxg zn@~$;O|Edd6~y0EiW%-PCWZM%fk@H0?_f7+NmdPf-%hAD_WCt~Pgmo4US@Wu__Rk!Du z^25y{n>D?DL!ZZ@m`9w}Z9^Vb&QoN~oN13Dqz?7GW(VRC!Lc$Tn*EFE%NV^Q8>IuU ze!AQxOw7?-F&T*8V9s;|7X}Re23N<^mFrPZf*@Uz?hN^B{=s$d4LOF-VL6iY98#i` zdmD9I@nmwP{gDJ|q$yD8$H^E`{XlihU^bB6c_NjEJghJ$sz@AS z!zGGG<`Av;b})97)U5no7WtpzS_&=9SGULMy%L*6R@4CBCu6T_7~g_p&T5FqQSv?z z*g>6$QuRY4wAV4;k|JN+)HH(U1><;?jDUI$@X7U1u+ac>6Qzz0C(HJ|K-kRDxMG1q z#&_F2N;{~^ZOM)@8_Dejr9OJ1xS3D7(u2^~p6>+$963Q5bU~vmn@@m~FBd8Jkdzfm zqbhRe5bf}+8H@!>l?bE?y`ei&=~$%FyeUr}t9pk$3+1E~{bE+HErd;D>K$;wwmVXYizl z#s*y9Jb5niekr}X5M$%z^H~*jKhWhiasd9~iX!h@;rfXibGGaxw)B-7T88R+N$1j|ptoeoevRJ0by?=|Z<2uC9G$-jPa5m~Jr? zrCzxhM9zzJ@6T0GW*YuW+SRM_GSTfsmF@jySOVI4Jr{gimsY{)@DjWxhZk<{gCDKW zC3U*UY;Pa4f;S?&uLBPiyIU7d*cM3VgSR;_chZ6N_u`lri-w7xe#VTklD{aTo(;wv zoGK1a0%KAqS-i3n2RTw=fdR`;H#|1lKs)v;d(5{FVF&E?Zc;{tJQ!5-ck%+<;)S@0K=%XXNeh>cX1q_5YIY&*7>?RO6yX(9+| zPybUL<<@ASr_5k(7^~A29NbhE7kkcMwujA$nG4)ev!_O*7Csq!dqsv&72xk*n9C3Ph_@a4>RogaB*iIao1V2Ur@vw@w#L6Xe z=s7GAMX($B_V5&spiMg5pqfanpDTs_);m#IdfDIh0-^{Q>^dH&d?+>Aj){X@J!;m+ zmv>lJBCe+qxzf9yZ=!H0UdYCfHazB>zTTgBh*_|oc-gO05Y=U(uH5->fO#cDp{G`K zE)|YJ3X2Ss%;yX;0Jqaxg+Tu4mJsPWq=c0RQ-V$Xk=e5CML+;@*=%baiQugo?SfA~ zrS9CtikR3h-5-a7-v^CD7VaX2>S5b2q3SV39z&x3=3tR!8t@5z+oY4@jBk`}&Rbz3 z;qG{h`UBWNNC~k1F+F1r$4#XK1>Ptel708t!_4BH_c>&(FtRqn`Ko_^cicmLPxk)= zKM**jvtPOLVMkwJrP)&JEE zEAg%w@(|B1bh`PB`#t6^dirXH&*raq%ln5&lb-Gz-3S^C+i5cAWP;~6OZ4duV8-f4 zTEMEhMHjN9CbL+=MMKm{e+Qf%L!CEFI^pjSbFD)Moj-sDF9zHM5`c;owB!Dxz)@Zd z_e;E}X|GES+(C~Y?rF{DO%D1qiY8-BqK6~5wU5OGvBq9!$ZWz~y`EHim^{X`e{NwR za9Wl(?2JVGJ|7;$oTlenH0uC1{@`N8%AJl+;I2>#x1!)ba*EE@8HcgDv?y2B%C1n? zdI$qb>oS?GNi&7yTW3VR!-D^N<~|bjNZKm>!5H&6VRQ%gUBzBkj@0NGrg(Dmu^`J{ zZ|Qz(xP0gTp3aX%Ut*=%dlO(DK=MZD$!44-J2^gf7LvQrD5W3*!Uv)YORAH?Vk;JC z5q4mFM&0qv_+?h4!}qucaof&`(Dx;JBS+ga*Hi|Nn$wziq0DGJNv7=ljzqProJl({ zK%UO|-H1ApfPEOD#bY|TueyhNqBmFQl&^zdpZG(hUC@abTBhI4dHHOw+Ic3ek zxvCE5MH8^X{V9PuKcdqr)=p5DN${}PFRDyGe{CRO+eDS?%=s`)^+~OCgsu{6E3@f; zJ8E-UGL(iRNawe#JyqXsuJGp=HbIoAPayHq2b_HPkPMy0&Zu9Q! z%75x6pO<0=Q&>lQaT5}+7?uj}IG~@V9%!@?KlOSfi0Yt;-|*Km9Pc4td{b?8nA52$ zgsSs7OYKO%RAmD@^7iCPErx4(c;M!qXh)p6FwH;WjM~5*S@g-y)WWKjRhf)@7AOhs~n z>~~LK7q}XaQYJI^50L#uQT|bl@<;m+=hFgN$F>sxfhcQmxqdSuVDSY(awjV013!^q zfjJ_Hp4cEMd|S~7HdghzcZglNhYKU_fFrl;7L%Zj`0!mxm3hv1Wli4FKW3rYa%2cb+9y9{6W0x8~()r_v%oo1~lVyU(Qp0 zMPg9i0w;dUgsM>LaL{AKG_Y)J2lyeMRQa~krIPY#$h40lOzCdlC3dS=Si8kI;!M9fo;54-WA)?!i2im#x-X z&RGMV?s4i+I6DOo0mLADP^Z&0+VLGTrsZ(wXruuE$-}UuD+~{}j;I&^gq;bBghO?6 zZ(ociko{$PhI>OGLpO68@RjfY7c%arB6|M&9=l2r)}+*^Wd zL!Xoc-p(QoL*H2bI;O`iJ+ffpRijV&IJ3vz!J{tBxqVPs3{-wMT{;)Cvv4Ueb1+ku zC<(_Lh&mRzu2=Kfeih%$<8m4*ksWo>NfWy{zmBVCS>J97w(p!QSB3g45MQ|xeNZEo zX9m$S*EDC(WMmT*D-yxG#1DIz(dEw0q|-0RktRU!l|>Rv&5>nO>)P2+MDc;BcW^yM zQ@bfK71q%V={vg-Tm4g#x0E}dKzXrMWqYCg*L{G*?Z(gLGeCLIOtNrn{3Imj4bB*V zbFs4R0a7{R4x*k%PZv;udvt5$tv6$?_&<4fWWy1^uc0AVJ^U}Ue4e@PZnMYZGSGqH z0IPfvDP+Eg&ELDJnPW{wrJdMA*-hWf{=@LU{E4JK0`Htov=KI} zCPlXgw`#;CJX+PLj$%nFWertFX_7wq@w-_jD$v&xaDJ;QnavHbZ6H>Cgoo5UsTrRs z;D(~qISs^x3q+d>03NK>9KJSNoz*J?J1#Ny*OzWBiId45^{PA}VQ8NK@0$26H_DZr z{3Yi0Giy$Gmy43$7kd{-IeS$Zq1tE@!_4a;=EW^kEJwfiIVWppVa(W^UMtEfpEri2 z!;|?rI*PUnrjc_*;N9r&U#{&=iQ)E44X?uT(K*IAf#W-?MeM{-0yO_5qCrjWh15>g zPw2FH*`?1VM$2BrG6@Nt-@{2^OSPqke?8Sw+`GikqIlTxIC+kHh)?(kJvI( zVm<8=m*mmHQs;qtskFy}j^o?d|0S;yeJw&Ykgly%8l&!?171GC&K7h8L+{1oi`*xrmeehzhMYK1v49a>l%nCnBlfU<_{~QYb@8hr zWiodfm6xyf#B+8`Ee7}I%EDE@_ih^zuEpc6ECnJ(5tHxPfO(g4REFi_zwJv2Ms=OXW2Z z;^~90%5gnmMbnPV^3$ER#iorm-%UqU79@47_-4lEnU)mCV(E30wF_p?Wkug6IU`6@ z{jGy{3rHT$-JY7G2pZUdQrHi6Ax8Hi$l;e}3W;Z)EM@tzv_SXRz4tIOGiB2$m3>R(P4jigvoqMA#w;FUM;XeRw(UT;>h zZryxMovd(B9pb^?CK=<`8^xAxkh69!Q)w5xk5_tA1?IF!gC^|gfRIiD43&|ITMc1@ zY|3Uv4s+_13Qr(=EFxW>Mt_ibu!LR78!r0*O-UXkdqiBE+~fXF;pU~1-|$7k`(w}l zsbcNf2mVd7cE+v}dN*$g)T|)=T=EnmY~7IQ@_NfjE0MFl{J~7z%gS#HaOn69#2L>9 zl3`S_A;|&fg=P781IT0eV=1IkJ@sHvmZtl59Usc|l7FmO5+Cd+VhhB7NzNS1S#7{` z&ZvWGMfI$g)%8Lx;FCH8?4hh*>}1yq7w%Z0|nry&XW!6v19xP>V7g92x?YxrnW-*aXJWoB}E9)(9B#Vfyw5e3hL#R4YKbxL;w-tSCWi9h`D-6OpA%94f6!OBB ztO(q;p!gd;k-2B~T-^)a8|s0>@6Wo8x;#oz+@e>hewE${|L1wovUk2B;UCI$_S~V3 z8DvIYGr&9eTyXo?8I;;)FO;4r!*WfHVXHTxkG(RET=mp)Q%A?hD?N5-Q75NO(%C91 z6PaUf8mz_?w|7Nyce=v!iHKHKxw* z(3XZ=DIl(^AmiX~f^b-q-xcJum4Yn7Mu7EDx-N`*fh!;zgMJ zpD7CGYpA}MjtB}6I=9LiZBZIL`f0X`3_6Z5Z6)5k2dAt%zY=eFN7lkeU*$gP-ey@) zXK&Nz^k_BeG7bu(+A-Owd3Qzw>(-nqYf-F>ZRx3IUOw2W8I}An9-6u|8VrdR!Zn>& zc$|q^-a2c>Me@dGPjfos^J~&Bj?R1K0Re>GpKvFI8JwRMoo{?0sd}c)c`Fm26usAz z`XC`okr|yxL5#EX*UTxDwN_(yei{?f{h6t2S94U=^r zga)eDX;ESppO0r^p&W+n@;g*sXgUCKT`8J9CEUYzu}wf2lT5wKCukQz6Ae+V%7FlJXz9!tmNSVE=msI~hy`9!uE& zlJ}4+IEV@U%no-{yK^ZJ3Yo4+@00$iO$7&iN6u?O$|WG+PgII}Q2z!RYKMU~+fw#RMR$$PZ5C;1s)4GvWZ2DTKD!@k**GR33mo{!b@QxU}Y6gbD z=@4#)#5}?{bvrY^y|AWu%;4!qqYPK+n7dB6Jh&%~Y5EZ*p`~wZ98ISGPJtKBfm}0E z#p-^@m9iN94^K5(dTbZLD5lGP~vjAgx#{Y_1vIa7tY! zR*n}1VI1!2&(exe^J&97C3E1%10yARZYCo<)U9XxLC(H#py@;$Sj4wEg5IF;G*LOt z8JDo@#S8h)n874tjr_MNa-4RCd((1K5d<-*I+Cve_HBfxxl?-xslV3zmfM#km!jhP zBi(WeatQ@dbt3`vlY8onO8Z&B%2>OR9E+YG$d_DsTA+dON(>MZ=|P%%)P-+Jm7jy z>G&8cGk4qPk$W8=!D#hycj#s=G^QQp)i9FgJTAq^S`NteQ%7UcC1er#h$M1_n>$ms zBlbA+^JwXJ$z{8_LdQq;`H{;d;ZzG{KeXvXn17LAR2>Q=cl{dUG*M^KL%lrWW##uL zwvyaae%i{0D+e(O7dF`#a-Ux4`E12LD|=3pw_rv?mcDnND!-)TiV582--0s;eB$ML zlDe`7v(Qy;ymF)~>BxShG-yiZxkl8Ke?gg1PlYe&WWTPTcsS_qq6^j6QtjA&|Ib^-Y`5dONP9`e9*BY+UNOV! z8Cm;eu~0f)tUHXt`UUc+)1K~NEQ9!v9oY}#UmvmzRQyx|Nff}~U&|8h>Dbcpv0vM9 z&i>Pw_1*d=!e!GoDO|qfOSt5BK@xb-g8t#iagA^r33|EQ?}GUmU_lur0+;XohvnZNyo{6Px&?-jbma+G-)OOM z)5Sv$dhC))4|X-$qN_#a%<1B$DrTB*t`VF!5v9gnJkC1D_mN-nAmK5n-u~`?k-^;B zNB7&EjDeT>3ZCMG-bP4U4d3tt)i>5~iJ%MwEkSzN0l2{S2DpekEgGCOfY=W!%Naa~EEI%Uj0$h*DiFcJvh>0Z%+)|~1QatsyfQWegeoePP6_>H~c`65Nn# zRDB1XsC13K4u!W}9}Y^i9OR%!j=`1LfEVa{U;y(~;nx;e-|&E|2gK_n7mI>O8+!Nyqz}n-PF{a@uRVC1 zjcN6XEPJeJlLb2?5|}&u{s1xy(qQ2x6ZNaTBPAR3f$(SB?kc@~O-FMleQ&t&g6Y}B z7tK3H1*c%{lYjCVJ+HKoS(Wkf!8xNRnzBv32!EA5mQ*~+lGh^WZ;5)06Jh+^`K*1X zP^`}l1VNukr{DO+u$w75PZvskydwp+H@d!uYfgSkp^o~GDql#9l`SD{&@+V7Lcgih zg5VjOyAU>bbwH_Dvv5{p?pDIdi(D6i>g+F~SYcMUgDho;qLM#9;aYAy)G84SVaDF&pL1A0=3H z-Rq2*mO;!Hc}VIViOBVPuH&-N4R_W3%!IRt_9%*cU1bh8 zkL?4oL!%$a;!R^t(t7|hJ))CVghmOHs~{1|1Vt-yFrs5O95J!B2{5tRi72@Ki(VcMdm3Tuw1X4n;?8pmt z{SJqeNQKWfG222Z`v`T z+FJr2DzKQ!hRATGNj4NKQ_8TP(HRv01lC+K6zIY?AbkOs_KY7y=OhWojwBEZh`ep+ zzl)5s%fnsYL96#{I%&Xq&C zm7%dWr0Wa0vgk1_py3}}vB3>57ODq*_PN!1Lhg4@Ty8N} zms_6(_CAn2w(Q!`r>B(XO->bEe-dm>-JNr=gxzMzdG(_AItofY8d)}VeU;#|y*ej> z@1!$)`j@b_;GB9jwK*s3HH?=ykn5}uw53~4^fw)8fb$`l(xRQqM$&H|mVu2hFabiI zKbYYfF%;GoFuT61&~6aZ^N?ph#V;S;w|%O&sUif*MZ{y z`tAU81K8g?;)T?odkI^IwTzRb9^_T5-HhcFMWhM*Bt@n_NR?!QH$of#ek%&Uw4PRY zMGw&J_BRo0($Mos`^DWy8j$y&B6k>(vLTv2)+0g9{Ggja=@c|3XW=?*dl3BSe>#ju zmMR-Yp}<*FpA-hv2z3-%5K%#EkmGBK9$@Tcqw(+O0IPru>P+HTY%HWYSR@UZOAbE& z#hsFLU+VS;S*3F7e!EzI?nl}H3YqRdoB34n=)_y<=XL{$bvjDmlq9?}dwF+Em+CMx z{zduZaTKqDWvGcs(gI37conNuKI6WkU#nZg#T-0pB?~}}M&4{Z{MKtGrn)-omnyu@ zXeFeUJWE)lKr3AOqkW9w60ZS~0hz1;m0g55wQk`t%QXb*5~ip>%m7cua~@*<(dRIFz)YfLU$U?GR`F`S zQ3%Tr1+OrjAGyULCZm012r^>&x_vb80*#f0J3zw4=Tr;G4Y?WYz@}C0d|X{H&&txv z+?TLBl))Za`&L#a4e|3*9-WX35+;=u0USZg5G;;D_cGDLD_!6EsW)Kq-QuD5PdzxFkW=og7B^VD{GRy)*<$!a81e`@szDPW1`> z5m?PDJrJE9)_1C&g6UCXkf z%S2hc%l;`f_z%Cqk{{idyaM_a780LKncSZ}&v;C$keW;%{e@1_xj%RDej7Lx)QXy2 zmK+D}PCk|`|B5SGv7cbSw1k=hYm)uvZ47_N)yMWn8LM^6ZF>DOl%=*$0Uwm>;wYYQ!So*g^7 zFbRs?_J(i?c^-E$nLhw{1J(k`x??q zNfaNuyGe88ajq`fk8(B@p{7pz9&#SVBaRKL2iIf}pLQ#qvz#W&Yh>gbVBK9=jV5zH zlonC;4_KEyT7~wfN=j0c^vZW#_L#ZByk)V*;LXI!R&DHtum!Ix1jE&k8W zecbUt+GtPGm4xf$4+?yWVEBpWfm-OCe%nY;C_I1rom1$MKGBjjI&=@nF`&nX!MevtI^gI1nnio!pYl4sX zjMWu$=f(s7yPTzgNxtpWAGo`I=a#1*ZAhIQWK8BCd(v4)_k6GJ{J{Gbpi+Ks&Ku9voHe^NN9&4mYihUiN8n8ck1W(~V2&@o6Y$Zroo`gc%W;^HHZb^I|Zy7ijAV2>gKf*Pjgz z;*1d=LsXz!DDnE%qe6c~d-74$OBB~zbkuiuKPj&gik_a7%wzTQPUmFk#MT)BO?m5u z`B~cP-K9Fe46T=4olq1$fTGb+PZ}u@Al6JdcqW{duz%gJG89zZwEtM9)f=JcLj09Lh#zZ^x0=d+)MQv`F7`9L=YIZW%Na~ffC8-8$DynOs5 zvs5hx47Or=zoK^t)YVcxw|U&e~}i8m6!gL^*e-aBU*l6 zqEc306aHkF|5GL=fU7o!>q(1JBaXpejtQRW$u{@DW9D8( zjBU*!<`@a>;$P_e2Oq~a2cGgY;*>8n=CtV%!(-0EFa@5yP)M{a=3JbaGEmA57$T*=YUHU1*CZ zhEtw0ws{!~7JKqIqn<|0D(%m357as?jK3}*sS+9uxpMox=)#S9bIGHhb>&(Omoh_v zAqpy{iL+3B0IoMDkZifS51|KGU$&d58iMxlJ?Hfl*Q!d1!(OZGU>+%LKY^ZV15Jg|H8{wD5D+aCYK;y%-w@85)f&z&glot30KC2^QnVAAJZOV$0 z*Pt#?IYJzR9<62F^HlBD9xU+lfd8L*IdMe>X{ep&+TRZyl(5#a89>L37dqA>5qn)CzG>^QDvBm2l7bp?|0fj?h67ph#yoR)J>U$b{nR0b_ci^83k03Uq zc0tNwV55CQu7!zk*b5>O|M_gVBY56bTP5;<&7Li$WC^a=Y{N`_lN6(&6`gL{NF`Je zJ!0Qg#si10WIu*~>N%|Jskvh}tzB*rB+Fd?@jITkAEsSOjL4 zeg4+7So#44(PK{e)BPGvzHu> zt@-T~ZZYkbj=t^WNa4l_U8w?RYC}MHFI7CCvaMxCG)K8zzFPShb$NT8XL)(A1{$zX ztT(`6{qtWwyZJxT@t(crbO*+j0s~=cI$2Ng`Xk(zRJ2^LIozXJ8B}gN9A)m7;~4wPvb1aw^k%3@8KU&`-DDz}`g%|v(E_f>SR2yq_2gz%Aqoq6E zL(%SIG-tOGR4u}7#H{~EM^!zw=c~G8We>^~5wrX?dAsU{z-%@16n^>CeuCZa>L8ci zyUuQ9?3xT|A-VS*wI`}@rC77-+KLfV3sSRQU-IV;ZE$~ic_U}{$hIM+H9BJ_rc_6f z(7aUF%LY+Ep=lrq`icct<>;!7-wr@t=aOovWmrkR*PK<{F2(8wDl-u z{j??&J~%3b;j}1^Hk(qopP(p~)&-EXdu{}+h}&ej=psc_bL@_GM%5IsN~x~*M+Sv=iDU)JmGp)GPv!^pAKy46B(kPm9z$3 z5dB~QDX)?9BpKvJ^KDym?_j;z)a=R86Pc5{T$#_=p1*fB7~kk?55M zwR~wPYxat|4hs%>v0U_Z6TF16^U)pQGL>#$?LMfDeC?E1^Cf1vqOj(PrZ;awLd#KQCscYa?O%qZ}>VV`p zAb*Ex^Ybqs{DwDQsOnD+izR%8*wW}eSl_X**gNgH)5&*ax8TYz@LnGUu}Bc9SK`5_ zXnAfJ*wFi-iqs9cue|OO$5YwbBK!b30sN-&ffR#)PUP#lZX5BHwwV2if442KzuOJT z-Gp>WJeS-Dd1k=7QX^MZ8+ajbv!}-0a#&N?CCKuC0i@D(S)BarZf5y5{0FmH<}NpA zEI`r|x?zCMd{?`BOh+iD^H3AqI+WO7i!g)Ddz?9v#Ybt+DWra#Qk9g8G_Ot8(>ndTvtLF=!bF0yXK<~ z{vx~B(>yZu$C?->axxx;MawMT)U0@5W>=@RvRNgAsD`>b>UDO(_LW_IYmN!1*`?PP67x)dD%iQ0m8#Nglm`}G zk5|U6wwcdd>r{`ILY^u06Wf8vN+Uwf?-XP{&Fbf0we}4#%?L|s0t`w69wJ_3%1W0& zilE8A0MA@>)(hu!>?)X^XU(||RgEWi_q8B!3CtG~m;HO0GOvLdb8et8*=xFm3y+i6 zh|9a~$_o)%1Gz&)dC-r@cM1<=uGlG2>@&M8jE04xd=4v3-ICdJ)i*N`2LfBE=hWjz zZo8h$VLCpPjPg4J8=+R6zZ3I=rq6n!$dv`p=I(;<&MODM#X?ZKH5CC(q{t(7E+qJm z!uX|-FP_!OwI5DTh?9PHzVJFazbVAIn8QhvFOTtXoAwG!kzrkyr`c9(3CEhKk2U9e zlhrl@k;k4?ADoMFZf`g@ML+*nEO$Q z*%x?2I2{W1`~}7C6OYGZOQDn5v{{@MA&GprX6)<1y5CMJ`_3rB7D=>)BTsWd66XB9 z=jxO`)V{w}po={^)PF%FO7w-}4F8i1O^P8U{BSB}iBE1!%59#opM@%V;&r}1=>P=o zb$uoDC2x2yj(!t(LhPlPOv!++@96)vWEfnZW*dC?@3PoZ6W5=6L?Bt4#wf>`-3G;MmbyAkPaUqC;4rsqDq8CFq1M#w>zmF^rbQvyv zC0>1R+UFN=Yl;wSr#xGX8sM16XK600Gv$hfF&n!J=c`m*#OQy23`Ml76|$?!p}nq0 z(69vuS?J7`z#MV$>a*h0|I_vo4}-9a zGv@&-%a>hI#~@N9e?8Z0l$K3QjfE6;R5LGdopIpO&F!b*{k-$h4#Oa>Va%HqvP2)$ zU3nic`dTWvR2r;Zx1=-)Jbczdt{)jxkrm>S=Yr-F zR!EyS)UE|8HRCy|m?rzYm-L|0W9;bi*%f#9A9!CL9rPCn}ii$+U2u&`9q<0y^pC_-0i=nWIM zA4*L_mB2f%T+|{_yYMW|AlvsTT>c9%6?tu-N2^{*4(lz9{IhUdSHIGgtG_lnFih=q z^tt95E?f=edB`D@?4FLKWB|_Uek?G1Hb~Hpb=~oUv=jf~E-L)dre5ZtOY_wCp#*G2 zS2nwP)&B@NsN^n2X`>4N-aVJ5vk6?LX|5*_3lXj1<(V@ z1gyxI^UiBNfPA0!zxyrstP57@_ExQ=Kka30RhR5hn%{>YzV9w%bHJt2TG*6%?}-uD^nQkp7)z zGR@rPGqYz}hHgF&7fDUj>&~IrJtotM=0Tu&Pd){*diMD^_ehAkbLThM(JuH9B!2-Q zfoNL{ZT*YBB}lsuDUXw&MQ7_(Bas36iq0_v=MI zI@vXhjQQeS>@fw5mRIMVs3SwUL3sf4p!W57(MX_&&+1*-5cyRqOQM2#K?r}_L zEbmFO@`cC$_XRvexIgFK#N8<$_CM>|B)=37O&zLpY2UV$xgV;dOElvJh{nV3rQ)?t zjn(Z2;!I*Cl=(S`DP#2gTiHnJFIz-9jrf}e=X-9$)FT{gm>!zvx1kjl98nk0vd_B(+U9dR}O#QzI$>wIxcQK*=&|lT1RA083 z*dZ8GC)&3Df=yPu$W)KaoBILdg#s8{g1racmT76eBjlwLwlG+mAQ`A6q4feYI8ZR2 zFT?z+&PVbYVlm{cS=j;aOTO^B8u7q-t%QT~fHP;4g;!%3DUqQ=hJCp;3~SzK0@I7k zV`-71k1@=9sGX%M_i6H)F?}q3{%dLka&<=(wciH!iCObEMz|JQ4Gq*yDLRoBrl4xO+;g)w>EAYNm#tf8%v@xz?M=ZSwvx8L88-PRnavxtFeKIPrLDU_n^2g$1va_Y z(FSxHJ;g<*>){rG{eNfb8s|yRThNy^H>&rJ!q}ypS+fgwlvg2Eb7MTl?8_EvIy#&E z-TnV@bnS61_V3^0RC1V*Bu|r&>dPb~+D6eHLXrxl5j`PHPOY_eOC?l>j#OI*omJ#e zX@_)ls8%{jY}Kl*lbze?-o4-b{QlZ&f9&-~OTvJA`_EDzs`I%qtV zhnzCd#2ugO>>kRx>Q~S?4I-gjsugOpV*e2eqM8QgE!$G zs%DQKdDXY}_n~rIp74K>rHYHPnY3pP%WF#+-k~$PjFe_W%ejU|hEY-j3!v^ApCl(2 zD{tOp`m+~8n*gyB5RruGN?YS=C0HJfF7b8qNR)81G{YLxv%8X*U%%AhIH7{B2w?$E z(Du@I72$$IB%2dSO0b?&0QcEYiQ03~*vi6syZd=3eRGw0Dh~N^u(-Gm2uK7&J0{&&>l<4%rgkee!yWM+2fz=j6-lZ|6WKX0 zYx4ReZcBg#0euxvb-{)TS9QK!s2=w?`>}Y*(2G^jPw#{JL)Et1 z>3<6vUMsU(B)4o22;c4_yscL}4u1_ybVdY@##)TVIg>(DHq$uJzu1KEz3NBA6p;Pn zRtc&Z+C5{7_}a(hA*_&ZR$#`wM|B~sUdJ_yEXl7pme?qRkJT1)50KrUibu-iFnNOR zm_|xrE}=aw!bTRNj#92Z3O|uk{T2Aq&fxTKqMv#8xi4H^XT&tPYtiDD9XuGzDd+ND zR02zwa`eZ^1C;IXdzSLSV_S7*%*`YPR0@8%)%@+Z_LB~mG&yvbgkCqN1V1@~bRI_V zb&KgYSeM?ph`y|3uBmcTdKh$-1oY>czIwve%B`?x2+jLv|D?7PCwIIm&I6)(A<+Sr z44}i|54C&av_bkt^1=*S9UDtQ%T$UPmhGK%RV{38nBF(&$fNoUo z+af63c%pD}@ewbj`Ov_8=CxLHF16zcPCp8dshPjkqX`RmLBAD^o*8-kNeU5@kLcM+YW-tvhV=&i%Z_IZ|+5 zJoa_H1adp$17<1bjPGu4Sre-{()s;tBW~!tgGK-41kOZf{NAuoT}MeK!cMrxL0T)Z z5e&HAy%%6Fo_7z+qJAIL1X3+9qw3Xz9#c4b@ut@)nfl4+!!jn)O;4zW*M#t~+q95g z-9@e4?jS(R~4Qxq+@$C7U>6hzEi&HltV-Wyyr%Ty|}y+1s$f=z{gZ^ z-`csK=>HuERaX8o?qor*@U5_lcbLcDoE9K%5ryCEARC4O?k1|HkW`L5|5f~CpSbz3 zy7XDgjWL6{XfCx?Hro-M$HUBCTJHEQYoY~BIvXo3%&-_R4QBeCNI<~L@q&Zw@xTzi zdno6)duiQ8HrVXK8Q)**^I3wnR8?CObS%)Bn(erlk^OEJCog7mfjZoR*@hfoi|PGP zUf92fY5i30w1grQqsn*^xIXx%g;a;Z>*+JbgtIC-*5m zK|RqBv;kUIp5+FRFJFc{kqNLrb+a~Z5JicR>~TcTK{8Egj#?+cWb}3}=EHKz$thfz z_|oxZGQK(6mng484!vLdA_q*tA?P>sPL%yWB9bfw)~<%#yv3wofUoXKQyj;1j))d~ zlm;>D^>4@D=${c;QN<`JW2ob^>>LBp>^Vp&2%8yfkjPB!kqW96K0oV2>V5skLryd5mnHUGlRdkGgea?k(3xQVkaQbnm)DZLEgnq1kVQC zbdjoBe@@CO_V2E=&Db7bzrvPFnaY2IRsRbtj<6k7rea%oXCdyNiXEt&n=G%M_&?zT z^JxP;)tLWn+4T{yr~m$BdNP;0GrfR3To5b|LpAeeb)Be)Q>>Qd1{9FudArsy zhMe|8+5fYrGw(ED|8aPVp4W95%0Eb*JRg1OBlb1d!D92UHw*i3O(TQ%DW)=ULtzUTWGcfI zQ0uw{Jpn9S`~oReg5#mgrgVgH)jcA@V+T)8F!#$k4H?Erq|RbC6z{RYAP3pM3GTrTwsO=^&?0P+vHu?}^YoVRAcy%c~MSY_Q#b(a-`$ltbZjx8BPf(ZWIq5iLxwF#m)41u3?HPfFZ6mI)0&J(;w~Z|j zd=f3xQd{w16Aj|xbWXqmz*G~+XlW_**PCKp6tnkLtX7Ja+f{%IBDXX%(!)29L|aP3 zCi)DqQ})GUdkI@6sI~`N>GPTYc5CO_twE%|9CP0-f0oWW;~wD5YdVdhZ7jlX#!s^? zpK=7sze;XqEA#U!G|z~DBRZN*8;|^py0aVjBZ>2X7XZ#tj#S8;&67(cx`>D1YN3C$^Yc@E5b8L85co7-sS!<$<4c1Kz{S_>nk zD@m2iM~GXLeiu7~l^eDMeXZiNocrR2N=7LWzXXBUMWoY|HwT@8Pkw|i&Ira?IkiJD z%s>Q0^S_0M0#qCdmu;yr4-N!>r#y?TV9do_2Op#xuojW;Cl}VSPrqGAY8&^>crGbd zt}uJUeG9zr`v(0*E5n{feRu}ul%ehggpPUOT?h9Cl_QnHbJ$(1{k|VNu;;OLMq2Z; zr>6)`oOmv7-}mLpAhaO<8{6ySAE_1aE3fLv-!0MSR?K6Dv#=kE`Pyy6h&RZi&e3HT zNWMAB%`!%lr-^!oI(`+Z4!|T!O~Fvgrkmvc!K16ynWfhwPi`#(cSO_V9z!d>Gv@Z` zLrk-%VNmf?e8io<@u1f@Y!heT?}tH>m@9z;Vgul~%Dmlq`>3dQ@vI^c%V%14SM?LQaPXY9;HU8C5d_B7%Xt}B|v$r*Wzty#$$77b zKEBSiok#7(=9|u(8aY33LUPZ6XS8-MnNs22gqzR&8+ZcNFBnrh7^7CH0K>&Ucv(kO z21}T_;?KzIXspmlT`FF40G(Kes}lBzX~h)Bbw8TbiOF#iix+%VC8n@ZI>-M>l;d~Q z2Ln5QPkY{WGZ-88X;(i;?Pn3eSa3hkzib9IB48B82+er*e;jG}bDgz^&N)Bw-o_NX zUy;U$a@>ZZV2#QyM2vPW^ihF-!tcr$U?o(% z1(3A!L5z3r#y)C+>@YJ$h-FYH+hhVi3mpvI^8db$?f_4X5-x7Q&SDw$c@-X%xOCK( zJO#F7Ns~;kQd$*<4vD@qHmM(PS=)*qth*pDKG2IUikU zvFov|(j3;TiaDshJ*=EyMHmpb8t!SvizDl~=ESi*-Ajp9zmS?aB!9Lfl>Dy3jp9+W zA2e5vhFhS84@ob6IdKuBqk6xUkV)qHQACz{0E$XS*6D(_07;W^cNiPSy#F=8-wFUJ z57**;A=OjJE6@e<`l)y`q&;QHvsupgZF0_QltVn}N&gqTIrDZ)Kx9tiuc=FU|5Gh8m+?C_ipha<~-dc<6w>2&((VJGQua`J%YYiO3I_2o;!%%`eu1k_VyHs1Q?y zL0*Zfp|L8Tj zG8ZFTnmyO9jxLU?PYRCw(?vukc&M2>DKVPGuLI^FR=9gf^R#n7GleUWDv3SF{KQrBhExPv}8S*Yg@6RIo%a@;sdaLpd8AGYF;o(vQ8yeNH{n=7^HSKo7 zQH3i!7*+JCa1DNb7a8Aso5lGC%VX!bjOxnT$wxb^A~e^S0^N^STcM6HFR>l-E&A`g zN>hk_J)tZO=;+fuc^hY(&Fp(P0H|kc48_WcmF?}0Tt{8`5U3M*YgLV;Q z2sjFZ8j#B-+d}945+A!l%6|msdD?TIQN7<_JR?}nAM}bsmMR;HO_>{eWLDVXKfKFR zsN)rxynm$7b)hBun=ZWOSmYE!TKkN4S`;K_KLnR%QtAnD*lQ#DC#RRmW-nw4;8Qh$ zxIAxo>oj4E@;f`Y+wTe~kP_f684VibMVmYh-o|lgByn^zXJh-!FFmRp~<%5(NSn7IZ-l@xd^jf31XhGq>X%_%loeG-ldbg^=na0g{n}}ScOKr6v7-}- z#Ma9gm(c?E^?(+)0?kJU1*Aw)1DOX@9D2D@4R>(GVlu+m!`PC|=&{oGLrrVp`P zUE+d^c6`cYE++89!5MB|6?T;LghCH~J04Vs`EaBp>=&?JJr8gLJ!MU*+9F?;mb2VD zC0Gj*`WhDkk@gk`9t346@}2j=JR*|T>$@OC=h&@{r9Gvl$Y(Rdd zcFS9L5?yAkgcB7>Cu+u2F4Q&rLY%ng>0Hf9V)3ATH9wtb3;OOnBFXJa)zQ;rAm%Bf zo80K4a{8}C5?BunIWQ+$@zs??k%d2<-x*)`Tqk+4ALjJ*?IsfQ9)-&tJlU)FHfE_G zI4odbqHtrKbAWFBeacaq#}zmq@#oBfVp!>uLC%*9y<4^Z0+Pw=dSb=W2_0rOGmwF& z#81RxZ*v!s{7#hM(*&n7CfklECU1~q)PnmuKi^X7$>Xb)f6z0 z{1-J~m(!_MuhSczGL0ez2R|90%MFeOLWHB^38Lk%#NY_|jOjoyHGuq8r4;o>H0LGe zA1M*EP>->Tt=Y`&yOAp6N`sX^#HC;Ol^HL`iv1={6#e_Cnhj@2{B?})k;sR#bH8v> z$^ZaPQR1}>PYBU_sLjK|P47oOq^RRyrH2VLE#J6AqP^8&lDTa#^8V5 zjfz2@(@sfDCrxx;@|LrbtB`&t0x?VY@tVmL$-8vxE7K^@D+iS{jRw7fA;J)8i;Cl- zf2Dc-psE`xA@ASahrdLk3#@k9y+m0(#9&e5yiV~) zuFP03?|+K#FwevmB^aEQnjT%CM%_+4AZh7o**4MQbp+lY!HkAdj={Eej=F)`q5c7y z$ts)Ifu%~&Ns{pb`4c6r@Hx{oPJb#p?pFX^>)6Am-!mEIAtrFYz^rL>^H3#IlWy_h znT+$})(b(tOaJ&cIwD;)BPOI3lfSUXAle#p!FEf1b{Y~A%?D9tE zbI}&L+hBq%@Q#fE5_lF^c(%|N{Div-aPVTE{_9vtC*8jht{JHU#cnw*X8}z?O8q+yTg!{C>Ix(7>ub` zpA?x=r)AO0ti9(&@)G}pS z6J^ny3Mb*i@Ycl1w~pvw*1qMs)y2oquMeV5ddj$F*p>2x@SPqdGyd$IHtdy}?-g&E z6K94*GcLLxzK5Ef8>&eg1(T;UoY_0`|FnkH81WtcclhB2ZCZ&jyUYdZfQ&!D_NKcC z`>3+Q@bB7;79_?*msq-#R?>n@ZC3nibEE|CFshV~$AgBbwq&I64LhTTK6gibF!_nj zW}sArRKEdF^TU^y%AAL?eG|!&}{z-0ZizrpsUXn}{T;gsG<{y|t{ zu|>kLhA}%6xITdo^C?2i>ea9&Ky;hMyHjMTIp@G^iICs9SODdXwMssWe^zIj$o7P6gYuA}Z`Wy#pe9Ujj5@v*#x3?Z&_wuFguEO` zGrV`j5*r^dOa$yU@X}H-{7r_8wpUY8`J60X-e83%Un5`X~uo+C}lo%`P2X)gT!{ogc; z>$wWKe5U(T?el2K9>Jk*k0}Wp95n^UVU!@xpi@R(BaHuyO9)~h)?Lk!$4*rIkHjgN zp&pmgCy@J_bV0}QH+D*o?4t^v<|g4rGM+gg95+8@zla`#x&J#f<1wr&`7f14a2|(T z)Uy^WWsZlDxX?XXI$I%u*7eluqTdI-D15B_Or-CdxX&5L0O?VtOMFh^Pv=1Ur~z}I z8CA$5ikjZC{O@DCJ4232I{S)#?qS{}vkq*~9Ig;(l_SR)QPy$ z!|L_$p+ZfEZ*ReJTsAOLCwT=?4eEc4JjB|k6LUy`7(vxi$|2Orq40InA@aH`T2$Da zo*>}7#QBJa{t2Owf?eNMj9;w2V+9?Uh?4b7d`o~OBsX-!NmG#l^jR5BS({-o<-Sbu zRor623~VGE8PPA@U!>xL6qc)LbJs*BYG(Mk&Za+jeOo`*Prd>m@U7->toEbCaVt4g z>5OUq`l*VtQ-=Ccm*mLDykmf^{L~NZ3GdyCBdvJw^Gh{5gDs2TYra;J{!65Tu1C&I zhYnLROm-6pGYwDZ0U|#r6D&>-1OLS?Qb(DTw7eQZFUR!lDEWk6LU;zgKO^6--7~RO z+Vltu8ji+00&bCA=_jyq8n%#9c8tj_N91Yyp7H*LH<2jL63gUPfldnlR$i^{`beB- zK_=>GG#C41`F5%AXXnr1FO{1wfqq{Yo6c57hVb|La#cEhh28MjcK0?)hIuT^*){0hCAN zRsa66)dqIwMVnAOX!@uC@CiHE2l8|wj&j2F|D32;hOLL5*s(id%+H){a5rGvgxP-d zWP!E3zwZ1mdL?`1VLNTGI1Vlx3uK@bmCX!bVM%E-P%A#h2{{(fU^PBImChgIx44vi65~}>zf@XD&w;`u5&$shn zvuyFtVNkZJ|C7g}{6O+sPeWdPoR~VBQq?|u- z_W?EaCVppZOS)-~T?@rO*!j_GUsHu3$|B3L(84OH)_?J6lI&Mhn6Sd7D(`0%hgZLqCwK zqbG)(wX-7*z#t=ac;64U19zF~Ja}}~flH!9Qj2$y#otPl(jX=~5qeY&gj={xIkA1y zmEpFx=mJ$L&&!QIA0qlCN#1cgYS*Z}JJ~;%^IJ6XA3Vc?*hpyg@SV?9sOGTN^Y#Jz zK4;I!CtXcj|&sXxU4{xGz1^g=& zq%nw^@VxMFg>NwHm>|3*oE#0ZUiCfKOQuUenbfKt$#G+?;-5Q+|CtYl5}3u($bbX- z{6fI5hsbgZ1Wje+L1DalzIUU8?yEp|w|1j6$u{6(L%LwK{4=&~^2IvZ8{r0f1lgf& zhPC)S%j9GZd3m}I=%n+pwB3!AY*4_CiIFRN?9lI#%_P28RG;);Ad!?}{ol^i<$z}o z5i#~BbCfr~SzIBJDd(e8B6n)eWe81w&Yb8sHDF&b0v~Ms8Dq+_pP#7IJvW+0NsUkF zXCu3W!KUhGS@L7*WqHscwX0|qlNZv1M&DgBy=N1oBS0W8OoG^5mb zFZ%C~6Z)&RdO?S)?So;&t{q{>Kbi5vPTJC@ z^Hz4UPQ>WJO_%qKA&3^puYLQ;7dn#EKeFIy(CxQo^iRH;5HIXThA>(T(DuOO5lnBo zB`=C`iG9FGEs^&H`D&l4@W1rnbX+IG zQfO&00ypT`)tnk&! ziAq#IP$jFhWM;a-L85bL`7%X(!@QkfL~GiJ@-8FwwL$T2-7_P?$e{_$4ftgF1a#wv z%9PJjfB?#VMwmHxm2`trCdRLUUT@!lO`aG9_IfaY>pD6U880hqmY6DAI8lTAMl=BPc_#}xvY7G|4K6PwE2SR&AG=Pv?1My zbIe>y-YqWg30*>|fm6D?2gS6ISmhN)Mf189v|e+P8xtHRd4h&RrRiYV_98%IDqo9@ zMK~AX+tTPlg9sca-O&$4Q$BvaHjpXXHul%%84t_36OKF75vPAHMArvzRgB_Kc%4QK z2uMyck{w^4vmr+F%^8k!_saFiB|%#(2{ti*t z71(vEZ^4X^>f95^zY1Zn-w|kzU~~w6$oI?aoFhL`I>-;oMgoD5J%af2mwt&13QuPu zf-QFWJ9r|$srUoP9gM^osn*MJ~ zB`%@k3&>Hnpd_#xdBsNv_IeiweElyn_PXoRu-VpQf7!E|5WVh#%`vu9`$9ET+R5-7 zYY-d9{#zr_dd_{wK<13ykMw~eLC>GjH_@6Ux5vqAH;u_MT3!!3deYOAS??~$39;a& zfZvBp$zOt+1ew5N#UpUvH8(xZQ{@|~d!}2Ml$8bPo||A?H!>O$VcXL_9~zF%%4QJc zmC?%UN9wga-Rof;IZJE06Wx#arr2;Zi&y(5puF%@kS%#B0jfWsI~;n@`y&UYtTDJt zO$MU zvjbf63)TWRy1aO*G?emcPo*?OOkNU1+{|QgRU$m6o2uhY==@#*epamCnT#M!Qp zJ%(B*^w|@?Z_g)DIfQ6 zhx$kyt@$f4xpAq>IS5lw6}z@qD_r5!5i%RK>2?Y>OZN+j8t-}S8)Nzo4kJ?LGA{N} z%nm?6#GbTd=tnP3KilUkZVcOR1b0#}m<#Ut+5h`u{+=IW+ysq3vzK_1Wk=T8KBr zBT8SdmShLZGiK8?sPA21>{1mPG6f@#!UQw{5VPl~py4OtphyR;7O{QD)L)o99)Q#p z1T!WLpO$_`w%&^8%|y!oS)B!z9*`V#Ll2eSTB~f2+nF8 zpuJRyJo-|(>0>+3@!lv zsd#K(g9ks_4qe(jYr`tyX^D-ZrSJ4IrfAL_!4z^6bh$lR=e2$~LDTMB9bf@=>Lxqg zH{V1zR1-1nFZ!!FPcILJpXYy6rd=h4Wa@Gr87-*f@D8)Z!L6t{XnWpZZuk-lAj3rJ zD7IoCYkc`=kI$m#L2?}Cc6|>xrQmPp?8s|L8t&=Wm;nqQdp-aEk$fU+#|Kx1`E?y0jOk>@ zwxiw$oYVi@I^hu!kYHf6YcrRZnh3g252LqJqQ~CsrMN{lrZh69JCm6NH|!bVsWI&u zm$O>XyZ^?^774C)Kbmcgg<~gsa#-{6R3W@>H#{qqLx~F`dd9-JcW8L8nLlzv`h4xV zA6_SVrO-x-h%0YbC_AuU*=P5hq@=R;-p+>}$~qHu58z}F>e|Sh!tESOX`x&Pjj`*d z;$0Db2ceq}Rf!_2IPSl(;K8k%r(nk2CnTpZVp+Y1+O^=hfa%*Dp_mE7qt^h7noFhQ z4h3ziBi*2Cvv;}j!^|A|Hk#jYU9`gyK6B5ByyF(^$IL^kWLc%PW$gpXTbGOM|8jiZPWHW2rHMa_GOk z0DP|oLJD-hGuol@6oSjdeM#Il{-tnr=GBR6?AnBNU9z#Lg^}UG9*ZM8XGAxl!Jju6 z2MjEB_P^H%W4 zz+}_pJTShl6xpnOmzx%~W)rx$g>7I5Q@o=shT=}i#WqSk>r{oS=+Y%U0o3_WzyQyR zjohkVifz!(7Ww6qp(JccP0GgJJ+)5(^?eK^P~!^3uwf|8`}?>2s&!yQv;`&zJP1A* z7BRSFMgJu%24C?~8L#-N`;A@Kp7Azd1G`Gz4)yHJxCILGzC(%HWS|8+v9*yR7g=!-&kQPriWFI_Gx@-dOTgW)}o z*hsS@oj1k#Zn=~+d`A-4lvAujNtFvpH?T9*2jL5jk{9@>pdzK(hn)+Px2%x%6NBpL z+vV&8$W~rgp+Kj5 z!X?a9o$+eT6U9o-H!QFhr;2TUv(Y@BFB@*Sx7%=Q2O=p&?gZegEO0w8AJZT!L`iFV z+-u}7!4FGgm^XS$RRb=^)Mw5!55Y5&-j4Lm?~h)MX($86-UKutjXd_Yazbu!+Y9Bk zwoNIJnFyy!=41pAZjK?0)KQmqRD2$#DmDmhw1KTwP2X1m|A^w;JqByO=&lP>){TYu zhjc`c{c6l1`pdYe1xoS~xHFCrV?OH|RmOkP_FsekfuTHzmyJ`*F7nyQwJWGI{c(7q z`njA)F@nqUEXm$aMr_pGOU?W@GggIP6>HCGEZEOA+wAw~Sjb|8J#|*c`z3HM%MJTM z>}c`N1W=%C{E9_kbA@Kad=FSlx?JFB2JM>&gj|Z5M%qC5Z7}nLUzyTjCNK$D48xgq zN#Rv&H;QtZN_zfGf)Y8iozA~>prSXqhTWN4b;?*#8?p&XP{wL>$(lnRYGpGin3ijC zY0HoYWkdK;Wn3M0bKlK~6iq+z_2%j( z(kRrtadf@1;gekuW0E&TfUm)`1UYArFo~Qth^dp_RM{23i=X0Uo*6mMuYw!I+OGeK z(l*oGN`s4}5IC;E#1`59jT}c^6N#QS^AeT+P>G1QP~{PaV3SraiU;K_lKwrS3b_Ow zis90DZ?P+IlYs#ETfG%54OphAox+xoV?rq=%wJ=+_1LX2|H2HZI}fdA;>Erpr%s4Y z`jp31I38o2W3=G)DK8)xVT(b{O6z&SK79aaI=r2CRu)D9;yvaCG&d>UWDDf%{4Xlk zd2@Iot*2G4Q%l#)9nJc9_1NjI2qE3iRv2;!FY zWt&PW1`#_}$+_tjxcmVdXq5PGSDxm5cJN3%?oWd6>ccQ`D;|3Uao7v(&-&S~A9!U5 z3O*^4=-&uw(H+_iBf)Zy7Tf*UJA8_1!fAU=*_L($GYOCG)0-TAVJs_jPyjEFZzi{H zlpeWsd%|E2dZFlv{_n#KXkUxOtvOfC}r0OKpKD%+IUxlkjS(x7NcUmg=di#tc z_jAQ6*|eo?Iaal@-VO*R6{DKXA1}RPsP%8xEzGd!`6f6~#9JX>U=tHGDF#0P*{IT&*;h zv~=+ATk{RiK(nm_n(`LV}Gb%%+xA#wkAxXmRHxJz zu+>Z2nPIfrRK6al>E7N$!j6a><-=Z;2J9dBgQ95&_HB;8H+jBu!>5@Vd^1cwpL~fr zFOHl`Y9@E7k_G#kO+28EF%A(ZozPW={RzhRYDb^QbgWp7D~z-^yM|XGn|1N|4?+6Vd8?YiPaU2wkS~VBM*6d>i6x=tZ?I;#Cz6}Jhn8So zXQ#Q>Rs%ioO_HOrYdtBD4Ry@1+fINdYIRf2cFBUZZ>pZn@NY&w^r)f#$ztu2Cu0bf z*D-;+R4Z=)Ij{kFBnyU221-6b9Rh)Cr?yRfOk1m?ko(^9)*Sn5!x&8yA1$JRp;` zD&_;*MKUznie?e7<<-4AUEzsc;v>`Dpqf9PM@OHTPxI;EQ!)cg zdB}Ynu}8E?v)y!QCwUFk;^dI>SgTldi)keRE0@k@SDcp5d?#A){&~m7X1C}ZQe?mu zv?ZH4o=`~mQV~q!&~V6G+LF~tLD2;PRB}? z4f<%-;xYpc$%I-S(vjXogGDAlryRaTV4?cPmAwrS;Z8Yg2db*W-qi z&yix>%q*#uo&!5XJY`Fq0K+UN+T-l3_5pui`zaf#fwSn+bxK2?floEo0(*nUJHq)K zOl_VqbE*DD=yH$;-H{>=y+|56kH1;0c$sw8N>fdSEVKZTL z7}$>;uLT*3UW(2jNb-`?H>}#+PS`dz-b8Gx89l7X(o!5Wy2|txQ@ILlE4<>E`G0)vt5^rlOd4fvm)7RL1y*Br^emjqB>(aFR2YN1 zpBm*hgHgR5Gw}aap?yq?3f`iQJ~ob?B~Ks~lk5Xzdq@JMjJe$&7+MD`hIJGA1*E03 z74Z?1^W+Nz89pYmIWF{yw~?pT=?#`Hn-N9R?DejlbGkCAVpTlB3@?%?d~Sum!6yHa zQ*W+f&mO=FwmGPtCy&{m77IL1E{cPQ{ z5v}rLCJCZ#f-lN$EWgt(L=rKN^71u2E#<#fV6Y`a?7K)m@A4r{)gR)}7W8IphZlUw z4fuT#3D657&Q9Zw%Z{#{`=~IQ)~WaF%`+N|4G<~ABItSgosE&(Ee^C4YM)8)lm;Yb6mpYmY)PqL z5o?LdTD`?2Gl3Mfvj{V_nR%`?4;9EgxV25DV<={vtC5S&$jJKp=pADooK|J{)m#ho zqKfEXct{G$&v2@u?NYb(J(CGX-G9{9$+j2is6SoHwR?mZrSPiyppFlIOF5$Mq%iV= z2j`u!>x_J?O4OV=LpFrGdn1JAT=Jg66ZauykrU2@i8o)UO*=PG?_8jW;s; zS1L0C?>;Kw{At$SYIkPm%E_e_5gmJYIH!d93g0UQ3pfpVzPpvagSb_w&whkWTh!*l z;B^sq>u*~jH;#`!SR}+CNX?9O)lE}~GjLgRnDhz8@!_W#*#igWmPI|IvN36kEN^Xh zEm{FHX(Na7a4tpQa?kW{S@=7h^w$Rhifs!hs31|ruzNjQWPGCN`YSCRU6sI`|f z3>~n)4U(Q1J(*RW7A71mZuh(BFlwc-?FmOb@TkEIpB`m#ALD$jfa{^m6=M7*t^urz zSr1n)Y0sB8v0+GMd7QF^D89=t0QdQ|gCh^ZH?eDh7qp>TKYc@KQ4j-%|RXFA9IlxnJod`G=wv=n0WT89ll0_4sAxd}iuuju*ii`6=*%PSG#|HYh(HAAG3(W#TXpup zY!T2HAdR?TKVu5RUmHO~wthF9#RX!ah!x@ag4T?5f6%hZlEr(an+13Y zZx(>`gQBlf9vk=4k2#;us#0z5Qb%ICvF{9=)*Pa+6aMiXkM~3@EBG_4`2n+a5zZvz zpYa;WP8BqTf zzHS>#=~*3eoZSJd%49EMsvatCM9vjDsW{G93zxOv#x(XF2}tW#MVicfePL}a{=PN* z?&Jb@jKD)#2*+ydB@Z--jK6nj6uC=w^mGu}1$^LN5e4uJezQ6M`FZ^*8zFwwDTQJ$ zSS=ytkCxt6Emt>vT}8EDpl6jCRDOzL-&z0)$er2>9I7g%#$tVXs@gId7E`IVtBg~S zl`6Xg;1SYOy)_SdcflT6TX<09V1a&cNaYGk5t49-S5Ne_HyqcVd*zt#CX$$(a&IRj zQ`&x07zi@T zzjH*1TCc~{LzDFZW^&uJx@um{N{Z;iOjzmsao*`O({UTv?t}A&)V@uGX6G^5%AUR< z+%90SGhSz+00SxgT!a9$1>fJGrzs9_#Q5VT>fimvtS{Z{v-yt{K9Awy61jj|D__=| zk@13VI+;&eO~7`b+KJycD2t`Awer5A@(0R_uWBz8(oZ_5-As8&NyRpO-^FUo@suwD z8&9t0;r4lqI%a}fKGvz3)`$|N{kWz7sA^N9A6PpX_BOgIIVN&GIKR#M16;%PTfF)z zyW>ns{~M>ynbG~DCu6>cQ|e@eJbC>dZ*}9Xa*tmy-?uL%oIarXReeCIYL# zBq1d3HIH+Q*OC`ia_r)kCTL!tR-zIhL$ID3GO+0#_Xlt27d!7dGz+nP9kl8w`uj53^@ve01?HcPhTB`t zEh&_!N;g}xP!+Zl-sQ&=w5ITY;-2^2+HBW~APG0A<)yOnh-iv%*W_#3Ty#*yB1ml0 z67Aul+e-my29^($Bf~$s+(+I@tZrc2C7%1Y%tlRLE@53Wliek$LT+)Trtj8t?itV) zmVtr;hQ}$*45>2=SYN(E|E<{B?EBEXK$;EE>*(mdE2Fva>?46kvMy;kM zP^P4d7t2BJ8AH8=)M0F>xp0`7`?z?f;kk$Z0oMARS;OS(`PC^Q5UhbP1oK_Y6+VVr(j{Q zAFkSM7TF3!d>jTo92>`P8hR^G>+>wuW7PTfrS;|7l#U?$MrN+e#oKtc##+m=I6XvHj;^O5Y=g9&Ur+8CE40 zHfAakOmv(ityJIfpgiaCKW*=`io%|UM9M-B?Vhv}$D6_^EG_LtIMh-Q+#1%NsBoHb z?Wr&Wo76`#d36Quq?Ld_+g!@09EItT`Q*7V*|2z{@UHC;F(hDwM*u!QLH^srRht(- zQdRmN1-e&*EEDWHofjW%OI|}mIn|#UBc)KxL^k`VlinTK>xN^$2|4i|PWor;eQCgF zAJ;^!t!-D z9+8(&_Dg~rwfxgpD$1XKru(P6gmf=#-7kv`1m;ohbYvW5h80k>t2-BQN)z;l-E`M7 z5(=+BR6e>YO4LjRG-`u}A>x0!ZVSei(nI#{AEVYZxP3OO{F0!UJE&1IS8OLgU4rR(DFS-Y z{XdeadKRhQS#Ag=$ z@XCM>F{T+TLigs&kbfDI?zw@ZD$+>&93ms+lPj=Fv8p3S(D!4?*J*?6N#$_k0CDL= z0O+dUc|v(^R~m2kC+HhQ%X>=DQu0-G(jV~i6D+M;K&iGeiK#%)ipHdE^maZNZ;=N2 zd~j;z`-v6$H0kr1sjKH`h)v)rD}okn?Txx#t=P!7TaA76+P+h?uW~X0H;VmH6#~Bg zYSC8efoS;E36YW!!xpBcCBNx_Mhx}0mD+3P0paNz z!N@phRURTILna7r}|~kd)(9uQQqcsPPS6a{5x&(;4k-+^d`ghH}J6&F-%-^uO`Q%~c zmj-2=cb1&jLKIdn5{pFD;3ybK)boe*U2!Q-&^$2>~Kk>P<*Go4uM%<4$ z&32`TlL78WAvI%wWlLI6Js16OYab#ZJd&3YM$sZ1GqENJ`Ll|6ZbE9NNj*k1J_6Px zKJa;e^qE&E=;ozrW`6(gXseoT)#*5dQ@IV__Tn`?GVyaUw637?Y}F85s!g&8zUpy; z)_5j9OW*Za5A+{&V@vdl2BCTCn@@!LBn@|dFk?kQJ-~H<9<6pho^cR){ts7#GbH=r zXJ1Zbfw82+`HUH4Lkt^@A1IBa#ul_mYd-22C%Z$gr7D=;+J?zgRb`p*8~is}6qO*U z{2D&vGqDwbET5PRK516Y@@#ow5VBC#c!eg@`Z zPJNA-)I8!Qvh(zj;D=#=A=g_dsZveMEAP$U!>62qjeU&77c;g`lZSR#GWX8^xR4i;PFCML%+GERu*>q`HlNBlZvM*sB+lunx6 zBosFo5v+cF_e{7DRrv(2>gPc&*aST!c9B;fAFO#;w|U(`WMot|VGC$IBSB-KCi2Y+ zLut+DeWQ@Z74s&v5u)fb_#JU&w7?(gmC?ViVffEaCV+2&euj%Kp$Q#*$a+wI4k>nV zK=PJ6kb-F-mkDgQ9*OzAyMBZc<3z`qrz3dL)T;vfp%b3!m+&6Hmtnp$nTa0SWNc?-J;ouAK5!R8GXOV8sPQ8~ciavAEUMqfTB&{5!p3KdsqY3D))f zBeFC1^8cgx=!cAd+fJ^$%ZK0ufeh8jof-WpsB>KyDmX@tsX!-uo9LetYan=0(=zut!GhR5@x5eqgJcI-jDq! zQx5cew9}jh;iwvRMjKTfxe62BRaz*dhK{tJ%7=AiBiEDtRFJq#fsemWliZiw16lGe zlYkU}$$ZsIe6y&cf2db6?k6)o%Ou(8Q!ypOS`Ytkoun->A2 zfbr<&4{u>6zqk01#~`Cng=6@rKEWyZ#0g>Dh{y=O*8w^zFc2Q+#Ox{_4Mmrq55rYg zyH`04LlFf*NZ{EQekHuSzUVJGcMeR=fSA@Tiu~tQ1iMpr{hUx0uZVJOyyr!^{riw` zy1R4y9RcE9aZ$)9!tOH^*aaRg`2~JQ$E0_i9*rnpg1fA&Q{ZzJuTLmOj!BGW zYV`1b%Y=K*rmpya+jZOy&36ESftm5q@PG9DVWShx%@w=sF3b{A`rrLViyS;oaHB8s{ zgFiF^bZ4)(h?_&?7&p6T8=(5bknnLd+kFm5gQ-3Mcty3~KCRQ~_fAeXZ3uMRUEd%& z;dgzUNa$oCCoDKAgm%_UF5@xkk(}|6d5=REp9XnPDCQXuRfK2+0VP7u-Qe<67Pf-m ziU;SB67F?|_5a!k-MKXL?p*)If0kXuu>R+mH&B~$>!+1=a}YPaf!suFzTa6$-AII2 z(CPUGLGL+n1S-@MvG^{-*;;%h8U2?2fpFm!cQt0=YUf|N-l(Pg2Fl-FaNEy7I%~k@ zyQTKR*&^6b-2tl>5A(w+6 zGT{W|xUKPj?qESgEd(>Nov@olG$vy)R5MQ5iZ>MR`(Frztwq>FM+g#SVRQVc>vvon z6?SIu!P9!cySo&PuTz=)9<|yC^d+#<&w`5BU&ewEEx{+nOe}>=M5^$gnKbBTA3`T0 zMV=;n8nn|C&Mb?pe*0LiBM$VJf@iDi&vkyH^_n0lBF>0MsA(6DwwrLAva1Xv;~9<0 z7cz5f5PrXxy%P>s$1(w0Sh*|L9v`nrd)?1K>ArRs^`2yTD7&{4KJP1|LsXz_N#M#l zy?uJg&s;F_&t8E61T$K6^wukRa&r^QY08Rj32F)NR;Qv?eY8WNg?qu(N_@l=wTqUV zZcr4r0SD!ZWW4Z3FqDL7WT~_#5C>4Q&(JSS25|U>ri90d5-LQ}oL=(p25i#3=F+=U z`Q&(hfxV&vEbHD`Ogn;JH~EfEl)g$du4qcWQ#*;ADZZvmS@VUnpz*v$E{eH5f>G#jw(9^1{>0?LfQ#VUU7nwpsW6)V@Z@*gY@?gNx<)Jss zWkT{Nn&;e|A(!8V8)rORC;z;+16~sQ%x|%36KchSkU8gc_~qYngI<0Vf$hEuIs8V_ z-e%=IpXkDcW!)1hJ~DtI(0sVGG<^_p1+r+ejk4&glL5o?L(EjaiZyn6^&o>Y1g^1T5y6A)ESh za3>)1Y;>Q~B(5tMw0@wciBqlO+wb7x6nvIUsfRwPHP^58?f`i>(T48&OVi>=kHtAq za^Xe_%uM0qU8QeG0s~&=0{(Ld7M$Zm_@95L1hi0gO5Z#KjXY~r=&B>Qu}1!qd`4@M z#!&kkW098gGJ@Z)Qro`~-(j_6A?a=ed_ez!1D*VP=y(SG;xEkA3FL=B_J*S;@BZ{z z3ZZD3g(UgBC#khU5SZiVR3bE+36%v}7-nCeQ2giWW{?32*X zDx5#hGeksz;yN*8E`ys%>_e%LXIC0mz74#=Z-Yipg3r%0QLEL1wGSz#>b2-+@B-2y zp@xa>C{a>QLx=of4M3{EB$wer4LO^ym{MKp(U+8mUdt|4|45Zr+KuvEv?kD?%uTsA zgIwP2KfVF_QuUAq8QL=)fO2Vl7yX?4mGORmi4V1_3Rg|^`*@G6DZkmB6ZlSoSc`ip zk?-vr(sB~*1C)0m9ooQ=hhWE6CHnU4eTeZwZp`XSG|XfdNK62}kNETiIq-Iy64sck zO^44O#V%|s=?DE9yMT!5$jlR>WqWjKjw03(ClLs>dz&cs18HU)B*Q?K%Iph^afx@1 zT8zdWzNOFtT9sNR`(6c3QL=ceKYP3(lo~0ogcAt0h|c~-ad6egA>0$JKeQ8*@H#O) zI71Y;4vYu%M^4BwgAYl*P|edf(VcQ%usJ1}ca(zwr}fjb&TWMj{qh&2xWK|bFbl!p zop+-`Go2=tyKn2>z`Jn(*9e#8BzFaQ19Y{j?pO=@N?3?HwoUZhg$p77M@v*3!M8kz zvNt?hf5e&7tWe$pl#l3wT~gI#p->^^-Q}pi4z5rszp-hz(N_#b9%~roF+Tiqv5T#; zTl~nPQEEJz8$qcI+c> z21wXmVW9dcN7au+H25kU93Gb4lvQp2s;^kyTt3ZNf)l? z^!|D6XU6e@LHxg`P9YM#xj^S@?l|AEmvT#`OPlC13y2HcG-NeTAbL*u<4%l8_Y&+Q z6wgCCmqGxTNW(;cyZ$R)!;rBgb%~|MMS76o!1^B~baOlxbywD+TXovmCU_a2Zco z=JV#aqRQYMh}W?iDnGW&1B^5k$+JVsOb(gAAO5eKSPz=|p0RAZDGO_rL3zSyRvX_I z%^wE|HcYU^a|YRXZND#MFN&lEW_7AxR|;1rI9pFngfz;Hr2di|Ut+vZO!a!P*&i?; zc#ljt;WMuR@&$Eo(4Nr|zj%3qlddl(l#UEhUL-k1_~7b|OUy7kLC0dzU#R#I9Q+kX zAFeNXN`9yYt!F%Rf{P;x7Y^Uw?W%UkWCfv*V&C^^zH6kOxbjUwtl6X7GF zV{x(*lrNnUfV;52yM+99BcEHFJV^%bfr^W;U5wtMTKv7-B`Ld7dVs*62&48l{a#LL zE>cW95%m?#A34|+M86qZ&(*KQhdIGy~(~%W~m0 zTr4Jil@1FNx#W1oq-wxZmG9yO6yBpG${#CsfW7RdZ*s{y#W=cK(j|oS{gfLiwDCWx zpwraCJ4besLrL~mAiqu3e2v9e2Hyw`B_lp$acsa@nI65WHsumwtDGGI`A^J8f#-!* zBs9FvVqsyzBTC(bi~sl*+vyS?A7&`KI~P4zVzpSn!C=RyY^7%E6>=}7dlx*6_EMhk z)$dvL^Ggf#>*_0IXVvf250qDMHp(nd<);y%jNz@+1Yr^H@f838*`r7HlntTpA$crq&?dfxT(L)baosu8^ z3{559k{xa%#OdtBeOB0!ns@OL{^b7f=kNq|bPn{Bs=uwjD;M4w20>?V$`k4L$?70= z<L-N-luG#T}!hXAgFF;$Gnwo2@Ix1#>dT=9N42>VP^ z8l4oxbod#A31#w?*| zHvYJQ6L;~Yq9;bvY^X&w$o1~3PldTaUpSxS8Ys?7M8Xu2k)nfFFOt6v55v&;l^bX$ zq&)-MzA~7&1#s}mgeta52S{^tDa8=tL5@P%_?-u$Ji2E2&L<0`QxZ2kyA#0}T@Ga! zO$w5gs{Nej+`B@t3xf7GZ^Wj)94*XNWm?r7YVTKNhH5=8<(B#q#)!*nK^WC8 z1nMjtBPzLPU?T3Ie=3l#XbMs{{>QjSRyPr1G6;r|!{doAJm-eVFH9@Bs_P{kwEP!)nCU!1DN=y``=`Q6U4gn?s=wDr$(P!~UrPd8vGSi4KNrhUQ*Ri@(DJFD# zAoqSLUG`WpNmYVhmBkU7`qIF|=M5O2l1lk(AXh?z-wUBE*xy+-g+(of$PV-83Pd>I z!zMyo)_}}ZX~1F7;9uxV3NK@jfYB&Kn-pH<_kFY$Ntj$>s*3wxlUe2EIF0D?>LDAv zp)+8m>XciUZLO+fl*R{x@Dx>=N^Nfl}x~3;f>Ri=f>$2)dqnL3ZpiU!B(TOUo zMQ~)D!5SSK9w|Ec!$GG`!C!8dJUoQw;wz;4GH^}#+c60uM}{)#eMk>K^{_MG{5qh3 z?6A#8`6-r~y$!xLZ=XP5x@tl)=g{MdS1Onr$;o)F&EbcTBoOlff_oy8NW2ZZl{a=2 zX)6No@CT|q`2qDuOIj=CN))qmF&w)4i3XPzGVz%y!hIq34Z~Ndws&aMqZ$0H2Vr%>!5XGh;pXQ*JtT+Q5 zToych3Qn>;b@)M}-AQt`%@M)B$hEJy6$zG|?k^wFpx{D&vPuO5 zUB_%)8+E8=fV7Ag4Ev|pqy*||f+{1Y7K{G!bGai*?^4j1en2mj$^DS!Kxf0BR)(R8 z+XidNsZzyl%2QRhs$83J3bc}*v>nPKF+|1Z!UGoUADzrpbc!>;SsO7H>n-!Z{OB*@ zvhD_%PFcb{Bv-i#eE53~rABZ&MqtM?lEU_sWc}fGd}IB2tLWN)Fc``k;L`R@v(^-J zH{dQ0gzZWbKDv0XL3we28{cj%;b+}AsU(Myy|^*EKp9{8%j45$Y7L2|rV(|` zH&HG+68>IJN><@C!t=xjf-?R2fnQefuuThd(qIftNu{@7Kf|j};kNiG!<-6q?IE)o zD@)3iyr|7n=4)vjpu)KvjM~}>3dc-Coodl~CH=hEp?#h13Zrf-j|IY)h%(9zR18-& z6{B6fV}YN`8YpR!W?cL_NO+RcD}Z=zkeZKrcqnZ-Me!v<^pK7+X1EycZRO$F6S?Xux2zti}<(@;Z4NUP1@V&1t(E@ZWDKdog8nUhu=?NPF_oPFBoY6yAh3VD7bkL~5fx7K zvF{G*RM8FTjfxa3=G)hJgYi~MZ=>jI`nC;{oP_9Xu;FHxG6|g#rxHVQCf!r{2RoKQ zz^PHRl3Qz=Fj^S}iVBS#zecgCM^uP8GdmMHFO~b*tr3;VbD=0|5g#ZuVd^JX|2~C$9x(+}y0F(LOBFVTz`v9=ig%03q{YKH=9^2{_K0R=rP%z4o7mD? z=PztEZok07Z0~E-)y$V*l)B{^7gdqJ=i#hZ5s;4oTOupj!><#w#0M;vsVyBYDoT4d zbRhrE7@}Tl%Z1qQ%v1Q^XOMI6?dR=(@5*X{Zj`5Ea#AY|;{s^BlpoAfh7cI&clPd3 z#+H0`R_fRNMDLdWjiC)}i-H=;3`&|rB2v8Il24l4=~Nmw>taT{8k;AYJ!$7ccZjcJ zI)Z<4RBSnPY?Zok08+e(5!z&;t9n&H$PZ7=T4`o7L;eii@o^;PZ2t38l)v?DUqfl^ z+aE2ILAbw6_(`>a!NWuRFhwVg^y2jd zmVdG8f=Kf1IdNel#N~uZZ}WX!yrFVW{=#L*Zz_x1Mdzif9lJ_R39ootC>QwrsIn|b zIOsWOhj#Ns!H8htwXFgtzYW}vouSTmlJHLn5Y=tq#0(POz_n04L$T#5f;Z;Qyt^{@zQ1XeWMJg_~lZp#-b*O70AS-e}#$ z=?}28Jz)=x`-y?C*KSg1C5LT|4~B*S@|^i?Z<3*kR#C4XfqWXWVU~dkdWR z^O!08UX+;B4+@s{FMf(^K4(5=6-Dml>^9A4T4*|F{MSf1Sl22wvg>H90lK-vnSBx}2az=l{|#v?5DEm*hEv4xY6b zcFMb*Xqm}d?X1)cV593~y`I82)%m6HU6mv^8nuwHUJqcO^!yBcqB?XcHOot+byKP7 z>+8Ji`7<8itbAC!gZXE5JVcDt`p&w0LxKiC$y9MY;Z%duZ?D0Jmq!X`I-Tu2Fptsc-9R&)O);ad(ppX^-0Skr0-lu2-9U82KenRpwj`;w zLw+Z64c@$w8zi0^_sJ87MftBzCU7W5bBLiBX%>7!4GO~oguc2#(Z zW&du320?OTQW+P*#diP0(+Su zY{x0~If+P9s`UiCYR5%szTE0d&a>k7&o673_!6QAdGdV+VUvA_1J@#*si#P5;@U5O zk-t*w5C@sJn`#=Z+qz}4_c%Wdbv`ebcs|oVUi4Skdc8)uLwp(|=&x22=HH(RW4ptP9~iSs-eBJJx4{3UAKk9% z5{Gt`K4ckOrLpU0MMJ6BFvDO_K)VbAjNNI>R?=PEu6XNKroD!bmDK7vJ#oFx1myx` zEpE<$LD^jp7=py?GtZlhItQEP!`ciIkLM|r7YNH-M--Rkn_L&elwo~G*EoHBx1Z%-_NJFsoX|LAieb>Td0hAqOcowwzp4_Hu08zai} zhv}%is$QaeKIQNcnZ3Whie?Ue{{2I?9Y_#bD%~29uC*9_V+=r&6epjwiY58a&rkh4 zi_eY&19w->>mp<3O9M&4gcXIS0Qg~is7-Z^en}fQmjOGK#uQmHCl8Po$FshX^j!7C zc`p=4xr#3RlJ@9LK&u1vIU|nO0i@-o0>fY?0aZ4-brnX?^4EB>qFt;J#W5WZOvRUi zLqd>cqx*`{Pj5~lD9>5Lv(8}BW8NsDe;(tO3DB>PL+Xsi@D-)Qd_)jlyFsMrU0;&T z9ch7u*&!X{OQu(6`NHELX`O?`Th0eQQeCOBU4@oN5@0}{^5H5`F{AHk3NtA~B-{&X{}r|_IwRLs(5gF8xJj zMN|6|!Rk>zpYf6!{gWPiVj(zE5>YT8zlkD>7ZeE|G1L?_O+71G%&c%qAXB&Z^pQeWVg&uWr zjDTb69Q0l2BH#Fk5r`&7*;1)kvVhb*j2J6kgRL8E0B%8?V&N?JSfqh6P5daD)<4t< zoKHopU;NV14#4kSHv%^)h%2qpU9NZ`Qk_oyIR*^J=os&vBbKWY%%^Tb`T}<@DitJN z$DQ8aK-gTS0O%kWn}4SDW@qW0*fP}JE@F7SC$?~7HJ-*)M{22`bB4@d zXbuEi=Hj^{s_QL`8mpF6i!F){4?wF0Bb!kVo=lZObH0B2$QA)>DhWk$Mf5^P~rdk?qufD?bI>_F#f33Bd(|C^~x7h@) zfdJm1%XA33s6@oevJHd;0Z91Nm4XnKuf?nQ2Xn*Yvij~GY^Fz?GHQMpn7Oc4o>f-o^go6Yhg0?kP;sq-oZ)SBwH#rqv~&VjpN4c`&bJFgN%oF%)}MJ zocJ5FLc%azZPv10SIf)lJ0Kv%q249bs*1ef&h9#9V7+Q|vK&sD6UE-dBo|OPk;(Wo zKS{1pjf#Z9c-r1YgQv#ZWH|oP`@;0voOlV zsO==WULbbM1NwiRz@-|WdHG1xV?c=8Bz@AdR)hhW+==?kV|T!#kWD5bmVLjB@x=DT zVs&RyZv%$yz;?Xto36I6KJ+MKC$-wg6W$6xf!1A#|O9FsJP1Ig}Qv(7pjU@ zaoa`R#+aXj#awcswQ6PRn-b!k83YLBc;KtccPA-%57{q)^Y;{>s0!-EpPpd}sTdU_ zlT~ebMtyFB@Jh7c(a)O;A=(RT*g4=CS@O|={TGVh1T@GC&FLo7IaiG~^K<5Jc=y=G ze~Ndm7`G5Sco5=`dhtTRaT9+H+6nKb;{xvBJo@-)oyxeC4vUcgej9LANu>{1u=*V@ z7&Fi(C1;SO&lxro{pU=v@4q)~AsPXncs4ud7(m4f#|a;+?e=$Y+;FZU@>YiM`qPa& za~bQ<;C}l;vr%sM;6zi{wLlvg+lCb@tdeb^-0S{%6z6DJ&=Mjp6@n47fP2xe6RRSR zP}*zxP(;qX*Y+ATjpYP?Dx&lLoO<}p7`_x8)me!kiZHLEZL05{0G^PQT?Pdq)mdIt zuvUFksVXFJC8YIw639`7m3Sf*7F%dzd}?zY_<9lUc`Tyq!VJ0Ym_Xi_nI};uecVXg zm6bz~6~ee!OcF`BuKw7*udpm%*h!4vBIQYtI%YUyP0>Zl1;OKxAMBqHU4VL>x;Lf}2{*>L#Vs=c`sveuV43Be9aOroX5pY8Z!2#IWn_K84NGXyJnH4 z^Z%|<%quX}N-r{l-+C=76s&tr4wT-VV>~P#Fpf`Ouf*RVacPH7ZAMlg*9*gd-b;f1 zgZti3dg!{9v?1wyBiRQm&&P|rtnM@v>#%#{S>XglAqz~DP9uJ^5=T#MS0ZY7sQ z{EWuKlegH&1~rCC|Ijn4DZr|NYMRBg0eHfc9!5y-gaHZcdf9^zM4WrN7WHqbK(2q= z3&cS&M9W@>r;<0WoyRoNJw*Pvn`5$1$$Qnr1xU$Jl~>n|tR8qMZ7JQhdCz-b2^c2H z{~gSL9t2*hR#C(c75- z^;*o+Z|Z2HM#wBH(@hCY9Sf5sp8lsVOSnRB@fCa(p`!+#B&wCTe+=N1YhlQZa$nW$ zaNI9=XmwY{dkhD*+G$*BSW17u73Pl|AI&-=J(ekhN%CI+H|wjvGzw!jPuI$3S|D%6 zR7W?5XF}~|Q?93|%!5{g^4)ZiT%&BwoW*;O#lVfC`*#BF(7n!qjsIZ1RJdW{chFq- z9lq7FiB)Vcntv0>o9#Vj00e%6KWjk-Pi=-qExgmFRjp~1J4cx@r-g)V^vrqC3Ez3$ zimUjuO5>IMW0Nx+m>`nb1;JG+L)R?DeY7{K@SdTf9GQfw5SA>@N*^nMIEO9oQGjPJPV z`tWYe>Ht~bw1@z0RR3;MlfJCQB^)Dar9cH>{5dqB(G&2KEIK2K+1b53Y-<{ z-2cN$;Usc$lWTq^rO3cVz}Ln(HmTfswjg&FTr1^lQC8`EB!~)%P)&ztJ!LtuUmiY{ zYN0h=!&rbVgOEhp6Ps@OYyl4-1Mo?92tjNPH$z0*%@y$`LXe{%6xI#YgNj#>5(^0H zGqd~C`?Xj?FZEj0(J-uLDt}ZV3gpNe5Ct;3&Edb)zl@JvBQPOf@Da|3Z^tuM{J1)a z*nL*qAEIy>@V8Nv{@L5lyBPbQ0J0gk=SH!3Pc;Ek(uDS!Q@A*Hzm=Tx$D3HzRThUb z#Sukku;6B*w0ycAts{(SxBz1Il5NOu6NWE1O_jb!lOssPydiKJgjIkY5p+Rse&RVH z-R+YJg&l?amtMk8ip4#PB4x`zA13Q{*(YLfKPsW4 z;8Y8;xiIk(4K&@5Ec(mK(31XYK~*Qf-CxDJXEl+?({exCqwWQ#Y*Ik*ciG|IZ`FHz z65RK1rrvl-PxjUUF0q|g41XF|A6n&>XCD?a6sR}3n_$gRy6l}j)Ue|X>q4gRrFyeL zLK56`$3>^>4bYXey~hyipC`#Ynn48G_OhbKuP^&5H~>RC{PK6WYcW8A*-RKjuVp77 zHl9(vRG9XR#L(84B*AmB8(pF8LaS9GS5c%y9pRLc=S7W$gAyz z3%5>GbK_&B^qP}pKSTVuKl*=7ji5`^*VZ~=)X@P}li2&;OC3QADF{?!mVi`?^&<^S+SrHl?pc}K=7PsOO@Dv43tHSwLC^b0NbnSOSialj-gzEK&{T2YM zzkgfaGFt9+mlG?DA?#Xr>V@{8;Dj0ID*-@TM64HXpt*?;m zfD=z-GwTRxvWuG5S6V|dulD#ip9X_|@vo++XJvlYV5=#hkH*yCePm;qu2Ha8^oj&e zv3U*FsXA~uAsD8&U^zsew`)~0Bry$6_Yk+ymyE|Zg<V)pOm3S)afpN3#XOBFgDVv%HVt1YOP&*{pZZpjb~T zh*x!poYI}4K_lFx7{}}bj~7cz4yPs%9CZKzr8>jistzIzesD+fv&^`?AVPwp=Z4nDZKh9@*XrH zH!TLVx2IscsceX|tg>@a7nBAsHh*X9IV~`X4ORtgPzr$%A7vMKCe3+jy&at`r~~7j zw?9-qbxsq%YXh>Lf#=z0mJ-M2{C6_AL~(S72cQG4mt?G=@?GI-?0bhE&`SBDMs3F5h= z;NAk+>j(QKR~0Xwd0!I~AzI@>xF3Tbr%%M_HUyTbA8t~g<@d0{ljUaLouLEjz4q)4 zA$8~zTONoORGJ+T!X3MYooHA8v2h_O#S6V0e$Y_w+zYyS*CF>C@1a1hCyAb>Q zyx#nkmzSRc_7kek02A^uf!IZ2A@H3|0KSKxPVJz3@H*1Okg(PZvhD3YIVG3W<3_C= z&1mld){X(nUvRz|_M1Kfaqz}AQspP$&%#=d<-Eaiq7)XJsCWjy2zFe(&%bX~?wseA zBq-y-NfvLuEU&f*-2H`dOIvZjF=R`xtHJ>DvqiNHW4F5cRNGWC+!&k<5_n$k6QX22 zHip2u1VjeZD9!tb*ZDaYC^OeukSBMLT+@WVK+Kf!pcw&R!!TPvxC=5FW^ z+eNMHrXaW~Qcq^qbbJ7Q*~Ii^U=D4K>YT>_@RG zH75N_HQ7sWN#}q2Hmb)7)33GNn-7kL#OTo;h!2h_p&;a>+$llz@aVL!`;Jyc^Xc&_ z{TTzhf+W;sWy0SLVy|>O(l+@d#9`iI0a5V)81UWy5<0U~{Y4U~O-;A?q^_Cp$%bL_ zZ{z-SKM=Lc*I-|Yk|CToY0^5I{k(^Mp(O}=<_n#uTKwMa+ZICK*- zQ!?UgU$|X%L-qE8&rltz_w8mmLZMpj^v@5=1_|kXs2V|dq`!w@ zVSycQ$-OtTPcp1>MuNsY<_XCvQmHFd!#})T9d$88;iR{mQ80p~zNK^A_3GSN?j}I# zW(g5$c|vMDQ8X!=BfEHXU2uNDzb5}73}v9b&oZ3WwS@KmU4_SNkP^>%s$KcikNvk* ztT37b^X`d50`e_Fo`9AUx@!iOq2j*M5on`OWr8KX)jdsuX@6}2S$VCpx{$VMH2MUD z750gAUb&lboo{!N)bURfpab8u$h);){lfV7Gj#}KZn?ntnOXExg_l0(XK+9|s^gDV4{&#>L=jTmAX6sLp&PtZqMckiJr$rh(gS%(kBCH92#r{%8 z1NZz$;-{RY*okN}Ip92o?M6klV#~7ls$6$c0&p_ydxJaz~f6Tv5292W(w!4 zkUG)#k~ai9*_q>nP`pWCK*QmPtD(j;dGx+^(w1DZnh(6h`ON|#OsfTurF7F1J%>ZB(n|O{xw;i zFnuONd^%4e>A>s&zAr0|mETBcpgVUaZuwOMC_&F@sU%R{>?f^a4v0D{F)pr?ff2uI zun|{9Sp}K^rrB&+4Bmg5DEAUN@EuoG&7 zX+zL|q9#$y+>TJfSZ6f7*pjhlQ&N%o{(Gow`@+whNz)K=3^SEp)F9fqXVY7iJQ93D zUu2#=IfiYM7pg{;cHEp;emc*Y9IfCMk*!-GS`R8OhuDogT&M{8OT5hUZg1v%KSTdF zS>Dl}y{92?KO$k|$`^~(GL|Z`>>GVt;T#VS8LbzWy5fh?Y_+q*V#G=wV4_AADhWF| zYUjWNz~B#}ADv3Zm91ImD2rW)tT1G=$R188;%OT9MgSlxU5Z^Y#5(M);?75xtzlMX zZglbEwMm9kSykStjQ)@amp3o=zOLr8pXCiaEb88U4p|$sg$DYJey(4*rB|alzj3MH z^8Hstf*KSba*An<-4BH}Rx->HEw(a(-CQD*?+NGgh84~*Wtu#Zd1Uq$?LIrSL^kv+ z^v4_L^YKJg@8IS^ZmRgB-$uB{kPYee$Nq~d#VYd*`bJ3GBVj}>ic=CobNb>uj~7)ZdpeN!$K}mxxfx3KZeL~f769|_&H~Z?V(ws!(U|SNl-lJk58@QV?(ZXLRq-(q z?)tTgKP~c3@+-wou`ZHQuXwxDq?NC~1lby($<=Dws*Jj^tCktKpVDVBhWtiLo-KdB zl#@ame()#j49Q#1n!ulh9Z{WbSC5wbJAp;~wxkPlVSM*OFit zh)!dNV*C?pSQ+VXzSDfW@hX0dDJnpyDIsaOYfY5z00H8i_{zIzV-$!Gs(=$;Nc4~0#ps`ax?NXPYc^SI_!Y$B)d zE{YLp3iziGukL{1L&oXH(?+K%^+iG&qE{~2;Q*U@YiSem4WZZCy!{1zlPi35$>#0z zdreg5G0gznKj4E}R=5|lHP@aJ7%<-knLRNUFiQOz@(5j^slAvu7!!)Q@@|7Xg_X&v zcY)NB^cx5<^d5LmrP-znWY!)rTlMNPIf7XO%bcjcgcB8|E^H`!)~d{OfJTt^wnIMt zK!j8^ZV*-bl5>!W0&i4XG%#SbY7Qr$o(M{|oz* zdvA-p@SKTwcgl3Uc%@9T*o1rlLy+HI_!Pn#PzU;5{{$D2*^07RqTmM@UOOvOadZW; znJ+cm=|dZZ7C&`m(X%C6SyTTmbwC6S=}O_7`~Fd8z1YylnqMzHGgI=KKCtL6STnsR zLd7gADZqs&=g6lf7?d^K%F{IAgC~kK2bF_h(1Eagk)KZgrtYDvk;nCK6;FNl3+9(; zEH0z-w_=xDH3PzPmWvOi4(mp)d?Rd?O7veYRh^qJT05KR?Dv2WzU~02k_8N~kuy^H ztK!`cir^qQ`3-$f_-p!Y-3WY>*q%vN!ecFFkJ?;Rq_0rk@m)r!PcyBigEbcRo-BPU z=-PVQrM@}+Ze+>Aalt>~JI}yNcFqNU6>slhoZmr-S(QaU#g+}l{fJXN^P9td{fW>K zxQRR;3(T{f2u1Xmbq&kJUgnFZej&(A3t-H}UIrGUS23sZLpWKU(_FAH#cyjTAH2~J zIM03eM9S7b@>*$S+r+-_udz4?6Qf~>d4uVkoP*>2d7@5!$vn4b*;9t_*Mat|4`;`) zNB+cYB@{p2l+HEqi}_-_==Jh_PAr_1cg*#Dzdn{A@iZD|oc}R^DDN_q9m+*6mE(53 zIvY{FtwKwzOFuQv7HtceA-~J?sBZ9$>Y}5c-gqdUe}s3ZpQ_{g`M3A~+8nPtwnFZn zOODVz0ossO>doL(_N&En6laUaeL*AS)8y0!F{l2Xc2iK2dMutlPWw>j^ya)?YrkGy z;PsW~YRrBf$WUCb5}tcPw^;#{7aUTy>R*M3s`3VUs53dtl=Rz z`T;(iwQmrCG38&NRlP>E0ll9HcWK$x55=cVQHF50M25snQEjd~8A;{CmcTIxut>E; z_9XD-KY&3WrG2x~+q}@5bH4AyTl(7urR5Wj*I1<;1zo_Wlx+m3dtLWqwE=Z-XI{rf zWNX|i4=Q;TL2|cSpOR(B^!v^ehS3Z~x3Zj{!nXoX9s4A_dLJEe|HbOJ(zsUiQdPOy zyeA{?*5?a^_`8HT)?r*PDK<@d6;H@_`ag=UJ+8&~4I?CdeOHpuSCdW%BZpAi5RxQG zl4yvMFeJ6w_L5QwO9zz>lO#kdouswtq;pH>IzD zKh4iuQdNpnFOHj9!M3$7>eT1?JV`0)_@-+WY43^CY2VZz{E1S$QGSg=f__$b742Z2 zeL8+~Ki#E`jxecXRZ~_9YCr9*w@;r{wJFX89~~TaujmcXcKX;L z>Cxv*K9Z%1J4S1Ae8qp+@7MNJl(sBlic+I_MhZyI96;YH)nPmSTP(gyN#iE-W=p;; z>C$BGckA%3aBN^eHz^Ei;N=SZTGg)lg*6z z#MX5bxn#xI_tCMWTNpvI4x$$tm8F>6uD3_u1DulR29|ThOlB<1F=N*Sv1YJUUZ=ZC zTIi)O2sFPP%uLZCJI13m&C2E~bx(c5?)HkIM9SZKW$`4ED7Jfy^F(#%y`!DRP~fEK zqSv{+tIidFjo7;TaQrqSP$T|wRL;K8n+iLyH}KwO1OtyxW|)f^_}j^(hd7tf>1c6Z zU0(|HM|i=$_-uyom3uY|K8-jie!-z^5!mx=U$^UkXE}vA?e&Uo9g=+^W3o|$Hs-RS z-u@?2pJqQlOi6d#B<3DL!FudMi)S}tX1Fd!za{fY_ghjM*+Z*jtY*CmVJ(STqttE{ zhl`1nAI9X*L#&bmi+WPSVeLJxtpl6Lw-imMy-wKz9_K1UQZU;_EBz%&0#kA4PW>6} z$ISJusdDH&nRj{H73VkX+Hr1%DwfN2>SVG?%US&5j8T|=958K7?r8#ayHk7NF6UCC z+=s;;4F;{3`PPs}MK!`5C&J9zgtc^S?j3UlXgcRCBH(BnDZtvDfv zox3K+)hKU928O36jXTOOaQqsd)CqSc0Na2V9(H5q4VK*-`rh|MTzFh9*5ozNlkvo0 zoNdMrGY86#sDuqHJ{3PBg(TrAq!X&kzTLn%_v(Y+#xN0ZR25hum9P8+{iGnGj{ zs6V$Fi{I}8gLzg*Lstf$sGHIW{n~4wO4x+(dGsfV)x&o?%woQ*$wBIHrt?0+{Yq;% zPX&Y^4g6nk)6Z&sn&CGi`hFhf1*_-I@-I0rU6RosJAIdrs&INIu8Y0ugXVYlLEDBBFXW+hM_d;NMz4JE$sq-Z8 zVUMml1V{7r7;e|7yB>aEx#w#xlZ`pu3(DbA9s&{L&i35x%y(6wewsxIxP$0bNlX43 z$F*7A&vx;){gL(cBP;R`{2c1~`OS>tc5tg`Jmn-Yiz(bm0k_Joj5~@p=_<&zAzp}a za7#+J@JAf$G&|k# zD)*)>{QhYh^;djg36ggHfCJGAAtxkCUX9mPY>mmYsCia=t)e?EuX5Dd4DF#A&px79 zzf?8zJ#oI8=?cbj7B_I^X82k483-+Kyj28cj@Rj8-XHk9j(}bY-p{+IG>YhPU8<5r z90lemuE0sD(WkE;(T@j(xj#T*&RRNlHikf2$CcX_ZvpO}nPF+m(!!J%N|>#uGZJy? zb|ekZ!%T&1tIclK^rrk~xI44-$9<#bu(V?e%o>8DDeHWY2}HgQ6W@6P1g0IB#GW1j zlMj#r(taW)ZaT+d0xVv4Tdq;P=+xk>US5vQCNgzM{L4#3kqL6HI#66$G79>$13RJx zm(6DxTX&<=6^1p;)L2)*y#UaXp1EA_LEv56zfuvI4>z5tR4TqM*mOsLhFe)eHidZf zZpJ!Bs*Moy^(@J{)`CCd+|fW5+kZSG0DunXjy-(Ug-DQFyTSCDS1is-YM_1Np`{ATst_%HeQWkP)v2HKV+$=`GW$R+E;nzLFxsa` zvjDMYvQX@@g=26My(trT2WN>`7x*NpT8xs+Z6I6y7Vg5OP>nW85m|cF>_CS1EO%gC zRL-zn${m{h0SbH-V|M)%f?jtN&ow!Ao|O>nzlh9}P2GW<4sy+9?7J)N6#)rE^3l;! zJRR!`IHZvJ6MJ2MBf5o>RFSL2e$_ybo*=L+llbwGP#ej1lXExzqt|0t#JbR+nrP;& z3CZTaY^RhyfmJh_W;{J`z{bOCyFEAZ<&(MftHsrCB;MH$Ao?bd-m54+6pj8!d{=Z9 z==ddLkQI($;GUi(b6>XZn`7uIHFD-mpr%dG&kyw1)RS^DS5Emx_j5mo>1~D_o!jT1dhlnvLMimkbF_al}jhskh^(Tq__;ZqDI;7fA>ePP6t^;9R<{ zbLGo_a}g)mElUygM;brdYAYP;o!L$m&t_8d>3bKcCWfL2jfK}$8&cqd)+l){{YnG; zv=vacUuM)!eNI}tLU@1zUBBtIMGpuX;&+=MPT5wxAvGqx8@YKB)HIa2BcZA7WD}8Z zp{V<6u!#eoYcSj6m>Vy(-3pfHT5M))jG*$I2hk}?!n!OYNnVXE-U2dkaiYh0$1=A3xwx0IV3Z zzJm5K;a@oOs)5`Nqw1vqsoMO9$3t&_eZnm(16Y#-2Gtg6)+qWtXFuYY?+V@!{8E+e zC^LOn@v+;3;Fg@U@Ymf+6)H@mPj)46JsWKAe7(bbq$L;~%WMYBL3e@{SN3p`)@4dN zuEvON?+**3zghmJPV%M3{!6SJcROXmWR2~U3LS)U&IJ6TOu4z4KVU8uyi-mj-1mCO zO=X>bOE2<3^Jud98#1A@`iJ*?KAoWsROg$~zM4;DXCQoM5{L2wr`RgIG|!^8|m z;2&=W&ux8GMT;!*swP6?u7^%TOVwGk=x^3hKvzh+nl4#&d#u{1O?vqN<;#-M_1B2!P!u%sA6P_ZmR#>f zr2G%h@ldMoInI~dwUYyqt3rh(isEYWUNwsRSM9hnqS~ak0)~$`>P(IikVTrgzQev& z+(&WQFzw zqkEu@erLoL0t^nRO&Q2=SWe5jrcq}Ro>m#ouSm#YXR0o{&EQp_IAy@ z^OU4Sv|oy7^?ELHD}N>hzvu3#XR&`B5_|VcUa>8|man}J1iCdx9@O&qh7G{-RB59+ zAex2Q&S(nFc~CK6WUGh)pB>T^n@k8aR;!GGtu*w&3aO!b%#nc~@-Cu%PAEBre&ac_ zN728&_xxt@oc1U_a2RMaDI(*znj|=_=+6nqJxh~R5s#{9Rgl%FYGbysB!_CxyrCuj zov?h2;Dok4T`7Fq$Pq@334>e(G-e9}`hh60Rg7CsQ4H^z1G{O?a|ah^6dB%43u00} z&8cgMWUE*-C3=(UD)s?wh-_7q^Tk>nL%5zp8)cmm*t9f~peyzTVz^~rG+T2H_}x(= z2NRd5YU6{ORcbI(fF1~VAI0{E+(-;hpGbMx!SB}ShC=j6#dbX|BmDx06!>B1wTkD` zsf^c~lu1_#+~*rj=r=G?n!hj(LX{UnPnoH=SC`njo^5frVu{Qc_AcM(Hs56s7If6X z7Q3T{w)YxpCOod5>pqXm^##nl5c=abs3SJfz%r_#Cq+EK620FjL*Hq7Kn2dNuP;r; zqN)Wv${#WFJY2pb?c;idpDjJJv*{%2Z{5C&5TZoWg03z4A#&ZTtPff#ydCOZBTP0F zj`cP?LK{55Lqik5iRl&Ti@2n+C(B;TiSqcyb9X6evW+Se?o4f;Eac!ucduEF{!J# zD(ry8ITd+@;p4}K?%OWYB5A5miH3EhI=r`HQ*mPpD@l1;k<&FnsA%TZf5hD>H2qA^ zvchlBB3+M_t&~`7&3ONwUZQVHNsUG@Y*scpehr5W>iMoFuPBfdK2$nr!Q&TZTT-pEStSm!JS*fbiLbEV{ z>|>1o_u!7VEFJmNj!m)^?EBs_FG!J&Dj(mPH#VWaBA^kePNm4lX&3EffULw5KETAiQ z#GhZzgjq-5A)c6WUT|5TtST05n+5!KqvEb;38JNESB<8sAx??9leO&ZDnSk>VN^b_ zKCx^rkrA~oU-KN0Olo|h;!LX<2Z{3P?QIv^Nb`344lukzUWi({tAqO^Z|7%lz(Br) z=dzwk_xS&t=mP42jr!9TgP-9{@;Zw31~EJ>b3+OGh*vZJdB|s2SH40|ZbLY~TtSZC zvuOmnZL7wcZ)C6ls{-}a1$<>pX=(Wm)yo%U5I+ zb&^5UHem^qq#Md2w~^CZ;_GBP;9oPrxlDCvHHOE+x~@WvscXkT+2?;2EPZ1tPpa~E z!H2V~Vi66m9l|9!&6)@Jum!Z@?5atXnlI!D(VaXDK)t+fgytwCSop2{$+iv`wf`pmAUi%Ar9 zk1NN^EHv9pmXGE8Q85X_l>~0DNuBqeq_mCTJU&q${AE?`q1Jrb} znU%NQPWFhikl%)a@9K>FKr%2K=>WQ$FiL zrA1Lx+w_sYAxq({X!%u^T|ay*$I-xRTxR5~V>nN0-Xl6P&P_bOVjSUZ8~kz|k>vI1 zJvLgz?zExv;|#6=KAC@^uI7p32NA7$aFY`Y-*b91-rWvNV5co7vi9pMtf5s`AkvkY zoC-{1NI0r z`~W9e=zeowK?eu2X)M;WwAB^Z^=wOy#UUYCKeSj4COM+Uo^(ai3-vCAqEqb0xhYg_ zwL8UdS8DllL22Pt)j7)>P*%e6ahdUSOt)c_MY^))80+08#P|19DfEA|R&=*2==!NB zt}K_lOKucD{1>`BL+%e%(9~qOoq?k`xU%;?uudh1lA(J?SaMVTaGE=D$_$|{lYVuU z+i*kX9KF^kYz_Mr2lseTRzT02w8sW^VrbY;E5<{|4JlkTk5r*~N%&Db7U26j`vnH>rxZg@}@utKt&y4H;7^+*?D2O&pJw^6xdepg~>*H5ceD zc*Cy4((+eHBs|UVSv5tl!kUR8CXZwV$4p~s!W;c%obav89ke>2u*gZ26a)Q&Xpe6t^5gdFnMRf zI?QWxY5cvJdMd`4UlqI!7=hNo9XH;>yogf;bkua4h&Q3@*-w=>qglgm42)UhpQ4+S zUWG%?8)DvL|J8|{6*){CZ=mQ><*UGQisWPgFb)QqoZuW;-8xHN%}AY>sg)+Ccos5B zeRQLYiHx+Mc^`grYmHZ5sHt@9AK33#>+*cLZ(YT`2m*wOK8hLqKGG$eu#E%cY~l(tB3i%OTz}SF?<~XPxNAjhIG}Rq3N!T>t)Y zDr}1<-ph(xCy;#KCa(RqK}Pe7liOdI@w{nlL;@Zy^mu`5|Kju(28@h-)sC{#Irdi+ z!%>jqd=A}dEhl&oGPPJiq~lVi|94Z2a-lR*Q7zlSg6G1`%rJ2dU<-3g9R2GH zrGVK9ZJk{;s!D8k043KhL`m#9j-#^w%;*JL^m~5IM&~P0q4By6^n^1r`X2Q#57T2x z1&+&ogEpi8y-3}M#aGp#tZR*QXoqdE-U`>5hC*HCp*=rpAmnL>Ornmm_0YC2DswY5 zYCXntsMF|Ct&yoY!WylZtyrThc5y)Bd@e9@t3u}$CbOVpKP01RiD?(ABnS8BQc&r$ z{LpZI-MR&WD>JK+x2Acz3LgrbbgTk(ZK)v)Jv!%$4!x_9NlH5jE%-IAl+<;X%X~1< z#}D*n!gBM3(?H>7hR@7NS^)MsH@6*QWidlRo{L|w|G0Uo&QxTCMtouH&1P*blzd** zPBQJ%h-3JThBO0y&L98d!i18$k5&UWDj}Jx;|y}^HPnR}-+b(I(Mlj8MYWjSpr!QIjhB z+lpBZc;zUn>ffjGRP91dyL|U@{Ww;OHFGc*;~b2>1AHXn#`d8>yGBL#^2!{U-yvDP zyK8~w0WKRvr1WZ-p`q@6;a^I7G~HOF_;zG8<--1G(u+8ZVuEUl8H~G522OX_1A2v$ zbHMB4w`;tHgm4PixQpRH@ZT--cl@Hc;6SU}5M56eBUjL+sjG?9q$@KlGw_@UqmwTI z1C70SB3@{3$TyZtlqLw(ODfowHx#1_oR4(jWN92@R=s@`g`y6ZxMM#_RVZTk6s3qx z{u`$9PLk&c;;dR@$lx2vWjXDe3h`7W&;)^~qz4J_`h3mk{t7$QZ`4GR_~0Aa_d@h_ zm8t5z9xc4oQTh{IOWvy@4eMDE;yH!tKuBq+6+|CZIW}rZbt@dwTeMeY1GWVrjmf4e zw!Rt%JIJoA?G|>gmiyt)KOadgAm(`_h8Q()`}K8zpulX_b-mE5VMheOCwODX0n(Jh z1iE*n9j7>{#F^cJDQ>>b#W<|7}h)4c{$Aq%dK=X3dM*q*JPU zEvA^bd-zy3^y@vgFkab}w~-!c3VgbBQPoT7L=Td$lC@Mbx~E3zYiiLOU!o`6X27G+ z5)bV&Iq5*TNMpfvTzMb_k&AK2YVGcHTY32JOl{EdN4z_gUqu-467zPf-7bNjrOQVSW&mcZd>4-wZYqzZ^p+ z2>bu`QZd&=j$2u@{WyfbukfgA2=EDtEzgkbhZ2`~7?OYU+$HB%m2Vcu#^ zlagJhxr0l|{pu8F>8T`U)3HfiS6|_2k16s(miowIsFL;Oerk^Kt?7_J4()K8+&1zp z_D%2uA(N2j_?bIEj+3zh#}=oFUYsL2r#Fu^8^SywqY|S6Mu2-WoqAF$OSEC6+|!zv zu0;MPN*dO0lQ_*_`%`3^&E$lI9<*73B)x(Bf$rm=!-dNnUPEUlz~p~0%sbovC>+14 zc2@b`ntg-I?GKlk48W)9tnJLNj-TD7e^)>O8#=wVifM0TZOxO0{(rkoxMf!~x~vCkTW#5=&XdSTPNUd_?=^cK?|oS+ZsBew z_mED=pJJ8t9)+b0p$0i_lW^PgvP`8e^a3Y5f|8q$VDq702Up@q@4_q!ZBhVFYjTS> zCP69O4BD9=(~wvf2M6wf)=!eVKXv-2FJIo1r50IC0|mL))dxiWyF^)+m5sc-{E>k8 zPd4jY=kacD;fBC%LhQ}WNnNz%~uw_Q{4L-w<6?x|;#JcXiXIaQ~#k$|Ow{Vi5kNXEK$vaFe_Yc=+~|ApINs##Z4T zA7=-G`Kn2b(@kQR*q$@}olYWnG=@6JwdU+M6l$(CYRn6F4*vH7n$bvY+qslG%QhkO zYixxdkuN(f1^wDQ|Rstd7q?`k6HTm&w&*kGjT zlr=e@OL3I-CTxY9ru6VGsmtL`N{8PzwnCiiH2ai3xT-F}3<`D=%%u(&_u6k3`8hzV z**zO;j1oRHtLAH^DBnN9ZgKP?%Wl%;Ez!ii*{V(Y3)T;RDGD)yoNw;Ygg$GC^(Lv} zqjVK}`r#>46vK6@C&0yoKfFoo5r^Ir_>r~Q?YZWz1Uc~o|FjvGtGyRF2roo@V}01W z4AJ6yb6(VZQb%bVZ?KhhX40}bO4s(qcPWtCEcvNhEv@IcsdK)!Ka%~O+u?sp!+dXi zJrKOG1l%NJ94=;L8(Gnzc>OS`LGFte2G*%P0}u zQ)$AppM?Chtq)fTcaX^*(HNLYn`^1VmL`C87_UX4h2nDFg|N?`i?is0-LX1LrX z@b>lg$lXY>|mpE`IN>K_8C5$ zi`9~)Ro_{{s!oyc6nX1=ayAk)CTcU)FvR;0h$vw$QH*9sYe5yV`wzgZcP)#6>dhB9 zrBgdw`B3-FSwt?u?RTmo=%mF(iotl{m)yf>cL@=G4Y)zuoH|`2gHbMPDIE0$1%b(1 zm#e2qc-0I$$-~A`y{Cc5}JOo`$*7yFYP?JMkDm>6YhLH>%|zM@YBW# z#(pObxr9#TBTJnSJXn#sH)JMj^8o88ii2le^lJ7C3-0f>Y*Rg?VWm*_8w;ss-rhD$ zPqvJDXr8d?4|J_7~z+d}^wfAN@jbn=scpY$FFF5k9Fj6s4rKF&5?t-PddhSwr5i7<$9tBSRj1GnS8I@Sd8Oq`xvnr(0=+GqA~N#DBwaT$#|TcE?qL| zV0&wZM;LN@$z^1iG;&YRQ@$M_3eT>dv2U2|Sclp9lv3SoM@t{CSGSseyHg5$*_&*^ zf1h4MFV=?0$Uz-UNZae+>c^KWSx#E~iHZuXnW3Q+w=qezjQIe$=gCicnLaVfNovpy z)0zq;K3pNA&z1dinLBA`BkMIA-oqhxsu&?1T8B~HhGG-k7U>v=+Pd07P+<4fB3{@Z za>MI$jFfSe>-ZF}2=H1)xvfXE)Vth`v5rtm4U2enA*KN45{H{{;d+>6h|m!QrmsW| z&iArzsDsmWo4ihp{R}%h7MEo3(4$vnKa=?cBbl*wZA~qp*PsxUj{eT$>%{QG_~}^} zTkD$@@E-OYH874iyn|}*i?rfesnwaXOPRzncMD;@I4Tb3U<}O6z9AkBx_1pgZk3lm zJVKbY&Y0=Id{{uMei%(_dYnU7-w-vO;2+Oz!*FJ=p##fhEH6pUFzjYKV%J4F)nwaA zHGDg;4dF43Fj^%@|M$lszCyfx_?0?z8ZkD5+sd`@djI;K;Vs3|;tgn7VXQI-@Get% z0D)gV0v)QhY>8=6?aW3GbejYp(H6$f9q(WNt*2i3X1!JwJ-?*Qc`7}B3qxIGVZ=)} zwLDr)i*M#xsNvm32Xy}TI%$e&C}#gOJLF3@!OM?!rx3?JDlUE74!`DXouc|V`-~Bq z*KGavDDPB9OPyrFW*g*YF5EExNFAt_G3wQS+5V~PvpR*H>KM<%n*FJ>{`8P}Os>`8 z>^e{m^hZFx2xmKdM#mfmM|CT?ilGLMy!A!2SL3}A=g^rXyFm&2IM1KjrOGxZ z^7c0jsTnhAT(jq1=Sh{c1|MDbj4w&2FR(8QpFPB@X-Z&Ysj`8;35h)wMBP;PY=MgX zsEbK67)Q)?78p?);2kjT^l#i5Cp2~61QAW_AxS|VWLa+keWmkp$Tf9%Hdelto^*!352-F&qk$jTERY!I507+jed^S;Oh92@ovQX6ex-3wH!JL8=KW1 z74BV`Qi_S;Gq&*UL);$Bi_{GME0s+rnd&+DJ4BJZ(2Rf-t)qmCTz%L|R@RO%%nz#= zw5e@r$wj3Cdv0=!x*C4(DA8E^@;aKwIq6={&C>9R62KXC^lxduu8J9d;vX(1gy|swqP`%`vx*B=eByK+xU#r@q2y%@8}ZI zE+#xk6?>1{v03i9zX4wK1<$JC)!#u@!4p4Zbrsu3%Cb*z z-0m%f`|bBLdO1OP=q>{c#!IpKi9xQ zwwU&e>8m!WGbXGV{z_<%4Hqj4UPez&mz0K3t9mM16$B)+{9&b$RHvCb*EFrE#YKc7 z*Y^z6FhkKNrC#z|+EnaouSntY;>Q!zLUqC__SlUKzqtbt@5{P;1Zqtf_@T?Fn}-zi z7)-hoRxB54oVwXN_(oDzocgp*?suo+wX#)_m;&pbjmo)igd8MWF{ZP2 zJSiO~d4&a^c*lO^zKH!Dzhe2M8NtV+mt0}B3D|M7CUU^C4%~$54-Q z(aJg^g6rFD3(8*i!bj|O)u`0c*pS%$hoR zhvK7?DPMQNMlyAVThfi!r3HEHoA(vDtSQnglSD%meY^aSJPYJh4X*W&r!8wPYljZD zFT^?{^+nEb=7Fh5>wAk)#bYit!2w1u?C|q;yS4zY?bV#86GZdSkP}th)TLAe;&`>X z{+);lHhO@c&JL=oQ|^Oel9;-1FciN51LOb8rp;=5ktkJEeHKe1MX(`tj>Z7L;Rw1H zSF!D(BtTu#6>l>(I=nvM2&!D6ydd@Zr5p*VK>WsT$Y5OPHc?*i9<^=#jPQA)y3F85 z<{M3xOZ#jh>(*MWkNN|-@%=UUg5zKG)1yPHYmJY#=2b`0TS0faAw71|%#RX*J zq*TP8iJNHCvJuI5DS@4qk7ma=wL?7QJ9Vb3kRERuBhi$UHjYXxIHdHT#BwN?+>;R? zH7aD{JzBzVX$g=fII;B0OH{1SP&$b}| z2jDY%3?z#E{z<&*$91ytgZChe4Yu?yY=o-8un|(3Sz_m)t1A}6U-NM-3G6xefspht zc*$<^tr6KAtPkf&7;S3v8VRxFhKX;B%+zGB0#)t7x2TCePT`n~nzt<_U1;5?e1*!8 z2-L<$iEEJ*v5_(HL0|40VaCT{19pplu|km{+%~I=+pj_3BdFsZRpes?%VN`5vTcU3UfAg2VA*+)5)SZ=p->5QLCB5G4z43wS zBNwJPJ{NFVz~*1wxtsQ5AZZDI;D-hv_rHgk6gCwQj;Qty3GRq*Qe)GrMQuz*MfXN$ zSfu~k?rKmLkU$$`Z5H;Hbw3sNg_%!-zl9-5lXI#D_FON39(Wf^N-o=1Oa5=Y5TR&Q z6$2M$T?Lp!;<|U%UiTE7Il}^4y6^+gWv`*In)wgI#7vhB3Y69oUuQ-lEOZ_*4;y3e z!z@x7fK(}xdN_c~ps9C7#1P63NU!z$GQ@u)srG{wMUv46M~rI#&_E>tIc((u`EQ0D!Z2lI;8aJ>1{+cqC#W z>vbxLrt)?_>#d9{M0b)NNU{`=*O_VqiM9L}FSr%-6D@iOblCppa$yV`e=d($&sL-J z3K_aplDrb7I$?_mWeO%RA|UPV?mwjmSQ@kTpNvb9yfdVa<6J{|`8^vf__=FP<1U~s zBKqNaG=69%pR;x1U|O`5#fdKjgdTG#-~&T(8FOywo`sSv!1tG)tmhh@TLnqGpgI4i zU_fJ1-Z$$u6p6rqy+bGXkl4mVzUsu+s~9=aR)P?_yRwG4pSJQ3o&~<&`|SQ%ktJyN zeU86~xOgOr`^5^`c zPU^g%h`Lnu_0r)0I(VDvkrw~c>K6t$P7g(}{AH*6E0d3U<#zMhi zg`$OqFQ;?on)sBfK<*I!<2<~`YM<)GxHtPbUMwi__CwbDGHB+}Xd_zu0kwOl{eVnN zE{x1=4-E$cD~5yzh9Z~Ww#BL(sTeHEjKvBzpBR;{W;${g)4^w#Fs4QYz!Uz#;ld25 z!1#)`BvNpPESW*@rTCm+B5x2bx63kk$*7BGM1uzPNiX+pA}6P>Kioiy7nWS!iQkIm z-rhhqCX!Z4_W}as6U3h-xj2zU9`K{KgHMIi(R*~;xLHhc?Vesr&xI4AZb|3S7UJwq zL&`#L(&O+c!_a;As0ae`Hd*lst4J$#knJ1yr379UMuBi`<|SJU-;=iIn(ZF8&a8_m z`KRPAW6!_Dx~jb!dkXy-!jhh*yvUKYa=pZ5SO9xmk_d zIO@yJ>0)pT6>ZR~95T8j$COpHtv~m2+y`tu+BL0hIn%n1*D)FpM`?;>NmD`5m7RDT z3*)>RgBYn^SNue6)fD^!UjQr;1o^P%!M<{xvDuAaEtKh2K)=V{DXtq;@J~h1xro%0 z<~x8FAg~K7?OcaJUd&*Jq65?U|YADHR23e*iT$eCim&(7Q*(D4gj9mNCwo8;@ z+nPnh;>R!WyNSIXFtFkAnA<)?{|ey-dRnQm(b)8t^OFX#=rSpOs)GJ25yzf+P_84_jek82|fQ)zC=+`b*J z*0H)JnnJdZGuw<&LNB&gZ@{t$myq%~zf#9ntWs8M>QmM`w-i z9CkjmeQD)bih+?pT4!v(j9PvDC=6d^PUwN~UZ2s;N1oc20-3AP-Tptl^mt_)cfC=2 zY4G7^LR#!O6Ka^+YNL;fkLF_EuETbWH1B3HtTCkjEKa*#u;ZyD(Ua`P!7-^Oy=yy z+<7xjrA6Mw{gEP+R1;B*^A~mZbhXio=np_7klNsAg^8&2@;wz+E?$HC^4t0v|8HI? zxChji8WU}}uk1(IJCLou3P=Z5MmaPuyu@?yRw`Hv-tL2}lXmT}m#qJIyl$9tsrv*W zHyQEx_$@(u{*@c+i(acwVrPwQ9JsxWa20}yL z-KQVq{+g&|qy`K+2a7dj8j&;K^63Z1lwT;3Lgd{wQH;{DR0sY)^ORB>01!(yH4sb~ zzv;YR^j)k+VokmaB}nyd4l7)E8@ z%+^YO)6=bCQ7k1jlNik2CYAhav0^qbKs8F#v3U4Y=@tmB{|qE3Z9_(&_mI!*knB|< z^99@2_R-={Q4=n}IkN(BMrUzwa7JOcYzw(8ia%pmne;<+DpL8>kMdjM$Bt0bd$7)f z2;?g4TliOa8`CUc7u z?s^?|+ZOiVlA$gvgNv;NLoD{aoSj%Evn+L=9uU#!XjQ@!@|;8yG<*y^P$iayr1Ev| z)MKN>Uw7H|W9atl0BOi?3${W7EEc~0PhnSPPy?5MLvkOk{j0gB6ix0M^-*qPOn}QD zRuV5&9@0i012-L|mmWNL4E^vAapF+iD16}`slba{HqMw6#yIflJxz%7zdSP#R67hK z)2>={5$x&qk5&1%@^!{42QHjM=Nh1+kx_FMz^U;b5phDH_=Ws@jo5PBKyk#!bGkLs zPd>?3OZBa7fo%J|64K0D)1G|`{>X#AHc%Mh}!e4}FwonPF z*H*&)A@N=Vvy6kz>qoylZie-R*pvV?qi)M>YDrvZ*BB8JE^P8T!Pq#<_Lwrb?;0sw zJSo2{p6Ep{CMky20E4UuZU6_PcK%2jc9gAKD5j^^y_9{vELzN+r6wH%><1}#NE1tO zkf`D%8{K+KCzNrGb`;OL1N=X_NP6aBaxwt0MuYu}Ur7ZJbRGR{0qVzT3Y}%4TWheP z&j@1450;FxKfWsI_#9dLFX&~Yu;}&mQE^NvZAvmDSB@>&cG8J3*{5Wj)zcHo3o*+j9;-?6{Tm77vvZ!$}Vk~XiW-c z0q4Y#O8Cujg3R5AY;Pbvbf@Bl=nwxkDD|K~-fJKKk%wMt$|rV)Ruf~3m!eR6OigKb zvWCEu*?Go1`<9`T_`UPc6$P!!Z_%j8CsLh~wWbFjbXxiVwH={QwLzk2apznAFraOD zb55u2p;k(_Stm*Pbr&%6O^{E27xNpK-gQ^KuKzV-VqByV@^A_DQay?faYkM!$U$|` zD!s-NyuXQx+{ueqq2Cb?@qs{z5s}1s)ZB*NI)oW|#Y-wXTLl#|2NE}QYl0@3$bE$-Jijw(bq%ixOJt$& zu9qwmy?xCF14CnYY7@Ci(zl4*w1$pI@Xe-iKb+{!HB^x2)NO=z688>E0y4Mrp#8pk zU-nq4N`9zVWMLcE+vO0(fx_rH|2&1CeV?-}`!P3bmjx=Y^58T&rA?{B!| z^nEJ*vi3qpZ%7a|kQuNT^PBRbMlqMcUI1UMl{5{w6+6v%22oXmm_Z=%O1qk9{x2#| zvdu~*39&KpD%6&BQ3QCBw8D1#^iL+0&&9A`fmgJ*J)wL))L^VITB4#v_lI%I(~aLw zQ+BCb42Jc4?Kh~o(gC&LwLY8BSj7E(MG|J>wzSe%eCy6}u$ZemmXv(!{5J;Y+}d7W z`&F;mhIf(QlD^{@&(amM4{UFJ=)Ouc#wu0?GYGa`ygHi^jiBa*R1)^k^t)ZaK?`XP zQ7iSE#khAa`nQf+oxO2%Sv>s!aF(!bvFPsp8t)>7X8}F6qefD{Gf)R~GI=d=>NLlp zPaF;H@)<;re^@Rvz>w;jE-yhV@=~exuXi=hJFA;+a#JfJQ-&}v5h1Ui3qP4B=rEGc zSjsXR1-h?;>lfVf0mOxV2KXuz1!dF22=~@chQ2<#8s}%$%|co6%x=IhR!h|_$+?x6 zZ*s`ZQJNu2_S&&$(tk`RQycxyj|jN-m(f4yhQruklPelP&nV1TC3)<|qQ*WtV|UuVni(z zb%!VZ!%A8&sNTtmZf7a?H(wm@cqG#k`?^Oc3?s%Z>Z0aYW!r)Q8zC8lt`kxNG@vGz z8SXsyvi>}RHCr+6d=Yz9)#h^hAprZL1OQmfo2TeLM-T0pSD)^xfq8_d_GniBDa3nv zmkTN!RC_pGVoYIhqZZxPdjD`(`>>zYCV*P_VWL|y>*CGLv=s0p2mU{j&OM&V|NsB* zN;y?RNCzXQqMA~vuoab%grrhdB+)^oFgumVvF4DRVu@0yktCVT`OGSEW)5Q*cCwRg z*S^>1_xo=*H-DI2yRPT!@q9e)50U3HT#(6OKUj%CuU}`3IFG@Vmq*MPM#n>vITJ~;o*54xcU=* z8JE79naXB0X;X@yvA1ie8f-QzNE(avj|bf-Mg|n z_l>1m67rX|{E@(v-I86te^BaekFortG4HQ!|E%Vi*rK!liykvZsCI+Wo?ESnvPc8+ z?AU7;-2dPnq9Gq}N<87YJ#J@kZ5LLEDsus)&i-Qa6F`wL213 zo9Ki)H4Kkels8k-^P``i+g8Z#P2vl8FI#67C$3muY+8wVjGMXU*%?3``IEbH;p4d4 zhgGbqqjiBvD_AY5Im)kA?dd0^&a-5tM%@ zEn*Ss@;ZI@xOfPEtJ7-nJG$_mT4`-KMe!_LGH70D|doK}}4NkW2pNV73 zOgV(g6lmzozN^FlUsiwy+f;IrY@M3t<_NAg0nr&viD^yFs;PXPT;zA37V(vYw~oMv zw4Xk2P!7`4x4Lqo?8Q4u_xIWbguPsR$Vk1!N@tk`KDlv0AFr}mElZc=4{m9usCi#L z!lK?Dim^QPZBvSg9X7qj&XaXAlu!X{q^!@ai*zz+8{$)lliIrV= zozTUr1AhI>l=p)yjL-D97 z!Q7A+2rp>cuP>|7?|FLDe}Ln-Gns0iK1`Abi^LnaOId!or2G6+SNva1eOZ_b?Zx*!Bv*ehSynw_soq*HysIg{ zPz3E=FXaf{A6$T>)2aA%oOjV+Iik=d2~LSvps~kvzf)(Ln*Mih0r@2Ee%P+*Q>|A1 z8uDN6`Pg0DyI!Y2YZpbLdlShiu9wMn@e6HQfN=hg4-!=PrqeU_G3SY;pSCeNn!jo> zD?G;gTgQA9LGQQqluYXbA@9{%@tR?TkBIE@jPUu`ddL`JYd=8ZmD;-OUqvgaDY~w< z@=Fr7!!@rk15fQYy@N~JE{fXmL0}p=HUWq z8*>!1sLVowgWZ+gh(Dh;Fru#v*4sp7Zul<59GZkI>>J;a_2~vsR5Hk7O>lL1$-i!2 zCy$cgwa>%AlZ^t#wiaK?pGl)4>A}(A@Ad^HK@V$n#wpY)ZovC> zeBRaDHHA;=AXaYnxW6Z;xJl3;t6hCymav5x?VVl+2NL514(#m62;qDMK@(! z(3h^gQVl32$?n}CmmFC{>>co;LLzX>%W8_Im~=BAWd?)7{k_ud&>};0coA%x{2HR!s?q)!q-fj`_Dwi}S2PQvQ4u zcCzY1FYRCSN|5tSpZvtrlNgA191S0hRuHtZUeUag;W~#Vi664@(^cRRs^sXTPP1iP zZ?%@#+G{PX(pq=VAH)q<(^nNy#}pC6EyU9(cPzH>LmT3ru4L_k zn}N`4vkmE(c4N=|?`6QPKarDad}XdLC0VD;%cV>hw@k_S`yY%S2e*^AU%>6uyUg5W1l%7Wg^b|o zv+IA;mR3$r*8NkkIWPP+fhiZ=_Ql-tH$6F9nnc1k3fPZ5o_W&KHxjG zYGHji^AYxu0X&p5VgDYof2?#)u~`+ET}8?I3GcBgVGSdnsm;!2Z=z)GZWis`4{Y8K zbj3n$?K{MV?2u?o8T99HWQXM6HBdzhR2S+YzB=ntlUYei@3?iiP!7gky}d*6EepPCN|UTxM%82Ye;s+p4S7B`+{U)cN31jrhP zOa3GUGZr;qi-9DcjwnPc8gT437vZoV%Y=M%1A%7M+yh;&)|3-;5fLj3pqRz#bQ`)# zH%tTDFGuwj_M32}kH-{P!}wyU8_g*L(IaI*K1~W&yiG(@e-&ATpVqfA*G&=*S(*1( zvGg^GlD$H;!+yG%#F&DV0_pqcG2D?YxbJo=6Em;C?q0Z*EU>*)HpzY1 z2Pxx-fN;qqQppe8kPC)W3i(HQR8*lFel5b7~5w*`+Pxa*P6 zfO1Q*Pk%U?xSI=YXtH zXTTTSEqO6f;lIDCa4>g!qNf|8WP_gj<;2%4sUz!ti}bt!@QfMUDW55Foe|b_X;CH1 z`3{nfBaridZSf&}s2Bg`%RIkBUm3>>y$A;FazHPn^OfM;i0B92_NAEGB{iO{WaAqb zWEzvvM^(mkB*vf{p^RFO47Dp-r)Ox0|ckivo4LWra z7)9~2h#zn>=+RdJ8dH9kXIAYT`|CafcV`|^`w?_XS{fub>nwh`T2{UE9>Mu8^zJq5 z^vkx6ljRia(=uxERDf`wH6pmwT|M~cN0V^}`ky$PN)%4bCkZrCmqO;Qnz1QgK8}Ar zrnf6IX3K`@Q(3HsZiax!Cj;)eMEzWt6x`xi^g!=!*A`l*qOLj~)xV7<8KE`wYAsOP zrhenTu9X>oU4NaQBz=BQ`EkXb^iKNTjg2< zq;yvg?{U|2bd*_laQhN*7t;WK_hCW6vTMhtnKgH9BNZ){uxSjSfESuk$z6g^60|?S zeW_~&y+Vf-zl7TKAm+VT#d{%E~f(a3pcW=GPxPVhP>%ba%y6CEz6CNZZT;N1wDzU1AIwE zvoS)5F#s_vKmcd&bmoZo~mb1}hd#s99xCP5_Ajcb|4bUB}|52vrFGvwz! zC^3X!T{i|tP5PfY931xHG%3<-T$b(95d{x&sb?HgkY0jAC%;(7?ymDvpYf7?t_99{ zY~_+Ov5l;3Tdi0`x|7Qmh$D;GFnZob1x@pDnXZdC>L<-^f64kp1{FXJ-0QRRJtDt^3(06z_pb)_~%`2SmMqyVI*#xaSD6a8ruAP2BIVz z6zn#D&%M%{;B8&4_nHQ2bO6D#-jC(_uW%^nfEr^8dkM!3Yy>latKm_g;m+V&EiqYg z99!|$p(q2Mu{)R5rtR~MHzxiS1F@^K8ooJ3J@@7e_KULkF5zILG%H7E1{#8VVkZ+u z2+~34!*CZ1-G@4plrPij)L}gA00VlK3NjiX8rnf&{U;x9Gd*{s=3lbw%|w(QXMt76 zz=L+p_ckjaQu<<4c=IquDR-Lk?kRyEXn+M%a(;jja%`bPuO3Z3w}Ib~J?jSlyLm;k ze{2`kZ;>f`AmjIe|GjOz>hckpyDRxzEs+OoFQFPW>!ijcfqf1KNJZ7T+;Ia{snLv) zh7IYv^4J;dnJhV~CQGy1TkJ5;whdAj!T*j7sNGGkWydIpJH~)S5lk|p3L;G3~c+_+q39Em?@HJ9$RcP8Wu0O_2{Q1|2gimxeZq&-Lyb**?Rpwr}_Uz7Qyk0Ll2 zr@*WLH=Va`PSiX`W%=R$w%DKWDT3cZ)Ieqy4%cow3W@9eU!ZU_BbGX!etZTMC2XK3 zNRdGDZJY;)bL?ma1fE-9FB|23C_`F*pxSRr(Q4QO$Tps0@rPo{06(lVBe+vai3Ev( z#^6R(Sr&EfNtCc(Bbx?|BxS(k#OePmnO=bprAz>FG+5pw*AxhQoTLCoZae`j%cEpp zR-s+*gVDhA81~vo{<_b>U;b&&rAO>DxJ0F0@s-z-f08RM;bPQkCxH7lbq+pJfZ*~a zj0uhR98WRmRWzOIFTH&$568EwSL*9fm944v&fYKcIujlKXVsP9^9qiQsKSLafna)aL2v8tQgP+x0c*{$dPhyF^3&jvXdPW(YKzbj#LLe z!F`7_c3{tnGGk%ZO>fw37^^scxyu-?NqvgyqE4et8=D+ zGJ07hqef@NurJF9Yc7>u+M-S;&!=v#*DahDg5s_$L%gjVtNP_e??Y4L+2DM_k7QK8Z16Oe$ z)|JOika()YW~vd(BQ$MMuRNycp;$2tja?!tiOODu#WMLQy@e5)yJ)FTAKk}q*0B{< zDqv%qMCMudlIVyOcX-i`MNF|3<)0;STZ_a20I4r#9=@*LBa{gjBDkmQGUfT7nl)X{ zzd<^7tYIp5b#C%C+t2-ibz;ZhhplBbmHDfDUVyVS_A7V?=^*AVuzm=^Xc|3X5or%& z?>C@*ZA(CCP3Z(DOf!9@8Wgj){j)is11}u5{0TOKphfppYsqGf#)OZoR#Ksc>SV|O z{NPi{WSvBZeY*3ifjqJ%{fHV)FkW;tvpX4yUsm!pkRaN1x^ z0V917^#_Aq-7t4Y_5&j@W-Z5#0q?2gu_A4-!xtBPoZFGdBIEoTrKuUU?#@|=xD zg*D330TbLM*M|jbQe5vkVZVi<;Zm8uC<;Vzfg7b_0g!?m70~uKqCpP4es6o{d1M*?_q>^ac=AxQ^uz>buJyr^(w^ zZS|LOG4(ehy}cg$Y&o)Ek$s2Hs?%~2LlL5(^(H%oN)$kH|gzGjz07H*DC6e8!`2(oSdfX%4;wy^h6$rN; zXLyAm&z03U75ieEUnkKU=ARdAE~zXdkAnpZI=Ss9N`06&$)O|CHaz*|0B#V3ecdz* z!|?sV8Kc!9q%2pcc@sD5u$>?Q?RW{vCvJ$vJB_Z^6NdVDj?hlR^cmK#Wag=EvkqMCGk*#Bv)OR})|M2~bFMkY z+Eq81QnNpIw|6b>aL+lBS-=pu>fq=}=jz1tG9~ht_YlV1GvOm^1De;$4d%Ui(07Mb z^30WyI&;TlV^HKPp5ne=bkyc$*0tPdVQZx000C~cfZ7$lSBsM*bGrc~X&_8+d#=}v z=8>mqVP?E;Fvy7iFO$`MjU(5doXAu+6vg?2DzmL>qXQX!ixf@6vjG(0@@ZUtfPv5K z#|N?L0{aMdA^)k5;&{klb&f90S7#+TVy7rI1e6+BuKovR1G?67m>0>M1LxrESf+o~ z-i4Ur8F#Rx=h~!rtt;G+Jm{1&E)xd)U7_@wgO0c#fgqYGH`{``l=JvH;_LyHA&*l4 zS2s4AFBnzhf_*=@LsO)XZC2PgGu%dQT=<)NE|EI9g^?{a%Cyko_4psI6SkFVaeR7@ z`MEw#(YLdYli_5>!|9j{$RGSO^73t`UWEOe3cr)JMW1qij%O_{h7CrBw|=%mKc<5# zmrDcqrPIk1I;sNdDG(BSQPJif533{^g!blA`JLbXC%qKy^m%s8tRYo<2^65Yso2j? ziKb%+$D2SuMC%PC_@VTTR}7$pyKqMCoV!|nu`RY`5#Mf%gJLwf)M^8G9NerR*UArj z$?C}f{B{4COT<<~EdJGJd-U=JCB4CfK;t102$}*)SwiITGdpqjHj!4)yo6%f)Nzl| z73ME4q+QzZO_TO3W#?X^B|3RUpFD%jiS?nfOc?GzS^HBn$_j5XJ2VP37fg_ z8-^l%7;h_i!CTe#HYmllq#YPK4gB{a<`K6kPsS^LFY%MTa%`0w$E^BAaadV3A+;Ct zzHE|OR9Ya~XwM=}*nHC2+(76cu+&5bPEH%xZ%&Gx6^Ol2+hrbZAnAP`Q*(N9ujBuJ zbx({xS8JO&ni{;3yV@c(}5c}jl$ zAl(#p`SdiPM7~|k^lpI>jVBO?!r{{VsR+lq;f1x5Kel70vTZXNO44FoagHry6+awL zjSkN%j1NzKMWwD}D*$*OWf*&VD%bzsDx#SI(4k9dL^AqsdM820E>Sx+670D+^IUoB zJ>!zX&5}%4)Pu=?AI4++54)0B;qnF7+VaP4&%+HW+h+b5i7nk4A~LD9rC{MWvpAJq zjC5D!K6x+A{In|f?EU;rs35K>JMY7b@V_&bn_xv`1yVyNd+m^`#-t@-~DW6=lpOH4ZvS)aX2DQl&wRMhTqX6A-^tecM0+Zb?fv=k{7 z42Gx}5z1c!DNby|k88e82|Y!q(7D$B!vU+%T3~%I=oYC;WdmQ|D*N2O=R~e~ynx8g zPhN40SV?}*+FvFQ{(-7_9&kYcwoRf3YFEEFL_H}8o_i8;tg-xU&CP|d5!+l>@a!%c z)Z|seD9}zu6=)Z^y}s2dkjr@gg7-4;hZDGtdc>wNt3Ij2-c^r1K%b@!KT*I2H})=p3r2RDf~->OpjP#Nm3D*S0ch zJh0+v0Dm~A;ClWqc)(AjcBsxTQ~CWwl?CUDz4@fuD|d>(LMGl$zTvct&GUtSEZ>|Y zK5+`SDA|cEIpzIS4pI<4n+d{ZD&A2}V&Lnt`!9jvInUZP75uG&;*9fu(Iw-EDwLX} zV|N)4@R{%r1{DkolzHAhRL%L_pABIBx;u9Y)1xKMI~dV-YqmjWtH2Jt09OI|9|-Y$ zJM48N*qBexIzzdgS!Oeg^r~BN*sIHH5_GuBk4(vTC9(=srN~epF7Re_0JtK>E{vS9 zy>6r-&&u316W~*c{?fv>?wEfFTwin%mFzvJPYVO(!^+h>?AIs-R>!jaT(Ik`>r%Jq zcThZYbYD=c=}$yHv(m;Ko%KW?82V8Rrr95oyH9PHn!A^Lgo)q8?q49qrr-K|mMc7W zZ7YTHK_AOl3WNX64|chXrxO-QQII{X0XfgjsxjTl(E5xFtt9AmSjCn-*z*}&MLIm+ zgs4s2xNI%~Cb6n;=nC%EO-oTBfJs9>j|0h?qv0p!g?!#O@o!Y_Nq{_4qz`lFT5!x! z^IuisXhEjZfq2^|UTY>0|>q7*FQA;Zs8 zKAvI1C69&^i*OHSTy_&o%Du{P56)^%^qhST0>RbLuhkiukNjkJRA7|2edEZVJ;xbT zKj6I1wZy{F!0W&>upe#P7-F9lp&>57y^|8eR42!csAPLFRVdD^47ly5=$}42oNQ7j zWEC>czc^NuDR}JRTT$x`<(*D;vZ+eeiJ6WFFD@?B2P7Z$+sn3`n#KM2vPn)hATL%? z2F3#F9j-I)Mba)*TOe+|f5xZx-j^18$v=OCAEu3JPpMvD_aDe4R`Bm*pBqA5*lG)E z%6iAE#f}>xA+NxBhICuLK+=J8E(f>p?2ugwqSf7s-R%0cn2usi=_Si!Q4mh__Dv;~ zXKMNq&lz$}TN4(8kJ~n-ZJPYzF{sri!IfYF-xyVPGvn_=x*ArGy^j#$FBIe?ul{Ry z3IhzbwEeApcjW0iap6r&bf*r>EhEM{$OJgOBWIxaKsSrX>jzJS3}aDtST}sQ5HC`q zJoaVX(O^$Sv!jReG^ByrqC}}jt$1Cik_9Dnu6!r)I?(hwh2wp5Lc*5WVIq#)ID&-7 zKSh|YVoLItWZlk)ujmCwy<$pcVGKY2O_bQJd?P)?vJmczF)=mPE7`y?hW$z%lo2(`~}n0Bs1UuwJS)0qZ8GLxMI3A{)z?CWC`IkU^2Fd!-Y0S?iu4|}tE zaUmL_vzjqp&K0iqcW5i<~Q$GG`tz3#Z&X$T*j^Vl2#|obxdq)^xG6G<` zp0FfQh`GB5h-*wNg>o(;e* z!XF22>XcpkcBv!b$TP_(MGY)M*I;v(ijw#*_f<&~uUJ`9 z-Q}+}(-gHe3FnumKPXcPf00#2-sG(>%@Jp9f6PUgaMYX(`LDO9t$5b~n**i{cy}B& zv+c=N(XQKzSIzV68bFE@L^KAO5YvX2Yr#rTIh5qYZpq1^g5ND6xf zvAw10VgL(zDz6p{NAvEimDmp-C(jJs*~He)>}t68Wfh`;<<%;m9;ro?^M)D5djO6P z6)f^7yN$TQy5uV8+c_cG6$SlL0UMWfVU%dZQ$e>0!+WA21&Rxj35?*&EX;s~W;L8}VCxeopS_2d<8>jW-N^<4uQ zUoK||RQh#Pvk5yzilH?|l$q_8%P39yhj^*>55#@>YknT?7uo6~bv4ANcmoFq)PSgJ zCH~Oq`RDuabY|!Fx4b)F{4=a(Xo}qEbe-IpceoGbta~jw2wKc0`A~lXI`F9JU)q2K znfo`w?6;h!pf7JSzoh z8cC^M*6r^Xggay4SLI2xVW}fs@!`cLOL8McEmpCMwl@jB%W<4`ZRKn?v7D7pkf5Yy zWr(h~>uwP~NbYrxrFV+<-l-pR;Ua#YDt$tV4NS2o-hE|ACkh4 zO^{rlV9Lfx`$K|2g!wVb`C8hwb4pWQj`fmcl}W^iqc8CDHetwnXEaE3?V#ob3(_!!GB7Qt@{)(VHY%@oczVSqGiSm(9yz5C#z zbKipMFzY7pPgjlPt}DVAEfXrxlkvib6kYL&-tZeKNGBf{E=%sb2lyg>2vBKy0-uy{ z=XUwDg6JU*u20Ep?onp8F>8!???0e(D$7cRDWa*}s+{FJ@vj6vDqQz<=+SRDkdeeS zhV~vBfJaawYfOdJ3;&=?>7vvso33CZx++2d=2lWCDI|wGxFPdU%4*t^MRi#KRIyaj z8UWS>HS(X-Q|<_pqmc<|b`+u>dgd(&U6%#Oid~?s|$(TIy%5;k^I6AS+G>a>QaU)Y|qnl0D3X9kzn! znaFimTMpLcUn%6z{%IpZMw-|%)L<9!Y%3#{XR`1qiPGJRC#OdOAM8Z;MrZXA302Jj zr0C+UpmEWGx{$!qAy@i8et?N5mlP_BH})uyzKHY&d)COV7Y9W5;=k2`L3=epSa$M% zSk*4QpSzpUCA#|$&@M#a(d{bS%eVgG%k8`;U?u|4>LMKOVEtK~tLk9xfg8;^Hy}U% z39$IKQdA2WX4aysEsehkT_*a?H92=+!%-u_+B3%CjO}EHDhu41L1NDSY`lju{J9Bn z-K;Ce9<0qBB3@^OoWQkecZuXteDNPcpIU8~#b>oGJ>In|*hBeU%coiyKYLyYj;f7^ zEz4A7yK77ud0wU+CIY8F0p-v}3gJAfPrzJR&(ppp*OwPA_LHsN%9E3W&y5moD>g_r zxHpLfzOa_z)HvH&3;gAm_=SI_!2Mgmd3Dj|pc`DLrz?Lzivy3TyYdB1Nv6wFEa2_k zYT_L|*(YZkXtoT*f^=PXOexP0-D;~OOZm8!UelS`)T5GXQMQ8IeOK?r46AQFTCF%I zXPT)1GxXTdNleRn=ksx{D81$fR?Sn74-4Od4;HJGBBJj5D2gh{A5EQ2rcS0a`4kbr|hb0d;Baa%&MJ3AIGBWG~!N`#Elo$M)znkm(R5T)~cEs)th*mQW z`>t5NC~o{mNLdT}R||Z=we&T6)94L8Sx@Gn<^}RDMU5m`E@L>G1YSDiPx}S@4S8_#xJ?A* zG57{GXciLzeEhnVx;~-7TZCQ#9Ew)}PAqwZQ)RFRl-;R7M^=3Sn8*~@QY^W^>=mOg{~s*n)mR@2X13KwNFh%Mq^f! zkB~lY#EV=}}& zOtbx1%N;ufMW+maR$a~=kf=!>E-uGaeASquXe4iAkENk3gAII>dS>AjKS+QEgPRr$9xx(4v@1? zi~7=p4KB*vl*9@R?6Z+>p3c=L>hM7B0GLOE<=9pvf)J5AmfIeFg$#<5rKg$EL#R_@ z`n>ocL!QUbzs!h9T%d>?-M$j1B|%f#t4RvH*L@NL(VYrA(llN#n_9r;4|@8-%S_#r zaOdz0>CbD%aREUm&}G9Y1Ndb}T>fHuCv!`cs;Jm;C1;WEFS{Q2mQ_i8#(5X=T3za_ zIivM*lRCw_!3gbatSmkH<4~m6Migwa2%?Ne{5WJo*}OAbXP}$G@Lq%3IyEBBLI@4U z#cQ~`MIY8cs6(tl;HWL=bjf)>VVWl4i;KsD2R@XG7wWOH*<@Fmjtk#4vvTxz?!^Oy z`(Ien++oj2$;Gh~lZ7w>&jnVb&Dh~Ba-J`C8D~HqUPoU*pmBlARJbyzD@D#y) z3gT4E6t*mP@-4oAvR@f=3qmIYgZ6D0Lj<%Ro4V&oqQ-=T&Xvf|Oi)8bs|Mg6PW3wb<_Npj zbyFT2`w9(4g6Gyqa4vB_!k^4JYf7K{4j)HtwX6&1N6tvNt`M4)>hUdO7eUfiVZ4ZP zWL;)u{%k^rJ?V8I1P2GxAs0IFDB$%nL3QPkm9dcDw3HTML`32C>~;TWKoBi z9{sOUYI{uhJTpiiS7IsNB-u%F__{Tg_8|Xxxc8jx*1G`mi$sDNZ9(c4v~>))dLb?- z4r3Za0I0;s;5#*LnpnV3yHbYh(B1%KeWGG7h-8A3+?@6m>8Da$^ZURTUVVN2@5uh# z)d}#FB$rcdG74K&?3F2kbC$aqHI5D+ohg{K`!*K!zk|5g?O(g;bT%#WXdnEn~QF z?aPedN|`Ttsc8iBmJ-hryTrkkPt`daqwz~l%gL*;4Ry&jJ6z-j>$RjOmx}_h!%Aa!U*dM)- zjT14Fm)ISb@DZsNvSqA&ZFt@EAMv`sSY-&By$yMjIP!R>yav-7g|{p7+NUOD+IJ30 z|Ak=t33?0Z>t_tE+rD$j)3dPdHs#2^iII_*hq5)WKyQQ*@892PwH*u2Do60t#GN@p zBQ)jf){|p5`G`8m6|Xqa+eY@$c==?;odeM3r8P_>(Lo%J?F1I3+#wcTc|zyvuk2y3$BDK z%Oag*t79sK&WI@FDJt&}X;kJaQrpvqHTZhF7>7+f45bf^cwzV%0ORy4M+D&c} zqUq(HDMma)nlyU)G%Q{>l+3?_vBUhX5Bv^IT`v3y@Ix>|1ifC$;3YC|e)(A2wwpfh zknitO>M>^tYuB;dmW;3-WQ5|x58~~b?n?Ku*Zo&1!~}wtbGX$y0~dqt7b_uhu?&L1(o$UklihZ zN@(wtrPa5xO2-yYXAha@(XJm(^h#Y5NvNUZ=`^k>Oysnrn3fR3YJ-0snvGI}DM`)t zsmXd$PUKD{thI3uj)H>^AU1`LU1~XuY!yx?+(Msd$992a-?MpYf2o<-DL7==U(68Y z@MoJFpY^_%X`#}IQ zG`S$x#-z#nEhBK{G3s@Hz%AanZ|;=!J2>{CO5^fC$;(6QA`6wnv8srjY-aRRsrK%J z?U0YXAaW`K|6G4JaG}7!m&h_AI14g8pqU3@)G*yl`HbYYWeRX)*aFINSz&tav*CVv|iIBva<9+);!^< z*PMYJZ0E*yDy>MLc&nDO$405aRfUJYi^+ggZh12)u8xG?8>bDgtecp6<Bo z^}2e~OT$OyzD#@E2pueV{5*qY5t-Az-}?j^Dv~C3KdT;-;_4OAC|7pV88RJZQa*z2q23MqNN>djaED;oQFp zy_Mgn#|^{}pW#iZTQ;#W#_V0;OjWxY-+~kKt57gW8sr#D_@e?Ju{N8b6^(Y>$-C;e zC6>XJnei(v9s=*KY4EHz!z!1ww!V(x#ee6O^R?)VO3M#I0}><$+&vjbMv%g>AGa2a zX$r-q^TLUuRY1otBX_8WsOan=C9I+6E!XF@VY3JQ!YTVxq|QqW@xUKbnlHv+Noq!1 z`CdvsJF~a@(w4DmbMd8w^=E1##i?bvOm7oB$G_l===7fRM=6X^^MgOhIf(J1LM3U= zk3-?Kk=Y~wKN5w7S37kw3N8+!&HZ78*NnLdCf>^4w4=1|UsJ|IF5zzP3LudfSX7(#saiHO!x2udl?jd9ckke``e}i3-Jq2XBmdY>9$&e})Ij z?8nP*qHo$RiWmAZyF>={=`*KSGt(y`lwG-?6!Uf{X%?ZmQkdHFG#_WN1@ihjfkl|V z=3`zmW=Lmw|Um(u4Vv=wqodQte#$89S`ib;>iyY9>y#-sYA=9vGk~ zJX|Krr5WOqVo4`>Q>)?WNV6?0Xk_pYa=EOWp)s}B`odx20VTmvQ1rqo)%L$%wDK+h zdD%1kRPks(otR2GBRYR<%6gCIxMEux`yqa8Kq@j|W5l(OcH$?TeeC;OxfF57Hzr z2cUzGwwzb95MIb&{SB%|Chd2Vem)@YdZoupO{m_^s#KDF>;m?Eg@$(H9tc_%J&xn{ z*30%`HmcC;G{M(C!rJCjm;#^ijx$;^b6i1&ZH67pdc%Ulvcp>XvFx|1UDPF35ii?}J_!KGe zaux#{rO$RB%{1LPS3YRo7?7<|hAao;O|EASM4tiZTV zVMrppll6yeh1;48X@qT^lwUh5j$thx@<%4nR9@l>!ar(~@H@0#!WC@X4Mgw+C^!p& ztsAB1l_d7IEv=K4`i++5H!#hG`l&*fM5qDnK6eYO`lJC+ab8E9jQ(>F@T41WMQ}w| zYazXHyoWZ<&Ql#B=$n9TFHb6SX@tb9z}_1ok|c_Iu*H!;CM7|%-5b&YQR3gn>m;$7 z^;Z3Lz1pmco9C<+q$87J`Af&Btg5!+SmA#8({bGy&$gp&&PRw{4u|Yyq^L(<36ekd zvfD==HWDr@H#uI~1iwjJ&of;sEiYad2S4r4nMT4I-8X1J7kE&AOxq5|J*cUs`0t)l z+kOu&>LB=?%A{lSYjx&|PDr1RLJ(r550Hh!?ekM8aO7+n%Pw}9jQ*<&dE_PXaflQf z`M5aJYtA~6ziQJ_*RHDHq^yR&l~gxURHEPxL&V?>6#P#i0U@!KQ1!NsqXN^r$MScw zF^2>`zi_VH#d>U)Jo_#tvo|1U)6AVC==4U&T_DC+K0+xJU+SZrj}HIW7Zbk9^;fb) zi#@o6FXu0!or`L?GGEd>Uawct7&XmV&&GUlP@CQ@XeS(?7vA?djS8i}&gZmlE1+HA z#7K8Hh+3gJ^lT$3qJ6-1#K})ORxg=x)orF!zFR6>d4y^Q4j8ZG!N2Doc!O(}CeYQY z0v%u~R`Jv^E33s=9gF-kGu3AV)Utt3xQej%(0a+6TShWfgLBQSOWomL>1S78ay@tB zovq6h2_cEt_BqUSq4EH7HQ^l*&pt5-Pm%TUWGi9=!u42`?PE^hHJ1+gXIxvJ8yyB< z6z=my*oiP#?&=A}I23&03hmG`OCOqq9KJQUA9jFh3E>=V%Pbg>Y1mwy53s3VsCviMxUuo3#o!xZFKSe-*s`WZ@yk+^hZNQ~k2Zv}y+~Mg9&RYs7ePW+K^3;Wdqhqa=2PHh;O*0ODDvx+);sMaZY<}IyHjI+;hs+B6R)Q^5U>|Aw}6Mf2C00`-D7fs zbeUq}wS%QIS^44Qd1$#6Al0kd{Q~V#k9}T2-oviw47;=Boojt<*41o<@lko<-=kj^ zgfFv%jx`d}+kKNntp8ntyDx=RY2TKwo^$w)GfTm&vuS-))FxY(H|EFH z$CbVfstsxKp~@u89$&zcZtZ0gB5;-UnDTT?>IhDpH@KosTD16xIqcX>!&x6wbfRAp zGD{n>V{vZfLYufLic^J|b3pxqdCtHMP(VcLeH9YKDMGR)#5lC-tt0&z{ zm}pxW+H;=TK{S%)0e$QG)*R?GMUE1m((a}Gt2SjjLS>rslD#|Oc^J`Sa-ar#eH5iz z*ujPxD~T%lEPS3s?ptsT)Zy|k(HzLIYNteM*DcezHN0F^(AY z)UYYmJdh$>?1XCRyxbrjTTMrxxBs+IJD}KyFQ*lU?nwN0!Bg%!_U9nU%RA$yBMv((XqVr_@ZS5~iS8=i+)agh z#)9^%TjBNS86wX$p_AFAyzm)EaUy9AlBNv)3ALxJxw>+jfzv@;@bCurjEqX>XnB2eqY6@g^p4Ax~6%;GQ+nnUkOvJ=F^QrR9 zQaBHxgcYjloy$ZFKNx#uel%OrXqM+>3ofT7hND?sQ&zF?H!0;J_i={s!YVSQ3??13 z!4{9JRpE}4@sGPJQRp~O+tg-NzF*EJe{8(R^h2x2>LG8X#fhBk-RhsMoL0UmHMr?D zIZubc{>b2TD@)@@X~8EbG6`7gv9k|1r~tg|oN36?@c$(IX=_Uhz7@XCh&LWnr9Y`{k2I6r`){;oM06FbDtRV ze^>GTkEU;rXX^js|40(5xs_6xyL4NqBy1tMCAvtZEZtP9RT5)6i-=OqHOXa3lB6X` z7dH2MhUA*fWeme^cEA13_xF4J{_!{-+vCCZKJWK=yp@*e1 zTe0-BpOy$CFN}>YyaG8J5kjI>i5X9vZ~wJmGA|h=8&qfV%f)Sj%5iC4sPgif`m8J5 zL1F50+1rwx(~19*3gGyi?9rDO4^5{wyGSA$0yZGpE@I-|!IJQKUUiV{>$NfZ7h-{f z96)t4%tqQND#-*_+Q>!T+V3%U`H4Inz0c2jU%~F-hj%{_cg{GpCre}A4sRnvY8$eh z>Y+@#?`qW$G~!=UIjd@m>|@OV=OG$IAlGDxkL`)e@_T^mU!nx8<~JFs?1#v1ATija zDz-<42nJ5DKu$*8kWjqh1GbzWf|J#ET&yk{Gzi@DzE~vDM!p%!+N(ZJ$xi=`V8tm1 z+?qv^q{Nib$%HLq$vgHh!@R8Vk7YMZS&9OwQ%_hUzuuz<7}jj9mkt)ZHy&|l8?J2l zk$9z0JS3xS?}R>8{2jzPQK{_vBcduF$W~+;d&zf8`yZlPg}U{FNg|0e^>Bl z{(>wl8UIaFd?X0UO>o?-CZ_Iu%km0tiGEOHon&y1*vFCb*-7jwNL+DSyUc~)`d9!z znWSEcuCau0hDh*sFsU$xa07ndOkDXdA-W3BuNBFh`xu{Kf#f<4d=N9yQ%+h-EI4LG zijG6(l&42OsQN&V8$6=TTuuRgo&_oPl%LDdYsGiv(g3cynF;hXtQ9gLxjP+t>Yd(X z;Zf5HO1o@!*b_0IlwRYZOOC7sq`Pc$5=~|*a`xv|=}EdE#d8%b1L@>Vvc^KdDn|5z zZ3JDWJ2B!*NbDxq+OoI7%nmVHwn;ohS7Sm%s#7&*KmEt0F}y^#GK9Uvv`(wG7{v)J ztv|q&hHJZI^gRI{3alV|+rmOxDuQ_?U1Cdn-_HCaGq50@ZU(w%1M}gZKVZb0|8&@4 zx|v;Z=5H1VCz2|!kJ4-2m(}HK@`g>b19#WImce;4tf+dgEpDyUtqJ|z5+Xl`vbw?x zVThfp(pxZXEB7HUmifITZrp(I{UDx*a}mm&Qx@iMM&y+QhvMt*YfJkXGl)MfW^8I-&IDr?8|C56jzQReTp z#=N|k2F&qI3;hb}n^0AAvE zU|XcsOMcmY|2~t>&#jU*F=g@SPBU#q;|8riWS(?-&jnlZ{dLEn8H)n~A2#eFgMuz& z%|pLmH#Q1?bc94JwHDomn$=0KFnv@wo{Qf!g(Iny)~9P88_egdTY_D};5x3Rptw@) z>1)rsQ>|eD3)!CA8oPFsuMpVF_*h3-ih7-v;iwN`h@z^H{{eU@SvAfr!K0( z%@8MQ?UI<`lGRBDH+pVEnK63oW9faA(aoU@tFfN2PUgvp!Xr# zIcL4eXN);V8#$28fc;{xfUCpfy9VH<0m3G|B8UGXz`?!W4rcRy&j7;$S}RiEf4N3ZQUBK~<; z^qcy28-Z_IL`vYn&RGvh*LCrBoi$oY{}`>-gD}CRY;HR;{o}|niXN|NkoXP6N+>of zMeq7n=0~`ahcofcl&UI_x>Gr)^^%x;^u4<1L{u8ogXHUrd~way>6tqSiA;&55oi^T zn^~Ol&1{FQ?EZZH|6*t;L`*MLH+h+a4^a8EP%Ouc$YT~h9j)u^e(9EUy81`Ma1&wPmG zFa8{;>JwfqSy2bQN6+e|n%Om8g2&WF(fCDL;`{ZHlU`U5RzBWp4>B;WSK(!c9C=_4y{ZJA8;W((UTXN`Ioc@V$9S*P-< zZ_&^M-;qUHi3ymlJzrz9D61t(UL5n&cnOUxe5gp7C8R*1`yi2ji)W=Kos%2Q z^NmbWK}ZIhq0>WJ)y^nw<@IWmX03g}(q9@n&P+1+?Dm>(R)@6vG^R1m;+gU>&au%(;YYoSYq))t~@zibD@P% zO${HHu3pPLy4dG0*Av;gx{{t6-T?|l*q0@$m}1=SC1=ElDpIo)dB54-N{oBf8H2ys zQd%vtjhBCmkJ7et_=-?CA$C7{p+lH)cY72XAi*07el@~G1;%X7_x%?YFqW7MZS82K zoab70u%;`V*`1aXjzJ-! zX4KBGl&|@B0mMXSx8FpvC9j;98;UJYZj9RFz}x|#yvZePZg3YA;~@5v%h;d0y@yO; zAbCAI&e^vspo&01M}u6`A!2&QL()s937U_zvdo0wv5?1c(U3;yuKFreo4!~ojfjTM zC+zNvRL9_Y^+#DsEyRM>k#^K=U`-TFD#7~n}CL^U%wc^rqG5D?mjffJuu zqUT!i_8q;gIk=yqGp}k<)BG)LtFTahq0OX2zMvm=7cdKfhpy!OKw5PD*==FUQ_Ya_ z3tL33*`GWW?%$DFi5O-W3coloHSXj)f->gx>rbd12fYl!-!VcZUrwmb**UW~i63A- zdtN%t69f2{jcJwPzjT$S%W-R>6NC*Tk9(AQ3(&4e8)*yG$BW==H1QkbWb+5%LKvvj zK|e+M^@IlQ!5}V#LHHDA>AbTk-^WXN_OEe1N2tq`K2eAROrcMlxl7IlR5QouzN{t7 z9kSV&OWc=AgSP6;v(8^Y%8VuM?Pnw78jq^dY9gK!=?yZVwj$`MfL9yotNqvc9Taiz zpzJ@B;9Y2)i5*a+&)n#_??|idpdbQnl5W)~wSQ z%sSD=;NCNq#J!CTYm2e^bhTEZSYq3U$W0o%q1?1Pjwf*TXxfvyM( zwm6L(k!9_{?b^b#*vzaR`Qsn}$eDzvuB2;{Q~st9Zh11qdo0~VKnePwL6((r@BV{H zgx^53v?8pnt8Dzm<_TU(d2pEY8AIq4Bi5au9bmW(E?Y|?CSgb*Ip7Z*;rFFD#cwy- z5q>zYC3kc1G6nsrBb?Dow!?i4PckO8(NocWKQwuTSG4xgF89?SnuJor-bgB}zi{s3 zdB}Fp6QaExjgsrz^_78OF?srUBhRrpdGO)e>a4Ylkzds+oUeKfnmo@i50V8zA0H*o z>T%%i2*GwZ9Nl1ayvG1F?Sj^jRZ1Y~z2%4mHiwQi>TY7($tRYdvGyc)KSz;8MfytP zlOWR|HQ{eZJo?1D-&cv%)CSRq_8-Vzx=VFt&DDodgg~oV4dPS&rSt*S;fF)ZWxScU z1ZSbAgy-$p;t@uIc3G8sfJrQdYNW3{j{O^JuBghjilzWKVg%MK{f4CDtV8lSI1+L% z;<`4j@K6D1|9)=OFQ;Ryo#$E&a-3=rIn}|nip=%z9#~ecg~g$z#3zy2ubr>DR_`}$^T>$&)18dJ`=M zz%dbZS=}~A<%)(sTcUafK~=}In@sytjL6F;pG)1VtDTRUBZ7&hG!t5|uD~(qG!VKciN;t*wzsE2z;(W&a^1Rp-88jG51-VkCfo+s&byhp$>JT z0NHCriz5deyAsudp8my&hIHj@DfjIopG`pTRo)w#ms;>{95R@ORyt_2Mkg-G)Lnsp z$BSz18D7YGkJ71@phmR!!fJ0(cj&k?YR7o><7P(QN|{jb=PA!*9_l5pg2XDnR>sm2 zbVij66-n7)0!sabDno0;yJG!&OL>k zXy8?#BU2k6T5Oe@2WOaL;$mlLrB|_Ofo-yD$)+=64a}iDc1yF(dgZ5jivOYiWN#@? zN7)erVhsW19Qq6Ch-CF}0>$C?FEiPdb@y~-w|*>%$-*%1F7n=CW6>V#;7b2Z97Ep@Q9+jHKWHu^xHv0)XkQJ(I;HnhK|TO1pkB~-7J^zij7B_UoMvKrH`zt z38^N8>P+wsPLHC~Ui>B;mC)vAo1^}wKYfZjJ8l5RXXM#sYKS+1ss_T+9mjnvbKB~h zhwFtg+bsSq79JYY;!5J!K%=*4gKLpYT@zZU=K2x^xsSO-J+4coowCce;(Cu_s4d@R z5C4dDFkK%Xk74I?bR=H3+;DVHGG{h0MB(w4w{p&$x2t)|Ym+b;1NnyRWW9rf=2NYg z6ll+M49Y>1PiJ4aOrx*vMZS3CPq0BZ1{b+ZJEOOid`9Ln&T~z<6|a8ivSD?HH|N0G z=7PM~1BZ>qrE`z@&^;^lCK=6N#=TcH6Ux znlt{oeOdNivUAG0At?9@9e1Zba1f+HVxG4(D8kdTO#daiH-(b6CiaFX>*rf3tXQrC zd7A5q7~QyZ4?)IEZ@WFSvAo#q0(@^1MxacyTRSOr6aXB)yx$J`WrG*paX0#M48EQ4 zWo53>Xd=@tyGkyCpH;pNE}*GT6R@68t`(dFNv|3RrAw1kNd3VHf;>+Jaij9&L%l0{5Xbz8C|I{VNP5 zEGL@Qpw@i|!IeEUevB)sMp;580$Z|;=4N#BS9?|eHf3bt0bb6R|ZO(eZKklfsI7Mz2ci_iwyJDRXCZw5jhKuR+>mlc7dL&6 zQ^&v$r$*)IqiV%2D6?X8~}YxNb|z*tMUvj1X=LzQrYFxzegn74vh&T*r*FE8zJdP$cNqe$cuAowQ^0~lf~{1ykwO?`C`kGo%p?NBlM{! zXSXgQ@WVbl(6};cUjz`Gdyp`BI0`sg>nH(+oJfa7r$_c&qMPG8|J)O1j1|R8NNyH7 zl(E@e?T8X~(H?rsQ#0T9>YjYL;|cCX@^V;FpYWpBW^v8J(dnqScDNf}s^XG`pz~3H z3i58T;m?ko4OEB*$f@*nnt8b#gV4vc#qEt#PPhj)Bg{L6+pKMX*w$&ZMpTL8SI$n@ zjVSB2czs_V9a{eNHW9ET$~v*vgiHy)UZi=r&|rOs2a-5W*j1g*5i_S19;F)_;M(80&~1Iv{Y`r=H@|Jtix=rpBcq!aUZfZ z_c|37(T{*a4v9v5;xR9=39e3h9<|X49@iUbn_V%p3n$M*HZ2$LGOBh_N6>8m=K=&O z0eB5t6Bi$KXpRy-V;n?N$Uj6KMuLU4z+7#Ts7E#X1)(Q~vD`%0NR5JIS>BE*mx*u- z=(xXEk~+#OV+6ZJUXcGJKDy9q)DxH8>o?!+V~etZ?1jh-4ez83Y@8s(P#NxI$zuwQ zSR8CZ_=7B@z!zNJ_f}icbHe>CN>SE4-<#Ndh(4FhRg|stWH;Ch(&G5lMjvZAN7!>m z$S)V2oyA99HEVuYWm@OqJmy3hE_fCXE1c)4gZ59x>})blVuJ5f5A$WWxOttzLyJyE zA-JCH!l3=!!j|euy#W9=o$&`y@BiieNA?tI{wOl6+c&uF6f#rf(hsE4-lT}_bP-8z zIz5Ek>5ICUwkbSRkOTI*K|TCJ(pL6>L&h4az12CF>Z*FHNvV4b%RR6a;)SsfZf}Wd zCQ-fT?3N+YvbZ+5x!3K9e7Uv_E#K|QhDk^Qv`v^yODsdV)|m2>&F9QvwJ|>qSj8j# z#u#_EtPxE{cDJ1)r~#kUYL>%ysOLQ(MXec|S2~y9R0!n)$hN)6|Do`b9j z;T<>vvGt>RUp)Ve7ZM~4!)LtL2x|GKXA=3t8Xt)#8hw6{au;f#YbSiD-U>0OpRA9Q z3E}$dd3n=*nqsn!M?L0-nT(3n2fKU=&gGqGg5TXTzuM!D*Z!NnDD6VtEhB1h48L|fu*)RERTZv-7nd8Ms{?-^->1`D#*YO7)fPEb=; z7$>Y+2CcpUu|*@etH1KD`B7*=uvYaHw^7d7FXSu1+Z&}rJlH{GJvi&;`@V+`nLXj{ z?~g%~AT&dcp9b<3<%4r=knk(%x%f}F7v|Q^+xy5K*Gz-2TkHG)O}l$Kod?0(P>?x`DVDDj z5wdj0g_a9dj`eHknWwy}aW>YQMf!*L)CP+S-qfU#>;unz4Gdw?qVov#(4*(cO#e1X zJnLo&NS9iaEhF;uMAP0Om|hjB0hn_Ls47h)l+l0Z1x6Y?`Wwd09x99H3yXoZYLy$4 z21{;wR;TDI4oWTRN)LB}0KEx za=G+EOf6vGc!EBeDnmdoH%Y22V-U-+_a`uPB+t!)b69tJv-Is5kc`rCL?$&JXB%V%7Ru2RXSIXezN3@N~O`x$JVxEVSsMtf%n*9AO?qTc4PUA9AGov){lwYiVsqUw+?t+~1Zls3C`u#k8Ac>V~ z?eHfw7D-ZX?D(adDhvPV>2^fw4!kX*cPjNnmu`I!2q(2$B^j)NfYn?W;6-1YV;FT7b zAbr48t8v+j>*vXtk^YEb*0FQ*Rwb(^ug${G?(wW)IA=^(7#Y)B)Tfhc7&>C&TPeG+ z9!NW**%0K(uNzK5jb`S~@qUm$+Bzj!>-_zH8w6=!SH{p_FkU6gwJ(}~WE2&!1B#Z* zRZ5EqGst$$;L9nP=Ov(}defceP{t-5)Hu>)h@~&;m%nGrH}6IcB#50s$wRQ9OI8r| zDXR?pgJhi{?7|Tj7Z`oudUZ|TEZ?$($*^5u}7B@J+U-FOmmL7Cmmgr&i*?BwEQsA-Z~yOTVMix zupoSD&s(%zg51C+LFaD0rYKxk`zT>uSn4-Pjkp+(`DfRBggY7Me2%b=l=YO>vXH5Z zJD5hsJ-a(3jCoP@T$5LBUEsVc21ZBT@`&j0XmpjCH04wAbKw0lP@*WPIpg8Zr95o5 zJJ*Ujm6FIw#FF0v=7R`SnX6OoMt3f$2qXnenLx`ny8n-c2|i%wtw`Kfo0LB72nQZRP|^6%aS(%X6Y^*O0d46{}J=g-%V z5$G<|KBeJIc$dYlYVZAIXixT4ZNK%7UE8Yo*5c8}{D7cVDh&85Ob|aKfl{+dUIJ2j zGgQtiY{C3$xD6dmM6I3-2-kRwSZaR@?f01W3q{pfD!$)^UfkOVdW^&S$S18P%+6YS z0dC_ShGyf{8iC$v#N&dIi^jaOp_Yo+d(cmYw*lb&JRB6qP{P4f5lH5Y&werrd^A8g zmX9Ul;vIi2_z4H3tCvfURqu=!d`OpwlN+ZpXb0f=^JgiCkzfwr?xzNK^VKE`Q!7$f zOJ%9(DeGS8+WCNb@pXqLuZ7Gp!f<~Ix#Y?*B3rI0E_k(nrUJPiyu~FJQ^F0g!`sGz zp!c=-A3O8LN-Uhx0+)})RJd2Le7{2iSBt1Jf3KROB6xp5oHN_)y!bOuK7D2-;DqmP z73L(MKM73E<4zpTWLE6L54~8%A)>?j@=v-eHHQt5yLpLS%;aZm)JHdqs7KqEN-O(q z5SJ1Ua5sXJ)F1r;6EVT3oeDpq&RI;jdo;=j_sKx!Yl_7eO!`6~8nG+*J5u7u8o+Ck zt2{-oidd7RN-`8A6n0d=i&M0f6LK`@s&Q$~0qHbZD}Kl9w}HZGgcQCFk^l8$-hvY75eR-D9zz}m#3B+k*COZjPEX%U%8k-P6uz%lgJa$M|G z#Z59pc=w#eWY7f;phqp-yT7aAhxHU>py~vO;#+HDI7zPX`cJyN2zv|VIPhnaiqzs7 zu8hWV2wu6Id?l-IOa64H2lE-<-|w-5T5j>;!=Lezo*3&Y-nNACqMx;a5sn{X;P<)F zlpp!?K@GrX4(iWB3qTRvC&}JL(!{ES#VzDZ99P(#D)oF;SI7HmQaR`LTPhnM=rEt51YWN_~X@i`I^&KzprfL zZ%L+&Iaj&s;dY#BojzXkaar*79k0YNSJI`g2f6832IVLP*7X?ULc02oNJhH?GVBr# zp;*~qw?*M&$|7!FHhi4O(BR9nKhyf)bFH$<3b-`Iqw$Z(!&k6vsraLx7H6ZK4qUB? z1U`mXIWR-1+bEbClC>cgw`Jf51@>!VLmlFC*1CxREgh{Udkt}^wiVZB$BRM;T8__> zC7@56T&XQA-p_l1Yg=sF8v;L=q$W~Zmv`?UeW)V3#zXm=brEv29&@Ud?i{#iCVkX{ zxLIlIlzSUmRU`xT2=8Fa6s&IcWnoHKtn@QpN@DaK19_*b5Y#!cHnSGkxepIBkpK~u_r6<<$J z`MO)=dkXpK&IRoB{r8Bo1mQ@!q(|zHiw1t+LGq%v7vFCZOf)W>HEg)J!bF*6#t!=U z&UKh#PPcC-cXy1)1+LPCwaTTM45@ha3$k}8X8w%kga&hyIgqmqnt;{36r5^p(NLu& zVGx#0SgH1eE=X_xIVjSdtd*%moF-cl{cr~_(OmKK5hHK~ z(<6ffky;DXzxNao6^|Hc{T>twJp^Mu-XaFV&qv+6Oa_*cT9!By<^(;8y!3x(tBqMd zLegCvLo=SlSa zCz=W2!5}IQIw*k&Z-2ya*-Q`l=jM8d@Yh+bK18zjOY$8B{2yNh@E|e@oP@-9$$Q24KZz@9{0+gHhpq4RW&^Y0wb z5`xI9c&qLvhQs-q;;he8dKE!jrjB!0IEYc>H{-e&lpnMHM5G0(kW+tJ!}-d|-rKwy5pC3{)Z@>l1o&jkSAeVhsT*>+hHtFy#PF(4VE@+Y`1!3hVnoJNKj3|f z`6niE2`_vrzDB8Z5v$hlMA0{jteM+t?b9|54SwUJe?=j>kms0Y!aGMb{tXNqezg~> zBh1-;YGkso5_vh_3rV2EJNnfD1K+wrOA2m=Z+R9$b)p7 zaBGjT(Y;>40;vnSbmw|)q=v@s{Xj_`HDwt^~D(c z`TVT5oMmLSb2I}qen5DcTrcVOD+t!Ps|NSKi46;r3U#h*s5SVy&-iWh4sL?-0`>+O z338G^p$aqYzS6xK1T_Lp-y=WCy~V02!W@3N9E|Y-GI!y|rNTQIRiDyC!g;Cx5}wE^ z#iGB%Nl16)Nrc99&U9DS$mXT&1oTqf#D*x^+{%r?4$6{pMz~^VDund?RoKx;G&Yz& zJn3}1R!_3B`!hM~Z-%X=xJ#!1SbX+EWzOSBE~d-xr_)DD=Vr?1S6x3%@eB6To9-*; z?4^4)53?=EBd9MT0~z?$d?Cdt0&;8?Ih~(T{-wD8fC1UFJV=o;yROoc(^5|Aj;6BH zr~Eu;ukUvxLKdrnoW4r~pMPt8f;b|`d4Qa<`X62X1$`8m&U%=O{8qRXTr~6&NXzRC zlC_Cd2v1w2cLod+SNd5{KRkeWIX9I-Tjpsq4%?&_+-mg*BBY($3M`Pz3AACB4OQ4@ z0LDs-z6L6j??Wx<9Hqj5YYo+s)e6=ZQKE+Fmye&2Ud?Zlet{^TM6g?MI*rt*DaMk+u<`;Y5*&J6aD$A&Iuiy4sD;0%iW0poiyYMB3N7C5-+LMq z?*|XP%&GpDTuT{an#s{O!3=Qj&-g6weXLP|mROZWtXJP}*|n{G7k(-N2vycr9isA7 z#JV)1KRyz@9mI(-&+h{mGT1)KUOmX#sw3`|$@Y>yh>Ek)C_LRSCC*&**C8eVjABm4 z(&E~A`~^uhJ&!^WB#U%^!fBvo=DkLQv|v&3eG8@P5hlmX?>l6KwE@*Jz~Bywy~L~Q zaRHb&yM|cVPFJCrL*R?45BQ}zRD3QNME%Y67h ze$$kOyz+=e6BQz&-XMF?85dX{RQW>-znA#m;9xtR3%KPE5+=lz6yC;Cl11M(Os|6! zKD`qbja3#nsrw$xuy6lCnv-6Zql0kVVN|;ZhT(m40yA1I7AjkhPq;MW&L?&c0hRoM z8V0x50WJg|WWo_3+?mUv)BmyP(*LB#8eW2?C2-6YLL|wU=a_WrrP*d`;qF9GVB7UPYDu6ehtm^u<7Kz72%c$nt0qTZdtvI3Iv-2^FpYt|MvLge!T_ ziJLTE11NWS%$&bhV+$NfU~2UV2}H2rDOcAMX;l92pr_&8)A<@g@NPQN`aDqaTXM^o z4+Ws9g2{h7XA^~Y0-xdeD)68`1|(8Wnv(F5f^Y>(SLlhWDl&s(v?@`xxfgP4NsF1H zmX5v<{L-VH-owv!3IX1;viQO=$y@nd%wuJ0P5$=w!YD(;^46?DU=L~47ZQy7R+v@B z;sD{ovb3vbfl2axB2w8|EQ6OA~avXPx;Oh3dEr|$sG{~Nw0tK zuGP@36)yGSoxpo3b`W5ogO|=gMH`EnKDT5sWp8DMZ3s#Y;nsqE-auA32upEK3=-Hsm!_4fXyxF$UprQK*&^BM*2Zv2e_wosd3Wi|efv(={GFjFym zSaR+LDk43rzO)t7Og1)poB54lg}o$oVi0G<{Jw9|?GeD~dI&ghJ9jIpen9Lc*IMqE z&U{piUI_ewybJy9%4l75OEu6?)@{G2q^8*sHRT@I3#6#8ea6tep=)KTK~RCmP@<-| z@zT!EyJ#7oVAE^(wpeTwV10s3?BiXO`j$Vc$$zsD>0)pj?nPz%mLMJ(vt7`o8z=0K z!G0kYeNP?3z&{5Ie5np#fU=w74)nIBC`$xxg|QvngK%4=*#p{b^fHop#5|4b_8)e! zERV@yz8{nrrdoAwLw<1Kz-|K}M?&(`vfDs)jJ-uPkyyPoL>+zQ$Of{S2xk3mCmZFD zu6j2G?YJnt`8@8D^sl5?2e($UJ-xr`3^En6yI)1%{u5sb&$SQZ&d9w*tLX?ViS};; z;b~~4Kt^yU`-*@C-vmIaHZj73)ivfZc5wMWs-1EC9RBEmNW@uM+=p1iqGy3KVv%c( zIijv$bWRUkm)2yhQ~LEYr0!0wll&>|6ub?3wU8%&kIPM4m?su_O=Rm+q2s?4Hpt9M zH)r^zTCiyT7Bzl`Fh+RfUykUTQVG6nX%g(Y?%+7a1kop0k{ybbr9iii`Ml-v_;sMM zW8ZJwNeZg1LDKnuo2pOOcR?D?j;uyTma#Tbwg-T~h_N^+0%#E}d@>aBD|h5`_|LST z%TMlv%?q073zEBeG&EUQD3KOq@MgspPKZG74>$(eyQ)yqkuj6VsCxdSGbr}~;%^r$ z@oXw;=Th}=B%A-2>4RwN7$mP9?h5?eZ;$|37OT3){Eftt`ilqu{CnWnJhk>L@?$7T zJqDxIEVZjVOkpK4Y|*P1Dvql!is$#V9udLMG@+C27C1{x*>dcy4dUO2jp!qC*_;hw z(j!59@OXQf;#YqbMIOX_pQ79v+KL*KNc8Czajbhq=E4}XE}p)?JJm1QX@MBrCOvT{ zpB-ckc9n{fWwf+y783Pd@#yObT=p>_pH@z|)n>-*$ouHGk37RZmm~~b*g&i5FJe6$ zvkKjiDGDsp5K#YlVGz|022(|LWPF>{;7m-G!G1K17(MAis1X`2Ib^zY5$P4U^Bw`+ zCgw9 zX7JE+O-3^Dqz?ukAANwWQoaRsNEg;9#RHJW^8y_gRLhQzXRE zavWzxK=uARc!l}2+4QPe4xoV?HjmOmli%WKj&|M13VA;BD9D^3{ef*JSKXOv!E+pz z0zdk+h$hu~omxuGslyB#vLHrA1yuypo;9(#gm1`t(9ZLL;J`mrlcWXX5)wj=b8d}? z7%%NRN(fr{r26n;Vbj5hLi0X1U!%wPVIvljmBS5wr@~?FU;b3Mz|*F7INgSqLzhkG zOzfj5`Psdff-iS9!UwF`WYMMNONqVth?>Q~$HJfnVFN@(n6uMdcGQTT*l&^|tfupX z%n!+|9;r5*6_^tGK?`#RSUIB{lIQaR-~HSN>xRTOYVmFmepkNSr?jQ#LFruNJGN2g zVHKYpSeTL3bW?S+LuM;OaR$MJ!g7_S!e_xrP# zwXwGt7{UInpJCJZbja*Jx$v~Vcv$8@9wk`xXAttPG_UqTvb2gsHZb`QRlqI672|j9OEO( z!&Ln6a(VJT!am-q(rjP$a>XF=+7lTwv`pn&jiPo0BXvi6RYKap32gP#bQZ{ateeYqQ8_HPTDOa z`7X#dNn+&_b_ow8fsf)*^%C@}^8ctK=w0z>$NMJ^A}=g9DlThK{(54&i{mF_-u4}@ zU&$twxm_0JR>3JBn~%!le#DPx8D4 zgC%=ow@nDcyftLsj=0?YRQ$29UdB5w-aiHE@YDqD8M@*%c^8qb1D6{ce)QyvNJG4W zL4%J_abX-L@krMFMf*xW!kGP`hYF`(_^s^17}9$A9j#zC{L3*)xH4n#p)=wu{amWB z2WRv)_>nvb076MPC2-mqeSl2JLmEB7L09G@@CUkJU@=dVm3qpLHzB1H$~xirz3_I) ziY~3(U69FP78?EwwOaIw+-!IBv+y92)EpEl`;K}x?q|js_);7CLxvDw{gp6HagxIp zvKilx5(N$#hlGxvqYovru`nSrO@WEn#3d78~bRSa4}~+!OEJfqgsd0IhGcUahfDX$y+ni=q>5G#8)56 zqpudyh{sr6W5_ZPuu!oePk%VnZ{S(|Iu|?=`l>wTZqDQx!a6Y!35d05CDl;u8^!Ov z4~R|7wca(~{4TIIb`ZY3U&@N8C(hH<>xdfCb3txsL8l(3cozbF^VtmT`9P33w_wZ$ zyKeok^zek*HL{5Z*NFd^uXdAcVkID{=|Z+j&vkB}VUZx9Y1g^H$6{T_<&R)G)3MTk zH_BXV#n}GYi!v=t>-5*)zQ`DbcRLyMwXII99~ExQ5N@$wQs%ln?Ar)>VBj|}g2W~% zm<#(U&?T8Q*X9D|hwS)e>gdx!zb|WI|9J$?*%hiNA34g?>B@{7_7n8O8g( z^R2f(mWeI_GG`z~XR_s5Pily7aoUnSpp`5ir9*nrDf=_5?*uxuyo#9Z#2w{MPM2s) zk3CS{TL?Twp!B<-E8i&g#M0`6uyw)WRcdc=UhR-6FLt0cC~S28=nDUsaX|LRo4wJO zP3%wc=w}_C@Cl#PN4G-96KiFa_W*n~&4?ZGjf6F#r3EI4$>1y)HL}g>EqTJ!Vt-pl zJmH-Ue9H*Ylz9Ist@EFrlBCJY#)K`$XKx4&9wefkwS_fOtH7-dT1FpZEn1|DZst-b z1&!u7?X9z{#dCFjk3hn3E&I9H6~1Z8gplLzp)*O-QBz!?8P3rLIq`D<*1EN2h6W!m z)fF(gwZT8C!5U?VHEh^SuE0e<48==s(w&<6h54-dsJoCo&BPvvD(*(&FJaUv${EunE| z9=$~kj<4J!qt10vqWR3NoXZexmb6F@i~eoq++?RZxq*Cdf_x$YRpQG9s$Z}8jQpR_ zXku2DfU>ie9ixsVv0A!_7*5a@KE1ma0B+3~lAvz20}krW4pm$q7MIzAp1>EY`p~|~Y$EFB zGrGO$Y@)w_8T3$b3ke-ULFy%)oKIIlW#4hUCgH0y${gVUBC-LoG)H~9D%&Silytkx zUffd%ckIm{%=)xM=6i}pXo+kcs5Pd+Sp|N7^RjYvd8hi%_n$yx`FIFSEdc@#tcP3x z4>#(E3>1Y8Z106$AS9n)nP6JG7~s*n(2496H^kLAt%4RTG50pZ&WAQheica^#wp)? ztVC`4T~SB75<|0&$PgpMWB3c0UNnIy7$$Oq*X1G>WD(nurhj3nu$!B=O5x^k+j(42 z;(V~Ek&bm+lc;Rf3d)F5C1S33#w$p&Kp7Exzq zI`ODmI2aN${lp2x#qNBLuCj%h81xeRBV%AhO29*rdItHF1A^>bAGl{dE$cI_Qa?_4 zQGR~S%A<4@;4Y`sAA6F@b733bp9NI|Uy5%S(KaPPHXeUzKVD`g0-g?ek=iisCCZhY zZ*Yi=7t?Wz@KB#sAqGrLfq%l%rJ&WVM2p0hG@xKB-!WZ2{ki4g08j)-pYxh(t~}(R zAA{^41fr3dZPv|p)^s1AYK*?^be(5L>tBr_Q^W@?vt`a@ok$8mN(#$^ha=q}vx^c`B>QU>)UB3H6!m zV_W#Nxnf5sU|#&;BA-?-Qgmcfdcpn@mYw~(@Ck^YGgU4bJqpLw10L&S+mM=VRgt!M z_tUg9nr(PUy+=VAN?!yF6s1S!-zHlU)6nbh&+dknE~Ssjwy+?^vMcSv)b)z?DIM7- zF7|uaArVqHhuj_4t(>N;O3j*)nH5nlzFW^(=3I{Ui^GzNy%Frdx3nVl5+lL}n(qaS z#HB7WO)OB%Sm;8oi%oJppa%BNJz2b%uV+=_Xj`5Vu588pvrfZ=g5%36a(uYl%%Rko zX>ZIg+?5HuYvst6BZ7a{N3Or<=5*|${O}XpT!D56qjLq{#X6YnzjE65qj6lb2Sa+5 z)z62ZN1V3q34Sf*^V~4ss*&#~G0Id!Xwf2MWolLk*?DD@Aw=$}P>jg)`4l(Aeds|# z#W6ol)r(oJ8e}XHB*aMN-qOoFlR^1b4q%Ifh;E7Gd!NxR9NtSK>S5w9A?w#)qMo`U ze@HZOQb%J`gkLV(BD}v)s{Dlw`MU61ZSchYA*Zi67tjtg=Qbc9rwZRUhjLiXee#cf z6|(R3Sw~YL?FO!rP;+H%#(xZO>}ka#>MO{-uMtBJFQm~HTxvU{J?XN=^SlIoWuM!* z|HIU|$20l=|38&f>b**}qO6jHYL&c|!xk!uTBsz4bs*{RUZrAe*Hk3JDhXi=iIS#N zDzghIGYR#!E%v`W02y zjOQ6M%?q@Za+8OE?8oGaL<)hr=r4r^k&>-3%ZBU_Hya$sj{2#sg?h2A_d%0oO3Vwz z&ThATV}5RTe7%MmS4=J=ojfN_iIbKbO&`?RSDPj99<<_l&O83vcu#jR9t#_o&jBpR zSur^Ta8S(%kP2TyOp`_!a^ka=jeN^u{8}*5^+aXBaqdiES*_An>92)d1Z zF5cIo?uqc7{DiOg87hq%J#jXry z(9}44^6nwh4aDLB(N|nU_pmB`V#`cmPdxDI*NYWe2|>o%=# zF3>QdR9V$O@R}$uhnpF9Wt3OStQ7{l!d1BRO6-0o@T2WWJ388lIAynB<_iNclM)cL ze5^QRCtU*pZ0UbCLq+VCUg<0L1bg;tnv~daTg=SX7Q`^GFCMk8KgSyu(HK;LuOFSF z%D|WHCvfUMvI@`^&>B6$yOnFNlDl3gE&lIU%Wr<3$D=^Dy<>_a(;OagV~JpUIHIVEVPQ}on(q%r(k=^mfDFmk{EtcTZNg5c%4 z!@6ndpOGFFv+Zk6XZceXH6&b(>r<^PHOKg);40T*pT#H#K29=@e~)X1c}bG693g{fH&{;h}c<-%WUob*)opyg^$A$-5zh<#cYj_6{9l# zmpZ_-2ky_D1iCs0HKo{{r^&-{XpD-|${CKIrAcOSR*YnK87PbK_4zYevF3cCZVpqw z9gFCRi@fymHpirbW7|HnhVDbWLC$mhg#U^O1Mw1Aj(ZbL3?+}rvu5a*%N|*(euy9$K+7)LbGtq};!)k9$4z?(|3qUyedS1f zKER2rpo@yg+%il#+&2*z6c3lyg4A$s>ozDefhXn%HdUVGM%cxwC4E|*2lJ`3diFDC zHHX$AQ@_pm|A!^&A=44p8axnFbd*c2CMf3^g3m#Z%t)OE2>-O)+|PIZqp=MwKdE?} z>X@w?Q_WV#zVnYEYB5Fdpi+I=9D_d$27wJf{ttq6^~}^S>~lZ~t_^fn96ir-pm|hK zZyw7)U+dhx2`9q2>r9&3nKJ(t*>k%$jIU1jk77kX{G5YU-^W&xciA!h7K@WYpNsl~ zoYLxKJl-X$tO8glVCWttiJsl_ttRdT=HKU(Altb_@-fq)SG>4=7zS*v-Y2-1?kmsY z*2fgO%bpQ91f@?Cc8Ov&KO`3520tZNaAqu|C)w)r+YsWOg8!69(!0hS<*siuXSL7k zlEGKq`M+L&z+VRnno2-f1ULOszXUGW_Nq>U=F$?%Ul`P^{SF=*@qM*GWU_VSWvwCH zuV?XlKFLGt_G8DuDbZl1XGk5gg4v~p7b}=BqssX$eJ3^vp)(+R?0UfDB=*qnh8R1d zc~WleUA{W%yTaQM>*M`K5V})mmmU>jiV!XQZn$n>2X{>@DWM@>XbM>}Aa5Kx z-X|FM)-F`AI`bkl?VWYQ9(V}=_LBRlldh)1kozJMc?ny67If5k&rzfv3C&DXWRK#l zCaCWtiruxA{;>AIn@leeOu!nFQVdNOZhv$=HprwAe5l5c`*LOfdl+6jzK5St4&yA& za44+z%^3zIY30`{>V(5xl_%lMu+1bz)ifJ)#N+?5l>Ep- zYEUXA_XxhJYBHiJ<#qm3Dh%xnI(R4NV$k8sxE5F=#k5bAXy2=QhcznPdJI?TlWHL` zXnObvwq!>Q#8}pXo~9bWmUsi)1zJy+hh~RHhCd!q%DjL0;XQ+@m4?%`Q`+kKm9-1G zbtATecF=A3E?1)8Xby4EGLzj*qe)bO#0GQg%3{$TyT|V#pzh(MO*do4kZ5nSWYD|vQ3>PL;9cbCjMTOk$jjEhO=s^iKBvC;6sbxGJFsi-k}_+BHB`0>bx(ACQK&BQXT^#M$~G#$t1Dgu{saVXziXTp z-scoCT83>fN%ar9b^hT?_+Rd@h#K( z{QtYz>pDzelOA;_-(BJS>!E}?#JI)!dkK_Is5WHk#zeHCZ!ErDj?|p_vVK}N3r?^7 zO_@#mYkM=e3t43tOHuT}?2TBq*+Ib`4muD|IewNZixFm39{8GIw3_DU%ErAVPle2glD zMtMA+8q}g%n-`^GY%#aob4Nd{^b}6?0r^iD`Md{97#F$aod&WFnIY+ULDHpPqQ6c* zcheI&p(J`P;IEVeU)OxFsNbF z$+GU{pO2H??7(h9rw=@d!fi>Sq>l<3n-HTjsymy|H;ODMuP7aPgS-sKApFCTWcMNb z0Lu7vZ2Hj5t_l3_5$S!ED30@Pc>zAX9;ykoZ1AXO3zOOJvuC0L29Vk#`-2Fhr&b)Gvliv@!6*;g9OI`>?(04eY=0tstn99Df!o(CG5|RKalPs*G=%_ zu?xq0Bz>el{(5#0dvphRy>d-zgskpTA;}|_dhOKb*TS_&TIvptE+BQCpSGm$8tgii zIU9KVv*LCPumydro_my(@txp0=u-gi0~<|`jih;pv0?|0H}%s6T_d@eaP@;tXrwA= z8R^KR3xyfFKa)(fLfbXbfocoZ!4OnEtSQp|_#fwfWrmwjpMElpv^I_VqCA?(_-VLU z)q|YBSV)mg8%npP)^!)dNgh44;A(BAV}?ZyKb?!Yzi14JP9`lyRn`YxSJZ{y;vNOt>Z3<8Kx z^^KKpWx9?28EyVhN4S}rNNWiH@0SyhI{I-I$D}d+NvDq!lzQf9v@wsx>FC=n4usv# zca{l!pK!}MUZ{^wI^{r%VI+{aXq6V7Rw!B%drwjNB#u;J>3mj}IjFmi6r~=caUCL{ zv!Z7Yb%s)o7gv`?&7r7Ph0GU+W;p(f{xP!uHrwopr&1Mz?r;0<`ggcRVM-+1<~p9C zy%filsdtOwsJ&%X442Uz7#Je(xRld>8t6F18K63ar;n}ppExB^^uDH?W+MFd#i?7u zus7X^i^F4fI{s?GU*;n75!DVNqz$ni&lkBki9@qsfu%{Cb}P_ih}LmP!c_L~0~p68 zo25q|7uCyQCv?lkOI7H!#LD#3f~k<>3ZYAt+ITeeZM)`=8OJu&O<876{KQF7F6%=# z<(DI^;_@*TFtOzJJ|Ubj3%2_XX@K;IA7;mE(BR$;(OSQ6cNJc@S-Wjp$EaDX7aeSk zUc$@-5;}&3zU#Q!;Hxj%Qk8lEG-blydd@Ul&03wB{z?8#QUF?guT!E1QM>6@-@)ve z!^IyCs!~ynWtt(!l@>X7lx|L)|6>-o$$EaHRBA9-dsIlQ`Ki_qK&9Jx9GymTZIlmZ zSK%{n?h#jWT)B`kjRjSt$oCBUA#dE1MqtzA1^BIt>&uZ2b6#Qfg_pobb&#fau6p9a zp84t?CVlz~lMv~ZVRzm%J*H5b7)rJhm<;?Ym{Bfr=B1BBp2)_QG(a_7zaD`bEtPi( zq^;CZa<%xJc3=iWRR*&fqJKsV8$~$Ef*a4tiO#h|C8R5y73ls70V zDYWvT7>eNV-WQz0gW990L58$*sV)dZ{p;gaRgsCAKu>vuD0<%UwY~PZJ~!N0`Mjp^ zw*YDaW;h-*AU(KA`xk#;to*9!St)c-fw|0D#0%j$Ho#^eYkzE07+~r)C|pr8@{xYQ z1}S0>c{}**(yPy$Lz8m%^y9KF@xr03Fm4-ElKYPMc>NS_o#NoYvAJTyULs2P$ZA|X zDgTm;J*KCtVjGQJ!Va3P5Yj&a^!=!Dy4?zAR&7f~GUc~@liSA~@dr@fz{wbJJx#7h zFFv-L;hW2nF2KHdqQTUPnYIh3hbaX;<>IqVuFp8}fF2g1BE#=X=g-WFnnywjei3P`dUV34t%cEv{cws}MFSjhF#LnOe~#SHUE^AuHkW1hzacffOBK1!nJTl> zn^N&L7-Mn_`)fUe)qgFITX0l>beC{8f+mLb@!KznmeoEJR@wlrp8FuUP zoRs^?ofVa2(@{I8+#(L!M-`9x>tQRj`@b9UUMw0OB2G!e0@>Cv)E80&xt4ne=)6e_ zrtd(RT(zV7zk+yo3QmEUF3|mmBuIreh z>!S>{ti)9MK)e1rN>5cc3O!dXJB^x%kYD=i6(bL*z~4eOF!D>GqB`ibO4Ll00F`bp z`dRqr=$5Zi52vX{N127Uk{k}B!0dxojMPDqP4T8vHVR+X`?Zs9(^wDb?^b!_Se7`0 z{7Ee8m-c9`UBUjNVBZSLaUkdEn$!@X#o819mE7KhN*7g(>oVPJhE37;rIBNFARPX{ zM;1!oALn4}($&nR&x1~Q2EHKu+bN%7E|NAL=cG#zL-~Z3eD%u&1-ckN_(?4z&qXko zTB7c0C@V=xa;O#36_K@9X}{5x8hdpLseRj zCaU7PtEv}Ph)a+LJ|L6#pc~&bZI|RXpbXShwLkI}FhR9r2|iPb>?2l?pF$7NZwKhs zZ4ul#<3xNDIv}79>$|=`+wSCB(@e&oSnrO`jScMr*X5)yp+Z__^>t|#R78oF_?IYH_UxRz=he zZTe8x$1E>mWe(Nll4EAX@FCn|?N>&jg)7R~Q|Ti^5B5dHZBxu%L>46)>Y z1%gFfC4RU(kDM7z@?%Z}FBE^poYLne_v+C>rCkyK!4K7q_k}A}YkeZ`Y|3G~Qi_^C zam#!>rE73vNP2uXjEWQ29@CwAZK7=@ND$J3x=M=t75XP}AO2J~RB(fQMxHg49qklU ziEqaWb!XkTbHs+4Ib`=BuP?>uFEKjrt(yh}UB264S(%6KC_d^BU$fop5}^owxCQwi zjU&kJvcsXtm?X}RAo?eeI$RwH75q6@cb$v+uudH&g)HRAI+pc?%J z5kJ|_E9PP50-5BLf^)hTad7_oA{iyD?CF}P*wZlEP>&Hu>+)aE@u$rOxbgCFLOWle zTs%^_C_jc3d!j|EDPY&4F8WhqC&~;yJp-MGsFgvo7r6KGgLvs#WuU4alNHSBsi^#k zeJ3?-iQJm{9rZ40E2@p+vNN2~@3vlne#x#Nzq6*Og(+aCOYcM$ruJ65jz>)C<1Pi( zrd|N?nVcku%{vI^S|1eZlZ-)p6RM-pLs_!`{Pp<*CF~XwVaWd-_Fu>CE>z3q&Mv9FeRcmqAj4i3|8n@@XwY zz1Cap!I^KCGaO!*ogyT6tl5h{z^0lDBP4tH()?*%8GVW_exRUWPTAV24sE7txx>U( zJpXT7KhH_FI<2e{ug)V+U*WMQO!qnN6xTsj@{*Uvw=`KR4Q`BL=9?A;D!WJRnw?fm zq5|ly?hZlEC~nUx&q8R3Z$ds0j**wCh;wn+Y2_LRLQ4RgBD-9H$x4L@y~Q_C8PsHl zfip7AW5nUzGz0OxpymHm=!Tpk{K|Y^1nn3epcuP(hU$7?b*4|@v54s3u=kF-HH!0) zwF?4*A~s^0gU)E)|NaD`Ol_q3lv3DEt=MLmd~*4YC-M^5?6oHD3az`v-ycU1naIii zOcOHv%_`l3@sBifbnCEohyO%!NaAs=<{!piE7eYSQiqIaUxANKX;IeRL{dcU_ zmZE6lLLkT>`cy9q{G?z_nSKx;mB|qBbvkD!qS^izvJ|7a{D)FORo4>iArpnRb1kQ@ z#boAo1UVirjFN~YKG4kpD?KT zL=GCCAY2fb0AS@H@wX|l8RMhjMS{a?@W5xPcO8xW2|DN(MQI>rc0-R$56t`nhP}{e z4!<&Oa!~?A+($8&_&#c z|7FxqC`LStb5M`1#eZSsUYvl6R^gE0%`uqh(2dcj+_eJ+$ErA+sV~3#t6!D?6WTOo z#xgi&BaSVUWOhZprF^#iPCjS3u^Wf1Jil22#U^O~BigosE#iXVIwfa(v%^WkM#$DN z#ka*{?QodE+CRMZY8wt$yJk3DVsrBH$F9QTz!atmEWfZsi0C9|Lt)zZs1I}lh?1^O zk^VNvzKJ&mVP=)JTA#HO&+%m;OOq9;2RKT{_&xWCn~+vQp2&gY_HkWeH`nnN`C3z% z4eQY5Yulr7Erzy+nkeMvx5ZA$Vcc?bjNT~bIepWoWA9K6GiEK^9`c}L?fxQy$Vj+l zf{4szHQ+MvMRW001vJO)`(>c^bCU58{tL3G`ji#hydjCh*}K z#oZQL$tjHQPgByCT%)~`!T*24Hq=?i_nAczS;bm|*A7XX!6HLFVUrU+0)tLzJrmTd zo6py6r5#@}kiSMqw$WXzf;yuehIjN5*A9pCky81u;?J`|Bj`#prYhdLp<~<;JN}|d ze#u3jwEHk{WMPv@K%8n5c=aWFKSCU`Emq^m^^N3oJGOt__?#_peeb(lCyP_tS4Z4X z>IIGb!s-dm=V2v_K`rfDbg*1cMwpimbpvbmo-u86MP^$ZF_IZMj9fo1 z*;51kJ%SyajQi`W6a-lSP{LB2(c` zif!0r&RkAbBVri8AJ~x`qq+I=aZEfn`eI8Yqix{WW7K=M)kD-tzakqldiaxKH#vtOT zTny=PmFCsjSuj%-lSRI*eu0>}B0H_#br9TFLg>d&6ZLpyQTrwB|&ECT1p zbnzd?^s;u`!JSK=t0iZ7RSn^eN2~-y)Cy3e_F2Y7BJg)^H0b-rCi}Vzh*@(=i`X zz2CQAN|e)K_Lbv*@jvJ3zA*PT;I+Y5T7uR4mwnrFQEkp0k>Xl#^3 z+p>NXpFyD;Fw?8kcODcN{4Jl?js4?sm`i*)O3%akS#`K3b1X-U{v3DK3BHk&U|t`2 zoc>H5!_sa2_}LYe&Nj;(%1!ldtJ;iYX%6I?XuqJN=9GchuN=m3v>`N| zjVblDH6#BZtPrJ2FwD(N2+hO9s)(C3<4B9?E>+ERdgrAnAddX1#kiY`p6&`Xyak@5 zcTUSUMEwQW$|I+AwsoKQ9Dk4eh0>xL;URL^TE6wd5Sl!7x8(=a+@aNl4Ehwlc&!== zVZ^W|O-7%HcYZ`enon>&DrnAKh5X{iZ6YIH@?!BB`n0bC6A30RxXI>bz>0g+HB~*Z zCY@eNkCmm9@+qG9lgv`d{?DAHew05Le8qJB0!`sDd^V=m=9kLMemY;Y;lDpq9+Q=Z z8t;7lBD-yB_aa>Us}Au2Lzw+Daj8N(x+)E@iH(Ag5N7jS1W&(J432`ehfvG{>^b&ziE&LBIJx1nJrMx{E&DlrXuT zxOf}(JZ^>Z_$SVwq4J&P21=3aT*O`lwjzck&e}s22;K2#l-uO%#-PW|r3~|j0^hF) zU)Z-}sdub+9{?S^O0zc4=E~R4Jc!)-_Q?pjT~Sgh2)7NH(%y?gmAPR1z4LV50ITCH zg}O^wa>9o%Pl$FJkhc}qjkGHrODQRT-w)HDU7OzDOLdi*UsWAKsu)AD@{8-p z@9c^!`odg*Z*tr@%vsMOfgL`>s)IdT1uS_=*#XoMIWxy41P)q)Q;}h$@ArLik>oRU zI#7>`r1maaM1i~c4nAXx1xTS5Y{TLf-=#?7v`TGwlU-%3(1Yx!u7PA;bbTh}B}Mx2 zgZQ4d4Oo#Ozm&qf>4Og_dI(-8d%;a2kvmfo66M8BS-?2;g1*dxdJ2{Luid26_kQc~ z@_L&~QZv5q4po(@;?QU=zt25}y`-_&U3`<4zb}Vl7MiRy*)HI!7s@*P^105MqED6z z`KWD_<~*ZHySVOXD&KIzH!Q@3lJFA!0g$-EP@12ZtwIE*pRky#E^Ch$??y=ov|)Vc zVqQafZkrttry>&bmI-7CD4dUZqRl-qKS*5GQ6aXLfI@Ay@h2r!+1|vSc5{648+TWO z{`lWapV~6__!(4iR9s7!_)!0Z^}8;cpow@m$SN18dp*qf5wa6=cA|v0Ip=hZc~pLT zusWq~$>=Lx=Aebj{ICmt+1MN_BKjScn~VNM+IxVx2up?Ctl0aNQjcCi#7y)LFi(9} z*XV<9k@Ir5DN^741&$E(umao+en0fM9tgzZ#_J@JQeA{fP3?!f*U_I*JM2io%xjBi!IKpj?K$Naj19bLY;Lq0C8M5wzx&ZZ z4^hPptztraGDS{9Pr@{&kFe|3tpnX#?5Zl}uSYF^jwnv>8Zl zbCV@E-xG%{11}Be^TXXCn6t||yq?}H-c#TVejoR)?DRpvf*oQj?i|-ry1e~-l7Zo1 zH00=xo;{HK=#C=c#=v(4e8Som=HS!W;~HKa9Z`(i3o@ zaG!1ojBO^tcJ#9iwig8OMA^`7M zv|UixK;@Nj<8SFsH{h!1Z#L4CBlX3%4W5r6jC1Hc)937$1se(J$rucp#jf+8|0qsl z*@DhN>d?xYDw+D8Q}Jxp)H0`P?26nRd^VzGohWO?8Cl8leN;7(p7#Cq1kyE>n#q{HJJx5XQ&vEqHx>~34KxD}F;kce zIx*??EsbU%&tz`_Kzq(Q&9xmz+H%*;*9?E4N8RhVjWIhlqjNEX@}{V>Sj>HN-SPLh z49T1db*%cuy93be+@Ru_MyL$@%<-`1_i0>opBvy_l(Sfb26;z*5xeCM<@B4sm_?n4 zEgUyjM`weuSaAS;ISHr@g`=rqXRbU6R|acAv8L6a=;_>7*d0qrl}zrpe%3~P!fqS& z5&Z54k>qJ-YtP;19RSAw(2NqBour4N$|uA=Zl9=BTk{0CvPk+3q1 ziS^kWN>2HQS0h9SnXRa-$NzAD-+=TSt-h$I30KV}xdm}Rim8CDtYXA4>PCGHyRF4V6*0a#XTV4u8r{O( zgO%js3yw&1hrEQZU2>M_M1tmVAJwCaXJ+88^-b7hSoI`v#Dh1(@ijJFmduKOxJB_p@mx1;5`}2Y- zV>oNIlr+!;erk{6A1VUH8}H*%b=y`bqJvCe{q3DKgjXAd^sT4Hx$st8*D?q2r@K&E zjGL>({0Ti$St|-E)R9pK7JhT19>s45(zLcnr?SHPbQ{v$CoZUO>2B(~|I*xDc>ikRrj+tvxphZ=w(V1tfjUqMn7zW4BM<&OPOsRB z^IfJYJc62}=b_(y+Q$df~l`Iw|WV2}ZV!#t_HPFrc zIdCN8gcL4M!t)JgfXY7%$(S1{uwoc0Wp*JB!9T&mCwtxOv^pf=}kVp@{X&z zIya@IRN?muX6*Y;g>5{-z4;!@;$w|}Bkx#q-$kD1;D)%P8zcg6)wnvoy--oH517Uc zq@zTQqMi+)4P5eDU*%Y#*=VRt&$Q|5TB=8{4qXzfZf(+s(ln0Up?^;K3gJX<`ugv> zSPsTuD3el+c48~j#(b}FhT_KUR4s~xuC{s}afL8xmvXDB6w5b{#SaLqnukc^WL1D< zE&?-0d%IE4kCII=??65NCbIz}jzDDPqIF^?Ik%~{*0WOfoDMoyfd8O2-a`=R#Nq=; z;liZlov5rT)7@m(jQDj@Jd1JgF`k)pK6~86mFHHc?nTOZO51GYvpGYJ=GX>Qp4?Eg z&KUId9)PkolkEiQ&32RWzJsj)=v`!ywbbm9x@`Zv&+Jw`%V}D=9-}9_Ve?>nEKb}W z8MH#?Y;T$NH#Al3eQeBEsovEIS@;AgR)a{dq ztDPs|572|_n}LIa0NRVgwf^*fif(Fw9NPtmkd;1L7jqsB8hVb`ttqoqiE>$qk*sqq z+eRKFFYnhKfCM?1^+5EY{ksJTo}@yS)E%&sM^K*7Pt!Bin}cq*TXg$u!UDAGATgz0 z<}pt~_sN(lqTC9qirTw1+<~BQQ+%dUS_*fQ@2C4;j8RrEZ(K6=uCUT(3x4(t@pa`w zP8PheHw*+XR(!%tUk9jsN4`NrD`yww&}%qNtD_;`3l|IQj8qrVf0?K(0lF+B{2OSD zWrdpOaLdOr3@Uf+O#IW=)evuog9KZs7>~sY{jYHXB{^3GGM45BeR-Sk^)2$YGbb|2 z%LQg(ie1~m?dcmjOkhYq8v|rI`8s7!#&{hYMuadrVMpl~~3RQ*_WGF<(GsL{#hzOiYI1oC-9|~ zufvG;|0%`#B~eeR$JDd6Z&!hV0ex~n?=k17`p*NN<|*ZNVcm_z9Qb&5T~(*@WzL#Mm%_=VlQM}k0&koPPnd9 zCPfS@e%7PEQEp|wDWgzsUcqV5V}gb9talW-D@YxpR=`fA>*`=L*U*Tx{pvXllv`a- zN6z)A3*t_@cT@Zfv)CRng#>M+k?ITcSglZZPTT$FJS-gPP{(H9G8J*__>E^n+ zSkg%oucGvxu9Xe)140LX-cL+G_!U3Oj*<8#PDu^9o46Spu`m}u@K=(i9l8T?ezhO( zfo}l+Gce?yz*TkoK`Vk8;C~h|ACudI4AI?*dpx4qtj8{%N&+haysm>`JOiSta5inW z0|LTn9DU~MQ40~Du$lZzjl}s-M)SuwU=X2M>io=Y%V)ySH^*xoD%>@Ce>~uCbJm68 zzCknf0rff3piar$y$W;nf`B8~u1t1wlEl~{;dYIar~svGokZN%xLEs^Ufx`>i*Dhi zp5vBzS`0m;p0p9WR6+?+%4z)Z>~c}$*k!?=v^vd8I9P?`d+N-BUc?)JX4JQwlde8v z+UMa=i~5;Cy+BS0XO0$FNa&Yp0Ki~inJDLj)_Cs*mNeGEDS(g z{jINo@-X9?ju$lFGn9eX2pap+T+ZdT@?m=73~^WzGH$RGM0ACopv=+X_?*)k5n#&X z4v}}=sXNF0T|z%TZ4j2t>62EgP8DqG_@Bz)pW}-(=0OBci0I7VAKAQHm2DuNNeyTRKpJO>@D!$r(*M>DsB&NivcoT6p5W)7W;o)#%~h+k zzo(*T6$yODdcj-uy?Yj}JmPj3LNh;v72o0tU!$5d?6-qn(FzC8{qu$acoEdw32Yv5 zbPSk-i)xL^hXc8>ONLE-52Q?lxEM8={7a4Q;U4t@&N{JuSC@)UR(io7)ubEhA>owN zc|YF1BbxP!+os{;JH!~N^&IWnlN7NuH*%m*l@+Tqn5nUo?v$C5ec0z_>g=R;D=DP6 zV9qe&6#AU_V^n3*l+o%X?E6}$6418F0yZ(bpeb3Z8d3QlPz3-2d9EyLCW?medJlZw z!skVP$s?%$)0XvuKX@URb@5Q4PcQDyj7c9ZuM-|u68pg=>CO}EaPoi#`H?0+M6PU$ zS9F}JYzp+cS9f1&T|#r?g=qFz&C!m)JRGUxzw87>-YF+`px1R&FwN&p`nxDoy4~+d z;+vqcBb#O{(xNiId=k>o7OMuR=Wh=;N3E_SJe~~sKy#aU6jdBbiTIM2K`l^VyepGB z#k)^ zBwe9R%*U=~atwIj*2`i`WnG_h;yzS0a%$}u=MXw9d!kG{9}{JLA5FL(R;T{Y6zy}p zA-+2LNfN7r*Q5OcJ`e*oFscQ%tgwjVTi0mkW8sJ^%hj@!v6)@UM!Xd##&n&1b6Z=2 zea|)HGjIKfuD5)wdRiHBje_O>T_$W>yWB(-_CBsQjDk&K5dlsTYk@|70Dl**|2oL? zO=sN{yxV_`1MM$D0^z#_XdBh+F+pIFT*4kVdC2y22~k~t%26HL z!OoJl-Sk7s#p?pfW-Qo*0l zl%=TMr&?Lq&i6EQOu;*~S+ZGu7_8`ZuMUjg6*d3wV zn!616wntmP$DrQs%Tc&w^;qqVKFSDm3DMq*VGHP1Ot)>vHh{z*cSSh3_1U~5TI3JE z32r-<$Nnk5M7J6wemGqY+w=*OwO3@xb z4dzShI{Fn!0TU|p079XD|9h&wnXID-^iKen+LS2CEUcBdgA+3Vd5zd@^Z73VqW@!ZI zlUrn9DW&K~C1>W^0C8ZK!$A|7%?I$XKp+ch<*q4Z;hTr6Lu+3RR;*@cS~PTU9|lZRMo_MQal`Q5`vG~5Oxg&97F|3*BzqsrFZd8mGhFozthXqlV#S!8uFzg^fL_l_jje@p+ZB`;U z=u3}TjP}&eQ1ubyidvfo7e25Da>?3(C^JsqrB^+D@@sE#+?5uC>mkGhd}5>?g3YZ^ zk4WxETr_sn7!6zY?a)Bu=0UN8rBM6qsEN4FR@F+`q5K{#DJhOs-!n}6W$_2CDm){-lH%mn#X~(3Zi~-}NgFsbPltZWz^c zG5*p4<~pR6O1=_=dqFdAHK9JNrMjij+uYRGkXCI-XZS$qf~{X>HP*L68F+lkn7wfb z_l&xcU!J&8$9-irMn5DmmoT=Nu4$sI9O1sXP2OQXJNoNTW0{Ws0v0f)w@60&Dd4_1 zZV&t=tgB~yTqwRsto>)^bsZF{`)++@wIJgBIQtq@$Y)>rOlT6b6MiFq^-vOm>Dh+s z-$%uiqWabx;v=`OFD0dPaP|pb1+dP|!R(^ZZW@SG2^?Ak z6-(f+;x@jl_A{#Q{+Mz;T=UM4RX;RLt8GtIC$U^wco*>S`TF-dO;rB0_F)nFpWztU zt`7%P$5mhOz^i$^;1jDE#JwRf_O_zu?LIr{_e*7`8373yI*akf-j8vT#ZMVNlJEQV zXBgH?#ddRb>m1Af1#^(+r(RIr8){6dvzIv%N&!nk8AcSX{M|(i=PM4fwMWiqFL-7Y z+EgBVLwTPqA0AQO`JoVRI`)gcc`y#`Eo9cK%)Ivu6C%N#5? zm%Fo$9Xm^g%O^<7he>;TG`XLjvi9lWY!7FLKD$x}UXPZpS%@KlUtBO7l%BTTNR+Qb zA2)MeOIC};av?CV8rwHvruyYpCwJ_y38H_qzDv2fq6SXe1|Nn&Jm$IJ%EY6DMF|pm zP^|D05FV!mdFC1shG~K1#sw5DVILHgt+E<)Of_7=feY_PP_>Xp(Kr~pp%%=|*Z8}{ zMIL|5QGKXFMdZF0&((-=C{B5bBIB9UN&3p}Xm~ndodI5ZJgIQO$GsS@4lJQ>E|~@a z{F^~ef^cE&d`W2G68nxhYFMCPvzt5;ofS92b6KHY58)OGiqBx$3~sS!+^z=Rg-W|K z`{UPvyFzQCXohJs#r5nO{rdPXM-wod)%}& znc4-AH{7+Boo-BIn*;b4YGTEWCWfVCt5>eZaB56maq=$lNF5K(ymRWRB3tjQ9uj;d zuVir^HAIKWVwAqKX-%HH*&pt|6bO2-8M!WwpYNaNE|7dFYNaHs9gEwi3OIHjTxrtn zlMLrlRTT@knY&agEhA|QRt(`Eu}rU`#QY~Lw@0Iqrkz;6<1YmA8C>AN=O?9$Pn}k6 z7;NrgJSJVf?*Pa47(IM}TN4(FoC;Ka+&hrJyGr{?{cL2as*h7Q1^ra1I{~|7+SBO5%3_0YkZg@G;CE6%EUF!)O&tPEpFr{6D%XUhLAih$e(q;W}am_?PeQ9!tO%!Ex#=3mWGO#y4V`M=zZjRH< z`|`hs8bqlsAQhHRN4|Yhi$YEhzcz*o@liOy<7S(#IA=iM2YA@FVk6Cu!!cR`3^+OF zje9zhKJ|H)a>mcB#Y91@iSC&*LU&47B-T5H>1#PBcC&p*l&#};2|H{%FNMPJ#-E{v zQZrP3JT$&o?Q<9?-c>!R$A{7;y~b#HtQ**RkHlJ!Nd9z|Q|@bc_gm#H89%(@XZ zUmay9ne-8zXMh)?geAJgsZ^a%!*!n?r&m9!ShNb6t+&WCp_IQ2QH`L=DMOIl=n zHR#-?TC;W*NBSxc`=pfi=1+WKkUQDloL?@KyS_sQgND=JB8ApX>~7+HY#7%on)1W& zP;Nvv;l}z_xrl_y9X-OYj#VY8SRXxAWY76qv`Z9~0i*tyieG@9vuzmRg_L;03xuzFYZj(;C!2+J4EbGgX=@}jlQBMe5mW+;5pUUpW@1z&! z{5Rtdo7x5ZLJQ8lGX9Ys@++$3G5eEn{*3;q+giRA=yD&+dtN6(Gr^!Tg~c zUjRHiGsphlqcr3u#pSK<#F^U9_zpRe_-gT+|le+1&RH!Dx!OREAju=H5y!GWOY!^t12}_-+S%OA)e?+7h zerM!NgrM8^MkVVqXG5oWuo=lD5>^X20cR0wniGN6k5_@13 zVRug{OC1=|$>h@~+GdL^Q3tRYx$Oj2fqfiu^VS}CE}$Cv~EXUYi5gccR{hD*9PCMmpkkJ?UI2b-}4KT z#F=9>W0~$(q2LF*UWRH_7oWIg90SYJSu(a5vlBQ#kdtzPJg`3rbUqCGwRDosh(+qe z5nsu3)jsi$S1B1t5F2B1q_jqLLW( z4tlB@Vue!V(FEc6xh%hyf-C-F`)U25g z0w#jm1ZyAa@e+>Uw*M=-@_Km}(D6HZGlZ7Y%B9Q6jY!;Qjsxe`ldG4r{!kck`{3#3 z&ih#_w{npFCkE*=oYXtnZfOj@P|sDS54w4h9cAWC*!M!u$Ymdt#ze2$B5M6Utn59i zk@T>Xe&killt#h^dK$k$G#W^&`a?361S>$Wc4AwAwjbi{$pUz2Q%Voxm6W+r176b> z^+^1Ypv*q)#=qn_Y%!ccJ9z2Bkz9^*`=wJTwqLaHS_ea=6|3y71T z%QVGD!cUk`D}|C^Z6oNUklP~K+a^u;ZMu~0K$7K2AK&-c#j)E+DCVR497aATz0cm} zA9EW=4>b7J0&Hp62}Pvw3*f)(_g6w) zs;P9R+0kk;5UtHRHci5Pi}YT=_=om-r#CFFYYVp2#e_5`^w%ozH{9>SQ5}JBrR&my3ATY;4|W)>Mm znorK<8}voZ<;x!G^&7wIi_&?TD{i^TNT8E*1S__K==W{olFOZ9%2$n%_>p^N62xbN&LA_} zQ5Bx~B{KLyE-DW{8!*R>L6oZ3fIp)FmEg4n`Ju^{>C8;_Ac2)o+aa5yz}%+upZk2N z=>RbJ$;o(2#f$RoPb2_}kd5`Y?aOh10Sh%lOc_gXzXi?`emjXfpQwy(0)pQ^taY z_EIRNYxC^4^ieHGN%x|szE2@^RYJo_%AtGI66ZlWRh$T6r#Ne*W!9hX_#988LvKL0 zf6##@P~$@c*}q4T{oc)hMV=yt2OJP6ZJfA5fiGfl-_}st%JgH~wkoq*jJVz^ zdKahBJ~^=IGOPW`EOfjQ{Bu((&R<`!V7IOc!?|EFHDEYqK$iG1#V^Xou29>`XJ2ww z10}?5APU)5X2vwCwaVqpLs=DF{CnAwUBH9vp&2dStzGlzwqWgP)+eEdwSXUHC;l(^ zXQq`|3%q-uSoSz_Q7VkDlBry z-cgE6CA6N1uin)WkuMiO>9t;GrO8nbxdwK>kIvNFN$5DcV53Mu?+SG3E~aC$&rS{eTqED%y4E$>XsJ0s?X-F&>5A$z)0H1B zHxREDiX?4xY*DeO$~lWBDl(tiW@y8|u-*(wT}i zOOpCC!_8lyB$P_2G9h$H@?tsxsPG&JJ9VI2$s2#Nfc!jS4@J@9jFKl@VV;)Eryq5- z^EkyB?I<4JDY59eqSuiU*B2hX>3>3!OXP*%RZt8kY*F2p;Qa@*WsC1^qvE)+rFCOV z6*2u=x$4633v`jL5>MSaa3d6-zHv#_b@x)XP2k!v;-ihc;M#-xht>D)7d>@B-Rp^9 zXqZjNG8r61tI?y{YoAgkf?k1_J{bVp*|;o*g%3y5u95uaY`mS$Vo3UtcXZ!ohB}Ak zRjxn3iM~3s*ZH}x4DTb`T;)7DL-|Gu<&&#FZ5AmGk}fP|gdZgw*nrzvc4cJ{HO_nt zsH}w#E)&ZEBMs0_+{8(wn$SZDhQS+Ea2-t+4*!TPV#uZ{jpVQzsqOB(^)!pr+en&P=X11wMQbF{ z=P(-~spW;6sG!GEOJ}^(g~Kd=*t!xl`!dq=-3~B#>&VNW;%J~_m+3s5M|{zq`U;rT z8OLBR7_OX}lq6moqmY2^KEfn}+)lDkTkI_+u3>9Q@N{W?%C`h@%dIP{0ihk{y}pmj zUZ?>Bbtq3RwJ3~PeFmWk{2(pk(VQ3ZxRvn_UJ!oolQ@>c?E1r{9q1=0UkS~v;vKpZ zt|Px#^Z>-+;p0n*)q%rqmil;`ImVLjfp*&YGm>7pQ6d97FUP-?(Xk$)(8)_Z4;XLc zpv!8+vq_|ghCbsKuapgDD^{!V`Si#|{%C63n0g%ywS5j8Pk9x_?~N81ZY-wbXD-Mf z!r#X=yncArM6WjR9VN#IqCHrqstB9%el1b!bf?8|p>x2oJvc1lA@5} zVD^cEvc-CHuwjd5Y_G;R!WHQ$Bnz%qHiA2PpJFsc)HQ+)G)fJFtm2R!^yRY9#}ur= zsQ4u_s7-iD=~xtAdT@Lv@2imsW|?maXRg#P_j~lwEXP;by3=;1HSj{+E0aq&jr@Sr z+A&FxwA&*}${w*K+#t7s+b#!d$ifg#Wk*TH*gGdG;U1}Ni^nU~E!?9-BflOj(Zg%QzD?%>U$c#&soYW9>@2Es;Puq_we!SN}p)$wcQbzdw(MBv$PP+Le(d$ESB$yZ9-up9UzT@{Ia zC>Im<8b;C0146Lx!ar15 zZ|()Wt_idnJqN8VMfYbmgHD$VF5sc^;nOi%jMeF4(bpv8x82%IrE9s;lt7pdy+%sY z&dE+)-o`tSIXkp5?OZY1@0_OkAwR-X!;(mZE(a4w+utTJMa0K)9vB+n-|@}VLK|29 z9uY8|mG}7A%{hHX>F^WYB>G7L-1``A%}2v$(>T+#Zj+H?{qAG%CSwG~jb08i+96zb4D-5R1n(W6Ml0$|9So%X7ziID+r7A~ z&h1A>ONKw3mmd%u;0t@?+xTCT;t8Jl?bxZ)!&lV*HAcwF#Zf_o z{BlwfNAnG7rkc7MRccQe@h;p+&}Z9dj!6dc+(d1XgHs69ym~X-Wx-0QA_zXGI%aWV z7L%yYwP;aczpS`>uLje+cpZ`PbiE{hDY;DQTKgn z1f3~KLjLh3r9TuDuHa~5@wPBtE|*r89Q2#2D& zbDv@4$Pts!TAlqjS&>klg!``L%=C^1i$gcCw>uX+z;EN6HkOrzr9K#DX#I}5R~5Fu7c=w{n=iqsG0>?S3}nzH1;M8>3mqca$;a-x8dZ*UF9x z@DkI}a3{M`5#C)yc8riJlx=vq;%_FpgEbse$@qD7MX+-)mK@U%=Fd=c8n#kI4xBy~ z?w2DM##jxFSklzr1SbjGhhu;*ydoEtkG(#>XvxM09X3OoO&@-3Z(S|?J8!T)$^${lz_vwh=m zRvw=g28WDb(Ul@0ovVX!UM~Yy=vpg!^DTm%|+mcQ)KZrn%WA}9AN{X^-Y3`M&m`^!&%6AYy^EikA|8<UkIo~z{BT|OPCB!>Zk*zAPw;!w*BYzXe!5h!7 zMe|#a@9Lpv&?TnN2iHi}KF8QLhMSD2+!tLvy_T?W2;lvFAx^O;CCdvf)d)&OD2Gv7 zV@3L#PgHm2Ps}h`bE+iOB^^PUEdQdp;C_Yu(-gVHLUyD^hbio$(YY!dznJ*|i=5I& ze+-*|P~trOD(xwNeUJHQ%9=bIp(L9LfAfc;lS?FEw*Y7H(vHDo7(|fao3Xd9X@MUO zlwKt7Mph{mwyoTW*vvRkKJJ^sphp}T2#goyz|0#}I@3TeyY7~6v$|hM zBy43yOA1>|I5%$nF>uoA>!Kvkfl?C>eoqD}25h6Vdc6;Ih8-m-#&2!|BdOYaU_VME zvIF9Id*`{gM9VXj?Zi7`?(N6foHx>2sDv4{#WM4IHH>}uu21sAu32#n<1fO!XysYD zr!8sp-V7c@toGbeEkRK8({{d)x4tGhrk3y?{NDZeKM;j`}=1esar z*7Yi2%rnbMg}@x1#18AxkEPQsa;iaS<1QwpEYBU@Zcht=Ud?IY!p5s+oMHpH;SZcQ zeAZ{LIKvhj4y)!_mpL+)V%M9Cz`+a>hY0sXZ7T&U&}XT%UnJEFZdhg0VDS)Qx27Ph zWC-cAq|TqTyWU3qtnzWE{xF}9HZ-Qu2t{xN%0pw@qP^$&`?oV#HP!9+vQeX=vAoJG zYWlYNqoca~p~>_r8Y$p!B^wOvSw(sb(AvlcWb7T25>OFe@zN{JDs40S0AxuOXVbwz z*u54BKA(SGMGCW_TZJqz-o(^;FRSn9ryb!7t!&7#`V@zAs$3-KuulBkV8Vv{PE<~X zmVbQ9!8Idqes(EJpD1?yp>Ef5_Z7*rTarjFm_(g6wW;@I_#gO1|3u)exH>a^B=3wM zz9QEyaD!z5d?(}b#|ayyHq!46eYT(OL#p!6Dvw9MadFR)+kPpG?`_yP%n7c?YVnG~ z0*1dpOCYpGj#%YyT7?QwdHk2S8Yeu>$tUl67J^r#%xUH@?x{R(rDv{$6`FVJx=ySx z%7BLyeW<`PIBIu=ZPvmHKX466UO#9x6>}s9+0pwrIjn0Hn0?kL--XbeJBs^HZM!J8 zrP>rMb-eWh_NgwKX@u!BYf@(}7>*hLf?lb`E@W)wW6{^$$a=E6brq#~jDMNN1uKPB z>G9Nwdw3+IRG0X?T6V@W#r5ugr4*H589ob>BkOlp;9t|twDRWPdrc}bA7ieqZH7$q z;JM3xiy5!~z==T;{>R(?!mJhg1;b-9jxipz<$FzZl+Y%+0A&Ul3Z9~IA2Va#&AVL{ z`Lq3?VWB|si>fbmX<3p!Wo+$YUc%^~rF~U$x)7It#omt#`SIV0)EUIOEfgkyLE_G3 z@=v$>@1m`ow+Ih(!(%A01Pl(jYs{fQoCFHS?B4NMHT*XXKeNv+FmxI4Z)g(D%7D6) z$5n%XidsffLx|X8yx?aAkly@-Jd3P&`;!b>pN~IxNRWDdk(>IRe6pV@nQz-Njgy=a_#n0`K*lPmG6A8J7C$G>Vl4$fY_e|2=|B{5aVhK?KI@f*OND3C)abs-1NCl!pj3cv+sP-t3sx29H-D|LgO~$>ADnQs9N(j)PV8D+PdEVUtB?-}KUe|!m2dAy!xgPWq}8!j$hi`NrJxoD2C_W&2g zT~DMg`(W`iLE60i<*P)ch}-kDR7mOMi<`ORdR7*V|8k61mRij-bmW(;(i^2@Tgk#^ zg8p*=9(Ii56I~tkMdHc?+rfsGc9?J5mMkbCS=zLz>!|GG5!FLKF>+An?M~Hj_?$)) z%2aymtRla^+ov&nF?W*5xf&%H9B=+i*iAON8(9I%lh=!|=HH?A2y~`OY!(%Wbs^rv zV<84+C82>uXj`EjPqw!waCjJ+snXCr(#!A)mZ)4{*WgvZg_??=0r{_`JiG9mnB17412h7Cs%;x2oT>F9BH$l<}N zL+$=SOIph|f5I>h*V$fYeT%^jJgx9+yQ{Pg%F=PrzH1iTQ%rTyoWZ6FDvBRk(+@@o z@+Y6AYPhZcfgOmA+?*X-%sQ;dH4d_n)Ch8WIFx^?@Ae@tY{n<=p!szdlMIT19Z#u; zyJ7W3Q&(OJs}S0_jQ$R(-(6HuB&=C%sSAmiw1w#(eeLKmf7-MrdR=41k98L>0W>qg zrwNI-y^-`uF>OEH$A$ufG%dqhid3vX>hLlhpVGghkEW?wL;s%U)`z-kU(Y$E0DMy5M=cnUQS!`B4hd6mgzk&M&wl*s4w_$YduB9U8?a{`)STF&u_P(!8LqzsPnI zTRk$O!Fy^os2gSX=pgLFhy+y(-w5AFnHzo+K_`{Kh9c+X1c5hLieiNX;+Bz+jM4ek zgwDHX;`}`gz;kbD=kl>@rs;=d2n*co$J#D~mw257gE)fGbVAV@5#MrkDbk}OHE+uc z(m{iLI5ntVysba%+uTmd9f~blGewdZ?i8Mx41Z&N1<`=C&me0pE5ZN%XxH6U6Qw(q zemS^A=C`0)VNBb?27^O;_6`$~Wk!Asf8cWuHM3WfH}JeO8gR5UlqPueL9q`aZJh9i zeU&&xVYene*_AjOhrMCn7?=%Nt8=}5gA(Z!Dq$v{fQL~v~j4VSxo^i77{q22W8r#P&5#}c#{9p+Vzb-LiaeYyU z96irC8HHz8C63%h>)gQuug97k7yW7{xQCw-??XEtrq5`Jb1t2co%#o!go*O!{de$g zn`lg9!gn}iv2^Fyw;n(fa-ScBkB!*HeY8nY{)mDW;K8}lB6WU@i0qwTt_jn0#)!MB z@w3?$jdX@#4(+`m^{JW0@?798CVvpI7xE|rFIfMn3i==F*QP#yr67<$1u3JsiI_oJ z;Qk}DuW+;*pNEHfMZt1dLFv=Qp@L($;Wvc|90;tL7S35pVU$JIDKi!U2IW0iaO z`HBmtrx@7+TuH*X@w#+K1H&_FKaUggdy^HzgN1(sWSB_7wZG$vgx=>h{QKvo)r0VK zFdyj9XUBRzo4~(0K-WGkt?X6FMRs=zB}?}e`%wo1>iM5l1vk`wDhy*{%j;OqRc{iE z#_>t>tL}}^zA_zv!*K0S*valD+pF7|QpHW9VFyq%K9sY{_XCLWGw>c4 zeAwCBm^Nuf*%RT_E?sWOkO7*z8QM##YXE`7lyi37(pSVk-N#f%9tv*c&me1JoqI6i zDjyYo0K%A8Bm8KXDJwYt1Cy-RgI?${KyL2rDnw+aDol~KJ3Vc|92y0$h&?GOflvwh zUp3!J@C{UUA$W;ZIbrW*mB*TV5l6@Qkoq&cIS&4j9qzYq-{)*Q;Vt|3rQ_l4yIM## zv_D|akrou8iskB^sr#!H`eI8Sl`1AO>bA5IZ~}Y`7~G=|1KFS*gEeUinVtG!j!T6s z0__z8PR0CTF~6 zr+&X8`-ii%^PX-#*%)h0`$0EYT=}d-tH$4dy01qyKcRXX9(;d)i2_zqui8ps@>rM$e{?Cl~hhjt}Q2QjITk|7|}T3 z!~M=IQ8g8lL*QRM!dOY4PSB?n6^8dBZ_CQ^gy|vpjGPy3?aT7Ata~RYZqT14t=NJnS? z!EtJ#C<3iBwP|Pee&ehbLshOY>@e-$DaCLWr_T{@>o84VBQ;BqXLIP!Yk&~EUOL*$ ztulE(OldAr=<$fL9PFIt@A&NnFp@Y~=B3HQ>>|32*jn)4Gd^X5WkE%or;KtHFK(Xm zswcl7bFNxvqD^}g4&uFPfsPV7KqLJjV~pD9hiUJ9dfGTT_>})`Nb=b~Ic9&GReO@N zFrBpXtHlbv{?GD(X0v54MO)i0|M>>4^UyqA5%-wusYCcobN`edO6U^;oTB#(cp>~k z4x`6immUC8_oOg_Q$mM#7h~qBp1U?7;9UowU=3=Sz&kr{NcdD)Emed8Lo59;l>(jrS2U(=z&Ekn zEv5V3F{W+C=O*>GjA3ijZEA})cB=@E+nsAs?{_#p>t(6BLebdL7L}J?BK75}gdQ+| z^n-X%zRh%vF@=X3D&!?i+Z7iNmW{1`eFPjbeKp9{+HqY7eI~8w>R;w5Euq8p_f_?0J2O z>&Y31Wy_coc%2!yiPV9k;zT3l0i$M;LO;9Qsh+PLBQYO1PfM7&rxKNR=Y(Hf3=Qg}@8(sSQhmEz%t1guM~dWErv$ z^1yG~VG}0EDg-l5q5%cQHKU5@I&($l7Y?Dey%IZRyrsh?L+Ux+AJ?$S&BPXr>T)h` z)`Dh_+*guMVjV9=*GfM-q)!AzzF<*ozY)GT#&bUW1FPm!%#50lPOQ8Ew^|1>A#ong zAQpYBXo4RAAxwAb$BJem1>z3o{wVmjl_tk%)?RJvgtna51*|Pu!e1PT=S_7RkT;Lo1PH!VGrX%8>o#hx)#IbJM((RvwIZ|&?s4Tp5Z5{h< zbwQ}lAA1Vz(sA7TBsnq`lEN9@j%C%rv$(M)Vv)Y>q75%=_!%RJYHqV^Ge7=@{C;wU za{oI&9-x`8p6B;)t=DFv?isw0-aA8*nC3`F?e)c~qRaN%D#<{H4fVeGmZYD&Oc(!1 z*UZEOpH@jD!i*5Sld!gg?emXGN}M4>JFDDGx&qL))8_@rL!?C1tkUk64uIGF!TJFufcude73G^j|a?ao8g?5kIU{fTZ|5 zR2w&N>@EfS^Wb2^py*n>a0YB`m-#>c^BjIp0H%@rL{6gNgwFtuh3gm!l&sC50DId$WB;nj z)#7!zKi8ZgLGbL1{&ThE?c9ELtjLm-x4af_s%|yKkMZSO!%=npJ_D^@hk=Q)U7d9FrdJkJT~iqnxGuV zk1Ki$&5`pV&)CmcogWa*4UUOhYzm3O-jzTtF53l|E5 zTt_!w3=!>lQu*kqNuG;roeFQ^hs$Q4!a&-W+t+0dLu|bZk|6gQk@TbqgNv#RIP_N^ z>}FDtvxRV`D7MJFC*NyN0X#=d=oW5TER*I+w3bVtonpoTH10-QEQZUfeLm;QgNAnp z+)`m}GN{2*F7jVi!2Kw4r4Aq=pWF+HiEbXQ7n#EtNZr3b{3+uNWQMbvd`xinufhvA zY2#o@?Ylx_K^%YFRuQ?!Xujc~NZuL(sV;03y0=3SfAd7hDRxq29s9t2*7o_76BzUO zk(3OV4r&3{{Syj&bgmsq!zjX%TWWr}jM^=8+PLY`oQmZ&HwD9)7&+P3Q>E$$oHGf@ z)43uhcU1iL0qlaTC$9|L09g+KJOm6gWb$NA6r8QZhhu>S*AMYkJso8M4Ja2|y! z>}UanVxMCL$Tn=w~@l-Nz~M8 zs)|M3VX}?sRPRn)!ln93@v%S9DRo+F`M1Qw2;WOf-!B{E3D08S3Y@GPGR;x+PvYH; zYJ9mofG~Uz!D~@5XzyCLzygEi3YF#GAOF3P)BqQx5>>G7S}m~M#6J_o zW}!m~@fG)tuJZD-*pUU0zRJNC=*ZRt%U>ncMpYxww`H$ghZ7jDDT&YHMZZfOKny;=6aua+TD7b`u@Q#nScu9S!qUZSR+dLGu;yg{<#?*1^enz9j7ahKG;S*@D0Soo>3(oTnIO<-`b zTMJPRMzm2EM4Z*OHC089^3oR_y^Xdd71ytj=I&JEA6h6~*Q*xPJ<2xuxsT@e=ZQo< zu@5{FdquYGwsKpLa1`h9lqt?&ztOdm;b&54BrXa^&`_5qOS7QPJ?Vtlo3q^mUqIp{ zBkbZhU|y2s7h7d4lk6g^59SrZ!1>Q@uO-{daewmGz#I zt&D_2_v<0_T%(kdy@A%nDY2JYuP-IpCG(Gu_j=SwXu%8yX9Nw&PC&oV#y%O7Zz97yiB-#TvUgv|omW@v>I&)~eV$1urSbfZFc#zrLv*VM=AUH!h}(m` zMF4G=>0r5AmvXI-r7!Y#f+~N1NGY*q~uV(Lg0qg?3&VJ#`;pV_G00oKn^+hnp=E$&i+Bdrc9F*kV`3TfM7 z`1dE)@+L(NUzkSFfi^<=Ph_}{ZqiYHB1TfVpJ*pD{zE?*0~#re72f75a!@%miEt{0<=-Z~eLR-cE8(gf8z`fZw)a@Yj(X9iW!r2eFvitP zVLT{&bLo5fKG{ppg?8k1mc7e_KS};yl*bad-Mun55R_-XBpgs&02=*qPlEOO6fm*B z$7B1$N?`2khXG5Y%H!rMKMSWqVa2l6B0m>`g?|Cx5Wl)S{}iU0Z)kgnn7JS~rrzqp zTt;|@LKSLzanUyh%q3{e)1KchkRpDG!7hr znJMRN$)yW*#?oDihc9{6NYBwQj~QEvN$q=#$2`on!Er#4AHn^bQAphln#%C1*yS2L z-Wg*~s(vHhfH`RUQm|f_>Uj^p6lJ$zHZ{SrcB}M?`f3UqI?FpE`xSC%O}$QIIEq~* zgn_4nF|Th|N<p#HrFp={ZI${9YwYh=#5|T>^U3$wv?~gG) zhTn^XqLf~UGj5Ou0(AQF^mGo4kln$9G59A(6#5&kB9Nlr9t9}4>xdma_o(#fdw5+u z%R%J_3UVOkoGC$e#5js%t3{<> z;}25PwM+A|0QM)S^M0Mt_M?bka^V26>ro9pVU{Ek+A6J85{;d(jX*G=m==70wDhVC zw!v)W(fw)v@L8@eKnsp!Tp+yx*RRaj^9n&RoPrJRwm=-u(BL?mBU^}klli$7PN1~W zEvOH>f4QG=x@=9YLNTZxYM5gJYPhW-w8lIIuU^JG5;paWr@B-T?m6EmYevvPtxt$(_YK4P!WHGx(IH`>ll*w$arX>IE) zL&6HN(-8pwYxRZc5=^-)=RQ)WQVSpFs}AWeWW+fr4#QZHJ$F_Xh<7R_n43P-`pV#H7 zrGMMOxl$pI_%+QE-PCC-YCSQ9ER9t1R2@sX!4gFS4Ti?P$Yhx*kJ;_Y7hKCS9&y+d z)K0j9@!G+T4TSPEHOa4s^dKAiy9Q~|!9UTD${)g7Q)4S7uRTNXQ0@eN7ixM$I-}@K z%}QlH^S5PaDi7bd8E%^lxHhqGJqJGxREjxiHa^Y&$|aW$h*_d%b#LSN`-1wW`m?Ar zPFg6iGGM2~*(<*%i)sSl)=VUL(ZzZW;QN&taBXi0eM&!5gbZ+Z5(o$S>{Z z-9Ohdl&SAW9?*P5(JaH3?X;#z^jSF~Ge%dtku+zt?l4`DC~3qdY+hoGKU4(P$3#J)lb&|M-7t0_T{50a~B@BH00Z1_-|R;Sa8>N zXKH5WLA>jX(E(1WGM~kg(|O+8fy(&IRxF-nOJ}1|V6G{Yl)0TvTOv zU^~#R>*jbLmL%P5lEw(ms}&2H4e76NFPI^R7 zlgEFDU(pvl3P<{iHyfIAct6JxU;BLY@x7dk2-LLN>U{*#77F$p)X^L%P`e_dRD}|C zGpS{S$@d#5HP)-3%Ot&&XXTBPlE4iUOmw`&=&ckT7jNjz`oGy|5Oj)yX>Lua> z+?+Qr6**{#=q4cQ}?Nk6utizpfgsL5iR|& zFL3w)aBvt&^o_?Bz@dfO6cnIT7Pplk6GQW5*43)koNUy0bs!I}C`aF`^FNu1{P3?X<9UBasD08I^OV2;>Md3LC1VEm zRy%Bpt0F-lykdA?7dR#;AvBZUg{)>b{X`1XsO7Da z=%$jEvY{e@zk30^3}dRSINgx-I5-b8OeYeY3`3nDGq>IeNI2K;hIXt}@a7$@G+UUk z)inhnwD-Tf+xkc?(*(4RB&h2-FMS@~HBp|eH&K4!8No;rB=p5MF2IC%MM>_m7mrv$ z`y)M2&2k9On^yZt^xGK+oL{Ut86(ZGGaVr}@zfbXGJF$%S3k}3Ed~!@YiX|Byi(w1 zfbYSwe193;)-RHzr7)(bSctsCThA%lZ}p_XZ9Gic*j5w9zGQzKk~qDKfL+{C=-}}z zDs)AYmS8!LK4X(TJ7z@!M>8!e2_>9|lt^fhA>B*Ed?GxH2bHoglL+Y(UaClG0JcQS z^KAf)1o{@&keO^VuHoi@KC-5Kf2#fvx$FrfPpW)Gd`JIZjr!0?W>2c3S>a1y=DQ`X zy{MHe3={)^hc@VlP`w0ItF2TW(MOQwiFa z0h5hD;D}6&7*T(ncXXBkjYz{lykR##kr9Ny$yQ_KnOV>1hVC?xhWVtauw7i~pmb*0 z!g0|~LX+8KS;_Yykys9^8AYmkQyR_DN2dScCsDF`2{?1)#Yx*n_5LuB(k^D}Tt9Y1 zU9{P?v{5RdObIlutskXa;(^Y?F~4b8%N7SCUR9*Ux>sTcEEooZEdWDs0G8qIR(@N@RZ#pr=>2X!ndfZ8jB7K;EAAh&P0CrLze^3 z@YF>j8j4_kiTgBT@!8l+(*FRD>|!|=E3N#Dx!>zwsntDGBjkXh@{1}Ol+FPW`qXh8 zKK#WYNjMj#49Yt-g!QGh=<0LYh;KP*$U5oJ1-C&uM;fk(EOB0nEv2~@K!|roj@l*c zv;C_O-};Mob}Q}m)E9n;mj386Zn1iPOt6xL-pTmVZbjN%$l{qQCCQQ}td6t|fa~ur z>zxr_r1=UE_0eJeOmrX7?GjKQ6Cvztj{&$FSHHCjHrN17P%a0nNN=sbMCh8@>Kv>= z=;X#s+9Vf~TN@ZIn6r_Wi0XfE#CSb$uQ+Lu{riFf|62uOHU!XUn_IW^m<(INvU;r^ z=g@dnRAunlejB)$@M=m@EFfP(zl=T*CA3=r)_uxeuJ9s z2KD~yj~40Ys>Hi8d;go3Ig|e>bGkM&-7YJ~rTU6hr9oM7tcvIejtQjCPM!*_37@go zUx~N?%@DT7t!M`w`*W9-$bbSoohkv+t$Jk%!s4rWR_cDt0jI0WMgF#ex-DZlp{F(q zTbV*V|HOG?p2x8Xs9UK8sIW0-;{##Wr%#5$y`H(yn{V{>Q|`KnDi%`jA)xI^_cZ~w z8m9wpET)c}D3e50i(g~$Cv11;z8Km2zX+2+jF+CmQj4W*xo9;>VllzxY0@Q`zC8HErLKg6@Et#L5dYr1~Hf~wjI3mN0%5a(D>Q< znQ%ZN`2O8=)Ge2KIAYV%)+vQ}R=wo=SJvEVWDZeDnJ2WZr5}O?$q=|o)Let4~D*Cud@ zp4Bve=H?(UtiOxzSP?sd`P*6jg<#aCw7X$53$}3V^M4Sm#?8iY#j3G4{fR@P!v%{= zo&1eZ@ImZ)4*MaKnDfPgCID*f2r0M&qjEfju5j!?GtZPxle7XB$=_KU+hPNOoj2?%d+e?7MP&rA>fGKlv1I{BXzrvGncn zO#OfS-6_?Sg!tH}i&WAo6*5~$D%B{ZPs%ElboneF%4L_6B)QbOkaF2VnoC+YQQ3~W zqRcg2v|-p>&t|jx&VJ|n`~Chqj>qFT-na95J)h6l^R)^rX+rUw^1e`)oC>aGKlnl) zWSVPq>-NxAzS0%#K#GYee@XL3gD|<=Hv2mCuD=FC{zA`E1g<}MVmTP( zR2{04aOUcQ1C-@c`cRXOEhKw4QU;abms>l(uFf~R`!?#O7Mx^3;}<}9wKdasA=WXpzD9KH;i)FG$otd6G0 z{q<;+BzW~FIZ|=2kM1=~gFjx^zjlYF-kg)3%yM+l$F_o};v#P7IIb7z&)V+LIEopZ z=$ue~#S+qe{aMGW5@zid7ICuiHL$sy!*nP;FmI3Hye`Oq|IT%Edt}pnbr(lIe~*`2 zlsv=lWApv#6|-2MaLVFmR!h94bAz)9`@SUeoV3dB!{_lUKB_Seh8lTn$;1BPgC%A7 zy$vNjY>TDWVzd)3=p%>nqH|}`zbDhz0LPAHj>iDCGhcp(E9<1Ro3wY}iqNs9NU=Zg zSHsUR8a`c`x!#~ul?F6e6qaq~{@h`9ZxeXTtc!I~A6y*Ofxl$Fl`m_NExZ14G32vt zDD-8?X2$&aa0j@}=uPQ@<$>P&!)5SLZ@VO8ohMS?!NYOIGxeeH{ z*>y(G%M0;Zl)(DH?Z+4yH|n;!u$0GB%@kck%HUaZb+7&@B>vR#;}R~v#6``dk7+yj z@+U)GU$sHrG@TLEwz&}f2RD9#`2~D40l~o|fp@*^wKt%xii{$tKG%uwmCcUBm*dt;VCsXTL_3=mg)+ zgTrs*LznpMQH-3cqp3O3yclrKwj}&`ghyBFWTSWGJxkQPyVAWQO#K2zlzL9JIR@ji2(29`#_C%W#hZoIufH_Bxf5#`pWNEszmh z!Q85fkkka3YZt%#0^M&UUd-m*@;glH8Ki3yi>tg|tA+57EI;52as0y}u2a9HNzb~> z!768RNL?<>#JIp^h>vp`Z98fvFjIG*svgGfgDnZMjuXoFs^57cDrM2Xi`+-C@5M2U zqQk#0!GnSFlsXsGr>HhRWSd{;(fP14(_|Lo|lH*I(7-T-_G!`~1(*p6}FBKd<&BtIAQqSbj3FixDKB|tBFbn$61wvGL$$$VvH1K|Vz zywpg&i7{VOfEz%)*k~K_nJ#o5rBu(;vIM@ieDT!~?&)g{A-X-Z2JFsPEBdL9;Mozh zaByff)c6zLqyL?;tIe&M#7l|bR&*xngA5;D-U1?ZhguQ~Jk__O?-R3VE&8RMJoC1{ zr&8{|yVYelSjc>}b6+=8ee`5-WC<}@FLLNoykMmnCQ@8Q_8-9Ez2i^lr6#$h9)v01 z!4;ZK9T&r-KKi6=63H0(csuKM!w06x70njBS=}5F6vSHU;S8Ct248F26JG9N(a^_n|RJ6Yk7Wr>Bi7{WSOTJG1-9l3^T!CrJuNdCSI4*nJGg9M> zhuBg1!S}Vhmw*M(a-~*@=tlkim~bA0u}QS_7=B|V{*K7Vw-n95;O>Z6L3Y4OZuc-T zg&?GmZDP~)t_`?R_RA?}>hOuLSu6S`#@;T~^!SEQ)Z6A$oL+e<{;nylkAAvi#nz!k zugmG;Z}s}TYNA^+>cthf*v=08_iISV=X=VK@^@>3>y^vY9c@KS^TawWy`Rj}pZft8 zNGiN(i%Y|H0n*HDG|AncbFH?E36a>@q{f3A{F%0M_{S$MFR~2@UK@drm4tSde|L`j zou#V)T~t|ff(6bFq)8zqr;+%XuK7!u3w%Z{#)ff`SGoG*%!NlRA=Ae@`?1+duVM7# zAvL3yy-aKTvQ9OLA7RD`0I<) zLQK`yolH;?gL%{ySxA`r3Hbq>3Z;cGeVq8duU05VamqiOflw7@n)eymcxKEHig>Nii=F%!xph*Jn)m7`5OUF)=}!c(a2!nZRjj;oD^Qv>gHHyy{1)Ci2> z;sim9Ok{dPj7hrQT;=Rg$=1`^{NL^kyG4*S`rgp^PjmuAq zO{nR)|KSgAmH2K9`=Ywo8v5PBhqi;|4`pRK8>_A0fBR|aj-4X%Lba9ZF(#8~(nzPG@0+T9VfvQ?_L;dyDGgE(6i}&d?M1ieSa8 z!s8@ewXLNBqsyq)U&Ql?Gog+BR?n3k`mOy5DN@VjvuapBHK)hSmO^c~RRz2Tc-|E4 zQtmv!*;+#}>oRcWP94&hRHBTPmy49`KMB~(DrarAt&3*89AarNR-&zE-5#EPb!4SB zks#E#-mKDB-8H=N=4p+9?WmQum(mBjxrs}FVepbaQlisIE!hR59!^UI5{}_IeD892 z7QzJ9$3oldQ@2A6)7Y-Uwa+kOu@PsYH$<^7y4J4DQy&{b>k35atsOSuY_6SO#Cae5 z`9Y$NXxjtOZ2^XJ;Q_<3gDNA(OAjm1gEr_t-T+AQm9KOaO>dJ?c3eDesE@H!hkhoE zkwphk-xyVLJdzZ^bn(*lEHUCP*(*|Db;2D?;e(9cnI{4 zh5UO*G@hHr{DW*e?O(tfAXNW5&{x75PcOh2c2skI9-2h$)2AffkY4UvwaND9-iFF! z`df28DuW`M1oSzx9_MqIoY&wY;HK#6@9bUJ6PN^mSb<)sbCo>^{ImwW$p{MCG8||A z1`{}*hM&f9;KU0ns;iAeL9o*0Mi``}P2s7*&C8 zo5KL!E9o;_7GotdAHlv~oCN)K*IggHKZb|e9}YBblt4jy$C#(XR{YG^CPPeiL$+Gy zkoKl3XTvSf zMzP+V%{TC8naESDO4nvHFBM5~?UDQQndhj9Edu#S*9Tznm6f;fPnHVR?*lqyl)#bZ zDj%ri5FBX|r*+GLyzizfYCVlBQQaE;g7j~?!JX0@O5_Y5!SCoW6E?FX%UTrNU<+Z~ z^AEGzDueR<=PA7A!l?{=-}?`R)Mu-hmu<;aE<=syX!* zDjjB3`%F&yV&$kmsPrY?3Kwh_ie}m8aj(PM@dePsx|1*y zp088Df3`>GTl6JH1H|3;eBh(ZHs0U-=IwW=glguG#OCOCy-+14HYHim{8f9?9e!V^ zqNd37h>LzPhl$bh@)=sj=#tSJIH-4U~lxV&%D{F?G zhm^j$BVXC)M(9-wQ7h4Le+uQc^$t6x8ZJiK^BY;47)LIoM%{t7_6zRM4h|clwQ=4K z^ssLbgfXI;sc48S`()Y-2zr_X(T)E&wVq0EvhBktV3a)s6N z$LcIzjEw+iLM}_F(#||iu2*$lpZFUg&~wz~Yr%}6;U)n|+@##D&4T&SL59OzlOY&Pu&Jn!k^|hkBp|?z)B${0B`2N3S3! z$(HwlE+|FfuAp6jLiejlmWF2fh*R3YTUSz~3#~=J!@0FpSq={s^*fRZ@!=r>*`p%i zX&|cO5PUB#aWmKNAsUIp$v1SVNNuGx1ehSQCa0w)jBzwKL$tgT4r_Jet?b8EFeZuT zKZ{~4_5A#FZ#{BgSV%48Hq_xe(z#x1A6Agm9eR;zvBdt4{#8(yC8=ni0yXFT7B>Z5 zviZH=Y|hzER_=u*D9^$ga5JBNnXPhP_psjsB74w@$Y!GZ-6wxb=?{P^10Ig zl%B#0%qH_GpX@<>fCQ(3>%3l1p$M~uCUSeYc@&HAZu-vT=uBz%KE1>KvD)hg*Xi9v zwGs{%Khy4@^4ky0tU&K}Gewn@_&5HIk#m8r)G#A3K{O5`x-44#WBY%6>qOlVv{7$N zkb?V`Yh3w1VJz!nF3n`)e)ZN?rwM5949v_Nmww8_O@zgQX6azIT~ajOP4#oD40o{8 zW+&xIixkEYY50){u5^_07sb7SgmJi<$+VSjw3Ll4Fel{&Msv4`9UXw}pJDIRA3OE6 zHO}1W>&df+LJ@t zq*=)gTv<7c7Rt&;r+f~`XK`mg9-`gCoY6V~l^}T&4rBpA0mlheNs@czuvK(%b#gnt zDU>|<`-L&K;Xw3#hHe!QRM^DLmah5V#R%n2%q!C+!lIXzg@#BF3^m9z`^kY;ofuQt zW2;UinXn@Eo{OB2ZwMittOy(fPjZ|<(w|qDtqZv5tNAubkh{pYHJ_kMIOI}9wAJN| zN~OWu7+|XSf!u1+X_9wzv|%bOW`DI{%cS-B2aBRtCX8g$ObL+H~EVp`|@a#>~X!NenkdB*>;y9U9RA4tI8|+O0*xZUXhkp<+AUw}# zpeqL4@OUV8wgefhF;ld%oV8CiuHr}FPuV7kyc~`^jKJj~%__HK+iWrfMZ=ewiEZfL z_TM6Igk=WKbPuszKj5Q1SiJ>AA5G}}YB(3e&9nWL*hZh_pQLn-aJTh~YQSv?$3IOQ zp|BCFo^SISMau(PGUOTl*e{qiWk1E6TZGC7XHAA+^;2~aMH>3mUT`!fgZb3CMg7Xn z!N5wJ9LJ{WBOL+)#m#=A-z{nzSE4l>HsNVV?xV-!8HA+Wfs(*d^_kZMeP+AhTLaa^ zUy4h#?jY&T#s?3n&O15sQK7ao@)k#94{^|4V)RGu`{Kobr(yC5{}JMm`r;h^CP_Y(B*2UrHNb1@Og>g!*$Kb88elFy#{ieTSp zgBo8#@m^;XTPCIa*HTHhJAI8M*d`7KzNC&W*R(CDoR6HKP(1%{z(zo3pr$!oBDQzU zrJt6CcFLYV=9yewt-IaJyDg|n-cA>B`4~7`wR>vxYzy;WI5oCZ%;WD}#p|wOwIpcm za|h&{US45$ON#DLYd-DXex9qKMY@lI`8kuoRK`ef1+LMIxeqyyxVK^OXA!qd9nlgf z_o>2m=5+S1w2t7ug=04V!b7mkgfrJL88bY_Xuw z(JI-Otu%H@9?SR z6`J69hKB!4b9g=VyTCfJMSX(84#)SylenIrH}S(1b|u)Cy&0BaCNNNUf!;@z59s1qFYEpQQYmw=3y6Ms2SmO+jG6yxU? zl6}a(4hEfJRtpf%5J?d`pL1dDag+Cf-FV-3aBkpUUy;(e6v&lD|e|*1r-uvt9UpOB;+n=LS4?qffl+PeMjj9f_8rH0i3|UMYU9V zAabPqkLRGQwBrYwneo^;fh?imH6zW@_*X5yV-^=W!S7^;yGSu(^P~nAdoeIgR`Y~qHkFLE5E`a0ZWTl8 z!=&)UZGIt_Zhm+dzUS)`DUpUm^3dB|NLy8=kuYNxu+Ua{bOvb{nF>|bo^Qk^+4(PG z^gQV%+{{_3TzK%oc|qNgy&uulGFNoUx59pRR6&|1R2;!^0jC$7Awy#HK%+MK-@WQ2 zT?Jkgv=(p#V~fTS-=CM_s~?W}x@zR?uVC{K+K^%k_ou@M zT{31a_g1mmx$n-@o1`mEs^Ph6SJnQ&pwo`svtB;1Q;NB{ zL;I!@Dm|*KQ;$u3b*56;aikzi-U3fQH9mwvE!j{nT0YAk|E5Lx{G&m+dR9xhn}8hn zhfF<}6w~qO4&~5~<8k;-OEyZ;+XMPfM>ptimYL#e6{u`I;z5k*!*$U9TsEZYS4AYp zh|&XaD_pfk3A%fJT z-Va2pVh`BEIDPa_tA#!K(}odxf?pA^Sky-$SyiGOZ|;>vBGJ0G^-WdaUEf;KbnRGc zb0u-*hOK>Zv5E^sM;d-b_I*fW%*ZddEGGz!o`m+I23rKF(Z_GHFWSC z)0+3YHrPt~`%b#GdsV|GV7v$Yey~wdu#r2C9BKfIsu^k~xuO5L+?0oN~-KYZd)7wgk~OkANQDeMYZY7aWDi!0x9nA3d#C68BAV(6egYygkhB;fFrHkjTu>2SD# zN@2g|nG~-cve;Z7qzVq9T``ZtZ`rioQEUZ~C>UY)wF8`LlRPW6gx z(N@-M%8$wIlDP=8`Z}ToZX1?EA+IN(^Ip9x_w$Xc6d!VwKw4UgBryOufW+z<-aX~B zV2>d^$vrspTyNHXzWu@W^v|}@as|PPjfucr>u{RfpNuz-6F4V=p9=Y4;Ab{d+B5M& zC&&q_F&Q!Zv59YDZKor_>%j4)SLBaK{U!@gCvT^l&4h!hMv z)!#D#>;I7h z_=BR(@(m-T867rIqOL{t-dm0Fz$8%)IBCrMw?EhTFN`3lGnQ_;8yA}9%YqTR_xs$F zjUT%RpQE!p2zBv&PL`^_`?!U)poWhBK<5(u^mwJy2SFCAW~RA*#&=~N|C?04L|-N4 zeEG?9&CFz7;IAsiv|WHc>2FE&+q9ojl6^gEHj*p~n*6`U zL#XhPKjm6q>EQQJBQ`f2RzDvgDVnMru7@pFy}vVgO3GQvhz!BXsN4bKAjYp=s7|KV zgahf+Ylye{2%!>x5QO;8LpL*h&aEZS7Q2KYGaI)&nrvcke`I|?%# z%jkbUUX5+t&wGgOR$?Z6CdHTAQYa@_H1}4-;3cX{1v=XuoOJ6bIghr`E6@7t=J=WA z^M7n$82(C8)>PV{#1Po0%YSz{CK5p5ZzpTxgp@EGUkJ4{89199`LavBf*-&aEz4c+;43!_Mt>+`Sp56rsv_}vs;}z!a(qK=ih;CU z6ZiqodX!y={vslbne0oY4@iyt+jM95SSUr&I*))$?1StY#&+Fh|4p2Wew8EAa_@Sz zHh3-Hndh8DjS4CpgM#%v&|B~NsW+y@tzdXVi6E~Zevo}Wc)?`ENJfs59GBAMe+$Sw(uN!vSaOY{Lgf)fIA&cyop^Ev+s6pK@>K~1pEy*EJ%(3$k*g$+@ z4A11zik@2FUcDw#UNk`J%+WSHS3SB5Xc4dV$6E4y>|=|#+tD}`KkaudSJzKgV>j~k zg`#mJxNI!bE$-qGC*6eAzUslP4E4@HTF_Q8c23vK_c|LLxp2ea=-&ZSPPZEV_wY*c z>|C6b`ZwN)SH7jGoRr(H-u3s0+#&_~HrvE9jcW-PxzLaQGJ^!}sI}nyv^50)x(Q=j zE-!>WO@1PlzU5j@embEyB;cTuz3N=v6hu30u+Z3pN|a^=Pv}G4Hh~%NQOG0o4=1%L zFfwCUy_Ea`8P1J*hMU&m?{zIGy#!vS-MKet2^;Ryrwg=+%7e^C5%l4aKmWEwo=fcC#*^F}zWLrVJANKqEB;3o>D}8nlp+a^J2xzk_*Sjnv(d31B_yB9 zF{<|&ZbD!<+1XC=E9ma<;9eO5aU2fAci~s_l(RZ+;+M!j`lG6zTQ#t3lQdyB7;S)G z;3vfLlL@bO!n}mueoI2k4DxoZ~|rAR5a$utOF(q-;B$ zA0t@NlA$FIouS@Ec8ylWt?ZAAwdiJ*^c z|El~}t-lietW&u(l)3+044?~MNwg?#P>eLnu1LZb3&W@z@P*4p zod%F-Y<~zp=6EH~!E0U`(9&GRd?9|8Pq}34xHeWqjXLQqccvB$*~+ukYp&uac4=Q? z8n~bI0ax^eovX)Et^z{fbnI3hzQ=je9+T;;YPW!Bty(F9Z7RKb1p2}&oUfn2a6v_| z;_4@jw7WgmbZ)e+Xo5GoQTS4M{e6*`1*kVliPDtjkmjL z%^5+OG1{u~V?rPD$5||y>M{RZ=19g;&av)#ZF2vYe0Am3gtd6>!*K@(!v-+MACCFP zxI<-@8tW8_oX*&MkytQNNfhr*pS(DvR2=`n?TY`qO~x(H_yYM@$X@Z46ZxxRt8E8E zI8eR+e^^U_uez=k&jO5ninvk9+M!N*<`3S7@#(`6KP*B(zvfiJZS#mN%o~5*KY+Vb z>34uH5Xj|GQMgN%>TK*$rf(CEnvxaltjkbsP8PsbM8@U&K(e{-02r|4wWaJw!F_lf zDu69U$rnA!Gz2C8hU#yPp>1sG{z6B!gl3dkf-Tx$n}WyS@uVR5D zn&2{$KZ6~{j0uj~WcwtPtvH;nc`^3(KK-6TeN7C$3zT%9$D3sznSwLnWnIGZj=lQb zvWrE^Hlh$Vb}4NlI%)bOVRDXXjR#3Ih87`X~qz*&GM6b8RAlQmB4m)Jx}<)tYn;bSHlRUTqvVYLd|n9Ss9bZ|=}r zBNKx+yZeCeY#cWcL}ACF*wrwP1yBv?*6D)>ZyFq$EFIui*tw|xMd z2YjL(pN94h3lE=-?Y0{#e~A##CJtUX3YetJV^SEyQ=aOb1m^PCCg(o#TtjCEh}ey| z%>iccYCoc{&ivs%T)q3Y&hM&Z8+)IA_wU`eW#3w8+E$CWjPL1iSA#?@wTG(&(_6b{xZZ9zw#dN1w~z0??%M;%*~Sh9pDt1`Pa#--JF%B^{srp7%tg zzk+Yk&QKmUkAC-LNRL%_ZLHfux3oRD+HkhzU8>&1>}V$eKFHjHKHHwcJgC3y^i6ib zgC}N%oi+q*+^>DOKeq32ICc3Q&ncPY`+Q2u(?%`p^_iVtGw!%9s601q1fc~8Md_RG z=+~ALKK+hA0CSWaCE-(tkn%~%(RMt>FJcPG9JSvYquG|8mkbS8ClY^)n&IZ|;xv(R z`&9nPgz@1nQ3w1)Bo&mdyXpfN_`sU2O^VBAzz{wF=ecj`(=~?$ZXJ4XNM} z&-PvV!uc(vX>XCd62cxsg6RLul+KisqZD)CIM0a})t6v4Db%leMEy|GkmYV?;5`(a z*vcO(dQ6JsDmQ2hWVcm)&}tUGKM1*-(jF=!7X{z)vXIe+luJjTp2QY7J%k`+B}w0! zZQnJl&l$$zjbjrgNX0yL@>A!%&YF}sRufF^K@>&jHV;_5@B>ze+tjhT%W8kz=@S-R z`S(t5(RdsgqEbBQdNKvF5-fVr8gohQK2$C*&8lMmDN+t^hPoMI5Ly{7EG10 ztF}yqWGYt%+)-XO>PQ3TAnDf;df|=Hj=oL_#XD#h{vhT!rbPVnx#n!En{e%Qb4B;B zy;yw6WcRw?qHXI$OhcD=*y&xsF@f_Zf%Y*!9%;Q_L8LxeYRkQ#BV51xklx1OLwlNhquhrG8>r76iC_g zM23GoRfEcN>!+X5W~_tqlmAEPOe@=^4$WqZjjnMmw08Bh`fig;Iu^l|0Vp>fsU7MsvBtVm8ho{ELUfRq_g7!)9s}+)z?t0a_ zYNo&8FUjFca0?Vy_*Hie5*!HZu|h%{!5IguDAvd+uX4U3dB zMa_CXzKOS;n2a%WPim#`GTmCWJ{nk{_w7Dyz}@)*`;}%aV&~E7R9A`lSX6A+5Bvhk zzAtDFshYVQ-+3t7kSI1ps2xrdm)U z_2|0~w6)WI?Nv*A5o-Hp{u23OWyW>Dz>mdN_WM!wf)x?;9QhLTfeCRzDJB-it3EvBXsF)<>v5y`J1fR}ivvrR`RNu|!$n0YGY#8n`U+ zfPRJxaV21iz#?n#3}gFZKm*8)t*2 zU~g_rhOz9yTTpRO88W1x0PZkCU*by!7uD$58$_^i5%UWx|EL^)*Z6z>ia|*65oI(64 zBq8k>90M4Qih=IMB41<+m%`(Jk|PDz4>l;r|Lga?k4kCGKU9g9+f=r@!f^{JLV7<{ zQf?Fba8y){t`B;J3Dw=^+$D_tKBe192Ok_W)6ci-&}H$^P(*#pM;6$ZgFz6g$)&{- z=TzCB;?+9sF8J3Yrj(&PponZVxq+X_T&CMZo11oUGL!<9BgRAYeiR)nz0gDY{d-Cd zAp@o#gzxz6_25-2xkbOMfhP3k7Ujzekd7M5EtrROZUgB5Lg&Q9;cR>kCnia=>26>uoJEU{oas z41RsobeC04q+T*lHE!z8@oB}6@T97Eu`AO|(|!{_AxYF$s}H;;EY$SNMF9=XKRnIl zAKQ?Y3i}5_e%noY)&KN~4JuI3@CXPeunq+OGf>4&N>PRGa4beiJ%repXiuI>+)kWA z#3BLO;{R}Yo8Y1_Lw`p!Xu5HC8rMbU6JE9x4-~}AgviR6E0xEryXeQ^{vuPEe~vcA zU2B1RT-AIzN6BG1pz@g?oom2fz|LNgrHUu+7V3yEhff<^87P(@s8bnH5$?%++kyYb zifyaETfk8zU)V;wf*aVyat0doC%ncV2Ccx2 zWNb26=k;q4{CU#8;{!gFIJ+q$O_Pm@n6kp}kK|TtsRSB6kYc{A9hsgkELAn0>%!Dy zr5CXH+jh~ra5G-qj{WC(3^<>%Djq!Y0o*X?4gC&o4;{dNl;(P0H4h3!W;q% z4agVwdxETfIX;tsq|CznZ}XJSgWhTjEhSM*%6vFv%F!PsS zKO)Rhdj@2);}7D-*CN1zwr@=r?o^Wi5jyy+ogzp@pD{0ID2e+KvxUL#dN{#_Sko~% zVDXZ`-Ax?I&e4^9jNLkE?b-oXN{mCbskXFr5;uE@Zp1k=5E8K(d)PQmgHkMXWHFq> z41?z~`MwajdY;HFVo3EZuUu^=jd>m`evYKl`$mADI)B}0ThQ8vfcZWr{_dNmwU4_` z(z|zgq95K(aAjff52(As;JV`Dxk^#KtTN)C(L7a8LHE*cz^sl0 ziD3tHoIdZ!95rjvFiuqO%(?K@aKoIzKF?E!Wik38lw1;a0jz!+vyo}rSD=ryUC6=K zb3<17Gaw&mM>Mv>Oq;Jj$MA_+d{ZQFd4Qj2`(%*o5G?8RTwRCcD5ivx#@emDduJL> zqEcf%zOE2ht3IXjuGHsjlcU}`o?%);=vkbJ&W8>VF~Q=6%1J!ifnr;@*c48m;yi{H z=^tJ_2nK&@kW21aks`c*>`~44fc_hMTT_b^Wz23ZS;#*%MEz|#<9|G7sNhgoB}9GN z%;X{M$CElAI88a%OE+^1_Y1=G(HFQUa7$B z*oDC=Q(2j6}_-6qp*J{w$jfg+BXm4 z8&AaG54bE(qfhB(N_^mkKVhmW!BaSXeAQaRppFyO-LKc1Yu>b|g#WvwBv7}B$5}Uo zEB!GtKJk)SpSmGBtqABQ1Ij}Vn!}7}+iieq?eCJW>JzO&bNHXLYtRNH4j;annfS-E zKx;iY+CXV4i-y;%BB+wc0+tY3TI@6ZjYpr}I{KRjDLERrs&IaF`&&O<8vT8MN?G8> zPSttz1oYAEo65<^s=s77_tzLIW-=xJnRb!<%`bynwsK{Ph9(KDR~|4T{+*&fA|;$Q zc=|R_LRy8fl)Hj;vAckdz44=>qgC|+Yq<^ZCYGR`~65M~gbU^St2w7xX?iQOfJ(qC@a3T#pD+)0Vm7G{f%B z5)bZvk>0(ZcHswpW$=QIqM`kmH$WD`)(~DB7Sog8C_^hhe`8iz6lN19akMRDCytcZmm&W|6Eyb$)*0>6+bpCn-BtA}B#Ka7EvZ?d1mIsG-_)(7No_cr1L`6gEiM7lGrA;9F&P2B^AoM`&c z6lWv0(k}3nV+GM}&pzqqYv;$l!(+1Jcj_^=oNvihQ8u0Qg|Q8|;@8o{3*5!L67QQG zEqd32XHBveDx&3cZTe5asv~?r&)tWgig`L(_tS@1$e90pEv`|y4D#{K#w3}cBY~Cs z!WE}>$MzlU&`%*j+-Jf06`-{|7}E`Q%yc+|x?wxWbarn9M{H0pj}^i1YiwNfGrU`U zm(NUKBO0Na(9_t7fS=4B)uLS>zaBfdQS)B9Fu^t2kmZBI7pPnHK6U!5suXBYw+gyy=lpO;($e*d3{jsvK-C**1VrK26nP8 zdRYKHGiF~1v;BSj7>Jc-ZR4C82+>~MWJ_5%x1Cm|E1Nso%Y3v>6XI)6-g?eq7jP8( zfo^gdn?5dRs{N61o!PE0EIm?ebe$339VMlRm#!Pf%mhTr&6PWU;Z?OUvp8>o>xd#h z@f9zN;bdr*m7UB~N(V87u{7Y{O2NGJ70Gx{Vz%aKEP%(OroC>5t1qvr(~EcMjq!uj zzXJ2&-2G5C(ZL}c^#0+%hcZ};fa|u(_~SJ=65Jy4_x@i-t^MQ}YxS^aMey!Q;^y+J z4S`9lOOv{@xXLh98BS6p*OBA7rZGTbF|19P?dLXpz zV#eb{gxtnirvx{wvE`87;>W8SMlXiy;=Ofg=$3R6WXx@F3g;EVp1Wy3k+=6erWan-?rMA5sD~jH_vtB#!ucy91_rCBm zy7)Brdm3?VyeeL|oA^styo$C1VYc8ittBGWWwafS*nnQ7>x#f#dRwFaYa$SC}C36riuvhnBv-aVqkexz(s z%|U!^Q+|*#URb^#im^o&pwn^VVB|5;rfbh28H+fa>z?*t@)JT4#~V4+@IxDjGm!^X zo%3#6N%5y6$l3$+!W@3N3u+}WEjEouqh374yH&^zlZz?)V@=Jwm0rfYXn`*HcJe3*-SL~b3v#`w>BK|i zt^XS&I8*L7u{8Q!isEh5)7#c^?(<|s6v9*IPcm;+eZLLJOryI`3&^bziVyv)Y!LMv zpC9NOf^9w?5uyvfKDkV9eIuB2j>(fva}QxG#24t$8|z&8C}b@Ly^R*!2+mU(%Ufjb z)o6gEp5v~y<9wS3g81yjHsnJdK+;LEsYn@x;*$LS}P*)Wx$OMJe9kKNs~#eGKg0Sb}f;lp3>Dm)2i> z@}nf?DX1xx8f?+od1lb zL@$orp{y6rB{M%5W=}dvvi|F*rHopqjb{Zv>3Yn1D8C}^#Gh%aRVTx_Uldjm1QE5u zg&2p~Y9ZWogCPq((4OHqt7cTjwJ6%Z36%6;2HI;`Qr*&Z&_P-Y_D>#+H%`~qzK|I| z+%y+u+u=fwMRee=I6Hhg;`nwN)QTSaO7@2hq1PrYT^4^ZQn~CigvPJQ9t~p!GO-?DzHM3 zH>vX>x>~EjS7ANqN6pLRoWFuncnUk*W7WmLrOK5yNkX!%eEXF4%$9LuwX60()x6&w zQ$2~(;fB$BupX&N6_j@s5jzJkM{}uhW!-Bh*ek)*Ya~7~h^gIu0^a6uiO>;&uFlZ4 zKy7!@-Q44NBVSOT*AIXdh5v>?YI#cK^KdS@&+7{Q;@sIwl#bS_rTGgc@Q#6l(V!@hrLGRXQx6Mv zCk>raDjB1oDd%Yh%Z1*Jds-Xw)ans8O8+oYI~a4aW6QY3jm2~IGWp;-Ec$Tla1G2^ z-9?Z`<1J}x`t#ZQ9TK7OGFeOjKQOFAsH3)$HGvb#eikBBu6L++dX5X6u&AZ#IKb9{T~VFS)JV+Reyo~qRXffL}tMz(In z5a6qh)Lg;=oTonJ_$+HW&ScjQ{WBPVl^8P7)|05VPhiRDaC;A*j-9 zo{YL5;64r^Jx<%%*&f^Hyg#q^>-Bv9dkOyPD1vnwu}`&6PV4dAt=T#m zQBU`x{XJu3vx~$VWs#npN#YcDj?T%G@Jhrd)jg#%PjCox5`Sv%oFnZGFTN2s;SiJA zUU5AfQ^8qo+bIiJPu@(!-^;tJxy%!#qeV(WG!A`CCNQ%~5F z$hLE7oU2Jyn|oV)eNJ;0H~)7Y_rAbUwO8}~Z#qX1lhR77>Jx9}@q zIa+Q}kC!KbkV`xLQNAsJPv_HG#9*l^xe{Mv4E3wwvATs%pk{=S6n zORwUa4X*5SB(f4$pO7r7Hu$W&a^4`n-dD4W=QHm6>C3V4NS%vSrG$AFmBf-aG-b;u zBSp2aY|&H!igZa3a&5|VDrY;@rTXhWLF6ZBlHXJ&I#XnnZFT$DQ~=fVkiDWSRw8ZW z_{fJ4Q=*^u_bhx1mb2r(K1PRwDfVG1V&IOmsZ}{EhHoAI0%ZO|}sg zgQR8~7L0y8$$0_koduic0bJ6yLjl52`I%RWET%t`xG zl9+{I?n$hP#_vS#QvH6+jd>@y4WfT5Yge$zTjiFMPI}TUOPGP9eykZX0m+U`?-l>o zN81w%ow*P`VL4R9sd|k*I{+O+=yc-9QVv#TP>s39@<&^Peoxhf&1OJ^TG+l1 zkMPhx5pSy|B|4X@wU?+qHx(pt#|EJ_C4TD@rXPV8$*Kd!U!k{scsq#CXSAaJ1mSOP z_k0C>ZIYVgTwjUK!wPLGlJ%xN}H?F^V<5Gc&6H& z17F*zq>TPr;m7=F4?XU|+tT@QuaOy23*gZrjfu+W5VXlwWk6IXk08AUP^4vzI2toq z&PO!;Vi#QFOZ4^1B>aN(uE#Lq8m^`3U>p2TQnVBsefx0KdeKLpW|jdj?;C9wE^Z?J z045LYAlfTksOrIB{n!YRYN8gEwJ#g(jkcY#ni095Dv$6SP6*2H}^;X+#JZ!$(SkZj|JRJaY02X|Xf;m6Z| zi>RyT)u~yYdH(nTUR{FYXU~E7S3uHuAad);9<3HE-ZTHJ`d1!p5ywf&x>7Cc6UV|~ zEo0PqAtm?=0HcNfQoD6xf}Zg{kaQ_&2x1{ijaskVW*(9)THm`n-%a57Sp9eV%%eN3 zUV@9wZ~8lBr0ajH3BJ{<1S2)j+L?3h!N*L|X`>;=?EuJ2o|^sFsgOur{ueV%$4ph! zZn{I+1PYkHCLH+Ms=-FP;U>`qfny=ME8Pe`LKT~MZ=E0pD4!2z4q|r>iTvQ$AnVw@ zH6X{Sh+2m}tEc$c9h`zZ*0D}eH>Y4CT~tcg2P}DDB8{eZl%mPXyToT z%sj%SLT>hDm4xGbZIS-FTNJ<#t` zVyN_pg{YReFqLbB7*&5xv-66o5TCi>3EP$=-^|X_ZhefpC=854h?Q2PSLivm=_a&w zbAF-y55Ge7aJ}0?-tgiX3jHAG<+kcqT<_MkC2lk?hgSTUrCK+a&u-|_JSX|6^gF{w z3$FZ1Y-J#}PMb)x0m_c$w*9V1hdALQWj(TelFYXlrbWh?Y3hej44jPKkumtz?Ze#} z)c7FDek^+Ck}c^cF6V1&D~Gv zU-$&_c}Dl9>u@{w@HR31p3zUzFdl^JbuHvij*QP{Gg$$?C8J7W^9KWFHPW6Q`IRDm zXm>w_zuBqLZrKkQ2c`A1%K{f8=^f(NrH5x^e-8z}cUyp(rABntPHZwK0O^C?*UgJW zkp$nSdNGUOApF)VtqI`Qk|x=nznmz(S%|S(*NK|Muax1&byV2zp|q9CW1={pAHKMY z6HdFOHy*6|;ePRE8 zTXXHD5WxSVO~mq$^|Jv>P4MprlXKt?&N-f8DjYkG#^B&*F#N*vwWj_tY)#SfM zt(M^BQrc+gHXnv240rp164vPnTR6i}?y{e*NEMS&bAWFFr_p3cZwW z$?yfg-(q~Q)rGUavQun-CvgtX0ar-bqMDTiyxc&BB#R$WQkN|s=w>IE|5l5Wun#|mNPbiaW{qkTyW<6wFlNjOy4QNg*nTNe%lla*2;Qr zlkVYhG|mh&9@#QeT?EwTAxhqr60|gR5sCR+hT zSTh)sh3|+3UgL`tL-O7yZmw7+J5245NjW3nclg#5{t7Vd+Q2XHgj$E<&wppY$PTiG zjIImAf~+Zwrz(0I{&sGk<^${>@cXG`Q4KL{qE^MmGcrG5PEVTKj@Rshzz;K47nb40 zniu7qQq%padZyec*R;y<&Q3*01^pgk3NA=*E_$=9mP#J)F0!+{pIJqn#RW12mD!lL>>> zN^`!u|2Q|ucpv=mrI^g=M}DOsa`Qpc6xC%l_<5)Bu&!AfXJ)IS*?7W_4d zX*8T8{izhJ#H^5ff0rY~kGVzX*ejYqaZdmBg{0TqhS57hOri2N@bo2U95)3Km9BSO z?eP^g(3VpEGH45dT&REI@TQKpURcA&vahO@xJLTLl(XXa4c5pgzu>-e9eDT;?ZbF0 zFvf`zWhh&S%4-g*cHu?wRQmR+Hnb`pPHHw9_l2B*CX|FjQ?2aJM!Z<+xp|!RJb!Rg zq6c1V^$O}a5mwr8N3C1e5-eE15rthrGavZFPak&#CNTr*X|!^F zxydIu?117(0sV$R-I8lABERxM^)s@Rj7j|V$=5$H0MG5YbOZ(M`omH;GX@)P)T%-^ zs3QgC2oEM~wEcl?|5lK>@erAx39TKs<=D^31h97rfNxY>|Jk5RUu zg|hG9FiJAN8zqb+J)FevU;42xz?4o2*w&=DnXd7Y>ZqRq50oQ5__>e1qEtKla))-% zr{phR^r3~_1!uT2s#dq==0D;zt#JN*P)xYbv=N6ZLm^VZ=g7Oj<8w6jdN>Yoa~NhD zb}PK9-}Rh$QD5*5(z~fC?|TXGrG8OVoxMkpy|%>tUK+a|$3B_eie9Ijzx0qZYZwL1 zK|FmjzH0s<3b7ks%)%&9<*?y%jzo!CKJYev)nOh6I&vI!VkT4E28H8*zd-8rs!4jY z5el`xkiRG`_09LCe9?pC!Vi)+;fiWPoL{hw}6l{+@$PfJl{r&;S|Wds`DzXQ-@fmKXe55 zVPxv4g29l0TSJAwY~hfi8A&!jBPI?N@)vU6@yL!t^6!@%oBffj=Ow5(%0#Xbn&bD< z`htiD!57~cy6P6{c5&o${L1>9C14>swx&Y4TJ|O0&1WcxQ^+yr>6v&%m``-&#E4#g z2Ff^wivl|03(sFBxSzO)<~*{aelTLqs%qW#MNx~7WOp* zK$5>?Gu?n=G4p#c|CXu$2S-IzKLbDbML>6r_(mf%>4cgv!LARtD&1Y_j!2Jj-8@s+ z9+F){?dLzom&&~Eua*_}Z+QmUF;(8EM_#`f5NJ;EF7aqKRW~IC2xgql67_!vhJm<0 z-3aXK4^{wsk$`Wws?x|CCA9g5gQ^IKFTb>oNYa*d?BSl7{Ri=u6?4-N0LnKPUI7Qd=`Z#z&OTJv#^gKvnEZ z37z;NR`}y@0;{D*c`@(Zyxvuyq`N$PS~Ty)Y$4sBbBHP3r}5@kWw8bGE|c&cA#11o znw^F<&;Y#gC%v*5bnSOqmz9_TKfA_H1F|*YYLHmsxQGxci#xEOLyZB^Wkk~uNuJ#9v}Z-vG8n#Q~8LIeG%o_4~|cdOM}KGXj8O|tuBKz_-2$q zRs3kA^eD%w!RrW8+3proSKwdV+>-cK%gH^?WA z=dA&cz`_lh`Z(D>v>q@p2<`R49UMVD0(}7~U8r5gX@$ELa}71q>kkB{)Nlp-|DHT! z$_9ysjN5QRiXl=y7>mb6(DtEghMGa_C;TKzfDykHee+W147xVwtR}b%vY%uMn6C)C zhQ{9I$nbRq91o`Ei0v#!Y=V(yF8~Cr(U>bj3Q5_lnQKhP!P!6j(&g?N42Aeba|Ggz zTC)HIn_~+IrS~+1adhpYr2y~=I1H)mm~%Kt3 zD+b+ZaXVMI3V0l!4{-zVc7@AtGQQ@$gyNLhm9Pci{WqAtJLy9VhqfCjd3pZo*_ja& zXi0mtj4vM5hx*Ji9m(h5u*BoI6h1UY&C`y7>ZHcy)-5+yvr{*%A2%HH!1RbWnal$` zP*IVbF+A_RW(%I*qb67k_^+O7xUK6Nw5%MBo|xoMH`{m3?V}}pBTXk@`o8>H1f=T& zKaJtBCA-_848_<5#;PEzfNi;&4rLM{>ue%4XUbYwqu?6j{uHysLGwl}0{nmZy;NLD6Bo}$jyE`R>@Qe3ebIA^939m@at0G_oHJdHUxN( zT!AHW<%gwyjSFNM8m<@}MMYEDQ)>F8<3(V~3OY>2ufSY_GDjACPlkN094i0r_s?mps0_^wSjUm?I~ z_+%EoZHTTqG)eyV+fYsyqyBkhT>@#YjCQ%%)DGem6@ceCfwh1@XlLa%!X%E2@e|<& zlrnJlAiKfppGS<0?*k{1U;dE2>np~KN9ZY2*NArk+Iu57PeT0!f2FC2R9>bcjWd}9 zuntVIWRBz&XvmoWrvVk;G1=gU7VPJ4hHP%%VW9sKJO#sT^h@0#-gICbtrSD@Zyaug zZ0_1tzVaf7#@7<0IYCmt8SI)D%KHDSTxImX{Brq~(ULL(*PoIA#!G36ydlap%`RJu zJ`M6gN5UH$yt1g9y9q;GF5yOsc&ecx2=y{9R)sA?Lm5P$t0ZKTlO(aPQsHIsE1=}{ zIL;AbJ-$bNNC`DzF#`lH&EQj*2G28F*?ek0#=PPnoqyRr%xt<_c3gcNtRid}7zaN%%J3+qtD#tP54{FH&+bX9aI2 z*$O+`{nA!-n%6p&)6yRSxIq#80*wqqD2bWWF4|WHe$lR_8tyHlw_Du9&*jG`?D2NK z3Qx{~E+(fu2y-8p$BQQCccaU={ux|ql!D&Y>H3*!JdIzFITM=sOLfglzABTXc8vnN z?eV|<@hy4Sjbof?c3pfGy2jCfr49p6y4cD%d|02vskY(?LxAXZdIe+_3rJ#M{T9?5 z_)tl|I4qTDKj5mH?b!Z(v&VG?)JHvaNIY8 z&)qPwnZ(u`brsQ|HJz*Hf7w9(E#OQA9CrjlswGR!V)fUFpIH-f<||Z8Emg?+w!nY1 z1z1RWt5&7Tdhzl>#_Ayof)Slq3p(OLLb{f7WA}A=lrP%PjfCny)xnvQ#M) z_7cQm`qpXA7%d-e*+XAKLfnG=Da8Ju5I}BEF2X7F&i~Nc_zE!0HCw7V}VZPh);g z(uorEdpA{PMe8MXQ&E#V!QV9}L9>lbs%N1)SF){|!nkZZYBbW!s8;DHqLl};>P=!r zFv??FsF9cD2+_HA-%uzbsAz6CTMUg65bUaI><)et?h&pPduS$}Ek%8FnZ&a#7D5wT z*(L`6&me>y)#pckLz#Mn9)QtJZvP4%Jf-Dt4(_8Rx_b^2&q?Qtg)a0PO9GPwfebhO z{zLrrntgH$ks?K#c^}8Qbu>k&Bct9IP(6G#D90m`hsG?^sp2roK04y;RtNMx&WTd_ zCqudk)s9BU?@p7Q$KsoC;PFv@StEksgh2LF5?> zLG_tUX2l5{@+mupVT@J|IXYZ-X!xPh3ouaD-uCA4Nm zO7}8;4`L2_s)?3WOs_py>DbxLdB{UDCI{w8-mSwWI;xD`bA!RD%R5uVN!%a{nCJQy zEK_XnQeCfQ?Ck4Yl6Y0)Q{wmk){hwp(0kQ}^dAuOObJR6tq5O`I1h*b!bLvnRs_c= zDr|z$tTX+$ns9W51+Sr-^)RJNd*3R_TvMF&PqVCEbW#fpZ}*G~-glXRu69_Y~h>S_7LWgZ}R0 z9F-j4#RzM*0R?v`cWlDf!`u64sqt4~vQ79PbC+;v6UN!rB*lb}KS=G3*0vl&ClziS zY#*HrtTURzN47eL+ioA%*%bdAzGZ$w@v;f|5iKO#u<@)%2M&rFq2+R~a#5GU*B9;V z#(B38)7gOM|5?JFIC@ffv(mEohpF%-n|j77r8{Fy6JgYe$#uYnorn+P0T_AWwgT-6%fVGrruR<{_91eT#C69e#>A(s8pD&dXj(Sm%9?~Kv& zy@G;3kuZ3LN;F9IKqyzX{czM5j04%^`38w&Y)-x}(*_Ep&QuajRjXxziw*e*!Z7{A z^Sv-HTBjDR@tB9=QqVqiuOFIN8@|IXGAxp)m6}T zl2g>&9BwET97we{~yc2rLu5zkjuDt7iAUs2U4tM~@|6mJo}lpxGwE#w(Q z%;fAL#;x>C;;K6O8&b5|Avv}N(P#H^^fljbktdPRQw2P7(qP2KW$)W?zWWIWXtk=i z8x8(f_U5#c8KX`t1Tozc+ObYoalxD0on7*E196al74!tYT^J)t8H|1|Sh|65r- zGGXh4gL--HEJg7q^Op!YeLR?D?lJo*I}AJ|nqAwOth$A8730D2ez{dGV!~UAVR@3fXQSc&yHNaZ+if3waC-wlKPr((!wE0Y{bh#15;NV-V;aS3&Y zbz1X~bx*)-uXAiWs56W4WwC^7FCgW^V!I=UJ+!)ao4ce(DtW z`6teU8mpS5 ztIvDuFeOG$I1i|QQadfG{A{ioDK?toqaVzk#yB)LDVmo>aXxt(ZKpTA~32~Kp3^;CzpQ5rlNSx<2-8nw{2@pqa-M!iCAsnq9M&#@( znQ!D&j~MQ8ZYS=C0W(Goei-gZLPZ z^z!WAH}==rQ$HoCP#5@{;eSW}6IV6+BJUY}fS4G|Sq*EoVLo^{E*CAHH6?`ovxhcLaF1%8l zB6$+eI_5|{N~|{k)K#1!*nJ|9C!_#&S{J>xaYgDgy~K75t>Q9pcLnrv|8G;(_cN>B z_qi-qR8i7pJLMMZInjGk4Va5v4#Kw!cU@%diT}SQ*YFr+6e&)^b2vTQNMVp_=0ugc zKj^pvniqcUJu=N8eXE*#bJ*#ico-GxrLTxXCdQS1O``^{{#DBuxhpjfwLT7&_S2?U zP4kP;o8?Ye{E9P?Ld>e#_UCBT%fhy!)QVd3!GJn&5#=N0sBU;z0L;Jggu~kme{7*A z=y!@{nDyYVBz42ta*aEia+-nU-oylXrfXB@(_y)rQ+JrKvW8p*a#im-RzI#WplxD@ zt;69vF$0PIwrg?6f2+QTN)VuRFCpkR?lpc`{B8vC3#6JW?E`R~qW;8_)NMqj3y{fW z{PWCnhfFKYCj)HRm{P-~lJC9qS@xCOYHVx4jR%>5dL}F70X(1F&OvM?B|!bNpC;>! zP^Tb-TjgQ-`+rX}QtZ=`&aZ zb$kG@(8JaT^@PVR`q;wx!E#&kkGH!?Go|uwTQ&4h5fXwX>#Vo3&AA0sl?P9Lc4}2|h%hQ9)@-ZidmC~eVj6hXwAJRvd$<>1uy_d zC5xAe{HjA%isjJ11DWHQd&YCz_U;?@Tl>jC(3q1Y+|NM3P=U@hlCqXqlKQpIfYVg! z3Hi$tKxKxKxU|h5e=6vKuLiyzJzlq9e3RGApjE=fZ1&nuE)Z$tCZP;1i$CO?DJ=e1 z%3XBpBj4URlhql`8O(AOy2w|ZQ7=~>Q|z91KmM!skOzCNZ5eSi=x;1%Fl00SY3hmO zNK3la*X^NArjM+13EX=rev6qa5K?q1QnrsFgF#r%>X_8rDEaSF{$e-9d$sW+>lXUn z7cKNC=Qv65f7vLKLb@hza<@tv*A!#;DRsnfT9@k#oc|V$7dda zTShU-YWb2c^O#)fFNV5M#GFL>XP5nfIQasO#iXeA2jLnwFHRKK9Ih(T8k&C#s0d=) z^tkL@SC3l-S1<7_)Sxc#CjIs*ZhFjbavVM+T53Zi=gPK*qDqpNrm-UsC-ov3Kf>T( zP_GT~=1f6EZTy9bX-9bWo=9h~?}70lP3UuuF1&FlzVw=WE9mb1_bs@7D1bl=N?D_P zFJD!yKFLE5)p_hQz*SJ$y6|#YSbvBsb?WZu{R*R0vJ19;Bu~Bh*ST<5Hw%aWBieQk z?HD|jLt+mAJ1FJHYi%urY+96+s41dU2E^rJS=Te?C%QMbMt_{J{rxwdh&8m$g zYL(}c0lsJ66P34IR($WEV9Se{_qa>#7<0Z`MaCIu@lY?_K)i7Z>62vzNV58JPAuwFMaY?;qJWiR z;jr>TN!l>JSnXLtW99D2q8lr3@`w#aT*j<}@72285Q8D4$T-ob2~~@_;h(4XqKm6D zM(yGho02dCuF)cjAg~FX^*eqry`M0O8V%Ms{>vLZ#@`1h{={3t#D96LLF`rPZ1qZL zpSR~G*5{m^FtL_lEUKFd`2kab3A6F|_)u;K%k6is;-wPdRzK*q5~Ki_Wby=UFPC^B zkq0}}o_ozSj-V`QH>1=+iCfUcO_IwA8?$R1wM; zMV~#awSDogMncLIF-g0#cnCX>y65|4U($fTvu&y)`9HPldcWdg)LTgrUe-w+qkE&a z$W+5#DXN=Z()t$e_TyyM{mmthE)LiD8}8+Jr37UV`6ESeXwFgfYzCp0U8-H?+OIxP z68yMkh{;uD|4~Gs4k`x~t9q8@siQ!K>I&Hp+2SXj*OLQJ@eA9R3S;gNN33F%2eF3l zS*}{Y&5PCd`vQ{;eoy>@%b;-%&yx*Z$kiZ~M5oJovI~^|RLx?*$)HC#yb{(qwnGwG z6}&yALuwu;N(dL!o*JNJA;Ph$obTRc^jDJ)xugR-yG(&?Nf$!d{Sy9}4(^&=Su%AJ z=bsyWFnz(%SNLls+@4)0$&XWyDA-)}Z21smn6_#QINFu7L8v_-CO*y_Q4|-RZzC3j zT^u7I`N@Qh-vOlbkX)GDW=`uNN!hQHn~`A>K~_AE3y^BbU*HC#oOK7h<;13tbD7z;uH~XA^9&bY zM^i-?s%5mFn(LZZUw|_0tJ(Nq94yyg=Ff`X;n(gk1b=LQkr;TcTJ2c8lkJq7KM%gf ziiPX;$eEu@)0Zk*ecI9=4p%60&TmGqs!xg~pXJ5W(u~4ov$ie{OW~oy;4IPJp1BDd z$F+0MzBij3L-6>5iYn26IkqxeO1n#}`f_oh23PJXVTyW*MlffX+R;ghCfzUeF)hKD_6q-2(ewP`%CSldNK4-9}YT^9!)i_fxSsimFTkQs7&3E z@V3=_nH5E@8b8)?|!VTCl~69p!{w98S=6dn#53yOR&aWxkOaM6#lw%^j*@ zmirNyuvx*76bZ>D|9K5Ldf z*d}xAP3l0dNYHkdvOTGBi`?A-Hj9R|?kElWa=eLB7bo?)O(!8twJHWF6780zja&ML zglC>fa$G$V`TvW=0!z$YW_)>;Dd+qA{(|vqHBxAPV`daG#3DilUtG9L!5;XKqeL{J z2-ZyS+Nh<9ixpnpuBIdJz8;ED#}&3{nH*j5u~PENRh6Ey6V5vi7#?X2MN~My4CPnt zRI5KrtWjcwWaq~IfLUpqh&Xjk0=4>PRI+?c?8$}`^{eIX$)g2#jN2H0IwjZVSX2BE ziZ-@$eTcExOC>)c)&kL`m{I;V%(Ev3wmS&rs+;>6u3U1>uc*Eft%16Gr&HEIH`?$i z+!7O5M;;S@Vh`K8Ekq=>MDyTj|qG>}=abI8j3+xp*jv)&JG1?7D}>iTK5 zt-!pD^SM~xKh;XRo!$C-A&jG?{86xOwQiQ*7^Yv@YL8dh2~K~41O%)zuVJ!7aizZI zAaxf?Pkr2!&ODW-`X)=eZ%v!H&(l`?+&oItAIi8t%W=(=tHbrDh?<^uOC=m%j2|PK zm*{O>V-Cy>)=D=qBi2 zD`u^2IG!)-ys=psno`@@9`q^;)>+WH?d@D7Var_#8d7u=-M&pe1NuxVb_AADDN% zO{34RIbVYyXmai$Y(H`vM=CQGTtEs8_x;3QUoni2Z9rx`nC8z{e*Xkoss(Op|J3-L zQqCGr#Sr7zz!B;qO|VxR=doO!c_ z-3hk(uax){>8%b=N;LWho_=*h z3`CjavxB5pRzg5OVG^}Qu|tzT1?ep0-D8ER?ftwppadj)ec<7rjFcL4JyyEgpaee@_%KV?rDF-@)W z;HC)}82{ih>xA455!?POX{V(QhYyJsB*v1v0>_ox&isfPd5AQpWRQk< z7bAj~tIAHL%Wl=69dOdY;IMv-l^&XzSWgf~)E02L>evbV5O#r|0k@@_vmlU{q;WT5 z%N~LmYTpVp$jTpO{X@wy*>q(rZCON?KR8vAA{s2l*~YyT*pMH>Sd zq3NWdmxGP!WonJoXGw~$v8~TsVk#=M#x`?2(xR@57IwUA5E}%(c4EXRo)qcxfr+|O z_Zm9{Xj%f#W(K7PR@+owygKcOGCDB;Hj1ccdr>K!`}Mtk*O=Q;cOz@|;X7a9eX1v< zLt123nC$12>cJZ#0t^lrBDa@Bw4gfON2#xiv<4K@!F3|+JhiViYQ>Il;6i`VNWJQF zft~@hD}q@bySmDj2gY^okj?daw2X z=GM+?(HV+vJ;#p}!9skz-44f)*;A@@<^RmEJCR!!TRQ2=b23!EFf);DS7trWHdkqz zepDK;rCTcE2Ss1l@;^V_R@$8-Bh1JO>NUn4mIonJ51|-1;MZw=kcX_|4~ZsST_wXa z9WQ!oF3Q~oj{3vd83@yDt7d%k=s$(Uk#64#@R3Co)OVUz09iDf!jDYY0VKG6v4*Ck zoF7m#eHr~nPeN9g4h;HA7a@1N$e(96Q!SyKI~kR-k4J-gKLUnGr2@u<#3+-b zT=rnut;AZd@K$@#mk|H=sl7)o0qI(eiET(B-Ni1S2{ z!dM_vgmClF@*8Lbg5%pnn_F8PEt_h88zM$k2FC(#mi4mJQI|}15dLqj(C4=|gRkxJ zfX8^bbghl*#t>Ex=PP;{`Cw-mJ|S;|lyQAMoKJb6790thwKB+bJ)EGGqStZlJM*Z^ zs7)Nq?QvzcI_YC-yEJ-kuenF0vuQ* zlgLtX|NkK56BrA!I~N|^6$HBS({T!fC*grS;AcU-w7wYZvOlO0^aX)gGI%iiE;2vi z=L_;3z~6Nr_$IR6YM;#LOOl!?*rcN=4ML7q1-~+rnHtNi%Hj+;7P8GNWmd75rIV_YT?GoP0s|eEtv3}qe7j` z^V1(dyl_( zB3yR8mlISokJ@xLoMjaEjw{k7CCe5P?u~#*%(tGA@i~&(^I(Tp`-;wVTpU~}Tyzm7 zCUMCwGmfhJ&o|icxi`m@+SjKX7|W1ppTxCknefeNM#Tm6Kv5d;I)de7im=iZ?BEm4 z?&-#A2xww$b4pBVzwh9ypsxIz0v&id*|fn4ngcc;S(VQ;OxIp{+ehG=ccVNlV>g-(qqL>u%*oRKp=j7faV`~=EB-elGJoV zc0oGbdOI;fi!dE;WnK-vU(QhnC!N~D>@1J=RM*eANrJoYDD$jDb1wm|3hpfW^KMoG zf8~e}s3G10L4)__uT#@HR-qS1mHdLcsrU}CQl<}9UE&lU2DL4%qi348RMY?uN}dqXILZxs zY0DEb?d~V_y)0X|VYFe~^0b_z5ch_UC)a(QxI!*PBeNvy2&T++nho$1@nd?xsF&1;-4o`*3C%+u-oQDy;7;a5e9@ z$nyR(`1;lq)7`0x`8KrEJe)fg)hJur-mkhjk)_6#*SIJs)hyXGCb~MH@WFJvMMORCzxhjRS99c?e`Kn1zj~{AzM+7rhh+B`rJ_BQ7PJDi`^b zPQ!5hQngu_>e@w#J{dD`WP{mhJTC-;M?cOIlGzrU6+X;)t(%AGoFjEK(vipLETi1O zH>_)YRoFuhiKQJwF!%Z%=1Mx!^9Z<*{aO3k+GMfCMaheT8zc_sFL5M~n}w?8__oOO?phkTx-r7P~INiA@r^LREXfish0B(eEhu6>JOh_f|Ypoji0-8++@KSa6gSsNGo6>=y5VD^+_Hw*OdyV5`a0$~mwsX+{m;mJSeQ@(V z)|U}w-cnJ=CEHUTcS-yR%J3}Q3bmJi?6ZmEQ{L0krg(||SNwCdWRM;S)rLzB9W4?# zC(yx-X$5Du&WWMs%>tU%b*BZLuK$9ET8ecV*_THR8kZNoHgOU`=#EPzS0;{+7nEX; zTmXCoAy*wbg1r2k3bB!G}q1B1thPcY1>0`)fj*4bLHc zxO0CQriLYO=+#g>|Ahb)O^b%<@$UvO(V;`0ZkXZ6e5p~ezBnrGHEZ7HT%yG9I0w#= zuHx0~a;uTVe@jecH-u6z6k2CT#<4!Ii2WgHhZ?!x_`!lg4HC3`?R)+x&1b&&@o(G; zej?@GxNn>S-~3xZ>9%WRzgnFj3(L90dj9un-!7i!`{2;ZE2T$iyZSX=xziNlG|96I zdC4L8h)TDXUaclpSuPw3^Sp}NH>%nCd|8lwsTIieJ_9wd~GkSH42%9(>OSPbZnz==QsSgb||xb7JC0}4>T#XoT$Wq zRXGDT`v*QqCS^S^JbDw0xt8iYR-q*>xqxnTyC6M4PIaVhxnoj}p0(_W{7TxoQoqor z!RP(9a}GCZ+A~Izb(du;pof|YqK{^d^Cz{_Wv_zMDIDbFXc%*sb#14{Flmq@9$V6u zF5d&%Z3Lyjk^Z@R?FR^^Fv^)Gi*&Q|C(coC$u|*Ygx>b#5x5Uwvs4pNQN{^!=Qp)% zziqbFTbHeY5IpQ2%Abl+)Owu|6u|6M6G?07=A%?wv}VmG^J&Wow@M+gOMBwhJBl;t zwHP^=$#Ub_I|?~-B?%}-pAz)e_&U=>sJ-@~jP{QoLCEi*rjew!=z z^Vz|_3BOf_qKM89*`Mxp5OSG&&Y^T>1ZSyD^6dC^!h&VZ<`GG&hvIh_ru5=8w>^&! z{0tU_1M;171O={xXzeuwJ(xOG3TF@c8GDZ1il2q9+Ufk6@ z)5EhJS@E-$wq9zpNHkIQDV$o6?ATA<(Nd>!A&tCY&zm7`exxb-C;IBG3g@lnW4^(9 zlLhmpWBx7n_A4-{z66FUjUy6@a0<#Y*hl@ln-w-=7<*p$Zob^cTozdVDNBP}4g{El z4X%nM>1d3;a&AW3a=-(kq?4+j5-mxON%|Xw&qLIO1>{BP%ei`Ai9N&&l0j^uI$$gO z7tZd#k((^OaYz@IWJYvkUM;gC95{9IMk*(5ep-daEc0Ml>PB^{(KPF22qduyfV% z5yv$C6qc|!9d=j$gm$2&Fk+ZhSh)6XRUlo3iDjW&tx^l>Btx* zU$43Kb2K--`QkS5mvKw+5Sc+)CF^`$4GA0Wt|k)yTM z4|JXLQ$ba48h0h4b{`6og{@WvC44WDRH}A8S|;-OF-Z6O8^hI|d=dDa!!lLIt^ACB zOgON=66&7n{vl&NBIr!@Vd>ZxczV3_42Wjd07}AK=>3ftNDtt?1twUmF@;xs!FF7& z=zBz`Z8x=C8Ych3jwVW0a%j(Cy=HB44=qWKbqWLCyiYIAe*8PY9+ zL0*B$gzVuLJ_(J5c&LC^mi!l$Dlu=0MBF>^djZkaq>+C~WuRUz@qXgZD%ka{&nq6Z zhSWV=?b)yN)rUW@?@eyo?uXh`#h;yiD;pJ>SzF`w@YF?kn_CChBSS8F@$eMZZ+CTe zEThr%&~!|{$exC06B8-(3=MJdpwi<|9{9Ks^yf9 zRwPAQcXI2%CKX8%l1f=8sob?n!fd-pa;g>`oXQ9}#nOq&Hsp{Th8%O)95Oa+GqdA$ z?RR~?kKcdSv{MXAX69kuAu{JCpIdBI34i_glL8N4o|;>(3Q0# z5pFR{lOyW9E0Ik-xum1hOn}lL(N+Ac0JA{H1E&HU{-`rfOxTiT7~dV2Q*`isn( zg*@+ARxyA#0!FAx{DVCyZTz9b2HHa$a!0r{N<8Uhvl%=iwWjcEdIsKEKFT{LOEpfj z{C8c0uu5Djb0!`(ris$bvT}2tg57f*iy4OxY?D*3=P~Dz$qIW_KAuFu8L$RiuL5sa zUv!~+)6Cu<)sj0Py`Au@ANv5;)OmR#?C8`4XRmBtSCG>edd1O7q?OLo23PCe>sjj| z;JoX?ss4-mhY-2%?wJ-81qUsBWUQ=y_T!GvgsbZLaw;KMwxD&@C0xhlFlhC&LS4RT z!|n5=qELzdI_UA5cFQmPzu^z$NqtxeM}HlH)lM9<*&vV?k#88s&BE7cM zt%HbmTh$xqy}>l_aO_SDX76^XBvTD7@>(Od-O!}3R1enTYJb7>nAAeMfq{Aorw&R( z*;`EfZj@-vr$0<UJosoZ{J7 z{~^wIwG(flQ;P%Z{o0kJt%D{t63z1PC&){hQp1p3nf)|1A^a1O{^MJirDD<54a)nl z7je*Kp4}`$Lu*0?o>b?%M%rYh9()?)0O?PO7Ag)p7Tgrl?Xr%1!vZ7Xy}Zx$+=3uL zNfY;^KI++b131uypzoIj(QJ>ie!6v=FRTy`6?F1nqj;X?hl}{jx-4fT)-C*)4Zmc6 z2csqS_qw7RZGrGP7BT@iQe-|)#zva$#d8Gv}vk8 zP=?CXw{sldwg)@0){VI_LJ}*UEXQQ9j-=harTAL?-+}PCL6e@KBlUc;&9z+_z>kRd zi1(h39YvlbiUA!$d4Z774^mp4T{88#=0n4bij6e`wbK=b`-^Pm&o&yes>D*_w^MCs z8~{_>vsD{RiYqQT{z6@Xbp2B0zDw0YR4bG(Fy#1>261GF!F+%k(5=qjnm$I|$Zo+8 zYy@IiWC4x1n%7^aG^VHa{2;z11?u?Ah07$d+ykemgHpbt-k*#BdY}1W0QZ z+{GIehYH%q)~bP3V;Oa_l{Mt&N3PPG!3TkU3n+mf6p8p^Hh*y89LsT`{0kD}bgm6d zQ%oQmWiAt_+s~a*S8OTSGdQVIfA^6Neq|+kdDapY{rPMADa1vZJ96|@KYszmBp!xwW*d`C&33|hoMigO2G zfvm@jRbI6$!}0>D=k>L$p#^&o@~OPo8SLMcHg=V24ft

  1. <)B~Nz2>UIOOO>P~S@yQs_rw2k_vnM&^@RQJE4IysIPs_QNb0yP(A(pn?q7o^ zt|i;s{LIDHo3@(KZOZI5d47kxSE)+f`X4*_^O_c#nOX`;xaGisqi6%=)M0`uCs zmIb@ezFQQMptM=R`j7T?x5~qw(T^JS=R{m|*gF`mu_@5P0AnSzWq0I&r2%o`G}PcW z_ik0O%2e0S8Pw(^J9T~3fL52K@laFdr5@tXKcPBU(O7w}m>N5}r`OXEZ=o8ecwT2J z{2#-xgX6Y2T8#XKrx&(spN9DTGhJb%=Qp8mWme3I!|yDGH}n2)!(Jvi;Akm8e@tmt zEN=ZY2Sl@QVR#JYnEyB@S>8NlW2i7B+{}^dc`t(k{$RT>CRg3=sC?J7AiUA|yjgz1 zFu5fHYQprMJ_y{tW{(9&SmB3Xy%wLj2!>3SY^A?+!laZoLciKq)HnZN@Fcb^4n-_8 z69w~8?}7ky*PK!3S@dD`3HJIBM&r$0O33MJ<;3xI?4UGrJuucn)~PPjCt)Unw~J?k z!WT@~*7cQotkm>0#Mj)<8w9k+iu`Fwu571Z|KCN(icz5apvRv$3?o)#jNit~LhP2{ zaQ|4MM{9GBK029+{|NIOQcWX3Y>EHdMF8J*ejVLHr3MGz6C=d&$FYRE@nA z`t-H`;LdR9G8%?3p@z=g)kNYwmqCLY!Ss5i_j&Y6f}EMJ@HZ)W7Ep?!>QxwGTTr@Miuk6vp8;7SD!)HDw@0OWvFd5D2HMq3hgt zoV_NZu=}VjwV3DHaPQYKFTiVAsjJjT$;|7$Cw*ilKj|^Z>9$~{U=g;xpWtY21J;ip zfN}eeMWQ8&nA=RGqp*{yEeh_Mqrq<-eTPY94S2pfP5t5gVYGtyymLM9Z6D8&@i2un zrE=;%26h>@Z0l5MDrqv49^R=r2e`y5d&2PxI-SJR*H?uV&dTVUd{qO@e9Z1L*ikI? zCxH2NZ5Ya6GdyENzLOUgOI!Bw64>xf&rMV9>-yUgCNT}thknkww<`bP5LcLD1EZ{8K@tyB4#aW0fS z;fI{_Mp_y$pZzomc=Lc!59pkErxI$$VnFO7Y<`;z<&+~I)`5bbae}egf?g?gX)^yA z{rEc7631In&N;XhKY)B6MweRb5kx1SQpdOC>Wf&LKe0v`sdq;d^mxhmDhMwB@|SNp zK~T|Y>lJJ;u*_0Rh;8zil58P9P66S;;`VLIKȍeQxO2kA6|6|&;G|9%6)h+`&F zl(5Qn*MyO2A{!(6HqCEdNtlRG@D&9CjS&52JwvhObp$UEPu>e0O)pF|b>+Ef#u7v?X`+fhGcywJlApTr61uB8RoE-TXk5NeMEJdBc zHY@3xZ+tr4b$WV_Qw_tf7UPG^?{oV74W#)?eGz(Hy(`F*;4-mKzTfKi*yr4Oy!loz zag^7QdjiFMO*BOBURc}5YH?OoutaJ|#pABblz60g;*zot=Y$G19^t$3LAZPst@md? zz9*uPrtLp44uWvb99{*VS*?9ZPucsn-Q-s?zF>wd3@MTjsvAk>Lci{heis}wpMqK5 zyL$&(lZvGJ2Q@{2K_tBOcjd|*+F=%DDN znDG?ssh6*zW-EggHl40LyEX<5&g)4$<~+K<(hX6W3JmzSlirZ{nN+XK`*W2iz-F2jTAX}!PP2@ zX>ONAnN21Q_#_%hJg3T^FH+5JU2o-(H-GDZxULpjeeC3vCFVu6DuDXANuKlFQ$GBt z=7lq7slOIdsB4cUy-|S(%?EwcK>#1{z)g~yB7z+ z0~@Yiq_=igFjfC4+*>N>y#{h)$7&P~j+2pPeIAl%{yvGu;O!dQWU>Ibo4}OZqp0%j z8kkSbR}iRR4bX=F{&9Hv=4X-QNy=F|_0Pm67*Uvwu$#usM`ax_l)D-a9=ea3jA&YD z%k@a)MDC>55|61VK<7r}!p3>)g_yW1F!VOvy`OseF+gdBA>$d^(hCe*LBN%=goy(o z$O8i3e#&xzyZ9gjJ3DbCjU}{2jJ&hg6S+xV6fr;ol}w#>y+Ue1SFm0A-JF7l!EZ=f z1FX05HBw$N4mXieiCpfzriDCg+RmM!#*2o;TqK6&Pk@3dH&3MU!C6nGk`&Fq@nWL% zj^_(*C>tS?JtPOek?;PK`G8?Xr`O!}7)7(>@f<>M6yq9dqU3{Uvdc4GF)fOzM%PI) z3NE4dH*Yf|grB9wUq8-@XDVtv)eUYBEMyvQ|yzlh$4VkV^)Sql)8sf{hDFVV0cOG~l zOY-#IHrg>SKDENC5}lBDP8g{zt-ReWjbyk9QNr;h#?P^4*Gz;T6yZ9GG0BvRd^blD zyyp(Zo!fGx>Em!WftY1qiJ=r1t(gW9=Lkib1;=0 z|45{;=}>*RZBs9Ek=ANb{J&tF`JA5;BJJ0u;#br&_%><8Q4Fd2#A>Qtv)d`^hcK*4 z<83uBXDDuT?K)Bva%iVdZNbYfFPb4?0u8j?wzvqCT2<{+N{rf1`7mN5F6N{La@H0x zj?My8U8vAeetehxQbY%SSyP#G*a?%GUR-G3;h@;VGG^l{K#y9<7e<+YMwQ$>yM*F8 z5dj02Y;dqF;}^?-7S}M^_>X3p>)o7Q{X|^lx94yWyR0G{K9ci0_h>RzOQ7~(MG<3r zK@JztSKc{m$SJWclF#anBdH~dVOA+in&3(z{wymyg?qV`+aDdCP|_?kU;XwZXYC{h zNbezow@Idnsf~6Ca`&(DqTKNR{i^@opk?v}F>z+HzY{WhjoAO8g~%N?B;?|&#tfD~ zyzI$T2o!wFgZlaLx=NAxOf1h+>>WwLs3NL{3 zF~AAceDsAtFJ)bip_b{Ka4PEL4a4DboHWx{D)YX+t;zxRT zK!vIFV?ZA3zhXs&_0*xUNDYGd7soctof-GR)RXE9UP+bAOYH=E`FahJv$+QejuXUP zq?t}utO`wFA$+WR@oZE&Bq=++Crc8_`OV~;R06^Avhce%6G*h54vG(+xpFM_FSk)S zPmx2{eZ4TB1?7Bkn?$})zL&T9PY#M(u%B_K8oQc%88Xz~>)({ZwfRAWR zG^xdRpO7~qc_w-r4K>-p{OmNZXVBUny%zt{CVs>{Yz8~X?g06nUpH8i!q`+@aDF&T z<|5C!p0)KZ{j^YTzEm2Q$W#SMsJ9q}heB$C_M|eY-o2@EkQR_HJ0tQNqF9!*Xm@DD zPxrb*vOvuV>z(VkGoCZro2u^3CSkA_j*}I{4XPYzIDxqN!I=q@Lw?z5RGoQC_2OF$ z!s{e%=s!yB!bb7$KQ~E92uLJycXAxYo~~0F`~bAMLRnAVtVpLNOoLm*;_oGIf%d`8 zj^0z$b>TlbEX}Slndr<*0cuY>h1eFutoRR)tb+*9s7C9gObL|OtOuKFgU|b!%MLh&~61{tlIYB*h zp8n-t4u9zi%L#1_Wx~BDF``&69Nf?j_*kk#8}85&A?mrICCY&#l1q-YKp*z}aP{%U zqSUIyn~YLw>8?pfnb8pRkeZ!XE8+XzRoo!99*rK;PQ2U_WLg}TbMCna`@U?8!+0AtZmgHNMHNMP5DP_YytF|wGah29%H>}g8I-<|lgQKkebEBK8 z9oheeK5&M?V`}3TlNha#W;Rx6e~7y$ZEjSo%kZQ~R;$pABlehCBuLUm$T%ICZBD(C zf2a7VFpK-b)^BZ+S<2F0>;{8v-2NNZz>1%kYGW6k-D9koOncF;zql>9LjJOGBwL=# zLbxToGtr*&ZC<*YF=$UY*+sfg{3gp5=h(@iOO=uxzAvc1@`525zZpI z_60qT;%cP#f_|av^PDyb3Ac1C($=?wa+OgvSCA}s;m9sW%`ez1VvCC9HCF+V-YzqB>PZHeC-WF0GHcLSnHAO9r&WHPel6=JvNW?xN{U5xpR zWclUNgo*AaCvq!MYD&V9I08Lg))6DFJCg=1%g%r`ARAwV_Fh6?i#lH)w*I~S^D>!3 zMthJhj0G;QCl>jNZKtaVGe7Sm>o#l@N9LZ}vxCvj@D}pLZ`nTYtJj<+%Xr)~frAUd zrWds)n6BI5pb+`DVF^W+KF*}%Hl^?^L=%yRRKDr9?}tx_Q$r<)*FV=Zk-wc@$>N+V zgM=R$oWP&^$W4ST!Sf5fV6@;NLqcNhl>}-^&GE0#qWU9}0n;LviF(C(G&X5Vf;@8? z3I#~-7yhlxs`Qx|g$_ygyIi54{mzV$-sqs36mt4x1}e3-usfIwFw#>wgAzqn&G3uE z(4y%deCh$GAld^5Z3@mh8p2e~cgkuLgjHwiuz?Qm6D1)NqE$UPX%`D@8^7f|;=W02awu>(jJtw^+zEPwI0zjzp>cYUU5i&VS>6 zzd#5)o+zg}UGNmArZM&&PZY1~DMj3#Z8kjkT71P&Mw<1I#zZmHpTAMOvhi+@ywrkK zJ8~OyAox(rfrCn8XB!FU6y1|x{tpnEZPbhSbrk-mX&(`SYh&lTV0`m9nGDtrrkWW-BgcCvp4B2`kDH zz-GO>;7aU%QZx%Qmxt#xX@lZ`vMG>$i^qE?>~6LL!x4pdO;?@JZTW3H@p18_8DT|p z#gpJsk%wqhA{)d2=wEa{IuI`_eF^?=1wX5bj4s1Y#N6_Ln*&4qrjGx83ddyWT`$bp zZAgc|ky);T6?f-C-S zABAnM*KIz{8H-qFyQVfco)Ina{b{}vW)qhLp?B>>W$hH@_v23>_K70Y=!fI6w;ULX z{kK%V<~gi3hkbn9LIg!yu>UFvlO!XKn$$zrAE0^#NYSM)xDF+e5_}#A77=2HOzIi` zQrh$p*d>Y^CC4$mh$SM0{l5?MWrS3An+_#{p+Vm|vUgpGfdKd4iPw0m0@}eXbPD^TkEA%wkqBKvM zp@C=Pe2COANyvJ|sjc_pR&suS$r^25l}zfP7D3YC8ku&0Y!K`p%7)uQ$nG$>SNqn2 z8(Qi?M#8(3}c)o!Ql9HIo{SNsVGJu1l{C|AQf>PH~4~@ZF&~TL|I=&8@W+l0F zkIR45z`9g?mZCgf0HL8#?wn%7_?3E@)+p+z`yeADoxj-#D9?IN&UhBiUs8u9pqOzB zRlBh>A2p@DEhi!ZdYwMAgA?jl6-9Jb^M_IUV2k&R2E64d^8CSzLP?qxAH^cbJEZ3HU#|GV8xYApIST@()`~yLSuhya3*gs0Fq+ed#r!G^R%C~)akO{_H+sH z?b+?BIMKOWxa0ML6?7--^+Zs$Y8|`8%6)48%bkZnxX-)x>qHw^VDY&nJa=MEVdKgy zzmIG0QYAvaWKvnH(r@*$d()m2lD{N!52c)+ACXFMDN=&zoN>I6&Jndm9A#kZ@3T*U zzg|z@$Sc=Se)pYJT!{A;q~|6v8NlH}8Dz(G#V8L)lWI>qpkJm7r$SWf%IbOtOBUyj z$k>5^Ra2hzDZQ)u4{%21{9QzfK5W8MU6}~dkz2zha&uo8amzFnMj0KZR}E6amA=&& zlb#>%`80)lEmXW|;?l0c(z)CWGjNZ8slEG4sZ|}S8VtR(={Ds6^y{plgz`tC3;lk| zxF2jF^7okXgU6Zi@j61l)GNm0)ohNvXocwROb>|Ttia(cpblx8_3-|fkm zTRwm3OPfgV8m^c{A#oRx+Me-3UrN1bm+z5n9B4>g~8#{rF?#QuHvNT5d{UgQ_}jO2)KbeQmy zdn8ACQ(ftC_0VOdrCd`$QzI%C)|cXkf?BQ%Bf1u`&Z06Enw>YVLsfFQ?S_;fLdJv{ zZSn`gKni|fhuA9eW!DtLIt(Z4>!ufnz<0>VqaI--sbvwL$rv4hS9Mf96pr3C&KH_)m|xaupnRPi{-EFp*W|q+7bcnl$Pr-bv9SA? zL~(tW>FGDgtB})O-vvyyNDb_68nx#fu1X=)j+QjMh=6{QFryld3$S-cj5op5!Vt+6 zYO9f6e5fSFx`s~iHCO|ctlC*yNi!wfNQm-pi7CxwfMf7}MU#3NX#9tj;Hrime;r}E z)@92?KinHQ?lh0PJ0V#j*O({6CQf#!n_)jCz)Gt$tkE%NL8FUO?Y%CazjiT+$5#`d zz~~5nFCNp^X_GqaqWIUbG`P1_+l4l6Z`CWaloscp8}!dTZ}65Wb&QFaD7*us`zA?ti~e~$a;{R*h=Dd#H-4;O zGjJK?eNXwB8{ZF`B^uSTT<0{M94GwReCl%#({aZ=TX3H*0KO3ww!r+s&2w(IM#!jlMjvt7H zS%|bU>FJ;-Pke8keCv&wtz3P5QqhnB4cUDqZ9n_-ns62?bP4!pPew6v@%-kNI3Gq> z{doLOCK5E|({<2OS#h=67S)zIUcNo%uiXVhieQ666cC80of{1+Csq@+2HOu@QS{7VGhfnqhB&Zcf7-;?@d(+}}yV!s|V*MRiahQdb9VLTrRG)@Lbx42>;8cY#19-lV z5$a-Lt^9o@DiN^x0QVK<{HX4-0Yz%VM8vU4MS>(<2QbUX-a_xU@Dno@VYl`X!+{n3 z&xQ8h%pwQXz)IeJEszp>X13SX^6h+;8Kis8<_-NGZ$LFl-}#3RZ1s$;I5k81aJ(#Vt(VXBe{1^#ej$ z;1S}q4(r(_81hn;j5W*tm2cc3R* zkPl_;@#vs)yKqrWdumXD2~H0fWkTiJV{R>ae|0c^h6K~lVSW>nkjt#NTUccrFcxv} zM`$;Nb2gnbwv0L?dW*nftI_OPnZv}YQFPqAN9(9G($yzCSEk&MonjJxXOJW8^JhEa zJ~!db7HAH@wFNJAsH^r7+ZCCp`Wvz9t`chqzP|E6oeUf_bObP4fqk!Tb0s42T3+EZ zq1vMip)?~}_Q$K6-@9+hFAaS1Q}VJ+jIq705BNP`bqJCsQO7Fi?Y2zQpC%1k-r0Y- zN>Ytb_1KsJ9bQbj*R$cFa`GZlQ4H_dl?S>i@gmiD;cKDj{`CiaSSQ3!daC$YYoTqU z=mQZ*jIhhW+09C-t}5&E?zd~;cw8Xi4?ms2j`;jy1SDwws{$~Yv=3;Qb}+H&0ifgzxww6IQ+eV`r&Q8T@;JmP!hc%3KA zFH9TP7rpw7q66ZHyKpdSIAp?GLaIHi{LHs$L0p6dH-7K}FW+jGzu3iFi6<#rspIXLF~$=JYpqsD(EhtEhOheUdg{kYXHZ}rFw-e{3cW`R0`f7f7Ux7 zQP#qjL2%J}@ihzF$z}ba)@&@Jj9R#i{*Dhg`j-@8>s;@uAJ2&Tb(X1B@GK*4Srx8d za)I)C z*Z-xTF+U}0sx~@>+DvpK0mCM}s+t$=%7}ij%=MLG&cR@}qB%jf*k>hvxh?8{ggCC` zp9c}leVB!{d&wT)SbY_Rec(&s^r&5>K_X{CVccWA^YG*VitaaZ;8G8}K8 zRs6^Lu03S(5lcbMRi;D&fvKBEy@(I9X`;#Js8ehh;c8EFe9w4o%fU5$Fer0<9#_;V z1Mi$%c$tRzayn&lU~PbRQC19?5dJmApK;wy(6nJPLGs4|lpuau97mtZE{EC6hl2){ zg*9r!tjPNg0FH~sFiQQ3u(~my#yw{uBPS!*wiZNfxi1DA!Vk|tk-+5Q?|k?217-?4 z#VRQBs>TalKK1Bm@INXCmvOq_f4D-=k9x^M!Bm|if~)$du-_?DlxKy{mR3|^1A)v_ z!@`}^pZvy!;3uMq%zY3Xq&eRcybI@hD`7X~%Y)6Aar375S=;V?yroi;S8;n;{}!Q7 zyGj(q6~88-*GS*K0bTaF0n_dQp}CGK^&uaz;@egr=Jy3+%F16A_nLN59wB`N9TOuG zn2>W8h}Pf!tD>Qp1gU*duPwN>cbwnKxXZxQ9!(M1>|T#&?26>kO;=2+bX0bEsV9(Y z(hBtkFCl3VL%KCLLGj_C$+*diMS#V&gH2F04}G;2t~aSZu+?M#4y* zWT*SNLTIVVJA(E{Nzg0O8!`FGfkhp#enhlt5cv>Hkdz*#jpwbI_UwHln>|I;Xn!f# z|6}Rb!qn%BfY&qR3DJATe(|Zi5=fCf<0)lW%x|#yyDeI2ZfuYKb&iJBV?~U zsLjh%Cx4e{=39JY-ZHq4>=T4shLe-%$J(Ds`7%e2*L;~fI|yT{w&XZw*?pq{ zl%R}m!Da8oRJuAjoU?({M2fC&=-a8tuG5 zlE0C!*qXvvU-nFPbHS>Gu}@^nA1y1Gi_OGvd~mvd87DA~GHN_W4Ma?PzKR>MJB_@< zE4cM~5C?0$mG6@AOL}}bkz-8-0R~Ny)OP9+>uo|<)jIU>?tFc*=?3{%XW3GASs|GP z-l7mTAIDKzDi-Iym6e`{qP-u6V=EOSXqhWp0xt`L*q>y?oO?ikM!t3iYp>u)w@Qic za|`W`tTzz9*CBloWs_`QX-jMuVYG)UzJxOm=s#EL{prx)|4tBxcCfa~WsP%UyJ~GF z!R2`I3b4PK>N>vj6u;8h_Gk<4u@eK~P>_b`^O#32R=T^)WXMByTz(^^z|tub4$^p? z9$c<9_G?gli=^HZE9B_*8#-OSjK1*wuW6u5EiQ(RC6lf?>KXw#?rz zn1wB3S~K8T_Hb{#^7_n+wjZ73b!lPOjvxy>qkGRR5#+SsN<_i5fA)@W>|C5wgY9cX zInPgb5l$~}@oO=gXS&Pmw~|WZh5^7)v5Skdnph-@UJdOXi+pD(7%!kS^s}zMV)jY?#bXcsICPm_kU$z}C1_Ry^%Q=@ei{r) z01*NTg}I1(o1uIcri>qDXo$lBN=Gki4C6#0QK+jQzanQuM{EqG=r4{(*~5QoN;-l> z%4{Gds01_z)+Ltpu!&QMQ6)2GZgt3?1cm#_WnGzz#Ea2~aHZ9N8h9-Rug>CRqULG< zDAGPVtNOr9&w+gsYOGXuvnV(7y8&pWuhiaBuLNR-nMkFHY}oNMvm2&`8?XAN(>E|0 z;WI$#%*FL{urZ(3^HP1^uTV9qR&Tlh-P=@umgxem{S|b=!Kw>o+yW$pt9HAU|70GJ z;jTF_6Y@^YSCHc&ubFYgQ=_Da$EToyI%Tm%JshBgU^Ocf7HDV4R!>zuRzf`ns#>MF zV4sFto*FNG`9!5R`PsNWwfrWu;0dj*WYTOgBi37?5tTYVY%*{(f-_hjd3uY==BpK& z{PG}l(wvi=n1*3i3@gS|1b_@~MH}U7n>GO#kS+XESIp@7&s1^|^5v18!1urBopIl9 zGE9@ig;*orR&>^=$d1x=VjSr)`TMbD=Wa!2EZ5JHQ8mVI@-ydolrzp~qDu#Q8y{i< z(Kez22VCMkS~YBga$q4Bvi26(VwX+hZo=5EN0O-2He360(F=j(Mtnrc+~t*7m~$_uPe4x;cBT_fLmR>0)>kNye6M7A8T|3c z!T$+R>OJd~7oN?t&_es;RO>-%oX4}QE1yVbJ{H=C*7ur}P)^oR92G+pLn`IsszWlL z+Ocx^*2B%=!>0uuS&|Ty!#3MM0>a`qrpHqayUO!zUXNb)K1P14{jjh2)hU`SDjD0e zU4Do+FMCmrsYSW60wy@o^1LAvG?{v}j;VAwk9#5O(4Vg)k?{w|38%5^+$_ZyB!p3c zcec=bot0xFa#l%~>od}H^9yw zc1DaaPc*is@Z7r!czANfT-T=ChYD%D9u|JSp_m-^kS(f*0b~tq`0`2Z>6UN;(`#1b zC|^S&w%!S!DESloyGpAkX&QHImfYv;X~^1VF0m*#?GCV~{Qa0kWf3QDo??cwl);=x zS0@(YWSdg?-H;{tkCLOuk$eOi@P@Rlj+qASy))nE9Hz7EfrU#rn{3w|mOSGTLM$eH z!upk1i&x(#nGHrm(>N(X-tF|S#5OPEK|mnsVDT&Q^&r~ZiLcn#G(HmXAkJX1 z-3w4_{&wfMWVOaG1r*R1$HM;C)Hn*ocfB1g0W#39#Sh~d*;h_NpJdWc%e2Zdvk^&p>QvS>RK+?Q2`W$^M zo6_8_#$eTax>bB~n>5yx|0M^HvT%ch5F}vShvmI%9CTx` z$EarbZElnGU1js*X8hlipG;_sWUfcthG)G=Ez~pIM*dduKBGC?EbaNj73_hS%q570qFVXEW1kahUFpqspIVy~em+OUtcZV(97N{po)nop|;N9|MBHp8rm7B`H_ zX&}A}`-s16K6d~!8nN!KO|dwIr3xxSiuU&tvm_A*#a}Ae1!cL`V2u+x+#3UdcyD}< zMRviHF7iU}2DF9p1;vxnMeen(AXNte(TYwP*y|*3rOr*`Tox+o`9W@GyhE;n7p1A` z)YWcpcC!wnD;2Pmlv6UxdL%6gsKj=qe9LcxX?*`CsJNR#tw@XK>>cDnVtL-N5upCE|Ap%{Z_Vl?~gma!kN{-;FjZV zO8IpByhpU9M))#VR-zr@#bDN;(8G=o7JUjR>S9H36X*=}Etthg8@k_SHly(_yC<}lmSaJZDX6cP>PM?r4&0oj^R75qu z)cJCFyAVzSM+{=P%m|D(_^;}{>IIMaCA*XSOARVX{nQjpi(oWjz+sZg_IbUOwpP=u z!_)Q>{>UJ;MZRKBv8&x;Mp)a5Rr2!Tbj12-sN}-oSh2xMkp{WT=OClN9*_7enwdA% zq@AGPR>|X)!_Oo`eCedQ943EQUjzcR2;JB$=vB3H?VrJ)*p0Tv_&bhoQ0cafh({~q zMa$+JN9__h^)_b=pdXdTvw=>7$j;PHHmM|q#$>@_d2hpc`i1Ynp+5iXXryK>bvMg5 zAN_{v_k{m9;&D}TD7Fpy#w^ghxU|gml*1cn*(6e?3=MtkCav!IF5YYk)~r6o9CT!w zlL}?C@aVz+#Q3FLOMGliK`)%t;OJ2s@Sb}DI}lZ7_#}^3`Z{J1cG|MC1Ib-3b$EGX-YMfX+8mV07uMR^JcsJ}4} zea(dRZEw4QLBP^DJbC}Mmb#5*;T!lF=Hk|1kE zK$b~`6s|x5og6bP%fZl`0@E5G3a><;b3={P@Hi&w<*^bu9&F#6rh| zMyL5h*@Z)NVQuG8>gOQrtrQu=M?qcyAqR5hc?iXAsbZ`6DK#-kvxh zQ?|IK=9uhjbWgk~>y-m8@QLkE_*fklL)x(4(&5^Mn~C!MVi~(8rw**wx?V@`j4LcgYy)p}H*6=Cg_P{9@^n8$d1kN-BYf2L4%Sl)aqsW7*K5^3Bxf0o_+5+@-MMimw{UF3Fe5Qkm-9fntkLUkE{PvQ zRhKVZv&Ho8kZj`~usx33*}GMGANE-n4sj}CKkZ{0=1y*&1C5%re{X^?MuBw>?_$@e zz#D-Rkxu%FJnbz5m5Wny?`Z!h1v>5IVhX; zIWsChLsNv*iZ?&MUpahwmQNHk=yZj}W^LRwQYLGM2`v)|Ub+VI&x6=7B`oyaol@+X zAuCp_o1`3^dMMcbd_z2HopggYk|S@>7oQ|JkQ|(+q7{^oYjxy^QL0KIc5Gtwd4@7Q zF+%$tsDw_P-Z1xPqLgU-yBW_ue_F3%&_v~kfOR*)$&ZFnUZ@4J!IPp+@MGS=k)|lp zCG-Q|PXXKg$Mv>8#ibYRq)<=u4P>=C0=wLthobI1ZYW+?n1;Bd0rXe|c416Q8cjP6 z1mG6h!Y_S^GTolXNcRl>WW&8+oh>2hI7$iorfyIa>wZdt$0XM@N=F?n_=}LbI@jx< zKN|qVaz-_=>^_#c;2J*DwGSky<$JU-c`KA}Y_uorS{$E2jcVPsSPLvty>a6l=x_*q zE)~|mcBI#`6q?lWY5k`mD^X&FW!*8P=nM&f*a5vROW>ktZJg zzOAZUk9WcqZ0;N=3m-NSon+?4!-`kLNzqZiDhHmUTiVBf^g--W()AAHO9EQ=UE_k+ z#2ZOz|2+vOea#u|2pW;un?=f-7z8G8|X5GO%WtyWP;7WHt_aL{yQCb{=NI8vcv z=NjR_MMnyzwr8M)a!HcTl}Lx%`4wrD8uo4>=RANmb)IKS#?SEait-9=TsWsZ9ar{W zKjj=Kaq-8sN9wkvPB7s%;xy_;ndklGi89TGc@A)c)*@f?IcQG%Jr*DtAI?&^b5rlK zX^i#hp8fmuhYLXxlA!cGh_Lwx-3LjrQlrg;i|k0zMc_KeUD8i_xd?br>USDZ`0@yW z+6u+16#e-7+KK+m`00J1b*Qd6OnT_Co=}ahEnCm$s|7i z>v$Pa5SiW|$1NaboT?J96n$ocXXhge)=x@~!C8E*$pYw@!yIo0er)~x-CHbOr^kq) zEZ&g3jf3Vp5j)G)(6sybcNti;1l5k!?!7yJ`$H*-R9LfA>wBBz5frcX0g9G9pUq9f z)V_(DOeN1-56C)|d)g}Ipw34v&tO}G5ByT`7gidrX1)l0lhnj z2x=-EFvfmd4gFaO-F==nXM>@ji?jg#H-*?VQm=}6A_tXKeb8KRMsL!urE5xZAf=SV zm|%qYFJu;BH4iN+roJYysATf%tt{6R5Ad)h1ywaNh- zz3EMfJenyvUl~~>zUjz|v5ez;&Wz3}EmGd!={0xS15bRFsOOa2pSen+4Ma@8k1##7 zg=@bL+H;Ez=L~r5@)nWc2Q-Z-^1s*Q##n&$VdBk9#FIUmm@Atw_m?Hp`tdRHuuC#@ zwvp&s>#n<`+2K@JbtZZ8vJzU?L|*hFBH#|e&4P3q=WMlU;=;fX%cvFB1;fwoYaD%M znJgL0I%HMH&(Xk9fM5T60r&@h*qA;CMwg~W3_n-2z7gxZLNT!SMM9jc!!34_-hyX_ zpe6MZKTG2`5@~t!H&Lk%0u~=p{Dc&RwZ)KZKEd^-a(B@R0QXIigpqkwBOf_~PjKx5 z+pO=xxjg4Cq)^=sBdV#EJaHkMf%l6Xt!`njz=_``Kb00)2d(PB16ucshK)*GHyDpX zueQohd(yVwqBQ2orTez1c0y(_PhV(qRVo`clnu8iS5h~q6yaHY6m_Fw$#IHGGc8RK z65v*c6UAEjZswc3uL}_T&2USCO1^3k5bO7f zs!V(1+A#r2()Frsa}h8h-euj=Ni}hQA#2;%&08uFJ|F}2|Jp2*#)J3j zu@^D-C;98(&ggwsOHby1I2&zl{{n3g$f$XGOreOc-Y4?6NQyXiVC5)%`lrLGp?CII z4zoK|;mVq&E!3B7$|u3g{sBG}vjE)f0+B=Cb_diFpdBQ&TrtV$J`o>5LGGGW8RsUXg5~)?K0l-&wvLc3n9S zt-G`S0pk3F|8Qd?JP|$27Fz@Z@&!zXQ|GfbB}8o2Q#WD!vSp2p`8;qbvp@ax4QYEd zXM`2x1Z{r6Y>R}_;pH1I_P=nBKAm*+}J|G$KPi_L9r#LyS3K=O9yA)Fz%6e z))K7LVA5r{XJkB6iYKaUVimZG2Z1s#k!)nl{kIZ35ex4|{;X_tv2XUjdLoPEDV-EG zOsLec8cR)BmGt;L>P<@rZaR96S4yH1?WG34DGQwTb@bUGhE|dwC--F37PfqrjDV?+ z=7)#x`C&H5h9HNef9aE%ktAa_iu&XYnC-UYzdtZ;S(rCY@90`J)f3DA$>jEt&Ik z--Mn(t;Wl!xnKBxfheq54MTDI>6ln4|8V?=pQPtuOkGMF+FDs@`JqPKcf^rIx#36L z3^XZg>o>na+57c|%^$Rp;apJ-nCoGbecJBFMynS1Nt=B`amf*UE9jE(sQ-hCO3at? z$c@y+3Ej!n60HARGu}*o>=GcHrl4`V<@kGdVllFln7RVt?pq`UUi(>G6iJfu2xzc& zC~>yFQ+OROJ%`~`0RQ0BbW#HSs)I#EUAo85{oqP{!#}Akk|{hSq}S6`@PS-T7eG%# zh*^G%fye>2v+#*B`)O27Sdo(?{y*kLRk^kN99@|*8c+!^b+$Qu3LJi3uIe%9ps%q` zRSbUqNX>H}#Wm>}e*JQ9I)#LhDbD=_531fE+DMt|ifXR^IW*cLRq6!dhVJRe|ADz; zh(YbnTg$C_hPcqMBE6MYGw(D%UNvgo*EBWh zaa4KvNc-0d_OWEaQu!s#$~Q_5>*^ngJC9wq9`B}rFhx_pNMzOprVWrLT<;-Urs{Eo zeL?tem~>M12MHOYor_Ywz4W5Yh(~B2kfnax# zk^{Jl179k0T4=g&LCu8?SRjU8*49#U#4xO4) z6SRrBR^`%Xx=7sLfyrZ?Z;aeN9@?n-g-PY-`qk$rCC>w)?W8lMK7`||Rb$YPf%VpO zRvQ=mdY8z(`tC5uM8yIS2?eKtNw3pe6&C$_8h`f--C5-jrvi9lIoH@fWT#fEng(yf z)bE@jv=A;yfmPGBZ&R?_{&$Iru}q&%>-nAc|96e}9uDwiDWHM+SC%Uq3QL(leDPC9 z@0qKA!`}c$RY<~yP;ZV|R-zlhuHq0azSXGv3BGsda2VO5PFY#wa5->|@<1cR&zk){ z_U$b#d4rjJPqxfR@2W6P1!-o6h#k2a!aS17o^H@+?2Is>ks8ZB3I1dHOyLE0F=f$& zokftFGsw{wr#v8C|4^VmtcDNGUmTcYpCGUzO=aAA)$7QV6Hv~kCS%RBT@WA%LlKt`d^rpGP8P+j=Lq`}NySkUYj)zR>;K_nH!z}HQin0j7ul%kfd9RXH5&co zG*$RuJxAd;?oJ#_b9fiUAwLwFMolUYJO1xLh<{#R*mTm~dE zR*49J+*av0CXaIjycO^?CPdA7Im#(zAULnwa9P4i{L~~(^b_+EylRWL`f*N4;(f=v%L(vpH3S~Tj3r4 znrOVz8+%q)mH&(Y@P34y8>sXRa~G&&h}9?vs1_pWoqXrr&TVAFMp5*x=|foKF$fP= z7%wcm_3$KR|9#F4*icfUt{&58HPg%_BXISjbV0#IbOsZ>CziaUe@c2~IWrg*YneC6 zsiqcgn!Kh#wVT{I2l>lFbl6xnslpC#2W}(IZOxNZ+H$a)In^S0{cc3hC0x}r%GQW! z$-f+3r5&|kfXLQm4|yejt%U?5lKhB_?n5(8V3vB1M(ub4XFK~W_2 z5jTgohDI9Ak!~D=EUc-p=L;#ozNLFUVXq_cY213=jbw?zWw<^<=&@5%P_x5!G&*0g zZVWHX5p4R-Uhw5=-!C5js<~{ol*wG~clMv*`@5+UyR&P%S!Kk|e(x7NcLps{eEU>y zEjHNl)8?O-Bk`AVJKK`;BN0fn&20Yyh-^Y>Oc)J=2W;tQzmj`h1d(U4{DmH1C3}Kq z{)B_CE7O}7#N>SAsOePrDCBCeOD-?}aGuTSC>krIiii^;eRlR)NeqDeXxW!R2pL7} z1#{TwUl=UP?p*CCJ(`<6Os7llo<=iyGc)}fLtSZ-VBedqNs&^dBKp<76||(F0Uw@* z#xz71FM)phbDf6M5L{w!d<1G720lX>ou#(4tx1%f_YCwtA9(10zZes24fv}s!0&>X zsKIT5EnB-^iBXpv$;CM8_y^E5*lzTfvn&{|Jp$(M%vDJFr*0hsMi-~7fA-X20wU>J z5dMMELYKfnAC}g6h2p&(wUvsY)!eGlG8SF{=+A_$d`Ch|S9i`xj{%UH3KO-BpiU_m zsdE$4|CaG(yLa{yw@AB{mGGl$8OrrS&U9ec`l!Xu9S!_~d5+BexA-jjy`w5Bh_Zay z8ozGNu+bS%T>HDgN<$?8fIje@7`UEallLM}INrkXHRGFKl3u4x>t_QDGoS;ZDYFrL z)FSwqu|_hVIh3bK9HhN)6Zgum{Ga#2D`>sFGgj97`R`K@>T#4fa*mTQfqmG0T;)TB52Tv2H0Fmhsp5}2S9R?nVYyz7G(org@q*W! zQXlOqcG^c{8I_;n=KvmG{srnI!x@z>WSP9pIN@CoAr2B8Mo`KfqhIGdIwssY$)Xk- z7By6o{cO>sBaR$Os&p6rWCSTkMb(-)CK>rO2}Nt2+DssjDi|>^z$XC6eNPnpD0bNR9mXS#EOhTN>)6WcBM^ zeAZ}2io&Z3Q0u%?zf8ffBe09a{}8Wmn}G6Oa*`x3ULn@nv1(KvX?cd0(%o)p3yO8$ zQp?~9eI5UF@nMY#DV!HcOYK;vC<9&Ln|YQtV3mrjh(m4^|AL|J>Musmzt00!D`qlG zGbS;I%9XB&h=N$rB=j_)tHEy_r&Em*I8S7L$;eB=lT4x!^vns(H^mqPDpsUuNJiL> zToHU>Jd|t)jHH4K)YToxRN>VULUBl8yKTFtWW6-oOd5S=CSv|qGIKQzRYKZU$FNMk zUJxEi_W_AzqT?xLaGrV=N}IA zx)i3=8+rF^_t*;+>U({8*UHLZOl0&<&_M;77F zJ>-@>l(vtd)cJ32SwKMn|CIAAs_S%wugNCn5i_ODpPZG1<3~;sHLT*AzaUvp>I%!z z7hroihFs0vH~^Oz@*)`49)S#1Q`dNI5oy+V6C7Du)W+_tT*-&EYX_J3LYEG}?Tz zOw)W7_30d|>WxDRxSdvxVXYlFq|M!=#+=sSn3w`d6c= zEcRXePxN&dU>7`4fRg6uU(F?S;5O_$*)kAt=3 z6vgW>cV;oeU7}PRR*b|L08jYgFFb76wHbC_@GaWf|8A z@v_LB+fa&x8DdAzaLm<;o&Q+YxRNi*p#A$~7|WvL7bwqyY_nKhaEN9v#%<=tFqZEb zOt>PJ9^KFE6`=)Pq(Xj_$zFB@~yhtmtn5{vwXKf=K%3r)UxO2{y>CVZMj1Mf0%(8 z_q1fmTqma$hv(6McxyhFW?;T(Tu>_J^c3_^K+(CTCcXh7BP1fqb>Z93U9M%US6-0u zJ6SQ&0E^y~8VcOAisElL2`hlSMg-asucqod&17(!CS}86j$}jsG$!5u^&C{4(|K>O zRo1+5oI2@9GlL)F66t^$>rqF;>jk7Be#h4@m%t+&RQ$DUI;qxLZJB%n-W~o1O zB?|uT9tk=9@%a0~=aHRixK8QjL<~8Sp957wiqKbcO8|XlJ$|5{vw1(NWaD-4L}4Uc zWbqw|OE)2)X|hj`ar5_S^#jP6wr+E7*NmFX?W*;^x_rZ{v7!?tPpZimB}van6|wk= zw@FdRLg8mZ849lXPy6((L>fJaT3df#dBDdI4%#zn1D&KHM>v)Y!h(A!bdS0;{wH|K z{U>S)`^H@idNrDZuJFJ=Umr!wkJhGkyd{f>EV!mP>C%k^Rl0#gY`Yo9JJ`~j(=C!o z!corwV*j7GAV0ie^U^SH2%s8bb#}}|KZpW;Y=YY)w^Ytmp z_&XvX1{vU`(t;NoU@0c4LwVuisFmPtQqWuvL<74wlTJ(+oS_&WuHkwasp0Z11Yutr zB!^!LmuZJOBmd^_psVh!yt{%Lxts88fhZ;g3zwBRL&>(ce(gtS4TPs_*{WtQ=ZcGh zgxj=3<5^Afm$Hlzpe&U-t2XZ$^Qr?a@*N{#;6Cg2*WbeuxG;YGX|g>nvT*7jF-q@_mTVjV=lzgvn=hVpR1I2cet;kBT`WtJfL;n|k>%n~h0U2Q?Gr0Q7h~Mu zo6A*d(sX>v6!^?wY90biD0rZ=y&W5 z09`N%2YsX8Ak(`j8m73u|%LV^dB2a;_%J( zv$WOq1If0CV{XtklwO|_+{94w<546p_zr-xUUglkiWZ9i#Z~JvyujW z{v|~rcg5HR%F-W1DHA1U-yoio+eA`n&aH@UQ2kdJN3V?##z+)?k-=!-HiA1jU$~&p zcW>o_&u!+{lWnJ&T%e-|CHk`3P=;*;;9JwHPBu?85_DnGuZr65n!%Jz9i>aLJ--XG z+CD|hrn8y`y=f^p^m^r%IMri;-LMzctr#_qc(xu`lsf2wWp9;h;_glN+X>ng3}D;8 zS@?JFww}5Ps5Aen-yg#_&y=fFoBemp-?&4uN&s5Oc%u3`fC68r3^D}kFvprSU(x{Y zV%(7@;?Pyp>2qd^)fW9&16QF3+BWQ#g;-|OZTajOQaCVNNg!Qw`udHX7ST@R(ak>A z1s152g~n(o$6JkJ+LCz^jfi@}CmNNLPTeBjhN3OPRUrh|6Ahfr>O|45`TF%F=4z2! zzB^6$3rYERhW?k-LByb5g3Vx6R%#~;P^jO57x^kp6c)pZ^G6fF_54BtgD zS>}u~GoaK?{LX&QS*H-yt(X_J^xftl2h8pWg@6WPyj|HEbJ?632go@uFuG|gV)zoL zEt`)jHMW%SV@@8)kcJ092_a6Um4Hn2*$u+O#o}eo<+PC3jtInD8I&Bbk>0Xa2dOz% zcH_HjNNsBnV=A}(9$QomzOW?(u*K|Q{?F^wfP+Lw>Q%C8xW^!X{y{uW@ zxVyPc5=}VBYv9zVtKJ`$U$Vs#Wv1N2dHM7NE^NtCO6gg7KzW!8^9lPm9Ah*_6gBCM zW?o5U6LvfIB77Ew@E_n;b1tdkVI8Ka`~bn7ZEA>o`Vwbh~IRksM8a}GG8RQn?&A(E)Or~r1) z6NOtZBs2s9Z9T8MpYSw)GwP*|39&*{gn1>}+4bzml&HxEa0LZGbP4AfrQY(H5xpr# zLRb)7L&mU@w%j2O1l!XCLN6zAasN6+WktJK%JW{UPa-fyByEnp0ilWYYW_w-uZuVy zRyEVU;}?h7$Z_Xe83}g-AuT4+$j*W}U85uO1U$#H+x>x8ukiB+Q^l8#F0t~jTn@mn zevmu-eg%ZeuiO425u25*ih%mUy+f(_?uq!FG;-YcWV)F|`Dx=31I21dArm1AT_LFH zyPid80L?1!zm_RhTNyT$ky_==)dx<1lT7S~BVYWtW8R?=l75gcbYePk(O8eP^VCa= zbe8vNLDJNHlbhD@T=QL@FhnvQe@2axSlH6T#Lq{{untdmydfNT2>}R2a*0=0=hJcH zQvlLS#z`w$G6jCtYN^U3!-6HUnS*`njc4oPBuWjLK1X}{?tbRnuVK+L1cL8Xitg_u z%I4X%js*#_;l7P|6H}|ZUGAfZvO^aWu7mISE>l!{7;}Voz6AhoAgm6v3qv{Jr%OPT zC>Wx*s;c$hTva7o8y#VqkvVu;lbrBCRf!AnPngkjuMGsLhV0kTpM6<@_ zn@TzDi!4ZwpcGFx;8$6>4auI*5ji#UJctfbQ0#FTO1i8b$~$f#o1FU|ZN?9zSVY&LC+vz|ph~Jip@(26m=*|H5(3-aF%p7^4bL&m*2H(&tqyrPh(1&YTc^mEt@jiPD3PWxnR|UF4(d~aQq2^cB1H!^fuN(qHpMvqG8l0(w}$!K6ohT&(|JQI!!ot-s^@ zHDBeg;g&?J?=rla_GUIqILoGO9&Tlyd1T1U!{K%0_!7+oVFL9^E2_yL8NAskMcOh- zHdVM>(V=Al89d>mWGs*Y?LN)9p-TCn>O%qkR?(IFI?p2?N^AnizA#Nd0olg&&rlw3 zh)5O=Q3AUG=IY&cGjrVlar{$t1>sYAU_jG}<`NmH1C|5fFQ%I5XD{fTLZf;(>lT@*u_jeSU3^soXDwK80x`O}k4j^y@Sm*^RVM);TtJD* z<{5I>kd3aYUA|~pq0fWfPr6QV#+q4HnBn?$Os;Op(iP z?ys*@zICO*7ELakKnnHmRpu;bE?aUKRNOXc1sPT|U7iD4vnPFq!~tM+a*-}p48$PI z@ifi9h~*Wg>;rh*no?t-^2bS-rA&AlTACs%&r`wA5e`=*%ET)%&V0hn6jz2o?rq9c~pduv%l%T}RBuDYcbRCKa4*zYw1C2w>OQUxOkoMFTOg zsID;9TWCVZm@f2RnQTCcj!R!@-sQz$dzB5lic&@=e#uSJ>l8x(?Jy66FqE3xBV67d zr!_K85^tQa9ap}$#llTw3Tuh%sXmP(`umhlN1xcDt#CL5`au}PQjkZ7D*>u+NOevn zIr7}@EaXx~e~&1UQxhA#m+$olLR9`tl$>e!naQwK4eGcr60&e9#F*?l=X4ucGOiqP2SdkTcoOZevZ zkr!n%gFskDI@*Bq!U3^u$$^9^s0%z6gx~g8zJ5OusmHD!t{jCNha#WYTIofp7BUyF zG%lMSxn86W0+=ns9xhze6yPp?f2`0wjOy>T1B+j=%p!hT(>r*69(8z0a`Ri^nHq;( z@UQv^b$P;eSUG#E%z)J4&jBGjeV3EacA_Ik?F2pU08HX#L{zIC}ULTjy5{I(w3S5u_~X?OFc3S4IJQ>6Q4)oiFy*FYdU%!9 zxrb5Yo>C@9dp*%dyW7QlDA+cg`iyve9yl=IZ#B07;H~ur<)~68MdNtLd4m)u>B9)+k`fT(_P75yZWDZN0rYX zmS`TeZ;TX|K9Tb9x&K4KjYtCV=x*3;*p8`WYWR_ACPnlrnx)S)Wz~Anb=;t~wC7LB zgu8`bm56J@Pc1sr*!Lz~D5a%6{~$)X|GEuMthbi+$|XN{gnGOb|EKl`G$P^nsWvTL zfR9oC zpR5RTzxsy=$?!+aKlj@9tr4v>jt&|Y5xoSHM-e@sl(LG2g{R@{5T z{Bp1`j3CZt9=eZ^Jx4WSUrh6%x7Vs!`GA=`A0%w4fx0~{U8?8}Qw{_tN)?p}oQn(6 zCrHJ~3MRyk{K0MvRcDu=^k%z)fwj$etrm;eE(J zS0ZGN&@2ilM}yfdn0o`NxikC_E5a!ZK7M8NqN8_A6hkP z6A?2DrGa1A4do5x>r4M`^$UN5YBm{9`os7DmVm3S6)^etO-=C~Ejc?;J*q6~%_mv? z(iMU)!315E>F=)0(F)e@@xLSz;Xfo6?l&@iSmvsl`u=_1`M|SwNis1yX~2 z-x&-oT#`=Kfz_3z{-d&Q-ku}>OEDA59W2iziJ4FC0t~jd5juLeLjan?BMVy z8vr%MqGID>XEN{bKnoWyrducv6tI9)>`czEHurWCVMuP38@W^zE2dRW1_(qS3J^;l z!kppzwR;_;N_B)(7(R=v?9%(TUQ|>N( zU#h11C=NV3knz26=QO#5lf#9b)sPsqVwuHr~brNp_l=7%qZnw5US9 zvob#lfOv&=hrL|cC{MK`^%*yLm3Gfv6GA~Ti41eq_Wj^eNq_p#Hh%meW=kFT3Cs?X zdk^mQ7yJ<>5IK1)O(}%mpAMKUMI#i-wd0^if|zlcC)>WUJx~IPfn;NuE-)X2$9>x8 zal}>=Q~5dn6CR3GAAnu(rfRm00kTk5brA6yi91L?<_cD$AMj5FQ94!IT3TKNaZrrqE3wp#O%5=nqXeJY048ry^rJjwUJQQj3vk3=P%P8dPY*qyF5Je0 z%3>ZWt=CF&BuBHJt~3d6510}5yDnZqOx~|w$InfUTop)ek!M5|2A6N5qqZ9mA`2%( zdQkrr&{t7~@zRH_bnWShL6O4?yrUcl&e0j?r5iQMY}a!G1}q1ofDdfFf}XeqN7ULzTzV`qgNQ7tKq$< zQ;hI|q?Kb=%fq@vX8MG6XXjfPxwO_yvt`)h`!_$M87NX=JCu2pz+A+BcIp?3^HTk; za`ZV#-Xi|!lF5R6;Vt2Ij5)l#=8ZIV6eXvG@VZ`Wn#*!dU|NK*@82PEuLkt>!sSDj zQbPnJ1Q)UEDa{Hyc0ix{?ki6>j=nlS8dKDyjXK@gya&IYQT+K9UJn^Xt!kA1BJv1larxx{b zE5v(GkT|(y=2ytQ!ZcBRmh6G_)NSPnbUTftry4vyE#mi*`1y!25r*nE{p--8{sV$H z!{G_}LBE>vbPuii$9>h@or40UHAlBaH3(oR{ilf=M8PtuNhH>R37M|^#LnIHXiCnvn81gK@-Ohe;mRy#z)wk4=8{V`rhiM6;D-~~ z8Ah*pg1xk-G5kCWS(}8J<9S;t9S_iV>SAS=4LI8y&^JNCz2oV15-m5#D_g4YM+O1P zFsq;*o_?rEuM_#tvfjrje=VpX@@Ggm!Yc6M_PhAQjh2|ouMD$brCTNHy|eUvG}*9A z$n#Ki#K5f>0Vzq=sh}l%Vj%kJI&pCEN;j5a7RJ{F{=4e3D{Gknbng$ZWK*rQ;Vi|C z>+lQ5hKPo8zZs1uk`zxKLko3fR|2^x4Zx;PI)|N=+uDjgO-32Rt82)CJ1>@ZM2m$+1#xCXNfi^DR-Op*WCKSTmeIygF z#v~wd_zkU7Z?5g68)55o+iermUxg&5((O0#xF9RA#FZ4aYqp_?M!bFR36fq1_x)+c zKdLSCX(`kL)jYshZVhr}?agAQ$`^Tx4S`4c+|RYrq6F%^*CblSXgG9LqHK(n*nlq8 z=7;h+()s6#XyBzRWs%=Ya5ixL8o<-X(`MRqV0rrqDU{}Uzwe;I;Uw17u|4zs;FY{O z0Ie#Nt^_NQO_qmmY*<*}O-^vu#T;dRvzxWdc`-g6QnbxX z*lM>9Zt{|Y)!6$C_1Moqfie@_(1jha#Ydm~yD!FwiwTn38RpfaWYJV6C>9Zfx#TA1 zTDP!PzrgP%`D5xF^jc6>ywnWIzm-?14QRf_UnwufI2!T5hi11ARI4<%0KRr~Ye)%P z;NgYUr)_9KzE&5;pC%Qx+ZEsQ7;@(x2-Z@F_d~7&@Jo;dK9^j~yGW$C`^fd;+I3XF zUe}AohKbCi0rnrOCsLeIbA!08&27k?>9y6Q-c3$v`)_XyJyF_ZigmcOS!mrBbwdw( ze0eVOYi78fBILWx@WlJUm8#h6!*daR()InRADpH$Q;Q5Y({cpGa*2gdFBA@NvsMB9 z4(zzF(1w=7t$V(}*QSZ_Csj2qF(qFKsk}2Af8-bd$63X&to+kTd-e_nsjezb`zG9j$=zH6xygTq<&0 zuOj~$4_UT}?2K|PADSDp7y4q1D$K_~RUszM-ymj6Gv1X~Lc~^8+Q}z1py}dPx!n=a z4u&J{^a3ux3RLa>5h?$G&(<5yc-g@Zg*E#ko`7~0ap z#4M?H9+H=nF~D9wWXAI|kEjlO*$VlW(nNE8;xc#f2weZ=r&h*t==&K`+UzwkCowu~5J5%^T;>Sp zzj61xnkoHkvrSQ`&X2Do1eQY#JY6rbeHlczxi95mQ8L68T-uB+y=mGIkn;C_iAtxQ z#+xe`N2M~GADG&4lK)l(|A0~9ZY%koe<=?GyG^4`bt1@to|I0Q+w`PUAU0bjHW&P1+^XWa#iLR`E2EFT)d5vU-~UK?jn99oC3x~ z{`+$u@x-@aBca941s(}XYWVZFF8VfCb6A=cP4k>9`?Pi=$P)-D^`6{J5O$ZXH{U`J-id8tL%r~N1~=3uDKGn1!Jx0NqWj{psQkRIe^LM$v$P4 zVs~m4rcSZ0aV1WPw2%AZL?(%gL>oRVR2TO%W2K2}jY9_Z(gvc13@0NdmGN)V6Dq6;JfvBqIA$ds~YU)HTx&Ais0(#PI zg~?V`&EZ7_^)kgb*I~Oh(~J(eLJ8l_<2%bM2+LnFeP4wT2O@12eN!c)8*@j3WiMvF zJaXlpivSkuCurWQn8Pl61wAo)>^hl&$7S`xwB+_xsuip+8B_qK{UK+DN#^r2R>Fr0 z))uf%F5;$WBq@yhX3Z!HRdqQm(E5mCNfD;$%ynJR;xS zfEixzE*?6x2rHLQgzDg4!1dBlS)Ae1upMf&`ahg21q0#MgLyh!>rGyQL>c=r*FkO4Y~6eebL7|>J5_QGTC9VzL%vK;fdV!_1G_|UKPp;^W36N`frPT z^>gLa_DATD6N>*Hab0zGShVG&2NwtHwB08>W2t3;4P@mhE zh&?nb$tRMb0AeCorVRY5zsrvHdp!qbt*G}D=zTu+9O5B&*+AO@1UiUu9{5gXxJ6)B zE^pP^vt(aE8Gj4UY3E6rcOU42G(Q4Af=WK6-s#_7uSl#v)%=CB_cXR>Kp$0;K$PeA zBv~soRQM96FDr!e=?NiZk@^Ytz5cV9Y@pCsDy*j{P1$J_r$M+hr)YQ^+gL}%GE5yC z*^969l&;%b8-2clmi{F}@mCTXK~+J2kUqmk`}HPr8iBi9jSabq*kTW#{Kl*8i!Mwc z{+Kww5xiaU^rFHdMauj-!FyR3B??e<1$C2t4`X6203XI%z4v9UkhD=wtP07p*<6kP zj-NqU%fBrXZhAROA2*Ce{{?GxYsLqs&S`pJ)|N2)?_3mKFD1aYHFY@@OMgB$Ss}Fn zp8oL`Q`)U4H~sv@CL6{5SSe@=kJY+EL+CQ1|U_OToil-z9FaEK`~76~&SLbloEv z!ZmZGM5$NS;g$H}c#1ZpbbzBd#_TxH5S(U{KDbE(qMPL8-=tX$-hgfb z)(Bl)cp4jelIhkQd8yTX3zgqwX)WG6gxs|sWHWJQjclDsLL)XYrM)_r8(Pvk{jjPL z^;YW>&57`hOVA4Zq=Sp`${zHpEQ!qTgx-FBSLxFzi+b!VK=|0F(7gqORe0!r|Lv&f zZ)nw|aVD|X-YRP3w+9Zow?j0jylP}_g6yCZX4%#(awZlr293!#^dx-Ng%=N;Zg`p{ zDn1@Z^oUU?qv;m7uvh+!D~dA}q@g2{p=kL_?w~^-xgc6cey%;2mg7Xm_* z*h|5}{;jQLg;#YHC*m=_GZsfZng6j1crmmg!yut7*AeMESatmoGi+a_rq!%&I)795 z0~8yg11J7uLWG!_ObPSCy$fPQDfLI%tfe6Xp*N?S)?@ZqL;A#DUj5UiqkUmXFNVHO zezPk?d4n5mQ>xnMsR*UOo6+>}b3k0eZzICvJIwJJJ=|YUS?Ck0dA~!shPbCyw)FG} zb)@PYqoM(9uisFfbnPVC{Wqw&e$vynBFRd*M*!*M>^%rEA7rl|K6HtR?5jGLz!6Tp zBg7C~4nF*8oI0i57j0BR^}eSvmChU(jlDLhBbFxV;hLh2?>2lNU3f z<1aG(KDL<~VoZ+CP5$Vsvew z2jarMN|4Pw*_&z{Ss6Htvg&J5HnwCuR>G41Q2SI4C^9EqH+2+umZn}ok1C5s$trB22Pw7Rpt z^Lu^JK$Hm?Pteaxnn4Yd$7Q-PiB$I#gvX@f&8bh+k0C?_V>JtjMeMMpwiG^uC)^|G z_fLdJI*!vyMm741Fr0K!s<5iwXYdQ9Q?RK-($LB^uCb+9R^YQYpm5g=I5h+0z~VpP zr6_{mTlatHuKPqk_OXZEqSH3-lrIPJ`dk|v4PI<#937+E#%W%`272_N_cSN&E+jx4Ka(;|i?n<;CYL|v;5pHi@4$9YW zLvN4z7?OY_Y?#vY7F_gg!fxFYbs6Vz24yO3E&eWnx^ec0-XX|dN8V}I?33jI$%Cp` z;?Zb`Cv}Rqkwx8sncYPm2$kjUYwlm z0o%vHhR{aQ4yVZW9buCgmZ|jb0f%l#mycKq?P$XI_BIkWvP!qhE|!3WT5*UW%Tbk> zvlE#5l9@ySJzSGY<r7X4&SE_DCYEG@7h@WEMe$8*l0#L$AVbSJB*8BdQ;=jL6W2z^hEqEi{U3+=-0#q#U=4`jJXys39F)mUV`7VZ*=ieljsSgOKa~GmWtbk-KF5J)A*8B z$W5Z4%y1BuJ}z?-67)yOt>U)8lh?qs93JT^+c*Igz3UaBLTsp_bdY9fhEn$+d5{6E zc0=Kb6qIRp2~EUSSYU-26}8Gr9U72|+AwjtnrbuHp4LD!b0Lf^LXNgUett+OCGvu)mrL-Bs+2QltbypnrPaVgYR zGT-S1?6Qm?hbp41M6W)G)w%Mb@7j?H*D;Q(bXW0vq&e|J>3x&W@nlS-Zq(O9d{(Fp zU#IKN(SB7tJ~dAqq_-b&nT|$^tQs--(zWAduiF$SZ3|4YZP-Ws6f-+>xKG97?WFqv zyrpX5m&J5&X@qpR0&e8BcMuyx&Uaukzlf`Z_Jg`wd_f%6@)gbtvhXEP4bBPEcx6^t~uPUVGt*Rd`yz0W8Ot(p= z=979(m!^m+t>I@s=AK89$-dYS0bJ?ntDwC{7FC@xYF96e1O~i_*n6ZELu^(oNV)lY z0!;1@%to{Rtf4!4;R_mo{huuSJz)OP>U@Ev}@>AeZVe23QC3Q{y}k7W_pQJ>ggCgP;uL#APc zVfI-ppClN&y?G?*;JjW^@Ug za$={+(sYd2c(p3WlQ;=vEIHc7}Fu#Q8=>?*7ow%GYsq(%0PQWgwuf<*1Ch@5E&*4ANB!U@Z zXDZ{bS$-=o>Q==gKhfzG_+oq7HE2NjhPyn$ZeMJ+AL&aJWhJ8rw=6fURHn>D`FFIN zaeuj;)l|CgM;xJqTGetfO7~OjHZ^YLO>z%->JVaQrd6xde`$4gG`&03YM2t(8>mUO zT9XE}Q?}h+^&!Jy0J|X8BMo}KIHfe5@VG%)7PL4;r@`H)Jmv#pae+(b zd>T6LSc6)&%olIS%(YV$bn(%;N8283|?Gp*OBTkYk^~Ew98M^PAN*(RoJ1Crj^?W9DHyTgArHt?o6@s&7uDD+x1^ zm+PgKEEPrKmq^PhR>A+=>z#S*cfwtmZAXQ_0^117_hrH@QUzZ@t7jw5ZnSnWpb zto0+m=tLJOBWa=eDJya;Y*PI9ca&MlC4OZzVAK-6K65XgnjZ0p-`ueoP5?aGh-uYf zCm~UDPUu#_ns!fe-J^X6XnFm1nY897W{GHhXZ%Tagmx!NQ7R-DXOXj$W)c&@i+QkJ z_rMsoP@n-!D^{Rv8xd*B|1kBTt3%&jq`o`c>6<^xcgZ}2-}5$5_{Y%}ev#i(ApPFG)6q1Q#awiZwL1@F%rsvW8RX%NC?@Ud`p(8IRuF1~ z#OH0qnf-{Ek;>~IqM~HP)sd)c`kw$l=TE7UTIKx`WCyLDywjM^`ZTw~S?RtHapySs zAEDmkX!X{Fp78Y}U*1aGvjTn8RE`GSXhcnoJ@)Wo@LI#l$g`7-C!ZWD`c5&tUXaVw zXqCrl5BiWrA+5b<`PQ{B6dY-Uxw)zP6=&Z+pg@luHj&%4t z<-&>d9_xhRrxVzf-mX((<7^bG(`kK{DqgljK=xMsh{yc5Z}UB}KFJ}r>J-Aa9t!}i z8YT|mdvPx%2HLI>AHsIB-qI<;sy{P3Rb~?zO!$QIYnSvSV$Uw+@)OCccED3)P;Z^9 zTtlyC!pB?=sq{D$p}!40CR+Vi;ewNC}1w{g$N&6Q#_$+eg zcD6V=cC`7tQhb2bNjM~f0tvI`ob2Z23Q!AiIW-wxSt#*|9L2D=+}4}4IBHv|PK?8o zAN)|iskE}BeL5!8=)_jFjd>m=NymYLNQQdWhmJOnalFkR%KJ zKq%i62iY0C{sC0Tk{9sxz%=&WG9es#GQZO=Jqa(rGzN>kkBX1NPR-p$Zb^CpGl)(UwE8(La%*s9_jErI?nD8cgX%5`tMe@L4EO+nCbm#uckAy zb}0fZ@&CXs{~!+v(5$KU1H7I%ln(EbgPO2K_7ZAjQl}|hVA*8;Y9aks3u}~ZP!h@xVZUj0hfH#-G}s^aoW}W$?eS@G)Z4QAq-s5H3pHpL z6WI`!$oEMb^io~#QzegQTx^oruIBk&P>f~ij9$eMqTHTh|Cp4~dt4QX`)Ku3c1${o zp1_Y%+k>Ts1;3$*wZ=%sK>z7$%nO{d6zK2OR0b|TG9)P%)z}+c)@6(RdDWzkp5TX- z)PN`0YwPq>Qnb0q%950D>)uK7CGespNwe>%l4ME_lR(~Qe60YbnCbNfUf6(OB6BF= z1U1AY3^>8Ig zM%S8g#8mMBH&hVptCyVdSOsv>8c-r@K@+h z(bDmRZ&ED55}E>SU_Q~AFz4%(!jcN7J%U_`$97*oRr9JF`z9Hmw+s2cLXAAK+^_I8 z-bV8k8obeE9JJesuwaRIGTgE71rJS8{66&tlNs_8%OAm^d9X{lqt^?G?6aHO181Bn zQn>WPGLK6?DSGVo5>;Jf)>R`Zqm3{#_f2+q!-`W(dN-g)f$^On3KR)Z9%c=S~AA;JV(qY}H-5dno9}OrFTucAqxTv^u(V zT0Sp$Q(5zlB6MJr)T!^EE43sEK~1qG^z;F)$44(AY7G2K)i=1=V)Mc?@q*0EoO;)G*P2~lbNNRrkPRp~*IhZ!x6vk5z;~kp#gBMN79%LhkH|V{`3dc}bm>up z<&2@K68KMfQI5eFY-Rr6qDO{5-DZ>*qP7Q4l);^80`^tZJ8G)-SmNNeFk}<-f%!{U z6-a2~DC;M&wQThqosL8~-vRjxfOn*BARnrrI+s)VXKv74QEdz7K}3W)OF+5-lN#2W z^!5?&aw2Rxw1crO$e$O2-Uq(IX7^6lhApz`w#v{;En@#e8;_G`7&&vgdnEK_uEE?Y zrzA3P?`_73Cc44$O_O4$XZ>{;59aGJ@jA{xv8KZK2JRnK%R=ZI12K|C+|U#2qB8G| z6NKK?RP2BC>#v9-Re{=4(n?g4YFG1TC14()rt<8a2^wm06Y?Jgvks4}sPypR(^NwE`U{p1e_L8+>?h)}o zZyXUueds06K1Xd`SilGMiOV<=#BLkYVVlAQN$Z?kQ?SNTc%W95zBidt0b9W`np;Jz z9?U+4e!{iR2_sjJDx_S9@;R?+dl4UaZ0H`Tc}_lghg>AttPbs0R+90%c_HEH+^U-E zZzvOwd@@xwzM8)Q+MpZLPemG6Pzjjhuiyc*o;!il7ZgYLA@<~>%A?Mco8XY2+Kygz z=`%X(Cdp2CNuO}NUMgT8+(O&oH4!zqlTKuXxDs_1wS?-RyvG5XJ~*dC`^tCYHqe z8D~*k5-M7eU;LDR+G#7a^Dt#mt}XR|wjsVs933VLh0YiI=P-r3rr|2ToYU9XWDvKK-nog~J&LCO><%SVKyVPfjzJ*zJ9m0{P4~CFk{8Qjn^|%jx4gvTO4;@l)taq`-({RrnvWp1ky^tP z?E$aZ0QL<`()&>c{@*rja8QJ#$-n_sVJz`wpnrl85uGX7tR)Zdt2g z{F4Oyc#p)^8}+|SSU;=F2czZZO=K^D7jmL_2!#?G4`J3Qu)BL6z?4@kr~r+Qcm=$u zW(vAcC^E{NWBFpX7G($u?vUpmUKvpqMIpIOI1TCZpje{a?zx+o_u_5B{FSdCDEBWA zBes&pp`E}j#KRBRC0g*d+Q^hI$5mp8Xu7<$1IAqU3}9kMX!>BxL&e=26#meEF7UlP z#afCcM_P~a!JjCh*`HKLR@LtDk-JDP|G~r&>)bTGDEH@aOZVfa?~oWk>%FKX57yyP zH&dB@0#E;pysZB!)IdhK+NQ~x8PE;?_tr#Y%Ok?X_={xe-=#{Mjm z&v~@}otQpEzO)lrXCd{sCmV{&5K`5{*)-m|;Qt#89Nd+M&e_NQ5wK)Gr*V^O>t7$nqMB< zau+J|)_A1yvK!YTp&C&!vl{~ITGjW$$|R3=C14`Y9)Wp|ng@sI zIR81|MGQEa6}LHYI=pHK#pX<&frk^)r@MNdKx>#auN42;M`AtqR`rSo)Gd1K4)2$) z?`Z!wlXdFoeFU?EwnRvp$I;{2(>^6^&dcC>X@L0rym%`SmdhJ0XO2IhfjSB-wgvG{ z#)OL_eI-(YrGji?`c7^a1w7%#r5|D?3c*YgruDvKBG-D_qw%7%a`?he7(>Arff+3a zj{7+{zs{2w046Q!dz5Qqh>BqcjODy;l>CA0>nwOZwV|3+>c!kL#EzAeUAtTnIkauM zqQU=x62S$j98hODAL3;%gytFeABEV$Cz3^mtt?1OemN?p#zRSaFLoPXKNbNRS2W08 zX(D|B}AEIfZ5I+UmMx%pA(&*m5DuZGa7_@2p z@SBYk!j;hG=0pWo{s4@57rw|kqc{_dzRFn@ zHCwDj-ZW~*i#g&)J}EqQa;-(4vpxCk5;u=}er=SwNh?k1faF|hoLA18?W&DD8v`53 zYpNxQ&lJ$+pA|Rstp%$#%{CLUFWBL@16x#|JuP*xjwv^lYeu^O&y^4(L{HewN%Wos znMp^+Ruz&b0YP#^t7Jr;NjJGR9Y3)Q1gnIyvnvJII3@9OtZ zn(n`aO5Gu>!1Mm31A7sdoN2GLdxhGkNll(ctFDl}YJ6?s<;N*6<;Gm~)+#6rL)mQH z`imKC&R9AeLpM>K(wBQ6x3ZZ zn&-B+#VKKe`{=+L{&_aw;d0%Lhr|LIul~eD6mZ#si-wXfN~__PSkb#VG3g6nGE^xU znG^pZBNAx0f~nx^l|-f>MYZZs&=i zC@~eaQap_tTPH5Q&z5A1Q>5}aXKQZu7#Eyz0rPo?C-f7w*nzVD1T$Dq(EAJU$*4zl zU+mU^H5{+TJYo4w7~~eP*S|RPLHVZN_z8^ESCujsxYv4iG*-jD9IL4)zVlNC{|00h za1LY+FLxk#+F(x%aqg9=+iY$MhI@z!d1{U;vQJVz?lMH}=`epRv4c$*s=%ilRin85 z6y@W^BoSMU9Qvri_!sRw=;#hy7^!J5RQbq4>lH_ydfpe>9pH7vL(%o~e8msYIYaK; zn=pLp{(EKvHpp6T{BqlAl>Ty61^!yStf>ds&~e9Djh$vSig;VZv#WZbsC~X>%EL(6 zW;EJW)tyPAb^>cHcFm}aMy|Un()X+)Rcfa-%5aaVc%K5&fi+93u7ZMyqE^|-2a3RN zSVJg|I8$31JFd_amv3w^UtPNSTec<$I+pZQJ2wy#B}w;Bk4oD=9wePF=+x+mez)(@n|MdGQalGbV6 zpJKO)z-KI{e}W+F>=@}%QkWuX$m_Cp|i zos6Ub^ttIfAwC`_znsUpDo<5qc&g4EBquleP65mU^4C)NZM8Xbom}Bm_a(H%{iM_@(=&aW77DR zh!?v|O}@^mLj(0vdg1r^tODS`eVS;c@2^Od7b~_w-S!(X|1`{DS;_QNkj~O856_aX zQkuE4(w`JqiN4GL-<#QxE$>~k1 z#9FK#kTDXVkh&{(#sCv3FH99%3#gkE`9{|3Cg&7Hq?bFJ>omJ47-luZWBtXrk9r^ z*QEot1%dbJNa~#;wmC2Ete-gMhsxM7NJ?+8R-`&(<)I>T?Ck zS(jfcLfx5KzqZs+!f^Rtiv-Uc)opH}yjJD7fELV26YG9HuKEMp$Y z94wzjYPh2;3oiYIo?g~Lm&_E`kY85`QnUytHIO>z4*_*8aZt3R=c*Q2GR$2;GWAJZ zUY5e7phl@7BrxCh=wL1biS`BHVt0wBTVL5xR@?^tj=2)qtAQ z*CO_&IX954Q+OU)E~J9vhN4SDCL=zFR0cxbcL2_72q$n<@usn6r6DrkFr?%Zd;}d8 zbr8sc*ehj+=XWUy?kM3_{rk*-_|9Y~QdHR-Tsi{v=gO3ybp83l2eL9#Z?`d2A?ci^ zs2bsGRHVAsYyG#aK}k4NLve+vh*HDuxpD&W^(?DFcAPa=ULtCjrI))4)!C0v!$m+P zX(?c9j0AD$a=h~SPWr||zt2F1&AKmus}uC#$`&oX-R6p$#WvoB*P`T3d=TuAWI)%g zgB|Rvsw5%iJ41 z|LVWOoQv<&0kiIsP&+PafVuKhm856CWZJwh?*dGE z(KW4TL@qz_Gd-#A7q$II^BqD0|4YJhKX+ZqU&{m*7{!Dq%;d() z>pBwEKWUE{%+#DAzPyP1ub!|-&OiBpPCt>uIYYPl8G=(d$ZN9JE}TQGM^1!hy`kIS z4~9O(Tu}^{V{Vtzv01EJQHLm7j!nifWGqh@YN{1uCdkniS0xc4d}ZDciZTgoyBQ^J zzx%$bUmScN{p8Dl?E+%l|6Mtgu+aPicT2%|N!biIE=WUjG6eElQK;L>&R%qaNNQ}E zlkpfIZaTI?^0A-&D#u_ic5h!SOaL+tuZs~GLhfft1Jz?3)u*teX^#Q_Hc-Ksxu<7M z$RtNI%4y-{h_hZptr$0^x}ck)7!IBoJx33#59D4R!eF6e2+F%;8|9?PYznaG@lhbH zq$UIXCYQ&D*mi=}b^Nsz@SiXZf);=!ibda-%YVSPd-x>;#d zk#U4aHhG;atyw9$#-`lstt7z$h8I2_?x1aeL)xrfN2^47hbY7D1XK|DH%rTY{4s&hOeK{6k4$eND` zPZeII{OF22UdhJpA|<>+JCUy+St3Asu%i?CNgkmjLqH-nS43Z@VHq9mClqxT`KMX; zGhnJWIh+AQcx`lK|7UoZ)3=ZChT;B>b`inDuLBMRsBMN|HKqdw{_aVQG3JgY3k=fG9*%lm*!?i{atJ zLu^#L_Aicwpo#rjC{LyX4(s{M>WYcuGc}t=^S5iuJo*Tc9jqT4N6X^4;XuaO_~z?* zQ4HQ$j-6E{jDAY&1(u zSmE?z^1o%-;Xhax*mhUkbA-hwxX))GcPV7YNIpb{--#MhAMe6u1D&9YH3yN?K&6!_ zUn1&h)5lgW2MX0!1e*a>(ED=!e-ybali7Yz>Z>cJsjRAEMN%A@x_d>GCtPjd(Ry9Qrs2*|C_5m#J#wv7{49WBF^AdvGxWjizJ*Af5DeYEo1_f?R}ZM zeA^7FTv@&{Gj8b7ENyKt6=i)wV>v7wb+4{;_^kX=OEV86)ekQuswhH`}^d# zSe#r%-4;dadcJW5@&PJrPabv-aD1jvP%ZYog-N6#Q6Eqx!mD=eVV6RCrzx!PtE8u6~*7CI%*&fr=a_K zpxIG(GdNZ$4tYoPsq;8>x|Vil|K=22`rDd}+-bLN2GdGzKt`QXJdD`!3uq{?9H89L zp(w#sPcq_ zn@XExo!kcFd~Lqq)FF8Br$fW}!I9ty{k17|=hiO`v>nj7#jEuL!nrkI`#g%;y^3BOdDZ^@`#iVC@ ziM`p;vIp?9P6)b((46Kw2AuwjMb0(wL)SdJ+$?bAT}96-+@rR4zy~OPo{E&Xht?M* zN!^}+#}bRbI|V$IT7&cd0#6z_I8I8AsL@th7Mytpj2w%r$#@Kjan;BHVlWx>QM((> zMeXT?rk_4F@Cos!Lt|y9qb0NM48aZDMI)@HRJo}Iz4_R~(H|X(^L-?psCYk5mzS$7R2;pr?^K;QRwbF zJn%0vxf~rIZro*OBqw$YOl-N9iPl}iwC8inuVg+xO`BWK8{eK9 zvEY7yH%R>Xuzlr105tXHA zx721rYGO`|8vUTjJhjBqeQY09bZmUxXw5}EZd0LEgi#{|`n!;DXA3ZA(j^Gvsj|@z zhR9}%D60`}P0n5dizQfwPLeYnVmh1PY}j1%w7?gw#>gyVT1}tVAr*udgSt2k$wzm| zmkaIZl~s|uksF-wv}slEnM{PRa3siJ1~=f!r0<a;xKKaD-cV{o7wkK#cNqQz z+~m$;~+j=`tq;k5p=+QpJJLVzDwsCo`^l-gNE4$bJJ>XTF z(EwTshFW*hN~>D>G~wB|NI&6+<7rW-0@7n$V(~#eB0D86P)qqGMY?zb8hPz*WCvSu z3-4yCMC|O0hsBow#~nKtxqh=1&$3fQ+i#OsBeULlOf`0qFgFNpondB@RaZ5~KlVmP z7QvStpUF;VOc`T455PH=&*a$_HQ|=B29lEJ%neBBGh1%r#tC+ilt&`SA*h|h@6M8C zUvWnhXwVfcU5F@X$LRGsK1zhomnR6cAx>)n$>^E5>i;yJ6B<|IQOCzJzIY-xyQ~{~ z_CeC970mAFyFFC(rUrL%fHWTwE00>g7zf{T8>8^G;syuKk}vhMp#FdX1eB-@zlG6r zDMu(+KP%rRIA6K}Jv zs)3jh$FF|0C!HF-;oA{Jl&qYCSCB4JL3g~|7on?&N;@3SXp==2O~9`{FsZwX$t3H} zCMYlI)~p`Iu4lK~6jp$i(jz|g^5+^T-dzk&DI?f6q?V>gDKX&09Am?5D!p6jKy46T zKQik4xcf2h&c_&W$cqi=9eK?)o0K2C1Z#RVNyG(wY!!Lq6w6#cZ23Ngza(~b-eoyL ztLgPnFl>n%5L@3uP7pojMLSWc$8p={*QKDt9$+US3I{9DZrbB4KQ_<$%sb4ySLU;b z5)Daz)z7gZ>H}(DI?D#nP{Yl+$f~#=PN6s1PVd~2HvA}p?@>~JzLdUX5@aeCPi}yC zc@TircTD&xT=4<|MGK$72+@=y0+#mw*(Ag@1g1dRQ1XAP%lo;#3c&>lr*-M_50qTy z3DmEdVZA978W?36hzp{nVJ<4->U%UIYA-vrs1x?D1yc;3<9~h#Kiv}dKlzG?|FGDT zQwauHs+)w(&}}AbwHvzzl}CIR_f_CEI$}&EtCg1jbKWMx)m+pytV7#eqB$yND!amo z$JT&V62?&}W0f@4xw$j~HI>A6ro+I}=H1t*r?M#ARK+lJ&ae#xd+d6#4;Nqj$gmY; zL_x(PEQF2DvL<<5CFdAqQUDVDI7%e&=nyP&xguN1*Qa=*(!*%v%b3DeV8p1De-c26 zmhv{)DJM-?D-6ij!KQmDF7McY-PX+=G8uJ)%6;`ZqrCohHMnl*#VJ^{?6@hIMlL-i z{y#sM!f|5Nsyoy7dO)Ct9p z75p2dtuxk6on{frpLlbQd!~U{;4ww zoUcUM61STkjN>AfM$anU`Nav->JdM^r^5Vv71(b|-*bzni1^-b5#+BZu5p(2VhZ`~ zy!iKXveR-}L=K-Z6|@NxGzt^^d|m^uX7;4QHTgHfz@8ci8c8EwN>+Z+pFn&WGo2K_ zk0`&m5%|w`_^btONBWeL@P3<_K!jSoJELOwaGoAsya{dhV}@=sQk z8S&0@tLbk|HKm=Zf75@=8P$dCSdDmh`VxM#T}afDZzpmgu0kp}O9MyAzP){(C+tnI|YEr*PQ( zcTz_$pm=Rw@op{Is-voJSIme{Lag+-$3jVEkXXh5NNNo9V|q(uheL^dM-!T_u4FVu z2>%5wwZWzrUdp}qz~6)@EoAZ9CgAxi_{*iBljg+NAzW*eY>gJm(-MEZYl|vgkjHx< zqio?s_N@ZA^c1+hJ$sx3n=+b@LFwdJMIZZAX0atwny)2#Sx6QT?}}-r&Tt zw62-jsVXT@o(V_VpM`~Nu%|&0;S-!T(mUCXdG3NLjU+DHARI*-FR*O*H_Sv|eRXlS zDvIp*E9O`q+U7MyfQ?9(6nkW@LQ8d+KF`?Q#!Zcu(5)}gk1G$jBR+2L#BNUSSg$SO z_hXm9dy0u~KvB2PlLe1_&?H9n`d#F!XBtY(EH}6{nl9}Ts@^ziN?!R@AcejEf%9B# zkPVnoG!8XNFW|Y>W3{8^pRD56&SsvcfTTEAu*6u z)n-D?a(7&sZ1JL~^(;!bpXE(XpA5D{JP!1gxVP5)9Q2UXz+K5r4t9FDf(}_(8`1l` z$P_ifo{f6mFrVJG7*`J;l|zM;sh~fFN^0Wq(dF{A;TSTMza2SrJf0^??U8RPbeWn%oL1#`T==j%^-g-?N#1d6iCFDu4B! z(^!8==bB$#!sO&x)z*m5v_<1m*w7IMM_wmuO=uto{0dv5ACZWX*&g$V{`}J)2d-|S zyOUjhg`XF=-X;EjiRu_u5qeSSodCOSrg%fo`z0q?xS;p(wniiD?KE*$#UtTlWKa&qvVZOl`Cw~+0l+Se&a z)oP#B2ni#b2O*}caFs>Wo_ZiyjBohCqK~9o_cY%)f;c?N!KQX+j~&-jWgKlqIMmU5 z_6IQwr>nnvPqFN>*c85@JN^25(DNd4i?ut&GNSqyrii#&OBrd^$-U7e8QtLgMFKm7a@va}z#g=wCYa}tulxSXQBWi8pomnqh*@M58kMEU7 zl6aRMQ{&e`gw%-O0h&?YD%KGom@lsDJ|r9vOSJ}Qr~i*aL;0(ny#bkjSh9<~<42ro z{Z#uKduCuB;_d9NJ}+Lk5}a0ixJ}ihh3<2IgZ5S;gcsr&zh5EWO2e+MMRiExPLO|V zV3-?ElYM3U%Js;s7XwbWe3xSOYp4zfZNLR@h&uZkaU)A;SD?7Q!w<1zAH8fUz?*?tULtCmV1Bu!ru~m- zB~6yjBYkie4s+hd*>O00LMvgv7voS{G21&pMPOUxq4O3z+M%T5}m z{A63jg2|y|cC~!f0K3|`zIi(1#VlP5S{X`bznM&;jt^71y+G&@N%aFB`|0l|A0&Cc z#Y$y6F@l1p9W*=Hipx5r$pbG*M$#t_S;rm?VSnS&mdbZ)lJDgvj`YRWXJj9!!!i!- zB?sfQlJ`?NC$lgw3)H107~Ha6kGcM=n-aWfVx6+{B+U4+b1XU1asVjLfb@ro9t%NA zh^D;SNPxJ^Ihe+}llHKMsPHUcTJ?lv>oRp!8W&COX$U%ew^~9qd|&$9erRh>?si3N zNYfIvwn?U(Vnd{H^&W#7*wVsW)JZDsDHu8zqQHAcg*b2B`3`u3Hnk&m9>NXctpwVv znwecx3nf!!nk$>9K{Y_`bb{pQIZ;uOB+Oh%&p5P%y^LgS>^+zypjm}R)fFCre7Fp3 z{9D-9QUs3I#-zq>cuEWLz9^SH)=FLtp3YW7_lqOf4PdkO)T_Hs9W`hAk?89l(u8L; zME<=)h6kn`N{SablqJYFc*A|G6jr{C>!|nCOBPvJ@^|*mTZHcr!2#n_!zvaz@*;B?jF%7AYnG=s07Mz&T!leyU0|s3g z-($Mt4xf~$PMYCkL;I}1bYOkQlG33 z!H-B;CCX|B^ma$sDV}EW1A@X7yNlk?ch;mWi29oWn>phG>iEn?KEjWTa$w#hPXtB% ziB?A55Q^=QGkHP-?+f^lYE_rqgM^7kj%^WyhS(78vm_b&$ZEKIfhK4+{hj=mCWf>- zG>ZN!o5J-FP7eV#9NaT}YV#Hg<(w7om7F$Bwde{V4h&jPFUgp&H6rAO@`(w9RtI6NKoeHj2Eq~ey_cj~eYg!i!%z5{xJ`F{WmY{3`zj_RKIJs{k`Nb_6^k)fGe?9xX$ddH5gOWV4Mr-q)fi~ z+X)(cuR!OaQRsIyVC5d?5vovDCsri@X{~04;UegU*!?Y%ww`rl~EQlBRo)uF27}(>Ez_eqc zJ&)~ycaVip6-mqtVPg_`09)M z(@3kkfDetcS8cU9p?7byok%V(xyzZi0+a~p zo=tp(uJRs=yovs?aAsGk6c)~!rvE-ZwcyZ|SaBL+97_xpqgH~h-mO!dN;}2wQa#cU zH|MFJl_%#XAkLq0*1rRVc51 z((Q9HL^PD`B@q%5hHqIMjb}YyGRLyb<_4v4RE1{*>XNDAW|@QYZcEhrM#=g>4@S^- z)RG|V8Y}LUXp!}gm!8q-a8vWL`D!H=mKx;6i(^?U%fi0pR4g#~{v1+XcF-&IUM z4n+o^6%_>)lDy3YIr$DzoFX2-#t)$2HM5Gd9q)+wj6+VI9|)dKm;F@b$s$Hd2Srxt zC2%f5Tn^Du*}vXRaT|kHx9@CrYEZKzW`x^(2y~)Yrz`7U$Fn{?%VM&R%RCZCvafxJ zR!*)EkscWE1kDm+IXR@TEu|aI0if**@;uHLDm+%b+l($3`!}6q z)7LvsWxhPw0lEIaJL#po2m5F;r~U@`Z8bnC?H=^7Qr6yMWDWv0;A0ow{uS@71W8__ z%{fPKgC)pYDYKSY%d8|x#*UG``t)~-^3;f`twU%zX!0bu{HgQwOIy6j;SJu}Lo zm1>hDBvHt*IVWM{&}yeBieg1c$I(HN3`tVk-HFm^I`v7v&4mXMmY`}9FtqYkG~|Gn2{pE24& z)O7wv`4K37di0Qdp{UUU!7Q5NS7+gB#21=GP8M`20C$3B9h^biww~fc z`};?E->D`X?K|chK7x@e%tV{tjT}P^uXA%M)zLeckBQN@c1C#pUCQ#h7b~*HUffRz=9dM|<*FY*jBMBIIZ5 zJcf8T`%NDDL$BisjpkUZvI^KpJXn!v=r-dO!&>x$4GgNb|Az(%*^h0pG4&=BWRw>h z(^h~Ci53ikp2?;RWc%BajvrHm%w3E$;N*hGmSp{{iymug=TsVdr~@Z7@5%*h^!*ez z32HgD40CUYKMR=5TPDZ-Z#3;&E6ZE2-RH=L-y=k9wxQFzN#ZhRjfoCsnakQFdSXA| zBL8-wCT%$JDQoZW-2wcx3{f9Tc4rguIo<zQwG618Wa z>;5eKm810Dn?KXr6SwfTybcaQ%)o@_LiCAjMa+NT%N3xj<#O~@$%}-oyuvS{v*VH% z$MylFZwJ|U?nIoXeff3vmyN=5>t$Lwbv{T1i!z-vXb$>)?r5LB*|+fZ(u=Vw>(Q;Y zs+B(EI-l$Z5)y4H|&kG~2^cWj~+q%ol}3s6NmgMN=bu_3fzLtlVV9~gD}{zDGi zWs^He2k*aqASA%4;PT(0&HN6)?dpWrk8d%5qo847eHFXj7$2*B^ zlzhVi{@VUX<;YzZn*3^uW}Mn$PTGX6(SdprG~zP{@!bDLBk#`x1NLYU0e7kU6!S%f zEa0(ZyVv4Bs_uhHfH->#32FE}AOvi#pe=IS=;-(;2OhZzSLwd1zrQ_EZ(-65CTH~u0IexF&j=;3Upli zh(}z)`N!O#mLA)b;Pc972gv6FzberKCIKg#s!t{e9q+%wZ@8R(^9%K<-uA)LjlyU| zxz?tRn^j6T0y;8R7I&KL<$0J>g(CO<|IMd_aC`{=m?0hMa8#Kf$O$=oj-MpBU1Sn+ zr>eW3Vi0PdTYXJfcRF|aJmw|Q`w5=6J0X}v!fvcad|SPw{lj3D{D0G+qM{SjyDzt- zsZQ%Koeb*eI&jkGYH6YnWr^eg`yu!HbpECW$he;4nyJgVbGEh=v_7h^$9&WvthO)M zAHYrepaFt#eXCziGS0vtJO;xLi%2b>{Wkr=AY1Q{o8hgfc=_ccl*QeO8xWW$SaI^A z;`mwwoFZg~jJdbVB3q|yd5gw8_YQ;W*cPJo$hE(OS;AUkeO=QWuVfgqUjDclkKSLy z!F$hSNIRTL%G^!fJC|QHY9@$f-nGV2*qnp|{lMFid6=w=p1n>Kjtog{cu{{J)~nj~s+{#rvts4vmNf(M{mBlG@a&F^IW=k%DtO^wi%Z$pR4Tu0z}b-Tyh@a8*R7um=pR~ z_^2tbD7I4mEm13^TeO;8pl!vz-U75~EDK@^w0SNs>B9Gu!aEuZ|2n=b3L-3Bfi##V zG0rs25kt%}KD3-rrMyM+**=15T(i#px35~Gbl0W47}r=yqiFL;pvt(_Y~MX5p`PZw z`XSrnBTC`t^Gh?dlEqMrF-3a9Xf45!L)AF_+RTUe(nY9MN6)J$2KIs#Uc^bgDd=Oj z6G>&!uvUPUug1r6mXc1nF;sbC>k89)J3pzE*bF|pJLM~fJj0mQGuJ%|eIBW9CT)95 z^P2_DRn%XTobeKaj!1Tw(_ud%?%&1L!qD?5W%zl*ltTPLGAwhL!n9uO@%u&P)!2>7 znzZFIgYRovi%#806Y|>j&QTNhhcNi1Y|vhGIl{S@^kZUDcxo4qBTVkD3{C4s;yDIX zl4A*?hl-f)lsEJdJY)nrc8sqc_U&0ce=tx81-JX?lVY`xokx6ibomb8hqvl|?c6xj zT_?Qq8@k4QTsr+weZw+zNb~nfZ;G`>um*R=YSf9aQo74)^TbSEdyj|10ISDOxAefg zh7-Ao^^s4;&N0nrtxd)SU zr{Sf|^uy?6hcw}Q!`Cjr4!4_tmUnZ1FDd^@uK$4HTNidO==FE@&xuJ5c4CN?K6(3P z+W5=uwf9Ksera^B&6z4{)*SVBAzZt2y!cfZx=e8=m{9|#@kPecH>M`i zH@E`w1HQUu(o>vs?`UgqQct63y?Mq@So4#0mTAYv-|%C65(8S z@h9u@BAo1BqcEYn?k{uWjg`}graSm|Q3-3FqPSb-+NG4jp;)fjQ_=zij^^25kB_U} zDSGf2IrOpfYno`}WLae~OCNSB@<%4!tD^jAy+x~(iPVDoltekzhM|b2nAdpuT==Ft z*7?560hxd6j+rBi%~AvZcEH{vE#uLf`JZGfKtvXUqq{B`3%p6-_%6@ z=ieLNRLR}vj7n3n^*=vd_AD=qF6(Gf;#S6=m%ZK2mJS2O|9CUlzMPM92JI1X38H-=S@aH=$+jSu$gyI&S zVizR4I1iz4F%CLeZNV*XODym!?sj#$to^S%C2;D zkIc7*HePA9O_WqKq;V8{<^@7|)@yM4{*ki5mM}FZVW@7C# zx;+`V`6f81vr_57@JAej$7cHdntY}YXRbhcrGDY6ap`_ND+A5SEvlLm9Xa2-y0XyiSa};?mQTLJvv6zOz%Ww9OX5O(0i6_ zJgDMa0i~OR0nu+O6*vCwAT#lbpZt>~QaHq-vUAlK>jZ>A5 z`f$BosxUBd+nSGrveE}MpxvC>D~Yt4045Yrp?h&}bjY(k;vDU8>H20uj40?+^)&pf zFg7G=^Jq>i?D=X9HVR%g%yAuC+@1(){)fd|Cbt>UWUxpybJ7w3kFdSbZ$~Vu$xD;` zSI+A<23Y#Ec`5$-q)VE74`qn+B;-E-*9{>Y4)_k|uWZS@h5!R*I9ZYLI^d{uISBma z7?2j>AF<}}%{`x?t}ViTJsC&%gL;!ybfTv87;iiW1->ow1rX#nC2J-Q0QWuQ{YhEM z&vDKuD$t?2e=uG$JtxBJv!zmMAoMKvvVWUC5|>fN>6J#M`(BMMm!<6QPpP{^Raz!c zsX!Y?Wbg%uKo?+s=P>IDHuUUUrWxnRPKRM4i&c?3`t+z2`r)*D9Ioc)>u0I;Nb0BnA zTybxRFI>(rYD7{;z>h0ixrk;*X&XK&Y>VHg4l)B4@_#V`Qn`}} z4b1jCIE3F(QQc$xN6+7x^YV=JFHV*Qz+Lq90vz)J5nUv6Z=L7?J(QMdf=s=$mMZEj zEpcPz8(c#H5+$^Zt*1R|k2eTi!jbt<31*>LA>Uy5YGSz2gdzJD(Aw+8R9R0DPFHCa z*^iaSsJq_#la?bCj~EMoWc2TBi};R=YqVV9DUZKE{Z>&8&+HNI`&QP-wm)iU)6?`@ z9yOdr$OTj#l|MMWL75kD&iP1d-g;v1+-o&t@~K%2&4*_r&Yr&`OJ7w$J|=&B@h;8o zPM@ku3Kz2H7vr;8Af>a!@rgSr*Bz4XVAsf5ro{%D5A!Q%$@k$)&ZZc9 zFXIv83NUNPAZe^*{qLO6=x?dwI-`MtgMrm8I*j5Bl!@ue$;%aX8AAkJ;cH)Scd=`> z+Q#^!Kk(#KX?Nbk^eb7?2<8VHv9C`b{Ve?hbcJb4v3`Pa@_z?}!ST^v_!?vH%jCFi zjAB$%lj##?I~EFRV?NEI9TifdGmP4yLgldwp+^I`OPa=gx4wI>ikpG-(|n%Lo(YcW z?$^&_SScPJVRbfd(H<7ij##;Atasv8tFQRe&_})hG7jw(xB3=K4rxdf(VyM8iO!XB zSh;U^>5hx{mru6+tajCGIr>0rl{!Zn$o-T$yL^qL~0 zBz;czg^7EW)YSve9tjgVa8KLU4Y;2ore|x8d^1|1ZEL3ks%N{Y3Z%2!^zxxOyHFcmc@1PAp;DaWuyGUxaNJWz7lylt&W>*0^_eEDRKra1}Y_b&Xd(#R5 zpU8XlyR~SrF52ic1*1zoBnXI;Ya(Ty{a%+8dNfeS$#Yo!dcinnN~@!;LrLYT4IL$y z{vk)${RD6(AcH?tE%SE79E2j+iC}sngXb}mCJA@e_#NQu!XO8V z?DuNIY1M2?sQ{KM5b_9$3?kWT4c}zX6nr@=s=8HeOTx{U{2i2;jkqiax8%8Rlv|%( zA;iwCMT8&-Ic3t2wSz{Viyk>Fjxa{nQ*w)TK{>Wa5K!GB13c@O$_8h^n`fEC^Rs!T(${Qa zhUA1BzNkPl39nc|yIeVgv3d_@!WnQw08*TNxX$~f(>{Q&_+A{ox4F`d5@lX5J9F4N z2;A9J;^9%_{}JgR&bYib-D5201gC?pzi64-FCSbY-GbC-Bd9EDeE0Z>c36icGXU0( ze392hsSv^T3B=IdXP{5qI?lC{=Y4iph9rzU^UP*np??^DDT%P{^0V zwjj-KYWijMvH5=tNh>55wy6^?57K{N#}eg*c2`>?osn>y&~(N^k`7bWl?C=QXI*;) z5#Ik+voZ(?wo3kt%Uhiar!~X7ryqSk3>~V(v(Cc*`&@hrEQNPI?a^j>4x*JZ&?z-> zkJzXuAUs|92wc{PPp;BBXQxcck~1RXkl3T^8qW&k{XA9kaGt|n>V#XG#Z3bShm8+?|ak%K4Nd5N{z;3<9G{x9^`(Ytmv+8(j_c&$J%tVOFniY zfyG|iXj1yWhnG80Tah4{;UvHPRZNjCUHli30I2sNW^VBs3&Cytn@vG}FW#V+)n1VM z{dE3_zN$#cxppZ%VkG6MA|*2L65D?bc zS66%~8qmE|dNTgzUvyR)a~G3;!aUUP{Y^3=sQqJAF0ze6QVo?z&%6p+9oCk`^NFfbJ4TRCl>S?nh%EkHd zqi;g!%vIujn@u{48we~gYfEs(AE_Pkg zSb$e!t5rq^zia^(k?rR7zwMPF>V?>f2kL*X99KtGhlBjrm@J1|Sk2<%nKW~u$0O(0 z%pVhPv3nNF1-mcn58vLsEvHZBBhUWl_b~K&)bOCQX|p_g^XSS!cPriT&c(pVj@e{V zhe-+0EN}Sd7f#*~TCoCPR1k)x`eN%%+sqE5clX(OPOrE;?IGxZu`I zxH#{SBQxAFNzYt{Uxq^s=Yt^nr}LoJplMaFs7>zX`g4xlVzwwk*hCimwBL=-&zqjz-3W#VXIt}&hh_>rP8J@a-YwS_JD0VbS?45x z*HeeeA~LD9DOVf2k;|6QW161mv5oIY9g6+r!upttGNhh+0IFV8l#AwzCai$qeSKw= zJEUd8TZ{kqcoB)RhY>LnGx-pQ&)hIL`^TO; z0+r`4eA^yz(mTRVHoCHrSP}cFT*NQYQClUmT{>K8$zzTFSz{)p9(|?VfeQde24Ru6 z{UWd5UbCIoc!FyZ4kAATKYE=?vgk{sv0k|6NdApI1IIaj1h)-2JA7Dt8$nzt@lnHz zC{;IiJDJYDmuu`JRsZ)yx%oV5Y|_#{17%o+=7XvYj}W5`pTm}%Z48ZG`zSm#x?Joo zUZ8_)o{#?3ZfrUrKZM_iT_$$LG^Ik~+n>C2mFvw6sqR7~;A)2EZkXnq8qQerAoQez zA!Wg+=G{isBGPj0e&un5D)(T(I}rmBk`3fR1KzGUx0WJ(u7>uJa`M%gqJ@J`e=g*o zpUKMQQOt-fpEl`?ZH@nmySFJSWZs3nI+D7>AvR}dN91j5=!$KgrhO-`sjoqw`p@!i zrULslW_k*veRnqEKSQ!DnP&!vJc)L5uRT;}I+F_$p+q~;YCv~80c1LP7#E2=EBxIK zFAZQ@vw$?Z@TyDl5<$3Rom`~z@HU2X zGk37df%Pbj7#5xp5gymU4ZK-8^$0g z0TMdr2ENu#=f77Bs0stsLAkeT*sn`>OPQ?LNdkX70=%1?tcD-|1$34z1nApsk;Xwb z`f2+Pk*;R;qfs`#xSA7NE!kd^seIrTSgV3JKP#;pPt`WAt511*?2vRumct;%#@SeY z|By9f0yG&dSIJ1~p-Ghxa-QC(y}I2RvauPagC!R2z?r2a29fr6P*=5n;}{4H+$hwL z(y!!Hspl9a{^M(J0hhE}2*VRIr5q9fxu0)ydSMp;T<69urI`wDphMKWpw-;at;o>x zMsjAarkxlUbB2b2O6pm28RusYc{c&QvMUuhc{o@na?q;^o4B)j=s6SxRjX2oE!${2 z{XDk#Ql1Z=w38TLqAZ-6eR@l)SGf`MoR=s5YWgA{O+4rIpZ&q4b06wN1GYBCUav47 zgE^O&E1{g29cRg)SC-A7`+aOWBQ@YBF`xW^E5oA5Z?=xePFal(uQ0M|J1Zo-M^e-= zTB8*pubTMk0~0da3EmZX8>CfHnO^CtH;O+^zXh_}`e$FTbwu9-eo(z!asu`%S4|i^ zYqv{7ZR+EK-9cM8ho4efh8q1XzlXWsf5Vcq+NPwBl)ke+%a3U%$Vu>#ttkT>?$#5b zFjcQMX5!8t=X=5IE@df1fUP(UEguo`PLHb4hT`g0+Uak={zJRF3+UnLA!3DQUBfs> zhTAO_8xt~>IC;n87Y*P^e{wx;0j0PTzfWi=^P~Hw$OoXmK@dOiCiV;M+4owC>GJ7W z)So^7oU~u@FS=RSkVbb|oc|pu;bbh2@60Q^`riQV;{CuMkpJ)-o^1P;ou2AcbMCNo zvH>{xGn5V?Hz~coy*Ol1jfvMw#XHVSVDFSEwDvR^oMusPy-~=i{+aO7J2P1x&@3^+^FPGkC2U13A%t#F1DUGaafwM$7F1x5rQFX9Q&zC<4W0D7j3gtU0?^}EpIB-_( z!3*BcW*_h6Jfi**CSGD}EtZJj`!(G%ST~gpb{|YfHSkXJDl|<`@HKd;1T*?KSlwI{ z<|_y!yNR9~0Zu9@SN?REBQxL-p~6 zcCOre+=|DrP}xlpj|m9joJ1DoF^yy+^y9dz+|7&5jFL09-pc8V<#^F$GMo1y15-}1p;IQ|l_5do&*}R!OPsKb6-OD` zermx|!WQk=hm?T@rFL$90^V_{q!9O6@2wNZUla-)P*+H9t61Uv&wwU=0?|*55+^B2 ztYt6VD0?eY1{?bMj&-h0;Y|N{^>$C-HU7l=r5Ft(8~O{*0r=y*wZW zOws*&l%YC1tl3w={w6iue=w`7BdZ?G5}ubTXb z3G>TR{5*g1&poV#6p)8ijz{k=;Sg4l4hYxZ|1amIU71rxM|g!ClbtZBvb?`q!Xv1M zWbcOM-&M0K)(;V4_^;gS*zCal(w`8gm%4(sAc2OaCq~TF8Dee4_FZq0&}4}xft;Y* zIJBy6X#C#QhlzUc2Q<|E3>$Wk1ArKB%+*0SuTWUraGRE-1H+_(s30qoaU^td>4kV?pRmd6RM z!~t)Bm~Na+51}7CO?KW&%NLK~c|%{=@p~n=ZI9EJz`GbCsoD}lc{OI@kc+qZfL1@l zRwf$qo_*pV8E2Oj%FW29Ls&L`r!jo&_Z#JUv4W?yS60XzZAS|}(#lm^ zmhlxnFhvK>$Fe9!5(hE=GD&^ClMyMLGv^$ZZfB3p{lm#qpCuoD%tV*=&o%!eWU!ww_AY?jZE+RE zeebop!o&O7=)lkEQl}ye>jvl1- zgXT}bjac66{CVw3?g!=Y8 z{gUu9)4|djpxpGIa2H2Gq~@xKlOaHt!rrvDPL_jLerzi!#vegiOX$%%ThPDB^txTI4NV{Eu?Iiqpk*K`CdBAo5>Nj}Is} zN!6gD=(q7Z-H6cphn|d^znUU|Aai+!Hx*hqyt;&LVLg!$=5>ck*g_~dqYdsw6~uZ) zii`$IEY&c)VTMNnQm94;AOKu%raTV9vZw-L9>{B+AYz$S55fIYGas-whLbMBc zC;sqr9Pjj)2&p*+zc^ntWn4MU-k#UaxT5kNTca5SzF;oTw?j)Uq~^I6uiR9LU!CVp zESvL_Ogr}7_lUC*>$UbTyS0Bjkai9~i*)$@ePLIf=|;%rvu|PckSed*Z@;n{nyot5 zr-~ia1&ZV<3Jbp-zd-%E@@{Udu$Dnv&xqnqheXdT(I=JYHqj*66f zAM51~*0S}(s`65s0lTE`(0xmwX(G?RepK~`^)ZMajRg`Rvjr77UoQRpCyeV4{djVA z1-@YE7f`6-D1NZxkg4CM8D>->`qrAGxWkZ{EfC-rEqJWmg?~tySUi~51yh-GSbTn( zl20Ubsm_sNT?Xo;Zw{!?(ctMh_QwQN!~#(pQS>ClAlV-_p=`eA&Auf*`N3KBFUCEQP|s`{)Fm98CUF6I7Okiv*79h1R~C_-92%+)D0ctFeLx8F^rGVL zTW|}FHa*vVP8jXS%_sncMCzZSgSKRH7~QI^Ae`#w$);ZB7c4zkuh*$5+%K=4+gup3 zIUUSz8yHGPQdibDpszP##;4`p?=WT6@x!bTYU%e^6!rXVB1f=_0CKpF^teUxxsC8w z7QUw~WfT7Fy{pQD#JCL@NAk>43xb-w% zCrzCGgVx#}KPG!NZWzlS*iRyiV)4P^N1Q|ot3#YE4ywk%Lu5052plGE4X54$3RUvn zd%z3$B5b=1!^YVQ7Q`bFH3nBmWT#8Ye^VkFU-rVea49KLxvp)TNWHp&BYQ%=wapUb zklCGfLy39cBHs(B*ypIP)q1}b?;`v!DI7!>`D4oPG7ItpGNS+D-ueBGa-l@z9|UKL zY(8lp{B--k7pT%Q4e>EO?p$f7S?R+)($=Yq)_@%rJur$9dDlAmZsW`tT-^>>^|f@| z(-C?wK4Jpq$sSNw)TKmA7i@A2P1cc7SI7dNK*X}EIqN&~W&kbIW;jAzckL{883qpc zjm9~yZD!A*0jGkL7yvyZCRhw-$-#tVUtsf)Ubf}1K0vPU2({It)HH9 za>G>4Ya6MmMZsu@C@DP$d|CR!AM#Ab*Ue=A;yoEod75OLPpwrtktqwL7_S9*i~w*x zqG`_y3CZ_cHF4)ZoYX2TAimMKH$<*6YUFa$2*MHk7R=A9*!fZi4^i4o-aCiWSOyXO zfIWlRDf7|n!vA1PGd{qB)J*xBa1(1H!hc}SBF!*zs%YuzD*c*bVZ*LGR=*LmV5FD0_sVb$a^4AygiGedIR=+ zi@L~8ffkMgs4*z*5 ztIs)^M5n>(^zV-Nq1s3Cubz73)Hd;tEC17&u(i zCsUH=tZ@%^YLjCRnzmiMM>$VP@8($4Dp!r+$!v}UIyXdqN9&`!#uhk@)D@;L88_gi zF#V&It7~x#TW2bt#k;#%2@fb?t@XDVbC?++) zpYoi`AajzW8}Z76cha$GgsdGStR(ioadVJ@$_;;ROyfaW$dMT<^?cmb0PQVp%e^cb?JdTp11~qB?7iwjPDcJ{V_sXN z*{jWff@3ySV?NM@3(3uKc3A)* zY4Y>HZUWzD(i!Fztr>N9y35Z*!PN-2dJw1C%a|lrX@z!5V?`#=1Z<=#OejzOexyO(Ho}x7C80Cst)OUw@CuE9eax#ODu1*+LRKT)|1YM$l zF>EVTU^%#cQMqNLq8gSxmI*^x>)ZK1(#=Ni8M-gV8oFFJ@qesw^7koCzwK>RX<)%A}oP2yTNQ+I77ECFA;t?^K@n$%!wj9tuw z<2QJ5d@q;3Rny52^_EF|ev4Hq;5$ zdK)HTc3bYfD*<@35#VI~0l2I97xlmHM8D*2`UiZ;t7KfdyNtZa9-q>z2K(W7-d+iu zo;JQnz<7%x10jZ*x-F!?->AW1{@X&pT6SFy*)d!oc+Nh0gB_u;BFV^OQrJ7MS#$X= zkmn0}eHZw3=R^;lT+}b4592%~UQ(YO1K{k%dn+90%S+suDN~i|S5;cW(Yk4Q8J~Rm zE9VGprwxx2=qh%P;o806yH{zN+J|o#Lj}PzQXSyaBCZZu4IV=3MUhI?;cw;EMMp`@2|vN~J=!{=Zl&fOqiA`@i#DnM32o3>tm!QO zlE=X{>Zq7VfBx*!%=_p~gl&AB)ECdp&O(Wc+otW5^`gLTkroSi{v!;+xou}P!jXci z#AQgmw^s^69k?4fI)9$eLTUa{)vEfG$$FyhXW9YwvPt}>NqHGZbGeD<{#n}|nnN`6 zP|p#n2UkX*)OJw*4vcnh&&u;$YH zVQP+UR#Vmx?lVxDCr%nxN8);?cx69BGZ$SY@=R3`r3AfUAKyyAqJR$3v7++2X`ISvcjJlD|JY~N8fOiz3oYkO5YLSTc-FRGNFf_e(ZmJz}GD&zWV-Sj&#WHfE+(@``F7S z&B4t_Y2RCV_$$`XRpHwe*zIinoUqrn6t%OyfSWckS9}>+nST6_;>81Bmrzbu!{DmHq5P+=&yPf*{b$d0{RtjKAPM~w4@RREVUBq7!L4A9?({;!&GR$>6n>-j z8GJk10Dwustm*+dwH~ye%gLlBIV=L*hvdBa_k7osz@n1U9=5;P>ph)1P>nPy&}YTjnAO2NcvT_sXHm>}e7FNi%mk3J0lq zMrxiT@OSIvN1Bi_NMh@9SEoXWvin7t>b5ax;2Qo7Cc<4hu1c8BY#`QT`UV3=_`b@0 z>Yt_Poy}S5i>r5IM#-zZ7Gne9{|ee6^==E^kfN|p@x)kut2zxeQWHJK`NJoy_E@kO zPY}a(IYcBuq8HK~VSy<6>sU{={AmW#w*fI18ag%F^_8 zBggPWJeOx8cz0E*&w3&M_%4D`OExBtNEY8gk5kbz zu)~zKj!`YR5f5W|Ix+~XwGfu1%3eX_)pFKM?Dz%E@2*KNBq%vtzI5*^$gDQJD_0?UTkhuoaWgMh1 zp%PML@KOZ$Zs@T^d!g?)3u_8SuK3l+w;pHHE=_wcVoV)Soy%(r1sPjI$~E1&N$Qke z5fW2IKY10?v&wslJbUOx9$ZQESpWP{*dFFA=*^qTXzuVJ6Uu!hL!;Vh@}9h; ziDO^)^=n8jq01*dn%QXkb&%@x7p!diD`s^vHph`x=75%o!o2%9cEPWdZyz|1unyDE z(lr56^L}HiOZc$z&29J$i2I$3vtRj^`Uo->1b!SFcfDt^maUy6Q#G7M-T^L2HnQd4N*+9@{I?iOo6JbS|+{RVAH`rflp>Y+bEs+2PCQI@HM-KTr_iS z-@jn#3zql?X3@qAx6xo~0)NH9dn_EZ!85Pg+gVQ(+A@ycY~*4ssXB-IaF33ThU|VG zro(Q2AkXwf4KO81#jB6JZ`C$rU(;+9mg;sHPgs}_rcg%v{9MKZL|@4ADmQ!O`L?8qaHVENggxP z+sBrI!7XeOZ6}q$3f08(Sv@im^`#7IE-NYxFj5Xci5qdXJ(_@D_zjIR8$Yws7;JEY z*nx=FI<=wswv0`kc~!7WH1{gLvN07>y#>-ZvYbh>?L0}L2ytYE?SN&rgp=m9rDF!N z9R4;*i#TcA{1^8kms{~O_7(7j{cUoLa|J&G+DHLrFzS|e0pLtBwE?Rq$D}iEI%Q4Q zLJI_%?v94)z+oX0g}N@p){X{PW3qvj8eTh@7MPl?P+|Wx`G1OBmR|HrKgI}LVrnDJ zpVI?#;PA>8MOKeuZQ zQ<<01z&Y?hSLD9%fy7febnfp)6&BgVmC`TDPP15y`{gg-@tLLr0(tGgiqIEobBJ(q zqZeYXEjr9WHc+-NakKVMvGBL2%z7D8@{S+$7g@@HOJ3HZBT4K_lThV&U251{eVopBTsYDhKixJ$zSpeUN4chP+KIn;iMeSc zam=+`HS&vN)<>!TFr+G1Jmr&Co(KY8;JjvH&zK&CzV&|lr-*M-uMaLL?14ol|yF}rrY3ayLp^y;qQ9n4zv^s z6~{AR@arVHiH*O7`SjMq73#3W2g$2 z<2@=NFi`SyAMfTMPI}54Ht+Bnbts^GS0yO_#8GBG-76p!hAsi!i(c1p@7!Xm)LjIA z$|Ddm*gu*n+KOKzb`zt^6;AB3J8Un|-HQrH9T@S1NBq22PNgD(vbbe?GVq~0$Qp;| z)@yncwH{NCq&aIj4InxMMH|q*((?{@Wycjy|GuV=+e10#@=x(K57nprIR2dR%zMr+ zU*JzluzKx3yI8hzto1>}C-m_P+!Vv}z zUoer27dn0Zuqc&ao~(CMyEK~sVs@h6Z9z7D?uNq!=c8v+l9H4yWyUPX{q6p0=%NUI zD*7^fF_(IcZ_=Z}FF8I1Z%n0+8E#y}GcJ#B#P*%~VZ+jT=wgLf=tP={unt(x*}fPy896e&`fm(~!T?6A+d)F)c(b39e( z{+5;^Q#wxsJe@c;L3;#e%HbeN&~PcFfCzlmFT9oJ2C^(6VcS{L4dx0gHCj8Rxly>R zMrFfB%w#m?l$c2=Op4HS6NGITVeC@$9>q|#u4Ild{LsHP2B~#Q(OWIe~tAB~s=^R(~xnycJWH$OxC3SMOj3OWgV77={lS(Bqr9 z_0~Ncoi7+B!@39k&3lCF*3wly9pE(IRs3Q~eeH118*TaY1on3tY9pJj$aor>Xy;=U ztTh6w$u7pls(q7<+&S--Dyhp%cw)Fc92G1~EQo_0Jx=&B`e+dOfq&aG+4+L%)1iYs zlA(`S9TgB58WLsqt_&5e#l#ksVrO3h_Jee3Tcd(pn$o;j{z&lcA?1RKsv$3!8CiyR zG!OzVyt)0t(CRwpytqD!oY+8xKF*@$2ORuNpA>S_Ri3l7ch9rGn9+r9c(Nb*k4jEC zw}dVaM7lX|IKTc=9cIk)I@QXTBOw3)&=F3Dim3Ev*aE7=u9<9s8&tcR)_u+i6v5w{ zr>3Xp%b(xIvgvRb)^9KYv0K)d!GZ82oe*dAuaelrhw3845mF&sIcP{T6FktxhW_|H z1HXn$Kw-5KmYdw<4E^d1ogWO0F%MnUOn!}?C%+Z4u*)uN0<3TO)x}2jc>5=wAuP)4`7k#b&c`oKpQf!pZG@3y2&#Eingx>5iW5^eE~u} znfvlSgBf1Bg*s0V@c1(!4D?W4=Chh8+YUy|m37afO$MtM&-B{x+eD#DckiU*SJB-S z^ZN@!k)~gZp8S_hu0{K8K2lr$HmjTpJ;#)?sQMu>9Ieqew$|?fO5L+mO9(MSI}w|G zLyiKw|L#)T#&Vg$K?gh$cu>k>YLFUT{`@^VTHZUw;ZSr`DvGYKpv<2l#&p>As*Stf z2D58V;1^ZtLax1$_WS`wPqSrum8zy$A%~OWq8epFRsQnhDinx$_?QkN6Q>L)2Pg{T zyd|=E012IICoBzA)&4S4P9u5af{^shc?zu zvtRy1E51poN%&QKk@CXy_e);JqOE2lC@M7D`!)@@1lspueA#odJh4A?UB`yG+ScjJ`_+M1;>}GclWkK}6g49V z{fz&=7jQlYXj@2&vNf--GrpMBo(&kBNZYll^6->wxqJz zO)izl%KerlxkRN%$Sx@4I)z-)CYQ}+Y%{yxe*6CZ+vPmYIgfMB`@CQ8=j(ZiS(cpJ ztxOt``S}?3J8o{*#QL*7DTCC&;m=@y*R2)F)yCN;Tn<#Sx<%)n zDcZi@k@FGq>tesgU;#qjd{UbZ*sGA)kdu@QtxQ#FUkZLF`ppdO8T6!R4m1RMeF{Ap?Aq>y^ZA7yhaMsS@`mvy4H z;>A)73wc{M>HY*!qli}683iZ>yY}@c2J$d3V-4hfGvbZd!8*cd73R=^?3)B}IT!nD zcGKL0Q-n9-iVa!mXO=~2W^QRfUHEwB7}5IBsncy!XAGH4e` z!aYAMqMaUmfwxpUwyP1Bk9ILU)Z$%|-Js{P zuaa%pD?gUMOzW=sj*KC`Z(uIAmt)Sp!GHcwl+)hzg6?DO1dWwy<>}LNKLwf-4k5|j zDT>34K;Dh;TJ#A4dP|;uTflq%c!KP#2BhuGyA@1B`|+<50MhQl-#XXUT|(jw=!eOj zQtHM@kF1}2@II~Fc*~Nw$ois82`~pU!DtFO30Ksp1m+PxLDr96p!#Vhg7wB+4Vx=E6t6|NIe9}oiQ-ddwmp2V?uw($c|b!yQ& z_|FRwRc~lOUK0UbxRuH5RoPL6~MZZS@&zsXFXPLTGO+mx@Ayfp^E4V@~ z*S>~=Xz*wI0f8l7R*}E2B~I1qMl0{C?hA}h(TT1R0>s7|KKbt z4HRw}`DO;&8oL(-(fw@+b~jJu)o8=N4i~Gkraw(h`%AuNsAJBfApO|Q%2_|yn0+T2 zyd2wb(E`#yvsw*ULZ!h{^^Z&mLza-(`htU0$E&}&o?y|ZSJ?Zl$|zu@7(v$9MwU?l z?Qy2uvkAIsJj&h$nc(vAR9;g+y5rs~;t14>`cigFO7-Sbitjel86Hrf!~sV}_BUuK zesfgNsBncA!=A4c@B;FFzCtOSuchMyo2D=P0`H!#@$OcJt3EtEg}uUIxGU=`I83h)Cu1v9&D0-)s5@mIS+>0MegNN^GpG z<~+L%p{-X3)x0;^t=h8K;dfp@ND0mmebEI_gElc_{MXCRG>NsjwBM`!`o7(!pcv*2(M z{{4&(B4^$YwMMc1d!fP)FB4++!=jmWY}vK#C}0t&GWQdPq2^}c&O7YXy<1+(1uyfe z*PcHQ0)-oI`IEJ zGyHbl`vZ1E>=pEhraLaZclw*rwuAk`OUe@kKDf&Aw1KA478jPTIiC?!4$*45m`3fH zHuxY z*Wy7paSe!7pEqP?exktXq7Cg(!2t9)ty&C|$qwrXGzY(M!@g$u62HwX9h3iTt9A;u z_c~Dux2vDH06j^fgpF5>tC*g=nIZ|a)D~Y>>{j;GdGIKPj4#2I=Ia+jlAYVsj)=_u zERHoDXv^&sOrzGu?~Fx6Jq-yi^BSi)O8k<==wtXyN81u;E;cp3oR) z`Bzj;mmm&8_1I_nvi^hnmJMLmuzw|U^DY0%1FMS3&EOOLGGf_jZJ*)(hDOuh&`h0N z(e~RtaYzmGO??JBT(j%9iYX5=Be5iPlFv&Ib<~Es|KtQ6$+w(xU##va>XN6j1@=9% z_o9YSupc0(tq{ObxyOXY=HF)!#81n@&!fgVY`F(53)E7q!;NUxgp28=n_f_uvLGmP zCl_T|qA6?JqC-;6|0jsZ+ zBAruwlf|&xswp%UJZBAzq04U`S&^^I097Fz?Xwn`2M3E|d%LAE*LnjmrrXI4tN%Qp zk)R*2=_Ln>X-k2vxXNtCY~NJ_GSGsREin|kA{j#NZ zY=Rr-pslrd8|Ko>SaPO6# zCfnl2Z-+paC0_Jvo0Zcw(tH#);fA?VvQdd#QWIp$W=xNKf;)HV2t-S0)nT}Tb8(~? zT()e$=LLIKn&nIF9N}?47uyz4@byy*3jQv3$@aT5n4$4RdUhY)v4l*POk&=R zF-%7#`+6C>QvW*y-B1i&F#>Aw)_FcVNZORl-q=fx4J8fA&D+#$5T;6G6Uh=h?b#3ncC=O|T+9`%OTc%%P`r}SZZuoOk#vqz1iuaQTuKmdpm594` zBFFXN)TL|<8)wC3aj)cVSDT4Dej{GxSY!-=ubT2@HaDAn;rV|z`YZg6_>|avD#4yF z1_f&A=q3Th`b^3~g&wVcxedJGe03vc*slcM$4p(1t7(@^9X}lD3+on$3zGLF(nq|4 zaSNddXxB=8=3QN&}g0I=AV|&4WSD?$H1dTl^P>(+AN+07AQ$1b}QxJ!V9#)D* z42PXO{>J_3(Vkchze9*Pv18gj;jv#M&Ltr(nk%gbN$yZI16mpq@84XJ(KrD89&7BP zGwZ6WcbTy4U1ZAKMaU#VSNEE+68FqmIGQce>$5vee6zFiIX_^GT(-mkDBT!adn$W9 z;>(ZgN?DaBT^@;U45(iQds{*hly3kn-D?T5c#?K-nl=(| z`4<7K^ZJDS7yG`~pVAVXeeSW30XNPKBL`Fs_#o<|G3m0M;qqcplHQJJ*~^)|tIgKL z*Fr;bY$hoLdOQz?(M~cqWK~a5Z=6yf1fvbgT2h7c<4=@|iZwRn7DN zDyZXg=rprQ&(Jd&;?o=BzY@sx3ux0pRaSh>cY-qof4LZX5W3YFcKQk9cL!mt+93M* zNP^fmDrFHgZIm=IGt4Gh|AOeklhKJ(E1E}j7AVA2NM)&H7>+1TTBl%P0dxbJ*I)zT zoG~Y=Em&K=t~^EH{ac6cQ1FwM5Oo=0|0&?aT<6#Q9C^rA0uWLVuPMG&K%IH&&ApVT z3`^4K-ESN0`8E8QvLZ+=Z-;-q86c3IL23+slNj|aTZ}43e-Z>ClFPrEd`Wx8s>2Gt z1Gl3}(C625Sqcgp@js8<6a5aW$wDmTG?GFCibts<`-VKJUW3g9S8jSF?TCc|&!8Y>=@NcF(u{dMemQR{5~-ck z`K~>nGfQ1kq-;#QhR@|?gg|TUp-t_2Z3KXqHm$SY>=URBoSvU?6$1KzRWe8H57Vkb zop()gR?ookS5%ODA3stjY_>O33QK5<0*5OSReyZ~Zi&t-h97UKNwh3M4ZlxZv9>ln zT%I(0VP@;MfU`fydcBTg23}HRb3!aP;v{MIf?uZ$@a?D$=D$d(jpxF(^)L(WQpCvw zZgv~|it+%67b4^5L($~ToM&uV#H`3+*S%JG)p|hd{*T03%1Ei?EZg(G4J_is)}_p= zd>!S@*}nIU?h3An#SO6Wo}ksf-q%9&Wh$?M0Q5UJWib>v!FWXV9+b%bb);-#z#26xAqPFAY2V9 zOP18PIeSY?moS+D{_%pcQApnIHnqy?h7fGW@?0=JDe5xHDE@RNanFg-$ZNELH?Wn9 zk>IZ!)oh}S+9WmW0(Yu{v3e$-`ju!{y9eqBetrCd3JE+k3@16w4INFNmE%hvLW zer8FwrfI@f?D~F>i?T$g?7g=D^T4s`j@|3|M;Cie%Cj8rmxy;{P0KL;S6R}y zs~X`IAV^y|<1Y9IZ^96R6nnyy!(Yj8KM$GuL(N&Zmz{ZJxDhxU(8Hvdp@?TqraLbl zXdIPWa>i}%p-4;0q*u9v3h-awiZisOKU^Sj%E47}au&UAki15*M^_rcDqjv#{Q8$! z_Y-z0TLiM-Q&;U?o<5^e>XbH;B#}MTM~~!g`F1ozX7ArA@feMgiKs(LOcnMD zeb{TfrbTWkDG6K4>hp`t1r!T%lBFgit~Az%9nVSsl!3Kp{{2F$+s2}3ZX+Qfuz#ok zjoTqfKAB0F?){)XZk!7AQ2C-d;pIn@#h8oL?kk^LpwAP~<)6^9$q5gGMYw%KVS(#}DIYg&9E#2Tpm=avD-MPbie+7qRUs_f z{5F2oyAU~bYP+)1rgZYd-x`0rKAVm`8~E)}VHEanS4Ei+Jco~LD}}dXPl64;VJH0o zQ@Lf*;8dRriU{0PefgYc&wkJoNeD`G+R%Ap%i>2!K_{$0CR+@xai)Znw9Lpq zxrCGzpWle5`7yOXcDk}F_TFhAS_K1yTmiIF3!|pcYCVty_yjn?7w7Qk8?9zt$7WmP zy-vpA@)V}a!)=LT8ezI=Yley(Q~$4$7R>X%sJqhBg<^fc3gQ^H_oPVVv=}<>-h%C- zo!P|_{7}{gv{(XY0@RsFl+Yxj{_}!U#XkSR*AFjdi9QruCI47yFrBny?w#EJ)l^*& zcx-^C&jfmH<@wu1jFqB1=RvEj@K0#C^iP;VnFe!B1?<=JLNNSVZhUft09^BIhQb6c zfI=0ew=oyKWUvI4z~kq~Izu|FtTVHBYPI?r(@yPl zcxn82F^!B8s%A^(6rcCdSYh{;@qiN39Dxqq*1OA|C$KfOnglXisA`I22B2U)eq02{ zt21;Lript{ormUXmj5muty0uG+r@xyQXMtr4N5-85x#)+)%0)W7GUq)5k_p~p9XFp z>5yr6(4?b{)qgw&w{oYVni*z7_XnlrMzb|C5<1W8^aU1q^at@DOc1rJ; zVATyb*HARl*Qw_K=}{iiDb-Eft}1jUS5TK8Xi>NJU;ZgN?neQvBSdjUolP{a8~& zN?QZ*;E=W4o2c5TU2@D5g}cQ`&f0!KiQ*l9Wh1nG|4rp$lkM&1awA4*xi!Ox=@%KI z+Uk$l_yqmd5+|yfHoSn@kh)ztr8KA9jGCM_ZhLroAAd4A4edlLhkwVw(&^fRTX7Z3 z&XxEZjKF^tli!XWolN~GnMG$@)7z}X)z0`_$`nLd!L8Jv z$ztG!Mgd0B4sWUcnJ0+o3auObguq#-1n?eC&B5<^)Z8 zwp(lva66bPq5#r|_ooC7VE!9jlw|M+|Id&O+)y8?2`h4?hyXc*N^HY;<}3 zMpkI~SQGhK>IWb`qD5hw+8KZuvno-JdlcRlC4DW?wI%W0Fh=xikF~XoXa_# z1C+q&b2-ehY3Zgye03tWD;TyK(> zPt;%G5)YC(8+~qr!>K!#z6mc)R_gSd_u|{`X>x{(PGcdu9H_Tm@$9(SV}POj-6r8q zi$j0k6*@uPoRfTUjF>6Wp9(JOc_cQUu{D#?aG3MD4VLVSqeLDn6sY-qq13evALG8- zISN#FWd>1ogx5bF+R}?R4h3(1pTh;%zbI0q$KfGpfChEenopk8Qra@TbeIx-xTH!j zt`oM&Pd}wE1_#W`9t{A$(GRm=)@1U%{)S}qw{d;Wg~0U_J5kRpnT!WnIfDGXy1L>& zs`A%paEGK*lptcfPzGbjf;D6uS%OSfyUgw8pYo5#zxWv;x$!Wd3HK6vg^?USbw2m5Ss$)Wd;lz9+C#(;Y&xF2`MCyBg#3w;0Czdo+$ zr(ASuY+_v38Gb;34G0qPukgPtf$qpxE;S5B$8}21E@VEP4&q)ZVuex9RdyCwl}gun zg=B$_vjlmU-{Iu*l^kfOHujo^HeA5sHT^j2TY0W0iXY|_@+5KHFUG|r#6#*Ubl1m( zxcf%zW4)%k==S@s&n~>k)BFtEHV55LjyUE7haqUPz_s=v&+rXfCpz`TDq*|n2DUvL zdl#4Xu)_i^T2P(F=Z7kTD+moPi6{qmS*dL@!d|y557e_9b{ZR(Wj&PI7j2L2ZZow1 z&Db%MYp)6aWc*WI;-RA`{L`sLcOTReUJp38TJv-bEb4s-u-SYT^Q82GZa61ZNkjK2iQ`|msDuQ&1#!0hox;rP z%wFz4{L>nW15Ury-Wt>qYBi9w#SoO+-WM7?&TjTo-e+xG+l;$#tmY-V9GkotS{-0Q zgUACo9>xwFWq^nNx9hR;;!=tfEdI^}3hV03Mu`&=qC- zoWU~7bVM|tkQ{s}hLvMeB=#-=;lbAqbR1PaT`e9EB}L;1q)axSL9e<5WT^(LJp7q} zkS{EHM^ceWh42SWDMlMN#U@*#f-RYXw_j8xwac=1wNBIjn{a8cw@#)T&+QxoPwU+w zoa^4Ip!Sa>(3~R6rKJ`3YdUj?hq-^2uA06#Q6X>5v%f^9?WZADo2ZPhHaMkI2j%&B zYU(b5(mz{6a;?r`S#xN6Z{TQ+maw~`0ZVb_xqv??%%U+@aEIq$#AkCLS*den@C{rC zC9zU&GM%0T3sgE6ufZvd*u+d13_aINiEJvT?X;28#0|K^dDsKWIzcxYt&cm*_VCQ3 zJaqm{Ddb0=QKSz4Q>)3pI$kdITOmgR_l}OtiqSNEQgB?!heqzZZB*|Qzd_RoBO#Rf z$XCizcEcCX^$Wb~)CpMTbvF2ZS32z^kGvapN7~?FeFo3;&xd%QuiK5_L7z3mDy$~M zXW{tcT@jIa!)9+=%Gm+W?d50cH;gDOW;MC)z?FR{FI6xR-LJ2~(_DyA1` zs)}>AJ{{uA<-3X~#`M&{NRl=erc&HyIAxXTm|wF_ZkLCRas%JYc`S?4*bdh`FQanWs7vX25hi4{)p*$UsdEwHr}VB zy1TAyPI5vrW#0nByR?;h`?pk_0vS)^S3WbYJMpXbh#r;o6DUI$KhQD_Nhc-58OTZz zrkFRB`pBjxx8tQaRYvWWdZ2YAM!Rcl|zI&t--JVEwO(LP$yg}!U-V0YU|jm*@#Vpk;RU6>(T1UMsM&QH0~#n+|VmI zh`tgS5QBXqGV3I+;|LEp^5P-qb?zz}}Z9rEvq zrVvHMx7dbM8Uyv$L6=ciVbql>oXNth{2s(Ai1t&SzU;}qPxhw8|I;QqbZ(oRZ@8)` zeH#y2EE72*(qeC}pjy7|{wRWx2WgoiZ(>4EX+R?1cfoV`;2m6m^h$6-A63p#l z(87Y}rNsAS$S**6<>bF&BR^?uF<7At%ZjVeSG3b8%OkUa*QAZFj82O9rFNI!_zbf2j4=wTK+zU z2&cD-%Gx)(xm1L&0L@P*;rR>Ca~q+lyLOBR_zQ=7hfbrOygdB9!7qS6y;DhdRcRzu ze`{9aAl_8A4DMk1=uN5o$BDyg;62-^F6HTq6#F*8xv6OTd#;%D*RneJSFfOHnTF?+ zQVecAV2p+Syz)onjCr*MHZy#X=7>(`wg^2Hr?jD z&MSybz5hw^+X(e=6H_pWQh@{+v7N5ZimW8+=%1+c_PI9F*&r3U3ZH9%{c2dS4YvP% zXL|h}QR$_+55TjGNkn+6dZYZth}Dd)@y%!Q3*SHFvGy_Uc7CnnI?y{mA89)6qRKEJ z(f0Ow*c>G-DP1hNYva8#BC&@Wq2bU842VL`s|W6f*%q|aTo>z4s=PGllk|hi8>^ki zJ@z9KIU{=`h>XGGyEbCCc-{chR0|d?U(G12YuHkiN%mthCq(+Inc#eo=4L77ayicT zpsD=)UUwH>Vk+ShE+_?!aHCPt5UY+{15g8@!O-}IUEc!iHDp}u zxe@}zWX0NM`wDvXu$tn>vIKY@^|ZfXcPHiO8}j*Q-+4iABcxdZwgy$8xg@hQUBgtN z)TNgUIeI}4(i#MT%9^uGSNOJWAN}`7a^89B^_00gK+9;-*>fer7812iTTWh5DOTmt zy7zv~lwR)^yhCIrL-sx{@`su>0Vt zo$-*v?mfRn#$2=b#JxgHnFXU~2INhh2rizZF)jb;*3?TB!nFj^&PtL;sPn*zcY*LL zxv$xoSI}Y+5b|szVL*FvlwKvrC&018p#Wjw! z;2c>MY}FHJSp_vKGtEhaf5mK8)^c0j26BglvK{8>%K>@0Rfi^Voj1a6lXf!$vQCeI z8_pz1kNySN$fl)R+~0*L0;-@FEV{V?_gD){+&8dG)AiHcbKr|~)WuYv5^S1JqDC8q z(kUg!0|mUt{#drp*yQP=kfs=gm#a;K6?DVn@idME7`qU+#p@pMb*<;vG`=g*o zs{t>3anwf|euheM1JEs;{`>v;fiT5xX5G##21|3z){fX4C-Ol1?Ct;87!5}RwV1>^ zFLX|0%q3itnDIVpBtJJ~_Y~KX_f#;z3<|zX3LDy)B*d@@YZBHLj~qqaW_99>*@44b z{%&_HQ#kFJw%=wkgV42d>CE~{S0?H!vP zrX=bL&CbmWqN~Ac7(3-p3}BZQ&CEYd%CBwh>oJ&Km)R*i%5@J{xDp;HSIGgpmkhq* zWB*D*OZFXv8p5=A^#(fX%6!>UHclG!Dx5@0g-exXp0;tDCgm}n%l(X{kDzZq%hi&j5$HxQfh0OyaA}R(^#16`n#1hrRHwR zeQ_lC18$V>B6ljacO}1#OpmRHhxt75(Mvk>D>9`8VTguoB4Dq)pjCUd&&N zA1TVT0XW|W(4RkHK(Osc6Xf}0;WEj;*DxI*H%Q1jy3@wtX{RdQmNPlufiFDzcs2v? zwFP>^H4ho)n1v-bX<7wE^iQ{iQek8}!HQLl&g*ZG5thPO8U%6vDTq!AnfLjWa+hp;q1<5^`s)`0Tm5=>FJ3jcc=jD#${MU$FWlWh zm(|{&ShxHxnqS5-d+dV?=4o2OJr%D(W%gk5A5E?zBBW1;alHue8J02PhAnD&}5ZA@DTKr`5h5zm3^9ruO!bItL1S?y{alTQg;&pqj4s zT-4)lx9RHVJlvQPVtV2)asiYT3&b&6g0&?GSi9DatamjRa(6df9wf%Rf@Z zcpXyQv*Qh5=|TJBG>_0H#-sj{Dgi4}VEamH@fZ+%+@L`@k<}G%FTNY7THKVZ+A2MU zcO`p$)YQ_*gH;STvwKV@X6r8{$icovkXlW1LoG4mCdwGtlI_mj<}#Ui{X≈`?Zq zy~Eq&Y9Woc$uC5wx>vbLI2Ygk$bw@l*Z8veT$jcX{Dav(u3z8heqTPT3}C^`i(EWt<3Zn@XEtII2dvxWn>Wsni~ zR%6`@GCl+J61tg*Wg7pfSr06#ph#4DC|}=*+}_v!0B?PAYgl0A3pJp7dc`(@!MU|z;mnwgcvtJm?t z%k2df8{J16s*?GF?Vti0{6I8J5|Yh`iLYJX2eFczd&7}7{_*$(;IscyF)-z<-|%wr z9q^)QMCEVUxi)T#?4bk^C?pzJ{U>ncYR)mV8Aq?S@^YD?cfqoY;ikkvg7dyNTx8~q z3U6m6aA=mN(NZtK%sn?*-Ha$^6CD4ds@L+W3!;Ei1jkTln1(#;a?36_j4Q`@=uAO+ zng4ME=5HyOm{QryF{y_~aV^UaLDoCDOnW4xuCKZcseywFJro7Cpl`hMMIeop;#ae? zl5AJe{wcK%lMir5EAF058tZ)6F;1!y9g5S)c*G#skg{kMrYbt0T}>p!@~A(5bD zUg>}0E8ECfFQam)S)%?B8a0C%LUS)*y+x{XLz^NMm~ey=CA+>KB%X8(;+Z{G`28sX z)0TSjTw1UjUy$&hp%3RTcldm=iX`Q6+)fhvB{uSz%3_$;yGJhua%PPv*fhaZ(< zx2?S%+lIfcKfIQ4J)d*6EN;{i9W5gv2&(m__uV|?#3kDH8X)IEi{b&?c^tY8S+xLM zzb`>Z;q}}_TP7}GAIEyEXX(HvJRB0Z4vvsFi=Mh{jlJ?1nMM%w;$NBJH>Em0?G;E# z(bw}i#!Y!bdTIDgbZ!c9?k1Lp9Iv;8JKE9TEcrF#|J_l<4v`+40y$zwS| zT|T|42LAJCo%DCU`Hb+)kI2_at8ptxQ>3~~1OvXN+efk0FDm+>MJ__C8yas}M-&x_*PpdRVPDNT$!xg$_ zxP=OVSQd4UE%NI6DxJfCdvI`ke^wDYwO;-!YRSfwlBZ`%IqG-252A`%KZQTNxYURX z0rzHEh%s*9KP|$3axSgr9IR7zhpcyOM>lO;Ci#m}2_AmTA4`sNVtRh?Sqa)DiNYtN zqkBMyusy{T-zCMAB^zb?cCml`Ac?lC{FBYGV;*bHMOqpHV;LXHe-s9l%_1iG_== z6!pZgRW2t8xTmaAB_;RnzK5<$#%@y2yHRrtRzlLEfi&TT7JmP6FLe`8#RM2`_`4S9 zoi@Wt>Bpu|o~b6A^^O?PX@^=o@$e@9u0}MJ50= ztN3%Fzw7jx{#~W2XSP+omdPA(KnY6uJ3b| z{!Bs?5b}YVsNPjsHw4FyBgNAwZ9(aH?t1neSDSv+omK*1lUW<8;st0jc3-m?@$jq4 z?GY0vpaj6a5JMiyA-CM*Ya-*jAUpCRit|wWWc(L6bO?t<@9y2Xn^V z&n_9=KjGgJ>7p+HahU?y#>|n8HM39eF3C{S>7Z-m*tICuJ54F4UYkSgn#R~g9M6YT ztqV1E!OcnPUy=)|S{|itdBWH#*`q`#+1h0o4KnTDM0b9fVXJBHmcLwVCP^BFZN*%S zr-9E!BKOFsBrC2H*=z}dsR_X^jpzBiNs_Gz2Wysz*Wjxos(?i_t4Y_gR^EpT*VY5G zD(n$2XpiYJaa`VwXw29585~3A&eck&vgzA=ay(Y$xYG5flyZ{1BM(}KV@E-TE;&-{ zU)Fw;Ti*;Nw+$Vdg!N(+D=8z(@F??7FX3vvS+25G*I?pzt5%eD!n18)^l|H3E2^Y_ zM{R!Pa)zL{RuW_y+ftO4l_y3WM~`nf9?VtBmdOh9EP@GNF(?XY%4lXNd%a`9xSQ?^=bz9_HpHI zr`)i#)nqpDqs)~7F%`WGy;zB^!BI$X>JPB$ zY%Uz={miimo8qYyZV{nFuQ#xIOhfkre=M`6*+hE<;${*odX=?|qhG=3PiT%ozBe-% z_kk0%PW07~PsbKR&=Zch51<`!wtn8rtP?!55faRd)&Xn9L zaf}3$!eP^=#Bb=7|6Q$KEg!`&kg%xRE{OPM0UnSZT1}Rez>e`NASMgVP4-Z?xU&8k zT#}MyxuSx1m}Xs*&$(nNu&i7|CgnV8+xI$O@T7T!%wQUsw4wrO?hMSBmNfXvgQ%BI z6J=nC~1Qjskr(P$dua2plQ;E?ptRexm9$)(NOwHB#OnwB%Q6=BG->(JX0+kxcB;n!G|zq#;4KS= zSU2~EfTQC`?K@en*P6c`=DIUs8RSlyUN#2kb%f z00f_w8@QLP&7SyqM$C!vBfr{qcSe31`wV$&yYD9*+#6@98Xw^yOXX8Rei zA0098WfWp)v)}#cWnRM;v<69^EAfr4Ohbv-B#z1WTT$eFlUtX&WN>M40a+9FIv#Rm z=Vh=3!_Q{pc1())f;*C zB8=?#1G91F9Op5HQ9Ag?XmUUIbA%!T3p<31V<=4vzAL7{m6-6T?#5}gX-qz4lj|iz z@`PynHk?2p=x!hJ{1PO7;WOh>A6JdbJthgfOj6`rB=#t;s8VnSdo$duEEAq{(XY=< zKrIgCfu67Y?;`}1%zTr_+F3t^@#)&{WAXo6;v{8=yS6kRkl}R@XvM>ggroHc@9_`s zz`hm&bhje#qccC86&zq2>rbZ0!OL`MMCpkA)bZ4{b}q|Y?-EC^$~^sQuS6vbRUE*+fXw$(}beWLevq>dgPb`JCAV+<{(UzGcH9E zf^F(RL#40x-B2(OA0%&COb4w&JRo+bvOUuk>*D)xtpSAxR$rBBv=(;$ZG4-6h@pRs=t4sNA#`Ge~w><~e*Y zw};$VZk1la*v?;?dHRhj9h2K}CH3HJ$?;ZMf4wEN9hJnEU8D=!Nl=F9DKS};8?5F$ zPsk{YbfJN?<#%4Yi7*E?yUH}``gJgov=qjL*3;{m*PUfDg*70|^eyGxY4B4K-wBdA z52OI|NV^sUX$~SjXg;xwoy^rU)xofQS7EnN_`oi?}EXiFyIDyME8p3m_KSioYNZbeV*(WU{pYO*D zY>Zho#WDg?fm&*pYzni-E{#1}-``;TSF&cO*_=;U&go|Xs)#>arJY)Cx$;cjas->L zlsOjb*;P6D{y8J1V%hmN%uw4cOB#r^cp2z1$@nCh6&6!sAY$j>W?8Ch@>?!LyS=Gi7TO2>RhenECm1{MD5WkR6E|Q&(ES zsdliO2)3+NDOz92!U)EnvNzbpqPbA8N8Zs}&{rE{MDQuE|zDGwz~6j@3o2(*5&6!~0$=j1>?mQNtl5xEQTAOf4kD zL)x>ho+d^S@&@;<>?K`x&NmuUYghi!u4LEhr!lVcNmh(hdR;)z10qG0YIDC{8MMOW zygrMBF+80qFx>7BSUN5V4e`uKR6eqpU>^Y{UTImP#CTFc-#GMgq-xM#dw0{0#qvh z`Jm|e?ZMdttdEL3(0bhN%17FwmnphZm>J==gK`5iA;!Ujw`IHXqt&xVe|2)qXA(tg z-m+!NL7P7+}g+!c^c~~A{t*{vu>scGF!>pR@EXRQIi^~`xG)SgV&fNDHxcxQ2#Z$ z>sEo@1Z>?(zBT(1J=mN}37OAX)p+_1Nr*VDJso4M3y`9AEKpP-rvO4o3&NcjIpmX! zK|vi3LKnw=n+(O)`2vAT=9cPHk4c<5xQrC@nqoDH>z1THN|66USqyCewb;|zPzO5t zzJqJP3FzH*GlDoIK2_wmBr^s9WQHoR_pEO2$7(Ji%NUkNXcgY8HW`m}BciQnpvR8C z1b&MYO#B&Or1Z;K1aNAIl`R=f3;1$TDWyVc3v4%F`}#)`W$yw`FRsY;4nCcV&Ugg( zp5$(FC63PY&9h86_2JdhFRnGIzB z{YcW*8GAiaR!ha9j+wX@v${zhse+PGa&SHieVQ!E1}PUqd(%v=7(Wtq?0wcJhT^shlatK7G8vZaE={fE7=R-fFvg`LeBN<=e%B#B$S2>1l?t$6H*a$j;m zzTku}Z59FK{vSnG9@p~!$K4?$=@OeHsW3?@tqoBKlS+t2eFIzu&Lpc__yq8hXcY^#}c~&>E}U z0T_GrE7}6sb^S41?q}z}j!uM*JV+E57UMi5`Z#!mmGCmIKy!@#znzfzztVYGkMgTxNb(wo@>}}M+n9a53?9W`d0`$N43B54BKP2 zD?bJ7;P`%B{8+p?nzjDpf#;d~1<-{&eg|<$s@}i2_65pBep03e_!zmHrP4^-aJ-u? z)+$qF&o-m8Bp|+ubWrr#ILF~2(yz6A2Vn)LejU4(5?QQyVBeVUd}x#r%1WeV9jf&I z?ONk={&P+Fmv_?2Z;hbw36H@kNswI$v}5hc`@G zM5D`2EE?#rH=^ighb@GT)@O&L_vSN~5KoCD%@l2rrb_@8==@Mtu7&>1^GCcXz59u> z2l8tu2zV%PY7f=YH2JSh_#)q=IWI`Ny;A7`umfKeW#NF!{v>5(4dW4EDWm>21&vT0 ztzG;#nHtCqh){e*)pj@lgNFDB5$|{=g+*dvEVvwYG*A z(lCG8qCc=vUDqX0y)wSfaob4!P=CblSaS1f2RMg!=SYi|Zlso|*!m@~P6<14X*Z^S zk@EZRq)#aS54+^m&ZGTw1uJ0k9J*$^@P+!wjVB;>UYS`4I^`angk{ylGh9Cr@6&4| zo_9mS*0PXo>oaA4y&}jTZXuBc9B3dRlRenAg6Q%^^C1Ji^UMJ9|D!hP=FM#@H5D68 z)!&JIb@TDWNlCau%UgS7_1fJ_7r8Y4WnG=k${p#lx@p*JQU63v&`mlo)m__U-&-YWtIOz zNBEj6o(BT=KUbp`sdl~mPGca_C=x_Oi|=@Izsu^8%&&vWU#-L_LnUn2qtUl7_%4u1 zNf=Ak?^~;4|>j{XzMf?-pd(9p9l>HEyQFC%F#f@=H@sh{1EQbCpyG zANDs>cP@8L9ruS>Ng(pn#$fslpci%T&c+{=7V=l zycy$n-&=hTRxi<3)`BY)(0RsPV3miruH%|EBsAgq>Lg8k^b(nvPGdL8n1+1$DISq-yoQGbLAKQ$q+i>WP{$& z3nQRe8+1V9wT)tyQya(J+$gci)f6&&acJavbzf9bonklkKb?+b>;4$OS;fLKeI~_m z?AR=ozRzNpaJoMf&U{>iel0n>6i^G*y^f4p*AchOWiv)VUufm25wRf~OrdYL zVIKUxR!iT@fj$DY`MG{=r!#Ry7G&O63!_$(MNEESlHB9NVI~FO;2(*)>%eD^$6ywi z;`2*robE;R+ermxs#&djllSR|Wmj+S)b-OR@HX+ZRVm!5wy`5PN*!*CE2!}gNF&+% ziP95kmyvIB4ahturXl|Zhv%c2SVwYhwFY7@`u1_nOU!;zRUQ7>WyCi-vbsJ>Pik)S zOn0bE3g&BmzFePd&>z@Yc0m1E!+Ytzs({}gR!U-V_ngo<`29H90rj=BbjpkG3y^_r zZwPigS!JtxG?IrvIwYHgOA+r_{^Q%d3RC_c6V2DjS4e1&Sf&P=H{t=z#d4B2`OAcYrr|v$LMn*%s z#KHkB5xM9fi{B9wWXK29L%6n2j5=jS^)U{5Cg%)dxrU>uJ=SaRr6^OAG8#ZPKHn-Q zRP!1{h~;m1!W|PFmdSJ|SvthjX=iz1dBQF58|Hp4o+*O$->(vW!+Y_p^}miJXD)ow zejO^9CF<7i0nj`G#8aFZQJC!3Z_kbj;u)gser0+mP^1k$4{7r-yWa}gvSHaxkucwl z5BFhx331*RRsi|-P=yuZc&O^pCzRX5eWKh8M>`+lfR9e-{teMYlRmB@k5KkZd3~9* z%8YTDIqkik*2lFp!{hJRzIm;<0>U^d_(^!oypmI1#%+=(#^9F z0U+@YeTRFRNrJ#tQ~`5))lZ6soN?X%W?SJ0aWD1H!+UApO!z2ny|bUbOkgf#JDrzM zgPjqx(w|WE=+vytQ_A+I=WU0><4~5xS`44dgwt)jzyR_k8Dsh90zgkCs%Gs|mhIrM zZob1_`s<#<99%+%t+~|hgfb)kI*{HWH0TTMg`(2sW`~$PqI-|k7dNmwA0?VAmZ_Qf z)NhQgd3Qfg(b;}cxUtSv{F?`@eiu{)S?b%>$A~R_O1kFUa!w}_m7Zp*{ER8fBDw+% zQC}UL!34PsxvfvovFC}frSxOsgIg`PlCSQOw|}o$9Pf4%WH(dpDGf{1Bfo#)W&{>I zaD4d>FBOWf$cTF}y@9CVY51%g(-GUQ+9?VFx{ zVqPtHK8*`>KQa_5uEVX#&m06hzh^kFj5|69omME%eq4#M%qIM%3a@Oa=<#$=)0&*f zj;c_)D1-9H=I5(qp9hgIIvGG>R`2U$b47Ev=Cm)rdBg~(30^_qD;Gm&*Y7yT><9L9 zOINGl$tHZ-XoN(M9O?C4bmh@aMjh*RnP>Hm+j-2vyLs50KNRw0Q8yZAgV4Us=9UlRH8SVC_A?w(Z*5AmI3xkARL=}hCZ6?mLR`Z z*^J48{|9$nFdhsv#%+~+Lz5}B1T1~uZ8Kxs#z>H`GTIZw!~{nt6VU-W z*-(~U0yf5P6Md#ub((qGnoyPpo!CYV286rP(BbbD_=8->LGEi?fqKn@je~6Pqx4^0 zb|Q)Ll%g8B|)x$&b<3nQp_ zQmQqA-5qkNLVS{EsBBoKI%t(7I9}`1D*ore!|~i8GIqhWmyCJ>k7qWzLTQ?sxvY9S|g_Mr*{Rwa-WDN@9gomc*lfN`wwbW8o6Qt#T=&5x%0s zXSCUwAowBr5CZXSvuNIAFJ*{EBdigJq9|Ifmsi0d{3Mb5<|{89FfL(y8%c(+mJ;<5 znY!wSkXOCE!l~+L)E)Ti8}`^my!{s^eUQV$I+r9e{J3Eg_hH%_Ire%~40`9BB?J9% zj@;90_Q#gr_H&(_O6Pj6VFlXp+jq~sXZDXs%deRck~ADI;m~$(<-Du%DdCMZFjlQ7 zK*}d)q3=Ixe264XsAuT; zkfk~AX3=(>AhyDW+@G1QngJZ7#R}UD`2{F@bpU=D^uJ=%VCE5UJOX%(T=Jh!DeF8_ zxGpttR)ue2~wJz2?qg(o1LPq16anWj8-soZ?+jtZ4 zqp_&t?aK%PGUJEn`;h2+zsOlJ1U@GoI}V6SJBRF3Bu%1wZ_x${69I}Rex})t51omS z?<{^M0<)mpanC}=gA(N|vKh}&Zphxs37o92!Tbx@1M%9TS}FChG!ZE_?;PU!JRa#k z--NS26Z(v`p!&-nm@Ben*EBVjX0IxlLci`Z>@RuVeTE@#?2& zTMb;^Dqcpr_6~cBfs~$F3Z_|zS%XN2g3YEp)>bxDu4NHcAJOh2=-ofBd~`Ee2W~s; z95Jta@0vxqbM0lIaGJLQ{EK{jHBsy+$~>A9uXx8lze$nwi>%lr@yB5qbW`yGWqc{U zRwVd@k*H$4HuRdf+`!ym&4P;xY$)59ZiHSRXT|+9I?3VA+t{n?>4S=-PMwTj7<|oq zODU!THVPf0-@5>veq~BE=z!iDnF9ZoM6%~4O@Tx#S>vJywg>(?Aii=3Xe$MY(*;san41M0vgi$2D?k&a`eej)w7Vn(YMsd}*fdo;|a{pGcTekmew_)6xH25vXLg(8pKMz5ZkKx9g z@B7a+6DkdW9ye9@a_2h(ndCm?(u7yftqQUM9 z&}JY6orPW}{O7EiIX3D((zX;@&`9m~4WzxPsA_OaR24a?&t}6IMOUAh^wHZRsXp0n z&Stym$p&AnA{2cykRp%9qG@UE>lv)3ew}r5Ouj>jz_On%Vi!9gAna+U7q@;Qk zHe+Px5_5k-q`_h;VYW^AUH4hM>QpnKLEZp2dblo{Se7D7Oi-87w(#E^x93y02-&KR zHC_@R37IO(QzX9`>#{Vzf<_oQuXIK0<1Z<5q{BJnm)U#tp z{erwObJK3wZW^zq<;TbA5%Xp}_C}1H-jkvYWbi>zvxpGtEntp-`vt3d^91?&$cBCV zH!nwsN$#ga+AYwpRn9s-q!|zRjY%Izo@5r)Ct3o7B|R z9B#7v*Y)JWr%27WD!&Wz3lMlFubSC8&%t&C^AZ?M4dvIXLvZU!FQqv&<-&{3VVeKx zpP$eM`96h7C?Ed%1#-Fih3Lx8i?*CVt7YoTE$j&OR{bUPu011Q=NlKH5IFLjrFvP* z{bZzu99ufcgR5ros`CGStK;4;;<``nlV*uZE}|x6?OZuu=bD?Jp_C{a#0aFs)~A`3 zz?x%AZIGbXEKIs6NoLM4)rJ1YM4gdu!Dy=vUOXP1`Fs`DIRv>{n4SO%x2FOOGgMRg zC#K2d)h@<`eZyF|_?Hu4JBhtV4@t!)$T4=D*B(|H3zE;8WYDMD2zT6N2|Z6(1L&Va5>)xRZ&Z%iu!=u9?!{%_h8*5}vVY zHvadW73iS*j`H0TdChTkqK|q#7&M0%vDgkwO>}m?mw&@7MIUchGsQQ~g6ZaC_Q<>< zl%U``-C`h9g3H&8ziua6UQhEBO*17qg#LKbmoFK%bCz_dIIdAr0<@*1`g zo&=~x^E)vslt}mgKY?bEIM#4bg6}5ak#_1UT+ z?- zRW-t*PG@l%{}Pa$XEldV}P=K)(@t z8t{tCrE`)r*QczDsfdi$A~=T{FaE8(S*&pvFBsPGP(hBL80tOGvrqXUcHMqt812Zj zZ?B8!J?&qo4rOABNrDpl!V02<5P-jkS(O*9JSGA^)PmQVZ(LTIPJtgZqWsh4baAze zP;Yrn^IVHD4PG(j4WJ68hB;@NljG`dB3{Qv$9gAz)!{5paW z1)MgY#^9VMk#jr}yaUsab5^q{v0NbHsn>2hg}RT4I@nPt4*CE4Z}%Ue|3??RzodqI zc+RKt^9!I$+7^T(hBcb^y8L~9^D}Kz`xa9j$6Q6uZWGIKN&gM$KMHaMXWS-e;9{vH z9Klg8Z4_GrP4e82S}P>q5tGpU$K%FQZp;Pdh_ZVnF8}6!0>D%ZJ5eaVR^X3sO?Lxp z+$Q41`Y}99l`gxoUB(eb%H3C~p7~jQ)B$08fnZKxvg{cxah%xq2o)jsPR6D{3tyl? ztMBN(RLO);x)T!uK;*BovDsVsYw9nasa^$|v}T1{#tLWj*+p%Ep2>vNztkGT*F}1e z@fSRsS@$#G$*PsOB%SN>+k|WJst->mG?1v~A@zcmya;F*U6LfaB#FF^IZq?~K8(Mz zEr#+X@Ha8lCj->&P`ZssOx#qn_KLa1tQn8~7-1OqgN^z!KI_AsDc@0aV-HjLmZFM@ zQlCyb9p9VD5-gfm6ci6?wr7cZ^z3Uz=*>O+LVw^h^nHRVe!AUFfZKj^$p|i~78%oe z#s)}T&w3r8k-A(QTh87tMMDObX`;49Tx$huZ6TYv6P|nP29wa zm`nN%M7JdNmg_^tPqfvoL4-^Om+!JiAX;e=?;VZd(yF##Qof*TcP$@V&(jyaF+c0#n<=)+O# zN*A`9J%ouNP*cwzI15EexM(7Luhd_|>SzFSR8iZ{$HA_J5)7wua7#E*v*Kr~rq`6x z1ut2|`TkAV4DOZwNYO#WJdOpRJ;bAaLThsA%+*JkaOm1oWi@6=#PPOH8}g#;%Z0Fw z_^WMZA5Mzqga33Z3x`Po2(Nawmj^O@+JxgGt3GntO^_T&w2?D#M|AhDAjF{3d&8K| z1kJi#;3cJjaETgYC@poPY!F&WnzzKSjrjV;&wkWyR=xOh+9Y7lH*)8wj>qDV=D#O_6}>?|{z1R^^A?R!90sPUKY=F_FM-s|Ne1={Q^1-U>>Ya<2gF zpgJn9s!ki}*OCJINEJr@^mo^s853R<|I}HDKheTnEvioK$uB8BKY|E~Sd#dVMn= z?V2ZApk1>Gw)&*&7Ie0sD6ND}t=d*cO1b~c{q{xK@C3DgB00~|!qvS51X zyDKE7?`#Ln_2Yof=XLCu0=`PGYlloO1C*}ikCAjfE>RVp)ii13} z9K27bJrUxu=-Jm%645-7dPxMi2cU6AV?scg>^=CUd0rl&(B5y9#H(}D* zl!u@wZ*L%uHs%?E!66i$%Jzhrgx6suAAXz;Tli;#=t}Z2QB1QRlTE6a%jh+9_mDIB zlq(ysc+nt+^UpoY)rRCyI8F+lHb0Rwr1zq7IWb^E#D7;d90B&60;!s-X5ySUnyWO- z0iDBK-PrMH3>IHXFm9~LSpe!vtaEN|pO)bvi^9G5Rc&%Pp&3%?YlY8|@tAO0a7XzDaXGA0Iz>M* zOighjHrk|&;L1k=H?)s8XQ#+kx#Jnc3e}Aky@(6Bvu&zqHiewmI2FWGR!mVwZrITM zZu|i5Dmz7ABLFj9pn|Kp7*bu@(0!eTs7E$-jzk)#=ESOOm7bdD0y36j!ItN7C(l&x z=y0Kxdn8BRmA{>oJ@0j7{U^)gPIx*OJ|cDS+J&g!``fv%SgJ3t7_HZxxng~CphW0c zO0SbOC_U%og<9{uR}lm@mh@zWeLS`Pr%r9zRh8KT{}94}Fq{o*sx9&oF8&_keQALzNH>F#W{DfR^uCS zURca;>hx&b(7!!?cb3V@`QfjXnhlI4{Bs6eg?AKjU50))x$8$H-xy%QdYVPPH;PmZ zdpD|bepf=)LNhq5n%*G($?4#`Qbqf&j&h$E*5;l(DeZZkZREC$JHl%p6k5`#*xr#* z3-${Uc1II$iK@w&-XQzzyvQs496Fp&Z5ovuY~yyx_D`9-R^*Pr^O+G+^Aw!mGUCmK za?D+oc~~4qH(+j*)JuHzna~<4?P4odU|p(77RN%K`jo%qT~lU?z*VXy<`U+*9oZF( zWsvh5b4Pf0CP74|P*ct8I{3$e5pEnNrAWi6e z7kRf~>oPz5%~zA1S`CTPCb^L-VdK%6m8gSlC`m>NuXm5=?OR$Q$D9X#tAMSCX$mt> zSPR-mv$ezl}xn$aCnK9(}^4N{u?4_=-X|?v&`P zmJTDH7&M}4aL{QIHPRl3LcCj&GOhUQzo)|rk`(yev+p`2v*=;^Y1&eA*NBzpC~wsx znkjtEJsCnb@EaYG^B_DzG#9rT59QVh+_v|*s=R$Qv)E#N5go56=IcOE+-(}LS+^z* za+>|O-~HRRW~a9{gxjrt_!u5 zCXV!oa5@in*BO4AvmCV{d$i<8+rMNEsjtG#wk~`|yv*;_Ot{W^g}#9PR=oyk!wyj| zc@1>*vXNX_Q>q0U9RM-NPq9K<@b!E&?<*UZ{++m2t;@UZsB8_eRqc9s&W{!M6?{zj zo5kAu@b5{nt2B?%0X(Nz!sp|dyCXk&U2+NG%MfaQMIs=~yK)hgq?(W&5o5g!Mq6 z1%j8rj|+wr`q^xvKYCh$Uil~*j&^!ppZUw8o!cn?VNH(4D;^9Dj3%fCcd%>4>uv4` zt(rS4=`!*fztFIepS$Gv5d%>nqCP3ScX5Cc=(D^^P&IFm&5^$j3mxBdY7&xVPZ0MhLI z;tz+4d9R`Bza)hswqPjYlPx6ihUOhtpx=afQ^TgUmM2y+2fqzLzfQZsciNE5dcvpU zLLgVH8svY`wli*7D}~J@cq1!yCqKk!*bCn?uz3$W^@h7T&c!UgtMW z8g09$M{5T(O{>gh{`#85$VF|nBZ_Ll?<>grcGGUp!Mz`=>8z(*{!GnWyz=K!p7i>A z{~;2zvtH!!F}x5HHn1}QI5yW?X3hzl`q3eI=7 z1$FNU<~tm>)U655wHjd2og|B)QUA3}d5_jdu9Nol)p%+m%oVC<9k{V(h_R?M>JwnV zb&s$oJ16qW46 zQMMBC6q=_lM^tmEJx1BA<@isr^t)2)5rgIQMsnUC#xix?r01YvH|$eUG?KnSRQCE! zI{T+%vTU?lui5PvF`?H!89OK?G}tF8EI2+t_i{?v_~oi!l+Dwb_$pDg3xw-Fg41sH zwR6PnyENyEvz$T8`zE;Z=q72JecEKN?Z^xEzcix$l$n~*#R$fqW0E{%w~-sMF>KOq zVIu4102jG-Lom3`)o)JQLB97Q)D*TWZp1!J8uhXUN)oM=y1d<*E!MB|QSFNaW?ucq z^kh-lMpvI=?1c&EpzOHV)wzU)Fm?DW`|`2P4*rmaKJ+l_F~GuMI8S`n6IZ zyVFFSGG{5=`Cx-w-nJ3?akkB=w_U1x#p^m*Pj+lEX$#YYp;fG!F+mNx>@BeUnqq;UqJp}1BLDj&R z{hJueOA=cwIQ9s64vH564-DGk*Io$y+lNtoDoKZXqp!QFtO9E#$7Cs**%kjfeQ$vE z62d+>p^y;wQJrpQ2ePqMEPsoZP#c|K?9# z(U1gB_8jEKy`S4g4N)&l?e-=p5h&c7j0pTxN;qCwwr3+Y+2S1gK>^^b?7TDTekMz^ zDnu!Hk)z&hM8NprE|>D5AZ>MD1rh%XzwE-7y8aU#v|7}-@Djr_qTbOsVxS;=*05c0 z#v5OI4jsYtC)*|`)y@qGIQiw?@WXpExW zl;u4ZllndQHB;`m>Waf#fNO(X@AZCY=p$~_?3bs&&4)TWpCacf8Ou~?Z}Bt4GlI=* z=wOQCV28P(;MH4-i=Uxz@=b(zJa921=MEW_;J%B$GFy>6f!Fk<(~=ba1A%)x;*|#r zx+v_y!1piHg}fWgA5{!f>K^9qT^gX9&7AEA4HF2lt8yHAcQ&*osF)hu+D%9i*Om>* zem-vngma>hosZzLhRohg=(!4mY*g_pKB`@@s#k;eDm4&**@}(A!-%R=-spT+ zGKL*iDo4o60V82HRsr>qg%h8|mp_k&e)A7{M~N0phLV>7&flLl;BW9$t$C^|{K}Hk zH@83q9ACKbyA9_17S)(4M#cHLU%WDhxU);Y8OrBb^s@e?cYXhe@pK+rf20CUMX0)G z6gHIJ3B$F*$6r|6r2f16>LR|1f75!!=BAj!NcK0mo*o-Xv@At-`HT}eGJM-Rn zdyZC=p3<_5s+?fiaZc7l3gqT&WSmpwYDC;NY15$u8)V?$ZcTMDL3Mb$O-Zxc+ToV| zF7@4KS^126iy6yv13Y-fRKj~Rs&@`h0rvk;1>s}G?z?*Mt#H^1^KGN%d4w*FA|+?H zz7?7~R5rI&7^LoI-0Wr?QGM+Ox_qSD2Gr|LS<8al(8i)emm1tEEk@k=bKM2@LfmoM zj&2@%XtfU~py2XHPm%T-!eK>b zbymKYn4%(b!+rhLg>aDBt6Dc=U5CFht&=f36cT4`&h*s>-yOIT-ebYBBfQjbC9H$+ zH|g*0nDTya>{a>yCU*Zvs2|RGXr&8YJU?_PZ>AAwqnfxrlOI7TIW6v1Os*;C;M-JwoWqHrk)pUD0Q%{E}c zhl(s9G>P`3oBoP#=9G1p2YJFnb_t@HSn%!Ngi_Wotq}yzhdw*eTQvpbyjp6mFYjE-37h=3WH4%Y7i@@IwU5^L_5wIVWKXh;X;LKVabig zz}s!G21yR?lCsGFJSr0OmasH^EF7}X{t$C-M~;Ch#^5DoVZyy?wz#`V95KMnBrH^8 z2wT1+(U^TKqstRf{pEreO4>(i5l_OYcMyK~Lbp&8^pvb+6XCG6jE*MHRK4vSF^Ex;FcC*H0qLkZc5AWe>kBclG$;Cu zK;1xK;f|2hfqZoxQlIzHQjHxHc;zBjV3V6;7Sp-ZI^q?=VDO5(KU%JuLa=2bD|J*C zx8f8+YmoVhVdh;|RSJ665+S^kLyERQ)yyO+k>~UI35+KTlm_|ZJ^OxM>smZSEk*3a zz<-fIyB?nk)nmmLj%OV!Y}A_^n8>xB=ACdQ9-GcogzK1=q=qxNUB8$5-TCW2fi@N= z{yw7Cp3ZGS?T;8PMa**Js=Zi@8aI+Sgt%hboZDOHw}I<)7`b{{cUbZ0`*#tlSzZB% z{+iVV9VD=s#NA)%8YkaM+3M`Lc;wAOFRBsr^tUA1QzJ%x4>73+n0B)jYW-8)8OeEw zx8=AToct-@T)bV}xu9c)siOru%dzi@vgORwX9Ox6O5+lVNt!s;l!tQTs(6 z8Z?*ut4foIuKgaY!UTaAlco8$OTx{NB_lU-fK75Q&X-sqr~&Fm5z1ZlK*=|RzU=!+ z5!a7?Zn85Sc9uIl-q~|lMWD+_7uCk{XEJ0e>;vKPue@cDzO^9H0K0OzJW-LWvPR=1ytgPU8Q<0*eb-`W!Zn?<6gFxi!x6q&lgA#yrCe2@Jv2IJRQ7Rs zT?6icgy691yyVE{VE~?PQ?8&LQBlP^K+`~cf`V5+IR1lJ$&MMiQJ_q%afwFkRsz3` zNfx8te&}PTs&B>1-1nO2D>bf03yCh$pc{pRX#csS$AGDP=b5MTN(co?jMq4y5bKj* zr3hV=g&lFU%k$IvS?Hm4N5q*9ELfefDRnt~Jx?+A12>62_JSod48S{v692Bn_2eM} zq>L-fzeLNVxoRJjbs(e9{V`g;`WkINu%vjLhQIC$z$3<#9IR%C1SnQcwE zu9_K*OP1#3t5!SmxZRp12L}&=VFcAx?t?A2QrJ@|n@*XR|+}lTG(5Wv2D=&Q-M_%fpe`Xe2D1->$M%g~>O$8;U=EGuHft`^GV_HXX&_5}7a3 z2~0TFMY<43uS&Il9eGy|WQv_p%5lZav`@FhjBGG}+eCD4`;nx`J}08Q0A(VU{&|5~ zqk3PAaRhab&FRf=Q#{R9843s_wZ&*9&!;aGB)kTN3J{~7^im9Cnagi~{7R^E_RA>R()})p zus~nYYjnLLY`$NcmD%@##gqCp5fmDs#lECM;A#wY`(7J~A;TlRMbrBt>^Qm|OWt+y z#2-!2Y@~FnUO}%h=ACR%^o_G-TpD6RH15dat{@&bbKsh;aNThD7QgFF^6y#Y6y#Pq zOKxrg>V|YaqRp4+K)_zEW|34_nNkBi7)4L$7tRlGKY2Vt`qf=zvb!BfmOYwNvr#Vh z^a5rxxupRBoBBTaQ9pS%G6{~1gzf4k*ev!K-5qVLB&tC=JDD_@W13k+Y9KL&KGsJu4-KhS8{q=~n_Ua#+>*C#?n=KJ8YF zn&Um6Z*o`swGRNU>}tec(JX6qBYxr{O9wks4&vuDeXhKZSDRd(h$4oqk@MqBo$#SO z=llkaJw<+OQf^MgJ%f)R;|O&2PL10Q4mBPx3!gU|wJT%UGl7r1q>-GsPMFf#O&x1> zMKv2N?^aTWSuWk)eyj-5l?s)!m#3+Eb23e+-Ux2|@KkVN#B{kbO#@IielU`%HarF7 zXQtfd3p70dLS3+Y1!;a9h*G`r@&KmmkYZ(2{`XTVcMHVcUO;QvT0vvYM4oi9qPn;I ziIuK|=Zpli<20s5sEjG!5cPGH;rySP^5tPQs;$|C4yc!fdXcB;Y-rFSwRsGZx_QVS z>)S4YpR|#P6C{eJ!2F{dPR3AHq@Sj-yssl_zGfa7`m#s{=JHDEI)wR?@~XMj){`2JzOpLQNv96ENVCFnJm;frVF;ilt4DPPW^CtODLRx6@KSLp{F zCVmi%BK{L;P0mFDpV6C*!7c%~ok+|kcrc4+Et)8#1(aU~_F_AwQF{YsxtLfkYE|F{h?O9-(TVqcJV)g8@3>{nPuLt*j$add5 zsT{=4{c}`h1*|1Mw5BG=KJT`2*VI9Q<*O@@HfyS_)T$@VdX&Oom2q%y9mH7C{>Idw z`1xvG(SAu^0xN=U06oYb-Y;=Pcym-`zvlnYH6SgEFwrK)y=X@4*`03CVD-U3HZvD}s0;QL*X{)>^!(9cYh z8qyS*Hdq&4z)IB}o~pK6PhM#QA%&~`@r4K@z;wD&m$+c!d@o60*0}EoLE&@a{cDiJQ^=E%|c_<}Cl}$M_Cy^Tn5;o#_IOJ2} z!HUhoAoD@?PyV(SC`%3E8lfm~6Gs8K2!l4*`Tx^c8#C)u?e}xhhfHYlgXGArdy|Uf z@Dzp5;p$=&k#^~RZzPd@2`T>QLXD69*N8FAKU=Lqeo&uoz8-Pe*LWhK{ z%07oqmogp$(UCbVakmqiZ}Yj)u1^`|m`Sd1&ekizfz-2}?stDOCM-en+oav>5ZRLo zdNi_F)U~QFd6c(_1%6RXErD~aSrt!nkfldp9KxOlPGmwo1=VzOJ}&fozfKpdlJY^9 z($Y%lnCXi8oDb_d8w<8bloR1W465X}BgF`~%R@@{=(DDZG$9=PW8{kp#?{-VR1JtM zHF5}>xrGx{9l?M0t&f$@BVg2$m1 z?0r%eLbsfESAhwnS*}UpqdCj@{tD)JgWGQBwm|2oTxCV#%f7Y-Vf2)5C~P-)J*w02|ObnM4r?GU3x&pv7LA-tO)xlum#+P;s5-J#uE3n-) znTa(oL_yXArnL;&_EI&7xDUOEzGS@uSLbjq4iyoiES+DE^P6~qq5TLNCGooQS%Jm$ zRm!qKEZK7YRV#EQ)>S<^tY;u(;wl0G(g#|rbuw(}Hvjo%w>|tX<#nXhy=S{jI`>Go zt*u$1Dz_(0*8?}_sEr@Fvf9DC{9eN2l`tXUOejlOSYzhiKh9kgo;`%w@y_r0d_{lx z4(S9RJWQ`P0S*4b1Ws&?NYLIu01l1iS&SJgZ5^-98m5SL;wUbmMiQ7U(~eHrPrBM= zJu)m(s#K=0mATYp`Jp>)q)U?RU92^PQ;X5Yt_S&4x~yppF07K8a+(BQJO$n8^FZiRiY}vPq=0LlsLWan zOg=WeH(nKT!rWMxI26bjKx+}h2Sisa{j91<7t@6($sp2MIoRfgeu3H1VP+D+4|#SI zAH&Ze0mH?pHeUUTVa15lq+-KHie{+10Br)@pGwwIicuG(B$4e!>*HOL)x+^ zSU|9-z=@OO7E=8RQ(D|J$S+{hqp%LT8^fU%q^}ug3moU{o zj4l7^As}DeZlx@`)#VZZ+{A}|0-k;dqfgQw-FPNTiNc$XCPj>0_>?Kk(^1cd>tp?`OYms<3srBCoN zQ#C||$Z2wD=dYl`j_I^ZY^P$HxGzsW;o8R6$(ZOO=WH%%=inc+c9&@gxXd{&%G|80iNs#@kIJ_5z9XV(QeZF#vJE)IvX~2YI zPd9E+U3v!{{LOIF_aqpeivI-@b;Lz^m8RNz(aLzzi*EXzilfLQ$;cGso5TtFRvQv~ z%!y=WAh>B5u@p4TrMFt&V$rixk!`3$`k_RosXt$&>q3JK!;PqVcjgq zsrWR>3G&6!SStg`*dSCeIyJdTz2L;vEyQ0d6^yG)LGKf*vplvwnv6SFIn|kyc#LHR zn9ld7heF!ih}kzw5oUlk)(X0>Oa8%wIvBQ_aLPg0paqe?VJV&-VsavDuy*ft?p89~ zVri|ik@#yzkvW)-nxuh~{MV1H&E)}ZHXPG$S%D<*gXvt-7^SCCyp;B`96aiHGKO@y ze4EhZt;&c`S0)z2@!vA>_vh6+@DK7BQ`-GI<>BczsO-3!z~y=<@xgIJGjfv# z1bZ_WS&xNwV7-QcRUEg5$d4nPUz>SenL&4Cl0f+B{b`A<3);R>aJWaHx| z;h3hC63Qh(!UJRz_Kf#j((8c~vFt=1Mqct-Fyzhq3;OT%y;r?UkQsc5D8?z>lln2C1Uo$W%ybo@y&Gi3n|5FfQF+g3% z+aRDR>;-2+h{;7}Q%2(BL{ruIV~ruiko-^OmpGYqembCi5N{#TzsioR+q+}FWU{r? zMc&#b%h;0mD5@uDDbRaun*ZXFyF|}Vx}4C}YbI3^c4unNu-8#nO5+3r&o$X-2AL#> zR^{q=dWXE>&#Wq?`H3!A4h1xOLpowh8wmUY%qeuVTxZ<&IOXkGjYMSdKM`Pu`RAf- z%odM*8avXSX{%=aqv{2@&!J3_(qC9Y5?i;Wb(t$y;W&F{LQx(}yBH z_s1d9cW3ray^Sb}n~9JX!FYtg1M=@ays;#o$%lPe&iO)7ql|Qx99U^cF3n;$N-v4ztl6nU)(rdxv`t1S5NfH?8YA|Lovi4>o8 z3a&K&fQga9da$9y2CAWGPSsq^p3gp0ragB=a%K(~5N!@oBWgF2+9@F;U|7o=d8(;f5GMpSbg z<0i3zSnS=%Yoaebixr|+!Y=4(!fDeBb67BIFViw#_Ok`8ua3(&h@T2=aCnHi_tsZ* zkX)6)c72;VHCU~qI_0Gqg$JkugLZgoObNF>V4A{e6$jO~oyGWbz38Zo#5==Yp~OW{ z^r%=KH`>9wQwwBn)Zr3%YnP(WS=?fcx>BVL4yknbH7*8RohO+HT1rOx6;+VGh?S)< z@ql;!WPp6(pt2sPfJ}axAlw-rRTyU~Zt^0d3I~6|uG$Oc9m{(W^jh@c`#4;4G7p#) zm#CEuv61T1y>9z6fWJoK*qHI=8gyRtEp&j-IbnfSED-XlLpekJsl>G8L`R@cyz>!C zw`n0RSaq@GKDOIhA=;yGVo8vHlo*4;Su`P!`ot=!ULl0hClTep`hEww-+n1u-JJ(t z?Ey8n;1O}wdCSzZPM$FV&pu{jZq7QSrYoz(m(^SN$ZPaHos?$FC$g{q(c1_Y!drFu zJ5jZ6o)H;+c+^&lI~n{LHL5Oegm4adZ8%Ka>G-Q}asIEM5zJG?RuqzJ8SH*?=(HJs zd;TJ^YokZ6f}fB1Us}{nc)U@SV?}$}Bs_lBvyS>%+K&6~v?&cOYse}GS4?8-HrS{w zwQ1`^kh58f20#1^h@}5CE2;&Hs{JR?``CA?*}P0s+WKGCLYIs#@)xL|QF+pK$d#k) ztpch%gOMZZ?%PtY`~u9$%PQq5_6gOdRskO>lDQzOc?Iw>xzO&jEFhRp`^{g)TWEV} zy4-+eI7=OlJiRn%Y~QEMn%1j^;MPl7*=Z z*SHga1M)}571hAV0Gfrxi%l))w2Pem`{D2D$Tw{BX9F#crN{~ms*YmyD_|SGgA%L! zX``-5&WK>7h_&yvujEyw;NNHV2Zaz5CJRh0CjBk4t+tTO;Qqo!C;s;P?qz&hy0K>R z8~4J=8vXa^C$_>b_<7`rE-57wniJkR*sPg~ReGH~@_>Bp59DCt!W*nkNJ@9}=S}9m z&>1&>z5>E&0SoXsAW%opeGT3_y`Fq!;je>o^Cn_Kxz#Ugc|t}lX0_&@fzaFQ^oi%k zeShdDD5d!U(JWdpdYJKE6CY*CUH6~0FEOng7c{fw#w_|bHwfJfUQl&re)>_g+f**x z^VCPY<#e0ls9!Sv_nt~PxaD+RXiG3_7F<8H_XILq{5BEx{YTNwbse_<$LX z7R^nBS36T3@amTCBAw+pH?7zW#osb~@`S85feK21BNIX|;0hju8Fi*{| z_3}Q)tF5g4#Pk{O;K8p-A;hM`l(n(wR zLShXVVDQmbL(QVJgx*aZef5vzsx3T5S%<5vnGPkbwT25z{{W-LW3cxk1NK|6Px19V z{3t3U4rr3^OaNRW?utGn$FCKA6!?6q4>c-y*%s;(V{L@K-cXXFbP*b?f+u}q|60xM zZt!@n+A$XaW#NJkAZ>AS!e3vEkS~6 zxm$isPHbAbeD{=ccYanf-$M+wM?ZtEFN{BfDNw(Tpf1O|35a7K9wChX)QoG-62pN* z7JM~80q>}m$MDxt9;P9F9R*id5hrTnXU$zuVh>{It-l?QkmtEFUHuE1fCh1E1 zxXJHWxz>80hAe95{UrLA210+wgRB_5G78OhjjyT7KQ!W^+@s>1O3W_G;j3SFV*--# zK=naDn(r@RyQp2E+Eb^33x|Lp2f;=zp^?zoq3843l<+uOm!1Y@G$={%Rt|5V>WwlW z0c(K6G|_P~r(wpse^g5kpJoaFx>;~9-LqFpP?K)YBBWQN7*YRQFekG;k`K4HHLC@17h`fZZjup$(+8_<@KIfxuL4~aX^q* ze+OyfFAuTuaaKRv2iDzoiBYw!6CIC?@i0*I*Mx4l4>NJ!M=xik;Bz+$eln74sFTW7 zS&6Dxgr&fXYNl$~Kv7zrU%XiDZ!f#-Ynn?{*)L*GnY#l%?|gEbpQx7h)>tpYCu7Zd zUb3x^Lr3ZlSU>=8(-@3`v_@ur=_Xo`WgvUSUrt6YB>X20Y$30(c3>+Z>m6jDg<`r2 z(^S&Y{+j45nIO+~^0~@gGdDFj;+;wkUhJp&6vJNwksnvN@8e)MSz^{I?(ud%=NDsM z%~&Vg%Jh)`###!ju%#~WKV3!FhzQMR4b=kP+s%B?OiZo`WXIFBpUTKQuM^J(_(qh6 zW7@6+YT|r&zO_w;ps$nuqZ+eosJ2+5i@JYfj%MZWbL5g2VMif*wIWg2f-1ZSj1o7W z{&&hY#G>dQk#zy2hJc<0GOet`oZ8q+BU=%KkoowKt|xHME4v)WtctQjec*5D<-`cV zw)#wK4TM3N`#V3;QGc}7G0Dqj*uRLpwqQqNAT)x+z8v6b9SC|MjovYeVFA#+_7Le@ z8%ByS$7wRAN-CaQQ}?xIHPpX|vRv&gb7rZqErA4!4L%)JrxZ)dRyBI;e36T|tKwx` z3&wv*RNrkTLzzhcIy%%z_oxPq6va|^S?a{TC3{6q)WW%5AvI5Wyn?JFT8uhzM-W6l z(2C*h2is0j9S|seW|CX}d*Goaxksx{+xHToj!QKY|MnFWy?lm|lv2poI;hNA`FlT) z40W*`x>S^*d(nnGO3m*{|3T)6uB-O*v6{FA;C(luu_cO8^>Q^@PA-YqX8z;X@Cv5Ypnxidd1(+=* zJNmgm9j#UhOO(81inPRnkc|<7&tkHm8=tuIQkq&UsygN!0z4HaA63t>*iYA|^#ugU zKKQ76IMgFwlJLqCNsj}>AaPUA(*`_Ug?1#Hy}jBh?K*{VmUkCE!&&4^wo+BaLQ>eM z`rx?92HJAVpcF`f=T@_!Yn-8GQz#zWM@$K2LWos1*?twQ$1N?`!Tm&XE+wxeZ%WhX zo4-=X+t(pJ&OS1;A+PK*Z;XY+^S(v}&SKB6A`!E4P@K1cc2hI^&s)u|NH@$(PX*@u zn4?8aKlV$fn;^KO#}9pYx5BXos*c-A*klaszM#IqtHWUoEPoQVjF^HMx=t=w&GY0P zW1+XIxUmnAv(gp#BORZ3cPZ!tEDou|o+UodB;FO&m52rTKw0;Es-uOiV5oLH=sTMxHUrxJN(rY{T9~EQaH1}J5>$}g9Y}dJj)~^t>wiUi zrMAsPi?f(@u#bPd^T&&9Y8G9_FV(DPnM?Z`iFnBc6r0~kCb4py*xQDCzb+&2k2NNU zrC!6ARuxh&uWmBAXIMzEhTiEqqerH6#!&(l@)u5pB`9>68*E4>u|Df2wA7@Wsgw=O zN9+(F2U3A-S~V_^K2%hnX^6WTrce4Nh=*tbLzCVgFuj`esu=R#E;^z!peNehP9Ygq zCddf>wdLUcF?yK~og(kdLMm9<)cqOBIP6=r`GU0 zmog+jv)H>%Gu4E=`&6X7QRnl3;Ukqf(nDjQR${ksi~dt=i$w^eaUx|s6Kb01OB3Fx zZLpCgemhP(bopQ|{{+GFdy9|z6{}85lbC?aoLWqb-$EX354RF8L_zKi>)98>mbNTd z2~(c+=Z$8v0XRxPt)WIO8VhKNn8a3oB(1Q{7KESBLD#Qj6Nc2W%?=N8FNkEb~hUp>jA;(ol5j}aIB|U`n-jOe@^4FDo!j;2I67a8)OQ!&NN68?BH*Aaykrh>}dBSwwpYWz= zjd0o7=aLv^ zQ)}P%4)xWu8xytdd|Nb#4w8 zcP&7j8ADmTY2^ph3>MNr9kwmuUEpm*me*%pn)~$PtDE}Yvm0kk?#y|$aPho|gdWm5 z#>TnjpXett!HOx93e-l@)UBZJ6^O^yBJDi+2ok(C-!A-n_=TpY3vmiA<#ni2DQCeG zyfJmjpZO~Ccx={PCbpxx0&v}UEM=&pVH^$rTLTLucsgSGZBd*7g(u@PF zE{%m!JhsR~mJuGV^~scn*O?rXIlBY<2vPaWq?O46f;VGLheD48ZL78;iGMbWfzqG; zj6qK9;&qvI8JEHP(#sv6q+2H)^r#Asu9<>nl3H|pg+Fwb;iA|7SVgRcCaG^#ASq+Y0kjct;}XPc%5@~c`dv8 z+H3s#Sf6nM(4=xIS@pBX38uw=9T3x8AzGzswK4@0PIK_NUd4jGWTgqKnjiJKQgX$@Gh|cq!nrKr|iyB)YvL;Yk2c3)EB|$&EK(kUN5JQ-x8eG?A^ zCSSi13&ouRHj{sjd94K9@b;{sTIn9y@}>|*V|`+oYJ-->VnH;WVWrsq+JVfvJft+i zP(&H=>^5i0CSm3hR7x{^CHyhCd(~V6i7!PksE>*)pTEY(#%6`JB(aTgV=2>JUCf7Q z)Kh4vRv?ldrRzl=o{sdSPr0y8Oqc63swA`8YEHB{LD#ZaG7|udYm)~!ur+}kyD~>= zU#tm=FS+_-oxW;%!>@quYK$r5>|e0{3j$BB$y%?NS|GBOg}yz`#^CML`=Jx360M#9 zQM41LKDJM`2`}}l0_))MsWLC{qvvX9#dBOoyw;LLZjf)@byJlIB>mXeG8H)Im^m`U zzg0c#)k@+!I;(EK3J2GEo}BZ#QOFL5IvNr_&9syvD1~yE!WQx_srSM zCe;9Jnp|v2lT;CtlrK8DDRANM!r>NkJ%E^`=7BpmoRzmj)Bc@{dJs#HlxW~kSe$a5 z7rAdwH@S{1Ks7^mOQ znu!hqe&fEqexeI-YjrqsCC#tFA~R%MTj!RY}lyjoT?DjrSX4%*EC5Xx3VM&eZXO&sOXZdx$qZ zOj1j1yy;-LmIkqCcNxZB!{Jic%BlCL`N)FLj$|Nylj<8|8_Oel$dw?wJIjV4V#IF3 zD^D~bbFmMi_bHZ8++|_m<3~~PykOy#i>R(Pn*XzSSIQX$`Ill9TKI%8+1=WwOK1)< z9GzMr{!-g#C$A1BhM+2EqtP2?^`-E+|Aj;}p~8fVvrPGky-@bA%ZE5`J1ZtheBngF z&Y5%abI|R}Lb6(Y2Hf$MsqUqP^kmcv$8ctI-#)Vc*2H_I2pqR^avBH}J4{m7)_KRapR&~}Setik z<(H4Eqc5P&>mr|g?g#dQQJsYT^T>4w8#ke{i^pf04bhsLN@#lCszKTI#~eWzqHhT9T8uPJL@^*oP;U; z(4Z4UV3-4c6lFPP-b=W$TL429&8IuwMo(3<)-~^+*YW&E5@E{Ms`+%00tK}+w3CIJ zUEu@^(MJN{PM&{vXr}xaP*cfllD6keDZ?3h)FvEuOJ5>5woSM_S(^5>CM+NA_5@18 z#5LCwbSn-Tl3Pw=iU>Sup&A6&;ya3NuQ(zRyU0)mPr@~`up<-jKjpruJUs8LU-e&S z7{@~gpDFv(Nema*FXcrXu#ouVONUyflF47t$HHz~xTDG6ADARaTIEZiUG$=p>7(JK z@s?Z8z{rEh`gphTEY&Q;az756Xg9_}n|Kp8_L0QO5@T2nF?)vor3*eW z>6kr&w9DSP?7>&iKE+k?CWl@p_At1`5NR`!!_|y?%5)r2KBI9J<0I*Zr?bRdAu5~i zno{JTN{rtq=&*qrxE;+TvlZ7=tTvzS2AVXSkFE3P61F{b??pba0~EUxRoiI^q=y6B z2n(B}wTc#XKHkI{HMt9sDk+W<)fe4PK|sU%Wu{1_8unD>}YeqC{zY-=QW`}Zcf&fG;^Rr+;-@X)4%idAfWFD#PP zY%kO99!NH^a7TqRoV*JeD|zjbxSd$KfOQg2;@lCMxkAiZdi((b-|2QjR@hu5sd6h@v{bkd zFZ@+oz7iL~Cww)>601;b(Qoqn@b>9|A)^(hd~@;po5aQW=Y7SO-04gD;)VYX8|aaa zTC?_+QQ9K65*~-lbw4P6h0|yAGvSfk(o@to@ek99Lw%LP)xWF-E}=%?+5gb1%3#b3 z@jqvw3?NQl8m9tcsapgw+lf2B*7;2P=J8!w=`z$Qb`th)YWYdriL<~mAI}DOJtr*i zT#v7N2xI(*c8N2zX7KMvd5)LNbhtz|mA8y1KzJed>P0()Uc%~5>Y&nOq$b5GGBV1f zhv3IxCOOu6tV|jsSPS%)DZ5Ur7JF11YSzz(%~5|*Py8*XAHuDwVeg#94Bq!~-C^~e z%Tb$(;deff?|B`O1&@JRH4CJ`?J;p3SjDvb^=)%=;Q5dfVyrv)++d#4j+<^9?Yt~H zsBergJ&B}-bSg)GIl*Jx3?=)y$OA#4s#v#sJ7&Eip}Fvv*cTf*rJd+CqNQR)gQcGY z4Ce4gnpEGMZpS&=FQfl=%&fsA)(w6@<6RgOXpE67Hf&JNVkei9FMtF0v*<6!W~yo< z_OqwhMBlOgNLIh-} z{1o2ZPR%4N;A#2!kxJ}6GD)OB_>PGxUQQtdyC!=`c?IqbKe9N4@wnsj@Wj5`|ZcRM3%4GhMs1JQ}-s>dvmWHMZHU9IuqpaMBHqsYrQ8q#gdG z!-Mh*V+Z`<&l`HQLYr_ZN9$SRIJRz;u~K>oYsF_#Qj0v*|K@sZBrPBJ^b3f zvoMui#=Xs@)SP$&R6jYHg1dQ3jp{5!wDrZgppxZ<{iZ&bd$!N*=XcUawn3f%JRhG` zNNv8$!UmHXjs77o4cd$G2_kLhko4&4ySJMVot1Q9 zHB}i&LAY6nQ(|-iA@etkKtm+&fvPfQ%S5pBAxdFV4ll#YMAe!~N(JqyChNcY5h2QV zwwK6UM%@pD8h<=vU!*iB6Hh$X;Qhot*@5kBr~^)06ZJ_J#fNkq4#`klGNV3 zpUGezrTZHy-S*8G%A)$mVf<<_R5URw?ta`XU;f#%O*-@r zVgy|=R^84A(qbMQRYwdQIj*^>N_p&vM>+p08eUS*u7QNJ^RF9(pSjq5nL7cZ)7KHq zy6As9+@5rTDjiQ9zL|q>6Y^j%Db{G$aT0;>nEtP5GcSJS$l+)bpQndkOO2;Dsfp2> zeX*iF%&ZM9L-?%sJZaPgIxHWfgYW3mkDiseCC$Q<-*A-4UK28Dj_^Kb*CT1zI8eCP z8SUH$0ZK1g0~=%p^~I}Y?_QJF3vO{A`;iLG!J>Uu!Gz3@P%4jLG>zyhzh!!nLMIr_ z+p1FP#KuADC1r1FsM~TBQ*@QSYWIBe5G?^0Y^uWQoO^)oH&HTYCLREgcgf^w0#-S0 z8>>M=NfnvSg2DrAb9om37`G4q2oLnn3jgZHt??=8H~?0re@TDeh&RtqnM&?|jmH-9-c5V%2l0B((V$AT0S3Hzu7 z)}y_g#Dk`d)v3FTgJ!$sQ6-3-tUDG@r&1n=LP?{^HB7=wDPg8a4S9IROVav-UO)*w z1x%ZiOG%q}4x-eTrSvH5AB;={nZ3OE2=1ugo4ZKdG z+~y0I$kc^k)MY}{WAcCUv3 zIDUbo{8Rpx>34y&`GD=1TS@gXqNc|-S-I$dcDkd>_wL5f;=eV#XDNycX~46MEb>FA zGKroQ!YWm&ba;BF6me5!EkKWmh|VqIU6 zZLY{FIqO%+am~GJCxnZ7wVq>Up^fshgLJ^3R0t~qUh2_5*U1M9Vae)PRE0(2Q>QfQ zZ9(KzXq#popiAPNey27urSdn4q`ec4Q-Pf7hno#RRIe~TYDjL{&{=1Z>7rigXTJd;Z)9S=DvQ$3{X?L(rVnP1`4WsF;dC@UY% z7eeAMM|`Ft^Ef(7(&S=s$n|&i0ZcLE&4X4sLne3R-Q=a!Fiun<#p?#g)b( z*_K?VS~#acf6JX?gz?bPyg5Q;zCWR?*+m}RRPSc=tR?G7{D@*R%?`ciS(6`F z|E4+Kr9u4rikXq*YCW`d)_%bjrT|llfFg-E0eGRZt%ui_ew#$^7A1sVdqIx0 ziUR)Mj0WM*b0{o{qky#rv6k=M6Sj`N?6V?4dVDcULwJ1mUy)(2Nhe+h59Mj5T&=I9 zOJHt6{mG$>%d2HYsX(}=&skcj_mGykJlA*Y2{6xV+}4sBp@2EDQ+Esi-An_$1XA-! zf1ostSt~8X8=m#7b(|WBIBMfHr)8@~T2muDsoQ8)wI(wo5i9kCbn%spF_2E^yh`LM z{<-Q0xi_4xR~drYeATlY=Kd`WVj;$J+J)*+4S|2ZK@S5prO~AExmX>%O}H!mWC=U; z7E$7r00yIY4-RbOd;IT_cA0%MFIxz&s)EB6+i4EyY!i5`r7{X00d12%c@^8Hmbr` z>a&#lAsY`=f>y`)LX`3$Z%0-<@)CL$w1QwC{`bYFOQBwaBuO~1sxxbHA^wRAONRlM zVman?aX-;Tmihy+3qhK*0Vr~r)DizeV+Gz@Np3Y4|Bw8~^?C(c)e;7XQOpFfF>WZB zeF{w>@gtYvbCmV(QNOf5v4#G19;;-FqF>d@H?#wufdXDZeB$V7wf~}_b*(x4sE;$4 zSCti*1tRrNU=iJsJ6d*7cz*)3Py=;M2N+6V?LgvqEN}M#3t?u?|0Li}v|Ii+#6xl> zqyay6S{{Q9lS4^K;A6@5iR85@q6HlY6bKi99= z;{#*kFPWnoK$ zE(ZBgojsvx{tZVhz~OAOlnDJKHoxJFQ#@5}PyKmPac%F^-zQ}G$v?o{r{nw>+x5Si zRll3jP!5B9pqtMxf(p0_d^S)-MQl%HpL{Rw?FI_pYs-yJbUBfigetyY&Om!6vjb&J zDIvsA9DD3zhQvQ&Z1>}9L&}e$=Y-Iy?;Lg=$mN$u;Ca^3SAZ&%>!xS|BLbM)52C+N z@Z}K7Awg-+mc5{$b_*sypiq>ZZBP5km(dkZ_Vh{{iOy3FvN!4}_2~SpN22m4UzWjR z(7}`oes9=ClA*y+5hm5(yoTe@dJ80tP@BN80rIo>IJh}x@&@}nI*4G$Bjm(p<(T(M zAq7-Eq1dTfp6&j&FaISik<6c;$v*R6*6Qz((epEZcPoS7+|j7{nTit^$!T-O^Y!ns zkDGZ(FKI1VYoKREFEMu~Lr5E@b80=_8%mm?OSEM<5p*~3XEb>)Y2Of$%GIJh%7Cg} ziP{mfQ=M2d(cV$ofuN|NI4*I{`YI`{+(?4SM5I^pB@!il;xwF!y?SIk*1Dy#)o5Pl z$iH8+W{Q2-qe5vCc!C@q)}CQ4Stz^^?+RCQN`&}-!$z==fDasf|y< zxlflL*WeCMrIHcc@;nU0yF@bqO8MAj;*YhA8zYttV9pE1nfBYN!R>swIO_`pWA9WP z26Epd^htNtW5CcM_@<|Ddnhrd`3?6(qKR{vwVEo!q2?D`4&WAeV4T&s&7^7HC%%fd z?7l&?-$DR7PR9I=?SS6!OftL-Ih1+-%b>^_a;eNAT3gCdTcir}kq@Xx{32D#z*^0E zgCLoW*+;PSI|m~}kiDUZfw|b}QTYR?wG-WwZpV~oUQ=7q^uY8YD~jyMP0ecF->Gj> z6F7djdZt0~Y7OCZv+*&>0z34DUgnVE5g~e`+W!+~!BXE|-^HZ7Uc`ccL%rpTHI@EQ zU_ppH_&;pZJASi5hbisxJxD4Y;I?!1-YB$(lJXVmUba)&0vfiuFSJiOr1vJu=K`Ke zsw+X(!pvuF0Jbw<*6)NFi@0YnDs@rNC%d_NkN8Lt z9pjyi08 zCDN7Spb48c842Hp@Fkyn$6pv%nNQ=?ujD1km+%Pfs|dOmjMV=-uy$t2pS+|yV1@|5 zwy_C?p{mniQ0XXIDI~q470W*oq|}90jfCQG#)IZq694i$+Ql-e7XR@uW+mQC92f@* zW64Za;9woib`fS&{~*_k1%U#Siv3u898-E8wSE!AgT)t%ujI^uZ@y<+*RFb5ftZSe z%qOKRrRjpw9kQMK{_{|7pMacS)w;;`58C{4(|N~{+Wi^xlgr`AKizPX9G46IEB>Z1Zu5#@B=Ci;h#@v^=7Ta)n|x< z1+e5Ozq8R}^>0eHGV<<}!<&0P()*8SYGDzA`|d`#V=u_x>to}Kp&}>)M)hbdX$|4= z^QK|(saQo!0l$=AZUawJ9*}2oX{NYikOw^6;spkOU5mznKlv(EEC!lxPU6FKG&J?5 z6oy2cQCTsO)jDsH4+{&*$Y#;S2ksRpDnBZonQ# zpCEMo+e4|ltxunF*6Vfiz(6wotOJz~E1p3_PYA-252;E{v28JtozhAsgr=_k8uB?` zc%eOG0%)1a80(!3E;dn&vZ%}HsC){HcnD`%W4&uqsk6Hw+E;b{0u(&@x>?|Urhv3E z0=RRdsr|dRa3OJT%D*_Tvziv?+~WoOq%PW`xJI1&odkRXtXt$AG>jj7w0a9;o95nn z*8JZV^+UQRPha!alvnk(rsRJ8=INYR>0VPRdSrJkRIXNAz9ud65oKfBNwrrslS+9f zqknrA+NSJ`)V^|gY)Z#!gUl-Q8&jKeH9;<$%SVVu{b!5zKlYYTpaGR?xK`4_)6CT_>}TlF||Ee+fAd31kbEe_c}P=%?NlzhL|C7p%;bz z?r)mrKc2J$B>UaztyBK*Xg`n{rik@DE9bYQflhLCD3B*_>QNje{j6zTR=QzYo5mk8 zT89emj9;g0m!ZCxO8!7!-e?NQ5LNl8CxfWY1rI9_Sb8O-J}PuevWr}v@6M%7!R%Z8 z^M_qpchRCn85ZO>H6}9|T#8U&GdN=0rpZ&*@&3NPV-d^C;3BV(Y=`3rJgvP24@V*m zH%X%ruWPgX^_%sd*B!_0Zxv$fB`zeB81-kC zQ9$f)yYFH{$-R&sTLJjMH2@S{V1wcBC<@1;UGBZ1$x*NoUGj~s>VKQrap+B|FOKN$ z45ppJu3&GYv^_!0?f=2#LEy(QnnIqztmMI-?={9;ixMueApS{@3w=3K%`-sD*Cx?Y zgbT8n5{ROz^e6aj*}F5yKdg!1mm8mGG8xs!Ok>(j9xvG2&mbDxK`%F%RIKwZ8|zZ% zZ%lg~O-T6X6Q|^0&yL}zRb&dcQSj-}`b0ZTQh|#xc?+_M zKnY0uwt=88(C<>Ii=p({>P)cUY^8=n$MA^DjNw+plseEsRZu}r*4$Talauq5$R(Ql zr`WX_cOlmU>w->n|fW`*?eEpO8Cu*>IqGke?vh8 zIV@_Z8GcK!$5yN?*kXSWjAV%eoIIiP<;U!J9gn(40f8HlalU@TvKg(AJKxLoNw2@l zm(v(ay1n_!Sqp~-Yo3|Qq+4blDK1&6hBFX%huOuGDgMHKCoszNB9_h|r>OXZ55B-E zxv$gmVWl(S;g#L~Lgxu(24$!0N7H4bV*{@Z{!y{r{%?DlDf^cgbJX@jO+e=)xK}*y z1j~e|6Fxxi2>BsWLi0@I0tx-eT&k;zlDSQ zMZhoi71S!Y|Ikx&A>vF}FX_{C`R?h!iq%NW*QP4+4D^>NBJ78DQ}5as&{D6D^j+qu zTb*EaUM}K^H7ZQDJ*u1AJ&*-9Z3Iy@FDt*P!8uV&+zcI^YBmjyb?0kVBDq1}T zW{&4gQ!NZJb-w#hb!p{GfL@#!fs{XTfiIm~C?|WsA1Tsen0L+uG}4<^Nj{#O6*Asg zQ>C?pvV!_tg_=Y9`$PJcl{YKd{*I!|?1L3^`Gg0x(kD0uZ;slg-fM||YNQMpI+CD% zP0#Yhyn*DFO^KZPHSKNuyS3!g+PxWF00c|<;ki-KJc@jgf%PcK%!c83Qv*1~=QG7} z)5OrD$eA9dZKK0Yv&F1jBTYWvdMtdeur*KCS4=fYBR@UIiPjuT5fy)=1nnW9bw&c? zA3S`FYP~JQRyBw1f`|>+rKACP8hF^*72+HbSQtfE$`@_TMn%~Spm;nbO3aE`*97@>jEfx5Ch2!+M;FaRIa zJcG2JS>Q=^R*m*kZ^5CWOC#34Z5;uokWhTuar#nAP83mvs#|w!WVfhqz0XkbUfI_g z@@2Z_{qbS7YfG+1N${OW<|VnE;01Sty{rR8PMapJllgso6+D!9kv&}alm0Iu`?6r_ zAu<)g{jr2~7`_x8-g1GYv-Vp}33~-9*gzQAmac(-7stbUD;O(d9%eVs)@M8ZzGkt} z?*&IXRnIY@l(d6)%opbVrr81aiuOtJD>`2U<>ViEHAQ;rv*VYC{NT8jCD|BiC_Yd7 z2JQJ*Fj&{0kQ2mPHo=s41TRA`s7tpC1kYi!;`2_hGVKOM1^R2&MULxr13njJBBI^9 z8rtg1=MIvgQR`Y2&qnrinBd6E`MFbME-XS)7j4-wCVmEUXuJXG^VSRNI_10H$H@nar@ab8(9g*v(K8;`Ch*LDx%ZP&OC zVV#5|`F<2K+!o8Md^#L2 zYiZPfd(?YjF`B-jF3qy;dP4Cqay^sdtFddhHm-N2kJpi z5ncYx1r9P4%>d#N^kS`LfkC?=QuFTg_*IEN5YDF1r|j8AeNEj2HRVW2HrJu$_r#cb zFO!U-1~tNW(PD5-EzJiqZxWt71- z_3)<2FZLRqJdFKT)<@E%HH!P5PcF6)X`6AG;BErCmS>ig&W`8OhLpObK^?<5^i^4y zBq>Vn#e!|=f-AzHg$O~CYAV%c5J=*ewfGKBZT71fw?9YVcZ0nB#r9v)=TpX#Ki3)@ z9Ih|nJKC|L=PyAVcqjzCFVIvZBSHzg z<_Ay_GFi-T-jBPMQ}=l`XP*YzQ;Rblb25y&;t#z!Wik*F(Bo{*@4erXmOb4Ejp zx+T9Dey*=srZSjdjP-U(1DgnXESeKEC^|7j9g7CWmsxeHuQq&pL2atFZg^>>48t4c z*L4L*RbB^oj9@vI$LI@)=SMzS+H;~*ogL&AEqE>X)jf^nM)95Ci$Zhxw?_|T;B1Hd z`gC7Q-}lX9=V~w|)0K7@ec9gmNCz%I1Q=y8_vZXyhGYDYGjkpXFSdcf#|#(2UJc0e zZ(1a41L(pWEPg2~;Nbi)l9b*8Ovk4I2b2rNa0B&7m-H`(@9zARSvXQVuhrw9N(v?$ zy5~>9iKen;k2W>R8Ke8r~#MWWrvax7A^KX3l!Hf1iiq%s6 zxf>%I$h=L>V1o&d=d|Mx1W!P6$-(rNaWl(DotCW{i z-Thm83sV_@k~`!nB-|n_mVnEmNe9l&qE8Lbrsd|=J^pf?+UDWkVxwn?gd<0Wt4-B^ zbglf=_XPhTqZ7arbPCue6a9;DW3A+wpP43F}gnraNW7+gdd5+z00D)^JzDy zM|Ddf3Va@Sdvnmn&nI}wCiKl2t66<+QWG(l;nN;8%y^_uc_m^-n2Jd{r47;1T+_;V z(SS*3WSNw}Yz{I57kP0aH@3*DRDa}tw=pXZzQGOUW9oZ3gpKzbfcE%cK!xJGOp-@f zlA#tYGN2gi1IN+z7GUyMLc8q)?9^z)bI&zQOOhMsND(SU!M{kbahjk-)%fxmVq(7d zl`=U$XqFrjCR??`BvFB8C~O(wO}#(8{d?d>!jNNm2&W z`IT-s!?%a~xAQ3B~b@$LYLK>&A&t)_$U5OauzeuuquTPRTB|Lmd#cTU~)=byg%gI;D!TUFLv?_eYj z?5{wa6M2noQ&_I0TS4bAmk+4AXeVX$U&|+A9K$Y*vCe}9^KX;l|2eK%ko9!~ErJgG z{7WK?n6eQ*W!eX2`&ICJMSEns3=)#~S%wq7pSuUd2Cj&*qIaKzWC?J(BwGC{>mPy( zV&8@2=@P@DmK}Y#GVujUf z!CY1sf8DP~Jl~r(#=v7cYL;8^ae}Gm{b4UUr3%!+C-Eo;j%*=yUL2_pA@iE~kMvG4By)atdW%eA?$n+2{ zHjZ-G&*;v4)*m{d-aN0VG_VvVcNqz`@2#c2bNpO?nO623T+h4^LK+Wl$XA3f>9+=J z#6Hpi=vAu_6tQI=Y`PtQchsVZVy45A;qD1&O%rmo55(6e~P z?Rn~8W*rHibh!r8Jy(CuW&m-ziGex$B|tq_gEDu)XcLZmqgBQC@P>r}rl=Bkn6L~a zY(oK}fM#(pK*^)bC0(0a)K9rF>-rSk$8hv(2(T$Urty5?_#R!Ae0cuDrdRB`b2jtU z7cuw>RjZ}zTwgM9QFC%q&*F;SBTcAcA*lT?l_}eGmqGUWgjH0{luMy6VJQ7h7CM{h z5VhTov}JyDbkcQV`TcU!7dwH;GSd&*E*9g5Xt~VLcL&M!aMy=@);+%e__wN&(SDB@ zhYF}A^yiN)<}RO~zpV!rjb^qHfBqHXW@R(EXu(TZfroVa(uF>M{?Y9>anc`&_$>P_ z_nNOtKAqs2IZK%>GLPl>B&ycqTE;frkllfd8fDrQ#TVFBqmeY6*L%e4w-?E6*>R0o zlIxfO<9&F$B4ed|dp_!Kw4?WT-;d%0) zj*?*~Ay~XMAdDXCN4+iiNlMhV{lhb}3-agICg9vjSMKu*1&+T~w@5F40}iyHJ+$-o zBYSfXYp8J!dae&0a~;|vj~3(y1a83fRo2jJ|CDd(2>9nGdRFYP37)ou{@<=6sK4Xh zCuqm!Pv`gy!~klK!__Cpv5`^ZK7XthZzP|7N_!vO6jfM_U+m-cl=?Js)%z~}cj}y1 z_}CbnUNuLR{F{Ga?mhfv);fgrZPCS7sBQynSx(Ax32sO|+#oH_(!<>^A$vd1+R2jg z<5azqw2V$|*-QyFsUu)SOb53P1`{O@4F~1nv+-hnqpUFC&;MT7Vd>f7;ByiqwGts4klkw70Mxv0BdZPMJZ5nOiYcl?lI zzrw5S0Uy^jr9bsSSi;|6JDa$dHE|2 zg=>~gNEyl-airt==pXRJJPy2J-Txf<=q+pSS8)0qZbOKt@*?M@O6U%1>-oqGHn#M;W%Ti2{aPY0GhmLht=k@|j7+ zfQ>)FAvJsSb2{D-!oQ3)#>q>Qfcs>QSU5u1M4bV@dTP!bBDbuC|A5Var^@Un5G$So zA?T9It>cux@>2vGI($}-gF1noyd=}+NiW3hSd3Y}pL94Htx~VV8Y!FkQa5MJW?a1G zN7W|*XfR888#P7(uQZyqw>b;#?72+!hxT9sC?`VH?W zqr8X?0MEd{(&;x?nw2~7nHd(8)e-P{CfYyx+kxdxu!q)L=va5kP~-tuc@%jG!K@qB zLaQXLM6y{A)VpE3*HqUq0walWJ3s!M>ztVOe56X1 zRI<8BpYnX<|46#>xRxLP{|QNjm5_?2k`RUvX&cc^k%*#+5;=y@we3xJ!a7wtCS6il z2NFBF?^+j?vURUxwXNOvZ{Nr7pFQ4>$KKmxk8SVQ`}KUjp3mniO_bK;6b^FB1-o>_ zl$H1k*Jey9BBiM~5NFu%3`1b{H!SA6k@V95IgMm_lQ4E_RXk)9L9Bg%y1YHSSySnq z;={wV>clOZtUF+Bf_K|oS=}+aIpz6^<43Z{1Iy*+g?A zQT>%_LlnfqW@d?~kmr6t{!mnIPJ8+V53`r#a6RjVpS}e`MaiTirGrkQ!f7XM>zua| ztQ5IRV9yKM_(>5U+NqgcfqCe%ArtY&M#*ShuQ7mT#r&RW^0-5pX=;NVze{a85vNDe z5GEgjj?yM$Rs+{EnQZCmI^dw*O*xSz|9i1vWjq0$im?<+?T>Te~~)}CUy9OW%2_l z{&_{6_UpJf;#@Y0xsfHm=PP@pBlxv9)QQ~GC_?;#|D;_#j?g%UyDw;A1r{DcZqf#| zOBRN#lY12OGVm7g@U|Y2Muj4Z>umdpIRc)mCphzBqgi<;3DYNu_0}%;Uy~)MWhgC> zZ#jg@z(KS^FNmmTX2Q;T4-qa|GxLJb4Id%j+@=3!wlY!f+tz>!nhWdJ!rT5#?wWH9*7RhqSOUW-?sGs+)kMOx1!%W%+mhZ$4 z$rMBW0TIFr+|9Aqo6I}3q3)OCsbRX6IVsK0Jv`_ZHznj-tkBKxaIL+kY`Gof+9W=! zm(l2Dsu}FtjA$IJl9Zf>FJqqiPy=oP-*J#UwBz-mpqtA!V$r@kW)hz;kM5XYlZT-1 zn1sxnazs#)tg(=MAI5dkFr?QFp(u?QO&o2*%(@j5LHkWQW}+hHS16ImBD==C)VX!F zbb)=;I7ppeORv^KP91cYIfqTtO*qKMD=_IOSS7Z73B=OiGW|HQ*^GX7MykNSfsk)Bg03od%~S9vf;iI^N^` zI9ZFMOwN`vpdV2Rao{88AQ|{=Pvx`LpapsZI*6BgMmd2pv~*7U!Zv{F!7k8El@Q#g7;gREBha>YDrj9N2m!uJ_`MK$Gu$Jo%HNNSN%4 zb6|Ta!yrGeUCxo5-`QlKJp;FDw%CZb?XW)v-$LAmmFOwiuW2Smd4t{XE9<23zx2_gwxI0D$GsKy50(4}K zlP$viFvOQ#lgKE{Wh^C1MDSRsPbR;dc;mp4q!P)hQr%%h#{nEezM2~pAdd&D(y@CT zeC6-oDLRI*5AE0;As2D}#-iM}vbcLWj8}Jv6aS66PX}DA5^n00{=)cNKDWJIM%}8V4;3a(N~yh<0F;1ZROq zI&!rXreQzR7pt^Mg2z19&~%74`^oih<+LKdAMgxsRq12@4NZeO;t^uX3)$f}gV+=q zJA)fGa#52{2|BZf_j^Boie-s}(1ydTbM+IX9)T4Zko zdOZeq2$Hc;;^tN_z7UX(Ef-Yg2sCYx{!xO~p!GhAOL!ZgqPGDv_O!ZwiQCQjwh&fF z%6~UT`2$JRMd6ub9-T03&NJvFdJj(w;6((58qf*V~e zuljeMHE<(wvIbF`hSHG?R)@ao|CP2C!y^)H;6H01Ht3$g7M&2P;P^Fx8N353!@P^QcshChJrh(T-6?P&!f(uRuLca_4|J)9F4jVF~bHnSgZ~3Zp0Wx$0`~VOj zeG&SCGkM+{JAr6!+d@di|b#2~2a3 zDyBcCQDn37fejc2b7Y%BV|h@GpDF4wtfRY0FVZ2$!4rvP!Izd@A1h)^?zt&kmzfoc z+K8LW#CFLz_X7z@k3hxExbDBSoo!<*qrQUAeTB0O`ur88}A13y9rmZ=n*aZA9zXUowSWdd`(umhL_FK?tY}j%RH3t#4X1) z&yK_PwBerqu1DW$dm1nDs7F;^-$Y0=FJ@)K=jgXYg{@*@s<6*?<&2}@DKc1ht^9A1m~4P2F)ivDdmKysI+ z@!YjS)PFEtmJyfd<59?6J4hR)X{n!$#my|DsiGj}g~&?Ne^%NO0z}EoZYo|Ij*Vx? zcdFpG$GnggxnQU8N#%&vSsyud_LTJ`&0MHPRsBz1b$!Kf(LltQBIH7BuX$t69`=Xc zh~PSi%Cedj6oq~5y_0`bDsBdtN`}^9HSXPD}mc-w#^~ycJSYlJJvC%iih}S$UL9!g{vb)?j5_O z51rLz&6{$)(x1JZ&Z5lF%~y(5lbXnvYB_#<$m&YS-$k4;rO{gtI!n9Gcdf;4QQ@ab z1kF&~vD5SQnEL?=W8rC_3aFFnj$$uX9l(#XCWC>3o9Mq2=T*VMH^>j3_||Mg{`i&@ zC8|8Wddg()su9V-e%D=9S@fcR@;X#T^~MLXQc+8mWbg3BQTQ$Hih(@qgGx82msmxb z9>+6LRmX+iK>wag40T^;Lu@I9PMvr|&A~pCJ*&;+2>9x#fnzq&eVyYc4?4M*elp4q4|L2u3$Up1Sx&&O6d)d-32Pmg`cYj zO*gB!Q?f=>a@S>5qr`|A+|^;|AYS-Y_|p3nVFeg;Z1UjD)i%;Wi>LWu;`1gPS9Lhj zaIR(T#dKWGCeZ@-1ES{5=HxL2(epHz8xSS31Z&(4CtoU0 zo@!LSi0yjMhG0Nbi3;v=%z#vRXi0b=;Tdn;|*D4Ngo`!zjw7{MTP5VbXA~IM(6_?H;^oSZlw=dv} z!!ZZ7n9Zjy>&c5>crZ)UT49+EGlEUhn=zNoBvwyMC9sww_~-QsXJ5nxc-J^(c>3QiJ2dXoZ?k_C09fmZrPI}dc z^zUg8Y(U?-U0EGkJJE9A#yb6`YM9@WY?b0eRAHm0xQ>Zzpdpm~S$a<~OFllIm{ySSIJ5IElf72)LX=IJB7J0{8RV@><$6|PG zteT{7R~?Iq7V!qecR>7_z95L)61Gs4~B9)Qou zYL9`RMPw;xT*5as38IfmDd1a{{V_@K&l~Ka^@uZvP-RhC_rd7RGv=Nq{923yUl|ZI zCsX!e$w(|>m-UZ7@_sHOfw_Nr_c>jNz1OqWW(-=IQ~HL zBVR)`b_0RtH3WZPw@&b{rdQqv8-(@1zezH~ptX{#sxn@Pm6cNc?3Zmr{FCF^86zTX zD+Jq+GkTqeK=-d1bCO=ceZPR_(jZ}q1O}+4#D-LzC<1ZRDe`DEq?-~vqay3qUq!&z z&*Y(qo0@KIWX*`l#SLmuPVa8-)bK%%mt^zUT4|5_gh|Y1JL%6K%)FnhzDQ~Oq>d6> zYDJ5Zwwi|iz%?=sWYR1#Su)+g7G)0|(!L7pScl{8+*e8aFo~*+_@pih17&L~FkjV0 zj+6EYvp$&7CHzOs)OLom4BXy!0{CZsCM-2dbSN)|KQMa`)w`#2;r3BihNHuQWws+&zVYOEQ4ND-wCC^WFtk+)(z86Vu2}AV+&yK+( zQE_3REX9d^K9ym1-uex)J`{BeyzVMkT1AifgO zd+Zxf{%dW>FZ9-xlA}B>{_#TF1=IRUHc9+Igw__m*Cijt{(5FG%VojU@MXrJ>PVYEE;kT!0R7!5iik!%0NR3*-p+(tS4@GegWUMUr4q`*I{Z5DmCc8TNBdOrv zd4O2rCiG@_JPuWnN^UF(hjCofn|BayRK{J>Avj%N;@bxqOFc1K0{t~aOQd-w=k&1_`+M&Ci=0}_Zk*r*ISuwcKDf^g`9JvU zsn;U7^+s$%@_jqRMWw=W7$;#Naq8OPJ%oTXLJ^L8LDFJ$EQ6KJYwE5!mpKh=>%^gW_g zq~N{sGGBuYa(debzj5ThXItfWK4ZHH;8uS zr5#kDOqjSO?C(5pmsZHao18bc)~5pVHw<9&L+?D@h50IgD$#F&x4||m@Z_oZbq?^f z9zY9xe%3W~6HE20d<_|XS+TDNU&=#nA)cB2S7tFHv-P1lQlc8^cU#m*61{GI0S({T zjjf=AE|a5ffKZ!Ldg9N(Z$ruCom&pTiP5{r3--&~H?qtIwM>WcMqKBz51S=};P~T!JK}NUB2MiX*rx3F1*$!eTU`ykegaW=T&gDn6?CJjPeNiZ^&-O zLxh^u0}a@ND&T)&Ha^BE4C~=N79OgM-$kPHM&381EK$!%DH|yohu`0V>yVz5hH-3r zNhyz)nE6uSG4LLt;58UbKdp+%j}v~p7q?Tl!+h7;}t z|M&3KW3n&N%Y$4_d8q8!>*9lG!zELGN;bfYobyU;jC+ID=2`DBW1wpNA6T_Xwu8Sb zS$;qjXqfX+ME9ETRNKH#K^{UoB+XK}mmBukiJz7W-!DGB-o}=nHXSQEqDq-OE*9qx z?rDz?r;jV?t4SB#Zi`eS;k~8M2*ow4rNG~;KvjU9q9oTxPR3C8;GsmO2^VB zY1WSoOAbid;CEKyat(Y!PXkI0dMNVWgl(D2g?rz~acr7oUpSwli$9Yr>exPXF)v0k z@Wzk}-Wzh9t}JKbEGf!gyHzSVNQI!KTqU74NEO5WN_dg>NOga`79Ln+QHL zn`rM=kC08r%&eeU%!lfdhQrb`3hzcpMbTzf@L_4=5hqPC+rbGgG8!}6FRz#I9p1yI z3$odsgs-vES^V~iGR)Iv-RpUuW9{#)XqbQFFTDs>wI$q(hkXFfH88msE;Ul-YF3pB zA~DSt0%jBHyY9<1hKtsehA(cANj0&-Ot6Lw=5wYL5GF8!f*ZWwH_4xalWZ04bq4%C zvzdjnBinO&S<%G9@$v-K(PXYH9+68}N<+8lu z$ui({IRNu~B^0Q#cQwj4q=mAW%Cc`ztlQVfM)gqUx!=)Sbmc#KT<_2uMCS!pA7c*e zVaM1?X36O{+!M%FGa;m2duMH?&yeGJ`1=?BOJx^g)3iB};+pTY+BqNV$nQn}Y? zhxXM=ojWa-*sq5`^fF{DZ9Rv4VH7!Lt6Q3O{1B7??!!dF6Np-#5X*b|68&qa;O& z(o%dey84H?i)$Y_)MF@|`NHJy9u^H@ayNcQ#r<@h8*Z0NsV{lLgrCacRgK_E9X?(RJRR@@~&yuffyXXOB+_!1%HHJHY9o?c#-VXnxDC|sf57DrkF7|cfp zh>xl;$NMq;#X_~SIdBFdn=bz9<;VbXyuDC)9+=x@Yy$T9rAlVo+ynNz{tnS7c>Ley zSOHT0`yIs*-Y?}_kgh&K?P#T+jiu1BwqB$frXqXhwE3K6)t%cV_QN8(t#tW1y4o0B zDEcmMoMR@M{LAi63s{BHhtv4pR`A=_%*g7DUX2Gh^z|EVEsNL#6+RGEKSMFd?rpX@#f=FC)y7niYbCfOV;p1)Q|Vl zb_{sTh23=;Y74s>UXNHN4U4`9pLzoqN+buYnEaEi^fROOesUU2F>;;u(+(t_enWm% zCFtS^Y|9}opk>p7!Y<%oXql#D9m>&YYNU&-KO#MQFmz^Ux9Hm%-lqZ2hrfugs1(Rl z%dJ(`IRgP|q0}W4;XOX_yz6&nSqRquV_WeH$PM~Rpuu@nFlpTH(X_HU-Jp*MbVfv> z0eu2v@95L;2jZg`n;#M7Rnj_9r}qQd>~L z!f1OY%=BrI=-%~jRtqfq48cvfvBfxAUwqyo&m;!k>My;ijCqIKwUtwjhzf}oIW@fz zA@}oieZbC#6rZ!$qOOAx!5wGHPANLRCO~oQ{35gg!JhcLV!>%pHW(%9~Z%dLdPe8aJJz(+=?Jg6UBil+j2E+mL7a#uuv~DK|GjplQo!a}tgxj|D{0xCoH?2xZ3!q8%6; zDhW}~G?~YAa0BwZA?MykTzzz4K<=0aE;{$tf*PPBVsy>jrokn98oVpmCt3Y<@ z5Hj&Em0b82?r+*1`13*}M;(Rs?@0e1`9NLJA!=lRXL@j z+oLz<-2saZGo@WZZ<`oj8KplZTRb;QS;GIm2nrK>I&o6co=}7QU0v;g)+#$K@UW;| zB%fa!o0f<;{g^z1RIXPTHdBp5XDHErx5vUXCoHU9Fq);W0$7)e%5?i_BJ;78v`;FT zK#y4%MHR#Kegsd~)L!;T(p3ww0ro8gza#e`+~7fZ5zEHIx>Z@T%%6$EKEw19`WQFbx6{p{sh9+XTTa?;l`ySaH|2j*vByaEzJ_~ua1lF1fl37!-aJT{DlIEo!L`K3 z$*Xn%3%eTx`w|5~qs}KmT;pLi?~zs(F>ehA({VT#4jZ|_cWSNH#YKg4GLCPTzcdCi z7z->x(kz~RnjNH0?P_S1d*|q6fU-{*zSvKJ-c+0i_MH-yS^t_1M?W`-U;fw@Xv{7! zxcU`%Z=E@7Ozj(z6!?Zb?`;y%YM8F?riX2HnM^-lU;%v0ZIu|3n@c|W&`cIeTU?4VQenc_(8Av`PWdZDg*s!%hcAmqT({A>_8@A`Q4kTTr3<75N8s_Supv z@OJ9tNowBSPI|_=`jAEka?oub+&2W2M8*UV;6Bu+*P(6I{lVXIM8DisIKwj*T9`GQ z3(lLgut%9fwa=I#!TKcNOKPLUQr^)9>`n*Ir_N-q5_y$2%G)v=r90V!SK~z8u$8@* zQRIJy;6}~&dNc%GNj(U32kIt?dr#zKb|U;u`SE--5Y>r@*|S8^AnQ!9V8Ki1qa%{caul<`v7g8iV<+=cd#q8s41bET+*h9|pA%hX>o{L!J|E5qm{1 z<+Rw`4}>Yr;psCVy3uQL+(20KF{Zgwf1Qy!kRhGk%V2(4Cw7%7wOPU1~|@Y$ASHxI)GE{t4-kLui@ zH%MR3Wh!NFakB05PiH4+_PMy7uHnD|A0Xv3SQF3{E?_nKE>2O-7%m_el+)wP9@^oX z(ZZnPM;gI+y!Q=FBh$th*~Q&tyJjlnIF;lDz28N!Z)SE*L@`w z2!Y%06LQSgjoU++K;W!#7U)@lk%%3-G{})OaBBL_%e45ZAa2X`yAE&<(&0G=&;qjX zu=?C?`R~vGZOWlPHqzV$>{co#rwx;}HC^FGSx)PR`f*%9tX*G(%cHpTTU&m(=I3k2 zky1nWF*dcKSHC7?&ww_Du4I#Lnrly@Tgu@x_`a>jfQ|O^=@7n@lR+-NZH@Tpk+&p@ zwV;+jzxh%z`QhT;>n|zN2P*{%tK=(+_ve|98FylJrEYPUlt4v%-d7dO^Y1Y$IBJEF zbQ!d!I!*@p5}9vk%D_F>@~CZjS}>Q7DW0_l-Z;S*Ha)21sPnh~EqNigYY_#~W6pyX zGo}z*Lt>`zKVLwsWZ+T6h=4LG`W7g=^Da{25ol0K-mSsL#HtF&ArVJQ6dJ;N7MDxG z$KUN+NWGjB$kGC2M5%19pm)+hQq zFb2M`JsP}2$)s?h;H`~~lzb&hS`~HS7){3{1m0|ogM^6I@k}mLT?5}@XEdG09FgUi zgy(;-QwMB+U`@GiWt(p)3EV~b>P|Ds8dwO$|JYy=+H37FUCT_I{Lm#Tlv+AO{?n;$ z#IYIALIe&POhz5k8S4t^QqCL}QQO!~@ko`EvRE79$R#iv-$$a2eOIf;Ot2td#Z@GP zQm%3n^lo0q`nStOV3XnA-}ch-3&SW|rJx{Y9!}%biDPWE#4U)=ic*L#!#{yhcaewV zMYT;h*BS1;WE*<0QdIq@n{0iF7ea~^IXVKk&*D=1O-W!kZcy=_Kjt@^1*2-TO(ET} z9$NJz!1Fi4qWg;CI##2GyjQ3evX+G#%(E9StP1fixRvi=fk6t2&yI)fCf16JIU&HE zFBU$8F_(44F?;0BxOI~zfj`s9JBRwMJFlBaHaI|Q7gOC3wo^?|R6mw*u*yG1#@BfCI232ClaOZQP+Q>ZVrsCm06_VFbr7hcqB(GkQW zTWZIXW;jcEe&BoU24P=)U7&IzDf=})NrcBJ^BqUXyr;<_WS4Hs!UVEFcHsx^?y5iV zt5Ncuz|RVBTS|13mkl`w{_hdY(rSmHyYz9`PbK1dZQN$Ri%B zgLw{JfmwopG7+1ofi0D_nCYHaQrBLk?I2o?*jjeM`o9AB$XWFz5O1Fe1LZH`@b72A z54pbT0-wtT?|1pC=A#8%YlqW)z0H>T*Q!cR9FfJ|9U~CU*LBc$@jB8LgqN|#vh7Kj zuZLOaz=Aq?Z0G}TxFq=){EpLU-Xz1-lMybf{c`xep?#f4o8I#AFNYb>fN;fqlHpR| zv$Zat$>A7oq^wDK29;Y1?ihH9Em}TA|D0>zXW%nZ_>%H zc6cXHJ9ylLkfctQ^(wTNtI3kaY5Tv`Ja>nII#gcCkF zvs8CBRco=n8h&OS!#VChK?{LR7i(ZSM8jTzbV`H*T?%I9nY{xpa2qbENDxn&F;52( zKHdV=uH_%(n#pPE^4@`>(=Ea-@a|}k*{ppfeWhTV{V4X9z++X&{t6@S^N;p=y~b81 z!QUtgRuIr6x5@2Fc$5DOWjV>L*{jXwW;lZ3_VlY-w^M0R`pR=lcumg4{s3RYcby|A zfGA9_)pkUd8m{`i4e)mIL6V4LGeO%vwr^Olv#0vLjf<3SG^V-tq78#XB8Rmh+-5S) zqO~Cp4xzXQQ$#t#TC_jiF`_FcaK@0DTd>acHsZULT1e4+K%)Ua7rFso$O&7b#mkG? zX+neM{6J!-EN0KOO<-c}D%`1Mgmk=4{?o_P zL1sQ4<`p3r?NTXLJEP>|JT?lNB5h{QDc72IIPa9anBYdmH-bIHiFVD>DT4il=YU5D z&25#UDfvHw!oAh*(X)efp=nF@Hju1gG5e+ze1F&0SbwW;FjzX zv)!Z2h;}murZU#Px?`@(8p^mjWP#qHKh=h(l=+SO^3uxTBM}D~*_`+g-y+YPmpt3N^hp>X>Z3 zY^GRm`H9K%P`}lUYI+xjfw_+=qAdQ3xKIf-P?7K2ZzRVtUzl;8UXP`rl2$ByD`1N@ z<^o;Dk6#PA1`Yxawcw!MS`n@1pn|^qq)=J8c$~BIP)|j|?lpB}OAzmb?E2>@Zv769 zRuV}hg^7#a@XgKHXR)!0ttAjkxfA@Ot;H7Ruio3TNIEJm8{#qxDGu5*DG-nMd`YL3 z+rJoBx%OdYk#N@y=}0pPa_PIkB3T*@U-1>}SRCYEYjzF$-@>5I6#kzZ&k*^qWSG>0 zusnARj4&U@?iwyhKhdoD`FGcHgoWgNeqRT=1l0$x) zrmRI?ukg5Sr5u}GL_KZF`B~f`z0{sBFKopzi&k3KnWnhQyJgzL6+gyg>wYM%jUp57 z*%J~cG)J~T>%6|iv+u0Oe6?pgeDJkQk!mld~qEdG7s4PJ_I=cMokn6H~TwE@`m{1p7`KsivB+Q`a` z6yAx`?-oS9m8|@V3D7+yVzwm|HUuNmR4B|*Q1mB7%g`S2!)wBIWHXr-9meTrBk<=>v>Z`cz zvI@ z&^lU|_Pj++O1R_^8a6$O7}OtDyNf?Qv2H}vEqb1;+o!1BeC=R}Hfzf^uk|t`PnyTf zZ|j#Q`Bfg#^mkE$JYJmS(-SkH!E;~*=DXs;vb-|*o2E?rapMd5dyBZg{(j`(x{!5b z_xHGs%i1Ql6!}eA_rY~qGlF|%H}Kc)-XU!7Ec%*o!TZ|XE2N9HU?#+4dd_u&WbaHM zVZ91{A-Qvb`avoD^UKn0=O&)nGvdAJtg{obq_|9c7)_TD15sI}wJvmX#E zOHaHO1F==vPHyW?YL2i`1jZj@TJF7ZgX2dRcOH6{0Ka3BERFY7bPgE7I~R&LHym55 zGZPz8{=S?fH|X|nfQJs0Q{ckbw`i}6F(Vol6dpwiwaSoD(+blI_S-! zCd0x(Sh0!fOoMlc52gxlb-q>xX;7v7LL+1#fL!N7~!I^xIR@mSM zQ|px1!D3V2pJe-tmg4(4ZAIPZy_fZvG;52-2+FYcp`8#XxP!m^J=ErR;X=q{%vZ|$ zF_Fu6eBZR~G1}Hy9L%s7u{lIh)#XS6Cpo z+PJb#Z7ymm=B#|9wOy7a8n(<7=Z?7^4WF!0#!Hz;40~n!{ZTd-_f;alH`z$P z{hFI&k*1?%+fC2@fuvG6XNOm;>uhn8?yNdZ$Hc2bRcM(LC#B|9YIO09x8HooPEM)g z7u<6dhdWzYUl0AE5DzY1L$FG0!fx<0S_3yvM5&pBx%zb-2|@`$9AhnLl^Urs6-x0u zT62}_`9ykA0Cd(bTJ7^}W{}rL<$v}*JgieGql(ujAx)FfKMHbac}1U~-Ts62RLfKH zt@;}TKAm=gm%4R^Qx}ZL6|aZV_@7-Wk$>K7VIwLl6|rL-5EDD0(QKwjX}|~{jXfw` zlMCaJ_nl#K18&LI{hX;Cxxt;CMs3$ z6KGxI0DKC%LcnwyYF^!Z@oG7`rSpbt=zgYWg*Tz?$v_BefS_ ziUjSjzUW|868FW#!JLH)l#)_?v z*pR==(u%fgob5h=C^##|FPSzJ2_mLUw!Tg5a@LRx+@l--zV3h7<%%N@N~X0b4Um@; zVdlbXI&2>5qG~4GW4^!Y15w~CTnd{kT}9g~un~g_%OQVl*g&pXj`YEO?@!s&)4KyG z!ML#yhh>3#6hPgdDpJ!hylR8eX97EA_xdnbz=;18P2f}}BOX6fD;PA~v;nb)PpMWL zBP780Fl5IDe{JhdYwftPTtoo7UX)Ts3MxZimE-$x8n1QjrUXS}rz+6vGrDfkau`P5 z`&8HmM`rV>7YnsqDX%0n!t~ol^7Y!&>^bMgi1wg`>3FJ8eK*3{wjs`N>~WFX-*@l_ z_Z<9X(>l;bld6PcNZHz^v;jo6vstJ%+tbsrhvx3|V@81GD&^{E{Y5BMZbyO_Ej7Ya15D|xUKBZ&N zy;Lp>+Bx9S|0y3{pOQeJpPq&2t%s?|n|A~&l+F}!V&_Xc>$xpg&_5kzYU)z+cwOU6 zfw>Jl7py9=4Db&|)QjE)jLV~rUyP_k2=pOBDTX_>SpU|g1Qz7K6|Bmc0ulr9pk z$TJ&j;9V(Ke16k5GZ)>1V31$&Dlc4B)M-gCN)8{wUfkl1&}9WbITuS|o^*@FK?BaS zqW$Y+KX0A=4kGLh9_N?j!!EXww#4NC`Xn+jA@mcM_(dEm&~KINbs475Pgp8a{P%O3ur^1HscQ2iY_OM|9aVs!%&*l@C3e%%MoSgXz&-#U>+09&ZbzC)8` z0h@<)q=kJ-f7n2IPPKeZ1w@0$_so`4MohJoszBaU;)!AAA$`7uP-3o3zSm&KL^N8U zFpdD?vpAUMY0N`A0y2+8Z{y&akI>j-u5`OZUY@xqN%4$L7*0Frh#?5}jCoC6t$;n? zI-rf#D*MT;cesP7D&s$Sm4`qhHqDsmqmE=Ja+(X~F=@-8;xtEkp1_~$Kz{WUNFm!{ z7caUA7o5NSM=M?R2MddM0e2B4BAgLa;bRzW!@3^JS3!5A$0n~@K}(s{C;6HB@Xt!J z+2CAkI*{5eIdkplxQu6HcA0s3iDIiOmB2@Fy%Dk`9MiQf+0Obec@!7FzuDsDL`!ra zYVKpa8&#Mnq4~MIevQ(L|G6*>#r<4IHQd)GG)&?zomB=nx3zb||^yk4)x! z6GEizV^0;pC;N^)`S`7@(-dPK&h&f;RrpG2= z&pl@FUI}$PbH=ma>FYnN1n}Z}JUK zbb?cFPn7nUh!+-D{2~ZH{s@HkCFvfcy^zQHDEg_`Tfp1i1uey2!RpxRfDAvU@gulH&hN_14Ff?cF+r!{p zW#ksju_F8B3jEH`0NL{D?3PWTjfVM$I=ZobN`75=Xh^D7I|KCB%2X=lx6@mW%D+D# zRS0JqG$E6kGKX&uMTK5)(f|T%IkcEsN>*Y~XCFAN&$7*1#V|^8dPF*M0LZ)U6#NIl z!YwYHf+yAdx?ZXFqB>>s2d*8&b2MG~q2x=kM27q?Li&##utDxBy)L;L&XLv8w(aBn z!%5@GC+6S!iwpo=*+tE=6;#|j?xW&Vi4=L`>aa3~h&`W4VF zx@jLaroJeXZ|=)}0z~FygQ%83x2gPjYmiv9ojg9AYa!o3hVO&`HSlCzYurDCl>pbr zJQ8}IhMw4J z68S5M!Ebe?s3GPgmbxFf+JF_-BAoEq65DJt7e%8YG~$-?mZZO>Y12-ppvvE@7S(7b z(&1~?5XP(-U~boSi&=;~6H_j^MUS6*tya#}6~{=mhh!_&o^R%>|C(Ec`H?8=%Mo9U zmTg`sFukK3Pqep+SYh7;51>$n{D#~k4Ev|wfmB_OIj~5)_GJJF0r=~B;M_Dx;2<3? z_Z}tl)G$AwCkdY~^vG4!wwxEn3oC#gkizwttFC49RnFfmjjc zIcb%QLR~cB`dcW5=T0f+mT?qWMJG*m1`=%n9|adF*)riqmM5%DlStkzOx}x;bjT`# z7dQeZIdo#3A`ZNT2@KFUB!TO)^b|mj|38+_J)X(`{o@@!(rM|WQkGLHWtB$rWTW96$Pw$t10z9y+hy8=wn9}5dyr*EDEQx*+XV8&9;Fm1m5hXH zR&lu^Nv@lRG>p4Qg!+K^5Dkfu^zWy8^gGNh9+C|Q&~&Y@x9O{=XdGIW?FbK*dF8q+ zsf}n>2j}2gU3GW!gUJ>ChMnBFDMc;$1+Z*Ah#e)BQob_`n*dcRvMvP$?thF+8RT)} zs<7FD-+tYKpCZwISTP1cC$+5;7;aqKtz}>!Q{;(1)1%YO7eSbB2z?YdDvcZIRKPR3 z45>n|MWfZ8eVTKuJ3`njE$CL%XiLNaIB*TPP3tGsOQ&BIwi$fCJ4J#M!ta~Pyd#lh zgTF%uS=zd7I8C4@usYWxwFLU(!pLmmKJz=2C79;-)muHF2lebp8QH1`q|%3qdLD}QdVX`HBmLPLGV_}d{kxrZs#HSaTHR)0r=n4Zy{28-5qT=@Brf~W|@Vv_z6@(?u036UVoF)MF;(l+`o%VZ00p7 z7Hfa*N>E6?bDZQWWhSi!6{JG?bxj3*FuosQzr)_&s6HgjO1axy*vZ%k_m_8PCKz#I z#__ql-7Y^tB$T#O-&?3&*XebcxLn=`UMJSI1!{if;hKv78zEtRk_5%$q3PUmJ}qDl zyHo#$;f!(TjSwQ~;v^E$lJti9vZjV2TNquzWsFaF-Z1~d@RTM^^exV36cA-p8rs z@DQ0{cu>5;i)sCPLTVu*twY>5Cux>pf4o1DRA{f=s8b&O*<^#nKB&jrznELe-O;vd zw#rj#V;fAiv(&FD)jF}BA~@;4q+&aInINIw@2FXOMvlg^XYXId!mFHMnn;IC|b)W=~ngbB35LrCyRx^ILigaUCnHAa^VH&d_FL zlC7a`b$h^h)Xfw$tXTwp>%Ag=+oH1)aLMwe2Al(VaJ&oQeARP$%dHzz)>85_cvsdY9cJ1rP0JKUTo(5o(&-BVsw6t(C>tv>*o(_l;K2?U4nj>Iw&MNo zMOOak_2(X$C~0$DGZe}NasOI+sn#GaRx~Jp5E%V1$$ml`l70hasA^TDy-(&tpoRh@ zyA^St%OcK`J0&U0|ErT|zKbgNX*omN6`G^Z7q+fzC_~~}nx;`3m!HE6#!yp>*G*km zaBbhzZssuRbN0VcS#(CJV`KrvEdG_fIlQ=SKjkI*6=T(q+pQ0GSeY@lfu~qM$>R6% z;MN;=XVBj^@3$Gr>#y9yZVZA2hT16q_T^Z*&n7)=t`C-HxS_G! zMj2KdLxICAn5{}}G*NEU73+m!&)Pnz^DLaM;sTRp3)|Nc#X9u#0#U7cHn3+X`0uTe z2CjPVenWJ`a-f|bzloYeLHz69_Cf^#vcG!@kz~!1;tv~I`O_l))ED;u?ohovc%~Hl zgm#^vO+ml&S$lRD;+=ZRs zA6_tNHx}{zd|Q*8rEG-gVA|lvR{eWiZ`^%}c^F}%{(7mt!1+@U+g7RXpF48~(i)|o zK|dh1{=Mpvf21s~J?^$`*@Rn-Jg7bJeCZ$1r*mc&;hFsBCJLJU@ptB1((afX2nRM= z6Zzj182BLnflC8WAaxz{FcK#>fmx)i@VqviIL-~3cN6$!Or*?u^wX$UH;SJ4RaABd zXhlMvf)(n$mq0hwl<@8;p|gX{-28X(B&I*znO8cy&f&fEG;l4u0cQr{#&o6^wn6@qrvb%5LsZFT`(yaMjIuT|AAREB@X3TTO+=jQM)rjU5pZ}g|$NR99P zJpTnk#a1Zlsc6Ru`ynqm{bnoYBa|l2t7TpzzTR+2HoL0rhCFC2iI4T?73H`!N5=l- z`yj@^MD_DD`WvlK+F*FP?qR)kY|9q9vtjlfDS7iqv9`?k%X8I^X#HV~75k(6F6MU~ zDYXcZpD()TMq6W*5BhNu`@eS&KVRD(H+p1oJ9i=|B%d=#=!GZ!qY5O2s=D_FFi=2; zifSHm(QTZPi~Y=feb$E4b~(x$T*wA$BG9TK+DnGCD~_v{pi6Qfja3y9wJIC;rg#&) zOd2?Xi}gZ>vDjVB)`#7it#4x9Yrf-;YAzIj^xtKH8BUY*@;^ba%e%ARSZy)agrbZQ)E=d{C-*X84miKkdIu;QPY9$Hh;>Va-(QGK~j`E9e(o_5yF=SSz~RyFlecva>Zml|^isqRn9wUJ;(7 zA}3z3Dz3qxJg%{A_DvKx=Z9YI_a9tDEnS0^aDZ{NuvRz23nqhKb9$)guf0R?IUJQLVB zNjNM|VDh33W3W%?Tm0n?hU4xhMpI$N;dXezd$dV(>s|OCehA)O8uoXluYCyjzK?jd zCc6~X^z6T{m0SCeyzmNQkbcXrBw9zeWa>oO0{aK)I;wX*95xXbw)cTeW728SCBc|~ z`uz#F?Ke`D;pgZNlnn>lh6A*Pc6|!C`O)R8z{eXK`IUuCo*-=&HQ?xsk}^s_J6CDo zaAz(mpxzD0MHdw2$vEF@+DA465VF+YNKsi|IN|oj!??sG$upb#owMMoc4Mn`B@Pvo zyYoZnTgZv@k8Wk~2D7_R+H0EL^cw$NAJvHvx0 zVFNh2HfjcY#UxTZLIa35_EnJvu0(E-uqLTKsEVSF8>jME&{wi8oqmoBEazR+^05;< ziJlz~T_UuD{4sGbRJ4DyK-s3+2L+_^zaB9ICe+T8FBcJcQdBPReZ-(8jo~^dQfCjJ ztI*I=PV_5ZP=_#E+ z0E3C?<_9063W8fifs$RA47AD(U=;rCS0s|B;hTxmSwZzW@r&g!Wd}`yf;nH%aCM4r z_(h}h9&!ZD@D1qkJ==;2j2KLWDfZdi6w+b}k%wy5s3NBF*eh&?y*6M(WFx9PBYr8U zP3XC^&-Sp)zX+)iQBr)*{Vm@6BrgMqVDkS@wf;nXm6D z&3j(j0p3V$)L8xTy8LZjkd{RDL2-eVz-($=Z!}w=2y5~b7}yS*O`5z?T>-Fk(o581 zocYKNM!X0!ll31QZR%_j=_*OJ4G~{}|Gk>W~ z$?~;8%UpGlRiS0C+roBj?#qP(m2FEo_c$+P%GZxHfnyY&(zck`5;TY75hXCYImxy> zPy~J%I70>|sYfvKly901&;+uhLd2gZKhuN};3h15$q;1#MLzdi$OBsfB&QPbr=>Z> zwHGzF_!i~aW0VcREAB5$2LE+6f9x1C2o)(q;rUr;Zn47mQ+OHmes~V?(@?`xnlzcv zKJ~HqJHvQ2>ngwRNQ3QU=Wq{6QfVg6X{N7^}D?{ni^~!yd#> zONb}M2ur+|)dQqB)N_{(^+Ss_$2;JZaWpCLC2y=-YYgH5=GNy^`+pMCAmDt~bGUW} zVbwpk%ZJ&mnK&3Pa?m{FEPW1-31|dneOn0oxR7t|uet{whN*U-oP6@XZlZ0!$dcTS zJ#|h8GVb8I@u2{$fNo!p@xEyXY=_~ss97J~im^GgS6p2`%v<2(x(;)}+C{H;N50RU zy0|i(`K%YSKxZ}T4E@`qJpY)#on+H0QRIhJFC|_Kr4uDdraC%qKYJ{MQ*j0J_@&S(KF0R0G~QtVdZ^l*4`5zd51tlKfy<(J%i;T;L}+v2YMyJFhS4jA``*Ya^n3Ok<8A zA+(7mPR)GfaP9D8{1)06zlQ%4$?4tuCxg5#)j_QD89R8JIlgI@h_7>UC;3y@#-5pi zt^&pTRzLQ32XaaZNvQ7Jl(>AzXPnYVOcQwTvgt*RUxNP5p?iHExlMGjJZ_{iD&H$D ze*Dqn?hK9=v66NrzZ$XE#WGlX0_}d zqj`8Ar<_xmGF1xn?EMjFr<}T@P28}cjv~OE?bzF)vxPS zrzf;3yIBoZhEB?RflZJc`DT-JY!;FT@9oD^UjZh;f?Muo`ayJ5Mn7|~f-}FqP3T3G zkHP!E-E5I8td@9p*#t{%DNe(unAih3B%MI@YqwiVZ)nd|Dinr;{*7b6a;o&rxIT(m zGrFyGgw560X5S#LEh$`2>-615ACh*g2q2VemW`6&T%fabrCUka<|^#K->+0JE=jGw#6Gv^^o`KqrOTp;aFI7C-su51aEt z81T?mLpY(S5$=nTb5jv{;#ZaA9GC$=^s}wB6lt-!xF(KUfzIzb=f5(~?!#~p{`%Fn zh)zRC@k@2*p?2}DLS&=ZMHrf5dJKJUdKu%;xy(7hlx70KeH`B8p9tKzbLeb2@dqud z20A2U`iCd6x#P^Yq;kTSA0nbMh^^MI>AMfgQMOib@y4Fu@AQkbce3vgPQLQYu-CmS z=U)NMC*#}R8=ZG%*wAOp3re65`qM4zv z9d}XsM!Pn+B}n7V&U}jkn*DZkjy$EWvJ!@14Xo-#MaNOt$U@nC*X@h4Xjk)Le#Y*u}>kL9W>|Z0;AXXc2%yhq=WG*Y7wsr7yB2u zguU{MtoShtt&P+ia8&}}_6lef@_&$@c|-_8hfH-LGw+{@s<@hnnWGvP$T^8G8oRAPncd!|GYPN|_{g0( zxi=0EpW+)&Xitj^1>UdmM@NsLD{b5&nmO)Pj81=ALnOnLH%487O*lFO@5EAV^ts2VqKJHN*Nu<|vwVnBD zILHx3XCU9#+S@)6&zyP%mSMU`4PHt7ntA;=JRhrc7Ktz#+T*W?xh6wwKGimE)k9(J zw^A*c97;w3g)=8hSrT0+8rx8*wMi)GptvKi-xq;pSgSA3E7SMgC&CfPqa?i^6Bk!3zX*IA^b3GMEf`-(c?W!FSJ`03pj zm%4ur`}~9+K%08}zisFqXV*FhD5zb~i6fe|${Cn6_%3r9vb>AgXQf|mcwMZY%WV$Z zDM81BcQD5&qohs4*pUCf6VE^PzgL$sF-fjtFrY!^Te%I<;;Yjze2nyi+)F!LP;Ailjh?h zh5)Uw099h@;NKYljp&+hrs;&Ut52#byp;Py{ zS*rNi8jCpnAQYOoyWgQpax1ZTQ==V)senz#D6DtGOW3-~r=PcXYL2NA@D&@&o7df( zMPfg?%(A4un#n%@hVQj<>r4J2w^Bv-d&|A-5IJ4CF_~vL&z{5-6i>LdV@KbHPF?+6 zhg`kH|A?zL)wIK0A5QjhUk%}>utZxB zTPOXbE1=-NxREK^Z<}~14z^gmGlV_*1o?Yn9^B$)0?7?i_|m194Q+*b28`^6NMsnUa$+U3Mrg z&RA)X(aUk;QT6;c%%Eq6T5{sDW^jt3%)|6gz0?>h^WOqIH*UXog35${MU zMWz+<4&y6qcBXrH+i8EgWGrH>J0;p+wiVu0Nvg-7YCr#<$cwAYW%T*UEE!}Xi)pWy zVfYX0#VHH;{P!*T_SaE1`w@$l!kBuM6R$0jd_81I-%6gyklQBVr6d0-&s%5(vh_yV zVC5wgc){PpUo?8o=t`GXuhf?GWkU2~R=DawGT+zl*lRZ%32MHDE)1Ef^kcbtqYwc% zZ#%eASu`JPLL5z07s9wfgKj#%u=PYEhJUVjoMJJWH06=w5rAp~Hjz;G5G{9}skqJf zkH?9{%1a(W$Ty1}1DIs)6X3vP#_QwJ>YMWp({h^B%Y~hKGT(0ZIGAGbC*t_-{;+Q! zN>#}t1%^IDqT}vwv8iuBoVYNO`p*=}ItiZpP$Ma=CZ=n0j*8%bE*2N zCQIU>>^}dTEi#)4jx7}%FcJglqf5_}CzQ;^HUbjuEnP+u|63p~Z<|FC_u z%@jMOMR{}eC4LAzZ#ta1B}PMYy~1=&M9I@bEpyxgzIg>?vwknlh8oe~S9J{Z&ZBSR<5x1w*Cj1()E9R%B@`ECWJ}-knx(&O<+);hY2>$fJRUNzTy>Q6Fm1p1Qm_4s-E`b@{n3~4psuP5 zC^#@vlJW)R{TAW`%Cdtq70%CA8CNsEdKZh{?n9CKt4$TYJ_Kgp?AN54=vEyx=V1kS zV2Hbj0(`D+@w7FNJm)NpFOGXstW-p4+&iYuTKeyXaESCG_mjaIx#5PXo2$~1bKlsb zhXJF6;4Nv*A>g9fl$-lZdYa>3i6sApqBSlOK$u7;zVU4bIjeeSgP-Py@Qddh8613R zeOtO%DpD)9ft#7C-VEbmoct{i9cS8d>o-RD24}SHt|Gde z2E@rdzQ{MxiAvSx=I}d6mE@9b&^?C!Hk0SlX%SEq_d{LL{3gt{xz)iH)NloiEMiqm zL{wny!6GJR=oY$bb}T*{L%%B7TvdG3R3#8r?JA|N>@$L1Ey=>pp3eMhc=kAPIGuki zwDA1HWBmUThz)(t`WJ+P#MFy)k4S;pj{$0|EOf58_&{8XeqS8=S$`xfTy?>T!F&rn zvR#hV{og}%-b0@_A8I6vFPw6FraJ4&h#T%x9ZD$IMvHYeM9~*n{pAli8&6me4;9hP zc}ACzn=9``MYs=i2&cDuS-)uKXI1C_!;S!9&+Ez#i&q=>)k1J1vJUlhH!s3ghsim> z#cB!4ZxW1b;p#b3)2qGTz(v;z(6Fn`Ctk{G(Ub>Mf5N-?y1jyzip(m>wu;lhHY07l zZ4oN6{_qc*P^dr9A&RI|q_1HfiuK|G!@ktHD%_y|@8(FAGWYkqEOD{R)&$X!cAQx? z`s{en$*hNxRh2)}0rk6l747{l<{h?K(P+4Wy*rgY;M}`Z`$Cxi$YmiF__2i_jrEYF z7q;nyas7WMF<|JKjL5ngso0EG_-JSX$4OY*dWI|vo(cX=dU~c9n|Ke*)me-)9bmN; z1^GSeU1JP-(6+2swZC?v7h+EFEY3`7T^>FMmgW)(Q3BbGaxi?^c&st+`S0dWRNbC) zj{iI1$+&3hTVtN{L#JZkG<;{h=F@h7qsTt5T95&D9f+H>w$j?Y5=3bJ^=&@GD7&@n zUw-!zC)nhCbiO$`pry9%I%mycHf89t0gJvfbrnIzS?=^ssYiXDt$M$85tYmKYXyR?#Z1La)(f!%r3=gbJ1$rlOz z%heZ+pk;yKvU-(#_#j1S?VO@2dSZh+Q8#dPtk8XM_Zel$5N-*B72fq!vHoQ)#KVs0 z%C9~vAJQ`^;Y}_0I2Rx9i#WRZqwzV_#W#%Ad&S=kFG}wbns{xw-1Js&FkTX;^w=Dw zNDF({;!$0kUcIOUSW!yn`YdfJ{LT{<+3>5{i7B{k^y^aN1oMPTwX9E))_j0-V8Pf_ zezYck>xFo0*e;?a^PCOOiZ)PrNYq#P9f2aT>DarbS)jN~wWa$3>rkqWU)Ld=+glPU zw=YCDTzad1W#35_+|Sc@-D->3%PIUoVh)c_)qTRE9lTfMla7x)&{O`NOM6o(bdOQ5 zR4OjhtGFH^3ac?-PLbBPHWXFcID$`g*XHw%P5PQoB+&?^ofK0kP=pFpTap=3yqzZ; z)LR`&{C;fkGdvO@jqoNPrVU+9tmkLf3H(`ByRju6H{45tliIOgpN3FHuO>gN8Vb#< z5Tp}#&xL%(Kg?ky;WX$NHH!XFT8Yx~p`yr|2&tp()^$z9rog8Tf9_+m$};pokKw}K zn}~gykO4|8t#SF>UfTlIswVm`2dCjeS?b=m+y!G;pTqKtOLvNzbdkR+UeMbm`_#-c z)DBj?dI>&{*c22pX~LL#kYbo%y~D^@ZPY_VcPrRu^YqY6*TYKNgx;0z&va0@9!iJa z+R4E}s1ku`bgGHhusFdh&+cTE=vPgBHN1sYH@SXKNxoF!_yTZ*eT9BQqm%(A>YyI>3Dvhj zLSPMId8|y$TDkQy>+`xQ6Z~=J&JHux?OxhBMex+?f7p7HU-u@wE}&Jfv|W*(EgJkE zxs7cCJlR6}ax$RDZ9=(G0a^4OEVZfMmX{8CyyQF5+fD{_F}G-kKAVi_KZdi9pbpls z+AkTZIm@{lB>xgxJUr*j;@7QyP|Yl-A1mUzXzowP`F>x%9+#F!zHZxZ@(G$rZq#4A z7O3gK5>qWDtc}&&aw|esV|F@mqryqN|JX1|aWAyu+$`*d^G*^^dSRY&@mT7Yd6MZC zM3;K&#cG|+b7g<`O&)#yDvjQ9zZ=`5$v~{8h-ddI9995}L_WH^{eiyS$RrxJCHVow za0yGPb&rwO7htC)?l*qn2=yg5gx_(^eX_uIFzGtoH5WHik#VG5MC}l)9c1~@!-hi5 zC_ze|CAy5Z-2X-KAul3YuDfLOFSLoIcN$Po&MmHqJ5A!*U+rp;uj$tAtWosQqpm)DV<$1%LoxIRifi+a zl3Wt%xM7L=2xr&7z=xg2goH0RFr;Tztld=t+#}Ctu3Im!*gj9@`=2q+Hi*>_sNs9B zA5pQLb`ukC)4|)4FA}eJ?$4JEN!D_QG*@MX#^r)XwueY8olX9))!z@zwn=;HH~WKT z^Dz@iv)-70lm>rr+zGdq!BXhY6C^1ORj)R6R(izJO_%II9kSNNz(IuZRzBe1=z`Qk z%j4dojsY5HYBXZ}e;H?EuLb;_aQm>B*=hLTHq1M;DoBZs2%&&N zm|-EvKFT_6zffK?sL~LAY*;4|SoKpz8j?#@+mb|#SmplztvxPsoDe+()`syHJ%X&{ z?PQuxi2mzW(aJmPRbi1UIfs8Ky9Nl=q?ZkL;2Lgt@4<~zjdN}@e-9r3GiX%WWtjT) z*W~re@BfR5(Zu};0hT`X2ebqfm<~t!H&g4|c3bEY{JOXvgDh;&fO)?uyb;X+iZtxu z?!q@=tS`F{?KWs7?h)C<`nUg*j|=4&X`+)uCsuWO-BARqPV}?vSph&ny@R~@!kamn z%CtyzWz`z7BC+`CYA4&g+1#s)UNb=#H5O39CsdbxYi~VKb^~ zkGpRp{;A?D48l6MpkA15xbD>(52ZTD?|9|mE_LmjYGlr$+ayTS+svo|c0-bvPPc7$ zTgYm|Wwl!l{i6O$xq)x=RKE4S#ao9%4GTWxax6B>2>5YIv<|wppLvD;E+U_^8;@FK zXJk42PM4An)cIPj%cWaQXQ?9hP(=}I;cF*4+LrH4vcA4#%-?hUR4~nQ1UF*J7>NRI zlwijc6W6t5kI8`kD}LIran^zt;3D%f#ocqj*r?kk0o}#JeOPqf>B?K~i{ft|qSP+G z{O^ZxG48Z9#b(geJ(d4wBvO4$R7wXt+~w?*W6)d>9@WFPqnVk_-rCw9WU0ti_c_P) zDhKkBk)&0eB^3-?7Mk!Gexv*^6H2ECbU_cQJ9t!c4X2V`%0XcKGhN zhA1WV)NJB*Pww#9ni{d9lx_hL`k3!tOa+UUyynD>d)^IdC_=qqs%m>VH}=42vlSYB zmhzjobSGwKXcPC5?+9s174GFfXdQ!;6LN?h9N!#r+7m&e)gN%2at3*`5n8vn1W56T z@F3A0q4-?GJ-5sx^QDTGiLMsyx;GGi`@pR^u`q5WAf6)B{2AcY?W^2bMY z4LvVGwKe|4${*ysh>Lu4YNv$}w(%Y_$6~=yu#gf9_k9V}3i!2?i9vKrE#YUxr0A-w zA*;PPL=qC-mK;gAeORNnE`h1LNvkjDVC=z1k;Jna>-i(uO|!`h&;&b=o!XyM)ZbG} zCrfAcwXI}7h3{Fdmn>VjAY3-`Y7Th9Mj-*tsDzm#A(?BZd~>6Op4XsT%g~N>6R>?| zeW$bL!bel+l4OXOh2AQMl4gmV`$W;PZsfg4eht6k@K@k*ON1$$Vzo$1-zlb};U>3D z;OBR0iPh>c^qEFCgV6{oa3zXW9Qzhw*Gwe32Tav<32^SnAvt>_H+?WpBg+o2^3il<9m;(oE4#yw&GH4as_!wKuQ8iesf|bA~bBBiF($rO3pW(KsP@(-p>*uin~c z&4EbRRnvA(jTJJmct@UFelCr9qPozxiFo_a6Jcd|?@Mlx%hn;x;j8eiej7}YJU9vt z+pz?09ol^#6d%8N$n67|1Cz}1)i0xf1*v(;>#VjPV9uT|^-~6A{5g9GN-^d~9?@p| zayN%MX8qdV-p^e63OjU$f;SyK)<--=DtJE&4vUF}!%|DApFon4G%8A)v|z9Tx2C`F znjx!4>-xm{wwp-{2-BBoAHJgAz8<1@(@ipl5^UoT8utYdu8Q&*dCHh%K#C|beWfXqmWZx&nvp8}KKa z_}L%mG+ZvP2L7CFDhUJ=2RJg1=e&6%fX@anor~Of?2sFiSPr?PJDiZV!kATK8y=zQ zo_pqHVO9kmAee$(pQ9Q&1)vWM$Gl}BtsmcDJ?FybQ7mfip$H*S=5J8}xGrL;IS%i{jgEgU=%sy@EroVd~}E>;GKhex9c{;hY1-PVUv| zsPvf8$?GlSg;f2I}(Xu}8y<|VWP4)h%*)i&K2Q?Sc3fn-UYEK4} zAI@m>RDH1=cc@#$q;RL@XS$ZmW5q}KApfbl*9r^8>6>c{J;9>Jy|qmCk`!5)&vE|T z6D7C}At-Bpj$wzvZqWf&B$aYmV!C|$1{hp`W{s_i!ZMvkFrI#Qul8wPUSXZzUZpu_ zq}06QdikIEU?;EMYI8T=qlW(DfY|ksQ##-hFL+44!uY&>C;#75IN2&+SvU^w&elHM zsMMfw8h+XhC{^=B7HM!UG$RES>s}NMq6r!3R-r*n7>clfb#_P7vrd^$VWMJ4q$`HG zk<`AU@>}O4ki#rJ%{%M&P$cj~zvGcjM4Qdi?bx4k>#v99&FskI5qxL4-iqei1ci+@ zk`}TQ&aRt8VxdX8e;(J|>#~TS+aWFu7Q;_jqLsijwhF@`?a z9s;(`OE5Pa6uLdo{7?}t%tT&oW1(KAGnXIGx4QLG%GScT$X=_uckR%M91iw!_b4em zZtTP(d*ISKC=+l!(}wKer+dG1kSkW0$MaKC8E8Kja1=*dpa>sBhh~2Af`oh zf%$Bzu}k5Qg=!rgxj$D=A3OtfAFHxC(mr*^-Tx7J7TpEwu1%7tp{v}hO}(S?i$;+g`&>C zUh%&0_53-aq-GOYUSz7)?uEi*V@NWQ-&g2CcT{%U>Wp{^)0E#O8K zj?`I*cOQl;KK)CdD4k z(hlb0(*Re=PVe@1dP1*dHt-R>FF11GAgh3O{j}(Q#x-TfVPHWg>zdRL2x-yUPflA^ z#?yTQ6u7Jz;bjHWB4-iZ zK9R+FEZgV(q1sk2ReQ0~1Y*eHi?^^x_lhKEv-TGgz1K7n*pUh0Xd18RGvM-9ut<;9 z;}5j$C{T}b?TgQc7RJzCF&joh2?5HszRfqf&H6O2by9d@SJY~&$J!?(4!Nn|Zn^gc zvCBkRwBaNw2Bv)0TH4)BkL&El{;`P?JF7+Ng3cp;5r^9qy}y`yYO}$9M^-6iM6=_K z2QlS_)|J;gW{1q}xuH`0(H~X>a2qGt51Tnm=6%JgZMF?o+Q-A^vM1R?i!CYl(u0*V zVgN~Kw3PiVqFWU@$n}O zAH9$j?73orZc#t{01;DK?i5Aj#SC#rz7N}TEW>Ds?}+FYP!2YGqcl?5ZOL?Ju*i;8 zoVjHu87ltORJgjHU-X~dBt=2nS!?)mS%+<8T$03D0FCEQ?{3@nA~2a~BN2#oR0phI zly`HDJI(pEB9jFpwp+ME=bRtGTVUG38ZZA6i1wKq)T4zD@fVMnKSZ{5v2b-!!g)iL zV>+{h7(6A@J7z+EDlyxu%a^?4k7+e_l+|be!3!(ncXLoWdb(f%Jjw2Dl|Fo}-w-jn z#eOe4ilAIx2~{B6Ri2MUzppa*d^4~CboX3Qq)DL2N+r7_!Q#GKhkGgfgS`@3kK$d! zBicEEuhcxQI7d?ZlbJ${(#-6tJbvQkJ-VDNt7C$=n%aM~>+-oHs#$v)t*6-KlA^{4 zKMs*U`#*V&awa51uP7e%bB8L&9flCY%@m*Th!25+C17%=MF4m87BJ`QpRE+10!3|% zU2#vu`ef!F#Gpen{7f|m26ckX%7?2CO)FS zKz}a@lp*j9_ZU&^!M{R#Rr`>3no{wEKA@>d2O0`Pk5S)}PBOCCiwA;6k|a8ELUZBK znG^X(j*^lA4q<-+&f*I3WkT~fEop)k>y5Mw@95GQ(R>LbtUT7vyewVE!1l8;UhyZL{9$XfQpQq)2ydyW5j}cR~F+R z&>vxwfbXcyLsHS9hUulXzEYLCZETqUpL0bAR-b{#-z| zLwN@lK%UNb_OdfjIknY^*)P4$-}q@5PoJY~8DuY`r^P|t+RN%xq5cE+3VLiFH|{P` zee1f2if!kSed))69no>Cp3^?h;4mZ(9N)@ja;N?Xy;{}U;OkEieMe^!1FS&!oca+b z!hme8zW)_8G2-Mw(T^)V_4?*TOmX4VV~*4o+SsB73!ElrCjJ*uyXl6?8TkXurb)0J zW2r}Q$^AEgjp<&&Ic*A<5~Oige_X64P73U1G++v&nu@gN&(U{OtVRjl{luTqS4YK~#q>hL_ zByaThDLdSb40?A6;H1j_o+61J)0}267xn841mY+BbA$=SQ0amI>yoa3!MGqSc?7hHGJcaoQu^S65 zTXC0|T`BZB2|RSuezuA$CD5i~Sq3H>RMpR5gZhU7nu$3VhBLP&l)~?R5g$_@u~_K! zn$xB#6MYHMYLGwMQVqG{l%GU{{w}o6zR29e!WAeqNFX$v|D^b(-Z}lzc|r=iJHIoI zPbKN@r9Va3LOM)g)>{3J@U1Eg6?f^m$(}KcLF7gQcMNEnq@w_vQ}@94^YjKpe2pL^ZCioKWH4#W$V)fN%QIzy_())?+(S-UwEiJh!*NA zF6FspXTB1-b{0$aaMuYb4-iL=a!8Y|o`DCdB9b^ert^l6Am2DCJkhi6F#2^F@hqRO zLiMZi@5}ReU!G2rS!)Sbxz4GQT~+_b(YeR9_`iQ#LX?l?7@|of=OI+=ph6UK&T(^2 zPLrs%wcV(MVmeSdY)DGQBuQ$!la4y96P>rt>#$low9~!a``zE)e`}A&+GFqgbiJ?Z z^?JV8t#O~5yhqdb1cy$v-D7yrU-tbzvoetCNr+`U2vxs}d)IJ`@a`_!NID!vI7T=_ zH1`sYG!}4~&ed{;F@v#>_)oJ+XP3mzpU35iA36`M1zry1!y7GoQeV?srRCmO`Ql+h zebo<6O~m_nPSweDuSUtlF*4!`Emdjh=YVWA_Xn5=NFp(pl8#{G&4mHqTda{bLap>$ zV@S~7Sz9I}B+Ng$_7YtL^7p}?%S2qf1~Y3gze9Q#WL8;s#wV{UcAol3_9GM@H3Qd=Lc>hvHV?;leJgj>_KdHD6wxrz$b|B|fnC`PY za4hXDa;822Qaj5B=MHyP;oS&lGV)oY+?1ef>fj^HWknBdZ<{eZPCugQ)m|YSp3b%H zGJCIT>U88DngnbrQ8nbIz&(tXjlW+>?o#vf(sa1Aaz1%X9uh&^2KDOnK@7BW{Mn0I zBe}BvfnTU5<)pQ6D16dHy3;i$Rmeiz!}4C;sImzAZxMfDXoChjSLS%cLa}b281SP_ znn-D(IrA_2po^F3sWk9YW5nKZc1ZqcEJ00_+tkV-mhB}?$t-!MU!kKX!HEDeMWS&1 z>?d9G)tbFB_gbbbjU_y%UqBy&e~}e6l0YWm61`XMzQ?NpMW7~00<29aQs{+_kVJ5_ ze#pS>C%(Gcg?$o|>p*$cWAjybx$JAXLqegtK1MT-T@!Q{Tz_o}+i;{0^39(ye9FjVvTpoQ|uiDkAhqwED*JOSegpXXhx^6kyFXxw4b}x?QO83NfQp{h#V|tDOt4Q{r9hZrXy8 z#64Ffes~0g$tj;V?;}jXZrVn;s(V1-@w|IcI%5luc=BCJy)1hra8H<*BmQWPSxfEW zI0G*L>54c0SSR;g!DNmXFyaocN}YcmC?xlkPy;dTg{SnD>zV_Qb57yGv1E0R27ScOJAe%I>xwG-C#oS}Mu2HF;|;I>o3Q+}a2~B_ zJau`tcSfN(MR{oVm$a|g6y3`&DipV0(g6-A%*kBUPf+yNGAWe0X*<|*q@&j+#R6F^ z68oXN_R=hC(PhVT;gRkkbR7ziFsOB2nHP9K)4xjxMt`Sh%S z;gnFF4_{ZzVMt2%8tNR#H(7e{gz*Sre;ww<(px7q0#i-W_1S~P?4|4?l6BC$dk5mf zYg#)*Il9t@^NgyP-5bzs|AiuWO-l0@qNm1FLSLIEuet%>5fbKFz%LH6pG&;E*J2n9 zQE+H7x`$#*TIpWv6(61}zo>p5N+1xr8EZKFOD}vH^ZY?UgX3{RF?4L=Qv)3E#rp$# zBC*i`}OnaI?F^*T{rFF!@QV(Tm9elReODehk4)S}!GCA*RSPT(8_&iky;Wa&HVP*LK z3O1F0Q@DA$kVQ)Rk4#2uD0SW^&U5E;hHtd%hp{oU zF}(m^SVLc_?|sdOTnP7uMzNgkg$XUdu;LtCA?AJ|6b(w@fEH3zqj?VY`)_;NJ0ptH)EG|MGSao z+cBQu>lGI)w8(Y8$O_xbH<>;kzD?NLX>oN{_&9N(?KY^s{8122L?0SNZ=!xdhs&E2 z>-b$NPbmBiiSsNWRR36^Q`4~oq}*#^sw3nnx{o4vMGYU-->MkBVMyosX&M#JhD_4Z z2FtaZgP1z=0N^H_6AG9rTTw=`WSDzoh+RSnu<#fRJcHOI8<*>jrK2^(pkL^BLC4C_ zeO_k?wdzpM`L{t*s?u(++%*;?xLqJ2@~u>7;0HR}E?(sTMNh>ZW1#tbj#n1>ll-D` zS4p^yPCu-B0UkdO*G%kh2`rbW@_C(gv@CSo-@RyR>b!U#3HQ=X^m>82blQwJJ}yse zF`)$c_ydB&hGL%APbQydAxIJAJS4eG=Z?N#T$eN08_5Ug*EovRO>VSImyTvnb!M00 zb>8-=w0_+K-Al(Ny-HKsY%8Bj$#(|fqb!H90=ayotBj>7FE&ue>T4=w7XCcklH#PB_B($N*9B{go zchD`?d{e@^gTja4kq^) z7V+F!08YTIui51x3G|Z(7yQ8FcEc#CZvDX~Z))n8=Ei=)tJTW{)Xe)P8AIhuf!BkH z@6ds|EiGPo;)rPG8<|Y48|#~@U4-;g{#T8Jt7m^QVnwEt9aYc?;n*OqiCL{IIH)rw zom?xxQKQ$Gh zh}ZY(uM`-1+6Tkbj$!xZ^OL}%Ves^S{GVz!%8*+Hk~x}9KiP-(m_L4TNaIIY#i@KJ z*JKCJ>c-5NKz%0bbXP2tOYO^NG>zrWM>N?JA$^_;xrahwv02j?ffW7)j7y+*tEso{ z1^|b1FcE|flSOmt9ZPu~(r{`16;hCH1W9Xg8*;Y~;(gv+0Q^+AC2-E^MxiA{t+m2% zDA-&gTCVK3i)D`W4(M!kD^_5T5W56={{LSW5LS6wXr(NNU4^#>aeq-Xfi?@AMP0>^ z(4HtZ5}vCMD{cN$d}_IORev~?cylE{)W)boRL!B$)j*4J)&$B0*qQlQcuN#ltMXHE zFA;zD^{)j2g^6#_jYBh_&1ALbea;1Ky=~#yoHbZ3e>+##*uCB5o8C!Ga|YUYGs=()-N;aM;yg6DmGSmf?Zj@Msl#!Oidgw+ z_KH#3DIrY}=sE6;d2f*i?I&E>-?)fWI=HJEd{6vN5%;;B?M)(_P!y4_FO}|k#`?kx zYjlugTzTJIs~@$Ce4w9fr{n?TNEf8UKQgTaoO)rB{t90GS%EgET9I7A*L%oc=(}c! zeqBo+?I4fH-G4BdeDujW#S1HT-khOsUVI|_EO5n`5l+B)SATu3+`AUt689=q9bMlG z4eg}f5WH?9nC%Fq{M_aT+U5ZpP4(xMxfgV=+UAW%uEgObNEu*k7SGU&Qe0ZuK$aQq<>C8Mo+&mYX9`i zWY+AtT8T3d$&%W4L48rnV?a9Lf;PMPPLedo8P`lIG7F^oKpmEyVCi_dosQsvl8!In zu5GGXiF>Xh>t+aP;p7KuU3RkEGRdku#Cx3U%&j_HOonTP?ZcCT9~A_jovXdsZgOof z9(}kk{}_+_s{i-9I!xE7ca|`*eesRfLiie#Oh-X zsxX7If$5@q%_>uoXamyPsTY1S#eb-`%wn*t!FrGF<)S238mSKS9?E7+`^x^owXZ@c zT#bWsws4H}gU+%3hMfA$c+7eE;@_@wj0lkp{+bYV!{CgdC3IbGWIZg&AN2^l12KK{7Vg}YEjtxpudCJs^}WC)V1P^ z9~5fcD-UK3|BGhR5Y2yNGkdzmI)ahe1un#ucn<_Eaxl{iVy(()2Zy>@7}n=IH~bD__fneP2V+vorN;y>OH71SQqnice@KF|Ubh1d#(lrvJZJG};7(oK z%5H1U1LGmxC90asVC?bI3YyG%eA+ce@U5FREA_W=DF$&e4$}O+0)#S(S;!dW4r3Ee z#tmQ`B*-N51;V41uqoLzRBtwbo-SX!AmSq2$|vWU{Qa>&w*o65naMYNvb|;%iUl2M#kyt zxGY$-tkb6q~0{m-S^$kOB8Flm-TV|a{ zf3E+nr_3Yq$`~xpJ?b~~dTVY{sBZV#m)*^&->Y&?3RW~7iL@HC>4J<;IrYXl;X1;9 zshralUj(DMUNY{niadAHXSZ6^z`dC5(~B7)^JbIdli5pMkBvF*dSr04Ce{tTKI6V#+oWCE?k`IBg?CqTczk(_ybt;8@qFp^|jte zPWjLlhdKQlaSxf5!y(*zzwkZ}`S;uq+bP2W<^7hRoF=jMF%sH;Tksg*kI(BtoPx1d zY=Q-{#plkH!g|CEqr$Di-7|2%x5v_zA!rLmJJNH>$Bbr}`B5FM?EnxfAojrGqc4hfmK| z)llu9j&tqm>37=kt5ZZ{$TTaG#YT%cTc~G$2>BWJ4S4X<^PSET!zzd-MCz>)|Y zQEm(`)@QB*E-S>&q?d6f3Y~66N?M0|C}jx&Tt^raCMJH7v~=G&Y54mnu(P?)b55Ug zZ(-Rskk^=#cH2}GxBZ{In$V(kOpvQwKhulQg7QQ{H@>j}R0XY|1+E{r+Gu3e z0!$Iy*DZh6Yk>RmOt!raveWI=4ejJ zc)3Wau23Ht5O&Pnp-;~q6IuL;EQV7wlt1fLhuj3c$3$LFyhl;leED{^9FUhUDcBfM z>5m_Gtmke1ij12UwjUBE5qB8!$KZrUIeGTrmJ-6m=Xf&w$IEeU079Hpwb9RUvs#b% z2lL|?Mf6J*>;beKzP5erdQOVR212jfP6U{7!|3sS=GdpsP~uQJ88-tmUfc1I@#D_k z=(CzNZScBullX{5E`*GWcL~2q(0{li`mgQAG}*v+w(TdiERsF?Zkm2_peSx?VdRoI zEyh6fNG-|3cY4sRG3^HGO%Z=^OSi5%_C9VM>tnc9GKfhDYG9fNLOqH%==W{S11UiN zhbiOLqxiD#;6JhFD8_cc@BvA6xhF!6OGYMF;~G*_v)$VI_+n2l`4TYS_fMa$Cw&KJ z;9U~Q78=^U@}S|XUNiY!sZ!)0bW$%ge(~%lRSsIHBhh@ z3`9`j-JRI&X@Rdq1sZy~`zOsWkzBf{XR5E2bOCCr^whqCVf6k$HD(GabwbWKF$`u| zZ{6x;-?dA7b@A}&HvQgv#LcVNQ9&b)x zsz{GrTETOmbC+H{6-OZSVY;zdDd;^)mY9URAwo@j8inhw6A!nc7Q7)*>TTq4d)vuj z(359YYPVYUeZtOue&Ea)P1OpuW!&*E80r`1A9}G|XIJjEnOeusRX2`jOcyk)EC9B7 z&K(bwjAu+!un$B`oO7l{NmKp{W$<+iD+qQuCpw zh8Z~Y-{p$cgW+5G`MX`DI@dKc?57$>nV!L7Jfe5ufmNgY5XL`Yo&1mumf$a$0l&EK z!^o55{Ng2V5w27h1hcP%G4`>+SS7|><4-Ms*HhaxQS=BW=BO~UyCz#7Jyn|VUQb#pe(HqV>t+_^Js(U86ETnqItA z{E|+N8E?020_cNLVjo9ieGqWxfo2o(mE-k8_>un|pPM#I|;mBE}m_jdz{GT#a(XLem%s|Z>NanaP(Ny2#hu|Fmy+Yoq>)%G`aNjZX>~@*K z^9B$GU`iZd?qn-f4gBr=)_|5U3r(a$9u6mCp;65&Qa&tTLW7cRKTiV-C;T=?$C z7IAsPaxF0xoFbJp*V!bo`TibIS)BknIB?5Lzco}#)qCO>)yLE#B$IZ@F#&TH zRQRv1w^o=SYN}<{hfw_3V3X4Bg`9SP@10mg^HrQdoUDmAKrR`55BmRy!zYr@h}?OOJA%IrU{ZAsT`2t{Rx;_m&{O1{ zs$EcqUh!iCFf__{HTcdllDq9jX(zr>4sh5hTolpL4gUE>QrY~VSM!XH{#cFvMADiM z6A8@&`z3>a^Hs*z?{9}2Zgd53R>;YECa0>9PhGm-L;OMzs*=5T&;U& z66rrn!Q*Y92gH>OB|{ot!%I}|nB4t3QRUE);8(tY#d53#UM14l$Vp#-K_#Ld_|rkCxfuhhbi=PfODeq`iM%15z2$spfjOgtjCLXy9l zV<1Tk@MgYcXv4ozjueoxQ1C-m6}lRwty}pd?Ilc;FPV)}Y}%|1N1DUKDc?2_)MoIU z-y+r9Vy^HILVGxLteDi=calY#*te>hQ_GA|++&F7Gmf(875=WlLwim8b#?4BZs}jp z)uR1;*f)>-TP1V23%$!jtm5sW#^9T4Vmc+E+HfaQqDD0~Ayi?r#^GoU%MyN1If15! zX>P@d$cBD|1ABuwxGk3P)*^9$kOEIDx(+A93Hw8XpQM9Lu>K+8nqhJ^RH*hxb)hu2JP zjYd|N(j=2tQ$$n>LXWncSAT)(42 z9N(?KM}5z$`%OVty~`6N_JAMsiL9fXbDAS;9rXt)x|XvISAuRB@NU&f$m)x75bS0O z+!tm`bT8+8ILv;la01q`pzfC7n~^DQ^m{eUt0zdvQQU89tlProyc~F9gc^3#Wo!C` z(QUd3G698~Rru1pFJ>;Z`ECNpac6LZIN))eF>P7HMfHAVZpwqgtLpt? z{q30nYGQfZwc=nz4tGlT77pA7Qc zP39A-f;_81M=CwWXAx>R`joZ=0*fvxn&ynPGoF|4(LhsK{dQYa{9V3Qy(g)|W>N#I zch|Is&0iyDeKeUK6va93Jrn7=sB3P@UY?YE($CAVHhC1{`p*L$bV|^ZDZ& zW85mBbf|MQ&{>ptOI^@Pu&FC}|LQX$>n>QSS#f|VVILamW^B_k_Gs349qZ=JIN()D z`gGL1kr}Re`|_H#)&(J7q5R<6>QzYg@r`=weH z0lt@K)-mxlo^gZSjLL+`C1}HXDZPjta?Y*r@*|ria!b}v-si-xByouj9;BZ;&5z7HMEU}2H9hT23W=m0+DR5 z|J0d7xpxOw0+)nGR<{SA3^>TQfd57js>A#LEgn40?Cy|oc@}z_y#IkS-o7{Z=v)#B8e#;%EaJ&mg|56BZMI4Dbo=i&}cNgRx zm;IBdEhLr{;PjwEj}u8Ww4q(jbtC{YpW4UGO1TxZNuoMjfa)VF76(xLXq-A5B~SEy z)EH=|RkG&5SK7pXk#W4tb$GtB&x<%xi|EyyKkRGlCwd1H^YK97qM|cd6#<-JXN&+$m5fU+ApR47tglb=a|?` z$w|Gn^#TX8GsoG5iZMbrs(;gqD_JRWU2zYpM{cEp3B4R?9iIx+gxP%nY} z_&MO}>Va>oC7AlW=p(JYzl2EQqUQyXcI-x-ItwB_PxfFr3lvL>$+etP-h@3orn_eOh3SO{4_V{CUPTWiA4zwSIhsa^PW%>l^{zNAw>JW8 zO0Bj6U-j{np(8(09h~d#!T{Pfy68s_xVb3NGk+kv9AXJx$VO+6-|>bi&3WfIi3+Q! zSzv3uC_kCaxo@HTcm$C{t^>3m?78l0?oHb|l!jJGS7(?8prZ}$y?HY=(R1WYGLsX` zO)qbmlV6T&qvW*bnoN8pO_1@0l+;kQYLZpcyR_1{_f}g>)oC!7sfQNVgBB8-3&8We zBmvmW3S0lz_$vMF?h5t-$g3*6n;x6}7szZCy-p22>jwEqs|T1O_U8Q+x!Rd!af?O{ zjp%HlV%fdRVpzS6unJ!;cc|P?E6lC+dh1@x3Cr)_E))fRQhcuC zS}e9$=UaZ{suk*0&=|Y$ZCoDZL`riHR#m<`{Pbk#OfSo@hF})2zKRNtHGxn|rua!X zmN=g$V5q+7-n95U*{$*%pkHVvudT#={6Qzn)8*;p2tqJ(Ew2NzDQrL8i-NXaudu}R zN`(4nNXp|VeQ~N-73IbjQNJRwONb_Y;Gf|J+!t)~5v{QtWYS8n|S@LA#dIo3tP?VJzu}}J{4AuW#KUwd1nBd_+p19u=^T?G~A~9Aj zqNbS*l0Vv5^y44X59IK_%Y9~Ddx^9XOL1Ecci{&L8b_mW&l2gryuJ;4wU5+)K9+O} zZ?53uE?44xE^q>Z$vGw;;zYp+O1;G7W6JxlosukWvUEqXRa;2gk#;@QMNGP6Fm1`) zG_nysx^S75*R1WV{7V1luG|Z) z7Cn;P-!Qm)m3YU)pl;@TSR+VU^5W1}jI9AXiT!q_S)Q%NxUjqLe#U*#ap;A>aTDnZ z*+xm=FXrnl8I1eFAq@>nVEWn8o~jSC#->mMJ{-%&#Pm7JTC|Cenq$f-R!}Y6|5X&; z;j=CQG*j|I7ZtHyEh_;%fhaIrGIy(f%Ll$D_cG}O{=%4sFxT3eY3 zjb7FNL&e#G*`)FZnIjlMcx&8OfTNk|*1!zacAG5>fP4ln?~%pT5o-L3f<5HBs-70w zZjwZAQltcy-#*UEi=vdo%RYkx?C0{}!p0DNB}+I}pFS&VMJwTomx})5ir478orc&J zaBF~}$$PS=@_vKa3+DJ3?Fl$5Xx#^JyVchrPJXYC?%8G11_6ftyZkP+DHPt4=B^VJ zHWPvccrcn*F4?77gPX)iYu@`_=kiEz{_(?7=2oaL>xCEcGg<3DeLKr?A3jC{UgJI` zGG+q83orYat&QJGLu#ZN(IPgr{x>zyJYoV*f)eeYd85j4*oKC;USsV-ok`y zopNvGKJQBQz7|fLf7@_l<(MPipBGerQE56L-$(iF3`k_*8Xp4GiEmE$7CbjMt$^Sh zEa2Jo;}VcDnthn2<$~$*Qgkfwc>y*~WA)H^1k)C`pq<5EM7g_4xO05owTv#W^@00k zUWZtjzOVrEqS_+~qW@F%(2iR6h3_63>R^6TyA?(*EFx@4U4NMI$yo4Any1Q~*UVf& zmrTLZw}0HK3aUEeR0F(KlG&UIZE<`w0e_O~$CgNgPb~2XZhwh(r&1>IWP<}ud*D^l z=0A}%#+?D>wWrP^P6hUYFRhTUblKi~=5u|kvLrAa^KCI-y*f~dxg{J?lJ`}D@06=& zK2Gx)J;h6|vxEwdIT-SNDtUJ|8BVWg3jrcLd}uqyO?S8IE4S=irHP3LvU66SBURg8 zgKhtiR?!GZZ~#-&Vfd>4Ew^+SgD-8GyGCOI9G+;_GB7kl9l|;9Al>mXToKAu_3fz5 zP&j<>+A^SZA-1^ykzMPqPg|@rcD!NAeGYSRm8Y>+mFG$h+Zs^v(flzeteW^tn^2Ay zaW;@{bhpE-@G}o%y{cPCN$t-~`ZdZZzCJ6{YKNGf329DF|InH_3-VjQnq4RVG&34I z7rGIpw?em$27F|>j{2^Jpwl?%${~}t&FxBV1QDSRZTmy2oT`I1R+p_7#cgD*Vt;tY z~#2x9@9APhsif>II^K+!49>rDaGF#?+_?28@a zoI9-?xu(}Yqk@FZ2MN9P0U86ej3Z`#$=$wW*=MVYbzRB0J;->0wygAYH8GctZmS~h)qs(*p2R)K z*~P{3`5nRJ5^6fq5gV4qg62=?W2f}b#(iFeO6@1mUxL?)e~)X6X};3Av{TC9BXX+8 zeEok-d0!Ve_HwDCwGugAaI@ik$FG`}D%8o00dnRM8Qvi>p)ilES| zgv_(7PS!Pz&u+|=YH}<^U?1#*TAaf_g^lqOe2aagsl7D-eXZjI=8Ds-L#N z6m}-lNLgw{sU$`P`^~U%gNw4*=IB&M(<%!bGf73C#j|i`Nr~$=lxkv+mpv-Ksd!YN z_n~gFCMF>FQ_ulrMB04s5oh0c7rpKaOX|g)ZYJyS6v_Y|fy{gH2c=m2nzS(WrarBf zG~yGSFnD7BB^F&M92Kdi-E^wUiAmG_(oCq#VW6?fYUC@_B5nSFv2w0rOMHqcnVVLR z`;>dvs*9Xo=%)2^a*x)kqWp`XEwJghcdwbE=L>;*VlWeUyoS3Fn#;>GJ`K-<=50Qt;+lgCBM;eGu5_Ts8dHl9juA^->^ zJs)Nb{dE!Kje9(_0xh(Lj+M89T*y%1ckg@0zX3y?9)YRNhMRNnNUwZa_JS@Bt)W*( z{P%AL(YF(c)gYR2+0q}+Ko?oIpIBAzPwhr04Nm>ZF&2~fxziyU)%ORxcKt`OGQ&`C za>N!B1n$Nhc<;0ObPITDMbq_WyI-1C`la(|(xUr>zPKrpL}7U=;Wm8EK*_pT+sV?> zV{^ds2~YK{0eg+rYr0=5oaz&uP#XpAh8hy^;OkQ5{@_!Vpw76+>&8W1&#y-K=_Abz z(DsK=z55k*EatbWW7fSf&P7YWUzvldRMxQc#o=(X=38oqe&zZT$@N;<4? z8teT{&k0C>nJlCT3vf82-l-9c?b_a5Ef%9{T|7pa9MgrGXnG%H9i?~O@)q1KkT=@H zlLt9~q(rq2b>85*mGivce}y_`-E{b){jR+Lty5$iNgV1Gb6&3rgC8}HjB`J&ge>lS zeosmr3ks?g#*0)HXCjKVzUGFePH07m=yEjt<)@^;A4p%Zig)8Z`$O47IB4xj#Ex1K z%v!Xuivzk)yi~JibNG7eE)H+|h?gwsHp})e!L87O@}zeOxQKgSf4vOd^%@iOG6x*^ zBys}1bbBKR4HQDjru~DGS}v*UGN(a<+jL~I{!i85Ii4-JTICLJVECszmWGFgAX%z3 zLJ`T|=8^Pxx`=+YDs~ySusP)@Eq9;2I_=ioE**R`1B)ciWI1#_OIMOVPF4fY^PXtp z5EI7BG4u<0J47dHY0oWQU3-8nm~)|!-K)WoVDo(DOzA@rr%XfZoOcm>c1302zaS;* zbEYdtI{ciYqY|bV1cTjlwatBrdvyXLBK(7X5DJ&=i)Jjdip4zX5adaFTchQLRqsr6 zH9vcOpP@480qTbbF{xd?-sWc_v&15ltoKl_~c*~ z1Mw*Nab%VHpYh!FCo-l=q5`!K;O{C%oIlnW{@c5vG~?XmSA`Vy@Q;~HpV>;-karpcNBuLrOEd6m1KwXD$+7g)2l zQtylWRK%wfd4?fq;KLB0vC3cdOEoya%{mND{ih;}=~g1>6Z@FxA(y~r6HW!8FS;`J zH|C|9R--)%xSQyft}ud97kVCX?ZZrYOH5qd<6eT@OL)wg6({qqAnmmth0Ed>e8wv{ z!B({9yn5Ozne&Wca&~B}HDR7C{V?5JHmc;#RRqSHok?XFMHBi}^?ZcpfEsof!3Q8N z2=hKltcNV^zM)6=I%Qq!nrg2L25vC;>28a6{+RJ#D?QRbcAB)y zT7~?Eq&Y20-vWf{MiBSbJU#IrFrFyMb)N)HJoLJZhlpwAW8Q;&>CsgK_VUM&ej2Lq zB^)vZy8Vo}rU1NhW&e}3BhOmc4*ubK@R#B%8*~Ib+M9L09pgJh%#F=|{D>9uv^wT3 zU5$|_&VTl>J4^UiGgp>Isbj4F0<`JNPF7&E`JQ94B|Y)3gpOUCVa=T7eO^&B#7%EbiuAC-90SvdfVAG>Ehy@95(+ zTv&6eZq-n@rJY#Te0Y^8c&!1i9evjH9IaQpA8-4Ogw8cz6xX~ljaY6N{8Ft z1}q0SZuB?c`qSS=h%T z2*L`FyTD?65oX6@cNBFod}JmJsel5@ml-MTo!2>jqUcdScMockCCzAl*Sur z%bN0fEGMplsBb1jrx)6(8^Eo2&mSC-_s==tJtSsJfxvdvi3vIvxV3L8QoIxv?&x94 z!u9W9E~LLEEO>4uAc3~Agnn8x^h=w#5)eULE4?>thwv8FIVoupj1(oK@NUpCiFx6S z#fRVvyRa$ohua7KYw(($W2SjrmHy8H*8=z|o^D|8gE+SaOLKsqTFz}^NTcVUV6SUG zBqhB#`L%9?@)M7)+mK>KT3MA51KfB;s?p0^qg0spM6Oj z?r4dP+;rsJ+(+`>N>WnMz&$&aRkNXH7;>x4c= znXd!kG^>WR!R`!5;frHO#bw7lvww*0U(o%wC5E)RuXR^ zXjhu~-jF&qO9H)l+=L{por>98#9U~%Qu;4d!AK3)&s>fxuUa;dLML&Wj}%`gh&~FA z+{U-Q7Dxi$zve5(hD8uoq@drCM*8Frb{8JInTX}H#W8Fjs^f&bT$j7ak0*UjKcj0@jR@TF`n~J5P;wE z2$#pe=xXDpHM;0=-IWE}V;xP|+64^`6z5)4{?#tV0TJ_0#AXojdns?b5gvPmn@Xbi z&|BQ-e*?}w%>GDJp4tYH_&L;kPL{f;u@|nkkhh->y0-~G9_V)cvCpOFp&Ptz#}8V+?E&XJO6TT)zxDa?Ms(LuHXRzzc~^DI(eOQqfKV z-c@lKRV%yGOO7}1R`KF8l7_lz0zYCypWO_(E6lABxpWYH|XAj#?o)=mwf>sp7S^3fssu;;m67+#Ry1Q&C1Q^h&8Ut^@@>ahqD>JI+x&+ zOONc!kX*#~jM4a-mR%^3iAJ^ctyP<65xnFnc;0Hg`U+!kN8a`zek4n+i z9GzNtB_&+l%2E_jcN|yl58^G=@z9)IzDM9#;>Jj3zu;$2nxeX#-*{go#lN1* z-6{S3J-G8Hb5(~VRRI&C2u$y6;#L*?Xe}wJ81jTJuA3wn?i|*1c4-(-m$Ow3Jh!5} z4Ts$54xW?MGXD>2OWbcIOvhhu8@Jc%1Rm-)jMrkrTX?~2$;%`X>aqKF!LDY1V7W4J zVph;f|CLb6@yz+H@7KI5d+Q5;!Mk_XRiI+Ql1qCGdp;5}QDPuCJ*1!GsU@L3I%l_pY6sbNb(-^LrMRrZ>f0FVlAt3CKj# zl~JK_(<2~dl?^ZMFndsc5~tO3A4`r9q1#>xbJElHHBh1lL&wdXr`!7jWmd-zI<{NF zzd9C3HY2L4XbCvo&`QYyuySZ7xg7jJGPh_0%l7}}R|P4&-57X61uTIwU?|3QB{0CQ$*_3 zzZl=TJ=&Pp&p|_kfxcoU(6qBEAVk{KSNjb-+5RyvwT>_3eAb)Q`Nmz=(hx7<{Z8`mSja5 zFi#D7DQ2eWLrab3*-^9bzXw-M+$umR3{C(&NtL^fdY53IFI+2j?9!hJm|jAh>L=Vj zgo^lK=m_k)CgFHUjyVU(thSUiCa`Q82ll=YAh+edUGb#b@E7>dnrbv`{gDB;7a|Ud*^uZ z4LP?5I*{~JR08vbB1DMP*bNcIy2&6Z&3(-KHK{)+%Fa#qPy7ejn3U(NU8FR87oJpvzd=8-8q{{1lfE(6w;-7|$Vv{a{)}D%$nqJtgR38^ zftxKGu^-AOM$d4@k8evV51`w~bSH!>t$HzvXFam&GpJYE3FG=^^hIp0Zu#)ue{>N^>YI-THk8h>^6%*0cl#Jn3mez~n%`n$) zt>;+5Uz`I&YS6b|88yIHwRA1A`fTZj3Gkh^OynhH5zl9u%tHjSH>1-rLDW>>^Bl=P z_%IMEul?M7l5{zgAfxYweO)a(_w1IPIZ1c=&0a3*E^?Wao(+IdlXi!LOn)1ghU{z_ zk^zJ=Q=UI9*10+=u&Sc8QRfP_&{)5XQtkGA)s%gngYHbvBAbVn?>(X+&|yL3`S+bx z)OpY<&qsM{H?xjgf=qDHoy1#ZD+HL#NST`VImhJs-y`IIpx|9t0CYW8GKr0WIcUp) z6xq}pLeC*lz9n9t{WQ8eL}kHln;SfOt=i#bq;p<4u4(lFW3E7SBR z!RL|5aJx!I%4aJQR~iqp1ulh_VVl!`?c`&APkk4y5>!t}wn3!r9YN8(A;uWi$GTCg zWaeYZ2I=EXb^j1^=Tnq@)s(a*S<} z@(uY;)TC$GYj^MtiX%8iGCl=AHrZ^Ac+2xf7&K%19;}jG!%8F7rYUQ#mq1vMu}bY5 zn8@}GLQFyaZLZdDOev(2)Owof4t%D5up9_c9j+M|=ikv1Iv%s^hr}>XehT`w{D-Iv zdGxgPlr}{D2J51}9>ERci-#f)vgbUm?$Oss&|OV>;Hg>} zO&>y-3W}e}9I?_sn+=n&J)mqwo%2k74AK@m1fE#V-!zh~*+0k}ZSskq!mn*qvgAKH zY~;Ozg-~-_%^b3j%wy$i2^HClSG4e{W@zg`;GjsKa8D*t{6sC~s^-={#myZA!6iM@ zH;G@vpUV0&e=xmH9N63|TW`hu_->nl>b`u0=!!wnnAjIzH5Cc|+W4w%=&$RU@`!x| zY(!B1)VwT0O5g4OX$)~qg+59x>>;tp#rJy*K~{OBDCLGKvO|w59y<+7AneSRmdXR7 zTUV$$X}a^}L+UjiyGX7<Z5OszRlz$NK?A0@t7a-D!SP-6eFIxko6R^}}eq|{R75Ra# zcH;b-#VGR@_f}DeOP6W+a)sKfP}k-7=%=zy_5!MMnb%^mzGUU%;Fu1_XBFuJWDc_^ zu(MVj`;EygraQb>UMMXoDhD!(*)Se^dpQN@X@ziRo_Io+P}vWKRB6IUtv4#0-V1Mjp|2qP~9xe>FsIQHJS(Cp;nsiUYJ3^$g2Tp)SZ= z?~=?G^6zh2tD#(2i`XR{t0s=)EcHc&=h-iagRq0^Ne$Q5-^BQO203r~Gh9{#eEA!4 zT4tzR^BW^EwI+=^s_J&|uzOZZ?z155%p-@K=2om9A?`uD^)KqZqW=2`(hT?;cA}YI z>}k9L%E3y6UZ%;o33k@QoeX&;$mQ70dh}wvpF2(=IbT+EFWWh~Ru>|siz-K_54PAo zReh}O*vB{&ykaK9vy49K!-DWgSK%$AgdBC*i`pPcZCD`7WS+W%`=i~aEWk2-rK*;F zt2#-Q5(FJ>I)m-8FoXK}Jpg#MkD%{?*@fu$u*>oxhr66KER&6j0b9hQej#z?1Kwun zk`e|+;yq=eqwotXKSvb#AqHq`W;0jFIsS#x7V<$0`FXR|ynnoKn0+r_SV=80sHlGo${}0eU2SF<+oF?)r`kkr5h^1)y&?oJ2! zhX06jLm`b_z9Yj`f&No#{)#sU?{i{N9 zMc6orqAvq_fgk9jvZX8=cjDKxjFdhp%O=m&NFzlcXLh@kP=nt$&%EnzJHxhDZ2H6; zn2J|w*Ftj?JJwDnOyG~st51796p#av4afBlyM)Q7u`@%qkkLwJ=a^&X2jrZEU|jh2 zSuA5LxVT;K6OrgjMzSce`ol7LHs)y>6Pz6b$bv<`k*wzo$8y;qb38k_D}mCTqsZMM z=&u*}cdSb-4$NFDInsiVxh`e5!)90yXI7DZDD!)fIXOK!bjhlay{AAaOEqbJ7hSOj zRQwYtBH1ZJFdFn##5%>7tEx{!umz7Yqs9VJKHupwGQ=7-$IPF#yDgZ`5%{a8Jr9y* zBfjzjFG@B%1Rg2Gh3?v1%LlW=08*hKD7)0Jyg-Kwxf~KALV5csiNJXicBsdOQtJWaN4^fuJb4|$3OP{FscSifil2@Bgr1ccOi~bEdl(bc zaB*0-&Cs5j;P2NUS(4O9iNRG!fXTv5q`}w7VCTjA#OFOWmb)dta@fJ2ow2tC&Sj9F z7;Kk~7E?G@Ly(bJQah*po`mcVG`IR7S79jXC3(3rRCZ5I8Cr_qly9SatK)^#O#9)h zuC|IrC=^>-zIIW4(rK^k9;{$0Qonw~oK*$$!J7qBUk*)jIKi266a``R4K<#|@9_c3 zOJCgw%&VCVAmuT?3-tS5Ffk)ttZ>K#pJU}N0S`wc;RvelMvK^485)@*%UsViStYi) z0GY*YW1jCLHF9+xPUhr1b84C5;`~k`mNK7p-J3sOiBve2cmG(%(cuU0pX^CxfVd4o zeQr*jhBTP2>EsCdRx>3M14 zHIybj#+mC}1AfXExBeD+j#{NBcI%#dHF#jc!YZ@Un7gjp}u zgYaTNLg3|X{TCL*34p30qPP|Y7;o5>UQpF*Bcmz$GhwRFbcG`LJ$OtLCegr5{p{ee zE!mlWUiQCXyfQIt!hG`%NJ4J-I~XYY*y!-XNc%ok7zg#&Jxb+gF%! zw3T@RxCKvkoUByw>?OSuSz=G;Q1q5#P^|Y=kxan09Fqh?496ic02uKyO&Xf4Pt>xv ze_asL#Qy)qko+}DD96Z0HGh+z)QMV!|5eMg+8xr$lGM=eLG5CTOx;uIvA}_0i!5gs zq%HX!H?U6cm+b4X(;s=(5bbs;&%gX+y;&tfHhSZm`sB_%K^QY*&@JoV`ViPuk|BWrv?uzWhdgd=P&bRTU}iCO9o? zYdVRTm06x(+F^g5D(_A_Xog!*Bi*J{U$m|Q9nuMJmvbXc4SqBKD=-;Qcq%I(?ukC z*oQIiSu=UPz@DejPg58Kw(Ovl?QSV1u42jxUf<_mHBjb0g#p*hKZ#u41A-n~b{jR& z?f;|ZBh^9DkB31ioKEkn#f)Nj!Z&cPYuGKXPDy)oEq(kTJLFSbb6<>y=dRCbZH)8IC&*qD~2AKO9G=_kl_` zbwrOb>@(#7g6p{PEmDF)qqErloK-J-(AStf@IlCTGdlJcTEjX(3LSTN{*9d*8y>Xf ziNiZi&Ro&La%!LM87o?2*ukZc-$3#Cd1?F$(ur`z$_MM3bxYsuQ1aj+lRt7TQt^UV z4W^R7DXDhNQKVqAml)v(4YpmCw7F|HT9V?e`YSe#a`FeSGeZ{WX7lsCFmO^2d)`}i zpTBa3UAvnIws>gcl^o0gTke2zH4CNIoO3O9G|6)PqD{6WN)+(_dphOPKdlTpgvu0q zsq!8X3vZT>dg`eDDSykCDw__yG*aywW)6tf&5_GD*J5QRshEY$PMDZpH)Q|s^!xms zzsY2+(*Aq{ae|No76OKaOzJ>K5ux?>?PgZ5@lE_~rYR?>Zii&9j13Fv3*!;JGc76^ zrSVV2{{*)*_*biNCoHsUNasMWC`p*YrRnTJ#rnB7#no2Cf3eHk$wVRKJbEi1TT&Jm z{6NDSzCR)9nP9)Uc0z5w25AMiB}QKq*{T2?FTiHNbs+F5vOr?f$2D<59};?$C_y6# zIne+bUmmz|&WZwCA8UhXw>JHdq}iC13>bhmX_p=W5C40bUh7eX(1Lsg&BCVQg7P($ zMZaIUJN@3AMrCgl=3lwHf?I#+#24C*8jtun-c{Sk&SlGGqZu2)_cF736k@}+>?Y@{qc5EB)3#7_K?&ZF1 zG%sZ?Wyb^Hxo_e|jSO1Eu}b7O@!2VIfWsR8VAQ;*lrL(=eBGjGymS^}BHS}xe-By$ zm}PC*LDVx?Er5@KS_ZK|^BfN@(<_Vs7sq+Odd=WIQ)A`Y5_a#@ggrknofUFkzOp%| z=5E3M7v%5XfPs&0e0D<0_D`sAQFV{mE#j1UxGD=!Bkh7ELmYf4J?_F8H~xu6hvi_3 zV*E@s$28@;dfbi(YRENe!vL5Oxi34JelFKaRbumfwcu*Vs}H1qO<~J;wdSeZ<<|x6 zOpe=6Bhrp$nZ&IMUijNaYliy}vOL5$kF0#iW!(0p(B5YVjk|9?nN zrf-@L%|-Mgnc+6GKcCTl&y0l}KH2LH)@?I3v_>(A%)KrF6SRY|Yq*h(nz`6>!ivHY zXQf6g@+DYh=0TM2Yj1!IVVUKaE37M$XZne@w|^N@Cyu54M9%espg+7*ZHEf3wkv;k zoMJRxp>uDrmxIKqm2DQq>Kdfmv;lFLGD!}5-4Mz+1uvU89EX2#0}`X(N1wj1EFsAs z_?~9}TyX%EGXk3rrw!z1IMg4ayOyzS5SG2oqWVi>$?P&Vb@lOnZ!)=6V(Jgleg4Z_s|f#C z{O)ySTW&fOPP%@G2nB3X`GF!YcY_{^!QsLf3s!vKRT>$S)dz7 z9vm)y+?US_x#SLHZdn~wd^+StfktnbS4}c0xDM86Iihrc^?VPmxHRWqsW{&rc=cP5 z+h}z%uR3Ia$e!^;&*ZWfp-C(Mxvv&-w8;^?c@> zy!^p`9Ftgdq|%@e-ELE_u&lji*G+xg8rg?=HwAPaHiK?z`Jf?+e?&rmdFsUbYmqj# zLdH-F+W!Rb`!4U_qN)INIkwl76~JR_wCnfS3Q#&RmFY+rh9~r#b}tJMI%U?zOkw&I--+jq(E;rdAaX=Q8eb!7aMM&A zp#n8S_AXJpEg@&Fmtk(2(eop+@a8=lc?1aPmAxv%zKNY%xK9u8Tt+-5@ZX1 zv|TX#CueSf5Oeo7L?iz;Q*;>2t?IoYfm=0r7OgVfYk~}nujL}0!JC-5S)OxC^?nz< zsjE8p)DX92TvQDfrX>D$7)qd$=hot$kS@7f4#R0V-l3@;#`cfh*;gapV|K;#(f?DIgbFx)*HeR`<9e zAn%y-NHq&ZzH4cpEiDtnWnk5H&ZbN)6V(U5?<};bIm>CkWg@8jFnp%Ulm%2tLDN#3bZR9!~fj2`LwH~JmJ)r?2)YgA3wD|u1Jus7s|(!8O1 zi6TvldnOIpkkl(VV?ep}f033q_{DN+W6p;1aM}GT??&kx;M1J$))kBQ9DL3KFF!zS zVW4%jc?)QVYpA(QWbxDK z2v8~9Z4iaHscObFIN0J{)FTXpr#_QPe5yn(5wC0VpOruE2p2$f?Lj!nr{NbsC@=p& zA}HEm8bnUPt;qe=UjM^nU>wFAX;ZOm zBPI91rlWjMwe&JA7qyE2_!QjM;skxJDfsUx($Lg5i4}M(`qla_=FVUGcrE2njk;eZ z4^({aSO$6pfb$$4W{$|;_8>Qx`vX(<5n=EiooRUZ)1;ByYvZtp=EWQ}#MyfrI6iMT z)H9lR#L<9DMwH}AG1Tx>QMB8FFhi*v2_=!r&n_?+izDS^=mel z24%Q@7KzI=r9Qms;Frzf~Nd~&1t6t$-~ z9M=kJJbiy}GVYH@U#wv6_8M0FiNC?KRzsu~n|znpHUL2#h0f%?mKpHU_z&!qQ`mKv zfiG*E+`g&z#a}2SUJ()4u;7cxRinC?*cwd#G5}K}du&)KH#Jb98fYK$fh?%n;eP{UyS0`$SU0#WOZx1}yEMa%VE^jjrc~pSf zhkD9y(v1=gfvzhFjCaoz$G6Y!0dt75n-*!upmFM;A1Di#o$sTX0m;rcUzP{D#>n5; zPM)h<4{8y0?j%9i*8l|4Jkbp3Hm!xdQ&Uo^+dYw_)obXVQ)T5zrl(lQ2Ds}bX?yH8 zj(6(8vJVG_hpwF#S=03`D@?zMu2pEx{Jf!hulHbvx`%guwP>KUJzIEXm~9^HpM`3W zyS%hl1sMqR>wCQghrAFKm)`KbEx_O@o6CEtDBQmT?SQj*Auom(zkh`At%(Y{N~^h8 z;XTz$_3WnJP`!~QsFk0dNm>_cHJKTVtcSkZW-~PcFO0%mG?`^@OKS<#tpu>U{zMh) zsEt=|LPtNtYE>ZJc{lcvKFpaLiPs!}eZk;%2Yo2lE~C=3FhFs-EHslUsUxh*J*8yu z=GD@zi`-N3u>ATI0~E*q&Jq>`Qw5u~88IKG6m%{E2BOFoI-4Kg# z<^9NoTFFCK>*vKrV2xEzc;K*lwbJ1dht{mU0pGktS(J^<&Wlo|63*>;XK}X*UySq` z#*QZ*#QbAA-i;LDwejYfn-3}vZU|{LQCj`%2RWhlr&ETpF|QPVjX#h+lw*~NHwmVs z)ES`D;-x5#_bF(FYaeudBmC8^pG6Y?n+yiHgP;tQaoN}dq$$Wm;yIPSh8lWW3`$Hh z!M4Unnk3t{2H09cZxT3uwwMf8e3@-Glr-+{yyy6{4K2y6=e&tf=12QppEf|3L=|6A ztIP-B!K8d__SIvQIkJAf=&V?+gv^#s5oS{!0k?@H%i#N%fj*{t-Wkq-c~hW<@>Bk% zxg4GyneXvwN9UMjs6DON3aI#JQAyJoL?*cAC~b8om)X`4hL3NdH#0P4UA9}INN<8~ z%iKX+dH6EiSV&@X;x~C4PTwTurimOEw(dA`sp`g$P@ef7rBA<7ioS^;{&*gwv&R#e z$}<^vI6tt86ftS>x{Z1J<8wi!yZL~3W-~qcvjN&o{`45Bk@D2y{zqFz<{!3GH#gVY zQ2b(lk#Z;_6%^Scc7)il=U66Xz#dQK@w#n$5CDjN^o=ThXt2Epauc{+iO(UxSWd}Q z$4{VQb@8e4%hfhVmD+uQix0OC%ENXI+a;IXkl*{)%vtwFUY@_H!Jj3*cD+xxcc++i z=d5;g@!#X5nY@S~s$$trNs^G^rYXNZ2IGNlqdlp9Di3Nb+fHYc7bAo1e|C1xQkOrU zcNG=#mdfsE?2Irp3F1z^py*Jm|z+2-_fwKBC}kzy1_c4AP8H)~balEpFB| zpHu0^3XZH6cN(?z8PjO0{!jpjB<|*V3+dij@#wSXkr<4u&m)X$col%M}!a5sdb{b|A=V7z_Cj9Q8 z8E9!AcvyMXl99gT8D?jnX{7otxj{O$sp+?hQRerh=g;v7eE698D)A=&qc!BUo33an zRDDx2?BAW>Q z`}du+Ysvki3vBy0tc1as-s|b@Fdfz8DDM3^eo|%nR=LP@wd(k^viMFjnQZxpplN%V z8@UB9&Dc85erUK$eEUx&3ex4J%s%*i)Y4*Z>7}r-rZ^J@uRoUfM|0~ zu53Y85l)J*q4xHi*&~gS7W+e(tC0G$uDsKa5p;GP@f~S@?3WqM#?R_I5^V9eeY{#s zf_~)`B4#3^R3QJ6Ie`aGvpwdLSVdSGHB(WYGb;DLk1EGbUqjaCc+xh7L!W_40z{ds z3&Nz^M4a{SM2}waj0VoNGh}Df5%D_U%2&p`+xutaFT~>!CNhiN=pp`>o%;WY`6%>l ziVZ_M=y`uEzE%2a6e{x~4iogfX+HvtuQHFme2HNWwF52b%`PQz0}j4?O=&yEJUnGtB@HKBz}W1*AiEwz zK6SxaLiZ-rg)NmpT+j3`07oL7!`nFC(M6x!$D?>B6~Lkcmsl*We~JPGgQ z=f2SYC0Pj;#KZ{k-3*d9-tXAnG*;>0y6GgTcEN)&VpPg&)kTU33{ut7PD#2TE8Ha$ zw=>XKm4&d;=Q#|;^rjGwi%cTRYUOGchBAi`jZeqGM`k;hB-EHS<)<@a<_3s#Il_+? z2Aa}Ka-`Q*AeSBZd4kDP)Jh%$T`g1cf3!J4Ax)39+}U{}9~vYg7-qajjj@#~l8|7616%xxTBO?&p5 z&UL{f(~%{xBel@CgivLBS?PoS8qimSD_9N^Svie9r+H1Y4l{Bw!IC3iR`M&Aw2(ID z)0+giLnr+A$<%t{XO|v4@i%>|a;dd$f%+?5g-q~xvQ%DzFsAom z??0RO&l`k7S@(vi*6BgygG~_v>SjUle~u&AvQv+-Z1y|q-f=T1eB6b!q}!VxRx3G# zIgnhwnU49}M;pc;2Ys_mrGEBi;z>_n8>ODO1-f*ny1ElDjJ8VkTTgLbDIHaARm9#^ zd4=>Zr_gYuk&uM4lFlmV_XVuBe6iR;(Ikuhw~se89M_<{BGO$?T$x+i%n6)L517(%Qi~?(Rm7?R1Cj5DkV-)LcPlgc_D}pGsb|F80c0y zM834e>DCN$cJJWC>av$OBsx#{Tr?u_c&nTj6cUJ*e}OV+U{?@^A|-kge&;V-M|&#$ z94PEOVK(fV>L(xeBQH*2>Jug9OVbDOiFRUEkZ$y%#ep!4ak>3T_N=RDej5lVxHA@X zb6Of%3ES9CONMTp$rUSQ>4d)7F?P~vCF2B>kmw1V8MRtN#5UZ5J9;AAP@smLK-}(*7U$RkOBu7#XopvOz{5h zdPTN7%Pu@<;%lwW+~Uv>B%*+mDLXN~5OXi=cfB)LLlE|qQ$Z!L6@#yzF#8htwr|b%5)bTQyZA5d} z#qF1ceOD>TthgDZQ6qaX27i4*X`8A}w|EM#W_S}}|DRBcLu&9$x>dg(C(ztk26I+T z&A`oa=+l+Xq`yb||C0PhyRzm88%CC(} zO39x6> zQ7bbQJmyt1uvszZyfz}~H8<;)s=#106Wp;$esfJuv##8#D`1#AE%);)?>>RqW=uyu zYnL=5hw=G zWsn!sC(|oWLLy);+-|Rt*#mw^Pr_c3FQ;W>_X>v4Q=S_@6J?e)HYF^k>5(7y=J#~{ zY0~>n5#yN)DAg|N;mLcy<|+~P5lA;>i64`Qrc~J-Q*^{K!RYTs^5-0nmEhy|@5$5m z<(y$$5;^J%%zsO-;b`Ion5#l|8ToOPxA~*K?{rgn*VHS~9=YNJ{W+5Hn-WBI8i8!X zbAO&D2+o|4IuICNcY6Zwr1O>`PZful+r%2TRn#Kp1^jK1-Efjr-XTiah8d+DmyCkS z->ROCS+bkMCYocBzh37nwkn;IJ>ylH#;WuG|D}Qc8>E)m9EW!jjL={Y{PhTAWX}eL zO9b!UTSWEY7s{s$oPKT=eLzQ3`KOhe!U8^}Zd9W2NC!$GB0VXfG#uz;y{}s@j;-UR z3neEM*&6iV)$k+2d%gK)$&_8)IirU8NUz-?{VOn*9N1;j{uckI@L=Q42h@VSU7VIbK`axfJ(Lj472!L>&q6++`Nw;bisWYUA# z=zmBPrq06iHr+`(rg&GFiobW%a;uH-)=B*C`HPCw@5tfDVv8#Oarr`=Ks?*bj_MBR zV>c_f-HHf!dSs}>{u#@@tC(|T%mb5=S4FyCRf({^q^pZA?kv-p#xRL}pz1AG*?nHA zpoPzr!OrJR&iAm<0qzTr>lX6{!nDqIj-SzB&mImcN^t@oT zQa7DBKkeV(@r?a*QLe+LSz&ZY=iY)Y9>m0Gx%X7`V&pcN8tM|qkX!bcN6iVaQiFp15GTi{ ziBEC>Gc6i{Eh-Au2TO!A;0qat(BrmWlFR+3{vscVOYAm^Go0-u=&juLW;kWTY=R=A zj(CzD*k_+BoaJmsN6$@P-Z@R(vKXu@{sYDprxS{~LWCA+UpfZFt^|=6b?_^0_GOX0 z#Oe{ec>`>o(%%mA4N>4!FYP3*CA`SLS|fcsu3Hi#$}~ehDzlq&3Ksfe2nce?^MB|q zvzkpcg7GpP+E5kr@Gp@&Wi;u~T-Ws@50$*(;IbT;$B|=<_wNMsf2>m9!EwO_$!RCd zLZ0jw0_3z06VP^&Ux+Ren1Yt(4UJVAOA6@HKol6c@XQ<3H3V7>zSsSGjP5>ClE8~K zdmBG49=qmLC*>2@;?G?Vj~o!9X;|Ee!+P+aqGxA|?Cn~#F0H%PDexR|;I_Cl_XYmfDCvd3xSA3pcoC!;CF*jp#};>S_gm?U?mdOnM#22uBw-iC zqp=pe?wnSeNys+DXLl%*JeWn>%Gc6LESO(5dDM_*rkRS}?8QT@6fh6T z@0Ur9Fmcsv{}(~Q(?R{CW7BYw0QkBD=mAQ7%bNZlsxZQwQSsxWlXi=9nwK2MomP;N zvq&L?oe1CNoS8n|ZCRs+3F6a{)EU7vbCEuXo#;z~_LxY1#IP++whYusF9FXpU?L|H z4@CHSFY?duwlnl|F*8kQ%5ajlT>UL=&IwHPCQ0tn?`}4oO?lwT@%dw#6IVNzjqo3#KL%6lJ z&XkpyQj9slr0wDjJg@Mlxl`;esN&wsomvfV4Y#T|aC`BT5gXQOIPPb;g>|zz1jPzH zaQ7vwg$G9TcWq?Daj!7;QhekfmAkXOoI*Xqwgic99%(Gp4Z`#Cm!SJQls78wNrTdP zbOW;3@B^JC={=%$E)@0q#4I%G7oCYMFc!OA_EH{M?*STx%x3up;$k@g$@GUD^BZML z)9UB`rcX8v%ic$`ysY#`+6_zg*&@7YwhG30SEIOblf}?6a{M05H3w~8algp9JfSRa z+zgm!u=|uPW__eq8_tTK@U^s*;|KmyyWqMqQ6ckwYP|r`)iw*S6F~0D9Md!CA7B~s z%92Cn&;`-GH)7|<@Qpf{?weeX<~rp=us9zn#8jh~zOxn-Z-pGB4;p7wup%jkmz>8aqMhni$A$3%j-)?qHTm^= zt?bYpPrNJqrw+9aw^>ludu9X#YrULf+F)V?0_&iveqR>eJvEZ6e6?%w193+_o}&+X$wb`(FTuGHVEm-7Dt1}rT>Wj*z`NrzrV%|efndD7rs-G51&C^OT*DN3wTp-(y|TWj}D0s(;*ieJsV zC&Bie&hk%j*IBFiOHlm)%S#avjnvNF+GetFV(5eBvj_GBnu9>S$hBFH>RRbm`1 z@c`%IHyDfepvRN=Jm_>TR7;s#iQ2j-hL37ZD0lbf^CZ90j}xQq5*O){A$_AA38anW z&p+sO;Mk}UU7K0YW88G2bI%8<$^EP0+YoOEa` z^VnJ`@#Ni$OgabRdz1Kl`{6yRzr%KUJ}&U>!M~!IA1BS$5?u~%Oi*az;1GQFZN8>~ z+bQX5*=@PeT)ChAJDImN+5~r!bfY0!H+-VST2S@?vW7s+(pXsh{+-@2Y`6EpK_;i{ z#8^96W#XP2I5n%HPQ9MY1!a&6X?|vy%KMJ_jl5_z&0{I zRZ)KVtJ>e1%ycA39S5#nz^7+du-8@E=?#dtdJ+@u3Re%%Z|LlhDo5eg`t|uFKmE-&WL(^(c3ArF^zYog>ky?E z%l(=X6uuW!|4mB%_!xoi%AEKX_-2*G>l$wl#b_#QPxARalB`ta(?0%HX;AIidqUqmS6&hON27<&d)8UK4R9| z=r5=6bvH1r7{-$(RAcdM1%823ZjW8yPCk;ktTb4 zrc49ptN(lhkdeG&JXg5@qIw><)(f+)f2WM!S1n}ouBZP4{L3I6d*(2+oxoGv@(Zd> z->`heXnTSp)fU+?j$3{;y`H^cF$zLNe#}$#B-0C6UbTkyf+d`kNT_TQ z4^%06Ma5IJZMS27gsjVcTj5EsI2t| z^0_vuylR%&XW+?6#a~sC*uS%E>h)?EyA~^IV_#=@D@IRV8Y9+JN&H~M=wo;H(5PP~ zJ+8=Ka7pb@W8U$kN>YG><)Bb+a;6BseEfxy+028L<7*y1$iUC-JvVNWZ-&+Sx<4l8 z3hps&wPGVn@#;u2UDW*__qD~&Is{wS?FoaOKRs#;%el{oJbQOVd@q5O5Pm9*{@Aly zeHL?zRQ=cFA#RlT2w9rMJTv3Q{cXmKO>!E{z2?VME)7*3qD1NIy-!+!iy^%_TifP+ z>Ea3uGfV6iBmV@)9Omv-);Q4vo4~Ex5@X;r6&*;Mf$t#ChX(4~V|I|a>glx4ya;%0 z;CvcvpkqzRik_xa;t?Mw^VeYha6;kxFZ~Y3>|e-3LH@ZA4OJpJF43ha*M*jx$qF%VoN3uXFFXdv`P%s^}+~Z?);FH*7EI ztJ6-irh_W2MX?f8?kj!cQpSP;05|`VlOzS~EnXs(5lM8ehZZk@eTK&DXC1?6(eX<3 zN1ff`Sp<=8c1l8$DD!xV6cH+o{Z@3P{0W81fgp&aE}Xn2B$q#dW%visNId0UnY=?b z5Q{_qMW|Y2`Exunn_5YSgzRNFNR%gdo{5&=J#?Fu<5WehOfNe@R_x4A;)&NN^ZOFZ zso#kYxe+F{>PLKNp(m+RZhuJ$CX&e*xwACAf3d-0HE|^jnOG3rT^z0aPGfU=HZG`p zOpHpR(6oii!K8#7$=$WepO zuD+6{5pYe|qsWzm!jKolbNNJE=mtUvGt*v?5&GAQNQFWX?8R}# zqshWYKo^Ej8gw|rUPR2QN^BN#The?^C`evZfeW$^oI1m9L4^IH8Eyf4c1Do_}SuU~s>i zIk}K@KAOAZGQdoeE*x;G?N|q8fTLY7NVj)B5)!eqZo@MpwmG6Ku3kQtV&o*OPN!R} zF`*Z&JeNL-Jt2yGmiJ10%KsspQvQs#a35o>KT;0{WeU2wmmO=*K0rOBUl6*B9w&ml zVO&oiw=n07B_FlLuh{YPmP~hqY6h6#@3#iF_Qd^`N#C16Pj0hJw?hIRRum>Z8Ku*c z#BysDyH>)E&;=_RZsBFIMr=pQS{2)t5O|U)pgT(}aII2wo?n8+J8JD%NN;Cgv+A`p z5+C$|HYUB{zWrrRWzM4l=uj@7G45B!{2ryZKTM!ef*wgdon42=oi z+%HS&8OI&nF_bBfuBS%&ERSA*ofR2DUluYCi1&?s+>2X@(CZAm1ZkK!<15OBHHwLE zSoM(yTS#54Om?0c#kKzv_@BBza{0+Xu2Z^+8tp?7^1q0X3cSTnSHcMzC6qmQDfm7F z?dXo3Jvru7?QUEE#Ome>2XLDuz|oDsrQ`>dz+?>;MJrL7<&Dyxh^f|BM{w(Q47m#b ze#^1gTi%1~jEXa2X87sHO7=f)iJpno2d=!@@!=5W>h(eFa9>yn4Gx&;TaJc_#FJIj z&vTG~O4Voq)r5vECUfrLdbTBE$z+ZJz_`42vZ(C+@I62A=3?JA2^wWW+v|#PMtjlD zf?lz`%bc0*qOf>p`Ppf_zQqhECcAlcW2E;NSo)z!X89&A_o<414O8n{C!`9Dm`rm( zBmK~#lf}986Bt9}7N;!(u5sgpI%p|H|GWCvLlh;E9K#E8VV1Y*UdZ69VgwttfRPKD z1V1^_nOUf8xgg#}hG1Qp?NUzwx@cODTT{2;x$9X4j?)tpwDnSOv&CS3RndV=MzSs) z82l9S7+}dl+w2=s)G*%QgX9mwbe0NoxSOm^C+P>|={A&D`5tRi25j%6QFsjQ?r&Hf zFETbueoQP~Ls)tQ+9!*%3%V>Wt&=VFMNDET4$UVE<=35gt8obo3o@JJ%HtAGj$N@J z{o*R_+)=j1)$^Wgy`+MYooogYqyvaFH{P z)JRT9I>4a=V_z&+3$4@{)1I^H)_#x87A?fiK` z8u{gIFEs(HF4#VnqRrDx79{EkhORTt1l<^pZ{;nsM(ZkSeuBlTAhC$Bw9|grKN(qH zgIVfZEB?u8*r@y)g|afPz&lfI04hBh2*}Y6O30Zk{Pd*Ty9A}Gmf)VIy8_d69&e2z z<%OgHL7^092rp3;H;Lex?yn4CI85S4O!q_H8DU3e9}}{-%gYgDD2ug4<|bW~;E~`a zLm%s4$*RGv1+PgTyLa=p4`KC^FJSw{QMb8RhXulCvy_Tsu(tQiYP^OPM4QHYIR>7U z+j$Y=g1=VrRvkRhmQ4C@V>~23j8Uw)PgX}vs32odH&r`mRmYk7$g5HGOyOX%Y6a(s zAtqH*B+FpfNHWALp9AgxhCwxE?XHA!-YW0FM`atKZ)TPt=D_9Y;^d&W=3+b7;)UBg|9_ZH(Mkk}-mfmYQSicyLoO zS_z8i-Syy?oTIvg-&${x1&kP~4v#I}ZYeSnn|gjxe8G=mYUT(*xJ~pgDR)DaEih87 zsM3ZCfZYgT2l)k%`$t0pZhSSvWVz7pNq>LB-xKSa98D51wi1R-y40^LoP^{vJn3o& z=MfvBp^SWHN=2T2T|o*;g~dUX*yf3?jq-906ESrA=TR*{!>2JkB{ZXTUG)eKW&9;h z(w@mo8F$RqTL)J?4FkEI{m7{>QYwW_dd?#=^q&3lrdw?u(J+mMJ4R5y=m}54SC8$7 z^0mEGIs1q&ZSOp|ex3?a`JR^yIpSogv$^=k$hVfk#KMv2$Tjstp19XHwE_9%(bP}g z*gtNa#6aTTY@54(>?hw_U4TgT@+NV0Fey|Mm+F649{G4kY(V**q#I_Oi!Fq;f%TyM zc&xkA$)JB%^4)REH1h+yJw?Cvs|S)WY*oA*C}lYl76pFWN9zRAeM}_PuG!ja6X8ew zLp9K2co|ubaZ+^O$l3s#c@D9noJvT0q1iSl_C#Cmk;Q-|6U6!K0$eTdY(iP@0{fxbM`@`*3jg@2eHsvK z!f3!2(RET9uQNs(f?JHH=9$qi4ZuouM*PwpP3K=)M(O`|<({kvHE#+07MV`W;%4;i zkKLQI4)hwsw#(hxru=q&1akaj?rs<2sNBcde}q9tUsB?k#3nDlRLc;Sr2|!-TsrUu z>BTnP+`+l6JSX_WcxWVL1fdWy^u&7pK$K?3D!W;RBV+qP4aNb~>^spkB>fkXg|8fb z{DuSJjJu9QdpY2$mXi4$*m7-oZ;`YLy@(R=d8wA5ES)5qDRP2}8~bBc?tS`J8XA*8 zSdx#R?oW{w?H0fCZRM&-1`<~L)xKP3Z=DgGkH3Q3z>{Jlnmx}q^$tU8b)<^p)yl`Y zc=jvg*{i9b*>+rTN8$jTCbSGmCWZm|((Ol@iWuvq{b|Ib@#G)49v@^w^}DIKRTv{_ zKthd?;(Mz6jco2W)eL*nNOO6oB7xhb&+7FzuIpFZkN4jB6)W7)>j(uqunNTI>@H;B zv3Fo!Dv`>rE~QRUy(nKA0(sr&f9QpVcu^_=JJqeYkyA2NrW0gdu=oxlJW0|2K2t>?z!@-a-LI?J4b;d_6D)2j)>p|(emd!Rj2CwsK9-3C%kpO7c33t8|@T z;GaE1y7Z`pZy}Ae3}a)*B|}>l94PO0M6WvTn$OX(os3b1sh6b4Ol-9=tWm)4IZpxS z?baL?c)Cbt_eZ6u4G+LiZoV&H-D1V;)98(S#7&G=3?|8PjE zM3c;BJxrjS5ZV7X@&d_14f0QNCN8ScdWC3--MT|0(m)YqfA?; zHkRd&$|zGtqASqForElip4f`wuepI2YL14&alx8{E(vd0LmdGfnS-EA?>FB_X~!cU zgd}xg$7a3d>k`2Lfm4z9UD<*a92eC@w%mC>b>TYBPyBN0C-V0n;um6FGV3uvjCkQU z;Y&e+x%z!n^anVYi`9{|S7P4f)TwiNePjo(lKi=pUa1$*{MD%C%zUIL>Q-cV>a)ob5_n@Xpj%y%y@i7Xs#e0Wp{J`!pie zrPrVFV?VjKt~toPqx#WH42!ILM3>+@G*%B7NkDJ5q%=DFVANe%`$6@zCFkr==hb03 zS8Tadc@hV?Z6_sPPtU(YF6CdBXqS>dkPa-Q;PZ8jU>z93?q@if=Qb;2y5;hNOz75o z0@65(5;si$iC}v+kUq;;feW^lNu}5L&ad+3kWR6>O58`=>9my7> zhy{6dL`H>)73K${mbkzwkjs*s;>dv@8>Mc|7Om!VQw-XNODIn-5xMg;d4b1^h=1#d zUMTKl@Tct@(N8y?LcHQ>oL5_qtf^mes*ZLd4qR9{k&Bt$eLQA-iY)`~o;clvk(K}t zwP)YVnPUx@+sAqjZNn17l#ZS*zu>G~Wkqu(hM~D^xO}HBzh)B#9`=hk7a1zRP=q0x z81zD&yBw>)I<)jchu5Wh!c{}e6`Ir4vadnM^7~1jX-f4=hJ~up8p-C*XDrrSAV+X% zbMo~n9mToD8is$7Rt21x2@Lv2Rj0LVQm*=I(MS!$X#=e`3ZuBP4<|TeOLA2ri-OKj zms%S|jRkSk+$Xy(ko#qN3o)(+8okvP-MYe@^{o7(q_XPGvg7?LB(I@Z3OY4P|wU{PLt4We7XSpSQwn1rX-i<$_me+L&;PO!#O#w|aH zE}9Y(E3JnC7jf8%7o7@^i>%ZcDqVW9G#;mLc8P0?Z1)QC z{A($nPFbePE{RlcWri8}$@VYUyKZNhk&|yJ=gf#!ixz}D=zUa*Or7drobmd)n)6Dq zZzcSv3pFB)0$=r7wm^}`AR`k*B_ql!YBEXL<)}SP{CimID(tvEH*u9zc04u*ScWeB z$@qeJRhCQ^e(2I6zg|LIZvU(f_{1i{&pthe{$);mo2+Y~!X;NelP*H|HN?q(bB_C3 z29t?L)&m!ZC3S1RsedB&O1jLIi%}WEnW4MKAyTUTWCz}IQ0$`?4h&sgQc$89)vMF_ zO7DwW5yEPB*8dg)9AWa7Ys>>e$d4Z6Vk|W&U3`=-uUB+>DR5B`H~rdyb$;7D-u9lH z@wJrF7li9AICG)rBU6dh(@({Ugy-RK(02e5uIBn?fKCEVj4cYkQ%rPv#TnwK_WI9J z&ey`0eGgc~c`2*$=MpB*Mo=iqbiQ3kE|@Xo>ELFQxGrYn68-=4$fe+djXkN9S2{!5zI{ z6j5kiqwMENoU;rYLRtyq7O_iMXGxIuYS4n$EI#=kt9L7p43JpCtQ8;_5$NHDhltWN zkfPX#FAtupuksqoI7AV(?tvfr+@x-S5RP2fQdEDas=Z1#pA*E=%Iok*=VN@`qt}G+5aNJPS6dpz3XLn3$w7=#x7vld1^GJS*%X7 z`O-oyf`5^m{_oBMH?!;c%984r88vr&zLS-&nuycKoaQ4(l-}C@9-xw$w@SF=>5FvU z$dfY{MulKf@AB*6d=1(ja42Yzf#6G@+R?c$pjnv7fz z9arEdYv}6t4=qOMBTG-bJCA%7u8Psl zMG^{R;R5mo8?Ey_+*z32D(Q9FSfh^_Y@zH!9d)<-WV#D#q!tn(t0BX);c)@#;vBbv z$!AOBm?v_9zdg7wIAQR{A@PEie07?W9(Z3(6Muf6=Ap4YP|$*21g~OC+D{N@5eC`> zQR7-@mut+izVYZE5#B6g2w?L27QaO?qO7F#YEt`vJv+7cvDf_1Y392bl2mH+Cl+h& zFaA#>uv&jn9syV$ghsn{yNkPXzGI5eA24q1pEpZB522PZolB24Drkyc&4y*>a4lc! z<2D^>kLFGG#_@G{G4ILal?~o+nWmRpW{3dtYb^hhb*;aN!~IE$qr%{c#a9052LG`E z@U=xpqQ6`%ndP4_s47WQ)-shTMWe*fmtz$yhB9W{Q8&<53JYfbazqRdfa*W3+N)qO z2Lz#CL?PyV)Bz7!ztQR=L1w2S;P;uk`Uab=)~b}9Y0=j|eL9H?q)LhXaTffsTKFEP zT;N&k7Vo}ABgC@Y=H7Cf!O;FVVu75rN3Ts>5@5|-z^>2JJ%wzlFI;j=R>EdV&wRi! zgB*>ue)$Yvq`v2E`QEw-0r4nwEf(25)f$K?bcIn_KxhnXJz`vXUvNE1N~FmTNm0wn zOXk)ItR3l7?@g|oo!8nw@|Q`Q2xkS0n-O7@%s0ACgfABMn22^P+D?j^TxRo78j$<} z&n8S`8)aRh(W?~_b9%D!s#qmZ4*Po7gl=&K@FQi8<8MHp24en>7x3;3ch_HK*B^br zoVEKywNwY#AKA(fqx?BR*Si|j!m!IUO*#Q{_R$BN^R};{^H&~kd?@|2gU^eZ4!v`k zEB`C(aw&~hfJY&+#U+FtCa@E6$k&_E;s=aYdED<*vhb13@Lv0OfqlRQS>~{7GI_pO zG}2d!pTRbYWv6Y>i^b4xuI?j)pR#}+HnFARJ;TXf;U=$_pluGg-p54SMdju z;xRL0iI%DMjiVHu*@27P;`$YM#}0wLHc~%No1ZGseGuINTV`!4p+(S4)7*U}e{5$e zh3Y4tpe-NNms~HNGGX#2pw2~6`zm#hIo0~FKuA8~#LB(hKWWcB#D;D$$4>YWhckIL zMfbzY6CZwnuY@MkgPQYOKjlxwLBxWjiSPXrMzAXo8V=#3X-K1tA235sh6AGNENTr8 z()W|U1mT><3mSUNv~O35p=I$r@t2-Uz=f~-_yG(5+^$5A>)MuKK z3uBszh%LWXx~<#YYw|ZGOVj_3_`o?2v90`ZOU^Uy9PfRjxLXv(R>o7DQXDuss)bwm zpDcJv9G1M0ewUM55*;w^DP_gu#TLY+ zr-n%Lo+b(|5mRcx;3vvPI<#-)j0y5kQL?O8PCn)ogo8{;k*t7j7tlQCw48Gns7fAM z^rd)}5DM&L#%ltD2TKT)Fq4x(*}~Lt%%@!GDTl#RqakZF&#zv1M1hO8aXEvE&~E?z zK)9ECgJTo3;#bh|9a2Syu~zz?_3u#lqX|ZhV!vwD=b&>PBW1xfQ&Hoj(pAk439I>> zEPvwyI>OyXoyI{uMv80!q`ee7Z6AhRu}e@GI;;OU&<(EmvlAPQUy33msk%!DclcYL z+D|eT5Asy%J!xL*=O3j{xpqZb=g~0W-`S94WxuiyfxUWy?Kzj7KuKpkc&DrKTk}I3 zOMSvEx;zmck3ST&9`(E$Ox8I;v$+%d;R^IMF8UVUiFNKbM%w>nRPL$TYgeG4+EWTq zQ?0{25^}kJYJ&`T7qma4UlC13l3pgxw~GI<-yw_ze@;10<~R}mibndDrqqR4s2iN% zF3A|9i4b$l+>xhY4g3edUu${6T5EISo!q-#8X5fUi*XxdeNbQr$igh-G19+mA2n#w zAF|qn`sBcm3d-i@-96^hhpDGC(;lce>Y~li{K*=9mBNms9KUb6n)Fvz!5j?XH~hkY z^bwb!Eu|{j`PGbtV*HO#%&Rh_ao zG$YcHt9Hr*Y$3mT?@9V^JS)ik1Evoto+_@BE*i6H2JNya<>5PNx^U5_3Ra!ub$YW} ze;gHk#)S=1chUG4P=tXmyoR{ru38kNrA=AUImBr-Tv7p8BC=&)p&06nXTyY$^+5y5 zh*2kYFVvO{*7ft_15`gS#J?-RTjQTSw9tyBVJp-KDICy#U5XlYnhmWZ8=!`-p|lh8 z|9c=LlNNAIQ3@flN1asm1=^!g#G(Mm(hm z?L}8{Oi+8&ubh+Mj_JLB|9FKwxns=h6~CJLK$(f#UoREA_45jj zHOw=0&c>R(*V(F~4#nz0x8WLLw3%v^KMJvxuiT94i8L2mLh}Je3r{$pbdq`18DF5F zj)bv#$X>LU0W$6ip9q>Kw4yYKhL3GORBT_^&#cj_mU3*V&5Q#1$6acHXA z??v!HzdFID2g$jFlmjX=+4S#R>~p)O5H8740Ob!uj=!LBd08097H_#ZVKL(;`e7ss@7H1a^7@%Mcy`_z3hMp?=DgV&2FdylUCN6 z(rBu+0fVLoCtd*8-jZk+(t+KfOi{B2r?MRhsm~};nGA8xX^%?6Rkl1YF7!^qHf-bK z;KGH&=fhQ0z0jo3d{}vToog z-*bQG6oFC?f9A;AFnUjg*u4K5;|gXZMSr}|Aqa^>Q5T4oY5AK+vD|O>7-uOMt3hna z%;nWS(c}C;0+$F`Fr5b!!Gc94`-vX|Z0})uGIK5#DLT*_*z_L8x?UTCsYLs4@k)ND z>AgP(;Q&6swo!4n7N1i3SdI$rT#w`arbaF9(^z-%jiw$qsV@Hqe?T(torV;`PmO;M z)nC0vmr|3I-l-Bu5U*Wz|4>YmetPI!c+iC#>eU@dUtSb{c^_WuHh$NT)MIfUyUoa)-$8r zYXY}(I`)AnBfttB)#4~J%*h2mQ2vow>Hw$GfH7jIN>BJ=R_ruc=;#=kgdT@ zr6~SfxqmE;6S6ae1?JzuZ>#E;u}+DCNnA3MJbEN(H(j@?No)uysQE{sPXr}TG!xjE zx4n_d<9uGN6!N9>yvQd(IqD7TkgyZWJ14v97TTnr>PKLONA2>!9AtFR4K}SG^E$>4 zlWm=PqW*VtfFI0$uJ{>Sb>m6MO1W<+aC=uc>LgwBs0K8MI!|yPOH5TmZ>ypwKNVRu zAA@Oo%%m;h+*Vu2TU`##G8$3mAS3a-{x%Dmr$u7;0? z&Unf6{z_8SDAbqs6OxFTpTWYO>MWEE5EF)JRa>cUk;H8cq49Y$=dmN?Wmc?w|1s6E zk9X_Bv%^_tUc>TzACElJy$8+VZ=Sf1EBkY?HyE5D>1E%J@HAy%4{ylaLY&x$SoN|u z8iaWbD<+w_oJ$lyOb)Tl0tXVy1vi?cQ~npony7s?1Jv*SJ7t$wiN7{--?rq;MKoDu zXYCRe?xDTm+-Lrte5TpH_0gn$dgOR!r|91l&6r}o$3<(3@O#Y}rXCZK&wzxWwGZoL zz^*O*F`*<8QR=Ba3`aSVIpI9{U)O((3VeH;pzmQ18|>9UXm-ohJQZ&#^K~vC;6(eGCeuv2 z#kWB>02r=6(T2aaeDyi{V{cp%<^oYUxnGbrcTJE|2M$Ru1!W;bY*Wz(3_Nk$)PN4{ zy*}zFfDmGQOJp=J_H~8k^}Bz7y-upoYiYt) z!}wzuGq&^$_Fkg*+|+$1qk(Fl2erBg996|rQkkueqD<(M^V+s&gzTarTPWPlDuo<( zy4MlDj8H$E`65L)b2gAX9=>ldVjS~R1i@dcUOEQ@cWXG{sT5~IjZK?&FKrCFs!F?XXf5JEBgmPU?tD~ZNeCuzFu}BZO zK<%jL8+pG0b>r{G@Cw#5G9>CQ5-KfmG=a~T1UfH#TyJwJ{8-PS_+HD~pd}qt6lU=pjlpTlU?fjuXKHDl*dH>P{@{0FUuxJtwJi!tfjia=LdcpDhfd7OTi8IFo8 zwnx8WSJ5PJ?4ag&K0|p9@E{vN4vnH;(c`@+g0zUJBsTz`#|p&vep-mXl9=ds`rgFj zC+JzQML1a=$AI`fi=#t+Fo~Ghh~_odHrufyH`JNN@f97Wd1r%84t6)9QjfEv`i&kx zQCOm1a$(`)HAPnsw>Rq4qAYzQ>XPn zSHTBd(SOmLuaa{=T*ZrEO{Q_79i`4q^qZ8MrRfTC*HFyK;$xKUtL$XOzjg?2OdJ`J zf3kB7vSxicPYA72!8fDluC8aT&Xa9FOsLq^6jJ_D5I?nD z5MOC9pXh^2U@wAZ*#|P;acbIr|8ko|l)LuIqw}zfFjguLPYqMjW z$pdisyOh&hm^lV6+&n;yefhwf;)SBS5$g`BlZwvZ4iDK7Rs-1;W_-s(bT;#EYsT3_ z;u28^HCaeAAI9PYtGNb++y&FEa9JzXycUU8mm{FBxHzfDnqGH*#Efvg{uzqKfYsLH&78a!D22rt;5TNU+ATeFC{fWU z=_Ux7B`dK&J)&o+)bclZG)MF%i!HJHwwkmNMmZ$edw5mMc>Q6*aEQKkLD1I`)VCSp zxcIi4AF<`0{6+og0)9WaZ47fmh#y8Sqkjg)I*FSPoFZg{QK`m#$YN3+I;k({{AWvN-{d`Tmo5y#D zH+MN(D~egyy3dj|4U$b0?H}o8FQGWbW9!jW?=(5yaKxLrLLnN(c2IuhcMWm2Az!|C z))G+afmN7u%p9K}Gl!Qs?~h!XZLv~kDyC;5@oB1cTNRhJ^9nXErL0Y5IOd8F#*ji; zh95+~5t2A&xZ0FX6T7d&qtuvbNREy67}mhd?v=P*4>y-DvO{h&m;zNB`!M}mYO#Tv z=w_l+MIG6~9I8XH(0xejsKo!d1d!vOUoZ-1A_?Nu z|5vM5hZ9-$PIYfNsm>`9Z}isR4d;Kx-SnF+Q9@D#afMW|31_4nlk4x1ScrYO-&!;Y zo$FA;Z3B6_eGX?bX4LzI$nn!bJXLm<|ASrB^w19aeYFn>lNwwk{r-zTXd%w_0cv{{ z%ZLYwo5rQJo@=!`BCY79Vr!Y+D@qSp_{SEAm1IC_kY<)5UN<&lNNnbzSuFYqBpMnk z9&l8Hk-nlTba`ZvdPW6@3?;1PIgj}LJGiyi4^1d*CpIaAhnmkFnjkkQl5khLuMPR# z^h%h#knYLn9|8;d6QkRlTqqVATeM-p?~U9WL$ zV4x*Zr1-vF^}cXi3W4p?@SbXnTW@IH88=De87N>z*hpCiqX!AR54U+nDZgIUbSWb0 z6ZfZX8b@xZ2ajY<@%HTeuKHK7#6lj5((kYd9Ajpl9}1~oc2D!?VFNSwR~mtS?yd_W zmTX!}pJ00aw2*%;g(Z_ejS8}Nmg8pKjnuYmvh%r00izV&ZP|o!5$SPmKgkps)-+m8 z&Rx|bY)VGWq#&u%vPth42=x1q{Yw+BHH-#>Np7bkrF%7AEk#j(O*zVXiYXFP5w}as zl&0HELgD0$36ddejb_Dg@jjX_$nSk3U8GqtHdTk;K5jl9apV!~vG0+5s!rPrdZ-O5fo?@9r8~>tXIQapUiky4!PNs-o>EK_ z=YE*xH=A<+jEUS*=)HuJpxzh=l0)Mxr-I?1D|_h^__x~!B~rTadA>OCZ|ezgvt%S|XfJN}O7(*Z^!FUKdKvSQiRw$?XgqcqLH(Np7j2e!4*NKw`#%E} z=pG=8Ch^N}uHLwM{DR;3q5+RowZWTx2vGd~11lNv2diYx(5)Ev2*=-Vrzc9(Z_xMs zh2E`*rJr|G`FyHq)8Map&IE2EZU)+=^8sKJ;!%*vlBo-qdErEzgZvWD7Gt&kAYth8 zsHQr?o7D6fUucQ~O13=;{Q!X5$5X0p$6oIzRl4d{=V>yK-s=jr##FMB!LOdm(f-TWCcD3t%EJ>tD1=H=v_TeI z!%xI=<~4Oc3$bHi8goSK_`O_((UcW&0KMTY#f>EA=qmj`2HjQr)HuvtpvfQJDp@NX zIeUfMEV@LVVf{#u?iLeR=SwX(kskvm!AV5I~VWqxLbOfXTvq zJ>&|}cCkZ{EnRrT{P&s;%4wPem+zS;o(6W@uuN8uhoaYqu9z?2H@7>*v@W{n-GErG zZ8~%ZZ=8F5p3XBx^bNC$n~1R2m?;3qXJp{1Y9DB+`4%qtJ5AxOdJ%;=;X8lUEb2vn z$)|Q>dE8Y}gbsXeO!8t@w2cMyNbAWjf~pSMCe$E!DmP8mOt)WRE^cZ9fi{5*^pEci z;=Hti7axH6g~`xnfokJj!N3{ByEz!8O|o4OmJ-$U4NyXVci$6pn`c=a{AqKZ`N|98!u&~%W?22r%`^5kGg#*L^aEmnksJ2 zVqS(=kH;muuP0}#)ojTxp~ZgDM(m`QTQfdnTOF{c^#$AlgaU%{pr)i1Dm>I%pmT{f z4M33Nxe(QqfGSUfULW~$=$y+m`?^02njy01ATIj#mH(jYI^NS6K-7_Doj9gP&K^EH3aCWuYVo`cdjRJngV zvv`gpz}++@el?u%A&!!uoSC1%!;jh)1sQ5wryAE~VBYcheYE)#x!}%GgZt7c)7JiB z4XbocBYvL6)$CH3Dlcg93p>}cKyyI9dn`)lkHHvl5;6)d+hjPr7)5$vIuZ*Z%JL*d zH!MbgD{qwx(@WGjm0Hsb7xBlm)~NLK95(Sudb2z~z51lK&2&j?E#*|oILYI`4YH6L zl^0=eCI|)dlvtaqsxH+OM!i3KyAUQVB6{FFUAmrKM0RLgtt#B9 zN4c#wqUkF_1;)#r7?(C&fQh!tiuXDFWTj@k{b5>9&+l+flo+r>b4H1Pt>DZ$Y@c#e zkaBUHdi#Mdrb|N(Re9O|rr+@@ou)^Cd%V{7`2R#~{&R-fOm@Y4r)Oj2PyhYQd%Q}F_#yJ^b7}QLVcS@23291-u4^Arn|V-Fez|=6mHyq-?|Hb*qe4|vx{cs!F6t(mH&^DP zT{iC}wOxeJZhaI!~DC_Pzr|lB^{#c@oWx zVWjkv-zp)WGC^21=_V->J7JH@xLfoHDQbgvw^q-%=}rF){)Tjd`H2~LTme{gl3vGn z?Fe7)wlhU+=x-tueo7_h=pEj|^D5^tU#ZoKKAb)Q0s+r$*g+e<1`7sI*d^{SvVp4t z)5uy_wcnAU$eem!#^1CRem9!h1Eke9G@De(5|q0JvXs7|Fuc?7q82otdZQ;4VllAg z<$}zvFNlVcVAL?hGnRA%)TCGtT0Vb(BX)+G$s0cX#C*9O7;Ad6iP_k*QTf?dz<(qR zxC*IL38vD|4W!+@q5B3`5FeM7Nh41b!9g9dNjxgH_bQwDWvcBA&~XRY5b1H9H?N+C^(P- z7fXNg&!fH{SWm$jP!>_zgv<7Y$<5f%}X6+=RLSe%a@-|YFTMN|Dx{r z8$+4SQDK;>t}j{>D4S`WA$`^8De5rKN!g%S+8dLv)Y*8V zlkQK4(XL-Wy0r0=05ajcy@6p9y-p&eWe(sL8LY>2`^Z`TRB;c~ zIl1P9HMLuPZi=cTIz@v_zNu)br2a07h8u_Oc&boT!AhA%ut0~wL=+bnhsxmp{rabn zHS8;lS(%})$Z%X=H_2krKQ$GHLs+9n zBD9cOBOh~PEQ10g6mS!^!KT!!l2+iRkcWa8;}^$C6tXN9+o9%4tGlnFh07`_y_VRhp>f3~Dj?x~Mj;d(cV{kqMK=o;}d_aL@rMb$<@<5(@WQeB87KZ`@1 zwLCTWKnXcww(awU!i?xf=r@iq)#<$PQ&!%4Abmlis@6yHcBdmql{aoBq&x5K zZ5QaRz~P8-;ch!1T4#er(><)k5;H5@nMP(?nKPFoob5m1#Ktzg+)V=Bv*oKxEug3D zbbhv4dOhBFukb%h0$ROj^dmc}4!TF=_L@Kg?pcpZVu{u`l4xhybP5q`Cqt}mQ z*YCni#<_q~De{UOzRM*W6OOLyNywQNb?88@%X06uf- zOJNUN#kcp}YoW)p%!rF+bE(Z+%Q|D=+HWry^9}Mh`-mv$py$s(b3ilV$pfBp=Sy!y zYFXp_$Cb0qgCOTi|HDR=zjHCMi$|D;30@q)?Xyjkk#R@tbqUsvgS)dH$X-aLyLtT? z;E)88CjSN11IEpSL?k;hUAtNlX*a^^hH^O*WSi!t%E@J@0kA{PhTtjw8pxysi8+o*wVGl+Ts`9#WyuQw*N?!zl<@}nLJ`_@s#u1QD(^)uhl^w&a*Vs)19aFBH;oUTJKkuqjUC3SL%`lWpa~^eTQFwtevwujg zpHu>Yk6h&{(evaIVB7E#inZd%NLr}!CW(`|Te#O+L(XM{*zAVaZ%UfvO_`e&*7ZyBrWvlXjV&SQrX*KaAcN&3 z*?@EeIA(Ez#tV^7tEDl@uIlLR^3Unc`GlH#GUt6k^rvXG)2ZQf0FfYwPxn-}o})t) ze63Fl>!0*YXdi{}Y5|Y)&o^`nVxet+AExn#Wd&;=u^8fgUpoMoh_>v+Qy{;%q;Xl`=)psb8m=|Fc}LQY9Sf1o_)1f`OvPkjJZrCcO$z>_LP zq&U>1RNP~VT`0~u+c{+p5T^7AT(`QXmj?@~(U4f(=5elc_BG72mDpnEi^(LgB!^J^ z8fu&Bo_hDeTNBjeCy$j#-dU6nvb)75nDiSoE-X*?f9`qF92}&avw#PBJ+=qaQDh_%LHp}5V`L!1l|q%6%b(x*3mHtxae<|P zx?g+e)K~lz+zDL6%6!gW8*$Ulmg)Aj&dKEBx+cA$7*1F@^^X41Y zr|Mo#nD2LBx2O9zFiTtl+j1Hd4;+y8qf3~u4++^!&b*~ahhuzSZ4uS~)`%1CC%(s! zVVj_K(oEnv_^TY zAu&;y*5TY6j`Tps2#M3bn@(lJgly913FpoxJm9-N54tFnE;bA@ieAhtBz9lPP zjWUbbCrtdv3cEnVe}i_N%|}sE3~~2&E=E7SHOY{u!c?|mldLUW%vW}t;r1cb<3fR$@K@#?u23Q88gL9w_=Tpjc)G40JhI0&izd0g&?GK*%WfUedj_&lZ zPOW1tR(at`!jeqYd(weJgAqNZ@t-Ei-;`DAEhV(|s)K$E!K|hI_zz&Q^?GJjBpiC4 zK)jJRxqdgS!SgumwLgKq1s2nN5k0b7mY!762?u7?M3Gf!O;ulnN_H|vj2tNo&$LD zoF|?(lEK zdy1MJ%6!us*%O-TQA|8&%aI2x&btr-HyQPI`>&o)heYz>swz$n_w{y~>S_$21M0Ek zroApBi-`rgxhL84S87f#2In6i(C!NgV}TgDW+VO#l{nw~ze7Byxr@erLWIF_?)_9z z>EOw#f8Q_(v;O*oRR86Ws1&pNpgK#YP`KQa*f4A(bgpCCjhq;m8N6*9Nr6Wp*ZQS-Gv20SR+%xE8AyMw7$<-5TJyIc|t^%Bz z1{0Z0^DF-ti6Z?ic^X;`x=Oc@gVioZ8GE2t&1Vfd=QBP4y{_Q1vAtRv|FIoac~Ad4 zQmw71c{`WKGxvC>7_C-Eb2#GHXX!6k7K3}&aHM)rj4_=;4H+iRZ}MV#c9rUW8EjXs z8x&uVyJv#1iS}@k5Iz22?rW>gxaiCCT8IP=lsc_oy#TW30~Y6I!o!Xa+CEBm4NSjX+s-IA+Z>q8n33 zKhJVq(HWr8m+IHL6-QeosW>XbbWhnjBIaf9zg*H)QWgRV(t{9%$O2_w82mUk7IRb% zxPT|tXp0SL2oUK_z8Q$i{^^cd<4>2PxYvma%lBWynh-;O42f35Whj1g_BX}()(~_S zqNkcY^*N6%Ry*o@u%i{2TR ziH}W%&+Ds0H2Ho>h!0XUM}j(IC+fAYtjVC5+>&y<6;J~OF+KJPl(J(mhvT)a(_riA+art(nVYgi2On=ZnC+$}#LY_`=YjqpN7&ccIG zV0Mzrpd-szSsbM!f(z>&@?`Ea*~!Fy{6)%j;)QV-h+kIc+pM4wi9v_|ztTWip^OlnE3`k(m)D}Py5LGWl>bJ4ki&_p(NiyNbj0+P1v5RLWDctjk=TDy zL-$YEjM=SYSjgY3@YMXl&La!tHN(I$ltGMNpQd~4hwpk96JfE_8$1pm!yAG4MjiMo-K{`^mdnU2R*H)I)=u zHfhEmm`qWn_|ju*N{CyNcXCuUr|7Y6#YE%et#1cIequWL)hTlLpTs&$}DPKCFOlFvC+W)B}IY_5GB$P;-+!V?*$8d&%_qhzF_4t2IO$pT~7*|2pww`O#5WyxXPUocM-n zW5f{=V=eYaJL@2s!~Yl!UK$KDFyZi&DaXry;)@ApE&N@gx(9lcqVMELa&HtSc@AeW z!teD1od(PwE2HKDM~kFi%Xo$FHuXrSBdey;HZ4w8 z?kt0nL=|ggo3be1{;BC`rE}HCq#@p_@$Rc(SL!gY=QK~z12s~g39xy}{g1C)>R!Oe zz;|a7JzaNrqvu7`rjhC_8u8dI)y9$blZe*J5idj7^Eo0$vkiWD2crMJ?ge7J*iUh- z!E-y=tEKp!a(uMXk7**>W&$Hy;2Uv1HO;Bj=OHD$cOyyZLR(JANs<;sSsdF^!P*;j zcMa?`Uw6c7EmbgR9x}Ox1SQZdjCLt+_755CD!17}=&%WCj?2O%pk^^rZf&{;#LJW4 zp&K0Uy6q?aGY=R24ey%3{gk@TI7357Q`rxyndk%f<-UIcCSKw;<@p>lS1(7a!}<|- zDAv<|nnlmFtLKxaQ~qGQwCK?bZ%b$tq+0lf6IcV#6(besHq2*Dl&qwUVmqlMP12jl zf7JGB-vo~QvE(4dxu=&VI!y6blzijyVl>VgTU8EB7!4)Ku*~>K9+X2rMn5`C51Prt z@6$92Bipm)88^`-y<+BmS?2$d^zCsi_W%F)%}vgeB*cbLbhDdKYVAUjxS39JYzU#7 zA!)V4g`!m2O(jwriq2LJcMfZpj_ag_R8(7S)v8rHwexoEcYVIUf3B^^u3c-_b?yCr zy`JyqVH0VAhTUXJPsL!euv6pLKtAu7`hq@`HFKsifv>dFFS)|SvFrJg1D+_!a(U`? zybs66PU{e(U(&mXDS1+*2$@fMOvc>w+2d@Pg1&1Mhtgit;WhN3JhQuQ`E68^d2m0h zljurW{f~8jjqs2ujvk@dm!wNxM(BHiuXP<$^}_jx|9&fEq5{XLsh=H?Wtf?aT)97m zmK^^^?mxD9@gSEQMr*B0TERSN-rEiKi!N?|w7fq(546n0l^$WGN&2GB3mO=R@7kvs zBx5RWCdpY|1~fz{K95Jc!LO=1#?;n`eX-8HK1c7fp1Z%dZy96c*=qFuKJ_w&p>`jK zS=C{_%*BYM^am1=v_>mUQicETuTl{GzrE=({H3_8D(OYbz#?`g*|XCwghl0Fq-G;@ zlaAj>tNVww_4$^p$u?H^!Sei09v3BW|Hgw*hahyd&>eLS5l6O#^f@ z;mK+H-?N4z;Mk)D;)^tv()Q_m2i*+(V8HwI{o_jfAb>oEDB)X{-iI;oSv-{4_z>5E z1erm^Z1dSn?1U?IMytfKN;r9sM=l?%+Ywu@NcxaXIpKH$^y$q);MKf2C30> z-ey0s2!nO{g<6)O@7bJR!6qT z?tHM*{pAcSl2E=<;#NNXOx#L!`X#U%%<0jGh10TF&FtkHWn@n&_by$d7zN)L^Ssa< z0ap*V@lR_AJo*Rty1l=li~6TOyPJ={Q)+b(zu?7&UoxWnX!o8dY&2L2-SoE~RuScA zy7ydkjb^EkN0v+jdvSi2v>DIJRuPl@Ea}ouQz9WE5fRPi97o1^Pi#egyMQaqGc9wP z@&Ip{!iw+43UV0Qu1<_$CjH-|=M{7SKVbDCZ%|-fK29{Bb;mb`;_BC(15=~u42>Zd zGE#;A0%JT`#^)?Pl{kQzr=ZZUW{;UsQfH(_!BFZ{4(|}qX;;Tw;mMl066zoRi`q!o ziJt?`+X`=(XY0HQ(VMeX$D4z1>y*Qo;^;33;dcKSCon_tyidTA-qU^)bs;qbnyjwN zJ|Z&LCDo9p=Al1AED`@1{Vz7XpdUXJ}loYq1LnmO4kE_oC3cTXorl}3M+-=DO#qp-|A;xqPX=Sn6JNbk>D3N&tyHk z1U23U*@160n|+Ns`d|22dMJ##NJhf*Ffp|Hj_LTEYp;0W2rpq8{`P36^D3+F2H_MU|H%k;UKl@MKlQB8KnpBAaiQ=r$P z)YTOEOgOBParg1bNszSnW~J30$%ft&WjIG6J$y6x2HOUn*1UgY;vn<2FPcR##xliav=$ zY&qpNn4vsVUZGHrG}qpMLMTtKx`yYANjmQhq^^EsluUW{F->T`D{HC@6AwS6J|UQ0 z6k~mbbKwz3*gX{1Z`pTCCJ*I)aYL%Te25k699n45Z>PD&q2>Wx8F+;_(w;*0VdkIZkPW zO_H*wZ*z1Xc0%d4*k$S${j^`KS-~NSy|hL|jI+&hhY&vNX8dFzLB#k=H2fa21kinQ zHzHc=UWC1CUuuQq1_f~I$-?*O#N1oRMW_^|%GM(M6o{rDY z15T@+ET0H41!oGIl^rWBwgX)^p^fsNBeX7GbfO)O?xF+nmR~n>KXH*?o;GG{VGTY}8GLK> z^ya7p`n*b##+6EZ06Mtfzp7n3xlZ^+Lg5LM%eGvT`A^VGy%(NsnQ37B0mco6Z$*sn zE*w(Jz)avauu^~I9Q;;-@&(0M9Xl6N*qKg#6aKb4U?Pt?N-`m~(-W=;3vS~mOX*5S zOrixsjPBCZVO9h1hw-_NjUV9OHDBe(k(1`a4?p$r{d-Ir@RuaI4>un(g)h?#M&IjX zzvhc0ECl8GyV`oC<+s@fOl#X%|FkqEs;_{HwjmKYhgGjd)O0v9({9XYm1tq70_P1@ z2mHTcutu=Nbh@F&@y+(77ztskQ15D5mJoItEcwjdsy~%3>-LVh=^CNTUW@s(J$-^3 ztv{3w^ep=Z)w9+{*T~Kd67G{8m?mMAe#@YfDxXK{MNfoPy*UTeX%NEx{=e;KWc;ej zGg;S%S+K^RL2$InXBxF9PcLEV*A<(7A4sy?VeA-q^M6~`|KEaxIhPGWck#O38d^8T z{XKD>@A;eMml3yg&-kwgRnEomkq!LceTPvhetGN2QnvC6m_O3-LJvVh?4=^=-X~eY zzl{65Eike7!%9mfvA1Kc;Xa_Z)44a~$?eE)KanI+-R1_Y9NGS~%yit}8@~kiVASG$ zV1;hZ7nnF0;C+CnpFNXtZRQWyk-YLJDk)bMuUdT?`18Tr9n21tv*B*v+pDzJs=W>L zQ!9gh;*XNo^k9fgbqR6eO%eP{%dhq$3DU?_oO|DyzU}^q0`E zRV=X5P{N`Ab(e$kOmn z*arH`V88K8L}dB!_{bUV(~edR*j~QXYl-R2XG*A3{dddWRqGsxv(DW}0M;vsI|Q3X zW;!h`Qu|R;Do>-~!v=eXIR$tcC)n@rJ|0|4VvtY5!<#{cCAfjc7cDAg)0cnWk1!UhmoTU3^MZ?d?w7x( zr`=`zV_Hjj)A)5BQ!0;!bnbA1#laOpq!5(N=7!m5%BEDfk|MGXD z`tV}Dcq_D_|J~R4P~rlytB8)1pH-M&74e?)k;SEU#H*NTi1NPna|vxYQC5Wbi|g*4 z?Qt#R!fvSU^2pf|D)uC??hSK^^ohABK=mG93Cx$BiGGFUExp!%`~hk}fj&u7%sryH zp|GNvR6{)zBu&$6t3t3yjV$rhy|T(u6Pi_s{i`&i&vjKejSAEi4Mo1ePTxnVGw)u> zhVE?ZX$fs_is5fX=#2fb#4{|J-SCi}J`FT&#ZJ{atVlvZ7$c}KANk{Fi}uMVv6h}! z3Z5}qg;Ca;Hy5(X?_a0FmGo*Nr9Yxnc=zS+Uc^q!49XsTL+jurwM|qC_@=jGX0+bD zgCRG~;PyEJn@vR;5GKbXRl5u48>7=9>WR~3AOml~z!_9~tfT@|+UJBj;XOL6>)p8&) z|H9@iR1V2oURgfBJX0VXi9nOVN9RRa+$TvD`a8Y8~9!DIm0XLZOu{W zU%6E@yG`9?n1*>G8L30M_sox^J%YdFTZ8+kiibY%_I=f#F*o*vWLqgHJj27Akk18Q zI-rSf|65?%RmMg7ebqh0uC0k6F;2wq3JGP7dA4{}U>M}NQfFsYN4)>Tk0cKF!Rsqv z(xa$9M?Kp+eB2?7Yw*Z=wx?)&vCL42LJue?k3({ImaAzUAj9~=FsXl42r*J=HEnhr zuFe=&?oqUv5TFS~BVcU*oQ$ zouQ{l12o*okC<~|?mU-g*l+l-Lh#RU*s3>W1ok&??6=K>D4Sq_3Q-4R-amNCI=t;ZMw>*Si;fD z9lQ1*NRces8a^E}(J`(*z6%cgLa8!rti@b(Gc1u=^=%rLnvfrkGwl;wo^Q;%sbJMXN_uvBVI)vRi92vnF9T$nm!)$`YRat z2i?y5@?oLtXhmu8Q6f`Oco*0(muDw0FzY(UKRdH zFxJm@*Ybpky)yMB9>M{gIlt1o!d@r&PKon>D++#mjDh))U?*~R;SL`R1lcT>RI%GU z6Mi7Uy_Ff*_bv95*i`2kPzQLAnqBXB$sEe5{g_NXG9cAxDTC}PY)VmozjPr8PPXQV zrzD%k=aQ@J6MD|m)56L(1r*l)GZ>4Eq3_Yx498Un3hbpNnIX^Bv- zjlf#HaWa-g%-JgFf0u`Q6Ec-js3YdHmabY5N~`yA;#%K?675CJ1Y}}NQkGr!9N7{x zfrKk1<%FDV!(Ks)xRH&ntNy@Cv={3r>svyPUjwQvE=ujQoDtfSbos2$N3%Lycb$PL zH&%CY<8~cY=;s<%jBY2?BC)xxmF24A{iNRr;@YA{XfZ}a>;;n4ceM`MlQl(hOD?ce z5sfDL=7drk$nD;G35nVeP0N`^Cw;*8Zf`*Xt$Mjo9P5ve+9a)~StVbUQBNGxB08ci zSuuf#e$~ZM6qrzT@0w z*94?1e2QiFA*~o?i>X!C3)NzW|FoU!#Yq+9m(wh(`UmnnFPpCn06BLvMvP3$EK5j< z?7pznOc`c)5vQR{b}&L4$RrN_4?&6qqiIabpJvJ|TXQRvp?{XfRLzQ_=Pxu&ioV54 zQf<9Nzj&FB#MmkPufqhzUO(_NRvCE#$~GT&CdQjGTf=@ZY_uJX#5LTvFAZT2D|t4E z8V+j>UtlBj#a%iuQCJM9vgU>_OKbtDF#!Py8I2Jsj2uDYXuE_gp@mDph&Kanxlvd3tGl0j>1Jv{*> zCU!!|CSABKV6$Q=JjvpyE6l}NS@PtMo?PpVz^(4{UXI;>Z>~<7L6uzE0~)NL&rvhz zuME8oZxq=xWbYwNMFvZ}v>Zq019cwbX1w$$Uf?&P3Z>x%S2i^|UWi8H6)$58)Do}gt>{2eA%(pxjF8iYPPSFnPnqC#nQdnf*0pHa^0sBZzNU~E@`anAV5Q5S{3^hix~1Qb z+gTIlj8h{)&h`K=KxU>Va3M0e#7fkVYOn1#Bs4qaZ%-H12MN1qhdAp7Bi_ zO->ooh-Tw0caPh6e5{_lW=>%~o8I2|_O!=|POsI+JMwh#a5GPJVJQT%`^62zFr9Ox zLZhRzC*pSI|h>IGN_ldqsU+WyXi4F6qITFFaD{4%Ku8-tXy=SphBf9 zyQQ`4c1aU5h1~yEUPNI58yI56qCS&?X7sQeFs!#Vy+_*aS~TGAPfaH0?zg-)LM>Wp zvCL|&r}(S*Z-Kd@Kb*d~#Bv^31Z9}cKPhH~X;Qx)38YGEfb$ygYs>>v+$R388p-n& z5JjKLjL&=(NgFM5N4-x|866=dLm0_zNpJE8BzQ0qD_V}B+Es<%VFsK zl3maSPv4>Vhon|f5$geyg0DcjL;~N1B~WM3dCt{naYUoGRs2cNCZkq6O}PSFW8hY8 zxB>`(I#^n*4fSo9Ia(`Z@(dMAPy^WEUKSLU77c*N)j_qz?}SEUcXHVT129M|(hGp9 z=s_fOnl-V+ea7_;>gLfk^no@fA!Z%=L>MheRq4N#ewc7r8$DX$x?I<8iwRt^Eey2p zkp4FElz!OMP4TqWxB;i=z4xq!e|{yNOU6jlH2Lln`0ooG=v`^ZR{8EPUuDDppiS5^oz!;fgSPWylFV2P_cTtbc#_Aw%bhrrSYXtISseR%1o zbE;4ksdRa3*+y&9(Z2ya`V!qs1*`3$4Y3v@(!M@m;q1b}kp(188h4jiRqnrX5)&LW zkf}zMR-v$ zd3!iLXap>d9`XCBD)JYeX^Clz7>y1n04D$IuC*#bp4r(TGK{>fq_yh(XSXWOYB;%V z4hwTLZX13reuz))6(*SXdZHF+9-$cgrfGSPBHoQE zkeJl(KUF*YQ3)~`&^mb@TxcT%jf6O`DF&=X@`7V8@{?R^I4ir7sKB`16W=2ZFhHY3 z4s69uYejkLy~mLFf7Rtp z?0?H`GIMGSX@Ul9%%9qr{lyG}CnPO%qdvVYKMP5-yJbhS>_knvc~)Pd zTX;{uDDBP^P=Ym$?WYo>1--8H=urC9f=p3So=%X(+J63!yd(l@&a!O7t=FB~Y1~08(%n+TYX${&1`` zz^swG31q5WUjbVBqYLcAwi__JDi$92=S9cz37|MegOzxXM7pWN((c#-@7ipx=%#-X zFs_Se*TKr(F4I1Xm=Uv~KF=0#S709L{z==D4wPJDRu~EjNhW(dtp>XTb4$^7w!%jC zr2o5}dS{;C?zfjpt5~DY0)cV!47m!om+K|g?oa8s?ibV+m2DWtYQ((4L~Af;~;RqD!(!3zD6e+Ez6%ZgK#6ZNut)V%}W zp&|P=BkpdC7Ae$9m9%tL?8J`Y=pIE}0((Aj7)!OZYXb~(A-PH@BtEvlFEJ-LJ{!3i zrs5F#8kLZ!hws5pxfluVP=C?vQ1=#i#8|1a9d^kjm)Idb(q4~GFK6f46WkhCabR3(|dINA2{=5%A$=G1IV>ztmTV`8ao=Orehn05r@SeVS zx&(XOKnhYk4#yvvEX$DxL#o-9*`V4(So*@UOZV&x`)~6i6p$<52dTQ;&AU=8^a1-V zBiS<;6CN0)P`(@4pJIx`V>rR2dGLfCzR75qkM56xukXe9DTJ0P9vR@*gHtTyEPXrp z-Bss;;e0MK)di3A289Hk1RxEcw_ncMHmm7bAb zamLllOl|Fyow|fCuFblHdj3-Q_^Wb@JsftMp>s9yXRwv_mN%6?%N3g-6>yZixC%10 zbo`@m-2m=%q^E;bj`gak7nlu$9;Z!<6XlzrGwn&MfaPe<4XCq98>F0-__iX%s?Vs3 zJ!&jvY^%WG6SP*p^s#UhBlnnr-!+(IvZ5y60<3*oFluu@{pm1vusn-?qu*nvAF){y zO^x4ynx{JRnod&O-yrOO9(0}=}UkH}{9%@OKD8lLf{foT5YN-(9Fr^60n70e?2E>YJei8Zk#m8Gb}sI68B zogp8~4cWUyp;4F%| z2p#I;2PACj!}{BBOIU*`^*6mG8@#GC9z8P8oI{`~KVq7}(wF1>Zevd-SOO*$a-?P8 zAkphbk`A#OT8p8s@2byZ*>{hzgFPl+}PIMJXRr>))z8kYF=n(F;sk$) zfRTO?;@FL>(>mxq z)a<%(dqPyV&}~OgFKZSh*1Y|Xu62h zK*Jm;=LpeV+yk@j8zUs;t)^`2Y0Yn-#JR&E7@llE?+_<;#1QTv*<|J!>hLCV3$@7m zf!TYHKHj+H$TLG_BJGowQHr+)_?a!jnVS8ffE<1efo^Dmi@m|^J?0jhoo&9YWLf{b zZ;dMPk>A|GiZey*Z4&X0EwOyLqOliy@|xQsX+v9Q!kr&eV80ss&|He;^~HZ0&$Iif z{ok!+w`>gt^t*eu&((deUsn+F#?KN=f?MUc=p^D#T}Ai?I*yrm?G=`Ns+YaE6w?d{ z2sluWT9&JYdH?YYb1PB>r#g+Bmcnw%_H|S`q^s!Jid7oDN1aAXD8NL9@JWk4-%R0o z3Wd^8SQ0t%^8~H0jHBY2OJZ7VWU7vicl6f(yk3|Q_lg&LXj$eUX;I`i>eXV|n<1c> zO?&5$u*b=6oeua#ZAree(^jiH3@Z;-86J#1ZX@1?{XVv{>17@JEy}WvB@~fXL%Ofl z%1WZ>m{F{>Z0Bl03tg~V8j)~G6Bkl-?y=5c#i@%afcfR5Xl<&>U8pJzei_NEm3={} zwLY0hnO$S}6_5Z{RBWlAH7;8M%5TbaO#s#yCe(R_>=XYw>m7@ex=wm*f=v#77c1) z_$%?pZg&FsQQNT2}tEhl#k|RA!UUumTGg+KTM&KpTZ9JeKGm%QN0DF}^ereXqfCbdN$?%2Qn{ zVv@U-Lbx9vN!{%1;WnbKCOFC@48fQM_1Ykl_CuSNnj}pvz?l3!fVBtV<)SN``76+t zf78s%S?4PXsjJPAH0u!0Fwa@i@H%?FT1{_{LR88;va4Wxzd0u%szTMQAhR8^6)wu# zCwqwhxn5vb3Ery)Muc783s+clPUWWMV0E%aZ~m9*7Yf7Sm;=>;?4e)do5f3V+Q4Kh8*zQ+7#+fHc)99bo!dgMeP@5k?YkCd64s@Vh@?LO*|cR-$h=5w4j5jNKM6stoOUa-txnB z(c_yyvLn%ewOjb4+ZG`)5BQAQrk+5S3K>t7ZVX-&K|Y+hCSR z(MjY9{@%o%D*7V@RrOS5t`n(VGxz9sT&j)%eH=LLuRUWuKxxt*H zqa%01oFFpyzPt@%xymLCZbpm364dHYu1H0Z!CObmLY9qwrD|>Vi$eGUClr%kbXTr* z!>UG5r3mggjgm(nl4u3etz}U9gz5xC1egRKmX)J^mUW}+#xvgeC7Zp6>LshN-{L#P zf7i)qGZd~Tf!(Zyus#IvKDS-5{)S5$L2Rz*K%HvJe2-DLv2``!P4A(I1HdB95YC6w zE>oQDCbok~LP`s2T%AtAPi}kA$@q2`*dn6D60gOty#OSTT$DMuS(c3+ebcK20es`l z;U*9I5}43TL>hTxDl!qyT(q%ilqK$B>3uqj>a zMKbKm{cRK^KOsNgZy{V5R>?o$+~*idyMwpkV!jkLsB7u7B%FyICOny6U`aBcd+6C{ zR|<){QN{fC7$@5V?O1;}%pr+k^NPjuWYKZ_wU}$B^Q==$Pe4^%9$$eP{`tkSZ_q2c zF>3`#NjBa*5U4YT?4-UMN3t{MC^aBAPvxc3dW^9if%vf>-3xxmDs<8DjS_mCtEVIq z5=o@=(F1xD{onS3dLM2_wIEn}kz@^yrZ_I8+!ggKE?_0II@H{;1BXqB-3BsqwHv1P zxt;>8)W`~(4F2ue#sN&JYoLkBb3u+X0opPT^&c(rKnC=W^~+X^Eq^(UW`zxg-|RMe znO)oV&Z2C#hTjf0o0JKx5>?hT;<1Q=K){=NnQzsXxtruMj+Jg--}`kPg#&F}B_iy^ zMawXi&|JauOIG!Y?H|RcxocBlA1bs<|97YJ!-^g1Lpo@ssG)xpd*_UflVw=LGKtYb zhxsqa>&8hdXvh0!A|rPixW0yeLnlyzi22oJW)St4%=}|%j7nSdc;c_iz?}%;;xF-c zD&lo}qBv*Ac<%qZgu{yEbgtG;&P-AzpS*M*6NJe7_UI;e=9sSXv@P^Nk?J$zMmAG1 zyp$cU%^ImKMP*Qv|-X;{_csyi3xfT4h`aGtK))v~M8M%M``N1e%J9NrrtN zwK+nXB(~~@ogq5HnmE^x5rub(YYY_j?2G9`wR_?d%x28HZiZ@yd49i9ivVv0zT~bb z8&f>URh?N@^puLxUYu?@CewG#xp){gZ*mHUD-i%ZZH{TI=MPI6q&19>k0i=63Lq3k z8`ChS;xIpQ^?j7P`4Y}{2O%P*P*6@W&(Pj8toby3{m4FZ3u!9oZ9bg^d}9d7i)FZ( z;O2bd?-mIM^IOJrN*ZR2ZZgxiEl3lVZ}8xG?T0>H8V|e@g7!lpKZ%FmpVG%J-BOts zw&F@v!owEX4WCn$tx z(UWVeqTp$WsyOnTXa@Co)S&O#9C+l?$3*zPALiGqkO%jFG%gzJ~IcImb2( zpB!CX@SartIM04>ui9`IG89S{>NME&iSNRwA2Q^QlGFb}+wAkNvOB6?g50_nU48kw z+9FA>`2hL-#ujQ_k>mt;8+s1kI?Dg~Vp9rRo1==opO1q6@rbCjBUl}oWaFzu6d@w<)ZLzvRWsQuH z0~5f|-<-}B%bx6!@eJocPfpvV+Ju;$0qU2hI=g1i{jcLZ`jq%dvPyY-lAD;Kh8OEr zzukW>WU{d=5E6wjdP;1{FsVp>#QiK|5m!hib60>HXd(QWUyNfufmxDE{TYWR0yMH9 zbKNI!*Dy;*>wP<&{aUem7x%{lLq(n-#mKD`2AC#+1jWsGpI;?5ee9{jFJj0mk^YG^ zs=iC^{_ODV$9D3FnVxTcFCmrY334I?{91=G*h(9)fG?w{&YZ*s;J8V05hs^IbMlN% zgri6MKR^QNBDr-9<3rM5Av`(}9+6}G&*(>Grrz|~0VWy0J7pFb(tijWH(?T=zfEv8 zG`7f&KgSU5rKA_%#?^L+EJrANZqK(bj%4#hoCNsbNe*tLRvY8-%O#CH{+yi&T-B{` zI2=kjb2Rvl76b>7extncAvcFf_TrXr*-Sxwd zsjaj_MV~EaZu__zVkz{Sij?Rr;~87cm7ax-wH6>7k@+ zi73JTQH&->lfO#Ls=j+Sx+fY0G(*qa_{A9m>abI^V&0@Yub4kVz_X0OM5N7AaSblJ zDheDEiOW{)RJ6WwU8K$mc`uk#aQY^xu!VXtjJkg%sn|6srr1T;;|4H2>`c=?Wo^BE(qNRC5ASAhBSaWfMWoqu{8oe~i zGrqLL3C(|MoJX#R<})tCJE7ufbe5dolMiTpCak2n#syz9Yb_lved<%-lOc&35h&ZK zE|hUA4Kt@1vSTPV=EnyMh)D(&jqX0W0h*tGDx)!M+;9OQjmV}NmrFjCz*dr21?8~t zTF0Ag`h33CXXc2E0^e3U%ek|yiJo(WUW8n$6s^}6mqkeKJ+}<_;z;ZdqcxPd?gZGU zt0qrYp4NYlA5?97=dsh`w3W)H`Fm~|-N3!{^yLNlz2uecc3Le-m35LmSKu)kc^Lf9 zaIcs*3tT40e-Nlp-L5H?(u@_X|8(bf*^!g3k3>>O%H~*_b|b=CbwNyOB=GQc#yND} z_^nT&glx%9_4jOxJ9+USFIm=6_W|<>e`yS>_|k_906y1}lGmE{hPSbAc*X<8i8@mI zE|b*_hKI>(Uw8Rd_dd&CEyEm%bxM*cKQX$+PiE+>2lANBKUCU6edSdxwiNLl zsBnfSI}q>5T&ILQjcl}v0-J^;(>*uM|9w9FOBJTrS7vol9gsX80sCI3#_}H@ z!|PzaefcNX9ib|yPU4u98EoQsxvT9Wdj|OWMrs)WVj~dTCGyrL-w%?!4!>-bQ zTS9p=&D6B}ws^9mrItR86BVajf!{p`o$Go#qj5g_85apei1X|ta((yFYwXQ1x0bR- zKFKpmVMbO9wfnLm*oV8DLpmiWbli+RUy%_$4^MIYc`Bs7K2IyNm31wnZn?T7G{k{_ ztX3b2cfzvfP#BM7!>IxXEK2}y>y?sWs#uzA+>j~f$10vDbc|E$<=8;sZE!irAb%qZ zPXWk?Zf6^ar|}W&p;3$2NBAUPQ@8LE)P5HKab8Q_J#y$;oIi0BhCz)vA|doJyw%71 zzwhU?f2u-AeQqOLqiBC+g*E2&u?j%0;!z7+7+qRvM)$s$Wm+E?6b*(Kg~4~Ih8CU; zBiezMkUc+1@8G~n(UB5V9s6l51kd)LjCdm?*9M}Jw67QHL=QHqKSj-R9?W@QP24^` zUdD_12LBf(-`w$Sb>DV@uMtIw;t)o8UgX7kN`(pM^&wr)t}7rYgZLlB+t0FYVO{~x znPxXr+?xUzcGLF)>e;dUi`NGOrcu%jzjrc>xa-VxeWuOZmfN0Q>~)%0#pUUy+7+;U z6qqh4o*MR+1lti7J;cvl$S?8wuK^}p#d=yix;z!`Z3_ec_g ziZ%xWRAR$>Qj+AP*cenR@fg>ys`CBj9A9Vm!(#&=rb5gq=u6XRA4Nk}Cjh6AnUs>5 z7UdzBseZ0NTXRpRlk@LsUn96?3#%{;h@#pEBKn9mRHqgMxV6_fG2=W3*h~udw#>)0 z^(3j;g@txm6$@N{xJGx?O8V?1Fs@iLI-Mgp6o{=e%rXrdUOoVS7NzQrY$4t`i4Cq~ zckky2?4Yzh;tcWh-`i{z+i{XR5cuHpV!ag!pxj@zWDAcbup+HW zve@_rW$-=SlAbo5{b+zZ#Hz@2|0SWCXZoWMYly^OP^_~LY7mFbu-l*GIm0GGpzKqdl`~ix&K>`rqsS>!2s&kUXfF3dK|W zPV=Sze_YJz!j5Q!$M`$*V5!c*7Zx8RcY^gtjI1gJ6#Jn(t#uj^1-IvhkChL>TL1auQ9z}3qlZsX+l9ee| zH$9&bULPV=J+XK@XM)&m?Ntyi%Cu(Bmt4}v?d=!Pk`QRenhf>z-(JJ^%$WH9r~s1s z_}J3(Y#l4ZF9B17yl<_qqJOG)lHt_`%O|fhcx;Y8t>cM>w$}<8rJ+7ps&$J9<#H=k z8_84!c)$!jdW+K$g|COUM2Yj**6a_Bh6p>Kxf)~XBMu)`kdY%d?|yd$tg8gXW?RD< zLVzx8GMgi_XJu^mWqhu7CRrTEW&SYUgGyXyjlLB7=r*)biOK>BGya+TrZlV{CX`b~67)Mb-q;ri;tT{}^FS4H)*7%w$XP-JtpJ~N5B~{=O2(8G;f-7a%ZM>0+ zYZK*DJ7mARFNn#lZVclV93pB~6xf*i$8{MY`Sg$5d0@4jPgb$+-*CkDW4JHrtLHqO z@yP3Z$HnGWw~xobpZg-qpq|#IwJu4~BJ8=^lcY2w?$G(eL(#Pk%an{W&ElHuT4v=k%an<+zC2U4}_RjqA}@n6oRc>H-?W5U8)ZOSfOFZP}xq))_z^ z;XQU;x`gn&poRKvh-I%iYi$y5zN>?;3`SNnTbl}t!M8?99cAl6227uTm*Yq6C>2Gz z+Rvzy^Ka|sXmcFpkERMJjOUll7Y46$CH9!JHK2nv^DGc^OI9flPOzNg{sY83N1x@8 z7B216En*0S0@t?C5BQ0g{~d0YVzFv@4t~AB!2$itSSgkI${CX3A+^TaKsSE1A^$rp z2N*4eQS!u2@Z{E*fmr=jf-&+!8< zi>r&xbM?(`ib+J>UyeX#uB;s6X$!fjYe>UY7|nceG=jyhMc(&r)Q2GolhUg5CuyDK zL(@6T4T#0hlq%_%kBlU8`VT7S8Gri4KmH4z_oYkB zSs3%@iH%~iQ{*Csy=iy;x+|s!kHKl|7uG;W)-(XEaaUvSqZX@bY(K2;qAau|t42pj zHq-;d%jtJY80SWPT6XX^6JB(j9q>ugTYl}GuZs-X^HIgCiy%PQYeVc2`|9i}QNfQ; zt4tAG@m>whMnV|wsH@zlRK06691_le`2~bmf9kl6Ub_9duvk(-@k#;WORQi5Q-%9F zZ4}!d-y*q*HcN~f;2GKsMfT?tZn7ueJ~<;2YdO|8Sk@)d`Q}=6m@Nia# zu1d1d_;vO0_uCaaski1@Zq}CTA&9 zWii6?Q*zXcW>tpm!bx?+AE)FExiwVRD+z09P!DO-=)fK_eA(S0iQN6wzWT>=!}gu2 ziNY(3O;-0)H!w@rH-x<%*GKOv+z!9Rhk0J_qKq3d?yD|?tJi<|37JHgkK(TZN0Nml z;%DU9lG;b*gcX*Og&FfD*sWw%ylR~(WHWYac8oEgL0Em)4|=}Cp*ueeV7w<;Uz&#d zCT@Fzz9~z#%onuxx(KB?WQTSis_Q4=kS?~$d_!&(2yDZhAByeclmbhGet2MfpeqW_ z$_GnsW7u^#NB`x0sHuu8p{IX7D!&B<%i;?&7E)=Yj_q0}dhYJ9WbL{#W{fV3X;pMC z%}w*s4eK(~{OiFz{dS!*ToF+qd@`Hv5;v(TWI@dPpY_5Ol7i;~?!#8Qn8Zk?hq&*+ z+xb-P0{n(=4jL=pI_vJ-xGINzv~4k;9iQ#(&hc}jQ;RE=nRwXe~{oyym& z(V<0yJ5@zx7#vEfM#kSl$q67$aO%oLiE;%Dm6p#3vtIyC22v@{Fxuz16rW~lrCwwX z*93qAq&l;c2|mTSrCZd>x-!8Kv6Xttyf3N$a8HUkX?tR}lyO%~q=X|4%O~4v)7piP z=F2{a*)#Z`YUqD)r>pN7DRJLE_GUD`D~w4M6ZhC@cFV?_m}T60Qyh>Ebqq-m08l85 zmx7%_j}U!NqovQ%X6(u~PYHeV9?BNSI(kqqMf*{)bXguC9%@Lhiuu=Nvl7e~3iUy) ziPqH9*MxX8l8l+QU4N}J71o#O`p{LRUU)68UOcq!;V#AEaT#Kxr)aE$AI1xt^iyoz zLAKgl*qXZcp6>JsS&HjS3hPzt6?i|LhoXP^#i)sS^>jRlTCI)w^T=T&6$z**k5fs8 zdT2dL6)u(gW1O^A7T+41tS&G!lCSkSgS>Qy+$uJ6Sz3RsiO*x>yBogzknBF0XSNukt%9#bLt;kIF;0`U7O=UrX& z#*B^{UBC37ml2fcO}YSW&eJt*()h0l?1px*fmYVyrI{RsN}$ig_by2nO*=mMA}Mc+ zL>12h7e0zHYB{K29v=}LrWng!msR8WR9DLQV0r_s1b5j7$Xsbk-pW_&S)S;$Td#B@ zjOr@{wwC_=%A(7j-Ja&oMxs<7An)j4Dda)|Bre4?=cByK(Ni%Ha!&;A3kad9QdrD% zS8%`KSKx;-PD*U5m3$kg{6ot0MvFSYk7{)~XfNw_YP7pLiPr`U{aUE&L3%8w$nSK8 z;kD5-e*oJi2YA)aAzOPh9z$S-$gWY-Yd5CAYlnW?^#Gn7p6>+s3d+)uRAeJ(-e=cs!%g@N4W43w&eW@{{jzyJB1$JayTtB(esBv}B>p zg@u&g^H;s^YtI`N7%d)i!v;=Es5TC|Ig5`B#VvPEKDj^_Ns6jpJ*DYXFva8Fxpv4T zB&*^EStbf zrY!WbZ3Fo7ZLoH|(Bv3n%t3q;t@*bO?Z_%E04qGZs!S9q_81%Ry~~58)Tulm6kN@* zBaG-T0`Hu^g|su@*2%e{`8Sjn_6s@tKfFe68pLl*P@b~0MDPzq_S%K#%Ij(G(5c@B z#5Q*eyy2}yaWg)H=)x|A z-}eO9N6uD8Qr15;t8bqVTpDz2sfyuFmX$%gjk>*O!9{8p((aEaV};D<)R;hiE=(Ns<0%~>%>3V4mpQ<~l@^{&9!`cQ587yiUIsz$w(i~>8qNbVe0(`?=kNmnyD z32GOK+6qx`1>t#!RW)&R3wbdLHPf%X^8rot=X@^jIQv4>Xh-f8u2*lKwz0>Ipk%c# zS9{)a4y6M=BAZ!Y&INrzEZjrmgtO=~@~SVYJI-IkU~=5S)YR!CrnI>)uIF>ah6J>{ zAxp5}=vp~@J6&1EI4diGUL_@8qqJu-$eR?6!kjYfsS1i_6GeZ`!X+V<0(eRyLoLWw z$XD9pgwt=H0-uELPM*~Q$#Rl6U%uGYG8X-M`fbo>O-s#U=|e_x)En830nNu{yJVQI z+8?H!mz|CWU!*i=Vagd_f0{s{U3%{%mtVCIN&~2>5H9IEMv-4Z3Ar;moO;fRYu3v1 zn^JuEjf*57g}KwUD_Jqh`UnHpp0FuZ?#D0#Ugw@?mc$5>w~xgB3_TOw@qI9OE;m{1 z@at$Btxh1GbF)tFJDSm~F*vM_G+mpsM>V%+(C9^ZC2Ov!;XU83mGq7Vk%OsW8G4fP zxUTq*IDWyp#E@@e=zzyLic8Zaf5oC|IAJnNJBeRo!82}w+R5y2&O+Rc{o;Td&_(LL zW!Tu4(@lq=c?As}ROR};+Bi7TIdPX_x9NA1sB>0(k=%%`LB?=8!q>3911oPZq>ZX;9|sd9UMsM0?+!MHb>tck zs^$ud-=x=*j13x6O|5(JwSpI(b@XplpCM##;ero%R$F^72yDHeM4M9p>3?w^GM`vhs5Hmga@(Dswuml2k)R`-KP6V*huhDe zqBg0L6+5OdJ-C}-04HMaUcSJQx0q`l>aWUz$gqEl zZfmazk^dn<``^6`s=VL}=~SP4A@EKZ{6M$!tRmxx?IGuy_2R=nQKN42N-_lB>DRi2 z=dzPA58)#D3UPY4_K||Ja~b(tBXWQU(E9=5@c@;+XAmx=phG}Nrno0Mwcu(bBNoyJ|5H?3FsuvB3t z$P;bWBzF%lhz!{&I$>0kmmPhBr^Wj3LNYiOo~a&i)VCc#)7fk2^O&|ca48NG^pJ#K1|F+ z?dYPDs8f`RhSJ*&?*lx%5-i->H~s(%DdjKhA9! zCMFGX+IuzE3I(Uo)XeOO;Vam6sD+(wmkUFlK|gYp<5*+Q0Y?ekK&yhHmA!%FpjP?U z5-PiiwD9ihBobr~$F>sspK1&w(JN_&rRd>wVgTveyzwl=OEK)(Ft8f;Zx-s}w@7d} zpOc-aq$ zmU&i6#2)LZR=>5>eIy>zd{i)>fTIMY*h>@DQP#ocg%k}dg?38w&kL&B?F>Cz9=wR| zFuJuV>g5_yJ?$iNaQuq0{j(_@+^5P2YycbX2%-8C9AL3VD#4TwQUpJ9n_T1iCL$l&{HL&}mp%6-LF?1$a4yaIoV0h~2> z&}k1pWtSj0NepKXdQOJxgEd*uW}ji+&e`Hn-g4&Z!fQ6rdNF;F8r$)+)AYbHD|C7W zfh}ZWmvFk|^S4|p!v+oBGdMS0d&60(H=wdUZy|1JRz-3zb6P}^elgE9L}4j=T(_DkAgJDIvDhE@f;l0$BC<8*( z`}L9o;`3gB!=!DU=hz_X#0LXy(QZB{R;ev_8~ATMh;f$|ub?Ou%v|tpmzOMf1@Rf0 z?hOclpW0cE-%+4BtS?)^zViLaT>ktZ3DzAO{%JQ?cTD+EV$&$7WECb0@t zEv4JhknlYxfp3HXev~e1(JLs6!WW>W9C^X(d$rp&+lN_DN;65i}eDUEe=N>6Wepm3t0C~xc245pd>2w z5jfI+Y@wGf0r*1`CgjTxckh^<=Yh>U#DZKp=0U-;#i^=F)}@2#alegWTp`5?HCJDP zmeifH$1W^6k2p3}&&4dUd?$4Tx;2YU8Uz;|xzH)M7r9|N?3SPC=gkr#CM>#e+sJ1a zxJqwZ87MJw$`1wcd___5A;m>&kXUq$A$^fQV{8E?ok|fuo8!`^>9of%k#^^+l|@-l zoi0ILvj!|qL-zJ+t-q`$sUTuQ>3SaT?5SGe2(qgc%;XbPp$RT+BS(4?phT}-NKgLX zuX@nta zK)l0PWzAQModjKaB6ytk{A1Ms}3l0aZk!<(r z3ZA{x;qGAzb}tnkzZ>)=3w3552A74lo(#uxZ`*|W|1d_AnhthpCJG6Bn&1@4xQjGA zqVlO=ytD?E5<5Q%-?S30_tO;2!-&DtnXlc~tBaRL2`-oNh_V_$Xgv*{xM(DJzv3QB z_yFsn_9}Il{1rNyVGnj`PF^})4_Nyz6t(P~eBl8f{&amOOLe2e!tLtL(Y$5CFf;l- z&9b)N^+3b~#|($qj{-a=-5dnotm*D%C9!M<X`EUTN#S*~%YO;O40J6TYM*dSdIV zh!(-79v_jOeEy#uBe~GY#UM)OdbROjB$#k{TeWaAA{Yv~N|91}gNbmBHsIOq7y|(`r z3BRa|rQVN^MbWlgt`FfgsD(gB`(Um*O#L*j;0rdrcEXK*FUoH4n0ynpqT<^t&czu-B5+_na?v*Jac1;{&w zad-5e_2Rp8X!WW^i}(642ePX%dE&Pz3N0XAh1ABn2v@Jt%hf~<$~DNN1GlX;q<=Xp z2f5h6$GyOwQaaYPBdzv+HnQ3jdAxG3evGD)qB_-td*r}tk%x`4gNKw;eW-lT4dPNU zT$Wj#s7`(C97oT$f_{6fI!kRUqu<|h5BAABhSIF={>e2z8Irgqrx)MrX+Ay_wPMZO zMkjCE8EW@hq-^MQ_KT+#*ZuLaqu|`*UgN0cOm=t8M^xvo+0D6fqawYR_=475l7)I; z(X>gS??`j7W%^Rh$oYv{d+E1sbao5(xR(@8CLx}`H|SG5Dc`7qsvNyY?xxH5DHnEJ zb{cAs2>i8`?nU!Z)iK;Wpa1=K;wx-3X66OJb~>O+tey8?!DwuaAS~cl=j0 zqM-^Fmd(_n53}C57ySp#sXU_lhXm~_p}fjDRffK-^nQqVV!fsFiz$g-+tqk0V2tVZ zzlGk1ksB)Le9af_v(lH-goi+00_>ha=?jcmKAwfL2vde0Tk-~*9{buR_o zl6ui~^s3ezX0v9VFzTV!pw}pfXvabeoqyp^wc&4Sr$|mjz!F-pq>oK{rPEvU=DUKz z^J>KqkK6_O$_>zko+nipK~XMg^i>A%SHB%GZxk`1Ka||(nPkz#M0!1}z;B`PP!T^; zB$~gb&@LY1wIQGTl1bCLnkmtssy)r4)^zgtA7^pDol~a4Eaj|R1Z&Kz;mk%ow7LdK z0{nTbLk!NcTn~|F#1*>2$9{Gc(JIYN;dqkDZ_}06Qy7V}lQmlUh^)nm`a8J|s;EsD z_6XoioGY(i={~7@I_~_P`=5qKj)b(*rnnkn6Z*fqj(dj3Q?bP-F#Uzxx(svV~Yy8;-M+{uGV z8-BiY`-clW_tD~^s8x-asB_w~FtQW3ef#8D@yPlPPDRdQE<)=So@F=)k#=pPd$HFBfR5`Cf_e?=*>I z@wpYcM`v}rS-kxdCiKWLQxSiSK5Ml$3x?0o)4+b-(MaYQ+_qZz+IxGu+K)UI#R1oq z6?R1n?nT!CzdJ%6Q;Fzy{Dzyl80Q z*Y*VFWakZ}D;PRddyR(2+WTQVG@Nv>v?z=mv8Msuh~U96lRbx|13HgATDt6xr6-)F zAuqwnt2?8Z(BfZ9*gjvr2k7=V*p2z z{5cMJZoQrc&%JtZIk6+dr1hv zX`8(~uZKtO3LUNwz|IGvkSg}ATnS{4Ss|{I)?UhYLmfZKuUde(3aALl)11W%`^kf0 z?7=(La9%BIgTqQehBSJFMF;Aw@7lh5#8faJI@jTi_x#mu&PRu8dIq&2hdK9#Te}(J zEgG~iskrBmbMX@*EAeyA=s}?@5rL^!fJCqo-N9R4$7z4vQYePEp(*4Y^Yd)2y?Bp6~X%q4QQLcryuV&bI5Y?zY`GZgJsFoQe89;Ia zX+Aanmz0c@=sqy^=atzcj5Gixmu+YW=`H`jg6+tif;5WjfKv> z`izw-AOknw91*QM&OyYm4^z?)AHsHODS`2FJAfl!!J|$bH#ziCy6q-ozuH|Q?&Iy5 z@clhS7tiWLYqI}+MzhbAy8i7hJ=5oR-ZMGyhK9SpgqyHUfBZ{}((eK5+@zkAc$4PH zVT^Wg(Ir=6g$BpFCx_)&3wyVa%f{d_K?act%UhQ=c~KG@p0- zfF|=3VA|rp&1wFh7Ev1oTkj<}@VJt9P(?;8&v9|cy$4)F#wwxvtm)j_^#u9}nXN2v z8{#-=+^Ril=~Aqgx5p~0?8agy42oQ01Tvz_UCdO=cl1vs1scw|wj*hDtC*-K5DZ&4 z5*;z#c>?6B^hEt()X&iCUf7EJnl3E9<5 zTmvLe9FOlkL{iz>fR!0%A-$(*%>sw|0W}<-nWyMSK6!d;s%0Eg81?czR8Qtc}%1`YcIA7MkmWh=mliwmSV zzd5W}eAiqK8v5KX1^P4G$cZzPaGdq-UI= z_wjm`;8yV%T!{+;!Z0*h6UlfiKL& z?eLN{YyU2+0T*F&#Lq0D62hH32*1Vn_;dkUSBiI3i_>jQd7izVDJoop#$afpZ-(@r z0@G!_Es8fi_#wifH`4*u)==9ufzv}j>VPoNX|(JauJ_wUQM9C9GFRA|GG$_uo&v{5 zdJQHyHi4-qYy@cu?Qkp`D{-$jO@jY+`U7d(uxBezI&zbig;}*JE{uyha#vle-&NJe zqXlVK$fh(i>MyGzd&97o1yE-eD)T;7@9D;u)$*yI)zgi9EiICcVzp*j7$Y6(U!i~E zO3?6&axhIQMwA`Am30#Gi-%zcl8QyD!ovHZjDG_CMj9fLHS8^|2@%Nptj*D1T zNcN0;$B9q~3=dg-$u<=K@Ez9`1HYRQDED@D82{ghGPjsO>xsP7u~n26agQXs2Q5-a z&z-wbS1Wj9{3Qmw)iix-+ZyS``M5a3#!mB#z#*6+BSI!cH~EZU%t<<00XeeB)l-MC zVG{xG6wttj)v~>v4Fm=7cp?G!x86|=%OTSK@q{bvkh^kNv{9q~VY`iIvRhFYY1(xu znHkcJX^=Zk9LFj0iA?J$lO|sUB~5Mk?PC?o&lQ+7q+rx|kRkW&)-^joB7WQ}=o!Vf zxk33P0ew;9oT%bc>=8p@YlTH^&c16}`Ag_Seuj-G_wY3{-0trmtuOU*2864Xmuonj zeW!BOZ+OS=qaisq~(cNX!xR9d_J)MSeYDNy%oqcsp{!4X16H4DWS|(PB9LLbuz$3H}RMg%xcul{+N~ zDOqlfwdiS5?ie-M=+w}l@hW}(mvmBjMx7I@-H{ksk4{Dm1ZtN^zn`cfPpjt9TzoJ3 z(8(lWu+rLw&|+P}+c|3c75|MPF}%&2Lns4<^pG8MtwL-~AENl|^)mgTDrVfoa1A)s zfpI$J*=YW6Bv5t__$bSnNgYMzHLZ=9WacQL)NN9v) z8o6K*r@ty(yGYW{{}&xO;R(rTo`JLHIzu{^xOuO9lUU;wQ3nNditizWm zA9p8&M9O_rlnYN{?s=b*3^Z%5RWMFy?z=s`r8OCUZv{H6mP)1{v8}n=l9=A%Pi|?Y|%MM3>Kx4?BTk;ehh2+bYT2auh$> z?S%abqC=IxGO_Q#`08Ru$a3V$cHEhQuTHxtqIYr(@lZgFs8K(eANW@U>!*U^6!J>t z;3@yYATK9>=qWK>3q>q}+s}SwYWHrsiRo&;N7qbCJBj4LOEl3EV#4%1Kd||8O;QJq zQ+)C+z;?=SNPE(ivPToPkK5jNw2gP| zkbDQF^`U>%^#d5&l$tO8DEh~*$j%nw%dz@BtCp@S*g>+M-F>8)-cgo(zLqP zW^r@JVW3FTt+yi#ZR{C{n>gM$?eTUqguZ0!^D zQ0g|U)0X3>Q2okO3DI#VBI0Y|?CUAz$wlKkm>Ea16)Xqk$*!nSZBpUU+K|JPH9XI; z7G&iD_7{1(s{+_^TmVnc6dd>J5`@qsZ*EZ5Ae;?+L|ygNFE``a;1QHr&^bJI_?KIN zrvl$Gy2E*BYBFRe}_gw;`Nr_&(ddS3i@!p^tz~4Gt-D!n}(_??vneI zRNQ{T5(BO`Fh~1%I>Ddv*yXOL$mG$sB7jWAO`9GCkEyo!Q({Cd!X#0#Vj@MeSo>J% z^zTRs9GNRG2y?cY41dESQWkg-U)s5TEu7ejd;{4wxjfY-PutW^9b9P-9s0VZD=8H{ zG&H2e6s8@j4IXh5k0ep-9&Ix~87og7R_DS&&Pr2czZPV;iZJIl3YK|L7U=#`KzTNK z;+`&QGQ8Uf`jEEmBoNL*w^dd^pWBCUKanl*uZ0Yr(!}W*=vaq3w|j+08;c)e9Y$}xzq_})r=1vT1Lr)|rp4v(Rp`5clgvy4X?Lr$Xe zeGWy6RMW7n+N~Uq)T8E}Qy7^8KZ*#wj$N^%;o`1!QltM8uVSATedG1R1wHS%2_l3s z<_PSaT+xM*o9L=FSE~~hwN7N3IzUGKyknJGJp%l1z=tg@fFaKR{3m&W6|z4OqJDur zh_rtQBxg|=-$iE+js@+@ce^Gd@~>24i3_l28-07_N%I?o-$e->u_DZs^)aR|zlqM~i5=ck(y}!T|C`fmME#gEYtu>bR1n7* zmb|@c>vC%ya`BUTcW9SCL=V`_S)_de{zJ40F_c}^c22S@utAi$|Bg|#{#8Kq>EttL zp=S=9)w7cw63e{(zZWIfnrf$7&d*Xd>Bb(=ZXVl!{x9`Oyj`w#`7!CFj<9_P_r(L# z8-z2s+Rnp~i~j%o$v2PK3T`{VeUVuW2`I4{NKfaS-?lGxS#Xx`&e7lW%RrH%IQ=W} z+M7z&zZ_2&VT`nm=qqM^``-{0ohhVWlzCqS6!6vS$X?HZANyXLzK%M+)(6oLw==p2 zuZt?^KmPC4w=I#|Q6Vyq75=ieLRD1;X0rQk*RpwS(642VwwrXhZ&>eAF}2>&8O*jw zXH>{r@A;K1|1QnX$>LhC=xV07sB5ZtlkHQ5>G8EgqC6G6(>4->p3kP`QQD9p9YP2M zdsXNcTk4apEWeyc;Quj^uv=0a)<---T_c-{+)}tcH{_Q_pVmHE{9j0!xSE+p-=7m% zrC@eY|4Zi^ayveUT~8OJoxEL+uf2kNCvrXX_`@lnNyUs+qHdkt!CU_Td#7(Wa)qpm zQ1e|B^k%6p*YTINJ=pXPef_i3zU+N55jJY;-CIYApTfPE$jRGzRCQCgL3G(c;$Fq8 z!WTu61)BE*DA#Lk@`B54@=mS6s?%Z`YQil_@gYx@AeT2*BZuuL;{?VXN1$vn;4JHXOXv|6x_76x`wPPw=7I0xjN4Wf%cqrBWg_wN8BMQR1C zdZ6+Fd6jl&*}->bs)|4i4(LW%yRg|lh2jOd9 zlu7Q#Re#rTgSwL%OgZMNR+J_Rqh|Uq54u{(ic{>aKT|mYrVon;97m<;j^LqK%H0x9 zcs3?U!pW01B{d2zU(V)H18tL|URl_E2{|9M6jW^vec!h;OZss5X{vTPtF(?jpSb|b zHn54;$mdTmzwhL;Ui?KsGS%o`MLEs}(0^|}>FS_ecyb=Ex({_vezqOytCG<)WDlY` z-K07*=P7l&JVLse|7|iiqeDS_e1E?H`d${XwpUWG>L#6f*`?f>>)E1OBpJ&5=Y6C{xUWCi!2B?#i5vCyWS`Y$eiFA+~ zDH-?df|<8!4FDuC9OFZuM70!;XRSeRI_K`;bk<&*#OptWSY8my=*x)1PDkbQ#h+o# z?-Q;gez`h=xY_Z)$o}>+USOk%=rcbLcgtzK>3^f^RPjOoTJg%={<7OT4sxp$yH+H< zJPIDJ4am(%|ITwuJT5u#e-pT}rPBHOA@)*!tLoLiCOOaiGnPAFdF+UI2~P1=5Wkmr zn#~#r7+=(*O$Qxk4b*zd?WDZ) z9K^l$#^pTI83o6BpCM%y+)H+VrM|%Bs1<*-0JJ!vdoONcVg?} zq7ndsA!f(@F}!oE_z&88A9n-vPvKUzU@y1E3LR?<9lGiwZG4sS{1Y#k(E7GTGWYmQ zl)bop=c%agNtr&~x?IJ={H5&ZUvIi37n?DQeH0q9U8pWd^XL$aoqV%>qS8aNiuxpz zZO+0}`_HWOp&*#zVyj`Jm>u>0PsHs^|NAFm1>em_k(`M!^k-7u@17r)I79}B*>Mr@ z(BWG!24(Te&-HRnGVZ2Up&flbU2)i14}m-ui+wFR`-#$A&7(Vr8f>OXI?4Vn9FEGZ z*M3jN{n^(cEZ-dlx0MS1A@Vi0h71R>JF-r#UAvaG8fuIhRrc6}-SmCK8H;_kiQHbE z^0XN?nq1GL-n_dM6+yMrKlcav<2h8%Y9_&BSCLrLPgpPhmI-GqUU&vDb>3=4z1|&m z=jvv~UXR+60s7qYG-cQ-I>7LMeb7)v3GgHX#X$7u1Ji&3e*SqHw2hDcXM z9&G};ud;e4*_;0Ro09%0f&Te_!>5v&5pUhk7a5bE50Ib(lISboqWpyt<6quj9r9vv z4!hmx@e~~rsK-a)PY0z&x!S+nnzza_dIde^(>60|1GS5?%$M4SEQCw<_H2CNhAi~E zsYe$GZlj%>z&vezrYSv1?enZ2wB9d0{#(18b_1#SLdeF~ecL@{B1y`IjhzP8pqh>? z#^Gi7>Dve{%>Z~Lr&V{mI$K@*i@?q|3S+ZPX19LlT3d2sP04nXZ<-X1?^lVTEuT#6 zq3Teb(eF$7j3-ly&3(gBA6!X?(PZ&IVf1 zaF+K#>xU;J0FoGl@TD#%(|QnNnfYMkhcMub=n_Lj;{Cz3eyJ_Xw{BNGdU{+JAZlQX zax=cH?uqan*W>;p1ZQjfmv>pq^#tEyw3n@B+XBhyYH|5e=dW2`hsTV!wXqwJL_vhJ zqd@6?c>)nwpLy3EeK*m0r?(+R{Y5a2^7=V(tB1<->bgiihOR-mh1`j!Abp)JX2<9? zlw*qMIGC(>et^fYxqD`c$C!aLhbvlcFn^z2u5(&1-+8($2E9}+uUmFrWHNl#_npz# z0_vJ)CWM!PdrdF(c!NmX!*+vnXPlzwBKho3+=$l$;OYjbQSQj)y>QbRXMbR!HMBsB z@8~rLJr{@^*d`s6UesIvqI}c?skqjC*RS}NP}=66aDdG#NW~Dt_X3@gGb(7ex3eQf zWX}yFL9!?eLy)B|52dAZpBYdac*~e$N5VXakzk80(uaW`N&4dSk9I80UfA9(y2p%C zl^d@d4V`Lfh)haH=d+E)_bMUs5>U7Gm&TfP3~lgOsBV|Iy;E(_NhzGwb@IU4y$Ev? zt^X>Vzqt#4`sgX@U6#+j*=IE$IYa6^!PZ{+Phnm^PojMQ84>C)+sjkb)`%ooeF1pZ zq^mY{cgd2zl6#nO<(wfs7eRtF97_98&72%7dg-b{i=OK8pxp=QRU>iJHjbsk5{>Ib zRHbjtXZ3<(lK{4jmbf$S{X~Lh|>5=pmG88%CaNCh!}!nypFAdaaGx zVo(TjzlL$t$?BXV=y|Tyt&qHO_9NW`Hr-;-O%<`NKLjv531BGiq2`t_iCsgvnhVe@ zxT$km4QAR z+U2hjTkz{L5b7w-1l@rYLmME4862SGY$=K?MB^~5v#|fp)|n-2qRamNBGaUSJ>W=8Hx)oRnN=bi47!h%0@BhQTw2+ZNP?DRVm>AX-nj@ILT*(Hg+RNFhm$OK^bJWOM z+~i*yQVadgS7t?uKjeGXnuT0q4rgy`Vh_E#2r>k}O4o>*RjVXRuwh(blX0q@kn^xI z5_Ds>AR0uL>dn)g_9{QMriTb_>*ag`EaFFQIVsOT)e_Pgjf;VDwz!1gi0PoNT+AEP zUelOFFu9+)VrkOqt6lv(@Q~9DxjY}yzU1+Ax$1c+?Ms^x($Y4?0J4e3SR#&s?iM7s z_Pdkl6eC4=PrYt1?R&GOTvWY4cWJW47!avO{%MBetJ<|sJDU{IvViP&D&QC0QM~<< z{>cIHnDzPMNQ@_QW+Nb<$i+9K8%54a)lE?C);KJKGf}2I#`1HBd~!;g)jv)vCodnDN#~+xy=wg__;E1J$kc=wk)EpI1uz?4(GA|BT|e-%0hzU zl%DXi%er4IR(h1y{GNl)tYm|()~mGM-&8{kW^&y3?!Wg>NXHIM&)!kC`ELX9kCO3Z zRQ<^(L>Q%gJnJ#&Y4U5CIhgt4rPj4c&jPn)G94x9?J*r+SdUA$W>L|5MTl5xROU9B zwWp0&-_H{!^x^mi>$LmY@Pq{;y+jW~B;hYiCW4$s0_?=>+((-5N1Mtx~>7 zX{lu|Yf_cylB5RQJMtQlxJUJzh9Fa4fiyO{`umU8-ylDX<{AL2y;9M2WH^UqZjYCP)J2YL0r$KC_H z*2sIZp=HpI0_EOD-&l_CBQdQ7-paZ;=@#hp#+y2z-i*|q@Y*`Rb(%CxNi&t_F1^EG z)%;G7?_Q0YJ6-btD^QjFpvemoRrkDc4e%hGa>R9znL@Cd!XQC2R;w~ZXL&(`XpBKI zqgltgY zOm=%1J+3c*cW2FG#+T9I+HOahevyrqSwxduqbu)*rnIC^c#&T`*^5-qvQY0hxI31| zWHZ?aEVWbbqoKDm-i}#fx=h2YM8B!T{&OiIPgVYrXToFnBr@i_MlO|>=v4##s!Ybh z<2$BAehOmD6(@Q|OWAp}sOKy$XoRuj7QX)591wiLYj`8kglvC7)1nk=!tapH-K(`b zX2@UdTvPiUFbBZ>TuZ)rzk=8TZJ~+wFxe7T(brAu@8~EM8HUQJ(4$EcTPv>xb7Q654P0v_^Uy)$e_Hj5;=cip+zIXez=`{tDyTluZ3I_edqEWs z*Oag$-}&b$OU|7MF>s9xU}t-l9_*l}VZZ6=BIMv*l@$=YYpXZ>_m*I8QK)YIaWGN0 zEfbR>^{L|}Y_sRMkLumN<;NRTjwo$+L@J=Ej^Y?RAIZw`7hCnj#B+d5h{H;hPci7H<_{!u~NLhHC9)S5`~(#WT~j zbtQ7i@_=1@?-fMhn5Rg@nSxywpZx-VH1Bzjmi{##b)Myy4s_AS=*8hw#))iih3u#X z>F%;r5IYkKA6Wt-=khm|=nER|k9b_vaB8yDw%4x_q33PTYG1}7b^DXfL|`7@Sv4Xs zBBlugA`AaF&1Fh+z7jpp^8&p~?7pYj$>S$3oJYvlDlO?9f@@S&Yagz@Y92K7lh-N{ zOzY_Zoko;~%$BTle&}S26;DwY@>2lJamH(*y-0^8>nRxZXXqhkvw6F|dU}jYEEuve za(`SrOs<;v&MO_SF}2#E7Wn5>v0SusawyZ+ZxGu{-In+2n#@nUr`U2}XT9#k>E)Fy zYuZm`+`Wt+CocN)BD|;Ew4rp1!@B6v3)fQN*Pnn~QAQ?aM!Hyo3{^qwdjBgF3I^9F zh=q6+jkq}Zr`NuRfMXqu!?pcWk%KFWyye$VFt=z2o$1^Y`w_i+&5)?vn~rp2hb<*h zXM>HU<$b77009`K9=7L&Jc4-Yb|Go3yGPS7lqb5-B;nwNuS<`y6jli z51U!r!Tz(lVFzUdK>GTS7QVq23BGg@8n5ho(Tw;N64Xx;zxKan;S7;>20_l4VO9Y7 z6gm+xG&KKQL5@}(FVehiA(;K$%akPDAd+~jhs~8N)Qs*TCU=j})s2KvOw{Cu_{`ll zB&jD1eohOM73>);ZxfCbE2l+V_2u_(x6QWsjtfMw6j~Llk>v7se<6GqxQaOB8Z9=; z*6Egme~)c#%)v||S7+Tc&tlm5T#`xnO$ z2Sn>4TrbivT4%T@3(EF&fmev`T-1D?|7vzs^zrm*`84K%za9$>L4PN&(K3)6Ple}C zY8oIIX5^~Z0{4eAxKt^bAAMO7jXg^>Ua`mk03T5H$R2zS>?#0uP^_ja!<`NQw{x{0 zakxNd%n4bVb7R`~SH5fI?Z@^@B%Zawii{s0J`-_x-Pme|gD}Y*si&oElNIb2`4N#6 z-=_)9Rtt&&T&L;Y+J(E*we05}9rqB)?i2O(5bm(K)6HBcPVw~ZktzdfwTEQD*m7FJ zJOsCWGV(8#L{P8>E=h3s%=p)Jx_Q34W^E^!T$VS!%TZX<3@ncyBJrE#!_n#s`PN)3eflH(pY2=Iv`zTN7s7f@noj~h@RzX9{yZ)&MC?# z7qFlop7={>;`x$ad;1_{P-@KxIi9U&EgAQn&}f;|w&ENskx{8(C#PBU=qn?9#%0rs zNOG_~j+y1zqV)m|^>5a<=O}L%c2&gfYxW{kHGMWoLJ*Co#kY1kpT{Gn@Jr-ZR&A%0 zx2)&8X^8#aU8)CJo^BJn zH14E7Luq-)bo_)x9P_6q@e20BUI`Qfor5P^a+D#3ACRmsVq4D9t(|I#gG4?*aXWQ} zk|=|aOZ)=YO;^TT%)+;UwyAyz>MJAAR%>7dx}zVB)k-j=1~Q{1Da~&{F=gR z*En3!`rX>>v?_jQx_|FG30~xN&mN>!=!}&Zuh2JGK6yNCfUFup{71*B9tsFY$+Z)hV5~qXL7>7dB=@U(y_t>e;JwfSQm|c? z52&K)dfzY2%NV$HTKYy!Tq7jDL+c0UlYX>=f#eEww$-5J1m*#kSi#tM; z@MiSW)?HI^sk#TwqwTI~St@Hs3TxO?koF!rCpiniiAY=di(skt{x<6-Uw^HMY;C7w zLC_J!g+_L#J)1qEq-CSqc>22Z8u0A<8O^+AqsQFJFrH~I35b_~ z?+#$>jB&2fgw70WJIyZt1J`o{L8?||=$fO3NQ+#OJ84uLKgDrItpWyc5RBla%&Wx)st~+;p&<w{CUgci1i*=e1aU zuscSVBJnczjDP;B14xdXf6kCk_Eu8f58Lf1%dKnuf z%*j@Y&dk&8UC4?QKo6npp9r4tLSv1GHt94*32bSa$Cw;}PV6%fgq%Lfwo*YgJ?+{Z z0%eOP;&v}GHBHrOihTXRuVH^aI!=1x4@6ZzY$Dp+cJ3$viajE)ZTWsS*JvlbD~m5c zsDgxt_lmi)M&j8=??ODVDZN%as?TEH)KKY{{iE96+~^6t|Gxstr6^zu9vR3+OkJz| zzc+Y`L@kir>%~4uBh7K&V0DXXOr52)IoC2vGjBaDE==_-2=5U2Y0T#VL4)ZL!c5qG zOT{zj*T}c48i<8_gCxu)LNt_8VTh;O+K434R1!s_BngwER=ZFVl@^tx+9XLOlcZ>EbiWT> zbz8OCy6S1-mmxTLMaex{r|M+^fT6ifdB0sFT1{%^DZWD zu*mN_?)YcTqyIe$2G?}PP7}V1Rm&fZ)F_8#%2YkJMdw*lv?F7x$2?WG))kR0TTs^e zxPIX>zQP$kRb%L&+7GS#KRL?I^%xSNe4a-J6K1LWgJz;!qKdeGzHHZT?D)mu)<+>e zO=~3IN#aQI@U!KSrE8g{(bQu@_00#SOIv{HyZ7Q~@CMV3>WLTMI9uiw*r~jkVZ4pe zkI&$U%7>@bcKg?LQtvq8!;9mHZCznv0cpOvf$cek6ePI66|O!;j_9l+5Ld?}F;~qB z{N{j>9HC z84)22`SQ9CgCjwILQypX9)^&hKyrD(%b8&2cQPGNo3W!~><+?gXMuIaR$aC~)wy`% zQDvAaFve$jU%b#~n3g5k@ta#klVm-}V%`xjBOpF-9(A}f|9WOz4uM7~;fCQC62 zCHF2q9sAf4QnOrfMABCueqO_}l85r;y;}}E#t#g4RQt9ct;}BzA)^~bA%2XGmEYUK zs}tx|2BPR62BOwN*YDTz4bometzJ6Rc|7eo_)s}Pn17_&= z>QGZcUc08jm#Td@t;$?q)cLq4gN5}6*H|z&9gJ7Hnm~kIX@eDFb;c9m!WA+Pg?Iwh zP{c(sd_{{4r<=`LOW7|PcqzhW2FxP1j;|3s>%_kQ0IP`Jvsy!p6Lw2h!!5h=gk%?$ z<@L*i$PXA^+A)@Z6bDy zko0@~;bANvu<54X``@duQwR4^vSOI8Jg_=YN>B9bPvCA)C-SL;b9(T!Iwn%}Ki`TA zVW)TU*iU7MF3V2RUi5c8>}67_{Ep%Hb6`mw1JYCNmIeECsA65QN2HnD?1hgmK@*n; z8f6nW;vC_TV}uxqHY&zT7ZqRyl9sng9WRd38H!EQt4VtEx~QsQY;zQQsWj{f5CDn8 zFe2|1cX-uP`k^9I*{#RWzoNk%9@&;lTxF!*ZLloT9=kuvXaqQf>{t%IYm%8Sa{2=I zA+9KLn8hATI^a-Q^PZmFc{U&QIClPO84+AdJm_KM1Svwj^*}2uv&HDEJ1SJ zgE>>GC{y&_^4L!s3i~C&a0_i-^ia0(^`9y>LGgQe}RRm44t6XLx0*sehwUr!;bBzkD;0Sncvn5R1NmeU(LWV*jkt_# z^AgcoNT2EYAR`?S?cOLU4KtUh)oplVTkwdvM~@%#wgvd_`V2CTy$pM!qx;t@e-uY` zvH+bSGV&_f&YV0yv^FbzP0@LfG_{S9;)yMkczcP+^Ij)zz>Z#9GWhk~2?cz`=Fk)D z=HfJXT$pzgAGu);-Ro#QuIY*_@b!Vv2X!5y@sRNlEqbuRAx-h zGxiO;0`{st2z*w2;HS3X_Yzp5mO`JCMI2AbO~jV)d>%+~N0V{Q4iw-7568zZAd`aQu~QAyftXEM?yZ?u@3v zp*eu~-Rw8v$mt>|IdEzt=@xH>w3oButwoH_S?@67r@hkCnl;Mc7WhrO21p|`Bi+w3 zoSQfYH%YzI-FM8;W1L?aI^^6%cH>0QEbadEp2Mx@2!?VX6g#>N@Zf~1A?HGMWQ@US z)nKTmvQ#%NR_GZBBB|-H=X_tBOO;NI`lh31GY1FR-B+&u&y~4~Blv*1rDi~CrFjyv z2DS!5)_nYH9N#}eP5Tl>OV|hGNNJ#~Fm@{WG6D{WXv(Q^!$)g<$ruF-9{GsmM?g>J z4cVdR%!QH3IaqIR4*|}Gw*sn&zfYNPE8og=1-a+2fnn-dFIK)UnSo=cYexR`OE|)v zdzqtn-fDE(?zjmCiYxO_lI-oYiOnpxVH<9{E?q%v}rnEHTT2P`sb~ z^;6!CWMh(G?dqry>Ur4BiZ&+>ZpRT#nXi?bEK=bv(XsU9rn7xqU?PWZnnH|{)GWl+mr72yX)mmdftuSz^O zgsC2aRC|)ts5A)^mEEn+gADa!8CW$G+1r72cs37}^5iFokf&kQK75dri}#hGPkL}z z9QSZ)$^5Rlro3m^x+57I>7LzqYB36fkeK$P>6}x;VT>2=avZmZ|hnG&Pug)gIB#g zdQM1m;Qs_C((z65%(I1`IAcSYna4I0ERU;e+x)D7yr7M3ia+k7I_xxM%&vaiW(>xO z6A8pke#}rSUoBQ0JJI~ivYQDcCz%M#GBhL5vJ$~S&V@LOR5C8kYJP^-hZGxJE&T<_ z05*JOwt*o&y$V_7UxkfQIwnf+)7+QjS7H+bUai6%_K~Vqn1DM&9zohRb_F6`w(Nd1 zMedw*eHfJOTOz4`W3Ud2=_nm-@D8&ZYcMxwu#@V6+xsvRiIkHUXROE(CopGd20{Lb z2=_SP)K0s7*ol{=zappnYUR;fe?YO6LYnkvpL#rM4Q$mK4*bLnYq%>@ztjve;ll#< z^3hKQ6u=+lmGpi9bly+jRu__WW(g-PtfOy?g-mXUR!0D+-EPe;%>0{U$`!BR{?Z*c z=VK@1X7t@QCSWtHS0sAYANjlvlFv*o{K`2T-tuUpZk6&H5>eOXNe6rHwuQw=HbUPX zXM>uDc0lgJ!R2tDW9X z;(ZWz8a87Do9p2_YxlyXKRO;ysbAUbj$^z!$EhX;i~k0iORX)aLGKRk)Z7qweq)!q z5`T4Bem0~h{-QkuL#FG$^X>kU_H8&{?6?`*s~nF9P7&)tE7iX|wm}XS=)G;gqsM?c zvlaj+XX1s7E==PRl!N`8Ywsf0P`61E+8(|qJ!$;R;OKcNE11t;__Foc-Fv$ugNe6u zt*FNWWBJARuLJ?g4S(ck>p5Eq(@(VGPs6_mpr4v(Aw;30Q;nNW(`=;vPirJ~qWf#? zmCXt;-e}HQ(^`;;3v4Y;OBHfWI7Tvdu86qA$+9!@l^v`W-Jpy63I8tU)^i4eEBPt+ zHbEOCb0TCBZiQi%xRVP3citxwB@WZp+!dvZ~>!QU8mDS zPezvt!s=OGs%NM1VdA?*!6fm_B8u2ET{+Rjl=o58ildYYJ?g zMk;Mio#~6%-#LuGtuFfz2_YSjkI2S6pWk95#)62mDN=7d>gaB%>a!*2F-bfSbz8A6E!0y3tAP-zE8tYlUy-o216%HCvZgMJFU9o(Q+{?(Wy@IkX``ugIR+ zenEazD%Z`2PQ#>G4ZKIO8P%CGOQ<=|Nsv@lZfBBZq>O2Ko9$P}2IGjSDNmAkXycs^ z7}w6%a{mQSZq$>O%F&^BlQiNLzH%Qde4o#<)EOnJ`nU*LkP?&tD>-er+5otJ?v@6X zj=ESyEbghTAS>%E&lCP~6<-F>0jPa(XQnY9H}XpkOMd`v`(_gb*v4SB-o-5!V36&A zDXZA|DPVov|F#C<*1DP1X*!hqs2vAOs%8LrR}pX%)1>ZXDe6%PQ+0IxFbU5zb<1Ti z`(qRZ-^io5A>t~{su9BnnjcJft+$LsWgO&!SZ}z<)|bfO%+I$kR^Am}HraVq6S`}x za>Yk%RpTfyW2+agwik`)Mrq$HHC!ER=PgUk`%hRIsRttl6K6NE?wQa0531?sQkfu-luOj{o zZ%9}sdt7XVB^)}mnf?l9l39PD1EU3b3b86C6M)Oc^wW$u>9cP>@%w~PcJvy`LtucQ z`8q_Y2A`7`C~eCJSDd+|8a&~PS`6%Z6wPV)2bh|G?7RQ zGXJQx^|}$sR7Oq}9j{y#zR4TjedHz)AmP4pvWqCdj420Lx|RN7&p5wB8$nUJS#bs< z`_WI;cS!y7Q{&3AiCtohR+iRuMgaOD2qYJT4fegk6Y?|{&T&TMXFu^1D{mOiBBH^Z zaEZ|~YZM!n9P}1@4t|N1F%mczUq641cT#f2Xdy$TUJE?RUx>>4&IPgszMm5P*7fdWqg|cF0_v5Rl zD4xQX>&Zq4@=#Bi(HJa3tZI)0TblE>_Q2eis?>+VPbqIYk5e}7ElgyFsrY|97}Vp!45-WNpax!831s zXx{R~R1WC%0mqS>D@jL$w420-0Y4NF=XJzuF>GX%t{6-f7guh*19{J7DQ0H!KgMG; zo$O%p&Oa9twDuX+$_KW0pxa0rHTJUTJa}-ONjdn;wsqo*+zlY4qo(8VWTwYBU(wFSsKdPjH-Uoa#VYhF&d}zDj=-Lu3zp6qwAhUwhE_IzN{t zk5bT+^y*+F7O{I(>1tMd#(lFIm#L`yn!0AntVq;m0B$oa}C|9H5rj7Xe1*}7m6}S7+ zA}g$0zz59lh#6r0gX~cs7KW;T+A&50dPk?j8;*R!4*n zmHRwWuOT=7rFV07x8xNTSrI$}tq9H@kEMtG56j#)j7<+O_GRq$B5pywzpxpsVd|3V zd*6fiUKvz^mNArIOKRFB#eJDiX~g{r)+yEPU+hi*rc0{&Rw)hcjvS1*{~C66uuUD5 zh`Q!HT_TJ>eIJIPMVzND-ynLIF zL*bVY>?}B1X0VEn{faNXKvph4uaRjH?XtE!W6X?p?{(lk_tfNLkBQ4Q$Qc56cOt_K zS_>B1ODvN;uTisS!s^0XrfVIwUp?fnlNdCcHz2LV41CFYKb4B^XjaEUUVv0AD> zgj|YQia&#nWo$s7KeVGsUYL1p@M~7Rh12$=v{&x5#srfO*U)Q5{li#D`ex}49dS!L zS9Rsq7)UyYMWSE7?aEZ$x{8|hhugHlhmZ{A9Ux;&Bl$vm6S0;3Mz@W!7M@~SOf>-C zjT7+HgY(|A>Q{`_Kun*s(1oOjX#0!1fUPA4Pr@I@+KRvLMO;SEQOV9sk=DBCG+$Ea zI9h-Lkisi*N6vG^(^_o52gu8$4r<0oP7V!+@1b8ouaO@~as=-0eY2IvLX_*@p!{hK z3!i%sN~;%lg|YvQLN%~YCmr(P%N_YBcjB+Pz?Cz2r+E1!n|L*n>Peu@RPKZCpTn}G zLFj^goTn3or_}IY(wVRDBt0c}vHw!O`bBWFg*tO20y!5S?dcL}JMUMc&VGl%8yLBC zr=!ogsZi4#BMi0^&(Twoc2Mb8yPm28AOdsqVuTBlJY4=J1$P3EYr>|JH%;-manH#x z#%C@(rH8cHv*SGHDH*S7-=Mj3W=pNkkk&gDT-7clP|TaAoGr;UTzV~VFVQ@LgTCF< zuDs9cO98U_IevWCN=Yrq33f1rKQdV9IGDhl;KmIq3SOHw0+`rP%}%)Y>5kAj=d%h= z3wDlKo@MnnL@_hU%ov$D6V}ead_Yk17J2YL;MTt?3sE)x;vB@sPa}FcnfS2zYm1oG zEr6NM@jU`XMq{KfVpy>mPfTJ(s+`6ucTC3C$|J!1Aq-V%ufEhMH3_(YjzYHK4q<;2 z+-1pesMa&IuM&SYnffQv{DS8G#J!Q2jqHkOBo#pww|Z)1$s)o4*Jg13{cDpa!mB)t z%W!4-RD&SrYL(+=vReeJCf4&1mM^QYYYTvPKa*w%BE%)A3FZO5QsTl9$jD7Z9)51C z%MR4(QS7_VOnZr!k`(fZOzEfGG0>Fe+43dE^f@c)qXIva`eN)_0YBWw?93AjcvZiiBRXIk z%6?}fKj>pwh=zKE!i2M>L5B>i&edFzT!0o>t5^>W{2DI#T*PuPg<#=d)b ze2{gzohAuJe<;E`Ssk4o79wsc& z$+Jr(@p<$$waOlW+nn=V9{WRuX1ti?V8!|F#NjGkK?AX`W|{PFy7Wpx`)|+l4P|}A zd%TUesGg9Qo3`A%g5AcbZ6!>7W$N-R6N8$i_+a%?QQu?WZr@MVOU7&+E|`#b=0O>g zC)e8X5&l=<7Cc%sF;@L(D{O^Z8|k8kt|QGo72q@Wo$qg_z%Nr=-_sO3tXz#=qjJhd zMT?fSNx2cbRU<~zVFyN7`e35 z32ZivvjTgoQ&y4CiRfvRo(XxYEU5lq4&h0qWdQZN+_OrNDPOm<_ZMS(gS)J&^&l5m zaQ2TV_N)w*7<5d8>y76R{KT#u)aw0wZg75D9>@11S6oF)DU$;xC1!PXKDG;5kKsFD!EqZ_f|!Q1AAxr!?Q&f! z&&HE6b}3W*(&c@Uy!A`2yT24 zH7$4AZY#B}m85eEK9N~#fU$YYo!aV)JbrJy=#9{FB%&$UV>8|orF@pxLbmXX8LRw7 z=|jJ7BIy7j*-lm8$c7)Kn>}L`#XrkN`&p)AQ)}cwS}B5Y{(A04kV0_3ih9q5?^ODe zF49wRSSV-kjxh&l2Anoj(AP2w=WT%e|c8mlq_!N52*gRLsTrUx!uL*+j7InFMbj% za|eJMpP1s4+n0@Y+RJQ0vCm1f^O6xTC2rfrw=`#gi|Q=Z$nOiMX1*G^t_?nV!I$u` z2qz{)|8e{#>0AI@+N^1-1NJW1_m*T1WL(`0d&OuX&=;2!XG*l?+49dxKFZcX#UjSe zwlw*-X@aT7m%nX}eTj7ieIqyw-5!D+!DAp$OK(~UEfuM*!^$18oUbVZv(gH1<7eH0 zfZ4FGQYFIauT=iE$H({20bud@D~H1I$)3K*f5#X1&~|P0=Bi&bVsn>oU5R@HNw&R_IZ zJ!%X>;@*5XHs9TqR=5?)Z!A27j+`ol#!41;Y&dT(YwWK}6#eZ%u=NmAvjS`Bj#^Pc zV@y7K!5e2_do^ZtnsmmnEU568>R1UM<7(QA3t&pb+kVPLVO+wl zu6ja-{{SH)fJI5x{YVksEk|^)E{PX0qvDFOiD*1K*;cv5p18#C^mz`<1l4r@M?jx+ zDv?#ONzR^kDltM>&xh?{!wXIzEgo@cq(_@c&5^Hq{!ueFqnbyC7Qd#&D7sGeYp#NC zJ<;@ob$WfwHN($-`8vwJD`0@*TR|S5c6CzlpYp4&($$t-{X-U5kJWEd3T5Y=TWh^( z_w_bZ*ed96C*|aQ28-sO^Zha^->Q0l?lc8GaujAKd}4r8rDmX)GZM>4;K?f>ca6(s zEn($SKZsv)b6)uf2%kpoR{bi zz20Mz8P`nN{(8Ayq*sPY&)v6mI0*0L|1Z8GiIg8=9E<%i@-rOuGNuq3qW@ss+C4g) z5v3cdNSDKJ4#)QZJ?I$oAHbVD0d6U{?!v-J7ShEWO5|8Kr(>)Ss55FOU^@@;3`-;) zP`A$XE&j|`j+wCfucDkrRDf5Wjo#&zWrf^>7GGA>|M1b1u1Wk_ol`>^^Bf!gZ!^hM zl>IXmT{L;YLtK4U5 zaFlrtvYP(3k2cnyYb!@@Bjd#3)U?JzACOd|))87Zpbz3RWb)N;Cs3z5U@N< zltXIWE3oD6kjrqEa5X93xxNRF?DJS|AA&4QZ=;ScoSw#h36^+1O!$r_Jz| z(*F(O!Zd~Df!T99t+3AKG!mG!OH~(b&y+bl@R_e35S*DTEWE9PK>3i7^z3m~+G3R# zrByI(GF2B{fZ0g9`?iWgFG=?=jE7 z?4%BV5#1HVoRLxNv3|{iUn#Pc3tzpCFl;*_!tT-y&`@N{2E#pmA*QfqB{a!cB+JCd zLztDyyZd9@RdsK~W3k3^OXOcwMBIpAJ%Y?Bj3&RBOk4kI4Mz_Zhum6(x2 z`C<1|Sqq~!i?IK7>U{}cmu)I3=~Fznp!*qXW0Id>7dUuUMFxq??A`gu-mNJ0T6&$l z^v1ARr<4`E+MrN%bKdEFHQ zvQrI?Z)?Nj74QDchL>uK&7>LBH^bO2EuE#0!->`TmM0{K-9r;t_P>8UgZ7WLz)B0R z$?7GCbvA7ze~Pa*$?4S6>5g>yoitl=4nEz&_J?1tkTfIFgY+*>MnN9U0TH$%G|MX_G6Qq5+3^|1b)e`sc-u9{1r*7Xx2x*JwFH}SsqfAjtI z{TpjNw`q$i{|v0QN9#ox8{RRMZD$?cSA30>1I47SWFh0;o}sUs%I0Z@&;J>qyTNv+ ziw=Bc+AD@?SXCtVyog%U?>6#-xlAv&5veQCip{HICDjZ5b?`)>+~(r#LgqCnqjfA1 zq_@lj)vxp?+>4oUKDU@;Jf@zhEkbxLEN5vsTo532$xE*{$Vn->M!Lf?R%1Vg*VW@H+F|>8KkjFIZ3{t)cmq5?gOL~j5fbmq}-|LlM!?bX& zR%mUqVPe_oO@?IY0Z~LaDVO!;U<90Vii!?jXG*)66`^}}eB6Bp+}mV8ZT0>iC^z#rFz4U$|>#DsAK|@;M01|EkTU@WOfJ zI$l@})Je>rS9(y{p|9qV$RIb_#)5YG?|UKQQ*JEmRpu9g@edl|<#zfN46C2e9l^pH zAO&r0-6i}JEI9Rrr(heB)kNOQ0GDlW^uf9ct#4X|8zm4gE6s)LwqhM+k&CQH>4BiB z+wc`K2K{v{b{S~;-r+dwKD&CD>#A}e?S2VgdH9W|AW`kEGV26ZVcl5GB1|f{pl+@2 z?}vK7g!(d)3;35wi=~{N^f$B?Wf0GpP}BEOb;OTx6GBnAOw@xuWcFtYTd6#S)tq@& zmZiGV{8tovr^S-+{*VkTJ*s*s#H136)170?#O`gk=JwOkL%Iv#8L}el|Id=iB2{f zkM=-fY3C9tw)T>fO>kG(=U4DIkR2$*IGsBS${TNFi zi~L*NPBB-k6}XcrleDhGK(C8iCpW`=E|A?Ow~-ijqHiK;Tbw*bay-=S)IgsqrvjUK zPiS;@{oyrDQ=BvvB*>#^Ie9d7=YxSo{jB?MbDPtQWqGY!&dvl!PqlkUYNccc1Y5}S zituXJcpqZc(%+0T=!D-%+I(ukN{4c~8cB z!6vWc$3x(GgSi1Z^AE+Y>s`dm!u&|}v^`qeE7ux4ZaL^UOEW06kw2~p_b=vbENV?e z*0~p|+i;y@iCT8xjePi5Ro|=mWW=^eyzs{|^zc1##TaC`H>$0QxaKhy-q|g6(_Fv) zMBr@N!CHXKjG`PzBG!qKkss&iiJcpJK*ePuUF6y^J!BFo=II|-x8>Rrx?j%J2#T};#3}zdqoUCBW--dOCNwhN6yy)d| z^WHD9{`6ytzflvhp=MB)yjEc(2bk#6>`I8zh&3^aTz5^uOxOiw4D!>vdhr^7(nk{D z^Luauj%ythm-b?p7aoAhr>o!#A2G~ z)MNC^#EJCG)xEGfzgg5rrF1;nxFHBy_@$!5=R8)=H5Vkr_C4i4>8U2fEz<0!oABD{ z6@x(VG;ynw?TEDan~x6OlQjN8ke;Xe7fa0xY`N&n;f_8^$LVozSL7|BGXqqPKvb()`Zw>6<~$w)hz zBM?nT2`s}6DjWNnzaiLH7{`4^2yfDXpQ7vJ=g0?)MsO9x&Y1UhyTJ~|?!^A-v(u;= zB6+z>#9n^j=0n?{;!+#@m~JpDI94&b1#yY!Yz6z0YAgK~!q6OB{~K?m&K~H0YD zap$fz0bJ##3~re?-1q?_3y)fPb*~Mmv;XHajc;6yoRq;2x@5#V-R37I47dQJiHwg7 zPH{SRnN5`Nz{HN#l(w9`sN%Kc0c%cff0{?RL1(vD8}VZl>uNS!nmjjzOt>}wSQ-3d-*J91Fjyrg*_Yz*VMI+0&ZD886muOt z|L2LcyL$7gM&|@a0dK-u1h%Kc2O!N*nPdk><3EOc)K2q#X4Q(Yz&kaRWsriW$CyAK z-HtMqw%#k)uBjt1L@aeGcGSd@KW!m@UMAn$gMCpZAU!oi=*U-$M|NpNUX-y6F%dW( z)_Pt{V#!GUwQ?o5_mA9n&HNS&O<@n+eS>ncb6q0&CNX{{ zcjND00o;@oM}i{%IjcD#jd7eIV1W1Hyussjqb0mU8nY40(4qxN1iM{KR+ zbV%hlZ1uEj@T5rn`v%l)u{TfDo8Gh4#GzEoO+!EgriSM2-C#Ui&uG~J^jt_0`-93mqbpXDcL*bpLMWl~F ziQFY$usax^&qBnDkok->EFxZsK4}1$9vZxewUX@r$+`GcUiIt*S5^KuWSDs}mi-61 zyHr+6_BU!m=7^1{W0Ec1Qq1)>Imwcva7VaL|86?~7s>K2(65<(BxeG5XPf({Ifj<& znxf4eBxNsnTQ#puw!+^?Uohk&JYcQHNL(DufO*F8j~v)}<^|MBUjMS@nk})t-q^4V;I6b7+2)Uy96t491Y-alKOb;| zogC|VD~6xjt9%(;xqOOCn(n$2pgc=;`F7kuS)o-kJ=$#mvJUx#2+7B>)(X6_1JwfY zPI8p6vmtDm`rW+8OBmf+z2_6(o)!4drMT|0_Z**U_#yaSpTBbpMc$WK_GsV9EK%~c zQz1eGJL$zZ65@lY@1Zz0y6Qib>O`MgM0zKiLgFdi;xfpIqFP5ZKywyc9?kMoD}Bga$|hk3^& zGO7(7*PVfpj7RV2Kt%3=xE<>etm2aUXySRNS;_7;n*FI7ahDP5Sh6KuG4zcbR4-9e z_XF_h2zCi+HY9$kaNvLm*RNF^E;^e@DcU)?-=KU@P2!{2kf`!-bPA_bG5~Z?Q0r6! zz#N{qw7h}JHX3T()W7*fS)4nas90T1a>--WrzFOrAM?qVSV&Entt2qnb1~t~x34Lf zMdQgb-5abbq}c}wU%yB37)ruigd)xverEXC^fg(TqL1!6?~C_aruZ>GHBp#>8MekQ#04Eo;?r*h__c^KgC}>>*5cN zWi0xisT}A+K>R~PUC=4;{BpP3d=+_D2iH#p2c{nEF1l0s0R`wA5`2dhs02nbd=o^b zBtUR^u1ybfT|PP6MTa@3WItw|CvYO|gbFe2e$&d2=!5fiVqNm_Rb&`!Qy{NHQ zr=}7a%v8`Y0OgC5BKvdbDe^sEv30S3Nr6nGY3~*^e!e-pN{n-_rl5^lN*)9a&#_0F zWZ9-2WY}FTn&WOywYZf<<`iu{wUzXEv~wc-|Lj-P9Y& zL&?u&lk4Ud3M^NQNPo)fRC!7D5^S=g8vgDc{Q1Obbch|3|4OEO8X)$3PoJN`9YSMF z;DvLBvo_zTH>Mzp%sG1vy@;a7x=C#DT%b8GC#`?=9JEjdk5yBZCPnOtv>OcrLgi^0 zOsL+h^ls$Ts@;VZyF<|K*IUZ+YomV@T7|!*HqtsqI@=3|hWzZ1)y`3CM{cGI_7V?O zkvCv{i7S~k!`^>Junm65?~R7Y()IKzh(P%Hz=;r*`8KHI`uk^E!mEw+yis~$VZCyT z6d7@lv#2|RlTpNOM4QXe50|VY5e|$v{t+kN9?O#MHfBuY5GGlgQRmiiGy}R-VtcQEZ#kPpxt*)i@xZDo={1QIX;D z4?~Bq`Vtn^*$pTTHRFbm8z_PNVbNi2`D3n^P(AhSo7`qGt$Z_sTiz|@)yJs6HcCFz zx6fk0Gw-!t=GBW_4bmqE0#M06pij4E7j6}HovbAON5G(&6vk@=Ru`kPnKpxay0LiT zFV*f3nBg>BDnR~ge~`jPQe!WR*8?77)=uybpDU^Y2LJ2U+Be&nj_r%VkL9fV$UlGM z`z^vg-nvu%EY;v`<|us&^X@Pxsgb+%Aw=J{poqgt$x)ecL$g$F0BxZ7Evh4bqcUxM zF8)}xR0>I|Q-IHz@{{f_Eia?i*7L8`-y6Mq8CA2>g|y8R@D=sjc8*HyPGWvb{YYoMu@ISlmp@p)s|FqcP|p}6e;8f>X>AGMYbFb43I4&T{X zKm|VRGwUVCa42JyLosqh2Q4mmBgm_!Jds#~R|cAh!*VD&fv+(IY>vTO0@6LjJSeQ3 z4y#9>>&M=k*QepI@c=tr<^U%a$fWrqg7Kw69JppYIvf??@I6sru|Fk|*;FO1{;=~a z%hXnJ{%2U?i*(FhsM_LyKaWGi=;Y98@9PX^nzb1c_L1C!U!{3fgc;|Q0WXo*ot9L~ zc=`1>qB)gy)%9T*vkA%M37!3$^w3jldHzL>GIZpDza^}=$_rN|*6`w63~?llD+uVN z%EAl29Z=54CNg9wgpS!xh@gEPC8qn5SETQF-Yp$~3mKLVSj5sgwWFcN_NanSh{4|p zvQmp)2UJSdb(yr(pDz(3qfi$$n3wezeqM0l2OYa)t@u_89G}`B;v!{7xhP1F^+x1v z#`Jv}b$IqVwD{}`sCE>pa^{Hw&pC`I97(zKHUm8^GKm3~#V-s8s~Yee`9+A86*;AO z5l8AOyMV94AJ9T4idH3RRA<2L_;}?LN2dG%4If`caQVghL^2)72tz)UUoZ5e@(-!*mkCmazpBL2k%s741Hy zlrswM2Q04*?i!4JgXM)zx|&DwmCIcpPmf(u|HG8%W8btw8lf2Z&SNKP@vNKX;&*=J zuw3~bK5`M!W?5}}0I^N}UoF!=Z}6H~ML+oHFHrD7U~xjFtQ?S!1o(um9mMTPWWucn zz{;1H3!THbs`N+@yLJ|fX@Tz(+i?U>0#cOynfRpYd%QY$m2~Q
  2. WKsIfFK3JYas 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%0A6*U-Dvn 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

    a}e~U)FIInZtBu} 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

    ~@B7 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%0D64oxwcFcV}b>_0uf|UeH`sXR?wJPNcJJ z_lpS#adnQXy4$rP?Dvov=)BT@cLKH)HGu7oh*TXX&$~_N>E!7usr$$Hr$v(*-`85S zMxKLigYwlCm$$dNk7p`_WqjhbkYm=JA}!=xJA!1>yVPR|48dN+x5e& zWRm(aad#bWEF}b+)@axlu@ifpYI*A%^y{P(ED@S8e98U_lcbO`y1Vn}L$nq3!36dr zav35+&SV@u*^Uyd7P@KE!J~l_Hloyt{EbZ^D)5|YDJNJs-bFuAxULA9xmatHuIZI> zpJQx<;fOf^F>|a|UKwVY8kW&{gnvf1Pht-6%il;scbJwpGDB)&p@5C2zg#*(CbCeG0WL?ENagT3g9)RwP<5!!_= z62?CKJE%?K)IONi<$j*`vX7`JynB*R{o>3i**kkF!kweGtl+I}r=5QMo4!2QKJItG z%*7t+q^d!kyet-Nx|^<|JVkD~{f3_Jk2|mWIsMA2KV}ochxaPHAxacD!`Q|wY14)i zY%s1Afjmmn+X$^!Y>uT3iJBz$?#g#bDQPx|lvQ_FM5TjF)wEY|f=7DoJaGzsOWw2t z;R8e?+0-U&HJfmrzeJ?l#M=bTUyFK(nGqXlN(9}kX4|1x3gu+YzKkgKOFBa8)5AB# z3*?i;Z;*7aS1FqAFhVl{FPbnL8Z*J$9@z^MM&O%>_@OF&TQoR@lo-t|9Ez=vrT5$s@!pwMhQ z-%~!ZUb!}ORi?$Tm&GzbPgQ+l_@PvBe6cW9`L=XIoF{mJwpV}oz3Yp|eJwdO2g9ok z6+Ua5I7kKCf?Oj(qihMvQkRs7# z#Q+V!7ndHWoqE~B-3=U3Vo1g|_PFE@<@Y7_gV8;xLCF6H_WiAM7F$yvg5~R&&yqF~ z$HlI#)J>_&EG<4?pAVj~SD@Tc!>?zo_C4d|-SxPrR{EOl%^IbQ{e>TV%xu zQn}8{yfP}Y#b164F7O-YPy_s8Q5@x~;DghR3ZF5}eKzZ$0hb|`f6%T2x~M;@3314m z)DESOEGAJyT@S=j-)g#k&8c;w?(Eb(m|;WtDgV-yd4qSP@z8s|18IvZ@H`zi$*=-{ zAJEmlRzm271dFlihpOs#`cSl6psO}P-v~a@|3-eK$4#R`GUtNJOv*ZAz-Sk3+0b@9 zXj`v#MDiEhHdqn@44SI1w?#@SGU#QJl-lQuUoFZ{$~-C zJvi^4`gY*3vCAl16cr!AE>T_{LnCCXIcpuRvs#mWBg@B93^cjZjEln6nSoY)mam`y zH8yE~Z1Bn@=kseh^kZ&u4H&7XOv^f4*)x{naNwEDwi4Wgd2$sS0Om10E)s67R>TEe zkrsSan_fhQ+@-E)v;IDtd4S>dR4lIyZz~hne-Z=>J(6Ur+<>BV#x>PzsJ(?j9(Z9f zQhB;(r125{Y9LT`18^Sj89qFa!Mkes+9xvxKJ;($#PVJ!_p`RlighOA`;;^bgNOb& z^H5D!Ssg5bekUu*$t6weyOSEcMWcS7n>N;uE|ue_C6CyaM1RQchDrQfyTgo`qvi6G>$YcTd-gIrD!mVEup`m*MnEj)Uruq*eJYh z80EVwP~QqXWLm2@WRFqj<0?Tn*!*#rfLD3{K#jL8ThU%}g6=Iy9W@mv-{ZET2;%{5 zHr?uOANnPg!9@7gYa(@P?nA1jigOyQknp-JzQfzBL5I+v_A@u%{niFcUTbZ@Cn^`b zZ?Pd5jNTFhdagQljmCM*O&&4VZEmYJUJVejjt`V)b9IHcK0iN8Lxp%7KnbOyKHko^ z1Jk_R{zL2IEHY3Y?>xG2`+~He+agK0eYYp&zAop2GOUZ0R!(;Q$bGD=g9Ey7CMAnt zGBYd9;wcu=G;41AWC)o#(V{CthCeFeb*fGpgPGVvXnEyN+*djGP#)vXXz)it>M5+( zrv$(8lE=#h*fIOr+J>>+E&?w?9KTW^e+|bs95&q&jWST4PGVcOn`c$V-en)2-{6A_ z_)9kpI4^Z~j=UScoJC{KO=kalb63~oOf9s9hx*Q^ zC!yXilk84g&e-9ipnh2ouAgGf76+OL*FDPE#Q3V%Jzl?R{CExR7MI6V>>ipYTx5!! z8}2~;P0e%Bs!i3e!H53PS?VVBmUqq@sTUNb7dU5hG`YQ@MaF})rLQesGfQ&*#bG}S z;`j5q+bB1XDK)gxOWN1EDqIAT49HQ6p!ZLDoP#uEp<5ooy~;FpF3K%}h?8qxBHzCJ z$QoDQmD@9EJ%mG5zo?VKb1MCyx#zUU5#I=PyC2KRUV10H2rUt{)LWhCnoDPH&xgv=l3gFeAINO!VpRn1lFUQiHd%O z8bm*@q1|2@#;(c!2ru}MCx6nu6>L=VBfWUc67YQqfWgf9&iF~YP52qSiL?nfpk6%V z{x4#)$P?GETkTXLD5>U)sCF^VWZx^0ob&Q^T<%pB)m=-uJnWYGHXH#`L8&F$s{A+bpQ`MeIcO5emfm>V;>q=^ET~8bQ)5YgLp_mkt)N zx!p%IekB{B3%X!|VkcGDrd$J46!2a{l!H-7he+)wu5LKHGZiD!;a5+w`gka9UmdOV zUGJDpEbU?BLod;N@sGFk*^Eo+xTpLF8Y6ewj1@neOx(CaLG`_;!)h1BJc0h4+HXSk##qlEg*^a-**bGFL7AaJ+#OSG`5DT2+l zLGh{kvph!3Pu^aGousT&|J2NuN@uc_C~O$>0HgEkyXhhkB(;H({Jfd+>#; zC+iSZL^G)?u2r#B6))=(^TOvJZ#BmNB zAU?>fYSY)~IKQdNU?-w=wUR0CUN!ht(3r@p{gv{gE&s08mW2q-(ZgKUL61o>@E__X ztOkrQPvOWds|;5O#|7?v#Npu)Z^~~gh;EH?4jlJGnM&v;;c*!oYZO`44}?V6*bztVm$tU`mu#q*|~DV`j|iBvU@yJ?kiqu72D1ZA|Rd< z>8uaS;5$hzGp@#3y-DmY(j8uji?Bpam=wz%iqa~Q;g=M0-tdJY$;nRC=~ed6u|B4n zJ68*BIal1+ID*)qEOk7oOCcO(wUs=(OL^6qAdJJ`CqHTFmZO$4Eh@Hiok=<)x)h}Q z9_^_+HrVNqZco%zjd?tNCm+!fuot}Srd42ig zZ2VIhR3*i{Nx*JVo`F{$IU7lV+UfmxJz#eRL!7R$WZVnVo~=7`O1-nt`ez)z5=!*H zv{vH1MC7Z_i)k@W8EsqJr2Ut>M*45XDPH|2K3{nZo=)hi)?XPwW{04s5GKN%l$+20 zB*83KI;P*FT4Olfx=z`)XNK(NHBXGPTPLM}hbC!t#YWoj49ylmwFz-vvZ6&^6qv~( z3RgD}7Cu!ZoqV7B8W@*mMT^i$#z2{m5-BbDr9Cc*UM$$DXEzoIGaZv#Lbff_q5 zso68mgXFu7hGVpKySEeeqIuhmIAjVtgp45^KPwmLDvXX%e*459A#S!@BV@QC3?v45 zz+XVZa%Ek-)f2kXwecOnn$lM=KO4BfW_&=rows@)er*-M5b;DsO~G8$8b%PkSs{zw z(NS-+H2&lHKDWFyrt-l$QO~K2HbHke@+ReaO~59Bnf&%C&COxL_;$RseN#(r!PaCp zrWqQ0Pe>$PI4%8iqcHHSAbF2ArysJABjEf0EDsi;R}PoY#_jA8NguOIDGNJKVTTto zNEq|+FU_}pn$D1A+u7%Dgj7&FW-i_C8W_9m^)C(|ETt{b6j`wC1RD^~b;UGqMUXIO zF=AO7CxjHI1OoDM4;l;jo9pC04>7-1jT8N7Go2;m^wEMtx3V(=J<07VGeSdv^h3r< zosQDd->AO4+aCn4F5iRvr-oM|3l6&E*@m752K`lsj(KQ;UG>E-g@k5V-Plt>u&dWV z`St14V{#ilm^7qpmwRihiZs;6WBm7uq_+=mXgk0xXbN0t!WT~?rDBbN3a#Cur8+-f$4L5~GtAEc=7MF5@kew1R!~9d}B0p%S6q6`sIp zW6@=w_5}911em^_gAbym!H{cea}GTv47&+%4jo6X6W&@Y+;?6)`^E){C)Ta-F0oWn zoPhO=R1CiT90&RENuNrW#nK18&BeDV89af(Z3iGluAcrwUosC``-$G1ytSUrTECqy zh~bMztlrX7NP|DgN%mJ|+-6l58#!)IL$x5sy|ugRwjl++|7Eil=O+L~yL3cT`FXL` zY`*G!IzmX-kSCcYnMkLh`QUYC{aa(w(J`(4H~LWFQY`nCF(6)g8BbS_SdT~H8h})CA;&nPu#RA$&rdpe zF-dvI3-7uI{VwP8QI;R9Mj^aNV;meH*oll+<}Muj<2SHjFP_YH88cm8MNb~8mN-?@ zPDu^+;$0Uk5M<7xKK~CDHTmjsO0|=dfkvM7lq5R7PI~})1{*dq|5}M-k|A*aY{Vsf zo2RC`q3QQybVR1w4@=xt>3LvrfpkH{5!B=KpRCZ^f1HDX-7?w zQ<~X!d>@A;)JFwa+d?({BcoC=TS1CP4zU92JF9Edy-fofX5%i`J2m(;W&<0x?#&2T zD|X%Rku38U#pSJ`Hh-{M0ywS{&n~jW7Xw%kMg=P$1*uiUWvr*+nc0#~=An8IR$Nso z#Xw460H;`ICzYTNd+9muIakV`(JAS>9K`!pWQUHh*27wJ;34K4Rs+hr<@4UF`XGrw zQgc{vSX!MGuq@ zhuc3=Upld_8rZDCGk0#u#vA=e;CVi7dR4OuH7Fu1Rad30# ztM|f3uiTqVOZ^j}la?7r3k_=c;Q;Xxy7+|2BVb8ofWM^t=Ali{uLUS8yeHn46q$w+ zKz~|wg_HD+fl)(*9rf_0;O9w`Wpw9fNMp&p()FV}UUF41W?wn>!g2;TxyplGZAQ5D zef?SP=1(L!S`Pmn+;+BddD%5ip`CoUj2D=MneXnaC0sw)(Pli7^=!gzB&h8fr(tu}S3(t*Ov#uC{jHY2@ zSxoa?a5KEcDW`QcD}amcJ-MGpcbD}=S)PNejLU|rhXV=G-wIZ^YE`%Y14_&chab^8@k5nkVm?QukH?i=5uD&yNhI0XIl<5!JVLw#esL zTwP=~RqH6)mtj)&3_S}$Gz*{UjCMpR$(S<601@3<2`$Xcm2@v^<(TY{A-?ZOm^Rdy zH`XlyyB|=7{SXtg9ZoS_Kk$y z@t;uT*>{@|klA}>qr9luW4e(8yFjjy>d0L>F2mrw9-_1kG0ckVuU#~WddlrSP<_@S z;uJeW!hN=Wt>6q?DAfT^Rj8Xtg zt2BiuOGW8AazNo>173OgKzGYxMnlwv3ELB@Q|rJzlR1gv+lj~nGc%K*@AF(SXpEi} zfxHiyKc2vfxP`xbY)RV$pDY#@Ap`P&N97WeSNsnK)Zoz%tOWBHoeLYtS4YjpGbfB3 z)e+Uen2{=`!^&FVoGx^PUz_;j6~g}53grotCFtpWGpv0~J>|#ev)Li@d=Eko$j?!q z-AQLL_*PEg!+xfcQm@{>d=CC)-szu_gw=LeuyKikecyQD{Sis(;sp8$f9_eJfyKTt z7T`d48*!_JG#fP^B(-1XN<#uqS5ez7`@NDVwwbiM%1oo2upbFfFTO-xG^!6Org2g# zVJmLsn*+Q{FZ%Yr+;6E_f9Ri9$j_tB=m;GrndyU3U;wktJXUuHzV1@3xSxFR!|kV7-)uJ^-N*NzPZm-n>!z`51ZQ}h z@IQe$YP$)f;0pWVVv$?upYUAMdNSv--Nbg@13~DW&&W!hOHmdrffz%YAj?zS8!0K_ zyzoMAn3RW*{?aTc@vB=e8*r~rZ{uCv{a<{Eby-i35o2>%>OZQ=+?!lAv%!6>u;cPY zVIIDtk6GYWOrqWAARXJq)4PS~cw-e|(quQgtj$VO1QW?bL!`k@+ zTe>3xWby=Mqg3xG>twm z1#jHGvwm`GyE1mV^dJSU&6BlVyl?T-*ig$__dN*D)_f*?Uo*(xuTc@?^HD=yr%>*>{Inw4tcvgo%uLgWEMM z0I7@bhiY7}p=&*|q3#|1#BGCobZ0JBI+l;w@CWc>kM_tjH<0dQKabZ}0U0{t(j2kzKqaIqK;uB`>0_ITvd;RLe(>egOVvDJ8ZkVqZtB_~xOXbaXf3t@c@h z6KFqV8%bG~Nb{}2vy!Wd@Z~bAwGwU9Cj(8K#rq=lwk~H&Ws>ak5nv#LLscd{bYUze z7J!M=yfsZuFUmer;v=9wc+$k<(3d5#?+IUtxMA3|oj3Mq^~0n+7UBLLLpc|eUiS&X zewHn|niB{nwxF18FV)&qMa&$Ic;^w$+S8~FqU<<-Uu%5-EMUeua~7m!ljD?Wr)Vp! z?oS&Y;_D^{DNjBlPkdoSSJp#w;jl_T-Z3?$cbbFD@Y^l3$-tuhj z@)XM6qS;X64^(&R?Pi7<(?D~1(Irb)RV7r9Ne?4B!zg z+XGHpN|M(8hFpD^?{;5ScTE$Za(h)m}Xy3bqA zD0Jso$bE0YJzovakg;o&ce~|W*oG>=!6v`&kV9GP9+5dFJFBO}k^J(Ap37{;skjww zfXRf(+sdWrtQy(zs7J~HyGaJz4^YRKT4mY}hXzC`DkJrxaqsGi-9k@MO$T-#&7er= z{gkT$w`ajIpH3;xKdp8$;QF2q`}LW(KQTCFdUe<_9X`h<9RGgq#POPJ!6YMo3mM=r8N@cO53Hf{0;CoO@3e{aKxg&?*n91 zKVjiKlw)WUR`&@b_gBcBD*J_2i_3ESIUuKVbm5p_UJCdvTtl4NBg{I6)5 zC77xNl#IC}Ksvsflx#M8H+G47Eo#Rm^sy*pN$$*U+HmJmYEMQ5Tq2=6aY%W-Mr@gU zmgVtV_x~^Vu=P}Z)Gq+$L1JC;1Ad2jc}Qe<{$={d0pj1rH4=kqn)6lEkkzEIH8#16 zHMnu|atP@I;bH%o8gdOvcxZAlVTa2P-rj$V?k@DsUXRsNJ{MN07v`qc%NxB}Oq0_n z5Ca?Q<3FQ58UqC$p9m$o^RSPq44Wl&>Kl33+)o-=(v44C(1NQ~b=aT31aJtGLj}#9Wq<4LYlsTFpKiV|IUp2ukkcE=sx~)6^>Jtvud`OnmmMEky&Kl)ey`6*H)F%bwZn zIm`1ybI$B^=@Xoc#f)AA_3EHma;Y9uTz2t%Se-j#UI*%WA@JYfH!kn@X>&eI#mqu$ zhJ0_rV{0MHW!@)FP;Dyk=W+^V)dECLM>O>m98z`8k$If;IAEzxk$sPzt?C+kN?E>roy@V1YMGT93%tzwq;=f< z6BL>J%0`B~6;p2ze!0&)JHJ}k^1++xY~6(O<4rx0sJ`>A6d8-nlcdCT>XRS#P^nfSEAI`DJ~uEKh}5X77Lj?5o+ZAzi6QeNsUPwy9}z&QZwK zHeej(q5}o#swo*@Eg^oeQ8c*wb(Nf4&ATQXX3-=MO_P=HOvi`)P;ao?=ay~9A|*R_ zxO@V(=tK0De19J8n_&7)?xd{)E_ujGk9Aj$^^yD~x32~lc=*dEo-NY&cF6Hc|mCkLOnvs*%8wt z1ZYe2o*V@26u##he)BdYNdtnItg^g_RxnZf!Xrg!|>#w58!Mo)Zbkd(|F% za4iiL2hjc5pBI~u=Q|1}c_?F2zcUXZy{Cc82AYf|BT?DU1IQMOft&v#-6)JQgz3pd zTKe}a>V9ra+k`cc;05Gbqu{kL^vW80QS_!M-$=byOVt@DSayE^IrlV513sllTGhu_ zE1ttS3+nXYYQ}u!9$@oa;6w{*;?fazTBO45A@w_9D$*jabG>K)GHlUJ>6`a!sf`*N z9e7Nib+@HWZJ&sp;m$h^q^LaBYJxI{A3*+ezVceGu42@kHhd=LGtR|>%$8~D$PIPy zjIPc80edHlvlmyFsxV$_&d?p-F37pudaH{}IB z_czvJGWhAeNL!hDLo!mbS)0)p`P{#ix;O{>Aq#tUW_mnb>wK}nU z;182N(VATsp{os0kgFt*0q6T&=ZvS{{T%SFs^HP@!`-TjcZqa8M(Lz@w9b;{Lsx;e)oWRB&z(g1; zC!R`hi)OPg#?4o8TpZ9=vuP3VrQBtUyWj--#GBpY$K(3*_23d0DT&NR4G(Wzfs|b5 zy|ISNpQpAFgS$CgJg>A z6O!{JI;9o#k=fk~w``zE`_t#dtu612o_x*ky zp3lcql;=TRKgIFRXf%JiVcKyq#@%f^u+`ge0p)&cIUSYjI#iH74z|`~a@!B8(!NAf zk8d8aOE=~6mq>b|pTcq7>|tYRfLvy- z$ojK$G8OYizSE|xb;Uy}bFeew#A6A77^2BUq#1){JH35O1YxnnVS{Cf)GOB+2U4VY zW&`PM7s8JmpOD>55Sv$!QDrL@a0`wn;;+G22siJFyemsJAMWl(rf@}p7_4ElroqCH zBDTRX+RQ=ykW2ErUXP4#uY>N|7eyp)9PEgD(T!j*>vPM5{EIG;p*?@${a+}k-~=wa_q3U--t7W5{MOm-RQ8phdPdPitVM;wI^U4<^6nKqo5f4I?b4*G z9$Q4d+_m5z_KX9vx8&X6+HW3{x>h?iyR1Zd1$t#VIqpL4@rllBA357^6-E1){E|Z#C|LZQ3pO+ zT`{#~tL99K@(_PMzH}yhISPC`f^c|6BSccG8`$t7`E%l2%nZ$rdY}|F6vPzmp!)R! z4`pjZn5Z|gT+~ct9n}AGi{p3ZrX^s|pUv0jI-d-z;I?@#oX)`WoFs}60MeIof>D^nDm8^dyH$mbO`W@3QgwNG3 z)lb!M{By3viGvb5zCEKo=<6MqcXV#&!!k2g*<5Cm!gd?#->xUZ#Q5mAR2`{z)5;bN z2)tz(vi1vI$qd@*@cm~U@D&uJc-blPaUnnCendhC!)t6yYlLR->e+M9u8$h_0l^7N z=vQ$eMSNy{#KDX~&*Kkh_HQVks+FaOGEbFl?zm?D6W{&&0Ge$D`AC_C_{>xfc*4(a zcSAr4xRtnuBjS*A(C5#3Do(Nyw8mi8H4Sz7uQ&136rYq?HzxW|kKmQg5Uktl<9)O# zb*x+gf$ppZ(XqLk3x|%|qjxh5xC(*A)%mpDHW4qRl5Z}`QN!NO-SN>nz~-uJSN1yOIut{!0< zP9fnnH2BD|0Z5WpU3(Km2_JW9D&aFIH8woeku6Do;}4JL;ncIQIKPcBS#glg+0Ut_ zOP)h|5e#F_ka+-Ln3P(4O#CA};iKGIyh!ba~r#B)ocNHq+&4&Kay+{x=c6Jw*}g#XT9r;I*QHdG_m z9glVo$QA^a1&YsM?pVw_iA`+f=iH|-&~k3N;rq#SN^g7+;e_E^I z>g*8em*x zT+Q;KD;oWF9hUNas(VmH%}CJ z69|Q-FF&7|CbYl&tf`rp5eC6`fFNqlgD6p9qv@&pZ9)YYyYm*knmX!>Y-C)b?Vn(5 zT?WA>7vs$LUu|7J_f&BEvKB@&+JT$5kmDCR7mb_MH)6@ zLx3i(t%_okS3nLT|B%XWY60{z%H7(W(tG9CN8Tu{L@{}$(g3JgOYD79GxI76AfP)g~js4;v(!7 z@vVVZb*XL*?q46O;~4}QzAX0CPekz}aPx#>>s|w4zpG2#@7Lomxb45D!&GbC|Mci$%^H^Sn;Du|Z{GZgsmw zY&-k2vm;94j0CiZ5l!ps@dXd5gS?n<+tjRj&xVJ{zlweJgye`(291|LH?VcQTE5e< z{M}wu3(0pOlz!ov{AjScUNKKN6!Xl5{Znh(X4D)c)I}%`Ab7qiQYORia@M$SvayD; zj}f|Vz@s2XogP$Y&J@dDY{&kb zsCg$xO_S&Ne$4DXW8tBh(#V3xDzEg;y9!q_velkCDb?oPW#Q&2ex8WQX1t=hN#4)m zqgW%-17hYzY3dQ;2kgG-Qowlnd2dKA?s+plglI-hL~~NLG^I%5KiHmYzJEDwHv5Mt zKhxSYe}OP7j;=s`TX~c|)o}&h#ID(qYA?*ItXcy{d z$BMauJ^)>7Gd1DrG=6ydfZf*+R^4$!`S4-XJynWclaw^dSj<}8Lg%DE2!XUmYmyf$ zQ8SZB<>LW1^L97F8R^t~&2iwb5HVRw52GrPs)uIOnv!>>6R$p0Q5x}c!uk5X|O~#wVCedL90fz=hYq*hj|$^Nh;E=sP-TQd{;D>=c&%5_9ZOu z5j}H@s0G;x?QxV9(>lyl``vmy4O`pu$ZhuWq|Yz@qjFln;$wsRnDB~h?P@l#op2`G z_?&5D%GMFP{Y>9E#JD06{Re`26v^SWZ7T*fuO7yrk(adQYq)&Rp^k-8k~s9nLUi+% zwcu|j^*w&)>5p2h{c|h54&I}F5T(|(%^P+5%cK&!I>)d(Gfg-DEW$5?jDsB7U1!)l z)%&vru4VtdRA)H-xNL@doq;l>obi0|RINJ_@`rp>J(hAx5k`FLk%_IFu*l@`U0b*( zy(x0aFYtS6Hchr{;v+-k-_bvX44&#V!G=5`)%puX&X~&aSZlQ{@si|zge@~~(CKiu zU~0^Jd(!%J{sdc}8$@p_RZH&xJ-dmuhydVcn?g#=X|YK?^3g7lU&7`6W}Mt_Gz;!y zPD@0~hnA1!(8q6x683WqZM8672fL`hCX1)oTBhEQRx%t}5J`&o@rCmTW0YIMAds=S zn2d7+$!$gauv(@FJWpye^9quTq)u=Emb7L9G>lO z8%!}^Joo2OS(*5KHDZ9NB|d|<5^IfVRS8aU2dPeeCd|~6AT2WaF1EJ`Z zg>Pi$UaC~v4eQL-eJZ^n*RQ2buPs=DJpx2VHa(^4t$BTxNa#ZNiDrRb#hSL+C$iDz z_a8BBW*Fqrdj4wG6G_fdDWrRtTc!>n&59DXa*pmW-DPUU+wuTpin?Izw4N_cBxb&S_bRF0|;d;J;0SD~-Z zNuprebX>5BEv{;!zVXoUqN6;b%wb72M{53zyPMeAJiY_?IX(k6yeL~Fa+xCOaaXnl zup38m(|I}cCgXLQtrU(9(SolCjwBqdM}8l7!PFs_HQPiy<%vqi4TuXS(VlcJz<>J~ z%Z*bqb)q;dJ*S<%J*!4@Yeh~O`Jpf4wiA~D?kMMXyjNGU9+N(?sMm%Iz)hN&I)mu;uo`<5$~8)u&d zxa!lt?q+vBrvt`ZKUA}Nn5>WNNdj-91wh`;Z#J%9#t_BHo zOpzZ1m5jd^8ax=mJCjPEET402T*EHxA%ho@}Ax>p@=l z!pR5~SYy>#6j>H4mXjBNg1xA_FM&=mR7F-OUY7$E$_3Npz0~S8>#oXm4$){!vPfGdzyNE5x*&~E=9N9|4x%IAFT?>&-_n1w3HdaYnw^NC5 za5lhPB+}cDkj-q(i58#N7rL@8I^aD=xLu#hfXDLB6wDk$Q?huf9$%eQx~j#I+GfwF zl2lkf{5}<9)fnOf@x%|+CeB&zO?47H2Qz8R?;Kq(q*Q-lYti1lue`4eYOM40 zBt;5pt7>zT9nos_+!L1q7j?}<6qRt;pt0>0tP5^avHzXrsu#wRSEW()5_%W z)HvC?-|;LyK`$pQq~H&GKa??=+!evLqYQ4GS~o8>MV-*H7AVsZThF^Qy{!p2wcnl}wu7iIi2t1gOdcH# zT4^6Zb;>ht`{vy=F>2Ll4ttDoR?mQpfsSB0u#+-~iH?o^Dl)$l03^ZqWKV$nnVZ&Q zJG2TL+HVZzUcDFI+$SIo1QpH33tOxHV3VnT{#zf5t5kWe4eTYHQ{5=`6uJyBAI)|_ z2@;Ae@nK%`Z7uR3-!-dFdaaR+4N?a`cjC*2g=emAj&%Aya;in=5T13q+nKY8A5)LF ziX>|+s6mhc@csi$wQ$;dMvD9$;Yb^)NY$dv@|lPH znR;=Nq{08%FhrWCyz(Vtol9BGL<*Tx)V9R~o7kqU*~L!UX-C{am(8<=w>DTZHVRqB zDBRfP{e`%>m~v>E`yON;%P~Ifz+*%>p|?my%sY91m~oX{<$(uT^Ig$Bg*wzst!e5&t?o_vGu@! zW=MQnPwA{8Ju#I=#@(3#o#exTX7p(4v3iZd!9EJN>@qEV!i;OR1p2j~*-Ub5jh6=8 zk609nr?81P3>@LOvd#Z-DGTfEO3M~O!n@}q@4}zr zRe_sDdqUawp#x&J>FdS9>j638cu{K#->-|kK9ud0qNr`vnj*MB=hfsR(-xlzXYdK3 z(ztZfp}=NQcaFX^U?o+bnkdy6xf}To=**OuiBCV}sf{C%%Ng?~Uj1~Gg{?;S0aZL# z&((?O^}@zc)WR%m3){3#$C-NjSQaO#by(eVM9K{}rqu(lmQ!a^jErEle;nM-WkUA% z2lU2%Ajg(@l*>*m*YE={%xSroCp|VICNJXQV({e*c)Wo9YkZx0LY#qWEi-zAvUx=l z#%<`(SngZ~TA(;!u`kX|jYZDi_ZjwXy4+g0MTOXa&0ds%!$Gdl2|gt`<7CSgK*2Jn+=zYC#xJv;Q~0}Mq3Xj3x#QT@NcNuj zR~S`QWRqV-8GI*3qNb$yP8)Z@xUHynfzw3a`q`XpaK`=LXjUV;**PcZ?_f83^f7cv z#qM`O2T;SV9iTB_{p4xUY%oW+D(@ys7rYO#3$fkKsR2~nRL&AGd0g?ty^zz}WI3(b zPBaqiP>}PZ^UlFMZXbK>c?X%f0Q4bp2Hkgh!ujnrh`;16?0Utrjoh;pd0DDKS%?yX+V$ z9qR9wFnuW$69_owbuOa1>+`6=)W=jTy!Y0^RB2;350==8rshY^%3_s=r2RSX`0@8- zqaU8ui#mnpKdhZ2rIt+#o;1YY!u!o=V4c_a@vgd7l9SteJ0Hrfhd|?yMFAte-ZNg0 z`W?GLK8z6SA!^v~b|UBYBEYFWKyNCrnlXJ6k-^M_(uk+J1S~&n;XOa)eZJv5Y%ozT z_>Z3{GJv(?P%A$p`krOgM9oVx>Q(2qZftm^aeX1@`qQ^CpFm-nQzFw8PS_<9RtXLSm}&x>Hv42@FQYP%qp;S zk16g@rE1W_Jd65kZVqlpEQt%iD!HQZww1yGr?KGa`momfohED$-#+Ytj-A%#$!@s) z4B}}iV&X&{x0>P%T*bb_wBf1ZZGxQjl*I+S(yXIG z?l>OZ9Pj&qdhDZR2qpR5pyk*DeoUKZrMkp|`<1e9gm6`r8{RrX7H^nH{Wz)Zi%O*Y z6&{kCypcJN#EQ&M9K}9oyF=xRD@Wnh?NXvZzm}CAwW$d{hBD^3C>cs%&i=_Ts(}?(XBKyO&>5MQwRmS z`>6D*wcrbf`;_=g=RKwg6^b68q(MR#`7YO+QFAiLhg^z6==6T-TEKEH|9gb0rZX99wd%fgJWl?-P?|IldeuLO( zC@3|(Nsu|kDW7}xs!SY$dC`F6G4C6XC|B`vHlc0I@U6qLf=W_(D>vK8Zyx7niy`3O zF}HK`7_;$p4s|d=)5<>9$LZPJq^lrv`8P5ULX!kG0$k)l-DmQQc6a55e1#G9I(8PxhCTzyhrP_WDG;e;7BUO$<_F>OC(> zFMB}tV$v!BqhX6sF$vzS&MA}$bQP|oL7y6hb-B5}M_d_gb30%<>wf_2ce9d`6$d6l zMixQNYSX6F%bet0gpPCAJO)CL68{B1e2{MVJoOA0hIxuCU_BRBVa+aS(Y=pbAsu#_ zv#U^Lwiu2bG@Wp(1c*&xnBN4io!-XGxAzH?NAD(*FNAC?!0nd?E_hc*vrlYBDeqva zd5EmV0RPcI-*AW{>_LCPnDvxe6ql;)MlN+KWe&){u|t7Hi^vLjPS;>|ps0CGTgr9Nxznu5KV*x|HQ zti6*7Z#SHy*cw$}M|mRLPcpkw7EK>6xr=$DBR8S2owx#hEQ5d1f|t*W(57JAe{~De zzNF?Yh*+h~LwOGHsBPYB{!QD^TovB1=hSWu2D)#1H<-eC+X4GXH(a*f^5W5J{W^QJ?@7ox!M1GyJ3a+=m43}B) z{T82n#b{bJ6^MX*qA_R1mo<6=CAyGK_ivO4UoV?-!Ai2-Wsjaw7~5t#Ss$8yXbi$4 zkA);uk`TFe(=F3V+?!7Syzm9{nQSZ7cH$k)ii*_KF<=v#jm@=E-fR6~y;zfJS?w+c z1(3V-W^i9)_BA=m=2)P{{jYr2MTTo*G$vDQDz%s&h}6releykk%qZlP)R(ao_g@G$ zb>p%3nsa9GACc|A4kWd6b`+Xwn)$v>uzSRZ{~6Q2K()?;pM^m;NiH(ZxR5o?$d&~f z?)cr$*vh2|%^DwrhSZB+Q%h}O^K#f_;xzRUPwjA+pQUk|D3OF(IdGP!!$n$}SGadC zk>^F}xB@*f3$<9Emys7OOS!h}Bc9gC{AMNRO6R>-Ul8RxkE7m-O~;Zfh%0to6;1D0 zB%;6~Aju)D`y1mFSpe1Klxm)20pXyYQu4&KmWLU6B<|VMiG6~rrR@wAV_0oB&lr~o|*yKM}TYROu;Gz$AOa^nk^s;rs z<0zOv-isvv@CS^f`S#x&;<;Jszl>wwnMbRjJFF*#Q~B*K`g6+<1(iGHwWQsX;hh*{ zHnZgdbhpSw-LA97g1C|qROlX$TP_a}8we13ni{TU89vAE6`C;(!ev&B$)Vf8Z{%xi zKc>;gLG#pdrAH+xqwSgr8VqtSM+(&fh}~#^o4)<%D9gs22`@K~xQ#>zfI@ z<5U}hO@uqLSI4Ff6Z&O+*n^5GM|L^AQ!kccg)fRzdjbM$r8l9J78T%RzMPfy+FFOxB#GX1| zAE=>p)7`Pk;h!O$<@iYX1uCH%M_eJsGn=XB#G#}j%1q8x_sEMMRtmc}QkP91wbh(6 z9gZFOap7+hoi&HG zp8CSiI5D<2r#0AA`UrPSSp-Lo;}Eb?_)GHULH?M%c4OQ(_3CJ~j31<2B8yptt`G8m z(q=>{`_^2i(L_eq+1KfUTvOh`E)ovYSz;=;i(dkHMvCm!ZadR_Rz`KGLb{RRaqCfh8DJ>@Xman4h3f|XD}KS6i16(-MHZ-SuV~DA zWdkLuo(@getUI*_b$DViMDzx^R_FzsHnGu2uQ9rnaWYrdYsMyx#a+aj(Q#fk=F`5> z1usr)SxaZ`o2K2>^IgnMpUc@dts`BKXP{m^TQw-&dNom{-Gx%@^X|ge%BnCz*NT$S zaO?TrS!XjemTDiTIV0x0cH?Y~0_9A~okUn~kb)-9bEBhU!i|@(;5A&@nxE1K0TU15u6H^wimcKr`+@ zHM}3@cNz-22Tm_k^8Zwa<#o;{5eUUv>hm0K2h~DuGVoeQ+Ub{LKs;KH1;GW86J9r( zyjTZ9hBL>$}z9;uSdlB0}}Fwf6uLN)?LYbaI}}s)dv^c zWK71GN^K560W_Yr=GYY8zaXNV=5Gi06j;xf)B`b5MQLt$swD@wD7^8MJD zJw6CVjRFP^ty^5*@j=BixzD748~GPV5` zz1ve<_ggTLiC20WG^xyB{tnI@OfH*vL+NJvMOIK&6Rw&=J|3FaB_EtM@pch2k}IF7 zzx_Kh8Q0h+uJK_yq5mN)kY=Xoq31mn2}(BBgXFkE?5^kPgh;~?kbPWi_F8`H(!n;|0o=6ZfkQ$I%tE>Q!TkAu{^_&T2e{xanS zKhD4@WcW4HzkCeiwq)wnhV)60Wjw96_EZhPS!!Mt9w`Jnt?4cT-~s z$F7(V%Kl8{a0&?{(lI6ttiaZ9GunIJTxqPl*SBFfE$)x(U!KgMG6%OMq zisidYbcd?0NQZYXQO4oY2R_CtnTzE$hY3_pFgwi$D|w#?WHe*hO*-oLFPNfZ+j88M zy}4lR>L}!X=EmugMU^C#12W5R_4t+<_Es1hQQ3s&G8cniPErppCGT&n^MEWqYDVqE zJ-WxolW^q`!SMIJ95a|^kA6uDBQ31KCY;nftj)H@e^IWD8Dfn6D=OZPs)aqYaD!X- zfU<{!nr0et7*(W1kV0l(g~wsTy`oppJ>`oG)IGMx+qqZ@U)9sPKnS-St%|O)ctyfI zWgKM(-{4Tq;bxtlviMh?XQxPxX+56JX9kRI?ukIffzEs!G7}FW&yuu0Q$*!8RVjfd&C1i(C-@`h!AoWrYzN>&jwP-}i8<$6}vwB7X3h zW3hks@GPlRThxdQ3dKGA&6O*@QKInwdn^ZxctKrdQ4EwbdlppWNT4J1T!p!AtR8a2 zSgu9?FG^K`np<%5eHwL^Hs(*7hw#$JPeziW{6Fx$_{QPOOO63)1E{%8P8~A*(9u4h z<0T-4mN%$!b6Rdgd;>%AnP=3uFzQIB1sqgWP`Tn_0mhX-1-qE0Y)X!GoW-$geZS|P zo)rph>6O+UG67{3<$fX|nHm13n#v{`5T943u`<15x%XEfOLxk{_h10p6LCc}^ z#RF9`x&ARcq=k(ZRsp>O%=KeaH{X{cD5OX3!QR%aiJJdpCHacCk&{zW%z#-0^%X*N z3^`VZ9AB*9z`sly2!kK5ioBSqi`7L$;G`ZBnup+D?NJL!u+~cEM%LWJTZ(DS_BG=% zd_kibXJcBNr6u zBBv&_WbQB1Sv942SOjlwj0!ndNlhHaMC3b-Qs&5Y?{@_e8rt8~MWTf&(kx;f<={)6 zs=@&&>D1%ASp;^-6}Nk2*FN%%xuWzb(k2wkmHH_4`g~QFy+b47HT79J9U)r{7sLZU z_o-r*3hn-@DGYMjA8*yn9&O#NVXMX0xie3^$HmRqO_A7`7Tw_?zMZ(tI5em8(hq3} zor4@YHP$DSUqIi9Ma~=Rcw$0M1FnVw#^dGBO{H;x(KfBW zM4o*ZA&cnv{2P`c>ym!$z<(LnFB`*}wNb}AFrU`LWI*PdWtws}{%-Q7M;tk(6^FmE zkt&6f!JWilZX7Ir_?j(9C2?5P3!ft1hLFBC#qq7BWep+M?CGLw>VYFT5BeZq`SpRA z@{0YXD}u|A3UBY^iszu$+Sr#{L2 zIqlTn?2e~A&;$w^z(>jQr?Al|K&uSViE0Jm4jUasc_GpL6_Ovx;qs>m`Q|aISmQ-) z0w^1n@NVOxG;XarE=NuM*DElTwe+|BmkP@n@zN!q| zBv+;5KBmE>LZ8yMJS-92In0>-!ENh~ zOhem_vKPxtK6YKj;v;6#pjxU`BvhqJeg0)5wGp{wnToUfaWar87M?)dB?>n0q-HTa z4n9NSl#>mz7hs?8GgJ2Vr%kQy5k7^5aKjdf64v6?VSGE;NvZ6|h+;}KBT8V(z#Hs0 zD;iT(F7zVBEzs%P&k#DkR=4!)zx>~$ieB)==}_u#mhDeYo@!ZeXI{S@;+lHim}SFL z{;+_;nS0J|)ya*<$ZN=H@3q^xL*)0=LJmTP$o@i$rEpFMvrnig7fth?e(UdS>QwIG zwyk0vl$J`@($=fR$%)JPMP#>JZBq{u)-|=RxOby(O(w(oB0mw$|Bgl3RfB|xcAJ4Y zAwQUt;-`>`MoAJp*_p}8Javz5Kz#=BtnFTg;bbZDhN0M{k|RZ#m8zB`D#K7Ig8}M? zCpEb@fDDkD<0&wc*ewy87l4!uU|Fxz=Q_@q;Z?=;M4%shzExeEInf6wjxo9g5+{wp zgNuN}Aoymem^%Z$qNXHeGcT*peM3|KV>4jUxY~>hCqxy$kjs)(XH}GrMw5|F6}T3N zvkTQ$e|KFe?$_v!VHq=Nu*dXnKMMf-Rlr65Be)*Q{vFacJh8{9>@MBVD?U7BLe|ERdazw}tZl+#JDCAV@UV2QS zcOlZNaGG0@xVmm?D6z}?vUsQ5WGv7_iK!rc=`Vo=OBbpcQ-s5aVbQM0e#ll7CW@d? zS$5M16R_+xtK=v%x1A^3uT)&!1#@2=ni}+#M{YzT^<%8I9;AOpzNsYxXMz)ebl@a_ z;QHa1q;rvwM&$iCxkZ6#)sbX zALng;8)yqIQ(h!j_PWbvNjM{pLl&H#oAoO#MpBrdg z>%hBUjQ*N>54b4yXck|ofSQbiNuM*;sY_!tEo{pG1-iS|ohA$e-p@Rq&shV+T`7}hbdSSyBCI&TPOURf~BBcO+ z?S<;Esxti?aC?>C#t9Opk^g$*fCxqZ{bDG`WirrS(og-gBKd&QLOSgQ%7i?~gQMA}RAJnq1qT*mKg`|GukB`(w{F*@Le3tqSz1`gKe@6O^@_eszW8A^vsjE@%sv6UTZwviY@9t4;Tk|*F#vqkCEBt5FM;d&~38w+XFiGrF{y}alSPYUBfD`s5xXmx>LEB^*+f$>scaHIL-KP?2t;%D_w1CHXn?1!V%vB? zCf~X16d$e>re1)rfDfA17s#EEv45)2&k!ty%VJ9t)~>hh8kY&%a_mZr{nl!?G7C|i zV|$6q+C+}YV$%!p&yY;(+t8BJUf(~M{tKSv?v*FsXGn|>_77eM~3}1 z&J8{q-HDQ0k&7X-7R$-y#I2YfLFp6RK`r_&Ci2vtMd~-alw1{1P0_>8{HqMCeLL!T zfZCOQj_OYH6(S7Y`#nJe6XG@3PGrXkDmUG89}{ngxCC%Xs|#W8=?0h#zonTFAXcv8 zD<{~Cr8QmTSVd1BY#AHk8G=_9nRYLF#=YrWPCKi-*QnXumD=&)$GRo3MI@!}A5zNh z$W&F#KBe`gD0yEs>WbvZNBmg#bKFz6A$~c9BI0Yen?!Cs?UbN64?iErwk-@IDcop- z&I>YAqrI1rws5na%knd5>=M|nPbBy_y*%KwOk@;~`!k8G<`DGf+!AolmB+hex@(7F z7lDtO*4oPfvMmS6=swt_eSyO~#x>^^$##d4M|nv@ubjtfV1H4>)2suEg!}RX-P0&B z=cS?LpPV@`_FoA;o{~4l44`}|i>dY}=NtW|n^Qh7-Zs}c1qP88;%L9D!wNY~IIDp= zRmeA)u1Z46IKg*TOufOK__CX@cQm3dhc$BQm!?JbO~yIH_nP9ZS0*UsTD!>qP>*DuPkpeqv+m-QfDk5Eo{fC3 zjsi^*1_t;u;@f+MuLwwocj)L&r>#=h&?{R}TQypsSDdAE19=HJ@dQ_{JT!i=!8nP$ z-h3WrPD{UY(&(M$A4boVkyl!rnSx^=Bll8(lNRK?lUAj}l()y-n$E8Qv{}!OGG33;_cCSqkN7Z_IL}<@-=W>WjZ< zFMJG|QXSc}KW+OcWqWnK#Rt&81g26btLVYD>ER-81QejY{EhP36S)Z7H8T;Tj=ywG zw>5Hf>M$tZIT&Z1wdRnziB|+hQw#4WHvgD=kC0h_TAeuqg6ArT4tJ?}kHx}qGcFva zpe$!-jl})QsgR|eHk@_T8O-XEd9IcBHs&d$Ana@B`AV6}w)FthI~*w;XpI0e`i;dR z;{8mfij|@G`&I{V&zLuz)|(?zAF)HvVah`N!iYC%O{!a#`jU!BD@h!Lp3+7p@7LU! zx8k~(xSO#*)2`m>{A471!zWVpDfN?qy=5=Dg8Bev#7koXm>F8Dq|74)=I{<{x^aJ6 zw&TyMZMsBsFD)Y?>q1%JbpVKqkR9!!bpg%KG^FihDzXV!-|Tr2`(p=sTG_2IX;PNQ zE+6TB`BZ+l76||5E*&^$+G1R>d(i#W@j}AC$G?Cko)7OKH=?`>30B$zzYW%t2t{xn z2Klj)8@mYT{hs*5J#xMvw*@TPCkX{sF3_-_-iLl|On!$a0fM8rCn>8SY~Akr;Gf&p z?;U32_d{pgHHn*`x;^yx3e|^|04hV9HZ0SO|d0-3Ha;xFEcd$oHHBf zrtUue1WF2JC(f~6T?k_nb_F{}?2ej8w8hE0^TKV-*s*IJVyN54Y)i?HQNi#`d-V*{ z?u{-le?Cz8GPxX|#x^^V+4+-_)ovo^+TfseUidR{gKUwyS)<(HE#5ptE@kZ_N+u6E z!g}&`ki8@25lDS&o*a&S9+8jJC2@R2-KK8*s{xXUc`}K7xDj7uy3)IstXq#4ERnpT zm%3g=_B@phil>h_ab7To#j!IW{MKDOlZ<`02S4SZBQp8>0nW*> z&*Z0SmWm(mfTkH^%`Ldsn9Jp~v4?g`(AEAPSD2Pe*$P;p%(6@5d=X_ib>8{QpiAaW z@^)2Vi^FXhGo=FUnYawXJ#q-;Vl2*u+V@#IYC!YA<*77b6u-GPb;YCFBF^VEq|6|P z6+)9s*!xibO&AT1zsIhoEK(T5&Ta3p&dE_U!@QcKVD&)z`8Vdz3XNeP@bMk(Th45% zK!!zbm^Kdcou_83GHS%9ylw&?`AzXZY5LwB+QYc8F+=1hh0b9ptBl%ZH&#U92+fRf zUW~kNJTMCRX>ySK-Dh8fmD@vWmPfW{SVcr?JE2wx@pojW8LKqABf{GXMRE zQMYb>*)dBBmbUUC*^$?a?$DCpxt&Hs$cyV3H{gl>omKN1ff8MBWi`!N>^UI2fLE%g z@ug+w*wqP6MLZYMF@vVGZI+9hfp_s!m`#rmB_Y;c$zhRWfzw)bY5iN8D?#PU3 z&5ZSo`u&d|(VFuP34?8KSnR9fOP>yAc0NL*Z10ur8AyEQ{dIe?^4eY|(Q9@Mo*1}P z;0R*iXddCB;c0xtn6Bz94YiosYfl{%7vcvTp-{;0H0#;p!{U01L;RO4+zF*FM-+}3 zVk#;xJK>jVv3BZfem#E|rm*>|>r&R^nJF3y=;V&=f3m);M7H@qnrxx6bcJC-5n6^? zpfEPRy@%2Hkt@lN1>ctEXF1S< zj1H$-xd{jEs~X5D5Ckr0raon6%afQ^Ro+B0&>1?x5rK1g2t}7^e!&v;do;P; z&e~!g&t?_hg_P_th?FZ9+T)+85}ryHAW%_sR!&y6%`zq8MXNK|k~iq>fZm9@OxwCq zf0FabV~$nYNmE)-r#RuG6aJc5h0bAwI11E>rd(1xlbv(O!^rK_cezUid|_OZ;-sN% zwfQxEcKuoPq&>CpnB#2G;l zEvZzJ&U7-AR4Nr^n{BVknY0QaYz_%gBY7jUIiEA9oYLkz=h@lL-+g|6{r-7fu9sb| zYqRI$^?2O({kZR6${!>;$5<_RJX4C47#v-32TNyNX(QsZr?I-UZ#k|@ zhUxHm$#x=p)|Ipv)EGzQSF1$Wt`IKpeMb|nww(E5BIPCVgh2;jd2;s(dp6>wXqNvX z_y9I1`6xjEiKmR&9jQDYhD~F|=-W@_?8jVsN4w$Ilg6O>_fDaQbDNy&6xvF>G}s#7 zQw+R2+f|6@Z1ml(+J5m=~OOAv0bCaFf0 zCBDUTSTST{`(XBh;_QL-(BIOO7g9g&Gt=GYR9+9vf9j0B@d+5|nQklrzhep+5V=-m zUAmDKb`_z+wb52>J6-6w2aG-jTs%S*|E8L*t%81AhoZgp5B|@8r$LAE2mjA^XhXiAxVH71?p=^5ue_cGC^S*ggHH5u+ygq2Dw-|UJGDZEwHCiJ@7A$NiZ{?(8 zA5H`D`aI}~!dsqe)`YMF!tkCfXfnH5wbUfDr;j~R3`$?3SUmDm_Zp z;N1}ZTt;uALE6mh5TRm~tM)KbB{yI{VE-m<;oFFD8OqD!5i$Fg92N2=>6N9YnrX_7 zcw7Fea`sA<7ZP5FJSg6dxI-Ii=X_jAQpwzDHqWU0dRno6w%9>tq=Peuk%?O#?#fVC zR5ESMc{B})elN~JF-Lt(IY7F7S7a)@SjJ9EfQZc_5kIBh^IzEqeF>q8qgmts}2F#(ZoFuQ|sON~zeZX~WoRp`6Q;=%1gIP8uij{8w zpqg-UlCHX5A+1)&vtnwQb}sUN->xBMg#9wOB{`KJAj3aYsEYL|C#akOa)5^b}s?D zcg!J5cwY8BTZ4Sy(D!1iEOkyw=PXMV`ObdCFJ#OwrupLE=+1Nk^+>6&hD=u#4br?< z@c?yFwN=KR9wm1u9}+k5W8gg1k;?=mnt0T%b5jSC8o`?D`Dgugu$of*am6G|6a(*c zq!^Ah*wSqVN#3$a33xVfo$3^^+RyO&Fm1p1( zzcO_L&^401iUL)SZN&doWm91Uz9e}fBg!5qQ+appULyTKEf*96G@dM*H>NBW-mU1J zJNsWpe)=!pG3tBUMA(`Yp>IRiuLuof5ZCw~vC45eYd1M~#YWlt)jxJ3Ff_~mC#Gf{ z_hpWep=2I6Z>!vMqK#BKxtCq*l+(jLd4l%Te&`yKn{%IsO!vUoEouqg^6xJ)rgYNb zHNr~S{W54c)ZrWH0G3QRW1skf>haYJuTf+$2w?N>A#N-XSQ?|)UZ5I!6I77O)}*;l zlm=T7z{|S_WY&0s~lk$1aw*|y@Qqx_^+FSu4=`GJDhpL+C*-1dhii#!q2xv`YbuwlEYT< zN%OwsHjw%6cZ9BKhyQHafT(YJlLTwx3;2|oK5s^wn{GR&yux(a^AVNi0Ws{ubt)j= z_a9i)Ov$uGGRV@KjWClC#BarRVb1ZcH-j?EOK`C05f7HTjz5vDNt2?L}Szi63YBA6)8A zTTnIAtSTxbF05VV6uxW0btfzr@qGN8q0p2ME+VCcyzXERU9#ds1D~zvU_1wpI@URa zV=gE>ekxB%M=8)}$?bd}%y!ywmJy`NTByzYy@oylGnr7_Tnxur0c0yBoGfLi6TKMb zB-a7|clLD~HOR!VoHl5S;(i3LQInt!Zw;1s%qyNKH*iQ^3Z4zdQy%c<&$UU~&v1D+ zC0?NNnIfG^B@v|GnvU!`Ly=!IkTz881m-v&K>Y|8QbkYW-AsSl5nT}Kn|CD!BF>s|;#(7oR6~fsLG^4jV!imSXEosUs&(mkh z8|%(PXPyAuME0X;7&4iYjv#QVz|ngbwb^6(335*5b`Xk?GlJb4?IwmTkS%15QL#My zrG^m9*@hdk)-#_FNFsLwNLY@~iqPDN4;MMOwnF7!9Kkz6V8hZI;^f8Ai@+J~cJ6Wu z)KMgy`2$iRuRZ(|HPqO~jNu&7c^(b788Cb(c?loQzb+{61bbs%;*OqC<7anzjEV9` zUMZa=x%!jVh0`mA%+^zwzmDRY0G+#59@gIMT1Fc_%bYEuyVd>Hkv7-#G zB}pCETxzgzbySFb{I<46{_Vsa!)Sov3Y)YZrbOJ#pne}`XbZRw`M$B) z!-}jaE$NH0p0&Kq{Pl(ST_5iz0j_tqwbP7Yg*KSBe;vv#&UN?~+~n1ES1IlNC>uP1EivbO8*rHC4jlLZD8yHjB7*tKs?kgq|*#{+wQ%bJrHN{Fo z`$QAWW48d#JasWP2Dcc4SfiL(Vz>s+>jIl)77evadA~_JFP)e+L&vv}g_15~~x4#qD^XpRT7V_XIg*gn@e`>e)Q{5)U$O zUQ;Xge;Aly|M&-44>UILvQM$Q=ojWcP(P(_l)fHmJ?QrE%x)IXz<#e(eck+ zeNvxQCI2y7Gu#Rijs3mybmx`h!{jr$8$B9Pt45zvb|X{1D4tN~YA=#%SrsfZFy|;k z{bOBz<>av$!9C?PGlpfz3>J4g!3vbOvsO=bO6KT1iTlqi#3|Vd-kVd5(f~N|ib*@t z5!U5IWffPpqV%9%rh+_#JCYG6BcP_(#UCPYdUr}mQc=W%%i{?VicLS1T3mGKrwj1J zwPF;5{Pa6wJ0*9HeOg~Kra1uhmFTE6yb*PqUuc5qPc742Qz{Pgkzo3ujz$ zHJ1>bO*;46mBkprCGon?C{h>GnJuXZH?A~PUA!q6k4#o}J!O2^Pjpm8r0u#hGeS9) zQu$?4G!R&aSsiD8nwdWrF{RDjJt^})j;7D=zK$RCgyf3vfOP~;!Kc0wN-V!Yl|sjiG?*8xyGaI1QHh0iHpo}Kg~X|fhuO$ zO#?K}6Uin9@H=50iA-KTYY8&qU_V4_R_cKHB3X(o`vsLPZq2f9&)haPuQWz9eO)Q=}B zJ}Se|Cr_g3U!7X}9*9rIz*YIE2DFzHn@Pv%%KNg!VeCoVIoWIBa@O_?eA89eQ>vJX zEIp9WN1yla;iui=+&9wThk~f`p#DbK>s?98k`~>e(k8J(f$Pr}-JeQSoE$QH;u`I~ z_@o8mUS8v6W@Dl(-4x>bWmAKaI-#yD4#4M6%!P4v7qz7aoa3)%DdS}y?;?~bSi=8z z1^tC8lf|$G>&eoyV%SIeb;T4}4Ev2-vJqRTu0*CJg|=u<6W9PF%!$%?EXceP(SYp1 z61LD)VXpBwJ^H(8CeQv1oIu=8Apmjo+a?;)m1l+TKB;~>T@TK`=U2H)?_~F`jrF9C)HS*0}-Qfx= z)p>M+DLty4!_g@m;<06{S_SiQlN-e)#s;AqY4a4F6(v?J=(n>9 z;qMivZioq|#e^04*`x}Q)j~1exf|l_-u3guc0L=#KQbN0~uJSgP z>;<^)$XdsR+<973kDx8p9|iTn`u!;VxMW>?XCGwZJ|E1o?+|}Q(i>&INx*P|q~xi_ zENqj6aiLWvQ_D1nwiTSo8XIBZr^13itU4k(^sYkA&tNr z&{G2~^r9U>-%AC7uqni-qaXiZDqZ@L*VdSk|BPC!+<$dLZSa_*AGfNI{2|Bc6?Vjt z%%9-tGYsP{{tYT<)~yvM#qV-OMkqd$y^t4P*pib!8#kH1HPIL5T+W6^AR9j*jA32Y zEV<{5!iHUq-$~Kq4Jgx@du<6Hx9Y}{EL30H-`kZkyo#<|8s6C)aD)Vg}u!cG9GZYvQ}!UaP}3SrD%$$o9r$- zFjAKMVRC_do$+pd(`scR5#G~n`Q8&wy8!O!j*$C@oB}>OEi?hd#)IY}U2UG=OqDzX zUY2xKN}PU5OgxE4o(#4LEkOo#)LOBRxT$kWijFUrsV&Uek_ZUxDZ|-88s;DA6$!m{ zQ~y{qS#V%1INz?@?Jw;p9x`b7A3L^0*9YP2&Px=Dhytf?dVv0Mx2YR+-YX4yb+F-a zb!C^ZGEiU(dbv(p@g`Qe+V3TH#QD$oA2h9cyXoi^mIK3ZdUnN3>t&NR(hit!Mg;jD z?Xyb!N)?C)kZZmC^5MX zGuD?lq94Y;&KY#8_e5?^^i*yyb$h9-7QT8#HN6u_XdLYmuh1oWDFWv7RgSMkF%8gg zo(ioT6x~U``y2ctl{^ghQmM%Lc%2uHD!a1pYO}Fahck0QU!3LUI9xbJ{50>3tS6AF zN)jn`b(9?_>1~&57F}+$X=tn1ut^;B9b%mJ$&2XJX5lRh%YN&?a03ZUiD%J~5Ivem za32cmC;KTpBtKVhwt4`cm!#or(^)mqh5en~XFz{NAB>{q(zAho;I@6%s1Nui;CNsm zDVAx7tHyobZI{C#IZ)rdeTDHnq(7|CW8VZO&;geH^uynH_anjOcO5CVpQAacXZ^3+ zk*X2KW+2vucg`ymhyTWfW1sD6!PjlYt^{7q`T7?I#p(F3EwZbp2C*dhr@~F@8XGf= zh%PMaIp0jz+NG1R8^*@=U!P3&^&!Heq|cRn7iNGW@=whk9Nb|qBdC|Ig>pN9)cRM@w z`&wS?{u6R63w3;a(B>WeTr5b<8D@7Pon3bM55j8P{Ni#cL9cX$azCRSVtnX_*@)s; z!6yK{Ib$1ldC4di-?c{%T9gJo?gRWF%qmQz;>?SLb63qL36bV>f!0{}Fz$)`lMt`X z>zwZ1PGh54*8LT#gYC2&@3ph5-M1fl&glZz-shj&oi9$a8zz@8MsK$Od-W5xHLpJk zeENxfg*EBy`$-TE!J3mjRItqSHinClfCryCF!u{=P6{X zoU?FDwX&a=Z-0k^fUj-RrCv4#9+xBbG3#+=_76B;o-F{X&Al+`7}4IvL!TQmgkL4= z!*wjs3!$H81&g>2)AY*OU>KWiL|H5TF?BIqW>^}RDx$w}b%ZgV#j4(b-&}46uEn|b zs-#P-rMNN7eUaKX=jSoey5zCa)l3r^iI2l)g{B za-Xr_%4*u>X@{YLr5iww`p7G|#D>2eMxg-?pqda#B;ZJRXWu^-0$wdGSQN8jX?th+x$hlKo3#Si`2Q2!iBhs zDL<6|*)x2?vAHL}AqjV1a6R5b>f0dx?$V$h{LOTcej1Ew%i%xH6?wsiT-#7bnHRG( zpkr8jaEBUy*PrujJxuF*h*?I6;y`O+v3=cFtx5f&i`7f^v!IQ{>(G~Ca4#fW-v9ZR zk;3VWnrb^eVj7#ybk7Sc1j+1^afHUNhHUnQiy&eai(`X9J^m(1!DV-a%!1yLlEEy+ z`B-phgkb6rt{vqLOk7{wj->dI7Sq+ogQtS?y=f>%+CH<(9aNC;6f$q_9(9BaJ?>zxOXSzKXyl(j&O>VM54+b^h9SZUvW* zLX!Crl1i%eAEmHzP^<@w(uFlIBc9-XCd4EPAan< zwVc{#SBpO{xB=c!*v8vs|ZGf zDYc|@QBooDTScT|&p-tW<3kr@J^{wZkJ^tc`nHS1HW|-=UOXGdjsNYo8#lCX|GOiq zxLsKxw{Zl(V$CV!ujdM$iYiK_-b!RtHjmL57*cE|d8H>cbLlx_(H8l$hv1fKQ{!OK2B{xXA$H`>8Rh&K;i!FxHuOL$ zbmCIMIyQMJ0C#IV!Vlo>)5)-T)*gkD3Js<%*H@?JT;7KG}SH$&J2{^7Zl zUD>K$<;nQ<0p`XhjDt~$`H_l1_*}%q)Pfb^J)53@Pi5O0&*l;yMBu`Sy3Jrt!_=e5 zARQYhzeyRNbP?7Svbbjf^3c?Rd-!RN%UTw1!^%urRotPgK*p!Zf9t_Qr?4%(=uKH` zeh9}DAmowBR%80AP|PRyVk6}SSUc0lL{I8+`hQic^RTIc)hD+f!-nIVIr&r2#Vu>q z=!U9i`~e?u*hORwGq@f4WLm4ib$Z%dVv;&<{-P&d41fGj*LHDVJK~Sj6I=V-YBZht zHjtQsw<`Ny7nAQcb)lskY4L1)JWPbmi(NuOtTB1wo&Ia18`gqB z13{5NY7TVi;RJN;EbN;!*g}-kv63FtX|j!lh&xb)TQ?N-Mt)&jl~19h{6hAHeHABG zd-`|uWy)qd>|pcX<{MW_4HF2W~#s`b$0?ph(1mJN$=!M(`p=?GH>> z0sFlxPiV|4#%C4nLQS#CQRZ5g-z6FEqPCnSyYJ4fEgn|9pq>J@$g}1)2md(WjNP^Q z8}WQLc{6<{+!CFre*ME=j@qhfW(4h?4Q`vjOs5nyUXCh9Grd`R; z0KUM!U14LE7r5?#)yllNCQoV0LEu_30Nbccb=|E!OB#sl8F#j<192$OzUNLkkzL;FF&K zyH4xmMi_EdhG4&6N%rskszc5nIPYIgTFoT}pG-hqvTRdkWqH~gA-|3)Jw8g8)35Zf z64+}wdwGvfojRs4xq7Z!<)MWJJRUNZ4v77;CXTT8CIPmtFHXgtd&VWt{C@ig5A4LsWY5=syHx28>SpXwu;`mu7oiQ ziAM+>^%|;DGDI@tUE>gB<%&JOe1CS?dA#9G_A9J^k8uhiDQVu{;Js-yn_mS(Na%%b zr|GT8U|`T$kzG(%`#{z4j?6!3p;pAli~RD)&iwV;@hzt@smQk3ty%&tm%ojT6$bCY zoQIJ0%FRB2N7pR5UG91I%$(coz;03EY`I7D*>mblXW;Wa?oR_D?cn1tYLpy}MH3>5 zs5~Y!&eue8QZFYg1?2gnC(2~{qK!^-w9wEHYOKygYx!m4trz!>| zkiAOBeRV1bJd{<0Pi;I+7S!`C$(d>0qC@>QTfX+v&fi4zU7F>k7%W-yq2&tpRpMyqzt|}1-MZk*o$Ck7oooF1k<|jn7HZD3?*u(o zEiUF;p2#;T@ucr7%-^SZ{e(y5h-YDI>ulCQ_X?i#;i#!xFXDqn+!?IKdiMB&g)`!< z<~#qb$6uqfj}roD$nha#JUfez|EwMac*?CeYE1iOsM}kp^OiMae`nubB*pxiI-i=$RDs+gYYvNu0y75Aj)rm*4SG<&x>z`W$X!0q38 zQY~>g1KB<9u)tbc^3d)9DDcd>iHu;r{(HJ0HVdFt5Xv=STAir~HPL*Yspc3G( z=B0D>9zC#y^wJ71R^!axIwk5a8uTa+KT_Dvf*b*muKox%kidBe{`#n2dE;1X6*Luj zLP~b3#TR~9+k@23&grKQ3`64^52D5n=MuJK4meU@I|c2M7k&bIdM))0VT~t5ZcsU9SuvJBweDrdJ*P92(1 zT$S#*nXCeXr$|P$qp~o*6Xzi)ZH{x&AHp)*GNh~))PIzJI5*QBeGIlZ>SoK{9aN3%_3dexc57t&cN0+A+%qI>50G3X@k~oS|%RCEEjth zgTi;el=|Kbm8?v`S)N@U2`U+lzDqKg{8y;DAAcrHap(WtA41%E3Mref)K>Y{+&Xp7 zoO3z`OS};a=YTWhS-7e%%X)Q-JHnS%(@Fz?M~^p*MeY5$S^N;?|8Q*;tkmeI19dUj zuGQB{tq}4$Myo`0^5n>AxRcIoz6P7BkNuZ=ZJhF6l+X7*Nl#PgQ)9r!$b27yn zXbb$>4Eo6_s&SJS&`~8aYqW zR|VaB<_Z3|>lryI3VABtQ&GBGE_I~oQxl~+>&f>8H&^2|>|Z1~yVcJAH948bx9obd@0>+g8o|)c{Rs zrl|xNE--x^E(;4!q95g-+6nuK+&Zh8;s^C7HGV}(5*JgwktNR-%=Fy|yzp)95MN9x zE$F8GLh*vy=QZw^|w<2^J3lhrfeaC-(4W)a|td6<~q?)Q*w_3F{f7 z@1*NNRl#meD8cyGQnYIPTCjoa1Weo2y@I&9_9wu1+oT{zek2Q5w)fK$#+TOROUctu zKZ^W2`8Ce&WSc3kcOw0X<%c)q9itYAZ_)*aO-DqSw-50xAtP+0!=(Fv@ z{O4+&|7SD(&r9hR4SI(^DeI!^*tP~Fc8^<5pN4BPFma0F2^>Ap7W6ssYa8&?<(m!9 zS6Uwz6eTDa_YOha{+)B&M|mtbd;!O8EyssYHf7_x$ns`4c$Fp1R+W_EfHF(ef$r}J zS$smgFzyn0Mqd01d2&XBN6T|io+YN`<;bW%2;vi;k<-<#n|ZOj?~C6Z>TP^MwD z-Qu?b=)MDyPH!X+LnzTn8Yxj$@TiA=J5!gomi&_v)K{Q=csz`0{%zwMFm9VV$yHcc4ocYZT)1OrENCe0h}7o#6&}wee1|WGggSE7(Cd_e@q; z@CCoe;N?&AW++-AvS4=+4R>>fxj-nTjRXhZnrW1$v20><(&yaF7b~#9zj&88K%jmVHxjPT>h;hn@?WIEh=bgX*KA|Du4+J zLw{jMdhcTzUcWAMM5%0?zsUc&L!8e&yeh1?Q!6XvsJ!H|e0&%*4YJx0>6k)YXz~_a z>#KyFNQF26tE66NMxmDir&Y!dZR|b@hyNVX;zWM_Q~c2&1M!lh#oP5Pw@~?PD+Whf zN%wZ$na%vkG9?BKxYZXDs7HpJTwU+xxo#CApR*Lqf;l&n55c9Agr?OaO#>OqSeWi3 zu#LSzA^Ca$OK$xpLh$^b?+|h__*6Ky)C%;HQoWXU2EB35VXsE~)~=GHpnat;QKz}# zIBaNycWbF!V|qeb$zUNVPJ2~9l5PH@BAQp+OzaVs z=nK696N_lQiJ3jOC-2TO8!>_Fn)XP&zuL4Z1Hhu$577~reSazG)enZ*!N@A5B^Od; zFsWO1#(f0g2oJmFGE3r=`Twm090Olt7xsIrVy&GkT~QjdjT)d)w`BACbj22k8q41{ zmC*kDO*sA`d~G`vog~9iy>r#Sw|h}@K2VVJ8J|9QdDsuA9!8K#Ws|yULI04i<5RE= zAub%<1Vc9rgSMC=tFy-4py$J4B*cRICJVQyX8t?bmLRu9o!hv?3lIQGO&A z%o0EOtXG15gPw;_+I^?g$4W-rX$|Xihfe@_|16mLBq0v^IaS5F!W@pA2|=xbTpvMf z^k6&Guapi5D_?boOaWyj%m>4VYZcXJskS|4&kjevX3=Ffi}AR>YLmCD8HcIWPSx^X z%|7IgzLz%m&9fT??1MwhboKTS%szn=#o`sFIc2h#PFWVcehZh8)w&(wjOsIP2;4J*6kaCjbG@=7Z|3F<*2lYA3~;DuGPh(B;H?kt^9V_5;-$hYYh+>n%#On`hOvPsE*#y3}XLNr;m{G2O z%1~rq$tJbiJK7@_+d09CD+Q$!jpEJ5%SZoh zo?~*q|G7fTexH4$JL@*p_*t)CHhBY~v?twup%?c`K{^I|-0$18Qt+NM-H|U(Ju5x8 z8r%?YGeo|c^7_B)LeL=}(iih#5`m{LW4`5et$~&b6c1UqG3khH*HHq=(H{jUPd1D>)*T0GgOxKC9`$NV9yQkdfN;gdi#qP@8c$ zi(+R{Mi1kE`)gBXwEow)B=(7JgxTGr_OS->I~68sqb{Moxdg$`g%!fbNY+L!$kDnV z$}hJiRFst9e@8p%LK5VK_91@W6oMa?b;DKEa!@^DokLG zGzi-*1V>^n%C0d8JO@ggFSZI_h|v`+aE`6ZrHiromDMqC=n|8q)IwS&+!@P6{j((O z$D}51XtJzjPXxw$A(GrAE;o)!%L7bHy#Rgbm$k$ipk9A6qwXc|&63LHZGj)8Ex0?b zv0G{={lyGSrCWl~?{q{Z*#{vDaaUm8&vJvtMR)skzm3+<8G%otnyu)LwYPB^ z{B*W`Ux?P#TCpLRx4RAS#leXyghiu%Ereup;y#k{)*1`ge5`ik5#;;b^J0y z*uH%&;97$CHP-!Z*iDhX8^Qg+{l|FwPSsY$;|C|jTfGr|QcIgLS)u#dal(;gVtYDt z`pT&Eo2mui>5py*Gwbz}siPE+4VG4dn=iqb{YL^DG&MvcR^X<@^_4~*PAo@dh=+O| zyV=%q+)*FIG)#V?GFNkR#%YXI!$4LKs*v-aFKTg)2!b6wMEeQ6dY-~0jY>JNMO6Et z=0FoG{weboXBKZcE8oAnlVJgORD78BYXa%ydr^hY^B^*8JDY%Ow1u>j1%`dWcI+HO z>GNu(5A3slGfOh(aAwh$I()De?sfNIs@WReI~9XA4i)eA#Ibny;EV__+R10jM}b!{ zTZbz*e9ET%^^)(_KNu}<3#roPndN_=jsH1b1-#ly3XlzFV?4N~M%ohf zpdUxYy0`3SkqVC{H?3@S*)hrQ_4K!??=CLFs7RIBoc8yiI?M$|ke2xTci)oX5vo~3 z2-^83{lNgV8Q1uURyf1_kckl4&2m)YmnT4|st_YE4H$p+=r2T1w}{(YHzqpr;a3Yj zKfag!yMUl2XPJ&DoJTXLc<7k^+$G}8P(kMYkDH-Sr2J$sjJ=+B;rNC(uGeJ&FI4_o6sMQYzH$JMOF#a9M=L_aRigl(sk5eeWAcI?}eD7zjrYLsG>HoR9bU{Ni_ zS&L(+K|oaovQ#b7-?GyPPv@6R=>Ej9)ugx1^0x`b+{wo#%g!LX#oNKHsP(F_9oJfH zptp7t`PoL(e$fk9le#6C-#17Nf?0e64CZ_d?Hjt?s5TDRdy6q@P;;JL98%@QNN3?5 zxo~pCijR`5A9F^&-hqv5Zh~5ZmuM7f+est}@<#V6#R#-lP6JQk_Q$QnJ(9!{R*3I! zIpR!}_ClP*H3hHantKBeh@UNpZui#Xg7yZ+%c!qNPPF0|z&mo`G(n{>0^RdNG=D?1 z%SOvy8O(7mI?&!H1+p+@MHv0rPUkR`@8ks!7G^oixZ(EgYphFd9zXC0mxG1fhYJXi zw;u>3_+px{n6wx#hrB5rjJw0P>&6S;%Kv4PrMV5#gKbQgfHVBptcnn6fZO}NYLBr( z@aTz1*5VspfP6OqZBJyi|4bl7rTtaW17jmp*<;x^T%BLIw400WckQJJ(V2M>Jtim?rwJH zAqXm(VtfnrHXX5-C2J0yl=GlI$Z_33u4* z1F3{Ml{7igS7RziVad1o__c>nOL4QdUjvdBNv-3#aVko8*{SE|yj8*1ghfL#EW`ic z-Tk{*A=2W?QZI?8+;$`bc>G>{e@Xff@+Pa;Bdv@jo)6VEV$`ADu_qIr`zj+jmZYxR zPQjGRs=w8F>5@?N4!um0xL`_}upjfne`#FHsjCUo--$_wXG%jbo}-C@y{tFtss>bD zP!ah1Bd(I~|Aba)4(5|%k+6sa2gL?(Pwl``7^e_fYwz5PSelrlaqeIWL`DHC`Q@=l zJ=abr)1yFiEHVlF4mlwW!Dgv$f>;}^h@<}3gf=?)4gg5`oyDpFn(6A4!FdS?H9JD!pX%w-Jg1=Jxy?3ubHPsxj#2&mWEvKC}z>1@CJS_u}?n z#d}?NEm3j*a~TK#)$KICCXAb#|LRXw*yf zSrk!xdpc+du=Y#aVFkcW%%%|hn8)=Y-Hn)I(w`GpMo>*9IZ~w6iK3N0OrlkPyS`YN zw<TsYYO878+FfS*yCNk*fp8^fGtR%(YS{M!x_P^BWzl(A|1hMU2@By*3mu* z;VRsKDaKv#r#x5uDWm28n5crz%^G{0TMvA1x1^zNRz9QhoiLW*cJ?@$8Vy^+!d#{9 zDe!G7I)LX4e@^%$PV!suDEDhOXNvR=Aw{b{%2Be5sEe)gU%Bz$5ZrmnRro&Uv5nIG(hM+Vu5)cCm$ zM_Mj*iDj4W;x$cS&n3`(r9P^T%;CeazVTuQ@OrSse{bL>d>%_)xA%-C;`iC_{ca~= zkt8eP1Ao2Ixc7Y@RHo7N>NB8*TCpkAh?5W7{wJ#q*jJJP+#m6!B2q>5$F8FN!?9E6 zOZ3=#T}sGW;%^=M5w)E}AY@rLDt5kHzG2VUdzz=rZq9^}Ffp(MEJOD#Gj<$R` z7dcg6xVy3#ZvrbIY=@DTLfQ*~@Z)L5%4ap=%)R7x#ntnZJZo^6FMC7Yx|Ws%y4 zkHOJR(qg$z*~444m&UK`pNsi|yfV7s!Ys6S^c9VcI!|~k_xOc*V^gms&%cTp50yTh zvA@0mm2nFf49R!vi3d0VS7&Oc6jfk|%m^)OqQs{9`W$Qc=03i1c{a3n2a`27+0QA9P;g*YqZ?20poL z)&_CWSEcnMQqSz1I^{!Q_z!XzMD5u)ZOUp_JdyHm4LQ9J;>Sr*MRL*IIT5>!h) zR8uR1L&v*kT(zZB=qSC8zP@#G{6m`FOrwTto?G6w$;};7mvB{ccN?*P zAl!nwL0c94zNQ-Wuo`97s;lzV+!BvFR5$L4P|;|kIiWfK2h%_-zs$eNX^Dr8_j^go zQ@+RHJou75%=b3R7t%3G{`@h5Kjo=qzo`d#Fod>}Urm;IX%71=GXkk)%X#Xd0H zAD<83FX6#HIph7MuE=NJETQ;s={zrk@xWeVJT3kl4gJZfSF9H$YZvTi_TLQqLkSP( zUvXx3_^zcr`MEO=eX?~{{lzzbM!F@%nipRvf79+Z7(ga`3Xqx|ck!@PgKKgfTK_h#si z3fLd|Rsx^$;4EL5)v$j*;Ql;W5`MyS%6x%<^*KYH8v4(jgZ?*WBBkE;9&&W(?{+v3 zg_#KIUySmF@Ra!xq5W0<5j~Kf>HZ);IQYfTA5W?R=P85^{@buO4D&2K)}O|)g$($G z?7!oCV?1SkPF(l9@cgyfE%Q6QGA}$v?61fqvd{5$#zXnX1AdhGO$K@3NOI!5n^G`7 zZpXv<0=%2;Z{N#}LD(N(%9;Yzn@)d{qFVQRWEZe&8o$s$zLwzi>F3z)T9qKKJzS**WFgmC&W<2QcX8tq8$B8xi zdVl<=p}xsR55|M}QjF*RMvph^e&At#!9!z+H92Ze z-w*=iqgWp;^>yu^6jF3&{tKiPG`yugw*2GCr#si*6P~hzd&pM&c$Lw?JXb*03|eLT~H@vxqT@Sxs|<+D55f85E9^0cJ_^*+3w=^QWS zX$sgc*_3@TEwp@&NAUMzexJTKKs{zI*M66S{)h?V_qgfdUsKwrWO7!M;nu>WlI#1b;65Kf5nd);_XadL%fdg6#FGsn1{^t z&1Zj=z8B{Ej7Nz2vWD|K#z9J)pB>l!c-H6llBFXa)H5)i5-$nSu-}D537n6aT#1)h z@xb3=yk)+H^?Ml){Dtvoa9()z=lZ6%Xn*73{$Crvyj9N|FG7E}ji2AD@#FrKdIrmT zd#mmbJZ-;$Wj{MhT_s=U(;ELv!6!pJqB@WIoV@8Jp2+r4%7*wPkF9|GYPw6YKhIaX zCI8EF#Sw4q?;iHw)yZ<~=frs^DTT$p;_tQeV{=g?)}N*)DEPMjax%sDSVBB9n_eb$nVLYtGhV#Pd{w(u5L&y57 z7AweSSK2iM;t;>;O1-Gh>->Y^&lE#HappBYfS20h4>CP?A-DlA;ruI~%2GeX^eC5Q ze86kC?}-P;Kz%mRBO3D4Bu%ltgz%tW&6S&y^*y3WU{;)+6TR!=btj`VtsoE3F=?Q{Tb@ls>67D2y6U><=nl}65iUcHuyOj^ly$HT&;ct!aseS^1BzUYQ?OJ>;it{5P%&>j`69;(s^)8Rogwg8RVfQDeOs-JcYD0Q-sgQA2;Nk)L^O2FQb4ilUE7?dN!yFB$8fbMXc3`*;lvImS1z zABM<^^t~1GQ6rvXioaleSmOl;z|Xaw?dRBfL;sg-F4(_C z#z8ype~aA(r9R9#kM|d^rA>$W7dnd4|FQ0m=kxK@U<01h=B?KP`aGp#=)a_+X#4#V z?4u&%J{sl|(ot|8ZRx#XeMHQLcstpMxWAF?$z^^HpD*U~JX*qw7{B89!Kc49-djG; z+Z?R`5MLvsD`NaKxpKBoUB!N4ZpViHOVSI?uz!K;+kqanuJK)KeF^_6&Nu4;&&PP@ zep9|Ge7{^2jruor!@M~rCC(oY)uBF$SJC?kFJe7)52fS#O@@BNaTL%WJP94~Ed0zz z!Fs6>y8jzL^ZBr!ot)T$`ZrnTmvB8g*azhALw?o9f8(mKf2PKzUe8RApxIX}bjqLj zg|78o>T7)A=Irp9X#YI`psS^NPIZL*u@a zX-ORL$P+?&pCaOg-p~8bW4WiqeBg1+1N;5jB`FW{9&$i`kay5x|7FYP`7fTFZj9H( zl9l@VW|*fnz8B(a^hY3HVa2OTexGXsvA%@9*D&wjSDY`JJJ$1OE|oFFV>`|lpg+=- z`Htj87~-eR<9urRBT9cjyNdXZ^u_uOB2xY%|0U zKdSfE<_|nNG|YP#c&6{g{o-^!=!Y=VH(>mQ{zz5t&#=#d@Gw5!qS7DQEc3227bF3F zAEx{jkIsktcDPjm=l`{8&>!@xP%q_!U+2x;=R3EHLt z{!3y%-0w$thWDm@FX2_lhZ?^(blj&DNarDaTd#)w8bR475>j?JpRl!h&NuQ=a2^!> z5#*QF+j(9j9|h_U7!UG|biQVgr-gV!nXgin_gkAGzuLOP`6{J0WxpiZ)Q0&(t}F4i zfcqS5c;i=bei+dM^||SMrQ-Yu#?$OcXV{nJUBUbZ5efPi20hO9IQ<*&7h?45{&+JU z|EevLqq=&-@l)bg z73bX$UNP*SA=4Y{xj5;t$`_)q?*@8QkM$9xLt#Is@qA1V@MnUrP=9YbU*yrpO201J ze{4^l=c5lirN0*Qm;Al9`6|$VG{zVIjlO&ooR`Z)SKhDX{jI|G)5G{)5~o`j5!} zL4V`_`mg`%fB6soU-}om(ErlE;Qyije|;bR1L}eZHzxnn_=$7_`6Ckl;u|QrPoVk< z272f8B+XllpP(LMh)-$_GqK z>Sdo{(&uT)-(cqD+%Rd&L+vX}TX3R!Hj~2Yyx-6G6JLpPQ}_Dzc;D(LV1PUP{*W$O(7(=;UkZG(+@a}&WwOmU zYP|o%=N+k2}$z}7L?tX~83Gm5|H*d@a zm=Q3)6KK4_pt&i=(72)drAImE`htX!EE@be)AH@(KE5dNiCMqDpc^R&dYrfLFD#89 zrc0fs%U8po)-&M6kYTbY|7*W;(O}3=F8cn}(NF5c;m=&MsIAYuPJ^w?LvGCfI#rMu zY!$TRPlEkET9D($DLOwtyskG{zuUdlhbb_p5g0*BikUhkaNU?#J*|Kq)R|uacQ#uu zEA!w>%)mSwQ@@mHnfJ+!pvX{Md}p5PU}5sPDkp_=n!$PrMXVRO#ZbaZmpUz?N9k-Z zv%5b#Tm~FtDrTF!>xo&u%QPM|d7FaX-LHmzw!Rv{6dh4_OkQv07{heu>1V4^rWW4$rMK>x%{fVr`<+_Z?ei2MHb7U7(tAEy*5-*wsb`+&JVpXZzg%=?SS zx94fOrPcX=ghr7!zPZoqbU|+6%YEXvZ|*aQB^>fCFX`{BFa4prxD^{+7B#wO;Lied z-`r=I5wQ2SBWC=8Mr{h=He&^-Dde$N@gjGRXbOxb2&HNe?3Zc2VxrXw=K2Ox zY`5-ilc*;Ml8A~Fb@tt#8oxdOr~R*(Ln1Z}H+dZ_%%e_C@I|(Z9RALe^2A%Xwa@qy zUkuB5zQggy24IX|0sRkvsow@*>h}p#fjcZed~&E|KA9p$=dY!D8+nE((ag!)hc7sos>kmYUPh8{{JL6C2 zRL)Zu$wNt$^jbE{HQCBDz1KIpJ2Kd6I2E0OMOBikF!c!RS`&WnRXUOYiOJoRxz=v;a ziA&?N>JRR#>PIv0yXwzTY>7H=66|?Vf`%uPXQpW=)1g(@T(^?TV7d2IO|N!i#!wP| z@+LXbr{cfuo;bskU&2#j&wrQUSK=>B+f1j61oP9GE@|4KBbGAgvQ{6wIL8t|n-vIU zT6h^EDnCVE<8-VaIR>GmGC$d3)|RPau2^5Z&-{5paS#kimO+9mA~&lFAV5*UPTqWS z5sOhmd<8NBzeL5agN2!3QctMFayOy-CJO6i$!Boflc?l%}8mQ zaS0`0_)D}o`T1C;l1>F;?2~h5h0RW3ji+%D`nGm*`I=IBIOn@mEYmg_I2Uij36T{y zVzx}q5$6Tv!!KF6>r2D@_IPvq-!oHbp73EC)P0zQ{VuojS&F^B=wrM(f zNW%UYl<;DOW{I(5E)pXr8%Z0y#ICEzTF@_w}HAEi+#nN)Q@B7*p~KkFMF}RwNHwCNEuo=Sw_6q|ol$ zr|Cl+AfY1&%P7v~cWdhU{R^{A$16a!Ql4~w{DqBg7-lh04E@1eH6!|)JEtZ{s3HWR zdt3Qai7o6fYnA)Vg1O2Ni3V7_&g=JY%qc?xsI#8}Q#Z9Qo}V#>0AY}yVusi6-!f#z ze#YPVB15_bQ>t38TZr>!{~i{&Ur&%16{k%7l*yueMK0~m8AN{e=bY=?{3#w1n$$D2 z8DhC=t^Qt@cq3iLTbP&?WC+%aZk*62a{g5bh83P-ZkdeCK7-^JdYmWzqT@{G%;JEj z=iC2P;pklr^r_!n2Akm*Z#23mgqq~rH?>9vADjofN^tFoDSmaspPHy`QOCseQ37oJ zYg)|`B#D0VeDspa@R$hu#nQe{H!xHGe$HQ_LswPe{f?y03Ig3f73^I!zH6eU?r;#X z{K=iXk%F99$Nb3wylXRqaOxNS1m|VLpFAq~KW06~eNG?1-FRF!LrC!Y{ec7A%Pe{IBS&^B9{B#)y%dem zf0cPoNY_3DvJ~Oe>7~=VyafpT?7J~<$aGxw+!xW)?Q~pq-(O@a7(|IM7p@aYHUysO%SRJzCUGjKY7D#FQ9Fe5agp8=-ur-Y<7ycFjvdh=)gUNB=R zYPwwE;cS+9PQ@ukrMVHFZk7@IE~y!%uxIj;C7T%}l@ij7f`quXBK;=l$bl8(vxp-D zRSLhQaebXeh?nZ|QRwvd9L+`Jn?LJ!xr7Bs8(tFr{E#7Vp8>voBR{*O`J7;O2!=dP zoWVJ|Pq%zK@;o|RyTY@X^twyXzVOm7GUWRG6%+HYzbMV?%`63S4%%d%Z@0+LAS!N3 zxqjZ+g=NFn(`#1IK6Ao0evJ?($JNnO7=@<<*E6xf9?*pa(OcG2mCsO{DaV zDF$1r=ZM)RvUej5Lwzc4@31mw639{)_r{!+aXdTcE9QKXc_Z1Mc%%l)Y zqMDm?zA(#ox<8mE#Vs^?Fe}{WLnHb2U02a;yGXO$7>FL`A>AZ;_%7e-{O%Xv>Y9bN z0&a#0Jb*KE(;(O`fPRuDd{>UoCr>q2q2TBF=5z%2FvaARGWC+u3w5fD!3fE&L{iH94*ZQOTwfWVF8 zKfa2cnN0C%=JUM=D=5ydPLspaMwGdkJS8zcjY$j!&N(5EKf6hIc?kx-G5z}OPvXPi zBfl|cd0>YMFQsyG!$Gq%Kr$&xbCM)E#T?jl7|&R3OJYPr#fktLy2r|FNGsF)!_@9m zB`48~P2tbXKtF)+3Z+@_0sOA9AHex&3dH{&Kq)}`{tC05>O``OyauyDfh@p#V-vmO$42MCCMP?E?to zWE7%odLSlXn)Uk$Vn`35Ar75pIPw9+t~lr}-PB({fU|EgVZ>Ab#R%P`TqG+t0}B!4 z;Zq1HB6gDxjBN!>5O+@ixJz0-br1hBQ|ey@?7YLgt#VocVJ1ZOE8s5j`gA7GxGSVt z1Tc#_-Q??@+H2`fT|YUs6)Q(mdNpq9l=_c0jS>Er2u2pCHbPfZ;nIrdg0HfD!!E(0@4LWnEu}Se}8IVTFHQ z<2=75`v{O%QInFJwLWX)~>e(|@_5U-5=M*|cxORr^h&_Cbu_ z5g)UAHY+GzkLxn~nb9)`o7?1>&)8N4{Va}j5(eLR zYvM=?APgRo7bAdaQz|`QOp@+3DCU+IV>zL`=@;NvAz?Y;OX^7Z+t=8^bHZJ<>r<>X zbqn0#RHsRv%C4-+uYk}jq4EO=Y~$dByV6^!%$a5#xEI3M&Y$n_)=xnK61t{(w1B+6O_bI*r(mu(8N!OW z4QkR638i^blneN3Pt3s3*AZr!_XCJy4mtpC>Z|4$U%5l1vIqwYl^?)4 z(Qn(WeC=6!N@l;?4|S@57vT4TdjZ^pjb|&SOuWT@V*Z&?~0H_hbJEtNK7rBz#MfDA?9 zc|JYq?Nr)Xp;KkoeLAPKNIR?2efm>7s{qc7jndnRfEzp3O_A-LRD*+N#`eZtCCrRb zz7Pu}93mior;8x=SryxHV2}Vx2hsQEJbrxv{GMYG!0)fGr5SRW&H(m^N-x&ao3XKq z=LuhckYho>P4$=n&entqMV1es6hLocIJ3s`0mM920l@F7Spe&-z^hRH`vCUy9hTWy zU1t|#fqeGUFeA-E8yP#_N}1Ia%2ZIP@iKH)KY-I3$yg%@ofsQUnrDaU1BiL5x&rP7 zsZ78;(@Gg9E(xGN^I@KC9S7j|uiDC`8$W^P|{H zw`xu(ZNM7YrRE#}Vy$Wb!0&JQ0h|&$;$Vmg_!wZ{PZ;N7h6fP&5CL~nRHlbJZO#bw z8A{*ICd%aF3J6qw)ShKtl>p9p(_u}pD0+00FAXw@cLGMJED*c>0o?dLa~f2XSR&TE zLb=E8gcC5#ZYrfy8VXW&*~qD+q>o?meWrPnq_St%`IA;a_~Z*zE=ZE1rd@092#O0Hg0GltOl~ z9MD*LD&xg+_|AvY3?SB*VjoKFgIHgi;F46Fi^X|a$6v&Qn4CMyy@H*6RZE{l&aMz{ zZeDm}f;v?iyEgUV^@)_vO-EOk$wyXX`uBA{n!0(`X?}W|(ZmFnom3S{;(51!YKAAv z%zYK8?0o>G_IUHvUS_kWS=6Ldn@b$}33=|AXlm701-nwF_)AMypOKP2X@f%#9wj4s zb>q0q*$e`Rz8V5RMIGg;yY%mo-#aBaba#IPP>hy%d*|ieD4L3@( zX?B_^o{*f-U_F(o2Fo*6>uZ4RiP-Htp&1+!C4)7E60vJ%z&!i89zgVj5OCuOO~5?6 zrIeaN0W^s4JZlynK=gzVaN`LHpzKXV8yP=&Gs|Lba@ zwDY$fxMK#JK+`;5pI~*(w$B9dEn7DkD&OZM?(0NDq4aeyk@p{G+Ylp2KWm>83$M?A z!`-Lzx5D$Aa*s3@5C)kqcwOSh@%qQ-ZhV0xt2lzVXz=9b@orw(s`xn7ah#*Kc>DY( z-Yf;n$K%yGJtWAK%h1+j{UmNW6SvNK9iMhG9Yh`WJ=vV_3P?E&2VvC*IL9;j)~hPrgD}y$#Bkf=H)Ft z;#6ImDDt#S=FqOPZmwA#`}fCL<`A1KqXfQS#mQWo9L983Cf^sJ;*4zESR0FT)-D$z z<60RNgOw%f{K_)FvaNN0HzB3AWs^&~*=r^lbU`+Gexp=`C1RANMi8N!92U}vEhbk? zb+=mllkKPRvC*D$HPV#+{tHj|a1{P=mLJ9^Xb1)UH|yVMVN=eL=g}^adfE9aExlE` zlB^b0B5gEzT~0Dda9c5(Dqvb-b&mf{+nA5U_0P`a zDDP_xsY~76QHTU-TMKy(pATsr@G*7X9VQDqk725p3*|~7tVJ9*UN~!*8zl&GoM-;{ z-cN^S*I+gWct%;OaJ}XaxOu*I((%5_)+|3OOnh4%*07ii-^JaH5(GKU57)RkoIW>r zF|@pRAYqMzihDUl)lT8h)tomYj@JRjXP?)%3rEZf0ir>Z$E!b%DVI00Kqlf{^6pkX zU;M##gp&mv*O_ifwY-ffm-CUh(a8|2K39WX*Qgl)^Q~=t1~JNKMOTE`FH^L{lcf`6 zisXIJIHlJcu7C2%_uCUKB-QkJ<&!C~WPvMj&dz3ZSA|=|Vr{&wM>3k#!N~Y;!9eLN6S!R2w{wwFR z26TP+cnh1fRG)IhHyN`7Rcf=1K?Kt-bTd~u-{uMfx^>9p522taGkeNx*}RZ9l4%q9 zx+6BjgPZ>S*VxUpQZ{zBpP^=%9lQpH=iMDGC|?At0T} z;g|2+bzjXm#w+9%*S9}K@X_|X!+JqNeR2K??NPYn)yepO-$WUHai+uha7m(%(xC5S zT$T0oT&L@_F=b`R$Ft``|I|r`4I$>ZsX4qWfES!T8DwMAO)vO5V7$>4=Dp9g@tu5@ z3C&sFDeSs%L~tXY?7M#v}c7*7WBC3zKbeHF9YX!gDBJ~>O1nv_YC5LiFCe=^LL%ClnShK`d^ znr;-p4V80}PnIDBd2K|I6UOr=r!E3{<~y&ms&8b5!*)aXvYc=_J|0@2e=yze4-NA1 z;||xhx3G%&4N>BgEfJNLR(Uns(kCCrjgE{W?4t~$O>0l}q_TwWc99F|0E>^fUx%nn zUp`F6-h6VA@mF>FE0@yztJzW{uq*Yw*B{aNP;B@Om1RAa7k{4U-M#?&vv8=hoAdto zVYsZqU!+Yr6D5l!nWZABtTRvKEl&Zvk%w8@6H=F_x3+nRfK6wj8LxSOx6n>D9UO^aF5pF&FQ5N97`Fv`A>UtQCt>Nr`~n5k+=HM46zS)_%?@V5gGW zy_D=lILzS#m;O@~y+Jt0YVzw`w@0$7(aG2rML);G-De$u>;9kBy55>|MJ!l(%TN^| ze#v~x8(&kBzt_30J6tzmiagB6PrieZ!^e`9aWMAk7YkM(qZW+PetYJ_}NPTb0xgZ#no`404|}&fEN>pAy_OMS_phUvw*#e=vz}+72o| zv(46tHa{5c^qupQ{oJ~CLI2Ul4qmoic-hW@$x6H9bHfZkDKZJ`(1BlEcqt1BVb*b6 zr~ac!9G(u3cZ7_ZmG8lc zwDC~yWDgPCFaywu_*(tt9~__SmoGk)H9Ky#zJ72kf-KOx={*2fW9b)@ScdC8pX_0s z`wwo#4HE=fy~7_IpG$vSClsT7eEc7My&&x@H*}op>W|^RTh|5Ae**kj>5_@)vjpj4rN6orU500MN#*p_g8jj0zvXlg*?ke^OH{;Qw39-Tq<<4C zuN@daxMmkcZ$1=*bIs)bU}J~yB z=l;gcOsn#Nv(`2E1!vQ6K8xyRvM=aInvAh4F^RJfnx5IDBMjipb7Ekg7oT^}A$IW{ zrbQIuI*(7m++;ZE!B2jR?J<2<%=yN$+~SVqVv}=9brSg6dG<%V&bh0xsiK9Y#>PQ0 z^K5F!Qz_+5_W7nv5Ncibxzb3!eNGG>`xU=``^5A~=)QWO*G|e$y6^5&{2e#vg9X@l zrhNO(<&nL(L81*8wLZUn@{&)6b4qnUkm`l&>|ZeBnMPh3Ey-A#Hg;dDd9KXi2j=!Z zg_oq%@}kz~ea_m=shqc%Zmu4^sWrZRopqI`MUrQcU)~Lt^-1_sGT%@V`r^-7YqeQ) zbHAP-FX~cQD~<4+JAXVld7Dm@;F_Y!Q+noLz@#T5m*?!`M=ot+J6?S1nR5xSrbfBXUF^3_%b5&tDIZ;jF8!v9FB!DT zr8O}4BY%b{_OtjPurum;M>ZWNZ!=1)%&!@9<-Kp;(Npj0M9!~+Q#D<@!E_R6m8^7t zroh)ZtA#&heX)~BWPWMsF0|vBM0{N@QsQ zhAw&SJ~uRymB`oW24+~-+rGZN8!)qU1ItLRivzxV`{bo<;g--nK4np$-+$A^L2MiM z==U}JuH5I=W)OW8#777lnOx5I8DzcNZ8gTJ^FMjM1LoESn{xhH!4SaTL>ler-k+qE zpSHIH`H3=l=fgVD9X*Q8u%?+__NTm~UEK1qL&Ub}VACoxWM?luHmwvev~_iGo2GerNB8N1oH)+E^Ld|>?lWw&mGebtRHX*8fDij%8vOUS z{V8pceXY2A>7#DIjIy97&*5F9-_QDJUtKwMoUCg1327v6({fH(0^p+*WkF}z3)A3p zky|_yC_$<~p&9YTOA-&+*$h%lTZBI=#8?n>$MdC#juZYYn{!%tK1$VG?m~C)WyGd6 z`P$)WbC7d}H4&i5r5%letnp0GLbJ6PPqXWG`dx~~)9mc_u+~L+n;V(zWhvwRqT;;c zlaAY!S4rDVaAJo*Q_xRw#p`Wfm_j3%bnv5&OCmpI2hDY}2majB$O(<)9fh@q{6+UE zlXpB{B-xkR!}B1Qe$mDEiwyEg4;D&hEE(vX>>DK1#6)#44|K4}mjPv;Ji>_utD9R`QAjbM;}ZB{e1RT-5Dcy-Xl`zPN60+W%d7+__^9Ifi(kaI_O+HBkM_30@P z1y|QeM|ozuUq;=|U=TyG&KZl>*+0(Nb>~jRb9~7&fbsd@UjwM4#Wj+adH| z%JhZ{UB{e{C~YPiv48(v5l^L=q;NW|#!{RUY1351aWj4J zM!JFw?i*&B3NFq$yjIL6=Um5J31*t9^|%=pd?Q@}mi!fS_7carIAn{N!y}MI5wD#- zan2x4Q^;?H(u4VYdtS$3zcBA_PdkB}rK>Av34X4VZm(v(PvNX&$?`nIy=NM93qi%-EZ|QMZ^;_%ptm4MB#? zrsI6S_q17wchPu}AsGtcP=;*j{$M`5gw@M+;iUoootHe)eJ!Lv-$R@{&g z@*Oi~ppgypWq<+Q0dq&AB!*(F`77o_cmErv@KRjs#1vlI?#Yu@f-(buzN|$8m!}x! zB8j1ob_tZHT}w)u3+Q4uWt}UNmv;JHMjliNDi+X3bD#TjpWD^pV${999cmZnhS%4( z@0vQjrr+T{1#{A9+psLjjx4qfV5T`r^fE|}m`~@?^N!X)P@3HZFP`58tm^ZQ%2&*X zKg&;;uXnWSP30ZsUGVcsoISj>2GXP0$uqb#7}bFJ@Y2fjFU+Zrw*9t1r{@e$T@ zid+(Xv`uP1m@i&h^^sr-FYRoGGLs1OU->I$kZ*UtVZL~2)g6K=BnMs*4ZQ8Q48LCVasq)^-+Kh8KHym4=K5X9k#X)911}Thz zLiaNJXRb}<@!oKA#*A{#uqF`{Ot(4bwb=H0o6qo*H4!PXAX^Mj3b(2xCh}USS!Ul$ znMs+l)0X7J z1#D~oMVTE_58&<^gXD8xF?kGwNO*RdAKR&QFU(0AjLAP{ry(YPBMnS(HxTnNY3h%d zk~;vmT`-H7Ub`He)K&!vO$Trd6xFsnr{r_}bD!Ta=gQZ=j^*@{$R@PELafnN}Wt`v_0ozddWH6TBj$N*-aYlM4Xc_h>MS@ zu!_w&!Z^#Iz)k%|pMzh!Y_o&Hl^OHQQHn@6`Zr3U#Ve@?t4jJBOB`uF1E$0hBkUJ> zFfDQEC~?0qd#Djp@rkUM!klYt_Jujmx$}jCE0F^4XT|nUy1|zIt5b{$G#}H0F40i73c52VLpmuRhkc` zD2`q1D?GNxL!-6pHqC9F4~;gv<32FOo>_~WA50ORyS!c$|2oQ4x3~(rR~~BS3U_{% z%p0X!6veSxH7UY7+D*oIVal|nur?q(m`|K)LnGNN%# zRo8Jwk2xn3Qp;xT$Sj(!vrY>Er$ib!CqSQ`jER%%@LDoGQeQu0as^XbbT9NTn3FoY zLDSNrOXi12k5#)R57J{d1T4z@J=uss1V2ZlcbT0Rrg+vkYaS!#yJ%;S`5Ru!@55S_ zsYK_t66wK|@w0wyXLw->w|{??ZO#L0Q)jfb9O808*s~cMR{P zWW`JEs9%S}Tw3x|Y;Ml^V7^508lq7!H(Nd1+$8)k=Q{f?PXqp8&W&eH1Zv1gYi$3O zXBS<$CHgZIT6E<)_f;^($x55mD>u@>d}gI1=9EZJ9f%F{RqXc_Q)&#hqxD7qJ_Eo3 z^HpQef5Q~N0A{g2nBo`2o#d3dub1rsm`UuzcE+qSMqTWL)zP?Snts>`yC_X95|EUa zo?)|9y`}N>AN*(Q_e098uP$>@M@r&TzR!@{bT3Cj;=7?BVd$saZ8f>#+~{sBcY81& zg9Zk|3Z|52?fN2yQLvV4tV8pEEd6;fU&hDU=d7i}H^DwPW!#+PfziW90ZVN6J7AOs zo0z6NifJ8YQDF@X<#NfCoa@36SGdt-M7#9dz2v&^s~BR z*7@zuf;pRu?wi#yXWpgFn$az$Y{j^!Juu@cK-yI5gWMP0zgwJ9rcB20&}h|d*W`pS zmtx2Lrs+54%wI-m&U|4`8kNmTCNKNNyle&x>tlZ{0nhV3zYEX%^@Mqg-`>%r(KP0^ z@92doyo5A*FtdS1QFti|&ntAF?B)qhdb#XSC#3=g_5px>HZQ2TZ zOeeBVwh)4lzt)R?%DV50Bg#zn_qQXagKytqCb>^}?+T4P@Y3#W&iW)eaGEj%w!qK4 zV4FF-wq0%Z!hGIQ`i41kw{6o%8D(#K6sJhTobNqYF#Q~ebD#L|?bEQ?etVP^k8viS zBE->Z1I*n#yEmr1_tl3H%Uu6<)ONWVdpMoJAc z&U0EY!}PU2=w4PDrIqfRI)FE36WeBO#(pqo!nN&oD~2XAc{D2#|GQf{ScB9 zStmRXdUMv#UCQochrBQ!o?nN~zc9tF+sXOa;7t~H|Bl(#bM7!DP(|LxluLf?e;ZcZ zW!FvpzO@wvQ)pxm#G^XIobW}#7DZ_|iDE138ooRF<4a`|LsbS)M+AyaL zcAG<8kjOfc!wE&!fajcb4?z+Fy$S6_qlGQfhhy;6wJx<;v4QTtBh-}GmaeE z2GhWwZ%jF71;6-toAW+5vM!XFa}8zIO_E!@$`FyCS^VPfy7&Wg@@HB5GZmS<$+-p@ zfEBXvXI=*#KJlgeE9Rt823zsLoZr6jxq^QNTu$GRezwr4PT#Oj9XCk(4O8sokYu@M zTKk~tjN6Ev+&1;cq0K(1&}0;TTl;p}te0)GZ+z#=+(-jchD{^p9FqI;xr~^T?yySd z!E_coInAL(m$z}*pKBOh?D^qt3>vkaFZ05jwhj0)kB=~im~4F+$;U)V7NQ^5=3?zO zhXHNdLZ|!-ht$F!e=y%M5)Q9dnzvG3Ozx!N*nSz1tA&Va;_lcNk z+F(!YVuv{g7N*>8Y)Q!v}y zCcf31WyWbknFHGJ+iMp&pAFwG{lgb!zF|&#-j^RS(>J;c<|}Tqr91Mxf+_J&XTX$! zwxP}w2@y{tkHt*<)`>c9%9Vpi3U@6g?Z8K-*jrqiv{Hl)x^WpgorVK)Q>&3MP}qT@Do*l$dU1;MuY|DUuk$+jKknVn0Hz|_#lIlcL}o^#s~;z&lu|JOU~ zuH2DeKt-sU;xc&e+0pNTT%~X=GAUHLiQ8&J};b}eYB27()VS^5Hg!59!>v^#>%3a@ArtJ#FIh~HpBpjg^Y`F_l1w9WFgNlUVxfL7h|4^k5q#J! z&Wg2^v7zSV{LAEWfD2+Shm%BmxkOlHF3)80KyHZC8C7ssJ%Bsy|5 zJL*HaQ_FE9{V+L*$TYC-s1NCk@j3mfZls@Y$cc1AS0Hr8wUP7cuCsHnUuPqDGw5{M z`^LFP&Wnwma{d7`n=|ra&=~A={zcwK*KSSxC*yG*&mfr0*^9;wAtvn*rylG^y6n2P z#B5d{?O}pbz0jXAWt|RZ#et5eH3xnv8h=w_D2yXGGGxMp&vl`{0nM&(2b!*)=9pi7vB_2=A0b5LS~YmT&HvH2kekjelo^q z^A)L&;>J1;a%;!oV1C*=G2=E3U(S8PC1TB8V5|4*4{Cxi+3?$gB4@b$~rf6ab%CSSRyeE7bLnE`pC)Qxsm?EWYNR}CUc%q z4d`NKa;md`WO7QG6Gi{X;{=E)drv0bK}_!5$u*kxKAn;AkGS`(Gm>+!oatV5BlxHL z>0l1Y4-uJcZEtITdU9T5GW5}tk6?X6&qrXc`=pC?kIM&L?ABtC|D0^FwSE^H%(HE1 z*G=}PQ{O>d?D2|X(_%o{L+yaPP3En6oGR`4bR0{}hrG2tOmG6p^!uAIDMOrCWM&Q| z`#4`!Lx183c$>cxpU+G*;UAHOu zigM?j?p@hP924b3+zSy6%!930iU3})e zN)wl1J(uLyd7M?IOqLu-!(Cvmz@(2{&Wf1gADMhw!K9t+$dKcpj$>Tr0n_e%6BB&$ zu)4UJGxFq8qg;|4NQ>FcIvvc0#sqWDo^$T;{oH3v@ey=yzNfu=+%E@*PdR%=E{TrY z&_^?-_y{IuDqIj{o#V${R{YPdlbk(c+fdd?zT*152ii7auxQux*h;8zxTf8tmp)U2 z{Sya=S`FRZL;7K1evI4bVaVV{Vs_Jam_3Y$=?+f5)X6?&NP32Gk?hGP| zSLMymKVn``()OoxU}67mr|kdwy~2#z*PiAd0MlvC7$f5{kvTl3#+H5X6F7fwo7w2z2_JWrnh(IM8zm)q~wywWX_XF-Z~30$*D$d(@GNw_BY9n0I)z$ zzg%KJ!TZZTzjyhbTjyRMFl}!abMEdLk)vkM`j~X?*0lG6y*nIBV$O+RK77w%Fg-ah zn9PMsriZm)-Zq%m5iCY>fRTBCCLYILiV1n?-W-w0-q4Y~a?Wq8zb6Od9k@$QFU3f| zI5HRR(tCe(9BdnDnCt2z-g)>(PkT?;d)(Q3d%!ey2xe(an9iN&puzj5Uguu*xp#e+ zyqXc#*v^>d&X;d@9yOtnxrI;n6KBN!jP4ncpJ$_F=Pq3r_3bW2#`GslGlwY-gXx|7 zgefva+ac`n%2_W?ZsGNNjd^HH_J<;-(;q5wi1K|}Kl{^m0EC^4{P|p5`N?(mwfz}j zGw{9d*`I=G&z<(?o(vI8=7*Tx6oScq!A`yQ^?QT4{GP=0&YeTPBL{~+ozZPGOtVRx zGn#z_a2HAEGklw&GRtJaG~bglSunltnZdEJ$6U1CIi;`h&3|Su#+T`Lu;)Xx^B}p- z0-5a9u2%FQjs?AaPo-@70N&rTAkV*g`Ly}qI_VoG)6W-{RGax$N{b! z_sP5yFaAzWwW2;QR%amhE$6*~+_5#uyTJWy+BcN$#*oRync;W+USn!|si3ZB!gOSE z8-kfvnA1Ar4rVA8Q`fc>a4Zw1$A4097IHyZ=N@F#^-MzxyqY`o_KBVOpIzq~Rn&ya zTo%txZoKmybAztC@ccay*RGz;ka?F1a^d1d&;7wnSm&Nx8V0lIJ}1;26Q-B%jktC! z;FB$;tP{G}!@PLjA5YtnUuXH`e9+(A;MOKSSuneq;U|6eY1=qldgshJPS1H*r|oL( zuQPLD{Hycf{u7HYNqR zlz2bgm=x#KPMEsxOosgkrV~G!FpBUULtIgrVo5oaRytusQeq#4u5PsWe>hMbQF zbDj@!)Q7eiKE^u^&JOQ`@>9RfT4*ODw(B&wjsc_RVxTV*bS?*DQVDs0ew>Rrkb-%b z8Iy<`3Z`d&3MPjQ#9*d?Fc!HLmkEqX38u;6`5`DwCzpdgMPopXSd2P<{$so&GA~^) zO&#<@yu;(DBV_W4PVU0o`EPu3nqp@Xn=qVJFqqC6Wy~RqN#ZiPwuOF2fz438{vm-} z(9!DZesc27UhM3^aDW+8zxR)^vk4P&{^5Rd4n6!$_kOY;;EY)ePn!&;_ueBhCH`*j zC+~dUx}W5JrDoZ@cj0L%=Ux7@8q8?t=^h5tyYr|sjqIgh?aE|V7|?+9^NCqMc6 z{a?%nI~o0~1k(8QPW}?k9pBT>Ut&CN!ZdP;9E)IjF+Q=E*z4mV zpMkv1PCf&BT+f)+4l!|U*A5X`hyL?VF=%3L*$gQe%xK<`wHdM(N1*P=>`9U}S2@Lx zXft>{viOcNZJR3;@yu1;>#UyN(Q)pfqi^BqFDkjzpyL|+&F1DFFy|z(J}#Obtg z<2*LaD?ZFv@%nOHNReN5ff>GF2IlBS>BD1sWL136t^PKd_Gg*;#+ZC>VD8lZ&zPu3 zxX>4vTXm)ZGNkftR$H^oGm60U^1+(uxUzmns6UdPIc{$s`ZCPjdN?Cu9vf$rn8OpK zKdr?yHBEb%i9MNv>CfaQqHr+_5l;}GsPWD*4TE`+&%1_eTmtd*V}t#&z!;9-lA|-1!TA zfw^(+H_~sN7&-fd$$l*T8z%C>F7(B@)8F)J|G@<%*4#Z|;=S+n&^V-*0x+ZP8$(%# z@9FmL6HM447y1H|GTG}R0sWp5XAwqIt6uRvcY5AVn5;v&(4R5sBlz>q4y;ppAtwDj zzs)H!`B7+hM9e$f|*Ij z9xtdvXvk*a&Wz7>wYJ{&<7Q0QA;z8;%(R2qAeSb;*!mru zha!HlV=v8^wCjw2M9fT1!1Irgvp4Y!51724JD8pIT%GH*oPf+3fiCuW24d1qww!>> zL%}<8IDzxcun$jKzayF3f^&D?(To|_?_JipB}2f^pIRiWF?mLH2NS$^N(XhE>61@? zlYOH689-bo?WJVqvJo?3@4@+=2^`?5g&>nnoa-71@rP${`ZLU!g_x#47%_S0-5I{@ zk(D_E-RPrh#76uxZ`aXB6J}iMO=5P`Be;4qA&30j`&jLLnqR!L_X{cFWLB8CpX3#H zG0W=QCmw8UoIC5a&kN9&cb;>Bq2t^+O@aK9=s4SFk28R%DC;JfY~~{rBa^*(Jric4&t>Lb*%?6ITp{*Ton^A|Gw-a;gdb? zLgpKC@6mEWyq}CkdfbKRql0_5{VH*nBwp;=OT=W4!DQy#*}1D;ze@R@)43Zys zO!k3HX^ly{PB;NiF4bYr$bQdm&dB+m0X27tGnG;>ITF(I7MO0&TiOhPv&EyX?|9+> zo%bI2HUqz>$yY=Jk3LKxbzuQe6BTS*}=rQ$IiOlVfvKHoDpI= zc1UNhk3sHYB$K~HOq{zvV+DI3oQE=W&D}I(rEjcrU>-_3=yM%*Hbggjcka?b{_{Z2 zUOG&_%7?ivj+{SG<8V4}ct<8Df9jjPg-M&?pzZBprgzNKjA1+uT>ANM>lg}SQjV=S zVKSGaI$Szq6V9ElkV~h~JJy&shO&oATd`VO@k=`NTVrzX{R`&l6+sst#$FPA1WwhRu|iw%$PQ*S zcWDok9N=N~do=5G?2v;T;DKIVr~EYElbDnt4##pJ4=@GvPfj7M&uC-sr$vKxhEChY z>Lc1@kT?7Xc_mlZHdzcY@Brfy?=0?8FjdbxL)t1Oxnqg4JLNT zWP{ln2V0BbajH-Dr>PlvuobklTo3gK*4K7y8?on0bTAF4x{1m9;-Y&UPna9> zGX~_>T~$Z_VFpvz)9{WOxS;0EaR`C>oiosbk)JZRWrv?1>`Oe@mv|KIBcOhBYrf2s z=Rf6?8vgTPCbF0B&H8uA)vSj5mHefxT+IoSew@iYc*v`C?tDXT%#>Hz>>LN$43u?V zjo5@qKhE&;4|a%$$y!VCxq4pb0q*!*Jw5nGb}j~VvG_+`t|sr&l&fiH5zibC-zO-@oULba5C$nJIdk-BvZRk^v zEcHDL`npRGx5KNgMh}g9#n(DbuQ{v}xg6#2>iA%Xgf4x|qOQ|tPm-NkFxT%DrpYn; zHVY;U&OzOcFs~+^+0b*w4S^0BY z*o%9@)cQzftN=3yucwn>QWqb(pTIP?g*_V`xpdI3JJ{pe%-5d!gH^24vFkXKZo)Ks z&zQqFVS2q&=x-j3cN{tno6wJXvmXn4$xfK24+T&#YNo~B;|Ck;`u$%_ zd*`QFFvN8ACf_^z^pRkHn_y(!L+?H>SCevHFzuaZ|Kz>4W+$f3DSes+s+m`7)DDJ7Jo;^l84#j486N z>O22wzRdM|jcM-E!+aS>A4S#|N9jpo&j@dm^HAKLx3c#{UuOM1k@M`!iYt{ew z+J+OT8q@E+56q6fTcO)|J-}q|eQ%CKB1au*&qsSdq2HxvxTD{v`zbzxu7{QTDVUyb z82CM#yiIM_fdkC!h3Mp6$lIJT&AIb!64O0*iBnMH=|V4knM@ogS_o65HNF=@Xul9@H0|BhKjp=a`7y6)`P-tAiFeeTusVKe7N zX3m(-+CP$W@09b7?r5wpZanv@z1{CRv&m|7;woI7B;v&q;8lJ!S1 znO@wVX4d?{#Cy-W2K;Gejq^6A7)qnw)H0bd6#7TW%cEwkWy~_`&8$;q){KpHX3o8u zFpV!`ViO+cAB)Tll)MWa6h?q+%)X-wXWW^Dixv57?hOGizdH|If3+}1GpegInz+iob4IL} z5lpK)>|9_^cL-*ZIgI9vWM<8V4;xv_He(vyK~7+AmTMN7?3@w(qq1>E8S{_+U>YA` zXiQhmOAp~l`%~v0OtBuGyXU{NZ($-Qkj$JWa{g)S9ffK!^&H0OjEL!dPs+N?y0cm$pPtIPhQQ(Xf*72QxneWLM3b>%)e9s_#bcq?wT;LE5rpGHX))NEI-EdaY(|+r1 z3MS_QM-zW1Cf||Et(6B%GY^HFs$jbLA)-4dm&^zc_ z?+E>u&X1t)C*ue^yyEqHjj4UEC$7?~y`s-m*`K!QJQn&L!mYV|qL`l?S=VFk{4}qJ zac%d`4~wZ~UB+zODZc4)mBdWzcNAzR<9oXAi1W%POf#2FcyD4lXEb3lm&3jzVuEAw z-;taVF|C}>RbzT`UNBQwzawJGtak6tXWH}32g@eUO5&Tq^l~*b{bIqixanxnw9kB){M%I}==y%?E+TPxsPY;;dH?%W=T;FiQq)i)*Uo4o+U-Ir! zdB8NYab>O$F+E>KFzFX3Jqvr9E5z8Db4H1?uqRA&my(TddcF)XSts>iFA*~{rthrt z*9hc?*(pD}?z49dVTjY5W%qs-(H-nhTmQ$nOrYLm-@>Q7HQssfHg4XU#PkKz%(+9) z#%WfOt2=0W7uq)eV_s0K7Sq}`pYm8HuChv9kKyNKo)qMg+YeAURmQol?u0IVg)w0b)w{;ThcazcDgB@8f+wvKZ4Kti?NI=m0*>u>Fs&rPEdAC~% zvoAnHMNe&PSgPoi6#|eAXG|TK^zUKar&B*244`S2@G#uT0Ysj3LV1y4CZ=kGovMg~ z!3^-^I&?X`6t)xdOrfd)wI4b4YWf5yQc-_HIc2;QZ!jA3>H{h?lK|>Nfgwh~<`gam=7gcmV9-@!ZQNPp4V7ojsbWklEN8zpb12f@J8v9{ zbn;@OBy(-520YeUPXNiLnu2lx#7ptW70gxnqAf(-H%h z%FEzYvdO&ZHBLaODRlZzFnlXr>rL_BVF0~m39M0sJT#LE1Tb#^vMCJfQf=D_*w|9; z=@?7wNJv0)4{I@iPOT>a;rL`@!9D=4SD3*SW|aG79kHCMJaH&a*MW?Hr2v|iz#Q2p zfNKFOfJllirst>tvX*^)u?s?g0%)6E1p~OgHU#9D!eXj#1#qLoL;hYg>%fRB=aOecU33J0$2`r48F|E2U2Gg-{ zezCwGW(MIMlIE;rP$am5<|vmCK+v9lA>lVzYc|3XJ79^eUrj@AEK+~XOdE*MFYMy) zOp+Hs_d?{+9L@x2ysDuA59c$|#XtwVpohKF#ppIpdpk5(;7HKf=Hnf1P2(QX|_W(qM zWY4=V05k+IopGc9xMN=Ei~}&6xrMxk1ax};%f(K&25f8Zo-C8os9v6)0Gcg#4d|^< zgu{Kx-Hi1X!1jI*JF0~{ikiEzW;ugJ=Hxhl-2!Tb6%C*>IAS1hF%V82ri)U*wUMb% zYn3`s#7@9)7``ARjp*dS|4{=VNwS&S1vSu-liVsim0AN(QDk(?oWTD4lJf zgpIe6vBRY3eY1;1Q1fp-fsb<(Ajw~nJ-Waorgh4 zPLUwQVyG+S*AEJAXj4b|1vHoxK;uGlToD1?k_2c|CJGqkN1;RF*i(KCnG$e4_-SWg zBI_^`Mpj$pmrRJoReoIq8nZiR4d@Xi*m6QLrPWoLc03~@PV5k)Zze#!Wezx#0EXl7 zB1bPHB4Sws5_UTs8V7u#fw?aaa+dRx%8r~pkhd{IYO{$WT6RWM-@^4LX3;9yirJ3T znyUcoMa*8mH<(5+R*mVTsD+Fc2Z5~=&%f58Q($^!)EVsrZ}gu>WXBR=?-IpdE7!ns zn+emjVz~M_{l)ao2wd`obYWUbi|fR>J0+#p?-gd&Z73$!nwU<@hz#p&+Pgg?j%^jM z)jK1>1aTCiZVB};Ue=+Nr|)^N^~zz?qHWXX@f28QhlA8@Z*Txgzg$OpAXR4|dvX}l zSq2v1wmZ2I9rCRsmA{(_hMy+0WVj#fXxE`3qr^R`6b1q zgFFCwoFjN!q&ije3{ed+O+8pUNENZbiqKuvDPB+GUDmRqBI&1Mz)3aUf~=4!HEXrl zUP8db0!2o8eAC znIdUeQRX>Of;m}4$cGg`lQ<yu3A0Rge(kkpWP=KzaT6W@J$ny9 z9b|%Lb0`9ci|rIlrV9Y zMw(_tzoiO0tl9}RFl%=vQZ+aUtP^OaH9ATUrdG)g-;GXn93pOKy2&Z0_fzgDRh$5g zHQUUV9oq(g9i{l)PK+Yp@qWr3jbQ}P_%C)`l(WKt75>J|U12AajBDem4vUBE4FR-o zIT=8Q%OW7#&K~xuSVYIpKJZp1NUH^G(046x!U41RLb@=`gcrJ3(hb{juO>_hVp-Rc zE*sryCxDkR=_9Zz^T};7={26)!jz&3^I`8MsmR@XvwOE^B-T!QKcj)*6HncaR(xnv zzy6qFB)6r=6(gA@s3US=##7{4Eh9$qhO<`S{ZT1c#rlxD@0d@L$PQb=J{)UHIKii` z4LoZxJ`@9ZHZ4-AXo8x24(6S2*|Y>?Ns`Sg`VyFzLF)u;hKDHz(BUH35i_A-mS+1K ztnP+h^v&TgD~RO^z-nn*914o8y*$f|*Ua{C*<^K-aSRM3dzFj`(=w~u$wJskweLun zLteu}N}nNK+_?jX2DHAF&A@Z+A?Fw%E%G4)kK&8^#c?M&xEO%ex3YkqZ-uJj4AuYO z3Izk`xI!rT$au>So(p{|T8z#;M6c6=6+R@)QAbm!IMfg#(*-FP5BY7`tk7Zmp`QiN zdM?EPI-UywL3uyqx0MfDuIM*20j?!>dp{HcR(O98`E3Lwt>I+q45U(_z|1ClJ*?0n zQ9)}6pf%&|wQtUCvkMj$iV=bctO#C&XxmPwcplqdd&1iHLWc+JhSP1Dq#%S%yW8^((9f}!d-QO4+yjFQY>oya?811Ei)~K~!$XhdEyxsM%S5l` z*R`h0L8!7$UDD3BY;2|FrD4Ruy@LP_vFkHJa5*RJ-D@o_m~5SQp+93D1Ly9=-Iy+t zK=ua{v*!4Ws|G*auVCrKVf=c?T&Ky|%E)`;o&VLzE-@3{d&ZdfkaZ9tvF$4Ed~&4R zpLMnsCfCXG^G(czwk;R>^WH;&3~|0E6V^iN4rakR+YTo0d}5lAslj+ScTd($nB05P z(Ko@w-o17cfA(HhnB03#;S=U`KTZ2M!DPD$?|W9Rlj9zKCBc99KJYywzNaHYCQLaa z&8JP6kn>KPksIk+XIWuNs}0JfO-wl>&7Dq|I3rgsb-p8}+u3&IY#WG-z+aWkI>#Ve zS*O$Op6^)&ZZ?fgAj|p2bMV^snAvlVKBY2W$Go&E; zoq08;&B#Ga?A>bv&f>z$`ndM4`J4<-e`?|D@j0jknfIQm-g_{6_hg7*%G=aA$`dAK zop+aLD{@?;#hm0)-@>F_*Te?Xx>(vQ!&Y=g=uVjOHceNQ2@`MAp~!Be>&~w+`Hnz( z?_%=3M@`s1ymycAk6?M`x9POw3p?xNn2-4#89$CPdFLHXm~!W>Z%9n)P4C>J$j`dM zlu>K>BPQ>B)a7%6nRfJM1Yt4Xc{4_Veh2ToCqp7h;UMR3+Sno!b!wUD=}n|+O+J@x zflm2Jz3G)038vg7>vLI|?AkVm$dIwbjQpNkew<+PE=6M}3npcVv-gNn(dmqWF6NQ; zuyRI@uN?>PXA@m)WF6%aTY9>Fak1ai=(uF%l6OCuj~dB`L~Sc(a8?-%xz~y?NXmXV z_&tpcR-lVfiR!fp4F~d3$8m3cXfKY9-YS~@dqWgD>eM+Rsq1T0AwH&Vi4HqSKseb$ z@7V&nV>5)WiHs-()B2oz4U*xq=eN(8d_THMc;bM_Re5)vHe$?WiHQoujLI1olcPzm zn{(~mw9)729geVaxm3ZVZnO82m^E(P%fOK~Y&CMdq`#Q>o-)qIkw+7zL=w%LZ1&up z+YYy=BSvoKEmc&}Or)oiu!4dOPE$04`U-|u6%1b~PHeJ6uy;hDyN+jYl1;%Cs*Z^u zfJox*I*M-re}63F8AAhVBc`GU%(Ox$af*O2UAt~HIRTdU6`nVo3@>`{g<~kowQ#_v z3d zXH1TjGNWfLrYp}6MA&9boo2z2Z__%Ry*G?op5iV|ryX2VaQ<+7Ud5eYHjZPoaTj9J zS8?Mmth$>q4X1DYb4T{F9{K#MEHT-xR7TIbn2ZlGfvlSG>chlHys>8&((jB)Sz|Ij zbZlT&awvs-hl%0ISQO#P9lg_#D>1FJ>Aa$=>*$|#dR&iSHjE0m&=;8SD~5MJ1Meqe zqSfd}oY6E+%sV5F&|_L`sG933wBO<_Ig8V3?nGkzl3hBg=4A>cJjZl7TJqc{?~=rB zwW6H-bH-U6zhc6qy-^(=0X~2iYrK$tm`7b<%BU5#klw^hJR>v0gqUpa?i8|y%6MC0 zO-Zv=6*Vju`ZFf-gT1jmS1ethk=C1uatUYT@~{)8#O$@*E|}CE z-q>A{^V1m_UqIyi@eQ+5e(G5Ggh^h;ks(a0pU$Z29)Z&cQl61_?)5>=Ydd5bK}tFA zRlhTCT{t?iXqo&m-p0{2A)#GtNalW$E2q!z>CG&$M&Y$}!OX|8ksN0mveXIdyb6x- z*o!d>X5rqmPVEv*^6y^EzEF1*a%b6$u8GD5^X$*e+?PcDC>y_0+PgF66uD#? zQ$1jMTnfACPUjwV{PLq*5=@bGKlGQoV; zF3hsV)OUUpQ*7Fz*`x`Rc8I6nX?u(PS#%c_8SzN_(-{pCSa2DVbjUL?QI0~VFXM5N zg85s+ovX3JyejC^4Zid{I2ySz->VGGhaj(lqo%88dmov62;&5Y&LNvd4#Pk4d@hbb znseQ>4aRYIQ?8ra2ZWenGw3lh6DE8^j}OVr(UCkVgZYq06#xI>S znlNcIB;By{$!754tZdySaq9<68@JxVOb6w>&S@4*iL*L(U7)NBwC4?9H{H*;A?E}0 z(xjs2fmgg`NCgk?@`?#l1_HaWhoEhShWpvzBQ%foZHx;xG%YQ~%q|G1A;JChI`eT- zYGR?aEm>oG!w`Y!u9D0eSlSa)z4ob|X}qs8aR%qKZ(Xy1(Uu*Yjn{;clkNhhn-rrp zrf#4cUox=eMyTu@RkXFx%Du{l2vPHH`|n;{-x8U!511(OX~=$XF+0kJLdVT4MhiEv z77bRnzfMZyCg0OwBBP>#U2!p)0FdNsDh{YYuQ%ATEqk^C^FHd3o$E?FDLccdd$}Z? z98gbuL0Sh-m1l7W6WnyE(Cfuk5hcD#RKR$#lZugv(l_hG)UQ%{GI5y>;kGFio*e)R@l3uS=sY zlEp+a+SUPaO#2Bgkh+qJb(?wPYsQ@MF&#uxdhUJ9iu&A8k?B(m(=GCdQ#_p7%}Yiq zS!^-EEQl<2Fhv#@c71wUCopk0U)EW*kgIw)TSEX&gq%mvQM{KjZCx84BHs6wDTc?f z#FWpufq4o!-gg9y9x&mw?i~>u6JaCyDP+tG?~p0lKVT=Y!?-istrR*0O=PAH z5;c%BtvcuUEaPI$n?nG2oZIxhWTou<=M*6VcL40tXR zIb$(-k>s7bt_ulsI;<8`e1Z+kNe5L-Mm#a~g%=&fm+oBnDG_42O9qo~z3yPLA;Kh! z4JK^kNfx_y0@{bvu--d$Mm~1dIo(ge)T9C_G-OV?GN~T&HfeX6w!fVAfW#+n+QW_X z+k1&i%me2h(iY~y@5yu5BO*oARoaJZ`mjt*EBYF_7EuW_S4 zV~Ss}v3H>mXBSfk3xq2ev)v4&)r zppE*dO!@>n ze#Yz%h4tR)5AFB_w(VTnn9eam-Yte|i{Mrmsfe$&seK7qxoUwnd#$5!07#cW@Em)XZk4kpdm9Y2HN z`YA?aipeBgzv*W%Rxq8B#-yLYv;r5C+P&~9=^?O_x!pF@W)UiStRdlHiJ##?A|*b{ z0qKg3miaMBq-|O7m9jHy87~PhOaO3sw5I)x2T0Or@f|WwY@e)hsWpVvUvKh(Z8&)1hSN__ zK=6M(rvOsDk&SDb(GM^XAb*_AhmUqk; zk+U3g6-<3AA26M87|I1BgNw~f@B6m%fg5zM_lIeMBZHVw6HX;XlG#d$9<`aP+|Uth z!gR86kn6$z5htR~Ncn^qs`O-)C$1^-Crpn#f?1S~K;2_0a;h`D9;df)B?Z}di|k10 zFNlQ$&KMeKn$G=(m=4IcI2zxiX)i9Av<%j@3HKNLeM@nxOk;Y|W*o8Xxajxl{#$2f z+DtPuAY(C@>o>{hO*`ak8prp`Dhp>Ch-F{~Lp&g^*O(%D^d%09FHO_A6H&_STE`~J za4X_L3Z?5lU>%(~BxT0Q_m73bs1wlyf4?Axz;Q1H9r{W)6J*hGdkZrqBswH^`7GT` zICxm+T5^bvOaxTo4LTBjkCPt8(!dzxWQ=5koj&OFxK%w!W@=5o<1&$pS^mzP_r%Vo zDWQA!iK!i_PwTwz;^mlf?>eLS8|HNsKg>u(CEMUV2ehVhs_Ajo{irKAoHhJ=Z|Dnq z_(t}aE?w7jG{`hsY}KP72J6$=8K`taxqibG%Ak=N?uK&xh8Y<`jq))yJ^B%ojitiK zT&Jn5bWyG=(QM z;s0D-&yBhARaz#dV-dE-b>_0dY#diFwy@`?F&(fUf@%C8hL>m)I@C@BVJL?Mi#ANQzXq^=lyCKyvtd=Ts%Jhr6yZY(hfOF5I!( zFKhkAG`1$!$uO8h61GMkh@^zU{HNtd~X8Y4Lo(11N*Q8>Q)2K+EhO{C~z+$D#Xy4W|x$Qex9414Suy`sw(x-tJ(+XnA_^8XDc z=6r0~HkX~PZEu~6^X=RNCzzEklkYU4Z&e&US8HyoO+skA@0{LNY@LvmPQKD{FcldMwV z*zq!S$?_zZpx=GD1YcViKa2TMF0qGdqU}9QGv`q8JsbA!#2*sRUD5~)W@97bu!ku` zVj<=#LNxh?u07wl_hW_mq>r3XXcRkyC9%VDR@Lm?38;6b2@1zDbUMz*J0C&rm(KXN z!TfgTFMdjKRzs(`e3T*Nm+r4{VXpY4EmFtB;5R?J-!e(UjRx|Yo6P{(6&Jf9O|+4#-14#;nUJ=E{J6@<6YrFp zIsxnRi9>EOKxQDno%sC;;~Z@qCa3GGhYfF-HFCp{-K+!N2{snC*q6+QVYu#3ykDH? zUW#^2b$@lQ#T(=$(oFYf?Tc@j`U>)in01H+-phW-D%UpGo-YWVM((A7{A6-5;p6@S z7o_o6zcBpwe&ZY#9hT(&;SStStAjl^3>vlyQRbkXFt>&k*{C@qR{vdS-jyab-uRR?W5U4}7n+mp znNi=IL?UW5bQlevjE$m-KQ{K!6FHg*g$5~LpzJxJH0`EaA?_J;qKKTU(~_- z)d>9#72QNnwC?V8or&0yfyoSW3pUi!oW>kfosq74JxmxM-LZuJa}pb`D?4A}6H!S$ zaK5<2&P8EeeafAmPxr;5IJxi~VUporCbr43aAg|}X`wgnBU=4)@jNu}mmjB#4PY6Rl-m82>gB$t2)xy-PlK8~z2$H`d-HZRq`bugmK&&rs0P--- z`^#T4X_dWJfrw0Roxz-gP-UYe|Ie<6J1(=r$yblkIikN5UGdF?Lfi0Sgwloimy<&NFFOFR$!F(4Z@(6Eoy4)-r@0j z%V02yF{`n{?Jk3}^uTbzVp^j8^(h>%itAt59=;xCtRD(tDrs7$H7%pXCnWc)Yreig zo_-Xf?;_WA>C+^K3F&D^1oUs2^25|*3wp!DPF^oDWwC(7k~f2NZn*Le$9%#p_K%s@ z@W(uJz8|Zzu=aPCUcoZ%a!xBSWD&h#LG_DMp|f&OZI|D*>gD15 z^?A%7#pBP)95gr;H|jGQ?6Bh%?lhJVTR9S?rtWqw&jHk<|H5z-DGqMA#Ubf(Jcnv zw*$zaSlUN%}^!SF7+oT;)!G07F> z?an2UD^mLk4mJU=hyw?UfG^CX0p7PGz21(__bN1_M#D~#X5+xk0-*E3nyJ@+@tmxP z%6a7Td)0VR-(T0B$^b8jD;AC*Jy5arI8Jixyuj?)h{g#ZT3A4|NpzdqFIHA+#*^_+e#loueB8xltp|6V=T5$8`bXWKYx51XT(Lv+J@XWgQlZaYq(4LDs^Ef=k`}$ ztl=o%Z`@}%oN9Z;OR0cL%c321zTqvIAl$vEWFB;vM7C?ZsMW2L##32s*rL3Ng}!}1 z-W%n|CXFTDhXan}U+$%P3*1;=L3R2K{0N5=-oP77r0rRrhmHr_#uNxP2d}dm+fnKY z4;f@}1Mj|nSCZTfr*s)o`DhC``LhERF=;wpg-26hLv@Ql=6ln1{pqi{7uS6Pq(n`G zs6kWT&gnXknNl!4ww4~xf^W?uPhm%;LSNY6(eQq!!&AmI$$P1ffbGxSbJs`LKc}!< z-!{e0_=$WwoqVT!MaPhbdK4X`!Q$WVw#I6OZ-V($K^Lr7WLH<@VpKO_2`N>*wk0Iz zslx{KAY(@?{{*M%&?&+dbz&71|xHwiwVefH)dv(z#!fM?(b~jYWeHc*JXrhZh9O6x>uR(JFaZ zAq}TfJz2|yT_LKYE}(!s18L&zo7u?{`7(GoY%;;#9iLJX+X|2+pc@P1)e%d{;Nj}T z4ZzGcrqip|^&(hcem4#OqypC!AXd16Cwb2jnX`Cm!|wWQR<^<0HZ}iLvk06?@45|~ z0C!@zXDoTPa;Y_K+GwtmhIJowg1XtDs6!x)( zq#0WVX0O#~!dRamQ)DwO7S7gWxJJ~}-D1q)jSgP#5SDn`a2Mrt<=rr@VBqKqY^;yG z)(!2g4{aPBJhE;V*>=M{2R;e64)ES6zyJ7H!I|x@@z@1F*SFQRSFpr>QMs+aa8usV zFxxZ|OShK%WlCObDoJyvy$x!jxKZ6!G9qFZI!SZK>;xTEiKlh3h#2@4)v=VIIeF`J z@j~cWUm;uOq-BBB@5IxV98$7qe}u6tsysnj*lBt|xx6DY_SfHkGMCY^I! zL;e6c)l-u?OS-Js)>C({C~WS7#${>~_8aD0=${A~|EFcL>TimWB(0b=DdJ?{z*C#z z8A*3hEO>ygaHQlLGr|oT4D44hO4Zb4r_aG;-fZXLp;u8lnCq5IAI1ZR!7(+?V~H8# zo?>KP-*3{$0u#l~!^sjryWKJ&YFY$Ce=g{B*HN!l8QC>3GxC>Ax5$pj1}vrD|79t* z87!GjT6avmM(6!^xdzthjqYgB^06}EC+Y5nwG$K7=pKj20aEvhFHG&?53n0!ysxvf z7$(ct)M$c$7Dk*!uwOml^zS*MdD!5poT zdDBhCckkwWoWQ7b25n-@>q!o>bxL-x@a2Bul6stVUI@~nnMUrQ!Iy3X(>ek)7OFuU zjeTE6LaC3(?yu=wk1iYKDh z2bA8Rk(-x+7LleKIb5w~lT-B1X52nzQPiXY4V`ZsKrGE|V3K9TWrxFwkL8NE>$BwmT91bjg6!@#(Q*NFl3W_({dV=sWO3TXK_oHA-iIzD|p-7}(k zFrvcKqvy~#ff-a;M_L1T*MK6_;AkI?+vUa61=$R=Mu|f?&#bc}coz++gSWL&Lqg{s z>u(q$i{PTWb*Sbq?QIl_}--%!bU^;ewK!#gP3?gNd11Wnarjt*R?)TC} z&}f2gS|#ia&+kqMrJU>K3F!cC#Urff1y`L@Z;*yfo}mffR@!d${d}$p@=I+JQL{I= z=l{HA%dkTIhJAzsW&DaJRsB~j{|%?}(*D?2jsiYFT1+hrR%qC(2ZyZusr8G2L+tx? zb<(Qk27ZQ9#UD;=5cxra?0wdJWJN+kO-RXiBw|hU90XClkeF!_AsFSDL@==~(`tc8 zBP(whSukcUBj!e2hG}4Gc_|Y$u`oI>5dh9WF~2c`dn*Z}a)~@)?s!fk~Z zUvem`doAthCvL7l1y0`4&s!)Pei2!z*93s;v}8if=r&D?umn7#!j^tTY`-@ zG=xUHrUFb`B$&~5kX~q~rXOw;dj06CGuGvv7?SG@M5yb@ZZ%y~`@KlMUTmYkps4Y>pvZ|9D zwu6X7!P{oM5VgK%7AJ-q1@Rq`t!q-0U7Lsu*4XGeyOe{D@fgGa zPjZU!IPQJr8s()ZNyhBo$#?M-EUIT>T_MtUk$`}Y$mBU9D#;j8ZzmBIr!*51=iD`K zxDM_|1mdr1qMtY9t&wSnVTs6U7e*~zMC4^La8Y!!KtOUI0~gUr4Pm~0BJommssJ;U z!`Qezx5pd*l^CHx6e@=?LI)9H?%M;t5SKI}JvN^$!FMc6L^grmiL>6GRh&Xp#mt33 zzmO?J<)y_?;tHbiuwXLdJC5~H-_B(GSAu*75Jt1a_||x2VVD|O^k_shzi!a^o@)hf zXspn{UojTEM(cDY(;AMM?XPf_zbbmVB5n)#E2lZPki>0;#_Im@ipEBP!eCpt`^&*j za%WedB{h5*5axkBK_rt2+3`)Ovu8#o%3f zwZ}J7{8M{eY?Tf;38_7H^k0;zAoSdduGEQaK8eKs=nSw=tir0X)FmcT1+SXlcg#vm ziVQs)L@JOm@G^SM=py^RNL6z&^FdHwIPqB?i<0@+r|-FB-Fkh;ypiIcI`*Qgp90bk zH}5>`$E)Ugfyp~xk9W))DgLSGE_%r8$6#Wds>J2owOmSgM|-jke$rL)y1<02BQfe` zN=l(PxyPbg#8D!%oYphZIO?N`Ibe#(g!+Nb?Op;Vlh=|MRVJs4^amT+Ibl2wLF^=` zicai$LiA`?w!;n_%~W)9*Tthma278lO@~$9g$&T?T~8E^7wRG9mBj@!qcVg_!YbX= zLQ+YMeS3?}^OAL<{aJO!D~5pDvLM4Uik-ia%?Ua8sG%_XTrmZw9l$X@taE@Lmp&>* z*Q}L6BaYPrjv0qJb%PAKL99@0TZl1}hMp9#3FFEtagV&*a`s1vGE~Z7^0rUw^h#v# zf?^fJONU>t<^3>OW#!Q22j<((1fr?j!kkwj5ZyWjPR2e)U1LJV!JzRlV?$Zg{S_|E zp!c5589Aw@4Ydz9`XeUqyL?Z#ryJ%Z#L618q64u{cgYEpaD2}#Nfww!a(bAl@_uI7 zd(xQg%bm{*@5&?)gGrfG5PJ6~w<8-dM4|0;i1$H)cz2#tgKsJ7W6Jk*F#Djsl%1QF z7Kb?@C*d0fs^btuosuZ`ePiDpxfY$3qz19VJlc{TQOLzq<#de4pADuHbV?{7zU>+x zQ?!tS86r|)ZrOBUYH2JIDZQW1ZN)^QKVwn@?_kD`2F#}$MSIf}R^p5*3hsY;WQob@ z>E7!SvkNdpYT})1P3|*w0DJm6f8)xJ+T|1HR zJ*DG-#f)5M+rm7!&hWm@EzH6Zl!cXJ#T36X+$ei@y%z-6n^+(Q(|Ru+W&`VWuXwRe z1g>d;_?Uz1?CW(#V1{>03E7LUVd{QA-J}LV*W_Iq#83CAA?v1zG+wW92QfC*3O12) zx;FX2p7Hb$Y9xE*JMTvO!pk^tHl8dlunt2K8mSxo`$fLT2&yjzu?}^n&^OEDM*6Wi z?50(8Dv4MgVi~Vbh=nS>^7WWh5?CI49u`{YNQF+(6Lqd*`K^(*jH7=ml7jD(x-hi| zZ0Dr;-HvG$izleth>2A!-_nsAgB^-xphD3TQ@Hm%@3Jwt*(5k_l4u?B8PFy-RZTz* zq1X;P!EH)Z*eF6MV~Yt}uA`3S1(V6H)ag|RoH}}Y*W2?jfGHr}G{i#2m{rZyR?rb68bo+N;Gx z>C&`Lk4=Hj2nUP9s}7Alow>)RH2N-Wjfv0$J1V_kl8cq^sY7EOGN~g((!JSujeCL6gDkI5> z8*K?T0h+BiLB@&a6A!rRK-+|wfVso%lA)+NBxdcSp9`^Mx?s0YEML{(E6eiz-0meN z>;J^Ru$UFRN9`M!!WavCR&_|sTE#AAA^ToM9_jE^L8@eFJRy%c6gIM~G3^<7m<=gG zw`KFgG-H#*mZRBP^NWH_By)R`GHhV0$g z#$Wc{;r@08)vIpVF-3)>cDniRmTIV(L0!go*XMKgEWnqm9$mI13Q?mo?&@-%uGNYc$n9j zH6}DAX8HEy#TXeMX=1(W*xe*K*Wn0$X~HphNV zNS~P^1XXux_^5}(_ZMEf>P`(4W`5V{6O$s5p{l$0f7BTg#fe$gX(B_-?A?oG!22g_ zSatUY%jkPwGjI^oMocC*Ro%^@qq9Lr37Us_`ae)Z2WJ^n-F@MwrT-sTwjZXGj}uYp8ih;H zjR`usSahV`d8>?^kPu~JQ`Nl$rd2|-6-TEZoPKvOK2UWxfnK=IvaxegGh!v^h62+n zH_kj3zVjm1rs*kwgtlqtP9{R}(VmFbLrga*T^yMZE>CP$lNDE>ppn}?j z;BinO*IfwaNZ&+f&$i6DBUoc~Y ziyqU2sa+OXC!9(zY{%^UC`6>e%qY1nbOt;+J2EXHQM@-z^%T6Jy;Gm+)aY7SOjHrb zI=vp}Y|0fQYt@>jj|$#pfq7KC9_LJui?M_yChFe`O%Dh2{EFCnZ1O#Ii2l>LpI?!E z8EDWL%x~u&E9kgbX?8W!p|D=SS zxfk>-jHTxlCf8Yxymgnb_an>q)b1)|$Rz0;0`0&E>nH(6i^-}$o{=|x0A+zAiUiRP zuzbzFfyi7b$?39?$IzG4+c-l_=O>^l(p4D+#zKL@EY6s&^9xoA&%DG8JfQN9IgqqF z*q@>4N{>>L`IrvVRV3=b77|TYdK7Tl4iuH?^|noni52EHHO&{x z)vP>qM-8)pKNNDNP4mUm6WZ8&;Iyb)Fh65{dP29r{C!X6YB$Y6Pa>XT&J)Lnh@`T_ zgv!k1d_1)=*w*IAa_(BhgDWrScvw76zoO$|tcUDfi(|g_$d~Exk%b&*6``cLa={G! z9rIjW=Q`ysX{i*bGItD5I+#OVrjZ}r+)n4z4=VP-{Dfw>avDnL(B*#38u>C=#@Gy3 z&MF@{b;mJaK0UK7n_`?Keu^;{ zDP3)vk1SxJGol$D=D9j%QpioxjO1i15YuIh@jVab{Wsf46yFmsJv-y4V`dC1vu#;3 zoFp6rO5^OsuvlUn3oA{VuI!qO_`HFcIV~oO%dV@i^3aZ!hk1TQ!~_q~!lq(MoMC=X zueym8d}2eermLGKgZp?t_gKiJNf~rAl}N}@pwsT}oto%K@;%Kv(puQPO9`!N?$f$3 zjkD3s_w;IVn4=#=*6BK*3A1dRQK3Uv7amee!A~+jp}-hsKVO1?U6+!(_J^QV4RI)IeE1%^w^_#8oGWaqj_jXD?3-OM|xRt zIvuSuFef25%1t+z1@C&|RCIsbjMhW4PA8u+986a~rgdta(V#C|eqU!Soa$KuHGG-xO3ilmG--?{DB zbBO`1l-HR2o;!BZ{S|-Tll4PQ*Ez}kL^J#BWVcPsSK$n9gGs$E_J@ZV(Qa$z{B-RU zZA7s@Jj{b5`=T&(8Z-B-?~EA4nz>RZf?b8l_udy=I(hI~&W zmnzPEW1SOmE^Vv~rVYONcZtl`#HQ(djf`xx=`MLSN#p`bTw`|1`Sgx?hsPpAW*4UM zU3Jjlce|Es8tUM03H69M-OnA&qsd*8J8xvNJ$DcDpzerqg*gQY<2&XQfD+cP>&DZQ zpUJ(u%xvIY%EUB`yx}ao+3^y16lS)YVZIDJf}_h$6LWHOQ>4A?X3;{@aqC{gEyl%# z@$5SN#q#mLj`6RI=M=*3x+Sv>4SSdqe=OnAu3ISE2-L3+{d)*oSk$gt9#70{+Bo&& zf%ELTMX^Mn$ax;lI!BY6)QD+V>1vMMsh~nYPk7X>TMAn?-b1`&1@YfGs?~K<;VW41 z_a-^^SB-K)eCxUiu;t@j%<{m^cHOjhIw5eg&a}M&3S;i>>8>k- zr@PtTcb+n|#$C&NVX8OO(3-k&LWMWTgtLgJ3TA`Z*>E0`)5DZX>nih??K)Z4h*N*T z?A*KD&ZaT%GiuP7FMF4Y@V>(2-dQ2*u9KC#H~IoIf7pBEgn_#@{K8Z+si85cRCPLC z6|U;herHNiiYie6#2mC-nNG$!?`t*`3h3$v{; z1HWf{$CS$G8-0O^R6o3T5A&{p|DC(&B2yWSs7ZrG*S)!-^`XMvVg|m=@Qx{+0B-aJ zCilLv&JdXH7g!6?brSA$=Qr-sRjqxq(qVz8`3@#hL8jYjtHM7@ zI($vGEHIEAlN`1L9os5YspfrvA!rZ_q_r(_s3vAj&$Br^=a9T%@V$CR%jI@qL5(wf^@r{rsNS*5m; zh={%y#goKr2S$E}Pqj#bO()nS2=EdEJc&2bBXDxFCeI~1n7r{kcNbIgD)OPX3Ctzli4n*>lD9+d9)28sd;si znM0i9j$q>D@Z@$SIRyv^D0Zb3f4S<$RY^MLHF+BNbqJ zLvCs(xM3u!&Bo$#w#!Fmr?7sgPGxM#LV6--DLfs<|{W?3f?HxDYJmw z;m|Q6$t(bc_M5)Dk^Mp6dgxezWPcFTjomUcOR_(P=HRdC-tkWsfS2vXk;#=M{KN3O z(xU_(Oj(Q0s~^doog|p1*9~OSPIs2cikDty7L!(d-ohjqD;-~k;W=fUWoPf?X{0}z z#UxKdj>^H5o;+74o*Ps1G;&61>x>%j5+O|@CN!qBrtzo+XyJM1OHzfooem^B2VD(= zZb+>#**Zv4dDoEAH0f%UbYq$}KQ=vht%R>ePM1s6&B41#Z1O+^*$%3 zU&cbZV(2~#neDeES;4bqSq5@YWe(G4K}vP*3;#>{TL;`oc9NtTw%(rWEbo}7T7%*U zG!}*>k8wsQ^>bShqfMAt@k3XK%LyGsbduZx64Itb^P!8muUv!Qsc)<@WweZ%iWY`0 zyzV$5N#l0HSc&1_lv$`Vbm_IEukVDdL#E2i@;!B#^v4sDd=d&y(^OM})(kK^_dVkc zO=S?nkmgAEkunIccR^=Agg$*uLmopW9h4uAW6;^VV2J#%L@(%0BxQN>qk)ud)6Nag z8}#`&t8C0B>4IqJQzCAtjF35`GLrikrrlh@`JkVQ*C6di`YCn#mk*dw>eAuK!OS@G zd&LV(>>WkyE~fNO%1q&Yz{Gto;TR$;Ywjn*n7hDVG1I|yQeW!Q)(pL#@jbIMN;D=mgGfofr*?`SFdYXb zBKP#f%%Zc}wEFnbOw6b3ZmP8PbZ8>5{{gwnEkk#qI5#rI_be;QchE zt%4agFavZ^kP@w7N?S=TZ0$X=>z)MJhanf_&VvLgUdVtG7J|r6UD`UG`^H_mJ(tUI zC8Y6N=^9WCyPp%+b24jmC8iuvdwHgiOtOPIwal)W35kd>3|{fur;{pZ4n>d@7G6Su(jfL>PwR()j= z^QPKQ&b_^#dt^lG7A6;_eny|ZXOzG&+w%-v>?d@^&gYcoyf6Vnvp@_XiY z%$N}+j2U9-#MCOTvWV{3IHSREM2B`iF-^uOQ-qm5=!nnG#D(5u?9sA;`I#qD0;$VmclI$Ha#M&#)c3^hpZZk-q(~Ip)ITvT}HhI0ikmETp4_uHnhb8*Z7W^B6LTJ zfilE~O_*N-R?Rv0FgR@Dkae0MM+Ixc?$qAf>>YQWeV^N*qa0J?AMD*}WDv=M#d63x zwceBhY&M&4&*)yJNO>KPU~+szQb2P`W&^?|7dQWmh|~p^z_^Ig$uO@FJH|&%Wd>eL z2wu#%TqDA`Oo0wL?dX zI&|>XT~9P+s~{SS+rCIAVnStEDc^K?#l*}qgzM;ZMn**gSwwm-V*`=Z=3>iOM6$9w zh%)~qFA>?#Uij!WVoK1GDFrzjEiJ_(*!Yq+(&f3VG3@{p7ZVoOz2XIC)_2Io%v@&* zYs}-r_l${N#$<8n7-mO4UWYf-y~Lj&NjfpFF-^?C!(>tGz2av~z98fx`s*Z7k-CFv zVlbZP!rZy@FTq@=-ZF1+?PUzKNpQ7s5>>lNi={z_ei<4>R&<&I;4y`F&d_!#Yt68jESdIu7O( zf?@cn9Xi3_A^hZZFcf+}ikR041`{UN=@?!T%4E3Y#MF+UoKbkkoI`|zcS)xhOd-N! zXPtbT(_PXj2Gh9{(+ig{j>hb2=SjT4&tBWSA@pNuw*j1XJG8R>(C?-_yMJXwKa!1wpnOd-S%$ z)D(S_@)$|Y;*tl%Z!*5J+wGXEoC)D-jKl*v!-ugCWai7xG=Wz3CAaHYDyPIR=pCL1et{!2fNX zx5WHmij!?I;}^`7XnzTDtS8`pyPs1GH;o<4xbr<(4-$gh`E`25#@n1?_m>8F!4w(q z`9`AKg+kPmdZ!ea4Y?FpVZf-!rO_4P0}SS;cXV4xKg=ZS zG`hpSBgc;^f%;v7WCm0AzLQ{aumk^5Mb>HEAxQ?TPu$8=I>e?mn0)W-`s`uSwuxzy zbtb_Adzbn|2Q!nI&yx%>LGiB7-Q7FlWapRV-c5QhoP<*}X~?XfrCjnbGt=aAYD>&d>%3q2 z@4btiY*L#a?xzLaXvRlIVZfDNs;FykIwt~i&KN_@W#a1$yl8l<) zF>kNnx6UDZH%YUf?&n|%#}UdBQznk=+)tVMC9mCRBTD%loymGv@wF@>bWvzKh=gpS z*>z3Glg@PNi!!qZ^R!Nl`JgkMv>kG(r>3KCU^4*Cb>9a9pp zlkD7-!yo~hDc#P?3{130d4(t)*-#kZA>IvOu6@fYO=}FMiMNe?cgCGN?M{O!{q1l! zJuUwM-gD#yjtl16Knx zwSq2JYA7*j$ckuQW+tjqLrH5y?mO=w%G|5ze6&p?_o!~%qecp(wXwpKcB7CT{yoAI zI!~W_*F{wnm<^m?gWu}jqskQDNN+N9^^^gWe)=cu=TqR}iz!+MyJ1D5AkWH2kgXV}`i_`jOX)k1iI8$YNncK=qC%T{ec?xn6#A47`0+Vr=x{WB$jX-d5KA@2IVWhX0LLOWSvI4HNAJ=QVNuF zYs|0K7iDLyYfM^S?HyAFir?tZn4he#^Ighak~7j;_~W_LnoXlDF+ZLAxw^!=M7^O) zAAblJCim`GN;30p)*BkLP`{;j%oB-TVWG~{rH>^Pvv)_vUr5TDHJA@)l)I$$ zFl9&>JA0RRRMwbs?i-fpC{%BOpHo-rO=^QjvH^=2?JWO!0YDWNMvdbU9>fQPjUgS{RN3!#CJ8AkjU&X<6|Od5^H|PoW7@% zoL9sjW$Jxt`H4)L)qB(3fZ zop~=V68sT!x}EhMGo}esZl|#qqWPTeYsc-3!u%P`htKK0cIe?W9nq4r*m>>u>Xd(A z%KyH-_7thyg$vN7dJi^;6W-N$5^jkNN3z+~!ZdB;4TJ7pbHm4Yd&lf93vy(1z~ zf`eH5Pot{1!2jGO)bH6wYRYUlCsZUhx9+OT_G6T_pN5 zCL>WhoXwD+W)?`TI`}k^>G?uUgQOgB2}#~F#2rWm@gs>&?_&PS|g@FkE9M>|CLY{A| zG8QlawK7RO=+exBmKz0qs*5wV>PGtSO=brZla?|%qrPB5XB1&U3?>h~Y^?KMT_pM= zW=5A;IU*0UB*CPN(sS1MZI+i zap=n7>1p0u|E0#Pw%*CCh+a34hn65d}9rNc5URr~^v<(HAz5+63xwZwl(@0gKg?X^kVRhJHzBN$9CuEn;Nd5xLT z>Q3exc;$(ibAg)Vm)LUTY`&+*190|;v`Bcs4!%rgJxXqnmU0q7lLa2v228oV5+& z&b0`V_coooiS870?w%Ke=;Mw4jLADc$_^&q=9JQIONa3`2k*S2J0zvOv7FFia;}B! z-IepOL8c5!T{=v;BpH;4V}D5oWfwojU^0VJ>@P1b;Go`QOO&8Xhnb%zeDC3veA3tK zk}a-FeHo9~!i*(^hcnVLS<1Wj?kBQw3)_=fOu0*A2NR`~_lg&oct>>uGo-+`DOQ~> z^_})!xAu;=nIyJlFr}^1&N^eE%^*>HgDJ8uZ>+O3UN%)-=4T_j8RY zdUMBKYAo$PCOL1)@F|xlLmXe`5IHaYrp9Cj*wlW(@wqN`;gX-wo6*dr6gp&Moj1~T zKkEup)+zVX%{QRm(Pf>>b^){*oc0Sh()Bju5>x#5EzBV@WR2O4FXLdwDAi!o_gt>C z@2wLuxlG?v>vy);ky&UScR`=)H_UT^Ddp%J?JRC8@p?ytm`k3LoRv4T?Ko)HjU}dV zYdybXo=EVIq&-{I?Gi4i?RDlX-?ObSCk`;aW5y^p*mUkj7n5Jwv%MwXAg?j8PLauu zj!Ota-ssPm^4{A!W;mw&4cWWV@AQl5zk5+)j(0iIvBsorv%%ZcCVW3*aSxdEkMcX_ zoL@9#oy%4cd-l>GUl;QdQ`Wg*+uWW({CCdRvX~-2H`aNt?yukRuuj~iEqm#xlp&0t zL^Ib{?);wp$#ZAk;{zt+2z%dCVsT@MDfVaE*}LSCj9k8yKfVDk5YMJ zG0_@lvb|kQR$mMUlR9qay-$@VYs|@>&+nKqAAIjkzNfYotFh-@e-n9nQQ87o%w~Kp z2Q#n>R&7=GZekNwE_wRBihd7kOyud&R&+4KA-s*~O+9a1&S=kn=cuF*#|m?@myVt9 zDYfoZ5e-SchNTXeuxh%_NT#QdpfyG9v>pS z;`EM;T}RBiwRgsg$tzk+e$TOUMxFE9rBg^WbLP=TZ^}Jz_AXsgdMGQ*$v+zJm^b75 z-#VqoLDU_0ro636bl)c5k;wUIViUCM_%^+`wv0JuZj8a4^ikNs z6j|5hdm7!rdI8FLhiCZzti4IHB`vQ-IhP!PQ$yp;Dd*ox|L#G16A0vBfA)@Di&!R{ zN~m-dXEI9PDJK0gEL(2bSOz--&UwGRJ6I0f^7RaDqvM{5w@mzIzOQ!r5uP1$7<)co z2Dkd2`#h1OcO1&k`uyyfI6u<~llrI2TV_?djioE1j!%y^`!RR9kjz$nj5k7+I2Kk# z@^cBJA+fZ6BUu%xhAomF)8_!$W7YgW_20azV8ncPM0y*qIM#owA#9m`zKtviLuTH1hM$Jhz|`H=na+)r*@Da79Xf2D<=CjrUNGGadwG6m@wLy zax%c520+bBH)D@5E>%7@=Q2L*X(Y9G&19=8PQzDXT$*z+o1x#B9LRaUq-EpRRE0$-U>Yy?@oBpLe?$yAO=I1ME!%sN97Dy1}DMyf|V9J^E$Ejgvs zWv4HhRO;Z^wdx}$G5Ei9ta;UUzTtZw1w7-@YRVY3{$y z^Al&C*@s60jo$AGIaLpG7^ry{TP1Q5&-t`vF7yz~2*v<%6xlMEcpRB>qNlsdhMZat zv5ZSn5G!Z&G4rbI4r*h|<0x5r2um*y0Vk^Tj2MD4$}Kgc$QI&aGX0Qqt(1)GNc>UB zii?5f-ROE(B}nkhmQZhN8m8{t*gXokVT&13D% zLhTbXq&hqoxOw10uuL}SJQWe{>{T~r=_@eEX^vgYluR@9s&g`49U0GT!%fbVz)Dw~ zE}eimItcxINn-AI)NE9l1Kn-S3I%frp{_J}>+Zo-ttD$`qI^K02~4G@!(4^x`i2{_ zA|){Mf>T-AJV2z%fpvg1JmL}$d6msX>z^Ms!SO)6V0&H?U#IIaw!cq zb5cu2!i21(WbDkG#V}uy2da=s+B9UbC)!B4GAqI<{hZRWI_LK5y=Gh*j5tt8D9G}7 zwU8d=2{S7*`Z=Q|!2~20wPZBCct55X7+9ZBGvRrLrOIG>Cti+MPBLff7sk%@Ze{-> zE6y>hPBG=^Jes1M#iKjiL@J?041XDKLMvF!bBd5$>gPm}jPiuMge}KO1Cwu zO5tSMrT?R6O*yZUC9YPyM@_j`PQPVdE%{eY-0Ylol`K)ytS1?_TPOYGbUWrSN9}<5 zpfEPubND$~Vo<*7_q>lfV)Q#Ebi`B-)@PHtYI(5E&bbn+ooR|GCrD(R$(+|PT$t{g z`MxM4-Im*PBWgkPxt8w;M0Q$el?oeh%#)KBvsOebC9QkDqg9ULJJf zCUs1C_j73fu!|0^%!cTq!IM2l;SU$Ph-o$0qlY-dOBz(f{N?IIodaCMVGbHka2TDu zVBV)6W*uizm;<~Q*RU<71mPzHK?N0zO*ygPjmKM()#>>l3@UJXu`#V+1CIj))h)st zkh~hZ<=&C8yMkR5=D^haU}wtM+did69qa9u#T!v!tWZd7%i;Ji z)_cRVwZcdh=7=)vp+QXJ*@_y$p7m$L9Q`#g-M5?pMwQ^X;O7XaKZW=I6|MX~W{rlC z%8OCOg<J=n^W&I6sWYg^cF083umM6q8CS z;fN^@gUGe1B0;V$B8N=kSCPf)RK2V)_T0YZ?4-Xv#4|}TsUiArrVr@3mEm{{Dry5g z%)~MN@qj@zS>wDb6RKWI)>VYAB&=W^R6GQkcxV|)4Jugor{S6j=f;Wdn?wKcYzTXq? zqG8^*=lt0lMsDIxUo)>BF;$ABbR*agsSE)!MfK?FkOcBt_DJM$w1ZQ=+spruxZG8% zByOU3GH{;pd*qcZ-WM8_5G@^4rzA3=gBY2~8I6Oz=hyspy_t6=?%@Y6t)PNn7VF)r z=z)9K4d=(q%zCdII(I~tQ69$rKi(VEYf{)Uv4@H~VnYAoof+pd9{ShOIhPvN67@vI zEHETK2Ta^WqmHZsfb{w_?;_~P3Bh@qiSL;YnBIwn&NWna2y;+Tm4JXM!Fe?r>$5#% zmOZn7&%Y|{7k%E}Mal0uo$)pH?^y$w#=9Lsgn^lL3uaQ^ z)38}oi3oUqaedCVfEa`+-!obMB3O{!us&xd=iPlXow!^*?8jjaQ>xPG_V-yoUf3QD zh#t2k#wNu0O>`Mq$rD@TSoh-}zDCudv~ zhq#M0cPggdKNb^JNIQMQd~ViJLPkhM1=c@}_8+EH-Ke5_RU;F~X9OfBXE0^nsHWAY|aOv>rM zneQCQyt~FVKi`)Uo>e6S%$#>84(#CRDBCm7){?kP-u0QbOssi+Ps4Wp;Ne;art%x$ zd*<)&*-$|6;louSafF;qdz0Muh7hF%Q6C`2q>Bw;P!H$e&dVupSViTV2q%QOh>8&R zGG@JfEFy0V3aPv=f;>7kMUM-^eK8YxW}XaNp4B0wJ@M+qOvp)We5ucU<+AiTfVVNb zz3-)y{$7E>Z<%n4O794Z`I1EQ$PeY59j%f^2iI*jdIi%RoKuTiCfvc2=x8xtlGu^> zP@iLtv$VgOcJU=JJw9@0HB*goxeKQ~b&1}f#rYlDgL%ox-t6R-ITcl)O|JYwb$^)Z4 z9CrGi@%?IVQgrf_wr-K~C5MG+m{A^nO1GC%uOSnO+C;;*+=V%vogL^un-ewcIRPRE zgd0On>s~{@3`SaOCVHT?_|5c)ll1IqtC&gB27dy7GT{v!LeVr6QReQO=_>j=9@=~8|JPlnw48fpC;i8awD%|`Do&nMseZqwTyTT`U*%=7a_fPd4!+qQv9+Zr$;xe#@D)LO7VhJzL~j+FW9r|U(lVa zkTw{FX?Y*S;PZaZJ(FEh$~W_s6U8+clcjR!kj#uU%w+l2B_`{YGj5qkZz` z4(Xynb(xY#(IYuMJ8}-z3e6Nbk#ud#$-Rj+uewZStoi4AEp^gQ&a!19rB{0TTFioO z1VdVDP+g{wGl{fTV=Z;k-@G%nQFp_VIg$?67PCM}9#W*koIl4R3;dpjMJWZ!>9$OM z&-TrHNgnf#^KAd6oWDI~}LQWQxG0&xj?@8u-cP!2&LuWv0d|{P;&E&aM zPnd|oWZAHwJ8a>cm$4@+_ZXdR<8UU=OcYtj`Gm>uIh=J$PRvpHW_Ia3=o==^#Ms?8vr9Lf^Lp$!m-09B zJ?bz=w5X|0U?}nhJtP@^ye5`E=X}~Sp@;B$T1?*WT=SZV?|C3+m(GK}8N2?TCKGeS zcZcd&#_uWTQZnLs8{Qp`I)h>+oJ;we*>5%vi8suqzNg{0kDg~8*ZjUn4aRQ7_@O&v zr*D`|&5;q07dh{=cB_tM)V*=m8NLHloOF>UO4VJA%mck{+(-1WtFB$t=MV0VPWp|# z?wLuA-Mo(wk4K$Bb=cBHe=MEWq5Ml@{EKE{Ewyi^bHy+A=6t_ju1{2hb;V%btk3a& z_s~C8*RHGY*-5|eS@z7E@97BQD9fR4eHNUZEFx4BjC^`4<%})BwQQ9&o=K<3_VzVmjdKmZJ zoA8z~m<63|I(^M7H)D56VrC1yTv2yL!n@;O%@=yk7;&JP<#KOwj<`ORO%-zHBRMn9 zki2DH$=R)Rzd6F*R2_Gqd!OvhPWtVmXUk-Fv7<8tg=JbIbG|!J@thrVjdT7%#FFFr zsk+Xf+xk(Lsf-$D1u-^p?hrHhkKi>tsgID;Fh{$BWZ4}sbHZD@@P41`Bm9DE{^UG~ zj3}(sgBWDZWaLiyW_CZRN9BnhbM}-kzUN5|i=4QR6qDc6AIOmB0^%p)cy|3CJ^v`hutQsZY~@<*ey9F=b+O!V~0LpznLydT|>v5n5eqWka_SuJLyknaC;`d=fRt+dn7z0-Z0z6 z9ChjZKmLxz*zq=O2XpkG2S-E4$EdpF+}h{yhUHnOn78(M_+jBkSjc%}pYPIn&^OE* z`+P=SG9P#@sm?$PzqWCH28lU&=>}8#wXHMx!TAY)N1W@dRIv&C0!2bk-r6!znBIl7 zWisX@eKT`KbZX>VW-q6_-%UB4#5s5RM$UA>43XWzEBB_#_>>$t=Fb|jMn#&Mgh2b! zp2-*TM>~GX_1od9N|a_ z$w@be?chBqfy62qdc|Ol^ z{Go#VWrck*%3!zgBw%vC+6{`5feB$(o?jx6XQ0HJ=br7_TS_aUGeFPHqTU;YUH{C? z-K|Uq%K8NtbyHPzi>l+#6{==6i=U(jVHA=j^4XI0h(C_Y@FO8v2eQ~BiYq51l6J^O z?O0V8={*)HmHQa3d70fswVshHp!f>78EwLl^-AAEntmt0LejzT>SL+!b8%p$l#P3o z-+_GSdsFFy*&j9iO~`?>h< z5F6#qpO{7+v6HhV_`y(MurA(GfQ+APpI}rh@DnVbU z5-b0)a+L23pJn{<9_O_ii!6J=DhAjn`D!#8$7^>twp%vg>AALSRP!Jxz-Ek5)G&05C$q|tNa;vjCBJeww8|Eqla#EQ1K2gjmT!(55<-F{@@domX#Fv&=k4k{$>V* z4o4e<%R0ddO=6p`akRX%N;J#RXp<>E5YMY2_@Z`ytu)qo9KUZA8bG_E?G zI5@hR>gMcr4QT2lmYaC}+p=?#OSC|!(e}^3-0eIEVgJi?bFQ{y=XcS(Gp%pA$1zeV zHSquFi9m4k_kyt|l6M*jl-#QjV{?xR)Fl$~XjC2FKHAgO_cIECzFW8$Jp zJvB>Xd?|bDai~{i7CfegqLm6I}>Qs53P<9c+wvz-TW)P@hQ7-OUQUy&d+yDH>tV3-_2hYYp`zf zVx7z`ZD{q3o+uytVcl9*c74d*l6(9cOqTcY)>T$e=m4#G?y(%Ev`bW_OJxHxxjDAH z?Z%B6gGJF4wSSfk9j-QLc6qU$7&J~xn!o?C<#x{N>+trW*;kom5wU-W$%maSI2o&QUte_0njayE3+kDu1K#8=p7x}(gdqRnK4%4*eZ%<1}iC$<^E zt!CO7&1xrxtv4OD#vWhvaUC{evV&$0V>J6ZLOdX>>k*kgnqOqqpbPOvhT<|h?i?EM z-FZG@*Q2b>-?}$cla4T z<_w+O4tVUHB{olg0hxhyPr*vbs@Z`YWxE{M0XURek^|233I1Y7=M)-LlAJ<;UdXLV zcop~aQ<mCCWfKxy@>? zSYg`-zs-&dDsY=2_hIQH4@kf33TJ;RL47!O7#UX{%Z7R@W*);H0@#k*K2Aa&d}9@5 zUi9gNQp@yOm3f-se7G4qSVlPV+GK7bh9ScvY)S){>(v@)@Rlx`W&sAPP4A39R*2K@x&EY;dF;7`B@D-1o?2dQ0Z^i6C7SFtm3t;kP z+^LS(lAK~Jh94-*Zbio3&LdC`LS=uJo5TLkfYkes!@v8+1&fbADGje=dc$$n3=8v| zZ*n|Z($|F_U|SuA;sUI${x5z87V->wqGC+fZb+=O`H83k4j0-8f&|6hAp!%ugb@3W zYfr1UWUYcS z&*{TThh=thc;BY`&5{?X8{-41sV$N+bBUlZErDKs+cJt7X&P$QsccWwXDYYfG3QY& zJuY;g``&J06v2yENl(ipJMDZW4f=M5T*pm}CEM-T0olGYM!UzpJ$+|Pc3l$GUvvNW z+9+!46z0!8{@=-t^M72HRiXIZD(mCac334_L%B?T^>D*xJ~_XdqqX-F%=5Evpc1IL zvCv@-_Z+|ox9hjIR^i(aE|;%DF`(p|KhXGoXrkuQXps2+|37%;M0!}I+IT`S=eR-PR*Q^s6^kpujXw!Ggu_b-owYuvC)dCre_e1Zpz27IB_`VzZn4(DRw0q#=W0 z4Uhz}0<$-L_^KlXy+7P2yobnMF`O=CJ23{}<+QVMq#^;A(Ls39uIMR#590U2rgXy78CS9*$r(1+~X z5Bn|>nFF%5m#O-bQPqd?tBDODB`TZE7ye_3X1H-mLyWFek%j2V*)PCSUDjH@=9aaB zjSR6FR4jnf%teiD^14IR$qe<@&x}44@Yi8-0(k8Ak0q(e zm;QEJ_z>?jlGzvd)^%k?4RX8AvHLC#+|(jVv+e1D;m49VkKNj}Fwg7!k@^ZG_|)R4 zLE7!7cfn&NvB^6frUn zIuwG&jWAA-WunHSKT#;y&{NLn)+d3S%p1N)`M4O4 z+vjDyPunQIEuVAFg7T(p<>QE8(uhW_!N0GZE;8{~EK#*Jp5haX{x#@6JZ9@pZl@|vE7Nb)r;Lb~LqajB)K!iD^U+h7X&-hv{t$qOse549Y(b9(y^!k$iFnK6Hz^NIC`0z<8GV z@nuuflOS(0V`4f`3vi@+9+IKq`!*1Q_N$KhR0E?|P80mWL|IUY2pl>5=UH-9r`D%Ix{SLBcaA1)_ud0^Pb$jAZ54g#eZWk%w7Q+oK`Yw7 zK{n%weS#eM{!41H$KSGpL4>9g&sDN`6yVTXxwF=L08uAa;CAt$SPc~jBNk>QXu(wDGL#& z$<}S`=X6hrPCJ^0?Vn>Bw&~MCSjN&8{|(pR>awg5&FN>8s)Fd#5b8YGuhy`{Yq)E% zx}=BU)l0MYWyrrKF{dB;_iCcdy&G3gq)dZ1dNZYS{hk)TwO4wbB4MhJJ_56DG$|8r zzMA*TWrZx`hZPVJl~ox)`xKk_#xnPBsUq$|n}|4m#>zJeyjjoTvm8=fL4W+B5Vtj9 zrL!-?pwliI@|Az%jj&ZTM>dekr4}`qXFZ<$`s}XUO+&1IRnAIfwjOAv@9lx1y=-`J zLq5x@jd|FgF!#f%)I;%__q~s8G5Gnt@2m;+rh2PWG|;xzL@Kc(baXq%jOVT2 zf1{9EQRBYHdK>>tDi1r=miF*@o&JiE`*XUfMgzv31QB?sQ&DF{zpo(Ur5@U)kzPO9 zTzHn>LzHIE!;+IUAjY$#>Jh~8N`zSRV~5O$LqL zKZAdVj$iU|y6$5ylYG;5LPfY9CQr7}H5iH4r(%0v$tgUhFSF|DEfL_RcT%uG;%Ab_ z{g$9-;9r|(;9klpEX?qp7dOAJz!Wl`$n-t_i=m6~qrNfB`ut@+uPo9<%McwMq`Ly5 z=XlJOb1vC9#1uuqZ2_Rks?>!jJH~d~u=}DiG7CaZi#a!kVZ{^0x9}E0gNz=OLjq8}G?np-V(41jt}DaZ-g8wr|_(xkV{vK}Cb z8xZ6ba^(`3SM;{<4g-?KeiD*fK^GRjEb)Fje8F2YV4=l3eJ3!!g3zj}n3`9_GONoa zxd320I0qr1vsO^-hA9Z$=EehZ_7#+ZVb|pK-GAvP=7r~6nrx~?^5i0&xmAWI@42{NXMfow#%)aXi3kst5ya(6jhgM)o10u=@4u9=?HrB0pa z55;c3^&hhua)}D+Nn^O+H+p6Du?>E9OMBPJ(@RAQ!?EZLu-G=(m@HZKZF+cizSRdU z)y@jxJXqO^4@x1S7`8~cow}8z=L90b8rgyWyOS6*d^pwc-)k5#L222lXRS@614xzC>1cGlB~D!@y=8*ZLpk!GjfL3y$NaZ{+X7(%pQlaH&=OEuUvKs zNw>gZeoN}qG{Y0USL@Z44h`RA$6O^-`Zm~pTv#C6KLjP(t0yvoN0bCSo=5~rnH38g zvM|V$esM}5@8ImP4}Vh%cXkLb`WXl&AYYiOEQ+F0EJkM8k82Xv6{dB7g$;zsP}zEi zVQY8rzrrQ~$O?g;e@uac+wpX%jbVVn4&d(DzmDOy`A06Sr{GvitTILY|HB^qLqUIEhVXj9-UK0TdHsfGjjI?K7l_d2WD;l{>9#E;LJxeMLaExFxI zhOdOEx2Wdu!`RkOj81(TWL6+O8N1ts7w2}nL!31$pcL8Kf?!3|Cnb%=fix3u3=qLXVZNinbTO+g6!ALLsCzMB2VVHw8x ztmWEEh%fJ6u!fv1`>q(dn`WsIDq$a??>Hpyte?BZ&(ME{k347MrQ0uxFk6orU+0s) z`t&&La839`O~N+KDw>HOG36I2x~sSyhQ1LiAh^_56s_NAsZ&x?`ow=L-zEK%%sgk; z3U1u}ABa+RaCcMi&*BT~{`k0OvoEl(!QaIw6gQN0GEZDZE23#yOC+dGnS5qJ;OEpo zLu*wgegymAhj&9b`iO15`U6Sf^l~A$AlzH^ct7|I$~}XpxC=JoR1d z*KaF#MHOF7nOd7<*p1hs91fn>t-Pf3_Sy9QT6O${cJ&<_Tif5MlaG9o zGd%-9ty=r)KVI})R-Ir|3GW`uze8vWzt&{`0#|7^`tkt{8GB!7_0b(v41TFZ3fgk9 z*8?#<=WVeQg}&y(m$Q5-smQnuGfE5XVBm&U13Vll<1=tpg2d%M%`DZih^K3cXRWkz zSty8Ys zhGu`|t_l#@K)WV`a*M2(yy3+iNo=fQL6nd&ydst6Rrs;I?Ukyr`&fxVz^Q!U^hF19 z(Zg1JB21yR$;moYcfMVnOO+NBo4rG=HRQ!DKnUVvLm>^4eCmqb@THAmrl5S>!aiaI zY%dz)!4pwbPQrb_7I8HcUsJ5SGmRskeXv@E^iCvB|Q;MWq2Cm zHI(bIQ$xdoRhaHME^kHrP#({s^CmLzbv)MQ<*vHP3(@s$*~TMPEBoBAt2~Ir&kuBG zX+d4RpDjnSTE3;ApH{sG`appvp$?bv3{Es((EXtf+hoo-xj)*rmKHk)ltiI%G7(_@ z&|z@A!no9U&Tw=rky^BH9#QC6pG8skh)sjRZr#e3vT%gACS0w%*0zh{i^G^Nu00nt z&2F=~L} z*e&evT{(Qw*&d@mkW;qeE}RH?S5o@fe!N|Bat(wTx5hAX2;HQvFBQT~)hr4)Yoq|t zGFA5#H0pfqkO3xfL>a*wel*w&0ph%I{BO~k?`fT!_b6Z}`~*c_%3C^dj>Uz!RV>^v zGNiz-^$D_GCN1i4av1sA#@L`Y*@`(9d4`4$K}ri(`VviYySm)pi2DSC)qes;Z>OYl&QKpw8Z^grTMGh#i+We{1 z(pamb#9Xbi3K^q}?-iW$jfViRPaPpn$f{G=JcR)Z+Fe04XQzi<;29#G7~UR8zcm6~6VV+SS&3Ibq1f3P0UEg-kSO$0Tzw0cqecqGbfWFZwPV zl2&o#AnDsn_x>??eG9X=ws(Rpm$}BDyto8IpyZ}-@b&O_#)tV|HD=r0h=!imxCo3i zZMHm_T~j@}s%>`Y_eE{$e?7bINMJlSzNbgGw_%&hon}&?TTo_7v>ovb;#TYB3wa2GOWD9XeT7Q&C2kB2y7H6YsTi@ypdR<@ z1+Cu){pVbpy~S^)62kIj)B4cI926!@0diEJla^BEeLYva>zD1KV*v6^<=uS0y*i0A zda`AwrxL%HW~oiHaAvwBPKvhX@ljaAph38CNLs0_5VPF!atxgWVXMa0+AD$L_|l0_ z8~=;tBt%r_DBR<9AZ#mP-EA-6H;~M(*C! z=%UE>Sfd(dJ|mOTFdNAnYjE6OjIT`csDZsp3<4gVN z;5vak_1zYAhV1ImZVgE2tM zji(KhdHsEWX%mJOdU6PqJd%0+Dff-o{&5Spt=7J9zj@h+!-13*k&lAA!t018yB?vC zBGxPQUvv8;-xnfNsB;WfA3a5 zYNhZc9yewWY+jF*4uLNf-39bfa1<2u=p>ejnm*NfO<5LN82@6<`e{bgWsTr@v{($yT#=DQtx-uKvMohen(9A=cDh{g!a-x|_J%@@ABSL~$u<|`hg4nU@K${|4%ZZ>rvD&bRDc8~81RIe-mVgOL7F~iWb)A>YE&qM~ z-{tWrq(U9J$S;u`^Qlba0m&W98%0z+OzqbOPG0@y!wG& z)eV>=htK~i6TexH3BDS35$Aws81|Fw1W6A*21cxia~W)w-?I(}U-LcxU~h{0k9NgH zd{bjjH$}3sGA3j?i(im3Pi2$tamhPiTIErHgVzZ^!e63YdF9xH(f0 zjAtO-vhfUhi0bDg=d2;4t^38tI%(91VIR@7F{+YDC8^`mKF+(ABi34yiVww~Kf~Sh z( z+p4~tcy*J-fFsBQW461PTOy%^GSQMSCv}B%Lp$yK(~!|1i7mpmhJ#;7+`g$3(yvo{ ziI6_Vr2s+2Cx`SNFt_shtk^WSyP5Gv2ZmsCVwp97BfkCg!go$+qxt#gSQ6s>mBGn7 z<5@;tr|n2PYu^61pCtB2Bgi?05M2?sVXtNS*_T^OD7Zlz0_PzrPv92)^#k~C?vS0b zsg0R60`i0CO*eB=o=nnDK;B|*bZHym9}@5JzBe>S($r^{`$fA$=C9W%*|mpb4gZ#e zi}*(!|8UOtEP<(BETdhM$WlP9S89*x!G%iibaq*UlN-};cDhioK>}oaH#AL-(;6@_ zA59-~0^Gz15*Soi2dJEpIx4Y=9pOzi?OfEX%vRtJ@XAL<<;)?49$X|2OLIeGg*P%nISVK0sMECee;mGm!=P0(kIET_ zI`p|dg$WgS#PfP<8EbLCRVUh&kD+$@h8{2KY|m|P>cn}T&m}GdC8st-^r&D%YTk;; zi#IKAe-M^-dXBTtul8rP-689pH;ygqvgQ6WkoHAKXlraFL_N_9w5W&$ZO_z7=wO~p z^=0b-w{m$CF1?$6O^lXJNuxvXk&|}FE1Q*A!p6#aMz@M#sHoh~b3w@I$rGpd_515& zGTSL}f(~QVX4?NE`EJWZ=U-y4clcf2CdLdw6;%VD+S`iy$whYW>OZ*?6Yx9*53W1i|qm26grZ~)fq1>SZ-2p>Gt(qmG_Cq$ED=;6spvoq%Fx`M7dE3yi_!YqB zvF~;)-=%tSk}g-S2;3w(`Iu|8*T5i|ttIg{leb#_T*O$iPKcw9!)>VQ%Go-FO9uTT zJLTb~G&ct$YKQ0Y_Z7Y+V@oir19D!XJwcg7urF$B?-dXDo#1RYHV1H=DiIH(uMFRB04a9!ArPSj*ou2x=;LM0z?Myz$t9nDB>}@LkMPL>$5G~ZHqg|k)X!q% zV|)E2Z5LR0T1UXt0GYMAdSny_DMv(F4ZB7Li0Mjv%4`R(#i|4U%Z;mwmBu2IrL8>E z-`vT2VNs;JM5ena{^_v9kn#Z3mIj!jwjs_F2+#U<3GzMLA@|M(K!euB~*a zCr7yv38ovmK#HcR^)|K0l#$WV(7f{Z0`xr4KiSBfx6z`4$lGL%oCQBLkgxUTTwN5E zAQWMi9zBqxHQ2MsAIKsYJdEUlgcGZPb_Oy=yzsu}Z{a>dAz{*-DQ9IG$R-dsiBK)o zjJ{n3T(4AjmLh!II4k79;uE0uANqR6%5*t#jl;Y7=Hj_%<*Esg32y}vn$uXOwT}_V zMXY~cM+p1l0oSU(O45Q3Q_)IkWaRf%<%`z@ZMWr&*wNu_xbp}Rib$I~SMem7zf!*-AG z2totf0x|BhrbX9!AVzl}ic{pEttZZhgS$ zkqDHsktzesHMU~;unUDRlfZbuh^~D5SP}-sxreS*7w^^N-dp)YR=k(gqna}ex&3{; zTT-x>hnI|$`uC{PZod7uf%)~f$z9GRvc<8UlVT=c64v_q8r;emV3mCyFW~dFb+Y*hbX9X-WocJyQC`Kd zZas0GW=Scu5y<m><`TI!iNL!03oM-#Qqqz0`4omTEH2_HeZicJ{)xgq(r->5JS?75V< zzfR4sIjD4Jgs$!^>(5Z-8Wd(B<#w;U&E5VnS&xsO_r~y990n4)wx{>ne>elcxhrpw zcO1YvkzWl@my)UGg2nx3;3;|%CN1ZryFO3OeF~Pfk(vKU^|7_ewP959?$MOSzt?Mv zAzV68EQb$@12u@}R?s`eQdXTxBrokFfrL-Wxufh08Q+qA441AxAfDujIyT_$Y4dYk6zJcv$`!QA)lIc#B7Pz-nff% z`6Sq$lcE~yzP5~Ddw$6pbyds+3mQg270IyZc z)|vTjb9d;7(K|IXOS{~ZsD}$XiB{_dG-at0X*Zn316Od;vTw zSApV`8_ISg^V|;=Ptux@*v&lXE-)79^l|f?9Q!*i(Q&jrKGF6nX@a_9lV%CaDIWb! zXdo8WqT2Vv@~@g!%GA-Wmb(u=T{@E2E&8vcYMQnX zI=(4rLichihfMoPM_s(8wxgWwq`wk0Hp{R>mJFQj(NOOUd_@6l;3g7xG0)ZZ{K4W= zK6gmo=49|0!UJk=R*}FHAbb8NKv{SoVVH-b15oHIwXYkgX2g?-kJKdUS0<7efP!rc z2(Z5=C~Qaj5LS;j9CZJP9lZq9uk27xt&^?h6!>|n)+3Q@dB=>EOV#gu03c9q~qxzRF|HR?lM_^L(HN zXMP3H`)YgKZs!v^K+U~U$D3SnVu& zjZ?U;8ho<@xoMZowClHir6Gn8f>1Gkylq^+aux~2>dym$gqsPtgBNch(dA!39as4;cFxuGKx#du)Ij~k!$NYeakNvK*U?_!TG(#j zC^B)Wcz(~hF^BYl80?>Dg08z;*f-h7*WzG0R*deYEiLTwS_y2Ejk#My9yO{keJ^(%o3Bkj0hcW6QVxlN?ZcRFUgXhrKLAwAP%DcqoyVy@!|Wz6EduP zO6zu9DrdKp{7t#GM>wbS;WMdcw6yvx{h9^|LhR(X!a$wN+211D%@e!ko1)vGO#_f7 zK{9*USR(w`wvqLPp5P!tv_su*{O!zo_{K54{XXa2=XDUEKo(f6kU;}k-Dv1^>NzV} zWgjQ`XSd6vw&-ooj~|P25lO7BYZq*mPy4Et>!}Kv z-$jfA?kG~`PiKjK-&t54X|na#^_MzJOuI4s9{FfA(MP*r;KmzSo8T;=;#K9*in(+y z9?X+*Z9{y;m&Zq0-&b(=NMQZad)6HNfScSThnS0#IaK#4ZLhVCRgP5wcAip3H>MNp zO3-Y3e2UoOnVYQU#XF!vUS;!Vd3Es>nOwPi$#HB^p2By79YH>WK_x$f3Qo~&SG;%z zmV}uLupT=aha^tn;McamsE6uCTxe)*T)q6gjHDGsvhi$%@Z5;Oy4!(UH|u!HVY%HA zUfc;Pd8rsCvNZ!7r{clOtt|{bh;4&I6(~U{fBc5N43Wdvs;T1xWGu8FJ;Xt|=bYqi zWS(Bf90@~)NBJq{3(pExU#RfWnTGxnUx<)m73Bynl9kbGLK+y0;+OP)j%@?o+c6M1}kP(}>L<%m7I-N!*xX@3j(<(WK^@nSPs0FEW@O_&e3Awas3lg4MlXjulZ zx#zf2NoepetYL5kqViE`p1Q3vXLL0hc)Evz>4|xIKF>$kia52OBR^>J>^^Hv#evyc zVhwD(Unrua@12YRZXWsPbQhK(0xl_;^wLUaXkeEUal!;Vt3RBe-R+Yp>`dpombW`4 z&9f^M$KMLOf*B-A5W~&BC0%&=*|%(5%SC>ajDbHCSlET93H|Obq?euwwvx4r)V=I;xY^~J=9tAi}Qi{*r8VsU-Dt! zu;!-+b!T=Uf4KdPLq4kH7u;&k#+4AIRk2*&hw1#i7Jj1ck@d^jVQqhR&%%DfdTU?P%Lo?-!9?>WamGwbt3d$EDq*a_ejy|!Pmg2kEzmAc3 zVZECJ_lOiEj3H|L{kJ+qNUD`mX-NB5v8okaj`eQUlI^TAh=~-7GFFp)yL-ok9P|aS^&nWAD$L(J4<6b?3Rg$zSs#f z{iCDCw6i@`2G~lRt)STq%8t4V5nj&BqA{^WTI%|SN)Khe_u%=w>4#8PaQo9MkptVu z(LX@p_#pPd|DtEN?G30*#p^%vnF~@xDjI{IcqK!NXVL~_#e4HB8Upa`UV?q&=J3oI ziGs^i!263`gexn;N9!~>+$_p=58odCBbgx9kd21}M?-z@p75_wUGTm$a7IBK;cTH8 zrpr|}VkHi*-aV*X(NkWOdJ>8AFiv<$82{%CFXbi9Su+&t{8vfw(D3Jj(O8#LTi9I)_v&cih4ZI zy!@zKQo-R|05y2&P6RUX7>Qshf{<85UcSBhHT+NKZnuOLu#fnmNO4^1-K7Wxem>TnwY_ob z62K;PO8oWvLHo0K@5NAD{k~tc{$~Lw_i-zAs7qjgo~f0n=W(gIQJ=5@iT7A&%%(=KL|BrFojg30j$%8{of+H)_qlxryi6S*~ zGMdovV*ee=YPFW4-F`i?=)Zaq#!BdU|z-|0efmQPgLD8b2pZXokB@?Wftj zR9i4-P#>rAuCRV$^O{#m0ZElG9aulsNh|A@KqUs-l1Vo6m+4Gi@F_@$c#$ZD(k zT*$DtX%+Hpj`OGQ?3Zln6~kJHp-#-e>=;fX=k-?6vxb%SiP2vid;nR@m6dPS4Yt%d zX=(nM{2W5A62YSG1hkPs$tug{xV6k4@NR?!N%7U-tpAMD#icd&G}VhR>*%0xUt3i9 zi^Exv$mo0jm69#*FMdH2rRk2}Yb<>IZT+=Gwm*~3IjkPaxBfp}%ZS^$gjAV^1R>E| z{agXr#|ikRs(!?0MbD)A+FUqG1&K5sSUCksEn11B?U~f0;G=JlPY?s4Ni_B(o;FaT z;ac}JR*1qXfzJA+{E^OO%~*q@u*E#%TSKY>aeJnpR!b?_5AWZgZwKtQ(1q{P+JF9% zo|Mk-53xmSo{<{=BoT3T7m3;W40e6<6CA%#%$AQD8{SO_NT7Y2$~egK6;0zYU_F5? zq#LQQ8Ve*-(pg7XPb`1?F4t%?!o(&u>hpG#Et~RU5|6i130SKP6hAMvN`P2$-mISB z-5$}rN*!A>Q1kjT{bg4Sa)#$8abx5oE=|HO+z;f2`J4##Z!~U2$WiVH1H@lm(H$<$ z`*|uob07Ig`C2%@ACP|I8HC|fyC+&a!?eBYuL!>!K?frC?FB#qh)7g^{6^Th_)E^S{Gd-n%nD0DkY+E06){CAxkV20oX*olxc!tl=z1F552H#n0 zoiecvzkg^xMkc*NEmn?4zn1^7vckp<%iBPIJ~0si?dh`HFq&k(~UNn4S8t-Gmp z4L0oFZ1~>hns(vg-d*F|m4Z0y$N7vRd>`Y~QSnZ~MXcEbOQZBb&K+GZ)JOJ@@v3b! zXLFpv?;0^TiB$2g`)Q`$vc|y-TQ3%7zMb{a#1F+9dL+|yFg6dy9pCow=M-~!4l+CZ z;>0*H&HYfS4)U@ydIWm+4ubxbIxWEQl}R;r@b9st;q{6-D5Zp_;Jg!QKT&D4P|dJ! z(|Z8h5IWa#7tKUWf#VN3j`G9?1Ic}6J+T6BzR%;b`11Ud;rgJmwB=2pkE`U)6}51D zzy+;zCioG4jr-H&hlbf0Od>2eOnd};kM!l}ZC5xQ_YrQKt4yc&&QgnaTZPCWCW2x)%K zA!0_|x>^8?+`^;BoX+(Z3*s02?bUNdnVjqxi%r#epQ6$1+@73imqWp z&hp<8cn6=koP50K6l#$Gz#A1{YjQiM!*TOJ(!YQfX>@d2ew~}F0D^q*xJHJ+x2Y~T zk&kk5A^E>o{Miqy4V`4)D66O}b2Ll#FK$0tOtxe{(*r(#SiT5lce-|HR@uJnFqMHA zJl6j3^|cO#09j3;4xP1Gj;6?Y+}@LT%yC01CqDWez| z{6gJtv~PXWYu7Fl%0Jtld%|Fji$G#kIFvA79M=wgzDZwEruWspz5ClG%<+Vjj2{bt zzXf=vg*=vD8REQciyvS<`Aqj$F#$&HD|!%*;_9V#Q(Ml{Z1TF@&B<$N_BwjjFiUwY zT!U9K?-foyRz3-h2xuX9GbCJf@$4uJ{lxb`sGgL&sf9YBM8qKd+(~j5eIe|6X(4@9 z`rx#iy8_WZ=K_=H$uU#1TOvy)bwzloAuvq(B*! z9mCZ{z6*IW6>pyXCi1+OkV>gNaR+eZoWp5E^X&5aOA|~M{v4(Lh38$`P)bP#mgUGy z{YRP+|8Q{%P`g0$k!YD+HGE!WJWe4(bO(Q5F_m9C(a1QB<*dJau_W;MEVXi7YA}lM zC7U;enBe@Q2v56Q{^*PsFWxA;G$BKt>FIfn`qn4Q3{#lblX99sf%Dk?@AYFpS>jZ? zi>Y-K98n07aw1V>zHi`;3^*`+~ zyD&#@*7x7xIjKgEpJh>^d1psd0ZDR+A!@=U5>&thvvIh_p?DeeDBJUVu+P?kx1Uf_ z!Ieao``w}w@d*fY$aEzv7Db$H67X714Br7`<1ZNxXu}}G_U-HibnWHQ3jWJvF29)E zvWT~hW^#!YLDLwpR78^?mNQo#xI>lxUAVyIl>rEt2-`R|M}Ks%EC@8mXohMgV>nOj zZnfzC4dhQ8K8+h7MNK2M@IEpt9tFvqtp(PIX!7IxE@f(Wj}RR$h;tQ+X^vD33)*Fl zO4@j0TtXeR0@cI~bYzF`CT_C$CTRHjJh7iww?!hOS;~O*B5{t;^Zcvk>8F+BF$u~= zpDU3=tlFJBBuQs#i9gLnhyce!!ha7W4J#S)#)4`0eblOwvl0HFJ^w1b59dBsrMdcI z^leLvugWD%m~=|v0U%A8X4D@p+r>A_;#^(Ve@XW>uu?=(zQ3S% zcKvHZ_ph8X_M-e7~Z{*l{E$KhL|)CNZ?7Ai?0y^VXc1gXOq< zGts%=9Xb@76lO8?HnMbiX+<9BC7F?{U1T98_aV|bmXuLayq7G$y+@+LT0!Q+0*N!} zWZ>aJ9iGANlT`FFf@9^yk@t3=>_n6A^fgo0X)u`KVZp6ohUQlc`Q?g_5`rMrdYQ#^-jgaiG=bg z7Sl`3;P;y2R#zrOM6$}hv`Vs|xp^MqBAqqX{^ z<(B)<8_!LJMB6zO5iyWSOuX6A$2xa5AEZ3mLK1-ZgRha?LG>Gn60a|t-%>?=;6OT& z66JzXjdg*%I*;Bp9v~)}Dn=tIF^wsAh#Ska)F>u*dirL*`^ICnQ%+_0f*BDB0LBZ` z%Vp^v+PCLc)Es*{*g-LJQxd5RN|$1a%9(g&%pHjbG1E7*JQBYgJg+v@MV8qQaJ?8R z{38*f{^7n<-9NF3pnRB2aa+6eK$TOSFc(Zi-G0O+8tA!IwK>?>>R{+S8RQTwqz zx~zb8{s`){VJ5}eZ|UNbRAVgRt1ZJ2g` z&e?`2m)o%9t)WYa+u?*)NUr#UkvFk;HMbX%<35-l56ee4|NNNBMF#Cd&W~a!h+gI= zc)A=_0RTMP*yGsX#w)1{8_Q9p&woHz_9?1!&4_oG9-mOGYHd%CJ z#_ib8);yf-(QTPr^XXuH7TjbCcxChzQGaDpB%kwxdLkMK~Wck#n8DiM?#spXR~4 zQl&{=N!dw%Oa%C8=B1nx;P*bUG2<#t@@iG~(!+lm66ahcI!W<%gkb)~YwiQ*#8Tm4 z*mpY9NsJ$G<~+t8$Jt()8tmpIBA#!eBE_<|(R9*u2Pvj#oWmVt*nJ9u+yYcNH>VLr zIWuF9-^^D!d94=&xoKvD?vcKk)RBIgQD<)N$^tp}^WI65E~l8HZ4bJfamJyPw<{hx z(wv?{=E?VbNfF=EZJCneHjLezchTi4^{zRU=2FheO7pPJX(s3WXzZdV{IrA4%-{2F z?jyVgsm~}T=lx)P7KD1edMugcfBK$Yauzy$&1~sz>vrmwYsO?rf#%GaQ;^`!m-eXS0)FPu); z5G5AT3P#p`8=7BGOyyzy%fzlzo zKr?lHL7OStorxe$_2kJn-!mg&We6nF%yKjKF*pexEzQ(r3(c`h_$li(E|@wF!e9=C zRGFycRPP{K&QZ|IN}-cIFnt>8bnclt8o*#O!k|1z z32>^*5mOQmzGo--vF_=DiSKzb_OX`g@IBQXr{Z7Cv7=EKqboF17v;6*NbGYD-*9t^ z1q1TxbMieUv4%x?7tD%)-g@*s1J?YW37vt(;jFPUt(W#r#bjBp1LjbhmYy9qr-G1q zwBO6awUoC^?)L*Z$1t+t3{kpGx|k#P4ByjjnGEhcSf4DNoEybdaZma>GE~JZW+28r zY2@NIGMz;dO6B4fxwwq>$QXHcrY&-D7gs*PJEp6mA@+F8Kc)(0MsHe)*D#CsRTKoQ)MWQe^rp2Q z!w+V?Qk(nVnAyu~*fIUssQ_tg%M+$UE~bAFQKOmYrurNh0vuAB9g{H^%yPjDE(}$oaBF_23gRqa=aET((3C z84if@Eh7!mnwai}?JzxHsvz#GaR(PTJ#Ndqnw~D52Yti58GB?|t3Wa5_a#@mJDGBs zAd7gj)?=1Mgd8f1csAwzUUMbmNYk#g0~< zVHs^t&7+$QMMWG7YZ%NUIg@Bzj>S*@M<%0=f3e1$sX|31>R5dCf03R$f59V_3x?=u z%@nWw5FKsAX)rRp&|ffTLL~7M4bi+-43+q=Una+{?5AFsh`hCYPZG)ei(l@{xu^&t znHh1tw;gwq|0m*FGZzupM$8YQj(@SnKjxgZ!020kPs2C*NV(e~I$ARq(b0RRgReOc zYktmKxSOL2lkBiH=OhCnIYma`%OfTlMn^lH4{$SbL`PTFpw`H%3G%2;lUWbIsm^d{ zKkh}9^Hv5b`-Jhus+po1v+=sYtZ=}v;*DnFp!4CI=?fdg)96oC zwz-%mbJV5tps$(qG#`A=f>>r>xZP*_hu2Hq@MC(ZxmN}$6;khZ1IZds^u8#hcpQgG zHzP&yEscTWX`R23zKVXFhrkMzvfvsRpQ$Qad36k7D{Wb8QOYdw$? z75oimWr{TIXewJJ=p)`rY#n0Fw@9DW*EEo5>Rsa=iI2&{!-&w4vp82O$68ALEiEMc zmq@jDDocmgrM%s|;j?Ef4PCbyDbK<193autdpJ52^1%l3-^d!d&*K&;b*+Bv4!;z_)o^sByjP^d4uDJfz5mW@#pcID@L$b{CO?>r( z8mIb+;tHY~XYKRF0jFAja-Sb)@7$Dr*yrIa zgYVy~_Lq>-m4o?VK^m-fuR1_3!p4jT8@$R6mxWhN5FL&VM2#69V29P-62(+INO^0W zkt3Vo0d|-muUg{4?|=z1f(5g~t%eFrUM10Z1d+HSB+}tgv(T%Am*6fY-8Z}e9du2v zdzqoYkNalQ$@p_EcINE96NliRZ}H33)=B>vQbMVFW|wnF=`_X;$7Q9<#j9Rsl(PtP zzdS2kL!QAI3#KGiRbto$0>C zG{2@e#bPj+kh6X>i#*axM)aYdvuUz49m`VqGh11WXjPGO+ajg7V3t656N$2)&z=Y& zbND9uM^^j0IdI6$eawb|gK0cevjlFtI?T_^Y(b6OGC|8d)Fu9qGatzLZc1_3X2&fQ zzsGJ(I;vE%nTTdC#%`FP(f*=Kyphx2%sZ?-g=vz0?zomyRbw|4nv8BlZP-LJlVi`{ zObJ@;cOl~bv)hBBAESQFSB&8voMM4o8yL24Vhr?@Q> zs@F;VsjedYDV>PE^Qz$*bT7UNj44X6$gy^g#e5E!jV}$yu`3$|jFEV;8d-yAGWg1w zznRFYFqj$1A0EZgyz04zGE8`~TB@v^@tIYa3?zCc8OX*^+X1O`_%eS?vp8Deq_;g& zeN6MoDwnWl*EO%YuA!DFgL15=Aj0L4>f}{3GaB>{);qUQ@Eo}c-UU)#myhwt3P_Sg zoUPX_!ql_iF{BIF@`NPr(_k$ zW2Opk%upvy3W#D#4@g|X7L!U%mw3s<om9RwQ@o*a3ENC5{rUca5+QVtSPG8Y=wwId2Z%^Jpz~ z(vKN-OsplASYMr$BmgXvg$~nlXnE09pr^l#n=eT1IC(^;n z?9xro0?m|6$&(W)qwFV5A9FLNyFHm{In6ubup>`)Pm&uWQ`J^N)|(5%6{zn_p7AQ_ zbTRP#(sWFoVb>(ZTpdQn4nq6fF7aBa^QQ99A<=C85b z*2asmmuxUaL6i_)lZoyZIUwNH&xx1lC4%nTe?KA0ytbQ|nl!gsm;x!X>L~8zKI-sA$Ap78uQ48Rkea zgBrUPZ!0-?UE(#fVUFqn)1ih+q+wysMT-*684H+(@i?M(jvKz`%#?Ql>jqiz%YS*r zKW5xBQR_uQL@j0x^3F*E-S)TM}S)tp0a1LU5&K;xZd6LgrjFL$&Nuo{}t>EYG zP6f|F%DF%45`xA8(pbG}?j*`m!OPA5ni&@yR+8$(M5kLjVv1#fO^*EBGfkOaw*0W5*FPcRz_zZEv`Z3?^=l-+j@Ub!HazJ@*Q2Crvk;VnSoU4QDWU zyH{4<`U^b&&}^)91=KVjwGhRGR!2FlN1WX5<)Hz2PR3)!Im&57X2oIb*za?u+iL9Q znwPyfXrGG7vDXth5o!JK?LKFv4RWUM?-|gcrdJLBG3UEO&XA#C_Wp_s4-z|>>1HwA zH`5iVFzJ|?^%vc{v;hsZ*Y{@~-r0$(v+Qhi1JMW}i;_DxyofbY8NaN7SFtc;miX~= zn%kbEenbiuX@~qJ;411yfchn?abXv*B&b#^)!>C(eZq|{Cr7ambR_Udsb{XGq6^HfZE5)LY& z`81HT(?x@+j5QV$wNGD(c^+?7Su&0EiiCo@!Mi1(?OcLsc z1``(3Nn%=;_=A~`m=eR^=^N(F*gXr{XP$K`Q3*x8*aXB1NfdLU&(UB?qLL^!HWRLK z7RlF4Hm^8hM#x$Ba>{))%=@0%w^gX2jPul6@eWED1o@N+UAO;h3+O^@{=XgJr0yF!^H+jLhXD`*gRMW=6=vsun! zx(fZsJzPbT&h-<|4<=rV`O{lw{bEHX#5C0XX}fMyV3SW7b#ZZ|1nXE7bRR=wDdk4tY0nC;mnUo1`Xk+~J$(Q{=#TCaIu!taq^_HLC)IgiQJfTc2i1%u}i1 zoB7I#K>L_?Ot_hc^}c5^veP*t=j%<3Q%O>Kli4cW_0QSzvqehg@n4AL7qZFa*8H9* z*25%mgBH;>WV$)e{nO@wcQR6!Si3 z2@msLPR7pcPUp8wsd|#68iFY&o0?@y&Z6eswD2aed!UqRP|X2@ybaK>A?^d+!b3j^ ztj3y|Scn=A_#@8J);DoWV1Z``aB5*y;g#8OBiXAS(zov2M{5<0Z(>K_#8&3?yIDs6kQI=yjnNTj;k6DeajAmU7?HAba@<4kA$jQuMu$%h>F`9856`^O@3)R-C7 zJrtux0JIT{k;Ka|+_s8{P-V=FMU>}6f=|F8p2+x*=Fhp=p1~-15X@EH^eWd~Q$_#9 zDz}-~Ih9{?J~25z&&k;7?d7XSF*!r&o7tuFpl_Hr>uA(iX(3hZU2(dRx!;iS7b#*Yhl7X}xxzh#o=#S!oa~vN z6-~TZ=l^Jg&|v1QYHEaMtH^^%Yl&iB-9TNs`7GKpk9H)y3lG=j_I-AAYG6n54XKEW zaa(IB=yOOB^{H-YSxKE5sy(cp?_@+Z$kh`O%b|%}=kc3}voi9|)kL+nul zw|Fu#7UhYOQKMTE#RD*m+91k#!T6#D5iv*Z9s=4NQZqNWOQBSi%;eWuU>1W=b`_;r(c=AlP1pHK|@@GT&%tX=(lu zr-k1VS-UoW6UR3$<0Dkl%_}Jb3SW)(K;0X(&2w%tD^7E2|NDNUEO%zjxm@7BW$s92 zWvq&6-Hx&)M;pCj>KBDsx(0DZgSHyK?;T^Gzv~^$;q2JoJn4i|3ItuTjJt9z9)|UBkGoOCi>zVI4VC4Aji4J95yghd3L} zytyT_BwP%4+MF=|GXno>)7g8@G8=9@TOyiM^Bmq2xrV51%nA4_yOVLJNlhij{b?dv z!G`or?AE|}zSYfpBV}+2Ohz#%=9Qe|naOiwE)y`=8V~%h?=247E$w)Uc{S(sDLmYf zTW=gHS$cyg0cC^FP!Sh*ujM0taHkFX@qfH~BVST^%e>POoYbd!R}|+*-IF(3VfRpY zcrDhPFPD6?36; z?3p~*dBSDolatvwsUw}_%{Ta874b?h8sY+Qx~V4Li#=|PS^|KE`Bub*-fHRwj0?bi zRPDI0qpSS>=n5taK;w-ZCR>|QX-&Bf;s>k7E6)|3gbFOY5yaMF* zF*+1QF=q|$Q$<{SOY4rLFOpi(T>fNb6E)wwuvkBJ%cS)npD_6bc;cQ3eb9e1qZCAl z5ohpRq=gy>a%!^SHI&-sgV#_IwH|B{r8-TlX-i~o((_Hs(v>OmeKwbTq5g969W%n$ z8E>G7SN@)i-bD0lYNEeblZ*tRCO8+68SLLDqn0}&Q&U&Ot2IuW8*MOq;)#r-2cKG- z>NwAFAFQ8%tctF)ubEhr(6CG1u5=dVt+cXk3+QQ0!D&b2O`2Yt=FI@!8~^>;^*souKC#S^{2 zzIUJ(FkVG5k;@7Dt$jZRFrPgWxwa=BBqs*k;40UW(qH6zMmdjy5i2>YCE6SnQ@_a# zrmtDXUQs(a%$1GU9FOr-mhLvp`<_XA_yMy>DW1X@hPkd08_7hxrVM?Z_wJs!up1b< zwFHF3VYSb?0a`XfMq_rU5&66&Ud?xw=iYEj&Xt!|@7(>Ui_{q_gN$2`E?Vap#3*Sb zuzW44#)!MT}*Z(I5uYbRKWrs@~#SN^5^toa@vD6>}k{Wmk99)A2Ru z+E8~h?knDA6(#mHlX4y~M|&ghUeyy_-;<^tyzmSTTc+f?a7UUR`Tj0a$xdl6=CmB|=6<|5&G`q}g&$Dq>NyV-Wiq|ND{+v!nY?%gMpMMplF@ zD#8y|YsKV?Jbg3!8vm_!%#ZHroM$;riwP=*3|4F1)LD6qP0LQ@%EYa!Dx1W7u`)-k zkk(sWDMsno_O8SnQ6tvOG_NIt*>#tn7DG9=k>*^VrWOOOkXp8`Y=Zoza=@&Kr*YUa zsbz;FIbkuPB}P>axjH{QipKV{e$7Pf5S*MAlUAt82n1c>1ZT(rlfE?G8LHOD;?6Mq zeGhcFJ#lek7(~2MsS9hOzAr2p#RkP2U9|?s?R&D%Y1Lxnjv`*|^7vq8!k&1u$BP7u z7RGR>?&Tcy!Rnz^i`s!AE-XgYy^F#TWlLnmos*kfVyX(`5LJV9-jRqhF-Bb=@yq@*Rzy@+e@-SOZN&H%e+l)*FTXTr`P^s!jdfmvj{xL9JUR=leht z9OL{Pk9;nK ztf(gDo;~vFOQKmBHOr{#;Y6iTn>v=#EDhq(dk<+3X-~Yemq4Em$oDXaCo=l#aAIaM zmBmqiNh6AEuxKU!&CEwkzIWW7$sDYcw}hA?(!-I@deP!++rJ)@=o~4;JyGw*J+UG> zD`o?!4>m){fOG9BTjXLl?vcTZYBbmeqppWi)$CZ74cc#^2``veJM#Zy?aPuR$8}}* z@>U>m*2mrdwq9h0;LfCr5P7QmE3B)`3lu@jL%{5`09#lw3o;*janW!(n0S@t9kZHO z!H8p$$t`@7W^FmV&b&fwb3}>gc!;LPE8=5{xb+_4LDDBpGGj#}8qO?sc#t*KDIz_{ z{EmnX-SkNxXp|T3ATnBT@MfmbWpH`%JRge|oYx#tYn~iLGldv`P{fCLwd+wZQwm#1 zroiA!a^~++Jg{|ij+l%G<`qm<;~jHMPCJh8n0*|$dpn~9-n#QX4qVzCbLZCM84&|V zY*{h)?!B`&Xt~MM4al~Y4vm0qxS^IgCM~U{7&z<=ZURS%8#Mskq&XLd7`M9yua#Wc4mB4tKdK(zX~ zSgtuDXw2`3q1kZfk9|;pIa*oDKVGh)7Gkz3COBxN5+-2g`c3gOCT@Hsr^2eDM8s*9 zc*R$#Hp{%TGjy(wOu_Ly6{A+qWqsvqgaSy`)+DBHv)(wK?kLsuKt)BAin2`BDw zW`-JvOixnnW_%fti}kc4obqdqXt%SZ!%<+4K4nGJyt{{ZLZ+W{#2x*Og?)uN*d!K~ zeMf|s>pZ7jEe2kg|izU$(_tx-?R$n(f!CP>pckcxJDi>m$e}Pt+~M=j?VwHxGdGgV6nfAU&W&FYw?kV)G3~~==h5XN zWXM_XrkGjI?!*Kwd)CDSW!ebhPK*i8zh<*=br%y;a>u&OKVAw?`3r|zuk&a#v_ zFg*8)?Q)v;*!%X1iIblzn6#?1L+2K^*RK8&oGJ5Vwxs2a6#ixm6>~>ke&|Hjj5VEt zxg|0CY$-Ebin${*`7%e(PokTuK0UHj2N3ht4I(J-1q`w z-~iM(L;R8!4El{mW@aKIPcl;oaU#~OJC&yqvBpSmSLYO6_ASc-X0XvZeO5{^`88KC zBc`K-mS>pNcH?&6)2m;$+)Rf!dXaqP3$Ld&AjT~K7N$gO1-9syE!~8blAeJDOK-gayokoJtpwm`~VY z^@j6?Fw~lrolPnuj-6Xa^(lKv6mjp)O_?7KB03G6~)CU1QOlUC&y{TZ|D$e}(bMJq^W zGVSQG&m9?NVO&`-w=`L2RTjpwbS~45G`fA!@Ao98#9y}LdcZD@z{sFrZb|l=x&ZWN z%q`gtG6U)jvP|n?X2x#)aPlY#Ueq~5{Ozpy>qU8pCMeX z$XpL11|A~4dwSwo=HICGd$`^`^O|jnsrd;HvlPC`FvDbC1{Sb`dHeKV?>+-leDQPR zhPwO_b7z9t(Yb($C>~>OStd_tH29d;xgpZnTACsV~Y7u3*%s3)(?53 zPv}Gq=Jk%*Rhh6J{C9QPq{_rzWplI|Yqt+rhYy%0kvP1?!?ZfBu4+dyIb)`+V47Kc zqfan(63!emoAAi!$H_7iMNjVBP%?ivb$31@wlJRCLCn_Nl-e~%#HqtOBGO%@@@`~O z91!#ScdTZ-vNlZ-`FhGb;+M2w&=VRZ6X_trm!x<4yQq5N1KG=Q=5)fByi%AV(zD3# zh|L^}UJ40~sChaTXta%V4KaETae>CpVx<+FbzY5llg`%G-eSGl6jLo$4>MS`S7!x3 z&?%8i7ZU?OLn-fPXZN_*H-xT-6CGGt=hjH&peHL&G@hLuw@7_49Q^LY@~ncPVXKQGqJn|(Z%5|_ush_hPTD|39n)o;x;ZPsjHtU+ zM9q$S{gB0)YCpetZt)_uqSf<#5JaDa-T67-dUg$IYR~tvy8IH z65z-y!Ayj39mKMN2+uS*h< z0tO&Dt!HM!6r|e~k;(D&ju<(AfkDSC0~oe=s0)sUtG;8Fu!2ds9v#fGL1({sr@M0r zit7z|ZFi>1?^W8*m=9$ZPTL)pEd`!j!q?z-6h(WjKBu`oZHoB7>rSzLMpY35xLJlJ zY{}q0&`gy!$6S%ZA39l2bxkq1q;QNFjvg6!l#vN&q32i~&%{Qbf2?y%3^7?5H6Joe zgiO^dBNH&RhVsLCLm8#AxqIu9dY8bXgLxiy_RlZyl8hu^Ihn~1r)1}&bFD%EaeIa2 z#_PBMY1VK+W+lr^f`?0YIyf!h8qPW5!<9RTCW!;%dD7?qFty)7G*j#BzT=3|0l9Q=8p4L~us$c)|m zIVM(;w0-EMd(wzO1lomyi2-LEWa3J=2aPV{1HkUo=$<6Dsa!Y3&zP`0@F-nOT1Yj$ zW3JG7Gy0%~WQYL75!0QHQ<>3Hp6Rm)CM<18O&1edJ;yS~gjUb*nD^@${2&=juyyv& zJ8IAvbIh%?)2Y1CCzv~D4^}7L`9d%QfPi1tu4%z23LDQOc6BDft* ztR5nA`%F~HSOUn7yi&xIEPg^iND%qT+X5o`Eg9%gL=BR9ZyaloGt;M83hnpac%!Ne zQ%sg#lod=gCS}U@IpzwTw;lYInLN9g2|ITlSu4vyRf@TF>o;`)=o8GHd%tbguiPNN zPfd?SnMvE@oMQ6c(+Z~5#oy=?%)G;&Ck$9}r?l_hRMvJQ{^q8qMmEgNJVUHV%9`Eb zA>RJfmp4h}%syJ8GRBMc(KW-|qw})$BGFmz!)>h<8I-^JqL`x40;?6QU1F{1p1I;ZU4u;7j zrDCFJAgy3xn(#rnshFnMn51-u$R-j*RlzEJH4~?mOGWD>8mD z?qIS+@j4t#m2U3$EV!dK#pL%)@0jtxn)|NwuZ%VfUuAsfrM{dnhdHK}!FiY{d+bUn z6%#Lg;ayf!l3gKO9j&6RTSsYKX%3=FxH%%q|GI)gLFA1uyvmFj(jT^8(3I+UPp_F!#Gfe?A2dbzvNxeGr^RSVGpxdJ^PJ5 z!GwHk@0hn;Iaq^rZfPxi&#q+cp!KGhJ6f%?gimH|6mv(f6>DGaEW#?bQ4uP=7kMMr za7_{UBEvf(?BL3xPo+_c**&RlYY!vq8mg40f-h0B=0x8tbsS5YB9be^0%Ep$HAY7j zQQxE6M22Y5$+sifAGAcH-PmhLM3$;6pA}3lmN*tLqdBHG`UDenUhkOaVd1>bFUrhm ztpqXWmhfdEsICZG$3dZ>Fux<-v<1VS5Q$pK_zoE{HiP+SncKu^y(?^#Er-a$3q_PV zO84=Y{LOWaD1G$~V!$}DkDB1+NM)uyan7XnDqU@iLg40x2Tag;E?`z`To2rrs+gR> zo)<6?bz|j)%x!vLbnk1jc4>}?;QB)8QbcgQI*1S&3y7B$NnA{N$t0+U*$nPuED#xC ziis(NoH*l&j0(syhlEXiyhGk~iC<~S3m+|_5(Lwgz{mk$B=-X*Diqf=1tPcS9Fw1O z0W%=z778s)87{ST?IEM{HnRdwF|Unlzo`pAf5xQHT+ludiQ^d9h^gaoP$a)%#he^3 z5aJYb&yES!(;BpS9y6XEqRdniM49!waok<8{m zeO^(SW8yuw1x%!OZ}bVKnlW?CkTLrpGxDaxckp)XJ^Hf93U>;#U4qH8mj%p>$Xj9N zR58PNcAriJ4}dt$=r8#y+^k)vh?MK$9g)rt4FpBp@l)<-!QkV|(3rgp+KFnDlT}NK zxsy}5Bi7+>oLL6EJVXaQ%wSjE&g&g>CF51?p?9$Z8O6fJ!G+iXCiz#!iUe^h#+U(i&-NI{#$|Z z4;*B{`U>ag0deQtY*|N+ToJcUolH%n%u~-})=N1#i!h@W^8s-ydU+o7ODix(9q~Y= z7rABDqop~f<~KcQY4x`yB!10Nsvo9#P&MjE^?IOD^vpc_7{i2*cC5J2!G@9C=+Bt! zC|b~GA0#VL4x+qc3dc`JzuS5s+AklQkz z`s=J0U%FI(882a+&pDUuH&XaTPjgHRp@}P)7Sa3gX8@*jXyNP&{%JkTM>{!2qsW+` zhkJLbs*1hM8-0SA6vs>@Bx_V?RUk6`k*p8NF$-5K>CD z4DvMQJmv>aX2ujYnim;BqcX{%GTC^J#8;^UXm$ptBn!r*c1#f;tPTg!#8Ic$lt$>@ z^Bu97?rj)XR&=-v^o2zZyezpr$Ijw#5X(DaGey~19Exau{z}C`sEBFRMojSl!p6Bn z;|`{9%rSRPepC0?%6!1wIeR=!uE!IrD~b$G(X}1!Koay(ogE*|D~uL+{ibfPkCaZ- zlr3;OYqfatFt@l?YU!*TCd2D{K+HRccI-?G&Y^L|g6s167-(9;JfFW{VMlZ=+%>Kf z%$<|p)CHhVFn6q1l$0?tTEe{65$}9%Z$KKg?%WH~$U(HoXeWam#047TiHa)52uqM` zxen2Drb%?~F_k$cqNCReCSru0EK*Fw2g;rogSkLwvJ4%Q+eOD2?c6#o4%*g=Sa$B*lG~k~rHHuk@{ZW7!loU3AH&ItR#8xpy`6=AO&`At2pn4ohZ zw{TMzfc}QL5)ns?oe^=FyR#Q#M;;(Kh+8yb2|E3J2XQ5{VD*FbT0z|UjzpBfKwICj zVPO)je?|PCzGFj{{2vkf{uIhK88)na2ODWwHQ!PRVlQlM-Pp+7#5Ll^zva(UuR27-rv^6T9v4}cHR6o~2 zL?u}lfl(S^!K~Pq#g^%GMZ!g>U1JhB>BG(7BkXXypPS4|9Re&l_)e+(<0+oLBbsfwFIwPFE%#(}6+`9D$sgdT0TX&9bte6)N7idK6GBKkoGjSf` zSx(HrTB;-CtBQ!|Q&~W?v0v$I3y2Fe_K|veW-?=E>)i1ysOF_zt(ZF}zo`pAf5Tj$ zvyarDd^_Sf!x~($fkP><4eIrdxzw9qF&L&42UGh@=a|e(HJ)62-JO$P7HhrG=JbH5 z^`{PvHt6jN4kAvy;7NsI8NM3P>0e~B(1RwQM@4U>pWDf_)fH3ar4wl_Y(rzlR54Xk zIG7pZ_e*rnu6-X)lsTA2tDR(*DM(wo;zs(F9`peeQyS)cs{JGFs{3 zq0fg3-$>!7Sui-5NywaIURJe#F}$vb`poBuCrVo{7P~1VZYRG(b`g$F_v#!Mczw{l zUW5aVWd9=Poo#6a6L!Z*i%T&z-{;xa^!2;5&uikLdz~(#65v~O(tWDgxIW3lq}{=o zy<)0HcRHx-iaKjkXSwX$dIBR+ayW`J~x2AS5PPcmDdhA?2(G{wY*B!O4rXxJad*L7crIQ}wAKYvzo&zF&rbf*3H>wnfD`k| zhUxUuf02HqaKem>2h42WGrnW?n~t!!ut>i)rxV}S!7nFFF)=$kk>y8B%+9VBmGCf2 zLy;rraVzG9iN`B+CVNIV`ZK0k9he~PVfLGj7}=8^@P{eN-qa>c`R;0WMohlV*4{Bo z3!szH`zf8>hWZ`f0XF6Nk!2Gk}itk7)k8|UDc2mCDYb=<%-xHHOIXV1+PJGW5 zIx!OVMt`Pr>wBW;vCBqZqeZjz+Bwgkk=GG%_pO_u-4#&^=#yfH_dtQoRj)^-uRxnL= z{*fONJu}(4qKQ73z|In4aB*j>MyuDQ3Xg!#n0} z$9#F7XBR8U^jiStJhpoy{qhpxQ;Hevd#+5<$ml2IBG9UXG{V;B zN?wo{HL&FX=`{NxpPCWVR>)A~&gYQX@`@i$CZw22sxRlIdpFXrH5aCk)R*T9Bo3bA z6cPugzMMnmGdx_69Q+)w$AvucEg_C%dIf$YSn!GuhF?86>$c~<66oLx55i-FS zI9DKz-M{ocL*jbqt~tgQ6-IFmevVw^LDE17Jh+6pK&2V3(Q~XU-H_;8DC8vv_aM!1 z?TjsfGMGL;^E+f0LP48n z4PwZ^Jzsl0hp~E`Lh|*b6-cZwWH?G7AvUObom4}ND%|wo_ASE#Bx@Z$6!7F?$!v-u z`n+w5xhsn>*@yP9U~UPcKBilov+qcw-jYETL6zB9yUYoFP9I1x`90eTCVC}0%TO@4 z*z=}th)d|%+XjCohWD_dwaU0HvL_(t!{u(Izn+yqCY(I3K$?(CbxtLO9GPfUGU*+X^?RRBKt7TryDVXHVg*)%<*PN%A<;sWALYwul*wZ zzD>q91v5y!u7?>>HPgR$@m-`A*1^1~3qYTo-RMm99ka8Q*za3qLK=B~CC`T5+^#NE zG096yQ6HOz{>N4tF_Wqzmp`G8a+{ys_;clLcIGUDrZRdB=ImP9(qf#Y9aBhVEf->( zpZ6HmH4p~|%(-&##F>M*;mhml(jj|hwwV1X8iP&L2Rv@hxFw>9~ zNQ@WH=^ZjNXNMl4G`&?=TV2;STA-BT4#nLyxVsg1iaQi3?heJ>35DS9THKvNa4l9W zxV!E=@3;Sx9IY!^S!>D|x6O#3S+8n%_mQ#~Pq+{F$lD z^4HkM&$K)^MaLx9C9EG_39w^BQQ^^Oe>{YwS8ke8y;JiPCx}t-7MEy&-FQ0191tgQ zF6cAw7k{3QPKX>xE@nSV+RW_eyadlu;$ z_&N5lB*65K>OIo_&rdGw0IbgYcX-Yw)QSH%gp9@rctx4!HpcGZHibHu8#7m#Wt!qd zeY*FxM6IP^{ zQQ2R$cwxAmUWG{UE9XdD*|Cb#UeDCOod%Epb{2mOnU!-!LuCAmM{T!ZnawB-`K52e zecpru@3K@`srad zjksK_-=XP~0^QxlKZ>{aSU(spc$>>(?GPWjJ<;|L*|QW*g+w9pFrAW+*$soix=P#$ zc+5*qHQB=MDP#M<>==y=fMlaj0=mGNaKhrh{GlP`1xb#Cyez#UU{!e62EZ=J#hjuJ z#ZSbe=0FDNHI*XFuWZHLfuxuqs#uQW*W-8J3DEUsc>i5wlSF~bLKG#XXIutCNa!?$w^cCA+7(E7UP$S`{AF= z#PMi4vd{&uU5bdNbI`{R&}Cl(k^-cjwIGSZhs!~yVjlS~%4YJJl0-el`rz>5Rgyv# zg`Ui}8}jPsW`&r~782r162S&Tw^DcIjA;iVdVG9yxm^Ys90+R<{nJ9@w{Jd!`#~Fq z!LeUlWbq}-rJ@;nBxS(4CXBk|x>O4r6wYUFx1%OjVmZi(e!_+uI^g{KtYwO>x}Qsr3_Z9NyLU5 zyubND6IwO%ow?aAvI){woGJVnMl`~e93#61(==!Hy@Sf6L-Rgz=jDwKoX~4`r@|t1 zb$KNGS$8ro`SDj8GyD1W6Mffgis{o_G|0!YmjtPgxBr_PDZFYe%igKd1&LYmpGj%- zeLtq?eV6_s8*_N)o+l4UClpwrAM*NbVtX4(C#b9Q*Sp(NFIRaVg(=68$yLz>QXfR{ z<0`9Q$7c2#mMPo{oCSeL@PX6Fd zt`Q2RcV%o`SK;5F5apfR=G#b+dN3JaU7&U2to@7Q+Q^en4(mSw$i&uzHjK*b{iW8j zKl;^4?E6XT!;P%=sE}d^eOls!n%^dhk!fvTud%G8cbO*vkHYxu|J{W#xLY&J$;B4% ztZ(rq;uTO`7W2vyn~F?p{ETH41{wsL_3gT%L$zG{`CvdMoX7?s$?@pVnMIu_oQvJm zdO_9+5L2%Ej%L)X1Yg4w_ED9OGeQa-94E~0g}LE&)ss|^f{@{YV5y{HlUD;A(+l?7 zQq-x;`ZGS*A|}FKQX14JwLEd-!c#zMA1!|Vk|@9HXOc6q|`+L z(S1l_54yfrZd?=*TWzX=mb|L~v`>XVM4SmFfUjk&yK4yU`Km|2_U(z+*HXM=!TXYn8jvu`_GE`dkD<;y&u7 zsZSzaemOBT30FE=crldNoB{SLNt4rs+m_Flqe`gmVGeC+2lttZe1##_Mi$UE`m>3n z+pUO!y7(D34RmEW29gNB93~kBOPTQXfT4WAl>BUd1MD~QzKoksYjv7ht_s8ymhN;3 zeLlAPp{e7HeuqPfg2qAjocBK$Z^9nMt2vE^&_nu~FQ|zYE$+M1Od8x8yUoKFwF(FM zL8}S>4#_#_3X`<_@DA@ij4gdHbU$JXd_OI2i;dQi)eUH8R*9`c)(RNhF=XDB&eoyXVX zN@5NgE-M$CmC&mcZY2G4pxS0mPJ!kNg)D9DhYLBN(C@6yk3y9?EeiZ!w=HW2*ouwK zI!NIX&7ZByvRkMGcT__|2^d6ZErgKY+>LVpSS?k23&L`9jWu6AI-R2*+MFb{skCj} z4y^>eQ_etC)_+0}f{T_7yhL$nSPg6Rrn&|)0VckBCRAni@jvk+M46#DvJUNUWdW9$P7e>op=p+CsvW|QcB4+i(*My1W%I};iHb|zhE;OiNPEad>( zDoXPDnXi##V6(@V3J_HFpCKxrV=7i2j^7CjPvEgIdGPp1?wqySgQ!*-JXdCp$f&>b zSk--OQ@!sUUo?ymdQ;$NIu4^Hcp5!NE%JM~PD zFZiyOM9iQcTOb62AFVD+GUPFBq*A5W2a@lETeTUFVSl$O$aOcz>>iwyeguv#!KwumbQSKb}B9Ps)3J3YmdSw ztWRAC=|!XR9BY{4Q^djERQ_?90z(#=HohbFWt?5mHkR6VA6G!Pdg6#y*cbcFO?@2K zoP|l_ra|P#A1`RuKqpQKuw!4)TLemWpWOdf&yB6Lpmz`1U zrk-xEAtUWjtxr&ly2>f3bwoqY{GOa*d9+Y5my#ef=UF+oO1G-qN5#3{!ef?+%9i*= zFkq#MKPw<(n=Q#PJGVi>q<9i~7mvV5GrA|CSN|?eIf8*iC{uxo&w8zWAFYjoGUzSV zB;H%hO0Eu?!o0+r3E8GxEzh6Ct&fy(#gLR#Gm%y=8Z+ZvL+vRtr_fYb4^5xqw^}oy z_%!MmoeRJuH~x2%)qX+8p9l0xltX&}Ciaq$eGMUO>AoBFzT+BN^V{23U&j$Ozsg)n zYouxf#`BcALO}SH_YnGJ+G9xX*N0#34rC@+_G8ZRk&e0>n4)^Uk)2?E>RlfLa;%sH zbrQ((L!b=P(pgQMHvm*YPI(zdztS#+B<%Q$Kl|=ay$;4cD_>e zc0YxjZ2FNNz8PP0oy(;6zOw|FN_t6hZJs3NQ^Zw@Z9T>0R&dL>#}D$$I3(d*X)SQW zaK8DNH}eNJZLA=S0m48jlcMI)x_Pxt7Oh_2xp1N_C~#`%$Gu zLMJd9oAD_|Hec@6Y`BI7mlT}vIh*THgHLdq-xpQx!VU`fff&b?@^lM;y8)YB=?L|kH`a*LtE(8yb8lD3l} zXS(eg{J)JDD9HBu)8=xb@#;i_%|tq7Q*N_ygn`!mG1)Nm%VE@F8G^v|B8lme1S5nP z`=!n4E*#OXY1MMfBB~z*enI10?Pv|93`vN`l}d*TXP^d+J)r6G7ev;h1@FowHi#9Y z612fSx-7mu#2t+YvT{i`9S)_b-oa7QNI} ztllI9>{##w&uOwEX2oZ<#{M|T^-42WuK(w=^q%>rN2y|s-`dqhT&WV7{HvkA@7xc; zlH4uZGJ(Up)nw;Dovo$al+F_4MwU9-rT!MKpBDKG^}SgzOlzDzoqt>LFMZjFs%+5M zt{Py+1R<|{9ABu)iF8bVJFjoCW@?jT>rzt!ecb~1ICfmO!-u&8))jivSxMU1WVS50 zxALv;UF1gws{h2+@`%0JcHQe+`+Xz73;~SEFVQpk$ zA?znd)&OPX6po5gg_mtKNA-I5ST1htMK8`5QMDeQ3-cZQ;khTj9fC-HGTflpAoIy= z;zRI5mkCEsrVjfGYtSP0P|-vJ6n*yh?vUHE3l9`((M&BO&^=<1KEJ?XWy9AX4oh1x_w2t>X{uok=lC*M1Bml8* zZDE%-g7P-h#G(A^3&DHiMUALV-jtRz7Q=0pTLVDh7UymnrBe%-= z@3^5`nvfxGiiv|Io5UWwryi-RKn55*UgpDZz4@4P8**Txm2dCjD_7MvMZ98!;BuYz z_d0*3CQ;9CTUc(iyd2JOEJ$K|YXk`zHXOyGOi>=R zDo7p8=5T^YeZ(*YFSnaW5S2{hpudPIzi4Ld8XMUZhj-(^!3oX1XNc2JPa@DSZ`=%( z8JlVQ-3K3-A&#cISz@EP$rhnB`ov+#*|Jxkjml&C*;PPVQUI9$jm3q2Vr8^~yS)tA z!L3&&Cvirq4CuA%EnS0OiHB}5el1oi^cA6zs2#11B4*}y0r8lS4fwbAVD&de4$SN? zV$*v+1ThPzGNgt-DfDGA1Ag{w;=R01fwnv(KxT^|v5^Q*B!^BVK;x)8`t^3u(3x-a zLUdk|E?|;qEolFNX#${6+*2B3v)`w58LC`f;s%&Ob)AV-6UYyq6|}0C$(vQPM>XclM(=a0!N6PQ(MtsEg#sIKu{PM0K7&8fFl$mZG*NT>x{wG9$ zMW5SrxJpJkw8>&2>gV@K8$$cq!xv$X2%AaWAn_0I)SymM&t@j9YP>0)1}R zQs_G_BJEBgGF?K1Hv{hww!qx*>)QW#+~eW8Lns+gh>v$`z3_2+T8r^LDda+%=9xA2Ud}F(Wc`$C`#!3SG02Au{GthZZxPwqD}b zICh7pPvWUEqXk#-5C7c%_>hpGN6~ar0UV3Yv#K-{XIG$-UiL#dMv$QTfB2Js2*cAz z+F(okgjDK~%kCfe^32n%OkGCtwdBk(tA5KT4SDmmR*-#|2_oD-QVec^1F4#o@G+DE z`|cfO80;T2$l?0#qeK0oh9%aCJbc3uO)4wPvy6$~zTx4Qb$*jr@mJt){fb(J?@FQT z{UJi-?)nfZXBStkU^gkCyym6RaV%ekbT{mnzcleB-5mx?;XBr=I&_UM+#%tRai}xX zimk$w@)T}xor&QsV5FViz)-ZnY>OTmkfIK^bHT+H{s&~cLU0rAr52EyoN(c>CU^bj7R=j-DOZ{ zh8mmK2{LRE5yD6guP|RpBy;C&!b{!>_5K0ENx;Mhew|Wahw)s@mXeFRBhT#&B;5q7a2`YW;(?a*w z)%88d*9w@hDaQ4;QSos4r&;>5bUprtLAWjI!Ra{XY0a7e+0CfQ<_j5~;_XuBC~3Hg zvw}kkNgO(EP<(ydZ7*&XH5qxr>arG#Oju@=s$! zPPCh?(i7)uwe@_;JEipnDU%m1zP*^p7j}iGhAz`d!Ohl{vLJGz9O=G<(Tk zO>=iloNVmEFb|UjTG0qwGj-cf5t$eq;hcP9ZlGZdDI0@N@q=m*6nM(Ir=}Qa&BBmf zcK$bH+XhZxkbm^Atj{c8Si3WC5(HcpH`0HjvD~^M7~*O(s$Lr&5UO6?w@BM)Rjyej zEVKojY_<(@N(nxUC6kLcRixM=M+gmm*1dU@PV(;3;Lnx8PH|rvG$M=xqPu|sD$CN= zBeFZNTxKN@SGB%HJ!@%5{<0zyl2I9uCPWcCsU zK1NcL$$HpqnU?-W{i(|r{3UM7jA_0M!fd!+zF5j_+bdYJ66nG87~U*ml)qLiCvny7 zZuS%Nom^0Mwi}dVr8B2@9d0Hm6VeO=q8WJ4Og_yQZb0khejjsGU__L+i6KpmS$}|j zuRXrOhjjAeWRBNtWk^8(H#}Rzu)(ERro>^nSeeh;11)YC)vMjbLbCHHpcDw|!Itug zLu#0ruMcH@2f%I9CBChQUiFkf;E|^qVlN2<7m(%k9;Lq$Vv04oQ=|H>plOU##2Cx()-0mp8nJ7NqZSez3)XbzN2!hr-#Z> zGS7m&vOS;cPqEU-Q03Fnn*-+03LhaSTg43$rR7^*9xwdEH|$!kToZHke^r=LdY~$M zl>roFAiQe{Cj#tf4Xek{Ux*MW{ipqzv}xckF*B?Cwog%Vtj}tesCZUywI<=nt{R+l z>z`>MOieTb)fhjme%tr;kH^l1&hq2C9c;EjIZkf~aw2~gs{oTZ_6`=aqHy`*pDmy6 zh3(H|H(Wzaq-e^!&g}ZX>l5&CJM5*l$#Gr%LE?;%q~3Gl7e2E9o$1hbeWC}Ke!21N zaz0kw3hhIMsU^|2J^MNdF^V5+e>^p2^~otHr&IX1-PY=xluEpH*21fR`ff&L2V)cN z2~6qT$VS?12Qp9p?x|D&f-(Y|05~3e%XF$({jBcF-yw14(f9YD6q^|;Ju+CEpCDU7 z9r7Q>a-*>~u`zk=DP+iWYzPG9VD@_l`rVH);rx%zn40&@m-Fk5S$k>xWZr`>60dO* zU;rESwBRAYA>;{sah&ibNOP$*>JPlmHWP`JzF?mOcGU1^W=CUeQaEnI_R`5Nm4DtK zie}^+q4~D?INT-m1R{B5%?81A$jN4YWlFg*YK!7Y$mkr=qB+)icdRCKRuV5DG*x0WQM6Yg>~kY@jQ{ zbW=62U0fMPlOnF4C!g+F)}R=|*oyE?lKhpGfk_eeBFgiRn=P|0!9=p1AaqdjH|Clj=2r@O-GnGL={!0T-XF$kwo3JQG7Qc zylAkr)iF#?sUg^}>26Bwhr0YgyI>l`*)NaZuNzBI&tATxHuJNsa25B@ft;nYuxsT2 z=ykJgAyNDS1OdTjpX%|}l7c>GT1&-~f#VsUpxYGy3xhcDu$$rZ;Qng} zK>nLplcusF8l~CaM-spamar`ax^tKeCok32$BeT~M*Y&?c{mmNq!{<#x$2XMrPdU6 zALBia&ekVv47PHnQ6WO3JL(J;Kn2$Tc6$CgMyPu)X*+BM^;B$+=}#mXyV@%O-hq_x z(|_zbfh=+(J9uvYzPV7aV;5hXt|EbW!S@S@?1FDZXxG;#r=tE@>GC7z_zKCyTuH+Q zRP%?Sl0^&+mJV2Y;lrx?X8d>v(+I=|u0~R?(q|%+G13n()7B=(K78&@A zpvW-?8ZiK9{*-y{cHf7$WR?KYT`$+}jVL6+{3TbN_Z!te|LaF37D=GIL{3ld^=@(4 zMDb5=pyFFz1V8OAr1?sirOsbNsBbMP_rJFXy$eBI;%EB2WHvWFR|?m|kGF8KVU7Fz zv>VUzr_-kA2PIx1<;`YjAnPIDp6o`udSJ%1i4@0GmqIu$zqqe#U*&4?`7D^Bq(stC zv5Gz3J3dOeqwfDPA+t6RlYq{cpz|nC>a5b~N0eOh_HJ@Ne5p8S8nuE!zto;=2?-?- zSTZQ$!s|1hJ`e>n>apZII+_$*{lae`UU+Wn#R-N$G6sg`SQvFd_nG zp!IeQ-u%D+hfdTPMGF7B$*{pY*3ji(0VE5%Jhrsn_P{p#@tB;)LTV-JQmn|3{}-Gv zW%&#n0v77fAxXpWloi`8&EJ`2DjjY16Lj;}V;apiheD(e-!Cb%-BQaIPAgn{zh8m2zqrwlJ*lzM3gBP!PY(7u%+?IqcD z)PnWXNRe@ajk2|}&lEyf{;r$&yiGi*4qnP}6l)9?;wL=}B4S1@Gz5;(Jufw7hlRXS z#=jT8yP@vN0EncKhGM{E8m|%awyTCvKIacV@PE}L;y#!tflfF$#VtN32rT5W_cuz= zj9MCy5Z4%3^vk<~&bZj@tSrx~;Ty@=JHmu8NvLi=3zkOvhG)@!+|2^MWpo=I@3nN- z{&X7^-~YIS1B0Y&puL(P;?>6OnIgx(n>h9TNDlvjtbZXBq6j|p)Jm=JqvL2;`v(vR zZOaq|TWB7qI+TyLEi^|C9bz1CFtZ)qKEf{_4Md!R+ zyRJ$E{r#Jq))6b2X^sRs3uosEh+rR*!ZZJI{DrdkB+jo_s?3H$HFPq@Z$`;)W9gj1pvL%09TXVc7`|{yuDn$FVevXu7(4sCKr_hdl%`ZUEMgOV1Ncl@&R z**(});fHF=$i8uc7%`cHL)7YH%D22Dzv`U#3GZR>1ib-=(0npL6ACDsG#^MS9Nlc` z1*B_#BYNhjah@__;Pd5D9MPA=AJY8;7~)dsD0Gc~Y|FF-eo^p@6FiacXqKrLV17U0 zQ96ZUPE9$fY!Ap*^&GdeX_m3a{{%+u4p$wE)sP&!x&oExw4+bx1nqH?CkQqvBpdq& z&}qqL@Hk@+*rk`aeVZ_m&(3~$j%VTW`JCWVu^lgTl} z56|41C<$rQ*)q3I0Oif4nOX&qd+(S8yrIwvO&0Nk_P*s~r_^x_2+Lcq^a`QxJfu^d z8ES{8xehWrPz5)G*~=>u`FxCmn*@rowh(FkZlMktGsZ4{i+xlMeqTCSiFoH4`$V2| zur;;*5ytm%1`9&;GYP#uRfr)Hb*^ea1d9E4bDIPSBz*qFj5IHU)UyT-l$I1z@=42) zFhDHA>Bry+Ew9lSk-wi-Vwzc88OJ2!D}b_Y8tTALXfQti}C4hCh89Ez#Uh ziV+$`78I%(C(00jP4&)085yYREpjaf(hrt10S(Gmi3O5iS($+J72N`o;_OP409?Ki zsZqYhN$HGi=+TZ%>q1_@YO3No0$I$)?7!k%`76@nxN0dqu7hUl!k|G-sf+2y_%9|C zp)n#cRp>kG%$KSkjMd@zfeJ#Q$tB=;jfpyGx)YsvkazFkJ&G?dHM2qD3JBR@#s zSqyWEgs?iLdQKEA4)V#2-`lpFeEHwFnRq5^cwVHSP}ES`>!e~OaXNJ!yh^J9)NBwz zCMx8xG48BdkzmxDzTcMg2?S-F+aXjlj21G#%+J2(ZiMHTLcKRn2!z$yew&5pb(XmP z!2!lQ0NJ(rsMdpfr|)a^kz04p1eb8z@xoGr{aHz7)(hL$Zlm}I2=$G1`;nF~GaTiw zlb_8t@-cac=DMOkpN*YIrhc)fNS8K6ul3E5np_lL8>+#@ELBF1)P7x7FcP27fWklZ zjyeU0*-r-IO`okyxnmqYD-cO-$o&+4bxd3l>SB#~a7=VkBpexkqp}cUe`sO1tcjW6 z5v8@~K8gq&42A7sctd9|choN(cqhQNwob@lMfyAcuMYVePYuu;dG6(T<4k9Qge2fU zRk;i#8jTlG=RkU_qK<{ZU}EK%*;ZQ9chs)`_iIR4h#|$?CkuQ>Cg*=^P-T%p-Nz1C zIYXP@*DP@IG(J9kQ(Y?K@&*_w1dd$Vm4s~ zy-MMPCkYKH>btF;^+SCVZ3DSoHzsOf)lg^&B zdv+!#1l#3_f9;d#?%HGd?<5ynXWAPK7#Jo|^Zbv@jI#m*8r?lT;k1WugH%|Aa*R#X zs0i1h%TTS(^m!p+{#WmxzCvgk!yubr5`Y||i`6lA4g1=VVycUCeA_)Yll=}@^@(l* z9Qau9j$mD@eW{<>`~{!I;~YT~?A@g|Tfm8dtA;9dp0;EmWrQrnDkKM7<-Pmp0*T`c zmq4YC!E51C1;A_SM%G07K8Fw2u;W@v19907iJlE1%~OgoRMXzZ?e=4+`@f&}Rm3y5D< zdm<3ZX}j1D)r%E#pK{$*kE$!}f72eG`}SA9)C*TFL0ERT3GI#%ky53L{VW_0g^F0- zJo#@9)iAd2zRGa8x zsW$sJ_i+Y}GbHYwRIJn;Li)jLbVdZ8iCY=%SXFUhmvrC8unZ(y3=|YN{f|Z@xE9Zt z0*H1xT>cyf4z_N#?A(UQmk`-Rex)y2yl=mv7xzfzFOeZzG83v|)SLi)nery46(nS8 zx5NYpn5J9#a90YQBTd0$adtVKqFD$to4R5P^>JxS=qLS*5_lteA;2O|(Ai~~uZ!ZX z28?o^DeO}dpwYOL#PK4J6@k+;(e}swku>0FqPYens@vTEBoIKe;P`Vf91uQXx=V?G z^{0=C*TT4g?w5u)9=T)DrlT&jYTVHe*htrMGIV9+=e0T1|21zvZwDLY*w!ya!MlN8 z)WMvy&t$xH+n=Nc!leT;t{aY-?jJ*2Lu}rriwU@sC8Ae?lyg7vet$0gUP(H-xQ*UL zl6AQrLZG7@d&{>&s+Fz!nJ0`1miYhd7`Y~ALKA;ZY8HX2si$+Dl!EQN!IipC=Y@cA z9BhjM@wGnYFEcJP;aYNgUOMl36c(0z^6WE?QyGUt-1Q9YL|>`@l=3d9hQ9y(T8!zc zgASA8O;qeEi@6TPf< zY!8mokM{|ApKuCaNNJHTHl`tW5e3YY>R4o~=)p%%Yei|m1pIR9UKgMQ0N9Z;n`%!( zqibj-`S5!WSNolmST)kPSF({z=%&DYy!!rx2d_+&--R|X>v37@8YM9ryWA96FEChg zrmJf-2>XsNNiJQfhR(tbzcf%jn>yutZUzf!LV#Phts%Oj$ClBV?h=(Th}{-HVoc2F zO&rdFfC4xgm#y}y(Zx1GQfnC^9x`7Cd_^Z;-M&Gg!R7T1FE-juod@A<#M_kqRONvQ zWVcVT7)WIUZD_hl)lB5VE5Ww;LHRA{K;qf-!@K?OI2t8Pv6v)-a5*6S$$S6(6V})e z(X%KYudCAKiG%eG0++e2FxzM=eU5v4Ie`qqwW}GQUHQb}{M6yhm_$h8<`nq+a2nCd zaUO5Z4Os_?)JP2c(IAKF_ho?4Uxdl>Xd~AajRRnK}XJUSKn}^65`Y`Bbz$A>P?tOlyAKP>U*3-iT5(#Uu&XCaX9O2J z_d2z1aNsCjL6vp7ra#h;rdNi~56xz0ON0yEB*xjkZ{!#V=_E7!zon|s6ny(Kk!sHwO!P%nQ5 zWtnLL6RM_wjr#_8OOl=cv5kJ>H%4SL-xtz$%c62)YGV3~y$@bG`SFWs3IOFvAP?3e zW8P6~tDHT#Q|`l_qeD6l795cUg2SGqk73>qG%R8@-UsaFoI}GM3I8hHT(t;1jlKcS z?A#s>(9-mgNM6N@8=E1}p<{#>(eWi=ws`qRr_+c+7Y0`$Tv=8}7?a`q3%iKt_t3o! zJPZOJf&ECq?ng`72`wjE!!?$iCQr^q|5?zgF6)Li-|YTpL$3AI(M}ledOPxndshv0 zpG1r=T%n-qb<@4A{f`F4P@!E46GF??uJRpYl3oXdLND0CIlk+fM$lOtm({n9Y;edA zXCdx}iq6$2Nbx)oP_e5uSSP;wzeEzLZ>**;0I6>urAKOT#IGd45HeA#cn+=3& z*Q~nNaC&B-=v^p{7c>Rs)>i=do0*1W*S-GPv)iiS(=52eV==JSU%|ZaM9jfo-ecXf z)>;p)6?WxW6`m)!rf=~}2OTTGw=!nn^M3jn;*gQ*c?x*Ry;g3b_lxFXt0B9mg_Rg9 zxf@{i5$yu^78_&i)EqP9(FD7#JzM&-x3cw0J5|hS(`^0A+PQ8W+w&JqYq!YPp3=~X zW$2MFt}w3B$nbWO2j)KD{wrKzoWx3`MxAKkG}BUx!>@I77y zOrFA7hMkFuB5YFrUAL|z8jZJaA0xC89(l3%6LzOkD;NQSE2zNm6bH^LF zs z*VwK^&G)4yo{UXH?g#ktPXmXmf`NrX>-{fn4xB0iiu@hU-v!dyE6w7uCGXgu8?DXW zbf8%o=jQikclT0X%{}kb1kM9gh)m~A<6jMZfeb(w<=1~Bza#9c|E%a$>4<)Z&iM+= zUAMQOcw@Ji=`2R!x0@WEgg{&b*XsvroLI7vtF70ah@^ZR*Nl9Qg!8U)o=l% zE*8xJLNHs1+w}`7z82nR!?vs^1l8t&BNmzTN0x4uST65!OPE22Y zc{gU;zT?!R&{i_i!nirLw8tAaAnjitAXeRX&#U|_f2fq3pN?4GgVUX?$IR%wqar45 zYk!_c7jCh6!F!OWT*-~*NyhC3>4CTHE-Ng2;E(*el_@|Z5KvaZ7YHik@zx+^1PA7> zs!oj|&|3tx$K}Kw=UaUBJtK>czI=r%io`=`^2oL(e1*8JcjneS-$?>T z(6Hlkk#OY+5fZ5F666=viQ*qQX%0{=%bY`=kneu_2(U5I93ysK(m~~?>T|I4$<^iT z{@qRi6CAk%jB zEihv;=c(X5$mhhEIWo}pN<~bMb8Nbr^D*!&E1d}U%~E%Cgygp6JGUT z4hNgSeJvS$ot1Rw5wGN{PeajI``Zrl>w9$b0S>VPb00nI>T?>On`Bb1yDNTW%S^$+qutVf zB&k&WEryNv+rQg^^5Bbt??Xv^(KzO60zoRrQR-xj0ETQ=4Vs(VY?V{Nx1@pd_6ml= zg7{OmqXYF!(C^TvwwsTtSE=?vqCeL)x$=)bieTKgd8wFh*DaT&$18!<4CtQzK-YrK zz+%+tsehA~U3sd}_HO$t_^mgxl#&mgwQe`Gftgpehmd-k-Ck?LH`rCgdH9WYIZUQ~ z!7uWRJ2}IpF)n^LY(WL%N~dz=3148!(;yk{u8=loErJ#m?B-asr@O=Y`6>hwl=^AI&>Pz^Umpu8|KmUxG(iDHT;ZT?*bcYj>1BW z5CO2xss@;MK0~`(LpqGYR4tWPQsUN?1mWzYeAYf|J@96e8(~jJ={&Dxm$=A=1flK( zAoiR8O7#5r*H4G_KuL=up>IK2BfqcMHW7Rg+0gUyV_%DUbVe{%&$r9jO6oPQkRDj3 z2pYKQUW4K(7hpMighzYwEYGAO=6uS)F+&+zF6!ET4@3eF@YTvxH^I&d)*~h6cV*cg zkA3lhKApxpw_-;JXIpn)Z7=;sf05dd)NX2W*`UT3$uD{mYV5xz{Oh*G+_fd}PAE0& z|B^I_VM}7i7DJ%E*RX^X+KETTYIpP>0`lAE`XCtZXD{DkJ`D&>4;xh_Pmd9{yUsy9uR(W@ub z7Uga^!qjPg%4vr^xVDb}G6$bsjeNER2v&!N#hxgoOf&fD$qJB&6z6g9I~5|yW)^Y4 zy=EX=6&V35owLynV5ZGsZkP_GUiOj-tMWRq1LJ>vD(4LjXC#K#LtXfjN24)c?vAIG zWRS6E$-L&>&W*SdGU{(8p{in`ngqO1t=HORX3nZI*K5D3{Po~@vl&G{o*94kqMl?y zJ7mMtT>EZMcx$X~okRAO<*czk4Hj zB^c5lFgMTew~gZ+6<4~TKa}Ohu&7!axT&|Z9TMeBL$fmi!@|j0R@9YuUfwzfMyFUt zAwHBb(V-a;NT?UMFP{Y3(@NmdHE(SSzbNDRFceunM@usp;WT>(cIgpNae;Ee^_(5Z z+ycfpr!R{Mixq4IaOcfSQu1a)d&QtFyXzwvm3pM%r3pzP*-$cQ$SSfU+_s6`)((Yk z0q|Fc<*(N1!@}1;xy)|Q3P%qG6RI@jLzm@*R~&$=rx7K&1-J40+-I7Fl=;V9t;@@V zA8>{@Bhe(Cd>o&63Etua{1z?1fptr{#Bb=hfaaQ@iZOPJKNQ-?nhRT+k7gATWfWL$ z+G)3w@SWc)vbxEpCDLYxU2be=YHb+?2|FR1_Um9{b=h0%+1w&+Na3%{jb_v)XYHen zEQ$9S2&bmmcnSyaI-}vyq4eSErPM)BH~oOcsR2=hT)?5ezbeDZRcNRM1A*W?O zPIQWR!{@!BPcyWAsgxO-*#Mz$Im_R_Hq{R!60b7*Yl5(Pm@c;2%;K9PJH0wp=v=>< zfL>up%t`tDVCH-=Mfc4$4&p^Kd{%bnh;QM-_-rdkD&)HK#UmnZn;zkm%A~q4bH$TV z%&FI5xMAVlQJzMG@_eMxP#DY!3*T9@B}%XsI{5n90v^jC5?r3%oC@ZC|SU~$nGeBWLX4j2vKo1Z^G1a0f) zr3PM-$tGr!Oo&2;tjE{(P!S76RnO!4R%+Xy?XG=X2nTF5C`v**6&0zr&O`SJ(}5AI zrtxts>|PWq29mIuE2(ClPr;8Jp0?dl&qelw?upCO~Nq2mV1!!H(%0>HXH|GsFB&4LqM_Hp9OIRu^C>hKCbAYXm5zTy)0Si-i z^SL0lDh&k+ugr3@zMREn#+Bh;{fi4ih zrsbUanMnTGeDubn$Z2@IE{2=JE8Ljr3)`RJ9G+ns0YxcQP?2JO=stH`8Yy~C6mR?3 zs-B+dLs?uG$2v>%ePf^q6{*M$LWWQKSKvHM7-L-2Wr_mvsEIMot87iFZ)W2?zWa@r z1coM^Un~UYi$LeF**{xpw1we59LG>TRz~WIF1sq+H^bvAn)z;;V@pt0oXB?u#5gYj3((@>tm=beshR@~z=_oU@+Z<&f*@vA1h@VmNNMA3yLV4VMn?gf7!`Rsy6O zeF-2vMf0Y|T4CYVTGwBv|J8IS{kkZfosFK$#6%Xi_U(KmhGv^xDWxL=3wk!hr+j%Dv2 z6d44|E}jMiD@+lq%{x?4;Ht;em;kytoV42LhK2ch)%3Of5AHDy9L@4Oa9@(tXeN*4E&%*Zxk@+%NakFq5P z$Kz&xeZeWMOp$%hdH6(foy{jSdub%R0hz$No(MysA=P4EYzciiuL>!bHSIVNkq8k!aQ_>|G_OeZ+amYNT)So^kP*xApY{qAckNzx@6@L|VaR%PV8K5$6Wy41jYZRg|h z-#nC3rM^X4`wQyM2z>p^%Mx=q60eQ^+O0MW9=~L#o*hU4ZCV zwx)uQ8|5t`u4Rrh%x%KWA1Pdiup2@A2gW?a%X9q1?M!OpUb~ZS6Ah{oEDK#n32I@p zZ$Z`-+Co*a$whSYe=GQu>b%NY_#SV|)e#sARp&xn^7vVSp9{L_0BVGXgUWfF#&pzLYtW0H+Pj=GAI2EsugRul9#`{?`1vRQuQYl$rq5b}Lq-dW6ANNt9JDEdnPz=t zysAG}vprN*<3OCgweOHgD%H7J94)HoZpD9M1M>hayb?mm3Wsb;y=_hxq&@_~?NK zlH16M4+vs~nT+w8r{W1R^&H`10-96{Un|2x<4+<#IPuX`Rull*V8)hja@~-4OO;!n&NL;WE7{(>0TK0vJ9u7i0E7HKpR}NGKora z9ewRXsV+ypp*QOqEa9*5rNc1-HLhrc7iD00)#*oR4%L4Qs_o>Ol(9!ZpJ@h#%;F<| zwU7-c9uQc5_M{H`gU9iJp}9C_2fWrECf-|}B7riTa_@g{ zqO%FrHDP5`$lu;7S3hhYh4n)1cL!ct&z;SheV&!&6|2N)#^fw{pFDg#9Zk5j1&5=N znWvF^cY~tK?!?MV<5z>_UlC{xnGfDYtt|7k^6}Uwh2b2>n{{^e0;xBEqK?8ERjNew!fL21I_LqP(v_UT$g19?{O+#K z?yD*)?kX&xlGHDhp^CUNT2ZE(JZ)`pm75p7pi)zbVkI)bTnqGUb<$l|RIpWCumDNw z4P~g}SU_5#1j>;sr~zvop`uv<317u=D<}Y%s(u2!R2qC6DF=bURH~tKCN9o^RP(SNfOlFf9mOd*=*J+c*NaA48{)AnyvSq?}AU`6kqT0whC>f#7<&_&zN zUVrTB^MZ8ekOPi)w)(jtSd=BrQ8$^jx2Pzq$D#*XREr!CC^=) zJu~7Fx;Lf6ZPiI}4v(1xY$5(&is27K)#_+mA0_cc@smn${y|bZ)?YpF_?ejuV{CrU z_P^H+1i;^*BB#|wccnkMG=h8JF-6~#F@28Am^kBV--4uGKL{d|YAC0EpLjri3x#U)Tl{>V}sPxiGFms zen6+Jy7E!OWycQ}X6AjIbD>l<-&~&%^oBCjsXkqC&QdN2&eaZd&{CVPAC@!~Uz9Lv zvC0`VIXi2{0eK@C=%`Hq+Ki>#hx+}H<3){8#4h5qB&8!~50g}h&b2D%pWD&JB3^}c zGf^T_b%)M^ji?`fuMX(Wdn$~~MJ6TVIE{vsu9>_ETZS_mC*v6I3RXAJaq0Y%-cY|L zFZ~Ds?O6YO2mL%piy?N!Xi*|a56tg4d|feGq#yl&3MsX~{Ur5OIfu zE}n$b6LlO93KCJ{=GAy(dvVt}8)aT3Dx6u4=7rIt`4WForNpW1pq|JhcB7L%;!-Nd z%t~WDqL-TK#ymwb)>x3&jd`*((&4qvq8gF9PX-a9a4;ILdV@p000JtN(?LL;(-(4T zCa4tSk<#$aQ}>LhUs&d)6m*MGZ=MgR^twSuCH?SCy&~Uel>T{Bih2mCE~;sOzqHP~ zF+i(hrr@R8^SV)|%?KEo>XzePn3>AiaSy1d@#5?_x5yW{nLtvXE+yO6$l1ToMUdojUJ~-l@!tca$NI6o9B4os&w?8_H0HRE(oUk*m{@)zCaZ zn`#`K)Ah}u7SlEV&^*|K&YN)n>b1@xI?XlXAzsosk>!&*a{9n7!w*z&P*LJ|uAnlI z9VDEi8plU;v@XnKI60N5 zYspVC>D2^FH>P;kW=B$R6I#BU|C8XHg9$#DJ{ug!psx1qu z6IUqc#yvSZ@?*BnlD^!R;@H)xnFDy^KZ8Cb=p0b2GpsC3NwRmB+~3|A^#%~oQKvQq z^#Y2JsNZ#KhB{6;<0nlEpA_?$Z~SM_y-yk~o*HRVCh`5b*2gR=hxcy)0hM%uf_mdP zE@RVM4BV(v?`KMiYquP63W;K3V1f#fQWsEvX2hHK*BGZwGUS5qG`=$xMT*IR2`Xet z%kQY%5PCm^FX*@;^+`~B0Z>eii=93dPaStvj)l7_aMTlX$qEWyZ401($A*&BF`dY< zp_1$PmhJ4i9rR)Z$I-2Sp7aRVJqy3XR6xi zMF-@KWT4WEkGo$8Q{d?Li4C;P4iDGY`JR`BJ}#ChWJ#vybEMN*ym>L2^6g2!K}Q)4 zP`)PT@C80fVckoXV8X*%KTn-x+mrbRb!^I^nXM3C5;~`?(&9In+1)1ht`-G`yp7WzM}Q=SCglG}v!b zElK6Yl5eu)3&_wU#=aIJpFb4dyjnToBTMw>LLK!&guZg6^Hn-Z$BK8H-{ugx0s8Yw z2+}g~lcn~9OYrlzH%&Ouug zPIY`KNJ&F7f|hnMh=h|-9zZt@lqSy)U%gV+M%GKU)NN( z_KZK@Rbq6=d@Y956KQo&8B$+(SU=zOhOM2gCLuZ-@Y!XP=U!E{;@?_2I;Z^!D>qfK z+$?k(LmohJQ7fPjoyPoq$%AMx-Ci5vOJgU5cn!C@64^SkM z3|eiqkB54%@V?#j4plU@eOB)EcB&o=Ey~8e+#<1L#;NQJIJuO|GM^VKl#9$D*R|db zp%;^>g>la!5n6yE>*XyrIvZU7)E$1#spXwh1A0AEcT2)iP55+f`3BbJHYVpDK$T4$ zQ1*}&)~1xPijI_Guc^bOmp%Q9O$0@ny%?W0v)_rN+Jz77B%npv$ptkH^@mb1da_XJ zh3C*g8GA~nk)&iLG~PtpujCxXsiLylaUnO+%c#OJgk>!D+mumXvh)i~1N8g?PI#_k zR92=HiF%V!L8=$_LLE*2^ff@e6ZOT^h`_l43i(h$?p=Q|oA(c>2-75>Zg3VEkI;e6 zV}9U%FXmS)f%r#32`V4zf`YmMgjOk`BkBUJF`zF0yx2unq=t?gIPJ4Kdp+ZC@BP>3 zp*8UUD$)5R(6bNE7Y!w&g1|n2v(h$V5+SoQMZ>c&CF%m9Txj38(ZT^;`lK9gSXe?- zq}h$23x^MIdP40q-&mK|Z3#Dl;xzh(Y87;$ve3Cmbo!xy)aCwXQb*s^0x2D-uIz)^ z^M_WccPm2c+?hy)s~5Yn{4$28S(s=o1i@+cOU)9=H~tJ%#xOddF`$GjFq2RuI86)H z{GQ^BGyk2x@O@KE_m?p^-Hg&MIqTXf`FtW(43#RRdd_4q`S+LBu__~Eq17wPHJc)p z+JO!)pxbG8$0vdZS}@@0?55m2px#lBU^7EK)P_-H9CT2|==9V3pGW+gjmU2dqZX;3 zBu63KHNX7Esr!ZL?jo^ifL2tbEgbzmv4NhG!&e)^Tb(G%N90?lb6_B$NK+!XD_+eb2cI zy&$0O3z18bPv4CD>B}k|Q#UC00rX}mj(Ks%akS3u zC8J6TsUqsPEEpK>s`Wj$o}5 zA6d<-l4Uk@(HDX#1ihgQb?T!titc2QaQ^$$hB~ixg{kJ|JFJ2*6^=_SV{$5-(AU=I z=4gP#fuUW(M?jzUZo6v5LW#8te2vrSpjEouoRgWU5ul-?^t~>}t0Aduawu2FtJA`? zm5g8Ln!LMZDRoSEQLWnaloy{OLRyho>zMEg3DRmMp74eGWdL^02xwPCvLILQC;Dpw zvDm%J@PvnWs;mF5Q$>KHKEzYKJZk?~BT>g1YCcvoR-6}blcirk8ol)kI6hFtKF@Be zQI!S?7JPzP-H_V#@URs1p@GnQt$YHN`IIXAg7^er0(ttXT5aCnFCh9#{6MFB3=>{| zObdPh8J~gA%0R7~O0}s(jiyB%vvk!)hEoYTfy!n^P|I^jxR#w*bve}%e}6znzalEA zm!zrILh%Pw9DpRCj!|s}P-9hUl~v9h90D%&tY5tS%1qh=C~m$ifMUkk7s)`U6?7HJ z1h0rBV*^#s`QzY}kRYdFs(RkKMbti)aGip7!Q}7`8qE5S-Mg2SMq9>Tu@|?F1;}=ye>#iiHMsDKSmZFO;E<8V~!6`J$Zb=lQ>sviZnvual`BJ-B!qmd1=nUnj2N-J(9cu^@pClsOT zyB}0DpE&OW_Ss_Vz}&D0$zbiAYfS}7EubA7@} z_tw6pCk>RPTHCu?=dB#S_a9CvLzM-uhr%6>e?nKCzV$6CTUFXX{kfpASek%KT+kcL z22(7f0mDBH$DcLeI8&XT{qz2tpz1_<^3a?RdJE!$9&6MG56vxfMs)&mbKQ_S@l2Pk z++1up|M2v&sHmO|@2G#W^3%5nRDDvTYna}?PJeSpZl?7D&}GPPt7&xl`;qV$pon&d z4bb~j&G(xS^3nIp)P(TSx{gsjapt&n6rw(5tWkNQ9qLoOnvcemks{&I4OuX1X*l|^ z4t-6icuO7DsCcJd@2HWZo`0x9ucnBadmPyY+yjeC{zQb_7QO}MA6TFs-GaSisS>nmYiY^+ zBO8@pL{8pyUxPOC0ALaxqK+D`H4BP5>hum816qhg)koLm zw1U}l!&GDBE|P%P`U5C!e~^%R8I?w*uQ9-7?}m>g(nA15v`*eDqLfe!bnfP9$<+SX zR!(Gr$f!O-3(rD71i`||tw|oq6ORj&8`VHkbt1xaJCIRSCw4vArXiokr=L^zn<+|{ zvT)W+fo@>3RPq3w_sR!~-nQsB5!Jkds}a>ZQaZWozp|R`pN*`J z`R5FqLVErveoP^jwXlqcWHjdW@sF)b? zgR1ucSeO~r3shrdRuOLi&2f|Iwu%(CicYE`502Egayg*$WXWX%RGxuNfSRltpMhjn zUK4$0)F3hy-Bgnn^RDp7o$o`$oGgYhn+hNID5FDT^1zG<58V)`kYjb9+%G{J+yZpU zE>MFGhI**K*EOtltXvDRUEK@_9aulE#W1b~ZCAJ!P9J@sddiQ~(E%m3ZV|jk_5*)W zb>SbjE2Dbp%EIPaq`B(E(!+LjGpm8OYjHsBc3p%1P^hqPJq&@&1BHs~uv1TgAZ4mO(%px9!lm;zDTvz0g(xCTGN~%G*_iu;kCRRjjL}|^itm(lh)hp5kgHjcs zhDd~YX=tl@1I{pv^oAl-onv8CjsiHSgB-Sj6w5F)DjWjd=4`+4S|IX zhc!m56NY9FQ&fkkflPDjya6lE_NoX14of1!pHGgZOUZ=c4kD}mfNBc>JXGxdfj;VC ziA16?R0owF>*7EiX23P;bY~797V2J|S5S<1bU+h6J_%5LN&$4o^l1v=pGjezEZqnB z>N{N2WbM!%te=h%eN0(q5;7?qQ)|>lT|c7uWtcjp zhneAPD{bUaHq163x}JzRb5We_&^u0eZx5q~MD=`ZxDv5`#PZC5A z)b8(&A06!UOF2!u<2aCWN@XO~W#ky>$dWphRBTS4^}-@)X75Z13eoK56jC?7p2Kia z=UEcz)$5^7lJLmfxf9ep&-l)xQ{SNr|3J~3FQ9{P=(xXF{`RiaDU}sfpU@aVw;}2j z%gS1{0rUe|a|0!hsC*up=|rp*ZBwt^v4h$iao?d!sydY^3BFwCdD`h6H7ThlsCh@2 z{sgx^?<!Zqy-A^>KZ)U2$B|aj-zetmNw*RnYt2oc@G5 zv|cHuyhHCl?cHtyeYYHLg2HsPqNrf#1W4_?VJYoBV%u5!6L6l`EeTK^r-oAd#^+-a&p@Kmg0fG&qf-oHxF;|W zs7WbPR%!DH;He?P3$jEid;)BN7PzUD$&7X_)-i(JZnFb(@uV{TtMyv1xK{ zQW6%R4?xf-6R1ZZ8#)a)kKztApn<}PJ4DZO@X`&65S^Lr3f?b%r?1mAQOshyJW$g{ z?|@P*1gbaXb}dI>V&@&{4ag)(Le7ReEz!&-BVOo>CE_ z>VpL_wT;m41hA;fkm?TVqz%8LpEv_G?~V9=j()nL@_g$bRC8O|n5q}5qjUoDw8JER z9t3sof9ihw0X31TZ~)39!y~sloPe zZd7diWU>oTNV;YIg=@+ZM@Cc49Y z0y*iB(xj3QqbA?ajZx#%Bh1MTp*?ZZ`P1hY6KGs~d?OM$KlFW3B|&cNrKijAGZ2N! zW<(kM3^6T1&%)G+PUzIc*H``ZC*eOXdP-eD8dsVfbh7&HNXd0nHxhxGSOS6exB*I^ zKEIeijoqJxXfA3_&;5dx>f~G`r$3LW(&)J7DS(YT2+-A2aw|%oB9rn3VWg&z{4k)* zhyD#ks3tpi686FO&#xv_W2pR=9`6eHtQAN9`-PKFXXnIPmG`yE-1w7w=}S-!C}(>0 zd7!aV;4j1+p;n!u6NleMEa?x6YN>n07SK65ZhwSbIT0FB@6^k+1Qo_Q-a#jTMKy8i zU{IZXg(z(n=ZfJx;8Zf^#W|<{JfqYJXh1tTQ#&W%pMadF6O!ttpR?g+@&p`9(8Ck( zUKG1hx{3}t+KrWpOrRSvgzE!p+`f~rpV(FRR$8K-xD*g|LJ_LD0#72ee}`4)!%Cp4 zJMhq_Ud7tR}%FatZ%PMA`#}o!MUIM{TqI z^cn-F6iXUwR7@q?&}(k|ti=8|NxCqVdjI&_0Dka`+LV4k_4!A^F9GWL>pVOwh*!1F z{d6kN--@`k^yrc(4D+r(e6)pp9<7 z5qCf@fWoV^L%4?lb;{|u+&vF*qbzy(!At6Ny~aT&$}9uAK}{nO)6#P%<#75l8FWGs zs!4njD)DG~sJU}FA$Vy&pjCf=r0s80K_gAUy7b6Zo zkfx-PbsFB6zjA`|b1^jsl>GD^^Jh6H5`k(%g+}-G6unc>?vjG$s5#qH_nCBiDG^Vq zU^-Lq{j5|snZn(~7lNu5b=alyk_nON<1cO{{h%6`nxphnt>6E$)Bt8PRqoESs5e+7 z_!rbdS^tj{#N{L((4s-h0q93Sy8TPImZ0MM%LZr+)J0afQ1t_<-~S^VELEZIgg=qP z8WdJ_y@RF;oS*R$sOJ9XtBU-|;oK^rlKVgZzyg(mmEubgI%U@}t_ca;H! zo#uDY9|p)K4AtB#CQJXq07-r|7$9#K_Qzl0DpfE*dNd_GLnp&mHK5GZSbBK}4REY~ zQJWUEYE*aDN#i<|j4W6%$$IegUhiuCKn(_kS?Oeb;Rx`aR#E&1u11S0)Y`XD(N{9C zugpLJ!~iL->agk(mu~#w>b0ocpuEM^`zK*zRNMeMyo{&=ax0WuuPvSQ%di!>VN=<_;n_#iGp##3O7`HEES10Af7@&=fVa56~!xEK8eh8 z?=o`X29+ls2?8w7UWL;xHK3nui6XW%0HL~5e^TWmOL*-Tm39G*J@ZjBGfRR1Ck36i ztkeovDQ{W5WGD!5VnEjF0hMeZwGGsSX%$7hTum|%(Pi4PFV(7~fh3MsgL+i0`X^yw zRGfr58`x;aHaZELGg)Io#arsMMkO}n#>pTbm6Ksrtd`COHo9RO`+{y6^Z;k6IA0BF z2&93wgIXyfIvFM=s=i^kX@R-Wi`TI($twC9^?|IyLH(J3iF3g8Zi2ChGdC_<2^XzL z5fU)Hn~@u=xM{&V3G3iETM@FF`W;S*bN!BUZ^h2%K$WPbE{tpdEGVw5=!r$$YA|^= zE;ZO1*xki0C^!jq_a+bPj6~QI9mbZ~w0oaf4Xb6kH!aQbOaCsNE>Q$qY)|M}{=V>V zG5LPi%$0|QG29j%WVGF&o>j*D*2am|GKry++PKecNYowk4=hm6^g8S8;%~`eFqDuF z?e<>DA-s$n`x5oAj_`ol-^ROgNl=%l1 zs2p8w-G8RAIuMYpm}6Y7>#L^3og zdhX)}>YZPosKO)CIpX8+Amy{?A9zMRjt}y^bv2yYraAB^Nr1#_5Q8@!P!F>NneVMA z&H>#V*qIx>aNOA=T#C%Ra^<{4ZREdpA{>1|rP**v)H4Os9Eczx>(%jHL_Jd!(Hw&c zy_R>>ENBNJPsd9^7YZ;*M5HMp-ye=;as7EMOH|&m7~k!nelA0tE=jDGNxzLV8{jw0 zmBtcP*udCAO}w{6G{WJucd6~_Olq| zjDZdol`94!#j`xr&ke}u0A`xp)xK|e9Vea@I9)XVzyg(8`nOKPKM5~Jg}v%36rSk0 zwPV5T^(S>-qKeZczN7xh%D#)pnQP|VQybv<6QPJ$hDH@OkTz`Kr@S9K*7QmrmiK3R z!^}UhKt&z)UU4@Wtn9@Iy29tQ7Xxe&S)7C#Ra9c9chuQ-Fl|8WSpAAi{EFLZaNrp% zG3RTEDmbIkJ8I+!G=K32w%2GmeQC8QY4*m&#qC(wu@?1+HS3Sug&Nhjd3K!#c_}Wp|PDRQWh}&?7;cN1GEl|bHo!(LZ#_!OM1q=HJ z)x2XlXGEvAM{v{N!B_a&QCAO%$P?++KM4`l#px1toe$UKM#^$W&jv6tIo2UiwLif1 z_FGcIDry%lv6edCxWHIX)Fa74_ww~{yq3~HxhA0o|nQ6nl|MQv)- zJ@1Wj$D6UYj9~;0D!&UF=eb?fi}f0jg@}gcI+346k*DgM0~6}@2S!<=(wkdkc|9B8 zIqza{LW;UUzfyin3{G%%tei(7Wz`-$=239{z*<%ePMG5o2vzL@o}92Xj$x9g-j;O< z4d{9op7n;jp?hj4ay7xuYEk)oZQPyaqN12~6k%DWGKEeTOb>D5gaeuW?{LHwD#p`} zchuaulQas#m#7>6Grf!g)u;z&JV!-OYPyrmvX)JmQvSE#wDp;h)>#5tfV zQv$sUzFY?PYB}+N9)!ILy_(zxdl|f1UMzzve&!!|My;5o7B^6*CwQX@S@k)9y%jd} z+J(K=>Y!5WZS;54%vZtR>}R};G*LNEln%XYtky?DejSgtL=6kbMCZc2p73V;IN6iEMRTt`A zqN$`x`OMFv7*WQcB8wWR_VI>)Ma8sYOjZ1#n%4&1hC5Rge}`3y)iSRQdKop^Ti$D9 zpsMyeOOa65uMOfu^TsMBL`ZTK8qha4?bu3s_3MfQ4?&myt3f3jsI+5Ws+Bo;oW$GE z((6;SoTmzUHURfEhN~@6Z?H)4Z>Rw;&LBJ@Q=J4l6w-hncfmjuFc&_ca@-~EpmOWp z5SzdhP&}~9u7eH(ancgX8WjFe+yUjKl1~l8U2x`T$I4T%L@djIVhYxtpG}}0WslK} zE2YP#2)(WkmM;20q)rXVgsCQVrvWv3YGwH<)YQt6`fEfy*HtPRK+m{bb<+4Oq>p@I ztRknOi3^@0`VJG!2m%$Jkj@z+x49G17s&^a+>JV6`jpo4+j9&gvfK zwFho$3|F_PXL;?4{hxRUV*^YP`}0=tn?)T_H!7boMn; zmJlpMUY>OD9Gs8Pd5MZV=}yJSUj-6#w}_?E7a+=}xX5jjW@W5F&uCUK0a#{olFq%J zRZUHzmbq4KiF#JuQ*foY6K0FoH?y!er()P*`b;x-eJXQz?k$ zH;*cIs`>j}h9RzJs$mWK&_?F84#+VJV)>2xPY2b`n1zpjO2z1@IiTI7m|i&6sqItv zDY}Z|uH9yWiiPVh46{G)%HE` zQ2lP~iE4^M(3Hn*-(G1ya+Y}fCsSu}*!kbkH-wckV;c?|{~Mmv;_lZY7Vc$_)c^kd z{`Hj-;rmE0Mb9mG8rbDl3Dc7@dZ3_w$UC6yr$*H{2i~8h`Qk}FaE>z8fFL-J;*lz-oe<5vwZjj#u)Uf_YYVv8-fO?xh@dRX) z+dhEOHU*`S11dUN#NB6@`$Ta z(RYn&33^CWg%@fE3E;QT>eof*`(&%80A;2kKxZd)6X+(b8s-&@C8%Ik+p0Fd0u;cY zdQP_}Fq|e;Jhz`28Dc|%&VVxeS)sRt56VH$B;HbHrZiJjfve9g+Z3+f5>yZXmK{*x zPm0gi;VI6~QQ@x3fXH)2LKDuk8B|TRgu1cif%(UyH?3d1_%){B zl-&9Fz^5td)RGwhKhGt}gaCDT4Or4C z-x9T{^?yO-a2H6avJUs2eLp}a6rmalu@g}XQw3yEMezW7s8z}#2&#mv!=2*$Iga2Z z`~ZsAY1Wa+W2Gi2l`pAmLX(V2S!7StDPUy$H&7PU1*Hn`Ur@8D{%xhEDwn8-_MdsF z8bFtuYIFZ{B_TZ2tOI_HV(7cypZWV^a!}7URl)jW|C=VWqxGLqQ`EMBx?`#z)XJ#H zcxOZWO7V%!4M6_%#D4?jNRkVhA3=>(RSoJmsTl=tDI?;YbtLWd04T84wgI|n03D*@ ztkOX*C}2}mPEEHRPQ;2zG8%Z;_ihltNRx0XfvY9LTZ~&~` zs=}-j6MqF-_4+%YdC;tqBBp9)6Q9EOZ>-c0D7L@u0D4lYcdGJKm0LbST{-}JmdeA5 zN533Ua{>CG^$FA*s{gi9Q`RVBVn^2MAC+NHX z?<+Mufto|*a8u#^BVJV&_2i`fpt7qfUX>>B$6jTkpuf}c0MH3VsOJ1<)VzgSc>iOo z>gJ3mQN5dr`=AH9Q?dys!mH-&th@i=s)`4|8a34|)XJ|4*uQR~IQ{;JLj^aL3H?2M zziU)*s)bdpQStpQDqL0Z0y12z*Z^Fe>nWhJtBN4C1G=+U%N55H=-R8`Q^l*zlHXr8 zP;slcsQn?VV1jk0qQX@d4zO;c5u&Dd)X!dp1GEFWBdUy5NYMWjtNTE)tB#~^*1b7T z7l0>e!BK_%ZwNT8|LdRs@c+@K`+!QK?rf?&1{^?ftmu}XGgJNOl6@5t-`2@zu!Go_^Jj;g9jRR zK#4TJ2rjI$6aREA6`%>A8`qz=`~jbjmC}WD$IH*xADT#t6RF$!{0lb~f@;MHs%yYY}qyQDZuMPfLNnJyQn~K%9VY+|&{3+in>W-n3(d(V63;$ZSuRl)#0of1uDQ0Ta zq4OKqPeJmh=s`?RXNq@F2R{9?`22P9tGqQm#_ydVRu@R+1QTx*d zFsNLj3Q=8D7=U=F>tQ+fOLBLuCV)lNSJeZmYpc8gP*i0>k1|#ClGZPE&CPPAfC&}3 zyljI0r=;4H%8F_VAP=?5@xLOhRg<%bM>V~F+y{U_6|pMA&T@zvak8TCqnKe9|Bfmm z0GgiU3Ds#%=k~;qD)vCtwCLg%xVB^!adlp;YNHh=i6vw!W;TIP*G}+8wEhEt2Mdbo zEh_bCY=&!-h%8?~UE1rWthlq1gL)+EA1a^OXw#~C0Q#{8kOxM_!lIt$Rz%7ct7WUp z*s{uwWhH*IXN-KUhQJ)VfD1u9UnmQ`VsDwT>O`os>0yFUB}aj}Oxi+LkNPA>SQhq{ zsV{@9<6YJmWG!S|qdrtEx&cP!J`wj;HDzlL?$Az!^{lI2p&r{nd6Lz{?M`eU#42Ph zYt*B>)$~%d>rzdS?NqNgwb8C?QIGZ7pJX*b<|Dn%GBEYduDT1h<$R=pEM8g;>X8N{ zYR)2;Og0Z_O8weil_zz6hUi0<5^z3LPbt^?^S@VkSxxu zRp;JrrUkcQ>}%Acq|kg=={H<8Wr3%9MYDleEn94Orq>K|83YEa31M=h-R9n6f1sd& z&7z*3F6aqG5U-jbCQg@)8r~TNwHjC_#&-4=g18fZfr@hTv?FWIe8*;?fwk|lS8onk zV_Ksg$tqE^)T=oO*Z3OHU9#9)<|MQ)dG{oQ|C$`s)041bwQ#=b9`>`ng~019U|ymAV}bMxw-V|yM!xC6 zm++(k6C$$btB(pB5VCHZ+B?X3>hcx0=@B7GE;aDqPVJBF^NvMA zvzn9!yo{}zyTH@D#v1kL=9Z{pG-u8(BL4<0~*J3o_oh~`? z-a`7-qGGi+dfKSzB67{dMAauDZkVmO3r1=e@#3_39ex|;Gt_T?#6&fD9h};GHw;p+ z64m&xC-)ZG8fM$U3iarYm8eC$3v3eV(9bH58d%2%w*0KZUU5ddK-E+cr>m8bg%O^n zLB(Cr_E4b#A*(qFPf$@VJBwsjs7D$=5#DU*B~)`}*|>|lS}5*_IA7Pb?Yn0d`cT9! z_>b?{(r~_}HR@?`qwooFYCCoKTQ_$`+7z8Q)#M@*@7S%HxdPus+*_s+9hG?f9rf=V z;0TF`5t*X#2U*=(Bykr&uVZ-*?9`(D`4*^~i)&OSW7#Z5!}%&s!gVeVdUZI+Qn~n! ztq$sgtS)K-Do#Q@)SxBaTN~|26YAat$VOV!hup>6_JpWI(}NgJZ$mI~7rbGbruRR+VKUy_Xv}P;F@-bIkk#`v1I?nDx9vn# z8erno2L8CUtdj66qu#w4z84UF)pyj-XVdYT#D>+W<3hx_jmE}&V}2{pglqxoCz`3u zr?D}G2E4eSJpH_gpi9#s-7`t0QX3rYW}h0Y)J~{gu?yPW(C*swn}C@Pd4y`I9>IH~ zOyrMM>CW8BQBt-lS5&mSqKT~OC&81b?jeXW>MpdZ`6G!twqElI`z;Vzi#o7Y(Lp8Z zU?SvoQ6tt0eB4d@LOeY4uGvb{(AEaPzEFifY)}jFaq|xFP=AaS4d30)cp_shYysY@ zP@)!~hLs6aHUUSi0f~YkK%)k|v|YJJ07UI*PI^FPQLlH@xrg+|>Si7jjZP37%i9C3 zJ?yM*m=tR?JIg&;$QKN#%j#wv6SnJ?0=`mNQ8j8kS*#fj`D%3tQS}yR^TIAnbRRso zwbRM+i>l9nPz~z(!v1&x7lC4SL^ng8i0HrYpjSs!fKDhvO$*dY6FEFlOXd!RAa;Ou zE$C*QmzA^jJl-W#P_tM(iVD8sb(%sMI>I(xvog-Zl;*lPd3Pk6e!f@X^`Fmm-~u;d zimYfiLt>_Qw9h?z3{UH!0rQW14j$Auk)QFV{_-mxmiJy%!VAyq`!3*wF&`Yf1#zMV zVnNFP2e?ER?*|y>tf%1Y!i7N}`}tLta5PpRyy7(`f@+v7-*pM_w3hIS_xarT^ttJu z7lYu^5aMMI&b?RoE&L;%CX(L8gZ3u!Gu~8ReZ|A--fK#D<#~DQ+v!3u=7Wp(!R~2= z^;pC09)6)$90uSv>AGd4P|h+B!W?TY#y~Ign8b~&M+6s2R}~t)^9}61f=(zx)t(-q ze!<>Eg;P46#v66$K74qkG<@b;^0ncXcTfg=N2V;?@<{%plL!^EjwDc*9&~9WtFyy- z_Er(Z{uY!*uM7Xtcgm7=pogxN=lLVTf%a--J4gS6RDibD(v7T6rXp}aJtIs%Y`lZC z%JTwT1&oxRMAfJ?* z+RznIjQRz8N9Cf8fbz8m&_bftEm1pvKWs|Z7)8n@L>j)f2Rfk$wJuP1zn_mPl$WeQ zBL#e4L?ug&Qquk(zaK|6rjHF>vvT_V8QXungKmBQpMWH52EEbHB`bl(gvWWN1doU< zaDRWS0&{JtTbl}P2VxSz(2-e2-Bl`|RH!gpgYr1%7o{?5zKF~Z9q)Zms^|Mr(?N;i zOx4leNKQqhF3jZ2iNi487!m3lx~znpDoUjWFZCbL93g1fhmIh#pot2LJV8I3pB-s* z2CP9Nc@!S#{8Ib*Dwq&>OY!%6l5)2}L(t%_{j3u^KH@%If{JzWzFzPp%g;}*>*Rof*lr-#IdnD6iAv``x0vle$XNncDvB}I zL)Yg#*^?LLqlaXuMXde!Pxh2yPY`sh3_nr1@{2vO&yNm^HR!fIjfcz@;_;9r z2v15sP$SNKmekGhp#mDmo~AUQ_c@)U!7U#F>&_M$}(ZVu(x7r^R1`MwHVEmdv3uaaN^H#6wi*3XaI3Ym%VSPAc{CkP)5`lRj2oO;2@!Uk@#jUg;S zZ>%4C@8~(oOgK)xSjhusCYtn5d?IHb8e30GFRD z=kld9oB#UWpHPIVkN?vxzz#(T@1UDo08J{GXOu5Z5`6aN!Q+e`Did|_Iuj?W>rh2# zRjk#<^UQgiMw${i@n1m2P3@#71obp#PvlGIK2N`2xTz3Tr|{06J@S2qF)<%hy#xMH z)LT9R)i=w7s7}E^M1s2HcTllZ4roBv3s~Yms4G`(Ppf#PBry8tOLH%uYPCSC!m9MH zI@Bt&M2E5gx~Elktv;aGs+!2?3DgNrRZ2;Q(u7gzE0E5=4Hr;AW-wXhOQ+EYQ>>E{ zoXOYY*Xu0W_gl9gR1@m!0>-oieNw6O`r#Rg@rpuHeWVGqY@IlN5^^iyeW6twL+|Qb0 zOFaF;);dv6;#bh9*Qp*@RE%(?aF%M;swYX^b;4^Zhj-My{Z#moS}z<@nhMKA6TGNL zpd!fS?*rzo6c6TJh!+4|IzL!K58Yr+iD)>+Jgze?N>$6AInS{{8;C^Zg7Os*uzeRWL@i zBk44KcQ{;M)V1DA^ynq(Xo((z(V{cM7`;RgMi9OCP7q;;KKdA4j21m4(d&>9B}CNd zqVvt~eZTj=d!Oe#&uwS#bI;mqt)1x+i`~M8DOZBTtU`13G;6|FuEP8bh26u(cuyW2 zti1ObZdF&bxDR+y)o@qw4Zq~i`N#qOaHBfS$rCtT!+kShk{aQN2Y}c><*6*V@kYjb z9N~#C1@RM9ANX7mm_g(lHx@I#7@pvtX>dZzr`h4h2ATD@Vn5Fu`(~g**Vq&gmDTI8 zTb$|-s>wJ%JI`L2uq_Yt?^fo0J4j+*pl82>b9}eS=nem~WGUeOK7}-Rwj!`rF_31U z@6P2b2gYStG8ooYtl*b1_N_?~D0XLJ_@c+`dc>B8NW+lXy2=)pL_1Ja&q|-8&Bto>EbtG-D27DRs!88alKOU-JTOO z3+aVU^p}b9Dwr>ZzcpXSv~z7{ram6~QaNZSg3M4zw8F4j1Q9bpchsp4#L-0_!{s|u z=O0=7s!rHm=PoK;{74PKK{_eGfdqM zIwYN~%V1I>d)9ccd6L5E*JPmkz;DzUfM^hnllh~fKNW!fY+9h+7IX3^vRB4mK$R;Xj z00 z)!DO*w;I0d>EA)0anbx646?pQw{1FlHrL;h=_h_({?0>QD!VY05S9Il(pRwr7wqzu z6t>$^Au%X_P2bL9B0toSYmo~>TEaHS5c0Qx111fuZYzCFbp@*4D;z$vRrd2Q3=Y_y zAihdLeVmM6QRWizff;?Gp3nSDY|`Fbtzl)%-yZB$fp<*AGkWeid>cUJ>Hnc>D0{&< z|5Zg|P_J?wnP2A6hr*C&T#^>+UXz#8GYayGVO{^qu+8HAcfAEI_*9&KeES| zMuCXEn+$Pyq8Z(JDv$*zQRJq~sF!K5#~ zP;NCwII}1Ent!dHoOqmP$ej1G9C=0cTYj{l@S5~Yu?D>C45VhgJg{p{1iA85my(>V z^u*)#Lfp0^j__^|HluzqW+N(B#GQfhlPJI1_l+h84c*4U@+(ZQ3qBW{C?+kSp<~`- zZgc|Ly7ag>mWnTWR#r@qtkExD3=7ERG+~0m1p@TuH0R~nTz#JK0+dpYAvW)#0gd z4Mm}&f>1nTT)7&(`e!citYLA_?g1lGW9vUg=gkY>QDTjd-K<2#+UL$_d8B|v$_>?B z^=o?MmDST`6A=>zRy&i_t}2rU=1(?2sZ`dzjDqS6@n;OV&FH!a)mZi$yok@YJ#&K60bs+@+j<2)uwrJmlQh`q%kPyBR znXDea#xsM^k&O^xghA0znid&E31#?*nYibRb&AO|PF37cL)>jrOicfApS?aZn0%HG zNz!;=j`PraQi(wtJCi8WR+I)es@6KErMV(&eM{LrbsROM4{(H0)h0@KlbMb{>cuAl zRTJ|s<2`76U9?xx3s-l^c@hN7`m<*&JoLj){EB1+CNn5EhQRZ#Y`zx;RW-=n25DCe zdHtc@L;~;~uHqyA+&z#n(`~kdj`B{lyTC^=U^E8R1bbgf-d@C$eUrl@+>#&btc<`T3_!+{_2y~p zL5=OboK08#DEezgyXB9f%aO+pXe4x28pZXfgE@g8B_#2y^3Xs&#wEI6pHUrAJwB?g z*M8?oXy7We{XF4^BA(f-;C=+(&T=Uwy{2qEP4OMmGMCD8AIS$a$Yor{*<_0cZlJcI zC=wsvkGufeqrlS1GsZU-3ew!2kmW_Zk}p4(!LcTRolkil#_4=>?%0}W)@fGx#ZR7# z*gb|T)<&tTJcPTID9-@Y8KzdHcM72b?1Q4hE%3UecK;cVn8A@IYe?^-#HS_u7s@=K z9PD0NA9HNJDsg;X*+>wo^YN3oj2IEqsS0?8grs)A3*QA5TSlGK5wU4jy`eozDf=A* z5NAO3Q*4>P4LnxY2Yc4-kkY^6ZGB2zD+zYxL+!@E*EdglYAZC<&wHDT zjSZJSEyu@^H1#;YEOtv8DusK6WklL)36RP7cYCtjINcU!8|4Trxr({3s>U z8mOXxS((}ZgPrhL4b*yqEF1pLCwhMb11MzV8ER6;M$=>{P4Qd`OlQojT0vSxuTHGvx!i2x3GK7?zR+%&-g{s|KeoI%=GCl@>CUnr^ohu4iNhG`zaMk_@pVO$lAC2U zq_Wp0@niksnI}tG{+ZXJbj?b|r0FnomUWJ_b&gn+zIM)k)*L^?l_9q8NSOwA$TT8^ zIIpRVZoKIxagHss*Y|UG8u?$iE4@bv{G`s2^7 zjyqv&$NJ(oqADH@MHBvc?nlkN&bbbM1RFoaL2c%VX`$%n41)@R_`c)P-QYo&at~pM zhC6uYSZi3Mf{qy?Msm?&>48|YkL-Cb6$%HIhi+soBpOK$WK+OOJZJMvBK07J8$v_$K?FJb7ZPW3DK4inOra`AWMQY3M1pZ z_sV#A9OzjRV3znnW^Te-v;$-I%wI3YIv6OPC$|Z%$spskD?TwDLVBT{#xX; z7iEE?1RC^TvpZE;^|r`OtxJ?V3EE<1X2(Q^Fd22f6nV@UZ)!6}PMJ?dx}~(a@9)A@ zp62+F9+*dfK~zL#`x#=%iWCj@KwIFBJoB_Pf!R>~@i?Gwo#~x}UPr_k1kz@**5^cQ zVm_`d`+9`?4?j5jIhujIyLXePU$|rXIKWi;1I((V@aVN+*0FdELd>uu>_iYI{JmNr z<3w`HWtQ>WDh!`)`(CJH@tfe@t1leCrRdFMWDwQKAGNc#4b)PJN(y%IdhwfY-V9 zZRhBjpAH3EXPFOhWFs^W&Ojvz^Q$&b9H%I9NoP~$4{K6*LV%P(57BVCkvCA$&0e>! zu9MtFS;+XKTq(dfLorUMrK0+t6=g3uW20Tl6@BB0jwmq^CAV*Z52-&+HK%CS{IKFG zL6TitExD}IhM#3ZoMir-pVN|dkIAGgF|9$V06&&`{(`rYOgq*f8}9T;Kv)p(iq<5*#*^4&G?MWEXzd=h zN4Uy9xk!8VoqV;j0a0wwk-#n>ES}YB&dT=7CL8g%x(z=G62aA?S0SJ4)p4!* zs|4Io=RfDmeHS5p@DKU@7y4;%R`=gJIsU!cJ&CWW;q6?;?%@|ys}#uyt;dM?g9v`! zK^wI6O?Xo>p>T`zsuV3yEDtfF*CD<7R?PVH z%eUQyQ`Y>`FE<*s7h`eb5oL>%;}R5hegz?Qrr^iAEGwVe$Gt0N2>3a*T6 zW1WO6I4a+F0H2#=o#Di3V}UOw5D6ChgY&e!gQUnsN`vH-KDa=?Ywi!zOhWI*#`D{U z%5(#gz0(^UA>rC@ghBm9zAAduGoauPuYAuJe5JuJIj?K9?fhI6IxUUP7pUCh&rtjr(dE81|btKs7BYSnAiH$cOZcCYTUA7YCVWT%-bL2Hhz0E1kJPpkc)hpPK~9QW=s3{{4Mxw=%_HhZ7sh zT(aY=-$MU@j7#KE_4AZ%Tg(DG$VeFc=@WukkLsa&I(CiE*)7`qo6TO?^wD(b7xRXEy4$$OFv&=*c%>ZmO1P)48Du3<_tE2JsljTg~pApYT^+v@u z>&*#47GyUT%-F=r+_x=wazoc^DZd5;Gf3-fJJ5eiEh&Tv@%tXwP`D z|HV3MI)u`A>88`&FdsXt*r5-k`L#YHO5Xkq<`RKwsvI->bgACej9X|~u-~~8KZ*Y9 zmv9E{J{k(mm=u2SmGmLg0NMC;_qDg@(B&0jMwJ$N5d%6)_U^d-W*lod`6`GMRmo6<& zbD~^7n)#Kiiu-(wIEnZ0)i?Y{Uttr{{NG|Ff$4X98V(Xj%OAw`N9a;NHu0e?7Vk=xql>6 zfxPuv_Lqe?T(Cj}3_NPIwmcB&Usd>g-a8en?J*JRi;=Mgn(xOj>#A1DyZOD;Pz}dV zp~xLjsiCu?ruJ;z4YdnS5~v$LB!N)9k$bw&8$uvxvT1+Vxv3SS&?;!GB*Vv>$_d)M zI{#_NusSqMCdi6pKH+=Z!n=DBW=J6~YvNC2YKXLiI0T3Qh#v{P-Y?-VY|M32$bw*E&kmRAs~NjD+@0W_U0-y2+#pu3WGN{)ABt>;-Xlh`a4XyHZT%821~kJC5! zTUkbx08`{p!cMFp3tyX354I*!+Ck%-Lu@BJJ|hSgIrgT{k`@dP7m7!`gLq4kmP4;X z>Z4y7Kh8NsW-{&d3ZbYW z;tD0E5iP%~oIO~FRg?2@)?l(sXzs}1jnj|?nyUgxQBYkQvvAv~rO>ki%XC;>C8Iz4m6z_k~ z=x~XV#4#cK=MEczvqj{z(cj4bidNlZp!GPY4s?D8vn7X z5s8Y^pyQw?%g$0Vj5tU`lM;lPzjQX9`c2T9K+Lkb$5dF&n8`4C%_!J3WhT6&{!^%7 zx{AL`fuS8w>KCb*58V@>IMJDmaNKUDAjtPAk@{Z+zWN}Xa@Io_D}vb&NQyFu z;1EFu*YWz{4z}BahX_k#dzX!9?(i5aL@kkf_^-H8i6Wj464bk%F=<7t5zJDqP%IEd zcl@(Gyp_W_eZ$8M3)bYTQRaO7bq~=5l?83S(#*PIKE2y73MinKF9hm$jz{f_V5|^) z09Wa*(zw}eC;dPYOH3i*--zjoS0)8xxe~4E6{+UVgR@xrp#`cL|Jm&Owq&W|NkHQvUW)!ML1Fv zkcfRjUzAtk@CxS&SncI>bzFe;6dz-N`O%BNCS{eqcc``+-`oB!pz`~U6slPBo-lRk zK40(pfWMN=xYb;GCOxL5Pf)c7MYdh4j)b7f_%xk-&0`m9A83zp&c^_Y-~$s}GHu^s ztB7gzj&BF=+ep9~mh0w%Fe-{p&ONgEI)EYu+1$4fE))XKz#1t^I7>!5kPX^1hbp6z zFskHe+XCWGbj|fP58rOF*K|j>E06u*c!{*(3RvGh4%LpU-w(Mgn zGVM)GIuvQG^%rC(0@-vWC;OAQ(857{`zXdvC-8L zlx$wjUd?mE0I0`s05l^%HkcGxuKiXm7PLEK!@&jcV$8XSG+r-R0w$64vzJU6jjv`| z{6OhM$)1!+Qr|e71932Fz3$d`5$;0&^D=eeD`4er0$Le4l&@t_Dc1v9#xVxCTC!kt z0|H*si{^;xH_~?_jP~lUlh?$o`ky^WBf}rA(jc1)KxjynF*G3Qts8N{mfs)v+UJx{ zBgcN@TAO1p=R!H`(h%epIVS*OC#W^~zl5P8?TU6ZiRn>wv|L)m3Ba|-|M1pvqZGv! zg*_6nLu;bXYg8RiO_fxoTUg%K1|ipQ_FO?qIJ+Fqp?K25CQ|>C=dzKV5Y|_iO~}SR z9`AhexLL~-x=Q}nPXCj`i949hb3F77&JDwX~s}er-n1HfTD;@ zlxiys=To)&nX%gy@dUr&EjDuTTF4@4lan5pN!Kpt6RO+yjm(oy;(+MzUV#j71EzG| z2$^1BFh275=mP{}YGiTp1#afcRY&quER8kt>^0CoQyxnf-8kSpKo(1X@4>-L1p&;q zX7Q%Gz>bNUyMJ_RdJ^ZnjqlE=Scu?zAz^4~!Ac;~W0bH<854H@9{6(iT2hDc$$jn4 zbdo`hI#2y-@>Lm5vIRALL^*a6qxe8?z?Y;6uIL>a2A+liL*Uoijx7sqQ$_?ok-cq% zO*hNO1sFYYSAdI{v2&!OALoi_%b?jStlA_Z5U)a#@C_{}9~HD8ogj>b+_!b8BAa(2 zWT-^kA{ZxM@iy<8D(e0MOW2dBLl*v^99)%I6%$LVL6ZkQP{LL_ ze8l7b&JdQ?mLDLdM?^I(R7oJU1r?1&MlC+J$uXjjM+B%)6UggWx^e>(G4SQJEVhDp zH*g^S5H1v5a%=%6{0)UR;AdXbLYndB)Ie4y9W6Q$`_iIBf((`zMiGWC2o>N3bFG+g ziwt`B$pcS_xWq%eDFkAN*!uVW}0}4Lz&KzV$p9m^fs`Z=&aa(YBPQPXhFFNmW`3| z*dJn17ewyZ%VnWyZB@?l{6AFK@P4kYv!old%%||5z@5d9Hd;~Ha5&_L5oI`GHr~8y zGU`}x2A0xNj>!P(qVOQ=c8fmW4gQ2xR6~&gEwgH~0Fe=h`S*|yc@G$0LCs5>lDkTA zb@0Ee{B*<&1_w~__;1U*vpEc{ZNNZJ12v`lJ|Q&*KHk-yl_4EuMr@hesW*qrU; zRa%J#Ql-n|_8j*E&6z3v`yWXmku58S))ktLA+3Bn#RtzXCXin_z|oGs{>=HNZ!Wur zP4DjLH}hd)-jrG3UpF$ zgV=fqto=~>UC}8lX?>>HrqN=J?eXoC*Z6ODuEa`y%Rfc3c~HkAjq3kUehu275|Z7> zU(X=YbLWClb|Q|u_$0(Cp3yQBkGHk`o+got*+F;>7Z(*X{-W7N=|)Ko^Cl=o5cCu=9m{gf}iy_YLU8~E5t?&Vnj5KfHcnjQBpSq^LgW-b}wGd}{=pk*hd z;e5hBaHf9*Bil)_I!g&lzSSN02Yl>x8GF9a8?w4KltdL1 zl0e4s1NNiqOO8#VE|d{r2ASJUB~pL+c>-oW>(yYPt*)c-GFl_n5zam<2qou8=Xenv zR$LG!G_}CP8Ycp<$Xla=?Z2*XtO0YjIsa5(6d&J5l#sYqQtBfZt8j0{fFq+7Ho~r4 z3P>yQ=BWe$xv(%(-O{MkS1-}Mp6VCm5dNnNQ@axbDO`SgO+9Y$@6sCFDVwDM!;3qN z0EQHuect3G%mQ$5l%d~t2EOP$&O5Y%TUy}HYn`d#I=9QU8HPAU&I#1T0hYix6Hq1k_2 z7Rk3$Q4`>8+u!5^$rft~0t3cO29fFjH>6^0n08Qx%O?O@e9}lK|3<}%FE3Gfp zlLF`?elG!!d82R0%-?59;2D_%P7c0`3RRxz;)RhvResi`_NDi8fD%8Mkgxlvcdyc` zeE)o6%Dq^X6`dXNA7b?!F>{oCv?mNuI&(aT`v_ z(-S74sn+Q21)$L?j~h_N-9v}64mP7btrPjhBW1vnM(3fGM7})7YyHajtv^Nl2L;@U z_MvOE@75SR0yGNG+WzJaEsv%Z2Kj8P2l;gdQY=Gwp2|~kX{GR0y3LT1_t5|o|Ls+% z1u~+z>{^hcJ$W*qK4rEju9YUFI?$>r$C2*rj|4x&ni1DxU7wP`2HE`FkuoCkhss7< z(7PFsD4-Tvj{lobx>qX}T-9~ydb&Twe96z^+S#2bt5OlNR_)7mW=A(w$2Ohnqw@2o zdVRpEMmF2>*kjd*hXu(dR^)5j2T{&_B~hP0?IE&~@PAvBdYvnMC;zF)OXm9ik??s8 zXNgnhLz&OEeaO6^zh<|4h&g;p5@^f{M#8Wmq{%{UQXi^`|Jqz3h{5X7d!|z67Rq-i zZ`#Kh#p7PTXhjByU_>E>_dkCxOCXyqw#Zkwzi{0U0y=nP9Bx%=`%A5(njYM?8G*4^9qv0{yFx<7-_1^Q%Azee`h9(p2w?|7Imd z0{PbgO+?i9s{Q3W0XJ(URVGXqpt- zAAHZ!xhC=&NNmz(!V&#F-}L7agR-b_J($yCV;;%%k5cwXtT@+U$Cuajm(HSRAl95| zE`lm#$n`K{xZ2kZ5j79=TeXDLK$n1o^`Fb+J|N|Dh6kuDLvQt7KX6aNQI#Ho2v@H} zhaSPCiO*twaFu;27|TACatj(C_2?91$`sQo{=;n ziXFL0;0Ly!vH-tG{+GeILmLALO%G3bjUZ0bOe4b@K=G-?JKo**Zyhz~o=WX46Y}gk zC(gW9LHc(%aGY`{0Ym^y_4Xd^Nc>mOH=vx2nx0Yv+((C|NP1U;N+ge}{lgy-9aW~O znI(^JaHZLtS0|blK4TYyuqKPzB$3od!XmDQ&?kRM3M=@6*5^to@6m4t=WKr&SeLF@ zH*EG%f5#ce{XFyq`H*)nAeWQ$Is<#hzeY%ANS_>4yP#U1{|J9_JpPFs@0q?QD-0$3 zq#$*KGyj9r^O&;dFY50Tw__XjyWnh))J&|OA0exZufuT%b2*9mQ=$W>kMD-mDDH64 z56zeSICj+Fo$Ay`w(untx285!9XQWglp4M`rQBgRvXlFFy~eJ};m`FoLKQ#v!z1I2 zcY=$DUG`py@(ENO+@Asj&AfOFQ-ny3MpU6oNpE=&Es+cDZ}?tCqE3ET5vUXLyH7|> zAji4VCElsC^=beOc!i^Pg-R(JcJn2faQ|u#S(4qpW%SY+(g0F9)Z@=(;#PHzsEV&G z@o?L;v)+@x+uS}d-FqWmX~j#KQ^}+!LQmz;#}e8r4%}%1 zSoqIXp8ujrCfJ?b<_1?u|6@$-EJ}UgH$Rll`Z_pW{?(FFkvM2K+=5r>WH4<0-K%6? zJyNH7{J))A!A4Fkm#(DRM(zyZkv|n5buRdR&!z4N6mo3cD_};3DOt_ayyt_PetS>2 zOV*!cO&oc-7ZT5lSd>~9=H>LE`n`#__Lz@^{Sy^GJM?#xBki5!&I=9q&B6|97%@uX z;^V@Po_$-3EAsLf>-kA<|D&uj0_j7VryXzf=PE<; zPnMXc^YfaFFQwDvyOeKAe&X@SFZx2_DleBJY!3W4b4Qa(*zvXIE|cc*Un9wJG0!*q zr}E+yy6964YU(*g(CS@%chEl_%V2@oOa}kBu(%bwPfd3vs`yuZufaXmUs+k+ebOpz zA{r1o2Jc4OWFu=#sn7g9pv2Ne&Ip+g-E!LT$Ik^7WMwNCqx#(B+G}uypoej?Du0#- zoMbZ(Pn0^2p0!$bw#9);mENvCI%v1GD$IE#cK+gq(648Q2=;vOFpb+KJ5njE9#t@5 zKtIf?g@Ubk^(4LN32>#lU7k}qPQD%-r+t4!bX@k&W;BY)@2MEWp!{o@$f`}g-`XFw z8DnV7L)sP;Z^n6rmL4m)%f=juIvDL|FFJpjv6Zkm_*!06=kPbM0sTp#%kC8!3Qq90b$M)YQBlXEDtSN?7D-dKyp4qyut4M zL;pDHelFYvo_QkexB8QHthW-I9uFy6^I{V|)f^7oZ!g=<@p5#H+cnaAe`DH#k!MqB z3=NrJcMxZ->0xXp>Lx#-ac0Kycl(H5;w(Ri=+*Qa^`+D?e`K&8jCki0CRLn!R=F5E zY>;G{pwKvKv|W;HF>3TQED!0%?kfu5#GQq&ML~c5pq({?K@qk|A)D7HGZrooKp(y9 zM!CXo3r9_;gfJlAAKdQL;jpiN9kHW}V=+ds^APwu(+Wu?Naz7@)VH3TG_TT*$PFS& zwP~!9pEntl8)zhA*e#L;N`C!8#u?5DI$`7jE!=Z#VU>5Nl@AbKG#?7IGZ6kVK*A+l2A81u z=2zx`6pKtz6)nVJ}qkj{iW=P01ik~9POV0l3y?>BP=TQ{$F1yoCs*kUN%Bd}&VCuHNe>;D}xi>86>j3nAoFF{XS@ zeRmU~Du6rvs}oy#>s*030?aP`c5V`@0*W5?P*^%1OWOK5F9~`9?$|jkc1OyE?F@Rx zCX>5!0>$Oak)JX6|BIf*1K+hTe7}lu%o>*Kxpk=8i4C=21N$yzQV*-ChXH*X;!cY5 z?S;lq?rj)9LHQ}Zk6Jt}PAWnlJMeuhiBC$lXm9^$_5Hr%u&qHik#hAl#y}Rf<%Pec zMreulh>#JRgsEtutYI)(TK}H&%lY-qyiqrB(S4H`S1Eg;WQWo zW0#Q_AX6R-h}2-39tqFg+xV(tm~dEu-{qjBBUoU9XQI>J?8M%Bo)#hk{qX?p9q!MR z+L6OWS6lR_Epub-t6{1x=tcE9#c4mGGhhRE*dK1HI|PqWOq1TyK;&)OzAQzpU5{B? zkH1AJiNQUqs?7oCb^YjRHtTgM>aUhT%=(%M z-5f-!PG3&Nz&LPx?r2Vmm>>coA0Z31Tv`2H7vcJH_t&40H6~1%#G5x!Vy?IWRh_NF zT_S$9dVh1xg^ADnYjYn7S2EO5&gQO~uHsDAK2oiA8-YrOhnq(mc^j738FOZ82KyYD zP4Oz{P{ApBhOO^!PA|VyCG4Dpf_7+&777qochn2_fkU&+hrB319N3c*dF21ZlVk0^ zBfR1697Tt99c;wi`+xEo+pIk6GxG8D!Pn=7Ua9|xQrtc`2W1=rf-Fmqjn0|{TtnZRXhNqap&O6YNzivS z@I>5g{7K^STU!uCAa&#|8gLx3O?XR&G&woH6HLkHIg)#>e3Qw!UA&ulZPTqh|!OUKW7GUqZ+YAt!EskDVGb5@w1smVe^?F-D6S5BG{gI_>LP}OdDZV7G zariUOT+-3A^o18-%88W+vstvKK;zP}PzZQ_ck_u74vN)O@G_jb`V#+ajT3$RN3#HG zb}p8#ds&`f6B@SqzUfQsASdV+R8G4(`h-EeYM9PAoDUNpPN`!=O&@=+S&56_zZppj z$76TD$Tk|r?JGi5b4n72vqbU>=-UR^8T|t1Fw$!rN{xHaH4}1IDV3Ab_i=g@v*gpa zUya!NO5xW0^$|-uzKO1yF3kiy3$OQ-oc6x@2x3PpoP1VAvnyyE_tdELsL|}lcBBGb znTkAuTI5dq9Lbj5qC$)akX2J95j!b&_BTbrX|~453i68lBD!=-GbCei3 zNFLM~oF;tgo+E(#0k)_d6s|~yRDke}dip?Z#R#sRMVG3CDKZ62ts_PT-u8l1Y^p|0 zt79j;>gWC1RCFlLLI##^VBo@yGA=c~jAb;kjP{a;k1J6(N67S$k?rB=B*8i&*gWQY{LAVy-B`)7(G@S zz9;u>|_hXKfnqF0q^gy8Y<5GWT6WW2@_`%Eg0vHlNLf@h?4 zhs2W~;dr%y+Ejw+GLRkA39u5QxlBq2DS}`aXB3EiOCxa!qp>YzUKlHwOcc1BD}nlv z&6<&Fv7#8odoQfEn^&kb9ixCk?)jtaamkFATN)F@`WRv+ShO!`wKmaYK z@^|N&e6W+2k2FKVBs~B5FSi|0`j2}u^j$=1eF?D(PpbO)s2P~=5g%uuM$}SLxq}Lh zVMLBiKbB%kbWz+=Og@ZfE_p$}NLkiyp9rzt1YMBLFod?>$@hIXy4&O4;bLNgr+ z_BTJuf(NJOo0C)b9lS!iz>J(YVHYHvV~FF=@z);}A?bP4YgtW5pOd4JuPT4jiPMJ^ zI<^%xQf5b!Z$e}0WnrOLVb+JLF{?MXVuA-%?TP{@$JO5=wCq*OpL$5bQ7`a66ngBG zE>8nq4Bp?;)0#tCaKw0z1#eglNw$^W5vULo)P99RX7hrS=n8Ehi@pz z%1h)Yf=jtm0Ly~%$znB0=P1)-#t+}jPp2#(QeCtDSW6XxyS$pJB7}j79%x3hhGEsM z`hj!(zZg{u{M`2SlnZ97$;DtPCAfB(_i#}t>Q|U@`<3P2-_A{>It<2gFhxI{kXHJOk7|O+DHddf0)gk zt9rchnZhc2npIT@>5Q&etN+CN|?lA0pYfAczjq0U@C_sT; zYrI{OP3$5pP}H^Dp4bohY_@7-u{0G&dXOqpvy9Y6DPAY^CX8~J&*A3Q{S$s`d3d)i zqOK!>{OLW0mDB{R!V8Cah51!=(yjsBcLZHQa+#(9#G=nU->sUK_pH@eDs?SPC8xKe6fgazB{}Pur+gSN!?)yQUD-da#m>cr`yv^4&zP zDmtu8ib`;@Zl`c_B!sv~nodVrli@FbKi%7(p?sP+q{sPtQJ~a=neJedKn5@>YGNL) z4S)4SimdXVZ&Zn-$}4BVfW)|)4?an!nI1;Ye(y_Qka6A?%2`qdb2>W6Dret|n$S_{C+_TIHv4YUR)v%@;t(=MSa5DP29di@{Y~to*sH7~8Gl>$se8R^QVjxf{5(mMMXt zzMd5i=-nVL&ka(3sLYC@D}C5py0BqqUo7)j7ax;CKWimek?^e@)VAQF^X$o4-~Aiy zz)JdwTjy^EW|Pku2WMTVwnPT*I_QvRZ#%?j%Ijin=)?lm6K>Sg91|^&aYVj3Vvk4} zg6Qt>;KE(){=JpFG)TE}O64BM@@)l;ZDXJ+W?yP#nDF-tYYjCsC$tp6L?IdDMYar> zpcNd%b@ckzftzG;ZvNH)S?f9EP~abR2xyvG=j3|NH@O1b4bfhFvS*VE zQ~O-qw!|>In)y#q@S)PkPgA7TQMWfyjFzLJN@j+-bwSX2bMUl7(zbHH~r#3&Y!~K`V-kec6;Kj-vXgZ621mA6EPhs zUs>qeS12cQ@=`@kbc}Q$)5pPx#BQ4hg6h^MBDB7lrK!6aIw1DhRXd{{$v^(1Sn*S2 z@34nTqVkmiZcoJc?A|Su?knV8yjrSwe_{o9$-JD@R~a+Il9`g3(ahnzj*2%T+>$ub zpU>>Mn0cOY6F@oSYAeH4>66}TYG3%>xyowK7NpHA&3Di$utVJ}z0Yo=d>`~`C&W{k zSuY4AOFR2He@%liFbYa3uLfxy2uCc1mc5C9vR%f>QD2(Z>HCP&s<5{{XDEN_iI0B5 zp5|PbQjw6a@U<$keA%caGMT)7g* z2H9Z~tQK%I!P?UoTFY%&s|yVg*xov7ZSO0R@FKy5>RrU4j(xH+Y3IA5m`Nt*YZ)p!7 z9?<0}fj%rJRBN$uF#dTgG(B*fN(Sa@x0ZSf<^^OdhQ2DPS=qSxeh^AJ{LCjn zRRJOKR#16GUE%#*h^>(UFBuC8sav4(c~A=SS)oe&abr~cNXhZW*JoB(9+5)DEIEkE z!057*7&}gz4l8O$4Sy*(b%R$}jzuis!EKZtKL7Otwl1^DSqlS+m5v0eL7dUwvWvvd z<1C0RBUlSJFa4C8av5n|ahIJO#~(8vT6)L9T{UN`*EM2CU|R%~b0~Ktnr39IEUf^s zzGM~({!x$PTBEU%B+K7+3hMI^ZZ{JJj7M~%p=`RUt;W-ir_}zv8$mlS%?KYt-j03d z-s%bqtmVgY*evZ{Bm4@rf6{2_WxJ0#)*6LE{ag!kl0DbNL5a!W@9@pK$8PR4pTAQ8 z<||hYJ(}(sz|RpoOk9;!{@DI%t{pK%Z@v3c2J-(My4Uz9)@2z~ya|@5&5F0kDK+co|hcj2L5nEQ~K`(S0?&dY_Y!%CF*fLEuu?On~d zWikN^lxzt-SqX1Ns)cvGGBB%%s~{jB9#Maq$pkV$Jkm<{xz`c^R2VciWBmx_Vhe-< zu&x^x*7Ahi&nB01QZ!B{c$YG#w?($4Fii^0-8cCF-vr<3CFB&zPWrXUTj~9mlsYsW z2ASGo&cD8%rj>OJ!V{2OF8>OVye^q6m=7X?o9~{D#vKd&%H86pu2J;N3v^W;6O_0i zlPWTE`Sm)45)V>I{o{0d^qc}k@AMWXc&gvwtzJWCSw(jWn@wWd@SFaS$P)50^y?n` z4Tm#ZD31Pu4m)VsfG#vL@o%P#QlT_UEPm~x6JpY6IYsJywYbeBW79jO^F59|*U#x0 zOo?aPLqlm^E_%>ORLan22fR2I0;fq=b?uWbeC20hokW8b)CY)$NfLu-Vmx0E$F)c?26fD(3#B`()~m*gPg0BNYBCqCn7oPXnLhPtzrV849}PolFV z?802HM!x#eB;cmPy{P)W zXaX%ujTp7}ge%ud-$toTs%+rr(c0A2L~gG|ll46qbd4HfBR2xY5Q8}I{mP&VI ziSIuG{gV&2s+*?{MXgAAqsPI5QW#)MtKnO4b3cVd9>w&HfZmU*UEO+5uA^+I&$6gI zDVzyDy^6;#YsowT%2=b?N#R?lk~TT%ehe|yp8OS$jQI0b@;Yb>+`wxIDm=FG4q7TIzAsVrpxY=4cjoU{0AWQov1e4a)=Kr+u3a^b zu~m^rx1v(>829G;EZ+gfibJq03p5Iwm2(NQS|uU50cEX%Io<_DrV8B&Ne_*9`hK@Q zgS+TM=u1?wR2!&MzzF=6tk$d?Sp$)hg-hg>^e_r8dBC*j;#KHer97!sJD1!(Id)Jl zbfsRUtWkNeG0s4zDUsDG$5EuB-M}NWno?N>n4*tj6yQ0R0nSxfqhhg2*+OMM=n^ig zZlVt%0;g#pSxU2PkeKrbif1yI6ame?kjUjmyGzRX414Vtsd($XOcH!aJ*M zprZ0Ch^h($YKfk`Er97EKTBo2D}4yQZGrM6swq^pqPmv=0)p}kFtYMm?Q8*dgyll% z@)vTgI*qvNUJE_*@&!Smo2n@Spqvn`e)l#NKyN5QHO;AnN`?C0&QfQk9==}>I_boo zj_(g%fg1N`3P}A5?9&BAMUfx2WkzmUPG(T?3~U>y7;q-5$qXn8-^M%Wl<#{^3AakO z{-8*Uq5$5!+$oj)euHYh-$Uhvn(zxyUMljdeNb`$#VM`laX_U#l1jJApJb7m0p-Pq zN$nKVg`Y|-gUSnq)!!=7YgvGr7=T%QZ&vhOlx7O*3@XL!h4nkA;3Q3;4}TDqgFy8i z^hc{*pvIK~$p3#af9}$dR%JkqRe3Y08#tMzQZ*uRfBTCnkEN$pnr}uXBb72-OOX*Tp$&LxMA>$ba)aeRy#Un-l$&@Z&|%4Fj8SZ zs3yahHL6zxHnEHbOt{8qz%AYo1p&p8l{JtzWG$826iX4eiW&0)Q1X7A374IkRJ(Ae zbdREFPG_rfsD9b;`z%>>K*|1@lG*_+mBQ73sPKKv;1ntcf=Zpid4E{!`$ouWhMYtq zCrmrrs%N|?FzCXfLIY`MvnDPB{E;;-O_gPJ6G2S&UPbAK?x;jAm{Glfgf$8cz^%}Y zidZd`a7yrKoUti-K8fK!1s#lT2j{T#{djyGzQ=~fv8@S->*S= zdKLzqxrbE_7B%Z8J(v}=>WM1NDmkcZ0c`^n^QbFIm$GiB!#rx-)~*x8TXn24`Ak98 zg8TWLvb>TbDDD4py@NI)W^7$7lewvQ_p_P$TWUOMRHIt|$3bnPVj&MlRO|n_`xG_S z7eLLON-E`9?5^==gsSEDYt$6X_iro|!7o60snP~$VIJv^q!pm%SwWIwo4Q3?oL3UV z*dI{M?eC2Zuju=|FqOoj+BuJ&tc^ldpI;rI#-%vi0LUsxwJzUPI8(jiWgc-q@mI1Q z?f{gm2(21Fr61Vpl*%f=pc=dKP_b4Me}Q_m1^$i`j#i=;EbHc1RBp1b;#(^R7Q=;8P@XJc ziJCT03zypefa-=-akTPUdC%a?hk#V8L49xm-AACx z0yZ}Y#IYr@{06jB(H5l@Jq!3gK9%m!KEuQOIgq5dr;|%@t3FX*Ql)=7%CQO!Y@F1sakmlEfs_!Nhnpj zKY>eCxW3-4tm7v@%nmAtYD#-YodQPSzsZ_6P(x&&DoO>If<cq2+lo$)j{QM z7*?x`8l?h~BP;copmWFF0c-(Xh-#`JwFUSJ$W#OMtAJHI(53=-ttS36DlgWS0;Y-H zYDH~D*8SU+lB+fM4ZE6Hw+7l8HTVCszq2OP_qY<*ssTOPt^obBE2!0srwpvtx?=(t z&(e!h0lK=9`eE|eS}c||<~3-h(xNTUsY|m|I%0LY1(*Z%N7Sgl|43A^RvDwO*0Szx z0UjeC1aU{U-PWdR-EWBE)*V6oZ%~B-+B<5gAi=$AU!qn_eJLlXA9KXrYCFTZeUn30 zZW;`A`>C%{Ik>!q+L@_-;xABXn2v}pyS`<}&WZkiV(0TM#FT$*pcLl0G z99Mo@aC}m$X$;S1t=zU?Tv%Wie~`5pWA%b|Jo#5lYsj|S+M1Q8fE?SC0*oh^&J-Ya zYg?kCZXJEWo&qW#f+ELa8pCPuInO?G2cMS-`;d3K)U^j9RE62HVw> zwSfs=ys%6UHxVP1$Xa#l_IXIVRIBX_k4mjBDz_OC{z_JU3&eL+sCC-H1T_sY+!xGE z>|UK|PLB#$If6m~UO70g)x=+*@?ybhbx6@Qw*-kZz@Tzp zD8=pl-I@coKwG1tcV(m98mOgqA*yNK;kDu_BR6ru)0(RYhMRtKw65&bgk1=SULqW3 zP;FnRR~0JMn$f(I^>E$taJ0IQ0czg)H7t$F^bm35i7}VRsMUztlv-U;yXcCmLIEaw z$q(0^qjh54vO1_i9|AAe0D+2zYXfS}t3A*^p~W>|I$~(M?i{Uz^}Pp0q|u=AHGo6F zLG2X0{`~4|(1-KNxdpg6{&%Si?~e8Z{9#C$qgOwo8c(nqQN7Rw)+&oQlRL%gZ+ps&k z#2%xnL>>S4;lw(Gvt8UVRm)-?RxYycG?*vWDywdUyvpiPF4h^S|!_v>GM z?Mc-Q@o26N3b=BL_fJ&*@h^u;w;@X6^Qb5K!X!~8=~Nx@25ndr99F%6qf}_Qo}%uq zrc!X!4gI)WY+mYH_DmE37q~1S0TsrE-aYlNuv<)PF3@7RGf==ctq=g(3-F+}%Lf z*)bwiN@#hZ@=+jP2vvhDz7TNB!QtHrGZ#w|?Qt}fdZWU2cc`-`%#;;pf!)n2ku~5q zTIWZHE*@SLHBEgLjko;tQ#cz=n~M4~B|sHTX9{ZNC@PwFbCCd#Dtzvz@MEjg6ZW|y zoXs@{kS8H78j8vRjS-(SyyK~+eArYt+yb&n>M25{RhrD__kqfqb(+*~?*q@;xq_

    9AWiO7X9_&#QcgmCTr|6!n5))Pi)mQ)S?A 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

    @?fMZy(yabVjUSo~NmZ}Ezg4AF@~cYDtli0$lG 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

    U=pBV>3z=dA$umxh>Xs%$Y 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�TUAAI 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

    ER`253l{+PnHJZSKkGe5H%2Z!*1no}0N#m+G|h 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

    *O))W$r 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 z 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 )#Wuq0q1yE^YK*8& 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%0A7^b}P={Nx=H0~G#9{VAs(_6=ITWSC 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 QG$79JKuM zy+pE?6=0wAaV{QWz{4&FhzIaJb#!~V2bkJ9k1(ho!Mvr;1bE+&vXzi={o^?vw=vN3 z^`tb%tni;d*&b(-e#jSlXJMVrR-h&3|@}oUwDth1AC2M*o;7@t>Oa66P<2Tu-)T* zrlOmdmm}5GS&B>6e=X{XlT04=nKM@HyzZf4!5d`5Zxqw~3lp58UC<~EXrCSN^nCvq zA!x8E7@HmVK0K$9rO{;C60y#GA-_f73bzCTruz->*qj$PB1Eq(uH)n4iZR&-I)2j} zg%hKyyeo}7b0YqMjyVzptZ5@@9Ln?WB;OFZXaj&xiG9vl{xk5bQDR7z(4J@V0*hwl zgd_H_`9xn&HkSpY5CbN9z|^+OLNuX;E$*LjiP@7n!bp9fp0>i6~Yp%^_U zj@-2?p%P&>;{#C=gAJJIpZ}o@Ez6X}*6H!&J}lH1!$X*Bkj!9Ah_Ppa^X9a3cEN5N zbc`rd*bC7}C-}FR28mXG{j$#PLI@$o%^W(*hjA$L;mLhCB-*o_8^iPT(TNVh`Ay%M zQ$I-OOC*okJE(^ABic;NSUm$H^)B1Y(%=q%48CYH1}lk;qN*{N27wPMklpB4BoB>Z zwzZsKah^w!4gem5#kg7>?cqfmB)Kx(gY)K;@m(@kyXGuXQ+=z=0dbDg)srfdgu7oZ zDv7Er-G$AeC?;qCO?w}0>!A*@0jdf+68Hiw3`>a5hIU55n8a=&mnF}pR_^QW3r%ZQ z8qlblj)c>sUHKXE?bjybK~{{@uHqCk(YLk=7fhj*+>iF{)KgYJ?~8Yi!zRB4KTUpY z;N)k#B=7tnTqUTGn}8UJX*&^y&Z9{&+Zv_9Vr?~NJatTW(JS^?+iVZg2|gpfDZ0z! z+T{iEupwkiSd@6_Lu{!BU-Q2JiCAynB7Pth>jx$XaQzR1^`T~R*rFCUUr13^eSp;% zcbN_>wvoi9ha9=(8Q57t@quPonoGmaZe=j6Q74RXzlRm7?kO35+>R<}Vd74b>k9cg z7i}p8(L(M>T+o7({EfOAe|aK4$fUd09UEydOMPKv_ktclI%!jZ4eDW0EZ7g`IOt*6 zfqwd*F?jQeIFn)&9t!FETKBP7=)r17Ax~1?T$+;#OyjM)cm`C%4vv%6XZddg`M6EV zNpnQB_CkPpf7eFq8H54*G>FRT9JD=?k#5v^^WVdc8U{oAObCS4wxcoEk=Es`wxc zhN)c?Bnr9~UYyN%=}bdBo5QNp#xLd<|j^igzY-AU&sQJA!7=xO* z?0CZctx{&heq!jnXE9%?MBmBP+*WCrN8KNsCk4(wld#zbsD`a~o1Q_sKDVv21G|Q} z64;Su(dca$D{FZ$`g8Rur4Ty!L>3Wt5ovV)dO#Jpp*oVe`2J*($npzLmXk2Qur6_=6$gQlQK}d_6zj^z z+~VSGxI?4rDde>nz6#d?yNMsB)twFS&+RtXE55FO+L?Biufzkjn8zNSr=8;KXPFHU zxjw1o=}!lmKfXd_L4*si>m<92Z^}Omy$ZNIqa?WKu_Y-&Z;3 z4l;@TVIRKE3+gqU-H&0{&&&^R9m9nR^r(@VlH5$8v-F5vW00nKEE5=tvCXBn@61Zs zwb%z=Uu{?mnBnFeM#+E=J?6x@K3to0^4U}q4`-Fph1k%@kWFUq0Vp0AOr@PK&R{2) zxZx$ZZ}DHYUnTaC6Jr#vzc-jWfvLmxM(%h$Z;tFpa6mB&xZ@2KNNQ;NfcU8$Gztvx z=k(hR+P70J3)@v^CFIzKj3+;)Eg|-}_h&;6X6|{|aF;@>B66Ncd&}X!IR>}K5Rsa! zz_0s-S$R9c-@}nbZE{Dw?T(vv+JU_@b!mk+G^$xeUJIA3teocwx8xQ&K+-fbyKpUf z@3_|G!7bRIjH&tIMV-)uAnD*2I*BtnkG}dP1p;oGr3a$#Kj3q*1ePLsquO)A$~>N3 zpNG<#%ha0+VCX;h&p_}ERc5t|n$M(H__E<;rZl!bjBS#lYPtim-&eyZzl1Ifdb2!` zZc3km`BFo7Q$O!3HkX2V4gihl&1mfg5czmWk(QG1Puqt9w?lOG0*TUSkD;WK!Alwi zY|7?*jXv+Lo!N-6476u*$}2VIz)JXL6U4$6N`-s5%X+7ZYA<880`x%~1-1GlABPi} zU&Ydrs1eT)8@#ioHh;lQ=(x3Az8wzzi(vX-cu2r0FADq;%|=z_EozYY&9tam>jSV~ zIBFsiFU}$$CNC<#yGp}n{br^pk$d!`1ufIrr)n@HrJ)Yf1P=bp|Spj@LUybXaP(`BC#@;Xc zUhS4z_xqhGukNcTZ1Q$zmo_``rS=Ll+k!5n2#WkX|q=$yDR zkSR=u^r zQ<mOME3k2d?+?rR4L(Fc zu?qGIjIq#0br|%eA_lM?c)Ugg7fE(-$@t3K<4B7K)v{wu>OZ0>B7bYw=Y!GUtwo@% z{`kH`Qj_fh1#I|TNMeyXaYy7PM0@nfD&`Lzxf+Z}8TCpj8+J}J@uh;iZk>93(ER)w zZLsAz3l}=rj*F0+%pqFq#soee$_-Xn)AJW+)&yOd zpCVnHjUE88%Eg%Ff1rcI8erM^o$FMWnc#7Z=|wmGo3n*m*=D?rS=6fg_hGd4^EbG$ zzVW13iTP};_t5I#Q3lu$dzy#eIazP{8Q5K3T6gLxrgMDzCtR!v1%1Q< zF<{>=a|jV%uxRnoxMv~-PR#~ey4!EFXs^!Cu0{d(JJd9V zx#B@LdEa8gsmUP#tI28^C;N+2U8$5RZ^tOD|105p31Z@;ikh!kNFYBnE5q&`Tibis z-0nZ)TY?afaj!O2;wVPGd4OW~PP(}~+uQ2gyi^59PUqL9a9}|HC|o(fVf~Y`F@b;L zXQXz+ldmA|crP*9)bZq+XEYE5q8ea`NCiTk8w+;T{`vn4a@&j@?;rT&JNpGWsh_60 zeb#M$&AER3!>NWQY3BR)hLHe6IN~J(w%)_~^|%ryhb`U}BhFNxSd}%3u7?&S7_FGH z9Z%m`FEPKUk4ZKS)x9g>Cf*KgCdO9UL;Y+ZzblBLxiO3Q;p^j z$oO%6$e(fo=`>x(`GvY|g3`)s>VQ5?F7c9MazSa$H9!7h=6z;9J)7VG%K%j2FKvJv zR-QfKTlwPfKC5PB>ZTf*zci4#@l$XovRn2`A_Ar$_O6v8nz_g2S);|YM|W}{T<$l$ zhXs@5t4NTa<~mT8_x8_?W`=7HfVH>$sY2nMWxGsJj#LyUrk_&%g{ zO76uB3O&rax?6M?FiOX=iW_u7f&0AEKOoND{$L|9TPcQ&iz#4-W7eY-Z_Y?6t*jaD9L7o_&?}1r%qFkLBLh8Opg|F zEBW4k1GnCC)C}q{2~0aZo|WErNRZOaeS~xhu(Gl!|RC&k?w!ERCAKO|eke88)gel|WB2(5VP7 zgF`$g>w?BH69j?8HP-i$jAw**6CuOw{XrdmGu|8oF~ioi6S1QphNeP^u3C%j808cM znT@heJg9lq;qA zsmS)_D9L58sr+#*#WruwsA+}Trex9cD;QIIM2}PU34dPQ^QP&z$_nC>RP7gJD=$TL zPQ}uD$=s$^2S+vdKCk=z$&4SH?-{j`S`~1FN|L{`$~VErNg(VjCw}7?keKy+fHYH% zyv;O9CHbw5?EenwAUw|8QUNn=JlrqJD$9h|1>vG4P*mSaxK9;J)kf_|OUJLU4go?W zmH!hWA*;y-EYkDeRYH&qo`Dtda6^WL500CyAAUUMwGO_zS|nci1en}x?^ROh$0-fB zvT%C*l#$)A^rkUg(%Fc$4}#1CKP#j%DRvxjPWBKHEn z4#UCsBQrqLTF9xyHL#O_4pdq^!8Eu8GWMqQV12_>Bn#ln$PKN-@qUY$Vpin0e1W*7 z?A2dv69AXTX`*R=^LDrt{J)@u;CX8?%HWP9-phkS}`t<0rZKx9nTm z2lKyXb=Zl#7t+ zKU9qf@o7kz@a?idp*%y13h2*!v0*IcoWsQC>mQ(II?2>eOf-Js#A>P&($PXG=;TiP zGO*i;Mqk#fPm$M1#0yjAMksQlu|?XC?5B=vJ(w_O{OL5#leGLW5?i>E*a*y%kebah zSYXF-qQStt0pDc`mVp)6LCw?s(MjG)_qmBO3OTIIBuLXeX9xUcFCB^fanAh+)**(h=vaS% zHpP=^>K1W2{!eF>e~;bfW{LP8I)3HdZ)r}e}e)O9etL6vq#0O5}K3)yC?)Ro^9T8UL>qYT-jrx=U&(6J`>K??|SVXyN5jq-O zG=5E~l-wWOau+qPpm{~S3A*w84TJ{K7D}v7SoQKOT&FyfYtUYt5-_nF`9vHV1g*dr zjIiMo!J<^P2z~&xJ$t)tdCFk(D{*M#@Inz7hjT4L zY6m)pqxTO!dGuB)#~IIHAl+};d8_wW$RpApf9R8iH=6Ja6>G`(8PeHuB5)NQZzZr} zwzZbmFL!S@cc1aSC||f+>j@C=-InhrpeeJlp8MQhCa4pmuXI;{(Pm8ec_8A;^J+U( ztcNM5wA#=lluJXkwzoR8i=z(5d^PcF1mlp;``LNs4LI-6j9TVQEJTYkZCD{&uZLa$}~ic+Fr?Vv-LsBWPOO zf}eF~wLa?0FV4hOZs!-4SGkmLDCpGnDHit-Uevz^!WTMNK)I^n}1EQVSFMzWMJ~X{7Sb9#yO%~dm^B-1zXo|j4W2QNk+F@)lNWgEc z+dS;Afh#lsAZ7h|0T7c*>^$&zk{%>ejt#gH>K>2u%sj{BA7bSvVV}EL_-r4Qws6sf z9{jS&CACSAxF+8X#3e57D`GVBSQ?mHpe#82R)jP=>7;-=%5{gMWn+8u$_Dv+GI0xm z5>soip@=cS;GkkpQE>H^8d6vtzoGNda}F!>f4GFIJo4W3M2l{_2^rxj5nXm5WW84R z(CZjd15B}KDY&ln6ia8C=m~(`G{tCFVaxh|xD9(qYFe~3>O|l>rET3b@pAh88^%2< z$Qp}S8NabUSMj`lBw&dm$zcL{#z@Fm4JVXphEr8C`*TtIM!{j(FXQ*+4db<((BNMo zH5dk?+!UO0=UXHtL%W8z^$k>-AU(rv#*1mPlVk*M64;Pp>G2WzEWV0uh!BGLjNuF3 z&j-TDh!b&J_i>0^$~ZCUz&IJ*y+)|FS;b*}2BZfdIE zax3`kCX}nXJ0I9z&;*2yXHGzDb+Fs;pwPr(R&{vdl_b#8GI}5HyAy9JKP$C(k7CQS z1~W56O-u=<32ji#3xgNnE?1_B3bA(XLWhNlHl-zGQ2u;PniRLfx;AjgV+s^1-$JEV zUa8>x#&)C9S5fPwez!x$5BkpdjG}yxe|g)+-lz}KGkgd+>ZjGd z$OrK0?`ZQO9nkt~x|vcq?cuS_dopOwb;mKV76bq0{DYR!LJ}Db+K7N@K9NOTMiU~e zvSO&yNCoviFJ4v;6HBXKjY(4#RUchF7;_-iE&0LUwEqs%+f{)bXqowh5gy5C0`oQ8 zhQoLod(J@evZPHSGBMigMzUfABWk5`K0fGT4t-Bdi$DMl z6R!GwDyTC`)@ML!{zCf43G6WQG^*|i>sO_i_tp=ZR3G=h0&76b>isX1vBLESpEOgr z&mX(7xK=(NNG08+b1!=!I8OW6gbqS%9S2p|w73D}IreA2lJ!+JApR%ntRfWZ$P=IU zS>L+a9Vk_CG*I5*=u!ZaM*70Y)QxKM=}9nmqmAS2DdFgG^rGmM8^V}$Vod^Eq-{{n zS?&?)225L9lj8AD{5EwQA^?HZ;Whiq#y`&42){mAGr=|#s`oz??4MhMvG|lDATPR}6&fy5w>O-G z6VO5*$AH+`gB<8%4Y$L|!gXUtgr;5Z$ch1Q5J+lMF6qwTHWB}FH-VB&-;GULE?=?$ zLxB8Y2hz_ZW%_&SHWudC7f-%^s znZ_lF-JFR$4PYmYhQGs%_1*7%yg2zW$IN%?Qbuid`;`lC^hTYKj}@pNdH`<7pbQ>H zu)F{zxp{%|-o)9%0-T3M%d{_Ys3;rCUwA+H*3VQdyszw|u-&HD#ERANJzZFx znt$%-`}0DbfFwSYvCEs0t@y56+n+%&XwX0SH^<8LO=(1P%y)P2?q+AFQ?E69SJ=9dms8g3Q8LZcg_2EfQ>@oGTenFAViaEImL4)yv)zwdycW2yiX+4 zVgjpMU*{z!dG1ir{{vVmvgK!#*Nf3biHlFazsP-LkVBXjDYe_}zojTs=*)o7srHdD z;3u3(Ft`=DMs)n~DC^dkN{I{|JaN0P*O}U^+n$Q|L(+Dc&@<$RGfP&8b@2&-P7gPDg`psYc04mI1 zM>c&^1O4$=OAIdL3y9OKfxbXK--v_yu#hd^<@uk+Z%4|@B_}lBk?8KVxGJerSEl-G zrRJNnqYonMRy=zY@%@KlN5?9s(|#I19_apNwUO_u_(23R6s4bIErJ=+)CU=PiPLqC zKY{SMpn)UCbdskp_>R8JN?~t1dfsF47Ekt3@a_CZl&!#`6iF9eRUN;Om^X9d^Oa72 zaVw7BoMDsR>BcNMa?;Sght+Mh{T3l$!sC#(_%{b|-_)MI1a`&k`^~d}PZNf>y!!Sn zZXI72Q<1)#9NceYkQ89eEdHK0|L2y8jlq*%|3`u7%}eCR6)Q~}0Ju~4-TTj~P>+oN z?x-<7{Y$KlUF zIc%H9r5ydIaygs1bnqI*O6!)cg~vj3yz0_&oC%glP;irFA3GBRcKJz0SnkF;<2d|w z6mj*>G&10AdLM}~m=j`~%}fq~<7_A{g4j0()CfPf4m>y6)2EDr0FUuM#Cl}o-Zu=F z$Ny|yP790(lHI}U!(1KbGJ}jk(?$thEg|<$9!@&tL%)7l+Y_vjHO0Y%mZfe`nykmu zQ|a12ht$s_O_*!hIbWSjrxMPfixClSs>{NH*6kbOGq1%0L#45ccV;5ezB(6M#(vnF z@G7>U8n4=h-oCzB`IhPlk=Fa~KB3ZtX~dNR5Z@<%3w>}{nEqMc#T|`>fh# zKOXSWJ^lZoZZ||r8GFqV46suEc2wB&ZD~h%$8R?-^p&+vWnG1{`|jf}9Fc1eQFwKf z+W}s`szL`SaRiOyt3ZVt-^eo6{U);#HS$o|f;NMPS>K0cK(xc&vbKPq^6$n+?7t^I zZoEnn$G3K1f@FBBB)Q+pEng}oTwOyzu5%ArIex^x?06gC+J6FO^ajS&|C&7AGO1+* z&F^51hU@0R0_M@Z9wov02wP85;rADKq?zBF&`gCX4HV(cA#NZTHRiz@02KD`;(yZ)NG4f!#_t=9f8{XoV3 zLh$>6EI88x{YA=3IP1WYy;R|C#G&-q_939GSEu8R}=zd2tKuN1+sNt;(%%o%@65(hWdPD{$mUY`m&&3n z)DCJ~-oT}DyVr|0cK;g4n-LOu9U{BuF`Tvt^<@J+Rh_MRk$c9>gVC@UxbyK%NSh=V$8GSM zEdVH62IqX9+V=O$kgI&M+59#5Kk0SQI{(!hKAY3rTE}T;*V}jUpHTf~G}K>l*jrWr zl?~a5Vx5CVfZBV;9)~erke|caQ=1w;b@fL-sfZg5qx$J+RMC`@;Fe!{w9jZDWy2_-=M&G{lQ86i5cx!z`(q`ALlJ zt6WpT)d&B$!t6d&bwJ_*-n)4e+R$R5u-^?og0&it3;B&t)>tf5*tS~o8CoRa>VU1D zs%|wIbcnyySJ?GyG4TDTM7D?hqUC)CPs?n1%Aaf*;RVD^)Z!L4UK^N&sTv>jt37IdRixi?r$%m; z^5U8^v5z#2ir3{uMakTjks`WvoH~Ca0wH$Ky1!gIDOw8Qu))H?*hZ0+F+)S_R=5X_ z;*H_|Tp7(a%`@@&^Dr?E_6t%t&?gOCzC@@Vc=KDe8!oz5x|9&J^ThGOP3KnMlMztF zb9=i|Wngz>#QBUod*b;XDs9#J*;_r{kDEd%9uJU_I43-;%ced_nSSV2E9%$ou)W|i z;`d411Z9E6^4dh+Gv`DN!O!n4x=4M0oqc;^S|B`g!#U6L>z0xa2GR~Td9)qx!p7Se z)z^N@m95@8Th3oj$Mi05|02Dcd?P*DWgEh^ARxrUm-fgmRn|a$NNc_$o8`h!jognO zI!SpHyLcE|6bllH4`N;CaSvpA5lG+r^dL5y`-@(KC|Riy_dD?pk%8}XCOF3OaBon= z!&L7lPN=A%xep#q){8z3kI&xP-#Wa$?d}8V6ph}xjW~hdiXYo&=RIs6m{vqMggiKj zsl9evGn4aS-W9**gy?BOQXp zd7u%!3T0A%dI5lU)!r{95dqBeq&V`{?GlKa@Ntac3Zq<}kyuZS@nOGzt@ zI20&Wx(Yc@0*L#HiCgN~TUlD0(bT+;+k%L?TwWT6b%P973A^s|bJd3ecb6^ccHUEd zDG;6Oa?!6&7hCP|9$S!;O#w$?Uyp2Y`()KcY5uYJfeMd`koip%oNR7c-mFV8<1RC~V!*53BSfwu|!60K}ok73URNZQL z*+IF*2|Z-?$8UiVffP{a&&LP)b&5A(QN6s%ubTwBHXEIGpd#Q7m|kMuaX`2j0o2CDmk-Uf?h0fPix$R z;|r$GIh4lBhPpIw@6)NZUaXNecs+`>nRcWJ*&Lm)VJ~;E?>k`F;1`jWI$qn`@ zh^w*A@8{XtpU&y?w(j`4Tuokwrh`2vk{o%N?%s&p@^$we(`B|$6hY-`3p%oWe6Lef zyT&dicCP^T^DVL@e)Wk`yLs_|iI=iL{K&TG#p9}$Hc^LBQ zyu8~rW+rXzAByp!rL#{J+3$%T&!!>1P?`Fcf5v8jTadaNQ} z`rC8Wl^=o^LIPO?zzxFG_C0&_U~#2H|3>(;=Fi6!`J>F|6e;MwfD%$QFqmG;GL8|f){L@*?C{6qx$MXeCVW6 z_BzT9_yO!zKMw|IY(hvN@bFtfr)5~XhY+C7pI9iAm6v)i`V;&8_YXn^+i?QsPpM88G-kS$ANhD?3rtJ|2N}?r#4I^kgn8q5-MjUBFe~n zR^8>JOn2uWNHN|`?GJCdQhwLu5LReG0iMq9wj3nk*`Casj&8c*+_iF;)14eag+KAE zlHB9ZGcUQYl%8pzLb{5{+&^=xi1u7+1nURTz822;-G2~LS0G z)7%GXEs{Cdd6_0KH{&_ODNe6Bs3nq0z7E>NjiP#0=NOy$JUPiePL`q}=%E1DVA%PP z3x4sC#aLn&3~+V|^iLkT%7;s)HVoga&joTr)9XUjz-T@gx24RS-3GRmj|Gq}h&dKyg$Y!E0A3LV~ z-G`%jO85!21cm!@m}7{h&3uL)M_VPx66AwAWoy8Oe!Hfs$PV_y<3}zz zE;4Fe{qDC72MxYnm<_-AvrzmpA509MV33KZ)st7uwMjqQGmYgGm22Oou9s^c4QumT zalspM=~hp37bMa90T1zv7ings+Wz`JWcYqSFS;#fWlwZ)HGE+Akw@?oc0$HQPxaX7 zcsN#Sv<%j)xS))>A{jo@Ee4s+l&O_J#oTAZRNx_IdhWjvBoa~Ez?s5CX=1Yg}S-(VD-)&0= z&4ag$A}ZT4w7f8W3ElD92Tuev=o@Qf#=8@&51mTcFmgFhOt=;|^7PZ|1E{Q3o6U0v z&<0dHqN-;{bUaqCBbGx{h#qDb-?MsY%4eAM9a77g0cuH`Zck^M755nK%9PoD@Q1A7 zncy9cJGkQ)pBkh)1gmHnqHnZ!qk(-yaPFHI>grHUOq)j=G?K%OeZoKA);@W$QCi44 zy@~}cX>iA0T(k-7bx(Zz~ByOus?O0mw&$RE`CJZgT|>f`Fpew!^+ z;Q5NxBWH=u2cet3cj7f)&{q{c_@0Ahl<}Xej6BjvXd+b4_giZTZRcPWJ7Ve>mKE!& zu=CCrx^#P~T54}Fkq3LBxstqJvfEN>^4m+;&Dod!O1=(6o* zLna5QH7~(S0+Eg?ApYFGXU%R_?z0cm>(^o7`}R2BfFQIjFEzNyI$lj3Vmrzt(NDGk zVr@I0Gcs&v)FqL+eQ{k#+qu0amZuMlT?!X=;#SaFo?_8Qa0ao; z@>hY>pt5WY{@eTNZV!t?p@b?Z{sWrfU%u5%ej3ueX`>$nneby^1i&&k7@lBoNvN*2 zLyUKk!}V2BXNyjStDI~qIM6uy(H(u~z{uO<7)gUhstb|2L|DgVMqwD6TefJRc4(X2 zGt6()rX`a1LQ&f?&^X_Am+2lLfo(D!D-x_LVYju_hT9Kj&H^a#&EsuHh?$Z`sWJEV zRRsp+bh!d(Mga{Vn5KDpq1&alAr5M)TzAkBDXgXJzU}nJ7#o{kIMw`w?!A+VR6SCa z#MIb;!TN}Slm^u@IpS2l+%g+cUrOp{8m(j}djLxOVTn|m(73XGX&Lj75Qx78o44~j`lbG{P=D>w;IaVq7I!`f}Sxedg0n4 z`abqv{zRZy#N4_Ys>2aG`NKuT#_OBp2%w|xG|HzwL-V=5+1Ti64d-aWqHjeU>Fg8d#Td&j+z~P3TfS~cs2Tws80)m@}_=HhgWuRw(vskE_{2A$hjH% zf%s3Hf1<%Y43RhSA95t9v_eSf8{$-*Z$??o<5lj()UlO-tIdoi5kJ4MF?&SRfmVI! zTn-~h0dBYQR%szU0oin5tC&3(341>+p=+GTGvFd(@#bHiSv4N^KGR7i&q~K@RBE4u z>TW&uA^poTT-t1BBjbq5heNaub2ek(vXevMQVOJ!)VRiTnO6`&?Wnsz-iLke1PB7V z<;fJlgkj>p`Rp}C>UUT z9j&+#1djrYrX^_(H`%Y5|3+IiAdu2M%cLe!9l2sBCaJ_1!v}Biq*5f1cUf^xMssdXE1XhZ(~?LAxGQSv4${Oj zOsP2M8}SX-wui4V_tkI;nfx-q}eL{_yi4^Kh9Xq#LoLg)G1Z#do z80{Qj?)~#ywm0Q!gh%X$Y*O(M&aTRk7Z;*N0CzK3aT24`qJ^}hVNltWYcbCs*ow6g z?W>M@TI|ZA=4$B`pDs2q=P$=%+i(|x0aYL}uJX+v&l10*TPBpBQ9NSIYs=^vN=I%b zD-cOJ+1++?|b9z-7-3s%Urv2WHK1vXRjTY0w0eZKSW8?Bp5+eVbHW+CWb z9xoTn%+#z}A?9{Ix7F32#D7u?LZyEts()D_12spnjAI`#vb*2Of5qOZ(V9RTLc@)LBt)m@e2hcr5ZL_|Li!S1hQB5aULY7RUV!{p$(8osW6= z$#)cZ(jO7opxFLn5VyXraT-#HAABt5W9U2lBJ7Vae?l|Ob9bqnWeX8UTkPg`C@okd z2;gl_2b_>L_RMWp36tN?3U*1G-;Z!me)qMSLOM-(9y_{tHQZPAXHINkZ~xE*Z6YEn zQt?@N3K8Bjd+AjNBJ2k9b}63(JRWd4zrdSUA0+`ixAp^%!r4nMCKq$gC(lJ^%WU?c4r>y-zeO+Q~2pF0_f^P1;t_*2p>#8wlJB zHD#I-i1s<<;nmLfS5JUR(CGYR<*(xDIsk431v|bc1JIb79&KEebE=2FtnH;Pd|+w2 z4oBWvIB>~1vUk0XhsC|cj4&i3ioj^XAXC!q)hZx07A$AdyLRrXSB;+H2<*pfu!4&3 zir6dx!JQQWo0FsmVtkw90S#uuIu1@0m}b=hbOwo)aM7?QBNp%7H{X6QR04ra?;0K| zfBWUqeMq$7G>epmGC*CB8@H-)IgEKi^gEp!1~g5=Z_+1UFfdFA*=eo~;{!{^-W{aG zpM|y#S^b5doagPP_rEJ69xbSE!}QEddcAL79NwP1rdDU3IiP_D>4*CG7Uqbgh)ppl z8q7_av>9kJ7zlVke%g4`oazM8#Fxxeu?TFdW3c{_vGST2Nf>PE&PpTfm3%Up5k~z% z1DEgPn-_YRPaB?9>-L;W;beO+2(sc{x7agb>%yfF;~|E29ZC=^RyKTCNm z=09J3xrKp!k?*=#N6q;UG$d;=W7>}7{mDOOyND6Y#m%-{q~z}3+jq;gX|XnOVek?1 zFc6YjO-3;j@=R}#yxWiGD<}ORW}|w{-uM)5tT~KG7N96@r$#z8DI> z2o{uxpAv}r(WT=fxZ!B+EEplTb(Ij1Pl(K0CKsk~K|O@)Hqh4lf}NEO8GK_hf7)Lh zFPrj5K8RQ{L(_b`-j;6ZjJ=11Id70SvO_Q=6mjYhdZE|W37HS;33U@DP&=g)JWE~k zpJ|Rhyf0W(F#OI~-`s=|hO47E8=3FITVnehn`LE=@}+d!!h1$tE=%xucT4_wSUCzL z)oXq6CdGF{qwRJB+Wwe)S{9>4_ByISn4Y}0l3%=S>hF!n0H`U9x_X!ud)rLK1jd6I z(y;SwR+CKXyk3AmtOw@>U=E;qD16`Mx)Xu}~&--*&nVDK6 zU#cobKhOM%DD|gB>b|2AgHxT;B)i!s(;&9kdDm3VVXqQ3&*T`Y<#YOGV8e$}9t#`Z z_ZZr*LJ-{vLsz#=2j!WVT%nH;{JePRfkfa^7W2?OzyS*@{OHWJF}lE!^*HKaSPN6s z`po|4WqHoCuC$;Ahy@8`WuO}+T$3p0?|G}9hi_KI!#BGDR_PZ~W$yJu?a(CU3wM># zca*i|NM2#UPF4}^p$Z!`cIucCNR4HF_&z9wb&m`_zEy8phSkS@;d^v(>zfq%r4N&9 ze&Cpo_lYx1_Y=zs10T2uf47BCWI*@L?$iE)wkb=dXQbnX{cA^|g}urAPbtNr;%cUi zb}h(t5}mc`UtXdr)@ApDpc(0g5)tgXj2hKLGt#(9H9xX_mT@+0 zu*!qF(<)Vo%|RX#i2JS-?`i}PzK0rBtQV6>`*%QwE|@@&ODSUPIPmWSREG#8tt0QB=4_%r@9^+8obSaoO{&>f5vl@n&ect* zDv=~9CrV`3#?T~>=y8f~Q0OMvus2;xqQvX6ZwlUgl`N?ad|8Yx>P>2Wo93Y~F3Pt1 z4w^**XjiBJnISKKGPzU@Mu)(wdOeS9Ayu#AIqJJS!KJHYZ%k(qUAQDe;PY9@%|2=w zq;$5eWu=MFW}a<((e(*&e&=jJe#iREYRT7+I+tI6d4gBIZW---FNuW_3|__FW4T+0 zuIo-X$Q9(uWQni|+1$>4N24uHv2HYKTVul67_>-MZnluA=QkJ1<9pfvW@10@CP*WX zfJ*P2y_GsRo_vAkd5TZW%9LhPh4+V73+CL+PZb^l*3+E4d+%?C`Ul>$$#KIzHVsr! z&E9$CxLx>~&^}34TC9TxNUU{y4SB!tdH(MIGT3hI3$pA;sQ$_x`?TnW1UrjvQvQx) ziJo;%uv#U9vqg#fww9wU3G9jV)Hga{rXk=-;=bReUZmfT!|{_hsGNPPL7R|gX?w=# zW748nwM8pi7Qo;Y+60`ig&(op8L~)w8CJ%{{#6Q%D0=?N?>EuSEq3GUqeBQrLc!h; zp{x&I^b)Zk<5?L8!*m?=J~+;)QG$a<_C%gYd0c#Uj)2N(Q0@*8?iUp`!n9GYPsq0h zZI~4egvsw%+cP&<3DX|%RT#TIVt&$HA*auHu42wMcFPZPFx!@rM*gUt%Q7zXTfTyj%Zpt!gaaaL19YYjXc~ zJy;fzgW;!b10`*%Vm9dk;8UF`Hkjsq5-AAw=6Q2WI3ap34@3=xf5Zz|Vi#rY5!L%( zf()JLJU-=-arYlqd(fDGYL8-fb{4%~&*r*rB~InV_`EWfv19Rx=0*xJ|7|hXbUE(( zNH^iQn;o6t0dzTO0o4fv4_}=e0>v}+aE?fmMpog)mzKr^9E2!A7I~jO zsfu%%?|Xoil~kPI6~~Cmvz*-9$*^UpWnyE3xG6(Gn&>g*GKz0*M)8>x^C~^J;_*_v z+4dp%&$!P+zf}I(C%tHhxTbsu(GBBoxuwn!Mkf@Hh$>NlN8S9crNzgH$+yfg3%do) z*Cr zEu=vQdOAJtV?VVhv7B5uV$C}U9$V92b#(HSeMAHYPU`c6{F-fR(4)AighBn!(}`R# z$~)}jWc!StC$2*`wN>J8q}x92-hbMStYXXBhDb6^pAlc5qju5lP&VprS_t!rVoCRl zd>g7X*w|H`?MsI_L0a(SqYW!10K~WZD8Dmjd(j^JW>bQZKJn?NU#*a3ko}v;)Cs<1 z0F3b|w^Lm7%`!e}=JHUfD zzImUP_v+WTSEO(y6(+a%RCOS_E>rKz-Jm!!dV5xrb5NBbQFISKa!B6vgi(E8{_Ix^ zLy#N!O8*__LQ2*KsiAIdIs@0&vBGBSytZcwkERC@2xlwh48%&sQmR=Y}92Q*V{i4X6d|myHjP3bx}7zA#$$FRsLn>Ev$3p zf!_+yhxSTIdN4WjkdIl0##f@Lt5z_f}bZ>4; z5-dgR+~0egmpuin>~mtm{j6?tVyV3=tgw-*G_h1o`QUZ>z$Y~CH7m-+Vn5D`rGAa4 zYA1I9zHYuQG~%DHYwB1xDP&Vx`vO4?xclM5(A)W)EsmAa;RqL7?crV})OFHx^`-lk zU2HF;N28gnd%XETu|n$VmvA2BL7t6|(d*a)X8y-SmZLrX4cChJn2XLj4^?%$HuHRC_6R7+HCmElj=sh_3(t99V zKVCRaj^K!wo!pS>aMG92ab9o2aph(uE%LtiG`mB=2e>~n&wRLZ(aqqb9KVIn2wzrG z@O-Xtb}{7pyzwQZ9bX;uVX&+BrNt7>i))9|F21O)boa*d%6Peqd%3EkSh(4X7l zRq%>IP)e>{zIlpEc8@9nV7q)H*|EO6WprOt88MY4iR@lr#X`#^#pW7Y`ji0$Dp(?_x;)UJ`{4vlDNy7$?&uDG z2ukD7y}7m#SBg}t=mLosr$?p5nvOCJi%HZ@FGg$a)}BHsF$O8f`w zO8o0_n_Kk^%m8+#c)T=DpH7M6Fy>Iy#ct%E?fRe*QAgS2hz%ao3t_rzoRJ+Z(mZV$ z7_)rHIA^p?d++L}3OSK?^wsX3DB{Yy!QM@h(3Asp*K$r_ge}lvRc%+YVLC15UjY_v z!ci8HIV=PF9AnIl#bIg*Ar9uq3`&?h{>`_^vC5Mmgfx87LX;=TOZHl4h=f_tXuP6} zBHr9U#D+Zuy!U(Us|Pbc_i;x|AcXi zNBt4t`iOoj4&yJrjmpG&!hVIk$Hq_GMJc=|BG#3@)4*eS9I>JdS$i?GL>Keq{+ZMQD1gY?n}SKHi_pj1#3q$AA*KIqXHm;c?o+@JKmZLZFqz43>yh>rQukZ7-e zF7S$aKJXx~t{+ji*UAsJrN`jw)TT#!Z+v)aGkSPTgjH)iWk!^lDi70n5Vn;lqkxgt z+zPsxXxG56nq9}Gox0Uo!UI>tHYeAowMmN_+^~xTp7IN;;LWf8#&ul22(`U_-;(g! z+D^S34S?+OFXIPmmMv+_H9)man$j4ZFPg$7eJj%#CviTt5h1gG2MwgPx%i_Fsq+#l z@uuZ@h(4V3$|57U?H4x8{7d%Io0Pwk!%)ucJEj}WmAgvF)&tFxDHD$Q-)|6JC?k0A zS_`)8ytVIr)J$dVT1H6W;_LFZ8?O9|FCJZ9aha?*-Ut$b3P%PPq^c_w_8S^w62Dtw z`$4qF-<~yeGxEkUTuVUHk))#iXRWr8Oe@w|8pe?Zxv0+gLd1Dz^LHANd&@KQ3NHD4 zout!xfz9K_E*aZh80tf%XRL9qMMiZ9jM*T#!S!q535`Dqo0$nRAO zR7=dwuYg&D_Ty(9ZGdX13b^b1T$Tz8^T>V$@SGw@K=;_L; z$=aO(@ln5Qp!}C(L7|3ZaMb~;OXNB!QP|>7Po~dD#?3Q6fut{d z5m05%U=qEs`e3q!4$rYd&oQFX7*ov+8?{6J)(CdA&GlzCzJ zCFWP5=-HP;wDJSo*R?7f5OV@(lA%Ihqm?PeX%2Jb_5$K*X?8(Jqv9Z(R;tsQM^eu` zo8*HFXWNd6X@K~c7q*1T1d^44PCEvA(RhyGs{yBXVShX7;A!H^=NtDL+By>YA(zv=9OuVMt3|9M_V#df-3ID@H4AbNipJ z&HL9>LZN>`ZsKZk|7<+Wrq7Uo`GAmYo+DC`&OI`FDUOa7{CT?t;3e^ z-2OdvGz~l&b*_)9W9{Ene^Bu0?w#Vhl7W*8@RXZ9ofCd%x{NI7(CCSZmt=YHv49|0 zgU0KP07?IEU-g>&Dg7mBWp^S&?4i@uABd{JT`Jy$sk=+M5eHG-Ec{E)9Z$Dj_Ymw9 zM!kMVR_~Xm#6GhzS3Uu+_*rlEo^jw7a*a+wG*yO%0r|dBXIg#`aMzdbn+0}iDHVt9 z?zHkb*SspuX+1gUBdsj7Q9|DeVrY4X3()F4QHu!=>I`j6=kA(ZMy}9uFLFP09kRWa z%V)RZKcp!ox}}=WAng{VQ1!rvGwWg@Bwp=tO&@3C{lXlgp!=0g!IbWECRkq+K*=Gc z>wA(8F1j_%?pA&PZY0H|Zw=hm!lMTm01q#Z_u48@j|Khr)BfnXW!0y20=zDKUkx7) zzF{*LWsBkE$E0lyOY&zDPBYS;)+sESxVZzs4oS_~7}~~k{q336%Sr0s5(Mqms@u$9!2fod+l&uwV6%R1Nec#mul&$lFh)q|mC z^$7i%%>~$iW{SveJ&UbAmJ}xUpt+ehFfj@)iimBaJgo>kER?n2_W7b>XML7UEmWOe z@4(~(2=`4sAT@HK-}WKq({ZAH9eO5ruPy+0Uc^3d)(AYt^fv5SNkHyxS`d`Ihnq-4kc;vEu)dw@Q-~7N1_+>yJ zTjCDSsyBti?Y4j#c2SO-y5jjKP5hh>>M0%#0JCib>TInn#xcaa$Oqwv&s|A=*XKumtd|Vqv zWN1$7sCm8y&UMZmlV5n2#m@r`SLq>@NSqFOZ|aJ@8WUjL=Ut=4v<~1$3#c}M{rcru zWfLse|5q^c8oKZw@jQ7kZsx({+~!{)kv_Pj!PwOiR-Hs_Ifn_W{xNW$2Twa&ig{(P z25ezHrM}d%#NQPAL?F&rpr~!CI>y7kQG-6p?o|L%451f*yh!NX&${#4O(D7Ig!3ZlNSslg-!Nd zgAQ@-bdl2Lrh`8tN#^DNuQ07u;yJtY?pj#S{M ztKmEI;u4c@>IU6gI?^3t)JU85hvz>Nde`pj725a=r))7dN=?g@?b zu|Vuam=_X^iXrx7Ag?O!!KZ7J+WDNRySH9Q)=E9)!;g++vv(E@0W5EHx1)m(bQSDV zuT$Pb9t+}Bra|Ct-d@|zR;em+K1KhL8-R)0Y| zklbpqYo~v*PE14Bk!j;`rZ-GhzkgnxWpqp)R%pAI8N$bd6SZ@5t>>Ym(d23kdVR^? zO74{2LL@Xc+R(Y*@xyJwttg*(OI6;U6cAfD7z^NZB-TpkvBtnOf!Io)0CB*lM{svX zx2f-u0G~HcGK2!WEyoh9Q;o<1bMQed2*|pZRj*+nr(w^Kb}B$|4`OY`&(}ywxazsQ zc`&+3kCrqe#pglv*oi8l%w7#mysd>Zx#U-2bwZKCBqWz@EyTQ8d%5jE;1NBS!RdoO zcS||;48#h#y4D#@Uv7zl3p$py$fzSH}gJK+f zR=llX#&bB{b0hg>2@s%}20|y;xC<37=KWKb>l7yWT5knel3r)j)tB-S1{v|07n=)% zc1j+ct_vs$&&V-P354^FQO*9Ou@VF>d@vdiXswT;o6yB@S`tGEGcE_*ENLbt@P3Ct zQIfG=#I5@1!!QahRJZIm(;iew!B`F3UxrtI-xYz|dt`Y~pw4rh?a;5%4Yi%f^4`Bo z|B`29`Bl=2+b4Xf}ynNpxBI%;mt0;?(nb2o#WG+6%gpir_4X78AM!trZ@D zm8F`FEe596fM+;29`KNQZmEUFDq)whD@+^rRoGM{Gg1bDnHOc1Ksfc$O722czU|S7 zQLf(N5BUpK#oqd?Pjr}MWy5?c{_2?@bC3kgFCid~{j{I;Tl|W5g9#5GcYB-*pu=6W zu0^$hK?liO39%zlF}}f&qkUA;<`Yy48mh@hr0=MJO-PP zr%;0YOo66Si)UdgNSH!%`@R=jQP8bwYDZ(|M0pxpF)m>D3`E^|7LBm}m;}2qDePf3(vBJIQ4suT63g~XKf=Wms znGMx1J*EPZ!Et-urq7?plFRCDI;vzYs|EEMkBZ)zE&@HMI}Xs9eMif5Fi3$df9m}G z3DrZahIbaU1~(qMTS%EV714?ZwAZv%;Qrv~dzd8c=ToCw`6Bjmjs&E_^(g>T}W6P{z|kzSC~@J^U&4 z4>pBwZ@$L1)#TRPIB6{7Q1Vk<`! ztD%T>mKMFj;zVQL=1->s@_uI@SDNwuC0OP;^=iAB^NWW##F=@z%g7*hZ}ryd)fmFE zk$qI7D3hdz$e*vp!ZrDNqIXOslXFUcCr$?s-`NWu<`Nwsil?|fVS%*`AMz~uYNxWp zuO19`uQN&$s}NOIa(LJ+N;#W*49$m@Ptl?8xe?H;4AB;k#96$UFOb@CV}uGX6z^4; za5fkoDCko{@A$b?ZqA=erRI!hI)Y$5ZBugRTaCNEdwMt`0*yh;uU&$aF7FM}hjTcd zNqzWud<<^VeCx0BWZ@Bwuf0kPOS`Dy^&`_+5==*Pgam?+q4S#_bmZxKnG>AcP zU+p{dK0ya9%?{>H1MW$)OLz}yQkZwUgTgAugZPaJzbdF#dX-K_MoPXrE4dCH(I*Kl zAZ&UZ9mMq7f4N#BLTdDPq4A}#_(0y!39uwae|z)P_GJ|-=hgCWIv4IHnP-0Q@ztI{ z0v0*g6{n|Tzb~2=+Srd}t$yiet@F|5sM#<6dPk30KE~hjb2WtYp`L)DjGf&~L1>%j zk~!hSy(Sme08|on`LCuQk|kuK($n@358O4)E_xkvz?NX7~%Rct49z3A@`ZIuh*m|hjzdC@t`gmmg<`T%0alG#?)RD zklycmk_uMg?M0*+&96&X#nOH~Q|K#m)_dphT6!Pj z=Ii#db~q)9;%>ZNLNNl5%Gz2ZWJmrEZpi-c;0D19PP;pQXtL7C+$KmqfW0+t_McGg zWL+FfA=GFzJR74R-cnB#wq)QR|J(HQ!DUM+Fuu|ZAERcQF+=gQhTfCzDN?>jf6=vf z#%kw!Xu<>NpZ8`1b=7zq$*7gwabEU%st-(o3VMzKLM5)o`Bki|k9iB$bhu^o3zu)x zGQrX?>OU7^g8tP|_lMI@#ZO9rx?;xnxQv zP|Ddd7#*d_O$3iZs(Gr)C%sp;kk*6#XaB@8U)e*tV!Z!OQqov7oku5@>U!|?#-had z2)07O0||bJ^0;6Rjatn?mdbA?J;7fq@&0yme|JtBxhH1*Sy$~C`D?Sy+(gT4yz=LS zlazzK%SqmV^g0T3Sf(DLAs`(F*TTWnd-8gfJqVaB|5Yyv*bYG`vp06=4W)E85? zQE4Kcxs>^C=~=p??M}?UMBmT@4n_jaD%NOG@mw{ML6`Jee|jhEUD?iMF}?+OZNtu& ziha`k0YhT#X7A^MU%h*C#Rnuo_}JB`G_`m%Ki@)>=jaBpCBd|m88N=JOB>Boaxpad z9wQHl5hje!x<8*a5hXfQ*0(pWC=qqK4xJ+JGWbDhglWXbXm@lwN6>pr?dUXpZcL>pj!O?S)LDh$bjaCM6f1Q%AmorkCJe1n_h?t{*VxGXw+d|5-w<6y!b-POeoudS=uargT<@RekLft zakfX6@%SNwQ^=tKoas@+BtN(-1a;~;*S-V)%6o(HPxR$C4m7`5JWCKUd!1*qc3fX< zmO7vD3%J7KL|KqnnknLl?9O=B`%jNA$~Y$r9(e6crGdp(gd;%$F8D#Qq%is)Kt2J) zC-c!~A|&pHi(QkauSI4wBRib8GN%b?CL*YlQWDxK?Dt#IeHE%j3QsFD({PiSOq%5YW$k8;dUr~;ZIg9?YNFp96JF@ZJ zA;7w<>BopDPR0zpo?=vLoW+~I;{kXe&+J9Y)bsV`(cSukH*K9$D$W~qx*;p~5&jki zm;)g0hs5T|k~zj1n>MRQERqgOl3Sye{dtmJyA3i;+!x->(*%KT9G>G9ORBaTs=)?_ z`Lba?8HL6!?a$^n{$!cN33v6%{47_Rn>buj!PIDcP8?L>8?|^1iyW5oae33g@x?c& ziz70)SjpuE@;H(@?FgIyKQ2~e_$YY?lysi65~vP_I(qR)U%1`CHgF(t@!jD!U6EK- z326B|>QC?~4MmnZJPO zoA-}n^Zu~q1>0GuQ`=WvH)(Z7+3$G-er=6HXJ`Pr(b%}ragt99dAi?v{jth|B3qTu zswtOP<~zHQ%-gxY2O_c9(zG3u5N=TDjp-e>Z=s{rXq547wqtFsp;X|MWdJ+g=w$6; zgy?wfZhDE{H93~bJ&1Vt9lfmTbtvqT_*2Bup3anj%4xE#I&eyM#g)-2f7v}n0_u?r zPLXN28TkKM|9%re;8iEzgk=M5^MER$`Vf=mvQ6M%s$-jMSYvI!E}w{a;@D37^(>;{ zqQsmrr^z03=BJuJPGMUBL_9jn2W8sj_+OGrs8MfI&_j6JBpz&v4X{F$-lr{ri!eQDi~^0+KEC=CbRh7Fq_ecH zQL84Yf#$}lgFSddYbk}(tmJq@gJhdus$7ln`<79V#OdP}aTQ0tbp-DP9SI3t{~h%X zj*}D(0SyuG7s|BX^1Xcn=}p;Zx!;_LWR}{HGJd+f3xeX?o8`YBk~2ij=~#c73o70A zu<&LqJjrRGodAL8NsMC<-<%_nO+@L!jQ5*rpu{zkbS%7fZMqx6s=OILxEuy9l$V-p zd@R1%tNylskT<5|#LC+h?*TWjbGynDn z_oV7LB;5m12ENmI{@j-bdJ{)v(8NMIra!vJ1X^{Bh;uS&)JD&gi}s~DW@A@UX6-4S zrL>loFAmA2EtI4w&dN|}*tc(b#n$OF?xL+5=vF*OEu6ZZxm&jF1#)rez<940w|<<7 z&OfWn${X~zQo4sB)14Eg!8#@A8yLr#<1OrqZN?e2FaP*Gm$4dQt z6GmeFHC}9i1fJO4A3y4~^d~!ls(z7_hF2#}txJL``Y5&m5$Ppwy3{`Ia{oZ_h4gs@ z=Lg#*9MHtdk{|ikK+k3q_dpbf1&k1g4ie;N8;bk)4L-kXvxOps?Mm+-I1_9vdx}Ih zOqh1HabkhA!_E$f+lu3nTE3;ZD=2X()4KkL18plS19XM=WaU-1tlAbQV+wHDsT5SX zKF_nvOJB|L`^JPK*;L2rVRMmV8ZUJ2qkcu$(ofQo3f2m_FT10khqE)dU_S0em5{;xQ6SNN-*5OIg_1LU@@+Mmbb+eGeUPvj-uz(0@4j5~<*>Yt&(G~k&!6GU`WZa4c1H_~q z-w+I$h_@2r)5}(tb%>j>;nb9{Pn?0r-9kwvlST1TfQy~=;z?%KR+7LS;tNA_hhKJ} zD_K(Y8*l4<3XC)Jz63jcmT-qgwOK80JQc}~KI*J8_$!QO6Sfs)&HyI6`6K#eQL;Pf z`~C@M;1OPY3DYlm{X?WLtqbKALY6+~$Nt6Sl11IZnQ`@AS%T{-$TT8dn)+3Ch?n=* z-MlHyc+MHPY4pm^$}Ps2DmC|dA9q{2xIV^8Y5W4IU1xWJ+_NV>Ppfc$Ia?PYbbI3n7N>~$JlD-rmE0Jv68GNSJvp(64?~Dx*D>ZBAIUr;T<#N_QuVkz(_VY z1oTLO_3jC=f=4Jzf0H^XS{#>oRBx}FC5f6Dc*9C+-Q$Sn8{B`mD4!IUF$M}J*@xZG z2kQ00yi0u8c4ayF1QucaAd9-7*Uc1DIlSC#+Os`jJF%^Y7#_CQvx(b(9lo9r-3Mkk zKh|j)PjDW;n9S zWqhnFb{SP9hr4#Lni_UMr?}t8Oz`o2bO3i@wI{!rS($;Tu0Hh55B)9b_cEa}6Wq>_ z`v)vtBNKebAVfO_0Qg;omfi#c-DunSm)?euu*pFjgc-Qd8 zq)o%UrPby`^729tw32sFJG}%TrCeetAX1jnGSYmG)|$-8KoS5S&TLXZ<^`nnn=`#1LUNO`+p`8s$zLuj z7}w9|x!yiy%0|5PNQk!!ZU~xvV?VmPpnwM!XyJ6A|3z-_rlBEtkrjOdYzf=ef0yL^$c#P|JPllBj9j2 zbp<3Tu`4!|DBr`>>oSm9{i#esSJoqB$tgTNd~1g}&@6mVW0V}i`w~v)_7O6wcmzvC zzBDMB_XQ{>%|ti6gC*1`dc7_m`@9o zvu(DmyFK;sVgQTZ?`9OStWJ8T{moD94v|m}lbbNvrWuGA_VVh^W22GuyV_)u8DFv{ zx5ArqzI!vJ@JLGL=%jbVrSC4OgD(z7cV$XBcUV4xPSKZ?ef763?U|#y{MKssW-x)s zQ~Ha$(Rez=*pd?3wtQ~Pt&Rw;RCz>RdXxO0TB}!uxTbX!Haf)YOuh5r8X|w><)iTB z1VsdkQc1I9!z>i%faRj&ODx8dolF-7xj{Q97K^!P)IMaFsjAFEGNV^hUo7Qn6RM4jdvjXp(~D(s=`##(5|#IOR<&kB9d($p zC*Yl@(z=APRs@JQc!7U+90^1+F1m52Swom^WTbU>LYXVru+8q2e;0FY@oom}rMj@e z)O1<|;ogLUk8urckA1(%*cqY}W}YGJi%pAph33L{4o9tZa+L5$Ha-^;16`h0W3PUc ztHbI;5aru(2?j)avk1sD9%q&2(Rnr?73h8Qo#wouw%(}5y?D?~{o;B_mN3nl#dTUg z1W{%-#*TZnFKd)N_Lpv-$GALae^%=|m(Od)-nsPoi|*`~kweX45x6lv8p8+%uEr@w zL&~>$RHSpI%*M58O-JOA=@7s26sLM_#vqC3mE^+L8jLj>#H$b7tSy?UBm{-2+jHn9 zRK$*0AO+zYlznq^&gkVg+x?%jT&{8F@T>}#diYJR%Qx8I1KK{*FUv}K`zM-oQX|x* zg6=sL3OMFR=GX)~_I_v>s`#2X+x_O}dc_`k*UPJuNb@kQ&VX|HKB1G6WMc$mjMUM$ z2hcPl%Wd_dBfOL&B7cr8us|EU-1%T$HEt>1evECMWmOzEKG&1Lx^bO112%-tVs0jG z$@kAWb@=Lh5~XK3E6aWR!df*VW!}b!@Q2hqU@=AgAQK>@oxTC?brrS)7ZIwc}PjVD-LvZ9~sg*xCa}m zc3tvqLI&G!aTXtyUoNU;ZLfy-o%7E3S=tS}bWTI;V&{7H*YTkF(W-K@ed z4Ed&Kp@sx>(HMy(9`3S}^+u7;j$USeyHA~;y+eoXa9k)iHB>WfMC1QSEN(>yTYd7- z1x+n>b3nZ&8a4;NNI>exgbFDo$?Q=$X%%;f*4xn2u+!W|$-?^dwukb2j#AaGY+Sr+ zDLt|%E`(n%rKq)FHx{S^71bbd(N8!8FnPzE^4}BkgrGV$PHDu=tE54Z%M^S%PtTE4 zAt?%7fCJ@G`C^u4;LaIeQX{5l_wzb_HhVFdklV6#b+*1 zg|Dd^;@L~g|YWR(w4-Y8)Scw&8#8$g48)ear=E zD%^u~vuq|?y^R6=EZDOXbVkdLNuZcdR0X>gn|hH>6Ws4v7%j_jrJtASr@^&~An#QW zD4YKn_XQ%ZnA~v7aZd!4NTym?jDJz=H<(mYKmf)VOyuUu30~CYXEOy(nQ52`zHj8c zIOSgGF;kOK1gH?ap}3(X#Bnlv@LH8X4rtIzZe!088S(7!EgqsM-}5Vy)hr?RJsIg- z^|gQ$)Lv9kTr81H<8^KV8R;2|ATJGMh&{3p7|6x*F@fytX> zN26p@H`3jK65molEq9LrmoWZLK6H)%T<$~$p0wy9hCQEhj&w&keS*Xy)5v@EU-#98R(@sHtf8u#BP@d3avER5kAVO)6UUM#ooyDP(3bH$Q@M`E( z7o-ttClE@MZo(Sb=*#C9;XNoaRz+R%tfNP?ZhT-z+9cIneC@o<) z?*%eCnP=k}Hm8U&>U~*)Yx44sVrV+28GZ(aMo);FDtg&NDK{>R?_Ah;ts4NuGw$nt z`QOjDq1dm|!A=TFTnsU{QACC6W^Lx$V1D2^@7OGz~ zc>Kf$Xw8bBdRMjef~s>xg1F4UO2Tw2F zAhVlm;SWxWFJ$3Mx~AvrP;Tdv$&Ud8zo*p&lxBn~__4tn98+`wPnH=36sq22thq{@_WwnZZ|lio!5_n83&l-w^NA%=aWmy1D^ z|1*7Z)7Lq@@BwY!g8kJMML1w_Jpmw|<+D7z&?=2!axd1h$hvObJpe%fBfS;Uy#DW- zTmoS2HOe69J@F@ir_Q~pHY?fE6`W~Iif@aSxA%9uOT(lj)dk}A`rP{sO%N&5CzpNM zh{(pr1ab?-q!Trc0#y+{4{m0A=nahU52TE?CNF;8DjXt8R=rW%RVTk@kE+(oXRIEg zQg~+t&EOvYogQp)G;v=ZGK@w`kNd@x|@>ww<_~lW}7T!jLR?V5D%VRLA-+ z_sN4%O~#m5oamDif*3SjXvkW_Kqlpd^U^7n1U_oV;9i zn-V~nz01wz0SF~yml4dd(tTrkM9KoXoTA?0OAEaV<@vjtinbZxCJh?Nr|i*uJr}zU zNhvJ9DATd-Q}>vCW+`*y2@;7!*3uafAsllX?nKm*EDQf*($NKC2uK zWZEkH1qdZ%X4b-QC2ccsBD`vIpDRSIZMRV+u>v0z8{m?{6$%~ZToE$CM5zY+5PSjv zABUti)J)>CFs%ol)shDn;%Kqzl63XChOew4e>b5rCr8O`bPONgUJ8Kb4|NKkxHzhC3@9(1e%Hi5BqdU9#s7s z0gE4adWY}Wgfp527VK?4Ap`(v#?@&sk;))mmnj1YDUZP1sw7o@H;QI7Xmxo>mh!aH zzJFP@*+7^T96*-2BDoTVcsW>p(>6Me&j@wpp}hK4CdFqDSwZ zej;XTv2g$hRJXmoh)%Y|+il+XVgv1`nq2gFMdeu zY=`q-2S^AyS3XFTJJfxi*n_V_{QTH2kB$j;-S6%#!l)sYs-ib88Wg^N{Tkq9*G;}l z11THp&dEw5lgiXC`Y*USumoQj7`!4W@YdGKSdtPMn3aku^`{y!jP6BMa1Y8JhBkdX z5E694Z)~%!ne2x%Prd1W)<3Zv7EJs62+@~a%KRW)V2jK=KbAh`9+0SWf=nvgN=`2S zD0Lu+YtZ#uQzv$Q`$Nv+E~CVtLmFgc;|>0rB#vv3(l1;9yIDpk`hzyoEXf7BHg<)TA$%{oQYr`Gpx(6kA_IKf@!2P& zOcGbB9lE?z!jb3sR42-nT%@qbn3j~6-~3q;37C-x{URSmC~AQW+T-c5sonpOEI?nf zSEFqDtzmfK=fkQi(}0iA7_kb@w~qj9{sMEL31_}@NVBVIN7URpFE!2a&!qbp8GiYj z*GvtJ->QhDGnXcPZ`hSy*f}9>2srFCv&TMGr(Jm4Wgp?CUzm#k&x8t;m%=)*2ifzU zj<9@#Z~%QUTlYSwOM#ONs5Ip_J3F=BIC#q6BV&vYo8@!}w_BrxPD3}Dk~3f?%ck8~ z?^Jz1N$ZS9=(hIiJSkLDw*<9otK`}wQO}76JveZ+qO~W02CHVL z$`JS1NJS@?&Q1YOSLp~Zl7Hvr`(moi#;f(sh{Y&07_v3Dx@b9bEU?~OWpl)@Za{Uf zO-<_VLj^xymf;4BTB|AE7AljbYn&#ZwLLuJIet{|@E2vUS9VMR$-{jLy`SG3Z4((7 zN1eKDe#&PGC)d!f=6(D7O%X7#u}lYKen5?AlQ6huP7~+mbC>_|=_a3ZkVRIN?jKN6 zqpZ~l!O>#|SrQ)Y9b?Bon4Z*!;EZSbaU=z%8z27>-(ly&~6yF7G zwuL6h?}T8{L7W**#=%tAzDuX4h4)7fL=(DHz2m=5syqxygFS@@O1>bWIeh-q(|VKU z*9yX0CUIcIT>o77%5_S3w_MHAnk+lWN2 zPa{e(DSuU#ybk#np(Qe7sdF+i8IE;FY}Gx$peDJ{63#vWWmFSqm0wdnIKNE+qANub z3sVXUDlt+XS`{(Fl9e%IqI?`E>Mc8a8ckl97C2j$aXv|j0+X*AQmOTrBd20X5o@+A z9C>!0qe>W6S;#k!ze!K?$Vby|h^_kOO$OYq&otQ6r`Q5cq0Q?eTOE~=Kq_I0ot zFf*Z3f^^xWPPl)8Klz!APd!J<^J6yr;kQz73(hZo9v&LQ7+?l*7uliMjZf)+X~_ieH0$l);1;opac^4!4s?J|qX^LNg9rUMeQ z;0&}Y@5JFtn0FpQT94*^ro7bDjMA9nT1jUIxA57S%_&8z(wLXU)pQU0JaaMVq%Q)K zINB9->v&b9ft!4X!*nA<1gb|xKS~q#2nNH3h$CILn8F&P(r3J$pZ6xR9JYBt47{GR za?rK3r1g!M=Q_zRsnw4Rr7o6R<}-h|&-n+7`Z(ni$5IRy%j|Y+8Bs#*GcXbnKMOmY zct!2)Us%TPiw;gqSQjgNkOmHd%j{lIG?6soUJxK4@1HVMNk@AG@W`ZIwj224airr& zl@q^X4E*G$dvBsH&n+&+(E%R@7JRk;fZq|&k>m@;&)3thZ;tU;jFG87ygF&! ztH4>PL>)Yl*+6-z1? z9%C;9#9}n1JvBd?lf{(g2vPqSmo%WDGTRyX>vQ=M6Y_SHSoKjFmPeo@RJD5%K8FzL zzjFvdA24I}Y@C5Xk!k;B2d42xoWvS!`>u2;Fx#&VOHPbGAHf5oIK)7wU!J`u+urB_ zD(!!BSc>LBW%7h>lD-dE+Ge$g%XkG`jwqj*2}E%AUhj+` zw>t<9uCK>LIL)3C-c5x$DH`UGqPFT~f11h)W>~h6fOT9D0f+_jelB%Ez2i1hKH?3yG7X*Q-dEpKzdNn$t(V?xN(`t zY=InNzeXug8J0@G+cTz1R5+BW*M}ozXwSdz;OXOSjnitvybA=$3i|Bdzf@f4tJbvW z%NjnguiW`LA+Ywy*o_y2`2!T6BeQ}2D8dQaQ&Wh^H576q&|K(rrY#J45y@GqeX(UT z$KNo7_n;QTy!U?Rke8TJ&8nluVvZEI5o+mUjH$UF&dgoUhPy_#*kuTNBLC&D{~(Cz zrzkOW0%1koXnv0V>g;kN!s(J$#Zes?Da?IXlX6=}q8{JA|Hak#R9N(y0vc9r&(FuV z$YNu>XDktiExOACXHx+CU-hBAO2(ZIG^m#WY=PezT#am61EQzGlU{XQqiC@rwmVmA zm)mEy)jvY*dazbci1VEK2uc+bvOg-O)0ofxGDz6#_>Y;^nx=Wp!w;ovKNbaJ;@%k6 z+Ykc1Pw2@qU`I1-Xl}mXAEd3dWslz@BV^xJ%fy_xp(wDxIN#s$$U5(IG8?rI_kh2I zVjB#sa&D9^_WV_(N>$b}`gk*hNECgBrH}EH_`WPItR(9~53t7wczK?$+?B3hk(tB{ z2QF<=tCnZ@t*z3hu@czmhOTd8G_T%w9TV*fPSh|1%6>pZML*G`Y5wLAzeUocOBBhe zG|b@tZf+CbGLr9I+Dl9j>u1)NkGe1)Xab~SVu;mhB9@H)-DQ9O_z$JBt<$nY883!H zdSs=0Unzt$&u)?wuq<*kmz;?$g3}RN)=(@N5CjL9q^q$LUeM@4-bb`o2Ug24uKDV4 zkltA7aQqA7)V2c8g`)sH9rMv;)3lXW_@@}2o({fzBSk$;b%X&{2PUJk4CV6zA#z-q zf$1+kF9!}e1{i7XOQI|(VS)9#Tk;wR@{cy0Ub!^yb+0Zw`awb5LZKb?%=tC0F6G-x zC$k)Z_}a$-k4o;#05jn2kmIgDm@6}>`zowSdof}`w`Ri>6Zher=cCL;!QQ)HoYc|@ znpkkKiGjeU9^fZ{Or0%Pxda5-7&9;OhESF8==A5-hh)p$>9EX_l?R;34SREp^q^Se zDmK18tZRaVk=&dRlOWsx$Bs;}!8vIqsnvE52jfyi;zMVuU}9eIF;5Tp*)1Q7&$<%1 z_1`K+v5a-sCvrf-t7jA$))`~q6+UN{xv7OPvD&`4719C1GHv2wHKq7mV?_ z)wz^V{B-we*pxtVu8HE0XUNE>*3NJ_95eLXm+dUSpI*dOtsV3CF@m8{?^HtAy7PoI zJ`>V)A!$D^jY#H(3ZAl*A+ty)=&FuA@K`3`Kax=6T)xUK3xiS`epY!~1dX@yth@qx zFkuOXe%CHAL-*3qTsMj;+4&&2GI)Fs{$r@;bKxyRcg+ulooQo0b$fOSb)f%x_zWdB zavm{H?C}*6HVEI($E?$2aZhJp-jw3XxVO}h1s3pw9WMKBGk<3SdPh=sig;`-@&7$i z9!Jhe2D=%*yEor)?0}yB#ObFnAf(CU<7)TyHimVDx*jB4K%Zq&czg8|=f2VPuVaJR z!v$$p!yB46tp{C9XWFYaG*U)oXSaPGjaTLZYAcw4js%C>cXoSuYc|k4jA+zK@X9VW z&a3&9&neF+)}!4x-Szjhy4i+B%HR%{JpN9RRnyBcrn1r&ckm)R@IIXII52(8q;#Jn zFyXt8I8VC8A(w@f78K4iJyY#T|Bxbra(7Dx{xU;`$U4W*4)}*-wME}x!ta~ZykGC;WkWj9c_X!kNrZw_!`UMuh&rz{^`-EfngyJj_hWujiTDR zKMVA#`fvUL{s!7V!)_7Tv2kKCYT<6D9gEm&O8w-}7_@AHB)DOX^P}81Bo{D{ixRB~ zYUMX{MrP6?B#l3=8At-Yjh*x@RW)0Z`<#HQ+aC-*K0}@%U<{g2Dyd%ewGT<{DBP-# zb~r5YVkIc&^}~vNlm+%Dt@0}Q*1T!i48- z&{O}5z+_+%mYrN|q*uZqsh-HQE%U1ZNU zvh;ez;-)7Iy~7~*ZWRbmMt83J4iJ&KJT~CW1?r>RK%P;(keXsg!lRcw|KiR2z(GDJ zw_=>dtmEF#*4!T|Xu&zx$_SxS#d;;l%exKn1cf7lKrI01A1;4ZVQUeQ#pl?-z<;v{ zNxQpOpMIQZriA%6czd_w{kBvsP7u~VF8|+~fJeAx5wvc2W(6f{$b!ccMqfMU$;`+@ zNrT*vy4qoxV>UmT8Ly@Py*3t1H&{dBUlhjMNTCuG-y=^n?eEQuN0n%tiBLUT3AtRd z5R9p&RIvEpJ5Ys@65Nz*cArRSpIUxrI(5?Ys=9ak;%|nqz5+yqdX_H!du|B}4*HE! zd=r))P%+xj*{A*QV}md{gAcHg*(#7Ab^n!EG3?rO05Qspa@9<|?*cDf;_E*G2_9ln zt&h8MCRzkxX1ccVVfhseTK~T2RlK`h%PMlMcB`b4(|4U`)*Wd@<9D)sfCgzb2EMzU zzME*lLAxxHbBeU!RF>bfSAu7-;9~!SVIo-G>yLR8}W5MV{6F!RW3aW z0XL?}Ku(C<(2IG3Rzc6_N#5ha;1T)|5zcQ7A zwyhXn&v@|%OEq!1&UTix7BfbfRCmLif>8-7f57$B9nyv-ekx)qxI{2Kc#NC0*>LYh zgo;pB2S}>r|U*;yquYT(155zcPh)y$U3;c2e*_{kA%@c$dwtE-KyDl?>ELWYy!O zmjy}{Qu};68i8XVso>|>a3d(J>_h%fNpuS;m3S+)v`0sVTPq#pPj`@n4 zLEPQ(9)V8nV*b$igwwVX@AF)O|1wX|n;MYeThcfx-)%2zcTnqJ?%>a8y#zVR4i}&F zNd;51J992pqZpC_ZIaKDm;$%PYm=RWRvsKYZQ8BBwowzLpuwLO8Reuoqj}NV2qMNY zUg5$Hx(wR+Q$uRj(ja1K$e0z|Yd&6&~nd zz6VlGDu@syM#0hNXT}GO?v767;Q_T_=1SZcFY=ec*k-DcZ?&-4e@&c^iB3-vbNX)3 z8qfx=I*d~QkNrW3_5Z$#afOcA|D0jA$5y}z38?u<`k5d*9htF*UQl_)cRy;eHDu8e zrVk|B=wwAx6@B7A6kM|MeE&5fSIFz`D<`LOTq4g4yn~fTdEaG8dh~MHwpFy3G=CPD z#^++Kk|-sh>q;ItEOTThY-@G34-(7#{;dv8PA>Eh*D3GJq3gU=0g(QKAh$xEUtNz6 zS)0B`%a>&_Ko-Ua@d+<7GQ6{`J%Y-NjR~6;D{qq)^%AzJcBC@WkDaXaXyy!p68!`8 zHwmEckqm4kXVC?Sq5+2PRwB<9u%qkuV-hDDya5&Uq`e7i`d>}Kamh_|yvARC+`G8I z!}b9@WEzaSqp(3b9d&UVO=7G31L(2JCZX5T5O@vk*pt3}RR@}fj!Xfu9&gIN7tUZ= z3&zr$n){d;`W!-FuEM8Y(V++M(b4fFp|VGpZgIiB*_8Ob{&sE8NVGheG9`zHXHHTv`WWw?xc%HP?_>e5^3#@1&< zoEjn_oz=yBlU=e3H3!^2_qEn#4fe_9j%_Ms?yuSRey$PZ;-e6>sIHO*D>@eSvpzrs zLrX;pMsPwURZHaW5|F#!45oHp_KE&ujODA#wN&GC#lX!+z{aoI&O9qsi)OZS@aZru z*uMPeA@dEjo+U}`*>EX3EaPxYco=woQJtF>OT}|>m}-bbL|g^;HPgkNwM(;v6rf1k6!&X2?V&HbblI%` zMd_!0Z_Tj52qmh*@Z|%>KF2G1#jVu0;AXFdTz3o`Oy#Gd0tI{DDmyAR1HrWfe^@{S z>&-Hs`NqBgy9Xp7=j~AA-e(Z|e-7(VJ%>s-0 zgFFsGza<>pJYiKcgs^!G~$j zzoDzeS>S;=k`at2fn(>L-Sg=(8DJCqvoFnP|M*JWr`Pi$TAHXpXG=j}*0-OiM-kiP zWAlxu5oeLbRxD7EG6q~J%x!+I{kGa&`0DME2Du+0vd)&exqzM~zqT-33?9@_n6`f6 z{v++fUorA{$r#zDea-_cIj8cW_DapkB0jenq<0E%MRFZ#bYJHlWF+&*nm?-W+J6N# zl#G-Fg9)gkX6gS6>DZ~|K_-ZHa$=_pgs7_Sc<=OfzSN9d8X^Eq=@ll($Ose`5&2FJ3Iq{p1=g5^w)#^&36ZVhcH=o(+cf zoM2JOI_uM;lZVSB`xsmGPZL@S78i3eCBFxLjanniZeDJK0`4K6fv(nvr;c%N5}dE9 zoRAcY8TUEAv2X77U(rjsp-Sy%lsEk=O(9PyVsTz|-3ZJFF3Z?Ca-0}*Me@cS3nA-{bjDTzt(ePG)l;8 zG4B}qlU-Txi9C?9{AK*?S7xU3(KTOu>sdlK_8wG%KRLeRYbjE)!l#wOqin8hZKNm* zSoc5EUx-|6Q6G`L_e~*c&J^CV$qrSX<@#^8pP1>ejuqj=R~+#M#DP^7o6kmbCuk1Ey>WyGv#!!8jM_NHJj^SsHc5ZXi|j3*c9(r z5FuvO2y+=7HxXooV@$(Edwwr_4(PUE&_m@777NLeL5m(04=z5&MSP!nGn5&nS=@G} zAY=-AQ8G9m5Rx2~sacS#s|06>KfinO8_(#2{O@2Gy6F4bNgO=5?pr98pdxFK^N**= z)?(Z%t#b;zb_UsZ55)JfaexMg62IF>m7+m)uZ+`eNW5Lwmma*oOO zsQcVod4U2pmVeQZUY*^3*%N%bEbT3dn5A|T85NO_itM7UD#l@C80Xp+i?fwwgS}*1 z1F2YO_bpX^(f%$ye$3*TQNWKJAhjtX8YnO`+M@_uHclv!`T!x;ygSf9G(j}-)+|J_ z>vhGq5UJdBqsRQhl;59fy6-7|Jr>2!SSdxiW>-H1wIDMlUBjc^@f$W2jRT?M#S4`t z!M@Y;uc`RVDx(`I_{y$UTn@4_+a5H1PygY|3X=yhvX?UtN7-bptz2jK$i&DbHVDLm z0Cd4@$v_(Cr(JRR@K5hWGxQTFxmdDZz1jhC#DNuN z<|wJ^*lgP^B=76T_!pI>VI1QN_=hrKC7b1WcfpJ-M)}F=7S3!BXXy@-#@#?Ia_n;J z<#%@c1&WHkbw7J2J~S}^Dqx8SU6(u=YB}qRupZdyTa!YZw$N>1@VDcQseEw3Yhf1~ zy%zzAmYgPbJ+aZ2oFxTpmYnxlts9ZsFQYpCR^;6;v z-#$M+Q>oR+q_Ei`nTw-Mr@yE$EzfkNMYk0++Iy2vh5c~@d zbqtZ=fiI1O-xZY#3PdX(fPg%JUa-e92uzONcmha+T zmp>WPnkR=7OAcFX#vtqyR!FUDec@2a6zj&le!*?%t7dO%yO{N{JsN<$<&njqeQ!Gg zYYTxbQ>lb~$;Y>dY5|K>E(Hyf?T!;IXF6f(bkGZYd_kUS#nlnf?iCcf%MK6$X8o5A z1ZIzffS68x$Ch zyJD1-SlJt%JKWKMbwSt*kY&IcBfiBm+mhY-s2q|5`w=R8yeni1|7kNFkN~0N5`iuGI z1m7EJ8{?HMC-2Dh8(;WQu2@YUf7)HBp&118LGFq3uiEaVDNQ+IihvU4dmaN0qBTTR zkAH)QrS9q9SwBX8kVCKiv){zZ&&t-ag+t_vltHGM`qH@#{*S^k06qJuxyPWfUqw~& zQlB7ULZB1yTaOq|%BIM%HLsb!>!e|i5u2n7lT;UX&puW0D)*^KNk+G~^evs6HIb1- zq(}eB@K_b;PyMyJid1c8;972BVqTg5Mx8U!z+^Bc|C$$UgI$Pxuyi0m*Ew2b0}t9Q z`!d5Frvz^g@M&%SEVz68T3*WV9Ouets>J@S#)Jg?I?U-&;NP?ly6hN{OOs;GDnZzO z{pFu%H$tE9jCY271A?y4V|L|-&Wc%a`vnI(0YDb_s-PX#$oeX*MY@4YxQMIjq$cdS z+R!-D9`e)VrP({`vhq&Ro_`7<6X;_`23ydn@N$t#cJ63FUTN>lHoiSnk6I|CJjURy zgvf8|1Lc)O8zBI96Oi+K6F`0 zLTER(u*o-S<##WkHA%qbWcCB%)Ew0Vn+ZD6$*U6BjniPCJGAeLUPZpYG!VkC!WMpg zQrfhg{A5k*Wa*Fi*79Xvz5sOSklRKd_ZT>^WM(dC+Q9!URgBDf5wr-IR?~p&G=NtI z=F_bQ7UJwE;f`2!m0{+ustMw{d*EBR1$fJF^WKGrMMTxnmIJa};Sjj*768 z=F-oIHyn~N79}Rx%HD(*7nU9MA2VsBj4`}@`edu@Zq|noI^2ziSF@=LkgteFone4_ z>ApW(byn;Ck`bJ8j_3bvq+`<(dXjHr0d^($2W4(}7t?XpbHt~0(h|ZJK8eTxht^f3 zPKZ2k-PL1&)jFoczVy7_2fLBtelc{*zTGT2yp#cMO*%bV{^Qhl{gbJCQ*SoIcemHQ z;K!g3y3h3+@y!_P)WWolNQgTrHjQiLtf!RpCQiOy8e@giae#|`*jAt=TBEprUo(_V zE$Y1PwFx|12sBfyk>5-!^@dWVK&5$uIfLs z>NL%)qng?OXA$+uU&LaJbNc2&?)M1^OdRcf6pvWnDyk-Y?x1ZhDYcv;=#|%0mTft( z&{Cwh=JZ?0+FHewy%6-qyh7CC-iWw-IcbVzoZ|{| zx4m@P2;&3##2*sUJX0%&{i{A(s;#kp>_Gs{X*f$?uak{2P`vo^Thdr0GE2Qpg3}fR zedYo2IcVj6NcYs@g=h8CjfI8s{b>)YjQw%mB5V%iDF&}z8G6zj4qnpqJPxRzs3FB{ z0o#SKnllhe;bt_9FN`ACh^m>Q2B7mB;twUkURH2WIOj@mZp1v1AAGloR6USaAz~o+ zgLOW5WZVAoWGBrs@vs={`LKEOZoeYo(X0-BNu(i_&R5(^K|Qbo$^L5MrozkB!Qx-) z0_|~MDnyDm6K5|b+7;S(j3`53%02U))_&vZcJ1D>=ca^L*GA?uN%5KOG3bh(f%1MiY8SyoL?-z`=Q0o z4kYl_YSL%9m2FIpc0uM{M@b2Fy^m7d%0}x9RUGj_xu%37{4F_6g3%;`YF4g@UrfDQ z<=o^K<)0lavp95jck#fb-CD~*9`yU(F$AHx6ye!}i77!vFveIQY>6mj>9K{RRm-^u zPSd&~dQh-eeey3$B_5^+u1kX-NpMSVM})Z^T*I3M)bA$6baSBFwK_LsA(LuZIYr)) zl#K(wZs@4&-;Y!TENolaC{c~V7r#W*mNWE2CvjrtK0&_NzeXnRFeMzT38e2+(7dU* z9-3~72A$X4+{^e4Tz*XA)EVE}{B-`^3f5D#qAAj_h0fCQ(>-buDTW!ESL?)i1x**3wMyg8+o9g_xZ-36k=IWTNMKA% z>?X5@ZJeO5jETi|j8*0L#o(itacXp-$i*vXTX! z_-nW2ya1(7YZpB%nxliy-ITFSY4;%!3XYKbPF+pizwKxl4hk8kMgf+Df zX%OZ;P<$ub`Z!t1>A>gv(!S}dEryUV<3BgD11Nn-M+rs1Dj-3g%~~(`32)u1pT!9l zx_DHayJS<{BqQ=UM&649-4@bCBKacDfcixP2rFXeiH|}iVe72wzuJ7AUh2EW_r1(- z>bg^XuZ%i+`E}xBhRnC3#N3a-xLY2Dv|;7OTIXUA>m)B~wdUrcrBxE)7M{_!`-HXM zpY8B5-(N%xw&wd&&E$2Gi>E*I|9Cp@c(}SR+y_B)(c7pYYD7 z_8v~?B+Bkv3zk(a>G*SXe0%iD8syo84)^GY{7IR@SA3;v)#@(^79|iFR>&L!VO0!K zk?tC29L?m!BXp^ZE zPJQ>mleiZ=GnsN+(h-|t=euPM7yZRXQo3^rzOpyp%r_=X0ycwppgG?H6{b9_V5ZzlX8u6;Oy4xyPFqcLQi8U(x;>`vZ&XVCW^S)j^fF_+N z)?xd8{hQN!@Q*#-`$2>Y_Nr$Ff2t%Jx2%av z{As*!OKCbdaTUD`Ss-z2aT_CU<#m2CLEp)?&F1h!WAcC z=}#}H49>88m#0AA7nSv0vG2)7##KIMrWGq_T+&60jvlBucSkaP>Vr-As*>A@aSVOH zf2LN$eHbA)Ys|iFogjC%EMzU&MoN3yWCBmOyMFewp(n&ApauD23hCSl4%M$Kb4&0a zy9hrgHM_U^aSuBD1?K2^OA*H_wAeInr-sI2*E}@3<%Z+-3TZin5t!@n<66wM;~fkkyM< zVZ7@(xLWGG$g*=1xv;{j5vE+|vd8Q{KlbEEFEyOM!a6ZaTQuY6 zEUBO7Bg-9Uf=Nc5kN>DmuY)zz2gW+=7zXUW zx9^j7O}8B}qf)S6vVdos|Aju{qSck9A%Jw;&ku~C@)d8pM6I6qUAy{y_!;6SP5_B1 zw|%mnW2>duJxe98Ef)Uo| zkE6QQS!;8Cv-uP4)>#^{`|0i~MA2zuuv#QiXCEpRf@8iJ?wbC3MEFOjRw$p|-`)VtKkKIbuBkSUt(2`s2(r{W zf|5}Rbtr+zE}cbo?N~XZshvnpN39le{h;6|pRQG|qur`klPdA2Af~kf{y!4HxLj$r zULTJXGZEi)MMW08ud6wQ%p12vdQ9jPqVTWX1+LhuX8XF_M)?8FWW2f8*BC=hmUPP$3_^;{lR)Kl|4@IXq;zmf|5vHnw+KL+c)bbl=u+H0Gju>in(r+G{1eoR(cZT~vO$#BIg&h3I` zy*S0k0_LH)UGDgx?#26gGCSU^Vj$)f#oYwIo&AU2+K194c{44Bbbs|$ireEA{Q#}F zyTO@b+m+6b0t3F_`HsEChCOWopU4F0dV!-+ufDn>U!>oljGF2}FiiMuvi)PSELO25 zlY4#BG-9q=oG||H(gxS7fcHOp|0mFdDAiBfb*e%I(%qihZQ|R&TH6?yE}7=ke>IRbtQf_Hoq0CO1JPt1cXa0HKrdy-spS^XULSG}Rgxbr*BoZ3 zaUrf}EvS)!Q>T*6HQ-eFsWUO~fu}PG^D2JFWfsR&U`^pq@Tte~_K=&e52+!&_RL)) z{HYzDTm2j%Aak?tzgWxxecp#z>M9&E zXn1HKbA{YAWuDyPE-su)!I-09s9kq|HZAE~@H_>=@x&=X1a`ni%NsNv(O4uEReYK; zikGTa6w#JTX|~aRuK3VHvn9)d$itPhIu8QPbU)EdH#9^I`GEDaE_<31h8eZdL79!f zb^BWW-8}E^b5*C2#n@FaqSeLdgUB|~z;j!JudxmHPv>s9UX%5QT=P?a?K8K8^yFyqnAN>ylyr$dj8U zti3(rA37W~MB^F`{rtr1$tMP`0~j4f!Q1vK;m;L~ORYXL9-Uo+MC-SyJwGiXo_1Jf zU(lNkdZ&5qX*RjjT3in#IUbkGmyT^ z>x-h;>5=bW4BaszaFsm@B9U+XY0>QP=_=KKJMaRI*u}|-UQwY@1pNNEAq04N=CtWE zPEG7rJNPZB@2AkGA%W>Vlg=Jjml?1Nf{@}UIhd+Q{RCT-`3DyPs15AguR7}K3fa{3 z#@DVzAhLnSm@kXFC$SWIfC=^$!&lW@i+s~zktmX5J;2>;`>Zs5@uh>TE_tZ(QVA3m{`c`~`-KtCt% z8@rQQfxT~oHsL_cA9A*no>pkP{TDSz`a|IvUj&=et2hpjGFy|ese4jTW z#$U~!Ksghvlwb`9Qw<^^H~!LI7*nKTRR>{cP=@181z+wqcY1GgwA83B(D@PH$7ly( z%MKA^o#}nX03%oeu1$NlH5*Is57Tep8OWK(d++|miCm)*fW1276r}y1S1{4-#D&g> zP@`NWDAc3;M@Bg9Mw>I+L`%iejrfy8%x;-LX7R@ZQkME~mLET*9z||Vz|Qw_d)pe$ zxl{k&g2{-;raa0$94@r{ac({E8`|PyEGK2T!;i2maQwe})eOwjKA63+VBbtx=6BF~ zk;f$CI3uuJB(`_IMyz6pv`UWQ0bR*$A~{r9nDY_qhxOfK0086vXX6q>o5ul@cmH?^ zHqwD^C&k-E_%^i6*XfUFl@>DY6IJdd#yS-@w_j6|E9b*(g^K{WxYA~V*BdsJ${b3{J_M9b-t+ADY%BqZsD2{zQy&G5UO^-XxZ~~?)W_bZy^xhS0g^bILYQ2$sey`PemGwDb_n8 zYKjWdhZ!kShE3mT6@pzc4=5-jdj+FAuK?Vy+-4~Oi~N%Qo1}4?9zb1_OGwvP7+jT^EOJ1uY1vhS#)*%Z z;f6TuO?}gsYeEMNLb?70zR1Jjb})Q^EyT3?mB2z}!?i_NrEk05o!J>=$NGKyuqqnp zM}=OAv=r|p#&WF5ttkH37w7I$p}b)o2;gVT08tqp&ToWRB_H=VWGr?)ZDZ*P;w|x|I~Z{?R(vaigcM zvwZ7YpZpgy#(LO6>3i;E;?X|^=iAVpjJQGwnkPQg2L2!)-`tJPr~_97{z@tvC9L!m zjBH7hwijwQe1CYiNdZHdxYch`4D9x?3%-&BUcUgy2Y69c4~@#HOMD*BU-Mfn^On#{ zquoSjs00QgGx#;>;tC zC;h~-`xU}uo@AA@X<qa^8-ZX)9L5=)f`-pSzKIiCWD}%b26;dSv+zJhyTeY0iy`h!N;_%V* zh?=oN2kn2*LvpiqX|>nbAN<}5ippUKZ~YFJ`Dk9hR$Sv=G$Uy*{Z1mp@4Lx_l^UVq zVOovXo>bFZI7~QEbHQv-Llq|PG53_eJmJUH=nvrf$`nMJnb@{&^)ASRX7P^j!m2) z8Yf)dW6O9%dcSP)5Xn$fWR{oE_$-xM@{Q8esDMaCeF(dL+%(C5U3MUuU)D7eYUq4U zP8*@1!Y2{*%Q~=XsLxPs&s2Wse5Q4xMWKInm{C=BD{aM4(*95}cY~maEXHWnxA>1D zFM;1^U@p2{=B*HVXjZ%Z&Jl)wxD#hK|{~3gmLv?(XWn=+aoMN*$a5K zc&`HqoN8swEh9Hc_S~xsTQdD>-IZV!GbO5OM%&9p)Ta4SPmyM&!^_^ruN0a0ht-E4 zN1nDvVDtuxxxfrRSi@a|Ri7HUPJJh{9qBw@FXHL@Zj6i3@WEmdYMlj2l-$Jh_DId6 zBu4frd4ohg8G~CRV_J9db16^vs{R@Zi!fnE7W=OJ#!s!G23O6S5oL7!9skfT6Sbd1 zX|^}XuoZbp%~5~1yyajhF=mNmh*zzOXb`yj{J#RJc7~{DVxgH(>{zIml^DC3ycDnlEIc|%p3lt|W52)+5DDpDh z*^bzH4A0{^YB#1DPBJ>Rga#u$09Hp@`yF|8DG` zWemJt7jF+=9_Qf7v*cZYU%BW~?Y}zjo&OyoF2iW25-)HWnB$Vi9w20_q(s&x-q9aD zwP}}xh>*ldS?Z-W;YFwON;>x)Db)aLTaSJ(mF&b)@%ijg&9yUFF&y_g4y|H2Ln z2ljq3|*yOes5snzEC})_&&G7 zlXYr#ZQfoc!zZO4cFb9ECYe}z~kTqD4MCK zY_qqpdzGw8aC;+gJS!G8M|LmCeFKE=NCNGCf7Kim7V(x|Y9Q41brh6}(OQOS?7yZ8 zG|9`gGKb1mh;vP!R{^!^Nmk|60$+I;%l9wxMIi3$^&`!CBgd1-ki7I? z7b25D-BYYtOKf1NRoEBdeS3j?5UYrOE0VVLri;kN!(kVI5Wg| zbB4S8MDia*W_>sBjaq0$zW39A!a7n1(P2yw`cs`!ck0ONdx^Zcgmlic*SjnzpAUzx zWTcFT)6#S4MexUG21?#0hU(5-waW{f3z7yF6EO6aH9$Rc((F}>&Jed4|)bIHkQ5Ntd8 zZJxPeun42F?tD$F#fEsyd(<=Dl z7ZE$AhUH(KJGv$5it-Npolea0+RnW)F;RT*AX^8u_-5Gj4t%#i)n3zlk@52eu{Nb$ zt*AXp=RPtw$^{%595(;5aZklW!8mZ7j2cm zkAsCAUv^c{(sjP|sBB*sk)W~SFRh6=nrSl}er@-}`r&m`_>Hvu zoKmXU=WU-E9zJBCA12UjRw5dVrk>Y_NWwCtap`OBJP{ifLS`)By1S*xbIq)E{fH>} z?ZrPE;71hf{ba2A$O-zR_N#vja74i7D|&!G8Noc1Xe9R)b|rhLrA!0HPoJ8WzIiq3 z+Ce@U*PPQ*pogIcPwQdUbC8GKAH%*p7&v9;ILX&l3q8()-EbNR+_dw`pM>9rXLo&p z6~4yM-cvc4Gr|+=HP$mpA!u*N>$5C3!>pLe_VE;=EoGB9ME$HSI2S1K6wDH|yF8de zG&$TZXHYLqW#`rF$==q+Qb-)J?b$F(`nFC$W@23R;HE5IxFZ)HTGwM;&;2OQsl?9o zmgB(n5n+CDo35;Kw4HO2P=iibXd~qDqB+}o(OY&W8rP3+=Dgb-=SK7yDl-HR2e5W zg6N7*P_vR+d!=-(nTHNuN{oKU>#+8Fc}@>RkjBdyE&XXj3^J;Hrt{k6BfX$>Q)Q49 z0bDEG8|X5&6z{N$HAs6znftw-un+vcOPGP_O~7A$qZZ)#ASsJB6WFVFO;6l%G>h8s zc}mfieEO?3oTo36fr@i`68!^kAe*|h3qA;aYeGYbir{g3>v>I{bETmbKDBJ~=$gBK zfdt~WE<;ZXz+YxkbLRPhxV<*NZ^>)I5EC$4?d-*)W7cyW5h>No{UZtwfnDnXj$Fj9 z9iW?`JwvFKEm^4OqbP-EvNV7D(%@R$9HkPdJhjB)RdI1s`NfY{!77`xda}(SoGri- z>E{;NK>3>iwZc;X<_|W+(ACwSJ83n?Dm1~eZP_Ya9Y})&^uL|Q7ysfWrSp3v8gtNk zdP=lPX3+et`YtmPO;1+!Yi4rc>dnVz!)1zZd|&*6SR1X@0d%Ym3WoSbS6S5-?I_u9 z{LDbIk+-29+A%w@RRQ) zffeuOls7TFniY2#y|7+zt!Hfg<=Z6;JTxD4OM~(%(y*iHM7k`^ulzbTAT&rQpg%F_ z^JZX5&Gw@HTURi5E7jU*xtZ-a#x00iUu_Ii62joC4vCOHiS)2cuLPA!xKB&=j{~0FnQD}9z{Jdir|~J$BMu`I=x>1|4rck>bIFYO;EmB5J z?j@fei&J={nZeQ28Fb!l@``-3MB@G%`1At>d{Sxt=Uqj3bD?@NTbnRW96|N zEFXU}l8}v_@<~ky7g7c~mW#n-r{A_mO^zQ|Dgc^UtHGVm4bz_+ygq+WU<^2-A8Vi2 z-4Yw+DY=_2pug$Ng0c8s7?)`4Dg~>Gv{^3X%#<9)7V{2iA}~T@^&~E3aWvSfdEfus zR~%Ccbr*9M%03J$tbFX1VDvmCKb&o`mEwV)&z)h9>1tHtOsp-(PV}+TrD%B>7akD5 zG9h2%5}l#-rURup zytzA)Q0Ibe>n6bSsIJRZ;DeirLh&!y>w_eTRbzsa|vBG=avFSV9`DL z2`_g^3N#73cHyaagzXyLI%fnp2U|zyxCIj}oX9-s>FJ`PCiTqSAU824qUoO1-j^^k z?!geO>N9X07=F>}IZn-O#9$83b3h*&LWC%}V$F&Dg&MYz+cyYV8k$~$Hb|0yI;#8N zDHOZsKvIEG;E5fbY?I`^1E%ikt5)*H8r%DF#w0C3cfBWpX<+INz2^`Vyfcl0YtmuKPtt5te47-QBPzkm{PkkWWo9gi1hD%t}{tf4ZbizjZ8_`3Cs%6P3eh zJmcUyjo3v(2Ja*qJoSfeC|>zC?!YF$$4}G=B~VOl7k*bu8W6RHdevK&_yNl>G*)yU z@A{!xaTb~>Q5=$;HO*WB5`6qq8s2bE#*j(WO>MsU>FX6n&dY{52+tZ3;U4T%G@`D( z&1JtQb8JP}(FbtQWw7)e%;BdBzMC8BH7GzEBwrI&Yb|IQKXNbF5Prw8Cf-+pg+(}I z#j-U$7h{{T_{477?4CnZaB(>j?ne6_K2rbay7m`SALxzvs)Tg7Hr5Yq;8RaMPRtS{ z{)F6?YIL!sQ3}`CWnZ%`V=sn)hN-J$r<=Q5`qV+$0G?=i$PF(HfS!833?J2%u&sA2 zi43DVapm#C_EkmrqYnq*#{-`3iP#NgcY%1n%debCgN0YyoGT`UAF7p>JcNV$M>)`z zUfw=Kxo~1qHtPSrNEDM|E9p~mk1uFlcQ4ktohvUJGh27e5JknBaX}oa^Ub(mQ2S?Y zs>pbb5d-;3sOd8nkIdf*Wr+v(ZRRfPGdGWBDq1U31c%cZ-UP?!S2?{g;gP62h6p@VFwis6L$G_GAe+_P@@dWlYhm0Y@w91PHCjd|?~>rO{7d}QJUoQLBG zzVWk>U`iMJlWMzRZO_>t&~pmv`Zcw%s!gxm0Ragk;S0+B5S9c_B(7jYg+QpMh_vM_ z$WYvC8K!ygsH&hp^pTiHm2Ymk_u%58y&J0y@1O7nm*iKQq{qNrBb1IvmU>3;R5tP^b9A5oS})U#sM#nN12Dp+W`Jb9C}?Jq#4=V6o9+CD z{8j2TgG1c@;ImnecD2-iEZqpW!C!u{#YqcPF?~8~kckay$V{R$vSCoj?Rtn7Saop7fVNbxPxlK3mPbP|m|^>{DO!%?`Tsd1+C( z$`@*$lm7Xt3w)0@QCMY7qS}~R&;G#D?B_)p?XP>XtOf~f%Vs>==Hj$wjmDaV`YQ1H zv%djmMu005;_>25TBB`Q+a$#t`odlLY3bbjNR`nwKcEqWn!IlG^sp-yCoG)9S4{nE z@}!7d@fB9`J4Md`dZ^gmN@7>10?lu2@m&U?z89S@9>CIqhBl}_CPmVwYFbB+TDeIl zCSC|+i4Z0~&XN)QeVD89mawt~^u?yrHY+W88J$(VTMk@$fc*EE5~)pz>;=r>xVxw3 zj0({bA=eyCKw-ba^n|3 z_7~VgZZmqSgWYjsX{M*W0DV`C9RLOa^y6I^&|d>}jOPk)lPvL8ut9ti16J#IumeD- z;2JR4PmGzNd@!2LZhyim3bnrE2qa|o#C?*BU@02fXlO!QAT857rmS~q3WdqaeBVj0 zcV)=%3n~WQf5J$4ZE%)?qxSbPtHr7vtbIsNbz9^7G^CLM&!-~dxnWaLp;P@BGeFh2 z!*5Va`y1_Zf9n%mEyds|rd-H4hhS!7x6}U@`;|xryQY7ze~YmvaV%&V(DPIUx$8zc zFkguSF3~fX6KZy<+VAo+E9pWFl(ZoS%N9n$P0>OQ2-xc$znXii!@aU;YXZAczPWoO zzSd|idYbj+kAsmWc2wJ@KJoSp=y?SbDv(Ar+klO1EwJhI#wq9m zP9B#LVAf$S(wms%k;JQZ+P0r~qs+Xf8A;cqz*{R$&ar;`sdRDZ!>9pZMbzedZvOya zvy-n=l~b(f9LQH_ z7y4EwS*^Gh9MrzAi1Fd4TFWsJ_V+ca&^k*HewO;}ZNN`7y8n&g=$Qr=`Ya^U*A2IWY-)xOn>3tDfL>>ntfOuTZOILU>p?~5L?lA!j$T#no zTyLXiy0GyM9-V^gOM98ysLzQFh{sc(a`z4r--IKia0RdWK%I4^-X1>09}b3^Zo><^ zbeq~fN_QiPcT?gahaHCIA<7aPHPZKyBS*ox-a3A}8G)8pllxSNukT_;hyTTzl;;)u zU)*fcvbTxc-Gtz%8I-FI{E&ZYzy*R>a3tq|dU3Ic z-KGZ38I6zJ<7m|CuHxUnp>}GqIwb)OEtj;F)3yBs(Hb%#H%z_XGbv-2K(=|SL2e4YCz*&8NATTuLp~itF8)O7RJv3+ z;EqVfsJHl2<36d;U&_;Wbps7^uv>&b=Hf~GWQ+5y!5&AJn}-|HH7MM(SZZO!A45Pi zC+siV=PR{vo!bs{t%IdH<_WK&1f0fVu4edbqyl$ly>Q7(i?|dAK!Q@A;^1QRe z3_K-YmFWs9+QGIm->@l{TD{`TJEhTz)`t=@G!G&0h4?U}DBTkvb{ zSKwG&^LquHRet(4r>+v1#Sw9IP0@U`r|<&_#<;1%DnbCy8#zVjSez|KoODK`mLh=} zpk+3&V?@DyegubI!GQpqou}A%*cVc5`^OP*eeu_78*QKPRSt$FFxl z=*!0tHqXZ?ttoa`vugP*mE-}~iDCJQCK$&tBVgf-NDLs$=fD{Ib)%Po3#xI?r>Q_w z%~fE$UM`~iXxWECzHImWo6XVzABFYPcI)8~KUAQMNexHqEL!eik$DxN&(;{;1`IHJ zd`g@O{IseI0?sUc221eFGT&!OgmcM8Bp!)MKgFyM+e~%8O!YBnOeLEhHk$9+wR-h{rX68jin>%lI zUcApBMv~W7yRm+yNhA1oy3NO^3F8Yy#cA*q=g>NIsZ5Z6R)dS*`~Onoj{~okleM#n$Ey?TkdKd zKO)mXlH7w%vnV%gAkB=wj>LY4i1H)3Y<$xysq&@GU~-QR-TN{N&i?bCzur(Bq8jLU zYCC7-aPp|Q)S2lQ+95*!+T@xVqropii32-~AUsB_;5|snQBX0715d&cn2JgpdyPKY z-8T%(_j19KSHzqQHR<_fDET=6WQ4F2MG@*C(>DhYo*%=*Y+wv z%rg2D9WRKvUhm$Fe_#y}>hoFHkoFdA4^JB|33Q1P3VDE>tw`g{S*z(Qm;So!YwVbw zbNx1~gqyInbLP@?2tQc|l{?vDYSiGD20JJU8^nYHDvT&jNJj5O=;!?k)jORx;G0AO z?hbDr9hzOc!FRDnEs7hk>wCR`EKd^l+ql^3p-40`SAfD`^SpHVz z_j^YzHh-yp!0%l0v0u*uuyGOCUGI{5?zI@UOwi?gcmE3- zd57YRAwzm`KD(i&Z2jO{8z-aVOFqJOS=49Shxh>wk+U$wX;iotsxo4z^n}%zPpoFO z{<8SjBivKUMs9vfecClr$IaI`S!DL);j*_PCzUVHV=;#~x*%r<-tTaB8`T6piSqrJ zAoTnzIrpy07|7bXGS3mE@W~1=0)7vZ)r4QYTaqbgUqE8|QPJQO5LAQcHh-r-!2@ij zwj)2j1VRfNs_A!n97?@gJb$o4&*QBtw^U*3c@2c*vRL0(l*=wS$+dyZoWdfEr|7e$ zPV#YBz+0c2BBm2?FcjkMYqhDllpmV#TKA7VYK(YDKVcnc&3bQd(sXcl+0dd)$|1YY z)dh*tmOQ^x^1$oDsM^xW9V>|-<9k_X;MH^wZy70a$ZdrPnKlyad40I}9rIG`6_0*W z{U;<|C9u)Dlw!j#B{!T+Hh5dH`EZGI!~~<u^khSOJo*Pojr&FNTmg%ck7yR8K#Dg!U7Cr*{Gn0ZOx2IQ`h} zQHj>xrrscMRpZ~QHghLr$p(UTVl~MPKuGArA6GIAm_MrIvU0bZ)Vg8~c1&6hcDGAj zhP7%--mOu$gf64$3=NKYaZ{)Ns_uEA)5JTWL0sYZt1&wdUy^o6dX;dFBT_|j!@*#n z^ZbMUnsx+n-eIu?K zPdHbOpcj>qAiCxAJXI=rF95m%dD@E2gI}LIxntUi{m|@D1hC@@<3FcDjiX*wVR@P# zGe00ysd!^Qn3{UCh8(X76Ni}*k&(Yi^mI{>t8JQb93(L`4XbzbJMepo?@jH zd(BO=pdnx7wDICs^_yL}KfU{V3bcJuED-kX|J@muW9GXPwrZMmr;XTr>M8nw$#_y$ zL-B z1q*Q$GDSIv9%%NOB6{s59ReI=>(2v;D3pYf^d*KIrtOPMm6y{tb8iaS-`A3H69AjRXgnXCk`BM{JjlERU zb@V@<`fck-B#707^z;^iEGV4HK14f3-ss3jmt$|y)^=uG497YfH!jYvk&D*$X5(|SaikW^$L-ZM8Fr$JJ`Xu zzi+kR)?XIXJ~XVD3VZ<`+Tl#zShK==r=CMyZo!{->lYl+q&*i?hMC8o}!pL

    _!6>dEoQV!L`=CEDS&6IIq0zCzpt=NcFD>TE|CFJX^&jm=8#@+B&;|AvyH$e=$(# z(Bjz}fiEfZqMJVUCik4$eOy65gz9-!e%Fz3doDziEW&8Kf3=79=xi%CwwdQ)$)wyk zTA}0b0o3Qzb{mWzp*x0qR6+aks~^jm6wq6wDy?mY-&k%M3k-*$PhrY2bD$Tk-GR7k zA9)oT0SQ8Oew>#Dt-^6Bbwz=;fu)4*&zlFa3NYHoM?GNfp$PD|ar&neRVQB4b=D{c z^j3S{;@^S(y?YiIKiOH%vH}LTKgyDmI+_O2OJc#lq;#mm4h+O*mu0W7QS$Q%R>@-s zE(fybi48NMja&a)+%yx#rN7Sh%#0Ei4`ADvLo-bwFH1BP2b?5N2RA7cD=&muP_-nS z)ahYEjwHe0Ago5H5o_)hHFV$Tpx-H6P@qS#k#*u{qF*13go~mA-6M%=4I1YdE_nES zU1cQX8U<37K0V>|o&4o#uiizAEGZS8*vPurQm{L8ed?dkaQR}g{>gf~B=lnJZ4l3_ zi&y#SiifI}G|td?B8bM{fzLAyTVPi-)S)U2@t2*fQbCTlVXU(Bad>ZH0?9|0Kj^$k0;O88dul;<3?DXHRCl~|K)xxJ3S27>cF(7+Io zkbbOwU?=!4pS3VKGf5}Sp1Y+~^f_+N{#x8%dd=%HUFC=B9_jA@|Oa zQ9v1EcSMfbb5I&*>GM4hueDEQKmm&({F#2$_H{K}7XlsCpH`gwv?jjzO5r)CS2-U- zDv?Fgm@$A6Xu2mvQfoK0G__vu8p$B<(61NJcfbqR>E01>h8s!)X=D+I)xWMS`XS)Ce+=fCxj1mE&a)h_1%K44%e`+Y%8PBB?N2GJbq1I z^T~q!vnS8edXI6G%y1lA@tA%u0HSPMFCU?4tow}c|7xmBlF;euW&Yw|O z%{`Cm6%E8lsKp{AhdRv%c6B<6hu52XVr3pQ63Gf`{>{f1j2S@7ZC&3JB8ZsbJF`=7 zp-QDQUD$;^@qNZ=sb#b6c`TrZUn>NJCWtv}T^|IvCUUg69wxx1@gN>SAfmCyS-NpJ zo{Z6%J)DcKl<7lVQGtGsAL$7h1rS`{CRGg;o1x)lDZl>6q34OKWIG$!!^XWtok;-q zO2;O?mcD zECF`?IWvT&#;CkjPio;>Q15NHMieDLJf9dV)F(ZODsk=@P!@x?Dz_ni{-} zYvcQ|xE&o*4}3+|DIFkLh(1yWI?2RBF&6qe1=-mA?okRp)8fE7>xtBLkev$?OPG{g zNa(atF{_mG+r(GPU+8ko7m&YHS2<3<$|g9hkT(>(LvUQX4*B2;z2Tn}dx89{IMX!M z&&&;$*h>imo18Nx>jW8+y@G=Xo^=(o3 z`yJi$5rwg*0u27c7pfYbrUr*^(`aZTJ_ggOANM5D%Wxv6?m7!yw!3M+OLuIeaaMX7 z1|8^i3X3*}YfS~xr}h2zMDEZ#8W4?FrFawf#RI|uW!~vu%MIN!VAu|4D-pbC#y56> zXr}9X>nnLXI_jMjaMK*w2i5PT&oa%tzbyQE=PQen=nhKpw>F~T-(;F9w(FM~B>SG* z0j-2UtHVP;O2sjp$TG*{P&6HPu4{)7?OJ2I=B38JkL-2kD6zO!CmFbclNUozc3Ifs zv=Lzd_8Zq|ki|ac9qM+@L$3KpT#sTpqX2dIRYj2bmlWB%2{YdAAZ_>#Witg%&DiqO zkF=&UABSPbK|joyZEq1E5P14Yxb)Qfkd)(Ypo{~-9Hdd$@WS@jfwQ?78bu`vG#%fi zFZya<7csfXy0wGw_C!;x0;?66v@$SNiC@|nrStz#_+l+P^qttC=@I3s3wT>6oLDu4 zl~v0R-Ht_84V_+M@4fY-{I;i56>l^?Zm89}U>5xBOQEz_V5LI1+0P2m#*3i1q&dD9 zYKQm`l>gp@=4p0FWLZ_^irQ;_CS71e{CJ;k>Y^wlr4v}1tAmMlR*Bwz^A+)u_*}nJ zVVr@1N)7R%A6L77$Og$8e%V5|B1E8#umCk*D?E4j%sM4`^i-#2_uzHv@X(g$7o!AW z=>G0sT}c}7A3JqwiEQgte*aUtXh*G2l-R>?H?-@7RQgHAp9*Qhxw&}X|S@jAkM zZ)o(%a}mrVluGEODdhJ^pqJ5{MHT!S$yoxMV;j0_5vyS*QH4bXb0n`5r{5Q}nV{T$aUilU~7+ zXAm!A1xlz}X3OX7pY#N@trB%iQiZuz67e@}ig$Xq`9uo{s`|&gI?!okIJc$>q4@kR z87@V-7CWhA>9;QWRyERv?Nc)abP22Hm=V*pe-m>Xi0<_zb?{h^&K99iMq!q3Bg&P{ zzg#&vkedlumf-p|3;Rl`zyIAI^_n`pBGlCHY8mYstwL)9EV8?XSCmb3i$&oRBWv8`DuO3&(cE|st}DQ9bddW zux7htKak_`OOXwW?fgpu*xPL1Z*^gDON>buxo(LcVp=yaI4S@#>vNS7D6Jz)12;G- zQ{Rs=G$u3jYeLhDfty#nO9mcWDE5Nmx)=oyTyM@ak0VmaOKQot=*vq4D4e;)NqBN z0-`rvUu^e%f0Bnpxe@ZER-!W17IZ8~UcbB!s)dJ%2{nFsTl-;GwqjinNHu~kd+!L6 zji1FV8nTtLU-kViW<9f7*h7`b6eblkL}a45P3zF08L}=%Fa14Sx@+n}(Ub*N=RQf3 z=-$GUDVgO+i*ae^kadp36^G<4D<-1KPsk-oMEcXVKS@&nCIfTS>!)_j(OW1=Wh(Ic_#}S0tn_%87}W?Z@a(SaQ?#pXncoN%9z%q2re`wzDlfZECc+s0 zi$r^$rcLrLzXEE2p{3C>rHJRUDX^qd^B){ut}$OT^#rQX^$>b-Y`lata<2v_A}n1&y&e@u#U4bgi35Y? zzP$3Q6qCN7;I!fuSau31&u$xN=Z5z&7~=0$r?IA8dw} zy|zE+>`rLS^Q+cb7yWXwXI5LHaG+(LO}>=LZDt3gs3{**zp;`E<(j1OM6n5_nP=cO z#%IDK_gl^6P%H2}x!C%!%6yOR4T1Cw67Od1JAt=(M#&biP^<|*xHT0 zT^Q&igqsqz|LBtLXCf}TZ5!FQUFsHW?C|f`>#uumMx-`#@Wv`|j~Hm#J&F1z!u}C9 zUGJ*@#XZ(hYq{8bbQhrq8@Cu2XS(Dk$GezlV>7EFD3@(3{rl(H-q8ux*hMV45I-;^ zg70acbL=49*`zBr=Wu>srovemx+30yCcq!nYAeydXHQi+S*0X!a@txYqJCeoWLRDF zm1w!up|}(b)D(Ty5ijvw+)+Qyh))PG>&Q7vx*_&zE*JLOwZ)VJ8V3H3J62dSHb3B045u;T&xiW~a-SFM*wg1QI7H`jzdS5QvU8+z z@LKNQmmNhvw#LaW^*25PFrhramA+J5pX9T}IV)*}-1RSY}Tk?RDY_)VsUq1>8?>~rzm z)1?BAo8B}{ z>mYXcvgVC`GMIC`zK@KAT@hxPX)6r!^69|5ss!9kcU_=nrG0Y)GSy=JCxJUCA0mRB zDxsJq&^!6Z%Ru;?U#y4iC##bZlzj$j5`ol53ss~OHHtFMMtlr1{dFYwZIs#Vi6A<| zBp{CPMLal8)kq`f1|1ztnmPORi|E;CLwSFa8<-7gM52}0B1w|-=Wiz=Tz-u@QI>Bo z{N0}gMnUQ~y;Jd16-)a3!yE;z$g!Vo5l;y<-8y84KjDM{{)=6kUexK|>EZR&=I?d5 zfh=9gFcQIIYOMM1DI7bMiZL9UVpw;`IBAqi28_aNQ29I(giFj& zFr5jrGHiA;qB19XLhNyg5!fi8!6T&HmCPSWbyT(p&TR zT!Y^zD%=Z8w@9H5B+UwlD=GDVqalBz!R`huB6J)VJZxo-Y@B3w*1n`FC{1RTV zF7$;}ic;<%$TLu^iyw%ay5tt|Bo%Lu%aKOKA~oj*(laA~no+{URIt%MrGHijjUJ79 zw+zTp0o)65YpfY(^CU(b_l_Ld?NpIX4Rs~~WXqf~TH6wCK)UTu3-OzFd|Mo@LWW6| z3CaO0fxEmf_b-%FlT+dcS$_c> zF(W&F<-Sd)Sf&Y1W0`$)e~1`=ym}=p?YhB^tpr3lNqwn|bO_W1;|?6hIK4Xl za9bO2ZYJ9g-d_c)VGpW89MD`X`Gcl@rge1*qxY8CL;#CTE2Ba(nAT#Mg?XBGREb)ReAG3aY^I7M$k5 zz?3kkSSoxChkXXF?_@ZjKCgs(h+uZ3oFmTpB({#0_$K!#p|BER(iZ=#z7-shjJ<-> zzyjj+j$S1Bj*$YjBD1UvM0w+Dq~XEOrIdwN9KMZ9u~8>Rrb5{qzb@N`1Z@MtJM;SYPWUX#oPoWv)bml8{&A(SZNZ*H?7(W7w-k;&XgzOD-BuAJ;#*Nw= z1&Mg?s4b$it~8O+lNpYs*GBf{M@lWNyx-B;pwNV0bU>woR8CI$w#}3;gk*T|k<8$t zLaIEUc%7Oryap*S!x^W+^kU!CN?EVlXwY7TA@K{pr9O*pM#+;R@9?B(ZxQ+;7XSCH zGtY0O{ZboU8el=dMFhEU$E zp2hsih?w(lZ1)-V@v@MCUpH)IQ~*QWv+gkz;QZ(=x{>79ne)=9y`tMM0vyc3Mn{I`K;xbkIfr%Q0mL0jNJ+n_d) zAKuppQ|BFuu?U@trNPGJ);nH<^JfFoFpDpr9{j&q$*?ngVX3WPCm!b7!Rfl^ zw&SZ)Z;E3hkr|*?o7aj=#60t2b=NO{Ctu^XSMGO8Qk_EnlY?)`W%(9c36!7|ZU-IV zTBpgQrowzD5=V8QsBfetog~w?L!?@{=Vy9EIp)7`(jR-^UmyLfem531-U->{WiaW3 zYmTYSm(NE6u*vduwBINOn~A;|09)%}$}WFg*s09CNeDn*{-^j*z-#+4LUPAqOt@n~(q_zW-azQz`#)nK3(8#ayIAm#IzLeT8V(@YUh;hU z?u%f1*7ZFrH6^yHEgz}F#2$Q$u0_A4a`di&lr!`Xu8}M8#tMzuy9evlFSL|3+q2d) zY4_z%;K@8#a8YRu^xO=cuzwYAolllbLD#N~LaXSxW_elwv;EQ$q8}=@mpei`m~Z&% z7c6<*C*y*d_DG;wnX%#(&Um!ZNb|DdnxGbGCjZG#F5CwKKHdQiU5>lfagM$?(79Ls zv-EV>l$`IZ-b@}g;x?d? z_R2KpEiWeMZQFg7)VUI4)%!PoY|TKfy#;|fH1d}5hT6tVf&_!{GCEqyw0HBiEJ>HFNMI97TXhWg4~;^hV$^0@$WY01 zc7i_EN&|718L`3SobGnk;__;jPZ{cOsd7GPeAY`nAK82PhVKzkLohemSAkSn7N2Fx z-{X0d9Zhe&%|>^9kohJMQs8}?Sw!b^BHj15P!T$s}YG}+Fq0t6(6;iCqYE!#j zl2$g>5Sc<_TBPkSf`z(S65lAk9h+7#<5o0$#t9;1`04BUk+mWU#ljzNA+j3aH*`^& zOgz`T`XGiyCqO?I=vS0wQveq$Xm;3(iSjl4~F$% zy2~}HYYPFW9*Klvr0)BPo>DSz>G_&sz>P~2oXbSCvOnpxyAzhk*;M^4#z%wZQ67%{ zlLQxKi!t800pb^bG$P7R%Jfh*O;MD%I6cU%DLyG`Oj0{T7-{3Ht2i14{aPC{nbR>@ zq_G}I*Y+n02T(LZx}+%uS{A&;-i@|Z5v^Y$#R1eWiH@eL+hBdQWZ81;=bSG>$<{<# z(a$iz4aeAwbxDj!jqDhrVWRJ53o!IhFss{O9;5ALwCrm801mp<_= z*KFYFa=))>x@Z&F`FMV6Rx}AUkcnq$GAQXWQM~sA@iVqly_XPurBhUz4IHE&We6$g z$cBPH%|7T zF0wH$xq5_~rDt6t-5Q7U)y&MWlAL0F9kP^2yT0N|h6g!-`F>_~!PFp@Q11#H(%A zS3#6uiRL3P5Pu@LX3v;!qv2gs?U;1W`$fji9>9lZB(ILK)r>luEc(-}PM@LW-v?*f z1#~f4I<1RM@RO+n6SN~mL3=R0@ykK31@5fXyJPaYe048B(Ji|N8S3s!r-nf7xWk!E-fCAnQ?NZl=Gy#zu7Q7KCGBAZDhg``llyB z!sm~GB?pqG^oE**Lq&2#>i@=yt2l|l6W`5+k-HPCl!?&H!xs3|NxJGaS|UFPXTQvq zGUU>TX8Kl{1fn+RQeYDK{AgP~RS-x_hri6ui`g5O zYGM{^plTSwD#8zbH}S?}kva}al=4C-b?RT(7)nWZF4hDV^?u!5cKYF4A`oNsz;r_M z5b7{2yC|-a`UZJ?`%k%<2p=+5%RLQEle~kk`6Mk#`cM5IV(TiS^m2^FU|mP^neReN z6b94;QE8uQL3+l4HFg)M=rIo`9PnPG)xQ=Ng8J;YLi#yo1E&O27TNS%D1V3KVM&sL zx0xfzy|1Y9HNE0BTjjb={g{PZtN_Nm%rJ2Ha%97>xlRqs+;3A~>3imU)EYB-VB9rN zcNQe8yY>n@s!R&fwxZB}cnbxK3jCW@va=)>jX^w&WJ*{bTq(yJ*z3tylJX860RDsm$<@4 zKobqfL*(VrLVTvenu|59kNBXHicjF9jb(YHi#1((;x5D9qNQ@(OaqRsQ1J(Il(%Hr zTF%$kKugC8vJq_8a>FKXfPQNP(I2Kiyq!@l-!lZsW=L1k0ejvT)vB-DqU0&McC{q6 zfM}D6E_O~G50>N59d7j{)#3!O68$iaSv$nX@cxzCD=l(-_CZRImb}g4X_jT{rO*9x z39|2zNtDd6=ay(TBw^4yb4A8J9PRmKYa-|*X0%hxmnb$~bOY1yG3Zci3^QGGjg@js z*H&cfDxvAsH+4%IVSBb;`f(7>a};?Ct147L!}stP{m&E*WIshC=@{AfT=q_#VW)Y&p&I#C;LqYzF@E6M_Wv1*^%nlVjC)npCmaJr7!ExCte&(F zDgRHeD+vh(ThpNAy6{%Oou9{|*A6QO@~z2$Se$wr$Jm$8_)K(%PhHQsS-JKD(Hpq+ z-JsevZ(o{oiiP-#+Q3&XL`cl3EiF{%S*Z*zB=5T0G-QH8-WvFRlni+REDOz_sGC1P zsjEzWFm!JlrjtdbR%8-XxhbykqBi77Fft`+>IxnDgk6T*U-a2N!0N#duz{ddbgn;A z+@6DVevzFJBYLnV_6W%aVU@K@G|9Ohii3a^!Ws^{Nhvf+e0c*$#bQo!&Fp@R{9`%h z+iyLoe`q~K zM7XVZ7IrpfeQw+VIdQrM9`m;m0m4ToY#$1{jIoU`KEgVPls5v}gqaUa!kCFE2DhN5YY=e#>%a)qARrGOkV&usvgCuHTvZY)0SQTjWkDpF7K|MdH@E?3B zU6nKEz337O!Ao84h7HN{inxC$ob3*^$&W5XzHoNjX_7s0g7WZ1?8OS=D(@OyzsuqN znbi#^tPQXvBmJ9H5~AfD=ssn`UYDa7Gli>X{iE+w#oY&I%GNwrUu^&D6CqC4;Ih(f z{bG}Vj3oSM9Db~0oSB4Ld9`K!wWI>OsuQvsIWlU>^$d+@EA=i`x0laoZ=NX7lixiq zJzP_D7f&ngwnVDTzg$D(Gmfi;D*6?;%Z9G2Jrl~FPmnD|^JQ#CYZl-L(t<{x@h`Hb z+VhD>^olIs5PXDHRc=ppEvhbxQA7wh5I&v$X=#(UROUU`b0+K#Fm{O*GyVR8FKH)G+ixo4j5FL9lhs}-zby+^l8Jm84B0t2yqS!SN*4e zN)z$VfJxcU%fq-DUNj4~b%k9VIhs=ybQmlhJU57&n_2YCWV@(o9TR^5*t>FhKydHT(`cn0U;9hSWez?5N7FDqor zOL$3T++rQ8_b82f6}i8xuw#NQSu#O6FI*jEtcT6hFZU9z;ncA6Hvz#SYyBh|e_bCk ztK!X<(G%@N^faN>R{79z+BnOTPwkH99W;;Q>JeTU`2mNXt4taGyI%#=B_2P2@bV@x zT8ekss;X~U@#45&pQAU-6kEzQRfalie!cu0_;OB;9K`6kPQ=3UJfDPjbJs-PchbvR z`OMPq>P&mqoai<-{SV|a%Bg+UOU@&+maR670IxVaR?B4=b<;LDP4Ur*d3ue`kcWV- zW4k;Jy&y9{CANgt2m${2qxY;?%dLX_hO6*36Ti@G&XB!fqszc@c%a&Q{<3c@j&iCd z>5HA+{W6CNEs5Y0O@12QUGCpj;OZECjI6=@B@Q07(cq>GZc5CmpK$Q=9e@$Tfok;C8FKA9gQE* z&%P}#hkyLUlDYIQk-0{U!6XdLs0nALKt13CLW4ol;R9i6Tn>iuH#x%})7kM|ZLlYE zcK4P>@vr_Sh;z#R3LQ}bvH|p0!b|$Y=pf%np7@0$7*OqJ85vxXZ)0D6obC&w{!gwL zXrE#I3%p*~&u;M-$iW}&LMk!;I}}LKHaZQ(+R1n?YK10Me^+L27~RrE&3B@S#7Q+} zYazOoowEWsedIBFPW(MVRhR=c%V53wwQ;&sf61El$&rZpbm zHl_^GY>p~!f@NZ&*mgU`I8b}5?*zAf*3+uUbzXsk^Vv!2>;${`8u5`U>`qju$r*lvLBZY;)wWEgROA0ovQVGV= zIU+8W?819K>e~i;1-$7@yqLf0qSG&tMzL4By?H&f5?JSkuV_Rn>hFSU{v5iZa1^y` z>{tF=ueSit7JO?P$CQOVXywDlZ`I(n+D9TawAf+WRDP3X_I}A*4WR8-_6rTWaJ;v5 z`dXw9pL+!&cx{(3r=Z$xv!nPMISr_tm zl6R-v>0xt9!U=PlWxlhs`&`EA%L{e=lXO{1Ro7)E?rf$!CZVr6hL>Gm=x;Xgy7TyV zqT%^5KON;IawI;@8T!B}H0mSS?JUcY#UK>hNxM7v4K}nFbEGJQ`8&DgTBHMdW>)Yw zie`T|p6ax_G1OI-pwvl2k)#KA&Y&;z5=o+FDsrJ*X}!tF5KPF@w{EAFZlaWK6K15%cYbTe+7oCfAo`BTojJR(MJOn?yr(!P`_eer&?79Ygo)1Nykq4Q;5lCr5ob zkDdA^cu-7w=%23NVld7qXwk$p*Lv9SnIgPxe0ZH=zDHJe*zD{f#zb~|_LIVT@^{PU z4w?0A=iCbhm4rWqRNGNEs`cxEAwENA*q^62zr5EEl+wrQ8DmUMHJRe*q&0xc0j4+d zXrB@+;Uk4XCq`))=YlPJ^G~-~$iKgz1(rfxN=JjKOy1oJSAOKIzgJ+`Z|CQjj^2Ow zi+fb>z3f)IC{pvdAc!+`>k)mfS+Ss@I(T4_~CNMtgtM2ZfI1 zVOdRIZao>3bvq`|i8?l^c9`yLs?WWNmx%CjUBD7ZZal`n1 zSP=ihedYs6efa(ahhh187@PCLzq$V`isxs^vd&z$@4FE5eO)JSmGmCkh~c)l+SJ0K zU$ydmMJKvXWy(gOvG_|}aNo0Kn_mkdW(N1AXSS&St3IIkP@8vO>!MA2te)Puq{p$) z`tjucR~FZ7@;{V6=zd*SiMU#_t8rPf+==LW`_(T@*wdH+ozsGCpPXA`8c;G8QRjgo zA3l&Sc1m#HVx;?S&uUVvdzsqOpR_W*J1 z6Gqtjeu+nmr|R;3cO;@Sv@R;PM;Z1QVR}~2H-4w` zHklkiJMH(ikmdIs^JRJny>iFspo{vq*d$>yk`vx%(C*6HdJ|tSn4RKV;7h&R`jwo7 z$*2nNRM=lXHQz|1#`5;B7>wdsLc{^Q2i^p=m*)zb0zVGo1{;^L2Ha$+ekL$FGBrZK zwNBG4{cZZHyymfHJg5D@3C^O9aUrKXEpqD7d<*sVL#cmW{`5q|Y)nsPch`o0;tSUJ zHPbC)k3FIpCH#I32yQ%6HX*gE;Gd#@CEN@p(i!yc>6)2#w$_>7iTFCc^jkSz+m&I| z#LNCsFQVa~!nkNRzhj=URPo#E$;~*Y=w5j>fwAm0MLZt~>g!2$(+a zd)42^`*+>;Q&G3un-A@xvG4er%oB|{_>S(njpiu2sViiuVN-?*`t*SNYPFq{)?{j> zytWyVV_ui{J4%b8Gb^I(Wn_mI8X8#{vI@ZBr|@Bsu2yit2Jg=l*>BzLja}i?j&E{b zX$M4DP)sK2KdY2QY}Ra~W=E_)t}MXlH5<0=Fp^KZe%$L_e7>AuIsMlc!;v^)2hDo> z`C#!9Y)K6KP$M8rd?<=xIU^kk`6%kjOYkT^c+EHdM|#j#MdTIJ7Ds!91lKOx=tX+|pQdN^lZZUHJ1_nzN1Lg#*|E#m+Zw_PYucM5?=@6eiRw*OM>^F{op_ylBI)Ff>|?YseRTe&qC@k z@_)sFIC)qsC=r4_RqGO5Zd|Ui8t`oHYcChs`c1KhwCD45J_KzeO%d;PW9{O@+EdB@ zBZ^ad_n)ND+YES1!S?kp+NDauLKTq?jBm%TS<3yWyilXWQ#$YRo$*oY zN_-f)P9rP!hGA{*h}@{5=VfXtK+k(w@t; z$NxBxaouS7MYs|QqU3PaIF}$Rw-jtTYifsGxY$&5hIG|}`$d=cdnD<_WCjLWeyji}S?IR0l9T->l;qgwq0 zR76FHHPP-F=r34q(#AfI$l85cLca9a6L8Z0UgVt8;2i`$7mhh?fN3VXCRN5s<0o(k z*VtLZ+Y&KzBVWhP%1Z?QTsBCZT!nO`zG!8|LXxBVyW=CJ4FqY{+#uxm&C#)>^>({w z{f67?Xl{Em7Dxx_*-1UAn2u$dd1XT>tGFjLqM+0te}2-~2J~od7);0yh7(3oy_8+= z5Tjyr9?HBs({_F7>V^J#e#Etm=?2li4O)vy+@}RLLu#as-9uh7^F|&iGIa}?7KMaS z^bmjWEAOo8X-WzWkrSes9%UAuVKoxO5yI|fJn*+?2=#M{IcaxQYYnY`Ak#9z6?4{J6KUc` zgG!Z-%+J@QXTyBeCR#~pE-~AAI)M1yb(h?ftJ7%tgjjnS8p4!Ukr{qf2a@E8HSN5+ zEobvA>RX+ok}xCD2uc@N^Hru~#zDPlEfkv51gdi^JGoaMbziquT>k7z)S&cd+oLq3 zYl}yL5#J4Sr&b8$tO&Z@FmGQHQzTg_+{l!`Qh%5b{*vIMI-2xNS1DbQXnONkGt(8) zN)do(M8EL-HpW3mME|Z4D}AZ|S_$38IGRygd*v2?KK;;Y)6eGIxGeA@cr8ghs=?>0 zr;()RsUX_~R`tc3Kd8hk+PjTIR+?Hk z5xML#YLd}$s^PU4yOGUc14iJSse)jCm!*i#{`@8T`$viST<3N#pC$jGAd~rv`TmK< zX_Uj?VNIHSIgz@`CywXNbCeuk!ihG6V|EMYB+S244s7FGa_iZ{n@#LLjxGnQ?re&O ziuc>`q`FN!5)j>%?z)Wxnsv=-g>)kUvsiM;O8jE9$&DeH4(25O!vLG&4mzb_GwO?2 zsBv8i78L)N7P^$h@BWB;GjzJpif)|s>Qd@K9BQ=J^~)W6Vmks+N;KE3CE!6H#kCmi zXjQ%&1Nhx$~Zaw58lsK{;A@T6oW|t6?u#^ zG{G8T0ILIa{q);z_H;Z5R{lf+xlTs2p($kuAsln%81r_6m2VMs(IurqP^2{p4j694 z!0)_&Nb=vso8;Du+h!$bt1!YNwAkW^lVViiJQlyEV0n$D=TiPFWeSH;7C~`v9Osn* z@|8FH6Fw}1*9i0<4k$XKBqoZAXNoi4vsjDZ$J50)c!zaez4nTm!|w@6#6X$HAsrvB z-nuIn343LBWJCHO$-m9skX-VolLWG7)9E*2_asH`AzmqM%LYvWu{Q`PrgyQ*XA8bXd zBGg$(q1IN2tD^R5$d6u!!i~UOs@SO$Jz7DYEU1_V#CdFhPbGj z3ZJ|(h;HOH+0=s22xrE(jm!W2Ys*U{XZ$}!UIV+D8p-(X?h=j92G9R1AC6zxgr^yW z`TlGK7r=YbD>}3gjS}^rjZ3)96^(y6PgkV2FGwb$V`dLlQE!W{~@ zo!!hGNG1ZXc|S_$bFo2VK3h|A=8W6vLU!x}@8?qnJ=xuQ;ug|WLEXG@ zsMe&;;ZLmA$l~5VBuZNOkA7vAb%&ne4XY$9V$^W(Wqgrj)o1^xi<&|R0L`0_+DZ=? zFwC82RE zO}UrDYp0sWl@Vsb$MlzYRSMf3XAUQB$$&w_MO8sF|(?kqd>)kkw)Od-{;y|u+*0n0Kw$36^%8=nz@EBnFMJ+L!~_m_LH`t zEgxrLB`;F{?7 zL8b9_}JQ58C#CD<#m&!C8J%X#0LKI$f#}1 zfL@LydB(0754*QqUZOWUwZXYmEIMtXXdHDcziAwEI4@X8^ohC7(rvFJNr4n0U*WAx zt&TR*k4U7O1vVMtV_vLQf9>T0(#Wu4X;A~gjQcfy2V~yG^6tckhLHK#Dz8QcW9SVVl2DV z%6xoe`Osa5EKbF(o~IPFDhNut5M|w3_X<9ZRsy2Vi)my+|-`C%wWs z;BsrgHTBNY+)X`p%Z1YNmct0gtrCG;F$t5gN39YpZ#T_gHTQy)u7!5vOLG-@S7KO} zcyxyjucz>hezaaik}g*RhC!kjcpe?PgaX%W!Q95gd4G*u;d|pvvZq~d#e2}5_a%I$ z;4i9Gi#boz-#&=kkP+^ZoUATEr*LG#zHxv3X7nP9RZtf+^=;#DQLMvjF0hlKTfEcQ zxG{yuLe0is3a5x<@;`1mZ)F2NisAQpI1w%|&sA$o_6>JNXx_4-5D)7?N|=J28dX_N zi>>*=pC{Q+l~+NgkR|4$Tpi`)-M-=TZ5wlCi8v#n7|c2Y{wYD~bBZMa2Mo?dxX7L8 zSDctI9m8KWYIODf>$7O{Fz{h?8_DBl(4x;X|LbhS?3jSk zmca8aXmujP^S3N;#Q=*0P|28>H@5Q{L@a{a{q;b-mN0>s^&LS{DHNv&ugq?pz zwbF#9A|hL+BVwyDGe%t0ze;Ho;?3-UBh?|r_}U!gc2Knt#En_=6!F`GiSLwKoEpcX zW)3nGuI-INI}U?7x=)fLC$5oBXeiYf17VJzq*cD+MQ-G6YU9m3!J@%3ubLhB-J{=G zQQP~fsM}Ou*?!KVvNA{dqSrS3FKp(Vs!IIbV=5g+l5&RbF=f(#?es0&Qc#FEKC&s^ zm#Lb^QFzavT~Om8uVnU@i5V(a&Nf7KaaU8#yb~+b%_KJIbxJYv9dh-ue@1 zZYvi3qImBnf`++NulDteY9vE%uE^QAf-sLSM#{x^C%Dk%3Y9!#sNG*(GuMCr)6Wp2 zB+{=S8pN%pxMI?cvC9zEkn0T#5 zd;W9hq9|DsvdF(e4z_kb)Eq+Vt-$w{t1dUru;%+hA8s9!7F|=*%2#1lWSKzuU@tH| zYN-@3Rcc%_ec7JfT$9~X_slQm*15Xc1#MYq^u)Pa)?w9=xOeadJX?Tgv2DjkS!In& zSkQ4JQk>lE7=pk-<0SM1*^dj+U=41@lmX zpw&7({qqN4!$hAWmXSe1Y}nsa+SVP?hUa^*-joeN;O?;5lOW8mPZ}lmR3?*61MN|tDC7wS!P4{S8FAwUj%t6OeQcbvt(AU~h7KjdcRr zUJslKOI*+G4^n4o0XE(89p4|}v^Jv5qqAiDL8BBJTL2_H?S~`ptGZU%42<#t{PpV{ zlP`(U)LstvzIV6I@b5I1K6PG6tl(ZdiqTjRRXOtIuDF%1|II-KuD_$ShGK~cYJ@Bj z5q~`B1P0e6m^fXts7*hOAvZ+@qIEiyt&)>A>tc49v;i-hJwGsj|0EeLS-{2EbO8%Z zJZPG5HCzFi-#}a`YVMFFTZgf%3>2{bsng~5wthFHDX%pZOf^6ENS4-DMtcGjD{Ja;#uw{6OAUPav4H=n<_ zDbu#xyIy*i#T)rY;}^}zIu-wavuwb7yt*p#m|ay`AQUYzGv@h{0zUvOMQWbmzg--i_2n8- zVUv9}d9-Z#hqHQ}X1$nD8Df<|g*>e)?{NF4fQ*&NaVag-6eIfDTSPdTcJD5hMpP#k z>G!cyoDD0h{UxPaT_ z`JH99U;-T8vV*D|v{E{RK4|NWQMh(%%|49|T5g)C6xtafr)@(Ht7z(ru!9oX{wcpS zVDWu>gcnnZP(9jfbhq|Y(ERVH0_d`I%e*^sZ{+a!OtPrJ0Ym?nJCk@+#PiR;L%P%Uob=Xw8deqrksf2p9SG3%o5wR?A04f!Qco}iJ$>J*u zw;{ph600t{bG?2}8B|#y0-obb~3LT?|Pkp{rxs@ix#$I*>D%UO~ zrhwW`hq_VF-r9};NFALiigj``BHH^{$d7g6nPvxBmpdX*KJ4r0_KI@a5Wvn#xQKO~ z92g~NY;-Avi7kj&5vlxl?Oo#{&_8cxxe=!iD8C;e3Dkk!AKBG*U(1cQedH2)NzM6b zjQoW6HLD(7SUJhZAuY?;OcGMi?Ki&^c%Bo2DoCl|bKGPk0*xP~F!bh)FNikIyuttl zop(_kuHY9(-&06H6IEZ@=1XTl=oN7MMb` zv=K6gj!7&lV6{>DXSla>^AVZ=0Y|9Qb4TC8$q|i7+tUjTY;9^rQ{D)Vbtx^HuYKe=d`uDQZ zD+(>S@7d0sV)9n*T@B zdB?N$xNpB!?Om%@RjECyC~B7?wO7Opwf9z=8nrjAP3;5;5?k%9W{9o!9#x~1{?gC) zdHy?I4mtA5x!vc!uj_q%Yul$7EdM)lr5GjS1-gPbYF{2x2R$Av?iRu5PaX6eBHKY3 z8igR1lt!vWU4={C1-0VAW~adF3uCBLAfQ!t9A#tV4$OmGG2NQJvook_0NBID?R39m}im86FNtKStkzl|}A9!1;lL1vpX_wZ($GC#!Y z&%J2JXq?hi8wUvDTFTtx!ruk?*kO1L_S$m1&Q1Kgx)=SO(2ZE*EyVU@OK^xr|9gU2 z@4g#SaS^h;E?Z4*Im;=H7;o8&@1aTyPw!IF$NGbkQuGI#(~k)3y}vlMs_YUl12C(^ zwa2`O`N-=tfWh#`nJTYMq?xCkls5I34o_q2;&tqcSf04ebPSchZy4vTkpVW}%--{= zG#_zlZ%SjM&V{U+@b-LB4vg0iczDsKg$?w^Qc>hP!u^0XGRa9hYg(w*pnBY<$b9&| z!9G3+g&>5kQXZqRoj$PfN18d})>}GX;S;tCAnI^N`c(KcTf&z;oftos?}iSj75arl zI`=Ff?>1rt$ysElb_k5k#34*fLs5Xs{!09 zt92qj;}y5je>k4OX3*j=!SC^DS+%}_GtpHm1^-cj!q4T5S<9sL5@sv?`hV-+D%1Tp zH>Rz2rTPaRN33E-RMSftSeV6-RhluC6}jr$`0vED0QSqa)JxB&U}(F7zJ1?qJb7~| z#CT`?!*W0R*y$AAv*$y4Yvkq4+Ze<_z#D9N==-`|6+;!aNRmM2k&Y*;)q}&-Br7m6 zN&c#4_?i_s{1Z#)tR5R%^RR}0EzbbjDlrn%@h~CVv=myUQegrgHGSTe2uHPxR(xZ1 zwc0p-+>+2ooKW+l5*PhPVd3P3oH!r?QTt+rQ~%kE2-{CVd3x}JnNo@jXDoSD8e)5* zf9>35|Bbf}-q^Bdd{BlS+)*%DdeUU~TZE}vRbiX4M+zUMzTR9aPinp+SG*IWtV(Fz zzKBNE1n43mR}78F*MsY}(spRptB~9(=qTkWsSbR5dUPlC_j9!K1T#KWTZUJjr3dXSq;rI9XkzR$RJQ_zP>~tQUF8=j_|5li4`3 z>dtIuUc%kfDZ=jaP$n@(M#PMnr2Ol>q#Ctqm?30};pGLb_M+PQ^72dm-$#KS34)S) zxbFK&Hr$i!Y|%$0)Nh6~$CXDa1#W6G-aOBH;-x=v-K}!q64>5Q1W{1*QJxx3&Jcw@ zG@~*K=bf>vy?;Kp@^hi^jGHgBrhQyu*6H3lJ}Bsj|9(NyrO=sA{yzKNvYTl7!zV|v z7Uq-t(p%V>2Dlij=#fd4fbI}Qlp!Lu@sU96RA2)N+FB)@N7M}gwVeJ~o*;5``GyHt zb1-=>zhj8-)jN_ZcAdIRHc3diROXHU*KX+vqd|Yr$H7zk`%?mbyoGsbKqpp7B7pQ)3F3}BxgR2 z5-ln|Io>otyUuB17^)ku$ z>b*(i4wNZlN$vN`1$`Kj4}nG?e^PTb><#c5iKzIreRtD-`Reqow=rdLxfPxb<5)fArNyD1SD>8=IuT80TLu6*=^aW6)e&nY-;5H@~tGj zY4H7QtOvtFQ)?YPUJi}TF`fvXi=j#N0mur zMv-8~F}znOfFWW|y$;jO#hDiQycv48rpeZ@D#r%0g?rNOk#!D%imJ?7xw2liBtY+ zZJ6LuiWu*GfK$%kM1NoPIPxzd8zG)ld;^30Qc$11~qlZ5tx9TjG+OP?zt zr24YXRNG`4UoSqL##-}C0dW!BI>2(2lvMFr4MlLHC-pO~*pje9E5L|QyHf5p6{-vm zFrVdU?|#*8#(&{oZV+B&MB1t{qiX`ZGpXlGdd)dYy(EffzMtU)d z^chRw&&gr>)*s*BT$P^wAS_nbKbFz=Y265>t=LpYk-vjEcJm-FG@Yi2yQ)HTEK&K( z-os|s`IaUFOd}A7^%0R(%{K-p&%{znktiWw?h(J+S`4iRAz(e9*8n#xQuHbCwEw5B zXW>fCjpv>DklrLD$3MPnC(mN-Y2hv{x~3(-4BT}?wR|Jv-N3u@rNr?0GF<}ZD{Zub zispyHzst{2K*kF0dxnZh;9hl2+h~JEan*xA0LbFdBzC*F@p+w|XoQtUpU}T-)imQr z13*$z1}XYTmOirXb0XGyR{zlVtrio)0mh31=dyW0OW?l;GKmx|1l=9~rjgG;3*}qU!mttc|F) zGHif){|PCsaDCv)vZ5fzbPEw2^V!`w{cS5MtHajEcT60me9DWsAB#&;^{F)Qj(SHD zvw9qoHi8oIApQk&^bn4l>Bk1oaZG=r#pv~pO$0uyYr)Gx4i&3RR3@uUKHnEH&@57@ zkxgMdq@r>^Y*W1hMRGD$k*rLjY+pkNiS=*7)Zhl}b{SRdkc-vtw+T>5(6s{J0r|HY^f3ZmB9l@(thK zTG(LwgFfgLpfITK)IkF^KmA2l47)KdLtvB}gmsGX7s=jt6FtEI!NATYwVl?BQ@J4R zV0%QZo46yM$e5Yw7zn&-Z*cSgL+M$yzZ~=vxssSN-y}rO$nLHsZ(dxZ2(jIMOEwB; zPNgCZ(O%k8BRxLNT6`_I>%{EP zrsJJ(Dx%V9ZHASes~b72dH^3=?5@h>+H5D^rbCpRYXK`gH5Ya7BMC7y3`hp~tcuBrMTeh|=gD5kY!R>Kng zrNA3sc;E8#bkBFiTAoPIa$bn$e2hd~ee>XE`+ciTv}?ONloApJ97gdGqlbS&vJx`v zx9e0GnG>7!o&hidj(Jr^C4x7I|E5c&oWWLyzETs*XG@P9*|i)H_#|vZS*nD?vkuG` z?goreBMnVd`aj|$g3Q20iLnSuuG){Dst6k^dP{370$9W9XG+hrx}OT51?I7`16Z9@ zri8)Wm&;RYW5-Xj?9sLChZqr_1*_!+F41i)tSxXWJxVXn(#`RCcRtl-=_M%IxwZ&j z>(SptvOBa|j4ha!I>C!LQv^3Uauxob z;9|$0qiLIC0t0qirfTR+ACLrm8Z(H3vbcnKpNYh<{OFbpJR4?)?_N8>rD`gE{b7=s z+j&#wDFFR^^c16pQ&(hm0!S7~U!OD%%r}&r_=G6`s&zW)r@}rq4+q z*}iTE690JuD(<9s`HS@})sQSb@gnim+pgZYeBFZgX0wDLTOkJJ=YZ0>Oy&yNAAP~= zlkN^U+H{rg@m`u7lhJn%>#jd~UyryqA%v}u=XvtI@zQX9a)fQ57?QAIo#Xc@i!0Ia zQNBXOh~sQC#?hEoL8liAhX8%?{yh9A({VJlmJq47z&t^8hVoRQgmnHq{%DDK1|{Zd znO3lPh)R@HmTJQ?69wrggl13z=6DaUYP6Rn<`_2-Y)jI&9_p{}quG|M_IVYBsxaVJ zp)E#K_}1YF7)3#QNZhljFO}|NU0u3dHs537NwMrgdnvTw(h*{Y8CT2_WXAdYkv$A^ z&eb^~TXgz51}9i)b^p%1rP!4J1QpU;F6S2PdBLN&8Pq5<`Lv!1RKEo~5{-y4G_$48 zh~WGNSQCv}=MR7O>!Ds@@Oez)+sy3biPnfno;x{Gfi7Vk>PBGxCZcXZoV(mm{;<;l z_bIEDQ3`j^wnWCGTV{!=(DoLCzV15Y1d&}4&n-m`$Ju3IQmK)J>lYec_XIeV3@^7c za6Fj@o)^Elk<3H7!4ra8y`jYRd4lN4f$y%0L4b2y0teg0D_3Epm%ar~YPo(FNvrox zmb*zwu$ZNdd+ypXA1d<`5r9{&ioI*3Q0eKr^zwJ{2{{JHf__&oKahGAL7I%{!2(#R z;Fc*?31jBPNJ-6&&uR6s)*Z+jaDh(Bq~aj#b$@C9TBznZMo6NE8waC+AJ>-PZs@=N zAP`1^jG^LM&cq<|7SEIk|FdcXFxo+&DZJx{N}e%N7LVVE*nV!6HNO}9wG|Xsx|wiC zbIBO-%zin5P<5r#8boIBak#4f2a8n^$QzDxD2^_SK2F895BjOx_T56N!kiv#`ifmA zd>@%e4LfFtdgcl>T}8nO|Tc9VqW#;Si^dmp&N0n3$ZnZ09P?e+3BR zNQW=0iOucIc-IKkN}TiZ7}0UhD#ucY-Jf|%PvdRq`*%z3J4cdMlo$qDM9?rVdGhh` z+-d1s_@WjXMRd;$ssCALlm&c+ zf)ibHuyx~Ccv#QH){V@>z(*|!39Sp*`AChVm#_oKqT(f8dL8|)u3tNm7w_zFiTyUI zbVO>P$38npl)~O5C_QjA59xGBA)qiDTl*n7putC(V87#jTzj6{@))5|W>BPE{R;ID z1a&!v|Eu}y`P%!_y@fQT_QSQ-wV^34dAgt~+@z_;zm98azdk8|)@r{@oShRJ-0}BS zd9k6EJdW$%Kc!X}tuW}`W<2+R=+`S~ufOO-{iD>EfRQK9RCxi{d|`%}0V=3|#m6Va zkUt(?!FY3b(gzvMM(C@BjF9{z~tZ$+aD3C>s5e zJT7@2Rx+1cHAj$8yR{JJ#X=t6s1Pw43~EQRU3&jIoa$=%6|vS5-_~u=EIIWU`o=F4 zR%H}es9D;GLtNEIt{H+1Na+&5L9l5^62jAoDJt3`>W{$7K!)lHz4n*4G zi+$N|N)WG!qq?dQuC0Oc>OVL>s3f)^#C>C3;z$M!=ddPE_9lLFQLJPmApp{Nc#^Me z@cw6U{?B-BktGG~A1~O#FkhNI-Ym@>n28vm0{|a$iu^2<)dE#Lc}-@yC0@6nHV>*Q z9EHCGU3bgPN`mw--*`X8dzVvI9#Fv-n-RDM$7IY5&WMI zu&kp)lE9!MJ~&GMQ0CW?n{8pOX7{s<96h0b{9jV5DL$N>5@H4+8` z5Hg+81)0Y;m}hEF=FqJO1e!G=G7o(6J=AC)YsbU8vw@JRwOa#7KZkYV5hWb}h<6?j zyU_BGMpZk}+ThT?#)U&UT`m2Y1R(7eZla`^1<T9hO>-N5Y!OS-#=|C#bn+%nT;w#OlyRMQ$m8=P8z!&oGzfYfdOu z)99*9c#!Fa4@5+8)NlE2dO^MOl!e}h;3u!DK5LV~L|olsXq}=vIj6_KwyjyGJXovn z;y)za0TI>uy$Nev1c%h|F(oF`)jDq9;%MT}*=r=5KG|5@#Ehwp$!m=&!oe3Ji6;{; zrj;#CzEbju0Ki|xI(rVndKTD!KO5{T`s^5=@oF`H4rc2c#X$b(c~G_m*h5GYCj77e z;jqLnVoY@(!${CjyMdn>N41Bf3)S@M_$*Eiw9nT$CMAC`|MfgvG%OcEr7y5evz~UJ zV~a)3mNNrdR7z=-ce0#cOc59L&R=bQR|2~49AgNXk_EF?Tc1P5;E&(9{1I4u9}!E) z*GopR`!hRFhB-gtSs`}3XdRxo%2ryGH6;uRP^*&8 zh{&`aHQIn|MPb9EZtoVKCxQj2zoc%qoal=AMca$=CV_8)?@COA49Hn8>&1>Eq^p^q zV8bt=_a()NnxR3rP&4Da{6*p3j$i}9FM&xcotlgNA8lOpkIb{`t?3*xILnPE{u`wfh?s_?mDom74HQIR10o z^JtB=tk4Utq6*xo8Nt#QTdn^896n$re8-dhl<&b4)albc{eHJK_hmihEE&v~7p?wG z8H=cqi+;b~HTkRQ^$h|{8F>vqTK)O!<;NTTop1vfZ+MR{)_HzoD$S308ya*~b3ZO~ zX9AmPJlPj^KMPBNVO|gi)1G`Zsa-{F#4kFDv)ukPmDbv#4@MBs(~31@+HE#NGod#vUFhvIG1FQ@sa6V2ZdN$xs2rX?sE^) zDvW~3Swf*b!Oe@TnE6w#UZ0F2AD;FU6Y(r7Qdq!uAe&FDjYPVVkp|#c(6h8i40WJo z-PP4cJkI#!^3iK$})}9d#cUR_lK~rJV&*%IJ@lDp~F>f~l3y>>PYcqAB6l$*m#ZqA&koy&j&<_Dc&t80!YrIj?`HVxa95 zac8IN2smx-^yyNuzyBJdOt-i$m2WS!gSee zW??U|MvQ@u;YoN_TOs1R>~HlckbK;1C#K7skcgkkgaxGqv(>_4?DK2SFL8MRj;1va zL|Goj6UTx5jx`Kjg&PK)=z9EUcXOAM*mRL7!%-iI$B|I%V&%Gdh>vY((J)dixNj;@ z6cX2poB2C?8^|@Cgc>wW(c9zdDrlr9Y6EgP3-2)H2>RC!8hRn!l}@nPB<-cqtvTxb zI+bEG-MSNZ!D7<(lgsf(!ap+V0YM*9eR^v#CHe=(8SF0LIMp zFMQ`bvZ2H{5FCmMIQ7JWL}^8{0(V>n}QX@tKqLF}^IjfevUxNj?mF7E(Sk@p@JrY!z_ z`4yv*gpWw0M$NcZTn4+RSjM)mai=`cKDlEY#vlCDUL_tUOZaYkDbg0$+YKhl zfq>yIiSnPs*_}HiRu(%b?w_&HA(L@G&K|iPaY}yS1fWkaLx%51F!VfA54^_z2@cel zlGBsqKT6Z$pzDrL@3!}aveTwFUlKi@L_gY>eYWK?!n>VTlAYGE5m8)mW`*KOj!8GvM@*i2 z66^fm;ZRS$?pPQxFi|~~*hPx|iCD}I;TbrWw#MpHujd-#RdMfxOpPVOi`70(-`IDK zCf_dvz!Z{T&~#OA%65Itri zQ|`FU_X&#ml4j`?qN(0*?PQ8mEe|5eD+E}HVwIL}c8~F)RcOz6rGk=DUXBjK+guD7 z86d8|M}u6M)Q27s6dJ~ZOGSLp;({QP{wM;Y$;B)r#H(-lwlD;+!s+%@yDY(FYLJ z413veW+|r$$s3O5Q(qE#IYiw^0)OGY7c0@r=`FFRuw+#ma_A3Bw|5iE!aUZ_$@$we za(tv7uJx!7J~ ziw&T7_;h$aW5&O3$6hI6r8gFI7ABK1yqD+cG!^4E4WGRbt?<#0mIdOw$V?=L*(5)G znxOsT3PBqq?7ywkE%f($lo!C(_?ZeysEU)JEti|I8HO3%2-)=Six~fpxkHzur;WfbctXOl6~oAD!^$mKu&j zO#&hyqL9$}8tu(?5a%q{Gx}=b#SbSf?AP|J`9#C>B0PW$(OBBOSMM?dl&#@1-^H`kA(fY%El(J*lOI1Jdhyx!L;0-)tBK-% zi~{jr$& zLNnef{-3~2DbFDi6QfU!l1;5u2=w2gk5UwuvipUmj;1*ef=m)G*5XAb5trN?e6OIK zd`zBvQA3qJeAOK=@`GLrZ70$$zya$qK3hEwhAuLo<}KR%-Zy=L9==!v56-r%`5o$F zHD}CM9fK_VHjoMHYkS=NmT-suV4p(if3@)K{ix2kChSkLQS`$xiMc4~#p}f821iAM z=vAu$vIG*NYqML8Wj0Urul_rSXufKdoNe^J?}A8ub#lo1Z$WRn*yla-=X-pYcTCgt zB)>GBjhvf(dc>Fp%Rz76|p)jJ&95C_Dy&Oa)y?rLT^?dAyJaHtQm>aB7V3AeP; z@|9SjAN;LD(^P!0&-Mvgq!}H3n*dAX;qS~04AAG35u&1vMTyzL&rzZ{=A(CRHWX!e z%cYI}5>Wc;?~y|MT+{Y{O_Id~RRF{o-+k)kjVrpP>4B6-+IL5A9u~&e(NQQ}0f<|- zMIJ9x=G=JIE2S(kT%?*LTsQ7;>ft!=d@kLG+q);)zYmWMON=y?6nEdv%6wz^^u8dQ z{8X{u+M~wh^X${4mR^<5VwcS?Q3XiBk#veJUK>(CxP5J#n`uIEbU;jxsj6Yvi;`n5 zO%?ZXv}kHWhO7WZgX@b@a5)P^<5v|x~_lRCT3K zZ10Gay>xVjofL2i+O>rl#{NBeX!nbO;zK-9`;4ZUrFF*3j}d+O-V=IS?lXX8le{-9o{k@cre^|(4wYH zIx&B0RhCyrcW{;g0@s*%wR}Z`BtGh$uB)^`6v+wYET^I)G804D8gfc-K+V-DT?JGn zh<`4(HK$z^iP#-l^tseOC>c{mfVp|*!TZ^yRiwRPMi-B76&w7s*r^=?RTWP47#k*tov=os%~^SMzO5gHh+i_PNND!=}(aHTPtQ z-QRI#e6m&s=6B(LxE|y28$#RP%}^NDC@J>ZM{`^Mu;D#bFvLMy{WG8WCyjFEBA z#CGBWYHaYNM)eaQl{R@xLFKU+HU1hQ$gC1+eROGOs6wPv>@JTaiaJ2m|z!r}_ z23tqK8{3Y7bd$$30P%lVw?7dE)%!Qcnk4(c%_xqaKe<)`%@0p!Pp)(6e8arw-_;$x ziO4UyMN!4*r+X)Kef9NRp#2f0GZAB5*WRdZ0m0b)S(azjycb&sczu#hQl6u_KW1yb z!xixl%_x1a7IBjssC3~pQz`U%dE>7_-{75ap{-KhdMC|>OH=J$`>oC;{}u?vwIOv0 zl^}XjO+&)N!q5vOWLHF{EoJuT zGxJajNN9Je9^Z88_wa!hRP5!ajZX~?>B6&pZO`!(HXrVKk_=&zeuvQX|_h2b94>Q3KLF#}^amR*H8KmCmmw7iJVo04n-^l#oSe&Ugu3n$|G>_E$q z;~QnMk2yy{oq+4q5srC9(ATN?jmNs8*X?6)=aPIfLfXZcnSq(FQtof(;$FIM1a!7S zZ~_>r@>GzbPFMT0R^$IVKCkD&Vsmk1yzrZh10}x2U}{faXff_4>q8}H*n9ou6-B-b zDJfc*(m_b@rHFnwf9Bt>rDYacZ3)uS_RI!6DHRRiDO9x&0InBDvuwkiLuJ9SxGQjT z+;*+=`;=5OrX;GeiR=E0Kt6Ft&9{=KlmD4V3%O}Enbp#h%@W(oao$Sjl6C(&OH(i% zr{^6AP(3fO5GNcp-S=w-{RRoht7+r*dDe;5cT9_vuxNI38f?#uuceV`n39=P{xSS- z{@=1*cgtw6j{#`CSzrypf(UaH4L0fgb|4_W#LKJ)0WxwjXdrhB={NYcp{T-{dJ6=d zAxK6QUqHYX;+`wd?jL{e8$nK_1mv*>NY_?m;2m-i9vI?pV`NsRT!eAnZbp!cG`3eU zG~6%Z_htt!w}F8!Z?t%{?|LkGPXW41>09ZHg61u0y7wu4D;ZUhHgkoVmb=r@G6c%; zwnw&Vdo&wgq6ZzYu0%Lw44Lm@kIyacb(!vVt2)#gGS1Gv`i}l>@;6I)aX$t#-cNL5 ze|%}NQ`56PV-Fvn-4}rl84CETmAXEUK(A2jaff~+%%(}X zd&)0TfbUVxNOh7a<~+g3oHMVdGT+aTK_o>XsiKbw{=aD%`080VaaH&J=uhi2>pRGg zJQ2HAw@0s)Dr&S@{a@qzWExJyVxu|&aWDAl%p)I;IPOdI=KpK~y`+%kl2*lJd_lH^ z4PYpv-!60h0^4kV<3{{&^-a zEgf?Ds3%}u8gmU~COd|QbQS`EWqqQ(mu1fML4__oPWWPVA8i-)>RymMp<8gsXQNH* z^5l~*4Lj%?&@k>{-YBij+|a+=Q*|hk;tc=vSWC6~pIp{qS(w}s%CxaSUB@e)^xjE= zZAZEj$ucM0zhAUw(m5rZC~j=rmYe8~vP>%UqK$l6g=ViZ;gt5=pR*8EDI5!mg_tHT z&U`b!?}-X-eEHfDf7J47j08=R(`z>(*2@AU@i6K{KHp632Qt9ZF$uBJgDu{Kn@N+- zE8V=JAS)o@fLvp71cR72=_m>gdq@jT2upxlS`;rb_?!s5L}o{tJReGMwlkkv=rE;l z5+&w~ZQzYiqI>__LElkOzBC!0f7lPqO-`-)YMBuC3^D3{|LNqYl*@=0Qf(6kz)cl3 zv-N6g044YA`!N&G5aT%?7xy{FRd3xJk5fl)StTjbet}HTWDMNAkN{wy6F#3kd}11Y z$RyH=f;buJK0L57Vi z<|F&H5uBcu#-t4V>0B5Qtj_t? zG{I!b(IkZsKfq)zG|0Aqe*JZ4mm=c8MXw)sM4Y4)f37P5rKhQ#`BgEw{LCf7gg9?l zrDgG#cZGy!0n?24KA}`H1OENBH1jfSE!8v=17`-*wM9*Bah2 znlqLAcJRZOh}hr8pj~|!-qU^QoxR$c8yxq~2_0_O_`^x9Bg$7BET%K>c|_E0TT)=W z%&QjiEDmiXd+LTo;PdtHh0`OUdGz<$c-9KI~sRrHoaD&(U2 zMr;1saM44%vMsJGl(=Or*avPWjoN%q(^NQOttZsgUGMTypa$t*zG&En^;+6q`qGb$ z|Gx=?6vyJg|Ky*??1~eea`ZpSZG)jWai|&-VohfIUJL4=!&Zka(ZSQ5N;}!mb+tlA zC%PRZSLu;6J?8K-1M+1GmyUn*la;pO#knLA+VjA+n_x>Tq*`A6>EcO z9jRSmV=9(>9tO#qm4({+U5yKwwKVtHvSi+r15S1+#6!O{k`Flm*mm1Y0|0*xmkGtH zU@%EnYplQT;)E}k+c=;`RHjef!s?zy87YhB#nwJJ@P+TfC0lc$#&oQbf8nyTn?|hC5G;pZ)nNk+S56;e-q)oTUFIZPM-_bB+-U zx$Q(es|d(#RXzzeDtg#Tx8v3SRr7fSF9njvdtjRe{M%2Dw8+xggEH~$TSf#cbxr+kt9r;#ZQ zuegsfS#h3>-oNYCFR{-C!OA9kOfpQUE8N5i(cT3H;g8bK@XPotM1RF&05W4h%X}J| z!L~>&L#H}}xSn-399rd=Er*R_-(WHT-s1mk<)toIt?c0EO6-?bA2^z3st0)3I)e@Q zK=$KuAmIo{EJ#?|Kzma7tXuKCbAR`+i(=QOSM?>0%dem> zbGeAS??)CGIMlw^E%^(q5>Q!Ldbn@PR_h{0@OTR=T>tvs7T*#^e){yu3#m;`D2MnW za$zO~6&oGMD6hnc>l>l)BB3n*y$ciRUO%p{A<_LHvC(b1MeEO3L40CG{*3e(GSTLp zaYWFpv4^CN1NDv^V$r&mOyDhZ|67(;72(D$TVC7g$g_qvlC|ie3z z(p3;dF*S`{+LtRzyh+rDTwPqXCOPMpXo9~nx`RBTQCcDWE9M@E;;V&Lz13ma;#Am0 zv?25;Mx)!Zx7#5+{Fvs1@*KUX%%^d?54Qc1>QjbUmURqVir7)J8{iL+f9boIzduNp z#)Rx5y~e<-efvv@_DTC=4U=oE5y@;BeP;E78&O;}#@ASvCKQ*B1hJ)C{m8f9CaA4= zI6h*ErZwPgmKuN1c7+L_x}=+^!Do`GI&mUL^RzJU3BhF^YV@#L)mH40ZEKA%X6T(f zYe~tksrs*W`cEk|emcSjR(A_PBg{O@hj6X;K38`MJm>l_cr4(q^iKMxG{$$|BV$a5$xi)Er$`Wx#(;L<>T(RvJMm{0;X~;zh{bU4O-o(L?*6nzZY_eDKH1AiCmzjFUxR3mthI`z>up_CL-u2%~ z(No92W7d7dIq?oXw)1-b88$t>>MItuGXWgofT&J(gNw<29oKI!qfw&|Z$qdFRZ4#} z&D4F@+XaRlNENxL8WP`MDXs<#0&94u)YA#MCYdhs^k=(|Y98Azo{iD!>#66KF zismOqH5k>n3{x^bDY&sl_cIp2n~3HhZJ)j8w#1IM|FgiabsW#+r;-NdEol;f$JUAP^y zF(5U3|1x33VvjV`GrlxJpkpEhd1l%5=rU-@J|}pZ`0^Cn)0VTgI@*;(Ali2BGsyEg zfwCUhMyT-R?o>@I?<8Fgc$l_%m#T&L!WG;}bC7CWr=N~RoU~a|)Bf0v5pY6t_^+{> zEiKX-`~BJqLp&!$J|Z}&{LWo;+S)SCqQYxmf$?Ub9xq>N+`Octliv90^D=<$z`TZF zHFxNj))cDz24}x3M?@%M4&In0DyU;mIo;VQ#^t)@r*N*8{&LXNiJgr`*S<}sAl5tZ zl7ms>m$d02KLq_Oqm9lU>C5+<^~F6DCnr6?sn{{1l)|1Ib~)(lwNSa;N8OlnlKbKN z&Ox_u-*NP%cMVpX%rF<8HoU>3^~O@s4PnC-@;Pvj89ko)h1PV@+!UV1;nWbHXUbzu zxl{K#N#o%WwvH387nRR?4LQ)I_w}U-y)b4vyCx0YEXj|dgnT`L3oJJ>92VAXE@dm) z!1TI(lHez7(}^u+AQFZxc1ynMt(Ntsm80yvuH?Sj?;Av$>g`dF_1^0sBC0j-?nA0( zUtvD_&m;K%RPZ^Un&w=TUi}ch`G$DyTlsT#`OxZ8#UoHw4#!3$7;w_`F=OV$2L`D9 zo+IIdH|0VM)N$75f(hKD`hO=}4&N&ERsvszvrQzo8#2w&nH@PYT6xoH@C(LHW zbq}I4g}ssf2PxI;?cO^uJ#s{>G^-9Yt|K&$pJ;^VXt}S3R{2ya9J&~+{n_c~Q$yZb zmSDVZE$EA4p+jcsEaFz=ZmiP6a~ZnX)|@${H#|-W9BM#Sm{$y|WOpiTd*~#o4ydtt zdCKG!kWtql4MuG8h=o@ZicW^{Ht!c0vkOIxikxBO!HM*(Sj_T^h zz}|)`e6(DZ=!ChrJeG%*5NT0v%Kj&@5?HFPH08PI){x1Q@GlfE?3Mm-^y85s-+ zn0;7b>?JojGk89G%7{YQq24@JJNj46Dy<0WGZ+^{4og3pnc3E@sVS3) zVJ>+r(zxXXYs~(!Nt{P@lS1l~nkI#U$XaM+k||FDHpJ5V!Y6Os5R%ZKIRyYkn?l8O zu1vAPbi6gem_n8bu{8aFt|If$Mch@@TQhIUcq7);cKDYA5JBTvJI<l|{c zQ{mjZMVwd`t`S)H9GY%&WX0#2RK@lOhLmma692YA?Kn*U&UVO>ZT(Y^3 z?xsvDj%=h_GF3PBpaFkli4$ALu(L8vB7y3;Gq|`g0aqlD-YaF^#q`htOi?T5TR?Or zYDE7_P2~dKc#d!fPkh~0sWwP%uX)0J@l`KR#?<0&&rXnvqU-mql9aywD~6E}OS8EeMzTc* z^Ut5w!uyTQ3rs2OZL9VW6L-qf)3+>EXJ6aZ3a+nCxR(ZhyogOfDd*TFE7kQ&2}ny7 z8na6q`FfqlRzT6?1yxv!)&-A@lQwn8M3!5l+`K;7z@u?-?ds}7QNLYpe^47-DuZ*i ztDl&A#f&P{KT-h8vdXLeM^3_Gdath2`?-hfay}c!21b~X`_cm3RH<|>+Z8ZnDb=W{ z64!NwHXG3GV$p2MOZmAm_sNJSzpa##Seh;g%|bwY&|UwHGP4XFu)Yv=E!pR_9Tjx_ zi|6I7QFLUE_FG0#obegr{2Cd5u=ZECoqtSWN2{k@>(!lMWcf=oVSVe?Jq*kb^ecU{ zKn{o48$?9~rJUl@#iR{xzaadP_##Dnt$Y{rbhhEgZTSy)r!VK9+bEclwY$%M9KIFn zr>Q2|q)Ko&QnfZSa#}ghWNu2Ml@jz`JA3>v3y48FIP++D#d+jCdTnpGh3N=c!u&aK zG10eyMF|;fx|lG(o?8~TN zYZOz2m|vT-<~1OHGYwxMJlOu9M4?oz#ym0s=b38JivR2B&K8^`tV=yUqb$dyAI@S9 zb{_2bXGo*Pk+0x-`L5-G;z92`EAWubSIG|E$vQc98%?=BGB@5oM1TaBT2-*%8-2HOz*!+dBovGuw$ zef4??kZ$-9p9LPouW4v!#Yhv=KDRf5e{hC`WM_L%nf*)M6E(gdtg6n8c0iFF`*G%~ zgPjp=;vXM4B8xRyA;y!A@uJ2QI^l8e4H}=6M6@Pl@DKL7fLB>(o-m&869s5uQj{iCtIT{g6j>x*TUUh4(P%s>p#4x;yZ zM!J(4rP9IP(Ys2G<}p;nFGqDDig6eO0}ItTnBS4m2mc>UUmext|GqDRgh&Vi(jeW^ z4I%>4-8mY@=tepvrKP(EY;<>bGeEi-9YaC%H{YM{@4ub%oSkiF&-1$P`?|02o*er& z*~ZiArjB8w+1OOB>hV6}vFv_%)qn}VPk5xcsq<;TQL&bD$0v#wZ*TG|q}T`f zEh`FVQPf3>s-u0C)gh;$Oi1PL`Pfrz8fEpgjiIFhE?8B7P68|h6@y*JjKN1+8^a5= z5a0exL~ML?Jhx;8hTi8R_pP?m3)vT59jj?+cKYS^TVx;aV_11e<=*l=VFgAQCUGfvSFD>`ua{v zSuCXl<@Lm|5;U>0eF?~d%T`;Rt=2>TkDDj%9Gpsa3YlGrg|cQ43R1fLsWc zAft|E_#B{$_K6o3gPqt&y#mTQ7hD~Sz`NgY#&8lnGR+Yh(&91rk{_AM{D;b7lMP4a zswS(uhL7NlEX!WjJ%uWD44X$AGg?Wfo%9Qgy>qM>=3V`Mq?nVFK56R(Q4VULv!KV; zPV?lE*?Sjij|Ri^6Zl2p;!V2wNK`h2>~btE#Fe z5Xf&vw(NfwC_W~UOPh>d8ISwDCYutq zG|g!j>*B*|KgU-WtsoXdWPvi)Cvq3n_4>o4D~(n2bAyGpMwH7E%b$HQC!IUZ{B682 z2-Q0p0GW-ADZ;~Py;&L5F!!oCc%a#o@!T3)fzB_?|8bW2G<#==5uw1}fh3(1r6DjG z@Rv$mW%ZPxenmBNQD9V8u=4r7Ee>6~!nVk9|lan^NmvytSLf}KW-XbR^U zdllTqQ&_*h{;e(1?_6-c=7lAY&TPbJ!R_7@U6nyK${@iQaHCpb!6$wt5V|K zyNv~d(}bqF3h{rHsYdIgwMkFo-P4)DrgUQ<8RcS4$bNX^i|hN{37S{&wic@T#*xOA z4g70($l7FX`KT`E(C|dVP%N=z`gEq*U1p>^-;s?JCe+IR!`fVJ9y4*v_wnI9i|brR z&&tW1ZYx~xyq-VgV(oPrA1GOe7$sv8mLD$i>1XXHqdVBwxlp*3qdy1xhIWKi=a!g* zB>j7n6kpxo+wgM3+x`j~?P#q&J6Idi2(Y2HC{Po$Y%2K^jGe$^iOO(<`i#rYc-!A3 z5y5ZS0JudOa_nQB+T6%1sO8x{!ZpL_Wr(1XwrF=$Cm|0%A$ak`zYD-_Orx-1ml*)^ z`sl9(fAf{)POk#uHCExg74B}q0u#Loa0Wgx^4PHJaM;$_9kV$iTxpu(^n{+83}I8- zYNn5$Gq_!65VkGB5D##X5#_}{7AxX#8n22NtNV(cX^A&vFsjF++Dp^}8t%W&YBLx* zwQ=@aL6}pU%nWTj%YGOia=YUb@b=Ke=dDne4FaXV-o<}o7AsSB$4Ln6JQc7CcpnHR*&Hbb9DegTITJI zlUF!ms?glD1UIOUNYR+RK`w$GSbwu7t}(;hkZ`~D@MtGG<6pd0+lhGouR?_*dJ2_X z)NB)$PMs)QK0caz;Oh?LrMP)Nz_17PUGJQOWZpe&l;1@Hf7ga1m=~3T`#0!ct0tK9 z=Od!%!U8On?a}G0u!Hey?F#(GOj;RE-$TfXn^l$5HO|`l?F*jhb;Okl+H%Q!02KJ!)y8lJ z)MHy1*(SvHdl}q@8?!a2F1$~kJ7_8isG5<86@<+CPNK;n{|B+sxd!A%^gVohEVm_P za^pvo&$tvk^`L)-+8|4ikPL;?eNgC2osmgjK*>y3Y{fUoOGOdL_ACd{6@Qwzg{kv} zGNm5aL;yAfn`kD#=u}*M=ho?f->xs8KyU8@cs$M<>76nWXwlScteFY$s*Ka{1&1z_ zXcRmR5JhOIbgW(zr7?cTX}|Sn2gle*?)^O7XT1}GkqR-ZbX|dWDUj}IjkAdwP}bb- zh7!SeeN@~>A)En1rTg5JH3ZBJrTs!s!BZkWIIQs(xGd8__SY)u8}0z=)xv%Fxp{@r zE~!PYf}|*&gQQqyk4`HYGBH>G`gs~MIkW*>lPn^HRsKu)aUGv zPHz?4Y}rhuNnh&0dW-XVXMcDRr$1}ovFXw?9^f=42aWs6-+oqMW!CvThkispf5>^u zHSTbo2v9-Sz5TThT@y&-`b_=zo17$*E_dKK$r+I`>ThZ%>g&1Wia9zo()aQi z+M#Atlvd}%VLV9Z>Q(aqcj_EcAF_8xh02XDF()fl)reBjB@A&!XfZgIhn1ajn^ITj z{A`23?)I`7S3G)?nW`FGL}}Tn)v#5;qh};9cF2=SgsTNZR57AD;AYuMhJ;WoStgN5Cyg@a5XN!Xz z?a<{Yg?j9o(zwNy#&rv%@dd`j#^(voo_GIYuDy(>HiyNFDE&w%f9bU%YRV#MMYCiAFY z{mxnMDl)Qz5#O_4q~bM{lOKnj6$=4UF;I3oMme*1oR4wj^_|!kf7QHyn|C%2xN+=1 zd;92MsM##=rCqgX4fAo;OWZemuY^dkWttTHYULi=(o7(Fo;LY;(EI)pl15WcAjA)W z?f5;Wjj!|O7OH_874vs~LC&vBvgx8z!-_INqZ998o_ul@|21beANhqiOE%oXg+{ua45kW3QNFmXF4F#c&oG+CfD@c_}+Np2V0@uJrzFB9QiM|S~_iC^V_J!o* zbz*0&{hT>-FeOWAH&2!xgDTMOq9$ym&pX zBMMRPV>IujekM?00Lg~nwu@t1Us6Hm($lUt*C^6w2GJ7&I)lRfA}!?4 zzz|-ue@D$dUP9Oc(-2js)LGQ$kMXr;iCEh0D0N;*Eumz2B@zoEnSt$!gc;P5LW-$? zTAjtxn%t5~YFZMIUq|zlMj4;k!NJOG&*|4dmdUHS;pE3Y=Zw2gp)_l|{=eAoHZtcI zHZBw|>_mhV8D4zDxwTJq=U*w(Y>1@dvubvNwq-h4u-BI3ExL+=Ys!bika=uXybw;b zK5qc)fZSKSTxMI4b zrs!!+yAchV>Q^g!K9y>b*o8e~bOv7>3MY6q3_^25qP`j9zn)^ISaRjKI(NC4Sb~ z0lbY54?blZI#*s_B^(naUzde>Wqw+l^RpWyn30qi8vEwooj?Bl?6%7{_rdx0k2`ey zutLxMDqO(xPAs*2^%wz-+tZ!aEHT_NtUrf2U5VY5eshFlw|nM}C6XxraNOf}DWYH| z@o%$!h)j^MaBvIVgTx$GU=qgJ-6@=xPH7Svc>L&yZqI%2UPz6%dU$;{iCl~E?o?zl ziwBtOUNFkk$QLc3chiL z{}ErKdxa}BI1EQs(`mAg${&oWNJ4Jz;AoI8dNV%N);GWihKmzEFnx8yNLdKEoZ{`9 zvIIyXRP{U}n~VeDMvP+Rj%3v(b5b5;nxnQ?!SN7#3|@@IX?axjv4C@bY-T|cQh_0$z0hWnE32nb)w`-!E@a;#74|X~2iAkb zN<)sx`{KIKZ>6>T878nrGwdCJTeXJYvp0wSn z$2^LFGh!UY)9o7>#MA9o-*ftelqpUofL9+08j&p@i-gf{P6FKUM~;)yX%XjiCc&~$ zZ<}IWaYfVBH2X(b)>I5t$ZC(wIKp{`yb+zQNTgIU|uNw)5s+SIc0Cg_<^` z2g$}Y8q_gZ2=+CoyAYnghZ@eb0h1ET>MN zJyKp7IkK|XxA5fZj^i3J-%!UPm8)2yjnA3pfHb(7@s%NA zMa4+Ug1x(+A{2Sc{8gOk{dAVsO{ikNJ+3Wl8Of zl=4j#jD}Q7#G5>LFdEldg97%2F}0lud@4Qt4?>35iH+O=cW7>nmNyop>O`DdlfCu9 zSL}!f5bK=S^$*aq^?8}Yv4*8p#Od6F#iL>-GrPHWZJpc-1 z8PK|2Ar`3lQ__LDt+Vw?VToKNeC%9I2RAhj>tBGfF`%B#WiqFU?zpeq-kAVsF zp5znKen$<)M>tAs6#Vy3#my2z>hII7pnw=MhO?GyQN+Qs5=Z4o55v+VzEWhw!hWiq z?~=KJv#ska6Op^RMk1`vv7oaGunVdFXVRD+C%k2aM(#^`N)Sunz|nRt#RU0xmr{Qg z-M6Y-{r6TQ2%-nF zHriS9I`gl5r~!slR#qeZLS;UG$L7tU>vi?q;?an#4>g1SiX{kl)1_hO%bLPEjg)y! zz!AroB4w2#c0dRsk>q}=#=ScENa*;5@wk=>1d_x})cSDVV;x_aEX9DJDdhs`=BDKMYgjpN3^@?6ka0IM|6OblSirQ;e+S=CrXeN-WRQDF zAH@Dr*!SRiX4%dM>QOxd4YD(=x|Er!J4O#Xu>^Ttp-L@pa{aBKVV97phLFCGS?3fq z<4*f=x;|)KT!x3{_Bsvy6|&Ls7{K=ohb=+&u;x6d@zNk&dC_P=u-)u?E^J~p6Lo5ztU9h;8zbd; z!0(BFM@=IOz1d$|!e1+*NEGwsFv*f^e$qkts+P}@(>uvWeNy>_9BaMqw|%|^8%-2_W}1#b_2lJr|9om zSoWAToeu`f4PfL0laPjU5e-cg?dtIoCI4DFj?^LyJx|_~ zc84+#4_*Tf5-!Y=eLM;s;N#d^Y@I=g;D)Xq?xEc1MeSKn!{K$~&R;|hACekcAHiE% zDHjiubWAeM3w`TzD)9940b@h=PvkA)Gm;uY%#xGc8|d#ZsHxW<`_CFet2aw0?Sr_B z|BD1}kWx&_m#GmOn!mOE<4DqADSCRvKKN72h6Wrv%^lGfRLPO3VqEsZ2%7#FAf<`+ zFB#bHGn37teWA;HXMy2yDrQH=meTS~$x+Qz0d0}KFb;4o!m>`z9r6SkQTiI-cTQM! zxH;U@EW%#{5nt5KdHdL_+MUVhu?F1)%j1M`D94e3Z($ihOR(wMGEOZh6O*v_P7>oH zTZ{YI=DxTJTKem|$0~kJ*0N)t`kZMzqsyN~PY}R)oIy$qt{6hj4^A_Y#BlwjOHy^V zISoShgG;a48{ybB>OZ~Fk)1eN@{sb5b(|+`?=7o9%VG+3l)-wP=03jB$WV=3sK+v( z^0qZnGOCEWl$CIR4YOwE4xC|*7~;(*6HcFjkm{+;D-%Vxp(LMcy%th?O$nJNM;zM$ z5u858%y{i(r*w|#fr~sl%OORjyr@&SIC_#upa>ez{etlPR8?Vz{7R2TmOgTlj2Hqo z(4AUJ)-LE-NX(cdKfkIyj*s!kE&bIl09g8M0X~qqR$01moM}aNbgNTx(1y3S(1rGc zY$QKCi5eFSw+;`nu%FE!E;6h6OH5bH%ml>Xri0F~l`F}L1<0>*- zriTl(#hu2uBOMx{$j6JeFNvXNX;lx3c4Gdr^-6_-6fC1 zY4j<7s9>lY(vZIYVn%bCAla7&=DJEPKJW1eaBBFA_fSA@sSr=M&O4Jqn9FKL5Rh>4 z`24P7lYjf0yy8p9FTt}dIzrmp_mL0%?(R@v+(PdI2Ua?|n-uRao7ies{$dXz>*0`w zVguwJlxSVWbAgMciU1Rchkr+5zVqRPkZepA3h`-WevOhOQH@XZ-HP>%D*dTsV@~D2 z_cofPCkrU0OCuj-IRkON)*(F)jG@t%$AGC(Bfysw+xQ%mCE+j>9pfG7^k>5Zh$UvR zfnjs_UWH{_zh<&#;X`uuxb?n{s&Yg6xaukO62c~ZBLEhBi_|qx3K>XlzMHPfRb2O*t67j>f6H(_WPa+FeXu?uGF%|F z57%uAF#Ek&=8#oMXLUcBd{$Ol<0y}~aN>lb7}2W25!3iNcbYr!M^&m$ed+XDMRaR- zI6-3b>{&y@{_N$LU?mCo_9qT5ZUApLZMAs5IJhB{7q^8J`5zjK3%@?RTcQ4jn=7Eb z^!@T@5U0;|o7MO8J^B{-Zv%^X&N-@_0UxHhG8L4y+o%9M2hsalKbMB^EWyPi7r2$KjJ;glum-n!;}yIC{cCf%pO`vUzh2ju*g--oY{pNfLCn3f&JSt7xre%vIpt0) ztVW8zn+2^Se>f4s+|;ViLB1I&C&pfnCfJc%8XzzOg1~xx!E=R}RX(wqxX%{vE|cmB zTO}!T3y$f4+0M>-t!Lu;Pb`)GQ*|%qICTR195&^}mvjA(XJr(mxLtGI7gQe>?f$5#X%Oo-QgC8uHbkxz5sqFe*j4==w@_gJ-K6jl0#1`>n{0_g8D^(^ zrZz3oGAx2QuaD6>z(eeLBH}33e)A||OV)y_n$aMX5lbFKk-2v8tshXZT*VGxLvnDO zJbMe*oWfp=pY*7gtXzO``5xZ_v@!1AKH|j8sP6k zdQ3)cQoqtZn#&tx8d!&?T7!2(@9eW2U&0FEaPb#?p$$rO9-fH_w(ilt_~OQh|3n=| zs-LNoHn*`BsfH5iz6h7q;x*NzVSfo+sEz2&?`qa!#&z`{RaXx$YK2hT7H{P|e}=8> zno>L&)qiC!ST0~j9@UT2hn@@5&8zOMQ~DeYC3}CYwsXw0_-rU76YJZ9WPo5l^@q)N z@711F&plu}nEiMzlhsao8Yk}2y`J)|_N2+eih@BSDTcE6V&|HfV9FZn5fjgWfc}V3 zho)+i&rh=dP&L34Bbzg4rQw%?P@?szyV3E0(iR8GvYceO*6eVxR5w;oena5 z#Hso6!AIrBFXBuk^$r)8veXAhaV3Yf@l-QcD)q7)ZHw#8DN{=AIduNxPvqZLD2jNi8uA#Vlj-L) z*|-HL7t8M0VV@Qm7m0g2E;tAUZYl>$7@o@FzFvI4IQ!| zhl#eNT2Avh+e?n>{y)R16sB(#M7b^74j+DUCM}}#{`CtVR(EmVZ~3-Sy~#5^d_kEO8KpI>H{vwqLAYC{lm*Jj{Wg}WWZ1w_{umu0f#WF|_mS!T{m&1o zdVA0*EOw`+O@t-9KL@-W5xN^(g$=T$88aLEKLW2E&1n!**$sb@A(U}S#CiPJ2d5j0 z1g~|!`4)C!N^Ryia#13VO|knA2F0T@e;N9cJftRxfH(Se(h}e1vF&TR=Qiw(TVqPz z_!#v4BPm?bE5L^JARPqko|_~oYIumGvGvkF@rVrskVy$j%ZBX`<^C+hMfE z&m~icmUK~MUl#99jKg`J5t;j&(-H%DmEwDjCa=`HjAk%r|DhEQ2(dtPk83Hu{fhAb zY3r%BF283DosDs;M72PxC-(4yTc+NVHxUEy{521)E|v&CJxsfgrZ8;AFV z=MJ9Gh)IR>{*)llZ`1nw*^>I>cE>7%+f%3eE1)7|R*fAC3b zOLU1~(2m`jPRKX~V_BHlYFaYx3^V^`s^fTo3!lS2zg9<^69y@S9$3IFJJw0MS zXM6VoJ@bbvX!p+l1GM%Mmtpl={jBd%>$4Ip^Z>jVtkML3jCBKd<#M=1$+-@+B|fZf zF#DjiPpZOEHMK&GvHYUvgMaK<|G6oXaML9ttv&muVn~1CkVaY<<|F0%M*TJ=J5eaL zw;ji>IONi*U<}zcUzC*0$HFib0TYYq#P@T!9b3d*?6)u5%9V40atXAe&P99ykfg$ii@6&!=WO_Eu+CKE{;R7##5; zoROUPgN4RPa%YhOJnYH;kOk=~nB?jwrN7zAL~lIe@PDpCE_BJ)2bOI+(IA~RiSPw7=D_KqbFuEjZTzkT8q7Ccl9j} zZ9%}vMMu%bTI1n1F0o8Qz1nz|_5@_N`;Dt&fe7d(XR^R6VnTxRR+gmWJ-aNvl4etr39h_TKVrs?%Gf-e!68{7cY z#hlJL;9voGhhM(jC|tk5@PbZ6wN6!x#_NSWz3rm~zExkZVBpE+m8lICp_fy|%Q zc?CT@+)ut~6@%tDilhbq?rfSEAPIHr9F4tC?yW~^7+~ebqBl~2l&Mo=O_yagnyzvd zGViQTAZvh6eL`q#yRb=7mT&SxE$(M%g|du}h{LZ|O+FpGU@lQQdH_JTkin&-9kct8U(NZPgDN&)LaY<{CeA=eHu zhwtdKgy(KKcy)C;nf5U;ADy&GywybfdwU?Q)R15Id0Q?puz)8LbpD<~$1!2j2%gW^ z<2UH4Cy%PM(Vd_FEfP%lM#Y3|^;lSODLCfq6DM2zW@bSX{I{bQX=oKeHZH4wC47|_ z;PivElBIdfJ%dg6HQBNY34M;FluelN>C&@*(6!2B(Bk-CfQ}lOPKWze{Lc>Dom0xm z+Rw1HV;YGRnOJRA3)ZGUVnG+Q8zS`_B`k=d4MUheb?;As9mO&{jG9gx-^?FUhU-zg z-_+cu8ZvIqx@4AG`#Dx7Ix)b8GZMUJ7Zxf_tJ^+%wmk}jkE)#vCtE*X!}HX`8k{bj(d);z8&CelU+_Wo&l>W8;#VDpdkbR7ucT%B~e zfI75)ek7Qn{O%1~FCc-4;pp2oHYIWeuOyu^jnJz-%X2Ve%w2IpDv#SUppH&2B`-Le z7BD*|q!b%NEq3h{*K#OI{JiVU6G))hSxIC^@!J~ek6IdR|C&UD`7lV{R=!4pQcMWY z+r+pR?=7E8#hbrtYaf1Jw=BLw?|Qk$m}W<6w}5g%!+oNu)OKz(a-y7l*X;5L+OITJ zZVha^%8+{C=>_tv82EKau_d$gSsxo*f5nwAK?oFzIpE+>sFsJ6RX@+-TH`7TL1{XI ze%(;r1i87@uIyqp*Z*=<076@2#lt5T@T{l3(pf9Tos;PblSmh!wR&qj#uHmkw}IC9 z#E$C}RtD#t#}cdQgPe5(oRN5e-8}*>|T)6Jp37 z{=~Odip{eKhnJ7WP(Eyn$Dw4$JZP{s_FeJ>V4udtUqH;5buz+V$-hcxjrFvN#b2=z z(80k`xPjPrmEFJ(AzKqsGHFyW7$4H8ZzuBkn#O!SD3N6>22I z+0IeRFxn)zZ>#?K2zy`2fq`wN~uL=htzU;sQTH@~2L!^$l$UeI|!$ zV!lieVY0=1%Echh@xKh#cEU$KR>J8yvHj=Ruynze=YU1>Qw!FLrV~QF<;j;= z89?)a9#>=xlasu33aRMN_#{T0MnN@Gz0PY<2r5Uj=&08U8iBnEe;PJidUo)T(%ZnE z?ebMs(Xor-Du?iCXULPUu0fwIlp95(Vk!KJto+%F*RncU=L!LN_&N=9-dBZYR;gEG ziqX}rIBFn5Oyx19V&NXw6~dUOS?hYHi_;(VUeJ^r(R9c~So&FQt)9I1I)I3|VHZgSF z*Rw=QnaeezE1qvrSZq$kjMcQwCEdI%`jqi%k&$(Yp&d;7D&+&0GK9d$-tmPZGGnFz zS{z2|&_+GxX&1F8vg=g-b`v5rG}xbTKAg8OSV;AO#|_o?Lgkp1n^Z2tAWMgv*NF4M7-zTX4Pc* z!o=vSalSdfi`KY!W7xZxvWV^mRt|7m;m_v4C)3ZM-R~<>)&kJXF^&N)i@tXSsvd!`o&D z>DOMFjE8uRdZUjPxvH&xFr4u@jdu|F*otqcPgF$=d~7nsY%5=7j*Tzh3o1D)ZPQw% z5hIw~K^3o@9LGr-J+irb(nM8VYsrC(xC}@{2>b*aMBY{6bo44>JjOznzdz(Q7e6Ni z9d)d86ZV~hMe~}{Igv{MWymw^C9b6Q$GKeQd&$`bQRFl5a}Am}nu*U?5=m$M8=UPylh#h!W+1xktj?%DO)xn z$p6#tTmrEHVO9cQe{6MHkXIR^G*mEg+-WGCnu$nufenjf9N{1B<7j*!a=KJf)BaDW z9IB|!v09#sn&92^k7xvFT$Rdupk%nJ7i_e=?K3CpM&{w{Op*1V0H4zj)7G2j4#v=; zIhUtTTSNc9wg?XebYlOi)r1PT8&>LlURz3OBx#!*tK3a(lJK?I9TYU<;|lzlw%OROq_XZ z6;C6GV{`8GT*zy4`nrcBrQ{;V$yV z4yddQh0|}5RIc6cNamPw7_Jt{Ly-}HaA=?%CfZ|Nwn8IoNtEqhUj89d3}fa#TRi22 z^|#fOidJsOK9g>DU!d#MJ13KJXkvfO;n;5C+HWuU` zeO%cCzlZar{J7*TywrhXW)!!_+_sW$d>k>DQQKgUM zMu@vC=NE+zp_`w6Uze-#sK*=$_@HfPK{#IA$I4x6Z=YFsrEKn9?#fFC0~KNy%U^W= zq7=s&+ni~o4XGkZ=CEMRkhBL1WUOjsMg$v_s0Ez;YWY>uo;y;u-Z&~0=Q21rhxJ6d zDFV^rNRt@SB76Ujl!ES1sz-)9-hQ#siQ=+(b$7Rr(R{wqb0aD06bcK<(KWB~nCtT? zXnEJwRg+w>`f0Gu4|UGhd`IMCYE=PRR_b`O=10A?YUTR5057N(v)C-Ng{t7xNw@vd zWsmrJ&~RYmXTDPzH%;8c(P0hQO1YJWNVQ<-zMxAH@20nW6xWA zi6l{XifFO6;NHJ?K=mS7V{M7Qf8U0tVKNRNf3d7Sr8UMnmGuUgY-QW(20F?n?F`lC zIaH!!Z(29#qo~zRs0BVbg6Lu10 zU9IRKkF+k|fK1$~)N}Wjgyx^>K8LU?Q|9Oa@wVmX<25( zetot`%C9Wj)1u`3&as7muSZa|<7GPM{C3^?V_?90WfG&9e=XSkT+kb%sw^CFk~Ac< z!9!1<;NWEqso#wE$_GX0`%rJje0oH+zM?TlOQ}PKgvcB|qPNg_3V`?NVojQENisjX zE#OK}x-Bk{A*3I_EOVlqA? zil4AHzuj}E9%^O1D^#{AU{U$_nE8{VN>rX~cVrJusTd_WDGSBM_V4ieLYXq&HVPy6 z-yj9D9*kA3*=L=^MBf9Kn97ryzNj=|Na%35YhflkuHI$@c1fRKm{Py*rqN*eYL~^A z{rOFi{ROPAT*!%|st!g!7zC+AAr=i)0!1W&m;&>O-%D!4D1MMn&e^e0H$e1`67HUK zMjB z3c&G;k|feOSv@_ixmH6c;=@!cc%-G$L%?B)Y6Mgzz;=%xi1hZbiU1w*=vbhvl?C8n zr!7|xadeh!y)i2cz` zXQ?fwMQ00=JJo~CxM`VZ z#dgqZ@Y}Ra`PIlp$+GrjQXiHyjs0l*2f(yjxJM^19< z;|`fF@BEO3Y%|0&Wf4s{8nz(iP7k&Xzj0N7#}?rn!BWe>pVyf!12aCe+U6#M6vVhj zx=;yXu;l3-nx4nj{aftt2U<59ThEc2pT!vBV{r}sr{Y7Iv}`C#1|N}`RzKM=0OVUp zMxZOcOVuv9s!it4e7{&sA|>_h}94>wNqL-*CxNsGrd`g6`@3I^P0WZXwZOw}!yd_(4W-xh?mz;U7~)ZxPs-wdgGH5iOc+)e+jimov2upT!A zRv0h$h-g91H>p~{H10?b8KYSa<2zI90i#lY`CcB$gBC~DkE02x{Iwtj&R|7l@@SODTwMvyB7AM|gzaMWgvdFSS2WRMOkztB1 zHD!F-Cn_KAee{p>ajB2g_wyZ1`s*9O+JJqz|c{rRX?=^3|C{GSe~peC;-5ev+_%K_?&mb8a5acE99HgbPaHLO6$ zn(t<2VRDYiM}8yHBy{D+=dp$BAXpUoI&F$oG3burHQ)&6rjKM*kDE&b68F*Rig(Cf zHD*0-u{6KiFh@B~*czIUXW_E*fl^sMxZ(ZUA(aKKxiJuFNNdk_p|khO!Mjaks+7Qi zN#IzvOd%>>+G^x799JjeG^2-+LRT$x*)r?S0_$<}69C_SS>izM{H3Qzx$Vi^{7Sxa~XwuK&HOGqbuNAlgoQ)~tMJQL^aNcJhzsm1F(SoM^ zs;0#q4MHP+IE5P=uZrBPx(T4rIfhlOxZ6uC{^F*??aHCPG8wyc-}n(W5S94LwqzbyP$p1U3AM$j`f+e?4k}=~{PMZlQMrA?&S6(|t5>2~gYB|*cY#4n>QWOgv}dh)<1wt^ z-g56?m(Tk*@0lqferK1Az#AvHGT-X78 zmkp5<2+!1eV~>##q9#_piY-dJMvP;LA@iT&OS#@6iY*~JFFc&dq^+U8?pnwu%+l`T zDj)3`iQ$4H|6UW$rQuz0ZvYh@`#K3nTztm9*vVVo?!u(|!VDlDBl%$PwhC!_#|Bcx zz8@ARIF>nDutwm2sg~@9fkjG zOG5G6xj}HBnRdXPL*{BMo-5uEg)~EXO!01Yze0DQ6JI>^5)nujuMC{HSe3rje9f3` zHB92$^l~6PJyRnu<27iz#VcN4J%2Syvz#|6WS?lJ7CpNsL>n61Fs>IDtzv)+`qI&0 zJVe#16234jz(e8hpzOXH)g!QQUuI`>T(y!3E6_uCgQP~6?!y+EP3TageX zxLa{|C=`ccZ7J@a;9A_>gHwtJcPVi5et-8rCNnV1WOn!2v*&ycEz$kntE3O1BVg{g z|J=T7^;zcs%&fQGNGl2&=J0}4sVul^yvr0Hs$!!xL=6ot;OKc*u)YM5P^WtDL)I^ax8k&#|D+`aiMw=G#|6D;?+=hIAWM$*w}Z z`DYDyV)wXfDymZzl!f(q;neD_aKxgP^LvW(mT(A3{BjBS9le10g8>dn!R^U zuTMAfnFWcnL)^8A@)Es55nPs>t@06GF`~`wIEFD@0+dzAB>qH|k#ELc;&e8{8tmb` z^6CrIbtyO0_RmnhwIy}f_qan>H#u(g{>3)ruI(w4nYre3#IEOb z@zFqvYsZ26BH7yjXUyKfo#%F*AS%;}%+M#}A8^0Mp<%v+Y2`u$b%Nm#@CH!Y`Zoc}|@wyhR_ zw<4+e^hIPI`x+@k^rxiPUewAGu3$;K4V>W^j3q5#nwAZbI1b{8DC@#hc>S#T2p8hB zqtvwrIws@B$AlV_1(IWg@yogc@I(c-z4mf9Jwl>8QP_vWx> zeqAGXW*~`5M48q{5!&XQ1B(o_duFVhXJ)+3)cE@(Sv5B=ufpv`!#^SeTSK19LF|!X z2}q-!|MK-$?7%EaCt0aBngkr4W=}Bq3jEKX(lki{)RrOjqOsLMzjZCok3466CwnWj z)}FMWQ0)ON==mqF!t2PnDC4)qBZzdJ<2Qv6(N9(Vfl;QR=sYoPkA9i*s#ACQ<;ZMQ zr7;&GnN(7}lI2-f)D3`p45S3qP%E=la`|pfP@y0r^FOG=rb8wEf{J6v2Mg ztu9W0)c!V2@N1~DibR{*iD7P(mSsf%2}V7BI_mUYMiwH`s@cX}j+knQcygQ|ShS3= z+pBuW?S`k4FO+^k%QiGI?Sxlzz{W#8u%@&;T+%zY&p|?LH^ynxdvk;9G_KFN(ZDd1 zL6oG3X?+`0)_#f)@IU&O;t=l3V2H85-%is^oBQ=nyzoZrw9VC_h0)1+!QaGoj3=#! zSZ5T?6Hyj^vfM8}W1VYehiaIV*eflB2*DDonW=KReS@=N$G=1M2DXu?D#`#9S#Suw z*T(GEW#o}M?8*OvM_q8bjLvH%c6@2$1Kv!S@5+I};;4$S^D%fu)}6*uy@|K`5ihPt zFVpT_k1|Ywv->xwAPTi9M!dB@=FtV*aaJcGsLFRtx=kz z60164(1{DMG#K+HY~r@Qz8%S49)7p}BD0?S;BxCtM8WpQUK!TDoQpa8lP<0ZL{|5C z@6*y+0jkaF1;{6q~)pe!+{_GF|uDMIw86!aD94Avr zE$e-dhSWrnpC`@LooX-sMDjg zDIo|JR2tlUF`2C`Hfp{b#3CVz4!H)Ru2%QC48pzebE7k!f;BqC@0?29*631?>%ADS z>LyqmhJ_mG?Pk+3syXp8sfysnNL#b@$EvmKIpwXFF0rVwaq3=tmkiQRP`T*x+ z-t2jZq-!eb@t+**k2O#ITr6dUR8*%1$A)9*Ux9z$c>$WR{%H45%x9T#uGJ2P2tE5nfsGND~@ zePD4|pk&w^++@6>_7D8LgC6(pcuSbLp!aD6kN9DGq}?+4zqYi1=4a*r9;&yX4frHD zA8-ioww^8uzbk4~A-y&!h<+i3>$!McDK4^1v4iO2&u>cWs!mCl@E_5dEy<;w94^Xfb(*Ez-^*Tor zQJ8!VOV@qInRyX7?URz;5LMjIWNagc;1wo28N;85 zXIz%eUawA>w44HGjHM?=wOG}RSVa2|xh2@g)kusC@@RNXHopS-d(CkyL3j(_^-X~j zSJZykn7Mi_{L@~2nJ=oqcGQG#2VWMS;ORO>GKN{-;=mGb z_pR+njv(Lmz7H!N{OJ#P@bF$RJjB4pt(^Czo0Lb@@v+8zQ;-2|6|u zhwo-yv`{DUaTdQgOufqxEGUw_(AK=(n7PpjW3NByk#_!Kx-*aOO!ZIwv~}M@vojqy zo=7CN3%?|a?)@<+o=QzyGuVTEwd4eo>HZCw$X2o{2?{k9W@>#X%?`kBXYq`*zoXO5#`u=-4}S^_T64W>Gi zoEzYUIo^wS@M4@>?f0skMV-1%rurVk$MQokcUj_%!2&?DCU#MJlieL@+@Cw355ol? zwB^+z!xnWzb`Si}g=2sYwlMRTkrNc+unjFi9*4e7@ccGg3^@x9aEpZ<|Sj0}1QOp#7mT{^Z1X{R6D3?J>( z5#oqgq@HD+C`!M@u#SJ;OHe|O zJn^AR1?SN)E_LrFwV_ROwhu7DtqVsL1y+@5gSy}jR89cm85vfn9>g|uodm*IUBh2< z*X~XEty_F}Vu4T&)ZreQ-kTniDBGI%>w@U>GV#en&$m!t*jb<_Gu@ST*jT=V0ty~+ zRgp>!P(SvwPyp)PSS37d2-2^0MyUKb0DsH)bON7R{&P#AE!rdzXZi2WQ}bn}iIMzo z*DJi49d&^tHu&KCo^^FwW5Q-F5`;4 zU1Y3>)*r(UUZ<9J-Je)+5E`KR7BbR=60F+zEbs>05!A}Ka(K+qVhD^Lschn?)~J)b z?L0W*w|UyCJfQE`PVVPrfn!K~m#gBrxW zG7K~Di!aE2AOs8CAUy5F>xN&$N_W$q3&D_EgtfFyGfqVm%E9f>b@uH;(UW~nSwSf` z)UuVjSO(7eaRSxD75)Px76u{regotcC$KjI?84E?<$s;Xr4J9Js%Z0qzZB2KqQeCO zkN?n_>7LSPN?r+`T0g~jp;S5E3TRT#WofTIIAq`b6W>0TT99Yzu~D z8&rzj7f`@IRbn^fQKq+6J4Fw{k4oq}xbE`9wTNYiDPZBR2C3I9nW+mhV~xxl4Hz#< zi|!NUQUq!K)!gmGw_pUWL7ad!E5Wr8ieq!ETL>zJ(9Xm6R2$J-bn_cY8R-6g{yZf` zRh$rDf>vm}TSkAvY)QgHgP?Bmd)OoNZpB*sZ(M46BkVH)wAf_3b?Pm~+zNAEtsQLs zR(aVQdqg6!&e}HcrG-8t)(jDgeX!mb@myI(ePXzKK9zFQ* zv`tsAN{N;t8_sw&a%;T**P7Q|;YGHvqDwNas+-lPP;8J3@;&U{Yb(k=7K-UK+}oX$ zKEa^=l;8&n;v82Mq%c<>R}KrS9QWbdC*#II8!%QRspPXI)A_hc>ihXGPTSI3Pep+* z)m5>LC$K~5ikJj^pavQ-oS*86>(W*9YrkG$kDEwwd}`+<6<`$pVnlgoRC!!?kT*6) zpRgET}x@L=(;4S#;UTG6`TV$6Hb&$E&K3)K+d-RdHQ~g6@ zkT(1&8;OLr=1>ZAvwq{>)x0&8lJrsuS45q&d99dK{r42?#1aQ*tc{NcTL(Iso~}-_ z^cJOzbtk5^Pdp#^f>EN)XhN#1cMf*(l7g&^?&2YOy+t$!S{LJwH*k*{V-@V3I&Xj- zTW0sLv_s>YV;$2u<6AXhV%7v8)@)79xJ0`K~tSYQW~d#NP$ze4%pNs;cA*Hz0D57+tct+>k` zlk%o*w96HNgj&&c8!LVHLdJ>yJa$`SVp+YC5(BYdwjA_gdlWbWjN^NqL7+M7iNN5u ziQkaZPe>4h9%}QQ>d#E)$)Z)P=DFRcL);``6>y~?A6a)p&4L3H+8Hgu%*+jk(-Q|& zwfwMbFEXjZ*yw>f21@q0fAjWEDph*i?RFejq9&A6bgWfP!Z^Gz%7A2Uxa$!=uOu z_zm2e~&)9a`q(xNCb{7IK3^{xQX_i07CkELHFPtnH!of{RT7ry9jN8%2@ z5oBqF_f+5?GhjHv@ggo%-s|%AF{K%DTLgSUGofh5lZQ()qH6 zNB;O#A;W>8OTo(KMPH1Ou>|ivMD$faGJ6K=N*oraBcBTo25Ta?#AGT11N2GP%>`Ck z2B*?KP)@Ibj#08Yd5KVgY(CG>AKdRxAxHyoj?RDM!I(}C=Il2(icL6Uqfv4{EpLIP zVGJ|JCi!UXoYiQwoM*Jupu$RT1Q)Tgx-U)lG}eoR&aCl~UHXHCty}4S$-xit=~kdEwiS&g<5|r?3^{Hgq69tq4Pd|o!P}_+TZ2_&XRqiQUV;kR#{k~e z5$}ywO!ad#bOIl(9Umo|aCWU@RkW7z7^Hn#^R9fYJxfe|65yVn{)oD>w_Kz!5;I%9 z1DO9r0J&g%S>VFGS*{T%LC`fgzl00Ym2fTxAY8=U`=tWB9^3b^=6@A+2)x_M3u{g{ ztb()K1mB796^{FoaoP~3PYmj=1g2nrTaY%G?jfmEt&$W!0lUlpqm-pH1EF}Dv?}~# zhZ*nk+S0=*k5e1(ENTm`;)Df=In-g7MYZ%5aAP}8m$vn6)LrapVY$KTx~aN1;uF_8 zttsx?xbWAQQ=~x*J8CE#ON$tTQZTl3zrKM%dCLdj?N#XrO0iIn%;(F`c&8xp)C|(B zN?aSDZt?yXkmwy*UB&p35~#n%5_F49!8`>os;xN37O-GAUeFD%B>Rw!U!w5eBaL-j zR2^T69F+fCb`6xms)tzzabmwV2X$eU4N4PyTnr(w0+rXYH)$Za0tw3B_Yu z?u0!=dy0U>a?bt$q|@B@Wh&oSLUr1<()l5}K|!82X9k}R&)j;eF^fNp%h~*`L@;z! z24o4&_HvInMG7E1Yi#tE)S%|@-AEYEUk#wIlGcWU~;tdu4h-!7Hm5cQ`I2oImfyD z5d9ws8c4+*n5XFVmq=@*Dcvlhj|*RtF6`07&%?3}>ElE@tV63c)MbAr>aq zGAlfQh<-J`A-NROmWipf!wwd33#()W?ZQ0aO@|NAm~g4^Hmm_ik)#tTagvIoE6t9U z|9ovM|IF3$xDgkvVx7q@ti~tscH zb)^#Sj(!2}la8HkwLbR7inI(k$T~>WMTQ9;1N5Ie;w4@_`DB){G_zoW{yeFcwk!1zd8s6sxI8h!TavTpc5 zK{Xp2-JprODi|1~DUkrNLRV-e=E%rvOMoV${o(C4SB zPH2})p%gG~K4Pbg-b4%!f4D|FevFVgn$l3N-_nFLdZ?Z9N@XL+Z`2cIe8rDUD$BxO zLR)F(LQ-)RubL?eI!4=Ze!v-dCrS33>2Gu@@cO24Ep_##6;y&YlYt?Hue-!Q>K}Hc ztI>D&a!9a0 zci@-E2$-E_sSHc^RxAp;`_}-Rc{4HPt3EPuq2erC{3o{DzciPh_jCr+9zjHB`Fes2P@|> zU`LuyT6M2W!rhX&bbFdXM127UX~X7M%}^xr&<8~*yZN{CIvMqN87vOSTU0ELE{Ecq z*CUIhO77|*y%KOKb2dH~a?$_*&c@yS=+r`3Ab2WalF=Ds!~!3bZezxsynxV)-w9s`n;*$-@gG2eZ+ z0{MidOYH5~oG+5zz5@@@18ljAdDrI1w1-9NgGvL(#{3K_ipWdcH5%C0{Bc%fz4X4T zT743s&sbopGd5&ACJfo`9Ww%Ed0mlzHENr4rBbA=qNsWE)X19f=YVuZ^4Cn;3ptFo z+0$&!^7n&p71BFW$!R>m=PpTt-t8V_4UuJifsEA^)1Slbsx%x6Co9!%81Pi_%U}6* zf`ta<%djYA0g?z93(jYO}n%8HW6}(Nosm?^zDJ|Qh#~iKs_-Tsv6DHnY6=H)2u3VvLIZIeJmEj<@cA{BU9_{I z1zg_z%Ip>JDf>szhr$_LI*rdD!2uN#7!6TYL`Fl3jWa*SwA*C-lc|Y*=Diw{X4=W8 zObwo`SCeR-i!#{ntVEAv3d+Z?P~#HaI84)s4fPClEPpD(+6j|7C&XCMouJsU3?dH4 z4v7*6E#c|ePdz&kwweJgzrZdX+n~E*3ImMIlPu!jL@F)fC9|%Jp<%)~;xHZimh&*- zbna3~%c`h|GvKhK9UbP_PUmG#I1mH_070u8ofSi?E>mfoGT?L!Ju+58 zB5p5109W+D%UV`SLbrR!kr7wVj)Y0tM+c~5L9Z7NaJiSM74{?9i`hHq2ZG)dl!eRC z2G=3fAxMR0l|O=aIzyE!xAD)R#lpLWC&R#5X|y1#hTAF+2y9Zhv3SRt3-B4H*<$b) zm%&`$1t#13b9#Df;kW&t6|#Xi`gChB>Kb~*oKyqr|Kj}YjWIugJ<5>UlZ>EQi|QCv ztTKuwYw*}i`|anChc(H4ZNFJBf-%{`msBh_bMlDayfurEWN4TRg*rP`3aPPjJoE|R z-lBSC;b#!4qBY#g#{v3&oWK8J0#pxjDBM(2>x5I!pKY*9mn8w!@WLCd#`W=djN~s9 zX&en_22~O+sVSV#ZIN%<9^Ya$66UE!+%BU_?9M3KZ5Pn@lRpxJqlGu}(5C_qdw+TB z*$uNp0}wgTuSUw2Ei8U7V+Sc7 zsWU#p6*YD*wDw!V8QI#xD_2qT&*H`q@ZAjIA}BYg3T*y#mip{;WT~Hf$JTaZCUBr4 ze%Fz-a_q*aEps-3?oUZy#ar@Q2M%R)+cr2AI)`#b#UcZ($Bj-J5mL$Ur3m@=@d@QX1i3TAJy9yC8;@pnK0 zThq6jlaK=%LI$o+N=NAPr!cn<{$cM}P_wXKuOX&on`s9bsW$r~u8(FS7Ye^!@|k%| z*;2&>k|;a!Sa3_`db$7P=pMZ?5E#3+UDEXS2dL^*9?pR0j|v zI=ju!q58a5{#g~>%S#X?&Y|t03EfO3V)tdX8sLXjE&djs@sF_^T_T?_tTGA6J#QRj z*pV^}ISE=^axfa5lN8Bs>y$?~mx;m$RUyYYv(ky(rTzD&1q>3g-#+a^jjdH$mb8%m zJksOPoaZ&x)2M1BB_IBnlNW4I{bo&~<>ISI%YIo~@@5c`v69+o4PSpoT5XBjva3db zcXx{g3j@dvIsz;+md*0y7x}SBJRJLQqc;55nHXG=N=MX!%CK$4%q%1H5M=|Bg9(a% z?6N7!_REYX$#TFaa{Ma?a@r%0PpdCSCJC-#laBhIM+=^+5BGNccoIPYdm1dXHzRI; z^d|Ohz3)|8X+`U|o7iP{dipkWgk-@|;97`GvQ)z^eWlcZ=LTIs>nE*5C<|b*x-d+`sA`pZw+!^-97q$A?`uI9wLgmwcv)px5B#FH%;^nb3?#l)x@#=2pH_L_Y&nS?v zE0ZqO=Rco+!dfRe*AlJx!D<#3ss{j}9*;5TI$o-khyIO+yJ^a4=hD#)kss?OE2MPz z(!MvI{iy1sH`sNsTLdY#5`%e&euY(Wu;*EXMypo_V0^fumdgIQfkk@MMlt>2ojjPh z-FSWy$PWzY?YO3X1JtPZ(MOy5{wSnlXqEFDtjfdH{Rj(Jx*E$t6=9ZfLeuvMZk4t9 zh-X9TBk6bOUiTP-`?E(DnB8#dmR!t&*Ij30R_=Hv0*{Q~Ah3mA^p;da{1{?339`9P zIGp>9jri#kF8*msYMaav@DDX*xk@$+NOwXssxjcEG5*xWJ7t=S%Ihr0$^=FK1i%Q9 zpi;Xo7ys$6ag*sQqlwp#MQc!}WluhyXNC=g1LSeoLBs{4P?>nXc z>baa}f@`i8IY?BSL7TxI#8F}x?&>HvdTGSksPHR%)(xln%WXDZ{!6)s41%T$c^Fsn zno~dw-mO!4H?b1;;f*u${KOo3yA|@8NrV+dnESdD6^)95b#yqW>T~@2uQ7Jrr`%05 zgKnYDO@dxH;dXa=_V(l}VGV-2x0Nq9_=k2s2X%u;_n>7TCS~U^t_u;!dA@nkL*s3G z*YTSu949d<`vw5hMBeWE4+ncjJY}HU-9#^{4<=|iZBI!oTyGUL>(VC%%}-VB z$8{x0qUFJ`ybu9fZ8Us}Ir|{mQL4 z_9z#y6Kf|~W&1CmO4}|r6Zx7ygEE28Qnurdp#1W`C)Hb~o3GI8>n#1+kbvq)=iB=L zVJhf+Khq5Cw$@1*Y6W{!m{n6sy!#|2lAJ1!#5f9wY_FT8W zvm1Ko60pgB^L`_a_Tm$^j_o9Jq#}_$ zIYx-iaD9;ZN4lG|n{Eat;;|>u zu)+Fq3kvZpU*|j}x7=j!OT!io6Mxo&I-H~iL$XMfJX;wcI&o$CiHFM8Ve%8S@$y9k z5Fz&TIPBo}nm$?L0@7+W+^9t$ovN#8(DAOc@A@^;@o3)_(?<@jsKWCuuF=u%`lWWG z#29RQluY!%fN+E#9R2hFK}p-2@&UeHSq3mw!x7p!RVNJnmt= z*ZcPQ#!S55y$)7W)Pv|8Xi@~wOtOPEI~qYcfn=3q-eo4u>5joM%b>%+@5d`bxAW1g z6u=+#_VLeRPF^T0Pv@7PlXRK1ih&0h8X%XOb*$+0I$>jA0*%jy_sZ*~H4>*v@OK_z zFYvX$vF~*7u{srFWrU*%n$*IM^pUn(pYPs+TFzUvQ) zU&PoKiEd-4%n&FTb*BDvn+aB6L56zl8w9$0$0+wnpNKv+OeW ztNZ^12H~a5vuw!&N2|FyNuC)JsYs=74((xPB{zZT6?CvG9(Lb^C9invY;qp$W1oXG zhfNi{ftPIAKuAakvW*no_T0dW-QkUrf^Q4GCP!w%r6P8vgv}Dzv}eKY#FFi?O1VPd z__f~K`>?K(v;A~zDZKytcgo`zA4mNJd|$-ymc0OBoINiRq!{|ktGgsAbdub7$s4q% zRf1;G#=@7p6Yut7}I zs1n-H$D>f<_+T@7Cl#~?^B*UxlU_4V$D3FT(>=nv)#V|ORq20KwA|V^kirR$2fkxF z(~>uXr~DB7BQ13D_H0L$WCtZR#d)AsujtUI@YV8Q5!ys?bltF|EMC!jx<+BQ6xv&7 zFr_s86o*>wNmXK}G3Wb6U{AC9@P!nz|GHn(I~Pe*< zlNe~wSZix$`YM(i^%3>IKQ+QmT8@PR)5gyBa$s4&S$jV7VuxM`8b2q$Cpx$4a8Q8i zq9|p8F*&j_sqgE&BfVNt#m+0uw8iY)NhIPlL5m1O``)e&H^U?|VS&vM?8JPBXZG*b zRFsll259acQLNR}4;Il)Up~|B%$yFPCdHr5Q=lu$fg0o%Eu(!ib0&HVUXm9!F~v(< zSuoJP@1|hHy@laEF)Q^Q(UY|*Mj6s74s%Fu$cu zYvA#Sq6qL;9`$5ELekSE*fjd_iYBJzSX`LW!~(jHq26xnmY*aN7E(GM`&RuJTK)Jy za{NRPO4>G9=f;$GvlsY1)A{g$xywY@&M5WtO`1SJ=3D<1f$yQ;LTwtaJqh00pWD^Y z(iw3!#hrXQp@i__`wjcNiJ9}a8aCCbHU&mQ@_Br*?m`lFnelKJV<7G)l8E+9RXTe> zAm8H`K5xRs5n!fvHFp0<2ggcVgtA4RVKEZHW_ud84K&EgM65&c=NDxQbA0xnOQ)72 z9l-ijGUw}c>ht6x+mhi%B?o9CfGs zf03yoo2z9hk%m`!d%4wn|JB_WEf*6^6c3eje}DvU#xiK>62G|pt$EYNBh^(m3VKNv z56k&n$LyFnh5;Me`qrz0d=v}jbmD$=SJFar=e+hM5Jq}C7*&k^%j%+T*=V)u*`*La z{5cFoJkb21Jsp5*-qS~SN3Rq;ZK*_i-pxS_%S$-!PU>YUGi$g;qF!8)es6?>_^Z?@ z#vgmcj@9Y=ln=IqTtfOowX?=^;#ah;O5|RLE{>QJ&R+jhN@J;B#iu4Lue`a3`;zHB zU74GNrq=oPT7BlOH}o`C-f9so8*Vs#plsQiYItN|5XgPw<)@+l2+$$Lv<)9zk(xO+WcclqDj=P7 z6YApr&yY%NbwXWC1us#c4cyiO6 zidB3XINK8fiFh-%DZ{*aK=Cn^7pF+!(131?hjnQK#TlfdN1mcKef0pHo6$uJZd{VwAAg+_X{)OxMAt?=eMPfdT`yM#g z1L{s_1+nu00cdGcFA-6q~-AL{!9n&dr24v_0heCbzz^+1RC6G0!aFuqGAWMdT3caOA9qNDCpu zr_C9C3$SDf-L=ai%bI>AviE6gRWc1lKmEXWLOpRgE4A>1TH`xOc7yZ8Q= zEUgmeBC}2-=3`oDlc|iATiDHd^PxD_Sjo=nd4Dyf#0`dwDiL&+)2A5Q3rg-0uG+=6 z8>NZAQ18k{mrvtqxp9IBoYnFBc7&R@yID`OJ~0?FSpbQMqrS!# z4owoNAsLa-oxwFsV=Z^IX!;7?_ITNmPEPd;t37X>$3b5nwwx&1}JyXeAEF5%V>L=r>PH&ygQ7 zz7UB)AMUFF;i47~gA?gC%fKwod#E(MReUBFf&BOG->Q}$Gs0PZNen8)K>*RgKR0rkxn`Wkhbnex&Sgloa(bRy zI_Nj6cKIT)B`c*lq=r#|Jdb9zy7iq)(T*Uy3M*6_7nnmD4*8b zMf=J|(&9^O<+`i)e!@b5Hl2iC&cmNx9Y@aIMXta1;h^K(ko+m=CZbD9lb-k6yD!rQ zXQ+){9=gTjx#aF2nG#y$lSf1aJ+*ARxabuQm>*X7;AKs)69r9{Fz9k z+3$v*Es#581)m*nN8&qYF6Zu3V44L6X7AFWV6C*oV z7Znu#Afxntt6CO;`h4*TZRz7-=u%v8cm8F#wbwL{>gLuf18~l%--c4*w{*ndK$#)c zIRO~H%3>PzYnrf@ zjAYG^?N8HTRTh_bx{JC3;=CI2H#uqu6lZ~VcGZFzUde1uk9l?$q9Z5hjwY?!_>AWW zMJL8{R~#9eR$G|KX#o+Sz|_{LCTso$;!UeZ^~x)WgO#jtjhA9Wt}Eu&M`i};E0#R& z-y^>|o`nvbmaosFx{!%)mFl+pU<1DrKFV*Ll#pxnHgok=#XL#Zvg(74$ z9E-)ej{njdMSh^F%YH)3EHqr~d1s`!S9~=O*tDANs7PYE8vQ*o?GqpfwR&!zFCt+4 zR5v!XLhYvvKg|}?_@|>+-Cvl9u)Dm>F6Y$(1L&*zo2Medvm9>WU$p3yU>W>HvqXn( z_~cB6MQi9D>(qHI>X%hnIcwlY`nj?&l2M2J%oHJPtgko>T;rVHH`05NL72K`8_Wqk zgPFb0)TC7<+#iRfNDi+qzNDl5_}1f+jLKe|s;(IkdfQr#_CtZGfk%LM+Gd>gUkkTr zrwSu%J763ky1+Nu->&Z{KrLbfutnu?d=&6b{;QIUBJegjm5McgjbzPFqCPD5{T^A= z7WLmRbGUkFF}!raUD4zVN_u02ywbU#n0`U(lnJhQ>H>1XC7Dm1ge^O=X;rg{6d99? zMgd>HS^NL!N;Sv`{OWJer3ni93U9T6>IJGukGGZ9?wIDmapW5=IGvE@Jsc$q(@Y&u!57Bt{o`~5Kq(V`h zIZ{)P^NEj0xVn!7KwYpx`PAm#v#=UpLHa@Ni(Xj^MXb%uFVvF#a6x6-^P5G5co- zm30}?9EOWBS~DYiW8uB73AhSd?Dk1L)Ipu2Wx$8kt}LuVsCp|0W#PA%>pff~37zSs z{yPu)Ntq*I7_Q-AT&D`CdE&f#0MgMIOk-3K3mWpQ* zIB48Rq;@V#x9Zes8TT<7=FI=%Qoq5r`d>4%x>v!Qzq-1AF>B^;BCzKT592?&$Ryu? zlVo*YS9Z|^g2F#ONijhYC);zb;NpGylhiI|=#HR(WN(M8yeI?VP{3*i_0Ss;#Kc3z zyLS!)GY{0BhboNgF&mY|Xe@-m5h+pV=60d~n;0#{3G8 z%osCa3Yv?#f{;T4FREfFTxS+3@Z2F zDZ>@NfoC*-?bnKN_$D}udJ24WNiw?Sl885-?-%`Gm&cbxI7)Hs4tn=9%qiO6p*L@m z{+7p)>d?%@mJbi`!AB5D6WV}%-_Dh+W?#bmZX-YZB-CBffkV=L8kt*-!C|{eB>9?# zB2bXM$#2BrG2oZN;`v_(eCm{f?^1vx2j0F|N8O%=aibkWbFD)DlIEUC8jU`*!n&}Y z3@K;5K`Tq{86OL8H#Aey|cF(P-Kg>a9;97Nn z&az2r#MW@cCz{Ot&&51~(+`!cKnj|lYj!^)hiMUvHEHj&o*q5gMXmWh^ss@RJ587& zr-DBd%3V>q0?l`2QgLs+u0jPZ)pt=;{ni~skSC6Ol6n-a6VJ3CokA4!K3lIX*+dUFfZ$hs*D}K0a4RKzIEWDi(mOm?~zQVsFbLF2U1> zZOa|(gsTTBIQ*f_$sGEKM7pHR_*(fIR#}!YHv_~6Vvb-f#+2@icF8)rjXIixnRni1 z?nU8)vWlB^4rp%5D77~Z$tJraKMiZAsQa3qFwhcm^4)=LYK8JZo9$<6EKRFByOtm%&cIS^hyK|taAc#!?_Iy3U9R; zZBsf> zhBvCK2m_1^$I&-Rd*Pl(5Fm!iOMi}K{>N<(W-yuk-BVbHr7vWmkD7eInu5usxrG$R zP$#s@99+z^T>IT2ktyk~9g8vSx+R+CBmv6@*%wjHUMQpB0~_Z-MsQD0oeLW!f%!)g z-ts{ty9IV|T~y8;5Gl%mh++f3CF?I1+pj2gfNN=4b70GKem_amu?Oe!>z&0yo~zbW zvYjy$e8(}d8IBr5>~$YT#(5a}5&UMAi8I8yhqiLEWfgN|MI_=DS=3!zTG=5~J2teT&`eNu-_SC} z9-?u}z1-19@z%M)L7W%3@_V-f%hZ|gq3RL1(jnK32Y7c3eYva@2jHaOBK@`ebAFNm zv_TR9wuhlXU-k`|NS*u|@DZ!(B3ZiYm>AQ}2g33D>z7gmrO=(w&9RY~8dF~Xm@OZc zp_@jnRnv$2RCyl&Bx(aVt1k#v!yEF99>4r(xDL#kukL-s1|edqXl0nKO*L7d5B(0? zPe~CjH0t&yHgCLZtctWOL;lNA!x{$cqIxIeN!(t2060xNQ_aaSqVrMwy(5n%w&sa5 z-ctwseV8G7TZz0fXub%TOXbLuOE{Z)`Qz#;9(h;2rfqmYxDD(?T zq3L&Xf!SGhvWcVVO`Qgt+%0QL3iUh;HL000+PrX^bT=|{5ldr8p>Fg~p;<}8dIC;X z1hClH1vBS>xZ$rn6I2pytS>spIkI#+S8d;nKH0;z>-q50&mK%elt0KzbVl$zE=|-u z;#Bvu7i{z0wvj!JL!N6JV;6c|Nv#TjcecVDjd(djhMFuq0+~L_k8hnbk)22p5qOf$$Ml<|m8HtSl5RCQV z#)`loKB7}dFzcG(vIhGySk?x29QUyFf_l>*5u^(wPfX{2=Vq4KO9D(S0 zs}lh|f_gc;s)-oFPxrt!*jN@YG##ao#V*6grjZ1B;Xjv~2J?n71 zMMvw~jlVw2^B&qGE2T@T62u~Df>tJ_$X?B(6MkJI8yjXq&Z}D)cF=DvaG)(dA4b$a zuO5j7j);Ckqk3!l+s()>usS+{^CPm>FYO>R7qIXhZg*!FjZz=KfZ7gSDB;t6&3?0W z2*JQ3)Ks^;qhKo~x8pPZM?YwG`^~$g-OSMaCYW`3B@e=Z$FXEa;>C_?H#2qhFQF(5 z9)$g07=y)vm4(3(nW5nO`_^c&X=snC)F}4wEG6e^Pv<_^8a%P#FFfo%Oigp`7z)B# zo(l`;=7<~M{&L)f(TN(cT^;Q!)g2eHHS>JRyv}ZqwK%w_vyb>39^DAJA;l~u24}FTqTbi9J=jcvFS{j)%Gs-R1@| zYK7NDhFl#aW~1SH_Snwacw#~)>8rf$GSXeK(#_UtiI{L<%?YN>NuWBT7}}20*5;gD zy37yCZ?KVczoj74A;;~;aYy4K9{UV(`=RrG8P)y- zqdNtMba$zMq)Lb|x{(Gck%rOTDIF36Ho7~cLt;__(v0r(9pB&k*SKI@d!9Y#KKFe- zaZa}k3-Eec1_v=h;@7!qf|W{S-rY^9I%zIre_V}0PqBF#-YA7ezeL~b7%zEXxvP{vy2#x9;k#H|4%?aCh)mPd`!JJhxQwQbf+l~th z3he41wqT2J!EqRaNtwtC(ZS3de*PM%02g0%-9QgAjrYI_MTY zrkAG7`&Ag;R$AOkmFnHMs73eBw-MH zs;VE(TOnuk=_(%_=+Jp~2y{VtgC4e=L4UGR-5qOt1C$GZT_v0C@laBP>Ou6 znXIk>3;!GrGLEnw?|)4JLLoM4D$wX zs=d4Z@=*8{ZV~D(X}DMO71SlzvemOCqbr0KFFaNGQUrYBbu(`2(!N^cD=^IpwN1ok z>pp8tjMb0>F7bHGiZAtxOI zg&IuD|DhDwC;R1+AR(bGsW&1arXVp%Adu$Hbf+C)IMa>A383@C`FGy)C|$l9@^A?g zDYi=_WNO9#u4i>SWGnLwYx2)@i`v={zM43p6ZX~JH0v2kQJN)qhD90;!)-)d)^xe8 zEuhD{G6T}Ht3$n~gLSHch4bD^Pq|P>La8&-ASP@2I2j<6`m5Synu7WV^zXNQ74Mft z{lQ|jvpK0;$a07p+z)1-_xCKjS%WryoY=D*AAxMsz~o=Wi{YAUy_GmN#n{Z|7%Et;pD`d{s4wdN zYaGdHc)E$Ahe>Jj3!n#)dJ4UijJBR=wkwxU!_o3zuA46j^;WqKnS! zZl_*u^8%?vhw6T$e{XIS8%>Kd{NR92=5&17;Au+*Czbk!5Y+V*1xILexbgO9z z1r)VG)vJ~uvO8Ug(z@w01rQ9YJ|JRn&!zdd&f#)D!wht*sX@FU$AIZtfJc(f@?&O9 z=?l~Oz$Rm_m7i(@r$TdGmxB3iEp{i&locCCqDc(Y{>U@mpVn^wT z1w<_9Z>0e($>V)bt66l!(6$32;!<0L+%{IHq6aZ=YX3>NTUJAj0)(j@A6Qerx43+i z-O>k%I`MEq3>@;HH^zfi2+tSK=7fY^&^s%beOK}&pd3|?0jvjabLedEk79cRp}7Pa zMvKlz0?pP6SZhluSzA?Y?s;WVU>y%B@~U8Hb2q0z9ktrq&7YN)1?SSXP*)qobZB_% zRZOIN$omr2*F|yzoPRR9Ibndqd_a!>boYp8lkZ*)U`O@Zhm0A~2{3A2`+}lnhgE(5 z6&Ygg%2@o z)UExCEspE@W)WZdGx~tR zs-ohgY6Udsl)6JZ=hIII_B9s3=MDndSf_OPS0x!3 z0!rH_?R~9Nqy)&4>(&mGTy$PfpP;-6s9r>pY_Q(OIYTN_Yls-Dkx0@1?A|%awb^5WHj8sH+>ks{Rqfu_Ok7F zk(sDP9wBWhD9*lBJ&MOSuA1naeaqZ93&1P?Vam0A_FB~4Kp@6&Z2L><=*3>*jZ`?s z@-5)~G|8}fA!(oi19EC$oLDmor8Y4$uR7bQ(pt;KA6s$KPv-&X6{` z8W~u3k~o`R7f~|Gj;sJii{5*U3RIFkpbIvcO_{H32KQwvX!tvvQb=t@J+z=6J+q<- z=C<>>Cxa}&O+$nH$I!!Wz6-vYdHhVOeTS{do9UWvQe&j6Z>s;71*HNrF@!r~gyv7#M;HNoioLARtG!xQ2`_NKs>23kHTcwGEhX+8)jw`>izRo4HbwO{tC>)A^em9bvQ3hbXAjL#Uvl%%Z80jKzh zxyL@Ro%<==L2|12XwE1MT^SGGAE(ZlFmgKt`0{4V#1TTy-t+vgz#@sG*K=Rh zDS@fVC7?X5rVrEW>5W)4IE5sSyKj;}n>xGR*YM41{2rNOaklM!FE+V@e7BaPSEvYX zNzjN%ocLuSx)-3SXusS12ZggX5V(s$I$niFM)c-uVE`NU{p)HZ14hNgnJ4Yag#>MS z@Us$9=alw8y-XxfKsHw37HW{gur5vhDecO(bKwBe*0uxXi@G|=wbR%z7S2;~rVZ$u z8Cmu8yoYC16=eOR{`u+L{qxLZ_j@6vrs8(a{;j30f>uYQzb_EPb3{za3VTbvb&)Df z5i(0&Dz$|0+k!vN>-F23HrkTWT2=jWnIaVHNhH3%{sz&ktP*Ofx2={uj+3w7L;D5q zUTV7j-WtXZ4+xjaz#C1-6}NaNkkM}sy1`zGVeXy&wS-4A=804J`|N;D%J8&NJ0mq_f04KVZ*Le zUo_|T1+2yb>b~DhO7#72rDU{1vRxfDh>KomNNUF$qTg6;x}|YWo99^Qt4)|gg{W1$ zZgGwlrRh|2MZGhs`HPKg>?_k9RDo~&yR+fE@Q(f|kl70Z+X|2vnmuz4jf9dI>)&%& zMFdIFe;67y7LHp5^xwwUK$2wOeO8($ozQwHdaiQTFfGXw4;c4@HDxkXg^y?1tUy|N znT|HO7KCsqXt$VUM&8fZ7=MmTH|6vM0BOvyjD1+y7jfB>*Oq>+AkgWBg3`?oQS1U`=>y5s+`B6NM@2u%SnLIsTBjFJwM}beOq#6leaW#wBp=T zN!G4fH#SxV&`2`M?O!;#sIGn;dUHlbi5FP*IrhN6@)Lwnt$kaI5A_yB5&lL>IOJ3L z#ow|va(Uedh~7nD26pjH7b+JWwr#%wr0-*)pbyw$P_ic#2z-r~i-+G`7rfS(XK+Qs zX6Y6CY-CKoLHrV4q|cmV+yRNW6h=K@E69`))JDs9LLVd1K=ZrHbch9N4=PNb>V9;A zb67FyU`R8f58z%ddruEVOv7Yo9o)-a)>kXn%iZAO0m9-8_xVm6(5^`w=K*3R3`WlR zBG{CpCRs+%CSL*uysrV=c<>IDSAqec0*22$+@>|Y$+T1ln`X^xPUSJq()%(3JS_Vq z(RR~subbsDm@62pdJKaJC3;v7>S)ou%j1gCL}#xvK_T`0B`!x!hyCI<)7&~%yPcOi zWh{{2MdVVG{sfTM=JSxefA!iJt=fn(t#}czqF1IaB>jyn7SzZ%>X}Vctw|Zfao=9K z15YaL+{@3gjOJOhJ*T557PLMQFC2*yrV8IRIhg&i>h(yb4Kepp`+)WP3hw=(P3`9| zf7FeKIcq7m`)7qDlpo^W>e5R*zCIEstKXaDy_p@f+-srwsMDg~F#!^D(e6RgtB)l7lC_$owm?x`j`paWE4n&w?egi7#@ zuLU9Tp=}ydqm~lAZ9XFMSLoL*TOFoNo%JiBj(h;A{7mevtMF>5eI8hx35J;oN%O?8vckDQj-al2)eM0m8Jej8 zy(%Sm%I2*e8J&=c!GNd*JwlwmE&&kj)Kre9T;EL6!}>l|6pf1bawh}m>pk>-Ed#KG*&w@7t>dE+5qEGpZI6##tHo;=cS4LWwBBf>)zJVJmd;AR)ETJ4*%`>UGtmO z@el4?gVvQ+q^hi@Bz~{GM_O7rltOAv+M#VTNy6kv(P(8G>^l+rG^y&I+?CiV?!>W+ zbB;5W49}%SwK`8WjFR^&pwws%KIJRZcbLWY1|TP0yK$6Yv*vKRv5Uo45y}%|AlYnG z{~aaK@Vd`@`)Y#nh+OYQ`Zu7@W(!;83%_)G7F}Vt6J3(jy}&RQ&I-eFD$dImFord+ zs@Cy_mO2&(UzNVTR$yD^YjG7mtP*4aSg9UcN$-JrKn&0#3dL#CBmZP#lu(Il7R6l< z^h{DcFs|~Y!Pc6TmW;Nq#ChY(4~;!PQr2=TrFv2-iLMT?PDdb6&N~rhcnHSg>ADlU zX{!MmJyo2uGS=r1G*~l|ny&+F4C}telE7|+fW1rg9-{9FC7KNP3IIH~y(^R6H&eYT zG~~7_SJ#|gdt92>J^^;t(3G?0Y9Qh&*9_AOf^EXy4+#y)oSy!MmL&|@-LDygF**Dj z!O@qp;oVbo3kl)5a_$$pkQj@6dlO|Dc65m!TwD;bum#fdjS^l4^2QKoEzVm(&3Gh_ zJTvP=;~HF#6>n(x0VwmE6_~FMql7*%l+T$ERxUid6CY|WC2<)=wH_JbxM<J)L^+QDaqg>)% zN_tWstY&)s78HfsF1pX;+Zvkc)}tVS>I-GiNAX^7=4>jR z8sIyqOEfu1;D9aX9Mx-Dks_?cQ{=$+Z=)U5t-tuZ9^2c;4YR7<)7YzS*gf&zw`oCV zI>dU{lByoE=X%}ABXEf5>kICEk6iONjkp!Y+PaNF1b;dX^MN2l2a>D8Bn*gOaDcU0 zAf#i`wzsSfU9uFQC$9z6flYp%t%m+XNtNef_8h!5 zGVH16zW<)*mRB~>@Veb{d@}Cn4IVwgA{}nz!NLp337Il11*(`%b)KA$E7U+kjt&A< zJ9!sycG2)kbtNiO^Df2O<&%c#8_hb)nQT8g)Rjzn2`XgW_RSmoXy64e$N1jB8}-A= zFP2--8&;gZCMO)nG4P^|k>5OL^0DSxUy*w~X67&|GobyOc>LK2FaBo$rwm&#2CO0_uZRj2(s#P{;Gd;Re( z%;5t@KgTbZk+k1+s9fo((~yB0hkE?WjRDqefMoQC!@|<}Pwf3?(TRk(SU%%_Ps&cI zzq{_~pxv*6j!XIBBOrUgojI|#q^l~(jCzd5R(}%lHNIw}?aU&BI2HVH9;x*MJfB7Z z9Wc9?6Z#P^6rc~v)^_buN^$w(&IGaa`29Oo#DAWcDstqj-{UvSWt^T9j0RFsmNo|l z==^JfCyDZA>LU4UhL=A0X{wdyqb}1tq#7FauY5_gTU{aG7|kyYOai}j2RiUQyrX?X z5~$mv6s8YV>ID(3DoFZ2?I)wIi((U&WKeO{A+`&_-_ZDcX!F=5k<(%Pn06dQ+%_(c zE;-L2=&+PgKP0is{3|R(!iup7Ia*nmqeC#o;|8=B0?I+oRwQQ6^PIkn5jQCHqy=ddE#Rah}+ujGY7YX_bM( zG5%eU_p}SSzpUO9SIkSOI(3vmGM-N&l*)X;4kW6ewR43jN>f0c$L|4@1$*|dWIlfw zrkCtRGYzZGYk@N&y`-4MOD_jwWA834iMBI2d*dVwJ=Ij2CU?F7313LoYL(~scWP5ozwSjq-{0vZ+b)3KI3Q;#$ObVa@skG* z)Gy$z^ub%K4Lss;+e6?t_7fW%SvL1CM5R~hEK5v42S z9sGtHV~pVF^4OXRCz~+P-kO=BYkjXmQu13*a%1h#mA0|qUJ`#)iZw})_#g>~r|Hp0 zsMql1skn!unE~?XE;Y!b^d3TOe@JIXyVGzD?{~$Aib`Q;?7pqorYho`-!rG2fT>!o zwWW^svrh2auzcyRZSCgCHm{E`$3qd8w#25>Uuf;wIeO^&;@S+N5_PwLN}-oDNQ9My zf)fJXUIS7IPor^-;Ius7tlXx`{f`6uop0g&56>j8*Mgei5P#=LM>NE#AJe9b^Ll0k zvK?1{KCgj;jP@m%ELE|)0_Y0+{g4;o$jCTyMk1(ky(O+9h9iY8-ML$S&ZjiB**T|S zgo~-hBLQgI&}Fk^o)rl5`!zy1#l@Abj4;s^FW53xj`##ZioNSG*U=?T6O;z&?KJtK z0R=7bxdz}1fguvBc2@W2ZX1`z$3;LyM!fcD9$A*0ccecYTLg4-*t7>^7mVU~~<&5_9xCD8v(#}gIYZUAKxQeO;%=V_in#GW@XtH0`yl%I)R<6MccpUjv5^3n95^FR zf&Y#>Bf&#ZHMPH|cnP16giG33zWONJ(!ByUXyZm(PhP67;Db5MK!*QgFCF{NQiJcl zJ55p0F1&?DcyE$1_V+iD=yyv<6RT9ppcyAK?%~e7gPb?U=?nSo=N7KG)Qsvd#$1RCFIk zfxdZ%s5a-A%)sqVBnw)4p0}X zV3d?P%yWdF5i#)u4#wzDx~m&7f4C{c@Gj=0<)}{EVRB2%dn>-z6&&DHh{lLl&;Ni$ z$H7Zg{2Vy|vC2^+SXdeZR6D=a6mIFB2OBJQCo<`N(kMWLt9S5{e6{ICB%Z0CvODkHE$ zj1&oED=o;36`8v$eJL!R7{H{+#V2`?WMowB&|y*If3lYBz0NifoDj{nM9z^$ia-J$ zydt3yjn7n5hBoFEK%3Knj)rNDh2aat3dF~kR3^GOH5M8zj$n@G1_CSx`Dt8TiQ#WM zqGMKTimCSu^hKsGhV^k2fJbd0}RAw4%9dHooHfI)xK0;z0d3;b(Grtq#Gq@7`!B zoN~+`u)GfJu>PZa-C|m2lgZu0aKF7QBH4QQbu+n-mLYeKk<>>()3!2Z?}@hYh2wg`ZYq zP^Mk!w{YvoKzo6s!ht6pg;)KZvufS6N|jeG;irtmQvwh6a~4pD+2=U?VnKg_8+n0XB8;Qy#W>J4Ewc929yG? zHPE&WzRlC5o2*q4D%c6Ujxj6rtA9yYrZt`E_+cLPNpXVIalDu4Wy(%A%!B$Z7K@0Y zo9WV9BW5Y=DYT>Qd%A}s4{&M^8WvzC*b=92%iA3n2y^(ZzjlWq3)#5Kuu50Nwj;|$ zM|IpgRlD2V@uHMe8|RVw>FG^f8pgg> z5j1?k(|-CyUj3A?=yNrpuYcn)FkSxr-E!zrdebjV(2e7jIK{im0Zo9MWz>6-oX$|m z0tSW`gR)kN!4G#2zSIcK&M$C_l|O0SnFFiOwUNpd6;M)vQp@JRna0S&u#gr^EJ5WKG);qWEFzG#DbT;gz~XFK-bRwKJ(;Q6vnIVDZuU32 zLEVRVsmBCo{aQv17fmtPWMV7aeOGlW4hB81*tCU5F( z``?}ZwS=CCxDpf#!(CDE{v!cuEHai=k$B)jnfWrVh+8KUkdC|i;B`t(@WiY}PDK7% zIPZZwmno8}mMCw61bdgF#~5m&!fqY@VHX+R3?D{mHvX}y2xC;vl`PTzH`fOilvpuU z;XB9?Oc7LFQo~5B_Re7x*>+#jj zY^Dj&Z_)!fQHtS6{PKW#86}kx0xa@9gjvN%Hrk90(DUX8qkPJPL3F>wn;~TQc#_VW zZ2m?rSa-y5cGY|-zO{A~syT2U6h_Nzy5|rtkD{9}??vST)8p$zWmf)iW_tE%kVM=o zp1R{TB=--F+H*`!!>c%P3b)CB&OMpQuR7M}ngQXK6r;gx`#nJyovAXxB-kUS3k@|U zNSZK(GWsQYFzI3wnFfws4FfN?y#Yzr)y0?vG zI)$I7F+SqALmYGqDB3lb#jqelNgF`(GBo?B@9^Pb_b4BC^v-#TBi+94m^(bpzT`n& zpjavfGxlBDh>Bepb_NEr6PoTVO4x9@G-*!|^?ChE$Tw%8ppy3TQZKn6h+XXWHqzW! zgQKQr1QQsX#+npGKWROOGI}}#mj^zH76o6uw1R?Z>aI)pjF73+DwQkb;jnexW9Qqe zfMTb{(9~o5-nh|=whb0M+nE!))n<1z4u1mS=Lr4!I65(}r3sf!Vtn_vchjIUsi)$f zwL%YU2$3p)4gHaNJ6Q=}A>fEx7y9(mrNsbIddlY0B{$K5F|8^8i6aixrZxPnUw48w zN8BErJ}of1Eml!l9-AZXr|sY2Lf29hQYG&?%ymf~_6F61p<%DFel}B9(Y;xduTOyQ zxB;AWStZqClX#3sQ^aniM%1!4X_%#kJA8H@MYbYD@lJZKt4-hqk5rE}WfT3agIoP^ z_}u;gz$vsv&+~jq4w;B-*NEwGQQYf~OMeO*-$D>x!SQhInq%x+NH~DY1NnYL0M}S| z6$QhT$eo0phqSD9^YM-i_-M{d2M>9bvx(FQv$X`1ue*jd`@~P5DS5%8(IO0=?I{$2 z6Jx^rdsu9-?k^I$9G6?-E!K#~L?0h(Z;^jyd6I0sH~gu$Hub@rz z@d;vw82QQAQWDp625~$(o_#9ns#fLUqO}$$6|S^A$YTraIK0R0+|msK@a3jpI9L?d z3VOOmhl1c=$o8xZQ|}wG$Ry_4VqJcM?Ff3fB(Swt#s*amz4UuJ3b0$Li&#LB%zZ#v z=&$cGpHzYcLKG28g_Mr@>xBM*STILHd0@^(`6(k>0A>E?}z%b|EPn^R}B??JtRp1WJ?ri!k?uqqJwJu4$m4(E6PkFxY#&H{N2 zM<_adPU8KjJn>3nUUhh&v`i|4>qm2)C$diXw>cNLHIQ zyXzEBJIh=-zff%hto z75~9o3>aZXq9JhKFb~6hhjNntiRcwh_dAzwBgD0uWGCT)V>rTKbhOO9mrGb0hu+f=?B&`N~hU^X7*nH(=-b?waQYI5wTe z&z7&^2-cIWf^Z3A;6oij`{`7u4*_zPa;qnR6JVTKxv`qoIKN4&CkT$(p*2fR$LL@ub$Cce-0fB zaCh!EhJ!#z1v3=NpUN8EdGPup(5ZF2%t;yW};4qP)7 z%>$I5ztN>zM@%B+ zXMwlkqe}4RPva8Ss{-7;yPzu{$yG2oH$vzxwr0fANT0FR;6(ae&n%XY5$k%r=D0jp zt-)5k`>zpX%V~$@K|W7pOv*arzjYk*A++UV{^Q^r)SY@QLq(w7(AU?E?LF^});Mi6 zVE^|ll?K=T4rMxX@3-%p1)llW$i59F=(+;87-|cyZ*U~Dbl$$48fVVOZfXlbS2X8N zto60eic4vXNB7wFBE7Z;i@&f$`K^pDeAHwhI&##shL;q4Z{+V+K>5y1_ZB8060cpC z8Gm`_o?tqgR=2QUVB|KIpSeY2+BrSkOCC&uW^*K-Dvw}9O;5XQ zu`W7L&QSU+W*Ogj6lb?+u&1p2F{NOS_<|E5s8#urt3sqF$hK7mry{#qSZ;@lv$DI2 z3KjB%4BG;OFGFZiL1`W&mU1R9`B#Wy*V62y^cGz?R)|b;o6!)>;XoT+Dw)=Ob~?q~ zyU{nfaAQHEdDV@zT4U7;l!mPNM*|#$qMn!?vyED!NJM1~XHZ>gB~N~m}fYT0BVbNL@o+qr7G7(`;EC}us!O`FOh_3pgly_WMGyqlO|5yjHRT&)OY zj$zG42S73E8D3Gf1XS@vMU->Cltg{;PY)5vi3LBTC7nAXa=p{}Y?EvBao*=P_V)3L z)FniyPE%X0ePV{E)~WYm8n8b7Hh;u2#Gwk)rKiUwd;UqAOg_Y=Gf-TJY_CGa1AmB< z2tZ}^MEMf(es^`>e$w0e54D80B5@ke*aIGY>72>GzvQ`orW_7tXFYLiDRoW?A^08{ zlQ8M9th9bTAbMCj7xk0yUIm+OG0A+dz5rUn5y~hZL32}|J?jp=1KlB8fz-bQy1K!n zb(?v1^#0R^_tn}G1lQlR;tPMXd2Np66s^%R14Fw!hLJovxgxIc?94Ec=^5q4{D<70 z53%zMSttlBU{_+6QuZJ-G7eP4nUE=m-PC^zL;~YPajP(_Zg*OHS={ySfkhp4bDM!k zX=Wzr^kUNlyOhy%1leK?YKaM%JpBAPLF-z z#X;C9J~OS)`YG8nG%>a&7*96ZA!GQ_uJI4SVwd+3M^P(j`QcakEui=)3hZa9w+D;zNAG5cX=nR$)i(Z#i!RFQ z9NTpBexdh$D%J;|!)W4EAG8jRK2X__FA~|%uD2jYGAgHdfYc+^m9=+>w+pLubOf$sF}<B1YZ>`A(5} z)q<0MNZ)<@8KF=SRf{R5zKr6(4~a@#H$2c~va- z&BzfNY_QS+4Ne71c|oAWkB+no!$7DnSD5xp5!@KJ903dhQESynv_|?|zI5I(e3(@EH$6sdk z0||2UQ}w*VnNY&PY+dG5iAN$V$3?}!MH1Bpr<4bP8__5>g^fY)6nNF3)F;v3UEK#F zPe^jo=li!riPl0?7l|BtRlSysEOnF@rhe6Ym5=#u=a(&0gKqfq*=Mcm?mnG-F z3N|H~O7g;_O8XF=17efkx*wXbjBQM>7SJFOr5~2iZYY>ANJ7lF)oiUDf#aiv>4_*d7zg!3o*@xWT& z7@d>#5yK&CQJW^~DAnm+M!51?H<6Uf!-QV051D#jU?JsiU18Oi3)ajwlq}`<$#=wb zh<#(`@>i3&m`s$)ER@XUSFVA*Yb^83<@bG;znJ++iD!??-5S?U?}%sR`4T|>{3=`| z!f;IrsBwP~C5y`BM?*mQo6vAu&yTBap=otA`V5>7KA!@B-l#U;hDhMmj%!+Egc@q@ zx-q2;7;gLKIxOW_ZSdEXDg8VOTFQD)J!`}ZB0D!`9T} zQq+n=ZiL9dH%GkTX4E8}Z3LtDJle@$q=s{N3ShSGF=?Eyw&v%ecnBBZ<_MVhs)i^a)Zb#BUee#sAnx`A$#ZJV5BbQP;B_S?bv)r^2Nj;iZdGumP(EP>oLmDHum4fc*E-Dn z_^L;C5e=ENFV)Lqpm_^bYCX5JZ|t!(?n-Lt<&btSnxME4au#1PkRB{ogcW`j`%H^e zW0U^*r!=Fy0J_S#U>VB&X+m+=eFhWc4`u!1g8@!mdjlD&z~AS?ZZnlFO65Z`Kl&z` z9|8>P%aS895l1hX{J)`o7wdhjW3 zOrzVaowXZCC}GD0)@rd(oi#!cZPeDEob>wYIDVF8uiw8?rScq9N7W?y_)cq~M7sF%z%e+eOZIBv#@pRQs{ee;np)id! zSo$)De>T~s{Z0CO7|xTmByYMe0-qJwR;k+l>~D|a0UM<@M7!}A<756pfGzojVD+8@ zCADbm`T5F3PZJ?EuX&eX_$>ONd}+?Z#ibMQ;G;c1*%bXpm(m^Cs7b6IF#eXFt^iDfJtCoG zauqcDEbM!;6<}(Wgks<1ewhX_>~Xx(cA1zU0{gZ$h%{oDzsKWzq;i=r_O&-Ik?{Xt zk;&lk7RPv5rCXB0d_iYJ9I^DLW}pRQ5Gk`eO{jbV%LeWQzI`*LJZFB3$qTgR`oS7W z;)Br9i^!XyQEIh8!-IM^vy>y#3SQ_V`T3^^i@`VP_K_yz5mDNQ0z&d-J3A(%4 zN~I{qYLC?GPq~ZvgT9Y!rt5bTy@M_T0zi%b+6A2Dy$9j`dME>eYFv@Hp|nS3@DrcX zmRXBF?Gj^-diR?upORio)vFKL)NboOmZj}`60*{!o_7>grC2HGrX2(dI> z_mU$X_jGl&^5P*RA0=cJ$pk)4AZI97vORZ^|Mowe`*%V-1wKTd+;mKmpE_M=1CMum z5`+2`7AfY&ujf}wZb6P{Hoy_7lPyg6_#Q}FN(p)zM0(q}NzLAEa)Y6mOe9v2Jqtr( z9&d;d3mEV?l03Qix=Ri(&&fZ(u8&~fi(_1*aD@inAl=@b0tq7TP6L2RS~Y=nTW;a7 zqTnZwWhw|K5k&1JJSd|TbkZ&IzuS%d$(fkC6j#ap6c-D+W{`71+;*DrH9yX7?l&Yr zB=5D%9M_I?nDVMieV6HCSY$_2jKfRL%Px+QS&1noctB?uK1-d`x>!t{mnkbbz#tied$cQzKbs^QYG*`76zWMhZTWrYqR?w zLBYar_@W3V6ukod?2x^W3V$EdwQhK}F`MFWI*^$|#PW}!Hmsz|j~;&r*K5S>m9d&F zXhwGZ+vY=+^FG}c9HsHv7k4T0plSZ6q4~>&w28mPmbRj~JZnIcs~iBxPBe5k6Pc=+ z*U4xL={wDI{bg&IZYu2T6a0g_!{1>R1TJB?UzgRW55Ik=y=nJUOqzvf8=367vqe1Y zf!YAlJBrW^|5T=qTXKz+uvKm&b5%=(_@JLTRx8_@GfXn3f>Su~?eZg;3jD#?O_j^R zD3l{Ko{#qlnq;y6^k1Gm;^&d9%(?6>UuJjzMws*u%9xSNqQ`ZB#g4e*^|w&7=V@^N z;qjxLQ}rP~-0L1KMP0jgu(Na(&XazL)=ZiMtsKk04t(g~2+|(J)nufCA$SU*Q2G}h z)S5qpdDQgg5Ehboybyow;7_q>KBhwl0n80YNMsKSa z+ucm{P48HVMezIJ=@kzqj!8lPEOXErCn?sjZ#jG!@t_CVJ2HYB~NsIQI+dt_$!!HPLOF)>_?tP%odQ=T0Sm)%y7wQHxl1=fSfdyN;m&Iv z6Lq}FB;2`)Qd-%5qsXhj=Ar{Ku8_KsABA!aX9`vL=Swjm_1cykcrlqC~c&t z+Ot70`A~ru=0Bgo*4bI1x!I{k0-fGzbfR8cV;{PQvlo6NG)4;#`N#=#1PHWc*N_6E zhmlQP>@ihSc6OTeOYuFzw_1kUqcgHIle#58J{SKk`J^6g<%_t&Ph#t-z3aKmZU9<@ z9PM9e5Pwwsw{cf6;HKa9d~S`Qa9Ms>DM*?Xdu~N5J3^2L0!hx%X{O@DK&q_wD9s9T zk_B8HP4AzzA@fS1urm!oAErLKzAsljhWJEcuL=m&h3_1m)otlk!v_R^*Mm;quw;y=5dANmm`kot;$N(5hN!IOUFhq*x=zDI`?!LF2ADpsk%uy0QNcdl?MtI8&s?EXcpR1k`L4iL84P>xk~p zU@7jek&X-P(<3!ppSN27VI!p7oyXbfsCiD3$eX(ReoKBCkFn^3V7jL4SQo~5?B0)I zm=M5y#Grf}PC;jrJjnyb4t$xe%9-+S<(Z8b78lLx%saq zLH_i5yO-a=PrU??Zkc7!4Bz2fUlhXlJq z8EH6j8)_IsyI)1Zla_Lzs@A-SHFE+hi@0eVXPI*V8^P2Nmk!!@|KYnWA%QtQ_uJI6L^LyhZy zPuJyhQf(Kg-Y_@V9qc;9!$Jo2&j>Vr<1?0TtowglePvjaU%0wN8gy9bC83WD$aKhOK&eZO&SyLPj4o%`J9{8AQ`rqFCn zc1=-=xRc?|EL4RDYAoD^F2)Mie`F}FWDx9aNR@w1`N=Sc+|*TL*wvvc!P(27WH=neYDjW zMgq!f7Svl&uR=xg-aaAB&VP4Q^P-M?XpJlzH7U6biH*kRD&A7rP;$mb-N}<&Z*s&E z(a@9#-Y1a{@nY1CYdS}r9lAD$XG=pjjTEO(Kxo01Gg%&A;`krMf&7h!nTk8o>ogz{=w4WrbgFLB<0=>K!He6+#3M4QTbbtY{{{PSaq z)CkH#PZs?obZKgtx%R@(E+2Jp>a7|m%m);Cl0F|dQf{}n5Nadv#B9?I=;X!601+!inP ztvw^nG@0n)23yz#90*eZloyZ8x_G z1SFGZBRxCbowryhW1^X_uA^ZvckZ@GE45Lf33Eyl?%z|3>au$_bM5219XH;)=LG&YX zW*YYGWR`-mYYxbi%T1vp?Lgs!#)QgR9g{6jV)`d&ass44?{oS|Cr)I#J_}Z|mtn|- z)J)yDaA#D0)lqmk->;n4>db8ZEpk zB(_4So%?u4JOxE7Fr&zCzkFp$InOc6dA_gY@`Ed%6+T-wo-%Ykh|=+qRwdOAYTh{9 z^N4`JIEBeK5m7cz;dFstRYiY&(z;!h^mjZ%K|UweL{4{iO98?W`&VmZTG$c$XQ#RU zG}S1%PNSTf$N>UdvqvyY>MQcu<F6Pp*TKB;^Jcu4SDPi6akxLiRTvH3)wtrgH3Q01z7BLK07& z*DXI_XwIZ;_a)PgF~7w%f_oO5&;>Jn-F0LV_I(4)hw1CQ=;|#RUq$=M3=yHkE;j!w zc7d3lJdjxBwRnp&UeyCCq4a;a{!S6X^9UpWrFhS7l!HuNf?HE2pX4hW#)C{hu@*p z6;?PfTOF(68}Uk~_HzQ>)69Hs9ohWFsGy~No0{-m9o9`u{1I0AU)Z2US2^6qDMJ@^ zBHys7wpr9zSB`(bpG8THA5dCqc0}(K%II(t!eg~bTgre$2W=4BuqM=_j1sOWCj-PV zCu@XZq#GT`KF^&K>e1)cV>{z#Fxz=i)JrWX}kjfZ1c(R1VaxCwF}+4JpjzM}Tcccd0_# zusKnRXREXTo}7#ue)UXv=xYx?UP*4O8}1d-!Nq;RhFfh?hWl-<&F0&|Gd)0;QE(>- za4qMm<(W3uF=MaDY=P=>)`+eY4V7GS(qh(F?V?JM(*iakQ2w0&O8a1jXXN@l?tVzw zh6H(RZB;}T{-$m2mZZi&Zxrz+G6UoABh+A3mhk>Y?23wF;NudBdz(+k6qWK! zw$X=S^QIzFhMSpaVoR&xbS5h0%lT+x&XP|RLJaGzjAub(-)RMAf25j=0`rrg@2Qnj zwCF-R;~21)b#!SHlR^$a$v5OGGc0=9<6-HiV?)6fVJ`?;nTl}KR)EZ{Y|e8uv9_-M zv5Ih-Ebii2#WB3P5Ll4F1o`vVOVfA>Z&3oU0lXuW=%03pZ?tqW^BxnNsO3=5h_K)G z2u26K@9@FBPi&ZIw^XVGA&&vQZh@m`p^1a(DafgO+|nEAJm^Ttt~@f^`Cm}*(;MMM za!b`b#eb$z^G1hQA*odJ#%j{v#ZMN3h6OVK$zMK3QNM>;6YE|@?Xv^XD0-o{G0r0u zPo>rn#L*7f!?_xKVuLUpa*|*U*PW;TveXxoD)-YF2hAnFnTX<~rbp9SZ4(j}WFOCoYD&yH}w2zVWA9t+*Rw*DcTd zT}!JUUK|MoQ_LbpUeA90Jbk-3-)H6+Y*li_;Hd}S+^dh% zJH|oK?j*Bs^uVc{@mc~wJZVW8S28{GYpAhPpUqEt>fD-Ei25$*Ymrsb&C+&sIaZ#~ zjG!1f|4a*td^br9(PVK|L#5#qwv?~3F>xIkTGgTQ@}jL8>z;DSihoRMjbywr;y&8o z=30le2qss*qpU+|uyN|V9{s<~45pNS7k(MRj{*Y1le+mYw_dm^>SVsp=DsWBolFk@rA?IZ!2gw}Pn$<);#Fgw z%}S#5yGKif$fZYLdVo56;0`-BNcZUN*WIvLT1ml*v+f0?*LpY#4?K=t`OE{Prph+q ze+~KdqTB$rxA~gaFdR)3xz=!3Z<f{T=O{q+qdOVU)B zJL|47uP2rpx+H2oy{@SH*BO==U3S6IUKmt--)iOA9~$?Ys{*^y*G|l(hQ0ED*_9JZ&IRf} zD56(xy9>Ur%jq-U(9)+gKmMR{ik0Djt=8onGEVoeP@}?hdzu*EqEQ=zZOZyReh`dC z1&`B$O+gFg5}deRe|l5$jy>iys~~bjXl_7scHp{EOhf@7l}QP#z*vDIZ|eVWbxlRD z4qTvka6_A#LayueodX}a(|H*aj@~?1zzf&*xKBOw>yJR@l1O2F_=DDegdZv$LM_?# z;B(^kLB$%^2FeDLCQ=6Z^zB5fn)_xC^2w&iCT^iA303)O2%YW39_O9hBX{B=_+1`T zED-2=1_@oG|iQk7m6!Jj>211MFLz|z! zIIBxQPG}pQscX_!f4gm>w(4>ym$Z}owtq-dQYFD&g!ddGb#))8In`d6IZ zjN3;CKw0<19Y3&mLQx*beX{MXIJ_}BIO0=+{ss$QQ3t%Er0~Fzws!G|im$s0(RrT( zyctDd$S8FBdq7-}V7FjhO=*N!RcKU39)W@#%6Th`QpirD(T9DNp*(-5nkXPq*JSdGpI*z@A-uaY#U| zN3+LuTKd}>uwA{GBFl63#wxOr-oAHK%dg!$Z3njz


    Gzo4~MQvyxD=sZ=h2t!-qfugMbQ|i;c?cLq+&|y&hmc zL2cVZh(2A=mjFiR2nQlQ&rfWmzXnfA@C6AHnps`MrtK3g*p3>6hih7BtrE zEYnYv9YLW*$r<#WD zLK^duxCC|EUE+dibt}y|3uYWs{YytzVCM41d3E8K6ian~<$#I(mPNAo2D*H!Xyx~tG#Ch6D%3^}k7a44 zScn-AnOaTC5o$5II8di8fTms0SO1#S8FL|W+g>#17KA2knMQP45xJaa%+Cy?M6cW_scOWIqx6tP`(f zg&QwipCKpwY_)!Dqi5B9h7l4{26=M*Y?^EuIzg-sj}IN#IuT2*ytiSs#Hm!uE!U{P z_E|JC$q|zN&|r&wS^k@OJpfzf8~(VD@COGwu#W!qFA9~`5^-ISzlCV@r)HWXS6hP9 zZvi!8n}aJAADezedSDnz8xrZ3S(BS#kW(Fft`67J_rL;KG`zS;EqFpl`0(V-CIu36 z`!ro&YCSJ$zu?JvAyek_M`&41QWU|{=x?t~nwrG>k?=zbve(miy5+&RSN>p*II;pSK za2s+jvo$hX8r3X>I24N|wf^W&Yv)zNLLaFr`?}+b5%Niu`_%Gz?V^JAQfjz1piA9c zGXeH|nPfOcz(ySe;Qz+40mB1`ZdF=Vl}v}J2c&K%^!2_mY;9;MU&(2CmfHPXm7+e- zO|`6(HSwjzqrvVy46BcfkWYXxDn79&2nDD|UOQ#$X%NKPWfVumu6>Y6-?Hf&Zrzy* z({iuaXa245Ho`sR7n3jk?8)~RqBw~MJAbYtZs{LWuB>ZVWiy8C)8ikbECVwUUb9V3CJ#a zC1}((LpHs+mmgWxd9>XO-@{8cY_D8~w8*Ar z|8MNG9sir`*_(V8NFgp9hUG$anoKItf+_A)PNg1;F7^7%GAJOI$CZ;4;lA7%NyLzB z7-YG&v}NUzJ_ENwMTm77!ci`fq9x0*^2#7aE}rGWfx;gv!SJXzT3BH>W8RdwrqyfD z?(TCv-Zi;aCBExBKwMCoDw=4AZx%-XzItp zpIEz@%;-po`3!80WS~Bzx;HAh-{RI$ff{-Q< zwb8OFgu*++iij-%XW(EUdrJ|aXV~m#S*0`Zj{G4Fw{fYYMzC1^Agg*ym8y-E*7wyp zZQehGyLH~81~8$9^-3RF%f3)_ByLqw>lqjwnKf*O5SJi1S!QfueKERnp$NylKi6f# z=>CRUxuVG2-Xi2aKgXZ^L8v?|O=rsD%gcs>js&do+Hf`ZPZ6XVTD!KsmKPJ+`2tF{B~SCTW3R;TkIVh{mm*>1+~) zaMqa0$Rar5C@7LO<^W}>U1(YuW#9zqR-5yuNmXS5KSEGVTquD|hAGz~pry||>7XfWR>ic`kX zEu5dDzTjA2hRIRgRITkl^HiKO(ofe-fvW1TMCc2Yrku(KpSAb#7cS7@==@cEz^jAk zr?$AP-%rHrIIV7*qMEp(_SdH9e~xoycHglu{g=Wd0d$YCBac6F|OW0~D zy{NpO&N79Kcyiw7H(0o~uJ?56gtA6xD$a$)W3Q8|Mvrv%6p-6C!)dCPU0zm_)baat zNx5l;=&C~S=9WV`Q=XGI=9l##t(f2V#E-qu)L(E-s;{@Rkc&k&DXfl&d|pKlM&vmC z-r4j{;BTJk1OgWCLlB@6Z5q#T@qhYaS~1C`qYioOqM^NdMe_ro)|W-I8-vYaBEhvs zj2T-VYNM58{IN(EDpEtGx6$kvkq_8G+|N1XIZ(!+^5MF0`fa#DVz9w?mK)^4W|sb~ z$$?$t^X*+Yq2J{b=R+d^g1f{VXau50JJsuBY6*D-A*|#kz&Njygrbp^NhT5uDWeDD zP=oDST(TqjDT1Vlujg6Ju*(Jp6`Iqm9k1{iGB<~A=qTKnsKLhV|Jc{X$WT95OC5Aa z2jlfzsxv#3GAzlL;k&3ADnWb3wR>!h1;Vh+4{F}Bf<9K1KK!O5P>cL(M#a#|to7tl zYEV(P0<&~>5Zx!Spxf$`G@qmk79?J}iT5gqupK3JZ}l0Lum7}-@&);JyZv`6+twdg zOebv!LFqGEy*x00bRwHmJ9y>$TEHgTb^VEpEufiR0@n(yPQR`|D-SrcbI9vIfXa{8as3cQFI%5Iu=4X|zc0yI z)hVY{kxd`7RGIlqxl=0BmljC1bE3-@Q@Yo)B+)Atr?9gvTuI@P)Vaw&Jwbu zqB(*dl%*-Th3h_Vb?9ELQ5+#WA2!BOZvsHO;pC!PLNT*}Uk~~Gnp$kl{^x+ZYnIk# z>03xmG&HOGq+*zo1gE@Y*$L?L)@6zLCP3Sy;1v^sK@Kddzf+0a!KUXB{88Dml1Fo@ ztdiXFcOh~?G?$s3+Grl}bFcTSQ|Hqg-U;#{(k}jZ9I1@97toMng2jZUl8yNA#5#u> zEIjV)FkOf;1rTx-!iAv!qQ+5dIrTIsQ3_MQCnmu9&*Q5^zp^vzfMzQ zJy+3mA(mTX)0FV?>_AsyHgw57ovC1nXk z=&xkET7Ix==RS~Qi6IJ70?S#vLnNLbADLPTTh#=sP$7EDC(ys zcO@cQ1Cd{cW$iRCol4d{gXY>>P&6j^^Q{tiRJ6a@ElJc+0+yv-SM?2)C9HN$mSqU; z*Unp%$(K>F|NbLgD5L(vdMC93`~)Qs&kymOY_k3PQn*5S`AMd=-hf4r_-0nL1u8Xa z&n!7S@F=~C?b{dV<=0@*rt%?K&a4d)@qQ`|9i75E4>CQ~-6B1q4YR|d+H?98k#qP4FVPQAV{#G=7 z6ZtR#)BOER=JQAf3sK4-$u?b3cEtBt$U6z1`sF8ebW<$JzHj@(-7*4>16fkqD$+fY zP~`teH#6&()EN{)Z_%94a^X)o?{^|AOnkBPtK8kv-Jt@{AV3jb!N!%L~TpX*ic?=+Ks%z z5EO*0uJ%M7=UiidyI0=aL(4>0PBiOZz?GijH<%rGQ2n>SBb}fj%=ZO!=*~;Zwk2tyMH(E3UE~)GCxk+psR$9_L^eZ6thF&#T zvlD5KO$&Hc4;d+uM3wk}g?`TVR|t8ag#281jH9@B@s1phTlqG9q-u%JP*5sSsbMbQ zy89`B?W{Y9eRpVK(`-G?fR7}te_Js)r$a_+lG#~Zh8t+KWcII1#VTX*+7<{- zVkEDh(zMm@t(D)kgb_ZaIC#n0i>ZA!(fu^jVB&y0$wrK+;Sc6)GgJBy0Q(;3Dnegp z#uN1Fh0py8;nPf?JUD!`7$|EqMXv5|RpL5P6SE4jiu;#);H>7)@nU&GNg%n63vm`> zFr1Tujdd9OOiLuG+HJo2S-Xe){yT;4sL|b6O{ZBD<4PhdByn5<%dYxB;@BAfhbnuC zW{pB>CoV`I1M-Hv=MbTMC*?8=^=IUaV&%usR_*6@CV_-fXL9de5fUG~&7VfYGT5T% zipL8E{&W8s|IRtimOs8YZ$>wi-tl~Ht0U{}Fl4A+ZLCM7NBKY9?LGr|Ly~eayYpU- z2yyEe76x@+Hw>+B+Dq+d(;s+{E5gN4kFWlA8)GvrYu7vV%c~2ra-ZK?4YUL!Pa=EM zPVD*sgdoT&vBW)-+2F-Qx9D?x#8Qk0R`W^^;|8JDz&KMGU4eeWN)q2Owa$#WGQvdb|WYa1LHlOBc z5=wc6d(8q&Ph1iw&eS(Op}XhDKoBI-j@tLPk@s*}-99nn+4Z!r?}5i$a@EOyZ_<%!@n!nAxrxoViX+79^*!>uR>rUWIGtz&# zrDzK9b0c(hU|mF|kM<8S#`z*IZxrfR{p>K%L=NM*t5h>}|Kh%)xYxN7O1h2Yrocvj zE(+}4l}5|d`kwzf=)4rgJ1Rd$Cxy83Lz!T`z>2Z2!Z}_Yv{Y|1S0!KgVpu;UI0vD- z7!Q3+1DZ=~O2$UFUwme5bGJVJJVH2GgYTfB{LuNOoyV!7{l;tcaJmuu1tAl?nx=rj z=$k0QD&+z*qAQBUU-=6-w7vQRo~pi)JpT!MU5q?lerQ?AGF=>ynw6aq6G16_6#@U6 z3!c>9GaJw32(dV7_I^km)QPwqzb^@L9TnH#!24#Sxlapsh?jhFqWt?;16`(?o+g>< znI%sbZM4v&pa%5sdZbVxT}^SS{9BZPgyEG%T}8>YU>&)<6`P|}ra?c;JUYbeNK<9z z`Kx}Q(G#o*-9Vud`Ld;7-@~2A^}|L!+Iu-LzhRQw<)3Y!YaQ=E)yM3nYB6alt?l8b zk*y`PFuAh`(d=<@nUT3s;+M&OqRULxrA@#WJ5!{*SnJ*Ue;TLU zNZO{f@Y@!#1L@scA1Aj>S5yLv_O_#5@1&0DR>w6BTHx|L(PgmVvq{6VXj;rNcA@i` zwhz5+%B^jjjV`&+W8>*$urL{;$yX_Ou}%X~zYwPvzLF}zw87=3e&?4-EE&r_9~8|m z+TEg3szD~YA6XByH0LkXsv=}5O3#~6^B9W_6^mq2OOF^YBH|I^rX~@;c%$3{z+aNu z^!9QvUD>jmZ!`M5e)H-(`^9b{i8yTj`I*jwZ&H)xLw$Ue{U0%ub;)v0cqDYn`dN-B zZcv+#w!OXw9lf#Zv=-b;uX)y=9^l-@a!Mp!d@e4$&O$l91J&^K6%kC^z9{W^m-O?< zn)OlRTEm9ivE%U0yQ$s@!gr(3I{m@8@tfb4R76jAb74RpyWDY&CtTIWNl|jzTe*~( zpS5Ql_wRX@2nsS$ zmzaDdy^Aoy^JqdkgL6)MpW-UMahX$m@!uY1@RqkI6+3_CzD&y`AaBG|oux@uog~84Oy@st`tUO6(Q{S{Cao z@IcxdrF^BW06v>F(=Ozk_Pn2$>F!FmS~)?$oPi;fPiObto(iJd8p{CA0lABn%__#V zsxu>?@4!D~rT^l;jp52+Xa45oNles5d2xXAp!b9rBCl5R(N7G~HSa_J;`)hi=iFrⅅuf$ia_kAVeE~pKg?@c**El-%1qlHD5zM4HX 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%0Am33V!bJJ#2 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 z zf;0UmV9`tVG2@7g#-fP3Q7?wb_u=Mws-@WO%-ajaZ_oSa0H-K0mA_RTkjBes5^y}9dw`P8~Pdvg|A2hC~G?zz5a-jYi z8c;kkc?o5KJI=Pv%6g@l$6DO?W7MkJ4QZ$opQ?PNBIohUbp+x~FGSMu5I7^p|A6pt zgKK#GMq&)7CkOmITbClJOXw`*yel^w5e$eOg@hC+xZ|66h1WI$t3nIKmTDc*j5~N6 zEBBp+()k=&{TFlMDttQ*xY+GU*=(R@LUn?16*}nWv}0RN);nINZY>D!Q+fq+C6(o-W35MPEV>Cr#(kl{(c;ry{z*d_uslOcw02i&0Ql+U2g3t zlml?}71Ms6!VUFl@bp7MZ|>ucIig)76Yq|2^lj>n#f{xRsAYJ@gWP>xq*-C+b=vZK zew=u<0N|nVS{V*3tEoJaqro^=_6J@B$Cmq&Gi;6X7|lt5w9T_+8*`O`)JcR_f~iY* zJGtYy5rO)hYVb&tWwN#2GjiuO=cT>}PNZi_^fd@w^H-l=uFX_0wukH$PyWfWD{vzq zW3wujQ8y<_x!Hba*q+EH6ZL5u8!1o5wx0p<+yZ;-kNwV7@!NKy%Z{!06IG8Nmq>SL zLru*`i+@(!Y?=?Tqx7Bswxu@wu>1E-jR`Roxx&cYeSRl5qW7wY!p2ZZ&!5{q=`6D4 z8Z{J+{BMUQ2mp(0X*I2b;!#lJPhLY4Bl*H4>5)6D-t+z|1EJXOj;)TlX(9c)2^0XP zF~b*`u}K_@=~se?j|cl+@wP=IyU)cT(lZoQ6F>iXqtJl(IZKE|`L8z16q#XrS8KUx z&oeuP*ImZuOq4ou@bI-Vg9A8aZ5{SCgY4nh;MaYZB+hzvS@;L;|b4* z_>Rwtb0^bNrVPCqA_eq3iJooiaZzl-)^qt9t{MFNfO5AlzvHVq+4bccfxc_}#J)bS z93|njeE1e$*ykcdr$5$zn}rw`~T&u@7Wz4u8Rh!o_yMADyCx+B9 zsGRH>a|<&`zLYU`r?^I4N8-D6&hEdH)c0#a8H$OnD79_Fwj)r)yqAofjIsXCG41~@ zV-r#Ol0V5A@J$^aR~z8Z_QY$^uHR9klPz;DBePV*jM#5s0TRmtUfU50`KS?}+XyJ; zdTZ~Dwqp9F&bBxm(=irEqS{rktjb$zk5 zVJ7=;d>Q5HdCR(%qPmynx|}m6nFgjW^g(T_hW4QNPrVnjvt{@5zHqqDJ^>Zv!wSz6 zw`jBXX^Jg5BIqrQV=Qv(&>Ynk8@>||Kh0~3inqN=l-#vK(NLBTIi;WeU{QI;N*IYY zdtsMjme%Ozh$%MZ2(V`QkT+$Y25s{%&MJx{tXDRi)k$HZ5>+M3hMJH2FCE_ny+M-@ zm6!#&3#GD2E4XGqInEzU|Ah7SZ~^ZIxR~8kp0r~|c=GX^orvU1NjuGz_LQv1e|dbb z7jGF;+7+3empyrm>kly&M$*@#*&f`Vwe|P*V3pcaW|`R^K+Rr>XQ+fOVM3%?ylo5o zL3v?rq9_#mIlOh)aG&|(SN+UyIs#uD0n$V=km`y;$%zroNj461voHNn$%z6hqYObe zCz+0!eKD$-NmpA%0i~N=xu<=SMfR;_v(+FmtjSXn-?ikd^Qb z*YC94`H72mQca=RlQ_?>>J{#Rqb^&So9n|~U|(2(j6oMUp1V!k7amZj<;z7S zhxGpOysd39<6V<4mTCSHh17=~%!WC)C+$}b!08TB1Eh)nL?()4W20+r8P)Sv_Ki2R zXK(Ugn8JFcToS%&YjesbnTa10f1DS&7*34A3>%y)(+*i8w*7Z-u8e-ftbD7tk0~DS z3}&&orva3i!=TGf_H7pe#=2RRq_3m>#Iwg868MyAggX{-2!Y=jlvTk`LELm>#)`H( zI7M&C;}2ie@*%R2n$sDcGC4S|9n3-;$2oTa557(`v$JFb>r9wOfkif)+&^M8>3`K= z{1`$E-2%{(<^r=|y zOs91S{LI+D=CQ5;GO~Iu2$vuxw$XVWbVlUPil)qlS5Q8!<;kg{db`=coyRH-u;SUoreNR{8&8!|J9e z)7sg+JejI00E3P(NgP~ty0=?s=In8g_D!Opzq~4T6CbkqVAmp;I+GBvr#Kt_SiD-x zfFZZ=S3UKaItX`_0qAe{U1br&xHE>X&kMPdcn5r_pZXW6HGkQRRcN&J5tj+;@{pFT{mA(BMb1Zwk0aqS#DB%wm*X*t6wbHu+e(Gj^=;6 zuXt6Q%qlh@>dN^jLlq_DVx?JyW;jq(1rSoAp_#pE@%MAlkCqM|_s>YPHETaO20wOj z^2IbT?e^)i&PB?5rhxHdslon*^_J2(Ax876iNWUS=k6d&Qr?Le7 zb+sQD6i?7mm{}Pa*C8P8iI2`_a}S5e-hVC{SGGOpatVntQP zIZH2X&MNO3c(Zrjb@JXCjzau#Ru|%=K$0G)D+DNz$mk0!^tvim=2O!P5t`NU&FS~! z&u%r;bpuw1C1!>IGZEKpN;{dNvIh_B147^uf2_}GWb|a{`ugKqOUPiVKS{Si;DF=T zd`{zfP$LBsJa8>3D;~V%fb$R22#0b|>Gumz@f(>e^hdxgwuL&sxx`v=&IYU5x0%}W zv%nhn?r4Rh^X^gu|0Skt_B~3RTRr{bypj!^7`&NPUHX4mJgy8YQ2%##UA}(YcnjIP zXU}cFi`(%x>*%3bM)d~Dw|8?l50}>I?Rj%2E^^Uv?D!ZZk&{TaDDZb@ zKnCG!pg#+~`oDEWL$z~dgyd|bY~@+ntgjOdF3fDoxhQT=0j*q=l9MIUhCxcU3_NPl zq&eb{gul{VRC~4$!Oio<{dgAcUlqB)^<;Do72h7Qp-cy1WX`|2@6lrL#wqMft95NfEKgli1FxckGM$iuH)P1hJ=}TA-?oo|N{tFHr!ke^J_I z1Kjt=&h{zXjCnZ0kJ{xJXJ}9}Ug)XS-!QipwlXr12Y&Gbnk-nVo#BWF_ONF4x*os_ zc3Wjg)8UG=FumqC7Fe8hYeKy3%g=$`f<~p3)-(IP_URcVNhH4BnC@Ro4RXh1Qsejz(~XghjI!zYLs4zm z+FDAdNl2auhTrOmjZ`Le>c2J=CIdDuny#ok`+%J<+s1*{dgR2l1StofgT5~1apXI|stC|kpiUa5V2XncI% z6IMn3ai;t08>OBca}*Df&J^p7vE(-yW^H#@$&SJ9aOF{3`VzmZ>Mb9(2GvB#sRSs* zd*gbHJw5DXG#N}?t);L6n4@AU%?&wM+uW6J`+Z`*iRDaL^xI?PjC>o>(p#r7B!fO_ zrpl4XdF6TYUxetXX9~3YO-)d1V4^L7%PVocK9Ku1cRC|W+}JgWtj{=9^2~oQqtSVg z;UCV74cW5x^xhDYE3Fn2XFM5ao0GVBVb4JUf{t8 zviA&QJMG!xQ;<^#PRmGpyWDUrTc)g(2@mz5jAN`eWe1yX@zu>&JH7#pTEusGM>*GW z|FS&{2!89q;oCB+ocHr{wtr)~%VU1=tt0KHW(SM=gT?43QpBEF8U3*tDm_eY{0$O$ zdjB=EeKb;x@(d+#_abs<2_)$~^&51Q^yWla^aXdIz9D~M{5pS~?qxJvv;Bq~k)P%@ zZKrx=g+KxJHqD*GG@9?Z@;AS>HP}_n3*A0Z#9I;u_sl!cr#=aDP!BPlU{h z8!#5R6Vv4a@Nez}h&mnylM`sBU=?6j&uS2x;{#x_M8>F$C3-+EjS;mBC~2?pzF{k> z*4$|gOo`^R*cm~d;X|2tef2tw&Fd>&S%=!E4FR_+YOW(xz6ovXj-_pSQ^eqgIz)LN z``9B7=D%3)LYL4@^z`I3uXN}GAKmKrIoXR$@$0w*BjufTbUG8uDky%2pNM?1^&UUG zBp0t^jJdHVG2tF?GDJT+|%(MKReDb5;2-LpKNpOu8{3RKg3>{g8-o4*= zY$QH3FmP6;p3)MGoG2#$OYA%~l25s{rV0#UlUNjBWT(G7bAoHGhi9%~gXbg=I!xcu z?i3LS)Xt&&>9vI>CqckN5c%ZFmd*0mF$=7d^Gw9<0J56%k~1E~8NxO`5ss=)=At-L zX7xC72%0zb(pC8>@c9^|QMl@C&r^)M&S?Q$-PH2L&{B<#TyY5kJv^r;h*`G?eBN!4 zx*btgAKl;fg-YSMtKZe`IX$c@rqMFzn&n7}Kt(^MU3@6qNceCq zQ=VW*mcIkBZ0Pl-bbh5MH1yXS8M~^wEqS~DkMk2#`(Zwnp30QW3bZ*~=pmF&@ojEz zQ!r1mBB3UUt%Fx+T1DgW{_iNkb_sUN?QU<2?03@KfF?-41fC!yD(8P9c)>zfRmWbN{*}nEz!$67N{%Y>{pDdN* zt0?Ohj9m}3eLG*c`LmV5k9IY_O$_rtT(iRQu1L~CFPuadzTUZHg9VD&vM>-a&;P&y}XyX5(hLog!!-0)UrvEChtCc~ZeO26e@RBE@ zJ3CsO0G}89QX~qh$e<2iNQ&RScFJE2R5Qh z79a|&^WC2v^;{Vp)pIBz%F-eAN=4lX%%pS2I(HVO{z3QR0p<4#5pq@?FWHra4gEB0f1;Z_HRSJU*%N5rK{6%mAp<5C>(FO zRLExjc)8TIoqu!<*tuavukdhm&4M&gCu>*nLCB2QZ_b~A4W3&z6VpiNL|d&;hNnK;*9F-0 z0Sc&e2-$q6cn@#gtNE#Cm8@*}b4xoW@?HMjS~9)U54f_1i~T!aT?W9Rjl6+vuMJ)6 zd>D)w0Pci-3h5rVj@j$R6+e5zg;)$TqMw+?!L;V!BRl_!WBmjE?Zb!_hZ{u=6a_&B zf*Xh6>9ac%T-1Kvs+&YgSG1k49G_9L@i225ALy}qJkA%1=be=-4T#-|2&YT+`|m1$ zc>=71Gl%qg3CiW_(*E5P|7IY4x~6+GuDHiJAo=an{B#_T?Lu6e1Z`7TB0KOkKVX;!mqAY=MOoAPv^93je@0_37C}SQJGlVh2zomtec}>>5kVP z*?=ZZ)@o!%58-DIq?N{@-)5SLG(QJB{e&`AP+R@GxIC5SKspRi*K=Q2sV&Yf(mtmCGQjRzi4dOFHTaNn)Y+mJOtD`B~|)xo8pxAbU`6G6mVJf17SzGUy8@u5D>?B;XY{}OPpiG~5{9jErBGh;%b zB>p){0$vXgi3no$fcFaE1g7bq6bA!SHmggyGIwAkG@xz{rC0i>u947d9bbn8coB{i zwae7XzD-~Wo^7?PVFc>Vd!cd3{Tsj$g#QLO?Kv%K4f3~xlXeXy5Qfn;ccHIKo&+D; zL;$K5!?nPf?=sh@Ak@l%!;AdGU9z8p%h9u~(qc{P&_2xTY86JVQ+}mu0@c-VrhLf{ zM1oE(DTAZoV{&N)V$Jq#OD0E@{U37P*P_l#8&~=lyBE6sC+|Buxn}ojcH>{A7mv%O z(H58a$=HogRo}(6U8@W}a;sc6`~-Q%WS2XGe^H^(l<-&Sqn#Ze<#TcZw>Z0HFK20C zDCHgzSo{=JH~dhr(tuDO2Vl!jXv$i~P3PW$D+imYsWaOf2)0BX>l=V7;cloxrOo-f zlUrJ-XUvL zK;2}Tpq9U*{Tz-OkJka=SE;8UC@imJM}}qzOeg_fK7qsVZ9f!*zAA6`M~?Ih#XbQx zL}G|4wb>6Bpj5VFNEv;bA7^s4_$1yaJ!vPHl_v&#V*A*@(9r#W?^tp9Z-kS5nE@*p0MFj?c3)qvCL(li{Y2iVjV$bnf( zvyH|}Du(-)2dF9=QI{?bz%3J4vxm+^+mSOhpP?u}eIA-sw<%i1QW(by!Bj+HT*Vcp zA90B<2e#7D;1Ei1zHTaD2B#`3VPT-2Egc|{^SUJs`tBk zDKC(_OFpi>qC_U59vpxf`mRPlHLAR(>ZT-84L{wL`ehMBCr25Yz@AVNI8Wk|YHZ+F z(M~f`u33nYa>}UnS&EzS3~{dm+KJZYfSF5WcsLl%m%j9E_|)3i9_cVOjGx|{(C1)d zk1=Zn3jEkgq8l+D_ofebsi+mItXvwswwD}oZ^fAr+I;(-s5^6+`{{EO6f3YX0o#fW zm&rGLN=OD_BRd&@Bq@_+5@$z3Pc@FZCWr47V{y}q&vYT)f(g z2E&M=9O}kw^pV;sWsW@4fAnP9RJG~n_6+B#X z`m9j{Y~YWfz_T*8DgGZ)18;hvx8mBsr`pU>p#51g#U*W&*FR)^BW(Z z8tYeM5@lcP_7VfD0WZq7C5KU67*K6*T-QE#@D|!gQt??nP2l3$`3zsI69EO<_o*9o zQ4%t@CZ0en8dd4syv;;jpj#7{@0-B>v)QS~RmMnrDZlu#%tTAnkVL=SRjIMK^&d8> z+hk>Ik({Q$`svmwhp+NdG@JMnId;UhB0csdZ-S0L%__QtPcX^-hg;Z6sRS|zAh7J> z17Bd1HtR0?{j|o61lb`F(FfHx?r|wo@aS#SGIbh1#|8c`^?NH(s%s_~ci-vxNUMbw zsX}`;e_TyEXr@`gDXy0w%XmY37x=vWAq9krl9PP=w>%VFxR}bJi93XNjF?{UJ!=kV zU#?a%O+3s{=LEM1wCCJCicWTww2=WP^ab|H9+9Cym6J*zk?T@3Pm@K9Zw#@Q(5m~r zbS}BHUlOQ(>Q`KPP9v-MZzF_^07N(P%?c=VQdeJ*SbR(b$>zVl{zK6kzx@A}T2*Pa?s{ux)_M0N5p|&MXMe zC6Gav4*R(RKUmTGf=FhJl>TLOoGh2&%y`sft$YnRQJ-kJsI<(A#af@G26Cjjw;6?V zx#hDSrG`|OTH@q(eLGat`Tgx>B-`{{c)DH6Htj8`t{;Czq(GJHd+$shai_|eADB5> z26Ks09ie=9=B~hz4%S0s3N2=M1#FqlKoQc01p*tfctgw&rTaYWoEVQln!tEshNH3- zS9{YYM+LJis~mSDE7hUjOmLrp24#4+>mp1x(`;`%_>#<+!sx}>p9P{uT^FLtj5i`$ zt+c3i#?p^peMl}?)@UnZMQxxf-D$w`u%4zTi46(`FZi*oRl)==c%&6zuCLrSpcxty zVV5b6*FpXKXO~*w!7%X@sn%3P9^l1nu8?yFV=W`^rTz{rZvvD=R*$Vel>HkfeW`Im zy>y`O=Uq!n`_MdGye*3a(+sz7f=|;msc_x1j*vaEKbnVj?00md9{VmQnTAS8AvheL zv66w*8jv%QIMrB%6i3fr5AaAy_0Xk~H?|wL!HrCFqiXuZ1TP46XKr8B)-qSeYTBlB zlb|FOvysC?X+{?-81Z3D~SB zYhNt30d zqV(ZQv`EcAofZpkDwakQ?N}rXj7aAuZn7Wcpn79B(qm!P`sT&mxpj^BoLN82W-`x> zY9SozIz|m!n!DB1n>wDfa7udKb1^x4mrS!|Oo>H`%U9jfJn4wAx)D-R%`+Z z(at69t3QOTmHRT;oAmJ7vABWE4T$@uc-0vOQ)?a2$v~*utuj^GGGvquDd=kHf|`o(j`$1vJykN(X+!(T!djMScEB}zXrvc5KcJs)b5 z`_}1mwJfy6W{VY>Wj((!n>{_LHN$%MsFXOPBJv8&S$^{$aA>33_Tx@6zw$$|X~mr1 zQO{qbk2LYB5B>eslFRG$&@P<&->=$lv5R1gE0y#_jSRj;=}8)%`&#x+e+)LV3Sl|; zSG-K@HP6HL#UyN<>L`Z=#MV%vZz54(_(=*G#T7DR^IsVPhre{xBb|(FoIT*`tI2KV zVzYWhL}sb&O#570+u`~&DNj|OUKj7NidV?T=K+lk6z6Zfo$=1ucz^;O_w*y<}(1&|Ivem+a(dKufqE`4rF$bf5 zgh7?)$r#lY0H49fF18IxUx#nM=QR$TGaLe(dbr(|tW8oxZM8rr#?rs>4n4-)jK`=EXB`1f?1i+PALG z8YNeEe>6|L%(GZ8Iupgs@=Q-;K@e4)I3DZLXQKW2W+$3KAdh~iP{^z|w0{8b7<7iN z{oKE$*T?<1d8!Wz-7^xWq0ec>yZ>RsW12_@v|b!`x$;q2FotPCHJb>vnt$x)(X%b` z#_hHeP>>u=%Fr)bqA6P_b3ZaH_TqHLhCfVS2v*n)s6~OF)hU(-{=KgQf{-<*OT2qp z7?A17C;dXg7VuX*wu620{+uPd|nf$jHC%RML2a=5{ z@NjE~?k{gE#5cj`hP`5oa3Syhu#)s~Bvw@=-b56<|8JqFQIq$`q zt2CE^8#wfM{xUO#nq;;9rM8G9Lb(mI(ZQSf$&%01n!}&lh82(#=6nI-ozvY9HC!nJ zK0vSl8s}Ihu7`q0rvwgw$~NZUJK_cdPL2ryBDz5pMfxC9Y*bEQS~;858>MN|h}21~ zj7#_hfr*;8iCGYKIQjY8;POr*b*5?Trb0`#i6Q zGb!}Oi`-Z4PLvW?56cGtN$9Z}2W%o7%e$NKh5a2s%My}99pX~S#UQK>RPPLYIDeO{rzAT2}R6_V+sQC(rI-r#023~HLozbfx;PAN4!b{x!r zuV{F>WBW?FCh`Gu#h*P#Hu*!*>Wqker~gikwd!s-94c(&e0Hg%tB8FQi;_B`L2+iO@%9Nfi6+S=J}XbQPzhD@Y2H&lz-gR(5w(;&ded}UDl zsDo$L_uaSZOBVT-pP(7+$CS>83?b#~+s=lwk8K1pDz_kc#S;|8{$s z{nGijYu%hrr;_d$t2%2EQhDu=^TVew=sZW0Vu+aTgU%Zb(&R&xgVU3A7H{EeHO%tj z+u+5=&uG7B8GsfQF;@WvF*6w|iML+CQ0i?uL-OSaHNT}{dtaTk8pGt+_h^AQ%NqIG zNCb-~tkRX}z2iab(9lpTw&6*fCT@kt2D#BLCHt+bt08Cx?YYU$sAnGr^*bplJxB!L z2wq+xk$qX=`pSX(&unqNGg<5K>Nl_vF^xcnVM<=@H=7>V#Sf1ZPVEIF0de2^m7K5o zO+i(*VO&7Jp6q0J@iLWxBGpuXh7qNwtb^mraftGwiEo90HbzeNU~C_;C;qK7FX)V; z|EUmLgw@&40hgr$8v>q|u%_`gr#kjd-PF7Eb}7Sd-%Qjj(1+q!^g0QigCw)OFV-LN z3#c|CUO|^|FW3NeuybS=dYR@DVcqXK^*pmQ0z$e8MtRB7Z5!xMYU0HtSS%`H8smTL ze-pq4a5J6#HBrPQS~ue-L(?6;(0#v@GBZ$i<_bP|Dqvw&s!+oI0%T@pM=A|k z>{TK)k`jQSlZh_}aX_ey+psi2ICr*ssee<~RSnuC_?ZPs3?DBJ)ZdudflM3msA`12 zZV-Y#tlXz(6NQMi0Vp96dPh&#s>4FhP4ojZf63-UOAq0Dg zU+79D3%U6I!7sHsV=|Ypffk7y6G^DUJ4Od4RE7$3 zdX!UA{>_tml%!J~Bx6|im&|KRqk6EVP@o(fwV@TxXnun!y}8LKKvWT{4Gt75sC4o| zqZw3ZeC_#4gRG2#re>Wzlyc~au^pnIq9}FXdg%*c=6<(I6y?w?4zMcQ+`Z6(se;+F zv+5h-b>ctUsQ(J7r;qC%ho%$KLe|Z0bt~*mkds@;A>(h z?g_eajR|_;*Z{%o@i8)|nuGWRzp}kcQSDX^#^6cZVap6^nEh0VZ(X2 zDa*h(!)_zM-$=X2@2~V}4!_sm7fAJCa#wdT%y{@m#XAJBQkjQ(si_{idyDG+&js zAVIz@2XVL>B={=7FghxpBZYAF(SAnDfuDj_1I@&N43;NbWaP~&^BpA<1*T!g;#Zej zWLnBzXW#!I@7K5LFIUFCDtVi;ct9XeF)G||JPRdwc?JJyrD2L`Pwn+rwJ0~)TMNMa zN{l$F`R~q}@PoA)5cRdrguGl5G(WFgE~Gq%joVnvpJWsj)~zKeEo{=fnNgQBu{3|g zP=X!lV7!C54r&jxe&t&jgxBg0RAG8kFVJs1Rg$ZVIO5 z^@J8U*h(vsh7gm-tGNFT9H8yG@KNQ}_>=1P@S5uX`z}*s}nI$T}QtI3{050v%TFvXu4O*zy((kRuh{0Ocre8&~^MxyLi3qgM)QSo|$HN zqICcC+k!HLV4xA##F`WlYtVSJUMqJXQMz7D{%!WD|KyD*U7KDF%^5M30n}dFasZj6 zhD>OHJLW1fuAdGJc6RU>b5>sU^d8Q8gVeHLJZc&?iYt4u0!=cnhLISgAsb49nkJI| zO^I)9b?+dHr^3wbZC%H_u8Cu44);U&lP_PrxQcmaFQ$yk1JD4?wIq&{>-X%_`77f7 z(9E^cg*CCua@6R8w3EtG@D`2$V@j}>l?}N;=DB})VB4k(Y+NEs5JFYW6d(weOq&CS z??KpJXl;IP02tZt)ME7EUEUZOx=)_I%8WA~N%|wnl4B-Y9d-y=+P0+<13#{{m;hF< z*5g4eX@2IKBFI@e_8{T_?Y2ur>3PS~)c8=@hHQB|?%Gi*c15VHC*zc!6^~ORJhKc% z+npD0i(#vIjXP9mDhwl*#!S{e+XKuQGKLW@+{`PWkJMS1&?ZcuUe%M?L~|dI7Y<1T z!9v}9tbUv)Ev`e$s?w-t*sTSx9AZfc~>vY^Njw>!HR{_n1TL+pqEkY_R;Bx+T(JSk^& z;~S&Xkb0zlg3g}$5gQsQwOGa-tJ4ujE|1*Pi5W|#6dmk*h*33jpk6OHmp2q^=x9eFFz$kfK5>W+D6@39zVE2(a;h4g4QYG zZ2humd4@J=U2u%WvYhI&*W>S69SuHP7TKWn6HjcR3`KT zu+e9Rw)l?BDq;hm-ix98vhEbysc;wh+G)s%>esZd$0CzsV+kvbsmN zo8oFBP{YhW%>eK5x2Y8yUZE;$sqia~G ztkQ*?jNNN%a^Vk;O{Jrzum@V~qcDK&x%!2g8rnAG#dZ!m?nN6xvS!_fkq?rp$XlhMdy?mER~*Hxj38oYvR8X{^{x|dryLZYAJe}kX&LK}b4c~?(@Yo9%x42rp#|B! zqjbXXQis`T-5)MiYkls+K<<`d!?&_(kSQP5mIYzV2H}iV4uLG zYZ%u8XTmX1eySum(L|hID;BHyxD{1iJ#W&`mUms&3ywWmw%8QXTjH2ZtN&=PArnJvt}WBwsh_{4wQIG$UHP$CK;&EZr4u1u| zwc{Iy7=5HBAfRdJ2Fzvj^3kNH*we%zGkFUIFm2ua(oK_roTSa*i$3m%jwNenkPN7! z7@<&t4-h1v>te>Y=QPoRZ<=y828J&NY2KT6h~VcO0$p!66~8kOP|LkV)LTy%f6Pg{ zx^kk5gNOlrg-v9hjN)WNh%-7rUY1?JDd%gol0KD--XG?C2f}c45EY`DO-+!owclu& z<%A*4=%jY|XIUxZDXEQS%enxHf*vEYz}M&S+c_;|cW{`Vz7 zrk6%_`AJis38dX$0n~c0>AM$t2D)To*Q)MS*Qk!iRMUxRHVSmYd-_scL&uHI0r@>g3&w%u>DzDEsbeHGp*EnE3@nL=NY2AGO-G`Cnc@+inLsu$gANzsg z$3|6C%CtduCv8b{=_k8wJ({*YT3x5J?1;usIddtKV_kWwmn5K4^I!wZ$ zzT$b8D!#UO(Gq`KAuM7%eKimMx7!0NN70Vk9U-2E5_?DOtk(2)g`B(*i6KUF!+p(V zkJFwScS-i1j%a%&qwvrUOK2ih-kA8!TdsL5@6n`p=_>AzV{&fyJ9D2D@TWvZw@T3dnso z5LVAtK<;htR~AE`^bflRo40>VK`r-dH!+`_&U)Ge{!}7X=Z`++1igX{f5ei1i6%~@ zN1oua#*}j)6ZUqVyC<8q`E~-}@Lx>zabt4({ZB&<4C~lHr(cYW1P4?W!27z3&5xl@ac@5Q!0G>v+KGTz_g9u59;zXirI z)7ylI8&1`civ5+V2({gcv`$X;^nwb|)9*YSC0YDmJ5OOQ+Qy%!QAhSh^5;nC@vFzYd!c8Qd(8!VFA9^Dva;_y&A|i^m*nTxMQ*)?&_+ukn)A)2z$BEBSx5F z8m5A6V}n{FG{>Lhe}Hp|mP!-jwQ=(u=z59e6!@4j&(3Uh6G{kR4vIajW3#KQr9#mg`1p+#pK(oUl%ZV{UQ#GOFPgm zCWz!dfcl^;;ZVh(o`n2iGo}8~seAM&O==?X+Qn7)b&lcojftp=T>NR>;Ugk!Z>N%7 zI=#&su!z*F=9}u`J#`KKy1CafkBQS9vpr<-naK9&vE=ehb2 z(5LT9R$A3u)WEfE!&CoU@Ij!mszGivsiQG;8co^gdEXmHJX^I4Hn+ZWPq7H>{ZWNR z#8s-4#-GWBIFz`tY=!~v=C_XZXFOQIXswYbOd;~|T)rV^f#BQKj53bn|do+dq zb3=p9F^z=#jFAF9qM^?5{`Du?nQajU?-~o{EamEw6$h(5*0}i_qSl8hVSt&=>MJ!n zDmG8RZT$kDo7(yYi*94^ko4=*k9`!VegU$0sBu^K$InDYpW%VYjolwTtneqN9-^-~ z$^WTxO$Of}&KzC-5HuX?L8Zx#^xA)&UFmoq=n$DZNQS61TkZL8dg2bn^Fg?muOvKh zM9D1N5b=(-d7=*vW5!(=(D~W4Yv&pZi73v(rJ2sEE6D(=uEMZ}Q3gMsFu`^`A+w+Rz5rvZM><7z*sieW4TF%uOj6;HGmBpTm5)%G48EW^B6pm~#4d;J~Oj&6+#bxzP zIyimqM*cKyWJ~W*>CDAioQG7UCGZI)c^6YcL(WJHYxG}|9tKODB(QO>*9*#%8Ivpd z%sI_CF0#4IAac!~vSSPQS}uR z7_4`BdRXl&P6!wqV@VEtN_Mp^tQ!Fb8I5iy4Tr0QOkRbIoQ|ewbFc~sUE6s3Oc%~T#TQdC*^|iYvFvK+qlwK@DbJ) zwmy47iDMse)_xDEFKyz8aZuKBgIQ?E)V4I zVeTx4iHgEZK}1V2qF6!(0yg((SnLSjcB4DiX7pw)y5s-=4rV6ZPd9a$1!r1311%Mz z*-PV=hal2M)_**8eZKBrvLBj!DD4&q_dT6u&ff1=6A%S=B8BCVLVv}>^)5F3flNAx zfn60zsEe81E0-oB7>(|73EP^;GIe&{Ly@d6rP|1sw=^esufWsJXy)$8{`U{)6b=_? z!$Iu|E(nB+B)?|;_%+QS^8!;6-azi{#N9?t4^rnxYi>s$K7v?=IaiJAVb%#SnG6s{ zD0?iYC?xN*bN6&?LOE9x7>XzxXK!~_Sw=s-2q>y5=7!O^ z8Db=f*YQ76PXuj$AayjdnCbUuH+sn#ZB}AxrAO~dd+9F z&DlVPD;0FT;8Kx~S#KcS5Bt?^6UN|9)`tSd4WpLZ9+5$&-y(I{;}F-D zx+O&*cdy!9W(R~Kbk$LIj?LmpI}4{pPMq1<=xTUfZj$dr+wJ#L%oD4Ue41S0%aePf zglao}e9Ei&d!t|ufJKbKxX+@UBaJ+_{7=cMUKzwjGc?rDF^{b=iKVLuHmAny{W->= zDShsTdNWeUsz?Xkp;zblbu2)`sJ7G&Py3+3dP(g=t|6sbXF|A>&PJ}G$|=GIX^>hz zb1F5hW;v4ndted2p&-!sdmGK~seJO~o{>s_m81#s4`ak|a}Pmy-A=vxGpVV*G=uH> zcTed5Ti&r|r@ZZn-ppL6YrmUO=g~2@+!JilaPc5uRqab~Wsq zg!L9%Lq3b{J>RnQYnMk=`S@v0)%`Y!kJFyNYUe41&(Kz(8Ab)E9&b=OVT6RWM)2Y< zpZ+;#c)FWWj>XboXZ+YXzKA2df^Vljv-bBaE+Ojg8z?aDKII)6n*>{ruQ14oo1y;? zk&5ZQk$Sb>SigkzJqm9v&0uuvsaJk_bbXAx^D9I>q%b}bJa+3Ma;-0Zhs(XN+5rDX zclB2-4pF|XtT|Ish<1B-V$&uB-^sDi>UzkBzHn@x!~moi?RJ9nDQW#rz^E#T3a#*D zz)Pxn$HE;TL&)Vv=(N4^5Flc(OfaM=K!-Ls=w3JdaQ3R+O|*yddY>*TAXz0hx?TQf zx^=6}$dmcoe&fnqk?VPVETnzfD$dn>2VSz4a~#3#5&00Gfy88S(H(n`Z0jNLDB&X0 zd}MIcE%-f*XDuNk*&s0^-ST;f@vmF-BXa9$LVgSFAf^%jT#f33ivE&(g562^MKV)* z&>^DaaoRU=>ftah5C`vZAUgLN{UI&who9IlkQhV~o+hQOF%)X5kbf^nZ<4R({{ZFo z(gthab$3I)8JP!&V%p_!HP_p{dDIhYDH=Mqf0s7uuJw`b6`2AY9nILc|4K3EPxpB`i_-rp}ic3&T4XSA!b2SB%R zt~&VLWi^#_7PtaF)UKF*t#H^j0oUj+icYmfMo~u z!m%g1t3W@?tnV!W#)l%@Sz$(|t>o-oFq% zqR}T0+s262*Du-{`a#U20F?Zofh{G8J!(G>X%6I16%EMoF3D+xEN^IE7MxY|-Q78S7hx`i z%MZDWXf9hzeJu`Hd*5ZJBkSFu^jbQrA^6u)v#8Qe@q;;)$%RAe&23sN(GW@zw`R~w zoBV>piVj`-a48f2!Q}UU?H*2`gGbTYQzl3I4mpaJBzy&Z63yOqTaXfEp_kA@0{p~W z)t<7HA}mJeLv+$+0C0kbAk}XgQy=8(THw6?@(}j~6yZ(XmK6_H!x$OVk;zrZsNp~* zBQ|5#DnjOsLVB-vGXDi+yelbKPiN}xHD`{rl>AZA=*iDndVuXiGO9VxwdO(P!K%~! z^!)SnE7~e20gl||)%9MkgWNgs^s^u84%T7^PtV=s4%3+!$muow6oGQtIamSkg*ras zv^Lfcq-n%GY)x`h9Ej(-=&u3o++l#9Ski;N<1PmqK{MM#1Z*I)gj|LWzZW+QJRHR@Hy=K_Eg3?ppBuP zL9Gl#lKBtc*`q|&xSo6p_KS<)g$&Gegx&ra_%Gq+gYkKZi643F-468Y&@_n9Fa8^JLmW2i>n6f(L6iI?CNCJ@;H- zuKnV8l3heV<`$yruLXm!Lj&B=J-RmH)qt4l<&syuSv2m%<|dlsmhd^0&RoM(Ev`eW ze$D7vd7CCWXa^$*t?PM?hj;r?YX+Ni=HzydWu4&XGtnRJ=7kSXiTcImcjxr3IO}T) zzFcSA2t|F95Asy#IX9;}CBHR6c|ECYT|lP-N68w9Bj1c_-K)Lu{N3XM)u}-8m7@BN zwfqVw6XMR^xvn749o~3i`}%PAMx4m!(eHWi_m-<)R}+z)S^7-WGzvRz<>jsh5B@G( zA{`!RajM}+z{HY_lj8RTLZiB_p_z#DAiBhP3S8;MTtQUYzDgxVq9R@MZVkDwRP`iE z^v#2BUmd;zURqVIVmS)=5?-(Lhz4QO1~N%rP8k}y%>2H% zmxqP>J);Ma1b4SLi*)w@3Wg=rXQdi2*!^Y-Lum`j>#mQcp6{8Y6gkI&!-=LY@_BT@b{{Y7YbeFpdU_wnpF9FV~Mc5=&F1EqK0XaD^2u zT2#8@uM<2H^j3hK(3)_FQvTGg4nw5ZpYLN%kkC8G&c&&o@bLmcMtim}E?I2Xb*#k{ zb4^!T9Xf*15ofabM~UAhSy&q*_I&$%|C1ZcJn*Sf`MVuB5%xj<6s}^VK@*)gIz$f# z|FC&^6&PuN0RE%l6s%WL2u*YN;eW;=YGBp$2{H=AXY+Th983xZ2;&?VHjhx8EETFT z#r@D(aKw)M!PE*iJCzV=Aupvi^t)#L=(c;2OI(S50nDFP0aHPy2ZX)XEX$vvs4|>C z9bFXrogA+{sNB)kZ2tj0c7V~sE%^_0buv>^^qqaVsZ$z!OSij#p#6!B3 zHxBdvo%g7{D_izdC4YS&D;=erF1;G$mYq^0TjGcwubfJxF?n!v#fj>%S^h}MC9Z&` zAli)+ld6ppUVMEekgCfMCAfQ+9136+6-IPr7*rdQuY`4)Vx|iG{!-{50GpR#3ejZvLP5O5!;J>ZVFo62vZ6VkUCV|-u26_;z*NYF~h8PFC&&Yu3c6tyv~=r z9+umM8EMfQ`EU%DxEr<)G!>wR6YMyUFT z0;gm5(25TZj!gDc`T0Yuas)6n?s}b;1i^Lclr8K8WGoT+_L3)N{0Dq?&-}{z+M5>Dp-}9IVhU3BeSJ#fILukft+wVSLNQcd8+0#}>G`=l zCvo^#RGI(t3&+r06}Re?4WF|dEAJTU-+4w0T(Vp2xJxss7L(bs(oQttDXiv?Jw_Rs z4NrviF4NumGoEyScfD zJ;P{ru#>L(AFPHp(XeH6iz4S-@Q%V93k7coA8T3EEIBsIVlNe*|DMUOP(yDeY8bAF z-d=2J;VWVQDp(`RlxE$tfVYJiH64+de=0rSJg-$2SkDA|KNMH@~6f%)1dXO|mYPoNK7qw3K|00QgP= zK}x1pc29&%l|vhAtL9oYvyRN_OsX$e7+z?1!5*%$FqWTtt4}bdIcHqZ-mdsO&DJ|@ z(;neFD`&!A%8h8+IES|Y8fO#4l#!?6N_Xlj-%!gHJFB*f6#C=MIas~dWZm1XQuLO7 ziTFAtzXU^O;hSHEM>q(1e<|5wjYhp z@SZ9i+IibM{Ne~+2n-fO;jHx>X%d8XE4~y6oC?RfeFsu_Q3XM2 zjWCwkeO(f>GN+eo5sRxk{dGuwn2B8&gbN^}g2|`~f5V6v)nR7a$ikXez0x@s-bjS@ zrqTSXP#E>KFlP+vWB6^-rlcC5nh9ayA9~Z1&!>FIEIoRn!RIxu(l;Plu+6Gepw|73 z^})fWUd-e52UbleWJ(332MDyYX8ZE(p>Su{^-DOx?LHzB9Yzu=2UQ_$F%~F}VO>Q> zDxDMgl0S^~h;Gz-yA0-Hi>>Aj9=%nNc`5(P312@@|0v6=_w$aZ9y*&dGi$O9v%?j! zWd{?ZRf{a$88_!vtu9Pa%Uae+aQUiPSe3GSb}^`{|j;=N&3`XVo>x}?XegSl&BsO-%=9tdSSR~Fxd z^(Ghk(I-?3n7`WtiieXhEi9bUXmwf$C9MHO2Q$IW%4QPT@pXUG5{hIAfYV zBws@h7NQ7_AwNW4yKBFn-oR(pF^!6c-mYR)6C%GI>1gGd^ax9y?x*oM_?N1x3TP<5 zMb``}OgO}zwqJn7ZNgC7wC849Li{yR6oV1bTXfrHfbc>MFZsa4-! zR#El#OG!?rtL`m2R$>J$X*8+k+D4v>#!uXudco40v?72amIn8PKj#R*uKmWbH6jMY z8P^~7CZDP~#EH*CS|Zu~jHg-ma7OQ??Fg3@YU&@LLtWpy07#U95zKP8_F!(}YtiHj2@Xk1D<8%RD}B zS&@6Ftfp&O01{(w^OIQpLJ+yw99x00v1IBi*Jt=Sr44b5yWze+Fwx)++ z3#Et~D*tdrJb%$<8WnnelRJ{wQ>?^_pZ-30>TWcB_e&P1=kP?MDKXYf(4~0D@3+q< z28=)DtE0DdZK(-8rj@M)OhRa{4r$cTD0&3+_Y^%LWJob!(u>64I(4T*zM!`J9y>$r z$W@q)eDU(T1;e!$S{nGNAwC1ZB0+*A(NqEl(TV8=qjO1c`x(dfUGEwr@3L{ux6_(jneYRb zEUkV8!PJL(u+la>-w)9ULu;dhOM(mjD^m`Y$2~QK5+cgYm-qz8M82QS2hR7JXKOfZ z^W*^S8PS-{&Q$aXa-oUr;(tDgK=zw+CRloOa@_FSAGH~W8OW;s%x~-Shq8Vthf~vI z%t>chyP`t+H71Fp8lfbs?HWp&rz)+Ax1?M>;o5#m%OAYri6sWN+^zxT#4eIsG_7xR z-}Yn?(*yvB>tDNlC{X{L5&TZb_VvLdiIHB0a(d3j@oz3_hRR>DUF>;`n|j|3GHD=$jdQl9 z_JQjeE4mH_Hvt6Dd`%> zF;|nrS@3SQr_zL!7%|Gtt#w|RQ51SP&iZS{m0IUfrM$CrD&}KcP>rp5%|}%xQK8Wa z=V-{XRwpIO&ax!xb@&ZSyp+XoE4pC92(SD`7cjSKgXrDMD!rrjB4Te7<_+v9-|8uW z=_u27o96)r-U>{D_L|CX6^Tv@Y;K25Yo#sWE2zH&J2GMwXQwr>qretR6Ch1Vd* z<@MS1&zbjLmLb+8%F>!`nU1sk59`ZCuw0JDGx0rU!{b0TJojZ{XndON7axc78#zW< z{Y*lyPy3eUF`uy6V(6+~j#*&FW$|-X7S!WDWaq}u$Z*yEHB9_wvq(o}eaZ$|N>6jr z)?!F~==6?;)TKaC10=e@PSPjLc{vL{MeygrY4c=meqgS#;xuUmOkNac;(b z0i#4%^C%4rw|`zhDYJKNe2C^r`lQCIQx2+>H24l2t$<(k{b>27Kswy1jc@i>1gl2C zB@aXzh*+OR6!2=xS>zg>mGWG>9k#`}&Hh}fO0~aBWh=cDZmit+rfV}6c>};T!2-J^ zc^py+?5#O*@=U3>Jga_qEW85dx~TfU<{B*^HSPHXX5EL~+7CWbRxTeh0&MQbc@^hB zkCpA4%mb@WGxlp9X5n69gad=Zj6;p5R-lj#-5AuvGt#T67h0M4C$o(oH}$^Oh4)&sj^eUdjq!@>KPB+Uo#XZVfnUEid>%RzdwfvCh~G0%)#y&TPD=gR6$ zg|daQAAf_~eQNJ|s*SiPPn;(%XVlYb)aPfG6dy8t^UQ2m^aOEb%r$MWxa8VRwM&rP zZ`s@n$+`Q;p>?h}I)I|Zl5s_b(fxfcfEamn3H!T25n=p5R4###7bn%vY(n}t!7!pz zvjVK{O7-`7*qt%M5)YW`S<&vWClQT%{hhIcL4xD($( zxdO}sybA5l0s^^E6JFkYTuV16pk_1UiRr%hTE(AWy{Ll|C!RSi%qNaBrp9 z#+IkOXniqcW-8PO3iGQ z76EaP-L{o(Oc}rr*lKXB^ld;fQgV$r0>iZfAk=oBILmVpuN@}u=>sz@;yKimjqz75Y{-~VOMew>4ts^EA zgvZ?J^ZRj7I(h&B*YnrFtqXz}A?zTp?&=LyT}O%fPI1fE4QSgjn14h23!>n%-%2%Y zMuBe{mq~a+jYFs)Wo(0jRF^lB@Kn13jeU)`1XY6e39u-kRFKx6XD3=RL)WH5 z*(N%col4p^0WmhxV{W4OZcybfNy`^^X~j8bj-@lhCBW1eP)O{MJ7-M@TU2|L8THpXtJVthMm z1+4N#0ma&9p4jUzZw|&69kr**-@|s31_THD&n2QQX^!J~jyi4tRnr#c7ccSYxNR*V z+)2zBBhFf`d1*hIcnCUWb9P^1x4KM}=?wDuaIFB32K@cPL0bB<)m;+>UfKRTZenw4 z*;Wpz(Xhe~?h&$1qs00gBu+=qm%;!VsGs#RM)_Rw*#yGBxHQY(pgkCqj#&t9OYZMW zDSKyp|GL0+_~&qaJN{=G^)?ah-WdIdfcw^I$)d&%Butf~`Ox8G=jVbP_S7tbnK!@G zInAnwJ)ErfWK~*O?*ceA9vpe@;g6mK@xG4O+W2syD#K`A=;3|xWz$MlgFVgSLzU;_ z=MeF0JvU1(%X9;7qOSj0g-SgJkX_@h$l}g-2Yx8 zAdy7;|AJAw*U<^rKKq@9Co6m1t}i@|ygo+5GdQ0u66zxJx9+Xz!~UPg1lj_F`}LFG z+)hy}$2bVSsL24Gz>l4_7J``_Usx#QCfy~$fRr1=Iaqv}&6NC3D#ax}F*K*9F-57X zhq~<+r@^`D1@%V{N^-QKA$;$p3{Rw)hu0-awncR5J0XLfo$)b-($?wYGi)?iV>vWJ z4U7rn0gAhOIt9#K>CR6XPS*x^0%ktZ$_75FvI_--yuUGP@zR>JKF`&g9u9TwY^bl@ zT-8Coq<-!dbP2OdU;If>ZlJw1{q+EF^n%PwbTe~#IQ}@#2RylBfGvrbH^U}I7z7U& zj_t(I8IOpw9uI^khsOL$D;KhHjM27qiK!@I3~^<3`n0!)`0b=Ka3}bPQl!dg^W~#o z_(e<;r+Vgi)kcY<9#t<$N{aIA4=NNH)g8Sbw^~t@q&WjyOf0Zvv=&|G36K>U+}#?U zGyh7?yoYv#CN3O3r}SqyPgArrOOP;1|R6-49c#6gXTyPT0TRsX{ z<=tKqX7vM4M%M!9z4FMr`i;mC?8>Fx8`$`QIDQe)C)RsTEFYgOg=%!#k|niv48iDJ zELr--#54xG;g;Kus8K|B_5++Taz$(VB4=z#)AXOv5e+(uZrQg>FbH+rEZ~eUokHT0 z7n{w$c!73iT2G&hz z#GbvDHTb(Nj{34aQ3fOz3Ikirdy|;VNBc#IOCN3aR%K*GB2( zpZJcxYD%D;PU+slES8m!U*y4+^G5C_da;1T=zps7=AmF4*2EhI>LU2<=aUa797GxE zhep+nq^0pvE$$xgVOp5sX#Xfbw4>Qye6m+6EnC%7RlQ|KBqrYiyhQvXYK3D!bid$k zL&pZC1om_r7`z}>4v4{%$7x%%o%thG{h26J zw^6X=!dtQg@j_SpTV^6DGz^FJ2i7(B71~o7JvI8F=R(S$E0;3YpTV%-V>`2Pf~N_x zf-h8Sh+Nw$y@gL(V=rd(&OA?I=pk}@i+g>AmNcR8xX|XA+gzSO@z4XzMpiobs z&uI!+4>u1wx~tC%m*RMi`BU(9+nB;F4H*CTHXD{_uVl0+c$vah0YB{iD^@D3jpaj$ z`>#_oP1EXcE+)=E8icN{TDn9@=IpmWjs;mLy<%cW$0xmvS{^-Q26W1xQ^)@8gIPTgwaI z_z2b7dn2D7oeXb(`y@Z*&*hkMlo2IbSDYt|O8~6$VFNx=yC49EF-1d?g@dOOpAcEOlpL2L`A7P2f+&K}n#Y zWc-~DQ=0fc{;Om$6nr*(UAAN4PZZaf%CBDSOH{w&Z;nN?>mrZf$Tklk3imNV^J zgj^j)8W!Oa+M{gM`PC?yMSxLL1)t9f1zpfqv=Q>F3%8ojGFoEfY`1-Uy||5W;dr6Q z9&w5*<177qh)Z|pcOpS)41?azj~}d_58Fz6&`oM|Y)9e)uYY$ivhG97&u=h(J0B9e z^PIhuo{?D4g3nf1)F)Wr70V(ib7|f$Mc6?r`%0wz>;L0X2k?#x`URe**Sq?;NT69>TEr+A*(qz87l%4bW`X;4BysS zq~b0RC&yaEOZD@7rl1pI6y4$^`H?dN(qNZl&GiQ5i|vTL0Jp|T7iLcrLASSfo}m6& zW12uGrwnr+4Xpa0+Y4FX%-(@M^A+44Me zu5wo#MjWhOUlvuh^!d%IqY9k9i#gz_wT+{f^1PY><3DFClw8~RxGP+%-U#}%Xu^h1 zEu*6KT#&6aW>1RDwkB?%4=#@EjQ?-`w#67A>e#{P5k=nuW0_l{_(%-*RO%0^si4ki zTS$YKk6e&{LbD(opGu&D}mG_I=cxZeQT5@Wv&rvBm`;z zOi4`=Bu>By9z@&>^}p5MO^HlBi{s&^h<$e-ryHE8- z*-7;O?Y5AbN3QT`i*f@jK!f8iql+;IdUk!(vXH!9Yal#6BVvy%0On|Oh%Ub+UnpbW ziLpw@gOAo}67sWB%E&r|?Ab0ZbRL*KH2@zbg7e|$BCKfI;m9CiJz!F;Hv-*rxqW0W zjh_EdlSSlu=B<0o!`H}6H`a` zkI_*Y`_BE0m?5k6wn1Brk4o*B)&1h7O|Fm+3QveBO0I^A1y_%8gbFcUL}hPCq8CMy z%otCNY!hvy@8xbEuJoTxz0@**;SOTSD743~{Q&%=F^@r4(=DT0012lzB$iM=JMEi_ zULw|&HU5iLp2EM;mnKGsMW8%Z+9R4`7L&L7YecSXwj1eTPmwcuxQc;AF@}iLMGitY zmhb-UdttM4sad`kJ_+0nHR#6eWli|STt5s zy9y}kPA7-Ih2}s4QFBd^LE`%-=*>&Hy*07}tQy6GQtOjeX_V#JUJ=qS8M5S)rf>Hg zPH)uH(m)kpHoBqNq%cl3mpIjH!@B?7vY^G)sYN6vR;jzF9=0lp=a1bg@6lfLVDG|l zdoJu4KLDMQ(YxT>|NI{|{sZjNJ3m6@R^n_%2qRGBb?(|#tSMqQiko$0Yyqn^tqmrR zfT$4C2xTx8`o2@UumA6LIBAc3o~r&F2-}$UPOtu~HrSa`^`4NTIvXjsbl{dsiePM# zx3%;e&LgJRe$fa$qY|io&jfm(oTX}|y`Y^IZWn1laMM7cHM5{T5F=KN!>Io@MaeO^D7SUu%-+-g-%)3;d^ti{9&6oGbhy-= z=Sg+w+3H7n+_spsNr6^15fzD$7VSBxGA5;imio>Det=9ZCP(ZSWJqoX>4{aP5{ z3?|6MPyag^u38JyibNnX#i);{hU_5}B^$p_<(E|7z}%~1G*Us&EBFsEOqNfQxSZA^ z$Nx7=k*bj3(%xO@n`9N=!SO;_zamvpfBt$4@$jG}KFDzk(NE1=ydwI zjR%F-SKOHp<0H+$q9b@6+hNEjO?q5~x!UJboe*=2(3Qj=#3!V=<%@K99^R$I+xF8~eJs6)vSr zygelR*>{W*W76g|I4Q*|GN*LnMH%^07@zevX=?=UxTJ_STYwNdFA^i*^tYb>W0JQ$ z^V_lV^LHH+-nNpN3D1D>@0O%!@(Wd!#cMRMQ?e^IX3KE{{7Ng}Ggld+(=~^VyNd4O zt8^psV<=0VjKBFX&tHUeF?Ra9L$b!B^yVlR%o{b;2@t=tO`p+F`78r4G>Jy?-!RSW z@x$0~rLQ%9{N+pT;u`g`QANPCK|e*1vtk2Xjp3pv$zk%}y&}*0>0C}WaoD`5Y#fXT zb!p$&RhKD>DwSF67q9m}We85ke=4#0(knT8kMQA_WTgMA=bs06{S6|>-)O6@J#gmH zVE^!FIf6}kTqsQd^!mYNxOmU*eUj9jm|IeRbmLCPd#AE|0LxZqyXN^iRJ!Qc*kMtf zM=9i$8F6-1lDZRWvmTJc1-bvpczB$oPi(j}W?uYl`n_T<)49$?141yym@tEVc_g@0-tE@#S0NN3)kV2V;4*`_qMAEQEz5*ZGq2Po6ZumF>~ z_jn?9=)>QVAE6>?+jE+$M`%J1PZ7e4^u(+CPAURUsHwyLYbYWpjDWL;^a4ANs{aof z{Ux*FaJAgy`-vlhX(7q1O=%4NeJ8sDkI*N*tJkFn?9$xC(KPoBMho-)YDRJhCksTapWjXwR?u_x>eKM#k+e9+O&RYK@BRJ{c*GXhS zNSMEeq6gA#HOL}8ambIn^#h38<^xa1-$Qmvtf+C45;^TCBvLdz86ec(h#qKrMmyQr zxy_0mp-g{^wO|-9#MF_)0%qoA|M$ZWy-El?b3{HnuHPSkK*yme;=UX#Vs0_<1aPVyai6|^MCFilOpip?I%xlyX0y5pAG97gue8C5+Y42X8tF$*03*~YigOq zJtWviCYg<-8Igv#tY_`wsiAI<8w@s_LtII07B0yp>^AHZ+Mc~jeb7Tq0Uw9^$gEbW z9TH^;g6X+YcdQuMJ%1bkq#S^$rP=CAKGGh^=|NpyIj(T?@~)f8leKoapxMVAR&!~0 z>)Xri>Ah5I8vb)lYF$l7;hrX&5qiTdi3Gt?7IdgIrpEZSHzW7D%r;yk5Z?1SaU;C5 z_Nb5Lmj-mjbco{Z^?#{)a?S@P%%DedNq~hoC*%kA`c9Y5G)u)*_WGzT zfzORgnG|zrLoz3W!9N7e#SmLhq~Mi7;j)K+)Zu@P3CjK5A4hI46-z;6cv(^7f@BsZymT3!?1%%DBAu9=t>djZ*8r$=P;@L zcj!5BYWy7!Z0Zn8bLfyBJeRw0q`hI=8``w!S zMGU&KO5Yn#l?|Sk#kGGja!K43YGv!gLV3H8qMO=~=JwBLTjV$=Q*wV; zS~H5*yKAw@^5Lgu56Di>zMXk=W5aaWTL~Gp8``Rhlf0v5Oej7CO(sDTKRQ=<7w;fY zX`tj#Ww-owva}SDU#0zbQsWCS${Ie1EMQp`aGUZSJS1M>3n+3Vphw&z;_>6nnQoU) z8Is$g3`o~&5SsQs5Q?9s_W|N^v;v>EhzTC5>8?J2asWBrtHfGY<+P9HGe-ukvhinO;_QFO&QvBARKA~k!(lgDIM^lG-OVh9*p*j! z8Ho|=)s8>50g5n9Yk*~eXL z{O*DDW-dBCtwA$3HTvDbDQ?iI;|X`g_q@cwD~?17~8S zEHg1|fzv(5XHU#QWtWD5!OBw=JliR4G(G((ItztNfx^o>!AEt|+F79C$3J!pCFt1( z^JOm=`eW!=j|P{9>=x1bQH{ddwBNTzTU6!nVvmY&yt%P(pOW+?8W&W(DC&Da;r`H1 zaxw@7D?PCG##ai*RJeR3_-7f$>G2rY*O*{lNIt;06pv~4Ez)}#F}E5w6Azvfg)p(w zf4j$p4ZU$Jc=3HVCLsO~uz&lvp#Wue`w>f)B9vf2)*fV90&`019o%^_#$$NwxzH~3 z&h@s53Cf?ev4Ex*wA)-fL3WGXK`En3@7PlYAJOOG^CXFH2550p6|^w3?iJ&fRubzJ zL_7Zp38H9aV!gWS)!)Cf@LuF}b+%_-sk8Cvx>0x>y~pb)$yXmU>7=T;ME^|uR;yw zD$G5*pX&z8Fb%4uv}!)R48=pB>ws4XWfdD;kiupYo)=~YgfXfWk76E1wOrABI%=MYVYzd%20RV^29YDcF1~x}&l_LthZvT50427)Z!v6r zm!Zw#J4OodMkx(5%-6X%cx`FG9;S8MY(bmS&tVC=2dxqF67qUCTW4l$h2{+Nr%|FJ zLcXNcZu%xS*b3$|jY7EeRr~u6kwMm++9-=YilZF~9238!LCiT#FVax?xWzlxOeQh{ zUA2y9EVrF!5JfSXj-OlY5B0`&<2bOjLzr0qfm~$0Nj)swpN7oC!h^OuRJT@7MfXwv z=iT=Knm{+L>6_Q|ika1D-y+b(aX^t|XE)wm3<9|OO0wyKe{~l-vv}zFrIS6@`pxU5 z%rn4dZ1=aie~3FA>t`_vSBIM}9eZLekDmr{*|?YP_a|37W;YK^N}Io~-^xRh9#F;0+fTd!2Gn91AhfdkHxR&4B$}bb)sA1x4&B>1c*wP8QTdQ^pgjf<3+=f&=s%sf zc(rui*y1fm)~MxhZ{aJscEW2jBcG6%Pst&FvoTtP&2BBi^mC!!Q^2^^$R6^>avyhsa5Y= z1Lv-8(ldEgI3{hW-pgw=N;z{z=X>8A3k2Tp_=#!a1yrEv(vbsnzVEiylC3v$>V{aJ zCWgDe_9km+q4T3BUY#aO`^9?tcv{rkm5Se`Am+fJ>PBo=9S6|<2AS#+#A|tr8HdA% zhbfE1YP#TX%O#!1K)+E=Z|6h zaYK$%lSJa#ocHQWeoqPPTk5uUaevKgh1+@y(dY;DgteITNb%=086&K{Z+-l08<23q zz~6%9@Y<##DVZH$S?vcA{Z(MO({0KNxr@r107|$2xrjp4pN+S@vC727Hs?J=H$r35TW4<* ziVi5pYI`88nv5eRzO`>X_;dA0%PDsDi8^~Df*@yaqh9eKr02L6_z6#)T%W^VW_Sfz z+Vu$)jN*1)naSL3+RY&mx)bzmzQwmLwpL=^!Hj0`cf|KaV)Ss)J=j>M7L@q4!1;fsFqpC&{~?^DsSNe1$cF3v$=Mn!z`g2E&w8fl7jG z-x0qy$|1qwkrG=RP(!m|7Ch0P?U0>}_dub;DGT##w(XXO9P(r%5r#(0)hfUJYg@f~ zJp^{=+@qB98Kst7)g}hxhxyr}THt}}aG{bF+5z&PJd&#}y;L5#e`{1?K`&aY^=Wq} zbSWGOnf69J3E0NzRpdfli@dKfRy24W9&PIQ4#7lMR^pbh=J}tKUG2<#(w7hC*xp&b zG50!R%c#Z%b>&~bV(J(#GlpCc3~M=91uRU<&_9Fk)eG%r>wfw})~0w6tHK1D^3(|% zy9<8Z{MikaUFA%@J|{@*WpxL3ervceI&#D>P(y` zd}~ieD>Hy(%`=sm1aXNzj4c^a1>Kyw9GOJlT`mRp#{E7DsI!Z#K_r8_OfD?{t)|Pn zuxCFsWCF#WB0x>U0OY!M!0)S{K^IFt{et!C-bXh*OZy>VJTwRX*{Xc?Ue~SZCTqi^XV&MqFIIID+OiXv3Xv0GtuoL4p`8?ewa8f ztLY7QT*Jn@@Q-JIPT4RIHT0y;5RbMv1@25vR@6IjioK%)g#W0|ZvoxM@o8QxQ-GA1 zoHFrOoOxgz>A?eN^v^eY#+Rs$b+~XzCqo&z4McVD4yo@(BGHgVR*ag$XNH0K!l$0< z;*X%lAM;E-Kin;zCIBj>pon-G+IoD{%O~bDMY_a_+bXl7|Lm|nht*K_+y}U`qK_ut z#fhfBQQ(tOu&=!!DzGMSpdbvH&k+6&MHgEn_aAr&36`;~2|3Z}!Z1FIurLwi9>Id| z@lI)UK1SU`n}rZ>BQC5GVHT#={r_PNXonyv$2S5|>8kwEJJ>r|f6=K+v&-%Lu8)f! zXUT&-UbiJt78WD29+5WPR1yoy3&y#1^VQJ&sR(Jq05;(BHx*GUMZ0G-rwIkwkf9$& zNGqu%^Hp0O>^Bv~Nn=|;O=SezHdMHfOy2y3!SP3BdgVtm9+X_?T1RBs6O#S+V3?Yr zj3sy}qeCM3ZEgj8Q1ki|Z9mfk0pvY%$}^AoLSQLyy|SI`=4a(Z-BV0XPN9-1dC>=s ze+oT}$)X1}RKdz0QLWpXIQpmzaE<8!qa!_LHSflhM840b*Hp>KN85K^ZxY$NF+3p+ zvf3RP+@3w4x>}g`BSU!uxL4)7BPtC)IkaVO0Zj(kJK}DtwdKsGt6>q*{AXzj#v>Y; zBT${t4BxI7COxdHH_NGQ{n1_BV`=Onc#Ux96s4~joyYe7@Eb5;>1)s>6_?n)wGb^; zR$R)25wOt5&dge|c~f4AAy#3|zMl&1_X ztNc*}xT>rF-X~=K&Z4jc8^?=RJsx(ejTb>R#^fc67L+sd4NLS=yF(bRYe+qJA%I%3 z*re+MHGL3)cc+d{jPFigvHkS|fs%!}Ty73vT&?MVsmzROasCLEzGt5IX~zRb(>zj$ zAfES~GTVZCvhiQ{j+t#`^`C*{plaln8(q#%i&L7E3l>k;d^3I){ucMzVO?c>TQ*zOp%JY|F9QH+_ zhxxRB5x6$(77mLYrXN1(u1>?ab1o^m$uVofQHspai1QKunh}1-uX5vZau&z>}e{nutg!TP%6f+unF##V*oHfx+(U7G&z9V#1P>PZ&Xo+ zN*Rsf5sg)Ek-<$24wij~yigA_y5*h|YVOK8M<9T-&*J~jyj)TWTpFmxnPp*GJd6o2 ziJLEa$JV6FAlte3d)?nI_goY$isJV&GtSj)UeRAPH<(1d^}4MH_WShsR>w*hS#HnH zyZ3M28k7Xir3kuj(Wtl#)QZvXG_F5?_I0D@lgFH<$e`M1tU4uhKD_Q>0Xh^%o=sR; z-aaPO?m!`d8T9M474#B%{3w4!y-`GF_zl5NU1?Lb7ufsD_k8cGlVMmB7g|8S9_K&m zTeU>$;LyubiRegP4Q7PL%TjI78&Z%Cb7HNfgFyrm@Ncgd`tLoBWp`8e9ZqE70xst* znNbdt96!!~UI}Xh;H$Lhudd#BgyNr0oHm*#xERzO+M0p|>yWkAl%fx1hC7^RCOuh&UGB_9&(Wo)mpAEf94oF3m9Ns#F^G4oIUm-kgS0 zr44FJVfveJi;@|Tl$gW6zySFsD7IsQd1M<8nv{8I5}BmEHppI0Mo1QVO?k>cfg2g|gcK}; zZq^~s5lGZEYD=SVlH4z%=>hSHZxb<_5cHq+{sNh25gJ6Z13|+F$E~efTz*DR%|UbM z|J(w8+PiG$IPhrGM-AB;=9`0}$SaR93k?|+sM(6e9@+MAoUXMXiWvix8UZ{}VkY-_ zccLmR9Le-F_c)CF=wb9Wp{D#VL!*V>{RFbpUI`4RM8t}THSlMDO^+f`yR1i8Ra8y% zz;{25oVOBv&1LSI3M0~U0y6$TEjKmJdUhGjg75p5Xl>~l8(K|4j!SY29R2tD9(A(; z)72{M%8plKy-vjMpI7@$cOx5qKJZu5%vO&mh|wI7ZW*MG2SK|rzxPT6 zoTQ&|6hEq|->GBglR$*LKZvt_f)yR^fS7S5G)WJOCh#iUPoRkr*#EGPJ zPxH#aFH?v3}EcGl8c>V(D0#@ord*WER?ryk4&c%t{>abC) zRI;A0Px@Qxt)>SlpF6fE5}F2irpds=TQ7E~vG37Ni{MRZqFo_CCslikL9G-_$!gLx zRq}l-pUwqJJ z9FdMAiKG6-{Gb76)IW1=`?W!ak@)6&ej>8c9TS%V;c^po=)wcod@gQA}+* zJxk4d%M?J)1*FX|mCyql^d;+%EDN5S~)5!Nu9K6fvMAf|qZi{5%1?xvo1A4`qx zL8pKIm4!**8U0UoN0F;rd#Rs7TaL}Q z{!<6EH1Fn-%B2GQ3_;eplR!xCMo#%7`}>6OaaxsuHFwo4uxgteIW*b3LUE^M0|=S+ zf-v_x+E+-33|aS)#^m1pVN04G1nX{-8g+>eL#ASU>TS4;48pI^e9~j8oCkYW%2Muj zJg~Dwn}hhCy0nkOAHU|x9f|z?eGV8+eM*a9`J8Ba(wj6An~g~3Y@2WSMzF&Zb0XUE zi=j^Ga>GOfe$#HVc@G6AJhSZdC?d)%Xv(6$#{KQ>W9k97+Nr})zu(`V=5on+fbo;B+?*7q2kgvi9GF|rBp70KEH zWXR;`?9arg)bC~ucV9F&Ts)V-&CGWr`S(W2I0}g#vZ#GDOlvU%ZM&fSnomDgxbpFF z2h9O8es=!qYsPl`Ews~LXm_z3f97j%u~0p%_UD7JY~5kzATh_!65%P#DQ5z*$YcA} zkamiX-LwW-eGIkz)nwYG5egvI+5 z5?LUYKTIa!_(sjue^k2PM`qT>eq+NfHgz%c^z_kCq0z)FV|X!B0T+bOYbo5fE^e%}``lRjvv9@k~@~r0zCz^Gh0^ z(KBkUF}T(lB2pBWLPfbbu(+g|d7iP9FoK%Yx1O1BXpyxxuR+^N?o{pD+T=rzUxi|? zw}L=Z8Xb>NmYk<14K5FTH8ZQWvOxeyHZe(rO!HLVK9bX0iy47RStO^}l*r%I=vI~t zFUUWbkc9JkC0pai7n~~j|CNZl@cDS^y?ZoS0!#G_`7U+#IWPN;rV~6tf1WNL$L*zb zNzI$;zmZs>a}x;f{fsZhyw>EFUO(i0+VbRgF#ma^YT{!(^3wWm+L zzCcN1>!<13SrrU`@*z9Hc)utWF6&C0I&*%&&5uVSGJmSjOPM|+WtPrLqkk0V5hHL4 zXbZyCrhM8=iadkd$6eLQCz?wrQeo%GiU57B;mggXOURe9!u=P%5o^X1V`E!pm*ZPh z7glsO~8X`W<~asP&eLG>aLS+LEii+T5C9w+PIY8*vPSqU~idKe~e5s zY6=ZE+C5894xPPW(8;SYlGR$VM-mnINY*v{F!)TZIP;ZHR68p?uv?{M+5xqA)-%ar-C zR%V2NpHoPiC(45}-Gz1cMR{i&WK2iBpdUl|JSr+PiwNo5KXHYr3o3D&QFE^<0qzF)gv zsay4#$rBwFepXp*mC_4ANdesgtpzutVj$L)xEr5T^IP+G-{#a-BDGtJ)~Gjj`(k-v zqLj8^`%7`wBe8p|l`C-p)Z{KKNx9KpEP1VzT;kSyZ||uKES=bqJKS+={F$8nXwHlW zYmXqe{b=cBXxB+xqt$AKlA@Uee_QF!Dic9_-dNE5Ed9kodW_ZE*D__ZEQwu42!v@@JdXWP1Fy-*-;dHu9WQ2bg zC{_tXb?=^sFPc@vNP8}QdRUW}j5P9>E#OViH8>ho1L4o_j#L%DE#jJi#}MvGY?}zy z#v9_nH9smYxU|P9wafXR)D^vF-Atgy7$(pasYC zBoeiP)yj&Vu`y1pJMxvQ{~`%EmHyHD?O*0YX?^z;s{}osu5%A#bbyuDUr73Q;Yf;- zuJ_f!y1=Vg0I#Ce`^Y-Y1CMR68t!v1<1K*^z64af#H7gOaa${_N1*)%BrWYlV4t?n z#1FxsD5Cfwr|nz(jHlCou8`r%%@#6;vZkBzSX z^=x%G>02ay8M8S7Gf2PZ* zv+Y7MUUMr(sW!!VRaQ8jis8$>EPD(?h>`O0a(axZb- z8i)?>UzxG9>e^y(kNC=ksq{>jUuc-yC2WtLXtk_$(l}vuuS01rJRj&6()Y3jL-t52 zK5ve374SvSfQ(b-^;3&a^|tJA)Hjb(9>&L(&}KA9Ws^XoZ|7BwbbYMGtvpw`RDn>9 z&~ff^X$q|#E$RJ*GDezluD8Mppt2`CD>JU1L;`eS3Bculag z`4xDc)OJmqf-wx(Y3Di+3VCSSR!Ww?vqNlu^S85i?~U|9zsE_qn5e3^pm+H!$AX&g z^ihw*N+TdkWJelugTz9g%);^C;K3&QU4(HD$y&^7KjbIt-_2jtDxU_ruYB%cd4*He zc&}oM&05Yc+LN`6n%@=vk!%V=kc}^lbL0<$u7_1H-gGAf&m(>5 zf~qu1VfSv4qrCXq*}G-)w=1-!A(C!~pKfVqDJYoVc_ORGVOEDWuYl=>@`A76^o)?FV?*-QF z2TUjg^ScN%D#rR5bxg1SGzUw)QwIgLl7wnxrR5b75!T8Q)2qV}7~E?y6bThck@`Moc$ zG6Ykx+62c_b7==w6=U8nvMKZJKeyqRN1 z`cI|$Z4Sm&%tE(kIy!sfUVYMtj74<^M1Wcf|2sebC!c8VP}S5n#=hfTyS*7!`N?2_ z>f$+n3F-0VfLxG}S~W9Q(@e)2r*;}oIU$swE*;!<+Uoj1d+LXUTFN)wX|#A7^iA-s zt=yXY^oHIk_g*DG0zM4yF*RwE+dxY!-M`ve&$^KFkx)Wv)(b)82VUzxm!@1V9Po#_ zuSQ#s*%b(kk#Hh_*Mr6UAFoH$hJb)xFb=VXgQgx3y}JddkB5mB^v zpPtGm&rEUNLdo<3z~tyrnY*`5)Hbv8?~xsIF(P8&wZ5xQ#74x_6~wZurIAznKcSGx z3Chtv>hjMWZlwAs=8vBLo=rwAWvK&%h&{bq7)*EQW_RR1;GF?XbSFYJKD}7Q2?}`DriOc_T6D7G%=Llb5{bLhf0LcahJb#48gF8T(txV=^!^3 zXEy#*Ca%d2?pB<&+RVi~V;sjRE=QiTS#z27M?O=GqACaP7lhV#)HbbSecE8I-@f7q zKg;`2QqTHCvkiQ#~$G9S9D%HCV25Wp=PL)XqzLxDn)PO<#VwsxeV6!JDXH z%-szICKpGQ*EIdM(*^YxTHH7XBaueo`1_SO-7Or+Sn~>MTTx=FHzAvD5U;bf3$qFc zjRJvE!poRYwVVo&ciE@Op~@w%^~(>D97yx&%_rj=de1H$;G(IidbpkYy!F5r)ZF2aKui|(&|pz zfw_6oePE3O(S8*WA)MJI;N;YSJv*t&i_LK%Cp4gUn6d0_&b$X35K?|?b^{D<lRd8&*5taI-fVyZf3tyzMK7zjQ6%S1em|S#>5)a6Z~z_78ZTacnm7QP(EyRG zR8LH0-F*e0`110qpp+xduhT67jw9gLYn0l3JosBnmJfcWQ-MkGVCruam64wq(J!`b z8BQtBQ)5btdjcagv@i^pw}9V=&8~k%L^Ws1Wo^b~up@3uspPwBzNWs^KwmOf&>kvq= z+@%ur99|tW7dH4=-cqq9Ma?Nb6~l{Q@#Pn7xU5rLd>9vf;Mt-k-qjOMf)Q+%UuslP^}E< zUX=PUOWfLK*!XaVmc7k~85 z5Pv9SYQtq!scp8X+d`s&YOpTGR!YTTgFe^~$l$Su+WK ztE(d!^g}c)eQLMP{OIel<3OnZM+^7dS46qa~|g z&-pGxm{TA5rK9r^36Va>&3GJcPK8R-t~NCqb(tZvgakAqZnzg;)kY1j;x#ZSW64j}tOviS=_E|)GOt!fEFTC0tb~b?5b1L3Xy3G2YW3m2hPU2 zFmuOrPdwf&8L#(@X{#?7fq8AgGRbX>63eDAuti$^jAmKE6d}000Aq)cCt#5YEBJhU zJ!H&I227lSj2X$wPdjYmF3$zOZ!~0o@oD^LP)_aHO9MOhAsfWUPxvl9Bexs!JG5BMjt}QLEe?c; z@fT!=Bf59Fl3%;G^-IGwuRM0|>`08n;gx2nQ69#1id#3hd-|0eu03!U8n`0DEDV(wcEa1D6l!u{$;<2Mw-m zdLDeV-m8=qlXDJd!K5m*Iva5a^OWoagGBs_s>HZ$6wb|acn5Y00 z6y7Ws4qMTc1Eh&9bTgt&QHz@|FYGcxGe7+0{QxB2?WW1B&~Yc zzEu+XBQ8^BFk#P*XQ;`jr*zyEOO>5&x{+;*J!_{-3qgjle1lCo!=M)#7=9{GkB(_& z@g%odaO5Ao|GsL9pOP!HN@vDYhX0~KyUdc!v-`I2Ev)_hmzo;S?QT8q!B0zj?q=$~ zXj00&UGauY@0RV)U@iP76}WbbUkAoawz;%l478dVzaP%jIzE{f+G@c|sJ+#SQ_vGW zU`ns4G@Z$8lKL%rv(rB%5WJHBI{yIj;C>b!(1YCGE7O8sPBx+t4fUDvJPLIrXpNag z%XLWI%_afM+OlPOLBE1MNbFQ^Aw|bxv35zdlPYW%@1GFZF~N2ux{Y8asc#LA-IrU+ z8{oFP`^b-B_c|8yE#$stxPYrO`T2Mk)aet*xw$3q(G7mwEE)mYA=Ry$G{k3db@i-F zN>9UCa>?z3jSNOdz4{}V?KNOO&f@?+T1dEz@ZHDkga~sXPaS}ZHP*PqTZlcG)6&!< zM8!ws2A;p=4{w=_^QN!FfP2izl?x2{>zQBCerNhVnJTZE3vWLxo&W9{#pQY*)ROGI z9BCD9$+kjnc&{d@Hq6e^E*g;j>fEHIk}XfR6&f`Gkl<0vFj|c>_2j%7HC*CeE9zUx z24SU-oQ)gAx$oP&$IFhqd>5-`pDMGF8Pos3$8do1ub>gf+OfARZ<;*QpBgHxe#sv{ zqzRey)Aabk%~!em2P9$7otiy)*JET9)8kJSFQd*jeQ;LhkxU^?1DLv`v@JeE?%I#d zYd!1EyO^8Y;F<;x>Z2D7h6eQNaNZX@jNG2w>HbfJ(h9l%>A`Jo!{IF)>oz6FZ!FXypn@GM9wC2{9yz?LQK3i4hx69ksc1xta=!px~k14h~ultVO zh7z-A(!|a(qu9J!;VU_}4Cj^A;a9Xi&u3M1O!z}scq-=Zcjo6|d1zb{7V71;AJHi6 ztUb%q9gR^_|B`RbXhU5Glg`rP;r=Z<@yhpaftgrw>^P|AjT^lHR!Au~7;MXsC?(tC z6BffMmUwQiz9sb9SzB{n^Y)j&IeXLB=+1&pVLN{cj}s|9jZTq1+@UGfvbQxRx(i+S z;O}H}fX8=H+=V|iw!KLlOVrgONvgk@KWiCDt~G-=kpc!sVIzU$+liFAB(H`i3AzQb zD<&dmLuaa zbd6nUNn#%7PE{~(U;ZN%AlCwWW3q%?Rc}2?gF5p$zjpfc!}Ygzq(aduU4D!$3&5L1 zm)-jW>~#cK&=V?@Q&JPXni7sbatKT~-_lhUaI5xNBW9knGjgw#N&@^OPjK z8^ufqf=L2U`^0mUIHZt}_2q(YD9xG}UJwrP?RbFzmF<*GpmsMI}kqX3kygdphJAinXUOTh9sF;LbA+ zJH5cJ9leuro)z|Ck~9l|Wjzg0H_LPQ|BMfnhYfUS7tB4<_PgCrJ(^o-yBNzP0NfIh zHC7QjwCxPg$rwzoi{3`5WJtR}RQ@klPKHS2tH=v|TyO?)q!LW^ck?c3RidB;vHlV& zRWI4(My%cy+t2k4a`4>van{RQ4yT{?ba@?eMKH$+m%p7#uYSMfo3oE0{L6^pflh_jDwSyG9~~o(*R7Ca3f%IC0s+Oc#9MYsnEP8TJ=XpUiq5 zlF}w{CXk`Sk@K$(Ec>aTbpKSzl;aoWquoH1jM7^dSwb2@-OwXTwmXqA2dv4rt>$gr zv-tIa$Dlh@l1}kA6*^)x+sZXd)qM1}l$LfIJGa#NzKB|y`T5YRUGG-GwgF9AQ=tc( zT?Jzc5{063FRWD-vY}oopm{|Y6Ja!l@;bukpjKu ztoD*6qCT7-r%VN((s{KBK1){NHzYZJQ3XZE5a1RbTr^3TN>yL6KVP#w?6skB%B_+Q zGb@y0QHO$>V@MehFTOaQ}NZIm%B^p&8dX_*Z+-UWi(<5>WvFE9#?R8&R zc+_j;26$wOEY(r#Rco*CPK|9)=EQqmVQ&(pUZGY_pJj11^|V+5m{D=+vzx6|`$016 z%m#0cky>ulgYL4$IHp|U0>AS-@-Ra@R_x~vhod6H7eTd}Np#%)MuK51ic-ynSR(z! zlE39H$h1%=oV!va3v(N~6x0M+d1+TkBv_Jnw&6mDh0`wE8!_5_5krUv6`;efP*ILJ z%y%)~bnM@_m}Y~Hcva?_b{c!qV_$l@HtQm<+_=Q};(LT6c2?<+4+fsH@+e3>hAb*c zc@6(Z06BDbblMcVCaL^rp0^d|%lqadFIC>;joRtaYgC3pg3n}CQ_nFf67j_*UhR@Z zEJ6SH(T5=Jy17H_O!t}7o>yi%3 z2qEC$pgiOdw;8(XSG`?hL3lwa`; zl6*U2XfnFG(Ek1NVuX_(rZ@3o^+PIZVRjIjp`9c$pn^|S8hkWqzq-$?TyPXVEoWS8 zFLn)WZF-vtO{CN*@sY*99t^~(mB`E{<%QLFGb75CotJH{+A2QhlYm(Kw4COEwxGm| z7CyL5`B>#owQ1^Owj-Ka*ybI4fE8e{yH@wP3&V=^)gXkwu6GJ~cHMn2*Q=4q5>J-q zIQx6>x-({ZRd zuSfJX!Bv#qC|w2R@?plGwv)u9MR*&cI3pjUAnJ8T-O?K%w<^+2$=w)$u;V`}eif`C z=#|^wn-0hK_H;^O`Qh4uO6$<${7eGLr1QL~@8pO8+MQ;wglhkS8#UQ6Vl+~|uZ(N= zOP&f!M8w4(k810^^JZP)*w!7YR?iZdkAgC(A9_2n&zA`PtFsnR;fHe>ayn#u_x^G= z`#Xsr|7&mbr%?_p90*Zu5G9FVbR{+SoU4v&G2L+op_*uF3gWs?<5)b2Ar{d<(Er(Y zfi@eo@pYu7k}0;9B+Cvlsu+^Bcn;r;&?Lx0|JS4exZTZT1eOQsdqiv6pp)}yhSx>z|VSdA}HsL5Qo zE@o(oIQo^ol(?pu2Rz`;{eB$}%1ii$Dd3cPE9#yMj*tT}X@~SCFvXOAJH##0z2MCCIf^o4$d6G>B`jhV9dXOv;;|NF|h;Bhx^@ zm^gv$XK+rGqa-TRXC?Ca-%c>*qD^WpKa|ThouMCH{PR@ko+eu*JOj~O>sWr|})>|BaPB-b^)T8

    X6D3YHULkGJ7{+Sbz4VhY?n!C+1?P=WFaO0cDeluHKF@f5=bM zUBrdoJN|=4_+!3a66;)Onw@zoKcq+Dlhj(zXa9unJ%t+=5BOAeF2&Fy@)R%&XH)zT3uVB2Bx3P!UJq;dytd|LbRqO)!+KBXZGyffI#YK$DgKo zRyCd^Kd|eCt{OhqEkF83LX)-GYJ102M*AhuVUXtEOZ%@VQ4m8EFxmMU-GR$DO;wjt z=Hl>me*TMaiTMd>_~Z){h5<;(Bdk!W4Flc|`!z=*IGfF=vb~TimPX3mQ|gJCa#04I z5}s`ZP{B`4-!f@y^OFGXKlOk2XYq8K^2F*$gZ#dPRF%3YYnisVNOGQ@FMzd5iE{6H z^iXpa?4`{^Akio;K(B=Fwrk)>L_C$$EVav60UBQ~$(o-$7{oj2$~IGdN0LT+d9Qs@ zXXUJ)1kBkUiuaG?)|ou{S_~?2x_Au~*_`%ZwZj6(M9r z2+{9G@6Y%5Z+RTf>%L#laXqi=dX8ka8VRHOnkO%YED&qG<8SY56>*0TD|wm99GdPv ze)O?Pp$xNpE3g**XUu^FMx7qnkCurAU-XNKf1Y)$_7wJ|@+ETkpaBmrfF z^^`6ei!VCp&e2G=hUtdn@7@Yj6f2H?dvL=C6*6lZ;Rw!=2>%`6oNsmCve%_tCV4~{ zs(uE0c|=YtTh;r5k5-y#n@nU15Hrckz3K!L_xjytFqs!p+aT1O;QzmHm!98?Y z%3G!6A%^nih3|GJ3UF(96OXto3)m`kofrD27y*DdGXIk(X&Rry98bWs(X0#4B!?(DLNP@qnm zA)>B>UnHp^AqS#O0<>$7grNY0HK{4xejw*ocu)Q!?X8o}l96K|o@HH}&kGP^+M56z{&dx5Z>@MQ3QJ)IznwH54lL!O~+S z$mv7l?Py|6Kc|tXaoZ}&CM;BNKBf4ZoLBhZ0}RbL|$!p49355)_`C_V&iLG zoxUZ#ORz%htp>Ux-^H-_24A3zx%;zK2`a;wDaQ;-txSqQUFc%4iZ^I~t3kcA-}2>= zU`Z+&4lODhoGXC$=@jRzNzC5_T$Aqr8g{OC?ds&r7jRCqdQZU0({XI;bdpO`V2xye zL=Wv}cJrCIt*c&BBGtd`u~5(z-Ma{HCcx|lMd3j}wuc1|vvi9>^cG^6)xPZAV+dM$ zcq@o+8dH;fJFLqHKJ&_n15z*rY!TJ~-GbH$0(ORhSI9JvdVP@~3T0h-dhNe|x^JdV zg()^Vz{h_Hz4CxOv`4;!ScyWb#J5HhDpbyC5?W3<8XPSD4H0i{7 zfxAYXw+M6@3Ll##oh||PxEfM55-~rRU z!?7#r32BE7tWzyGYg>U|VcRV)^2#-OwQrrG#PBw$_xI5#uBtscJgAFevm3;%fp`2D z`nvR~8=&PLeie1z#sDR4$~%f^ZVXoNcsOC68c*Vv4gUD+n$);6t z0mnO_L2BUTv71{k=~7yc&Da#zU*9*5jFPW^%d?MqK0JJ9f9#-Oa8W#>C`uWpX{(A@ z)N?1EvEE^@yyaA&^z&qahdI9Z+dZ5M@{=Y20Ub;pXjI}H0O^bnl2>OO5)M@j=Xg(0 z8SdCpIx$yfsn%y~Cb&<}uIzk>1f8LO@nGQw zj@s()H+Gn6VCYr{BdSYw)M^R8J5&o%Bs=OF+ydQt{!7fBG^>fv2d#M_E^U09gf4KK z{Xj4AC^+A3cGRr8%(2l__sFYPYa=5y8lVK=tnol0rLL1mgOoDl*&`q&eSdoo1*Ew7 z-h%6dU&MFN#NmQ10${s_-=0?g%7;(n$Nt^uf>jT&Bq4N?{_n|qeYbDtfzk*s0IdHD zT~KN?@+z(f$W-T@-nBGmx^wS7BpKAOq3Y&g#;nQjR*(iGPg<7i5*vn-uO4{PpK&QI zSnl%z*OiBRt_14E;j@)qL>y1}XJ=Ltkb2}yx`E5D@|dwHH0<{Q1+f(%Gj@9r(%Oi6 z`9vXbueXF#!*q*7>!fV(jH>L-2!qZ@oQ;=)3(%1S0H2i7j+ zC*O+UXQNtiTfwV%T<{zEI}ixIgQ>~;mrQ69O}uh|5)?+7Xw3g+{-x5K(ajw`0Hw&% zs{HK6xGTu8QI@k4`8qjN>dAhBrcP(O0;~Wee%5aiOQ5&QSqTG};j& ztBrL5#J{@Nh8W0>TfWf;yP?q=&l-svHD6Zaprj+wbKlP&DFiYif*esn|FxDU^4BF3 zk)X+hUR>NBeY^1+3$a?dP;ofLfA){?9f+`WQ-+`nP|+zm&5hdVG3%^8Qm*AfsM$AZfgHIDrt&J6rwDU$XWR z^#4S&MDUMS9p_o;>z6sVM3?Rs9J5f+TS!?a z?w}UiA1s=jMv<02ev2rT)R%sFBn0{!Eb+pSE$$}Jm3H}}%5V1d73}?afqU)!i0A9N zGEk>NG5Enm(ZljKaxepPKQp9Y$~UqfI*zYY#L`ZT0ePzEMK>Dl=&A<38+}#)b?;F82vkwz1hS(^`$0bm2-&&s zFl$yT^Z|DvJXTQYsMp`gt7^JD~y9lZV3s?_#Sso%sQybJxD9%#d4fhv&m#-b6=3E51s z_fx57z6d}?hl-Ye;24gMGUivfnhG-H%ipR6`!m4Wot8o9%eq0T?*oGD3xffm zcg9yBV31zKa!3&R*(9vrA^3b98m>W=p@mq!F1HdN7g&%j`jO#%%3CRI-@}s^3lxd+ zzj_G$WBJH_+gaw z;|vv&xWR&GEjVQ;x+_yaV!xl^#2qTdQj_P?<*lrO85i3SE2*hXG2zDX-eVEoP=toq zQO#l4j>%q$B-q*>`Ky1hp@O12YQ2>oWsw|_J)AfVY01<$Q%V?YQa%?Fes=uOw1IG_ z(=L)1SrMX}eaCDwmK$`aw8Ih;_;b#}YSWJSLH0LN%>`%6o#3wBVM~3DM}|N9W7IC5 z5o+^%WSu3PR!c`2Hk^$Aabng&G*|YI-1Y}F* zeH4jL*0Rrh#<4QZDi>4lfaddOj&I_X(%gc#Ses_I@T4+x%3j(8KpY2d$^5pP*`eag zZ*SwEGP=tXNU6`4Y=&TX5g66PSTaBVtndjn>a5H}s!-P0 zsObY$!yeB|ImrH9;*`aQ>tCJ#6$E0n8C|J1oZahc%p#G+tR$3wbrjW`9C7{mpfR@a z{YsR;1`>h#)tPxw_X(rah>nCB5_Qf z_Mox;dkJH33uizfdigGiB395F&ptqfG2Sxb*Dz{Oe8tgU}%VhMDNslcAH3DH+&O zLXIMsu%XC3*KHOSR~(Y5;TR+=mNqlK zY;sh$6-H}KLGMx7!sbLvq*I5UbK-iseApwZSh8iS`A^EZ4H(O)(ycJCUpJob;*?B& zlG<_96R_eAR7(DdjK)UKmwzP{X=qbs$$rVmdY^Al_&k=>yTa%*$7AA=*2Arv$#lu= zr!FNP;mtYP!Oz`sXab?T*EfiSpkYF<{bO3~d|$SE$6QL;(Cp-NltI|-lFsr}+QxwQ zuZv}Q``4`1mU_&~1$Y___o+7H6ij~AGvvm`u}%i{yTr8v1<8}hqHjC}(KeN(`ju_` zm=eYu$qx6K(P4_z>~@+0B)+^fAiUHSsmVkkjd5eDv@UFvaz! z#C9~lc_o@)%NJR#22|YoO9qGaV;Kk(G@M>Zq70+d&*7|d9^MM+l^lk7vNV>*nfgGnVu&!0D&5vn@Tv%7CumW_T%L@Sr0TsbU(KR|KPUoBdIkd)x0wJ4;z zS-z}{uI9QKag>D(VDNxpGbcuvZq}En(PLsXj2{@ztva>w-`8&bjZl}Y25+&)T`9#( z1g9BoFT)g1B>T9XBg_df=O{1~>-9Qn)KL|kkt{=K0$MHmTstsB%kV?D0RS5WQEU=6 z1!rQxP$MnW%)(ZK6r=EyBEr@m8KWrnL$k`7^Uf6dQ(QIc%|nBhMHdwSEBwsv_yIGK z@b;IOM&*pV;aXg-UUj?i=SRySZeji1q1}-sEHMEORtl0}HlR5k|E~gl`fzMFHK7Hx zK&SQPnk3||8r8W|-|eS>>=xwLS!IFM(hnB0l^0CnMULfR97v&n$z_|+>4*QXiK0(- zL7YF&bW|pI{QVY!@5kA3D}u(=wGaQBV@9ZJ2S5zKOk9$&f#T(`?4soYM;B}S(#a%# zQZ(YNS`=Kyr=q?86}y%<#3lSJ}a-0kP?f4wC%8nhiesWkzpuyV@g` zUktKg{2Nm(A~YJ3FQv7Z0|M4RcB*JYQ}_OXk}H6}9xEigIe-{?mNMH*!`R+{JWNI#z#`qibEk*)2I0qKKyklE8}FevhRrcH|d zBMhJE|z4y;fb9VPev>L_QVR{MhiDeLnWwE=t<2OeZ%$+=Gx#u>P36rD?byZrtMDdcP6j&C<8uxK4WP!aV*y48}wK5iqb^@R| ziL{mYj;jn=3xW`!+28!K_fMjGM8+J0pWXU~|GnKRw(D!48HcOyC?+ocp7kypEY%p411GL&SFA@=ncgDC@uf`|4W{D!^ zOD?S)7@>FA7a626Q0m`IWs@zB)9dX=na={xP5X;rH3RIWzHi8p6b)Vwfp${2yLINz@$IY1luZ@%rd1 zf{8F4^QAA_oaJdTyUJ8`ly9FjKs6htdJPO^L>)sQ{yPA+&P|rzeqj_w4l(n6q{GSf$9pFcxN_tGvxt^g-_rLOxS9qndUkEzus1npSCr2GN(1ifBB&DL z&cX{Zd)?o5jP)in?JoANZ~V`6RC>kERZ_He;eZ&Q)Aw-&R2OOu}ZB33W9k8 z7Hq+RNRYJ+Cq)N5SyvM5cE8SFPf|MwOJjT2-220sGkt^KD{Z}>9R4ycmKO~+BB}7lsA}Gs;46lM~{H06vXLwo@ju{&&=;5>n1DroGQG6BOw$vt_om0o=$uhJ^uZkV)tx&U}m zZk(~^TWGV~f9~=3(fWgEu;gS@$bkp7UUn9P=yU(;sviL$x0L4q^2>DVX$S0lWro+_ zPo49Y0w{p*O|iQcX|z7JTCb%;MCdPln<9k(p|mcsXNw#E6I-K|_9&M2VAk=&KZ`h> zYnCz4EsK+`*{hFz8-`l$2MOa>3yxp$^Abz~WC_+~@<*3cQ=P=IJ3AHbxreys)_`QFMdxGvkl?hZhn zEbU5AeP{QhtzNMu)hA>>td(FDK~hp|7uv{CX{IuVw9@;%E($yyWu^o8`yf znDJI+o0#mJ6d?o3;Ch|2pfgEeU-q5n)XMU?$cmhGS*NE+fzPR=Hy34 zC6L=ZqNNh0#yos6aNQSvdbh{7Vb?m?BP@0`fhL~A=(7vrYAak9PMo^+`OeP;XK)Xd zUEg)wf$@elX)u#A6?X9U`y7btn*{R826kWOV546Lr_1MNs0VLUC@)KE5Z#$w7L>#! z$FAS<8nB-G6}H4qn?bf3cpIQr=Ib&iISD840Q9Yg3P0(iP$Nm@t|tYYc+SeW+`oiv ziZPsF3Ybj;4x=0>(&+u7Qne`@JGc+5+WyVNYCcY5q$8cxwczjL8i|AapGonXEPFpo zRfp5FSm6h z7j5TBxp_UbZ1(onuYxOgzF6r?!+mdiJuRL5=`r92TWfR->qG82T(>QYV3~+O<*i{t zihkHRi=G7NHM~501|VQSkkf213!xpxIp4k@>d##dxQwb0h&Xf0C~D2dh!yHbsd*^u zr7+iXjH6s%wp~aV5Bmz+=F>$x0Ynp#UrTJ~AwdKG zy&83c!zCx~{AwEL7i#1`!y^R9FC6LhZ>+W698!+z#7 zfJz?+SOU1The3UYSzXhEoO%kBvz7DrIxowRC7!8wQSL?`_dQ0{nF_@7Vhed8MT6TB zsYc%4(}|;J^2;6uUyVKwK!LpzA2sxG@#wkT?I>gJ$2%TWZ%!NmugB$8t+#Fv{8Xdj zRe0MY88JE6*?%TXP>s&W_jvx2V)qdbGJ;D&QRV8Cjq(i{JJy6l1p%3IL&o>=kvE$s zKlf1NvcLvZO1Ggf?kYfKV&)qVp%IienlBiFeq(O;Y*W?#=g2zXe)_}}&J02UJJJTe zbNB$16miX!66H(81!^gfV}}q*^OuZ9<7rX@uRj-2JTV4@qI>tQ9q_|z74zQ~Te;w% z=Ay%udN<8Q-|kX1TzA@2W{O_E6F(ixKU5r3I14RjZn;lvF`)1)ExmyAXzsEb0PwKc zH$IuauWGI}a!5qC%W@h$WF7i$FqE1nWU9|6scuuPTb1p`JWQRoHU238Kr;dD%RblU zasI@Bl26D#a8+}OgXb1~c*k`Pq~ z2YMN7HWh5_s-RlL{^2~&%g6pNzbU`%<`H9oAXb$aR37D70nFk;S%voBkVtJ%y zR%rzmKE7ZnNoo2YxW>KbNcJy9P2n4w3WoRG3}AP@AU1 zkLeYqbh;lnoLkR*;4ZMqjf=7`K%M|YQSNcHm9+TY*i6LLdhX>2ALyJ*h3l|(0zRWn>O_;`AerBJ?ii@g(JL0NoCL~XQ~=`s9jF=)6fus97fnylY*!m&7r=rz#e zdHYfv2zkS(<#@1$a7P8cBI`v8%{ zFVvPrZSM6X?yBTjQt$&?(SZ;ke)pF;Q9F-HJv{Gd^mWkBoAQ&f(a2m{lliR4a{t*(gGh+6{)4o=ihq(Nt-5 zS{=@+mJV3xo7wJ|9~Bac!2G-MA87@+*sjP;))Q&wHM=c3?r_y04v-^!wfJm9iDQb6$p^CxHhhOxyA$L6a4; zu@hbNx;wBBDeraNRwh91#eO4} zQVlPeqe*3W@`DUb{CkO6TUCXU4)|H??jbi$!NM{+ymyy;*ir09;=p_JV+{Oh=^AnR zge+=s@5<301DopBFoaKbhh^R%PK&z1kVzB0ew+jfwrg?My^5v%n4sq|>y*X2&9}Y_ zn(?V03jE^s?a3ymb2eStfrZ?Bh(=FGB5aq%%Ay#8s{ z>1E>bS&9h62KhTf1m{9NnXU|!33Bki(SPQh0J|LVyS!$u)_(7}ueK@B?}9V3hEs;R zcB4olzfKYjIaw|wID-d+A4gm`%Orqc@ANoyS^(C;%^EPPN-$@SLXJ?A9z!i~;|=-# z$SO~Q>D}tk*%;StDEf99q_)`{+BzetWF*>dzW5Tor9iA2e(Qkcyx}~6mH45X#iYyC zNx|UFdhUysGlIMFvr{2-ytbhHA=PI6L+(}!&SRI5CbS)#9TO&aP!6Cd_T3m+HyGgZ z&R;;Z#+nuU&FX%+$rKM;krxBNBbbG{cY@;BQtt3QzA3}y1blM-9rt_wjDUZq>aW)b zlrZhkAvbGpIfRz`^Q|7D_#$BLQp9Y;1Ly!-45Qxc-r86}+)>es{=UJogmBoX zh;oH5d_SyELuJ$;Vkc9JIVZv$Ff^2O%Y(a?p>v+!+)B=7bJm@8)tI zH-AjyqTlpH#mEY%c4~r?NP+)C7G7VFmQ1CNDzZeg8f{OkHb(<&$to;GAVC0H5?4P^ zY>=C{TW|@Q(3s4}lfV(*=KOC*qf_4P8Cy7&fSRi5(nuXv$YI+@QgHAs|IL3XjeO$` ze!>qb93pDkUy=~}{8PH@3&XsY^NCIIbkb>I(Uij~tL)cR4}j$vn)M%$vao#iQx|3R zhB*s7OhB(+v*4F%RT`?HF2Z$L;rs93ONx*v1}{Pm!=^|E<$t&R>PbS}yoHY&4UF7xIhj0&3DkUtq`Uv^sGgJKOm5hK3XIWcYz8;K#$rCIm zCdEn`-nlsBx9ubFDGcCmY{vPfwN0K|-O`^oJ#R<3#c?d)9$Mw5?lG0Ux}n%rBU3Y; z(uisMW06Ab3(_zsBX2KL9E%BUSlqZ zrDqksLy!9q3+p=tjycrtzsi9eQj{|jlw_w$n7^GwjQYFLp;-5Rx=K$;1aP|+N}KgL zhGvuFQZ}LMvWWjN;$`v*wvAZ$@ohpqmUN)qiZOfHa?tR`X;c|89vN<^2${s{-Rloo zWR<&AGoF*s-fj^$>`@3-Cmsw_E-=Y}uN=600{Q2jAIfu3|IXeMfjc(d!(j0I^Va`j zZc^rrj>n*0B-@Hr>I#Qg?C(j%x?cS%;TN@0s$5RJsDgTBAQg@L<9cJn4s`no&&U8H zN%%aHPmG@gJ>7a8MtYckB0UrUZZwCDw-|Ng+jMJ^m_wltSl-m3F&gH8QPU%d3Huf0 z<;lcHk>df1(clnHBY^VT8YQpaMHH_L%-QvVI(jduM>Gcyy+ReQnpE9claO56FudYY z=Kl&?M|l|KW|zfBaquuJ^0FPuS`;$z9cO8~g|U!QBA%ZXV1+Nb#ph^H6CUh`miwwa zjoSR%#GaH(vFa8t9-&&qtC6gyYOb{;(zg;LXU3YlKchNfe5Ymxt;_Qw-hLQa`Kmwx z>(lY`0iKJQ9zf{pb)@5OoP7>)?KZmR652e~%XZ`7iw%Isy7sZPa9qd=uwv)*Uw+Go)_la z*nr0;x)j6k66lnjds!+`FJ5TT@Po}Bu;h4^Z3y@K+?)Di)kZq^L&SJ849Uh%I;4t= z{2{_#S=w7hk*d`BA6ctwpr_ELa_;R1njR=iyB!(8q8RQqV3DIiot^ET6R#}}|3{B` ziH8T!Unw|Z$9DCsKh|zCGcBF?G16I#STQchHsoi$D;4lBE07byVGM%$@+O7;jlfOa zV#;Mp9k>Q0%X?R1h;bENTRYA%Pamxa9h+@pBXPg}JkC$nb`AE6F;CfCPNhiwfcN9! zkBBcS-J-E@)rt(X%}Y*5W5$AUGuPw0-%rre&{?|g#IT+mS^%-JIOkDb9;hP6Ibo4{ zH=|AHnrmr29^kxT2TvvyQNV`C1I!)oNbA>3S1&qJ@8_C|JxB!w!y?2=HDQy%%h~3? z*~=2CBi?!7>&c6@e(0Bp7l7*P7pdL!Iclox2?lklPYW<0mxk!lIgR?* zr#(zr0jyG&N94>6S_)VXcwg{rl$(i0XL(NVD*oKFrB$H1qyT`3+fL4e!G*?nfc@{z zPN^sEAKD_C)^a8m`?kC2WeYHTwEy_Ig00n4bp>E4mhn79?JRfbsfJn~L>mJEyC=69 zSX48S%WEy?UADB$1N)$rN-dKQ(9wmpEA{S?z_wNPjNR79L+)KrHPWJb_Ty7!t9H91 z61hES{AWjF_&*=$K{Y;4GGRWC0g27@H7SF*{@Cf$2sq|mxVLR|DQvUEMkjAp6a~TTR9zLg+ zuq^|68xff6t)NNFwmF^Gi8_4Xe&%_#V{&vQvp@lwCzyI&$X&q82F!OK9AQ`T@mh<4 zOWgTFlXG5bdo`7Rtu_#obDAy{>k!tvb#)!^cUk0BX5&=Ld8aVK5d7i0oxrS1B292| zZ`~Wcnnw&6%uWrbTw2>8iYNoJ?J7FK+t;8HY4iI%(>>T%<3^$zE~NV7*G~Y+#SAq*aE`Pu4z9ga{a=iUSsYk62TvKnvaG z(ni5HgZ2g-DQlTTbD(x9D24ymt#LB?#Kv=S=}7M-W0#)Zf-`T){ZB-cwQ=rJ8-K6c zThuW5?a*^D_U?cbGpjD=Wi+>5&P@`t@OhqDZiNZS4$#X0#SxPIb@%tHxJMno9dHCd z4?}V(+HvJ(C49pAWwadajGzGO5U)4)t++gJuL)er0Kcd8!&t{98`PsQ65tUxnn#yh z?00yAK)9E6SuhTn-r5QdP>HBQb-C10s-Zf*K}^*RbYd4ngm=%i!QKbjk?L1MG@@*|GkCE_nTu)YNm z>Ir0f*lixy$7heCLU+t)>Tp;RNd}&IG80R~nxuNMZ4J-Mum=U8SxNdHfAp=52OOez zTVPc+7O-g@X3gs^)a4;v$P(+N6u!z@jC?xmf}5_no$5tY&TEp%1_-pUP@9yV;}V>; zHn>SO(%GhTu{H&$qTO%_N2i*lTwy?eXLgkuEdSWX`K5nfE-j|$*krBU%R36#cYy!A zRS$~{EiR#=j|cWf=?_%r{8y>3dA5H+e;Gw`5?7H;Z9U+S@fjc$(&++xA*Vh|m;`ew zm@u;WNI}hs|HCl{lwR}spbEWk^@Byce{;WtSQD34hPLEFsu$yu@4@uVhMeR8xzstS z?xdsr&yRs$2Ax1l?tLpO3<(;~c=JMu&h$D)5Sfw2X1~trb2?}0j8A0mJvLU~s`m}E}dh={JAF)%{%Cb?0i0E|!C_=yo)_2UN zx&i;tNuf+rVN%rVJ0ClZ-@uJ_W`&rx%yB?O-2r5tv@PnmK9ZTYwr zuOE?vWEXM_0zH1U+y=O5$G?BhX19Yb0@N$zW$pi`AhWi+>w}Rpsg9NxP=SU`Ozx|z z(oTMIgUEMk4Brfa0Nd<=(+JHIZOVDLFmfhf%B-0v0SNYODq|6KDG*}NIl zt?I=4qM+1_NWs`BkcADPNmJS)((eE>i2C-iL0pMJ;qt6XgJG^N!oAcQuH7wa?qxXHjAT-WTnvCsF=M4-*rtVeQ*@9D-pT3wMH`_M%0;Jc$A ze?#4CJl&J(>#0^J$Nze+HJ&kcbxsT^Qj6`yf&7Tgu5#9kJtH~nn7i*sT#(UHyc<>r zxG7UPC86r2+3;Xu;=X-X=u`dCY_BC+^{l%qB!hDopCx_ldi{;t<}LNi9YoPe4>iLY zVp&^@MZsmAB3$rt<}7a_m3IO*SyJ3%c?xM6v`suGL;G(WQknQxKT4{fG`>Ug^m5Me zBqAlRF2Sy-9!y^-#W3MsO{3Ci@`esXpLnElcinFMjd!LfLVg9fwU95ipZ&qMTPh$KCBh~??cMBlGQ8|pgLuElJh z(!WyB_t_EUtN?j*f@ZjD@zvEezRQ*oCSnilnd$Scc>eYSj2H!KnO$#YwSBu8sa>T$ zMgLo!(#XpSm;xY*05#`18FtQ)Y;N=!sUQi=p?sCKDP5X8KUn*Z2zKBOsuwWbOH;5a zXZndQV5sK3KMo~T+Y`G$-3{=~qW5m#DC=hehhNe8D>xT?lt{{XyLsPaB(|IyF~!Hu z9v?rdyrt%Ru?_5sCJ`9DVOv8YYu12?9-S`Qc@fzEAwt}!4F?rPHvc$^SYA&uT;g_h zO#-m|vy#fKF>K@OXx&QBt|7~U^!~AD+sj+aiJ>(P2K>iS(*iN2r(uA{gs#{MEarSX zSlXOpVG&+zO~WH9#u+GB&T(ydV~w|S{9cjX--h;XV?V$gTe3BC9Zu=*QlxJL9mE5! z^*NWQh>(;8cnMX=jZ;_gH08B)`oLiiUD~3G+;82nSD^pSk!R=tcN+Xp)t5@8ucY{_ zp~jw8P1`t!WW1PJJvvI<$ifwJ8xu@C zIrX1+L3s7&W2bi(GkwA^KqR|ZmON$>_8?a8je}Q;*)W-*kuH`+(g}EE8WL&XzrSHL z3|WYHPePP$+S&!`57}rrKTmbA2?(hde|24P34D(W1bornf?xg_$vw3>#UFZeNB^zQ z@ViHn2Yvp#4BU&Cc5vL9LZ3CwH3I; zMU~^e@jSn6m-MM)UMFxUV{VY!>vqsPn(MVo+JaQ)YoU;-1u}}~u*Q~+r#)omN zw#m3c>lK&MgL<^2nJPn;3hxU7=mFK7D0Za9^Lgn16mcJ2jHje3z%}}v7qxE^ z+5A-k-lA(C4?8Moc`>&^P$+J~>sEXjD8TmY_;K$6KM$T{?m? zlGxu3vPk&TZ!NDzv^mD$?8*bzQV-^0E5G%9e&pZl&BR?`W=+J{HPNNPRP=CA&;CXN z>mHhFT^Jl)rISU1dP-57SVZzZ?Ifbe<((N(dK%ZFAoXN!p2fB~RuVj7QQ* z8H`?x%zH_;w3bI1oAh=S-&$aEOZV%{)Zp<7F22}iWJiFphRXQOfrG94ScG0{=s%>& z-gH2Hu5ghoTNJ*DC?!%mE)js-*4O*H_U|@XnCo@fcc35H*b#5A2FjEwWDPgkBhs*UoK1M zH^o(;wP)Yk{S;T(3(|iXX!7ZvH!7Zonn;`KkN#}LgXmag61yP2ChIS&Ui6sfE$zx7 zcF4i2k0XC4Rgu@j^l_E=iWE@}F*1?H?x%~@V+T0E&Wpbd^Seb-Lk~S%_9@cCA<)G& zslJ_J#Bsx=w?E@K>wH%0sPeV!IhC5`SI46^-j2)_bu^UNm-JP)Aco1nmj`I2MFhqw z2N6XEt5#fmS*>GH?;CYEUi#$9L$^aYvL=yi_c*D1%KmU#f=n5;AgNqI*o)u+j%mh& z3GK-!ASNY`_&(etem4;5HwLW7u)WU8B9WGpv3Dcbp7Plb#wUsohIB)tFCIgrn8Zy1 zs5uE~upn>bFgf6t_RxV-CL(%}?SqlGLsF;AYTvytRe>vk9>o^yLu@G!6H_15Qe--n z|7}q06Y3bIK{lgmt8hwN*w7OSK?t`4lK0r9j;Lc5%#iZ^t#7v0dU=JVo*`)qJL;b4 zjmGosTK1+lOverkfBRU0o;iINleS*u5xiBrX!{ZWph#CEluh&=P?S`8xpJ151bR*mTIl1TVSq>Q6@F+jH3D@u zr$%-Mvf2`Anwt~jaa(fkmhiWR`}^e+eby?CfcRvMKy)k}!JucUV)vId9~m!EYC-nR zgLtEPVstueBn`)Bq1RqI_`>Zk)4Bh*Tszr>F>tlY$o;?Dm)kzQ&xthlt1=Y%Qx11nW zXOw}~=?ZH*&J53AVQO(`MflI5sV3nVGT`Gz?3InPt@t1e?A6n^*>q6fxR1dXvSkPBJ;SIC-7U`G-`rM(>-%LH8ll^uxhp!cQ+E?NDW#o`aS8b8Zjk!j|}5$9YP=e0pD{qCUazWTCir-v@eGZ_TvZ$mHKc=oG(Vl>?j0ah}i zYQI(t%K)H7%Ok9KAWIs~FZz@e>K}{osY%t#I(o#AM40a`K_KR#^ibs-*(9Du^p@>_ z)yRKk!DLHem7Q)rAxKjHJH;Tkv)2jvr-ST#=ctNdLB6Bcmv^nI4G^uKV2!XuPvl+DU&+?=hj0%P-qr07LH0IH*eJXLM61n)qV8+v+qFu+dA>lPfpX(fm*HuIuTZs*mLprKY9scI?S-8U@u zs18?w>2CgY=kzzMWD7pMTCVk)G~q2XCXuTz==8d{IhGx}KTbO36^e9VRY%^|rJ6p@ zJpq86UW48!Woicg(AITZzjQ9<3wr^WlOt~hRFGGzja3TK$_489$v;c(vSF9bwQen^ zoslS?_irhiNh{ZWq5kKRc*0=?HO^nzQsVQ~)}iJMBuq!o`5+4O=C`2EgtALvZ`?;O zrkZ3H48ESQGM3f=j;hvEohh-0Ao=edg{-(C7gwH!#UX*%yijn1Sj-%Kn$pwF8?r!h z>y&S}39k8#k#kmTE^Om9)oznvE{veF!7SMS)maFqCyF-(R@RX#q?NN<#OvY2E>;aq zbhW&WBGW`;&AKxibh4Za?Y}Npj$&L6?v#PfN&snnYFmTJmb-rxce0=&oNV8t>&l@K z+To*E1N+>>*<6q4tHNihvccZ)8uQvH?s%vYv?K0z6H^vbUEO4!H~D4qa)nKivH}ed z&dmJURzN(?tp+r%?X0?C>52Cv5*#vXzye_vaUH!#wp(Rar(3&Cz8zotO{4J{A@U0T z?1ky44cqG=VB4J)VDd!p&Z@XV9F(OrfbQ{oM$srAkw|>vO)gDLefZa~c2U^t&(_sK zGnO`Q*%D?5h-`z}RmqzbV4b9nT@a@`Cw??`F{YynGW0ddw>;K3i6ni&W?YJn<<0%i zIVXL$ngD#rFH=OZw1{-F0i}wD51~@fJLHsc&d`9dL=`VZquq_K zRW9sp3-wj8TQrhJgF!i$kB=bUvAgFJWA|XTX{It2hTb+uEvbu%eQUusKic3HR$Fk^ z9ljQ)l__%RQt?3Zi&8R-8P-zI!R^PTQq52$)W=KlNe=_8Sgwk`^>q1UY2xN9sQb(h z=AM_SUt!5tx!X6iI1RJ96SVb-4{7E5CtGpQ#eHu4_8S&_==MGoLLjiVjF>^C#Kg32 zGT4dSGdXnV_YENx^aFKSH9Oh0E4imzzw<)w9i2mz2FoAVFy0oJWB_%Q`M3U97)4_7 z-WtHkVr74rNU^QIc`&8NI+FB00C7An8KZFmrPM!ing+8{(rRAo>bl6;dYU$RUGam+ zRJM5*WYvB0f@bBg7BPQuyGL}(2lM%Y_sKCl$h+OW_itUJ=v66@C^HoCPUExlRJ43v z3YwunEXQ&nP};9DK6V+rYE!&)U**=jNmKEL7OMXs-T0=`mN&%itAQP>G;ORj7Nl1a5Pm;Zwio<}eO+`_rL1=mTk7opw*n;X=A7x{+h|$i+P3 zP5iu`lZRa11rr11BrPMYssx#pxv9A8OE7>?OGxr8V>(`qkzM^p&{ z@nf7KAk@pl^+wzWBdI&rO~2-qe%}O)B_sff{HCuVV0mU#kN2owD{#_fx9sZ6=AW5^ zEQvY48L^*aQgMBJnV)tw>q&zhT|yx?uj$TedtX%ji?Y`adOzJqW9kIj5Q#Ihw7G8S zhedR$u5QWts?+9x5J}>ZOArICaS;-!H2jRTdZ6T*$ZkTtR(^kNRnNVjMFd1`4_yxH z;jDK(3ECEzm!vS!5vUi`2A7!uLb{{;jCGA<7Wdp zjdG`%hUM-Hth_1pn3@J+Z5(3M;WpTSlWF?g==YmPW++_G6^rTclNHm&t4S?Q5!F+8 zVm|1PE)a{vvW#a|!2W?0GeV8#_~i@sNB-;(9L;d33RpbUjF8H^^{%RFylG=Z&f#wf z%WgLaT6Mq=p#!x^PanGc)Aj0_FFjO*C-X~p57{oxsno25gr`$%Wu2c(@sRwp$6ak+akw0%|1=+QZsRSf&wGJ!K`aeG0$gxC{D1k zuF)HexQ9@J!HAgB<>GER?@s75tJb`!nfg~E-M|&V)h_cKUrR;}FI+Dp;nY*BdqVf> z^Ga~#)XbaInJ}|lt<(njN-Nbj#2+TmOJ(`E&qT0u9L#^Ezz>0M1AKXCC7C^LbTS!S zV46GkhW{FSA40iz*VK@`1UD11Bpun0a?cTyV=VqwY*9_x9@}XvN}BwYU%|svgw;%Q zrjM?ofb8VxrAgZ4Z+T*zowI~YY5bOTN4drt_O_TELCk0{;sj^ei{lvA`Ohl**QFZ> zF4f_hZ7qBU!U3`Q@F!twq_1#;s}8HPGsRZ)w13*~23}+1M2bKcXKS~)g=I|&qrZA= zN3kU(C36@(;}Z&KEP!NTKgwzUGcAh+iPcq@2DS{FpDd%&p5ZPL{qR#)Zw36-Fi>fA zphY(bT1zjz#JX%EbEfv%N&|mV9wm6LQN!)7vXG zvE~DCD{pfmPf=7yi}Z?x;Un*ePTpltitDQdnincsZ41*gu-_S>IbL;E8U#6_X6RtA4iE1>YZ#w~Bcm zrgNCspQng}Dx_|=3%YX}4s5V_TaDIVIHu2&fGPo5k@4UzD4Ol64AIlXS9J^XF-$qr z9FM!Yt~1nV)p)8qD2Cj_=~yucauVOq;7O!ov+Q#JUb{@g zU@}=mkSnSqn996-M;!@&Z^q~44gm|y9dpU8>YL3S&j^h8Ds>mbZPJ{Y{ugV;^wo{R z!qP~Hdn7#SUTbO<%kTNPgyO!GOxxhU=4Fm)` z7Px3kT0+$6#yq!s$S6!)gkBs`uOiaLVM0@4l>zAKYdL6RN&Q_P&y3~~6qg}=5zeXQ zl|Y+!kS3q&4M+w&^BXETCqPCxi)rx=>$j0Qiy->#s&Wj|L|d&F3ETvBr4W_T!Y6$b zzT4B_((_S8kM)KtYv97VxW>L(sT>bu6>r~h-w)8Bq)S}GZvg6AQrsd5$h5RRFWOsy zcj6@-_m)ZFU{~J#h6-M@TibUU_p8gSc-Gjt?Cj0`$N|IX09-k-D9JqU>g!QIN?!ad z zVAN+(<%@pX@fpzfGDAglM=TDrNq6qo{N{;*pg>h9RIX&7n5%iD>6Ka+}G7TT5m!4I8+7;aFP< zt|+JpyQMbvH^v6Ta_YGOhO6+0lpF5GL4H5uruPp>QOTx4KMx!@EDQzi(pMCWd_)$Q zyQfXsvm2#rp%{Wli$j|nC&0v`ZuR#)-UP~$=*#!$51Dkv76c26_QA>c)aEM<`t% z%~pT3{*u~O$;p2nO13-`JV^dg3D2WM%albT0rq2F#6aCBZFbW&&s^?P;*4nE*1UGz zK?({Iz$t2f2jwEm`)IS_m#;~NdKTKu`4*Eh`7$Pje%$NaABOD^Q=YguVfwA9oood) zTMo?Zl0>Y_6}H}T*rUh>lG&jpOSr0zh>2pGSGMtkk(UNxT16M*30GI@-e$2OUCO?= z@MS*tHc_1RkGS$CUJ&5?fA>sJu2RdLUiJ>`4`cZ=_Z*Q6dtfg?+|)xk_IDOC_-Mtw zlY}tOh=x7E`+l@OafJE#=i+ictBfMFRa@U_Gt?XBUaVa7FL$8i!Tb$t&UMsjd9uGO zBd2BHE{~d0TE~Uqf=?fQ?BTP?V<4!wc;Vg?!3`hz2+7r-L{RhDzd1=N^BZ5?078Q_ zVOguunV713V9CeD#7j&N)ppp*WP3}{xz8Bmf$of4c>ef`D{YpmlXl{eshi{hTc;&~ zcDe6Vt-+X8eCPW3Tink0m>7n)2q$zthu;u^2q8HE?aGw5s-+jXL-2k^^N%^_03JbC zHcua-)@PSgPjMWO-llTt)GP%(gjJ`$IQw{b4;bHF0laJ>AoK%-t%@8l-7`j|gXMQ$ z4A=Lk{7tF>0Rd1v;P5T8$Hi&d)MJ+n#LSpz8#hDmx9cxS<9wu^J2e9XSs-UlmfXM5 zy9YS#72ig&$Us?n1qh{67QSFMwC`p`t-ThZoc;#Al(XfR4ncjIL{?Y&H9YIv%a)Z3 zwA+&*uvnD`@f%sO%q%wuuSIMe`g1+7T-+{_46kmP4rCluXO|)TXZTzX7YM|4j zhvM+*INuQV$7?}Yu+I!Y<#F%u!X2O}ETy}do`)~7BF?BTq|;abzt zW=+#USJTnPOZ5KwK|eMgOA7FqdyU=y(rfqr9ij(Od$j*4345^9o1}5DIkIv{eLaCa z+_0NCI$W2ZXzJWs&&S@bQDj+I(iK@J`f8F3&<)l*g|;ev}6?s1md6rf!INR0Iz6|3&%?k$j;jtJ z0-XWAFi$@HTLczbIBxaO0sa}Y<0^`ATs7LD?6i1XZp2H?vVGl|4s;e2+I@C3Idq)v z-|K&ah$`u=egT}44FGZOI}kj;CraA#CpeUx&>l|CDCo)ZpP=%)KL2^sty@N!{{9P6 z*J1tK8NZD?Ru%-Ao)o>-Kki=pFQCo{{^FJO6%_AxpcLpqAYC^fUk~p<`5Px|=q)tr zn}sSAZ{@v3tQ`iub%$Q;ow+H!^RChSx+!-UgAkL8^10mq0><%2t>Wv)a1CK(!apo*9zE6axWPC z7cl?qPu$;GCh>>k=K8LozL_QVwuE{2SP0w7tQ<5cSYkV8&p^bqasAeE`QTdG^H$aW ehXkY)IzsD61_(wbTGwO*o{fMh>N3QDcmD%||KeW& literal 0 HcmV?d00001 From e0f5e72e965b8f512ee0bd9c9b4c5f91c3a9d550 Mon Sep 17 00:00:00 2001 From: gangatp <145573667+gangatp@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:33:11 +0530 Subject: [PATCH 36/54] Update CMakeLists.txt to ignore cmake_osx_architecture in TESTS Previously libreSSL could not be built on arm64 machines, so there was a flag to build the test only for intel x86_64 machines. After updating the libreSSL library, it might not be the case anymore. So removing the CMAKE_OSX_ARCHITECTURE flag. --- CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30a31120a..6384b06e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,10 +237,6 @@ option(LIB3MF_TESTS "Switch whether the tests of lib3mf should be build" ON) message("LIB3MF_TESTS ... " ${LIB3MF_TESTS}) if(LIB3MF_TESTS) - if(APPLE) - # libressl only compiles on arm64 - SET(CMAKE_OSX_ARCHITECTURES "x86_64") - endif() enable_testing() add_subdirectory(Tests) endif() From 22d9d619d3d58359d491770d8b3b8676387b284a Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Wed, 15 May 2024 02:01:02 +0530 Subject: [PATCH 37/54] First batch of python examples --- SDK/Examples/Python/3mf_convert.py | 61 ++++++++++ SDK/Examples/Python/add_triangle.py | 25 ++++ SDK/Examples/Python/beam_lattice.py | 65 ++++++++++ SDK/Examples/Python/color_cube.py | 89 ++++++++++++++ SDK/Examples/Python/create_components.py | 60 +++++++++ SDK/Examples/Python/create_cube.py | 50 ++++++++ SDK/Examples/Python/extract_info.py | 30 +++++ SDK/Examples/Python/lib3mf_common.py | 148 +++++++++++++++++++++++ 8 files changed, 528 insertions(+) create mode 100644 SDK/Examples/Python/3mf_convert.py create mode 100644 SDK/Examples/Python/add_triangle.py create mode 100644 SDK/Examples/Python/beam_lattice.py create mode 100644 SDK/Examples/Python/color_cube.py create mode 100644 SDK/Examples/Python/create_components.py create mode 100644 SDK/Examples/Python/create_cube.py create mode 100644 SDK/Examples/Python/extract_info.py create mode 100644 SDK/Examples/Python/lib3mf_common.py diff --git a/SDK/Examples/Python/3mf_convert.py b/SDK/Examples/Python/3mf_convert.py new file mode 100644 index 000000000..53be1484a --- /dev/null +++ b/SDK/Examples/Python/3mf_convert.py @@ -0,0 +1,61 @@ +# An example to convert between 3MF and STL +import sys +from lib3mf_common import * + + +def find_extension(filename): + idx = filename.rfind('.') + if idx != -1: + return filename[idx:] + return "" + + +def convert(filename): + # Get a wrapper object + wrapper = get_wrapper() + + # Check version always + get_version(wrapper) + + extension = find_extension(filename).lower() + reader_name, writer_name, new_extension = "", "", "" + + if extension == ".stl": + reader_name = "stl" + writer_name = "3mf" + new_extension = ".3mf" + elif extension == ".3mf": + reader_name = "3mf" + writer_name = "stl" + new_extension = ".stl" + + if not reader_name: + print(f"Unknown input file extension: {extension}") + return -1 + + output_filename = filename[:-len(extension)] + new_extension + + model = wrapper.CreateModel() + reader = model.QueryReader(reader_name) + print(f"Reading {filename}...") + reader.ReadFromFile(filename) + + writer = model.QueryWriter(writer_name) + print(f"Writing {output_filename}...") + writer.WriteToFile(output_filename) + print("Done") + return 0 + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage:") + print("Convert 3MF to STL: python3 3mf_convert.py model.3mf") + print("Convert STL to 3MF: python3 3mf_convert.py model.stl") + else: + try: + result = convert(sys.argv[1]) + sys.exit(result) + except Exception as e: + print(str(e)) + sys.exit(1) \ No newline at end of file diff --git a/SDK/Examples/Python/add_triangle.py b/SDK/Examples/Python/add_triangle.py new file mode 100644 index 000000000..afaf16e4d --- /dev/null +++ b/SDK/Examples/Python/add_triangle.py @@ -0,0 +1,25 @@ +from lib3mf_common import * + +# Get wrapper +wrapper = get_wrapper() + +# Get version +get_version(wrapper) + +# Create a model +model = wrapper.CreateModel() + +# Initialize a mesh object +meshObject = model.AddMeshObject() + +# Now create 3 vertices +p1 = create_vertex_and_return_index(meshObject, 0, 0, 0) +p2 = create_vertex_and_return_index(meshObject, 0, 1, 0) +p3 = create_vertex_and_return_index(meshObject, 0, 0, 1) + +# Create a triangle with 3 positions +add_triangle(meshObject, p1, p2, p3) + +# Get a 3MF writer and write the single triangle +writer = model.QueryWriter("3mf") +writer.WriteToFile("triangle.3mf") diff --git a/SDK/Examples/Python/beam_lattice.py b/SDK/Examples/Python/beam_lattice.py new file mode 100644 index 000000000..b4a395184 --- /dev/null +++ b/SDK/Examples/Python/beam_lattice.py @@ -0,0 +1,65 @@ +# Beam Lattice example +from lib3mf_common import * + +# Get a wrapper object +wrapper = get_wrapper() + +# Check version always +get_version(wrapper) + +# Create a model and set name +model = wrapper.CreateModel() +mesh_object = model.AddMeshObject() +mesh_object.SetName("Beamlattice") + +# Modifiable size +fSizeX = 100.0 +fSizeY = 200.0 +fSizeZ = 300.0 + +# Define vertices (creates an array of lib3mf position objects) +vertices = [ + create_vertex(mesh_object, 0.0, 0.0, 0.0), + create_vertex(mesh_object, fSizeX, 0.0, 0.0), + create_vertex(mesh_object, fSizeX, fSizeY, 0.0), + create_vertex(mesh_object, 0.0, fSizeY, 0.0), + create_vertex(mesh_object, 0.0, 0.0, fSizeZ), + create_vertex(mesh_object, fSizeX, 0.0, fSizeZ), + create_vertex(mesh_object, fSizeX, fSizeY, fSizeZ), + create_vertex(mesh_object, 0.0, fSizeY, fSizeZ) +] + +# Define beam variables +r0 = 1.0 +r1 = 1.5 +r2 = 2.0 +r3 = 2.5 + +# Create a list of beams (strings are automatically converted to enums) +beams = [ + create_beam(2, 1, r0, r0, 'Butt', 'Butt'), + create_beam(0, 3, r0, r1, 'Sphere', 'Butt'), + create_beam(4, 5, r0, r2, 'Sphere', 'Butt'), + create_beam(6, 7, r0, r3, 'HemiSphere', 'Butt'), + create_beam(0, 1, r1, r0, 'HemiSphere', 'Butt'), + create_beam(5, 4, r1, r1, 'Sphere', 'HemiSphere'), + create_beam(2, 3, r1, r2, 'Sphere', 'Sphere'), + create_beam(7, 6, r1, r3, 'Butt', 'Butt'), + create_beam(1, 2, r2, r2, 'Butt', 'Butt'), + create_beam(6, 5, r2, r3, 'HemiSphere', 'Butt'), + create_beam(3, 0, r3, r0, 'Butt', 'Sphere'), + create_beam(4, 7, r3, r1, 'HemiSphere', 'HemiSphere') +] + +# Set geometry and beams +mesh_object.SetGeometry(vertices, []) +beam_lattice = mesh_object.BeamLattice() +beam_lattice.SetBeams(beams) +beam_lattice.SetMinLength(0.005) + +# Add mesh object to the model +model.AddBuildItem(mesh_object, wrapper.GetIdentityTransform()) + +# Write it out +writer = model.QueryWriter("3mf") +writer.WriteToFile("beamlattice.3mf") diff --git a/SDK/Examples/Python/color_cube.py b/SDK/Examples/Python/color_cube.py new file mode 100644 index 000000000..8cd7b0972 --- /dev/null +++ b/SDK/Examples/Python/color_cube.py @@ -0,0 +1,89 @@ +# Color cube example +from lib3mf_common import * + +# Get wrapper +wrapper = get_wrapper() + +# Get version +get_version(wrapper) + +# Create a model +model = wrapper.CreateModel() + +# Initialize a mesh object +mesh_object = model.AddMeshObject() +mesh_object.SetName("Colored Box") + +# Define cube size +fSizeX, fSizeY, fSizeZ = 100.0, 200.0, 300.0 + +# Create vertices +vertices = [ + create_vertex(mesh_object, 0.0, 0.0, 0.0), + create_vertex(mesh_object, fSizeX, 0.0, 0.0), + create_vertex(mesh_object, fSizeX, fSizeY, 0.0), + create_vertex(mesh_object, 0.0, fSizeY, 0.0), + create_vertex(mesh_object, 0.0, 0.0, fSizeZ), + create_vertex(mesh_object, fSizeX, 0.0, fSizeZ), + create_vertex(mesh_object, fSizeX, fSizeY, fSizeZ), + create_vertex(mesh_object, 0.0, fSizeY, fSizeZ) +] + +# Define triangles +triangles = [ + add_triangle(mesh_object, 2, 1, 0), + add_triangle(mesh_object, 0, 3, 2), + add_triangle(mesh_object, 4, 5, 6), + add_triangle(mesh_object, 6, 7, 4), + add_triangle(mesh_object, 0, 1, 5), + add_triangle(mesh_object, 5, 4, 0), + add_triangle(mesh_object, 2, 3, 7), + add_triangle(mesh_object, 7, 6, 2), + add_triangle(mesh_object, 1, 2, 6), + add_triangle(mesh_object, 6, 5, 1), + add_triangle(mesh_object, 3, 0, 4), + add_triangle(mesh_object, 4, 7, 3) +] + +# Set geometry +mesh_object.SetGeometry(vertices, triangles) + +# Define colors +color_group = model.AddColorGroup() +id_red = color_group.AddColor(wrapper.RGBAToColor(255, 0, 0, 255)) +id_green = color_group.AddColor(wrapper.RGBAToColor(0, 255, 0, 255)) +id_blue = color_group.AddColor(wrapper.RGBAToColor(0, 0, 255, 255)) +id_orange = color_group.AddColor(wrapper.RGBAToColor(255, 128, 0, 255)) +id_yellow = color_group.AddColor(wrapper.RGBAToColor(255, 255, 0, 255)) + +# Set triangle colors +sTriangleColorRed = create_triangle_color(color_group, id_red, id_red, id_red) +sTriangleColorGreen = create_triangle_color(color_group, id_green, id_green, id_green) +sTriangleColorBlue = create_triangle_color(color_group, id_blue, id_blue, id_blue) +sTriangleColor1 = create_triangle_color(color_group, id_orange, id_red, id_yellow) +sTriangleColor2 = create_triangle_color(color_group, id_yellow, id_green, id_orange) + + +# One-colored Triangles +mesh_object.SetTriangleProperties(0, sTriangleColorRed) +mesh_object.SetTriangleProperties(1, sTriangleColorRed) +mesh_object.SetTriangleProperties(2, sTriangleColorGreen) +mesh_object.SetTriangleProperties(3, sTriangleColorGreen) +mesh_object.SetTriangleProperties(4, sTriangleColorBlue) +mesh_object.SetTriangleProperties(5, sTriangleColorBlue) + +# Gradient-colored Triangles +mesh_object.SetTriangleProperties(6, sTriangleColor1) +mesh_object.SetTriangleProperties(7, sTriangleColor2) +mesh_object.SetTriangleProperties(8, sTriangleColor1) +mesh_object.SetTriangleProperties(9, sTriangleColor2) +mesh_object.SetTriangleProperties(10, sTriangleColor1) +mesh_object.SetTriangleProperties(11, sTriangleColor2) + +# Set object level property +mesh_object.SetObjectLevelProperty(sTriangleColorRed.ResourceID, sTriangleColorRed.PropertyIDs[0]) + +# Add build item and write to file +model.AddBuildItem(mesh_object, wrapper.GetIdentityTransform()) +writer = model.QueryWriter("3mf") +writer.WriteToFile("colorcube.3mf") diff --git a/SDK/Examples/Python/create_components.py b/SDK/Examples/Python/create_components.py new file mode 100644 index 000000000..d20bc5b3a --- /dev/null +++ b/SDK/Examples/Python/create_components.py @@ -0,0 +1,60 @@ +# An example that create multiple components using transformations +from lib3mf_common import * + +# Get wrapper +wrapper = get_wrapper() + +# Get version +get_version(wrapper) + +# Create a model +model = wrapper.CreateModel() +mesh_object = model.AddMeshObject() +mesh_object.SetName("Box") + +# Define the size of the box +fSizeX, fSizeY, fSizeZ = 10.0, 20.0, 30.0 + +# Create vertices +vertices = [ + create_vertex(mesh_object, 0, 0, 0), + create_vertex(mesh_object, fSizeX, 0, 0), + create_vertex(mesh_object, fSizeX, fSizeY, 0), + create_vertex(mesh_object, 0, fSizeY, 0), + create_vertex(mesh_object, 0, 0, fSizeZ), + create_vertex(mesh_object, fSizeX, 0, fSizeZ), + create_vertex(mesh_object, fSizeX, fSizeY, fSizeZ), + create_vertex(mesh_object, 0, fSizeY, fSizeZ) +] + +# Define triangles by vertices indices +triangle_indices = [ + (2, 1, 0), (0, 3, 2), (4, 5, 6), (6, 7, 4), + (0, 1, 5), (5, 4, 0), (2, 3, 7), (7, 6, 2), + (1, 2, 6), (6, 5, 1), (3, 0, 4), (4, 7, 3) +] + +# Create a list of triangles +triangles = [] +for v0, v1, v2 in triangle_indices: + triangles.append(add_triangle(mesh_object, v0, v1, v2)) + +# Set geometry to the mesh object after creating vertices and triangles +mesh_object.SetGeometry(vertices, triangles) + +# Adding components with different transformations +components_object = model.AddComponentsObject() +components_object.AddComponent(mesh_object, create_translation_matrix(0.0, 0.0, 0.0)) +components_object.AddComponent(mesh_object, create_translation_matrix(40.0, 60.0, 80.0)) +components_object.AddComponent(mesh_object, create_translation_matrix(120.0, 30.0, 70.0)) + +# Add the components object to the model as a build item +model.AddBuildItem(components_object, create_translation_matrix(0.0, 0.0, 0.0)) + +# Writing to files (3MF) +writer_3mf = model.QueryWriter("3mf") +writer_3mf.WriteToFile("components.3mf") + +# Dump to a STL file +writer_stl = model.QueryWriter("stl") +writer_stl.WriteToFile("components.stl") diff --git a/SDK/Examples/Python/create_cube.py b/SDK/Examples/Python/create_cube.py new file mode 100644 index 000000000..1e1da1bbc --- /dev/null +++ b/SDK/Examples/Python/create_cube.py @@ -0,0 +1,50 @@ +# Simple cube creation example +from lib3mf_common import * + +# Get a wrapper object +wrapper = get_wrapper() + +# Check version always +get_version(wrapper) + +# Create a model +model = wrapper.CreateModel() +mesh_object = model.AddMeshObject() +mesh_object.SetName("Box") + +# Define the size of the cube +fSizeX, fSizeY, fSizeZ = 100.0, 200.0, 300.0 + +# Create vertices +vertices = [ + create_vertex(mesh_object, 0, 0, 0), + create_vertex(mesh_object, fSizeX, 0, 0), + create_vertex(mesh_object, fSizeX, fSizeY, 0), + create_vertex(mesh_object, 0, fSizeY, 0), + create_vertex(mesh_object, 0, 0, fSizeZ), + create_vertex(mesh_object, fSizeX, 0, fSizeZ), + create_vertex(mesh_object, fSizeX, fSizeY, fSizeZ), + create_vertex(mesh_object, 0, fSizeY, fSizeZ) +] + +# Define triangles by vertices indices +triangle_indices = [ + (2, 1, 0), (0, 3, 2), (4, 5, 6), (6, 7, 4), + (0, 1, 5), (5, 4, 0), (2, 3, 7), (7, 6, 2), + (1, 2, 6), (6, 5, 1), (3, 0, 4), (4, 7, 3) +] + +# Create triangles +triangles = [] +for v0, v1, v2 in triangle_indices: + triangles.append(add_triangle(mesh_object, v0, v1, v2)) + +# Set geometry to the mesh object after creating vertices and triangles +mesh_object.SetGeometry(vertices, triangles) + +# Add build item with an identity transform +model.AddBuildItem(mesh_object, wrapper.GetIdentityTransform()) + +# Save the model to a 3MF file +writer = model.QueryWriter("3mf") +writer.WriteToFile("cube.3mf") diff --git a/SDK/Examples/Python/extract_info.py b/SDK/Examples/Python/extract_info.py new file mode 100644 index 000000000..3b9a06d91 --- /dev/null +++ b/SDK/Examples/Python/extract_info.py @@ -0,0 +1,30 @@ +# Extract info from a 3MF model +import sys +from lib3mf_common import * + + +def extract_info(file_path): + wrapper = get_wrapper() + model = wrapper.CreateModel() + + # Initialize a 3MF reader + read_3mf_file_to_model(model, file_path) + + # Print library version + get_version(wrapper) + + # Show meta data info + show_metadata_information(model.GetMetaDataGroup()) + + # Show slice stack info + show_slice_stack_information(model) + + # Show object info + show_object_information(model) + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python extract_info.py model.3mf") + sys.exit() + extract_info(sys.argv[1]) diff --git a/SDK/Examples/Python/lib3mf_common.py b/SDK/Examples/Python/lib3mf_common.py new file mode 100644 index 000000000..37b710d0c --- /dev/null +++ b/SDK/Examples/Python/lib3mf_common.py @@ -0,0 +1,148 @@ +import lib3mf +from lib3mf import get_wrapper + + +def create_vertex(_mesh, x, y, z): + position = lib3mf.Position() + position.Coordinates[0] = float(x) + position.Coordinates[1] = float(y) + position.Coordinates[2] = float(z) + _mesh.AddVertex(position) + return position + + +def create_vertex_and_return_index(_mesh, x, y, z): + position = lib3mf.Position() + position.Coordinates[0] = float(x) + position.Coordinates[1] = float(y) + position.Coordinates[2] = float(z) + vertex_index = _mesh.AddVertex(position) + return vertex_index + + +def add_triangle(_mesh, p1, p2, p3): + triangle = lib3mf.Triangle() + triangle.Indices[0] = p1 + triangle.Indices[1] = p2 + triangle.Indices[2] = p3 + _mesh.AddTriangle(triangle) + return triangle + + + +def get_version(wrapper): + major, minor, micro = wrapper.GetLibraryVersion() + print("Lib3MF version: {:d}.{:d}.{:d}".format(major, minor, micro), end="") + hasInfo, prereleaseinfo = wrapper.GetPrereleaseInformation() + if hasInfo: + print("-" + prereleaseinfo, end="") + hasInfo, buildinfo = wrapper.GetBuildInformation() + if hasInfo: + print("+" + buildinfo, end="") + print("") + + +# Show metadata information +def show_metadata_information(metadata_group): + count = metadata_group.GetMetaDataCount() + for i in range(count): + metadata = metadata_group.GetMetaData(i) + print(f"Metadata: {metadata.GetName()} = {metadata.GetValue()}") + + +# Show slice stack information +def show_slice_stack_information(model): + slice_stacks = model.GetSliceStacks() + while slice_stacks.MoveNext(): + slice_stack = slice_stacks.GetCurrentSliceStack() + print(f"Slice Stack: {slice_stack.GetResourceID()}") + + +# Show object information +def show_object_information(model): + object_iterator = model.GetObjects() + while object_iterator.MoveNext(): + obj = object_iterator.GetCurrentObject() + if obj.IsMeshObject(): + print(f"Mesh Object: {obj.GetResourceID()}") + elif obj.IsComponentsObject(): + print(f"Components Object: {obj.GetResourceID()}") + else: + print(f"Unknown Object: {obj.GetResourceID()}") + + +def read_3mf_file_to_model(model, file_path): + reader = model.QueryReader("3mf") + reader.SetStrictModeActive(False) + reader.ReadFromFile(file_path) + + +def create_translation_matrix(x, y, z): + matrix = lib3mf.Transform() + + # Default to identity matrix with translation + identity_matrix = [ + (1.0, 0.0, 0.0), # Row for X axis + (0.0, 1.0, 0.0), # Row for Y axis + (0.0, 0.0, 1.0), # Row for Z axis + (x, y, z) # Translation + ] + + # Fill the Fields with identity matrix values + for i in range(4): + for j in range(3): + matrix.Fields[i][j] = identity_matrix[i][j] + + return matrix + + +def convert_beam_string_to_enum(beam_mode): + beam_mode = str(beam_mode).lower() + if beam_mode == "butt": + return lib3mf.BeamLatticeCapMode.Butt + if beam_mode == "sphere": + return lib3mf.BeamLatticeCapMode.Sphere + if beam_mode == "hemisphere": + return lib3mf.BeamLatticeCapMode.HemiSphere + + +def create_beam(v0, v1, r0, r1, c0, c1): + beam = lib3mf.Beam() + beam.Indices[0] = v0 + beam.Indices[1] = v1 + beam.Radii[0] = r0 + beam.Radii[1] = r1 + beam.CapModes[0] = convert_beam_string_to_enum(c0) + beam.CapModes[1] = convert_beam_string_to_enum(c1) + return beam + +def create_triangle_color(color_group, color_id1, color_id2, color_id3): + triangle_properties = lib3mf.TriangleProperties() + triangle_properties.ResourceID = color_group.GetResourceID() + triangle_properties.PropertyIDs[0] = color_id1 + triangle_properties.PropertyIDs[1] = color_id2 + triangle_properties.PropertyIDs[2] = color_id3 + return triangle_properties + + +def convert_list_to_array(_list, _datatype): + _array_type = _datatype * len(_list) # Define the type of the array + _array = _array_type() # Create an instance of the array + + # Populate the array + for i, _list_entry in enumerate(_list): + _array[i] = _list_entry + + return _array + + +def vertex_array(_position_list): + return convert_list_to_array(_position_list, lib3mf.Position) + + +def triangle_array(_triangle_list): + return convert_list_to_array(_triangle_list, lib3mf.Triangle) + + +def beam_array(_beam_list): + return convert_list_to_array(_beam_list, lib3mf.Beam) From 13160670534e40397f8969ac6e12307493eef6ac Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Wed, 15 May 2024 02:09:08 +0530 Subject: [PATCH 38/54] Update 3mf copyright based on existing template --- SDK/.gitignore | 2 ++ SDK/Examples/Python/3mf_convert.py | 36 +++++++++++++++++++++++- SDK/Examples/Python/add_triangle.py | 34 ++++++++++++++++++++++ SDK/Examples/Python/beam_lattice.py | 36 +++++++++++++++++++++++- SDK/Examples/Python/color_cube.py | 36 +++++++++++++++++++++++- SDK/Examples/Python/create_components.py | 36 +++++++++++++++++++++++- SDK/Examples/Python/create_cube.py | 36 +++++++++++++++++++++++- SDK/Examples/Python/extract_info.py | 36 +++++++++++++++++++++++- SDK/Examples/Python/lib3mf_common.py | 34 ++++++++++++++++++++++ 9 files changed, 280 insertions(+), 6 deletions(-) diff --git a/SDK/.gitignore b/SDK/.gitignore index cfab9db9a..ffe319c10 100644 --- a/SDK/.gitignore +++ b/SDK/.gitignore @@ -5,3 +5,5 @@ Bin Bindings Examples/*/*.dll Examples/*/*.stl +.idea +cmake-build-* \ No newline at end of file diff --git a/SDK/Examples/Python/3mf_convert.py b/SDK/Examples/Python/3mf_convert.py index 53be1484a..6df74a264 100644 --- a/SDK/Examples/Python/3mf_convert.py +++ b/SDK/Examples/Python/3mf_convert.py @@ -1,4 +1,38 @@ -# An example to convert between 3MF and STL +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: An example to convert between 3MF and STL + +Interface version: 2.3.1 + +''' + + import sys from lib3mf_common import * diff --git a/SDK/Examples/Python/add_triangle.py b/SDK/Examples/Python/add_triangle.py index afaf16e4d..809d500d5 100644 --- a/SDK/Examples/Python/add_triangle.py +++ b/SDK/Examples/Python/add_triangle.py @@ -1,3 +1,37 @@ +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: Simplest 3mf example that just includes a single triangle + +Interface version: 2.3.1 + +''' + from lib3mf_common import * # Get wrapper diff --git a/SDK/Examples/Python/beam_lattice.py b/SDK/Examples/Python/beam_lattice.py index b4a395184..036f47747 100644 --- a/SDK/Examples/Python/beam_lattice.py +++ b/SDK/Examples/Python/beam_lattice.py @@ -1,4 +1,38 @@ -# Beam Lattice example +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: Beam Lattice example + +Interface version: 2.3.1 + +''' + + from lib3mf_common import * # Get a wrapper object diff --git a/SDK/Examples/Python/color_cube.py b/SDK/Examples/Python/color_cube.py index 8cd7b0972..a10eda52d 100644 --- a/SDK/Examples/Python/color_cube.py +++ b/SDK/Examples/Python/color_cube.py @@ -1,4 +1,38 @@ -# Color cube example +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: Color cube example + +Interface version: 2.3.1 + +''' + + from lib3mf_common import * # Get wrapper diff --git a/SDK/Examples/Python/create_components.py b/SDK/Examples/Python/create_components.py index d20bc5b3a..07be5b11b 100644 --- a/SDK/Examples/Python/create_components.py +++ b/SDK/Examples/Python/create_components.py @@ -1,4 +1,38 @@ -# An example that create multiple components using transformations +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: An example that creates multiple components using transformations + +Interface version: 2.3.1 + +''' + + from lib3mf_common import * # Get wrapper diff --git a/SDK/Examples/Python/create_cube.py b/SDK/Examples/Python/create_cube.py index 1e1da1bbc..d71b50887 100644 --- a/SDK/Examples/Python/create_cube.py +++ b/SDK/Examples/Python/create_cube.py @@ -1,4 +1,38 @@ -# Simple cube creation example +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: Create a simple cube + +Interface version: 2.3.1 + +''' + + from lib3mf_common import * # Get a wrapper object diff --git a/SDK/Examples/Python/extract_info.py b/SDK/Examples/Python/extract_info.py index 3b9a06d91..2bf23b05a 100644 --- a/SDK/Examples/Python/extract_info.py +++ b/SDK/Examples/Python/extract_info.py @@ -1,4 +1,38 @@ -# Extract info from a 3MF model +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: Extract info from a 3MF model + +Interface version: 2.3.1 + +''' + + import sys from lib3mf_common import * diff --git a/SDK/Examples/Python/lib3mf_common.py b/SDK/Examples/Python/lib3mf_common.py index 37b710d0c..64e5739cc 100644 --- a/SDK/Examples/Python/lib3mf_common.py +++ b/SDK/Examples/Python/lib3mf_common.py @@ -1,3 +1,37 @@ +'''++ + +Copyright (C) 2019 3MF Consortium (Vijai Kumar Suriyababu) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. + +Abstract: Common set of functions that are used across all examples + +Interface version: 2.3.1 + +''' + import lib3mf from lib3mf import get_wrapper From c7f7aa84d8f409391159b602677dd50b4bbe0fa7 Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Wed, 15 May 2024 16:21:55 +0530 Subject: [PATCH 39/54] Modify python imports to work with SDK package too (Even if lib3mf is not installed through PyPI, the examples would work as long as the SDK structure is maintained) --- SDK/Examples/Python/3mf_convert.py | 2 -- SDK/Examples/Python/add_triangle.py | 2 -- SDK/Examples/Python/beam_lattice.py | 2 -- SDK/Examples/Python/color_cube.py | 2 -- SDK/Examples/Python/create_components.py | 2 -- SDK/Examples/Python/create_cube.py | 2 -- SDK/Examples/Python/extract_info.py | 2 -- SDK/Examples/Python/lib3mf_common.py | 22 +++++++++++++++++----- 8 files changed, 17 insertions(+), 19 deletions(-) diff --git a/SDK/Examples/Python/3mf_convert.py b/SDK/Examples/Python/3mf_convert.py index 6df74a264..81a3a3cc5 100644 --- a/SDK/Examples/Python/3mf_convert.py +++ b/SDK/Examples/Python/3mf_convert.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: An example to convert between 3MF and STL Interface version: 2.3.1 diff --git a/SDK/Examples/Python/add_triangle.py b/SDK/Examples/Python/add_triangle.py index 809d500d5..311c71b87 100644 --- a/SDK/Examples/Python/add_triangle.py +++ b/SDK/Examples/Python/add_triangle.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: Simplest 3mf example that just includes a single triangle Interface version: 2.3.1 diff --git a/SDK/Examples/Python/beam_lattice.py b/SDK/Examples/Python/beam_lattice.py index 036f47747..f6ca9097a 100644 --- a/SDK/Examples/Python/beam_lattice.py +++ b/SDK/Examples/Python/beam_lattice.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: Beam Lattice example Interface version: 2.3.1 diff --git a/SDK/Examples/Python/color_cube.py b/SDK/Examples/Python/color_cube.py index a10eda52d..c7673d9e0 100644 --- a/SDK/Examples/Python/color_cube.py +++ b/SDK/Examples/Python/color_cube.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: Color cube example Interface version: 2.3.1 diff --git a/SDK/Examples/Python/create_components.py b/SDK/Examples/Python/create_components.py index 07be5b11b..63e4164e9 100644 --- a/SDK/Examples/Python/create_components.py +++ b/SDK/Examples/Python/create_components.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: An example that creates multiple components using transformations Interface version: 2.3.1 diff --git a/SDK/Examples/Python/create_cube.py b/SDK/Examples/Python/create_cube.py index d71b50887..1f82ecb0e 100644 --- a/SDK/Examples/Python/create_cube.py +++ b/SDK/Examples/Python/create_cube.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: Create a simple cube Interface version: 2.3.1 diff --git a/SDK/Examples/Python/extract_info.py b/SDK/Examples/Python/extract_info.py index 2bf23b05a..62e325587 100644 --- a/SDK/Examples/Python/extract_info.py +++ b/SDK/Examples/Python/extract_info.py @@ -24,8 +24,6 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: Extract info from a 3MF model Interface version: 2.3.1 diff --git a/SDK/Examples/Python/lib3mf_common.py b/SDK/Examples/Python/lib3mf_common.py index 64e5739cc..058a66c59 100644 --- a/SDK/Examples/Python/lib3mf_common.py +++ b/SDK/Examples/Python/lib3mf_common.py @@ -24,16 +24,28 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0-develop. - Abstract: Common set of functions that are used across all examples Interface version: 2.3.1 ''' -import lib3mf -from lib3mf import get_wrapper +import os +import sys + +try: + import lib3mf + from lib3mf import get_wrapper +except ImportError: + sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "Bindings", "Python")) + import Lib3MF as lib3mf + import Lib3MF + + + def get_wrapper(): + libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "Bin") + wrapper = Lib3MF.Wrapper(os.path.join(libpath, "lib3mf")) + return wrapper def create_vertex(_mesh, x, y, z): @@ -63,7 +75,6 @@ def add_triangle(_mesh, p1, p2, p3): return triangle - def get_version(wrapper): major, minor, micro = wrapper.GetLibraryVersion() print("Lib3MF version: {:d}.{:d}.{:d}".format(major, minor, micro), end="") @@ -150,6 +161,7 @@ def create_beam(v0, v1, r0, r1, c0, c1): beam.CapModes[1] = convert_beam_string_to_enum(c1) return beam + def create_triangle_color(color_group, color_id1, color_id2, color_id3): triangle_properties = lib3mf.TriangleProperties() triangle_properties.ResourceID = color_group.GetResourceID() From 8a26e0da486357c31a91a0a043eee78a842cd7ce Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Tue, 4 Jun 2024 19:05:02 +0530 Subject: [PATCH 40/54] Integration tests (#367) * Added CMake and CPack configuration for building and packaging lib3mf across all platforms, including Debian and RPM builds + VCPKG. * Updated and debugged workflows, .gitignore, and integration tests, ensuring smooth deployment and artifact handling. * Fixed paths and linking issues across Windows, macOS, and Linux, including handling symlinks and double zipping problems. * Enhanced SDK generation and included examples for various build variants, ensuring compatibility and thorough testing. * Cleaned up and finalized actions, environment variables, and documentation for consistent and efficient builds and deployments. --- .github/workflows/build.yml | 660 ++++++++++++++++-- .gitignore | 2 + CI/Dockerfile | 17 +- CI/extract_version.py | 32 + CI/integration_test.py | 128 ++++ CMakeLists.txt | 27 +- SDK/CPackExamples/Cpp/CMakeLists.txt | 70 ++ SDK/CPackExamples/Cpp/GenerateMake.sh | 7 + SDK/CPackExamples/Cpp/GenerateVS2015.bat | 10 + SDK/CPackExamples/Cpp/GenerateVS2017.bat | 10 + SDK/CPackExamples/Cpp/GenerateVS2019.bat | 10 + SDK/CPackExamples/Cpp/Source/BeamLattice.cpp | 159 +++++ SDK/CPackExamples/Cpp/Source/ColorCube.cpp | 183 +++++ SDK/CPackExamples/Cpp/Source/Components.cpp | 183 +++++ SDK/CPackExamples/Cpp/Source/Converter.cpp | 154 ++++ SDK/CPackExamples/Cpp/Source/Cube.cpp | 140 ++++ SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp | 269 +++++++ SDK/CPackExamples/Cpp/Source/SecureCube.cpp | 487 +++++++++++++ SDK/CPackExamples/Cpp/Source/Slice.cpp | 191 +++++ SDK/CPackExamples/Cpp/Source/TextureCube.cpp | 205 ++++++ SDK/CPackExamples/CppDynamic/CMakeLists.txt | 75 ++ SDK/CPackExamples/CppDynamic/GenerateMake.sh | 7 + .../CppDynamic/GenerateVS2015.bat | 10 + .../CppDynamic/GenerateVS2017.bat | 10 + .../CppDynamic/GenerateVS2019.bat | 10 + .../CppDynamic/Source/ExtractInfo.cpp | 271 +++++++ SDK/GenerateSDK_github.sh | 2 +- cmake/lib3mfConfig.cmake | 104 +++ 28 files changed, 3377 insertions(+), 56 deletions(-) create mode 100644 CI/extract_version.py create mode 100644 CI/integration_test.py create mode 100644 SDK/CPackExamples/Cpp/CMakeLists.txt create mode 100644 SDK/CPackExamples/Cpp/GenerateMake.sh create mode 100644 SDK/CPackExamples/Cpp/GenerateVS2015.bat create mode 100644 SDK/CPackExamples/Cpp/GenerateVS2017.bat create mode 100644 SDK/CPackExamples/Cpp/GenerateVS2019.bat create mode 100644 SDK/CPackExamples/Cpp/Source/BeamLattice.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/ColorCube.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Components.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Converter.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Cube.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/SecureCube.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Slice.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/TextureCube.cpp create mode 100644 SDK/CPackExamples/CppDynamic/CMakeLists.txt create mode 100644 SDK/CPackExamples/CppDynamic/GenerateMake.sh create mode 100644 SDK/CPackExamples/CppDynamic/GenerateVS2015.bat create mode 100644 SDK/CPackExamples/CppDynamic/GenerateVS2017.bat create mode 100644 SDK/CPackExamples/CppDynamic/GenerateVS2019.bat create mode 100644 SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp create mode 100644 cmake/lib3mfConfig.cmake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2260343e7..4b0c6d77b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,32 @@ on: [push, pull_request] +env: + # Set this to "on" to enable integration tests and "off" to skip integration tests + RUN_INTEGRATION_TESTS: "on" name: Build jobs: + set-lib3mf-version: + runs-on: ubuntu-20.04 + outputs: + lib3mf-version: ${{ steps.set-version.outputs.LIB3MF_VERSION }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Run version extraction script and set environment variable + id: set-version + run: | + LIB3MF_VERSION=$(python CI/extract_version.py) + echo "LIB3MF_VERSION=$LIB3MF_VERSION" >> $GITHUB_OUTPUT + - name: Echo version for debug + run: echo "LIB3MF_VERSION=${{ steps.set-version.outputs.LIB3MF_VERSION }}" + build-linux-memtest: runs-on: ubuntu-20.04 + needs: [set-lib3mf-version] steps: - run: sudo apt update - run: sudo apt install -y valgrind uuid-dev - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: sh cmake/GenerateMake.sh @@ -15,22 +35,23 @@ jobs: build-linux-ubi8-gcc12: runs-on: ubuntu-20.04 + needs: [set-lib3mf-version] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - run: sudo apt update - run: sudo apt install -y uuid-dev - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - run: mkdir -p build + - run: mkdir -p build - run: zip -r build/bindings.zip Autogenerated/Bindings - - name: Archive bindings - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: bindings.zip path: build/bindings.zip - - - name: Set up Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Docker Build @@ -39,30 +60,62 @@ jobs: context: . file: ./CI/Dockerfile platforms: linux/amd64 - tags: lib3mf_ubi8:latest - load: true - - - name: Docker Extract + tags: lib3mf_ubi8:latest + load: true + - + name: Docker Extract uses: shrink/actions-docker-extract@v3.0.0 id: extract - with: + with: image: lib3mf_ubi8:latest path: out.zip destination: dist - + - run: unzip out.zip working-directory: ./dist - - - name: Upload Artifact - uses: actions/upload-artifact@v2 + - name: Upload Artifact + uses: actions/upload-artifact@v4 with: name: lib3mf.so - path: dist/lib3mf.so.2 + path: dist/lib3mf.so.2 + - name: Extract File Name (CPacked Archive) + run: | + ZIP_FILE=$(ls dist/lib3mf-*.zip) + echo "ARTIFACT_NAME_ZIP=$(basename ${ZIP_FILE})" >> $GITHUB_ENV + shell: bash + - name: Upload Artifact (CPacked Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME_ZIP }} + path: dist/${{ env.ARTIFACT_NAME_ZIP }} + - name: Extract File Name (Debian) + run: | + DEB_FILE=$(ls dist/lib3mf-*.deb) + echo "ARTIFACT_NAME_DEB=$(basename ${DEB_FILE})" >> $GITHUB_ENV + shell: bash + - name: Upload Artifact (Debian Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME_DEB }} + path: dist/${{ env.ARTIFACT_NAME_DEB }} + - name: Extract File Name (RPM) + run: | + RPM_FILE=$(ls dist/lib3mf-*.rpm) + echo "ARTIFACT_NAME_RPM=$(basename ${RPM_FILE})" >> $GITHUB_ENV + shell: bash + - name: Upload Artifact (RPM Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME_RPM }} + path: dist/${{ env.ARTIFACT_NAME_RPM }} build-macos: runs-on: macos-latest + needs: [set-lib3mf-version] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: sh cmake/GenerateMake.sh "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" @@ -70,16 +123,29 @@ jobs: working-directory: ./build - run: ctest -V working-directory: ./build + - run: cpack -G ZIP -C Release + working-directory: ./build + - name: Extract File Name + run: | + ZIP_FILE=$(ls build/lib3mf-*.zip) + echo "ARTIFACT_NAME=$(basename ${ZIP_FILE})" >> $GITHUB_ENV + shell: bash - name: Archive Mac binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.dylib path: build/lib3mf.dylib + - name: Upload Artifact (CPacked Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: build/${{ env.ARTIFACT_NAME }} build-macos-debug: runs-on: macos-latest + needs: [set-lib3mf-version] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: sh cmake/GenerateMake.sh "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64 -DCMAKE_BUILD_TYPE=Debug" @@ -88,13 +154,14 @@ jobs: - run: ctest -V working-directory: ./build - name: Archive Mac binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.debug.dylib path: build/lib3mf.dylib codecoverage-macos: runs-on: macos-latest + needs: [set-lib3mf-version] steps: - uses: actions/checkout@v4 with: @@ -108,7 +175,7 @@ jobs: working-directory: ./build - run: ./Tests/codecoverage/run_codecoverage.sh - name: Archive Code Coverage Results - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: codecoverage.zip path: build/codecoverage.zip @@ -122,8 +189,11 @@ jobs: build-windows-release: runs-on: windows-2019 + needs: [set-lib3mf-version] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateVS2019.bat @@ -131,20 +201,34 @@ jobs: working-directory: ./build - run: ctest -V working-directory: ./build + - run: cpack -G ZIP -C Release + working-directory: ./build + - name: Extract File Name + run: | + $zipFile = Get-ChildItem build\lib3mf-*.zip -Name + echo "ARTIFACT_NAME=$zipFile" | Out-File -FilePath $env:GITHUB_ENV -Append + shell: pwsh - name: Archive Windows Release binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.dll path: build/Release/lib3mf.dll - name: Archive Windows Release lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.lib path: build/Release/lib3mf.lib + - name: Upload Artifact (CPacked Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: build/${{ env.ARTIFACT_NAME }} + build-windows-debug: runs-on: windows-2019 + needs: [set-lib3mf-version] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateVS2019.bat @@ -153,22 +237,23 @@ jobs: - run: ctest -V working-directory: ./build - name: Archive Windows Debug binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.debug.dll path: build/Debug/lib3mf.dll - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: lib3mf.pdb path: build/Debug/lib3mf.pdb - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: - name: lib3mf.debug.lib - path: build/Debug/lib3mf.lib + name: lib3mf.debug.lib + path: build/Debug/lib3mf.lib build-windows-32bit: runs-on: windows-2019 + needs: [set-lib3mf-version] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateVS2019_32bit.bat @@ -177,20 +262,21 @@ jobs: - run: ctest -V working-directory: ./build_32bit - name: Archive Windows 32 bit Release binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf_32bit.dll path: build_32bit/Release/lib3mf.dll - name: Archive Windows 32 bit Release lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf_32bit.lib path: build_32bit/Release/lib3mf.lib build-mingw-w64: runs-on: windows-2019 + needs: [set-lib3mf-version] steps: - run: choco install mingw -y - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateMinGW.bat @@ -198,44 +284,52 @@ jobs: working-directory: ./build - run: ctest -V working-directory: ./build + + assemble-sdk: runs-on: ubuntu-20.04 - needs: [build-windows-release, build-macos, build-linux-ubi8-gcc12] + needs: [set-lib3mf-version, build-windows-release, build-macos, build-linux-ubi8-gcc12] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - run: sudo apt install -y zip unzip - run: mkdir build - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: false - name: Download all workflow run artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: path: ./build - run: ls -Rl ./build - run: unzip bindings.zip/bindings.zip working-directory: ./build - run: bash SDK/GenerateSDK_github.sh - - name: Archive SDK artifact - uses: actions/upload-artifact@v2 + - name: Archive SDK artifact (Comprehensive) + uses: actions/upload-artifact@v4 with: name: lib3mf_sdk.zip path: build/lib3mf_sdk.zip + + deploy-linux: runs-on: ubuntu-20.04 - needs: [assemble-sdk] + needs: [set-lib3mf-version, assemble-sdk] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - - run: sudo apt install -y zip unzip + - run: sudo apt install -y zip unzip file - run: pwd - run: ls -Rl . - name: Download lib3mf_sdk artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib3mf_sdk.zip path: lib3mf_sdk.zip - run: ls -Rl . - name: Unpack the SDK run: | - unzip lib3mf_sdk.zip/lib3mf_sdk.zip + unzip lib3mf_sdk.zip/lib3mf_sdk.zip - name: Build CppDynamic run: | sh Examples/CppDynamic/GenerateMake.sh @@ -248,18 +342,75 @@ jobs: cd Examples/Cpp/build cmake --build . ./Example_ExtractInfo ../../Files/Helix.3mf + - name: Python Bindings + run: | + python Examples/Python/extract_info.py Examples/Files/Helix.3mf + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + - run: ls -Rl + - name: Download lib3mf cpack (Linux) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip + path: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip + - name: Unpack the cpacked SDK + run: | + unzip lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip && ls -Rl + - name: Build CppDynamic - CPack (Linux) + run: | + sh SDK/CPackExamples/CppDynamic/GenerateMake.sh + cd SDK/CPackExamples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Linux) + run: | + sh SDK/CPackExamples/Cpp/GenerateMake.sh + cd SDK/CPackExamples/Cpp/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Download lib3mf (Debian Linux) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + path: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + - name: Check the file type + run: | + file lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + file lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + - run: pwd + - run: ls -Rl . + - name: Install the debian package + run: | + sudo dpkg -i lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + - name: Build CppDynamic - CPack (Debian) + run: | + sh SDK/CPackExamples/CppDynamic/GenerateMake.sh + cd SDK/CPackExamples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Debian) + run: | + sh SDK/CPackExamples/Cpp/GenerateMake.sh + cd SDK/CPackExamples/Cpp/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + deploy-windows: runs-on: windows-2019 - needs: [assemble-sdk] + needs: [set-lib3mf-version, assemble-sdk] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - name: Download lib3mf_sdk artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib3mf_sdk.zip path: lib3mf_sdk.zip - name: Unpack the SDK run: | - unzip lib3mf_sdk.zip/lib3mf_sdk.zip + unzip lib3mf_sdk.zip/lib3mf_sdk.zip - name: Build CppDynamic run: | ./Examples/CppDynamic/GenerateVS2019.bat @@ -272,18 +423,48 @@ jobs: cd Examples/Cpp/build cmake --build . --config Release ./Release/Example_ExtractInfo.exe ../../Files/Helix.3mf + - name: Python Bindings + run: | + python Examples/Python/extract_info.py Examples/Files/Helix.3mf + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + - name: Download lib3mf cpack (Windows) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip + path: lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip + - name: Unpack the cpacked SDK + run: | + unzip lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip + - name: Build CppDynamic - CPack (Windows) + run: | + ./SDK/CPackExamples/CppDynamic/GenerateVS2019.bat + cd SDK/CPackExamples/CppDynamic/build + cmake --build . --config Release + ./Release/Example_ExtractInfo.exe ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Windows) + run: | + ./SDK/CPackExamples/Cpp/GenerateVS2019.bat + cd SDK/CPackExamples/Cpp/build + cmake --build . --config Release + ./Release/Example_ExtractInfo.exe ../../../Examples/Files/Helix.3mf + deploy-macos: runs-on: macos-latest - needs: [assemble-sdk] + needs: [set-lib3mf-version, assemble-sdk] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - name: Download lib3mf_sdk artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib3mf_sdk.zip path: lib3mf_sdk.zip - name: Unpack the SDK run: | - unzip lib3mf_sdk.zip/lib3mf_sdk.zip + unzip lib3mf_sdk.zip/lib3mf_sdk.zip - name: Build CppDynamic run: | sh Examples/CppDynamic/GenerateMake.sh @@ -295,4 +476,381 @@ jobs: sh Examples/Cpp/GenerateMake.sh cd Examples/Cpp/build cmake --build . - ./Example_ExtractInfo ../../Files/Helix.3mf \ No newline at end of file + ./Example_ExtractInfo ../../Files/Helix.3mf + - name: Python Bindings + run: | + python Examples/Python/extract_info.py Examples/Files/Helix.3mf + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + - name: Download lib3mf cpack (Darwin) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip + path: lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip + - run: ls -Rl . + - name: Unpack the cpacked SDK (Darwin) + run: | + unzip lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip + - name: Build CppDynamic - CPack (Darwin) + run: | + sh SDK/CPackExamples/CppDynamic/GenerateMake.sh + cd SDK/CPackExamples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Darwin) + run: | + sh SDK/CPackExamples/Cpp/GenerateMake.sh + cd SDK/CPackExamples/Cpp/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + + + set-integration-tests-status: + runs-on: ubuntu-20.04 + needs: [ deploy-linux, deploy-windows, deploy-macos ] + outputs: + run_integration_tests: ${{ steps.set-status.outputs.run_integration_tests }} + steps: + - name: Set status + id: set-status + run: | + if [ "${{ env.RUN_INTEGRATION_TESTS }}" == "on" ]; then + echo "run_integration_tests=true" >> $GITHUB_OUTPUT + else + echo "run_integration_tests=false" >> $GITHUB_OUTPUT + fi + + integration-tests-latest-release: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Get latest lib3mf SDK release info from GitHub API + id: get_lib3mf_release + run: | + LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep "browser_download_url.*zip" | cut -d '"' -f 4) + echo "LATEST_LIB3MF_URL=${LATEST_LIB3MF_URL}" >> $GITHUB_ENV + + - name: Download latest lib3mf SDK zip + run: | + wget ${{ env.LATEST_LIB3MF_URL }} -O latest_lib3mf_sdk.zip + + - name: Unpack the SDK + run: | + unzip latest_lib3mf_sdk.zip -d lib3mf_sdk + + - name: Build CppDynamic + run: | + sh lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: List files + run: | + ls -al + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ && cp -r lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log + + - name: Print results (Checks the total python script execution time) + run: | + LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') + LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" + + + integration-tests-last-two-releases: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Get latest lib3mf SDK release info from GitHub API + id: get_latest_release + run: | + LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep "browser_download_url.*zip" | cut -d '"' -f 4) + echo "LATEST_LIB3MF_URL=${LATEST_LIB3MF_URL}" >> $GITHUB_ENV + + - name: Get second latest lib3mf SDK release info from GitHub API + id: get_second_latest_release + run: | + SECOND_LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases | grep "browser_download_url.*zip" | cut -d '"' -f 4 | sed -n '2p') + echo "SECOND_LATEST_LIB3MF_URL=${SECOND_LATEST_LIB3MF_URL}" >> $GITHUB_ENV + + - name: Download latest lib3mf SDK zip + run: | + wget ${{ env.LATEST_LIB3MF_URL }} -O latest_lib3mf_sdk.zip + + - name: Download second latest lib3mf SDK zip + run: | + wget ${{ env.SECOND_LATEST_LIB3MF_URL }} -O second_latest_lib3mf_sdk.zip + + - name: Unpack the latest SDK + run: | + unzip latest_lib3mf_sdk.zip -d latest_lib3mf_sdk + + - name: Unpack the second latest SDK + run: | + unzip second_latest_lib3mf_sdk.zip -d second_latest_lib3mf_sdk + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ + + - name: Build and run CppDynamic with latest SDK + run: | + sh latest_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd latest_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + cp -r * ../../../../test_suites/ + + - name: Run integration tests with latest SDK + run: | + cd test_suites + /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log + + - name: Clean up latest SDK binaries + run: | + find test_suites -maxdepth 1 -type f ! -name 'integration_test.py' ! -name 'latest_sdk_test.log' ! -name 'second_latest_sdk_test.log' -exec rm -rf {} + + + - name: Build and run CppDynamic with second latest SDK + run: | + sh second_latest_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd second_latest_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + echo "First debug" + ls -al ../../../../ + echo "This will fail" + cp -r * ../../../../test_suites/ + + - name: Run integration tests with second latest SDK + run: | + cd test_suites + /usr/bin/time -v python integration_test.py 2>&1 | tee second_latest_sdk_test.log + + - name: Compare results (Checks the total python script execution time) + run: | + LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') + SECOND_LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/second_latest_sdk_test.log | awk '{print $8}') + LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + SECOND_LATEST_TOTAL_SECONDS=$(echo $SECOND_LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" + echo "Second Latest SDK execution time in seconds: ${SECOND_LATEST_TOTAL_SECONDS}" + # Compare the total seconds + if (( $(echo "$LATEST_TOTAL_SECONDS < $SECOND_LATEST_TOTAL_SECONDS" | bc -l) )); then + echo "New release is better" + else + echo "New release is worse" + fi + + integration-tests-latest-commit: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Download lib3mf_sdk artifact + uses: actions/download-artifact@v4 + with: + name: lib3mf_sdk.zip + path: lib3mf_sdk.zip + + - name: Unpack the SDK + run: | + unzip lib3mf_sdk.zip/lib3mf_sdk.zip -d lib3mf_sdk && ls -al + + - name: Build CppDynamic + run: | + sh lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ && cp -r lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log + + - name: Print results (Checks the total python script execution time) + run: | + LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') + LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" + + integration-test-last-commit-and-last-release: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Download lib3mf_sdk artifact + uses: actions/download-artifact@v4 + with: + name: lib3mf_sdk.zip + path: lib3mf_sdk.zip + + - name: Unpack the SDK + run: | + unzip lib3mf_sdk.zip/lib3mf_sdk.zip -d latest_commit_lib3mf_sdk && ls -al + + - name: Build CppDynamic with latest commit SDK + run: | + sh latest_commit_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd latest_commit_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ + + - name: Copy latest commit SDK to test suite + run: | + cp -r latest_commit_lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests with latest commit SDK + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_commit_sdk_test.log + + - name: Clean up latest SDK binaries + run: | + find test_suites -maxdepth 1 -type f ! -name 'integration_test.py' ! -name '*.log' -exec rm -rf {} + + + - name: Get latest lib3mf SDK release info from GitHub API + id: get_latest_release + run: | + LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep "browser_download_url.*zip" | cut -d '"' -f 4) + echo "LATEST_LIB3MF_URL=${LATEST_LIB3MF_URL}" >> $GITHUB_ENV + LATEST_RELEASE_NAME=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep '"tag_name"' | cut -d '"' -f 4) + echo "LATEST_RELEASE_NAME=${LATEST_RELEASE_NAME}" >> $GITHUB_ENV + + - name: Download latest lib3mf SDK release zip + run: | + wget ${{ env.LATEST_LIB3MF_URL }} -O latest_release_lib3mf_sdk.zip + + - name: Unpack the SDK from latest release + run: | + unzip latest_release_lib3mf_sdk.zip -d latest_release_lib3mf_sdk + + - name: Build CppDynamic with latest release SDK + run: | + sh latest_release_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd latest_release_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Copy latest release SDK to test suite + run: | + cp -r latest_release_lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests with latest release SDK + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_release_sdk_test.log + + - name: Compare results (Checks the total python script execution time) + id: compare_results + run: | + LATEST_COMMIT_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_commit_sdk_test.log | awk '{print $8}') + LATEST_RELEASE_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_release_sdk_test.log | awk '{print $8}') + LATEST_COMMIT_TOTAL_SECONDS=$(echo $LATEST_COMMIT_TIME | awk -F: '{ print ($1 * 60) + $2 }') + LATEST_RELEASE_TOTAL_SECONDS=$(echo $LATEST_RELEASE_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest commit SDK execution time in seconds: ${LATEST_COMMIT_TOTAL_SECONDS}" + echo "Latest release SDK execution time in seconds: ${LATEST_RELEASE_TOTAL_SECONDS}" + # Compare the total seconds + if (( $(echo "$LATEST_COMMIT_TOTAL_SECONDS < $LATEST_RELEASE_TOTAL_SECONDS" | bc -l) )); then + echo "Latest commit is better" + else + echo "Latest release is better" + fi + echo "Latest commit with SHA ${{ github.sha }} ran in ${LATEST_COMMIT_TOTAL_SECONDS} seconds" > results.txt + echo "Latest release with tag ${{ env.LATEST_RELEASE_NAME }} ran in ${LATEST_RELEASE_TOTAL_SECONDS} seconds" >> results.txt + + - name: Upload results artifact + uses: actions/upload-artifact@v4 + with: + name: integration-test-results + path: results.txt \ No newline at end of file diff --git a/.gitignore b/.gitignore index a41019361..87ee8d189 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ Include/Model/COM/NMR_COMVersion.h debug .DS_Store .vscode +.idea +cmake-build-* \ No newline at end of file diff --git a/CI/Dockerfile b/CI/Dockerfile index 846332f66..efedb0943 100644 --- a/CI/Dockerfile +++ b/CI/Dockerfile @@ -14,6 +14,7 @@ RUN \ tar \ gzip \ zip \ + rpm-build \ ${GCCTOOLSET} \ && microdnf clean all @@ -53,14 +54,28 @@ RUN cmake --build . RUN ctest -V . +# Add this line to generate a ZIP package with cpack +RUN cpack -G ZIP -C Release + +# Generate a debian package +RUN cpack -G DEB -C Release + +# Generate a RPM package +RUN cpack -G RPM -C Release + WORKDIR "/../../" RUN mkdir -p out RUN cp ./lib3mf-repo/build/lib3mf.so.2 ./out/ -RUN cd out && zip -r ../out.zip . +RUN cp ./lib3mf-repo/build/lib3mf-*-Linux.zip ./out/ +RUN cp ./lib3mf-repo/build/lib3mf-*-Linux.deb ./out/ + +RUN cp ./lib3mf-repo/build/lib3mf-*-Linux.rpm ./out/ + +RUN cd out && zip -r ../out.zip . diff --git a/CI/extract_version.py b/CI/extract_version.py new file mode 100644 index 000000000..4fc0b0d53 --- /dev/null +++ b/CI/extract_version.py @@ -0,0 +1,32 @@ +import os +import re + +def extract_version_from_cmake(): + cmake_file = 'CMakeLists.txt' + + if not os.path.exists(cmake_file): + raise FileNotFoundError(f"{cmake_file} not found in the current directory") + + with open(cmake_file, 'r') as file: + content = file.read() + + major = re.search(r'set\(LIB3MF_VERSION_MAJOR\s+([0-9]+)\)', content) + minor = re.search(r'set\(LIB3MF_VERSION_MINOR\s+([0-9]+)\)', content) + micro = re.search(r'set\(LIB3MF_VERSION_MICRO\s+([0-9]+)\)', content) + prerelease = re.search(r'set\(LIB3MF_VERSION_PRERELEASE\s+"([^"]*)"\)', content) + + if not major or not minor or not micro: + raise ValueError("Could not find version components in CMakeLists.txt") + + version = f"{major.group(1)}.{minor.group(1)}.{micro.group(1)}" + if prerelease and prerelease.group(1): + version += f"-{prerelease.group(1)}" + + return version + +if __name__ == "__main__": + try: + version = extract_version_from_cmake() + print(version) + except Exception as e: + print(f"Error: {str(e)}") \ No newline at end of file diff --git a/CI/integration_test.py b/CI/integration_test.py new file mode 100644 index 000000000..dbfb7bb3f --- /dev/null +++ b/CI/integration_test.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +""" +@original author: weismam + +lib3mf_integration: + tests whether a large number of 3MF files is parsed correctly by lib3MF / + the Example_ExtractInfo from the SDK + +""" + +import datetime, time +import subprocess +import os + + +def listFiles(root, extension): + lFiles = [] + for path, _, files in os.walk(root): + for name in files: + [_, fileextension] = os.path.splitext(name) + if extension == fileextension: + lFiles.append(os.path.join(path, name)) + return lFiles + + +# returns a list of files of the following pattern: $root/{*}/$inbetweenFolder/{*}/*.$extension +def listFilesIn(root, inbetweenFolder, extension): + lFiles = [] + for path, subdirs, _ in os.walk(root): + for subdir in subdirs: + if subdir == inbetweenFolder: + lFiles += listFiles(os.path.join(path, subdir), extension) + lFiles = list(set(lFiles)) + lFiles.sort() + return lFiles + + +def ExtractInfo(execCommand, fileName): + tStart = time.time() + proc = subprocess.Popen([execCommand, fileName], stdout=subprocess.PIPE) + pOut = "" + errLines = [] + for line in proc.stdout: + utf8line = line.decode("utf-8") + if "error" in utf8line: + errLines.append(utf8line) + if "warning" in utf8line: + errLines.append(utf8line) + pOut += utf8line + + proc.wait() + info = dict.fromkeys({'success', 'time', 'stdout'}) + info['time'] = time.time() - tStart + info['returncode'] = proc.returncode + info['success'] = len(errLines) == 0 + info['errLines'] = errLines + info['stdout'] = str(pOut) + return info + + +if __name__ == "__main__": + tStart = datetime.datetime.now() + + root = os.path.dirname(os.path.realpath(__file__)) + + execCommand = os.path.join(root, "Example_ExtractInfo") + + print("Execute once for testing") + os.system(execCommand) + print("Execution done") + + positives = [] + negatives = [] + + for suite in os.listdir(root): + suite_path = os.path.join(root, suite) + if os.path.isdir(suite_path) and suite.startswith("suite"): + positives += listFilesIn(suite_path, "positive_test_cases", ".3mf") + negatives += listFilesIn(suite_path, "negative_test_cases", ".3mf") + + nPos = len(positives) + nNeg = len(negatives) + nFiles = nPos + nNeg + + print(execCommand) + + brokenPositives = [] + iFile = 0 + for fileName in positives: + iFile += 1 + print("{:3.0f}%: {:s}".format(100 * (iFile / nFiles), fileName), flush=True) + info = ExtractInfo(execCommand, fileName) + if not info['returncode'] == 0: + print("Fatal Error: MUSTPASS file \"{:s}\" does not work with returncode {:d}:".format(fileName, + info['returncode'])) + brokenPositives.append(info) + if not info['success']: + print("Error: MUSTPASS file \"{:s}\" does not work:".format(fileName)) + print('Contains {:d} problem{:s}:'.format(len(info['errLines']), ['s', ''][len(info['errLines']) == 0])) + for errLine in info['errLines']: + print(errLine, end='') + print('=== Output === ') + print(info['stdout']) + print('=== /Output === ') + brokenPositives.append(info) + + runningNegatives = [] + for fileName in negatives: + iFile += 1 + print("{:3.0f}%: {:s}".format(100 * (iFile / nFiles), fileName), flush=True) + info = ExtractInfo(execCommand, fileName) + if not info['returncode'] >= 0: + print("Fatal Error: MUSTFAIL file \"{:s}\" does not work with returncode {:d}:".format(fileName, + info['returncode'])) + if info['success'] and info['returncode'] == 0: + print("Error: MUSTFAIL file \"{:s}\" works".format(fileName)) + runningNegatives.append(info) + + duration = datetime.datetime.now() - tStart + print("Tested a total of {:d} = ({:d} positive + {:d} negative) files in {:s}.".format( + nFiles, nPos, nNeg, str(duration).split('.')[0])) + + if nPos > 0: + print(" {:3d} / {:3d} MUSTPASS files passed ({:6.2f}%)".format(nPos - len(brokenPositives), nPos, + 100 * (1 - len(brokenPositives) / nPos))) + if len(negatives) > 0: + print(" {:3d} / {:3d} MUSTFAIL files failed ({:6.2f}%)".format(nNeg - len(runningNegatives), nNeg, + 100 * (1 - len(runningNegatives) / nNeg))) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6384b06e7..f7983c519 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,10 +46,10 @@ if (${MSVC}) # using Visual Studio C++ # this ensures that the min/max macros of minwindef.h are not used - add_definitions(-DNOMINMAX /W3) + add_definitions(-DNOMINMAX) + + #add_definitions(/W3) - add_definitions(/W3) - # add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") @@ -131,6 +131,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/I target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include) if (USE_INCLUDED_LIBZIP) + # Something goes here to check if submodules exist and initialize the submodules if it does not target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Libraries/libzip/Include) if(MSVC) target_compile_definitions(${PROJECT_NAME} PRIVATE _CRT_SECURE_NO_WARNINGS) @@ -226,6 +227,8 @@ endif(WIN32) configure_file(lib3mf.pc.in lib3mf.pc @ONLY) install(FILES ${CMAKE_BINARY_DIR}/lib3mf.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(FILES cmake/lib3mfConfig.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lib3mf) install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" @@ -249,3 +252,21 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${STARTUPPROJECT}) ENDIF() endif() + + +######################################################### +set(CPACK_PACKAGE_NAME "lib3mf") +set(CPACK_PACKAGE_VENDOR "3MF Consortium") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "lib3mf - An implementation of the 3D Manufacturing Format file standard") +set(CPACK_PACKAGE_VERSION "${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO}") +set(CPACK_PACKAGE_VERSION_MAJOR "${LIB3MF_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${LIB3MF_VERSION_MINOR}") +set(CPACK_PACKAGE_VERSION_PATCH "${LIB3MF_VERSION_MICRO}") +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") +set(CPACK_PACKAGE_CONTACT "lib3mf@3mf.io") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "3MF Consortium") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}") +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Source") + +######################################################### +include(CPack) diff --git a/SDK/CPackExamples/Cpp/CMakeLists.txt b/SDK/CPackExamples/Cpp/CMakeLists.txt new file mode 100644 index 000000000..e75ad0874 --- /dev/null +++ b/SDK/CPackExamples/Cpp/CMakeLists.txt @@ -0,0 +1,70 @@ +cmake_minimum_required (VERSION 3.5) +project(Examples) +set(CMAKE_CXX_STANDARD 11) + +# Determine the platform and set lib3mf_DIR accordingly +if(WIN32) + # Path for Windows + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS Cpp) +elseif(APPLE) + # Path for macOS (Darwin) + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS Cpp) +else() + # Path for Linux (Here we check twice to test for Debian / RPM packages properly) + find_package(lib3mf QUIET COMPONENTS Cpp) + # Check if the package was not found + if(NOT lib3mf_FOUND) + # lib3mf not found, so set lib3mf_DIR to the fallback directory + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + # Find package (lib3mf) + find_package(lib3mf REQUIRED COMPONENTS Cpp) + endif() +endif() + +add_definitions(-DTEXTURESPATH="${CMAKE_CURRENT_SOURCE_DIR}/../Files/Textures/") + +add_executable(Example_ColorCube Source/ColorCube.cpp) +target_link_libraries(Example_ColorCube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_ColorCube) + +add_executable(Example_Components Source/Components.cpp) +target_link_libraries(Example_Components lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Components) + +add_executable(Example_Converter Source/Converter.cpp) +target_link_libraries(Example_Converter lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Converter) + +add_executable(Example_Cube Source/Cube.cpp) +target_link_libraries(Example_Cube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Cube) + +add_executable(Example_SecureCube Source/SecureCube.cpp) +target_link_libraries(Example_SecureCube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_SecureCube) + +add_executable(Example_ExtractInfo Source/ExtractInfo.cpp) +target_link_libraries(Example_ExtractInfo lib3mf::lib3mf) +copy_lib3mf_libraries(Example_ExtractInfo) + +add_executable(Example_TextureCube Source/TextureCube.cpp) +target_link_libraries(Example_TextureCube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_TextureCube) + +add_executable(Example_Slice Source/Slice.cpp) +target_link_libraries(Example_Slice lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Slice) + +add_executable(Example_BeamLattice Source/BeamLattice.cpp) +target_link_libraries(Example_BeamLattice lib3mf::lib3mf) +copy_lib3mf_libraries(Example_BeamLattice) + +if (${MSVC}) + IF(${CMAKE_VERSION} VERSION_LESS 3.6.3) + MESSAGE ("Note: You need to manually select a StartUp-project in Visual Studio.") + ELSE() + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Example_Cube) + ENDIF() +endif() diff --git a/SDK/CPackExamples/Cpp/GenerateMake.sh b/SDK/CPackExamples/Cpp/GenerateMake.sh new file mode 100644 index 000000000..16fe9cf2b --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateMake.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +basepath="$(cd "$(dirname "$0")" && pwd)" +builddir="$basepath/build" +mkdir -p $builddir +cd $builddir +cmake .. -G "Unix Makefiles" "$@" \ No newline at end of file diff --git a/SDK/CPackExamples/Cpp/GenerateVS2015.bat b/SDK/CPackExamples/Cpp/GenerateVS2015.bat new file mode 100644 index 000000000..e6933cdeb --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateVS2015.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 14 2015 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/Cpp/GenerateVS2017.bat b/SDK/CPackExamples/Cpp/GenerateVS2017.bat new file mode 100644 index 000000000..4014d2f99 --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateVS2017.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 15 2017 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/Cpp/GenerateVS2019.bat b/SDK/CPackExamples/Cpp/GenerateVS2019.bat new file mode 100644 index 000000000..efa4f308f --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateVS2019.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 16 2019" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/Cpp/Source/BeamLattice.cpp b/SDK/CPackExamples/Cpp/Source/BeamLattice.cpp new file mode 100644 index 000000000..c1509cc88 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/BeamLattice.cpp @@ -0,0 +1,159 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +BeamLattice.cpp : 3MF beamlattice creation example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and beams +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFBeam fnCreateBeam(int v0, int v1, double r0, double r1, eLib3MFBeamLatticeCapMode c0, eLib3MFBeamLatticeCapMode c1) +{ + sLib3MFBeam result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Radii[0] = r0; + result.m_Radii[1] = r1; + result.m_CapModes[0] = c0; + result.m_CapModes[1] = c1; + return result; +} + + +void BeamLatticeExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Beamlattice example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Beamlattice"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(0); + std::vector beams(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create beams + double r0 = 1.0; + double r1 = 1.5; + double r2 = 2.0; + double r3 = 2.5; + beams[0] = fnCreateBeam(2, 1, r0, r0, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Butt); + beams[1] = fnCreateBeam(0, 3, r0, r1, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::Butt); + beams[2] = fnCreateBeam(4, 5, r0, r2, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::Butt); + beams[3] = fnCreateBeam(6, 7, r0, r3, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::Butt); + beams[4] = fnCreateBeam(0, 1, r1, r0, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::Butt); + beams[5] = fnCreateBeam(5, 4, r1, r1, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::HemiSphere); + beams[6] = fnCreateBeam(2, 3, r1, r2, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::Sphere); + beams[7] = fnCreateBeam(7, 6, r1, r3, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Butt); + beams[8] = fnCreateBeam(1, 2, r2, r2, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Butt); + beams[9] = fnCreateBeam(6, 5, r2, r3, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::Butt); + beams[10] = fnCreateBeam(3, 0, r3, r0, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Sphere); + beams[11] = fnCreateBeam(4, 7, r3, r1, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::HemiSphere); + meshObject->SetGeometry(vertices, triangles); + + // Set beamlattice geometry and metadata + PBeamLattice beamLattice = meshObject->BeamLattice(); + beamLattice->SetBeams(beams); + beamLattice->SetMinLength(0.005); + + PBeamSet set = beamLattice->AddBeamSet(); + set->SetName("Special Beams"); + set->SetIdentifier("bs1"); + std::vector references = { 2,0,5 }; + set->SetReferences(references); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + // Write file + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("beamlattice.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + BeamLatticeExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/ColorCube.cpp b/SDK/CPackExamples/Cpp/Source/ColorCube.cpp new file mode 100644 index 000000000..f1c46baca --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/ColorCube.cpp @@ -0,0 +1,183 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +ColorCube.cpp : 3MF Color Cube creation example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +sLib3MFTriangleProperties fnCreateTriangleColor(PColorGroup colorGroup, Lib3MF_uint32 colorID1, Lib3MF_uint32 colorID2, Lib3MF_uint32 colorID3) +{ + sLib3MFTriangleProperties sTriangleProperty; + sTriangleProperty.m_ResourceID = colorGroup->GetResourceID(); + sTriangleProperty.m_PropertyIDs[0] = colorID1; + sTriangleProperty.m_PropertyIDs[1] = colorID2; + sTriangleProperty.m_PropertyIDs[2] = colorID3; + return sTriangleProperty; +} + + +void CubeExample() { + PWrapper wrapper = wrapper->loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Color Cube example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Colored Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // define colors + PColorGroup colorGroup = model->AddColorGroup(); + Lib3MF_uint32 idRed = colorGroup->AddColor(wrapper->RGBAToColor(255, 0, 0, 255)); + Lib3MF_uint32 idGreen = colorGroup->AddColor(wrapper->RGBAToColor(0, 255, 0, 255)); + Lib3MF_uint32 idBlue = colorGroup->AddColor(wrapper->RGBAToColor(0, 0, 255, 255)); + Lib3MF_uint32 idOrange = colorGroup->AddColor(wrapper->RGBAToColor(255, 128, 0, 255)); + Lib3MF_uint32 idYellow = colorGroup->AddColor(wrapper->RGBAToColor(255, 255, 0, 255)); + + sLib3MFTriangleProperties sTriangleColorRed = fnCreateTriangleColor(colorGroup, idRed, idRed, idRed); + sLib3MFTriangleProperties sTriangleColorGreen = fnCreateTriangleColor(colorGroup, idGreen, idGreen, idGreen); + sLib3MFTriangleProperties sTriangleColorBlue = fnCreateTriangleColor(colorGroup, idBlue, idBlue, idBlue); + + sLib3MFTriangleProperties sTriangleColor1 = fnCreateTriangleColor(colorGroup, idOrange, idRed, idYellow); + sLib3MFTriangleProperties sTriangleColor2 = fnCreateTriangleColor(colorGroup, idYellow, idGreen, idOrange); + + // One-colored Triangles + meshObject->SetTriangleProperties(0, sTriangleColorRed); + meshObject->SetTriangleProperties(1, sTriangleColorRed); + meshObject->SetTriangleProperties(2, sTriangleColorGreen); + meshObject->SetTriangleProperties(3, sTriangleColorGreen); + meshObject->SetTriangleProperties(4, sTriangleColorBlue); + meshObject->SetTriangleProperties(5, sTriangleColorBlue); + // Gradient-colored Triangles + meshObject->SetTriangleProperties(6, sTriangleColor1); + meshObject->SetTriangleProperties(7, sTriangleColor2); + meshObject->SetTriangleProperties(8, sTriangleColor1); + meshObject->SetTriangleProperties(9, sTriangleColor2); + meshObject->SetTriangleProperties(10, sTriangleColor1); + meshObject->SetTriangleProperties(11, sTriangleColor2); + + // Object Level Property + meshObject->SetObjectLevelProperty(sTriangleColorRed.m_ResourceID, sTriangleColorRed.m_PropertyIDs[0]); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("colorcube.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + CubeExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/Components.cpp b/SDK/CPackExamples/Cpp/Source/Components.cpp new file mode 100644 index 000000000..f91499024 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Components.cpp @@ -0,0 +1,183 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Components.cpp : 3MF Components example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +sLib3MFTransform createTranslationMatrix(float x, float y, float z) +{ + sLib3MFTransform mMatrix; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + mMatrix.m_Fields[i][j] = (i == j) ? 1.0f : 0.0f; + } + } + + mMatrix.m_Fields[3][0] = x; + mMatrix.m_Fields[3][1] = y; + mMatrix.m_Fields[3][2] = z; + + return mMatrix; +} + + +void ComponentsExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Components example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 10.0f; + float fSizeY = 20.0f; + float fSizeZ = 30.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Create Component Object + PComponentsObject componentsObject = model->AddComponentsObject(); + + // Add first component + componentsObject->AddComponent(meshObject.get(), createTranslationMatrix(0.0f, 0.0f, 0.0f)); + + // Add second component + componentsObject->AddComponent(meshObject.get(), createTranslationMatrix(40.0f, 60.0f, 80.0f)); + + // Add third component + componentsObject->AddComponent(meshObject.get(), createTranslationMatrix(120.0f, 30.0f, 70.0f)); + + + // Add componentsobject as build item + model->AddBuildItem(componentsObject.get(), createTranslationMatrix(0.0f, 0.0f, 0.0f)); + + // Add translated componentsobject as build item + model->AddBuildItem(componentsObject.get(), createTranslationMatrix(200.0f, 40.0f, 10.0f)); + + // Add translated meshobject as build item + model->AddBuildItem(meshObject.get(), createTranslationMatrix(-40.0f, 0.0f, 20.0f)); + + // Output scene as STL and 3MF + PWriter _3mfWriter = model->QueryWriter("3mf"); + std::cout << "writing components.3mf..." << std::endl; + _3mfWriter->WriteToFile("components.3mf"); + + PWriter stlWriter = model->QueryWriter("stl"); + std::cout << "writing components.stl..." << std::endl; + stlWriter->WriteToFile("components.stl"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + ComponentsExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} + diff --git a/SDK/CPackExamples/Cpp/Source/Converter.cpp b/SDK/CPackExamples/Cpp/Source/Converter.cpp new file mode 100644 index 000000000..2fefdbc56 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Converter.cpp @@ -0,0 +1,154 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Converter.cpp : Can convert 3MFs to STL and back + +--*/ + +#include +#include +#include + +#ifndef __GNUC__ +#include +#endif + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +std::string FindExtension(std::string filename) { + // this emulates Windows' PathFindExtension + std::string::size_type idx; + idx = filename.rfind('.'); + + if (idx != std::string::npos) + { + return filename.substr(idx); + } + else + { + return ""; + } +} + + +int convert(std::string sFilename) { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Model Converter" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + // Extract Extension of filename + std::string sReaderName; + std::string sWriterName; + std::string sNewExtension; + std::string sExtension = FindExtension(sFilename); + std::transform(sExtension.begin(), sExtension.end(), sExtension.begin(), ::tolower); + + // Which Reader and Writer classes do we need? + if (sExtension == ".stl") { + sReaderName = "stl"; + sWriterName = "3mf"; + sNewExtension = ".3mf"; + } + if (sExtension == ".3mf") { + sReaderName = "3mf"; + sWriterName = "stl"; + sNewExtension = ".stl"; + } + if (sReaderName.length() == 0) { + std::cout << "unknown input file extension:" << sExtension << std::endl; + return -1; + } + + // Create new filename + std::string sOutputFilename = sFilename; + sOutputFilename.erase(sOutputFilename.length() - sExtension.length()); + sOutputFilename += sNewExtension; + + PModel model = wrapper->CreateModel(); + PReader reader = model->QueryReader(sReaderName); + + // Import Model from File + std::cout << "reading " << sFilename << "..." << std::endl; +#ifndef __GNUC__ + ULONGLONG nStartTicks = GetTickCount64(); +#endif + reader->ReadFromFile(sFilename); +#ifndef __GNUC__ + std::cout << "elapsed time: " << (GetTickCount64() - nStartTicks) << "ms" << std::endl; +#endif + + PWriter writer = model->QueryWriter(sWriterName); + std::cout << "writing " << sOutputFilename << "..." << std::endl; +#ifndef __GNUC__ + nStartTicks = GetTickCount64(); +#endif + writer->WriteToFile(sOutputFilename); +#ifndef __GNUC__ + std::cout << "elapsed time: " << (GetTickCount64() - nStartTicks) << "ms" << std::endl; +#endif + std::cout << "done" << std::endl; + return 0; +} + +int main(int argc, char** argv) { + // Parse Arguments + if (argc != 2) { + std::cout << "Usage: " << std::endl; + std::cout << "Convert 3MF to STL: Converter.exe model.3mf" << std::endl; + std::cout << "Convert STL to 3MF: Converter.exe model.stl" << std::endl; + return 0; + } + + try { + return convert(argv[1]); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/Cube.cpp b/SDK/CPackExamples/Cpp/Source/Cube.cpp new file mode 100644 index 000000000..18e99cb51 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Cube.cpp @@ -0,0 +1,140 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Cube.cpp : 3MF Cube creation example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + + +void CubeExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Cube example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("cube.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + CubeExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp b/SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp new file mode 100644 index 000000000..661cd30f2 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp @@ -0,0 +1,269 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +ExtractInfo.cpp : 3MF Read Example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +void ShowThumbnailInformation(PModel model) +{ + /* + // TODO: this is not yet implemented in Lib3MF + */ +} + + +void ShowMetaDataInformation(PMetaDataGroup metaDataGroup) +{ + Lib3MF_uint32 nMetaDataCount = metaDataGroup->GetMetaDataCount(); + + for (Lib3MF_uint32 iMeta = 0; iMeta < nMetaDataCount; iMeta++) { + + PMetaData metaData = metaDataGroup->GetMetaData(iMeta); + std::string sMetaDataValue = metaData->GetValue(); + std::string sMetaDataName = metaData->GetName(); + std::cout << "Metadatum: " << iMeta << ":" << std::endl; + std::cout << "Name = \"" << sMetaDataName << "\"" << std::endl; + std::cout << "Value = \"" << sMetaDataValue << "\"" << std::endl; + } +} + +void ShowSliceStack(PSliceStack sliceStack, std::string indent) +{ + std::cout << indent << "SliceStackID: " << sliceStack->GetResourceID() << std::endl; + if (sliceStack->GetSliceCount() > 0) { + std::cout << indent << " Slice count: " << sliceStack->GetSliceCount() << std::endl; + } + if (sliceStack->GetSliceRefCount() > 0) { + std::cout << indent << " Slice ref count: " << sliceStack->GetSliceRefCount() << std::endl; + for (Lib3MF_uint64 iSliceRef = 0; iSliceRef < sliceStack->GetSliceRefCount(); iSliceRef++) { + std::cout << indent << " Slice ref : " << sliceStack->GetSliceStackReference(iSliceRef)->GetResourceID() << std::endl; + } + } +} + +void ShowObjectProperties(PObject object) +{ + std::cout << " Name: \"" << object->GetName() << "\"" << std::endl; + std::cout << " PartNumber: \"" << object->GetPartNumber() << "\"" << std::endl; + + switch (object->GetType()) { + case eObjectType::Model: + std::cout << " Object type: model" << std::endl; + break; + case eObjectType::Support: + std::cout << " Object type: support" << std::endl; + break; + case eObjectType::SolidSupport: + std::cout << " Object type: solidsupport" << std::endl; + break; + case eObjectType::Other: + std::cout << " Object type: other" << std::endl; + break; + default: + std::cout << " Object type: invalid" << std::endl; + break; + } + + if (object->HasSlices(false)) { + PSliceStack sliceStack = object->GetSliceStack(); + ShowSliceStack(sliceStack, " "); + } + + if (object->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(object->GetMetaDataGroup()); + } +} + +void ShowMeshObjectInformation(PMeshObject meshObject) +{ + std::cout << "mesh object #" << meshObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(meshObject); + + Lib3MF_uint64 nVertexCount = meshObject->GetVertexCount(); + Lib3MF_uint64 nTriangleCount = meshObject->GetTriangleCount(); + PBeamLattice beamLattice = meshObject->BeamLattice(); + + // Output data + std::cout << " Vertex count: " << nVertexCount << std::endl; + std::cout << " Triangle count: " << nTriangleCount << std::endl; + + Lib3MF_uint64 nBeamCount = beamLattice->GetBeamCount(); + if (nBeamCount > 0) { + std::cout << " Beam count: " << nBeamCount << std::endl; + Lib3MF_uint32 nRepresentationMesh; + if (beamLattice->GetRepresentation(nRepresentationMesh)) + std::cout << " |_Representation Mesh ID: " << nRepresentationMesh << std::endl; + eLib3MFBeamLatticeClipMode eClipMode; + Lib3MF_uint32 nClippingMesh; + beamLattice->GetClipping(eClipMode, nClippingMesh); + if (eClipMode != eBeamLatticeClipMode::NoClipMode) + std::cout << " |_Clipping Mesh ID: " << nClippingMesh << "(mode=" << (int)eClipMode << ")" << std::endl; + if (beamLattice->GetBeamSetCount() > 0) { + std::cout << " |_BeamSet count: " << beamLattice->GetBeamSetCount() << std::endl; + } + } + +} + +void ShowTransform(sLib3MFTransform transform, std::string indent) { + std::cout << indent << "Transformation: [ " << transform.m_Fields[0][0] << " " << transform.m_Fields[1][0] << " " << transform.m_Fields[2][0] << " " << transform.m_Fields[3][0] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][1] << " " << transform.m_Fields[1][1] << " " << transform.m_Fields[2][1] << " " << transform.m_Fields[3][1] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][2] << " " << transform.m_Fields[1][2] << " " << transform.m_Fields[2][2] << " " << transform.m_Fields[3][2] << " ]" << std::endl; +} + +void ShowComponentsObjectInformation(PComponentsObject componentsObject) +{ + std::cout << "components object #" << componentsObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(componentsObject); + std::cout << " Component count: " << componentsObject->GetComponentCount() << std::endl; + for (Lib3MF_uint32 nIndex = 0; nIndex < componentsObject->GetComponentCount(); nIndex++) { + PComponent component = componentsObject->GetComponent(nIndex); + + std::cout << " Component " << nIndex << ": Object ID: " << component->GetObjectResourceID() << std::endl; + if (component->HasTransform()) { + ShowTransform(component->GetTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + } +} + + +void ExtractInfoExample(std::string sFileName) { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Read example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + // Import Model from 3MF File + { + PReader reader = model->QueryReader("3mf"); + // And deactivate the strict mode (default is "false", anyway. This just demonstrates where/how to use it). + reader->SetStrictModeActive(false); + reader->ReadFromFile(sFileName); + + for (Lib3MF_uint32 iWarning = 0; iWarning < reader->GetWarningCount(); iWarning++) { + Lib3MF_uint32 nErrorCode; + std::string sWarningMessage = reader->GetWarning(iWarning, nErrorCode); + std::cout << "Encountered warning #" << nErrorCode << " : " << sWarningMessage << std::endl; + } + } + ShowThumbnailInformation(model); + + ShowMetaDataInformation(model->GetMetaDataGroup()); + + PSliceStackIterator sliceStacks = model->GetSliceStacks(); + while (sliceStacks->MoveNext()) { + PSliceStack sliceStack = sliceStacks->GetCurrentSliceStack(); + ShowSliceStack(sliceStack, ""); + } + + PObjectIterator objectIterator = model->GetObjects(); + while (objectIterator->MoveNext()) { + PObject object = objectIterator->GetCurrentObject(); + if (object->IsMeshObject()) { + ShowMeshObjectInformation(model->GetMeshObjectByID(object->GetResourceID())); + } + else if (object->IsComponentsObject()) { + ShowComponentsObjectInformation(model->GetComponentsObjectByID(object->GetResourceID())); + } + else { + std::cout << "unknown object #" << object->GetResourceID() << ": " << std::endl; + } + } + + + PBuildItemIterator buildItemIterator = model->GetBuildItems(); + while (buildItemIterator->MoveNext()) { + PBuildItem buildItem = buildItemIterator->GetCurrent(); + + std::cout << "Build item (Object #" << buildItem->GetObjectResourceID() << "): " << std::endl; + + if (buildItem->HasObjectTransform()) { + ShowTransform(buildItem->GetObjectTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + std::cout << " Part number: \"" << buildItem->GetPartNumber() << "\"" << std::endl; + if (buildItem->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(buildItem->GetMetaDataGroup()); + } + } + + std::cout << "done" << std::endl; +} + + +int main(int argc, char** argv) { + // Parse Arguments + if (argc != 2) { + std::cout << "Usage: " << std::endl; + std::cout << "ExtractInfo.exe model.3mf" << std::endl; + return 0; + } + + try { + ExtractInfoExample(argv[1]); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/SecureCube.cpp b/SDK/CPackExamples/Cpp/Source/SecureCube.cpp new file mode 100644 index 000000000..de966b61f --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/SecureCube.cpp @@ -0,0 +1,487 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +SecureCube.cpp : 3MF encrypted Cube creation and read example. This is a sample +skeleton code provided to guide you to the process of reading and writing a 3MF +file using the Secure Content spec. Encryption and decryption processes are abstracted +so to avoid binding this sample to any particular implementation. If you would like +to check a working version of the process, there's a unit tests available on the 3MF code +base that implements the entire workflow using LibreSSL: EncryptionMethods.cpp +Tip: you could also copy buffers around - file won't be valid but you will be able +to run the entire process. +--*/ + +#include +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +namespace SecureContentCallbacks { + // Sample random number generation callback. Do not use this beyond the scope of this example as it is not really a random number generation function. + static void NotRandomBytesAtAll(Lib3MF_uint64 byteData, Lib3MF_uint64 size, Lib3MF_pvoid userData, Lib3MF_uint64 * bytesWritten) { + static Lib3MF_uint8 random = 0; + Lib3MF_uint8 * buffer = (Lib3MF_uint8 *)byteData; + *bytesWritten = size; + while (size > 0) + *(buffer + (--size)) = ++random; + } + + // Structure to hold encryption context for keys + struct KeyWrappingCbData { + CWrapper * wrapper; + }; + + + // Structure to hold encryption context for resources + struct ContentEncryptionCbData { + CWrapper * wrapper; + std::map context; + }; + + // Sample callback to wrap the key of an encryption process + static void WriteKeyWrappingCbSample( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + KeyWrappingCbData * cp = (KeyWrappingCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CAccessRight accessRight(cp->wrapper, access); + cp->wrapper->Acquire(&accessRight); + + // This is going to be called for each consumer you've registered to + PConsumer consumer = accessRight.GetConsumer(); + std::string consumerId = consumer->GetConsumerID(); + std::cout << "ConsumerID " << consumer->GetConsumerID() << std::endl; + // You can also check for keyid and keyvalue + + // A call could be made to first identify what the output buffer size should be. + // In that case, outSize will be 0 or outBuffer will be null, and the proper size must be placed in outNeeded. + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + return; + } + + // Query the data about the encryption process to be done + eWrappingAlgorithm algorithm = accessRight.GetWrappingAlgorithm(); + eMgfAlgorithm mask = accessRight.GetMgfAlgorithm(); + eDigestMethod diges = accessRight.GetDigestMethod(); + + // You should deal with the encryption process of the key. + // Use the encryption process to wrap inBuffer (plain) into outBuffer (cipher) using details above. + // Use KeyWrappingCbData to hold any information you'll be needing at this point. + throw std::runtime_error("TODO: Add your encryption wrapping process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + + // Finally, this function should use status to return the number of bytes needed, + // encrypted - or zero to indicate a failure. + *status = outSize; + } + + // Sample callback to encrypt contents of a resource + static void WriteContentEncryptionCbSample( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + ContentEncryptionCbData * cb = (ContentEncryptionCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CContentEncryptionParams cd(cb->wrapper, params); + cb->wrapper->Acquire(&cd); + + // A descriptor uniquely identifies the encryption process for a resource + Lib3MF_uint64 descriptor = cd.GetDescriptor(); + + // You can map the descriptor in use as you'll probably keep several + // contexts initialized at same time + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + // Use an existing context + localDescriptor->second++; + else { + // Initialize a new context + + // Retrieve the encryption key, if there is one + std::vector key; + cd.GetKey(key); + + // You can also use keyuuid to look up a key externally + std::string keyUUID = cd.GetKeyUUID(); + + // Retrieve the additional authenticaton data, if it has been used to encrypt + std::vector aad; + cd.GetAdditionalAuthenticationData(aad); + + // TODO: Initialize the encryption context + cb->context[cd.GetDescriptor()] = 0; + } + + // Attention to the order in which params are tested, it matters + if (0 == inSize || nullptr == inBuffer) { + // When input buffer is null or input size is 0, this is a request + // to finalize this encryption process and generating the authentication tag + // TODO: generate proper tag + std::vector tag = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + cd.SetAuthenticationTag(tag); + //add tag verification status here + *status = tag.size(); + } else if (0 == outSize || nullptr == outBuffer) { + // If outSize is zero or outBuffer is null (but inSize and inBuffer are not), + // this is a call to figure out the output buffer size. + // Put the respective value in outNeededSize. + *outNeededSize = inSize; + *status = inSize; + } else { + // Else, perform the encryption process + throw std::runtime_error("TODO: Add your encryption process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + //This function should use status to return the number of bytes needed, encrypted + // or verified - or zero to indicate a failure. + } + + static void ReadKeyWrappingCbSample( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + // A call could be made to first identify what the output buffer size should be. + // In that case, outSize will be 0 or outBuffer will be null, and the proper size must be placed in outNeeded. + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + return; + } + + KeyWrappingCbData * cp = (KeyWrappingCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CAccessRight accessRight(cp->wrapper, access); + cp->wrapper->Acquire(&accessRight); + + // This is going to be called for each consumer you've registered to + PConsumer consumer = accessRight.GetConsumer(); + std::string consumerId = consumer->GetConsumerID(); + std::cout << "ConsumerID " << consumer->GetConsumerID() << std::endl; + // You can also check for keyid and keyvalue + + // Query the data about the encryption process to be done + eWrappingAlgorithm algorithm = accessRight.GetWrappingAlgorithm(); + eMgfAlgorithm mask = accessRight.GetMgfAlgorithm(); + eDigestMethod diges = accessRight.GetDigestMethod(); + + // You should deal with the encryption process of the key. + // Use the encryption process to wrap inBuffer (cipher) into outBuffer (plain) using details above. + // Use KeyWrappingCbData to hold any information you'll be needing at this point. + throw std::runtime_error("TODO: Add your decryption wrapping process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + + // Finally, this function should use status to return the number of bytes needed, + // decrypted - or zero to indicate a failure. + *status = outSize; + } + + static void ReadContentEncryptionCbSample( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + ContentEncryptionCbData * cb = (ContentEncryptionCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CContentEncryptionParams cd(cb->wrapper, params); + cb->wrapper->Acquire(&cd); + + // A descriptor uniquely identifies the encryption process for a resource + Lib3MF_uint64 descriptor = cd.GetDescriptor(); + + // You can map the descriptor in use as you'll probably keep several + // contexts initialized at same time + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + // Use an existing context + localDescriptor->second++; + else { + // Initialize a new context + + // Retrieve the encryption key, if there is one + std::vector key; + cd.GetKey(key); + + // You can also use keyuuid to look up a key externally + std::string keyUUID = cd.GetKeyUUID(); + + // Retrieve the additional authenticaton data, if it has been used to encrypt + std::vector aad; + cd.GetAdditionalAuthenticationData(aad); + + // TODO: Initialize the encryption context + cb->context[cd.GetDescriptor()] = 0; + } + + // Attention to the order in which params are tested, it matters + if (0 == inSize || nullptr == inBuffer) { + // When input buffer is null or input size is 0, this is a request + // to finalize this encryption process and verify the authentication tag + std::vector tag; + cd.GetAuthenticationTag(tag); + // TODO: verify tag + *status = tag.size(); + } else if (0 == outSize || nullptr == outBuffer) { + // If outSize is zero or outBuffer is null (but inSize and inBuffer are not), + // this is a call to figure out the output buffer size. + // Put the respective value in outNeededSize. + *outNeededSize = inSize; + *status = inSize; + return; + } else { + // Else, perform the descryption process + throw std::runtime_error("TODO: Add your encryption process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + //This function should use status to return the number of bytes needed, decrypted + // or verified - or zero to indicate a failure. + } +}; + +void printVersion(CWrapper & wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper.GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper.GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper.GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) { + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) { + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +void WriteSecureContentExample(CWrapper & wrapper) { + + PModel model = wrapper.CreateModel(); + + // After initializing the model, set the random number generation callback + // A default one will be used if you don't, current implementation uses std::mt19937 + model->SetRandomNumberCallback(SecureContentCallbacks::NotRandomBytesAtAll, nullptr); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper.GetIdentityTransform()); + + // Move this mesh out of the root model file into another model + PPackagePart nonRootModel = model->FindOrCreatePackagePart("/3D/securecube.model"); + meshObject->SetPackagePart(nonRootModel.get()); + + // Locate the keystore and setup the resource as a secure content + PKeyStore keystore = model->GetKeyStore(); + + // Add you (client) as consumer of the resource. You'll need to do this + // to be able to have a chance to wrap the content key + // You can set optional public key and an optional key id + PConsumer consumer = keystore->AddConsumer("MyConsumerID", std::string(), std::string()); + + // Add a container for your secured resources. Resources within the same container will have a shared key. + PResourceDataGroup dataGroup = keystore->AddResourceDataGroup(); + + // Add access rights for your consumer into the datagroup + PAccessRight accessRight = dataGroup->AddAccessRight(consumer.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA1, eDigestMethod::SHA1); + + // Specify additional authentication data that you could use to further validate your encryption process + std::vector aad = { '3','M','F','C','o','n','s','o','r','t','i','u','m',' ','S','a','m','p','l','e' }; + + // This will effectively add your nonRootModel as a secure content + PResourceData resourceData = keystore->AddResourceData(dataGroup.get(), nonRootModel.get(), eEncryptionAlgorithm::AES256_GCM, eCompression::Deflate, aad); + + // Query the writer and setup the encryption before saving results + PWriter writer = model->QueryWriter("3mf"); + + // Setup Key Wrapping process + SecureContentCallbacks::KeyWrappingCbData keyData; + keyData.wrapper = &wrapper; + writer->AddKeyWrappingCallback(consumer->GetConsumerID(), SecureContentCallbacks::WriteKeyWrappingCbSample, &keyData); + + // Content Encryption process + SecureContentCallbacks::ContentEncryptionCbData contentData; + contentData.wrapper = &wrapper; + writer->SetContentEncryptionCallback(SecureContentCallbacks::WriteContentEncryptionCbSample, &contentData); + + // You'll need to complete the callback code for this call to work properly. + writer->WriteToFile("secureCube.3mf"); + + std::cout << "Writing Done." << std::endl; +} + +void ReadSecureContentExample(CWrapper & wrapper) { + PModel model = wrapper.CreateModel(); + + // After initializing the model, set the random number generation callback + // A default one will be used if you don't, current implementation uses std::mt19937 + model->SetRandomNumberCallback(SecureContentCallbacks::NotRandomBytesAtAll, nullptr); + + // Query the reader and setup the encryption before saving results + PReader reader = model->QueryReader("3mf"); + + // Setup Key Wrapping process + SecureContentCallbacks::KeyWrappingCbData keyData; + keyData.wrapper = &wrapper; + reader->AddKeyWrappingCallback("MyConsumerID", SecureContentCallbacks::ReadKeyWrappingCbSample, &keyData); + + // Content Encryption process + SecureContentCallbacks::ContentEncryptionCbData contentData; + contentData.wrapper = &wrapper; + reader->SetContentEncryptionCallback(SecureContentCallbacks::ReadContentEncryptionCbSample, &contentData); + + // You'll need to complete the callback code for this call to work properly. + reader->ReadFromFile("secureCube.3mf"); + + PKeyStore keystore = model->GetKeyStore(); + + // If you know the part you're interested in, look for its resource data + PPackagePart partPath = model->FindOrCreatePackagePart("/3D/securecube.model"); + PResourceData resourceData = keystore->FindResourceData(partPath.get()); + + // You can retrieve additional authenticated data using in the encryption + // to further verify the consistency of the process. At this time, it is + // already verified. + std::vector aad; + resourceData->GetAdditionalAuthenticationData(aad); + std::cout << "Additional Authenticated Data: "; + for (auto it = aad.begin(); it != aad.end(); ++it) { + std::cout << (char)*it; + } + std::cout << std::endl; + + std::cout << "Reading Done." << std::endl; + +} + +int main() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF SecureContent example" << std::endl; + printVersion(*wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + try { + WriteSecureContentExample(*wrapper); + ReadSecureContentExample(*wrapper); + } catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/Slice.cpp b/SDK/CPackExamples/Cpp/Source/Slice.cpp new file mode 100644 index 000000000..5b8a3828e --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Slice.cpp @@ -0,0 +1,191 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Slice.cpp : 3MF slice extension example + +--*/ + +#include +#include +#include +double const_pi() { return std::atan(1) * 4; } +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and beams +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + + +void SliceExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Slice example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Sliced Object [outbox]"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 100.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(-fSizeX, -fSizeY, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, -fSizeY, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(-fSizeX, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(-fSizeX, -fSizeY, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, -fSizeY, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(-fSizeX, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + // Set Geometry + meshObject->SetGeometry(vertices, triangles); + + + PSliceStack sliceStack = model->AddSliceStack(0.0); + + + + + + // Define an ellipse + Lib3MF_uint32 nSliceVertices = 20; + std::vector origSliceVertices(nSliceVertices); + for (Lib3MF_uint32 iSliceVertex = 0; iSliceVertex < nSliceVertices; iSliceVertex++) { + double angle = 2 * (const_pi()* iSliceVertex) / nSliceVertices; + origSliceVertices[iSliceVertex].m_Coordinates[0] = (Lib3MF_single)(fSizeX / 2 * std::cos(angle)); + origSliceVertices[iSliceVertex].m_Coordinates[1] = (Lib3MF_single)(fSizeY *std::sin(angle)); + } + + std::vector polygonIndices(nSliceVertices + 1); + for (Lib3MF_uint32 iPolygonIndex = 0; iPolygonIndex < polygonIndices.size(); iPolygonIndex++) { + polygonIndices[iPolygonIndex] = iPolygonIndex % nSliceVertices; + } + + Lib3MF_uint32 nSlices = 10; + + for (Lib3MF_uint32 iSlice = 0; iSlice < nSlices; iSlice++) { + PSlice slice = sliceStack->AddSlice((iSlice + 1.0)*fSizeZ / nSlices); + + // Rotate the ellpise as we move up z + double angle = 2 * (const_pi()*iSlice) / nSlices; + std::vector sliceVertices(nSliceVertices); + for (Lib3MF_uint32 iSliceVertex = 0; iSliceVertex < nSliceVertices; iSliceVertex++) { + double x = origSliceVertices[iSliceVertex].m_Coordinates[0]; + double y = origSliceVertices[iSliceVertex].m_Coordinates[1]; + sliceVertices[iSliceVertex].m_Coordinates[0] = (Lib3MF_single)(std::cos(angle)*x - std::sin(angle)*y); + sliceVertices[iSliceVertex].m_Coordinates[1] = (Lib3MF_single)(std::sin(angle)*x + std::cos(angle)*y); + } + + slice->SetVertices(sliceVertices); + slice->AddPolygon(polygonIndices); + } + + + // Assign this slice stack to mesh..., the exact geometry of the part + meshObject->AssignSliceStack(sliceStack.get()); + // which is not an exact representation of the sliced geometry + meshObject->SetSlicesMeshResolution(eSlicesMeshResolution::Lowres); + + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + // Write file + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("slice.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + SliceExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/TextureCube.cpp b/SDK/CPackExamples/Cpp/Source/TextureCube.cpp new file mode 100644 index 000000000..a8cd51d76 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/TextureCube.cpp @@ -0,0 +1,205 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +TextureCube.cpp : 3MF Texture Cube creation example. + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +PTexture2DGroup fnLoadModelTexture(PModel model, const std::string sOPCPath, const std::string sFilePath, eLib3MFTextureType eType, eLib3MFTextureTileStyle eTileStyleU, eLib3MFTextureTileStyle eTileStyleV) +{ + std::string sRelationshipType_Texture = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; + PAttachment attachment = model->AddAttachment(sOPCPath, sRelationshipType_Texture); + attachment->ReadFromFile(sFilePath); + + PTexture2D texture2D = model->AddTexture2DFromAttachment(attachment.get()); + + texture2D->SetContentType(eType); + texture2D->SetTileStyleUV(eTileStyleU, eTileStyleV); + + PTexture2DGroup textureGroup = model->AddTexture2DGroup(texture2D.get()); + return textureGroup; +} + + +sLib3MFTriangleProperties fnCreateTexture(PTexture2DGroup textureGroup, double u1, double v1, double u2, double v2, double u3, double v3) +{ + sLib3MFTriangleProperties property; + property.m_ResourceID = textureGroup->GetResourceID(); + property.m_PropertyIDs[0] = textureGroup->AddTex2Coord(sLib3MFTex2Coord({ u1, v1 })); + property.m_PropertyIDs[1] = textureGroup->AddTex2Coord(sLib3MFTex2Coord({ u2, v2 })); + property.m_PropertyIDs[2] = textureGroup->AddTex2Coord(sLib3MFTex2Coord({ u3, v3 })); + return property; +} + +void TextureExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Texture Cube example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Textured Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 100.0f; + float fSizeZ = 100.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + std::string sTextureFolder = TEXTURESPATH; + // add textures to 3mf package + std::cout << "sTextureFolder=\"" << sTextureFolder << "\"\n"; + auto textureGroup1 = fnLoadModelTexture(model, "/3D/Textures/tex1.png", sTextureFolder + "tex1.png", eTextureType::PNG, eTextureTileStyle::Wrap, eTextureTileStyle::Wrap); + auto textureGroup2 = fnLoadModelTexture(model, "/3D/Textures/tex2.png", sTextureFolder + "tex2.png", eTextureType::PNG, eTextureTileStyle::Mirror, eTextureTileStyle::Wrap); + auto textureGroup3 = fnLoadModelTexture(model, "/3D/Textures/tex3.png", sTextureFolder + "tex3.png", eTextureType::PNG, eTextureTileStyle::Wrap, eTextureTileStyle::Mirror); + auto textureGroup4 = fnLoadModelTexture(model, "/3D/Textures/tex4.png", sTextureFolder + "tex4.png", eTextureType::PNG, eTextureTileStyle::Clamp, eTextureTileStyle::Wrap); + auto textureGroup5 = fnLoadModelTexture(model, "/3D/Textures/tex5.png", sTextureFolder + "tex5.png", eTextureType::PNG, eTextureTileStyle::Wrap, eTextureTileStyle::Clamp); + auto textureGroup6 = fnLoadModelTexture(model, "/3D/Textures/tex6.png", sTextureFolder + "tex6.png", eTextureType::PNG, eTextureTileStyle::Clamp, eTextureTileStyle::Mirror); + + // Side 1 + meshObject->SetTriangleProperties(0, fnCreateTexture(textureGroup1, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(1, fnCreateTexture(textureGroup1, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 2 + meshObject->SetTriangleProperties(2, fnCreateTexture(textureGroup2, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(3, fnCreateTexture(textureGroup2, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 3 + // Go outside of bounds on this side + meshObject->SetTriangleProperties(4, fnCreateTexture(textureGroup3, -1.0, -1.0, 2.0, -1.0, 2.0, 2.0)); + meshObject->SetTriangleProperties(5, fnCreateTexture(textureGroup3, 2.0, 2.0, -1.0, 2.0, -1.0, -1.0)); + + // Side 4 + meshObject->SetTriangleProperties(6, fnCreateTexture(textureGroup4, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(7, fnCreateTexture(textureGroup4, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 5 + meshObject->SetTriangleProperties(8, fnCreateTexture(textureGroup5, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(9, fnCreateTexture(textureGroup5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 6 + meshObject->SetTriangleProperties(10, fnCreateTexture(textureGroup6, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(11, fnCreateTexture(textureGroup6, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Object Level Property + meshObject->SetObjectLevelProperty(textureGroup1->GetResourceID(), 1); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("texturegroup.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + TextureExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} + + diff --git a/SDK/CPackExamples/CppDynamic/CMakeLists.txt b/SDK/CPackExamples/CppDynamic/CMakeLists.txt new file mode 100644 index 000000000..4fee96e92 --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/CMakeLists.txt @@ -0,0 +1,75 @@ +#[[++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.5.0-develop3. + +Abstract: This is an autogenerated CMake Project that demonstrates the + usage of the Dynamic C++ bindings of the 3MF Library + +Interface version: 2.2.0 + + +]] + +cmake_minimum_required(VERSION 3.5) + +project(Example_ExtractInfo) +set(CMAKE_CXX_STANDARD 11) + +# Determine the platform and set lib3mf_DIR accordingly +if(WIN32) + # Path for Windows + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS CppDynamic) +elseif(APPLE) + # Path for macOS (Darwin) + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS CppDynamic) +else() + # Path for Linux (Here we check twice to test for Debian / RPM packages properly) + find_package(lib3mf QUIET COMPONENTS CppDynamic) + # Check if the package was not found + if(NOT lib3mf_FOUND) + # lib3mf not found, so set lib3mf_DIR to the fallback directory + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + # Find package (lib3mf) + find_package(lib3mf REQUIRED COMPONENTS CppDynamic) + endif() +endif() + +add_executable(Example_ExtractInfo "${CMAKE_CURRENT_SOURCE_DIR}/Source/ExtractInfo.cpp") + +# In case of CDynamic and CppDynamic, the lib3mf::lib3mf is simply an alias to an interface +target_link_libraries(Example_ExtractInfo lib3mf::lib3mf ${CMAKE_DL_LIBS}) + +if (${MSVC}) + IF(${CMAKE_VERSION} VERSION_LESS 3.6.3) + MESSAGE ("Note: You need to manually select a StartUp-project in Visual Studio.") + ELSE() + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Example_ExtractInfo) + ENDIF() +endif() + diff --git a/SDK/CPackExamples/CppDynamic/GenerateMake.sh b/SDK/CPackExamples/CppDynamic/GenerateMake.sh new file mode 100644 index 000000000..16fe9cf2b --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateMake.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +basepath="$(cd "$(dirname "$0")" && pwd)" +builddir="$basepath/build" +mkdir -p $builddir +cd $builddir +cmake .. -G "Unix Makefiles" "$@" \ No newline at end of file diff --git a/SDK/CPackExamples/CppDynamic/GenerateVS2015.bat b/SDK/CPackExamples/CppDynamic/GenerateVS2015.bat new file mode 100644 index 000000000..e6933cdeb --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateVS2015.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 14 2015 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/CppDynamic/GenerateVS2017.bat b/SDK/CPackExamples/CppDynamic/GenerateVS2017.bat new file mode 100644 index 000000000..4014d2f99 --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateVS2017.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 15 2017 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/CppDynamic/GenerateVS2019.bat b/SDK/CPackExamples/CppDynamic/GenerateVS2019.bat new file mode 100644 index 000000000..efa4f308f --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateVS2019.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 16 2019" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp b/SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp new file mode 100644 index 000000000..0a96b29f4 --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp @@ -0,0 +1,271 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +ExtractInfo.cpp : 3MF Read Example + +--*/ + +#include +#include +#include + +#include "lib3mf_dynamic.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +void ShowThumbnailInformation(PModel model) +{ + /* + // TODO: this is not yet implemented in lib3mf + */ +} + + +void ShowMetaDataInformation(PMetaDataGroup metaDataGroup) +{ + Lib3MF_uint32 nMetaDataCount = metaDataGroup->GetMetaDataCount(); + + for (Lib3MF_uint32 iMeta = 0; iMeta < nMetaDataCount; iMeta++) { + + PMetaData metaData = metaDataGroup->GetMetaData(iMeta); + std::string sMetaDataValue = metaData->GetValue(); + std::string sMetaDataName = metaData->GetName(); + std::cout << "Metadatum: " << iMeta << ":" << std::endl; + std::cout << "Name = \"" << sMetaDataName << "\"" << std::endl; + std::cout << "Value = \"" << sMetaDataValue << "\"" << std::endl; + } +} + +void ShowSliceStack(PSliceStack sliceStack, std::string indent) +{ + std::cout << indent << "SliceStackID: " << sliceStack->GetResourceID() << std::endl; + if (sliceStack->GetSliceCount() > 0) { + std::cout << indent << " Slice count: " << sliceStack->GetSliceCount() << std::endl; + } + if (sliceStack->GetSliceRefCount() > 0) { + std::cout << indent << " Slice ref count: " << sliceStack->GetSliceRefCount() << std::endl; + for (Lib3MF_uint64 iSliceRef = 0; iSliceRef < sliceStack->GetSliceRefCount(); iSliceRef++) { + std::cout << indent << " Slice ref : " << sliceStack->GetSliceStackReference(iSliceRef)->GetResourceID() << std::endl; + } + } +} + +void ShowObjectProperties(PObject object) +{ + std::cout << " Name: \"" << object->GetName() << "\"" << std::endl; + std::cout << " PartNumber: \"" << object->GetPartNumber() << "\"" << std::endl; + + switch (object->GetType()) { + case eObjectType::Model: + std::cout << " Object type: model" << std::endl; + break; + case eObjectType::Support: + std::cout << " Object type: support" << std::endl; + break; + case eObjectType::SolidSupport: + std::cout << " Object type: solidsupport" << std::endl; + break; + case eObjectType::Other: + std::cout << " Object type: other" << std::endl; + break; + default: + std::cout << " Object type: invalid" << std::endl; + break; + } + + if (object->HasSlices(false)) { + PSliceStack sliceStack = object->GetSliceStack(); + ShowSliceStack(sliceStack, " "); + } + + if (object->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(object->GetMetaDataGroup()); + } +} + +void ShowMeshObjectInformation(PMeshObject meshObject) +{ + std::cout << "mesh object #" << meshObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(meshObject); + + Lib3MF_uint64 nVertexCount = meshObject->GetVertexCount(); + Lib3MF_uint64 nTriangleCount = meshObject->GetTriangleCount(); + PBeamLattice beamLattice = meshObject->BeamLattice(); + + // Output data + std::cout << " Vertex count: " << nVertexCount << std::endl; + std::cout << " Triangle count: " << nTriangleCount << std::endl; + + Lib3MF_uint64 nBeamCount = beamLattice->GetBeamCount(); + if (nBeamCount > 0) { + std::cout << " Beam count: " << nBeamCount << std::endl; + Lib3MF_uint32 nRepresentationMesh; + if (beamLattice->GetRepresentation(nRepresentationMesh)) + std::cout << " |_Representation Mesh ID: " << nRepresentationMesh << std::endl; + eLib3MFBeamLatticeClipMode eClipMode; + Lib3MF_uint32 nClippingMesh; + beamLattice->GetClipping(eClipMode, nClippingMesh); + if (eClipMode != eBeamLatticeClipMode::NoClipMode) + std::cout << " |_Clipping Mesh ID: " << nClippingMesh << "(mode=" << (int)eClipMode << ")" << std::endl; + if (beamLattice->GetBeamSetCount() > 0) { + std::cout << " |_BeamSet count: " << beamLattice->GetBeamSetCount() << std::endl; + } + } + +} + +void ShowTransform(sLib3MFTransform transform, std::string indent) { + std::cout << indent << "Transformation: [ " << transform.m_Fields[0][0] << " " << transform.m_Fields[1][0] << " " << transform.m_Fields[2][0] << " " << transform.m_Fields[3][0] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][1] << " " << transform.m_Fields[1][1] << " " << transform.m_Fields[2][1] << " " << transform.m_Fields[3][1] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][2] << " " << transform.m_Fields[1][2] << " " << transform.m_Fields[2][2] << " " << transform.m_Fields[3][2] << " ]" << std::endl; +} + +void ShowComponentsObjectInformation(PComponentsObject componentsObject) +{ + std::cout << "components object #" << componentsObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(componentsObject); + std::cout << " Component count: " << componentsObject->GetComponentCount() << std::endl; + for (Lib3MF_uint32 nIndex = 0; nIndex < componentsObject->GetComponentCount(); nIndex++) { + PComponent component = componentsObject->GetComponent(nIndex); + + std::cout << " Component " << nIndex << ": Object ID: " << component->GetObjectResourceID() << std::endl; + if (component->HasTransform()) { + ShowTransform(component->GetTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + } +} + + +void ExtractInfoExample(std::string sFileName) { + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Read example" << std::endl; + + std::string libpath = ("."); // TODO: put the location of the Lib3MF-library file here. + auto wrapper = Lib3MF::CWrapper::loadLibrary(LIB3MF_LIBRARY_LOCATION); // TODO: add correct suffix of the library + + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + // Import Model from 3MF File + { + PReader reader = model->QueryReader("3mf"); + // And deactivate the strict mode (default is "false", anyway. This just demonstrates where/how to use it). + reader->SetStrictModeActive(false); + reader->ReadFromFile(sFileName); + + for (Lib3MF_uint32 iWarning = 0; iWarning < reader->GetWarningCount(); iWarning++) { + Lib3MF_uint32 nErrorCode; + std::string sWarningMessage = reader->GetWarning(iWarning, nErrorCode); + std::cout << "Encountered warning #" << nErrorCode << " : " << sWarningMessage << std::endl; + } + } + ShowThumbnailInformation(model); + + ShowMetaDataInformation(model->GetMetaDataGroup()); + + PSliceStackIterator sliceStacks = model->GetSliceStacks(); + while (sliceStacks->MoveNext()) { + PSliceStack sliceStack = sliceStacks->GetCurrentSliceStack(); + ShowSliceStack(sliceStack, ""); + } + + PObjectIterator objectIterator = model->GetObjects(); + while (objectIterator->MoveNext()) { + PObject object = objectIterator->GetCurrentObject(); + if (object->IsMeshObject()) { + ShowMeshObjectInformation(model->GetMeshObjectByID(object->GetResourceID())); + } + else if (object->IsComponentsObject()) { + ShowComponentsObjectInformation(model->GetComponentsObjectByID(object->GetResourceID())); + } + else { + std::cout << "unknown object #" << object->GetResourceID() << ": " << std::endl; + } + } + + + PBuildItemIterator buildItemIterator = model->GetBuildItems(); + while (buildItemIterator->MoveNext()) { + PBuildItem buildItem = buildItemIterator->GetCurrent(); + + std::cout << "Build item (Object #" << buildItem->GetObjectResourceID() << "): " << std::endl; + + if (buildItem->HasObjectTransform()) { + ShowTransform(buildItem->GetObjectTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + std::cout << " Part number: \"" << buildItem->GetPartNumber() << "\"" << std::endl; + if (buildItem->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(buildItem->GetMetaDataGroup()); + } + } + + std::cout << "done" << std::endl; +} + + +int main(int argc, char** argv) { + // Parse Arguments + if (argc != 2) { + std::cout << "Usage: " << std::endl; + std::cout << "ExtractInfo.exe model.3mf" << std::endl; + return 0; + } + + try { + ExtractInfoExample(argv[1]); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/GenerateSDK_github.sh b/SDK/GenerateSDK_github.sh index 6a59330ea..00a0d6236 100644 --- a/SDK/GenerateSDK_github.sh +++ b/SDK/GenerateSDK_github.sh @@ -43,4 +43,4 @@ echo "GITRevision = "`git rev-parse HEAD` >> $VERSIONTXT echo Zip SDK artifacts cd $SDKARTIFACT -zip -r ../$OUTFILE ./* || failed "Error zipping SDK" +zip -r ../$OUTFILE ./* || failed "Error zipping SDK" \ No newline at end of file diff --git a/cmake/lib3mfConfig.cmake b/cmake/lib3mfConfig.cmake new file mode 100644 index 000000000..f1305b8f5 --- /dev/null +++ b/cmake/lib3mfConfig.cmake @@ -0,0 +1,104 @@ +# lib3mfConfig.cmake + +if(VCPKG_TOOLCHAIN) + message("Lib3MF - VCPKG Tool Chain") + set(LIB3MF_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../..") +else() + message("Lib3MF - General CMake Tool Chain") + set(LIB3MF_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../..") +endif() + + +# Initial setup for known components and default selection +set(lib3mf_known_components "C" "CDynamic" "Cpp" "CppDynamic") +set(lib3mf_selected_variant "Cpp") # Default variant + +# Check if any known component was specified and select it +foreach(comp ${lib3mf_FIND_COMPONENTS}) + if(comp IN_LIST lib3mf_known_components) + set(lib3mf_selected_variant ${comp}) + break() # Use the first specified known component + endif() +endforeach() + +# Configure paths based on the selected variant +set(lib3mf_INCLUDE_DIR "${LIB3MF_ROOT_DIR}/include/Bindings/${lib3mf_selected_variant}") +set(lib3mf_LIBRARY_DIR "${LIB3MF_ROOT_DIR}/lib") +set(lib3mf_BINARY_DIR "${LIB3MF_ROOT_DIR}/bin") + +# Adjust library file name based on platform +if(WIN32) + set(lib3mf_LIBRARY "${lib3mf_BINARY_DIR}/lib3mf.dll") + set(lib3mf_LIBRARY_IMPORT "${lib3mf_LIBRARY_DIR}/lib3mf.lib") # For importing symbols +elseif(APPLE) + set(lib3mf_LIBRARY "${lib3mf_LIBRARY_DIR}/lib3mf.dylib") +else() # Linux and others + set(lib3mf_LIBRARY "${lib3mf_LIBRARY_DIR}/lib3mf.so") +endif() + +# Print the chosen variant +message("***********************************") +message("LIB3MF Chosen Variant : " ${lib3mf_selected_variant}) +message("***********************************") + +# Create a special interface for dynamic loading scenarios +if("${lib3mf_selected_variant}" STREQUAL "CppDynamic" OR "${lib3mf_selected_variant}" STREQUAL "CDynamic") + if("${lib3mf_selected_variant}" STREQUAL "CDynamic") + message("*****************************************************************************") + message("") + message(" For CDynamic Variant, an additional source called lib3mf_dynamic.cc ") + message(" is required ") + message(" It is made available using the variable LIB3MF_CDYNAMIC_ADDITIONAL_SOURCE ") + message(" You must append this to your sources ") + message("") + message("*****************************************************************************") + set(LIB3MF_CDYNAMIC_ADDITIONAL_SOURCE "${LIB3MF_ROOT_DIR}/include/Bindings/CDynamic/lib3mf_dynamic.cc") + endif() + add_library(lib3mfdynamic INTERFACE) + # Now alias lib3mfdynamic to include the namespace + add_library(lib3mf::lib3mf ALIAS lib3mfdynamic) + # Set properties and compile definitions for lib3mfdynamic + target_compile_definitions(lib3mfdynamic INTERFACE + "LIB3MF_LIBRARY_LOCATION=\"${lib3mf_LIBRARY}\"" + ) + target_include_directories(lib3mfdynamic INTERFACE "${lib3mf_INCLUDE_DIR}") +else() + # Define the imported target for static linking + add_library(lib3mf::lib3mf SHARED IMPORTED) + set_target_properties(lib3mf::lib3mf PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${lib3mf_INCLUDE_DIR}" + IMPORTED_LOCATION "${lib3mf_LIBRARY}" + ) + if(WIN32) + set_property(TARGET lib3mf::lib3mf PROPERTY IMPORTED_IMPLIB "${lib3mf_LIBRARY_IMPORT}") + endif() + + # Define a custom function to handle library copying + function(copy_lib3mf_libraries target) + if(TARGET ${target}) + if(APPLE) + # On macOS, copy .dylib files, preserving symlinks only if they don't already exist in the target directory + file(GLOB LIB3MF_FILES "${lib3mf_LIBRARY_DIR}/lib3mf.dylib*") + foreach(file ${LIB3MF_FILES}) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${file}" "$/$(basename ${file})" + COMMENT "Copying $(basename ${file}) to target directory on macOS if it is different") + endforeach() + + + elseif(UNIX) + # On Unix-like systems (excluding macOS), copy .so files, preserving symlinks + add_custom_command(TARGET ${target} POST_BUILD + COMMAND sh -c "cp -P '${lib3mf_LIBRARY_DIR}/lib3mf.so'* '$'" + COMMENT "Copying all lib3mf.so* files to target directory on Linux") + else() + # On Windows, directly copy the .dll file without worrying about symlinks + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${lib3mf_LIBRARY}" "$" + COMMENT "Copying lib3mf.dll to target directory on Windows") + endif() + else() + message(WARNING "Target '${target}' not found. lib3mf library was not copied.") + endif() + endfunction() +endif() From 88a66854d771c99b5fc9d3572dee3a2637a74b0d Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Tue, 4 Jun 2024 19:05:02 +0530 Subject: [PATCH 41/54] Integration tests (#367) + CMake Refactoring + CPack based Packaging introduction + CI / CD action improvements * Added CMake and CPack configuration for building and packaging lib3mf across all platforms, including Debian and RPM builds + VCPKG. * Updated and debugged workflows, .gitignore, and integration tests, ensuring smooth deployment and artifact handling. * Fixed paths and linking issues across Windows, macOS, and Linux, including handling symlinks and double zipping problems. * Enhanced SDK generation and included examples for various build variants, ensuring compatibility and thorough testing. * Cleaned up and finalized actions, environment variables, and documentation for consistent and efficient builds and deployments. --- .github/workflows/build.yml | 660 ++++++++++++++++-- .gitignore | 2 + CI/Dockerfile | 17 +- CI/extract_version.py | 32 + CI/integration_test.py | 128 ++++ CMakeLists.txt | 27 +- SDK/CPackExamples/Cpp/CMakeLists.txt | 70 ++ SDK/CPackExamples/Cpp/GenerateMake.sh | 7 + SDK/CPackExamples/Cpp/GenerateVS2015.bat | 10 + SDK/CPackExamples/Cpp/GenerateVS2017.bat | 10 + SDK/CPackExamples/Cpp/GenerateVS2019.bat | 10 + SDK/CPackExamples/Cpp/Source/BeamLattice.cpp | 159 +++++ SDK/CPackExamples/Cpp/Source/ColorCube.cpp | 183 +++++ SDK/CPackExamples/Cpp/Source/Components.cpp | 183 +++++ SDK/CPackExamples/Cpp/Source/Converter.cpp | 154 ++++ SDK/CPackExamples/Cpp/Source/Cube.cpp | 140 ++++ SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp | 269 +++++++ SDK/CPackExamples/Cpp/Source/SecureCube.cpp | 487 +++++++++++++ SDK/CPackExamples/Cpp/Source/Slice.cpp | 191 +++++ SDK/CPackExamples/Cpp/Source/TextureCube.cpp | 205 ++++++ SDK/CPackExamples/CppDynamic/CMakeLists.txt | 75 ++ SDK/CPackExamples/CppDynamic/GenerateMake.sh | 7 + .../CppDynamic/GenerateVS2015.bat | 10 + .../CppDynamic/GenerateVS2017.bat | 10 + .../CppDynamic/GenerateVS2019.bat | 10 + .../CppDynamic/Source/ExtractInfo.cpp | 271 +++++++ SDK/GenerateSDK_github.sh | 2 +- cmake/lib3mfConfig.cmake | 104 +++ 28 files changed, 3377 insertions(+), 56 deletions(-) create mode 100644 CI/extract_version.py create mode 100644 CI/integration_test.py create mode 100644 SDK/CPackExamples/Cpp/CMakeLists.txt create mode 100644 SDK/CPackExamples/Cpp/GenerateMake.sh create mode 100644 SDK/CPackExamples/Cpp/GenerateVS2015.bat create mode 100644 SDK/CPackExamples/Cpp/GenerateVS2017.bat create mode 100644 SDK/CPackExamples/Cpp/GenerateVS2019.bat create mode 100644 SDK/CPackExamples/Cpp/Source/BeamLattice.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/ColorCube.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Components.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Converter.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Cube.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/SecureCube.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/Slice.cpp create mode 100644 SDK/CPackExamples/Cpp/Source/TextureCube.cpp create mode 100644 SDK/CPackExamples/CppDynamic/CMakeLists.txt create mode 100644 SDK/CPackExamples/CppDynamic/GenerateMake.sh create mode 100644 SDK/CPackExamples/CppDynamic/GenerateVS2015.bat create mode 100644 SDK/CPackExamples/CppDynamic/GenerateVS2017.bat create mode 100644 SDK/CPackExamples/CppDynamic/GenerateVS2019.bat create mode 100644 SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp create mode 100644 cmake/lib3mfConfig.cmake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2260343e7..4b0c6d77b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,32 @@ on: [push, pull_request] +env: + # Set this to "on" to enable integration tests and "off" to skip integration tests + RUN_INTEGRATION_TESTS: "on" name: Build jobs: + set-lib3mf-version: + runs-on: ubuntu-20.04 + outputs: + lib3mf-version: ${{ steps.set-version.outputs.LIB3MF_VERSION }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Run version extraction script and set environment variable + id: set-version + run: | + LIB3MF_VERSION=$(python CI/extract_version.py) + echo "LIB3MF_VERSION=$LIB3MF_VERSION" >> $GITHUB_OUTPUT + - name: Echo version for debug + run: echo "LIB3MF_VERSION=${{ steps.set-version.outputs.LIB3MF_VERSION }}" + build-linux-memtest: runs-on: ubuntu-20.04 + needs: [set-lib3mf-version] steps: - run: sudo apt update - run: sudo apt install -y valgrind uuid-dev - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: sh cmake/GenerateMake.sh @@ -15,22 +35,23 @@ jobs: build-linux-ubi8-gcc12: runs-on: ubuntu-20.04 + needs: [set-lib3mf-version] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - run: sudo apt update - run: sudo apt install -y uuid-dev - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - run: mkdir -p build + - run: mkdir -p build - run: zip -r build/bindings.zip Autogenerated/Bindings - - name: Archive bindings - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: bindings.zip path: build/bindings.zip - - - name: Set up Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Docker Build @@ -39,30 +60,62 @@ jobs: context: . file: ./CI/Dockerfile platforms: linux/amd64 - tags: lib3mf_ubi8:latest - load: true - - - name: Docker Extract + tags: lib3mf_ubi8:latest + load: true + - + name: Docker Extract uses: shrink/actions-docker-extract@v3.0.0 id: extract - with: + with: image: lib3mf_ubi8:latest path: out.zip destination: dist - + - run: unzip out.zip working-directory: ./dist - - - name: Upload Artifact - uses: actions/upload-artifact@v2 + - name: Upload Artifact + uses: actions/upload-artifact@v4 with: name: lib3mf.so - path: dist/lib3mf.so.2 + path: dist/lib3mf.so.2 + - name: Extract File Name (CPacked Archive) + run: | + ZIP_FILE=$(ls dist/lib3mf-*.zip) + echo "ARTIFACT_NAME_ZIP=$(basename ${ZIP_FILE})" >> $GITHUB_ENV + shell: bash + - name: Upload Artifact (CPacked Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME_ZIP }} + path: dist/${{ env.ARTIFACT_NAME_ZIP }} + - name: Extract File Name (Debian) + run: | + DEB_FILE=$(ls dist/lib3mf-*.deb) + echo "ARTIFACT_NAME_DEB=$(basename ${DEB_FILE})" >> $GITHUB_ENV + shell: bash + - name: Upload Artifact (Debian Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME_DEB }} + path: dist/${{ env.ARTIFACT_NAME_DEB }} + - name: Extract File Name (RPM) + run: | + RPM_FILE=$(ls dist/lib3mf-*.rpm) + echo "ARTIFACT_NAME_RPM=$(basename ${RPM_FILE})" >> $GITHUB_ENV + shell: bash + - name: Upload Artifact (RPM Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME_RPM }} + path: dist/${{ env.ARTIFACT_NAME_RPM }} build-macos: runs-on: macos-latest + needs: [set-lib3mf-version] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: sh cmake/GenerateMake.sh "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" @@ -70,16 +123,29 @@ jobs: working-directory: ./build - run: ctest -V working-directory: ./build + - run: cpack -G ZIP -C Release + working-directory: ./build + - name: Extract File Name + run: | + ZIP_FILE=$(ls build/lib3mf-*.zip) + echo "ARTIFACT_NAME=$(basename ${ZIP_FILE})" >> $GITHUB_ENV + shell: bash - name: Archive Mac binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.dylib path: build/lib3mf.dylib + - name: Upload Artifact (CPacked Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: build/${{ env.ARTIFACT_NAME }} build-macos-debug: runs-on: macos-latest + needs: [set-lib3mf-version] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: sh cmake/GenerateMake.sh "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64 -DCMAKE_BUILD_TYPE=Debug" @@ -88,13 +154,14 @@ jobs: - run: ctest -V working-directory: ./build - name: Archive Mac binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.debug.dylib path: build/lib3mf.dylib codecoverage-macos: runs-on: macos-latest + needs: [set-lib3mf-version] steps: - uses: actions/checkout@v4 with: @@ -108,7 +175,7 @@ jobs: working-directory: ./build - run: ./Tests/codecoverage/run_codecoverage.sh - name: Archive Code Coverage Results - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: codecoverage.zip path: build/codecoverage.zip @@ -122,8 +189,11 @@ jobs: build-windows-release: runs-on: windows-2019 + needs: [set-lib3mf-version] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateVS2019.bat @@ -131,20 +201,34 @@ jobs: working-directory: ./build - run: ctest -V working-directory: ./build + - run: cpack -G ZIP -C Release + working-directory: ./build + - name: Extract File Name + run: | + $zipFile = Get-ChildItem build\lib3mf-*.zip -Name + echo "ARTIFACT_NAME=$zipFile" | Out-File -FilePath $env:GITHUB_ENV -Append + shell: pwsh - name: Archive Windows Release binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.dll path: build/Release/lib3mf.dll - name: Archive Windows Release lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.lib path: build/Release/lib3mf.lib + - name: Upload Artifact (CPacked Archive) + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: build/${{ env.ARTIFACT_NAME }} + build-windows-debug: runs-on: windows-2019 + needs: [set-lib3mf-version] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateVS2019.bat @@ -153,22 +237,23 @@ jobs: - run: ctest -V working-directory: ./build - name: Archive Windows Debug binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf.debug.dll path: build/Debug/lib3mf.dll - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: lib3mf.pdb path: build/Debug/lib3mf.pdb - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: - name: lib3mf.debug.lib - path: build/Debug/lib3mf.lib + name: lib3mf.debug.lib + path: build/Debug/lib3mf.lib build-windows-32bit: runs-on: windows-2019 + needs: [set-lib3mf-version] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateVS2019_32bit.bat @@ -177,20 +262,21 @@ jobs: - run: ctest -V working-directory: ./build_32bit - name: Archive Windows 32 bit Release binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf_32bit.dll path: build_32bit/Release/lib3mf.dll - name: Archive Windows 32 bit Release lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib3mf_32bit.lib path: build_32bit/Release/lib3mf.lib build-mingw-w64: runs-on: windows-2019 + needs: [set-lib3mf-version] steps: - run: choco install mingw -y - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: ./cmake/GenerateMinGW.bat @@ -198,44 +284,52 @@ jobs: working-directory: ./build - run: ctest -V working-directory: ./build + + assemble-sdk: runs-on: ubuntu-20.04 - needs: [build-windows-release, build-macos, build-linux-ubi8-gcc12] + needs: [set-lib3mf-version, build-windows-release, build-macos, build-linux-ubi8-gcc12] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - run: sudo apt install -y zip unzip - run: mkdir build - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: false - name: Download all workflow run artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: path: ./build - run: ls -Rl ./build - run: unzip bindings.zip/bindings.zip working-directory: ./build - run: bash SDK/GenerateSDK_github.sh - - name: Archive SDK artifact - uses: actions/upload-artifact@v2 + - name: Archive SDK artifact (Comprehensive) + uses: actions/upload-artifact@v4 with: name: lib3mf_sdk.zip path: build/lib3mf_sdk.zip + + deploy-linux: runs-on: ubuntu-20.04 - needs: [assemble-sdk] + needs: [set-lib3mf-version, assemble-sdk] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - - run: sudo apt install -y zip unzip + - run: sudo apt install -y zip unzip file - run: pwd - run: ls -Rl . - name: Download lib3mf_sdk artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib3mf_sdk.zip path: lib3mf_sdk.zip - run: ls -Rl . - name: Unpack the SDK run: | - unzip lib3mf_sdk.zip/lib3mf_sdk.zip + unzip lib3mf_sdk.zip/lib3mf_sdk.zip - name: Build CppDynamic run: | sh Examples/CppDynamic/GenerateMake.sh @@ -248,18 +342,75 @@ jobs: cd Examples/Cpp/build cmake --build . ./Example_ExtractInfo ../../Files/Helix.3mf + - name: Python Bindings + run: | + python Examples/Python/extract_info.py Examples/Files/Helix.3mf + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + - run: ls -Rl + - name: Download lib3mf cpack (Linux) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip + path: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip + - name: Unpack the cpacked SDK + run: | + unzip lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip && ls -Rl + - name: Build CppDynamic - CPack (Linux) + run: | + sh SDK/CPackExamples/CppDynamic/GenerateMake.sh + cd SDK/CPackExamples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Linux) + run: | + sh SDK/CPackExamples/Cpp/GenerateMake.sh + cd SDK/CPackExamples/Cpp/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Download lib3mf (Debian Linux) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + path: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + - name: Check the file type + run: | + file lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + file lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + - run: pwd + - run: ls -Rl . + - name: Install the debian package + run: | + sudo dpkg -i lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb + - name: Build CppDynamic - CPack (Debian) + run: | + sh SDK/CPackExamples/CppDynamic/GenerateMake.sh + cd SDK/CPackExamples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Debian) + run: | + sh SDK/CPackExamples/Cpp/GenerateMake.sh + cd SDK/CPackExamples/Cpp/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + deploy-windows: runs-on: windows-2019 - needs: [assemble-sdk] + needs: [set-lib3mf-version, assemble-sdk] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - name: Download lib3mf_sdk artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib3mf_sdk.zip path: lib3mf_sdk.zip - name: Unpack the SDK run: | - unzip lib3mf_sdk.zip/lib3mf_sdk.zip + unzip lib3mf_sdk.zip/lib3mf_sdk.zip - name: Build CppDynamic run: | ./Examples/CppDynamic/GenerateVS2019.bat @@ -272,18 +423,48 @@ jobs: cd Examples/Cpp/build cmake --build . --config Release ./Release/Example_ExtractInfo.exe ../../Files/Helix.3mf + - name: Python Bindings + run: | + python Examples/Python/extract_info.py Examples/Files/Helix.3mf + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + - name: Download lib3mf cpack (Windows) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip + path: lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip + - name: Unpack the cpacked SDK + run: | + unzip lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip + - name: Build CppDynamic - CPack (Windows) + run: | + ./SDK/CPackExamples/CppDynamic/GenerateVS2019.bat + cd SDK/CPackExamples/CppDynamic/build + cmake --build . --config Release + ./Release/Example_ExtractInfo.exe ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Windows) + run: | + ./SDK/CPackExamples/Cpp/GenerateVS2019.bat + cd SDK/CPackExamples/Cpp/build + cmake --build . --config Release + ./Release/Example_ExtractInfo.exe ../../../Examples/Files/Helix.3mf + deploy-macos: runs-on: macos-latest - needs: [assemble-sdk] + needs: [set-lib3mf-version, assemble-sdk] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} steps: - name: Download lib3mf_sdk artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib3mf_sdk.zip path: lib3mf_sdk.zip - name: Unpack the SDK run: | - unzip lib3mf_sdk.zip/lib3mf_sdk.zip + unzip lib3mf_sdk.zip/lib3mf_sdk.zip - name: Build CppDynamic run: | sh Examples/CppDynamic/GenerateMake.sh @@ -295,4 +476,381 @@ jobs: sh Examples/Cpp/GenerateMake.sh cd Examples/Cpp/build cmake --build . - ./Example_ExtractInfo ../../Files/Helix.3mf \ No newline at end of file + ./Example_ExtractInfo ../../Files/Helix.3mf + - name: Python Bindings + run: | + python Examples/Python/extract_info.py Examples/Files/Helix.3mf + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + - name: Download lib3mf cpack (Darwin) + uses: actions/download-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip + path: lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip + - run: ls -Rl . + - name: Unpack the cpacked SDK (Darwin) + run: | + unzip lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip + - name: Build CppDynamic - CPack (Darwin) + run: | + sh SDK/CPackExamples/CppDynamic/GenerateMake.sh + cd SDK/CPackExamples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + - name: Build Cpp - CPack (Darwin) + run: | + sh SDK/CPackExamples/Cpp/GenerateMake.sh + cd SDK/CPackExamples/Cpp/build + cmake --build . + ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + + + set-integration-tests-status: + runs-on: ubuntu-20.04 + needs: [ deploy-linux, deploy-windows, deploy-macos ] + outputs: + run_integration_tests: ${{ steps.set-status.outputs.run_integration_tests }} + steps: + - name: Set status + id: set-status + run: | + if [ "${{ env.RUN_INTEGRATION_TESTS }}" == "on" ]; then + echo "run_integration_tests=true" >> $GITHUB_OUTPUT + else + echo "run_integration_tests=false" >> $GITHUB_OUTPUT + fi + + integration-tests-latest-release: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Get latest lib3mf SDK release info from GitHub API + id: get_lib3mf_release + run: | + LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep "browser_download_url.*zip" | cut -d '"' -f 4) + echo "LATEST_LIB3MF_URL=${LATEST_LIB3MF_URL}" >> $GITHUB_ENV + + - name: Download latest lib3mf SDK zip + run: | + wget ${{ env.LATEST_LIB3MF_URL }} -O latest_lib3mf_sdk.zip + + - name: Unpack the SDK + run: | + unzip latest_lib3mf_sdk.zip -d lib3mf_sdk + + - name: Build CppDynamic + run: | + sh lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: List files + run: | + ls -al + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ && cp -r lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log + + - name: Print results (Checks the total python script execution time) + run: | + LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') + LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" + + + integration-tests-last-two-releases: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Get latest lib3mf SDK release info from GitHub API + id: get_latest_release + run: | + LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep "browser_download_url.*zip" | cut -d '"' -f 4) + echo "LATEST_LIB3MF_URL=${LATEST_LIB3MF_URL}" >> $GITHUB_ENV + + - name: Get second latest lib3mf SDK release info from GitHub API + id: get_second_latest_release + run: | + SECOND_LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases | grep "browser_download_url.*zip" | cut -d '"' -f 4 | sed -n '2p') + echo "SECOND_LATEST_LIB3MF_URL=${SECOND_LATEST_LIB3MF_URL}" >> $GITHUB_ENV + + - name: Download latest lib3mf SDK zip + run: | + wget ${{ env.LATEST_LIB3MF_URL }} -O latest_lib3mf_sdk.zip + + - name: Download second latest lib3mf SDK zip + run: | + wget ${{ env.SECOND_LATEST_LIB3MF_URL }} -O second_latest_lib3mf_sdk.zip + + - name: Unpack the latest SDK + run: | + unzip latest_lib3mf_sdk.zip -d latest_lib3mf_sdk + + - name: Unpack the second latest SDK + run: | + unzip second_latest_lib3mf_sdk.zip -d second_latest_lib3mf_sdk + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ + + - name: Build and run CppDynamic with latest SDK + run: | + sh latest_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd latest_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + cp -r * ../../../../test_suites/ + + - name: Run integration tests with latest SDK + run: | + cd test_suites + /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log + + - name: Clean up latest SDK binaries + run: | + find test_suites -maxdepth 1 -type f ! -name 'integration_test.py' ! -name 'latest_sdk_test.log' ! -name 'second_latest_sdk_test.log' -exec rm -rf {} + + + - name: Build and run CppDynamic with second latest SDK + run: | + sh second_latest_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd second_latest_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + echo "First debug" + ls -al ../../../../ + echo "This will fail" + cp -r * ../../../../test_suites/ + + - name: Run integration tests with second latest SDK + run: | + cd test_suites + /usr/bin/time -v python integration_test.py 2>&1 | tee second_latest_sdk_test.log + + - name: Compare results (Checks the total python script execution time) + run: | + LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') + SECOND_LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/second_latest_sdk_test.log | awk '{print $8}') + LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + SECOND_LATEST_TOTAL_SECONDS=$(echo $SECOND_LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" + echo "Second Latest SDK execution time in seconds: ${SECOND_LATEST_TOTAL_SECONDS}" + # Compare the total seconds + if (( $(echo "$LATEST_TOTAL_SECONDS < $SECOND_LATEST_TOTAL_SECONDS" | bc -l) )); then + echo "New release is better" + else + echo "New release is worse" + fi + + integration-tests-latest-commit: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Download lib3mf_sdk artifact + uses: actions/download-artifact@v4 + with: + name: lib3mf_sdk.zip + path: lib3mf_sdk.zip + + - name: Unpack the SDK + run: | + unzip lib3mf_sdk.zip/lib3mf_sdk.zip -d lib3mf_sdk && ls -al + + - name: Build CppDynamic + run: | + sh lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ && cp -r lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log + + - name: Print results (Checks the total python script execution time) + run: | + LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') + LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" + + integration-test-last-commit-and-last-release: + runs-on: ubuntu-20.04 + needs: [set-integration-tests-status] + if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + + - name: Download lib3mf_sdk artifact + uses: actions/download-artifact@v4 + with: + name: lib3mf_sdk.zip + path: lib3mf_sdk.zip + + - name: Unpack the SDK + run: | + unzip lib3mf_sdk.zip/lib3mf_sdk.zip -d latest_commit_lib3mf_sdk && ls -al + + - name: Build CppDynamic with latest commit SDK + run: | + sh latest_commit_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd latest_commit_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Download and unzip test suite + run: | + wget https://github.com/3MFConsortium/test_suites/releases/download/v2.0.0/3MF_Conformance_Test_Suites_v2.0.0.zip + unzip 3MF_Conformance_Test_Suites_v2.0.0.zip -d test_suites + + - name: Copy integration test script + run: | + cp CI/integration_test.py test_suites/ + + - name: Copy latest commit SDK to test suite + run: | + cp -r latest_commit_lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests with latest commit SDK + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_commit_sdk_test.log + + - name: Clean up latest SDK binaries + run: | + find test_suites -maxdepth 1 -type f ! -name 'integration_test.py' ! -name '*.log' -exec rm -rf {} + + + - name: Get latest lib3mf SDK release info from GitHub API + id: get_latest_release + run: | + LATEST_LIB3MF_URL=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep "browser_download_url.*zip" | cut -d '"' -f 4) + echo "LATEST_LIB3MF_URL=${LATEST_LIB3MF_URL}" >> $GITHUB_ENV + LATEST_RELEASE_NAME=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep '"tag_name"' | cut -d '"' -f 4) + echo "LATEST_RELEASE_NAME=${LATEST_RELEASE_NAME}" >> $GITHUB_ENV + + - name: Download latest lib3mf SDK release zip + run: | + wget ${{ env.LATEST_LIB3MF_URL }} -O latest_release_lib3mf_sdk.zip + + - name: Unpack the SDK from latest release + run: | + unzip latest_release_lib3mf_sdk.zip -d latest_release_lib3mf_sdk + + - name: Build CppDynamic with latest release SDK + run: | + sh latest_release_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh + cd latest_release_lib3mf_sdk/Examples/CppDynamic/build + cmake --build . + ./Example_ExtractInfo ../../Files/Helix.3mf + + - name: Copy latest release SDK to test suite + run: | + cp -r latest_release_lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ + + - name: Run integration tests with latest release SDK + run: | + cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_release_sdk_test.log + + - name: Compare results (Checks the total python script execution time) + id: compare_results + run: | + LATEST_COMMIT_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_commit_sdk_test.log | awk '{print $8}') + LATEST_RELEASE_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_release_sdk_test.log | awk '{print $8}') + LATEST_COMMIT_TOTAL_SECONDS=$(echo $LATEST_COMMIT_TIME | awk -F: '{ print ($1 * 60) + $2 }') + LATEST_RELEASE_TOTAL_SECONDS=$(echo $LATEST_RELEASE_TIME | awk -F: '{ print ($1 * 60) + $2 }') + echo "Latest commit SDK execution time in seconds: ${LATEST_COMMIT_TOTAL_SECONDS}" + echo "Latest release SDK execution time in seconds: ${LATEST_RELEASE_TOTAL_SECONDS}" + # Compare the total seconds + if (( $(echo "$LATEST_COMMIT_TOTAL_SECONDS < $LATEST_RELEASE_TOTAL_SECONDS" | bc -l) )); then + echo "Latest commit is better" + else + echo "Latest release is better" + fi + echo "Latest commit with SHA ${{ github.sha }} ran in ${LATEST_COMMIT_TOTAL_SECONDS} seconds" > results.txt + echo "Latest release with tag ${{ env.LATEST_RELEASE_NAME }} ran in ${LATEST_RELEASE_TOTAL_SECONDS} seconds" >> results.txt + + - name: Upload results artifact + uses: actions/upload-artifact@v4 + with: + name: integration-test-results + path: results.txt \ No newline at end of file diff --git a/.gitignore b/.gitignore index a41019361..87ee8d189 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ Include/Model/COM/NMR_COMVersion.h debug .DS_Store .vscode +.idea +cmake-build-* \ No newline at end of file diff --git a/CI/Dockerfile b/CI/Dockerfile index 846332f66..efedb0943 100644 --- a/CI/Dockerfile +++ b/CI/Dockerfile @@ -14,6 +14,7 @@ RUN \ tar \ gzip \ zip \ + rpm-build \ ${GCCTOOLSET} \ && microdnf clean all @@ -53,14 +54,28 @@ RUN cmake --build . RUN ctest -V . +# Add this line to generate a ZIP package with cpack +RUN cpack -G ZIP -C Release + +# Generate a debian package +RUN cpack -G DEB -C Release + +# Generate a RPM package +RUN cpack -G RPM -C Release + WORKDIR "/../../" RUN mkdir -p out RUN cp ./lib3mf-repo/build/lib3mf.so.2 ./out/ -RUN cd out && zip -r ../out.zip . +RUN cp ./lib3mf-repo/build/lib3mf-*-Linux.zip ./out/ +RUN cp ./lib3mf-repo/build/lib3mf-*-Linux.deb ./out/ + +RUN cp ./lib3mf-repo/build/lib3mf-*-Linux.rpm ./out/ + +RUN cd out && zip -r ../out.zip . diff --git a/CI/extract_version.py b/CI/extract_version.py new file mode 100644 index 000000000..4fc0b0d53 --- /dev/null +++ b/CI/extract_version.py @@ -0,0 +1,32 @@ +import os +import re + +def extract_version_from_cmake(): + cmake_file = 'CMakeLists.txt' + + if not os.path.exists(cmake_file): + raise FileNotFoundError(f"{cmake_file} not found in the current directory") + + with open(cmake_file, 'r') as file: + content = file.read() + + major = re.search(r'set\(LIB3MF_VERSION_MAJOR\s+([0-9]+)\)', content) + minor = re.search(r'set\(LIB3MF_VERSION_MINOR\s+([0-9]+)\)', content) + micro = re.search(r'set\(LIB3MF_VERSION_MICRO\s+([0-9]+)\)', content) + prerelease = re.search(r'set\(LIB3MF_VERSION_PRERELEASE\s+"([^"]*)"\)', content) + + if not major or not minor or not micro: + raise ValueError("Could not find version components in CMakeLists.txt") + + version = f"{major.group(1)}.{minor.group(1)}.{micro.group(1)}" + if prerelease and prerelease.group(1): + version += f"-{prerelease.group(1)}" + + return version + +if __name__ == "__main__": + try: + version = extract_version_from_cmake() + print(version) + except Exception as e: + print(f"Error: {str(e)}") \ No newline at end of file diff --git a/CI/integration_test.py b/CI/integration_test.py new file mode 100644 index 000000000..dbfb7bb3f --- /dev/null +++ b/CI/integration_test.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +""" +@original author: weismam + +lib3mf_integration: + tests whether a large number of 3MF files is parsed correctly by lib3MF / + the Example_ExtractInfo from the SDK + +""" + +import datetime, time +import subprocess +import os + + +def listFiles(root, extension): + lFiles = [] + for path, _, files in os.walk(root): + for name in files: + [_, fileextension] = os.path.splitext(name) + if extension == fileextension: + lFiles.append(os.path.join(path, name)) + return lFiles + + +# returns a list of files of the following pattern: $root/{*}/$inbetweenFolder/{*}/*.$extension +def listFilesIn(root, inbetweenFolder, extension): + lFiles = [] + for path, subdirs, _ in os.walk(root): + for subdir in subdirs: + if subdir == inbetweenFolder: + lFiles += listFiles(os.path.join(path, subdir), extension) + lFiles = list(set(lFiles)) + lFiles.sort() + return lFiles + + +def ExtractInfo(execCommand, fileName): + tStart = time.time() + proc = subprocess.Popen([execCommand, fileName], stdout=subprocess.PIPE) + pOut = "" + errLines = [] + for line in proc.stdout: + utf8line = line.decode("utf-8") + if "error" in utf8line: + errLines.append(utf8line) + if "warning" in utf8line: + errLines.append(utf8line) + pOut += utf8line + + proc.wait() + info = dict.fromkeys({'success', 'time', 'stdout'}) + info['time'] = time.time() - tStart + info['returncode'] = proc.returncode + info['success'] = len(errLines) == 0 + info['errLines'] = errLines + info['stdout'] = str(pOut) + return info + + +if __name__ == "__main__": + tStart = datetime.datetime.now() + + root = os.path.dirname(os.path.realpath(__file__)) + + execCommand = os.path.join(root, "Example_ExtractInfo") + + print("Execute once for testing") + os.system(execCommand) + print("Execution done") + + positives = [] + negatives = [] + + for suite in os.listdir(root): + suite_path = os.path.join(root, suite) + if os.path.isdir(suite_path) and suite.startswith("suite"): + positives += listFilesIn(suite_path, "positive_test_cases", ".3mf") + negatives += listFilesIn(suite_path, "negative_test_cases", ".3mf") + + nPos = len(positives) + nNeg = len(negatives) + nFiles = nPos + nNeg + + print(execCommand) + + brokenPositives = [] + iFile = 0 + for fileName in positives: + iFile += 1 + print("{:3.0f}%: {:s}".format(100 * (iFile / nFiles), fileName), flush=True) + info = ExtractInfo(execCommand, fileName) + if not info['returncode'] == 0: + print("Fatal Error: MUSTPASS file \"{:s}\" does not work with returncode {:d}:".format(fileName, + info['returncode'])) + brokenPositives.append(info) + if not info['success']: + print("Error: MUSTPASS file \"{:s}\" does not work:".format(fileName)) + print('Contains {:d} problem{:s}:'.format(len(info['errLines']), ['s', ''][len(info['errLines']) == 0])) + for errLine in info['errLines']: + print(errLine, end='') + print('=== Output === ') + print(info['stdout']) + print('=== /Output === ') + brokenPositives.append(info) + + runningNegatives = [] + for fileName in negatives: + iFile += 1 + print("{:3.0f}%: {:s}".format(100 * (iFile / nFiles), fileName), flush=True) + info = ExtractInfo(execCommand, fileName) + if not info['returncode'] >= 0: + print("Fatal Error: MUSTFAIL file \"{:s}\" does not work with returncode {:d}:".format(fileName, + info['returncode'])) + if info['success'] and info['returncode'] == 0: + print("Error: MUSTFAIL file \"{:s}\" works".format(fileName)) + runningNegatives.append(info) + + duration = datetime.datetime.now() - tStart + print("Tested a total of {:d} = ({:d} positive + {:d} negative) files in {:s}.".format( + nFiles, nPos, nNeg, str(duration).split('.')[0])) + + if nPos > 0: + print(" {:3d} / {:3d} MUSTPASS files passed ({:6.2f}%)".format(nPos - len(brokenPositives), nPos, + 100 * (1 - len(brokenPositives) / nPos))) + if len(negatives) > 0: + print(" {:3d} / {:3d} MUSTFAIL files failed ({:6.2f}%)".format(nNeg - len(runningNegatives), nNeg, + 100 * (1 - len(runningNegatives) / nNeg))) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6384b06e7..f7983c519 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,10 +46,10 @@ if (${MSVC}) # using Visual Studio C++ # this ensures that the min/max macros of minwindef.h are not used - add_definitions(-DNOMINMAX /W3) + add_definitions(-DNOMINMAX) + + #add_definitions(/W3) - add_definitions(/W3) - # add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") @@ -131,6 +131,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/I target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include) if (USE_INCLUDED_LIBZIP) + # Something goes here to check if submodules exist and initialize the submodules if it does not target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Libraries/libzip/Include) if(MSVC) target_compile_definitions(${PROJECT_NAME} PRIVATE _CRT_SECURE_NO_WARNINGS) @@ -226,6 +227,8 @@ endif(WIN32) configure_file(lib3mf.pc.in lib3mf.pc @ONLY) install(FILES ${CMAKE_BINARY_DIR}/lib3mf.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(FILES cmake/lib3mfConfig.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lib3mf) install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" @@ -249,3 +252,21 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${STARTUPPROJECT}) ENDIF() endif() + + +######################################################### +set(CPACK_PACKAGE_NAME "lib3mf") +set(CPACK_PACKAGE_VENDOR "3MF Consortium") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "lib3mf - An implementation of the 3D Manufacturing Format file standard") +set(CPACK_PACKAGE_VERSION "${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO}") +set(CPACK_PACKAGE_VERSION_MAJOR "${LIB3MF_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${LIB3MF_VERSION_MINOR}") +set(CPACK_PACKAGE_VERSION_PATCH "${LIB3MF_VERSION_MICRO}") +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") +set(CPACK_PACKAGE_CONTACT "lib3mf@3mf.io") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "3MF Consortium") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}") +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Source") + +######################################################### +include(CPack) diff --git a/SDK/CPackExamples/Cpp/CMakeLists.txt b/SDK/CPackExamples/Cpp/CMakeLists.txt new file mode 100644 index 000000000..e75ad0874 --- /dev/null +++ b/SDK/CPackExamples/Cpp/CMakeLists.txt @@ -0,0 +1,70 @@ +cmake_minimum_required (VERSION 3.5) +project(Examples) +set(CMAKE_CXX_STANDARD 11) + +# Determine the platform and set lib3mf_DIR accordingly +if(WIN32) + # Path for Windows + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS Cpp) +elseif(APPLE) + # Path for macOS (Darwin) + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS Cpp) +else() + # Path for Linux (Here we check twice to test for Debian / RPM packages properly) + find_package(lib3mf QUIET COMPONENTS Cpp) + # Check if the package was not found + if(NOT lib3mf_FOUND) + # lib3mf not found, so set lib3mf_DIR to the fallback directory + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + # Find package (lib3mf) + find_package(lib3mf REQUIRED COMPONENTS Cpp) + endif() +endif() + +add_definitions(-DTEXTURESPATH="${CMAKE_CURRENT_SOURCE_DIR}/../Files/Textures/") + +add_executable(Example_ColorCube Source/ColorCube.cpp) +target_link_libraries(Example_ColorCube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_ColorCube) + +add_executable(Example_Components Source/Components.cpp) +target_link_libraries(Example_Components lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Components) + +add_executable(Example_Converter Source/Converter.cpp) +target_link_libraries(Example_Converter lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Converter) + +add_executable(Example_Cube Source/Cube.cpp) +target_link_libraries(Example_Cube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Cube) + +add_executable(Example_SecureCube Source/SecureCube.cpp) +target_link_libraries(Example_SecureCube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_SecureCube) + +add_executable(Example_ExtractInfo Source/ExtractInfo.cpp) +target_link_libraries(Example_ExtractInfo lib3mf::lib3mf) +copy_lib3mf_libraries(Example_ExtractInfo) + +add_executable(Example_TextureCube Source/TextureCube.cpp) +target_link_libraries(Example_TextureCube lib3mf::lib3mf) +copy_lib3mf_libraries(Example_TextureCube) + +add_executable(Example_Slice Source/Slice.cpp) +target_link_libraries(Example_Slice lib3mf::lib3mf) +copy_lib3mf_libraries(Example_Slice) + +add_executable(Example_BeamLattice Source/BeamLattice.cpp) +target_link_libraries(Example_BeamLattice lib3mf::lib3mf) +copy_lib3mf_libraries(Example_BeamLattice) + +if (${MSVC}) + IF(${CMAKE_VERSION} VERSION_LESS 3.6.3) + MESSAGE ("Note: You need to manually select a StartUp-project in Visual Studio.") + ELSE() + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Example_Cube) + ENDIF() +endif() diff --git a/SDK/CPackExamples/Cpp/GenerateMake.sh b/SDK/CPackExamples/Cpp/GenerateMake.sh new file mode 100644 index 000000000..16fe9cf2b --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateMake.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +basepath="$(cd "$(dirname "$0")" && pwd)" +builddir="$basepath/build" +mkdir -p $builddir +cd $builddir +cmake .. -G "Unix Makefiles" "$@" \ No newline at end of file diff --git a/SDK/CPackExamples/Cpp/GenerateVS2015.bat b/SDK/CPackExamples/Cpp/GenerateVS2015.bat new file mode 100644 index 000000000..e6933cdeb --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateVS2015.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 14 2015 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/Cpp/GenerateVS2017.bat b/SDK/CPackExamples/Cpp/GenerateVS2017.bat new file mode 100644 index 000000000..4014d2f99 --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateVS2017.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 15 2017 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/Cpp/GenerateVS2019.bat b/SDK/CPackExamples/Cpp/GenerateVS2019.bat new file mode 100644 index 000000000..efa4f308f --- /dev/null +++ b/SDK/CPackExamples/Cpp/GenerateVS2019.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 16 2019" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/Cpp/Source/BeamLattice.cpp b/SDK/CPackExamples/Cpp/Source/BeamLattice.cpp new file mode 100644 index 000000000..c1509cc88 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/BeamLattice.cpp @@ -0,0 +1,159 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +BeamLattice.cpp : 3MF beamlattice creation example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and beams +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFBeam fnCreateBeam(int v0, int v1, double r0, double r1, eLib3MFBeamLatticeCapMode c0, eLib3MFBeamLatticeCapMode c1) +{ + sLib3MFBeam result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Radii[0] = r0; + result.m_Radii[1] = r1; + result.m_CapModes[0] = c0; + result.m_CapModes[1] = c1; + return result; +} + + +void BeamLatticeExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Beamlattice example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Beamlattice"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(0); + std::vector beams(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create beams + double r0 = 1.0; + double r1 = 1.5; + double r2 = 2.0; + double r3 = 2.5; + beams[0] = fnCreateBeam(2, 1, r0, r0, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Butt); + beams[1] = fnCreateBeam(0, 3, r0, r1, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::Butt); + beams[2] = fnCreateBeam(4, 5, r0, r2, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::Butt); + beams[3] = fnCreateBeam(6, 7, r0, r3, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::Butt); + beams[4] = fnCreateBeam(0, 1, r1, r0, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::Butt); + beams[5] = fnCreateBeam(5, 4, r1, r1, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::HemiSphere); + beams[6] = fnCreateBeam(2, 3, r1, r2, eBeamLatticeCapMode::Sphere, eBeamLatticeCapMode::Sphere); + beams[7] = fnCreateBeam(7, 6, r1, r3, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Butt); + beams[8] = fnCreateBeam(1, 2, r2, r2, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Butt); + beams[9] = fnCreateBeam(6, 5, r2, r3, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::Butt); + beams[10] = fnCreateBeam(3, 0, r3, r0, eBeamLatticeCapMode::Butt, eBeamLatticeCapMode::Sphere); + beams[11] = fnCreateBeam(4, 7, r3, r1, eBeamLatticeCapMode::HemiSphere, eBeamLatticeCapMode::HemiSphere); + meshObject->SetGeometry(vertices, triangles); + + // Set beamlattice geometry and metadata + PBeamLattice beamLattice = meshObject->BeamLattice(); + beamLattice->SetBeams(beams); + beamLattice->SetMinLength(0.005); + + PBeamSet set = beamLattice->AddBeamSet(); + set->SetName("Special Beams"); + set->SetIdentifier("bs1"); + std::vector references = { 2,0,5 }; + set->SetReferences(references); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + // Write file + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("beamlattice.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + BeamLatticeExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/ColorCube.cpp b/SDK/CPackExamples/Cpp/Source/ColorCube.cpp new file mode 100644 index 000000000..f1c46baca --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/ColorCube.cpp @@ -0,0 +1,183 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +ColorCube.cpp : 3MF Color Cube creation example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +sLib3MFTriangleProperties fnCreateTriangleColor(PColorGroup colorGroup, Lib3MF_uint32 colorID1, Lib3MF_uint32 colorID2, Lib3MF_uint32 colorID3) +{ + sLib3MFTriangleProperties sTriangleProperty; + sTriangleProperty.m_ResourceID = colorGroup->GetResourceID(); + sTriangleProperty.m_PropertyIDs[0] = colorID1; + sTriangleProperty.m_PropertyIDs[1] = colorID2; + sTriangleProperty.m_PropertyIDs[2] = colorID3; + return sTriangleProperty; +} + + +void CubeExample() { + PWrapper wrapper = wrapper->loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Color Cube example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Colored Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // define colors + PColorGroup colorGroup = model->AddColorGroup(); + Lib3MF_uint32 idRed = colorGroup->AddColor(wrapper->RGBAToColor(255, 0, 0, 255)); + Lib3MF_uint32 idGreen = colorGroup->AddColor(wrapper->RGBAToColor(0, 255, 0, 255)); + Lib3MF_uint32 idBlue = colorGroup->AddColor(wrapper->RGBAToColor(0, 0, 255, 255)); + Lib3MF_uint32 idOrange = colorGroup->AddColor(wrapper->RGBAToColor(255, 128, 0, 255)); + Lib3MF_uint32 idYellow = colorGroup->AddColor(wrapper->RGBAToColor(255, 255, 0, 255)); + + sLib3MFTriangleProperties sTriangleColorRed = fnCreateTriangleColor(colorGroup, idRed, idRed, idRed); + sLib3MFTriangleProperties sTriangleColorGreen = fnCreateTriangleColor(colorGroup, idGreen, idGreen, idGreen); + sLib3MFTriangleProperties sTriangleColorBlue = fnCreateTriangleColor(colorGroup, idBlue, idBlue, idBlue); + + sLib3MFTriangleProperties sTriangleColor1 = fnCreateTriangleColor(colorGroup, idOrange, idRed, idYellow); + sLib3MFTriangleProperties sTriangleColor2 = fnCreateTriangleColor(colorGroup, idYellow, idGreen, idOrange); + + // One-colored Triangles + meshObject->SetTriangleProperties(0, sTriangleColorRed); + meshObject->SetTriangleProperties(1, sTriangleColorRed); + meshObject->SetTriangleProperties(2, sTriangleColorGreen); + meshObject->SetTriangleProperties(3, sTriangleColorGreen); + meshObject->SetTriangleProperties(4, sTriangleColorBlue); + meshObject->SetTriangleProperties(5, sTriangleColorBlue); + // Gradient-colored Triangles + meshObject->SetTriangleProperties(6, sTriangleColor1); + meshObject->SetTriangleProperties(7, sTriangleColor2); + meshObject->SetTriangleProperties(8, sTriangleColor1); + meshObject->SetTriangleProperties(9, sTriangleColor2); + meshObject->SetTriangleProperties(10, sTriangleColor1); + meshObject->SetTriangleProperties(11, sTriangleColor2); + + // Object Level Property + meshObject->SetObjectLevelProperty(sTriangleColorRed.m_ResourceID, sTriangleColorRed.m_PropertyIDs[0]); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("colorcube.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + CubeExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/Components.cpp b/SDK/CPackExamples/Cpp/Source/Components.cpp new file mode 100644 index 000000000..f91499024 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Components.cpp @@ -0,0 +1,183 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Components.cpp : 3MF Components example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +sLib3MFTransform createTranslationMatrix(float x, float y, float z) +{ + sLib3MFTransform mMatrix; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + mMatrix.m_Fields[i][j] = (i == j) ? 1.0f : 0.0f; + } + } + + mMatrix.m_Fields[3][0] = x; + mMatrix.m_Fields[3][1] = y; + mMatrix.m_Fields[3][2] = z; + + return mMatrix; +} + + +void ComponentsExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Components example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 10.0f; + float fSizeY = 20.0f; + float fSizeZ = 30.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Create Component Object + PComponentsObject componentsObject = model->AddComponentsObject(); + + // Add first component + componentsObject->AddComponent(meshObject.get(), createTranslationMatrix(0.0f, 0.0f, 0.0f)); + + // Add second component + componentsObject->AddComponent(meshObject.get(), createTranslationMatrix(40.0f, 60.0f, 80.0f)); + + // Add third component + componentsObject->AddComponent(meshObject.get(), createTranslationMatrix(120.0f, 30.0f, 70.0f)); + + + // Add componentsobject as build item + model->AddBuildItem(componentsObject.get(), createTranslationMatrix(0.0f, 0.0f, 0.0f)); + + // Add translated componentsobject as build item + model->AddBuildItem(componentsObject.get(), createTranslationMatrix(200.0f, 40.0f, 10.0f)); + + // Add translated meshobject as build item + model->AddBuildItem(meshObject.get(), createTranslationMatrix(-40.0f, 0.0f, 20.0f)); + + // Output scene as STL and 3MF + PWriter _3mfWriter = model->QueryWriter("3mf"); + std::cout << "writing components.3mf..." << std::endl; + _3mfWriter->WriteToFile("components.3mf"); + + PWriter stlWriter = model->QueryWriter("stl"); + std::cout << "writing components.stl..." << std::endl; + stlWriter->WriteToFile("components.stl"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + ComponentsExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} + diff --git a/SDK/CPackExamples/Cpp/Source/Converter.cpp b/SDK/CPackExamples/Cpp/Source/Converter.cpp new file mode 100644 index 000000000..2fefdbc56 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Converter.cpp @@ -0,0 +1,154 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Converter.cpp : Can convert 3MFs to STL and back + +--*/ + +#include +#include +#include + +#ifndef __GNUC__ +#include +#endif + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +std::string FindExtension(std::string filename) { + // this emulates Windows' PathFindExtension + std::string::size_type idx; + idx = filename.rfind('.'); + + if (idx != std::string::npos) + { + return filename.substr(idx); + } + else + { + return ""; + } +} + + +int convert(std::string sFilename) { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Model Converter" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + // Extract Extension of filename + std::string sReaderName; + std::string sWriterName; + std::string sNewExtension; + std::string sExtension = FindExtension(sFilename); + std::transform(sExtension.begin(), sExtension.end(), sExtension.begin(), ::tolower); + + // Which Reader and Writer classes do we need? + if (sExtension == ".stl") { + sReaderName = "stl"; + sWriterName = "3mf"; + sNewExtension = ".3mf"; + } + if (sExtension == ".3mf") { + sReaderName = "3mf"; + sWriterName = "stl"; + sNewExtension = ".stl"; + } + if (sReaderName.length() == 0) { + std::cout << "unknown input file extension:" << sExtension << std::endl; + return -1; + } + + // Create new filename + std::string sOutputFilename = sFilename; + sOutputFilename.erase(sOutputFilename.length() - sExtension.length()); + sOutputFilename += sNewExtension; + + PModel model = wrapper->CreateModel(); + PReader reader = model->QueryReader(sReaderName); + + // Import Model from File + std::cout << "reading " << sFilename << "..." << std::endl; +#ifndef __GNUC__ + ULONGLONG nStartTicks = GetTickCount64(); +#endif + reader->ReadFromFile(sFilename); +#ifndef __GNUC__ + std::cout << "elapsed time: " << (GetTickCount64() - nStartTicks) << "ms" << std::endl; +#endif + + PWriter writer = model->QueryWriter(sWriterName); + std::cout << "writing " << sOutputFilename << "..." << std::endl; +#ifndef __GNUC__ + nStartTicks = GetTickCount64(); +#endif + writer->WriteToFile(sOutputFilename); +#ifndef __GNUC__ + std::cout << "elapsed time: " << (GetTickCount64() - nStartTicks) << "ms" << std::endl; +#endif + std::cout << "done" << std::endl; + return 0; +} + +int main(int argc, char** argv) { + // Parse Arguments + if (argc != 2) { + std::cout << "Usage: " << std::endl; + std::cout << "Convert 3MF to STL: Converter.exe model.3mf" << std::endl; + std::cout << "Convert STL to 3MF: Converter.exe model.stl" << std::endl; + return 0; + } + + try { + return convert(argv[1]); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/Cube.cpp b/SDK/CPackExamples/Cpp/Source/Cube.cpp new file mode 100644 index 000000000..18e99cb51 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Cube.cpp @@ -0,0 +1,140 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Cube.cpp : 3MF Cube creation example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + + +void CubeExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Cube example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("cube.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + CubeExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp b/SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp new file mode 100644 index 000000000..661cd30f2 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/ExtractInfo.cpp @@ -0,0 +1,269 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +ExtractInfo.cpp : 3MF Read Example + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +void ShowThumbnailInformation(PModel model) +{ + /* + // TODO: this is not yet implemented in Lib3MF + */ +} + + +void ShowMetaDataInformation(PMetaDataGroup metaDataGroup) +{ + Lib3MF_uint32 nMetaDataCount = metaDataGroup->GetMetaDataCount(); + + for (Lib3MF_uint32 iMeta = 0; iMeta < nMetaDataCount; iMeta++) { + + PMetaData metaData = metaDataGroup->GetMetaData(iMeta); + std::string sMetaDataValue = metaData->GetValue(); + std::string sMetaDataName = metaData->GetName(); + std::cout << "Metadatum: " << iMeta << ":" << std::endl; + std::cout << "Name = \"" << sMetaDataName << "\"" << std::endl; + std::cout << "Value = \"" << sMetaDataValue << "\"" << std::endl; + } +} + +void ShowSliceStack(PSliceStack sliceStack, std::string indent) +{ + std::cout << indent << "SliceStackID: " << sliceStack->GetResourceID() << std::endl; + if (sliceStack->GetSliceCount() > 0) { + std::cout << indent << " Slice count: " << sliceStack->GetSliceCount() << std::endl; + } + if (sliceStack->GetSliceRefCount() > 0) { + std::cout << indent << " Slice ref count: " << sliceStack->GetSliceRefCount() << std::endl; + for (Lib3MF_uint64 iSliceRef = 0; iSliceRef < sliceStack->GetSliceRefCount(); iSliceRef++) { + std::cout << indent << " Slice ref : " << sliceStack->GetSliceStackReference(iSliceRef)->GetResourceID() << std::endl; + } + } +} + +void ShowObjectProperties(PObject object) +{ + std::cout << " Name: \"" << object->GetName() << "\"" << std::endl; + std::cout << " PartNumber: \"" << object->GetPartNumber() << "\"" << std::endl; + + switch (object->GetType()) { + case eObjectType::Model: + std::cout << " Object type: model" << std::endl; + break; + case eObjectType::Support: + std::cout << " Object type: support" << std::endl; + break; + case eObjectType::SolidSupport: + std::cout << " Object type: solidsupport" << std::endl; + break; + case eObjectType::Other: + std::cout << " Object type: other" << std::endl; + break; + default: + std::cout << " Object type: invalid" << std::endl; + break; + } + + if (object->HasSlices(false)) { + PSliceStack sliceStack = object->GetSliceStack(); + ShowSliceStack(sliceStack, " "); + } + + if (object->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(object->GetMetaDataGroup()); + } +} + +void ShowMeshObjectInformation(PMeshObject meshObject) +{ + std::cout << "mesh object #" << meshObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(meshObject); + + Lib3MF_uint64 nVertexCount = meshObject->GetVertexCount(); + Lib3MF_uint64 nTriangleCount = meshObject->GetTriangleCount(); + PBeamLattice beamLattice = meshObject->BeamLattice(); + + // Output data + std::cout << " Vertex count: " << nVertexCount << std::endl; + std::cout << " Triangle count: " << nTriangleCount << std::endl; + + Lib3MF_uint64 nBeamCount = beamLattice->GetBeamCount(); + if (nBeamCount > 0) { + std::cout << " Beam count: " << nBeamCount << std::endl; + Lib3MF_uint32 nRepresentationMesh; + if (beamLattice->GetRepresentation(nRepresentationMesh)) + std::cout << " |_Representation Mesh ID: " << nRepresentationMesh << std::endl; + eLib3MFBeamLatticeClipMode eClipMode; + Lib3MF_uint32 nClippingMesh; + beamLattice->GetClipping(eClipMode, nClippingMesh); + if (eClipMode != eBeamLatticeClipMode::NoClipMode) + std::cout << " |_Clipping Mesh ID: " << nClippingMesh << "(mode=" << (int)eClipMode << ")" << std::endl; + if (beamLattice->GetBeamSetCount() > 0) { + std::cout << " |_BeamSet count: " << beamLattice->GetBeamSetCount() << std::endl; + } + } + +} + +void ShowTransform(sLib3MFTransform transform, std::string indent) { + std::cout << indent << "Transformation: [ " << transform.m_Fields[0][0] << " " << transform.m_Fields[1][0] << " " << transform.m_Fields[2][0] << " " << transform.m_Fields[3][0] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][1] << " " << transform.m_Fields[1][1] << " " << transform.m_Fields[2][1] << " " << transform.m_Fields[3][1] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][2] << " " << transform.m_Fields[1][2] << " " << transform.m_Fields[2][2] << " " << transform.m_Fields[3][2] << " ]" << std::endl; +} + +void ShowComponentsObjectInformation(PComponentsObject componentsObject) +{ + std::cout << "components object #" << componentsObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(componentsObject); + std::cout << " Component count: " << componentsObject->GetComponentCount() << std::endl; + for (Lib3MF_uint32 nIndex = 0; nIndex < componentsObject->GetComponentCount(); nIndex++) { + PComponent component = componentsObject->GetComponent(nIndex); + + std::cout << " Component " << nIndex << ": Object ID: " << component->GetObjectResourceID() << std::endl; + if (component->HasTransform()) { + ShowTransform(component->GetTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + } +} + + +void ExtractInfoExample(std::string sFileName) { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Read example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + // Import Model from 3MF File + { + PReader reader = model->QueryReader("3mf"); + // And deactivate the strict mode (default is "false", anyway. This just demonstrates where/how to use it). + reader->SetStrictModeActive(false); + reader->ReadFromFile(sFileName); + + for (Lib3MF_uint32 iWarning = 0; iWarning < reader->GetWarningCount(); iWarning++) { + Lib3MF_uint32 nErrorCode; + std::string sWarningMessage = reader->GetWarning(iWarning, nErrorCode); + std::cout << "Encountered warning #" << nErrorCode << " : " << sWarningMessage << std::endl; + } + } + ShowThumbnailInformation(model); + + ShowMetaDataInformation(model->GetMetaDataGroup()); + + PSliceStackIterator sliceStacks = model->GetSliceStacks(); + while (sliceStacks->MoveNext()) { + PSliceStack sliceStack = sliceStacks->GetCurrentSliceStack(); + ShowSliceStack(sliceStack, ""); + } + + PObjectIterator objectIterator = model->GetObjects(); + while (objectIterator->MoveNext()) { + PObject object = objectIterator->GetCurrentObject(); + if (object->IsMeshObject()) { + ShowMeshObjectInformation(model->GetMeshObjectByID(object->GetResourceID())); + } + else if (object->IsComponentsObject()) { + ShowComponentsObjectInformation(model->GetComponentsObjectByID(object->GetResourceID())); + } + else { + std::cout << "unknown object #" << object->GetResourceID() << ": " << std::endl; + } + } + + + PBuildItemIterator buildItemIterator = model->GetBuildItems(); + while (buildItemIterator->MoveNext()) { + PBuildItem buildItem = buildItemIterator->GetCurrent(); + + std::cout << "Build item (Object #" << buildItem->GetObjectResourceID() << "): " << std::endl; + + if (buildItem->HasObjectTransform()) { + ShowTransform(buildItem->GetObjectTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + std::cout << " Part number: \"" << buildItem->GetPartNumber() << "\"" << std::endl; + if (buildItem->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(buildItem->GetMetaDataGroup()); + } + } + + std::cout << "done" << std::endl; +} + + +int main(int argc, char** argv) { + // Parse Arguments + if (argc != 2) { + std::cout << "Usage: " << std::endl; + std::cout << "ExtractInfo.exe model.3mf" << std::endl; + return 0; + } + + try { + ExtractInfoExample(argv[1]); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/SecureCube.cpp b/SDK/CPackExamples/Cpp/Source/SecureCube.cpp new file mode 100644 index 000000000..de966b61f --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/SecureCube.cpp @@ -0,0 +1,487 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +SecureCube.cpp : 3MF encrypted Cube creation and read example. This is a sample +skeleton code provided to guide you to the process of reading and writing a 3MF +file using the Secure Content spec. Encryption and decryption processes are abstracted +so to avoid binding this sample to any particular implementation. If you would like +to check a working version of the process, there's a unit tests available on the 3MF code +base that implements the entire workflow using LibreSSL: EncryptionMethods.cpp +Tip: you could also copy buffers around - file won't be valid but you will be able +to run the entire process. +--*/ + +#include +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +namespace SecureContentCallbacks { + // Sample random number generation callback. Do not use this beyond the scope of this example as it is not really a random number generation function. + static void NotRandomBytesAtAll(Lib3MF_uint64 byteData, Lib3MF_uint64 size, Lib3MF_pvoid userData, Lib3MF_uint64 * bytesWritten) { + static Lib3MF_uint8 random = 0; + Lib3MF_uint8 * buffer = (Lib3MF_uint8 *)byteData; + *bytesWritten = size; + while (size > 0) + *(buffer + (--size)) = ++random; + } + + // Structure to hold encryption context for keys + struct KeyWrappingCbData { + CWrapper * wrapper; + }; + + + // Structure to hold encryption context for resources + struct ContentEncryptionCbData { + CWrapper * wrapper; + std::map context; + }; + + // Sample callback to wrap the key of an encryption process + static void WriteKeyWrappingCbSample( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + KeyWrappingCbData * cp = (KeyWrappingCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CAccessRight accessRight(cp->wrapper, access); + cp->wrapper->Acquire(&accessRight); + + // This is going to be called for each consumer you've registered to + PConsumer consumer = accessRight.GetConsumer(); + std::string consumerId = consumer->GetConsumerID(); + std::cout << "ConsumerID " << consumer->GetConsumerID() << std::endl; + // You can also check for keyid and keyvalue + + // A call could be made to first identify what the output buffer size should be. + // In that case, outSize will be 0 or outBuffer will be null, and the proper size must be placed in outNeeded. + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + return; + } + + // Query the data about the encryption process to be done + eWrappingAlgorithm algorithm = accessRight.GetWrappingAlgorithm(); + eMgfAlgorithm mask = accessRight.GetMgfAlgorithm(); + eDigestMethod diges = accessRight.GetDigestMethod(); + + // You should deal with the encryption process of the key. + // Use the encryption process to wrap inBuffer (plain) into outBuffer (cipher) using details above. + // Use KeyWrappingCbData to hold any information you'll be needing at this point. + throw std::runtime_error("TODO: Add your encryption wrapping process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + + // Finally, this function should use status to return the number of bytes needed, + // encrypted - or zero to indicate a failure. + *status = outSize; + } + + // Sample callback to encrypt contents of a resource + static void WriteContentEncryptionCbSample( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + ContentEncryptionCbData * cb = (ContentEncryptionCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CContentEncryptionParams cd(cb->wrapper, params); + cb->wrapper->Acquire(&cd); + + // A descriptor uniquely identifies the encryption process for a resource + Lib3MF_uint64 descriptor = cd.GetDescriptor(); + + // You can map the descriptor in use as you'll probably keep several + // contexts initialized at same time + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + // Use an existing context + localDescriptor->second++; + else { + // Initialize a new context + + // Retrieve the encryption key, if there is one + std::vector key; + cd.GetKey(key); + + // You can also use keyuuid to look up a key externally + std::string keyUUID = cd.GetKeyUUID(); + + // Retrieve the additional authenticaton data, if it has been used to encrypt + std::vector aad; + cd.GetAdditionalAuthenticationData(aad); + + // TODO: Initialize the encryption context + cb->context[cd.GetDescriptor()] = 0; + } + + // Attention to the order in which params are tested, it matters + if (0 == inSize || nullptr == inBuffer) { + // When input buffer is null or input size is 0, this is a request + // to finalize this encryption process and generating the authentication tag + // TODO: generate proper tag + std::vector tag = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + cd.SetAuthenticationTag(tag); + //add tag verification status here + *status = tag.size(); + } else if (0 == outSize || nullptr == outBuffer) { + // If outSize is zero or outBuffer is null (but inSize and inBuffer are not), + // this is a call to figure out the output buffer size. + // Put the respective value in outNeededSize. + *outNeededSize = inSize; + *status = inSize; + } else { + // Else, perform the encryption process + throw std::runtime_error("TODO: Add your encryption process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + //This function should use status to return the number of bytes needed, encrypted + // or verified - or zero to indicate a failure. + } + + static void ReadKeyWrappingCbSample( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + // A call could be made to first identify what the output buffer size should be. + // In that case, outSize will be 0 or outBuffer will be null, and the proper size must be placed in outNeeded. + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + return; + } + + KeyWrappingCbData * cp = (KeyWrappingCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CAccessRight accessRight(cp->wrapper, access); + cp->wrapper->Acquire(&accessRight); + + // This is going to be called for each consumer you've registered to + PConsumer consumer = accessRight.GetConsumer(); + std::string consumerId = consumer->GetConsumerID(); + std::cout << "ConsumerID " << consumer->GetConsumerID() << std::endl; + // You can also check for keyid and keyvalue + + // Query the data about the encryption process to be done + eWrappingAlgorithm algorithm = accessRight.GetWrappingAlgorithm(); + eMgfAlgorithm mask = accessRight.GetMgfAlgorithm(); + eDigestMethod diges = accessRight.GetDigestMethod(); + + // You should deal with the encryption process of the key. + // Use the encryption process to wrap inBuffer (cipher) into outBuffer (plain) using details above. + // Use KeyWrappingCbData to hold any information you'll be needing at this point. + throw std::runtime_error("TODO: Add your decryption wrapping process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + + // Finally, this function should use status to return the number of bytes needed, + // decrypted - or zero to indicate a failure. + *status = outSize; + } + + static void ReadContentEncryptionCbSample( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + ContentEncryptionCbData * cb = (ContentEncryptionCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CContentEncryptionParams cd(cb->wrapper, params); + cb->wrapper->Acquire(&cd); + + // A descriptor uniquely identifies the encryption process for a resource + Lib3MF_uint64 descriptor = cd.GetDescriptor(); + + // You can map the descriptor in use as you'll probably keep several + // contexts initialized at same time + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + // Use an existing context + localDescriptor->second++; + else { + // Initialize a new context + + // Retrieve the encryption key, if there is one + std::vector key; + cd.GetKey(key); + + // You can also use keyuuid to look up a key externally + std::string keyUUID = cd.GetKeyUUID(); + + // Retrieve the additional authenticaton data, if it has been used to encrypt + std::vector aad; + cd.GetAdditionalAuthenticationData(aad); + + // TODO: Initialize the encryption context + cb->context[cd.GetDescriptor()] = 0; + } + + // Attention to the order in which params are tested, it matters + if (0 == inSize || nullptr == inBuffer) { + // When input buffer is null or input size is 0, this is a request + // to finalize this encryption process and verify the authentication tag + std::vector tag; + cd.GetAuthenticationTag(tag); + // TODO: verify tag + *status = tag.size(); + } else if (0 == outSize || nullptr == outBuffer) { + // If outSize is zero or outBuffer is null (but inSize and inBuffer are not), + // this is a call to figure out the output buffer size. + // Put the respective value in outNeededSize. + *outNeededSize = inSize; + *status = inSize; + return; + } else { + // Else, perform the descryption process + throw std::runtime_error("TODO: Add your encryption process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + //This function should use status to return the number of bytes needed, decrypted + // or verified - or zero to indicate a failure. + } +}; + +void printVersion(CWrapper & wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper.GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper.GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper.GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) { + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) { + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +void WriteSecureContentExample(CWrapper & wrapper) { + + PModel model = wrapper.CreateModel(); + + // After initializing the model, set the random number generation callback + // A default one will be used if you don't, current implementation uses std::mt19937 + model->SetRandomNumberCallback(SecureContentCallbacks::NotRandomBytesAtAll, nullptr); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper.GetIdentityTransform()); + + // Move this mesh out of the root model file into another model + PPackagePart nonRootModel = model->FindOrCreatePackagePart("/3D/securecube.model"); + meshObject->SetPackagePart(nonRootModel.get()); + + // Locate the keystore and setup the resource as a secure content + PKeyStore keystore = model->GetKeyStore(); + + // Add you (client) as consumer of the resource. You'll need to do this + // to be able to have a chance to wrap the content key + // You can set optional public key and an optional key id + PConsumer consumer = keystore->AddConsumer("MyConsumerID", std::string(), std::string()); + + // Add a container for your secured resources. Resources within the same container will have a shared key. + PResourceDataGroup dataGroup = keystore->AddResourceDataGroup(); + + // Add access rights for your consumer into the datagroup + PAccessRight accessRight = dataGroup->AddAccessRight(consumer.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA1, eDigestMethod::SHA1); + + // Specify additional authentication data that you could use to further validate your encryption process + std::vector aad = { '3','M','F','C','o','n','s','o','r','t','i','u','m',' ','S','a','m','p','l','e' }; + + // This will effectively add your nonRootModel as a secure content + PResourceData resourceData = keystore->AddResourceData(dataGroup.get(), nonRootModel.get(), eEncryptionAlgorithm::AES256_GCM, eCompression::Deflate, aad); + + // Query the writer and setup the encryption before saving results + PWriter writer = model->QueryWriter("3mf"); + + // Setup Key Wrapping process + SecureContentCallbacks::KeyWrappingCbData keyData; + keyData.wrapper = &wrapper; + writer->AddKeyWrappingCallback(consumer->GetConsumerID(), SecureContentCallbacks::WriteKeyWrappingCbSample, &keyData); + + // Content Encryption process + SecureContentCallbacks::ContentEncryptionCbData contentData; + contentData.wrapper = &wrapper; + writer->SetContentEncryptionCallback(SecureContentCallbacks::WriteContentEncryptionCbSample, &contentData); + + // You'll need to complete the callback code for this call to work properly. + writer->WriteToFile("secureCube.3mf"); + + std::cout << "Writing Done." << std::endl; +} + +void ReadSecureContentExample(CWrapper & wrapper) { + PModel model = wrapper.CreateModel(); + + // After initializing the model, set the random number generation callback + // A default one will be used if you don't, current implementation uses std::mt19937 + model->SetRandomNumberCallback(SecureContentCallbacks::NotRandomBytesAtAll, nullptr); + + // Query the reader and setup the encryption before saving results + PReader reader = model->QueryReader("3mf"); + + // Setup Key Wrapping process + SecureContentCallbacks::KeyWrappingCbData keyData; + keyData.wrapper = &wrapper; + reader->AddKeyWrappingCallback("MyConsumerID", SecureContentCallbacks::ReadKeyWrappingCbSample, &keyData); + + // Content Encryption process + SecureContentCallbacks::ContentEncryptionCbData contentData; + contentData.wrapper = &wrapper; + reader->SetContentEncryptionCallback(SecureContentCallbacks::ReadContentEncryptionCbSample, &contentData); + + // You'll need to complete the callback code for this call to work properly. + reader->ReadFromFile("secureCube.3mf"); + + PKeyStore keystore = model->GetKeyStore(); + + // If you know the part you're interested in, look for its resource data + PPackagePart partPath = model->FindOrCreatePackagePart("/3D/securecube.model"); + PResourceData resourceData = keystore->FindResourceData(partPath.get()); + + // You can retrieve additional authenticated data using in the encryption + // to further verify the consistency of the process. At this time, it is + // already verified. + std::vector aad; + resourceData->GetAdditionalAuthenticationData(aad); + std::cout << "Additional Authenticated Data: "; + for (auto it = aad.begin(); it != aad.end(); ++it) { + std::cout << (char)*it; + } + std::cout << std::endl; + + std::cout << "Reading Done." << std::endl; + +} + +int main() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF SecureContent example" << std::endl; + printVersion(*wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + try { + WriteSecureContentExample(*wrapper); + ReadSecureContentExample(*wrapper); + } catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/Slice.cpp b/SDK/CPackExamples/Cpp/Source/Slice.cpp new file mode 100644 index 000000000..5b8a3828e --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/Slice.cpp @@ -0,0 +1,191 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +Slice.cpp : 3MF slice extension example + +--*/ + +#include +#include +#include +double const_pi() { return std::atan(1) * 4; } +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and beams +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + + +void SliceExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Slice example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Sliced Object [outbox]"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 100.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(-fSizeX, -fSizeY, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, -fSizeY, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(-fSizeX, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(-fSizeX, -fSizeY, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, -fSizeY, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(-fSizeX, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + // Set Geometry + meshObject->SetGeometry(vertices, triangles); + + + PSliceStack sliceStack = model->AddSliceStack(0.0); + + + + + + // Define an ellipse + Lib3MF_uint32 nSliceVertices = 20; + std::vector origSliceVertices(nSliceVertices); + for (Lib3MF_uint32 iSliceVertex = 0; iSliceVertex < nSliceVertices; iSliceVertex++) { + double angle = 2 * (const_pi()* iSliceVertex) / nSliceVertices; + origSliceVertices[iSliceVertex].m_Coordinates[0] = (Lib3MF_single)(fSizeX / 2 * std::cos(angle)); + origSliceVertices[iSliceVertex].m_Coordinates[1] = (Lib3MF_single)(fSizeY *std::sin(angle)); + } + + std::vector polygonIndices(nSliceVertices + 1); + for (Lib3MF_uint32 iPolygonIndex = 0; iPolygonIndex < polygonIndices.size(); iPolygonIndex++) { + polygonIndices[iPolygonIndex] = iPolygonIndex % nSliceVertices; + } + + Lib3MF_uint32 nSlices = 10; + + for (Lib3MF_uint32 iSlice = 0; iSlice < nSlices; iSlice++) { + PSlice slice = sliceStack->AddSlice((iSlice + 1.0)*fSizeZ / nSlices); + + // Rotate the ellpise as we move up z + double angle = 2 * (const_pi()*iSlice) / nSlices; + std::vector sliceVertices(nSliceVertices); + for (Lib3MF_uint32 iSliceVertex = 0; iSliceVertex < nSliceVertices; iSliceVertex++) { + double x = origSliceVertices[iSliceVertex].m_Coordinates[0]; + double y = origSliceVertices[iSliceVertex].m_Coordinates[1]; + sliceVertices[iSliceVertex].m_Coordinates[0] = (Lib3MF_single)(std::cos(angle)*x - std::sin(angle)*y); + sliceVertices[iSliceVertex].m_Coordinates[1] = (Lib3MF_single)(std::sin(angle)*x + std::cos(angle)*y); + } + + slice->SetVertices(sliceVertices); + slice->AddPolygon(polygonIndices); + } + + + // Assign this slice stack to mesh..., the exact geometry of the part + meshObject->AssignSliceStack(sliceStack.get()); + // which is not an exact representation of the sliced geometry + meshObject->SetSlicesMeshResolution(eSlicesMeshResolution::Lowres); + + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + // Write file + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("slice.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + SliceExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/CPackExamples/Cpp/Source/TextureCube.cpp b/SDK/CPackExamples/Cpp/Source/TextureCube.cpp new file mode 100644 index 000000000..a8cd51d76 --- /dev/null +++ b/SDK/CPackExamples/Cpp/Source/TextureCube.cpp @@ -0,0 +1,205 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +TextureCube.cpp : 3MF Texture Cube creation example. + +--*/ + +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) +{ + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) +{ + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +PTexture2DGroup fnLoadModelTexture(PModel model, const std::string sOPCPath, const std::string sFilePath, eLib3MFTextureType eType, eLib3MFTextureTileStyle eTileStyleU, eLib3MFTextureTileStyle eTileStyleV) +{ + std::string sRelationshipType_Texture = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; + PAttachment attachment = model->AddAttachment(sOPCPath, sRelationshipType_Texture); + attachment->ReadFromFile(sFilePath); + + PTexture2D texture2D = model->AddTexture2DFromAttachment(attachment.get()); + + texture2D->SetContentType(eType); + texture2D->SetTileStyleUV(eTileStyleU, eTileStyleV); + + PTexture2DGroup textureGroup = model->AddTexture2DGroup(texture2D.get()); + return textureGroup; +} + + +sLib3MFTriangleProperties fnCreateTexture(PTexture2DGroup textureGroup, double u1, double v1, double u2, double v2, double u3, double v3) +{ + sLib3MFTriangleProperties property; + property.m_ResourceID = textureGroup->GetResourceID(); + property.m_PropertyIDs[0] = textureGroup->AddTex2Coord(sLib3MFTex2Coord({ u1, v1 })); + property.m_PropertyIDs[1] = textureGroup->AddTex2Coord(sLib3MFTex2Coord({ u2, v2 })); + property.m_PropertyIDs[2] = textureGroup->AddTex2Coord(sLib3MFTex2Coord({ u3, v3 })); + return property; +} + +void TextureExample() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Texture Cube example" << std::endl; + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Textured Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 100.0f; + float fSizeZ = 100.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + std::string sTextureFolder = TEXTURESPATH; + // add textures to 3mf package + std::cout << "sTextureFolder=\"" << sTextureFolder << "\"\n"; + auto textureGroup1 = fnLoadModelTexture(model, "/3D/Textures/tex1.png", sTextureFolder + "tex1.png", eTextureType::PNG, eTextureTileStyle::Wrap, eTextureTileStyle::Wrap); + auto textureGroup2 = fnLoadModelTexture(model, "/3D/Textures/tex2.png", sTextureFolder + "tex2.png", eTextureType::PNG, eTextureTileStyle::Mirror, eTextureTileStyle::Wrap); + auto textureGroup3 = fnLoadModelTexture(model, "/3D/Textures/tex3.png", sTextureFolder + "tex3.png", eTextureType::PNG, eTextureTileStyle::Wrap, eTextureTileStyle::Mirror); + auto textureGroup4 = fnLoadModelTexture(model, "/3D/Textures/tex4.png", sTextureFolder + "tex4.png", eTextureType::PNG, eTextureTileStyle::Clamp, eTextureTileStyle::Wrap); + auto textureGroup5 = fnLoadModelTexture(model, "/3D/Textures/tex5.png", sTextureFolder + "tex5.png", eTextureType::PNG, eTextureTileStyle::Wrap, eTextureTileStyle::Clamp); + auto textureGroup6 = fnLoadModelTexture(model, "/3D/Textures/tex6.png", sTextureFolder + "tex6.png", eTextureType::PNG, eTextureTileStyle::Clamp, eTextureTileStyle::Mirror); + + // Side 1 + meshObject->SetTriangleProperties(0, fnCreateTexture(textureGroup1, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(1, fnCreateTexture(textureGroup1, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 2 + meshObject->SetTriangleProperties(2, fnCreateTexture(textureGroup2, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(3, fnCreateTexture(textureGroup2, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 3 + // Go outside of bounds on this side + meshObject->SetTriangleProperties(4, fnCreateTexture(textureGroup3, -1.0, -1.0, 2.0, -1.0, 2.0, 2.0)); + meshObject->SetTriangleProperties(5, fnCreateTexture(textureGroup3, 2.0, 2.0, -1.0, 2.0, -1.0, -1.0)); + + // Side 4 + meshObject->SetTriangleProperties(6, fnCreateTexture(textureGroup4, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(7, fnCreateTexture(textureGroup4, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 5 + meshObject->SetTriangleProperties(8, fnCreateTexture(textureGroup5, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(9, fnCreateTexture(textureGroup5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Side 6 + meshObject->SetTriangleProperties(10, fnCreateTexture(textureGroup6, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0)); + meshObject->SetTriangleProperties(11, fnCreateTexture(textureGroup6, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0)); + + // Object Level Property + meshObject->SetObjectLevelProperty(textureGroup1->GetResourceID(), 1); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper->GetIdentityTransform()); + + PWriter writer = model->QueryWriter("3mf"); + writer->WriteToFile("texturegroup.3mf"); + + std::cout << "done" << std::endl; +} + +int main() { + try { + TextureExample(); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} + + diff --git a/SDK/CPackExamples/CppDynamic/CMakeLists.txt b/SDK/CPackExamples/CppDynamic/CMakeLists.txt new file mode 100644 index 000000000..4fee96e92 --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/CMakeLists.txt @@ -0,0 +1,75 @@ +#[[++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This file has been generated by the Automatic Component Toolkit (ACT) version 1.5.0-develop3. + +Abstract: This is an autogenerated CMake Project that demonstrates the + usage of the Dynamic C++ bindings of the 3MF Library + +Interface version: 2.2.0 + + +]] + +cmake_minimum_required(VERSION 3.5) + +project(Example_ExtractInfo) +set(CMAKE_CXX_STANDARD 11) + +# Determine the platform and set lib3mf_DIR accordingly +if(WIN32) + # Path for Windows + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS CppDynamic) +elseif(APPLE) + # Path for macOS (Darwin) + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + find_package(lib3mf REQUIRED COMPONENTS CppDynamic) +else() + # Path for Linux (Here we check twice to test for Debian / RPM packages properly) + find_package(lib3mf QUIET COMPONENTS CppDynamic) + # Check if the package was not found + if(NOT lib3mf_FOUND) + # lib3mf not found, so set lib3mf_DIR to the fallback directory + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + # Find package (lib3mf) + find_package(lib3mf REQUIRED COMPONENTS CppDynamic) + endif() +endif() + +add_executable(Example_ExtractInfo "${CMAKE_CURRENT_SOURCE_DIR}/Source/ExtractInfo.cpp") + +# In case of CDynamic and CppDynamic, the lib3mf::lib3mf is simply an alias to an interface +target_link_libraries(Example_ExtractInfo lib3mf::lib3mf ${CMAKE_DL_LIBS}) + +if (${MSVC}) + IF(${CMAKE_VERSION} VERSION_LESS 3.6.3) + MESSAGE ("Note: You need to manually select a StartUp-project in Visual Studio.") + ELSE() + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Example_ExtractInfo) + ENDIF() +endif() + diff --git a/SDK/CPackExamples/CppDynamic/GenerateMake.sh b/SDK/CPackExamples/CppDynamic/GenerateMake.sh new file mode 100644 index 000000000..16fe9cf2b --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateMake.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +basepath="$(cd "$(dirname "$0")" && pwd)" +builddir="$basepath/build" +mkdir -p $builddir +cd $builddir +cmake .. -G "Unix Makefiles" "$@" \ No newline at end of file diff --git a/SDK/CPackExamples/CppDynamic/GenerateVS2015.bat b/SDK/CPackExamples/CppDynamic/GenerateVS2015.bat new file mode 100644 index 000000000..e6933cdeb --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateVS2015.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 14 2015 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/CppDynamic/GenerateVS2017.bat b/SDK/CPackExamples/CppDynamic/GenerateVS2017.bat new file mode 100644 index 000000000..4014d2f99 --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateVS2017.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 15 2017 Win64" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/CppDynamic/GenerateVS2019.bat b/SDK/CPackExamples/CppDynamic/GenerateVS2019.bat new file mode 100644 index 000000000..efa4f308f --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/GenerateVS2019.bat @@ -0,0 +1,10 @@ +@echo off +set startingDir=%CD% + +set basepath=%~dp0 +set builddir=%basepath%\build +if not exist %builddir% (mkdir %builddir%) +cd %builddir% +cmake -G "Visual Studio 16 2019" .. %* + +cd %startingDir% diff --git a/SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp b/SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp new file mode 100644 index 000000000..0a96b29f4 --- /dev/null +++ b/SDK/CPackExamples/CppDynamic/Source/ExtractInfo.cpp @@ -0,0 +1,271 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +ExtractInfo.cpp : 3MF Read Example + +--*/ + +#include +#include +#include + +#include "lib3mf_dynamic.hpp" + +using namespace Lib3MF; + + +void printVersion(PWrapper wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper->GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper->GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +void ShowThumbnailInformation(PModel model) +{ + /* + // TODO: this is not yet implemented in lib3mf + */ +} + + +void ShowMetaDataInformation(PMetaDataGroup metaDataGroup) +{ + Lib3MF_uint32 nMetaDataCount = metaDataGroup->GetMetaDataCount(); + + for (Lib3MF_uint32 iMeta = 0; iMeta < nMetaDataCount; iMeta++) { + + PMetaData metaData = metaDataGroup->GetMetaData(iMeta); + std::string sMetaDataValue = metaData->GetValue(); + std::string sMetaDataName = metaData->GetName(); + std::cout << "Metadatum: " << iMeta << ":" << std::endl; + std::cout << "Name = \"" << sMetaDataName << "\"" << std::endl; + std::cout << "Value = \"" << sMetaDataValue << "\"" << std::endl; + } +} + +void ShowSliceStack(PSliceStack sliceStack, std::string indent) +{ + std::cout << indent << "SliceStackID: " << sliceStack->GetResourceID() << std::endl; + if (sliceStack->GetSliceCount() > 0) { + std::cout << indent << " Slice count: " << sliceStack->GetSliceCount() << std::endl; + } + if (sliceStack->GetSliceRefCount() > 0) { + std::cout << indent << " Slice ref count: " << sliceStack->GetSliceRefCount() << std::endl; + for (Lib3MF_uint64 iSliceRef = 0; iSliceRef < sliceStack->GetSliceRefCount(); iSliceRef++) { + std::cout << indent << " Slice ref : " << sliceStack->GetSliceStackReference(iSliceRef)->GetResourceID() << std::endl; + } + } +} + +void ShowObjectProperties(PObject object) +{ + std::cout << " Name: \"" << object->GetName() << "\"" << std::endl; + std::cout << " PartNumber: \"" << object->GetPartNumber() << "\"" << std::endl; + + switch (object->GetType()) { + case eObjectType::Model: + std::cout << " Object type: model" << std::endl; + break; + case eObjectType::Support: + std::cout << " Object type: support" << std::endl; + break; + case eObjectType::SolidSupport: + std::cout << " Object type: solidsupport" << std::endl; + break; + case eObjectType::Other: + std::cout << " Object type: other" << std::endl; + break; + default: + std::cout << " Object type: invalid" << std::endl; + break; + } + + if (object->HasSlices(false)) { + PSliceStack sliceStack = object->GetSliceStack(); + ShowSliceStack(sliceStack, " "); + } + + if (object->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(object->GetMetaDataGroup()); + } +} + +void ShowMeshObjectInformation(PMeshObject meshObject) +{ + std::cout << "mesh object #" << meshObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(meshObject); + + Lib3MF_uint64 nVertexCount = meshObject->GetVertexCount(); + Lib3MF_uint64 nTriangleCount = meshObject->GetTriangleCount(); + PBeamLattice beamLattice = meshObject->BeamLattice(); + + // Output data + std::cout << " Vertex count: " << nVertexCount << std::endl; + std::cout << " Triangle count: " << nTriangleCount << std::endl; + + Lib3MF_uint64 nBeamCount = beamLattice->GetBeamCount(); + if (nBeamCount > 0) { + std::cout << " Beam count: " << nBeamCount << std::endl; + Lib3MF_uint32 nRepresentationMesh; + if (beamLattice->GetRepresentation(nRepresentationMesh)) + std::cout << " |_Representation Mesh ID: " << nRepresentationMesh << std::endl; + eLib3MFBeamLatticeClipMode eClipMode; + Lib3MF_uint32 nClippingMesh; + beamLattice->GetClipping(eClipMode, nClippingMesh); + if (eClipMode != eBeamLatticeClipMode::NoClipMode) + std::cout << " |_Clipping Mesh ID: " << nClippingMesh << "(mode=" << (int)eClipMode << ")" << std::endl; + if (beamLattice->GetBeamSetCount() > 0) { + std::cout << " |_BeamSet count: " << beamLattice->GetBeamSetCount() << std::endl; + } + } + +} + +void ShowTransform(sLib3MFTransform transform, std::string indent) { + std::cout << indent << "Transformation: [ " << transform.m_Fields[0][0] << " " << transform.m_Fields[1][0] << " " << transform.m_Fields[2][0] << " " << transform.m_Fields[3][0] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][1] << " " << transform.m_Fields[1][1] << " " << transform.m_Fields[2][1] << " " << transform.m_Fields[3][1] << " ]" << std::endl; + std::cout << indent << " [ " << transform.m_Fields[0][2] << " " << transform.m_Fields[1][2] << " " << transform.m_Fields[2][2] << " " << transform.m_Fields[3][2] << " ]" << std::endl; +} + +void ShowComponentsObjectInformation(PComponentsObject componentsObject) +{ + std::cout << "components object #" << componentsObject->GetResourceID() << ": " << std::endl; + + ShowObjectProperties(componentsObject); + std::cout << " Component count: " << componentsObject->GetComponentCount() << std::endl; + for (Lib3MF_uint32 nIndex = 0; nIndex < componentsObject->GetComponentCount(); nIndex++) { + PComponent component = componentsObject->GetComponent(nIndex); + + std::cout << " Component " << nIndex << ": Object ID: " << component->GetObjectResourceID() << std::endl; + if (component->HasTransform()) { + ShowTransform(component->GetTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + } +} + + +void ExtractInfoExample(std::string sFileName) { + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF Read example" << std::endl; + + std::string libpath = ("."); // TODO: put the location of the Lib3MF-library file here. + auto wrapper = Lib3MF::CWrapper::loadLibrary(LIB3MF_LIBRARY_LOCATION); // TODO: add correct suffix of the library + + printVersion(wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + PModel model = wrapper->CreateModel(); + + // Import Model from 3MF File + { + PReader reader = model->QueryReader("3mf"); + // And deactivate the strict mode (default is "false", anyway. This just demonstrates where/how to use it). + reader->SetStrictModeActive(false); + reader->ReadFromFile(sFileName); + + for (Lib3MF_uint32 iWarning = 0; iWarning < reader->GetWarningCount(); iWarning++) { + Lib3MF_uint32 nErrorCode; + std::string sWarningMessage = reader->GetWarning(iWarning, nErrorCode); + std::cout << "Encountered warning #" << nErrorCode << " : " << sWarningMessage << std::endl; + } + } + ShowThumbnailInformation(model); + + ShowMetaDataInformation(model->GetMetaDataGroup()); + + PSliceStackIterator sliceStacks = model->GetSliceStacks(); + while (sliceStacks->MoveNext()) { + PSliceStack sliceStack = sliceStacks->GetCurrentSliceStack(); + ShowSliceStack(sliceStack, ""); + } + + PObjectIterator objectIterator = model->GetObjects(); + while (objectIterator->MoveNext()) { + PObject object = objectIterator->GetCurrentObject(); + if (object->IsMeshObject()) { + ShowMeshObjectInformation(model->GetMeshObjectByID(object->GetResourceID())); + } + else if (object->IsComponentsObject()) { + ShowComponentsObjectInformation(model->GetComponentsObjectByID(object->GetResourceID())); + } + else { + std::cout << "unknown object #" << object->GetResourceID() << ": " << std::endl; + } + } + + + PBuildItemIterator buildItemIterator = model->GetBuildItems(); + while (buildItemIterator->MoveNext()) { + PBuildItem buildItem = buildItemIterator->GetCurrent(); + + std::cout << "Build item (Object #" << buildItem->GetObjectResourceID() << "): " << std::endl; + + if (buildItem->HasObjectTransform()) { + ShowTransform(buildItem->GetObjectTransform(), " "); + } + else { + std::cout << " Transformation: none" << std::endl; + } + std::cout << " Part number: \"" << buildItem->GetPartNumber() << "\"" << std::endl; + if (buildItem->GetMetaDataGroup()->GetMetaDataCount() > 0) { + ShowMetaDataInformation(buildItem->GetMetaDataGroup()); + } + } + + std::cout << "done" << std::endl; +} + + +int main(int argc, char** argv) { + // Parse Arguments + if (argc != 2) { + std::cout << "Usage: " << std::endl; + std::cout << "ExtractInfo.exe model.3mf" << std::endl; + return 0; + } + + try { + ExtractInfoExample(argv[1]); + } + catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/GenerateSDK_github.sh b/SDK/GenerateSDK_github.sh index 6a59330ea..00a0d6236 100644 --- a/SDK/GenerateSDK_github.sh +++ b/SDK/GenerateSDK_github.sh @@ -43,4 +43,4 @@ echo "GITRevision = "`git rev-parse HEAD` >> $VERSIONTXT echo Zip SDK artifacts cd $SDKARTIFACT -zip -r ../$OUTFILE ./* || failed "Error zipping SDK" +zip -r ../$OUTFILE ./* || failed "Error zipping SDK" \ No newline at end of file diff --git a/cmake/lib3mfConfig.cmake b/cmake/lib3mfConfig.cmake new file mode 100644 index 000000000..f1305b8f5 --- /dev/null +++ b/cmake/lib3mfConfig.cmake @@ -0,0 +1,104 @@ +# lib3mfConfig.cmake + +if(VCPKG_TOOLCHAIN) + message("Lib3MF - VCPKG Tool Chain") + set(LIB3MF_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../..") +else() + message("Lib3MF - General CMake Tool Chain") + set(LIB3MF_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../..") +endif() + + +# Initial setup for known components and default selection +set(lib3mf_known_components "C" "CDynamic" "Cpp" "CppDynamic") +set(lib3mf_selected_variant "Cpp") # Default variant + +# Check if any known component was specified and select it +foreach(comp ${lib3mf_FIND_COMPONENTS}) + if(comp IN_LIST lib3mf_known_components) + set(lib3mf_selected_variant ${comp}) + break() # Use the first specified known component + endif() +endforeach() + +# Configure paths based on the selected variant +set(lib3mf_INCLUDE_DIR "${LIB3MF_ROOT_DIR}/include/Bindings/${lib3mf_selected_variant}") +set(lib3mf_LIBRARY_DIR "${LIB3MF_ROOT_DIR}/lib") +set(lib3mf_BINARY_DIR "${LIB3MF_ROOT_DIR}/bin") + +# Adjust library file name based on platform +if(WIN32) + set(lib3mf_LIBRARY "${lib3mf_BINARY_DIR}/lib3mf.dll") + set(lib3mf_LIBRARY_IMPORT "${lib3mf_LIBRARY_DIR}/lib3mf.lib") # For importing symbols +elseif(APPLE) + set(lib3mf_LIBRARY "${lib3mf_LIBRARY_DIR}/lib3mf.dylib") +else() # Linux and others + set(lib3mf_LIBRARY "${lib3mf_LIBRARY_DIR}/lib3mf.so") +endif() + +# Print the chosen variant +message("***********************************") +message("LIB3MF Chosen Variant : " ${lib3mf_selected_variant}) +message("***********************************") + +# Create a special interface for dynamic loading scenarios +if("${lib3mf_selected_variant}" STREQUAL "CppDynamic" OR "${lib3mf_selected_variant}" STREQUAL "CDynamic") + if("${lib3mf_selected_variant}" STREQUAL "CDynamic") + message("*****************************************************************************") + message("") + message(" For CDynamic Variant, an additional source called lib3mf_dynamic.cc ") + message(" is required ") + message(" It is made available using the variable LIB3MF_CDYNAMIC_ADDITIONAL_SOURCE ") + message(" You must append this to your sources ") + message("") + message("*****************************************************************************") + set(LIB3MF_CDYNAMIC_ADDITIONAL_SOURCE "${LIB3MF_ROOT_DIR}/include/Bindings/CDynamic/lib3mf_dynamic.cc") + endif() + add_library(lib3mfdynamic INTERFACE) + # Now alias lib3mfdynamic to include the namespace + add_library(lib3mf::lib3mf ALIAS lib3mfdynamic) + # Set properties and compile definitions for lib3mfdynamic + target_compile_definitions(lib3mfdynamic INTERFACE + "LIB3MF_LIBRARY_LOCATION=\"${lib3mf_LIBRARY}\"" + ) + target_include_directories(lib3mfdynamic INTERFACE "${lib3mf_INCLUDE_DIR}") +else() + # Define the imported target for static linking + add_library(lib3mf::lib3mf SHARED IMPORTED) + set_target_properties(lib3mf::lib3mf PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${lib3mf_INCLUDE_DIR}" + IMPORTED_LOCATION "${lib3mf_LIBRARY}" + ) + if(WIN32) + set_property(TARGET lib3mf::lib3mf PROPERTY IMPORTED_IMPLIB "${lib3mf_LIBRARY_IMPORT}") + endif() + + # Define a custom function to handle library copying + function(copy_lib3mf_libraries target) + if(TARGET ${target}) + if(APPLE) + # On macOS, copy .dylib files, preserving symlinks only if they don't already exist in the target directory + file(GLOB LIB3MF_FILES "${lib3mf_LIBRARY_DIR}/lib3mf.dylib*") + foreach(file ${LIB3MF_FILES}) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${file}" "$/$(basename ${file})" + COMMENT "Copying $(basename ${file}) to target directory on macOS if it is different") + endforeach() + + + elseif(UNIX) + # On Unix-like systems (excluding macOS), copy .so files, preserving symlinks + add_custom_command(TARGET ${target} POST_BUILD + COMMAND sh -c "cp -P '${lib3mf_LIBRARY_DIR}/lib3mf.so'* '$'" + COMMENT "Copying all lib3mf.so* files to target directory on Linux") + else() + # On Windows, directly copy the .dll file without worrying about symlinks + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${lib3mf_LIBRARY}" "$" + COMMENT "Copying lib3mf.dll to target directory on Windows") + endif() + else() + message(WARNING "Target '${target}' not found. lib3mf library was not copied.") + endif() + endfunction() +endif() From a1184b8fca0d09df2f42dfd9604e6a6080d752e9 Mon Sep 17 00:00:00 2001 From: gangatp Date: Mon, 27 May 2024 17:21:39 +0530 Subject: [PATCH 42/54] Issue-363: changing int to long long for putDoubleFactor --- Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h | 2 +- Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h b/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h index 6a6954ba5..74a5b832d 100644 --- a/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h +++ b/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h @@ -84,7 +84,7 @@ namespace NMR { nfUint32 m_nBallRefBufferPos; private: const int m_nPosAfterDecPoint; - const int m_nPutDoubleFactor; + const nfInt64 m_nPutDoubleFactor; __NMR_INLINE void putFloat(_In_ const nfFloat fValue, _In_ std::array & line, _In_ nfUint32 & nBufferPos); __NMR_INLINE void putDouble(_In_ const nfDouble dValue, _In_ std::array & line, _In_ nfUint32 & nBufferPos); diff --git a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp index d25fb17a5..e231329b3 100644 --- a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp +++ b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp @@ -52,7 +52,7 @@ namespace NMR { CModelWriterNode100_Mesh::CModelWriterNode100_Mesh(_In_ CModelMeshObject * pModelMeshObject, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, _In_ PMeshInformation_PropertyIndexMapping pPropertyIndexMapping, _In_ int nPosAfterDecPoint, _In_ nfBool bWriteMaterialExtension, _In_ nfBool bWriteBeamLatticeExtension) - :CModelWriterNode_ModelBase(pModelMeshObject->getModel(), pXMLWriter, pProgressMonitor), m_nPosAfterDecPoint(nPosAfterDecPoint), m_nPutDoubleFactor((int)(pow(10, CModelWriterNode100_Mesh::m_nPosAfterDecPoint))) + :CModelWriterNode_ModelBase(pModelMeshObject->getModel(), pXMLWriter, pProgressMonitor), m_nPosAfterDecPoint(nPosAfterDecPoint), m_nPutDoubleFactor((nfInt64)(pow(10, CModelWriterNode100_Mesh::m_nPosAfterDecPoint))) { __NMRASSERT(pModelMeshObject != nullptr); if (!pPropertyIndexMapping.get()) From 0fa4ecfe696dae89159a996ed1c4081a3814a2df Mon Sep 17 00:00:00 2001 From: gangatp Date: Mon, 27 May 2024 18:11:45 +0530 Subject: [PATCH 43/54] fixing stringRepResenationsDiffer to use long long putFactor --- Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp index e231329b3..1889288d9 100644 --- a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp +++ b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp @@ -79,7 +79,7 @@ namespace NMR { putBallRefString(MODELWRITERMESH100_BEAMLATTICE_BALLREFLINESTART); } - bool stringRepresentationsDiffer(double a, double b, double putFactor) { + bool stringRepresentationsDiffer(double a, double b, nfInt64 putFactor) { return fabs(a - b) * putFactor > 0.1; } From a5088c27c1a5a5631ff037a5e9ad5d7fda758b46 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:52:42 +0200 Subject: [PATCH 44/54] Using StringUtils from develop branch --- Source/Common/NMR_StringUtils.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Source/Common/NMR_StringUtils.cpp b/Source/Common/NMR_StringUtils.cpp index d8cb05ccd..81dad377b 100644 --- a/Source/Common/NMR_StringUtils.cpp +++ b/Source/Common/NMR_StringUtils.cpp @@ -38,7 +38,6 @@ correctly and Exception-safe #include #include #include -#include namespace NMR { @@ -151,7 +150,7 @@ namespace NMR { nfDouble fnStringToDouble(_In_z_ const nfChar * pszValue) { - __NMRASSERT(pszValue); + __NMRASSERT(pwszValue); nfDouble dResult = 0.0; //skip leading whitespaces @@ -174,18 +173,7 @@ namespace NMR { } if ((dResult == HUGE_VAL) || (dResult == -HUGE_VAL)) throw CNMRException(NMR_ERROR_STRINGTODOUBLECONVERSIONOUTOFRANGE); -#else - // Convert to double and make a input and range check! - std::from_chars_result result = std::from_chars(pszValue, pszValue + strlen(pszValue), dResult, std::chars_format::general); - // Check if any conversion happened - if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range) - throw CNMRException(NMR_ERROR_EMPTYSTRINGTODOUBLECONVERSION); - - if ((*result.ptr != '\0') && (*result.ptr != ' ')) - throw CNMRException(NMR_ERROR_INVALIDSTRINGTODOUBLECONVERSION); - -#endif return dResult; } From 0e91f7a9d95ba77e254afdf9be108af84819b29c Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:53:17 +0200 Subject: [PATCH 45/54] Update CMakeLists.txt to use C++17 standard --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d10fd2a4e..bbc8f5ee3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,16 +34,19 @@ option(BUILD_FOR_CODECOVERAGE "Build for code coverage analysis" OFF) option(STRIP_BINARIES "Strip binaries (on non-apple)" ON) option(USE_PLATFORM_UUID "Use UUID geneator that is provided by the OS (always ON for Windows)" OFF) +add_compile_options($<$:/MP>) +set (CMAKE_CXX_STANDARD 17) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # using GCC add_definitions(-DBUILD_DLL) add_compile_options(-Wall) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O2") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O2") elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") # using GCC add_definitions(-DBUILD_DLL) add_compile_options(-Wall) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O2") set(CMAKE_MACOSX_RPATH ON) endif() From e94864b46010c6fc41ffbea3427fa7ef1e613865 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:55:08 +0200 Subject: [PATCH 46/54] [CMakeLists.txt] removing pre-release information --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bbc8f5ee3..2923a8831 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(GNUInstallDirs) set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API set(LIB3MF_VERSION_MINOR 4) # increase on every backward compatible change of the API set(LIB3MF_VERSION_MICRO 0) # increase on on every change that does not alter the API -set(LIB3MF_VERSION_PRERELEASE "implicit") # denotes pre-release information of a version of lib3mf +set(LIB3MF_VERSION_PRERELEASE "") # denotes pre-release information of a version of lib3mf project(lib3mf VERSION ${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO} From 23a5c5ca74382e55f528b1529d6f58955e5ff649 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:25:56 +0200 Subject: [PATCH 47/54] Remove unused lib3mfConfig.cmake.in file --- cmake/lib3mfConfig.cmake.in | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 cmake/lib3mfConfig.cmake.in diff --git a/cmake/lib3mfConfig.cmake.in b/cmake/lib3mfConfig.cmake.in deleted file mode 100644 index 744c348f6..000000000 --- a/cmake/lib3mfConfig.cmake.in +++ /dev/null @@ -1,3 +0,0 @@ -@PACKAGE_INIT@ - -include("${CMAKE_CURRENT_LIST_DIR}/lib3mfTargets.cmake") \ No newline at end of file From 8ff581069eefe4760ceb2bfa1c17977fb71d7896 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:28:21 +0200 Subject: [PATCH 48/54] [SDK} read lib3mf version in CMakeLists.txt from environment variable LIB3MF_VERSION --- SDK/CPackExamples/Cpp/CMakeLists.txt | 12 +++++++++--- SDK/CPackExamples/CppDynamic/CMakeLists.txt | 13 ++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/SDK/CPackExamples/Cpp/CMakeLists.txt b/SDK/CPackExamples/Cpp/CMakeLists.txt index e75ad0874..5697a68b2 100644 --- a/SDK/CPackExamples/Cpp/CMakeLists.txt +++ b/SDK/CPackExamples/Cpp/CMakeLists.txt @@ -2,14 +2,20 @@ cmake_minimum_required (VERSION 3.5) project(Examples) set(CMAKE_CXX_STANDARD 11) +# read the version of the 3MF Library from en environment variable LIB3MF_VERSION +if (DEFINED ENV{LIB3MF_VERSION}) + set(LIB3MF_VERSION $ENV{LIB3MF_VERSION}) +else() + set(LIB3MF_VERSION "2.3.1") + # Determine the platform and set lib3mf_DIR accordingly if(WIN32) # Path for Windows - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-${LIB3MF_VERSION}-Windows/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS Cpp) elseif(APPLE) # Path for macOS (Darwin) - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-${LIB3MF_VERSION}-Darwin/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS Cpp) else() # Path for Linux (Here we check twice to test for Debian / RPM packages properly) @@ -17,7 +23,7 @@ else() # Check if the package was not found if(NOT lib3mf_FOUND) # lib3mf not found, so set lib3mf_DIR to the fallback directory - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-${LIB3MF_VERSION}-Linux/lib/cmake/lib3mf") # Find package (lib3mf) find_package(lib3mf REQUIRED COMPONENTS Cpp) endif() diff --git a/SDK/CPackExamples/CppDynamic/CMakeLists.txt b/SDK/CPackExamples/CppDynamic/CMakeLists.txt index 4fee96e92..d896df0f0 100644 --- a/SDK/CPackExamples/CppDynamic/CMakeLists.txt +++ b/SDK/CPackExamples/CppDynamic/CMakeLists.txt @@ -39,14 +39,21 @@ cmake_minimum_required(VERSION 3.5) project(Example_ExtractInfo) set(CMAKE_CXX_STANDARD 11) + +# read the version of the 3MF Library from en environment variable LIB3MF_VERSION +if (DEFINED ENV{LIB3MF_VERSION}) + set(LIB3MF_VERSION $ENV{LIB3MF_VERSION}) +else() + set(LIB3MF_VERSION "2.3.1") + # Determine the platform and set lib3mf_DIR accordingly if(WIN32) # Path for Windows - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-${LIB3MF_VERSION}-Windows/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS CppDynamic) elseif(APPLE) # Path for macOS (Darwin) - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-${LIB3MF_VERSION}-Darwin/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS CppDynamic) else() # Path for Linux (Here we check twice to test for Debian / RPM packages properly) @@ -54,7 +61,7 @@ else() # Check if the package was not found if(NOT lib3mf_FOUND) # lib3mf not found, so set lib3mf_DIR to the fallback directory - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-${LIB3MF_VERSION}-Linux/lib/cmake/lib3mf") # Find package (lib3mf) find_package(lib3mf REQUIRED COMPONENTS CppDynamic) endif() From b4eb2ae5b8a5e200c0946c11193a5c85b2608600 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:46:27 +0200 Subject: [PATCH 49/54] [SDK] adding missing endif() --- SDK/CPackExamples/Cpp/CMakeLists.txt | 3 ++- SDK/CPackExamples/CppDynamic/CMakeLists.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/SDK/CPackExamples/Cpp/CMakeLists.txt b/SDK/CPackExamples/Cpp/CMakeLists.txt index 5697a68b2..bfa74e4dd 100644 --- a/SDK/CPackExamples/Cpp/CMakeLists.txt +++ b/SDK/CPackExamples/Cpp/CMakeLists.txt @@ -2,11 +2,12 @@ cmake_minimum_required (VERSION 3.5) project(Examples) set(CMAKE_CXX_STANDARD 11) -# read the version of the 3MF Library from en environment variable LIB3MF_VERSION +# read the version of the 3MF Library from environment variable LIB3MF_VERSION if (DEFINED ENV{LIB3MF_VERSION}) set(LIB3MF_VERSION $ENV{LIB3MF_VERSION}) else() set(LIB3MF_VERSION "2.3.1") +endif() # Determine the platform and set lib3mf_DIR accordingly if(WIN32) diff --git a/SDK/CPackExamples/CppDynamic/CMakeLists.txt b/SDK/CPackExamples/CppDynamic/CMakeLists.txt index d896df0f0..7baa64dbf 100644 --- a/SDK/CPackExamples/CppDynamic/CMakeLists.txt +++ b/SDK/CPackExamples/CppDynamic/CMakeLists.txt @@ -40,11 +40,12 @@ project(Example_ExtractInfo) set(CMAKE_CXX_STANDARD 11) -# read the version of the 3MF Library from en environment variable LIB3MF_VERSION +# read the version of the 3MF Library from environment variable LIB3MF_VERSION if (DEFINED ENV{LIB3MF_VERSION}) set(LIB3MF_VERSION $ENV{LIB3MF_VERSION}) else() set(LIB3MF_VERSION "2.3.1") +endif() # Determine the platform and set lib3mf_DIR accordingly if(WIN32) From 216be33c1728ae6b11397d5e2c8d371bc51f6a50 Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Tue, 11 Jun 2024 09:19:23 +0530 Subject: [PATCH 50/54] Include a additional entry to build.yml to pack source code + submodules (#372) * Include an additional artifact that packs the code with submodules * exclude unnecessary stuff * avoid recursion * avoid zip.zip --- .github/workflows/build.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4b0c6d77b..0d8cd36cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -506,10 +506,29 @@ jobs: cmake --build . ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf + deploy-source-code-with-submodules: + runs-on: ubuntu-20.04 + needs: [ set-lib3mf-version, assemble-sdk ] + env: + LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - run: | + mkdir -p lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules + rsync -av --progress . ./lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules --exclude .git --exclude .gitignore --exclude .github --exclude .gitmodules --exclude *.yml --exclude lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules + path: lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules + + set-integration-tests-status: runs-on: ubuntu-20.04 - needs: [ deploy-linux, deploy-windows, deploy-macos ] + needs: [ deploy-linux, deploy-windows, deploy-macos, deploy-source-code-with-submodules ] outputs: run_integration_tests: ${{ steps.set-status.outputs.run_integration_tests }} steps: From 4889e3fbfbe9bdd1ad4b6da2c5aee474813188cb Mon Sep 17 00:00:00 2001 From: Vijai Kumar S Date: Wed, 12 Jun 2024 11:15:50 +0530 Subject: [PATCH 51/54] Switch version in all the required places + A Python script to automatically make the version change in required places (#373) * Included a new script to automatically update lib3mf version in all the required places * Include some rudimentary documentation in lib3mf_version_update.py --- Autogenerated/Bindings/C/lib3mf.h | 2 +- Autogenerated/Bindings/C/lib3mf_types.h | 4 +- .../Bindings/CDynamic/lib3mf_dynamic.cc | 2 +- .../Bindings/CDynamic/lib3mf_dynamic.h | 2 +- .../Bindings/CDynamic/lib3mf_types.h | 4 +- Autogenerated/Bindings/CSharp/Lib3MF.cs | 2 +- Autogenerated/Bindings/Cpp/lib3mf_abi.hpp | 2 +- .../Bindings/Cpp/lib3mf_implicit.hpp | 2 +- Autogenerated/Bindings/Cpp/lib3mf_types.hpp | 4 +- .../Bindings/CppDynamic/lib3mf_abi.hpp | 2 +- .../Bindings/CppDynamic/lib3mf_dynamic.h | 2 +- .../Bindings/CppDynamic/lib3mf_dynamic.hpp | 2 +- .../Bindings/CppDynamic/lib3mf_types.hpp | 4 +- Autogenerated/Bindings/Go/cfunc.go | 2 +- Autogenerated/Bindings/Go/lib3mf.go | 2 +- Autogenerated/Bindings/Go/lib3mf_dynamic.cc | 2 +- Autogenerated/Bindings/Go/lib3mf_dynamic.h | 2 +- Autogenerated/Bindings/Go/lib3mf_impl.go | 2 +- Autogenerated/Bindings/Go/lib3mf_types.h | 4 +- .../Bindings/NodeJS/lib3mf_dynamic.cc | 2 +- .../Bindings/NodeJS/lib3mf_dynamic.h | 2 +- .../Bindings/NodeJS/lib3mf_nodeaddon.cc | 2 +- .../Bindings/NodeJS/lib3mf_nodewrapper.cc | 2 +- .../Bindings/NodeJS/lib3mf_nodewrapper.h | 2 +- Autogenerated/Bindings/NodeJS/lib3mf_types.h | 4 +- Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas | 4 +- Autogenerated/Bindings/Python/Lib3MF.py | 4 +- Autogenerated/Source/lib3mf_abi.hpp | 2 +- .../Source/lib3mf_interfaceexception.cpp | 2 +- .../Source/lib3mf_interfaceexception.hpp | 2 +- .../Source/lib3mf_interfacejournal.cpp | 4 +- .../Source/lib3mf_interfacejournal.hpp | 2 +- Autogenerated/Source/lib3mf_interfaces.hpp | 2 +- .../Source/lib3mf_interfacewrapper.cpp | 2 +- Autogenerated/Source/lib3mf_types.hpp | 4 +- AutomaticComponentToolkit/lib3mf.xml | 2 +- CMakeLists.txt | 2 +- Documentation/conf.py | 2 +- Documentation/index.rst | 6 +- README.md | 4 +- SDK/CPackExamples/Cpp/CMakeLists.txt | 6 +- SDK/CPackExamples/CppDynamic/CMakeLists.txt | 6 +- SDK/Examples/CSharp/Lib3MF_Example.cs | 2 +- SDK/Examples/Pascal/Lib3MF_Example.lpr | 2 +- SDK/Examples/Python/3mf_convert.py | 2 +- SDK/Examples/Python/Lib3MF_Example.py | 2 +- SDK/Examples/Python/add_triangle.py | 2 +- SDK/Examples/Python/beam_lattice.py | 2 +- SDK/Examples/Python/color_cube.py | 2 +- SDK/Examples/Python/create_components.py | 2 +- SDK/Examples/Python/create_cube.py | 2 +- SDK/Examples/Python/extract_info.py | 2 +- SDK/Examples/Python/lib3mf_common.py | 2 +- SDK/Readme.md | 2 +- Source/API/lib3mf.cpp | 2 +- lib3mf_version_update.py | 250 ++++++++++++++++++ 56 files changed, 322 insertions(+), 72 deletions(-) create mode 100644 lib3mf_version_update.py diff --git a/Autogenerated/Bindings/C/lib3mf.h b/Autogenerated/Bindings/C/lib3mf.h index d22a9aac1..80ba9cd19 100644 --- a/Autogenerated/Bindings/C/lib3mf.h +++ b/Autogenerated/Bindings/C/lib3mf.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/C/lib3mf_types.h b/Autogenerated/Bindings/C/lib3mf_types.h index a0c6149a6..6f2dcf6a4 100644 --- a/Autogenerated/Bindings/C/lib3mf_types.h +++ b/Autogenerated/Bindings/C/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc index 937582f41..e1cec341d 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h index c524c7583..044c754bb 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_types.h b/Autogenerated/Bindings/CDynamic/lib3mf_types.h index a0c6149a6..6f2dcf6a4 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_types.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/CSharp/Lib3MF.cs b/Autogenerated/Bindings/CSharp/Lib3MF.cs index fab65add3..9caaa404a 100644 --- a/Autogenerated/Bindings/CSharp/Lib3MF.cs +++ b/Autogenerated/Bindings/CSharp/Lib3MF.cs @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CSharp file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp index 864f8704d..44b8273b8 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp index c5718c58f..c69787d70 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp index bc584e7b5..705f02718 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -84,7 +84,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp index 255061d89..4efde3a1a 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h index 5aef62409..bfe996afe 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp index 3411be9e3..a374db4eb 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp index bc584e7b5..705f02718 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -84,7 +84,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/Go/cfunc.go b/Autogenerated/Bindings/Go/cfunc.go index 66d256455..0256de1e0 100644 --- a/Autogenerated/Bindings/Go/cfunc.go +++ b/Autogenerated/Bindings/Go/cfunc.go @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go wrapper file in order to allow an easy use of the 3MF Library. -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Go/lib3mf.go b/Autogenerated/Bindings/Go/lib3mf.go index c454d5b63..705bad104 100644 --- a/Autogenerated/Bindings/Go/lib3mf.go +++ b/Autogenerated/Bindings/Go/lib3mf.go @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go wrapper file in order to allow an easy use of the 3MF Library. -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.cc b/Autogenerated/Bindings/Go/lib3mf_dynamic.cc index 937582f41..e1cec341d 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.h b/Autogenerated/Bindings/Go/lib3mf_dynamic.h index c524c7583..044c754bb 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_impl.go b/Autogenerated/Bindings/Go/lib3mf_impl.go index 8fc4c8d1c..f91e68c3b 100644 --- a/Autogenerated/Bindings/Go/lib3mf_impl.go +++ b/Autogenerated/Bindings/Go/lib3mf_impl.go @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go implementation file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_types.h b/Autogenerated/Bindings/Go/lib3mf_types.h index a0c6149a6..6f2dcf6a4 100644 --- a/Autogenerated/Bindings/Go/lib3mf_types.h +++ b/Autogenerated/Bindings/Go/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc index 937582f41..e1cec341d 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h index c524c7583..044c754bb 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc b/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc index 983c79636..96e56c3d9 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodeaddon.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file for the Node addon class of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc index c4bedb2a2..36b978e15 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file for the Node wrapper class of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h index 66c489824..49ce0ade5 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Header file for the Node wrapper class of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_types.h b/Autogenerated/Bindings/NodeJS/lib3mf_types.h index a0c6149a6..6f2dcf6a4 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_types.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_types.h @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated plain C Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -85,7 +85,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas index 6b5ff029d..8271fb01c 100644 --- a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas +++ b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas @@ -30,7 +30,7 @@ Abstract: This is an autogenerated Pascal Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 *) @@ -55,7 +55,7 @@ interface const LIB3MF_VERSION_MAJOR = 2; LIB3MF_VERSION_MINOR = 3; - LIB3MF_VERSION_MICRO = 1; + LIB3MF_VERSION_MICRO = 2; LIB3MF_VERSION_PRERELEASEINFO = ''; LIB3MF_VERSION_BUILDINFO = ''; diff --git a/Autogenerated/Bindings/Python/Lib3MF.py b/Autogenerated/Bindings/Python/Lib3MF.py index 54e233c8d..1b5e6d2fd 100644 --- a/Autogenerated/Bindings/Python/Lib3MF.py +++ b/Autogenerated/Bindings/Python/Lib3MF.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 ''' @@ -58,7 +58,7 @@ def __str__(self): class BindingVersion(enum.IntEnum): MAJOR = 2 MINOR = 3 - MICRO = 1 + MICRO = 2 '''Definition Error Codes ''' diff --git a/Autogenerated/Source/lib3mf_abi.hpp b/Autogenerated/Source/lib3mf_abi.hpp index 864f8704d..44b8273b8 100644 --- a/Autogenerated/Source/lib3mf_abi.hpp +++ b/Autogenerated/Source/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Source/lib3mf_interfaceexception.cpp b/Autogenerated/Source/lib3mf_interfaceexception.cpp index b484bd6a8..5f10f6f2f 100644 --- a/Autogenerated/Source/lib3mf_interfaceexception.cpp +++ b/Autogenerated/Source/lib3mf_interfaceexception.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file with the basic internal exception type in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Source/lib3mf_interfaceexception.hpp b/Autogenerated/Source/lib3mf_interfaceexception.hpp index 1df317ec2..38891fe7e 100644 --- a/Autogenerated/Source/lib3mf_interfaceexception.hpp +++ b/Autogenerated/Source/lib3mf_interfaceexception.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Header file with the basic internal exception type in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Source/lib3mf_interfacejournal.cpp b/Autogenerated/Source/lib3mf_interfacejournal.cpp index 106908b7f..5a94fcddf 100644 --- a/Autogenerated/Source/lib3mf_interfacejournal.cpp +++ b/Autogenerated/Source/lib3mf_interfacejournal.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It provides an automatic Journaling mechanism for the library implementation. -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -286,7 +286,7 @@ CLib3MFInterfaceJournal::CLib3MFInterfaceJournal (const std::string & sFileName) m_StartTime = std::chrono::high_resolution_clock::now(); m_Stream.open (sFileName, std::ios::out); m_Stream << "\n"; - m_Stream << "\n"; + m_Stream << "\n"; m_Stream << "\n"; } diff --git a/Autogenerated/Source/lib3mf_interfacejournal.hpp b/Autogenerated/Source/lib3mf_interfacejournal.hpp index f12f333d1..361b67bc0 100644 --- a/Autogenerated/Source/lib3mf_interfacejournal.hpp +++ b/Autogenerated/Source/lib3mf_interfacejournal.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ header file in order to allow easy development of the 3MF Library. It provides an automatic Journaling mechanism for the library implementation. -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Source/lib3mf_interfaces.hpp b/Autogenerated/Source/lib3mf_interfaces.hpp index 9a479767f..906ffae2d 100644 --- a/Autogenerated/Source/lib3mf_interfaces.hpp +++ b/Autogenerated/Source/lib3mf_interfaces.hpp @@ -30,7 +30,7 @@ Abstract: This is an autogenerated C++ header file in order to allow easy development of the 3MF Library. The implementer of the 3MF Library needs to derive concrete classes from the abstract classes in this header. -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Source/lib3mf_interfacewrapper.cpp b/Autogenerated/Source/lib3mf_interfacewrapper.cpp index 8eddf9ce8..92633dbbd 100644 --- a/Autogenerated/Source/lib3mf_interfacewrapper.cpp +++ b/Autogenerated/Source/lib3mf_interfacewrapper.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. The functions in this file need to be implemented. It needs to be generated only once. -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/Autogenerated/Source/lib3mf_types.hpp b/Autogenerated/Source/lib3mf_types.hpp index bc584e7b5..705f02718 100644 --- a/Autogenerated/Source/lib3mf_types.hpp +++ b/Autogenerated/Source/lib3mf_types.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file with basic types in order to allow an easy use of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ @@ -84,7 +84,7 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_VERSION_MAJOR 2 #define LIB3MF_VERSION_MINOR 3 -#define LIB3MF_VERSION_MICRO 1 +#define LIB3MF_VERSION_MICRO 2 #define LIB3MF_VERSION_PRERELEASEINFO "" #define LIB3MF_VERSION_BUILDINFO "" diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 273d1792f..078cdc4b4 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -1,5 +1,5 @@ - + diff --git a/CMakeLists.txt b/CMakeLists.txt index f7983c519..1c4f8c009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ include(GNUInstallDirs) # Define Version set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API set(LIB3MF_VERSION_MINOR 3) # increase on every backward compatible change of the API -set(LIB3MF_VERSION_MICRO 1) # increase on on every change that does not alter the API +set(LIB3MF_VERSION_MICRO 2) # increase on on every change that does not alter the API set(LIB3MF_VERSION_PRERELEASE "") # denotes pre-release information of a version of lib3mf project(lib3mf diff --git a/Documentation/conf.py b/Documentation/conf.py index 3b05e0b61..70c28f068 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -22,7 +22,7 @@ author = '3MF Consortium' # The full version, including alpha/beta/rc tags -release = 'v2.3.1' +release = 'v2.3.2' master_doc = 'index' diff --git a/Documentation/index.rst b/Documentation/index.rst index ad31b3b56..4eb80031d 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -1,7 +1,7 @@ .. lib3mf documentation master file ********************************************* -lib3mf v2.3.1 documentation +lib3mf v2.3.2 documentation ********************************************* .. image:: https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=master @@ -12,7 +12,7 @@ lib3mf v2.3.1 documentation :target: https://readthedocs.org/projects/lib3mf/ :alt: Documentation Status -.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.1&color=green +.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.2&color=green :alt: Version .. image:: https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey @@ -27,7 +27,7 @@ lib3mf v2.3.1 documentation :language: bash -Welcome! This is the documentation for lib3mf v2.3.1. +Welcome! This is the documentation for lib3mf v2.3.2. lib3mf is an implementation of the 3D Manufacturing Format file standard. diff --git a/README.md b/README.md index 910d569a7..1586b2a62 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # lib3mf -[![Build Status]](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.1) +[![Build Status]](https://github.com/3MFConsortium/lib3mf/workflows/Build/badge.svg?branch=release%2F2.3.2) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) -[![Version 2.3.1](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.1&color=green)]() +[![Version 2.3.2](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.3.2&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() [![Simplified BSD License](https://img.shields.io/static/v1.svg?label=license&message=BSD&color=green)](LICENSE) [![codecov](https://codecov.io/gh/3MFConsortium/lib3mf/branch/develop/graph/badge.svg?token=3ARnBye33c)](https://codecov.io/gh/3MFConsortium/lib3mf) diff --git a/SDK/CPackExamples/Cpp/CMakeLists.txt b/SDK/CPackExamples/Cpp/CMakeLists.txt index e75ad0874..64e493284 100644 --- a/SDK/CPackExamples/Cpp/CMakeLists.txt +++ b/SDK/CPackExamples/Cpp/CMakeLists.txt @@ -5,11 +5,11 @@ set(CMAKE_CXX_STANDARD 11) # Determine the platform and set lib3mf_DIR accordingly if(WIN32) # Path for Windows - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.2-Windows/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS Cpp) elseif(APPLE) # Path for macOS (Darwin) - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.2-Darwin/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS Cpp) else() # Path for Linux (Here we check twice to test for Debian / RPM packages properly) @@ -17,7 +17,7 @@ else() # Check if the package was not found if(NOT lib3mf_FOUND) # lib3mf not found, so set lib3mf_DIR to the fallback directory - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.2-Linux/lib/cmake/lib3mf") # Find package (lib3mf) find_package(lib3mf REQUIRED COMPONENTS Cpp) endif() diff --git a/SDK/CPackExamples/CppDynamic/CMakeLists.txt b/SDK/CPackExamples/CppDynamic/CMakeLists.txt index 4fee96e92..0e1a52a69 100644 --- a/SDK/CPackExamples/CppDynamic/CMakeLists.txt +++ b/SDK/CPackExamples/CppDynamic/CMakeLists.txt @@ -42,11 +42,11 @@ set(CMAKE_CXX_STANDARD 11) # Determine the platform and set lib3mf_DIR accordingly if(WIN32) # Path for Windows - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Windows/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.2-Windows/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS CppDynamic) elseif(APPLE) # Path for macOS (Darwin) - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Darwin/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.2-Darwin/lib/cmake/lib3mf") find_package(lib3mf REQUIRED COMPONENTS CppDynamic) else() # Path for Linux (Here we check twice to test for Debian / RPM packages properly) @@ -54,7 +54,7 @@ else() # Check if the package was not found if(NOT lib3mf_FOUND) # lib3mf not found, so set lib3mf_DIR to the fallback directory - set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.1-Linux/lib/cmake/lib3mf") + set(lib3mf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../lib3mf-2.3.2-Linux/lib/cmake/lib3mf") # Find package (lib3mf) find_package(lib3mf REQUIRED COMPONENTS CppDynamic) endif() diff --git a/SDK/Examples/CSharp/Lib3MF_Example.cs b/SDK/Examples/CSharp/Lib3MF_Example.cs index 53c85dff8..a5b5b9dcc 100644 --- a/SDK/Examples/CSharp/Lib3MF_Example.cs +++ b/SDK/Examples/CSharp/Lib3MF_Example.cs @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CSharp application that demonstrates the usage of the CSharp bindings of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/SDK/Examples/Pascal/Lib3MF_Example.lpr b/SDK/Examples/Pascal/Lib3MF_Example.lpr index 6a564d7dd..22d95d28e 100644 --- a/SDK/Examples/Pascal/Lib3MF_Example.lpr +++ b/SDK/Examples/Pascal/Lib3MF_Example.lpr @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Pascal application that demonstrates the usage of the Pascal bindings of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 *) diff --git a/SDK/Examples/Python/3mf_convert.py b/SDK/Examples/Python/3mf_convert.py index 81a3a3cc5..10e10e264 100644 --- a/SDK/Examples/Python/3mf_convert.py +++ b/SDK/Examples/Python/3mf_convert.py @@ -26,7 +26,7 @@ Abstract: An example to convert between 3MF and STL -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/Lib3MF_Example.py b/SDK/Examples/Python/Lib3MF_Example.py index 22220afd2..b656b5ac3 100644 --- a/SDK/Examples/Python/Lib3MF_Example.py +++ b/SDK/Examples/Python/Lib3MF_Example.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python application that demonstrates the usage of the Python bindings of the 3MF Library -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/add_triangle.py b/SDK/Examples/Python/add_triangle.py index 311c71b87..80e335d32 100644 --- a/SDK/Examples/Python/add_triangle.py +++ b/SDK/Examples/Python/add_triangle.py @@ -26,7 +26,7 @@ Abstract: Simplest 3mf example that just includes a single triangle -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/beam_lattice.py b/SDK/Examples/Python/beam_lattice.py index f6ca9097a..c2fbce2d6 100644 --- a/SDK/Examples/Python/beam_lattice.py +++ b/SDK/Examples/Python/beam_lattice.py @@ -26,7 +26,7 @@ Abstract: Beam Lattice example -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/color_cube.py b/SDK/Examples/Python/color_cube.py index c7673d9e0..704b15248 100644 --- a/SDK/Examples/Python/color_cube.py +++ b/SDK/Examples/Python/color_cube.py @@ -26,7 +26,7 @@ Abstract: Color cube example -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/create_components.py b/SDK/Examples/Python/create_components.py index 63e4164e9..f0bf17c0f 100644 --- a/SDK/Examples/Python/create_components.py +++ b/SDK/Examples/Python/create_components.py @@ -26,7 +26,7 @@ Abstract: An example that creates multiple components using transformations -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/create_cube.py b/SDK/Examples/Python/create_cube.py index 1f82ecb0e..5a5aa007e 100644 --- a/SDK/Examples/Python/create_cube.py +++ b/SDK/Examples/Python/create_cube.py @@ -26,7 +26,7 @@ Abstract: Create a simple cube -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/extract_info.py b/SDK/Examples/Python/extract_info.py index 62e325587..0aa1be623 100644 --- a/SDK/Examples/Python/extract_info.py +++ b/SDK/Examples/Python/extract_info.py @@ -26,7 +26,7 @@ Abstract: Extract info from a 3MF model -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Examples/Python/lib3mf_common.py b/SDK/Examples/Python/lib3mf_common.py index 058a66c59..c9296d1f1 100644 --- a/SDK/Examples/Python/lib3mf_common.py +++ b/SDK/Examples/Python/lib3mf_common.py @@ -26,7 +26,7 @@ Abstract: Common set of functions that are used across all examples -Interface version: 2.3.1 +Interface version: 2.3.2 ''' diff --git a/SDK/Readme.md b/SDK/Readme.md index fa392dda7..7ed4124cd 100644 --- a/SDK/Readme.md +++ b/SDK/Readme.md @@ -18,4 +18,4 @@ The specification can be downloaded at ## Documentation -lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.1.pdf](Documentation/lib3mf_v2.3.1.pdf). +lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.3.2.pdf](Documentation/lib3mf_v2.3.2.pdf). diff --git a/Source/API/lib3mf.cpp b/Source/API/lib3mf.cpp index 79d207aab..4b309cab2 100644 --- a/Source/API/lib3mf.cpp +++ b/Source/API/lib3mf.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It needs to be generated only once. -Interface version: 2.3.1 +Interface version: 2.3.2 */ diff --git a/lib3mf_version_update.py b/lib3mf_version_update.py new file mode 100644 index 000000000..bcae19022 --- /dev/null +++ b/lib3mf_version_update.py @@ -0,0 +1,250 @@ +''' + +@author: Vijai Kumar Suriyababu + +A simple script to update the lib3mf version number in all the necessary places. +Its run as follows + +python lib3mf_version_update.py 2.3.1 2.3.2 + +First argument is current version number and the second one is new version number + +It does the following +* Update version number in lib3mf.xml and generate bindings using ACT +* Patch the Python bindings +* Update the CMakeLists.txt +* Update all the docs, readme's and python, CPP examples and so on + +''' + +import os +import argparse +import re +import platform +import subprocess + + +def update_version_in_xml(file_path, old_version, new_version): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # Use regex to replace the old version with the new version + updated_content = re.sub( + fr'(]*version="){old_version}(")', + fr'\g<1>{new_version}\g<2>', + content + ) + + with open(file_path, 'w', encoding='utf-8') as file: + file.write(updated_content) + + print(f"Updated {file_path}") + + +def run_act_command(): + start_dir = os.getcwd() + act_dir = os.path.join(start_dir, 'AutomaticComponentToolkit') + + # Determine the command based on the operating system and architecture + os_type = platform.system() + arch = platform.machine() + + if os_type == 'Darwin': + if 'arm' in arch.lower(): + command = './act.arm.darwin lib3mf.xml -bindings ../Autogenerated/Bindings -interfaces ../Autogenerated/Source -suppresssubcomponents -suppresslicense -suppressstub -suppressexamples' + else: + command = './act.darwin lib3mf.xml -bindings ../Autogenerated/Bindings -interfaces ../Autogenerated/Source -suppresssubcomponents -suppresslicense -suppressstub -suppressexamples' + elif os_type == 'Linux': + if 'arm' in arch.lower(): + command = './act.arm.linux64 lib3mf.xml -bindings ../Autogenerated/Bindings -interfaces ../Autogenerated/Source -suppresssubcomponents -suppresslicense -suppressstub -suppressexamples' + else: + command = './act.linux64 lib3mf.xml -bindings ../Autogenerated/Bindings -interfaces ../Autogenerated/Source -suppresssubcomponents -suppresslicense -suppressstub -suppressexamples' + elif os_type == 'Windows': + command = 'act.win64.exe lib3mf.xml -bindings ..\\Autogenerated\\Bindings -interfaces ..\\Autogenerated\\Source -suppresssubcomponents -suppresslicense -suppressstub -suppressexamples' + else: + raise RuntimeError(f'Unsupported OS: {os_type}') + + try: + # Change to the AutomaticComponentToolkit directory + os.chdir(act_dir) + + # Execute the command + subprocess.run(command, shell=True, check=True) + print(f"Command executed successfully: {command}") + except subprocess.CalledProcessError as e: + print(f"Command failed with error: {e}") + finally: + # Change back to the original directory + os.chdir(start_dir) + + +def patch_python_bindings(): + start_dir = os.getcwd() + bindings_path = os.path.join(start_dir, 'Autogenerated', 'Bindings', 'Python', 'Lib3MF.py') + + search_line = r"\tNone = 0" + new_line = r"\tBeamLatticeBallModeNone = 0" + + with open(bindings_path, 'r', encoding='utf-8') as file: + content = file.read() + + # Use regex to replace the specific line + updated_content = re.sub(search_line, new_line, content) + + with open(bindings_path, 'w', encoding='utf-8') as file: + file.write(updated_content) + + print(f"Python bindings patched successfully: {bindings_path}") + + +def update_version_in_cmakelists(new_version): + if '-' in new_version: + version, prerelease = new_version.split('-', 1) + else: + version, prerelease = new_version, "" + + major, minor, micro = version.split('.') + + with open('CMakeLists.txt', 'r', encoding='utf-8') as file: + content = file.read() + + content = re.sub(r'set\(LIB3MF_VERSION_MAJOR \d+\)', f'set(LIB3MF_VERSION_MAJOR {major})', content) + content = re.sub(r'set\(LIB3MF_VERSION_MINOR \d+\)', f'set(LIB3MF_VERSION_MINOR {minor})', content) + content = re.sub(r'set\(LIB3MF_VERSION_MICRO \d+\)', f'set(LIB3MF_VERSION_MICRO {micro})', content) + content = re.sub(r'set\(LIB3MF_VERSION_PRERELEASE ".*"\)', f'set(LIB3MF_VERSION_PRERELEASE "{prerelease}")', + content) + + with open('CMakeLists.txt', 'w', encoding='utf-8') as file: + file.write(content) + + print(f"Updated CMakeLists.txt") + + +def update_version_in_conf_py(file_path, old_version, new_version): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # Update the release version + updated_content = re.sub( + fr"release = 'v{old_version}'", + fr"release = 'v{new_version}'", + content + ) + + with open(file_path, 'w', encoding='utf-8') as file: + file.write(updated_content) + + print(f"Updated {file_path}") + + +def update_version_in_index_rst(file_path, old_version, new_version): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # Replace all instances of the old version with the new version + updated_content = content.replace(old_version, new_version) + + with open(file_path, 'w', encoding='utf-8') as file: + file.write(updated_content) + + print(f"Updated {file_path}") + + +def update_version_in_readme_md(file_path, old_version, new_version): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # Update the PDF link version + updated_content = re.sub( + fr"lib3mf_v{old_version}\.pdf", + fr"lib3mf_v{new_version}.pdf", + content) + + with open(file_path, 'w', encoding='utf-8') as file: + file.write(updated_content) + + print(f"Updated {file_path}") + + +def update_version_in_file(file_path, old_version, new_version): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + + # Replace all instances of the old version with the new version + updated_content = content.replace(old_version, new_version) + + with open(file_path, 'w', encoding='utf-8') as file: + file.write(updated_content) + + print(f"Updated {file_path}") + + +def main(): + parser = argparse.ArgumentParser(description='Update lib3mf version in multiple files.') + parser.add_argument('old_version', type=str, help='The old version number to be replaced.') + parser.add_argument('new_version', type=str, help='The new version number to update to.') + args = parser.parse_args() + old_version = args.old_version + new_version = args.new_version + + # Get the current working directory + start_dir = os.getcwd() + + # Update AutomaticComponentToolkit/lib3mf.xml + xml_file_path = os.path.join(start_dir, 'AutomaticComponentToolkit', 'lib3mf.xml') + update_version_in_xml(xml_file_path, old_version, new_version) + + # Run the act command + run_act_command() + + # Patch the Python bindings + patch_python_bindings() + + # Update CMakeLists.txt + update_version_in_cmakelists(new_version) + + # Update Documentation/conf.py + conf_py_path = os.path.join(start_dir, 'Documentation', 'conf.py') + update_version_in_conf_py(conf_py_path, old_version, new_version) + + # Update Documentation/index.rst + index_rst_path = os.path.join(start_dir, 'Documentation', 'index.rst') + update_version_in_index_rst(index_rst_path, old_version, new_version) + + # Update SDK/Readme.md + readme_md_path = os.path.join(start_dir, 'SDK', 'Readme.md') + update_version_in_readme_md(readme_md_path, old_version, new_version) + + # Update README.md at the same location as this script + readme_path = os.path.join(start_dir, 'README.md') + update_version_in_readme_md(readme_path, old_version, new_version) + + # Define all additional file paths that need to be updated + additional_file_paths = [ + os.path.join(start_dir, 'SDK', 'Readme.md'), + os.path.join(start_dir, 'README.md'), + os.path.join(start_dir, 'Autogenerated', 'Bindings', 'Go', 'lib3mf_impl.go'), + os.path.join(start_dir, 'Autogenerated', 'Bindings', 'CppDynamic', 'lib3mf_abi.hpp'), + os.path.join(start_dir, 'SDK', 'Examples', 'CSharp', 'Lib3MF_Example.cs'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'lib3mf_common.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'Lib3MF_Example.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'create_cube.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'beam_lattice.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'add_triangle.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'color_cube.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', '3mf_convert.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'extract_info.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Python', 'create_components.py'), + os.path.join(start_dir, 'SDK', 'Examples', 'Pascal', 'Lib3MF_Example.lpr'), + os.path.join(start_dir, 'SDK', 'CPackExamples', 'Cpp', 'CMakeLists.txt'), + os.path.join(start_dir, 'SDK', 'CPackExamples', 'CppDynamic', 'CMakeLists.txt'), + os.path.join(start_dir, 'Source', 'API', 'lib3mf.cpp'), + ] + + # Update all additional specified files + for file_path in additional_file_paths: + update_version_in_file(file_path, old_version, new_version) + + +if __name__ == "__main__": + main() From e2e80ef550edf4111733e8c7d2d7c6727eb7a0f3 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 13 Jun 2024 15:22:54 +0530 Subject: [PATCH 52/54] updating zlib 1.3.1 --- CMakeLists.txt | 3 +- Libraries/zlib/Include/deflate.h | 35 +++++++++++++++++++++-- Libraries/zlib/Include/gzguts.h | 8 ++---- Libraries/zlib/Include/inftrees.h | 4 +-- Libraries/zlib/Include/zconf.h | 10 +------ Libraries/zlib/Include/zlib.h | 22 +++++++-------- Libraries/zlib/Include/zutil.h | 27 ++---------------- Libraries/zlib/Source/deflate.c | 47 +++++++++++++++++++++++-------- Libraries/zlib/Source/gzlib.c | 12 ++++---- Libraries/zlib/Source/inflate.c | 2 +- Libraries/zlib/Source/inftrees.c | 6 ++-- Libraries/zlib/Source/trees.c | 20 +++++++++++-- Libraries/zlib/zlib_v1.3^0.txt | 1 - submodules/zlib | 2 +- 14 files changed, 118 insertions(+), 81 deletions(-) delete mode 100644 Libraries/zlib/zlib_v1.3^0.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c4f8c009..aaca07d2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required (VERSION 3.0) cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0048 NEW) + set_property(GLOBAL PROPERTY USE_FOLDERS ON) include(GNUInstallDirs) @@ -12,7 +13,7 @@ set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility br set(LIB3MF_VERSION_MINOR 3) # increase on every backward compatible change of the API set(LIB3MF_VERSION_MICRO 2) # increase on on every change that does not alter the API set(LIB3MF_VERSION_PRERELEASE "") # denotes pre-release information of a version of lib3mf - +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") project(lib3mf VERSION ${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO} DESCRIPTION "An implementation of the 3D Manufacturing Format file standard" diff --git a/Libraries/zlib/Include/deflate.h b/Libraries/zlib/Include/deflate.h index 869679142..300c6ada6 100644 --- a/Libraries/zlib/Include/deflate.h +++ b/Libraries/zlib/Include/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/Libraries/zlib/Include/gzguts.h b/Libraries/zlib/Include/gzguts.h index f9375047e..eba72085b 100644 --- a/Libraries/zlib/Include/gzguts.h +++ b/Libraries/zlib/Include/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -210,9 +210,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/Libraries/zlib/Include/inftrees.h b/Libraries/zlib/Include/inftrees.h index a10712d8c..396f74b5d 100644 --- a/Libraries/zlib/Include/inftrees.h +++ b/Libraries/zlib/Include/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/Libraries/zlib/Include/zconf.h b/Libraries/zlib/Include/zconf.h index fb76ffe31..62adc8d84 100644 --- a/Libraries/zlib/Include/zconf.h +++ b/Libraries/zlib/Include/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -300,14 +300,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have diff --git a/Libraries/zlib/Include/zlib.h b/Libraries/zlib/Include/zlib.h index 6b7244f99..8d4b932ea 100644 --- a/Libraries/zlib/Include/zlib.h +++ b/Libraries/zlib/Include/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.3" -#define ZLIB_VERNUM 0x1300 +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -936,10 +936,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, @@ -1758,14 +1758,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); diff --git a/Libraries/zlib/Include/zutil.h b/Libraries/zlib/Include/zutil.h index 902a304cc..48dd7feba 100644 --- a/Libraries/zlib/Include/zutil.h +++ b/Libraries/zlib/Include/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -56,7 +56,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -137,17 +137,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -170,18 +161,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 diff --git a/Libraries/zlib/Source/deflate.c b/Libraries/zlib/Source/deflate.c index bd0117519..012ea8148 100644 --- a/Libraries/zlib/Source/deflate.c +++ b/Libraries/zlib/Source/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -493,7 +493,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1294,7 +1306,7 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1305,10 +1317,15 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1539,13 +1556,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { diff --git a/Libraries/zlib/Source/gzlib.c b/Libraries/zlib/Source/gzlib.c index 29fc4486f..983153cc8 100644 --- a/Libraries/zlib/Source/gzlib.c +++ b/Libraries/zlib/Source/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -563,20 +563,20 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax(void) { - unsigned p, q; - - p = 1; +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/Libraries/zlib/Source/inflate.c b/Libraries/zlib/Source/inflate.c index b0757a9b2..94ecff015 100644 --- a/Libraries/zlib/Source/inflate.c +++ b/Libraries/zlib/Source/inflate.c @@ -1387,7 +1387,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/Libraries/zlib/Source/inftrees.c b/Libraries/zlib/Source/inftrees.c index 8a208c2da..98cfe1644 100644 --- a/Libraries/zlib/Source/inftrees.c +++ b/Libraries/zlib/Source/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -57,7 +57,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/Libraries/zlib/Source/trees.c b/Libraries/zlib/Source/trees.c index 8dbdc40ba..6a523ef34 100644 --- a/Libraries/zlib/Source/trees.c +++ b/Libraries/zlib/Source/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/Libraries/zlib/zlib_v1.3^0.txt b/Libraries/zlib/zlib_v1.3^0.txt deleted file mode 100644 index acd062169..000000000 --- a/Libraries/zlib/zlib_v1.3^0.txt +++ /dev/null @@ -1 +0,0 @@ -"v1.3^0" diff --git a/submodules/zlib b/submodules/zlib index 09155eaa2..51b7f2abd 160000 --- a/submodules/zlib +++ b/submodules/zlib @@ -1 +1 @@ -Subproject commit 09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851 +Subproject commit 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf From a18d0f1f932affbde0e4b31d6f32c6d9e6fe4ce9 Mon Sep 17 00:00:00 2001 From: gangatp Date: Thu, 13 Jun 2024 17:38:21 +0530 Subject: [PATCH 53/54] updating zlib 1.3.1 version file --- Libraries/zlib/zlib_v1.3.1^0.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 Libraries/zlib/zlib_v1.3.1^0.txt diff --git a/Libraries/zlib/zlib_v1.3.1^0.txt b/Libraries/zlib/zlib_v1.3.1^0.txt new file mode 100644 index 000000000..bd2d16a9b --- /dev/null +++ b/Libraries/zlib/zlib_v1.3.1^0.txt @@ -0,0 +1 @@ +"v1.3.1^0" From 7ab2649df5d4cc4a8b9f72ab2d59f7c85006f6c1 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:32:14 +0200 Subject: [PATCH 54/54] Update interface version to 2.4.0 --- .github/workflows/build.yml | 20 ++----------------- .../Bindings/CppDynamic/lib3mf_abi.hpp | 2 +- Autogenerated/Bindings/Go/lib3mf_impl.go | 2 +- Autogenerated/Source/lib3mf_abi.hpp | 2 +- .../Source/lib3mf_interfaceexception.cpp | 2 +- SDK/Examples/CSharp/Lib3MF_Example.cs | 2 +- SDK/Examples/Pascal/Lib3MF_Example.lpr | 2 +- SDK/Examples/Python/3mf_convert.py | 2 +- SDK/Examples/Python/Lib3MF_Example.py | 2 +- SDK/Examples/Python/add_triangle.py | 2 +- SDK/Examples/Python/beam_lattice.py | 2 +- SDK/Examples/Python/color_cube.py | 2 +- SDK/Examples/Python/create_components.py | 2 +- SDK/Examples/Python/create_cube.py | 2 +- SDK/Examples/Python/extract_info.py | 2 +- SDK/Examples/Python/lib3mf_common.py | 2 +- Source/API/lib3mf.cpp | 2 +- submodules/zlib | 2 +- 18 files changed, 19 insertions(+), 35 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 72f1bf534..7f98691c9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -506,29 +506,13 @@ jobs: cmake --build . ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf - deploy-source-code-with-submodules: - runs-on: ubuntu-20.04 - needs: [ set-lib3mf-version, assemble-sdk ] - env: - LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - run: | - mkdir -p lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules - rsync -av --progress . ./lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules --exclude .git --exclude .gitignore --exclude .github --exclude .gitmodules --exclude *.yml --exclude lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules - path: lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules + set-integration-tests-status: runs-on: ubuntu-20.04 - needs: [ deploy-linux, deploy-windows, deploy-macos, deploy-source-code-with-submodules ] + needs: [ deploy-linux, deploy-windows, deploy-macos ] outputs: run_integration_tests: ${{ steps.set-status.outputs.run_integration_tests }} steps: diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp index 6b1dac4a1..c9fe364e8 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 */ diff --git a/Autogenerated/Bindings/Go/lib3mf_impl.go b/Autogenerated/Bindings/Go/lib3mf_impl.go index 552faf054..a01a2f902 100644 --- a/Autogenerated/Bindings/Go/lib3mf_impl.go +++ b/Autogenerated/Bindings/Go/lib3mf_impl.go @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated Go implementation file in order to allow an easy use of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 */ diff --git a/Autogenerated/Source/lib3mf_abi.hpp b/Autogenerated/Source/lib3mf_abi.hpp index f1340326e..5c4790230 100644 --- a/Autogenerated/Source/lib3mf_abi.hpp +++ b/Autogenerated/Source/lib3mf_abi.hpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++-Header file in order to allow an easy use of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 */ diff --git a/Autogenerated/Source/lib3mf_interfaceexception.cpp b/Autogenerated/Source/lib3mf_interfaceexception.cpp index 308a29e1c..c93e0cf1c 100644 --- a/Autogenerated/Source/lib3mf_interfaceexception.cpp +++ b/Autogenerated/Source/lib3mf_interfaceexception.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ Implementation file with the basic internal exception type in order to allow an easy use of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 */ diff --git a/SDK/Examples/CSharp/Lib3MF_Example.cs b/SDK/Examples/CSharp/Lib3MF_Example.cs index a5b5b9dcc..c98dfdd31 100644 --- a/SDK/Examples/CSharp/Lib3MF_Example.cs +++ b/SDK/Examples/CSharp/Lib3MF_Example.cs @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CSharp application that demonstrates the usage of the CSharp bindings of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 */ diff --git a/SDK/Examples/Pascal/Lib3MF_Example.lpr b/SDK/Examples/Pascal/Lib3MF_Example.lpr index 22d95d28e..1fa94bbb9 100644 --- a/SDK/Examples/Pascal/Lib3MF_Example.lpr +++ b/SDK/Examples/Pascal/Lib3MF_Example.lpr @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Pascal application that demonstrates the usage of the Pascal bindings of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 *) diff --git a/SDK/Examples/Python/3mf_convert.py b/SDK/Examples/Python/3mf_convert.py index 10e10e264..428afe7eb 100644 --- a/SDK/Examples/Python/3mf_convert.py +++ b/SDK/Examples/Python/3mf_convert.py @@ -26,7 +26,7 @@ Abstract: An example to convert between 3MF and STL -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/Lib3MF_Example.py b/SDK/Examples/Python/Lib3MF_Example.py index b656b5ac3..00a022f79 100644 --- a/SDK/Examples/Python/Lib3MF_Example.py +++ b/SDK/Examples/Python/Lib3MF_Example.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python application that demonstrates the usage of the Python bindings of the 3MF Library -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/add_triangle.py b/SDK/Examples/Python/add_triangle.py index 80e335d32..6093235a8 100644 --- a/SDK/Examples/Python/add_triangle.py +++ b/SDK/Examples/Python/add_triangle.py @@ -26,7 +26,7 @@ Abstract: Simplest 3mf example that just includes a single triangle -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/beam_lattice.py b/SDK/Examples/Python/beam_lattice.py index c2fbce2d6..71baccca6 100644 --- a/SDK/Examples/Python/beam_lattice.py +++ b/SDK/Examples/Python/beam_lattice.py @@ -26,7 +26,7 @@ Abstract: Beam Lattice example -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/color_cube.py b/SDK/Examples/Python/color_cube.py index 704b15248..dc4e505aa 100644 --- a/SDK/Examples/Python/color_cube.py +++ b/SDK/Examples/Python/color_cube.py @@ -26,7 +26,7 @@ Abstract: Color cube example -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/create_components.py b/SDK/Examples/Python/create_components.py index f0bf17c0f..363e0d3c4 100644 --- a/SDK/Examples/Python/create_components.py +++ b/SDK/Examples/Python/create_components.py @@ -26,7 +26,7 @@ Abstract: An example that creates multiple components using transformations -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/create_cube.py b/SDK/Examples/Python/create_cube.py index 5a5aa007e..f7ac427d1 100644 --- a/SDK/Examples/Python/create_cube.py +++ b/SDK/Examples/Python/create_cube.py @@ -26,7 +26,7 @@ Abstract: Create a simple cube -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/extract_info.py b/SDK/Examples/Python/extract_info.py index 0aa1be623..cbec134b4 100644 --- a/SDK/Examples/Python/extract_info.py +++ b/SDK/Examples/Python/extract_info.py @@ -26,7 +26,7 @@ Abstract: Extract info from a 3MF model -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/SDK/Examples/Python/lib3mf_common.py b/SDK/Examples/Python/lib3mf_common.py index c9296d1f1..2aac42422 100644 --- a/SDK/Examples/Python/lib3mf_common.py +++ b/SDK/Examples/Python/lib3mf_common.py @@ -26,7 +26,7 @@ Abstract: Common set of functions that are used across all examples -Interface version: 2.3.2 +Interface version: 2.4.0 ''' diff --git a/Source/API/lib3mf.cpp b/Source/API/lib3mf.cpp index 4b309cab2..19a7094d0 100644 --- a/Source/API/lib3mf.cpp +++ b/Source/API/lib3mf.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It needs to be generated only once. -Interface version: 2.3.2 +Interface version: 2.4.0 */ diff --git a/submodules/zlib b/submodules/zlib index 51b7f2abd..09155eaa2 160000 --- a/submodules/zlib +++ b/submodules/zlib @@ -1 +1 @@ -Subproject commit 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf +Subproject commit 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